diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d1afe2413e..26e5aa627c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,19 +3,22 @@ accounts/usbwallet @karalabe accounts/scwallet @gballet accounts/abi @gballet @MariusVanDerWijden +beacon/engine @lightclient cmd/clef @holiman +cmd/evm @holiman @MariusVanDerWijden @lightclient consensus @karalabe core/ @karalabe @holiman @rjl493456442 eth/ @karalabe @holiman @rjl493456442 -eth/catalyst/ @gballet +eth/catalyst/ @gballet @lightclient eth/tracers/ @s1na +core/tracing/ @s1na graphql/ @s1na +internal/ethapi @lightclient +internal/era @lightclient les/ @zsfelfoldi @rjl493456442 light/ @zsfelfoldi @rjl493456442 node/ @fjl p2p/ @fjl @zsfelfoldi +params/ @fjl @holiman @karalabe @gballet @rjl493456442 @zsfelfoldi rpc/ @fjl @holiman -p2p/simulations @fjl -p2p/protocols @fjl -p2p/testing @fjl signer/ @holiman diff --git a/.gitignore b/.gitignore index 75d73f5001..6496f59bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,14 @@ build/_vendor/pkg /build/bin/ /geth*.zip +# used by the build/ci.go archive + upload tool +/geth*.tar.gz +/geth*.tar.gz.sig +/geth*.tar.gz.asc +/geth*.zip.sig +/geth*.zip.asc + + # travis profile.tmp profile.cov diff --git a/.golangci.yml b/.golangci.yml index 90e5c591f6..f7e3427bb5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,8 +6,6 @@ run: # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ skip-dirs-use-default: true - skip-files: - - core/genesis_alloc.go output: format: colored-line-number @@ -28,7 +26,10 @@ linters: - durationcheck - exportloopref - whitespace + - revive # only certain checks enabled + ### linters we tried and will not be using: + ### # - structcheck # lots of false positives # - errcheck #lot of false positives # - contextcheck @@ -41,8 +42,19 @@ linters: linters-settings: gofmt: simplify: true + revive: + enable-all-rules: false + # here we enable specific useful rules + # see https://golangci-lint.run/usage/linters/#revive for supported rules + rules: + - name: receiver-naming + severity: warning + disabled: false + exclude: [""] issues: + exclude-files: + - core/genesis_alloc.go exclude-rules: - path: core/state/metrics.go linters: @@ -50,14 +62,17 @@ issues: - path: core/txpool/legacypool/list.go linters: - staticcheck + - path: crypto/bn256/ + linters: + - revive + - path: cmd/utils/flags.go + text: "SA1019: cfg.TxLookupLimit is deprecated: use 'TransactionHistory' instead." + - path: cmd/utils/flags.go + text: "SA1019: ethconfig.Defaults.TxLookupLimit is deprecated: use 'TransactionHistory' instead." - path: internal/build/pgp.go text: 'SA1019: "golang.org/x/crypto/openpgp" is deprecated: this package is unmaintained except for security fixes.' - path: core/vm/contracts.go text: 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated: RIPEMD-160 is a legacy hash and should not be used for new applications.' - - path: accounts/usbwallet/trezor.go - text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.' - - path: accounts/usbwallet/trezor/ - text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.' exclude: - 'SA1019: event.TypeMux is deprecated: use Feed' - 'SA1019: strings.Title is deprecated' diff --git a/.mailmap b/.mailmap index aa074b76d6..312e51d854 100644 --- a/.mailmap +++ b/.mailmap @@ -56,7 +56,6 @@ Diederik Loerakker Dimitry Khokhlov Domino Valdano -Domino Valdano Edgar Aroutiounian diff --git a/.travis.yml b/.travis.yml index a55583a703..31c944641f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,14 +9,13 @@ jobs: - azure-osx include: - # These builders create the Docker sub-images for multi-arch push and each - # will attempt to push the multi-arch image if they are the last builder + # This builder create and push the Docker images for all architectures - stage: build if: type = push os: linux arch: amd64 - dist: bionic - go: 1.21.x + dist: focal + go: 1.23.x env: - docker services: @@ -26,44 +25,27 @@ jobs: before_install: - export DOCKER_CLI_EXPERIMENTAL=enabled script: - - go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go - - - stage: build - if: type = push - os: linux - arch: arm64 - dist: bionic - go: 1.21.x - env: - - docker - services: - - docker - git: - submodules: false # avoid cloning ethereum/tests - before_install: - - export DOCKER_CLI_EXPERIMENTAL=enabled - script: - - go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go + - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64" -upload ethereum/client-go # This builder does the Linux Azure uploads - stage: build if: type = push os: linux - dist: bionic + dist: focal sudo: required - go: 1.21.x + go: 1.23.x env: - azure-linux git: submodules: false # avoid cloning ethereum/tests - addons: - apt: - packages: - - gcc-multilib script: - # Build for the primary platforms that Trusty can manage + # build amd64 - go run build/ci.go install -dlgo - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + + # build 386 + - sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + - git status --porcelain - go run build/ci.go install -dlgo -arch 386 - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds @@ -85,12 +67,13 @@ jobs: if: type = push os: osx osx_image: xcode14.2 - go: 1.21.x + go: 1.23.1 # See https://github.com/ethereum/go-ethereum/pull/30478 env: - azure-osx git: submodules: false # avoid cloning ethereum/tests script: + - ln -sf /Users/travis/gopath/bin/go1.23.1 /usr/local/bin/go # Work around travis go-setup bug - go run build/ci.go install -dlgo - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go install -dlgo -arch arm64 @@ -98,48 +81,34 @@ jobs: # These builders run the tests - stage: build + if: type = push os: linux arch: amd64 - dist: bionic - go: 1.21.x + dist: focal + go: 1.23.x script: - - travis_wait 30 go run build/ci.go test $TEST_PACKAGES - - - stage: build - if: type = pull_request - os: linux - arch: arm64 - dist: bionic - go: 1.20.x - script: - - travis_wait 30 go run build/ci.go test $TEST_PACKAGES + - travis_wait 45 go run build/ci.go test $TEST_PACKAGES - stage: build + if: type = push os: linux - dist: bionic - go: 1.20.x + dist: focal + go: 1.22.x script: - - travis_wait 30 go run build/ci.go test $TEST_PACKAGES + - travis_wait 45 go run build/ci.go test $TEST_PACKAGES # This builder does the Ubuntu PPA nightly uploads - stage: build if: type = cron || (type = push && tag ~= /^v[0-9]/) os: linux - dist: bionic - go: 1.21.x + dist: focal + go: 1.23.x env: - ubuntu-ppa git: submodules: false # avoid cloning ethereum/tests - addons: - apt: - packages: - - devscripts - - debhelper - - dput - - fakeroot - - python-bzrlib - - python-paramiko + before_install: + - sudo -E apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot script: - echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " @@ -148,8 +117,8 @@ jobs: - stage: build if: type = cron os: linux - dist: bionic - go: 1.21.x + dist: focal + go: 1.23.x env: - azure-purge git: @@ -161,8 +130,9 @@ jobs: - stage: build if: type = cron os: linux - dist: bionic - go: 1.21.x + dist: focal + go: 1.23.x + env: + - racetests script: - - travis_wait 30 go run build/ci.go test -race $TEST_PACKAGES - + - travis_wait 60 go run build/ci.go test -race $TEST_PACKAGES diff --git a/Dockerfile b/Dockerfile index 355273b811..8406afe745 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.21-alpine as builder +FROM golang:1.23-alpine AS builder RUN apk add --no-cache make cmake gcc musl-dev linux-headers git bash build-base libc-dev # Get dependencies - will also be cached if we won't change go.mod/go.sum diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 8c7e2bd0a3..bf1caceda5 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.21-alpine as builder +FROM golang:1.23-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git # Get dependencies - will also be cached if we won't change go.mod/go.sum @@ -16,6 +16,13 @@ ADD . /go-ethereum # For blst ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" + +# This is not strictly necessary, but it matches the "Dockerfile" steps, thus +# makes it so that under certain circumstances, the docker layer can be cached, +# and the builder can jump to the next (build all) command, with the go cache fully loaded. +# +RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth + RUN cd /go-ethereum && go run build/ci.go install -static # Pull all binaries into a second stage deploy alpine container diff --git a/Makefile b/Makefile index 252813ba05..f806be62e9 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # with Go source code. If you know what GOPATH is then you probably # don't need to bother with make. -.PHONY: geth android ios evm all test truffle-test clean +.PHONY: geth faucet all test truffle-test lint fmt clean devtools help .PHONY: docker GOBIN = ./build/bin @@ -11,7 +11,7 @@ GORUN = go run GIT_COMMIT=$(shell git rev-parse HEAD) GIT_COMMIT_DATE=$(shell git log -n1 --pretty='format:%cd' --date=format:'%Y%m%d') -#? geth: Build geth +#? geth: Build geth. geth: $(GORUN) build/ci.go install ./cmd/geth @echo "Done building." @@ -22,11 +22,11 @@ faucet: $(GORUN) build/ci.go install ./cmd/faucet @echo "Done building faucet" -#? all: Build all packages and executables +#? all: Build all packages and executables. all: $(GORUN) build/ci.go install -#? test: Run the tests +#? test: Run the tests. test: all $(GORUN) build/ci.go test -timeout 1h @@ -40,11 +40,15 @@ truffle-test: docker compose -f ./tests/truffle/docker-compose.yml up --exit-code-from truffle-test truffle-test docker compose -f ./tests/truffle/docker-compose.yml down -#? lint: Run certain pre-selected linters +#? lint: Run certain pre-selected linters. lint: ## Run linters. $(GORUN) build/ci.go lint -#? clean: Clean go cache, built executables, and the auto generated folder +#? fmt: Ensure consistent code formatting. +fmt: + gofmt -s -w $(shell find . -name "*.go") + +#? clean: Clean go cache, built executables, and the auto generated folder. clean: go clean -cache rm -fr build/_workspace/pkg/ $(GOBIN)/* @@ -52,11 +56,11 @@ clean: # The devtools target installs tools required for 'go generate'. # You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'. -#? devtools: Install recommended developer tools +#? devtools: Install recommended developer tools. devtools: env GOBIN= go install golang.org/x/tools/cmd/stringer@latest env GOBIN= go install github.com/fjl/gencodec@latest - env GOBIN= go install github.com/golang/protobuf/protoc-gen-go@latest + env GOBIN= go install google.golang.org/protobuf/cmd/protoc-gen-go@latest env GOBIN= go install ./cmd/abigen @type "solc" 2> /dev/null || echo 'Please install solc' @type "protoc" 2> /dev/null || echo 'Please install protoc' @@ -67,6 +71,9 @@ docker: #? help: Get more info on make commands. help: Makefile - @echo " Choose a command run in go-ethereum:" + @echo '' + @echo 'Usage:' + @echo ' make [target]' + @echo '' + @echo 'Targets:' @sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /' -.PHONY: help diff --git a/README.md b/README.md index d26fec81c4..241e20a514 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Many of the below are the same as or similar to go-ethereum. For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth). -Building `geth` requires both a Go (version 1.21 or later) and a C compiler (GCC 5 or higher). You can install +Building `geth` requires both a Go (version 1.22 or later) and a C compiler (GCC 5 or higher). You can install them using your favourite package manager. Once the dependencies are installed, run ```shell diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index bc76df0dc2..dfcd059393 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1218,3 +1218,10 @@ func TestUnpackRevert(t *testing.T) { }) } } + +func TestInternalContractType(t *testing.T) { + jsonData := `[{"inputs":[{"components":[{"internalType":"uint256","name":"dailyLimit","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"accountDailyLimit","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"onlyWhitelisted","type":"bool"}],"internalType":"struct IMessagePassingBridge.BridgeLimits","name":"bridgeLimits","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.AccountLimit","name":"accountDailyLimit","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.BridgeDailyLimit","name":"bridgeDailyLimit","type":"tuple"},{"internalType":"contract INameService","name":"nameService","type":"INameService"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"canBridge","outputs":[{"internalType":"bool","name":"isWithinLimit","type":"bool"},{"internalType":"string","name":"error","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFrom18ToTokenDecimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFromTokenTo18Decimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"}]` + if _, err := JSON(strings.NewReader(jsonData)); err != nil { + t.Fatal(err) + } +} diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index fa5461895a..227a088b7d 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -127,7 +127,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error { return arguments.copyAtomic(v, values[0]) } -// unpackAtomic unpacks ( hexdata -> go ) a single value +// copyAtomic copies ( hexdata -> go ) a single value func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error { dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 0740c69510..b5e6e349c4 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -142,10 +142,10 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou // NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer // from a single private key. func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) { - keyAddr := crypto.PubkeyToAddress(key.PublicKey) if chainID == nil { return nil, ErrNoChainID } + keyAddr := crypto.PubkeyToAddress(key.PublicKey) signer := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: keyAddr, diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 96d284cdcc..0504089c71 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -59,11 +59,12 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) - Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds) - GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) - GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle) - GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle) - GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) + Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds) + GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) + GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle) + GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle) + GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) + AccessList types.AccessList // Access list to set for the transaction execution (nil = no access list) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) @@ -300,20 +301,21 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add return nil, err } baseTx := &types.DynamicFeeTx{ - To: contract, - Nonce: nonce, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Gas: gasLimit, - Value: value, - Data: input, + To: contract, + Nonce: nonce, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Gas: gasLimit, + Value: value, + Data: input, + AccessList: opts.AccessList, } return types.NewTx(baseTx), nil } func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) { - if opts.GasFeeCap != nil || opts.GasTipCap != nil { - return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet") + if opts.GasFeeCap != nil || opts.GasTipCap != nil || opts.AccessList != nil { + return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas or accessList specified but london is not active yet") } // Normalize value value := opts.Value @@ -461,7 +463,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int if err != nil { return nil, nil, err } - sub, err := event.NewSubscription(func(quit <-chan struct{}) error { + sub := event.NewSubscription(func(quit <-chan struct{}) error { for _, log := range buff { select { case logs <- log: @@ -470,11 +472,8 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int } } return nil - }), nil + }) - if err != nil { - return nil, nil, err - } return logs, sub, nil } diff --git a/accounts/abi/bind/source.go.tpl b/accounts/abi/bind/source.go.tpl new file mode 100644 index 0000000000..c84862d03b --- /dev/null +++ b/accounts/abi/bind/source.go.tpl @@ -0,0 +1,487 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +import ( + "math/big" + "strings" + "errors" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +{{$structs := .Structs}} +{{range $structs}} + // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. + type {{.Name}} struct { + {{range $field := .Fields}} + {{$field.Name}} {{$field.Type}}{{end}} + } +{{end}} + +{{range $contract := .Contracts}} + // {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract. + var {{.Type}}MetaData = &bind.MetaData{ + ABI: "{{.InputABI}}", + {{if $contract.FuncSigs -}} + Sigs: map[string]string{ + {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", + {{end}} + }, + {{end -}} + {{if .InputBin -}} + Bin: "0x{{.InputBin}}", + {{end}} + } + // {{.Type}}ABI is the input ABI used to generate the binding from. + // Deprecated: Use {{.Type}}MetaData.ABI instead. + var {{.Type}}ABI = {{.Type}}MetaData.ABI + + {{if $contract.FuncSigs}} + // Deprecated: Use {{.Type}}MetaData.Sigs instead. + // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. + var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs + {{end}} + + {{if .InputBin}} + // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. + // Deprecated: Use {{.Type}}MetaData.Bin instead. + var {{.Type}}Bin = {{.Type}}MetaData.Bin + + // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. + func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { + parsed, err := {{.Type}}MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + {{range $pattern, $name := .Libraries}} + {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) + {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) + {{end}} + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil + } + {{end}} + + // {{.Type}} is an auto generated Go binding around an Ethereum contract. + type {{.Type}} struct { + {{.Type}}Caller // Read-only binding to the contract + {{.Type}}Transactor // Write-only binding to the contract + {{.Type}}Filterer // Log filterer for contract events + } + + // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract. + type {{.Type}}Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract. + type {{.Type}}Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events. + type {{.Type}}Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Session is an auto generated Go binding around an Ethereum contract, + // with pre-set call and transact options. + type {{.Type}}Session struct { + Contract *{{.Type}} // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + } + + // {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract, + // with pre-set call options. + type {{.Type}}CallerSession struct { + Contract *{{.Type}}Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + } + + // {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract, + // with pre-set transact options. + type {{.Type}}TransactorSession struct { + Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + } + + // {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract. + type {{.Type}}Raw struct { + Contract *{{.Type}} // Generic contract binding to access the raw methods on + } + + // {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. + type {{.Type}}CallerRaw struct { + Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on + } + + // {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. + type {{.Type}}TransactorRaw struct { + Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on + } + + // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) { + contract, err := bind{{.Type}}(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil + } + + // New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) { + contract, err := bind{{.Type}}(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &{{.Type}}Caller{contract: contract}, nil + } + + // New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) { + contract, err := bind{{.Type}}(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &{{.Type}}Transactor{contract: contract}, nil + } + + // New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) { + contract, err := bind{{.Type}}(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &{{.Type}}Filterer{contract: contract}, nil + } + + // bind{{.Type}} binds a generic wrapper to an already deployed contract. + func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := {{.Type}}MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil + } + + // Call invokes the (constant) contract method with params as input values and + // sets the output to result. The result type might be a single field for simple + // returns, a slice of interfaces for anonymous returns and a struct for named + // returns. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...) + } + + // Transfer initiates a plain transaction to move funds to the contract, calling + // its default method if one is available. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts) + } + + // Transact invokes the (paid) contract method with params as input values. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...) + } + + // Call invokes the (constant) contract method with params as input values and + // sets the output to result. The result type might be a single field for simple + // returns, a slice of interfaces for anonymous returns and a struct for named + // returns. + func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...) + } + + // Transfer initiates a plain transaction to move funds to the contract, calling + // its default method if one is available. + func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.contract.Transfer(opts) + } + + // Transact invokes the (paid) contract method with params as input values. + func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) + } + + {{range .Calls}} + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { + var out []interface{} + err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + {{if .Structured}} + outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) + if err != nil { + return *outstruct, err + } + {{range $i, $t := .Normalized.Outputs}} + outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return *outstruct, err + {{else}} + if err != nil { + return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err + } + {{range $i, $t := .Normalized.Outputs}} + out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err + {{end}} + } + + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + {{end}} + + {{range .Transacts}} + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) + } + {{end}} + + {{if .Fallback}} + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + {{end}} + + {{if .Receive}} + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + {{end}} + + {{range .Events}} + // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract. + type {{$contract.Type}}{{.Normalized.Name}}Iterator struct { + Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration + } + // Next advances the iterator to the subsequent event, returning whether there + // are any more events found. In case of a retrieval or parsing error, false is + // returned and Error() can be queried for the exact failure. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool { + // If the iterator failed, stop iterating + if (it.fail != nil) { + return false + } + // If the iterator completed, deliver directly whatever's available + if (it.done) { + select { + case log := <-it.logs: + it.Event = new({{$contract.Type}}{{.Normalized.Name}}) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new({{$contract.Type}}{{.Normalized.Name}}) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } + } + // Error returns any retrieval or parsing error occurred during filtering. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error { + return it.fail + } + // Close terminates the iteration process, releasing any pending underlying + // resources. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error { + it.sub.Unsubscribe() + return nil + } + + // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract. + type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}} + {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}} + Raw types.Log // Blockchain specific contextual infos + } + + // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { + {{range .Normalized.Inputs}} + {{if .Indexed}}var {{.Name}}Rule []interface{} + for _, {{.Name}}Item := range {{.Name}} { + {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) + }{{end}}{{end}} + + logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) + if err != nil { + return nil, err + } + return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil + } + + // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { + {{range .Normalized.Inputs}} + {{if .Indexed}}var {{.Name}}Rule []interface{} + for _, {{.Name}}Item := range {{.Name}} { + {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) + }{{end}}{{end}} + + logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil + } + + // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { + event := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil + } + + {{end}} +{{end}} \ No newline at end of file diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 95dc13cc18..4a0062af0a 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -16,7 +16,11 @@ package bind -import "github.com/ethereum/go-ethereum/accounts/abi" +import ( + _ "embed" + + "github.com/ethereum/go-ethereum/accounts/abi" +) // tmplData is the data structure required to fill the binding template. type tmplData struct { @@ -80,492 +84,6 @@ var tmplSource = map[Lang]string{ // tmplSourceGo is the Go source template that the generated Go contract binding // is based on. -const tmplSourceGo = ` -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package {{.Package}} - -import ( - "math/big" - "strings" - "errors" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -{{$structs := .Structs}} -{{range $structs}} - // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. - type {{.Name}} struct { - {{range $field := .Fields}} - {{$field.Name}} {{$field.Type}}{{end}} - } -{{end}} - -{{range $contract := .Contracts}} - // {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract. - var {{.Type}}MetaData = &bind.MetaData{ - ABI: "{{.InputABI}}", - {{if $contract.FuncSigs -}} - Sigs: map[string]string{ - {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", - {{end}} - }, - {{end -}} - {{if .InputBin -}} - Bin: "0x{{.InputBin}}", - {{end}} - } - // {{.Type}}ABI is the input ABI used to generate the binding from. - // Deprecated: Use {{.Type}}MetaData.ABI instead. - var {{.Type}}ABI = {{.Type}}MetaData.ABI - - {{if $contract.FuncSigs}} - // Deprecated: Use {{.Type}}MetaData.Sigs instead. - // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. - var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs - {{end}} - - {{if .InputBin}} - // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. - // Deprecated: Use {{.Type}}MetaData.Bin instead. - var {{.Type}}Bin = {{.Type}}MetaData.Bin - - // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. - func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { - parsed, err := {{.Type}}MetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - {{range $pattern, $name := .Libraries}} - {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) - {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) - {{end}} - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil - } - {{end}} - - // {{.Type}} is an auto generated Go binding around an Ethereum contract. - type {{.Type}} struct { - {{.Type}}Caller // Read-only binding to the contract - {{.Type}}Transactor // Write-only binding to the contract - {{.Type}}Filterer // Log filterer for contract events - } - - // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract. - type {{.Type}}Caller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract. - type {{.Type}}Transactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events. - type {{.Type}}Filterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Session is an auto generated Go binding around an Ethereum contract, - // with pre-set call and transact options. - type {{.Type}}Session struct { - Contract *{{.Type}} // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session - } - - // {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract, - // with pre-set call options. - type {{.Type}}CallerSession struct { - Contract *{{.Type}}Caller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - } - - // {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract, - // with pre-set transact options. - type {{.Type}}TransactorSession struct { - Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session - } - - // {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract. - type {{.Type}}Raw struct { - Contract *{{.Type}} // Generic contract binding to access the raw methods on - } - - // {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. - type {{.Type}}CallerRaw struct { - Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on - } - - // {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. - type {{.Type}}TransactorRaw struct { - Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on - } - - // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) { - contract, err := bind{{.Type}}(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil - } - - // New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) { - contract, err := bind{{.Type}}(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &{{.Type}}Caller{contract: contract}, nil - } - - // New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) { - contract, err := bind{{.Type}}(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &{{.Type}}Transactor{contract: contract}, nil - } - - // New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) { - contract, err := bind{{.Type}}(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &{{.Type}}Filterer{contract: contract}, nil - } - - // bind{{.Type}} binds a generic wrapper to an already deployed contract. - func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := {{.Type}}MetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil - } - - // Call invokes the (constant) contract method with params as input values and - // sets the output to result. The result type might be a single field for simple - // returns, a slice of interfaces for anonymous returns and a struct for named - // returns. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...) - } - - // Transfer initiates a plain transaction to move funds to the contract, calling - // its default method if one is available. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts) - } - - // Transact invokes the (paid) contract method with params as input values. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...) - } - - // Call invokes the (constant) contract method with params as input values and - // sets the output to result. The result type might be a single field for simple - // returns, a slice of interfaces for anonymous returns and a struct for named - // returns. - func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...) - } - - // Transfer initiates a plain transaction to move funds to the contract, calling - // its default method if one is available. - func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.contract.Transfer(opts) - } - - // Transact invokes the (paid) contract method with params as input values. - func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) - } - - {{range .Calls}} - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { - var out []interface{} - err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - {{if .Structured}} - outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) - if err != nil { - return *outstruct, err - } - {{range $i, $t := .Normalized.Outputs}} - outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} - - return *outstruct, err - {{else}} - if err != nil { - return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err - } - {{range $i, $t := .Normalized.Outputs}} - out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} - - return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err - {{end}} - } - - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - {{end}} - - {{range .Transacts}} - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) - } - {{end}} - - {{if .Fallback}} - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.RawTransact(opts, calldata) - } - - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) - } - - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) - } - {{end}} - - {{if .Receive}} - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function - } - - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) - } - - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) - } - {{end}} - - {{range .Events}} - // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract. - type {{$contract.Type}}{{.Normalized.Name}}Iterator struct { - Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration - } - // Next advances the iterator to the subsequent event, returning whether there - // are any more events found. In case of a retrieval or parsing error, false is - // returned and Error() can be queried for the exact failure. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool { - // If the iterator failed, stop iterating - if (it.fail != nil) { - return false - } - // If the iterator completed, deliver directly whatever's available - if (it.done) { - select { - case log := <-it.logs: - it.Event = new({{$contract.Type}}{{.Normalized.Name}}) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new({{$contract.Type}}{{.Normalized.Name}}) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } - } - // Error returns any retrieval or parsing error occurred during filtering. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error { - return it.fail - } - // Close terminates the iteration process, releasing any pending underlying - // resources. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error { - it.sub.Unsubscribe() - return nil - } - - // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract. - type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}} - {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}} - Raw types.Log // Blockchain specific contextual infos - } - - // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { - {{range .Normalized.Inputs}} - {{if .Indexed}}var {{.Name}}Rule []interface{} - for _, {{.Name}}Item := range {{.Name}} { - {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) - }{{end}}{{end}} - - logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) - if err != nil { - return nil, err - } - return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil - } - - // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { - {{range .Normalized.Inputs}} - {{if .Indexed}}var {{.Name}}Rule []interface{} - for _, {{.Name}}Item := range {{.Name}} { - {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) - }{{end}}{{end}} - - logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new({{$contract.Type}}{{.Normalized.Name}}) - if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil - } - - // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { - event := new({{$contract.Type}}{{.Normalized.Name}}) - if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil - } - - {{end}} -{{end}} -` +// +//go:embed source.go.tpl +var tmplSourceGo string diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 592465f2ac..04d1bb63bc 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -82,7 +82,9 @@ func TestWaitDeployed(t *testing.T) { }() // Send and mine the transaction. - backend.Client().SendTransaction(ctx, tx) + if err := backend.Client().SendTransaction(ctx, tx); err != nil { + t.Errorf("test %q: failed to send transaction: %v", name, err) + } backend.Commit() select { @@ -116,7 +118,9 @@ func TestWaitDeployedCornerCases(t *testing.T) { tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - backend.Client().SendTransaction(ctx, tx) + if err := backend.Client().SendTransaction(ctx, tx); err != nil { + t.Errorf("failed to send transaction: %q", err) + } backend.Commit() notContractCreation := errors.New("tx is not contract creation") if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() { @@ -134,6 +138,8 @@ func TestWaitDeployedCornerCases(t *testing.T) { } }() - backend.Client().SendTransaction(ctx, tx) + if err := backend.Client().SendTransaction(ctx, tx); err != nil { + t.Errorf("failed to send transaction: %q", err) + } cancel() } diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 1863e5bb7d..729ca93c54 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -24,7 +24,7 @@ import ( "strings" ) -// ConvertType converts an interface of a runtime type into a interface of the +// ConvertType converts an interface of a runtime type into an interface of the // given type, e.g. turn this code: // // var fields []reflect.StructField @@ -33,7 +33,7 @@ import ( // Name: "X", // Type: reflect.TypeOf(new(big.Int)), // Tag: reflect.StructTag("json:\"" + "x" + "\""), -// } +// }) // // into: // diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 2eee11787f..e59456f15a 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -64,6 +64,9 @@ type Type struct { var ( // typeRegex parses the abi sub types typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?") + + // sliceSizeRegex grab the slice size + sliceSizeRegex = regexp.MustCompile("[0-9]+") ) // NewType creates a new reflection type of abi type given in t. @@ -91,8 +94,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty // grab the last cell and create a type from there sliced := t[i:] // grab the slice size with regexp - re := regexp.MustCompile("[0-9]+") - intz := re.FindAllString(sliced, -1) + intz := sliceSizeRegex.FindAllString(sliced, -1) if len(intz) == 0 { // is a slice @@ -179,9 +181,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty return Type{}, errors.New("abi: purely anonymous or underscored field is not supported") } fieldName := ResolveNameConflict(name, func(s string) bool { return used[s] }) - if err != nil { - return Type{}, err - } used[fieldName] = true if !isValidFieldName(fieldName) { return Type{}, fmt.Errorf("field %d has invalid name", idx) @@ -220,7 +219,12 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty typ.T = FunctionTy typ.Size = 24 default: - return Type{}, fmt.Errorf("unsupported arg type: %s", t) + if strings.HasPrefix(internalType, "contract ") { + typ.Size = 20 + typ.T = AddressTy + } else { + return Type{}, fmt.Errorf("unsupported arg type: %s", t) + } } return diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index ae69872ad8..95922548c4 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -25,7 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// typeWithoutStringer is a alias for the Type type which simply doesn't implement +// typeWithoutStringer is an alias for the Type type which simply doesn't implement // the stringer interface to allow printing type details in the tests below. type typeWithoutStringer Type diff --git a/accounts/accounts.go b/accounts/accounts.go index 3f1b1b59b0..714f4f196e 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -196,7 +196,7 @@ func TextHash(data []byte) []byte { // // This gives context to the signed message and prevents signing of transactions. func TextAndHash(data []byte) ([]byte, string) { - msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data)) + msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) hasher := sha3.NewLegacyKeccak256() hasher.Write([]byte(msg)) return hasher.Sum(nil), msg diff --git a/accounts/external/backend.go b/accounts/external/backend.go index 12de26b09e..d2fcf5a3c9 100644 --- a/accounts/external/backend.go +++ b/accounts/external/backend.go @@ -205,7 +205,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio to = &t } args := &apitypes.SendTxArgs{ - Data: &data, + Input: &data, Nonce: hexutil.Uint64(tx.Nonce()), Value: hexutil.Big(*tx.Value()), Gas: hexutil.Uint64(tx.Gas()), @@ -215,7 +215,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio switch tx.Type() { case types.LegacyTxType, types.AccessListTxType: args.GasPrice = (*hexutil.Big)(tx.GasPrice()) - case types.DynamicFeeTxType: + case types.DynamicFeeTxType, types.BlobTxType: args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) default: @@ -235,6 +235,17 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio accessList := tx.AccessList() args.AccessList = &accessList } + if tx.Type() == types.BlobTxType { + args.BlobHashes = tx.BlobHashes() + sidecar := tx.BlobTxSidecar() + if sidecar == nil { + return nil, errors.New("blobs must be present for signing") + } + args.Blobs = sidecar.Blobs + args.Commitments = sidecar.Commitments + args.Proofs = sidecar.Proofs + } + var res signTransactionResult if err := api.client.Call(&res, "account_signTransaction", args); err != nil { return nil, err diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index 4ed1439514..f7cf688e62 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "sort" "strings" "sync" @@ -31,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/slices" ) // Minimum amount of time between cache reloads. This limit applies if the platform does diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 6b4f50512b..837e4fb043 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -23,6 +23,7 @@ import ( "os" "path/filepath" "reflect" + "slices" "testing" "time" @@ -30,7 +31,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "golang.org/x/exp/slices" ) var ( @@ -86,7 +86,7 @@ func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { func TestWatchNewFile(t *testing.T) { t.Parallel() - dir, ks := tmpKeyStore(t, false) + dir, ks := tmpKeyStore(t) // Ensure the watcher is started before adding any files. ks.Accounts() @@ -114,7 +114,7 @@ func TestWatchNewFile(t *testing.T) { func TestWatchNoDir(t *testing.T) { t.Parallel() // Create ks but not the directory that it watches. - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) + dir := filepath.Join(t.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() if len(list) > 0 { @@ -126,7 +126,6 @@ func TestWatchNoDir(t *testing.T) { } // Create the directory and copy a key file into it. os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) file := filepath.Join(dir, "aaa") if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil { t.Fatal(err) @@ -325,7 +324,8 @@ func TestUpdatedKeyfileContents(t *testing.T) { t.Parallel() // Create a temporary keystore to test with - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) + dir := t.TempDir() + ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() @@ -335,9 +335,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { if !waitWatcherStart(ks) { t.Fatal("keystore watcher didn't start in time") } - // Create the directory and copy a key file into it. - os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) + // Copy a key file into it file := filepath.Join(dir, "aaa") // Place one of our testfiles in there diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 0ffcf376a5..df3dda60b6 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -87,15 +87,6 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { return ks } -// NewPlaintextKeyStore creates a keystore for the given directory. -// Deprecated: Use NewKeyStore. -func NewPlaintextKeyStore(keydir string) *KeyStore { - keydir, _ = filepath.Abs(keydir) - ks := &KeyStore{storage: &keyStorePlain{keydir}} - ks.init(keydir) - return ks -} - func (ks *KeyStore) init(keydir string) { // Lock the mutex since the account cache might call back with events ks.mu.Lock() @@ -321,11 +312,10 @@ func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error { // Lock removes the private key with the given address from memory. func (ks *KeyStore) Lock(addr common.Address) error { ks.mu.Lock() - if unl, found := ks.unlocked[addr]; found { - ks.mu.Unlock() + unl, found := ks.unlocked[addr] + ks.mu.Unlock() + if found { ks.expire(addr, unl, time.Duration(0)*time.Nanosecond) - } else { - ks.mu.Unlock() } return nil } @@ -509,7 +499,5 @@ func (ks *KeyStore) isUpdating() bool { // zeroKey zeroes a private key in memory. func zeroKey(k *ecdsa.PrivateKey) { b := k.D.Bits() - for i := range b { - b[i] = 0 - } + clear(b) } diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 74ad9801e0..f8922a3f3f 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -20,6 +20,7 @@ import ( "math/rand" "os" "runtime" + "slices" "strings" "sync" "sync/atomic" @@ -30,14 +31,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" - "golang.org/x/exp/slices" ) var testSigData = make([]byte, 32) func TestKeyStore(t *testing.T) { t.Parallel() - dir, ks := tmpKeyStore(t, true) + dir, ks := tmpKeyStore(t) a, err := ks.NewAccount("foo") if err != nil { @@ -72,7 +72,7 @@ func TestKeyStore(t *testing.T) { func TestSign(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "" // not used but required by API a1, err := ks.NewAccount(pass) @@ -89,7 +89,7 @@ func TestSign(t *testing.T) { func TestSignWithPassphrase(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "passwd" acc, err := ks.NewAccount(pass) @@ -117,7 +117,7 @@ func TestSignWithPassphrase(t *testing.T) { func TestTimedUnlock(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "foo" a1, err := ks.NewAccount(pass) @@ -152,7 +152,7 @@ func TestTimedUnlock(t *testing.T) { func TestOverrideUnlock(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) pass := "foo" a1, err := ks.NewAccount(pass) @@ -193,7 +193,7 @@ func TestOverrideUnlock(t *testing.T) { // This test should fail under -race if signing races the expiration goroutine. func TestSignRace(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Create a test account. a1, err := ks.NewAccount("") @@ -238,7 +238,7 @@ func waitForKsUpdating(t *testing.T, ks *KeyStore, wantStatus bool, maxTime time func TestWalletNotifierLifecycle(t *testing.T) { t.Parallel() // Create a temporary keystore to test with - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Ensure that the notification updater is not running yet time.Sleep(250 * time.Millisecond) @@ -284,7 +284,7 @@ type walletEvent struct { // or deleted from the keystore. func TestWalletNotifications(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Subscribe to the wallet feed and collect events. var ( @@ -346,7 +346,7 @@ func TestWalletNotifications(t *testing.T) { // TestImportECDSA tests the import functionality of a keystore. func TestImportECDSA(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate key: %v", key) @@ -365,7 +365,7 @@ func TestImportECDSA(t *testing.T) { // TestImportExport tests the import and export functionality of a keystore. func TestImportExport(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -374,7 +374,7 @@ func TestImportExport(t *testing.T) { if err != nil { t.Fatalf("failed to export account: %v", acc) } - _, ks2 := tmpKeyStore(t, true) + _, ks2 := tmpKeyStore(t) if _, err = ks2.Import(json, "old", "old"); err == nil { t.Errorf("importing with invalid password succeeded") } @@ -394,7 +394,7 @@ func TestImportExport(t *testing.T) { // This test should fail under -race if importing races. func TestImportRace(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -403,7 +403,7 @@ func TestImportRace(t *testing.T) { if err != nil { t.Fatalf("failed to export account: %v", acc) } - _, ks2 := tmpKeyStore(t, true) + _, ks2 := tmpKeyStore(t) var atom atomic.Uint32 var wg sync.WaitGroup wg.Add(2) @@ -457,11 +457,7 @@ func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { } } -func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { +func tmpKeyStore(t *testing.T) (string, *KeyStore) { d := t.TempDir() - newKs := NewPlaintextKeyStore - if encrypted { - newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } - } - return d, newKs(d) + return d, NewKeyStore(d, veryLightScryptN, veryLightScryptP) } diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index 5f1f369ca2..1b1899dc8e 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -95,6 +95,7 @@ func (hub *Hub) readPairings() error { } return err } + defer pairingFile.Close() pairingData, err := io.ReadAll(pairingFile) if err != nil { diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index 4414713f06..b3a7be8df0 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -20,7 +20,6 @@ import ( "bytes" "crypto/aes" "crypto/cipher" - "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/sha512" @@ -72,11 +71,11 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes if err != nil { return nil, fmt.Errorf("could not unmarshal public key from card: %v", err) } - secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) //nolint:all //TODO + secret, _ := crypto.S256().ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) return &SecureChannelSession{ card: card, secret: secret.Bytes(), - publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y), //nolint:all //TODO + publicKey: crypto.FromECDSAPub(&key.PublicKey), }, nil } diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index f0ca9085b6..58cfc88301 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -73,6 +73,14 @@ var ( DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes()) ) +var ( + // PinRegexp is the regular expression used to validate PIN codes. + pinRegexp = regexp.MustCompile(`^[0-9]{6,}$`) + + // PukRegexp is the regular expression used to validate PUK codes. + pukRegexp = regexp.MustCompile(`^[0-9]{12,}$`) +) + // List of APDU command-related constants const ( claISO7816 = 0 @@ -380,7 +388,7 @@ func (w *Wallet) Open(passphrase string) error { case passphrase == "": return ErrPINUnblockNeeded case status.PinRetryCount > 0: - if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) { + if !pinRegexp.MatchString(passphrase) { w.log.Error("PIN needs to be at least 6 digits") return ErrPINNeeded } @@ -388,7 +396,7 @@ func (w *Wallet) Open(passphrase string) error { return err } default: - if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) { + if !pukRegexp.MatchString(passphrase) { w.log.Error("PUK needs to be at least 12 digits") return ErrPINUnblockNeeded } diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index e67942dbc1..e22dffe971 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -26,7 +26,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" - "github.com/karalabe/usb" + "github.com/karalabe/hid" ) // LedgerScheme is the protocol scheme prefixing account and wallet URLs. @@ -109,7 +109,7 @@ func NewTrezorHubWithWebUSB() (*Hub, error) { // newHub creates a new hardware wallet manager for generic USB devices. func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) { - if !usb.Supported() { + if !hid.Supported() { return nil, errors.New("unsupported platform") } hub := &Hub{ @@ -155,7 +155,7 @@ func (hub *Hub) refreshWallets() { return } // Retrieve the current list of USB wallet devices - var devices []usb.DeviceInfo + var devices []hid.DeviceInfo if runtime.GOOS == "linux" { // hidapi on Linux opens the device during enumeration to retrieve some infos, @@ -170,7 +170,7 @@ func (hub *Hub) refreshWallets() { return } } - infos, err := usb.Enumerate(hub.vendorID, 0) + infos, err := hid.Enumerate(hub.vendorID, 0) if err != nil { failcount := hub.enumFails.Add(1) if runtime.GOOS == "linux" { diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index d0cb93e74e..81836b3717 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -16,7 +16,7 @@ // This file contains the implementation for interacting with the Ledger hardware // wallets. The wire protocol spec can be found in the Ledger Blue GitHub repo: -// https://raw.githubusercontent.com/LedgerHQ/blue-app-eth/master/doc/ethapp.asc +// https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc package usbwallet diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 9644dc4e02..1c4270d255 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In diff --git a/accounts/usbwallet/trezor/messages-common.pb.go b/accounts/usbwallet/trezor/messages-common.pb.go index b396c6d8b5..73800802bb 100644 --- a/accounts/usbwallet/trezor/messages-common.pb.go +++ b/accounts/usbwallet/trezor/messages-common.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: messages-common.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type Failure_FailureType int32 @@ -39,37 +42,39 @@ const ( Failure_Failure_FirmwareError Failure_FailureType = 99 ) -var Failure_FailureType_name = map[int32]string{ - 1: "Failure_UnexpectedMessage", - 2: "Failure_ButtonExpected", - 3: "Failure_DataError", - 4: "Failure_ActionCancelled", - 5: "Failure_PinExpected", - 6: "Failure_PinCancelled", - 7: "Failure_PinInvalid", - 8: "Failure_InvalidSignature", - 9: "Failure_ProcessError", - 10: "Failure_NotEnoughFunds", - 11: "Failure_NotInitialized", - 12: "Failure_PinMismatch", - 99: "Failure_FirmwareError", -} - -var Failure_FailureType_value = map[string]int32{ - "Failure_UnexpectedMessage": 1, - "Failure_ButtonExpected": 2, - "Failure_DataError": 3, - "Failure_ActionCancelled": 4, - "Failure_PinExpected": 5, - "Failure_PinCancelled": 6, - "Failure_PinInvalid": 7, - "Failure_InvalidSignature": 8, - "Failure_ProcessError": 9, - "Failure_NotEnoughFunds": 10, - "Failure_NotInitialized": 11, - "Failure_PinMismatch": 12, - "Failure_FirmwareError": 99, -} +// Enum value maps for Failure_FailureType. +var ( + Failure_FailureType_name = map[int32]string{ + 1: "Failure_UnexpectedMessage", + 2: "Failure_ButtonExpected", + 3: "Failure_DataError", + 4: "Failure_ActionCancelled", + 5: "Failure_PinExpected", + 6: "Failure_PinCancelled", + 7: "Failure_PinInvalid", + 8: "Failure_InvalidSignature", + 9: "Failure_ProcessError", + 10: "Failure_NotEnoughFunds", + 11: "Failure_NotInitialized", + 12: "Failure_PinMismatch", + 99: "Failure_FirmwareError", + } + Failure_FailureType_value = map[string]int32{ + "Failure_UnexpectedMessage": 1, + "Failure_ButtonExpected": 2, + "Failure_DataError": 3, + "Failure_ActionCancelled": 4, + "Failure_PinExpected": 5, + "Failure_PinCancelled": 6, + "Failure_PinInvalid": 7, + "Failure_InvalidSignature": 8, + "Failure_ProcessError": 9, + "Failure_NotEnoughFunds": 10, + "Failure_NotInitialized": 11, + "Failure_PinMismatch": 12, + "Failure_FirmwareError": 99, + } +) func (x Failure_FailureType) Enum() *Failure_FailureType { p := new(Failure_FailureType) @@ -78,20 +83,34 @@ func (x Failure_FailureType) Enum() *Failure_FailureType { } func (x Failure_FailureType) String() string { - return proto.EnumName(Failure_FailureType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Failure_FailureType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[0].Descriptor() +} + +func (Failure_FailureType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[0] +} + +func (x Failure_FailureType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (x *Failure_FailureType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Failure_FailureType_value, data, "Failure_FailureType") +// Deprecated: Do not use. +func (x *Failure_FailureType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = Failure_FailureType(value) + *x = Failure_FailureType(num) return nil } +// Deprecated: Use Failure_FailureType.Descriptor instead. func (Failure_FailureType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{1, 0} + return file_messages_common_proto_rawDescGZIP(), []int{1, 0} } // * @@ -116,41 +135,43 @@ const ( ButtonRequest_ButtonRequest_UnknownDerivationPath ButtonRequest_ButtonRequestType = 15 ) -var ButtonRequest_ButtonRequestType_name = map[int32]string{ - 1: "ButtonRequest_Other", - 2: "ButtonRequest_FeeOverThreshold", - 3: "ButtonRequest_ConfirmOutput", - 4: "ButtonRequest_ResetDevice", - 5: "ButtonRequest_ConfirmWord", - 6: "ButtonRequest_WipeDevice", - 7: "ButtonRequest_ProtectCall", - 8: "ButtonRequest_SignTx", - 9: "ButtonRequest_FirmwareCheck", - 10: "ButtonRequest_Address", - 11: "ButtonRequest_PublicKey", - 12: "ButtonRequest_MnemonicWordCount", - 13: "ButtonRequest_MnemonicInput", - 14: "ButtonRequest_PassphraseType", - 15: "ButtonRequest_UnknownDerivationPath", -} - -var ButtonRequest_ButtonRequestType_value = map[string]int32{ - "ButtonRequest_Other": 1, - "ButtonRequest_FeeOverThreshold": 2, - "ButtonRequest_ConfirmOutput": 3, - "ButtonRequest_ResetDevice": 4, - "ButtonRequest_ConfirmWord": 5, - "ButtonRequest_WipeDevice": 6, - "ButtonRequest_ProtectCall": 7, - "ButtonRequest_SignTx": 8, - "ButtonRequest_FirmwareCheck": 9, - "ButtonRequest_Address": 10, - "ButtonRequest_PublicKey": 11, - "ButtonRequest_MnemonicWordCount": 12, - "ButtonRequest_MnemonicInput": 13, - "ButtonRequest_PassphraseType": 14, - "ButtonRequest_UnknownDerivationPath": 15, -} +// Enum value maps for ButtonRequest_ButtonRequestType. +var ( + ButtonRequest_ButtonRequestType_name = map[int32]string{ + 1: "ButtonRequest_Other", + 2: "ButtonRequest_FeeOverThreshold", + 3: "ButtonRequest_ConfirmOutput", + 4: "ButtonRequest_ResetDevice", + 5: "ButtonRequest_ConfirmWord", + 6: "ButtonRequest_WipeDevice", + 7: "ButtonRequest_ProtectCall", + 8: "ButtonRequest_SignTx", + 9: "ButtonRequest_FirmwareCheck", + 10: "ButtonRequest_Address", + 11: "ButtonRequest_PublicKey", + 12: "ButtonRequest_MnemonicWordCount", + 13: "ButtonRequest_MnemonicInput", + 14: "ButtonRequest_PassphraseType", + 15: "ButtonRequest_UnknownDerivationPath", + } + ButtonRequest_ButtonRequestType_value = map[string]int32{ + "ButtonRequest_Other": 1, + "ButtonRequest_FeeOverThreshold": 2, + "ButtonRequest_ConfirmOutput": 3, + "ButtonRequest_ResetDevice": 4, + "ButtonRequest_ConfirmWord": 5, + "ButtonRequest_WipeDevice": 6, + "ButtonRequest_ProtectCall": 7, + "ButtonRequest_SignTx": 8, + "ButtonRequest_FirmwareCheck": 9, + "ButtonRequest_Address": 10, + "ButtonRequest_PublicKey": 11, + "ButtonRequest_MnemonicWordCount": 12, + "ButtonRequest_MnemonicInput": 13, + "ButtonRequest_PassphraseType": 14, + "ButtonRequest_UnknownDerivationPath": 15, + } +) func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType { p := new(ButtonRequest_ButtonRequestType) @@ -159,20 +180,34 @@ func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType } func (x ButtonRequest_ButtonRequestType) String() string { - return proto.EnumName(ButtonRequest_ButtonRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ButtonRequest_ButtonRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[1].Descriptor() +} + +func (ButtonRequest_ButtonRequestType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[1] +} + +func (x ButtonRequest_ButtonRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ButtonRequest_ButtonRequestType_value, data, "ButtonRequest_ButtonRequestType") +// Deprecated: Do not use. +func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = ButtonRequest_ButtonRequestType(value) + *x = ButtonRequest_ButtonRequestType(num) return nil } +// Deprecated: Use ButtonRequest_ButtonRequestType.Descriptor instead. func (ButtonRequest_ButtonRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{2, 0} + return file_messages_common_proto_rawDescGZIP(), []int{2, 0} } // * @@ -185,17 +220,19 @@ const ( PinMatrixRequest_PinMatrixRequestType_NewSecond PinMatrixRequest_PinMatrixRequestType = 3 ) -var PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ - 1: "PinMatrixRequestType_Current", - 2: "PinMatrixRequestType_NewFirst", - 3: "PinMatrixRequestType_NewSecond", -} - -var PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ - "PinMatrixRequestType_Current": 1, - "PinMatrixRequestType_NewFirst": 2, - "PinMatrixRequestType_NewSecond": 3, -} +// Enum value maps for PinMatrixRequest_PinMatrixRequestType. +var ( + PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ + 1: "PinMatrixRequestType_Current", + 2: "PinMatrixRequestType_NewFirst", + 3: "PinMatrixRequestType_NewSecond", + } + PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ + "PinMatrixRequestType_Current": 1, + "PinMatrixRequestType_NewFirst": 2, + "PinMatrixRequestType_NewSecond": 3, + } +) func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatrixRequestType { p := new(PinMatrixRequest_PinMatrixRequestType) @@ -204,60 +241,82 @@ func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatri } func (x PinMatrixRequest_PinMatrixRequestType) String() string { - return proto.EnumName(PinMatrixRequest_PinMatrixRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PinMatrixRequest_PinMatrixRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[2].Descriptor() +} + +func (PinMatrixRequest_PinMatrixRequestType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[2] } -func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(PinMatrixRequest_PinMatrixRequestType_value, data, "PinMatrixRequest_PinMatrixRequestType") +func (x PinMatrixRequest_PinMatrixRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = PinMatrixRequest_PinMatrixRequestType(value) + *x = PinMatrixRequest_PinMatrixRequestType(num) return nil } +// Deprecated: Use PinMatrixRequest_PinMatrixRequestType.Descriptor instead. func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{4, 0} + return file_messages_common_proto_rawDescGZIP(), []int{4, 0} } // * // Response: Success of the previous request // @end type Success struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Success) Reset() { *m = Success{} } -func (m *Success) String() string { return proto.CompactTextString(m) } -func (*Success) ProtoMessage() {} -func (*Success) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{0} + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` // human readable description of action or request-specific payload } -func (m *Success) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Success.Unmarshal(m, b) -} -func (m *Success) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Success.Marshal(b, m, deterministic) -} -func (m *Success) XXX_Merge(src proto.Message) { - xxx_messageInfo_Success.Merge(m, src) +func (x *Success) Reset() { + *x = Success{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Success) XXX_Size() int { - return xxx_messageInfo_Success.Size(m) + +func (x *Success) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Success) XXX_DiscardUnknown() { - xxx_messageInfo_Success.DiscardUnknown(m) + +func (*Success) ProtoMessage() {} + +func (x *Success) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Success proto.InternalMessageInfo +// Deprecated: Use Success.ProtoReflect.Descriptor instead. +func (*Success) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{0} +} -func (m *Success) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Success) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } @@ -266,48 +325,56 @@ func (m *Success) GetMessage() string { // Response: Failure of the previous request // @end type Failure struct { - Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` - Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Failure) Reset() { *m = Failure{} } -func (m *Failure) String() string { return proto.CompactTextString(m) } -func (*Failure) ProtoMessage() {} -func (*Failure) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{1} + Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` // computer-readable definition of the error state + Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` // human-readable message of the error state } -func (m *Failure) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Failure.Unmarshal(m, b) -} -func (m *Failure) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Failure.Marshal(b, m, deterministic) -} -func (m *Failure) XXX_Merge(src proto.Message) { - xxx_messageInfo_Failure.Merge(m, src) +func (x *Failure) Reset() { + *x = Failure{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Failure) XXX_Size() int { - return xxx_messageInfo_Failure.Size(m) + +func (x *Failure) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Failure) XXX_DiscardUnknown() { - xxx_messageInfo_Failure.DiscardUnknown(m) + +func (*Failure) ProtoMessage() {} + +func (x *Failure) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Failure proto.InternalMessageInfo +// Deprecated: Use Failure.ProtoReflect.Descriptor instead. +func (*Failure) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{1} +} -func (m *Failure) GetCode() Failure_FailureType { - if m != nil && m.Code != nil { - return *m.Code +func (x *Failure) GetCode() Failure_FailureType { + if x != nil && x.Code != nil { + return *x.Code } return Failure_Failure_UnexpectedMessage } -func (m *Failure) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Failure) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } @@ -317,48 +384,56 @@ func (m *Failure) GetMessage() string { // @auxstart // @next ButtonAck type ButtonRequest struct { - Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` - Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } -func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } -func (*ButtonRequest) ProtoMessage() {} -func (*ButtonRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{2} + Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` + Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` } -func (m *ButtonRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonRequest.Unmarshal(m, b) -} -func (m *ButtonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonRequest.Marshal(b, m, deterministic) -} -func (m *ButtonRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonRequest.Merge(m, src) +func (x *ButtonRequest) Reset() { + *x = ButtonRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ButtonRequest) XXX_Size() int { - return xxx_messageInfo_ButtonRequest.Size(m) + +func (x *ButtonRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ButtonRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonRequest.DiscardUnknown(m) + +func (*ButtonRequest) ProtoMessage() {} + +func (x *ButtonRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ButtonRequest proto.InternalMessageInfo +// Deprecated: Use ButtonRequest.ProtoReflect.Descriptor instead. +func (*ButtonRequest) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{2} +} -func (m *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { - if m != nil && m.Code != nil { - return *m.Code +func (x *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { + if x != nil && x.Code != nil { + return *x.Code } return ButtonRequest_ButtonRequest_Other } -func (m *ButtonRequest) GetData() string { - if m != nil && m.Data != nil { - return *m.Data +func (x *ButtonRequest) GetData() string { + if x != nil && x.Data != nil { + return *x.Data } return "" } @@ -367,75 +442,90 @@ func (m *ButtonRequest) GetData() string { // Request: Computer agrees to wait for HW button press // @auxend type ButtonAck struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *ButtonAck) Reset() { *m = ButtonAck{} } -func (m *ButtonAck) String() string { return proto.CompactTextString(m) } -func (*ButtonAck) ProtoMessage() {} -func (*ButtonAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{3} +func (x *ButtonAck) Reset() { + *x = ButtonAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ButtonAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonAck.Unmarshal(m, b) -} -func (m *ButtonAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonAck.Marshal(b, m, deterministic) -} -func (m *ButtonAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonAck.Merge(m, src) -} -func (m *ButtonAck) XXX_Size() int { - return xxx_messageInfo_ButtonAck.Size(m) +func (x *ButtonAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ButtonAck) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonAck.DiscardUnknown(m) + +func (*ButtonAck) ProtoMessage() {} + +func (x *ButtonAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ButtonAck proto.InternalMessageInfo +// Deprecated: Use ButtonAck.ProtoReflect.Descriptor instead. +func (*ButtonAck) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{3} +} // * // Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme // @auxstart // @next PinMatrixAck type PinMatrixRequest struct { - Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } -func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } -func (*PinMatrixRequest) ProtoMessage() {} -func (*PinMatrixRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{4} + Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` } -func (m *PinMatrixRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixRequest.Unmarshal(m, b) -} -func (m *PinMatrixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixRequest.Marshal(b, m, deterministic) -} -func (m *PinMatrixRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixRequest.Merge(m, src) +func (x *PinMatrixRequest) Reset() { + *x = PinMatrixRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PinMatrixRequest) XXX_Size() int { - return xxx_messageInfo_PinMatrixRequest.Size(m) + +func (x *PinMatrixRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PinMatrixRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixRequest.DiscardUnknown(m) + +func (*PinMatrixRequest) ProtoMessage() {} + +func (x *PinMatrixRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PinMatrixRequest proto.InternalMessageInfo +// Deprecated: Use PinMatrixRequest.ProtoReflect.Descriptor instead. +func (*PinMatrixRequest) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{4} +} -func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { - if m != nil && m.Type != nil { - return *m.Type +func (x *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { + if x != nil && x.Type != nil { + return *x.Type } return PinMatrixRequest_PinMatrixRequestType_Current } @@ -444,40 +534,48 @@ func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { // Request: Computer responds with encoded PIN // @auxend type PinMatrixAck struct { - Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } -func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } -func (*PinMatrixAck) ProtoMessage() {} -func (*PinMatrixAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{5} + Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` // matrix encoded PIN entered by user } -func (m *PinMatrixAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixAck.Unmarshal(m, b) -} -func (m *PinMatrixAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixAck.Marshal(b, m, deterministic) -} -func (m *PinMatrixAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixAck.Merge(m, src) +func (x *PinMatrixAck) Reset() { + *x = PinMatrixAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PinMatrixAck) XXX_Size() int { - return xxx_messageInfo_PinMatrixAck.Size(m) + +func (x *PinMatrixAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PinMatrixAck) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixAck.DiscardUnknown(m) + +func (*PinMatrixAck) ProtoMessage() {} + +func (x *PinMatrixAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PinMatrixAck proto.InternalMessageInfo +// Deprecated: Use PinMatrixAck.ProtoReflect.Descriptor instead. +func (*PinMatrixAck) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{5} +} -func (m *PinMatrixAck) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin +func (x *PinMatrixAck) GetPin() string { + if x != nil && x.Pin != nil { + return *x.Pin } return "" } @@ -487,40 +585,48 @@ func (m *PinMatrixAck) GetPin() string { // @auxstart // @next PassphraseAck type PassphraseRequest struct { - OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } -func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseRequest) ProtoMessage() {} -func (*PassphraseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{6} + OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` // passphrase is being entered on the device } -func (m *PassphraseRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseRequest.Unmarshal(m, b) -} -func (m *PassphraseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseRequest.Marshal(b, m, deterministic) -} -func (m *PassphraseRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseRequest.Merge(m, src) +func (x *PassphraseRequest) Reset() { + *x = PassphraseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PassphraseRequest) XXX_Size() int { - return xxx_messageInfo_PassphraseRequest.Size(m) + +func (x *PassphraseRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PassphraseRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseRequest.DiscardUnknown(m) + +func (*PassphraseRequest) ProtoMessage() {} + +func (x *PassphraseRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PassphraseRequest proto.InternalMessageInfo +// Deprecated: Use PassphraseRequest.ProtoReflect.Descriptor instead. +func (*PassphraseRequest) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{6} +} -func (m *PassphraseRequest) GetOnDevice() bool { - if m != nil && m.OnDevice != nil { - return *m.OnDevice +func (x *PassphraseRequest) GetOnDevice() bool { + if x != nil && x.OnDevice != nil { + return *x.OnDevice } return false } @@ -529,48 +635,56 @@ func (m *PassphraseRequest) GetOnDevice() bool { // Request: Send passphrase back // @next PassphraseStateRequest type PassphraseAck struct { - Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` - State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } -func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseAck) ProtoMessage() {} -func (*PassphraseAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{7} + Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` // expected device state } -func (m *PassphraseAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseAck.Unmarshal(m, b) -} -func (m *PassphraseAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseAck.Marshal(b, m, deterministic) -} -func (m *PassphraseAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseAck.Merge(m, src) +func (x *PassphraseAck) Reset() { + *x = PassphraseAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PassphraseAck) XXX_Size() int { - return xxx_messageInfo_PassphraseAck.Size(m) + +func (x *PassphraseAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PassphraseAck) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseAck.DiscardUnknown(m) + +func (*PassphraseAck) ProtoMessage() {} + +func (x *PassphraseAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PassphraseAck proto.InternalMessageInfo +// Deprecated: Use PassphraseAck.ProtoReflect.Descriptor instead. +func (*PassphraseAck) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{7} +} -func (m *PassphraseAck) GetPassphrase() string { - if m != nil && m.Passphrase != nil { - return *m.Passphrase +func (x *PassphraseAck) GetPassphrase() string { + if x != nil && x.Passphrase != nil { + return *x.Passphrase } return "" } -func (m *PassphraseAck) GetState() []byte { - if m != nil { - return m.State +func (x *PassphraseAck) GetState() []byte { + if x != nil { + return x.State } return nil } @@ -579,40 +693,48 @@ func (m *PassphraseAck) GetState() []byte { // Response: Device awaits passphrase state // @next PassphraseStateAck type PassphraseStateRequest struct { - State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PassphraseStateRequest) Reset() { *m = PassphraseStateRequest{} } -func (m *PassphraseStateRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseStateRequest) ProtoMessage() {} -func (*PassphraseStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{8} + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // actual device state } -func (m *PassphraseStateRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseStateRequest.Unmarshal(m, b) -} -func (m *PassphraseStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseStateRequest.Marshal(b, m, deterministic) -} -func (m *PassphraseStateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseStateRequest.Merge(m, src) +func (x *PassphraseStateRequest) Reset() { + *x = PassphraseStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PassphraseStateRequest) XXX_Size() int { - return xxx_messageInfo_PassphraseStateRequest.Size(m) + +func (x *PassphraseStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PassphraseStateRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseStateRequest.DiscardUnknown(m) + +func (*PassphraseStateRequest) ProtoMessage() {} + +func (x *PassphraseStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PassphraseStateRequest proto.InternalMessageInfo +// Deprecated: Use PassphraseStateRequest.ProtoReflect.Descriptor instead. +func (*PassphraseStateRequest) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{8} +} -func (m *PassphraseStateRequest) GetState() []byte { - if m != nil { - return m.State +func (x *PassphraseStateRequest) GetState() []byte { + if x != nil { + return x.State } return nil } @@ -621,191 +743,456 @@ func (m *PassphraseStateRequest) GetState() []byte { // Request: Send passphrase state back // @auxend type PassphraseStateAck struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *PassphraseStateAck) Reset() { *m = PassphraseStateAck{} } -func (m *PassphraseStateAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseStateAck) ProtoMessage() {} -func (*PassphraseStateAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{9} +func (x *PassphraseStateAck) Reset() { + *x = PassphraseStateAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PassphraseStateAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseStateAck.Unmarshal(m, b) -} -func (m *PassphraseStateAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseStateAck.Marshal(b, m, deterministic) -} -func (m *PassphraseStateAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseStateAck.Merge(m, src) -} -func (m *PassphraseStateAck) XXX_Size() int { - return xxx_messageInfo_PassphraseStateAck.Size(m) +func (x *PassphraseStateAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PassphraseStateAck) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseStateAck.DiscardUnknown(m) + +func (*PassphraseStateAck) ProtoMessage() {} + +func (x *PassphraseStateAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PassphraseStateAck proto.InternalMessageInfo +// Deprecated: Use PassphraseStateAck.ProtoReflect.Descriptor instead. +func (*PassphraseStateAck) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{9} +} // * // Structure representing BIP32 (hierarchical deterministic) node // Used for imports of private key into the device and exporting public key out of device // @embed type HDNodeType struct { - Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` - Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` - ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` - ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` - PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` - PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *HDNodeType) Reset() { *m = HDNodeType{} } -func (m *HDNodeType) String() string { return proto.CompactTextString(m) } -func (*HDNodeType) ProtoMessage() {} -func (*HDNodeType) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{10} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` + Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` + ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` + ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` + PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` + PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` +} + +func (x *HDNodeType) Reset() { + *x = HDNodeType{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *HDNodeType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HDNodeType.Unmarshal(m, b) -} -func (m *HDNodeType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HDNodeType.Marshal(b, m, deterministic) -} -func (m *HDNodeType) XXX_Merge(src proto.Message) { - xxx_messageInfo_HDNodeType.Merge(m, src) -} -func (m *HDNodeType) XXX_Size() int { - return xxx_messageInfo_HDNodeType.Size(m) +func (x *HDNodeType) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *HDNodeType) XXX_DiscardUnknown() { - xxx_messageInfo_HDNodeType.DiscardUnknown(m) + +func (*HDNodeType) ProtoMessage() {} + +func (x *HDNodeType) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_HDNodeType proto.InternalMessageInfo +// Deprecated: Use HDNodeType.ProtoReflect.Descriptor instead. +func (*HDNodeType) Descriptor() ([]byte, []int) { + return file_messages_common_proto_rawDescGZIP(), []int{10} +} -func (m *HDNodeType) GetDepth() uint32 { - if m != nil && m.Depth != nil { - return *m.Depth +func (x *HDNodeType) GetDepth() uint32 { + if x != nil && x.Depth != nil { + return *x.Depth } return 0 } -func (m *HDNodeType) GetFingerprint() uint32 { - if m != nil && m.Fingerprint != nil { - return *m.Fingerprint +func (x *HDNodeType) GetFingerprint() uint32 { + if x != nil && x.Fingerprint != nil { + return *x.Fingerprint } return 0 } -func (m *HDNodeType) GetChildNum() uint32 { - if m != nil && m.ChildNum != nil { - return *m.ChildNum +func (x *HDNodeType) GetChildNum() uint32 { + if x != nil && x.ChildNum != nil { + return *x.ChildNum } return 0 } -func (m *HDNodeType) GetChainCode() []byte { - if m != nil { - return m.ChainCode +func (x *HDNodeType) GetChainCode() []byte { + if x != nil { + return x.ChainCode } return nil } -func (m *HDNodeType) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey +func (x *HDNodeType) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey } return nil } -func (m *HDNodeType) GetPublicKey() []byte { - if m != nil { - return m.PublicKey +func (x *HDNodeType) GetPublicKey() []byte { + if x != nil { + return x.PublicKey } return nil } -func init() { - proto.RegisterEnum("hw.trezor.messages.common.Failure_FailureType", Failure_FailureType_name, Failure_FailureType_value) - proto.RegisterEnum("hw.trezor.messages.common.ButtonRequest_ButtonRequestType", ButtonRequest_ButtonRequestType_name, ButtonRequest_ButtonRequestType_value) - proto.RegisterEnum("hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType", PinMatrixRequest_PinMatrixRequestType_name, PinMatrixRequest_PinMatrixRequestType_value) - proto.RegisterType((*Success)(nil), "hw.trezor.messages.common.Success") - proto.RegisterType((*Failure)(nil), "hw.trezor.messages.common.Failure") - proto.RegisterType((*ButtonRequest)(nil), "hw.trezor.messages.common.ButtonRequest") - proto.RegisterType((*ButtonAck)(nil), "hw.trezor.messages.common.ButtonAck") - proto.RegisterType((*PinMatrixRequest)(nil), "hw.trezor.messages.common.PinMatrixRequest") - proto.RegisterType((*PinMatrixAck)(nil), "hw.trezor.messages.common.PinMatrixAck") - proto.RegisterType((*PassphraseRequest)(nil), "hw.trezor.messages.common.PassphraseRequest") - proto.RegisterType((*PassphraseAck)(nil), "hw.trezor.messages.common.PassphraseAck") - proto.RegisterType((*PassphraseStateRequest)(nil), "hw.trezor.messages.common.PassphraseStateRequest") - proto.RegisterType((*PassphraseStateAck)(nil), "hw.trezor.messages.common.PassphraseStateAck") - proto.RegisterType((*HDNodeType)(nil), "hw.trezor.messages.common.HDNodeType") -} - -func init() { proto.RegisterFile("messages-common.proto", fileDescriptor_aaf30d059fdbc38d) } - -var fileDescriptor_aaf30d059fdbc38d = []byte{ - // 846 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x52, 0x23, 0x37, - 0x10, 0x2e, 0xff, 0x80, 0xed, 0xb6, 0xd9, 0x08, 0xc5, 0x80, 0x09, 0xb0, 0x38, 0xc3, 0x21, 0x5c, - 0xe2, 0x4a, 0xe5, 0x98, 0x53, 0x58, 0x83, 0x2b, 0xd4, 0x16, 0x86, 0x1a, 0xd8, 0xda, 0xa3, 0x4b, - 0xd1, 0xf4, 0x32, 0x2a, 0xcf, 0x48, 0x13, 0x8d, 0x06, 0xf0, 0x5e, 0xf2, 0x6a, 0x79, 0x89, 0xbc, - 0x42, 0xaa, 0x52, 0xb9, 0xe4, 0x11, 0xb6, 0x34, 0x3f, 0x78, 0xc6, 0x66, 0x39, 0xcd, 0xe8, 0xfb, - 0xbe, 0xee, 0x96, 0xba, 0x3f, 0x09, 0x76, 0x42, 0x8c, 0x63, 0x76, 0x8f, 0xf1, 0x8f, 0x5c, 0x85, - 0xa1, 0x92, 0xa3, 0x48, 0x2b, 0xa3, 0xe8, 0xbe, 0xff, 0x38, 0x32, 0x1a, 0x3f, 0x2b, 0x3d, 0x2a, - 0x04, 0xa3, 0x4c, 0xe0, 0x9c, 0x40, 0xeb, 0x36, 0xe1, 0x1c, 0xe3, 0x98, 0x0e, 0xa0, 0x95, 0xb3, - 0x83, 0xda, 0xb0, 0x76, 0xda, 0x71, 0x8b, 0xa5, 0xf3, 0x77, 0x03, 0x5a, 0x13, 0x26, 0x82, 0x44, - 0x23, 0x7d, 0x07, 0x4d, 0xae, 0xbc, 0x4c, 0xf2, 0xe6, 0xe7, 0xd1, 0xe8, 0xab, 0xa9, 0x47, 0x79, - 0x44, 0xf1, 0xbd, 0x5b, 0x44, 0xe8, 0xa6, 0xb1, 0xe5, 0x4a, 0xf5, 0x6a, 0xa5, 0xff, 0xea, 0xd0, - 0x2d, 0xe9, 0xe9, 0x11, 0xec, 0xe7, 0xcb, 0xd9, 0x07, 0x89, 0x4f, 0x11, 0x72, 0x83, 0xde, 0x55, - 0x26, 0x26, 0x35, 0xfa, 0x1d, 0xec, 0x16, 0xf4, 0xbb, 0xc4, 0x18, 0x25, 0x2f, 0x72, 0x09, 0xa9, - 0xd3, 0x1d, 0xd8, 0x2e, 0xb8, 0x73, 0x66, 0xd8, 0x85, 0xd6, 0x4a, 0x93, 0x06, 0x3d, 0x80, 0xbd, - 0x02, 0x3e, 0xe3, 0x46, 0x28, 0x39, 0x66, 0x92, 0x63, 0x10, 0xa0, 0x47, 0x9a, 0x74, 0x0f, 0xbe, - 0x2d, 0xc8, 0x1b, 0xb1, 0x4c, 0xb6, 0x41, 0x07, 0xd0, 0x2f, 0x11, 0xcb, 0x90, 0x4d, 0xba, 0x0b, - 0xb4, 0xc4, 0x5c, 0xca, 0x07, 0x16, 0x08, 0x8f, 0xb4, 0xe8, 0x21, 0x0c, 0x0a, 0x3c, 0x07, 0x6f, - 0xc5, 0xbd, 0x64, 0x26, 0xd1, 0x48, 0xda, 0x95, 0x7c, 0x5a, 0xd9, 0xf6, 0x67, 0xfb, 0xeb, 0x94, - 0x8f, 0x34, 0x55, 0xe6, 0x42, 0xaa, 0xe4, 0xde, 0x9f, 0x24, 0xd2, 0x8b, 0x09, 0xac, 0x70, 0x97, - 0x52, 0x18, 0xc1, 0x02, 0xf1, 0x19, 0x3d, 0xd2, 0x5d, 0xd9, 0xfa, 0x95, 0x88, 0x43, 0x66, 0xb8, - 0x4f, 0x7a, 0x74, 0x1f, 0x76, 0x0a, 0x62, 0x22, 0x74, 0xf8, 0xc8, 0x34, 0x66, 0xb5, 0xb8, 0xf3, - 0x4f, 0x13, 0xb6, 0xb2, 0xbe, 0xb9, 0xf8, 0x47, 0x82, 0xb1, 0xa1, 0xd3, 0xca, 0x74, 0x7f, 0x79, - 0x65, 0xba, 0x95, 0xb8, 0xea, 0xaa, 0x34, 0x69, 0x0a, 0x4d, 0x8f, 0x19, 0x96, 0x8f, 0x39, 0xfd, - 0x77, 0xfe, 0x6f, 0xc0, 0xf6, 0x9a, 0xde, 0xee, 0xbf, 0x02, 0xce, 0xae, 0x8d, 0x8f, 0x9a, 0xd4, - 0xa8, 0x03, 0x6f, 0xab, 0xc4, 0x04, 0xf1, 0xfa, 0x01, 0xf5, 0x9d, 0xaf, 0x31, 0xf6, 0x55, 0x60, - 0x67, 0x7d, 0x0c, 0x07, 0x55, 0xcd, 0x58, 0xc9, 0x4f, 0x42, 0x87, 0xd7, 0x89, 0x89, 0x12, 0x43, - 0x1a, 0xd6, 0x47, 0x55, 0x81, 0x8b, 0x31, 0x9a, 0x73, 0x7c, 0x10, 0x1c, 0x49, 0x73, 0x9d, 0xce, - 0xe3, 0x3f, 0x2a, 0x6d, 0xa7, 0x7f, 0x08, 0x83, 0x2a, 0xfd, 0x51, 0x44, 0x98, 0x07, 0x6f, 0xae, - 0x07, 0xdf, 0x68, 0x65, 0x90, 0x9b, 0x31, 0x0b, 0x02, 0xd2, 0xb2, 0xa3, 0xae, 0xd2, 0xd6, 0x07, - 0x77, 0x4f, 0xa4, 0xbd, 0xbe, 0xeb, 0x62, 0x3e, 0x63, 0x1f, 0xf9, 0x9c, 0x74, 0xec, 0xe8, 0xaa, - 0x82, 0x33, 0xcf, 0xd3, 0x18, 0x5b, 0x2b, 0x1c, 0xc0, 0xde, 0x4a, 0xd1, 0xe4, 0xf7, 0x40, 0xf0, - 0xf7, 0xb8, 0x20, 0x5d, 0x7a, 0x02, 0xc7, 0x55, 0xf2, 0x4a, 0x62, 0xa8, 0xa4, 0xe0, 0xf6, 0x3c, - 0x63, 0x95, 0x48, 0x43, 0x7a, 0xeb, 0xd5, 0x0b, 0xd1, 0xa5, 0xb4, 0x3d, 0xdb, 0xa2, 0x43, 0x38, - 0x5c, 0x29, 0xc1, 0xe2, 0x38, 0xf2, 0x35, 0x8b, 0xd3, 0xbb, 0x49, 0xde, 0xd0, 0x1f, 0xe0, 0xa4, - 0xaa, 0xf8, 0x20, 0xe7, 0x52, 0x3d, 0xca, 0x73, 0xd4, 0xe2, 0x81, 0xd9, 0xcb, 0x75, 0xc3, 0x8c, - 0x4f, 0xbe, 0x71, 0xba, 0xd0, 0xc9, 0x84, 0x67, 0x7c, 0xee, 0xfc, 0x5b, 0x03, 0x62, 0x2d, 0xca, - 0x8c, 0x16, 0x4f, 0x85, 0xf1, 0xee, 0xa0, 0x69, 0x16, 0x51, 0x61, 0xbc, 0x5f, 0x5f, 0x31, 0xde, - 0x6a, 0xe8, 0x1a, 0x90, 0xd9, 0xcf, 0x66, 0x73, 0xfe, 0x84, 0xfe, 0x4b, 0xac, 0x3d, 0xda, 0x4b, - 0xf8, 0x6c, 0x9c, 0x68, 0x8d, 0xd2, 0x90, 0x1a, 0xfd, 0x1e, 0x8e, 0x5e, 0x54, 0x4c, 0xf1, 0x71, - 0x22, 0x74, 0x6c, 0x48, 0xdd, 0x1a, 0xf3, 0x6b, 0x92, 0x5b, 0xe4, 0x4a, 0x7a, 0xa4, 0xe1, 0x0c, - 0xa1, 0xf7, 0xac, 0x39, 0xe3, 0x73, 0x4a, 0xa0, 0x11, 0x09, 0x39, 0xa8, 0x0d, 0xeb, 0xa7, 0x1d, - 0xd7, 0xfe, 0x3a, 0x3f, 0xc1, 0xf6, 0xb2, 0xaf, 0x45, 0x37, 0x0e, 0xa0, 0xa3, 0xe4, 0xcc, 0x4b, - 0x1d, 0x96, 0xb6, 0xa4, 0xed, 0xb6, 0x95, 0xcc, 0x1c, 0xe7, 0x5c, 0xc0, 0xd6, 0x32, 0xc2, 0x26, - 0x7d, 0x0b, 0x10, 0x3d, 0x03, 0xf9, 0xdb, 0x5d, 0x42, 0x68, 0x1f, 0x36, 0x62, 0xc3, 0x4c, 0xf6, - 0xd8, 0xf6, 0xdc, 0x6c, 0xe1, 0x8c, 0x60, 0x77, 0x99, 0xe6, 0xd6, 0x42, 0x45, 0xf5, 0x67, 0x7d, - 0xad, 0xac, 0xef, 0x03, 0x5d, 0xd1, 0xdb, 0x61, 0xfe, 0x55, 0x03, 0xf8, 0xed, 0x7c, 0xaa, 0xbc, - 0xec, 0xbd, 0xee, 0xc3, 0x86, 0x87, 0x91, 0xf1, 0xd3, 0x13, 0x6e, 0xb9, 0xd9, 0x82, 0x0e, 0xa1, - 0xfb, 0x49, 0xc8, 0x7b, 0xd4, 0x91, 0x16, 0xd2, 0x0c, 0xea, 0x29, 0x57, 0x86, 0xec, 0x81, 0xb9, - 0x2f, 0x02, 0x6f, 0x26, 0x93, 0x70, 0xd0, 0x48, 0xf9, 0x76, 0x0a, 0x4c, 0x93, 0x90, 0x1e, 0x01, - 0x70, 0x9f, 0x09, 0x39, 0x4b, 0x9f, 0xa6, 0xe6, 0xb0, 0x7e, 0xda, 0x73, 0x3b, 0x29, 0x32, 0xb6, - 0x6f, 0xcc, 0x31, 0x74, 0xa3, 0xd4, 0x6f, 0x38, 0x9b, 0xe3, 0x62, 0xb0, 0x91, 0x6e, 0x1a, 0x72, - 0xe8, 0x3d, 0x2e, 0x6c, 0x7c, 0x94, 0xde, 0x8e, 0x94, 0xdf, 0x4c, 0xf9, 0x4e, 0x54, 0xdc, 0x97, - 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x7d, 0x20, 0xa6, 0x35, 0x07, 0x00, 0x00, +var File_messages_common_proto protoreflect.FileDescriptor + +var file_messages_common_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, + 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x22, 0x23, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xd5, 0x03, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2e, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0xeb, 0x02, 0x0a, 0x0b, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x55, 0x6e, 0x65, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, + 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x44, 0x61, 0x74, 0x61, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x10, 0x04, + 0x12, 0x17, 0x0a, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x45, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, + 0x64, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, + 0x69, 0x6e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e, + 0x6f, 0x74, 0x45, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x46, 0x75, 0x6e, 0x64, 0x73, 0x10, 0x0a, 0x12, + 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e, 0x6f, 0x74, 0x49, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x10, 0x0b, 0x12, 0x17, 0x0a, 0x13, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x4d, 0x69, 0x73, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x10, 0x0c, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x63, 0x22, + 0xe6, 0x04, 0x0a, 0x0d, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x4e, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x3a, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf0, 0x03, 0x0a, 0x11, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4f, 0x74, 0x68, + 0x65, 0x72, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x46, 0x65, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x54, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x57, 0x6f, 0x72, 0x64, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x43, 0x61, + 0x6c, 0x6c, 0x10, 0x07, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x08, 0x12, 0x1f, + 0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x10, 0x09, 0x12, + 0x19, 0x0a, 0x15, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x0a, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, + 0x63, 0x57, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b, + 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e, + 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x10, 0x0d, 0x12, 0x20, 0x0a, + 0x1c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x0e, 0x12, + 0x27, 0x0a, 0x23, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x44, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x10, 0x0f, 0x22, 0x0b, 0x0a, 0x09, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x22, 0xe9, 0x01, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, + 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x7f, 0x0a, 0x14, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x69, 0x6e, 0x4d, + 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x69, + 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x46, 0x69, 0x72, 0x73, 0x74, 0x10, 0x02, 0x12, 0x22, 0x0a, + 0x1e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x10, + 0x03, 0x22, 0x20, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x41, 0x63, + 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, + 0x70, 0x69, 0x6e, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x6e, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x45, 0x0a, 0x0d, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x41, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, + 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2e, 0x0a, 0x16, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x14, 0x0a, 0x12, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, + 0x63, 0x6b, 0x22, 0xc0, 0x01, 0x0a, 0x0a, 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0d, + 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x0b, 0x66, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, 0x65, 0x7a, + 0x6f, 0x72, +} + +var ( + file_messages_common_proto_rawDescOnce sync.Once + file_messages_common_proto_rawDescData = file_messages_common_proto_rawDesc +) + +func file_messages_common_proto_rawDescGZIP() []byte { + file_messages_common_proto_rawDescOnce.Do(func() { + file_messages_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_common_proto_rawDescData) + }) + return file_messages_common_proto_rawDescData +} + +var file_messages_common_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_messages_common_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_messages_common_proto_goTypes = []any{ + (Failure_FailureType)(0), // 0: hw.trezor.messages.common.Failure.FailureType + (ButtonRequest_ButtonRequestType)(0), // 1: hw.trezor.messages.common.ButtonRequest.ButtonRequestType + (PinMatrixRequest_PinMatrixRequestType)(0), // 2: hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestType + (*Success)(nil), // 3: hw.trezor.messages.common.Success + (*Failure)(nil), // 4: hw.trezor.messages.common.Failure + (*ButtonRequest)(nil), // 5: hw.trezor.messages.common.ButtonRequest + (*ButtonAck)(nil), // 6: hw.trezor.messages.common.ButtonAck + (*PinMatrixRequest)(nil), // 7: hw.trezor.messages.common.PinMatrixRequest + (*PinMatrixAck)(nil), // 8: hw.trezor.messages.common.PinMatrixAck + (*PassphraseRequest)(nil), // 9: hw.trezor.messages.common.PassphraseRequest + (*PassphraseAck)(nil), // 10: hw.trezor.messages.common.PassphraseAck + (*PassphraseStateRequest)(nil), // 11: hw.trezor.messages.common.PassphraseStateRequest + (*PassphraseStateAck)(nil), // 12: hw.trezor.messages.common.PassphraseStateAck + (*HDNodeType)(nil), // 13: hw.trezor.messages.common.HDNodeType +} +var file_messages_common_proto_depIdxs = []int32{ + 0, // 0: hw.trezor.messages.common.Failure.code:type_name -> hw.trezor.messages.common.Failure.FailureType + 1, // 1: hw.trezor.messages.common.ButtonRequest.code:type_name -> hw.trezor.messages.common.ButtonRequest.ButtonRequestType + 2, // 2: hw.trezor.messages.common.PinMatrixRequest.type:type_name -> hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestType + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_messages_common_proto_init() } +func file_messages_common_proto_init() { + if File_messages_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_messages_common_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*Success); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*Failure); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ButtonRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*ButtonAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*PinMatrixRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*PinMatrixAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*PassphraseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*PassphraseAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*PassphraseStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*PassphraseStateAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*HDNodeType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_common_proto_rawDesc, + NumEnums: 3, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_common_proto_goTypes, + DependencyIndexes: file_messages_common_proto_depIdxs, + EnumInfos: file_messages_common_proto_enumTypes, + MessageInfos: file_messages_common_proto_msgTypes, + }.Build() + File_messages_common_proto = out.File + file_messages_common_proto_rawDesc = nil + file_messages_common_proto_goTypes = nil + file_messages_common_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-common.proto b/accounts/usbwallet/trezor/messages-common.proto index 75a983b0a3..1f524e25d7 100644 --- a/accounts/usbwallet/trezor/messages-common.proto +++ b/accounts/usbwallet/trezor/messages-common.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.common; +option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"; + /** * Response: Success of the previous request * @end diff --git a/accounts/usbwallet/trezor/messages-ethereum.pb.go b/accounts/usbwallet/trezor/messages-ethereum.pb.go index 230a48279d..a92123efcd 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.pb.go +++ b/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: messages-ethereum.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) // * // Request: Ask device for public key corresponding to address_n path @@ -27,48 +30,56 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // @next EthereumPublicKey // @next Failure type EthereumGetPublicKey struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumGetPublicKey) Reset() { *m = EthereumGetPublicKey{} } -func (m *EthereumGetPublicKey) String() string { return proto.CompactTextString(m) } -func (*EthereumGetPublicKey) ProtoMessage() {} -func (*EthereumGetPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{0} + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` // optionally show on display before sending the result } -func (m *EthereumGetPublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumGetPublicKey.Unmarshal(m, b) -} -func (m *EthereumGetPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumGetPublicKey.Marshal(b, m, deterministic) -} -func (m *EthereumGetPublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumGetPublicKey.Merge(m, src) +func (x *EthereumGetPublicKey) Reset() { + *x = EthereumGetPublicKey{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumGetPublicKey) XXX_Size() int { - return xxx_messageInfo_EthereumGetPublicKey.Size(m) + +func (x *EthereumGetPublicKey) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumGetPublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumGetPublicKey.DiscardUnknown(m) + +func (*EthereumGetPublicKey) ProtoMessage() {} + +func (x *EthereumGetPublicKey) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumGetPublicKey proto.InternalMessageInfo +// Deprecated: Use EthereumGetPublicKey.ProtoReflect.Descriptor instead. +func (*EthereumGetPublicKey) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{0} +} -func (m *EthereumGetPublicKey) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumGetPublicKey) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumGetPublicKey) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay +func (x *EthereumGetPublicKey) GetShowDisplay() bool { + if x != nil && x.ShowDisplay != nil { + return *x.ShowDisplay } return false } @@ -77,48 +88,56 @@ func (m *EthereumGetPublicKey) GetShowDisplay() bool { // Response: Contains public key derived from device private seed // @end type EthereumPublicKey struct { - Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` - Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumPublicKey) Reset() { *m = EthereumPublicKey{} } -func (m *EthereumPublicKey) String() string { return proto.CompactTextString(m) } -func (*EthereumPublicKey) ProtoMessage() {} -func (*EthereumPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{1} + Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` // BIP32 public node + Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` // serialized form of public node } -func (m *EthereumPublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumPublicKey.Unmarshal(m, b) -} -func (m *EthereumPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumPublicKey.Marshal(b, m, deterministic) -} -func (m *EthereumPublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumPublicKey.Merge(m, src) +func (x *EthereumPublicKey) Reset() { + *x = EthereumPublicKey{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumPublicKey) XXX_Size() int { - return xxx_messageInfo_EthereumPublicKey.Size(m) + +func (x *EthereumPublicKey) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumPublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumPublicKey.DiscardUnknown(m) + +func (*EthereumPublicKey) ProtoMessage() {} + +func (x *EthereumPublicKey) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumPublicKey proto.InternalMessageInfo +// Deprecated: Use EthereumPublicKey.ProtoReflect.Descriptor instead. +func (*EthereumPublicKey) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{1} +} -func (m *EthereumPublicKey) GetNode() *HDNodeType { - if m != nil { - return m.Node +func (x *EthereumPublicKey) GetNode() *HDNodeType { + if x != nil { + return x.Node } return nil } -func (m *EthereumPublicKey) GetXpub() string { - if m != nil && m.Xpub != nil { - return *m.Xpub +func (x *EthereumPublicKey) GetXpub() string { + if x != nil && x.Xpub != nil { + return *x.Xpub } return "" } @@ -129,48 +148,56 @@ func (m *EthereumPublicKey) GetXpub() string { // @next EthereumAddress // @next Failure type EthereumGetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } -func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumGetAddress) ProtoMessage() {} -func (*EthereumGetAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{2} + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` // optionally show on display before sending the result } -func (m *EthereumGetAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumGetAddress.Unmarshal(m, b) -} -func (m *EthereumGetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumGetAddress.Marshal(b, m, deterministic) -} -func (m *EthereumGetAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumGetAddress.Merge(m, src) +func (x *EthereumGetAddress) Reset() { + *x = EthereumGetAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumGetAddress) XXX_Size() int { - return xxx_messageInfo_EthereumGetAddress.Size(m) + +func (x *EthereumGetAddress) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumGetAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumGetAddress.DiscardUnknown(m) + +func (*EthereumGetAddress) ProtoMessage() {} + +func (x *EthereumGetAddress) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumGetAddress proto.InternalMessageInfo +// Deprecated: Use EthereumGetAddress.ProtoReflect.Descriptor instead. +func (*EthereumGetAddress) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{2} +} -func (m *EthereumGetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumGetAddress) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumGetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay +func (x *EthereumGetAddress) GetShowDisplay() bool { + if x != nil && x.ShowDisplay != nil { + return *x.ShowDisplay } return false } @@ -179,48 +206,56 @@ func (m *EthereumGetAddress) GetShowDisplay() bool { // Response: Contains an Ethereum address derived from device private seed // @end type EthereumAddress struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } -func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumAddress) ProtoMessage() {} -func (*EthereumAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{3} + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // Ethereum address as 20 bytes (legacy firmwares) + AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` // Ethereum address as hex string (newer firmwares) } -func (m *EthereumAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumAddress.Unmarshal(m, b) -} -func (m *EthereumAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumAddress.Marshal(b, m, deterministic) -} -func (m *EthereumAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumAddress.Merge(m, src) +func (x *EthereumAddress) Reset() { + *x = EthereumAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumAddress) XXX_Size() int { - return xxx_messageInfo_EthereumAddress.Size(m) + +func (x *EthereumAddress) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumAddress.DiscardUnknown(m) + +func (*EthereumAddress) ProtoMessage() {} + +func (x *EthereumAddress) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumAddress proto.InternalMessageInfo +// Deprecated: Use EthereumAddress.ProtoReflect.Descriptor instead. +func (*EthereumAddress) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{3} +} -func (m *EthereumAddress) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumAddress) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumAddress) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumAddress) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } @@ -233,120 +268,128 @@ func (m *EthereumAddress) GetAddressHex() string { // @next EthereumTxRequest // @next Failure type EthereumSignTx struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` - GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` - ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` - ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` - Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` - DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` - DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` - TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } -func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } -func (*EthereumSignTx) ProtoMessage() {} -func (*EthereumSignTx) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{4} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumSignTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignTx.Unmarshal(m, b) -} -func (m *EthereumSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignTx.Marshal(b, m, deterministic) + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` // <=256 bit unsigned big endian + GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` // <=256 bit unsigned big endian (in wei) + GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` // <=256 bit unsigned big endian + ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` // recipient address (20 bytes, legacy firmware) + ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` // recipient address (hex string, newer firmware) + Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` // <=256 bit unsigned big endian (in wei) + DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` // The initial data chunk (<= 1024 bytes) + DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` // Length of transaction payload + ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` // Chain Id for EIP 155 + TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` // (only for Wanchain) } -func (m *EthereumSignTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignTx.Merge(m, src) + +func (x *EthereumSignTx) Reset() { + *x = EthereumSignTx{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumSignTx) XXX_Size() int { - return xxx_messageInfo_EthereumSignTx.Size(m) + +func (x *EthereumSignTx) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumSignTx) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignTx.DiscardUnknown(m) + +func (*EthereumSignTx) ProtoMessage() {} + +func (x *EthereumSignTx) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumSignTx proto.InternalMessageInfo +// Deprecated: Use EthereumSignTx.ProtoReflect.Descriptor instead. +func (*EthereumSignTx) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{4} +} -func (m *EthereumSignTx) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumSignTx) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumSignTx) GetNonce() []byte { - if m != nil { - return m.Nonce +func (x *EthereumSignTx) GetNonce() []byte { + if x != nil { + return x.Nonce } return nil } -func (m *EthereumSignTx) GetGasPrice() []byte { - if m != nil { - return m.GasPrice +func (x *EthereumSignTx) GetGasPrice() []byte { + if x != nil { + return x.GasPrice } return nil } -func (m *EthereumSignTx) GetGasLimit() []byte { - if m != nil { - return m.GasLimit +func (x *EthereumSignTx) GetGasLimit() []byte { + if x != nil { + return x.GasLimit } return nil } -func (m *EthereumSignTx) GetToBin() []byte { - if m != nil { - return m.ToBin +func (x *EthereumSignTx) GetToBin() []byte { + if x != nil { + return x.ToBin } return nil } -func (m *EthereumSignTx) GetToHex() string { - if m != nil && m.ToHex != nil { - return *m.ToHex +func (x *EthereumSignTx) GetToHex() string { + if x != nil && x.ToHex != nil { + return *x.ToHex } return "" } -func (m *EthereumSignTx) GetValue() []byte { - if m != nil { - return m.Value +func (x *EthereumSignTx) GetValue() []byte { + if x != nil { + return x.Value } return nil } -func (m *EthereumSignTx) GetDataInitialChunk() []byte { - if m != nil { - return m.DataInitialChunk +func (x *EthereumSignTx) GetDataInitialChunk() []byte { + if x != nil { + return x.DataInitialChunk } return nil } -func (m *EthereumSignTx) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength +func (x *EthereumSignTx) GetDataLength() uint32 { + if x != nil && x.DataLength != nil { + return *x.DataLength } return 0 } -func (m *EthereumSignTx) GetChainId() uint32 { - if m != nil && m.ChainId != nil { - return *m.ChainId +func (x *EthereumSignTx) GetChainId() uint32 { + if x != nil && x.ChainId != nil { + return *x.ChainId } return 0 } -func (m *EthereumSignTx) GetTxType() uint32 { - if m != nil && m.TxType != nil { - return *m.TxType +func (x *EthereumSignTx) GetTxType() uint32 { + if x != nil && x.TxType != nil { + return *x.TxType } return 0 } @@ -358,64 +401,72 @@ func (m *EthereumSignTx) GetTxType() uint32 { // @end // @next EthereumTxAck type EthereumTxRequest struct { - DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` - SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` - SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } -func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } -func (*EthereumTxRequest) ProtoMessage() {} -func (*EthereumTxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{5} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumTxRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxRequest.Unmarshal(m, b) -} -func (m *EthereumTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxRequest.Marshal(b, m, deterministic) + DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` // Number of bytes being requested (<= 1024) + SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` // Computed signature (recovery parameter, limited to 27 or 28) + SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` // Computed signature R component (256 bit) + SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` // Computed signature S component (256 bit) } -func (m *EthereumTxRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxRequest.Merge(m, src) + +func (x *EthereumTxRequest) Reset() { + *x = EthereumTxRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumTxRequest) XXX_Size() int { - return xxx_messageInfo_EthereumTxRequest.Size(m) + +func (x *EthereumTxRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumTxRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxRequest.DiscardUnknown(m) + +func (*EthereumTxRequest) ProtoMessage() {} + +func (x *EthereumTxRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumTxRequest proto.InternalMessageInfo +// Deprecated: Use EthereumTxRequest.ProtoReflect.Descriptor instead. +func (*EthereumTxRequest) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{5} +} -func (m *EthereumTxRequest) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength +func (x *EthereumTxRequest) GetDataLength() uint32 { + if x != nil && x.DataLength != nil { + return *x.DataLength } return 0 } -func (m *EthereumTxRequest) GetSignatureV() uint32 { - if m != nil && m.SignatureV != nil { - return *m.SignatureV +func (x *EthereumTxRequest) GetSignatureV() uint32 { + if x != nil && x.SignatureV != nil { + return *x.SignatureV } return 0 } -func (m *EthereumTxRequest) GetSignatureR() []byte { - if m != nil { - return m.SignatureR +func (x *EthereumTxRequest) GetSignatureR() []byte { + if x != nil { + return x.SignatureR } return nil } -func (m *EthereumTxRequest) GetSignatureS() []byte { - if m != nil { - return m.SignatureS +func (x *EthereumTxRequest) GetSignatureS() []byte { + if x != nil { + return x.SignatureS } return nil } @@ -424,40 +475,48 @@ func (m *EthereumTxRequest) GetSignatureS() []byte { // Request: Transaction payload data. // @next EthereumTxRequest type EthereumTxAck struct { - DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } -func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } -func (*EthereumTxAck) ProtoMessage() {} -func (*EthereumTxAck) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{6} + DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` // Bytes from transaction payload (<= 1024 bytes) } -func (m *EthereumTxAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxAck.Unmarshal(m, b) -} -func (m *EthereumTxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxAck.Marshal(b, m, deterministic) -} -func (m *EthereumTxAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxAck.Merge(m, src) +func (x *EthereumTxAck) Reset() { + *x = EthereumTxAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumTxAck) XXX_Size() int { - return xxx_messageInfo_EthereumTxAck.Size(m) + +func (x *EthereumTxAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumTxAck) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxAck.DiscardUnknown(m) + +func (*EthereumTxAck) ProtoMessage() {} + +func (x *EthereumTxAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumTxAck proto.InternalMessageInfo +// Deprecated: Use EthereumTxAck.ProtoReflect.Descriptor instead. +func (*EthereumTxAck) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{6} +} -func (m *EthereumTxAck) GetDataChunk() []byte { - if m != nil { - return m.DataChunk +func (x *EthereumTxAck) GetDataChunk() []byte { + if x != nil { + return x.DataChunk } return nil } @@ -468,48 +527,56 @@ func (m *EthereumTxAck) GetDataChunk() []byte { // @next EthereumMessageSignature // @next Failure type EthereumSignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } -func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumSignMessage) ProtoMessage() {} -func (*EthereumSignMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{7} + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` // message to be signed } -func (m *EthereumSignMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignMessage.Unmarshal(m, b) -} -func (m *EthereumSignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignMessage.Marshal(b, m, deterministic) -} -func (m *EthereumSignMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignMessage.Merge(m, src) +func (x *EthereumSignMessage) Reset() { + *x = EthereumSignMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumSignMessage) XXX_Size() int { - return xxx_messageInfo_EthereumSignMessage.Size(m) + +func (x *EthereumSignMessage) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumSignMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignMessage.DiscardUnknown(m) + +func (*EthereumSignMessage) ProtoMessage() {} + +func (x *EthereumSignMessage) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumSignMessage proto.InternalMessageInfo +// Deprecated: Use EthereumSignMessage.ProtoReflect.Descriptor instead. +func (*EthereumSignMessage) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{7} +} -func (m *EthereumSignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumSignMessage) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumSignMessage) GetMessage() []byte { - if m != nil { - return m.Message +func (x *EthereumSignMessage) GetMessage() []byte { + if x != nil { + return x.Message } return nil } @@ -518,56 +585,64 @@ func (m *EthereumSignMessage) GetMessage() []byte { // Response: Signed message // @end type EthereumMessageSignature struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } -func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } -func (*EthereumMessageSignature) ProtoMessage() {} -func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{8} + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // address used to sign the message (20 bytes, legacy firmware) + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` // signature of the message + AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` // address used to sign the message (hex string, newer firmware) } -func (m *EthereumMessageSignature) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumMessageSignature.Unmarshal(m, b) -} -func (m *EthereumMessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumMessageSignature.Marshal(b, m, deterministic) -} -func (m *EthereumMessageSignature) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumMessageSignature.Merge(m, src) +func (x *EthereumMessageSignature) Reset() { + *x = EthereumMessageSignature{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumMessageSignature) XXX_Size() int { - return xxx_messageInfo_EthereumMessageSignature.Size(m) + +func (x *EthereumMessageSignature) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumMessageSignature) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumMessageSignature.DiscardUnknown(m) + +func (*EthereumMessageSignature) ProtoMessage() {} + +func (x *EthereumMessageSignature) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumMessageSignature proto.InternalMessageInfo +// Deprecated: Use EthereumMessageSignature.ProtoReflect.Descriptor instead. +func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{8} +} -func (m *EthereumMessageSignature) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumMessageSignature) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumMessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature +func (x *EthereumMessageSignature) GetSignature() []byte { + if x != nil { + return x.Signature } return nil } -func (m *EthereumMessageSignature) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumMessageSignature) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } @@ -578,121 +653,350 @@ func (m *EthereumMessageSignature) GetAddressHex() string { // @next Success // @next Failure type EthereumVerifyMessage struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } -func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumVerifyMessage) ProtoMessage() {} -func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{9} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EthereumVerifyMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumVerifyMessage.Unmarshal(m, b) -} -func (m *EthereumVerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumVerifyMessage.Marshal(b, m, deterministic) + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // address to verify (20 bytes, legacy firmware) + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` // signature to verify + Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` // message to verify + AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` // address to verify (hex string, newer firmware) } -func (m *EthereumVerifyMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumVerifyMessage.Merge(m, src) + +func (x *EthereumVerifyMessage) Reset() { + *x = EthereumVerifyMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EthereumVerifyMessage) XXX_Size() int { - return xxx_messageInfo_EthereumVerifyMessage.Size(m) + +func (x *EthereumVerifyMessage) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EthereumVerifyMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumVerifyMessage.DiscardUnknown(m) + +func (*EthereumVerifyMessage) ProtoMessage() {} + +func (x *EthereumVerifyMessage) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EthereumVerifyMessage proto.InternalMessageInfo +// Deprecated: Use EthereumVerifyMessage.ProtoReflect.Descriptor instead. +func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { + return file_messages_ethereum_proto_rawDescGZIP(), []int{9} +} -func (m *EthereumVerifyMessage) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumVerifyMessage) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumVerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature +func (x *EthereumVerifyMessage) GetSignature() []byte { + if x != nil { + return x.Signature } return nil } -func (m *EthereumVerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message +func (x *EthereumVerifyMessage) GetMessage() []byte { + if x != nil { + return x.Message } return nil } -func (m *EthereumVerifyMessage) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumVerifyMessage) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } -func init() { - proto.RegisterType((*EthereumGetPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumGetPublicKey") - proto.RegisterType((*EthereumPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumPublicKey") - proto.RegisterType((*EthereumGetAddress)(nil), "hw.trezor.messages.ethereum.EthereumGetAddress") - proto.RegisterType((*EthereumAddress)(nil), "hw.trezor.messages.ethereum.EthereumAddress") - proto.RegisterType((*EthereumSignTx)(nil), "hw.trezor.messages.ethereum.EthereumSignTx") - proto.RegisterType((*EthereumTxRequest)(nil), "hw.trezor.messages.ethereum.EthereumTxRequest") - proto.RegisterType((*EthereumTxAck)(nil), "hw.trezor.messages.ethereum.EthereumTxAck") - proto.RegisterType((*EthereumSignMessage)(nil), "hw.trezor.messages.ethereum.EthereumSignMessage") - proto.RegisterType((*EthereumMessageSignature)(nil), "hw.trezor.messages.ethereum.EthereumMessageSignature") - proto.RegisterType((*EthereumVerifyMessage)(nil), "hw.trezor.messages.ethereum.EthereumVerifyMessage") -} - -func init() { proto.RegisterFile("messages-ethereum.proto", fileDescriptor_cb33f46ba915f15c) } - -var fileDescriptor_cb33f46ba915f15c = []byte{ - // 593 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, - 0x10, 0x95, 0x9b, 0xb4, 0x49, 0x26, 0x0d, 0x1f, 0xa6, 0x55, 0x17, 0x0a, 0x34, 0x18, 0x21, 0xe5, - 0x00, 0x3e, 0x70, 0x43, 0xe2, 0xd2, 0x52, 0x44, 0x2b, 0x4a, 0x55, 0xdc, 0xa8, 0x57, 0x6b, 0x63, - 0x6f, 0xe3, 0x55, 0x9d, 0xdd, 0xe0, 0x5d, 0xb7, 0x0e, 0x7f, 0x82, 0x23, 0xff, 0x87, 0x5f, 0x86, - 0xf6, 0x2b, 0x71, 0x52, 0x54, 0x0e, 0xbd, 0x65, 0xde, 0xbc, 0x7d, 0xf3, 0x66, 0xf4, 0x62, 0xd8, - 0x99, 0x10, 0x21, 0xf0, 0x98, 0x88, 0x77, 0x44, 0x66, 0xa4, 0x20, 0xe5, 0x24, 0x9c, 0x16, 0x5c, - 0x72, 0x7f, 0x37, 0xbb, 0x09, 0x65, 0x41, 0x7e, 0xf2, 0x22, 0x74, 0x94, 0xd0, 0x51, 0x9e, 0x6d, - 0xcf, 0x5f, 0x25, 0x7c, 0x32, 0xe1, 0xcc, 0xbc, 0x09, 0x2e, 0x60, 0xeb, 0xb3, 0xa5, 0x7c, 0x21, - 0xf2, 0xac, 0x1c, 0xe5, 0x34, 0xf9, 0x4a, 0x66, 0xfe, 0x2e, 0x74, 0x70, 0x9a, 0x16, 0x44, 0x88, - 0x98, 0x21, 0xaf, 0xdf, 0x18, 0xf4, 0xa2, 0xb6, 0x05, 0x4e, 0xfd, 0x57, 0xb0, 0x29, 0x32, 0x7e, - 0x13, 0xa7, 0x54, 0x4c, 0x73, 0x3c, 0x43, 0x6b, 0x7d, 0x6f, 0xd0, 0x8e, 0xba, 0x0a, 0x3b, 0x34, - 0x50, 0x30, 0x82, 0xc7, 0x4e, 0x77, 0x21, 0xfa, 0x01, 0x9a, 0x8c, 0xa7, 0x04, 0x79, 0x7d, 0x6f, - 0xd0, 0x7d, 0xff, 0x26, 0xfc, 0x87, 0x5f, 0x6b, 0xee, 0xe8, 0xf0, 0x94, 0xa7, 0x64, 0x38, 0x9b, - 0x92, 0x48, 0x3f, 0xf1, 0x7d, 0x68, 0x56, 0xd3, 0x72, 0xa4, 0x47, 0x75, 0x22, 0xfd, 0x3b, 0x18, - 0x82, 0x5f, 0xf3, 0xbe, 0x6f, 0xdc, 0xdd, 0xdb, 0xf9, 0x77, 0x78, 0xe8, 0x54, 0x9d, 0xe4, 0x4b, - 0x00, 0xab, 0x70, 0x40, 0x99, 0x76, 0xbf, 0x19, 0xd5, 0x90, 0x5a, 0xff, 0x88, 0x54, 0xd6, 0x62, - 0x0d, 0x09, 0xfe, 0xac, 0xc1, 0x03, 0xa7, 0x79, 0x4e, 0xc7, 0x6c, 0x58, 0xdd, 0xed, 0x72, 0x0b, - 0xd6, 0x19, 0x67, 0x09, 0xd1, 0x52, 0x9b, 0x91, 0x29, 0xd4, 0x93, 0x31, 0x16, 0xf1, 0xb4, 0xa0, - 0x09, 0x41, 0x0d, 0xdd, 0x69, 0x8f, 0xb1, 0x38, 0x53, 0xb5, 0x6b, 0xe6, 0x74, 0x42, 0x25, 0x6a, - 0xce, 0x9b, 0x27, 0xaa, 0x56, 0x7a, 0x92, 0x2b, 0xeb, 0xeb, 0x46, 0x4f, 0x17, 0x06, 0x55, 0x86, - 0xbb, 0xda, 0xb0, 0x29, 0x14, 0x7a, 0x8d, 0xf3, 0x92, 0xa0, 0x0d, 0xc3, 0xd5, 0x85, 0xff, 0x16, - 0xfc, 0x14, 0x4b, 0x1c, 0x53, 0x46, 0x25, 0xc5, 0x79, 0x9c, 0x64, 0x25, 0xbb, 0x42, 0x2d, 0x4d, - 0x79, 0xa4, 0x3a, 0xc7, 0xa6, 0xf1, 0x49, 0xe1, 0xfe, 0x1e, 0x74, 0x35, 0x3b, 0x27, 0x6c, 0x2c, - 0x33, 0xd4, 0xee, 0x7b, 0x83, 0x5e, 0x04, 0x0a, 0x3a, 0xd1, 0x88, 0xff, 0x14, 0xda, 0x49, 0x86, - 0x29, 0x8b, 0x69, 0x8a, 0x3a, 0xba, 0xdb, 0xd2, 0xf5, 0x71, 0xea, 0xef, 0x40, 0x4b, 0x56, 0xb1, - 0x9c, 0x4d, 0x09, 0x02, 0xdd, 0xd9, 0x90, 0x95, 0xca, 0x41, 0xf0, 0xdb, 0x5b, 0x44, 0x6a, 0x58, - 0x45, 0xe4, 0x47, 0x49, 0x84, 0x5c, 0x1d, 0xe5, 0xdd, 0x1a, 0xb5, 0x07, 0x5d, 0x41, 0xc7, 0x0c, - 0xcb, 0xb2, 0x20, 0xf1, 0xb5, 0xbe, 0x68, 0x2f, 0x82, 0x39, 0x74, 0xb1, 0x4c, 0x28, 0xec, 0x61, - 0x17, 0x84, 0x68, 0x99, 0x20, 0xec, 0x71, 0x17, 0x84, 0xf3, 0x20, 0x84, 0xde, 0xc2, 0xd8, 0x7e, - 0x72, 0xe5, 0xbf, 0x00, 0xed, 0xc0, 0x5e, 0xc9, 0xe4, 0xa5, 0xa3, 0x10, 0x7d, 0x9e, 0xe0, 0x04, - 0x9e, 0xd4, 0xd3, 0xf0, 0xcd, 0x64, 0xff, 0xee, 0x48, 0x20, 0x68, 0xd9, 0xff, 0x88, 0x0d, 0x85, - 0x2b, 0x83, 0x0a, 0x90, 0x53, 0xb3, 0x4a, 0xe7, 0xce, 0xda, 0x7f, 0x83, 0xfb, 0x1c, 0x3a, 0xf3, - 0x3d, 0xac, 0xee, 0x02, 0x58, 0x89, 0x75, 0xe3, 0x56, 0xac, 0x7f, 0x79, 0xb0, 0xed, 0x46, 0x5f, - 0x90, 0x82, 0x5e, 0xce, 0xdc, 0x2a, 0xf7, 0x9b, 0x5b, 0xdb, 0xb5, 0xb1, 0xb4, 0xeb, 0x8a, 0xa3, - 0xe6, 0xaa, 0xa3, 0x83, 0x8f, 0xf0, 0x3a, 0xe1, 0x93, 0x50, 0x60, 0xc9, 0x45, 0x46, 0x73, 0x3c, - 0x12, 0xee, 0x03, 0x93, 0xd3, 0x91, 0xf9, 0xe2, 0x8d, 0xca, 0xcb, 0x83, 0xed, 0xa1, 0x06, 0xad, - 0x5b, 0xb7, 0xc2, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xce, 0x81, 0xc8, 0x59, 0x05, 0x00, - 0x00, +var File_messages_ethereum_proto protoreflect.FileDescriptor + +var file_messages_ethereum_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x1a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, + 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x77, 0x44, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, 0x62, 0x0a, 0x11, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, + 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x70, 0x75, 0x62, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x78, 0x70, 0x75, 0x62, 0x22, 0x54, 0x0a, 0x12, 0x45, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4e, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x77, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, + 0x51, 0x0a, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, + 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, + 0x65, 0x78, 0x22, 0xc2, 0x02, 0x0a, 0x0e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, + 0x69, 0x67, 0x6e, 0x54, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, + 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x42, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x42, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x48, 0x65, + 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x48, 0x65, 0x78, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x10, 0x64, 0x61, 0x74, 0x61, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x17, + 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x74, 0x78, 0x54, 0x79, 0x70, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x11, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, + 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x22, 0x2e, 0x0a, 0x0d, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x43, 0x68, 0x75, 0x6e, + 0x6b, 0x22, 0x4c, 0x0a, 0x13, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, 0x69, 0x67, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x78, 0x0a, 0x18, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x22, 0x8f, 0x01, 0x0a, 0x15, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x42, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x42, 0x77, 0x0a, 0x23, 0x63, + 0x6f, 0x6d, 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, + 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x42, 0x15, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, + 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, +} + +var ( + file_messages_ethereum_proto_rawDescOnce sync.Once + file_messages_ethereum_proto_rawDescData = file_messages_ethereum_proto_rawDesc +) + +func file_messages_ethereum_proto_rawDescGZIP() []byte { + file_messages_ethereum_proto_rawDescOnce.Do(func() { + file_messages_ethereum_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_ethereum_proto_rawDescData) + }) + return file_messages_ethereum_proto_rawDescData +} + +var file_messages_ethereum_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_messages_ethereum_proto_goTypes = []any{ + (*EthereumGetPublicKey)(nil), // 0: hw.trezor.messages.ethereum.EthereumGetPublicKey + (*EthereumPublicKey)(nil), // 1: hw.trezor.messages.ethereum.EthereumPublicKey + (*EthereumGetAddress)(nil), // 2: hw.trezor.messages.ethereum.EthereumGetAddress + (*EthereumAddress)(nil), // 3: hw.trezor.messages.ethereum.EthereumAddress + (*EthereumSignTx)(nil), // 4: hw.trezor.messages.ethereum.EthereumSignTx + (*EthereumTxRequest)(nil), // 5: hw.trezor.messages.ethereum.EthereumTxRequest + (*EthereumTxAck)(nil), // 6: hw.trezor.messages.ethereum.EthereumTxAck + (*EthereumSignMessage)(nil), // 7: hw.trezor.messages.ethereum.EthereumSignMessage + (*EthereumMessageSignature)(nil), // 8: hw.trezor.messages.ethereum.EthereumMessageSignature + (*EthereumVerifyMessage)(nil), // 9: hw.trezor.messages.ethereum.EthereumVerifyMessage + (*HDNodeType)(nil), // 10: hw.trezor.messages.common.HDNodeType +} +var file_messages_ethereum_proto_depIdxs = []int32{ + 10, // 0: hw.trezor.messages.ethereum.EthereumPublicKey.node:type_name -> hw.trezor.messages.common.HDNodeType + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_messages_ethereum_proto_init() } +func file_messages_ethereum_proto_init() { + if File_messages_ethereum_proto != nil { + return + } + file_messages_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_messages_ethereum_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*EthereumGetPublicKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*EthereumPublicKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*EthereumGetAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*EthereumAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*EthereumSignTx); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*EthereumTxRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*EthereumTxAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*EthereumSignMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*EthereumMessageSignature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*EthereumVerifyMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_ethereum_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_ethereum_proto_goTypes, + DependencyIndexes: file_messages_ethereum_proto_depIdxs, + MessageInfos: file_messages_ethereum_proto_msgTypes, + }.Build() + File_messages_ethereum_proto = out.File + file_messages_ethereum_proto_rawDesc = nil + file_messages_ethereum_proto_goTypes = nil + file_messages_ethereum_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-ethereum.proto b/accounts/usbwallet/trezor/messages-ethereum.proto index 096bed2e4a..8e1150abb6 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.proto +++ b/accounts/usbwallet/trezor/messages-ethereum.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.ethereum; +option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageEthereum"; diff --git a/accounts/usbwallet/trezor/messages-management.pb.go b/accounts/usbwallet/trezor/messages-management.pb.go index 91bfca1e3f..983e2d281d 100644 --- a/accounts/usbwallet/trezor/messages-management.pb.go +++ b/accounts/usbwallet/trezor/messages-management.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-management.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: messages-management.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) // * // Structure representing passphrase source @@ -31,17 +34,19 @@ const ( ApplySettings_HOST ApplySettings_PassphraseSourceType = 2 ) -var ApplySettings_PassphraseSourceType_name = map[int32]string{ - 0: "ASK", - 1: "DEVICE", - 2: "HOST", -} - -var ApplySettings_PassphraseSourceType_value = map[string]int32{ - "ASK": 0, - "DEVICE": 1, - "HOST": 2, -} +// Enum value maps for ApplySettings_PassphraseSourceType. +var ( + ApplySettings_PassphraseSourceType_name = map[int32]string{ + 0: "ASK", + 1: "DEVICE", + 2: "HOST", + } + ApplySettings_PassphraseSourceType_value = map[string]int32{ + "ASK": 0, + "DEVICE": 1, + "HOST": 2, + } +) func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSourceType { p := new(ApplySettings_PassphraseSourceType) @@ -50,20 +55,34 @@ func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSour } func (x ApplySettings_PassphraseSourceType) String() string { - return proto.EnumName(ApplySettings_PassphraseSourceType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ApplySettings_PassphraseSourceType_value, data, "ApplySettings_PassphraseSourceType") +func (ApplySettings_PassphraseSourceType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[0].Descriptor() +} + +func (ApplySettings_PassphraseSourceType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[0] +} + +func (x ApplySettings_PassphraseSourceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = ApplySettings_PassphraseSourceType(value) + *x = ApplySettings_PassphraseSourceType(num) return nil } +// Deprecated: Use ApplySettings_PassphraseSourceType.Descriptor instead. func (ApplySettings_PassphraseSourceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{4, 0} + return file_messages_management_proto_rawDescGZIP(), []int{4, 0} } // * @@ -77,19 +96,21 @@ type RecoveryDevice_RecoveryDeviceType int32 const ( // use powers of two when extending this field - RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 - RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 + RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 // words in scrambled order + RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 // matrix recovery type ) -var RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ - 0: "RecoveryDeviceType_ScrambledWords", - 1: "RecoveryDeviceType_Matrix", -} - -var RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ - "RecoveryDeviceType_ScrambledWords": 0, - "RecoveryDeviceType_Matrix": 1, -} +// Enum value maps for RecoveryDevice_RecoveryDeviceType. +var ( + RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ + 0: "RecoveryDeviceType_ScrambledWords", + 1: "RecoveryDeviceType_Matrix", + } + RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ + "RecoveryDeviceType_ScrambledWords": 0, + "RecoveryDeviceType_Matrix": 1, + } +) func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDeviceType { p := new(RecoveryDevice_RecoveryDeviceType) @@ -98,20 +119,34 @@ func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDevice } func (x RecoveryDevice_RecoveryDeviceType) String() string { - return proto.EnumName(RecoveryDevice_RecoveryDeviceType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RecoveryDevice_RecoveryDeviceType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[1].Descriptor() +} + +func (RecoveryDevice_RecoveryDeviceType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[1] } -func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RecoveryDevice_RecoveryDeviceType_value, data, "RecoveryDevice_RecoveryDeviceType") +func (x RecoveryDevice_RecoveryDeviceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = RecoveryDevice_RecoveryDeviceType(value) + *x = RecoveryDevice_RecoveryDeviceType(num) return nil } +// Deprecated: Use RecoveryDevice_RecoveryDeviceType.Descriptor instead. func (RecoveryDevice_RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{17, 0} + return file_messages_management_proto_rawDescGZIP(), []int{17, 0} } // * @@ -124,17 +159,19 @@ const ( WordRequest_WordRequestType_Matrix6 WordRequest_WordRequestType = 2 ) -var WordRequest_WordRequestType_name = map[int32]string{ - 0: "WordRequestType_Plain", - 1: "WordRequestType_Matrix9", - 2: "WordRequestType_Matrix6", -} - -var WordRequest_WordRequestType_value = map[string]int32{ - "WordRequestType_Plain": 0, - "WordRequestType_Matrix9": 1, - "WordRequestType_Matrix6": 2, -} +// Enum value maps for WordRequest_WordRequestType. +var ( + WordRequest_WordRequestType_name = map[int32]string{ + 0: "WordRequestType_Plain", + 1: "WordRequestType_Matrix9", + 2: "WordRequestType_Matrix6", + } + WordRequest_WordRequestType_value = map[string]int32{ + "WordRequestType_Plain": 0, + "WordRequestType_Matrix9": 1, + "WordRequestType_Matrix6": 2, + } +) func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { p := new(WordRequest_WordRequestType) @@ -143,20 +180,34 @@ func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { } func (x WordRequest_WordRequestType) String() string { - return proto.EnumName(WordRequest_WordRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *WordRequest_WordRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(WordRequest_WordRequestType_value, data, "WordRequest_WordRequestType") +func (WordRequest_WordRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[2].Descriptor() +} + +func (WordRequest_WordRequestType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[2] +} + +func (x WordRequest_WordRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WordRequest_WordRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = WordRequest_WordRequestType(value) + *x = WordRequest_WordRequestType(num) return nil } +// Deprecated: Use WordRequest_WordRequestType.Descriptor instead. func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{18, 0} + return file_messages_management_proto_rawDescGZIP(), []int{18, 0} } // * @@ -164,48 +215,56 @@ func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { // @start // @next Features type Initialize struct { - State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` - SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Initialize) Reset() { *m = Initialize{} } -func (m *Initialize) String() string { return proto.CompactTextString(m) } -func (*Initialize) ProtoMessage() {} -func (*Initialize) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{0} + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // assumed device state, clear session if set and different + SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` // this session should always assume empty passphrase } -func (m *Initialize) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Initialize.Unmarshal(m, b) -} -func (m *Initialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Initialize.Marshal(b, m, deterministic) -} -func (m *Initialize) XXX_Merge(src proto.Message) { - xxx_messageInfo_Initialize.Merge(m, src) +func (x *Initialize) Reset() { + *x = Initialize{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Initialize) XXX_Size() int { - return xxx_messageInfo_Initialize.Size(m) + +func (x *Initialize) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Initialize) XXX_DiscardUnknown() { - xxx_messageInfo_Initialize.DiscardUnknown(m) + +func (*Initialize) ProtoMessage() {} + +func (x *Initialize) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Initialize proto.InternalMessageInfo +// Deprecated: Use Initialize.ProtoReflect.Descriptor instead. +func (*Initialize) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{0} +} -func (m *Initialize) GetState() []byte { - if m != nil { - return m.State +func (x *Initialize) GetState() []byte { + if x != nil { + return x.State } return nil } -func (m *Initialize) GetSkipPassphrase() bool { - if m != nil && m.SkipPassphrase != nil { - return *m.SkipPassphrase +func (x *Initialize) GetSkipPassphrase() bool { + if x != nil && x.SkipPassphrase != nil { + return *x.SkipPassphrase } return false } @@ -215,282 +274,297 @@ func (m *Initialize) GetSkipPassphrase() bool { // @start // @next Features type GetFeatures struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *GetFeatures) Reset() { *m = GetFeatures{} } -func (m *GetFeatures) String() string { return proto.CompactTextString(m) } -func (*GetFeatures) ProtoMessage() {} -func (*GetFeatures) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{1} +func (x *GetFeatures) Reset() { + *x = GetFeatures{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *GetFeatures) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetFeatures.Unmarshal(m, b) -} -func (m *GetFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetFeatures.Marshal(b, m, deterministic) -} -func (m *GetFeatures) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetFeatures.Merge(m, src) -} -func (m *GetFeatures) XXX_Size() int { - return xxx_messageInfo_GetFeatures.Size(m) +func (x *GetFeatures) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *GetFeatures) XXX_DiscardUnknown() { - xxx_messageInfo_GetFeatures.DiscardUnknown(m) + +func (*GetFeatures) ProtoMessage() {} + +func (x *GetFeatures) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_GetFeatures proto.InternalMessageInfo +// Deprecated: Use GetFeatures.ProtoReflect.Descriptor instead. +func (*GetFeatures) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{1} +} // * // Response: Reports various information about the device // @end type Features struct { - Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` - MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` - MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` - PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` - BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` - DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` - PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` - Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` - Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` - BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` - Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` - PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` - PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` - FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` - NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` - Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` - Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` - FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` - FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` - FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` - FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` - FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` - UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` - NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Features) Reset() { *m = Features{} } -func (m *Features) String() string { return proto.CompactTextString(m) } -func (*Features) ProtoMessage() {} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` // name of the manufacturer, e.g. "trezor.io" + MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` // major version of the firmware/bootloader, e.g. 1 + MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` // minor version of the firmware/bootloader, e.g. 0 + PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` // patch version of the firmware/bootloader, e.g. 0 + BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` // is device in bootloader mode? + DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` // device's unique identifier + PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // is device protected by PIN? + PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // is node/mnemonic encrypted using passphrase? + Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` // device description label + Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` // does device contain seed? + Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` // SCM revision of firmware + BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` // hash of the bootloader + Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` // was storage imported from an external source? + PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` // is PIN already cached in session? + PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` // is passphrase already cached in session? + FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` // is valid firmware loaded? + NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` // does storage need backup? (equals to Storage.needs_backup) + Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` // device flags (equals to Storage.flags) + Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` // device hardware model + FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` // reported firmware version if in bootloader mode + FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` // reported firmware version if in bootloader mode + FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` // reported firmware version if in bootloader mode + FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` // reported firmware vendor if in bootloader mode + FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` // reported firmware vendor keys (their hash) + UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` // report unfinished backup (equals to Storage.unfinished_backup) + NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` // report no backup (equals to Storage.no_backup) +} + +func (x *Features) Reset() { + *x = Features{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Features) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Features) ProtoMessage() {} + +func (x *Features) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Features.ProtoReflect.Descriptor instead. func (*Features) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{2} -} - -func (m *Features) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Features.Unmarshal(m, b) -} -func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Features.Marshal(b, m, deterministic) + return file_messages_management_proto_rawDescGZIP(), []int{2} } -func (m *Features) XXX_Merge(src proto.Message) { - xxx_messageInfo_Features.Merge(m, src) -} -func (m *Features) XXX_Size() int { - return xxx_messageInfo_Features.Size(m) -} -func (m *Features) XXX_DiscardUnknown() { - xxx_messageInfo_Features.DiscardUnknown(m) -} - -var xxx_messageInfo_Features proto.InternalMessageInfo -func (m *Features) GetVendor() string { - if m != nil && m.Vendor != nil { - return *m.Vendor +func (x *Features) GetVendor() string { + if x != nil && x.Vendor != nil { + return *x.Vendor } return "" } -func (m *Features) GetMajorVersion() uint32 { - if m != nil && m.MajorVersion != nil { - return *m.MajorVersion +func (x *Features) GetMajorVersion() uint32 { + if x != nil && x.MajorVersion != nil { + return *x.MajorVersion } return 0 } -func (m *Features) GetMinorVersion() uint32 { - if m != nil && m.MinorVersion != nil { - return *m.MinorVersion +func (x *Features) GetMinorVersion() uint32 { + if x != nil && x.MinorVersion != nil { + return *x.MinorVersion } return 0 } -func (m *Features) GetPatchVersion() uint32 { - if m != nil && m.PatchVersion != nil { - return *m.PatchVersion +func (x *Features) GetPatchVersion() uint32 { + if x != nil && x.PatchVersion != nil { + return *x.PatchVersion } return 0 } -func (m *Features) GetBootloaderMode() bool { - if m != nil && m.BootloaderMode != nil { - return *m.BootloaderMode +func (x *Features) GetBootloaderMode() bool { + if x != nil && x.BootloaderMode != nil { + return *x.BootloaderMode } return false } -func (m *Features) GetDeviceId() string { - if m != nil && m.DeviceId != nil { - return *m.DeviceId +func (x *Features) GetDeviceId() string { + if x != nil && x.DeviceId != nil { + return *x.DeviceId } return "" } -func (m *Features) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *Features) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *Features) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *Features) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *Features) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *Features) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return "" } -func (m *Features) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *Features) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *Features) GetInitialized() bool { - if m != nil && m.Initialized != nil { - return *m.Initialized +func (x *Features) GetInitialized() bool { + if x != nil && x.Initialized != nil { + return *x.Initialized } return false } -func (m *Features) GetRevision() []byte { - if m != nil { - return m.Revision +func (x *Features) GetRevision() []byte { + if x != nil { + return x.Revision } return nil } -func (m *Features) GetBootloaderHash() []byte { - if m != nil { - return m.BootloaderHash +func (x *Features) GetBootloaderHash() []byte { + if x != nil { + return x.BootloaderHash } return nil } -func (m *Features) GetImported() bool { - if m != nil && m.Imported != nil { - return *m.Imported +func (x *Features) GetImported() bool { + if x != nil && x.Imported != nil { + return *x.Imported } return false } -func (m *Features) GetPinCached() bool { - if m != nil && m.PinCached != nil { - return *m.PinCached +func (x *Features) GetPinCached() bool { + if x != nil && x.PinCached != nil { + return *x.PinCached } return false } -func (m *Features) GetPassphraseCached() bool { - if m != nil && m.PassphraseCached != nil { - return *m.PassphraseCached +func (x *Features) GetPassphraseCached() bool { + if x != nil && x.PassphraseCached != nil { + return *x.PassphraseCached } return false } -func (m *Features) GetFirmwarePresent() bool { - if m != nil && m.FirmwarePresent != nil { - return *m.FirmwarePresent +func (x *Features) GetFirmwarePresent() bool { + if x != nil && x.FirmwarePresent != nil { + return *x.FirmwarePresent } return false } -func (m *Features) GetNeedsBackup() bool { - if m != nil && m.NeedsBackup != nil { - return *m.NeedsBackup +func (x *Features) GetNeedsBackup() bool { + if x != nil && x.NeedsBackup != nil { + return *x.NeedsBackup } return false } -func (m *Features) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags +func (x *Features) GetFlags() uint32 { + if x != nil && x.Flags != nil { + return *x.Flags } return 0 } -func (m *Features) GetModel() string { - if m != nil && m.Model != nil { - return *m.Model +func (x *Features) GetModel() string { + if x != nil && x.Model != nil { + return *x.Model } return "" } -func (m *Features) GetFwMajor() uint32 { - if m != nil && m.FwMajor != nil { - return *m.FwMajor +func (x *Features) GetFwMajor() uint32 { + if x != nil && x.FwMajor != nil { + return *x.FwMajor } return 0 } -func (m *Features) GetFwMinor() uint32 { - if m != nil && m.FwMinor != nil { - return *m.FwMinor +func (x *Features) GetFwMinor() uint32 { + if x != nil && x.FwMinor != nil { + return *x.FwMinor } return 0 } -func (m *Features) GetFwPatch() uint32 { - if m != nil && m.FwPatch != nil { - return *m.FwPatch +func (x *Features) GetFwPatch() uint32 { + if x != nil && x.FwPatch != nil { + return *x.FwPatch } return 0 } -func (m *Features) GetFwVendor() string { - if m != nil && m.FwVendor != nil { - return *m.FwVendor +func (x *Features) GetFwVendor() string { + if x != nil && x.FwVendor != nil { + return *x.FwVendor } return "" } -func (m *Features) GetFwVendorKeys() []byte { - if m != nil { - return m.FwVendorKeys +func (x *Features) GetFwVendorKeys() []byte { + if x != nil { + return x.FwVendorKeys } return nil } -func (m *Features) GetUnfinishedBackup() bool { - if m != nil && m.UnfinishedBackup != nil { - return *m.UnfinishedBackup +func (x *Features) GetUnfinishedBackup() bool { + if x != nil && x.UnfinishedBackup != nil { + return *x.UnfinishedBackup } return false } -func (m *Features) GetNoBackup() bool { - if m != nil && m.NoBackup != nil { - return *m.NoBackup +func (x *Features) GetNoBackup() bool { + if x != nil && x.NoBackup != nil { + return *x.NoBackup } return false } @@ -500,35 +574,42 @@ func (m *Features) GetNoBackup() bool { // @start // @next Success type ClearSession struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *ClearSession) Reset() { *m = ClearSession{} } -func (m *ClearSession) String() string { return proto.CompactTextString(m) } -func (*ClearSession) ProtoMessage() {} -func (*ClearSession) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{3} +func (x *ClearSession) Reset() { + *x = ClearSession{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ClearSession) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ClearSession.Unmarshal(m, b) -} -func (m *ClearSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ClearSession.Marshal(b, m, deterministic) -} -func (m *ClearSession) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClearSession.Merge(m, src) -} -func (m *ClearSession) XXX_Size() int { - return xxx_messageInfo_ClearSession.Size(m) +func (x *ClearSession) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ClearSession) XXX_DiscardUnknown() { - xxx_messageInfo_ClearSession.DiscardUnknown(m) + +func (*ClearSession) ProtoMessage() {} + +func (x *ClearSession) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ClearSession proto.InternalMessageInfo +// Deprecated: Use ClearSession.ProtoReflect.Descriptor instead. +func (*ClearSession) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{3} +} // * // Request: change language and/or label of the device @@ -536,88 +617,96 @@ var xxx_messageInfo_ClearSession proto.InternalMessageInfo // @next Success // @next Failure type ApplySettings struct { - Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` - UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` - Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` - PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` - AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` - DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplySettings) Reset() { *m = ApplySettings{} } -func (m *ApplySettings) String() string { return proto.CompactTextString(m) } -func (*ApplySettings) ProtoMessage() {} -func (*ApplySettings) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{4} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ApplySettings) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplySettings.Unmarshal(m, b) -} -func (m *ApplySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplySettings.Marshal(b, m, deterministic) + Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` + UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` + Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` + PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` + AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` + DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` // in degrees from North } -func (m *ApplySettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplySettings.Merge(m, src) + +func (x *ApplySettings) Reset() { + *x = ApplySettings{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ApplySettings) XXX_Size() int { - return xxx_messageInfo_ApplySettings.Size(m) + +func (x *ApplySettings) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ApplySettings) XXX_DiscardUnknown() { - xxx_messageInfo_ApplySettings.DiscardUnknown(m) + +func (*ApplySettings) ProtoMessage() {} + +func (x *ApplySettings) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ApplySettings proto.InternalMessageInfo +// Deprecated: Use ApplySettings.ProtoReflect.Descriptor instead. +func (*ApplySettings) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{4} +} -func (m *ApplySettings) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *ApplySettings) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return "" } -func (m *ApplySettings) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *ApplySettings) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *ApplySettings) GetUsePassphrase() bool { - if m != nil && m.UsePassphrase != nil { - return *m.UsePassphrase +func (x *ApplySettings) GetUsePassphrase() bool { + if x != nil && x.UsePassphrase != nil { + return *x.UsePassphrase } return false } -func (m *ApplySettings) GetHomescreen() []byte { - if m != nil { - return m.Homescreen +func (x *ApplySettings) GetHomescreen() []byte { + if x != nil { + return x.Homescreen } return nil } -func (m *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { - if m != nil && m.PassphraseSource != nil { - return *m.PassphraseSource +func (x *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { + if x != nil && x.PassphraseSource != nil { + return *x.PassphraseSource } return ApplySettings_ASK } -func (m *ApplySettings) GetAutoLockDelayMs() uint32 { - if m != nil && m.AutoLockDelayMs != nil { - return *m.AutoLockDelayMs +func (x *ApplySettings) GetAutoLockDelayMs() uint32 { + if x != nil && x.AutoLockDelayMs != nil { + return *x.AutoLockDelayMs } return 0 } -func (m *ApplySettings) GetDisplayRotation() uint32 { - if m != nil && m.DisplayRotation != nil { - return *m.DisplayRotation +func (x *ApplySettings) GetDisplayRotation() uint32 { + if x != nil && x.DisplayRotation != nil { + return *x.DisplayRotation } return 0 } @@ -628,40 +717,48 @@ func (m *ApplySettings) GetDisplayRotation() uint32 { // @next Success // @next Failure type ApplyFlags struct { - Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } -func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } -func (*ApplyFlags) ProtoMessage() {} -func (*ApplyFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{5} + Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` // bitmask, can only set bits, not unset } -func (m *ApplyFlags) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplyFlags.Unmarshal(m, b) -} -func (m *ApplyFlags) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplyFlags.Marshal(b, m, deterministic) -} -func (m *ApplyFlags) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplyFlags.Merge(m, src) +func (x *ApplyFlags) Reset() { + *x = ApplyFlags{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ApplyFlags) XXX_Size() int { - return xxx_messageInfo_ApplyFlags.Size(m) + +func (x *ApplyFlags) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ApplyFlags) XXX_DiscardUnknown() { - xxx_messageInfo_ApplyFlags.DiscardUnknown(m) + +func (*ApplyFlags) ProtoMessage() {} + +func (x *ApplyFlags) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ApplyFlags proto.InternalMessageInfo +// Deprecated: Use ApplyFlags.ProtoReflect.Descriptor instead. +func (*ApplyFlags) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{5} +} -func (m *ApplyFlags) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags +func (x *ApplyFlags) GetFlags() uint32 { + if x != nil && x.Flags != nil { + return *x.Flags } return 0 } @@ -672,40 +769,48 @@ func (m *ApplyFlags) GetFlags() uint32 { // @next Success // @next Failure type ChangePin struct { - Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ChangePin) Reset() { *m = ChangePin{} } -func (m *ChangePin) String() string { return proto.CompactTextString(m) } -func (*ChangePin) ProtoMessage() {} -func (*ChangePin) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{6} + Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` // is PIN removal requested? } -func (m *ChangePin) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ChangePin.Unmarshal(m, b) -} -func (m *ChangePin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ChangePin.Marshal(b, m, deterministic) -} -func (m *ChangePin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChangePin.Merge(m, src) +func (x *ChangePin) Reset() { + *x = ChangePin{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ChangePin) XXX_Size() int { - return xxx_messageInfo_ChangePin.Size(m) + +func (x *ChangePin) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ChangePin) XXX_DiscardUnknown() { - xxx_messageInfo_ChangePin.DiscardUnknown(m) + +func (*ChangePin) ProtoMessage() {} + +func (x *ChangePin) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ChangePin proto.InternalMessageInfo +// Deprecated: Use ChangePin.ProtoReflect.Descriptor instead. +func (*ChangePin) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{6} +} -func (m *ChangePin) GetRemove() bool { - if m != nil && m.Remove != nil { - return *m.Remove +func (x *ChangePin) GetRemove() bool { + if x != nil && x.Remove != nil { + return *x.Remove } return false } @@ -715,64 +820,72 @@ func (m *ChangePin) GetRemove() bool { // @start // @next Success type Ping struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Ping) Reset() { *m = Ping{} } -func (m *Ping) String() string { return proto.CompactTextString(m) } -func (*Ping) ProtoMessage() {} -func (*Ping) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{7} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Ping) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Ping.Unmarshal(m, b) + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` // message to send back in Success message + ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` // ask for button press + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // ask for PIN if set in device + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // ask for passphrase if set in device } -func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Ping.Marshal(b, m, deterministic) -} -func (m *Ping) XXX_Merge(src proto.Message) { - xxx_messageInfo_Ping.Merge(m, src) + +func (x *Ping) Reset() { + *x = Ping{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Ping) XXX_Size() int { - return xxx_messageInfo_Ping.Size(m) + +func (x *Ping) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Ping) XXX_DiscardUnknown() { - xxx_messageInfo_Ping.DiscardUnknown(m) + +func (*Ping) ProtoMessage() {} + +func (x *Ping) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Ping proto.InternalMessageInfo +// Deprecated: Use Ping.ProtoReflect.Descriptor instead. +func (*Ping) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{7} +} -func (m *Ping) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Ping) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } -func (m *Ping) GetButtonProtection() bool { - if m != nil && m.ButtonProtection != nil { - return *m.ButtonProtection +func (x *Ping) GetButtonProtection() bool { + if x != nil && x.ButtonProtection != nil { + return *x.ButtonProtection } return false } -func (m *Ping) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *Ping) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *Ping) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *Ping) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } @@ -782,35 +895,42 @@ func (m *Ping) GetPassphraseProtection() bool { // @start // @next Failure type Cancel struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *Cancel) Reset() { *m = Cancel{} } -func (m *Cancel) String() string { return proto.CompactTextString(m) } -func (*Cancel) ProtoMessage() {} -func (*Cancel) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{8} +func (x *Cancel) Reset() { + *x = Cancel{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Cancel) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cancel.Unmarshal(m, b) +func (x *Cancel) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Cancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cancel.Marshal(b, m, deterministic) -} -func (m *Cancel) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cancel.Merge(m, src) -} -func (m *Cancel) XXX_Size() int { - return xxx_messageInfo_Cancel.Size(m) -} -func (m *Cancel) XXX_DiscardUnknown() { - xxx_messageInfo_Cancel.DiscardUnknown(m) + +func (*Cancel) ProtoMessage() {} + +func (x *Cancel) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Cancel proto.InternalMessageInfo +// Deprecated: Use Cancel.ProtoReflect.Descriptor instead. +func (*Cancel) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{8} +} // * // Request: Request a sample of random data generated by hardware RNG. May be used for testing. @@ -818,40 +938,48 @@ var xxx_messageInfo_Cancel proto.InternalMessageInfo // @next Entropy // @next Failure type GetEntropy struct { - Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *GetEntropy) Reset() { *m = GetEntropy{} } -func (m *GetEntropy) String() string { return proto.CompactTextString(m) } -func (*GetEntropy) ProtoMessage() {} -func (*GetEntropy) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{9} + Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` // size of requested entropy } -func (m *GetEntropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetEntropy.Unmarshal(m, b) -} -func (m *GetEntropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetEntropy.Marshal(b, m, deterministic) -} -func (m *GetEntropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetEntropy.Merge(m, src) +func (x *GetEntropy) Reset() { + *x = GetEntropy{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *GetEntropy) XXX_Size() int { - return xxx_messageInfo_GetEntropy.Size(m) + +func (x *GetEntropy) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *GetEntropy) XXX_DiscardUnknown() { - xxx_messageInfo_GetEntropy.DiscardUnknown(m) + +func (*GetEntropy) ProtoMessage() {} + +func (x *GetEntropy) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_GetEntropy proto.InternalMessageInfo +// Deprecated: Use GetEntropy.ProtoReflect.Descriptor instead. +func (*GetEntropy) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{9} +} -func (m *GetEntropy) GetSize() uint32 { - if m != nil && m.Size != nil { - return *m.Size +func (x *GetEntropy) GetSize() uint32 { + if x != nil && x.Size != nil { + return *x.Size } return 0 } @@ -860,40 +988,48 @@ func (m *GetEntropy) GetSize() uint32 { // Response: Reply with random data generated by internal RNG // @end type Entropy struct { - Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Entropy) Reset() { *m = Entropy{} } -func (m *Entropy) String() string { return proto.CompactTextString(m) } -func (*Entropy) ProtoMessage() {} -func (*Entropy) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{10} + Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` // chunk of random generated bytes } -func (m *Entropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Entropy.Unmarshal(m, b) -} -func (m *Entropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Entropy.Marshal(b, m, deterministic) -} -func (m *Entropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_Entropy.Merge(m, src) +func (x *Entropy) Reset() { + *x = Entropy{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Entropy) XXX_Size() int { - return xxx_messageInfo_Entropy.Size(m) + +func (x *Entropy) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Entropy) XXX_DiscardUnknown() { - xxx_messageInfo_Entropy.DiscardUnknown(m) + +func (*Entropy) ProtoMessage() {} + +func (x *Entropy) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Entropy proto.InternalMessageInfo +// Deprecated: Use Entropy.ProtoReflect.Descriptor instead. +func (*Entropy) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{10} +} -func (m *Entropy) GetEntropy() []byte { - if m != nil { - return m.Entropy +func (x *Entropy) GetEntropy() []byte { + if x != nil { + return x.Entropy } return nil } @@ -904,35 +1040,42 @@ func (m *Entropy) GetEntropy() []byte { // @next Success // @next Failure type WipeDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *WipeDevice) Reset() { *m = WipeDevice{} } -func (m *WipeDevice) String() string { return proto.CompactTextString(m) } -func (*WipeDevice) ProtoMessage() {} -func (*WipeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{11} +func (x *WipeDevice) Reset() { + *x = WipeDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *WipeDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WipeDevice.Unmarshal(m, b) -} -func (m *WipeDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WipeDevice.Marshal(b, m, deterministic) -} -func (m *WipeDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_WipeDevice.Merge(m, src) -} -func (m *WipeDevice) XXX_Size() int { - return xxx_messageInfo_WipeDevice.Size(m) +func (x *WipeDevice) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *WipeDevice) XXX_DiscardUnknown() { - xxx_messageInfo_WipeDevice.DiscardUnknown(m) + +func (*WipeDevice) ProtoMessage() {} + +func (x *WipeDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_WipeDevice proto.InternalMessageInfo +// Deprecated: Use WipeDevice.ProtoReflect.Descriptor instead. +func (*WipeDevice) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{11} +} // * // Request: Load seed and related internal settings from the computer @@ -940,98 +1083,109 @@ var xxx_messageInfo_WipeDevice proto.InternalMessageInfo // @next Success // @next Failure type LoadDevice struct { - Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` - Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` - U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LoadDevice) Reset() { *m = LoadDevice{} } -func (m *LoadDevice) String() string { return proto.CompactTextString(m) } -func (*LoadDevice) ProtoMessage() {} -func (*LoadDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{12} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *LoadDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LoadDevice.Unmarshal(m, b) -} -func (m *LoadDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LoadDevice.Marshal(b, m, deterministic) + Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` // BIP-32 node + Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` // set PIN protection + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` // device label + SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` // do not test mnemonic for valid BIP-39 checksum + U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter } -func (m *LoadDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_LoadDevice.Merge(m, src) -} -func (m *LoadDevice) XXX_Size() int { - return xxx_messageInfo_LoadDevice.Size(m) + +// Default values for LoadDevice fields. +const ( + Default_LoadDevice_Language = string("english") +) + +func (x *LoadDevice) Reset() { + *x = LoadDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *LoadDevice) XXX_DiscardUnknown() { - xxx_messageInfo_LoadDevice.DiscardUnknown(m) + +func (x *LoadDevice) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_LoadDevice proto.InternalMessageInfo +func (*LoadDevice) ProtoMessage() {} -const Default_LoadDevice_Language string = "english" +func (x *LoadDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} -func (m *LoadDevice) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic +// Deprecated: Use LoadDevice.ProtoReflect.Descriptor instead. +func (*LoadDevice) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{12} +} + +func (x *LoadDevice) GetMnemonic() string { + if x != nil && x.Mnemonic != nil { + return *x.Mnemonic } return "" } -func (m *LoadDevice) GetNode() *HDNodeType { - if m != nil { - return m.Node +func (x *LoadDevice) GetNode() *HDNodeType { + if x != nil { + return x.Node } return nil } -func (m *LoadDevice) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin +func (x *LoadDevice) GetPin() string { + if x != nil && x.Pin != nil { + return *x.Pin } return "" } -func (m *LoadDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *LoadDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *LoadDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *LoadDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_LoadDevice_Language } -func (m *LoadDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *LoadDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *LoadDevice) GetSkipChecksum() bool { - if m != nil && m.SkipChecksum != nil { - return *m.SkipChecksum +func (x *LoadDevice) GetSkipChecksum() bool { + if x != nil && x.SkipChecksum != nil { + return *x.SkipChecksum } return false } -func (m *LoadDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *LoadDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } @@ -1042,107 +1196,118 @@ func (m *LoadDevice) GetU2FCounter() uint32 { // @next EntropyRequest // @next Failure type ResetDevice struct { - DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` - Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` - PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` - NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ResetDevice) Reset() { *m = ResetDevice{} } -func (m *ResetDevice) String() string { return proto.CompactTextString(m) } -func (*ResetDevice) ProtoMessage() {} -func (*ResetDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{13} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` // display entropy generated by the device before asking for additional entropy + Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` // strength of seed in bits + PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // enable PIN protection + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` // device label + U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter + SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` // postpone seed backup to BackupDevice workflow + NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` // indicate that no backup is going to be made +} + +// Default values for ResetDevice fields. +const ( + Default_ResetDevice_Strength = uint32(256) + Default_ResetDevice_Language = string("english") +) -func (m *ResetDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ResetDevice.Unmarshal(m, b) -} -func (m *ResetDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ResetDevice.Marshal(b, m, deterministic) -} -func (m *ResetDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetDevice.Merge(m, src) -} -func (m *ResetDevice) XXX_Size() int { - return xxx_messageInfo_ResetDevice.Size(m) +func (x *ResetDevice) Reset() { + *x = ResetDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ResetDevice) XXX_DiscardUnknown() { - xxx_messageInfo_ResetDevice.DiscardUnknown(m) + +func (x *ResetDevice) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_ResetDevice proto.InternalMessageInfo +func (*ResetDevice) ProtoMessage() {} -const Default_ResetDevice_Strength uint32 = 256 -const Default_ResetDevice_Language string = "english" +func (x *ResetDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetDevice.ProtoReflect.Descriptor instead. +func (*ResetDevice) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{13} +} -func (m *ResetDevice) GetDisplayRandom() bool { - if m != nil && m.DisplayRandom != nil { - return *m.DisplayRandom +func (x *ResetDevice) GetDisplayRandom() bool { + if x != nil && x.DisplayRandom != nil { + return *x.DisplayRandom } return false } -func (m *ResetDevice) GetStrength() uint32 { - if m != nil && m.Strength != nil { - return *m.Strength +func (x *ResetDevice) GetStrength() uint32 { + if x != nil && x.Strength != nil { + return *x.Strength } return Default_ResetDevice_Strength } -func (m *ResetDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *ResetDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *ResetDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *ResetDevice) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *ResetDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *ResetDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_ResetDevice_Language } -func (m *ResetDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *ResetDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *ResetDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *ResetDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func (m *ResetDevice) GetSkipBackup() bool { - if m != nil && m.SkipBackup != nil { - return *m.SkipBackup +func (x *ResetDevice) GetSkipBackup() bool { + if x != nil && x.SkipBackup != nil { + return *x.SkipBackup } return false } -func (m *ResetDevice) GetNoBackup() bool { - if m != nil && m.NoBackup != nil { - return *m.NoBackup +func (x *ResetDevice) GetNoBackup() bool { + if x != nil && x.NoBackup != nil { + return *x.NoBackup } return false } @@ -1152,108 +1317,130 @@ func (m *ResetDevice) GetNoBackup() bool { // @start // @next Success type BackupDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *BackupDevice) Reset() { *m = BackupDevice{} } -func (m *BackupDevice) String() string { return proto.CompactTextString(m) } -func (*BackupDevice) ProtoMessage() {} -func (*BackupDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{14} +func (x *BackupDevice) Reset() { + *x = BackupDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *BackupDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BackupDevice.Unmarshal(m, b) -} -func (m *BackupDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BackupDevice.Marshal(b, m, deterministic) -} -func (m *BackupDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_BackupDevice.Merge(m, src) +func (x *BackupDevice) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *BackupDevice) XXX_Size() int { - return xxx_messageInfo_BackupDevice.Size(m) -} -func (m *BackupDevice) XXX_DiscardUnknown() { - xxx_messageInfo_BackupDevice.DiscardUnknown(m) + +func (*BackupDevice) ProtoMessage() {} + +func (x *BackupDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_BackupDevice proto.InternalMessageInfo +// Deprecated: Use BackupDevice.ProtoReflect.Descriptor instead. +func (*BackupDevice) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{14} +} // * // Response: Ask for additional entropy from host computer // @next EntropyAck type EntropyRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } -func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } -func (*EntropyRequest) ProtoMessage() {} -func (*EntropyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{15} +func (x *EntropyRequest) Reset() { + *x = EntropyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EntropyRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyRequest.Unmarshal(m, b) +func (x *EntropyRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EntropyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyRequest.Marshal(b, m, deterministic) -} -func (m *EntropyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyRequest.Merge(m, src) -} -func (m *EntropyRequest) XXX_Size() int { - return xxx_messageInfo_EntropyRequest.Size(m) -} -func (m *EntropyRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyRequest.DiscardUnknown(m) + +func (*EntropyRequest) ProtoMessage() {} + +func (x *EntropyRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo +// Deprecated: Use EntropyRequest.ProtoReflect.Descriptor instead. +func (*EntropyRequest) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{15} +} // * // Request: Provide additional entropy for seed generation function // @next Success type EntropyAck struct { - Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *EntropyAck) Reset() { *m = EntropyAck{} } -func (m *EntropyAck) String() string { return proto.CompactTextString(m) } -func (*EntropyAck) ProtoMessage() {} -func (*EntropyAck) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{16} + Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` // 256 bits (32 bytes) of random data } -func (m *EntropyAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyAck.Unmarshal(m, b) -} -func (m *EntropyAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyAck.Marshal(b, m, deterministic) -} -func (m *EntropyAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyAck.Merge(m, src) +func (x *EntropyAck) Reset() { + *x = EntropyAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EntropyAck) XXX_Size() int { - return xxx_messageInfo_EntropyAck.Size(m) + +func (x *EntropyAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EntropyAck) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyAck.DiscardUnknown(m) + +func (*EntropyAck) ProtoMessage() {} + +func (x *EntropyAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EntropyAck proto.InternalMessageInfo +// Deprecated: Use EntropyAck.ProtoReflect.Descriptor instead. +func (*EntropyAck) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{16} +} -func (m *EntropyAck) GetEntropy() []byte { - if m != nil { - return m.Entropy +func (x *EntropyAck) GetEntropy() []byte { + if x != nil { + return x.Entropy } return nil } @@ -1264,107 +1451,118 @@ func (m *EntropyAck) GetEntropy() []byte { // @start // @next WordRequest type RecoveryDevice struct { - WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` - PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` - EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` // number of words in BIP-39 mnemonic + PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // enable PIN protection + Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` // device label + EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` // enforce BIP-39 wordlist during the process // 7 reserved for unused recovery method - Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` - U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` // supported recovery type + U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter + DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` // perform dry-run recovery workflow (for safe mnemonic validation) } -func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } -func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } -func (*RecoveryDevice) ProtoMessage() {} -func (*RecoveryDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{17} -} +// Default values for RecoveryDevice fields. +const ( + Default_RecoveryDevice_Language = string("english") +) -func (m *RecoveryDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RecoveryDevice.Unmarshal(m, b) -} -func (m *RecoveryDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RecoveryDevice.Marshal(b, m, deterministic) -} -func (m *RecoveryDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_RecoveryDevice.Merge(m, src) -} -func (m *RecoveryDevice) XXX_Size() int { - return xxx_messageInfo_RecoveryDevice.Size(m) +func (x *RecoveryDevice) Reset() { + *x = RecoveryDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *RecoveryDevice) XXX_DiscardUnknown() { - xxx_messageInfo_RecoveryDevice.DiscardUnknown(m) + +func (x *RecoveryDevice) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_RecoveryDevice proto.InternalMessageInfo +func (*RecoveryDevice) ProtoMessage() {} + +func (x *RecoveryDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} -const Default_RecoveryDevice_Language string = "english" +// Deprecated: Use RecoveryDevice.ProtoReflect.Descriptor instead. +func (*RecoveryDevice) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{17} +} -func (m *RecoveryDevice) GetWordCount() uint32 { - if m != nil && m.WordCount != nil { - return *m.WordCount +func (x *RecoveryDevice) GetWordCount() uint32 { + if x != nil && x.WordCount != nil { + return *x.WordCount } return 0 } -func (m *RecoveryDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *RecoveryDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *RecoveryDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *RecoveryDevice) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *RecoveryDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *RecoveryDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_RecoveryDevice_Language } -func (m *RecoveryDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *RecoveryDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *RecoveryDevice) GetEnforceWordlist() bool { - if m != nil && m.EnforceWordlist != nil { - return *m.EnforceWordlist +func (x *RecoveryDevice) GetEnforceWordlist() bool { + if x != nil && x.EnforceWordlist != nil { + return *x.EnforceWordlist } return false } -func (m *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { - if m != nil && m.Type != nil { - return *m.Type +func (x *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { + if x != nil && x.Type != nil { + return *x.Type } return RecoveryDevice_RecoveryDeviceType_ScrambledWords } -func (m *RecoveryDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *RecoveryDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func (m *RecoveryDevice) GetDryRun() bool { - if m != nil && m.DryRun != nil { - return *m.DryRun +func (x *RecoveryDevice) GetDryRun() bool { + if x != nil && x.DryRun != nil { + return *x.DryRun } return false } @@ -1374,40 +1572,48 @@ func (m *RecoveryDevice) GetDryRun() bool { // Its position is shown only on device's internal display. // @next WordAck type WordRequest struct { - Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *WordRequest) Reset() { *m = WordRequest{} } -func (m *WordRequest) String() string { return proto.CompactTextString(m) } -func (*WordRequest) ProtoMessage() {} -func (*WordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{18} + Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` } -func (m *WordRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordRequest.Unmarshal(m, b) -} -func (m *WordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordRequest.Marshal(b, m, deterministic) -} -func (m *WordRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordRequest.Merge(m, src) +func (x *WordRequest) Reset() { + *x = WordRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *WordRequest) XXX_Size() int { - return xxx_messageInfo_WordRequest.Size(m) + +func (x *WordRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *WordRequest) XXX_DiscardUnknown() { - xxx_messageInfo_WordRequest.DiscardUnknown(m) + +func (*WordRequest) ProtoMessage() {} + +func (x *WordRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_WordRequest proto.InternalMessageInfo +// Deprecated: Use WordRequest.ProtoReflect.Descriptor instead. +func (*WordRequest) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{18} +} -func (m *WordRequest) GetType() WordRequest_WordRequestType { - if m != nil && m.Type != nil { - return *m.Type +func (x *WordRequest) GetType() WordRequest_WordRequestType { + if x != nil && x.Type != nil { + return *x.Type } return WordRequest_WordRequestType_Plain } @@ -1418,40 +1624,48 @@ func (m *WordRequest) GetType() WordRequest_WordRequestType { // @next Success // @next Failure type WordAck struct { - Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *WordAck) Reset() { *m = WordAck{} } -func (m *WordAck) String() string { return proto.CompactTextString(m) } -func (*WordAck) ProtoMessage() {} -func (*WordAck) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{19} + Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` // one word of mnemonic on asked position } -func (m *WordAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordAck.Unmarshal(m, b) -} -func (m *WordAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordAck.Marshal(b, m, deterministic) -} -func (m *WordAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordAck.Merge(m, src) +func (x *WordAck) Reset() { + *x = WordAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *WordAck) XXX_Size() int { - return xxx_messageInfo_WordAck.Size(m) + +func (x *WordAck) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *WordAck) XXX_DiscardUnknown() { - xxx_messageInfo_WordAck.DiscardUnknown(m) + +func (*WordAck) ProtoMessage() {} + +func (x *WordAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_WordAck proto.InternalMessageInfo +// Deprecated: Use WordAck.ProtoReflect.Descriptor instead. +func (*WordAck) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{19} +} -func (m *WordAck) GetWord() string { - if m != nil && m.Word != nil { - return *m.Word +func (x *WordAck) GetWord() string { + if x != nil && x.Word != nil { + return *x.Word } return "" } @@ -1461,161 +1675,602 @@ func (m *WordAck) GetWord() string { // @start // @next Success type SetU2FCounter struct { - U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } -func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } -func (*SetU2FCounter) ProtoMessage() {} -func (*SetU2FCounter) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{20} + U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // counter } -func (m *SetU2FCounter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SetU2FCounter.Unmarshal(m, b) -} -func (m *SetU2FCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SetU2FCounter.Marshal(b, m, deterministic) -} -func (m *SetU2FCounter) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetU2FCounter.Merge(m, src) +func (x *SetU2FCounter) Reset() { + *x = SetU2FCounter{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SetU2FCounter) XXX_Size() int { - return xxx_messageInfo_SetU2FCounter.Size(m) + +func (x *SetU2FCounter) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SetU2FCounter) XXX_DiscardUnknown() { - xxx_messageInfo_SetU2FCounter.DiscardUnknown(m) + +func (*SetU2FCounter) ProtoMessage() {} + +func (x *SetU2FCounter) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SetU2FCounter proto.InternalMessageInfo +// Deprecated: Use SetU2FCounter.ProtoReflect.Descriptor instead. +func (*SetU2FCounter) Descriptor() ([]byte, []int) { + return file_messages_management_proto_rawDescGZIP(), []int{20} +} -func (m *SetU2FCounter) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *SetU2FCounter) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func init() { - proto.RegisterEnum("hw.trezor.messages.management.ApplySettings_PassphraseSourceType", ApplySettings_PassphraseSourceType_name, ApplySettings_PassphraseSourceType_value) - proto.RegisterEnum("hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType", RecoveryDevice_RecoveryDeviceType_name, RecoveryDevice_RecoveryDeviceType_value) - proto.RegisterEnum("hw.trezor.messages.management.WordRequest_WordRequestType", WordRequest_WordRequestType_name, WordRequest_WordRequestType_value) - proto.RegisterType((*Initialize)(nil), "hw.trezor.messages.management.Initialize") - proto.RegisterType((*GetFeatures)(nil), "hw.trezor.messages.management.GetFeatures") - proto.RegisterType((*Features)(nil), "hw.trezor.messages.management.Features") - proto.RegisterType((*ClearSession)(nil), "hw.trezor.messages.management.ClearSession") - proto.RegisterType((*ApplySettings)(nil), "hw.trezor.messages.management.ApplySettings") - proto.RegisterType((*ApplyFlags)(nil), "hw.trezor.messages.management.ApplyFlags") - proto.RegisterType((*ChangePin)(nil), "hw.trezor.messages.management.ChangePin") - proto.RegisterType((*Ping)(nil), "hw.trezor.messages.management.Ping") - proto.RegisterType((*Cancel)(nil), "hw.trezor.messages.management.Cancel") - proto.RegisterType((*GetEntropy)(nil), "hw.trezor.messages.management.GetEntropy") - proto.RegisterType((*Entropy)(nil), "hw.trezor.messages.management.Entropy") - proto.RegisterType((*WipeDevice)(nil), "hw.trezor.messages.management.WipeDevice") - proto.RegisterType((*LoadDevice)(nil), "hw.trezor.messages.management.LoadDevice") - proto.RegisterType((*ResetDevice)(nil), "hw.trezor.messages.management.ResetDevice") - proto.RegisterType((*BackupDevice)(nil), "hw.trezor.messages.management.BackupDevice") - proto.RegisterType((*EntropyRequest)(nil), "hw.trezor.messages.management.EntropyRequest") - proto.RegisterType((*EntropyAck)(nil), "hw.trezor.messages.management.EntropyAck") - proto.RegisterType((*RecoveryDevice)(nil), "hw.trezor.messages.management.RecoveryDevice") - proto.RegisterType((*WordRequest)(nil), "hw.trezor.messages.management.WordRequest") - proto.RegisterType((*WordAck)(nil), "hw.trezor.messages.management.WordAck") - proto.RegisterType((*SetU2FCounter)(nil), "hw.trezor.messages.management.SetU2FCounter") -} - -func init() { proto.RegisterFile("messages-management.proto", fileDescriptor_0c720c20d27aa029) } - -var fileDescriptor_0c720c20d27aa029 = []byte{ - // 1393 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xdd, 0x6e, 0xdb, 0xc8, - 0x15, 0x8e, 0x7e, 0x62, 0x49, 0xc7, 0xfa, 0xcb, 0xd4, 0x8e, 0xe9, 0xb8, 0x6e, 0x1c, 0xba, 0x6e, - 0x12, 0x04, 0x15, 0x0a, 0x17, 0x09, 0x90, 0x5c, 0x14, 0x75, 0xec, 0xfc, 0x21, 0x71, 0x6a, 0xd0, - 0x6e, 0x02, 0xf4, 0x86, 0x18, 0x91, 0x47, 0xd2, 0xd4, 0xe4, 0x0c, 0xcb, 0x19, 0xda, 0x55, 0x5e, - 0x60, 0x6f, 0xf6, 0x45, 0x16, 0xfb, 0x1c, 0x7b, 0xb5, 0xcf, 0xb0, 0xef, 0xb2, 0x98, 0x19, 0x52, - 0xa2, 0x65, 0x3b, 0x46, 0x76, 0xef, 0xe6, 0x7c, 0xe7, 0xe3, 0x68, 0xce, 0x77, 0xbe, 0x39, 0x63, - 0xc3, 0x7a, 0x8c, 0x52, 0xd2, 0x31, 0xca, 0xbf, 0xc6, 0x94, 0xd3, 0x31, 0xc6, 0xc8, 0xd5, 0x20, - 0x49, 0x85, 0x12, 0x64, 0x73, 0x72, 0x3e, 0x50, 0x29, 0x7e, 0x11, 0xe9, 0xa0, 0x20, 0x0d, 0xe6, - 0xa4, 0x7b, 0xab, 0xb3, 0x2f, 0x03, 0x11, 0xc7, 0x82, 0xdb, 0xaf, 0xdc, 0xf7, 0x00, 0xef, 0x38, - 0x53, 0x8c, 0x46, 0xec, 0x0b, 0x92, 0x15, 0xb8, 0x2d, 0x15, 0x55, 0xe8, 0x54, 0xb6, 0x2a, 0x8f, - 0xda, 0x9e, 0x0d, 0xc8, 0x43, 0xe8, 0xc9, 0x53, 0x96, 0xf8, 0x09, 0x95, 0x32, 0x99, 0xa4, 0x54, - 0xa2, 0x53, 0xdd, 0xaa, 0x3c, 0x6a, 0x7a, 0x5d, 0x0d, 0x1f, 0xcd, 0x50, 0xb7, 0x03, 0xcb, 0x6f, - 0x50, 0xbd, 0x46, 0xaa, 0xb2, 0x14, 0xa5, 0xfb, 0x7d, 0x03, 0x9a, 0x45, 0x40, 0xee, 0xc2, 0xd2, - 0x19, 0xf2, 0x50, 0xa4, 0x66, 0xef, 0x96, 0x97, 0x47, 0x64, 0x1b, 0x3a, 0x31, 0xfd, 0xaf, 0x48, - 0xfd, 0x33, 0x4c, 0x25, 0x13, 0xdc, 0x6c, 0xdd, 0xf1, 0xda, 0x06, 0xfc, 0x64, 0x31, 0x43, 0x62, - 0xbc, 0x44, 0xaa, 0xe5, 0x24, 0x0d, 0x96, 0x48, 0x09, 0x55, 0xc1, 0x64, 0x46, 0xaa, 0x5b, 0x92, - 0x01, 0x0b, 0xd2, 0x43, 0xe8, 0x0d, 0x85, 0x50, 0x91, 0xa0, 0x21, 0xa6, 0x7e, 0x2c, 0x42, 0x74, - 0x6e, 0xdb, 0x5a, 0xe6, 0xf0, 0xa1, 0x08, 0x91, 0x6c, 0x40, 0x2b, 0xc4, 0x33, 0x16, 0xa0, 0xcf, - 0x42, 0x67, 0xc9, 0x1c, 0xb9, 0x69, 0x81, 0x77, 0x21, 0xd9, 0x81, 0x6e, 0xc2, 0xb8, 0xaf, 0x25, - 0xc4, 0x40, 0xe9, 0xdf, 0x6a, 0x98, 0x4d, 0x3a, 0x09, 0xe3, 0x47, 0x33, 0x90, 0xfc, 0x1d, 0x56, - 0xe7, 0x9a, 0x95, 0xd9, 0x4d, 0xc3, 0x5e, 0x99, 0x27, 0x4b, 0x1f, 0xdd, 0x83, 0x66, 0x44, 0xf9, - 0x38, 0xa3, 0x63, 0x74, 0x5a, 0xf6, 0x77, 0x8b, 0x58, 0xf7, 0x27, 0xa2, 0x43, 0x8c, 0x1c, 0x30, - 0x09, 0x1b, 0x90, 0x2d, 0x58, 0x66, 0xb3, 0x1e, 0x86, 0x4e, 0xdb, 0x6c, 0x5e, 0x86, 0xf4, 0x9e, - 0x29, 0x9e, 0x31, 0xa3, 0x4a, 0xc7, 0xb4, 0x76, 0x16, 0x2f, 0x28, 0x32, 0xa1, 0x72, 0xe2, 0x74, - 0x0d, 0xa5, 0xa4, 0xc8, 0x5b, 0x2a, 0x27, 0x7a, 0x13, 0x16, 0x27, 0x22, 0x55, 0x18, 0x3a, 0x3d, - 0xf3, 0x1b, 0xb3, 0x98, 0x6c, 0x02, 0x68, 0x41, 0x02, 0x1a, 0x4c, 0x30, 0x74, 0xfa, 0x26, 0xdb, - 0x4a, 0x18, 0xdf, 0x37, 0x00, 0x79, 0x02, 0x77, 0x4a, 0x42, 0xe4, 0xac, 0x3b, 0x86, 0xd5, 0x9f, - 0x27, 0x72, 0xf2, 0x63, 0xe8, 0x8f, 0x58, 0x1a, 0x9f, 0xd3, 0x54, 0x6b, 0x86, 0x12, 0xb9, 0x72, - 0x88, 0xe1, 0xf6, 0x0a, 0xfc, 0xc8, 0xc2, 0xe4, 0x01, 0xb4, 0x39, 0x62, 0x28, 0xfd, 0x21, 0x0d, - 0x4e, 0xb3, 0xc4, 0xf9, 0x83, 0x2d, 0xdd, 0x60, 0x2f, 0x0d, 0xa4, 0x25, 0x1b, 0x45, 0x74, 0x2c, - 0x9d, 0x15, 0xe3, 0x06, 0x1b, 0x68, 0x54, 0xf7, 0x3e, 0x72, 0x56, 0xad, 0x90, 0x26, 0x20, 0xeb, - 0xd0, 0x1c, 0x9d, 0xfb, 0xc6, 0x79, 0xce, 0x5d, 0x43, 0x6f, 0x8c, 0xce, 0x0f, 0x75, 0x58, 0xa4, - 0xb4, 0xdf, 0x9c, 0xb5, 0x59, 0x4a, 0x87, 0x79, 0xca, 0xb8, 0xcc, 0x71, 0x8a, 0xd4, 0x91, 0x0e, - 0xb5, 0x89, 0x46, 0xe7, 0x7e, 0xee, 0xfb, 0x75, 0xdb, 0xcc, 0xd1, 0xf9, 0x27, 0xeb, 0xfc, 0x3f, - 0x43, 0x77, 0x96, 0xf4, 0x4f, 0x71, 0x2a, 0x9d, 0x7b, 0x46, 0xf7, 0x76, 0xc1, 0x78, 0x8f, 0x53, - 0xa9, 0xa5, 0xcb, 0xf8, 0x88, 0x71, 0x26, 0x27, 0x18, 0x16, 0x75, 0x6e, 0x58, 0xe9, 0xe6, 0x89, - 0xbc, 0xd8, 0x0d, 0x68, 0x71, 0x51, 0x90, 0xfe, 0x68, 0x7b, 0xc4, 0x85, 0x4d, 0xba, 0x5d, 0x68, - 0xef, 0x47, 0x48, 0xd3, 0x63, 0x94, 0xba, 0xf1, 0xee, 0x77, 0x35, 0xe8, 0xec, 0x25, 0x49, 0x34, - 0x3d, 0x46, 0xa5, 0x18, 0x1f, 0xcb, 0x0b, 0xd6, 0xab, 0x5c, 0x67, 0xbd, 0x6a, 0xd9, 0x7a, 0x3b, - 0xd0, 0xcd, 0xb4, 0xb5, 0xe7, 0x93, 0xa1, 0x66, 0x2f, 0x42, 0x26, 0x71, 0x3e, 0x18, 0xc8, 0x9f, - 0x00, 0x26, 0x22, 0x46, 0x19, 0xa4, 0x88, 0xf6, 0x5e, 0xb6, 0xbd, 0x12, 0x42, 0xf8, 0x05, 0x7f, - 0x48, 0x91, 0xa5, 0x81, 0xbd, 0x97, 0xdd, 0xdd, 0xbd, 0xc1, 0x57, 0xe7, 0xda, 0xe0, 0x42, 0x05, - 0x83, 0xf9, 0x6f, 0x1e, 0x9b, 0x4d, 0x4e, 0xa6, 0x09, 0x96, 0x2d, 0x66, 0x51, 0xf2, 0x04, 0x08, - 0xcd, 0x94, 0xf0, 0x23, 0x11, 0x9c, 0xfa, 0x21, 0x46, 0x74, 0xea, 0xc7, 0xd2, 0xdc, 0xf2, 0x8e, - 0xd7, 0xd3, 0x99, 0x0f, 0x22, 0x38, 0x3d, 0xd0, 0xf8, 0xa1, 0xd4, 0x7e, 0x0c, 0x99, 0x4c, 0x34, - 0x29, 0x15, 0x8a, 0xce, 0xae, 0x7b, 0xc7, 0xeb, 0xe5, 0xb8, 0x97, 0xc3, 0xee, 0x53, 0x58, 0xb9, - 0xea, 0x04, 0xa4, 0x01, 0xb5, 0xbd, 0xe3, 0xf7, 0xfd, 0x5b, 0x04, 0x60, 0xe9, 0xe0, 0xd5, 0xa7, - 0x77, 0xfb, 0xaf, 0xfa, 0x15, 0xd2, 0x84, 0xfa, 0xdb, 0x7f, 0x1d, 0x9f, 0xf4, 0xab, 0xae, 0x0b, - 0x60, 0xca, 0x78, 0x5d, 0x78, 0xd3, 0x3a, 0xb6, 0x52, 0x72, 0xac, 0xbb, 0x0d, 0xad, 0xfd, 0x09, - 0xe5, 0x63, 0x3c, 0x62, 0x5c, 0x0f, 0xd3, 0x14, 0x63, 0x71, 0x66, 0xdb, 0xd4, 0xf4, 0xf2, 0xc8, - 0xfd, 0xa1, 0x02, 0xf5, 0x23, 0xc6, 0xc7, 0xc4, 0x81, 0x46, 0x2e, 0x56, 0xde, 0xc8, 0x22, 0xd4, - 0x7e, 0x1a, 0x66, 0x4a, 0x89, 0x0b, 0xd3, 0xcb, 0x8e, 0xf3, 0xbe, 0x4d, 0x94, 0x66, 0xd1, 0xe5, - 0x39, 0x57, 0xfb, 0xa6, 0x39, 0x57, 0xbf, 0x7e, 0xce, 0xb9, 0x4d, 0x58, 0xda, 0xa7, 0x3c, 0xc0, - 0xc8, 0xdd, 0x02, 0x78, 0x83, 0xea, 0x15, 0x57, 0xa9, 0x48, 0xa6, 0x84, 0x40, 0x5d, 0xb2, 0x2f, - 0xfa, 0xdc, 0xd5, 0x47, 0x1d, 0xcf, 0xac, 0xdd, 0x6d, 0x68, 0x14, 0x69, 0x07, 0x1a, 0x68, 0x97, - 0x86, 0xd1, 0xf6, 0x8a, 0xd0, 0x6d, 0x03, 0x7c, 0x66, 0x09, 0x1e, 0x98, 0x21, 0xed, 0xfe, 0x58, - 0x05, 0xf8, 0x20, 0x68, 0x68, 0x43, 0x6d, 0xed, 0x98, 0x63, 0x2c, 0x38, 0x0b, 0x0a, 0x6b, 0x17, - 0x31, 0x79, 0x0e, 0x75, 0xae, 0x1f, 0x02, 0xad, 0xc2, 0xf2, 0xee, 0xce, 0x55, 0x86, 0xcb, 0xdf, - 0xcc, 0xb7, 0x07, 0x1f, 0x45, 0x68, 0x4d, 0x65, 0x3e, 0x21, 0x7d, 0xa8, 0x25, 0xcc, 0xaa, 0xd2, - 0xf2, 0xf4, 0xf2, 0x37, 0x69, 0x41, 0xb6, 0x4b, 0x17, 0x4f, 0xdb, 0xbe, 0xf5, 0xa2, 0x81, 0x7c, - 0x1c, 0x31, 0x39, 0xb9, 0xea, 0x06, 0x2e, 0x95, 0x6f, 0xe0, 0x36, 0x74, 0xcc, 0xe3, 0x1c, 0x4c, - 0x30, 0x38, 0x95, 0x59, 0x9c, 0xbf, 0x44, 0x6d, 0x0d, 0xee, 0xe7, 0x18, 0xb9, 0x0f, 0xcb, 0xd9, - 0xee, 0xc8, 0x0f, 0x44, 0xc6, 0x15, 0xa6, 0xe6, 0xf9, 0xe9, 0x78, 0x90, 0xed, 0x8e, 0xf6, 0x2d, - 0xe2, 0xfe, 0x5c, 0x85, 0x65, 0x0f, 0x25, 0xaa, 0x5c, 0xae, 0x1d, 0xe8, 0xce, 0x3c, 0x4f, 0x79, - 0x28, 0xe2, 0xdc, 0x68, 0x9d, 0xc2, 0xf1, 0x06, 0x24, 0xf7, 0xa1, 0x29, 0x55, 0x8a, 0x7c, 0xac, - 0x26, 0xf6, 0xdd, 0x7e, 0x51, 0xdb, 0x7d, 0xfa, 0xcc, 0x9b, 0x81, 0xd7, 0xab, 0x51, 0xfb, 0x8a, - 0x1a, 0x97, 0x5d, 0x57, 0xbf, 0xca, 0x75, 0xbf, 0x43, 0xb4, 0x05, 0x3d, 0x1a, 0x8b, 0x7a, 0x68, - 0x82, 0x51, 0x35, 0x1f, 0xa5, 0xf6, 0xbd, 0x06, 0x0d, 0x5d, 0x35, 0x69, 0x5b, 0x97, 0x27, 0xad, - 0x5d, 0xe5, 0x5e, 0xec, 0x43, 0x37, 0xb7, 0xaf, 0x87, 0xff, 0xcb, 0x50, 0x2a, 0xf7, 0x2f, 0x00, - 0x39, 0xb2, 0x17, 0x9c, 0x5e, 0xf4, 0x74, 0xa5, 0xec, 0xe9, 0x5f, 0x6a, 0xd0, 0xf5, 0x30, 0x10, - 0x67, 0x98, 0x4e, 0xf3, 0xd6, 0x6c, 0x02, 0x9c, 0x8b, 0x34, 0xb4, 0x87, 0xcf, 0x67, 0x44, 0x4b, - 0x23, 0xe6, 0xec, 0xd7, 0x2b, 0x5e, 0xfd, 0x26, 0xc5, 0x6b, 0x37, 0x29, 0x5e, 0xbf, 0x51, 0xf1, - 0xdb, 0x65, 0xc5, 0x1f, 0x43, 0x1f, 0xf9, 0x48, 0xa4, 0x01, 0xfa, 0xfa, 0xac, 0x11, 0x93, 0xca, - 0xb4, 0xa4, 0xe9, 0xf5, 0x72, 0xfc, 0x73, 0x0e, 0x93, 0x13, 0xa8, 0xab, 0x69, 0x82, 0x46, 0xf4, - 0xee, 0xee, 0x3f, 0x6f, 0x98, 0xff, 0x17, 0xd5, 0x59, 0x08, 0xed, 0x4d, 0xd5, 0xbb, 0x2d, 0xb6, - 0xbc, 0x75, 0xa9, 0xe5, 0x6b, 0xd0, 0x08, 0xd3, 0xa9, 0x9f, 0x66, 0xdc, 0xfc, 0x75, 0xd5, 0xf4, - 0x96, 0xc2, 0x74, 0xea, 0x65, 0xdc, 0xfd, 0x0f, 0x90, 0xcb, 0xbb, 0x92, 0x1d, 0x78, 0x70, 0x19, - 0xf5, 0x8f, 0x83, 0x94, 0xc6, 0xc3, 0x08, 0x43, 0x5d, 0x8d, 0xec, 0xdf, 0x22, 0x9b, 0xb0, 0x7e, - 0x05, 0xed, 0x90, 0xaa, 0x94, 0xfd, 0xbf, 0x5f, 0x71, 0x7f, 0xaa, 0xc0, 0xb2, 0xa6, 0xe6, 0xbe, - 0x20, 0x1f, 0xf3, 0xda, 0x2b, 0xa6, 0xf6, 0x17, 0x37, 0xd4, 0x5e, 0xfa, 0xb2, 0xbc, 0x9e, 0x57, - 0xed, 0x8e, 0xa0, 0xb7, 0x90, 0x20, 0xeb, 0xb0, 0xba, 0x00, 0xf9, 0x47, 0x11, 0x65, 0xbc, 0x7f, - 0x8b, 0x6c, 0xc0, 0xda, 0x62, 0xca, 0x9e, 0xf4, 0x79, 0xbf, 0x72, 0x7d, 0xf2, 0x59, 0xbf, 0xea, - 0x6e, 0x42, 0x43, 0x27, 0xb5, 0x99, 0x09, 0xd4, 0x75, 0x87, 0xcd, 0x74, 0x6e, 0x79, 0x66, 0xed, - 0xfe, 0x0d, 0x3a, 0xc7, 0xa8, 0xfe, 0xbd, 0xfb, 0xba, 0x74, 0xbf, 0xca, 0xdd, 0xa8, 0x2c, 0x76, - 0xe3, 0xe5, 0x3f, 0x60, 0x3b, 0x10, 0xf1, 0x40, 0x52, 0x25, 0xe4, 0x84, 0x45, 0x74, 0x28, 0x0b, - 0x21, 0x22, 0x36, 0xb4, 0xff, 0xbb, 0x0c, 0xb3, 0xd1, 0xcb, 0xb5, 0x13, 0x03, 0x1e, 0x5a, 0x71, - 0x0e, 0x67, 0xd2, 0xfc, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0xfc, 0x59, 0x29, 0x0d, 0x00, - 0x00, +var File_messages_management_proto protoreflect.FileDescriptor + +var file_messages_management_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x77, 0x2e, + 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x15, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x4b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x61, + 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x73, 0x6b, 0x69, 0x70, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x0d, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x8c, 0x07, + 0x0a, 0x08, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, + 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, + 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, + 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x62, 0x6f, 0x6f, 0x74, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x72, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x62, 0x6f, + 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x69, 0x6e, 0x5f, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x69, + 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, + 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x19, + 0x0a, 0x08, 0x66, 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x66, 0x77, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x77, 0x5f, + 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x77, 0x4d, + 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x18, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x1b, 0x0a, 0x09, 0x66, 0x77, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x66, 0x77, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x24, 0x0a, 0x0e, + 0x66, 0x77, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x1a, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x66, 0x77, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4b, 0x65, + 0x79, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x75, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, + 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x1c, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x22, 0x0e, 0x0a, 0x0c, + 0x43, 0x6c, 0x65, 0x61, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x03, 0x0a, + 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, + 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x50, 0x61, 0x73, + 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x6f, 0x6d, 0x65, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x68, 0x6f, 0x6d, + 0x65, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x6e, 0x0a, 0x11, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x2e, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x5f, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6c, + 0x61, 0x79, 0x4d, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, + 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x35, 0x0a, 0x14, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x4b, 0x10, 0x00, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x48, 0x4f, 0x53, 0x54, 0x10, 0x02, 0x22, 0x22, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x46, + 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x23, 0x0a, 0x09, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x50, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, + 0xa9, 0x01, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x08, 0x0a, 0x06, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x22, 0x20, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x23, 0x0a, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x01, 0x20, + 0x02, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x22, 0x0c, 0x0a, 0x0a, + 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0xab, 0x02, 0x0a, 0x0a, 0x4c, + 0x6f, 0x61, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6e, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6e, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x12, 0x39, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, + 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x07, 0x65, 0x6e, 0x67, 0x6c, 0x69, + 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x73, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, 0x32, + 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0xcb, 0x02, 0x0a, 0x0b, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, + 0x1f, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x3a, 0x03, 0x32, 0x35, 0x36, 0x52, 0x08, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, + 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x07, + 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, 0x32, + 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, + 0x6b, 0x69, 0x70, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x22, 0x0e, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x26, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x22, 0xdd, 0x03, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, + 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x3a, 0x07, 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x64, + 0x6c, 0x69, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, + 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x75, 0x32, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, + 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, + 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5a, 0x0a, 0x12, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x63, 0x72, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x10, + 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x10, 0x01, + 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x4e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3a, + 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x57, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x6f, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x66, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, 0x12, 0x1b, + 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x39, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x57, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, + 0x61, 0x74, 0x72, 0x69, 0x78, 0x36, 0x10, 0x02, 0x22, 0x1d, 0x0a, 0x07, 0x57, 0x6f, 0x72, 0x64, + 0x41, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x09, 0x52, 0x04, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x30, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x55, 0x32, + 0x46, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, + 0x32, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x42, 0x79, 0x0a, 0x23, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, 0x72, 0x65, + 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x17, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, + 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, +} + +var ( + file_messages_management_proto_rawDescOnce sync.Once + file_messages_management_proto_rawDescData = file_messages_management_proto_rawDesc +) + +func file_messages_management_proto_rawDescGZIP() []byte { + file_messages_management_proto_rawDescOnce.Do(func() { + file_messages_management_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_management_proto_rawDescData) + }) + return file_messages_management_proto_rawDescData +} + +var file_messages_management_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_messages_management_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_messages_management_proto_goTypes = []any{ + (ApplySettings_PassphraseSourceType)(0), // 0: hw.trezor.messages.management.ApplySettings.PassphraseSourceType + (RecoveryDevice_RecoveryDeviceType)(0), // 1: hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceType + (WordRequest_WordRequestType)(0), // 2: hw.trezor.messages.management.WordRequest.WordRequestType + (*Initialize)(nil), // 3: hw.trezor.messages.management.Initialize + (*GetFeatures)(nil), // 4: hw.trezor.messages.management.GetFeatures + (*Features)(nil), // 5: hw.trezor.messages.management.Features + (*ClearSession)(nil), // 6: hw.trezor.messages.management.ClearSession + (*ApplySettings)(nil), // 7: hw.trezor.messages.management.ApplySettings + (*ApplyFlags)(nil), // 8: hw.trezor.messages.management.ApplyFlags + (*ChangePin)(nil), // 9: hw.trezor.messages.management.ChangePin + (*Ping)(nil), // 10: hw.trezor.messages.management.Ping + (*Cancel)(nil), // 11: hw.trezor.messages.management.Cancel + (*GetEntropy)(nil), // 12: hw.trezor.messages.management.GetEntropy + (*Entropy)(nil), // 13: hw.trezor.messages.management.Entropy + (*WipeDevice)(nil), // 14: hw.trezor.messages.management.WipeDevice + (*LoadDevice)(nil), // 15: hw.trezor.messages.management.LoadDevice + (*ResetDevice)(nil), // 16: hw.trezor.messages.management.ResetDevice + (*BackupDevice)(nil), // 17: hw.trezor.messages.management.BackupDevice + (*EntropyRequest)(nil), // 18: hw.trezor.messages.management.EntropyRequest + (*EntropyAck)(nil), // 19: hw.trezor.messages.management.EntropyAck + (*RecoveryDevice)(nil), // 20: hw.trezor.messages.management.RecoveryDevice + (*WordRequest)(nil), // 21: hw.trezor.messages.management.WordRequest + (*WordAck)(nil), // 22: hw.trezor.messages.management.WordAck + (*SetU2FCounter)(nil), // 23: hw.trezor.messages.management.SetU2FCounter + (*HDNodeType)(nil), // 24: hw.trezor.messages.common.HDNodeType +} +var file_messages_management_proto_depIdxs = []int32{ + 0, // 0: hw.trezor.messages.management.ApplySettings.passphrase_source:type_name -> hw.trezor.messages.management.ApplySettings.PassphraseSourceType + 24, // 1: hw.trezor.messages.management.LoadDevice.node:type_name -> hw.trezor.messages.common.HDNodeType + 1, // 2: hw.trezor.messages.management.RecoveryDevice.type:type_name -> hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceType + 2, // 3: hw.trezor.messages.management.WordRequest.type:type_name -> hw.trezor.messages.management.WordRequest.WordRequestType + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_messages_management_proto_init() } +func file_messages_management_proto_init() { + if File_messages_management_proto != nil { + return + } + file_messages_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_messages_management_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*Initialize); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*GetFeatures); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*Features); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*ClearSession); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*ApplySettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*ApplyFlags); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*ChangePin); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*Ping); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*Cancel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*GetEntropy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*Entropy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*WipeDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*LoadDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*ResetDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*BackupDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*EntropyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*EntropyAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*RecoveryDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*WordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*WordAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*SetU2FCounter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_management_proto_rawDesc, + NumEnums: 3, + NumMessages: 21, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_management_proto_goTypes, + DependencyIndexes: file_messages_management_proto_depIdxs, + EnumInfos: file_messages_management_proto_enumTypes, + MessageInfos: file_messages_management_proto_msgTypes, + }.Build() + File_messages_management_proto = out.File + file_messages_management_proto_rawDesc = nil + file_messages_management_proto_goTypes = nil + file_messages_management_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-management.proto b/accounts/usbwallet/trezor/messages-management.proto index 0ab825a1bc..55eb58983e 100644 --- a/accounts/usbwallet/trezor/messages-management.proto +++ b/accounts/usbwallet/trezor/messages-management.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.management; +option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageManagement"; diff --git a/accounts/usbwallet/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go index af0c957144..4518db679e 100644 --- a/accounts/usbwallet/trezor/messages.pb.go +++ b/accounts/usbwallet/trezor/messages.pb.go @@ -1,26 +1,29 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: messages.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" ) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) // * // Mapping between TREZOR wire identifier (uint) and a protobuf message @@ -241,397 +244,399 @@ const ( MessageType_MessageType_BinanceSignedTx MessageType = 709 ) -var MessageType_name = map[int32]string{ - 0: "MessageType_Initialize", - 1: "MessageType_Ping", - 2: "MessageType_Success", - 3: "MessageType_Failure", - 4: "MessageType_ChangePin", - 5: "MessageType_WipeDevice", - 9: "MessageType_GetEntropy", - 10: "MessageType_Entropy", - 13: "MessageType_LoadDevice", - 14: "MessageType_ResetDevice", - 17: "MessageType_Features", - 18: "MessageType_PinMatrixRequest", - 19: "MessageType_PinMatrixAck", - 20: "MessageType_Cancel", - 24: "MessageType_ClearSession", - 25: "MessageType_ApplySettings", - 26: "MessageType_ButtonRequest", - 27: "MessageType_ButtonAck", - 28: "MessageType_ApplyFlags", - 34: "MessageType_BackupDevice", - 35: "MessageType_EntropyRequest", - 36: "MessageType_EntropyAck", - 41: "MessageType_PassphraseRequest", - 42: "MessageType_PassphraseAck", - 77: "MessageType_PassphraseStateRequest", - 78: "MessageType_PassphraseStateAck", - 45: "MessageType_RecoveryDevice", - 46: "MessageType_WordRequest", - 47: "MessageType_WordAck", - 55: "MessageType_GetFeatures", - 63: "MessageType_SetU2FCounter", - 6: "MessageType_FirmwareErase", - 7: "MessageType_FirmwareUpload", - 8: "MessageType_FirmwareRequest", - 32: "MessageType_SelfTest", - 11: "MessageType_GetPublicKey", - 12: "MessageType_PublicKey", - 15: "MessageType_SignTx", - 21: "MessageType_TxRequest", - 22: "MessageType_TxAck", - 29: "MessageType_GetAddress", - 30: "MessageType_Address", - 38: "MessageType_SignMessage", - 39: "MessageType_VerifyMessage", - 40: "MessageType_MessageSignature", - 23: "MessageType_CipherKeyValue", - 48: "MessageType_CipheredKeyValue", - 53: "MessageType_SignIdentity", - 54: "MessageType_SignedIdentity", - 61: "MessageType_GetECDHSessionKey", - 62: "MessageType_ECDHSessionKey", - 71: "MessageType_CosiCommit", - 72: "MessageType_CosiCommitment", - 73: "MessageType_CosiSign", - 74: "MessageType_CosiSignature", - 100: "MessageType_DebugLinkDecision", - 101: "MessageType_DebugLinkGetState", - 102: "MessageType_DebugLinkState", - 103: "MessageType_DebugLinkStop", - 104: "MessageType_DebugLinkLog", - 110: "MessageType_DebugLinkMemoryRead", - 111: "MessageType_DebugLinkMemory", - 112: "MessageType_DebugLinkMemoryWrite", - 113: "MessageType_DebugLinkFlashErase", - 450: "MessageType_EthereumGetPublicKey", - 451: "MessageType_EthereumPublicKey", - 56: "MessageType_EthereumGetAddress", - 57: "MessageType_EthereumAddress", - 58: "MessageType_EthereumSignTx", - 59: "MessageType_EthereumTxRequest", - 60: "MessageType_EthereumTxAck", - 64: "MessageType_EthereumSignMessage", - 65: "MessageType_EthereumVerifyMessage", - 66: "MessageType_EthereumMessageSignature", - 67: "MessageType_NEMGetAddress", - 68: "MessageType_NEMAddress", - 69: "MessageType_NEMSignTx", - 70: "MessageType_NEMSignedTx", - 75: "MessageType_NEMDecryptMessage", - 76: "MessageType_NEMDecryptedMessage", - 114: "MessageType_LiskGetAddress", - 115: "MessageType_LiskAddress", - 116: "MessageType_LiskSignTx", - 117: "MessageType_LiskSignedTx", - 118: "MessageType_LiskSignMessage", - 119: "MessageType_LiskMessageSignature", - 120: "MessageType_LiskVerifyMessage", - 121: "MessageType_LiskGetPublicKey", - 122: "MessageType_LiskPublicKey", - 150: "MessageType_TezosGetAddress", - 151: "MessageType_TezosAddress", - 152: "MessageType_TezosSignTx", - 153: "MessageType_TezosSignedTx", - 154: "MessageType_TezosGetPublicKey", - 155: "MessageType_TezosPublicKey", - 202: "MessageType_StellarSignTx", - 203: "MessageType_StellarTxOpRequest", - 207: "MessageType_StellarGetAddress", - 208: "MessageType_StellarAddress", - 210: "MessageType_StellarCreateAccountOp", - 211: "MessageType_StellarPaymentOp", - 212: "MessageType_StellarPathPaymentOp", - 213: "MessageType_StellarManageOfferOp", - 214: "MessageType_StellarCreatePassiveOfferOp", - 215: "MessageType_StellarSetOptionsOp", - 216: "MessageType_StellarChangeTrustOp", - 217: "MessageType_StellarAllowTrustOp", - 218: "MessageType_StellarAccountMergeOp", - 220: "MessageType_StellarManageDataOp", - 221: "MessageType_StellarBumpSequenceOp", - 230: "MessageType_StellarSignedTx", - 250: "MessageType_TronGetAddress", - 251: "MessageType_TronAddress", - 252: "MessageType_TronSignTx", - 253: "MessageType_TronSignedTx", - 303: "MessageType_CardanoSignTx", - 304: "MessageType_CardanoTxRequest", - 305: "MessageType_CardanoGetPublicKey", - 306: "MessageType_CardanoPublicKey", - 307: "MessageType_CardanoGetAddress", - 308: "MessageType_CardanoAddress", - 309: "MessageType_CardanoTxAck", - 310: "MessageType_CardanoSignedTx", - 350: "MessageType_OntologyGetAddress", - 351: "MessageType_OntologyAddress", - 352: "MessageType_OntologyGetPublicKey", - 353: "MessageType_OntologyPublicKey", - 354: "MessageType_OntologySignTransfer", - 355: "MessageType_OntologySignedTransfer", - 356: "MessageType_OntologySignWithdrawOng", - 357: "MessageType_OntologySignedWithdrawOng", - 358: "MessageType_OntologySignOntIdRegister", - 359: "MessageType_OntologySignedOntIdRegister", - 360: "MessageType_OntologySignOntIdAddAttributes", - 361: "MessageType_OntologySignedOntIdAddAttributes", - 400: "MessageType_RippleGetAddress", - 401: "MessageType_RippleAddress", - 402: "MessageType_RippleSignTx", - 403: "MessageType_RippleSignedTx", - 501: "MessageType_MoneroTransactionInitRequest", - 502: "MessageType_MoneroTransactionInitAck", - 503: "MessageType_MoneroTransactionSetInputRequest", - 504: "MessageType_MoneroTransactionSetInputAck", - 505: "MessageType_MoneroTransactionInputsPermutationRequest", - 506: "MessageType_MoneroTransactionInputsPermutationAck", - 507: "MessageType_MoneroTransactionInputViniRequest", - 508: "MessageType_MoneroTransactionInputViniAck", - 509: "MessageType_MoneroTransactionAllInputsSetRequest", - 510: "MessageType_MoneroTransactionAllInputsSetAck", - 511: "MessageType_MoneroTransactionSetOutputRequest", - 512: "MessageType_MoneroTransactionSetOutputAck", - 513: "MessageType_MoneroTransactionAllOutSetRequest", - 514: "MessageType_MoneroTransactionAllOutSetAck", - 515: "MessageType_MoneroTransactionSignInputRequest", - 516: "MessageType_MoneroTransactionSignInputAck", - 517: "MessageType_MoneroTransactionFinalRequest", - 518: "MessageType_MoneroTransactionFinalAck", - 530: "MessageType_MoneroKeyImageExportInitRequest", - 531: "MessageType_MoneroKeyImageExportInitAck", - 532: "MessageType_MoneroKeyImageSyncStepRequest", - 533: "MessageType_MoneroKeyImageSyncStepAck", - 534: "MessageType_MoneroKeyImageSyncFinalRequest", - 535: "MessageType_MoneroKeyImageSyncFinalAck", - 540: "MessageType_MoneroGetAddress", - 541: "MessageType_MoneroAddress", - 542: "MessageType_MoneroGetWatchKey", - 543: "MessageType_MoneroWatchKey", - 546: "MessageType_DebugMoneroDiagRequest", - 547: "MessageType_DebugMoneroDiagAck", - 550: "MessageType_MoneroGetTxKeyRequest", - 551: "MessageType_MoneroGetTxKeyAck", - 552: "MessageType_MoneroLiveRefreshStartRequest", - 553: "MessageType_MoneroLiveRefreshStartAck", - 554: "MessageType_MoneroLiveRefreshStepRequest", - 555: "MessageType_MoneroLiveRefreshStepAck", - 556: "MessageType_MoneroLiveRefreshFinalRequest", - 557: "MessageType_MoneroLiveRefreshFinalAck", - 600: "MessageType_EosGetPublicKey", - 601: "MessageType_EosPublicKey", - 602: "MessageType_EosSignTx", - 603: "MessageType_EosTxActionRequest", - 604: "MessageType_EosTxActionAck", - 605: "MessageType_EosSignedTx", - 700: "MessageType_BinanceGetAddress", - 701: "MessageType_BinanceAddress", - 702: "MessageType_BinanceGetPublicKey", - 703: "MessageType_BinancePublicKey", - 704: "MessageType_BinanceSignTx", - 705: "MessageType_BinanceTxRequest", - 706: "MessageType_BinanceTransferMsg", - 707: "MessageType_BinanceOrderMsg", - 708: "MessageType_BinanceCancelMsg", - 709: "MessageType_BinanceSignedTx", -} - -var MessageType_value = map[string]int32{ - "MessageType_Initialize": 0, - "MessageType_Ping": 1, - "MessageType_Success": 2, - "MessageType_Failure": 3, - "MessageType_ChangePin": 4, - "MessageType_WipeDevice": 5, - "MessageType_GetEntropy": 9, - "MessageType_Entropy": 10, - "MessageType_LoadDevice": 13, - "MessageType_ResetDevice": 14, - "MessageType_Features": 17, - "MessageType_PinMatrixRequest": 18, - "MessageType_PinMatrixAck": 19, - "MessageType_Cancel": 20, - "MessageType_ClearSession": 24, - "MessageType_ApplySettings": 25, - "MessageType_ButtonRequest": 26, - "MessageType_ButtonAck": 27, - "MessageType_ApplyFlags": 28, - "MessageType_BackupDevice": 34, - "MessageType_EntropyRequest": 35, - "MessageType_EntropyAck": 36, - "MessageType_PassphraseRequest": 41, - "MessageType_PassphraseAck": 42, - "MessageType_PassphraseStateRequest": 77, - "MessageType_PassphraseStateAck": 78, - "MessageType_RecoveryDevice": 45, - "MessageType_WordRequest": 46, - "MessageType_WordAck": 47, - "MessageType_GetFeatures": 55, - "MessageType_SetU2FCounter": 63, - "MessageType_FirmwareErase": 6, - "MessageType_FirmwareUpload": 7, - "MessageType_FirmwareRequest": 8, - "MessageType_SelfTest": 32, - "MessageType_GetPublicKey": 11, - "MessageType_PublicKey": 12, - "MessageType_SignTx": 15, - "MessageType_TxRequest": 21, - "MessageType_TxAck": 22, - "MessageType_GetAddress": 29, - "MessageType_Address": 30, - "MessageType_SignMessage": 38, - "MessageType_VerifyMessage": 39, - "MessageType_MessageSignature": 40, - "MessageType_CipherKeyValue": 23, - "MessageType_CipheredKeyValue": 48, - "MessageType_SignIdentity": 53, - "MessageType_SignedIdentity": 54, - "MessageType_GetECDHSessionKey": 61, - "MessageType_ECDHSessionKey": 62, - "MessageType_CosiCommit": 71, - "MessageType_CosiCommitment": 72, - "MessageType_CosiSign": 73, - "MessageType_CosiSignature": 74, - "MessageType_DebugLinkDecision": 100, - "MessageType_DebugLinkGetState": 101, - "MessageType_DebugLinkState": 102, - "MessageType_DebugLinkStop": 103, - "MessageType_DebugLinkLog": 104, - "MessageType_DebugLinkMemoryRead": 110, - "MessageType_DebugLinkMemory": 111, - "MessageType_DebugLinkMemoryWrite": 112, - "MessageType_DebugLinkFlashErase": 113, - "MessageType_EthereumGetPublicKey": 450, - "MessageType_EthereumPublicKey": 451, - "MessageType_EthereumGetAddress": 56, - "MessageType_EthereumAddress": 57, - "MessageType_EthereumSignTx": 58, - "MessageType_EthereumTxRequest": 59, - "MessageType_EthereumTxAck": 60, - "MessageType_EthereumSignMessage": 64, - "MessageType_EthereumVerifyMessage": 65, - "MessageType_EthereumMessageSignature": 66, - "MessageType_NEMGetAddress": 67, - "MessageType_NEMAddress": 68, - "MessageType_NEMSignTx": 69, - "MessageType_NEMSignedTx": 70, - "MessageType_NEMDecryptMessage": 75, - "MessageType_NEMDecryptedMessage": 76, - "MessageType_LiskGetAddress": 114, - "MessageType_LiskAddress": 115, - "MessageType_LiskSignTx": 116, - "MessageType_LiskSignedTx": 117, - "MessageType_LiskSignMessage": 118, - "MessageType_LiskMessageSignature": 119, - "MessageType_LiskVerifyMessage": 120, - "MessageType_LiskGetPublicKey": 121, - "MessageType_LiskPublicKey": 122, - "MessageType_TezosGetAddress": 150, - "MessageType_TezosAddress": 151, - "MessageType_TezosSignTx": 152, - "MessageType_TezosSignedTx": 153, - "MessageType_TezosGetPublicKey": 154, - "MessageType_TezosPublicKey": 155, - "MessageType_StellarSignTx": 202, - "MessageType_StellarTxOpRequest": 203, - "MessageType_StellarGetAddress": 207, - "MessageType_StellarAddress": 208, - "MessageType_StellarCreateAccountOp": 210, - "MessageType_StellarPaymentOp": 211, - "MessageType_StellarPathPaymentOp": 212, - "MessageType_StellarManageOfferOp": 213, - "MessageType_StellarCreatePassiveOfferOp": 214, - "MessageType_StellarSetOptionsOp": 215, - "MessageType_StellarChangeTrustOp": 216, - "MessageType_StellarAllowTrustOp": 217, - "MessageType_StellarAccountMergeOp": 218, - "MessageType_StellarManageDataOp": 220, - "MessageType_StellarBumpSequenceOp": 221, - "MessageType_StellarSignedTx": 230, - "MessageType_TronGetAddress": 250, - "MessageType_TronAddress": 251, - "MessageType_TronSignTx": 252, - "MessageType_TronSignedTx": 253, - "MessageType_CardanoSignTx": 303, - "MessageType_CardanoTxRequest": 304, - "MessageType_CardanoGetPublicKey": 305, - "MessageType_CardanoPublicKey": 306, - "MessageType_CardanoGetAddress": 307, - "MessageType_CardanoAddress": 308, - "MessageType_CardanoTxAck": 309, - "MessageType_CardanoSignedTx": 310, - "MessageType_OntologyGetAddress": 350, - "MessageType_OntologyAddress": 351, - "MessageType_OntologyGetPublicKey": 352, - "MessageType_OntologyPublicKey": 353, - "MessageType_OntologySignTransfer": 354, - "MessageType_OntologySignedTransfer": 355, - "MessageType_OntologySignWithdrawOng": 356, - "MessageType_OntologySignedWithdrawOng": 357, - "MessageType_OntologySignOntIdRegister": 358, - "MessageType_OntologySignedOntIdRegister": 359, - "MessageType_OntologySignOntIdAddAttributes": 360, - "MessageType_OntologySignedOntIdAddAttributes": 361, - "MessageType_RippleGetAddress": 400, - "MessageType_RippleAddress": 401, - "MessageType_RippleSignTx": 402, - "MessageType_RippleSignedTx": 403, - "MessageType_MoneroTransactionInitRequest": 501, - "MessageType_MoneroTransactionInitAck": 502, - "MessageType_MoneroTransactionSetInputRequest": 503, - "MessageType_MoneroTransactionSetInputAck": 504, - "MessageType_MoneroTransactionInputsPermutationRequest": 505, - "MessageType_MoneroTransactionInputsPermutationAck": 506, - "MessageType_MoneroTransactionInputViniRequest": 507, - "MessageType_MoneroTransactionInputViniAck": 508, - "MessageType_MoneroTransactionAllInputsSetRequest": 509, - "MessageType_MoneroTransactionAllInputsSetAck": 510, - "MessageType_MoneroTransactionSetOutputRequest": 511, - "MessageType_MoneroTransactionSetOutputAck": 512, - "MessageType_MoneroTransactionAllOutSetRequest": 513, - "MessageType_MoneroTransactionAllOutSetAck": 514, - "MessageType_MoneroTransactionSignInputRequest": 515, - "MessageType_MoneroTransactionSignInputAck": 516, - "MessageType_MoneroTransactionFinalRequest": 517, - "MessageType_MoneroTransactionFinalAck": 518, - "MessageType_MoneroKeyImageExportInitRequest": 530, - "MessageType_MoneroKeyImageExportInitAck": 531, - "MessageType_MoneroKeyImageSyncStepRequest": 532, - "MessageType_MoneroKeyImageSyncStepAck": 533, - "MessageType_MoneroKeyImageSyncFinalRequest": 534, - "MessageType_MoneroKeyImageSyncFinalAck": 535, - "MessageType_MoneroGetAddress": 540, - "MessageType_MoneroAddress": 541, - "MessageType_MoneroGetWatchKey": 542, - "MessageType_MoneroWatchKey": 543, - "MessageType_DebugMoneroDiagRequest": 546, - "MessageType_DebugMoneroDiagAck": 547, - "MessageType_MoneroGetTxKeyRequest": 550, - "MessageType_MoneroGetTxKeyAck": 551, - "MessageType_MoneroLiveRefreshStartRequest": 552, - "MessageType_MoneroLiveRefreshStartAck": 553, - "MessageType_MoneroLiveRefreshStepRequest": 554, - "MessageType_MoneroLiveRefreshStepAck": 555, - "MessageType_MoneroLiveRefreshFinalRequest": 556, - "MessageType_MoneroLiveRefreshFinalAck": 557, - "MessageType_EosGetPublicKey": 600, - "MessageType_EosPublicKey": 601, - "MessageType_EosSignTx": 602, - "MessageType_EosTxActionRequest": 603, - "MessageType_EosTxActionAck": 604, - "MessageType_EosSignedTx": 605, - "MessageType_BinanceGetAddress": 700, - "MessageType_BinanceAddress": 701, - "MessageType_BinanceGetPublicKey": 702, - "MessageType_BinancePublicKey": 703, - "MessageType_BinanceSignTx": 704, - "MessageType_BinanceTxRequest": 705, - "MessageType_BinanceTransferMsg": 706, - "MessageType_BinanceOrderMsg": 707, - "MessageType_BinanceCancelMsg": 708, - "MessageType_BinanceSignedTx": 709, -} +// Enum value maps for MessageType. +var ( + MessageType_name = map[int32]string{ + 0: "MessageType_Initialize", + 1: "MessageType_Ping", + 2: "MessageType_Success", + 3: "MessageType_Failure", + 4: "MessageType_ChangePin", + 5: "MessageType_WipeDevice", + 9: "MessageType_GetEntropy", + 10: "MessageType_Entropy", + 13: "MessageType_LoadDevice", + 14: "MessageType_ResetDevice", + 17: "MessageType_Features", + 18: "MessageType_PinMatrixRequest", + 19: "MessageType_PinMatrixAck", + 20: "MessageType_Cancel", + 24: "MessageType_ClearSession", + 25: "MessageType_ApplySettings", + 26: "MessageType_ButtonRequest", + 27: "MessageType_ButtonAck", + 28: "MessageType_ApplyFlags", + 34: "MessageType_BackupDevice", + 35: "MessageType_EntropyRequest", + 36: "MessageType_EntropyAck", + 41: "MessageType_PassphraseRequest", + 42: "MessageType_PassphraseAck", + 77: "MessageType_PassphraseStateRequest", + 78: "MessageType_PassphraseStateAck", + 45: "MessageType_RecoveryDevice", + 46: "MessageType_WordRequest", + 47: "MessageType_WordAck", + 55: "MessageType_GetFeatures", + 63: "MessageType_SetU2FCounter", + 6: "MessageType_FirmwareErase", + 7: "MessageType_FirmwareUpload", + 8: "MessageType_FirmwareRequest", + 32: "MessageType_SelfTest", + 11: "MessageType_GetPublicKey", + 12: "MessageType_PublicKey", + 15: "MessageType_SignTx", + 21: "MessageType_TxRequest", + 22: "MessageType_TxAck", + 29: "MessageType_GetAddress", + 30: "MessageType_Address", + 38: "MessageType_SignMessage", + 39: "MessageType_VerifyMessage", + 40: "MessageType_MessageSignature", + 23: "MessageType_CipherKeyValue", + 48: "MessageType_CipheredKeyValue", + 53: "MessageType_SignIdentity", + 54: "MessageType_SignedIdentity", + 61: "MessageType_GetECDHSessionKey", + 62: "MessageType_ECDHSessionKey", + 71: "MessageType_CosiCommit", + 72: "MessageType_CosiCommitment", + 73: "MessageType_CosiSign", + 74: "MessageType_CosiSignature", + 100: "MessageType_DebugLinkDecision", + 101: "MessageType_DebugLinkGetState", + 102: "MessageType_DebugLinkState", + 103: "MessageType_DebugLinkStop", + 104: "MessageType_DebugLinkLog", + 110: "MessageType_DebugLinkMemoryRead", + 111: "MessageType_DebugLinkMemory", + 112: "MessageType_DebugLinkMemoryWrite", + 113: "MessageType_DebugLinkFlashErase", + 450: "MessageType_EthereumGetPublicKey", + 451: "MessageType_EthereumPublicKey", + 56: "MessageType_EthereumGetAddress", + 57: "MessageType_EthereumAddress", + 58: "MessageType_EthereumSignTx", + 59: "MessageType_EthereumTxRequest", + 60: "MessageType_EthereumTxAck", + 64: "MessageType_EthereumSignMessage", + 65: "MessageType_EthereumVerifyMessage", + 66: "MessageType_EthereumMessageSignature", + 67: "MessageType_NEMGetAddress", + 68: "MessageType_NEMAddress", + 69: "MessageType_NEMSignTx", + 70: "MessageType_NEMSignedTx", + 75: "MessageType_NEMDecryptMessage", + 76: "MessageType_NEMDecryptedMessage", + 114: "MessageType_LiskGetAddress", + 115: "MessageType_LiskAddress", + 116: "MessageType_LiskSignTx", + 117: "MessageType_LiskSignedTx", + 118: "MessageType_LiskSignMessage", + 119: "MessageType_LiskMessageSignature", + 120: "MessageType_LiskVerifyMessage", + 121: "MessageType_LiskGetPublicKey", + 122: "MessageType_LiskPublicKey", + 150: "MessageType_TezosGetAddress", + 151: "MessageType_TezosAddress", + 152: "MessageType_TezosSignTx", + 153: "MessageType_TezosSignedTx", + 154: "MessageType_TezosGetPublicKey", + 155: "MessageType_TezosPublicKey", + 202: "MessageType_StellarSignTx", + 203: "MessageType_StellarTxOpRequest", + 207: "MessageType_StellarGetAddress", + 208: "MessageType_StellarAddress", + 210: "MessageType_StellarCreateAccountOp", + 211: "MessageType_StellarPaymentOp", + 212: "MessageType_StellarPathPaymentOp", + 213: "MessageType_StellarManageOfferOp", + 214: "MessageType_StellarCreatePassiveOfferOp", + 215: "MessageType_StellarSetOptionsOp", + 216: "MessageType_StellarChangeTrustOp", + 217: "MessageType_StellarAllowTrustOp", + 218: "MessageType_StellarAccountMergeOp", + 220: "MessageType_StellarManageDataOp", + 221: "MessageType_StellarBumpSequenceOp", + 230: "MessageType_StellarSignedTx", + 250: "MessageType_TronGetAddress", + 251: "MessageType_TronAddress", + 252: "MessageType_TronSignTx", + 253: "MessageType_TronSignedTx", + 303: "MessageType_CardanoSignTx", + 304: "MessageType_CardanoTxRequest", + 305: "MessageType_CardanoGetPublicKey", + 306: "MessageType_CardanoPublicKey", + 307: "MessageType_CardanoGetAddress", + 308: "MessageType_CardanoAddress", + 309: "MessageType_CardanoTxAck", + 310: "MessageType_CardanoSignedTx", + 350: "MessageType_OntologyGetAddress", + 351: "MessageType_OntologyAddress", + 352: "MessageType_OntologyGetPublicKey", + 353: "MessageType_OntologyPublicKey", + 354: "MessageType_OntologySignTransfer", + 355: "MessageType_OntologySignedTransfer", + 356: "MessageType_OntologySignWithdrawOng", + 357: "MessageType_OntologySignedWithdrawOng", + 358: "MessageType_OntologySignOntIdRegister", + 359: "MessageType_OntologySignedOntIdRegister", + 360: "MessageType_OntologySignOntIdAddAttributes", + 361: "MessageType_OntologySignedOntIdAddAttributes", + 400: "MessageType_RippleGetAddress", + 401: "MessageType_RippleAddress", + 402: "MessageType_RippleSignTx", + 403: "MessageType_RippleSignedTx", + 501: "MessageType_MoneroTransactionInitRequest", + 502: "MessageType_MoneroTransactionInitAck", + 503: "MessageType_MoneroTransactionSetInputRequest", + 504: "MessageType_MoneroTransactionSetInputAck", + 505: "MessageType_MoneroTransactionInputsPermutationRequest", + 506: "MessageType_MoneroTransactionInputsPermutationAck", + 507: "MessageType_MoneroTransactionInputViniRequest", + 508: "MessageType_MoneroTransactionInputViniAck", + 509: "MessageType_MoneroTransactionAllInputsSetRequest", + 510: "MessageType_MoneroTransactionAllInputsSetAck", + 511: "MessageType_MoneroTransactionSetOutputRequest", + 512: "MessageType_MoneroTransactionSetOutputAck", + 513: "MessageType_MoneroTransactionAllOutSetRequest", + 514: "MessageType_MoneroTransactionAllOutSetAck", + 515: "MessageType_MoneroTransactionSignInputRequest", + 516: "MessageType_MoneroTransactionSignInputAck", + 517: "MessageType_MoneroTransactionFinalRequest", + 518: "MessageType_MoneroTransactionFinalAck", + 530: "MessageType_MoneroKeyImageExportInitRequest", + 531: "MessageType_MoneroKeyImageExportInitAck", + 532: "MessageType_MoneroKeyImageSyncStepRequest", + 533: "MessageType_MoneroKeyImageSyncStepAck", + 534: "MessageType_MoneroKeyImageSyncFinalRequest", + 535: "MessageType_MoneroKeyImageSyncFinalAck", + 540: "MessageType_MoneroGetAddress", + 541: "MessageType_MoneroAddress", + 542: "MessageType_MoneroGetWatchKey", + 543: "MessageType_MoneroWatchKey", + 546: "MessageType_DebugMoneroDiagRequest", + 547: "MessageType_DebugMoneroDiagAck", + 550: "MessageType_MoneroGetTxKeyRequest", + 551: "MessageType_MoneroGetTxKeyAck", + 552: "MessageType_MoneroLiveRefreshStartRequest", + 553: "MessageType_MoneroLiveRefreshStartAck", + 554: "MessageType_MoneroLiveRefreshStepRequest", + 555: "MessageType_MoneroLiveRefreshStepAck", + 556: "MessageType_MoneroLiveRefreshFinalRequest", + 557: "MessageType_MoneroLiveRefreshFinalAck", + 600: "MessageType_EosGetPublicKey", + 601: "MessageType_EosPublicKey", + 602: "MessageType_EosSignTx", + 603: "MessageType_EosTxActionRequest", + 604: "MessageType_EosTxActionAck", + 605: "MessageType_EosSignedTx", + 700: "MessageType_BinanceGetAddress", + 701: "MessageType_BinanceAddress", + 702: "MessageType_BinanceGetPublicKey", + 703: "MessageType_BinancePublicKey", + 704: "MessageType_BinanceSignTx", + 705: "MessageType_BinanceTxRequest", + 706: "MessageType_BinanceTransferMsg", + 707: "MessageType_BinanceOrderMsg", + 708: "MessageType_BinanceCancelMsg", + 709: "MessageType_BinanceSignedTx", + } + MessageType_value = map[string]int32{ + "MessageType_Initialize": 0, + "MessageType_Ping": 1, + "MessageType_Success": 2, + "MessageType_Failure": 3, + "MessageType_ChangePin": 4, + "MessageType_WipeDevice": 5, + "MessageType_GetEntropy": 9, + "MessageType_Entropy": 10, + "MessageType_LoadDevice": 13, + "MessageType_ResetDevice": 14, + "MessageType_Features": 17, + "MessageType_PinMatrixRequest": 18, + "MessageType_PinMatrixAck": 19, + "MessageType_Cancel": 20, + "MessageType_ClearSession": 24, + "MessageType_ApplySettings": 25, + "MessageType_ButtonRequest": 26, + "MessageType_ButtonAck": 27, + "MessageType_ApplyFlags": 28, + "MessageType_BackupDevice": 34, + "MessageType_EntropyRequest": 35, + "MessageType_EntropyAck": 36, + "MessageType_PassphraseRequest": 41, + "MessageType_PassphraseAck": 42, + "MessageType_PassphraseStateRequest": 77, + "MessageType_PassphraseStateAck": 78, + "MessageType_RecoveryDevice": 45, + "MessageType_WordRequest": 46, + "MessageType_WordAck": 47, + "MessageType_GetFeatures": 55, + "MessageType_SetU2FCounter": 63, + "MessageType_FirmwareErase": 6, + "MessageType_FirmwareUpload": 7, + "MessageType_FirmwareRequest": 8, + "MessageType_SelfTest": 32, + "MessageType_GetPublicKey": 11, + "MessageType_PublicKey": 12, + "MessageType_SignTx": 15, + "MessageType_TxRequest": 21, + "MessageType_TxAck": 22, + "MessageType_GetAddress": 29, + "MessageType_Address": 30, + "MessageType_SignMessage": 38, + "MessageType_VerifyMessage": 39, + "MessageType_MessageSignature": 40, + "MessageType_CipherKeyValue": 23, + "MessageType_CipheredKeyValue": 48, + "MessageType_SignIdentity": 53, + "MessageType_SignedIdentity": 54, + "MessageType_GetECDHSessionKey": 61, + "MessageType_ECDHSessionKey": 62, + "MessageType_CosiCommit": 71, + "MessageType_CosiCommitment": 72, + "MessageType_CosiSign": 73, + "MessageType_CosiSignature": 74, + "MessageType_DebugLinkDecision": 100, + "MessageType_DebugLinkGetState": 101, + "MessageType_DebugLinkState": 102, + "MessageType_DebugLinkStop": 103, + "MessageType_DebugLinkLog": 104, + "MessageType_DebugLinkMemoryRead": 110, + "MessageType_DebugLinkMemory": 111, + "MessageType_DebugLinkMemoryWrite": 112, + "MessageType_DebugLinkFlashErase": 113, + "MessageType_EthereumGetPublicKey": 450, + "MessageType_EthereumPublicKey": 451, + "MessageType_EthereumGetAddress": 56, + "MessageType_EthereumAddress": 57, + "MessageType_EthereumSignTx": 58, + "MessageType_EthereumTxRequest": 59, + "MessageType_EthereumTxAck": 60, + "MessageType_EthereumSignMessage": 64, + "MessageType_EthereumVerifyMessage": 65, + "MessageType_EthereumMessageSignature": 66, + "MessageType_NEMGetAddress": 67, + "MessageType_NEMAddress": 68, + "MessageType_NEMSignTx": 69, + "MessageType_NEMSignedTx": 70, + "MessageType_NEMDecryptMessage": 75, + "MessageType_NEMDecryptedMessage": 76, + "MessageType_LiskGetAddress": 114, + "MessageType_LiskAddress": 115, + "MessageType_LiskSignTx": 116, + "MessageType_LiskSignedTx": 117, + "MessageType_LiskSignMessage": 118, + "MessageType_LiskMessageSignature": 119, + "MessageType_LiskVerifyMessage": 120, + "MessageType_LiskGetPublicKey": 121, + "MessageType_LiskPublicKey": 122, + "MessageType_TezosGetAddress": 150, + "MessageType_TezosAddress": 151, + "MessageType_TezosSignTx": 152, + "MessageType_TezosSignedTx": 153, + "MessageType_TezosGetPublicKey": 154, + "MessageType_TezosPublicKey": 155, + "MessageType_StellarSignTx": 202, + "MessageType_StellarTxOpRequest": 203, + "MessageType_StellarGetAddress": 207, + "MessageType_StellarAddress": 208, + "MessageType_StellarCreateAccountOp": 210, + "MessageType_StellarPaymentOp": 211, + "MessageType_StellarPathPaymentOp": 212, + "MessageType_StellarManageOfferOp": 213, + "MessageType_StellarCreatePassiveOfferOp": 214, + "MessageType_StellarSetOptionsOp": 215, + "MessageType_StellarChangeTrustOp": 216, + "MessageType_StellarAllowTrustOp": 217, + "MessageType_StellarAccountMergeOp": 218, + "MessageType_StellarManageDataOp": 220, + "MessageType_StellarBumpSequenceOp": 221, + "MessageType_StellarSignedTx": 230, + "MessageType_TronGetAddress": 250, + "MessageType_TronAddress": 251, + "MessageType_TronSignTx": 252, + "MessageType_TronSignedTx": 253, + "MessageType_CardanoSignTx": 303, + "MessageType_CardanoTxRequest": 304, + "MessageType_CardanoGetPublicKey": 305, + "MessageType_CardanoPublicKey": 306, + "MessageType_CardanoGetAddress": 307, + "MessageType_CardanoAddress": 308, + "MessageType_CardanoTxAck": 309, + "MessageType_CardanoSignedTx": 310, + "MessageType_OntologyGetAddress": 350, + "MessageType_OntologyAddress": 351, + "MessageType_OntologyGetPublicKey": 352, + "MessageType_OntologyPublicKey": 353, + "MessageType_OntologySignTransfer": 354, + "MessageType_OntologySignedTransfer": 355, + "MessageType_OntologySignWithdrawOng": 356, + "MessageType_OntologySignedWithdrawOng": 357, + "MessageType_OntologySignOntIdRegister": 358, + "MessageType_OntologySignedOntIdRegister": 359, + "MessageType_OntologySignOntIdAddAttributes": 360, + "MessageType_OntologySignedOntIdAddAttributes": 361, + "MessageType_RippleGetAddress": 400, + "MessageType_RippleAddress": 401, + "MessageType_RippleSignTx": 402, + "MessageType_RippleSignedTx": 403, + "MessageType_MoneroTransactionInitRequest": 501, + "MessageType_MoneroTransactionInitAck": 502, + "MessageType_MoneroTransactionSetInputRequest": 503, + "MessageType_MoneroTransactionSetInputAck": 504, + "MessageType_MoneroTransactionInputsPermutationRequest": 505, + "MessageType_MoneroTransactionInputsPermutationAck": 506, + "MessageType_MoneroTransactionInputViniRequest": 507, + "MessageType_MoneroTransactionInputViniAck": 508, + "MessageType_MoneroTransactionAllInputsSetRequest": 509, + "MessageType_MoneroTransactionAllInputsSetAck": 510, + "MessageType_MoneroTransactionSetOutputRequest": 511, + "MessageType_MoneroTransactionSetOutputAck": 512, + "MessageType_MoneroTransactionAllOutSetRequest": 513, + "MessageType_MoneroTransactionAllOutSetAck": 514, + "MessageType_MoneroTransactionSignInputRequest": 515, + "MessageType_MoneroTransactionSignInputAck": 516, + "MessageType_MoneroTransactionFinalRequest": 517, + "MessageType_MoneroTransactionFinalAck": 518, + "MessageType_MoneroKeyImageExportInitRequest": 530, + "MessageType_MoneroKeyImageExportInitAck": 531, + "MessageType_MoneroKeyImageSyncStepRequest": 532, + "MessageType_MoneroKeyImageSyncStepAck": 533, + "MessageType_MoneroKeyImageSyncFinalRequest": 534, + "MessageType_MoneroKeyImageSyncFinalAck": 535, + "MessageType_MoneroGetAddress": 540, + "MessageType_MoneroAddress": 541, + "MessageType_MoneroGetWatchKey": 542, + "MessageType_MoneroWatchKey": 543, + "MessageType_DebugMoneroDiagRequest": 546, + "MessageType_DebugMoneroDiagAck": 547, + "MessageType_MoneroGetTxKeyRequest": 550, + "MessageType_MoneroGetTxKeyAck": 551, + "MessageType_MoneroLiveRefreshStartRequest": 552, + "MessageType_MoneroLiveRefreshStartAck": 553, + "MessageType_MoneroLiveRefreshStepRequest": 554, + "MessageType_MoneroLiveRefreshStepAck": 555, + "MessageType_MoneroLiveRefreshFinalRequest": 556, + "MessageType_MoneroLiveRefreshFinalAck": 557, + "MessageType_EosGetPublicKey": 600, + "MessageType_EosPublicKey": 601, + "MessageType_EosSignTx": 602, + "MessageType_EosTxActionRequest": 603, + "MessageType_EosTxActionAck": 604, + "MessageType_EosSignedTx": 605, + "MessageType_BinanceGetAddress": 700, + "MessageType_BinanceAddress": 701, + "MessageType_BinanceGetPublicKey": 702, + "MessageType_BinancePublicKey": 703, + "MessageType_BinanceSignTx": 704, + "MessageType_BinanceTxRequest": 705, + "MessageType_BinanceTransferMsg": 706, + "MessageType_BinanceOrderMsg": 707, + "MessageType_BinanceCancelMsg": 708, + "MessageType_BinanceSignedTx": 709, + } +) func (x MessageType) Enum() *MessageType { p := new(MessageType) @@ -640,250 +645,722 @@ func (x MessageType) Enum() *MessageType { } func (x MessageType) String() string { - return proto.EnumName(MessageType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MessageType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_proto_enumTypes[0].Descriptor() } -func (x *MessageType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType") +func (MessageType) Type() protoreflect.EnumType { + return &file_messages_proto_enumTypes[0] +} + +func (x MessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *MessageType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = MessageType(value) + *x = MessageType(num) return nil } +// Deprecated: Use MessageType.Descriptor instead. func (MessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{0} + return file_messages_proto_rawDescGZIP(), []int{0} } -var E_WireIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50002, - Name: "hw.trezor.messages.wire_in", - Tag: "varint,50002,opt,name=wire_in", - Filename: "messages.proto", +var file_messages_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50002, + Name: "hw.trezor.messages.wire_in", + Tag: "varint,50002,opt,name=wire_in", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50003, + Name: "hw.trezor.messages.wire_out", + Tag: "varint,50003,opt,name=wire_out", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50004, + Name: "hw.trezor.messages.wire_debug_in", + Tag: "varint,50004,opt,name=wire_debug_in", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50005, + Name: "hw.trezor.messages.wire_debug_out", + Tag: "varint,50005,opt,name=wire_debug_out", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50006, + Name: "hw.trezor.messages.wire_tiny", + Tag: "varint,50006,opt,name=wire_tiny", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50007, + Name: "hw.trezor.messages.wire_bootloader", + Tag: "varint,50007,opt,name=wire_bootloader", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50008, + Name: "hw.trezor.messages.wire_no_fsm", + Tag: "varint,50008,opt,name=wire_no_fsm", + Filename: "messages.proto", + }, } -var E_WireOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50003, - Name: "hw.trezor.messages.wire_out", - Tag: "varint,50003,opt,name=wire_out", - Filename: "messages.proto", -} +// Extension fields to descriptorpb.EnumValueOptions. +var ( + // optional bool wire_in = 50002; + E_WireIn = &file_messages_proto_extTypes[0] // message can be transmitted via wire from PC to TREZOR + // optional bool wire_out = 50003; + E_WireOut = &file_messages_proto_extTypes[1] // message can be transmitted via wire from TREZOR to PC + // optional bool wire_debug_in = 50004; + E_WireDebugIn = &file_messages_proto_extTypes[2] // message can be transmitted via debug wire from PC to TREZOR + // optional bool wire_debug_out = 50005; + E_WireDebugOut = &file_messages_proto_extTypes[3] // message can be transmitted via debug wire from TREZOR to PC + // optional bool wire_tiny = 50006; + E_WireTiny = &file_messages_proto_extTypes[4] // message is handled by TREZOR when the USB stack is in tiny mode + // optional bool wire_bootloader = 50007; + E_WireBootloader = &file_messages_proto_extTypes[5] // message is only handled by TREZOR Bootloader + // optional bool wire_no_fsm = 50008; + E_WireNoFsm = &file_messages_proto_extTypes[6] // message is not handled by TREZOR unless the USB stack is in tiny mode +) -var E_WireDebugIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50004, - Name: "hw.trezor.messages.wire_debug_in", - Tag: "varint,50004,opt,name=wire_debug_in", - Filename: "messages.proto", -} +var File_messages_proto protoreflect.FileDescriptor -var E_WireDebugOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50005, - Name: "hw.trezor.messages.wire_debug_out", - Tag: "varint,50005,opt,name=wire_debug_out", - Filename: "messages.proto", +var file_messages_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x12, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0xb9, 0x3f, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x10, 0x00, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x1a, 0x0a, 0x10, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x67, + 0x10, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, + 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x10, 0x03, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x69, 0x6e, 0x10, + 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x10, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x10, 0x09, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x10, 0x0a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x6f, 0x61, 0x64, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x10, 0x0d, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x0e, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x1e, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x10, 0x11, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, + 0x26, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, + 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, + 0x12, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x41, 0x63, 0x6b, 0x10, 0x13, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, + 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x10, 0x14, 0x1a, 0x08, 0x90, 0xb5, 0x18, + 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x10, 0x18, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x10, 0x19, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, + 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x1a, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0x1b, 0x1a, 0x0c, + 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x10, 0x1c, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, + 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x22, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x10, 0x23, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x41, + 0x63, 0x6b, 0x10, 0x24, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x29, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x41, 0x63, 0x6b, + 0x10, 0x2a, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, + 0x12, 0x2c, 0x0a, 0x22, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x4d, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, + 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x61, + 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x63, 0x6b, + 0x10, 0x4e, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, + 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x2d, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x10, 0x2e, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x6b, + 0x10, 0x2f, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x10, 0x37, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x74, 0x55, 0x32, + 0x46, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x10, 0x3f, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, + 0x12, 0x27, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x45, 0x72, 0x61, 0x73, 0x65, 0x10, 0x06, 0x1a, + 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1a, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, + 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x10, 0x07, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0x08, 0x1a, 0x08, 0x98, 0xb5, 0x18, 0x01, 0xb8, 0xb5, 0x18, 0x01, 0x12, 0x22, + 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, + 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x10, 0x20, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, 0xb5, + 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x0b, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, + 0x0c, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1c, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x0f, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x15, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1b, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x10, 0x16, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x1d, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x1e, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, + 0x26, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x10, 0x27, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x28, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x10, 0x17, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x64, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x10, 0x30, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x10, 0x35, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x10, 0x36, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x45, + 0x43, 0x44, 0x48, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0x3d, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x10, 0x3e, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x47, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, + 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, + 0x69, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x48, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x1e, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x10, 0x49, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x10, 0x4a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2f, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, + 0x6b, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x64, 0x1a, 0x0c, 0xa0, 0xb5, 0x18, + 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x1d, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, + 0x6e, 0x6b, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x65, 0x1a, 0x08, 0xa0, 0xb5, + 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x10, 0x66, 0x1a, 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x6f, 0x70, 0x10, 0x67, 0x1a, 0x04, 0xa0, 0xb5, 0x18, + 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x67, 0x10, 0x68, 0x1a, + 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x10, 0x6e, 0x1a, 0x04, 0xa0, 0xb5, 0x18, 0x01, + 0x12, 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x10, + 0x6f, 0x1a, 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, + 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x10, 0x70, 0x1a, 0x04, 0xa0, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x46, 0x6c, 0x61, 0x73, + 0x68, 0x45, 0x72, 0x61, 0x73, 0x65, 0x10, 0x71, 0x1a, 0x04, 0xa0, 0xb5, 0x18, 0x01, 0x12, 0x2b, + 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x10, 0xc2, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xc3, 0x03, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x38, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x39, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, 0x69, + 0x67, 0x6e, 0x54, 0x78, 0x10, 0x3a, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x3b, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x10, 0x3c, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x40, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x41, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x2e, 0x0a, 0x24, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x42, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, + 0x43, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0x44, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x53, 0x69, 0x67, 0x6e, + 0x54, 0x78, 0x10, 0x45, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x46, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, + 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, + 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x4b, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x4c, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, + 0x72, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x10, 0x73, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x53, 0x69, + 0x67, 0x6e, 0x54, 0x78, 0x10, 0x74, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x75, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4c, 0x69, 0x73, 0x6b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, + 0x76, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x77, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x10, 0x78, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, + 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x79, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x10, 0x7a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x47, 0x65, + 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x96, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, + 0x01, 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x97, 0x01, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x54, + 0x78, 0x10, 0x98, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x53, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x99, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x10, 0x9a, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x9b, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xca, + 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x54, 0x78, + 0x4f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xcb, 0x01, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x10, 0xcf, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, + 0x6c, 0x61, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xd0, 0x01, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x70, 0x10, 0xd2, 0x01, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x4f, 0x70, 0x10, 0xd3, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, + 0x61, 0x72, 0x50, 0x61, 0x74, 0x68, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x10, + 0xd4, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x4f, 0x70, 0x10, 0xd5, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x4f, 0x70, + 0x10, 0xd6, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, + 0x53, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x70, 0x10, 0xd7, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x4f, 0x70, 0x10, 0xd8, 0x01, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x4f, 0x70, 0x10, 0xd9, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2c, + 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, + 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x4f, 0x70, 0x10, 0xda, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, + 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4f, 0x70, 0x10, + 0xdc, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2c, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x42, + 0x75, 0x6d, 0x70, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x10, 0xdd, 0x01, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xe6, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x25, + 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, + 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xfa, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x10, 0xfb, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x16, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, 0x53, 0x69, 0x67, + 0x6e, 0x54, 0x78, 0x10, 0xfc, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xfd, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xaf, + 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x54, 0x78, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xb0, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x10, 0xb1, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, + 0x61, 0x6e, 0x6f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xb2, 0x02, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x47, 0x65, 0x74, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xb3, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, + 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xb4, 0x02, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x10, 0xb5, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, + 0x6e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xb6, 0x02, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x47, 0x65, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xde, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, + 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, + 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xdf, 0x02, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x47, 0x65, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xe0, 0x02, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x10, 0xe1, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, + 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x10, 0xe2, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x10, 0xe3, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2e, 0x0a, 0x23, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x69, 0x67, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x4f, 0x6e, 0x67, + 0x10, 0xe4, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x4f, + 0x6e, 0x67, 0x10, 0xe5, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x6e, 0x74, 0x49, 0x64, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x10, 0xe6, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, + 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x6e, 0x74, 0x49, 0x64, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x10, 0xe7, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x35, 0x0a, 0x2a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x6e, 0x74, + 0x49, 0x64, 0x41, 0x64, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x10, + 0xe8, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x37, 0x0a, 0x2c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x6e, 0x74, 0x49, 0x64, 0x41, 0x64, 0x64, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x10, 0xe9, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0x90, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x91, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x92, 0x03, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x54, 0x78, 0x10, 0x93, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x69, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xf5, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x2f, 0x0a, 0x24, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xf6, 0x03, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x37, 0x0a, 0x2c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xf7, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xf8, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x40, 0x0a, 0x35, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xf9, 0x03, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x3c, 0x0a, 0x31, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x75, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0xfa, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x56, 0x69, 0x6e, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x10, 0xfb, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x56, 0x69, 0x6e, 0x69, 0x41, 0x63, 0x6b, 0x10, 0xfc, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x3b, 0x0a, 0x30, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x10, 0xfd, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x37, 0x0a, + 0x2c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, + 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, + 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x53, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xfe, 0x03, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xff, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x80, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x6c, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x81, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x41, 0x6c, 0x6c, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x82, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x83, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x84, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x10, 0x85, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x41, 0x63, 0x6b, 0x10, 0x86, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x36, + 0x0a, 0x2b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, + 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x92, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x41, 0x63, + 0x6b, 0x10, 0x93, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, + 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x65, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x94, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, + 0x6e, 0x63, 0x53, 0x74, 0x65, 0x70, 0x41, 0x63, 0x6b, 0x10, 0x95, 0x04, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x35, 0x0a, 0x2a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x53, 0x79, 0x6e, 0x63, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x10, 0x96, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x31, 0x0a, 0x26, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, + 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x41, 0x63, 0x6b, 0x10, 0x97, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x9c, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x10, 0x9d, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x47, 0x65, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4b, 0x65, 0x79, 0x10, 0x9e, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x4b, 0x65, 0x79, 0x10, 0x9f, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x44, 0x69, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xa2, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x44, 0x69, 0x61, 0x67, 0x41, 0x63, 0x6b, 0x10, 0xa3, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2c, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x47, 0x65, 0x74, 0x54, + 0x78, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xa6, 0x04, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x47, 0x65, 0x74, 0x54, 0x78, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x6b, 0x10, 0xa7, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, + 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, + 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xa8, 0x04, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xa9, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xaa, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2f, 0x0a, 0x24, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x65, 0x70, + 0x41, 0x63, 0x6b, 0x10, 0xab, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xac, 0x04, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x6b, 0x10, 0xad, 0x04, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x10, 0xd8, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xd9, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x20, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x45, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xda, 0x04, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x54, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xdb, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x25, + 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, + 0x73, 0x54, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0xdc, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, + 0x10, 0xdd, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, + 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xbc, 0x05, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0xbd, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xbe, 0x05, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xbf, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, + 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, + 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xc0, 0x05, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xc1, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x29, + 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, + 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4d, 0x73, 0x67, + 0x10, 0xc2, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x10, 0xc3, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, + 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4d, 0x73, + 0x67, 0x10, 0xc4, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xc5, 0x05, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x3a, 0x3c, 0x0a, 0x07, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x12, 0x21, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xd2, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x77, 0x69, 0x72, 0x65, 0x49, 0x6e, + 0x3a, 0x3e, 0x0a, 0x08, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xd3, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x69, 0x72, 0x65, 0x4f, 0x75, 0x74, + 0x3a, 0x47, 0x0a, 0x0d, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x69, + 0x6e, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd4, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x69, + 0x72, 0x65, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x3a, 0x49, 0x0a, 0x0e, 0x77, 0x69, 0x72, + 0x65, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, + 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd5, + 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x69, 0x72, 0x65, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4f, 0x75, 0x74, 0x3a, 0x40, 0x0a, 0x09, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6e, + 0x79, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd6, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, + 0x72, 0x65, 0x54, 0x69, 0x6e, 0x79, 0x3a, 0x4c, 0x0a, 0x0f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x62, + 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd7, 0x86, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x77, 0x69, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x72, 0x3a, 0x43, 0x0a, 0x0b, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x6e, 0x6f, 0x5f, + 0x66, 0x73, 0x6d, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd8, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x77, 0x69, 0x72, 0x65, 0x4e, 0x6f, 0x46, 0x73, 0x6d, 0x42, 0x6f, 0x0a, 0x23, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, 0x72, 0x65, + 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x0d, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5a, + 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, } -var E_WireTiny = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50006, - Name: "hw.trezor.messages.wire_tiny", - Tag: "varint,50006,opt,name=wire_tiny", - Filename: "messages.proto", -} +var ( + file_messages_proto_rawDescOnce sync.Once + file_messages_proto_rawDescData = file_messages_proto_rawDesc +) -var E_WireBootloader = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50007, - Name: "hw.trezor.messages.wire_bootloader", - Tag: "varint,50007,opt,name=wire_bootloader", - Filename: "messages.proto", +func file_messages_proto_rawDescGZIP() []byte { + file_messages_proto_rawDescOnce.Do(func() { + file_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_proto_rawDescData) + }) + return file_messages_proto_rawDescData } -var E_WireNoFsm = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50008, - Name: "hw.trezor.messages.wire_no_fsm", - Tag: "varint,50008,opt,name=wire_no_fsm", - Filename: "messages.proto", +var file_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_messages_proto_goTypes = []any{ + (MessageType)(0), // 0: hw.trezor.messages.MessageType + (*descriptorpb.EnumValueOptions)(nil), // 1: google.protobuf.EnumValueOptions } - -func init() { - proto.RegisterEnum("hw.trezor.messages.MessageType", MessageType_name, MessageType_value) - proto.RegisterExtension(E_WireIn) - proto.RegisterExtension(E_WireOut) - proto.RegisterExtension(E_WireDebugIn) - proto.RegisterExtension(E_WireDebugOut) - proto.RegisterExtension(E_WireTiny) - proto.RegisterExtension(E_WireBootloader) - proto.RegisterExtension(E_WireNoFsm) +var file_messages_proto_depIdxs = []int32{ + 1, // 0: hw.trezor.messages.wire_in:extendee -> google.protobuf.EnumValueOptions + 1, // 1: hw.trezor.messages.wire_out:extendee -> google.protobuf.EnumValueOptions + 1, // 2: hw.trezor.messages.wire_debug_in:extendee -> google.protobuf.EnumValueOptions + 1, // 3: hw.trezor.messages.wire_debug_out:extendee -> google.protobuf.EnumValueOptions + 1, // 4: hw.trezor.messages.wire_tiny:extendee -> google.protobuf.EnumValueOptions + 1, // 5: hw.trezor.messages.wire_bootloader:extendee -> google.protobuf.EnumValueOptions + 1, // 6: hw.trezor.messages.wire_no_fsm:extendee -> google.protobuf.EnumValueOptions + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 0, // [0:7] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } - -var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ - // 2430 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x9a, 0xd9, 0x73, 0x1c, 0xc5, - 0x1d, 0xc7, 0xb3, 0xab, 0x11, 0x88, 0xf6, 0x41, 0x23, 0xb0, 0x2d, 0xaf, 0x2f, 0xf9, 0xc0, 0x96, - 0x2f, 0xd9, 0x10, 0x0c, 0x44, 0x38, 0x60, 0x69, 0xb5, 0x12, 0x8a, 0xb5, 0x5a, 0x97, 0x76, 0xb1, - 0x1f, 0x5d, 0xa3, 0x9d, 0xd6, 0x6e, 0x97, 0x67, 0x67, 0x86, 0x9e, 0x1e, 0x49, 0xeb, 0xa7, 0x9c, - 0x3c, 0x13, 0x48, 0xc0, 0xb9, 0xa9, 0xa4, 0x2a, 0x21, 0x57, 0x85, 0x1c, 0x4e, 0x25, 0x55, 0x39, - 0x08, 0x24, 0x2f, 0xc9, 0x43, 0x52, 0x9c, 0x86, 0x40, 0xee, 0x90, 0xe4, 0x0f, 0xc8, 0xc5, 0x91, - 0xa4, 0x7a, 0xa6, 0xbb, 0xe7, 0xd8, 0xdf, 0xae, 0x36, 0x6f, 0x58, 0xf3, 0xf9, 0x7d, 0x7f, 0x47, - 0xff, 0xfa, 0x37, 0xdd, 0xb3, 0xa0, 0xcd, 0x2d, 0xe2, 0xfb, 0x66, 0x83, 0xf8, 0xe3, 0x1e, 0x73, - 0xb9, 0x3b, 0x3c, 0xdc, 0x5c, 0x1d, 0xe7, 0x8c, 0x5c, 0x76, 0xd9, 0xb8, 0x7a, 0x52, 0x18, 0x6d, - 0xb8, 0x6e, 0xc3, 0x26, 0x27, 0x42, 0x62, 0x29, 0x58, 0x3e, 0x61, 0x11, 0xbf, 0xce, 0xa8, 0xc7, - 0x5d, 0x16, 0x59, 0x1d, 0xf9, 0xfe, 0x7d, 0x68, 0x43, 0x39, 0xc2, 0x6b, 0x6d, 0x8f, 0x0c, 0x1f, - 0x40, 0x5b, 0x13, 0xff, 0xbc, 0x38, 0xe7, 0x50, 0x4e, 0x4d, 0x9b, 0x5e, 0x26, 0xf8, 0x5d, 0x85, - 0xa1, 0x87, 0xaf, 0x8e, 0xe4, 0x9e, 0xba, 0x3a, 0x92, 0x1b, 0x2e, 0x20, 0x9c, 0xa4, 0xce, 0x51, - 0xa7, 0x81, 0x73, 0x05, 0x43, 0x3c, 0x1f, 0xde, 0x85, 0x6e, 0x4e, 0x3e, 0xab, 0x06, 0xf5, 0x3a, - 0xf1, 0x7d, 0x9c, 0x2f, 0x18, 0x57, 0x80, 0xc7, 0x33, 0x26, 0xb5, 0x03, 0x46, 0xf0, 0x80, 0x7c, - 0xbc, 0x07, 0x6d, 0x49, 0x3e, 0x2e, 0x36, 0x4d, 0xa7, 0x41, 0xce, 0x51, 0x07, 0x1b, 0x52, 0x7e, - 0x34, 0x1d, 0xe0, 0x05, 0xea, 0x91, 0x69, 0xb2, 0x42, 0xeb, 0x04, 0x0f, 0xc2, 0xc4, 0x2c, 0xe1, - 0x25, 0x87, 0x33, 0xd7, 0x6b, 0xe3, 0x1b, 0xe0, 0x10, 0xd5, 0x63, 0x24, 0x63, 0xc8, 0x08, 0xcc, - 0xbb, 0xa6, 0x25, 0x5d, 0x6c, 0x92, 0x02, 0x7b, 0xd1, 0xb6, 0x24, 0xb1, 0x48, 0x7c, 0xc2, 0x25, - 0xb2, 0x59, 0x22, 0xbb, 0xd1, 0x2d, 0xa9, 0x3c, 0x89, 0xc9, 0x03, 0x46, 0x7c, 0x7c, 0x93, 0x74, - 0x72, 0x10, 0xed, 0xcc, 0x94, 0xb0, 0x6c, 0x72, 0x46, 0xd7, 0x16, 0xc9, 0x83, 0x01, 0xf1, 0x39, - 0x1e, 0x96, 0xdc, 0x11, 0x34, 0x02, 0x72, 0x93, 0xf5, 0x4b, 0xf8, 0xe6, 0xc2, 0x46, 0xb5, 0x24, - 0x4f, 0x47, 0x81, 0x0f, 0xa7, 0x8a, 0x67, 0x3a, 0x75, 0x62, 0xe3, 0x5b, 0x12, 0x0b, 0xb7, 0x2f, - 0xad, 0x56, 0xb4, 0x89, 0xc9, 0xaa, 0xc4, 0xf7, 0xa9, 0xeb, 0xe0, 0x11, 0x19, 0xf9, 0x7e, 0xb4, - 0x3d, 0xc9, 0x4c, 0x7a, 0x9e, 0xdd, 0xae, 0x12, 0xce, 0xa9, 0xd3, 0xf0, 0xf1, 0x76, 0x18, 0x9a, - 0x0a, 0x38, 0x77, 0x1d, 0x15, 0x7b, 0x41, 0xc6, 0x7e, 0x28, 0xbd, 0x98, 0x11, 0x24, 0x02, 0xdf, - 0xd1, 0x11, 0xf8, 0xd6, 0x0e, 0x97, 0x33, 0xb6, 0xd9, 0xf0, 0xf1, 0x4e, 0xe9, 0x2f, 0x13, 0xf8, - 0x94, 0x59, 0xbf, 0x14, 0x78, 0xb2, 0xe4, 0xfb, 0x24, 0x73, 0x00, 0x15, 0x80, 0x65, 0x55, 0x41, - 0xed, 0x87, 0x57, 0x57, 0x52, 0x22, 0xaa, 0x03, 0x52, 0xe7, 0x10, 0xda, 0x95, 0x2a, 0xb9, 0xe9, - 0xfb, 0x5e, 0x93, 0x99, 0x3e, 0x51, 0x52, 0x87, 0xa5, 0xd4, 0xd1, 0x74, 0x11, 0x62, 0x50, 0xa8, - 0x1d, 0xc9, 0xe4, 0x78, 0x0c, 0xed, 0x83, 0xe1, 0x2a, 0x37, 0xb9, 0x96, 0x2e, 0x4b, 0xe9, 0x93, - 0x68, 0x77, 0x0f, 0x5a, 0xe8, 0x2f, 0x64, 0xf4, 0x33, 0xd9, 0x2f, 0x92, 0xba, 0xbb, 0x42, 0x58, - 0x5b, 0xd6, 0xe8, 0x38, 0xdc, 0xb9, 0x17, 0x5c, 0x66, 0x29, 0xd7, 0xe3, 0xf0, 0x0e, 0x15, 0x88, - 0xf0, 0x77, 0x02, 0x56, 0x98, 0x25, 0x5c, 0xf7, 0xf6, 0x5d, 0x70, 0x73, 0x54, 0x09, 0x7f, 0xe0, - 0xf6, 0x99, 0xa2, 0x1b, 0x38, 0x9c, 0x30, 0x7c, 0x9f, 0xae, 0x72, 0x0a, 0x9a, 0xa1, 0xac, 0xb5, - 0x6a, 0x32, 0x52, 0x12, 0x49, 0xe2, 0xeb, 0xa2, 0x9e, 0xfd, 0x9e, 0x00, 0xc7, 0xd2, 0x89, 0x29, - 0xf0, 0x01, 0xcf, 0x76, 0x4d, 0x0b, 0x5f, 0x9f, 0x20, 0x0f, 0xa3, 0x1d, 0x10, 0xa9, 0x12, 0x1c, - 0x2a, 0x0c, 0x5d, 0x51, 0xe8, 0xbe, 0xf4, 0xf6, 0xac, 0x12, 0x7b, 0xb9, 0x26, 0x98, 0xd1, 0x84, - 0x5c, 0xa6, 0xe7, 0x66, 0x09, 0x3f, 0x17, 0x2c, 0xd9, 0xb4, 0x7e, 0x96, 0xb4, 0xf1, 0x06, 0x99, - 0x45, 0x66, 0x5e, 0xc5, 0xc0, 0x46, 0x59, 0xcd, 0x9d, 0xe9, 0x3d, 0x59, 0xa5, 0x0d, 0xa7, 0xb6, - 0x86, 0x6f, 0x84, 0xcd, 0x6b, 0x7a, 0xfb, 0x6f, 0x91, 0xe6, 0x3b, 0xd0, 0x4d, 0x69, 0x40, 0x2c, - 0xc5, 0xd6, 0xae, 0x93, 0x6e, 0xd2, 0xb2, 0x98, 0x98, 0xb6, 0xbb, 0xe0, 0x49, 0xa7, 0x1e, 0xef, - 0x96, 0xea, 0x99, 0xb5, 0x14, 0xc1, 0xc9, 0x7f, 0xe3, 0x83, 0xf0, 0x5a, 0x9e, 0x27, 0x8c, 0x2e, - 0xb7, 0x15, 0x74, 0x48, 0x42, 0x99, 0x61, 0x26, 0xff, 0x5b, 0xc8, 0x85, 0x9d, 0x81, 0xc7, 0xa4, - 0xbf, 0x4c, 0x8f, 0x16, 0xa9, 0xd7, 0x24, 0xec, 0x2c, 0x69, 0x9f, 0x37, 0xed, 0x80, 0xe0, 0x6d, - 0xb0, 0x5a, 0x44, 0x11, 0x4b, 0x73, 0x27, 0xa5, 0x5a, 0x66, 0x7d, 0x84, 0xbb, 0x39, 0x8b, 0x38, - 0x9c, 0xf2, 0x36, 0x3e, 0x05, 0xcf, 0x04, 0xc1, 0x10, 0x4b, 0x53, 0x77, 0xea, 0x41, 0xb5, 0x2b, - 0xfb, 0xca, 0x28, 0x4e, 0xdf, 0x2f, 0x07, 0xa3, 0x58, 0xcd, 0xf7, 0x76, 0x19, 0x31, 0x69, 0xea, - 0x5e, 0x78, 0xc4, 0x14, 0x5d, 0x9f, 0x16, 0xdd, 0x56, 0x8b, 0x72, 0x3c, 0x0b, 0xeb, 0xc4, 0x44, - 0x8b, 0x38, 0x1c, 0xdf, 0x2f, 0x75, 0x32, 0xef, 0x10, 0x41, 0x89, 0x04, 0xf0, 0x1c, 0xbc, 0x36, - 0xea, 0x79, 0x54, 0xf3, 0xf7, 0x49, 0x91, 0x13, 0xe9, 0xdc, 0xa6, 0xc9, 0x52, 0xd0, 0x98, 0xa7, - 0xce, 0xa5, 0x69, 0x52, 0xa7, 0xe1, 0xdc, 0xb7, 0x0a, 0x1b, 0x9f, 0x48, 0x0e, 0x92, 0xa3, 0x5d, - 0x0c, 0x66, 0x09, 0x0f, 0x87, 0x0f, 0x26, 0x85, 0x21, 0x65, 0x90, 0x4d, 0x44, 0xc3, 0x11, 0xb9, - 0x5c, 0x30, 0x9e, 0x04, 0x02, 0x4d, 0x50, 0xae, 0x87, 0x1b, 0x05, 0xe3, 0x09, 0x60, 0x39, 0x35, - 0x34, 0xef, 0x36, 0x70, 0x53, 0x0a, 0x1d, 0x46, 0x7b, 0x40, 0xa6, 0x4c, 0x5a, 0x2e, 0x6b, 0x2f, - 0x12, 0xd3, 0xc2, 0x8e, 0x94, 0xbb, 0x35, 0x3d, 0x0c, 0x32, 0x28, 0x76, 0xa5, 0xe2, 0x11, 0x34, - 0xda, 0x03, 0xbb, 0xc0, 0x28, 0x27, 0xd8, 0x93, 0x92, 0xdd, 0xbc, 0xcf, 0xd8, 0xa6, 0xdf, 0x8c, - 0x06, 0xd7, 0x83, 0x12, 0x3d, 0x9a, 0x96, 0x2d, 0x71, 0xd1, 0xc2, 0x41, 0x2b, 0x35, 0x43, 0x9e, - 0x19, 0x90, 0xeb, 0x38, 0x96, 0xae, 0xb8, 0x82, 0x63, 0xf2, 0x59, 0x75, 0x3c, 0x1a, 0x4b, 0xbf, - 0x16, 0x12, 0xb2, 0x6a, 0x6b, 0xdf, 0x2d, 0x35, 0x33, 0xe9, 0x2b, 0x52, 0x61, 0xef, 0x81, 0x77, - 0xa4, 0xc2, 0xe4, 0x98, 0x9a, 0x80, 0xdf, 0x88, 0x8a, 0x8a, 0xc7, 0xd5, 0x3d, 0x52, 0x2e, 0xb3, - 0xd0, 0x31, 0x28, 0xc6, 0xd6, 0x69, 0xa9, 0x96, 0x29, 0x63, 0xd2, 0xa7, 0x1a, 0x2c, 0x67, 0x24, - 0x7a, 0x14, 0xed, 0x85, 0xd0, 0xf4, 0x14, 0x9a, 0x94, 0xf0, 0x38, 0x3a, 0x00, 0xc1, 0x1d, 0xd3, - 0x68, 0x0a, 0x0e, 0x76, 0xa1, 0x54, 0x4e, 0xd4, 0xb1, 0x08, 0xcf, 0xd8, 0x85, 0x52, 0x59, 0x11, - 0xd3, 0xf0, 0x91, 0x75, 0xa1, 0x54, 0x96, 0xd5, 0x2b, 0xc1, 0x6f, 0x4c, 0x09, 0x10, 0xab, 0xb6, - 0x86, 0x67, 0xe0, 0x01, 0xb4, 0x50, 0x2a, 0x4f, 0x93, 0x3a, 0x6b, 0x7b, 0x5c, 0xe5, 0x78, 0x16, - 0xae, 0x5d, 0x0c, 0x12, 0x4b, 0xa1, 0xf3, 0xf0, 0xd2, 0xce, 0x53, 0xff, 0x52, 0x22, 0x3f, 0x06, - 0x07, 0x27, 0x28, 0x85, 0xf8, 0x5d, 0xce, 0xc3, 0xd4, 0xbf, 0x24, 0x33, 0xe4, 0xf0, 0xe9, 0x4c, - 0x11, 0x61, 0x8a, 0x81, 0x54, 0xc9, 0x34, 0xa4, 0x62, 0x54, 0xd4, 0x2b, 0x52, 0x2a, 0xb3, 0x1f, - 0x05, 0xd6, 0xb1, 0x80, 0xab, 0x70, 0xd5, 0x04, 0x9b, 0xee, 0x8c, 0x35, 0xf8, 0x8d, 0x22, 0x4b, - 0x11, 0xef, 0xaf, 0x36, 0x3c, 0x50, 0x05, 0x17, 0x43, 0x97, 0xf5, 0xc9, 0x3d, 0x95, 0x48, 0x8d, - 0x5c, 0x76, 0xfd, 0x44, 0x61, 0x1f, 0xcb, 0x69, 0xb1, 0x91, 0x0e, 0x4e, 0x41, 0x8f, 0xe7, 0xf4, - 0x3b, 0x6c, 0x5b, 0x07, 0x24, 0x8b, 0x7b, 0x25, 0xa7, 0x5f, 0x16, 0xdb, 0x41, 0x26, 0x2c, 0xef, - 0x27, 0x72, 0x7a, 0x34, 0xec, 0x82, 0xc2, 0x8a, 0xe3, 0xff, 0x64, 0x4e, 0x8f, 0x86, 0x42, 0x07, - 0x19, 0x63, 0x9f, 0xca, 0xe9, 0xfe, 0x49, 0x9f, 0xe2, 0x38, 0xb1, 0x6d, 0x93, 0xc9, 0xe0, 0x7e, - 0x9e, 0xd3, 0x0d, 0xb9, 0x1b, 0xa0, 0x6a, 0x6b, 0x15, 0x4f, 0xcd, 0x86, 0x5f, 0x74, 0x89, 0x50, - 0xa2, 0x89, 0xd2, 0xfd, 0xb2, 0x4b, 0x84, 0x92, 0x54, 0xd8, 0xaf, 0x94, 0xe0, 0xf1, 0xf4, 0x91, - 0x5a, 0x62, 0x45, 0x46, 0xc2, 0x23, 0x72, 0x5d, 0x1c, 0x38, 0x2b, 0x1e, 0x7e, 0x2e, 0xa7, 0xa7, - 0xd8, 0x4e, 0x00, 0x3f, 0x67, 0xb6, 0xc5, 0x4b, 0xb7, 0xe2, 0xe1, 0xe7, 0x73, 0x7a, 0xea, 0x8c, - 0x82, 0x20, 0x6f, 0xc6, 0xf0, 0x0b, 0xbd, 0xe1, 0xb2, 0xe9, 0x98, 0x0d, 0x52, 0x59, 0x5e, 0x26, - 0xac, 0xe2, 0xe1, 0x17, 0x15, 0x7c, 0x3b, 0x3a, 0xd4, 0x35, 0x62, 0x71, 0xc6, 0xa7, 0x2b, 0xda, - 0xe6, 0xa5, 0x9c, 0xde, 0x11, 0x7b, 0xa0, 0x75, 0x20, 0xbc, 0xe2, 0x71, 0xea, 0x3a, 0x7e, 0xc5, - 0xc3, 0x2f, 0xf7, 0x0e, 0x26, 0xba, 0x45, 0xd7, 0x58, 0xe0, 0x8b, 0xc8, 0xaf, 0xf5, 0x16, 0x9e, - 0xb4, 0x6d, 0x77, 0x55, 0xb1, 0xaf, 0x28, 0xf6, 0x58, 0x7a, 0x10, 0x2b, 0x36, 0x2a, 0x72, 0x99, - 0xb0, 0x06, 0xa9, 0x78, 0xf8, 0xd5, 0xde, 0xca, 0x51, 0x4d, 0xa6, 0x4d, 0x6e, 0x56, 0x3c, 0xfc, - 0x5a, 0x6f, 0xe5, 0xa9, 0xa0, 0xe5, 0x55, 0x45, 0x03, 0x39, 0x75, 0xa1, 0xfc, 0x7a, 0x4e, 0xef, - 0xe4, 0x1d, 0x5d, 0x9a, 0x32, 0xdc, 0x0d, 0x6f, 0xe4, 0xf4, 0xb4, 0x49, 0xf7, 0x38, 0x73, 0x9d, - 0x44, 0xa3, 0xbd, 0x99, 0xd3, 0x83, 0x6b, 0x5b, 0x16, 0x53, 0xcc, 0x5b, 0x39, 0x7d, 0x48, 0xde, - 0x9a, 0x65, 0xe4, 0x26, 0x78, 0xbb, 0xdb, 0x56, 0x97, 0x48, 0x18, 0xd2, 0x3b, 0x5d, 0xf6, 0x53, - 0xd1, 0x64, 0x96, 0xe9, 0xb8, 0x52, 0xea, 0x1b, 0x79, 0xb8, 0x49, 0x25, 0x15, 0xbf, 0x69, 0x9f, - 0xca, 0xeb, 0x0f, 0x03, 0x7b, 0x00, 0x30, 0xb5, 0xe3, 0xbf, 0xd9, 0x5b, 0x34, 0x06, 0xbf, 0x95, - 0x87, 0xb7, 0x68, 0x2c, 0xaa, 0xaa, 0xf2, 0xed, 0x3c, 0xbc, 0x45, 0x25, 0xa9, 0xb0, 0xef, 0xe4, - 0xf5, 0x3b, 0x76, 0x04, 0x4c, 0x47, 0x9c, 0x07, 0xae, 0xe6, 0xe1, 0x45, 0x4d, 0x54, 0x26, 0xac, - 0xe0, 0x77, 0x95, 0x58, 0x66, 0xd6, 0x54, 0x1c, 0xee, 0xda, 0x6e, 0xa3, 0x9d, 0x08, 0xef, 0x37, - 0x5d, 0x24, 0x15, 0xaa, 0xb8, 0xdf, 0xe6, 0xf5, 0x15, 0x7e, 0xb4, 0x8b, 0x64, 0x5c, 0x9d, 0xdf, - 0xe5, 0xe1, 0x73, 0x9a, 0x82, 0x63, 0xf2, 0xf7, 0xeb, 0xc8, 0x86, 0x8b, 0xcd, 0x4c, 0xc7, 0x5f, - 0x26, 0x0c, 0xff, 0x41, 0xc9, 0x66, 0xc6, 0x58, 0x12, 0x26, 0x96, 0xc6, 0xff, 0xa8, 0xb4, 0xc7, - 0xd1, 0xfe, 0x6e, 0xf8, 0x05, 0xca, 0x9b, 0x16, 0x33, 0x57, 0x2b, 0x4e, 0x03, 0xff, 0x49, 0xc9, - 0x9f, 0x44, 0xb7, 0x76, 0x97, 0x4f, 0x5a, 0xfc, 0x39, 0xaf, 0x3f, 0x3e, 0x74, 0xb5, 0xa8, 0x38, - 0x7c, 0xce, 0x5a, 0x24, 0x0d, 0xea, 0x8b, 0xbb, 0xfc, 0x1b, 0x79, 0x78, 0xae, 0xa5, 0x7d, 0xa4, - 0x6d, 0xfe, 0xa2, 0xbc, 0x9c, 0x42, 0x47, 0x7a, 0x7a, 0x99, 0xb4, 0xac, 0x49, 0xce, 0x19, 0x5d, - 0x0a, 0x38, 0xf1, 0xf1, 0x5f, 0x95, 0xab, 0xbb, 0xd0, 0xb1, 0x75, 0x5c, 0xa5, 0x0d, 0xff, 0x96, - 0xd7, 0xa7, 0x85, 0xd4, 0x26, 0x58, 0xa4, 0x9e, 0x67, 0x93, 0x44, 0xef, 0x3c, 0x3c, 0x00, 0xbf, - 0x6f, 0x23, 0x50, 0x51, 0x1f, 0x1d, 0x80, 0x3b, 0x3b, 0xa2, 0xe4, 0x6e, 0x7e, 0x64, 0x00, 0xde, - 0x25, 0x31, 0x14, 0x36, 0xf6, 0xa3, 0x0a, 0x7b, 0x37, 0x1a, 0x4b, 0xdd, 0x9f, 0x5d, 0x87, 0x30, - 0x37, 0x5c, 0x79, 0xb3, 0x2e, 0x66, 0xfc, 0x9c, 0x43, 0xb9, 0x1a, 0x00, 0x7f, 0x1f, 0xd0, 0x17, - 0xbb, 0x03, 0xeb, 0x1a, 0x89, 0x6d, 0xf6, 0x0f, 0x65, 0x90, 0xa9, 0x5c, 0x87, 0x41, 0x95, 0xf0, - 0x39, 0xc7, 0x0b, 0xb4, 0xa7, 0x7f, 0x2a, 0xc3, 0xf5, 0xc2, 0x53, 0x86, 0xc2, 0xdb, 0xbf, 0x94, - 0xd1, 0x19, 0x74, 0x6a, 0x9d, 0xf0, 0xbc, 0x80, 0xfb, 0xe7, 0x08, 0x6b, 0x05, 0xdc, 0x14, 0x7f, - 0x50, 0x6e, 0xff, 0xad, 0x14, 0x4e, 0xa3, 0xdb, 0xfe, 0x3f, 0x05, 0xe1, 0xff, 0x4d, 0x65, 0x7d, - 0x37, 0x3a, 0xbe, 0xbe, 0xf5, 0x79, 0xea, 0x50, 0xe5, 0xf7, 0x2d, 0x65, 0x79, 0x07, 0x3a, 0xdc, - 0x9f, 0xa5, 0xf0, 0xf7, 0xb6, 0xb2, 0xba, 0x07, 0x9d, 0xec, 0x69, 0x35, 0x69, 0xdb, 0x51, 0xc0, - 0x55, 0xa2, 0x2b, 0xfc, 0x4e, 0xbf, 0x4b, 0x93, 0x34, 0x16, 0x5e, 0xff, 0xd3, 0x6f, 0x96, 0xe2, - 0x98, 0x10, 0xf0, 0xc4, 0xa2, 0xfe, 0xb7, 0xdf, 0x2c, 0xb5, 0xa5, 0xf0, 0xf7, 0x7e, 0xa3, 0x4f, - 0x7f, 0x93, 0xb6, 0x5d, 0x09, 0x78, 0x22, 0xc5, 0x0f, 0x18, 0x7d, 0xfa, 0xd3, 0x96, 0xc2, 0xdf, - 0x07, 0xfb, 0xf5, 0x17, 0x7e, 0xf4, 0x49, 0x36, 0xed, 0x87, 0xfa, 0xf5, 0xa7, 0x2d, 0x85, 0xbf, - 0x0f, 0xf7, 0x6b, 0x35, 0x43, 0x1d, 0xd3, 0x56, 0xbe, 0x3e, 0x62, 0xc0, 0x03, 0x13, 0xb6, 0x12, - 0x7e, 0x1e, 0x52, 0x16, 0x77, 0xa2, 0xa3, 0x9d, 0x16, 0x67, 0x49, 0x7b, 0xae, 0x65, 0x36, 0x48, - 0x69, 0xcd, 0x73, 0x19, 0x4f, 0x6e, 0xfa, 0x47, 0x94, 0x5d, 0x66, 0xd0, 0x76, 0xb3, 0x13, 0xbe, - 0x1e, 0xed, 0x99, 0x93, 0xb2, 0xa9, 0xb6, 0x9d, 0x7a, 0x95, 0x13, 0x7d, 0x5a, 0xff, 0x58, 0xcf, - 0x9c, 0xb2, 0x56, 0xc2, 0xcf, 0xc7, 0x0d, 0x78, 0xa0, 0x77, 0x5a, 0xa4, 0x8a, 0xf7, 0x98, 0x32, - 0xbb, 0x0d, 0x1d, 0xec, 0xc3, 0x4c, 0x78, 0x7a, 0xdc, 0x80, 0x47, 0x79, 0x64, 0x92, 0x18, 0xe5, - 0x9f, 0x36, 0xe0, 0x51, 0x1e, 0x81, 0x8a, 0xfa, 0x8c, 0x01, 0x9f, 0x7a, 0xb4, 0xdc, 0x05, 0x93, - 0xd7, 0x9b, 0xe2, 0xbd, 0xfe, 0x59, 0x03, 0x9e, 0xe7, 0x11, 0xa9, 0xb1, 0xcf, 0x19, 0xf0, 0xc5, - 0x24, 0xfc, 0x50, 0x14, 0xb1, 0xd3, 0xd4, 0x6c, 0xa8, 0x0a, 0x7c, 0xde, 0x80, 0xef, 0x50, 0x19, - 0x5c, 0x64, 0xfe, 0x05, 0xa5, 0x9c, 0x39, 0x2d, 0xeb, 0x50, 0x6b, 0x6b, 0x67, 0x89, 0xfe, 0xa9, - 0xe3, 0x8b, 0x06, 0x7c, 0x60, 0x49, 0xd3, 0x42, 0xf7, 0x4b, 0x3d, 0x7b, 0x64, 0x9e, 0xae, 0x90, - 0x45, 0xb2, 0xcc, 0x88, 0xdf, 0xac, 0x72, 0x93, 0xe9, 0x6e, 0x7c, 0xd2, 0x80, 0x8f, 0x16, 0xb0, - 0x95, 0xf0, 0xf3, 0x65, 0xa3, 0xd7, 0xab, 0x24, 0x65, 0x11, 0xb7, 0xe2, 0x57, 0x94, 0x1b, 0xf0, - 0x4d, 0x97, 0x31, 0x12, 0x5e, 0xbe, 0xda, 0x6f, 0x36, 0xa9, 0x46, 0xfc, 0x5a, 0xbf, 0xd9, 0xe8, - 0x3e, 0xfc, 0xba, 0x01, 0x7f, 0x0a, 0x28, 0x65, 0x6e, 0xdc, 0xd7, 0x0c, 0xf8, 0x7e, 0x50, 0x4a, - 0xde, 0xb7, 0x5f, 0x31, 0xf4, 0x67, 0x96, 0x2d, 0x19, 0x48, 0x9e, 0x26, 0x5e, 0xed, 0xd2, 0x27, - 0x25, 0xd7, 0x17, 0x07, 0xe9, 0xe4, 0xbb, 0xf3, 0xd7, 0x06, 0x7c, 0xff, 0x49, 0xa0, 0x22, 0x81, - 0xd7, 0x0c, 0xf8, 0xfe, 0x53, 0x4a, 0x7c, 0x58, 0x78, 0xbd, 0xcb, 0xee, 0x98, 0xa2, 0x8e, 0xe9, - 0xd4, 0x93, 0x07, 0xa7, 0x1f, 0x0c, 0xc2, 0xbb, 0x43, 0x92, 0x0a, 0xfb, 0xe1, 0x20, 0x7c, 0x73, - 0x89, 0x05, 0xe3, 0xa2, 0xfc, 0x68, 0x10, 0xbe, 0xb9, 0x48, 0x36, 0x06, 0x7f, 0x3c, 0x08, 0xdf, - 0xae, 0x24, 0x28, 0x2b, 0xf8, 0x74, 0x6f, 0xb9, 0xf8, 0x76, 0xf5, 0x93, 0x41, 0xf8, 0xaa, 0xa1, - 0x40, 0x79, 0x18, 0x2f, 0xfb, 0x0d, 0xfc, 0xcc, 0x20, 0x7c, 0xd5, 0x90, 0x68, 0x85, 0x59, 0x11, - 0xf7, 0x6c, 0x6f, 0xdf, 0xd1, 0x8f, 0xb4, 0x02, 0xfc, 0x69, 0x6f, 0x41, 0xbd, 0x30, 0x3f, 0x93, - 0x31, 0x4e, 0x9c, 0x46, 0xd7, 0xaf, 0x52, 0x46, 0x2e, 0x52, 0x67, 0x78, 0xef, 0x78, 0xf4, 0x4b, - 0xff, 0xb8, 0xfa, 0xa5, 0x7f, 0xbc, 0xe4, 0x04, 0xad, 0xf0, 0xe7, 0x12, 0xf9, 0x95, 0x60, 0xe4, - 0xb9, 0x87, 0x06, 0x46, 0x73, 0x63, 0x43, 0x8b, 0xd7, 0x09, 0x9b, 0x39, 0x67, 0xe2, 0x5e, 0x34, - 0x14, 0x5a, 0xbb, 0x01, 0xef, 0xc7, 0xfc, 0x79, 0x69, 0x1e, 0xba, 0xac, 0x04, 0x7c, 0x62, 0x16, - 0x6d, 0x0a, 0xed, 0x2d, 0x31, 0xad, 0xfa, 0x8c, 0xe1, 0x05, 0x29, 0xb2, 0x41, 0x58, 0x86, 0x63, - 0x6e, 0xce, 0x99, 0x98, 0x43, 0x9b, 0x13, 0x42, 0x7d, 0x86, 0xf3, 0xa2, 0x54, 0xda, 0xa8, 0x95, - 0x44, 0x4c, 0x67, 0xd0, 0x0d, 0xa1, 0x14, 0xa7, 0x4e, 0xbb, 0x1f, 0x95, 0x97, 0xa4, 0x4a, 0x58, - 0x89, 0x1a, 0x75, 0xda, 0x13, 0xf3, 0xe8, 0xc6, 0x50, 0x61, 0xc9, 0x75, 0xb9, 0xed, 0x9a, 0x16, - 0x61, 0xfd, 0xe8, 0xbc, 0x2c, 0x75, 0xc2, 0x44, 0xa6, 0xb4, 0xe9, 0x44, 0x11, 0x85, 0x99, 0x5e, - 0x74, 0xdc, 0x8b, 0xcb, 0x7e, 0xab, 0x1f, 0xa5, 0x6b, 0x52, 0x29, 0xcc, 0x63, 0xc1, 0x9d, 0xf1, - 0x5b, 0x53, 0x77, 0xa0, 0xfd, 0x75, 0xb7, 0x35, 0xee, 0x9b, 0xdc, 0xf5, 0x9b, 0xd4, 0x36, 0x97, - 0x7c, 0xf5, 0xff, 0x79, 0xd8, 0x74, 0x49, 0x4b, 0x4d, 0x6d, 0xaa, 0x85, 0x7f, 0x94, 0x9d, 0xf3, - 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x69, 0x67, 0x5d, 0x1f, 0x22, 0x00, 0x00, +func init() { file_messages_proto_init() } +func file_messages_proto_init() { + if File_messages_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 7, + NumServices: 0, + }, + GoTypes: file_messages_proto_goTypes, + DependencyIndexes: file_messages_proto_depIdxs, + EnumInfos: file_messages_proto_enumTypes, + ExtensionInfos: file_messages_proto_extTypes, + }.Build() + File_messages_proto = out.File + file_messages_proto_rawDesc = nil + file_messages_proto_goTypes = nil + file_messages_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages.proto b/accounts/usbwallet/trezor/messages.proto index 3e0482e344..c232bef60d 100644 --- a/accounts/usbwallet/trezor/messages.proto +++ b/accounts/usbwallet/trezor/messages.proto @@ -9,10 +9,13 @@ package hw.trezor.messages; * Messages for TREZOR communication */ +option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessage"; + import "google/protobuf/descriptor.proto"; /** diff --git a/accounts/usbwallet/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go index cdca6b4e0b..93aee3c289 100644 --- a/accounts/usbwallet/trezor/trezor.go +++ b/accounts/usbwallet/trezor/trezor.go @@ -39,10 +39,10 @@ // - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases // - Build with the usual `./configure && make` and ensure it's on your $PATH // - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor -// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go` -// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...` +// - Grab the latest Go plugin `go get -u google.golang.org/protobuf/cmd/protoc-gen-go` +// - Vendor in the latest Go plugin `govendor fetch google.golang.org/protobuf/...` -//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto +//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto // Package trezor contains the wire protocol. package trezor @@ -50,7 +50,7 @@ package trezor import ( "reflect" - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // Type returns the protocol buffer type number of a specific message. If the diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 69083dc893..0fd0415a9e 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -31,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "github.com/karalabe/usb" + "github.com/karalabe/hid" ) // Maximum time between wallet health checks to detect USB unplugs. @@ -79,8 +79,8 @@ type wallet struct { driver driver // Hardware implementation of the low level device operations url *accounts.URL // Textual URL uniquely identifying this wallet - info usb.DeviceInfo // Known USB device infos about the wallet - device usb.Device // USB device advertising itself as a hardware wallet + info hid.DeviceInfo // Known USB device infos about the wallet + device hid.Device // USB device advertising itself as a hardware wallet accounts []accounts.Account // List of derive accounts pinned on the hardware wallet paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations diff --git a/appveyor.yml b/appveyor.yml index 4a8c4b737a..92369537cd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,9 +24,10 @@ for: - image: Ubuntu build_script: - go run build/ci.go lint + - go run build/ci.go generate -verify - go run build/ci.go install -dlgo test_script: - - go run build/ci.go test -dlgo + - go run build/ci.go test -dlgo -short # linux/386 is disabled. - matrix: diff --git a/beacon/engine/gen_ed.go b/beacon/engine/gen_ed.go index 6893d64a16..b2eb1dc982 100644 --- a/beacon/engine/gen_ed.go +++ b/beacon/engine/gen_ed.go @@ -17,23 +17,25 @@ var _ = (*executableDataMarshaling)(nil) // MarshalJSON marshals as JSON. func (e ExecutableData) MarshalJSON() ([]byte, error) { type ExecutableData struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` - BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` - BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` + Random common.Hash `json:"prevRandao" gencodec:"required"` + Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` + ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` + Deposits types.Deposits `json:"depositRequests"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } var enc ExecutableData enc.ParentHash = e.ParentHash @@ -58,29 +60,33 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) { enc.Withdrawals = e.Withdrawals enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed) enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas) + enc.Deposits = e.Deposits + enc.ExecutionWitness = e.ExecutionWitness return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (e *ExecutableData) UnmarshalJSON(input []byte) error { type ExecutableData struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot *common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Random *common.Hash `json:"prevRandao" gencodec:"required"` - Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"` - BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` - BlockHash *common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot *common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"` + Random *common.Hash `json:"prevRandao" gencodec:"required"` + Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` + BlockHash *common.Hash `json:"blockHash" gencodec:"required"` + Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` + Deposits *types.Deposits `json:"depositRequests"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } var dec ExecutableData if err := json.Unmarshal(input, &dec); err != nil { @@ -154,5 +160,11 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error { if dec.ExcessBlobGas != nil { e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) } + if dec.Deposits != nil { + e.Deposits = *dec.Deposits + } + if dec.ExecutionWitness != nil { + e.ExecutionWitness = dec.ExecutionWitness + } return nil } diff --git a/beacon/engine/gen_epe.go b/beacon/engine/gen_epe.go index e69f9a5951..fa45d94c4c 100644 --- a/beacon/engine/gen_epe.go +++ b/beacon/engine/gen_epe.go @@ -19,12 +19,14 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) { BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` Override bool `json:"shouldOverrideBuilder"` + Witness *hexutil.Bytes `json:"witness"` } var enc ExecutionPayloadEnvelope enc.ExecutionPayload = e.ExecutionPayload enc.BlockValue = (*hexutil.Big)(e.BlockValue) enc.BlobsBundle = e.BlobsBundle enc.Override = e.Override + enc.Witness = e.Witness return json.Marshal(&enc) } @@ -35,6 +37,7 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` Override *bool `json:"shouldOverrideBuilder"` + Witness *hexutil.Bytes `json:"witness"` } var dec ExecutionPayloadEnvelope if err := json.Unmarshal(input, &dec); err != nil { @@ -54,5 +57,8 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { if dec.Override != nil { e.Override = *dec.Override } + if dec.Witness != nil { + e.Witness = dec.Witness + } return nil } diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 7ccc0d5b37..93e2af8954 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -19,10 +19,12 @@ package engine import ( "fmt" "math/big" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) @@ -57,23 +59,25 @@ type payloadAttributesMarshaling struct { // ExecutableData is the data necessary to execute an EL payload. type ExecutableData struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom []byte `json:"logsBloom" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - Number uint64 `json:"blockNumber" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Timestamp uint64 `json:"timestamp" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` - BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` - BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions [][]byte `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *uint64 `json:"blobGasUsed"` - ExcessBlobGas *uint64 `json:"excessBlobGas"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom []byte `json:"logsBloom" gencodec:"required"` + Random common.Hash `json:"prevRandao" gencodec:"required"` + Number uint64 `json:"blockNumber" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Timestamp uint64 `json:"timestamp" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Transactions [][]byte `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *uint64 `json:"blobGasUsed"` + ExcessBlobGas *uint64 `json:"excessBlobGas"` + Deposits types.Deposits `json:"depositRequests"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } // JSON type overrides for executableData. @@ -90,6 +94,14 @@ type executableDataMarshaling struct { ExcessBlobGas *hexutil.Uint64 } +// StatelessPayloadStatusV1 is the result of a stateless payload execution. +type StatelessPayloadStatusV1 struct { + Status string `json:"status"` + StateRoot common.Hash `json:"stateRoot"` + ReceiptsRoot common.Hash `json:"receiptsRoot"` + ValidationError *string `json:"validationError"` +} + //go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go type ExecutionPayloadEnvelope struct { @@ -97,6 +109,7 @@ type ExecutionPayloadEnvelope struct { BlockValue *big.Int `json:"blockValue" gencodec:"required"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` Override bool `json:"shouldOverrideBuilder"` + Witness *hexutil.Bytes `json:"witness"` } type BlobsBundleV1 struct { @@ -111,9 +124,10 @@ type executionPayloadEnvelopeMarshaling struct { } type PayloadStatusV1 struct { - Status string `json:"status"` - LatestValidHash *common.Hash `json:"latestValidHash"` - ValidationError *string `json:"validationError"` + Status string `json:"status"` + Witness *hexutil.Bytes `json:"witness"` + LatestValidHash *common.Hash `json:"latestValidHash"` + ValidationError *string `json:"validationError"` } type TransitionConfigurationV1 struct { @@ -132,12 +146,7 @@ func (b PayloadID) Version() PayloadVersion { // Is returns whether the identifier matches any of provided payload versions. func (b PayloadID) Is(versions ...PayloadVersion) bool { - for _, v := range versions { - if v == b.Version() { - return true - } - } - return false + return slices.Contains(versions, b.Version()) } func (b PayloadID) String() string { @@ -197,23 +206,37 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) { // // and that the blockhash of the constructed block matches the parameters. Nil // Withdrawals value will propagate through the returned block. Empty -// Withdrawals value must be passed via non-nil, length 0 value in params. -func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) { - txs, err := decodeTransactions(params.Transactions) +// Withdrawals value must be passed via non-nil, length 0 value in data. +func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) { + block, err := ExecutableDataToBlockNoHash(data, versionedHashes, beaconRoot) + if err != nil { + return nil, err + } + if block.Hash() != data.BlockHash { + return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", data.BlockHash, block.Hash()) + } + return block, nil +} + +// ExecutableDataToBlockNoHash is analogous to ExecutableDataToBlock, but is used +// for stateless execution, so it skips checking if the executable data hashes to +// the requested hash (stateless has to *compute* the root hash, it's not given). +func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) { + txs, err := decodeTransactions(data.Transactions) if err != nil { return nil, err } - if len(params.ExtraData) > 32 { - return nil, fmt.Errorf("invalid extradata length: %v", len(params.ExtraData)) + if len(data.ExtraData) > int(params.MaximumExtraDataSize) { + return nil, fmt.Errorf("invalid extradata length: %v", len(data.ExtraData)) } - if len(params.LogsBloom) != 256 { - return nil, fmt.Errorf("invalid logsBloom length: %v", len(params.LogsBloom)) + if len(data.LogsBloom) != 256 { + return nil, fmt.Errorf("invalid logsBloom length: %v", len(data.LogsBloom)) } // Check that baseFeePerGas is not negative or too big - if params.BaseFeePerGas != nil && (params.BaseFeePerGas.Sign() == -1 || params.BaseFeePerGas.BitLen() > 256) { - return nil, fmt.Errorf("invalid baseFeePerGas: %v", params.BaseFeePerGas) + if data.BaseFeePerGas != nil && (data.BaseFeePerGas.Sign() == -1 || data.BaseFeePerGas.BitLen() > 256) { + return nil, fmt.Errorf("invalid baseFeePerGas: %v", data.BaseFeePerGas) } - var blobHashes []common.Hash + var blobHashes = make([]common.Hash, 0, len(txs)) for _, tx := range txs { blobHashes = append(blobHashes, tx.BlobHashes()...) } @@ -229,59 +252,73 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash, // ExecutableData before withdrawals are enabled by marshaling // Withdrawals as the json null value. var withdrawalsRoot *common.Hash - if params.Withdrawals != nil { - h := types.DeriveSha(types.Withdrawals(params.Withdrawals), trie.NewStackTrie(nil)) + if data.Withdrawals != nil { + h := types.DeriveSha(types.Withdrawals(data.Withdrawals), trie.NewStackTrie(nil)) withdrawalsRoot = &h } + // Compute requestsHash if any requests are non-nil. + var ( + requestsHash *common.Hash + requests types.Requests + ) + if data.Deposits != nil { + requests = make(types.Requests, 0) + for _, d := range data.Deposits { + requests = append(requests, types.NewRequest(d)) + } + h := types.DeriveSha(requests, trie.NewStackTrie(nil)) + requestsHash = &h + } header := &types.Header{ - ParentHash: params.ParentHash, + ParentHash: data.ParentHash, UncleHash: types.EmptyUncleHash, - Coinbase: params.FeeRecipient, - Root: params.StateRoot, + Coinbase: data.FeeRecipient, + Root: data.StateRoot, TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)), - ReceiptHash: params.ReceiptsRoot, - Bloom: types.BytesToBloom(params.LogsBloom), + ReceiptHash: data.ReceiptsRoot, + Bloom: types.BytesToBloom(data.LogsBloom), Difficulty: common.Big0, - Number: new(big.Int).SetUint64(params.Number), - GasLimit: params.GasLimit, - GasUsed: params.GasUsed, - Time: params.Timestamp, - BaseFee: params.BaseFeePerGas, - Extra: params.ExtraData, - MixDigest: params.Random, + Number: new(big.Int).SetUint64(data.Number), + GasLimit: data.GasLimit, + GasUsed: data.GasUsed, + Time: data.Timestamp, + BaseFee: data.BaseFeePerGas, + Extra: data.ExtraData, + MixDigest: data.Random, WithdrawalsHash: withdrawalsRoot, - ExcessBlobGas: params.ExcessBlobGas, - BlobGasUsed: params.BlobGasUsed, + ExcessBlobGas: data.ExcessBlobGas, + BlobGasUsed: data.BlobGasUsed, ParentBeaconRoot: beaconRoot, + RequestsHash: requestsHash, } - block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals) - if block.Hash() != params.BlockHash { - return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash()) - } - return block, nil + return types.NewBlockWithHeader(header). + WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals, Requests: requests}). + WithWitness(data.ExecutionWitness), + nil } // BlockToExecutableData constructs the ExecutableData structure by filling the // fields from the given block. It assumes the given block is post-merge block. func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars types.BlobSidecars) *ExecutionPayloadEnvelope { data := &ExecutableData{ - BlockHash: block.Hash(), - ParentHash: block.ParentHash(), - FeeRecipient: block.Coinbase(), - StateRoot: block.Root(), - Number: block.NumberU64(), - GasLimit: block.GasLimit(), - GasUsed: block.GasUsed(), - BaseFeePerGas: block.BaseFee(), - Timestamp: block.Time(), - ReceiptsRoot: block.ReceiptHash(), - LogsBloom: block.Bloom().Bytes(), - Transactions: encodeTransactions(block.Transactions()), - Random: block.MixDigest(), - ExtraData: block.Extra(), - Withdrawals: block.Withdrawals(), - BlobGasUsed: block.BlobGasUsed(), - ExcessBlobGas: block.ExcessBlobGas(), + BlockHash: block.Hash(), + ParentHash: block.ParentHash(), + FeeRecipient: block.Coinbase(), + StateRoot: block.Root(), + Number: block.NumberU64(), + GasLimit: block.GasLimit(), + GasUsed: block.GasUsed(), + BaseFeePerGas: block.BaseFee(), + Timestamp: block.Time(), + ReceiptsRoot: block.ReceiptHash(), + LogsBloom: block.Bloom().Bytes(), + Transactions: encodeTransactions(block.Transactions()), + Random: block.MixDigest(), + ExtraData: block.Extra(), + Withdrawals: block.Withdrawals(), + BlobGasUsed: block.BlobGasUsed(), + ExcessBlobGas: block.ExcessBlobGas(), + ExecutionWitness: block.ExecutionWitness(), } bundle := BlobsBundleV1{ Commitments: make([]hexutil.Bytes, 0), @@ -295,13 +332,30 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars types.Blo bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:])) } } + setRequests(block.Requests(), data) return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &bundle, Override: false} } -// ExecutionPayloadBodyV1 is used in the response to GetPayloadBodiesByHashV1 and GetPayloadBodiesByRangeV1 -type ExecutionPayloadBodyV1 struct { +// setRequests differentiates the different request types and +// assigns them to the associated fields in ExecutableData. +func setRequests(requests types.Requests, data *ExecutableData) { + if requests != nil { + // If requests is non-nil, it means deposits are available in block and we + // should return an empty slice instead of nil if there are no deposits. + data.Deposits = make(types.Deposits, 0) + } + for _, r := range requests { + if d, ok := r.Inner().(*types.Deposit); ok { + data.Deposits = append(data.Deposits, d) + } + } +} + +// ExecutionPayloadBody is used in the response to GetPayloadBodiesByHash and GetPayloadBodiesByRange +type ExecutionPayloadBody struct { TransactionData []hexutil.Bytes `json:"transactions"` Withdrawals []*types.Withdrawal `json:"withdrawals"` + Deposits types.Deposits `json:"depositRequests"` } // Client identifiers to support ClientVersionV1. @@ -313,7 +367,7 @@ const ( // ClientVersionV1 contains information which identifies a client implementation. type ClientVersionV1 struct { Code string `json:"code"` - Name string `json:"clientName"` + Name string `json:"name"` Version string `json:"version"` Commit string `json:"commit"` } diff --git a/beacon/params/params.go b/beacon/params/params.go index ee9feb1acb..e4e0d00934 100644 --- a/beacon/params/params.go +++ b/beacon/params/params.go @@ -41,4 +41,6 @@ const ( StateIndexNextSyncCommittee = 55 StateIndexExecPayload = 56 StateIndexExecHead = 908 + + BodyIndexExecPayload = 25 ) diff --git a/beacon/types/beacon_block.go b/beacon/types/beacon_block.go new file mode 100644 index 0000000000..e4cd1340e5 --- /dev/null +++ b/beacon/types/beacon_block.go @@ -0,0 +1,110 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/protolambda/zrnt/eth2/beacon/capella" + zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common" + "github.com/protolambda/zrnt/eth2/beacon/deneb" + "github.com/protolambda/zrnt/eth2/configs" + "github.com/protolambda/ztyp/tree" +) + +type blockObject interface { + HashTreeRoot(spec *zrntcommon.Spec, hFn tree.HashFn) zrntcommon.Root + Header(spec *zrntcommon.Spec) *zrntcommon.BeaconBlockHeader +} + +// BeaconBlock represents a full block in the beacon chain. +type BeaconBlock struct { + blockObj blockObject +} + +// BlockFromJSON decodes a beacon block from JSON. +func BlockFromJSON(forkName string, data []byte) (*BeaconBlock, error) { + var obj blockObject + switch forkName { + case "deneb": + obj = new(deneb.BeaconBlock) + case "capella": + obj = new(capella.BeaconBlock) + default: + return nil, fmt.Errorf("unsupported fork: %s", forkName) + } + if err := json.Unmarshal(data, obj); err != nil { + return nil, err + } + return &BeaconBlock{obj}, nil +} + +// NewBeaconBlock wraps a ZRNT block. +func NewBeaconBlock(obj blockObject) *BeaconBlock { + switch obj := obj.(type) { + case *capella.BeaconBlock: + return &BeaconBlock{obj} + case *deneb.BeaconBlock: + return &BeaconBlock{obj} + default: + panic(fmt.Errorf("unsupported block type %T", obj)) + } +} + +// Slot returns the slot number of the block. +func (b *BeaconBlock) Slot() uint64 { + switch obj := b.blockObj.(type) { + case *capella.BeaconBlock: + return uint64(obj.Slot) + case *deneb.BeaconBlock: + return uint64(obj.Slot) + default: + panic(fmt.Errorf("unsupported block type %T", b.blockObj)) + } +} + +// ExecutionPayload parses and returns the execution payload of the block. +func (b *BeaconBlock) ExecutionPayload() (*types.Block, error) { + switch obj := b.blockObj.(type) { + case *capella.BeaconBlock: + return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot) + case *deneb.BeaconBlock: + return convertPayload(&obj.Body.ExecutionPayload, &obj.ParentRoot) + default: + panic(fmt.Errorf("unsupported block type %T", b.blockObj)) + } +} + +// Header returns the block's header data. +func (b *BeaconBlock) Header() Header { + switch obj := b.blockObj.(type) { + case *capella.BeaconBlock: + return headerFromZRNT(obj.Header(configs.Mainnet)) + case *deneb.BeaconBlock: + return headerFromZRNT(obj.Header(configs.Mainnet)) + default: + panic(fmt.Errorf("unsupported block type %T", b.blockObj)) + } +} + +// Root computes the SSZ root hash of the block. +func (b *BeaconBlock) Root() common.Hash { + return common.Hash(b.blockObj.HashTreeRoot(configs.Mainnet, tree.GetHashFn())) +} diff --git a/beacon/types/beacon_block_test.go b/beacon/types/beacon_block_test.go new file mode 100644 index 0000000000..d5920e805a --- /dev/null +++ b/beacon/types/beacon_block_test.go @@ -0,0 +1,77 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestBlockFromJSON(t *testing.T) { + type blocktest struct { + file string + version string + wantSlot uint64 + wantBlockNumber uint64 + wantBlockHash common.Hash + } + tests := []blocktest{ + { + file: "block_deneb.json", + version: "deneb", + wantSlot: 8631513, + wantBlockNumber: 19431837, + wantBlockHash: common.HexToHash("0x4cf7d9108fc01b50023ab7cab9b372a96068fddcadec551630393b65acb1f34c"), + }, + { + file: "block_capella.json", + version: "capella", + wantSlot: 7378495, + wantBlockNumber: 18189758, + wantBlockHash: common.HexToHash("0x802acf5c350f4252e31d83c431fcb259470250fa0edf49e8391cfee014239820"), + }, + } + + for _, test := range tests { + t.Run(test.file, func(t *testing.T) { + data, err := os.ReadFile(filepath.Join("testdata", test.file)) + if err != nil { + t.Fatal(err) + } + beaconBlock, err := BlockFromJSON(test.version, data) + if err != nil { + t.Fatal(err) + } + if beaconBlock.Slot() != test.wantSlot { + t.Errorf("wrong slot number %d", beaconBlock.Slot()) + } + execBlock, err := beaconBlock.ExecutionPayload() + if err != nil { + t.Fatalf("payload extraction failed: %v", err) + } + if execBlock.NumberU64() != test.wantBlockNumber { + t.Errorf("wrong block number: %v", execBlock.NumberU64()) + } + if execBlock.Hash() != test.wantBlockHash { + t.Errorf("wrong block hash: %v", execBlock.Hash()) + } + }) + } +} diff --git a/beacon/types/config.go b/beacon/types/config.go index 8cb8808b6f..7706e85f6c 100644 --- a/beacon/types/config.go +++ b/beacon/types/config.go @@ -19,7 +19,9 @@ package types import ( "crypto/sha256" "fmt" + "math" "os" + "slices" "sort" "strconv" "strings" @@ -27,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/beacon/merkle" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" "gopkg.in/yaml.v3" ) @@ -34,10 +37,12 @@ import ( // across signing different data structures. const syncCommitteeDomain = 7 +var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"} + // Fork describes a single beacon chain fork and also stores the calculated // signature domain used after this fork. type Fork struct { - // Name of the fork in the chain config (config.yaml) file{ + // Name of the fork in the chain config (config.yaml) file Name string // Epoch when given fork version is activated @@ -46,6 +51,9 @@ type Fork struct { // Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types Version []byte + // index in list of known forks or MaxInt if unknown + knownIndex int + // calculated by computeDomain, based on fork version and genesis validators root domain merkle.Value } @@ -99,9 +107,14 @@ func (f Forks) SigningRoot(header Header) (common.Hash, error) { return signingRoot, nil } -func (f Forks) Len() int { return len(f) } -func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] } -func (f Forks) Less(i, j int) bool { return f[i].Epoch < f[j].Epoch } +func (f Forks) Len() int { return len(f) } +func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f Forks) Less(i, j int) bool { + if f[i].Epoch != f[j].Epoch { + return f[i].Epoch < f[j].Epoch + } + return f[i].knownIndex < f[j].knownIndex +} // ChainConfig contains the beacon chain configuration. type ChainConfig struct { @@ -110,18 +123,34 @@ type ChainConfig struct { Forks Forks } +// ForkAtEpoch returns the latest active fork at the given epoch. +func (c *ChainConfig) ForkAtEpoch(epoch uint64) Fork { + for i := len(c.Forks) - 1; i >= 0; i-- { + if c.Forks[i].Epoch <= epoch { + return *c.Forks[i] + } + } + return Fork{} +} + // AddFork adds a new item to the list of forks. func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainConfig { + knownIndex := slices.Index(knownForks, name) + if knownIndex == -1 { + knownIndex = math.MaxInt // assume that the unknown fork happens after the known ones + if epoch != math.MaxUint64 { + log.Warn("Unknown fork in config.yaml", "fork name", name, "known forks", knownForks) + } + } fork := &Fork{ - Name: name, - Epoch: epoch, - Version: version, + Name: name, + Epoch: epoch, + Version: version, + knownIndex: knownIndex, } fork.computeDomain(c.GenesisValidatorsRoot) - c.Forks = append(c.Forks, fork) sort.Sort(c.Forks) - return c } @@ -171,6 +200,5 @@ func (c *ChainConfig) LoadForks(path string) error { for name := range versions { return fmt.Errorf("epoch number missing for fork %q in beacon chain config file", name) } - sort.Sort(c.Forks) return nil } diff --git a/beacon/types/exec_header.go b/beacon/types/exec_header.go new file mode 100644 index 0000000000..b5f90bae25 --- /dev/null +++ b/beacon/types/exec_header.go @@ -0,0 +1,80 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/beacon/merkle" + "github.com/ethereum/go-ethereum/common" + "github.com/protolambda/zrnt/eth2/beacon/capella" + zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common" + "github.com/protolambda/zrnt/eth2/beacon/deneb" + "github.com/protolambda/ztyp/tree" +) + +type headerObject interface { + HashTreeRoot(hFn tree.HashFn) zrntcommon.Root +} + +type ExecutionHeader struct { + obj headerObject +} + +// ExecutionHeaderFromJSON decodes an execution header from JSON data provided by +// the beacon chain API. +func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, error) { + var obj headerObject + switch forkName { + case "capella": + obj = new(capella.ExecutionPayloadHeader) + case "deneb": + obj = new(deneb.ExecutionPayloadHeader) + default: + return nil, fmt.Errorf("unsupported fork: %s", forkName) + } + if err := json.Unmarshal(data, obj); err != nil { + return nil, err + } + return &ExecutionHeader{obj: obj}, nil +} + +func NewExecutionHeader(obj headerObject) *ExecutionHeader { + switch obj.(type) { + case *capella.ExecutionPayloadHeader: + case *deneb.ExecutionPayloadHeader: + default: + panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", obj)) + } + return &ExecutionHeader{obj: obj} +} + +func (eh *ExecutionHeader) PayloadRoot() merkle.Value { + return merkle.Value(eh.obj.HashTreeRoot(tree.GetHashFn())) +} + +func (eh *ExecutionHeader) BlockHash() common.Hash { + switch obj := eh.obj.(type) { + case *capella.ExecutionPayloadHeader: + return common.Hash(obj.BlockHash) + case *deneb.ExecutionPayloadHeader: + return common.Hash(obj.BlockHash) + default: + panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", obj)) + } +} diff --git a/beacon/types/exec_payload.go b/beacon/types/exec_payload.go new file mode 100644 index 0000000000..b159687dfc --- /dev/null +++ b/beacon/types/exec_payload.go @@ -0,0 +1,141 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/trie" + "github.com/holiman/uint256" + "github.com/protolambda/zrnt/eth2/beacon/capella" + zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common" + "github.com/protolambda/zrnt/eth2/beacon/deneb" +) + +type payloadType interface { + *capella.ExecutionPayload | *deneb.ExecutionPayload +} + +// convertPayload converts a beacon chain execution payload to types.Block. +func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root) (*types.Block, error) { + var ( + header types.Header + transactions []*types.Transaction + withdrawals []*types.Withdrawal + expectedHash [32]byte + err error + ) + switch p := any(payload).(type) { + case *capella.ExecutionPayload: + convertCapellaHeader(p, &header) + transactions, err = convertTransactions(p.Transactions, &header) + if err != nil { + return nil, err + } + withdrawals = convertWithdrawals(p.Withdrawals, &header) + expectedHash = p.BlockHash + case *deneb.ExecutionPayload: + convertDenebHeader(p, common.Hash(*parentRoot), &header) + transactions, err = convertTransactions(p.Transactions, &header) + if err != nil { + return nil, err + } + withdrawals = convertWithdrawals(p.Withdrawals, &header) + expectedHash = p.BlockHash + default: + panic("unsupported block type") + } + + block := types.NewBlockWithHeader(&header).WithBody(types.Body{Transactions: transactions, Withdrawals: withdrawals}) + if hash := block.Hash(); hash != expectedHash { + return nil, fmt.Errorf("sanity check failed, payload hash does not match (expected %x, got %x)", expectedHash, hash) + } + return block, nil +} + +func convertCapellaHeader(payload *capella.ExecutionPayload, h *types.Header) { + // note: h.TxHash is set in convertTransactions + h.ParentHash = common.Hash(payload.ParentHash) + h.UncleHash = types.EmptyUncleHash + h.Coinbase = common.Address(payload.FeeRecipient) + h.Root = common.Hash(payload.StateRoot) + h.ReceiptHash = common.Hash(payload.ReceiptsRoot) + h.Bloom = types.Bloom(payload.LogsBloom) + h.Difficulty = common.Big0 + h.Number = new(big.Int).SetUint64(uint64(payload.BlockNumber)) + h.GasLimit = uint64(payload.GasLimit) + h.GasUsed = uint64(payload.GasUsed) + h.Time = uint64(payload.Timestamp) + h.Extra = []byte(payload.ExtraData) + h.MixDigest = common.Hash(payload.PrevRandao) + h.Nonce = types.BlockNonce{} + h.BaseFee = (*uint256.Int)(&payload.BaseFeePerGas).ToBig() +} + +func convertDenebHeader(payload *deneb.ExecutionPayload, parentRoot common.Hash, h *types.Header) { + // note: h.TxHash is set in convertTransactions + h.ParentHash = common.Hash(payload.ParentHash) + h.UncleHash = types.EmptyUncleHash + h.Coinbase = common.Address(payload.FeeRecipient) + h.Root = common.Hash(payload.StateRoot) + h.ReceiptHash = common.Hash(payload.ReceiptsRoot) + h.Bloom = types.Bloom(payload.LogsBloom) + h.Difficulty = common.Big0 + h.Number = new(big.Int).SetUint64(uint64(payload.BlockNumber)) + h.GasLimit = uint64(payload.GasLimit) + h.GasUsed = uint64(payload.GasUsed) + h.Time = uint64(payload.Timestamp) + h.Extra = []byte(payload.ExtraData) + h.MixDigest = common.Hash(payload.PrevRandao) + h.Nonce = types.BlockNonce{} + h.BaseFee = (*uint256.Int)(&payload.BaseFeePerGas).ToBig() + // new in deneb + h.BlobGasUsed = (*uint64)(&payload.BlobGasUsed) + h.ExcessBlobGas = (*uint64)(&payload.ExcessBlobGas) + h.ParentBeaconRoot = &parentRoot +} + +func convertTransactions(list zrntcommon.PayloadTransactions, execHeader *types.Header) ([]*types.Transaction, error) { + txs := make([]*types.Transaction, len(list)) + for i, opaqueTx := range list { + var tx types.Transaction + if err := tx.UnmarshalBinary(opaqueTx); err != nil { + return nil, fmt.Errorf("failed to parse tx %d: %v", i, err) + } + txs[i] = &tx + } + execHeader.TxHash = types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)) + return txs, nil +} + +func convertWithdrawals(list zrntcommon.Withdrawals, execHeader *types.Header) []*types.Withdrawal { + withdrawals := make([]*types.Withdrawal, len(list)) + for i, w := range list { + withdrawals[i] = &types.Withdrawal{ + Index: uint64(w.Index), + Validator: uint64(w.ValidatorIndex), + Address: common.Address(w.Address), + Amount: uint64(w.Amount), + } + } + wroot := types.DeriveSha(types.Withdrawals(withdrawals), trie.NewStackTrie(nil)) + execHeader.WithdrawalsHash = &wroot + return withdrawals +} diff --git a/beacon/types/header.go b/beacon/types/header.go index 2ddc4575f1..c8388df1e7 100644 --- a/beacon/types/header.go +++ b/beacon/types/header.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/beacon/merkle" "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/common" + zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common" ) //go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go @@ -57,6 +58,16 @@ type Header struct { BodyRoot common.Hash `gencodec:"required" json:"body_root"` } +func headerFromZRNT(zh *zrntcommon.BeaconBlockHeader) Header { + return Header{ + Slot: uint64(zh.Slot), + ProposerIndex: uint64(zh.ProposerIndex), + ParentRoot: common.Hash(zh.ParentRoot), + StateRoot: common.Hash(zh.StateRoot), + BodyRoot: common.Hash(zh.BodyRoot), + } +} + // headerMarshaling is a field type overrides for gencodec. type headerMarshaling struct { Slot common.Decimal diff --git a/beacon/types/light_sync.go b/beacon/types/light_sync.go index 3284081e4d..3e9b13d0e2 100644 --- a/beacon/types/light_sync.go +++ b/beacon/types/light_sync.go @@ -23,8 +23,15 @@ import ( "github.com/ethereum/go-ethereum/beacon/merkle" "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/common" + ctypes "github.com/ethereum/go-ethereum/core/types" ) +// HeadInfo represents an unvalidated new head announcement. +type HeadInfo struct { + Slot uint64 + BlockRoot common.Hash +} + // BootstrapData contains a sync committee where light sync can be started, // together with a proof through a beacon header and corresponding state. // Note: BootstrapData is fetched from a server based on a known checkpoint hash. @@ -134,3 +141,96 @@ func (u UpdateScore) BetterThan(w UpdateScore) bool { } return u.SignerCount > w.SignerCount } + +// HeaderWithExecProof contains a beacon header and proves the belonging execution +// payload header with a Merkle proof. +type HeaderWithExecProof struct { + Header + PayloadHeader *ExecutionHeader + PayloadBranch merkle.Values +} + +// Validate verifies the Merkle proof of the execution payload header. +func (h *HeaderWithExecProof) Validate() error { + return merkle.VerifyProof(h.BodyRoot, params.BodyIndexExecPayload, h.PayloadBranch, h.PayloadHeader.PayloadRoot()) +} + +// OptimisticUpdate proves sync committee commitment on the attested beacon header. +// It also proves the belonging execution payload header with a Merkle proof. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate +type OptimisticUpdate struct { + Attested HeaderWithExecProof + // Sync committee BLS signature aggregate + Signature SyncAggregate + // Slot in which the signature has been created (newer than Header.Slot, + // determines the signing sync committee) + SignatureSlot uint64 +} + +// SignedHeader returns the signed attested header of the update. +func (u *OptimisticUpdate) SignedHeader() SignedHeader { + return SignedHeader{ + Header: u.Attested.Header, + Signature: u.Signature, + SignatureSlot: u.SignatureSlot, + } +} + +// Validate verifies the Merkle proof proving the execution payload header. +// Note that the sync committee signature of the attested header should be +// verified separately by a synced committee chain. +func (u *OptimisticUpdate) Validate() error { + return u.Attested.Validate() +} + +// FinalityUpdate proves a finalized beacon header by a sync committee commitment +// on an attested beacon header, referring to the latest finalized header with a +// Merkle proof. +// It also proves the execution payload header belonging to both the attested and +// the finalized beacon header with Merkle proofs. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate +type FinalityUpdate struct { + Attested, Finalized HeaderWithExecProof + FinalityBranch merkle.Values + // Sync committee BLS signature aggregate + Signature SyncAggregate + // Slot in which the signature has been created (newer than Header.Slot, + // determines the signing sync committee) + SignatureSlot uint64 +} + +// SignedHeader returns the signed attested header of the update. +func (u *FinalityUpdate) SignedHeader() SignedHeader { + return SignedHeader{ + Header: u.Attested.Header, + Signature: u.Signature, + SignatureSlot: u.SignatureSlot, + } +} + +// Validate verifies the Merkle proofs proving the finalized beacon header and +// the execution payload headers belonging to the attested and finalized headers. +// Note that the sync committee signature of the attested header should be +// verified separately by a synced committee chain. +func (u *FinalityUpdate) Validate() error { + if err := u.Attested.Validate(); err != nil { + return err + } + if err := u.Finalized.Validate(); err != nil { + return err + } + return merkle.VerifyProof(u.Attested.StateRoot, params.StateIndexFinalBlock, u.FinalityBranch, merkle.Value(u.Finalized.Hash())) +} + +// ChainHeadEvent returns an authenticated execution payload associated with the +// latest accepted head of the beacon chain, along with the hash of the latest +// finalized execution block. +type ChainHeadEvent struct { + BeaconHead Header + Block *ctypes.Block + Finalized common.Hash +} diff --git a/beacon/types/testdata/block_capella.json b/beacon/types/testdata/block_capella.json new file mode 100644 index 0000000000..fa6149ada2 --- /dev/null +++ b/beacon/types/testdata/block_capella.json @@ -0,0 +1,1703 @@ +{ + "slot": "7378495", + "proposer_index": "806393", + "parent_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "state_root": "0xb699414b8cae77b7cc01cb3ea5d218062dc534fee640759ef504f1f1f43cf693", + "body": { + "randao_reveal": "0xb9b9101090eabc8d0060ddb91f88bcf579c236883e8b3da0e0192466f5b5739af17b8b7a942036edb28637d1ede61e6c1388e62999b34ea9d54c3b9f1c3683cb58c6dae377b49bc3f604ba7698137c69f7c94108ad29b8de48cd74fc6f173ac1", + "eth1_data": { + "deposit_root": "0x79a2ad4067ee252dc60760a40c00ca5536906668eba5a9e7f7a30fa3b078fddc", + "deposit_count": "970997", + "block_hash": "0xf4fe68e4dab126c3c8fded4c7c825c6cda8b460c81b1a8c3c0b6e10b33e3a4c4" + }, + "graffiti": "0x0000000000000000000000000000000000000000000000000000000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "20", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x89a2fdc5d13638100251a3a447bfbebb205b23e87671f2d0744a1685eed149e5377f9b893ce2cbba559df9ca48cfa075160dbe5d531ed7e32f8ae0a371c38d46c15eedfc1f73dd824fd81607dc84660b97552137af6e7b28ddfe58f457c70091" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "5", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb1c2789fa06b3c2e0019597c54df891c24ef30c8a0c3a2aa2d0ab95b332af97525d4f42518705eebeff6176c87d401e8135711345620a17364f8ad9b7c96ec9973f749d2d05208012e3d25699565f8046752c33c4508ee6d3d3955ca01942a83" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "37", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x825e16bb91abafd316b9d1be810435bb07635a8cd28204e5a1b60f4b2604b085fc6b51850e32d86c137720c1b9e515ae0fc882551f037ba4549d74f686efe48517261eced01174ca699e32e1a42b98d1e2eb523db1e03d7d40be5543c8338645" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "35", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xaff3a1152b91ee89a5557bc852374ce81497663e9a4a18df47cebe59bc926d5845c7f550bb6e55e172c14b12afd7ae3e13c78dc7f256637daa1f0ad66d1d859ff025a379d7c021ff1b4825d6a044a9775254ac0674665d4b361d605fbc6fce18" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "60", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xac7a6651bc4a755414570d441298a7840755bda19fa8b77393e544ece6c917dcb0d0cd092a2b7ec347745c504a626fb70ab0951f48743d872fe21af088668dc29c96f7550d70c34f8f11844c091ed8536696180f5ccc3a9c55b287ce6c709853" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "24", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x92d538e3c9fffd7beb7e408b590c4cf084bc9d9e55fb49d1f84c3da36453c6754b434f47c84139c962c8b0fef8ead19901338417ee0c157e946b987c65babdf767f508981174986a89a5505061406e63f2630dbb5553542dfb7b23993aa27aa5" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "13", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8511a4bb585749da9b9d309172d33358092a07574f213459b618259e38daf493dcad876be2370006c132b384d6997cfe190fa9005f151eb489a5bb1d3cca9491ead28bf3b1874a00612f6a5616757b99109abf42e08fbc7d5a9d4808a72b161f" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "14", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xab5c1637d860eaf8700e1da67df1ffc763cdc0bea2c31261329c6d7d619c9566b0bcdcba1d6a0d2a546dd730d233469d0eeb21dbdba538eae77c9dce5e6953b89a0b47c5a25378b89aefb8a3cb387f10b8ad5b3d4e22b4c7ed6bc99e418ad393" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "54", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb1528f2cb78dda3644816272ec4c24bcc5c554075d3499f48f66f8a3056b5b644acc68733427309567876955199520e50ce72c462d9b4641fd0bd9ff6310a1456b2160d3a12055d37a2d44b8a8739ac04a3f3d498e2b67695f6bd514a9988567" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "16", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb5c2376070b13b792d91ddd3afcb98a15a59f6582a5654264e850064984b2c8f0ae5df8b45b7fe469caa55dedc9ab8950b7bbd375ab1a5de3f20e1aea85be31c3d8c27f3aea8fbd85769ac39e2718ee3aaa4060f7b6290abd3d8a7969a129a8b" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "3", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8e587c9dee7f54e2d9c1058a4afbc28b32f4e45d51303078fa7405cb1a50b8dba1a70dcd4babea8ba37bf9c9e2a1504e007eefc13e2040ee7d11e741e6fa58474347dc490af39868caf2c7c6ffbab90fa4429b068b0673fa7b811ccd847ff9a1" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "31", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x95eb7f201e93f10df263956eb26f3f0e9f0d8db2588d845f0f50314f76ab5b33c87849d7546d56ee99ce6a1b0fe6e67b11e6a813aad3f04f61763772091471f65a1f976a0d2180e58f5db3e54dc16ef7f2b3f20445be68ea1a6701f7d6c6b4a4" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "28", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x97e8426a39404686826704f6f7ab5eb31c532f64352b0e756aa95f4a6742e733053d8bc7e8b44076eed03802dd6a154a177933582503fdfce82b0472e9a7b8c250f0cb7a2c153ad43736c0613004f5b4e915109ed64eeb445453c59a7f51cbb6" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffff3f", + "data": { + "slot": "7378494", + "index": "62", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x861eda1e26cb7866100650538319a266f2c946986db3c90349ac88de7e8ba30d5970454d19b91543d29c1616197e98c2020c3fd54b726cb06249075a0969f16a492282ff60e7d7e656e206eef371ea6cd51cbeb4aed25809077a3c389d505e33" + }, + { + "aggregation_bits": "0xfffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "11", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xadf1e3e7a66cff8cd606f8142fa2341583870f0ee406bf9ce9dc1b85ce004ce42b1425f27c18986afac16b80df70264d0f3ae1b22f5d7d3b34ae88f5f18a37a74ee67c7c1eb0d593d98dcf30b8b18dfe8db9359dbf9737c018ad78da4a07fe55" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "61", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x85dabe8ab392970b7ab10a6415ce2d2c928dee022a148c096c6626c1431a305912a96d267c173d3a388e167fad9586fc0367703c97f6e3d80de3576ce2acc136c69d86f14e611860a29f425593ac0cf1639e8adb49a580051823603bc4fa1871" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff3f", + "data": { + "slot": "7378494", + "index": "9", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x91370c8bfd2b5a47aeeac66693bc824ccc4ddbfe4bb90520efdd60ea0c93083638b21d1574fbf6cc3bbf88094ad9e2e5019c3d1dc316c68ed81129cfae87860a45c7801ad180b2c69df9375b6a8b48ba3e33faf72d48745d2dffcce3199da875" + }, + { + "aggregation_bits": "0xffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "22", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x974181ffb8c8820580b1bb35a58c8cb2fbc5704a2b1f9c14101314eb3bcfddf558aad925785b0ce13dd4d3fd58adaf10168d9f06ac198161bd73e351b7fc37a5a9b6b62a4aa3b028a54779d9f16cbf6872a8339cb58c564808fade87ad7cf3cc" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffff3f", + "data": { + "slot": "7378494", + "index": "7", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x81ca3a2e57e8ce743313c8e83d42b9847d18f48835e1fe445e689fdaf7d72568984de9444a88ba9e7a01b4716581723a0cab39f739f6580ad7f0348c7c5a32d069b1c86efee80161142af6dcd84469f4dd5f19b53318dada988ce2304f7195c5" + }, + { + "aggregation_bits": "0xfffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "1", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x86757289ea9294712661b0c4da2afd17894bd43b1ac2e11a1627a50b0ebdeced615b11058919058356158005ff8d2363157d9be67f4a4600100f4547e7d2bc4b9ef14f81cd21dc42bdc207e3e22375b9737147b5a1cfdbef8959cf1d16d64beb" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "4", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8b8c158686252d39fe3c6edbefdcdedb99ebb7df7f66f6c18f2ab45baaf076c1ad889eca5d3621210f81dafa8055284b01da2e1c0e0309fdacee0dede2f4d33a707d539841488e40e45bd14bd38dc5df1758ec73a0a3dfb34d7be2b361bd5ee1" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "33", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x86ebe26268beda78609de2009ab037c042a8b96acecab1c001ec587fb9dbdb5693595d13b7c61e05cfee9eab79c400090a0c7222d08932956580e5ff0a76028da6375045c7e52ea4a8e0a547aa0464d6ebbcc2a72901e606232a2ff349f59cec" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "6", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x91caf7efebe5c9e719e69d69fb7985348f488391f8885368355fc6bfccd5923d9bbfeaacf6e88d060e6876cf388a3da808e63950e76a9f25b25b548b4e1fab691c7f4bad81021154eeb8066383b2519fb594e15f37938b8c821dd2742193c963" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "46", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x880458dab1b2c5f63576cc5d6de51cc53842c3f8cd491a045317e5cac9010aee197cd578bbc276c487c735b98cf2aa6303651e54475ac7dbd4dcdb5552300d369cd9ee5cab8d9741722d8452957844de93edb8d357f503717d179dca6faa7e78" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "19", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xae536d3961e78c85bf1756622f09ca64d0aca31d39042f32a28f8e7c72ce7778edf53cc997407735c97ecbb06ef49f8c08c33246ea80e9cccf86aa0644298b9ed2398336f88ed054521b94f0ed7d61af4e28c516889e2177ebef4f180bbf2ab1" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "26", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x9822678731a8db092b5e007e53c7e5e7f396a102bec255d3773613a93773bac1608b2530a83d467825872bebf6403d9d0696ab837309b82fbd0fb09365d7d1ce20c19f1abe44bc17550483c5e2e8ec5b630443ab338c522626b9dc692100177a" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "45", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8cf67eaa40f2095c91c19f4a8eea844266d0a9b91211c38d8fa0552cbe41578db864463b292184239eb8a4c64139510c0cb4b7f419d5447f812e4f6b2f3665fb8f717cf07f7e76ea196de7f16711d32d3a9cc357cb9d95b5599e31cf698b88eb" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "17", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x94ebbd88f4aa545d7a7fe44b4aadb74a31a84c38a7ac519ebbc26730a4046ba85a5f64585891b8a67b0822b454892ee816b92dd53fc81799b5f77e3771ac6db169ae99415c6d86cbdb973c826ee5c6869f5840ca86273254c4211981da262001" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "30", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x85b54e1443aeb87d78cfe00681c9d30a619b850a454c3b7e126c23c9bf2df0188f59c715dbac64adf1d93453eeeec7d605f5297b178107bae8ef2293bcbd0c3d8a73f924558b4331661951f5706472fd355a45589e3fea173db238355d0b8d60" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "18", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xafc699d33be631418d821a44f64648697e0921cf1dad336c04d3a4424b293ea70a680683f414e67565d837b55b027f1d04f3d0a0e9a42a4cf61ff977cfd23695e5f91890da6eea51bd46eb22085e1241e970788c17ae8f13288c04724caff17c" + }, + { + "aggregation_bits": "0xfeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "59", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb5d6da99f07a3afe87593ab930848c99fa7ddb352298c210faa0d131ccaea3727cf3389a8dc07d64c6312ffe93660293088e4332aeb60d0df51fa25bd7c922d15cd084db19ea8d69a42661738ae02a0370e99573c2db8b4ba7b6748a0fe15b74" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffeffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "58", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xafaa8a5ad8082a05db922f78205ae39fe45c364176f732f4697a35659d9cb803ac10b90729d11a3f35141095b478a939086b0a195430fc4efcbfc61ef4b79ff770c2b50e3949cb51f977541253877ed319b60d27027e29363b5fa4d8bf37f24a" + }, + { + "aggregation_bits": "0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "42", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb3f70d94e80376f986498cf8c41eeb3376730c19fa0c14ca03dbff1d85180aa475865f4bd85485d0ba5c97f9918f38320ed3e0a2edd1ab159493c5956f1dd111ef85e0921105c7b77dc940401a94db4b62929e839035559072260aaa78f21bf1" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "32", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x886736358ded1b56826412fd3e604cd71832d88a597656a65ca1eae5121fa037148a2e2678f3c2369868e30937cfe7b011763f6bc9bb78107d9158b4048ad7eaf31348a2622541be4942e4f522fbffba520ee58002e8a4d71a3c5f7f040cdafe" + }, + { + "aggregation_bits": "0xfffffffffffffffbfffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "39", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8a8a8641c5c757b6a46dbf2500adb236cb100781588c9b156cf928f237f338620b1856fbc200c95c197b7f08ba89a8a606880a64b2b47ebbde066bb4694ea38795b54cc55f907e09f43eaa0cd4d868b57f0805d3aefd1538102acf295078cefc" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "53", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa26e6c52b9e82f286ea699339e7156ad6e62590855063365c8beb4923e7b5f9bafcbbd40d476a70da97d452989b7b6c307ae8265e31d8ab35cd9d680b5ef4f277ee18c9167a81ec68a58c13447a23cc995807d6a2866d44e2afaa39333cfec71" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffff1f", + "data": { + "slot": "7378494", + "index": "36", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x888547c6d5d294f66ce31b96a2357f7e27e72c8f76865310f83125f158bce9a1ad1506835086cc0bfe88bc2f94ff42de1823bbf61973372da2133f93d1a8d202f3a2d5ea75c446fbda5a834b2f143a7f24d30b1934e511ec8b218668705d2f0f" + }, + { + "aggregation_bits": "0xffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "47", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa35f8f9fd4848615e331c08e9088c434d27f885c1794e138cb6f2dacfbed501df2b07de14c9d0e7704fbb597e6bc8668058e0e838d7a2cd64301068db3e8f0b74991b1a81d2d4591a55ea6489a3b80f5ba2ba818f7907273bfa3aec702cab0f1" + }, + { + "aggregation_bits": "0xffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "29", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa480ba3e3af31e33277863c46165f18ebd710838949b051496eaf1bd79ea361586d37959e398368905bb9fc55bcb48c80a8aff7420234640a34149905726653cb283a4d0f348f572ad0afaa8e42c74cae152ad20bad5615b2a65bc1657260e7a" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "21", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb0be1593527fe7e9bae75a9686dc8027610ffc969dab11c6f4a5b94e6c46e2e4f57022630da357da98c61fc877c8697010e2e15456fc2c4e74932f07ddbccd3fb3ba756f52365df96f9e7aea690554be43d03cb720d2c03d79af35d3b2a1f456" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffdffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "52", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8019f790aeb9e5d5de1c179a02b648b9936a5bced2e3f64eaeb0baa8ed794dcd55ef5a861e7401deb78af96cb83470340c8ff39e320db4e445359519a477740aa5f836aad885759d3759ecf4c56dcdea31b9299a5d476334778ad203656bcf4a" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffefffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "56", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xabc0dfdbb7ea5255f92fae93243569d1362d47d4f67d44c25b38185d4ae2e3b02f812223531e901388f003dbdd4ec1841181e5bafe8f873c06b4e9f01b4701362bd89917c563ae077745e81a922371aed4e17669e3bf5e529743dccb8a5036b3" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "55", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x828866f494c35c712f5ac17f1dd259d9e527509cae8947089fbb1bbc10e6ba9f13cc237caa217c280d060b200cbb122807486307a42ff96c940ae27fd175c5337fa093ff3a64153fe7723e6a54981372875a5a82ff41bc675d4eadccc9e5884d" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "34", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8c77a3007d6fa118fd801dec53dbb8c58b133b319b03befddd022f001dd0b0480841161d38e8f833d128cbb959fab7e90bb1ab60aab531f6af4b77b102d713b2aee48536129b7a309dae9bb0371af7ce683748646087dae41fa528ecb579506c" + }, + { + "aggregation_bits": "0xffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "23", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa790ea43694fce44a777b9071e1a9c7ff6b20783f9c6ed59dd90ceefa71ef770a1b4cbb8c23a295e019055e7fb004b99025dd54fd95b050dd13162ed1d861090db80fda95307ee0196d0faeaf8f83caabc33b332d603061d8de8b44ac9956e8b" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "25", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb4aa421f9d93f03a62f004c9b24e66253957f237fc548b9d60d5d51dbf6e99656c16aabfec33ab6c0765ed16745e33440650c42ce90e0ec4021524610d6ec7211b1bbff23ba913fbdd2505970213a9b890c0347f35f671b01d9bf0387e97631c" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffdffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "0", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x89726e95f463d159279178dd7abb677c507575ad4b0e59f52303af95983e1c5bba45e49df86f5ba88ea8c433b9b5beeb02ddbe75bbc3404d85355a0af642ce615051414897b6bb3fdf14787cac832f3a93ee3a83e00d412af3f5d513ee12152b" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffbfffffffff1f", + "data": { + "slot": "7378494", + "index": "57", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x818dab21ea1a34d31179a3db511b93f538399b1f898744b01b5c569a3c27107641d5c16c3d3a3367df8dfd28e8686143035b5334d595e30b0eab3739f248462bf2bfaa69a067cb2ce9c279630196f554d73912e38702fb1e5991b7003d1c3546" + }, + { + "aggregation_bits": "0xfffffffdfffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "12", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb8cfc57942d455cd6a93d9a0cddd662c99d3f317a6e2585bc36399192d17111f9aa2fc5f7a5c80ba532c3a8a1bc3c46b08a2bb3b2db007eb7f78056332d8a9d903d11488022927f1a7c9d60c8c509089ca8ab30cf913a9aa7c45c91275287774" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffbfffffffffffffffeffffffffff3f", + "data": { + "slot": "7378494", + "index": "48", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb5ec81bc92ea85c105acb162bd95daaa7daff124f5effa1b399ff6d92beddbc10d9c8a217b8a03e047f8c9644200e27605a7ee60068fbb01a1517bbfe383759ec24a553d621a5e5290a41e9b121fa13e82769ac40a450b30cac877871f90841e" + }, + { + "aggregation_bits": "0xffffffff7ffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf3f", + "data": { + "slot": "7378494", + "index": "43", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa40d82c6c4e71c5ee93e31d4987c016fb3933bc348ee33a7a9b6e9cd592377af9461138d40c1f1188541acc9b6a10bf4035820563a467a4c345125660188ad9f5ba433b4a6168757c37ba8f895faae87dca56b4e1940834ddd5765ebc7cd7dae" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffd7ffffff1f", + "data": { + "slot": "7378494", + "index": "27", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x9439508713ae98aa4a8614b4fe4de5738bf4935d00f769e3a8afadbc1880e87854918cc6f1cc1e4beb61672fa9ef944e147c469aca29bd2d0a924730cf618729269a11b3c65edc1b8dcb836bd670ab2fc0af20ee139ab2bc57de07412771d26d" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffbffffffffffffffffffffffff7fffffffff1f", + "data": { + "slot": "7378494", + "index": "49", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb67ecdb8a80153ee5f63d2f1afb1a5e9fbcadd280f015b3eaddd420126b5f550e0d2f1115781e29da657662c6e821a2d0014076059eadb67468e269d6fa277555f553e54d4810525ed31277644967c8f2a8ac98f95a406f055172ebc78f81650" + }, + { + "aggregation_bits": "0xffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffbffffffff1f", + "data": { + "slot": "7378494", + "index": "10", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x99ab8d38886fc33b205acd97c0c069c0fb3f55e5dccd70611c1f159b73e0d3d20a91997f4b3e93f80bac42c99ea92b5d1460a78b53f335c0de7f9d04f77ac59bbbc141fdfeabadb1125a5ecff7d9d421c6d553837d34eece99ac2a59f3938af1" + }, + { + "aggregation_bits": "0xffeffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "15", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x922c40a03459860e7b32df69fb2f1153e0c52601a08e7716d8a637a0ad2eb717ddd8f90d95d71c77f1baff1d9c386c2d1627c9ae755698ba3a1d5bd62dd4343c708da623db4c8aead3c52d309aaf3fff7b90a8ea739ab076f2e623227efe57a1" + }, + { + "aggregation_bits": "0xfffffffffffffffffffdfffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffdfffffffff1f", + "data": { + "slot": "7378494", + "index": "40", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb6b43e392a1ee37d435a900be9fdcc1e4802c87fdfe441570f6869a61c8e2de9efcf80e266d3dc4bab4aa70f0fc99dff1424d5eddbe179b4abe8c356f948a7309290ce791de8af16410727ddede4b8a8fdf20fcc3496495825a15a9cca07f04e" + }, + { + "aggregation_bits": "0xfffdfffffffffffffffffffeffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "2", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x979301b9636dc5decc492df123920c28464ea97c2630e300d44c4b6d700a2f21d46f1b922763517b0e8234c7724f146505c18b0397b613aa2e1bd2fbca5266f03fc113af517726c7fc70aa930ee95365f32cc552d779447622b1b27dbd9394f2" + }, + { + "aggregation_bits": "0xfeffffffffffffffffffffffffffffffffffefffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffef3f", + "data": { + "slot": "7378494", + "index": "50", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb06352fe674ca8af724db3c28eece93c8ffd29b12d1db38f04dc7a4d74c454899aa0a17e821d7b768ed3c5c849b559270126a0f2572cc7076b9278289d79415817691d7c3519666603f2b0ca8f80dfdfdbbed87ed8fe328bced445aa9764b684" + }, + { + "aggregation_bits": "0xfffffffff7fffffdfffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fff1f", + "data": { + "slot": "7378494", + "index": "44", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xad45143668483fc7aaae6cd3f46caf4461bd543a062679ee3c8c786947d580fcc20b358858606edf65d21c512965aeec11fbfb0f9dd3212e9b04b4fc683fd69a2dc2991a9297963fa683c0806948310b645cadc76f7208ce44c05c5f127ea110" + }, + { + "aggregation_bits": "0xfdbffffffffffffffffffffffffffffeffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffff1f", + "data": { + "slot": "7378494", + "index": "38", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa34e85836b67b56d722c02c0cbbfd44492f0f8ffeacc9deed8e1ec8efb2180d1818e102451eb9571f4e265a20e73ac4702fcb55ef2012aea7bc2a73efdaf24e6e81d01aed51d937a17df21b4bb9cc5945dd5a5fb2d7a14d727283ec2d5cd3ee6" + }, + { + "aggregation_bits": "0xfffffffffffffffffffeffffffffffffffffbffffffffffdfffffffffffffffffffffffffeffffffffffdfffffffffffff3f", + "data": { + "slot": "7378494", + "index": "63", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x95697e4ab24617346af013bdb607a4cd9ba68647ecf77adff969fb25cd2849a0f0947a71dac14cc75bac28f13b88490701cc5c1e3d8578a147c9fb2ea5ea0641464d4702bf2ce4ff733331d6946787f142fc2dbc2a31c5d4bdb859d5464c6c41" + }, + { + "aggregation_bits": "0xfffeefffffffffffffffffffbfffffffffffffffffffffffffffffffffdfffffffff7fffffffffffffffffffffffffffff3f", + "data": { + "slot": "7378494", + "index": "41", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xabc2f9ce23e03325784b4fa68950f36f93c9b51df97040402e72b4edd7fbed17f624632e666ca725a8044906b2643ce10cf1eaf55cf661e0ef9d6024a013ae4eecf14d2952cdde2169d8f2dba7b28dc7d48465f0a87f2b3c6b3a287c4ea5e63d" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffdfffdffffffffffff7fffdffffffffffffffffffffffffff7fffffffffef1f", + "data": { + "slot": "7378494", + "index": "51", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xaf2d02761082aff8842a44321c687d8722aebea6611d1d65873f50515b751cf67eb5929fb99c3a8818929d2d7e8bda97189c3589a5b99f8b027464017208e7ec79e3fd0a4b88c5df1ce277d6da7ae9d9b675cbe00ec0085e85f36e15d9eea1c9" + }, + { + "aggregation_bits": "0xffffefffffffffffffffefffeffffffffffffffffffffffffffffdffffffffeffffffffffffffffffffbffbffffffffffe1f", + "data": { + "slot": "7378494", + "index": "8", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x93669ada664de0740ee57235fc4aeff39daedca3d99190c4bf0f1603636ed4fb8d2289aa63362f2d0ef109c2e01c54bc0c01fc17f71c5ebcefabdf5237803a4608e621ea0f576d0209a96186ab548b5f8a35ed44dd8ae034abc7290424aef1d8" + }, + { + "aggregation_bits": "0x0000100000000000000010001000000000000000000400000000020000000010000000000000080000040040000000000010", + "data": { + "slot": "7378494", + "index": "8", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8136d4d491ac7d49fc966091ff31631e7da9dbc33ca7d5ccdcc8836c3c797ace914c8cc512a371440e0352ccdfe104231059453e21f915d16d9ba64463f6943963f7515f7bb6e823218852d583109ff99d99a58928820020f36cb0ea7987acce" + }, + { + "aggregation_bits": "0x0000020000000000000100000000000000004000000004000000000002000020000004000000000000082000000000000020", + "data": { + "slot": "7378494", + "index": "63", + "beacon_block_root": "0x8d93e82f4ccae01a237d9c1bbfe4deb546aea2c02f3a5d8fa6f8befe96c9a537", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x80996d8bfad4ce23481fdfb8824b8e60ef828847174dc64e824a12542680572fd38eaad95f2d99c8bb9cbbcdaae094f9066d3ed62875bdf402f678808e6b545d843ad872b3a14e3d69e5b04a910877b92299fe6586f1a0768a83639c76814872" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000001020", + "data": { + "slot": "7378494", + "index": "50", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb649f1829fbf1ab8c2737fa4bb5a2db3a9f4d9ae8dbf378b9f9e5a0f927a0314bbcfea4cdbdb71d78d43922cf0d489860b7570e02489defe2276c88c574388dbc32e926ca124f25c20cc6e8ad0951ecb8f2f1ef70291bceaf5bee6ace949b235" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000020", + "data": { + "slot": "7378494", + "index": "9", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xa71226b5430c675b00c95baadd0d051d83745f995e449e00a2d29b5d3e45210841b8023bf1a6f32d5756751d8f51623e162ebd1e2faf773552e5900152bee0cf9e59c7e955707e99a2fadda7859d304c5f12d328990df642006aba9d777db1d8" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000020", + "data": { + "slot": "7378494", + "index": "33", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xad1f93841542a300585d51d034d2b4c906054eb89b5193efabc7ac8cd0461ce31af127d973361cb1f9c98d3ee1fbd9480d8b3786df4c631619510ea75c8b1065e2077dda4f51053e9a36096b10b5e0b781bb0be24e0cc8ba7d2dfc564fc96618" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "7378494", + "index": "38", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x88b2b792e1f1ed648e645fae6e0bc6c7021a99f11e05e9a994120887c65280a2e5e49011e06f263a666c1186cf73252507b6efe0b049b876ef686deee017fac76d363b687dd53c6dae6926b6a831304cd15b83b7d46b33fa9ad798fea3f7204e" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000010", + "data": { + "slot": "7378494", + "index": "27", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x886c27c1f86d771936ed595e7f145b0d9fee329f6beab5e7e04be10ae3043cc964612e8e9e60e0a1eb65acbe58a3e93300df489d2a782708db1de1918e7ffbaf276594df1a73746805a4e321c52a61b4af6422058cf85cbc322b6be791287b27" + }, + { + "aggregation_bits": "0x0000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000020", + "data": { + "slot": "7378494", + "index": "1", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x93ed986d6948d557e631c70abc77a8b18b82900b5d95fe91fdc9c6d53e239b0095a28133ba21a05779758299545d64ec145e3e7c805ba4c26c3a71647597fc5923098f196c1d514b45db59f109b77238b0bf98c8dc5749c6426be4b2aad9d827" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000010", + "data": { + "slot": "7378494", + "index": "21", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb41891824051794a18ab11a12a524c7857b327567304109dc83abddb49475ee6e639525ebb505488a631b84354a97a6b130bb559cbe773578969c2608da8854b76283a48f1b1af6090f13af65436c444ac4fa3e023a55716990386f61be6e30b" + }, + { + "aggregation_bits": "0x0000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000020", + "data": { + "slot": "7378494", + "index": "41", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8145a8db62dab4c43d075f212357edf2395a50da11173b0455a88e0aef96acbbb403258265da20ed30b2bd8cf741f9320a659f3bb58f22bd51b011c1f15ec1bf9c23d5471dd40b12c939abfdf97ebd6a81305451dbb970cb3d8064621f3eb14d" + }, + { + "aggregation_bits": "0x0000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "7378494", + "index": "25", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb29d54c853e60e0e29f59ebbf00a729f04d7e948a4a063bfc66b273b0cc3de66dbf9df090afc48e472a0ab8242ead35306ecf170f5dbcfe299927201c395ac18f42afdc0ce3974c88a06ed7849cd8cfcfe56db4853c9490fef930a8f8dccdc55" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "7378494", + "index": "15", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x99ab43ce9475ea56c6cec9f284782a7b2234745ce68e3d25c2a2b9044ad7fb2a1f574fa329e849b64c8eb0224acd428510131378b3c3d7d9a8bb50a147939bcb439dc808e153217e3a0ae2ad31e3c570fab4ca851d6d9d9397a60cb8c769aeec" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110", + "data": { + "slot": "7378494", + "index": "8", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x953635b952cd3c924d91b80cc8fe725bf256eea9d28a7325c713bba8cb6f0ac2a4b8161dd865a2dd460531046be9bc4a0e4f461002d9d51d43d20c3d3cd61c18738a0254769502e915d5235dcc0f59f65d962e660b24a11896cdd133c68c001e" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "7378494", + "index": "32", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8d442fe70c41b582ad3bb0c8ae2044dd6f8990cf2030288e9e8d2816f3ecaac2c74db82c6ebf730ccfaf40b8a61b18d619729f0bd439b0b638168c15d167a8e12f5f3ca9e609582b0e70525d9aedaed4f4cad6fc186e509af58e99d8d847b53c" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000010", + "data": { + "slot": "7378494", + "index": "36", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb250f21b8113d831e77df1a84ace39a7b44befdad1090f6d653ea687ee96a8f3ab061389c7d7d67f8488a2cb79259c29070b7f4ba7dba087fa1051ddb6278bc377db21e7bdc42cab6f7c1bab75a9ce7bd7a8d5645294e16d253f01a73df6f50e" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000010", + "data": { + "slot": "7378494", + "index": "51", + "beacon_block_root": "0x27c3f56f32193ea28595e76681ea327d4a165cec76e7416b8ea63f8706ec9391", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb01b9b75b99e2e22b0a6f29c6d89c3c0aaf5e917d322fc487ff0fa4a32a74b498c6c6bc823f2247e84fb0849dd79f8511293d78ea24e671fd803e5894466d70cbe6b997d59a5fc530435551e41e5a3ab713eb42586375db8ee3349221f23516a" + }, + { + "aggregation_bits": "0x0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000008000000020", + "data": { + "slot": "7378492", + "index": "9", + "beacon_block_root": "0xeab9fe966f136db09c1a42dcaac1b8bf6e58a9e722612a5ac73ab4b2f48b001d", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xafbd61d25ab5fdcb3c8a263b08a20e3d315b209eadf2db068300075baea8f39a7afdcf7e7453733ae9ba9eae8422aa0508ad01fd943fe694a474282d66dfb32c9f2c6669f17bfa4ee01a11281060e310a7d8e834fb9d6e43676501e013a1c204" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000020", + "data": { + "slot": "7378492", + "index": "43", + "beacon_block_root": "0xeab9fe966f136db09c1a42dcaac1b8bf6e58a9e722612a5ac73ab4b2f48b001d", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x8a55078263eea258c83d53073dc9bfd783741914eeda57dcfe1dfe4e935daab5320b46f0ee60488a1eef6bb427a4fe490c4c347dd99f986e246478071923488b37c7e63fde9fe0c1b6d259423cc9afc0e22f38abf172e335e5a426229a54155c" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000020", + "data": { + "slot": "7378491", + "index": "11", + "beacon_block_root": "0x7da3491e9e1ca60297512f8c2304b13f570f395665236a24a968fae6dd44e402", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0x86a7aeadf1031d01003400c5912323b659ed472ea4b913239a12fc494388884ff898b8f9c0fd400e935917021aa42fe517e6594d304e57930f501938adbb5f759890bbb2d2eff9a4a46b1e6dcdfe64a01d6106037b735fc4d721ebdece7cfd11" + }, + { + "aggregation_bits": "0xffffffffffffefffffffffffffffffffffffff7ffff6fffffffffffffffffffffffdfefffffffffffffffffff7ffffffff1f", + "data": { + "slot": "7378486", + "index": "41", + "beacon_block_root": "0xa1946350486b0ca91a93fae2de443411901a9ac824a8cc93dd046ba15f7c8ea6", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb7d6275bda2982202a8c75ce31190bf726a43ec197bab381e4ea61997b8fcbaebc1fe8a94b6f865b297fbd723709222b0621da909edc0fdbdbf5eb085961c142afd07e73dc7075f23221d934eef0e835dd5b042f1c74bae569e6446c5238e1a0" + }, + { + "aggregation_bits": "0x0000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000020", + "data": { + "slot": "7378478", + "index": "55", + "beacon_block_root": "0x96a3675a608ca14556c06d35ac4783492cf033cdd328973788909444256a8c9a", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb98e95ffcfe118d1d5b5a4f310d1871dcaff5e65cde31355828787bedb27146c96689ca9ed3f32fa204ec81b99523f4e0848161ce7b9b3fa5fa38d0a9d96ba50b1ecdccad3e2a17d3598b9c64017d7589617f3a8009366664a884bf91e2049eb" + }, + { + "aggregation_bits": "0xfffffffffffffdfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef1f", + "data": { + "slot": "7378469", + "index": "33", + "beacon_block_root": "0xe91d6c3eaf1b381dff1bbd0558d9e6dcae714efffc72890391b3ac8fcd56f51d", + "source": { + "epoch": "230576", + "root": "0x8457e7b625df2b40a671fb135acc0fef14d29c39a2f8ffb80fbe0d274bcbcf8c" + }, + "target": { + "epoch": "230577", + "root": "0x4d12215357069641e9aca3d7b03851bde21faa001110c6204dd88d317696f3b4" + } + }, + "signature": "0xb7cb86960dc0dd66f3bf556de8f71a09ec8d2e0d0d0a483006e19671b3fa74470492b30e9bb7e3458e080577b031b1560aeaccd0861092f05a0116144d838931b78ecaf1ed4b8a5dda64bdd18758956b1f01f8c4d579c614d68880f9c49b0834" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xffffffffdfffffffbffffffffffffffffffffffffffffffffffff7ffffffffffffffbffffffffffffffffffffffffffffffffffffffffdff7fffffffffff7fff", + "sync_committee_signature": "0xa3e0ea489cfc3f2370aa2587f486e99a3ae405bc1d46466c2cd373cd9669bec5818914ade2a465096eb4528a1d1f368817ed65262a195206ef87503ecbb22e17dd90f6155fa61f4288bf44baa088e50ed3776fd9e005b45b15a016ec8fb050bb" + }, + "execution_payload": { + "parent_hash": "0xf08c1d3dd9cc49d708e89dfe8543dead59bda12ebc714c9df0a5902259dd4fb4", + "fee_recipient": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "state_root": "0x7a4d9731f6fbcb9135225b82edb9418b8bf9407957a524cd3d3f0e60dd520974", + "receipts_root": "0x4e30ab0d1b712b4b4b93864f956287dfcd688f3c077dd356d1b78b6d316d1622", + "logs_bloom": "0xdaa17125c458582c508070b48993d338a9aaab4f0f902129981d200a8110108262b67dd54282243420d2138b013505390a9333083f917cc0d660958ab12ea300e013a1dc040bdc18890f7a19d95a80e43e8326e289c79c880ddaecc69e62a0c019087924d209c18730c210b24c265c0f02974088880844b29754921a52793855874822d02a468aa0114dc4c84a230c96600e6485ed1d8c8eee6900ce14d8166d82a0f0c14aac2042e10600e851d68c31260a0ea844b32833244d056711105941c7c1129239c51d395142886aac98f20748382938044ea6534a04513a42303063a83eb1960b326db1c3a7609a8881c801aaa09a9b5b0038f3806bbd475f971c43", + "prev_randao": "0xf25f7763261cdf5ba7a89b400998a1403f12dde232c5d9ed85caeac1f30974b2", + "block_number": "18189758", + "gas_limit": "29970705", + "gas_used": "10355584", + "timestamp": "1695365963", + "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", + "base_fee_per_gas": "8339352708", + "block_hash": "0x802acf5c350f4252e31d83c431fcb259470250fa0edf49e8391cfee014239820", + "transactions": [ + "0x02f9081b018314470d808501f1106c848305bc1a946b75d8af000000e20b7a7ddf000ba900b4009a80840efa8910b884be341de2523740544851b599aafe5870c5997e5c8addecc2649caa3918b54ce26f2e30f64c5b684b141311ce138ab5e00e71d6ffdc00059448e5de5cd0ad98ba6288ed7819246a1ebc0386c32c314bc4189840ffa4c5e25dbfc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0d56273290d339aaf1417d9bfa1bb8cfe8a093301f42df90725f901e6947e52eb9fadb02f95de1eb8634dc0b4bbd4628f38f901cea0ab2e97a75db32eb3b19136ac5fcb6d7a64d182e81eb81decf514e3d877434a50a00000000000000000000000000000000000000000000000000000000000000007a0404e955b4f11522f99577dfc88d0dda82da90992492b18491843775f5a1cdc61a0000000000000000000000000000000000000000000000000000000000000000ca04729effceb34e32ea7539c2827046bdcb467a191dfa169688430ec34d1dd2963a029cb8bd4e192d16f51155329ce8b0f5eb88a1d9e4d3b93ce07efbac9e1c4d175a00000000000000000000000000000000000000000000000000000000000000011a02dee8fee0050f9b50254bb2dce2adbf1d1176c39619cfda08a9fcd208972e273a0000000000000000000000000000000000000000000000000000000000000001aa0000000000000000000000000000000000000000000000000000000000000000ba04cf2bd51af1a8ac56b4fb0e23da1717ba813b99917e5e36de6e3ae319a316b3ba00000000000000000000000000000000000000000000000000000000000000009a04c39b3fdaf585b5ee5622d9ec0cb4cf2bc86694673ab95e5a63f084e37d4e9b8a00000000000000000000000000000000000000000000000000000000000000018f8dd94b54ce26f2e30f64c5b684b141311ce138ab5e00ef8c6a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000af901c59475c97384ca209f915381755c582ec0e2ce88c1baf901ada0404e955b4f11522f99577dfc88d0dda82da90992492b18491843775f5a1cdc61a04c29a58e6ae8e8d5675a8f982d2b7b5003c687633919a622b92973af39bb0548a0000000000000000000000000000000000000000000000000000000000000000aa05a0dc5d4d49c845a7e5c8f30d3eb17f36afd4610ee030b6b45acdef0e06b51fda0a1d95ad0e500f5e4b1bd149186814df18eb98e8780bf676e8f3db3a0f3face33a0d6cd76e208ea80eb6f706515ebcfc15fc94f57f3e18452883d9478107143d407a0000000000000000000000000000000000000000000000000000000000000000ca0154bb98efc83b034ad81fbf23cc88c9737739df170c146ea18e8113dac893665a00000000000000000000000000000000000000000000000000000000000000010a0f2c891cab2af1155379e2cb5a591b3e1f3859d3ef1c231d4987204c1fe7ea115a09bb3e24e1534bce24e9896f3377327d742d6c1d430477b7ebc070c2eb64e3147a0000000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000000bf8bc945cd0ad98ba6288ed7819246a1ebc0386c32c314bf8a5a00000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000001a0f09b457c15826396efb730bf67656e5debac76c904fafa6861ed5765cea4df44a00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000000f85994d0d56273290d339aaf1417d9bfa1bb8cfe8a0933f842a0b17349740b669941baf55dc09d27353d5066f7515a585f533b40596bae334695a0577b913a3c8810dd10161c9ae11e2ee31042564c62114c83b0bc5d3a3e71b362f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f884a012231cd4c753cb5530a43a74c45106c24765e6f81dc8927d4f4be7e53315d5a8a0b1aa816c3c240e8935aa44133611887ed238c7d51f01f8b123b6f452e8272eb4a009d0a653d028a303e3445ad078cd9784c32b672ecd784e05dfa863f177744f2ea027902350b23dab8e343168a9c4efe515d63cf66808c513bd6a00ee1036192055f8dd94e2523740544851b599aafe5870c5997e5c8addecf8c6a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000000680a0b4686af228e16c5e21f2b62f7896e62b8e47e9a81c89cdfc8c804880880030c8a0606201c4f426d1864e52a0833c31f7b6e74f828a1b5e425ba2c01acef3635bf0", + "0x02f9015a015f85037e11d600850667aa78c683035925947a250d5630b4cf539739df2c5dacb4c659f2488d8802c68af0bb140000b8e4b6f9de950000000000000000000000000000000000000000000000000021d6a5778fff4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000002e0ab608813dc3a413481d8a600ccb4f5704545200000000000000000000000000000000000000000000000000000000650d3bc00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000007e52eb9fadb02f95de1eb8634dc0b4bbd4628f38c080a0c616f500f8735ac3ca85feacca898cb12b655633124e6781d4594259db78255fa02bbea542ddda2bbccbc45c9729b006ad7929a768adc8d3de97eba872dc9b8f64", + "0x02f902fb018201c78405f5e1008502ceb580f5830326ef943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad876a94d74f430000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000650d423b00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000004dde6c0c64ea600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000007e52eb9fadb02f95de1eb8634dc0b4bbd4628f38c001a027bb6379a22d41fe5cf6aad6c448e7fe2980e1844b246d3a338fc8904b9ba882a05a438e766d3cc916550c63157b7ec6f654ecc94b30009ad54039393bea47e7ea", + "0x02f901da01818a8411e1a30085036d589cd58303455e94b517850510997a34b4ddc8c3797b4f83fad510c48801f161421c8e0000b9016466b210ac000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000001f161421c8e00000000000000000000000000000000000000000000000000000015e5073bf5771200000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000b619d517c47fa807bb19e6a4e66bf4552fd2e6210000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000007e52eb9fadb02f95de1eb8634dc0b4bbd4628f380000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d2a52f45c74b358abe1428bc43f0ce9ddf130780c080a03d2813afeabbb404e687b0749061af0f17ca73f95c8b2813fca9bbbaedc929aa9f3b3da0c7b741f3badb07c45c805c5a186507d2842612688b02ecef3848fdb3", + "0x02f905d8018204b784070c4719850239295ca88304ebeb941111111254eeb25477b68fb85ed929f73a96058280b9056812aa3caf00000000000000000000000074f33228ced53754d0e3fe7ba92e46abd5b15763000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000075c97384ca209f915381755c582ec0e2ce88c1ba00000000000000000000000074f33228ced53754d0e3fe7ba92e46abd5b1576300000000000000000000000019f4d695952cef25328686ac7db05bddaba81e1e000000000000000000000000000000000000000000000000000000009502f9000000000000000000000000000000000000000001b74e3d0196b6e1d324e40efc000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c472501348bab121842e674cbb95ce7116199c57adc865b22220a8326716986d3f7026efe4e32c5b5788b54ef177118af7b39a2aa632ec79bd480a6a462a2e423500000000000000000000000000000000000000000000000000000000036600a007e5c0d20000000000000000000000000000000000000000000003420002b300029900a0860a32ec000000000000000000000000000000000000000000000000000000009502f9000002705120f6a94dfd0e6ea9ddfdffe4762ad4236576136613dac17f958d2ee523a2206206994597c13d831ec700e4f02109290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000bfa899c1ad97229d9c604e9ea927c7acb988c05c00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f00000000000000000000000074f33228ced53754d0e3fe7ba92e46abd5b1576300000000000000000000000019f4d695952cef25328686ac7db05bddaba81e1e000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009502f90000000000000000000000000000000000000000000000000015cb4e8892f0860000000000000000000000000000000000000000000000000000000000650d3b680000000000000000000000000000000000000000000000000000018abbaf4c47002000000000000000000000000000ffffffffffffff001b5d4864463ec6000100000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000041d2aaac950ed27cd9eafc88901ba8fecb9a9e787076ed7ccaad7a5b2ac743e3f76774db49ca7e585494c45ef5361da23f9b2ac2abe1f04b97c3a67575af4160a21b000000000000000000000000000000000000000000000000000000000012340020d6bdbf78c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20c20c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b54ce26f2e30f64c5b684b141311ce138ab5e00e6ae4071138002dc6c0b54ce26f2e30f64c5b684b141311ce138ab5e00e1111111254eeb25477b68fb85ed929f73a9605820000000000000000000000000000000000000001b51926d602a7b1bb5bc8f7c7c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000e26b9977c080a01b70f49b8caa36113ad532d50e5bfe8106213089870f11918531e888fe8ca111a0087c38a323105c67801b3a260ce1015ff467cac1695397bd371b3f16e928e0ab", + "0x02f9021a0160841a483f6e850242357375830372d09468b3465833fb72a70ecdf485e0e4c7bd8665fc458828a97379e7e50000b901a45ae401dc00000000000000000000000000000000000000000000000000000000650d3ff500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000d0d56273290d339aaf1417d9bfa1bb8cfe8a093300000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000741f485b010da3f2c9d4131f867155f1b3a99d6c00000000000000000000000000000000000000000000000028a97379e7e50000000000000000000000000000000000000000000144eba8f77fc518b23de7e0e4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0ad879c7b36b6756e998558fb6f4af076035b4d8aea7558a50bad0146254cf541a0143d22a8ae3c317bc879511c43db0c8bd93006b9b0935696477c3e49ce74b4ee", + "0x02f907e7018314470e8521fda6fa928521fda6fa9283055234946b75d8af000000e20b7a7ddf000ba900b4009a80840f6920dcb8aebe753de2523740544851b599aafe5870c5997e5c8addec7e52eb9fadb02f95de1eb8634dc0b4bbd4628f38c2649ca9607a38b54ce26f2e30f64c5b684b141311ce138ab5e00e75c97384ca209f915381755c582ec0e2ce88c1ba71d6ffdb0005a7869f60e85cd0ad98ba6288ed7819246a1ebc0386c32c314ba4c5e25dffc418e5a880c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0d56273290d339aaf1417d9bfa1bb8cfe8a093301f42df906c2f901a49475c97384ca209f915381755c582ec0e2ce88c1baf9018ca0000000000000000000000000000000000000000000000000000000000000000aa0a1d95ad0e500f5e4b1bd149186814df18eb98e8780bf676e8f3db3a0f3face33a0404e955b4f11522f99577dfc88d0dda82da90992492b18491843775f5a1cdc61a09bb3e24e1534bce24e9896f3377327d742d6c1d430477b7ebc070c2eb64e3147a0000000000000000000000000000000000000000000000000000000000000000ca04c29a58e6ae8e8d5675a8f982d2b7b5003c687633919a622b92973af39bb0548a05a0dc5d4d49c845a7e5c8f30d3eb17f36afd4610ee030b6b45acdef0e06b51fda00000000000000000000000000000000000000000000000000000000000000010a0f2c891cab2af1155379e2cb5a591b3e1f3859d3ef1c231d4987204c1fe7ea115a0d6cd76e208ea80eb6f706515ebcfc15fc94f57f3e18452883d9478107143d407a0000000000000000000000000000000000000000000000000000000000000000fa0afa9712ae32b996e680ddfb579f88c5714eff15e4f29153eadd3decaad54ebcaf89b94b54ce26f2e30f64c5b684b141311ce138ab5e00ef884a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007f8bc945cd0ad98ba6288ed7819246a1ebc0386c32c314bf8a5a00000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000002a0f09b457c15826396efb730bf67656e5debac76c904fafa6861ed5765cea4df44a00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000000f85994d0d56273290d339aaf1417d9bfa1bb8cfe8a0933f842a0b17349740b669941baf55dc09d27353d5066f7515a585f533b40596bae334695a0577b913a3c8810dd10161c9ae11e2ee31042564c62114c83b0bc5d3a3e71b362f90228947e52eb9fadb02f95de1eb8634dc0b4bbd4628f38f90210a0000000000000000000000000000000000000000000000000000000000000000ba04cf2bd51af1a8ac56b4fb0e23da1717ba813b99917e5e36de6e3ae319a316b3ba00000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000018a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa02dee8fee0050f9b50254bb2dce2adbf1d1176c39619cfda08a9fcd208972e273a029cb8bd4e192d16f51155329ce8b0f5eb88a1d9e4d3b93ce07efbac9e1c4d175a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000008a04729effceb34e32ea7539c2827046bdcb467a191dfa169688430ec34d1dd2963a0ab2e97a75db32eb3b19136ac5fcb6d7a64d182e81eb81decf514e3d877434a50a04c39b3fdaf585b5ee5622d9ec0cb4cf2bc86694673ab95e5a63f084e37d4e9b8a00000000000000000000000000000000000000000000000000000000000000019a0404e955b4f11522f99577dfc88d0dda82da90992492b18491843775f5a1cdc61f89b94e2523740544851b599aafe5870c5997e5c8addecf884a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f884a0b1aa816c3c240e8935aa44133611887ed238c7d51f01f8b123b6f452e8272eb4a012231cd4c753cb5530a43a74c45106c24765e6f81dc8927d4f4be7e53315d5a8a009d0a653d028a303e3445ad078cd9784c32b672ecd784e05dfa863f177744f2ea027902350b23dab8e343168a9c4efe515d63cf66808c513bd6a00ee103619205501a01099ee4dda8320e58fa87e38ad5c4766544c04e9254ece6d1a3c4ccc274ee2dca07090040021e1b7f9ccbc624e5da07f116d614fc01f09a9fff9486206f9ee979e", + "0x02f9015c018202678506fc23ac008509e5bc4ec683043206947a250d5630b4cf539739df2c5dacb4c659f2488d88058d15e176280000b8e4b6f9de95000000000000000000000000000000000000000014bdac5c38b84104abdb58400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000f6ab629ecafe852cb118ecfcb769d07be76ff84f00000000000000000000000000000000000000000000000000000000650d3bc00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c6980fa29a42e44852e29492268d9285d89c9dacc001a07c0b8eb74b0376c57aba5629769a2d859b374448e4a4af1e712a306abe80da3fa0288f7c9958856d9756d758412924b5c3be08b307bdac7e431e77aaad5d771060", + "0x02f9015a014f850342770c0085062c0faec683042bbe947a250d5630b4cf539739df2c5dacb4c659f2488d8802c68af0bb140000b8e4b6f9de95000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000005ad7881a995c530d519ca843bb1e5c61441c0f4200000000000000000000000000000000000000000000000000000000650d3bbc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000bcd657377d4086cc582b215294c3611b997ef1bec001a0e4c47bef5e5ea64705bdab7477c89e220a29c3402d17edaebef86894b36c8c1ca05ae62df6e69158e03ae480d2415bd511af7dd9612b64d87f4ec735a5cf294fc5", + "0x02f90175018203bc850271d949008504685640288303d0909468b3465833fb72a70ecdf485e0e4c7bd8665fc4580b90104b858183f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000bbb34ffb832146d599ae08091b096d982c76a2e2000000000000000000000000000000000000000000000005b12aefafa80400000000000000000000000000000000000000000000000000000b7eeb4a764743c6000000000000000000000000000000000000000000000000000000000000002b9e32b13ce7f2e80a01932b42553652e053d6ed8e000bb8c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000c080a03c983e7673809a7272afe748c4242806f7830a2e2de3f3601c8f07b3240b21d6a02240632441b63caee132602f48cdf69795f449116ef6677dac7a8a05b598ef3b", + "0x02f901750182013f8501dcd650008504e808dcde8303ac91947a250d5630b4cf539739df2c5dacb4c659f2488d80b90104791ac9470000000000000000000000000000000000000000000000249e29cb37a9ce051f000000000000000000000000000000000000000000000000000432db12e2353000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000001630d8aff69591bc1e7e0226b55867e4587e495800000000000000000000000000000000000000000000000000000000650d3bb60000000000000000000000000000000000000000000000000000000000000002000000000000000000000000089453742936dd35134383aee9d78bee63a69b01000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2c001a0b373e83ac5f99059fc700e20e7f2acfe059bfb57731d7d5478b2342101e93619a07cbd8831561f65d1629fbab4836bdf4216871925c7356ec364f34f1fbd00f49c", + "0x02f9015c01820151850165a0bc0085044f395ec68303beef947a250d5630b4cf539739df2c5dacb4c659f2488d8802c68af0bb140000b8e4b6f9de950000000000000000000000000000000000000000000000000009664a6852aa790000000000000000000000000000000000000000000000000000000000000080000000000000000000000000481104920a3170954144d97f0a38757ca92c928200000000000000000000000000000000000000000000000000000000650d3bbf0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000007e52eb9fadb02f95de1eb8634dc0b4bbd4628f38c001a04c7b5d7e2454abc29c2a93aa65d4264e7d678d7a0ca79343024803ef2523fdf6a0239df32468a6e2a8fe914ed76ba2d959d10aa6daf4d5b678abd99607ead4986d", + "0x02f8b10139849502f9008504b6f005708306cdd8947a1957ea071eddd490d3a5eda903eaa0dc76a1b880b844c83ec04d00000000000000000000000000000000000000000000001b1ae4d6e2ef50000000000000000000000000000000000000000000000000001b1ae4d6e2ef500000c080a0ee6bd76834fe37d3248dd7bdb36476036f459be43264d0a162dd2deff8e49e16a0096ad979fac82231507a3370f7cba185910575d39448656974545041dfb7df8e", + "0xf9015269850306dc4200830497d1947a250d5630b4cf539739df2c5dacb4c659f2488d88016345785d8a0000b8e47ff36ab5000000000000000000000000000000000000000000000000000a8e0c17312bfc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000008b8eafa96fddf5ecc8e13f5c9668eb6d1b69e6720000000000000000000000000000000000000000000000000000018ac0d5e26c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000404d4a815ea854bc0666cee8041af8fd1add1a0125a01c14cccee71797a25705f50d74232fcaac27cce9dd776abaac6b4bc16603da20a073f8671fbc40d82219e604413e38e3aff8f72f7cd565d9fb6b3863d6012f51a9", + "0x02f908b3016184b2d05e00852e90edd00084011a49a094260552861d45681d7a2789ea29981f184aac43da80b9084412514bba0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000002696459e63520de63d10f8bffa89c1fbd0ab67b000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000130f7fa60923711db8a5b57b1da930c83cccf494000000000000000000000000130f7fa60923711db8a5b57b1da930c83cccf4940000000000000000000000005b5a6fd70a7e7df8580331f0389e95bafa6c16f40000000000000000000000005b5a6fd70a7e7df8580331f0389e95bafa6c16f4000000000000000000000000130fc0d30181fd072d2d47f57e9f99f9db97f494000000000000000000000000130fc0d30181fd072d2d47f57e9f99f9db97f494000000000000000000000000a5b5408340fb28dbc20833af0a2fd28cbd39dbbf000000000000000000000000a5b5408340fb28dbc20833af0a2fd28cbd39dbbf0000000000000000000000006836f0fccb1473833c4e6a174c626afcdae441320000000000000000000000006836f0fccb1473833c4e6a174c626afcdae441320000000000000000000000005b5a6fdafa5ecf6bfef4ce654957abf4fa6c16f40000000000000000000000005b5a6fdafa5ecf6bfef4ce654957abf4fa6c16f40000000000000000000000009e2c3c4d1c69c1124a68ed427f1f8336e6001bea0000000000000000000000009e2c3c4d1c69c1124a68ed427f1f8336e6001bea000000000000000000000000a5b5408efc081bf3e475b4661993bccdbd39dbbf000000000000000000000000a5b5408efc081bf3e475b4661993bccdbd39dbbf000000000000000000000000dcac4d02bf15d84d87de85e7c3ef45632335d924000000000000000000000000dcac4d02bf15d84d87de85e7c3ef45632335d924000000000000000000000000ea2402baa40d3cb80ea47000f238ac24f72cc452000000000000000000000000ea2402baa40d3cb80ea47000f238ac24f72cc452000000000000000000000000dcac4d020a47ec66da0e2c23632d35df2835d924000000000000000000000000dcac4d020a47ec66da0e2c23632d35df2835d924000000000000000000000000e4bc15674dd27cdfb960eb1d9439ec796d2a5fa2000000000000000000000000e4bc15674dd27cdfb960eb1d9439ec796d2a5fa200000000000000000000000068d985eec63bd7826f70fb3add66a5c098b5368000000000000000000000000068d985eec63bd7826f70fb3add66a5c098b53680000000000000000000000000ea2402ba035899397f09fc91e61e854df72cc452000000000000000000000000ea2402ba035899397f09fc91e61e854df72cc452000000000000000000000000de06285d8a040612d0dbd05d4399f0a3dcbc1bb5000000000000000000000000de06285d8a040612d0dbd05d4399f0a3dcbc1bb5000000000000000000000000e4bc156b3576af8b257599923d810ee6632a5fa2000000000000000000000000e4bc156b3576af8b257599923d810ee6632a5fa20000000000000000000000000000000000000000000000020f5b1eaad8d80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014d1120d7b16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020f5b1eaad8d80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000554a4fe826a7c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c629bcf4aaf2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014d1120d7b1600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000554a4fe826a7c80000000000000000000000000000000000000000000000000000000000000000000c001a0ab7d5cedaf8addf1751c2f6d2b580de1c01206cbd9ec9db3ff88b45abb4361d1a03102bf37fa598ccd40bd2462ef7afaa86fcb8e0005468d11730f8826bfe456ac", + "0x02f902fa0181ab849b4a5b248504840300dc8304028e943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad874a9b6384488000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000650d422f00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000004a9b63844880000000000000000000000000000000000000000000000004586c5c7355b6aa875700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000055559d9b47fff7b7f891de11e9ef56654b42ffbdc080a08d3ceb25f1579ea7be864c88a06d5b3248d9c8b531250b401ecd5775ba75a0d3a0084a0f03552dfe5a19cea0219bbcdbd001d2e7018c9dccc6c14a73debe72106c", + "0xf8a955850424bec27a82ea609457b9d10157f66d8c00a815b5e289a152dedbe7ed80b844a9059cbb00000000000000000000000005a479d8b3c72821d41a9c802a492a832582d2c800000000000000000000000000000000000000000000000000000000000186a01ca01d03b929585ed25b52fcda511ddba993d5c33089a6979a91322979c84d719227a07eaf12e88497e5e0605ab09e79c5071d31b2cd4e722d8d9e4bbd361b9a458dc3", + "0x02f9015a0182024184b2d05e0085039c6900c68303e88f947a250d5630b4cf539739df2c5dacb4c659f2488d87b1a2bc2ec50000b8e4b6f9de95000000000000000000000000000000000000000000000000000001347e08055c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000e0a01fdf17141ca25fcdf03e0549899da1f7c4700000000000000000000000000000000000000000000000000000000650d3bbc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000005041f018b4c130e32ae985edea8e76d2195001a6c080a010bf2f3323e4ab64986f19c242cfefa8f3337cdf51aefa6bd14c2162e0841d85a039b874de823db572e680d2cd2977947cd53e97cae3de37f28e2e2ec82be58d7b", + "0x02f904320149846b49d2008502540be40083057e99943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b903c43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000650d422f00000000000000000000000000000000000000000000000000000000000000020a080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000014fee680690900ba0cccfc76ad70fd1b95d10e16000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000006534c83200000000000000000000000000000000000000000000000000000000000000010000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad00000000000000000000000000000000000000000000000000000000650d423a00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000041c51a446e5b38de3265e4aac64cf330db3b161068817c2528156883bf6d37974a4cccf0ba1de588cb06198574a5e078996a302c3fc44e485658a820a1e1ee34711b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000003828eda98d800000000000000000000000000000000000000000000000000000000033c38fb00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000014fee680690900ba0cccfc76ad70fd1b95d10e16000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c080a05c0b5c4fec450d7bdbad29101e73841a790a5ca301c216cf2b1e2fe4364a176aa05bfb1a25a5696803ba38712379c43348b0335781e677bcaa372387a63f0b27fb", + "0x02f8b2016285016a53e9ae8503cd844cd28307e76f9441c2ad4add42a83eb74701cc8b132501a991a93380b844095ea7b30000000000000000000000003999d2c5207c06bbc5cf8a6bea52966cabb76d41ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a07d54a4d6c40115cd4b473c549c4e3e777c07409ab76240af7a02c583c776ed8ba067a3dc9cb4d5de0388b4f10ab6ff4d16738fc7d8cadbea1dbdcd0be56c2fc1fd", + "0x02f901d3016385016a53e9ae8503cd844cd28307e76f943999d2c5207c06bbc5cf8a6bea52966cabb76d4180b901648ee938a90000000000000000000000000000000000000005535f8d310d4b800000000000000000000000000000000000000000000000000000000000001d81dec19f649700000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000038400000000000000000000000000000000000000000000000000000000650d3b5e0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000041c2ad4add42a83eb74701cc8b132501a991a933000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000067863757276650000000000000000000000000000000000000000000000000000c001a0deb6157d8706b9e2b6c0f563880118a8d1af08b0ae0fc5c5143d08074fb91751a07d4d3ef21f4e10facabcbbf35ff1d6058333ba0309818f15febe38f02f5d4906", + "0x02f8b40183020a3c8501c4a33e8085043c98d81482ad0b947d1afa7b718fb893db30a3abc0cfc608aacfebb080b844a9059cbb000000000000000000000000de77e98e58dbb7e77e253c090843508eecb3d74d00000000000000000000000000000000000000000000000274a9edfd85320000c001a0393071e73830abb485f7c44cf466fa0623cd75dbf55aea004c4f1f8b459b82cea02e5b3fd2945a43df2e863267cb7ad0923f1606ec85019e566f6c9a281aadc2f2", + "0x02f9019201028432a9f88085033ff5448183046ba094889edc2edab5f40e902b864ad4d7ade8e412f9b180b90124acf41e4d00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000ed12c3837fa789b8bc37ffec8b2d19f05262396b000000000000000000000000000000000000000000000000048e7fb600addc0bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000001ce6fc6b5b56cd00e9ba034105888c40e78af8d31afb2146c9b06da5c504162b451c4c7f47a49bcb9f8065f95b39d88513111b3ae650f2bee3b831eeda243ba0320000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000048e7fb600addc0bc001a0a733075c6d25de1b3e400a40e908e7a3bee8027f1a0e055145cb0060a179da6aa01f5af45659a9f2c7972d590f3b7aaf9f8783d2847fbecefcc2d633d582dc748a", + "0x02f8d90102849502f9008504b4ef743283012bbf94f5c9f957705bea56a7e806943f98f7777b9958268802315429b2830000b8646ce5d95704a2e178341aa53fd0c0852851ce5338d293401da5e2101d4316304bfe656e3900b333e3142fe16b78628f19bb15afddaef437e72d6d7f5c6c20c6801a27fba600000000000000000000000000000000000000000000000000000000002688e5c080a096545335507fdbe249d1a93a4c7d8bf85ca933b4b22d137919d911fab7107590a00300ebb0895223b288c4dcc4486bd92f9503c947ce10128535c6cc7168c2623f", + "0xf8ac827b0b8502a4a6930483013880941a3496c18d558bd9c6c8f609e1b129f67ab0816380b844a9059cbb000000000000000000000000b02ed88986b74574650de87e8f6a578b1e2427ad0000000000000000000000000000000000000000000009b588922c49ec28000025a0c07fcabdae75efa779e9237bae6a42cecd95f20eda89cb106c6183934d38da6ea036dc93263ff67eeee085dc92497390199bc7b5e734d65931009992860b30fac9", + "0x02f8ba0182ed82843de47d0d85029346fa1e83028c5694fb071837728455c581f370704b225ac9eabdfa4a872c934b294cd400b8445173ffaa0000000000000000000000005c5d5202d8cd871614c86ee7586cf27f7ded92750000000000000000000000000000000000000000000000000000000000000245c001a0649da1987303cd516dbfe574df1107223df0ab5b828b9cfdb8dbbb3fe40c880ba02284a3e8563423761dc74f078a5cfec479936dd84aefd28ea91b1dc9897c5b51", + "0x02f8b1012484773594008502b96b6cdb8301117094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000cf3aa1a77fa8c221f80bd15f4d7a36186eeb7df10000000000000000000000000000000000000000000000000000000007270e00c080a0d5701426adcbf17f20353389eeedff7c30420dc3b95b1a105b42f67f45994f8fa0040e87ced08417fa84ca69d6886c06d34cc35655eecd745f70633553cc17884e", + "0xf9018b08850218711a008303717a94be6fee3756f7be3a0cd492059341cb5b77dd81f980b90124f01e063a0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000069df738dfc2d1e2ea3e1314f00000000000000000000000000000000000000000000000000801277b814c28a00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000020000000000000000000000008a9e6d160d7c0087121e40e398fa3f67a4598b75000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc225a0915fd2529c30cde9428210ce48f96ccc6ba1f46b2ea0a17bd50e2a0471b6a969a07bb3f7e47bb7f1832586634194c777af4c7b09390eb8ba8c0849d3716f6a2f22", + "0x02f8b30182014c84773594008502baa6aeb78301117094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000001207fc953ca19e470063a9d3c944fcd5509fdfd600000000000000000000000000000000000000000000000000000000b8c63f00c080a0ed29e0284c913d8c1fa3d249a7325ba87efd8e74df2e60922fbb8b21022c5c3ea06ff2aac75a35a5bcc92d437b8856d4123d8b53b02f7e597e046b495f341452c1", + "0x02f8b4018376feeb84773594008517bfac7c008303291894430ef9263e76dae63c84292c3409d61c598e968280b844a9059cbb00000000000000000000000019267f3000ad73223dd7a8fa9b9b5ce58c28712100000000000000000000000000000000000000000000011578c3544a26250000c080a0553dbd4c1d4227a24041d09bbb6b782b0b61502d4a5a6161694b2b59c3f237b2a07c155a16a056e8079870843155b5a9ce3d28bd8c2371ab18c35f8cf57bde7e93", + "0x02f8b201820d9c8459682f0085046856402882c992942960d71855a521c8414d29a27218efdb67c3418080b844a9059cbb000000000000000000000000781c876ce98abca880f304c5a3934f65e64302730000000000000000000000000000000000000000000002e2b4737ca62f6e0000c001a0b4c3620cb8b4fce3aff26c6016de8b9633530915ba752e1de440d69fb7d1b5b1a005bb710b536b214b076d430e03e9e360cbfa53da7ce7df02aad3a25b7f8e1d78", + "0x02f8b001598459682f0085046856402882b5f394b92e40c0bd1a135c5cb19ea98d2d729909ceab6180b844095ea7b3000000000000000000000000e1ce310e3cb20073ff25b1a76faa7e032f41cf7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a06a91c0e1442a2be601ac13be71946b026c0e9b60c7c36b8c3b595bcca611947ca05fce31d09568abc84ef55ac29b90c078b9518fb033d62ac5289a5e45174d5336", + "0x02f8d301821db8843b9aca00850430e2340083010323943506424f91fd33084466f402d5d97f05f8e3b4af80b86423b872dd00000000000000000000000072b83a114e3254849679673e97b2ea3bd9a3920a000000000000000000000000dcff7bdd67eb501f214faf41c9d596b53dbffc5f00000000000000000000000000000000000000000000000bcee26cd2632f8657c080a04a69ef73e530864823505230de965a2b356f98a73d925486f4f67d2b86f0c358a0533047aa4de7d29814677b06933138b74cdcd994b3d12199cbbd655e31724c9f", + "0x02f902db018205a68405f5e1008502d00f7c9983095d7f94c36442b4a4522e871399cd717abdd847ab11fe8887470de4df820000b90264ac9650d800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001648831645600000000000000000000000020561172f791f915323241e885b4f7d5187c36e1000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000002710fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe10b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2a7800000000000000000000000000000000000000000000002a1f12d4e0aeba9d7700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000002811653334d531c09600000000000000000000000000000000000000000000000000465205e1b4d892000000000000000000000000560805d557eba6a00e5618e019a216efa47775d900000000000000000000000000000000000000000000000000000000650d3b6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000412210e8a00000000000000000000000000000000000000000000000000000000c080a0afc9c3292b7fdbbcd16941d4fc65d344e0d302943e2a59490593b838ef1b1293a05902fe30e723dce269bb1f0860c70185af61a46c8f90577ded2d63ad1e9c61d4", + "0x02f8b20182019f843b9aca008502b4998a8982f35294fa1a856cfa3409cfa145fa4e20eb270df3eb21ab80b844a9059cbb0000000000000000000000008cce8709a5fbd78a27aec1e7174cc5276fcc68fa000000000000000000000000000000000000000000000cb8e39d1bd0d55c0000c001a0eb27acf651a0ac3afdcfbbd8a8dab0c857f93c993dee146e1dbb0691a2aef6aaa00d8fea3ea755e14ccb60a96ca51758820e7eecea035423a14d6e910154bdda7e", + "0x02f8760183021d35847735940085048623a528830329189445e7d523dcf83269f8b8586655a966a733fe1b38870e4c533842e3c080c001a02572c1abf8481b58339d759464a03efbc5d1cb131bf6a307fcb9d8f6634977baa0488ae4caa36e4458e9691db0cc546761a6fd6012fd34a26f87203b0cc7b6959a", + "0x02f8720101847735940085026846008482520894dce92f40cadde2c4e3ea78b8892c540e6bfe2f81878e4be056c093e080c080a0cab09875ed6df6893ac90891df5252bb0063bdd5b179b3fdce5e403b34d46d2ea0239c71539b9a304b712197b1472c248dcb0e52841fc4aa5887e288fe567b66c9", + "0x02f8730168847735940085026846008482520894dce92f40cadde2c4e3ea78b8892c540e6bfe2f818802a6c88a9741b23880c001a0c683b1ed551072e7db8937ad58dd78b4ed01a17e0b2bdd1efc2bd67a792f3828a0261297f9861d626d3ab4b1bc70b55252a708a308af1d2a557215f086c7149de6", + "0x02f876018301a9658477359400850459566d0882520894b2943be603e11b493b20411692a2e2efbfa82aad88010fc90b84e4d40080c001a0592edcd0217bc3c65ef4d35d9c9da691e50489a409e7c1b51cbd6a309477a78aa02aff224db05486243416bab5f1a876e789ec7ac6d443c55ab201572b4e49db16", + "0x02f877018372bf4e84773594008517bfac7c0083032918948745d208d684a61a5023b9a96c1f28890d20a064880558f9e74f19580080c001a07f9b8ba8a93d671036ddc7f70c72e7f78d90fb3b512f16d57e48b26ec8d4c0d6a04987db6930bdca36415a3e3394d975d0d62631d0433cc7ac4f38ae3163254180", + "0x02f874018201ab8459682f0085039c6900c682cf0894cac0f1a06d3f02397cfb6d7077321d73b504916e872386f26fc1000080c080a053d7a48f67ef1d604f88d930ce6e7f9b3aa5259292a66b23dbf2b331fc789967a040dfc3dcd1a9009e93987ec6cf0cf5e7632dab5a09138211aae44f324a5c8efa", + "0x02f901b201058405f5e1008502ceb580f58305f0e2947a250d5630b4cf539739df2c5dacb4c659f2488d80b901445b0d5984000000000000000000000000df98398d12eecd6275ff3c906686ff7aabb4513500000000000000000000000000000000000000000000001ac42dc434e9683659000000000000000000000000000000000000000000003c49e9764603dc9f33960000000000000000000000000000000000000000000000000ab9aeb24e319a9c000000000000000000000000484219de75a791cd83d613e14408a433848576f600000000000000000000000000000000000000000000000000000000650d46070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b9a9af484bcba44a3085ac4180e942823d5060a722e9b7b5802ff83ae116cc656397a4bc869fb7ce4ac178414ec2fb454c588ff36e25363adda87c8e8a6301bb7c001a032255120bf16f7ec8ad6cc0d1a54f90f32a3c45e54c05504e97c9b46594e6ac2a0361d40030b950ec6b9e571ef065b46f678e6a03732c3469f1c6fc215d8f2cf77", + "0x02f9089e01068405f5e10085025048a8558304f81b94def1c0ded9bec7f1a1670819833240f027b25eff8852d9b35e9d150000b90828415565b0000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000052d9b35e9d150000000000000000000000000000000000000000000000000000000000022483477300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000052d9b35e9d15000000000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000052d9b35e9d15000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000002360b0cea00000000000000000000000000000000000000000000000052d9b35e9d150000000000000000000000000000bb289bc97591f70d8216462df40ed713011b968a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000533f6f812421b9271db6edf0e46fac24ff9d6aad00000000650d3b760000000000000000000000000000000000000000650d3b380000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001bfba32863e0e5c402ddb4184ea18bf566eca381c20c49835abf88888deb33f4636aa077425d4e30877a69365a4e27f5f5c57c254c4348123a9509d9e09f0f520000000000000000000000000000000000000000000000000052d9b35e9d150000000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000008c8f51000000000000000000000000ad01c20d5886137e056775af56915de824c8fce5000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000869584cd000000000000000000000000382ffce2287252f930e1c8dc9328dac5bf282ba10000000000000000000000000000000006937218260a6fe77fb37f7d4df81cc9c001a03bb4473cc91acdff066f03c76fcf96aef9bd697c23df960da88042d620e0f0b6a002ca2df45f6862adfaaac674ae1043d54dac16fc46c18ecc5d6d6868fc425e1e", + "0x02f902d4018201ee8405f5e1008502ceb580f58303f8e294ba12222222228d8ba445958a75a0704d566bf2c880b902648bdb3913e7e2c68d3b13d905bbb636709cf4dfd21076b9d20000000000000000000005ca00000000000000000000000001717b7ee44c3723b4803a11ee843b697ce6c10300000000000000000000000001717b7ee44c3723b4803a11ee843b697ce6c103000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e7e2c68d3b13d905bbb636709cf4dfd21076b9d2000000000000000000000000f951e335afb289353dc249e82926178eac7ded780000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000006e7491a814db77000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c6ae2cbe30784f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000778b18beaa1367ec080a0050b4419f0b5d0f3b5f401b140005dd239e3942ca214489de4dd3a6f9e813bfca00d2d58a2513c3e3a313271e323c582501fa6551b239aa653f074f1d054f3ba19", + "0x02f874018209ff843b9aca008502c6aedeab825208943f4833b244c7dccf034da7d733c3a485f0c121cb870254dd702e280080c001a0682d91b2afdb8fdb79e9e557824eafafc13cbc3938b59f9e2069271e0c63b46ba038b4ea5e7fe315e2fe7d7ab753ea7e71426bad774e63ea74cfe05ba1c228ebf5", + "0x02f877018309113a843b9aca00855d21dba00083033450946fddb91b1e3cacec85b8b8c568e950744a0c9037880de0b6b3a764000080c080a0a159e0e7479d0ce98decae732245a2cf4ba9895fd6599c05739bfb2d0c0b1777a002f81af2bce29a0eaa3bd5b2a2110681aeeaf116956a0bebaaa1c4da430e5250", + "0x02f876018317771c843b9aca00855d21dba0008303345094605f78cd9fd82433dc1fd9c3b331aaea445708e08723b8084e6eb40080c001a064278ac9b8eaf6ec3a6491403dd3360ab49396d33520c8487200ec41095cf979a00cbc0c2ab4910246ac613f1e80e8bd946fdd377fdd7089c3348a46e415109129", + "0x02f876018317771d843b9aca00855d21dba000830334509469e28c8d85d25ba1cd0544e76bcd6d24fd4313a8872386f26fc1000080c001a06803dec8fec9bd1a9a833bde86397f3fc9209fe6786a45cd122601abad8e7a8ca0690337d320e450419489bc6e5bc1547e84e69607707d22a6e774e3f43739f555", + "0x02f877018317771e843b9aca00855d21dba0008303345094ab477e5d4cc2d975ae082be6252813d8146eb77f8801305350ef75c00080c001a0fb61c6e7d898b87df03cb61b2a95b1ecdef0501fa5b28edb9a933ef52181a167a03d66b75f2bd8855fc0a9419b1bea646e946d715ef49199e8690c415d6644284b", + "0x02f876018317771f843b9aca00855d21dba0008303345094fba5a6c47c5477a48e151f6e0d7bd00b025ad096872386f26fc1000080c001a01617cbe439398443fa1ddf8db7423cf96b210fa744a9d557fdfd127ba28dd793a02f34a3b89a0265ec8b26f3318ae2c781be64081f57a4207308cefd1f52ad1615", + "0x02f8760183177720843b9aca00855d21dba0008303345094601092bd5dca1d80f7ab81e858a001b699f3360f87b5303ad38b800080c080a05a8be1066f4ad8bb8d013f5d8671cd0cdeebc3b58ece98d1b294be1a8d062a44a0136be11303edf7cdebbe64fb287a09bcd8fd27a84ed2ac4759cb3753f8115734", + "0x02f877018303de21843b9aca00853c89352800830186a0945af99d79d74a2f14e7f71af444dac47ab0f8edc188025b5b7c3634602380c001a0f2b74ae6aaa3aa430b91b952def69c7f86a7be3d7426ddcee2d7128c47b4c60ba029a970d3b242f15c5f4041f77add145458f65dd53ad226d5f6388977cd385e31", + "0x02f8730102843b9aca008502540be400830186a094c902fc03248c7024456cd2ae6f21eb804495bcd787d8b72d434c800080c080a0e2e167824f28238ea5e48bd18d94c3872c1b2f891df1f968c08c34efa6c461d4a061e2793b77dcd67d6370ebef6baacb8600b08574ebd25342df115603ab775fca", + "0xf90193808501fafa22af830247759432400084c286cf3e17e7b677ea9583e60a0003248804e0bf754f744f00b90124eb6724190000000000000000000000000e8abd54de0a63797f59a9bd150ca91088fc242200000000000000000000000000000000000000000000000004df6dc79989000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000b54a3000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000e8abd54de0a63797f59a9bd150ca91088fc24220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026a071f36d2a326722e5b7fdc463f812f58ba4d65eda867e1cadc41df67bcb13a73ba00830771d975236296a0ed54c3b062cf8305f43b814f54b7f9ad2756a1c621a04", + "0xf86a81ec8501fafa22af83020fc99437476750a31266557609212e9707895e06e36ca480841f83bf4425a0bae5b977cecf7b90264dec4307e611d4305ae02ac714179968f9357ae421b5afa05985a78500bbc35b18c6914b47a682a24f5c4e4c0ad7afef7a32155f7c199676", + "0x02f90574018202b38405f5e1008502ceb580f58303978c9417b5a77d6e7cde0e8d1f59bd1edb26d9badf6e9e80b9050487151b880000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000117f385a0d4aec94000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003b06bc7b205f1a827f6504244db7a8f5b0bf7dfa00000000000000000000000000000000000000000000000003c57c4c7d3bcb5e0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000cb83e1143173140c8a2314ff90df5b68574a6c9bf5b6bd23f1ca6a0c04faf71e675fa4a7d9eea857686f38887307c74f310dd9d5d7ad0f03f766b4143974dfa099632d0c373e0c1de94476e5ef74b6bfb7890f153d65fed04e17ce6f7a071e9a271efa2ab9f7d8427716e425df8119373c5e55910575b9c5a3b232dd75a647b185704492b0bfc912392ab9748398d6590290c9289d49cbe4f9234d2da2d483f7aef656ccb10b9f033832ec9c9985711c1edeed643b652143ed632b91fbf5a26a99bfa4f414bf756586214ae1629b9472d84611e9261a117cc7550c12269bc8e7bc87d19f9d86a184ba374c1b266062d4482c39f1865f634c74309d3afb0734cf3f291e8709c6caee62ee9e873506d7c640761259dae43539a776213b8642f7bb0a226e0fb9373a97a95565aaf5f2982abe18d9a20a2a00c6ee435dc4d0c9acc21f89de707b46bc7636728f0d0c1e1dc032091d72eadae6455bddeaf8ceb6f39ef2a0d596396598f6876744405716f180ae880c5f158098efa1360f85568da00b1000000000000000000000000c55126051b22ebb829d00368f4b12bde432de5da0000000000000000000000003b06bc7b205f1a827f6504244db7a8f5b0bf7dfa0000000000000000000000000000000000000000000000026d8e645dfd3559940000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d847b709d8cf1ce1bfcfbd95b61af94558dd54972ec8aa7b4fdcb0092a8a3e8523118a915a1557371cf10f5c8dc24a60fea45f7d1d1b3350162e952dba5bbc259b4e1a3edb86654bc8f8292a95ac01b8b581f9ddc5e632d4c57f4c345380686d7e11ae992e09634ea7998437703fdc39d512ed56b41c43d1b672d9ddbff2cb9132724ddfcd6fd2c1a1db26f45de6f271d02d7a48d92a4b0c50ddddaee7f6d6cfaa1635f5e826379d2afda090ec54c462f5cb22a66cccd3252132f2771c0f2e38b6326cafe5ed2c21e287f1cf5adaf409e62b4b9b2d3459d9b70a0708f919b55cd1d93cf68330451403808e0bca32236fb54c5c33f274b6c4b151b9ad77c970a7cc8c1a3f5db80adde3acc78401a26e94eae5d51e672083ca6ab126a34ba2955f03164bcfb9afbbb86f2fad7153fae146b396b7a402e49c5b954cdf3c56c4969337b970128cd940cdef8bb9ad944bddb6077db30908b48bd26054273916895bd008abe7f481a8aedddab03befb792704804cbe6a51588fbbb0cc38127a904166338c90b1fc0319ba61d5ba86eb9737921c05509afff5f27c9233780e9881b117bdc080a0e76e6674393dcb18e1448fecf3d10fcb44fe68a3eda7d30fe9b91956bce9e015a01801e00a6d848a81c471a563b9acdaa664f4c6a638f7c2be37186915a9739ca5", + "0x02f9011301820fc98402faf080850212f12e1983069bcc9487870bca3f3fd6335c3f4ce8392d69350b4fa4e280b8a4a415bcad000000000000000000000000ae78736cd615f374d3085123a210448e74fc63930000000000000000000000000000000000000000000000005a0d8f1eab8280000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014b30b46ec4fa1a993806bd5dda4195c5a82353ec080a0f7c36d6285912b8f627c437b18d009a67183870d8ecf0fc73480f4758613008ea06ac686e66613a7dabc54502ab69fc335406d0d6fd2cab9a74b47097c55174d0c", + "0x02f9043c01820c568405f5e1008502ceb580f58303cde6943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad88012dfb0cb5e88000b903c43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000650d422300000000000000000000000000000000000000000000000000000000000000040b080604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000012dfb0cb5e8800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000012dfb0cb5e88000000000000000000000000000000000000000000000b3cc654d78fe95e73ba70600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193300000000000000000000000000000000000000000000000000000000000000600000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193300000000000000000000000017cc6042605381c158d2adab487434bde79aa61c000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000600000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000b3cc654d78fe95e73ba706c080a03d105d8ca3dffbe1f993d1962e60df96904976af7666274e6b72536ed06eabbfa060efdaf5966babcbfcf7355af6356f4563e15e172cfb8e6a27db596c292ecd9b", + "0x02f902fc018203cb8405f5e1008502ceb580f58302c93c943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad880140c7a6f6948c9fb902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000650d423b00000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000140c7a6f6948c9f000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000140c7a6f6948c9f0000000000000000000000000000000000000000000002f1024c33a47334524b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc200271020561172f791f915323241e885b4f7d5187c36e1000000000000000000000000000000000000000000c080a0d46cd893e8374cfd37b258f92d666499174bc4206d6490d7db55517f9954e0aba0256038e0d6f705a1a6f8c155eaf1051fc4736cf90a4e3b128bdd7c55bac9a63f", + "0xf86b028502125f613d825208943e180d55386f7fe1441c0e0d7b1b79b768eef31f871550f7dca700008025a094572925a303a4831e4fef20210cafe26266fb97688ac02e5a9c8a70b4966fd9a01cb943314ccb59045804c15500f57e04e3875228a63cbd548cde6369d66a0793", + "0x02f8b901028405f5e1008502ceb580f58301c9ee94ae0ee0a63a2ce6baeeffe56e7714fb4efe48d419881bc213e3cf2118a8b844e2bbb1580000000000000000000000000000000000000000000000001bc16d674ec8000001ff494ffcedaf5691d5d737fbfd8a8b1fcf6f04dd096799dd59e016537b4a3dc001a0f7039fa4032a12cb3d5a2599e38315f8217b2f8e1cc3ef15ad34881a01f1097ca06244f87e4541f839a97ddd86f285855254969bb0731eb4109476a3c2f8831bf5", + "0x02f8b801018405f5e1008502ceb580f58301c9e294ae0ee0a63a2ce6baeeffe56e7714fb4efe48d41987104843555c18a8b844e2bbb158000000000000000000000000000000000000000000000000000fa1c6d503000004bf4d8c999b4c2df6432edd5d615f6d0929ed7bfc6d082144e74e8d6c917bb2c001a0f282c15d1cd33b9e9e3270d9505545dfffa02362d32c1630337d3916db387affa0605452016445e413a0c534c17cd43808a356d4276a6e5cdd0dec8b1ffc4b3d21", + "0x02f8b801808405f5e1008502ceb580f58301c9e294ae0ee0a63a2ce6baeeffe56e7714fb4efe48d41987242d6ef01a18a8b844e2bbb158000000000000000000000000000000000000000000000000002386f26fc1000001d31527f66aa942b93e2276f98db82099fbe704edca8df182800d771db456f7c080a07b4ee84124626997bc8a9bd2e253a546c69812f2ffd0a8c049b2f56a06c907b6a039fd8216ab2f6ad53dcfb02fcd0031472e3bf17ae3ca23b04205f4dc1e3bd59e", + "0x02f88f01298411e1a3008503936aa551829ab394c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280a42e1a7d4d00000000000000000000000000000000000000000000000000b1a2bc2ec50000c001a0b157dc7a49f31bc8ec7622051e0484c5cb71d2ab262946e816931850d333e86ca055f477aa21b1890fd28451945c843613f5830281079f8d3e1b02afd957b77b59", + "0x02f9013101028405f5e1008502ceb580f58301d7d5940000000000664ceffed39244a8312bd89547080380b8c4b510391f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000416c900627e982831c8a4026c3af1a44415170c2ae9241abf0ecfea9a4c9d62c9a1e3b7ca03456ecab60a53beec75011810bab14580efe9397e52851f138eb1e8a1c00000000000000000000000000000000000000000000000000000000000000c001a049d132b84645a86e88c15f29d92637f8e6b934ed5a0cdacdee6bd734769f3ac5a0079c35ded64a74cbb12a638505dcfe6c4e1b0de90e7b5a975f5b1f19cde64f17", + "0x02f8b101348405f5e1008502ceb580f583021b3a9406450dee7fd2fb8e39061434babcfc05599a6fb880b8441c5603050000000000000000000000006a79acf27a5a7eb7a94ffd34be7540e34b216a7d0000000000000000000000000000000000000000000000000000000000000064c080a0747ff3e0ca333bf7fb2b045888aaa619135e9a7a18f771c2ac62ffc2d793635da048cde2afe81eb019f520cb86a8469a6168bfb9ecdd52c77d4032739e8549a563", + "0x02f8f801018405f5e1008502ceb580f5830183e594d19d4b5d358258f05d7b411e21a1460d11b0876f87adf0b4bc3365c0b8849f3ce55a000000000000000000000000be68ef12a001181f9ac477efec411029cffe1add00000000000000000000000000000000000000000000000000007f2cb64425c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000c080a01882dcc7b988693da16b43e59079f93d4da54eb9b2be5cd71cc6c47e24589d29a018528b1840bea8aa7e24912adee3d7de376eb84df7ec501e1263d64e9a5f929b", + "0x02f9013801108402faf0808501f3cc49d28302acc0941eb73fee2090fb1c20105d5ba887e3c3ba14a17e8701c6bf52634000b8c4fa2b068f000000000000000000000000d2bdd497db05622576b6cb8082fb08de042987ca000000000000000000000000000000000000000000000000000000000485a0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000037ce8f01b71942e0dd12e81ebea73dcd4e1afb70000000000000000000000000000000000000000000000000000000000000000c001a04b9a337c9bcb9ef9a9271817abc644b033613af4d8fb902f01e30e59b2a69aa2a01b0a0fc78a641c27dd48a80401a9c9db6062a28bf2ce417150ce351e1fbae103", + "0x02f90138010e8402faf0808501f3cc49d28302acc0941eb73fee2090fb1c20105d5ba887e3c3ba14a17e8701c6bf52634000b8c4fa2b068f000000000000000000000000d2bdd497db05622576b6cb8082fb08de042987ca000000000000000000000000000000000000000000000000000000000485a0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000bae146ad179cde9b8d6a512687503ef8746b79ce0000000000000000000000000000000000000000000000000000000000000000c080a03abfcfa49081cd0db4e6daf97c9b456eee4ac7fbd3f3dea5dfd991faebef3dbea05a29a607d7b3941e960f011f03e17e1f19a01b2fd06a8c2b1116eec8663765a1", + "0x02f9019a01018402faf0808501f4add4008301f7789432400084c286cf3e17e7b677ea9583e60a000324880ac3347f23902f00b90124eb672419000000000000000000000000d4254e71937d2fc36c8679a911f62b1aeeb320430000000000000000000000000000000000000000000000000ac1e2d16da4e00000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000b54a300000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d4254e71937d2fc36c8679a911f62b1aeeb3204300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a03a6a7e95d52947ed00f9c23543a5a6d782208802b6c9e955aacdf877d2773bc0a00ef75c8398317269241f31e9d4cb6893bedd47052e3a461cc34dc27d9051b02e", + "0x02f8b801018402faf0808501f757435c8301c9ee94ae0ee0a63a2ce6baeeffe56e7714fb4efe48d419871aeee3cbde6088b844e2bbb158000000000000000000000000000000000000000000000000001a4a42c3568000034c3acea1ced1cc9fd27ea3ad5a9388b8061e5eaf70d855baca46f127cc93a3c001a0ceae79abf8494af8bc6c155fd2a462fb617604e5f5cf5bdc8bc9891f6940520fa05832e9d7053f35ee54d76fde5982e2d919c2b7ab4e0e064e3bc389614e6746e5", + "0x02f9013501468405f5e1008502ceb580f5830120b19487df0306f147e752805261156d5a00d912786b1880b8c8f242432a00000000000000000000000046365df48693de2bf9da6e7e13f84b96689a05dd000000000000000000000000098c19790299f2704c4306ae58aa0f4bdf7e8ad00000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000360c6ebec001a06ba992260842c6b6fb79dcf8f09d978276d08f8c1387384eb1524e07544a4ba3a014fff713157d371432127c390119a51383294c4eb4d66f69bd28ebf72a070e73", + "0x02f9049901078405f5e1008502ceb580f5830120329400000000000000adc04c56bf30ac9d3c0aaf14dc80b9042cfd9f1e100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000009e17d5748636fb9440eae5ee5504d4e902013457000000000000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c0000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000650d381c000000000000000000000000000000000000000000000000000000006534c51c0000000000000000000000000000000000000000000000000000000000000000360c6ebe0000000000000000000000000000000000000000c7d1bceb8ab790d90000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000071d1e9741da1e25ffd377be56d133359492b9c3b00000000000000000000000000000000000000000000000000000000000013dc00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0bda27d97a80000000000000000000000000000000000000000000000000000f0bda27d97a8000000000000000000000000009e17d5748636fb9440eae5ee5504d4e90201345700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062c3f3e4c180000000000000000000000000000000000000000000000000000062c3f3e4c18000000000000000000000000000000a26b00c1f0df003000390027140000faa71900000000360c6ebec0809f7c8666d4d7a13d2030362ff414d41c09f15d3d042bb2d1563b1f36765967d7a012cc4e0716be4dbff5ec448f72dfe824c4fab0e87a0aba3407546ff55ac77ee6", + "0x02f8b101118405f5e1008502b07a01c083013e6f94fa11f91aa636ef5b0cb62597a0fc49e859beff2380b844a9059cbb0000000000000000000000001866ae7c471022c5551e999c8dc207a56ce323c6000000000000000000000000000000000000001a8c9d0f39bb51ae0ada000000c001a0115e50b731e69007fddc53aea34099d045788bffbe288eb01168eae9600ab0a2a05e0b7cf1571a9722136576a25420dae3e12e0af46adf1e69ed72db1cba89e44e", + "0x02f8b801808402faf0808501f3cc49d28301c9e294ae0ee0a63a2ce6baeeffe56e7714fb4efe48d419877a25590bd96088b844e2bbb158000000000000000000000000000000000000000000000000007980b80351800005e14eeec8882ecd790083b12c4c2ea86b632e79747b63a6689dcf2d787f3bc9c001a059672fb40dc32347bf98f5bc888af7017211bf329affb2f6dfd8c752ff4d05c1a00f8875985194ac2680a987c64a349821bfe56d71efec0ab97bfa2cefd2614ed3", + "0x02f8b3018201eb8405f5e1008502ceb580f5830132fc94876a76c80b32e5cfbb27fd840a1a530ef828ebec80b844a9059cbb00000000000000000000000093628ac572b92d5561ad19446761394fdad22fc100000000000000000000000000000000000000000000010f0cf064dd59200000c001a0fad9b6f6e14d2cd3d10518ebfddb216209586add598416dd053388826fb7962ba03bbba27f988ef668cbb4dcbbf49b1fa6e140e4bb9c18f851a38b1c8083ee2c03", + "0x02f87301048405f5e1008502ceb580f58301348894ca1de18ab658d8fe3439b538cf361b30c500d02387208d9273d85a4e80c080a0eb96e050cf314770227a4f33a669d2aca841ea3c890c989650720405c7d22469a0342aecc7158b4e077b0ca44530f5dfb0ed66056938617f1dfe39506ead93539e", + "0x02f903d201078402faf0808501f757435c8301bec694d4b80c3d7240325d18e645b49e6535a3bf95cc5880b9036408635a950000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000b58500000000000000000000000077f801db98b34b03d4da3dbb2ed3b61258e62f7800000000000000000000000077f801db98b34b03d4da3dbb2ed3b61258e62f7800000000000000000000000000000000000000000000000000000000013c9a110000000000000000000000000000000000000000000000000000000001144a070000000000000000000000000000000000000000000000000000000064fde17a000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000010e549f3fd0cdeeff94c4a7d5348cb0146fb3cfab2062a0ab9ce95f8b69b14d1aa8e858cad3c5b8de18ddddc3cd7ee5e445c871dd9c2b680daf181172b6d30fe5cd9ead1f5c897a2811eb5a75d91fa0fde64e250ee86399f092c2f28432b169912890589a222e30125f94fe0ecc62ce6a64a55173ce05961f0082ea3cfe540d267f70a5729dbb70cd0e90a619912cf09fb37dc7f05c82e49738dd947c42038ad236ae9f5506526e51bc67795a8622635072ff71d508823ea78de1c905838d633f7649c270d85cf1fa6e686975513d1f7b4c2ead0d07524b39062971e29ccfd059c0fef6a8d93dc135030919d239ebba31bcade5c84a675ae01f8c11eabc66c377ae604865d1b9e763776b41044a8e922f8a20d24dc67169a6c4d24b4c8d2565329dc405b0ea72b2fa26146cfb479acd302fc8e2f49cd2dc7d239eb55f77b5add227604ae62fa7ae8bde0b15be58c0296febfd0bb5a88d8cba7d5b66029eaffabea0000000000000000000000000000000000000000000000000000000000000000f47f4f4df7da36596545f2152e25f53ab42298f7f0654416b1aeeabc340bdc8b0330e9dc43a98d1a70a990f7a3754ede2b7a64de2df85ab95577ecb4fb6d4d990000000000000000000000000000000000000000000000000000000000000000381c1afe39558ac38a213df9c4b61f4bd79ce80fff5dc5ac773715cb19e3b9be0000000000000000000000000000000000000000000000000000000000000000c001a0466af3380fef0d5741fe8484f3940642533fb69968afd47987c1785138550473a023b2a9f07bbdc45b093b362c2f80fab216f086be63a4183768ea12b82a6f1da1", + "0x02f894011a8402faf0808501f3cc49d283028d1794de9d2181451620bac2dbd80f98d8412a6da60fe580a8efef39a1000000000000000000000000000000000000000000000000000000000000000372db8c0bc001a092617c3ccbb9ace9d815cbd079272ac41bd466c696d3aa375d1f3174de56858ea07cc7cc6ddca2b470d4dfa2ac5a58b71fa49d20b60bd39b46f048c041def789fd", + "0x02f8b2018201e48405f5e1008502ceb580f582b4969496610186f3ab8d73ebee1cf950c750f3b1fb79c280b844095ea7b300000000000000000000000021dd761cac8461a68344f40d2f12e172a18a297f00000000000000000000000000000000000000000001041cccd61fd4fc220000c001a0314ab6d563bd638aee7fa43d1bc4d4ee2417fa5bcd8e2b181eb0b2a386bc3b7ba03112a43fec744b462831c7409f9b5610faf083ba5a418cd843177eda3e6b7736", + "0x02f8b30182065f8405e69ec08502b82ea800830110b9947e52eb9fadb02f95de1eb8634dc0b4bbd4628f3880b844095ea7b300000000000000000000000000000047bb99ea4d791bb749d970de71ee0b1a34ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0edbffb0a196cd02dacc675918736f76d8f4b78d3e2b5b82f57b21852324779e5a01f3166b6dbfca7a56c40e5558f102b42a61be892045b997f218f30c440ff2b22", + "0x02f901160182029b8405f5e1008502ceb580f582ec4e94f4b84cbeeda78c960eda07da4ae8828594ea515380b8a8b88d4fde0000000000000000000000002725bc53a2f792d4fff5397092ad631f51700aaa0000000000000000000000005a98db5d98a9716ec48012c364d42768d7b1e243000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000360c6ebec001a061e295684da6c6c058934d827e9cff65d34356ccb63a4015076680b404c871d0a0169facd30968f911a233caff684db10bdf371264a0b51eaf93d590f91705c3ce", + "0x02f9035b010484010fabe385023c3b4746830479a294881d40237659c251811cec9c364ef91dc08d300c872386f26fc10000b902e65f57552900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d69630000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000023375dc15608000000000000000000000000000000000000000000000000000000000000eb7d1f000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000004f94ae6af800000000000000000000000000f326e4de8f66a0bdc0970b79e0924e33c79f1915000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80502b1c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023375dc15608000000000000000000000000000000000000000000000000000000000000eb7d1f0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000003b6d034006da0fd433c1a5d7a4faa01111c044910a184553ab4991fe00000000000000000000000000000000000000000000000000e0c080a03e307cbdd556823f6c1e62e32b4968deb6fdd1d572cbee7eac07411ede411e3da05fa59938d2dc7ae668f83e6f16ba330661687d6113efaf0f81b5472f7b5cf17d", + "0x02f88f01088405f5e1008502ceb580f5828caf94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280a42e1a7d4d000000000000000000000000000000000000000000000000000c6f3b40b6c000c080a0e34071b9b7a00001e33dc9ece3c868e1eefb21c2b0d210cc7b0f4670dc622acda05e3e16c226c7fc252dcd4d1d6112211d930e99aa04beb82413912069249f8dea", + "0x02f8b701058405f5e1008502ceb580f582701694b584d4be1a5470ca1a8778e9b86c81e1652045998727147114878000b844e56461ad000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000db4af0457279effffa5a4be6e3b941ea240d8f9dc080a0d752b19bfbb31c0cadc48022d4a9d1426fd17e849c1ca4b3a87c4e6188185fc7a07b5a012d8fb7b37e79bc7c0633a87110eef72166c9f7dca71b358f111b9c3c54", + "0x02f902fd0182026e83bebc2285020835c4b68305221094881d40237659c251811cec9c364ef91dc08d300c8810a741a462780000b902865f5755290000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010a741a46278000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001c616972737761704c696768743446656544796e616d696346697865640000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000018ab2786a7200000000000000000000000000000000000000000000000000000000650d3bc700000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000070e75c990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108794965da6c000000000000000000000000000000000000000000000000000000000000000001cf085811d0d1a14f1b4da598717dfe9f697e8d756b8f2386172102f3b32cf95fb13679fb740c53e2110ae831a5c9668246d7fe3d7483afd30c671d24f30fc0e94000000000000000000000000000000000000000000000000001fad0e04d14000000000000000000000000000f326e4de8f66a0bdc0970b79e0924e33c79f1915000000000000000000000000000000000000000000000000000000000000000000afc080a0af47adc6df9c8da3b40abfd6a9fd576f52f30c320f92f4717327adef91df066ca02276054e598f1998d4d8836c93f5956b6147fca6a3d437a04e88d2210c54c6b3", + "0x02f872013c8405f5e1008502ceb580f58252089437adf7b1a95a3309fbc58f80320d32a5b72caca287a327cb389b310080c080a0562adda6d257d3c47a4d34f4f94eae088e0e0ba833507f7741d4d45c0fdacc19a0389bcf9af90f8620c3f55fec3ef29ce5b08e576f842db64a390c1fc58e434e94", + "0x02f87201128405f5e1008502ceb580f58252089423392d66721cf9e8c23e346139e81ccad62b92e2878e1bc9bf04000080c001a002312d85c66cf17b6294db8c74b55534c187740323c440dafb5c744d7cdb3f76a048018cf5276bc2caaa3bc1d60d14a9ee998959a7581063e41685599e81ec8d74", + "0x02f8b701038402faf0808501fc8c382a82701694b584d4be1a5470ca1a8778e9b86c81e165204599870221b262dd8000b844e56461ad0000000000000000000000000000000000000000000000000000000000000089000000000000000000000000445fbcdfef289f7912d28825edc7bfb74f419e5dc001a089b4cf16fab2259337030947f546ac39c34242638c6226ead7037fb8ba943eeea03e0682ba6675e121fcf5760f3458a65cf57b44f1bb12a11520f2f1e29b7d3cd8", + "0x02f872010c8402faf0808501f3cc49d2825208943780f6ca38dec5a83edfb8826486fb1ec9b182918708e1bc9bf0400080c080a019ebd7842667fa13d5443dd4fc0eb5a550d295b2f016640c48069720c4cca5b7a06613cbf7bac311b61db3237875b8d09e8b3a779d9544ab6895c90e71e0d0d3ab", + "0xf8ee048501f19233e28301c9b69400005ea00ac477b1030ce78506496e8c2de24bf580b888161ac21f000000000000000000000000a460051def6ec25bded4164722fbe6230fbdcaa90000000000000000000000000000a26b00c1f0df003000390027140000faa719000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050021fb3f25a036f34b67e18b41aa1fb43ab94867a892a0a9fd400fd7f1aa52b227cd47065d02a053b3f27507e7a9523e54bb4070fd8ec31908812d0e475990a1823b93761b8e19", + "0x02f8790182013184010fabe385023c3b474682afee94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2881d012bed3c91000084d0e30db0c001a0298573a2670e93f4cab424e66e4d8be46a5fcc160dcb7f472952b441307b9468a07414351600bf1f3c367431c79caa7b3d69f8623b572ba8afb0c5d648e4ad9671", + "0x02f86f01020185028954caba82c18594c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28428e3878084d0e30db0c080a02583325121bc262f83f83839c5faa0b1172605d971746e342705572400b449aca0589fcbba5567bcadc1050bb24e0ee22bfef7ad803f66e6bcce646ce72dca46b0", + "0x02f8b1012284851ca9a08502d044dd02830131249472bab498fa50a33a03362d0024bb27efbc50a7b780b844a9059cbb000000000000000000000000ef811bbb9b8a2ce8f598ba04329b6db8b36d95be000000000000000000000000000000000000000000084595161401484a000000c080a0898e328e73116724d0d0e3ad2f0dc95401cb5c7c3abad90e770f634c0b28ae71a00e563a05814bca0570ca44e1cf26a06d08ab6695a28ee0c75b1f566aba4627fc", + "0x02f8910181838405f5e1008502ceb580f583011cf594fc8f838d593bce8da977c83bdae3a6df00db9ca280a4074306c2000000000000000000000000a848a1d33d8ef1633397a6acf617620fab8e5da8c080a0bb7d0b5d028076fc5b0ce6accc9cc24486cb31afb30a444b590f0b9de9e4a419a01a473551dd6f6d3c93fa9da2214dbef2b343bf09198446fe637173b2ac6aa40e", + "0x02f9015a01648506fc23ac008509e5bc4ec683043206947a250d5630b4cf539739df2c5dacb4c659f2488d8803782dace9d90000b8e4b6f9de9500000000000000000000000000000000000000000bad97982994a61d7d504b94000000000000000000000000000000000000000000000000000000000000008000000000000000000000000014c0c7031e0fcbdd0db81c32a90b29ee5c41d1d200000000000000000000000000000000000000000000000000000000650d3bc10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c6980fa29a42e44852e29492268d9285d89c9dacc001a0abefec6763bba15dcf373f8ef4d68be877afeda8afafdf93d9665659fe34cc91a03556acdf4c8c6fd7cd4c54308aa7d59b55f33e9d6b63f88b537b4b57238d6cf7", + "0xf86c0a8502710caab782ea6094897b425dab19eb886dc6ae2010fe2a0de85308fa8802ee03111e5f95608025a03997154468e725f5c74e3482479eaab55706fadbd77c11a52d952b538ead2fdca03cb969906b9a7bbad27798e074eb5d9b9a1143de8a327fb8925bd2c8ee0f0116", + "0x02f901980101839896808503b9aca000830202059432400084c286cf3e17e7b677ea9583e60a000324879fcbb8fc976611b90124eb67241900000000000000000000000000037fae997dc49e357f6d717f397b14241472b9000000000000000000000000000000000000000000000000009e04f9aa34261100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000b71b00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000037fae997dc49e357f6d717f397b14241472b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0040420abee74512bb5355caad3f177779c5556dd3d276b92c88191f65fbe1178a04fe64531b6e0216ba29edc217489bbce8298ea71ee4eb8b4b0a64245a0e100fb", + "0xf901538204fe850251cc0894830f4240947a250d5630b4cf539739df2c5dacb4c659f2488d879fdf42f6e48000b8e4b6f9de95000000000000000000000000000000000000000000000000005340a142a486a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000009e1b2e13d5adadd4f18a84396ba3825e9f8665770000000000000000000000000000000000000000000000000000018abbaf99d70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000011a15d6ba4c27c89e468e959ba2230337317184c25a08e6c0aac59fc29108246cf7b05b3a133fc6f87d2a84e757f4cb257d2037ed369a05afd77fe4804d67098e13d1abb9bc0585d54dbfbaf2c4c4c9846e55fb65ff6ff", + "0x02f8700182ecb8808501f1106c848252089413f2241aa64bb6da2b74553fa9e12b713b74f33487d17a925100884f80c001a0f60e642a491338ca56b7975712bb0ef2c3fdaf3631f53bd16f17704002b92688a0593d2ec21ecd01a46982ffa35732a7ac04a1eeabfb0b8366f23274160d68f020" + ], + "withdrawals": [ + { + "index": "18476769", + "validator_index": "711858", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16008754" + }, + { + "index": "18476770", + "validator_index": "711859", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "15964023" + }, + { + "index": "18476771", + "validator_index": "711860", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "55978346" + }, + { + "index": "18476772", + "validator_index": "711861", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16018825" + }, + { + "index": "18476773", + "validator_index": "711862", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "55701351" + }, + { + "index": "18476774", + "validator_index": "711863", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16048658" + }, + { + "index": "18476775", + "validator_index": "711864", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16109594" + }, + { + "index": "18476776", + "validator_index": "711865", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "55192849" + }, + { + "index": "18476777", + "validator_index": "711866", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16034174" + }, + { + "index": "18476778", + "validator_index": "711867", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "15996922" + }, + { + "index": "18476779", + "validator_index": "711868", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "15988508" + }, + { + "index": "18476780", + "validator_index": "711869", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "15991175" + }, + { + "index": "18476781", + "validator_index": "711870", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16040454" + }, + { + "index": "18476782", + "validator_index": "711871", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "54619862" + }, + { + "index": "18476783", + "validator_index": "711872", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16119355" + }, + { + "index": "18476784", + "validator_index": "711873", + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "16122912" + } + ] + }, + "bls_to_execution_changes": [] + } +} diff --git a/beacon/types/testdata/block_deneb.json b/beacon/types/testdata/block_deneb.json new file mode 100644 index 0000000000..6dedcfc343 --- /dev/null +++ b/beacon/types/testdata/block_deneb.json @@ -0,0 +1,2644 @@ +{ + "slot": "8631513", + "proposer_index": "1124880", + "parent_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "state_root": "0x855b6335a3b955443fb14111738881680817a2de050a1e2534904ce2ddd8e5e0", + "body": { + "randao_reveal": "0x8c290463d6e68154d171deeca3a4d8d8fa276c72e9c34094f8b6bf89e551e99d63162e362a936b628af4840d69b10c24191e892d0a282bb5358a5669f44e42b627ebeb63fd6467c7aad62636a348b5f4edfb8ce01650e4d079339d9dc5700f05", + "eth1_data": { + "deposit_root": "0x636ab1747c976fe08cf337b437ccbb5f543e0d0c6b5d70097c3ab7737c1748d5", + "deposit_count": "1342638", + "block_hash": "0x429813f0390a9e104740e8a24ebb83ac03929dff4a9702385f2bf24391ba754b" + }, + "graffiti": "0x526f636b617761795820496e6672610000000000000000000000000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "19", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x903146f136e4df8200be0229eb96bc9a2409d04763df61ebba51f54cfbd9eca2c88274cb94828c2705bff1454c50322e03372883c2dd47ee329cd17a3653f44314fa8693c73fa2097f622e7f2e163f7b7cb688aebad93e14c273d406743ec7ad" + }, + { + "aggregation_bits": "0xffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "27", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x99d3c97b5036025d1b30ac32efd469a815269e2575a7525b1cc8323db85556aef7af7464d965ab9b6ee1804005436a0b05faf870cb213dff04552ddffcfe355987d35201e58dce3897c0de27a19016321fba9ac346452755ae9340f60cea895d" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "44", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb2f0775dd77d2969cc57c0d03ccdf0c79e9f4d34150a539f79d9f090cdf918a4092f1170008aca3c5c7d6ddc743f79d317f8300dd58ce040ac7a9e50940b3bae964426a7883d143012e504091bb669510d5901f11d008b8b630d8c42ade6863a" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "22", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8fa4c08ee7406d44034e6925dc65e1ed9b08d9fa32260f0e49d7477b5ba9762c413d7385692c498a57217eefc4f11b4b0c6a470df5f1c1e98f890975424af15a6925e657628e518fbfd80db38553790e8ae5dc6704de1cb727011ee084bc1af5" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "35", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x81ec8b97197bc59634b30a2356035f664a648f6aec4d30c7f357ad33d39f28205596683defcddf1ba6fcf1f3fced1a470b8a78ea360d7f1f1db4e2e5d6f98045071e5fe04338865d986c6b8f4aeff0d01ce19952d9a7084ee21da0d557b17f38" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f7f", + "data": { + "slot": "8631512", + "index": "63", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x950881fcc3a1d4d88feef09eb6cf4e72bdc68b76754ce5d496b2f1232b9ea9851e453e45eeb8e23524acbc756cc7b9f614ecd1e34aef281487d72e73078e0116ac30a846f2b085aacae17a5066aa6eb383579e35ed70508127f19e8caff78ce1" + }, + { + "aggregation_bits": "0xffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "58", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x940c731c48b8ff0d522fb38f301228f47272b89b5bd1f1ecf44d79bf762616baf05be5ad0f389a9524de812646ea5a50096ed04747bf642f8d8a75b60015d5c690414ee4d87b19d8fcc111b1cbd594aa78d939205fc5ed28e78b82afdec0f92c" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77", + "data": { + "slot": "8631512", + "index": "53", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8c528252b23858ec845a50f6fd0d001639c8dcc8c665cf10bc52c2076ef0b97711ca1348bdfceebefc45ea9065376da90217d1ec09ae4409683b6d461c80458f3f9bc0308e5337ebd856bd8217a8b530aa56f0b8804cc181b636b990e88853c7" + }, + { + "aggregation_bits": "0xfffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "3", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x95b64b1648464197415f13f02601e0100318af579c8774fc4192124dc2ed181496c09304a7f3a342541b3da1a82affe9199d3f4ef40285dee2dc082d6783cd84e5df15ee29c0a4436eabdeebe236a2973b9eae91ef9c929406e14de1ad78a7e4" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "2", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb40357603fb9b486e6c37d0152e52a76dd5e385f63bac25816bc210bad5501071474745ba808e1767b95c5a7202eabc512010e470d351ed49089de3e0f602ef3d6a4cab8603ac27217cb26d523517d340bc784270191573b18c5c7f4f68e70b2" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffeffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "9", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x866b139ee2b3d7771212031592f284836624427883ea7d9f9e247eb507c18a1044bdd71a27121fdde10a0898ba536d4400a9af47a470f61fb7367f038db35e1dcc4f9567a6251e9c01f1cc43624829811485eff6e64f5052f2f1632d6beb3728" + }, + { + "aggregation_bits": "0xffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "16", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb0742e0f82acb1366a6a1887388a80461c077e705fd1a5776491e80b34bb2c60f1626e2f4fafe3f0361da79731d465f40667b2abbd2abfda557a845eae6bd414593a4bcc9a82f3cc1a4a0fbc86bf5255caa794cfbcee4c87619b44ee5be8e713" + }, + { + "aggregation_bits": "0xffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "24", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa606e4d20408f30f4552e3e1d62f6964140d2dc4a297f2c300ecaa35594e658a55801d427c8166a1033bb8d46daeeb371779c4c1c89cbadd019411177ad63b22d42f083e0882c73df093523bb2184f5bcfec544366c3180a3c6d5d4e4715bf01" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "20", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x886d4565a820a4cf546207ea013939830add03e5147ae9bd6257ef886dae1119edc6e3677edee1937c433f33646264440d7c06c91642cff4f8f875fbc706d590bf51105ab8e7c3ee7779ec9fa40058935ae30227c338608f05650df94157422c" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "32", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb2ec56e1cafb774c4f3e86447b9e69c997699d4a611846f582ba6d60886aff12cfb87442cc650996cbe30f35e0c7c15f034037762103bae2a8b8461ed21a6e6000a3f1afec40eeee45ed82243400086d3e6527d9cd00954d661392d492ca93be" + }, + { + "aggregation_bits": "0xfffffffffffffffffefffffffffffdfffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "13", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x872a82d58281f34caf12e34046ffd1a137415090ac37b84e797e1f9800b2ca339d5d6fbfab056662bfdbe201634b2c5c0f3001a22e181ff38ec6841b804a3aa214ee0ae863de8db9ded627280e05784f0c715dc6256df492aacc5185dd602369" + }, + { + "aggregation_bits": "0xff7ffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "34", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa491e4ee4f0dff0b0282b4fa3dd6e6a5efad861a33f1ecddd2eb9cbbdf663a88a19de6643276ba341739b9a0d6fed65a09b33d499e947d2836bac1c098a012d9096d4bc95eb86953dd6ea425b973418de05fbe3e439835bae81d61db3c85e098" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffe3f", + "data": { + "slot": "8631512", + "index": "15", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8663ea9804a9a07f32291db4018a20024b06b5e45fa55de6a9a9d6db7f75f2af1e71af643eb6bc56f15da20ba74af1d80e6d0d459c69e2971d71a72d83a3807f269898669e850fdf49dbae277dfe3e48dfb5b34436c9476e137a34f2f56a97b4" + }, + { + "aggregation_bits": "0xffffffffffffffffbffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "8", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa9d69c457435763e8afd1e2c26b2b39e063e951ecdeefc1a3dcca848d75c617aaf25c5f79f2185f64a54c13d7883ee1315b18d1510b35e194b0502cd1e56ea470cb9eebb5592601cee169e4b65c79ad34efa1080e55523cf08060550f092db62" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffbffffffffffffffffffffffffdffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "21", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa42469725f212b6319a9113eb681dbbef08297b4fc458e16c8b157a77c426136c1215d3e885753ee5270f0e6dd53e58717800baa56e74a50d59c975a6e6838ec3d4e7e7df71a3ea02d490dcf496b96a16ced37467e746308b39f7ba11c3d417e" + }, + { + "aggregation_bits": "0xfffffffffffffffffffbfffffffffffffffffffffffffffffffdffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "40", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x918ae9885a56fe78cdb92a710af61738bad108f08f63ced0e12419930dfee4191c91bf7b32c8189a206f73fa497ef88308320d4fa1e1437e45946ab8f372e292e0edd897696a6a93b7ea2f6b6f97e9d2e2c10b400a70591b1cb482f7f15e383c" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff3f", + "data": { + "slot": "8631512", + "index": "51", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb0ce301a6e464261782af4300275f915fd1e9bc33dd3c1d8d79476e9d3fd2098fc1b4d967c9773864afcf7de12e579260b0cf8a7048a03c4b8b2715e5b8dd7587fbf5e570e4b77e31fe92fcec7db52ef909106122a9ee1ac56c856a9022fd54e" + }, + { + "aggregation_bits": "0xfffffffffffffffffffeffffffffffffffdffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "11", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x99767e9d12d961d8c2845c230a6a56b753e8c9eb9d228a178d8aefb93a96c320d87ba648199db301af51ce55628cf1a70f5df1a5c150130ba81113544bb3cf361a8be881590a7fc123cc82023ea5e4ea115e59a1c765ef8f926f199a27ee4d6e" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffefffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefff7f", + "data": { + "slot": "8631512", + "index": "52", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8452d2819e0e02ed4bf803a31d9a0f2b2b2b249d4944f4729e3d8538a1dd16231061706bc82d56b0f3365b867dd3d2840bf813e116efaef44a8dc81ed37c4662503931f479e1ee33095195726ddd06f843ce4f1be58009a9209528650a8ec40f" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffbffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "1", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaef55f46a3fe443eca0644769a0e1ee3805c60feff89335493789c8814223fccc863cd42250a64ef7e6e026ab8171ec315eff1f2a6d080ffc288e266aac71c41622c714578c10942bff43c11e283c41bff28fa29e691f71f19e1f994d7d35045" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffbffffffff3f", + "data": { + "slot": "8631512", + "index": "59", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa3503124a73c7e04e7a4912364f445b6dac529c9058d7633fafddcc837bd23464d26cf2f65d5f368b9707d3b4bfe13501028d3543f1f0b50fb5069ca377b7ba0e0cf54734f581e5fc19ffd6eb67481f0895781dcf677977986b79f106d2eeaac" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffff7fffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "18", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa47b9fa745d4120436e297fefcd31c16169be9d4f20f55589c0d4e5cd4d84c8d3b88bb0a94778ce44dad47dd9f79e2b90ae0956a1530105f450ae10ac229c2de887fbcad2b7ae339f3bc1a8ae505bda878bf5b9e021229d797345a483dd04239" + }, + { + "aggregation_bits": "0xfffffffffffffffdffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffbffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "55", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x979245abb880bccc2c3f67a31e913def8e090cc821aa3be3744f1c503316421cdf1711d6287a6789b5c48d92bf424e1b0c7dc776ad5f9c559f59d4ef98d495d25321ac2c8f33ff943c442662c691bf348494480757e3867a1d20f07e21eafc4b" + }, + { + "aggregation_bits": "0xffffffffffffffffffbfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "54", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa3cec14a422ae48d91b03da27937ac6acd1e258dbc6e33133307fa1077da8bee97608a0a806400b819fb46d06f23417f0c8e5541ecc438e783ce27cd202bd0d69ab92092df7b8bd372b2a18f4ea30ef39883c769a9eb2c2bca520dc44c0e6eb7" + }, + { + "aggregation_bits": "0xffffffffffbfffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffff7ffbffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "49", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb356179743682d9df75eed9cb2398b3a7d91df8bcdc1abba65aff74b61c31bd91935893ed6223d5d61b1b7f5f3e5f819068ca705c824fa9860faf19022208b24fa3d9cc38e304da3722308dfab3535cc4460ed416513e52e87ac56c3d217b3fc" + }, + { + "aggregation_bits": "0xfffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffeff7fffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "50", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa20edf17e5b0f1fa35a3e4327432db00c1957e5ea6eaea5798c442b3de5b01686f8b82901ebda7860428e554afda95760e729d9d917f36f74ce1094fde666665b7f5b4b11e71e80566da43e0e597a0b3e23bd5a8d57e380885622822aa0a14df" + }, + { + "aggregation_bits": "0xfbfffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffdffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "4", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xad119153e2744c66c9b8066d694e49db4ec0ffb8a2bb984db630bc00c7a6e6ebb343b7a6f7e1ac1f40762bfbccdcbbca09ed57f768a2baa18073e3c144d79bb19c7f1ada89cd44297d51aa9a399963ca99bf5c91c653bcc2502d575df557c732" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffffdfffffffffefffffffffff7f", + "data": { + "slot": "8631512", + "index": "26", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb9a04ea00e249207cfafe9693d77e87cdfa34512db9781dd32a7fb80dcf5f4334f848574966d56a6447e54031e0eab2a08b75f915698d2cdf5266ee292a57bf265135887303998fd99fa2b654117667649e0ae74db015ec954c9ad18988c92d0" + }, + { + "aggregation_bits": "0xfefffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "28", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x88133f0ab0d7cdff20b844feb4275ae15b832c91e46afae8704e18539da6596fdd8a37f95559172b1afdfd40b340a23a180900e7fc2679e1b257206e879db706e0c9d393ccbcbbd1793c24834862f6d9fa3d9614118b27def456148fb2cc6217" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffbfffffffffffffffffffffffffffffffffffffbfffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "7", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8c379743152b7330835e9a740a0b102a762225c2e5108faf02df7ff9e6438018f5331c3ab5e8b1424388f226250e622c145580ff9f972a66767bce5d9d74e34fd809c12cf404940f3eff0596cf4a2187cbc0b614a9f25a9f5111fe54685e5ea2" + }, + { + "aggregation_bits": "0xfeffffffffffffffffffffffffffffdfffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffff7f", + "data": { + "slot": "8631512", + "index": "29", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xadd685e2acc665e03c10eec1777b1470650b41c931fd3856cfffd2413709db3e77a163da695f2e79a06e447f8331ca5f12c8f8737e26fe56c2ff203e884e0cc7fb36c53e1e7e517a9c2628805d583c1e14963077abf03a5dce22145b50ac1b37" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffdfffffefffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "25", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x994f6497b6671372784ee8ad0876f147dc724d0074b8799925f4f21d318d1e2b8c78ff571a234d32da916dc94dae967b194073192ffca59c5bcc767b5455472edfaf46e7bd4afaf143f9ee562e4fda8ea187d809e2e68b803918d266223cb938" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffdffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "23", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8efd6e9c8c41beebbab07a4952739123a554b16d527ae4e15982d339fe50388b6169d617c83e11a29230e7ef464e31880bd21ce4f9154faf101bc6233ed09d4ca8f51ec143c437428f47f64cc0b104754f3c19292a2bea3bc4d292bcd5a9da1c" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffdfffffffff7ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f", + "data": { + "slot": "8631512", + "index": "37", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa8b0c046f9cff0a03e328c384b96df4ef7408276ebb2731f3ca95d12239db218f4feb4669a053b307d991d77ba4692530d6b4f27292e79d51b458cc13b109e15d63504a4cc16ecaa15f4e396a3860bb5f5977a8c8da37a786beb88a48187363e" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffbfffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "10", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x87651e4014f8c00148f196776463092f1574eb24816cae2b681ebf944f74957757b5e90550a73b2d1cbc3aa9f9a9b0ca05966502ba0a1d23182fe2a99c86e35e1116069ce4c61aa5e8548a7a42ca1465c30f9c3b3e0689d2ef87dfebfa78f2fc" + }, + { + "aggregation_bits": "0xfffffffffffffdffffffffffffffffbfffffffffffffffffffffffffff7ffffdffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "17", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x801a1d09004c0fc95ed510b9deb1a98c4abd88e91c46179ff5a7f17bfa1f2db48a0b42c3110cddc71ec0097185d6cd7407e36483cdb36745a6a0a23d3fad3123c0ffa5008f26c9a75b8bdabd2753fe9dbbf08d292d79a73a2736d533aa9fcad2" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffbfffffeffffffeffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "46", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb564bc7299fa09ae6d355ad187719ee147965f3cedfacc0a0f2b2b627c06e0535067b4548d810d9f609e5d55369e9b870dce515bb482202f324c93d8ba100f1893073ac010399918d642294f08b3dca311f56be91395a6bd4b5c43666aff123a" + }, + { + "aggregation_bits": "0xffffffffffefffffffffff7ffffffffffffffffffffffffffdffffffffdffffffffffffffffffffffffffffffeffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "6", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x910fb8a623531872777c69cd9098b4599840000067fe94eebb61a5aad67520718e3c5d1b0e674ba334e501d5414443e3132ffc00a8bc087d1c7c24c1110d2ab3eae5eb52fdc1542d2e85973eb94193735ce397bd55db2adaba1c1c5d80dd9ef1" + }, + { + "aggregation_bits": "0xffffffffffffffffffff7dfffffffffffffff7fffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffff7f", + "data": { + "slot": "8631512", + "index": "39", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa74a52e52313fa31a6d69f139de567134459d9eeec28eefbe5d0f05bbba2c755a3d854d058ccf2ebfc45e45209d381681964e6a419bfdfc8921f366bad44759fbe7c768cb55bc5353600b8b51f08b6f5f7448f42bde2de52466255a1a255145f" + }, + { + "aggregation_bits": "0xffffff7ffffffffffffffffffffffffffffffffffffffbffffffffefffffffd7ffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "62", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xab1adcc9c42316e0dd3d02d056c6dba3baff880f217cb256f88262fb265d813c0704fbf08e2e60e1af25618bfd637d3918161bf3750803103fb91df250c281126fa3119ea020ff56ccee61cf4b210ec8227cb90390be77258037f46c15d5e6d2" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffeffffffffffffffbfffffffffffffffffffffffbffffffffff7ffffffffffffffffffffffffffffffffffffffbffff7f", + "data": { + "slot": "8631512", + "index": "47", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x84180e4ced9a7260462715bfa0a474693bc6e56ae4d4595d72abd6b2fc16afc775bdafbc4690e30f5495be40dbd5442609848e264ca48e7bcd6895ce3340b57521a266c3481f01792f1e7cb7215105345f6d05d192969b07520f02f1f61d04bc" + }, + { + "aggregation_bits": "0xffffffffffffffffff7fffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffdfffffffffffff3f", + "data": { + "slot": "8631512", + "index": "12", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x901c3f60fbc25644d817e3964f29cb3c5a090cb7c9c843a23b39a1211635ebf4d0a7599ec511b5a637e60a05d6b809600bf096a151434ef9e35645ebbf943b442cecb3745d2a91dcaea4cd71e93e334827c558a78f7ea9101db95deb5773fe13" + }, + { + "aggregation_bits": "0xfffffeffffffffffffffff7fffffdffffffffffffbfffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "45", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8303e3e0aa2ffe77dd162a3660c8916a964aefee66152f27be11da6ae97e3704573b5a7c9282a5e5a9f7fe340621629e03ff9a4988b286a895e2568314f151ad250518d356b2ed33d6017b9405c2b341213d7654fdc4924b9d789f3568f860f7" + }, + { + "aggregation_bits": "0xbfffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffbffefffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "38", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb9697d52d9483c8770a73a7b28cc6f4fe2fbd9e269181483445582a18b0e580f8ef1680ed68506ac52e4bcf5285a1ae108f97d2baa542d39b1efca6f509c1344cca433af5ccefebe31d1765b5e697db7fc40a917f995982e6d71c17c074f265a" + }, + { + "aggregation_bits": "0xffffffffffffbfffffffdfffffffffffffbffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "14", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x873a15e74e683d9a128b822ed8c73a592a6abdf5b6b67d0391614cb2772f4b6ccff445895ea34f754e7436986fa3539d0875cb6db0210480f118bffde9cf04504990a57e040384ba5fbfb921525a1fab7b2eda325df5d49a99208578f175433b" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffb7fffffffffffffffffffffffffdfffffffffffdfffffffffffffffbfffffffffffffffffffffffffffffffffffffff7f7f", + "data": { + "slot": "8631512", + "index": "60", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x98e3833f9dd9f4a50342789ed1cd462072d0e3e04e734d352c8366bfeea49a0e94def4c54461a5c603ce53ba1efa07c60ec81de0625f0b770f858b90b5d8762b3111c26357b026384b2f1d66676500d5090f7f9b781882bc949a722f8a2bdd0f" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffefffffffffffffffffeffffff7fffeffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "48", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8af584ee4533db14726f67b0045ce97a185fed5c60cf3a1a5092a7335fb7fd804399362373613d9032fdff3d6993f0b8024d46db51119fcfa9d631657075c1c7a2d86551df69034d821a8b2a587374b4c827c9031ba2274d772ab3cb35360cc5" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffbfffffffffffffffffffffffbfffb7ffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "43", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x909dbbd5a35c63d3584bdc244753df1afad73d36e322f4781d8f729bf859b3c059aeaaa496b1eac32aadb21a0718de5114517884dc2333373b20fbd38f6a44c5a1e4783c4cbcde6f47fb2bf88ad1e5cafcf83ed6a21da26c25b67cc7db90fb96" + }, + { + "aggregation_bits": "0xfffff7ffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffff6ffffffffffff7ffffffffffffffffffffffffffbfffffffff7f", + "data": { + "slot": "8631512", + "index": "31", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8addf5882ae131192defac2c0fd0fb2823b175ef9c3935eac43fa6ac2ce0799320cc7ddf5198cac4fca3194bb6c350c50d5bd7961585da8aee3947fd70bcf35850afa2422335a9dabe1ea355ef8656621151a64c454a2f151b218f865d3208d9" + }, + { + "aggregation_bits": "0xfffffffefffffffffffffffffffffffffbffffffffffffffffff7dffffffffffffffffffffbfffffffffffffffdfffffffffffffffffffffffffff7f", + "data": { + "slot": "8631512", + "index": "57", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x934c856940d84c4f14a733bee6274d9cc2169f204ea0b6ffe56ac508a6415bf35205fd375345e77d8a5f2300efe4ded2132d832b056ea87652113e53a5b9b0f4e9c2d5fe12d71c7c469dc249a58d5d0ff6b3ec1a38f7b2357193dcbf77e08667" + }, + { + "aggregation_bits": "0xfffffffffffffffeffffffffdfffffffffff7ffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffdffff3f", + "data": { + "slot": "8631512", + "index": "33", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xadbd39160d68eade93f8c1c347d5f279f5da8ed5dcd1707f6c4baae397c522351a13a3fdd88dea0669767d87937d771b055be2e0788d1b71bd94e37d453418c5f14fd633ce1cab4948b4f0a7ee8389d44af96023550add95e53166387e8a5651" + }, + { + "aggregation_bits": "0xfff7fffffffffffffffefffffffffffffffffffffffffddffffffffffffffffffffffffffffffffffffffffffffffffffffffbffff7fffffffffff3f", + "data": { + "slot": "8631512", + "index": "36", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaaa9a9ad6e62fb6d72fff1f8adbfbff847c7daed439f2d61f427eafdf9e635bfd737b8c50b22f5254e7aeeaffe0aca4207e0cc9789ff8673222c94fcb00d565dacd1b4d7174d1d8d46a94afee1823a9e253ba34512416f5b4b9e6ab0ec7a4603" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffefffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffeefffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "5", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8796bf82191746e96ed7a4815b529d58b89637a73a257f91a37e5efb24f45928d73874e070baeede5dc307192a66adb61622a9e1cee830a42f9dba769b5f2faacb1ee48b45c4b3ef36b250d507b1e1d98da615f2e449f4e31f2399ea967e597d" + }, + { + "aggregation_bits": "0xefffbefffffffffffffffffffffffffffffffffeffffffffffffffff7fffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "56", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa8e03e06c2cb4c547a999470566efb71762b3a1c6799dcaa88a87fbcac801ebc6b8e6c6a3356240751a002050d96c7e805d8ee44b371694bf134b14a73f66c98a3d4635d7de9c87d66d8129d2b2baf6555f3dc89587e9ed8170a67430d967dc7" + }, + { + "aggregation_bits": "0xffffffffdffffffffffffffffffffffffffffffffffffffffe7fbffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffb3f", + "data": { + "slot": "8631512", + "index": "30", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb123ca42495b24ba8dde57f7de4076a3f16862e9bf6e4553d4362a6f7a79734ed4e42e11e61645436751c96ea4232395061a0f14a6b581f07f690256d87c266f73f6b1184ad38beeb32fe07839b2ea7d3d4a0fcc90642896d92ff4004c1b5dce" + }, + { + "aggregation_bits": "0xffffffffffffffffffffffffffeffffffffffffffffffffffffdfffdff7fffffffffffffffffffbfffffffffffffff7fffffffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "61", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8de31ecbc01fd8fb43d4aacfcc2a03b6e936931dae2c5e183d76ec80d2529344167fc2b2c9418ecb55c6aa28bed977660be65b96f3af37a5da57f8555cc6c4eda2048c86f49035ec627d52b4bf8df4661a750528eedfd68e50917d70bdd2d32a" + }, + { + "aggregation_bits": "0xfffffdffeffffffffffffffffff7fffff7fffffffffffffffffffffffffffffffffffffffffffffeffffffefffffffffffbfffffffffffffffffff3f", + "data": { + "slot": "8631512", + "index": "0", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb74ed75a3bfe483a2481cc43e8cb7b3cc8d5f24d8d9e94857a507a1dabe821551012ebde3164a8d6696cf5e27e424626036eb52dcc1c306e656c776994805865c14b9e8b68e387095d76da3ba18522a5616fbe3434874b5bf2aa655996191799" + }, + { + "aggregation_bits": "0xfffffffffffffffffdffffffffffffffffffffffffffbfffffffffffffffffffffffffbfffff7fffffffffefffffffdfffffffbffffffdefffffff7f", + "data": { + "slot": "8631512", + "index": "42", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8f17caa5bef643c0ad87233155725f33f74561eadafcd08be133e3294d5f203258d6b0ba931885dc4a539baa2731971801c7ae96585a57798074ea0fb66a75413fca184466b88f30a12a18d44243c5342e7422b1487162dfaed5d27d8a88a8be" + }, + { + "aggregation_bits": "0xeffff7fdffffffffffffffbfffffffffffffffffeffffffbffffffffffffffdfffffffefffffffffffffffffffffffffffffffffefffffffffffff3f", + "data": { + "slot": "8631512", + "index": "41", + "beacon_block_root": "0x5a585679198d1bae7f337f987496d22c9f0db95fb1bcd4d8069a74be0e76a5ae", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x83d26a533885e91d048c8afb165513641e3290db26884d4bd9f8c250af11174a40272e38fbb676e7bcf9adcf35b6571808623f517ad35935dd3c7d44faf12769bdeb37e692e2176c6af442c170b8a787e154e7aeb219fa3da054377a59785036" + }, + { + "aggregation_bits": "0x000000000000020400040040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000040", + "data": { + "slot": "8631511", + "index": "19", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa8fa520c646b127498e1148bc60cfb946ac50527b5a370533c4b7f1386cbb537872f35e684d4778708aab0c505a7079f06d318b0871899ebd802c3e0fd7ac75cd8a9e1ce68a434aa5056b83606125bc6b0511f87104ad56e487b44b0cc9f2d18" + }, + { + "aggregation_bits": "0x000000000000000010000000000000000000001000000000080000000000000000200000000000000000000000000000000000000000000000010040", + "data": { + "slot": "8631511", + "index": "60", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x941256861b17a7842620bd000ccc6b3927d80a9b8057895133404d78f4a2e3f89f031cfcdcda558990758b394789b8e6013d85b889b1e843710885a8bdb6f2a0f8fa1ae6ef87e8e80b9c33208538f4d93e2317b863f2eb1a54fafea716bb969f" + }, + { + "aggregation_bits": "0x000000000000010000001000000000000000000000000000000000000000000100000000100010000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "5", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x929bf36ba7957d5c34c8d7f07d722be4e5802cdb112e4453e450df0210e1744d8aa936a5c003aa0ad08c3f469819915b05c0966b5bf989530205d9452588fff8a17cb6265fc29343d585249d2dc8e8147dec0039b61a5aa2552a72d213bccce1" + }, + { + "aggregation_bits": "0x000000000000001000000004000000000000000020000000000000000000000001000000000000000000000000000000000000010000000000000020", + "data": { + "slot": "8631511", + "index": "22", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa76f0c0d444a02d38967477fb80cdf171597303fe26287f0976e3289e502d9dfdb69f9909f96b4e3585f53563ff1f0a5067c0563c61f0a96497dd263eac1269e2b0b225c06dd26347230933e627e0f5bf5ac885f0952323f54de3e874a7393db" + }, + { + "aggregation_bits": "0x000000000001000000000000001200000000000000000000000000000000000000000002000000000000000020000000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "4", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xac3da2d3a7bbdf5649e13fbae50c7a70dd215754b731e9d644947948384e050926231850273047cb711c3680cff91aef07aad7233a6a5184c940f798204753ba0a09c6774a1fec7fbf200331a7252b1f54315219d3c12c030fe8d814078835dd" + }, + { + "aggregation_bits": "0x000200000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000040000000000020000020", + "data": { + "slot": "8631511", + "index": "35", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xad0193b75611d846c91a8ee3709158c93e716ed635437668b5a6518d5deadd43ea76d669d341de52042d54b5e4f932b107e042f5187db2bf08cbd38cfc10cc6d5759652dbaeb801860bae78f734d6d56600cd514b18be9e7b487b17fae791590" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000010000000000200000020000000000000000000040000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "25", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8a2f2208e25bba65d32e402d293eb4cd533b08750ff4184791b1b4846e08ab8ba0fc405429040418abc14fa880c8af7300978d3146a85a1fbda1467749c6c6aaa62c752183bf66391760b2fddcc84c1646530541aa592bf95f10ff05ea0f63a9" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000800000000000000000000000000000000000000000000030000000000000000000001000000000000040", + "data": { + "slot": "8631511", + "index": "18", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb97f6842a1472ac1f96646de52f131d6aa0a68cf440e0caffb0bb7d073c07a6fe416dc3664601a5dcefd4ae1916778a30799dcad6b283713c4ad79d8a2086ccd3fe5bcb4a3f95ad363bc0ff309f75e2004c8811469bb4c82d1601c05ed23255c" + }, + { + "aggregation_bits": "0x800000000000000000020000000002000000000000000000000000000000000000000000000000000000000000000002000000000000000000000020", + "data": { + "slot": "8631511", + "index": "20", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xab3a064a02d7e06fbf1332fda21aa144afb7f56f51054fd9df07df17433a66b7e68536d6866a8e92c542cd7d4c2e4e410ee8efe1ce8e3e5fe30fadfc4097d0eece0b2e6854403e8410470b3b7fdd632e20ca17b917f8dd8d920d4d04d4438cbf" + }, + { + "aggregation_bits": "0x000008000080000000000000000000000000000000000000000000100000000000000000000000000000000000000000100000000000000000000040", + "data": { + "slot": "8631510", + "index": "26", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb582bdb2e6fc782ac3398a41249b751714ee06c5ccb9c1d4fb8fd1d2eeda4e7e024a0070ca7100e4dd9a167553d1f14414bada9ca70d29844742f3a03e35283b167d3e02f1ba091a30ff95ca48b141061f1580d7ae4ace2b561ea29769a601c4" + }, + { + "aggregation_bits": "0x000000000000000000000000002000000000000000000000000000000000000000000000000000000000100000000000000000000200000000020040", + "data": { + "slot": "8631511", + "index": "13", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x903a63dc8287b453fbe6e7a5346042ab3953ea9aeb4f97e6938963632386a7138e2ea57186e4bc448127524833bd5b0607f2032e835fb603b3c4c8461b62776dfe91ac8d361ae4ac799d30550b238d1cabbc03d17792d7e1ce21bb4773793559" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000002000080400000000000000002000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "49", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xac50ce515c5097b44b5abf3ba8eadab663acac8342956b4a9c81d43139726d2db3508ba086d91643017453a194b9223f0ed6165375ae8d1e8b838bcc67e1e12c1d7748c2c7add7c10171cc32c8f1008c086ad0d510cf2a52dfa112bda6fb263b" + }, + { + "aggregation_bits": "0x000400000000000008000000000000000000000000000000000000000000000000000000000000000100000000000000000000000004000000000020", + "data": { + "slot": "8631510", + "index": "32", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaa923c5ab1e1d9bd56fd533d2079936f0de80465cc981588ea5d7bfc17216b165e7399ad57dc36177066fe8c25c1b10401edb3f5afc471586cc00fbaa6bef2c9c5e73f1526aa9a0110f31d05a663931db95dcf1d2be0a8db6708b44679bbdd9a" + }, + { + "aggregation_bits": "0x000000000400000000000000000000000000200000000000000000000000000000000000000000000000002000000000000000000000000000400040", + "data": { + "slot": "8631511", + "index": "10", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa71aab6347798a06e86bbb73ad7048816218deffbd49d3317c5eb4785530cde15aa10b1d0ea76b4484461b10bb19ed2c18f618bb293a8c02b35fec12615eabf84a6a385e152fad263e5dafee8754cd7e4a031d0ddf4a3c8ae923bd69e324ff79" + }, + { + "aggregation_bits": "0x080000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000008000000040", + "data": { + "slot": "8631511", + "index": "46", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa993c440d798f29489b9b2149ba58a40b54e00590f403485221b257c2daeefb287f137911284ffc5a0f54b09f961641f0b1fdd7ada9bf01f41f03862c1253d92086134b14d7fa5915d3d5f2ccff25f44283f6624fabba31bec6df2c74787cb9a" + }, + { + "aggregation_bits": "0x000000000000000800000000040000000000000000000000000000000000000001000000000000000000000000000000000002000000000000000020", + "data": { + "slot": "8631511", + "index": "15", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8554ae2377e193ba5fd1d377c2f878d8f482acc20ed4a252effb4f1a493ecfc25f50fd458ccd5967b89110f6b944384410267966b24e05a30f3cc8c5fe03520bc0b85768f58413f8400ffbc6680f0227651d234cc700d5ee3f4e82383bf58cd3" + }, + { + "aggregation_bits": "0x000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000020", + "data": { + "slot": "8631510", + "index": "25", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8fb874900df428621171d56646474315b1f86c13f9ec4a63cd5e993d08089adbc1c7343e0928c5a10cd69510ce4cc1b210c40515c0142099f373840c6941f84fc9dc82f069ec23d9b1f53b33ec0dfc65c2bfaeb0781fcb084824b9f79835f845" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000100000000000080000000000000000000004000000000000000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "56", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8c8b5f32af81b739ff6ed6b3853013641902dbdc7479fb58f64469d1d414cab4ec029fa6e5f24d856f87c4602aa9f2d819b805f63f151e529178d3ccd108d38c71e87ce24a8e5d29023fcfbb8b05319c15c3a09c833875825efaee52e832f328" + }, + { + "aggregation_bits": "0x010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000040", + "data": { + "slot": "8631511", + "index": "59", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb2545fd500913cb22353af3d7e69c4470a049d4f43ff7b20f9fdbbf75790d6f8acaa5911398414ba52fcb8539ddcc8450e23eca65a1bd336a6eb0fe94a403de50b5e6da9f892fecd00eaf8b61d690c6ca8ad40f9964e4f195d9f7d83a0f800a2" + }, + { + "aggregation_bits": "0x000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000042", + "data": { + "slot": "8631511", + "index": "36", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb7b798c12586933f6454b240658743062db77e6b2a05d99c4abfe5189f07e7dc94558e57d037625e28c18d61d0976eb1125e05fca38e563fdd092f02963077ebf545aec0246006c8024172eb5813f24c7d66f845b75cb5324755f1bcab76791d" + }, + { + "aggregation_bits": "0x000000000000000000000000080000000000000000000000000000000000000000400000002000000000000000000000000000000000000000000020", + "data": { + "slot": "8631510", + "index": "9", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8a15db0376937efdbf6c0583dfe593547f039b8bbdd4985551dc0f4b3cd7f1a045622deb071f61e54d3a0a31b4716b500b9fb9a3bdfe549a11264c2ffeed2cdd63fcd84dcbe33ae28b207b768bbd24ba2c43f843edd45813ebddcbad59bcca99" + }, + { + "aggregation_bits": "0x000001000000000000002000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "18", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x982cc06550a70787a073eea5d83815400ef4e83545bcb05f827df53558d9476eed3413644698748e6b4732fdd3641a50036a09d93a7084e0cba0122923a49bf628467026795a5159732a87450651c3e64fbd1b3076b417f0013e805f1bf288c5" + }, + { + "aggregation_bits": "0x000008000000000000000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000020", + "data": { + "slot": "8631511", + "index": "12", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb554a32185eb69e174694065a11af9ce5d4db924c997fd369ab83674d6d437362308ea9728d3f024df9bc414ba235e6817bf351c60a30d2d7b7d4e532b47840f08e1aef0287391afd840e1ba3522f82d6c70a6cf0fc36d3ea8d080971cba0050" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000010002000000000000000000000000000000000000000000000000000000000000040000000000000000040", + "data": { + "slot": "8631510", + "index": "51", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb643396eb85db6eefc67d810f21ff0dd54bb5e102460029dc2eb90c6561a2831b9217ea8ffb97e8f290a25db820492ef0cb87e8f281a4c4517bf5f973af4078c8d394e9dc37b398055ad1cacad65391cacd26bf01610db40acb695e84e6ef134" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000080000000000002000000000000000000000000000000000000000000000000000000000000000000021", + "data": { + "slot": "8631511", + "index": "27", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8cd635309ce8be6abdb592c6ac2430c702841031d47418acbe4edd62aa0e5bfa13f6014d5520943b131f88887c950dcd18dc1befd85a268220121f8b30677a4a4a31bb36ccc2c4b3c008822076bc4d2c308ffca97758849ef14ce4a0906c5a0c" + }, + { + "aggregation_bits": "0x000000000000008000000000000000000000000000000000000000000000000000000000000000200000008000000000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "58", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb20259156b98e6cf14baf3e168cd21551746da97cf6a28094e08c7caf20e88487ee661468f2476012f593c0e5f373294099f692ad463ada9d3f1d746974bec9cb00b2a4852f8df2044c18f759f13f4e63f1e32ea2520de4950718b9455b83438" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000800000000000000000020000000000000000000000000000041", + "data": { + "slot": "8631511", + "index": "6", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x92cd0e974f0be31e3c7baabf6788678496807cd4592894dfdf63d044c91a74b7a5d85b6126fb02daf6f129ecf2fa69950ae228662b512fe5f3de4a0e8578ba2ce73114d90c0d9c58eef33314b5d3916ee465c055430297103241d4c7490eb033" + }, + { + "aggregation_bits": "0x000000000000000000000000800000000000200000000000000000000000000010000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "47", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb6b000777f0e5022994fd0dc8f4264b0ddbafc128daaa27f2cf8ccdcf45134c24b57bb0c719c427c52c80dfe0f73552f059139af95a1f9ae152073624d5b26c90e66cbc582db51328f37d9fa94de17932e3956a5946000d31e62ce39cd1f3cb5" + }, + { + "aggregation_bits": "0x000000000000000002000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000000040", + "data": { + "slot": "8631512", + "index": "42", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x97a6cfc872eb64f6fe701fda43c418a4bf24b57a00bf0c06e37dd3825643949c8435c7124d22f61e003544ff7bfbc206080cf9abfb0589fd53fdffd866ad0dd2d67797ac1f70df6ca868ddb411abba17114c6018de2c6e7ddd5ac9f8bcd786e9" + }, + { + "aggregation_bits": "0x000000000000000000000000000000a00000000000000000000000000000000000000000800000000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "26", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb7101682aa16481f440b65471da4841f50806df7e0fb42f8377e6673d94127c27fa891045af4c4be5872798328e546ec035ec2d0ff8d6045afc7d3d882957a2c07584790e00cd584b74755fe59fa011606497f41efa8c1cda7b24f9f5b85bc0d" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000008020", + "data": { + "slot": "8631511", + "index": "51", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xab57f287032eaa8faba41f725604de4558e7a8b16535d1c6de0a0938742e1a236812dd92c4922b38bceaa6f2e8a32dcf195413f9532c2c325e052d77e24076237d33ec60246235b2fa9f43edccf1f1f59ec75e1e80cdf1852ea60b9acc1b634d" + }, + { + "aggregation_bits": "0x010000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "14", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb345079aa0fcf1fec97e0311d14ab06d82922c9687794a1cdad8ff8b862e10984e4f39bac677f1f28f9d93eaf0fc0e4013250514952d1249cf8b0b4e3936eac5cef46bf4a1316990a3e3b42f5594ed06268b90a6da5b7e957b495277ea522494" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000020", + "data": { + "slot": "8631511", + "index": "9", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x90d714486d6af4450b192cb61a3d0f27b5f8d3224482ae5f4cdd094cc93f1656a59445cb7cb49e1d637fee67ebc57d240f4c6ae04af5a81df81c522c367b296110c8235506f51e8e7600ebd3ffea73ec0dcbd6995787344d3ec1b5ab61db9ecb" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000040000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "16", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb1cc73e3063be66b25c580a794c228904af071144d3419ce67f4a553ff174e9980ac4b21d7ecefd9e4eb88a5049e55310083b7bd220b2cd5c3e3ef994113dd9843076377bfc66c862d4e120c138d8d004cbbe929a89e01a42c60d504a4fbb0d4" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000004000000000000000000000000000004000000000000000000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "38", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa327b99a8052aa4bcb8b6b430d69ff5a9a38e70e6d72500cf56b05bc11ba2b5c67084aed2cfdecbef4428302279f3d2e10ebfc89434f98a961f7d1010fac135224b801a19bf86f0e266a24f17b2574bbe92d9f045434fb2f341076014ae74a52" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000400000000000000000000040", + "data": { + "slot": "8631511", + "index": "11", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x93c7c98fb3fe5849dee7e7b2496c8223279265f90ffe6667c9dbf12c945ad05761a194354f51ab4c6ac10f127fe893b202455a178cf05f88e4c25858705534f59c7e4e12710450e6de73cfa64d3a9baff5e142c4b1e6c7511617e1061ad0cd2f" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000800000000000000000000040", + "data": { + "slot": "8631510", + "index": "36", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb3c48536b6f029d4aa9af5b0d3925900712457674aaa3bea97690ea15cfc38b0bd591161ff24b024096bec8860424e650069a6ae1265c97fcff48b622a46c9ef9c7e042e000185f8fe758141eec8a72ced2abaad0e21136c1a0595634878efae" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000100100000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "3", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa9167a98dd2e7a1fd3e806abcb0a0ca6d7a2387d09082ef31148ce2b10f9d268e48962a76e43e417842a48bbe1b58fc6035a22dc5b217475dffd5b12eba3122fbdd5619aa739a236491e2c5f65e8f646606fbb6621819ffa9a531032f5bf74a4" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000001000000000000000000020", + "data": { + "slot": "8631510", + "index": "7", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x893819c979ca70b9bcfb02a022cb0ab9a30500194c993ffe3e28c83f15459d20be0c6fb0888862e18a91db6d1ad49df40fb59769675c7c00e6bd5de13d613d5fec2587a07e4c00986ed2cc5744661c72197fd02c635899f62abdf0601b8f5398" + }, + { + "aggregation_bits": "0x000000000000000000000002000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "62", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa450e8ccebd05fc7cb957b80d2b095cf6bd6a87ea47604ebe44bbe1b9611c6c701a47a39bc63b34246b72384c8ee3b5a1088bba7e62df199d0817c34795cb335b05fc195381362fe1578ecf482159c06f6c36bf074b174e56788474d299ed73f" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000200000000000000000000000000000000000000000100000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "34", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8f3e898455473c2a0ffe6f1e06eee8719cb27f104c03b480315959ca2ecf5003790c34c67c9564c48e0eb100109cec60127d3048e360634cf6baa7b6fe5dc52dc191266491170bec046f6528d03d26976fbba33ca5e5919489ac91c4887b17df" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000800000000000000000000000000000000000000000000000000000800000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "28", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8c6a20eb7479a966dad4a0355aad6cc6222ab3c4a3ed0633e83ac41987f28c330cf140a91c47166f4da91213f5d2f8dc18ad0766424066e86ca6e9ac1fe72fb0351ab5a5be2faa31295b4ccc080511d81acd15bc49c13ec922b566fe93b8c95e" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffff7fefffffffffffffff7ffffffeffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffdff7f", + "data": { + "slot": "8631511", + "index": "41", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa0249d3c4552e9339862d138967e41f7c78bf5ad19981ee1ed573c2c2ced58899539086efb5a014b2fe1bc8a4b40a4d8157cc9e78330e418e3016f5467fe5c7ee9e0b13f10375720eee24936b4bf777008cfd1f08070db501e3aefb6c93673f6" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000080001000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "39", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8ae1e3db8e3017986bea4d9fad3ec206d3ad28826588becc8623cf7108e11e66b3c27351d1cedae1bbfd9ada038de094116476826204dcde067968a673669dbd55ed9c029e03ef035746798322433b6a23dafa29a69eaf38d16387e7803a6798" + }, + { + "aggregation_bits": "0x000000000000080000000000000000000000000001010000000000000800000000002000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "42", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb8bb8402eef655b5e5dd2b19757d3fbcdddd6872b40e18c9af1d3b8fda7d7123a79f0ecb116fd1f51c2a5dcfd463df1502803dd4d5f3a4e77defe4b7c0b979380282b6b9ac91bff0dc77a575aebff4a213ab88f02044756a11e22f4a3e8432eb" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000080000000000020", + "data": { + "slot": "8631512", + "index": "36", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaa4b0c2e07e6b988eca22d355675cdceb52273b8adaa90c8a830541713eefe358bde676571bb8048c39e4c1dc61230e413daba8d34dbdc0c98eadd812ecfefd6f484c96db50ad82632aa13699f6510cc2493cac8143d0905aa1c0e5eaea47018" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000140", + "data": { + "slot": "8631510", + "index": "13", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa448bb31a03d8d4991c4d0bff68fedfcfaa56b2b715bd0df636ce97311139d22b7220520f8206060a6f2f14bfcfd94710ef60cc8ce79bf3407a92ac9562bb8f87b29cae92b192e4acdef407cf7af5b0a6b2c143d184a74b9457ea1547f73207b" + }, + { + "aggregation_bits": "0x000000002000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000004000000040", + "data": { + "slot": "8631511", + "index": "28", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8d5db320e083f09d225104d450de1af9faca98f133271f863f11cd85a6c34314298e45c95b66ad9e4812bbd10983cc4c035ce9542f91eae44669cbccb19033c874c4be3c50646bec9fce48013813ee764d8f0d0e11be9d7f77de6dc571f96164" + }, + { + "aggregation_bits": "0x000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000040", + "data": { + "slot": "8631510", + "index": "8", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x9918318a0d0e53213039d99b67bb3d4c8c8c6e760d2a318daf531cb503e77bb97ebb77bb52bb2eeda73cd83b17dc8a740fc8a8d8733131908af8bedb4721eff9782144291c40088a5a34dcf3f00b6ce8fc889912f7fd01cef80b407641795b6f" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffbffffffffffffffffffffffeff6fffffffffffffffffffff7f", + "data": { + "slot": "8631511", + "index": "32", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaae3ec3d7f3f2b3fe4091a3c355f5e335ebf3a8d8cc1e3d159ce8922c49c1680bdbe416a2a6a845749ae109252a531eb071865d709e6b79467e15e501ed01ed7c2da20101443e3af6b3a38f91e7188187f6b505534b6eb8d6c0b434fdd5c5a0d" + }, + { + "aggregation_bits": "0x000000000000000000001000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000020", + "data": { + "slot": "8631511", + "index": "17", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8dac2f31202247c4794d9d97c081b5f0f187f4a6bcb6cae372d05f9143468951dcd9488ca31fbd4727f60e2dc9bc4b1d18a8d1f79ef19c64a0d035ef127dea40486ec2549e08218af66709be9a61ba41e8f07a5e20db93f18bfc0825e93eef7e" + }, + { + "aggregation_bits": "0x000200000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "33", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8600af9f38e1f010ef20400ce2255c5fd7716fe99541cd2fb83a0cc8865ff9b3baac450ad032d09580eb3b72e721faca16066a0d97fc152749cb60628ecd37118d2f61d1d5526374ab06edc61cd4b6b62d927c87254b26d29f22cb553ba63ee0" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000800000000020", + "data": { + "slot": "8631511", + "index": "33", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8254b51bf9a36d557afefd737fba80b97bf9d3e230518be396beaca728a32fabaf3a61041b670b254c3d2f31d110a73e197c6ba2ee93ea4f1492f8dc6944f92dfe1a18172b1ef78cf0ee221039b13886af835134225c850641bf9b8a036464a4" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000400000000000000000000000040", + "data": { + "slot": "8631511", + "index": "62", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb926adcc0d2d36128b2c9957171cac55ac3c9ee397c4e8f4651b8941210c381e938e0a7de217722c8669063e9c87ac40114813a5ba587fbe6b9ae74b13ac920d5bc1dc283196e1c6f8516ff4c5f60e10d5401a4ceedd4ae3a0831ec97db1795f" + }, + { + "aggregation_bits": "0x000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "21", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x914facfd0403c914108f1fa001ccc2b9bf3a54aa6e189f9d23c22254b785363a2ae1bbb158444ccc22a17c781b373f6e199dd12f27032653edf2b1a7ecba0b0fbebb7e261bb44d33fb40bf95acb3d41b47997b69f948797b548cf9b851b65409" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffffffffffffffdfbff7fbffffffffffffffffdffffffffefffffffffffffffffffffffffffffffffffffffffffffffff7f", + "data": { + "slot": "8631511", + "index": "49", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x856a03f298ba41988bc8aa2839c6bf1d387b24a086e73857939dcaf7902b37f022de604d00c11695b4de360932a86407016e6e91609abd7964f80f4169cb25b253b33ba0d47f555fa69228f3f11efc859098c470f18d046dd5701d01f0115c7e" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000020", + "data": { + "slot": "8631512", + "index": "38", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xab26e1fff20f4898e615bc5791e95a5753ecd292a05af731136dbb2835dc5a6e9a863d1e8df66a5202be497a32d429550b74271a06aa5b7432191b14ea8fd13aed719c9ff839ed9383d0bf86eaa4c83e933888443f591135e50d33ba35a7c0c3" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631512", + "index": "34", + "beacon_block_root": "0xeb0c08d706859c73e7172f788977b3cff4ad0e2936c4dd95582dd27dbbbdd69d", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x834b554ba91baa6ea4cf3d4e852a2885d6f04abb002a139e5dab1dbff60f48272af14027b76e3a4a391d406a56ec1ce701977951a43d5a09fac3d22aec58fb50d7274c2fdde568dece8b87a67418b41c68a24c89927942ad16762de0ef4b450d" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "10", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xa4d7dd332d16fefa5988346d73848e61bb40ace8da64f9a05163cf558644ef57974700e9fdffa56edfb8ecd8a37673e908b10eeb32b065391453e395bede891c5a939be445fff7627ef6bdf9bc3a90300dda43a6c2fa69ffa81d98b516062dfd" + }, + { + "aggregation_bits": "0x000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631510", + "index": "11", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x83c37557550d1178642e165c617c56d372ee8193197887e823bc466e3508d269d20ea16c144c94b1e95665e472622bb906fac5c0bb0b2ea70b144b683f46ff0b8de44f8c0f513c0ca7b962336fdc23f26d9c70af2d08c393a76257aec0bf9211" + }, + { + "aggregation_bits": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000040", + "data": { + "slot": "8631511", + "index": "52", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xb6b02a9c1c729948089dfb5f7d9fe974fae6cd229abca0b5ff9a52e587500941551f6f700fc2ae3510b7dc905a22cd2218f8825fc08b7b35f3484ac19341c4b222533a0f872a4a26b65d36b532408980fdf6fe056ac130c241be3c9e7d57c8c9" + }, + { + "aggregation_bits": "0x000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020", + "data": { + "slot": "8631510", + "index": "50", + "beacon_block_root": "0x5509ec83ef9b0cedaf406785234c03bdacbb0d7398e361cacceff28e9dcba9c9", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0xaf15aa9471b6951bff42fc87186422f5be3a9220b001d0a060ea2ef0ce79215d89e455edc8b26b7c180b9dede41a418e11fcdd5b7f46b7180f2dd447217151e666e221ee061df533059cf69e7fe3752fca19aea5b18899f008e711b39129c4de" + }, + { + "aggregation_bits": "0x000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "62", + "beacon_block_root": "0x450216d36649e2c08db47a5bea94a17fd299d52b57981172e25792be1616eaad", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x92316b53d5ad6d7d8575e06777caf46af60b2f743fa29df4b60e9f6faa91f97dd82bade290ac6c767b69f05142d1e94a0fd205350b52afcc518546fb954629c937aba5ec16c59932b0140668a9a5058be802986fbd6168fc9606b71d7e995a2e" + }, + { + "aggregation_bits": "0x000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", + "data": { + "slot": "8631511", + "index": "41", + "beacon_block_root": "0xe3e518a58e2685b72179c7fb86f63dca7a5717006a7ae0ffc9945495f4664573", + "source": { + "epoch": "269733", + "root": "0x508880ef7fe7cac1a601bcb00868cc41a523497b34d85fb71dc338f891eb049b" + }, + "target": { + "epoch": "269734", + "root": "0x89926ca6add36803c7239a78f78af0fb91df932f8af2ac34d4cf89998ea3ec68" + } + }, + "signature": "0x8eaf69445a5b52667d0af90420b2bcbf38920da1f5fe37be19a76975dfd59a932f5da17760751a699949f3b1157db8b50ff59a2ee8b76dd469e5a10ae2a05eeccfd44a940071abe53def172ae6df613a797010987887743e6ac97a6878d069ca" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xfffffffffffffffeffffffffffffffffffbffffffffffffffffffdfffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "sync_committee_signature": "0xae953c135ac95f1cd669a8caf9e89770483bdf3dbf138b2dfdd76198e9baac00ab4d807b518ebfa9e665a8a78dab9c210ff7a073b85fef1e75ccd49f0747c73fe850f9e87c63985f9bf5d795c28474c4ea67716e194a320382c6d9e560aebc9e" + }, + "execution_payload": { + "parent_hash": "0x5cb0f2822e542e2c6fbc0099aa8f996509c178bfaa634e04b728add8da42c65d", + "fee_recipient": "0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5", + "state_root": "0xca4e0ab986d29ee5bddd8b4b9d9481e90d7bbd1ce7ee9e0d077c89ba03cdcf32", + "receipts_root": "0x09fdee17a2dafb2328798f9e47b44e50a5a8e5d9951929afa51f70fc222846c2", + "logs_bloom": "0xbffdca4be5945bfbba8a8ed5eadb7ff2dcefce7f6cb67b94cf81ad38dc9a943b76e541efe10b2768ded9de385ffdd9596b79a4ecffbafd407ffca3453cff2d9ebf7f57ffe3069abb7eebf66eddc460ecd9ef7ded9c67de1b1ccb7ce9e9f9cf7e3fdcdc2fbe974ae2be4cd35271d47b5bda4459fde93d3f0bead5c558997b18386ef38ff77e234f6eb7cda7d47bee4ab6b273b8f9ffb37d5be6ffb7dac9ffbd36ffc6eb33ffaa7f832f264dc5f9966fed1fc7c0fdf6fb719e7fb39b6e38dddfe3defbde6a7668fb7f2166e79fb8df91adbd73545fbf3ae59caeedf7df6937fc5039fafaff21fd720fd9f5d6a3e85798e0d7abde86f3a6afff6383fb0beefcdc0f", + "prev_randao": "0xb48f684132ba484557c07ea6964d6b3841607a44a540a24dd31cbbccb14f06a5", + "block_number": "19431837", + "gas_limit": "30000000", + "gas_used": "28138718", + "timestamp": "1710402179", + "extra_data": "0x6265617665726275696c642e6f7267", + "base_fee_per_gas": "44330915133", + "block_hash": "0x4cf7d9108fc01b50023ab7cab9b372a96068fddcadec551630393b65acb1f34c", + "transactions": [ + "0x02f904b40183222e6b80850a5254153d8303adab946b75d8af000000e20b7a7ddf000ba900b4009a808509bafeda9db83a7f381ce270557c1f68cfb577b856766310bf8b47fd9ce8d11a5b113a7a922aea89288d8c91777beecc68df4a17151df102bbfc4140e8c3d5e806f90407f8bc94e485e2f1bab389c08721b291f6b59780fec83fd7f8a5a0ddf68a16e33fcf794c93d34148c2e2c4391f4f3f27ff7a52703ddbcdb5c569f0a0b39e9ba92c3c47c76d4f70e3bc9c3270ab78d2592718d377c8f5433a34d3470aa09edbdabec2e16ca41f1efb3c19f5f3d18c604847272628636ea866af352b901ca09bb3e24e1534bce24e9896f3377327d742d6c1d430477b7ebc070c2eb64e3147a0000000000000000000000000000000000000000000000000000000000000000bf859941ce270557c1f68cfb577b856766310bf8b47fd9cf842a0b39e9ba92c3c47c76d4f70e3bc9c3270ab78d2592718d377c8f5433a34d3470aa094fe3377ad59f5716da176e7699b06460ce5b4208f8313f3d26113b1cf3d3170f8dd947054b0f980a7eb5b3a6b3446f3c947d80162775cf8c6a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006f85994c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0051234925bf172ac8e2ccbd292c65330169d67445a0966551f13a5df19bb9321a012231cd4c753cb5530a43a74c45106c24765e6f81dc8927d4f4be7e53315d5a8f8bc94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48f8a5a0d2764b6d304d6875dc1632274f53a7d27047ae66fe20f57cce9fb878c86ccdeaa010d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390ba07050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3a00000000000000000000000000000000000000000000000000000000000000001a0154bb98efc83b034ad81fbf23cc88c9737739df170c146ea18e8113dac893665d69443506849d7c04f9138d1a2050bbf3a0c054402ddc0f8dd947a922aea89288d8c91777beecc68df4a17151df1f8c6a00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000c80a0bc7a0020d84346ad4ffdce908fbf7291f7f7f251a6381bd43583f02606a05471a04acbaeb9886f864bc654123665b91e527623fd2a9225e1371e061ecf5fa4dbf8", + "0x02f9017501829a308502540be400850f8839d18083061a80947a250d5630b4cf539739df2c5dacb4c659f2488d80b9010438ed17390000000000000000000000000000000000000003221ceed0394f7b8ef2b12118000000000000000000000000000000000000000000000000213a0fe9640f2a2d00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000001d283807630ffb876a5d78b8e0788e491449f2410000000000000000000000000000000000000000000000000000018e3bee84e100000000000000000000000000000000000000000000000000000000000000020000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2c001a036e76fbcbc86dd2d6fe3d37e65ca3e83aec7259a850b28686fece7105c1d2a24a06c4b4d44d359c9360b8ebf2554eacae621824441f00d99275be3bfd01f554239", + "0x02f906b4018201e28402321261850fae8bdf9a8307159c943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b906443593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acc300000000000000000000000000000000000000000000000000000000000000040a00000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000160000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661a375e00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b16600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004106882e8110f296c60d47cdf7cdc88434fe9b82d97c4dd92b797f7e8d8a54321968be5ba5e9f6ba051f28d593966a89493c697b93af24a2532df7d3083a60d3ae1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000858b793d000000000000000000000000000000000000000000000184dba000c3fc6b755100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000042dac17f958d2ee523a2206206994597c13d831ec70001f4a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48002710e485e2f1bab389c08721b291f6b59780fec83fd700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000007a922aea89288d8c91777beecc68df4a17151df100000000000000000000000000000000000000000000000000000004b1e74327000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002bdac17f958d2ee523a2206206994597c13d831ec7000064a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dd04cee96c94d5a7ad100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000e485e2f1bab389c08721b291f6b59780fec83fd7c080a0d70b4c189764065925757d8bd2e3969810dd6e3b440b8080f1b6feb7c5562baba042a71e23d5021929ae4371a3b2a7c55373d58cbc5b4b4a228463ec1e1802f6c3", + "0x02f904440183222e6c80850a5254153d83033bf2946b75d8af000000e20b7a7ddf000ba900b4009a808532577c909db84e09177054b0f980a7eb5b3a6b3446f3c947d80162775c04b3cd89213a7a922aea89288d8c91777beecc68df4a17151df1e485e2f1bab389c08721b291f6b59780fec83fd702bbfc4020f036d3f606f90383f85994c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a012231cd4c753cb5530a43a74c45106c24765e6f81dc8927d4f4be7e53315d5a8a0051234925bf172ac8e2ccbd292c65330169d67445a0966551f13a5df19bb9321f89b947054b0f980a7eb5b3a6b3446f3c947d80162775cf884a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007f859941ce270557c1f68cfb577b856766310bf8b47fd9cf842a094fe3377ad59f5716da176e7699b06460ce5b4208f8313f3d26113b1cf3d3170a0b39e9ba92c3c47c76d4f70e3bc9c3270ab78d2592718d377c8f5433a34d3470af8bc94e485e2f1bab389c08721b291f6b59780fec83fd7f8a5a0b39e9ba92c3c47c76d4f70e3bc9c3270ab78d2592718d377c8f5433a34d3470aa0ddf68a16e33fcf794c93d34148c2e2c4391f4f3f27ff7a52703ddbcdb5c569f0a09bb3e24e1534bce24e9896f3377327d742d6c1d430477b7ebc070c2eb64e3147a09edbdabec2e16ca41f1efb3c19f5f3d18c604847272628636ea866af352b901ca0000000000000000000000000000000000000000000000000000000000000000bf89b947a922aea89288d8c91777beecc68df4a17151df1f884a00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000000cf8bc94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48f8a5a0154bb98efc83b034ad81fbf23cc88c9737739df170c146ea18e8113dac893665a010d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390ba07050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3a00000000000000000000000000000000000000000000000000000000000000001a0d2764b6d304d6875dc1632274f53a7d27047ae66fe20f57cce9fb878c86ccdead69443506849d7c04f9138d1a2050bbf3a0c054402ddc001a0d54fb22d1cbfa827b9fdd559512572d4524b1085d8f933823d76cd5c678415d8a0509fa03693e2371027c87ba95f77c2f916d6ba1ccb0bf94b9d715e053ae922b8", + "0x02f9015b01824c5d8501dcd650008513b4c10d008307a120947a250d5630b4cf539739df2c5dacb4c659f2488d8837f0fd2491998000b8e47ff36ab500000000000000000000000000000000000000051cd15f4c8240f4719d8880000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000479cd4c24c567cd18520f0d087acfa5f89fe6c890000000000000000000000000000000000000000000000000000000065f2aaf10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9cc0809f82bf8141d135009cc6b3327b566a18577812eadc58774dc0e20b8891c604c4a069fd890b9318af6a641380d6da52ef1632c8bc275ab891129718b66a4f76a66c", + "0x02f901e50183222e6d85db5c95740f85db5c95740f8301a3b5946b75d8af000000e20b7a7ddf000ba900b4009a80852960773c9d9b7f371ce270557c1f68cfb577b856766310bf8b47fd9c03cafc6d06f90153f859941ce270557c1f68cfb577b856766310bf8b47fd9cf842a0b39e9ba92c3c47c76d4f70e3bc9c3270ab78d2592718d377c8f5433a34d3470aa094fe3377ad59f5716da176e7699b06460ce5b4208f8313f3d26113b1cf3d3170f89b947054b0f980a7eb5b3a6b3446f3c947d80162775cf884a0000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007f85994c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a012231cd4c753cb5530a43a74c45106c24765e6f81dc8927d4f4be7e53315d5a8a0051234925bf172ac8e2ccbd292c65330169d67445a0966551f13a5df19bb932101a0e432951488a733bc6f10ac87caeff25ebfa3693ee0362134588b580d99d358d3a0036bbca9bf15f825e87ed5d98bcc4d56039f1e72a6647b87a44be152bf7445a8", + "0x02f9015c01823437850f30220c2b851ac688be008305c7ea947a250d5630b4cf539739df2c5dacb4c659f2488d8829a2241af62c0000b8e4b6f9de9500000000000000000000000000000000000000030fd894eb7a45600000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000067bb6879b16ef6bc9035e92dd6c24facacb931b60000000000000000000000000000000000000000000000000000000065f2b1840000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9cc080a0a5110daab9292819ba68d08f3e8d1ff79b371f70c4c9bc83fe4d49bf9a917834a0665ac7171f7393d00c68657189fe84d8a09db79502524a5e5f92091acd997523", + "0x02f904930101850110e5e5f6850d422605738305357b943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b9042424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030a000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000001600000000000000000000000008881562783028f5c1bcb985d2283d5e170d88888000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661b88f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b17f00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000041ec33c6271e090e54429664d1291e04b4de51f1d1599563f11efc1ee3cef82a237ffe73ae66690769bccf49e0a4ce604881b75d31e53c8606b07177c88832940e1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000006fd727d954471cc8000000000000000000000000000000000000000000000000000371c7a0a17166eb00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000428881562783028f5c1bcb985d2283d5e170d88888000bb8a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004402ba72aea4abd839a0d1db7d7273b1bc9493cd0000000000000000000000000000000000000000000000000371c7a0a17166ebc080a07ac12b4ea5fef6892b2c4f45d16d4fc4062d4f5ef59c17ca4e656776a91f779aa0767f63688afe873454cbcc9edfca54469a2c62c97b42c61653ada04adb84e9a7", + "0x02f9015401822b6b850aabbc443d850aabbc443d8307a12094360e051a25ca6decd2f0e91ea4c179a96c0e565e80b8e4ccf22927000000000000000000000000b62132e35a6c13ee1ee0f84dc5d40bad8d815206000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000001a590a1dcc7d1aa3388000000000000000000000000000000000000000000000000293cfb12b6a0d0860000000000000000000000004c54ff7f1c424ff5487a32aad0b48b19cbaf087f0000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000001c080a0a13a208f888da29bb1a436d468bffd0d96c6c8db1c1ef9d862906a112568354fa03a6bf177eaab40161405f299639309d96606ea537f2caa9094dafd28d4ce1dd4", + "0x02f9013b018204d68439d10680850cc9aa78c083031e1d94f3de3c0d654fda23dad170f0f320a921725091278802c68af0bb140000b8c49871efa4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000c0466456cecb64500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001b0000000000000003b6d0340f4041d29ad20219188cb6f4a3ea0fd1b8192a856c080a05a961ebd36a8bc3c8811d9f7c26085d96d91967b069844a9e6240c443aa776c7a0720e8ee65b702c4101f1f0359d0c74a4f64653a23c6bb559f0019742fec01829", + "0x02f9037a01658405f5e100850bdfd63e008307568e9468b3465833fb72a70ecdf485e0e4c7bd8665fc45881d24b2dfac520000b903045ae401dc0000000000000000000000000000000000000000000000000000000065f2aa9000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000124b858183f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000637a7db1da1c54b628fa5d597632b8d3d9c266660000000000000000000000000000000000000000000000001d24b2dfac520000000000000000000000000000000000000000000000000361401f699b7406e8e40000000000000000000000000000000000000000000000000000000000000042c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f4a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb88881562783028f5c1bcb985d2283d5e170d88888000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064df2ab5bb000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000637a7db1da1c54b628fa5d597632b8d3d9c2666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000412210e8a00000000000000000000000000000000000000000000000000000000c001a0a4e5008b47b5e17669d14856dc4e6c622c8acdc12decf8f34dd2c76daafda05ca079ce55de2d7276772335d97833960b6ce6cbd973753367e1d9a1305f316b9599", + "0xf8ab8203a08522c334157f83030d4094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb00000000000000000000000095362c2df7b2afaff345a6adbb19ed68e9b1e5fa0000000000000000000000000000000000000000000000000000000000f8b7e0269fadb6373e31560e5957c588df5755e0ace18e74e558871d6549123ebb68fbaca020ef57772468b4a9b2629a69308b65823f16883a0539ad5b824ca913ea3cb86a", + "0xf8ad8303a84885151165cc3e83015f9094d26114cd6ee289accf82350c8d8487fedb8a0c0780b844a9059cbb000000000000000000000000710513b93c5290fe7d1cecc31d3e15a9628ee77500000000000000000000000000000000000000000000050a33598e3218e0000026a08c153454d4ab15fc9d650d5893b1b49fba29bc079f2ef8bca6526b4239fbb848a017e3640a6d6f2d2bea62f1fe1af39d1262e7e77a8c0d09ef1d74a23afb67ceb0", + "0xf86e8312edbd8510babc5f0082d6d894aca60a27d73947a6b70d9573dd854ef009bf094b8785e382247de0008026a0015d8946bcf580c4755617989d7ab1c65c2990b00d38cb3c4931ed3ea53268f0a06bf359f294159f30d8aa887426a852b12814bf8a8099e6271ad597d37ce94106", + "0x02f9015b01820188850f574a5a40850f574a5a4083034cc794f3de3c0d654fda23dad170f0f320a92172509127875029ef9204b429b8e49871efa40000000000000000000187cf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004fec5eb942a44300000000000000000000000000000000000000000000005172739a75a59691fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001b0000000000000003b6d0340f0f93a837cce0054b7c0128fd5ae507f54aca0e73ca20afc2aaa00000000001e96c195f6643a3d797cb90cb6ba0ae2776d51b5f3c001a0d2167b629edb7e6a9d5386996814ebf56a7dad6beb0c90747ead2ba86e36ed29a0548b78d63706aa78207e50965eff54c999b7598f91531d2ca6f338892061403a", + "0x02f8b1010b850f0ecdfb42850f0ecdfb4282a30f94e41d2489571d322189246dafa5ebde1f4699f49880b844a9059cbb00000000000000000000000048c04ed5691981c42154c6167398f95e8f38a7ff00000000000000000000000000000000000000000000006b10a18400647c0000c080a0520b5000347377c4d1a5f29f76101a8b105551c0396a20f61518f9701841eb0fa040fb134c25d38c449f8d6c3c650fba9cd817e3b8c2bbb6fb50238b8c612d0ff8", + "0x02f8730101850e5fa55382850e5fa5538282520894ff7a1084b50dbf07fc970ec42f2fb4cf1de8d635870d63202bff8ece80c080a0d7583160a9eaffa2f48665f8f50161b29985364ef68b86bd9c2b853664e716dea066446e0957f5a7ca5f8fe756202318c923b303e1db4abf6c53d30050a9fb412d", + "0xf86c81a0850def3fd16b82520894c8700fa8338e990b4dc920568c9d43df748306bd870d23cf3baff7ea8026a0816e5b8e474a2f2286b1cf2b838e63915d0c6026e4d620ee90a453e907e3c528a0322756d81a9524bb20bf38bbd51238bb2d317db9eddf42cbf0fa3f06e92b272f", + "0xf8a980850da7cffa7f82d87a94f411903cbc70a74d22900a5de66a2dda6650725580b844a9059cbb000000000000000000000000af91f2d992f37450695bfdd15f26362c40d710880000000000000000000000000000000000000000000045640b8bfa7b44f9380026a00e124e09655f0e197aacdf3ed5979a8308449577c86192caa9dca6dd8e7d5c5fa01d7d9e637fa831426e9da71596108c98f8d1ec2f6d73ed493f212b90e61a65bf", + "0xf86f835d07d3850d4576fa0082c3509413d142b7cc2c5b02ba8053a7eb5a68d16f44b52f88016345785d8a00008025a0832f200ae1811363271ffa92ed822a1755cb0d741c49008197fcec4f5e367828a03d2e8ca2dd1818ff4edb43b7c9c492a6d3c64e2a747e5aa3e358b1966c94d003", + "0x02f8740180850d0920753f850d0920753f82520894c88f7666330b4b511358b7742dc2a3234710e7b18809b0389825dd240880c080a007b71ffcfa989a5b57707b32949ffda068f0598a425ef42770dcedb8f6b59412a010bf8db768ee58088f74e824806066af8631f48fad75a7c5dc0a4be46cc72aba", + "0x02f903b301808502f4fa9f00850cce4166008302e96594c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d00000000000000000000000000000000000000000000008a22af5c529b9f0000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000008a22b7e5f992b9062a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000125b25c828c914d3d336fe1db9bed49886729be2d88b0f21e8967f3e23ae8548315c8c08b6354ba860f6d1b680d4f6eed04e394bfde3ab96bf6d1c6203be68c17b99871806e775e36a9d27ed783034164f7cb2c2a7227f4218de0b86b33020daceaab8a9a40c5b986471067add1cd9b392ba37d0e195147c529b66d3e07f1f748acaa383752b3f2742cb99b986462899cd082947dbfe7c9430540b374ec23fcc435c212e72e8fc80fe0ddf1261af59ef66849c3497f4997af2932cb06feef87194ac6f37ca3b577a3cbe764030048784f2dc9bbd21ecd0121a7f6413b2fb77d47c51a3f065731a3122899c4f967475bae44e87792598aa0d1ce0cae2af3f8de75502593b78f42bd3f22887a4fda93d01e75bcdbee061cd4ae41fd92d17efc43ac2c6b091b1c5af4ec138bacecf17fe968408a5f6dd91eb09b6b649f5d579f2be42753be136a7c76aa63dfd5594a78eed1ff1bfc19681837c9d003a2ea9217941436754398af6fafcdec394c601386614891260b3ba9b0fc62571380a77d3e1c374a1777966baf36dc8cc5f4d0c7fe31876428aa616efe94616aeaf74627b3f00bfc003099ab80200205567d103920229171d9211ec23859d159fff215550e91f0267eb720753f9423aa17accea01ce7ac4767da5678c91eeb94e7ab9ef342146c266220d0d69d2ea75f1abaa361fa2325dcb8d95131a12081acc0dbca9d16b8856ecef3f38904031cbedf8f8d77f7533385b9176d0ebe964055755bea7fdd7a73b3bdd1e5318b1af41fa68346461d94bc4793ebd12fd81ce5d0b74b62d096838eac080a0a3899e36bfa7ae0aef62ce893a261a263b14d52e90cfa06692e329c4e0aaa9dba01dba59634e4cbc0c3eb9e7740ae5b4aec63c1210c6dd0896a2fafebaffee9b3c", + "0xf86e8308b61b850cc5fa7ff8825208943851451f023494a7852d95356c19bef700f11de9877a4e6c9a8d068f8026a04d69f82c3764f637bd77ea5ac1f8a1552193acff987f408d683dfd2b75b20183a065c65e4ba60c875164017511411ccf836ff53ce31b70849188564884cd6b267d", + "0xf8ad8303333e850cc06ca3d5830186a094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000004d1ce86f72f03fdd683bc802c7f5c5fe948a027c0000000000000000000000000000000000000000000000000000000004a62f8025a0f24eaa90a2c97e748c719a71648293e24e01b74b11724b3d91006a57a18530f5a054c1a660581f6db579c889031eb9ecb06d530384110f6747907497e44e91b6cc", + "0x02f8740180850c96e98dff850c96e98dff825208943f6b569d627896c41711c1925d8070527c34e38988161f9c2a4b66220880c001a0b1e740a79b0567aad3bca673a6ced9ae7f2eb939f82063da4c529c2b003b725ea0111a29b43768cd3cfba84e9171eb23e630e08cbc254456410e61e50cc0392162", + "0xf8aa80850c92a69c008301117094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000a6fecf2344f5bc04ac6a67fcd1938d6eb5195c55000000000000000000000000000000000000000000000000000000006fe318f825a06b64fa4d2896c6aefafc7f0f944cd11440c13028455dfbdbcbe45e6090bedc94a00567579905de4c573dc9d5c3bf08368240dd8671f603f8c9a080c5b8688e6dc5", + "0x02f901f50182214f8502031b2cab8516e070d5ff8306387794767af52d988d1241a346851a1b39ccd11357376e80b901846ac56d4e951ceec2ea1b3b1b2ac1b07b819ea391c6fb5b75a470425499dd77dd956d78ad000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001208e349991b942ad58964ada2a7de1036823b30cbfbd3122ea8984fc38fdc544b589c2891c6485ab014452bd8a12c396d802409f49295f22ea8984fc2be2d00c827d3a161dac8be4ff2d79ba957fd847b367b2347b295f22ea8984fc38fdc545f38ede111dac8be4ff2d79ba947d3dd5f11db8d89204bccf04969c1c2d81c0c3e6eadf3ac76df47172039c99375fba412a2225f546aa41e5ea88703c1257fcf7d070531b13f0c4c315f47186e0131a3d966ae404cfe60cb5d356a8a19449031c01c65313356ca14ec69f5a441875d61bfc4058ed73152a4e2895668c6d81da2d3c3ba9a94bdae8f440a63e47097fd847b367b2347b295f22ea8984fc38fdc545f393648c27f6be0eb81c917b672b69270134d2579ec9b5d115dd220dd501f04d3cc080a05c211382dd4b2791049e1c2eb4bcd70a7ebac8653591aa7f470e425f0b59eed1a03154927a96ca6bce1c92ed5b99b128cdb5a740c2dab8731035ca30271a8183b3", + "0x02f9015d01830154918501dcd65000850eab17b600830aae60947a250d5630b4cf539739df2c5dacb4c659f2488d88106033bf82f60000b8e47ff36ab5000000000000000000000000000000000000000182cdc4f62c8ca30c7b140000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000021375e8ff94a9acad555e0d8a4f17c69c5e33bd50000000000000000000000000000000000000000000000000000000065f2adfc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9cc001a04f64cce6e85bc3440041b3bd9f659d8e512414b78fac0c4a234f7068474d5979a0797bfc1c30fbecd372a2a4d11d8cc08c449f822428edb48e280d24bb28320138", + "0xf8ab82e083850c2ab8a11f82fcab94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000ac26b31b4ead466dff55b967903b3caf9577df9b0000000000000000000000000000000000000000000000000000000014dc938026a080210bd7705207df754ed6e6d5c4ffd81c8a7198887e0ac13f15c2a6f7416266a04ce56a6684754c995f3662b2c12a16a122737c6faf76ba5a34d233b87cf93972", + "0x02f8b50183010e00850bba6f5042850bba6f5042831e848094bd100d061e120b2c67a24453cf6368e63f1be05680b844a9059cbb000000000000000000000000f5aae5276b1ed63544edb779dcd7e449a7d8017b000000000000000000000000000000000000000000002b39036ce57ccf130000c001a0d13bd010a8370eaba6c2b85cebc78758f216f8b80a7d5b2028d477f251b478c6a0442e6fa4310adb03d9958a3c7fac3fd9acad9f832f648e0cbe87e63eb885f054", + "0x02f8b1010a85015fe197c8850dd0a712a282fc8d9425b4f5d4c314bcd5d7962734936c957b947cb7cf80b844a9059cbb000000000000000000000000e7250ad3e16c6e951dbae9e7d178bc0ebaf9bce800000000000000000000000000000000000000000000003635c9adc5dea00000c080a083342b5b702f801b07c8c37ba9b358c8879fcdd995c40e350fa83e771b7a3f95a0671509edf7e32e1d9162d4b11f403838cb4d60d37ef2bb6451724333dc2f548a", + "0x02f8b1010a85015fe197c8850dd0a712a282dbed941ce270557c1f68cfb577b856766310bf8b47fd9c80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a01741a609fbab5fc00b91ca5a7f0e90f5fa2da99c83b4f86339b97a066fec720fa01a76ad61adcd119512439e26ba65e859dc5e93b70d93a7ea085d49252f5442a2", + "0x02f8b1010585015fe197c8850dd0a712a282dbed941ce270557c1f68cfb577b856766310bf8b47fd9c80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a077d3134cefefbdb13c6379aaa352eeb67f927b87494b84a4957b7f9b313568e3a05ef84f4583d7a6cce1aac7a54d33b8ef58dbcd17b7fe69d27e1e49a16f82325d", + "0x02f90473010b85015fe197c8850dd0a712a283035de9943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b9040424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030a080c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001600000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661b88da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b16200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000041eb0bebb9b24b4109bb4b5774799e230aaed199d6417881aada2590f90ebc03b87282a6db4529e45f57040f94c0e6020b800212d1cc98b80a9a9f71d9ca168c511c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000cb6ca86f57525e1052017fa5000000000000000000000000000000000000000000000000091384da0a48737300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000040000000000000000000000000c916f41c82aaa584ce0912e4c1e731c8259ca306000000000000000000000000000000000000000000000000091384da0a487373c001a09f22832ca93e3b46f6f4f6c8d8df7c351e6a17b892255a4fc0ef43c4ddad12d8a01c4ced5357eaaee98b52c1da26a7f828e10200ebd9de94b9dd109ab66092e7a0", + "0x02f90473010685015fe197c8850dd0a712a283035dd9943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b9040424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030a080c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001600000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661b7ac800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b16000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000410125606f39d2916aaad8ce811674725e537a40131f8fbbc28b5380330c6368740fbed970b6c46a9f3622b9b1cf3086344be41be48001ee67c29132913fd1ea581b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000001d50debba86cf9c4a071f5c20000000000000000000000000000000000000000000000000140dfa843c70af500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ed564d4a96cf7aaf9770006147a597eae55f3c580000000000000000000000000000000000000000000000000140dfa843c70af5c001a0bf2a2178f25e1b82536c4e7b186d8be7414c844138fdea6a5ba1b9b0ebfec056a066f45ee787c89524e5c4225dd3facbf0910e5ea2e35ec16565f0b6dcafb6fab1", + "0x02f873010185015fe197c8850dd0a712a282627094e57d40f34f40b67c7b7b1dee0765018479849b8c871a4a42c356800080c001a08420ceef61483108d9d205f481faa4dcf638c7f2c385efc80de9afc999e8b202a03f4e3a47e527e127ad1b6fc00733475e2a987e58e07230e589c394eee8cb90b6", + "0x02f902da018085015fe197c8850dd0a712a283035fdf943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad873a248477002800b9026424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000003a24847700280000000000000000000000000000000000000000000000000000000000000001000000000000000000000000009fe3e7148415e10a8812be17e405650d31f91a3a000000000000000000000000000000000000000000000000003a248477002800000000000000000000000000000000000000000000000002d86a4d20ee7faf9600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001258d60b224c0c5cd888d37bbf31aa5fcfb7e870c001a0c57cf927cdc7c543566f58b447be7e0d61a1fd5b23b1ff5873f387031b4c70a7a042faf8d347a265ffbd36ad35ee962020ddb48e629bb99c96e0f8cc063f8ac4a7", + "0xf903ab02850b9cb52e848301f0d594c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d00000000000000000000000000000000000000000000008b80d253a5feba0000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000008b80d8228c84f7b00c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001225a94f1f723fc33d5167fc43903dc9353f4f19f428ac36b0a3fd477343cdfc4e9f8c406f1b977f765bc096344fd3d2980085057c671cabc763803db36b9d96804615f13139c222f054d34d67e42dd1fa049cfdff64f827de1cbc6d549e3eef89832a18674b2a0b983e8873f7f8ac67897b71776f2d2bc1ee8057e16b1fc9d280971ce2259366ae4df90c802d9d4e0f00ae7f7a0d34f6ad0348358fed204020ff1b920c3877bb5f57fe795d129914d48730b67edad54c0345f80989c36736680fb646c4d68523b00bfa5ad9b04fc5fe6a0af064af8355ab8af186ab4e944d00d6ef1c35da7929ed3924661dfd31e155dc17cb5fc940e62a91ab01481d7f7f6e527945bd2200c654b4a5d706b5f051425abd5f1a2cd28904d9505adfc4ed3edb0bb6b38a1585c891b98a146fe173dc9a113927d40b4a99dac98fe5d61b456fb938e9214ebcec741a12ebc24cadf7a2eec6aa832dcb37f8a2ea980f3776e0e04e061d8871a61d7eed512be66b0c5cb544e1def1aa1db20ee6f680e5a2d4f5c3a5663abe1c71045451b3f33a32d42af448881022424dcc910536e38de38666fd8612c99568fe3f7a990d0f00b2714b7105fecfa26db4a56489b71f088208342c09247751e549c0b5d29e5f473b4ce26846c3973dc05e90bae1daa1156eb69fb68c9d08a7d0a6af883df133f4dda40a2bf9d18ea6e9b3b90b30974c74803005be777e854f5656ba40bc7ae01e2b8cb95cffecd7cc1fa7a3a3e69fa5faf5d26f1771383bdd1e5318b1af41fa68346461d94bc4793ebd12fd81ce5d0b74b62d096838ea26a085e6009449a5343549691699bb5d772ec8efbdec71bd506b08377cd6fa6aa692a02c95599cff9cb2d8752868f37d43141233c8d2a521e2669fdf4471747d80b164", + "0xf8ad83a549fc850b965e63898305573094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000eb132715c8560fd3832baceb36699e4c275480ea000000000000000000000000000000000000000000000000000000001cd9410025a08ac4221d205e2615a3955ba50661f0eac5a099d2dbaf13898367f86511365966a06c39ae260706750e747e74aef8f42b36c7360ccdca60b4a1b27a35528e05655b", + "0x02f8730108850b964f2148850b964f2148825208946cc8dcbca746a6e4fdefb98e1d0df903b107fd21874c9adcb727bda680c001a00c2ee154ee471824c18edea9309f2f9480d905924ab956387cfb0a6252cb6d7ba058f4b65bd333222be823b34186061bf634622f53b9ff5146befa50445aef1fee", + "0x02f8b1010a8501330d149e850ee2688b4e82dbf694be9f61555f50dd6167f2772e9cf7519790d9662480b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a065730e98a96c93448e582150b3cdefd1d2472f54d08f997adf31e171828764faa01369bac5247c404c93795ae163f8611c4277b7215bc7c698f20b38a1e44bb80c", + "0x02f90493010b8501330d149e850ee2688b4e83061945943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b9042424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030a000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000be9f61555f50dd6167f2772e9cf7519790d96624000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661b88ef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b17700000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004134866262fbf32e9c6a99477564fcdb5b81308e3c6ca7fa2afc6d22f76278c5db60a39206de9436fc96f5072e07cf09bad8a9e6f852b0219ab419e2dec1bf03061c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000bca24a51b82889d831c0000000000000000000000000000000000000000000000002018643b999fdd1800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000042be9f61555f50dd6167f2772e9cf7519790d96624000bb8a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000006997d59f49ec919caa7c8b1c5bf1eaa03842dfd20000000000000000000000000000000000000000000000002018643b999fdd18c001a0e8f24ff09f347e6c0b15f6bd0a98e881fa543e351ba0c652827f5824ee555b67a04da8b7a7432c9c3ec967c81e1817e30d04e896c636b0a9634a4929e81cd6ae8d", + "0x02f9035a01058501330d149e850ee2688b4e8303a1df943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad87976c11aabce199b902e424856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030b090c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000976c11aabce19900000000000000000000000000000000000000000000000000000000000001000000000000000000000000004732dbebdf7e45faf5cbb0b5923de36392e551b500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000976c11aabce19900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c3f8143212871014b472ea83285af7f25928dee400000000000000000000000000000000000000000000000000000000000000400000000000000000000000004732dbebdf7e45faf5cbb0b5923de36392e551b50000000000000000000000000000000000000000000000000000000000000000c001a0f251bcc144ee6c6728961ff9b607a34f0685f98e03ec75da8e419a7513c5173ba01b63fb36405c5fb3b3c1da8fcdd5d2e35fd34a6260c8d341347d890530fe4874", + "0xf86e832905b2850b7fb7760282520894c027ed26517deb1c5ab035575f2572f8d8162be487072293978f32e08025a06fcfa4b5b68cc408c008cb6d3c4bf25ce9de5ec57f4964403c7b145d7372e225a07db25c643e7ef418fb104f979d6a174c5165ec2002c8f707757f436e59224071", + "0x02f8b501830d046885012a05f200850d69a4441d83030d40949e976f211daea0d652912ab99b0dc21a7fd728e480b844a9059cbb000000000000000000000000082547bbf74f4eb48138e83fb1d8845e7c239a70000000000000000000000000000000000000000000001eaf49fa6a83627d8400c080a00eb64f6b37eebbe016ff20ceda921d786dbffd8d3d33c1f403ae74916b7e557ca01df31dc95ac330361ecf3fef85dc4d3cd273fc0343248516ca2d652ad8c2fc33", + "0xf86b01850b68a0aa00825208944e5b2e1dc63f6b91cb6cd759936495434c7e972f872aec0a10f272008026a0af770d803d6ff43bbf46c58195cb438a87bb497d4bba6656584655d67ffaeb54a06ca124c1bdb4b4a283f437629e73e9d0486dd81a589fddbecc33642a0d84dc88", + "0xf86d8208cd850b68a0aa0082520894890026952ed29515d96098db1250492669692f67871340c2cf1b2c008025a09a4cc2310ee789f86ec041761741a601063c43077451f2506ade19faad0fdb1ba048e9ce05a675712c238db18f738796b7e9e3799dc5c3f9767173f7e6ae6e80e0", + "0x02f902d40181a6850110e5e5f6850d4226057383036231943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b9026424856bc3000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002080c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000009580cf5d9870000000000000000000000000000000000000000000000000061d4e22009bf0600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000006a6aa13393b7d1100c00a57c76c39e8b6c835041000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000400000000000000000000000005a03ce41153697783d7ea8e0fb322f8bc61f82170000000000000000000000000000000000000000000000000061d4e22009bf06c080a0a7d3d023f9a2080ad2810049d7a2720c70789d61c934b545ed3e7166c9b2a25da05e748f58b1bce7b0c9ff172a98b187aeff4143d427ee90a495193635cff28475", + "0x02f87601830ecd7b84fa47a7c0850fbbdd93428252089405922b84abd2b3451f17913cd38ef2352177583d8803a38582c41b800080c080a0b66f717de0184280be5ff97dbee3305fdb12b2a079787a0a1e9601f727e4bda1a03d6dabcb515ec812463f311e002b81aa27a6151bef3f4900ed9a260ba922e743", + "0x02f8b40183032be684fa47a7c0850fbbdd93428301482094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000dc2f340ee359ac809b991160204ab92f6da62e18000000000000000000000000000000000000000000000000000000001df8e1d0c001a0090ed221942618d7d9d7cb8bda17028dcd1f45b6f1f7a0a1b1d158a504af867ea047519808a8384bcc0af521a1c84de12dddb70d5f732e0eba459a98488b728148", + "0x02f87501830a29b784e41b62c0850f529d556a8252089426544ae074f3f4a51f344c38825ddd32424c94bf877a369e2446000080c080a0a5956b53be8203030d87a786e099a62c26de8a11d4b5657d88b3dc45699c5cb0a01f32f207b9b2852cb5bb42dc5904c5ebe6b818ad9f4cbe5beb7f1a24e647e4f3", + "0xf86e830aa3ec850b2d05e00082520894e9e954671db1ad060398951b2be1841d293dd44987306e3b559400008026a0225af81b392d9f053749b318e51bb3d7b60da0be7bc67e4b00d9423bdd6f047fa015a94668988c165e91ab67cb9af4b574a4a67f24d70e7cf7674fa12dc1a3e371", + "0x02f90292011e84be740e988512289ef29e83036b76943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b902243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000006acb2ccb83332e66c2d9670c000000000000000000000000000000000000000000000000000000005002231c00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c001a060ff4ed8117f97aefc70b422b635d594e607b4780abb274428426b41faffd915a06dfffd7e0a9554270e5b38671c985ccf0590d4c7e44edb53f40d3b682b9ecacb", + "0x02f90492012184be740e988512289ef29e830417f8943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b904243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000030a080c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001600000000000000000000000009760aa5124b8255fff140a76994f91ca22d2647d000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661a376400000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b16c00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000041612fef4fb4ba56322a8d1e4cfc1635ee5f34deb6ab07db91f80015ecf50c717376450e9ff133713cd2d0f456ff507129b465d98185e4a129374646eb5fb9ccd21c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000a80715fbb4f80000000000000000000000000000000000000000000000000097fcac4a90ad9500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000009760aa5124b8255fff140a76994f91ca22d2647d000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000097fcac4a90ad95c080a0893245f2cbba47ca744104efcfbbe50f15706340b93e2ebacfee83024f26a7b6a054ca7ae631f571bdd654f16f06e6a02a83bd20b9a4c1f6108ba5135a698aaa7a", + "0x02f872010a84be740e9885108a9b860682520894b201d5c0e79fb09ba79a5d11950ab78f57bf3b70872386f26fc1000080c080a0d9b225d61474a24cb41f5c782eaa926c4926f7007d81e892ba579c390a139583a053035b248ea719fc3ae8a76d424e83fb9979a927eec03d4227f450f891ce2eda", + "0x02f8b1014284be740e9885108a9b86068301b9b194d9812f24f34e0d727bbf6ea7caaee05b7f7a260380b844a9059cbb000000000000000000000000a2d12ad88c21830f438620467241213e8e8616fc0000000000000000000000000000000000000000000005d723aaf284072c45d5c080a08428cf84fd778c498ee2362997f9e3671572e5ae3a7b4253f641e451e35666dfa0512bf68e37da709821827252354eb35a8b4e6dc75736f363c3fcdf043bd4c4c2", + "0x02f8b1010f84be740e9885108a9b86068301158194cae6ebacef456e5a942afb40fc99f2f38639ef0180b844095ea7b3000000000000000000000000b9b213d92253a405977ffe38fe8e2bd9c14457a10000000000000000000000000000000000000000000058f03ee118a13e800000c080a03aa2432066cbf8f82753a0f81019fe406f9a34a1e9c98648260e3de2386fd79ba0061ca71e72ae5ee0094364d735de68fd9fded576f027c0d77de7d52ab8955041", + "0x02f872010984be740e9885108a9b860682520894a40d8cbb65b546a1c1740fe35feddc1eec6983b2876a94d74f43000080c001a04bfc01b60f0d5ca4b4b8d9c9206e36271fec9f3854869182a6ea82374f194223a0595dc7d9eca0b94d88a5936f2ad7c065eed10bb85fa886ca15e33e1567cd7380", + "0x02f8b1012b84be740e9885108a9b86068301324694ddb3422497e61e13543bea06989c0789117555c580b844a9059cbb00000000000000000000000042a289b725980361669356e0fd6fd52ab386e1f200000000000000000000000000000000000000000000004b56763adf67a40000c080a07d853e7042e5454ed9920381453b775dc0331993baafba96bbafd50b002e2f29a020a24aa1988abce355a84e698a066f7378649607b57829808894ff7ab76daab4", + "0x02f902f9010584be740e9885121f2937978303b8e6943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad870aa87bee538000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2accf00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000aa87bee5380000000000000000000000000000000000000000000000000000d3e77830498ac2900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000cd24ba0e3364233ee9301c1d608a14753c8739c5c001a02a28422be21a9442f6e1283f86a52248e3b1a3b7599dcecb839c19a95e310597a038a4b35f2fe9cd57117e0edda565c3057507473c3f3e79fb9332e4aa9f69248c", + "0x02f875018302928d84b2d05e018513a7cc86ec826aa494816342193a94ae0bf0a4807976f78d5ab03d12ef872fce292419000080c080a05ec69593c99e139227d5015b70e0b5bbf68f955137b75edde3753efc703c6359a048e542994553c9a7535fa1dcaafd4b857dd9ef6c86b2049d4e64f14973fd91a9", + "0x02f8b401830adc9a84b2d05e00850d4576fa0083014c0894bbbbca6a901c926f240b89eacb641d8aec7aeafd80b844a9059cbb0000000000000000000000006767526a362ec6c6b1df185478e4f01506b73ff30000000000000000000000000000000000000000000006cccb85a7550fc00000c001a01ad1b4dfd6dc28ce7ac910abbacdeec4dcbf32d15208b85758d1d48d7498c072a037377aaec06ef2d5a626d6874eb040e2a3cd07c341dd65f53b3f30779fe7a4dd", + "0x02f9023a018084b2d05e0085104c533c0083021ed59444acfa1395e583b9fdc88137b7a03a8e173788b388034d8bbd308b0000b901c4b77a147b0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c45a4e4df40fe2bf63d9de141376f050f15916b17e3c729d28a0ab49ed8627800d27062894fa8fb51238dc11061d677f413e6b772ef39e06b1c22e0021eb8f880486f0f3fbce03139aec098665754ebfbe38380883968524693d94ac35f958ed9eda1fcd7a2e4b8db4c41fb63992acf6a950070d33546b08330ade10e7fd68a5cb0cb062db4acd87fdde77d5b891f58c57dd462de6991b7a6f340bc1f73c1ddb53ec90c20c54f6f0be2115cf8fc290dae6089852c57d6454706604c8544918ed392fcc8e2d922cd23f5f4bb61e6f661c4b93bb9404fea2179db3bb46ca1088d3687ca7ee737db680b4c814f5de84a0430f54e4bac146d94709abf0da7cf1878a29dae9a8fdcc2e3cdef8edcca1a1bb3d4c6bce50adb9005396a73a4e3e76e047676d7155dfa18871344ba028334f76f25081a871a310975ef8d4d333a21cc947390d4db92d61c9563f6649309b5ff90ecb576cc35e86f5320327060f36d22181d08cc612709bad88760231f5e7fb70d334443865091f8085cf14e0e97f120d247c001a0524fb2543274c82f343e5f55e944e2df33814f3823ece8d6ddd44c875ae3eeb9a0066b35ad284d1994e76ae4e8128768137d7c23d41fc06b1527d0a4e92b0e4cb1", + "0xf86c80850af16b1600825208947f58200b81d2885807da57589b1f255be825ff0e8806f05b59d3b200008026a029c4e6ebed80d23439a5641591335fb27b39a42ec4e737a2b8d6887fa4875a70a06810b74b2629f4ed9ac3d802fb48ce57623c93874de9a2f6cc723a7f074e9a2a", + "0xf86e830fae65850af16b16008255f094a62225f6008c092299637020fd97c25999f319d687183665bb1ea4008025a09ed1ce836f07fa12b2ecbce2ced394406d679940fa1a91456383d6f3b4757aada044d77a96e5e679d64d8d3f2f5e4deab4234f1a225157e7c28534855f9757a08e", + "0x02f8b00180849402f900850e81818c0582cac39495ad61b0a150d79219dcf64e1e6cc01f0b64c4ce80b844a9059cbb00000000000000000000000040e129cb3a203ae007a6411191fc0d57c350b3c000000000000000000000000000000000000000000006a1c870d47e5e274df800c001a0b1c0b14b8db85e946216205bc50a9a1fbe2d2187f5d0f2cb3104288c829bf8f0a0140a2b165388bf9908aacf6a793e19430ba918f22467b5d5852ac73ddb8a7c38", + "0x02f8b301830321aa847744d640850f20621b8882a4d89495ad61b0a150d79219dcf64e1e6cc01f0b64c4ce80b844a9059cbb00000000000000000000000077095982aac409f3fb448aad9e209c7c07815e7e000000000000000000000000000000000000000000526ddddf71b28034a31000c001a052383a32119afa16a15e8cfd2aaa180561e44d7ccbd0b58c016ed46b45a39a09a06bd599340379746b89c39e29a6a4cb3c94a49fc3039c5c0ec926be545b6985c8", + "0x02f87501830211b1847744d640850f20621b8882520894650993dc97634ccf05d362bead78b4add5d506c587246139ca80000080c080a004b465d6891f9fb80bbafa255b204a4e7572072f2b92031e3660b965dfb9125ca0665a80460becb67e705a29e07c71230813649210e63cd11f58b1321ae02c3051", + "0x02f8b1010d8477359400850ddf42a8cc83012e1a94467719ad09025fcc6cf6f8311755809d45a5e5f380b844a9059cbb0000000000000000000000000fb28aca9355a6aa973f6b2774c811c5d0320c850000000000000000000000000000000000000000000000000000000038ec24c0c080a0416d591a0f4f0264b62afabef8a7137dd5f81744300e5e2ae57cbb5249619257a068ac9dca55e16482aa4f959195819f4215138adaf216b2cc63c63b54ecce46c2", + "0x02f8b001808477359400850df847580082c35094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b00000000000000000000000000000000000000000000000cbd47b6eaa8cc0000c080a04890ebf991b2338963de4b50d01f768becdf51a5a98c6e1abe4a62c682fc7400a058396cf140403ec2fb171dcb82052bc00db3309b7bb2435ce205d9864d469654", + "0x02f8b001028477359400850df847580082c35094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b000000000000000000000000000000000000000000000007ea28327577080000c080a0106082d34ac82abed0039a1a6425b59eb1fec8da396517b47b8e2ac2e6fbf8b2a030f9381d899c51c1f7b82b653dfc1f82b8cf7fe1b08ea15a54f7f79871e6cb0f", + "0x02f87201808477359400850c0d03af5582520894808d0aee8db7e7c74faf4b264333afe8c9ccdba4873636e8f996a35880c001a029bf001cb0b6aa3a71024a3d60a92e3bbfb2feedd4f44c1c33d47c76080234d3a053395cb47773ebf4a876053f4a9397f697e8707457f08029b9a4875fe5129bb6", + "0x02f8750183029f2a84773594008517a2d1caaa82d6d8941bab31b520c8c312ff722477b7a1cc890473c883870a1d0c0facfdb880c080a07b8ac6701ca8162448221202bf26e8d16a20b84447c1cbfb144ceebdf2fe3db1a02ddcb2ea4c943aab10c370a423020f3b551d3a11fe18597e825ec0a2fbf4f93a", + "0x02f8b4018388941c84773594008517bfac7c0083035d1494dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000a5c0ae1c0d7838ebd6b0b9c9a50be5511e0aa11e000000000000000000000000000000000000000000000000000000001dcd9188c080a0b55571f4132d1baa4904720f50f2af59133fc98d7d81e7b58eedc43c2eedf316a076c80841a293cb799727689ef35c6350b42d5b2abadeb34c8671310ba45a324e", + "0x02f876018381e9ec84773594008517bfac7c008303291894c1e4f895e81c6fb82e4a9b043f4e0da61a29f7b4871b3bee858c300080c001a08fd3f48b41dc515b033bf466bf42b4fd835366adf5dcea4c67807b737a92db38a078f866574e2b97ac1453c2c1f6820d596a4ae215d121fc092d8200d85e80d9dd", + "0x02f8b4018381e9ed84773594008517bfac7c0083032918949be89d2a4cd102d8fecc6bf9da793be995c2254180b844a9059cbb000000000000000000000000cc4013a3afe4630eb4671d924b0084c01a3e5a64000000000000000000000000000000000000000000000000000000000000a8afc001a0c19152c83d612d923e27a7940a944fe0069915bae2d1a1fac44b9873bdd06cc3a0409cc2b5b59c3362a797f8a2737a5d01b0e58b5edeb705f9cefda28fe5db0a5b", + "0x02f874018204cb8477359400850df8475800827b0c94ab83a311ebcc5be7466edbcd5b798f18121f5196872bf55d2dab36bb80c001a0debfe435ce07e8a7f572adb752d41f385658a28b2459448b4ee53a91869652aaa06abab0000360f08ec7668a0e164edfcd9e89612e4aa7efd303f44eb141eae265", + "0x02f8b001808477359400850c2521caa982dc2494e28b3b32b6c345a34ff64674606124dd5aceca3080b844095ea7b3000000000000000000000000f955c57f9ea9dc8781965feae0b6a2ace2bad6f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a0e4224fd2900fd472113cc8db34a88bfefeb78c754b17f93fa3ec22e51e9a6d2da0522311d1bcdef7c15d66b358c00c2d9eb9976dbbd8cfea040c727e856984d05d", + "0x02f876018328af298477359400853a3529440083015f909488022e41f7c108e7fc786b6f15bc705d10d34dca873d7642229d400080c001a082c73d2c2492a2cf4613535516b3ed769cc3f08d4449b302506acc68234adcada0245cb18060599f93d0575a430a980dc44c3e662605fbf7fef843768fee04f86b", + "0x02f8b20181988477359400850e5fa553828301117094a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb0000000000000000000000009bf81cc31d0f1fa7ade83058509a4db154a182a2000000000000000000000000000000000000000000000000000000000dc4c7c0c001a050d9b55158f4a76ad549c5ac6e5ffa8767426e81298bb9a10ea35cc51ac4ebe8a0579dcefb0e6bfc3a067dce6000131aa3b1fe09bf290a09bcb3eb92b06b8234dd", + "0x02f8b001028477359400850e65be4a6b829ed194f411903cbc70a74d22900a5de66a2dda6650725580b844095ea7b3000000000000000000000000a7ca2c8673bcfa5a26d8ceec2887f2cc2b0db22affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a05022e8b159eb3ebf3b8aa40863855a0fff534d9045de0327c7d50d5dfc4e3ca0a039c05e5cd887106d135ffc64b37cda928743950acf837ab298af7d3ece712119", + "0x02f8b001688477359400850df847580082ea609464bc2ca1be492be7185faa2c8835d9b824c8a19480b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b000000000000000000000000000000000000000000000266acc439ba50730000c080a0d8c067895655081946eac52305e0b11e2d310b38e1de9765da5bc9917b704d2ba007256e53ac4e6c32d25277011a7f110b6b91a3fc9ff81227c90d88d0f15a8f2b", + "0x02f872018084773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca871bb4d4b62cd6b080c001a05938f654a7077b081ed152d911e9505f659d23fb3b82569067413883bb653a70a032dda885f92738ba8c75661ccbc056bb4e7fb466d98c4960b48aadb34761b9d0", + "0x02f872018084773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca8738e708d3ee119080c080a03b8bc43d25584671f81e962959a228cabea7d4916b2b5da327f31d068290e910a0403dea2d3dc8b582cc4bcbcabbb18c3af3a951979dbd7b243ba521b44c4dbd7a", + "0x02f872018084773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca874dce0dcd5f92d080c001a02d50f46b5700a8f99273831ba1652ff79ac78e4b55fab216795fcbfdb79d499aa010be44e79c4444c73bb29d9c5e2c1e57bac925f6990ee177a3d51ad316cfc356", + "0x02f873010984773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43880564febb0d6e6cf280c001a062f0679cdd027ae0293e2b460c80f3675b7c0d0ffa02b395a63eeeaa4367f78ba07252d94b81f0d35f314b3d1f6ef1915d8ce9a01e0090245b50aedb68d2d68621", + "0x02f873013b84773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca8802a5c9f4b52a525880c001a038a46b8582f9f92f65c7985150e5160ae27d9c04f8eb2e6bd084fc56b0897a33a0739cbdc2a82a452cf911a86bce6f363775d233f240e7dfb2144c42ff2e2f6f9e", + "0x02f874018084773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43890207d4a0b06100358d80c080a0ac2bf9bcf27997ebbe1ee31bb91de46e9a97ae599b0b66e35bebee95caf9a9e2a049d3cbd468e87b6aa6e02486c29087e29e3df17428ff696c9453bf4023550754", + "0x02f872010384773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca87ac81d977bfb82b80c080a0775e385b916c681963114c5aa627e7e20eb087519f89600b643fe57bcc97ad47a062fb00c672cb2f6365866be21aaacb3a44d8d0b167e43e398b93e14cf96d11c6", + "0x02f873018084773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e438801077067cd1bdc0080c001a08ac07c8cf253fe07cfdf5651ed1156ed40c617e57dc8d4152afd7ecac3a9aae5a006ee7881bfd943ebc6f2c078c75bb1b9324e7992e8a1777ce9d17420b34ccd51", + "0x02f873018084773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e438802c409f4ad946c0080c080a0c87db5ed2e5f45ba65a98e3b8e4d37e0dedc97a5d0580ee2afb1ab8893c44e78a028d0da83975b13050467cdd7461fe926b53cd1dba09d9bf30b6db413b4704af6", + "0x02f873018084773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca8802aa4c08e8072f0180c001a0ef55f969d0c720f9fe95a6c1c7c551bbf066a006a256bcc6ee758c1ce27694c3a0685100f72084c8923f98ee90a9da40c0d768db33c88b9c6a8e1332be83e4769d", + "0x02f872010184773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e4387de86aa0b18a36080c001a0a217f7527ca9b1bdeed84be67aba1dec65a24b84d02a66de9d36f0e190d35d80a065225df53f59b593a71f6b10e37160aeea7193e4527fd0c36588b43d93853554", + "0x02f873011f84773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43885b1d3e80723e434880c080a09774f1ad0a37a05948146ca07e6a6b069383c3707695b4975ee1fedbccc1ee7ca02a6e21ebbb427e870dcc9ceaa7978381ecec9efe5ee5a8a482e43b4550e5393e", + "0x02f873010684773594008517bfac7c008252089477696bb39917c91a0c3908d577d5e322095425ca880a7578444257064c80c001a02b0b4425133adc0c98f986bd8881e237f4cb91e177868862a39483ec443e37eca0039cf8dcc580114a394875fc26a7870e4fc30397f29c654387e2be0283b0ae88", + "0x02f875018301bcb684773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43880523effeeb452f3180c001a0409fede92e8ed5f980492516402d600372db0b35cea0663ad7a8de262ba880719fa9de714f459f81513d413a83952d4cc093f93aefc04bc052177fe4fb0d2b62", + "0x02f872014a84773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e438782ab24ab6b5c8a80c001a05e31b9ac844d84f68bcd6aa2f5248d42846c06618df161ec49ca52472636628fa00c12d0e716b76f27f8c3d62e7ae87caeb683b7aaf8eb2b30d4f996e442f6fa97", + "0x02f872018084773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e4387198b6b551f687780c080a0a40bd0778d94c6c64c3b0b01682a73ee495f888a9750c01cb17d360eba6d240ca0701cb6c2be9e56ca8374393579b875040d093b6caf6d96f629df09f6229adaa0", + "0x02f872017684773594008517bfac7c00825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43872709ce03efd1e580c001a04bfeb49efd34d0f8260ae341e5c8ff0ae23182b92c2235bde25f5772dbe1cf88a01848d5b95f3ccd5e5332e16c8843ea922a39855bc7b80885f4fa3c0fee3754de", + "0x02f8760183106eec8477359400855d21dba0008303345094215b4ab21d2296222c76cdb16588d585b169af6d874325732a41400080c080a0bfbfc3e114c3ca68887d8d77b1ae791c275852cba4b0120af30146120e680c12a02ecbbcbec039dfa0f9ab710daac89b8760b2b9fc451d0003d09d7fdb7487b867", + "0x02f8b001028477359400850df847580082c35094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b000000000000000000000000000000000000000000000004c53ecdc18a600000c080a0695e0c278594b3610d8e6b8606c0b8fca37a9a5df0473365bfb258163fb1abb9a0544fef1342e53370273231a1378b33774e81405fc78c69d23532cad8ceae3971", + "0x02f8b001018477359400850df847580082c35094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b00000000000000000000000000000000000000000000001fd242edf0d24c0000c080a0560e3dcfc62acecc0ab1316577003453775de1f38b17b672fa2e866903c65c34a06e9de5009852cd0108e4d50aa2983474be773a1e54ce2ca764dc9f4659b76dca", + "0x02f8b001808477359400850df847580082c35094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006cc5f688a315f3dc28a7781717a9a798a59fda7b00000000000000000000000000000000000000000000000fe2311b9e95740000c001a0d762e1840c43133ec0873c9463bf1d9edcbe2ed0701779ffb3467e50e8d5662da0090085f359fbcc7d2724cf1c676c3be582bd3205a22585c0a41d38ab70b3c9e1", + "0x02f8740182035e8477359400850e5fa5538282520894ee31993ab5310f1f85f01e3fe12f4dc8ed017542880de0b6b3a764000080c0809fc4ff9124a70b6c21181f55121f34253caea75beb53b51700d7e6b040999331a0647007cb4c06237905a35d2bd8d08251b01e908de31e688a0c9e13d22c868fed", + "0x02f874018202f28477359400850e5fa5538282520894cc6166d957115d4b2a93192c5060d763de913bd78756d2f298653dd980c001a002ab297ddb7ace9ec230f208522331dbc4f9d97b1ac90dd117de5043e3b41e07a02e744a9539e239f49cfa463fec1bf43b9aa4a86e914bc501e216aef43749925a", + "0x02f87701838ceae084773594008517bfac7c008303291894398132ae4b3f8a9409a5d9af816079c3b8ddee53880bdec7ed01e6000080c001a04bd782765419be32b76491b3a1aab2197d19f6a6a51649402295600713a19dd8a03fdcf5d50fae76476f7190d1b01ec1f33b75970b74d9ea8dae20e509f7a8f9fb", + "0x02f87701835c488484773594008517bfac7c0083032918943a4245a215a7af26438e42d97d21119b769842b388d0ea8d3d90bb000080c001a02fca9dcb60c8603084679d442df49d2a07d2a37036281292ecae8a7ecaca07fba014ef6f7e6c140d0733e0cf3a950a04b1cec57789dd660884dd4a0cec4407f266", + "0x02f87601833ab70384773594008517bfac7c0083032918946894e745915afae9dbb1b84c8bf11cb285a16e698722c5681358800080c001a0420441d003f0dca8f0fccd858211e34c9fc16ed1b1498e0e6a9b37b00b6719dea04e70b511251868b46a471ca1664ba52b453ccfcd8960d89affaad83397681742", + "0x02f8b4018381e9ee84773594008517bfac7c008303291894fa1a856cfa3409cfa145fa4e20eb270df3eb21ab80b844a9059cbb000000000000000000000000082f4d0b3e90aecb5b38143a50278bea1308ee5b000000000000000000000000000000000000000000000bf5559e13dbfa508000c001a066b3e6f72e613d95ed1fde25bd0991973ffe958447aa359ab0c13a0821a1b713a049ffa84a401cc799804a51bccdedce4eebc64c725b05c990d0c48f14df7ed5a8", + "0x02f8b4018381e9ef84773594008517bfac7c0083035d1494dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000002b88cec110af5376af0bb6ef8598c65bb87460290000000000000000000000000000000000000000000000000000000005c35f50c080a075d1a20346bf6d8c638300f788f69970ae166561290697d6ccdbbedbdddfd3ada00362acd337471e8f5619a4a134e20aceb11d988c94671b5cad7659f20c2feff4", + "0x02f8740182093384773594008515a73b6200825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e4387059a4ae4a761d080c001a025c5f09b3ebea185133df5a68124f8fe524d07cce849ee74fb31e0ef27999685a03abbf03958bad0a1ddabc778268af404bd735f93772561b3273a205bae0d2519", + "0x02f872010e84773594008515a73b6200825b0494a9d1e08c7793af67e9d92fe308d5697fb81d3e43870599cead3a4b8380c001a0137ee0d80cf0d1c764fba84c2ee695c8e133108ac1d7c182d1936c355af6e699a05a0ee602e18285c685812e12053e9cf06f76da18c2d337f840c33d740164498b", + "0x02f876018328af2a8477359400853a3529440083015f9094a93eb99caf4570eff900d1178c1d7d6a80b1c5d68710aa62945cd80080c080a04cf98bd8f135ba9e1f9a9dd1d7e5a50c65950d47937313836117736f38b0dc94a031785f37f35d8e76135191b5c28d1bf25191a266d4e6bc37690fb06d1b6d122c", + "0x02f87501831c5b2784773594008545d964b80082520894135f0b874d2a810ab545f18457574860a1d41817870cca2e5131000080c001a057fa557a78037aafa623a1bb1d917e9bac86e69228c40b9749f26ea8186d8ba1a0102ef4109e8ff9bd67e234919c4ed229d293eb0444efd68db54258368e2ee73e", + "0x02f87501831c5b2884773594008545d964b80082520894de0932875d9eeb403f327125f86614b70d57a903870cca2e5131000080c080a02064189b7fc268be45dc602bac349a611506b81be7d55448005b9eaa67d8679ba07f8cf3feec39cae186cf38afa3d53c1e120ef2e49f7e3187d26934db422016e9", + "0x02f87501831c5b2984773594008545d964b8008252089467006f2c487cd503539491b383c63032a8414397870cca2e5131000080c001a02bbc892b61976edb8b03229619ab408bb3f310513e36d2fa8184c5fc97e17b48a05ce6b50aa0d6e7f0837790923574e5590076680e35a6d040f69436a105d0de5e", + "0x02f87501831c5b2a84773594008545d964b80082520894b880725c8191ced33e344ee794d01d7df39d7fd1870cca2e5131000080c080a051d8d2705d2e2460bb187aeabb4986db6de4abb8daa965a10ce4c9163a2149bda069f970b13513455ddc34f76c4a0820adca2970811b9fb3fa4d8f36ecd44ce209", + "0x02f87501831c5b2b84773594008545d964b80082520894188469409bed858db50465c9e3b1a2d51e62afd0870cca2e5131000080c001a0bf669fc5a6f5782fb321065b96e7419acc29d0959cbd6975330f06df2c075ef7a05542db702f0ba5f8d38c47322af0f412dd8fba2c717f7ab1ff2473715cafc00a", + "0x02f8b3018221f884773594008517a2d1caaa830186a094cf0c122c6b73ff809c693db761e7baebe62b6a2e80b844a9059cbb00000000000000000000000086d2929645aa65b01931857d816b9fe3c7df1c3100000000000000000000000000000000000000000000000000f78176af9da400c001a04ee2ce0578a7fd506d7c0aa61b1fe468e28d77d8e4dfd8af21dee6c01754357ca062722f6ab2bda05bf3443774af3933e7f552ccdbd174c2da56a1eebff4666c1a", + "0x02f872018084773594008515a73b62008252089477696bb39917c91a0c3908d577d5e322095425ca872f470281e2500080c001a0179114a619096f5e3c451784184ed2e11897cd108e9c6e2c0d3446a2111446faa00f2f8428217ac1a36aef0952c8f18038df31a8830937d9d4cc8d34ad37a20353", + "0x02f8b4018388941d84773594008517bfac7c008303291894a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb00000000000000000000000004b888c81c747fd2fb04c96e2c314e59598f326000000000000000000000000000000000000000000000000000000087fe000880c080a00b27d31bc9ddfe8ff443f8b81fa502562109e37c6dbe0f4e61f3078fd0d82f41a03263f94c0b815003b9c0522b0318ab651e3f56fa691dd340ba9b7d5ed8765bd0", + "0x02f87601838ceae184773594008517bfac7c0083032918940b5b51be20f30d22024ee7595513fc7b11b31e2b871b0028e44b000080c001a059d21c8d2aecfa0b2ade92909ab54d61f93d64dd0c1a0c3be26caf0d8c95166ba042eaae0da63176afa7661d9156302a67c6feba7d576a59e56bb4ddca4c403cf4", + "0x02f8b401835c488584773594008517bfac7c0083035d1494dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000f6a78eafd03f38d1a7ddd3bc3db91a8e1b90072c0000000000000000000000000000000000000000000000000000000023957f40c080a09f58532c3d3c85a6ccb155e9a454b2df9cd64e92b8d557817e6d24e50b02a8aba0374bd38629cc102ce51151f0eb2a52bb017b3435904b157ab50c2cff8d810d4b", + "0x02f876018328af2b8477359400853a3529440083015f9094bcb6d31e3363ff68e213169b50a5b2650646f79b87b2c2fb32d6940080c001a009d20a97f8e39e9dc9b364686548505d073dc00d8e4dfada8ef727bbda392372a06ed4dcf9c2d5f9f32bb3179ea3e4de9c525c19b8fef7d700ae1df759a735b4a2", + "0x02f8b40183064e6c8477359400851087ee06008301d4c0944b9278b94a1112cad404048903b8d343a810b07e80b844a9059cbb00000000000000000000000065da6725d8be6090b07af197969ca64720a79853000000000000000000000000000000000000000000000439387a52dc6e040000c001a0f832350a8a3fb47e51d14c28480bdb6b2b2bd3338e57e6853a38dd4739118022a0446198ed466d78e9ef3a23efd697e1c7ba8ecaaa8abef2e8fd47d2cecb1eaa2e", + "0x02f8b1011e8459682f00851791a15f08830124f894514910771af9ca656af840dff83e8264ecf986ca80b844a9059cbb000000000000000000000000a2f90b06b1d36a0b075f5fbdd7ee2c091ef7610f00000000000000000000000000000000000000000000000244fc7dc57cab0420c080a06a79dd00aa022286b27ecf31c88fceaaa679dd217eedfec091175054cc939d35a02cd5f884ad8ccefca82afe2be8569942755ebebadd77b96d3f447e5b0076d428", + "0x02f8d3018302d8bf8459682f00851791a15f0882f2089446950ba8946d7be4594399bcf203fb53e1fd7d3780b8648f975a6400000000000000000000000064bc2ca1be492be7185faa2c8835d9b824c8a1940000000000000000000000007b68226938b4db2d74404caca4e8d9ce9ac6dfec00000000000000000000000000000000000000000000000ea5c73c6b468c0000c080a09fc0f6f254d609ff633b7a861d1b9ee2af583a97a905178f32cffe0265c10701a007b522edd88729c7451963d6da110c1eb1a932cf97d986bfed89ee1979a2be46", + "0x02f8b20182068b8459682f00851791a15f0882b770947dafe897a6ff1d7b0b64f908e60e8665b61d53af80b844095ea7b3000000000000000000000000ed12310d5a37326e6506209c4838146950166760ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0356435050fcffeb158c1080d94b9ebaa18e351b38015de9d047785c857007415a025eff1463b90980c67bc18f7fa1d6f02b025e5c14b567ccfbe7d38e41e518f6e", + "0x02f8b001118459682f00850e47f0e56b82b5a694cc8fa225d80b9c7d42f96e9570156c65d6caaa2580b844095ea7b300000000000000000000000064192819ac13ef72bf6b5ae239ac672b43a9af08000000000000000000000000000000000000000000000000000000000000afc8c080a098818c0328568bff1b14d823a5dc4bba9341e17ce6f4f7226f02222903764800a031662073f64f3f46457c1e2592bdd682b1dcebf753b1c9acd349249f4460eef4", + "0x02f90374018252388459682f008515699cce3e830f424094787a0acab02437c60aafb1a29167a3609801e32080b903048c3152e9000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000028e6000000000000000000000000420000000000000000000000000000000000000700000000000000000000000011dd2d9b5ec142dbafbefea82a75985eae4e12b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031b8000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e4d764ad0b00010000000000000000000000000000000000000000000000000000000028e600000000000000000000000042000000000000000000000000000000000000100000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c5740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e40166a07a000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000b9d571c1ec576300f01ddfa5a082d9c571e45e360000000000000000000000004d44b9abb13c80d2e376b7c5c982aa972239d845000000000000000000000000dbab11a841ef6b2761acd76c3b9eaee847d7381b0000000000000000000000000000000000000000000000000019ef4fb2dc400000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0a1dfb511b6859fd0ddfd7576a19469b12907866f287d624ea8f3c9039a52a80aa0052f682611c33e9d39e1fb9ce815ffbe30463142e366f8b1bbdc8d00c77dec48", + "0x02f8b201826a44843b9aca00850efd30b58282f88c948881562783028f5c1bcb985d2283d5e170d8888880b844a9059cbb000000000000000000000000e12670fd59c315cc97ef77cfb3d06065b78f85b80000000000000000000000000000000000000000000000c3a88f6c9983bbc800c001a09a61be61ade365fd0557a61c0dc454287ec70f13074f116831980f010f79c511a024c94f6dc0b710695d878c9040f2204792e1ffc61d2436e6f8391963e0a2c017", + "0x02f8b301823566843b9aca00850efd30b5828301482094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000005edcfa1187d1e0216a0dfc7c7898a9f0f556039100000000000000000000000000000000000000000000000000000000014acf80c001a01d5ad3c53e8ffe2cf267d68366ab3072e97d0ffe5ce22fc729b6e4cdde67afd6a04608dff99f61af02858d52cde53a559a6884cdd232b9e05fa9e20b0e5b38becd", + "0x02f8730104843b9aca00850efd30b582825208942df9b935c44057ac240634c7536511d8aa03028d8804f741fce15f881f80c001a0092f5e983fa9a4c057919ce3dbe03f77ecc26fa4c9f32e0247a1c3d5897565c2a0785370e61ee455422a2347c3730cb357eb5e123672c66373e2b936ed6f48e3fd", + "0x02f874018272d1843b9aca00850efd30b5828252089447b6897359d31b648a10cf9a3e886400288bea3987279e861cce1ff480c001a08f303dc0353ed26eef5574ec2cbff01e379c32cd79f26f0645b9e152748435b5a03ce267967e335b7ce2df87bab4892385f9a1c9932927e71e9cd95111a73cb50c", + "0x02f87501830f5966843b9aca00850b6cbf811082520894c406a13e82c5a57fee7a68b4508ee07ae0de74af875535d1cfbb478080c001a0dca00e515144ef862d5a790ed8dc27bd36d7b93cd14765c4537862d8bad3d9c6a058e8ff7ab4aad2c8682a910f666e643d432782d71cb9f4a49536f6d646fa3cf9", + "0x02f8b201826a45843b9aca00850eaa1cbcaa82f88c948881562783028f5c1bcb985d2283d5e170d8888880b844a9059cbb0000000000000000000000001417177c3ba9187d90ab76de062cff18b4b530b60000000000000000000000000000000000000000000000c146e25f2f4756d400c080a04be2fd58f9764c65133f67a069b1078b0545e21c523b4851f1e5ef5b869fc3c1a0665f85c3edaabbcd27428c2f2f30a8f9788905d43e17445962c305897620e123", + "0x02f8760183087e39843b9aca00850eaa1cbcaa82520894dc5a0c7470b5671567771901b080ce608749ce2b88014b62071e11c00080c001a0c842ad8893dc8b1fa3833f429dc21fbe59857ea78cbef9ab93811ac8caa92830a02f33ccf399e6f1aff96affdc3c760ebc3bec06bd2e553d57f187e5cb38038b77", + "0x02f87401824169843b9aca00850cdcbeca1f82c35094672feaaeff55ed395e43f93a875d5dedbe3692498709a6dd2c01f9f080c001a0db911b0abd3e61460d33631f8cbb3ebc3f05130409a6cae91edad110fd39c2f5a05459d7ff083a838812ab756655e617f91132e8a3ae38d83a71275c95935a4db9", + "0x02f8b201826a46843b9aca00850eaa1cbcaa82a660948881562783028f5c1bcb985d2283d5e170d8888880b844a9059cbb0000000000000000000000001e7127c81c8a58661a0811f026b6be66533934be000000000000000000000000000000000000000000000069bfd250c6a77b1000c080a01de08434bcb35698ce9f348edcea70b4b9d32874771d599affa459e79b87665fa052504ebdb3da3d075b1b12c3b5fa1ab146467c2f7005af524d7d621a3906d272", + "0x02f87501830f5967843b9aca00850b6e4de1cf8252089439d7e80ef17afe7261b947c9529b869ba7c88045872853aca2d8700080c001a00466eb79832050fae55fb33067b7df7d45853f6d6bf52602bd1a90dc5137452ea04914e94face76b18820ce5db22c4c8be10b0d44b5b416b9ab6e8352272120234", + "0x02f876018302b841843b9aca00850eaa1cbcaa82520894944311875ecc192445654b1794fe48ab54ae6a8f88054b7b77377136b080c080a03e7396b978a14081cd3e90f0fb592687d11c2559805d4444d5403e5420766d4aa078a7006e9899befd664a084f94de1c69a1da9977f694b94153476cb2a4fa9766", + "0x02f876018306c414843b9aca00852098a67800830186a09464f961eec2ba222dcba8fa354f03e27529b96f5b87153ec73fc1c01b80c001a0583dc990d273492b5c74d3c94524e058f7de47042e4f92cb35b11c3b4dcb0e1aa0180e393a76b3d6065d0c55e625cc82da05c7896801d95c64e99a91b7fa170a5f", + "0x02f8750183087e3a843b9aca00850ee4b80f4882520894136e2d4c689617daf7110c53a32b512a9acb20b8877ca8599fe1000080c001a053f72254417682846121f46cb0d828d3536b027ef6a4894a9339fae216e62291a05df50338a3afd9db52bee8fef6ba4563e7148259660d385bece9d58e99f31ebd", + "0x02f8b3018189850a88b2e61f850a88b2e61f830493e0943071be11f9e92a9eb28f305e1fa033cd102714e780b844441a3e700000000000000000000000005c17b7bd70a80ce3fa7221aa1bcbf62de3985d2e0079ee7d871797a521c7a0cd953e51a1f079ff3d3a0b02a4d63f995258fcf0efc080a05d6371050d017e140b78c4f1e77b4deef02960c04ab29c9a3540315adcd12f44a05b1a7e67963f6838afc484c2b742e70b9c6a019712c1d2f66ed712ca956b43b5", + "0xf86b01850a88b2e61f825208944d24eececb86041f47bca41265319e9f06ae2fcb8757edb39a8dad978026a03d319923d281a9a0e87f33c43f419f75ffff2d2ab346fd0034528a2fb1ead3aca0046b56de8266ab78e57c448e451c51f372ece5f9600228d09b01bf4e7387218e", + "0xf902eb44850a8590080183037460943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2ac630000000000000000000000000000000000000000000000000000000000000002080c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000152d04202d703370c47900000000000000000000000000000000000000000000000001d45d9126f3dc9300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000d1f17b7a6bff962659ed608bcd6d318bb5fbb249000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001d45d9126f3dc9326a0fcce90823efc87c96d390627c0e1b553b98739665be61e32dbb619f62e0627f0a015432090f7de23806fa2f6bd067c92643043b198507ccd29744366661ca09816", + "0x02f8750109842a51bd80850fbc9e4b40827c4b94f70da97812cb96acdf810712aa562db8dfa3dbef8703c619ef1625608319b786c080a0e32c688e8524736de4a3dcd1b687fcd7275239d6c6b9a05db426f73656a073d7a07c50950254c39fb0aaf410e0af41c12c0a7ece32c93fe76a783dcfabc20d3a7f", + "0x02f8b00113842a51bd80850fbc9e4b4082b15894aa6a914c605f9134a8480745729c6d0e00be038480b844a9059cbb000000000000000000000000dc1a50161a07c451629356ad5dc2c488b4bd05f800000000000000000000000000000000000000000629404873eba963786b37dfc080a08b66989e3401856b05bde57c6822409b5697b06de8e49ee068105b2af9441c87a00bb782a16dcdc72223335211fb34b703c5f0a636530839f150ff88df372e041b", + "0x02f91874018234728429b92700850f28c4de2083114e6c94b2ecfe4e4d61f8790bbb9de2d1259b9e2410cea580b918047034d1200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000178000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000b4d24dacbdffa1bbf9a624044484b3feeb7fdf740000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000154000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000006f43b26ba724ae3ddb0c55536d64e5f985000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f9493c46d9b905e227ecfc266752eb7c7aef4cf5a8fb4e84018df3536ce8a172f9e700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3d71500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8849281b1971b7d614adce8504681ed0000000000000000000000000b0a206794611892587e3b0df04a64239e2a3490000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949a0c92bad50dc3bc9b7103be708607112c3cb42d094333215bc030df903c51e7c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065f2aab4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bceac2eac4cc05b5332bc268aa69a140000000000000000000000000e71c843ce2c374e3b7bec768fd3abc8b7465b56000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949c3fdd6f428a207dfcae4fd4e947ae2782b9af579b42ff22eff9c133e250a8b1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d355cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000afef5ebe12de0c5895cb43a34c417d600000000000000000000000006d02ce0cd50bff383035e1de5c8b2235fb22e4e8000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f9493c46d9b905e227ecfc266752eb7c7aef4cf5a8fb4e84018df3536ce8a172f9e700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3d6db00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f9badcb58f445cf9a7ccc096fba6cdac000000000000000000000000da714bfafbc2b139bf6e91d9809fac5a104a9798000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949c3fdd6f428a207dfcae4fd4e947ae2782b9af579b42ff22eff9c133e250a8b1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3d1a800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c44722ce8a6747a4096e0c79ccceaa9e000000000000000000000000f13532cc8f5c700dd30f9faf8b833b38cf78c7d6000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949c9799823cd012e2adc57aa64008c7af4b388f9a6b0fb7387b1c94fe217238bef00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d311e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008583bb513a7f4bce368f190cb1e0d2df000000000000000000000000f4ce3f01788a6066d38145ca5995f68ed9128e61000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f94935952892cf0503d50413209caa900477ad2cd683d3d31d61b83e779afc67082700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d311e700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc3bf7e6e1de2444e4eeed5863070e90000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000004c38000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002f51000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000002c8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002eaf000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002d08000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000021f4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000031c2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000003807000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000023cc000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000043280000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c73f69c4c2d9de81380ffa825e2723744a750ea770c2e3ef35a190cc0a7e651bb75ee9a54a45770d7a514920819c9705553754efae5ebfe25d4dca57bcff8fea051bd4f747cb65d2d2aeb491359c61ea62974182170bea195dbaa357bf5673d34a115bc8026d7fe931bf2f2de05956701057b186a862dbbc5e0f7f9bc5aec7edabcf1b4f8d7e9f4813bd2a40f2dc56fc307e44f13b15400b20363b9773e3cb55519221325bf18920f7ea9470aa9571b1dc14d88507846f8fa2f567972aef341535fa971bb4276ca35a2e0efcf6a9a439a2dae85ce62e0af254c3f32fc8c1e52f6b267cf642f87e72034d240cc0c72e797d6a0a66016150d84df2bda0afb639a03c1284541c3372aa12fdb1c96c09df3bcd793d31fb92bdafaec82bac791c22090ba6ba0ccd021ef04e8fee62420bbb46448bf6892fd7ab623b7c9c3aad3f2a1734351053331baf3f6f03d04af9b9693ef440db14efe5fbddf364d311386a8149aa6035f1c89e08cad3ea9669e663b95636a07406f0c1acdb6458099cf3d3cd1f86fdb51b8e531bab64a8552da0eb41c74617033a5ef07296ed49bdcfc38ada79a45193544beba46affea94c132d9f59d7209003fcb4b7555c114486168fa265a8814959afefa691c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000592d73154611fa1946c16daa7834137449258c80fa499f4ba58070ba1e9c0cfcd5709885a5e3404a4e9c79df8b1b0d87983bc23ecb90643c8cd07eb93c0ffc81ad1c0128819a6af68e5d010513ff70a3aaed9afeb8661116e6ce00000000000000c080a0f63d057c9061b69c3001a666186f91fbcddbce1afaf6ee053201f1f913cac64da018b61e9fd0dee1a2a31b0647540392dc5b139f4909a64857f2e7f51f341f2fb4", + "0x02f911f401823473842a51bd80850fbc9e4b40830c5d0a94b2ecfe4e4d61f8790bbb9de2d1259b9e2410cea580b911847034d1200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000b4d24dacbdffa1bbf9a624044484b3feeb7fdf7400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000006f43b26ba724ae3ddb0c55536d64e5f985000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f9493c46d9b905e227ecfc266752eb7c7aef4cf5a8fb4e84018df3536ce8a172f9e700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3d71500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8849281b1971b7d614adce8504681ed0000000000000000000000000b0a206794611892587e3b0df04a64239e2a3490000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949a0c92bad50dc3bc9b7103be708607112c3cb42d094333215bc030df903c51e7c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065f2aab4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bceac2eac4cc05b5332bc268aa69a14000000000000000000000000927192c4158bbfd98874ef9e781abfff43bbbb5b000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949ed0e627242314a2d7fd604ff2614c48994ba23e090f4bbf517ce43210f2cc8d000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d31d8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d0e19226ecede1101d9f454860067a4000000000000000000000000a3b3acf61034ccd05f204e24e5935cea4d291065000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f94913bb5cbedf2f3d8a64e1efa7a0ce0e1e21c62daca139a8ed77f521f00c7c5c5c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3cf8e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ebc11bce224cc654fb2acc8f5588dc0000000000000000000000000ba3269e784c087c2c427c62499b5badca6775dcd000000000000000000000000306b1ea3ecdf94ab739f1910bbda052ed4a9f949a433df76e7d352a93c61a503f86ce9192b1857b4f25470be2d300b1fcc0aee6f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000067d3d6da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e82a9ff9a7afd0165c2f7a4f4c797d4e000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000031c2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002e03000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002d08000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000023cc000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000002644000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000002ea11e32ad500000000000000000000000000000000000000000000000000000000000000004328000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000021f40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001453f69c4c2d9de81380ffa825e2723744a750ea770c2e3ef35a190cc0a7e651bb75ee9a54a45770d7a514920819c9705553754efae5ebfe25d4dca57bcff8fea051bd4f747cb65d2d2aeb491359c61ea62974182170bea195dbaa357bf5673d34a115bc8026d7fe931bf2f2de05956701057b186a862dbbc5e0f7f9bc5aec7edabcf1b37ededdda37a8706ecf2f1690cd77abdd471c03dd6ab290d02ba01b823c05c0a52811707d9bc26a609560435d87c4f65fcc62c2ee12cf47b091b2182ca5528e81ba7200a3acc4243d870eca358f2633b96d3a148c8b02cd9ddcdb38eed07c83e7e15fab344e41c7797e7c911aa6b9b22dd8545e1f7137e372fe1e6d9ee8fc17a451cf2bca54a737139fba92b3a95e37c503bf5421cfcd2c67b5119635233fb1263b6292d2390eeb32a5faf40d931b26705a5c4e08ff24fbda17cfb716cea782eec101c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000595568309a8db19f87180b74a21c4a665f80195e9107b8f7388d4e294c174d1fc00ccdc2d240c9a974c3626a307222dc9a05a8ea4551e90390f2f3b6cae42bde6d1b0128819b6af68e5d010513ff70a3aaed9afeb8661116e6ce00000000000000c001a09c538b5a2e4536a0b245e793dc7040a24d1e61893a9faba926263466dd3e3935a03134ee529876102b69b839f33061aee638fb0620c0b596aa3257668c80d89a23", + "0x02f90232014a8429b92700850f28c4de208307a73f94ba12222222228d8ba445958a75a0704d566bf2c880b901c452bbbe2900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000086b1fc73244a6df1a3cf0accdd1bde525932d630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086b1fc73244a6df1a3cf0accdd1bde525932d6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a333e9b15e9800000000000000000000000000000000000000000000000000000000000065f2c1db596192bb6e41802428ac943d2f1476c1af25cc0e0000000000000000000006590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf5495efe5db9ce00f80364c8b423567e58d21100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3065f8bf46c54a500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000c080a01bd842010f6fab9cb92eee450a25cf5e359cfeabaf30314711241afe67ea3b40a028f8b7474cc42e1e2dd6d3f1c8e09baf2208cc2f49671a7378d439cbca280384", + "0x02f90259018205588429b92700850fbc9e4b408270189400000000000000000000000000000000000face780b901ea1f8b080000000000000355525d6fd43010fc2f79e554fcbdf6211e4a4b25242424a8c4f37a777d04ae4994f8505175ff1d27e52a9ac7d99d9df14c182bee719a8e3d61edc7e1edef81af0a92d4abfaf8e6e7320eefe6d351decbd24f61f7d48d53b7ef088fc76ed771e376fba7ae8e0d538fe4130b81f33a52a01872525a01d9e01c526224d42e09a8c62ca78156b5c6432299ea975264feded71fdffac380f5344bdbc2f9b0acf7c77578ff6792b6feb95f6a3f1cda74433ff1262dacb22d4a078739836072458b06efbd0b5e025fd665ded6db34dbe8b56129042441454b6255114a9a2805106fa3b8469b85faa997a13e3fd144e500cadd87ebe074bc16367297b48b51e0f6d6d80846df02c4d5fcb248bd19873a233d939d684162029d2403281320816305585a5258ac269f635017f2f6360dce5c807f117cfc7ad3642ee0f5c3785adde95d47e3b0f42cf356e4fdf84b864d5707b0de29e3ac40b2590900291bd9618cce4529c51bc7b426feeac2cbe5a85e7fbb6ea938d7fbfe4136875ad9149f8dcbc0ffc1abe8062f2fad6e41500066d6262150292d6fefb34d5685e27db081452144e6dc82454e31a7e4028362d78a31e25a62a684e6dea269bd91297a6d5c38a0581f122b5b0058a5ec20e8f62b72146daccf2914a6023a77e7f3f92f4b751e4efa020000c080a0e1cfd7ed04ba71a4b1b784a44fba06f4e708cb2613fa89197dcabe0e1ce1fe7da02aac895e125f07125572d4e28db67de2f441e762137f696a8cca3207f48e65b0", + "0x02f8b101028429b92700850f28c4de2083010ed994dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb00000000000000000000000092e929d8b2c8430bcaf4cd87654789578bb2b786000000000000000000000000000000000000000000000000000000001d77caf0c001a0ffe55b891ddeefdbc515ec2d5e98d303ee7deb39ed0954f7129310565dbdc3c5a073952d6a0c70886478da9d6d639f86c5721a6b255074ad4515489b2fa0e678c4", + "0x02f87201018429432e978510eb53889682520894d455f7c9898cacd7b1f820bb45dcaffd33d030d0873596be64fc0dda80c001a0ac5c94daa1e787f2919b8fbe5c959d3c2e4ac493d338e416d26b6175f9f5ce80a058052f807831749e38bae86b0927ba765e7c30307062866a16f3b60b5175b72b", + "0x02f873015f8429432e978510eb53889682520894fb228b655d106c81756b11ff07baf93ac8b9a8058842c1bab096b53fc180c001a0d8c479149bd51784e376abcd3ebbfb7700af5180f6103c77747c621fa7b0ff6da07040b9a753018bfa5f0d3709cad09be329c069bb11778292e9f5779268fdf6e9", + "0x02f87301088429432e978510eb538896825208949031943751e319da09ca948ae56b0a67118dc41988015dd990412daf5080c080a064d860d4f407c5d941d2f583795e75fcb74539dff0e21676903ce0d89e5afe1ba04434ef0234fe4871b82fe539e4bfea525bb4c4c536c2a64449abce36d05bdcee", + "0x02f8b001208427f3f16285108164a99382ca25944e3fbd56cd56c3e72c1403e103b45db9da5b9d2b80b844a9059cbb00000000000000000000000030f6759b7db6596897116ba606d7eb580cb1c1670000000000000000000000000000000000000000000001c2c84c5a9fa6a57aaac080a02ca94a07d61c94c0943da11b479bdcc6940601339aff80c090fca9f7b8c3836fa00c3aa253bac32d13159fce078080e9701e8d4b31b946c714deb80c36da1416de", + "0xf903ed82013b850a7a3582008309873294c36442b4a4522e871399cd717abdd847ab11fe8880b90384ac9650d80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000a40c49ccbe000000000000000000000000000000000000000000000000000000000004b51500000000000000000000000000000000000000000000000a51e89a8d0bbd9b69000000000000000000000000000000000000000000000027fccd3250516a761400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065f2a51f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084fc6f7865000000000000000000000000000000000000000000000000000000000004b515000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c00000000000000000000000000000000000000000000000000869046150d3310000000000000000000000000fa2da36193c5d80829529fc71bd0f2cf63594776000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064df2ab5bb0000000000000000000000005a98fcbea516cf06857215779fd812ca3bef1b32000000000000000000000000000000000000000000000029dd40184d25d9c21f000000000000000000000000fa2da36193c5d80829529fc71bd0f2cf635947760000000000000000000000000000000000000000000000000000000025a03dee2b757a75890d31b4e1679cb51c85d9809b2372989e5b313fca97f0686c22a0482b6532923cc89fe72d58c20a5334384edcb9b3bc7eea7c4192a25dcadc366c", + "0xf88e03850a7a35820082b2679400000000000e1a99dddd5610111884278bdbda1d872386f26fc10000a4497ecfc56d31396470707265773637000000000000000000000000000000000000000000259f04b55ff9c08d6a62858854e9441b9c3e477ac8f7b41b4e3a3fb1bfd5380ba0a0787f4bea2be6e65860a3cc6fe9282a6cdde15abe7206957b11ec1132ae0edc1e", + "0x02f8930182011d85010c388d00850a7a3582008302107d94feefe92e2192cf49cc0bb75f4c0f044d3313370780a40e5c011e00000000000000000000000044d585fc510c5d30d909d83563fec8a47d8d264dc080a0cd3f4c901dadc10dee9816c19f24f8b7b6a97e985ce54f441d15cc633167049ba036d90a8e25e7d2400b57f84cde0358535c4c06619649d36630e3d52692ac6f57", + "0x02f90332018084258d0980850f574a5a408301351b94d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef000000000000000000000000000000000000000000000000000000000000ac510000000000000000000000006be13e25bcfa44b43ed359c9a6e436eba0b083100000000000000000000000000000000000000000000000019274b259f654000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011b72dc4e4d0b42a6839af67ca600078e35248b55f38301a4cb184cc526fc904aa3441c8b9dd1d18f328cdeb1811105930295f25af268937acd71ebab1d5dcd079abcb76e5db2538ae47c4e3538c86ba3d88df9f1f709a32eb611492f3388656feacd2140d70724bf1f7297d4cf7a027d6e643e43d939f9c522ec165bdfbad171e653f63ffa60a3204bd246211f0f2f99b37d6b1944f6f33d001a512502aa1a376829d388ec86b231c68730723bef51c856adf24670469cd9063d2fa37db902198b64ae6788fa19e5787a2c9281d6f98ea6cad20553c2fab031e9dd531cbb726f1aa35b2c66d55ecbefa599d6de6c8efd717848ebe6abbaf40cb6f9e07882a2b7ee9069f62d1461a0ba3fc962021e63a9d0a98898489d6bbd7220a7aaf4974f226a3c43ec7e0b18cc01a74c3f8e7603e3465925484e6c5834c0508cf43f278ea3607ad21985c0a7b220c77ec1c4d2ba832cd5e2b80964ba4b60ced2b5967de3919578d7be013075f6f887937e87075ad37f49a82d0be743328564015ddc49e3faa3a2daa97f744d166ab5c9b170efc3e9fcf70d2dc968e4cba43ba29ed414753c8439869e225fee3df7bead8c9c011e7e36996bef45fc334cec3a7b3dd000cc2801845c13f25cbba3d726231691cc1678de0936fe89df8d408c9bc344d58d0ae0a46e70d0e09debcd1ba9ca8ff28fa3dcc7b1318cdac64c0b387c56304d964a2f86643f31da169680b58a8548f4d3144a13fdb0eb53a2844abdea2d4a0c76a82ddc001a07cd7e54a4d194ef506043559379c2dd6550d67dfa1c8752cf9b9b5125d283c62a04b1e25140455769f5a453696600f4a764ed8879c36809ae69d57ca4798cc9223", + "0x02f8b10101841dcd6500850b398a3880830111e894c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280b844095ea7b300000000000000000000000040aa958dd87fc8305b97f2ba922cddca374bcd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a055c69b24a62cad13ca6d1a23f10aa931c025176fb61df1c5d4ffc06d5aa6b11da07592433cf4b012de8f5676c7a0fb9d88fa632b29d8e7c176236fb72c8cad1b48", + "0x02f8730181a7841dcd6500850bd22a8aa6825208943a9b6fe84c1d10549d234100e301c43db576ebbd870be1fb16c5e74580c080a02fd8afb784c727d3b0fcdbf9059b1f8b1da148073dac76d3dc1a97418fe64252a07bc8a7681d9aa2e4c8f4cc81e96decf5e1bad3e72f4dfad8e53961ac6f5a7cff", + "0x02f9063501820257850a6d3076f2850a6d3076f28307a12094fd9f795b4c15183bdba83da08da02d5f9536748f80b905c49ff802a7000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000e3c2881d0c899a44e610b0f6ad13e5a240eb28910000000000000000000000000000000000000000000000a030dcebbd2f4c000022fdde52ca166b82dbda5ed31925283641de12ef678c571eb359dd14941475a300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000420f63c799bfedd6fc5dfd04b51c99001c0edc8171c4ccf30e4ed26e29dc468e9020000000000000000000000004f42cd614516409e9bedf91a6e94dfe8dedb3570000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000412dc0c42432bdb572655756bbfdf0199ea3bf178aef3fd7d3357872d2abfaf00b44d0f0f6bb07afdb697cd5e39eac02d44b9e703b8a39d714cf09c396c38c37491b00000000000000000000000000000000000000000000000000000000000000f63c799bfedd6fc5dfd04b51c99001c0edc8171c4ccf30e4ed26e29dc468e90200000000000000000000000079182fb1ebbc09f2b8aecfe2dfbf7dea40b4fc6a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000041e35381ed52125d436e4e3b649054197faaae99cf696f8257f4be2e59b832431e01b9e2c73b65f6e7f497902fe7b134e684e206c01fa89993b86c2d86a041908c1c00000000000000000000000000000000000000000000000000000000000000f63c799bfedd6fc5dfd04b51c99001c0edc8171c4ccf30e4ed26e29dc468e9020000000000000000000000007cdcf0e56aa0f34d844a03d388c1874b6edaf400000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000417b28ea1fb229ea7359f15dc0c4e42c803bd8823d59ea3375ed0ff55846aabe0a7531141aacd9e2d71f09ab7bbc37aa63c2b0c9bb4f7c44508eb44e42c1dd169c1c00000000000000000000000000000000000000000000000000000000000000f63c799bfedd6fc5dfd04b51c99001c0edc8171c4ccf30e4ed26e29dc468e902000000000000000000000000aac269d7d513b09bf721de748c4969fb01d3af06000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000411c4bec7856f808655ecc0fbdca9388e4b7b05b38e38be145520a0948753005e51812b1c1d14007deba833e8ad51f41f4879270d8d1b706fda5e2af875d77a9341b00000000000000000000000000000000000000000000000000000000000000f63c799bfedd6fc5dfd04b51c99001c0edc8171c4ccf30e4ed26e29dc468e902000000000000000000000000d8d8f676d5479c4cdfc27ee7ba370a3959308ff60000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004184b80bf38da6bb99aefaa2770c0394c4b7d4ecb948972aadfa8aa5f5ccf106ec7593e8bbd30f8729e7d45ddca1a3608da27bb3b4e54c860e91b052ff29c71a3a1b00000000000000000000000000000000000000000000000000000000000000c001a0f89dfb9dd5727a66d815d1f37ab709f8e925199dcfa1ff28c4e5ce9d384af582a0728d78422b1bddf958ce2462a61a7ed831ee7ec872095394ffb153aee4775cb5", + "0x01f87101830a6d8e850a6d3076f28307a12094b05178ed26b624875de845e07a8eb612d14097e1872ec391d29f000080c080a0ca6269197e71623f391827c2020871d611e341f74c12ee1d13e274348cf8c996a0189ff08439030629c395d59fbaaa626b4fdc37744b94a30f6773ed3e4a31420f", + "0xf86b02850a6d3076f282520894a32de314c33429f9b83d2f7b516b597b19d5d520872386f26fc100008026a05a7bfbdb0d54db91077ce176d6469fe54a69dbcbec926dd3f7dd028db500b6b7a0473734fb8fec5db3778b1338aa30803aba5528bfb9dd33d2284674974e475a29", + "0xf86b05850a6d3076f2825208940297567c6d98ac887a6e2abf7ca5beb65bf82663872386f26fc100008026a0f8e2555b04b2b4bb471d827f27c50777a72ccdd250ada84d485c71d14184a851a055b80cc36821435c8699fc33274a98446e575457ee6792fe6edceab500a9d080", + "0x02f86f0177843b9aca00850a6c97e07282b54b944679b663b018b6c944da502031634ec1ea96a6fb80841b55ba3ac080a06beb45f3e17dd7b13c6953de2a8da57e977b2d10ee93ba5f9c5b230ae5bca80da066a0b33596cc99ff61fb60721c115e01dfdd6fc8f603eb575bd93f0e2e6cedbc", + "0x02f8b001178414ddd4e78510d6ee2ee682b42994dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000003522965bf958bb753ef12de9629a8e453e0d71f700000000000000000000000000000000000000000000000000000026b545ae80c001a05fd964572f3d2b7857c84467e656f3cea3d9c99d25b76dbf97634e6509d66901a05c5ad6323f5c0114d0ab0a7e3be84032e8475444d3984b29bb2b2cd6da5445d1", + "0x02f877018226318414936b2c850cd2f622d6826270945a3fbda16754664800a638ae25c689c358ccb1a4874a9b63844880008319b77cc080a0c3ef28405b34c3d54c32e56987899212fe8106536d9742acd0aadef4b631e140a01e85eb7237502a2bd4b4b655892ea7a0f8f511cf4efa7fc167a46618d930ac07", + "0x02f877018226328414936b2c850cd2f622d682627094a7a50fea91fba3860fb86ed3610a5150f84ab7fc8740a8cdb6e980008319b781c080a056364c8dfea21baac1cd2643de6596d091e5ad91bad0c956e75fd3395e817825a00f347b03af3be43c67a543f0449d885345d6148df5e7499f577ff334e7a65814", + "0x02f9013e0180850a662dad61850a662dad6183023463941111111254eeb25477b68fb85ed929f73a96058288016345785d8a0000b8c80502b1c50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000d97e29537a876cad750000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000180000000000000003b6d0340106b3f201f7b152b3239d2d443b1b1743b108b743c748c39c080a07c17d816c90cc71a19c56c4818d7c97112fde84d0b10b6e0e092e54b7da5d18aa051cef64e0fecba40c2ad98875987d1a2f557896fc7f0e59401301a305cd7e173", + "0xf8a949850a662dad6182f2ec94db82c0d91e057e05600c8f8dc836beb41da6df1480b844a9059cbb0000000000000000000000005c549e582566fc28f88aa54b0421d5f9093c90c1000000000000000000000000000000000000000000000001a055690d9db8000026a08ad6d0f6fd5b12e0c7d89dd6715569de7179d6a6e24cffc568bb56adc2401363a013dd090887c2197d89cb811a1f6aa6f78fbd1afeef710a6923b55876539b536b", + "0x02f8b10171840a21fe80850a773f59d98301132f94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb00000000000000000000000063e3506625e417776e3f83d1121daefbe81ea6340000000000000000000000000000000000000000000000000000000625900800c080a0790f6ef76840fe24032a2591212b926b3925eaf3374a878360fa9fd3c3aee796a06a1fec622e81eb6967c75f7848b711b2a934f7ba09b6a02c57a23797638cbec5", + "0x02f875018202aa8407bfa480850f66404f008252089466c578190fc157e230a7810b1a6db67e13925cfa880214e8348c4f000080c080a009318f77023c606cf6e2ed00d1990ae450047c3f40018629f2f1a1a72feeb8daa076380b6f8553a6f71e66b8d321c5a055fe4869372a9a1ec6eacc3e0ae5e5e46f", + "0x02f902d40182ecf58405f5e1008522ecb25c0083b71b009440864568f679c10ac9e72211500096a5130770fa80b902645578ceae000000000000000000000000000000000000000000000000000000000021015000000000000000000000000000000000000000000000000000000000000000a007295d94422783d4fe7fc43c5e20a5776f9e46e12735c9aa8d47979e40954c74022c2bb7ba287e18bbb1bcad42710f34f0505d45cc102632660dc3580b81dd7b0800000000000011000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d030d8763f5ee5e9f912a63c2e44a9a4b0719c27d9226863d5e0c8ba4e687471007f8b374db3a04403df6611d21e1bc998a0e3e36767edd75507a14923bb7784e0000000000000000000000000000000000000000000000000000000000095de801dd2216b6b224cefba3913dc83de22a9d3b642daa52abff17d46b561c25951405ba2078240f1585f96424c2d1ee48211da3b3f9177bf2b9880b4fc91d59e9a200000000000000000000000000000000000000000000000000000000000000010000000000000000c131ca811505599ca4957903c258741b31aabc4f79ece9f90000000000000000876c27b18bcddf530b38fd396edcfdb15c140c435359d33e0334c5d4f6189e872ad078beac2e8cd9375bf73b5583f722ae89dddfe99d52e6000000000000000000000000000000008c5109350c693c3a2e974a6ea38a07d200000000000000000000000000000000019464e94991fce56f27e855f2c1e5fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a05880cc75fe51c36c156414a3cb71c8bb0e73a0cf62b692dc057b0f15df6f1807a02b3e069c603a9beff43f4be59c0afd2002ee0f27c8d81775eec52a0c43afafe4", + "0x02f902d40182ecf68405f5e1008522ecb25c0083b71b009440864568f679c10ac9e72211500096a5130770fa80b902645578ceae000000000000000000000000000000000000000000000000000000000021015f00000000000000000000000000000000000000000000000000000000000000a007295d94422783d4fe7fc43c5e20a5776f9e46e12735c9aa8d47979e40954c74022c2bb7ba287e18bbb1bcad42710f34f0505d45cc102632660dc3580b81dd7b0800000000000011000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d039cbb700c264ffede35259f488b494a2139ac52f72081eafc46383768e6f54e036455b87817766982a35fe43819b54990ed473b33d1e06da6243dd0f1e5b8000000000000000000000000000000000000000000000000000000000000095df2041d22eb19105f41e51e88f421ff7a4f55af77c78408af37641a15b5db4f889c05ba2078240f1585f96424c2d1ee48211da3b3f9177bf2b9880b4fc91d59e9a2000000000000000000000000000000000000000000000000000000000000000100000000000000003f9a24475b02b33e946ade4cfc4fa7d4deeb303cbb437b6200000000000000008666b93ba6dd4f173c6b5325f26e15f46bbc58160f1e8117001abff59eb9692eb2fe7a6c3f4c46a3bdf97c22689d103b43031a60efcf1592000000000000000000000000000000002a32a2aff1b150e918c96156d91faf280000000000000000000000000000000015b983311b9371ced1cccbe7953e047200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a04bf9ba9a85c626beb6d447ad26e53f70185d9de883f678484d77e8609c189cbea0073cb98e3f4999049403deb809ec6c9c0068aedee833df6e614d0cd1445c26e3", + "0x02f8b3018203778405f5e100850b68a0aa00830111c8941bbe973bef3a977fc51cbed703e8ffdefe001fed80b844095ea7b30000000000000000000000001111111254eeb25477b68fb85ed929f73a96058200000000000000000000000000000000000000000000000e706091ac5abd5591c001a08ecd4015a2c7ac2d89419ff0d895b8fcda713ed3f247929505d803d68eae20e9a00cb7a59bfc73663891daf7a216d9b5b5641ceb68e6c18dd22cf110e1208915cd", + "0x02f9033201098405f5e100850b68a0aa008301cfa094d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000013e4a000000000000000000000000f5d7e9c98b50f79f95cf1ffe4958152001f678040000000000000000000000000000000000000000000000019274b259f654000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011a00fd0174c1ce8ab4546d6b0eaef4cf67a009c8a94c19d12ca849eb71fd192282608c7bbdc2544905d5ae9e9930bd059aa42d46a0f959dad4ac9faca4f798f0abc411d8912717a1eb90b30a4d317818bdc883d9cd8a7190127fe47567fb82acec3eae723a4148abc7691b2dce46761e28cf2f87f5232fed73e590dc52ff30b53b47ab1b175b5b5e551b0ed445fbe36420411d97b9e2a93107106d03b9dd6acc3ccbce6478c3784fd9b4a3621f42f370cef10b05d547896b14ec35c45c7d482805648abc7a4e6d0b16c1a1507e1994556e4e2acce89374a35ae0c061b645091425fe80ef85bc3e331bbaeb3161c2fb1dda6fc18f857831e23c927451f437d1e7d5937f65a1900a8336a53cda2bec24004a9d1456f78ae70d1f73465fd4cf919a4380350982e0479c032ce002d60c2a6ef7ae43f20642b726bd71cca1c3a49f4508013f45562d05e53b3a266edb09d6c36fe1dd603f311d68fe6f3f0e0b955dd735361874dbb87e350500fe9bc850acd8dfd03d626be0e60ec97ed189d09a0056c5f22909cc52b3cf1e69c3f1fa49062129331fc72283a842f3555e1bb19543955591b25fbbf6e15798754c79aa53f46bb2c72ba25bd77457c639d37bf351fb0973817ee8a14f49b7efe1f8351d9e474eca711776c9d4b2f80a01e0889a1e8a3497dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec001a022ae5e44a99bb95e8a1722a50fdfe3cf64956bcd4c15fe2a708bfb1aee4831eea04c1b962f1ac20f8d77f59fc96c0816790812a325d65f998b4ef9b776bd6f5f78", + "0x02f876018307c4838405f5e100850e75d6a3118252089496b48748b24b91498d44fc8cd84ec389b54e798a88116d89737007300080c080a01906902fc22e12725dba875cb92b9c189ea61f180fb7de62ac29346360616ca8a03df0354777b23d762a4521459378e2b74a2ba89eb9388b976a0933061b157aa2", + "0x02f8b001038405f5e100850ba43b740082cb0794b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb00000000000000000000000067006f2c487cd503539491b383c63032a841439700000000000000000000000000000000000000000000000657b3801b80b40000c001a0ffbb920cfdce35101bbf5c7f009fab0ee43e9366686ad698be97fedd490e4289a0764c9c151084f7b5530ba85f581ccf9de86810002dc3210902a9d659fd255d1a", + "0x02f8b3018201418405f5e100850d09dc300083012d7a94b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb000000000000000000000000498d3b772abf0d83be724a95518e7201126fa4dd00000000000000000000000000000000000000000000003487938e0499840000c001a0f09582e0fc733b9d6952c2aa9ef94274c94d3bcb8362f0d57d13ca89a21dc232a020e44fbe4dc03bec5eb08a1821a5549c2b23368a3f7963b33ea9f923ca3c8416", + "0x02f875018207478405f5e100850f5de814008252089443a61be362f1c4faafc7f1573e5bda4619bbb0f48845a805a27464780080c001a0fd17102e6557f82743863977af9fedf62f214db05bab0a458128d555876449d2a00a471be82cca8be9570c13738f31e0b33ec2b7298b8bd3626f9d5ee60b14b555", + "0x02f904a0018202918405f5e100850b68a0aa00830480c094b2ecfe4e4d61f8790bbb9de2d1259b9e2410cea58803782dace9d90000b9042870bce2d6000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000a00f2a39633e4106ad37cc4c4e10c7f30d77c2300000000000000000000000028a11da34a93712b1fde4ad15da217a3b14d94652719600d335e65eb5bf5c0d037479e9086f9efe57069d205f886cbe3ebe32b2200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065f3c6a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c57a69b180a4367e796e4811d19b7b4400000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000005d22babfdc8047c4a91070aa04759bda4ea77f84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000028f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000010000028f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000417b9d43d62383e3bd5dad9411e62388543e7fb56de53ba9e91776c7e0b002e0770d735e2e0b9b7be59ce8bbd4db583acc243e0d45ed61cc14bda0ce68381816e61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059e1c5e24c8ccc22d545feb2ee523984f41249b0dfc0a3aad6210f4e33c44656554911616f2beb995495963488a1009ed1bbf275e3dda76a691c891a9919b19abe1c0128819a6af68e5d010513ff70a3aaed9afeb8661116e6ce00000000000000332d1229c001a05780991d65d7cbf54a7f7b2933e56d1d3ef409d1970dfc5459f7f0c87deb4ae0a07536a692c253276ee377987675e9db6d6819d52ee6be0cc1af644de67ef3b83e", + "0x03f902fd018309544e8405f5e1008522ecb25c008353ec6094c662c410c0ecf747543f5ba90660f6abebd9c8c480b90264b72d42a100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000d02a4e2a181575ab70a9d8404b79a32169d68df616485ca2461fc75012eb719fa033bbbe635ce2226f0b6eb17ef629cbbc493f591df3382262d9b51a9f08ee426000000000000000000000000000000000000000000000000000000000009544d0095d2cc27eec6a3d3f322887081372fcacaa45e0bf613bcbd1eee0f9cb2be9505ba2078240f1585f96424c2d1ee48211da3b3f9177bf2b9880b4fc91d59e9a20000000000000000000000000000000000000000000000000000000000000001000000000000000046d28d2e52040577a77957256c530ca25974f6a814511b1a000000000000000097d62d4572935295f909f243714201d9221215bfcc91af650500bc56e61cc10fda276c872277f0eb212b54000c8ef146f5d7f1b2a6d176a100000000000000000000000000000000f1095b16b9bc2e06de338ad6bbf6ee810000000000000000000000000000000017e5d40332f9657814a4deb4d81127b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030b220fe303275c35177980f7a03cfea1b71092701195fb3cbde91fe2389d0c0797f4cb6976711cf4bb184b0372d48930a00000000000000000000000000000000c08522ecb25c00e1a0017f8d5e53298d8d6c73bac47ffcf2ec1eaef1d9874c402a4f4a7c187b2fd57401a0cf8f0152da9400b324b56b5c14b52fbd5ffeb7f46e4a15736aa0888ff9e47037a07f40ae77195347f761f2131338a78c624de434f7414713f236b08fcd5ac0ed8e", + "0x02f9039601178408583b00850a583bff808303d4e9941111111254eeb25477b68fb85ed929f73a96058280b9032812aa3caf000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000a5f2211b9b8170f694421f2046281775e8468044000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000446c8de76c4d32b607acd88c56380bc9bb732d710000000000000000000000000000000000000000000000fec99a4a552ff000000000000000000000000000000000000000000000000000000000000076b71256000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000018200006800004e802026678dcda5f2211b9b8170f694421f2046281775e8468044b4f34d09124b8c9712957b76707b42510041ecbb0000000000000000000000000000000000000000000000008273823258ac00000020d6bdbf78a5f2211b9b8170f694421f2046281775e846804400a007e5c0d20000000000000000000000000000000000000000000000000000f600008f0c20a5f2211b9b8170f694421f2046281775e84680443d3f13f2529ec3c84b2940155effbf9b39a8f3ec6ae40711b8002dc6c03d3f13f2529ec3c84b2940155effbf9b39a8f3ec06da0fd433c1a5d7a4faa01111c044910a18455300000000000000000000000000000000000000000000000006fd1772e66b5cc7a5f2211b9b8170f694421f2046281775e846804400206ae40711b8002dc6c006da0fd433c1a5d7a4faa01111c044910a1845531111111254eeb25477b68fb85ed929f73a9605820000000000000000000000000000000000000000000000000000000076b71256c02aaa39b223fe8d0a0e5c4f27ead9083c756cc213dbfa98c001a001697eb858418a3989ee6ff94d2a7a22e16c615dec996a0d47898cb0bd55603ea00dd83d692700edcca09da2d4ba150852507df921bd372fb6dcb17bb555767337", + "0x02f902fc018201a38405e69ec0850e20cf5200830356a4943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad8802c68af0bb140000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000044e46be818a9e00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000088490ce333e3f3aa384e5183836142490600da8cc080a008207e2bd0ea1ebf384169461e7775ff60099963e09cb519547c76225a3da239a01756fec9550faf2b48f0180db30e2e019915c2d9c0881d405f16ab2e036d4719", + "0x02f8b10181e98405e69ec0850f896afe8082b77794c668695dcbcf682de106da94bde65c9bc79362d380b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a0906def09dceb8606d66f1f346b528e31291c036742049b45dc5c52914f262288a03436327bda153fda3c63c0939256a239e0297e75609a944f748e240ebf08d622", + "0x02f8b20182011284055d4a80850d14fd758482c3ae94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb000000000000000000000000d3b5e8704ca157ca747890162cec428cf71c1b0e00000000000000000000000000000000000000000000000000000000089c5e32c080a09c8ef1cfa82438957d36aacf2d46583fb083b4c921b13f13b8584e2582561d55a004f1e185bb4ace351de31d541ba40fc80cd932a56034185734292e836b36b49e", + "0x02f902b40182014984055d4a80850e2036bb80830460e094def171fe48cf0115b1d80b88dc8eab59176fee5780b902443865bde60000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e0000000000000000000000004591dbff62656e7859afe5e45f6f47d3669fbb280000000000000000000000003de254a0f838a844f727fee81040e0fa7884b9350000000000000000000000000000000000000000000005c38daab6873ea764d90000000000000000000000000000000000000000000005c924c7af1d52c03c030000000000000000000000000000000000000000000005d0962bbe25306ede6801000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020096bef91365f7415d82b2e1499e8e5d2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0a3f62e50c347fff9f263d8eaa39573a51450b6f844c939c45052c9ef0f70db05a056b79404a999551f31cc78502b6d77b7492175addfb307d9941e5576e2d47817", + "0x02f87201558404c4b400850e1f9e2500825a3c94f2566618d6d4f63bec3091602a678d59e1624bfb877c27fd1ff8ce6880c001a055ee943aaa726c9c2dadf8a4120ba3f20e3ac1ea7b400b49e23d4742b2a90654a074e9a6c93b9fddbe6a3e8263b49e2a96865745efbf100fdfd5bf975a33b5684c", + "0x02f8b101168404c4b400850c963a23008303486194b9f599ce614feb2e1bbe58f180f370d05b39344e80b844095ea7b3000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a00219612083352645f4ced91c957c510fc470e3425fe0b485a11e5aa835dabd92a001991f629910c577cfdfeb5c1f9b455347e766b9cf7db2efe359a54b687796a3", + "0x02f8b101248402faf080850d09dc300083012fa894db82c0d91e057e05600c8f8dc836beb41da6df1480b844a9059cbb000000000000000000000000d74d21ae35ff1337a0d6d79989228a8ea0a83904000000000000000000000000000000000000000000000001c9f78d2893e40000c080a080aabe18ee85ac238ac6c33ce3df02e99518d12a2edcfe57b7b126af9b4526c2a0141c9b35a2b5f9725d85bcf86540e0850ad4a2af63e3156d8b578474c573039a", + "0x02fa0186b80183080e6e8402faf080850e8a27214b831d252e941c479675ad559dc151f6ec7ed3fbf8cee79582b680ba0183848f111f3c000000000000000000000000000000000000000000000000000000000008d67c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000161257000000000000000000000000e64a54e2533fd126c2e452c5fab544d80e2e4eb5000000000000000000000000000000000000000000000000000000000a039428000000000000000000000000000000000000000000000000000000000a0395360000000000000000000000000000000000000000000000000000000000018291005b1713353b50bb4d0480b19daf979a3df50937c6d9ed2cef7023ef935148af28ab7733feab041b0ed516bc1f5112591a87ba60ca4623e0060d456880a53150ea20da8610ca03f797c76bad37f5aeffbe33c01d566e71fe3cadadf7feff33dbc492924ba552a1ce1246e48260a1b4d1236515468fdd608e7127177a8795ab9c62a3bd18c7005df3fefb482c115bf9c3e2f257cb1f96b0e0c5e5c52d6c416bc14b18a06b7ec60288452e680997c805adbc006c6a53be7f4a9fe566680b2ccf851e0890509a2ba5cf09fb8572df46364b555f1b838541cabc8875a7efb66c2e56c4de220cd38bfdfdbfaaf6cb071194e83155b62bb529adfc120c1f21c67896bc0359c35d6a6794ce19c265161a8b009f6051022543628a4a12956d2e6952aab805beb83c9429f0b981549620351b52e116d1da428a5b446b6b2168d12b13d4b64200f60c05113b29954ea942f01e9f1b2d3745e4a3194a604ae30c40a5c0e416a6cbded2beb62bd9a6ecfffeef6ffbfb48fef6d3e547d9fee98cfef6e3afb4665fcb6ffa072570a2afbe24a43443dc4f7e647b52dd9b7a663f6497840969e62e1b07c6613cc270382cee840f7108c985b44b9c5db2bae00d4223141ef84f2f02a097a10381f3036d3e350346e77e6d73c9efac6c977fbebfefdf774e33d24f0b6a944eaddae94e5d3af5308201e1162c1a81b6a3807afb4d3f4c1126a4db45c5e79f39fbee7d6f5a79bfee76b69bce262661ff30094e30121b3a8aa006b18315937e16fe5f979ff75cb3a02f9e82fb80976ef0c04831d86260305276374e9f94ca4af3ff1fddbedfe7a2f34acbfcd235d399f52d191f2acf878a0db151fa4369d24a422024900e38ba521534c6e1aa5a2116120362898cea4253010aea31b498812dde51e5cd60680c0a7ac3403426513dac4154b23f77a634afb7da688daa5ac8ed180de1441c168782fab70f02d001281cfd67ea4ed16e2d6e83305ffd5629b4e1c12d8264af947bfcf068c22676d62a16ce9b8ebca121a11cdf0997c78eff078c1f56b259ec78e48d842072cd10d3fc2b05f04593c10cdc08362e296f8e027d3a900d06160943d8a6f34a20a57d6fa63afa1eaa76e151122dc1734d1c086795d77300a8c6bd09d2881380140c906998113fe9ef835afab03246d3f8da653bf9b5606a845d8c0a207d4438a42082022ebd7359340064ee0ab1473b77406e6e15105beb1401b84b657fac71029c4206014bd6a6033b45fd5fdb9d0769a4954273659071f90b6c1f8c99ed5a1f5156699ee082fb81d97313c8354b1414b09ebbbf5fe73013abb92a98219dd8f121019a1bd9dbadefbf28852524b851a11b5ad28c72bead226f04186ce36e6067a36ffcaed01a96349a4de496faabd1ff58bd07d460911607d281aca6654346efa41e59f1a7299e53c3cfa2f15ae853ba49a4405764c17a7824eed03051324ea2859a0b38edc2040920050a3068ca2d46315dc830a3044d2c5380189a96a41c70de31297339d227af28695491088881d9ed4bebc3347c50135513ee6ab4349a46615620cfa5ec2403a680d4252b017932237a9eee36b6ea5ea62e84b75532a284c42b5dc19b9f1ae6322ee2b50b3d3be2c262a5b33ca16d298089a5510084550cda484a6086dc15a39229601c1dad16a7222be6c7f13b4c5b5157effa52b7ff49fcd34ec251045cc725250c04039e346945437ce8f0102ba198ca0909ee043b382c00ce0816437df9244699b33be0c8554a03e42f4c42a9ad2a8aa317c09dfd13d17512f5fe418e08b796f5e9d1a313dafa9bab237935bbf46915cb0d145adbfc54bdfe30314307c5cde844972186e8c907ad122cccc8938ca56417d14e7086e27e9ccf4fd21c2e4158d98e2277c1f656e391f572e0c86c3d809f21fd2919059f3f792dac991ba276f90335868624067a32011405136094bdf1b132c2207ec5d0feb299b3d7b02c9e0c3fe6b2fb12a8372193f0617a0d77971671aeff9ac7dc3a0400faf346b64c37424bdecb9e5e197dd33c7875085a72c75b9a38caad2a19940243d8e84aaed91bb92d2582ce8f4166c602959e3d3cc3569c94aac9a7431e599ddf1e75d12ec0fdb2c767823bc131cdf2906a0d0e482991cb299dfd6adbd987ff72fdb2ba5ab86dc20c072b093c801192bb4ee1abc4283c4b8a52e62d8e75acddf8e461f8e80931bcb7831d5ab4c725443edabaeef7903c5fe16bd3a930b4295ed3c54872f640ea2f029464e7e07f65ac066aabce59853c9c59978eceb13dd6a06a83993206b53f86378b5837bf60cb96e4ba1f15f9a92ca6980a3e64a4cf48122608211f810793049939f039556c8ca0b26ac44e2d7e05fdcdc45fa5db65941922ef48ce69dab8d316ee24b366c3ca909518d6eb5f36a8612f3ed7b761dd0d29cb238a208ce5017ef8691b10ecadb39482542200a357b6ef602dab497e25158426f0b8d1f9e2fad17f4365df493aa40dd445d0960199cdddf3b3c5bda4e1c00ed5dc55fae3538fa2433fe47be7287106183b6b9e07100fac82802d47ebde67edce90f0a6392350d9b75e1a5029de8e5b2a3741e0d83a44c1dd6f3ebaa2844ee6ffdb37ccc8c19d0a9550053d005965c8677b71a1febb34286853048dc81c51eb9bb4b7f39a53037c07edd97bc08ed716b15ec22bea39eedbed2fc2287d3ba57f1168f865352658597f7b5f91df0c12a140508c6a8e301eb6ec66e35cc3e55350f64cff13e30205d20621f5a420e3e5e58f50085035f26e91330058b78eb5feb7aea786371ceae6497fe2b5f0336dd71440e573d653cc2fff921ea17fc88c2a089dcb3459d705c15d1005a1eb642dbb6c901d889fb33cf18f1b22ff4d3d7ad55cc24795a0c37af566e5fe65c3d305699e6e9aad9148c9eedc38031c56868c3dcc778f18160f16c2f5c7f88022e134d0a2a3c11b34a96cad0d31425a0a1e9be9f5b6deb2e5e66cca3263a0c8a240684a082e957b5a2a1b13c6188a51eac11c549dd167850894babc29c9034246bbc3f8064e09b5f57af641a5de2634eb5093dd1bd9885b954b26b17e3eff56226d02d492b02c1dce0acc07d03037bb61656cfd98b029eacda37c42876fe046c767a6e178e14294ae018f6ae96ea554611c4952c7b6603baa3392a21635f69483a1ff1d9ffbddb8a0f16c57bf96b1d08d4524a05cc3395c078201294e4e46523a4f2e3db5a51ac65eba331c6c18f6b34502ed0f641e1c758d1565807b9cc548f4e61e472fed1aa7caac4d4681f08791f87e9c5f6dfda6629aefa636ec4189216f14832f1cd6981f54aa2d1e9f4a329be2b2b55de1288df894b4dda84541fcbf7a2772911951c104540d2e2f5f6611c5b9242377b80f9b70ca30a88dab5bd98d2d877590704ac4d0ea5a96dcac063c5313505a58e1a141e6552ff651fb93226943409d93c7a026240cf39c9abbebcb07a1a434cb144f663084061366fe4335d7aa81e457c879fcb140823264eb15397e88cb522ccee7cf5c263a952f0629615a3127ca0c6d0ed8f7253463dbd763c644de71f4f0109346d87c0c288e61946ca3e941ace4f7ddfc810c9629144c263a7347467f4d5e4e6e3590f62f2f708d509f3e8434dfa9d749537e1efbb1fc4eea63f22b6223e577e04418067b3f2bd95947e4d7cb61c96fbb354cc16a517edd0791a95acaf04acbdf80782dc44917d85b15e1810d8e43d3571112baad279bf316321350f883d2f83c9301a780b542be890a6719b072f368e386b6c854a3d3ec9c233f24c76f980b3293de0e3f10bbcf038f11cf9e02958178394195f7797eb9915a3a39fd7a15a450a8efc99a8daa44a244092a60ee2780c468904a24c0baee0c759511f06f8c27b13bb08b86a4a1d9dcdc89e040e1beaab75b7e01560b3044584f2f949da0f6d58fe2ed07cf2061199dbf91b3cc2f7cdcd84bdf227ff8dbd100b0fbbd3031c8fde5d068c6f9d5d42f58fbf1590319c299dc88e323efc281b682a9cee04e0538cbf266c1e64fcecb17405b9c2f9de61faa87bef68af576047b4067f5cfc4d13d652e115c1ec18389616a0ef9e0c45cb061b47abaa868c8fdd3ea0fb839630e4b113b24a0a4d6e0bc2ffcb8651aa65b8986c2553c6dfe6521179b653f9b2119778171b4d30923e62d2b5221e43e0fecf8dd088b075a8a52b2e3bb73244984cb53ee6aaa5edcb4739fd71b5fddadc3bb7346d6a11007852cc29900f8750b8d5108f45b22a763e3d83f02f7facf5281e029e7cf26911c846bc6d22b6b6a0a046c99105ad21c8de5e517eec5990a2a538a8c034ac918f552f935a9a5f91395f7343df682180f06de90a0cbc6a3682fe1324d8241d7921cdfb23e4f34665592492bd0870f0e9827af8d4b9fcc9676817126d860605dd8cc00caaaae6c8d46b639d21b08c2c3b494ab4a95d95e24aa4fd080c01f43b59298ec5089e68d86b5883148291f82c3f88cb652c96c7b2e8495e0bf48328ff0e3fb1b186234e29606772128889e53e4044e292074030007227aeb17d77471cb073457293e9af334ca4f7923b6425e6dffce06ab0847a098c86ca434a442ce364ec165d95ee2a212be7b4effb1673b396dd7bd9e5a601d42e9ada053e09ef042388c9b8d15a4c65947638c893bb17bba834a11afa7222aae733046a9b3bda5ac89966a27627f933423e6086fbbd85df637f1dd1b9ab9e7f2c361af552f3c964fafe4460c4d38b8b8a6af12957831287cfcf140d6746c4a2d6cdad3b1c0f1ab836f69668fe1011b3a12ec35243cef3f8ac33c5cd786d9fe0eea773907357eb405ef1f9c0b3ca403187257a01ce9bff10dd77d9c92dcb88ca1f8f83f22f8bfe4a16120df0954114fa23462fde150c01965941a5b42c929c51ae56a4a50c6fba8ecc3d287b562d1d0861e075ec19a8fc16d7dff8cc993cf397b3ea6e8cbfcb8949b8c122eae74d4da78f2ade8d2ab0120b2b258b9a02c3886985e35c71932324d0e12ebffcda413fa1f61676c05cb18ec59e80ba6ef03d53acbb1226d680e22897c9930d952eb34a8161276956c3704b8bf696f0949ec1a85792435dd3405c840ca698c31d77c03c1c07c7ce0a150ad80486c10871f34ab697b81c2237a6ccac2d3812633274eeb973fc0fd1b964fb998d969ec5f6166be63006369d012ba7098694a78a74b66659db6829c1b8d211f5023b859b1c1c0541a05eba7bbbd8be9993aa78a7f882a29be214f5e12128946c317ac2117e5b9e93842c39ca50389c14f00bc24b369d9ddaca45c3a5be697829600046c6e6dd58f16c862b425b9f3fe909125688b80fc33ee4360194b3f7595cbfea40547b86b9623cc059c4464064e162c961e9d85e3bb90e6ffac0a36e37f0cae02543a653e4c368df87b907fa9d609cee2f6c36fdad910718a3fbe3a4da9a6c1e82ba6a4c0521189e4d89496c3a07be01d9e540ba4db1bbe9d1088068a2176448c30b0efbcdba4b5f5a7c7c53783b3f100cea045ddb633e919b0c2241ca7a1872465928ae9ae47f9aeeb7c6c88b69dba99e6ae0b04025ad9fac038a8de9d10af4865cae763267a7ae762199ccff8dbbef43e0571426d7bc41bde784320c0a76d5b9177464d71fb23f628d498755ea076a3a49748fb5ef05337aadcb67404b84a227accb760c1824bc391ca68eaa23914bd5eb82331c7c3649f35b01e9ccce0a142e149abe4e0614fbbcad82d098ebddc6fab556bc20dff7112476da215ff7d5f548f97087cce9d8d9de46dc9adb52e8afc96fc3a5ee2604ab62f5635e2d98bcfca9a231f0d97fd41c14ae1b6bf961a61fc01ed459b7afae965577710d1a21be3967795bcef5017e4dad51d045d76c47273c3da500e175ee3901e7db47899b5f594c3276d04d8339b6a65ea2bac27bebf38de894e1470b96462bdfeb306c5b9818c7a55fe53288e99590c10b98820b786b7bdcad6a938df4bfd19f28070110dce60bdc8d61bd6ec7e859de1dab074d5d4f7cedf0dc6a27cc7d53251bf59827621c444871affb84402b8a2bc72c6435b893438aa7f3631d6ba20fb4e70b1d80af1f5269c4e831780218ea1b9bbdeaaac5e58324a740edbb032ba1708a4b59d215c277824c2642ce9d6d44b084e7af82593423c47444b8784dbda9ee9993a39825c2f235fd624c3fef2161e538f82da4adffebf00409b9a9e819a1de0221f88031ff89314781d0900d440013a0da66d01ac3a379def00aaed6f4fb9803216d0cf03dc2200800477e0b03f70fb06382f0b7c8f056a1480b7536f17f720343760dc5d009a3e80a63e2da0d9016812402a1381ce6e40b701c0dbfab79864c0be0800b07d0b0c78011c5903843400c1a781dd3780dc59c0fa5460c57760c84a009adeed80e19bde94d0de427481111b81c812c0c7e9edb1db157f44d832e547cd1fea80a7de5f174fd3ff877a2ff4ffb3c303681ac2a4695ca0695b4264a427f45c55e163e07949becb5b08414594f8b60eb0f65e2e378eb3e42f31ccb6d42326a1db10b8d65ed324aad71f91e2dd7891378eb1355f171c99027257904a52d5d395da0eef0bc0f028d540f1af6db2f5cfe8103afa52abbd12d71763bfb41027a8ea5659d2bcad799643c990e513912558a0a443ccbdd08006e3e7c63271d0e4a75e1eb9f467613638c2946abdd27b52d05cf396b1d9de177bf7bcd7dffcda4e895f3c22bf60a4e88d5452fa22966b3a2dbb7fc508f472343e27c4cd5b6ddf9da9534b96d423e7debd733dc39a295f31fcafe1021cd08753f82a98506784cfbf007a2b39a8b84223de944342e8ef83f5dad1b742eff50bbebb49acde0616867ea375249e3f2fcf1179157c8c6b2fd7642751a28ecc8963c2ea289b56a99c7af94566c73b0249a0a3c0e2b97a4929e186e8c68ae78d8af255b1834541405ccdecd073ad65f6a79614f19f594c90a76b47a1c74515c779343302dc9486d3e5836a64ea48d6007cd83ffc2f1654fbb154bcb9d21463ef8a282bc1eb7add24435ba16e46a6f515391f14f0ee5b75514b29dd417cdb953d4f79f6ed11fb57003be27ec0aebed721256e7f1874a4a8a128ca9a0aca8776f79d772ee5f27c4d6de1358a12ec7973fe829f4d2991b6c98ba3f9608987aed6f0786401a01accd06475ee8f4759811a7743638c13741441e0c6a5fc4990d494fc5eb885be93e87447164ba1218b14302877d85101c2a875bf1a5fd6cc341a4185f4da6275486d2e078281457836fd5d459c3adaa0e171c98a30fb562a3a3e2aca84591344fca199f1d26b00b67f21e67b124075e3edfac32a690c87237bfa37343da13b6f23e5cbcbd72ea81322aab24a0a6210b8c3d0742f5c678804885695660b65c87ff5e1cd8b3d5d545f27fe4da6bea4144d8a5dcf40ee1a8b1a05a4495f200a33f9d2553323ef2bb0aef99d8aeb8e2a66a995fa1a1b1c124b975ea023af39a6d79bd6b0ccaa2ae7356e2a7926f1b092edf5ee416f365af1140cee2bdcd67334d868bf9ab9088b162371c8ff3f4740a8313b04fcca3f37069dbbad95ada885a98b87a59b16db3ecd072727e5dee391ec1fb10dfdda46c27342083ced7eabe2d4f4cb7e90a50987461ad0f0407587b8e8e366352a10704a9f496b032ef619ac5e1bd98316d6e5d31d23f27e9efa6944f8c762963356893ea50bb5fc2241a9135b716fa815dc5a564679d6eb3f581e8d71e3ee590a661c6e9a6582a55d8daed32bfe019db58c7e723e02055fb57353716f21248df3c8ddfd690f2e1096cc80960373abcb851dc0d19df4c211306033418e730c0a9b4faadd3951b82527bc1841b676f09a8fcee902f5010cdc88ed51e5cd94b6f02223aaabc254f29a211275747571cf89c56002eaa530174b87fff148dbeff86c714360ba400a53e4dd0aa1ad39cc9102577289964d123f58db789830f470dddb7ee775fe4e78f030fedc40dcbaadf6e64a7b103f4c827bec6d49950d61fc5aa32f26a4b04d1ebfaf02290a12605466819a9b001c10314f069629bd61dd3403edc62f38d84e844fc9310b61f01d63777706c9ca172bf3810c6503a180dab55936a887874a0f4284e508d1c17093a618b2f9a3a7b280fe1685caf9cb45276448adb7fb0720e02b7ae8355aa6fda98fae840726882968ac426968b2a3e4086b2f4b9a60e409c827d9c86f67c0ca088c1ddff89f0fffac368be56c2ce224906a84f9d597292446038b407db029fc09f0eeb89119966087ae7da17f933330ffbf43e8de78321adc443b868c889c98175cffc025cfb11ce61a2b5640dcb5186ae9f82dedf6aa9bae260015b220d575a37db3c0b42235b5b6e89c421fd1778535cfdcffb746fb37d83009b39e813c2a9fe07eb5e41f082f8579170f7842730a86651fe6b96b2763c50df1761bb5753322d1588cb87c3e0de0714549baded81c811741d2df3dc2c03b4e26e0790de52f4f64b4453180f4e9ec8d5e182c04e916b198b4000a3615e7865761905d05eec1ad55f23c51da37afecb3e0be24ef37eff6a0ecd9b168f76c368214d7b66c11fc0cb0ae5f446bd3446b4ec7d380026c3ffac8139499f24d227e6a33bf5450c5a9bc183df97f410d500f4f4f02f6a16e913d860743a440cbe119b1aab11e7a7d1f766eec003edebd04a9b9fd4f1e741402b61c7449c4441e4710d70de3a6a3146fb713b5d228f0ad66f2ecbbadfbd447f1a4b372638eacfb85bcd26229d727e12aeb912318f7c7350c04e8356d7b2fe4d125aef6b4abfca286e8a9ec8d0461f42fddfba94cdab35b0dd5f19d404d40f2840cc14cc3aeda920ad6ed57add498672c58d6c98be77057febdec61def25b8780ce00e44e11ca5a85570fc840ea9ada8547b66aa0c5c796bf4b8b09005c14b5ecef27823b417bbadd7dac031038a944605be9dfdcada9b94d2bcd7ecb9506ced415ac00cf082d4b4235841772e0087319e20d036d161ae8585dffbf4f124a05bb5d3f26a9c308a1d2008c4ae7674d19f036803c41a10c4789b0e191ba50ef96c104482cca1d2b03954c63b1d7b9f3e8cf3f2ebe214dd8bb852dfd44d31dc008f8355e5121971f397792c749dfefc50a10779cfd673182ded3c535ca780d8ee83224770ddfc5ea2a9a50ce5a11fc4127d3b10862f757428e9bb0abcbf0d9981a2467ca196f23a9ab9cba4dd8404749af2f83591bdc699fdafa7e477cb6c0cde1be9d1efcbf5a0380539edc4b5eb41c7cd7d23c41d5d82c54829bf76ce5911fa18839f9b0ab0b491415769f926cbbd41423e884881c60ed7e606bdb2c85e0b54e9a82f13db861bb812bb49ca655c9c92bcc88a7e91bdb526ba55bb8a8f50776ca72ef3e6852fda3acdab0f805808473c5a0b6883ceca31d799f9c398d83901d3fbc06b22c4bf28b9d73d2c53d74b881d87d2edce1a93c63ab637696eed00fb31c2a0df7f4ec60d754653502c5208ae95823080ef8ceb366b10bfb78df72bcd48db522a44312d5a7a25e63e17e4ed3ebfdc32b3f7b94c48a03deadb654c412c88965c1217e613cc723ffdea49b894fadff3c9f30d3790db11c77c2ae03ec41b91e9dba66e222ac4e19780f9f30153b806beb801a4f718b6e9d4531d42ca193762d29aa095242d528f65028951db61279ac1ec319ea5975b83724a25860f33cb717defaad651db9f276ce0c4f870c5f97307382ad0946304ec8b90a8ebda04eb9f9c6f739c1eeba345da1efaa9c1e4347d44079de78692ebee0697549692d3ef9097f9b50b960c3805ce3f8afaf7e115955002a7e29ffd99f6c49d01d8f5a82daa0ad97640230a1c595ae3dd9657b3451c3c8fe64301f3b804213affcca7eec5bcb69cacd61a2121ecac627514f438d2befb6a05567652ae18232b65e4c0dffd4b020eab286701f1a0da5c9b20356a2b203039762ec3466d8d1cb11a2b89d411287c96793a22caab04f9f828325245e698b8b86ae71dda4e1d596d869b941fbc2970d15358478a478bc2a817a4eac9bee93a7e265c30c14292c3b69c9be601af5c25d51f18d81bf2b56eea4faba354a6183cb52e4c78cf7d43301cde4d52e160335db6b8c4d25308b49d62dcaa475b065c1b7ff62710e0312f2df81a5b7052d06a06bd7e9e9d6ce2d4b0209a3ffb5f9e031a80759855cf3e7c88041750dc33657287b665433d3ffae87ab924cb87f4fffd1782a7502d5db74225f1b289b24e25b424b01ab13f9dd05a8b2b252638641bd96a891aa10a5598e60e5941bea1b14ac1288f6e96a999e99224c15441c5a146af68348c4285a883c81e61243c4313213f17bc5d53c67eb79e308fcf0ccf81fc5d68caa3da04e51e633399c7ea5bae2c69d72cd6a0c9095f286c17f66f492f8b40aa611ee0ff1bff4b672d3a3fd890f2fe13bc04c88ff7d64178c8050adb318bddcd74447a9200080813dc837cb5d8fc371de4a38fd6c00e2c080f4978b9e71cb1dfbd4870d2eaddae9a9d13aad7ff40357a401ce6095279e19914df63c92f6906a42a4ae6434b553c0225644b28b34e9947df852e5a762449953f78d0c6fc0fc05dcc1bc6e8909408529419ef4baf90e6e9ee2f5e25a9a57ec13bcf0cf9b21d75980db67595e3c7433bd6768614798292bd100392583b7f57d3fbfe461c3e27c40244102b6dd8ebb9552149731defe8078e12c50c54b6dd75772d9c70524dcf945c92b9c4ae7b49f4f357c9180c39ea8309a01540860a141e04ad90b72484eb0e5bd3839ff383b5f4c2cfaa917dbf6e24b22ac5f1769eb68ea9140ea7f58a939bec62539440138f728ee91eb991ba746c72aadd86718311fc5bd500ecc1daf4d2e8bd506a91106698a3c2ef0ee9be5255bc3006eca3b9f113dfb20e61679c66574ad90df503d3171c65b34ee003e1f2cbcb8a3aa8639eb4fc5c6dccbedf375349241600fc8fd861c76066909d109803e81685576a4953ac203b76973d659c0d138122886b435e330abfe2b67e3ed14b2dba6bc7f3e32f81ce443d6ed4efeb75af3d547bd07d7161ea812ed7d64c8cc79f290524030fdebf736f7ede57d14311bcd24168fd79710f5bc92f75ce26e9670a69a2b71ff75f4883ca9eecfe6c072a9b73b1db3abfdfdff47cb55ffe258fe30edb82eef76f2bf38e26f75f62ed91a305aca0fd8f7a11d71ce5cda03ef6c292dbc874674e7710b45a578542fcb10292e54f2f4b7225cea0ef9f1c66761087c96e33d43f8540dedcdcdac3bcdb602edc66481263e69d31921f55a0e2f37aea429401626c507331a4ce2abc5860634e65db0074f8ce3ce82778a9b3aefbe877ab69550809347ccdf723e78032972bd8f7fc7f6ab10fc95dd262a6baa4bd4b9cf70d8c1e6a39b00cf5b4990f5e9cda3d2fb3bbc0f56c3443720f0d72f9ab8a72967fcf9ae0fe67d3716cc5339caa190cdbfd2a22d56651c6b62b8adad359180df1eeda5bdc2260372c4b9e62131e454a97574ebad6fd1476fe2d19474c5b76d24e174943827b4e74c9f1eb10916df4d60080a92050480d4f3c23f8e1c0c5f4637b60ecc46088b9382c0a0d49a4789427df93a1013a67af77967fc94ad37280a6bd2e1b871dd6170551feaad59f9bdcc2deb017931da8dc2aac8d86ed13e4be32dd2164b31fb7f990148661a2d67dcf231b925fa831017d666f2d77b88a148528dcc8c2e38f1c82f8d7a9805a589a6644acf382205d4f67b58774d34958527bc413b15343021c5494ff821ba99702d491199cd8359d12011a9e24b031a69432e086e7c2f5030e67e8f8c1859ac0fcba0e5a2ada3f495871127134c32d65a363869ef857055538e75b236cf11909f541f5dba7bf6f6fd75256c3a430aa92107a9ba228b80b4926f6840cd86cdf47a137fdf690a845668c4adbf175f5b9cc2d3bfaf2b6f1f009d87c8510807f32ce68a392a69c17faae647927bf2d1f82002da71df216a1a4e2758fed7626e4c873c60bc7e2befa9aef9dd973adb6f6f342dbf372701b17089e925f60125518e19dc096270f6fce1691a360a2165f08a25e4d851d07c66876ca399780f2db44e960059b937d369de97106b6614fcbb081a43f74e9064d2d609d8ded5e9bf301245d83bcbb12a5a13fa168ef21782911953cf9666001af32d79e3a32731dd99124c7b81268b4194077052d5825aea1f763600e7a89e551dacdc0095ed79772af3e405ac791f4bda2ee0dbe782bb2c81dbc907794b8b1ec5063cb0de63636e4340147fe47d54a3e8b2ac9706a21eb644109f43af4dcfcee644a250164444cee0dfd10e30b0e57068793374aa8bfeb8fbc57942325d313885953345b87957e3175e2550053b761bf4027756baff61a097f525c825c2aa0f315a9cb717cbc45299b16ab072f0bf592a6f6a086d20c3be733946f066004cc255b4f09df1d134093e5f9b79ca576c1d88ef572c882ad75087f4a52c88169d60328e467bfc683e9768a6bd60b08fa0b5251572ee20078db3459195c9d23e341e719481b4f088f746a38e9bdab7f30efa2bd5a1eb0002dd64a7fa66953f550e2255b9438a6d14326f168c125516ab3fea54d0392b8ce400c394efbb762d23c1998bcde438b64db74238a936af298e2b968abd49e7a19cdd1d381102b6141fcafb89cc9758fb391b0a7b0c2f88f14db7446e588ba82380b06efa815e611cc560538fd02cd31fb8e6dd945c2b2a0457edd687d01520152c1e0bd69ee0110660387f3b5d65a918c8a20214d7ca4532967778acadd868bf821ced87ffa388e331b99e4b61131883cb4e5da32f282208a6805bde77b3a640842222cb4d1a550f236547425d9d8952254da8d7398d36848a95db8b718963bcfea828c9c5d1db510fbc96e039ed35bbceb2e72b83fba0c104abc4338670f2625bdad36e6d00034e9a9c3dd83e013d4116964fd88de11dc3aeb99d34c57919eb4af8862f1b28d092d4e051f990685efae6eb21d2c7b8f593481d34a14cefff7ee30bd97adadaa34779f02408d832ce1c12a5561508db448b7cb722b0a427c76e452d193bdc65cf46634fea5ef04281c6c1b40b8b5ad2ee60424f5e9572d9f1e778d03b47337c6caefe7235c53956cebf8ce61b0392f395923a8c8ae929bf23d4548b18048edb4a95885c651b257f2eccfc526c40e8c2eeb6688990b4b82859791bb2e50fcdaa3b3ee582206dcfa0cc86adffc5bc18684b2e39e0f820436594f689f809477643fa8c73e61452af9810a239537f3942f1acf9d8112fc06ef7afd6a67e655da00aab77c1df64495c1baf3d3df4c82a5d83107906e44e211e5c00b9cfc51c295d6dcc6f42a94f88b317c76d83eb947b921af0368174010ba4a85150d601617b3ae11d78f66f33f774c8e1eabf2bea4a39e4f905ae933af7ec9494f918422e5f3c39ff6f7c1df8d96ac842cda75a7376d4baec93ccf971391b9ccf6351f7ec6ee6c7eadb31b1c72f84fe82bcd1c5e8d435d34ebc0f1e445d305b52c15d08f694cc7e9769e64e74dfe58af189f4d2c6d204acc24623fe2b15bfe18aaeec2be10bb61424594ab47df65f56affa0f2ef66b29004ebcbbabd45314e6e152133608b316f0095254a4e2ef9e6352270d7954e5471daa3e461f1c9536bfb8533f9334f336427f06dc617fd73dd07ad411258eb702b48cdf293c5458acb19c8ff9563224bd9df667f9542d009f03c8ebaef51b0111ff303ecfb14446a59b884572a9b905ffb5e3e7213ad4b1cefafabf74c4d65d5535b9db7a3161913308bbe37cb8593c607f55021c562127ce63117c9c0f4fee5e95fce16ecf7be04e6c65b7315728b1f05af83d1d66d29f084c62757634a8bed25d519753a71a2bef622a6a200ecd8fd17d8b3d63448e6bef9a23e5659b8ae02e903d61e4b23c38256eda5a321432df28cdf5e0ff7a5ac9ea6fcde72e19c842234f027865bf0b7b527bd12a2dc6b1333e4dd52b710805bcbe28ff17031a670c69167bf073da7311b17bd88987cb9ae4de13f55f2ff8ead583cb90fcaf9aa21fa4cde4145882a17f530cc1cb70b70b132f8853e8ae190a244dea4d59b2b9246824d89f1bf4b4c21cc3c2a4dcce6c5a40fb3f985e0cedb78e96f309070c0ddfbd8b4804c0c3133547e46e75dbb9b9f98e235ae4c3133d02cd13bb807bec273ce8989f38cb07527641c08dcaa4712991b1959055926f214fe5237f13c7c1843d1fa140b37b69f741844d659442bb5094a300fc24a512ac9365981106c12dd734acdf129dc45bc1e6c97827a43aa687855c14412f7134233fc7249eac9948e24a092918ce121162db72c1a6cc2a1cddf3235f7df1033129bc721c74ffcc4e61ea5a478418240408d62c8e78a8b5d4544a121a4293b46529ed74a2c15b6fe064eb3e78418b5d6de9ed82434042e694674bc57ce14f0e190fafae8971f67ef843c5125a804993a11620c4fa3227ebbc7bb5419c71a459fc8ecf33328c605b534fffb512e955dca7eeba1cce00e212cd4ee8515d42af83455eb60e62d3b6e1ccf0792f5ee342873fd9ddea8c363e26015df8183e864c2940bce00a88499d59b382365dc2f54b81463aacffe70d8ba4ad1304aecb13134445d341db452e4d95a9c2836190120315b9e7d9f5474492c6e39d27eac79482bf5110c9e12563c1902d3a2d4f9354f29f13d3d478193323eedb7fedb5a2aa486e7e034c43fa6359ca8c31f12f809f92cfebd8b25fcb85ea00245e87929a7156d9698b00f2579b8d8bf61fbbebe9ad1912655681a7ae7c66c20d4e536483370761b43ff8a8fa9ca2c1ded3c9a9e3adfb94bee3371a1b96a85902a9a5a79f59b77d63a894208bcdeff6114b27799fd09c591f970119d9f0d72fc7282dc1ff23642b15d53334d1075b2173262c3c957c8289f290aaa3de529a48fd30041a8b31eb285359c5c80fdeb9ad32987e24811ffb569a831d1691b1b81278422e936ea1d9aed0b942fe5c9a66171b0003fed024f02612c995b5e1fc937baf612a9953f992f3c02d3640850a0ec48c8686c2c54a28aaf03563b1b69b8f4cdd57da7efae69b7104f6266e68fd62b4e9a569e10ec8499457c3edb47b47309f4694ed82e2c9f2338bd70e12615c54b2a6a6ba0a6c9f615b6e42fb2c5dab49dd94e375332f26b9593e89d7d338ca6122ee7cc1c6d90610be3f050e00909678f175e1e9ef315cfcb95036b04ecc032412cfb755e49031e86d9eea1a7bfd270cec2f8a5fe5fc1631423cac81cb92bbd0cde256d4635b9d7baf871cd2e0c238b8c37e0c766b73e0c6be96425556209329d1b460e7c83e15ed8f29c845801fc401149141902c5e521a791e468c9aac630ef946119a66ae665dcbb3a657252e83a86a648094f2983e39f48c1ced9e8cf316d1149f1408a7751bb40ee0ea504eedaf334de28afe520863f509ca6e4f746582ea841e249418ea0da7ba9e6c890a6bf27a2cbd42fab943e24c74a6fc28c57add616505a36092c3abd45f3d6e2ef1c84f46dd850c5a3ef1731bffa3454c5088e6d8125acd8afe03092ea066c4d01a6051685a51cbf68c54ba624c7d3bb8459115b5de5134604da27b8fb3352518afed44a40271843890125977b67a1cfaa44b6a3656ee14af3cda057639b9285e57add5f2acdbe8948cac3cb825d324950ee4379acdcd2dba839c024399c7c614c0e8b3c5f1fd0fe10ba9ddc359444916d1dd0ff3d07fe9abd57742e82cb71f7e447bf5905702e8c10fda4df57b8663105d7db9553e326a4c8a41b6398abc2129c927b48c903e823836fe506113ae384d7c85acee468526db72021e31a42773d3bc538bc679ef038e01dbc590f6272d69ad0ce48109abbd8ff9630443c6f053c2e38849fa97d00da8ddda6b1a462bc0fd151d9de4a6670c8df9699422461f5a0123a64482c943de8b5a8444a1928539be384a0e016fa4585125cd526389779b22fa81a27ea8bc6c97bf205f0e427a87fe2c240638a96ee548b4d044fef2671e6522e8f7392eb1d459939a18ec915e88d83b81032d8fc82ccfde149af7e7ac4e583fc694b711be723393d10127bbba96670d79f0f51645ed40eaa7b248406d75ecbf2c639c6cc8e440cb0056b7e57db9f77f7586f22fe6f7db9ddabef35f6c17e45d1bbd5b06af984c2fa13ea5020efcae358a962777bcc1ccc14cdc8b35ffccc5bf95c693f7256e6295f58718858e7c27b3abf40cc033d5c7db0421790abd875cea216332c549836c2a945897e25345f2ad94283c599e4b545af5eb6c0572973155e44066199e86be13d687a536291e319970ff270d082ed1e6c7d3c76bed9fcffe77d737abc12b6171eae833ccb9ee01f472650662cef23f805affbbf1b05bb1a827d17376fd97c7157c652bfaf05fae3a8fb62b086af120cd4e0861a43a0cb93f1086d0c35f1695db2c3e188623eac501b2b53dc7c88f85687cd3fce9684a9ce3132aa8eb73f6166035fb8ba6fcb3cac980c4d73b9ce38cbbc489b7c169ce6562de591af569a8a3f0fd703b237e7eb88dcd2f5393752ce36c4a17c2de4bdd96bbc9a30efacc08d7bb07582c578f7b3515c8fe20d6498764fa97b69340bc8d53b9ccd83a2b95b8193d644a66363d0abc5c50e68bb970911ae2eb84f1209e540f2a24bc94f0b943a48681600079e12c39ff11347a0b8a48f316a77800597db83e98d45b25db88dd279748e802606e163233596692eaaee4f0f453ec316d3d76a5845a8e52e6b98610b8d53ea7800efd7d9784b316b43fe6f06f6646dbc601827cabf33ce5a51fd7887112e3ca1c7ec50b31b1f00dacd07f6525cf0385e713035446613407ae4b2e7c75f19b0b43547b0cbea41954a457bd58f6277836ff57200598d44ff436b6079000b26648dbd374b87e75d5e5bed791a88e407314671dffe844854131c00fc53437a95278b42a5906677fac21a1cb22bd5a841735f7d06f3e340b8f22af796e9bd9c3476dc08de3dd9a21d3deeb84a85d50b0d1dc4015bcedf5f8a54bb393bc5f715a861f0a7867e6bd81b4749495edef6b250444cee946847ca063eae546e61318f8d68c203a57dbd3891b5ac4dffe797312739ed4156b8eb5b78cbc55e53a41ebf1331a7225d75985c84f7e3b1d1950957d48cb41cbe8ef23fabbbd65f51503791918ff30ed354a24b9feb0b0620b7f9ae54317367a8d6f6d9193f875cbed0d5d3f54cae46daf768a935ad605a932851d6c79f8dd54aea8ff13204f3b3fb9b127efde44e32f33f17a141ab4e6954ddafe5da972a48a4d728665170a01aa0a001de3f048558a94c082c272da593162e870366f9b0921fde5d6180542def5516750b1e6561b6aac17fb5cf873840cfe90f536f0c8fcda855faab8fe1d815ac2f08fb1592cfc1240855b156c444384993f444c6550f0fa1698276f9f40f165576d93739b5464e0d4e1cd71451775b2f45e4ce41cb61a933d6973d3333eff03e827fc93bce8dcf4d48678f08aa6edfd63822c97c001fb2b649aedae37fb3ad729cc923c71d060184ab27fd0afdfb5b216b2d47109f867f92c992937418a9537a0c92bb0121e50e6f215f18c139e3a2ad1dfe72fc97742fc7a9344367877dc8f3dea50b008077f7c0f0dc7daff1a1ccdcd4d9dea3ef573a341cad444f94de523bea798e4ae43fd2eb81354ae3ff7cbb411e6e8c9d5fd5539c0e03a49581d9e06d59ebdedc41e4a2b866ead24371297882f776c86b4c0806ceff1408cc6a186c13769c46075ce92db9041d03c49b2f21fb31545bfbdeb9dc6cab99083e823323fca81ed29dbe59f47537185f93311cef72a6d574c507f797595aa188e687c5c0938d7b11fdee74ae53ca53e2a242c6ad43d6b726baf9bd58274ded79c93baecb976880e8001ab46d04e2b7fcc4b8ac29d59f8a49c9cd0b8a6534dbf645544698acf8c80223d4012ff60a32757c191a47a5019cab71ec65e91807c89662f1da98e5411713e890f1ffd2304dcf22eb4a419d55acd21f26b198bbbb4626cfc006ebfe9488cc7dd3e9f535d323999d27eeccc41590a2815f91b36bba2454847769df8ac7dd66a90a9fa94390995cb9c31f59235f00a6a827af78d7ef6f6c42cc2982180b92887edfb58a3fd9de13b2cd169bafc0c013712fe691f9d1b22e27bb3afcfaf23990eb9dfebf8f284225aa7d70d2bdf1d21c8f3165513c1998589deb2d42f74e47b5f8169b02a3be166bb1012e68b7fed3a81627bbb36ce4268b350971289f69c933d6f7bfa13e9c77f312c0049869c6ed3bff070edb4ade0324b3677fc11503f306072ab916c3f402e4c2ceb022bc43d8d48aa52e8ba91cb4e3355d5178e4adfb92b2b4eae379c442d372290e3b7bb840c3c0c0cd15e9a5a086359e32b9e99e54c611b12c20eaf89dfc6c779e30066a799a7f6053d3523344ef062debeb36b5702fb75883564bf2743988f3ff004f0a08720f7fb43c1b3c7d3d3e27ec12aa83d283c344b1040070d0a9ea91544dfdfe9caeaa3dcb2dde504586e3e7a97a9673cb55f9e75a5ea53c2f8afd48df996279b300c2dfef0133abcac6a679bc2586f018db24ddee96d03b868346d678ae304cc97e76353e5131a77d8c09baea78bf73d4d45cf6aec20ec71b1a168338f7bdb13f247e46f8de063cf70dced137f2d22eb27d189cf0f83c533b328781a6ccd5c92cfc25fbdfe5b065e7c07577da5af4c208e32d237d69068ef0799534134f4f3868baf0de0b7fad6adcb8df79b757b4699b33bf7de545f901034233d0caee4a412267e7a7930b72bc6c32d5506d642c3dc7f44255be8cb9171d8d5396d2400d4bc1dbd09fa8c3d49c10be12b79b8229c7aeda444387d5c76b55ef1c0d34af9a60fa043930f4473bd8e3e87d1c9864d314a537808e0dd9d57b1232e2e3931da3921f96dfae23dcdc92f41c01bf9c5d814e2867c13ca9160a37adef809ee1a793380140c3e36daca1530bd3735d3603cd937c2fe9d57a4503c43d7bd07c7cdd9f5231c3ddefb2f07d1507a901429435dc0eb364fe434dc4d0fcd2137a89f24c1e73b9aa648d7186cd8cdf365432f4f6f2c68438ad11ce17bf01b3f2964835dcdad8cd6230fe706e0c38609ed5b6eb20ab01fe2eac7599997c12d42786be6c4ea51148ccd7971b7918ac77dec874e886df655ed25ba0e7e957fc8efe33f5404b1eba5a280af1ff2603bcd9137c8d3680897634038f6cad3d159c576de3e46d41d4378eaf8879aacfa33c3dfcf02c44a5ed4e9751efadbcf059e332565d53672b831e8bffe503e4b8a4c5f2d1150424594d1af2978755799d31d554621129683a35b88236dfcd950e3ef7ecf2c328c4a9e09e1dd9dc83d77b2f904d6d50bfa67f5a3357c675efd3225a5d2cf2a6bb423ddcfcd8d69d32777a8418e986852ca318af4a1fb328aef62538d803a663279be59c3c1f529721d71b7b582227a94424e0b7300c2e5ec064d4d24ee521c6a1885a5039966f3f4f5ca2ad93cc123a77e2a782cbaa48073987e46032f47a4d0cb8734bb5d66654d498fa312c570b1df8ff989bcad91eee6f620f30d33568bbe33216ed83725139e9f74c57e936a6021e0c88f86c5150975597e2c2590beadea2a315bb53f0c58aa0dc2cb58223d7708b696de037b112a3b3cf9f5b235458957e20ad0e7cad097aab6d7fcebf0fffeaff6e50aa40064d750a2bd0281e630dc678b74d65d99714a0f248651b574c0cfd5b5d7a06d898e83279c7f8318553249610ae50111f6a95775f359a02f54e2f48524c72012867efa273599e338590297001df2df3bddef5075e028df52c65de1f4934e4fd012afaf5bca823aa3521e1262fade05bf61ff26e7a562c623720187a22c577bf68cdb1b8339705138bf57273d14cb03cb121340345f0c0aadb6df4a9d4bbd380a2a9e83db1b6d21e1ab2f990e3df1fddc31190b3af2d480239eb5d0d2d90c2ea807aff3f5a9b699ccae04076e0ce81d6e9127acdc3b41b737a32de8357b7b3881ca36b47c9a6864d16021aed66c7f6f3fa3e6f2d881cc285d8f9044e7a789d3d3a5c48d39cde7198dad3691510251e9a25598ca368e3f0ecdecff39227d8e6cfeb898302099037feb394ce66de2c4a1732e90983d3b048eefa46a43cebab4a36efc2a6dec822ae584a5dc7334e02406872bdd012fdf8bad77ddc49eaccdd62ac1ae786369e7c82cd8b7a634e0bb896dd8007b9bbe721d49e6d11710a510796fce0d19231718c334297082ccbc1823fb6375c9c5d217ea7798f14e0f55327e70fd47ef984cb942ad149a790b8354884042ce462a6435f36842325ed4fd328bf26862b695e36370fc47abe20f31da6c11b97c9b8c0bf95fe2ada2668dc2e93afc401780de6ee0348c6ffbdc726e98040020cd11c18ba1aa3f6209f0a02808e004c6089eda0a4c32c9128970db57913ecaefabd81c34d9ef02d009508f57aca2ac1c443a1c2bbcac278d8c6bf6fe2cbf5c253186855d55fe4feaf7577340ef74c01821a75f0e0926216012d4906d8f9bb2ac5f525c1207f58e74e32cb9ded85840f4779cbff04d25ffb2fbbe9ac034838dfed334a7c91f2b85e172e87b885dc567f4abe55c52840537ccb0d84c501952808c08b7ecf4521cee222400a8b657a3e655efdf2cbb02aaf535bc8174088a08fc39d93aa3b9bdc149e0fed44fd9298768801fdeb8defef4e3fbd35d219798c953b19ff13a81a0efb313699323fdd51bc3aaa5e18fcd702ea49b710362e2d71438ad78929ccf73ac33b09dd2e509783d0677f96164704310c01ad8aeba2db2e978592862ec95159910c96500938a2b297acea0d789a3d7e8088580ab1640ecfe6a28d8790de35466cb224cbd5cee65257dfbb2567e1f63ed7714bd44bf7b7f8276d807ab207d01480f799a25c03e4eab186c83fcd1a7ba3673b4c3494c7e13c8ec54da7a896bc3930de888c0f974d7fb1f692c7727a3c55fd8bd1bbc76d8e84e7a019231483687803a9a4033116c9eeb82c8f2cb912be7b2010eadd488fa1f8266114fefd6702bf18ee66e27627f327e748da76d85a61afeafa4e5c8824f6c409318bb812ce6f28ba01e8747f778fdada02d213cba64393236c915e9c93d7ada8154540bd68b9fbd2dbcbee6120f5b4b98c1d3433b47c395d7de96bac448174aa2ea11fd82bf14f6b1855de95d00b2e7781ffbb00dc3d7a0b039895bef468d2ff0c4b6f52f81bfd6bbce0381bec79d50f0966d6209b140ebf6dd27675498b4eeef25849673e1050c71f0a6f252c838ef83413202081df8aedbd5325f86b3c33724606d4d7d118c98fc1e9908d5fc4cb5379e2195703a545d4c480b5f28b1f0e8f298a39d020323d85c6628e58c070c03d25ab9df48e13faa8987c3235a6e4df22b95872cef715be7c18b2c433cf15555138f0652503ed8d87f39cbba5b941aa7ff05db6f0dd19772d0eb9ba2064f3691ef16de4f3434b141f0059b39f11ca56753dafc0bdbe973c245c65f4e6820fc850b56c9a1ca12886e429316818ce443497bc2fd2bad2578c86c3d6661f4d1b56ff89c319e49260e2c6960804438e1a09aea14d92b696c08aff3ee71feff67d1c79a22aa67b4012560c663be8947dd87ac11fd774535b4f82048a268f86be1d7af13d17503ca363d7427ddad9f1eb71d9625ed8d56dc3f3aaf88de6ea2b57e7d8237ffeb4fcc11b18eef95024b20f59f97cedb482920cd846a0e10f3b03ea4d3f8aaf4461053d961a013d9e4d44ea4149a7ca28ccd32ff6d9c7167fe1103a9f904ad9c8cf3f9fb98e8652994a69fde244b0aca3bc1a451da7e88bdbbe2c362c7a2195ac50b18f4ad77a607b16677b70b4ba7f844965523a0fd5f7764d4ae20ea8fd298170daaf9900ddcafbf92fd7de9d64d8958920205e27ac3f353384f8d28b35d69b5f17d173cd835f53b2cde51470c178a22a913914f7b36a00d76c0e1f7791762b8eee49f4ecf5c11d27c1cad42e40a92a9fd90e1b373f4946d2be74ee371f829675ac5762e78194dc954a5691ef7a3a9dddc3bc99dc67411a6b99a2324158d378312324fd7972a7284f08962638366b73d07d7a4d48512c609930c86e7b3e9aad4eb667dd592502d5ed021683c1d5aad4a3dbe8732f877ba9dfe1abd0158d46d92166c0d435de1a7b8fbf76588fa6e75f5f7e2151e1cb164e48ca14f6f6bd72b1b6b1a23754dc9f2f5653b6daea7820c3e4b232fb1c3438269c430a32d1e868a5b318832a3979661d4865e05dbbfd804ffb11cdd15dc0f07828163922a781fe32ec8cb47c1304128bd17522497bc8f82e2d438f8ceed4bd9637180e9d7c628021f1fc4b8cb9176a978cfe361998d1fc241b527f637a24153fd7c0c75f8bbe708b132352a907a71e8d93179f79bfd7f2a74b3d1f3f061d6443c6577f063328c7419856f70619c5bc10487545d070815830a43fb0566b07c5a483eea8a684bfe57d3d265c68fa750f90b3cfa1e7fed32f8f5034edd4023853f343219fccc4c4e9de7ea2e06535166d83fc5f6c47b3f07aa397499c711695b90a9fd355e479b7df266b2aa1d1103f380ba8a470095e896083dce49b210bbb5b6541fcf684a9a2032fd3d2a7762fc0c6c45b471684a11138afa1588247bf1686bf3ed8d354ceb55a9c316622d25ba4c511859b3aebebdebd2d568dfd15104f611aeb3507b5d602375e9daeb5549f8b14a545066c92f79151862bf964fcff1411fb54154dad084e9a4faf229c9e2d24fc5ba417932fcd53219a22e6ec53b040db7922869691685e1d122c7b4c13b9e691bd3dd906649c8c79b5a24bca6237b60406319bb9b66d7ffacf0096951b304e061f2d070235641c2ab0a275b7023ebf6d06d54ad7661c589fe30a2d2d43858c681f719b8e57614b3b8716309f6214a6a49f1af6a87f8f9773a5663efd26ed551f1aaa7c3681cf7fd2a22411054d9cb3dec61a74244ff9b98fd59d70628a0b0d24b45343b075aeebcc79b967e9586859719aebccd3a3fa8afda4750d5aa0cd0be2594fbf259e9c205c167331ac251af4117285a85512f204c07d6dd9dfe8bc65c8b20f7f3435e2b656730f40119a9e5c2fc30b9573649a92333fb325590b058c762d3e092f6362b4a3ea88dbc165e342dcb120ac26718ace76fa3c1c6bab9c9f876a8b698c9eb0d3989162a96e47b6be847bd1a710878b7d25de8bdd78db7e85c6d05a468ac458a5e63ff1bf8749ce52850f372de448a37100066906a1ed6ec18589ac0027f0af0ae511d430ce08e1600af737a8d4033c83abce74688406e5ac9b27537436924afaa6ade15302b1cc68f9fe58aeae67ac46b31f68a858b4400fe10bf13d6aef68a5d3fea2eb69c529e7c30a5951b151430ffdafc86168d84eb8413662de4a4e2fd7afbda7b55461ddaf8c5968e2e8f5042af2e88b0c5e968b58fdd09971ca74a35637c2f9c34e95710a9d730f3299636d8cca4ba23aa48de82c59f62f3b670df31170375ff343d35236e8b74ef371ec5f7b80039a153fbed0df285b670b0653d9e93a3e1b269c69f8d628e4aed17a3c4adf28a06828103519bed56f1bb631e6a5ffc9842c49fdb302deb8bfa3ba3f85be658c2eb7f5280b0f130457446bda28a4f901f987df808eaced2cc3e901831be23d6c645881b3c8200bff7456d70954c2188ff4e8732b684620fb0af7bdcd6364d9da045818558f5ad758a84f738bef5cb00e3df87f490cf5d227f2ddc74c5b6885f1f1d49271399c98bd2b0465c830085f698fde7948c2ecae3b7f298ce354dd3b1e2afcfc8b9c41459641a120d8a823341b4356eab521e110df2043c03912492889615215d207b5ba3e77e72d116dc9729a1a68f4c74bee0a09c04b5eeadeda6e190995f95d1c985242d3d8392cd4d02e1708551d2aeb0342187fb1ae3fd3a7714538860143eebbe3c627fdfe2752e654850b5d2b0a3669c9b0640a50d872209f6b87bbcbcc36dbcc6d198735895ff0b9d9df435ddb51b718fb1392db59a1b87d8b29b875d4f5b5b7af99ecd55da4d354297874a10c64b8518d3f618920466a5f5a360c85e64e34100fb33d589400444a84e439d21862f531eb0ca4e1de4a09859689fd6f550fc3b8f900702e26705a2c80588a7b42f4ac277602567d57cdc1bc3f5eb2e0ecbeeec1caafe3394a3dd8523d0217d3bcb66c760c4188fb5d820dab873fd969907fbd1bc8e10bd96506d82ed7cad1d0dc93a678b930f826a4879b5a6f74d8300a40fd1981da2595f30200cca79a4506465a54373df0e7a4c9b0a4f0dd48778e90636cbcaba1203fb72d1b66183156361dfdaeea684fbcca107c804669d6f5e8c5a5db6c97e5f1b39a89c542a95c125ec3d95e4f147e7ab900c1893aebc28368f792b19499e191e269ecc48905a9b21ca1a633940781130d820e695472937c2dd911aa36e46307f1de08de719f19bf664958c44064849f8576df8c4461cdb79cff39dffafa23ea7eb15eec375cd3fe2422da73799e0499de08885e061cafb0ca0d38c2bc6ed26e0563eaec456f69720cc8b9c2882fc637f025859d7a78590e1f1f5dc6374e6e3260502a3c8576e86f3c97a162bc62dde8bda1d3ea0e1c21f40559204edef00f458ed3a3f906aa434233bf07d589e97f2aed981935a7c467bdc3a0aec5f87d3d048dc0786d46f12843df04c0b52ed68f7c3c8b122f3b6f26549b03d07297c3b962078ea031637876b7ffe1184b53134244f18f137414bac450db982efab218cac48367b0347af85a50b1402d5416987c60b9d185677b8fa4e34468c26edb6b86b08b321d05f51f39c1181aa35b3923e51785518ee9e44b45b83d1f4292d21bdb51b81d5d8138a6b70fdc4c2ff8e15d655bcb857b967f68f8e517b3a95eb1e51b76a14cf6811d3fe2d78cefaa259a4c0e1ce192d56b5d0e3f00a4861e4c7f3a67f46b5b8a98e428520cbe5cd622ce30564d761284a24fd6fbb894c26d79db2ce97816264df0e50aa2872e7904180ca3d5bd2845d735f4010dff58717f5e8f2fef6dc89a0540cda1bc75ee43d511eb815e63d436cff6766f4fb9a38bc0a31d70c13157ebaae83b881d88f4616863bae00e72e67f75151fb922174a757ced101d8d92133f5354dd4fc734208cb82669112864af510b410c284c5f3766c9d0581190770950e904a453a8a3edf2b978d6fbd6ed6fff2a2c4668d1656aa342f3cbf6c19b68a291642e3400b7439e6ef1c19fcea87a01c4bd292ad25460149d35116ada194b100c4817b18d85299b3be893049408865b269b54069a1f72e0c80837f02004e37e5c781b32946b6590a4f3ad04e3180a7dfa04373603080db4f0d4712bee5177dc401bf1746fd86fb6c821c01000c050a09e718000121832802345a37d606db5f2aaa90aaf6c81d953f4a51d3aa26c82db3e9c664d6c1492745bf9f941c1f63551d2834fb8285ee51837f681a505df8def47e510a47b6021ef83f046c79bc18a7e8be81ad6015a2a23fb7fe81c905f2844332560ec5fe46a9ddf59ca1ff8d2403f3194c0100b690138adc63e479fe39c4168ac796137040478edcc53db1c979bece0fba78d62ea78e73f791dab69607035078c568c20737231c721fcffde8cb3a06e082281eb2f5535376579efd333aba823cb8749ab5439b39439ea99861e6476ed990c643659ace569c5f557ab224bfce28f0c51ab68cdda74523664fc448f05b43a3d5d56460d69316e7415c012cf76f32ed0d1518547402ac6ad00a7d21a9305a1450f6fff423af9264842fe860a8c1161380001b3c3c220c64fa0200aac76b36db5fbb85da81f5e41eee0e917910d757e4eee2cc6575a8dbbbf14f663f3b7cd06a4736005ace30cf8154463d34c64427628fbe47616b9a1ae9cd9079bfb13bb6176f997b918aef843cf02d91b0943536127e4645aac44d9bb77ce517d3b6791849ff03e8ad8a3258b4472a7029e83780aa911410d69d3d8ba9c0e2aa09e739b76fb06c0a9e492f54232a9d730ca019abf60d137739268415732c674d69172a612759bffb3d178cb06f95fc1884bddb8ac423d6232fbd9639f7c3308aa5353549ec2f9ae8ccb9f33c5e78800547938c35096834b685ecef8b95161a8e3fc4a7d54cb5705a5af0ec9df6f47cfb3333a69e8a4d1c6f6c38ec7dd93a5cd201fee9d3bb16cf78c52f8f4042f6bb64a926592b9992492be5806af107fed65e83a54946fe0648a12bcd323a63b39c014e6c2ac8ec21d01ec309d1e649385c3fa3eb0c12ae2d0625d0903981b5644210439e24f91f3eb556391cfd5f50d87804784354356733b260482f06a9e938ce31ba070593e66496906c591774395b88070c1d99e12996134c0b8180fb4f0072c0888efe18a9f6626063c70e67ef21c9becfcf7c168f863458eb3f55a4691aa514323a087528b6c1f493646b43f55915bbef678a0ddcb40a0987b4debcbcbfa773b4551a7c409bd256018bc00ffa363d8f41ee2522aa55002a5e6c5347189348e2644ca6d39cd76cc3e14df996cac9a5530ea7ce4cbdbd4049d5f066277a1d0b63b11d3a6145f3f7932621981d8e4fb46f29ebf3934c358bb4a7156dc250de3df7f5a3bc1b0e9ea8dff526db12f9ed1df40656b57451be39ff9eab0ed17e29635e7927485734be86993bb618d354315d42aecb45f04926317c92886746ccfeb8eafec4099988cb3ad3eea7cd3675462d2e5c5f5dd0be76f2e7eac7e9fc4646cc7f97d59529c883fdd1e5d3e74358c6b06c6517a84024df893940b3dca4c28f3044b69617fec9cdc2623a5f7d46ceb2876c79ea00af268b75caaebc581096b9181f095894abd794d4db827f0004300ca994df7147f8fb4acae257cbe1385e3beaa4062d1d269cbb75350aeb26fac36545b90f30b118fe469c8b07b9d86889bc142a0fc4998f4138f5d5b3a5c869adea00c998319ab2a41c67a56cc815a01acc199dfd4872ab4e102bc2225d29d8ad2ca29ba423c86d959f6ccd417274e89c0e45a40ebea02c7c0ac184eb0d36127c4ff744975f105b8daa2d137bac522e0cccdd45b6ae8a398d1230b875827ff8901a5b200f581f4576c7468379403f35dff3e5c5743d5e694b218b7252fe67ae3e926d48701748e1c64137fd3774042933b272854949949d6da7e48f0a1399efa0accd2efbec808f8f32e77fea27bbe295879d35c0905c6b2d61fdbb67751572a9b0fed38538cf17031bd979c16e3eeb1e1a67346c32f7bfa7723cd84cca3681e7aa8a1337a2716776394032a850c4d12bb8d30db89fc5839dcc6e0fb48c2c2d8b45103ab7fd6709caf924886e14be607404e5d3c47f1f6abb74a07d47dcdaff85cd179d038fb107e8046eddc4fc6d0087d83fc9d91f283fb41139d2eb95ba08d7ae7bd5f0e40413e13e1aa1e3cf627b9f856290aa09971683db59b98e9d6162c5fb10b5ca9f0091431d82ecc479d6984118596f637bc9ed8adc6aa92dfc3a35b6dd098c1fab3d55d411a121aaee6cffbacaa58e3fac01c62f8fe15f6b7e43a932eca6ca1bbf2dc10450d5ffb161b09d213b45f906dc33ce2f9f7203eb5ae8fe1522d01bd0f8e4237cefae5199c13c60f4d64173511f6d0fafebe9409fc5093d90431b1055998704135c46f8ecf89e70bd26d74fd2342a3d247da9bc736d5d23b6bac2686dac8ccc708d997b354fb1a443071eb023a4eb4bf9f353fb53569c9ac36bec37d0c22eedf21d650da69e08ce0633da9f65a9e6b644c924eb04aa147fba4e7925cc588275993421c56657e9aa91b2585e627f22b4d0882f62498752da62ca6c39ce61833de6077c20357e7f42d32b9fcf6f4b99c902ed45e76c0f3883f3fbfcee4a77de44a6c27bcd0cb9334d9906b83c485ba4754a9783f68f48109397abde4b9eb5b5b311376e207f1e0a5997455ed5c5f239a3df3826c343151bac3cd3cb8d82a225f792da7cc2b1321cbbcfd4d4fa0c03f9aa751597c08ae392326078ed9a29ac16f2d1cacbbbf255cbcc759798cc156923e6d48a0a835b2a4afb7c6a5e6b9f16dc506dcfec5be4832972ffab3f44be86e799c5337a7d75c27d411269c051843989ee6d532f742283fd77d3a8f4635766a5f33937af9092496bd1ac04a873fcfb19dc512e27ece8008a0e015dcfb3e1db92fbedc9aace90c925cb816060ba9d679d82a72e880a2533214f0ed78343eb5113096f9e385f7a82d29786871cf8b9b4dda5a6e6c2c443da95cfbe5b09dad2acf4c2daeffa28c1957dbe1363b4dbd32415e4037109d3ff2b55c0f59996b6089866ffeb2c83bbec4e66a6ed43f74d8e353c1ac4d2848c91cca62960c888641aa52dd3788c619d2d7c271df91bf4595731fa0c6e469c082b2024e7068e39786e440d3c26d6082621242330fe0550e7b66ea258a3d5748fb81f33a570be44e1b23e91b57fc57d701f0f3e9ad07eb4898136e3ce20999a51a666fe280464c2f5bb847c59bb9f3d088cfd0acd6354102878d9bf457f89624da5f89efd29565f8e35ef9e3cf2b8e8a33a949c6f9656578e711195d6efa817cc740b7a11e2c32e009223702b48dc82bddf3b6de66bc276daf16b05c217c2fd1e8db6ea31926d3d35261b412ca3563ee1bbd1d8f474ebd8752a6c7b82010455bccf7e2d1d0af56c64887d9d4ac415c943b135e242ca5404a35a66123eca404cb4a71044dbb17241a3fbedb8dfb8b912cf6ea3d69b27b87e28b73254134b25687f0ae8c952ebc3458a1a77b4fb821945ce13ae497b9a50f72a65e0cf56f5041c3d9c8a9dbff8d0fcfce0d3d38e81a5d98da14832c6100eb1db9fe7fadf7b8cca83b33294c88412fec4d1db89fee80d37a5439554761e364b5a48d231c8b1a602b57bff638f6d31887804bf9eb99cbd3d50356884ad46a006a4f03b9af135d9655c3e807ff69dd31ff605c1a9a2cf60aac9fb4e048831078c2500477b668b1762477a49519fe85297f4e760a7440daf5e6de175ed8e61bc54715e5371207fa4fe6be88928ad0cc7734a871d27dc8adfbbffb08b3c508c44f6e2867a18db2a0cebbc377388638a6f01686dfeaca251308c03e9df9f30a4c474568bff63371f6119f3a4e6670c0b366cb728d173fa17d7b8ca2cc3e8a9466c469bc1162d5a8fdea82e03eef1e10551723ad160b45667fc111e63e94744f0b796028326578f4295d38517087a40ae4782541cd3a71cf47c610277b57d8e35b23b7e2ae15ed9ea0ccf38a42d92a5349d6831a72f282c7caaaae604276518308bd7abb8c5f6503b862f2e6eae1958df4e108a4ef2f31b29fea7c6e68ea4f0069857c70b0ba6d2bf019ebf065d36f85789d7f7b0d1a09c38eb2941f35a66268160c229cf37e09e5fab13ca0414b143a8cf8e06910fa4bda86ede9fba950fab8a1a7f980e7ae7aafa2b30d4c513c824a817823b217bf5aef1748e848bd65f52a3cffc53f56835fd810dd6afdf99cb3061c4177b9cb366757049367c8b62e4650cb49dd5f3d03bcf56b835ffa646fff665975333edd9da177b79ed06b7fa4d213880e9bfdcb0388b073add75775f1891abf25ec1a3387affe71b96bd9cc3e0b4c185dbd6fbcd4445f92163eab8f8d4c0f5575d30074b25830c3b3c596ae831295db3d02727747dd4b589f07508153b2adb59120dd1fc23147a82c8d3028f7171729405cff03573167bc8f6b7e1e4c95eff5a66e7c4d1ac1fefa24b70d42ecb7a223f6a024953102e252259f991876e6c882d8c9fa464748785bda1d2259bb6106253f9e49f5052b36ce691cb5420cbdb68aa9f95923a5d92c74863b90617f3e498f21b66b8a02f94011fb0be587a65d75a6395c0b7317a3bcd0696dda1fae2c9d348c0bbcd33ea997d0e3a2f2812ba17f508f943e70323212a7e7e5ed0425b3b0f4bfe43fc2f4fb72f5f9e8c034fdd72e59f9260525f6f6bd36ede7fa72dad99f06fff8fde344644d702e3c9cabf07583636f39336dc1aa5edff3bfe1bcd4895c72b877488bc908bd0e2566c4874a17b22adc6380f813145787cb6ad7338c1f36dc68c096fb7aaf393d25f7c00dd2e47cd23611e14bdc27ee0449d54166d972dbe8c20561e1e3e869d442a0a0ca6e882ea851b1f70f4455273a3ef18b7a34350992b3a7f467c8a20936c99399a0ba62fd34e06af4221847331d468b06f5e511ee536d5f44865962cf757a1b8d070ca0f9230a6724092f2f987a54210ca27823d791914f3a04f81028020024ce5bea36ffe7b117b049705f22afd2e23bd625418103b79858240c6a94001e695117e9156173c157cebab293f3a3c547eace7d1c38f72b361f8d1a861c94faba9320c0c948071afa9a474f8595070479863bff80404a772430febb5685d09f52c3a40ba7bd6d3f9203e7daf49a54e0b9be1b9e1634ac5de55760a78026b38addd10ff60bb8aeed125cb1c080b520a0bd2ce62647875f62f658bb4916f8e09c2c3c889766aa39de62b2f15c0156e87d67a012b5570370842fc5b401271cf40f0fb756904e44be9043e6ee1e43f14ed313dcdd7e327e05eabac5f644090d225ef564a5a290fab16194c3b10f22cba5b6f59c39d6aa9b230614a05e17dc53082c5a3982abdca1e75d3c488962043ba2ae94eb67332edcfb11aa5baefee8ad655aa87297ebdf01af6bd41e184beedf7194bef3534fc0f338d8b6b7010fe80c3c43156d240b875f346bdd48c6a22875cbc3eb8e712bce105fbfba17aa78464c3ec7febea9511103bf49c9c37fcefba8efd6350e5de02bcdf1ccdedd1387c8085ae67c0e27392cd5747dde939745775037d1319b52b5be8841e5e7dbd4852c4930ceab4cb99477afdfbc83beb51ca25ebb76e8b109d08232fc87804b121c543c830322293e6b092c084fa13e92f0ca2ac86dfd58f3e4efe75b83ed323f07ade320913d61638e5c65562fc4891c1cc30eb32b7bc6cbf093d44681919b5d6058746a1a9bca2013040c7b4866946205537179d5d8aa565fc4ccbcc6f7f3df96a09057b963fe47dab0390991bec0a0c2ccff95e18f9ce4b0a694df879ee953da0e92ae5ba63d81479bddb9f7cc19746c037a1d17ab5003914bcc67c66384a39405d3ed3b57b2cc86914fa949c2874f572c447ce05564660ecf8166875d7fe62f0687f4b94bc12f89890a8ca7b81b6307a6c564d2a5a7746bb2eb3f080ad3fe1114c112e3066e9272d12c14cf1b771564c36bc343c270ea4b373c6b79a4a966eb0b5de52d1fc3d186c46ddfe539bfd5fe83b13ee88696a40f1c3903f8b4b03d14e15c4092c92e203b987a8a5ebe85c3a82bd1c994108d11ae99c1c0cae701977ffa11545a67cd9809fa7cd0f5b7792c385873f8c55081ab252fa752b8500b840d7f410d287b9098f8659e34e4ddfcf470999e24ec97fe29a1cc4d3ed55897464866e9c775e08b99fc7108e703c042a251dba4dd56d2fc49ee6b1fd954d4ca66cbaaa6591c738c81f5c52017be6fb7266811d2b90cada3ae135ac4332f4731af6040d6ede06c31f2c2db07a9dd3a1a2fed9219dd52b920a1dc076fda4839cf6b0d5778fb2907a06edc35bcacd22a6c0ab90c7f9f96f8b64c94b278c344239f2500e6b324ef09ae4ab2a77db90ea2205e53d299c777c70d5c3a2d68f8a6e8c58ca1985657766106d3218e9836c0e43f67ceef5383afb8733a61871b2679599a637131648b1d3ff9565f016452efad7987cd568517bafd200073a10e2d3d156313f791ff4769932bfefd6170426b1a12f8117cb9cf537c58ac2a6b1d52b16920954bb30e5e5f99dd51046761fe069faa5a22d05b0aad4e3b1bc4b04c69c747671342125a57a25a43924801f96abf29aea0cee027812d0144a04236e888ac29f207f85e3fb5dff6e172eceb7d94d53ab0659bba376ca245ba4b02e92871b23535ae1346a039c898f637272a87a9459117457bdc5aeff87a4d57e16139655073cebfbd4fb71182cc9acb39ed04a264ffbf3685c5ca43d3ecad9019238856cc73d893c5ed2bef0f73c55666238ebfd9f4911c7046d9a7e7961c463141c47cec2437151197baf9687c158fa6d126511c0161f977e12bd442dd4da8a6ae79617d16c415b825bdc56a0c21928916b107005a47b73af3416a407be74a06983ff8ea9fc1415aaff4cb2922af012e7e8b390de4e323d1e794881c5144c73a949e2098469fbd75ab4437f62ddaeb0cd231ad72b8d51c4d06289bc8b0dac1ca02e4e6b3e77aab896c8191ed7f33e20f558ed49ce45f27b58a1aa4df6114ea5440d85880ad0325d5d836dcdd509e35a36b3e8f0d3092082e8173142896bc7c8a69678f4dff1641d3942e76642bf7ba4a81756e3953773517b7c65b2e1c7001a055e39f962b78bba3e1fb3707d95da73cc8b09851822564660ecf87caf5cac0d9dd968384d8be396f0637525957b47bba587367f15e1f92283a3e8b61bc1984565d760886f440e918587b06b395f42031afc20fdf52d381caa058f105fc710536d2c9b3d7ab73ff5b6e06df6b87d943323b6df7370dd5de6ec027541d8275c6e5bdfd145e494b67afd5945df6d51beee5e3c082f632e7cec1f8720a91dbca148c0049f93806c035a2c24b82619253942ffadf38054ea82a65d779b328f67524206803be1f7c3ea0a9aac08b4cce8a3d8f6fba87cfc056a4950abbc97127b2fb6cd1c2da1254b9c982f3e58356c966854241672730706b316b91763960d80011d5f697e47085da11e50fbe5da3faefeda203fe1dc7b8a79199a11992041c2c703308b82f3bcb61bf8deed4073dedca6ed124bf7d674a7c50e72ad72a0d534910f7604f41f23268e8356d013abe9396358db2c72783d51a82de512b30796fdb157939a016813b8b3252c163f55302c00bd57d4b2f4c2f6ac9639101baa3af0498974b396a30a08c036c7d8101d20627e7a10dece6f94ca0d4532581e064dd0e47bbb26cfde84eb08bf19c243ee0b42e1af4fe2ea8e94a6ca10835b053caf21df6f584595b540116430d0ec88e64909f298dc01ad38be5c6a3703903527afd01502459fadd4bc13f379a1cc3997f9bd2d42a2b6722058580ef781a2ec577c9e13fab0c3723ffc4e6d6d5d4066da01dd7025aa253643674756eb04939809692a4910f63ebd2c2d472f17f7009562e7f5c1fcfd095167ea4decb5aa75ae273ab2cee0121dea23753687600a778207c000fec2db5c2dbf873f791084095ecd3068bbbfa011106b70818afa71d9e48e582700285ca3c735a102f925e93ce8ff03d1f1675e247015cb716fa8aa7e19febaf170290782c172665cd498b81265459c9e3fd5e17afa803231436e929f8f5515624fc6acb3c440cdff13e69175b671ebd8a8c09caaa06f143a4b663ff8c4fcf4306d83f507c11c331fc0198c52a94d1377720d656c1dbb9a3fa4d819247dce64da40b368e34425337f97fd504a93c4c22508ce85a3603a312ecb5d70d0912a87b14ca767ff27e1add0aad167f1c1e4bfde585edec68046944b77377ae272527dbb95f4a115973eaf674fc3242d2f29d9e18f594db8961e9356654fe91ec871b352be18d068b4608261f296328a794b76f3eb2d6e19836dcc8cf67c70860245f632df128359b0f8128646a3f2630adf9827f087f338cbb58b604a892034833a3eddd8f9324050d374fc5420c20f24ec32a9d4ff4657ce09dce9bff2549b03fa351db1efdd525e9a1ba3e1847f42aceb77cf353cde6bb23ec6b307e226c6d7b188d70e2f309f19e822b22b41944fa4cf8a46c04aae4e24ba14e5a6ac134bfd8fc560ab54a54d6ca3c262918949c354a27d678b42400cf61ecd59816c5a16940c32773ea3e1a74c74751685abe90018208f960011e0548aaa7d1ba08a075a53f90a98c0210afcc7a165e980f7f4ab0140448a3ad2fdcfa690f117dfcf5601993eaecb83627d7788d1d9d4423cbca4fa4331891174590e056d38768984d48ed51d84786b4edd70c05bf3b3ffc2cc206931b47822a0592555c77b7094c7e1c7272567c1a08527dd2092370201ae50f28008d72dfd8b85a8956759d0a4c07b28bbf6de3028fcd0e8c1460da060b26c92db043bbc3231826ba33d032b466f4c39fe31cdeda3a62f54419c2fc72d48a3a45a34ef8ec8bb37b0de6b0d6be9a4726422784e0a7dfba6eab04e134cdd683c686dfd33c88b0c32ef2b2b7bf6ba5af0c3efbefce5571b411d526e0f6fddc0a3b871cf3d759dcec234de25148fc490f296309dcda5847980a7fcd7b02730f620e520370f9f188ff1882d5ab8ba8b0a75a091a61af7d8e5c1a66fa1926fc40cbcd13c01b9f68c51bd6ec8b36533f2098318932c06b599d82157daad3508bbb382d537ad0e21c74b66ee0e4358d3f15c47157ebab7a015b9f1bcefc9730dd5ed1f655b688adab070b6787948962bb20f8702889d0f7bf2638655344d259816c94bd3035c92a9cdbd602a05277e52df5daa925643e41f52c7a66f142761cecd63af75ebbb7a197a702d028859422010075c9af6ef9e81f58deeaf1a9a275793b19ed7de65442e53873e330cd0d5c5a1281f0302b62c0b2d6f969d927343d42e3a756bfdeaa8e1efaf16d4ff11c7f03769dd07e1989e91b7f71755347e253737bc85f1345d42200d83b3fd40eec348da9326aadcb821b3e792d1a149c6cdbc4e105fb027f10950f86f5ecbfad9691d566c1995c5034933d047481be4766079e613569f32972adb096e596149ad0ff94054c252d7cc8b19735a725c12575205ed49e473d2f6e5857f2a5522ffcb19c3f53815d0877ae09bad26fbc21a0183a50928a9c3e7f243ac0e285ff390ff91cc0541c48069a8386f550c520226774a5a641fde799649289e1ebac82dbf1ad9dd5e01efa92722392e2d16b19e26c397f899744d166114cea6205fcd78f18e72fd471951b4fcf8cfcf1484657ae2fa206ae4caf66fea6b7678e580d5ade484f9d960a525cadddb0051cba5aa4d01b382a1c29384be3844c2c290982ec8bda3108dc4172d6b8e7801197ea16e2ad5a60ecdafa7fcaac34d6268fe2d4cc40d293be528f0127e680285858ef084d2c8f6ee664ed4bd36e3475b1add44fc2b5ff9daa83fadcb4db75c5dd8ed71d9cea4ae0ab9560f06c922b0524bba525a69ec670d8dbd58cc01e225cfedb715c9a828a307c5a111cd313d3a409510a3326ab9411e887f6f3a0191a3dec9c60a2d2b0837649c933537b8c4f80e1db96d1088ee5250d68d51613ed02018e8f227581afe93f4d296bd5edd670be647c5d91f83f100e33ac3df722b091a525884b267676fcbb714e6471a2ae3cb8d123ba18007b5b4f9cd080872fd04f3d92c599a4b0f679388cb0a6bde9872262c3f12b3a3d37f7369d428af7cd7d75b4f4e4b6e870f80d423c9daa46bdd98381b4528bea86297c791e921f544aabe5118ab17b46005d3ff2322cae1073dd1b5aec80808094b4064f7df518ebaf17a93e4c3d2356032bc50f027e54c8ab3753967fe6506ec525dc627d6bd818fb5def80a6f6608c367d2089ad47525fd2341e8d4f99db38e5660b32761483a16e37bfba5a6fc8decf8d9affb08728490e4d152918e63a967139bc9bdfbc0b260c6b00280436e28fe6a7ac7f12fc16c73675fb3900cf3d59d97ebdaba6ca2f2822cc22d343252f75598b44f17e5371700996caf4a85f66dc30bdd1dcea14cc4a30921b8335b487275284561be2651836628e2fc7b3e19da97f58d82255c925a637ce2c6737b546ac9c1f7ab3c5ff5ef9ac4aa6ce4539214d61ea80c4f7634d6a048bb0798488a292579f4bc068ab0a865ad476c2440d31f853febf8326225fb48d0025483d595e05301712e9902a86c0daad147ed0da3267fe87d3d5f6afffdd7bf8f52470b96c81065bc0f82ecaf55b44e14049581aed7a3a7ae1915221da571e21e944fd917da6cdeb669c655f45289c09021903dbe240e563836ccba8a6862bd93e090eb77c79c960c7fd21afcd60ce4f82e1c11492e5ef9dadae2f198220cf24a2541acf0cb1c4d5770ee6643b4e622b9cd38cd0add5a13c8aa82b40a6467a0fdeba33018f22973eabb607f853c5d4d6603f492fcb6203543d561cee94b08bb42e11f66d7ab7ebf7523670858a3413b4812d02becc6e3d6c44f97b649834197a116a10f9c9c6439de1f51ec66032cf866d84875ed6ea18ac5dba1aeadf8581604b37223bb5ae4a171252b00aa5260aa7f0d07d115b27cb3842787955b2600cf01175f7ed9e0c35c294a6c609cff85cfadb5a63b7a000cf8daa926fabc2fdbc138d7f199e5f84707e740e7009d28555fd11d142a69cec30428a5c609b8ad92e4fae33f41d558b70af18b986952e1cf75c8837f499441c55fed04ef6f1d44a6a5ae59d405e4fa57b741b65c620cf2e6270c67ae1c774d06aa6269420aeb77ebd70ab2d47bb52165e6ed6afd33713c2bd9b4d61106efb45dfa737f1422a39484734b467e061a73457f7ac00d04a2e36b6de0c912b5f76c2e3e25f950551e87f1bc5900f8d8efa05c43641a285da60a05422f2c44983b233cfba798e95ab037351b1cad51e0192b9c781d39ae4051bd3b27ce69e230fdd4ffc5f9adb9509602ecfb0f0afb5fe3f86d4341871fdd00df888564da1ba50f9ef446eb1f8b7fedb154ff6cf736074634ea44f734f768b03be20aeb834a2060cbf4abd197eb5317068a85c7c8a6b00261b4457d30bec24c151e90e9e0d32bd70595429b9cee97c189980ef795eaa041eec1279720321433100ce06576fdfcca7111fa218235515a5765b1ace8c10fd333d476ef27c718fdfc6b0cf03b4e8c2ee725bf9c88ac348b1489e7764ff27381a1e27b256a7dd79a4e928aee44998bfd980c1e7f7b3404a5da971064d52e8c8dcfc60fd19e5023ab6c8fc9604799e6ce99b83a320838e3dbff0186ae1416f334e678cbff1efb9f5fe527a25f1399ff1492ee73f843b72eea4700b5279e9008d35f649ae644e4813d1e70a7a7b762d9e3c8c65ab734be57801c3e4219a18ea1cecf216ece593064346a59e535f4f5feca64ac53081afd71e23212039987fd4d919d3f38cbfe459912d2a438b7e743468b8cf9c500c68b2699c317ca94fd092922fb90a2d603e3ec1e5d5bc6e8b240884fd393ec3eb8d45e9bb3eb09ee6e9f5b43913710f8663973901e9127d999b45ffbba58c1e16de4801d506af8270ac5768b32bf7285a4d000ebc99c2cd74f759f550ebf634718df6304bba83ded3aa1d4675520421d67e89e6a08e066ff48db1c6403f0b9ffcfeddb4313120c7bdcea3e3a0c5ce20ea93d659ed433ee9fa36c691c141e7a52b6b740941c06d235872574eaf62f560fcc90b4c58bc1b66bb6cd77c5b04a26fa1b8a63df721b074b4714440044a37d9c36286dba0a454c97025d53cde49b00f3df907b40b7268662522403e63ecf0097225ed9226a865c2ba14c86cc80c2da52b0133943bb0a98303b12a41e71459cd7036d3fc25661c47650c5f9fe887634d86b85915e26ea627c729195523c8a0d040341efd28f28ce3174175143c8de70ccbf6bcc2dbbab918e048cd3d72d56e8e9d5003b629df8e9678194ba5df1dd8e524fb569e145fadb345a51b54b9f151a8d5a927b353e3ce6699b76cef8f2414bfed30224ee291d175425848f06ca44d0f3c7abc732befc71dd2d87f7f6c1e81586df66b2d965b45862d3cb3210b43501d615d6cd264ceec123fbd84096c0f68930c810683d2136faebf9d36d7a01cc64ca4dcb7285794eaaebec57ecf2538db311e217190a2b014aa2dcdb47d2726cba359fda39298469fab2e93077616a115cfc8ede33f8f64686ec6ba7cdcde39ec14a0108ccc89723bf2c417be27e0253061da7821839c790a92f97954308537671af9ef3371c056efeec325ab2bc4095d0f7847c5616a8a9462ef7f7f67168304e314dc94277bf8bc44725bb99478eb9fb799e67de28a03d588af94599681c6c3db96558f185c4264e2b915b10b0f2d48295b1a3d5765476b58eaf666891769a80ca58739d4ef873583ea017466cae6b4e4833b1366f6c63dcdc89d5bc82bd1fd25b07324fbab2c023b422d0721006bcf08cd19a987e96ffe2fe68f7c829d115d6207b9f2cde387572df30e22f39e34deca569848a3c41de09184620c4494abc074040ca6b789eece7074eed140aca5a548c484d868b6da64b07c15ff657c882f916027014ceade441ea77886ea365c454514ddf897e093fb34f3ebbd251efb4810f7e5a47925534aa086ba128badd35902e49190af98abcdc1b61ee3d7e2e93865f3f370ec39482bf4e9cbb929a13d58b74cad9ecb101f2c9ca493d2c3932912f4a417ff5d4f779b0b1e6b2aecd53efd5f445bf3423f0b2c629a378c2d67ad2cdd729ee84853ee372cf2b6f1eb04645389acbf179363affe6b7ee3369e5e62e4e5b5f465d55e61e19c91b77715413a50cfb4ae66e525f026f39855f8044120ef55f7b0c206ab25a81dfd091cae91e0aeef531be93527fa45a2cbf422053b3765684379a23c031c48eeb473972149b2a53cf1f4202f4c6d49e78bfa9de52cf5578de04d0f72762a71de1b74270ce168833d56e17fefa16428955324011b4d7de2f9bb12339b8998ec48c1d74364326c3fb8a2324a7ae7d9f2b3599e2b75c5d4f5aec1c4140e2666065b599760f1efc6a3ce6e8406e0ac128b3a1b12c19874681a5e3085252abebd5bb92dfed0564973e68a6616f66dd7651789d36fff0f1b47f38541c6f86cc721832fce67bc6a734664e4154b6c7b9a68d89aefb6be858d19f5c495e2e4131dc8e4edd50973f5eafc8fe5f71dd0bcb28732d3bc3db297388712c56b65f9b8e9ef47fe292e9d9ca87ae8abab7cc69be293b2c5a248e87424a72dce92c8c6510064763a9c10ed7090a907ac47214a0dcf999c931b794b9f56c0e2de59d1e67e4ab2ddc471366d9e78b0519e50194e4a91f8714b3efe48ed8bf35b19613cf89762bb7b4cf91469b1277754e144a39d59ff76e92e33d7f77be846e44cbaa4a3d69150dac7b595dcaf5fc14801f7a36c77efc6d2819f1ac492b4b252e778ed4624d9d22977fd277addb25261aa65ade1f4a5ca7b64dcfe8475116334aee619d51c9d60d173ddaa32cb53a12063cd5fa36cec9f3fd617e5aee8f6296c9766e95a034c45b29d936f36d64a1504b02b8a3603ab656d8e1255631fdbbccca11224fdeee2452117bcd5bf7b2188dd4d3d0fdef8f0d899ac24ab9d43ea6440c1916846318f9224b34734cbd49fc8159b31a20964e7af96960d79fc3d0010313aeb17ae28574bdcb448bc3ccfa2f8b16fb0edf9a5e76776ecdabd1142cb55bf38836cf23636ecf7671073a65505cb87cb568fb29f8657e37213a0c65d69256717ebe20be7257da47267e7da74a28d68c4f01e7d07f82aa7f2a1998e68739ca80f5cc6374995a607525466dc4d100537788cc342c439e0973ddeee9d7c4c403749c821d5f081968b0cb777b83e3bbd1834e4d89e9f3680b8b19a8493434890f85683bc403c6565ec04e9a27936e64e89f9d1dd2c7550de4c23817cc22a1a6b1e95566965371e02708b8a5e13a86f6973f2567ea5eded9e94d0ceeec05b4073d1158a54645c6ef92f442f17183ffc14e278abbd19141e98061be7c2ccdb5478602496cb0bfeb43155aac31e06eb3ed7fd5f1bb79e26a6ef4611cf9c62abc9aaad200c696231c07a92ec98daeeeaf2338d68f6077b338d2313920d41a137f63e16a587622520294731741eef343f515539ecc978912489dccf541a32017b0942666ee39ccf128e92138867c375343f136507e37b0fc2fe84aa5e2121ca4087b2a9834d7920d00591827717c56485a89ba7e640dbb98c76f149bdd1503d8389b909a18b5ff3ccfe7f35c9f210f9a549491f8f91696bd4fbdd5f7e7197128cdf957f805739d080c69331e3520b5423edc2e3a7f24f73f2a9424f2327be03113ddb2cbcc6635b4fb33cdf6ba58b712425798cae9bf6eb072a9e0afcfd5abb6bd44057fb6e5177cfd5e80150385da3f28a47fad4e30a120f48dd5e3b553f9b1a2600626f9bb42c5aac7423ece130adc1615853553d4d4f077950249460d59f1634350411a3ad00a72ef63b43dfaaa02d213de9064a045dab9270bce65284867dadb84bbc7179f9f155b2db5ca1be868e4be18e0828dc4e0ddb97ea664b8980029b423f6674ba7bbca201ede016d2a6009bfa229ff7714178f1ef1f5d44c04bfe80e39d4cd899b87557b212ece0c52812cacf82a50319bf0a6288c1c723d2263f83fd5c35dea44136eed8c27d70f7d5296851f27e80f9561c95d911b1a511e3f07c830a6954fe10182e457580d9f4309b48b118070869f21abbf430d9756ef01229f78077a7103af13820df4e610d44b434710804b98399c69a67d462727e4b3b35b6adb36a0188921a4ae176c607b000127d127e90c14b83b65ab62f4d3e0ba9bda16e382a532fca486192c95c83997042048194f386a90041d5276ac46e0287edce674b9618751e76386f9795dcf02b6f4800624a4b30441651e10561d5ceb58f1e43cf638ede2cdc63c61edc1433b0383abd3facdab57e1e57e51cc8e0a127032de1c2c34d64ffaebc00e09a5e99a7933c3513997838c5c0f57ee834d295dc70d76612dfb321c1cef78dcf5ce56a751fde1c560e79df508aa5c87fc43816728c1c291fd7467554683d8830d865a50b2cc7fbaaf72456118d7b45c296755f6c7f97130cb903680e812ba15f1bc526be46095bc76794a19f97b355545916cac5b9e028ce5737aa2965380d02c574b55065ac83fcf1ba217f361054f0737ce1c6c254ba86fbfcc8a8ae3673ac1a9c61e1204046a1760197d8c35b12196a63f08a99ee3f77a3a4e470b3c712e6006801535329e5a557f1734af974351508e87066cec60cd9308ff71faa40d618d836ac58712ac55b2336b0cf4be0e47bbce3d80596146098107c4fd993a1f7b830c7a9d8df5628640e06d12c679d11b050cbde0b992966a507bc7f4c3194d45067943ac28f0f996a7891c8b0b646ab3a3e3ddd645f709bf81b40030d05dc40114652f72c8a9401710181340986fb45de9b665186d35c6a22937dbfbadd364990b0240af142135dfec81cf92a342a57d18ef8fdb1530010000119050d08000c1487800c0f388959b5b464db23217659f1a60e74b5a51ae25fda0cd1da8823e692d0f017a2532746c20b4efccd62cce528863d2e64326680a260757574d2b83a4a903fe6e44beb6ed142ff062fccc8c189f2e27f5d3b7154c08b8cdcfc18f519481d4cc3d4024527ec04218551c3bae9fd12665692340038aa77e84029af6151d5973aecc562fb75b7168810f89c5b763687b3cc0250c835e199a231ff947b5337b22bbaa0e1e8dd5ceef31925a8dd8226bf9c73560643c9ae988fcefe26d0b2e0471a141306ab3bab62fa5c06be4b7f2c3281201765cdf2bb8b4999d428fce7da88efc50dad88238cdd61ad076fcc431ef7bffe43be486c5cec74dcacdf4d5cf7d426e65b3dadd002d7274df44c69a3f40ff2429b80ff0e79915a28a9daaa26fd8b16671a06abf64f7601054fb3a62ce4d1b42fb673061b9a6a91380d43396a583b2f5532d4c3140b6eeab1b95b3979b1f870f2a965a994613641a8f5fe0f9acfa80841b27b98e3f4133288caee018c57a34c790aa2e248fd63a810e23ad238cf0b98981009dbaa12ef78cb7e07bff18aaf9a8e9762540cd7638b0f57e22ca3f1ae8eff2cb308cf7f14ccf9ac55b1ca878872e14f753f0f3cea7338174c8b1aeeaad0a954ac7c53eb71800a97b2c4701ca9d9f493218f67985b992af033612722e38ceebf70e5bc03e0ccafae2ee919769eff719ed6d43e9c2b13e86218f0adee48cd2efa20cbc76a27c27eaf693c11d4558aac2c7cec77838f9dce80c47e54dc560c21fb060048cffa743f820f241840bf88196567c8d8162bc5b54269988ded69496ff7f44b2fdc22f300d27605ebc6d8793555e6168c397dd9a67b43d76ec0c926c6a9b6a5393473159f6f1ffffe66fd0533e753fae8cea728011f1d5c5838c461e85904e609dc13f3037133bfa0b3ba737cd4b3f76a46c2e2b62b9449e005da60e58b90612667af0285339fbdb7e2ea5ac3e9537ef394255ddf665766beed1ea6e4b5bfe8ec4d5c98a180df9bfbe98fe155aa87a1130b5adfdac1f4abc8d106c24a3ce3d9fb3e15ae7a957a2d54d60127292eeb51d9e883534ac482ca34b6249804a2163bfda24836591e42024642cab92e5358e9d134797a90a561e703cabb232659b1edca25d0e9b3cf13cfe56b8827603495aec1c0003fcee170228fd2166537a0a5331d03f7713b8404a4f148bae88bba6701eed298c8753a02df578581738a2262a9186c6f4d42bdf4a4967f2928c5dce8e069dc90ab2b57c49c8640921e2202056ba775e3babe567b19b7b5ebb6db12fb3fe9c57001eae2f52626909fa7cb4abdc4813aae4edb7696b99b4ac960ebb9a21974f80af41e19ffc12013e81a0bad3e6ea1a324818b3266bb46c6b0d6ea226108a39dcbcd27453c829010662f1e78e8120c6110562b0ea1e114e1099e2ef8b7387c6755bf6b2b7331542d932b42a936824a978c3201b29d61630c0b6d7a842821985ed1b5fb3a19f3ae11f9cbbfd8dbec523c52fbda1f0c942f55e801de6b885552df34c866411e9b740b9e79281bae18a6dec0f7820c1c58b5c01a90b6109d80c5e576005acc98db134fd415c5034c0808eb05456ce0efcf9ed7e835983126dc8521b3e6d7983b6999e0d2c197620141b31b9ca11d8e1b6db86125941a76580bc6e79107e9602e5e8cf93ef39f9b960a064a57b2b049ce3c557eecca276dcae16e38d746590d7ff53514232eb45f2bd260899c3a3281a17c0dbefe1caf655fd1120817f305f7abe05e904e7c08d38fc451137574378631fa113d40aa47111fc7c6165c9fec2eea669c74b1d1eeaa27a839dccaae2960ef4b6e9360d5c4804d1eaa51bff27ba5b6232effb9e2cd05837c241e849cfc3c9b4bc66977eafc23bdc98c6ae025d1fd5179a48f26f798a3cd73bc7b8fe66f2a10f73dde70b1b267d806e82da1201c8b563b854107091b4d6345a6e683590eb054feb40ac614bbc2a29e451ffa9d202b447a49d890a60f38e50023afe9b9d18ec297a9f0a70739c1e731657b0712e3074c23cc15397239e168e42c4b8494079ea55495fcf916386cb3146c2a6e0537bc1a9b5eeb87ea90cf5561cc1bc02d3bd4ce4d765388b7d7da7b180f08b9b8bfe125b729358010b0abec731a5001334fe1d8ab16167339da5bfaabd4fc43f420c85221a0a45ed8eff1aebc86ca222ea412f0ab55c1e6e02060684b71db85efb1748904f0cf6610504448d18873b64275a071d48bd60990a94ad1fe9273eed59a9862948a47e49980fb389f4edac1d534b7aff7bac543a8a9b2d56458aeb40ccd75891e5d1a086e0025500e37709ca0126b1e3d6b91ef6dc5ba701013a75435dfe3991322fba9ddd7d68ef5daff52a28a8a6957d70fd64f0553d7e29eaea0854be226167fd181f644089038a33c31b464eca1c0e180b29090b1b20e238da52204b22b0755f6ed6766b5ed0e6d962fcc5e0eed2842924eac09a2819e7b3ff579c6e66ca65ecbf8663d126da018c51ee09ae4a6d77afe32f1275b8666c9c769fc05c957bc351efd1645d8b72ac8aa04b97a90b56eef2747d23f171641a266577d9de5e27dc8462e7809994dbb7e089d039dcf2f7df7dbfa65039c147b35b2383c2491d58b673567dcd7a2efa5983eb2002c062799b86faf09721392cbc575b85afa487ab965e8de0993b23c9f3c9cf021aa2db671bb3605308ba0ca5bf9771c6399176aee1c753c44bb274fbe54c3f3baa52331d2dac59fafa1fb87722108f61538fe1c8938a0b4bd7dc74fe1ec0d22fa1d6085a70091328bf164ad2d247ef6cfc1f124b8d05973458470c217ca3cbe1e66812801ad6b38ea797204a8661a8ed2cac56b9687a082b23f4c372ae78d14c83c5aa8f4e308b534d684f8f42506876afb2006f6e2a45795b569b04c6650b8045bfd9f2dbd91ecdd43d0a7ca8dee62b09348d91d71da3c12bdde6071f3ada835a91bef26ade4f5328cf00f6a4c571da5dce1b64dfb00b3b1504cc102b7ff2e5613ff69e3624f1ce5c4e2cfa5f7cf0422ad7a5bfc5b6f20036d4330ba12970a0bee313a21ce7c99ae774b495c4708766024513e250df4e34fb30d1469f931f33cce701b35ae2a1e4f0a00dc39e365e65beeeebbf6d662b772111da210b81883b313a0bf49210718561feaa348dc04aaa9a5996e90b0105a5c5681519374363e7637e97d4eada4a65d548d191e4effcf0e5f578cff11f2dbf377aea28a7ec7e3cb1f4c0b71e0b7031e4644c443f7ebc1726ca89db9973416b43c90db5361def6b58c7c1f5be3ff5325bf9c136323c8fea96c523d682e9b0c7764cff379ee9b14715d21287a4e0f8ddfc9d592d1a42b1ef4e07ba0ef014c42b5c46ce9477ea08b61dac5347af01858124ce55db7f7c75dbe5ab92fa19d38382511084271a28b99fb45e6ad1c2f39f4630873cba1c8e9d25d1003ff74049f15b4842bbea908a3afbbfb298cbee64ab610e956fdf1f951ff4fa30ce75ba0ff19d190c1c86b76354daba40107201f136623e468ba4444b4eb24e96fa4596ae4b64cae930a038063affb7b5e0f07b8c446254da556adc4dec574fecc7c7c9d96074ea7a0932a450298094666991d11de7c4e637fa728a10b8741266541544c177cb47d77e63841cb72bee2c19327b757178fae4df4fa884f3ae112735c033969e5cceacf4174add0809b784a4fa01948d0cb8c76df02b711af6009a1aedf54b0dc30525e221fc0925acfade43349f4b8483ceb1f1b7b80f7e5d4b9dc8e6a0b095e890cb3759202f62c7f5d361e060b8f2b232d6e841494a3dc797eb1fd9d3166d2f91605c8748024f55f512b439be3ad489b55625b6bef1dce2edce9500e72213224fb5dc586b022326017097abe0ac83e6b72aea7f1ec50fd50a8c496fff2472b7ebc59174125f129ed5e42fc847f91980f05baf85efb10a44064f95e976fc33d5308fcf5a49bcab77db6af924a6ab9ddb5dee7c9c9472686c703972d84e89eb8642aab44243537f84acfb53641463c4ed70a303bcff11d2341940cd90f1ee2cda80721e07d6f1078b3b1686e5b8acf360a6dccf121fa49eb02c1d94ad2e8f04b19721028d4beab307d2c06a5cf086ff5793732eb88a3eefb8f83aaf4d2374afff61765ebb879eb33e5a870bc32131a130d94b1ef1a0a7fb653b0b1cfc11d0a91beaf2bfddafaf99f88942fbdd394d5f3f18f985340e6f2c8d48c93c7883bdee44abe031131f14d95591faac83c9defd93dc287d6c89ae6a5954d2a068120edbc665c717850f2a0c009ea300e5cecf48a83db9c3cadd6d1267da34a7d9968aa444350fb74d9697c3534de659cd3a55b0db8a0c4790c5caf2e2de2548b5d60a2f7b732f1c08f89004b5e9f1817a6bc61260e76374064d5550291f73fa2ee55faaf62717ca122dba99cff5840749cf255ac0904e3815f994fa009d209a6c01ec4cfcc824d2debb3b24b0f1d33e84d98aa523462904b25bf38436cf1dd1ff196a0174a1e2eb6355fb68372c3d987542adbc6d3b754469c58c4cabd64a83c77393530296bf7537a3d30536072df8b8b12e724c34ffd7de1f6a40d54aa2cbd406ab7f1282d99289879b7be6f318c14c462e643319bf612beeeaddc61b350c005abfb9fed02641e81546d535b825aea0e1ffd2eb4f5850b4a31eec8412fabeb1bc437888e594fd4fcaed6db88001cb3c60d74b8333f2d0c2e826f2bae39ff170b5742140a5ecd67f2b104f146837fab6ee2bb6d2370468fba3a05b62809b2143b7fb05b46d786bc42fafabc2fa43a9a0418fb18b1367b7f650e610e6d6f5390f1e02c43f88257ba180def07ec78695ab066b89dc9f5f1f2665086fb0992c379924555ea35b7a9dd4ba9d6022f57c82ed90688407676833f3d40af316491d1bb8ff64fde99fadc1dd32c2b8f4d135812ec51cdc314222b5e0f98257aca08766ff508b4fada1906e30eb2ef6721e183dee46af2828df3ee5bfffaff568ec1a7a30686df639f45c838ee61fbb5bf3e02eceb35facc1371e0806a010879141c3bc546e523db3a61ec7d5e3653c3904b9014e43c8f4e95369a16fc05f371ea2ed0e9d7d6cc6791f6153f06b6a290cebf021d0d2e5ffb7601b85e6cb4e307260c0cd78c457f932c4cca58e6b2f93d881059c461150d500f3c4bf6310f7a3ba158b3a05391caaf003c779679fbdb3db7968dcd4084a518eb355b4723407dcadbe326522162719e1e8873b6dc61553c977af708364491efad0bb21f9cccd2b4edaeaa204f69a0005c30c08ccd6d7d098b8afdb19ad7fa4d9b44a30efc7ab15563d03efc494c79c3b711b41940fecd80e096e746cf666a4504efb91ca1d17da93ea17588f094dbc9f08f9a6b093446f5e3d42f3738252492481762d70e7a418d435d38e029539876d710faf6b500c049575d000410b0f5632c17a2bd842831d4db01f38d331915ffb38d207e29a0828e7f63e78e71e0ffe0b2c3834f78ba9f459edc962244616268225dc794a3e09c9043a77b2259076745081a52b49d262c90fab8e8e7cf2785e5391ac484c1acc768276270fe04124a0f49995e560c4430dbac1f865857331c1822737894be71e886c4708687f68a63af48c2c7226b64a00743e74aa85d08bcc4e4c42ea554fa1d8f901a920666eab60dcc9650b22124147ad725e55d681a23b970788ca89a3fb8eac0130400a2978bc1eecdde6ffa70b5f23ce8a458c1e9b296a65d2c3eaea1725ca88de4d8084995cf1e96065eadfc4cf795579299ea256ef152b89cb044ed2ab7d11e333757c7e80bcbe0b25736ef19f68ce9270a055e1974870474cb41ff55cca540c1b704f217b5672cacbc4d82ffbef91abde0e8d5fff5b369a2dc1405f2b9aea67a462970fd6ad0a60dbd717776606f4bd70395c506923aa566277df859ff7ee52755bdd2b7e52fb11925331c2fe64a50e85da8944acfdd104a6d4cb175afc391b0a13961db9e50033885ed6bf77e1506a2eabc4d54c4f6208a257e8b1da9fa15d748b42cdb4498de2bf168b3a7b70f8212d705ead3b067761f3f8eae96483940234d3cfce32bea06c5ff1eaedc1a27f59cec35415faeca9c2c188e7883f1436ab81952029eeae6e5e61290d5db7da3ac3ea4e5ecae6579fdda4fe314eac9f9d3a7a6d2a141e1bf014ca55f42453353fbeffb558d0500e3797c2a94921ccf0e64f8e06473017206c4baad3a654259d7d1fc973f8f5e3523ee68369389bd8a930e5093dc5ebe86f56b9a0d7a26895a90d5f708c48684f14fb9fa315c388eb9d2e54971c25dd9e787fc736cff4f72885a4db545f3fb07781e4cd4bba25eaea58c4eb0af774be847c282c06500b6aac578c99122d89fb4696901c235ad5ab73490ccb6a19a367d97cd548d5367010229f9af6401e687b1492f5dbb38d1a97686aa02f320df59f78becd4a35c1b24138c00767d22e1a02c7db89c80604d5080a433421d282d50f9adfa2f3ce33bfa566393359fcf146329a40f98b458352bc6b85a60fc867460f22b3ae47566a55dd506bf0a0dc181da579103d57f7693e9f948032a0d8bdb8ffd4092a852853a9ce0e1829493f1f959cac224d27247ed6cf8ebd1b7ac629800dcbb752e01912c6d4c54ff87562605ca185179aa7c321f0d2d5c53f3046e5a9f6e81c66718c5d3511c41445078a39f545ed789eee7f2f17dbde4291e2d6bb80153cf1bf2a58d9ee7c05fe3f1ff54b95797aac80c22c0b5f441cdfe19b89ec32fefa211d253164323d3e9fef7b9b74610a0597bd38703c046c295c8024fdee433ea88a353b6d1b8d8499a0b32eeb28a555af6e55843d5f3434e36f6af2203809181034d40bfa92e010d0bcf82f9bf2dcd699b6125e812385c3e8338380ad8293e10ec0d1675797a73a1f78765ac3bcbb1ba08d906438fbbd8e1d3b0597fdd5895afba1c317f4a825f41f7a92d5f8ab24a97022a3ac70c15447147c32be1d8aff4bbbcb8df3a37992090656ad013dbee38dd1bed7c17e67671ac7fccabafe3c9ba161e0649d29924fbea48acf77883f3604e8b5ad6ffa024d428a65f8e975f3ff3c4306ba22b932fbf6eefabdc1f94493642743b9e73d94d9a1cf2d8995ab4ef37b442add6d3231456b05d4ff4fa09f71266106acab5f51f82bbf9c4886958fb192ff6e4fba56ee6ded08f9619b816e5d1b76ab81d7f0ffd10e504dc6b07115b6e043af93666cecf6e098fc210b7bf6a78209b3ca562f475e84f4a9da9a1a487bf39a2a1ac87a4cc1afe7fede0bd99014b030b3adc85228cd34324452e18ec855efff5d0354fc1495ded26688b90b181798403ef601c025ac334f950633278d6c91d261ff702b47fe711db17734de1be9f029a90be063173c00af6b1349654fdbf2a64f88201c8ec7e288ff0141c1e5c7e6814950e61b3c94651b77670d5061f6177bbf0427d8e80ec890a83b188e0aac6063e528757fbd3ae507f4edd876421503f4a9238d47a80d541bc74027955aca50507b066ff23627e6fa069d3bb0249987260ab57c515c5f949b27ba318ad49818048d1a5478fff9ff1ed798f14f5a6b2fb45eda1dcf60c4dc75801a3001d730d395e56780229d762b8c0d45b243e0e02f933bb4668722ba7d06baafa453444160df2d72e9a50c01aff184b3f333c431f8b79d497521b86e250a8f119a1f83a77199298857e79f6713153a3f75527deafc4e83cb249bfcb4307dca8bcb2c1ec2966de40eff05c1984d02b4a574aa449b1324bbb4a67f4a5a17bfa6ed1ddcd63a8e903591d1eace5eaecc2a580229460bff18faf32dfb203e1c9637730330e8795d64f82fe2a8af3c9df8d7fde442beaf3e36098f73bf5d704ec71ed59b637f676852ed89ea3056be581812e8fe2fa45afaad7ca3ea473d0338ecf02e0c6ca34591d2f2e0d5545d2d8f7482ee3a6cdee77716e2dde3c86a22987abff9e71db5e165ce7402f25728c318e93411ee8c37dc5850b7efd88684ee9d639cf76b51da9d5924c3e89fcb8944557516c86964baa65f8b8d8e7b05941066af7fd45e934683afc4f070f63e1a5fe1776bf3d160a1b7fdb34161a0fdab5c7fe1942ae61f6166f31f639bc64a5c9dd13a0035938efcb44e0d96c1cd30167df26fb91b576734fa96cafd4341640dabfd53cd5cf641c6ea09f62d26bae14f85be3c00a0a65514c0a54397078bcb54251f8da78d01c5f9f8bd4e3d0f38ec5dd3e6c51b18a7534cef73febdc3a426c332ccfd38912a288720f3d54982f876daf82f93a1fc392dcf572219adab7522ec5c25f229b7ec0fd2a76f0ba72ead86fb7d38797f8554852a40e5a61821b29cbf9d37f879b2f12495952419ad4eab49be2b769cbe54161e980ec9f13759ccf262c7f52bc3af15544623314a8bb2c4062de1256d6df75030f0e57c68b940a4c12206a51ab4790696239939c74772bc55fe7280471a0d976380dd2676efb127da82989abc056d235fd62a8b5391959f978e6e5daa8b3f629074dd6b1f71be5714cf82965e83838c1dd76f951bf221fbd9f017fd533cbf8fb97372980b73985d2dd898eb95b5e97bdf0902b1f371c47e2a4e5bf4a957cfb15429a9a9f523f53a0a9b0f3eabd4c55a228e13a26522b0b30f30f4f77fe9b4e1546d74e67e626e7eb40eb124bd360f8c607b1853dc761080d42b96a583b2d565a6630eb4a6cca0cc083afd2a106c729bb2a2efcff5c82cd2538829acd609ea0d18c4fca68b2121fca91b2d8c451c08de1c35817d5ab0afd3f68fb8c74014421e9dbaa12ef78ccbedb5abf8796074e14b5a28ba03dd86f47b284a0b3be49a85aa11d6d2a54e98a43ddb3e871b69ecdc23b6c874562c666e487ef3371e9a1ec6689bab7ffba12f48bd61390a50ee744db5e0d210bea51b62db26e555f5a766e0d9de1f3265ebf12a32a11bcaa9c481623e4121ec32e9a6b4d837baad45e6a1ccbc1baef52e3c86dc9738b1b0ef155a7dec7cccd98864804206398d9cd2ff58050c4a435c82fce6265add25675616e84727ce6ee9f0f950a7eea960474ebe0fa23f5433abb83aebe32e7329ab358e29f2a4ae63f8b25bf38ab647e9553f8b7d7bcdb410a18b9b91570e0c2b2689aeb71287c79325a27a3a8f2154a17dcb573641647c28dc453333d127478f8e5d66b066d4f01f6cf7ecb9af62d90409a3bb2d7af891ac48582064b7e60d6d8fdd41705ed4c221443d1d5675a8dd5b1873bcf849a8b17a1929c2fb42b0370ab108970c23b8b24fb361f4c5272cd0f911d2e08b9de8cdc00f921a5d762846e69c005da63e58796bb2e6cf584e5c3a8be78b5f884345b173c5c499a85354a5db7e000c6851e41efbfb1c9ce7c47aa6288ed959f37402733278c350f45f20ebedc7d6890cc08bbc83bc885bb6449ebffe6bff736b126faac0e6d3153a3d7090cd44a64ae0aa133c1ff87f8008c19201be41e1938c7c76b6f254607494114edac7ab802b217b90c0c6059aceb667f757b8c864e9eef40ce68f6b3b0de90e02c3f8b8dc448840d933f31037ad0025131dd335c4587f20070b9a1ea5a3d16f7ec39fbf191f6ab401a6075096b0078783583027c8f170f1df83340b49a845043ffb1cf46afdb0f877473be0038bea7056ce451ab891e76c6368f72d1e23766cc767695a90c7c0a5636e4b2e81e0e359846861e56c78d8f7e35652099b6cbfd3a72a9eb4a1a074bd588fae4e0a308d079df79f65905f4ba59a8893cba56750c772bd6751d6697d56a553c424b6e884e9bf5b001119f163e12810c34aa154beb033655677dc3f1bbe6665b78b11439f02b563c03da87f057741caa96b533f5d4a2e96f1e32946ddc3aa5930b0fffde66d78399cf7ea67168ce7a45ea9e302ac618e1cbefa97c46261122867e4f1838534e45396893c34178a121a6982caad94f962b7c2999d9e14ab89ffd8d8285138d6f58218ed94d4cfacf676fb75b3d7e24078cdc8edc77ab85b13f50d7c18e19d4d1c08c9d74a8b65956bd0912d48a9c366ae5ea7f9511ef7d49b40a819656755061c0a8ef506c186260d57d9e9135b24afaaaf88b9190b273b8b25238f29170f230717b739a32987b905a3153bbba919ebb39f60e69ce66c20d130b3dfe641b8b71e252ca134d2ec51dd20da7c07e0d1aa62adcffd5559c3d9f9901afeaa26419c585570662d44cf735b18fb880fa6eae55b6b18d2629b8fcb36c1c52b72549ddf6545509f9ec1b1ea68ba77f27f65fc9da9d54ff88e5ef8b0bf2584feda1f7b1f11ce1980517993f90a98c4c94785541afce1545dc8ae450e20276e0d33b926dab566d2da9559982ae6d0f77976b107f9ebd865f9509eeb2ca5033c4fd4f4443834a28fcccf56350c9dfa28f5a1ce43aa036054a945ada0ada566746edffa5b1d5c2e3889c66e88f29a2448a148e441fde89e8d57bcd8ba634e7c51cc7e5a370b33cbfd8e7b54ce4193b0be935f8236ff30189f1f7038e0debf47011c5dbfcb9907306cb1c903b73ae0b7ded9d6922aa530a779b24a3b308e06ae52b4bfab2226891b2dfb24a339d302dc0f0da1910cee04c528454259c1df69874f451cbd9715cc7ca1174c90ccb8dfc9c050a9e1152ba16b3f56094a5bf3367afdb1bb5823186fa86550b566381997c24030507c0fcfe0afcdbdbd0a75ffad5d45798934147cbd3f9933e45f8a8c01a82b8d0a205437f91d744abd1aa76439f637e96049a582007aa0841cd40b2b5743836627b92bae6f4148eaca6bc8b7cadb503ef06e98f2836b1d6852193eeb1f68d2c54e92dd3bb468054de3384b7b1fe228d77a086131664436f48dac80a6030a8941671697e02f858ea28cde93cf305e0ecb4c472a81e744fc27e38a27e1746830e9c01dec864958448ef6f0b0e526686e71470483dbb3e21322a11226cd254222255e1225495a496b11c42829922ae9d246da4b07e9289da4b374956ed2537a4b1fe92f0364a00c92c13244868a4932245386499664cb70190123835febe0ffb604784a3084048828bc410431892892c8602e0a1083086212512491c15c94200611c424a2482283b9a8400c22884944914406735183184410938822890ce6a2013188202611451219cc450b3ff13300eabd16014053631448bf9ca65120f7720aa340e26534ecd072b84a9b9573458995588b8dd8ecb115410fa20f7682d8057b511c82831c1c4de2149ca4e02c0467736826061743709183ab49dc829b14dc85e06e0e1e62f034044f39184ce215bca4e02d046f73f0118baf4198b4910ed243c28549baf41677091326ada58f647ec8b18694f61ff2245cce36d2e372464a90f416fc982321433ee470487b51d5e51c819d3b2032dd5967cb287d645347063bf3242dfd7acbf11d8d9e99e9741e8ccad24dbd694b473d7e4d30b2736546439214d2c1d4837a92ee45776e2a8d2f2e4aa4d00bd47d5174d59b1aa957ce1249efca38474d065fb9045b29ad8f98794dbab2e965ddaeea9aaa3ed3d42397ca705194b16aa59da9f3cfc195895464abadf54369d1aad6bf92c26920cd5ee90c52501a66532831883471504bb3a9944860285a090c45274d0856d21e6bced25a9a5a890486622b0d3c9c628941a48983bd349b6a893429471c25c0509ca44909ced29e668466d26cea2512188aab34f0700a26069126fe1f643f00003da386588490e9ed5ea4b44e6c802b4f904d3b6d6d839736cdc3f405f6a32ef8e7768568f8f9bf133cd5343190e5ffb639b494e868bb8329fb35501b8b77a56dfba2ed293dfc88e695cca293c8ce57cf621e7505959bbbd5e97caeec5b0aa445ba17b9238247522cd2690e75a5b2ccecfa63406168dccaf9ff75f52cddf141910bebc759df9956a36324c1a76a8f8eb88fca98dfd4bc3c13731cc2275bfcca383e7cbf44d13cd716664381ffa0f5d79cf3481e0424658cf1e2411b8e95515d93aee7071f847eea97f6b1309fe1f5ad99adc785b5adea49fe9757a48689d079c8fa45b7fd525f7354d5d207fae55de4e52feb577d7dd92e73e64db8ed97ba69e79ea7b87db8f108b879cf1fc01165f7a9018487b0d4409c0b2e04a700dd8f30d76b8a3b8841991fb4e1c1551ff4d1c1e15e607f05ce23388605cdb4c25e4040e1532136287303c606fdce40bb05eb81411f1fd4aae0d62fa8ae056d7d30c405d5ff41bd3cc0d440b203db1ea02878360bdaf810d02e0407078798e03120b824062ee9f5664a2b20a20088456dde6302e457dbd45644813d264e294f71412c3666108aad7c4a61aa2b20a2808802220a80581ccd602a4e3208c5590661aee9d4a7bc2f050af43e982ce9360176d979ccedddf17c411b8cba62824940873fd468caf2add3f7d2fd2e86d48e4687a8c7259abff6fba38ce34664b5c06b7916979639c828cf1dd569644afbbbae10ad44d24afd7152efc4ab125c8f57e2d0994e3d48a3443bcadc24e956a8e5e6157c159df922ad4fb26cc53dce6135f4a1c3f4db264b904ec1622aaf67ba5f4d3c48024d41ed8bf30f2c72ab2776ef333607afc172ee7826cb4315fb6e2f9dfc09d8e329badf8752ba55bffa662aeedbecb076d99d88cda8a939295d82cd72105897506462770f325219cb7281a5c9952d884bb9d14b0fc472f955349ffe497c1d5889a7749efb043ec3ad32f5831839da315f303352afc65d153cb6d49b183ef4d55a3785e5ce3ce5ae8daed2abb1aa84f5abf5167975c6d0836d4a7fabd2ef9bc4ff3745fe5ff5ab733771a0eecc3619463060bf0b4120d3454818e89544c777fcd5af3ece33843d13a40ef0cff4a3c663834162a9f849153797d0cdbaa271b16c009d1b812df664f8e0fd9629ec27a7ec2480327b70fdcc7c83483e444246633e4c0ff215f2fa29f25ae318391ac3c35400ffaaf548f0bdd980939c8e183ec64d47d4821f42cbb829a76ea3b55d123849d2fe387eff969365f5a9f121655950eb92987f8f14c1b10c7112a6d300d40d141f5e6ab3d55a902bb52553c687f7cbdf99ab3585df72580705addd39b130482d7267eaec747f68785162b9a07cf64a65aa7ac8349588a7724fd83ebd19bf3befed9780aa3a5919ccfcc641e327ab64e7c5487467eca91ff74166049c88f9b7fbe51e417edf8852cbf55de3d656a2a66678b206f2eb9defd95129134ad0332e1c8cb8e768818d230dee6e08299d4ce8c64500250323802db73a543c90a50a36ef3a4617a15c316cfc2981223a3eae8743ea92aa3a0ef99a0af6dbd376166cc2c95623c19b49f504af8bc73cc865d162904115de37f1b176f06569e8daa0489d08f65f69628d4c30d1153761f4a84a7b5fd4fedadc4718e930eabaca2642bbe9a6960fb8719b5a9685bd31f5374a838dab1fe32039ca077523e79e70cf66702546c59678746c437574c4c68657947a48700c92d703a8548ce922f5849378cda5d82db493f287d0bfa436419fd5bf41d1902c571e8ce164a99d10fb611d8da65823258df98d8d06f55939e9975251f854721f17b1c225708afbc25604e1767be360465e9b9ae64cd1980c2b36780c72fdc66b758b85897e895a849b9c3764bd83023045fcc033df3894431e64a50c98788af9016ab316a3b0b5d92422e3d7184481409924aaf66192ce082b150a65497b4eb6073cc448f084a729c9d82df774ecd183561388c37fd0ee375eb1ba07fc7981ae10a48e25464cc678bc0e63d923f308f0fd029efc9fdb24c8087833b542c6b7ba7fa72624a3357af7b8f9cbc23c3caa5f47223d741ef8aa256f0750aafe360a49bb50cce13099d194c0973a60fd23769f24befa2af2cb262cfd8e1a557ff0f5f062ae4a8b26d1c909cac221f157aa8957f49e34990e5fff420219a450649996c786786998b1777c4f16c9688a53a6c6de2d432b7bdd2c885afd7ae0259ebe5a0b74b5ce432b3f03065e13ae2e3dae51a6b0b6371c1ebc5c03c9ed0ed6f170456f57253da258a531dcfac52b2b86b5c69748ed4b69ef3805c28be015e70980299866621e0e15d410ec222da249fe104f78feb18dec64962a3dda26dd0690577b2904eb74b23b353b9271b5c7adbcf904c0a025d5d85356f59c7908b4f0778209a96530d065f42c30a55e2259c5e44d1eb5a2be2089ff4d5f1895a6b380ce62861cdc1c3fe88db032d8dfe4c876e216701c747f6ebaec94ab7774bc7be4c262271ef4df3793fb961253823ceb21f5b3b4938674d093c3b05afdd577bfed2c9bc932a90f0a38fe9498213875f4c7834f8b4de77382c94b5280e347d13835f30dcd735a9f2cbe9ffb7dfce8bb205b984c522e9b4d389ba00ea8a0405259cfdea90beb693b14354adb277b545a1ea4edac7b38f0b603c92de33a91d44174821abee9d04065c8493c6361c811e4a9b20854ceb945e2a716c7fa52fd1029c014dd50d878f00ac3bc68e7403484a770153f9050ac6db652b79aa657e2cf40a2cc9ff1b86eb84af1bed2bb0c8cea1ca07b25a7f9dab6f928951efe03870f6c98879b8017026a0ef919519e7121381ef9b4dde559ca87602336b0dad73373039abf957a1e5d999f9101ed3720228c1ab4e6fad5475fcd1f19bc71182ce9eed806387c6ca768b72ce6445b4454a30bd2e671832ef96ebe010877d7a6cdeb9bd505b84a39202a06cbe203ffaa6a6249474fa41a8369bf54de9346dbae4381e11c5fa2a1b375ecfbcdced98ebb8819682ac9ead0338ad7891e0142ec685e0e78e67085532d6c706c430b1c3dfa83401d0a8da0e240894c188f40af69c2e6f22b0abbfd14fe255139e027a145e1e8a0271fd3c02867d6e1f521de27c03044a575b12e535e6db13e77fca7144349bece102bfb554694616ca36af90be2835f45e31f7eb160adcecc0e01c9e31417a6b2e242161f827d313197aca8736fb642d31e78d06c6b5a9c434d46af6d073001b7e64c64d33735be67d590b4acd649b495b963277127db485d68c409f403d78f996e1a1fd5caadb3b0b8788c4798e8c45a57893e7c0946777329b8884f26c8f3c810e47de7a7892bc876a8c64bce5680932a34bf62d40699185e22ecaa984df70743238b294dcbf4039efdaba7b9e8aa3442161c31aad000aa31c3fe77813ec1b4d10d2ac65fed56be9fdc9adeaa91067f98c433c76308eeccc5ec678f835a664a8aac7e81ed3c9579c63a439484138e7ff729afddf4730bc7f35030654290b0dc6a403f3079a19bf86c9a4f07accbf209809ab02eef1f33fbb8a1445ff6baae8e63963f9268d96f58eb73ef5d3b82e948a0541f21af0d61b0665f83e0378375584d94cde2ee88316ec84900b89c55aac6a43feb68682a2b8ae62be8a072150cf24a7d63b13d290fdea3c56f68e3e65caa8d6da122e17663cf9113a30d650ce96f709cacc54320c8aacc21cceceffc7699f5a81b9b31156928b742c5577db5d4ef1009f4c77ed751ef0487ea891b3a44c752afedf002d6e5dff46d75b98eedba02fe5e528e4c1194af35d786c0e96c7acf8531879d52dbee0a9f00a8fc2a46260260698c3357d0fa22976fd13c83aa91151d5fc3fc97167294ac8946e3f1cd163ac41cce5c0f0b9412679ba4c646d458d028eed141fe2172810a5c5a683e00af857e04769694d943f85c4762e35097664a06b360ff55e9c38c8565d3d24f2519df57cc5a5b8fb9ac0803ec3e822c5a21bf9e7bac32e415bdd702a42e8accc620c7e502937a1008a29c04c71293ab28f08ec1476f1071ad26719b04c6fe0f03c814c32c2df498ffdb6709d96885f18aee14c91a500f14c4f1fd842352ed0135fac41df3ef412c742beeb332f677e9213a122e35fa28ad9a68b2ca2305256f66623a6214433949625bc240de392bd3e95b7bd09717e7137be5350840358e7bdbc17e0143d94940e341891d19ec49456f931e35ac42738eb23da337ef6d8af45f220b2b994f75c0db0057a907a7de6d3fa928b822ebdc37f1d55ca723bc5a44c6dd126139cdc3a46a7aa5f0ba5184f5500182a5bf4f34793f7090a7ea39f6c96acdb91ca689bffa6a6bd07f4911fbfadd9e5c24f4830115f4ec7748dd5ace2d68d7da726f9b01cd794399fe2f4c83033f5f2ab70c5591ee6e044f8aa80745b9b4cc50cced09c3258d911aa058dc72cabb04746b57c332c101287cce793cca8dec98dd9a7e66515d8727ffaf89e20ff94c8ca82f89420dc8987f0ac189b5bf98067aafce71af9810b2b4d37dbb4ae99925d93af05c0c9656c792ccca31f6cd14b02535488521d09e41e23c89c2123f67e468ef7be7dd393cbc1fedfb63f6b63fe00e2dbf94c3a9088f9c6880cbf98077710004302575f714717df6dfc2707c27f38d880026fe8854edb167814ed3841db4357d142ef079ba7d923136595c17a73d8686f9a95cf0052d46e71c2c881f6f96fd87b3d1545dc68322d479d2494d669671597df2f131a1eecbdf438e35ad22312bacfed5f5d3b3987a5dc5807905a978c2020889cff61397e996ef7652f05496e5c693b0ebd693cca688ff7671f6c05dd01b22ba667381344bf1c44ec5a97dc2281f45f69f9bb0679f3fc47e2b9d245da075cd9e4d16f5ba7ea8a69068b5ba7bc3ff88b90a6b2a47ac88a14e39fe5d95b3558bdbc1dfca140220522bb80ebf0c6dbb77f5974d0b3282f660c62f074d8307efa78c94f622a89c3ed48dc2e5480cc4263b49f8fe4fb9a6ec6fe4feb40d2466735fbcfbe18d60a65f152c4d08b7a37f4725ff3608d07eb5c403371ad9d273451e5edaf250d68a8e7ba279f9e70a236d5266cfb07ce762b53bdd684abda6e521ce2f7471801394858cf6010d0c618b146fe21f75fd281739bf80cecbc63926358864d9ff43b57f22a19225e822a90656be46d2067b0e1a53d828e0e9eb1233cd5cec227dc40c3cd9bf678d075cd639bf135142933be8dbee23bee9d26ddd0e5fa6967fd36f3fcce7398dce818bd5b1394fa26bd8067e6e85d539e645ee22ef51f1c6f69c5a06026b57aa5abd380726d068715a35fd9f129ed6ea47a6a2c87e8ce7ca1fb430aaafb6e0645d49356cdef5448330eb1782e45f579b1e6b6cc35083dea4344f0bba905c7dde6b17bdc233d63b2113fc9870f04483673710c42e7a2a10ef1c88bf5518ce3474b545153d306d2176da1903f29d1d65ac2a4fe3d0ee6b0ae4f555771ebb9bd6012f6dadff54d890cac2a45de3fd841760b9fe70c1d58756fff48ccb47451a6e79e2c51066a1fd39b7c7c99b5d851314ad07ea5b33a684b9b5eb208b2c8d2dfc4cc93f1429d43ad4c08385038cb65dc6c1c0b562afc7bc37739cf4b73a12815e1d262bc8250cb746211bde4ea1ec1c057b6460f81dadb93bc59bb2806b8140ce729971521486e53f86b9017c8bd27a0b469afeef5cfa8d2953aa1ade5927180ada70fc12859b1ee7b84ca426c777a442158e54953e93e37d2ed0044fef661ba0cf41c803bc7cb40e46ecd07729688218f31f08285ea1229401a2e02c0d69897718d2a96f28288028380a5088b31982b9300a95b51486324ddacfa30e2fe4ff7f267724c60a4c5dc99247fc49f6b5a1b2625f5d5a1c2e94c0a9d694d72c77de5acdebc27cd9d069d69f80f2875779af49dcd2645d24d8e9cf89596770fcb57e7e3a3e45d4f21be56528fd3a30e9d15a3a4238f12726c040773b53c0ebe128eef77bdff5caf947ef6f41bf3af03814a44dc9a3755856d1864bf5ecb472f54c788c378ba37f0f53cfa7718d1b984c10152ecb10898c24781d91873484e79974e6b2b35ef30eeef838f62b8d9c66b051959e8c4e4011e58dad0c1b0c3aa6b547885d4778e9418b6298a9ff3391e109278c26cc7fb4bff62aeb71ad21f5d30dacaf19a7e2cf0985d0c240a3217b008ee1e58550f6247dc5cd66f6eb6059e9fd62ec9c3d4ee1344b92d9d5d1757f4ae673bd94bf2d949794a4728be491e76f8b343a3d428a7f380396a2d73a09e4c5836d1eaa2cb9de4da7f94d0b37a911ef4f8c3fe772b9e1a9063a1201763f0f6ca644f2c5ca2e86e9aeb398a0e5855b1821f7171f84ec68f5e046e5a2e50a3973c24ebb7e8e511f7bd9a358e66dc5367d251d89b4e675dc0722b17a8c941f004d73c0f45283e3051f798003cf6bd7485b8b407a0a5665fefed8d30e649ada9f4e183d188492fc5092ae451c6a941c2a96bbb4aec296d96a30c3942f827d183d6f69b27f113429a2089e2e1ffdd3d872fb13c415ab82c8874cbd8196987487ddb0081973be5a8e841528ada9d5a1a5512d95b60c63619712f2c7ef96d200f8c6d82d754332c53ecfa7d2b511fc44c21e4b1352438de9884d9fbb0efa78249453745ec9a7212bb5284cfd1c7da080a36fe5f866c7cba47efeaa2afd24e33053cc4d1c19582b6411c8e4290c5b6941a59b229d9f57f844639e9f1f6b3bd0aa3eb141425d4430ce4b0f38e8f92c0b2fed142b51536ad1112d1c26b2243a7df2d566793794901fe4feb73e502addbc8ba8966a90e1950fa80986e1b1eeb43d79e43fcfd98a177916fe39917156aa8b9aaaca0d956a047b291660fd8da104afb61d4b5cbb924c2ac1d41eaefe53bee54e5fa200f2dc3f1e34ad6e359669f20a2bebb2528257da0ff53c75ddc3ad179ae8b98c313db118b8fd9ac6a8a07592b5bd56ddcdd2cd26aa3313c47d4804f378b390004196d4c152851d94aaec0054bd8667ec4c783586d372d1430843072750d65bc60063d81694298705fd41aee3cd607cb4747b64763d68be2e371fbc6dcdc54fabe136022f7fad1aa93acff29a02c2b2ca571ba4936833cf31fbf44c6abfad3fe3a79cbc30497322523bb5eccb5d3d993669cc7cd78f29c958816769f3a2a060e03a684c9a14b986ffd88005399a093e42c7e12305ea8fb9b1e782135f37fcb535a09a58728cb0f2210dd69fe0c80a344405fc79b76745d8994c5804fbc8e8a863bb3166b2a4e85333bcacbc253e578f6e0e97b73acdf71c3ee77b2dd3e6b330cdbc9c20612cef9fcd5566cbc881402c6942da88bfc27133db785e9c6314db75848fa096ff9d64ad7b06dc518e72c939d5218d8b212fbade700c07a8170fdc74db22eeb21f23c49c384fd04c48065d76359082b2e11b8be9af1f61487d74f36e5e1d99d037c1e56214d076ae7598b8b155ffa58b4e8fa2016302a001e9004c2be1c5ed473377e09dbeda5feab80e7039c397535ecb949299bab631e4f966dbb29f03d75f108ae7a0cff2fbea65e01bd68e0d0a404a44d46db86a41b39ee3a3f8c3e4d4d0de21555972803dad4bc8118d1a462a1d0ddfb34372c076015a26b071d0a657ffc7bc4246f7aa3c4793d880e1f68f958ea30b7f160d1d90e3e1deaa3f0d0794d31a9a950c17ca8dd74f0b1b714c225b5045eb394c627e7c9511ee028918f47c61842fa48aa3578de6c2726d6f214776cc37820397b8c1a75bee80aff5477a50ae601818064fd3ff6d5cc411dc0ce85fcbae5e28e483307026efc99806f78eb5890c26a52c8a5500fb26d488d31226acc89c3ef91d467917cbe487da786539ba9a8e37f5150c2add0f75b5e0990e963a51a43eb0bd27b0e6d76d227edeada82dd7f01e64bc81d34c309ba0f88992c252327d52c16582e7f4fdb2aa630ef389da8591078fce567fe8a60bafc76e4e98c013b150b8afbccee860e36adc8b47af382d40955085c266c0ea0c753fbde7e9d13cf10f344447d50584504f1a68c7598e1f289d202a2dd34788b35229d7d83f08a105b5fe22179439d464c4763788453a4356926a38227c460bbf22e94fa44554515acbf053dad6891e2810bfcc87b4ecf6df450737f5fe809b3e82d039f84ddff7b982ba0454a264d8137b8c138e3fd84ba74e0e7589bfa32aa2d586eb11addcb4a58aa92ae052c3d722856ecbeec8e02d1c2c7d3d504f17478042de4bde7be6580782816896415275b4a13568a16736c24ea4c74e2e961439889bbd885bed2f66f497810033df6127fed182cc9441a1b9b5f0f2baa054a54c7b50df5e1bbdc33bf5aa536727f8a9c8407ad02828cb75a6827b5f93a0c888a371dffc65932d92c6a923cb0d4ef376cce3dfbddb5f7c8dd6230de6174c5352533775c58754572c397e4e65239afa7db7c5f49de715b0aad4d76d0c909679cc2c0383ea9a2361928f9382033f22ff27147f0bc5ba86258d712c2ef83208f43e341eab97b5493bbd3c07a3f623c077722692965d6ab38d2cae337fad23fb0d1340049ac22470f00a8c3abed54f23a7948ea73c8a40fdb260e48d2a7e5b7a1bc6ee89228ccb343cda95847dd5524ced51fe4b2e94382da8fcaec7dbfa0efcc7f87dbc7265e3c38f12d33ffc4e5027dc746ba829af005e20103774fcaf8e420f29c6d3c66bcfe3924f90641b1b8fb21576f7f376ef3ada05954d94787db6c9a9c77433d4fdaacd77e935792c0ebe995baaf946c2101f6eee071fd5dc237c0e63ba850bd833feb10a16f31daaaa544b09472bc0042b4aaa84add7b12e9091dfe7ce4f9ca22bd2e862c58f3f2d7f35f9b09621e32ad90fc1ec2b3802b93f1806ca0889604aba5a00155db1086d950666f3001db8d3461797427848a57ce4ef2027ec30c3cded13e77f32e83a0b4acef686b492c33ade26551a31dbeb153d420ba81308c8a31b858b1c783a8b6f12a9ca7bcfd6ae249464695761bf0024c8f18431acd6a91d191f15a95527a89887e3a897fa0688c7c6a4c094aa9323a0afdae11041d91f26d74998b65b57238116b7d46670b00b4be5a16f85ba04a2b1014e1a1cf5ae4cfb41567d956fb13f396ce37eadf8bb8b778b81dcf2b043b333eb2fe27b3d5b74e29971b60da1ce9f7fc10bdee46fb7149e97d82732660ca34e8ef8207c79ab403d0a9d5ed01dd2e128b625c6769090b1798e199f9e631e4e796b934ceed3e40ede2b36d0b36dc642fbc40cac8b40424c3cfd88d630b9425d8e8f836c7dd1530cab2000a44dd8af05a91e823385705be25b3ee169b346e7f4b049094eed0ba3ef9789e67622acdf68b498a9f4ea6284f1a6328f619fb197526350f81f68b33cdbea9234f7bd4643725a9cf45ae8b7dafeca04e7ceaee8ff4ceee07cd270d7dd61001b5f21969f246b788253f924910a5100867962f7d1da43466964e07b65b4c8a5a31d99221aa5fdb6caba7cc261967f1c74d43093609ceab7f4e2b3468b0eb53d7510bb9f15a217d58039db8d1821762653bc6aff3db813bc47d036321647858de30272812c0822c173e20a1b4e247a39daf27a47fbfe97b7521b5ceb98655e38d52733612c23e3f7b37309ef81aca060ac7d0e5cbb00291527473c0c68856c2c25ad5b649f8cfd01dfc32ad01a8c5cb09d57fa5d4b09e013f94e7bf0236efed765fb92687bd89055a66fa72df2612d34ae33eeec9890eb841a9a69ffbb81ff25933d4d212ff5372a685d9f05cc3ac6e5a8a9e9e7efb54990ae04acd29d0ab72aa149f49787a81d921fb4b0ec7d8b050fe6542fa7f4988e91fc31f64f549b836ca5594991dcfc610d5b298a1cc97dcd7c295fb6dafda8124a65bc320248d31c29870dd9563554ec61378ac7f901f88187cfa7e95f1a4c6ce819d0dfb35912d33193888999730e5cd04b471cedf3c0b5959f99378a6e9d9031d1ff71896112a1790ce20c0f69ce28b96afb924400436ddd5b65bba62ede60fe3ae5319b6ce161327c1854c9e0679a58c3f04f68560a7e6c69de464cbe8126e797b6b891dc8e636bdf8082700d474ef8841a9301e48a9bb771347573b627f84c56f80b3627f6203cfb22139f84836dddd7140bc68f63913a32e4850f6888801c92604e62d3610fc5183107d551005013aa0babe1964d10b92185008c75f0b035162ee8ed82df3b73bb5fccc72e439c73d67d2545eb8d2587c42dfe5e83bc053b525055951f00db5681de060194a3865dc57736ea22b14b53fe1ab2af3ac999c475417f1b03ef4e483f848146cc41bfcfb5661ad809349d0111af2fda5f40107b9037276f30df9b8ce9f7dcd9dd8141c729aad48a263d0fdcec3c77a11a40b62d550af1e1f3385af647159397e0b68b82147bcef51a42029652f14f1ba154d2e840a4fb578c80ef43a3a5de34150efb614dde25d8fb402d2b1077876c7deec893824b3e4bfa725771e804585e8151c73763a1af56b2f83b36d2c1b9bd910ab3abb3816324714fddfabfcd79af3dcf6a7a5a4fe5debacee7cebf891f35d2c756dbfe5b39390f2a59fccc12563f67e059e7f0595abb0a58cda17884bdfe075411bdce61657f6fdca555e776ae79994262f4cff669f34f6fe8f92fb61bbbb6f68db147b850a4469cea496b557ffce647df67dc693344cdcf900391144f8f2433ddb290a7701bc66fbca745216ded261dd192a48dedb70e32dca0b0e7fb146dfae56ceb7f6f0fb6f1ee081df6d8e51ada44d89167f78b0ff31ffa7b9faca97f1a64cdde7e951b56ee2bb2c7aad1ab011b43dfe6fdb092f8de6632578559bcfeaa37ab79c551c1d7a616c7b2b0ff28c2ec622993d6d55b2cb254b6d538025167bab3fc428023d7e624001ffdf71a952d2adfe70f021ee0e0d6754333a7d6111cca31a9c550904ef49e28d0220f295795fd5835e391160fe49e18756e40dc80122133dc399614251a0c8f335efb10014178c0f257a672626cd65e24a547a0b5fffd68a55f6e6011fdb23f1570adc0fcdd6c009eadcc85c16aafdea27a1c32456836fc1fa3bd12c2ede8d31edfcc609a446e7bdd5a4a357079623c66fd1142763a558bcedb6166478f6f56be294254eb50310cfe89133548489dd83e5fc0f1dd522d74994d30a78373b0b9e7709fbf5006e31821d38dca5087fd0a470cec8fbf82355c36faccebace80f418c0868d3ac7b72df7e2530a2066fcf0eef04fbfd5a87465f09a1a6254f233083aeeac8c92a749d07f566c7f027bae4b7c8d3a8a0a1c804ba2f5a700942e2ba014699d9421c98918117c11d9ac40462465dc9bb32bce2f9301c7bb6240d9e9483a69fe5a649c13446915b491436217cb76757b977fe3015f8dcce9de03774c334a0017871b43633ad9d39c0717af4489bb80f19ff54186cb6c0bca22d8dabedc06a18ae12311eac1a5ebea8d02c58edba545190520623b8a5c1a58f5da2400fc85a95b6738889ea9070715ec24cef32c215a6de2a8de534862e22c2da019020bd3ea07f05a17da61b0b8db9c1e8d29b6cb022af38fc3d2076741241f1e7e80467fca24556845e7a8832e4cce022ba9910b1510e4647aa95f01c1f2391c74b6e8c784cfb872b4cf9e59dc46cb2b27b207d77d00225211db6e3ce840bf628429a02aa8bfe41771ce1543138e1e5d99d2d3b9294ab26701c02d8914d5f139cbaaec363e86a59ab9b5121a9f15170cf15896a0c51b2c745b8bc4f6548bbc89a6b2174f0e6e7b40eba062904455083d1b7be606c4fdbe54c75ec27d56c307768fe52d7fd9cfb8861006f9b5205abe4805f7f7173413f7910b7af743461067cd962f561cda24ceaac15717353e20360c0bba8f01ecf2a2965d6e67e9800f3d98bbd06f3f10c9e82dd765729e593927b1d404cb07aa621909c330e5c3314b452860c89a4f1e79cfc993be3b508d09c5da1bc3f9d44508ef960945290166c705ddf223bee493d703deb459c36d1337336c2d21ec29a93f43f170fee280fccdc1b4a751721e248b4fceb424aa5d2a41eab94d44465159835d525ea8c71090678717b7fa3db30c54178944fd77283faebcfd45b9d2e277ca5bbc36d1af0860025f42796fac31afd88648cf0bf5b16ee07a4704e4caf658bbf87e1e285cca3c0ba10f3679e4ab4245a0ca3605c6f7425a44a45600063aa355b95b12dca87dd4b2ced1de0ffc90dee82d88f4545904650073012d0ff3b25c5441627a46699ca619964a7269375ef3b8b3d0957a1daf0cb4c70f7395ab6b0be96f298ec407b405f3b1631334a278a2d421d3c94ed06773852f152eefd77c50b2f087cb4e82c0a36d10af6670cabe8020aa71b09772a68bc75c7adf23de60351cad05fd8bde9cbc3e9289cc3dfb02801dc3ff222f630246107e8e0bfdb090d2875e3d78341faad6c6332eceed26d1ead7583578e7b776fd10b69fd394dc87a61173ea2d752312dc3453cad22381c21557d34cc583a3085d3df9c8d6650dc4ab542a00f362902433289b06e1f07a7c5e5ca66c86ace5ef7fd24bdfea255ae6c5fab839fb685ac3a725d5afa70bfe86698cace6a5ebe6c6e0aad3962a8776980881b525bd976451b072976d3fd2ae330a9d548c84b0c29f9adaf46451b993a9635619f9ec970a4975ac18787a242be19c5c35628d639637f397f44de67bcaed7533511bc83c79c12be1680a1544fae906eebb118269aaf923190f1e2ea971780376dc1b277026ee9d0c06666cbecbfc5f620e819f6f669b63ff7525118635ae6626bcaa4d48ca40fdad7361a83a19694ab700e5abd6d257005a74a7e29aa2c2efb7de4d945a79c0772dd468a2be59af40224218cef37f992d5e324f104e928cff52ea11368fef8450e07d1af083720a4b7628c7fb318e73a9f94d3a738a67cab35081509d6fa4d544fb6ff916a0a5755217bd9fa67fe307c9cfa717642f6b55321f3d6e59625ef617bbceb9faa90a52605b26afb1b39dd4b7df933410f6bccd766297715548abc01bd2842c99d6c69af6e3047b86b143a2e289463c3c1b0a570b357432a38b29d1ff86e9ecf67824e0ee08b00c3763709738ac69f7106bbb95de457aa816f711ec44f7469e39866bfee53cbb87f00a10725757b6a681d76aecfa7938798d36996ea5b1758df025e8ee6bf47afe606a402369bf4ff992b23bee5fd7d718d49e1888b6e6ee7c193e867c223e81995052daf11f33ca29819490457a9792a4bdd21078b5a0675a69a2685dd9f1af7665518ec3c00db02f40b7f73f97ce71f615c2a5ad52f1b8af85ab444588b1fd9b8ded96441e2993ddf2f571c25b562a9ae839993fc12f465f85dd4a85a903dd9e212144eccd92d0be83bb3cb70edbd5f1a9e78ea8f685370274119c68dff3b672d30214bdce00df8ccd07cbb08c1a30946248f18c6e538fabff7fea446c85b1c83a042a833ffa9ac7205c8fe588d0fe0940000dff8f9e65a988ffbd1e73ca12d9a8368b78eaa3199ee59be084cb6c9a7b794df000000da212e34a0bb8b38123e1d4011abdc64b763e38f8f4b49c8213b9644283d61ab97926f0be0440dac69d310335cb6ff3037e50f28621a7e718d49cc64069c9ae5687e9cf42fea44c596c8bcfc2b16e4fdd912dec11ec37fa49fca7ac4356b6dfffac1e02018a83f3b6c387c4dfdf2364b718cf41fde004a5f4300f9e7fb72bbb37fb3d6f75ea722cca95f093c370634310c8575352ad90e882e49f1201413e36dd67e00db2b67b9dba3426bc33c86554039ad18a49cf56beb6258963592853fbe6045a1e4901239b1880634ca7c80b904eb6efc0c2e37a0d8bc9f3f1581ed8ce7afdbf184675138fd367eed88ce97960057fbf97b26fbfdafe45ea3fc5f0407ac244fcce9c629a41351b35fb37243ba7aab9dd0341f8869c4a4f496857272c66c6e9cc19d8f150df9fa9db88302b42afc372cf6d1271fbe428a661998e955bce7ffd5dacd9dd51a4f093e60c5e27fb40d02c61b436365c4ff128895fbb6a67cb6982c6bf1430d7d1079fe5b8e88ff227f51bb59f4d5b9eff104cff80d8ba5ab58872fca9bc93e696709d2d022d12422450afc2a5badd0b547f06629758bba11eef0240350690e257ed99e0eeae02cc282133c3ae29a014c0a5ee5c4e2b760e0453651b2549fc6338aa2b1585289d7c3cfac4dafbfc87ef98b53287ca73fa3993bd2204916e5b7066c1e70cef87e39c6c94ac8cca64bf9e649b400c0a29d1a4880b9acda5fa6856c2828a1f665deef17ec5868cb5f73abae86d6a7968bc91921ec12796aaf3029b9e2b5e2d63cee27fa0cc8fbf653aabb24764aed3a6796e536b500fc4b9ff397635bbe377bc396e6e4f88903a4b28e36d88f0df09723e3dac57ab91c18d3de81d9ebff640604e7485cf5c75308b5ab4a687fce91b09dff185dc8705207435eb58d14861224ea74b205eeb0181cbee4f4b0090ebb664734738aa48aae4d5b4e2cc42244afc108ca405227a17e725f51f6230c53e633d3939c2d203e4ed3c718a4049e363423c762b6bf4f7beee0b3c5814e34bbb4edd4192fc794dc6006bb58ca74d4fe593e0bf5b830ac8a778a1faa0977a964f1eb5a5a73bc83c25c6d698ee700a43a1ab85d71bfae3f1b4bd7e3c10f4715dc2b0c794830a5d0e1e6a456814d1c16911b0efc6b301d00ade49cdf4504958537bdaaca526d32f4977fee84301327251ad0e9462f49e74d45b761f98f02266f352bb051212da30dec5bc413a68c863aaa16cc024d2babea26cefa5637a26a64337c9629fd9384de4fd9de23cbf6f98bfc7920ab56c2deb2e0b9d66ca8b303e4ff0a85c38a8edb5685f811dd6644067cab4a7c59c91c4b5cee32f4b5314716d6f347a2be8081f449b84561fc4b81b0a1dea93a5f30ec4da94f220e3205f4615d81781b88e542020e5a2677a6b97f59d8494e884c6c200cdb3bb9d5de1aaf9b8ffac6b625c2111310df92220c5df5faa493d5fe53e7c700365ba2fb227f1b47edbde687a39412773aa06386390b1d362cb82ddb5a310d40ddf42cfe408912ec31e139c855a4e6d1522ea26f4b61c0dc8d4c51e725928ac65f07d9d6e348ff4ddd33f61b59b1fcc1ae9eb6fb9fa87427dd4339a2624d7d3bc12a3bc9858e96f70fc5bf7ea54cbd94971de44c421cd96e68f9fc29ded48f4163515800f1543e130485d2e23306ab4f840fce8f11c8c784b23a973a2caaddda2c060fce2f9905e66f1337da32e27d13cd6742fc9eb8825dcce2cfafe7f3b7dd3c0d20fdd01124b8fb60ec882cc15e51056eec1598dfdda0caaebaf5dba8d04dc0d777808fbff6caeb417eef096f500486d8654aeb65ddba4bfe3ce4e71af2374cba919f4c46f64ef33acc337d9875c2c0b9b96ecbcf1222299694138c66638e8fa735bca3f3747d4d75a22338476e851e4b6e1a5dddfc0f3cd9dea549449a467624c22eb8973695e8b11df462dd05dce1fe7a311fdda29c82872ce0a56335114c4507c351d3e2c8b985956abd731f01e92682a19e5bc023479fa23a139a2281d9cc511038b34a648e560ba279ce291c349243a6f28d21093496f9c38169e23ad2f1aad2d890e576a4093025fa255dd9e13cebd731506bb4002dbd3360ec86a903491c727e93867ba98d7156916460bb308286a47b28e84835be6451c2c6448e66df8c2b783a794b8a8f07ec00705df9763c800218fb4f76baa0c8c1cdc1c581e7794c56acd5db6c9aace866b10f1911b4af8a4ed07f1d64a8ef323c166fa6237507c21812a2b633572c7ab39bf220151ff5f7799b7e523640b955c4110a5ff339497809731699a97b3062616e9b8b7968c59594f357f83072a0a18a3f52c046708b8d52dc31c049bb0d207d19a50f3d24d183b38cf3ebe0a0ae2ff4555d66fb17d9b0f3b19e9dfc82d51168cf8fbae9068efb9f44b2be24772219e76d969ce4586a01a7c48e1d908ea776bd6f7ea0b70efef93f714aacfca64488eaee54f8c6c4070797e07de14b8163888504e998e7f539d36fcdd34f75cec63c3802f43400aec87ed4c18b1ef2f50c6eb04c3d3c1d6831d19adc73714c5ed40c5ae36229cbe24ae9190bc3564d1592c5af711453e17706837f462461e04dc7ec4a341821453a871f085027d252858d06fa6497b0ae20b80818be487e26d4fed28dc86afecf2929329c709008a0cc7db7e2d2ecf83afdbf45f2134d756b40a9a2b0e26749dcb30bd2c130618e4e472730f30d9349581f27ef1f4dab9527c1e820628557f53c48cb33cf1ff398cab2478bffd2c5744a1e318f4a5279bb61e1b4e6e0bbc48fe3421260d6f7b7b194e8fcf2720062108fa40cc6a081ebb6d1f3dcf14a3f3d8040e24f2c33ca2ce86c1d872695f073c9c41a65b8a140ac1685c02298a7d95eaf133ceff0258ae6cb331b30eb804fb0067be95b4bf7fe35224e22dc7fa735eec971b6e8913ff93f96485684af1b32cd6bb481dc7aab2aea05ddc6b4c9fe13eb503b9587084c8b9bb53abfca09600fc427d84324de5df97808247fa81cc2897cf4672c36ca87d974c0446aec4c32a07478656bc6e7ec5188cfc9360623fc5c56ccc00fd3dd2143a274168db0cd82617f8858c7e79c1a7a6e708a7abba41aa488fb135c869562ba9452c00dc452abcb27f093f91f61336f0c34436ed8da436598ed4f4523c4d468a4e1cb08f6f5d8ccaa2a857408c5d5bb8060934194f11a75b65685d9927ec1402f4782222a93ac77815f1dc527272949c94fb11ab92d68c04ce33ea5ad6e1359f9801b2b554fa48f0cc3f079d46c196cac70bb32010577cd415be0cd85b1b834d78c426d93210e729265b878d6335c6070116d8d71fb0a4e2090c8e7f7ede4db9ac3feec8df31b35975cf0f9e2ebb7e4e23be7f918faad61aa697e5d4c6fff40acd6b0dd9833473dc41baedd5e3dd5aaae2203537d212b97431e72d2a391ccd2f41b7ac64f64eccf613d67c8cd077878cc8db3db3b9dccbe0cb64c7829d0ae1c069cff7e0aaf87a5ee2218f60b97d8c470f7f37ba2ffcbe1f2da492a71b3277ed182664202c5b61e31c60bf52dfd06f6594ea355bea545ddbcd9d9ecc1571527cd627507e69060d48b3ebf333dfe2611a0c3686c1e41239fa59530f68c953d9f8aa3388babb88b410cc107829f180221048a2108f684500887102e86e6109a8b211242b418e240124222846431b4866014431a8436e291f6c02b02c8a19310bac8a1bb107acaa18f10fac961a01006cbc124844c390c33876c08c30d61a41446c961b4398c35855c3114402812cb7800314c8230452cd301c43203400c2284123194422817c36c0873c5b200400c8b202c1143253c4862e4e977f53d0c303d87a010434989b518e1acdf3fec56aa5ea39b1d9f8bedf93af7421d59000b2bf43f833e807a725bd3f91805fd0a80a643fc5d178d1a0b7001e384ae2f53d56a5938d77de35db406fa015464a052037d3788a7dd5b93aad922d2156e157e114fadcffc4f2f45004ea86114a32623a1726a01912cefa747718db11294867910f0c4914fb1a29d3a552d31ef874a979daeaa86391dc4dfae02e99fdc6eaa6a27281ded4e40903a80faade577a52148f63b442557aaf2bb3990cb35b548510b6527a82ec290dd58f6026c5abac25250f1c7d53479125594137afaee15ea421b09cddca7daf3348fb8be1630efb535a0522fdd840a55a5c98a1ef5b59d38d505fab6a07f42e47368027c44a14c94aaee7948bcc699ae5a72d56540b2bc94012a53b6aafce71753c164d5e79777c7a151017423447ee401204114ca5c5567b769cc79dabd8665d27c730b01bf49bd4c3b925b0b9a39db4ad6715fd35b0d325da35855902a9817e02cac05cdf41f44134cd1dd366e35ff8b9a31a8549ee75bb900c2c53b3441e559c16a68441326981c00b599ac8777b29386119169fe32076c5245c33be53d31376f6e09e61b430468260f8b3ee3488930234895d6a85930ae85aa1e1428298b00c3518a0bc577799a56aa72080d28f30ed0ab72c8fac527084630ef5f0365d63e2f5dfbb2ee1760cbcb0b4895d64700e72205aac3215813e12ab0735e475570f7e52d99fb340052943f125bd27ad30bf7530fe9aabd961a2b7c4f4b0c8c2d47224dbc118445a12ceb9bbafff03dfebe37ca9be5dcb5006e928f6e29da5c15a578f235afd3e7a971611f3ae982b0fc429df70640a26b907956fff65f1cbab954be23f07672c7658078ce0a1859d38dca5aef81a102facc9e55f03151ed04eacdcdfed63134a9b8cbac742ff7971b005509520d6b0e9cd8c4aad49b87cb5f5cacf515be39781be2a041df65b9804b1ab05d950c94d961d33434f5312934fad023a5fc41be8b1a84f2d0673be5aaff678c07ed7cb14b4f5b6b58074a224577868a3a411c5deb2684553f5cc4c0110630ec0250e888fc5ad1071264f0e759046a332a8fd93180ea77a42d71157dd4ca9ecaefd7a877d57253ba7bad7d8d9e093e1b82a87688ea833860fb2ebe2794559cfdcbd61a3bb366f434cb85dab401c723414549a77891beb87bf8a4f18ac8ca9419a578d602361c71aa76b5ae90b111b10e835ecff90d4b0fb4484c11d50d45a433c659440d87327fa0d78bb7a331700dea34ab49037a0d41c863445e72e7b3f9b14df5ed2250ab1119f6afdc08389c6a17643f2a9f90452db4c5084b9ac0c7e423913a083f57fb5bc846e5bfecd715fe2191b288ea05a9d1e10d340d610a65a1cfb9615c756eac29b66659a85fa1a0c53e5a8a5fb0f63fc67f327a2ee7c01ea65096dd05baa7516bade318fd31f315f6b4fb5e67a2ad9aee9bcb9b4f4f6997efef4f49fc26f42a44e16b1960a8285468d34f46f5b35c630f804ff2906c02dbd5baa22456581557c2bfeca16fccaccfa1880c0d0a65b9e9bdbd8806602bbc4931cb44596f6fe4bb38143fcaa5d4db54c92ef3c4ac42cfdf84ffb6bf10f397550164122a0afaf3c5ae98cf232f7bc90e58c41cf0fcb7aaeab0fbec2f1e92576934a026416a11a421700c210ae55035654a445710c39135aa1b9a70ad0cc24ff5fe5dd4a245dd3f01e22d3b53f69416782540ef431455a201fc4570a790cb5767c53933829ae472cd171e60668a3f612b1c8eba005725d116077010b9fb129c16dd1c42997aff298ea5adb2256bc270d4df5966ea200e86ee10350b50eb030ee8fe4cc49e501611aa6c96a2a1358960ba6aefe9e64dc080142faa6a375b8dcc140cb508521b22430028946587c7fd2c6e6e00c38f297dc50344bd92d07cc8232dc6cbf0ae24b506d946836a97b068ae52d2d36d78a47576a3ed4260fb1ff43544b1766d20437b425976a63e907d5c8869d42acbb5b3064049f2916d92ecde36a69ed72de97ca56970eef0caad27e453a45026da54cbac8ca91161ebf7a6fa0b3099e40ba1d0c044d166bf5c619a1f4d2b9369ad4255ef72d31c02b26ac25016f406adb287de3c451f7b2812c07f3b2c38c2ac237cd9dea7167aa73150573191bf017cbbc9a4500e5523ed2792f7304e0ea006b94e44330de08b890f03d2b4df7e167ec74afdf754667f165efa4b55ecfd8ff9eae5327af78ec95929719a7a7217340815dad541866dd2fc790ed42e1ffd1511c4dee2b5300886ea3b52d98953f51b806d12f9ea0d78a748a5fb92e62fde08f6f232b9099b46f89944e6c518604a298f3c26a1a2a06b2f7665a70bf9e82b75e8a6f7e6c724a0efc9570113d38e077d0b519c680048e982649eddb1053d575727734635f2b9909735e84a13ee3480c71738fc3e7339972d39ed70a05091ae6bee7075306940289a99f004b12e421dc493006c0ad9af78714f4f7ca0aeebff42e2630a971aa5c53db93e99b924b3c55e1eab9445290cb8a76b253024cc29f8fbecdbf45e5ac99aad3f519ef9ff26fca5371cd00931e2e39662f5a8c06485ea5170ab5b00f60613ecb67bc781a5864339b6bbf5efa02cbb61a8d57a532c3c6605bee53a71741eaa1775d76b1606dcaf263f5085409f1d9bcccb50a97a1d994c346303accf4f546f236b4c2b3d712851280f7d5cb442b4e577686c9b92226a38a048f5fe5da3d0abd0aa907c4f7796c003250c9d4945edb248270307c199f5b1e794299cee9bb4341781232ee0a3738a1139fd6da24980110afade960cfffc455d861d92f8c083308e4da7bf437f21f9b7bc3cfd9d54e58e14692e2503b2295e0a6a1a5aab5f6899e35b536879e453340965a12ffffcb45f13061475c83209366bc0f195c8101f81db921e3d2104be963ece2e648b1a142b1b3051132bdc680ced10c7290ba86388ba6c70b0b529946967dafeaf947f931afd3b9355eba1fd72295652643d748dd2294c1d79b637cdc9cb015dc096aee56dff86d8967fe5b32a02f93cebd2903853bd27948375f738d729cea0b2c313ae869066d217c06001e40fd97af69ec517e5b6de748645e2f5e2e7fcad963643b5e61068c088ac6bfdc19a9e36424750f23859f8b19bced59e4dee236113726dd46ab54fd9c5755004750f52afc21b41a38badb7ee78591c4324e8c934abeb5ef4fc268a95c6a81c34f6c3c6adc7f7d555f051903dd05a67385cb55d723774e4013ed52c14d43389fa0a4de04dd09e50d6aabb4b6dc5ff49eb3fd46c67b994791ad08e61c776419f96ac9cbcd5dd560a4c6d9096a1ff4d849951cf10a513a5a8fba65454a4768118923bf5c968c0b62992e5582fe34a7ecf14a6bdca52e898500f3d13738e70b3fbe357b4f54c53163c3146bd42d3d7db0299607ea6c9d96286f6b5e600a84b7092dc696090e477e1af7fe3ce9f9968591ba7078de4f6cab0883132f5566dbbf62cbd76d27b18a959dc9ac6f64c7e2c4a557aa6304527044301d9bf0d4497c75dffcba76c5ebaf73f0dc794558870230f58df0c325028242d1548da95dfd123515fcd5377fb7c7246f25a9befd22c816db783d409f37fdb556be0a1e48aa3b9a3848f84bdf22e744bd5cfd55c7d5034b6f813acbc2a24b6771325b0790beca83da12cf4ede9e92391c48ea31e592ea53500f8968a1281aedcaed615e6745fc6a695ed28557414eb810e51d82779b317c0d64df09e50d18f8239e16acc521f3d50fa50c8ef926aa2ba193d3eec69bb284fb81adb4944dc024244a1b2c03eefee9d0c182afa1acb37febfa71b481577bfa177c5b29b4cef11450e3634193f381de85e65288a3fdd7ad352e1c2cc5b65690edb76415344fb32be56f52a54ebc07175be0212e3a2f8498a00a4f673077b984945ae3e72b63f67a72edafe6ac777131991e18962d6b8eb566d4defd91f28e752bb748be7033df67e28ff31bcf0dba785ab4235764b6fbbfec71ff068507dac4b6b60869075862b31fe0a2b88d480f8ff57ad2acd4f9c93253a21ea03b32c22dcd3a80e246aa174b3546a7847bec57abcb67f00ff34d8930e2f42c213bbca19bf27f23a23a85f21a6e885946f021eacb3756daaa8b0fd17b2fd1597b753bbff9d61f23829408cb1030ea4c9d88c2900652d8871c0de6569028918089ae06e0d4bb74c02d90e24298bc1fa3446973796b6ef910068c9c2ffa4a3458cdf144571c9445d30327ed7f47f3e34c517c8b11776933df7be97c60cc1412996ea28b6e059b4623321684d1b1b26df9c2e1bece034896596d8bfd0ab9a12b24b393452288be3ffe7ca0412dfa01d6ed204f584892b21994e75007095acba15dd5a3533b5689c63ae1788befef5b4f132af024bbb8cfdb73c980e151abb92d522bcb7986ce12cb571d5d405ff2080aae8e81d630a51b97c2460f587310eae2a77594dc97fc266b63d82bd9e18716a44d4f562038b6d445c1327170f0c41c0a9e56ffa8b497197a6eb141f728dc443ea7af53187617b5f4ead6b263343f23898f289a776cd842592122a0b37383659083cd2e308c226c09d89b86bedd6d060b649d466e1ff157bfdaa84a23ca935bd03666fabeda372d260950fc5d520c6838ff24f350ec5aae9ef46903a0d1ec65be84cb864d1d91e2640dc35444376d82ea3a0780e306788007e1b112ca50a894c14abcfbf6d35a98dfa38a1340a4a8679b2d33140977fb9bf83e3751b2c9866a2cf080d3319673f48ffa44e9fcb1c6f67574cb3aac09f2032e18266d6a2d2f30da8da620ab3ed54615170ba4e6384f5d266a925e40bb60bf4adcd006364ea223fb0f2ecf2203cd0362d110239f700871213dda25bf8160c040810ab134dc9bc6e21e921199aa02b3dcc74bc7d99893aafaae8b66da84699f80be98f87012db54526e48851459e3bf94d6fc321753f9311e8dfae36513ed1ff47e5a2f1903bd1a3766592728c5e22258b44e93c8413ce5a82ca416c88f750eab7466e9bb03781621f73cbfe04601bad0c8ad7b368bc0c7a00a53441cc421856841a72769408c490ee14cdeab3fd933680e12bf0601d07e20a31839d0e3334bce8c62d80b295c207f40859e10ec786184da943f709191909c269ce5a0d19a4764af4a7bbcbf21c04ed8bfca2e781bc691e1dad078494ce60aedf21b037e1bb7aaedfe11497e85af0a8fc06f4cc896351e87c840589f687db027e7dc801602cfc6e9110cba2b5684e39d8337b8792c0bafd83075196b5384b68639431eb5a74651b3fb195a9a4da2bc7cc0d175e3c3ad0f17b1dac70099f83f7c9c5eaba507911b00497576ced85428be1b0ec0f9c421f409f6b83f38e770a32dc07eea7bfb04dd943b748d9cf43f98c2c338ea41ce618a60e60fe916c62b35e8f8a18819d2c28aae480f570f7df1dc054eda3be9f195a4a70e12eeb10f2d06919869ee84c5337bb816b3dfeab7b1a5c083fbd97f0ce722f42f2e7fdd88d97055c0d4b652142849710b7b5c967a1bfdca347195f49b0e945d1480e3cc444c36311bbbc5ddcf60855ed76b8a9ed962b921b15cefb44edeb75ea44146686b0e9363f97b7d1ae276fbdb2c885a7bafefc88a2580f96a34f89f2163935024f8c0fb969899aeae360bce21b8e4739691888a7b56fe0ba1b26529b5b61349b65064169d1c944f0871874f8f07d9d5236318e7a7514bf0e29fee5dbc51b73c40377f8cddf172fbdc0cf42c68026d662d35ed06c37968e1ab83210a7c476e694c25f54643e14579793303075d3ffcd73d5d6e41471534600e7c5f2c17991988bae38a95681b4c8d75fe0edc854a83f0425ee8f2bf2babb3820ecceaf3f29f597fc2bdacae1f5cc2445f4f32fcb1e0339fd4fa6dcdac8bfb902d091ace138114929914b2b39332feb982f888afcdd8e3ec9d0dc095b315466fa6423028b1fc590677087cf4c6954e04cc42ffc3a313f9258675f5585e030ffb720119c384d9d8063c8fee7b11058c5df190d1220a737d9c61d53626350cd550fbdba30c4d27800544f6fed4dafb0cb1d49222e8d12dfeff2f868a21d742e739b37f3f9b02feeb1bac01f192d6fd9fba4ae591f8d5e39135c52112e49ace6a4a0b9f4599c814d4f5090152c67253bd61a24840bb06419c3e20564d19060a5865712cedd67a33cdd3f1c2b31296eeda53358f544b9fb4e835697d32610f36ecad5d6e4e05849c6b77a26e14fef90a6be4f539bd760e52b11551d78638866539d2c12e237c1f7bceede2b2834be691fc383ceee15beafdff3621a6a92477af41dfe8e041208f905b577f0973cb7fdb571b7cc2d567106e0bf9c55c5ea7ed0d2d9c13f5c0a1ea3c7924a62d635c449dc12882dc0d3fc293c58dff02cab041df560b374d4c554b879333b7d7fcdb0cceab98f8238f0691539e4614d080604adafc8f254cb82ae4f444d85195eb61c8be87fe8642cf858c5c8dde7dc77b203819e7c66e37d0bc49aaae93d2ed989d2bf36e8c08fd591452cf84945ab8f566613f3196d0dae9976e0c82c39c597039015b252972b011aa4612c96e075647494894004e17bcce3c0093ebe2df71ccc1caf092526d1a94c57dda0742bcbb8b464fbda91eab0177d3a1e62a3fcd276b71e0ebc6ffef526bad9f137a2a8fc7adaeeafc1a9a75f1d7bc29355a6cfac89945f658a20a68d9f24c79e246e95e76252d7fed193563456b7142eee2cf947398a3a4ce20b45432dee11b0445539be72bc8add6fa23646aeb6515ff261b4928c4b4477cd7a9da6b281abc024af68dba44cb8c1bf5f9b7c7f0f433ff9e555e97351d35fb0df0da351946a770a2a4107acc1be402353f2e141f4e912e5c6f9d39aea4139867cbb3513bd1c2b33fee27f40cb0d67d34f8b80767c3cb434016e6c8eb5831957cc787cbda99cc7d190575b15cd3467171f922e2afa63599f4cff00344e0597e42dc36db2451a3efc265e2416c074001bc11610b7487256d2e2a6d27988b4ea42200486fa45606bf9be334ba05271146cebbebccbbc8e65ec514c9059de88e662a77c50385a904fe3e7430b24fa73927b8f2efcac6c27d4c2e8ed61d47a12fc918d9745de2d06728b779c48a59288a45771545856b6a6464ae298fe0c7841ff49cb6d8abb29b25ae19fe974d4f6e4cba188aca86700f183a0dffdc6ec163c8af1ccc06ffe7d9d2b4d3952a6edb4a2f9d0cc379765b84f5536c8ecf012aae8cf951fa5b6f7176ef872ebdbcb84071247eab45ce5a76ebc731bb6c6e18e1f30f977b3e31f67479cbc865735bb43f845d9df5473f90b3af5567bd23cf096ef064ef6e5cd811b1504e974ad81b5a9028ef80b4df3b9eb584ac84cd307711adc6dcd8c0229eff7ceec24f5d73c9c9eabd57086ad3ab1e8f7ec4c5e73f6052c349e46a7479443bf85d47e4f101af74dd62bd475217f06582372a6a62ff21d18b607b383fffa171bb71621498cda85ccf062a2daeae0bea8af8856bb5aa5cbbae5aa034e8ce47182b6f98f3646fb34d38c2cc1aa6e209d611f22c34ed92147270bee71535bf31687bea05c61bdc7e2cec21fab042ce92db9da50b4398d2fc3c8adac56c8ab124fd6032b1e59b3ed6222fa6102e2b2d35ace428afa715b3ee83600a4ab40830334a183d3286afe8e9a57fc09824e8c6427d891beec833f0ae00a426d2bff47061a1c8d2a8044a7e93d66c336ac830f496407f08f5ec3e434fb140d4bbdfd816b19ba38036e1000e82eb1b867860c13698c57d8767ef6cd6072093ca1ce8f109788ff668cb31bd7ad007c38ac280550c3811ffa1e9ed27b27178763e0e12d056bb3349c7b33ac3ccb29ecb3f1bec34a3c8c96134e452c69af71aae397ea9bb4f0bddbc2e2a52039737107bb72d2db62fad4f774226f2ba21a3c68f86798849b0b92eccd07ff6447a4325f45305c4713626ab312fb4bd964b18662896ef45a7364fdb0508194c8a6d57c49a780542be27ea828303ff54f082cefc420941bfc89b44d6e8c3dc1544de414dfafedddeabb0de0a9b5f32ac8cb8a5ec1c5594bb84b2fba5ce8fb1f415525ec7fbe973eaf546d7f3b52abd7ecfc610f12ce11d2785b0cad75085def26bf1a1d6c021b88ff1acd4dd956d7c8c86f26a0ab1afa025ea5594ca5b456a7d44c2c9e8e29b18dbd8e14010627d6d62955e5995d762c6e9da85f20cae6b64e873c58c7cbbf33a7dcaf67aaab86243683bf5b51950994865e0d0a60a6285fb00e1a9aa553757015709fac1c45fd6d5300ee88a69b577aa457fae0db5aee945c9eacc89c72abcc1cd0bcdc8af2fe9a2546d08f942b72312f737bd1346f3a1599758ba3992212e78a6edcf66a212d3cd7c8198e82e753f045fd91596458213400e5d70168e5847ead48269f57c45737ec8f22a4fc5f10bf57e4127ebeb4fd0f1557c1a126e5ca7dd8191aa9d90756a26877a77dda9c08e3f60c4d600cd7970202b42763e5a46e2f3de8d676ac932115b2f13bb87edd0f5bd3d80f5f58b25d774187a6e921224d718df994b998764b7aa71c4d0228a1243c012d7dcc044ddaf04762adec15678aa123331ea9cbcdff902d186d8c6a619d82f7f88ce1a0b61fc4980c80017cdcb94f2ee6d6fa5d10deeb75431b15564b7398bc4daaff3aebf7f4f56f6f9800af27b309ea06e62aaa0e2732a8301708d902eda6e13f9a2be38fafbd1a748a3b9d50bd5fbcc63e81bb021b600d3b158bd71f5897af699b22fb11ec3b07e73a34545122e2d3df58f6d09d6c4309e5bba5720d2ac6400ea6227b3941b7d19a3c9bac8211c4eb38153b1ded251b5dcc886ab9f6a079dce294ab4068fa75e4b63421aa744ad4dec4440b89bcf4ded043d3ed8a11629eb5d15cf18d74fb808a0fadf91f8c0338091f7cffeed5dbd769c49ee9666fbe67999ec3d537e244d15a3164826f09c9cdc7c476361854f3e4fc607e18e88168372a0d84fd23ff62f7bad81c85af5846dedf3eb2e7e68b080102e716e8cfa2c3b7016c18eaf531cb6998fb0f8ebe1455bea0ceabe4b3a6f987f435e839c1a0185b0e6656e3659b490a89cc9da3d3c4327849e278245f1173cfbb6e42bf898750e4f27dbb043fe2cf3fa9eb9f023f5471feea894226b7341ce154d4f40a970890e4085a6ae1c7d5e00dc35a6187dfb5b85003afb93c82c53072239a5bb85c89dc162a62d75623c4afccfa5e5a5a662282fbafcce3a19a33adc3fc270286764c1a04fa0034da5768961c8a1797e296f5f73cffaf924ef4c67ffc65889a5b660fe13dd87fe312b4bd87cc596a5f1e93ee8ea9961881bc418f95f2405b69335ee199d3d92830f32e1ac0acebf1a899b869e510ea23b2f706be0e9fc7ea244975d2f82336145c9f533596c731bf801e8ed3e1cff9836ac5c60ecf900b2b268f9932d04f0e168e5f11f538c721ecb43bbcd36985ed87476bbf9ab719dae7690be513125b84563ef78d085adbadbf0e5188578238a35b2c012226dfc4f3f4e2c0c54e2dd6e7a204b576d6b183d8228621bc99d61007754633d063f14d01f53eaae5692cf9a99259300f5b6c6ae175fa4c5e36f933e653e1a256fc9093bcdce4e52b1f4e70dd6c22ffc8617b8453c77ed6417d7a79c5d16339da223f70329fa595dca00c52e699963bb2655a09d3fd6d7af80417a8fc00ea87e1293598e5027ba40e0dafc52c599481824944e8346af799ac19cf18ead14e3042b916494bdf24b809534d112cdef10ca68ca9d5ff7426bd20f0bd2c2e751e5e5819f3a23fd27011034448a35bae140025898911ee3dcf9685a3e45e1cc196ddcfac3c7f2ca55377820e8dafcf4884466aca1590fbd23090224938f4efa18130b40193543fd8d121b28c81fa4d8573c11d34645c21d72a8de02c102e0919e185e297a803c80e67e5913db1fcf703b35a4189206490811f3c360f2a693d0b4e14433573eac92efea9fbe75a42fa4218025e9292cf7c032487af13bb27d0f17c0424ef67cae95b61146f8ca345d11f3ec3a73aa13fbc0ee55db5e09322dfcfec3f538ff6320aee44421aaaad499b970516115ca40b5f5606ce3bd3cecbc972be251ea2c5296569b94856d32c3d1dd416940ca7582de88b6f58c1944ce5d4ce2ded1889f51828a388ceef5e1d455cb7edecd088d72883eb7fb7e9f4bf049a14e04ca607c55530fd13bfc8103ee3956a16fd8fde1ca96767ec65b7f093d7ac4eeddf2c81d195a1d36d53b929c20e104200a782be5f65e2c440e668ea90372b28c798036e30223bccbb05f2dbb12cc6f881cf2335756395ae812ee748a575c8c6bf7ae37e4ea0651c0b474314cce545701d856cc161db832e05cdf6d45c65d23f5123f06e2efc3ca5383fdcdde4a7eee74c784ab7aa28ea03ba0088c33a340d2ca802e7e3a7660637f9bd4e9074f5ee66a5cfe6db50eaf04eb1cb35681ebb58d04af1f9decc8069c99482ed5149fe26e7081b08068c4fe71255da45ab86611faa005fc7e109874c1cf297580d972ebd0a9ecd4e1680fe7c9bed12373b29d1ea89a8a8b1e71e61982b0ca510b91eb7cc61675f6685b5f82619e84111f6ecb67629fdd68408a0dd99cc35f64732699478452152e09804b9bdab1c3a4ad3b7f8d5d2ba7d681e67c0f154334188897340e75f00dc696ab6878a1e56fc5f52ffb98b9df5920e0e4d16d925df20ca826c35f532f53bcee85c214e4de0188623ce4297eac5beb467bdd1f4105d66a35a2fd1449cfac35db89dc89617ffc17d2d9ca8b4f66e643031bc4c7a07307c35603c8d7a716d7d1dbf32cdc69b7b048f4e5ea7e851e44748cbed20405576791f1e5a0d3d3bb2c05fca077a8add0b617d7aec07962f3d71710834a62fd656c26fff37af6bacc6f646d47e556c3ad38c6c27022f2604975d3dc494b5238ac7e3d0c37085d98316bab580e2e2d63e559d0ac676ac19ac9f4a23f74b5fa55ab1606608a9da410a0ece97b84721d5c92650c42abae55970d8df3e8ea64dca763d510fcf661663b5e016510127e17ffbe3e9756d607289a8392b43d699c986cf612c1741e6df364163cf123379538f3e96fb20ab00643a3a972a12fce6bd448bc701e3653c8b68c50087e1bb7c28015d180127e8c2ce0fbb6d7ce19209080faf54b54fdd762c94a257330b16370a7678165a70bbeef015459036ef83fc3ace36c171950fba0ad764ba3b3b18c5edef30a0e3583f51487963fb785e50bef936fcf6ef3c18572e3a94d6d515e9e055bfcd6ea86417822849f98fdeaed6334236351a55218d70fde033a0baae77cd1b0203c6104d45c550f8a2d660fdf950f2ea6a733364ed02a82eb75fa9c188c59bfe83809dc9cde6b40465675d349e1c11e44fd2782e87b84e9dff0adb1e70860d74e5bf36873c7490628692a3f03de173cf8152a85aaf154a590f1270a954ddf61427e8bef55936fc588c16df22b3e406e8eac3898db24906657f05c84cdd8fab3ea983a4097b2c6d7c5fb888bfb592f7208d362812e32e7988b98bed49dd7f8638292418764419d61a12a7441f55b52cb6fdec194f70d21276cfb5f603349b3d8d3e23a5999d9054112d641373f7c8fcde8635094da4d2ced38388e13ca1af8feca88e6065df3cb90ffb0571537c8985f58e0d828206e29e10380d7d70741f00039634737791325bf486822e7cc2f286f727413b4166e99b1dffc99a948aed6c650089ae4505a7247d9d5cc6c29810e73134bd21563ab4e8167e51c9cfb599787167e810962d43246a2135abf246d3874ab1776cb6e6cb80cd38c780451772996ed976f20418373b1491c8c322f9e74ff0b0245b1b93e19026d6bc9b2489ea09fe5f7fb3361909446472466ee6409ad9c3fa9224ebb45a169cf9d8dea2978f86236d467daba46c27f8834f8d7215c68be602d3ff0dc593fea75a3dbb25086e0e9dddacf863ace017ff0c807a2d2fc622477c31483ea0964ee2d8f4c2d4717102e611f2448f31375b8561dbb89ea8c63eb59e1b4e3ecdefd0d60361221dbfa72b3a41148dd79001bb51a8dba7b5681ddd8e9f19468dc83d278b5091f23780e728da9126b9d1df7a83b920d5d29e981f984c0628427d5f2f8c27b8eef03a6edec974c60926d282ac9e774fb8a1739861a20e6d41ac222a7b50e4b2331ad6097f709b98767f13349cbbdf67fdcfc5cce263267f263deb593412ee7f7f993019005a36ddf40e77a96dff17fea4cb3e5f8ed385b1aaaf32f8436d183a47b6d83a097782bd426fe11f48545bc388ef0552f8c9aa35ff3c2a6a9130a4dbf878d78e42e021553acd45cb934dd29caa87a5d11775d5e7ea2b2b59caf7d66cefbdcb0957fc0919a7c6413008306e8522ff202a929333baf93f32c30807f9a1dc1e7b04468b8196bbbe37a95298d10f09323b76616db072911df193eb5fda36b496b306a23b18f92abb9813061a17d702c2177b8659634df53b5c4cf9c9bfb2173d079b9f8e9bf1d5acf2a8fa4dfdfd2c120fce91e6c49c1a03e32c0ba1cc5500e1ddbebca8bdc4a1725f05e0b206b9bd0955ec487ad45a8116dbaf7d8005dbc57884523393fcd04fbed7f3772f3d20b759b030a6be8325e393739f392dbb2590c433ecd7265ff5ae4ea6c074d236a04399c60adbb91e8b285064ad7cfa2a9976d2baad4c0dcefd24463b876caa803c684cb4266caa1d5d4d53b8345f21c4edc7d3455a46973a57348a799900b253f2a8aebf191c85a71219f196b6b73213898c455e74c87ff9697a07126b920fd3ca30df5ebeff107311832f9beb01e77dd4d6a151cd70bc2a3ceeb73c4c4b82ff90dbeb1e8d9117bb64f5b94c2bcf80fe548f4bd45955aaf96f2f7723b84589caec4d3ccf62a82b34fc433c2469c7adaed81db6af42648deb915815bfd018afc4c59ef70f7160c2c79c3634d51104898e065283e1dc1a836930fc1ff218139ed7983cc3e4e162dca1871c4fa845b107d7cf76415c19abbd730f5ccac09694ea9f931628e677d1ecb294c1950b8b15ae526ae1f48eb8283527de4cee8a29ee4e795b74d0625cae5f2b6cd385d61ea9bc00583f2bc708b9633d0e42c014ed8cc400146e8e44b174b6d65458123d671a1c4caaa1f1a01e6f4c66335b27fd84837c1e800c7752df3f45d0f8a19eab29751d4c6a7bb89accc755f9b5d20b3b773255b17d426edb43ee7da311e66c254cb575ab25a98802deedf640334ec328ec94b32b50d5ee6b194f304555c14ca4fdaee561db465fe0c56d62809d56b61e708e5c95aacc9b57170f007f1938dfded4b327c3bdeb6b423659e494e3bdb2fdc68cace7211472b530d0e4b6976f26cdb0d220462822516fcdfbe0a2008a1122e98af5131348df770c3243dfda38fc449144f98188ef2641ff7f68022eea90a933f92af5c143974e38687a70b1b3bd70a43383b1396ae71eae186a53812ee4698db19aac6ff35d79dc658ce033bc29a2b44f7d0b7622e394d4190c1c27120d56d18f39a038be8a24de373f549328b4dc4453fa94198fd4a0d8ff7b132a44f34fcfb7f888869b541787707c2a4160defc55d75020f6c444d1a65cddb2759dd60c6e7b26c2879f7c3776e22a8b57499ae48aa957bcbafea6abd19caf3ce14e16f215128d56d9b59c084e5d08179cbb6355cfad0b4b318d431be245664fa36455fd8fd193defe4585e4860f056e0c25152488688277b9540e6b6269680c5d0943511dff73800b095f8f77444bba6424c81c6004bfef8b233b32181d4af5ec8b5c8ec65e529db1c268159368b2a6bf4eaba91c2756ad8f8b6eee79597e4ec71a1365964fe3cfcf7300d97efc727c897f7d49eacb9b3001fb4558c46f64a280fe165d7b065d3e4a9ade56eae91de04b50b93767609d716fa99c93960ab27d7084886aada110d2c862b2e01b02294e8f8c1eb41da25d89c6e709de498cb358b2ca1cd4063a01d6076df33114e823c62fe95c510f17ec6601edcf6c29837563ed4ffa777df15fc1a1e27668c93fc8bd2abac7c282ac5c947f9cd308228cbff9aaa801cbbde757a566ac313084baa7f312a6092c2ee484e2eccb960db438abd88e425b84227f283225732c0d81f29264a6ae7f35ca4da0fa81bab6143ee99a6853b097e8cd73971a8909568d4c82fc041c0e52f7d2f872cb7b039679bf6f5f6847d45b7a5531173bbd6f017e028acf3af38471011ee55123523d4006f84163023b6480180285b929a02c5acb3d73ff6f0f1be99ccbd253d0ddc450278c8ef7d3fd78c8542d72e4a02ea2fa9a7b345dacdabf2cb08e7ecbbaffe3a08dfea3476666c2feef235c780c5f5a22b75d82898bf285c4d625861a133c13f1e02b4a333cb28bd600ded284d9612bf9c1d06efbf9f15e402844f6b9882f650c6fb1622b8ec2a3be1e490aeaa5d04e1c821b890ca7cc53ad04070d05f0c684ef98de55db7c17df56840da94619a3630c9697ab7442976b849854a72ba981316914fbd4b2d9bb8095bc9843fb4d8dc1e3884cbb25aa7777ef6fff6e1ce64f76faf8dc82e3362329080fa735746d925b4836c3a624d614804abfbf1a63b9b0aa0f1790bbab35a7832f2b40c8af0f243068ff606cea94c356f15221143b199eb0a5c220d53cdced82d01327918d5517cdd999a0bf62986a68040dae60f74062ef3dd6b39eab222f87e622b1ce17c88a2e2468b293c89c6f4c1a3cebbf86c8fa38b72e292ce269b423fb4e428801962447d159dc9d45b0a05a2d88ab95a65e75e25c1f2368b471b7af0c84126e011fb13ba7c7c960afd7f6cfb42898080a97a3717552a0de6a081dc667de14d917dfc342fa1ef84f69f1b511906d7d015d092ae2e6edfee1690f43d0fad9f0cac4057de273065b4b9fe8e9fa273338184a1e82c3327cada5e017c2d8246096e6646029881f75e668f96348d4f9e66113b4bdb94339ae6b28fb2d04e83a00a61b13f3ceb2bf2f1e682896783f8ab60f4c5ea27ec577fde9dcd08f32d1295d09850095ba996036e12a242a304a8f184c0391107df03b5ee872c7cde7cdedc397ab7af2f159e0b3f6c814f1a3a419ebff91926df5ef262d002a80de56d6a6c3da3d486c29f544fe418c7bf1e9260bce95ad934028725027661631dd238dc6f97dd33851d5c68a4eba0596ba07b09967daf43371a2b5bfe075a2c1a63fe4741a02a270fc2f0b3f22e8690f79799fae207cafe30228b618c78b8b2b87c9f5aabe27751c4e0041dea874396f702e6f7599b2a95341da543a8e095d8b970fba9209330b69db16c4b25e8bb48243a6ffd50147ba3a352568c2c497e69b6858cd2779a280309f6bb16b23b8e4cc93a28416cf9579f604e5cc3bc2fb8e061602cf970f425eb5f1442d1c8cd285f7a43c1d0003feaba7a6b396e2f442116b19d57ad48231d1fc7d8f478b9878f45e0f20aab0170104b175e41a69e7efac606373329abeddb8792c7022c78fae4220afe27d5f6114ea84a3d9651a8bed1c2c3ff352b5fd142bd39e0509b49331e2d66d968f82d681d111a6a55bcede7ddca5b9e84259c98ac468ced96983203634030136fd008e57292f6040054752783aef30904104296056502050a140214081218602b3d510e4783449b28d3abcdc38b0a25395fd32cb613e27ef9b4b72f08c743e226c26493e8c88974eaa18bb8db892d3edd37207152cdba873c97daed88ccaf604552a12ef8f4f6396a1473f0cddbcbd74843c5c1c6e77e2c6f1449c03fe9eaeaf281a06dc7b798a6d4f1322bf0ce219f535309eefaf841af560896a75ecd64e35db90b55a7f57163e5c4b39e1319ecf1cd3485f367413d2d3a8d854788d0374f343924bb6fe6074d23dc7a61b5315f6d5903bfa4c0d460264898ebb8f33f991f948c861d1410eab4dc3182e7beda78f805a39aac2057186c02632584e4a6f6896b4bbd2e5b5f88ba08b5ef6553a18cf06a22aeff21158aa126e53388fadb3ab4ce1a8eb30e17c6b17e6911993cb3c84cfbb38d95ba5e326365696871f718f0ba1426562f16a87b4e0a191fd2777abb60f40beea2915c28308ffe1d3ea1e6bac9ef91fd6c77037f7e623a7f93bba795bdba9bae992f1d426e4698ad4a9bf279122a2235e598d673157f5b172b7c8f87149c1eabf0bcb0b50c5bc28479d3a499ba8a92fdad17be18dfd388b6091c4001820d2e0709c2778430c7efaad2483008dab60d4c118e69f48f4b386f62cfcd3eb3c003590e542fd09d3d41be325ad91e8f7bdf7a5e1a45e6afe52de5c095cf6df491b1c80124e42ee4bb016fce16c42636892fae1befb1ffe5f4daa410e3eb618c12313696c3c5d140a9d0e895c2558e7082ff54d0c63b5a8cc1afd085d06f44d5759082ab7d75eeae1cb6214c94af0f1375e8302d18e7190162f039af3e014b2086863e24b672bc9c4070731b9af7d7cd8f859704c65b6f3ad8af0f33872c86ee1009815c6b125fd52524248eaebcb581650c9108313cff1735d8a2aaa01eed4f92c465b34b25e7e49ceacbf83dfbd0388aa97e4d3c253ac63ddb23868619f8312c086dec5e336eb53845a0598838d88a502703870a3f415f9a78284ff166df94adbf97cb1b67ea3bd80c1cfd6e92c4112e59060445670f949b7ca4bb45615ee27a8b4cc8aea86a1d408b01212bbc8e144a6682d3d7dcd69d5ddcad847d8c95e126e363c34fffec62fb4130a09aa0685cf7f91905d937bcdadb755c33da77aff7487c0b6f5d8397b6ee11b8f2d3ea36d7f8889d524534702fd877d526bf90645d6462cbdcc6be91d93f76f3d82f3fc8f7840b9292f8dc24507635e7d5ba43935993b25cd79b4ad28c83c2be41dd41a8f7f13f4273131bc5c9e30a6852b7181158a88bb60f6a8deff6d564438e87820acb86f4cb8e0e6e1cca4f6befa2667709d4881f422ad5331b8f40e22e2db8627f6aad6271b755c2e6bea2690c1fda4ade5041006f71fecd402e52aabbc905bad559e55f3f9fd2b6176ddf4b8274ac42482953ac150a1e74215110558334577fc1f0ac74560875224dd9785d10f76f8b8398af3753bca62008e5f9f04ae4b06699f3cf50bb75fdbf0795d789e78f5c10df14ac1384494b9d94e004646d558b168cd6019496dcc7480ac2eed6d5b92b3c2329cb0572b48026f931ac4d4e08987e5a54d45abd290b4259211bb55d49ffff5e87a51077324704346236b248834f5a2c0f6965b8b1131caf897a8a904f859f0dd23070224244513074b2e074fa2de959307001451d656138427976316a88974b9c2eda9188149885fee6910ffd97bf1f0c8a8385c8663e6d4da15e982937a8fbbfd233a69f8e0a417276c74a8d6f4e5cbf9cfebcb14d0a568f5e259bee62df596dfc69f589fa2b9a8e2d842f233a5c08c801360f3ce1359be03eed8a02f9ef758bf67b55f38443ba2cf14dc7928c3c69a78f23ff0950bd17e3ae8e2ddf6dc93970e386cd18daa568af8bfaf70fe9fed1933709effbcb160a7eddbc2714303c0a68919ffe9d1fd493c92d9c859f5dcefe593f6998025fd266e29ff35be44d60efdf99c1191bc359afa7971cad921b0ffb6e54692f3873b2435328e514d010cbf7c650eedcde2bd00d7b8e356003568254a491814b0eb27d8675d50014f42f2cd96b70c3e7c263c822129edf47eba8c89c168d9f4f86117daa4472d03bfce0fdc442f2b7ef774a9133263d1a64c09f5e83ba4699371b688f36e9408ae6e36b7a6a3f7f314b698671096e04b0a75b4f7612a285b7dfde47a9d27a6315af417263b47f3fc05f352ee99304a06b89f6b145ff141893d226d7f21e4b7a122c7a3843cc281840936752d03c8dd8e450fd80cf75493622a7eff1c005a38c7f58deec43eb4a19dc7f7e6dff7413dfa34f7fa257965738e242273c3c7d04cfa52f7af04813e81c667f44af121d53fd528c7f40f52f17784e522f8033b1426b1d665b902b71afc6d536330a1f50a9f3a3e473dc6fa1ff14ef06795f74a27cd442525d18276437e73d48caeb6c4621aaf87fbdf13fea84d2e42bef444402d6c813d666cad790efca3ab9c2e42da6ad407a3245fe0260dc47e8950428a5320f8cc552f0ec8a9ad62c988dad1750a1b3fda05bba493f2f4feed8c5e8b62b013c582b9af0ff57be9b7f0dabe95e2544373cf41fc26bca148c04f10953169d9a02190440c6575713e193c51a79841cf39a1d8af152e796e9f1cd03dedf218bd61d2d46952a49d8392e05bdb38eeb44a65aaf68f6f1180ff7a5b97880cd1cb125af9f243acac686c301ca5c6ea66ad337742e37e841802633743157e24a45d98617b0a7b81e1c422b23dce7b70f8b22ce1eb6c30d72752f6abb1cd60373ce733dc29e9c1eb49db8c2cd650dcf65474ac6a513b50ae726747355daa1499c0a046b6137c6242eea2082f48cd1b0603e862b1324dd3faf21fdb5bcb6350fdfa15f0b6c7250ac1fe7c25181b97ca825405d4e6a804e184c2b552d69f9bee5cd3ff9522f2afc54c21e080f857f7a29c9eab221eb7cb2bb05a3f21fc50fff833ddf79ce874bc04931131c81c6f44c32de2aebf6286165f6e718e37c5f838ceeed2d2bdba1fc9ac8158d26b8d7baddf65506b2fef7b02760e80a593a21d47bb61b8d9ee322a17b726dc6864622d580103c73593be8de100ef34f21391b755b4a97db804bfa105b94d257f6d74fc4b013ddf5817cfd32a6d33c5bd278cfd51df0f7a52db8add2a15385575c1ccca48e6c2eb5ba0b6a6c1d8daed1dfba21900e6ee08d871124779403884fca6f246289d876cbcb6f4f280af58e09081faa0001e0405206fc83241b939331a3799e68fb9d0ce7145142a8bfdd25d7cf885430fec27ffff13e2cde999493c3881aed36f51b3da32fd43842c0dac1edd422c5f8b681519eba2bb579af57bdbb1e27ae4150734fc9a5ffdaad5431ac65ee829cbfed3e5ee438dbd7521f39c40306a91bfcb05f8685f3b6c709238ba5b2fc6a4375b796dbf14ccfeab8ac8d26d16622097fecfd2095e559e9a34744e107ed7812824fc60b63c4b42016a1ec9f07737439f77c56a2527dbbcc2a44677bcd4a1d4de31358d2db9011cc40ce2c8b85f65ebff8782014e9c03f510d3c7546bf492f824ae6e4f7ceacabc37d21191ba35577bfa75f9134cb6cf794ce935b0f34f2c0359dd715c748f47e112b0ff717b962dda87b772c0aa127ed26e09cf5d2f7d3be13184cd41c5081e5419b911ae1962e2a1a064ca9730108804ff589316a87f87d20f7c230d59127a098a9288271daec91a1a97a554a988222ca2f6a5e28aba75f29ad184079b18cfa2c6f31791b0b41806d4924d6eaed04a9392a5ee62793b3fd914d7593a2cbca211e9df7d0edf33938387beeaf792fc50c9bd55f2ab76dcbb8e2d10388b8b1b142d574d94898be87395fcb5ab279b957c4cc15c040b6394f7ff6b826d93f29eb2a6ef485a09c34db1735eeb3039ab977243f2e43756b34929a87ff1294d26f056391195b35857442180ab3281f27ce4f113633e15372c62eb529434e600bea8a45fc64baf66c880408a90b310edf480261f6b272deea46f2dbd58b835c74043d9d6abd4c046e9690387ee07eaf52ca4c2b969a00e7f167f8875ae148ed54fa1a6145d2e33a6b148ef99fb0c84543b6af799ec6a185a6bce7813a96a6343a50120db79302803fc619043df0415e76c39c625cc1f33bcdab9739e597ee9f33b8a60449d24ab5651c9d0d037ad2978f51cbcbec0edac8ac91bf33f0c56f29ed9111ddb889cfd9250d96bd1c170758b7d4ec00ffcda05316bea4465f52b22042dcae3c2f2d8a2b653068f82752af9a35815465445d983669fd004e3d3d2537e352a187bcc8d1485d1492cfb9c31e0933909e3dbd25af1737bafe5709cc24bc8bac00d7fdc917016def88fba9e17e30343d3ffeabfaa37f16c0cb5c596eeb294387a285bc566dd6465c011ec3eb2fc5f8d7874780aad952383fe2e58512979a77a16cc2e2caf8befa2d8dcadcc11861f95132b3bf7782f32a7eda4f919817304baded27d984d0a26cee3909a1f92c5257a26c5442cc9fdf5f6774ba17369414d3de5ee739f84bad0bf5fcb6353c27d21a5c4b36f6df733fc454bb19032dad9d17d57a5bb932c785dd5ebf43b12adb788e0c9b35f52992a85105a297fc49c53f8bfec1dc6c530460b8234863753a880c683a8a29046b538b0d966b181d2f233b4ed35c17a949f2810053ffa8abbba3e659fbb103dd545e7920d870f4ea7207fd0770a4fd81dcb71f165831a33063f3b0ef2259eaf76ed49fea652e8eb42ba2b76383b1a045ef30db795c1957330031b866953b3940597c3fac181fa40e707a69032684cc5558318d9dfbfa5c70127352c79030563e89929564a57046e42fcebaf4a35271b1a895721025ce2fb2f8a3b4c2ee1d954ff8138273a8668e256fc80b10d409b606e894fff7f0ea1ec7e286469a1a840b65c30f52dc4d72717e9d731d2f842e78bdef7dd22d911f44aeb15781d03e48935e940c638cd7c0abac9e749446a1b250479bb1e6cc81e5784e95ae129e49ae584a34bb1bdaa8a92051de5485f10a46da73132cf492fedd593e788267dafaf68e33976814fd61fa7e5eba3be0795cfda2c507f52aa8808272a4ffe5bf845d533a929986c6eaae4cced4bd4fbffadf438cc1b108ff8c61662408eb0b18d6a97c19683df93168a09c97d940154e96057de9f008e43c4b05cf3ea53978c83a80d88993d497d1bc8dcb23cb28486a1c62ad565440f83c138a14ac25936b77896cd9ca8458cff49157d154efa89b6f3a976e677afa9ced5823597051185e149688bdcea4efb75915972f1f9349a162ea965b8aecc11fe63060cd687fd8276baaf662f5cfeb94623f5d3bb2e67e50df39f4034ae7755c5ec10ed24dd4b4abeb7c66bfe7ce63dbffb2ad7caef13e7b1cd50ba51c5db9b235043e12018dcfc41d10c98bafbc6adc1f0506df50e7dbea85aec6c26cce568dbc3062acfd42f9ab0f3157763d4fe770d0f66a3e01f0a02047ebb9c7ea6bd0b2f317cab2ae7cf2075132525a3b6c1ba1a7e189328bebea8c85759f2ddc4db4961e7f4fcb22336dbbcd0af09e2e6da8c4c4ce202e2fc3087316eeb18fe5c2168f8e384b8316ba69774202d93924676acd9654278df298f6258df8f13ff33ca5d964b1ae5dcc40992582975791f5d861c0da48bef223644609246dd64e79552f47d7568f55bd22701ab166f604823b1682a7e1a0ac35efe0cfd34cfaf48773c915ce8487705b37f5d3d714f1c5066aea87dbaa963815fe7c8233a7b562afe4229de64d7def4532c74778e873bff0586dc66343e2ad3d795b970b3f337f26fd3d97095eb1091e13c99df47135ad179b99ea06e1903781f17dd90bfe47a237dda3fdea67e4b6496ff13c3379ca61d9da0a505437d7d6a9bd4cd6cbbcc7528618d6dabd71a4024e7d664ed5742f7149428c22ffc521a1cea1a1ae479e445b230970b2a1f1ddd694d514154e6e413d855c46b201b02d9224fb0cc2a6df09d933b1cd69ec397724185180eef0f1d96e2d46c8c6eb222040b05ca970746387a9e28f38540515adcd81351cc075c83f6b3d9dc2dcbcf936d82f4b57e25e3a5fd4657669596ad37d0c55e415899ab82937f0a17a66d9c7203dcce187e8cfcae093522a7e0d6130ffa41b5578a7f1cc67eb0cf97472d3ef270828401e29e068bef4ab0e374fc76dd2e3133a87222c882db66e366388eb0ec040554e42262535c806af8b52ef06efd7704d6fe7f265986510805a6906003b3bffc92ef1b45cfe383b46327fd474bad3f85fc682f9de0be9da17ecab8269f729421f8f12fdf3fb0375e9adf5a000dc6da4eefcf828079a8c6a387e46445a8c857a75acdcc0b5b23841a0ecd73ad624c36ba9f1c06aec81f8e7e82c7132658100173e223b37447ae217bcf0c10bfbd963a8a3114878d413774fb11078600e4f13d14aa0255ec6b88dff4173d47fadaaef467ed95f592ff077e6c9564355f3d8e8b152e75cd9fc8f0627702ec26666f6a33f9d40f5408114b73a204b766374efb04e91fc476b079c78af8b5abe97d581858114853c9e55d5d4fdd4084f563b20ee7d86ecac0e3b5b9c56bf7de0ee720c4baa61e3d125ef16ec775de3afbe15d1afa7a704644747312155636170df0c0e86052de752e1240177d47894cb6379606199acd8ca2df71fa5d889804187f5b2f624f1e43d7e456efd91de7bfbf34d86c97470f6adbc7c2b412560400575738631f886c260e01fe321259ee37366e563fda994f6b3b87dc9ef9b380a790b50a4014296906080a5d2eee3a9203db17a39532fb65f8c9d0031973c97770186f551540725553d3056600a80697c3c27f5b5a7790fa5bcf1438b10e8a8fb07a3ee773e52836a61a0ae58a85db8419cdef6bdf93e0764f56ce56e6ed60c0c1115ab9e5520f3aa0285a65662ff18fdf411e08c835c58c726b1c2cc7f3c1fba8dc5f71f7e6c63571289836dbdc76989525fdbd1961ae6996b6dea62ee2b30d3ca6c81854f447a4de0d2ec1e9cffee96456b7b489c42fa7f9993578a57192c7215d7e70fdbda295c2ffc3f68fabb3b2ac0ccc4d6be3c818815300faef55cce4edd8091b616aed0febaaf98d9f38a90c625887dabb136a99cb7ff9286c08fae8a5124d5af37b6f9780d7fc8a6b7f145a04ac5ddfdb8dbe63b05cff0e0639c7d098fa82a7f2d34cb6b46f24e0d9769a55dc63c0d60ee84d8fb47f208e7da88adeced6697db235a6ecad49a203add6cff1104a9dcd2513d473fe2ba4c323d77c1cdb5d851a3e0c4b7ce8abdcc78f27f1bf21813fc3b74caf15977c669de777b8006c97dca03f31fd0b1c45944aaa0f3a68dd6f84337b2f12ca81966387d75c70bb08037beb1dd65179f7e58c190eed015aa07133c5f021f043d107a7ce19c000cf0882fd5bc9ccb6a8d62bf8a73fc3f434bec38d7f5c0cba2d9ad9d4ca8b058e02a259898fce1c515f31b28d29810cb07015bd2e59c3419e7c03a5e1268d28f6829e29c807a9726312998b23ec901d91e666a44d05561feffd7d1f6b0d4285d96c0df8dc8456f0045ff130a9da13194c582b3eeb87807f13917af47c39328d8d362963b8a7d59f80c5fb9d9bf4d56395daff0da512b0333c2dd31aa12fc7d38c8dbe23aeb9c738f59a875185f4952b3d161ef718a76d40ada10c679d8903bbb9164195a3758ddebbdba7fc294efbe3a5e9aeebb9460ea709ae7e57b8c92de5eb78cd3de8662240f705e24672ada1577ef01d365b7dfd6d18fe6cbeac5f5472e4b9a52aa25c87b6139c1c70bb9cc151598f2b4f141cec4baa082aa5cfe6c96878043274bd545be239008b938a4b2c90ba65902df19e7d2a5d960bfb40065e538243592d381c3f3400bb5588c438c9b20a126f2efe2c626ecd6c18d32fed424938d5d9e34ded5a0eb51ab2f461acd537230afcf1159d9916c57208569e81870abf29ebfded27876b0f47f2ba02f3fe11f18145be88e7197725638d69de1076f7d7ace890b878b377524dc1857d2d132373de9679193adf1041f9d9b1e1e0d52d04538886aaed20469fc15dce7cf54f5a8e8ec0f928398704d7d57f4dbcf5e8fe70d1780e0bdc7f30b277b2b112ade9c362176b440af762e2291ebc84a9ad95654120a69fdfdf2489a219c9858caf20df0a41b93520c8b89d054014909a90a0c5691692a9da626caabb40df23d00c10abe9bf2d8feb8c03eab0db35344b2e0ce6909b56c451d07512557428b9ebecd706c966073ab5624747098e88dadce7dbd365d383dd70b2967707f26f11d5bc6d5a569c80995e1a605292648b3468c49b3bb3a2b9177f586de9b0fa65b0b161fffec389f1e2ef5957472cb0cc0fb2f18a52a04de2f58fc71fde3d0a365db0f37d63c19676eced3a1c9b1c21ac60cbfc74d54c1d810092296ce1e39d639a14974ad9206f3266761a1d9dadfddf61dd83f61aeed244ff500850465f5f5041968c093dac42deaf3698661498140355279a9912829e458c6013f596a1bfdf738c50785184e81df220e0190d8cdb403c22e04d0765578aebe476f70943421ba459838b12d378cf68d7e8564b898f0d1e3cd2899c04ba51c26c5337ddb5ce100164add7f116568cad50a1af4d1b9ae079ef28354f15c873694bd904603aee7787c23128ea9c393b3a97ff0e8fe1a884b0501f56867484cd0aa150ab0423253ebdf2b1b9741f20c18d3aed7207fb2e4938989592da120e8a031362da843571cbedcf9ad36ebff462357776991c92ccf263d01f3cc12ab96534fd215817effbd0932fd4eed4b201bfb9778c1ac276122e539a2f2d43420292f5e0d6fcd05bafd722bbfe6399deef16c822697b03a786800207a5a018b80a2b4545400e2882a69bb642ada6132bf8b37d411b74d323db15ed7965c95be99cbf4718b0847a9eafc3f9cb35ae331d0cac1bb004bab5be04b105b9d9604a7aabf15dbff456fa575b74399a2822cbf302ea5798e0a58f44ac93c20cdc3c41b020097919ebf4c3c81191f275a90b64dd0b41abdae4fa51c3967b683cca4cc0401a7f497722d44acd2fa447925c9dbfe62db341e9980a8c3f394f70451f37d09959588155b63bfec1eac7b6911425c9a984b366a199040e024425ffb7a8b347b6f8a49ffccc8e2c5eb0a55af9aef89991cfb5da90078657a836331d7c4e07038fac9ffd73d8c4d5998cf249cf9aaa999ce21b1f57f21634da10e706c598bcc6c16d5e7af5b70fae8a8dcd39e3ac9b6d19ecd37c1b7ead6c21a942e872f9c09f072140fbfae527ef982e331aeccaf4224ad0ac6b518bc69e07c93856d6b205d531d243987fcc09a2a8407cd116f5e1a46d5564d07e3543cc80108e6c9fff753c5802c76d7934ef59f1e0ed94882886c980a0e8e8ffd14b9f0e1181edd7df6dd1dda78565e44ea64d9e73c3545286a2816a839d06f85010c5393991a1be1f2c54b81b21dea50b545965087ee246f826af79959ef06f5700cbaaa7535ac47027232419fa590b05f5ffdf92cdedbcb324b44ffd9948de7d249329dad50c42998f6a08a9f83fd267011a97f6500ec95c543dff42a13d5c8f3d7b05105778cc6186b52df6317952db5ee0b6fa23bd756bc6f177382070a7459338fd08ddda4cda8fdfc0673e2df8212bb033e4fa8bd2562476b8443bdb22ae833a098b827d72db4c5ad90c5fdb280415f21eb16bf951d1406dd81a19ea70c1f656a93db1e48df382857998dd1f27c6768fb97e9bdb896258e2371f6e8cf093cffcd2c41a094fcb4932da7c3e61410d0deed86724a55cb522c852d23b3cf7b4a12e985f307a187240eec1d7655b17d6f90f80cbb66b56f4932df6403bc71bd9c481508b6218f9e9179306532ff483c5fc16f1b5e93c443fceee85baf5ecb1eda89fa3f3251705438e7946a1990d6eb35e6b554510e90a7e621423484239b54bf82f47a1e112090860b96838feb707e77f271fd455e53fe948ec698175597cd940ab6e7a0b2f8b1fab893fe892d6b83df001be8254a38086343956b63467220d31596859b6e5a27daa2d648ba4b8b4f613641701b626a7be7ef77561240e79dcc09c626add25a9622f3a8aba227c565edd0d445c6297b27565ab2b91b5ee98e8bfd062bb1d04526d1c22610ddc19fe6712f385c12640ba3eae5ab4f59d35f86578b51a7c7956a7d7f93f2b9d9f8e9ec2448b97838aa9139a44a596133b216d664b14ea75de30fd50b65c96823f9f0c8004bda28b636a98bbf785e36d5f5ae4085226bbf3ca1027fa69b0d6574fa7eaa08ff4b29c4f7224a0dfbf05cbfaa61d485da4ca3e1d79c111adadf2dafd1a6c379df0502fe08f7b6cc32d12771ae82fdf75a690f33b3a4bfcf884ec46018b79a80130bdc3b71b35123046113b63554d77b91c631c4afcb5489fa03b4e713c992a6df8f5f6ffca884f377ffea970503fd813907a36e0c2470bfa172b82d75c017ebed4d2924f505118059fd01ba45ac167d1e80bb46ce1358f1f92f06e8d5c3870f003066eb9e3f618e4c022b7ab23d65546c8737d873d894d7d0e013d38de9b3fa7863fe2893e0565c00068d3ee60b4ea9d6b827477dd4a0f226dafc3d641020480d77b3b712de79d2567188dfe284d0587c35b59887a7d66f89ca365000cb88f5b9757fe2b5f248b9be56839bb3ecd48703d7e262134f39c57d5914b94e10dfcec08d73b2418d6b055666e4b52bab54a173fb057aaadfd908cb84c835df2bc09e2e69e0db92f0fdd176a41da0c892a9279a6f1192c4041d32bfcff82ea0e18a486e067377819770dda10006ffbb511f840ac44ceff63d982564683a46fdfc65c3ac85e2f110099bbbc41fd655ee1d5d46cc723a598ad00f04cd139822953b899fcf3e85349cbdecc01b9df16ba3a3df16fea7ac3583756be7f46c9dae825772f53fdd386041646d15132b8430ac47d453f713f4c808110503bf083408dfcf7734883224120e51aaee3a30d46019f7fc42f902293a2e9663a2e97d1bf5aea96e1a75cb4f78d8af26c5b6a4fbc8803b4e938e1b2da747187de23707c98e2c4b37d2af1d64508533b3fd6be51377bfe0301d8cfd4646a82c21f1617340aa6def3fce464934a4df831fc40c976c6fbadc6b12f69be9f9032ca23ddaa47fdb5c02af290488fc47b3ce78fc3b191f4d42491a4179e2d6f503e3fd7d214a000abfadca78c9014c9c1a2ed8e572b9a4182098d7e1a246b794dfb9fd6306acf54f503f639aa9f80516b0c35d91a20aea1f974fd33c5eaadb7dcb07bc2e222514657f6ecf53ffd3b3fc27ee7400e1d65b205722f8521664fba9686a86dd558203ffaaca040c9e8e0a0c64e1101e1358f8ed4860e02c01d1982f023d1c09128dc1525f781deeaed161e06293e11bd0d881dd9d870081a57c630754627f4ae27027926fdcb4898a03404ceabebc105b3e2c6f0f37a9951bd6651eac781f9fd7359739d748dc38f3ae76be80c42b266375849faf8a529c6735d1b0c5dc63a178904be72e8d725f9c0bfec330ff7fbf9e6ece50e9f2c99e6a809ad0d30cee1c3d1590358f62887d6f36581c51139e6d6daad1de42c03aa97bcb05c678fa279ce88dd3f3ba1786e1204ee4148a5b8f3c98d4d9c7b8683f0aa826145bad4145e439f7d0c3cfde87fa1a78d783374ac833b4a7039d48621304120bc0ec0399ad005f8961104fcd7a951c3f0cf281608f111a871821af2fcffcc2120054bc8db3f6fbdc35fc7b31027088837658dff0a4479ab573483761a5c460d47007c2ab859e936052dae00af90d79d527bb1d820141a12844a43fdff558a92e717f1ba64ae080c9f4133aa41dc0dbe490ea197f3d57006152091d9a126b7bdc31806ac4997b9866a55fb4c73bae89f058b3b1b480b0073ca252cec1fd5b53afd3fb1cf8b4482b434461054a56b99c82d2a28f37d480ecab8306880808b67e263a2bd79ebb2fd7851793778be508e5f2d399ef81396e330ad41e8516505cdd2ab48062ff0aa1ee4ad0756779352978551177f1ca85adc2787bdd168aedbf4c180e9687acd9f8a605494c584dc05b0418a20988d5c783c11a728e173c3355971929d4aa79204c48c4b8bdb3bc249e8148da65d922ee56a0e4e88fd23da7f6f707e0cbd262dd95c1cc923220329cd88554e3079bbcbc9a61c5fa66952ac9364d46e1bf5a6e20e439f81c18be69f198c563209ac1109ee777bd165b1088e593ea25b0e63de577e831edf87c65b0498ce6c4cc66a2de9bfdac911f1bcffe65daa68245f0cf8c78f0a89df36a2e8305dc7a43773c5a1bef80ebbe9e2bd9918fc0a460ec768730eefb391612eabf9cf9768daf608a69d418d384fdc2c72803b67a367440ec0eb3c579c3d1cdbff46f8f28f11143fe980567273fccb67b7ca8926da7b2ce0f662be278074dde2d192802a07c57170ec5c710fdb378852a0cbaba61d961b8a4217c5754cac8cfd927cff0d529b4b1c2c5d08f843c2c359ae425ca022937e9093dfce84c854e250e8c8b10efa21af63c33df78eb304376244d030e2ee2c2a205b3d667510542e1b2274d5f0f6a79a9b51827b0acfdcc28ad79a7108e559084b5f13ab6357df7eb602e1d19294322fbb6090dac544a44d19164f17c47da7d4c5337a1efb1009998aee3d7106802da43a1aab2a2016afefb34befda601301a30bf1b16cc7f921045fa5ebf4c0ecabd337293b2516078dace91577748bec985358eca5306fa9ad17c5bb20b793e7d48f68299b6e12bc4e692b9e5e308f908933f3e78c2d945622550c8f02ea84b844fcfb118fff025164747bb3e2b37c97428095a50d2965beee4252ec6da51010f4be3e5af4101052ea14a8672afc4f42956e8c6720e290b81df4db757c24a8ee9d5091086564bbb01fc9a06aa1662870a357e8cbdcae3ef5a0cd191ab4bb32007390ae47dc1767a4b80afb02c72cfc8acc77eca3c1669d039616046d03fb9f18b414c127197db0a56b7973eab3de4707074777cf045ba1760f9b849e5f4d5bbb97a67df061ffcfa45c762c8011e0b6df42b318bb8c59dd7ac48ba524ecdf3c62950089bf9e793999b8e390c99b89b448e3dec6f663bef336199ff25f432ad3d26b170c8001af3f06a9145abd0c8f1e94c4ef106ce3a5770586f69f0d089486b16624521c5900f19fe3f08fd6659f7519c1e30cc98d5da521a4a7e1f247546e7d880e0cda1459e344bd1123bfbfb563d73aa0f9c7c7e3268edd4482e5b4b53911e3a593e80155c92ef3933c157a0c85ffaedd3301bb20c65b4e707d5032d6ca53c9458ebeab8694e94668863fe5ad23388bd20853a51df245bbe6793b1788abe0b3a53ea311464ae13c01f5ba7c53e72b12370f3ec5c519b6984d4fb81ef0f57eae6a0d9e30fc7fb6ea77c9ff0b5a51332d8b025f388374e335801a19a9b60b220b600f34291aa4dc9754a9b0d4c717acef150d83b10a99407cb25dde1e823d629aab48d14ac66318b56ed6a499b6ad154644bca83e514998a8904feba5b0210bfae16a8e41f4c0594126b67213972604d80741996dc08a9d4a41909f1d99c66cd82fbb3861f1c7eb45c7e49401031efd8a391f0cda5d03e37622333390c7b4bfed4164c609f2acf2b7ed446619216b1522184e5319b5217249d8d0a42d397357c6369f470e9ce909859f48f5b7088796c18deba052321be0ee098e794e94ba6543e0f109fefe99589c55fbd98fa06120cd3ad8b5e0c5a7b423a70ca268e9246dc392f589e5eb4fa757653db0870417d64f0c921c92d9620457bc5039c84fbfda82cb216e160e2d27ae69955fca88aea4015020e241d5001860654ac4c13abaf037c6b2f04384e2a8b628ce48eadd48268f81378c9c85759bb0e0a2bf95e23b5f16794a5ff25a98bf495b6cf63fa8d3c6aa02c360ab348bf1677712e3e4fbe14408a647eb3c276766bd128ba39d375266c83d0d0455134e473b1b408df4afc54921f7acc194ea3e562862e668b9f5b1cc136a9f7a05c1566d88079a9a0a4190fb70d00c54fd29d11c398452e5c26bd3aa4516dfbbf1cd30e8b710f528a04a03a3401cd6c0ef3c4aa28cb5fb26a03eaf474358bb682789e744829ef7dbb9a6c738e5571d6388bf0ae1317905c6bb104c5abc236e0b5b61d3c79cc7d3feceba09b075b83ecf60fac4447d4a6d6ae312c1bcc492d5ee120f2687bd792eda44df816e403993a95d2685555d4ee4e8af1c043c3cd9e9ffda1b4a25651551a4e30a4107abb06b84c19f3678325c1c6670b71fd50d7964cd7b662ac56697a6a2ae211699a271bf1801313d39564cb6ac9dddd44589a6e55ea3aaf838b41da4d6cbf3a678c1ff0d0ecb9de03785c9891badf967c859fae3f71cdb51b55c346215f11e95f8f63e84dfea17da85f2b01a963694ee584a30df9a5cdc9464dcbb0b0c58db14fcf8968f247a90d3e602ea818c67360065b24eab175597258df3f8e5e94c0a5e48002ee394c0cd06bc9ecf0d002db4d77c4efb4ea2872653f6ae75f7a31b7ed783e2d4756eed96e3c4f1b80e06f40ed2341c66fbd70c648ec1b4b4fb228b6844a55ffa30e3ec4fb2d593191a6e9eff10aaf362e1ba2b50866e0a38d385cfd25e8f5481aa03a37f58f713fb021e9bb018324c75c2b2f63e2285e7a17c19acd68bae0aba2c7535ca78480523b805c9e4fbe24f3714637325bd162d0032de94586ffaeabd26162b01b5ee3f274969227ee4c8087070935d7157b0a171c96ddb1d7ff2c2f9c6444bcfdb2e424ef73462e8f831064bd5837e819df1187cdb8450898722692c8194ee5f29027d0e8d4fb6d36fc67e004a7791221e5e43b69cf95c7d983536c8f9f455c2c1694280d17502a3acbd02a38ecf26c518e7d3799b91b66c9d0b9606ca7c183bb97536feb293da1eacc854a3dfac22c7e39b6e9fbafff912a73f6269f4a528655234f5b7ab7db5866dbf27a27e5d1220a0a1ffa85b1e625edd41ef20d814a77c07cbfc5eeed7c1a05a1e3e981ff17ae04c2b83fe95935f0a15e1cc17f2a71ab2a29c8dfd59fe20f6da4e8096f4af850e5e732440a214934f8bcac85c9cf1df67ed93715406ebf75ae33823746750f156195a4833dcac7c659a6ff5643e1dd3f7dccbe8e711253b56a9e533852ac4cf7f38fc04b43e9d605620dad483446e56908f1b09e88a8e35e22483faa29e3685d480bd211168682a1bf4e0f7122be747661961f3c06916c35c7b7dba736732bbe76a97660500e2c5ed33c5d569e2b888a4dba77585ef62e536cfdf92473f6971c5d4f412df25ba314c0f5ae82879828f9cd27c2bab4c3343568f2c4a34a4827b5d498925a405f9e9bf32e68c653e7d411716605e71decb010f6a2943328a98a27816fde06496a7d2eebf4eb67029e4daae840a594b406aba3de667db73bab6ae89941eff9b616565bd3f33a7b82591df1c98726df64927982c4d8f42a0fbf01884e97e925adbb514672af858c5c52f8645841e8ae6ef97961a8fd743bb7e3d0e82b2c32b41968160a0d52fd63bdd6d7c6d3bce29fc7400a790448c3131ce2cee2ca6832bc5d07a240610bcfa3572ab93eb58752b62fad1e35a36240b1df3a33775bc8e0e82f771722f94f49406df5b88e71da542627aaca5d92e7735cdab456deb29a33ed9697534e7f3f900ee117e659491c2ac354264f3ab53f0ca61adb9f8c94acd0eb2ffcc20a0c28917ae102d64d119d69b8579d600d2c6db148f40278fd41636de3b331f696f0a9c527a9d77649739662ea06067b237e4de7d1a8b239f0c6efe702cc174e11309c3fa13dd1d2f2b6726fd954e9bd649ef5d5c08207d78c9cec2e0d8c3cc11a0711ce5c73b5cd81ded975a0b71972f9fddb8f8a04e608049ef65abd3a71752f0e304234316a03633ecb995ac5fb870b4a6a7d2b2779f9bff5ba46089ec8bb05c2297c748a90ec4ffd93751faba5912157e174a999a51f085863a1c8d599a4744b06f74e1a173b3baf36d2c43791759e04d659d30d6dafc939afda7415c690180dc061fb946885e2ccad12faa470b25309185e784eaffc965531c1df8df1afacd6023e7440840f75cd07c81e7a0dc8e0dcafa3b4da43ea6dd2c60c0fe1f80877721c07796b01d0c957f7328bc2cfbd4665afb14622f57aaa1d8b4b0c0e1483bf07a454cf4ff7a6e14239837687409642897bf648c0b810669fe7d616a9029f167c61feccf7deaef09ab59a879c7c19a2d8a53f58efb94f8913a11dcf6b14b1e9f4f8be2f3670feda944ea1ad2a820824e66f13c913eb5f53352934a66ac55f165d223017e40c70f951178e69c493279930761e943753c067013d7c23f786782fd148840187ae41745d21bc9f4f8a58a60990dab1e6aa267c477ec6987948e446f57542f05e5edaf22bd116493cf71e90e01439f0db80f75fcb25d9441e93aee9210af1a22ee7a956b0937ee3d01639d2fbb1493e21a36d8f84e12d2e01f2535713118e95002e81620ec3ed53dfdd36c321cd3c87cda220c7970ee6d338bf1d90486eac574f112ce5cc3d16fc394b99ad925439621d02356bf11d792532fa5b0e7215e6cd94a6e7455371fe30ab382aa50efb6369331498c549172783a37b2654111bb562eabedff474f271bdb5bbada24a44fb34ae03ac69524fcf643115b93709ae99825e5fac9659c4572950be5b38fb7e14105129dd041205aa7a2ba554949fcaab6cea522466dc5e22b994148b20d83219ff06f8689ef7c8b42e8db96fac8f0a4e6270ace65571e699ce4c0e27afa12b17c2a1fad1ccdf691c1b16b62baed4184a406fccc143cd3d64df8d611a859e509058f9eb0c6f4b962a4bd0e4d62b9566fa3e6ed94340fc09897d224831455d4f4298e651bfbf9ec0dce31c81339af53b22f4657bbff918832c53b4c9caec4a3e3012a0a159a9693a7890b9922f7b7cd0a6f04740f18acbf930f5c46b69334abed466af38f47668b9002ea5265fbb81186939e8f55cfa62d5d742577a0cb2d60819edebc542d40ad29fc12d4df5d1547803e0250b685dd436eeb383c718814def657fc8ff9f96a2ea446ba30596b3463e2c946a09ee269e096abb225a87d912fa96f5baa029347bb34edd70d05a923bbf54d2d67ebe0634a2263ea609bf4b1bf877db9d2bcad71327dc1578deef9c49c11db085dda2e6c31f99ffecbf1ac8b40c05c2f07bb7a68e07de967c5fbb451895435492f73a1ed6bbef2729f631ab21607e9f073860ff13b3cc82c96c35fc619ba1318b814fb12a3892c724260b7f51f5ba9dbd251577df2f336707e745fb42f98a4bbbc21d07121b57a8b842747f6a4373b4c51943de0c7ade0d91adbef653717ea91f90b72cd3aeeccb1f2503a891f772022b7b8b3efd1c7bb75493b5d37716fcd11ed679aae17a8e59ae9b67d738591c7ab2b4495a6c948187e9a65610846719de7ef43142b351fe6f8519a2a406350af5b902857e108beec1b821f17f364aef21bdc16bb1903324ea7bc19ee30f4dd1e4b5c2707b3c5c5cf1fc8a08f3b350c9f43367b3ffa731b42cab3fe6a4877372d47411c3f091f41d7bc7e138f1a6b68fd7b752894cae4c0f5c59a8140fbb68e0889a1fcc2bc250e55799687b0f6fe723c52c15c0cb4afb898b94cec2fb85ea99f0449705ab8450f9514fb2fe2b049e10667e5bad21e6d41f2d55eda5c974e58317144ca6951833b0b71453df1fecd4adab33ef15c06eed5a61f2a368c1e22464d9f542ab81305a2facd9e15e67718f6b2cf45299f9b417c4e7daa5fc09b07de4226733cfdbfb6d718f5d574f092607754bb7d7ecdd8ce9d4b8b5e6662bf9b87d2bd5a157423fd4678f0b67a6a5e3de32d6bb742ab1b787adb71dc0eeb6e8cb751aeb2f3ab1ffecded74eb40230dadb1f9fb938b58d68847a2f149d1c53e817a75d1801ff16c2321ae7e4b4657ed4b7101bf577befa8e996f8bd1fee92bd0c712f5b470de3eae04308311d27e0854f8e47cb9e58ccb0f611351ee7fdb0535a24f56748533089d10802224a2ccdd2cf216eb2458933be37d5b66c1a0c2c98b2b708d3965a56804bbbc10b2e705ca92531f7f64bbeb5773a7192997f33ef1766df2f291923b044a1850466afa4d912b92ac558eaf644ea49ef461250481efee268686fe4d21563c53df9fea723389271a521bc978cc36b06c4c047a5938d1420c688b8893e3e1fe5a9208d3ef1ca33665076ffc06596eec37fe9b65417bb807c40171317103f12d9d5f4a09281f03d603129f0461e4c52052c7183cd229388f9619ca44804a5c14f8219629024615de5c3d5bac51bf38e00404ef5fe843b0c6d71bd2f74a0891e9019313f31bbd099fcf3f18db5158f5e6ae47d2e55f74317885fc28fc9919b294f55c5c4e345bc8e2bfb134b68805a703480fbb369b5fe4a4efd62c14ff4343bab25a21224198f46c79c22db0006e628abc841c13807e885fe3fabec303d342a3833476c63851d13cdd83b142e0a83a4e526e718d4a4535fab89fd302e89e85f8bef6e3c66ea26ad5c049b950facc617fade63f02d5e94e5c9207f09776f6b350ab3b47b30a83f83ed77d2c498c44b519ae5e2d94a5d172fef7e7e982271a124fd6872105e24e270290de7f32d1f0ffc25aa57b1194e55a06fb89defbcd79f950633bf8712079255b9a3e7c34fd87e74861830dbb004bcf0e18f2ac7eaedc172336eadf18382062723927085cf5d3437d555e20a89d61a88f92916a6dad3b1a7844ad375af460278c9a8134dfa63274b286f61c4480a118822237084c90589c6ec10fe3d30e1636e8315ffd6286e927795bcc4e6391837939041486484ae478f9cab721e27d80d80b6e4176efda765e69f03c5e77de8ee4376b5ae29377f732441151252cc9bf42bd33c3c6b759ca622752d407aa61f28563c93614b11db839904d1a2cc387942e0624ab8c4bf3082ebc067d522e77509ec6274c5036ba4fd73ca28e553d329fa1405453b46c0ae750eb3ef7fbdcbbb4a03754d16ee272736e41f024e30da3f835abc1593afcc3bc11c027b8299a4d3dd8b6ed8f0fb78b86b932e9c0793f92495c77716b1cdfb057f86eb60e50864fd576ff3db999b735f0b29547ad8da067522972da6ab7364da64a79a26bfd5e9b9b5f39be4e0131733af4250641ecf2f131e80e65188c8e12eea6404b0dee0b52135b0e2f46394703a4947eeb9920208f94b3b31e391a459300abd34f78688f8341b4d7739552e41661bb9ce335f73d242815b3e1b567b1bc2015dbce086193a034ccc4bd547dbdbfe0a0574d8fbae7684765cec8cdc78452a496ae8d7b44b2b70b0323554077d880fda40861ff78c6f0a1109cf64eefcb86fd86fc8a8e8d922e1d08733aff91e91006dbadc57a5b10da2186e8a23f4bdbcbbe831103ec7cb342a4bee7046cf5765b72a6bffb9aea16ad6ad5ebc20924ddab833f3fc75573529c2f84f13476caf42ccb721013850c9181893db645747fa1b1b3c1523e0de87426d6422465ac2f0d3cc9454adcaeb88422aa5bebfffc19b3b6328d23e05efb519aacd2bbff4ad49eeadb2e71b449a3e85b4e48fdf842ecfb88d3e54dba617f02add7544625e7cf288b076f2ba03dc5b1d707a05e453b5a7e38b3d4b08625ff9ff930816e96be8fd9f84113d92c68b73636fde64e6c1fc41f65bf0b58860d5fa6b8dca282c4205c967a5a1b1cef7cbf5faa1fbd9d792e2208f891f8ef0c44c7947f0d49c55b254b4c3f9a76dd718faa7f2fe4a3237ecdcf8df1dee55ef4bee5cfcc9a98bba530a854bb63cc3295094a7719709eb2d0f155ea8b4650bdae1493e172ed05e6b481e7b441b6fa4ae637fbc7ea9bdfda41aae87cfe9c2c4fd1d4b7b6f4549dba87075a5cdaa20a34c49e7de63c530d321483cb971f1cde384575598a549f8ab41428b187425b7257bbbe9bfe5fbfac58ca046377daee97b756334f938421efe8167c25fe464de40fbe509046e42aa4a9614ec0711080b071090f5b978061f7bc08429c4ca3e35b480b89dc1b1c19659cd2a88ee336c1ca1466b25cb1a17eebc1f38902268bd2d8b819acaff50e450cf106dccddeb3afd212dbcd8548936dcda405f96f29f68f30c198bc1dd1c21e4a5b011fe0dda6516eaf0d2039a2c2db3f5cc21fd7585cd840f319e24512e17d15b811bd054ca64b3c1f34dbde99d7b2b638909f944fefd71cdf43de5cbf13cd636fae8fe46afdff2a5112005abf8ed412ddc7f6e188b62967caca35623001d705964811b4c02f143f5dca9ef50ce7d9d947af863efb34a92adc5f3d020122cfde23b6458b9490c83aa63158ff6817e620a2865c9b33fbfecf0519b07db612c562e2f05123e083dc17fc478eb9d9b295e6c06ac19e496bb15a0f99e6e6bac3dfa2b216837a3c51de92b1a7e13e7213c4d42f6374979a655d491ab45b44592ec19bad069a591657a40aea095b745c0d8646a3ae876c7a17cfbef04a372c5fde5c7d2cf02c8a2d00b8c7502f5c67af3e9e3aa71e9e86bd9ac52138acf7b419c5fea93d72157cd41de8ef8c61ffa6b4cdbcbb000c7b44dcfe46bc2057e113b670d667ef18839610801a7f382516624852b0b1719e92de5ba6447b3b43b6a2894e561fd80b18508a1f2bbbe59ac9f957079dd3a9d614bb06ace8fa2623ed4c263ff75c51fba3beb68479ecda18747469038f3535c5e193178bf35785e794adf098a68d821f19766f112494be5126490db3e919061e78ff522535cfcbb37d4e41239348b1ef8900352595a58316fca7445817cd756f2c26816485d4c13ef3a16ac80667579cca9ef4defdbdc99fa8ddc8e59a0410e2bfd839d90f540fbb5bd6b987427144df257244a704c8f027d6f1822af5916b63b76d41867c7e0750b75a1f6d728c3b276723daa5416056827dd699bab7b3c5b096bc98789c7f1785e8d39e11b7fa45c2fca10609a43b89fa8c96a123e91788ad35ccd8204b3d0d4091361e51b60726d9df6fbd7243f6fb1da2a41c9ac7c3d09644e9edf1b16972db7a49528a17cadf900b08354b3b18aa662f1fa3ebbf42209b60365b33a6bbe7eb0ec6576182ff46c426f18344d0b6748ad8ccf96d71e070c59538b79be3752a21162ad5a0646ad1f6fa224d1d9024831d15b31d6f6a835305edd9fd1b3b03873303ecd78dd8fa897a1ea3735acafe303142b3cfa9602b6663bd83e689720e1dea00fbe91e5d7f604ed0b4ed07ea2fcd4d435ee8e8f358309d3f121c0511a5648687c44e707af2ef0735d9f2f95d762440fea6e9dba9d356b430cb6d21c3e9be05f755e249e9e4b524933b80bfe0ebee26d414c8a1a9e603068010775cf3d417f652004bfa10b23e52b2574752150c2fa1dbc3afa6473030eb196ff9fc0b3358a18425504e46331e10a824fe88052cd05be669f0c81db798a5ff62a6a88eec876d4d0a66687344deac943c33cbf51d896d80fe718bc0e9ec586f412b834934ae429cafaf22a94f3dfcc9c47f735a93b93ec51dc45e3600893bf5647399af1bf39f3d0829f4bbf5f1b224f50137348e00d4500dbe818de33916d11e5b348ebcc358307ef217b9bdd7e0a5cb32e9359dda784ad806893d74efc6f6551288f00c4d9cf0d0722f378ed309daa6b72f504c57eabb773ddbf8b91e541bfed85177969ad90a1408dfae0f41585e27de3d71bf53ecd1415b5abce850a5ea6be58f6b59abc6f382920893a714943b957e283fb584b1cd459fe3047c7bb9c2bf4e7c46c14b5a7e3c8ed40a57bef0ccd21f7d4bb69d27431926c97678dfd17ae4b9a5324529edfe9524e65d97c270d5ad53f0598ed68995a2ecf0cc3ddd8d440af67b42619dcd01cc1bc441d3ebe1b3d7a09d989c00cafa06ecc4cdffe14855c4a53f95ae927a222c7f1f94e87f4ab5fd6bf6addf8a6bc0acf117afa18d1e214d13da12754b62fdf2a850099a3c706dcfcb99494b1d13f3ef412b13f6015954c97b32eb40cb42dc93b678c4e05d581e84553c03889847cc57ba8538dff333a71204036743be2bae5d6133b6c0a3117b683c917f5c41cf549afd6be7820f50d84f4e81911e81e92f8f079466af689066ad893d8571429c51ba2ab7a9687bcb4322916aa9080828e2f19b97432f418d25f00fc1a210834870e487f94c36d54e15b3907a91f3c1205f569822ee173b9ca08fe3c9ff864bad88b79f15c09283d99263ebe742d818c8ca8a4492cd78f703bc3b9837f78c827664d1bca283f0b15bf878d72d3b3496d6d4da37e7f13d4c4ee0c04e6de6c58685d75ddb89c61a7be8b06ffcf0ebd146677e312a73faaaba4c52ec74182a6085e7f5ad6797f1cb45f2fcc241f5bb1fe8a5dcd6856179e9723a236320efdb27f782bf443f0a39fe1e8b5b7a4d6919f3f2b6c9ad739e40cda91cab7fc6dda28d070099edda84c9a67ea4272bcfbfd9e8ec1105e31a2beffb0e44e0d1ed126d49f17b4ffd21b2a9b8f76ca6e6d7464a01953fbcb70123c199befccade27f231d58d833751d2872876597bcc22bd38fb0a218f477aaa47c48964b4f3e81ae59b0643372224cfe9924f7c61d27d5c8740ffed137f458f362a966f96c47e4afb1a1a34447e400718d00a42b3466577c112067fa461d2c4e0dec8793a4cc43e37ab5bee20916b36f9392f8f78f7781f9fa349c6200045422a2b3911d6505a1dff5c58256d2ede97d0924d9b8fb97eee89b2a31d3f057e1dc8847f3bb832f50dcee7d350a6ac217ce937f8eed8e9a12d8ba29c0cec103573a0a1add308e03b5ebaafe9b279868fc2208986655a777c1df8ccde2c1c880428a76288203b9b928b0bb98a407e460e8005801a82afd717253450da77592c60c9f8f5b5f9733bc5bbe47117ea065ddf28722e0bfa6742b96dfe398f0b95c1f84ebafc4150803b2fe3051d9438103d2a0ea06ab13de73c1998aa844b85f290553380cca1c680cc6ebe8e03003fa9fb9d1ee229d721c515bfac52a160cdc87d35906772256219fd2fb80d386ea183ba8c9e34cb1bc780bb7c6ffec63ca823c198735be64f5f81b42eb47c91031dfcb002d2f377e7d6786246b725888abd1214bf7b68398e9f5ba5c0a985caaea902aeed5ff1325294c57fdf575310789e20994efdb012e7e59ab52c988c902d17cd56ad27d5afd65ee9fd4bfa3386b606b39ed8c5e88abe430913e6f826682e00b66d872df12533e8092c8f7870c344852d445f5880e75ef569a1d7c4e59827e7513a5740bf30bdaca59d23474b9da3f7689483d601dbd40e4a1ca243f33685a69c325bb6868061e9e44e4a83f9ed2467f6cb1d82df11c360823db417cff46894408675a06eac803240f19e434d32510367f1ced61975c16f0dde1beb22bc030b8b64fd7686bc2bbf48e7ff48ccc14cc74f9d34912fe39f523bacc4397af79558fd0e83ff5a34ce827720cb88f6bfd45199a6fb7f9291b8f3dc8f447232cc3bad2531f61aaddc5b3815756495c461da0e8bdac6e6212b91686ff1e11e1893ea7d63223c180bbd214f5af4586bf88ad33fc47d5cc6b7c9a93e5350006b4fd91e7cbc7e8e3fcda44d684a3ef777f450baa49385d171ced49b2afe2f96a051883ca31d7b879d99fb1c49aa65e4ff733c376d438d143d4ea4564fb3dd97fdf8ec12799538e93ddc65e3a164781fda439e2471b300819a73b3ced73b482da6b043c43ce4b61e3e946eb55fc047a35fea6363e31cbf640253491a11ba3004958c2d509190181dc3b74cd73958ef15fa7a3f374af560bbb43d5c41e50ad426eefa8aa94ed1780a52f7a1814b676acf4342cb16be432f8be38df1d6ecb5deacb44f7b23f9498dba81555b55cd3afcdc64fce02bd0defdf658f068f26de766382a01a6cbf4a622b0eb48f66b5d0829c8b35e8816c61ac6b0253d3aa4c2cd363f6bb21a41c2b628a6a9e6f79821ae50031c65244b91e7ab06fea054efed5a4f5566b4e79ba5104d393c9ddb8cb3505cf186b4db3282c3439816e28c157c37d89c81511e6430cacb8fe4fb1e37b96fd050b607364a7105cc875ee25e8d20a5a6fa18085a982d8d5c3635d6adf2722ba4c43a518ae3b70997752f78e99d59690f43ccd500890b3cc0e4a30d97dcf5e7ceb12deb0dd74ce993dc159798b4f9f0c070e0ac64da6d323e0a41985ca039b4f0ffd80881b58659af39261d5bdca4216f6236cc397c45f29a2897e9aad9e457e85faa99d68aac8bc49563b3b48f351cbea60b0f0cdc7a3ead4917e2e81215feedd5e0ae1b2f2ce32489a8450ae71e2bf678a5ac00582ee958871ff4ad7f08db386abb26f29bb1fcc74f1e89c81976469dda9d36b346d0e69d4419135e4d271e926ecdf5517953782c3b3b7d72af8dc1532c707d3ec72466555d782e2d82cc5a7bc540810907677b50329ccca0d899c79180a5dff159dc96a6afca73d4396a910661971f095f09f210f7c6ad40c6938da1da24ae764487d438ff64891589653332f6860c19a44d28ac239ee388a814f6b910f9f872cd55d8a1943bcc3066cedbcec1d3015156a1eee8f5b6654e89634eda42a031a505004ff2ca680082af004ef810feaf00ccd2029e390e095a50138c7d5963f43060a3c0170f3baf28956c959de577ab534247cd8ab2d2781df89a90b9d6dc893d88ee5ed6d1f43a9b6792bdffe300604f42d990074fda5d239015a43538d365eb0f46f6d6abf2db855ed7e3252dc7f47cec211135d2d4923cd83ba3047f618d8011aa4b0cd1f4d93cb6e3f0c635cefb95d073c14054c5458fbcbfbb48f69c8a1e09682cc00346ca7a6beffa92255fdd664ba9150f6757081f30fb47915fa7230f3ef51617fc3a059f093057260afcc14223955f0fb8dd7b46d058d0b741047f877523842a1e315ff98e32e85f863f231c473fd19a728867b5f8c336e7e2ce154832e6971803fa511046a04d02765709c73dade5998367632d43ba4f103eb114da5a5c6807ef7df67d69f32b1ad05763a14c3b7eefdcc95a656b8fc8d0b9018f746021aaca369c8eca8e174b0f27cd5969dd849e348559d424ffd47367b69b0837798d1466ed0445720f95c7e3a6189cec431711d72f9ffeca9341f0485b0876d61c637a2cf6a44811cd00a1b58c962471cfa3ae536b6da20f822a9f53d799cd8c917b47bf4b734ac76b4134ca415bd79eb9b2778a7f67d99e674189ea7708ba9dda614434772d6f8d94e647a03312097a64f986c45a3ebed59b5218623c0efd784b343ef5da9622fbf32d80d7c2882dd0815407025129dcdd9b4b0488e33ba0fc42fe581a7edba110e2ffd2ba5e4ef6ff133fe337c8660698bdbaa91c038c2a3eca9111e91236647f3e1d3a2c582231cd6c84d69d98024e4328397661e5db40bb1c81c19a61efe42aff3dfe236d97085a7fe4e48fe2dc1698ab7124c946957770d2799909c5b52aa2cebf5fa2736dddfbe4996b65ae9726f63baa06f13a630ab6edf0506868121d16c0dad17bf6ea604e6f8dcb1f59c63505fd9cac674761cee7090f016142d4f1fcde067b6fd266e14df878b348abe87ba526a88bf728341bb8fe1b3fa23255470968eb69194d2963a9a04d61e461e33b42bff5c179f71c793775278197e85235f10d5f1acacbc62c12995a533a39384bd7bb2a350439818818029b6ed31764478bde67c25a5d53e0c83774a983ed2ebe9ccb97254eafe8a815272448577b36efd839b27dc8ca2f67e92cf5417cd17dbb79fe275188d0d8f2e441faaf2f4d2bae83c6b3df30851d8f3f4c65317ad615c16a3c1783f66a1789a98ec70f2e0622d04e406644c6fb2fd2995e8f5747305918c528564fe84b4dcf11eeba5edf5b03a207ea266d11ddf11eb8c0a5f38532abb311333d29d0babf7f4e84f93e9010c035acd4a030fad9aab237b17593c2685b45d47c496fa7decd652b03fa60f8224c9e9dd397109a4cd0e43b26c96d2fa0c4a7f652135739f8aa9fe97a179b6bdcd6f13601bded2099c155a02b0b3da6d9c0704183fd53e2d729609efdf3438fb1f72ee52a302484f020979235976ff592c6f2ca1fa66244da92a770e803ad08a15b1fb8039b7289fd1f12fc984d7a260d540608b34fdec67a886c96ec9185bc46c7b8ec6f3042b1d3ed5087d8af3d7970fce7b92f59dc82a1d397f7f5b12bf88f216c05b7ed2b050358790b192a6cb9f0db81e4b20b5f0ae7ec2c42278c97af3dab972e1d16797c538438becb1fac8cc63ea42e8c1986b5042cadb2086354df01135f7b0b52a6d6ca21a52075674b354511f0d80019325c24ec2da0df301d00873bdfe48239b4a6bd37a6ece93b3d37d7d479a6fa20112514fd7aa96a475fb21f78a76c3c8b564b6242bf1873457864e9f2487f6063fe4f49068b2aa3d81bfe42941b5b45153c74b9a691d365e11df3a1adc471a4dc61b845a4169774076c5c976faf7934646d6a883f632fd7fcb9087ecdb1067a2c6fdc8c67f40462b85d56edb5e7224994375dab9ee7b5a14a1494321fd6740397e78525f304b871ba828e25010c79ceb54205620f59fd69cbbc438a5bca9b2306d7c14c20f78057f11a53233dfe09083c08ee8ea32aae35bd1d95b4d8dd4613688810c4126ce4980e89a74b407be98b992b283c3d1aa9338aef20e59e3cd44cd164d58bf144399522784fe9933144af566854ae73c694ab42ae944e0c834fac42a327759156b41d5a8d71b8a00fcb4c8d067fde0a7e72b739a6294209ff44888b50bd01a0099eb9beb6af64d0b60f1e0339faac2593115a8c53b3720ab4a274841697c348243ad1eb8374dc2a4ab83b47b45a16c1695747eb3b9d495acd1b6f8045a41a6cbbcbf9f29ff2727b1d3a682c31545290306c0800639571f2e4b6e3dabbb09120deeb6d6e5e0973c4f9229c8bb88412e03f6667cc0805fd334b35a6743fc2706518646be89dfc577fd1cdbc84393454d44249ff71c25913e018ac8f428b4b64f6631feb579820a44e908a79d2e5f8a3d16dfbe69ace89d524d837838294c420578afd0ac2828846896c8d6cda1181f06f9846bf5e47a7e83b366bfba3464ea48296519cb26a46888588faa63498408e85137a95127323e64a301780adda08e729027f2621e710137bf63a4c883c4d052fbba2cb9a201336911ee31f0a787c398cf8ae8944cf873c32e3359e608b68fdaee7fd6cace223bd1c2911a2fd91b5e4581cf45abccd06fbe75418de5d1098a8aa9fcff171cac139879112039ccb9ef6daec1deb7903a49b74e353745a36adbf62b27e61d04eeb46cbfe122e468df066c4887df40387f4f723a4affeb4b6148433481d769ab8ce6f6048466606c7338a43dfd7da6f9ed1c4e200060c4154be6208c9fad2d5304b5382a5f708c97b23cd694ba88ef01001099502550300082d1038c0040219dd03c512ae4780510304f80bd4671480191bef24823013e68818992ba365ec4a0daa1ca98e3bf14863b82eceb0a329190263912ea6b7ef37357f2b8bc3ec51458b4d1e24850fe5e68b456cb72d1e82054853a8bcbb16fe3064cbd929d171b4181b9e101bd939ae5fdd0849cf96dba186cfdbd6ef2e6426074d83a14c40aae42111a266461f626839e096536856db7527f4e4bf660fab94554a4f90f143b1bb2865bc65c9928057a86b42b26c3da27db870cb5cd24786e8d2627c803f615395f054d17d1c281c2b2a94badefea4512aabeb6b167096988e97dcc1baa8bfe6057072bb4f4f30c0da1237c3b99625c43931cfbbc3ad37519329b435c71bc6773a0f96f1940b4298ad0453acc476efe2ed0cc3bfa5bfadb01869bc8afc8bb2a74e3540cf01fd8b885f0d7374e2441baad9295c06c6a7a37c8f7830f460c6b890212ef5e7433075bf1ad102af85cbbf9c21e93ac2414a1c1ea17ebf42ace194c37feb5f784877ea171712977ed087f277231ea91b0fc2899c4f8b7a6b1d315f2fa2f6d4de1b8b9161ec2c766b4f22429c0c37332be0ee7db56f1e260ae34c018763e7f459ec436a943b8c906414ed482b64308f2c74175ac5fae5c3c0f3ecd1225a426c77724866a2d0e7f17dec5df1e8007834ad7a2da07c892b58c278f07d259e68750011aaeaf34266d29399522d62e10a7c7b906bf07b83f6eafbf3af745b3e2a9a440b3ec09a7c9f8343107338aa04f93b2a06c54c6c3f1059a2ec4f27de1de9705eb5753a572d25c172c94e99974e44da8b11734d266dc5f136ea180c854569ef52549e3e50f3f96db4bc6c1e68c3e50ef0745595e66a54ca0e17e0e1cd2e8be37046f2d4afc3147812c80b412343840133a38ed672e8a2313bb4200f07f9215737d6bc215e0f69ccfbf480502fb94814c7a029a8191263a62fba4a23f1c30580ab4fa1c6b38b09b22bdacae648962b7d19637314bbacd8cf4014e46aea0f3e23ce2218cc6a6333d1f617c696c38a3ecc6c277f8df0d2cdbeac423536482696c9438a16d110979c328d8b91de60813c01ea0f9bedfe5e0142359ba096a9aa16a8fed6f24daefc6ee02298413d2b72fcac8f0ece81551f78a534f48015a0770c699fb42d7a0485154cfc294f721083483af84b1c12b0519dd01c25d282ab9c54ecacacecdbfb452de8a6adde4a4903db8044d70ee2d2146377bd1081f977d5a400217d68c0c47b7b7afa88eed7b098126a1d76d6c9caae7c64d9cb27cc0fc4456879f7bb6a31415196cdfba429ca949e290987caaadc60b26712a8d8820a8201ba837f838ded91a73c5af205e849b524b8dc07dacae1caa1cb8fc255813b76b51780ea6550297a4aa2676b5f0ba8914526107ad11a332ceaf7d12693d5062af7adf5ae3d65495e5a65f8d3184d3d2932a987be51ff1ee2aa65c1a4efd7096ce79ba1d629c606248c2be9db27a8fd84d6770ae5a43503272af3acee10361078a6ee7f1936ec72cf9d3f37d0632e7734627ac05db5b4da6a56d545ad6561fc4fd2579086ead1d6b9cf152daac183034f3bb5957f654a073ad6f323ec3d07cf5b0581bb961fb1273c18498d187611d75b00c7a9ecb36a44024d50df6d5829be3251e338edd9883cb8615ae39d423bbf32afec3102928462610780c7d478a63dcc4e0d9e40b18c2a9a9f90793132ca4fcd1ba34c6b058c95f527840762b2b44cc89dc8a4d8e7ccd3c1b820090f90902407a0473517a2bef98e12c449ac99fafa3d400719e6c33cf4e648bd7713cd85ff40a99bb50563e1df020f37ff3505afedf8c4bf074a308d3cd9a521dcddfe802012e12e2978074db87e68839242cd1aaa5bf45de5072515ffcfb0a919a19505a96d428ed54e76edd6fffd57532c00c1f5795c303ab9177e4a3700595a80967db0511f95467e8f7891513b8d740a1f8b7bd9bc620291a4fdc45340486cb4af7f870cf6caf4e75bb62b9ccc03c65e27dc11cdf09c1015d51e996ec8c175a2413eef8f7e5c37deb965bdb198e478c4b5c82bf1fe72aa1939c7c62d730365c7ed03b930763620c58e2d0339ac240c2c38f1ec70072f6be1907afd0543247d9500cfb309b3c7ce1df8c6505fa1c0f5d275c0995b862bf67b332c1681e88140a40765a86f50eabbb32d88ca6f60002bccfd92714233299b0907927385056bf0688c0d26e0dceb320141f82fa607003007af5753542d60332231f9a8df6981beff2185da5d14fea5147e6e9ce4ad7fd6ff5c144485035fe2f531624999ebe3c4bf53d9e958e06b2c9f0a768b029596f1f6f15289ce8cb02edaebc03d51467d37d260a35881424765128bff44d578c632932a044d4dd0111189af8c87a13be773d8432b34355e396a5ab478f5ba5bb1ddf613c03f99b8e7144b7892e49a625ebf6a7dcbc59a3a963f6d35821d509d4a532aff611cf242e2cc93306c6018a691c4f4c77679fb0ae2a25b2a040545ab0e0b7b24a11612a2cb09a37fa112f32934ad28d7038f2c515ac447546d919c457503a56d4ae08e898f3e3959cf99650107d6962e4b26d8efb3314ecc5a5b317d6ab66e7f643a4d3ff1e51d640f8a6cc3542ef97bd3529e32f87d3e1d25583f7cca8a121eaf28ee6a20a4a2434b258c56978dc3aa5644a81e83f020af915077f6865ddb750a1b3dcc857a7c6ed88deb3cc97cc8be8f39b73565de288d478c0f6bf6a48093c65381e431d7315d62babd2e7c6188fb062632ba47cbb02668035aae5b8f3a8a62b9fc69f701d1efd1527abcd038df2e435a2f57fdcec2fc8cfe53635328f2e1c6527f838ac35b5a10f8b9469aa46aa5e1e9b5e2dcc6f0df4e1fe51b03216ee8f49a1e9a6e1d806284c78611d61b4b610b60c1374e93cc2c2178e732b500fef282355abba06c806600533271afa5af3626d8e77e67ff6e3321beeaaf876ee6abb970df98ef0778287802c825bcaf4ca072d285dcdf559fecf313c857473be7ba70db5010c2809d069982a26416e1caa6b46e6461c55a35ac5a8bb6119e442c674b9515c9c02788fd205d7e12097cb1f33d54be15081df5d43a203a172607f3d665474486fa78e72250ca15bcf25d3c2d0cf72e6d4fd513e7fcb888649ffe10854c14660143b151179ffb8ac359c5671942778e9512acb4c0e9712bb011faa72ecc06b702f92d46380d46a58c1e6c3ebaad719e68e04f58a64118839d6604ba657bdf9e95425bc09af796fe14c42f3a5cd0ae1629e50fba2ca4a05e83abfc4629314f3c54a9892d9e68bf6abd4064d3fefb220259f0c34b3d0e05d24034382b264676ec0c1c83a2b711bb0f18a2d85617cf7784c0b5d5b143e8d901bf773ae5a48f2ff86d0e3a6cf841542a998016febc0a7caa0b68cfbf707081babfe7dbd5faaf6b7a464bd062fa87bb344827227587622561cb0d5a211507f9604850f9b4f022fa59a716dab5f9f763af083b687d6f1423d536432c35f51714d9f661460803f90ed80b8f8903c95ea3a686d8b4b65fb36087ffcf7395b9a717fb329fa67578b5aa4b7e660e37889233c927d9643970dafbcd6b4d4752b152b0adbfcac4a8e52a7aadacf66d338f85856b63f94a54ec939b6f6e50d2126a4e3aba37b97226ac1358c34fbc34e131fb69ccc0e907ed9d5a865589d6d74f0c400054ad40809cbb513ac08a9322f0a36711d9383d957bd272698bb024632789e8b5f94b2b78b5183acee5451f9fdded330d3135c50668c46348c79ac0c2c3a1c1714b8dbccae6cb47d62bfd3400f2966021d86f00e0dfe8abdcff9ba7964e62cac3b10ecd290ed09f82403adec72f0e93e330e5f031e3a3c9b16b46e85353a7eaf923d97e7841088bb34aed8cbdb9c60b41322444b7342c4d47250adf6ecb551095e8ac0cf3191ee570242f16743716382370128ce8664dec240ee1343387568e915d4594b3f981ab815daf015e64f8cd5711262c94f0cd2d510680f0ebedcbe2044c2b9fa6f56fab354de4a16d0d2f139aa826b110de61610fc94a81de3b7ca032e953adc40cf26822aa904a7dfe4ec3f03a342afa129333a222511b34751d0329ce615ed3b583322003cdd2d487eb396bd360fdfce290f7d454b3b073a5b58fc928758faf6f21d8d6780a88b0fd7c0baed1fdccb58640f8202a83f98eecf4a5af5888e36b1317bf7af889d082ffb091115bf3747b2c34fa4dc38c07b88177ad46e114223846c58b6acb2326a627e98c8c4ba6055e183554faa46c43b2a6e41911a63c537a8be0bbc99ff9ca0a5882e477ff629db70eb325598563ccfc497392680c1736af25feafc4586f412f850061cfd2c3f8e50fefaa486f79596cb0b126de49cdc55ecb9b78abec0b7fe07f022e6f5f545bf841d509d186e829e272de6aec925daa636e8a218e61ed93e9d74424a00b47df660bd8b4e8532149ce0a1b13ecbb372a586ce484c2d3d211eafa2e464b9f4d3bcec05f1d5efeab5d836fe5178f70adfe2982b43e9a842f42b8bdf4bc6167cfe8f5661e670c6bf8c4b6044a5f994432069680d35780997b076edf9fe3bb351830dec1f49c3147e4de54ced6929a63ffe5d81a3a301ce989cc5cc9774a02bed65c091d4af7ac931fb496c2e72e2542e346dbf5a85bf6d04f85699f2f87f7dcc2fb59bd445644849d7d133bbb94a5f4b7908e23571233e2265e3256ef93460fbdd596257ed5ce123a4c89a4bd7d7aeb30a26d8029ac0a4ab5e339d096139af7326a511bef477aeaae0dce8524260fe66aecd263fd7c828f6506f718293d6d7fba82efa12f974f7feb8ade436ebaf958d0cbd3eba190e2758b65ca741d63c7d73ce469b1dff893d6fcbd8b85deb6703902cd8f68e80bb074e5a8825a98a532591a4d45b11aa2fa6614870c9641ccf30286ff185efd9c677cc3368d50b5460a7396a74614bffc4844b164ae57c0661a8b4d7866825016e48a18395c480b0d2f7f4f9c7659c9393f3f605877f2c90f10c67aebf986c781f911d5496b1f54c2e8e44f8aa3da62ac19102e0e550a1e5807ba7577f5d47be7dd296a0e83d2f1e14292614407de6c763a6af0b291fcaa94d78074b4564ae9ceb9e5048d0851f1ac2dd646ada12f68785f867430199980220a4880fb64730c3ce5789ecf1a4683a221b85a14f24d71a7ebab8aabe5ff78047e82ba5720704f4715435e491b2e5d1623e5649809cb7a6732b4b43c14a5a2be378ea4cfff9f65637bf607ff8d3053f692caab577d5e475443891ddf0bef056f6b1f8a61c74fa208a7a4a9bd39f5c05c2372109f11a46bad749989ad83f16b21b56b83141fa747407ab717b93cb9e66ec0908fc351fa1281cde0aac5e6b1b6fbc6d415523be27ac16fe130af6e9674651d46ad2474bb5251653e352a562d682fdba4e3f1b81d0312bb04b2b1f6e1d69b7b6b0eef7ed05b493e34a38de4d8235100c0cff17093d43b687e4d3d4095960e04f640cfb1bb15b4dfe3f70dadeed69031d1fa007b9d16d8b8941de33fda4b6fad3d187bb82b238a4e5595b62f36fcb9689be7d47f63e0c5a3c7b412878ebd51914aba35feaf9a9b624396dd83cdacf94c219a67941dcdab26868f91fd0e88068fe3ca63d3174581bdb397bd825ac396543f09be6028bc2a6608dea4f7b1e03821a7b732bb5760a91d4806a0f4e402d583e9ae7f69ebf0c6927b6968fbba467faca6ddc2b0efb90099d14c1b90aba0bb5bebe24d1a3e8e9f020cbda13e5f6949c4f15b055fd6a616fed5060f22da45a41e96f533316b31420c5d08a392866093c0904671b49b4fe1fcedb20904d7e184a6a97bd07bcd223ea7c4216ecc1f42dbed2b9f03784f4775cff447b9498ec808c907499220f5fe75346b2f4e460f400bd013a06d0b0c1a3c9a640e843b5485d88fc869bb35fb48cc320629a424b088bfc2a0dfccdb7607b3def06ce3d29e591e173693439a4586bc5bcf9d4f1267c4a223f1af3b27b0dde9991880b8890a1fd64a6c45bf7166508260e27920e657fcb168678a76021809a9f6164031047e7b044675e1f6369c67fe02773b8d1bb10825b41d99aa9a49c3890a916089ce25c997eafd1aa9b0be953e4e7c2d32abbad20f46e3b05a4a7f65968d0caf45f49de11997a6ade9a4c97cb4d68fde349d37494ecf356a12f43ea569d906b1944b791fca150ef98b187fd86e99f87fcd25e13e4af3590d2e64731b882cea3989ac89b3ef1efeb6e4fde10658ab89dbe855d2691fec41142fc25a6bc7c212bf7f480b6d7b505688d43b0e66c5f5bf3d8529dae9db6547e54cf27638d34bced3c3945768c078d4a8da8712d951444816c88ad9c64ba97be0bcae5d804b4a5ef10521655ed1cc62784276cca1c6608d1b494f4d9a1abcd0fa3d2730566f4f4bcbfb36ee1b886e2b97e3032b13618c43b3f9feca888fabf30d93ba0f0846a40ac66f0c9406a2b2dcc55b5055f7a7571862a62b00aa5e1752c8103f25ccdc5cf24c21791c97f6a6f4e8d2914207a79a3e327f17ff06c3e04cc27dd408c72252ac6e149c468a9fdab156d186f03cf013e5a01946058219bf606028bc4c8f4251d74a779aceaa8f8cf19734eae44e8280dcf32fb536449e8a6471261c70c66b0acd6b4f6ca440213f03057b6788d53fec0a8e41c2cfcd22fb682a29bc3d52a6deba5883f0f8148d27d1390a23c30b7a14e1a202ce1da0bb208909583d2d65ded58dd5e4bdc644afc0e42f0c9127dd74450b13233bf3c3a94c9038e0fdb35dd3953882c908815d1e418121606b9ae9fad2b7d7bb370a32e577e9c9d601df26986fce07b330da9f73c9fe89d76414f9f06dea8810e7d7ba298c124c4e74193a91a76fe9d9ba873227c2d2d199361ba9145674aba6779773c1cf926d16bc4ccbaee9e9fe8b28f95c5b880c696cc1802287576e0bff37468a9cfed45fb698760ad309e2abffc585395e2b9f698c313574706770fced6036ac27dc7eb0102bd82017f6e4a3a9a50f74b5efda192b3f0fc2ffd2a2330f8bb1406746e260ede609f25a1333bc31a3c2df42b6134ba417d85bb58b75fe8b647a4afcb5cf5e6b76f7bee6a50f08aae17ff5aa967e6218da60b108b855c491fbb905d83d2ab4a6e9a9268316a937680023740312efb3df6e9b2ba6dcefd23c1e10597c30ed7147a5771e921e4ca06e12f4f556b10d94b723103c519a06bdc670bfa33ea5a9f80bde8c1f89e0f9a45cc2ffe7fd4fa05494140e9586e91bcf327283fea9889af13f465cf5a2149db73a24548c33ec32e39ef569e7f6d0fd8a902e672ff1eeefec205a4c55bc1c3406face0f80e08710f0ffb99de2d5e253f7a1ae42d32ebb470c343ba104cde6a4c22e3822f8b40ff83466f634207d6c207f14ff3fc722cfd15962b5db99ceda37f77f0f389ef45217aa8daf2c9627905c63abe852a1c1c0efe51e6e6a955233edec49651dae3d053c8c7a8467cba0d5a9e5cb18037c11b6358fdf8d995fda67a76f8029ac2e65fb4d21b1a327b891f9f5db675288154e3ee6f2f93caec9da32219c8d5d75b91f6ef90a28f84f337d68a1a759dd2ff642f62bc32f159d165f4d02bb0e137ada841e5514b96990001211821119f263b1c7fb64c507fc67551111bfe9884bd812974104f99b0df5952e10c232d9466541f0367d26b1f2e7ea03ff77c4321f3f1985f8dbc8419c0fe29b8539bb0dfa35ae05ec00ebccec02dff8480e2b172635311a5c6a46e186abb19c3a0ffec3d0b4e9fa144c0350130927d7cef370f148995f85c1d5ea3b4ac13f3b9e28c687b9895d7d5d7a72fa76d3d100c78af2360b9d4ddbd943e0b24d511ee549fa31754507d5f9e182cd82ca3d7faf200083da025023996a79377e7fbe0ea247b199269f4dd3dea121895afc43ffd53b39d10ee55a6f7dc765818dce9316bdf1556564c491dd8a32b35443d8cd6dce7b7a8d8e7f18574c603d162206dac8713a885a89340f9da69a42c7383e5042cf5808692f8904fdfcd2578724d854423233ba67f8d474af381b53e948c03ef6ad8fe7511551d3583a60636bed6ac68c08ae3dc7ecffb356e51c197be9945f6552b52e2c1ede4db448cdd2353f7db7efe0035449faf32db51d484d31f6ce23c2df503685367e3fee17b805c14cc6622c95a83db5927f3067ad843f8af6793c82be3ffb6258358dfdc286b3437f240de9001f2c11cd9ea1e5b05b9ef089231b2b85d82b0f7d139a488984357483b468de65a2a85333e1e62e7cbd6b0198833d37d9cd7e745abaa26a0391ca13fe8b8ddd4b721c7c79041e53d48a8547b69907e5e4376176ee057dd6c7933f7aef45f23112bd0f5038a3c2271e07cdd3db71935564c2578146b1c6e453b19f866942552b694c758770d0cdc0bacb05b2ea9c8fc3b08292b6dd572136cce67f9710c2e898b5befc070a9bb07a760e16a3db79164f88ff739d32b35485dbb80ab2fd4dcc9aab8d1483c4c4c3f3dfe50844068d492b69041893db95fccf638fd5367027a6eb78c67f9dacc10c35da3510ee5377e6a1542c62251c54b72d968d3263b7003c087eaa22aff155bb1076c9f42499c5f797bfbef61e151c4b9d74a3bc728a36309a7ded3756292a8eaaa229945e6613f6dbde35f22b5978f328059947e633b585ba4c3d15c02472094dfc66ecd4195ebbe11b7627ea4e55c5abd9d70752713e6a689e9f04de9e942b7bbfc85aaa943d578e9a14d529d5db4b68353edd44a1daab6958928671d3c33502a9d8b59942ca2e0724a7bf70640d5a8e569b2786ce095c3451362a9c069f14316640726d978158d99c76b0a9d1939502d133f93105f50561b1b9245eba10dddd0d3cacfbd11948832ce2e190c7a9f18e451523ba1314f37324abc63593b15e9f9500b79540faf12ac396c47bd1ab70445d03493f0a89d4d24b81e6361f03d04020a4281c9642b679d85851590603e8534430b780e5236fc6352a120529fccbf234226d13f7b721ae0810cce23419e35f96ff1d231873d8cc1bf17e9fe1ed9ea49b2745aeaf02406f6e91a324c25211d1d08ef29d280cba7c8b6f3e72888c0319695684714713be1053112c408e3a9dd4392cd93422f7e8433fa5e4b40780fcf7cfa3cd0968715187eb58546eae03442f35628b930310e0d8391d6d4f1d6760784bf88939990be72646e4bea9deaa321c1939ddbd2166e5dd8a2d723e180e8e70fc263ed521e9f1c6b191ea75629a701118f15a3feab3c312f2ab253bd658fc679894c42f553d5e70df2e557164d99d30a7ff13b913a1feedb66ccaae2d3c834ebffd66b2dac9009029d82760ae3c1d2fd4c80c5c97f62b7bd8215be6461fb5098dfbf36e3e1a6f853f6b061c72575aea494c1d52bd27b35e3fe2c3c4072bd4897bc41a85fb747450360409c6e30aec479d1ddb9989c37ed7f3c1295efc49ae60fd77aece6178b6449021d008ab432d55d20fcd5cc8a7def154e4455f2edad6182f3f3ac3564b13b5ef73cf54eb07c6018bc8707fd8b6a57988e432595488868d137fec99f545ff2169169c4d58fbd52906274c66bedb885c9b81cc0c4bcad36a207a157bb4194e57324698213bee053e8e22aa36d50c424100c33ea3b934b8a3d77bcdb33bf2ca8a1b3881e7c2dde19515048419d080740c0c99a929d894e90203b0b9b85a3617d93f646154c042313f238efaf3150cb5c27000594ba69f69b046a78747ddbadfda5c9cac12b34d6ab8de62538b88952f435ba137110a0487c39d46879e39db29440287e93184342ed9fbd441eafa95da2eb5c901f0873f8e0266eb187870b698a4c83f8dbc45a3467f08e55d472e2899ed3dc3b96706a26bc7eed369d8c6dd2a58a6cefb78c78fc7c3382efe9c7c92264de3d2ee2ad3c905092041cc3f2b11af8cea997878ac72d3de10d4a6d4cd41279b02f4a1d7bf4b41f4e89f1108455be5f4ce53d0a4f6e29891a7e6ecb6221f4a82f48b4457c9c0d7388fefee40d04c422e8c1aef5a91847c75e5d1221069d1c136459b16c68a49bae118c9956355e48895a7e8e160af63bd46e681e30aba8c8d8ce86f8916542337a89d9904ee0a40b0aa7caa4fb081f83ec56ab3175d1e109e32796bcf7a8f7cff6444a99c8116aabf118fcb32c9f5dc0cc37773a18729d244c6d00c9ab4968eadb1ee2a01936c7139c6c6aa1d9bb9358f6f5ee5f1902fd0f1a9f2a68f3977e03b2e15bc48bef02d6f67123c55a072f679f2bb21541104dca56fb15304aed1518757c6b8323fdcc3e2498cf25d6e79194dde11afb5e4b843f865d505314bd55863a41b83d34689bc28c60457ed6dc08b0b8db5c979768df8b9cc51ae63620c5432049c7df6175d96efac2a8396382734e7fcc6d25ea071ba05e3440e256296dcc2d739c07fdf7fec5cfe2bc0b30c0819a10267db813bf0cd1c2a1cbf8db708dd2d4d20dcea3b0fd65c91b9564a86d879fae37c30cdd0b7603091dc4ff5e99bd084fffcfe3b1a11440c065d65dca09e381c4fdd8610f4591b434281f5b6d81555561a30889f963686496a1c8775747d8ad920355d595924622217f7ebbf0caf7b4b15fb0fb14d1e3271df5efeab0ef1e31bf76839485dd3de58e403375fe5c3eb016b15bda9c6bea2d277e5747cd862ad12a2e7d07efe6e9c4e1af58c6b4abad5d7e605fc180fccc02942ed0b14c5ec61ffb237f2361dd2f2a8bdad03c9f109e26c93073732c868727e033dd7e3a0c0335b2191c2aa648d8c27006200f11af36ca384980cf2931917cdc7cb1707e2ee168cf829b626c2a6d3272feef82b811759eb80dee974be47d5014035609377bbbd010a9cbf5c92389cb7e51befa07b76e558136592d5dccb6d7f4208470f7048b9069b257c8db23685f19b0be06ac2bd616d07e42ef07ac5bbd3ff5911f4a9a7a7518501b4cc11f8ec44ea16c2e9ffcbe622fae32f3910bb36ef9ef59bc91958a326e6f340fb86d421ec0b65d04c4f3ce98a71c13cf993fcc43b4a178cd917130aae3ec0b343b821b6f104d994489be9218129ca2acfb4aa94f3860ba70780a4c5f7939952b16c44edbcfff36621cb0d965dddb092280713f257cc31ed192090294e153f2b7b6dc0387ca8f58c1e45f5dfeb14da64a3280a38f0199c4092d9cb4f60b154a253808f4f2f5391ccde1e35232e9f114834e6127e883c67dc2407c18160501e32a930fe362497d7d2704409aff82462d3f4d0b0d5f6fbcd94e0e9c037dbee7291b381ab67e52007c46653afd388032de6550a75d08b9dcf44f48b156d7c84b5818f1343401c2d0b851898c6ec2552d70748bdd79424f2451cf3f2bafb527e1f1be576a987d3288732e5f880566bd8e31db173b5926fcaff19f61f65e5e0245306b338747fc923abb7dbb4590cc92626c623ca62cff030e021a0106badfd123adff288167c78415cc1f2cbc898c04ffba623d731feb99fe7bde764311090fe05097c103f2c8b3f50f5148f910b58ba7c4302e560d1bd0ab469914367a3df6181429818cbf2f8aa71812c165ca59926dd4d2206fd06a36f33928ee847f4e68272b5e9fdcf29ce92435a1be5b407616008b8a721810d0e0fc83cb04badb0c6245f92e1765a0a2f3146ee98e5ee3db5502e8fdb0a57ae5c60f77904912af080daffff4918ea87551e2bc5c0ee3e9afe39a0ed99bf26b9bae2f62bad7fdbc0f8040f74b9cb325b70bfde21c3a036be26918f56935570782c5be05994d37614e7e17844ab3334341e9e55ca211270f7bf7d7da4768fabb0881c56815a4b00a5378240c7d81de4de674a8387bf4793327bc064d6a2d0ff6116027f310d0a86084724a15969c9ebc4bbfe495bf32f5bdfcdb4991f23f020dc3edd55538f6a7c05361f8e91533e4ca923d9d3abc3ae08f277b2aa83bff1fc7bcd2599c1fc0c86789102b48d1ea47cc7aaf73f790a53160124472238a68d32b7e5890727abadeac1c4491c32bea4853a8cc83eed7c82d1ac433246ae4907790508e1a1aa8fd93c54090d4eee8da500a0fcde5745948e87e3d4e1b98de54c6237cf1f60d57b7208881f5616085a68638730b239588e3315e58483f377a91a5e3e9c4a9a2e4f767163ddac9b284adaf638e023ddfcbb408af9a913570882973ea56476b24db7f86a7dddddc64d3588abac6fa3d0d8daeefae3083336e4d3018bcf969945d400223ccd4c403b4482c54fcb6f23264ff7d0f453c28118789d6bdbe73e93bdbd292446bd1d62cda7ffd7b1fe14622523246ca3c165527569bfc8e4a8e76da4d341ca87798873acfee1005d8e8a00308d9ab5eb73ca191251c31186611c8ae4d25eb8b36a376e5636c509d7d145a1ce42ec106b9ef187a79c76740f4fd23435a188108ab2dc6272d4e7a577df6c57da8ddc39bb70f38fc58809a7b182dcea50ea82d3851c74ffdcb2be7b451217c56522f690e29b8cc1c25b80e97dbd7c447e8ff1e8519f40eb80c7963409eb09afcd9246643593104abd206d5d8a48707ecbe51cee555a5ed3c2d2fa6dd17204888b0aa644d73a92f489581e8d3e9359b213078355a8c1dbbc55b3751e057c166bc21b7a792b6d35f40db05710b9951ca7fe7716f87bf529af18ba838e5a2384af1977b310fdcee0b4dc23700779e61b106b0bfc2f7a56d7eaad89d997a682f53f4c3d0436deafacb63e011339de01f4c4f290cc46f3109e64aaaeb8518efbf8e81902698a5258561e17e36c4d8470a25f51481a19048bcb2fd2d4ce0332e28d87fb8aacfb6e8d6559fdc76a57aff28768a0af7ff11b642a88e650adf3723c71f3145d61df4d33ae63289e701251d5b7a09f13f6b930eeb0fb494e1140009711f5fee9220ab11b0c340b34311fe6f188afa9aa55b1cfa74af0137060734e4411404e13e1744f5cd87d5796a7883273590ef2978490a8e84bc23bd384d51e9fbc8690fab2ded4c2a75e1e4526a01018a130a8d60c5cc3c35a34d66b7c2592fa1f546e7f1da66ce2fc84416587074129cf7107fb61ead8e08824c670320643ff9db05728d6589a9dfb419cdf3d90d9cde3936b0ddbec904dbf43e45c09f27f9ce07e201a681d423ceab1f708b497be6d1a67a120e656c79960885b223cc1caa9b81fe4a9dd0b9553a32f9592669a4f986194c5e33bfa612380006687c1f71c474257e5f5c6e4578170b75736d61b378d8f3a7222d23ffb483e03e0ea0a22ed5be2f5cedd827496e2bd0afac5f97afa672f10b30b91f71d36d561527a9399582f0ee28daba1930e6e8d1724279ac26977652526c217bf2b3e2404f7748a123e4c59461fcd3749db3bf8a8320e8c7e6a8abd054b250bd8ac62d8a904a81bcb883e13e4a15f560b52dbb289691f39f5b3a78cb63bf1d461c330773defb3c3f3387bc59988f1fbddc02bda6f86c1be469eb01fbf54784a8407e8292bdc75901c3aa1e09bfd03ef34004aa6ee1ccc216a03bdefa06c7a7c4c751288c1caccb555d4c90f602687462f2a7c0b99aaf706ddccc75b80e2126bdfdbc1c977577fcd6a412e4c8289d9920b6ce9742b52bf5e556813a1658e97fe425878953a4f8df703b6db9b7dc5196d75d38b899b963e490bf0e40207ce82b960acc4d6734931c9bf087acbfa920c4d14270ff00a34c0911e4e4876266807d04e8db4749546a04df8cd7f7489a3ec48079c6ae835e9ec7c315eb4426249afec905803da45a8595b70195f7e123cf0f94cb7ee01fbe01558dfa7dfa4e9714abfd35973347e7cfc115f4bf333dca32e4e5cd8a7a3857bd2b916e236d65c403b00d559424ce0e80b8625cfca2682f0212f48ac5be7613becb7855184f90c365e4bd7b9dd68a557fa0c4175db1911fda8991c0ec479711c1719942fb5080454ad8a701b205d31729a1a283024d8bba85f9517f40fb2f5497b8de36d8c57300fb2f02048ef9a9f1c570dbedf97f4594adde480a3c9d504a4ffc8c8814912fd3a2078a82ff9b47e541ce0006fc46435fb33817f267db67c7cd8b8b1b129fb164493cdf44c38aec4f2db72d2506bc7c3f10776f2bf2b946101b2f7e8289649b5ce9fdfef115ce417c99bf8cc1498dd4ac1bf2c0daa22042abf9f29c30a4963c795e19a56046b65a3d00aa8628ec05adc729609d49b8da8403d97a747d12fca532d699bf89fd39bba6288430a4b6ee89eb4b7f3f6cc2db20fae56c9cb661a32999cd36b8cbdcff12de442947e253ff93889c0c6f94c203c67e0ccbbe4aa7e0cd9e22517a7b4a3bc9a5ca0a023ac48b5fa46dc029ddd6040266cadda66774825b877da35a94b37a44b80d4b432bbd5865cb89c80f5458800b39f6ab6b29f43cd55df9e2558d57da52caac5f6de29d0532e2fadcd3534d942e30699ddf04467acaf9ca9cb3b64966b7d4091646f993bcabf9296988440508a7316f250c5a9498f729a43362c5afda4a5bb840aca8c4edb0bdab693ee10923c4b0406adb5f8e9ce9d018296b1eb640ffdb81937222949e414f338daf220da8987ce3612ce6dd19b0d5a263a90e8410e445a08549c37d49443a5f5ff0e22274ceb48f9724887098285552fad7fb0f42bbbf6e1f2b912cc2d345460da59d248a3c609354c9d40aed029bc7ce0505f18182032be8b61fd1fb9850e32a6c291a97081ed6668bbe8b0dd700fe04ca7a9bcc54f839b95dbca5e87ee49695aa9f324d875ce87703196daeb96e2734e1a8888eac523b97881380e9b9a2f2c6c881551118bd953c738f94db73d9b819eba25e0e30008c667fbc11a80624f38334a48bd6062d8f548e053ce5ebffb90dde51b9d74eff33412fc1091f56831f663c03ea9e3a0c4e25203779edecbe8946a149a52e62060d11180e28355b84bcb1f928b0bed880392642cb2314db8b41ec350e1ff091a39903c93f543209c42349e32d1a8cb563376bf68f60c7652755b5b76519854a04e216ed60495aea3087e7009bf5a747c83e5f5beb4b23784d8c242366b7b54c4a32d2475df801992793991ee81194a929f28c97655fd511e133d273b0242b08275ec8eadf2d41f44a6481d4020e06f998867090c1da700a7b3ac40f8ee83f28cd47f9e71b9a93814c3d6105549af8039c04a8c2236f08f41bd47e6f85db50a3de78420a4ab3463d9eb3262214efa783eb24012a0062952cdbb79e26764c1ffaeb2e4ccd17a4443a0b7cdab49d96f6dca96e95b685f6cbc96e45a64f1b720b1e9747cdafd2baf7a8997acba653900251a7110f32c4e0d0cfefac8060aedd6c6c5c3eee1d201952cde3a0abedc9127c6c3b84a1360f99937a99bf346bf95febf66be30ff189c66ae9ae80c9c21b63b9a5e3164878c46c9ac85f89a9417d3cad5247b85c7d0c9e77a95befcb72a4eaf4d9478202e30041a63f815c166a0a5ef00bcb3aecd50ae9e5d6be90924a7f66a00d7167a3a24f3b96236b63bcef667a45a1a1ec5bbd603aeade2b086b5f66ca6163dfcd2b4307f9eeac8a3d0a9ca1aaa40221be2cd28517754fa5529e0789a32bfd623435d9d661b2fe602c315ed455f4819d60371dd29b7a75a8ad62e321b7b4e5a94a2684287016fd7490e4a5d114ac75970a16f8da25396201db3e36a78b8c5e041cf07a7fe833da45e54ed509e0c730370624a2e684b6d4f9b50cdbb56b7467544d0ad7fc4acfd1a628c1e3a4299a1ba5d602c7da1f1f463e417eff8a63c7774827db3041e199613ff9368b8a211f1de4abbd735bb7ff94ce63d4d574b59b4545d55f230c720468a8b7b2ada26abcbc9b96bb062aff489cffc38b4cf3dd8451328e2dd3c8bac7d9cbc6fed5a6b1f131678eedab7e9aa35cd7ca1ed2d7447b10c4d6ae1adee9d5d3a9fcac77168f673a367048020c4ed86bc44263c0f6b885bed3948ea5ec89e670ba7b65e85dd042ade2adccadcdffcf1fd36f8e6084ad9331ce7f1c1253eb157c4878aade598b9c2f9dcf5f7416bb3d856d6719c44310b1f031492676f6844aaf1323038e28e4a2904c3c81c22b8cc36263962fefba22b7f8b824238b51c2bebdaab94cdddd91c530aaf9e85593f06cb10463ec5c6b0b4961bee1ee1570598c99e98451e98c1051a9084d711ea12300a612939fa9ea268d0cbed632220192f274435c6d37a8c74d11e517a5f4add6d39250906d31beeeac129ee02daf84d6aff3a3d382ffc228079fa6128f2d98af2ebd2fcef7e1fad839399500a4e48891aa92361f15c61ffdf956b59ccf4c14f7337c5abfd9bde1bc7ac477c17afc26e1877f54f65a7589eeb8894c69cced518e1828e157d9b0323fdcfa0093a69da272c6fca613d76c3540a0e20087d7b92a843768cb59b64f54e3634a1da188e7de5dc090562293e812af1302fc3ae8e0b47d2107ab7b0a4522262b7fd8115855aff0bff70e24fa41e0712a5358d36c0acd7386c4f638de6ba556110d489db2f47ac523dde43ecbcdc7d9c6f97d449b31b7989ef62b003242820ae28f1a7b80516462862e6aba8f5d11e2c09e3c42c04cd4fc7f58aa2d75962f6280cbb4cf052da2ba5e298c811f951114060d56147dba9ec5a64004acf2b7a5c60f085b6b1ec02c538b591b76407bd1fbb8c3d1079ecc9a85eb0e390047f47d05159efb06d5c8132c34f818918481ba1116520356e573ba1ccb065a3165bf86071f9fd4b39bde108ec4a9491afcf13795749df6dabc6755989a5eacf2fd638a1446b99207550fe88f288d72dcfd52765d42897e4d51e0fb94885f1c0704b8b13602bb2d71ed8553eb2af32f9ed09d12b6945e2eb3e4fe5a0c4416595477427e01ec812d44b9576a344c95601d1162746c628017a3074455294eaa13eb12eaec0ff53319e5702d061ca9a339a4ce780da6d875f6a01b50048f9ffb8a26fe4a05a4d617fb4909c8ae77df39d71167f130f705783f9870931bac4aeafc82bbaf55d55445b70b836123d7b35467ac1bec048c3876e3a0adbac9f2f544cd16ca41ab29547cabbcb4ba366e353033c0c7f84cf6293c30c61cf9282c2714d267b96b751d16c9613789dbb9edca06621282089adf37d16ff4917ce4b9c88842ab438fef3dfe88b6c596936ea8d5f3170eaba2d6f399c36e9df9c9f58225bfda1d06ab543cca3db5c18c5818af254d3fd935099f77aa7a2512c5822d84867324ce419018d27669e7d62d8238f0f91f5a5fae551aa224d2e2d062df14e9e6e072aac732c075b39085650958f0b61319112879887bd5eff7427e084d8879e9c658f2df42ef132d8c874feebbd1141c542b6e4ffbc48f4715140d985b1a7c2cb60cdb9ed4b3815e5c6cd74aa5a39fdc9f70cbbd9158bb9a0cc2f928ed2a3e1f9c81a05b8bd772e0967edb0dff04920c7543d9946793618da9c83b3098c04bfdf9522160f89d8e9447d87cc69e59afcdc184901317eed3bcea1b74f38f7faf5d5cf8efc471ebbd089e4152d26800b6da7d025b95d11e387ada19ec3606a0fe523a6547a77cef76730f6d5f3f5f533189e0a79e70e8feff8a049e016672a510c6103e4fdb314bc519245e8a1cbd441b6e0b9bacc0680f52352f24bbbb60953dc5da08b57ecf8cce95ab82b92765f547bd9bc498138fbcff0d75291557687e123ddf4419adcbc570369ef17398ad2db38d2ed4aedb9fc9d0a424752c28833480b9fa556a56e03ac760588c54ebe4adbacf8262199c91f592b68f6fa43a5451fe73994523864b18e54cb9f1af4a538d038641f6db085a496edccbd1f0f9f79daa212a0c4c59d5ec74bc2224014e8c9b9aae5ba91fad46f0fe8df059e96b279f0e6f832c59d2b836d917c015ae59144ae80a699cec5a531f1a71f0fd49a6ede97b4907de060e4114ca4cc0c4af9036ad2e32394696b34280f48bd169b9433bc10a7412c275bdba9bff58b2ca9b67375258a12b2774acd5ddfef025ff4edaff773266c1f57ebd5ec69b0377540d5bacd378613a759508740e3328a9933a7522b5ca129aee4f22751b95e9efa5a695d42e8ed2cd9fc1f373aeec076c55e1da0300efa83c5f58bfac9d775f98759a570c9d0ca7fcdf59c21629a8feef957c91ffa5aa5a80c269c69c983612f4f80d6738bd540269feb844a2a1103fa684f776fb1f5d6571b464940d63570c4d9df0f1de6b2f20ee3300c62b390822953ee29bcd4bc76ff19102c89aac017e4ddc9d55864b5699e137c5304b8c9c27048994f120567e3be2833538c44722241ed39153bce173074d340aaa3860426ac51d6fdde93f351399a818b8e4e7602d974813832335a81fa8f27369aacf5f391b80b50163d0bd9e31c199f7794facb6bf39eb0fa9e4c8737940f05d50ddf814df56c71fd044d8bd1eb87da0baa85eb992efd64f1408bb1af6acbdcded7db2bb6b76a0ad508fae04c2195ff8f93eee158cf97086aad27959f4da6a0ba1e7b2b67b86adb1ec6e6c4b91739c5518f4a9ee03744a2971a90faedac98b9d7e042a8a221e8a985a382152b3a57221ffa00bf6ea3b11dae3a5e34bab6d791cf95c42aacc7990a3ad85a8a01c1550e4acc1585760f0332148217f023f8756f8fecee267776a22c70dbd8ab5f866c1554b6b571cb33918e741ab32b0b3fc5b9300ecdeab71a1dac3777774f54011c16e29927edf3ec41d666ce8d4a9434bc9f62b751b74ffca11f0bb68b4564cd68dce3e2491117587acb5840b14cfb8f2bb17b4b8c80a966b657b21f0e580e51518757c133bfe785d93a6690c8615dce7c88093caf7110ba2c767b7a0cc35f8ad946325b108b7f64ec4ef28e9a4f731bc34e7bfbbeb03eb09ae721d337f0ada060f118524187d1d6229757c7dd1f60a44bc704b0ff574e883fcb770219b6e6dbedbb11d6ded642fa3e02550a90c9fb8f6a1ceb799f6071f11372893c000ef9f889845489f9f1aefbce281d1d6fecf1da23ae4d2dcc7fb498195755e99e1fc23a928b313f80a2db12804708efa75c2b8cad94f01262834438c80c01bffe41887841916f28bc321a3208bd74e28931e663399e0e91ec249cf176db2faa8940bd3b06d118a5cd3e0604b152a2041fb330a4995263eea5ad35dfe8d9df051bb5dc3a5dd53f446914e3e8c3cad4453fe01507df2421e928d8f28621eabf23a34617997a5f7233315bff59e47c9ad4e2159a1c36f459489cef4de1d1a9d4de8937752630c8c9487a22c512ce30a3fc470fe9538fdbd5a1529e3390676f8a7134c4135498b8b38693225270e4946483e0bfeb05dfabe6f608964355483e120752e6f5bd3ed9243151e411c7e742b13ed7d8fcecc697972b2669cafb6ca51fece4d8c44b5becb1edeb12137ff3b15bf6b87cca7dcc1920db02793394147642516598a6edc05b030bba33f87fc4441d39dfa44c9d6db36632b8a5c66ffea431f2b97f155a4ff7a9c22cc8d76d7826c98de5be11addc60c873611116d7f44921bbb07b234049b21cc7d302a322c7c1735de5c284f750c6a8e3445d31b07a046d1ce35fe996ca0439f07e20da97238c92c92c2eccc89bd36d1a21b1831f180b624d160a73d47d3079955e233716060c29002e7e12a65c887b6e3592d5598a174e581e59cf579316844389fa69f6400a93ada7d79ef6f4f4a8aa66287b33ba2d467bc1b97135d7894155f18ae01c406da8e9559e4df2a501d2dfaaf0833f2e04c197c6ff90fcab428d87ec4a7cb50ef9ecbc3fc31dc162786b1355c6f962466277fa594ba2634f47c0cfc532d9f22a108b9faf6881c0828558447754223ff8fa4838beed2ee6d98df8e885f28a5f64e71ff496bcadc251e609f44f3f1ea0d1fa41d994fc43fb575b8e54d7ba009bb1e777f79bda8a8f93510dc0d5c449105b4b1773f36daee4dfdcec50f61c8ccf3f90afd93c44a226c0e40c575dea038a480cb1866efb47a4dd5f223c279223dabd9b4ce0f48e4c56bafa6382419416c131922ecf7e210d70b8575c97849c35ca54c0b1aa4bcf1dacf5b7fec914d7eeea674c423bd2eff72f9541c3d0f781a6372c1104e4d358f268e4627dce528981c20b9949b4793b1a19f2b99524ea478712f310b354daa06d094e2494ba22899bf1ed50fa0121509fefa4811708a6bf9795b110ca28148c5dd93eb8324850849323ba62f83ac3c836565311a3a8a0f3f9688a4f5ad1d184546ccc64c1b7bba01bd00095eda2a8fbe567657b7d1d306cfd6128bfde0e5130d0d09a49248e271af4e72025c876691e884d888e78face4a162ff846e41817395700282409c7facbe5d5c4a8bfa97198f70c4beb11ddaffabb436742edf0d9c717786af0d9f2e93bbec3116630ad5fbb0826d6a4f48e112605883b117ac5d698ba5332c9edbad3cf2965fe8fd3b4454735711f16168570a03746cbdeffec4fa533e2a0c161a83d45a4813c63784e184a52b649420d58255395fce8a167ee3993622a59534d59b9d62bb167d74acd24b3a442d9e4a7561d668b7241263e2b5903b62f5dee6075c0364d069edd1b23d3263f16aa488c366189ec71dce5251ef47a1757b0359c4dc2e965f6fd1d0a52a6307a8d84e6bd95f27ef498b10ab2d9eab527ea203ed934ed12bdf672e22021e1a8a1b3d828305ec9137a42370cd5aa89450b3326b5ff912eba1b72b68a20b80906ff40ee367d7fcf2080ac05e0617b7259ff10fa796f94e61815a54d635b5b90b09b1654e8268367a14f8f52b7338ec0c862d25aac2ea8cc930da7b762676c415e7c63305e12a66bc22eae2ae53f3ef85d59835a8247933e18a471877e7e04023b908fe6a0df811dd64b84c5cc5b109b8f2380dcbd33061cc8d72fe232caffac3fb60692e4ee0803c40b36f85b6f6f0e796a076c65571e845a970fe26a1dfbea62fd97e743407613fb46348e1f4d3db57b0d2bdebbb5ef3a36037e2a17437e02ae52d03e09f3dc7fdf95d33d9d16d341161dce1037765c79f5ccf361417d7a78cf2c7afbd74dfe1c40165ab76457ae0a473ffe24deb947f533a37656264ffe6d344fdbd8acaebcb14d08368f50562f4e4fdfe821bc8404fa3e56b8109f4397f37bb1f84dfb3d8e576f148334eb675080cfc1196b37dedfbbdfec7a50ca221ac3f76f196ddd5cc9bc8883c3093054e85c0f8c1ef6dbcef475999d3b9c41f39eea82c8f9b15f8d8d8647a866b3db718c56a80c404b6465dd8cb76b292094e955576323c8b143e1125c78dcd3b98086a9cc8ad13820f600f9411272271aaf1e561a53e89a2425fbf580d612c7d91f017fe11918c75a30aee048fb8fe440707bf9bc55e2b3a3fd1e54e1c427c1ecb8850b0c49516017017e9280302e0edf7d013faac426bbe44589abc48ddf0ddf11484f57c6316779ec40aa67fe09dc8dfec00b13f095c7c91acf0770480455ca0cffcc6aa37ee42cfaffb063a7155e1a39975a13a8ee4e3a3495975e0b37a13400e39e39fb7274ff9e76f2fab3f99abd48f37891d2f82477c6cd175d4d9ed10592763f6736caf7fd4d8f4d0818ca36f5b53e486f3ef37d6732a196bf8e81ebde069df6d4e1f2a2c364de2ebbbbbed8cacffaedf77e67ca513c3679c5633ed7e3343ce357e752aede58cc982837bb5e0dcbf31bf857309b1bfe2d3b5f5eb85d43a6845fdfdf3eb3ddb06e21aea3ca39086d74baaae24b180c24a3ee895a20df96c0fed817a72ef9d8e8df41033929f80bf7b960f4cf949b313ea31229ea4976946280551ab3f959bafb81dc64aee9672a73f6caaff39b0a133645965a116d44491f62a3433dd443ad0234e0b69fca1559ca2225308df464db1612983221a28ceebcf9cea5908647710ad1fc875f110d23f85e4df61a8030e96cb5113d98166d16d92abd772963fe0f76724fa67b8279390f146a0814b4a4f40e5385e152fd914bb52c5fcffbcaa22e85856345e3d1d70e21973446a89e75e7c4f8730804c4510958616be581ac8a873d10f49915d356b18c0dc8c0fe4004835a2cd7378ad6ec2d7e04344f4b8ff087920d3167d533f1f8dac2412b03cbcfea19af6016b3616808ca338edefa3daeb8993c9f399d250dbab410f35281a9b2229b86f031e61f5806d18db56fb8d0e6ba594e502197c7c45427d328251e8172aa9d3d78602a1e1f877c5f4101d18295514d594c29cc938493a9b3a8df326a44c0cbd00002a24c27f845f35757ca32fada554315b7ba39d771d2a8a998f76348ae7a93aae331750ccbf16ba72bcd1e84c53b9ed3c2deaa31918ed2332bfccfe65cad075c537350fd6a26e157813140e439b9e73700edb296a10214dd8fc77a388878bb2a708df5869252fc5242f47aec5fe0500d6cc19901a9b80874c9fa22673def7912bc574a3534c6299a4d304a3337c4351c62893e9dca11de9a48986d380df078bacf28a1c1ac99daf24eb5afa14878f01e6afdcf8a573adf987817134aebf43bd81295415c7592dd757a4071a8f325185ee2bd7360e9d2dadbee48a81e381a5b04e5c3739732498b7169e3a09ddb6be3df50277aed650e596b0b366ead74f9e3937665d6c9300e5dbfa28e4a01bb7e05ccefe9b9cff3dfe26be16f6a622e4fc0b156a1e53eeef9f96c76f463ee088741f7edd3878d70c7017f12d8f8448fd05ad7e15e3ab0ffa52d5aa9d2d3d04d01cad8efac491531f345456a51b2d2493371bc28866fa9b7f14d8b5e23822dc4451cf70ef390e277e38f1ff95fcf9bc3341fd2a25f964fe0fa6d9d51cb82b1d8d2afae202bdef5a1a99a9002870702db39cccb62bf60ea1f0bcacbab857bb8c864add919f62c9d24195bcd84dbcf6dc9037fc11a5e0d899f27934935997d41b169416063e94876ac44fb385548ade38749b2551242769a2d43f773a4aecbde28841ff4829e164e760e764bb306559c18f0a1bc7898efe927909dc252571d16792827b59dfd4df6477e7657f2568176c56c72dbd947e55e2ff7d5ef90dd14d0b870921ba6e45ba17f1307ef900c7c2e0d26c92a67f4ae6ee086e87f3d61c64f5f9100366b236b563359d8bf73725691c1c50a4991eb534f5844f58ff04dbea812a897077eced49ae487d751650b8bb96fd7f9a7f4f0577a2edfd586c32ecdc0d273e2c2b07c77685f773db716804f53b2e34279764d65ec73ba52bc216da4344e3abe898a3f1b10b17c24425e3f83fbaa4aadfbd2a461124f03043d41706d1c14a5656d8c48747a3b08c80b3344f82f3d18c0e20f31c3754d8b9513d22a72779f315aacd6f49bb5f6893bb21c92512e8337b9854b4cb0d1975c94e622d6737196bbca8419b57919d5982abaa60dac9b4246222342139c4c952d79c95b1b66c77707a510301395d58fc797baed28a6b611111b9e6af8ab2d21620ada1309ee077f55fef583803d482b4b9360c28a5cb916111f4cb25ce16baf6cd274722619e276f13d492af7b8187740c03afb18707325339d6604438679374e0d7427dd68627d1f1667c8a59cc8b76c5d0e6fa86beae4ac7c2286a5ae4f022144a22b710cbb4e92be66b8ed31c7b99b2bdeb44be28eb9ce13b6d7a4b4c561ca844d3c1982a3a8f8fbc2b56d4c24adc7324a68a3657834a70324cb903c63742fe8c421bdb1a132db93894807bf5625e2e495b28959f84bc319503a511928534372a7bda05b32423cd5d945ffb252c1dfa5a33f7708f68fbec557e723eba9116e9a04b06d0646f921f905c37601539cc69377d9a0448788c69337443ec43324e054bb71ca46bf9aa29a1a435f928bb676738ecb8e13345cb08d0f6e993d3e100af75ce44cf96d3558d63f7b053521b9110c83c176667ee55c6a89e48bf24da3f6580d6b9e1322a8490f9387417515fd1ab3e88f79c269a24e574488b0fc1cfb97f877f9c6a33517cf8765a6dfd5f33ab0dfa15dab36e275bd5bb004778f00fa7b3b8dd080722b1c7414fda7bd09ea925aa6b2c667a3af24e91069b1df1df3ea032a3dde24b860ac17ef6cef4cc5334c155f6df74e3e09804dc12c0c3b98f826a9f75537318b105b8729ecc246878dcd2fbbab07f54735ef38acd989ca770e754d953f11e6ee93b61076a7cf3f39b3678b3b82b4cfe9649db31c1dc320be3fea1616e42b38ce097939db4fae32a76290fdcba1ce4c955dbb2f5039b73ee4f165d50a912562f2caf3b54b73d64b0385a96bc477423f8951c067d4f97e09655874bd11e3cbc6776c150156d145e08fd1fa207e0d6358e1622e1a831f8437cb9b32aabab42ea70c9ed70e7a7c77955e1e695c3025db50993844c33c1b11b3c73be5327615c7d8f2b18d0fefc0cc35b50f3084bddb2ee172897fc7fe0e05a1ddb9b753c06310d83bc1cb86587387bae701d75dfae7f3b631e4883f2734e3a2adc72aef436f6add6645be083e01cd21db9e391928082dc72b9c354c740b1c853c402ecb42ea1c592a6a86b05dcf28ffe2fc79a6e00f45be6ab217d6ad8eacacb861adc52ab0d931687da46e4b3ef718fd38488bc0e819c845b3e13525dbce31744ada74c50f0e134769dc7e160c02d5fea83b8434fcbfcfe9766382b51cf17cc78e3efa341fff550a829da21fef8e02cf42d8f9e3b962c2d8f30df7c793557a6a711af86278daa034419cc5858c4d6c518bc03ca49ead674e65228654f544e6ffbaf119d14b2a6fde5d3fde8f4b433f5cc3197964fb31a1b6761d224a1628f724249ae80830654ff41653c30a07fce8055fd897c8a23728132eab84b8f3ce1d828d583aec9ac4684c1a5535800965782fcfdfdc77ce301b10d2da7f37665eb7e5ba97c863b560abd5cdc9debb9f3563db8b0d305780b9577fc550de52cf19e5cfb2f237a762e9fa404f2727f74c1f2795a3e535543667947b3a70c3dca492d2b606b06532c92595e1183032f831f5de9ce6c1eae85c30ebb80d323f5287c5c7ade61b243c2b8a98a6cf787075e996d1ac1ba4e7cccff1f58e924a3b93ba3e18c016749a162db5a9614abe7c643a2ae584e88eb8f306865919b6b156dbc05e622af1c3ef23e2e54395ad5021642850f5de6b93ae71f8b6652a9ed9275517f6611c68add2566bd8fadcd767dba2fe61e44ba1197e4ff9cee527590317b03f111ad08ae97e6004c6a1325dcdee6521183d15b12af316a37f68f8d69a13799e212c50e2f444eff4ee8bc74551117413b252ace63f5e3baa4dab9f6bc8c585e42ce68f36f07c733255543546858d34a7047574e8521a6b80e3d1ca63509284306a4d673fad687cb04ed71897187fc58ff04b8c9963402c5a40aa2013223d204a95d8119386f3b2c8e8c0fac7fa1d7f1f8603dbd736dcfb4825e46ed99a85fbde46ff0e485d9e94071f6c6242785c4ffca815991168bbf9460aa8332410a2057393c0e11505656991795240b0605890e04038b8770f56df387906b6f4af5e866f021d245df9fc5d5cfc98f7b1d7d92947f83017ea61187dda8632b2199e247b838340bb4c69fa08a40050e90dc3adf90f019ab9ee3aec001588f3960f1fa03eb0659104f07e7b5bc41ac4ad4639e13dc8f19a26c337d624255fcbd105fa4f457b587c0e1765a8fd3e04c128e650b5e45c5d05ccfec15369cf675c4ad8e8430127277cd0a75200228881d1763157e3309732ff087134e2f26c9632a98344de983573c8b9776abe2037c80febb3fba15ad43a647191e8f05d49fe833f97eefc53093b39e2351efeafe738bc208efe95120f75755a43f5e4fbd9dffe43cb50bb5701e9032f64f19c6c38b56248d02739b113d3345e09120a33238072e11bc95203774d458355517c88ea2041d2e2cf12ff57038504f43502c5870da13c29d01c6ab7d61ed61b3bf69852671e5a57ec91f827ba315258214e25b63d4567c154d3e03c140ab6dca6050d32ccbec18e239ecef25ff035b6db855d44fb6759e6c5409f42768c0d6c124864a46ac1e555961f206b1e539ec0049944ecf6421e33fe9142c524fb44ef0b02bd5bc3f216fb8109dbae678c92d48e9c027ee0a6950c8c6b47f52c8e4ca667c4f5c1f2c5e404f3498b652e70f19f253d15f0f1c6a19a04dee3d63a86d4e7351fe04021b7734e3dc35309591fd603b6dbb2997554f39e1a393ae76f07d422aef90dc8ea282c5c0cceead34fb8b49d672ed1fb3087e4c0009f07b56e8f5c05676af4c92144384772786ef3298b9f40cdf9e075d52fd0d7d3c6e5c54cbf07183147ff82d1504acd8ee06c9a4faa8e06fecc5bb9e4d28195924f5ae459bf36409e0c368d3fbba571ca2f496e79af08be8244e9c94480e8ced9b102652c4b5f32d8be7ef45bfaa8621c0dabcee0ebd23e5fc63bb91f83041ebace201e5a52baf784586c7de8267eead4d2724dd0b95307cc110aa841ea2f81eca0da4fce98a15e6972427c8a05a371dc770f61614a32905c71b7eb2690dbfc438697d41f8612c2c6f4bdf6a655a3ec2f00713a24cf2dbd4f723b8dadd59cee7a8c7252714830aa92c57fb78def1869a8d3143b73c8e783de4bf0a10fd12dd8781d15e502688215b79459afc3233db1e6ecd52673f9780cd96dbe3121007f9a8fa886a237481634c6037f43989ac7cf70dbb2fa9597e95dbe55f06d5c7bfeb081399fc88814f3e1af3d23bc3aac2f9abe6526f5793f49ba561d1d99c23aa972ea09c4ef86ab33315b9a3dc9ec2855d31c01925b1c00552a794843f0f99c8df3d7343b703e99bef428e2215cf5a3b4242e5a2aefe11dfbebe262abb7203504137eb44c9a415bd16b51e313f896eef225e19597c4d50ca88318604bfe5899a2096aece95793e0d21dbbfe722b464b76fba1285a53f4c1fff13fb41ae4d6047df23b4346b0826c4a43107106d42d106aca65f6eff2225b6d158d02d4bfc26cfac1acaf332d9f65f32d276b930e06177578b9d806835860179f1846599b1822c754fe16f1815146551dcb7b3123cb59b50707f117facf3aca9282cc5a893c37681a0c102e88c584df076190bb604a04573ad2bc5d925a9c92f621599e0d8df7e0f97b402835cef870c6da097c27264116b8c22fd562888809ca86a336dad822371f09241a5a8deac0ffb9f073f6b0b4883dfecbc4f52fe606fcbd145c233fd25f311a9308531ef1dc55792d6afeba705d5da4bcefdb7bc4abed4edf7bc5baeb4745b3f8209ffb7bb6bc86815d101e8aab98453f914d3b8657a2b2dd2e17b827840ce007b5e78db9d162f8a68b80eed2299b1e54006a523b8cf3082d62db86fc3c51345bfa061dfc8fc7d5769e628d8a7e45dfd954199d9f01193e0b9323fea9005bd1e76719950d89990cc9305f41d0ba61afcbbbbe20922cab03acaf554b37005a4870542f1d5c5b3285fa69a7f344a49243dc5a766c285471fa8a276c4559b783efe203de910adf674d7ed0e0f2e2e266039de8e31eee2b2b7d02ce1027b3107ac254a6db5276cafe8c4eac87267c06cc10d72506ae323885504f0f0336c426a2eea9dfba9ffaf4b7cca62825fb845eea07e2a50321504c2ffc5c19d2728a44b0449beeed8eadf547e8c411dfbb1d2f8815ef259e03a6ee9188058052bd6756e14ec14aed0cc625fadcca59263db5bc8d2d8109aab1c369e6c56f54af7a21535fa9d2bb2c7977cbf9aff3aa83bbcffd3ef02f7f3d173f113729562eff036d196ebf7cfe3ba5891d03b018279ae5be3b4814d8fc6ab69d966a8b47850b57647bb98161fafa7750b7cbe5577c2d6c3805c1376df7a91d5343ce62fd6a992769aee99b3096f37cb167c5df7cd6bb6cb66000000000000000000000000000000f902c0f8dd941c479675ad559dc151f6ec7ed3fbf8cee79582b6f8c6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a10aa54071443520884ed767b0684edf43acec528b7da83ab38ce60126562660f90141948315177ab297ba92a06054ce80a67ed4dbd7ed3af90129a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d03a0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d04a0f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f37921f95f89b94e64a54e2533fd126c2e452c5fab544d80e2e4eb5f884a00000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000005a0e85fd79f89ff278fc57d40aecb7947873df9f0beac531c8f71a98f630e1eab62a07686888b19bb7b75e46bb1aa328b65150743f4899443d722f0adf8e252ccda4180a0fa172c7225c779e82740fd5a7ee3c959b35f65da0030217bfdd9b7f491c92485a072ed12dc052358dc89ce62d77d3fb6cdc9a9c2f5d3039140bf60b02385dffba6", + "0x02fa0184580183080e6f8402faf080850e4f97cc0c831cf4a1941c479675ad559dc151f6ec7ed3fbf8cee79582b680ba0181248f111f3c000000000000000000000000000000000000000000000000000000000008d67d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000161257000000000000000000000000e64a54e2533fd126c2e452c5fab544d80e2e4eb5000000000000000000000000000000000000000000000000000000000a039536000000000000000000000000000000000000000000000000000000000a03963e0000000000000000000000000000000000000000000000000000000000018037005b2ca73412216c1cc0181afef79b008c0c041b474000f13f4744552d5b8bbf38b01b3e3f42052760382a15100815a108d8ba8dee365ffed71bead97d429f4abae9111afb24f7e7f9b9fd39f7debd350c5a86383a8c1ed8055853698368f3e9663588f6148cc4023673c657ecfcfb82d5e8df446580aef981e0d22296746969d94bc0e28207e09cdb5acb7cd2331ffcfcf203b116e07f0f7af5e0473c3d080f0f9e6af3dfd3fd5de97c7c813a62099680df248b04954e1b180810e0dfffdbcc7e790d8d4013d226ac7108f997a7e2d192cd9366c6a8a6a8421b71d05633da803ce2356ff0201ac948386834517292c6519293e4c0de3e7d3582c76302626abb019711858334e32d8bc149d6067943042649c086aca2bb1d10c129c921337d1f6f525b4eb2a0e51e416b43a2aa5bb3a145cbb5484e38cbb33fda2cef97c3e7e6ef14befebd7ffbc96cd486f4376163fccbf1f777e9f9ba01d0b35bfc6018364781859a638001e6f7eeede7392b0c12639af017bae43b4aff6d42eb739e47e22c9333d0150e892c2d7302dd18b46451088bf064df9a58e42a4a4ba0ab2d142dc4cdde7f209404da222855ed93a9f4fb449c2b4dbfb4f0ef18433076648311208a400289e2f8ffb166fdbd0f33cbcaccfc9d33cd8f3492884a141111f662b30a3a876b1e0db7baaf8c890487039942a3da504b0114b88340acec91dc3a84c3741743c3387b51d38cd98d37422c9bb5fffb62bbf67b2484e7c33ee94643a65b89daec83c048c2f952b5154160a10184550f5746f275553960c72352604180851a20a63e921011fe62439838f831f859f252491298094ce0857a30ac4e5132301666b733bd13e3cb8dba94ba486703406aa0c9aced14e4892a32dd462a7453fd29eb9d2a7e4835448b8a1140d5a791684a54d472f464046a474d736235007d1a131d2d50c301efeda1b9180cc7c6f34c7d1bf0eed80cd390415dadb290bd923eeed6348c9518294fe7dd8ecba48f931481c1adc403565a87130e75fb1fe8ef4ffcb5e12892e905cecfcffa4b09ca9b8ad954e3cade790648e6a1216d20b06001109bb647bf6d9186eb65586bf86277ffcf00230429133a6634ca5919101762bace02541fcaca840f9188c63f2605713d340142895372163e13f1b1cf17028865d8afd2517fee1cad0c835d592ad6ffd526a8081447b5214b29975c09f4c60c771f30b8c57aa0856fa2469a5f2086cff36930c4b0afa37627456e2d323dd66625bc4e35010ae0fccd1256bc1963612cf400a53ea2cfbf0a92cde615564302bb304a1e23a8d901fae61f158611c22d5a9db795c3aabba5fea7703fe158b5a85f490d07302b1273315781120c6e1510c24aeb44428ae2f9fc245e9f66270de53a2a927f7cf0af9b55bd0f15dd04b1982daaa1b0837d78bf2f59715d10b2f3b3aefeab467726bd4a37b59d75fbd229ffb6419c687f7796c21be4b8195e62bf29458b39f894053ad2d3ac3c3426e2c04e1544df22ebcaaf68500f8210fc5086e923918563569d3ca88bbd475f4abc344be84e554069d2ab89e80d5492162dc86e450749360c1ea92d54be0fd8f7dc128708e5969c1712080930d34e0c2b58fe08fe49eb138142e1b9917c4a410c636e9cc5d7c8a9802702ce893eb7379f99eec02e802f094d284ff8d71d515ae2830173ca367a4412ae01dc831a8ec93e68cb9cac1832dbbec6a4a6f87180e5caf4b99bb48319f0583b1a3c6ff1aa6e9075dbee5eb30dad8435afaab5fe4b0a8319dbca1e9cd78522008da05b605672a9a580ae084762c404693f3d3ca5cd3b2b57534c86fe67b37dfdaf8e7309fa913b3a15d2010aaf938654b8bff0df9f68a24d9185fd3c6ada3e0ead73c758ff9bbb6dc40f07fbe17b504566f1799a05d450b4802e4b02fbd8f6189e4260601b999877cbfdef743ca4d75e6cfef251ac0d993090b3e4b0b5ce2f9b0d44904402e77f256c4e47572738a2e231e4561efd1a5d2dccabbd34b644dfd11eb2f553d63e997afd7ce228d2ec1ed92fa5476413adb41ee637efe8f48f32862f8cb42fa531b104c4bbe4536803f867c92fbb39cac96bb88ff48d572385430c01bf7fcd04acd63316b2703a10caed9d92bcef05084acc6f93156894c5cf0fc223b6541de01634a057b347230081afa2fe23e34840f4c64bba3aae8b755f0ff8e49d6d133aff9ecb20fc245f71786acb5c43a55e0b28f0eb48fce4fb5abe556867ccae8e280cde5d23c22d8c0b8b39302cf826b43f6ef7013162c98195d6c1bab9c1c28983d991c2815c6ca0921f35e6d53963d6567a9ca865b3a0e3fda1177c44239bbdb79a55ef437a42005c848e32aacb340233cb30ec3f5a98d399c73d31061c1c0bb5be1e7d26828b3480d39697460dcca16128e61a4d430d81ac1f9a0942788c8164fc02bfc19677865207780e8059493a6638ce7e1148db89ceb24a72f3d1e02141089ba9c76194d08dfb2328545b9f7d4c625885537ba8dc351232b888d1986781381f9b951af58ad020752659e21f1713193a081e9261ffcb1293024de84952aed8c6c9c7cf9cb7f90b9e37e5ad21bd35ff5f728f902d2c0a12c6b051e18b58b4b028f7cd0998df191380a6e156e5aa310fa2c96bb3f53105e7ffbcc9cedd22cd434e32075252176be1575ca165220b13353f3ab61eb57184078971d2099a7ecddc7b8bb40cb0737335385e5c3f35960a7b207e0754709edf0e3390e500acb8ce3b241c19ed734f18fa69435a0aeb718a241e213ae489acde57a816705460251bd22e03675cd60422152b997125d84ae9a9a46d11d5d3533118c862d6a046f998635d16aa7008f7038110fd822884d60a2e4b471b0489faf2d875bdfd687edb8c40f285f04ed8427f0cf049e5f58440bc42b0129b4027463f341a5833cbed5472a8bcb411afcef6802fc06e913d01835bd9c23d3e575fc6703d5b16902e59e30e749f2f164ae94098ca4dd6bfd9e795c3ee25ffee1d102ce687b4812d87a222484aa8ad982bf0ff4aa672b22677a114bee7636dbdc802d3a886073fc16a2307f4db03fc7fb21d2a5932789132a3f46c021e6a2a423d645bc1cb0a9c50bf6e0039bc9788c150c4b1567cc27f40c82fed860fd412d9314c4f312a27ac24aff66f16374cbcae7b5eb81b629e17c06315b3c380bb7e69a5de6bbdf45f4e40bfa1b55e17440d1adcd84c0422b18d6538105739109fb3f4fe4bfe87e337936a403d4e5121b1c106a7af9f5f3fd1d4b90a6513f95ef58e3e6736f24c92cf9e60c2e9d9022d0d9ddf9ace2fb91a84d21e4fa57330986e5333721e22d95fb22319951e6079e1fb437924a49ec29b09776cb0ab84b8dca63a872e8a903d35248f3c9dc3ab3ffaee2ee0d8a94fb9e6356fffc36e308e8a80c19e62b2915bce0edbc83c7ad0f843581a8013bfaec16339117d2721b65cae9f7822372986874180777a30c4b010252fa41858b04676797e5b86e494c65ff3b4f50d44b13eb903f167aa63f1341d2754db3dba1ad322aa4c42045742bcd71ef6996a88a16200750af73b26f6e0fcf4c7f890e612b60d63d4a9db247a08efd24fb5615c6088d1f3f794bea679d35c6f7f9f13786ab56fe741e54a7fed9675cd4cee20e8ed38f5223229481dd3cd3c19ff47c26465f9d068f3abb391d9ad9539f8ace3c19465907c4a822c591cb831afaa511674dbb0105433da241ff1f665441c96cc408731e82c5f43324ee43e6e9293b1704cdc7c69f65728fa759afd6bcb684478e390bdf539c866e9ea1341b244836b820553113cb36970fb21857b2913dddce63869ffeef5e7b0f28470fe77edfb8224fefa1498a10f5960e2e17739ac3cbe29b75f5b49d47b100ca5db46cf4ea2ae6cf15a9bc7228ed148c71e7101f29ade3e1897326d51d3d55e33442991d416d129926919214c83b3034191e5936b9d2af9577bf1100cbde1452948a17f25f01b251415d7c73e0d530fdae187f931367dd83b62dacf2cc6f0b296e006fee88cc55458db19e5f4d774081943d16627a67d21d82fbbc2b01c1dcdcb902c204ef77184ea4c3e13eaeb62117565e97ebc7a86d5532a73b4b1ff07bfa0b1631a0b2afdcb9159488681496cff365c5906311a976f451fc64a27cb37a65077d0ee19c8fee2d55ce6394e1e614520ce9febfa0f1ce10660f3cc5e6872026333656fdf507d6191aa4f766b7238ea9fc602e8eff309f60537f2a12801131a1497ad2633ca7f41c9d79541af9c602060c00f57f5cf35fba42cbfcab1604b1edbf59ba178a2dfa71445e13a242c1c00f68e90fe2b748cb86983bdffceaec8388ca0c8fe3344c77c5b40eaed8c8dac72bbe709e1c6f72c5cfe90e0dc44e5aecdadc66b908bec5e8d906209e5f887b9e0301e81a29631bc97d0d794780525251930770d6898ab986670a5e0aaeb09cdf71a6162f8ca7b1ac513d3edabc9320f9cc4c725d80bdecea6990e3051002356e4cfe546612c40dbd58eb86ab2334dd33cdbec999090ca72b88a9c87b1a1e3a9a05d3cb2cda0181ace171f49a5b22fb6a1e070778b0191f50515fff3f1a438f386bf1a596fc9ae6523503fa8998d34fc07ad6ad88bb6176cf33004e2923962a92334a1e00684c733f6a8fb82fac3d7a8cec415ea51ee6caf48d9f52fe6e669b621552e0749c2d695dc5763aab88d3c297c638016cbf90459c404a2b2058f6d0d49e105bca0d0e2868b581d3c4cbe8889b945f4604ca21e6fbe619e69885bad913f629a879913fd073cbe11e0ec9e30fac945f6dcfcea1736d9ff05bbabd0dced8ab408328312612ce1d26655ed4df29fe2e0b5805bcf376bbb314bab8b9eb63a0d881fa448a5193e6f2ae5a64ed46503996767ba535236e75dd1188e39558663751a98d99c83780db38d93ec0f01ec64deb1c3c4971f16fe38a0667f35b18d7b27d435fa93f416241a6394529e2000928f27e7deb7f5d51f6f87e8b4141889177b1ba0fede93e5d3d7ba8542ab3dc1b5d60298651fe89a07d8dfea23d1d2e2e9a0a050f9708ae76e1bb9288fe3194e13f751fbce34d5ec1651ac4bd81f951a1f4d5c780852aa426e3602720e3da8d6b8c4c31ea56f61df9e0688854c9bca8349e10bcea0b0c97942481a7c329da6967e542332fe7947abe5870e4500fed49b6260894e18ccefef2eec6fa63305dfe6624ffa5ee619963b571754289db156a010613f2c2f9929b04cd4051043c40d114814171760fe59828c5d10daf4c233017493d69c57e90cf909eaae27cf5a0cad269cb92d6f128d0e65bbd11cce403bf6b536002a305aa187c428f724aa0b17a1122aff37d1bb1ae2f194f246d1c6fd41aa3aa7117089ce09e7ae80265fea8f7b7d506d0c5893f4ff3d243e4f14c80db1a945c7011b07a1d9afbae4c4041f5dfa5a00084fab5e78917c2284863ab7c5c907eab255e69b6578e7cce064be19546c22e7b6b655bf6ebb923decc308473bed8b7fa8f012b57849b4e026d22f40371446db6c476e61ca50df0be304bb29e2d16f789d58823d23f1fd4fc2feb8bd7b30a35ab8d86c71146d96f27a2dfb1184a5a2702b0d378a519f38c0ab7cb186be97b1e5d0429c7275bc06461155d3a951fe780df7a0ee8078f823194bf2282ae9f9151d1a8e7c792b24ecf3226bda6c9f83f1a4c2de8c24c4c215a68bf83b944c1966480790ced60b2ba6649890baa17014f41dad5713e6a949284d8254d1c006e2314ecfd0af6132034151257d9cd041578674b8672d484caad6f8f6c1bd5a7d0f0353a7a8cdd050e84b10feffd7f663fcbb143f831f989c41ceee98c81ee657d62b38ed6806dce43fe9eb4f3b9cc4d4e1d542933b296a27ba35844649effbc18013f668b1972c06c4d0de01e5ab55d81261f0b114b1a6624b2a1d38260626c77540da11bc924c0193f234c167b47471048d7a237c49bfe8bea7a26ce7f2386d271d93563390e530acb88e42e113d7ea636bda43a8a63306855a9240bc0943a2c3b831c8e0234121045bd07699e2929ec937a1f39e7cf6b746e95c170d827a827a7e6b30806dffdd4f28d0b1cb12823743960461af911d12c064fba7632784a673a7e4225be41f132a2564616fd3d112651e36a154b052c5245efe8c7d869c922827b68cdeacddf7e37c404ae3c2afedcd10e4dcc323c6d1e703da9b147748ffc0e105184c9654eafed020fd1ec4d2a725d09c5f657a557a966b72d3c22073e3d028798068a7eeb10e168fdf108ffb7e1896ee4e7887c46e50b2e90197513d13adf2e52dce5045a42b48d80f050849b6df7c99370b65f073e2bb0f3435acdef0861f841be80efe7748d9699da3292f840fdc85376e35efa5df98fb5a42f6b91791a98075df1b6c2ee9bc2f8e5eb7e1b805f0c7d0827c9f1674b46ad977fef7e648d7c615443135f546e31c35d974a0268001d9487dc2cc276e8e97e21f84b0925bca1c9d2c1fe88776d203750752a0438f6a003c981a33521e4f6c5e3c24d36217acc8d0bb3cde58dc6a06011e8825204f744a908ccdc484c2d762e5fe2f1ef3449e48b79329a592128264d5213dc1bd9da4533f9a0b348f8c7e5080ce810c15a5e3ff7194c1c846b08ea439978ec54bd13455e337cec6ebb07a832620d063f7a3be759411b7e7d132ced01c852888982aa09b3248c202c118e1b670f51ae0d9d6895c9e34c022a466d382516184a89db28b2135768713df8919989ba85aeb00dbbb51542195ab0549418f3298d0f8e9cf4815bee893997f367fc2e0566a33b5ef966cde44e15f3d74592c0887e1b531f7430123fa13638e025e13b37f16f5c4699b913c36a826dcfb1493ab7feb0c56194f1c0185c1244e777d11589a345b38cb47954c8b8c8c9fc53528795fcb988ca426feebfca218497dd1e227624989fae326ad8fe6f62ebc63fc823ae121aaf8fb2d45c282b0683467b72bf22f1ae3bbf63d34cc6916d56aeacb2f47de704257ab84bcaa69c1ba5dd0fe915971a308520fcfc2980e95ed838077f5c5d4cc8ebb6a87f024c431615c71592fb49355f41ec1efc083e51b798a4ffd0df25d0437de2fda521eb96a09fdf82017e090a752a4f18c0e2d4a998f6bf4b7b06d544fdfaaad231f7fa6bad3647ae4bd6883fc7cb5275bc91e968521576cff7622a1bd3c975636ed455baa5d492f0a87afda2b5e91b5cba65413520c6023ba95579b54c6ef861b58954ce69f7ca6619212d7142bb2fdfa6897a2e4229c4625ace3dd9a40ddb9e406830b9d81e317fcbd4ca44a9d97d5825d18192c0cf2bc9695e2f20d6d28235f3b7d30fd154c29a4a1dbc1fbab84a75fc276d5c4b5831787b1753b0dfba8c67be1109644592eb9bd4b0a4c59a424458ca9ca4d031409366afb1cf8d8ebd7c0955a7c1b46ce0d368e352290fe5d4540cf158887358f35fbf82d63e1fe771f3c79b720bb31dc2d2d404d8d75b799296c7ae374086c82999729a3819c97e4a215b7e84fd7e8f2de6298b032a93538176315c5910bad9d1f5e60c36d14c82c5fcf2ba0ec7053be74303d46e30a8e5400a90ab87a35fdc575e58b53d581963002c8421dcc8a4816777c500a140f1e9cde937bf467a5975a4dbf36076838783fe0e01e93f71da45b0ff266c4620b07b7263a5be2bf4f35ddcf453799d2a85447bdb9aaf78988c26fb5ce5a0369606744eb182a9f1567084c99a4091394d4cf5da48924ebb4a23d7e376e14015364e5727656f7437c25b874d185a20786951f20a813202b4cbeac1ddea22166135efa5da15722c59b4509c3fb1af365bdaa85ff271f809b77e4438f327b6412b757f822027f710e708864a712eb0eef34eb448fc4e9a903748ecf5cc806bf4c2108874ef40909c3e8e24f4370d71644e2727534f9f7f3269681babf689153360adab5b90ed4cd1172e99a5f134214eb9df15665fcc9da425e0b15fcc6831116c983bcbfb40b82b7ca04e2105c4c31f8935dd024d8ad9d13a7dd8d88dc9b111f7e4acd565a577ea83ba29924a538db0ef82b5a9922544dc9c31c4c07bc127f9b15b5de49cf9e95ee81ede7afad6124d00529738a6615f9202b43bee8ab62f2893966ccad3483ae31dd6d5377be9d5a06c4e7e7186ea39256270a37f2fab222ecaf87ffb7b2ac1c40ffa031f8cf8bacca97d3f672607eb89892e24420c3f328f67edd520b102b05fb8570d1c78fb9c703bd144e35afb9d2e3c2e0c85c908925bd0a13dba060fa3a7173e99e5794eeff4e01d0b4bb60b1d356e663ffeaeaf9798302356b5d5c4b8c4d4af71cd765be94cb90251d6de9d80ca466751860d5e9ef59a8667005c22259ce5211a3230de19e4dc33110993ce3b4e9a2f2b32872d6e6677d5c1e1ba69c1145908d4286a406643a23f13b6d1d07fc1aad8dacb73f91aa5d6f1c98096eddf8de6c262daad06900e48469f95e51dc0adfbca8f91c7ed7e49f31640e180d271aef19eb0fd62f434601f8a4d3c1e0962258691da41e1cd7147ef891e7fd4fc316f3e104d9995f6014c48155df68375b1b63a7a3b8dda9b7cf5141ba270eead2fd218074e60fa313849eef755190e0c017f8869d478f20e4a56bfa9ada42d23ff4c9d170702046b336af8f124697bba9eebfcf4065dc669caf83fb5e4f3855f134f89a39a976ff287bf5f144248932571c0f4bfb4024dd0e070d5df3ba51d3a735a9d5649dee993f030aa67a69fe90467126380946c26da6a56bcbe71952a78fbb5d12a0dcc80241508342b5c30e50d071fb1de13c93b16f219777667f4a5eb728da5a662d9c2f0fdcde667a900408672fd757cb9409fbab6af50326a2571179d99e99f5d5ad4eb008598f8f93002c3e38f8a1c74c2ef42aed5c5a0fcb2d3d7ff2577d72100e2477a109a10d7bf81b02504f99f840601bc3ea17a7b42db354a5ae98472b5dd330a1f647b0b42ea2ca61186dd575ad94eb5872e00b0947a57e0b093325f24dcb5f717e58c71bef888e98d786cb2eb284643b3a08e9000d7dd5d1a203f15e7920f21f91c3f0b4a12cd1547ec4e9916f517f6be1784750882ce44388bee058707071b6323779636d2e692bab6542f5d67929863915701e25e63570062a7e1db62dc952268af521b7278e4f9787ef1a11d7cd3bda5513347fc375cb6e387f17414800b41eefaa9703674e696e8106a0b146bc3842d4f0391b662211eaca16712b81036495abbc9f8a295fd43afaf70001b68e22905907d7acab64305a403cfb5d97b73c617884a69b54afe449c64f745db8b9e5033fd639abc23c683827ca6656fbfd576f7a36365ad74c9d2c7d6abc7ddcddddcb92a7a4a382cf345bcced31cb494161e9ac7cb24d2de09e8312ab0991008c8ba9749cb43b288105e142cf2fbe6530252a736f34f143c3095f2b16454e09f08e2128085cbbdb0c0aa2f9175cfb45f0f63902b36c1c3f43f1d0bc9b939a968fb93047f02bc30e83ce4b4f5e890db43cd35a629f148e1b84629c7f2e731966103172e090665fd186503c1ae2c5a73bcf1ad1a8edf20a01350a829b6cc6e2fab768bc7c1c29a7f59f158e387610208ef78482e250cc085091101886af5d7a24ec7ec73adfae5477a51cd48752e7bdf6a450041295da5c2a84a12e93d5f8d0bb0a1be4adbea7a8ca6505d23d75be38c620983a016a73d21398985755dfabd8e4fa9b3b546d6f0c2e21fa85b3498d3e1d4ccd3b745938b679fdf383bec6ce43b2c07d14f879a49750737b5fe7354494aa00f85fdf42132a2ce46f85171b7b93a20c297bd2fc8b0be223f814ec228aac109689d5c7b2b9775071f564dbea9add651d214821b1d58c65291820ad3b87ff5abed50b6137745632e9e5aced5550f6851930732f2343d4b57d270de766b4bd523ce1e8dd8f4236de4fe4237cc6e21d43104ce28ed188338b809e1d44176b6bd9b4adaa6f370e12d8e9f6e10e94cbe142fa6dba011cd5a3be51d975895c83a71f70f7a908fc86ff504e7079979d05b85a33d8a33d73bd79b8466554e76fe4d18249f4239016c6798f4ba187bf4b30bd84eb75369604a0acff939bc7637f1ad2e6388f2568f3f00dbdc1a6d8d72a206a00ae76d8f12ae404299370afce524e6de576ee06f23ed63122becafa8674e7640f602a1eeb6613bdafed43a6139e6c0616131c88f6e39fd1fa998914b45c119d6d37888f2d6320cb6a8974fc81a87008a2b7c4df7f2e84a1d32ca73fd47a4ab703f4aa35a8157435344c2e6d9bdbd521c57ce3381c2010fd366ab411c6d77262efa012a8c11458858953a43e2fff75d7e9c4aae589fa0e3d7a30a5d66d7e05b2fd1595e537a9f941ad320958789d1ba937c623b18010bbcdbb23699c0590a222912246799bba7e7afd1c16ef8056422ffb1865b270a5aa7c3ce04516e8f2545efa6e20217cbc5102fb918dcdef0199fe6b26a8952dbeb1db70edd998250fc3c9b3253e3a6b9940640901b44317a0a37ffee22b4ebb917b362fce8e6826505408fdd0125929a88e8aab394d8b3e1abfed404c9aca947540cd5c17f3c522c7c136d514d882b77206a703fb4fd516ef3ea8b6d5ec8b60ad868d91bfa0de51564e3b1035ee5b19bc99e4428d8a8fbb04dca7fbd2d2fc7529a8b304a987ce5c477c81411703071d8b97ce05a3d54a0f9a1c73c1afe802938bae201f676b33a1e9fbbfc4fde1af8e990ecfaf4970f70802a022092c433a80e058e58718d620e12c54126df662d69a85fed5cc5ebdb7b52f0658a190535820f976f0066981856eaf60e254cc172677fbcaec3b40d9249d5cab695121864485294a4541d173600b10dafd78c637c8ed5f54131735987ee478ba99137dfe678f69097c25835b96781ee58c4a58e546352f60aeb9ef34530446d891e09f807bd25f7d57a16165c9a9f190332ea08c1b539ea544f3feaae0e957b03d19ffe085ab5c6a9cd3e90883fbe342ccceaca4c202edb51c425b87f047ffae219b420c592470fa6ba0ae5348dc2406df0f2a5259b7996bd867ec533322a68b8353dd398a4e5c1e110c68259b9aa4e2e4a92e7f57ed7d0a7f292fff2a7fafeb64b4a9fe6975653c645441c82d1ee34d769e2ad98683fed82d0363c5498d1da4c0ef17ce7ddd038c6447637dc9080a95d45fdcd16d81654d36faa7040911558e6f2ccb50d1b482283ff3324108fb5bd67df51cae2a92e466deba6874eadf92069c1d9b7528e47cfe5d25f7d0a5860ec87189946aff5b821f8f76520d088a8e00c8cf70ac45933b446e3610c4e83cf43f53bae7a22b24434bb24763a528e945870cf658cb3d2b570794568f08394fdafb88c31bf6bb7497beac8f85e942f0b55302033809d0d06666c036194decb95ec3ff4fe18612de9bb6ab7eee17901de13571caf48282b1ae84b2dd6bd80195a525697529371261759a280ff11e65685bc3bcc039d665f2ef9daf54d2ab28548a2fdf300d978103f5e2931013c59c8261a457d2d4fd8b53c44a1b8cf3c0df25523e25c5816a3fb5573e00f67906efa190308bb87d57c529e589e6c02ac5cd36451ddb49d6096268f0f4670748f33476350359965fa01484b8989cd8934e9ca655953b24c78aa8c223bd326325fecd67fd8b3fb3015a2c9001730bdc491047f50081152694dfcbedba165815c6220524102382351e4c04600472167d278173f281ce00cb647db39a27e95fefddc6a6594628f2b5262425a273fc4ec99549560c6c6b11a544b0c3655af03e4743680fde4aa11cd5d6a2c0b9f89965bf04f6a310cd6ff4b4162ddab58ce6ea23bb456f4e5ad96f667e7e6e6e3ec59782f64b5d91b702b04cd773451f9092f83b8abb5ac4db3b69abcc53cfe921568a8c6574ed4dae42c2c4e8087e456ce40e4383228569ea9b830e6dad8bc698fbdd7e5cb9d2bfbb0d0d3d1ee87ecd3c88c3bdb002e49cbb434568d3f6ce0b25c75592cdbf3e98bae5549141a6afece7d5d36afce15f35c5e854cff1bb2f972f84065d96960abdf6caa84f40761220b6be1188420d5ad4c1cd3de858018586f31ebacbda378696bf5d24482e73f2f5eb4e5dbacff07a61c0ed1f7dabf3ef111e927e9fe9d550d5f559592725fbf289ff7b5fdb3500230acde743da48153224f35b8ac2ab5f389dfa4f524af269ee4189fe459371caaa67915fa8fd9b41f43db50bb0f01299f2e232b3268177bff3e4f70d765f6dfe465c76d41ece0c308ca8461845001c4bb6547fb93f9696a970819c09d05ca28d7604d00dbd412be5506de844e976da30ac422ea807556ecb6669e560a1fe638000f50ee5ddf4865c204c01262060ebdbe37fd9f829967ad308eadb9fd2181c64f2052ef3c4cacaafbcdfa44d950a50393696f3e34db7b8fff3a1620cf14626ee8ed574dc6b77437b9d39da1a7ace6d03f2bfcfe50803592a61c575a1b3f7a8de862511f96e7b14b24bd374df91274956606c3abdc5a90b065a4c6f67429f7e30205fe9d11ea89837eae3bd0c83a903fab70c30f9278641e0b06b55c0091d6b2b084879e09e1f893d2be09f00a7883e64277387602735e843c24617ff5258a9bbc42afffda095468166a4df5d5b18d26e57e87b766665230164a700914134517a2517b065f550b48ae0cff1b8c85723fe9b1fbaddb9bf5d754b03d41f68a220ec3e7a340651dcfbcf03463a8942ec8da40d0a1a28d23201452b7bd1752e8bd4ba3330c1b1d243e5a8876df013edb0e7100f87d513c9d7775e3bad8a882249cf1a6f773b7b401999a4302d28c02c0f702067d185f9b97b85d2711f450fc56792bcafb20ce3472cab1997c918d37522ff672cd6512101207933c36b702647164fc56266b55657b52c96df0caef13c0fbf3f376966ceeb22191dbaba294ca5ee520956395049cbf3a53d727eaf637c9b2a0f349a710ac0a7f020a4bd18cd7461514b435202c4af5a2910481ed01f28ca03d4107f483f14b81942f95b22b5a66ec52eb993b57ba5f5d26386fd8f8e73d7328622381ccd910f608a208941142cf21763a72957b83d8443188a929d19c4256acc4f08a8afebedb10945adc1af221e32197629e12cc48792e84407cc888f57aa3a7066c8d70b3f70228c589b4883d122a4d4b036a48185f2acbd025408311bb004c069e4ed4fae489fd4d32e19646484c3fb27fe8d3b518c24fd0bdd6b8fac0f75fc5f8cecab38a4cacd35e156aa312844f74fe9fe71bd236df62fba043da7ac4226a742ca93b6275cac8fec090244d2db329706995a3d3b9971f0b94c5e6db4eaebaa8a556f6b3d02496810b4b55b620aa31b6182e573c960aadbf4eb5d48f261ac1e2c626c13f3172469b50310e826c133097e131be4d413723f19558404dc3584bfab3e7f38b8ff88654116de8010c8677d2e537a4f323885f08e0cab908bcf75451411f5a9fac72e5b5b73978c400b122412da53830c58d0631f57ad860ca5fc39301c35e96eb3effb0c64b1210288830491a74624f2b2c89a2cf265b2b8991f48bca5a962fa392d1b3dc0656ae3b26856323ac3ad2b564130896dd239751a72b4d08346410a0f0e4d5dc75b32ca9488008286f92c38236732591816d27878dcd312e3a76081ea2c8163c10f1fa3687994cf93a049c7729fb7a64143da8e70c5426f4f83471c58824b0e9c233519489270fb4b31e51615ec2b338bc344e874eb5faac2fab0be6d8b93b7a74d598e4a52dd34d961f6501986f09bb75a6ad830216478c0b89076190d03ad88784e962f8d13498e8a1e219e67520bc8f9ac76d009cb5c204ce88c5e96ef73c2abbeab16738b9bce53ad29b738e75393c64907b2129a30bf3bc25567507c29d0fe1ad3a6018699f4f67e3b87f18c18e29cbe268c3f8b00f5b5c186594729af15595f03d89fda1b00713fe161e4cd878b255703b47d1544d3acd33851faa9860f3aac6cc2858a77c11a27895b1b00443a78a9dcd193e5ea6f65e494132fcea7e8c39807be4ee94437b77ed1543917ddf4c1870d4800f7aadbffb5f90b87c9239b3aca0360d86e9cd4119acd8c8d1f4755c0570e5a3adb2ad27723956fd18c966ec0895d81fd03d79897e3e8aac14d92f1046342fdaf26c723e047fc05237d6a061ae3dfcf6dc647ed40997f8e7a19db639d0c25615e426994855d87145685a9ec5770ce46a7434ea0199c6966a17d1659b3f0c4c1feea7fa1ca0dd0648c816a7bad85edfade7297678e378b11e6754c31d38aa9128fe5a70786076bbdd6db905142ddff811ba7b374481646f4ab7ad0db7488866d21ad5f8ba828f8afae721cc75bf513c3e141a5ad87b4046a63fb3b705d7804159e3e04868a2d57d5976735750e8edc5283c5faa61ac5b627827e04eea4c1b7d638fb4041ee71116848d643b4b4cd5852a2b191ee51f043b086c8d75f333b3388484555aeab44098b3cd489cd96b397bc15b8898e19b9d0dd28f0c0120f9d7e10ec5f9ada0015966bd9715ce9d1323bcc6a2e09e4e632cb1e0267faeb8bff762f0c1cee20ad6b4ae8a1e6ec83773519a83c48eb032f34f6dd0394784025e07b3df2eda0b45e3d520ddb936275eecf18ca43761bd98c1ecfdeecf3265e85acbba31053961f17216915db3905311c238153db77a8487a4f3cf2c39490c1cac075c7f0e8f6220c4b403c138422ae618b52d8a9252a98021b4b4ca907cb7fa916c70b6b6eb365ecd6d3ef8cce88ec70b45af1722142268475b82be95e47b98e4b752440303b41d695a3efffbeefdf6473aaf32380522a975f190a6a998ef3d0ac21f185858f3b8e70ccab67fa880fdc8c4557257e012c1f042b7094a72fba452fdb7c1d64f515d94949b157bfbabef243cf7f5e101ed51730fb6070108e88fef135e44f6290984c0bb2aee8faaf6be7babfc20d8cdc3ef103483c9cfb87ee02116e9778d67321e1229fd5438c4d2e8adc12279f24e032e177a89785f01044d449a649842d7fcf02dc6ef196185c2b7e8ef08930adc97f7265a02be3f8a38c5ff102c864d50758c08b16daf62599bbc75b2c096c8b4272b9f36b1a0ced678b094fa175008301b4054e25d344293c199bd8266fa973df138f016dcd7f9d524132c1a5103b5255e7295851fbc39e35d5367b9a65afd4e15ef837dd3e5d6c1f8f65ed814a77e80ccd7b66948706d04a6594b6db2431f6d5b4e8306c55581787c59788fab5fc0f9f886797bf0ec5ff3a84ee2251e42be51ebd108d74b0f5b61167cf357c871931fb7129d5b5d60294c7f2d1752412a86fac42c0c7f3f0ecd03efae729c63d7b65f8fbb88fea86acc49d3848cdd18702b0737e1369281040966efb3975bf4bf41d6a45ad6a3719ce0c2cde18f74f603b75406c622ef41ef895ce84a5ad394fda7aee0d29f3a7d37002b9377768f09536e9d7389542cd133ba8579343da102ce9597e808d94207a4bb650afaac3bd4151a542dba799bdf096ae8675e48845095a9f0185c2f8f4dd1fc9a3c3d566c30d5dc55fd21f6cc54faa8c78ebf85b11570d27069cd50a32546af71a385f51ae74ffb99a3aba780a29a74dcd024c4939be2ab408728697df2f55b9f9ff172f3d32c82a4b515d29ce3f75dd8042c4de633380d446f56fd146a0e2e8bae1fdd32904a4e2c90a01229c23f2da9f1f51d118586b08accd4137f266fa91ff7280007d463ce8d102a6b8e9b0f9d5ae7045f7b5cd38cbf05d93ed4be4bbab8904a6166afd4033e018a75f259e0ccbbf52fa6d42d263d97d715a7ef154ea625b5393c5f74b56f54ad60a427789082984f27e79c1fb82295e92d83a306c71d7a494a2b84cf8b15a18e977ac647bd5e7220dbd7316a7fdd1494d56cf1bbdc1e885626fd0d0d8a7ec9283adc94c9c850190700b930a00977089b6d2cd99a9168b3daf690668353531bf5abd34e33632d6b0396839990c37ee3944632abdb2d566b146a3a4237db47a49a92b8ad12af845b6994e532756de701fd206dccb7848f431ee8ab33b3fc3f476f11aa4b57f0b363b2be6374894230291c4084e3039738e59e587cd6717b1020c143f03db63c4edfd22e2616d462c324fb1ee1ad74b9b129632a91a902c4a346cbd633870b0152316cdc9cb09e20e57ac9c6882a357710c85433d92803b2042ae4bfeebba532b4d54da89e1b7efedef057ddeb6aed4f5aa8278aef4e4bc6aff77991ed038bf3358848ad5571fb1a88dd132dcd3bbe96b54621811766f493f21a3d68f46fb8b8bcfc5e4f16612f3143ffea8edbf4be60224c0ba6699e6dfe0bd6f872f3b63936bbf48579af1e8accb28587ef620fbf4011d4ffc54994abb31e9a7c9b40b1965f68a3a7bbed048ff3ee10490548fbca268ae9f78e66d47c9294ea51031a277afc6c4d98ffdc1ae27b695f48353b7a77095ed37b3c2dfea4b5108c0489d9adbeaba61994ce21f0d6eff3ad6ff97ab5d71ae62dc0292a1dff08c471c1d9039d68f86128da0089542220fe90e13367254da884eb21b648c1e7fd02ec6c64410a4d542dbbf92516a92b2f94de7ff503ec5020387f1caf575f4e10d571e8f442e377f3fdd5f00075fdab7a2611e17fd3028fa0003c90b241c0a20c2f271d37658296087ad98a2d2e0012e50690d68f4182894ebb39f3c4a8e14006abadd551a2889f072ab8b1886d908fa052b29510b20461cffa597fa6e23aac7946ca33869e7c04299b87a696189a81a1970d5e26e0b2f3f44d5b9e32f7172d432d6b307d736dcb488f096aad315b2ca62c54190cbbb281336495ef08272219d622fed8e5632124869e0e73c6816b027c7fdfcd53d196b9e0baaec0a0573cfc36106278ed585361c30799cefc368746874baba86549eb7d8a928fbd553f6bbc8357171982b25eda5a10da1be533c11ad252e577ce303f408885cb90e8f7bf8b7566fb410edbb56de0adad1d67a2846cb2ef1b130cb5b1e556e25d5281762f5504ad04c755944af164d9370201d9b7933f3a0059c0601aa41233dfcfb2ce405f4fcc99911644ea3b3252e8a0b1a2fa23fa935622bbe94306d9e8e5470e97295d7e7660995118461d4e228c07157ad312994244611727beab206a0980630ff392596a076de8b77bad1b0ffd44766b801b889c3e27ebfd1f6a5819544c1fb09104499208d8b696c965e815343caf376c1b75010ad4cedd182e8f245e46476d7100150744d4bded63225e04b8ec8a5f2696797d45ea3ff958ff94c746bb7639e7579ab91aaa28043ddea16a2205d6b2ad05e5308a0239bb64410bfd65eb37435eff5a1e45ce6b3f1ba1b824645fdebe12e777ffe1ce0f3cec5b4f012b00017a2f30f86f18af493517bfe01ca6b17dd73d9d94a97c59890b719f256a9895591d344ab0e8c4fb0efc7f6053d37603124996b45e41cf408e8a6f040b259fd4d39f03dee958a46c2c7cfcf63cb5b1c18d7b46dbf1d7e268a2f0152f61ad4bfd6ef62307ef0ebc8d8c7d193fe9f04f430c16c6fbc042096db0a5fe17fec3324f9284a5ab1fcbb758bc7cc2d9f12bcc1aed3a20a197b5e940cd2d16628c809020306c55f967bc9cd32c5955d14f922c5bf2d77cd4a0aa97affcdda1ba80ec63cd47e2fd55c10e5095199d6ff5fc2438369be1c7e59614d83204a4b7af7e3de8c5dc372c9142a56e4f5562e236d40e84e5bad330638492f5f77cc9adeff5f08ebfa627e5321be356731ff95f81abab74589e28f24d2170ca85c829902ffae84baf8f6ca28234de3fe8f9e4975a0311d3c9b2f44de6062c3ef00eb03d0ac9c7b18a64b48b80f571a48d723325ec2a90805fda66b5f060a96f1b0fb1f5a35a3c08f9c77ff28ce8177cc13aab658cbdbd6af5e68e7e0df529353b8692dc40788befdb47ef192fdd047fd17e92141ad0640e9449621efc52f98d2e4403f3515702cc58cf970af87f6ce3f497ae1c0c2bc629431a12a26db652556c915df74c7f61c22d003a47e4e5f90802ea9681842d0062b3e0af9c2b8542ec125e3ee118002ec9fc3bf60128ee55f3c3753c74ed07c1b34e6c72eb6ed3b76d06bc96dc1542c3bdb0079f69f0dafa310dba8449202232c3a1351a481469a40fba05cf26fd77b4bf9b162243862f97ed5779cbd4bd87e842eb9fa71dc0adad35c94d04661aad8cdc77382f829a1551eec741b537c13f2887299e6c4481e51ca99b84985dea861e62c5911ab54130c9845fe96c5756da373ff036a80b062d424dcae225755518a50146cf1b0825a0f0c07ae195da316ee340c585d2e8ac75920df7c3a6a102e2dd6f0b6e59e0922e37fdfaa239525db8a9036a0e587c825059294d67f6ca44221f374d3dd0ebe97924b9753b59e3ae1c96afd6c1a484afca503b583589536d3c831bf96da3f090849d25e08d2d43b1c4ff50d5efee2b1e059d27cb519761cbedca03ff4b14327a460e88ce2d75e4d34d5f8d15fdf6d3e7c9da894fd27fd9316ce2ba5ccbd7965ffe4cb99188a94db02f708511fe4f718c4fe52740d8bee62edfbd0aab07bf51305d5dffaef24770b57b33ee5ce01a626d998b3e2320bd06b4d6212f7e44f90e5310b1aa0719a5d3e89224bf1603fda90f5689305bd660ca0649c1398115648049005f11eb4dbf369d22adf19290e88b6c8f30e9f2f6f576e33c259d738423ac00b08e07419b34eccb8b466148c9255436dfe16179a3b9fc81085e668855dc747ef1f4c6ec147d4f901925209901a07411f2254cf0f3409989b21cbf63b03521382453332a1af6902449a38300e1975b184a49284b39a9e14c0869a199805d1b384882f42b9b9b9a9cc32482f4f11de93700623afd8bb59dd57269df528d4973c2b03b561ec651020f77f254a651fcd73c20af27aa6a2c6d59a715c480c9fe8caebac1dfa9e5f8b6df16c6297405c96f5e93fe6ab2aab8b85dd4d476fe5d46f638cf0f864229f4953f3f9071ae01c523033f72df4181926e55c082d8883f39e65dad4bf0d376fd93b75688e840b3b0a6b7f3f66a62228d385616d6dc90bdcd41a665c961f7666556de75f7340deb11ceb5ad8dfdea6bb22cda805756c266ec90421ed563e3309c0a9a63e2204707cd4988a5de83a02ef5c543eac1e7efa09fa6aaf986e07cfa84b1602eb42d29848a6159586262d1b9546395e2a444828b11ad1d9464a3ff105cbec86331da5aa713329cd20c148132c73d20751b4dadf26e3b5117f6bfaec27c2dc064f7eb518ddac4eef4eb3629cfcfdfb08b82ca12420d587e86f8d41712b581f5c5987165e79e3568ae265f53d7aadb5ca6b9b19c35df9d9215662d5f9f9df8bed7f4b0fe15f8d65b8a32678f2accfa34912c595e9698780ab2e8001f9b8f8c98675937fdc7971284811a0cec7f2ce5444d7c0bbdf30319bfcc64f9201a10373332ede7b790e545bf930a2c590b6e6ef320beed63c5818aa1cb4feb24c8a80c9c0afc435cc605bbe4da9cc57659ed2e07f38b65d64f1963cc8cd75fce8bf2890878682e71f2acc49b239b4639698f04cee54adb63df73872fd3b5fa25f0fe6ccb1d359a4147eca732583d9bf00eb32550f084b9c86e8104310099cda3ecfc43fa66be2be7a8a9f77cbabdf5320cefe7b9c435eb695ec3c8db4836e74e435b7f20227f8d93ffd2f3b55eddf4617fed60766ef3c48af27ae4ca97fa90c68cf04db37d5abead4239c1e3612670101125b86608b6906b9971ac901b57869f482d141fbc52e007ed076fad6f35037d73af1bb682225363a67f7ec5450cc794e9b286a54243036ad0c799db4ec3e5c9999b2da047674c283cdbcc60651bbadb66d13a221fd13e0a2a66fe7d0d438e0ac1ed99a127cbd71d434486eeac6617a682191533ead57e9806c03302b6b042d3b645838b372f1b75b8ba26d9219b42ed7ced3657e6652341009a4286032260211f5555a1644950d442f7f609e5d4e0b571327a59f7c24af0e238b24023f43cb3459c58649bb70ca308dfc242977274908224507b2c24c7fbbe7e7788ce92386144d7410777522705de775981c7c2faff5f15d94b542ccdb61d431e1c7e6c1ca88d1fa763e6c91fe18577ff2ff144bb406322726877780fc6d0965927c53f70f87a6d75f3123f9ecf7de0b69edb67d81247b4f0501ae9f1d58e4f5a2adc06664779b2f9968bc1bbf33a24301a4ead34089b1f794552421a65e2b1e420244d98d7b9e4b60597f24a53515b3e4b2190c915e1209b2715d4c99a23f3f65fc6cd01e77c09112ac3279fab0f6e8ae436c700f0905a6749d3b086acd0faffb8b6055fdf6702629f78ee84283ad0dc5d99deb6c37384c7bf49a59584e4cf8cf07890d800ace0a2fae3c4c64236289744057fd713e796970f2074a938dd775fc6864c356455143e0158dcdd71eb9a7e691c0d5a45f26d0a5dff1ec77ae376517123f0a012099b0f11aa4e49f35b808ba28f26b26e501ae4edb84da33c421f81551b2563d6a0f4011e6c5f2c7bfc9676933731e4cc93ea32a87f7f9d9ec99652a49f7268b194a7aabfef581299eb8e1658391ce888505de1ec137266dfb6c9a19625147ecddea08a5c32b90ebe442c68489c84f3860414c59a26602093184048190431823bdc3858764711ad0d9eed61328e5147f21861601859cb68f0f9cb791473b81e3a5467b381a932c3dba38d4082a12f983bd0b8ff71752b3a9115f1a3b05f47e9e4b1460a59e49a779068fcaadc9f3f40b77da55555f926ef4fcbde9128e107c44c97d9a356b8b6efc40219fd141fc8c59184bb326a1ff5d2c95b96fd838f247e273b307e392c638001a8c40a042022b9de91a7cc59651c71f9d43f52fabe7beee7e54038c95029d3ba0ed0982df3980f15131b25454bd7fc2b6e443d30cad6a8d560ad8b4ba8f0b18a7ef773d565ecad7701f70fadf56b77bf4b89e98c8959c9687a41aa2d9127d3984737dd4b9b20406a8045fb05a9c05e8ea49cbd6c38465821cb24aa05bf5001a7dfee751368d3522f2bfec4d4384a57076127329ce488f2f8d79ea111ea2ef84b57b0024040ed7b8113b51ea699f0a59e2f5afccacddba94adf30289861f2e4c553aa9f5e3b73c347edbc4314dba1bb60da121f14fb82f06192dcc91d388f9c3d8205195909a0ab84c3e427635ff7f45f4191586a3ebfa230bd6714e3c4ace226c3774074efaf57bff6e00a7c7c03ce5444fa56d0a792034920db878ad5ff91f20e22ed577429df9f83f6942ead580e0f87abd701849e96a5111de5cbc68ffbb0eb0affefd8b22acf1b869dbef8751530eb3960a1e97661b95f3ba2c8bc72d974b5747161aad0bff8f2cb84804ac3be84755043852166ba98a2463df751afc5bf6955a18ea03750250d06eea8168b6b9fb7da66beba7e4744e0718aa9cc6843eb8b71817f4e3a6435951dcf46992d921e36f76f09e856309cdf5eafdd3d1be344ef48259bf9a840a5582ccf101fae206e10478b634063b1dd23dd34d0dbd192b35eb9622a00eacdcd10807f745ab2511a85d90af374e4cdaf4641423ea8624525edf7be5dae947c37897f2b93860cae718e7c6647837a0ea3d65b4601bb9293b965cbb365aba92a9e19a6ed0c11cb89634a8c396be098ea700ac94983ca8f3447ebb09cb4e97e6108c40df2e8af7929e7be16f6d52de9b0aa2a58d1437d4272dd82aca71e5c6a492d6b06ce64a7010445d7cf4863189ae52f63770052ba43dfce85fe56e403451f419b7f9d65f9cb5a4887363e2ce675b6494580cb0686cfec00824a9739b0c93c9f016c66b951ef24c247ed67668630ecdc4522f966e79bd488af9521b5cf9f25a85bc42bae83064b6aefdd6f55799ffa26043ece0fa7404282ca1c3dcd74364569590502db39facae19c63c37c14a6c5d38dab77f3be0da7b4b15ee14d1b5427316560f033579d4a20057bd7c7ec2d95d12ff6cbb4e56ee279bc63c0285c901d43aefea2361abebd79fa217f5fa93f15392f177d212f4bf5ced44e9962d1ea3d388e17be985c10bc94a95d037124b4af950ee19f089706bb27f826fb6a8a1822e7064ef559a79557ea5e70ee23099918b19f9bc8e4cf49aa2c300ad9bbbb563410c4f4afc496547a116d8f474717c1522962f817c8a6d9ca325a53eb607b842a529a0919da0505819bc7bf5ee2a6a184029d3615c8f894022c1ced58bc19c2dbabba0a8934e1fcf019d97a503908565864476e86ef840d6556c4af01a11254addbefe2e3aead9c0b54e0ce6c0e96fee745ce93ee38cf6bba55c67554d7352eab2404eb102611d05ff3d98686aac5c0159b10413e8a9b145a78838d15337680e372e0b3ca4cf2ddbe5eab9fd3897df3364d77343a78c4e68cb103361ec3f4657728f7ea643634d57726057511d15d3f3c7320b8de93b112d8b1c90e1eac1b309f90c9863e5d9cc64c0b67f78883023959cac573235dc5c1e6df9df816904e8d0a1dbbcdc8240021bafc1d5af5a21e3bd2cb4762171ad2773bebe0f093dbd1872138308bf9dca2272ac11b1dc1373ffc5bb6f5923b0f088fbe5d7b8b7522f6941d40218d826eff412692264753b4a2ea2867c2f011bb736595593a0a977fbbc7108970fb1d30a7fc2ab7050d741d8788d80e3667a690fceb4d4735c6e605cf92436042d795499274ab3303818122b223e88331f2750314d3fd1fa870122f44315123edde91ea17a60a5fdf1210e3bd66063a111245a36f47a252953b5c0a6dc32cc7dc0e9a8bc11774b28cbb0c5670bc330ff3f0902300283841c2b393e9f0ffd1ff343ae5104eb074079040610a0661179734da42da3ffeaa62998b4a435d1f5c4597625348257a62147b04771e44ff4252c51e2b4c3b7ccd8b857fb5e09b152cfa4d33ca3e84f0b8544a7729f6b50e94447157ba5c7a915be8e21f26e44a39f526defcd4179c85a09841a3c69a8891594cc99b09ae0f3ba10927d0d8624fbd48c7073c611230450218195cefc8cc2675971e8a946af8556bd5d987bd5d2df3a5bf2ef6569e62c9e5e860128af1e6cd37d71a535f44b659182fbc8da3493af9c334172692ad900c602afc23787076170e663ea329fcdfe7bff5983a0d79cc5e652f152b55470561ecda27f45b132e5ca91f071b71677bd3d44a93ad35030dae02c97db7323401318b864a26367b37d350c092220af060c87bb11d5a3551e1d9671ccdd0e9db3128fe62f6f0abda173316e68da1c66ada5b599ae45c857980f39a7d888965cc87bce7b5cba6daa3ff664e0ec15c14d20ff453a8e1412d6bb4d725856314e2222a6df55527c2671331268370d40e41da91bc7dad59148a7fbb2bb5849bd4d5e2a88ed58971dd0dfaae0d520a0ca5d42c619ea74ccb470ccd4a7465cedb27f4d2bfb244125ae4ad5592927d82326c89ae0348a7fcac393e4bd137c2f595a03592d68ab1c80e5136f287efa2eb602e0ea706c37f541e4585a23880d7fd90d5d8db437648897c5fdba9022ea13b73916a9070a8c22f6cec4043ccc1b3fce10f88cf6d71f572a39568452b0454a0e71e6ea345201baccd33d570dfa2fe07fe6f2598cfffd6d23bff47d3ebe59a1301c4f7b951f2ced00c3ac8328aa15759b81d16e9e0d6231bd1397fcf9d124c415cba6c77a01ae4ada0ef7637d8a4032719b7c18ecbbe65bfcff585768c452a1580facb670b175c54004bdd19392640eb23129d9c620419eafd7c41e801cc9a3d510848290983c31307b0eea1c4a52046c8a423bf1b724b921a58d95500772aa7a15302e09c7937876fd92dcf5f234b6e18c2057b42f5b74e138e7f588e58ac508d72769fa1cf9ca99a5d2ddc419d1c6e4cafbbf6f9d5d66eee9a2e973f5afcf93bf9acfec0112262a643aef104227f048fa2bff4912de26a23fb3bf7b70756a5f62953b5395b12540deb8ec30d40de29f3416462bb79695f9f7985197f3450c2afb70811cb6544bb21b8536e4c7b30705f1339c983d78a7eb413d2bbf9ba6af445d179ddbc673a5c71f0b1d1f8def0b2aac800f0940e326c9f2f04e9ccaa385100c7ab61e4b3fa3e2526fe23a2c1e6d50ecf62975c2e4d809fc8ac230f4ee8ec51247dd2da5fdb63b05969a8ede647f319d392c4dbb51f72a63a892e9b01e81579014ba206b2aeda822f0ad61c1f6ac29cde124a405416c0c0837e86e55ba6f1a455b8fb06ac94ff77ce9d65be59da5892ca7ff9974a7b05d7d9d523de63a04dd24624a6a0e0240460805212292b294f964df882c2d755f2de6abb946b4bed1e449da0e5bfb0e123ca2ebfbadb6481f268aa9046591ab291c49948620326b2fd788b4ec24060453856e66d050c62e8ca1d5e781e2ba2b2c450a97901517ac54b32200eced7c55cc15395dabe2aecee20f8ea2a5ad64bd16f8c7433d604bbc79bab5100a01f494c30f68752edd8a6919b4d01c3e3504349a8a1986d31ee2cf1741d1a3ea39a2fc582f74e29686e0c8d94004be2623ecd9374dbb894b76a06967cf6ce283dfa91e11407fce28d10b83cd3f2768c335c9a2a69fcf238c83e1c1e664fc8ed6ef1e0ab03870d456d1e01f05b9e14e46df9ff97d3a2b6e69b6db6bc4efd559e7eb55c2073d31ed69bf2b960dff8be82fc1185ddcc09a5da823682fac1044618d065b75e64aed289de86893b3471e52d83afdc5807ccc2ad9c9d37e3d28a9b5fbf7485908270851187c7ea8da0f063cf4357b82b1811325614c78fd6f14c0bdba802fd45cb43a13f38edec1dd552c00b726dd765fbc90a1dc0674f3d37c44c2d3f1552230314d070f2d704935711fe8401006502b7abb636f90a83ca709b1b6dd09a2c74d1587fff68cbf240ea673a7e3afae4f96e2830c76bb16c39ab1cd9f1d8cb3df7d73eba2458e3f89c597ca78e2ffacfe363d750045092e4b55caaf3100f36f538e04d752f27da7fe28239e5a3cbedbc4dde6c5fb82eb60fc3d4b3b21e9f8af774a5b73337ce176bc17862328d13288be27fed49df7f6a8cc8a933fa63c4f697b5572450e39e2dca0cb4081426164ecd1b1e4207906c8d862d5144813d85ad0ca44bb4ae09488197126d2864c39ce710d4cf8ae0dc77c0d77b1bc93ea5a5b06c19ff736422d9789c7bf3acd3ff84962b17991f9a74bafbba0845e72cefdfe26c6a0c7395c162525f43b8dbaf384616e1753d735c2e50203a98e0a502465c306a4050e6e8f94fb5f2beaf02c33942506ed93ee486d697ce12f06b20a6f65a129dfad068467bff0ee1a8e143e7a820501cf6686ec210d9e8dd74831161cb1ac6ee1fa6df06dc244e75f037966169b6a14b77e166620a6fd5ab5cc6f513eddb1e5e38fbb8a0b97859b29ec3d6eb88fdefe325c6f0c875d2c40439ed8c06ee32d45dac112474ff5f62deedf7e33a299a650cf53b835a4fde8844fbfcfe8c538e25a4cb213352d568c904037092b393e8a97265077cfb937341c5664d38e6cc4776febaa53c16560b48b3710e4e8ee99eecd97bcaf074bce4bf63091702e135378363b28b4bd9a69a8cad68294a8302942acd433e9b4cfe1df2bdeacb8fc429138ad6b76f50a17909dd034d28041904d7e45be663d09913bf6b88552d2a44fc847d275d49b25ddcce1cf267bb7c5e00f9addeddf57c74f040fb92bb78878354858eef9edce2f6ee3d2ff60bfd7089947f1b26e17479ca0fb5f0fd199448ec8d31ed83fe309e6e0520bdf90397a4c7761811d5175b9f9faebe0981db035f334e1d8c38ac1adde89316e5e14bce0ffde0f6aa1707dcfe57457ef112a925f9ea8fe77779eeceb26072126382f2b174199faa0e80930e359428929a0f5704e27fa060a1f45acd9f2b50660db7270a9b9752058b5e97580bd1a0d9af2de60d196a296a84b237e6ad93d26f1eac01d16fdd2a57b3dcebfb2fc1d8d884b064f303800326278cb888de7ece0e871d8b22c50344b648513f5bf381b04c2a2b3bb4543f78ad571dc85987cf38ef410f4550487d7842c1157b94d7ffd4841639a371dff84063ad5f554d2699b28e3836b8269e91feb32fded5682360d7f9334a986d7bd20d6a10c183a59f547755dd60a79a755bd5521d3339bc126ef5f62c2004e666d99c1c211fcee909db36754223ffe47571d137531034a0e1ff0cd71b1f3ae7a37f6d1116cc921bd7cb85e9d917989854e726e0e21c376a3a6ead188f223b53ae5854e9ab52e9f221017617cc68c55010a4a205441827a042218e4c92ff7ff90554ef798e84953e0ba29cd77d3713bb6a9e3b229e42091a64bd3e7b0fb2669614e4f9dfafd589e7f6701f8b1575e44ec68e8a8385726886748bb1ed05cf20e794496bcb348855265af6ae9f2a7ab63f23393dc09111481a1dced044722b40165d8dd608f5036d7886ccfb5d3fce8f9ed69c64ea2d8ab68f154d645b916a359916d3fad10fc1f4b5897bd6dab3c146931d6728abe86f9edf98b66299d9cb78f53cc6e5ad41a10570abc6308097f092afacf2dd94c7388a7dd72e80e72490b2f88dc78e7c2f7ef800c9ab97272c1d946b008e0da82ea4cd5472eb8503b99504598574d4fb104a79f42d4fd4c6a2aca3625677ac4ee59fda686e5f96df42c086bb349cea2a982ab6f11e78a0c7624f5c1cd71ef2822e63b18a8ab499d1c450f32285ef587e219c1ba9cd73743fdc3f5d8199864363363b7ce0f55e3ed61aeb84e969b5b23c278411ebe9584b917496ca1f6dd7afda09de5ae135c1a08de544f0449a55d9361f86f66957625f259969169e5832492597190a11a72acdd1bc1f8b72115db0f589ad5625dd4e92edb2f3bd58237fdd83c9cbde9ae4bf852d374c00b29cb83684e09e8419f2f66b602d717d25099ca4f125da47e7ce750950dbcfd8d602f8ef4e31db1791601635b2f41969e33ae695547bfd2cdd070588f545ef3e1eff6fc2be2bad19b8789f19158e7ee6943faf057e191790148b156177ac0808ab520ea918672917b6d2274b6991c6ffe42dbf5544a61e073008da97535ee1e08510958871c14e2190155ab82c6040cda74a06c740f1a7ae65e28509534253bcba418427dd6daf9e2616b68b6bfa4451da275779c93b0385d254d794e334363cc894486b4eed5fb5bb9be753c0ef83bc28aa17ba0e93c81bb791404ee11aa172862167a316e00bccc913449c22539dc5c6b7364ba600f5b38854e7472fd451d60bf4bcd3cac6c93e13a90be3a0fc1bd5ba1608a65fb4fffd777b4b07bfe89fb4107bcf9ec0d09665f47a8d5cca1254a80a5456d0d6fd27cff634a98c9b6ebc6ed1cf910975d7a6146da56452191beca2580c0482dab32d4d7aa92f88db188a9d24b12118cb50c00ba06f155dd11ed13cdb54c2c3f83431258b171918c3313d8811a3f0e3dba34b87444de7c2f5db52e1616bb54e32e7ae74968ee17f33cd3438a9de5b18574ae82137155f011c2bcc781f3994a12976eb23a8bcda18749b10d5e54214dff1b5ef9a44c0f1528fe9c93f5b23682c90de91fb0abd8cb4493dc84f718bf12dde2a26153d7b24e7f0d0ef5b73fc7e57412ab0f6b1ffd74260229e84e178f5915bad4be887dd54005a9bba98d1d40aee6fe843ff96d14afb58805fcaffb66cd92c46a7a17deafbeabcbc1aaf3b6f02a9e1f59ee7853be2c4b4d9289f352abcd3a86dfc1f43cb337184a88b8ef66989853e68b22fe9026fbdb5f971332ac3cb6b8a423a769ba917741a02d291d9bcedcd576945136640ef1aa2723973a75e897b1623e776da2ca9b55f4080bb0e27a9f9e9390e38b41b0b5f3b64cbc19c67bbe84ce94697d37a8341029c256b12d4655103f7414ce68038f2b63b5d82e87d5a873339ba6a1ee1541fd21c033a6d2209233c5ffd906de7475d6564deae14a28e9841fe01b6f53c45c1e9001702e47b27ee12b7fa61aafd7f740d81f39185f8952f896e8bc7d84103cce821d6524b036563fb6cb38bc5103195117706f28b209a7bfea0b316ce221c043388b554807381ae99cd60f8db2b11a268eea0ab8139ccfbe122d0973bdccd990677e9e813ab81aa4208bb6852e5caa9396b6ffe691579ce6fd3179908864133bda223b0b2525e07fdd9a5a0a18e77e57176ab83186a668fb82c7d590edcd29b8503ac1357ee401c4e105ff0a100dee9dfe452bb56c4e1480fe10fb3b92e7663c23af53c98777da20ca5020732dbe8975adb29e05aa2dc87e98e0a7b41a9fb499aaf51f953a0433735f2f2eb1b4766e0c23d76e9f2d3ed9b3c61fa017eef72c941af72d053c0ac0f592a4995b20062b7cc71b08aa5ce1b901175a1bac54245c411a24eba26d2e4da3bc2990fa8116b2be46b120c0104092d57de5bc004282e59fca7238622ba17b36c6f8606232c58580a6ba656293f85a359aa2d6f99a07bfd85e2a21039741b2378f2e8f2c74eac6d9d303ea1a733e371b89ce4fb287f93672e2410ac92aaefdf4d63d5cfe0b9d7dbed97b2cea1bdb26a0418d639c1089de163a41b627c0a8864d6eac3fec79f1c898845ee4bbabfff6e660fdbf75bc4bae46b936331cc7e413f49f6cf57ff7be50c0517982263a645e12f739f5f36790bc7579e190edd31f022450795ec8bbb72fa68bdeb70dc8ed1bd15af697bd3d1abd8f251ea46e18f01001ccb95eda946af11455cbfb7c299253617f506785adb059e54918f57d15b18f663ac0e600b4a9c9d575df85612f2e576ac840ddb444f6e0c83c5f86adf977475cce67f382bf252398fe03fb88eaea4927c935796fb4899f2632ad6243f4b25e763297458ef4989d2cb507d75f5752152df68d809b3a05c58cb46d4523b742bfaa6491b5f92d4ff11f9fec4b430a19153a35864c7d8bdd61609746dd2bfdb7240d3ae4c96ee5a487a978f36a7ef4f6f2cb2abbfb211af27f73578e138500997fcc762eedc2f17e62728b5ac9c4fee168b00735b73a9baab000a6a437d0c0fd17ae8ded5ddf3676c57a305f45a2cc7171264884b39e6863e3c223771878c21ac484c960057b580ac3e47e3bb1b1ad1b4c934a6941ac361bc0ec68c147b1a2749a17b395490d293ecfefed04f0499a0bd0a75915338012677a0f2505f396d89045941b12316ebc01a8a9e0faaddff17f988a13a94125bbad7a8040fa90b9c14d7cfd6b36f7e311a36a11a6c2ce758a2c56e3fd93fe8e8b07316381257fff40acee8e759b21c4975aca5337adaaf08bd225a7b7b0101436fbe2eda05564caff6ceba78cb5b976950549de250cbd75007445676e04979d3db626f50d69717d9e53fd16b925743525c388053fa7e50492e26e309d5d3ed2ae5f18bbf21d70a4cce2f643810e2476cee26cb6892dc69f957c2cbf1e3b496705ce14e25a3d701df555150af3e10e9fba651dcba27fb2820b275737d7c1d21c853d4ce45454e258bcc8e965fa6865433f72d9e74e6392d6d7f116edf145bb5b68829a4dcb009ba0d95593aff89b1c74c55ca5f378a97b42b8e0bbaf4ef21451b73127ffe91bd238d7069631231dbf36d899d685b021b2302045c14dbf1a746c6d8e14b9ad05b5ba18fd1438cc626c4b1ec835e710026f8bafa51f4e7ffb0098916c29ce5d4660a73ea29f6173a5c5229e20aded7478da687e0921b3057d0c8dfef62fb75826a2ea943bf368b0eeee6f88a8667c35dab2674c5bf033d1cbc1728aa82b9c228e2602473d22e51f955cfdff9d48778d91086c803c6169a7f31a52c2c4ec6209dcd332d20f7c2e871adc302210e44422c96cb8d812a512595939e54fb53893377f3f17196cfa084ed4d90f89dfea175d377a1b9316489c0cd4259802299a50aa166812dce88e7e4d859c94a46c274246517a7fc27ec908ba764883160b84ec0b77008f89bdcd15af2df6dc8fd29a630a027b19fa65ccbe5d59031684dbbc01ac68d10e38817e924031d718187777c8c3623b4a9d93d3ca8bb57f1c5c9d6c1f6ca7349754bfc98305a847a11dc8036a96137820b6f849ff8b392f47faf7b65513acf45d3ef17378ec1a5dc7cc649fd0df5a5e0fa1184addc3ce80ffbe0a91c7232c199ce1219aeaff119994ffb059358144c4404837b5cd4c5e4c3c2f51faa30fabbc33c92bcc9d158c0bee29ae59d6303f586a42806558a1e512e785482f71ee50d2a69e9004fdb5c52a05882383be7bc4e2bbb6a4b7cfe1790a6dd38be15ace9a35fc9f271bfd8999af4e032c4ba1b1033c504e224eab3dc56cc40a6d4820c5c6f505c52ffb982bea23666d40a311773eea8cade825880217d1febce5cd2fb6e68db912256a64bad4ebabfa1238463af02a708cf92d0de18292dc89952a8d8e7e1970b671261fa6a2e14768d6082096008e8f4c67f0ca920da2dacc86bd977f5cc07bc0813257e65670407bc3ac075070561dc1187002c97f4ffcffbae4e3776064fb61a7cbf252b122fd0e730e0f0004e6c302a536ee8bc290c831a53c453264d769387356c4c5d0abcee0cdb846ab813e78fdb8b4e06c7a514928876b5724f86e3eb99d0f3d4bf38c9d75913cbb930e21fcdfc73f82e3c017996860d03bbbbb1d6401c2b9ae95010991275071445e5e2af90e1427d4f809b08aeb92a42f78102af5c3dd354870c77fa0b3d1ea6de30efb243b8e8996da82045c6cf6ae8f83f4dd6902f9c7503c2014e7136779fb85d6eb5198eee166e8d7d700acebea4cae6951a23d6dbf57ac31522a88c21d175b41d8e4aaabe37269d45904c025089c902095cbab3b6fb4678e395e3517185941046fc901f6be12ea93a34e06f8284038f4df061b9bc9b52739be22bc79c0bd8fcbfa1394512b008d97afc68f04cc586e7d1ad0c8e7195a7c20fb88ee2899d9115764d603e614ddd35c0a31058d0387002d73ce568a7a6a610a5ebe9baccd5b3b8cd4390f1a9fe69ee0604cbd071b7044eaf6f0ffd8fcbf76ef28f9f5202fd71c2907caea9b988f228ddf2b321b81003e22e3ff50247f97f5772acf07f5fcc261d5c2901715a1f7d113dd8eb13205fb079f3734364ac8aaf6b1940af3f4365a44d5978685bb2210ec4c65059bb1d057dd0320a0f57d9182825bc6fe305d6b5cc7e92018e1425647f92e0d9c1c1d86d6fb760eeca49dff6b67909a8f80cad30dd173a7d7193cb7745ef4e46f13dca3f98c221606ea271f5c1cf8be098c300de8720fa0d18ec4dd288a5aeffefd37c5310c49dfbf03fe6ae4d893b393b11654d9f7ba979d45c1255a4c3c35fe09e5f8e149c31d082b06ffa6b7dff39653ed7349f8247068d3d9048b5349ee8808e0ca37ea4183c765ba81be42fea4ea802c7b842c06867db8d9ea007b90f313895460b629b2602a1f9e52efd727b7568ab65201184d818ed45741f15a46dd14fea234c87380269a529d0e3efc14ec479f810214cf966666a5390fb9e9d4aeff6043aa72bd4c1672a9a3d31dd6f55e395e5e2ce0dbf7ead5040723b97683f5b61f3c0955191fcbef2c068ab0691ff5551f299a6e00344ce835686f6cb8cb9e1cfa3ebd5aafe2e48d3b8d3d00220e22f6d1e1a4c33c5d56f95e379c2afd2ffa860c9124676527fa090f6455401c37dac61bee1f5f5e051accabb8890712873f6c4360f6dc3732131b90c28f0d0f75508127c356347e0a2d8d7d0887b7fe7c35e4b10ef0142dfd40d3a8e52b96e5d8dc53096ac8eb325abed71597138d8310d1c722b007adfdb2f2d2741b474d15650436df847c65f1d2ef311d86cd01994c3482f01a836e93c197cfb40bb42466d1c1b7249994753b82efa14c9077d3a004334801f81ec7b00a2eb61b31642c77e8f81fb05ee402011a4c3f052814f022d5171314e01f16449f79ce255d700f5fa8f0138f29f1e630c58aa20075f4e305782b2286015575858216c2cafc48299fd68f5ff77f728ce3475dad645e5c321a366857e3653ac01ea5f57df3c12f39e826b80c630e9839c733f728ca578fb1b71080eee62152bd231676273e43cfa685ee29709e4738f1a39ab48028af723a2c945b6b276d3c7de4d717f0852030957027ac13b749ce60176904b68b227c2003647c53fff1360a96859656d309dd0f44f136fc1d11aa5c739d3e910eb5d559cf999ce189818bfec6ffcf061a9e5b3e8fbdcddc283b236d82f0db697a131c6a5f65d6a101217c5d6361b69b273d6e372079201e4927b9889c267faf56c17c2a73187e50879c3dc5b56bbebb0fb9641ac8c61a18c87254fecc646fe71dfe71ae7558344d63361af1479f9e0a415746628013f817426e8047a0ed32386146842405d4831504031d40641506a043ea0aa47148fcfc0bce4365660f18c0f83619865a5dcb16cec597d5d54daf5117f2717397bf0b1a681c9a1eff638f0c78d6c1f9606dcd2418c7a8846bc60e9927371da9e1dd9645a58e3e7b54f12f81421180b63c6899afb3e07f8ac3c66b88fceb7f87d094a705956b76b37ed17fcb49ff4e7d4e39d8cdbae375bedb7cb2d3b0fcb19a2ae1b5dadaebf402ca0993a0608a27c5ab46ab2e8d5ad2d13aeed97887f2d19b4c5a36c6763a1e9c667abcd08d81d87b259985f7609d6430a633acb0e4c72821365e230b327165bfc639cf38b775dfba52045cbf085d8a51b93eeed71920fc21723682c1999eb338ffbdb046f3b8c74681bc408f12f9b9931fde809b8501b10884555714ff79ca594017794c0d7906db5c6132f9f4ced5be6797f7f75a0dd6539960eb04039704184140428e951c9f0f42d8eeaf5f36f3e0bdffd88b8d07d69ee79f29ca20690036b7d026e450505ff43b0b1c9005d839cf811c938649fb815dee7bb7eb6c4ce93bdb5f81416e1f906458a967d2699e0577fe635ca968857f8da45bd0319bc05841e5cf97fa572c76fe679baf4a0eaf81d395d8512f9eab3a159a66d19bfac615038e99771d37d45cb8f69407f607f5c10819544860a5335d83f0e2e7aee20dafdd253acf8e68a5124f2faffa312f2a1bdc71dae84ca5c5b384083d7ff7aff359640fa70b69235255989f9b90f6277bd3ff19cc4bd301e49a589cf918aae11dac83d4fbcea4152d66e07e2eae430fa6bb5b984c36995dc4882c4467d6145bb02c5ad412d7083e9d59fafa0c9b20887a9a9ff3e9ad9f49f3b59ecf4f8d30f06a20a87253773244cc63f764fb26e6c9de63be709ffa0df3023013ab6b2f861f28c7c3743a71e08aa65273cdda1d608e03cd0df2922be83e9b57df3ca90182f654f2c401c0353dc02b31a2b7c8b8e001a355d9f7095e0d32967b26e46c6013e037e115c6174dc8fec8f6a20dfcb062114e032f856fbad4d3fe9d30613ca7d0dfc589f29789aa3c163afa75768477127af3124f10e271aded1b23656ba6dd3401913f94ce13142edc4b51d7a5ee9154ec268f24158d626f38b3fcb396c0d37eaa585c8c31537ff9b27a01871aea7e137e8a5559e84fe909c5ac5c76035800458ecf1edc2274ccf008b3d4ca045e552559658d20cb4d80d98fad248d87e6a903e85124b5925aaa457a37880a93ae68882d72ecf8814ae312b389ec8627d7347d5fe2284314fe4892bbf60afe7deb860d4844f896ca2596f9b8fa3ec9b56f160d7c32b395ff37d12692093043de0780f3239c5354766936d14d4e14a30e6741254f4d48c4f5ffaab31106c6fa6631712bbef1eae11d605c709dc07993c425a75946fabc6e1756b1153f59ed9cf7e74b1df2f0e404cd5b1e5bb11720ec9289cd7c4ddb857923d53c68ad470fc6894d3813de322111a9d8f976a3a3d51e04ea55dd41e260e27943415853e484abdbca82fe8cf67f4c6cd0342753231aba7f6d652d4a54403d09014a9d8874c4fbab1844f5267c180768e8fa556a98c193afb3a9aed1b6db535b42e1442f412e9356ed16b33d65f80775894f4e1bcf79127322e739913a8a0364a1596dc812bac98a5fd4edc1619f085520e57a0e0759f209638945df6131f1b5c8bac16ffec1f45dc3892fa403215c2bd98dbd482d96a41efc7fac6121ec317c42e7a9378adeebabbcc9efffac6d18a5f4d0a2f8cd842820f0aa1b1b20f7d79b0fd4b7f620d237544c7199c889674423f9a4379983794a5e22fee4a501fb137bddd6529ceb2d44a69290cea099e0d3d1ff21d958d0cc5e9fdc7d3a1bc37614f290336a56a6a86bac97aef920f8d96dbca53f4e8488907c5d99d52f222127a6a614fafc2f0adc9824cdf77e10d8fa7ca10501ae25940c014127d760511048fc326f41c00d8c5908018103b78025080ab239534200705dae020420a8422b03008e4c38980381c8f39d0a00d8bbf30a04a2d79d536720e8bf68b496c9557e774b5ee0593a7d30f176df73b2ba5213e4f47267cf3b85d7c1d278b9f86b2a4152df6d7049cfcff892a0a86882facfa8a7eb3a5cc5b3cd10e89e88a1e058b10e708d5178d0eb8cbd029852c867646f1444f3fff6268b7c44c8886acdc3e0409f5345d9b85c01b0eda51d9f3f2d212a7ff352012fb88e9c35d3524737af5cec455efbdc78c5e8376438786b3de7a69d6f4dcbadb48fecdbd818cfd26efe134c264584f645daecebc228a402de1fffe2408fc22ca351fd2a02681259b1bd8705f91cb718795a4983d2e9bfbfb2fc59bba746e3793a689e88c47f1a5736e1143275f164d7d86c4b8b9b378725267f135e940de2f435e3e2e4e1e66067b764e560e7646367e7e334e330e7e034b3e2b1b2b4e0e4e4e530e3e3b5b4b6e231d1d3fc3d5da4035e1c7112e5035641b953cb8ac5a781a27cb91b9fba3b71067026a17e40a09f55aa22795eb81fc58f3f6f846dbda1162b327e461e5b28ea9cdaff7eba627a1237425577746199ebf7fbd3c63cbe2617351fcb9c41afb13b90ffab881a2513283255bca99d45f38ddf6bf6198c9eea90a5047501c81053f7040ebf1219fccb56a04372407e3b6ac60d54fd30b71bbaa9e3119d172e672e95b81fe271a7e1ebcd5fb16993ec1db634937002408a86c842509c2b4f203b91145f59a6a676eee5c16debb247ccfa9c58f054fca8fbe14089566786a58fbedc02c51f1baf1107a687aad9048e8d07b46ab78971aa2c198b17a17e4a9848cfd94cc4dbff49acc7724fee3555c2050f8a3f395a42ec075ac5c31e3a682f6557856491b22e8f8cc8dabfb85db77412df7c7e5dfa69502d2fda7ccf9f5ac7f33b287424ce059c0ec5f62360e3350a413f27ed0d4d90e2e693a5e2e07d13ec132df87b776716bbd126db42a33754079ce9b9d800feb483f0d0ccc699385d87e09849c4a5ea951cc3df2b79eb451bfaadec21b2d2527a782dfb744f78ec3b3ffab58b75257cad39c3e19a8ac37dfb22db12dec1081124e458c9f1b199b5a6424488c62308dae77319430de3aade58374dc81ec644377bd2b8b390d55a0bc4d958505c485184f11b1ebf69cc777d48dd0da970ad1a7dfe5d8189104e8e957a269de61989f98a8e7e1bcf2ee5cb61c08cbb46478d08bd8a0c7bfbb942e595907e29229193ef5ce6e9e3c78eaab8c05e1ab812493db7e7f1e36b2b6ea2d7855f567f5438314201151258e9cccf58bbadee2a7f6b06f1eef05f4a280c4a07776b8121868a2c98e1213c078ef18e51f325ec2394c0b8a154bed7d588fcccd22f8abc62a92c556679b89041206611230ccef4ccdb2eba4e57a228a04f6e13d2ebe6fe85d14c378ca43d0ca7c4f0fa55ec93c2488ae4a1c1dbe1987e1d229b02f1c9c4d3b252f93d014ae831c967efd14bfc4f9cbc1a442c7f641d2c36ad6ea84f74bf3dfbbb31dc5512f4d3e1cec7ee938b3abd1e9f7ebe3ec21b9d2bd685f1b41136f35d1b2da5a456f8dadccd1c4ca55d66fb4aa075a4a1830ceda621885c70990e82c3e2dcb3e92c2ef3b0a5026573e6d4b12e3b235f43e1d5a060b9671e6af44e66fc1e46e442a6df2039942c78f5b0ede083d3aac006cebff61e7246160832577c84f9442e6a4c4ed72ce4aa60fb3baa42adaca2dfeedceb0cb79fae1fa2dd34059197b465a655638967b677df7fd0c6d89db2282e802148d0a34fcefccf19d775befb6efbe7dc8e2ca9eea857f6aace666b1b2765b9fe2caa9ff7923980ebc748e8feb2a6ef8ca82ad28c3be67178771c6dcd8c9952741ef05d364a79866e1bd3c1af6805833bfa899ff863b56384bc1f0de1895ac597c73430775ff2875b3fb5a1ed4fe4b5e334b12d8eebdc88beefe98dec79581d7f3f52a780907f1eec25b395790274c90c8d1ae9189d0fce3486a928eb8955163334844e20dce30bcbdf232c1e403b2a24dc9a9f4c58d0d944c27a94d6780e747b6b9e9a50d28c896ec3119585b0790641442297ac115ca8ae87489e5117d8d4c3e7139b1915d5a178e3c1a3620ef825137622120efd8955348c69a427edfa9c86e43f69e8fc474c00edc2e7021944b9b6c190188477682e00a3d8a004e2da31509fd55c9876a2f7b877148c4a05806aef34fbd38a9762d1046461f4f700f34558dbc197bcc6ea832b336ae28d07c2b8b5cb8013cc33ca5d02df26241b298cbf8b3d6c872d4fbb18aab1d344aa48e9be29651be3e7bcad2c8d0f5b2a5818611fd990767176c9b4f252517c16d20f1c4f927e070610fd6b40b6657789b0d624dd813c8004701f937c4173fc63ee03929e466df69fe6766a09396d5fc845404df27d1c9656e080b5b24ba73f3f015103a39f42462a3e4d2666dfbb667c7417bd8b5d1794b72ec7af63f73290656797ce180c6208940b8f25ce713d4c03c1c1cb20009779e931d0a9381df374c977354384d90c04dd9f8183f99b14db8163c897a556f403017f8fdc3bae53a9d77c96f2919717ab4e8a9e6f9a4e2d7b5957cb05be20bd926500abcc23306109fd65a75144bb5a6244980515926c348258b7c818a350c05da58ec6fe6520cbaf569b91018ce05ef8cf5f6858765175fa275fd620c85f4be7fcc73085e7ae0b84ed507cf090d6c439d0ad44509171450aef7d89c5328d252e898af8a991915f174554e55f6981497123b105b90f6116b78495571cc9155549a37d82cd4bf233132b9063b6e5a4ce0a6704fba7fd831280aec443151608f4da3ab0b6c1a068b5e3ebd89308d4e4c63130663de84cfea38a09bfb2874fa1d40fc3969be4c65f7c69f7bc4b7cecd2698913430f54f4e7425feabcfbb221ede1f190d46217deb370777d34c7bce03ed244bfaf68a6623d1388bea2b20d67a36b5162d4793147ff05261858bbd8763a58c008c59f90193604e92f990a7e8567c104a39c2da38b07dcf26222d45f84f8c898ea16644d686a1aa6069812a52225eb0fa59d86271baaea8300dc7bf57df3d41bbeb02eab9bad0335cebafa4a5127074226a00356487c160b3e7cb6be90dd1c06ca080887b99ead13c6bd6097262e66e25894e480156e7d4162d56cd9d9a84e4411d20c02abcf8e6fb041923418c40603bbae9af85afe7d856cf0796ad7877aa7f7f8862cc2d492999a9f5b86f9fd6f77ac557a740915c0750dcced69c7c7a1372b55b96a91b73175877046974c35344e0a6b56e940de864fd94750128698391e2ec8611a6206bd6a4c278c6efc98bd685fbe155a6a4bd1296838e91442aab4b98503c960216e30eb8ef32f688246a18183c4364e12840d1c2e201a2dab035e488e406e858b350071b1aed44d5542d30aaf0434f3e9c0afe24b72ce46b47dd1251a5d0765bdc21a60cd4d91d164a14fcd0d81b0528475434819cffaa93f3da87e8b8dc8f9db2d920dc4b5abacb5df6e18b03a32fcc28116e425d8a7758eeb5edab3eb90008e65e5d8eddb2f7549ac38b80883e0ba9002524d8b714858d20f9a120e4ef8aab608eeb80a127741200dea00e55bde293f7ca3f9224d8e81f9ab588516ca7a49820a32a1fbc760aed1954d53a6cf3be01fec9e5775cff1002f8c6d7231a8493f124cb77e61de449cf588a50747cf9bfab04cea027e45bc30b4d9d42d362c5bc381b8e521e9df3469287d063f7a5979fbd0b72193ba7c99ba3621ede5389cea4310d400c4067f54e95647e315df3c53a4e73bd6fa10c97bed768e928f7522feff65d5d3250224d66652ea2f9c33ffb8f113d081f695359b1b7b21f85da59712f02982a6a752d84c048968052a39c95528e99c9d962fa44032f6b2274b38b4ec0a4cade8264348f3d932b5c14c5c71245eeeec30e305500eb8a5267343f3528ba97f6852069c6fce7c39fb3c64ee714e40b0b1c5578cdf7c74269d1d0624430c87acf4f58761ec71a6fd801de923cfecafdb50bc10dac141c6e377abd20cc9c446c785f4fad4da30c41b822b8c054fc4d4070070aea7a05b1efb25455f6b5155ee802d75f6493ee3d08452b1d253346c7689c96b4ac0a9ef0cc0add2b812282d37fbfa4b10d9ba4592ccb32a68709f288904d5eae1b71f14a710c6ad6020cb1293ff8c91a7c8afdf96a63b0e170708588bd9e99b2437540870941aae058ec706b2bbae2eb494dca4854b25571550e2f73f855238d4f9bb098565ad67da0b4856817e84892fbf1ad23ddf173d4a80751de73b3077988a05e2a3c705ed7ed90c12cedb469867a1c770240f7dd1b00d0ed334d43f0d8a6fe391ae52ffec5f1cea4f48a8c1df06e9010be6f39e7b20628800142a15f89c29942b322e8d92b2a02f85a9aa07fe6252935c01dc8f26a5cd972a70fa2da5e7c32d27d4d4f0bf27654b686958492bdc4ab0ac78cc30ff7dd00520117ad0040df9cd8f12315a5d5b1c7ac369493337f71dbed8853d6c8381c03a3229d79f61443410690080e830d0ee5d00a8b52d05cd3d643c07ba096d17b4baaf1c040997b1bb9662e30b8281bc23aa3c738be6f70dd75ce664a57378c2f0ee575ec484108e21030ba8d885dbda014f28a8fb1d17c09bbef0e0fd365d7051d088f9a3658376f92357afa944098d16fc7069c5c7367379587ead14a5457e2801a4e42ade62aab62ac7d2939ed77db45198dd401401dc599281488fa9b6f7f4c6d6715fb0acb38d6272c04eaa11109868d1450ac898a3b2c2fcc4bc87bd5ca6a4608644dcd580b48131c6038377240fb1c0e1bf5fcccb4ef0a670017950e96c9c5fbfdc76d2fc6a3ae8f041376acbdb39f1df6fc1a958931451ee904cd62fdd43656821eff9d2c18fa5ebce2c5a91e34cfcf6760a1de074dffbb017dc163343754323440e3ac99efc95e3a47a85faa082e5ced1c13f77868848af714bdb2bccd244f77583782a32e1e72c3400311d2d110876cc7888c1b5eaf2b90cd3feb7180c8f207c31ead502d1d2b39dd4d64a3e0a75fef4eaacbe014e68c0b9c14d7dad54f3e39e9d9eacea35e529ef37b38170358b45fcff98c81a94f4a550489011783ffea93b5ea52091d90d287164f6765a28916c1eb1b3dba5a2df7030e9d75aa417b6ef840100c37f8d246534c8f0a0ce2a79f2e020543ab090f7d20a41116a6c5246b4d4589bf50f565a1e0344b936357c9cd569c5165c9a658129d851bba2a271315f77a98339c1b0742267a50a75204eba5213116d4702697a36079b9f7b8747b95b84e27976fd5466698cf5b40796a11344902067801be2f438d4ff7ef8ca358e38b18cfbc88b1b5b0f5b567b45a36a449b099baf86b98592824b985f17d0ba9f0a47fe776ed286e83ac172c5318f3bbb3263ddd90f060c36c11fcca99f82d42a0817ae47968f84f2c6da99c42fce523a94f239f08671802ed8c01eb17b21ae19c1ab53c917518c83f05f9afa6a71068e3f05089372a6ec1dc86100ba3a3c8d4b7134b5f937884cd3b277afb67f70b76d749e757411805d4bbcedfc1d0da25200a8be42007ccdbf3e352ab24fec47e61b2e5f3adc1b95024a7c50affa4aaa1aa57e40fa779d820bb09373e417760ca48905a435a966e6fcf200d36af633cf1680fa88a9e3aa20c21ec69042c6e00afd9abafc803e6625214bf5f718969a423bc4e8702f8b9be5fe9dad7ee38ac1e1cd8256d9ad55e420f2479248e8451525a922e7e0fbf3c335631eca5cf1e9b1f6902550f04c420f3e4bbe1114bdd216de0cfaecea98699dfbb29e7af1be1d87af86158108a07b5035878f505c11fc72551f76fd8866eab5e53b425fc072600c94367e5a8d0fe03e39fc456e2feff84bb61bc7ab33df2c5c766d9f7056c06a6156726a1d9e78786116daff97d961106cbc468df8ccff1cd5693c4d5082f617156e599881cb60adee50c3f4b8725e5de63a5626ce787ce2e267e5b70e7aed1bbc17b005c154a3983d0f36118d01de42294d3cd8315b4b0d1e3e6f4ee8dde76962f062d7d6ea51e2c2c83c64e5eea9e1fdd94a50639d312118a1826e125672b8160938eaa42dbfa4c7e9a9d99d5b4857feb2c88c3e16741f3498064d3ed7152cf165c9bda27d9ab7d98a29d11773a70db243b97187d9c6bb19ac44924e6fb93061a59e4955aec6da6398ccd960a0607e6c687ccd1a129e270024e257c64e355402be87272bf0e8a5309fd7e04e6654e2af521f455ed016d4b535bbf1795cc73c5b72be1b5a63654d5e0d2a963ffabde1c368ae64213964e35538d8dd81059f591ca6eab9952479964ce6ad8890ca5085e2c618fa6579371b3fb72191d8d1bf872b54b5d697f79ef0a25059abfc2744bb690e491dd17175e7c8cc5a632ec8770ffe7f27d7d010afa5c341e69f0fa77052f43f48a64bd9171e122615e96b7ca0468abd6d2d1f750425a82d0e01ec74d6e8fa357882fe24d084d78fd03f8b843a93b2312feed8d089253cfd4e3b908c890d094a478b57d70da0b9406e3e78b647d9e7e3f1d839edbdd13265c919982515ebec8bc702771486c99fe66b959cca6ea81132d2575524a20f32d0ed9be3e0908471d96cfea5c59f54482a2afcb6697f138d674604ac889d1a8bc07dcb9a7f148c825b109ae0d24be7033dd5d54c6df68aa4e8a4bcd002e59e05cc21ac0ceb1919b399ee22a20824f703c9cceeb07513fbcc254efb204cd3a2c8d2a3ae42efd4ddd29f43daaac8f05d250f7218035986af1066d674a508cb478e31da742febd19eeb7e39f29839e651d6e49998a3d6b58f5f31bab5c0897fc4ce41f0a74274052be44d28b4bfc259abcf69c406dc39a459bb2923a13b2632bface5f5039a682ede10967a0af707be49f15d1a90a67a4c1ad693403fb5c767c254dc06440adc2caa97fc6d7cf8815442c029883b3d97676182398c7ad81f5e9a6211ccf30bb701eda6dcf18d4dda2fc69d0a46a2f0562eb7328dc9beabc65e15f3931a8232d15934497678bbf6e8c335ffa7bcf673f9f11e33e23585402ca521d86e9e2fc525199b7565e143db3579d3ef9c2a16dec8a8f618c47b342efec98c7db1486d0c154baf3f1b41f9b3da12590c370c30d82a1b0a57491fbb0cf88e745c7b9ad432cde3db595cc8cb68b06e266837d29afc0c5f71c56d666688515461ba2cbbaa833010627d5ae5408e2ae10043df5a3056b1ec5144914fabeebcdc5a9e2039304035285d3f10b4d5a73d60eba3a82d5beffe4fdee4b522b007ba55ebcc4b3f2de7bf2df77c279a7b7d6d58c0fffb7f6bca1cab97a1422249fbed1355002a475487f79a2dd7fd4df39c1dffd3898b28fcd7ccb51cee32fb91fa4775677a32f94fd204ddee5a343d921842e25deed1b938e1dce6f1b6dd16fe5b375517ad9de165735b59a62d6f644015a786acdb079aea562190883db2239ad7a49314512350c22a67b1ce2b17bc6855fd4a90d5d98f3da5958ea45f7230a70c37cd21fca8b9a895891f06df1883a961cf68237f23df96ba1d87e3be96f2fdb00598d3356557b3f51d76b4070c381d7385804cbc8b0d29aff63c811bd09586da7a49471d20a3908263d4f7c661071000756b98d9bfa6fd6b53737718f92e8c7cbd545cbb995b152ae7ff6fe7d8bf76805601d411f409c2284a53a0114e81e59b31db9fb6bdb6f1a3c00e5b9c07ffce0b65fe2007cc99f27f47a3b95c74018ea6c6720c6c56fef4d0b3ab5543ce8fea85244b70ade1a3bd76da7f96cf8e7b99655b82f7c1aa1f9b24d18d8f8134cce76bda3a2798900c02bf1255bed12fa56e9f7093c64e6e15cd13cafd891828a9915d185d856954e56366f60c8ec0b65a0757e136dfb18b25fab4eae28ae46d349e48ebaec9594575a733e920f176451c9317dcab9f0ac72186ed707193ea942483239094b97214a523a1ff323d0d7eaebe38e50d8cfbc9d3c17e9c150936c238411cbd61dd84150892b8b9ad24056fa0f202ead0a83c903d0aee17e21afe08d50b6cf9fa116ef6e60c403fc97be72b768934736ab8e24fd22690ffe7a75eb56174c15d2f4b51596d956519d16fbaff984b44a4682dcde25d518894a4766607757c3076808f795ea050532243a00379e2b479f2553e544df3b4ebc755d1081e1d33b97b7b20230e78ad45a43bd806196dd4ea65c5e5ec9140600333b0e870855d620b098593f5154fc44142b3a3cbec329ebc68b592b26eb4cfb50786c942c5c59f8a2385238d98c1476208c59e96650f75ce3ea0b251d00f512d199debce4bdd50c2b156add44178132fffe4c8cd1a06b05febacd3f40f0c4672bdf8eee7ec45bf24ec722f4d4b7ff56b6e277231c4f41495b45fc8c345b823aa0e214075ac0b2ccb4e9a683caabeabc8867747879c8140409a8326a5491abc21d41401208358c069f6fcc68a15a2bb53d18ab589e733e47f26745c1020344ef5cfdfdf93b3ba03f3ba634666e0513b6d89bd4ce6d3888589e7fd131e03a80da46e11d907dc7e70540a190090ae35416da74198daf50026f67da10e3d18bdda1da2248f35590b44ffe140a887a782b64e179b883fc466e0422125fe84ce69cbe7381151641edccdbe99a2842d91fc11022c70d638d69b678d893f03442bb2140f7237ac89a49a7dd54e3fb8987b50d2d128530025fc327b9b26c11fb4d3e13cc52398e0bb4738b8ef252c8223895f7eadce99b68017a40e073f902b8474460b4f10f9475b826fc61b8f0f9a4003a6571201dc9f9d0c6404713e0d29e63f3f38fc25e473f54545821df17362bb7db23cb32a94742c9eb55b29839d69c611c0f0f98192efbfd9abe42a2007b01fbf4f2a97877559a70ea4605c35bbbe7c6e21599c677c9c72d1125565f2dd3e369226a5bc3f216d2860c17b2d9a06a9fa3d66cf6270b36a01bd072f54b4de1f7f24b327a2fd479919596bc92be500a9204ee6464e5b3301cc4f8d3e54bb81305527542cb86cc70c68b0fc6adea8015483b4f4428529451a73b9f90a6918e7f3e15e9852ea85acbc3cfff33a1b70f8f85d100dddcce8ee9bdb11615611d1b04b781c57cbdb7e41e9e3bae545bf68a2246cab054f4be3e430c6b1179473c7128d2cb55b9fcfe3181595f41010a3a8702e9bd1793ad354a3612cc5b2464db5002e2b020341cf89ade9f3d58669113ae94abcaef08e2be5a55b4349b86f07c6b4e5ea965081c10b03b2740449f789b3f62e25c3d47e64dfc944533f2641dd89d5d5cf40133021138b716b3914625333650f811a117f5b600f323e2e8cb442e07c0884612add3718833fa6d17cbb8173e3272f2a07f69f16fefcf67330e337d27bdf957efca439e217cd9214c790380d188ac0c3ed696febe91c248b31d8050340d024c96a767ff3ba73da7e14fb1db7a399d758ce6be03bf56b941a5bcef57a1d9afa0d7fffefe709e3fe2a2ef2516e5d1e4a54ecf9ff1a3951d422ff681f79f55a6c7a6bbc94bba050650d1b187d7cb13b3abbde2550b5e68344990203dbb1ef1a2be5d9ddee7a772d90700dea727f4b555b739e7091e6fd19f4317f899a3cabddc9f1de617dd1e74301fa00eb275aa5c9630a3022801cc547b4a4122e0b6e4c4413755b5e666db648c6b5c6b1a53e0e5959e7b836fc3674e978829a1a0adeb49b6b6c67b319481b98ba4689ee502202cdea2b96f4df569ae3db4984eff67ef1f9e46bea062cde3106f3c5d58da167f50c69cfcd16af6276f5cc9c12f11711604922e4bb454888d9bad40b3564ee4b38cc08a3bdeb0bef35cf7ada3df414b9f02250ddc77bcaecc8cb14d2271ab371d58bafb449d68641b611feafbf7efeffdfe42188e31f22c002cc18896f60343da6e153046e4fb76706368e076c2ae75fb413be5f6753e6c7ba048835b7575c8a00ac01730866fb8d754c7acad1c53de72ac7664e1c988f06b7ff93abe4dd0fb6d116a4240ab9b18fc06912f97c464a8115cf803d78ee2a3adbfc582bb6402e1ff616fe4f65aa17bfd558df0487d23864beebe3deaface517bc16d3b76fa2603fb1fc39431dcf03e9c549b2ff2b087ec216b7f09cf8be6f6e7b429a88281ce822d2a2fd91fe495d20dc01298ef81933370352961a93923e4dd1331fce977b87e36a346606f773f8aec7db15d174113f40ef6eaca6281a139b8b7a2b08ca9de105653eb6da1deac8ef77c754a1d033d5c2ee190781eb8fbefe3ae51f144945efa2ec787f3000b8e9dcbddfa1e8b2df6caf422a30cb099ff974126ea2229bf13ff660bf27d10c34a7b8399de877098d3b11568e729ac52265c904fe67aacf4fa3ee871fb8b251c87c4fa9a4a08e6ff66fae0dad5896f7dafa948bed0830c7944c62514f33d1a83477dd667fc7d5c16201d01f08e163de6c1d13e8c0f3db64b86563b4aa7c8947ebf1811792939f9856136e02d0fbfb038f7fdd65229ba5fdb0f02d092bb36f007b45a7f277c00bef28efd7c9ecd942a8e2f3c5c4380213409160a3bf06eaa3546b17bc6889276f9f24e69b7714a94e38f177b019b46da5a53e3ae2f1bc296fa4a7e7fdef3173f7a29dff32dfd1d23db0e69b17f6a6587890ea620936ad5009e8e589486b213f76dd371ee56fb9b6373dae42aee5258fbababd2f0ffe3bf35634496135078fdbf92f5731143275eba0d7c77679c21b7e705bddba65d35936d14788aaffb8f44197bed7b37240ee6774baeab1972077b1a2940ffee7c7e5c56b9c44e820e0f10033cd0c65495e3b8d5119c1b4ff8b8974d5333607872430dec43b585e92b35de3cea1ad00e883b09aa40636eb62f6be1b37754bf0901a9cc52fbf99a37dda13f0288efc9c1f0e23c70c906e06a0001bfd35d0de95d9b772a85818549283dab9a113cabe8af3abfb9f655e36322b0240b94185c3f7eef96b225078a565f5373e2929b40cd834b9621ed9e78aaa277b5687538a6071c8e34fc677ac68174bd7854938a9092f0eecbcf52eaa7b9e327ccf47c65b758cfda311f40807d172b066fc3028e540c9b4f1a6d86917ba9fd1ea882598b747c96079f5ddf20ca20a67c3a5dfbba7391a8c5559736a7141a987a72d1696c61bfdfe5200c5b3f2d21f55111a724ffba3633999bed24393b73fd3dd0d0f41ba4ccd65023f1f00ca6152ac39aa7ae1d0e3d010d35fa5b26d92d6e578772f439ef81fb17534da1369f5214560711fc81a5c7d8d22827af091419df92d8c07fb906dd8609e2cd22fd25d97fac3ecd3be0bfd82d85f32bb7c58b902a9376e7adaf7a9fb38426c6e871c7397edc30676dc15bc2bc56f402c985c4b3a00c56f57f9e5ecb9e216415c5d67b0c149153765ba6578294a075c4ad941e2609272f1863bcddff627f2a93a93811db1ea67ed697dba445144debbf48228ecaf22ac426dc3463fd10dd6c9f2a16d6ee2a14c6038d4ef946bd6ca51caf6ff411180bead160af2dcd7a6135cb11084f2c965fac5effbf26712efb36072e148a2317d1b5539384209e95aa7b8e5746bbeaca3803523bc0bffcc2e6ae0fd89c5abb1e64423248a2812d5093c0dde130224a8f8882b976c76c40a2ec5695f1575cf058e5a163e740592d048d3f368898101fe41acda0b2693b6d0362fa11a3b2671f17ae6f6a2d2dd504620e8a960a9e0361620709a48801396b6e6ee316e7802efc7d9828b69f724c94544e65fef84b51ad5bf3e45d5dc2f4da30dd34a8fa540eb400185c2c8b24e8f6eddedeee3c01fa07b69143025e500869dcb3bbddedf777491d82532eb7fd22859610e27eb433c005942ef9568e37488573475e138fddd7b98fb29472d6df652f1f93e029adf65a7e4342128f3d50d6f1bc232533e9afb0869db71fb2ff45c35c5169256a571f3727799c222cff7de13a3cef3d3968756a79c127d270fcd87e37b6ee012519994950e52583005f59401bae29c952b3fb81534457ec033b083e45eebef44534ad2eb9f0efc194fd3c87fe428fb2bf9ed0b97120f97af138648783bc09df8b8774719f9241fc4852e2ed67626aeee2e202e806d521d5552583e6fbf3753b4949e8855d824c6d24331f792f67efc76e64b2de9c8950eca981a19300d6caf2039add375ea9e8ad7f2fa88304e42e789cfcbfb3e17c2b0f4522357877d4bd9c32a43c3b54be6349a83693cf65e9675d1744c0e11592553dbcc997a6e046651bb0bf4f1eb21a08a9857211efb190bc5a2a32f7daa4918fe56ca079ce9ce21735252a24885fe4799d07231eb6f048170c0eafac72fe20706846b82a298451adad0ddcea56e76c6690f9941b1f176f014ee0e30d34e4bca604ad0bb11e196843b5a73750c26f2b6d9e74b652a4bb6bfb99119b0c588c179fffafce3e54f4697de1d8b18c2f64bc257b521128308db49df3fb014688012565d4c40c06ff73bb5ea11cc1a9870b2e6da7f69d720f85e8998e281079bbd1191173aca0da0c1afe00daa95456e582d18ce55ab1c940a785965cf362e3f42826b1f3782233bb0b22e74a06dca1818981cfa6eb3aa9ea2d35922a6e7d144be09ada8b6655e549c4ddf44483b43dab0e884a5ffee57d082b8258fb1e05c5a0eb415eacb9e2ccee9a8d0dd22aee476b88447a87907a412cb647bf9a37bf1a2248df7eded9fb23d4a56ca86a45851f8da9cebe27a12c82d524e86bffc1dcc3dcaf5844e51b5bfcac87d9d6ec4d941ef5756439a08ac7db1a884b9884d87353ea3455e2b96201a2aa67e628ce3e5ae8efd883733c311c76c761eb52f239dee10d240991eb98afa719b65c398174e05b6e57a71fd839677e38f587c1e868cb0526491b0d4a5bac7b24dd97cdbcca7f98d0211886c0e53e269a910d24facd6d3a6d38ce32d6f376ae4eafae417d2a8298b6fcc18367412641644006321e38b489a26a565557f265c9d6351c236d11a4873a4bd08e6230e9f81a6a030a1226a16f6cc8a58cd44746a4cf64da1591004388f4503940a31f5a184a984081f175748182b4d53a5912ca2f63ace761e3e66aeda1c345d8f07177b82b730b2b34337ec8e2442ae87228fdfc325e7fde5291d7182eb19491b85c276132215b62d51f9760f7282d4f56dabfc11078a0d7b2c829d8678ef9ff5cece5ddec54a9bdd846d20e44987995a6eee0d4db2f268a4719450f7abcb2bfc4462a9846d7e3cd53beb59c484ce1a51694b215ed75e317e4e916ccf823fd45a8c0267c140909a403719e7a1d089a948a458a64a0efe9145182bd2030098571a3e718c9c07edc12aae1bfdd563f063191e50ad02b0a9e7f46c3d5251d1f0ddba48fcf163b50623fbd278e235d1dbdc1e376ff068e03b476013730481f3fea6a94a46a7dd549e918215051314307d38a900978c08c5865990dc1d9c1f4bed1216134b1d517501f18b13f7420200943985957e3a32816bff855da72f8748cdb7cde53e2ae37e53ec99a6dfe15b2f1d08a0c3edf0cf9c26d1baeb2220f2a65fb50d4cc48e3355dd452deef0ab3fbbe96a1dc0997e891df3979e15e93d8d96d41e5913f526cf8e786f73c8cb974ce625b837123d9bdd066901b0303223b461e0634dec1a99e3605bbe127e6acf8b9f7e274c23e1cac9c5c3039249c7d1134304f53b944886e91fa61d568e77d42c5a7040b3ab97996696327a7fb490bf3625cd1bbd1399497a50d4182c4246c61c099a621a1d32a3e636b39b320a967c3d00e397334e0ef66b194dfcd5c09687f1f782d97761dd122b108dc8655a06db37d0ad977613b9ddd113fa58d9164e6df2e2d4dc0103b34c297976d788939a543e7d700b6c11f777e1fcee2aa22b1f1351433fa2a3324943fc8fa4a2b563b306ef8be7cf345e731e1028764e3be74fcdc2a37125ef886d9efbee6ade3e62ba01ff7f86759941f9df14f12d7729005379894cd662cff1d8cd4e652193e605643a065f37ba254ce332448d12d48007ce4b1dbddbeb0cd0c8eb6a0c83e2956cc97f4b4698b2c4fb99135e3f6d0cd2fa510169bf74d9614129a8059e2a4f67c3e357a7b19f3a0451635f4e548f63933f16fcc16ec17b75fc2263749568d1a2e0bfb4b29a263567f6faa57339cbc985460b7a403da2a923e12b57e9f0702c76d3c1f6c8d5f3d674e1b3307c330ed77bc4f983cfe94b928077f994e7b94b29807b182b3c9f2e97d74a38bd85c114cba2d247e34220edc57e3ecc2d7af9af9e10000170a62e876df2543c4ad3788884ba56b5dfa8f37e14362c2bb792903bf1172bc0dc7a47d0b3cac17fdf7271be76bbc03f710261f07135e48a759e3d3c00f97d466b398059cac31033ffd8454d6e173c7d986cb050bbb3034b5add5c511228300092f647046f26f506446208d035ab21406a2527a5aca6603329668b23dc5d99289109d976fbc736078678bcf152517d7e4a58011097a744b4e620c489e3e0c80ccbd2f2f381474e493201a403a610d896e977a71d3044007a1848db8130b83f55a1883f339635f6d799f19f619c0cf12a6642e25a5cf03fe2a79fefd976e7ad57c246a78d5823bb691ed7fe14c42c57a160051438216162c4fd12c05e2eb6fb73196c28b52ac0b86f563e4791f074aae55bcd8af0a47064e6c892116ffe8d2aad9bd30fd8f59541bda21e8099e2250920c7a536afb48ba6d692946c205d8ce9c0daa7433a5bb8b65b6f6daae83e9a3c9f6c7f42711dd4ab5fc0154e766501b2b9b15549a99d31c8364f3cff65d0524534b7fffce63c465f822a847d555ef5c57bddfc1784b0572a6e7f2df88fdf1be6c941bd1b57af489904ffdae2a994dccb1fbd55df4aafbce5a1cccb7c2271e0f39a470844daf108ef21ef68346331f8357f37a4715e05bada76a281bf6354a6b906495e73b885208e60f140cafebb5f6f50f05faf6c4aa3657e879ddb94ed186aaa32f3ff98c01e0aefb91e298df10c214ad57dd45afcd1227c7827aae7bfbf5d1b502a7aca1ce85410c17c664e45c28b3d0e1cb2d2171d97931942270023cc1402723fbe3c69c75fb03cd58fa80a4977f24294e86648473265a9b7ba26f8d20698bf01b6c25d4b9ea625007e98eeef51ad42654d7a8a61d49b71d85a289716b07cba46e19f75c684b6f4883159e097c97e71565cab30d44de3d67d604a7b4b335febd413174715feb4a721708a04c4e3e9d540fcd92dff8f15b3f760e8f5515b5bcc68df81e868b244b231d351d62b9be6a29d025f5618e089d0b4de46bc0a9d13f43b0fa6dcc563ed3fd65df3a63558f2b455eec7d6af84cfec7d678681217431031c0eb43e8b4f3a0d308d0c85cf1af6d60992ec6324b5d4737fa6f98592ad1bc1f811e43e8a39c9f82c45d4d149e96e2a245cf165c2c63a52e43ccc03e019f284b69f70fff3feb6b4992192a4dae7dca578a844daa7644cef61ac1c396042fcc21ef1ccf254660e8998b4f87d8a591cd2f516575ee851d9d60c8be2702f4813966f320ab6d6d4bab00d42637bfaafc43968cd71a29722c4f03a82250f534094a0a612b0ebd2b9f39a18747bd12bd85eafdb8f2ecc99ca8800b5ad8f9e03f25ae0233febe3872dde6fd6f67ddeddf5beb77a4999bfbeec0487f127e42f5c92cd787168701967afa300f9534a929f80bb910b8ac03972b2c03f6e575385a10752bf50095ef431fb1fa546e1d0f37f181291eb96065fed591a2a7dc1d61f4ae47257151e3499f485071a93afebf3b81e64be524125b34ac44e303b092ea3c34d6a486d9e9cda09c1aa0ed4dadaff7027676d6eea6afa444c0955c131d04e6e768acac491279168f2507832817dd96988b7c3386ab27d5eede54aa5a0e208df6c113e4ffaa5a973b92029ee1f9cba82773fa861976d7e191145442d398818df2f7bccb0b7cdaff53920fd438b2afa02e7660bfe5cf49bdf0ff4f1c950d0acdc8db9ac718f567fb9783e60a4faf82b237d5adf4073427e00c04094e3a3fab748d305d5e69e545200d3efc3dabe68f43d117f0dc74a3a805ec144f416f8954e5836ce77d0ab72baa3afdc5696964acab1026be418facae73ddf8b4673d6299f8f59ca72b7c0271361e3aeb087d4a077ef0e4d5fc66940f48def1c875b229d9df0b1688ed8034ff799d9c257042b2f73298fdaf69e18a4697eae56ee8e766e5e766a5ee092ac19c1ca5ddce61bb2a20d0a056fbb843be386760817ebb817f1f048c1f884400449d443169c27fea9762b25d6f9fded0d1c973ddcb091e85c3b174fccb9ace843589c44bc7d09559f11ed019dc0ff8c15bfc38e6887fa55066f8dc2fcd90d1b24280bbf00e6755c02addad88f29b2550ee7e3128cef50ace952d1ebb6eddd26ac7e65fc376de0e900ba277b29a18da779269b80a7193765e9a7d1837c87727978c476907fa523cf6045817828bd2190bd8a40243fe02d09eb6d72c6f914d02e89ca29c4f03b6bbe2e4dbb0f6784a85aeb734c78537732b76073f5f3b1e1e2f5f5f6b7f1f572b4e5f2e0b0b7f774f372b7f4f6e273b2b7b5b7f7b7e0e57475b77770f3e072b7f0f7f5e3f2f67177e3b4e0f3767742d3cf32766caaf8f6961c666447bf6cd675904c5380e9cecacc603b99582d3ffc6307c02ae8429f7ae5e2ed1196e47049fe64191f2ae83970f7f4ff88f911654680e45ef8fbc9e48afb9d97a3a04459718d8cc6e145da51ac99e1fb0fe1779a9077090b26b58d660acb9317d86cfb9234fd75a39630b65f7c31c44937c0766d15ba1484d2fdb8efb46c0026cd362bd4b81d20d8ec59138c7994e5d33f719cf59b866f64cacd25d46d17e51a4dd261b0ea09afb48d824195fd5041a720a6342f2d3bacf4ac1bd78fdb41dfe63c2538035f16b743c2c5703bd0cf5e3d52e4184f543b2a8f86c31a0e06b8f0228c0b669534b788a876b0143e03bf9715013eded2f962877fe96a61213697446f430506bc11180bb7ddb34e0921d1f66e141d500d80ede551d56360c002e86fc6f0b39b4f9e628928292ce2c17e40400c54368bf1ccbb6417ef5159e16c65a3263c2ecd211ed4de2e99812248e9ed7e163877ab3617011d14c0c189366ee231194fc61545640f89a07a6c1d6c266d59964587dd56f8602c864047c6aec36713b97d541605c4126c770cf95a56ee2fe5d8759f9c92a4046dc4d74f675e26e81479b5c707c5c9647b4187c2f264847f864e1cc9060a8a0899ebf8afe3846014b46c03bd1fd9859a7cdd56ee23a4eb99592cae836fc9a866b649dc00c0ba3fac8f2c3731be3eeed4f4fe8b61bfa4ed5cefd9347cc1a47e0ef52b13741470eb0f016c7c4474317665f457a6b8070cd1fc88b3e79bb3e5ca374edc658f5deba387e500a8367d1b292b33bd7c0cf4d4b4191685510ce86b8dd140264e122817d7234edef62400b32cb6afddbe70200daa4fd366d526801b61a49692fb6c2a2550e47c9ce82d87160f2ca83f5a5d575f047f7fffdd9ec086a87d78aafa56b2f3f4bf0c9a857b266d730d9504c43a6aafeafe148b2154541ff2071b72c780e94da2ac526e1f450b5175f7d114602af3eefcb7c8488b16ab548861c09edcb3e975200846bb92b94b4f4f99a95f1ad2770f7fcf5ad33bfd6088353dab95b4700c0293f4a608c8a35ec8b2e4f6fbdf8e5be93831d88617355a945a25b53e76db23812c2267c10b13a4bb9b96ad3d3ded4e3bdcced276b1d90d9f29a1a49c08ddd00deb7d5de585cc1cd8a922ab1d6bac99d27d35a83b5babaa4dc50cb07234f9858d63861202701b3f62c7837fff170df54f0b3aa063bb376be48fd37a0ceac6d08fea76e777b76e5678baa766348ac0f9c5cbf9f0e721e0f642b5521cb893ca6699e2de6b3c30f75b0db44b5e906082f9988c38568df4f1601782432bc2b7f9110ce6ed655b4898d538739c21a1a7faff7f51e08bd9617f4130bf20373c8fdc7a02f78254bd76e2555fed22a103b1bb22ab4a4bad9d2af8918033e05059fde06391e571391dba845138b789f65ca6b03baa6191124e29ab668d534423b11d78274d4740c1aa1a86a34ffeafba2529fae804861bceafbec520009a224982fdf013a548ae5d74439b350e01b9f1afc8a54c5d0dab25c4df3ebece3a6b077b024d597d904471502a8a84018748e7ebacf520001009902f3e94fff258a5231fa7d4187bfeb3b30bd6f9c97c52f19c7e5c6bbe75b462dc4d4a73090371ef513c22d7b2d6cf8c8f555b1a117582857ffe8c867808d281bb1527ca341155362ff2dbc8b6ecaff2f44ed301689305085c3900558d9137e6aa19900718ed1c71b05bf0151c44d67ebb88d9f1684063b681b9e326b08f3decb60c394d46b827f71339f46a9818ae762aef4f4b47f6388eb85730b6d0339c65a82cde2300d65177f0ac6843be72fef0b46647e8a66f1ab00c0a10b67ff5a8b27810c35e1d0346fbc48dea599fe6d4290f65f1918d1e3dd784fd243ceab9772c96a1d9fe95e7d3fa9514b9820195d7754de4d896dcbe8c4eabdc32c77783f24765cd4ea8c50c04292d8b4dab450453ce5deba6d7785eef50468b16db755a22e4b76e15f3a3a05cd110f3609c1e60b9dc2d4121f4cb1719b69be8cd4471e44211996417ff4992b42bfbaa074f35410738eee1f1961b43ac43e257170d13e5954813447ba236da19645182ccdf9085c6f23091c2969e4c592070a6d0bb9a0dd49cc752d47114195145a4e4a0a1b5bad42c3fb9ed16199b7026c463f689f8352baba93ba546ade940ed955820fbe725459d79101695b9512746bae1d8bf4bd913a9ffd150aa4df4efd6282837c9911ff5cc1f911dfb79db6b03309f4617a8dc0dd8933628fb3b3b490beb745b3baa1191faa4e39e55caf54ddf751864e076876b43be0e570f259e77cba2c48c55d5e961c7e7ded6fbcbde55088bafa70036c3fcfe9ea662a8739487761e7b09847409c5a29b647622f4f08968d2d26221d108519c252b2e542cd49c7f4ada3c3fd436256a35c0ca62089796f7620f1d45dc27144647d4b320ed4e2c6456160e4e6c148b0c165860390be927169c8c8dcb6586fd6b3c7629bf793a9d59c3106bd60ba3473ec48f1d812d51b31c8f2fa6a4f58581293b89da6d0e31d5851803350b66622150776481fee863c54c390b13ca2499097969b6d44c50298111ce547e79662923a622d44bb3ca120162abb4ec2c5f9ed1086164fa239fc54965a802843457c702996d1c2d3409cc0cb2295333f4e42956eab2b4893ffe4bfbbff9826e4eafd0e593f9c18cdfccb3c88810e0f7f813f529c1d57ddf1531ef09b32472f2c09e9737088b23bd59be0e7f53e7936de8542177bbb76cc893e0ed0c701213011309131b260e4c5c98b8335131f1edc801d046a298432a219eac31732226bf1a274fd6ccbfcc08dd39126f469149de2c4295e4ab332f0064851093c12aa3f8dd0b3c1923242a859333c12bae223c44b0bb544cd524779c5aa24cf0b558340138c8ca009eddd0e489899e81f91599246a2b25abb3c18a892aa92a5195a92fcd969c0908c2954a34e14cc59767922a652fcdaa48c4ca8d3426d52d2fafd7e93266f819f342a7f476c6428d3836d23fd8427a10c2ba80a7f01a57f106d0b3e111a6a72325fdc332af73c56187fbccbd304bca66467f1b326ba70f872aa1672507d9c3fed0cb70081eed6d18de14b9b167220776ac0cda2fffac193d703619f1084883a85987c6682e40663bf1f6efc7915870352e426aa774648a0013c37510e4f3fb61e5a9f67d8b0034d722b241b8d342e9b253caf49527981389795bce2fd351649c02dae3ebd42efd4a21f3473eefabbcbf5a78fc076cd66f06c7a4e0c0dd4607ca5f1d1508555e31132ae7514479db1d8729e2a134bf32008a041bfd35d071fe96bcc858845a6c19593ef6655bf790e81bb51cfbfe4254bf1d41056eae3bf33b25cc6f2bc2d81d3a2726af3cc4357cc1dfbecf0d704634981605bff903d148d6ca5f0abbb578f384fa1f2154131f554dac86e102b7b9167f9d89c3509e3c7500beb1a6c6cae733eab693d737bada744c703eda7441c02acb598141c56090fd8b10cb9e38ad821c94b46fecf3f5d6cb4709196bea9ebda7b6c7be901a129c5106b4624c001f0bf8744e73d34fca9cb4c290cf0e7f8a499f5f3fb06a8e43c7dd94f99570305c6cea2969b910615b7104cae610422c4340e41acf2698e8d6f728b4ce6de9f7e40298befd29f9cb88cf5f3935340886afd3be9ca2b138f951a9c324682b6802b9cbcc3e802313ef45a36a0b5ad3ffbd204eac67e1b4ad25c8e63cbf867b63a5138422f3c3b918fcbf0712f7404294127a745a5ac3a2c69ea6a95016fd6f8d6fc18e6588a23265822f5b10c324aa7053fce9280464c462066999386746f8bf0cdb122c1124abd0a665e5bd2ab39ff04bef407f6ef06fb802f7b6f933670a63e627c4c314d8f40d02ae30fe58b6fc85f39721fc9e4f573b5143d00dbfc4b87fdae0394a9051a40996c1864152c3ae234b2ed8f73770a2a8ad6bd0a94b9b5283820493c562b11e25b121dd35c20404306560237205cc09bdba43f1b8b887ef8e8a643d93c6aae62674157318691d0870c3a2ede4a89f834874c38148762218a43d2cabc6ee320f4d91a630278f6af9f0343166835fd10978bccea53daf4dfb5207f8103813c373744361912d6f723d28046d6614fc78a9d7c0ff9348bb7e7607968ec2ec11bf42c860fe58f696c55bffec5c2a1f5327f8f7db9e392cd8639be1d78225b9ed0185efd604aa1c8eaf0c2ee4728df685928ec3f39c15a677cccf898306cbbbb654bc73e39e27827885dfea403c9c686ed3a8c3d58b2abfaec80c38316e0cc6858fc32b17426501965f38c5226b7fd4d2c930026d11888aa2ff5709a608d5bd8da273a138395fffa7100fd401826251f793d2df9cbb91dd0dd46b86f551be3774feab914d7e66c6eb89c03a5bec80fae2db6b12ce8b51b3b6f1b6b4177d52e77aefe2d11ae8739a718c203764ae6a781065c512d5b445394a6f13e22d9aa26db8b0acc1fc257cdee2928fffd6d26e1a3c6bfbc10097f2143439beeb185baa1c3239898dff832657d519b58f0a632d9c7146f3d44e00836a4d9a8a418a201b33f7643db5461add37b86c6ac7904068ae79756437c5e7bb010b1d4422addcbd960c65b3fbfa6639f0e48c013e48f4857908d1e1563b8ac1df02ea877dff74b2f12250a5b2ea954f15ea2181294b075028a79f9738868fe865dfbc32590656bf0f19002f4af71723a7b2ea229ecda473b69a69b25cf24e9c4909017018ee29c70fd5fa5bbc49de1bf4c0def20bf2e5b5897393c540f7f12fee69b7c92c8f2357c5d28fba1c6d6161dd823bdd9fc4c92f9bbc2e7087d1ffd53aaf7c56c723f550ccacfebd06fbdb5b20c9d102c54fdf2ba5bd6ce664ec4cebb7146f2ed5648ec2c89e76f3ef5993a946fb8af69a1cbff51c062a4638e3badf2ebe56146e85a40192a6d6c461a130d10c7655145508300e35805630abe7b72d79b4bc7b609a0ba97ce1ae1e5872f257ce67492c9c0900dd55d2267d4b1711c56ea29101b9d929fd35b96b5d3afdf7ee1b84a22fe634a4078f5fff5bfa6725b2be9880c0ab76ed2e091c7f5fee7efef443cd1817d063fbee22aa62abda944674856e3f01e8163ce125360cb45dff72a47b42d8eef0f34255d703febd0cd8b686442c4eb77720c848408a7614dfc161e9dacec38767e351fb9b19e08042d9ee3a24e96752f5b4cadd9e3615cd829876d682f7a59c4d4a287cb3dbe564ed1ae81667c45a26b8f7f98e27035217b41819d3dab50b9aba6d2e4bd23b4626d81c4ff11f446ae554fdfb1bbf458981fc3376ba8e72bd762438dfdf6cc92e7a287ce5a751f2a1a0e48a8f1ef384b03cdf0529e67e7d6f00afd0abdfc01ceb21e3d5fa0e0fdba48ea03bb2c3ba141c135cf9cf955c9c63621125a77a31218a2cb94577b9154d1c34bb5c3ed465cd131e07ddc8c2409686b4528b2de5db3cad21fd65e47dd97224f8de54e0696e7b3837d386d39b9180b8535c0f5308143fe19bfe93d8afa07f3a2e7bfa31d8f5765e049ca74634a97f8be198faf8883268019a7aca771fcde96a6dc8b59fa5e32687f74b5f590b7f8abab29807c46c3cb8b031c82cf3a66aedf5b0347da8b05d51b25cd298ab02679adb2f9ad20f063ccc0d0be5e1793f86b47afec3546e68304f45e2c85c506a715634652b624acc86e3e7e24bae3e634994f6e0b1a7af18a61359d0adb700dcf67c819f03d1959dfd1d604295147f54b938369b769fd018e623cc8dbd91f2f9f6c35834f98fe4949e1bf2b78dc798fe64af784beabfc6188b2364fd53b67f41e29dcd02bb58f4c5083b4cadb860acf8d7f4a5f61aaa0f0fa5779ca00effbb2568414145b9df3b85e8c3fdb7b4bd9072e9bbb93fffec8e37f415a87c2a3b4972aeb372b2f5a70b88db058ebf3f96b97627c7bbfb88d6c3999ed344c308d80937719eaa0318709af4e4a9fde510cce30a391a7410ecc50a79c60039d008538f17eaf30bc6d012e029f6fc02c74e639dd4102583fe76dadbe9a1f34aaa725d4cb43030c286a30cdc15371fefb818ec01b3109e7fbc6285fe697cb61a133ef57e9cf38c4765948334c009822562e49d2cdfa0e83c6b96ff43b551cbe0c8f74299fa4daaa808db353ff2deee54ce8bf11fdfd2d76549140b50ec16316ac0725b497a79cb8dd786dde19295152236571822d6c22dae20a480df8d37cdb280aeffcdbd34bded604bc403e7b1cf59ab45f8713171a6587bdc6eef3171132406d586c03b7116c0ee115b5dfe7fa13aa91925fe8e8a43c66dc6521adf5048e3e5f1a85d56be51ceb1ae6a112b92a5fe5848926699b4540950210d61b2faaf21a3238ff922f03c34ddece8cab9724884872a99a2b24cab772282aa688c9c04bd3dab598218d97ea92595654646074b8b49d3a77c2ac894aa4cc6f4fcc7df7c3f2ae8e2276507f3b2eefe04c1f9dbb7dfc2d1134000f5ef6b09772ac50a533a21e0c54871318c756bba8aa0ebbdbdc2525c0dd8f88afe32033fcec357116ab5425622c5773d8e991a17ac7973e9b436b1da28d4f2806b8d10b408c99af96c188d6e36467a9ca316299fc8475be3928879e87e995e58cd07071ac28048d2abb3690dcde818077596abf36a7c8303349b6540d3de1fcca497dc3f0e73a110c03f924896611b264d33a549c8bc36c3e5f1ef7958e9f8d8c9d7bc3755a16f9f21f3df8edfe16c4680788b553400b7403a69e34d3eb0bb3d35f6776d97600cdc0f0536ceeef6b26ec411273dc9b1af1b649c1f62e8258e703585f85aede5ce4a6b6c00d8566bafa7d74676e5bac3a3c99bfb209a755b460c9ad7a02c34af616d47849bb82ba9ac96b060370d56f6c0dd83e879c87fbce6d0157f4f70c3d5ef7b0f38499ad8e278c6344d40141e8db5436d9bcaa3c812811b051e2dc082aa26221a341c596cc2a3078148811952e068675fc196e147459febd812a13cb4505b709386e2982da7f17b4baf597e3a039da7f453a126bba5df6b61f5b4da860e5a671d605a00b6e74f23d07b8a8152b78abc4ecb4ebd33c5f3f31b98088e43cb9bb730d353e6fe79ad8bcaa8b49d950f3449eaae850152eafd5e67e13dad876d90a7d89bcc7d48c72d84a6f89dd003379feb0483604eb5d1ad2ec5f67e96ed6c2a4cee0999adeafdc8310c7ea7c1e8b926e70cdc32ab7dec1d8efd36a21e6f3723dfb695ebece46bad9b853ab9278d41580696b00dae1b3edcf51eb99ad0c5248d292c1768e21c2044c665f90649e98edea307bbf99ff39d66e2e0c8a1518c0e7b1a44f7c87266f8da4123f36ce4af8b5bf566328d55aac18e68ef812f48401d4505e0a72eb737fde69abd7f62b270800e9cde42fadc6f83ac0c0096e3a5fe40e27d51ac9ebee1f0458a2d3874afc1f5330a0dfd6eb674940b37ff8c961ade831cbc3864873a08611dc113b07f162bb927e68bc2813b9ea8d82cbd5ad1407b46129dd845cc163291627148167ed9413fd843040b201ca76d7b4a838b0e63789ead3d73fa41ec129687374b947786671ddea12228c4f176ab9f20bd08aaa8483489ac744e54e41f5bca05952e7638114580ce4490591fefab124496f4c65910a5ede2f45bc7971a28ce3b11b3f3ee1d7c649a3f5cad58a6e30ebb522355485578e86d98657cb9ae302e188f00c66f21bd1d3fc7838bb116d22394ace2246780831f4f6581c06ff12025ed905c4a268d0a0aea2e097c5c8f4735b4317dcb689958b9c5c245053931a437f484adf8ea065b0a2c2a23092fb7b194e89a0179f00592fd5331327d8ff226b411d06b2479daada82956f51d60ba4101713eb6ba535e1e7d23ae0884b460b0a9dea3a965e524727144c8867b162bbab19976fcafe0ad01c77747cc75fef3182698020671ded895c59791795ae55ce0e519e828f621cb90577d2ee996a2ecf1d73b7cfa172e2312ffe1a06d574caaad8de1cd6882fec0c6982580fa8f158a43cc6edbd7604ca1a7c7647bd4d7e80557ff44286726f6de7aaa10eeba888fc7b52c99df6fd3154fd1bd9d68a41c7b8c0a99c3d3c2f0b12f8f39b8b19558a989ce8e0dc17800776e1f565eeccf97718195499de10117601fe6847e7e0b0178bac4b401f80ff254815ba4e46e09f35bc8f8b83d556be1b103f41d7e2a8856e4ee3382c14ecdf7b09d3644da2b676d015492ae114754dd7f270e46c4abf1e13720c78256b18f803d1234e33f0d245025944a11b0ed4afce4145727b4ee1c8caa1a0f31d27ee6754aaf8ce044695e17bc748adca03286eb172f02ceb2c3bda7b83414367c684247846f2c932bc0e76bc89498c88dbf0e67a77d6a07b87c5d8482a1dfd0c34558f3850f69fc8dcdf21ec33e12f21aa14e7628b399d1cd9940345df7b5d23338fe4e1b62a7d0edb61fc04c603547cc388784722ce6ec255fbb58b5e464c6f7be65fc7b59763dc7d6c01009962e38eac62768fe9050b347c2986c2ed2400000657e16d421ef748bf7951ecaaca807662a3a27cfd2b2f518e4870cb6813085e9123d06b62513a02362e18b1e03dbd024b21670346447835817324921ff0feefa85a04f92326fe2c09b087734ad8e108415d49a077b4a1afd21404ac4c1e33829105731622f86cf48ff645fe1856387c96456c95878833bc6420f5895511bec677fb2d35d01be84f2b6b6c2362ce53a0b3d2e3263649286291cb12509851b45e08f7ce08c9b5b1c2afa4818b912da1090afdf6b8baa16c0a5494950c6d8a6ee8e39b4063cfad8d0c5257b2c0c7432627fe2f344c43957395f73c2c6f5bb32ac034df6184502dadb161177417523753bdf503363c7804173ac1ae5266477abb5312f3de15e5bf19bd46ce83bc4ca873eab2b94e7a7d5b4a632011e00b72a551cdc9c4e97f3a0cf86ac75b7575e13b267e77392c439a63ad3382124df01d3086056e12f180a450b49897b9d69a5adde6d1bc9915ac84d9cb544bcd44f0a65dcd9b928222499b07961b08461d1089a03b19890f3e7df328e69ad4cb8ece078c7098a4edaa6a14b466f8b981055f20cd478f9da02010dc28f1990805b37df437ccf57136d90d611e4532921597981b92ff292f94e3889c4c4abe6ac025b2b2a3b695c4c86a98404d9d0c4e978aa88faedb26437e9aaa3e1c1643f3ff8578e07c96cbc8481f39495fafcc20037c3af03022f4c91853a26b6922ac40a33f97ab839118e7f6c5aeeddb025166ce0b7f7872dbfaf784a51f0590aefba300a1ca75af4b08bd1145ded617122ac9b68e9707f5df576a7651d4fdd5f16ea7f8449d6f9953eca1350860656bd805cad03f344517d0db5964100e7d278e824a503985ad3f2ebbee17e065ec52fb8a3bd3b1d09ac7d627b5d2d3de52f2c5a99f89861275a1ea79cb9543b7094f6c3fabb9b433ce2fbb08383cbf734b42320538c7dfebff11cd1d7c3a3da31890f331a2c78e396cc74ed110f7c44bb1fe5dbe83a5c3734de75f5d04dfff4396d0538c53181d0e0842409ad8575c05134f87706a5505d0baccc87a685b32c0e1e242e338f5f029bcd8412ed1b12e77afa64e057a61196b6e6e11e7f6408a06c52c746d87b0946396a97b2b8310850289c2c341adac75fd871028aded555805cef42d413a8dee635c23b9b6efdeb693b8b4eb639a88d0db39e6f74dd7037af9fa974d006a15175d65b801348a9855ffecf61e44bdb79c2dd71ac1216cc65b639edcaafd445fbc3c15817a5bc14f49a2b48faf91b6fd2c3bae1270713c747faccd2366f466d2b557fe3971947fff024d83945c8da881d833ed773cb1e100554470f6780266600f8ff892127524c3fe7c86b96e6dc090251b146f1dbc0cdff412c450363e0a32b8321d916b88145eaa04cff3a45dced912a5c74df28cbb00f20798e8f1a0d23efbf1f5dc6f8d24befb19075eba727212d9d85aa1369cc0fe745003c1c6eb9ab03a1d43686b8075f6325ddb6bb5d731f8adbcaaae9cbbff1386f7b8c1495f755e01d6ef84ff02afa85da35cd10ceedf1a0456ebca749904d0f75ff9d61aeece4eca8b63f04e0ea1fff441722ac97a8aabfc37bf7095d1777f91f30bb569726472e899b5dae0278aefe06bb8b14d05ed7f2dea56269fe82b4dd8ef85e1b97199684f455472e0e753e4d8b774c57061db5d37c3d440dc521ca65ec339849e5dd26b4da846c259c5fd6e6b39931bb749b0b7d3a84a74579d64eb1063558c594602856b05bc2064a95d372ec408a0fc13ee5348f665efffe8e7e29607ecb1c17f7a8efa4eccf3d7bac195c1aa63ec02ab3c72193b274b944fe834cb7032e59e74b695e6a0c7acf343161a2a24d7e54ee3a0fb9770e0ddb074ad8700c8527737a43392471784714cd4fbb779173610b46b81bd9800dea6fe244b161bf097ac1f1ff8fc69b5fbfbdcb8219206743eac29981c52ae4ea6c78ac04ffc239061f918f4aa8f8b1ca19625605e14c3bf3faead0e1bfc060b38eff22d1339b73cf5733a3c8308fb35612ec50abef98f0547e56c5768719ab170028126cd4f6bd8042ad47d57969e81437f4e472f5fa8e8a2765d8d1a298ae76c4ca0015a752585bf10f1aa7591e1fb2c9e3073f48ef301afb9556dccd879229002f6af7fb349520f325e0aa92a097fec30e4a112be773e27d3699d8204381672ef5f4639dedcb59edbb442c52036b65aab248568569e22a59a7c4c54101873b6c739ef2cb80f01cf66fac744d00425395bcce1a06d268f76394c525c83b237e2ce825f9ed27b8c5d81d30aec16ad7d354fbd9d4b82c4edd80b6da5aac8d1f6e91d72fc7ea86b3297ca470f0ed1ee009951a40ab1902857287ef2ccb9b69045c6a8b411cfcd0b2361bb4b90125eb97ccd6fa494d91c12812846a6fa17108ebcc80a7d31564ddffcd1b4afdb34b4176e549d1ef6ba764fe83499c21032ff9c5aebfc169eda4334b9add4c78efd1d2b975316541c4d2b4779a2ee9c1ec5d44026a7481aebfea33845056925e939e7edb979a6f48aa0e3abcb09f75fce4d9176f5a0d57a7441f11f7fa6b6f41efaabdccbffd856370f6b5c78c86163ca1e26bb90f91d1639c370b4fe5e8e2d44c66027a0a673f21bd6a6f1893a32d284276ccf1163d7b636be30fded7c6a01931dbb5eab64700b61e6945eed3f5101e9b85b849755c05f98aa68df4df7fd02d05e668f234ff655a78ee1c41976609691f20959ef37a431e26328e36d998c72e2d1301fb272d47aca89c86ce7cf318ff2d39cfc9c5b1b901f07474e64dc7f238c3fe10001dcdfa9a8ff030f84f689cc55e607ef28b33121b4e8b1455bf27a6171353c028e0befde1784831e8027ee0f4b2086e37803881d255a3134895132a97c951357dde01e929992921860969dc2a96281120d21914060730c334bc1ca69982831c71827107ec24ba8d695a0f05f5ffae8f6b7eac1b357497c9235a3f04213aab5e22f831bc672d48e4e721bd7a93c6aa2ad9ad00d45d99895c86db8eddddb995771ee90f7c6d2e545696772c7abb5c95469764c2236b1b05a456df347eaef4551075f88cc8d341bd857b528970fe12c311747e2ec58eaec7451845fefc71c0d5fef2e861158f1e86eff921c8186234458a5cfdb067d922df1324adb7b2c12d4c3d01085ba982787285deed68bc141cfcce8a2601c606090fcdde37da86c0b6697b42173d93b0b72d7dc525290febd190829865691b275992d2e4dde3e2a808f6628c5b09a0142959449c9a841a591b88c5cff6e86351df1f712a41908471647ebd9561572eab15ff8795d0afb59cce227d12a917c436c7e93608d2336bd3f10bc03362f9d56a418855649c64e23c95a96545936ae493085fba5ef740a9b367f73746e26af018d214ccae9d3a2d6b496e3a4ab683329581a0668858093cfb2eee178e0ddbe0afeb0cdcd5bb516a97847ec786c4a464e007ec2158c9c3443f320b0983bbd09b625356189c2dbdd78b4b45a0e5d826d3923762c61fc13de8de0a0741757ba4ba415cd287e4ed2005767238f861c6967f8a66cbeaba83f854eed48bcaf8e1a0a2ec782998659dd7f907399f754733f15d6d556e131fe3bfe28a67e500fbe5d235356386d8af14fbd6f13104f5152924035aed757b28e69705b72c4dda0ea877270e87fedcff83cd104aac36c2c835cd4aa0e27bbe36ab16115c604dcbe85f1ea64dcf8406e9454c115c177dcf565505af96567421a63cb39502d1782fcb962816c093ee6e8db9a0d67d10be0dd71a6ae24ca87cb8fdd10734ff0ba6350c13644222e68f44387eca2fb647bfec29ec1228dbdb36ab2618d368276ea8b1342e1cb897a7c436761e3ecdebf3a5ae3b3bce44a16b389ebfb787cd35c424d02ac3ceb0f6920af7844f0aa8250c01167792a6f3ca07b7a8393917d05299e09fcd0a464df6c6bfc2e6ca35343028fec261c23f26cbf2a6f3241f6e5da1b062f5ae9b788677c1c5d1f190787108958ace8f3a6f74184cd9a77d2289db119423e5d95b7c0c3f52b011f5636043d8da7397fddd44fdfba7e2dd8736ff638640bdb55b89f8e2c6146aca389ea7b8808e5fbbeb3fe3e6ffbf23f297249a01346a1f29bc9862a1279d5dee6aaf49fa48d939ff2ac95289377be55f46a64c4fc8447eadfbda9b87c42a5684b3e85ebfef75f7b2ed4eccbb959bcbde5601f8b641036e7059b7e2cda50e8affb1d8bf15651de9d6871b85b75e8699eb4ec7ba650d0728e8d56e116c3ffd0d5c5ffe8694d7a05ea4ff356c90ff938d564ab5172d9951ad24114f30f38faad085cc969fd52a592c06acdd36fa5eef01f661cd3f2a8d5e913f3b7cec767f1a95b76a79bc09d01a428128abbc13144ac55677089c8fe8963f51f86b5022937150fdaf8dfa34372492d7000fd7c38bf4d55c04a40a3f9b330711d775e3d181294dac161c3e76254f136bfb75016b0ed397d65409fdc2241d329ecfc58882bffa252e7d8f04f1bfe3a3c0d296c35d303d360f1779a5ef666be3e2cdda2993c5675979bd17a4a2f448c8c797c242c2163220de244d84c333db908f1d2c9ad3fb790ffd61e367a3c7bdd5f18fab6a9cd552c1ae287fd3f85779b4ca2ba0c37f81c366b1c5a8fb63122d7331f27ce879266da57535558db3eac99f46fe59c3cbdfd4ee0228126cd4f69d2fa39afbfd4cc8796b689e063bcdc94ff8f45e2c48f5f3e1b4f78fe0f38d9a3f8e63b4fdc474507ef0479adc6e625f0a70f1f8cf4e4990bffa2ab72a978dbf2661562d2139ce12fbbce31bbb4b32ee03b2fc7e26a3aabb69e2ec3e93408be1e63915ae8edfbf4bddda96b4a4b6987d5c30af921c420793d9d296dfd32b338863b8b0bfa89242b5b207b09734cf65d555517a92c5abbef88edcf13e32f24d41771aa43980985018e1858ef8ae8895138ccc9f4f839cee90d0ab0b351d88807078928d01fa1df2f0270e83baab1a4e3317525cc55cd70829d1f3ac29e02b3f1bf036461c6837b70e19a9ef1da221fca1433dafd586c6d31220e3e164799e94147181403b04818143176d9f9d2c6262c6691daf2741f8ed0cbb5f2a35c400e162c1c3e3bfa711d771965e6468d7c15e259f8575f73f19a8c9a7f4fd8ad88ed80f6b036e0c2f0c42b226d3c9230c445f07ff43e1aee24499195aea0a78d835bde5b47c45c0dc544eed6142e86167dbfc3829b9e5a2b9a35ecad092d41417b54a9cc9dab1ba2f235953f2feccc4ff9cfa0a60e7ff4ab5f67ae343b21fcf903489a6a176e30f66d73881e924817567d86b057f5587412d6ababac5a1a52563530abeec446503b16d0194e45f78e20a819fdaddb6d5b2b12316925c986c12f26cccf9ff7bd112b4916176c2d6d4de4280cabdf35757e26920c7969ed858cd4a68f7c8cda51b17e77f1e3b95cc7c01fef1d66f002def68cd1509a15d9e8986867113c41193b6bcb6c187901193a3a0517d888945c744db9f65186c4234dff0b468ddccbb37bfeff343918aea3b8771c44675773a40d6c046408be10d67bef2965d0d60c215fe75ea1e894b98a1f5c0ac26307ace5010676526ef069746ae99fa83a09611c6e296245954425ec3e1f46f50f188e87a676c53c1d89bb7ff4e58a9f28c310c904116c1fecfb1f7946c5185a2f9cd2fcb57fa2ab9bbaf4606eb7c0045c57ec3b7fd13440f82470bf2d1dfa01f47daceb8df4e3418bb95a0147bc46ff6c70359f80527997f62c62dcc03b2e292839339d85ca3833d544dcbbb0a2ca1251d4e3f3445ecfcf4c9f3e820dc75ea20f7dba73b268f051bdefc92ec18d8fed036b20a0dee0ad05a2a03725a246db712333f0ef093f34044959ffa62228e8653d1f01009ab6a3889541d33c6f9ef3a712777542c556b3f6b9da38e2f31d4ca57ffcd15eaf3968f1d01444dfdeb64a587114b67c41e2d8ad7317316ea7f04f7db6564538dde0e9f29c33ac2be82e8fe402623e827813fe2194e6584b4858522a22c9a8bf9dc63acdc81fc719ebb26edfc0f73cc280a6ed34e16d7d914f5b40794f9437db3d9ca5fe875a13e4f0669bd4371e963fb13691469a30c902a4aa1a68da700219e148e5a36d93c9748340230d39cf43790c42521a4786e2875fcacf937cf733c8039a5e0c73929611043593122bdc50316a7ffbe80693a4247a7a99bdd3f68a771a734a7464f0c6983d1a13e7838773da9bbfcfb7df8b12270df9de33fc3c60f900b45a2dfa3dfab9aa82490a609a65b036134d5224f501d95347222cc8d3010440ad525145cb67779500acf94ba83373b1f515e89c3144e887f682792934b05bd6014ac825d700b1e1000c28018900564765238f954a8811ad0057480316006ac012be008b8006fc00f840211201e4802e9401628044a403550039a8136d00df481516002cc020b601958039bc006d807f6c0217002ae813bf0083c81d7c0e7e0bf1208211b80623900500100f398b5c7676a990b7eecb43b68d3faaca8995683dab0e74c8977780c07730ed1522e5476f45de52a7e208b6d5b8de1d4f2f652603728f9e6cdfd89baee7669a12583dbd2bfcce92b99cdf37cbd35e237aebd76ceb46f247ff2c37b46645f5e44931d94eeb5bb63c18807d5e44ab8f094eefb3d0d425da68867ead40f8559f6059536d1459f053d8452f220b1db60847479f9cd4a04c28a178af8a410c0805959802ef5bde415b475d5126dde6f0d2ec14154da04888473ba10da9b896047bc7d725a0040eaec9673b9c249c980244c0562c1081dcdf79f4b508fd0ce2ff68e822c3b205858672ce362782465f7d2adc37434904cd47b5ab589e78040f7199a3e68fae9e6978639ef5915c2a87a53bc55b6ede165cec6ce8312d6798c7ff8260ab088379a54389c69e786a647b23cd54c79720f0440e2463488b3a5633a54fab052d96b878f88087931c456b36fc8a158b14a3d233a07cbf934fb561189131339e4865213740f2cf83eb1126129dff7847f65d5092e50afef7525c1b48a7aed815abc2cced11676f65fd5dd639be8d3c0164e19a50d05ff131397e0997c29627065af938df29875fc28477d6a2656cd9c774fa8dd844c528ee3bcf94b930b11e987614fbc7f0a25cc8b26e68748620af223fb52e9286741fd6b26ae5922410f848de607e2fdb49173794c71c8d1351644e732b1851fb43eeaeefd55c80b45f20c0d2c506733044c3b11d0f852669b85d8d621d4490aea3dada206ac60a3ed2c167e833d66fd3ada6ffe8d8e8154b27fb0a3467f16a93bb107a69808a50aeb814ccb6df6bbdbd3d784c68d1c43836a26aee40a7102a4fb688649da79e303c7e22e58996a9d8aa40e8accb6ac6cd42a0434942739a41ac4f548826c25591e36f6a5e828b0b2bc8ddcfa773d27ebca0a7e4a6d507a78249c653b8492ec886af2dd05de25bb66392eab8cee9e58001a3dadfaa1a8103d0ab1fce3bebcc6e489d14cb4f0d5be468f8f20de3a6ea10c35938c078167240c790d65b2226d1e1d945fed0968e0046d633c980949628ad851787d3907587f6f42d93d5ca46ec3f10f8905a189451a1c03a037605f8ae82e010f07d4717c0bfd5933096c53f057401e2379e5732d6ee2f0eb16641970140492be5556726f8b253fb5b7981b8982bf8af544534a342cae07d45a8d2f2596e1a696e9d574bc82420c7675e86464698f60ed1f6d55f33569e1100efa506409d02b147e908bc9a0c19130fb5244774754c3cfbc8aa468e2b44aebdc82f9b6b35800d14ede3005b310bbe413a1362d69d35088fe2ad2088215410a6c89e830c54e15d79c004da9990c262ac49805f55c267432c9463957ef7ffbca8409e85d3e5e559d9e0a6d76534ad046754a947b5a656c6e415c571d49b74334e5d81c57c1129c22f924398f33b93e7394b32f8596992ce1447603cf42536b6e243207029821098507d1762198fe1bfd8ae31ef87a8a33e9d1f0dea5cd81623201fdd8f8524867e442ec6d173e9a5673d909c1a34464d92e15f8ff4db233c9db60b31f0a4759638948a9b8520c8fda14b2bca68f79242a28d0ca320ea1c479920cb5e321b41b970ef99df39994685a914689ace0360826cea33be8774be58e911b908628a10c84c2cd6c6f0ac23696097c7b478e620ea67261a2d9451acf988285a502b12f457417f0219944651b15c51bec3afe7bc82be02cec9f0af99cbf9b8fd96b6e8eb2b27713c51eecdae57358a9acab66f10baa955585d8f66ad63b9b7690a7a259237721e43d259a17526afb4408e1ff0009abbf4e4f580fb84ce4c8cf921fa24e08f8b915f281976438bb32bc9889055d124dc178d1fcfcac193307ea140a3572c132757381a3393597671ddaf8cb2c07c602a93666fdb96a8beba13cccf95ae31814eca8d1bc224df45dc1b952c16f70630e6efb6b295b3b514747ff6a0b53a2d93597bde907cbb6721485c2909e78961dda2f2b9659602125fe136322042d2ad1f4cf2d487116665f0a63196683ad3992e586824afcd0c937d703a243a18f5c1c727aaa4705d6f4f46d7d7af852c43df1ede75bd8a4fff547372d043014e9e7c209f43a3c914a3384314eaf39f7c638718d043fc85655882c615fea24f25950d2c1aa87d38fe45361bc4361ccaac83f7ca8eaa6ec6731cbb048904ad642b95040a9df5da13439ce499829fabb48b3155650e74408fb522476611ad8315778c902677ecc2345216a902363c807c1eff6815b738c583404bec026c81473c1b02f8596d97dd557a6990141cb6a6e56280a1a81ac6460d289fdb72074728bacb2849fa0b2252ac29b021222c1c69712ba7b7756f85954688d96d55ce1680e7c13590eb568c0c23bc1e2d71ec1c274835f83482e5b0986c2c692f008bcef9c948edcc4023eba7700880ae9d7c2b7634ca92273ca9483d46bc3cb276e3b3c5a51a2b9b12ae834d992895d5538ef8d2cbcab88a5ba8ab1fd103c4cbf1440a0ddc2577da7a4ef925d5aba63a9a7783fd1ea322dd054c135c0be948861ced9d9771fa7a055a7954007a5c585421f5e0964d48fc19506e331ca9af5e3b927e7120c2a5475c0d3aa85d19f4f0975748fb70d8d5b5c5756fa85060ef549b3ad9e853f5f9083309a9ea5f0a0c4315dde674042bef14b3211e4635d1cd211b31cd59d4888b29d622de4eccbb796a529aa26930a40bf168aa1bc6a1426db1aeabc8227a0a1cf2d58e21d0da21bb18fc25e5c0a96307e8b8c359cd3d9adc725f4df4654b544652c57502bb02f8574265982f518aa88d69567098b0a3a837a2d4c7fe7554bdf309ba160203e472e2a9f9c44b53394ba7a71261c617834d444fd658fc6ce5d11e7e309e682665fead6028cd6d55c4511330245b2542356996213773e1c9408411b8ab40c7405494925531c7d247902dc65f54e79d42342d13fd555ea98039b46faa530a399d85e1aff11920b9f89361669790e40b0932c6c527474f931466549f5e3a91f6f26c8c72c2519f03d1602451d7141f3b700b43565682a180bba12aa5272fe5ce4dd552fa7665f951e0c19e34d03f532529565e753c2c3102dea7f506419d6df101ffb1a45783e9fc541ef315bd4c44e12fb43b0d4400c7072a7ad0f02ed02ff7b9536b1f23743d697ab9bb560a8f25d8ba2589c7e222adae846f551878c561c50cd1255e400d050b02f758936d75cd56b6f76e02c9ae5c05434b28da532edba5d7bb6c8f327920c7e5682645fcac4eebe2f35423b0f10b4719a555848c175da5822e2a6ec103cd1946b91f723da5ca495ae290427d897228931499c235ee52124147ed231ec01bec247ae047231365c08975245cbee537387d0e3f50748f7a434027d091b6750d2b5a8b12f457467e2c926d8e6738baadf77fd55be01402ee01529996764b8d8a6b14a2568dd78242e0767b705d945a177a445f146f0fc6d242aa3266e95a5a2f9668f65958700a984b1bb7e6138724329059ade8abb599a4dd1acfe741c8a449c8213c1652a31a9382b0af25dbf25e2adc6d6eb87ce23a0b93a12a54c7bc08c82852402b8c39bd44041af761f256344ea34f17f214efd647af5da4221f5dd9160beadcd862b7933e4df56e7c66772a7a1e82635cb3e6c298aca6ab545c81cf731a545a81b77809b74b77a889ee262ca8479a6694f49dfb45df325b2ec4e55413842d171bf8823c3fca88a02622f7339f783ee28ec8de2055fb9a0223fb2268116aef8716d94b4eeabc37ca2316ffc2f033f31f9af0662b3e0e1d03b2f6bb7a875199f77fe5eafcda865c5235c151b1655c500e1065151130400be9be5419429f5c14246fe49fe3f6448220aed701f8efe677ae5a7d30ec3957e4c607e651cc0fa754b32938f8c2ec34c03db18511ae84aab2f5b7fae2759b73701cc912a74f988748621571b73e4764ab5eecdd87c09c29cd57153041709478ef00e54543885adce95b8dd44d1836e3a934aa9ca34c9efd50daf01d1e21cfc898d052b72fb93802b72b4d2e80b7857ab8d7192b406cdbdb0e49eb8832064ef76385e3ede94cb7907c47fb39ef27b79750d9084401fb34590a5b36b43be364b8f54e659f1da4e3e84e1169aa7dfe0f04abcec454d318e78cf10b893945d09d619c206e4672e99d99988f30aeeace4a32952f2d0616d3e6d59fd7faf41ccf458c677fbd15d2d14df6f00bccf1c55c8e8a0558c00ee4b9778039e05f718094ea8bb56600a91d073897964620ee78324219c49264201c1c3dd2e312d2a440bfbe1503b2820d799424c3db7377ff9b6f545d9dc1a2218d06994e0b247ea6f8e9f45195be99c1c92f65652459491efea9cfb8995a7c5d5c05e5edd9ccc6134cf44dd095a25c3f0b507528b671e421a88e08d4dec60780296c9531013a4bbde9a2343035d8c14839723b4bcca1da8945d3f758ecf44215240e20725136a321b7d2b840d5f1331c2a6587893a82a890458f2d36b6ee50c8f911eee6c457fbe7adf60ab5debaaa6ff81cdf1b533fd7061674071fc74a58412ffe311fcf97749a6700a18c48b3a380d909a79cbb4f615b4369740fb5368224ead171de83cb81ebdb3d884f18700962981f14ac585ae069127e395d6216d669d14af9ab5bea678aef6c30ad7a087bf76b388e9211171d56622de898f70e4db55b1f4f6873b38ad23679212d10b2d2efd079be90026ca7a4ddc9aa9939066d7d75846df4d5b9df081b9d9e516575c7b189a055f8ce988ecb6327495ee098416162735176765be81406dc72de17841770684c4b44b36c3fe10e03fe4dc94e2828f2c7bda22b6ecdfb263c88524f53b951104b336ce1ccd7f4c63705967374f3c62ef9d4793c50bd028bda0f7c06d450106f3b11699d7ad9e2717464c464e821f495b685677cf0c779f3d9b0ed27873ed1c0051c0ad12ac3b5a75c17ef9aa3eb62c40b1cc92b3b6dc33a64e0f1ca0ca2f37ca5a93078dac4114dea70ad31727b6327e6f3fb2c0bc0ad19a0640efcfed9835d0b7f1e9294aaba739e3053384ff6a74e1ce4fbe1b5a4e4aaff0af163e5c647c763a77d06781413749b18eb57233d36aa50a640ab95ff3dbca3621520a0ce06402d10f24efe54a7fa7a05afd7a8085a3fbf06314339bce83c9b178347d0e369bd84fe2592e909b105d45c2b0988f9a8f693cb4cdd06cc8e33a1640a29774367941eba86e466efef98df45497d9ebb925969b9ec43f513b6528adc2b1350c643972900d075d2b94b32d4230ce0ab2f3f9f878c936b79ba8c2f1777b40e62f9cf30ca3c692d37b5ee50997b6bd97648e08c3ebca68a12da7c676d78a4873053022dd9806debf776ffdb341aaf46d2e4e56e48852e36988227caf0f1e50ac95ddc4ab7ba8850e88275770cf3966011e39ab7fb0e96cad2760c0e407de65eb60e471aae89a5c068db6619c91cb588dac5dfe3f3be60d0449cf1f002ad008c45c825559507bfd6e3e74c3de18f28ab1ae92c9ebdeecad4b1ed82bd201b33611a9dc5ca4f8b28020b879833416508509dbb2a69d7291acba96b887767cc0123e496ee5f35bd90e56ccc096fdba9a41194e4b24d7a189db5a3f79c374b2dbedba4798f5defad9651c569611c057e01f20e432fc4e64f8a1724786a626ca30a303ee7e1ae8f4e630a96ed991047532c42143f063c82de6dc84a7b181852186feb8de19b6cea2e2104500810c200bc2671f316d8013ba26444398be1b1045f88368e60a595e6323d455618fe0f5b7b4f12007d0ae34ca44e5f234196f4c78d1f649184f31e27b840c39f400529c17872fdc5edcdfe6ccf8d1ec4d5b1242ac4569b9058111691c86e46b6de2a647bf7f15efd06f3186e61e3002aef646883f799d0c6ff2177184ff148b7aefad0f9c36662c6e0f5e174112a424235ec960efaf1e9e0e01db930259f238188e90ac0c5c5ea85a0ca349d885c39f643693a1916a287509540d6083188e169c6ddfbb2b7b1e17bd6bc8a06f32feb2118ef4df0c1dee53224c4f18498d629a92d098c9e6454d59eee7f405201e37a22d2938b0a08b3deca688a8b7edae1113ea4f5112cc040e76f954d8c0e1d654a484cae14dda8b4a31e50d52ddab5a107fcd09ac2292c4a192879ae7db8975b131408079cfe17921e85c05e92cbed36e99966688851950620d32f3dfaa3fb16961d9135a9919553f70f909bc67b01341749365dab254d90c3403aece61c7a5fc26ef9bcf03752ff4196281e4b84a623f6fde242e4b24a623aa3bdb80ad0066c506e7c481e15668174693b56845224ddf0e11917680c9b063514cbbbb18997be024824d6e87351d481f89cb66610634921c61f3d938494a0952921719f4f17c0e4746f11cd70008f13a84738a7d91df40a738e294ebca49c6ef14ac7c3c14d452fd78a561f02161a5c2067dc7ce91a88d9a0560f396e173d80277496decfc99605248d7f684e4ecc02e695a1ee9f867ae3249b2037af55908ac1e6988c06c97a1503f047bc0335f4301d589f6279470e9cf88ecbff15369b99403d7decad6a037c4e10a9c6ddf3ebb3fdd7f4413713d3e0d25ee07cba06fd7deee00ffc7cf6bab780a5f95cce578b0ec966f97e0d18ad86748f61a4b1dfc1f67468586864affec7e1f3420dd4c208713b37a73f1d83df9bd0ab679ee10afbd0987caed8ba01baf69a4d1933dc3f8cbc8045f8c06c942df8d8bf52805dd212ac0672e9f56b81c3c7c7e10fe680c750ee687078f5a89504eb52558e6dfda91939a45f6e1f5197217e31686bd8dc2241b9b01f23302ff71fe889e380d74d86da80175680d5b9d112faaa6d60c77ec6c7425d0885790ba3df002a8b7b52047ee20decf6fa88b9680e741adb43706218c495b6e7d0eb40185c489d96e1066903b2967ff9f1bea300e6763cc101065ddf260c57e97303d4d19f51512d1b0184e9b66e414aade722b92622e099a76a4da1361155b7aa325c5765b4e885d8b4d0058857efa8305c0a77a8f1b8af7c9e7e0f84ff8e2ab1a62ae655d209527c87752585ac1a1ac28cbe4e40d2033b58efaed0762ee84616759f02513daf9374364e1317870d20321b56cd8a22040363d0711bcf9947b885e1591a917da7805deab3d93a4a2536c91df919fba2a12c2a170daf1acf910c45a3c8e790dad672681e38aef2e5e7d969fe3ca7bdcf75ab91405fd419c123a9487f291e0f8114c7c2c6d42c58c93c7fdb0939e20073d8996aa14d6a68ea618e38ac2369e8ac3e9978110c7858d16075e1a8a2b535217bb6c32d4dec1403e67b9e606e0add511169fa8b9fe8b062e6a93c61986a2265d5ce905ab1be9533279f7e2807e2824d008949fc7b11dc27481ce57186d8a656cd587e2e19208e1141385747f3912f768d48bef4f1ecc9a6a0218408611dfcc0433fa8e4f6c8bf635bbb2bde638803cf523277439a7d54e65ca401cc043b43738b5ffab3fef3337404ee9023f0339d1479cf8488ab3d36c36f3efb7015269c35570f55cf143e0bd954fd492702cedaa15aa03b16829a61fb1a98d33386f42e09449e4deca7a9177969382ec4fc02e9bf0564f57fd536500adc6d6a7fcf7b2c8dbd6e442fb330510e03afd08ff7316bfa1b95e2a2bb843860c3c9f75f9db1e447e59d5f8a8d9f8771b92c2e554c2d4fbdb0aafccac96eae91a2e7e60bcc71ddb2a0fcedac6f92a58f95eeabdebaf7b25a5c3af250ca5ffdf11d01ba95da320fe53c462ce242be49b73e28fd6bcc11ad0341151f354cbd595a174b7513986e40f6bc4a3a1bf781e80db1bcd1fe692dd97ed8cd6af64da78ec6fdd8df7700c8f35df0d437173fd723b4fe29509f8334e550e466a7bc7bc73fb89b499e3628cedfe43fddee4484e1361a1f0c5efe2c4a410fc4a3cf0d40e3df0dde26eb1f286bc3738a660954c463b2271f9c5662f6cc93256a2c9819bd1dfeec67234bc9c7e490dcc9379b92f868442f45c95cd847d040303167a5569fafd713fdcf898ccc55a4d0df2a1dd204727da57d378a5630a50f30457b07e1e5600dc0d566a3efa2242d3b258f2358ddcabbf18f3f3d1526de1017707e892681bc7f8111ce752fa95f0575ae287f96d4441b40b28d43cf0d73f86fa96ce22696ec847434835276296e83f8305920d87d27738f012089c9e32fb687068e16b0d3f3418ea9017be593c439596a2e8454cfe8722305ac82108b763810e3af72f1ab0fbde1aba6e343875d0d97970c335ae0fca2c9dcaeaac905d3a694033157f6cf5949a0ed331782b65d8957fe466e777f8f77150e821cc0bb9cca83f7745444255f516c29ef920429e59fd7e489edd926da2c574bd4121ab621da3e2678289604df113469f4d0fe1ee6d20ee1ec680e268f7472a35d5e89f9585df4734de5a3fec6ee8df9589c5dbd1ea2b4c0cbb6d1c47c14a165d95cbfe37df7cf189112524e08accc84e671d91a8e01728665af17525700e6239964708878d5e992f497bf769ae7974638d8afdb9c87d08de55cf17acd2c351e3c0bdf1846bacf551c988f5272f958785c8d27516336edf68f9b77e472576aa7e992549fbb2d6c35019e1fd9b1bc94e707fbffaf3ae09c6f67a62e0493f5b870f404c3844bab8539eba0dd87c7a28ceadaf803182e4071baf78de08b1308a1e05b03978cd87043c921188320685c87540b54c3f05f59fec5cc9b99cd50ba7be3654c44bc499434cd6a4303356616b72ef7aa22632b89f8bfa6dfdd6b7cf5996c2234f5b8074d75cb979a721787c5925617f9f3c923e390a685cfced021df64b57912a8d25ba776408c910cabad470fd61fae00116aa89d8239fb43e762a04da771d6733747551252a4aa236dc9f01e858837088eef1e08c7705c5ad761d2f9a8a56286aa2bc72ed1ed2dce4d492ec12f1d23c53eb5956cf342a72bae7c99cdcfdd6102d60d80a38940abdcf055244419f870da8eca1ea11832209bedad4ef18c89d16f63da7cce9bcc1a1a37d074b59da7513c76ec0ade0cc492f79822eff6fcffc5670feadeaa11714f6b8eebc134a50de0d40682652b420552fbc9390275977cd6bb9c320709a75397cb571e9efaba3b71cde898819c5db316bd92c80a40cec909ec7ea90ea159d2bead911c17366094e54097f43dda19bc9e74b8236651d1af2497aab72f9636d5922bdad5d6f242bb94f006a476ca0f8f993865066da6902b351a94703f94aa4392d44ab8d3562179216f3540e40f65666fb008bd6f8a514de54cb5f14d73d26f3363c7cd53a94e020ab0777e7d0014508985b90f6c01ba06e69831cb983ac162ac47b68c68dd2d4e7fbb88f3455fc6ce098b6720d60cfe2334abd41d4bca8f75384b939eac3aaacbbccb3bc95d7bd7ab454a4292926c0fe785b689bd6cd2eefa4322773e1ae5ba9b052e7b3a0f48bb4ebaf49c0b8c983601d9165b49d714be2f2d98510f6b449e3659280e62e4982af3367d2ff30e8436e7e3300b3a3f4b425f9500406577876e6930f6d18c726b9d8f8d22d581f8a3813376b5123edd772b14e39f9714c86af11ad7bff210b4d239a98b8659fd9038c5a074bc8108ab15426e49a7954a49ff86c74ec6340d3060477a3993cc893dc0ea4a762fd00842dc1af42aeb0b4359f21668547f75b0f5bc880ea5272e4e6a79b590c728451a685e0aea60eadf28c804b1e891643a966d2549d198ad31f509552d781310961760b3c0583aa39499695d29e27505818cef43edced1046bb622ef682bb1be7dcfac4a4d7f3c933e4f3d5c297edff7219bf0d6b1ce6b6c94aa067336e6c1059f7d0937e0a35bf2b211595bfbb42989feba63890a43f64a56853f6ed811e35ccd12fb5e1b289b2e1d111c6a3a5efa1be1f80068b4bd2a8f0a5a1c1a7621bcd4183a50a51caed22a8fc02f8a42f1bae331ac535ab13f05086efce578bb085f3d978a3b39930b168be3418fcf119080d098159d3394846ad701187b45c0130c2d47e1f0609e57e5f681b044a2eba5f043bfc0ff53287eec3d86ff985c087d1de02d03f0a5abc3eeea31079fb1422daf4c1d3f756a2baff92da74d97d313ca2ac369ceba3690f181094bfe64b36202c9cec77c696286b9859aba685de23801a8f6054a9856c7ccf0098d6f1ffe67872e1d9f2e18ab64aa5e15d8d5696ac7cae29e80a1bb254a9aa164cfbd91c54908c6312af94fe94d0597cb9d241b1cff7c751727904da078e611b59c27ecf3cb8ff898e2dc83b0af85e9ce4de3ccb858618825e0117e58248bf0611f444a829da9ddd82788ca3e5cb35628a19b9d7a811338aa65cc1c8390db51fb96fddaf04f8cca0265c0cf02ee1ca5a2d87ea77824bfbf7e88ea89ca7ade1dd7abb980da469f39fd830e6ae886d1cff107b380023d81b10becb6a5b2ff71e6ac409f8c320e2fc4f3b10bf59315dd8f1b7d1c4a0cd1422da9cfe00d3d0497307c79f7ab812c4c8ae21e8a06b499f6da30430813c6c9cf1a44b59a3ce2ffb06cb70fec10e3442d9c1d0d09a6a715b5184d0dbafb945223756aac59e45951612bd8f0b7a50e583e72a0b1c6d93df7ee466cec762ccd7df81d79709c099c03e5a6ee2b8ae7dfe059ef8447b424f3f7224b983208efea19d7121e89f6d078448c9d54d289ff297619b169369507ff6180dbc1af78930110446d243b90644849950b619b029e55035348b89f52fa5f63fca68e3bef7e9dead2d364e75c185ca9cf137ff8d3b4d773a913a91ae5a906844513235e547dd45aa1ef7721c3a83df591061e589b8721675e199214595d26ff79f8ef296000c68ac7d76884655a9765555762a0e6e5089db167a3a08ba68998142f2cd29d4c20130fabc71be887a27a9d46278187b887107e7a2c3d614c34b01dfd67a93bf45cf0dd25fc96375e8932e69a36ffc5c34123aa4b707a5033c615cec4a4baf4da71d495dfb99fddf5f65c65feac67a757f650cd1c54bc0c2cbaf38c5aa04c5a18adc04d8f017eccd45d9534e7acfacf6f71ddca1f12bd0ce1f066263e12a8142a67bd23e17d5241fc59e6995bf85f987d8e7b4079760e30b0c7b153d7f7680de72497a7f8df07458d89e4cc7a5a0267f4e4354205c81a5a89a91aa3706413c5e37e12d404f386a2f6a23146238ba02e75f03daa11327975ce0802996a08c2a970ba3d149e01b6613ccae611d232a8d984bf94c6d81bf4500dece3270f87b44e2b27cdd525886e7f536ad1b3bb3569c4ebca0978c886551050d69adf0177e55d45cb5be87c99211a54d6657f221babe56f6d8dca0a4e9c7b299d64beb2d7833db49193868c6549a0734d487a654ff426248445d1439389303ad72b62504742d9974770696bb4cc68601b05f14b5e6ce227cedc1b6fe9b5908a2702fcc18d5e19c0b09d2cb0d7fb0cff4d8df3cfd0b0d2f1dbfab2d0ebcc763857a81327bc5f6c017a03e02821cb983787f7f724baa992eb9befb445d57b9dfde7f1015d055970cc007f18e9fb2eec33787e3fa487d51ce8a939008ad23cacd04431896fdc750e91a7217ceb51022c5f9fad59a921829d74a6d957b877234be0e81f984a370b45e7b2cc7edae2990f94728164c718547a1f4c90903a93a5383b6ec4e943fe9073a11d3b90b7752f1d55b3a09bc487d56ecf29de2562b09047cb3660c4c431654fa9b145f4b7916483a225fe0598ec13f454d850bebcbfeb8017c3eed6faead293c4f7c7c5adc440b0d8712291b92f3a572d425973fb2b1bc933b806ecfeb410b328099eca733eaeb1e9a9b2c2b9a5e71fd462aa655f5f39872ea418eff537184e5fdb1c98b9e38015ebb9db844ae00f0ae0ed6d31deab545ef3f5cc4d6be6c9c1b6cf755a7693ed56105afd775dd32b3f8a9da493ca6be3c4fe4af2f0457b42a02ee7d8389b1083dcf648bfed419a087d7ca3b52bdb0386d14bde16c2241bb29e6103015c424d52932a39b3461e7218e39fcac86e8c00585a5766ee3978ef94a3095368b08b6be4dfd4077b8b86fa084d843d60fe246ed80314a93a7068ffa1c1ae7877cf7ae53a6cd0be0295c481b646feefe58100d0ba63f1bce06213488d39ecc8601a7a03e1cdbede299115602f1879028f7a23d304c8a2dd00d849cdbe529c0fea7527dfacaccb7f6f33e512695a66f4902e74315b379890f0d84ce56f97bb93ea73ad1ff10f248b77f9afbc2c29e557c85b7aca606da8e4342f9151311fffb521dfc39212a8661da2f2436fc3d78e7d72a2ab8f5402fa6f0778ccae932f1f9d9c7f1335e5f77e20795788f07ac98583e150a2d246a788c3657b8e529750e80a7b9409f456cdd6b6e02013b166115805b465ae368eddc5e64f1be746706ff7ab7a39fd32cbb36b78e63dc2f962669ec8d33f9f534d89f386717c8e1144b604cfac02fa1457e0f45b637efa851767723e2a7016394460bb39bde47f789765bbe6014d8028836a6db73f20226a0e3e8291f49f03a79fead15f1095c82bb7ace0c6b4f6828239d1f3536dc41ca0c50579bea05a5eeda60a03c6a3b06d4f2ee59dd500ff921acf1b75d53dc3e086eed0573479f881ec8625e3ef1fa11a2c99112f3592e14c6ef8193408ce7ab4dcf3fdd7ea75356671a8a7c6632ee76eb0dddca258f9b5f3ef13137817b267db96a5b93956eb290866eefb8ca54a6fa7915aab33b1290d53af4d9e6158daf4679d73de9e172e5a3978149898e8dc1a5786f913dd07d9052e10d2feb738d73beca989e5b3475faa2fbbe82a20dcc84c63d13c902468dec516930d29af4cd2d818c7b995e252f44389cc6f31ebcb2db93aa54e7a76209058014ae8ec4a46542352ce99ab89d0d102afae87d5251caf83c16b5e573747d8fd22a2ede277e54e0b6fb1f1863a9f6395335c904004377bdd33030bc1c433a599c7c07f3ef08fb6a9e05a7f626b40cd534be8c3f452aa4bd78407861246d40b8e604896634bc6cd7d6ddf5195ef96d075587ffd7eb3558eacd8335b6e361764a151198013f82fa159d62e7fea45dc7b8583202163e44ad187d63f88d2306a92cd85b4a7ec4224919117752ebb12f4ec27b1b1ded9e294654a620d06dde0b530d9798d35fac0b5768e3ba9e9f7c6d4ddfdfaaa858dee1b83f9cbe52ae03917fdfa8cce36ac08a2c2477937c666c4620f4b2a15144df5f2ecfe944113d59187f244d512e3534cd6c6f03f4366a1350e2b6e072a23164af1bf171122e51b5d88815bb3f5f59dd50d2abe3293fc3a9284da9edbef276033c5a579b48246b3eb9c74c7b367dbb2ae04a445b69433d2d93bee32374b2d422f047422e99fd135370f26619870de4ff4bda407980e1b06949aaff3222b26b8c3b0152d6badf2677aa34d09088cf2760d5349f9a2ad52e4f9fbc6811213a37856901dadfd2d76aa9389e808087d3f4c6c32ba5510c118c1792ced9dad1622163232831f74ec24fb491f5c15327473980cafddf629544a793b707653cb5410d2ecbdfbd3997936b0bf5b2baf78572d825f9ba9514f15a09dc8b45d5a912faf50d3ba64a0aae5164dd82f3931974bacd7441e81488888dc479d3fd6a913652113ed40af47fb0b01840eccc0b148408c422ca1080b6e17d91d7d2b5a38137722d986cacef250f7c3ee28b2c107a418516feb65dba03c9ef55df91448189d2d26d8386d3b47fc4e44ff173f64d7586dc513061b2c94f61a28b8bad7a9845cf1c3a3c3399da4b3c0acf6452b6d12829e1d7036e439e812014facfcbbbadfd384e55d49268bd8573af5fc432047d9b9cc58d585fa95d38b3ae186a9958a8838dfb88281a7eae4e3738c6ffe9a0b8e02871b1a828a145b10f0ded4493ff117e68530679a73ac25fca2bd046c662a7c3132eff74ba0d8ec2255e6944927010292dfc7b738f974cd406b8ef60b6660ea3cca37c01f734bf933917ec41ef9f1e4affecf45511a096e98acae23e98ef1fad305e4cd69126abbc8d336e82ff6f0f77020cf614da0de6e3ad417ee263950c43d4ee14923734956ae54e3ab87edc81f6dbcd4daf305ef3a17b09f2bab481deff484eab613bd35c1ffaf8e95d3c23f9f0b5b72010306ffe553c025d7717d51babcd146b58f67c2a9b4bfc89ac98ba60e0c8e140b67b9768289271673269c3f26c3a6e248d5455aacffcf4f31f09ffc5d5c4aaa870d9e9bf28e7815168b0cb36b7532ada9eeacbea7a5e0350f5e6647439d617651949dfb398399cc7b3310db77a66e3a76c1e8458f3495327aac30fadf29821b4699abf2366515451bcbfbe931ad0c1ceea30fed7928e86649eb6c32d000156888ac870f8530b16c87a9ef4a074e11cfb06c28a72f8d670fcaaffba17bda3e1fde1629d3395fe737ed3e3847e69e163bfecc649964dedc51a690d73372931caf4fe7400459e816406639a023991cada3f9a4bfa589f06471b12ce9743630e411895c525dd57aafb0ab0fa3dd81a1a454559c0397dad93927fbcc5f018859a4cf8159254e641a79c34953c7c190c0e78c7fc24286ff49b5e66a179e6a1ae0b5d31ebb2e3d85bc03e9943eeb9eae73a07c0040604a3435fe80dee4263f5cfddd14a845ef2e14a323b5aef851665edac7e51b06d61c51b84f8408282d5db8c1867b13573ebe01e71670562aba707116ebf6391bd416d12457476319c785cc5f9dff515f50d91ef6bb4077e00d5eb0172e40ee2fdfd859a3b1f13404c52adab33da43891145f1d0c5f2b10d76e7ebd3f44710641da9a22cfea393720c46667f8c012be60645e9f5069ce2d45d999a2eaa5393509f4897deb34bc79b0772535a5206dde6b0596bec71c17cc03c77ae2c5901fe5c03dabe4fb2fa0edbe57062eee1b980754e0c0f1eabad72a6032ccce49492504f360741df46abb22f18fc3a98f02a9e7b57dedbf205257e2e8637244d5285a376fcee4edb1ab484883ec850a6333e9a68c006900558d26eb3782ad58d55fe8afe429feeb7da3ab210713ff46fb10c75404019989d6d51bf86fc8ca695db39244a2bab9679b91b4986d62fe0faf3c5c527952f931d76d72f2078b495b6bf5f91020e5d97d6fbd3b1f049f2df8f95553d0db6f860aa103045a9538da69165a532078167a319a50f04816d9c64ad08993a6aeb5a87fe0de93346c204700be0329aa6a0a85232da1f161e2f059111709b0acc0cc70261af5ef2a8f2e2a40bad42e9683d1d91f043038bf158b69849ecf64050cd1219eb65a49ad52004c003131a6ce439203331d9e7267d334386b493323fa39edb9b8a5b998464f55d0034a5afa005fd548df37f6fde3d9cf796a17c2a4dc3519bcd5a51a454afcd691c31873b3629f2144a6fad692ab51397771ac04198c92650a02a93eca5a193c3a6d115abc02582e8000a9ea4952f1583a42a554d81de55184c5520035c07e8f68ea9d610080c67317c0f08318e754c106dbc249eb082f568c72669e5235a8571dec89fd8730012275c3668a3ec49a3fbba1825be3261ef51cb417c1113bdfcbf2819b50bb59a24df0067cab4d196896d3ac1cc42aa878aaaaec4ec2a1b4851e8f8de03b3a1ade6fe3193052fcb28949dffc086961bb2443f9b7054986d200e9b5a6977fcc1c3d83d36c64b05307cfed1add45b8a37dd0619e455f32b8a65b7abea5ebb93bfa0a4bc86b443fd75034cf0933d7cff79fa35e430c4043ec46fb495d2fd4048727cf9dcec2d6d26746e055e61471eb2c247ece3502b365071b59caa201f8de702e57744d3b339378a8e03d28c6658e6fda95948a17798e46234db55c67ee47be9d5cb0b500624f6512c6f07b15005b30d42b5784c4a433eafffc53bc0a365c4e95bd250b1433634621a62799c0aa282799e443b76fea718f056dde9bc675145c16cd1a46f2d09a3ea0f85b0c618c6b1657bf68be395a132f3589092e621105a6cdcf2c7185e7c749f020c792ac154776a872d5f7fd07b5b07362b7fb31696db57d28537fec7677308390bebf1afaf45a81998e39113c99dce608f75a2d194c2feeb0a17eca79c76f837ea4e3747a7d83097e9fad9aeeed6fce7f8c347aa236a9e46f091a31c7818c2b673683ebd8f2660d337164a787f8b30425310825bc8cac537a30297cf9e19288f4d1a4364eafebf03fc9243cafb6b82a723c176a5b8cf6fdec836141fcce2b026b7aadd8a73a38a8f729be5dd85b275b6c9ae49db02e40a36b67dfb054c63a4ef4f8bc2a5adbe4fd0dc8817fa2cf2a27d2675b662378b7c7382c79d220acb698014921acecfc7f510e75bc3efabe8b41fec5262f5cb5968e1384884177341cb0bb77ae87d1ebf5d927f4d4a38b2ab83ee72908c975c5730ee90730e39c24e99e813610928dc543c52e3a6a670caa74d9732825fb134ddf92d2acb66d520677e83edbb76a370d5767467bd3ff7c665ef8fb643379d0346bbdfc6b1606932ba9a0009097cfdef86b2be5a4b36316c7e3b51dcf6263988fec0087505bb11e293701464c29f73a0ef4fd9580f974b932286264fbb18b4c7423544e648f8fdada26fdc0f44132ce8d41942e91dd1bbbb1d92098af8cdcde8c6043589cb0a3bf6fa0711e097bd86efd95026c8845acc0a4f387eeea0e7f181c9d25d289b9b25ddba494a1b82979d3f1eddb91eefd707d0fb1fedfaf80c36e4992b16dea9156a432cf39aded7b2c3e9284476e79ffc812458a30393ac2d2140214690ccb353497bc0690ee13003b2e83ae6ab72eb9f2dd551f5281d4f317967000f1485125165ac11e3e8e5e86f6e9dec8ff1ee2d422a55ffe223b5212e121ddc01490078aa62c11e4e15218d42ca913570c90f40766180a5d4c55b8df9d68247207ebe657ba439e62803d68381328333e69ea51e888da98486303111084184143ca79f2b049d3b0a7f51877c3f1497ff6571861ef6d7d97e986aa517f65ecaf04f9b3ce887e99664596ad59636af85bf2adf064553e4ec92c6b2cc560093ee24f650155bdb25ae4086e63117c6d8eb48855ad0c5df7083a29a88c5884b0f0f73fe927be66fd2c2bd1b07dccb416d0f64ae33246d1915ad97c20919fa7f48223bd51f7d99d728879288faa7f31a8d25f5c34c1abf7962dddd0df425e7a161c6f880ceab78cdc3afe2aa1ccdb0d7ede3113e43467075837e3c099dfe2fb02415c164f288e4e6d4004e5a5d49df863384f15830df7c2f2a91ec8fd16ee3a712f264235023260139ddb0b5a71c895bf6bf4840156af3b93375694a9478d9617141522d6565e70375d427f08d34d414f6bd5ad73cdc650e024832ff14468cedc40f3d27c39348487214e41b27a0b4e3bd7d288a0d36fd4ee37b8928bc21f1fe67f4cd3f45f68ba3c1c99a0145f3b6d82d766e47740a5b001672dc948ddcc5e7bf1aa736e649ea07215b956cc0802060ba0d7a11f7e64b8be6f6af1e698e13d92ec3d412e457bba947855074a7038ce7ab4ffeaaa9aef0a6d08286bf38ea0e99ec33c4e10a9cd5e6c0a4a10383e1375bbbe86a1b7f89ff68c1105c437e301344af8fa8316fb4123be43253c7b8a9a659a4e3b1441632a056abafd921c6ee86c58434b1b72e710795a0491fbcb9659b2893da318e7594fe1a315fb9848eb922e9df132d7d49fcafb20a17f6af111f1d21ddbd5ff24284c49f27acf4799df6485d19ef693072fc1e2231bf78d5abac124a3ff3b24255af6a9b27b59f10fe7c5afd4efaae19751abfea9102052500b092250f8c08cbb58e2bfed362223712bed68e536938cd051c7f818e7af90e2ce04080f9460fbd1912798951fdead2d6e7c43a51b74170f163435fc0763ec1e94ecc93fe60fb599e180860f9f63451eff2d5c1c8509f98edfa64aad163c470682cbabbc56490ac321e756b125cf744695bf14cafb9fe1b03715ba50505257b0452c8bb127b58b67987a4592f037cfe1fd3104ab05ff60d9e26b3d1962715e12e29494eb27a8105f5af85d3fd5f1611445201ed3f9d5f2c27a3b8795193a95c625ac37a51ba21593efa01322e1caf7fdf969213d2d65d37b03fe4caa1ed77a1377a72ff047830a483c380f41f2a26c4020d5c2d62f7fc781746c37817a8332587ffe19fec75402d66c45277c74cc3dc3f6aa9e45e29cd92c764b986580a93121d87a4089bc798aeeb24a9eaa81dedef5969177f6425a7aacc8422c36dd515473a3372511c27d062ca39e4bc9185ae8c06c787f9929d7cca4f6a54b5d1ed9af96492f34b20a68597611d4cf601aff8514ee06c200369d4185e6e5447ac20d5f332dddb70d7df5d185cfe88acecc22f54a06728f8e278293909f3443219bd3cb0f2a0c5d77d13b282391a119e5b7bf497f5eb464c72c2cc880549e69e73063b29a75ceea5b3346b56e4b97ccf3091a50fb5ddc5591d4096bf383c19a3f79cbf7e1083d3525784f2980f6031c309dd895d43695c9b546cc524fa230577946419228339332b60781b2e1a656f69a06a13e9ebeb24a20586a7bf2e68c2f1727769c0ae4334b0e171bedd19e9c23907de90299341bcf4fb43e179f6661c8f191308af768e71833dd7fc12eacdc8cedcf9e428bdd7f5eb187a27cd22f52553f9a72f4404b43483d57c9868ac413ed35a6e1ab53e6ae4021d38386e95ca47de3c1f6890c7b6d8bb3a8c220528cd8a7eef5cbea0fbc9abb96890f8edfa13c16423bd507695e914583d068a760c66c84a3fee348874bc0e27aa23227e13afec9726280164a7133c1a1d694e73f62fd09ee0760446116b44086c73e02f5d2dd8124bc527d6bf779793146794a92648b8f343b7538369931afcbce0b5e34c9eb4d733fb087efd12598e2b70eca971b15a44383842b9c42f4ffd2c58245cc2cca41b05a5498d8007eba6280477be0e670004fb274c327273b93121f5af39ce0d1ed39967e69b50b20cf54f36d2335bae19c4cf7d7041aa93fccc9f52c9ddfde5cbb6d577e0e23c641c74ac6c4aa530211e631a97f3f7363387466e4325e07e886d1d27f5570cf239e3e0ecd6d029e2d6825150da62cf74065dbcec613272ab08dda2d7d8c7395677634da7abc02afc42aa288ff52a5e036fa04460842351c68435187c74f3e7921c8f5177fb6d79f9d31dfa704d361deb35be8e19c34f809cd5a1fffd9ba68debd3dab4eeadc6c693767c1fa3cc82db0b630d22cd3b57eee93c2d2524d0083eeea13dd0b6f83b1511bb98d015779f6481c751d82a2bf9fd3fb32f24cd34c33eb7c87ee39e4ab2a6b873a660a08bca7303fc53f520c72005c9b41f6697dd3f34663a647dcdb49567c6a70238ba209f1a05268dc0ccec2d509b33e4b47133e4186de9de8bebeb9e8dcb8cf98b6bc826f631371cffa011f435ece8b3c4d2bf2f2ee8cd8147c3a3c653d61275004b9574a9935fedb8f93862df2ed5a0ca87c2a0cf5699be3026829722b6b6975f8c37f7aa29c5eb2bb03a5767b4b4e8623f7cd0f601a284f21e818ea5a67ac5b7f08d7e3846779602276f3541d82e6c125fc0bc64b9c4dd5c09c40372f864e63eaa14ca109574f46896e99df53ad4cb9bea7a4ccc265e3405ae6b3b54f37b38d97811c484a15253a90bbee1e2c107247d7f18bc03af5813752cdba6a38a6af479b3c6ff26550d89307c6affd723e56e44d4e06d3fc3c0675f5d3b2efe1a8d3a1a91a4f4332d8663672b285709c448725188025d7088a97a0baefb36e43c39a9ae4e5cf3b3d71370bf46f3a35dd959885573cbbaa5f5e4bb7d9581733179e65314af269701f36452c54527772429fe1f643fcf498fe1b032cb307c68d0b3c8bff2b04b8db411880f02f16fd287b6ae8fecec7b3a4326cd6df49533e985e6ac7e66c384d846c92dd353148eed7ca65b9b22b3e0957320c995f9a742def59e6f59760d9a00cd70373cad8975d52668f25b83a7587e71243d21568f7e88c5da3b04aa50aa7bdfaac4ac75b158c17d1e9837a5e477d48fa44096cf5fa33b28b80b41fa331ca713a83c79b88cb0cd2bf84bcf889c3f21ff9d2691035015e803469a7107a54b0e486d34cb8d896e132c2d5d5ea10bdd20ba710260453c3bf95df02b4e87a5adf95ff31bb3e2d4ee3112c6405a8a2405f5d56b76e34e2b663fc978545a1ffd8fcce7bdce350bbab90f7284d19a0630e30e4b89ed344129eae8e3589833c9a6dee6136192e8b0e895c516f9c17c5eaabecdb737c897ea22215675f8ce4e464b66998bebdd4452b9b02c76002f0cc267cefeb9965038ed50e7f82ac22cf68753e7015bbc66c4eab85fe8812876b100ff20257561d70eeb398e8212fa719cd5e68d849bf5e7cbc090f95e3796edf84107d433cef5156cb66e6a4c4533c4640e3a38221d58307dd8196b2d8867bdf97608284711594cd52dd567119deff6fcc128d396af7332161472799629e7b6d98cfe400f0d4de2edc31671f3c73593485613aaa6850f023a211a4df08fdbc6b676a340a47f7df7cc34e1f4c250e35bf14527ec7ec859cb3e61104916ee339ef43db2839a8bc54906e7a715d9d57031dc27c8980c48f004f42c9f7f743d8756a12040412af7380dc82acc1046b4a1bee868d6603a9bab18479fc3391a0002b6e210f96431700c6670267af8a2d619c2dfb26d970e9f1eaf33fffeee0538bdaab15345f6673d84fbf5e69d5d9c0cc8e66b50763c8366e51388a5df3af0f351ca7fe007bb5947385eb4c557f5b7dc9bce8e2b5c910659bc75ada0bad2f3e7aa430237d3ca5c521b550ba44c3ee0593f32db45f13d08e014536ddc1a34dec0269e0cc58cf5310aca0ff729fc22c234bccd6d2820be819ca6028115b60732f51dc5ffccca8669b5c526496e94e6ee7b3a42a49d17a7760f3816dac0c58c21488b19499758d11496be2cbbc9aa92ba10a7bb30dbb0517af1892768c95d84bf7e0329a56a9da977fd4b1c2073eb221713e25f62ed83af4760fed5fe88baba01aa78bf26023325eb2cb830ceae8c702e831cbc82159e6584b432b81d5ee4bf32ac692b71fd53658f67066be564662f87a557d70583d680830e9a0364c2f50613403b5e53151ad0576735608c376613104ff2d2124281a91f793b32965db6608ed2307c577b43afac73be60dd265dcbe5ce3d6911fe52804fdfe9820e95c5230954c508dd50b91717bda72d83137272e44f2a0fc723dde7bb34de5f0b3c1e15366bff675271f42fe5c4301be52030ce8615ffe15efb37ef1f26427063bfd2d8fd540172051b1faa8736f441c1ecf3614580bcce21832a65128c88461625f8762c97b52bc269f17576ddf0b5c906ae895355337d2888810655a0396db8b5f50e32bb891a0595a66208676eb4680e6c76f1a12326a770f283e3e12ffb7c9910257f9bd52ca4c62a976c64fca27cdfd6d821b54e51ab3bc3de93f7f41a4e44fb6d11fe81a8528e29f9261e59a9fa7f553234e7938d71bafc1de8110d2a94928853e161a2d3841c0d09bcd57b1f4380dfc7539c1c87c6693c86312aa99e98d04b0aa28068b9d0fe049e7b00b1c313baac65b1cb7513e1a7d42fa6d4fbc6069b55a1dc6e3f49dd8b35cf97bec583e96945d7977d98c71885001af71807cf227c9e07c9a23b69727b82c2692aacd854b8dd6a2b7630efc634744ee9eaeede0aa459ffa4cd6cb539b5dbe1cad2fcf8bb38e2a7b8c44faa9347b2e5e1f37df0bbaf99e8d1befe646e60d54a2e3d67f23f3cea48fd52ead174e2402262a2a416d5c012958fa5588c76f9dfc7b1d7de3735bcf133d2c3c7297ab63d3ab08911d83d99a7a084dd8d6025edcf73af8a4137b45167cb2abd42738f9279c6d3b3b55dec101c7d22cdbea88dc78f64d0b6cf6c4b3c61437c517ce55c2b2571b8e5f8fdb9f9abfbe608308622a6648ce6dd9977feb66559d341ec2e3ff62723ec88381de43681bc3afe6d4d264800bf0a74426f77e2af07ef7ab39616603b1a696ff94666fa9c78b24f8ef3dd1d45591185a8f5dc6bfb0c32b2bd89986503661a0fd6243aa245fe0b2be3fcdc6f4a3c2e0a492be259fbdd2db90c7e87e0e24c251dacd88f356682c3933ba71ef1b0bbfec29102e54542ea95f8f8c50443ab666e6ff3ef223e9e52b631e907a171357641331f02ac8524e3c5beb90aa626dc95d3a08390d14d277a5028c779b38f461ae4acd18da9d9acd1f1a53781ea91a720895190260c25ad470f1b8533de1c5d334bec892fb26489070e0cc4658fe5799667e8a02bb8172cca37f5a70f0787907424e4e67cd538698221c525ccf5d00056e5bc82733c2170d0e1bb4d7c22da917e289b060f026732882181d98724334ce427132dbe10d08bc6b816bc69cb369cab8f9905cb2ab54236a3e7b414ca6ed38a911f0216bab22043d2cfe6a3668930c5d3dd99e87774f02f4e6465844998b8fa2590d82f9bfcfe826d9ca59d0ffbfbc180ea74b3735baebba2580f6701a26a271c58f8a5ccf0d282fc03eb0f4df226795600d27549c7e1f3e2cf08c93b3e5f0d1476fb45b6d6024b371948dceeefd9390028c6e8013fa0d24c50c59b204758059e64fac9a321035f4099aef8e9aefee0c95571c90d6e0589fb8da8dcb0618c910e7ea9e55d1d822d31357107feea9d5c876d46bda26107fa04f8c9eba9c2eaa6770a6ac3d6c99374941b6ed10876d515f010c82a2296865b2256d9b80e7ed4e65cb31c247b547771388311c0798039cd5ab7c0240d0a6e7101fb6ea418f7f04522f1c5d65beb7ba8d3ba072cc066ac61dcefb6c2854768b9c61eb2d7aea00b90de7ed8cd5ba818331310a1b2b6e1b62aa36010042c2c62d59aac8bf6d53c75878f9899f5ef10c261e4491f544964e187b82aadbc63a65908c29610bc5ac891be6325423ff439f25bf4e27bf1ef63a9390e3fff644b7db3cecfa2a4717b7fbf7a3dc0490002051c02a8f667883d6762af355f2c5e6d05fb60c9b9c625832a9839fe86233496c019c82d50ec1f3e2e85102325f6b84acae26f5983c5393c8f2f861c894808739c410033b4ea5d54c38429bba6244b2abdfa74ccd3b33dfb8b9b6906a61b009faded17d8c2a66f88a35a727093343c009cb89160c816d5c25a43a9da00528e6cf1991d6865aae468d9a3b578b192d3f5bb825558d9cfb0e1fc15004ff2d43ede52574a58ac36ba5d06ed0e06725cd99ed03003e63a892730e7f77d7b3da07d8264a0b01a55718d5858d5b8bc5021c6d6231cdfb6b9e848ac93709934124590c8b229202f524d37b74fab820c0ad59bbcc9b80a134fd68f5332f99f7ae0560f729c285483383ce4a81a53d930625570f50ab58a91bee6780a8dcbaa28b1767e80a10a52f69b299457df5eecacd23a366a64905f8c48cae4e63b37eab0cdd8d64207d81dec198a4bed71ba7499fd0c1bd3023edd524f9dd261b987039ad1abcec420f313f28a03156647dda8cec55a881ce7a4d66a0f2ed2eec2e4205bbf1aea2e09cbae81eef70ce9e4877d331cfc29c0561cc359a69402997d0d68db9137b3aeea5d19271e877dc2b7cf3a459fe0bf46600322e5adbc5188388ab39da37dc67a32825f4cb099c3c6da9c85a570e742e419afaafbff4e1e7c459d7fa8993e2d00037b2a23705912f27978980e653bc059e69257b3ef721a55807c6331ca64bd7e212c5e4f83935e2adb3fb6af8675e462aa1970c983bef6f0a0e0fc4f39dc9a050ba01b65c0ea8c512807708003df991d79a7f4b82913955f958468b7c669b02a1c2d164e9e140f780ca8562cc98391a710ad55291415d66c648cbdeb0f01c40778149fc95b838e5490062d0c3effbb8c54a61dc9ac6630c92c5eda31c516c02dbda46255fc964bdfec21a6c3ac89ba1f2621f787a497db62997d9fa58e9be377bb6b1b7cabe65538563d5d3ebaa3062dbfb38a65e681497509beeebfb0e57c2512e954ba54361d44d94e009b3bdc33453661b607ac4028a1787b90d1f785d38ad56fddb0c775280fd9bcb1d06e721da03e60452c40c1019cdac2dd43fa510130fd9b100047ee1329e305d6ded7627b091723f31fe1521a4d290a128ec8e35056011cbeff4aae3cdedda1f91160fa67dfcec05e0c5c152ab453b0ec3b3ffb3ca0ff1df165f49e8ef60136f2ec610ff0873a83085c4306885789bf451407b3d0d59720d58bf67cd8a11a577bd6ff3c70776864009255ed5977e564139f06befbad996ba8f65eff998628ce7e8ce206a0058a247b8160249968ad954005772844f664d3e30573c4ec2d1482a19f78ff1305f94d77850bf542b6c8951d23ee307a58fd814d48e98bbdf7c8192a89d44046a88e99e45568a90fd07f366876dab7c50023eaa6170a9cf98e134e403cfebb322cf9ab4bbcaee969bd033cfc513b6ee2c214a8a53fdc9e4fb82bd4d240c0b658dc2099fe3c2adc8ebb7cd3b70d25278f4478b627b298e9000bd748d6e6a6a4542fe4297d4cd4286bf8aceb23c3bc869c204760032633426ece235f7c434fe06f644c4cc757ce232f00d635c8c71d973da6b360723f92eeded639eb229b6b7f95093f0e1d88a31b6f28dd3e3e3e6d234ec3fd23037767aab3679fd290fbb65f05ce08cdb63c56fb5d9bf8e83b9292c24ebcf7465a5b457cca9abfa1d916f2fef957ac9c2081d05f705d9f1b854bec28abdf8f5a9181924ee0ee147af2e1bed70ad2f65c3943c66c114f9780785e7ac233f1d9a21e90b23f630fc8947f925123f4ac8a9d60a0dd7956e5359d0838bb9e480d79f44bea4072065f1f79625a29985c61c0642791af1d068a11418d519166bb21e5fbd836ebde42b862f49b2035f81896c541ffd0e9ac5bda5e11b1ff1638f58366958f09c4f296e6b8621e42eb5e462e0401da48a778b0a78cf6357b543fe8ab642479b236c5a03c56b40af8cfe754b13e574501507a4dcbcabd1fdcfcb6270a4e3d6904599afbf2914caf870544e871895f5d9b4b2673438a6f362eae60538d77794d080108518f91074c8e64ade8627e3e7db73e4d41a4d10ba1fa3a3c0e431e2ac4aeb4017a3f75e32ff3e453181e7e5017f4533e9a5be2d3879811dbdfbaa3294d8d51ca2250101f28d09a12d98bc6a8a3bc66c93719bcf75c9637dab06b29741fcb2c39ee1bba7022787db5bb1066777be065de971979e1e13b275206511f2ae0ad7b30c30fd9de11236d0f642da9d83f97e0ebf552af86e95360ad8f1c54959d0b4b9649409e38ac3e05116b757f7842bafb4b186183a019b9dace2575344d69b04e50ad735bbb1e0cb8b49bc235548bf247baf365dff45b16678087c8374bb7bd5ce7e7e2dc229aa000d9af39a7cad43097fa849acf63f58e50fda73c9b35228d6e42f1641916e6d4f18072b3fc8d1074fc1a8cd8f0900e32b5333d7f5a9433489618cdfb5a514c09fd2bf6190c0db9a5b81924b3ed5a5d1d220081fdae0ea65854d6d2a1f5c8747204498fdfc6b27de9add94a9045bfea97b59d01626f28f7e23be8d6fb920e0eba5a6f5435b109f530ea2d2cf2c359356b72f982c72e36c7b70c74200f74c0b94118229bae6a307c01cce59a2d596ce53bcefd2dc88a046ff9cdd81c6c890a17423a704bd3845de433e88e86c2c630e412dbafc696a1e0f72576b2b875c32458dd7e7273f5d4c745a933cc04443535690071c444c544cd44c38467a2676212d3acc21e13d5cb714c003bc3d88d3a49ea912c67f111472b2a266e8eaeff9cd56665ac3bfd2188ad44133e0df4827f1121c21726d21781a906c0a5b94b8c76b5cc4bd5e9080874741519e83aa75bbee893c73c0a53f3bf17e050f47435c600d9629a23a13c3401c1ae716d4ea3d0df0c0c95121d7793548d74b4e1e2afdeea5be740ba712beb312a381534d21a95d25dcfe99775078f3b0a7fb7c5877077e72a5c22920ef7209ebf7ca418bd29fa1dcaac789b2902f3334205c8556216a377d78d334014d64577058f2ff9fdb4cd2b923d8949a6c85d82d8757044e77b71a3cd44dac168d35740120566764295d3ea0385e0fba82183539ebbccfc1214e908e27e68af2fc64581b74dec218df24073368edb1cfe7fc86f73d35cf88c3ac7e0bf9f0c2786314dc285b1b3b05c0854697f7d6b719170ee33c05cb4286466f414cae7ee91f83bdda60b4fde67fed60939f7649b67e18ec03b8546cf517dee908fcbbbfa17dca7ff0f5453c4df4738f7bfae1f6d3ab4949f3775fb3b7fd1f764e3e0c48a4039d464dc115ff58b6aae95fb39f8be0e3988a5cda68608a7876850661b0be3cd337b32164516c54df69fb2119a1e5dd0132d87174c26fca9cf33c0467e913b0d30549d6b20ebe9455e6b646e3afdba12390a4fe4e793bd0b7d15f6952c3f417f3fd57fb2096f2db1335ed7075b903225bdadc7ab755a0d0ab480172c5c6cc2922bd6e0b71c7d14f87c3c73f2c3265d17febc02ddd88eb192e5fb81a23c428859cced25a010e57214693cedd3935334c29bec08b679e5ff7d8680d8fc99a24f131d7ded54c7e5437912f3474fcd1ac57db483288a7aa85e379874b2e46833fa0f55d05ad94d0d54c9d5fe7f8306358288da787cee336b4b63fe4cefac717655d3f1a6f50adf52283677dbc30e165f1ca1a7b312bb562dfa872a1521bbaa7006f6fc6a8c23fbe1c43a74332b144a2d2e39adfa8e77991cb479c671464e4f996e8046bc77141d520f6647304d3f935f4dd1af1e19a9fdac41cb428f43c2467af879d84601fad66f5385eb35a41111f34e6dd3a9565b80d544a5b7a391a095bbbb5aa0ab6e995e113c879fa8dacfebd2be85549dfa41c5fc21f120a24e85ece67cbe1f4964295fe70618232c347982dbc0aa39a259b7febe272b4e9cc8b73a6240e2666698ec5b80da4a65dc6149ad64e64270b31883f8a3b6966e8a35dd65e52cd8d71017db322849b094383532c51af2f63acfb06444e6eb2b51fb1beb697fffba21de3d464601043f4e4385458deb5aed6232dbbcca94eae921840f1361c0f65ca1adade4bc93020aafee9ed6c507b9f61e51f1a6f3f4d36b73ac0c152c284f83deebed3002d36859301f6ba2f7c33522846dd91d55ab3211e2e775905a16ee447773f7dab22aa8c0d908eba336427b57cbb4ef7114af9ae5684b7cd5e8b52a756831ef8bf98eb1ec055943d6e84866c6b2273a17f0975e6760c791db34de0c1bb373f0bfbf627af2087c9479d3a90c3e865e9f60a7f2e333e81b19074d628bb87d6c604aefa239058f0cd1a3765108d01d7cb71a44bcb771b4b3d991f73d851c5f61f16f1b6e3e273841e5a8645e875c71fc099013d5886ba09cc67e642d827e0692aec13925b8c9e8ff280f4493439a2c14f4b2191a410035a21f0acc408e485751174d63055835dffed81bbf67a744307fa8cdc60d32e0d03c2e2d8113631b6f3f8b86dc70a329582d7a4b8fdf917611a513f5250e8bf1866efebe5047aa2723d253b272311f05c4607cbca09cf0595bd49d58f88c588c0b45c1d8f176803448f7c9ec9f79d93a3680cdea61742778ffa3d51d212d42c748fd939610823cbe3a65b4770c70bfc3966b5b41034259b65185e021cb6d673c731e6460d38d4f444b0bfd3bb00f44f8b34f93248c9f246996af7d1c6325510272a3a2b191e50f37d6cb9e8abc05b1f3bb22d956b797b8b53d972baaea4c68336a973f77f355e753448da9696052f9fbaed80146560f9ee87f291e85b1e114eec1ca2c1d689416aa9b5667dcc392c1133f7e737640e064d1f3b9226a4304a09b679ce6dfaec20c116ef0db9bd5396ed967c939f24519f60f615c06ed958d02b021989b329f441caae6098f8dedd944fd669f0a3d6ec88d63a19266a4c5b2cc22559578682d7b042bd4cbee27b23b059a5cf32978449fbeec4dd34e0d1ad7bd1f08417663dda5e62fc4b71c617d716aff9ab97829df1ffedb54dcc34940bdf356ea67eca3d9e61305f8747432e27d25f6b1fa3b174d367dc4b2062715acbabfff1c99629491030f36e564e80a7e45fcd0bead3fcaa107946988ec28af3b3581f18373b2d846a105dce983bac59e0c5c6d43855f997a1148963d972e8be93034e3fedb7245c94664e626b8bcc9b3e1f6019dec5916c3aa528434d5cbba49edc86de4ff6efc6359788b2daf66585c3735ba76be095abd78c477e77856e0e5e8c9c4869ab27a91330517810c6e7be1c80691779638b4e13f22c2ca6e523f2256cf266a58f1bdfb442d3e77360e2a773f999d9cac20e07b499e5bc653103b6e34ceffe6729f5b71a7840131f0488307547f519016a1ac08ae32202bd71211e8af9f3cea1a901c8b38a670ebe9954155e6e9adfec8666600548ef0b8163e07461212d278d1def67e90601810fd313cd809e77947289a8913d801befea42fda231d4852bf7c7a0b436223ed262b65a49bea335fb86a5c7347ae4c8fbe80e32914ba5df86a6e94d05e5425ca0af89912d2a4de284fbe7824baf6ada80d5cd85b2c6a3ed95f54392a22287d111486feceeb77808d2233e4229a6f0063b9d5a72580fde3cd0eaf0ce2544f06c3daffc046be213c5ca828f092bc86641e5162f46a153c09c0c6c7c69b7f9e6e2929fcbe1ab2997f17e1ac713bd71169ec0cb722f21bd93eae6e2089b442d38360233e2b0e33553a861f5ab3895dbf2bd4eeafdcafb39fc428d0573fac0ba93ff4f731ad862a2155a3536edbb6f133135dc0dda48696de1a25d8ae3f5aa1af04cd9d94294a913651b8fd6378fe757609512bdd01561bf16fd3fd2ec4f284c9656207a7274789d18d6afdd704d2284821832a992db78e23aee0d146fec240e0ba78b16c3943c65af8c02f995f18e418449f7e4ebfa9152352dbff26d3bdd981caa62627a99c1c6a3f69709ac5d8e0522b56db64ad897965365ac19be29a226648382a176f507f08c05aca4b38e071653ba935695d6bddcf80ba8b761d3a0281962cbf512e0c3d9e001832ef7eeeae9a19296a75f6fb1d1283169065fd0b7698a7d40ed44a452a4c89db8a5f7615bd022fcbb5f7afd1e788682cb7debbe856ee7fc9bf72d08937513fab1283952ce8607a6975ef86911fbf54fc2b3ef562da0ba505c75e08558da4c114b2bbfa7ba119e4018264efeef255cfe25374f47e177a5f0494db5390dbc6cbbafc7751e40f38b8f36aeea431a8e1035a8c8d11346ad153883bc8a9fc0b8fa1a2046f6835b2a461641d201810c6ef3592c4a47c13314f213d330735fafa6a346c27469faf82513813b628c4631c2ddf9ca9dd05f9f7c3e5ab095900ee7ec2c542a68b38746d7ebd1f188933798954061068de87c8f0f0d3b556f82e9756f377756e1c79d301fe0da5adb990b874e23512a878adb621841bc1e44a17c457c7e8703f917aa68b596489076b531da34fd850fae7118f0612441af870cd1a31648fc43997bd6a273a88ec2ec98c4668c51000165fc2ee77c49f226ea59de06ba179821cde7226f7c60e2bdf5aabd4d982ab99f0daf04169a4006c72f0301e69732b4a0a6d16a207df3922ab1b605171fb9fefc53c5b40d5c2a9f67a40c4339a3bacc5eaed150247bf9319e5a59f7f716028c80a6a2952fd342d34c7694486fd1ba56654ccc93000281dd96bc59d20f5e5af5ec11318c3b4b4f0833f6a7479d4f440c41d9443fa7107e48b4e58287f949a708e30adeff1bf1e99b8e08978c10b8496a86b6d2c42d7b99c08e74a1508ea8d1b5eaaedfe62a8f42689358ed2ebbb3b522d0827a54824357de3d3229e730c17a9e2d378969c9a5752a5b1f7b99dff8f88cbc19da7a71d055600f729dbb261a16ea71c73aefb0d551ed49fe6f8c5fd127b99e6ead18fe1797e9c13fe2a025ea540a6bfee2f76fff3cbd6935ce227c6753b4ededfc3f44e106b8de951c3fe3f4338df6300632581d965ca397f87ffe2fd79f98b16dff14b024ddd738fd0577fec6ff5132653eb0858cf342b231b64722f74951762870e9bc9630ee678e6a88a18cd4fbceb4a8206f333c2be2542c4d1c297f6569619b438824f5674bd1ca07a573b7450f49842662c00ccd877e5d7277767a0ec23d39ce08176d7bf5466dff812b50628bd8fa745758c4826bfe382d47d4ae85e32c37084b5b8fee7f317eceeb0eacf988d7a212268616763258e57794b4bf74ac9e7063f513d51aff31ed19251dfec251722318737fa278136c9e1a53fa9336cfd402042b06e799d771a94a4e9668e9da82a34d4650d3e165c70eb7b29e17113634b0b70c6779e352f1162d83dc8f1b8e3095329a36929bf6ede0e9ecee8aee6cb07577540cc2e1adde004be4d10b6a9f90baf35272174da2c6074c4150b176edb98c278957b6ed6fd3f78c2dba8462534014294332e949c1bf149ac561aa9ab8a10faffb016d53ac14614eae219e20aca180c1034dfcd2a20be784b62376ef430e4fc8e1a5e9a61b1f94f38db0e27fda52150cc0ac5f8f61f7afc5d056a6d161b8bcd4bfaf527f1ed54ba3dfc9464c9993f1e572334f75ce6c42b3b0296eae7577032c18792952ad1ef24169ff28edcd3e23de1d6343d1a2ff81c876711de4b302172431e4f1745d81cc6780e799ff966a3a1fb8ff83f40d03f532458a7c574a548b8ab77802e18548be8af4af6b33e4da4e1e4f607b408a917b443cf422b32803bf2e252617d234b52aedfe1a8ab5b1dae131e8501c577a70a81e9d9d54b9b672337f52538c0f61775f1e2346752ffd4460c10e219f90d2a05cc4800a2715f2b6a42e7feef3f8e1b0341e1fc0b8cb32e872a7c4f3fd350f4db0ced230c2174e852da9ba240e19682f62fb66d9879cef4b28b5383dbd5e35ba2feb9e0c07aba72c9f8cefd7889beaa629d71e18485891df8b6c904d3136cbc57fad1b59fd8b17f884a175fd2bce5732c112b32d627f8c54465f7a3272491f23b18b2fdff74dbc700cd3dc3a3e432d244dacbef5fa0fded6f534ce4ff9822e0139b4e4cbf406f02312a47690f025a7707b5320572e40ee2b94dc04ffcf60c573bb2833b7a20f27f3bdbf7869fbeff9ba3fe61e3162e57d66bfc6b3626a7aca36714f91315693bba27d22a9a0fd1d078c8872e05cb07e71deaa1f63da9fce62e492164f337ed6feff8151c316d4d8784bca39692db13f00f68e6eb99440f9bdf5c253b69b2d04a71eed648deee4109d6afc68a36218c7a03121c5531a4b0b414df1d67b2783c695639fca8993175df0f5a27b9790b4e83716186d5423a40c562182f9e4232a71199ae8b9a26f859c6f40fdcbfcbbcb162218d2c15db964b516ea6e1ed5bfed808bb696a4ac15e6a7dd0edc5263b4392659ad0d5c86d04e027f2967848025b4980ebc29c0c8f6ea854ffa0a254a772fcf030a987e27949c0abf08b6d006a748f86e1f5cadb257cdd8280e279dbced673dde3b996b4ae8813fa4ed67a5484a569f8246d1cbb53ddefa5bfff91ac7b38a5340b001ff9bf28462f8f22053a354d3b1a8dae14d430b82ba52e369079b3726415ad03ad54978c2e1844a5508b02a8fe2edf2207902e33d37838a68e638aa05d5fc1a43525b6f074dd972755ca3a71b52ff615a4c7e8e4374c78446d8be03777b62ccc3e8bf6a0eececafee666ecfb4fbf17d9a16c37a7714559adb543a3111f24bf412243e04820acd51d5d7edbfc1d4ba6a5ba9c4b379ccc14df2e4a858a5b66842be287013507a43c76bf673d1e8a963de60e2cb3154454cc82f385f013d9cdc43234125059226aa516b36114f4c79934a2f951ad6f84f2b70dc9a09d111eddf6ed0c7b3e4addfb32b7cd13219184954da41e774b4fa2cc8ce1cf3c68961784d9f67ffe66d61c0f7c2401eaab6dd2a301a8554a5dea35945ad99ccf96f643ff8f65a4d50148b6e7f5a7133e5271a8cbb74a261ff00a83425805073c38557368ce1385cb78ab5c976e5e024582609bf2c857771292dcd2c544ddff70a3d00f1a977851425a7b3dd9b066c51f960a8abdea2292fd46aef1f72bdf4a92733ba75c1e79cdf106fde2137c9f2c023687d9950457b3479697c9e7d8083e5a2dfbf95825d356dbe1598a5bf4f21bc7d5a39a3966fd21409587883cabbb4678d7af292715ce636c9dc8c417fd9fba1b479fba0de2f5f0897008764470a4346bc9f32fe6ff849338c3611bcbd2bcf29f1c91f7b8332fbfad4faf961523149a81dfbd341f8125469f6b9e6672c7b354fb392db7558218781ba41b0beec418235ac07b943569f134b52c25a94366440c2f1a1d12ee5bcdc233a89aafc3a1b1230c7afc00b4f077eddc7895881cf3ac871db62bdcfb04b271163462603e0e209ea0938fc7f8a05a5b38da638c0fe1e4fae0119cfb6b5fc714ba141e06f24bbc50c0419590c35d9d9506091b66feebc34cd53713d13c9525c549269af7d255483555cd2a64f51345316cf2da16f3bafba360749f9f181ba4f18e65a4ea8864422acb5eb1b66e1ec89286aabc4091f9b86437b85486f90321720b4b7a1f86a4044f56da62b2f805f905fa495f2dd1e63de210f0fef3e55f98132d2d560c7b99a20d33f7e46a08597a4e093f4a34d4325e66359b2709c41a8403653bdcf251594c0983bd3c0e26c203c05ca0c204f9011c4f8cf7a2ed683a9a8639422559a3427bed9eb11f643c7a1fc543146a98a1457c9c623a17a92eb57b839137d695f27eeb6809477ccdfcb8dfa0e9bdf944ba8bf255429cfea398479e9cb087c1bef5f73567bf2a4512d9afb747216377cefa130ed336ce405840dc024e49e829099093f350369ef46ba581ecf78f297edd4fb32b7c92db59f7cf3b5f231cadeeb6af289da33b2b63a5c834dacc92bf4b1fbc503e9af7968e149695fe159aab71914a4e80e3c3c6121fe5942b51d9a2c84c31e5063a85fe635cbe7eb530d0f639f86fff833814126804bd0e4d63b82fd34dd431e1b90f1b555094e976bdfbe1dda09e64c2fe006b3c8c6c098bbf775a22d1b14fc3ed8998a24f906ebba8241d040a3199d19226e1cea2f21a6f16084dd820cad015dfef8e1e6a01ca4a5f1973c4ecbf1897f890e41d2d3c293db54a118007750a9f6824c5dedec84bd2f875b4a699f8fc1914699e4f204f608c5c5b486c3085005bbf1917e7fea796a8b6e71eea915450219e44db4b91118bc35fa1079bb9d55a01fc45f95c7b261409a5ea12474cd5f6381c4ca7962e25f86a0c4a082474135a198b47854fbfe758ae03d397c06463850bd4029bdeb389cf6a2fcc5dca28b26a0952984b00ea492470e55ca6a7e681315f611fb79b95a1bbbc78573e2844759c3310fec6eda8d7260f683f12dd6d409ae9f5e6f48e7746ff7ffa43f4734720339160bab5d2aa1d1e657e1b9011d45aaa448968041abd99d6224541add5747a197903cff463a79f2971a7a738ff2672c7f366fd7569e8ce0f28f462f21e218f563af7fbe50102da9a18bacdfe60f8fce7fb8137234e31f98f66ac3c982d8cc72d03c0b07d8cd4e61ddcd3fbf2c9a95bb1a5f7eb56c3f969c762426ed262e20e874423fefdff773fcb1405553f2527cb79a6780e95d9c127ea398b6e838cf830f07a2ab1ef193ca9fa5cdd4d11a0ecb29c1fe0528f9f59d8d5646b38b5745345869d49cb0176a5b4016dedfbb7f4d72d100c146e0a82cc64bf96245a38060fb80da80358fcace0d62529f50b59fc54ca76860f5fa244f4ab52996cd4564ee8806100bb2894a4470b0737aa5298270bf2382f67d3dde27414d94e2fe7d2871a1e27590939dd153489b85ea3296dfb6f0f1864649c852132290512d0eb29785dbc5d9b190ffc0844ed125a2222b2fd042c8d2d94363fad51420438558dd0d32c0f3ed821a64c79b0eba363960a066416d44ff2a9d4e8a6a1b5a2efeca7115ccee86f8ea8b0105f047243ae163708d38ee91b2e59779426faf0dbb582be6f159c3d81dd0f8507f72c01d97b1fdd6dd1bf2c5f846ac7bcc42460179825944fe2979595a2f869f58879806f361058111e3fee0604e85ebd9c678ef11591118c618bbf69146b0e1f15530e25862fb0f03e2fec764068cefc125d0cf49f8c3f32dad5a2681b95fa57c74593f99fe52eb7968eef7f1e304e5fa45794d582ac1bcb6b7352e104cc8e69ba1de6ec0efbd28d694746e6d863d40fecf4fd5bf7374f48e96bf6fb1d600608446d2dc59cfc184fc3d9d26682aaebbff558a216f897fb807b84104acf28c176fec726084c1af78098f997886b97013f6955fc662388f77010813a36d2904b886b93f08d2b3a46b5dfc135aebc97b17b873e8c685459bbcbd2fbec22161c02fb06a63f0b28e94ba482e075e19ac8806c405b2c25486a9702d3397528c0bb616af6026de413cf8edbcf6dee09db38112126589028efe0795ec8d892820e7ba653f8f69b2124a24bb6d73c881e5e6492c05fd1782398b94f4374d9e58eb2b2c90b03d08df17acdcaf3edb44b87e83692b6623adb47e8fea8096dd90adf6757716ce1d401e7bdb8ce98ee84a4876a39379ef4ad13b47f67ed6af74e3eebdbe8990ced26d973faa714f71be6d5eaeb977a014e0c33c9b8803e0786a6bc112b12e7cb232189c1dd2a606547eb1436c9f2db325d68b4604fb0f79123425b6a89ba3f91db098b8661af9d3cea4ed461b216a38427c6b5e1f8dc8344d60f170bd7c109d8c757b2577417cfb3688772fa547d9082746ed816e542d154a00aa3ac2703fcebe60345dffba504af2acb73c2a2fe1cfec9b11b0716f1f8895ebfff8495788b76ad93f8cf07927d9c4824904aae14c40f43131b36c67721fbbe8e5a817b74110e43f8c7bb5f215ad9deb7295a904eda874e61ed4f337ee27f40a5c67e8d1858896e8664e8ac20ab087ddab7bd13b6e1f44301ac7f95c633d5cd9c16bf5062cf84ae3f44572a250eac66d27488c33f37148db501928de03783baaed55a096a383da0df6feab688f5ac2228cf854d07b72c7615673095d13c677442e7d589dc1ad6b14291b08768491ba2e749caf10d9831de87bdbb5618ae67fe97c6132afc471608ccfd20fccc3f424072ece3557ff5ff06fb687da17b7c1731403afa908ca0769eaaf76733e5b7edd4ffb96935527cf0b11f62bc60330d4c197b48608ac0f8b211df16d2dea64bbb9e877ad3de874395c8800ffbb668deb0d55baee0271ba2a7f1d86f8d210f07b7e24faadc366cbba92b047d62c0320dd20bb2a1645301d5052671820202fd24b7eca341e300b5b5b1e47531bd3c1237378fd668c7f9f4008d5c86f5b914f09f77327159823e6a9b231b4bdcbd7909b584c5783f40ed491d68ed29ebbaa2eeb824e9f04674e4e782cde708d48a2b08178e63197859d1b05286c4109c685e234dd8acdaa5e71e17e5a37eda4ff96f84dfaed29dcb4f8ef204ec4fb28e629845fa0b2c3636c9592f78aa3d369ad6218c126c9261630f3c19761ada022bca0e6203f5c2411107262700d546b4ec044f92cf3f41fe33ce631fde2bd7efc20fee10ac711285ab3daad17c1d10fc578e0a1705eec1f3d9437484b34c5daae234caff4624690ac7a4c6327469e639561bfde6ee4fad88011423d0bd7abebf7b25fe9252dfdb3227daa1e324b6e8778d8b668547c5e7ce887a9967561217438ae55d58c6818591b17e31309a526474613ad62406b3a262a1f6a956e3476e30bf22e12c2c95231eeb7f6d541b0d292432d86fb648c5dbedee72ae222d680e6392ef50845f916d4c2dd2ef193bdf2d8a4397f62f7b9f24137123d85fe0b8ef893292a7b3a46ca06cb9af8bc8acd75f7867a3c8054011ed5dcecf44ac261190c7a6147dfd49d269e28e0ec410b9612f2dd7d83354a90ce103e444c3725d6052a41179bc4a8455277b4d0ed42fa68c3b3445719f3b4d3d0b0ec2f43af8fb747bb39c63d49ddedd1f63141e447858d5ca5fb4214b583eda5079028580904977179b72cebfd9db950570b822d210065a6c11359dc33a2148569d24fd889b2e69d1e90c769fde4b24721154f4dfabdab76ee54a84c7841bb285225d2d218ce4537e5c5537ff4ee6a00a1ee2f399ca5ac9765089ba2ffc4ded3fac8360793f25bf2036fd9823e0fb01ca6479c474ad6ba9563af65b5e559748fce767d271761148a6c432bb7df10667f5fadaa266131e4fcb9b5ebeb164456a3a4f3636ebcd8d1be764c9e48831986f88e2322d231410d2f5c31d687c6e215951c4bb0826201652af3ecc49761c40ec125d37b3733f8305253ef8d543c6145358d3f671b43c3c5b881cfadcf5bbc29cae5336bab4e228f8c3101587b219e15396010e01492e8093e36d9d3d39c8986bfffaa7c6510ba32c3658b0fe54780a11cd6d3591fbb90bfc7a5163e0050db6dd82ef58c5f43e9be7b55b6b306c361ab3c682cf068009a44a15c15329b1a55f6ac84e84392180cfade8d7b137dc24219f8fc544b83e6da077e4e778d5dfbf6df4595c57cf3d7811bfa0e398a2a7df54760b2015a453d88e099ecec4cdc2dfcbcc8b9c8468272d6d44fccfc8224312c0d9be043d52e1061cfd9467354769767b1f9da31ba6776321c4fb556b2e1dbde90f54ae54561c193b2020cb1e29be7b1f47182bc03acd5f1bdc4e01f96171b40ef5d8efab2de9c8b53e7fb52baf93ff7d3b05f939c5d3781a4e77899391bf869f88fd13c489e2001de9ecdc2abeccd554f45e92233db761164626b9c278025898a84804209b485ec12a181c3c9849cb515b3b5b73603328ee171ac1350e12b0c581132355023e1a86910d5db4495c2a6f79c3d22e057f09f3a4538df7435c480b9f7e16ce4034e08986c0881913a9244517cb67f78b457bd5cff2afc7273192274ba7a5864dd03464439bc0544e7f21596ef3e0fa2e275a12481407b4618e23e75f61faaffc36dcdbe1ce2b9c27b35e7c9d29301f271c4b89a29ab4e83bd2088a5ac63ebbee04549fe1cb05aa423b2bf5c288726922176b94bb900b47756279573cf0ea9ecf0ed47715dc606d5b3a73c8cfd679dcc1785b17173e82766508d05e20878fb0ac867409229b110e2494f11e3cac65dda52e64e28a516c7a45a26b4312fe657c5919186495a5765738d1e3ed9c9170304e1e7193d91b003a9de906ac69833cf8af35ee1ea31fa7b5b3cbec986c5e108bf6d80244995244dbf713f3f24b0f6ecaa5fa9d7a2ee031f3869d231b6e47b34dba951cd157a4aad9d46b489658659836b1b6ce93315ccb897dc082e95970e6b3d1ebc81048bd07e57989cadbf6037de0ae9727760586833eebeaeb77c7e87cb6996682137862f4ed9354279bdfc14a6e9c6154a237f324d33e57d2e60e290e6401c2d387161806b2ea3b517fe1dd5d0578cb70b13cdc1526ee674c79cb52caa6192abde6cba6702bdd924db448520bb3d77cbf6d51dac683124e2f12ddc03e728fed28d3beac9e5f0f05367c4d40425b3332692a1ffab3107896cadf742a348e5d09f2e50335be0697b84323d3af1438fe9f47e8222f7144b6f325544c90d0959f649cb3e214dc2c14fdacf2796bfe5e97f3acc1d7f2cf4bc854e426b65ca6723fc31245094e929e40a5ea75f4247ac6de624b42378fd4a4e36ea690d459faed3d3b7d29d60e2b5ddea420dc3fb43e759b6a113b0cd0df45977fae1559c5df3a8f4300adbba61904e6c12375e13e44d13ffd40fa324deef1c8070e7b6d81cf1e97b8f3ac9635c970a51732326a740303f2bb18f6e42680076a0eea4dcf0ab71f53b7d076edc90893f25b844838b7db3766eac166ec996e6549b42fdd990cff1f163e81bf3e34fa178bb3186059923675e667dee12510048363244da58ff939b4b0efa108ea7679dc87421fe28eb486e142d4804a5fe7906c769e8d195abec8144fd567d7678cba8b39d826b406429e3e0ad3136117dec8d996b338480bc0dd1ea3c3149138348f216a3e97b96318d169cf70afab4de5907cb0971648bc383e589eea37d8ce614f58e5c29957a502d9d0e3a3f5b92834d9fc9dc7a5161ae37788a674d008459f3df383da85ca09f3eb06389986a88d1196651a985c4567fc8aa43e89cccb2c70412129e1c80d3327e7e9eb5389e2d82c55e4af508d599a22eb44776d52989bccda991c445763efc65b35748451405ce19db034efaca4c794a79b962fbe5ecf2fef53da149b71ba06045aa8b0500a3137a523acf4870d93ab1cf1b1a6f64a9c2cfeae4534f3ca0a8051ec97d60f5f8df72694a38a0e21daba4fb2f1aa65fd671d1a1f88715b771800a32bccbd82558374d114279c2240a669aa89a04651388d50f2ade437c67add02086071d4316d165e735ba85eb4f8e7d19fb30c97320714a8e424ac4e477256be727a5fff98d07ae262d4fcd90b279bfc16c76cbd4b8e42302da96f594b7f5d734f2a0b0d35906a86793f419ac2a90346bcfa9d6106f02e50230c65478f653b410750e1e5125c57ffdf73b7d69423cfd648227f45d02a2fadb00f354ade69e23e7ffd31839cdfd15d1020f8fb9224940df3586e5b03afd165fabc2190399b06075ba295aa001a5902fb6163411314fe0b2eb50cd7ab11a6c124f790be40378d6cfe431549472b8d1f1f2dcb039302284e7c5d4330d1556d350818da7ddd3aefbf4700a2b07795c947eeda6257dca73074036a4ab7711e6de335e81f8ed95288569a740880a7232c0f4d3db61b5248f6150ee740dbfdff21d143f64807d8c038343920d1c11cf7df6bedfc38a368f4ff320c70b85c954528ff4ff65f7036f78301f7dc09c58ec7e0ee5569910dafcf77495b45761b559ba74fcbda1ed57eb644ed80d95db02cb8c05d871ea1450540e310cc7e1e0f010e73906964ea1cb39b1cf6b7265ac01ee6c20e3ae761846415a9e1cfde938558d7f692df6f4d9d018394126c70078808498957861e8348d15319d7e047ddd3757b99c815e4847fdf8b7080c82e46402f6fe801a2aa4b881e82db77fd992afc18b386bae2e8e03d3ef9614d43fc3ddfda6ca9600f5bc3103327745e2ba16d73ef58a1c0ed2d5ceda1fa355c2b13a4d500606fd61e170d1c89c26f141d026098e6506f110633ae4893a117a4d5ec52a456b61bdd2c9b9944233b4f5c058db84b0751af04008f5677d989fb038dc3ff99bc6d7d06395ca3977c5380e546e1f3de1bcbe7f27d10804ec932ff8f8cabc7a6c517f47e302592232b5f520bc74edcfd278e38a3e862699deae9a99aa91005b0cefdee3e114d81f31e1e556fc1d827eddfe35576e7349db07a64c099eabdde63d9c695c0979630d9245a02d247a17a1e4d5ee20e59ade1d1307803ab1d11b37dae4c7857b9c7b061ea5fd59d88d7da5a15ccf0db3a5ab1d819ccdd934540ba5a7b836479509406d7eeaa3bf6a7cc714871fed7faa478a209a4533b79e55863bd450754385e39171c5130412f2f805b973c46151defc9a9a20abd5ae1fb4f8b73f987b957e4d915f79f081dac7898cc03a147561f5dfa21dc26b2a0d8f266fab3fe3053a9e19099e7a03d51f36b087b58b735dab4970163006e940c7111a04c670158e7b009c222380d489ba314bf64d164eabc2ba30eef259cacb6ab9e90b29f394c2dce6c9ae1c6fa166e8d090421f7291df441ed3ae0b73e7a3989df101b840e0821f738e409e0b184806c53000512bf2bac2c7f69fa6f81f525ad06256ce755fee28eafe6c8eceaa406e9d39d4965c78d56593e280370e7e4045dba6ba3c1afce63cd8e0373351bb9a59c42a5cffb1cb15f83f479caf02ac32935f9604a9963dd23ae120717bda61d055aef632f4c2eabf0afef08679ac9d8cfffb19ff316a77e6c9ffd28c4c16e41ce41ec6010d1ff7a3c8d3963ec2810d16748cd09379dec808cddca0674b4cc39520252ad278ec3117c285afe12aa9af1d24f9664501136d00a145ab228df68a63970ccb02994820f2a3de807a0a7fd5fdcea2dcfb8b1c45b210fd383ffd7eefce1b3fd1357edeec34a86272d16fb9e05835b4e9da39821fb6a04d947ff8340ee453a7e18a503e614c42df7c466e78bc9402ffd336bc8dc68d1999f2090ca77b27dc47117dd427a2aa45cf8180630d0f909f6ffd8e7c09a20baa847f8425180d3b0b2a4519488cdcd189971d9571e99b2a72142de70c9280c12a5c6cfd7435eeed7f155ba16e51a5566cdb6714f1ade6718de89df6cf9e0f2d34a9ab7792549468336ee5a4e5edd62327ccd81d62b84f2273b5435651840cc19bf4345aed0fc14ad852366fad037a775e1625504823b2e55016d577fc2173e3b7d2a54367be5c0b65c0d4dcb7f6fb23540dde08eb848ea32f055fef86f7f1adfb2200152ac841b1f1cb999ff01ac1fa46e7f0deb3ef4fa40ede6da4b1c5ab5a0acad40cbb6766be0a728554cec72b694b3077d1850d3e30ceddb7ac84216fd2b11d8585e384e5f942be6485aa2db556eee3fbfcf8084cfbde93534e6df7ec3275982dccc005c43a6808972138fac6adace23e5d4f5e775ccd3010d2fdf8c82d9e48c525bf8c983b29b390c2dce6cfae9b5fdf9817b38062e8c45fdb6718ac96c48ed4c0a65f679e99cb68b465e5e46f46a6d297903daed8abb8eb8eeb312e08aba3fbc83612a995755b32d23fdc4720a7216e70b4aef6d3bb8610f7ea64c8474a0310f48a03d0804a8eb4d20476e202ff3fd02c4a020f308acf7f05b647d951c167b62829aae08674be940be851664755e6750848940d639d3d3a58fb7e305820f5645951d965873046e9dc1fc4f3cf312d38839dd4a23e8b1e7cfedb5f1fb2e25347ee85797cc66c1535c52e480b8217ffac4b99d06b39633ae7b345d5661f350dcaabfc29e48d5006ac6561c9c240bd694cef74df1f39e1eedbee4cacdda1e910eaa2421e7733f708c2b9f30dc15fcc2409d8d4c25dd5107caa3ebca9c997a538a736b4b085fe819e0a863b07ba1d1f556589e1be56366122f2830549cf4956685dedd0ef60c3a52cc4de19f98665029e4a9c99ad239f747a328f56b6dc3b0eee392a927197676ad2add85c9c0eea90ee92443ab76c69822f8a780ebf3cb83908ea7d67b809f1fa1064384cb3806f65f26287a8ccb29a783f4693deb6cecdb04b31e19385704e30c06d8946f0f94b31fc6a9e2180253f651379a0bbd6e0f8bebde4709b1ec2146f49b466ae38145259b1486f25f8e525d11773633a1ba2c7827ce593befca85735bd69656dd314b4bbe2d50b117acfe1fa728a2bc1aef7b77a3c308c7ce76de49590c0d944e6f335f06b52104409e8bdd9a12c92aacd7fe879126d7e2b97b850035d304f9dfcfb0cc6155367d5b00433ab128f8520c3b9f0c777b4ce89b9f4171ace5266babe061b8590f4730370f3ea6279e9330e05238cc41df721801e58bb9fe525af7e4012878a47f2be68cf4c3e04900fbbd22d140906a0109cd5db2fb89dcd46728b56d341ef1cc315ef0fc53d0f97461f8cd60c23511142de5c5ee57e20929557a847c518d1bb9687551041974d33a430b40f0fceed4fbd2c6e2ede06bdc42d05420f5957d9b0d8a5a188c0852032992c3db401acaef4b528042f9d80c3361f4ced2adde9fcead248d86bda930bf9357fe2bb0dc1f1fb2f5b8564aed045e57d05c44246f3f2ff03df94664fbe2394315a6e3ded980afcd23bd111262c75a79e85fa1210936cc448306f9e0bad55cf4afd42189297308757cc00fa1ecbd1c447aa6d4e4c2164372af6f874e3235ccbe2edee1bd8d9d2d71af77f52a2e90ac694080edda5e4fdf6d1839b4c20a277e2bee6cd0709a4230b9f560478f8c5614e14f321c92f06976543570119aa219625e23a701b3b385710b6a58c5fd7f4a387506acb10dec056056e61a06a6d09baab1d8d6cb7c33adf70d0d91a91c195f64bc45c10182216492bb5829a4030c1ed1b4f1a789956cdda83ebb6689a67271747329d4e7df0ca3d8818ba26c5ce5261eed4fe00004baf181cbf623188cfcaa918303d4edcb7425cc12bc5cb68f4f1832e2332c5bf0c3a0ddd7b36da15ea225770b3a64ba01327d412729d1ae029f3f86a88a255d2b91bc810a98feb58494b9547d3e3e9605588180ae190bf2540c7ae4451dd274d33024009b3fc31219a4867b82c9cf1e3f5f85f8baf3ef112114ef765233495be7a502be6a14384e9b6127b08161490fe13e741f29a9c39d69ff254e35e2fd3c013f4a6b23f0e7897a0f45999f454f54c239a59148181feb445c89a27299eabd843762373ae586f6515ee97d278e418d12c618f3568ba9a02840174510a451915744b1bec0f8e03d98c923ec23e5d0c3a1a88de57167ac7f28d7de0c68292369caeb61b9e182eb4d1e68d2f162ab1bf62c5a16c121b788077d753fd267dd8e20d2a3ddb01b4e7191b3714b3864f8d6e15ac1860b44242626a26d65802bb95d8fbb1e76ea1327764a8c61fbe7a652cc576d6019806e7375435df58e5134c13c882cdab0bd92adeb9ae8f02e68030ba83632ddeffbf56774b1d4f55527fe59862b0b22829c8626f51137d28c5fe5fa8a0983f76b307b661424b7b1ef15222bdd29fdc94cb035ba9145e4496815d3d7eff4bd91420d3364927ad13b12c88dfdb4c279e524f1b09085e44856844a000cd749c99126de9a69ad14cf8799917e435def9fd0ea652407c5988173a1557f3a20d7e733ed332f0cac20309ca50e16a07559594a5b4784f565b009e7dcaacfc4e5b3bdc56ff5dd0a0f898090d78e0fa7ed9b9f88d512e71497cc526a12ee660cae3c06c9f5c9a27b86f53685cf634b65c9e41590de82ff9d3ff025a1c5d752374fac01f119d0bc77954f497e8b7c944d4bbf2887895802f895e9544264d89c537c603d17180db91ca9bfd838ab8d74af159103a58f3d01db9d7acb9588ec7a9e4ee4b74677bb20dcd7be7749463147fbc887d3d4bbb201d097d86b69c0ef0a13bdc8e64086d7c20067a32cc5666cabb0ef4c8c3880f8a05ee9dc14b330150b8da2aa993572ffd22ed608c6fe225f269f7bc5adc571201bfdb12dfcef328673bde90f2ebc9bb7c5485cab261d9e0fc799d3626f3f0aca58752e369708b45658eb88008afe255cf24f50b9ca1843f76b2b1b80a9130ee1c460e167f140f34b8df65214e99cbadf8088bcbf56783a1e6c576616b523e27a7ebd048ce2b5f2e53d9589ad5b9a28d1e1272b151cfbda1f74c82300b9828d6ddf85cb95388e0358e0066282559b477b8b5ae0ad6898af22c3f639765faeb22a930c95459e869afca6382482dccb0bce5094c54a8b9b899af6784ecf14ed16538408c4ff2f9cd0e0dfa4979d903fdedd2c7b6593f2944eebc2295d6c635730c7fd40471dabb50871993ff7b1bd89f458e0973f469d6daad8103f266e5869c85f8eaa1902c883fe710a2ff31d3522b26dd7feda9f72b3a3a5beed7a7ebe18692e81cad1deb1e50da063ac171bef8cd7c14de37521b4575b29115b886d35cff0659cc27db3c8a57e6bf075dc4b160c0c33fc6bca537f720aa39e42b9d01ad24d0c9f6a8c2213d206177eb14791f929a94fa157f5d7f4ce32a1a3fde916e2ea0a5f3ca929fe2095dd07b8f6c5c7a86da07aec34a26056c05185c715663e23e876d5c1abaf942f9cb58e5bb85d26834e0634513a801a37e7f16c2542ae10167f18711e51cbf657efbeccfd8d471ed1b1a09c58724daed88bc68da07921b562ad04ba8d2c36e1c9ef638d1044476a71f3fdfd07542ea5b089ea891b8997c5ac544540e4fa5829bf1a2e55fb1c8443a5d8d6b493cae0f8057e97499bb3433e9f92ffd6812608a043f1d7e2ce1360a91d1517d330046baf808c31cde8fc1612edd1675df38b55a008ae3bcf2908061e5da5fbef9af7dcf2d27e435f834023cd86afa90645acafe982cfcf6e40c5dbb0b85c2c5fa85a68225cd74d84ac3aabf1e2e9a631aec2e5374b46c2c593c92d8d64a2ddc692b1cddd6974477d1ff30f66607063a5cc5dbbf6d332f34ba868c2d158647845857a87e71e3a56aa3b7eea9f40be794e31d5ddd1a1e2b58a7fd2f07f0ce21a270072effdcffd97e2d9b20cfdf2e770912426b2c8b478dd897c0ee5d14e4034249653d081b1df2debbf1169cdd5d22bf21f797ba7c679ecf61e68f632c1662078b61e68d0f581fcb281ef3f0c174c17e555a16927f7b516657ef1b1ed26e25a1547e179224697b0fdd4d3319021f1ff32187658d8c619fe7a2f3bed6e04b387d66c9730ee778efdcf35ca0d772e772886fbafe0f7de27be0009d90916dfed6d90af6697d46e5dfcd5b9b17024f301a359211f1d381dc6b9f462f1e3627c847655c68a24c1564fb59c7a871e9300d8b7cf8d38152fccdf8f5acb60fa3a85f6fc11d8e4eb4a5a0e664830ea4e3b3f3dd65fdbb41488b223c09252ac9ac02fdca4a5ea10427582715776be126c51c6b8bfd4193fa36c164bc3c3d72812fe2f1c4144014fc34d5d700ccbc660774d3677a0aabf3980b9e8bf09508de3dc42e44bc3dacaa777f0ae9059c94be96ee35424ad700a1cc3c054fa3c0c857fde6d13a7c9f91886dae564c902ee4ced51aad1af993fd3faa0aff831918b6a88a0eed24f077826af1e28cb00e97536340e4c1771c6ec3fdd99ffed37cdef9fe16632b65b8f9d57e61672541841148c97b8cf6787d281925bf28b00db65c014f48ac776ada1a40ac82bedc20ae6ad9ea054a1e388a38e0220c8b14282b04e5d5f61667ff096a5f35db3da9b567ff4e0a20109dc87d43188428cc472c78d6f27874905935a11f18e9d2773da2175c1ac4e5d594c0b2c851a5604f20f5de4d2556f72d63627b26f6659b2a54d0c67207412d864cac125a8606827ff42376bd2d473f81b7f51bb90a8e047f6a17c8d529cf250d135bfd88209dec8fe7d8a00a2d3b76a76f53864b549b31bd2c8bc1a82e57aec22c7fc6ff1b844a2755fd8cc7f6ae3cf100c73fe7e0be8d608627ea9cc4cd5acfdeb9150ac623e6d0d138350a001621f799467a15405c3f511745629bd5e780c3edf0c58436bcf98fa6fc2ea634b6a14ce30e2a3141a7e615fee8b22e2768fde5b7a13677a1d46833e63bf659dfcc703713522a13fd4d4ad6a5a7990a003694ae97ff6fc47de8e93c22f545856d54c77bb52de7ac40e5e0d17ed937ae70c807520a3a103194ffed4e5ed3159832f99e3a80509d33b4ab7c29f44385afb503c9090627af7ff3164fcc1cba1852cde82f79a4cff2f6ef10b85670299902f88c3882571a4e8b056828bcdbd4176285004c9f1b57f1724fae7c9e89f18ba6f9d308512c589498049d079cf7655144418937027a37b14ecd87d3b18fae5ab7e2c697239cb01eb0e86a17c14845b5a98ec0ec55aadffb87f22186a1a3a7219d6458220835edb098de73a09bc5b65def196c96030bc21a6fcce54982457fe0c45e38f5103d9da739ccbd68b3ea7933630974b189e49c84bc7ba190430699a1bc9916fa701f8e7542b6cec94d3808a84af81e44b1708a9ff15cea3b6c7cfe0e71c8b4f96e54fa6eea4b85c47db1ad8f05f74117bc40351f179f60fd3b55f40b284b785dd0d4ccecb7d777383bd4efe3c783a1325f0ca1ff8cb32450103bdd1136443792f48379345de8def22433097a3eb7d2f2fc628ce09fe164b5fab8afb3081e49bc7e9789d7f61c2eb675d50f5cf16a4a5c5b493f185952c9db712b6402304169bb15174c28a6c4998cc83879faefeeede82cffe1a9fc41233f8349c63feb0d907b2b9c12f04f6390f8f6f6c507a0f3f5bc04bb1149b931a768eb66eca203117ddcd4298c48a928a389fb65b5426aadec2f69ef7707cb554fd19f37716c75a19e7e30b4851eb0029f03c36cfa76ee9cafab6b80039ead859c6ebebc168cd3abc6b30afa78e14dd3746b6046cbee8555f6d8258d4d2c217f5d006ede35056b97d28db4d3182a177ca157d457b33227c36944c05c21829814537c5b0d17dd444f5c49297fe78106487768bbe3b9f200ffe87fa12250dd97ddb36b4cb8f3f40578bdf6c749272e20166481bcbefb60d7cfbf84757ed902197a2e5558c349ee18f7cadf0d2fa8f9f44f365cca5556eb87452e9400126a6a3a35de54283d30b08fcb1416bef542bfec38b21085d7e788ade312533ff5f05040c039c27d84960ee0c6cc4560ffc56303d7b28e322f444aaa9e7d91747d70c22b751458fb0002eb0ebda3c7e7f063e00388ff1ffa4681d13568b92fef0d63f2710c4063f89962bdd966b9e6593fcc28defffe0335e93422ad3ae39b374e462feb7beaa9eb8328595382993557c165330218abb374ebb4b3cbaa01d1f9d8c5ab52f8297c18f21ceec6d1aedce94aebcfb18726696e66d85b22cf0a5fc9916cd16ba9f3d8f640edf0fddd4d3775b6fd2736f83e2bcffa75bb6b9ce8dcfe2160ee46ed16346670ae655dd9de087a7a8647c4d0c6e30efc44d436e40a279499d7deb47bad93dc7989fb59512f465ea4f02d0afbfff717e4eedc9e82a78b3e05b01d8ea8eff154632d0c5d13f2ff201b9a9e8f03215859df14a560b11f42a08f197a9a6c7eea996b47acabb539baeed3015c5fed07af42e3c409a39e0f389182573cca09b6039d9b023aec1bf55d14a5e720e7a46d33f8f80999817c1f1c412754d2f421ff1fde98d89dafdf237bbcaa271e9f156d51e90401deee9aff2f1ad6ed151b504572b961048c9360fb130c02c2c81a05a27eb9ac741af1fbae7e978204fc60c854c8104c76d6c1651e13d6b8b3a3a8ab5eb2f7385322d67080cf88bc109e679fe4fea9a35f734493f9a63de0cf375ed7294a392b557c4bd7f1e1c20d0f5c7cde08c490de95e12f9172380c32436cae36322347eb236c3e5afc1a0b4e8f80e06b3c9d8ac233a626eb00c5f88f663cf3e8d03f10a9fe4bf36bfadd523b9f235b01f548faf53d6fbcb70ef5bea4e773c234e7af520a0dbd4485aaaa7a1e1ed0a8969d9044b95ef5c4dc3f67302627eaa435dafba395e50964bc524026ed53b9f24bccc14f24a64b36fbeab807b5fc05430a023516436f3c79a5f87529df0437d0292918221ebbcf2a7b73757d4b6da401347fb8f3d4c517040d80ead2856e4af000b0f6909abb4c2cce71397dd6050d648104d1465d33b12d51f3ce897327888f3072fba4834f3836f5798f0ecd592eb70913e734c8637a81b45725001fe42430f391e508b0c38e99e7a6a32134974834d49328ca049f93865c441784fbff2b6038ddaf3548d7869d8e72babefa199b21182f3d1aa4881e566f0e037b859729763d5e9a38f9b1991550899a9025804807d988182a16238deb4988843ce387ddf9b14e128fc7d53c9e11f44ae0fff90cc8ff08fe515857fd20d36fc7f5d7dc3bd593c1df90f6c38213932ddee639b57f32d3ff8dffe9dbfe22aad0f027dff547de6cc5a436fdf753e646ed7aff4b087ccfb79e9adfe2b4da7f4135766b52ccb2ff75ac3c812aeeac422ef7056392a37e05931644e94930862f739dc3e808b58cccd7560fe68bafbb444ac8a69851ecbcee82113579179e8f330f70e35abac5fd879c4463152f11c424ac3ef6db98f767e3cc217eda383774a89939661aa88f71e687b8ecb55b12fae8fb6410b09a4dc3b93bfa8d6e7eef0a6c3057c97b69b7113d9d2be68765858eca176c8d7a27dc747c06df1eaac99753cbb3ca749ff8ba1e657879b6bcb31c7111aa6962e8d20b0ad7e8b62c6cc2738e0c4ee0657cd64fc0b371723247d5d75701f39cef0783e96e28e89060b3efea453b8b72f3180586ec599e9006348d834d3d484a6b03f7ed368bac33d391beeb0d6dbe33ad789eb227a232c2cbb599a33d4426cf65abfbae9cc4011ba7c4d696ac94335da14bdf7354187ff6640eb0c03aedc05334f4b8ff54162ff1860e7bb3eef63b294f1dbc27e59940b5a1650340fcf4108e6a8db2caad8925dc0d543d7e2a6bd1cf9f12b88aa90493339578c9263947a9e4f1c9e58d205d5b17ef4df4a10f290946f0b9c309b15579b26c2a69fa953a96b8732fbb5930d5c3825f0479862214ef3e030d20295f9493613e36c2a607f48f3d38d88e1fd8f68d880aac5c6de553b821d86438974dcb51f07d21f82b586d9b588a3f6789082bf8cd33c82da6f0490a47722e0fe089b30f81756465d6ccaf92dae3f52fe37e04cdfb236851dd15cd75d9ed994197a35bcde23a57bf294ef9d0db254ca903147b800d051860c1cd897d0801e95bb39af1f3fdf5eb303dcd49c4e529ec68ff724e8b8fa75deed21c1a90e6c0a3b25b4b82a4d635a069b570fdfd1118adbfb6532d21789c493498aa6fe7aebafd70132e55e0a29f7b502f2dd04bc0bd9595f52a5c5e783c4429ec56c9cc3ae1349ee6bcc1ac37ebd7ec3031d70f70dfe3c73d19e7e811d10d4c6ac0755242f87cb5535a73907ba8328139406179c68f165f70d626add7f1b080422f8feb7e9efe49497b6e9d4643b8bed31ebcb0850757ac0daf284d3590b3e8bade5b1b3be8b333db7d3fe6bd65cb439ef897447c669e12abc148069d4ac694fdeec3eb481426e0d2cc43464662935ab3adc2c05a2c054cf8ab60b13df02bf5c0f856489e20e8a0afb9a86be6a5aaeed7c62819acb4fe436e078933ff02aba058dfe27f547a75ce0e0b2eb41775c70319677eab4fc0305dc174d09086de7634cf65772506571b1e0889872099d65137219db1d236aa7b47d14a63becbf1aa2e3523d253f52251b6cc472453cee7a26e5068dd3c35341683288c3f0f5a16c05c080f820eea0437c8b686b8bb4b6f84052d78d03f86acd2ab94bf3670fda8c80d46f389dcb6867143ff1611c1b87d5960af58292ced48ee07c5b667c281281901b5beb5a53102dffe34a51fe2c887557ad7cc3a0d625b71ad34a41eb6dbc8f42a4aadb68f67ea5fde34ad9899d3c3d6ffb3b1a1d874c0a3c039a7b6f239d466f6d8eaf57a1c88ba703f8342f3ad7edc1264d907239cc0886f899f8ef83540505777831beee5aac665667cee0d0f205c1acc6accff388f3bf18f3e20dcc64cb47278e46c3f0bff3a8f000fda817dd25c6cc36bed3962c36ad07f493a206b23fa915e14615c8f9fe92dd6a8369c5016908ea2fa6196f0e60b479a07e01891bacb58807d9a319a643cfd8e8c3f4335c6b20a8adfb2b14ee5e898edbcb341f9beadd4567856cf3f01b64a44efca651273c622deecf26b6e9fd26da8a6ec94efcd4d2bcc59bab9b567b71fd1ca543a344e65f1089b815812f0ea0cbd0ae214f376e98a2ac6d1627e1adcbfbc5836b7d8d3f979a5e4d07523ee08db3ce9412cafee6aba2df4befcf5bec44c8d2437e45f60e4e67561b80c1a8fd50c0d5b73ca250902b895ba3f461d7c17a91164795234c2fdefedfa2c14d6ca9e43f40a98ae029c35373bf1b5199be708524487cd58fb0bb4c148a5ecdefdd20a33104070aa41af5b79ec12a34f813b9187b7149464d7a7d9564efd72671c0dc44345dc9c5866c9228ecff88c844166fc91b326df05565e44586542529a30427aad890956f7950c4846521a09c7d182f13cc15c933bf239b88444c77c1503b4969b59938da954932d46cac31de9da1097a37d8b1f5e552944fb596cdf0d9d9ddff39d7a023f2397f265dab810cfbe47d186dd9077b7858a85a278ed8d44f31f2c7fdc72ab8958aa3c5f34306c376548d27578d4e8b1313f7ff51b4e31ec461529cff297bad1d403100b3a220d1ca969d5775167f1a3fc5ab043126ecc500259afd739b1f62da78665934ce35194df68c4043ed5d39280dd5c1fd449628f1ae0bffd2809083321bb6ae01d2598869fc15c8e6dd0311b6129c01530ec5e2986478426004b9e043a30f21bd579552e91eab24a56eda28287cc7b06a843914af3ed9c914a9d1fd017018689cca39f3b1cefc2f4ec1dae645463dfbf1ce309761cb6d0abd60e823bda116d72c54c2b63a30b8dfcf27d16de26984e5ad194da218578d0026ed6663aaad039a994714785fb5ed6732c0509fdf15ae0a39ea3ed3fbd0dee2d78254cfa5753f49a93205382c17970cc38fdfc65cddefe2e287bdc721e647b890ec58d56818a3b8d5fc7ab866fe73b1ff6e9f45eaeb673fbf813664ac0d99df0fea15223e4aac022a223f7f19e497eb3950d4290163a7e05ceeb73084956b45a76a560b40f018da71d47256c34d1ba3901aa5a9df98b7da7a6f1a4c1c6cfdcd13613d95aa03d26d2400b46697e056a7fc5795569fe345001bc6bf6fb5c126c8714862106f6df1fb2108a2fc15feb51a3b434a5881db69cabbe309b5baeec4c525c75d178d2ca46a57809abeae2fc4b0435f25dabf43029ca40fc602a04ec4e16f7ef93dccd4b7ef7d2a9f31406bc153cdf7043e39c0d79c93f9a12a9149ce1827381b4b024ec42289f8c1412bf193c8f0c848e7f50d0b55869d13fbd7c5de3251da73005b61b64d23d292f393f9ac3a4f2d74fd708a52d70be414480f98fc91d343934bd827ed82e6f75880431a19927897a00e9984c214379489b92c90cfcbfb6b83c713c2661de7bb1dc5de060829f6fcbb6fca36c477105fe2c5a872862d1de9336a1d754903c8156c6cfbb8aa262794db6492a088e552f1d32a737fe0cf465b49cc83734d6f929e39866b1d64585b5d93d54021ac7bc235ef10846def5fa2e67caaa7bf735df7615a59d61d81daaf90f3f25be623321ac9d25ad316ff3dd9e3fc945bcf22709d67f8d9a0ab2ca7268ccb05ba147d4da3bf9af5acfee6628cac23609a5ef4a15d07fa70c3543df0a5d94d8e57d7347075220e1d2969e0d82e37f2eadac42045186c70cb0a6c9ee9ac0d00f087772cd466f1d0490cd10e2d5de7bf9121c78e38a64cb2cee5a3592cc4d2b23bb1e5cfcbaf3362edd6f26d7ccd30b02b8f9200cfb75fb8b3e3fe7898923f60ee265b452fc9c222cc954f91a21e9c093b857992c9eccf09a0d991683925a348895ce97c7e915b95bed877b5acfaffe297e3368814e2a7127f81805b2535abf9d0e46ceb68ab83963543f9bae14d8a0f65da1b8378bd65e0526973e0035a0415de0f12d4537e37fc463cc2496bc81618f58dea8506b79dca87e84ae78bb7e020d129f4618fb812b585776165c11cf0364a58a947bb3b72aac151f46d040fddda30fb9bfe9572f5c999e6f1b449d4dd1e580880af5788bb66a8e0fee70b685028d965c7fa7a3358dc0f1c6d1df4aa68c8609b3dbe25087869fa1124bee83e609d27ad088eddcdedfa4c93142ddf70f9e8e826ef9ff3f9ec7e9b800b26dcfc973a435393411d1234f074f3a2b038eadca0ce7b8614b5ca8063aad189004802b77d902b04e73163be4a94b3ff0438cfa0bfa4805854ef943a3fab4e4c0e23b9e4c6be70443c0e9964d27a51bacd2645bff374ff5ab17ff69e61ddb56af0175ca8c4b9180b29c0aa35317b13c04caffd35e45ca47219636b9ca0a366536ccf1e3028d220fee8be4ea6868c21d1017e9faf98cadddd05c6b5fb8c6a9b7a99db4ed56006ea00b81f2f948276ff6fecfa639c30c9af2adc9311c513d5678f8d3e9455a16e7f929b350b7d231b8c55bae2e11e6f8b8a91f4dd0e3ab66d2df6669fadc09a0280b62768ef83bee2edbe5cfedbdab897783a75f0bbee2ce1e0a423103b9be354bdad23dc86bf3b69a9a833a004b312b46b3fab686104aad5514f3fb7c5642816f5640e425d11435d5649bcb2ac76738c4812cb3f43dc112b73ac8983360119a65353f9ab22850e26cb7369f22cc3d23bebf15f83aa94c7bbf513bff06209a56cc61eaa1bad4f5e4ab73b76686d8ed1d3d4648cd85f478cf6c3e475a2f55e43450e0767a7afab2162ea763b078efc3f3452b9c49115f68aa1af27c32a2e896a15dfdbe31c8b3e42f1fd3da57cbde1d086266cd158c6355bdbe4e5379ca5dd5a6daab889e0c5a8c378fe0481b70cba449ea0d0abbe87587b0800b2188fc7a7c8c35f3eaec7e395ca5a7a8378bc2b9413569f99d5d99c9ccb1b640e5b2d63cbdd9536884c5b5135760a415a7b92f8ecb2a3c65f73ea51532b1a0d79f6f4e06e75b7fd62fa819a2f85df98feb84bf1c4a8ab2da1d957d82987c41d0284aa7cdbaeed187f83014e16dddb2b1ebb2509d593c3af09fe6530fa237bb84766d08ec492bfdf4ab8e3c7cd10bef2de148716216e6b4c5b76ad562e2e0638c093a3e5ae598a180df194043729bec82a26819f9995bf7f9ee1333b05480339d745060dc0e431c96a98de76c1bc396ca3597493c5bacb3029b85dc16877603da06ff2c08de34a9dc80df64a9775cd44eba02c35216ffbbea0d16931234268c4fee4108a0c1ad2065c08f3baf8a1929e32491aba8bf3a3ea09b2ea0c7317512135268c3bf3f25f2ddb2008000aa274230e1d0a228d459fa922e9e021a134ac4d441f8ba7ce6c5675c3c0db86a6132dcd33e4bf7d47c35420f43b16d4f7916fc33a1791a6f7f17813441ef82952fe31806c68fe2be15ea86a5b77358d1ad794ed9a9fa1406efb0e41022aa68b4cff60fc981fcd885b9e44541fec90a534504ac3ccadbbac970789170de15033ef77231b70abff37c971ea31247124ad0079a78de27be4ef8acd47bd67d2cb1e8e06cfdbf19874f562e063ad21ca0a224dd62de5371233034112a6c9cdc7744e53b6c970c427caff35cf9e5a845acdaa6eb2bcdf527da9240ee94519395c6c3a4ce6f3b7d0922e76e73b551002f671c0b0ff5c7dec5c1ad294a4834541c59df6393e830cc759f5ebac3423aa21d0e2f223bab28c51d924b26974182ef54ff6cf1d15504fcc1b3dff5bac460a66ba0314227f73f170bf38c83ea8120a8daf4e9b9da7b4f476575a58d982784bfeaf01da594be3eab343d1a277bb5f1155cd60b902f0af61ebccdfc1128d6230191128fd234f57c4d0fa33c362c3733eeb1e33e42e3f40add179107dcdc5b2985243436f241e8e7a3daf6eb1e25772eb4ebea55e9307249c0c5f429934d4d25c2978cf76f3737253d87a1eafd5c0c9c67d5a4b3b82fefe5551876dc832f8ef76e7ceab82479d7b7559383acbf1a1235de3c9da1913513ddabf678c2b8c0bf60ff704b95532bd30be54df664f3677ca81f99c69f23177f087e9af704f1d57f328b6560591700c336775c398f0077f91a370ebc69583926c45e3b0c79c275b540f30804ac1dbd6cafe7ebf5728bb0395e4f7c94f51087163646641129bcae84d914201c0fe6b4de95de79bfec3e068ec3d6b0644f846373bc27b1b55afb07c9364b24dbcf6c59810755d2b1aa51a766e8a1b2398e216d26e19d548f171b385cb0f958af5f9ccc9cf5a73562ea918c4ebff1f646c2bcc5f09c9fa8180e10ab8d295b1c87cc10ed9086abb5545bc033364e7d1c708bba2ff86a1751404fc4b062be6ba0857899d45def2c0f7341bccf3db5bca24150cafa5f51cefd0922f1dd0f9f1a404e773c6109cb410e56cee743f4a50584052aaeafebac4bd7c615fa0db28783ed53905b35b90439587f13ca74a4e0a3382bc135642caa20a1b471be668888dfdb7c868b3c91982028dbe3f16c479703132e8a1e95684b85fc63cb18f32d73e4089724403d5bb195600cecceb70c89d2dadf155f164e6afcf582bda6058207b5c308751afc8f16b66a8ea153d20082acd04153a033972878192b5fbba884100e1cded845f836afa7fe3f3e06faa7aa1e33b53b6f5c206148aef9afc422c3589e50334214336dcd009b96ec3519572b0dea98e985cc5697cf13af12cbf6c662348c494f65788092cf9afc3af8e84c66292998ef3328b69993b2a7ffc4529e86f54b7d2f31e80d9393a61841032800ac9d6ef568a76e621015a49af8b7e81001b91a2621af3366d5599497a8ae3945871bc95f6ff366725a6a371134f8bdab704dc83587bf990abe92bf7279d39406f31f2c578a4cc58dd2048e6752b462c1f5c3b2d73078cbf27daf7f0b2050a92fdce78cc79fc7b6fe137449ef2c2428c88876e588f270e6a552230ccafc3eee4eeaf55affc1d4c8cfa4d9e495c0388c2839a72add0c297f27594a66f43b5704f7eea833626a096682c3cafd0a6da3a0e099713a30aec06d90a80616614bcf16ed6f6ae323bc5b2ee5b413ea2557cb79c816392013ef599b003a0c5e76fd96f9c49a992c1487a81487a7b1a79128843cb6e4e32da4d47902517e980d009f624cc09639e2679781db520f204201fa1c8e9763dbe68b623d11f774ac2bf0716e0165357ec323fb458e919cb01dd0c9fc6d0baff1f33063600d7c0f8c0f5b7bda92d0cbdaad00b60be59f82b10a7e45837365a32991ee705b4f51139e49d1ac06570e4a7e4990b20fec9f2affa8af07412d89eaae2f462a47266b70d37dda35b13dd105ccb9f6259838d074b6ef52ae07f5298462088b8828d6d9f15d3b4ca91f2406010ea5f2512eb7eb6bd92893c42d971fe42cfbf38278fa4ef8cc83003061a6a33bd096d4efd84267286ec35495ea07b7b9e5ac4ee33a23598086d7f7704d7504dda8f25ce9f47dacc4d28d8c4cab17592174c08d58455fedcda03edaf0183748059aa9db57c0ea66bc17c1fe283733f657abab483b276524812e02446007c426f387fd0b40a9849df66d551d45be719b8ee49d3be6d2b6c43da9a5ab296017182c6dc47d48eff7513675c0fa90ecb845fa30dfbb3846144f5c0b222b7dfef0e10a132194c7743d24bf59c1b2270c2599bbfcd9fad3ed4ea0e721b660d3268f39b1390d3ca63e5829c35bd962a783fae45172028f19244a585964e7dfa3a9d50b3064bdff64be5d3113e1745b1fa6359ec44ebf67b4a6594e98eac1d2c632909a643a8ce181c662e2a5b8503ae583c8a009c281d84b9ea2c52601dd61add819b4e8e022e574e430490701775bcd5daa6969cf9e0936288f2dac71ea639214cd968df23eeafad335733e016054ccf4f1c77fc73cbfa695c343d4efc7f42654166b09008acb902a7c3c9b1037208409b33676a29dc6bffb03f9c50fd6f0b4ddd37c1f553d38a6ef87865b4dca2ec52c134c405f649a8c7ec39809f4201ac2a97b21e11ee90e679cfec1a3cdc0281fd3cd596415f1ba9e56cc6c8169c99620833db3e8ef6171ff2ea770a5f83cdf30701ca0ce89fe778129b541aedece5c08274cbdffa7f0380158e1eb3daa47af2f27ddf0267a86414c41315ff0d4f6818bcac900a5f6b2ad6f4f0d31f06660c87415e080d477fcb8086316c960d7975d790dcdc5c0f5e4043c59efac807ae4f712f498b018c64f85fd5d4170c15308d0fb8a4443ec26498055cf29a7ce57836e167677593b803fb3f7e24e74b1064effc3cdb11a4bf9bccad81b8710e5ae6249024b531c3eae28c324df64428ff638179b979938cffdbf2ca432426149a0ec7a3da2da5e816959c0bfbc043c678aa1108712f19de2bfb3513dac84986f71434742d5afb5192c9c8b79a79e96900f73ccc96decdbeb3c61a0b0c657f70f30e06f4eb758b8ba059caa145f8dcfb2e09c0b991af4ee9cb3040dba49deda930463ad68df6ce5c75503caa85442e771a7f7f3319bc4fbff3266ec81666db0afe02f701667b692d16d76d57457a483aea6e52106aa980014bbd65333d8b14e66405dc3f72b43fe12f6022d3f2a484ef1c673a3d1771a842431fdadd199218574fd8e174c4a42200c916dda7ecffc2ba454e0b66a05b5f51222a56beadab45705acd5afa21780d189ab9117abd797ce109c7a5e92f19957fe730a27b779acd414c2660b62fb7d48e9418982090beacd8d731a1d102d6763fbaa8bbc0e4d78465b64f65fe8570962c7b86b9e62fab121a2743d369249bef81523ebe357a06defada4efb27833c2003a5cf8f7f18d85abb75c8a26d7ca9371608a771a36f6254025abed60ec09abf0ab752b7ffe8e7317ab7015e27cb5887b37196495a400e4e8dc21fb603f92cbcbf76783c714fad6d96ffcbfabf70a51b8365a6069eec4f22e25027b3fab91a58ac5cc71ffceebfce570172051bdbbe5be38183fd93c4d18bfcc3795008eaa1ba1fb3bf09d1766e7c563a5bc06b61f2a7becda7a33c0b8b373b7a024281c62034a3809936bb483a8494aee10b0e838630e16fb6b4c1d669171adf965c8c37bef2f7bbcc0515fb32a6e8d1749ca1944ea68f6f6eeb3482d377ea93b5a532da70ab6f74718644f868ed5b044a2efe2a06f06a58fe53667d4029bbb83e3c3365029f2d84326b9fd24f983d9c860795418201fee77638775b3b63e3215d71c69f3b3885f1c447df1fdc07eb0952fff0ca52b07e7c154afd92d72f610f2b3f4f029684bc56d302ffc82291de902ffc438dd52bb59a6af14c75fb1bd97240fa3f0450a17763b20de11a0fda1fbc122bb3e1348be2b48b292d3f43f9e8cca2559c7fff784415569a9a3ee3a4ae028a6089ef50bb40d1ffcef64e33e1bfba22af21d027506845f884e2148cbd644faad5c0144b78f32590fda9c2f0fb2fa0f09f1abfbaba8c3436fe72b09d219f98d67472f9e217e2081bb33780e7c31222cbe421ec77253c10ee7df388cc45c2a7c1f1b307e938ab28dba235f6a1147f8576db12aa79dd0988e69b83742a9c840c6359587f55e84ad0e0d569b2bb44765b27f464862ffee9732ae3b2174be103d09a6c957ed4cd3ae3a62e2b92f98e8bb83f1e1fa0fdbbc02876bf2b9d782a0c3272e200daf027d316e1bff68f65cf102b872e3571cce0d3eb5ac40af8cd988446185e3a9c118bb4b36507cebcbb19e01c4768c95ee9ef42ab0f5d88df848ee2a30e8fc9650aedd672c4a5fb3b2b117e0143fb5d89e5b817886f0121607f1b1f1730a9de4682d2fda3a2c08fbd0fea3a456b7e9506d3ffe2ea7f57099c83bdd54f48231537f2cb4f581967e7588ec489ad9a31015b5d8e9d7f8e2ef2027041da340193ab812ab7d175a5571a035ed7dceef15e524c66e34a4851460787612c3c369e8338a9e11e5f33a7aeac00763b66ead175c723153da65e64f06df2f73e062f8fe4ef485f44aed708ecc7404b82eeaed9115d99ed06d759d72e99db9d5990cf51ece8d5c2315a58b0c531ceb67e3422cb4279e1d02b650e05936fea7d4f0a5c6f0e9a14722b7ce788f3d187e6ff1feea1f0b3f95488fa5cd59c0c32270ba2a221b883188983055e913ff4e9661ee0684c93382c1f76e9bc1daccf22816ee547c41c0c2d56096e6a9907e15e2f199ce21b9f6b466fa3ba29291e564711ec4fb399323e323e0f774f5b8eb76b04e0c4493a047d3ac5ead04ea5f18683f0ba98aea795b8bd945cc2cb12a3e779d0f08b3000d028329c7e4f88933da4d936d0c947c19a407a92e59523cec634dd32027ca3c93bc06f80fe1e1c7a94ca8118e6b943910ef598cd79bd642e3d9767f6d72eba731175f347d07a9dfd3b4ae3f9749ebb66787c64414e61a68005dd67060eaa1b33b3555205e4633e57e4f542f5fec7179d73cf92a952c8bb2bcf2173533f27b8348d1b5950cfb8c26664106baa8b2ffa9873832cd5e4fb233be1c708c5fe61e6c7f01d81847a22d50c877fa7550a9ce813b5c899af344a80dc879a03b13095d98e7e3198501ac7bdf1b8964e65e5be38226d3e4f6c6f07d9225a569bf4d065ede12da69d710a03e766d010ec9fc4f94f9c4bd3f888233b61888b9a94531ea61fbaded635b9168efbb79faced3fe1411654e76bc5cdde0bed3edffe8bae651676d4cd0a8816ecbf4b9ee6c374d5bdc37ed2671dd0ef9067a24b82796f0521bb75b542781bc10dbfc70932fdf7feae183e23ffd53caa20f2c63e816e10aed9fee04305dc73d792e5eca3b4dda060ad1876a4c313eb68967401cfd103df01e1454393744e07c68895dac41e681d95410db0a93d5ce8a0f7ffa70e03b07e9c2e891deb44e318f0a44bbe5fa4d81fcf1c3946dcdc5052ec7641fdc16c3f21f1ffdae578510deffd47ac32cbfafa06008f3f6288b40eab71bbacd0939176589cffe54db79258dd91d4233b0f68b02af48d0aa1475be2158e147b33ffda3c9e47eb12b3a3fe3064e116d315bbe13604647a3c85686fbee4ee4dfd533fc07e93e49afc2770e4200c4fbe9a9abfd646cc7b969449679b50929d4b0a7d7902c3a4d1ed2be580293a976e5c6cbb38564fbb614569a6e3477930a2c74f15512bf9e2d26f1487b4a10eb8d443acc4048a97a0fd5e291b2bc89e7649cf039d94832d18acc81ee5e86e5c35efedfa69c142822aad47ae78e22e0414a2a025879df42656cbbbb93b5c94523a18ec7614b4ee77ff0f6cc10eb4bb83ecf08a790058938841a5ea5df836d18720d4254be1b38bac4c114a8ca300a7c3fb3927d73fcecea764c2325a351135a29a0202e4496c21993bd220215180bd2b013b3e2e3b627bac50edaaa36b00d63cbc35580db0613abe13e1656dc02652b1156c471b1792701e4942f44c47d8d1938ea88366ad6907b059f0708825c5da13474414b2a0a52809c26852579f54d3b8f0f38f0f53863e0bc091ecd6020fe58764c5f7486df2b34968a210de526557d70e49fd35638d920d12b7abaf10e32b67abed368fc7dd436bf6a851434b95abcffd428aa69d601dc34aa5b6a9e398c1d3d93bb01be611343b70adb217fc6faf8381db3911f30789b8c1a1785e99a99cbb515f1ee5d5bee3d57f754a696a31c8153fe6dff5e11379898469a6d4f62b8c6508178ba3595065798e9016a371c77cfad6dbbf5bbaf5384550abca67b0d46e447ddf3ac82dcac7b1b3b99b74c2f2291352f07e78b02fd7fbad2212e3eb1b0ebf9e203342125952d40d046b29e322ce50258d4de3159d0fa5464aed56179efebc2677029a953734c5e4dca0d72fd5be650d6e2b32561fbc1e318d7a1d3ba4fc56008c4cf170bb8d61fade669a11a44465bd9d285a56cae61f2351c3d68aac3c198e8aa11f604de1859570148ab960b26c739c684f8e0f1cf9efdfdab2bc9a69ecb89559b180c53e13a8d8356b0c09ab17541194198235a51e86c9c96456b08a367a2c8562677d06dfefcd5718a40b8d34c8cb10a856dbdfa61e88ce5aa764f955173f1dedc5214943673f958436d7f0a68d4902bce33e2ddbeac39e5e05348f2220472b8a26200035210a8ec1b6833449cc1af1b474eddfa7efb3f1e6d2e995dcc43e44eebfcc821b3efde9e447f313ea27dd35d5e37d3ea08d4495163c4a6a414d2bff4c12e575de0195a93320b4ce12f5396568ad643d6c9ced0d74eada3da400fc91339dd395d2f266c9190003187acfa7c1a3c33d8ed5d53dc1f15cfe9c8eee6d64a878f3f17bc7646c92bc1c00c855ae3dc56ff644bad929545bca08b5da3244bc728ab1758fd7e4ff0f069b85da46f0337ccdd9ad2601f38d01157bada0c6c1fcfe4a7bfde9d27e3aad4de4dd7b04ffe0fe2d8b55da2afbdebf0c6da32d038fad8d4ff5efb3e2debe80d23debd900c1cc45318e2a64ddeb0ecfb51c93c18213aa9fd766766e42ab79770f7fa7f31201325526939ea0de85215124632bc1c56f03cecbee470e326e4c58757d55277d08bf79e139210dfa003eb423b53f3686c6d8b00c95c36e736a4d26d91b35f32d5628baf1594c377b79880b9f82e439085bab56aa33eeba9f9bdcac60e9410586e8228b2ae21ae2d3cfc4eb598ba0e2103bd313ef51ceb4e8f781b25fd516b03101bc39084a6ba1fe6f2ee48208e4322484bca1988ab23f48fd7afb352fc5ee051a0afb54b2b60254189dd188cc6679af3179ea430b5dc2e6f974f4a69895ca35dce5927ba2ec52930913be8797617e285510c2e33640e44b8284d0501babe31c7d4da7d11c4b89b1816721440a845ba92cefbb98b6baa4bd8b6e9eec663896f3ae54252e3bad265957ed14b24ca2df5a700e38403c6ddf3efe33165cd1803602c12984144a83457c8192d0e448504a45f0dfef00a0ec4660b4ca882d755bb1df69038dafbf142dbc47d0833ceec83055d99975a16d154af19c188c1953c0afda2243d20f4b2e9734e311b8b2bed8b5042e750f74fec50cdbb82a04ad488f0671790105cb395f896e9cf17c28ec8ff8a56ef7b8b05156d7f0f5630c6fc2a726cadfe0b21ad7e1ea6d1dfae4dc201d46462275f46c2d19ab0ba5c1cd46080d2095947184f67e2da8ae8d4c634cdaace19afc2c4864193ed6b52c739bdccd2f2ca6cf9d571215fbb888b0cfaf25440e59ba949d7bdfb205330aa8c3a7001fb954e9a96b02fd93d4474701465e44b7af35feaa42b8574ecf378ba3ee89904df4282d5cd518a1390d598f9d16410232e43c0d4bd593bca8c3da15c3e61fcf9bd14c20bbdd4beccf5a993882de5540de090b5987b77c7e0f36c6c25366c42099a9e7f002fabdf32c08b72faa4b7dbf3d1054b95b465198e89ce25bd5a3cfc553cd247a6b7a638d259348425947d7168cd57b815ad18f2aef803550e7012e2d434df508d051b871a7f0e63c72a1ecbb59ad74a75ccbdaeb2d9d52d66b0a1c30c8f051fe0ca6d66e31a23a7d9b941612225548a46ba22c267b5c57bbd2f4c65986ccfc4135ff592936a5051d5b6ee0b8c09b90990660a078c0ef90830c31334119a20b7d8b8233f27d42a9a824e8904811a0f747edeace765c521860336ccda4aa9a532f3ca73100cb9638300d1c0ec10d220ca321df4c17a3bf208cdde6e4c6ff7a2adefd004b4d6ac7958d642efa8edd12eb00a35b08e7cc05d91e5b597b2857d6a55125319c22c4856ac2117f33c9ef0f633b9048bf930841c33fe139c27833f978c4ee6a575e8136b53c38fdd857534b448b2594c3f9030807553224169ce2d2ff6354bf7b3f2cd46c9a782e2c627f202a5efb58e4aa6f27db77aeaefda185004042bb736976c25d55b3010b10615f7857ddfaa9e87eea7b8a45ddb849ebfe19eb00cf9e739ca4d0a70a635ba8cb94d254c185fb2f448bdc973c90c1cb59597bbba1ceae21a5e40a3e97acb54470ae070c50103b679250bb7b7d095aca38be077b97cfafea088af98c24d6504824f578948107338f685cc51b571879c03fee588b4777e80a1cedd171c87f5ecdcc5ea855c30f4354c3be97daf4b5e0b38a31652f6245f7fa2c309ce447331b1ee7346fce7960316c7b63cdb64f329bc811598b5d8f10c81146610f0bb78421f225daff5aae7ff6b9a1548aa078fe10fb678619b0ab08e9731ad851f2dd2c6a4ba92f9c3366553250b1c58e23648679fa38bbbe3c23f0e73fe97c255b2ffcd89bf6c0c86bd7bea76aa98667d5ab6330ee7e8ffdb4c4437c79cceadc947d0bf02faafd18a3ab62b6733fb6bea092b95f5fecacfff9a61529074edd779203f168c44a568a85eb38872f4d01a9478025e6b9ec4bd392d042b20a1524293717270fe8020a63997ddcba18043ac8a92eb9abadbe00cda729039eb77240b75848daf2112ebb94a3ad2bd95f1ca4d4379eef461c536fe184e48ec06a1f4e6dc9c2a786462430c460876416ecdf549504ac4e17e0262822d0dd84e8f812902e3c45bb0280ee1d089b9383b9a2d67b0bc2aebed9bd6cc790c596177688da0ea07a85dd0cfbc067c9eec5beed84f68f5441a545f380cd4d79ab7d91d1c5d9b841bbfdda6857ab44feeefea9ba4d077c0f309e70c0af68b5078440a555a042702047aeafb2ced70e70de06542d69754144f089b10abf5a46f5f7cf9645de824091617c422afb3e0c89f1d44942c26d33c36f9d2eb27f26a22c64f67bde8f2ad7ef898f8e29de6698948866840f87c5114b7fe349a149abc22ef7ee188e3efce1062d3a627fe07a061a3cd6c134860ac8d8366a924f0a5aa3b957e8195ff87231c023b8e97ba0f45422d7e6516af714787f682b653b36476de918557d90a413150b71c7125b370d151de36ae9108fc72448a981c315b85d901137fd2f727459c5f93128c6dcaac7d70aea6db5fa3464209306ca40805059e3723adace4d6b1b5e7186a0803e8f4ed72782b52391e80b30fac272c42ce33414875357d43e918a05278d09a7c7fa8d939c128c89224de89653a8da592cd38b53ebc2c971ebd3a09cf15a972d5f86c7fbeb80a793c176d52cb544e1872d6a16fa6fd98691d7a39a189c28ce364094c88efedf2e658aee42030e57e06cfb9c9316614d1ad4f71134bc82bf0ea78c64e1e10cfa25b23606f6bb01fe474be850307b1e817846c614c5a716e360f103de9675c4a9794c88159d9e71837e707188706ded84e84193e77457929f9716b4fa97517693b64f0dae216a080a659e8d96aad72e976f8cb38975790f06b11221930f1d1e8c31cdd6273f1415214f51a5f01b388311c0b1c40693059d1ff19c45df5c2b891033cd0f57b13d634e08392abab2fb1f4dc180989e07c30688c82ae75bd5f139bae640d46529dfa6076afc839b9ac97bd250531f4395e98671477ac6a62bb608d04b41e7443cfd65772065267e716dab3cb18a2b7941aaaed8f643eee6ce4e35ce099c667ff1c04b3b88f6f2e397bfe94b608cbf3c3b1396e61ee828362f3a2fb6a7933a7c0210ed3f635d15446349e586ff46c8bf1d52a1df1d3e7173c2aed3a9a0e3aaf62f54cacedecf611f1ce6e5a591c70cc2e1f9cc98a427cf52fd89c078cf92770d38751d3ce697b0f8356042962d8ad500abdfc8f8192d20e1bb38f9eb62b74fb7c60cfefee80fb881658e06267ea8ff8fd7bf4ef41c9490ab3d8a38a7b65cf6667dc1fde9ba5e55928cd3b3d9127c8256d9c6796d69c447e57765b5c8a5be9e4e564da609f60945e84ed9288a4450df5017e40e20f800e7d3f5b475cd26fbc19b8bd3bdbde02930a66d6d94d4a18cb41ed7e148b36fffad9bc46bf9afd337ebe4c815bb3fad59a53f2b40428f314b42aa61a149795efad7087b64e9a381760e62e706fc92cba5d4446e800b635086ee21b7669538eedded1004091363ef18e4bf29dedfe30335385fafaaad79cfa72bc3f0c3c9c7fe3d67da70710f17d4fbae172b3e1fa31d8e808ba885010ca09f5996e0f7e02689ae4106099dd73fa01866a2fffcd79a6a1160fe5f9721600210c267e5344d6b6b0c566bcc53f991c0fc2eb5f955a9e99fba4f093e93be11bf52ae55f9926a80bfc1e5cbe56323219d01cfb0d9df195293af3c839878f5fa378a078dfe0db20700f343522a643da66b51dba8cf5d00589b8ca99b9ca768d86a4ab57f61a7e717b10020b420c3984bd92d175eccaf5ee927361a855c7ba8abd9a6ff3417e24b2727ee2109dc428651704a2e637a7cb4eb56196b0818472744e6aca0c9331e3704dbdb41c2b5d91b5b3f15be66369e96db53de1b7787476ace2e99dec402412b3f0a309bfeeb77374e49fe231ffca6892ed512a557e06d14ff22393852e7529ddf4d6436b63c807f8a52b834314eb20fa2c8282e834c8713196100386deb078f34f7b75d5f37c854bae3f0ea874d79431af17108c52fa3ec7b6429f1ec96cc5c10abba868833512b34eaae1094bc43209d601ca4421d1895d86eff666805df3be9857011fc4148be47d637de2a72d3cf7caea7889b7a0937b8b0089cf84de05b85866d5da4c395357e24cef937bccc16e018978def527a855f6effe840dd2d39cf8ca449267862edfa8f8abc7f093fb351cdf93404897d53c1d0fb228dd87bfe71a3ce9957e57eaad9f6777261c075608f177e4bb7cf0b92009883cb5be147a8f8532dd6e7808bc3af3efe1dc347047217e575b6b479f64ef7859b39cbbaffc9a469853b7a27a190d3e1e3d7997bcab143c3217c46824b0d074357d10d8d3dd311221264bcb40b0ecccd3776c7e4e5b694adb2ba9dde4bab30a9542bb337b42024ba09debfd472175cf8c6927ca447d55fe7630f2a4c55b8cc5188c60261807f45ab4bd3415556ae19234a560624eb65d901b906f80c2359d598f1c3165f2f96f22fb04f1c9a62b69efe5fc966c8eab3c686e422bcba1fee26d716a13bb4e0700abd2bb52f322c3c3b4a2219d54522749e8494b9f3edec8e27d547649806d0ae95f358cd33d69ab0c02b6f035550add7fc84e5f96cdd7d7e8f7645bee8e821fea8472c77daecfaed66aa4a409ef0ea9fe0403446fba9ae341ab0d195008f2a109b67f0a1f31781ba3b07473c21f6bd77749767abada3b72d53f8c1e59bf12ba734b86ad970ab507eae40665d38429e2e3c9fb192d118aa6a4dfaea521361ecd2108813d9eff815d6c418ffe179407617c966d1cdfd24dbc8042799e353ff1f47b0e947d2ec01b7c21620327911e4dd6d6c8c0bd8f099a1738b06deb86dc2a25cb2ce07437a7ae817330b90e8a50e25f9fcd0013f0989bf925fdecba76366ced971611229968b77099febeb1d0c5e2c1bd373288c44e78b8966c33e8c68a3e76d0896d33307838d5d49c080cdc82e34f9b5feb25756b8af59972a9da601240b29d2600c69269d09515c2092fd838853722cca77ad1c9d4de126740dd1041c97b0335c290d4ab681a1ce009f133b59db0b561c50575795f16431c7b7a2ac80d67dfffefeabb87b9c40c8fad7c315468bddcf128ce1db57eddea27f0874306135febd73690a11e33d0e2b4876df0d3f2e24abbda4766a7a2d3c670e459f3424abd2dc93472c094181224cafceb5c377517045d20ccdb6b12bed3c492b40663263f4ae5f2179b44cfee1ff5c1748be472e84fff55ff0ac072de9f29c5b16592b534e44fe1262abb47090f84597fe1bcac4cfe62326d399a7ec5c93335ca1edb7ab2dac3d2668d7889ac2e26617951e904d65b7bf2d7ef84ed75c9fdebffeaed11e83f99246b54f32f2ebde190eedd45fef985e49c5a1e2be5dd22f3fc15a0b29dacb7951d093bc93dafe3aaea9a289925080a2d9ae2a02f74f6ff3ca3a224b9e46f1a5f34fbc117f73e467bfdf779b4d1e430f16262f342b7a1dff14078a7cda783b90e758ff35e5375133d3f023de2e7b19f90986d380e644a25e265201c7b1ec9c82bf9b5effdc8ffdcedda7efc4306ebc9bf8facede6a0db33defb52fdabe4f32346e4cbaf0f0133a43bb0985c0df6110a67a65044377106c39abf6898c789e69bb5dc67972dadb67ccf64b2acfbfbc47fed3f37385ca68ed8813b5425cf8626266d4e9dc6311c1f7aafc75b08e01b69fac16d290c316ef4e6da74e2006c86f3a7a44e3ce580880c02e1d13627f228269065970b5294ebc900b3b9d5ddbebc0d3b7330345298b5d3d60f3b3aa548f55bc99960e41baf5ff12bb27eb2a9c0cb9a6e2d391559165c1f31449a77e3e87dd125707e423c483fa477816db519542559e363fabe8b6e5b6f8e32819a4e2dccd10a433426b4de29919083dccff7305f434358400e838ad2a0352859e4e53d5b215aca0f3085dbce194d4dbd3c0ee295bc33b271efd570c2e522234e8685237638c483348d0c0da4e728ea71aae543d8c589844cd3fb504fb5cafb7c59dacf4e3984efc0c2e271caab298ef29bac7ca1be7fbbeef07701083ec25eabe2d90e78fc52f77cc49c44ef9138bdc5af0d05c347970b508583004aae2a1e6b160ab42d98e483e7a7670fcefd630edf5858f9fcfc0c8f0281591466e4690390f1c2658ea8eb966d3db1d2642dc7fc624d2a28540961fbd6356f3bf487234cdb7ea94f5a852fc988c6f6f55422832976aa1471fcb2594923b15f204f0f37e57a5da7be19b1250fff03b9dafb39d88c5a3afb6c0087e037d5fcdfedba51369198cd1c51d22bffab0369df077bb4ac07df835bdde17e50a1ddf11fb541de3f06c4ab156407edc427eb3a6b8672d097809e7961bf5c6da0064eb71339fed8c7dab0b9680a9699cf4e2cfee71f4d7e9d6413fcc89b379af2cec079e434cca6e8bc2c4d8990e88054016b107fc844a6b40a9dcb852c15de61b1e41bbff0d3184a1f4ad06e49d7d31b4e17bab761659d6ad7a5bf77ef97edd14bd2a4dfe654a7bab469c5c70c941aa36aeda9a67a576c3dd7a24002b65670fb28a828de37ef5c1a88c30d2590d313d34e96964220e2d450490a71adc179f369d3241becc58f7dfa26896bcb8f9867018ab6c9ad5acdcf294142099dc133d79c4c510cec93d1f52e492b4d64b8cca5a281514ee1589d47f87f66c030f00cc715670abd7694cf5fa83106f3925131eb07645b5b040d7973671698451377e97a4f5146c4fa3eb72953a34c72e7a7fe50f04b78801cc265e322f5be4f026906683c2fe0d124d84e4d37a895e840ac887c6f12312d2748071b5d03b82151c733026b6fa7e7cb4e335add0264068620ee61942885ff20bd77f441badddfbf7e16abfaeeb606bed5f43700e1bce697165f1e7d03ffecf91895e73dc9a5e8ea0d9873873acde1f3bf1928a6153864251dca17dc0e2041c6c45226f35ef39fc07b892a7b4d2fe3db87efbb48ffd2d716c23211358c79fd300e18c2cb5bd5fa0726a99ee415bc3fc6fd82f8883b5318c68aae2ff387c22f7c97d61219e677bfd7af98acdd18ca2c7516e765cb411b72cabd40726c04428447dd186d75654fe4c3b7eeeab5cba64a7e4304b0acd50966da473b6a3caba33d36f02fef20769a1324a6debee8e118abbc62eaacf414276bfc267e9aebf3fe8e4e61af5acbe9f689fb46928a0368001f8e571c68485a59a01ccc7c6f512cf3ffe7d13f8abe435d76b8b65b2a993f241027ca279a68c1f60ecff958e1fffc71850f3b031fec6db6fe9fa0483951134fc4734deab3968f4b6fe3f881cab6ed8c6b14f7449eb4e1fb4fa49f0e4789ca082d18ecfb8a0bdb65edc6df8b86d3130ff8436e34d45259eb076bfcd471fd1f232e9fa575c56f6f34e112e7e3bdeadefb8284884f2b5330135a4f336813891635c864c9236a494544a79a7036cb59d51ca6d0c210c7ceeab3026149e67dd3dfb56ed23036023fc3a1b9045d17f7172fcc95873cf65ca4c1556f7cfe9ff28dd2b52de87f17dbe5d03134420c52da508835f5c399b2b844d440e37891a676329ce3937c42990b2a65a4dc6a2cbab47129d57abe91f61b2bdca04fdd975bf436ba3e833b9f644af3aaa6a5c99886f3e569ab9ed99022c7cfebad1e92682836fe3f5a0df5dbe2ea0a7217ded88dcc6302d8c890e31262aee3b14f2ad8a412f656b88ecd698292cbb15c3b89e453c9308b6366c9b94448bd11ea8e9d8522f46c9877eada2ea9b559eaf75eb6c673f1690656272bb2e27461c39af4f50388e026a15ab4c500b1f59942336f942a3050c343e01780388522f1956b4038d7135a003b1addd26c531aa6997cfc1911c30ba40ad6c36c6322e53a59d24f589dc9c26715f6fb3ef8049b68a82e954ade0d5ac264a673945570073c9802b90e1d44fc063aa1addfe75a9b314135590cda875e6c3ef12a72292724eec287d224aa3b27445aa1be6f30155897bbb0044ec80e43a2539d5e54b5f6c19eaa84fb28a7c1b4e0b49e635eed1c7a03d20142a3580aa61063972874ebb7b41083511377df70731c7200cee6d9f39ddfabf01856dd796ea3fa1269993dc38f9d25b68183ce97a18513f085907fde3b01756c7be58eea304ab03fb2123bbf37908fb9b53ea52dc77a46dc4c7cd3f1cf580b75d7bfd4ff5372c861fa1a7e22796ebbb113cc07cef66bd32dc05b3eb27dafce92be8a56d22eeffa29132a316523758eff5999ee677230b1d2c22fd18c2fb2165c17fe7ee591c847e038a1801cd998681b7752b15bf145bc8ff7a362c93e526b53eb23cc172b516a54bb4b55427f167eb509ebdd504362902aecc616bc92a46c4ba7c3b28c1f658abd4766ca5549c866078bba0f69ddaff5ea8edfffdd519665f849fb0eaf521ab7818a7d5fc6ff70a894246562e39a7cbd13855e9861da6c3b83e26cba61fffeaf575ac8bceb0e286e7f768d5abee6cda2651549de0cb641c5f1c6a9eeb59d020668966597491caf4251cf717ef393b9a54b06d3c8bd2773d48fe0bac24bccdd68c7654c2a89b66c60ca7ab716cc34b87546b1a1e455892aadf10af84d11c182b3ee1124b88232228d33ea4fe9b7290426e25854a308663e18b4d506352c4e62c34a35a78bf089fd46528d47fffca624a389abc748350bfecfd63b46c6cb3dbb4f0b04720669ee911894eabd7005240d6408c04fe1b9d19316fa05e1502467fbc43af115e3ab7db545ad7f2d9929b29b231f01e089606a04d5bc1dd3d8cc3c63c5d20a138aeb118633bd5806c415f85feaa4e47c7e6546518adf274b61be08a7c48f8884cae5d63f60eedb392cab00a1e049dd1817733e46a15913bb60ab6a35644f4c4d1bf7632ab3e5adfc58e41eb00f863eb38527b46d01d6baa27d36e21de44ffe588971704cc77faa0103e88ae84434de6c2308d7c2cd099723159c3fc33dd5f8e2453a852436c72726bd7eff92f367eafe51bf62f19a66efaa6c6d1ddf050f891bd851adef9bcde541245e255e44e5e4100426f1c40997970a42a7ef74a9988c929278b7236063e5bf793e2be786190947291bb253de4edfd75c2e3693ac160b3dc91042faf291619fa9e18c8992f1f828c47e3f33c57ba9ce053a72dcd6992080072051b1734b77c1196e153288cf686832072faa5c760933ac8547676f7e2676cb0bdb368baeae15aeadbac509906cedb5099327bd4847b63ac6066284a85e512c051f6b816f828f9f2f1430b9e497a6890f79f2d2e7f1b3c2b3d59dd294c0f2db66a76a3ad251cac9720e116fdee21014af34a28bf96715f2c4946ab2218e859799a7f7e712020ab9ec02fa00c526cd03824c47965024e899f3de747bcfa6800c22b6c5b49b124ff011020ca9f2c77217a25343529e5954be9f113ba1a6a082c8d5aa87797f2155ea0617374d309a51bc120ab346b54d74241af3b1add2f39737692d26b6e87b214f1dd2c99f22a8ea88a129cde9156d8d2a56361e06f9ef01356e7f0a01159b91b7a6b93f1301385bd9344d4bf6439a6b0a43c94416642702e3f066e54b96cc48062d9e4593ff4fbe2a9c45fdf48c30858cf8a6ff94d0f1332ae0f88bccc47756ccd3643840ac1e670befe72dc79d8c9cafeda148b8d64a847bf477ff93b29378d0094e0b817420b8f10f6a9096c5ad2b5fde21c453aa60999b8202d7320ef697b4c1cf231aefab92d0f8e0be2d71ce2c48b89e9bb07a8219812916517148c1b93edc1c484515f9bd74c850fb19912629a878faa376a6b505ca2f306302c7b7835a7740aead1f20c55a86bc0322314ebc7603e88640b39f12c5f7ef6538337258ba227f7b23589aaaf4b00ec0c7112bc1bd08293cec0ce48949168aa48c31cb5f093396531fe39d2bf63ca5e658330dc3ad6359351c596472647dad6fba3a651961806f2a586601e0bfec4e30e82375fb1c84b398b2facab2f0a7f61b6701a38ae848b634f7da50add7bbb6716fabc17268c4d490a953d419d1e5ed43fdaa9c9fe1054c5b4f6ac41439448d24bfd8bb61cc28e246af3abc433a5ec0f44d22dc4f34b21ee9140bc11b34fe98a2e6c4b2a26c392bc5fd03e2f5453e7ced164ad415241d7adceab781c429fea497cacd1eb90e0e8ae64d0c7e27c1e8b13166bb5abcb47619b17955f4a3469fb87db7c71be822e3236bfb5f7beb4136fba3279bf3b46e744e2df03972ac81d0cb97cb5d36098f3d61251cd14f968efe3cf5f9053ca3de53f197108a91e1107d8ea3cd0e4b5a4432faca4d5a659255f0109b5b3c684ec5af254a7a67881f2b5ea79a15a5fbb4fb9d69c7962ad4010744320c575dd9fdd61b687c4770b1c881b18600be3f51b3bae88434ac1867d61bc903f1afe9ead176138ab279263638be029c3ad1defa8c15baee155dbc81d7f1346b151862c2398f93d1c4ac1b033f1291cc2af3a0a061587757ec248085dccda034df8fb32c4befed267e2c0f3666d9b97a7366dfc56c28c1c95a721619682510c81e662725c788f5c20fab38fb41f08d80e4677f915d313e4252f9afcadcf23cef7260e2686f27c9933724ba2a19e0a07ec2a822a723e10b993fe64c62b2d196b7a66a0aaa2a7f505c31ff6214ba125db845c10675d0ee80f2f69fae5745689bf64eb6749e23b9e79d28c18a02f183f9d6f38e5989a9dd30f36f64d5c36cefd47b636fedb8216969ae165b8f26234ee4d79768a4b53008f21c20ded0b533b61665f609a18754940fa2fddfe77797645b33f6c68ace64fdf0471860e2ddc9d50b1277261829b0144f088782a4cb0a9a7797263dc4f0204042d97bcb4ad1d8f51235d78369132ce0c4128ceb17eb683b6a2ac25d581b465e6aac47ed4e4d6802c42878af093b11b97ae0d15d1066d5b7e122e9f42bc2986b584264d333c70681b98216011dfc5ab1961843f55340fd3e6bc89d147ed53da246b8e4ca8a9cde949ab332742f71a1c2be906373655508d63cf0c4c6f42a26dac5baad01136c4631c9de29907cd779eeb95b41a784fefdd1d339478035367c575a124f786312f94ece41420f2710b049969fac95a6aada7d57cbf3d0f425d5cc0bb60335d9f3c84ff537ed601e65325dc50ddde19848a1f519f5ff5efacf78ede15d9c0e285b18bded2341a7fe39c740a1f99affd5519b788735340fd69bbbe74536932d809597465dd50928357455025bc97de0e817ffe1d961b62c15e8f15c004fa39aae53324b461bc8a54b183a04c99df4cbdaba378b432b9d4a4023fd39092b2bb62c91a7a2cfd729310abe0497aaabff34d5f227620cf0799fa5ee80d2393278edcbc674fc5db0a3f90e957d558bccd171af936d62e70921b5a0f2cfe96b26ceab854b90b7d6d27308d73011c350595a7677967caa0b527c73acf5aca98f1ffef93d69a16c8512cf9db7393a9f7de6d39e147c625759912faedc52836c5a369adf1f4703039d9d108c85c5adbc145404f8075bff4cda3bddab3e551eed6b4d7e8a9f2269ce6340a0a845ad10f065842a4d01717587d3fdcb5ec444b37618949d42e3cdfb1d4f34255898aac1c6c03c68e998f375a5bc89051f7a634cac95fe0a72b0c3194a1a112d6cff330053658d0de56232589572b2b0d9a6ca5cdce5aecf48f0430671d22f16c15b605e63d067f559f10ee05ef8ea83a763a3b755ca528eb1314daad073b2608191c7ed1056be96f59886c130050f1fe48aefd5f16f78f3c081aa6464057ac0af9674dce638e2d6eff21f371c19834f496238a16581ba251dc755dab205549a71bf3f750e2b8e193327b79c53d332e6ae6dbd152c8c22eab3cf6470b07996af69dee6e3fb43f6625ea0ed1616a5d87ceb4d09a23c169922515a669f2c987eda8a64c3678b3b37bc0808f0d10a1627ecefefa661c643dde50f13ecdd3e8cd60dc987f296136d4f28a0d00ec3a977fa41fe9b2feaadf14586f8ff00b2e7a71912761c4e707c42df9bbd5cb88ff6421095d7e222d79f408b331edbf39f7745e88f56e9fb3c3641e818b0271bf852dc856f2a58c60955cb915653343a1f19a49347d7a78941923006f26ecf4b4c3be1cb103ceb69adb7b89a8ec654cb5945494f47f54c56126a7be46676e593befd78d4735521b701e40fb74c94c2c5fa05cfd1e9cbb21200a68f91095711d8ccf3f6d1ec953fc955d4cec3ba323db8f552bac0cab76f3c3178b9580686ca2b4627e931896f6f4845f73c17a5c0e94ab2b72418945e2b39d41d5d77a8f1fdafe53cae75aa05f676497e7837d699dd73d6280cb711414f2a8fb6b4b0a6ed63dad35ac165198bf35ad6757d545e6dcc7b4da31fb023d62247a11eb861f74d0d5d52af1d03a9f8f5c8a1ff83184573609e5f4bbf49180b716733836ec5683a105f1b615c324a49bf5b053789d1480b1a788cdfc1be8af634ec17aa899cf00235435d72558ebf418f3807536e15a70798a4760022e7b12f3472e31fdcf1dd4e2181173c3d1961647dc86d6453f833de4d0acae41d083755abacf3d95ae9ad3cbb4ec4f59d976b6c18194f96063db0bdf0e010e4e5c30fd121935a3413515d2512c73b6cbd55ffdcd7cf2a2d8a9f8356ec44e476b74f04038e9e251b74f6de40169cc45ce38dd658a36bc3623538d8c97c9adab4651b30b4ac1aea9ffba8cf44792ab136e6962917dc3cecc145e1493fd280b545f501a5f9a49160cdfcd67f41a1dd436efd5ec2f2ce6b893bbd57d0c1f7e2f6c598446e2dcd21037fefd797b62c1e01c49c99309e0c85b1299ab6147e5c7f2fcdcffdc402060e092359fa3a587f1ac7ebee7523543e504c23cac7afc5c83918547dcb6edb3cbd0dc79a06386bdfe0989f8a69325a237a941123a22451fa04f7565a0c8cb95ae37f8de73395f12202c9553c539dc5b665f6105646bf26436fddad8b37cf8d73ef6d67d34348bb4ea982f9d32bc9f8f2e7439b742bd16c81541000fbf13e3b4ad5df0202bc4a3619d8215f7b0e35a185ba8a6f13c6809a693b55b11b094d0c715817d108a21a74b6d426ae3d887545a1d592110318eb88ac74dcf20c7e5319ad8ad3de93a4b6473d38b18a7735a2c74614c3704d001148f655d73e6cabf4d4b242c0f731ef9d56cca6badb61d44d613030ee9871d30263382181c271cc1faafd1cfb6b8a591c2f39f56236bfe5592e300cf9f4af2bc52e536225a3e382fd85885fac2a36a3e667e23465758ba7a55fbf82ac4631cedcf75bf69541f1db85b23e661edf85cbd412ecd7b7b3d65f0a44c310943f58a4a3b1090929be7caacd205661dabd6d08d91e6172988ebba8416e1fd29b5394f6f59d17685d268ed99b98bf94eaf344a686c530abebeefee6dc085fe58ff55aaec2eb04c9cc983326bb7ee9ecfbf086ff322c39622d887756524c41f026aa3cd594848667e743ecba84816c4a06555dd98b4e2c4d2e70a9a73a5d7f74330ad8a2c7f9445768b5084f62687dbc1110f1cbc52e7fa738aa21285d3eaf5217e820bb5e81e1a3dc751ff7b2661308496b010e576ec1fc543bc243bffdfffe6f75afc68f5c854ac737fe71148c994b456268548781340dbec85914a348533a48530a6fd1efb0fbd1a5f83678af247fda55ecf9869c1dfd29147fadcbc5078e75de8910b9757ec4d1caf094d6bc719424a53b9f8e38b839085d4a2aec4845a113090b088b0129df4fd694ce8c077922597133e18817a8785539516f35bce0f7f8e1badab7754ce16bddba848bb416a162352957d3495ae011eb709229fd75003551cc570d713ad986d3bee30d09cc11a43a4e8399a90e64f7867adaf44105c900ebcb9f432228684bcd0f2ae3b3fc698623c0242ef52051df058d1ef64379b2a5fe8afeaa2d687374d08c94a302fc02852c4a3dc08ed761d3d0052c04946eef665b84c7b33687ecd6c6f858101d947e5af06d87fcbd21cdc74c97fabeae64f2b3c5c43ee7984ac3eaeabc076afb8d03078d5df93712d6f2d047b55768f9b9eef4462f2a23b960f663e88f7518dae62addbe6a530c55f78c6e110364b8ceb2619abf3ad0f963f5cf5fb4ed743a38668a8c3a30d1330a551b83b3ac0ead2299852f3d556e8f6acebd6deec2e3c79002a1d3dddadc0e55f817fd7e3d51f5771eea5bc4324fe22e225b53c91cbca75a64b8a0905262488959d091aae66fdd52fffdf31f7a84283fe1b5c2657c91ffcc524adba765f42a49b81d7e0a76cae7b84345818804041f9f487a9f4ef06596ff98a9192f10c53baf1c0c075f51445a32a2d0424f3124057ce5c514fa2b36a4140749d8b36b4a13f69295feb27edd97abdacda3b267397641c02baa743bd1c1c861270e9bda414a6779ed6ee2fe190fa7dbc6a68f8f6a3eafbd192b33ecb36aad15a7ad8ca1564c470c3e8b391f318ce698f45c993ec27d5b6ec5d4be937ebfa82c0feb228d8780bb8b57f56904009704f14d955ed5c6c06dc15ffb8d18102b145ec87026d2de4ed25bea959c443077f3d3bae300e2aafc5cb8bfec5143748e12c3bad3d005a8d38cdfaa89d43a5a073c9a8c776bb28ecec6a42f1e48ced0b4efe9a67e7d5c380f38f9d263b35358b4992b26a9054035d43c26b6c3e84906621ccd5caf1db8e6dc1a37f9e86e9a7b9fe8715392bc13bb6607f4bc29482d84ab89b71ce2857c739730550ee9ffa5a2b4893ffd505ff016522c529cac7ebc24f0cac9152206a31941700561a5253fd9714e18b8ebcdf80e68f384be3d39781c4cdbec65669904ec29accd183b1f1435823a77a3a8db6256a1f60463acaf1d0df64381c7ec64272515d05df5946c07b39213f3cde5602ba20140a5a7319c14aac7cb1d323d3676dec1e8424949185243fa3b1ea100280034f7d467b4c22e5fb1e59559234dad738b1de8d62a2a051bf8a13396dccde0172c7dbc16a868a3b7a2cf2fe34b00374e25e4fc3c672f2518cd18e1559c53905000000000000000000f902c0f8dd941c479675ad559dc151f6ec7ed3fbf8cee79582b6f8c6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a10aa54071443520884ed767b0684edf43acec528b7da83ab38ce60126562660f90141948315177ab297ba92a06054ce80a67ed4dbd7ed3af90129a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d04a0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d05a0f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f37921f95f89b94e64a54e2533fd126c2e452c5fab544d80e2e4eb5f884a00000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000005a0e85fd79f89ff278fc57d40aecb7947873df9f0beac531c8f71a98f630e1eab62a07686888b19bb7b75e46bb1aa328b65150743f4899443d722f0adf8e252ccda4180a0e1968202c85e3b5d912a0b5370f48abef3d4ab876863b9b74dea5594779b62c2a07f23d9d32d6117f3c9484504682d2311d0f6231df9c98f254b3378049e03fa56", + "0x02fa0186580183080e708402faf080850e24f0b130831d1ec3941c479675ad559dc151f6ec7ed3fbf8cee79582b680ba0183248f111f3c000000000000000000000000000000000000000000000000000000000008d67e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000161257000000000000000000000000e64a54e2533fd126c2e452c5fab544d80e2e4eb5000000000000000000000000000000000000000000000000000000000a03963e000000000000000000000000000000000000000000000000000000000a0397140000000000000000000000000000000000000000000000000000000000018223005bdf1e1445b071001088ec97d80344116c1c4200619f9651d46bd2ea7f8d9f0915ef9628ed4d12b41907698af2ef3f42639fe4fe3cbfcd3fe7defb125a106b82b161448073ddacc5c865c322ca8feb849f6ced5f973f2a1d80732e107c7a1097f1403d010338b7ef41b7703204893e2951122d925221917a0e4a4848f5090111a442d0932d0812155e411cd2cde62e2b6bed24fa0e1ed54d4420fffff7aada961f322829919c5275385d49a793beff70f009c911a414d83e3c43b7940a4ea58e457cc8b449918a11d1952932994a4f1599264d513e2f9e64f21374614958524886698ad3284e492f2414f9582cd30a01a4500553576915e4fb448a98ae18781898e4e79153790e404df92452a85116d25466aa3c559ee9fb59d6beda6776b3a4a72a53daca8a569a5559d5b62a1d9effbfefc7114638ed15ed955288519d759aeeba74d7c304134d3ccd120e3f48e0c33083f23401167814bf276ee7dd7d5111a292488c62aaffbb874bd29999f74be577fec47ee1d98a8513d926890a96551a024920902c092cd45a0a44fdebac9e0717b22efc257deda50d6cd646d85bb6c0199b6c5b8424429615c048c2f892598b20a14e0f95d3e1e0a10075646c3bf4034441b20b02f1077f073b87e86d2b84425191005c63522fa9c031b66d27699c653752532d1fda1f32c4a1d1c0a00e30b88744363500c2d0c3adb68d7f689b33caf27afeae093d14a430f80080719d07bad49d0f3f7480ed81084024b87dc4308f012b008f4247b67014665a3ebb0764d1400ca2b70e0a995342e593d4b8d569c307bc1ea100e0c7a942c4bf12bea0a9d975c61562859f7634fc74f131b10a1c8193c96114779132117f13e03e73cdf55bffe71f5062ce38df4b5535bff834570d6a3becf5fb39858b108e31df13159f0e31bd92813fcf54c1990b5150895ccd5035a6a5479ebd19ad16cbfd62c5bcce02646086c2d8ca42624cd47c5e9e98aaa587b8ad752ce17f33ddbf4b0bc19d283c0044920b9009034e24a52a22f7e0cd2ebbcf8f0aa1c979704d66e9aee97494c21b47ffac51776d022d757ab0626f89fa471e2b0d3b11201d6d94167d7228517e4da4962b6dca223e186180a48836eb4f33b272731bb8fc0f1e1b42f8a599d5e3c5cfd1a6e6cf4163c2199632e0e828400219bb3f53a944f931be7d31fa8528fd5520b143189195cc893c427828c93a99cb4e170919c0eee14d5cdbcae46e796001064436c4ebcde3f9c06837947411c6ea641751bc8483c2391e4dbdcaaf91f66881517e57ce131a177ff7f6268e812e6fb695ec27bd5e619b2e3c90f4610b53bed75cda3ab1af95d131ceca38ed63e5a087bb355a2c23e140ddf6aa45e125f6f37054dea75e444ef0518741eab66ea50c56855744bd8a292b10d405d867a430c42162f1b34a09a10f89eb0dce87a09bac527f209d78b5069fea00dbcd0887d1b973822c84a42e87ac08b801a2fc99542c7fcecd032a5c854dda35668560d3f80ed6ff8941ed10730aa63f200079ae06e2399321d8a3ea706f5058a1c0fa65762ff4dfb7c61500578498a8942b02fff90dd91265df0b1d29e3e55b80c1586caeff6a97036cca94b92955029e220f0079f8997be2ff656b8b1286b5010dceb869cebea089d5ef3f34fae6c7ef342173428780ea13cf45907ef9a91451c851618cffbea24cff1306b8dbd51cc0418990d1b05f09ed9abdafa21e8401eb69e1050a33805a63d92f2413019162f61f5c9205f042e30009cc1976fea8bc9bdeccb2950ac9465a682947f712b98a0204f4cbfe6a876dc38fed7fdb5b868371d86bb8c902beb22d1eb30f3d0a2cf66f103decb0f847404553d1be4bc51b14d2a54878b4d5478e9e353bbb7bb54da18b0ca9ba55d00cfc6008485b1d8861abc14261cf1b0017ed74626a6dec94c5a95fec20590ad5c87573892865bc364b50bb6a2544ee5781e7f63abdac01e9a5dc43508a46715a6a37c31629f60071e0ca71c187e352e23b360b385673a35d2ab60179a599b9da2c51215835dadb9b9729faaf336cc41a68188efd79d611e9af6a4ff4744b9371a6998268abf266fdcdf9d0193a3df56dd6011e0ca2e265d171e85b3578e8d3f058904b474e38f51bda6e6c465f9a603a37ece8c8bbb0bfb560b42311580e69c99091de8aa25fcf209c8d07d91ab34e486047f2fae4ea8e0fdff6ffcfc844930d5bd748a14cb82fed6fc8568c04374c0dc79878db486642dff62e80014ef83d84ad3be90afecb31ea696f40f66dafd3db5cf5132759510c87cbd15ba935720a0a8afd125c56ef10148a0777d61f824fda2cb07a4f57a0fadb064b89c5fe188eeed9c677637e571c961c44979c05f583008768a876fdaa0e25edc6d6131febba885b19f015e54593f0837f04704df6231481dec3d92b68ff82e8482dee4de08e62ef1b889681bbe4b246c1349df38e16f8e69c1567c1df81b9600835c3799e39f183a41e8d1b88cf7ea2a638ff417985ea91bb626f59f908ea00cce3193b618e85e1f98e113d98d58302da29a3070ffdc36ab40452004056c3061853043964829bba0bddee4c587ae95be145483d7ef6a7576745873c2e1066c0dbcca68b15885c8fc93d7c3f9a715d87433a17e507d80ff4677027f031f169212e3a8bf209c021aa1475c8476569f00fc6ae63fb69764c37ded951388455febd8698704dacd6f5e1cdc0dd39f75b98ea814354376beb3a961e42205341a70e838895e664b192704862ed71db6e5e71c5c6847b1c66eeeaee6b8000081ea53c06f143f587b5f8970d5f5d49c96f676cda408d02dfe65937142692993dccfa0de2653aeb5f1c54f39ace3e1978722373b5c19bb59f405686e57341a9c5b2e8275be6f13e95ae4d82d091046ec663690b1ef6cc0bea0fd2a3b40e0a8a4d0a2eab47cd888482b00802dcca036b5fb1d7dc6d05e502c82c51a0ab8e9d29ed25e3edadb2f748830ac81957d600202726849811e94c037afda10cfd1fb22b0c400097ff445db91f04483d00214e15147f6dd6dcc3fb17aa978a4f7189e26767ede3bb75eb8a34920a0168afb73db56effdf5925a3d213b383f15b34328b7e2713bf0d7def6051960face9d764ce183d419cd912105129f18c310c68bf0cb1c697cbdb0f405c30ff8535ed0296b1f4081db0d6a6a3a52d8586b68a5314d7ee6a97774cb0c028af83e4200105241c10e3de5be204f5baeffb333324cae376e0a8500311c32577f8c048407d28d901f227437ad83e2828b639b8ac3e4a805023d48b231590399508173a6bc68af35399ef2d7609c7223e1fd3eb44e7939eac09815c6aa652aaf4f78300ffb6eac2e61816f180adbdb40476dac09c0e318aaa5320719b267427327d695301893551b2591d9ae0a79bf345c5865daf3c751b9b734ba9ddbada2a3fbedb35c23979567202fa56f3f77d349e361fc0c519eb7701583e9e43c939d2a5d11b294dfda991b38a72b4b71e8c64be8f7ffef6b58b07d547a2090530c60fce5a2bc602156c9ddc779a5d56ce8ff6c5f5db9f86943640e7e5217657c896aeafd8a2d67d085b0410078f812ddab682e44df03cf53c50830ed0ad3afa7e7450d0351a0d5552cfa2af2e55db60863f953e20d89c08ec0337303244148d04361c1c88b1d5e5014aeee45cba04a50f214e557c9d7494bb882d821b2497d2438b3937fae105903c112482a912112f6ac0cd9293362f372abf698072711920460ab1336eb20288223f00bc1467ab902ca93cdf9d469538c30fb19591836450fe1836b9546bdb8daf7d8e0bc4ce5b6bde53df9433f5a73aaecd0d5d5a94fada5bb1502d4011eafe2536d64f2d7483606ce155638ad3f2d41481e324711c7c54f013099d9f6035e051be85b4703086e5cd589a80d789a1699e9feb73b04b58df2feacc654cf18a6570fa7de3fd845e10c08f04b61fbe4eeaf020bc1c86c5d1db366b5710d7e9cf61da0c31b1ac58a18216efd800152968ca753d8ea1f59517d91566fffddd9969a5dc6148255b0be0c7aa57fb810a8680b443a06ff7e168351cd08c272a3bbca28c0aab25f53bdbdd7d68f7e80565dc634449d10d59dca2a0702438f35585ac8ac35efb110afa0c6d634c500ee83cca5147364ef5b896fea7527a2bb854334f124a79b4c0448e2c4de958c54ae34f42c68f07569c21dae992ddf689055e726aa03509d62eee8c6050718393292ba74ecf68c52cc12eff18537a00a0f882c9820bb3d79e6da9d6b5dc26950b27348b1782d18177dc480e937bb39f5b72cbf2a87439e78a0a59a87eaaf7b1307c4380f1d72e54c1781ebff0efb2ad8d75043855b349d7556107409e848b510a5062f9b4502953140150a9d9f7e7ba7878cf207266fbd904909b9721442b01fcb4430be7744da37a17ba6e3ffd15f07e9a7e5d037cf5adf7bb34e52786adc484dee8c8c438a6e4538eb25657af5feda22005d211d08ef482abea790d020b25ee9cc604f5a02a2156d45f8834ed52661572e4d3fab72d15c4b049217895dba1d077d34121c62bf3a9a5531ed4259a95b4c230b8babda215995b2c0ab5416520663668bf4aac9cc946e30a1a2376e1c4caf0276545f05b2e6309c34f145ade4f9f0dd00de222d9f8f39feae4faa6245069226b938f1fde47561e8acddc3352b46e2475df217a3970e09cea6ced00cba703750ad73d0305c5d695541201f61b697983c16598ba5d3727075abcad97fec5e0c63391b1e7da30cf1ed4ae9adf5b9920855ecd157aca04050ac9286d2f64dbf6be87eb504bf876a32887a4744c209481a9a751f914437b21fdff5caa0068924c3eb18e7fd5781a021fbd5d99dcc33a288eb3a61fbe878047e68ebea5b20f6a16153c033894f07210f08b57a12ee29ceb5464112f7680cef4022d3f06aaf043bdd9de143f154116fee0340000f7929daa643f0870966e5a4595b8c5c46dff23b295eab575bbf79ef2df816172599e90d5e9e8633790219477fe1f91504f58b51542344aedb33998b997694893c939b8588f47ff13be31276d102437ce1b9b18c1d116cc554af8c4d6d93f96e6808438e5e7f84513d02c50681d3fe78f414c45b2a9abef6f81ebf44c16346cff5b31116a3c7f51889147d79ad0244b9c0d41205ae51b62d559b48ce44014db653ea3ffc5f30ee06c384e450ec0a6c618d937df3382a7bff6ae39525ab6ae086a273efac82c56144e65f6b4954430788e599acbc1ef5a62c9628ac64b67eec2c09f1b0aaf5f9914f1a047d7b8639dc80ba868fd344b2a9d4e17ee2116271dd3c59321fcf75bca072f09c84174b0eb83fa362f5031b7cc1b5288cd9aa8dbfbbb5bb058521b80d213a709a847a653f4689f2638d0525f94d5b1de7a83cdb847a78589c909cecade979dd6f824c8af41d377de3ef5bb341e64d29023c3d117930ed1893d68dda7fc14a55c0d4ed4140de35745694dfd8b13bad0c43518fa8463da113e8b80bb82cb566c8784e862e33561aed297172e2a2bbc9544af7fd3aaa555d384ac8594c88abb5e3e5cdac70ea64c589e92bf6fce8738ab41521bea8d3d7a84de6b923704e35b336eaf3678b4ca1541497e036d6ab5f2ac009c71c0720cecaedeb48fa6b8a42a0f85e682a6ca6a60c0c2071a614296101e9896d402c26b5dd72043869017183a4430f2785dd1ead6ece9da7fea8f69cd2c434a6dfdb71444c5e3c2791374d0ebf9ef9f95aedd4585c3e48b6acdaecfd9b32bb5be6aa929b6cebefdc7bb53ae6fe06d583ba9d0a3ebeaa4c7f955b4c1f6d5d666bed047993c561bad0bf1dcb8f6bcfd6f735c96ddb2e018aa81a77923dd05d45b705f92fad60524f931f4dd3abbcf0d8ecc91838d752b7e9bf8604408321548b9f933b6e7a3495f444c9834a91917ca6138f581526a7b81f68307b4be445fd1a0b4cf2ce04ee2f1b7ff9b465061876b87edee6b3a1746b486f59f3821d80f7d1e30d8e061d3df43d2eaf1ba3bb93d477cd9f09e15c46c323dc91c0ce9c702fd00a49184846b10d1f3b75c00fb22d3c04482e126fab87daf3de9538337784288387b4a673c29865f10e727592fc819a1d15de8da1c1e1a54ffa22cc864efdb6e05be81258aadb9d2dd23aa76eb224ba4221d69cb4edabcde2c1a8ab4d47f20e15c21a065cae5851c70b21e6d5c5eda436577272542521dc6e25fc7b5acd79c5a51789470910e7749a199e5d9090818caaa94788c6266c550a4494b00ab12bdb8eadff563d7359cd9e631242c47576d0a3c7146c12d9d0ee75d337331ef4b93688b812c957eae30d4808610deaf827285e0a2a26fecab0963d1880dc9efd54c99f8a547d5f8b31a9d01f6c84001257845edbaf99c2ef7aad569b07ef9a4bda0275bead7a0bbeaaaaf6f295fbd2e3e16ca612d459e68bc40abd1f7dfbec23fba067f2d3f24f49916c0daa0eeab7b7b1ae65a537e9e07d0a70a96a1516e73a4d2c4d725a3d640db2b83ab9c6eb92d23b092233cc98a28a3d0f190c691abaf8e192e84a834b8c873026d1a8ee1758ed6457a5ec406511fe61a571bfff584e9222bc1954c588b3d748a8bb8b50e90314e2ccc62488891050fcd63deabbfa3e4235408f409e2a085fa679eeee70c4ff8f37a68b79df0ffbb6eec2f4159498464785ac69f30cf1335ea6f775d3e2063af5cf74b5f75a2dbb85e0d1b11a2cd46583b9bb19f90fe92424a70a0c1b3ca795e04d4087181c2748d4943ec8c073ce2cbec0a5b6f2597ce4af6c0c494ca5f12c28111139dcb05adcfa21fb5acba85e8d986851532c890588f1acfecebf925438d4b80768f2868fe7903c23054fc19159beb1646834da0d3042ac25bc2e43d50e5cffc40601487be032c5190ed4e618c89d7f30037805a19944ebe4a0db571860abcd7421593847b57a178e26b0b6aebd3521ce805c8cf04d9f600e8350328c88406b7f1e9f48a1af7ca59cd95f84d374321d6daa17f652bf247dc49528e341367a93037fcc6f296da24fdc09d0b4074ef3181bf1ac0296f86ebb2c902d1c9b93fa7ab1314fed73bccd53feb358a6e8652e4723685acca4b323e6ebec074802340d4f8c67868366bd1f31c05aefdf55612f998ba0619d64575a6db32d4b786265e8e2dcd5a40071741926b2ccd03d6a8401e3e0785d6769ae06fd42d8d3b3ac42f908639a8ec48e2a8adc4e822703d986262be89eb6da73308ab67050ec1005c9f276dd2ac0cd48cb2c51fa8b06e79c4155b46e6779746fe42a8651ecfd2fdcf45308866d7feee367e86fbe089ec5d52634b3c419530404fbf44462e348eae0385fee6eabd56ac1310adc104bd7428d3fca2e5aaf38cdbae525ace507df4cf77e4186b5e828e0c3adb6a36bfc72823018161b2facd32bd8a7d8eb8c9ab47be2d3127789a16edfbe323a5c6dddd0aa32a9190344f8cdd3c4d86a9cf8b0abc03a0c1cf4e42cefbc7981febb00ab30f3152b838309c06bbd6554d3fc4c25349597fb483c453d8286b8c1ed2981e5c30919852973b85cfbee5aa323f9e7b2a765cd28a90a6375a24b3b195de31f8c9d47f1fafbfede33ba3c55e28b4d2f1a341c2a39132bfbaf9d80b599e1999cbf75fc594702cdc4d2eea9b52a5f80819715f0bfa920f2e2b922ee36802c8bfa1cd75c63e4c2f8946ab6663189a5dc6ca126b8dffa61017357cd528a12586e08cfb41aea1efe0bb2842c8ae36be6a9f3ebea4ae382a56934dfd7d62b17e7f5245b904fd933d365d950487d6ab80cb3d444d89aa4c59ef83a94a8faa6ddb1e2fb4394a554f22854052f0c4fb8654f1855999e5a34c15aa3a4f7fe69e431b6407bc642263f777b315a41c24b403de78ad19f2ce3190e26592a190357a6d2d3efbb04235c947d1690d5b7b283de3449c8e8c2ba099dea8468ec46f8348a5b5a9f9b0f657cc601e5f89fce5462f53dbe3566347f2ef4c3dfbdf479c87e4bbabb8a3bcd5453ec1e85a9c146ad83f9570e304f708b3565d79210bb9959992787da4b59faf3eef75de7ffc7fdd4fd951af03ef112bb4bfe212aa8c4f190a8493cd6e1cf30ea6389ead3cc1bb411048dd8651ff11597dba91408a92a9137d3114739239102c1c0421f48a5f34973e3287b9081cc376b332772919eba34ccdb2edac538c815bb0168ea034c8fd6983e913491d0ffb6a7a5b40fc7ea3ef1754989058d55490ae2790b990c243529abb4d6833a077622e308255d2c4f4dfd1796b46b86db6c506b55bb427037fa390bac3702ebc83b41244cd8c5cbec5a14e09a4b64ece459537f046f60d5bb2d6d0e639541baf8ab4b10acb667f8d307630a787034e360c491b3cc53688d4faffb218c48000d33524008da0ff0bc70f34a351ec2c83e29f90c3891b0d48b3a0f93fb387a85701b552a6816f592e07ca1edba69ef4c2add48f4c97fdd9524ebbfd323ffeb7e459a49cbb44504f9b5dc358ea2f571a79b6c6b368c33444589934ce93c58f6684a52aa431f7b4c0d1a0ab1f049838fc18b05a6b5949ffe921d8d6297a718126b3649b23adfa9b0013f19166c1074810506f4bc2c8142616a4d5ac5ebb8cd6b50b6e78ca864a28dff12b249a405a9cd663fd5b2c292739a1b934a44da9d247a1498dc5a8de97d62c1e02f7fa82787b785facdb079c6eb4feb8a35f9bdac28d6faa3dc08922e4261b83572ab02978042166c3a15950f2fd9f2c13c844eb3c37ada372aeac69cbb33a05bb8643eada1b62fb96094ce9c467fe7680de764562d0b447a7bda05653dc3f1aeab027ad8b58f351554455a8b31113047cd701d0ea551042f1398b9ed7e72b18ac64fdd6850861c7881bf60b1e3eb7f101d525106e9fb1642fafc6ff9a47b8123427bb5df5c61e7852c7ef8854b33176cbdef3c7384636cbcc99a2f2f9801b91ef9bbbe2f26f330efef3ad02d4b16a1b52607d01c219c7fa64816a5b1fca6cc80f91bce59a60b6c1013165c95d2d0747d05f7ba09f4526aa54acc52dc166321876198de84eda457b321fa8f7c38667915ed986048631aafdff4091963cbccd1198924e356435dc08326fd17cf24676ee778b0bcd47296b0775404ac45334e5850947ddb3d4a8ba5f878110b89ab20d734fe5744bce263873ad0c335c392ee73048e64c51404aa8d330cdabc551e07519f32dc6b7fb0afddb1ae1b2cb97c4b727e8f947d839c4b938924410281937cf0739c9b6f9ef77ae43800aa6b695647d8760d262b0975151d876e8b721b88e480f10a2fbeb65e75d18c18e8a655b1a2ca13cdf2cc41b0fdfb26e17315d5cac4f4a71d2be3d11eee94fde0e554d8d68ba95f30d85915bd8921d39a24f557e690524d046fbf377034a63183e15c3229e5014e4c1bb8e67e841c5b9573dddac63fa0fc385bf06dce7ceea3160c86571d514d01dade6b8a1508380d46268a4657e4873e1c66b6253cdab8418a56c3487714192f39f2c5e3b729b5b0ab5afe68994c70546d964d1f6d84d8ff566347850066da16db9dca21b7e3b4760c4f476d026895f850afbb996ff2c73c9a17364c46ebb2093d99af0eb96303ff6e3a905e5871a65efbc9094afeba01ee365c7a6b46def61440c4a29a4f4baca29aa3877e71dc27116cdad1ca02f3e0e024c2b6095a8454f20b07b390aba9974b47e552832419e0eef70cb7a7ea402da7d1cbb90d3ab0c86903810a28f3e96a047d71571488abc678d5f6918321c362093ed4fc0a5e536724117692f2fd219b396e473dfe1797efd6eb47fb4d7c6faf3754e27a0576d499f2534cfdd2ee0e6b991f4b355c3c7d2ba2fb7270434c4f07e83dfed38b4a806edebe4aa0ea6ebd056f40fd3b37c44f716ca18185a5836aac814800d50258f6e14df50c595fa3dd141af8f7661f7d9d3ceeb14cb942ed7f41b3c2c946bed5372588f41412891962f227f3dfbe4bbf812fa4c6b60b92e52b026e2560f3a9777a905f55061ccedf9515c9ace4398e32c1b4ed6e61658c37f207b55c318de7a37611e997cc4ba453aeb6ebc42a00526385a806a8f523dfef4e93414121893ff3ec06505c095a27631402cfe7e5722d9d5d96e76807800ea8ef174dda093c4828f3ca41fd2b02ec4e70c97e350ecf7128e3fd64011eef796c799309cbd1fb765d2bbfd6f06b9072cd0b4dc9f7826b105c8e80dd8274c80a0fe9cd8121524c889b991f4fdf1c74038b10631ad1360d92986e141909b7a62d9692cd40156db075b1d450d043f4c11b92c5fb54e29981c300061de423ef203be8978dfdba969f8b6e1a337fe35b822f0287438113755baf2d67640fef5547b3c8386e2f69521a338f77dfb5870591c9683576bceca82b85682ab25db7d1622275f8f20b6614093ada99f077fc1d62ec9778b99f5d9e1537e0e6aca42a3e3c9ca0c42f34828881f192a9cef6f6de1220c2c3a00ffdad7419a1e3d33eb4622512a2fc01b797a7651fe8a5bbd2c00dbc3a880d2021bf87543f28c68b3eadd83dd40b78bc99362b894fea1948ee6ea19ef69ed4cb50a5a1bfbda64f57a01a40a19bbbf6b8d308829d35e037f08f264c28b6ecfcf8b0d29fbbb8c329c12ec3a2d91d28f7d7c725f4e212875ad9aa020754a2bd6ed3411929709d248ceb7d2b3128ab15ef8131425e551d564dd933601b8b310ff441bf9775ae1845e941f8ebf26668d18458a5feacd42835cbd9d9026481e2de0ce8e640a11f93c6781f04f91d3e7a1a8c344e3bb169e07f617d5fe5842e7f5dea7098124da6ce7a748cfdaf0ef596e98a214bf014adc8565b59e687d1d83e4b11bbb973a98e4ff344e9bdaa2b0a95431bd81dbd4b7426c0d6da768102409447ad03fbadad281cfa9bd0f28f00c9588e8b2136d727660746fa6388b145c1e48a8d9bf8d1a2cb766c19a00e5f00ba5d94b840c8ed4047b36f5c7c1b367c1cc631473452efeb317251b339041d7b3f422074ef2d231956b38d47f81bb0070dbfbafd87e15338db9742c0d11aa8f55d8747cf54ea373f23f232f0c1395888917254fc7fffc13e1ab7770e75a15609dd5d2ce6d7343074028ec1747d1fbcc36ff0b4e9b2acabeaabc88ad1264eb5c054a26ee64007dbe38cd01f9bef7d5ea5932cce8f55ba51e17604ae01cefa47bd19610e370264ee712923cc00089c458e749f2f065a8723275df31a05230e1236a1d1ec487b4a3ef0f55c005e3d682a9813db5c32401ab8cf5e0d371f775714affe7938d7a11f49cb7bc14ef0af9d99300bb302cf4d637bbb89b86f56bdf458689116b567a9e504d8631180814a6a4f8f45e06b2e7e1c71637f3e451fd3bd37098b29c170ff9e030e86cbb054553f977124c29de0149df774c264b715e0545a4717acc2431bf7aaaaa6996c92b3e3e85f9481529177d63c7dffc4e8570714e79bd0680b7afe84822e5ee7a0d65f28760da82f6f91b7d0bbfc1ec897d78e6b6b95f5354b9e1a00999969ab25672a5a3670dfe90cc527df624d14c4ea322b89e7e018ed5c82ce6f5c2e86bc50435bd8e9732186bf237b7637364c88d6b514cd463019b04eef49cf3d9d365a75c2780a5aeebbb02a4a470745281e94e4416800c4a041177a059ffa276404fbf1aa7c8ebb27a025192bb53ae1516b2e15ecfdb16a2ede5fa24c91c9099e66c2432e1e41b633a7f870ab82ac2c2cb21eb211c4b4de096c4901151f107c360ae011b7634e2111a7b4fa81bef116eea333628ed6b587c625f3959e56b66f80efbaf5feba058d00190ac1bccb244f801606bdaa28478f126efab4a1636e16ad2a91db8d5ef049f8461c39727322b3a692a505aabc0a35a77695cb52feadb8cb1a9cd5b0b23285c8a604cdf3bb10bcf199f3b18084d3f570a651f14b427e382f2fead4ddfeeb412ae97b734a358ce61413df20871e1b67df5165c9d69b05634bb1308dd918b6aa65319dbf57ad931826e9f19c6ec59aa9a15b60d41426346143c0e39713b292c8266dc2f2032f23b72efd32eccbff5063caf1019bb6327599c007228a60c32a3f7d94beafafccac5b93b8654cc0ab2347140983fab46dcbd907a748ba7656da19fc8bd8ec2be3ff9a93fa9424a24641efedc9f706b45d384a06c0b41fb1a723aa49c8b26a8a6658e63679386ee7b1d425ce722a13e6e45eeaba17e270391b955641c7fb026dd3454c79a09e07652bb07b8f2f7db5395d1966975ed96e2df0b2d1b7d161e8d7fd51c78823a8061e9d2ddf5dba55596518392c592156e4db8f8a124f16057afac4049ad68dcbe8ac5d99289eca892324c957425a0bd9dc7be0e1c93b2c75ce1b404a1b58f8f1f92cbef0487d0203b0621c67d19ba0eca1b91062fcc34bb93f72a71724fd6be58d2a71dd07e56f5e60d46b91fe89e8d5765b50bda6755f428e93588d9eddc3865b07bdb88a8b365051658475658b56d7026c10a20770bb813fe687ee1ffb0016bee0b38c7756990d6ec5d05dea68bbe91827ef8890e900d049d4cf9120c10e7768533a56dbac5b91e7a58b27a1a3605c64474e144296977ad70ab171ecd29236d14be526a386fec03dbf6530fe3db453c4ba18d332bd6aead56fc3270884eab674b924240a76d27f7277e200f898353b0eaca08a45e11cfccd51fd3007ec96b4463ffd5d4a8d095defdb9e23733d342df01b42894b9b4ce597db7bf6a151a52917b0d7ef5d273f7a16e434e69f164685b753615e4ecaa4360f840ae4b2a64a772f708a793ce9dc692a9d1ad773158d7a508bea25a9711b92e286b7e944a5378b2264a45ce0eec1c0374944dd56baff6c241493f88cbcd50e5918ed8504c1b6e706765518100f09a1bd91c1f7080edacd5c52d8eb584a5e4d3d8fd782caf12f19442b6f31934b4ff8762c44dd05e5ab82bd1d845711b1e051fbfb1d8d66e25a81ca906e21e228428d9605458e6eb19daef7a926fa01ade691ebb9d6f47d950d67fea17d1beeaeeae52d53feb2916da5e870c4d9c9e1dd06dd7fa233e0705c5360497d5b3b70515855660be6c030f7c8075db581a828083206733e826a81090818b02c2ae1aac3ab4f6fe021776d3d36482b754b3152568bc7503209e95ac4922cc52b84ba897341f0e9b6d5d77fdc240a38b00022703787627a3a7d0678ccc8ec675d311fe45cb0d514e964d653acd5a23da9d16474eb9f847fb1ab93cedf4a21ce64150d6b5a6ad693b53a054d7409bf3e6dcbefb1a8766c1408190459eca91ca0a0d613b237ab7ac8a5c6f03afedf088b1d3dc4271ae960424b096a9abbf5cff1533d172a9426275f8c524cf2484193ce6e58b28e1a8f86f6d059a4bfd1faa2260b473cfb45733dd7bf3ccac08d67cc66510dce11fd689009886d7b81f1c15f41d861c05223d94951545c5e6bcc63e41a125133420520d46b44a542fe6fe145685f92b023da3075b91becf45ea2feb3881597ca553f871114f26ee64988dbf6fe173a8766213bec43ca2133f4804caa99f5f9d6389a15fb71a6992cbf0edd87d40b8043c125b14c76403e37ce7166141ba5e4b8db84ea2d1cc6bafb013fa35ae95a44048b3e663be5175daf1c519f67495362bbced03a6a2c5e13ad894c53542c1bd238cfc096702c8d4f55f4f41bf316f9235a6e5b3ff26a334d4d2c3c3f82d2ae4be11bccd443c4693469ab7da10b20dc25cb244d809354778c2f2fe9b72d198cef497acadba23790b6fc09699b273242b9603fb2fa2f175d5d2d648ecfcff6f937e7f6832a5ad9cca3626565a0c31f7e38a47e62472de00311eec93c7bf5477cc42d89e4150880b651df3eb1a7e615e166b5ac9d368ff2f76c66e8dbfaabf98c73ba44b3214323e2828c42a2e68848a68e1d4f438f4b1b4a500075627ab6cfad8065bba23f8d9d6a8e85301d292473f0dba67e6232bda7e35e2787051ea0b422eaf3a6934288042e1febb6d79f2b66e0fcf743c104c6f06283534444b5684878006e1fbf3f697e395fd6d614b3f2b0d4d9b852bd592e3c0aa3e16518ca1f8664046e388d20bffe21558218a87caa96cdcac1634e02483e0a30d05da0f7ec7ee5ba2609110b7eed99cbd3d800f18a6ade1af01c817ea7ba329e2ec17fe5be9a274b37d7ec8f66e196a977fc42d560d913dde3344801a920c90b98e804808b72691e11b59ea9afee231165c17a4adcfbd6edcd08c162b2e6a2af6e58ed4a2069f095f42db146d6fe7cf5a2b0b30795212d4eed9a9a919b1e13ad23aedb69a444c3247fc02265580b84b0d2be1c536667ae71296dd0f028f62fe9a78163c84bc088a77dabbf8ab48fcf499060e8af50f2ea98f929aeb050903b6569501aeec4c64ba7bf203d247900a85f8e33f9da71f3e73e4eecf8708b0f4cc2b1e62c0bccdf6fa31ffa19f3712bd8b36eeded6f8959aa7a9d00c6dd56c7ffc9e1a5f35f2053880b05b54be7798a408db497e81e50cc71170dc70c5610cd4b3b706e859c163ed30a44c047ff3690efb4471d17db8a6362725d01e8698d53bf64c09d4a1ee917304473d8a0247fe7fe2fe82a8211c9421904f4a75ff234fe3fab154c7e3420df726e294dec2d09ba13e5844400634717d7d098893a7580a72f8243f240c954f18c64241bda05605e9773e6f6ce4eb3508ea36659195e39508eaad436b2a96f52c3badcfeef92fb33662451e854ba7d24e8a751c259855e1dade8196ffc0be38ca4fced35e02a2f0200009848c158f6b2d56f9d5818c4151aa031801e85b563f03d1cc98915c3d4f09e361e2103eb43d1ff8ef8f01052c58634a601195a27e3f94a8d4e5d0519335f17b9d50175aa2f008eb263ea9ebde494b158aeb4179e59c1f75fd0de34a148b674046630729221463d1a605cad9714155f215f70559f5912825dc3aff954155c1ed468362c0a30bcdb4fe6fa010c6a753e841877a8f2d113a85675e274c9014648b303fc6fef7b94076c57cdc537fa9f94610259db227bd4ff2b05899567b0959e9434bea2c1eb4373de0e916862f809a94b312d44cac483a964a04709284889bd3fdc1d57c96a27c66f83632cddc215334fbab45bfbe8d6ca8080e72ecb0ea946f068a161d1d93ff58b2926f4b7642aeadc6ff7033cc1e952bc72ac6c81bf2ca5ae3a542a8a01838e5e2bb6d85406e22553d9863d35e1275921aaa521156414c923d8eb08c46932b5cf787dda53c9cacbcef70cc444d5c6cd469518ca80098d0f8fc7353f9bbb79120a2e279067818935e60c4b95d56dc99a21dbd8014f20d8c826077fc46db10dba9bb6fe141c13872d0d3e7b063ea0163633ff6951dc4627dfc02bf1e489d096d4fc3eff7ea5792568fcc63ba664c45030f76800e0ad5f10433f6675c43ab29032a3178195421e35f0335d0c23c90d2edee3a98288949e230ab79ce3d477c937d8eb7c385a72f25057caf6bb2651b68a3c561bca8a471e7c5b275dd4b6151b35ddfd175e99cf736739a8c77586ae627183a74370363fc87795da7d14fe5acb68d6e043a0add6dc3e34c4e85f9ed16c9e5fe2f36dfb6a879d39462a436f29e12d779d58d0bd5e7d8a87e11151faecf4f8ef2341ff773dc8f2af24785e34d57abcc15f07b2317e966d3283c9d947620d0fbf25ca686fcb5976e53ddc3aa8bb620db215ddc5b8f6bc2a2ebd1e3af85366470d864b75e8be3e4114fb54c6547ea271e39e9b0b00a1528da05699a206c6d9c7196c232c299c94e4e500976efa2290dbbdf2b1826cea2080f74431ca34dbbfce44097baf5f8075d10cf23f77b0aaf652e5b20972df12e12ec639a9f9e7f7cfaca269e5760e35c7be3454a9d882644bfcf10f66d0606c5a1df42172e98412a98dc1cddff94544fcafd52da63dd2a2dcf87100d721e08494f86deccf9cd74f8c31f53ea239ca4685988811ca7d2f3a3dc81acb77864b422f717dc66ebcdaf6001a07e4542267149778c2e1c09d670f6b864539983a7c934e3cb10a4fae45616021d88c90655407c082303e8d8beec4bd04de3fa7c8783bd87c1df6e33f57141b0b4eac383634e43108bcdc4d813d85b95d782f3408673e98bf0267ce149431bf71ac4be830ad33affff344b7bd90c08ea8e39fa019083165a0e9d6a4143acfb54a218d00a7a099e2f78e3980a1e798be159b3824f45d7ec11ce1bce19479be4e3462bf1e203455a1b8872ab28e92ff3be4ca54b065f186bfeddbdb09e7000a29475f08ab3de00f88dc4d09dbda8e554b59c1d04ff1e363b1ff4e872e54896ccae5b3051dc17de525dbbcfca076001c0f661f1ebdefd037fefaee4faf0d4e7d48f787b17728fb5960dd1a31de59a6d66c581949e5901469cc6a45e0b9c627b92d3c44f8f7869e7aca131dba02217a6059204089a746bbe21e02ea1559f7a39f297e8bb90c38c8d8157f8154b314c067e940f45405a60516706814edc2f657adf98c87a43a463d35e5ff2594c3fd79144b4a841e2dd498e1ede9040dd0208c1cd78dba1b48ea8f372a26f67fda7f86124ecd881d062138e777c49f14f7fab1649c81b44cd363a874743ece051cc6285d452f3f939497c22991c78390405239e1cf8a56301827c6fa369e221ef0d45e165f042a1e07211ca25115f0d7677fdfc48fbd54b4a5d2081b206e61978748b627467279efebd129f20dba13f8ceb72ddd9dfa34fe26ea026aa2e7d4118404ff00129fa8378bd500976d136c6fd41c779c3824df3eab5e0a67fe24ae0ff2b26ae5b4f0399d05f9ac52281ff220b48b3bacb253286615f8ceb565afa8ffaca6d791675806b59dd6b9756eb62601458ddcae1a51465a5bd2c71695b4a0a83fbffe428cf97f04cf574f2de3c24c7b93070ab1a8294f90f1611d95d994cf4ae65aa2685b4f3d4cfbb0b24aa58aecd273ca7f8458414e4e4646963e4ecea04d73bc66048fa70b4393cfcf2bc0a32fade2e9f6ca5bb1768872b2d512d33fb1de305da9d00291176b9fc5a6611b7ccf1ffd7d05217889a8f63d4a8b340a333384e990efed685a066baa3cc10353f3a84d319d4581468d9ab48561b9db73bc8130a6b9ea3c952cd7bb048fbdb6ceb9c56e4e2ecfffd0022081afa2318bf1f84fe1dfb08fabb04631e3356a89ce88c0853b495ff2469f5dc015ee1c591488158e8e622243b58114c6ea6a609c40e0993bc1daa9aecf6b77d171ab7ff903be84eb1f44536a7b1ae4849f2cd8af0be36a0dd815eb29632e339a7a847ddc8c52739502cc9b93287bf26cc50c1d56a4f522dd5c9a1ede5c41a50b6454f745880cd345d84fb56e1bc539234b190b67dba64e9b214209a5ed89973b13cc9072d4affae991ca5234fbae00321a00500b46369fdb442d28a86795e2a61553edb7f77a28c2da7ddbad24f7f8f8fe0821da76936f18150fefe94ce5529879ffe695c186a09f13af7e18896d6390558a66019e171477b0c83cd7b63d3f69950384ba14cf5d0805f2caf5c9765dde9b37189b313de555fbdb141b57bb87376fe879ff34125503b73fb379d8a921d5b020e058ec704018758bb20650eea8add50ed90fdb25baa1c4689aff58ef2647ae9ccaea70a935681fa59154a3e81a9156e3f48f5a95fcc0fdadef57628f0614d8271abd273af3d8aefe29154b2ce1e977c2a177ec0e81a58c1ef145edaa2f836eedffd672628dc00d1053d807d61ebc7923c369ce25f7effc96866ddba887d7d5d08013d87121c7e1736295e8a877c135c9280a1bba7fce804b7ec84167e2026f038947735b605b4b6ee6339ef55cf2f4428e1c3b331b5e4eb953d888170600cf39f2dfdbb578b1ba33f2ff1a7b74e1ee2a20fff80211c474e60147753d72a40a655379f9900ee1feb67553ef3a586565593c6dd9e51cbfa33e1520b6e8df8523245e26f966b89c277d47da40e88c690e05b29243478ffc8985a2f87f9fca99c4a6393e3a9fc359f802087ca79f7878232fe6acebf862aa3a83c67f42424e96837a3ea25271c3ad0ae1d2033d1c598b6f0874942f2e8c2439ce44f93125b1b3c3ab4b6f258b293e62be2f8a5ba3afbdd0ade19dd66007d69bf0c527c889d34cd325daeb2d7e4cb3433140e9fee0a6b7f2e8096792c1093e914ff84f3244fec7b2def2b29ed27de9a6fb2d9c120e9d77c78bac4c15f0d60159fb539bf750310070f1a1170c4468cb5fd0fec04b6ce3648164ec8e1364f190c7121e8fe6c94810cbca13c90ee29888d6f920c2636b4eb8bfd92a2e4c9c04cb66d15fcd35656922bcb6ad43ef94421d70c24fc305f58312629e7c9b4b510b0d63e24f5375ffe9aaaff3e351a99bc2f7cf86da91d093b8f19a9886907ffc6ab687d31e6e50bdd0e90b32122a586f0dfde0eef7e6567fe8189e8c604b22aacaa6d7c402bd0dcb5bd656601969ef9a92ab5aa3ab51e914613156223e8f26ace74ae2c7518c8ad1b36ee3e36835cb9282c281aa3a3f477702818edafbe202598d822d124ea846741da3d12dd00d850ab0b3fef3c71fd1d9d0317a778bbfbbb36d44a80efe9f4efd60de03d83fa97018ab62ea05c44e9d3c20b75b154f407010902326225c6d3f1722cd64e764c0cde80399dc66beac9de2f86eae944d8c138405b995d8d696e498497c542207e8d3dc8afdc5aaac83bfc8d3b3a75d0cecdec1752df8682625b3e0b72fb4f7a4cd8f2f4beeadaad4265f3f7431d1bb1d12c302a8d4636d5f043a34a1620c0abca58ff160a80dfa3773587f6f046c758f14c70191c47b9eca63060f43134e73d915091d0118f0101de82f9fe39c9f0ead7b2ba2e421dea8eff855dd6c6f772d781ce800bc772e1d307c4dba04ad0cb802220f9911a8aa9ca52266a21bc3e75cd00b58e6b60fa18aec01e7689290afff64cc6fa5448d085c2fb154519a44e865f7cca56337d2c74e6f1136b8c3f419d875ed7ba40b6ce0c639d32f0763dfc59827fe324a44773ef2f20e248456411102078d93806180693f6c6faecf1e093cf1d089835a978651addd631920f17ea4ad306b4ece24e449ae011e0f433c40b26e1a0fe20a01cf83bf1e8424bddd019ff91412de24043a092b261f290db2209d23e9bf7db3950a1e89c69646984e7ebc6b5108d08bafd8b30cb3978759219b5ca5a375686ee020e1e0ffee6851e10536fe25e8954a762fc4fd73d08c509089c29f1a63c55c77e48c6180859ca686cdf8c9cbf49f8f668b9c7545e882f3e0d2c2038216e7df36b78118b62ed6ade1bb82281d18281410f78510dddad14263085fcd7261b5075a94211a49121792dde077dbfebb47b1d305d03c987e3ff2b88620c8ab3566d75a4a2f45e73d1961243c608b4ac1917df9e35a96a949fc8f21b5ffc71142694cfa8ff8901820fafc96a4eca12c304d52020adc31e2299e95e0df5fe3d55ed206eccf29e2e402ece0aabdca1e0a8bf48780773df3b795b24b459966f0c4728a91a0ec40750524877d279db0ae479e2905a095344c4798b164db7b74e080aae0a1abab2dd971a2c62b848a1b2cc1cfccfe9947bcffd997d793702f96e28db75a9cd83d6d4797ddb2ca2d6dd89d35c1d7d791754d2652f7e24502912491b7f96d4d9cc85a9f216fba299076fa5659d6c32543eb0b06c1dd3121cf8420eaf3bf644e4f52699b6a4afb15df6adfd0711862c822df4368e87b5e9a9aa0310bba1afbb000a8a7ded51fa90212ef52140383a5a29990518c2ea6994ca05a1aa8f88b4e8a9959b824a890d0eb7aba004e2d274c7ea70f4916003909eb0fe20e03c366826a7b6b5ce676fd24752ec7a6c6e947193cea31a5e0b22344647346950205431f86b700cc3fa31741d33b3f11614cfd215c2e22937b247680f3cff5e32d04d9c00e14f20453fa4b415ee156e97df42c643c4f534ee7bb113eb631407e854c0d649956ebd62e4bf94cac7ce77163467ae40ad3f86583b4db418d7c329a2aec4f7b7e790b5c7fdbf851bc383ff63cee0c03fb5e3e8026800c74c55fb8e15fddc0d6089b07eb8490dc34f3d35ae51b748c56ec56b989d9909fcd08b1f733266e07cf2fe0229d03f96943d7d09d6eb5c6f06bdb8be9e919b2ef4d1e6f950b425532a85a9f59b84b174a4581944ce586d691c89548b6c5ee48ca8faa2ddd6294eeefcd3406ca811a52e0fb8441eedcd1d4b55a249b54fe630de32dd8739600e96cf2deda5e3714f99393af4465d1c0472aafcd7083ad023fc48ae86c10984255cf6b4c98c95666242868ac70ef8bf77c24191115b991cb4fa0fa2a76907bbc8f74b909ef3dd0764c842f1bd30dc10c2cd7fb672456203c963c99cfdd145c39e501bab4781db1c38af948ff3d68251260b96ad6a49e011ad25ac4a5aea3c3e9cf02ad9f7d71ca7db2c21680d32b62a2668a720eb0490fdf401ae6c5af36b8c2b6ca527acbf4fb4afbd1986c3d1cfdd1c54324abacdaa5476914faaeedd07ecea2bfa66b793c6606055943ace585b8dd808e2557f5a588bebded380d3ee0cf837fb40fe4d0b1a5df797693a17a86c5fe8564692ca893bd86c593855cba070443ed4aee9036df36c351575398034879f517248af791f140e2a682458401bc9c35fb6d08cd67c5c7adedc534d9ea5f9a249758000bbf4cfe44b4904b1e4acd5413db960f5cb969fffa9ef675ccceab6e680bdbb671bcd39cf193b8bb1de909fef0af567cdfc7d50c5bcb727bb74b9425e5786e82cd98105131211516cfb8777541f9d9b890e6402b12e7dfdef5152e8fe046f326b9818a27e2a9748769d0b068f3a427e8fecd97d8721301fbb2a06139f36347aa08dbc5d784214850a9568279980a0f0a98792bbf66e7e09d33739919aa568f7b0d5e0da0e728d7a02dd8a482b4828b7b0da93ce99b6633ca79e7acf19f9639c1ceaafe56c1ac1d22a27148a66e2a8aa1f158af5e53b0ab56c5a3d28ced2340c79cefeb0be5a3a32bf4c3cc784f352fbb79f87513c63b11d9aa9b9452bbb715c3da69e6dd20f027419bba76169dcd70a4fb2b6edd8e2baa7031b28327c55abce2fb268e2b1d9da06da9b468487c73cdb17e67e7e87640afb0a0a7bbec8689b2c18200ae67895e842df263112b6efec05a3a67ee9e23a3678168dd5425e934e2004b82072d4c0625630b2a0dff5c0bc413327d7d7eb97241db2393a9fbaf976a190afc86ed074d3993a9f4b76c9ae17c43ae5fb05ca7664190b2608264673cf201fb48d0b2db6fd6736f70c6c0db4de0f0847f2e1364b92a67201a62aa5f383d8e9fa6c5def016dd322ec140c48c5d7524cd11f4fecda1bb113741b43362abab645d568cb336a417c5bfa5f32fb5beed8dd8f37de92cac9c4227e17b88144546cdc02f48097dcfc1d79b46026503a26717652ea472e0de14071a81dbd9ef925a5a38f80c5a8064683b71fde9f6e13f8671b56d38f9518d6192092a0ba1e2d1bec797aff5cac444a8d452e83b513d052a0c88a9e671992fd249ad45a2a319ed49c3f8fc89c2a5217a5379995521663b417e71a374a2ebe71f8cd39834a667c06928e9aecb2fab560f74e4309e48907491dd422ee763099c47e10e0b112e921ae35b9b6da2083bef45bcaa9a7a8afaa0b851a72d9da0b5334f66337d038c24699d412ca666bc03d811f71aad1800d675b718e1550de60864ba2b6a4ea583f055e3e1b8f5faac93e6b17a49ef947118abbdb4f3e1894dc09fa6743744869317fb13587a0de4758aa2ed4d9c2d97e143426113135d03a00f19bab5eeac3f2e18b2f2c2a86f767ff234197cd67b2a4968ffc26bb7839a837f0eb85d459d0f6543bf8f108f24e7e149358357bd079b70e8d3f46f0b77363d6868bdb637d7dd8af8397521532767f2a254e862f6ad037202e26a9a1f99cf46848698968e63d45ee38504d9ab68db5e16ac2cd024ef4ba80da091572714d9ea08b6a1a0e5e83e8d43e9fcf6cb2eabde1bbda6cf668e0cf78e3c75857dfbc8cb9cc9c8b6c121966dd836d8edbacf12c1aa82b4e8087131d9c015ea0e31506adf0b33a4c7728e625b997363239585c1ecb2106c28172fc8520b661fef82a549f707d0264c353bcf68cadd70df3ee89a238252183e040dd6a4dc51a59e681147ead6cc558688d54841ab2d88934fee8f6ac4f73048b071e84b4b066618064ddce72aaef4711cda80f23bde082b6776e08d7772a00d5b89ccf7a91c8087be29770f68b7c928ac9f60f85903c63633c575b0e07c820c7e226f683fc5a0b14df3b43476d5f921b443e0d21678b0813cc4688c8242e0ce490fdb1ecce573415c2b87e4293cff69bf741940125e37147852d4ebca1072a71a73ba0d1efd25f71a6875ec9506cfe0182fa76ef26ffa13cb0fe37035d8826ae7535ebefa35c247199919d164b8cfe2c9473505729b7c17a86418f66abd5fe4dcfcaff08a70a456192e21616e81d997fecd8a8ee783190c3791698c3fe53e6f1da3f60c5bf1bc42d1120206ce0897398f0d5bc1cf5b27aa4501c1d51684ab0fe44369bfce8c0cf92aec0d75dfb8d4dfd90712cc5645df19fbb316da65da34b81065020fc4f8a27005e2db78d4ba2f4c08bdf72abb4e88d9fa3f96995dcf494e21a5b830d3ed959b99df6c32e0563050a1512d19eccb692f4e496cff9fccdf4601f498cad6c83de6fa1a5e385fe6b4499d744fda1c1ee165c7e6166ac9e7db818be7190fd641581b8fea8687f31f2b9efa6cd3f8b01c5c55270f7533118280eb283238e50b16d1ec66ca135802f5bff49af37ece6490b41c0ccc51146690bc6f8469deafc8848d8e5e64f05e9172ba4abc10f77d425e0dc6d213dbc95d3ff14c1a4000b3024a61fc2f5d8d237e278cf76f87f0de3c4dadbd774a3384e0cfeca13e7dde712117a86224424978a8eaa90f976f9f62e34de06115adf031620ddd63a477c11183338bcfe47af8e0ca0f2e3c3b012f2e1bd54747477754c82a1ec9b4b5b80220bcdbd6b66363a1f4753b99c2a5ec49e6d384a31489ead191ce59047ceecffdf33f21695ea04acc6cea9c9145d66e481f5df582232bf44888c9698ef08ea3d46d2ccdaf905a248c177c07e00e4bb52e3d2bce1277c99fa4ed21fb8bcfbecc1b12f8f324f1e000d797d43847a400b248c635b997490c62df7b5cbc11ae8fdecf93dad9014e43d57953a0fc51a988ce8df180f2e8f94081b257d7d18cbdc56b9f6f7621eb598324e8d046bc605572b9ea9b0271ae6c4d21f04e4020161635904aadb09e9ca799a9f582e74022ed082c204bc8b593f23e84342a35dc059a3d3794cec694ac2c52be7cc9bd099d978bf2d8e9aef0266e60b9b06b63a60b542ccc97e5073f1ba09315bc0173dd546aa844242009cd984f804f56e8a46f568dedf741130153749fe7d3672b0e65bdbe1db63f33c2b23cc361a9e02d469cc99a228dbf0f962ec35cf332c458c678eb8a235644423b7a2cad3cbc9dc7360ac4a0585ab2b4adb1e119d8066e32fc474852f928d765b858484c88c8cae886b4751cc86e2fc47516b2ccc445b3a5a1cd561596a263b245b502d1e95ba7cbafe8c9be8eb4540e4d8805b417a7dd1bfb3de3b765f68058d13c52a7c47d564f82bb382bce6fbb9645cd57dc51a611150f8fcc4fb630ff7fb527684eddf36c3ffa0ce506e4081a7aa2c650fcb942e83118e33ae34a4ad409a1a4add1e3f4f359b6f5ab6778a2e6fdb55612808a0395922724688de556144dd1522b34f14fbb3d9382f5ed4cd8019403aac2fb7bd410f4cebd9f893a50844dc0017cbeafc15d51efc368514f94ffe3118490b2884200554b7fb404da252d5b027e7dc79832a15071fd8ba1c359b6e382881ef8041601c8b83c28c27d6f3312666907aa996020306fcb8a342f78c12d5d63fc57715213d2a11dcb891fdea859f1d9025ba7f8d3b01f2fc9611078b9744f269a916241d0a0aaafa4d93ba576b429bcd3acd2b6f3a44706516d9e7201c0d4b9370c818cf6a015e252fa6b1689a5b21613af07e9b1e6508ca0ffa4db2f349a65814441afc10e9d8eb51e64bcb34c6c09609dc09b8de19745121717e7a885283d58729c4334aee6bea7434709f85baeaa2d8e706f611c7fbfc445217e918153b1a9cfa5e5f3ad076112e90acfb83cb6f86a758392df630330ef2083029d2589135e8ca1e10498ec6624d74b20fbe07a51784c1f9f948e0bdc9fb33b18d37f1a2af05aed383cdf5959853687bc9e8563db547766578e3227d81a3feec6588acb3e5adaa1e5c1e6607f9a880e01f569450d066f08da8067924627695fc0090e433b1323e68b403a6e27456004929e0b50083e5cdbd0a799b5ced4bd89f9002287b89c42ed3d127f3ad5f25c87d9eef228cd5df4b8e41246f80aeb4ac7e5238d001e1347cf1d6f8ddfd7baa07afaea7f00bddae49a2cee567da095d6515956804feb979f37b99310341dc37f47e25474516a1b92c9cfff71948174e7523eb43bb7ddf569362645d448af15946147b7f855324a18ae2c65ba2948d62136a1094cd4e58324d946bdadcdb9ead2552f36406309bba43378d8789f0e7c73fb5733f2fa007249634c2fd5944e05b71cf25ffc0973ac6175a787f34d270ef447fd5fc1daa7dfb8b6ee74304141c497c10ccd892cabf9e96682facd0b4a78a539b3a5dd8b3a62a76fa9bbf83559c639be34a647bbfbf7918abb5361fe65712787823ff3eab34e7cca3a931d97b311a74fbc580a36b720169bf23f7760a075fb845787a0e81ab52d33d0b6ecc7ff712f6e11e25380df65d156a16c454a26b733617096673caa1fdb024b38b045763056f96924ee2af0235957a758d2860bfb8b2546be6d0a0745b389fc3a0f84728f3d7f87f39a2fa6fc69f5a5e22c4822c79bb82a05decc8d76e6ab7807e7ee304d340f03b0d76fd9810c2673a8bed262fa9486c406dfd870d08d922393d3a83bc738b7a618a8b14a0678449bed7615350d73b95d19afca8707fa44c1a0fab0967cd804b0841188fcf609712a2c394c7c603edbc3bfeebcabd89dc9f68de21af1b4bb4063e154ef3ed7be76e76a38ff3fd1420077bb17a762c97a77c276a2200084334e351912815741d0ba6c4f5c31773acbd49d5d064e5cae5e38ac7d2cbbf3336a89cc86cfa9ab87446d08dd886a98ccb38ad428ff6d88818a92c0f48945dea048ba7f0d2c0401ce24918128a37e9713d8f401c5110ce7c6f5a30a888ceeba31032f37530a78a9faaad835a0de3467b4a638dc68e0f2eb762b44dd51999566611e63dc86fc9a3235f32807284ff8534e6785f16f9689b19d20bfcff3bb30e8c55f9cc164988c11a3cd062d0e0e9b6324b9c194f10f0c5dd050247e4eb8bfc754580e506d83cd7f2cf7da33e01275c7c4b8be3490513e9efbf1265a336c58a5c0e13c1e908143f4c02561ee757361625108f83e90d4896c3d3949dda059ae386d541c7ec959b61b05d4401d906efd09c90a28749fe068f799b34bee39b6424d8f192ac01a71ec660c84d2b505e6cf5d2c8f4d6cac7350e242876b1f3354b73d1715e1797f89f3d42353e01d001f03c46d6afa9e4faf68f965b2396ef6cff4f4715a639c49e5c15339a8dd708dc0bdf6290ceed70d7d9f1e696031847210e0c08abdce65dda5f8843de7a1c230bcf3c7bcf87cb244b06ad7129a65bebfd1b8f3da73060fdf28d441117d35157dad1b5d401d25a4306eacfd27efb7a96361747865876679d0818c1c90b89dbd0588d4fa646395b95d39ae4e6031f55b3ec58fecbcf6c341f0daa256b785522e557bc0664c39ad475caced09f31b9f49afe87fb191ef58ba5fe20f8fc6c8a9a88cee4d7d76db335215668a919fa8edf08946aa5849d5a2dfe48823af0a545342c1a5e7236b067239624fa82ec17e2d2f3a1f12a69f316fbb5b95a44eea5bd28d9fe2c61c32785f566ffe78a59d5c62b69dd40df2d4a0d1ec44830a1d11e9caf1ca2d88a342511761ba338648af9c3d08604977b153776ef13895ec3d1c6cdcbc45993ed3fb99b7e60b2f27ce5a813958e4cf1112cc7b05a3e570b9dcacf52457d61afce190eaf6f88b0f730fc20c2a9cd03634022f312e33c7c2bb2f5328fadc8b72b8a94885ae8bfcbdf4d7ea5cff58d0eec5d3f8a41860619e5a3a28ddc69cd8f65936a9eec81d43b0099290e47621c7904e5283088a01d8e160061e551af996470463efe754c536a75c1a8c59775cd9f1474f09159b9a5ddc0a28ce8f16699c3f47540edaafacebc3fbe9542bd31d2474d5788873a09aee420d78020cceedfd6327ae08f6ae393bc0d4102d4ece05e6e5886a8b108ce2c0b9a7a50edcd05aa5d88f84659ce1d66524055f46931c84b44b6795ac792a80ef365dedc4d8b017586d745591639f6da7b9e1684197356432121d811bfa87e082ad34aea639dbb643b9053b916b982a6968ac1a96d73bbda35c52750d87436a3ce37273056079d33ba2af61d3698a1efc668ee87e79ce7098cf73259d84d872b7e94db57a73b0cad6f3b289d85efacab1adda30774b05a3d027ca454c77ab57d7ef33e2a4a9e2da3e4cc64c2b4b2f38cccba1a7c584e1f898f7cf869a1b1391072963d9a49cc0b026dfdb40bd77fd51e5041d132a09de547978221fbcba6c72f9afdbb015c14de5bd8d052dc40bec9d3fbd27b7508d78f3e663df55ed312763f774bacae9076c5f06768a430830e180dbbceac62d07780290a3ae58f53a2da36b89aa9b989f16c121203cae453ca63fdf48f17d985df255a9ffb584cda5e3c83945b7bd71e92354b59b1da7f96f29c92b11c72f2545c88070a1f724e721a63fe23de13bd8854f8e87cff0757819752975156048b1db41a6d18be4a5ab9f6c77720b4fbaae439d8d3ddc377aa4bd82f631305ff45360f8935197bfd5f28d7a45ddd6ac6865e93cfa56b3612a1201443e1c0152cb1e8443ac47d2ba664a59c6a7c4cc766c8f300ce9142b69b9a8d1c621044b41f02a724786ab223f1109a5b7bdc2a88a8024ce439044da24b8879366b82ad257afd1d943b595965243ab0d9d4ff268683d3f64f4a90ee07c55f99f1e7b5c64ae99bb1a2076f82d468d38f83d54ef166d24293d02fe33ac86f28fafcdcee8c5f660e226a8936930b3ca497b7ab1215a98f58f96a4089528cbdfe1ecad569b7de3f52746342fdd26e4755f0424dbe023bfe235ed90ad73b3ed194b34c96fcfb4a568a3cddec7388527f10c8f4ae61a024c8a74cd0ea182954d3e82418bfb4a509132eed5b6c5c251b4d1b35038c69f00dd8ebff41b989da0e8dfff81c4f4c2bffd7826c47b91ef958e84c40fb83050a8cefdbc3c6e4be763ae49ece48cf1eb4819959a86f0faf21404d951078f717c8d963e77af39ce188ffaf1d962918444923b548c5f90e9aca23e8f50f50a6a17238f7314306336455c51fd6f25722df08ff3308a479f3a082c7f9b34f96759ca8ab5d338e6dec9f374cc65ad7043448e0e3da14ec441734e0be7f108d7ee1c7f19bafb5d404c1375879fe61f7bd9b0a247afd7fa8cebbfd3b6dedba5fc021141bf914d46fefa8e8708609feacd6bda97f3cc9b79d20ccc23e4bad4301504244d19b3ceab292178daa47a08d46941da6ce9d3f29047f1f1ebbcab0e286df5de2abded6e70b7da6da84e0723e233bd270a0d21eaa53349b229646f81f7f4bac524871ea09c1cd0c663feb3fca261312627140eb1a828a1cdddd3af584c8b39b2827f624761184c0e6094a7ca2a85978c49781c1e0a0ed38d200ea795a8c60f0765ffa0f11c949588fac20fa4af2fde08ee9e6cbe3b9fa7967ada17c924eb4ba161c21b0f1436d2a32248a04cce90632796330e5fb7333b77dcfd0e726b2ca0822b114f88eccb208da1115b7e150d54e055c02e150a917b4d820902252011f31f2972ff27fc1006fad71af9ee315f96a5fcdc5f4d1c54b50057b4a26e18c2a4b363561f3ef50006314a6ef32482960f403d6d372b82c8e796a4d485d36e872de80a79f523289bdc0a9aa5b9c1b31e536976f0ba3824fd52764470ba29d416710065c09de6f0ae9b02d719a91085b64d64c955da8368550f8974a431438f3bd2e7409e497b3a4d106a1174e3048f04786c05dab57b56104bd243907ba5922ecb9e29fcec5d4b7bb9527077a4d71903c4fcd80a5952e4603173d248487e78fcd2135645f19bf407c4e2c1939c5a3556ca004dba6f9763ae91790e54c14ea5b5b94a4b7c1110a2abef49916a4758e0878a1273e2dbc2168e3daf0097dfdd5ba0a708d18da2e5ad2a681ce0860b44fd54c18e4e3d54c54bbaf724cfb4b6813f6af51ecd968d07e218c44fbd6879d83808d5c2a0d081b0b8375f4388b2f11433a22be408dc9c8ccbeee66ba7ff3ea5cf8086f3ce9eb080c82b2333d289549ff37b5f9cf184f2a814e854914878ef111bc4b64322cd00f1ba6e588bf3a36708950ebdda1b985a23dbf8d04cf00f96ee0aaf14d606c4c023b4fee2072368995bdba5916490e0334dd0e4be9d4173bc07d1675df1744e4eca0990c8014fd41047c106817cc4fd17f7712d75328da168187d68055b92f1d6db8c1fcee36f91104a74e58a8abfa3226dd4f52a310c92acfa375d4be860be47d0167a636d1ae42bbbc8da57b706a3c3a2b477f3de87508e2a76c8abe9dd08f04849775e505f0b3052785977981170f587cbe0a64e0d359ee0fc8c3d4cb32f4512d9a7cbc4cef07a1196ad5c37369504f72408d8702d3d8ad640f7046e7273be66afcd14311c9a5648f521183c6b368c33f477cc5f5f39e87c264c355930a4d91858e402d5f7c307459eb58e37f8bee393eb851e201e58837d3474dbda28f2ad63c3ab41de95b03ed9683d9e06fa121a092fca168d0ee9621028c7ca956bca4166e88550c1f99fe6277379247d10662d0a1849a6e95b1001888fc3d0f82281df80e4c32d757f48010eb7121614d4811acfbf6bf8ccca1345c11a43b8ddd53f0693c2b8d05035985486babacea2c2ebc9a5da889f25c07adcff219cdb54cf5fee3d0389d9111e581d2a6f6860821e8461cb37d65b055e5b445edba4e72e81e3813cc7e2ce2808380f5b1fcd344184c21c9d816c88bbb7f6f0174689ee52ced91322efacb56898f672eb8bb3bf7fae47315dc64853d2738d83b04248fc7efbdaeb4abeda98bf0d09c5c56a1ec5b4d19143cd677b8adde5ba1416f71f01113fdaf3ac8caea0c81a6ea40a31631ee1370be81fb73bddf6fe412c8ca7e86210b3befa01e347e5de3a690f814fffc8652fdfecbbdc12cdefce4c73120d5f51a2aea265d51ba03d412402392c581c6b66343a1358b2995c28a38ce112df71df301b0dc5ce2c0b7dca7fcd7fde2e05f723fec07996bb23a2ed99a28d27abe8268f19602fe42cf3ba352021db640d9339b8de4e9e49321cd447a39bd9f4ba9ced081127381d699322ad19abf33f48fca4af7c30403a1158a0c9831fb01e42340295268ee0dd402e9dcf713fe2634f93c480ce91ec5075ed1c7888b43e710038952ebc4bdff443105f43f745f85a54dff7b418505a1edc8747a047cbccb1ed036849c9c68e1d18ac052e3b50a3d01e3d397e378c65341973cf879eacc072272309def0af9921cebe3631d14904edfe9e7d7888992127a925319b9c4927fee66c646f4eedf80e262c87836931a71bbd69921d53b6226b0787e9bb3c5851b317768afa6b2b9cfd55fb655416af6b880cdf2170f8633f300516ca37b391558fa975e5c737ceb32b87f9e635a5f702f51bff7d0fe2d6252ea581888e8cf7af48a9a6cada64a1c9bbffe719af075ff0ef34e781904932d58ddddced10119f114eb6b4671ed258c835722ad8c806e8e5876995f88731af50fd001da23c21ce210bb1c762be1005e787961f5e44b8641f0d37e3bc7572656cfa7b671a681796d6a9fb7532e6655b83fb01f5c67004943dea551f73f6268bc4863f7035be9865b8a26a55bab8b78b1ae30e55b58768a5b1288844aab41fd7f418abebf748ec13f2d1211a83a0f0fd3668c0f4ce041aa4e17c4bc3a7d8da2431cbd94b4b26b19bb87afdf4577428a2705e7b88fd42c96f0e692c8540de894b0507b3a7567980cf90c0902f4d5ab9020db63356339e82bdac5adf63fa694a62b7bbcc9b0eb40ce05475fb6f273c3438a313889215d57eeb3d81a981390ad59eea57c382bf2b94516a8f05a318c96efe98ff76e9708d3a2d51fdfc83083a06b2c1f487eb7636d34e967e0b077b42e1ea10718cff50fba366a96aebf599674f823bcee64c024d4af9d2c26d342d3abaa23a2ad6b73af9ae78f1a4f0404f7bafd69d7fc332ec3c3a2a7a1e533de7a49ac4ca83a1b34bd610e97b91c0e7e090944b650a9b1227d521d4d5f93f9ce95275f5c54099f9de8405183bad1fa9d42c386fe7e1aa7f0f0c712556fbdd2a5458d0b506f910edf266332d2ecad44f5cc83585289fd79a8e99706b7eab546c9e0d1ffe3fbe99cc8c0cf45115858d0e3f75eadf9f628523fd39a3aeef8857d88a13a8407e982d761060107e81e6350874a236bae70db4121c910ef786e921b6a6d4bd01a14ce4988a6e1407a76dd3fc619a8977f37032d6b6d85b5699a98f8786fc5ac76ac21e721741d223a8037109d0cf5e642c05d229e3b54c0613585a3bd89495f07843783b3f0c27e447ba4c7bfeb17b443619457db622fe46b4ebea267792050e682388acb1537df848a87a726888196b783d98986793173eb69296bae7aa72e563c8f0db55f9a767d05bd88097c8c8b7e7c70acbf17402ae0ff114b683f61fd827a121fe492a124cf970238dbb9aaf8483ece896c328147820fbfa0c497aab0c017f6e4525332e3048e975c9afd2483567951362ead0410d5716ba0fea0add2df48037f4141b137d60ef6bd3c0826cbe754428ba330d697b90c29af9b403ddebf6cd9dfade145802573a3e02401bcd13339b2dd41a5c87a68e9de53c638f9c562e107805f3ad3e63b2364b2f64feb456a72447d89d245d7e2fdb2b3c52bca1477a9e48d81e493089955b7ed3ef7b446f5c15cdba19abf9496282e05a8a427a64c28a546d6d311cdf4b84212d6895826cc00c2c3c709c2bdcce0496a0ba5145e69f9118c926719a75dff7a8be1fd9fa0d41cc32ae5637a5a8a495459d33e87470613ee70fa99c280090f505a93e92c954907865d8e25c8d2cfad3acef5ab1cc53eeefdaebbb0585db059a2ec3e25288470bdf18332d26f6fccf4a9b72b75dd3b33b37101ca6fa0547faa08913f3a15f44d41a177c897bbdcbb348ea1c0af0b6bfec19c8461f2ba07039c7660e3fb58ebe5c9f867840d046d7d9915b002d4a08783a168f83f81377d03b5d520d3fa53e264e158ed6bce3ac7fce428b294c7d79f500b094b64dd012ed296a954b7254170cd1e70ea7a3388e6ec9af2a2ea07b5b208f5cf16d1dcfea82fb2ebcf445bc544e582335be57b4fe637fbb8cd038229529c1876b32659087fb3019bd03a63c050087bb8f79f4ababfef9b3909e325f9277b4ae78b18b1d88a48163c2f42d24123268da63df96fc4aecf63bd680dcdf1d27f6970ea9272934700fbdeb57a1c0202c3603ac1d78ddd6506249a3f529e8331c825e3b68b12b3c3e24adfd331ab84992de2b4835bbf11f535bf046983db6643d4bab242e4eb34066173789b5f07feb599f05b7467012ed71dfde4d8a6682c68bacfc13e1600a5e7567298c89909235ba7684d178e0743d4aa956c406f218ff44ce996fc8a7feca30990899b0b9d8c4a9dd90017b132c32cd4c18f880a7b463dee4dcdddbee80ccf6411e78d1c4a71f7ec1e5253220935078f25c4ad766eb21771fc100ce8a58436295c072d031b66358584d7e95a0a54f7dbfe3572fc513efd70e338bfbb2da9e13e799bf698df66cb64cec7d9df1ced00f507d09b9777e08608ce8c6ff74cc91ecdfdda38f078c54cffa6242e80bf55a302aff4fff33cefd72fff7851e705287df0f300e1a6a9db170db8b0061310a3c9c64e1fb50e6a5fd5ee404163ef730db04d7e8ffdc0fa3563be85229596460fced3f6ab6bd4d8740557e955515ca81bdf40a661aaa3c1eb5bd44b4f8bd0650d56ec75a04b8327e55c524647ac158e4c984d0ac90d4d043090dba56cd4647117a5a2f3156f7d323828d677b51d85d3ded515d6371a0be5b1c39923e2d27f4c5ecb176dc11c81ce84dd79f662d2f71c7b934ee3469f7196b78b061eabc6877856a09702254ec10e6484b6a9c317ad7b1212b363d2eefe57bc9844f1888630272cf5525c0a823971e6445363fa0294d4a95857dc0afdec2a701779ada2c7a9e2be5965afb2fb127fdcbeb828f1eb66877daa6151f8f86125eedd174dbec31631c4fa5f701326085855ee96a00237a0f2992f5e65d85bb76023fe0eedd0a4fbec602fd811269fc901e4121b68d1c21500bfad23399d167693db32bf39f01b9fb1c56b1cfa41f80c879cf66e4c99674ed3a1e6eba2077df7d8f87d8571afa54e6c0d3b9dce84182b23022a663ed2057018789ee769f46d3c025ff856320a13bab256fc669e240b878f170956a7b96f300ad56c400143f3061a30e17540e40ee7bf9c61051759d02e09ebb442312fdc67944b12d5c22eac93b03c7e344a5dd1fccad1fceaa0b086f097d602845c15a2a10b349c082608e8cebde04f49aebbb8b81676194e6e54f3603fe4537152ae759ca458bb0af92f1fedb42f40f74c95974abff9e952edb7e5198cbf7257bfd57d0a879a190ab8e1877664f96893c736abb844dd3af4ceadff2a46bfc48af0dd6e4e6f1f69dadaeec56fbbf6fbca089168bd4ed433cf6de90448e128b5b78842ab98c50cee9a9f405584021a56229aca292a48fd52bcaa1f734c03e6f7e5a332ae8ac225587fc8228a3ca7d20e36a97763cfc864bd48b9555a1e3d85e73eb909bfc9a8fb313ab98773357ce913945e27cd23efe675fcabef5ea8ea9c52d85174a46a3045b9aabb4f7cd175b6e859d34ac399987910ca7c47f555b6bce1d52995f70c5d1356c7f299f2b87a6b54da941b35c7febf06d05b9f1c2b1aa4813246317bb9a023fdc388839597464081529f897e4d7c7527ad47d8b61deef6a32261e22aa04947025150690368326690a23fac7f4cb23a404ff4b236e913d095345b8096c98717d09da001cb11220028fac895394dd7eadef309c9a9a3b0c8bffd3f79806159a4250ad75d37c412f0ae840eb282b773fe9fb69ed6ad9ed4ef13af10359e8e0a7e3e12c5f4e1412f374a824719901de98420eb2207f404f6e88ffc8456e750b2306df5a2baed3cb2140fb2782b5407e00da0d56d2688e9b19dc41c34b160239392d7605432ff5917698e732e9fd18578e46c9b3251e36724c41911b07bbe708e1b1968321cedf318b06691cf45f533bc5dd869ad2b6b4abd146db5f2fd465e53733937cb8b8280df5109aa5a5e2b9008e59264e00eb91eab92232bfe7c564b8a9de3ecd4216d2237803cc7576e5d7dc18a661eb84e70e1199383dcb09347701382b2053d65e09342756520970293a3f76f55dc969fcc535381a83071d3c078eaacb91dcb2b7776fcaa1f6b570a5a64b3887d8862ba288764b6a9fbdf865622aca64ba57a18c6b049dcb1bb122618c1ccdebd1e6c91432e3afd326e64e7e1fbef57f57068ad5b07013c41150e671715124ddcffc20c67620f9081725a245f125358259aca088f634e7bed8da00e9d84b755342906238524977f61a7e89b46d616ac279568bf01d3f1c93550124f8168f9000aa18798c458529611e21d4d7c32fc928012d563c47a7024f312fd685e64817f1674f711ea985e4422fe21d9015b140e7c8a544b5889a041242602abb92268a90429b4b24edc2b20a280cd795053f67d8c06bf2c5d2c798e2d21830db2cdfe55528c0b731fcbfa2a0f7b543b972753416564e27e9f6b61026512125a940433129fafbce020b25d423b997c2cfc736bad2b9c75b9e8812e98a85efaf008eca361a220f7c1bd50002182d808d8077d59db34879e14f701bedcfe91e844fffe7fe064084afa28175012063a80c4e0bb8175dad282efb13651681331305b87d3f49d61c1464ce3b4ce4729445ad91bb6be799b20cf5639c346f4ada47299286a42df809a6a686cdef07297fd9024efb31d90e3894c31828d64ad1d5d050fa4f51895e02f0814dd54fc48cddb170701eb55200c42e71060545b62e4af630d1c8687276f1c20c9872b4e4453551a70bcd8ba0bd1778c5c3e47367e06dea7b753b8bc261e5f64a0155d65cde796ff0a06ce4632c29aea5090d2f3cbc37b11e38f54d104ac053936e1f9ef9fd2291f792fca8892eb65fd948fda0f79ad771b14fc65d7b6e119eae23e168459dcf8cf0543bb14d4f41c503fea677d266f480e014eedb07ec3e2c3df4628831b4b557564216828e27a928ee65c0ca4ff72473c39289aa0fa47a4e9090d2b6b88fa32894c73db3c7c4004a5e79e8c8c0c2055ad32230bf78d257bfc0774f6f91420eef2fb6039921f40faebe14510f8a69bff708a0deff9464d9265751d768448a0063e2206e8a9699bc3f0cdd9ce3df33acf5188a0edb3d1d0784d9101cdd4920fd098339a38490b6f5fc6780252c18ffb8a44ceecb634e62b169e548475b1207bba1c92c06b5f925a2ecedf38d78ce56682e94d68799d689a40c4ccc65162c676e799c9b83cce24ab309487028043dfb57466ec6d0468468723b47c00edffd7e9f49fb4e5926391ea1dfe04992bdc3cbbb28f46a1d7e2225683f50c786b671a721ff497b56b3faf1f8b04a5fe5a161c53cc325fec20cb32a51686ac7800ed140fea00426b8712d686e7908a68abf52f666a2e3d78990e155cacfff3f2ffb081354711b237cbe3fed781676d017dd0bbadf769f212b496d5ca751e1d349188d50b8edd020020e3edf290511ca7ca854a2354fbecb14a74bfb0a997f180f8dafe8ceeefcf6dd422248f24951937d216f1b2a345b9a1fe3ebbb7e4dae079ab77030f9257e9d5d6a2f00a97549d51073177b9c13f2eb59e9f11758239ef0b235e5f1bb5c13bcf305d312da0ce6dcc5a8e406bfd92260aef98eab78b72c3d3c9ff25b5a23b977916069dd35d7b87ccc75326fcd480905f09e7dad907b2463fc30db8e5b6f0d04b7346c8315709e26bc4d86c20ae131806a70dd8da8a68426994aa9ace3aa43e6551c290811bba43c22a700ab2d51cee8ec77f2a8f608e84a0f95668aed15e6e11645aa3f85a0fc9f5dd1d897f7017650838ac1fe2d2a3b722b6da49d04347b2b2a67ed33ba5248701394fc7b3f43115d0d4928f8677a1d615c0d3c6e13e17bf636106badc723d00abf96d358b1d0bbdfe3fb292d080d937b12c656679bca030e8615332c89fb5661b44492d22b98239bfe1fd84d5b20a62ab49f46bbcce4726799b36b6d06037857958194369522d67dbc16f91ef412475d9307a525ba081a8ce61d7a0b3c424b4272e976022613b9c484b2f23722777d7288103a9332978a11217f9f8202d06487d385cbcaec9c14c6493708cf320ecddfd04e55808bc28d0db59600f25bae5955ed48f99eb160b18ad9b0306a6a73c56afac0de5494f2b0ef4db499cf10fe6aa6bc8f74e48b1bbbfef6ac5e900fe3c19f6e48007fd6fa902b4bba9215874d1e7cab524489239a4369a1a10cb5ce1f513e30099c411ae6192228609a0eaca35b967eee16e0ee451e240f05b9cd45391d517f3b38ac066b256664a25668036ba303da40802519ca10019c802c79101c3d93f8dd4a9ed02e980392c5ea861c08730f0bf533b7500c57f15d88e05501b0e2daa596cfe2342053145b4c035bc4765f53d56b41ec07e85eb7ff890042eaeb35ccaa0673cc58dd083c8a15b16814b8386fddf237b863cbe9201ba3c36cae4fd5726f3c39e3e66e12b167c1bc44c1889c078df567d7194165f99b39c31094a8f6a383b785dd3fc6b748a573de413ffdad6d7aed55ec01d9213b79ab0932f2253c8c35621eb6dedbd9c9580f6e6f2edb429da22d871d0c6537708ae608651ca94ecacb8334f09b536a95e111d006b538ca4213af6471363c47b84eb4f322b3e1de43687a6499e7410ec4ab318bbffb0f5be54bc35146bc238eb609603c58bd9fdde5478daa711e2a908746926cee657aed7b0f4855e6f52d4f1170fa3fd31a660f419aa3703836e6a8361c5786b15a304d13d752bac2d549d6ac97256040016f8865eeeff01dade22fabe6fd9b7c8159a0fb5f95d82faa123106bb816b2f281340aafb8f5ca110c845fa2b2d961be94968e313539c941ecfe871358cb8342564b093290c1bcbe06dbdcadafc7dd7b5718bc83e52c92c381bf6d723c4ee5ef448cbf4ce8fe9893743b28ab7d8b1dcb4582ded97571f6a393007556d57290c898a5bae88aa814438d9c408d4571bd6dc0b22df369b390f00b073a409dd71912af70eb954a79f892ba7990e8b9d91d7435ae8b73bab208b48ffbe56d9a7888065e691dfe0d29b1fd7d51c4dfe8ef159e169a5b71352db80665ff01745a1ce4db7256b8a18e7b9f76727234218e58be579e91a33e3d18007709caa1f8aa160021315cda603d6e11b40439fcc5b33eb5082fb9e72584e30ab3f622b05cab84422906c38177bf94198c107fd91875c4a7bd0ad47ce18ff2f3e8bebff3409f5854e2ff579002e13cd7dd2bf502c4d48dd1cc985f5edeae861e19e8da6741e2fd9da849985323c324e6c42f7527d76afbbac9eb88603cbb21b0f04ee6a9f8b61cf0ee7e8421452e62ac038d63997c926f033c1e6eff1d4721d119ad8242d76b5b4aa9eec136f12928a80fa1a8094f8120ccf47f0223e69128deff590af9e47f31ecc7f8553bb01223f5c0c6bde4e26248bd04c017a4a53de4a60ad35288b5d98a58aa17f856337af4ded57de92101cb6dab05bf554fa420ff4e80f9ad486e19bbda482f711450897e51dc8607557298b0d88b8e513f582f2511a8a4287512d2fe49b3fdb0d1c6f0c36d1108d7c9cb11ed8f31dc5ee2b93ea6d4a550f5f657f8324811032b588baa67c36eb703c4b3239ea23dcddd74503dca339282786d5a01bf1473cf5d40efff8505d7288dc0c5fd271307f218a0725d7312a7698650ab29efb281c9e51754eb8be4cd0b03ee816dd09b785080aa729ea65b8c86699756c848125ebcbd06eff90f215cd043c07db2c0259f7e5ff34e8b760823cec5ebee0bec568759f800cf5fd9156c0bc1277406e1c0941ac2c59d59c01caf10c3454cbc8fb9c1e071ebde640a5455da12edc627350da0e3d1b9144e1329c9bc92445bddd483b9acf118f58fe758e51829dd79210a2da216051072166fde6601a62a781fc2f31eb0b16b57b070f06f7890af0e0b9d22b357dca7d432be055b2d1ee287ea280b3607aaef0c898f249811d1420f835f05d0502e18d24fe492c58a826466ccaf134d14e9cceeccce571672d26bdcb254cbbc037aba7789de64b139654332fccb170cffcefa5efd759e1b0eaeffd2fceea35604edeea8a7cb35c84b9ff1d5ca1c5099f4d4350ced9a6163ad9eb0456904df135857d1e3fc1630b203f4fdde510fa9ad5132cc501ca6f8975cdb0cfec7876b7214a4e3c4553be538e039259560967158e39be82066169508cc36f70a5ea7848c3ef84c87ea9f25cb046d0c40697df212f63a428be820e16d101d796817d00147890168c7d2faf38d62f37da9febb7839ca6a85783f3d888ba8eac3085f58ea9c98e5f6838c6320fafc24d5e0e5f0ee39d1c79e90c5407793c0e3c94b8549c330c99ea73f7d611c66e5aea0efb0db60bce0526351548fbae610b09ac342c18bbc1303f4061a1d2359cc354bbe59fe2f17e71f3cae6216937b506a59fecfb8786b47c4703a584bfbfc59b9737dc6cf9b61f26f72c97d9ceb227bba946292cc6496aa03c82855adc20975e076285c34a2420975d3b8f059c116f2ae1f49ee36f34acfa3a1a1c39730ca891863b1eb13c74fed382afae5fb31fe69e90d34292f5919f304afb9b5140c83b0e388eb46b9a2daadd89b2bf58c951fb7f2001ff07340d680ea154b403d5d66fd13423b848ac1d6c2afb4328f4f1d81c0f4fb7f673908ae3fb137e55372e080872cb491526c85f80bb9188d1b59fa310c2b01ec5bfa95ef1e4887964521124c9142f32d020ed1e8be6e1e7f485732a0e1d87fe2f49f0f5639a3caca04649bc8e538881859f28d3fce1404f9bdcd397751c30136538de22f55512a4a70a5fff7dcdfd2df79b8d101883b35dd06d1e106ba975c98f87f973b4e2a73f9f5d9e1543d724adca5c7fc35a329f614e0009904c5921a45c03e16e499ca2edeb35a9232c377eca0f4d257f51f9dd8141acbcab1356376d327805aa18bd32dc4fae239488fff3e861b3b13f7ce0f947b7ce7edf8721a0529be17eeef61525df450a14436d31b3b519bb90da151739d06922e671b6dcb378cbe16f61cee8a28430a6d99d29971d74e682a09a999e4ee60134d2f1eb329fa4180fb4c0b6b291b427279af6b812a082ec83599d53e6d66249679b5fb802d03b88940a37cddfee5cf524faf05ff7926103897741090a8984ced5da1bc42136acbf1ff0d8a60829636fe99ba4f94115ee7c82d61072e2748e2424a5d3b095c00e72a3732c42e0591c42ea3f51eb3f607013df92d74de5fb0a5408f0497c460a1c077a05fbce5f2235b75fb633ce1ff44f8003debb2aaa6bb12d8451a35cff392b81a9b5278f5c67dc184209ca3e27f388da41e7fd8d6a75ac1370bab47c7c5dc74c02a8cd5ba9e5e59290d834740425f6aaaedf9a353cccb5cf96379c147106623f572f2c79095f3ae5c97e9367c2b7ff53c0f1ea09c043230ae66b12feb1a30f741cd902706e54f048d70df42f4836b0d5bfdc9f1dd84ea2095b19a481a14a3714d598774d34781a405314224a42a16cf5df3878a764963ce5ebfd18079dbcc52d7910da85117a03b65ae559d4d7411445e78651d787d5c4447bf0969751974b97a8d6c4522d3509bec0883808689771eff0553cb94dbf863f1e296c0306f15eed24c24b12fc62ee47cff99be00d9f9b43b084ffec2077cf87c06bf5cb8eafa6e24bd592a0bbeb9312e6fa6bf067ff853c032be527939425337f2113d152a757a4bbec875d65c5bbf6b7d6d07176e8f30d33456386bef3c60f920f23a6042c588667c1cd26a6edf04e8fbc8138440ee41c0a38c574f10be16f0701114911817f857c611b96bb93ce8276654d14241ff10a306a32532d1ba8caa3d6caf976a74cfb5dcf03d23b3550ceff71ca0150dea4015d57c4654c2529b9a3032f1a0cc85768b4aa415c6f81352a6fe7d037072ecc3917cac6741f29ee4774b55ba5967a28bd4f2abfd4ec09d332412d49a8e6e93b845d7d680301789aaadd11a97d589eaae17425973691d901b19f1ca7152362ddd5f5ae3433d8d8a5fa90d4f9af762a7e8618c0bdf0c254139dba9be0bbe73484092ef698eca4873b3ae6c1783b66b1428edbdbc36b2e822c02a4082e4d06485462bc4a20ce87abe28eca258b589a31f433b1c2fa49bbf4396c61c5f30b3052e5e8e00fd81d38ebfd31078bb8a0ef9a89708f138eccc77fb2965aca9a32ab69fad6a108236704fe6ad8f2c98adf1322555b1d7342726a72e4e5bb4f2e5e6b7a9dfaa1400cec74d13ddffee68184c7b630a1041eeb8a18f3abc5d2f82d39b005460f9ee03d3e8e1f94890fec3eac03c902ac9e046c24e547ed7fac099428dc66f0e01636b87e9bdabf9ae5ac03f9d89a5fdc9be4abc932b5b24188749689bd4c8c95b86c1571c5c5260315ed91412110ab06284058dc7ee63b27c58031e7c9eead17249be4a8ca903ac7cfb03c6619b1d40695682857e912ca642bf13fae5a481634a012474867ce34b32589ffbe6e195bcec58739bb992880d8e26a321fce7fe650564a5a80164f4ba449408f45c2fcb84b3f82875a5e50e6649c1aa4f7ea4eb13a52e7d1ef6365395bf8eab57788f73df8e2444c3e736546139fa75569547eef3f989467c76be4e7a70b6eec9fa57f6459a97f003b66c0b7e56d200204de9e464c531087a760468ee0369fa26b0184c4132bc2141245c48a594c092883c61507aea559facefd519bf17ef88a35f12fcf05ed1ee99ab5edbe49c3505ead22370fa031d2b870026dac08a0606c1307117f4595936e03c2d85b3788bb6615511f6c6e3af0ccb835a5649b9ccce5c93040ad1e7d80f0c9a80bd93ebedf43fdeb7c7c3d0db0d88810e5ffaeee1948d2a33d7c897f249c324e58ea9aca41acea1f28697f9efd63070e7f80e6a20eff1fa89cc9be649f9dc4717071fe8e2942e13dd69390d6a6f836653627334fa1b83ef11b9ebd0ae959c03465bd4f85818a04968fb6c3b21891d07c6192f895b76aa0c4066cc7b58cff86fe6d124537c5f0f254c07d90e862be88613a2c59b9f1425901027f6db580415e0da1e674d37c3f96491bd3848a4e331a0c8940ed410d0fd58b4c504e5d791a6244a32c130c198086948fe4f55a05946fc4af600e9cdb2343385bdd98fcce38d336ff0faae44a6eb880f5ac47ffc123ddcef4f6c376e1e2e94b53c21f804109a620614adcc0b4d1db2e6cc5b198a3efb67aa5a57097617e98e21bb6f26f9eadf7ff32ab8af5540f701d2427d2d92caabd0999842d730033965c9fe894ec0b3e13d9e1564af7153fe33759ff70dd313d2ffcfe4b546ab234aaed888293bafad63fcadfe13792d83ec12c2ffd77701408e7fb8fde3de645e8924c01330c1b656d9790d0b466bccab2e6e2c185ad498276230296631972a94b1e34c36aaa00b87a2e691bf22d0b6161a194f152514ef832e519c8d0840f3a263766c3d785a41cf662996f654e01ceef84e72cbfb04db34cfe2cf1f716189fc25792e3fc243b38c5bf3ac155cc607ad1f0498fc1ba1fc824d4c0d15509f6b559cdf17df6d846c3bea26d4bf010bd13bdb7b0684d80f5c26914a718e9264d0dc459dd9b2c8ae9ca4be2efe78b75db22615b1eea081844ebd54e671e560a6f69094e85cec86ebd3ac9bf5eec74fbd26a249db038c8910926524deeef9bdea298b7c8f8a4b6670b726cb5a224c2ea2e457674556d0f7a04ecf940926d2128f82e090d0bfabdebf1dfd947ce495de52a6f059336897e8e01c08000a8800487926f565f983d295cd92da6c9faee588334f617b47633de14e5f120119ba8913adeed2a46267adad8eef44c402626537428331bfeda2a9e5bcdbb461010ab28e0f645bad8c95da211c293588ec56bcb724d2fe0a03379638fffed286a3f9a627dc0d0309bc1de35c663f2a272f122332d3dc5f250e0ed3565b837c79b366e8ce146184bc141ed008a63d9ddbabb12a6b19b21890f7e19d6d649db19edaf78e45eda899549ffe3843822f0434ee6a8a9f369bfb4007889ecc96c0cd03572e4cd1369822e75a4c232fc8ab2b9937c8d83e647f5f15ff711f404682454a043f81a2eb3d96bf88f9830ce33d14bb28afdf98e0cd55669aba1c892debdc46c66ff4070179a93b38b096b1f7d945ffc13cd3c434379a7383c974b5d409febf74189f93be06a23fde9814ee34543d5bc24aa6d86cbf48feb4e3a0e4e3156643fd9c93a729fee900b903d1a12292f2e3a262189247c6df141eab39ea69eaa6646e3b60d5a6760f7bd3eda63c179644b4a6662a4d0374b08742bdeddd26451773a11c18a3ef336e71cdccaafa7914ab31d9aa77402231fa5c8ce740ede1fd79522b0084f5e543a10ed5a8cd059d440e1da757d6f7489089147f41af3e09ef6df265f6341888438fb55e58429dc9d9ee98e834a37d1f7648329546b526e038e6af01215c0b12c285d8aa98379ad372cf791ecca2428ce54fc3d51a5789d4da0e6a87bb2d0483b367f4c067b05c7479e963c624e6146222d9c42f496c007cb4fc875150d61b6bf9044b2d74da10dc6413b9ab79be488890b767091fe5b78d504f4eed014559fa9040355d7bf2d17da348c691118a2271c90faf09c1f39c790b6b584bcaeb407d7aad55f650651cd389f3d1bd9f091128532fc9d7d3b32995085341b83ce4b54150b9c21c1d94af15ed359ed0ffe885debbc36407840182666fd34e247a52786f505a8254d1d9eaea3535dc55b0c5180b0a70cd2edf0272c8d92230f4a69e8ee33c2893c82b2db1796815aae1058cfa8be96628ec7c2ac9c91c71d0f65208b5db8a6f4619755a291a08f1582c6656120f2194a6808421616146b9d714e09bd11e4e9ba83bc15a67bc6caf4abc97d1ff0e465c262574d3be13b41ee54349a0cecaeaaf02b111e8a55222dcc4f03d85b1b2568d5388da77e9fba7a6f963df44777a602169196e04b507bc8027ec5b7ed9c47d53e6f2fcfeefb5248dec94e88b8247ec74e13eb1828446d3b45673d3b503bd1af832d5311bd2da2477a8bb4267d13c01d810e9ef9fc099fe42b9e153ed3872b208a9a9ae2bab3199c9da54332eedbf7fa17fb37e32bdd1b1915b84076a4d6fd70e131f2628ed53309409be9ae43d3937880eb03110848dc28b2c26c5a0fb5c8c66403c456a360c84a3f2da47a2156218cc2c29dc8d69f90be83bceb5b9ee1b1cc67490fac8ea896fc5a7d344f4b25b515ba6eb3dc0700b13d48e13da46c4840fb8ecd4c85b0901c8257c7a4c0de62db44c12e8539530b7659cbb7e475edbda8e89533b5d313a2de78b116ab4ade723c2bbb2f0e32d2528128aba98827e1733240cdf882e3825e0860667abec9d8706431bda11e83bb108b6eaab295c5d85a401b48a62bf40ee10ac63f625481c72fe2f614fe2f218d7aa268015d977638ff6724869781d09ce7b5b2a7887bd1fbc0cd3fdfb35f5697d3f94771b1c5315233843f5f83219f9d15ab27cb90e0b1fae5014461484c6f24ea2348cd59f6e480b997267e886240ac3c03154e24deb335b29b001f502efaa9d5286a2d0926534461d4e61ff76060d6fdd747bac793016b6c213a43ac0a8067ed3621c029b1874d847d2222be4fff0752e8c93312a784c8e65211c48e7a10c29a5667540dfc526cc222f8c805cb87a0222da5d705ec73f478c616a0bb4365c3f97dc7f858568293127c4a16b6589117b4086da3ee70649dff0177c1bf4ead279b5535d3923f316cad354b8fa1752f16a0689d550d5c43cc61782f0a916439c2dec7f23c25ffb42f474437500e293645df2beb9c3cd8d22b501debe296ceb2b4d0f08cec3deaf49b214f3ff82f4e1a51ce9c12d6ed9c2b347f1c3a819549e2b8588576a377d98561e100e766848903225b49c6bf01a736f52c38a9c2f005723a6b16a7bd716b2f80a91137189f94b6164eb24dc24623058a622ae2218f6ed901bff3015e09f8e84e3584f9c065fa2a4875e0d4feb8554620ac9b4dc0c0d8bc980ed47f02b50cfa6cc0d974dc7ad3675336f2a1e7bf7c8df158e25fe28a3ea59feb0fb3ebe4db676e38872d83de190b7783a075e537c10961a06df528dfc8a22fd5fcb2064c1ceac93d1482fbd84c20d82718f7545e4e69d5deac4020604b84d8f8e394747412641b33929db84f59719b15497a9c562e6befd9c3a2cbfa9112de6e1e8ed4b980f4ae6162defaca782c2191240365b2c5b3e7e957a7470a264d6012eb974b8b4c439bf424512abfbb5b628d64b1fd06534b9f768ea0eb34587539ffae4128a523a96ae7c570bd7311d62abda2f9135cf3833c188626c11e7a8ec4f799fe3052e0961c0d72a3229c48bfaa1f45e6c88cb34b94e88516e386c281007116616f3515fb2a440969ed04d7783f3cc5194079b5c0c035c61f9836efebfa18247314ddce85fcc84480347a06f9fec7db14b8462b2aa7a81953ec16080c636b2ae26d4e8c93af6d6f9b28c632bb628c3bee9b95ab5d681200c48e517a781aff52f726efe16f3ff81d58601e967428be565a72395c924ed8c21079078a06c80a59e7fd4be72cd3cdba0a8247f759caad323fdc440d07b6cdd84c77e9285d158e9635e63fd2d278d447b7ad4d271d898e011a27a25cad1464249330c39d03fcc3a85dc7c12407b18cc06cd6b244d6cbbe2a9fffdb3c3c75f5d47cb026e7c982aa9c82255b6a09815d3a0ef40020aacfddc6c29eedbd47cafd757ddb538c54df92c8a0939cf5c3d04d3bfa3cc445c48a137e1a298ca01ced7c8c613a4eddf68d20c2ec5b85e63998535ae6c7aa65c41335f336742ba267bef1bb02e923cc704681fd5f40b4c8a769f9fbdc61db0c46b95c599798333864207c6c40d56f89e4d3a5656c1fad6079583ccd4822f5884db8c95ffcd6b252ca60b8c37c612790dcfdb7b7370e43ab7c4032a79c3cf3ac37c5986437d779b29cf635b4a40c7dd817e1aa77e3b2326b9cf6aba6ea11a7f04b70f22369e432f33d802d77176f7b9101fa5294812faea30ad6acfa0179eda1870e2a585248d863df68fc069541775d984403d12a2214df8a8e60ec06562b4724c929014dad8dee3015b060e822971ac214d04a0a76b8e64681ff622e00032ece4e8017e7f267e7fcf8d3309de9ac5bc961993b484f0f1ccf94e8303b824d0014a8ab46806fe0ea8c11d17ce438437387cfe8e4099ea2286bcde7327a7a459dff8296a7c33a33b4827700cba56e61bb61d02ed816ec8876b2f28f24057d3fd6ae0ae59ab40adf6e39e0215f540809ba3b0fd612a57c88329ee795c785b208a238ca4b375baec9f7783301efa289a7fb33a3dfc0107b8d31d87fe02690a2a090a04a636b00cbe38d88f5f5d6c0b8409f55b30516233a75783887ea50f4d4b41334f08f8b341ac7cecbc69e0b55d828d09c2eff5d802ff21d5081d8b1b49dddef268fa8f376f57b13cadfb6cf8ff00188048d38aa2f55c19915d744513ca36bbef8f4d153f567cfd00340a1318a5e9869778b52679463240fcc221d1a8e546b8356e9263b30cd50d2719d334c893c33114c6825829e9d402a98ce858b013d84ac5229610652169b3c7f98410df290f6993209367ee0aa3a72d2024fe299f2beb09aafb7cbcee04c8bac44abeaf19da3757052511d0af4f50fff8157393d81acc0e246e3252ada0e590b8e90da1f1bf6bc45a898cb329f7651b70728e0a462397096771d787c120b506a9c9fab450bed0205336c7ae4be5d29709bc7f532b4f20d0687f6bcfd08d9ba3bf0eab4acbf3f85b2c89fdb002b39d735c8d4d3adad8ce695e1d1075d7c1c094b6bf82e22f88e2ba28a6fe4160c5d2b0f470ebb1705bf30f12e3d7f88b7d52acdfbe08968a08c8f3ec03dd29c007190e39006f8cf2418add94faf354dd638de7f96167806e84cdbbe978ff3011b030ec8caf81c9c9824abe9c6527abb6e300a722911d06b54aea903ff1b6c1fb24dff9f6a0592e47d3aa2694f5011f59d18fe65becab251b294ced6759b36e22f7504526366141db2c36f554015266ade704d215ca8d792885bc9b1307f1530bf797a226c17c2096e94b84d490d0cb6c3589bc5677b826081008bab0489b445dbf623d44b8b212436cab9a19d514fbbe9b8c51a0a7e85059584ad78397ecb16012e600426b2d8acece8ffd620ede3fe8ddcb7b2d1c8c9c5a032a8ad4f99c3d078330bb6543424ec97b3f04e0c8437fa7394b8fcdcbfe0b99dffe955887163332c72f5dbb222f2346e556099a18a21ddb081583e574b3133c91a7bfe3d94c2b8a57a9ffb199c9b24cbef08a0fdb137f4c2bf60039ad86090ac6905afeb8be73427cf72e8d59e727c84dc3dc808c15b9628a450e7580fcb168d0629b85c63e90831e23156b25e98062cb49d08c334f2c6c083bdb67e80d49ef45e81e7aacb0936cef7f70f8e1e1a7670a2789c263fa7332b5ba9003e126d2dee13d08399959ad0d7774b899bc7fd49770cafcc8ab49a77e7c74066610342ec5331804f5b48e44175ba9effa8f6fb402e28d2be2fc533826e8fb47c51cdb41a174427761af1ef3c17c0ed4866681e0d57b5453e9175fb3332a8e60499efccd04bb8670c9c42f5a4070afd72f0dc10b3f6a84186b0ef2dbfa02337096b96a4fe1f6aa4504091ceabdc9ce0f00c58694146e922e90bc6f78ade74353859636a23712628539e746877f9946ddc54c11226319071cac14c701d86a290a55f8c340f81fd8504db0d12267f81eb47d2c6cb82effedb8e3bad0925d36ce99033121e430e0fa96a8992e94d1857e48a3ffbbd3ee8b16d40c1419c32748ba0c677440ee56d41ab65258faf16e32c15ede2dc8fd4c6211314fc006326e9103a1211872976e2ad6f69c1345e336cbb72c7f2dee2921a538283a04a71ae6fcce119752fe032e7555df02d516638458dc23735916d4f706242acfad54d1e685c141144bead79d99ffb48ca5559922c52be72a9566023b358cfd33522cf0b5e21350f739dd3e7e2403cac83dfe49864545460c05563cec7991459acef6b243efe72487dfbb1112f1314ca25466d28e02299020f10eb53c1903027482770db5c58cc50139b38aa14ae682c46ed563084b694b566ab41f8646ee6005fa36cc1474b78f4c0d532df7da0d8248e8dfd2c24f05ba22f60c48e93e93f1c147e59803731329d552f6092beec00d8be90da9467ac8f01c2a6c8471148ae90e742691993c9e626218b14576ff2c1fe9b56beddf6bd98d223e9fba018fba23968840ff2bdd00e17ec7aaa413b03e9f9e3eb7bcd232e82579018d10aba2bd00126d3bfedcd2c9f94afbb2c520b92cc5d88e9e476a1c1751af28fd4a0fcbb1f557afa0eadd124fff15d5baf84ec3cd07cb1dc63090a09c0d37f6a7d870c5f18f177ee2581e0b674f0d3145f9e45e68a805709198b4981fc64258719e060cb9f44f6a5dcb64c11712a63f4b1a7f38c2f9cc73f3979275a550b6bcc8236ba78ee4e594ac1fc1d9e00e1f03b340a7e4ac929c33dbaed1117610f810d0c7f7089cec7eae7c4e93e931b8ca66578d020f0fc2c7d7d576db0e7137bff16f7b7ff0b0812e6f0080fa2f5729d5c3ec5fea22348e718c04bcd39d795900e083984b3203d790f46f62aa7ccbbc23e3c71980dcd539da9ad924acec3cfe929ca83a2366d54cce7e45c4f28906c13e283421231a9cae2580112daff7a9f61a2a32e8293a63bae5b19abda9dcc7c2f5c79fcc4e80bc73c4317b33fbb8a717a7598429422424dede7bdc5128bd759960fc81cc1e8936ac31a1148cb0ac8c39cca81559d7b7197cd59ae642bdeab1ba2a6bddd43ecdc6392d61d093fc83dac95c446d1c7902648335368ae3bf221893c9b5846863a3c63985dd1b6ac9a9b3046d2f8a968b2c8c7ac404f90260d83a9a65aa18226d4e668b88ebabf52edf9e34845238ed7e4204523d217c7c9f1e1f46c3357170de07c47f1c26b7828610378d60c6b89764122dff6790ac09c85ae22ce77a033fc6326e03b6e7d354cb4b160a6c1282242a1c0a357bd21f4237f198eabfc9e0d90e075b9cb75a125f2f8212fc347bdb1dd40e88b7438757d3294a34f067797179b3f7a6609be60c4447ce86a6a2f884e05c31da23a12c45b26c7b5e6058959e53c5cc7a13752f484192ae949adadce017a25f2bf50a3834389a061de414ad72e9094bd7a7f4597cd4a4b8b9e14bd65bf37ea8c5564aea08f11023453dc8f69eac247570f7e3af255d71aca1173be18360ac8d8a049ee7f21f0f3e535feb5d40a64dfca49c509f5e9a9ed29db7013713f46df2606cb2fc10fc15af4a3140edc483429647a5cb716ac91941960a0a39a3fcc036403eb86d54bee831623c0526cb15e152bf9c397f74e4904f9edb87fab24ffe1f977bccff483308703380aae8af451b7a8fd8770976515422606e22bb262f35d7b7ed575635ab61cbe8c2a006512c76a3815ac55f2f889fbcf6c953f6b2660216a92e3b6acabca26bf5c024161e49007e26cee487e833e3f2654f7857200be0892b0743c8ac3431ce75affbe8f2208b9ddc5e87b0882b7fdea60e111ac0bec4b7f3d46ce0f8ef810c70feefc67e5896f5dfbef5d9d0ef5d0451caef644ffa423a787ea3b8552ed5a58a879ac8d35a24562ba5a3502a62bb6e2081d2961ef69d2d8f480f3ead4bdb5d50fef7d03b7a089f7e1f313fe2b6a558860e1067007d225ae1b4ddf2d334e7225656105c7d41e1d631d29b2ddaff104a64d2ae2150e0fca922a09d360fe6fa469ebf45e35ee7270bbb82748becee3da929e16f38e1204172d6dc54d389d7ae72dc4075a559a39b885f221d8a158526e2e51a658280d2d096ca6f02e6069ead9abed5b5005fb6358724bd352877083c067a367837fa859f8bed2c7b60498c073ee9537c25933e9c35da692cb81e8a401a8f2c3f74b12c25cfe39fe0bcdd7e3ad77ae8608d0354c0567adcb9853964fbf6565015402ebc837065aa63650452e17a5a8abe934bcd842841d24417885ee42bce43d9f5b1ee1ffeeff2120200ddbd541a221ee3218811a99703fd60b89356b07a1ad4f8eea1dbd521e337ba8f81b81cab548f3885bbf13b87eb6f5caf3af63f566ea76f02b7ff593d0615297534db3d004e165a5cb328e1557c7f731905e515376617890ffcfa114a14f4167139c49a3682d21cb473f58b44e99c75bd41518811bb1d7192b682e3e994bdd24e0390f047d6b998fe5a9be347639641dbf0e0a8377375b7db6c46d3b062659eb5750731250d3eae632a3a01bb41fcb477fe4f6c83daed5aeff8cfa14ee24c55f28b4c3a060fa2e8f4cf515eeebc05c52490d7c9e6e84f4672d805027731b447928117e782914b606765fc99ca8b8ff9936299e2bb71e42225c295c06eb0582e441e6905597d42df877ce709f53f8becb6e91bc27448f332e679b4d78312395667136ea9143bfed3f1dff85b5be6fa3ad27e48656cba54f21634a2cdb6b683ddebd3636214e7a6fa82d26d2dd4a017552bc39288454779b2cc9b0ec74ce9d3f011f5d90663e701fcf336c6ebb6eaa4333a4200e8adfbf97bb906dd535049c2950a15d0321afb18d4a5eb51d76dbf9689ea63a900d4932da07603c1ce39fb7a7f559a98683cc454b9c6ef65c437cf73e38fd52f352ba33341bd00e8bf734870bb0b00f2c2b740c93c36fab4217f04ea6fbe17158f4a3a5f395d5af8d5e9233e6f2f5776a09fc4b7909eccf9efc626b90b841c56f4cf9ccb5d1b1e1041b7d0d3d3bdc93c494fab3b1e7972f4a9bd8252efdc767f614faa524d72f0b044f19f187162e2d82291c4cf8293992b4184e3a1ba8dc6928b3dc93cbaea51d14871984c92915c9aaf0c912b2a45a3f2450f7e235d947484ccb94b68084b78acd4292ad14f522e443bf89c2fbc677ddbe760adadeb8122e6308491e7e71b037e7263072a3a5b7a891f88c5019e12be8d51be19b67cee5dbbcb596e26dc49645ebfea717680e7e4c1d2067b908d6a37f540bc2484030d257aa37fc49eba8c317d27aed4af2e33352e6a3351685b0ae6ca21917f813105128aeb5fba86bdec716ea182461461cb749f02e464bb058f9e483fab2b15a0f568a0bf8af8d44abca5792b5c3175d7f9f341c3f1da3651028c0f15d94b5873da05fb454fd0dafd00bee03f605650265c8c927c8efbed1c12edd4f48f09865395b95ae0ea7d154f4648a375f114a4759209838fe2210794f6575bcd4195bd06457c90eb1386887e2c83e45871ef7675bbd38b44551479d858da309838dbf86e64bb8ae1c9bb01427fc7825212e5a5f0419097e1ecd0acca2e7e6fbd99b38e91f249c4f7b6a21a78664f606d896c0ece8de5f56a04960536f0800c14617cc4e2587df20ec87ca8b2d44cfc81434aac8601d6ce65324346bd061d1de022dcfa63282876e651b46ae37ffaa50e26fa8887e671a77477f12d2a69443127f74eabb41b17d150464487e496f7502e16ea3bbf8e9f8d9325c10e35213a6c4248b6d47a4c592e747e3e86d21881984d7467e9cde7f42252b2e28477eced0f023aab6108c15a43c50faaf1fed5f9d8327a3d10e28ec47153b0a707850f05ce1301b9ebd01c7528b2db851dc5e886f852ec7ebb611953747fb5b96c9da85ca1361ae6077f3a888d68ad198eb05389aca005c78492e55bf02cd07d95fd7336dd209d23b08338c5319f00f03caf56992894745c2d36a6aaecfb10422c16e66ee12b936b5d290f6b3a337d9aebd1fc258dfc33629a864f3d9e6fafd4f8d71a819c7737baf57386e17966580748758bd2ef353d780dbc4df2c5bc83b2972399fce8039683c408065d07013a6322dfdeeff94f15cfcb4cd9df8fd80699152b577a05893df662ac96dcb23f904ca85b12bd33986fc1a038fff2ae668db154acc2af33a95534d8fb10b3cbf863e2333124321663e550e64b80793d172f93104f583affb9ad3939bae0093a45fe409c0d18d938ef096ff6ee6857a99f968683149e76bb0ebee53234d4c9ba78b463da9c4dcaf16c5545b8b6af2de76d8bf584b76de02d2443d2b97ce793ea3a75301848b54a2e56223c6690852996f7b21b288543bb35ce2f319b4558830b53fbb026e120e82e27bcec15e2586691ba49a25e51baa372e2f4a0bd41ea0f0a2fb0f641dda07cf9a01d69dd00054d2acb57b4ef17a328a82fb1501e99a73e01a77defe21ecdab4a3e393b432d3e75cce7ab3949c2774b6da7ae7fea7416d84403052ba985ea6c1b6bcfb600f1963c53aca9b0da319f3cec8e788fc688a983264f041452830b3ba40bdcb4639564f5832c11993c31604c475b8f088929301d7ef526b1e84d65536c3c34a2a1bf2b8b5ff0c1f8b3caf22f3b9232029d685d412ad5b64e680f9ab17c218407dd7fe8fcace9af143dec2b1cda1fb0de01fb6ffe200e87d08ba603a512ca483e2d229a0a5acc863f70c0b36fb033163448de18ad134c503cb577b53ac06a57065c4a43b2d59c4e605b63693ed85417b0a1f430de49e2cf6f3671e9c0c770186b517808f7e89261c2216c6bc739e4d2f3da5603d42bad7435bbf570c5352fde6ef76160e9b7aa632a3bc2550ef1eb369fadff4732e56b207f1005443af86fd4282af09e8c361d27f56f8fb51782e865c9e07ef298f53232b443233e359b7ab9ea93a379c4769e4fc4a7e3c1e51fb63e76bfb31237f6a4257957552e7ec2bda6b55913024a7b39049c9074228182793c31968f75153c739fb7f71f1cb8b79c202e06ff02e5a05d57b8b12d5792c084213d6425e510d5d6a4d5c1f34c2a04b2293a53460b65338e2f2d08e585ada438116f77399c1359575def552c0015a6ff6340b57e26d299419877590bdacbd11ac529f5c871c92f5c24ae0e0515d6dde5e225c2f3386aa9c1526c06aedccc21516efd936b1fd31758d8dd94d52d9e97d8f98340f0a61bd029622d4b3b859285d8e5985ddd91044428b9fb78c8ce547d20a550d24bd6225933814c22bf2dd9edb6c5ff5c77eebef40eccd97e5379f50d86856072abefc149d5b03ac079cc8bb4a16a17c9e9ef1ac1d54bf2b5d9da081aa63b7ee2cb67c7f4689995aedf197aae90d748966c066e2018544d02e58dfaab211dbe3f90b634c29bbfb9215d036f8609717fb5f97edf6f1085d70d3cb4790333e4d915983ce8aaaee799fd61847b193526e7d1ac39c6ec07e27e938ff1d4387a7ad6d822ca910a4d4502459ef6def0b3e9e94864c36433e050c7a5aaab6a8cf2fc41d55ca7efd26a6a3f1d8685425f5d6a76738b68053b714ca9a406129b495565e24e4122d49beee7a0fa413e736a25c94e420209d439770f11478dfe03adb99324b79aff72325e3112337240a097ba21bb43974f842d9872c754042752e82cc6463bf9857e6b57a49b5ba9b6c22e2cf77e25485e106d960752a0d33fb7c3b490bf38c8f7cf6dc2a71dcf05cec1dbd722422ba7a59b34b700a942c6eeeffa6a239f88cc98ff574e99042eda501383a0366c59b4ffde880edba0a5553a6650bc1b6d9a20bd6e459d52f4a867983368ae2c606bbceeee9c3ff6933a270fbaf1185ef5def747e2512db01bbefbe102a3c57d2aac0a2ec8fa704d8eedaf58f1a4f9e075c6418b8de54836167158227553cce3bec58de3192b65665aaa4d9d9d4fb60ec1f2e4231d805feda6e82a54b419edd1759cfbdcc820e413a5aad032269d38f22c4081443b2262cf6106a95df42874db6c2cafd439fb494b0ca345eef4d56f14ff148c83ce2fa49f5ca244782e9673142ca76a98677d64f834ea791342e709a5d37b9121c64334f159c1ccfd20403992075e23523748b4a4c00b1e64b0f176a135243604a996222a79ffc10b792450e39a887d395f416929f5fc3073d4bdf26027d3920c0144f0a0a58152685a1de33799d3cb73bb44a8ce6b57dc21a8fb5c4f81cbcd471fd2f50c6776cb332e94bd8a688751d335d8e7ef55de903f99929698f204dfa6c828bf0471cbb8a020d7dd00f9e53bfaa12d10d43911b7c3d59c089b3ed8018639b4468bbbfaca055cf16db24daac51b8d75400041343752e8af0b7192fab307848106a6ce36fcdcb59af7083d7a7f0426756847e07c15c5facc2332029282ce3cce06357b200e47212ad4c595f03c9ca1812239e6780abf73a09e14ab40930a7b192ab19c55cb55d25f3f76b21d7aa73c5e58b752cbc7768c710ca756d3209a8ff3d1f196fb2e9681a9cca4794f5bda8f5ea41962096f2a1ab8d4e0022a411de0a3d29bac7b6e1f850b08ac96fc0b828ad8e9f44c9083269ac8760b1fc61b9af8c078434d1db98fd2b31f599f84ecf43ae220e2fd8c6fa08ec201a91450610e4035a64e0bc385647f4473ca1595d6183a68ba163d3ff2e4d23b74c110c7281d0b1283e927168a3fa8a63c43f44a1c1dc4edb87f5af8fdcafffcaf80ec11a94f0134e536dbc0a5ea455488dc5e51092ede0f142f1afa9e8f8a3a1659d3a768d54575d4d9f474bf6bb72869ab7dc185d1714df87e1ba919f505dabcd79790256515d7a300124fef372795b79e5c409f09d11820ea6e7548abfe5de90dc7abb9434f2bbcc1a195402138f14c119e659d6294716ff6190daef80ca99484fd95724cf8ba184cdd47679c2509e11c6fdc286537c8d65511b4d0be608a52f10a02392f617210637a7fb7b87886476851350c38d6b029ad7a0d567f98c6b4a05fcd8ba8ef76f39de4e74bbb6642c89c18c01fdbf33a3f59f0cc9022db85460bcf77de9d4d43afddfc0379d860be289c2501f1ba6b1d527f0714b6c6a710cd6527ff6c6afa9a80faf368152c579c5415439ad7d6c143a6b55c388ddbde53d6a48af542e02a9282b14ac32c16a3a9cdda3bd18dda6401aaf993c0df540296540af03c435fcaf0618267f29d75eaddb61c72e352670a2847745228ee6c9355c9b78dfaaa79c15adcc043c01452945ae57a3c7725d011f71c5303e61631ce802c8e3097e1141540879b24f716df8d6d326ee1c14799505d3172254955480d8cfc45f2d2fe830d9319b6ffcb449f239369f65025949292a43b7d3546fdd0c81bc42d58ea063a42cfb10f1fffc1ea3b74d43e8a57b8b1459310937bbebcad5caeadada80dd53424cad7966db5389f0b32442d0cbd440f0ff1a7e043cc36b9e92bee44c18acd5e5b86901b7a546db6b1f07f111ddce4dd0efb4180fd0e1f29c37c2daf5ce4a3eda5b51a095d05311bf68a775e84746936a07189d168367792f6f05666b9c0715bc91efd6ca4e5d17479cc433cb1d6cb2953821a2be402347d23f41da8473136008bc46d0dd14ff0d210bfb5d7491f4bfe2fd663a67aaf49df76c256ed6d8883eff7817945902894d8a9c7fd999cca11a0a1fee4d2c84ffb89a7abeec65039a8e7f2afbdf25702db0b026437d680ef8e08368b9464c256c46d23d589ceaf940a08e138c5ca454edc443c93fc892b9bcec7f74a7745fde8676368b1cf525b71a3e10762cd476b20258cbde6bb04a65017d3700b897814e0421f5004c912474d547585d0bf6abb7d415c635837ce813c501ff4b722aa37c1d7dc7122a1ea4492cf380e76f325562826d70b540556e71d10840dd19b8f026a3fdd770ae7e519def73a9da84882f065394ad9163e41019ccac17776247622559a0ca3e7bc1a2ad76260e2b8bdc1532b01edf765ec340dc7f444dfdca69773eabda078bef40b4c3902fddbd6f680cec9562eba56a15adad5901a7a717a3ba01bb04c826ac837d24899e5733c15e7bdcd22dc789650cf7b882451ac593938cfe9d3ec056b78cbdefe6a074143618620c677585ffe415d0cc885e4da85723b137bee3d423e8dd01f7c7d427026f378f101a2c8cade27d6c936f85892c148e2833ddca99e879d4495c421112ef0584b4bd4dc7ee53986b81bc697e9ebbcf29475c4ebf62c17c89a7088aa83ba7150abc840440eab6496f8202eba20843ffaa3abde38adf842162e53c5cc514df47cc7879742765469972ccf3ede7a7d0f3e44f1176a39c61ecebe90dcd47796913811717516451bd4e51465cc9b7dd2a6abdb5d40a6333714e49cfda0f24dc510697c78c7c934e84d76b1495dd2b09d77a4e9b9e40ef0cfe19b047e7d90ba00daaeba07436bc3b97b124ac536e27459812006b1bdf08b7c4145d837902acab15674da0e0852854c747fbfa695c3e22f0e20c95e250e8b88a8f97ea7405d42491923ffdf7c96a7cfee5040daf4863475b9f2aee635cb493ff6ea7ee87b35b9dcbedf6e95e5950c5353080a8b8703dc99e128c6192293c3dd1f7277c2b7abb3c7ab3fa1e49a35a570ed2bbf65925e48f99f702b91477aeb16330dd4f4845dfadc9d913fdd8f0f41d5e825086dd8d3f2c586ff319c04b98f5e7e9cbd17854fd4a09f6cfd4c9ae2ee048b780aaf2906b880dad9a4608fcd37d73509d2839596671634b5354012fdd27f61221ba31a0e61ec05bdcd7ddf24276d04a444b9a5452cfed8e57fff53ba52fa028e5f3ee5f54626ce563c748d49286cdc8ae22dfb6d78ffa403034a9de83c1f5a31de56ca78f01046517baf7ae402136b56b5ffbb4126066478810fa8157666f0fb48f3efc00ddd205aff6ee45068982c00b0e36b10b133444abe4e204f1ca5912df5a2e617b42eed613d90d89a84b11fbfd151fbfedf94de1449b5cadb7c1e3964dbd30328e074585a402a0da4a5109335ee03161c6ab7a6ac32a92d8f0d2304badf9dbe6167e24b14adf362e19fcc5dcae2b4e24275115efcd5baf35626fccd30fa9c0b42c561cdf965b291362673fd990efec58af9139c5926a046a33023e0e31748a3dd31d0a803c112258ae85750095bd1a7bdf48300e93a4c3a39445698688550a6c1d8e6464b24d09bb93d163b525a8f8fc16f149d81346cf07aceaf5c4c87a27e87bfb8f57e60b6415a07328bbf589afc4a75abbca41d20d8e77dddf550506cf2ed3c12477f398379b89f6adc3e2041a6cb729f9a1d4507e619f3e8efdb56852c5b4d7d243d99312121ba6ce90f76f1d6fd2c0b87a1c19be4c76d8a7024874f39b17a00df2bcb6851527192a46899e3a45a03fd540462648e135cd52d19e97955e87df1df38fd06a1722304cc7ea24017043b67197b5a50d58e06927c7d4e5d167c65351382419a5e3080364cd40b21ee90fb0aa7cbd6bad46b5f1109e6ed499909d99e1fa220ab5fffd1804b9c8204ffa34f943383f98838fc7407fa811e7b6a2be44d7b38b99bb2b57b82baf4d91cd037df0c678021a07267d050da231d603e00aa09adb3017119f412e137831145be3bedfcca19bef608e506e118e6606139209f12a8df6d3088a9b4ddf0da6713342765fce7ecd2fc33415b403a98233519163d90ad12a836843641b62e110ac7f4cdd95dcbe5f97c9332f6d736e96398d17970a06412f8f543f2422b086eb3da5b7ff1f3a1ad6fe0680f0534db7bd7fc8850eb3219dd55530002d519e195c00052858cdddf9f590886c374ea340a7f9ed172fd001bc4ad9ed35729f2e3d391bc331d88d25b81d5baf7733ffe8449ed90a37d84b07138f9fefb5e709dad8dcd2f796323bc27fc008b702117c91317282932eb71d95ed6b28d75aad5a037e0d74588c1cf10af3fa5d59d8f6abacfd3bbc51f269f282fe95a7c0a5074f651387ba510acec422eecfde6db424ecdcb7d7be86ecdfc6c1ebb10658d80a2dfcfdfe9c5fc708f4945f0a7b832dd7ba083e5b893b7a25de95b1b976f6a1a83a9369b3f280f54433ed7dce9ea3c87dfb403d4134087d34a66c7f505a661db37fd0ed7e586fc2fcac9c63f878a761a4c5a2e5cb390eb7af3a78ff3eaf07c740608d9a5632b7d40b23beb8680b2613119d73d9026b35a793feb9ec6e82a338430cf58699bcb10f69c4c74cdd2a54a0837a54e18b861086aef03051a51a565780c682c7d8f5d16537d4bfa74e73d1c9994d6ac07b572a9c4dd314072ab4a1923116cddadee57704b5a024be40c8f08f6e5446c0dff03b2b1cbcc246564d502a1b01d58933600e4d18b260c3d1ce8884f345a7d3e6f95d237afd199c4ce60b98ed0f1223110935bd1470e48b6dcb74190930f1df8da498ce2f877d4f139f290bf6c399db1807cb9fe6b9c3c1b1f6f63817b34b0c815f4c686bdaf6ff993c283136b4975df4caaeec0b0e3a2330e6d584910d865db2167b338d70293f2f6aaf0d4f6418fc49342e71c6577e986a7a44cbc2fd1c613ee64f9b119d7f42220f08eac76ed9b1b0a45a113e4700d9be34417aeec80dddf35f3266a82da09c9e974b703bdca625244df6f8dec0d5f364337ccd6d0bd4815af42c88c5c9dd90f5b1513652c67b08f04e55cd3240d9a8b1a44910992099a09c694eb934cf181f3cd3848903c17e1a0f241505775122e4682904fa2b086fb4cfb24a6a4c7d50933b0e58e62e6cab7bce6f54ba413e77c501f8ae6e2930b1942f098cf4aee788d0fe3d22f0f083c4c11129162018748423a173d1362ba87ad00205ce43dd97ee7712733eb4573341982be36ed1ec56557426e1a356088fd5e10356c99715c2bb76e6fb5b85cb7b762849f5cefdf4554bc765466c50414a66ea3a75ec607346f0dce5d1d7f41659f866d559e46a4f6f96244a4fb7723e590c49555996824a1acd4fdc7c6ffdf4deba66387b6bcaacf2ea1130aa57ad95226658a2ddbf28c80e2744fe69b80d2f96d75fe19e04ead92061bd46dde558c6b2c46d7fc244e8fac4ecc213c0cca9ef5609cbef4722c2ba0ade779bff2b7cebb7aac6ea2c82d289420961c53ea75a4a8a2164d7fe5df4d63d8fbbe26e22ae3cbedb898ce42b4e95cb75bb116deb69ceece5d2ebc2add8dd1d536a0bbecab77c43002da4e1fcbc141ede821a01525b00c4ecc5b1bd2b855c2301acb880e6c3d3f863893f65ea7ad0f6df3a0c306556ea1e94dfa93a5ad1cf2198ef16bcd7ae0ea84384994de8156870b2038b1bfc46b82fa174886f54b4ea3e292fcdd50597c17171517337cf02f535976e60fea71577c5a5cce4bec532270f2d24d0d2e426c25d3efd0a654f272c0b9988d83d5e8afa519631d77da42c20443d08b5c19e444180aec6a19228db9db9d671852420b4d9504432d0dec65c95784bbe7889807e06efab514d5e8bccacdf820375e8fd03a38b5dfc37b4318009bc3ddf5b1c2ab04501b6e3b3c487edfeb6196dab28cd0ed855f479c6c0e84a8f30cb643f7b2308e9d320ca9bf2d97943648a59db7c9c942ff2f7a6e63d81a2fe41352c9471ecc6930ab979fa5e1f1a46dc44307f8919752143512066dd3503d1bc6ea745e6426b6eafe78d0028f82ea707c2db8215710c5e9da4c1d5bd79159e3fb63f3b3ff500c10f2661626b8fdee672d4943ff90fe2bc03f0964dd335c5821ebc10b0fbd8454d2a95176e12797bc66d733f0928e2b01e52fbea4755a7f65d74a237dfd2ecf98f26981a0b774b3e66864358631cfd7ae1c1b34221f0b38f2bdef110be5f78773db023e768a02b796387ce80d3e2e116581bf0b6e525dc9e86dab8fbdb1b1dfac33fd5f1dfe966223b3a441c3f5f26fb97ff2594a3f0890cd6c341696dee94ab3d4927752f10c715bd0ac302f1ac2f0c6d82fcf1049e52f906094636c6be3cf086052ee02f167cfd8a848647188235f9deb15b503c46aaaf67253c70b950b962ee0d3b983e8a7e06433cce61d648be24dd86126e0bc5e915bcca280ef44bb5f2c445c00b141a46e207ebfd8ab2892e9f21dba4d1ac4903f77e233fef1fc1e0fa82496f70089a843bd9767829c70c72eaa99eabbe02c29356924eeb81b4ba3e7db740d69e86c13e273d74f9a50de299e470d2cfa82ed2ea9062929ac48aba77335861e8cfd52b62534313b94b2980a0015f9b79e4262f4fa2f83cc3d2e379fe230c0ea9adf26de40c9edd099fb73bbd6740057f3fb650279016081d6ebc8f0351e9bfe6879bcb4868f2b80f1abe08f48cf529a6ffcb39d78a718c3f722537bc50be232078a2f9cef9e6a3c5b6841e992ab3f92e14b605e27a8439ddc1f67feeba1c75ad68eae1a126ef119e4fe2bdc44859ecada517c92f8ad15a1c94ef77f9deda11acb56829329b5166b9f8a808601da5a213dfd69ea22bcf14ea21e56bb66e0f558c57482f3ab408d1a6b14e9edb29285b011d48db2ce12ceeb9c117101eb91a46ec1fc08fda2e02622e850033579052ec6225bfe1e0ff7a0e1da6f04ccedcd2d9242bef8d3a41c480a8eb91be078e03a750d83e8f83c38efe0fb04cbcacff1d8788c087128ba1cdf01602c4f0570eba58fa1c3323b5d1b69ce24df4f91ff614e42b747b4bbc9bacb822e89a4b798b0805ddfec61a47983ae917e5381c69c8394e5c9bccc64bc81d899fb81f28afe7ab9eb3ce5a0d03c01418c60a3f86bae498a1c0b7add46505c0da40285f13358f8f295a5123dd4b4b259d4baa23538824a86062245c5dee1b9238a99bb5bbb79bbbb7d59fe62d856d433c5bf4c99b37693771fa057a03e66b22d2b03f967a044f630f33dd687fa3cde26ee3aa1568e6a4689be8430e48b5538ed69fa3b20dd17539720f6f4a73c19a8b438617997acbf20226886200a40cca5e450b78785781b465d24e768d66fb6574b6c02d32aa479d78341686a5b7268f45407a03a36525c06690112100ad160bd311d99c11225802a6ecc75606f7f9e560f8f8edc1b9737aa54899d72e3021f9c138782fe81315fe5f8db441445e2b96f62c77e0e1d863a5577bb6104209ec88fb6b7dea4a48edf9bd1db632ce5ff50e9ee498f1ff7e3f6ce3976598866aef355c51170a46adafa95e7b8d7caba297d12995a24e804fccbf2c89be610ca9b59614ade3f1dec713b8a776ec2f03641f8f154c38cc083d22442e683fbeaeff570a9292583911e13798ad7e329a18f0134a89c71b5b10e033fcd76c2ff6285c40ba97a03fee1bfde555e9812a2a01f0418f70c3f9a64f83d608d00a9d72df0ed0903bac452c28001fd9ad5ebbfb7c5f91c90661b83937eeedad46ec940ad24a28149edff8c82506b9eeac7da32e53c75ac4ee71eadcba131cb5251e2c0567760805356b9c9b01ffaedaa2deca2ceceff54b5f81df63bf2234ae0d34b0fc2b9effe533b7c45b18f1e2a38fcf20e08cd547c8e53430ec3938f3fbfd74f37c023cc767d94d19e4e446fdfbecd6b7c1f0c0612918616ef9000f9128c415542979673465a7a56b688b8ae356988c430e0749abdbf4fb9f0491fa18d02df70503f21bcb614d6ee53fcc87aff29ef66830210c3c9f7212ca515cee2b51d71d135c19411d0f6225890f5b00a78078207a914e900436ad9a4751f2584b0c5e4008342dbf30c2efba4dd634276b84a19f421383caefdb1532e35f754e06f3daf027712e86147aab5469240423f559ea3e9140612f0910f132e37ec87993c6d7bae99497518bfad8867611f5607df7a421a1a934669969a520cc6c1b06ed07571b1666e6f32be8caadd67736c9df5f037bee23f53ca32a5db18d315c8f0bed3728b0a0cd0ca5694081498a494adbc3b52b164e0d60d7645d79106fc75811b44dad2a55efd5e47a6c1b89465cc4e8de44cf5ec141c79aeed63d29e200c5726656509b870dd614506fe9f37edcce1257d2f22a0ef650444d0f73e62b4ef75a455513228bdc0a54203058e646d46c82b7e23fdafade17b278173811831f3729acd7267d3b46ac496ae12f2b3ad663bba042f5c0872aad4fb80a158c86edff7b0c9a678146b083cf3ec8540459aa167c15820ed9a1b31d9cb54e74373d8e38aea365d4992ecf7bcbfbefbdcf4852df832a3d81dd0c53f50c4303f6f7daca19a46e6a623a4a4878224c8cb9754205557e03246933b89d4aac08a2d05475bf1de4aea219ffe41740b5e5b0aacdc88e14f8b312cdbad0b84936f0cd994974cd6433673b30f90eb2aa5e57f0a7850bcfcffc68df7820763c89c4c520b9c731d22ba79af3603d84081c06f00521746db73fe87d2ab2fcc68b8ab23318d3cd01fa50db52839ce4f04d3b2ec27730aff99d01abc6455c8d8fd59bf2288bc1264833061e8d420cea51a5a7bb805c85b5c0d6997e17e4e8bf709274b8712c7e16d7e95979e6446684d195f2158a74049c5ea545f111c912492aac08b19c4f05b0175ffffb1e2807a9d4c95e1f3931ac7821e163f91122aedb366628a3c45f709af2b2675d200e623e6692b0545e9634421570813f88eeb8d5ef5388f2de18403c5e8f419e42a45e6db9a76cb640c2887a0e5efb5e946912e70bd8492458e4ae4816a73753395aa639cbb72e85a067875283f64385a13c9a04c98d14a651596f85f874288b114bbe2d8b75d63eef7656fa3c0a1b43c5660436d124b411449c4f7af4c879c3e7a56e0f05768097568c9157228c8078ac2dc2e0ea74dc0f840ed289c722cc65645135af5780c2b4c3aaf8d92985bc882983c94bee7c895c6b8afab61b62ab9ce30668a8ec612a1f87d7e42185d36511ea566403bc155960e516521b19b1a0dd5efdd35e43038d41844102d7657f9c838013ce9c305911b7df1194c81459e7126b17a867e7e2936eab6dd423fef3af94137938539ff5528af478837a0c1dcbf086ffdd91a52b4db7c3db166dcd51cdcf6c4bcf010215ecbfc7d34e902dede3726fc9ec4b8ec15bc494fab2149f24b02293ac0720a043ac88922d1438c4b3533f5a0093fe880f8654b8b0ca3690b91528bfb84f34734a06847a57fe04d322c28fb89ea05ca8eefbfba97c5881805f04ad8f19c6987336fb9da3be0233bea211522123deaf8508c7f8f77047bec5166c5d13e7a61590b1feabb7bff0cad4048ec5bc329b4b283ca8dbc4a2734fc6a33d35e6db681f36219d30455eeca2750e863f0b13c7804840976b10cd14a54c61a58251717389e44cd0b87ba96a1a250c6c8b79dfc876087736468a468db150937bc171a5920b13a5956f18eca72b7b42cebb2d1511cce134072ebc0f209bcc9bfb1b6f723fee505eb5c44d7b471f423a6d02d1b214366c3fd877da96ff2964fc44d4b0bbce828026cccb2e2564881b7cd4de295e0a32d85464077dc47f24808ade7ea2fbb75176d52ab8ff4af07abadfa875f4ed1b1392861c941b6ec761ad04a8c623e04258c1045a6e51434ac4757fab679a71685e3c107f4201062c1f7575d246ec24bc7f019f69d46a4046ee14a65fa2caec786ac15c356dff68d8be6228701d5b661af3aba0e8e8f029795d799d01bae0c02fed756567e2ecdde66f1ecb5590d060769876295e3693d0d48f6d51d33ed9620caae7abbb2c7928861723b7b18ae1d11eba30cf2f651fae40fabc985cf5e873c7b1e942c95aaec5c5ab9f571a232edbac22d4ca900915024c030c424d16e97a87b4a96fe4f82dd9f434aceb80cdaa73d6df86a65aac59b302b0accaf1fda346508707feb84035c42955ba900b951a66a459cf2311bd3898f0c1521336905b50f03000a157015281da5b63e2e85b92b587b7d12cb99940077200024ab0f29b585fdc50f9454a17dceea255d7af5c0e6b8d08c3818d6f4aca75734b114db86b3f7c2a0428d892ee2e08cdcca672de62bb7f989ec2345e26f74843bf1a1792c07ed4718525c011c904e0ac0e29962e3d4e9a3cf83bd9acf7b0cf0483008a8b5a0da36bab2cc16e41a098055bf471eda1aea2dbff272d746667b171661416ec80098f5a32bbae6227b6311366ab2ca18249a0204b03377a2e233a124f112a32af1cf76d349836e7f1030cdc83b8a95fd1570a6f198ef78f5a0c17c1c7bde99daa7f1a37a49c0c7c2fb011888dcaf4a869ee231675225b11323bdb640b571d7f849580a0f63d5222cd81d90a4b2742a211eba905eb3f5b5c753e7faec0ca7e4f666c5c116efd19d443f21c4cbd143538673f1c0f0c0da9641686247459a8ffb342df608da9c677e2c865aa756255cefb4fea90eca8d8b711096d02ec6cbd3fea14af8b36118d9485bc3a70e4ac6eeb13d559959bf1824623eedc56fd5cf47077b4f0e97131def6e125d24f74176f433e2adc6670768fd44133353cffbaf3dde0baba5e45abafe20a04946fa678fda79f48baffeca9dbebb2d7b8959c9e877ee7eaa1957c9aa08157b209f39fabce8ffa7244a99259926e3afd29d3490fab5bbe6bd68e8f35fbcafd25e658b77810f25a21e6d71825899a9f8fb6189fbaf76f64f2ecd331e3fb8b87974f4747df0b1366eaadde5ec11697c96cc383f9fa422cc8e94499be72c14b3fcdef5f45b7eb1a154eb4aa6ff5e7140750efde6839de6279710f7ccfef5ff6fb9a5ecc2023a90d079fdecfdf0610c186bb6700d372c50bbf41d26446810fca0c4f1a8cf856d16062193bd9f41265efc5511b8aebd389f83ea63cae2792dd857904e7a48a855e1969136136c0668e26f42505be2c201c9ece62b8f98df43190dec11a49deebbe0218ebc5b25ff6630528c8e9ac2aca1b9c333310d274a3b6d5ace8c2b9746dd870c50b4ce0a61944566c2f58508e4d1df4f8716d4a75322d67fa5d3ae3e97f0b1f0c114d37a1b404d8e032510ebb27adec72e3b386f436a0f75ac176ed459d16703bb88cc8bd5eb4b56c79a33cbcc2a80434e4d8df50d3acf311213ad5713b3c90b78029196f50a02d1e8dae46e720942be5f9bfea5627fb2e038e67bbf3182785dc3b53a20830a82205f4a4b308ce1e8e545765f91d407f5500bf0d055010da586360a43cff4db92ea9c580011c83ebc018057b52014debc50914a4a68f2b582509a152b7b41b6e73a514fdfe3c3484960cde9961e88ba2e35482f5f6b89c4a4fdac069ec2ae5e013d04f4b47a1e7da27748955a66b6e9bd70662602b742167b5e79368899df390544eadf5050ec6d9efcd093824240b279422113c92b4258f0cc5301f2275cfce67d1fab4f2627d81555eee86e04e860adf57722c0fbc6726f0308080f0284f703da801283c2414e174cc154d19ad12c8776d50224215b6b4971b1433171538afe7c9da3bcae68dd559de981c7f6b6907f084d8f351ea6c895a6817624c5813e6f281050440c50c405c1d8390fc8df6b18d65b413a69c1f61f32d601f2400041e7b2d440709b487f1030a0dbc84a6c232d756ffacd7ecd4a7229746fb746c3ce675a556e133bb501490d247ce2fe295dde941b572914446fd8d908eed1cc01c375e5dc8d8d8f09b9c6aeb76ea49182be43d9a18be12c5cd2b9a1e3e6adf888c6924ea11100f8206d388c3e82087b29142605cf5506480a50fc7fec2786263f447fa69ba97c42b9b5e44c202bf161a47d627688b03634a46d1448354175bdd994d2d7e789731a73f55b502e5cb574fd27452135a5df6f7032df287c85dd7ae9afe7b8db0a9071fd760a6ad8921d17e5e421325d2ee7ae2b0b31139a23aff933eb679810057a18d1fa1cfab1c49afe01167bac16ccfdf2a32ef6a307f53a6f53be5d24470c1a74bcfce88895722f787d99eb708c142cd4d4d06b81390f30ef410cc701edcc46d5a7758e26943ac5167ab94559937194027cc425b99f6f7641f89e8be775c050fa4a534fcec41c95ba1c5d94b2218a555fa90b0c2b5473ee1a16e063c8950ef4a01b9022ca4820fc1f3a365f1091301354cde4043533c71199aafd344c3ba6f420f7ece89108a84f3c0ad375f74a90573e5a23be42b62f3e61fd6effc47443901a25e347f7e04d8caf41d9cf9cce71e779be27c97da779e74e3e17c4b67a64c5723ad5ae16d59673daae655f4d80e47e1a02e2d68e82dacde493e3db5ed063b9cef13d5cf729f199127eaaa0e6c2d3d2f67c44e6efdb0810e5884f18b975760be0baad80c6456780040eb3e9279f21ae072e2ae9d66a19a49e20bd2c424a8d9e96aba5b16866d67ef809c48c3e6c557a0e2ec38071d7d9717bee988daa9d5ba070e1d742dd1aa80b1cff8d455a0054b5dfcc34647505e58696d6d2dccc5667f690eec6f1a1491d37028cf57daa8e3037bdd9fbac0d5edaac8fc3119680a0f2bff8d676ef236000fa41b590d81fe5b5df3c0151d6682fd247c291353ccd86c0d1b2bc09fbe61477efeef1cb658683647fcea6a397a4c2328e45bf4bd8424eba2c67b2314ecf49091ac393c2e07403b393a7d39a3deec7904aa6608db8f330108dff1cae3e3e78bd6a4d62c1554c55e2a9e5b441975e4414f72870a4233a3cbd036207a00ee964955269e657d3e66d84ef49f525ea8ec903b2aafdc2d56412b823c39ac816913cd985a71edbbb3c40751c287aee83b283be88e8e79556d198f20edb067ca75a6d5cdf5384277b83bc12cc64c0061d4d53b79d683e398a5513306fa06a4d76a110c7b32f127b15f5be109cdf117de8f6b5ed607cc99400e8d9fdbbfe22adeb8a02b57f5177670589fc7424cee81e33ffe0c662c317d38f107facd235d019f25a5904b3d76d329d92eef1579c1b1d84add7b067f8df76d836ab883dfa8d5d9c116c5ae79aadd78742f657e489695e6f96feee8ef3dff08d11f9a34eacd050c2c23e2186d52bc68d955de08a00d45c8272bb8483ec8c6b8ab05bea624dda49549c918ed53ca21b09be1dd217f8285069030df03a7265c8616dd6d238f8bbb54eb7e1f71f43e5215c813ea0a3ed85e761b3e8d69a5a2ec6ce2531cde10d69ce12928d224d69f39a54161591bd2068b201e2119bebb8a5791609cb3ef7ebcd15ace2cd18335be18c8014a61c14d1540edcaf2830ac93b1fc0f6203d9a2a788d22935f5718c350deb3260f32e0ec0e1a14fcffd6e2e2ea777160894d27f5a2f68bd2c3eb3deafda8a83aa4f1f91eb60eb77a3d2d10808ec67d8717f07b544a93d9b52a226a8303e114325b1b5e1302867a77df54906e84dd3538ca4dc602e0a606ac09f6c01d6fe9924d8ba8605f0c349228d757ceb484d75cc7ea68f3d7efa5be9f83e640212e4a0d493d3d32ca0cb99852a81bf6dd9f83ddea53565ee9bcc8096791f99cdf91d32282d4c5af3bb297ae4d2bcb541246852f55703f22c1e96331d66db6f9b286db00130a5c7943a3567ef022b5881fa6fda939eecc6c1706940ba830cacafc07a6fa3dd8597e6803db0f756b4d2b471fa82f9333b6ef490b37f4644bb050634cc5358f663dd47f33326e5265d80f1a8d12a91fd023524d7620bc5da5c7dd0c1309860c07af9dfc9cb5e3b44359d4d3d5199d06492c23b091bf838bfad82d361cd10710d0a5517a1f0ef0f0266e63c1d08fce59e13937939780669a5dda9ce91a5f6a01be9ec668917b1a66c073af74f27a5646804cb8a4bb79a860af8b8731b1e94338efe8190cc24483e65f7ee00675b72293dc5289b951514aba53861c5d54c270b2e690235ac3f53c59a87de2e15ec0543fe377e6821af6207e58333fa47b03bbc152762d33f90f1ee3f07f73ed2ad70e2ba40f6027b3d5e40366fb85cc8251bdbcb15f637d6608f56e58d43fc456f2141c394cb5df53e0c686ccc50bbc413317326f426c45c539ac9498bc5035b097b020fc495d30e6c4983dfa27370ee03a510d2d25728de076d109836def5c1a36c34657a5bf7da03eb1fbd4ec33ad2038768430d58e0a5a018c80819ab8188f163595f545514b0db0997e21d6ca0313ef2957bcce0e7e547bb68daa0cc6a166747c5eac4175e9b0cae7595f19ca9b952c401dd1bbf1935c4cfcda4e3221f9731aa4b6f40c2a6865e22cfcbe91be85f0ac46a94bf551fa3d2f3a08e6c90225201df8cfce00f587901e79189e12eb574c51f6a7890d11c58a32c90ddf8329c589077e19c9ffc65b101abc9d2291b9a5929643755fc79390fc9fb86c08f3d7411c380683cc657f94414572008934e415056f7d5fd265bf8897bf007314feb8876bd1740b4bf832be7762e67a50b347bc75af04e1240795c43ff1b4017ce7eba2653fed30ef0cd038f0fd6ecdf02d278953c15f248c28001b9a3857c355261bd1adcea7367bc8a41e5c92ae9473ad3caed180f002f545d700b42bd7d196c736b486dc62c22fc22a7908da6c1b9a3e3c8c5b7a7683e0a72fb08eff60bddd792af87533f147d814e53e39436e8ed4f7094d3365300f308d66d7bd63795b4a633d9d6fa99a3e15396e4954bfe95cd3718b2fd47c5489e45c3fb22f0a7cda20a56cda3da653ee64422321dcd6903d65c8c52debac39c96b1c9ee610d75f04717bbb455525bc22834bc9636dc29baa18fc206044b410c3bef4f06a311f263f499ee62ec680e80a9e978cf9be5beced15404fa37df7505717f12570c6e9a948cf88de8a90f7a1e4ad1be2f4bcb26dcbbc0495b1a3ec826ee4d0b3f627de80d356bc4d83d7204768cfb1def3ac0e7d040d33dcdfd4881207587fa8bef4549565d9be734bf4ff4eec5cb3a95902d5d4a24be57119fd716b59ef86699f56fba56997fa1f34b6904904f1f4402e86a9113b36737ad630f70841cbe6b6e7f2ef0b8420ec7acd6d36223879a59953ff02559e4cf4e8887537dd69eaf504ab4ce6eb412b157787bcfe9a7cf192c5bc168c4fb4b3b2a0e18e31eb03583fd61dd479a7960f6ec6a4df9a8c015b3fadb28bb832829da391de756e8d37a4219fc958a754d1d059a642fc3103777c1c4556aa266a263f5dfeaf38302bfe2f997201ef357150d26d6a9df82159aa6126bf987bdb6a420268fd75d7d6836b8ea06e20cd6dee53d6b6201a994aaff348821087c5a9ad04c4dec5e4fc8f763f8b018eec9cfca2bb14fd40b44e3b76148df42466ef6efad1aded97db9dcecc54ced988931e2fb3577970704c729230ce332b7527981245e53b2e6d67d1aac4d61d0d766bff5697730031c2e6fbfa10768be390b0e76f35b1eceaed57fb3e64fbc9fd28a69a01faad937a927ea3df6fc9d7b6e8df61f9a8e08d76795ef58e0df7e384439253fe3b59f602682bea89c6285f1a96d75a4435a34ff98cbc9f7aa0a89f71b38c73eacfeca0acfef9c72b8e5b62458f68b4ef27c33f1591d665552430c0401c786067c5351fafeefb9dbc85bd4b4078b0b2176e2221eaa8adf779389fdc530006259f6e951eabf18742609eee7402f9c08716a05671efc43ac08fc25856f1aa4ad2a0110b1e11cdd435359ce59c144533870c0901e898d94841bf3fa205fac6deb44c1149b58367492634d875d2f6c293007a89d4df4ff00a32347e81683a6a610a3b544de4156388435a864442503498e63d401b50aa0db74db17c40214dd1da4e80fe2f542a5d84551ec07fa4a9f1fffe51718f0c9b704b25706501d30eec18b88e6a4f146d0146175e2b32c04e3916d7a5837b14e45cc903aefd0da7c66f69eeaebbfc4f743ba87cb921efd062662fd2e876f43b492e7bf2be13b8d8b1c57d8ccbd8556927aa167c5944ebee2ae43214c503effbfdccc6d24ac316e211ece0951a29634d19a0ed310552cd724aed277145a0c8501ff86e8aedae2cc0acfa3eb410f571dd8de2d550794f57afd34e6d17f3c1c7b5200c5de7cc14aab21f45d9fab7dd34a121cd98205146cbd3dc6b42faecae1176f518d08d5c7a9b40e346c2748d10f6cf7039bde00508789052ae9aa9029079a05ace7650fd6315a8f44354f397ee9315fbc9be81480823cc362415975d653b05721e1ebd91078bcb0c5d6cce315b46dd24411e79fe3cfda40f4856139a3a285fd77f5295576641cac5f7fe49298f884cc11a38e8a3f03e9f4f55fdab043ed906ac75b8045256605e8153a6da919930695cb8fcb58fee3fe39a50caea58177485ff366dc071bb199e06e7ceeaf87e72fc68f957dcb0a20ad0e4ca0c95f7138a6a983ee0d86b02c6219d77415ab43a037775b6f0bd36ded21ba1eb26954dec06f109217fdb635da2c741ffda7bdda019eb53c9c3827230491f86d749273917b9d8591f40e6ac8891a40aa90b1fb278a2b3eec7b390f4d8d7a89459c856ff1c8841c3b7d1bf503b079a65cf3bf5e9a689ab6c56c2dc4dfa9f96fe4c06daba15b4d3369e6cfe8dd197894af35d2290e781f95bdb6ea926826fb413c5cac90bf99251234a143c83312e6925b97093f6cb836c532ab2b86c0bc36c6ee4276f78f1abe6d4de459a19f49196ccbaf5088536eb092eb03c5191c725d89e24c471a9065470ad35f22a05c634d852661d2c1d0c2cb134d409234d59f8e7adce1419e11658b915ac4cf5f345f0415fe7ce45ac20e5c45ff9dda18829125690e9d4d8e2579107b1b5d6122e1c5268878d0566af4c2d5fa8783ff8eda767285583ff2f51f3140f6458320f94bb88f284e6f7e18c714e266d913f8f75ce9b156438adf9fb22c9f2c8436e25082e9d7be819d4ed67a70db103d777dd434884164b89f9e170d5be78c14e0accd1526f5f0ba6a1a85e24d7a998b78a6c32f5101c1210b902177a8455d1583bece890a6f26554e67e9fd83fd9fb85e6469de0bb9382a31ef7d909076578b52f262a2566b1efb554a50d36c095e5fcb2988fb13006b6af2b7d527f9b1fcc044f5036a796f56280e083cedfa3af7935bcee878bfc5dd0e222b8c2fa61beedbde9a4d54c2d549b8a784304e0f3aca67dfaeab7ef5ecc2f878e13ad49b9e6ab9adbb158752ff63e14256f47a462c2a0976ef3c43bb810c54d2cabc4766ffdb384d33176ed84220f41cbf864ba2c2e79674529bc535fc7fa0036274ce583204c59736f2433400876beba95404ad2bdd17dfee0755f9f18bfd823e597c874ec1b8758d886558fa5acd9e0c0ddde69b01b81b334e7c2f341711b9566a601c00e7f285c507db67949abddd2291d798646ec144a4f9264006e9ca1745d4f26fc16e8f38e0eea197565dbfb04009c490fc986200093c7e028355d9ed88feacf5a3ada05d09c30c9ec75d40760059f7f4830b4d5421011a52c34b2e2e3c772105568e3e7b6a209c32bd5ccd3e107c4ce2d04676d93ef8e703b451870a78f147f4ac47c1cc3b23703074cde9abc0b126803c01be1892b9d65e7f07fe52350900fe58d97f059a4407cf78735432e08fef0e3c01f9ab87ff3847fcc7bf46021554f5d8a671f5a5019594e4e13011499b3768c23bdd91859821818e365ea1422ae5863675d4737ed5c1061124df3a3afcbaa0ad520474829786c559bf928b2b892cc50b69ae08fb3584e67d9a61e6ddd070c825d8aa2fe6c4df177ef2ae7e937c3ac92ea8387d97e86ad9c5b0fd9badc88244ba94497ebf53d2142d9fd4640c79b71d38804eda9a8762153c03a48fefe93259f72d632c9790fdffa9c06a8189073a1a31ac0e88b266b158d6e14128fc8228e2ffe3fc14456d4f2f5b7f97db3b233fac350e6809b0987a1b522af2bddf1c7f501894562ab6d6d58d58019b2c68098a308942539649c9f5d044b1f3afbb98160faf08b743e5c90bc6943190d10c52467717b301e4bb5954b91e294e3054a462141cd423b4e6129c05a14f49389950ff19337950e67e57268e62042b6ab56094060674519c97b50fd5c2ec9c4a098190d7fe61ee5a88e37fafc96e5d07e838642282aae9fcf99618008016e5faf2ce665c1ea8fc4b596b9b94f9045080e20623c5165d0b98f0f4e9144c20ff49874ff5c4cfb8097ffa4dd01507d8142e3684cdd8f6e6b76fa61676f4741768630e0d7821e4ac0ffefb74f93151c983cd14613f35fad7a3561483619fa0da69efbec5d4b71041abd2ef5ba9c23aba6bee0e67c7e554718e778e80b8970a853d6e48f3eb2d55b0c1fb0ee9faf91572172c46a0dbdd72a3bf4d1b5507a8c0613a30663c37a87ba91860b5e73926898f699e185d95c1c09752bb8a1fec45f9796d4817f3ff58570f201a298e4013426f5edb0b6fc4964b5ed9ef9bf84848e6e7a9e5909fdb4484ac38624b1d22adc86c5b9f6b15365dc2c520fd7c09b59a54973191a0ebc515201521ed41fec1d2a81354449e8b46260459d4b9042aa48431fd8fe1f2d7830bcb533ddf4cf4084f4c655d264320f1774d86c02786e09a52e61ebd49fa85aa4a527e2ba5f635bad0f47c3e869dc0772baaefbbd42fd15919c214ba9fc843e97036aa2f43a7a9c7569ea578a38f11ba8bcae25d0017efb4cf1324e75dd6888659887edf8b03e288a4dc036eeafe5b0073ffbcd736cff2e2c12c99e73563730d8936de80a52d354d617e3490c1fed28edd51c3197003c1f6701d6d0c6bf7528fe54b1f5c7b243aa5fcb73e120561944f215b2f41e2fc10f73fe5a75c1d867f8a7f805e98f63d48a9ce3b1254675b1ea585e0d32fb3ff99d0b4d44e4ab1e53fa1a462fb7e65c613bd42f5be0cd8f069f3e4398b91651ccd8b78d332f704b5bf1a3b6677c0949cb790ec57b0557cb344323d0444653fbf76ad6beef62ea57be9314376cb7c9e9f92af6ba8bc573df3af319a62494ada8443b57bd7911f71a2df34349a8f7e7d04bdae21b116be8aa2c0af7592366315dba135c42c79b2765281b51dc3e9ca34c62642a49bd2816c2a051836a9d600e14c6484639ad51f7a77f4a501565c060dfe769615f0f76d7171c0a9034c7f0623be6d33489aea51b55c5ad7ff0906f3da83836cb63c0aac344e8bbb08b89d2519d43e3987c3e8c7673fff830354cb06b11a1f8e9ea3209e24f5aecc95415bead271ba006fc455ce81a02d19fd24a3a0d0e0345f15566058c9a3f1f25d803a0213390bed4e6d5d3ce5d47e82e8bedfad5ee35a86c9d1a1cea20eb46164f7e3813b8dc41bcc8e62493fc8a864dc6c76108dd24f6d364903b93b8bf512a64d3664f663b0759fa6bc5edf734d74d0d58f146507972d02f47f66c80ce0e6777d93d53a240703431c6f4a6ae8af9abbe8721fef4aa9ffcb5d46bf2bd9f55d4f0581544cd5518f726c9de78f5027356bbff862f13e39039c16d11a36be52e62963e4296d104fdb645a04cea2eb7b2990bba60745bcb5d75286a734394bd8d4d42ae9a640ca9ca14768483a054e00ed2f6208b1a732f9c2d19b54c9292b3897696dcc5a660c0b89253e06590613f8aedd27196528246a0a7808d1fb74aafc7e41efc6041edc90920932b5c8bf9d596624f858c24305e5ecbaa0eebb9d3c0da3c462b716fc3709554ffa18e1ee6f3de7a4c2c60ce879bf0d385a9f067fc2806f9c322b190e85570941f11904d077575d8d2e42245e39b6026c39af120eb2d856ad4a5b6ac8f4bdab9bc9726bcd7ba49536cb61a525e2a04d5344d46511eeb33044f13d310f6c218d4a7e81073485fb4409d27b0e0d1b91a3c8ab0a86f48cb3b5313fd0f19f8531cf98705eeb0dc5dd2702a2b5ce7660ef4c101116eab30733881ebf6e0758abc7e29cd0c6c85a463199b6e51df786135b90e331247d138c8efcbe75447ec706d4548ba5ca23df9360db7a104064bfb48a76d39618389634973410bf8521a8e821ca376d8510b599f0f55556ebe1503fae8cecf064795b9b2f817b73e023f1f05aed22c9bca9a37653987fabe3584aa5dfecc25e886d9893a6f521489170472c888c9a89b742a18877e398096a0c32d300f416434b263a4aed4722ac629ce803f77a393e06422a9882651b30f3dbf119f3919373885cfff5ab4a43ceedbbcb7bfffb246a1cda650969e639184ff0c33e2a1684a38b0dfa8017c42fd66f02318fb7c60ef2505d9dec8a10cd8c24a306fe8f9d49ddcadfc41d19d02ffa5b861d5ce8d9f56b02befaf5606cbe8518c553194f4a2efdaa3e4b4b9b71562dc2978bf959da324737351b4b5a82439c855bdd4f9ac8b8a4a36c6a55a42cc5207a96b02106c28142e4cdebeb7e49c10dcf5d691e63cf53db6b2ba369e37ea724a1937268c0e2ad81ee6be042ef83ba06cfd5cafda9c473dc0f3d08bbf24735850f2217f665752c9eb35cda54430c5ace59adff02fe4f8ab89be64484efad642f3c8d00bb0eebf96e0d7bb8897c025f48a84c5aae85b14dfd175b2d20230b923d942b5e7c8308def8a2ad13cd2d91647457fba79579877ffcde45a426c92957b9a9b7b350faf747498db65fa703ed208c6355718265c405504ffe1db1110bde369cfa1f97544afc4c9be1be0e66c5042ff28f2d6ab23e7407b1f96dbe217507dcd92b7b9515453440ae4cdb7ee767311203e4fa4e448f81248d2d0f2e0b3554e545a84f06e497af6271feb34312a4f3d18e7e556b2132b11bc3bb2d62906eeb8b323ccedca0e69ab3bb47e58d0311ab29fe00d2982649c3cd7e1ef16628ddbb04152e38881f4d5570b418db0ee3d499bf263044f475173ce96f105aed46949cf21fe1be24700ef7ecfdabb8c8e08853ed968c06a0f0dd0b2f6b56dc71234f763c2318ded678e4e7c8b42f499ec991df3e2ea49679bb60861e8008565a1a9a4df9d14b2b32af3f056406e7600808934df109ee20a4004c798e343661acf6dfc51f6986a9443bb2d6629b3fed512752ccd72a1e5cce2dec3e6c26d87f7a3189b249e116f8852ea32736e71bfa938d89a2c7a1af264f5a79017cab54a100bca3f86a3354452cf5518135cb72dd54c67bf2084e2c69ecb714ddba050899d33079a9dfc820057ef6d8b6eaa36b5f6c69edae3fe3fa88556499133240105ee51eb73e0efff81b6f5ccf1da7ed42d892a9e2321e353f23bffae496ac1722d06f7110b93c2b768dabe0dc020358f2b712014190d261323fbeadbead988c1d206b9668933dbea7748da02109c995e675363ea33bc4ab4c0b987238e9c49002c301d4a502d7d3d2ac3583cebfda19ff7aabbcb06d9d4ae86cc807023719e7a0ba01b8b60ce79ee9656e8684acabc0195812d2cfa1ba9d1214954ac2891b9140cd9652bc48c8ceb09f86a67689500c9bd115f746cfb4def67518b1ef8aa79d6b58791380a0d2a6e3e028cb4038e40c83b75c9252a36965dd88790cce94f3ff2dda2cf395453b2ff9b862d75e06e61c7dc32c22315f59387957d7786199a8ceb0fc781bd408a0fee183bf585f9fa84bf7779627c8e438b4a63289c72b018a30e8ecbe15b98bd21d8e3ce5233a0681697d8d51b6f5094ba672fdd9f29210b13ace793e1f945a3b0ed0b4e3f83dcb3b9edf5f84b4641a6d9fe9d2b61e409234bd92b2cda5c8e61b0d6cc82b0cab2f397dd64676afb31ab934e15df785bd49a8e85347f898dbf4fd40058036d59d8fa634cbab17269d0d23bf4db609f469755869954957a12139ff70f5b05eb228e9c4bb5ee8b2cc0e775078719d5e431e8198bcb414cd28edd9571ab22e0582aa68ba4d2cdcce5d7a33a179bbcc81609952b5a42e16323541ba56f90491d00d0deb711110a377593616b175b99f80dbbb7f4660f3ecfcc849cf4a274ae1ec4993370c39ac7dc83ec8c7498db6ca215d0ed9bf7711dc58ba1ad93ac1e5ed3f7f0916ca194baa7c71fea4d6dd164444434bb3c9086d5e6200b022474b19fa82136e8504e693babe95831a739434f8400306005aed6470535050b7ef7bfe3e9dc13347f3782dd0a64075b0540f8a5067ff869d0500389c734664716db500ecfbff753816a0d72ee60f921de97ab0d9c7f7bbb44e2cabb0a6732e57e0db59465b4ae862b69edaa425f61ff2f229d1c1b55e0a0213624f1a0c44a3fcf850f5615fb39883f37f06a9d97d014684ae545edca63feac7ae37e7ab16b2e797bc99ad4dbd8ae84c3017708fe3827a13af08812eda8988d53f27566ce847ac913a43c3797033a4c8c5d4fe0fa5bd3cc0a9ea1e9a8c0e42f4461c62baa84eb2fb65b8e0273747b00ec17bdea49e48ea46146e61df1b0656de03d71dafbec87ad51ca84dc1fa2812a00f68ed0ef208553ee87a685456628a11dd825b3fadf92b1c2a2329800180afd1c4a3f8c33e2ed46892f8fb6a51b2e96518389213f82feecc85f7caf309d949124664761dfe35565db1ca23dedefe6d93b73c61b911fda94256936631c3434c8791f50de07e7ab0e7eb42beeae878c26ea11a87a6a8b66d5c968a341d7dcd2d48d520c10c9a8b952947d7e8720f4a72d4fa312170ccc197d94b99c917de94c5efc3e36aaec3e39f3542056b4fe1cd663ea23ac8d4e74638f4496a2ff246186f05f357bf9ae2a91986a2b3d7a227a712eb78b7a361aa7924384a8eb4224addbeac737c54c772c26e01bb73b61eb29d141312cf57fbca59f0867f818c19989107c77c38ededab8071585dc572abbebfaab3dc0e760ee342294cc016569131a733e985616efa4afce95ed9eefbcabe5f58ea7cd9b497920e6c5ef00e7386b51a7f5573d6089ba4a2e3ccde72c075da6a402c9ca991993e9ce56974c7c4d8b23c1ccee790bcc1098a79765ba89b537e2dbd3048b7177cda24d19da154c7ceec9cd4c3cdf1d22e493cf7b9031286e2fc2f674113a648faac0fd82c278f8a8168efdd9b20a4a8504e6a25da23b4b844b0a894b152916d5ca861c7db655fec77e520037a6c6be2a310dd531eede685068fd2d114304ecb034eb6e5bd309c9ce711e2e20ed26b3452203bd3175b67c7573273cff35d522adf8c3ba5e328e99a25e3bf218b7ca7e8d98245da5582a2ec30e84db4b516c6a6bc2f68bba68609e5b0a21f046277fb545d9a4f1f3c57c7855dcc6e08e148ed0b4189bd04aec99c21e77fe00d3f390ca06cb2fcaf168ad68a83ae68fb1da72ebe705c46f487d213eeb7e7cd0b7bd3428becad6c5a71d166e4b15efae5c8893c3ff8ed1033524da85fd3989106113d05ab547446b98e869509030b1c5cf83ff5a16534a386379e38c8a504c53fd336a992970dee86b4c8752fc28fede9f20921e6af498faaed9c12682fd5f893864bf7afffc4a382f6427bb71a7a7bc6e488c4e0fe1b79b71ab9e226ccdf8c55fce1900fdbd6ebef595e3c7bd233d8fd83f10bd97eafd4790a49f1696d34d681a4a6bfda0789245e2f69f2c9bc3849544a5d047c28e9087eb78d9efab70e4676e22de7665942aafea1725f5c379f6b7bc326367ddb07a95220c240decdfdacbdc5b345cfb4f143b422e85d6c6f070f241d3ee81f8dbf70bd8e4870c7314f0a2dd9dee5b8ad6286ececef92b0329b15cccc44e5fe0287d3e74d70290792b3e6a108b00689ea58e4e2120a6ae9f7bb4269b8132a8912d3bcfc7a51dacbeae810427639be5cdcade7793750aa77e04600c82e46f49c567bc7f68fb1dbc782d55ee8c62647952c9417187da6dbf9edf6250049e98ef7d4954a7b6f16f21e10a47b4b8683a03e666695ddf8a4f90cc8fc5ba3d8f59d7a4ededfb389e55780d4b18e4ece85abebcef5ceabb2a396199016b6ef0a33a86802a58be6b9d2ebae5a6e3cca07281194c894bc5d5c11d944c4e9cbb6c65ed81f6a705aab758e91f97aca6b9bffdfe01365b0753fe32a3693c7d9b953147505061d4cc39c5d15123ca0fcaa113ff29a12bccd95adfea484a2bfb0f5aaad199bd76e9b1a8e50f67dea17794e8c0af76c88019897c244161c8d7bd8450d142f1f327225d28d104addb1564dbcd50b4289faa13dc2a7d274e29ea483cfebe73f8687c98548abd9c2dc948be44077a6516bee1fa5ba8b0a8fc586a8fd11359eb2aca8cef5e33e8de7e902c73719e7e32e70ee0ca6d414b486f4850cb2670481c737b106d9f069b15fda0eef73029972101b9189fe87a97d4f051ba3ed1dc6b81bd12e7d975dd13d0feac5797fd9267b5985ec9081e98b421e8c446499588fe5de224a6ba0f320e4b93fe6433b3db007d5f6ebad142013139ff1ab96ae286ba690535a24d177f2fc03f4e7a3816474bd700089b012658cb0c8ccf8d6f2d9939f3f2cb0d6d7a85017f518da742d640b9216ad4b3f41147fdd675a4fd8644f37a731c335c77a9794d0d52db53ab564e4451472fe21ebc3c7e59f63f6d87e88b0efb450a910d143d8e460fe15203fe2cc3ee1fdaece85bbbebc80df74596fb10eab75ed3bc51527424e2d1d6016b1ec4c7308346730cbb89a6c7710d5222407a36b375b96b12ec8853c882fee1de02de5f69e106a3e1a11463f8dd1150e7f0623d8de6e3aae555ceb1f7276e2a75fa177c96c83c3029c4c0339e2fd05ae06235286f2200c88d2a37f929ef921052c6f657df69cce29a62fa967ea644673b893b7d200aa3ba21f23d4c3a373db0537a433879fcfb5699153b3f79afe821a24d2bffac084e44d44ce28f6500d9147ae183cf25a595ae919b37b736863ae3d22a11275a60f60bbea318b3257efb6e2aaf025c7fefecbbd6fc3e39e3333ec1639c6b5047fbaf6154c38fddf823c502ae4405fcc38479d0d537ab72c0a925b1877525de97d21c0403c4a934eebc3ac95514468a5625cfd5fc44c6a584147a4149c8f370ec94f2de3110eafb4951133b929dab60b7f62eab3d0269d8950457f1a675dbfe2d9d98cbd2f1028d46f9a31db8172d84d28f6b95623da109ff96812444876da646e081543b82e4ed29a8532833dd34bccb96460c15017991aad2bbc8d1249176cd53cfe16482017402c755c86a23b68bd61b835b39aad73eaa3824cdbf5d14ebf6b4230967dae177cf8937b28192389c5f5172ff1c732ecf2f0f83e31794e7cea21dc088a170793811e20573f739863e63f264d6752a7998a0fce6456c2a9769ab8d71dd2633fda30a082e45244e8e70d3d25c837d7c6faa79a1d4836904a2a6f4ee2e1933bcdf32a94750b027fd2fa32c0242fcce60973c5247ede80238ea251df63133cd2e1888eabc369734379af412e02567d8cfba80e12ce29c34ad616033c6605639da2310beb34a59101aa3bcadfb407f96423229e788e7ecc0d933b6ef384e8171fb0b28d0e7e77764b0db0f93a99909dce44ca83b4df8648f0f1530b13850b173095ace79ba5c2f528f80035eb85c75b58d2ad91f17db0253a0657ced215691ed3aade8445e643dbea7e43aefe9f3fbdea3475d7b35322d4c16324a20c37f0e78392e79f19a3e9f4885dd46220c86b6e5c5a103e9522b9a52a5d0b3772be0bd7f9069d25ff0ea55c10b7abeed4cd04d8f4077b1f7ee14fb98254f68f4e201585085bb793837f422a5b0ca8d4f8d10374f9553cc0abf359bb3e182b61def4ebabc3b3916f42c39f17faa3c1676099c112fd4eef1ccbc939605c000bf709ac20098b2787564a59f0dbc4a9bedaa44b862c40df53b1857f7d1c9a4927db7e2cc4bd6d946951d66a75969ee42dfe6f3924440513f058681fc8d667d010d8ca40919d9139d5d10f915acf6b40a7656764a5e79406d24ddd4e35bc98b440e76ed76c1332432ac703cdb9acd76f876209ca4e63b7af90438004140dedc6e0e3d227b659dc75c6dcff65d4a41f019367fc1b6462bacd27f171b7adacdde4af93824d9f99a8bc418139f1da5d9b5b4d3700d32566cb53a051bfdd3d7c43fcdb1445a66da0adf2bb29f41f81aa272b015e3d42882a4300dfd02e1e7146aadcb4edb50239f2ec1dd2271974a660094b2c9cb5381fbf27847ccc213f9a6df5c1c6873eee5b4c9eb6f51982e48e946e0f7fe3c536f65a722cdf5cd1f763e71eac8b4c74193ec02bc2fdba3a4879bd013e0aff5984fae30671bc621457792306162c666dfce02e9a835f72e7fb312f139559cd86e41e64018eb1e9a4b5f58445a47e6c1f3e6869e3bc64fe8e165821877c74f9beeee17be1f7f501f93a1c01975b7b540501a8e6a1765a79a6cf8ebe75ba407343d3c66f146dfcb34e3447fbac8735cb568a5d5c9c47d532a10eaf267eb2b7c55ce58c8cf156433dcc574c212612beea4dab9773fe8d9d9ccddb3a334540a80bbcd24ceacbfda5d0dd91adc2b36adfd112241b4d74572833d58e9715f45f47a383c2ad858a460155775d6d9bcdbb97aeaa364bff127ab5c4d518be0107841aa7bf3109092ed68d2fbee9373b3c170beabedb03748b0a12565cffff8004453d1ab5c15b6984c69a80dde52c4966274aeb2f97b95e94ce6391e12a101b282034cca3ea9aee2dbe2a8ef5861445b04610cd1b62a664f198e41c102e37dcd95630f526d3d74e4d354cc344e7e56ec173097e6243db5c2c3018d0880013a7b36b1b003fffe6fe033bf64a8e7aed47723acb3da3ed0a65af8b65796098ea56e2ccfdbe9362a25fa02db3f8e6ebcf919d235044c1364670456c458723eed4a6a599c020114a6c71df9158315773df10c373b3c8a35d0f4708eb4774b445937fd90623341124d562c45097b87e3c864eaf49580d47c722167fd7bd79c5bbeb6482baf38d641b19bb287488ff09a8d746c62035979edabcfaddca72d4e783e01080e8d42c0b05284da076ae0e2a8417782bdc7408a35ea86893220a5eb9454dae7574a42e3bfeb77daac14c200857d1a1693fff84d73354591b7a5d02aa7e94209158c3d9d3e5b428cda74a62d9d70d34f7bbdddafadcdc13bab0bff774005c8eb21d01f4b638c649fa54812ca8f752eb5a58955ee3d70dbe8cb95498e085b78da047d8c9c9553e9ee2b85a872fc962b98752c57cd5b590234fcba0e6f337fa29c55e787999ba5ff487162acf723afa9de1d6f5b58ecb23200f28ec20b63fad4881a2e5ff25e1790bc713b490e79a5ce2b03880c501919d409272de8536e310613f29c8b98255a9c329145447f363e7ea75b8ad4bdb9d6418f0e505e85770216ab1cfe0914d94d41274fe9fc324fc3940456bde52584d5033331096d1e78f84a5c2c73c0cf78fdd727a3cb0cc1a6e71b4d38ded069227be3ba2860eb0656d84601069da721a8e5400790ad8e535371d7b32ffe91017873a295f7a9999660c3d44598ae7fbb7c9d1a3b800058f6b632e730c75e91a878e37539cf05e7451ecd40ad6dce8f972274c630b1d0d489b750876881973fc75dca67ea01266312ddde93f35af11c7850a0712b6f2f7cce7d9d6ce6ee71421ca886bdbc83672afe61582cd37b33c94ed75f5814ccef30ce0e3761bbc8d2dcf3a956c3042e0a9d212a2d651eeed44be6ea504536a42a40759aaddbfe10b52ae1fc1464099e1381236d4483d0283dd341c0e8879d9c11a3847b235ac92dc18a3056a72c2309181da92e2aa47bd74876b65b4bdbef5fd086d6290e4a9eba2255e7740ff5e37da424cb0a2c552229c82e2128be65b8b060ece30a267efec31b3fadb5bd41eaa493fe0317489a64bd54bacdab9ac376bd8f303b82327c30e537639d21aaad5788fdf73b80b8981121afeb96f78877b5a9a8bc109b8d5ca4dab91943bcba64d6498c81333c2231b1d1089758686fe515585f29c58c2d4664c10f01a03225a373a49e8cf2869fc5f519d4ee8cf0130fe9aa90ea77a2fabc25ff445a009a466d24ae0ee7d96d1965bc6698280f20a3d4ba2a712c3cce5013df5dbd2bb9fe824108f4abda0566e205d7f70c461e00745bba5f7cf31331713ebe9e21232e0305a93c971f94e1336d4a55ff11cb8bef838852415dea263f360c2e91bbb01ac432282d60311fb10c7abdb8fd71f03d168c4895c03f9a8cda80ab891e1f29256b40ec6bf66bac0064441406c10d736d18bff37ea48d265b577554e10fe103b2059dc67058813611f36bba025360b4f90e7ec9de12bda188e964c91bf746680f37c30b85ff15d56cccf3b34714d9d75854cb3f4d0db925f353c28f174415a5eb450787c6d207b018fa001d0ea043ce1dbd4e9772e4146bc0ec7dec81a6ebaa142062e562b5dce0d322a6e3afc2c25dfd27f6279439083d578dc7ac58e4d112a2add91bcb20df97b507a4c048308b783ad049307d0bd1e6a5c4a0735bee3244c9d8654006fe28aaf8f6df7c020a2f7f8f2afe9d69c29e75023ea59ecdcb1bebcbf546c8789d421569ee0c3bff8ccb4a5015ec7bf2dfbeb65ac1bd16536c1fa0f4ef41cbbfc7fe1351b6ae83ac386e13a0d7cce100b4231bc3f0898003f45e37a93c67b1d4fd5c0776c46c3dbbaf15bdc082bd0db648eb3ed6462010ac1c728a7065d970fc4ce954dc4bed98f53adb741cc612bf89452465c2ca0491e35d0e61a42fe068d5a548553f1990875e9016fdb5c02cf1b3502c4e80deca3e129b70b85a7d37755edec01ca02a446037ecfe0007d9857e3d339e4ffe1b037535305a9e86067a304f5ab020966dd0698f88513d030ad01e48ed20b442e6cce8ed5336b5907cef9a7692783bff98580cd5b2c644de21ad4a78a35b38483bcb6a3c436242886c6ae59cf5110c99aa9991663d32fe4eba1658a4ca8dcf133a56cb3d4de467620ff7f883bd7c721f529286660a21ceb0ae42729c3e81150feda827fd80393fca63abf1b8e5c1947d296df24c64ae9bb841d5d58ced6e2f0f37753a1254e5cdd085e877c276a0f9d71f7b8379c7d7ec16afeaabc63d3bf57189dc734578135e6ee4977856d9cb1df420df29200002bfe2d78a9433d9c743e3a13b6878edb57d7083ae8bc4088f63860f429e383003cb88ab9149acb4bccbf86383c32c55bd09f6538ee640c5dff6999c6311a36e662198e943901c4d9f3968a778b90ea408649ceae6c088b5f1ce434a20ce6a00689c315e94c1d00e743efa6b5f52319cd438f3b38c2aeeaaa6f52927775df7330ae6a818983fbbbff9229bdc19b567b4cee06a55c154f62befb02f14d91c7db869e1a762f8b28482bc4daeac0b8ec92d5a19505e9d38a0daabd2a12e59e5978d39e0868a690198dae6e87d80f02fc40e33f279c27632d6c9bd847b310d4e9afab5d5c7384eb4230f1a25d19c49803f40881112615561df8a9b7f7625c70de26b599416a4b6d8debe6f2da25192ecaf8006100fb2162a1584bf915f35e19d7633c989aeaa236636c3ec4f91a5772fb1002359757fd1da9b8cf107767375cfcc9b2c08df128d9ebb2f7771ff66ffacb582b79f4f6047232f5603eb17c13b15e9ee86b989bf61d8a1c05a6fb3e788cd9961aeea9923b96f76062ff72aa7bfddf9b5ffce6a707488abfacc8e1200f9ef19299d8c28e108cb57f6b2ba4d64050e8b580e3d392f320c0aae32e00c9ed0705c5c1c50321040ac317146dce9496cba1542b9cd79d70fd43db439df54e0d95cc7eac3fcdb8af018bf794b463161add5d2ef2a65491e5d46e020d821d200577f290d202a46d461c321d3d4bd6ecac59b459b9dc17c53524f72ae38077764412dbdfccbb3092e388f63d467953b8fd0f41c8a7d5f577d062f96f7803835c168c72097ff7db3e9b3a93c0a01f7fc27ccb848ae4699ae878f370ac3bd2754eba8a639c33a1a56a4d3ee3a5174c2c994340e673fa6ba4260eea6c43297f36d1700c308e20840de8fc4f9a501240dfd540f307d568d68c68eb2e21e88cf3b1c85eedeb714241308453e78c0f75b61edc8c26c22b04aad6916503da3718023dffe10d43928b6e9a80291f7858decdce60c783930f25d33c95dc2ddf63bf51e58cefbdd45c6b48f2aea4974061f10e0505062623e875771183d192a359669699313faa61e73e7a521dab3c843bcb5ee116208edf8620f70687030349964f2afc56ea7603ea1bd154ddd6a96dbf0987152d988c76062c314e87cedafd7bc6a5cd37203e6522fa26afbc8be5dffea0e68ee734070d34c2bb77dc8b8777b8de0f1ecb6db23f6879e21220b8d6124c282b086d210305eda42d31fa0b5b22945840a684503babeaaed63c7f97f2cdc49d5976553498fd21646c6f65c015874b4c81ae79e13e05d9264827f3b18e680f7914358a64c4cbc09295b0afdca54bdff9975562ed4be4ed90314c7f7e1d783015802caeae35fdb22f7bd18f57a96f70f38835ddc3c1789954576f6ecd38c5313b3d4f036da101095a2d3b311346e12ada851e7a4face652206712e126337621cf99b3e50d9918aae11f91f08ea33db3102ff774be1319bef7e1ef7f772458f4a40e2e23803825f6cf1e201a43c1685c20bec9eb06c53e89a0a4e9dbb86a58ebbf5dc775834775c1aa312be720c72995470835352a062629574bf30b8aa5997409fd4860511bfc1f3d61b7be9a7282397bf4a3a688114ac5380aa8edc314d968eda2682a908ea5ad90ef0e0f75f1c3d3e0fe1b0e430cd90196f040bdd6a05d8228942d17c2cb1d520c2615865873d11bb8933ca9d7c5db598b28cc8fc35cccc84480f62d55ad7dc4385541e5a06e0705a5e881bcc678fbfc0be16975af66cba7a8ffe8a046ec12cda41dc77487c6f9682c94887580a903e8743347323c4fa87ed9b114ac046191454984834d87044685b1f44f60d646a75db63f79e63d74574ee9ca3f9006a8cc2883c73c35a73d52224634264e76e2f5becf061c11682596ba69fdc475d0a4f008cc1cdf3437bfe94b86680853071bc948359990af9e2e7e542357ff3f2ae530561ec4cab11a966d32ce1a1de410ee44420c8401c1396641460e20ce2d0cac6cac274c4d4e2785bf43e2d87a54661f5dd730c6914046b3af49b4605946b3cb9088ae0e7d9dd83fd479a001f8b75477ab14de39858fcff06849cda2ecf4ec02100594ea9d9e9e9c80fcfa79112e533ad079fb3714b18c62c1d0809e182267afdf3938b22e9ff46beb9cb36233e8f2ee592d31050d7e93f6fda33d5aa6784bcdeb5d2f34cc2a8a2a535d37d7b52686bc992ba6fd9a8b7d67dfe620cb565b6ee7d0ae5690bcdb41a201db936685026c5f76ff4bfc836d3917c4f9001c7e25a87d304120e8550d42b2b693579f7a3e4b90dc7429f8cf530c8b043f821bed653646906aceba7604f2a945582fc99f2dbeb2786cc1c10274a32d15b2112cf90e5f58e4a746d8831036f50d47d6d7eb207067bfa3f5ba22291bc8b1406b32491638511f5d4ac8bac92b7880d2cce1e36136d22164e1ea5ff200b582567b33a85092cde16b852748f3bd5dc9c95b722fa8f4c71d2a43497b2c4dacce47f4b497fe20a0b7cef2882b57c85720572ece074babd84e868703d53b47072c4c92d5398d2d37d09400d9ea3eae5af45c4c261cfd589c6ed1af4050745ad543b8d162d4fb6c55a1036cffbcaa0c25f34f00bb0c2d892f34fb2aa71e21c9a4c3b0ea62148b6810101b4a6b11e9049eaaec0343e39e90f92c65053e7102b838a59ff622cb5d1446d085359aa48ded534405f8fb4af8b207a530808f0b9c09da145459a41061932b50b90b91707bc549aa9fe57c0961cfc81ddcb2dad3177cc7077dec9ee5b5281c970fdb3f54308ec41c5854f82b6062448dadae4bc905cbd891eb888d8c56d5d180d6d6c5c664428f2e96288b90778a51d47cc5ae241b1f39f1380f5bb73be58bcf2c08c6819c13c8a0e790d282bf6b9dd4171be43a6c0f0f77862488c99a5afdd5d2dd3bcb2bff9fa823e4fa9bace4a3e37fa0b1698f0f44018d57c71e30112a5946a218e6cd02fcf2a309066f6b480b230637b3dab6f0f92bea61dc940de7728db68ae39d25f5a951dae1bf0294b3b16ab100cbfffeaa6f489dfda076471bd6b8ab65ea1bcd3b15663912a7aa90780dc95135548d7ff0114e06ddfcbb3cf262f1d018c53db7c2676acda570b29fbc812ffc8c74d23bfcb98e595d0646b13548a05ee9d868cb33bad4a63487f768531d2e63c449d6c9e1ced5cc2951996bf564758e6a6833bcaae7fd839cd54a9af621e4939c6e485c9774b1ecb8fed368c79202cebfa916c20a6e8bc188c3c6a6f1234900b4aea866622956062b97fb18acb59b395af749c45829573fa4c7e4d1402d7ab5a976d7bb50931d09a596a9b1e1274286d143c0acf8d92001353649cbf1d7cc48a2c532aec6fe6fa42fc857a959a8e32118922eb25805fb4964e4dc08ea5a18143bd56af1811b4d7db24a0494a5cc8b190535170ba110c0048198974df5851b2893b38e890f4a80dd68e75f2c360a26ce93a22f4fce61f9984d395921269882d8aaa859e6b1512448fb541a079c7d4d3c3c31799f8427551e347630313df4f5762f5d19c6d4b26aeb59e078534deb9c88ad8f0902353818556331bdd38b4bd2fb766f2b37deb9d15ad8e231b060f72bf1b3c51ddfaebe461e345eac7cb1b2e1bb68f5e4723cc8976afbeb72c95fa4182f7519b3a24adba4dffec9bf232f4ab97ca5516058c4e027f87fe6726f46ce696ba95c495f572f565d8bb4b543d2b93320387f20a56926d65adaa5e9fe40e4792ac6f77d1338f6d4e940dbc090d699a0a8481bba2a36a9e4a1e6d25ea7d8eecee922e16c84103e434c95df32fa7e8d58e38a6c2e433e00c9abde9172580d34c90f1cf54318ddda440ee0ed116301af2daa3da842facbbcb88f4c237d285fd5011d3cf54b0a06d9b38cb9d0a42d93a98641d96fabe868b348ae176045ccdcf59a0f4d43c7929ca2cc92acff551fce5a6be726afaae25ac3072181e19a23c305fbf9f826812bbf2e64b98d0c289882caf47f3a595970c429f55544b3bf6ccb152d9a8827c13194028655e7401a03936fc829e34e24bcfba2085ca40a83591e1f1039fea6e0b2665e0d807dc51009fabbfa32ab1f834745f75ad94d7f10b0f87544b29fc59ff18f528503448cf9b9f72738499ee247f39af36ad3cb4de2232065ded5f4f3c09a5d973508147e1311afcb7861eadfc673cbbffca1de01e2d5271d7079a0a915ee6030068bdfb1c9696c5a539d2b47d9f19a03cb12562fd472053f175eee36c7ab716c3e2ef3b276382b114067cdfea9d04fed6eb5de01612f90abbf0a831335e615d5e8215567a3aaedb966fbc4c0bc5bb013be319b1244bcd156b7980b74621dd62261f48322083b074586c925a3936eaf9d6c5fef0cbced51a13df04d982a91c29ceeb3f367f6fc7b376ea6f52b42afc7feb365a4ea59b6c0cd6f07dea48386388f378a1fb230e6f874ee697f328a43f931e320114b703f06ff4771355cf9a0bfcac89cb8672c0e554b46db6a4771a8a765316ff89a290ed10b7287c2cd3c3fdcccb5a7d74395033dc1efb3a2783a2957e9f664622be0ade6875a88884d58f64ae3115e96d20c85f5b9dd2e8a27371b2b2d0ae0cff99f6bfcc3e7cd7bb0c73fb668cff039510b36ba2c4cfd2780dacc9c09d9c059f1e6d0d67cfec2d8636968937cb86660fa6369011bdce0321e11af2614c388000ab9d7f492744f10517bdf9cc9b5236f1eac0d52736f9c06d726d0822f5b8b2de7254da24f20da7d897f3d46c8a09d857c2eeb3be1be16ab1910577f2a7a5b59a7d36dc15125c88b5cfe356552247d01b538f9c9ba9404547ebd130ec894d51694fe16fa2a2d6a36e829f5f676b8124bb1e846d8c553236020bb4e721fa545955e777bc58d0bec7f76c1fcfff3382e85ffde56cb915aa34d29f9a2d762e8bb81d57bb048dc9ccb0f365d135339721197a46914c3b1e3cabbe017100db55e4561d812a1c8e1d5b35bf033fa7546d08d1bb097f30a111fb4ebbc482b8b20d533bdbbe78b4f2940b4d81e8044708152916e51ca259cf73c6ec858dca72a1591294261889ac167756a2fd08a7142d7a47e758af7dc5a55f1a281047e8d61b8bd3301f60072927d3fdfcf96dac8c5bfbf3ae4d60e421287e1c36f8a798f643a6a76615404caf55caed81333ca9f7addbe8d045281b881487effe973ba08ca6617a312e490d4b48f1c199b5f283bef2d13226f82829cb5a07866d3988858f32b7ed95ec3cda187ff35e36af4effb289b6290a76b4bd576dd7a88dd30758375bd3ccad9f602fa3ade8bbbc03a207588c608c8df81fdfd380140adce5e0c4aa824a3f50de5094c82aabbf6ffd26aceabb635836a0eef0b858c069030e9335649ef0d1b212e5ba47719473fad34da0ec4b5acd13a523ffa1cd76afe4ed042b4eacdfab336a99477807ef974120507749e1caa0d18dd51895e358e8813313de5371e2f90b28ea3d7493ac7d7dc33ac6c7f0560586f8892c4d001a5aaaec7a0cf223998ff697922e89b0082ac6b901bc75ee8185f1941f4f00e5c36a9a6d3613e530728de7f2d3f629c4324006f5dadb3734b99c00afeaa0c545dbb0874e5e3ef43fadb4e8a0fa291ae31160cf2cb2cb8705fd9784df2b6af781495fa7554affa7d0492927322742f8c194a45fb631dd878a27cd52345fb23dc5d36cc6b7b71e41c56deb5f19788368d9017d3aaf32d71151bd97ed13f58980b3c6ca0727ef3e4f3bb0711b6d5b287ba82cf64dd21347393caffdd5e09d5207c365e937ff6af0964385dfc5d8dc0debf5e9542e773b815e6ac36cca829daab6ac949c3b2f9710863fa2349b58f7fccbd35565807e608c442ca60c5e161986f7918cf3bf97a124c152a36a0132990f7e2e8f2582df6933c638f7041eb8b11500b60eccfa4f78ff06044024ae948c5fb29f1e6320f70f88c3b30ac176c82631ad8c68b4540681d1e30d4ce421c941cba23618f1eff764a4edc1a9fe1c63aa2e6d848a2adaa73749108357ecc3a086d4131d1a31bea24cf87c564ba49abce47a021d05327413113f428bd9ffac4a8d4a937c024da632552d4a7e38873bdc4968db8e5931b46babe044367165b0ce1380d51c94292c05f1d189183b20aa4b2f9333710b575cc1dbdf9e0c524b8a1567ec5d6841283f647067a19cc19385684e4a3613f2e523cfa57212f7413dc115c420037ed8f4c5165afa275ae0afcaadabb041e9b3d33360c1ca4f2445a953149828026207ced4384667a83fc9709633cfa996e76378e1333ababccd70ebdfe54d9a5993242f6cf9f22c421b0c48a089b87b7b91fe6fd58404342bbe72644c1f36a5fe2e9f7d1a15c769c32a1df9bb3a8a2cb6876782b1bdd75e6f430d1e303eb9a826115837f5c0f7492eb1deae699be618589b6631c263a13bd55338100d067da2108fb58c9655d2df19727db2d430c0abcff85706b6ad19fb99112d090d3ee69bd04d92efa16c9b3306ca8547baca0eb132fe9e3c85b878d7016d1eca9970486354263892df7ff348d5c9a51858b762cc88fa11bdfc99940e43c288def9f45387da613586b4e21da438d92bc9a2f43beacadaebc717ae3d5461f0a2a3a71fdd6f71f97c884ff1a62b5f5c2566cba16e24b866548359fecb00c1c5576e05920c017c54eb389291cb7c24c2bde2572f7867d491c8ed01c59f992724776afa541f4f517548f06da5c0b36afbc549cee9029f39e95ea7c903dd273c92dd1c5519b45493b98459dd88b98ffdb3b1000d22b94054e28b1b20547a6ebfec345e9703c18b3ff29a7545ca980cfe52f9b4c6e0f00f80c724ebcbe2c6a7530f94b90145096ab7aec367b89c9db84327ac21261f03e13a9d22f58c7c6f288cf25ad0507e252454b0dd0f75ab7185ab65cf5ec682d5338414cf71c274937d0fe39a3e894a0888616099e002ec91ec97babcd499d2ecede0df39df31e92286f91e510da4c2746f038d7db6dae3f755dbc7ce9d26d4ef081bb8f74dd0aa72956b9b12b06479d9bd2c91c80fb757eaa96aaceb6ca38adeaef289ce84fa64b510fb711ea03a4f642443f7ed216069263ba39eaf1988cb7f7d5fffa4acc375e9efe59f1d69f970fe984317de568d9b59230ed995efbeb5259f93f52edcfe37af5b0b0dd9198dbfb41b161e6593fd6a97c3e0638e975cc87a0579b13117224d643505a5fa748645753312da94557d947c18775028742515a955c6f9a0643d353077300054874d5bef29f1aaa550e0efbc690b3247825002fb858553abdb97c38237d573c1e03f9637e493de58cccb6e46eb608126bfa578044f1b9a3357d8980718b66c54cc826fc09e420ac25e3e6897abe08cdb29b7b720da55be06e7c92c1f2d04c2ba284b27f3bacd3d3e452472271d1738b177233139b9a29cffeeb600bbc03847fbd64ae9dea2b27f8950e9938163f8d0695e17e6f7165ec609e445989a90a5f48c58c4f506171fc7aa5dac526da8bf8bf3508df8ac658f64e29a01843f1aae6ce491f7d50e93cf9e89fe53af1ab5b6b52d962f4757652fda4a3cd11e5ae031a3b28b8e85febc7627fd267284a1fc612c07fd40b6fa1975510a79251cbd6f087b4235ff496ef3797850a916e9b65ae4a5882ef0ba9c1f53afada26f6640f22cfec7300d01f1f78fd4edd8cc3adf4b4308f8cf618929ecf7d36e13c4743e31873d324ae64cf5a221269727554dd8453f1105063b26ccbade7e916c96edd0c44590ad5a41d147c1df76e1c87cdd845c4085e0376793335e74a4ab1ebaedb2efb19085a31335a179dbf9e3cd9c8d60a30907fcbe9f38c06cc1dcd8f807e7327e58d9cba5576e504926968687c2b3de9ac0326ae3d446c66a3762ae92a28a8ce27d5a37ceb49dd3a2c9bb3a475f843176d7c56276e661f30b19e73260a8737e681e890eb7aa78b1d8e56eba354974d323020e61f87d17d7096ee666cddd523c3174ec9a2db3f285f6f479d3911e76fd9a5a101f501eaa3631edd0e7f374ab63a02ace93812f610d8ad8425e162a5e6c7d9616dccc2fbba798ab14e63050be1265be85651428756169bd01f2c5e6db863e4a1130870fd6c6d2bc096a99bb07fc32937795142aeeb1c075bd9658964e6342d02cdfccafb2bbd41cd23954b61fe837f62252d6382ebc7d32dc74db0bd09df91de9d8610b6d258bb98b84fb92fcd895f0b59247ec96381a9ca090724942178dd1d64d8f66a57e2ac801d7bfbf8b22bd87fb0ee4afaae509827746b948de4e8b6c110c294813a58dfc21c6e39a72263c10ad0dcff878abbf64d26319fb634860e3c70eadaf84923027d07e825dfe4cf2bbeddeed4cf17f9b575efd2b813366b39a614f909cc43c7bb82dafa4cff769ec5b0f449e3cf9f499c49afda8850bdcb6a6cbbab8f75c83ce43d18fb45d3fe08e9088508cad671198b88ee741e2d04ee6f6107a4f90faa978226804c10a6e014bcac9e2fc1b165f65573b3ce79d4a230293271cabbe7c92df19c865b122c4e36fa06e4c71e04cd3c60570fc6d4f94fbbfa5d4322df861e042b9d8a3d97e1636a86328581bb1a6651769362f51114660717216a96b5532bff53311f606de1e71ebe5edeaddea5870aac310575c0822020e0245eada80949f50828598bc6bafc750e14571e21800d45a6e7b77bf93bdc32901ac09c7bd52a09418180b1981ff45c1db6cea08517bb2ba5911596df999ba0c2e533239b703eed67b478a83cbfe619c0a84c9e897252a157b3e5b1684466ed998a49afd2c768399bd6d596d9bde2babc492fc7cde3514bd3b0476566e427802648dd868e79aa4aebe351b733915bd90d1b68a36c5e86041a2a07d27ddf9f207a99f3f33262a6434f37c40c0f7f03030dc8b9f87864aeb5db29cec74fe62612d65f74ac46e07b85690b5fa866cd86196c22f290f8488d272e4d4593aa1f3d74c0765e6dfdcbf63469bdc9fd5b403034d9215534b17760069ff3ae37cf5b4b1011c083ae5060d64ebd36ecdc15cf94a179220ecc088cfde3a8d90accba3aa8a9297e819d52cb8bcdf4c7c6a4aaede4675e383f5458efe20d2ac85a7557a459ff431e5f885936824bbd914d4f006954eb789706ad04b01116a7f59c7d9f9f78685156cc2164cf4cf4f5d2730a68064d53b14d2a09949512f8c87a60a63e77e2ddcea6488a23bf4e07d24f85ab2317362a67ddeb14e96f00c8342e7d640a62acac81f5ca68178fdeff3baaf4ac6623a2b2f0ee6f2447d3efac8693e9d28ec0c5734eb4fbac2101f15cbdad6b6308a3cfeae6d3dcfcb7b214610dfb7487e42478539b887609666d3bc0527266b2b421f17342fb77b7c6dbfbfda902b82bc6b6a3d78cd7681e517cf36fc52cc5e857bd2bc1ff3a8cce9994d707848917688fefaf1748555940f51d80035dcd24067f32ec4d86e8e0242d18d971c7c39ccd6738b7133408b40371b8e6dc3bef0d8bf9f909477f24e13b399857f2caf6e479a6409bd78e4d9f4a94178d6cdca57a622dbfc145a34f4d0a3ca1af1414ce9fe2fc0b6615a74784384dffd8c4673c091e570c06d0f58300b3378a0e6a3394d6782421f7587912cd5af299653f0f8853e16a579ffcadf2ee81019d08262ddf78024b4f60ca9c687dfcf8abe2db60fa5d2bcf201a0e94813475ed88d2d19f433665bb79719f7cf56d84e642bcfe8c071df03435a9fbb6fb6f26fc9042f026f37f01284e22ec5b4018ea7232cf011e11cbd5244eaee686422dea52f0a3143d1eaa9c7d8ce9025ab4963c5385226584b1578cf68c12b9ec068644eeb973fed2c23b16532ce72d690d8c60e30cf703c86b783b3206b77407645b6fc21f77a25b211cf1184d10e0770fc75b6f56fb78d500fac523c659a4c4fd43c51538395a2cb342094996f3996bd5109f58a721529483da04d953e03933ceb9dfcaa90f781fe846273a8e4354807a62103f51f17d3d14d91a6008c9f056db2ed1420808dee30b685631106879f328a3ba12330e68a40fb8e0379cec6449e7aa9040c9e24db319d901485d8f970a0a82fce4f6d8dfdba3db58240db0383d4a8741a21d8867661863416fbfcc8293ff8b8dd7646dacf7e8ef097313b51722b442314e1caf47c3aff331584b47fbac2ce8d43599b47b9295eb4f6f730d86828d0b5b8e9759124f079d54a75c9f6c69178a91e5ae3e561bb24f2f0c584233deda758e98f9d0e8fc3f4f25d588566cbf6f0a9d5ed85d4063e33529bfa67173d872ed8871ed0bda845dea17b35da4a078b2e27515999bf7cfb61e369b1fe7e411b0b9e52b6f9f95dfaab917cbcfe7c2f9f3d7db5930dced149d192c2a68926e1d209ce258b3b7e92fcd69686a88e5f19f7a2dc927112a96dd1da8989d4de3c3880c94d2918af7930e02394677aac4401d12e5e9c9008bcf10503ea6aea609ba09789d05b9c8cbcc9921045213e9de63dffb2d2757a9baca917ae47fd8288346bfd6f140cbe02586478f6ea8933c87e445b778fec0ff1516f8856111ccae91afd550a7b36427f206b77f551556a5e6d0af7258823b004cd503d6d31e7f4bcca41a00ea671391e4fc916ed29c22d860440aca2a90cae6cff8567034fcf85d2a660ba01adf3dc9bb07be64fe8d313087b1f484a4753d441f27d7d49e422aa097a437567d80b35dd07895f1f8ec6a043bcf542c4294df7bbfe0b3d93311673ebe4abdee01ce26aa8999dca175744b8f6d9acaa55a84560b49c5fafd0ca0c1621419f18fd9cc8973d5f677ad8204781a7fa91735af6ac67e9a83f4109b62010d19ed8f3c77ccefc1ca247269bd33a5e6677f0af5e7cbc5df9c62dee99c4cc32a9eb30e074af598195824c960c3f46b05e3f141ed6c0b57ef316da7fed8ff64d6fab01ce2d3673a82e5570fab0f023f5824e3ed789041cb4e2c39ffc79419c8eca29a9880869476cf3f1695e27354e9493f3f56cbbfe9362a834f6f468ffbb6e5877ab48945240c87cc51ca749034035e1414c99a1d351c4dd02833e2e36eb2487477137c015f6c319b09f5990e08c239bade582328d7ab0152c3259fd507ddbb046961f60ecfe27e7155effdef1ca3050cec3770c825a772efb5a0a362d9595249e0c05095429d674079ee1bec891b9f7322cf43b3e04ce12424699c1f2e71f2270551f7c5d70f82a6f992b28e971acb29a48e0cbaa96a0322dfa1755bde2d565a1ff340d2ffce1e8cf111c44154ae144171cb63f81b2a114cfe39724239dd87bb65e7318bbf59781af1308d6827bec50ac82a348461c868a68f793aa2ddfe6ecf0f995ae8e8962d16d9a9c51a37669eeac33f6e5e54431d62cdcfd3536a5348e36ccd8da2700ac92cff26528023f230bb2193da7c5a4fc3eb31ddf557e55e9e72042edc3ac416bdcc4544507f1219d8886cc14933594554e2f9b6edf8c46fc3dac2339ea7cce2e70f38a4d756ee7948f022305f7e9508bd48f04555d4e2e5c142fae92411c821250613d9cc8b17d8e3ced5649f48182ea242996db5a0c36492343174cdbabf16beb4064d588e2228c1b3bf0400608e0315eefa35e11d907f53de61e2346989e788e89316b47b60fa75b82353a64bd6494a85ff0079a4555ed145be4048243e2004effe40942ea7a5f417bb4bf5785cf6fed5c6f983b4836a3e9d36b91e9abccdb023411bfcc0580f4fc5514dc2f6cbad5881b035185ca192ae38b79094d556a07675aaf8a9ff53f35f903ae35ffbd93aadf15859c7aebab57fdc636b99e37fb98d051a6f33500f956c2e6b1d8fe40c507559ea7f479d3dcbc98ef66ccf6efef661a9463d24ae49893e87eafcbcd2de3918e88c5d8a08a2a4a9a7db5f0874da88eb6de6bb1dd8735ebb4ebc3fc9928ef836c4a53f970b2dd71efdfefdbe8b3df8bdd0b79260e037142af4675708ad33466a2f98e92180839520b8ee52025858ff7c1e7017d92e65f150850b4a3924c595ecea22060248ed8ebe197d0d92f14d3b90bc4c95793ef282c15c5ee5b17d4ec9eb8e21835e33d922763cf009fb79296fde28a3431b3c039e42fa7216a81988ad04b4691fe722acfd3d44305e1e665b9b774985f63c6d0af39d7380d7a8b32c567eca7c6f9a00a196afbb1689682a79433b6b662646766aef7a3a462f8de32822128c63cb7d32419d5806014aa369fda97364b9c409a4699560e8345775c6e8a811bb699a232c65d92121ca29d0ba4f0c4d93f3fe47c7a3cb094d3858d898c08cecf48f52e88d8c5f812791a8037119400f02db15ea5f17c0ef1a55ae5d69ba492ba9233894e07bb9a698b6119486d18f298007647d083d5ab322c4090ffc8f39a8edd1ac4fd3e9826bdbc4b0f17fecbae42ec5d430b47912322e980a1353668c6865f5b45aac3ac9f13d067711247d8f928900d0e05d19d8a2f51dd9b201a7ef8aa8bf678f260a350f0af1d9f2193cf1672f02eae84207ec0a6c1345302279572bdf8bbd7b159acd535f30de577df88b9a222a604aedd5024a4b865668716f3ad01b76bcb531dc4e0cd94ee93b7fec825f7c700144c505cac7b94f6d20e90f946e63d6055f617f93cf97225feb1fd79c4a73b2765a824bcc385b3b0d7283e6e3995a5f39420525b69fe9b88975e075e0083d7f5b10005652db85bb81f5016ef09cf7afcd5694776a17c1655c65989700330b19497e4b90f391ba054ade7555e1dd0e8c8f1552f67e24974acdee008cfe2d4d0fe8eb53170023c6dfb77a96fd09f5b9bacb6208b8b2fe57b54318b6dff6c158fe44d56d7a2fe4ed1db3c7f5cf92de5e3fe0f11fdff01137de90e405af95e034bcb7a7fdcc910d08647c7067ed5db0a097fe06b61cbe23ef7be6119c1a5d67252331574cf3017e98a9a6cf6c9e5a7d8554e3bf874905b682b57f2e676c1e7d76bcad275f8dbd93894d0094f3ca8cc354b973c59a8916ed3d994dae9220d24573d173550611ea344a6dee5f50161cf0b8dae0729d3ea2ae5076a63d74861d30729133b5ddecc2e1035c341a8088b79001e80ad7f385d0debf1fa5025dc0bf8b6f2112414bb12ac5a70f593f404717a2c2b1ccd108e14ad4d2093e50a4546be2d124bcd5871403efedb4f828130c209f8ffc95e645d080ec443859275df52ecc33b58897d74539bed909da14f4f7de91d5c731007a385093b52ce545aeca1e3144189c95d80e7338bd306c7225cbca02947a2e47c423c14f8bb4024a0d492673538fc5b66a55471c466c2c8abb98526da74634f74a1aeb6cd99177679f4f3c8711dc897b31df26596e5487c329c4320ad020c4229f5fb18d51e121ef2a685a1d09763bd8f66dd367545a02346afc312b4be5142ca97266db73b6fe5ba57ee9423f0aa9af73b3b8bf6e6f40a321c57c746ab9d740902d6fc8b10537484f417949529f8b01e61a4dddefa469ad2a3f8fb0d3b93863a37b816ebca6fe0456154e4c5359a60d5945a980685604d5f54fbbd97df4dca80602747fd37c56c1c2dd47053a8dae05e78458336b6bbedf7793ce46ed6898794cd428421bb5dab748548ecab96d4abc5cfe4878fc14e6e751fe59b604af93f678f1d103e80fe1214f44f6b9409dacb7ffab4138ecc3fb6076189b4b8db6b8a61961d23d5f68ecaf9ab3c73519a1c38bd9e9aa92bebcdf148638e064ec178f5c2ea570a44f7099d90313cb08529af03d207ca34175e5ddaa6be4b3a8ac2b36b12b17691dd25f3112f2adedaa83fc0340d9948fa7383a7863a68387f300bdbad9ec01f5244736c310053ebf5d5470a0bb2234edfe30a0d127453ac8825be814750a04f483623dfa37385e90d7ab4b923d63f2a97556fced3f01e3099c17a7518a94bb50e9d026b76b93759354b782af4b2c6d872b0f2092ab2650c7ed99cd82b8f63241646a3aec741241ece601a9b9f119787e2138eb8d684b17093f1d35bfdfd76263ae3384b78858546f83fa09dd665aa146737ba8f73157f524e6b588e67eb825660254603aec45a3bc5083d4f32c030f7d87d2e2cb9fb57d70e794b94a2520b15c7a94efd42d8efa0b33069adb583949081502b87b95b22f13b5a8b2d2b2696783b321ba0e251b922c11dd85bdd3262c9742f1592b557ee455e474c8943cc4f7ed0aa27f12a230a20b225f7f90a18bc8f5123709f0ef4e380c763e1e7bf9091d48b84a44d6b263136551139a72e0ea2f64c2f9134dd7905fc2456c6d518c0f4932706d844f43c7a929e604778a9781df105297a3ed69d0153b45bc57c0b40e1b9101932655debd582b810c7dcd36d0b6c71f2174705f0e2fc36f4226dddfafddfe6a76f1b6baad3fb07a0f3e975079a4237756c9b7dfbdcb8fbde150fe179783419c973ae8142b9bcf5d2f4ae6a568fdd7ab1e4a7aa80168ac85e127e97ee249e4170d0795102bd2bcee538b9fb9bb2ad430831037b09923db4ea436eb9a04894cc1f64de74ed14b78ed01f65d2dc7d4c6535190674f89a5257e2b780b6b069c96e17ea6656c65aefb7258643c88661febf5651a4f372d8b45491e663641d8495e878c40e1a0ce5ef75d04d68774373858ac75c1276c6d4adb3cce9fd0e0fa153ef9659f99b4e7e071e99cd420c7f3c6ea30d99ac4eecf12110cfee55fe73ab18c4818f15c4adf225044f14e77348b0ff40b43d03dfedd7531ea9d087b8ccebdc5c87dfda8ecfbcfeb2b2f503dfdb99ce9d267ac7c10acd714d1f25fb6eaa7336a3f2f6034892cd1cad20155074ca833f7e7c46fa6552be4803bab85830ebafcedbbe9d9c75bb245563736223af7d149819b32e45ba9037c3a158e1c8d1fede78d07171a11155bee2eb277cc993e7c6c5f0a02b30224ad1beea16321ba6a8f10d54ec6a3ca4771bf56269e4b258a8a2033d192099ce9649100198aedf041c8871a8e8bf1dd5ef4366aea10a1c1f33038e1810f8f2abc91c817f1b391f03c67ebd718e1fc5a54c5af374e54ea59a3004d7cfe27551a93518727845991e47f12a43471c593d9f5545c2e91a6941b65bd877c9002c21a7bfe151baf29d69f9ad4fd1c8086f6da8230703b64fd996c0ade1d923149ee8a801928f4080bbcfdf1bc3fabb831a4be83e48f51ac5cad466a5cb6acd8c9509d300b579abb773165f3807b7463770c31108f226f9296aba7e3ff33039d889c6fa313ae3d08fc209bb5f16144017aad908af773b14ddbc58331f5e52637a570dd8a4410e37d3911e7990653a07e811f03d4f94ba85caaade2e12e730818c9a782c734fc4911408024d1cc12075b5cf3b1d2de088f1edd506ff79c01a3cdb4fb02eb68cb60c836273724473d35c0735921ac4c163efe51491930602699dc6fa0b6d49d8eeb96e0c8e853e8901e5cd849718f8b0c6af9dfa72fbb4b021a0ada1f21904b817b20ca859ca4737a6c0eb302d9d9aad50c0c3892199bb137c3fd1e8dd4589cf1e42e47777415d3b4979527919da10327b3477b8330a2b4af4c2714f4f8f4992e08ea377dd0207030bd91d57280d4a649c475891049fba55df2371c414b00d6eb29dbbca62a3dd31960a12e58451992ad56e80ac6d55a618e7301e1aa23cb1b1258fb7572439ab2fed48e47b2fc0117e9826fc57dc15e8464d25438d271bb9c42ebd377cdca1a7ab854fbbfe5883a1752fa017f3b443912d7c0157a5ee60bbb48aabe36e8b6c4af78a9a634c289a4a7cc88e8b1c070c109447470eafb139abe08e465a781f2163ec0feecf71451ec3e1160ad22e0c05fed3aebabf381a4e5a410ee006b154a329e2dfa810a47688bbb6ef5a98820c0f1f6e7c60778fb108c10f9c0d390e2a1a982342f578d7fe138711e5cd8fdec9606006df21d665c6ea687ec6b2f0af301f97d8d6d84ef76f6a26e3cb1b68dd384681af4f75b8aee3ebcc3d4785c09eeab7ee1ef172fb1124038c80df6d0f31889f3c828de8b2f60876485bf2bfa7edfb339a0785c76787ffef1bc905a00a443f7205f9ac43ca2f63cb9fa428915be73e4a6b0a4ac9027d2bbde8b2c4d1bd133f17f127abdca8d5a97803a255ccd27922dcbb14bffdb97de71c72a5e50d17425badeee9fb7cd35b5dcc53cf448d336da906b58eeab0d237e6ba30b56fe9654428c03f9abd96f5694e9dc6e7e3ff2db9df3cdad95e0f174e212ffdbbde9eec089e1fd1698de6cb3009a637675cbd001b1273b4f794970c3f1b7d64fea646154e2356b7d72c51ffc763ad9dfa9511408832061a803d3befbc90bf1f40a2f156c4b41642379e2c14fe8da73bbb09f555daced3626f643cf182eeff775c494a3e47d8ee29edbe05b37e7a26838ab04c99c60089ced70d906254323acfeafe69c5a0e65d18a4234e44582c3f7457bf0be28ea63e64c1353e78de6f55a601c88b09ecd3deab5deb9ae6294f4ff006d890bdd1112f3f60dd8cec3ffed123f8d216df9c8b11593e0664dea847d10d32886b4c6318fb199c863f9a81d5644a12fcfe469405ca9c6f785a23360fad42628748db19c8e5e0658f7435ad85f28be4503fd87630f0150c4376e35317205289c529d239962fced9818a7f5ab5dbf8fde9468de7a82ebe294dee71ea19f2e3d29b0161f7df76ff7df2bdeeb815e53c26c361cd1964558999edeecd935867e3fe252aa95c7240ac2444cdab9851c8096e0369f4d035df9f8e88b47f3a766a5de1aa3f9f80c4c06c6a0e42e9899e82872fe8d947decc04f6b00416f318ac8d49dce67754aaaae34e88e1d2d209c85e0c39984c1f2cd40c142ad85eff188e0ce45b53ead550fbe0984573b4e3377bed8b4219ebd0a5e1e1cc9c65da1f9847fac62fe3510d4c385809080f3e0af063bd5072032735cd8be9a46e0aa968896a4ea14cf9b5962e5552a90115c1505beb5fda1bad0a2a903587d2c603df81a4cd9ae44703113996255fb1f9d00e30fa3b70e8f3a77363f05902665dbe65130b02d29660b1041db64c78140a74c535effd2aeeff5bdc81ac72a7a5917a14cc012803451fc5ffa3362b29a6ce35e6bce348bb2bb1a654bbe31cb99fc84eea504931a7e9fcf8853f5e5452a31de62f00c0bc969da35ea90670c056d28b1e0b298cf37117f73358e69c9a1ca07b5284797c57821400c4023e713a032ef36ffa95cb238bb4ba4d7fb1d59563ca003eadb9f644562d10f0031dc7f7b082166e9dda2e202623fc6fbf21d12112be056fbd23536ed70b6eb8140df37e7ba008713ae7b86c707f61293da123b6f16f2cf07679d3bfc8aefa3a4f10e30b9f1ace5a713aa6a752cb95641100b7ac4de2827de50bbd210edbe7e85f8d2087ee4992fed5d39a55f7cb6e34d7f9941ac5127efafe2b52d588e3f5c11efdb601115ff885959156b90c6209386bab912e3da74716cd100793325f42ef9375606b0a257144196cc311fd12187dfc877530319d6eab53827833d3aa6bddb750a1fcf7344298d3924c7ca40944d4fd1b48923184dd65cfdd384fc8fef354a4ac1d30e0c200875b292e96b26ef3a3ec1e57dc6d7acb59e894ac9c8cae7567b3fa26aea917d83685aa326ace67514f1d95f031c4eb5d01c4b47443f0890a970d2fddc738f519d13f08ffa35abca98abf9fe48e3f8e30ca77334a9539d15904a9a5f8d97ccb7d56d1d487fba3dca9ffeb7461615d91a95a84090ed15582ec7c1d3c141b101ae755218a8cfffa6d10887d2c27aae4a8dc27c6d04c647384d7e91a0a34cdf55599382f23cf6d75b148c4bc2abdfbdd8d04ec620880fd267dab3c9ba1e336bc152a86a46834012a173580f329bbf998269d321bae05070ad562fdb4b48d37f3bf6e04586b9b6f5720f49a73e6c5db24d82e3253b9e79b73f3fd0e240f012403393cf2260579e3d138145675d225ed94b1b2d1bf468c7784ef1941dd6ca7577ee5d2de70918d401b753b4d35450a0a3be9e44b13722daebb79b3f0ce0417cd7ea96876473bce38f0182094c56db381de0226abb9cc216ea8fe27aa915ffb1d6e7a7964fe09f93e298a11d122b6d6c82c8d3daf069932a51c45cf765557b45c3ca4156a109f13f26e9237d9d048be386a32010e1d42e11a469328e5bc6e305a0d82b3d46c3cfdddb9c42f2999b101244fd77eaa32e5f1e5c3fa45d2f73b8e779adae44c2d2dde9db120a11b5303dcaefacf24c0fb8578ea3f7b693d7ee97cc020a9254ce68ea0596dbb61757c9da66b17e83fd44e3c538d6bb3692ae01de062cfd2ba462d6a82778b246a1aae36aa3bf632a3634bf7e878eae0008b0f68919e5b799565e2123c5dfd04f51efb2188c4fffc679880b7605c7173ae81103917e291d073e1de8e516303c1212f51abd219a041c3ce98a06228be467f380dd75eab72da02ec938de16fc8574f948e3b30dd42b7090ade7f72111905331284e2c4da39b861b88cd6992b6881a92ce881c43d83f90553d52c703c3afdbc32258c1c8080cfc7f4d6fb16e5eed17204810ffbf774bfec799847a6d98b9653b4c3b82aabaa21dc60baa6d1ac75e9f9ed6afebbfaf46abf72e3fd2732018f56b7091cbf1d516584e375a2eade14a45ef5ba887dab9fbc9d3dec4456630ede0dedd8ca9d48e7132417cea5696ea4804161f8192692f5237459a0e8fbdf9303f8d0dc2d6486d40e66609052ba297c659853b703b369cdfccec7b4d8500c98c4aa8539a95cdb4998420c6040b25c5602840a5451f6185e65d67a49775905e1502c8c3f3289f28d2da2f92f59f1f2f97f3f3c8a9c62c608198488595c65f77bcf14bdf799cc357d03ee7f6cf850a38dbad77616d97c7d3b0c37fb5322b02bed1d9f63b9e5983acfc854422d18cb3547c60365f3714adaf81ab6ce0df20565a0572d834ad76f9047ec3485d91b6a73c00141dff5bcd819de4fe7d0f6d4e5d5741c9454766f06926b619c7c2b81c011d5e86df844cbabf674c13a5bfe88227b7a77f134fb372a3ff1218f7460f92f54e3f084fba8cc2062a34c93090b7d8aefd5e1d43267912db966a315ad752f07d71463f2704fa04dce18323ea709af0869b121e220a0d96f1222c0dc50216da5ab21de8ef3c499b3ebe4a54d45d93890d29fe321b1bc3817aae5fc83c720b2e73a3522470f81a80630c9a70924f2893d037f3aa161a520cef925600e275073f60ba71e092ccb129f24995cc9034104f9503e6c3e97cb9b56f6f7b9ae8377095cf0add29f6166208e7617f6bab84aed7b704ba21f2f2e49c2f48a004b55f5f888c81bdc2466482eb207de4c4a36609263ad62ff7fdb848109b76f84fb4c5c311e3fdc3fea818c3c566c2270ef8f74bfcecbd05f0cfb0909167a49d0c5519e0f80f445cabcef45f43cb6a3e5fa370b849c9b90c37cccad2a0efd0041464f009bcc818687998aa605fad4426c5d9b12f730a33eb24310b5ec8741cd401258f34a0c3780726d2f95997fea745472b83669c092b1ab0c3b93d16627042130690e7afb6ef4347712962847b1092c840e648817cc27094ffc43f9e999ba710e6eed637374ffa7b8d16197a97599920fafd1249153ecb4bc43a9956554466830d048c49105ce8c11074ae86a8ef93be19bdbffb9a90ba6bbbc1446886ba01dbacf7d27ce75d9ee4fbcf31de8cf854da16087825ba932527ba51816dc3b0638e3e5221bfd3d3bd10224814aaf56eb79cacce425490c82ccfa1de4c751748936e736a19e3a06027a49664b7bb1d26bb7fc49f0c02d9f692cd08f31ddae7f29b673c9ce4644517bea295f7d5b1874679f77cad1dd5136f06252b54b43975f9f5fce8251fe5ff993166edf48a8aaa960b74a7939b470540b052a673b5259510fd5d00dbeb30110f1c5fb31831fa5228a6f9e3b6edd35195a31cc2d78eb1a62f82ae994ccbb914b136c649328695e34f714976e6181e784b07021dd0fb9cb89447643fe45e54ba7df0c88ecb73cab3b305d22469c6720a6f5b0bc2b213fdf69496d7eaf8c147b3bdecfa076f25bf48eed03671502f6ba574133902205d1a990eb4fd4b6d390c8b4962ba9d62fd5579a011f332876b79ee229f1cbddbcd51bbb99310aded035d6a60c1ad77ddd956f6a1adb995f4218080d476ba107d0d20bf9c6385c6dd70927ed2b9654c4717e26ad523acc6f35df6ecb3da008324422cd8c37caf0737c789d9ebec48d6216057e01984abc47414e484fa197ffee0b63882c0d17796e7f96446f8696ef1a1a1526173fc1bc249eb37b7d4bf033f9d22660cc735fd4559ad5479be0f25ae75df149d5bfb56341eea43fade4ca58a6542460bd303a8ba27b4ee7775aee2847e70747bbf42fdec889356e1b98df984ca19a70c3c0e8949d394d6ae93207259a309d73790914f4a678afad4c2dfe8ab2420d3bad23dca4010c5891067b3583fa252b4d38c73e5b8c62196b9ad68536f65e2496ead60bfd406b1f177b908306297357cb8133d94760c176c5c517d8253156ee0ffd316956bd001b466b00af921b8589dc43c11255c7f9b9a46d12fec7bec423f7de7b51e98dd93ab03891bd4bc18ac195a108ae2c6714c2ec338bfa866f129180286b8ac182c207001d42fba5b8762392247bcfc0b91d25c70a34f9db85ac13a37615022323147c1ea4894e48e2a52f006c7c976ab7f04d388ff079c377958b4f8bff974fa08726a83520e9c5a776375f76effe0d80c8990bccd5b59d8edee40688c9710cb36460493a297bf9e60b8848259d70030dd858a4a5020c0540eabd3c940a042de79542ab146020fe403d6f3147fbca4b21c37fc24b6e93a590578236a0736f5defbf45d40dd02bdcc4d259380648a1465f438dce3ac6f207a4a187fee56f644fe23fe31d5a6b2e3e57233202519415301e2cb2c38316d6cbca6f9ec8384e1577211ea0c37cf7d25169b01914f2124218a7f6608c619d63b4daca0fd11c1ea244c38644319d2a2920efe5fee92da8deda983e196940468b3dfd5b27dab8025c796414d9fc810afa7ed0aa256b1d56a2640e43df8fe73c698139fc7738fc7c66bca26f70a33d5521e01b59b9295c3abdc3741afe0fb8fa88d0d52eac4689e200e34367b0e9f6cc7ea7a6b4bb411874be2d09cd0d31abb22608d1058ada3809256c5a24a05ddd30b0f6afe294e518d862d920bf1e6c9609d6a516d5cfea0f6a81dc9809101231a504a472a5e97c0281121f2cebfbc9213f5d62a92dddde1bfe433238883498152a6804c77893863436f8366b28693cb7a39dd48b4d2f1c38c3f250c50cef37eafad5bdbe1d78bf4e8863ae9b145351678c0d9a71571debf1dfa9b93ddeabce846a01b2950091f619fbe89fecc025bcf2f0f5b186593c0bd0af47f04f58096f9f3afc379de4ca5dbd38b01a491114694a0ac02a96c760d6d3acfb5c7832b42ea5d6dcba002bc254e5e92f237777c7c08a3a4f63e78df2cda73e86522ecd4679a7d47f82ea70bada1e9e9c312ddc9ad835887963938fa259b3d535155ac8759369ef8ff1f9b38ab65eab8a018ee643fa119d9570708ed21847a27a3f659573a293a73b212459f2fe7c0c53f12e851863d28465499cd9716ab05412ca0a1a1fd316694f5017504191a2a1c3dffeb466fac4c8424cc48fe25662b1fdd2c75abbc8670416aa8757062d5c75bab1ad6f9c68d99dfbfca604e11a6008f9f964f5c30029f3ed31bacbfbe35cb674423e1023f47f24c32cc6c242e11b5656d2647f110d050d2fe38e97e3df027cf956a4ed3d90a92d0ad86e6fbda07cffc39848b0bc25da664ed9d72b90ce301d64794255743c7ce785ed6dfe4a0b47d12dbf46d3383f2c10564148f3edd0d588838ae3c0080a50aa4497f197cde4f270557703d7f6b44d6972153b46cb6c0cc6d32536e67978052ff01da97e199654496c852d2c10e8f9b378e042b7a7d529831d2e8b417585fedae0086f51a2162d64711b72587a2cb567fe2aef7a9ddeb4f87946ae640b66dcbb8550afdebd9bb2a41cedf7927827230586edc1cb4603fddcd30e0a794ce94241ebf2890783141980001c92e8d972b6352def71804efc7736cf66e8960b69f4fc18dd325b9d06037259f38735f36cab3ed182541d5d3682e0167c1914d3c0e558ed2f4e90b2d91ae661388b14ab1c0786c75fe14b858fa80b0e5130cd6e200051e6ee2db83aa8f68720afe28828c170d17d6773c4498e42eb57bd855ecdde2aa97050a3be6df4a27ee763c296ce1dc99f6dfb01c35df2786f93c66dd1b15f59b481fc22500ed78855100a4c0f212c3a14149c3a88deda78f30660b2061ec7f2790863811ac28217dc515f94a6681066325b9af5e206bfa29693595080f57fdabf80f8f4627d378065b16af82a38ae7e5e03f5604d9de37d80082f23863b4aab9a9717777304da336095b3c82375cb6cf386e78d4aeb610b7fae66240d8df9581ad69a778e9d3d984ebaffb6f8ba966d839351efc7f67f4c2e4f425c6c35a285ebdd9021ec7c66b6ae1b747f557b79486efc7f01babace0e611220e651c6c1b129038a684528a6c79b47b426e28821b92e12cff58019af4a7be0e8b58b6776753de7b807562c0cc35013fdd2d3c88d2d4250d21e434413ad4e005722bc05f89fd6ba5c006d63b6e7a2814365e53d577906fb18298fe67c852b2778a17bd970aa98fcdee5fe953abdc9538d5f26d62b3e7b69f137978dfaa312351581c88f1388e0471565668c31e2a0b2261fd42c1daaae4855ad94de281dc447b732cbbed5824779daec8a2f62549542471a7bc09760e30a206a574a4e2ed757a1cad4302da78062f0732a644bf7f413f2dfc6aa049bfb98a7b2d7c5475aea32972cdae93a32b18d4c696b24cb2d6c8d3ba80523a1b78960127ed2eb911322c4b8f6ea8933c23ea3e644e51a0c185928eb67cbb2fd4c25096a946ab12e315c43d080e8e710ea8b1f76d720a5e10dde7c1a5cefddcf5836cc168f1f0be5cc81f3bc4d9346983c1880a94552095cdae79f87298a27e9a9c9484a95c2218df1d1fd969b7f7de2bab419c901de987569360617b8382e1b36a7562aa7a8bcf32e37165c1a720620747cdd900a11d1038696cf68c030ea553ece3e5dcdbb841229ae9fe15de6395a5e84aff2569f91ad1d74d510a210986c372f3a6d02eb0624fb492f5f5f80e5de925f179740aa575b3409d0db15224a0a1a6fdd16dc5553ee5803859f063de286ec745c9f5883ada467ac3ed3260c69c30193c96d74df7cda13b8c0d1f7c140b85ae4825e12787a27119a7ba9dfda93a967ecd018f3ed30b2cdb06c16c92021333259ca10a5f35b04cef1415463090297dc406010d15ed9e84c371c9b1aac041dd036f048ea8e3cdeccbe7d8250f1fd324cb7bf6eeb6d8716a44a28cd4c8b333043a2103735f39c85be1a18f9d9e9ca70570acc33e7f3d7a2aedfa4c4fb05e4cfeac16a58b75a09c51cb4da29c8c4bc91d64c7fe90106f96df1cd99f8ae5ec2872557d4c3578fa2bbfb2575ace930b08e155dc1274ffcebd072ad5db268337c4e8338b5d342869204220723f88372c994704ef99acf867ba80b3eecccc7b3bbe4e85737f58980c6059519444f608bfbd69857ed586091dd565a2c2b3c2a8d3237a91e45b7cf5909a7d06616dfcc79a085de9df6247642de033838bad4afdaef0078b0d0f28523aecf7e6786f655dd27458f451c740ea6945feea5ea12b60da8f8bdc2f6e5954215d5cbfafddb08a9b201c4f5b84fe915da81e908a714a25d73dd102fbeb42681f307c7b6ab82eaeae96450a29cadb40e007b494be1b512199f5f2933e04dfde4114992dd0e5e383c8ff3aa59d569a1ab076de013ac4ad8f0707c57a5ae1fb53a0226d5da57eaec99c00e6e60c4d333836eaf44bb46f59825a0785cacdadc2f58300b5c2cefb3c2ecf21a83f526be3c6f1e5b4e2073fe6ef654739eb581ce816f1c50222c26f8b27168b3463116a6ac1ab21c85499b7e592b17613b38242e5eaafaadb845cdb2f8b3e6d359211e6d6fca227c888bc01c5506c26d1c9cb09b66fd72f5bf50f9d2412c83f390c86aa95cf93748e962afc95efdc04b5f028f04260fb7f242dd495ac9500488774684db98d31f5d4450c93e8279bc583dd9230b0f51a9ed9d9b95f36e8f7dc01cee154363e70a5ace94f9cf8d81cb8001b764a3c52dce86f79a0847cf1bf81c25a92d66f2807295735828efd604242bd9b482920f73f61bb5066ee0b7ef0ae4cbeb4e81c016bbd3fec08737c0e79066308156ddeb59103bf1124afb430f8366b82bf54d807b3710c5877e45c83221916b7192252cf90d3c6ebdfa93b1434ca09e8372193ee6f992a7bd60a32ca8474548e3c6beaea372fec1513f87ff2cba09cc0f9134cff29be6db832b7a264e4c9d52588971c49ace3075ab02aae6186cd101249545632297e3a3413910ea6b7c45dd15818c69b1cf4e97ca74972bcb77f9848ff3b869fe9143d031b7ba33442c590acd73156bfaba501ed7f0afe2c3bbd70fe24791c7441c218f96815d0939b28a4e163ca3f30fc49851cb275f04cec955c6e7b7d60f38f265419054afbe89ef632f42d7371853d5e7b4938f97eafd43a27362847f5bfcdfd8dea06bfba4e3aac546ab1f5d4857346e395cb0b5e1fd50906a3480e02f6cc3492c7c87a8c568acf691272c2f3ab7aa2f29ebe985ffae7ff784e6dc40b03e90acb54ec2d64b2c879bbd039e7c3a0c9b345ddfeb6a6f1e0f1e0f0bda6498c773838ba47e48cc3e60df5f4d5a37ab2ec2746875c486b5ffb4d43559c55fca93c75a5d5b33b31dd7de56a24f489efa60c0e737ff7971e0a109e9295e539de51a316a99cf3541692c981e99323cfc4773ad71f1c9cb5965a2e133a1b1945ef6918b776284f7ff79bea5176c84f528c1f697f5c168efd33e7fc0ecce7732be7486f141954a571fd33f52fae37adc0478234f1ee0d3d387dce2d58fd1bd981b1139630fd479f62cd327bb2c1a5ff1c34adef01b05ac79bb010e26c30ccc3b894c9cc8bf772245112acf8715b7780d754e5646eab2e8ebdee2e18d0fc970f345e5f8071fbf94c76aac8250c87fa34c202b685ab32090b28054a6ed6e969b863c464ed78f680ad1c12b70e580ee1c0ef1b2404da373cdc967158ce485b17897b679c10c4dbf7c689e1b5e4624c66c5400256b790b75e4f9fe0129a56582bb7c4c38a1e93adff72741c5078da45eae9d1185ff904feee7217cc0bd63ab5e89e70b954faaffa47ea24d1d324b7764d1a0113ead61ed8680bd225540fd3846c6237605bc291c842df2f428d45264074352ee9a989e8472c2a8c5b2a011c10f926f393824815073b1278660fdde183d2099834721e551527624124051e0b5eca48e16040b4a935e1e4405c58f24484a0895c26ffc91a59271b640bbc992841224c64881c3014560313fb072c98387c9206b245fca9494420d860c0248312b48a03a6a68521486c0992a00906ac1b0e44e004416c0992a0092622b5f020123841105b8224688201eb4600113841105b8224688201eb46041138413c60600b900f3501002a2a60bd8fcb6bc8871a9223691be198c49c1f0819204b1442283044295420a2126a04510b0d926885b69fe8885ee88122405804ec09439030120b63bf0834262661028a206113b47794194820493cd60c0759684a62c9808b8c8ca67a4f9fa7995c1ee5585c68d0037b99a6e62867ba6a6a6202316a6202196a6202016a625ce93531ae1e8289482d32863511ae2080304a4c845daa30ae22820108a3c1d414762545448bae9f11a94b7dbfab89f403e11283f80759080040974049dfbf44a55eb45f3239b77ddd91f8c2ace920a0b3a10dd6eb52f7b6fbdddbbf86e29811ab6076d984b0558f7c085beefcad7cf2539226146898e786ec381c624ee0e086b920a51712c370bb7e13faa1ca21ddd8a943eaf260de9cabc8dda9c9b4483ecad460044c36bb15d37b8ddc432bf6fd8b30c1477b577c9299e483dca640a902b4301bc2a6e6be38424512f58ab4f4287356d065687b6f76ef63716baf7292edfb07b26e58d355f165404cf2200b6a50dd91348c2ddfd3c2c03be732e2bacc178fd2fb2f241911676e7a6e94ea2dffa2c7567ab6450469927aa6504a6de9940c316468a133a54aa952aa2689ae9c166aa8484c8191b0eab4a4e111f0890c21c1f10bab9588d410e2bc08fb2b84af221d57042e0a759fa0e2421c139662c1e444ea97b0aa089623241c815b82c90af84f686884d648c4f28a0c3c11022932c1af729aacab98a009a8a6ed40fa9ab603d14f725b573281133481133401112401015ba35aaf693b10312275a95977351320212640424c8084b804c8dfcf909f465c63ec96839fda8c29d65902b4f2e69379dd637daa6281e228f2aadf1c9bd0880a776ccee7acf65e03e55c718c1687ca765d5edaf9e3d0c753b42987923a67fafb3cdaa50d910f49f1b1cf97dac6d24011434f27993636414d9c66a62c4d1daff15dde2fe309b83dbd42954de40531fc31cd20218083ad0a25e85380a92fda1232ed71a5ff5c4f5282319da38aa6d3bf889e022a71152f729f41a7999427318810235fe60b64861bdab775d7ddf1988caaaae3d245e82c27fe3571054636b74043e5d12c6768e21c9982586c5753969fd01d9d3d8b66219c4672c951ad03b74a602d4e915d7b2af5208d02e5287383b84bbe968b27aded65a5f4ce9e9676b482e20ca7aba0cae576ade8c40bfabd8c82685727ddcee85245243e50916011a1fdf3654de416c013d8c8f78d04b76b82d365e93ba2bcb35fd74d257f19bb349d67819eed5e940ef9afcf0310accf973a68eeec3e107d5f7a4badc031e11b8c7e2e900a6bedd9967387eb7676fc32b9db5a8b9e3d3822db57269ae50b4da7754b4276cac550edba7fdcb1c9d4bb2b4757763cd5367662cf1039eb7c817095d734213f84936eec8e3702eb9e6a9a71f24b3f58a3b805dfc6bdbacb2658d17633f7dbcc28826125194c484481b3a8f57b903907d0315074c6a25a8bc6028c6b10026d3e582e115798eb7a0ae24da132d090e5703fd13089d6e269d880e857d6f96cd6855e9f53cb6b5e6341ccb2f8b74ca42592d077301b953bf25e42b80d1f534933eabaa4b8220a6db7110a7c95ff4a7ba6881e86c736b3041f777500c3f4bb706931613893ef857d09d50fd85485f0d0acda9ed7b8590e06686d462da7770072db08a753feed43233a7bbd719b8f669c6bee39c0f3358013d08fb282bf58a1fc0cba103189ff89a09fbc22fa904e003d9bd034bc045197f27d5f1ddba3e8344bb6dc4699bbd763332ca6e19b1f8178a01920b47b00819c62bacd946528f72caf6b4f641b6591db83a74b1115d6761cfeb196698da7b81d205920f60748154ffe2b2a82d0cba922b41798d1dbec9cb83f2f45875f20c9c91d14d21130a01fe582aee73b40c8e743d97394292f191954f9da4a32101d8c5861e6f14c8fd06450fdd6a44bd0d1762002343e035f47cde854e2f3931070a70b250cf874d1cc76e75a5e6b61ee9abb9c51cb7f80f32e726cb9631f1ec1c1aa8749bcfc75a5964a415e2af0fbaa531cd1dd186be5fe4678527b5cf207229b114eed83609efc6d19609ea1e1e2fe8490131a1d9508c1622bed428df004cecee5fd7b00420504efebd9cd3c16b310b5b272f09433019d0addac2430b988938374a36e3c3108eb9cd52701b45d0c7b6faff56845b8214a43f9e74c9d0058c63c09298d8b8cf15aa0c4cf78170c0ed20ebc82dc3bbb35ce5d6bfd5c2ab5543262ddd03cf532626ffa38e097e9da14c5691ba764a07f67d553d2c000641a90a0ff659552429498c4bc671d8ab218e22210c4c45aa9bb48ecb96473fac4edf5f60c717ee02c84a6aff7860b6fa8ee5105aba687bed05055241dd31eff1d171894700e17c196301177fbb30dde1f3b02f497d3cf4eeef7444508a45f06d3a231c7f234c8dd8cbdce5cd43383f7a127b57c7f9658d9273f927af47fde6dcfc06c32aad04f5162efd14ed0ea10694632dacdb755caf7dafac9d220021a4199e2fe6d10a51f14a7064fcf98ba7a87db6034c41a87a20236fceec4d0d03c9851f8113a7054b6455f7ceaf044ebe593d0571fdacffe0d0ad99bff226d2a0313b793973af41b7a2ca183f4dee6c0a8c9a0c51a19fde4ee6477b5b1703362665f7474569bd57a435e68856744e98c20989187a8f8b24b5e2b57ce0c65e8d785433fe66059014138c148fa099dbf6df5e5b19b288468f2bc762c28e9687361735277415b4dfd0093b2bc8d5e54baa86e4932ccd7def3a686b747d680c641437d9b62dfe4a70daf6cf6f10a1d810783bdd0f17630d5173e09edb56c0fa9ede7d3be81aec415fd2c1e239c9cfd789eac9ff21d7f314306a7b2d064cd3431b9ad9db1f613bf0f344aef7a9c570725fc40ed9131eb5f92d1e36579b980347703d636c190a08677d57759bbc9930cca4edad106c09ce27c28602398fa4101c4fa2996b856a501e23d183cc2ff38cab8100dcd50c21184e82942c0e37a35b45707812a1a01a918c3d532106f9721eb724acd4e30a6ac18e868ab76559ed6c7024dfcab012e69625221d4115bf839747d4c638e127473c5af0fb464b8e3ad986d10bab651e451bc1b8778aa38697e271320db67231aa22ce453c581107483375eac194c25f0b8c9f980e9237bc0b1fcf4c7292853c1130630337e3f551632e038deadc65056cc9511b0f2df8b1edda3bc4460a7bfc2fe7764042702cbda75245d6d756eb9df1ffec64c32c75d2feea9737b8edd50dc50a367ff917aded7abac33d99c2613861d6f838da7b0d5251c8be620dcc9216b5f719f1d80a4471f1ce87bbf9735b32c97eaeb961438ac7d02e188e8fc7c5afa1a5fcab3c1bd31eeecc56ecd07d9862ecc26a7b338613d2f49774060ae9a043dd528af03963fb6618fad0c339603fd7614a1da3753d2b0b098623a4f6e2eccf53db0b8c2efbd44e5ec787edd9ad4e6e81a720d2f588d7c17e387714080b39a814032961b2624cc6cbdac9853ee2894f2e7ce330d102c1f9ef00bb33bba83ba3f3ea3ad33413fa7b8997eb53b6c31140eec2a5d73ce37fd90153ab5421cf03baa820d4ede4d29f132fe19dd7d7bf817c607d4be59f420b52fac162e08618ff29e88a35ac22912ccea897bcd4fca153ffd99ed7d410924a0d206900d4a701b957c3ca8d302415d2e7508b2d7495c7b21051e4de987edf51a829c718370ea9e367c5eca5e383a2e1b8eb6fa103f8271e1d5b569fccad237e80dd22b310cac967e0ea547ec0fee09f40669ad846effee04f63da94c812c0c90030c4894b309b29d2e7ea79b4d0615fe5dc4eb9bfda9c735082f11fb48c745878dbb3faddbc06f0ca9abd0f6382b078f378c9e52cde6c145ec289385eebea50b98f4beaf6969339e7ba31523dee1a5f94dc8a4fb3bb3ce27842fe1a8d59f9b980a498388742b2b7dff0aafdf38a8d95f4e1a81ff10de2f06949b063e5926991ce994a711669dddbadf428487defdcfeb0ab88deb149e5969fad39fab4dfe8daa8bee3d5650b067e05549b18d533f7ae5448c27d890f1a24953bb800e6d01845b37d0ab6ffd012a423f064ccd34519fb94cb14bab1be4239b7b9e7ec9cd4b587219e1e701384e4e26147de92820316d763cd021b0f59c6a4cb70b54c42e3242db0ad5c42733bebaadab575347d9529c391afcc3f7c7d2306e617dde21adbd8d8d9fb5d8ac9838d020b1113cbc5049382c937aea807fb9c37a62318bebf27ac4adac5c8a3ff054a09def17c9029ef25efbdc22533fc56872618777fb712192f78f56dc180898641f9b15837b31393fc6f0b5dde8261f9e580d8663abc2b769348a7c408738b8f64ab19e3ef5e8e017eef6942681995c52e25131d3a4fa38127974581c8b7f3e08f892993afe8e740ca877fb808fc02b533958f67d51b33fd193e676f413b9c35f0dcacbeaa17a9ab10d98b6ee115995a6fa182df4d969077541cf36c453e667c41400d254ca814dfbda0e7447f0899d3560837a325da6055934e2c27daf7ce11c78e5e1c0b1892c3bf44a78f878f742b55ec435add508bfac164ff3518bad9bbb23a7021026544b2d5f5fa57edeff6bed067a7e96de55a33f0de33c38782219fe3ed56f3ae9a50586bc13936028e979b0571cca220295f7b3f0e236ff31efe6afe9209ec10244c3aaeadb943f3ca68e726934e723ab2e5bb1a79c37adfed7d66f0264f6133a04f0507b44a29f191161cfbf52a9da4235f837fb013d761d66c318720615905ec100e50f97d89c2c42c02e46fba3f3b70b5da2f508d743e0b51e76da657ce212f9e5975b31db1fd1e3b28059de36826dd21f33dfb0436e9d8ed25a11b8e5006cc6d1341004d149258ab573d97d889ec2904bdbc589cbe4b76a644dca857437a9a0f4202d2287ac5dba546a071a2f66debc557e265727a87bcfb7bcb75ab6d7bee9176e0e3a1044685b7c42d0d925623dd48e72396503991692bcd12622e30f1698e1bfc4b3c65c981e36c5ee5d896fd02b8b9ad958d52d7c4cd60130ae28fd1190fff33bf6a703a009fcc8229447c63e678fd01d2e23e1e6e598c0fd39b411c26d2466aaa75cce56a1643da4f28b3e34af3bfaa2d127712f7a1fe11a9ea6679c863be07a36e480890269196936a09b429e8c82f60964828d4018cb73a4cac3befe79b1034d97a4b5132173299e515592dbfb4751439d483ede58defe98f8cc2492fad3d8f165ced2f6531aa0cbecb408b375f61f97511e63a196f90f43d97a92c8a40345ac1ce219151d6721e6f02737c303acd6ea783b7f4127e9ff7f72a44137e6eb40c768877c11f35d047e90beacc2f4e2eabbed8839e6b8f6b063a6afe288f858d6984e60480741968a429a4656909da2c5a34b2db1c05e52e472b5b08025fde1badec8a3ec640ef3a46a87981dea70545679a2e38f3e2d0f8b171d041228f21ffac70307bb12ca0bb27fa4e02938b1903beea10b4f397314141f4bda1481d69c275c2400e0906f1e9cb365e3804da47b278a68901e4b8ad459cc8327de437b1be80c889e6614077a63393bb8e31759dc1ebc3959908e3b31db2fc07faa0f3191935282c404019341e7c61556f9e4b74a1719d7b6a7f1c3835b94e35030215b58c5a9a25e77d7815613f6dc920387213a53e119e1cf2ee415c62b41bc6b9bd9ae89f6af73fd6b5a1d20aefe251d010b69714c0e4fa91c1ec85025b8934eb73f41cda33c5e9c8b730abd08ea216ebfb624ed000df454874afa8e1d36fa13e45b57a46e09271ce8afea1a273adef39a2a33566a46f6903d9311f448c0d0ded8600f950d76db180c0881853f0d8a0ccc61017cb33e2cfdf01f6c7eabb9847ae8d0d728a443a7208a75357392820ba5cefe3c6f734d1523e55a29181d772f6b434ed6f4741964b609358c3f1fc4f98bed55bf3e901506393d6f65e927dc4f63407d85d5da1b82f55e653ba0eebe6db6330010767afb42492011957a41334881cf30c5c7ddee19f0c18842ce8981e65f9401607d950bd8d8f563975af3a7a8cde50d37f712c4d904188453e7932b0093ce5275b50568d5c27da592fe8e2d09a0f1558f392a9fc88ed7d6c9de86985e9b95884626a441ea6b78e6dc916c6419eccb816f52e56b7f6bce289e4f08c7bf8deee56fc6fbba39a0423dd085464546f4ed5bf280db0df17afdc8386d575df989f3d2542c074c6bf1edec7cee19b3be015757c9cd2e6860de58e4fe11a031f5817e1332d5fded109311b2569b90975c5844168ce4b098e3e113fad6f6b7804341e2567db3e3dcd12492d10826e3ecb9c4c8d50fa651fda5c137a0a8fca32a7c29830a8a0c4f299ee2376610813b1750e7d7ea96e8181c666652fac978f37e7e24986e483daaf88ccc437fdbbddee0ec2b498743ebff45a3e5b1009b7b2a1cc253d8ec394dcf6a9599f4b8be627ccdc5ad5f33c101b0461535a994376f69d056d45eedd3c1487d708c8a1617c89bf32e31afd8b973b5072a70acc714f26fea54145b778d8ad932d3178aa04bb0789509e436c383ccce117b0bbac67317cb3eaaee863ddc5e76d317874deef19fcd69b5ef3f962035596120d8c040b6a31dca9f1c513590941cacba3f01347299c00a2c8e66634990aa75876e7a793b5e11886ec71a7d68ced40ef9f73b7152e200b085f77c48d8d3176e8df7073912cc8f83919609b2596c4f4482a82232c8ffdad5dc2e6e6503899a5930e2704410147052def3476c4044000d5c2d15c0903816b4f5a1ccc91f309879af2efe264f761e4a9f0f0ede8457961fe6a966aa519ea411e28c1253718572ac3773896aecd7c18fc35f6c03068e0a0c4c5e53d7922b5c9fa03e4c17a5ca06f3b2a5d235b8a0f2479a69fdcf9403f3bed7b999649e651cd5b2724882dcf2814108b59148006589b0cd13016ef4fc294e5113297c614d165536de3f0fb1c190c062420813b8fef543f9d8e1ccac2efb666049297804b5dec2b9cb1359da5b3b9e4136c15968e55a895152378bbca8f360d774f36245d683eaa95b1466da54b230ebcfdd069bff0c9a838c80d3bf1a1f15ceaf1e868e78eca083289570be2e411fb40bf42f5691590caa8b3be61f2b14200a438c271a42287fd27ee3b42481345387d68681d9945dc5e954cbc94b0ae7c7ee5c2cf35bed912020794afc9c54001fe4c8017f7d392e4ce0924433f915038914e177f53db3e6b59dd28c735deb73c9be92d5ce1ae428db4006ece87a0eb50d7f356a62f295f27f02a02a06d57e03fc211f5f6332633f525ef85a2e11fd2040c7220106093874f593a9bf266e5fd3c9e2dbacf3a5bd0d7399115132c78f7d8f407679fe8ea64fd39e6669e0d9f70211f7bbcd6a02f4f4d43d1d04cce71379156bf514a40dcd694d1b49aeb787b882ec199dc5f4394a2c41fc27730dbbaa4a59f6d3136314433e3c4d04690268eb48a7e007e5006e9d9f0ae6245c5eaefa1fed12d7efaad074cadcee5a5773e9dc4cb985b16e582a2c4d9735e188b396d0514add2268a0a5a0d39346af65c6206ff63ad39afdb099b478de21ae832aef1ffd6c97052f684109372deb10b1ba51d15698c2b85f200a98409d2a35bee2e29491f98591dcbb49859489c4e86f4d79c554a08df686a7c8e3df64cabfc8fc6d0bac8744b680ca97a8ea68613d7bffc2a9d838dc87794cc42e97c83f575c5fd0681c573977135f89102b1b82a43b076b65025a35a03833a07a51ecdffd262590b836323eabd7c601764f762e591b2bc88cd9df8b3336365c55e6715a24abed67ce38cea3a12dfb00eac5e8774ef75d6b7a25c1b3557384145d1760e03d1881ee77a47a73abaa3c4fe2e1f0ff96416ffb62f490f55a063ebed12b9b614d0597892ecda72a6b24575ba049eaf85528be617375be59c1d6ffb44d7525af26f8ef4085792e2fdee179e4d7653d2986d74b37554986c9cbbadea1ad4820eec68fe4b4db6e925f310294a4c1741bf7efd573311e84e43d12de7f22377d27efa85e163ee047c8aa9aab555d5c9faa84057207724f04ac3ed4d769dfcc532cabc76d8de8e73f1f7eb0734eb8b6b509de10d9e93552886f82ad62a8b0459d3fcb926ec1ebfddb2026b9f8e9f66c1570f0475bd6f1a925aa9ee78f49b60cf80f07d6c669e416daced53d2f180d95fdbc966a7508097139b1f1285fcf5d69caca4320b800be1af6110e8c0fc5491df0b9524a815adae5c18a1790f82fa19dc2840ae6e7281c702d53ce0d44240efdc8121953f83baedbf0379249cc03665d71d53dda9068aec869935d22b603e69799999931f83b543998e7d633b68b108aa310a69e1acfb7412a14863e7872f209ed559848d7eaaaf9bb5e3e3e6adcb22801607e18938864eb21b1bfe8b3623a83dccb6590dc22f5294ce18a4a3fe53a0dbf2f18cdf940789fcd2f1a2ad98e2fb0330d08df70776399cfdbe5a72217a19215576ac71d8473241546410834eec85f846fa49a9f69f01c6b147608cd4abfcffd8351154f9cd462048f02e4affff003ae998a52ba808fb332dca6e85e71b0038cbe2b6b2cb87d656fd73a3eb9e6b0b02987af53b7879578b060ba53147eeb0ae485a6442049f418e36761eedf37daa72d1f92d526abf509af9f9dda1336196c931abc5c7a33abeca8f78efe2d94ee4f23e11f70fbef83c57a5b9f94ed021cd85499ea5ee34dfd09b44ae4a6035fbcbb4ac9da17b68ec92aec51b17083e8fcfebf0cca5b5a70fe69c0ca5ff8bfee67921034c8f5bdc66cd3c21fc49347cf4f7b9e34fc148def62795c96a4738d52ae1df93e9fa7fbc9695061f4be8719a8242b78bf8f3c5a9a745428645ea9785f60a0dbcc258039a4eaa8fe73596fef53c11cc7733714f06fe427c82ca0107bde2afa6fbc58b6f96304add20e69057a5c4ebd2e6058acda988f2ecfd6054c578eb7a1ebd3cc059bb11ea3c8cc425e1395a8f5804cb4f7c4d67c201e8b24fbeb13e5737190c8fa1f8e0da60c68bb9b28fa1ef556b0efd5bd23fab0a651096aa638847ae2ecd03b9d3d46ca27e7374843a676f2130b371df2d7326292d2adee09a35617c6467f5fc4bade80fcc606b6a52833906a9fb27f2b9f0cf35b6090be3f87286203cdcc8d5afe0d68c4f143c94823c562d95c6458b864fbcd65e5b0febf5b37e9f01e524e9a6d70ef1009abaf1eda8e12bc29e61382bc556450bacbbdbf2c7d438c3fb3953ffb8548824d6bf09ec591236abb427c1d1a4023d38b268fdd19ac81b9f74428ecf7e91e96127e3938151c8a6e3178de29cd6253341d498d6dac205a14a41d998c8afc0da7991f97af91fa91b0e1824831853edf8a1ef7bb90c05c9ca040f5e85c3c5a85f5426c5d0b7947317a835873c05a8e40cb7f3c06eae0b3a7275ab25605d93a25339fe174e182846425488dc2b22b9bacaf65ccd2063e5f3c5415ce04280eaa8b0f1a7ea519c75c0932e5aaa6199bdadd61a8da55b193638f8941b7dc45c6768b938f5e49d45eb86d1168bc590126be434a910339a1a5d51eb06cd86dda0cb9619cc7ae6051f424b0fb08c8b7f1bd4875672a2edd5e971f992adce7170ed1faa4d55bf35a70d18cca6270b4031e352c1f5241bf89f1f11740fef68dc45f2d24aaa4d33834c2b286ab2daf2e1f30ac48e43fc6089112e367b7d640168397f9dfbf7a541a6d42de96ef2c72bfab874a703fecf227260efdec70871e1eafda07e872a76e3e84a7459d0efa9c995a3e1d48c5eb1dfb8e9d7efea06ca180dd2a9ee39251d5d8d4fd00afe2c6bdca0ba675f0dab5c25553da6bac0588bf97d08198497f23b97ef980b83e0a73cd89320cc93d365ffa23ddfae581662ae56d57842f865184e11f073c56daf41eb30839fe01ebc3e4df0e578840b8545fe1797f426f3c574679d4068c22a6ecd433619cbbe3144a3e856f293c3e18911aa1eff8f52822db5004fc3380cb79dbca7eb6f18a2f8e8546b824dee0f044d00b131e559e8b9b285459a9e989d0446879fba12afbc32be2a21fb670d38de8a908e60a56fc38a686043a11e84783e46208766d507eb9f5b1c4b7ce018e6356d76bea0c6d5f1bfaaddf65b4bb1284338fd643dd10ea5137c3e85107b86379867c26dda8638196b227c6dfb2dc50f4cb4115981ec71e1f7cc70a7a1c2ed7388f37352744859a8eefd298906ebd2e3504bc9ecdbe39461edcd97b5e59910560bfe2aa6c56c30bc58753fa1a8d15998c5cdaf08d64abbf84d8e89cd5b725e93f7d19c76d913ef045ef80c44c8228da4d6786524e263251ecef40ae0d86b8a5d3b4926ff9ec7e585a68cb547113a7eb119eb29a86a0e0261aafeb1ebd943551b5fb46a65496f30870e93e829bb8e9bca0f3a3979fe06c4c9380f99c5507e414ab8b5fa9a91bb9ebf6b5495fedca31b8b8d98731c4d24c93ae02e5f528a766272089fdda6efbe035dd97c52f8c95dee1954bb330a1ff64dc0cc53a4070daf15f031d85daf749a17899a9e12dd1650f6aaf8aea927c0748201906c938d00570908ca50e32803d0a8079665b95ae9b069196a3cc1ab2333d3fda4d16b900004ce6fc9b702bb75f7d93543de23c04d92c6b4c6c0a0040080086804a40400030a855b05cb176fd97e812f38db244e6ff4c6fa795a2a458f0cbcf5d12fa692f4e3ce171019517f52edac1d8d15cd2231a4b3986d12d7bd39be778d17064a606483b5671ce5665ad316bb60d49794471bea91ca2f3cbf796a01aed8ad68b930a2479bbbeb48209443a8b51b2cfa3c67682d6574bb88c7ba92a0b6a44fe12a13f63fe1058513d5f95a079d89f40d07775ddd6013ab37dc8ba9736acdf46ccc95c8508b3290dd8ffbf0b7a335f0e4db9a22fc3b0c7c0c22e4a539ef18e676da52a7b55a44622664ce86622df2ae31330186bb5d53fb08bcd36f9c21e30b351c62bc2d2f297a54d3280beba82c26c176ff6a9b13d1e3e6fe6091ea05516c211f5b57addba9720efc7bafc8aa7de03e445a35536cfde9692dc9146635036b66948e4c51b7ad23608c8783dbf3a1c5384aae0034328fea22b7624ef3456f1cbbe3a1a0acecc507b8cae01ab1c7b0d9542dbbca11b306c7665d53c19c8a345805f14d06a218ce47f2c9388f10364212260d32365b8c991f8b808fc73bc63b320db340bdd4560560e22a322deb24c08ac29d95ed33084e753a5a377bb540344bee8aa3f529c5ef1b80c7d9507cbe140997e579e56397df68b5d47d3b4b69badfe96e471b81845a62ed498e3e702f3ee0e30e8a7fb626890484e19c94cd96baa7bab777db19b0e4cf0bb16b9bc2a181d118e47113ceec5f5cecd7f815b04a17bebdd2de2a5b25090453daea383c1b249c6d23a6ad595834ef340c544d1435ed19c07c7d7881e3ac1edaeaf0f0cf7505bfee3abcf842c6dc3ab82252fb9134ea01e6798a43c7b6afd72c01b1b2c616d0ad5b5ae4947ec9fee1cb5e93173098c50270ee474100e98daba4430253b218d16f2930a362affff138f029df06921024d1f11f1f55d15bce51f6d4b60295ea2e71e636598a0df800a56309b9827a5bd1e6877ecef78872b06808a9209ff51fee7d4d0625cdb7ffd1d9dc3183a64dd02bba55fe67950874d1ad0588ec1dcee45b7120fe2341c9835e48d0efa2e2163d6de43acfec63eeee0959cc0ab8b9493881584060cc5679179ae01ea93534ba87e26b34dafa9e82bc80f4e0b9f0f3461979c56e8acc877e4ebac4a44cee5d483d0fe0a13412c27de8f10c2d44de6d6b476668f62897a04620abc325d2e4a3d6717403c9e98f77c1d32fc388dc08613cefee761a7d96447487b83394feb68d28e31102f0badc19760a34e095a43bb42bbdf6f68b183e7ab9a22c8169e059f625095aa038df5eba0fbc993c16e552d40f5fe27e6bc8f5535a8dd71a4e771b2b8bfdeb7238857f755963ee893147dffea0b12d6a215f57d07a6201c06e553552f78ab5697d3ea9360ba84869aec1b6c444b3ef3c13fc2a370763d7746fffa594bed3970185b814f94f8dd10e160849418e8c15798bc85ac9519e8e8b0dcf1ab9a9f4362499f510c24d7d6032a2d9e3e8995cacb0b953a7ff667a270bba9de7aefe20e3079511fd9574d7694a55b0a88e51f78bdfecbfcf3da078b92583842deee043bd891a0ec7d5a31d1754b5e21e0fa3c38fad61fe8c5e8dbf133cc10667ce04505f25514322f8e4aa04ea7ad509e7a81c9fdda76c92fe97439a432d35cbdb324ea86005d39d7a9ec6deb3a49f03c902a933ef2dcad2eed2356550c97e85bfd87cb14176f6e268164545a076a6601d2f5fd3e46e645937a0ca88bf8df9e5fb44c40d3cb0ddc768294ed2dde7ff57b688c2f2b06b494b33f8d53170ed6f6d5d96c6fc269e6a9ff4fcab119eeafda03e40d1d5242a99d6f4aedf494132fa74813536c80d0b5d7d24d7d09b35dce9f7e3806dac96bccbeccedf02141ff7532a9706b89228ab483cac80c98fbdef0663339875885e4049250711a87fa89890ed6a78a229ac3cfadd0e09434c54df9ae6dffb350ffa4847bd1cd429f23b8f6418bf4bb6cd2845ee4d10eef7edb33202071ac90afe86e1f93f44b4b0f533fcb7a791fff4a7a80c37b5484ecb3878c493d52ab131dc81f6bcdc575123511f3bfe610366bc56adf08543853c5a2d1c776bd28c9f1e1e09a2eaa3e45a54e90651290aeefabc11fb0dc019cf52a490dab54b1aee1ab63d3b6ad5df1af3ae957995851caf343e99e72209758bf71e0634ed6ca41e0e25d0925a46a890e296ad2817c614ab6f15b4fa7b2c4ff636a8c3b24f61b55996e364ce6934e2874fece1b5cab00cd8d2fd0436c79421ebf60e21c54a329550a0d76b1e2517fd5e4d77cdc97162b9d7fc38b26f035cf965985b8ff818c73490001ee218afb9970f609801fb60dba88fbcde491eab5c39632c7250b95419f56b62800ed79ed6fd38cfb2f50162ced6fd751adb488701066ac74222adc395736559192f9904213f41db701e506be94846adb5bfda63af8b2783d2ac35d9827498a96e411eac3fad739b481c615270f7058b23ad476626c4a78b018bfda98ef5658a9c0e7afc28efb4ecc927b119cde0237da29f071011a60dbdaa30bd35675525420a20e5dff7f443fbaf0eca8f71958ad1ebd4ca53978bf3dc97dd6725dd9f1daea22ec9937744c1e9bc7952ad50b84f3c87df8abd492bb1c1e1baa43314cb878bd78d854454e79108d979d6482fea937a9021e7490d8183fada2d9826c5ed4e64abcfb841184678c72a65040fd8c69a6f46a69eab2fa9a469d4a2c0c0ff9f12897768b8474c370c8b8014f0d5dba990038899754ead0026bd4099ba2f069cb4d49b47f7036b2e9ae56aeae134afec9ffb7f7e56c52f5c008d494556aa464f0d601d5bdb9f9869e1d60062f7e3ca6c79afbb26def9aa176a81ef582d872be466269896795454c3aed9b5b0b991b54cd9ce03be5893a8e4299bbb2b86619f30e0703bc3f8951d772191c8be12dfe263bf59089ebbaeae328c03298ce8165f8bfaa22a1fc7c28a229519a5c322411a7e53aac2309635e82b2ebfcaca07ffaa7ab991c25ffb258fc866e564e30931fdfbe90903196bedc712933518c1ffc4384d27513cd8850252210d551dc0fc43840e437de7ec8ed4f65612b2fe54ca8c085b0c73e217ddd6456bf0532aea1ae711bbecafa6b055880c10d03a1ff40f074f7bdf18ad364b8c97f9bb297e6719553287df6999d70d73c547e952722a4afe9e17cdb20dc1b16be2f22ef4344abefdd2a7c7c840e7ef496892c4f9a8519d28ec0ec94b20cf832f880d2aa8d85aba9e854e415aa14b31c996016bc88d0bd7da8268b592bec5f9fc03f9bd1f92976b5f0ceeafff051bb4a9e6e125f3fbd1d92284d0eba8012a52cf5195804084214a83b74568e7b9aba89ceeb7072797c00d47608add560a36ea6c3d5e480a5185ee78d842666517c5758c11716bc294d18e1457a44e84f04b4752379cab6a8f3cf4955aa223e229ce830a5e7c8c5c70f106237f45f61ff8c5afa0f2a1059f3128d9017dadd2245e1f0c01a1c1b91d494468712a8aab0c3e55448b7fa0ab15416eaaa6c96c982d939155e0a873595d68883c3e4f0a4e57b0f632cfd56e311a27be05d77dde60df96c8bc0331db18d2a1c3b0e9405cd641d8b03f40f38fb4921d35aa294baa547e35449e087f4e2e8838b719ecadc7a14cb0f692813fbafff929b7298123fcb5287614cfe8fe252be4ee4093c3f589d2c9fd164ae63badc3722698d498e2e95717909495c5dedd5e4c979c09ac2103eafc4a91a4b253fa32682ff43a31eb4929204611532ede8c3c3375a8ac4e7c05246eb44a17742a2808b8d1fdf3636c8bd2f71d62aeb0cab75555173b780c893a2a3fd65e271c6048c6b14325b0b4b6fea7a57ed0345c998bea3db17527200572e3b9c317cdb1e0f80358815884967e4269067de16db56ce61e8fef1514a34c26408ea783600bd90eaa097ebaacb5271b04bac94d240e5fd80a00297cebba84e5bd5837a46989d78e0bb7e78fc20c087c06b52849ee199d53b9c1824b3638521d57bcc3c87061a32be7b6dc1d8e7c7d33fb69779766dbef7899e5744eaf22c99bb535632fd464e65192505e02a82f9bbb85393052cf605eea22e950cf8e4be03e18f5e4299b5ad98cf964955dd2d85c9add8e6eb2dc214d8782a0cf32e84ad3cb217a839b46fde82015db3f879b68abfae40ebf91fdf9cafcbd5bb3b4f02e25737c065fdd78ccb1431036ea5087361766a79206e89d4850be1721cb4624f26afbc234e5a6df4ac9b7cfb55016e613f7668534edbbddb5bc604abd48a55a5809940fe538769b6ce0963c15432b54dbe2e82a022ec462d0800f9bac755e9f8a2efa2174662f70fa549230105d7f1bf595ae46b70ae186087b5ade8f05bd694e632e6aec99c2652962fb57ca72500e635af90221cd6e16bdb91127b1c5300b5e8ba6a7a6cf7469d7c417aa1cff75f425d552f3ec3e66c0d70d6668ca6a0484c7f10f0721a3f2bccf4ab769c6b397917b4aa4d30fe4be42617ad6e2df0eecf10f08a0b08e698660ca3ca36966ac2e1e2989b9359e1647d77c0883ea3ddec9fb12c4f52d181c35bf5ca24681be64cfd945541e49d151ed3a906c7e2f9a5c30d805dffa6a057b2c8f947bda82935f78078967c4601a4d4a84670c8332e8d702b443316e80d43c8421d455ca41afd7d4ffc655edc5abfe1121323173e5a541a01c8d4442b3c4c04b68918fbfa032bd9bf499e6ca3bf70e1613c727eccee76ca8eb6a6a54277acb72c5c1f356c47b5e03f3ebe84bd4decda0f45f740439e6c9475ebb829414c421446096a7b7f5fd189576e38b92532456c9a5040841dc4a66e1679e92491061304cc1f463e1d11c73a2a6b10c696f7a4dfad83467df981dfab3abbda47d68543760d447e9183d2ea2b2354ae2be5bb4644a27df743f068f857e4b7f7c1dc90822d22ee1a7d5c04a460f9892ab12ad0afa3ff3f83d3d5c2f817229511fc2b4c60910240754de70a33475fb7b342ff21496ce540c240ec78110406ba4eb020000c0c12e5f6a7c703d6c2ba9aff8f54d67c0bea42f3d36d11cd5f074f34fe31a38ff80904d82bcde9936634e71ea32e167f268c747bb1deb534beabeca102c1dca4f86725621cbfe085046f81284c74bed6e47ae1a3f52bc8c21a4fb93e10948f6babbb48ba4849b5484367245215cc0967824ebb3c44550dd52309c4b8cbb8360a40b2b58d86de52bd2f31353a3cf7dc9d8903a1e6bf899149b7309b6136a6d1272e019badb87ed0897073a2e7bfbc5ec7bc039dd2e5b33d7b1b1481e2ba0b9dd317b1c6d46afbea6440a12562e2233b8c23e21806059f790e5d84e4f1a7971a12de56235b9b484c226a818a43255b41bc3fffa6fc582fe145ac57a518caefe9ce3180dc196b7e97e545bc11a16b782e21132e833c891708d24314a9bc157af9fc5143dfb4a74d4461ae6ea6cfdd2e85ae70b504f42bacd334be87b8e71fba1011a2dc7a74107b78976a7b3fe24da1dee093f45449e8327eae38d0f2d4460be47453dd72eace13b0b1bf45798879c369f900ca9e583b9c245a32fcbcdf61e380595f0afc2690ba266d8f77be6811627aaa1442d3d2b4444ceebadf1767485d0edb693c827becef67f5aae06f62242393ee6fcd7d9933bb873c2addcfd7338b3c6a5b1574e27e35f831ece955f7f6fc3ed74ee7fd256f151fa27fff215ff28d9722fb298a2713bcf9979b1caa0d6119b48c5ff06b82ff25dd18662dff097a05e996117fc2071bcdd5460621d22edb6b1301e9e7b1d6f3eb5c2d007437e21a304f509ca8b937ccf53da390679d82d4942f6f7847742d53adbf87c8c775ff76bcc125b747f0c9745500855318b0e0b83a4060cd049fae697b0a149971952cc18e9d1b2ab86e6254351308057eb5bcef05c3246eacebd6df6041c5801d273371ff562693be76f1f92f69741daffdfc16dd3a8600f65435bcc38e82aba1bbc5bf17987b3e2a9a1812dd0e020abca1974a28a328c6cb941f0f4ad6c432caa261cb297b7b67a243372f410a1eda19a3aa7be3714eafaf3921c14c33a068b3533d689c88fb683e320a28e3405d9eafb6cff59a6181aa4adf84ca9c1bf8716ddf56a648944e235761aa3384a3feefb39d0ee5db935f43e64470c331f1da0d9f3e96d7894eef9ff80d7455c9307f7dcc84fe39d10455df97297ebf07cc1b709091a29373d39b7555fceb7480b6a6cf7df1f61768fd198bea64310498b7c017b4bcc73c47a80bf15f3f99188d61349e1fd3a34f9b5464fa7c3fb226c83bc31d5d323dbafb3e81298934e08f5859264c92f42dd47ec88decd1982def4bd9bcd5a1f5adcb30c7156ff9b3b46a333ed101b1458ebb739f3990a84f6535f2ebd618e474afa477106a7c83790ac6dfd9b18c75a0e3ed138689cb69f0d642529753ab42df7df0111ac11e5b037cc3ebc33387804e671e67a15891d699f692a1b4a74ca145503e24517014d7d0dbe1aa272f3e42fb335d6eaf2bd27c223b8cc761e81bf5e8bfea727602ea14ccf75f924431202531a1fd7af1465a455703f958fee41ab8e5d776a33f9a8e93aef6e395b4503634897c166c5479bf09a932235d09e393b1f96a62f0e38cbd85e7376d1de435b95a9074c0b998cd0cbd9d224dde52e4d3aa8daf679b8b215b7f03deb1a1e2056cde0337065ce1bcbbecdbe608b9350e73d11f26dce7ee714846ef67ac1ca83d79636c7544dc7b3153471c377ef6aed90bf0e01ef72f7e56d62210f4eaf2ec0536406005e94131f4c66ce018d017b742b6f96bb85fbfba86638b33982d33a29eebc56de12ac4e36e3f534beacfa58e802fc83a109fe0044de271f53fab00ab964ae90469772f353fdea01cd3de84df7191d1de11582e79a67a46c22c066b1dab96ee9e2e4257864766a5429def22cc66b0b07703404b4ebd446414648d415cff7af000785bab88bc5c71a85c3f9b2bedcaba8d83d4c65d8d3373e941c07c7a0fa427dde60f6a37ee3e4fc1881370a05135f560c2bf5861dcb1d73a72d5a0b9ffdfb855e2209c865281dafadd0c0f201ad2d50f6f31aeb5a52e41cd5ffd0b8bdff04b7e5eca6b7d8d3b152b036d885cffcca6e9e2a7a149aac29d8b12c0479516152796bb1169978afff36feb2256de1e8f43084642a7abbd122b996a39e30f3feaf5c464696a4a6f5c7a82f8fc6ad3aa2395005cd637ceed5712e62e07e523434ed7263f84f53ec7270ea2f7fe2539a1bb5f8262fff611c554b91e21e8e2c1fff90325a0078c468101bb407ba82d4ccfcb8758795bf33eaa9525fbaa97971865d14c1306c902f5bcc05a22e1dfc4e334824fc5e0d21292963ac65d6bffa1a0d15c52e6759cc26d4a13a2ad3a7962f2572d3a0898d3237d73fd8ca5c574d5ea5ec94dec13f9e28d4991aa3f1d5ca014e1938dd562deb4a25da222301ac9d5c460a8ba7a1d1b54b777aed2e458bb658d29eca31cf306d7f906d91bc78e7555ce3a44b873eeb2ab23ccf05e2fbf1d3dab0dc154606fe469179879467b1a0f3a05c4a2eb76a813cf9fd293020fb9b831e48fd295d4ebba05a98da45342f0c229400884d1d0f1faf6e461d16996e1cf470b7dbf5e97541bde6b9c2ee166117992df90cb5fe0bf2c5e57e2b36fd8afff530cb642b2ac9370ab5f721e924318acb1b37a37e033e4da58d5ffb36e0bd49300ddfe1cf37006d9cc5a218a57b78c5ca1447f1b2af16daa1fa45bfa3050bc09b86fbb96be536f9bf5fa97a38cfa9e93939919d4ed4662e67aadffed274a723223a5b50a5e8c982ba7a6a3e70af5e2ae3d3fe243cacc3d8494d82ff41d5b4572e26d16e60f6df069784670b273beff27b1b35c0e4be9f3ea0f38b4b402aa389f1864b1e4aa040e073c99b26f61f8b4d8a70b247c428d3e53a7f87af4411b69b2a3a3725200751959633753d1206d511627684cbb2ff273a82acaa3620f1410a923cd163cf2fd9512972ae52be08dee5914e1b07bf380dd00aaf53006e9551e738a24d0c121b2a58fab4d11707b5670dbcc91490d5ed18e0dd14d58ffb7cd93612304ffd17e5bd4c44895f81f2f1b9833d1736aea2b768bfef8e9aaa87799951e0eb9c1b8f2394915c98c946eaaeda3f19e767080349e4866a168a76f49b495629c344690cd47f85f8ada56a38ca68000540a82fa9d009cb531841965ff55e79409c005f3f9be9fb080eea51e398faa72e722e6e441b0900588338bf7e3d37c6134f3dd0a57eb690f0ad730582783b893ad14fe7745e7fd5d6d293549d663ccfa71d715e5f5df56051c3bb392fcd00dd749ae56fd4008ef5e18774b38ed28c9922625ec2eeb1b5c6bf455d4defff513c2bf4ea6bcfd9ae0bc1e8a4404cb2e04ba072bc0f0c386f53d60f3ee82138d5f3801eb136edb20997ec9bac8b82b43d0361ac3302fa1f06575ed48a396faec0c11600731470f9d120359a20f853acad1c169db2c5c015cc32b18f613fec996dafca58af9a981e2db48383a58f05e158cefbb1f02c8353584dd98aad92d4ed352b229c83904214ae6a4051729d68643f0a646119651e35b025e9aa6c4593523fb9e83b994353273c432288ffedebca39d1a48afaa18dfe952cdf27a94e50eee1a45e683f4e7b844f4e468562a0624209656b11c5dc4fbbfc3fc9cfccf9c1f036af516cebc6715ffafff4abb4c97e0a4b57ff349439b5d4786d11a2c57273d0696b7d629d2f2b922b6afac89c03f90d75b37a8aa23eaf8b40870d66485931c7bf6729051c5c9797c4d6bb9a3b1d955f3fef24646ec2e4a1c515b54fa6e21d5618cc5a4edf8d80067a1cabf03fd48d861c088341d03bdfc854804c2f83b2a886b45cd2a4342d801dfa6ce53293885cb0f44abf97637851e8ed8a9a8ae674770abd143837c0adf5238975a058096fbf093c4ad530154eddc19b60cbd78513a184150b5c5d190f39d7253fb70cc166cf961cf6c16ebae1112cd876c8d1521eb81a74a6ef179396e8c17612221d5ed5431324df0b014bd2cf688992c5dfd9e91e56f37ada072675ef2e0cfca9db094ad0cadd0bee1ec28de48532358ca376e75123ec32c0c955e5a708b067cc914bd4a2361b2d403ae97a06c87c777d63d5e8ca27c9e36130c971984254812fdd16697b79a4d97346761df61caffe4d0b8253b379e6c6546bdc785d4aba40afe4de5aa5e7ce200ee4a4317a22c9e424aedc9d5323f45b3853c2f466b2124a6e7142cf9cded7e03652fc8924eed2e11e978dde9a5a4933f3ea6381aa01b09e10c1105b7a28f88a8d4f1268a3579551e7cef329d318308842248dd8b6fb0faffae04f1d74513970f06017908a637c3ed6fbeb3936578fe5db3fa54a12f3d7ca04396227385fe8468cbdcfbcee938cd37abbd6f7a540c9779f6cf0a01947dc4e8ad794be611144687476cc7a8ea4c4ee6bec5e883b8bf8308fb03baa838a0dd50ed88860d7bfbead686ad12b9cba9ebc11f99ce80f5e173c4bc8cebaf3d8c7b5bdd806765f0d40aa1bf60d3bad604864206d3e0e76e42ec9513d2a28c77b5d65306c1293253e78ffac74d26e256382bb8705340fbecd8b84d25fcb90d422583fb87684d9fb26c92c16bd3f357b16b212e27a30190dbfaf98912e54ecef0e1f7d5e8ab1b5fd6110e376ecc7bce281f2c224fe512fe9ad1cc4392bd9eee6ca0401f78b99815e5fe366c93db38e9a973d397c7a8c7d5482640a133f8eff90709dca764635d28f0ddc35af9d7e6c5de45638c22d7e0d25193b22f55c3ab1f04581f40eaa0a2ba6ef044c8d556d133203335cb6cc0be38a8edb6a6ca66e033cc083449359047f863e29e27dfb80030e172bba8f2ffc0afb4657f2371976a9a554119177d0e904dcbe3dc1c9d5922f00405229774ad65b118235a9482cbfc14748b7b3d2fa70238a2798655f98c6bb264a0c77b6874625f0a7422bf575907b7c4a813ee01213b09befdcc63a15eab329c3aaaec6ef8797583d801ec77dd16b7d91c71dbfe7236c3bb2fe1c4044dcdf4851d80796885a36933c80a4fef6fe26ed3b87bfd940111b17ab734aaf365c527b228b0789418d1f2a6f13b20e5b2eb4725ebf9db1a83f5b0398a3352acb5ac7db65b465779b6088ec9d84062d4ccccfef087e26f9bd661d6fbb871563b9af9c19e00a87a9bc776561398899e20e023ee9f934eeb60d1e15a13090756cb0bf38c8c1b2778bace257fc3c258bfe1a229657bdbf688d3a69fd0364daf01e9544985605556cba37ff9c00ccd45f964b57f609782d94f257f5a34e5089627ed00d5f8342758c9f7fb45924017df4d81bb3912e8c5d770c86c45033b7b5de6d07fa49f5ec82005782bfbb2da60ad01743c5c39c42fee27eac58a6cd85d30f78d6d06ed6590c7077832b8448e9dd3d17e4ca641c183457b78dfa023239907d9d410d222f10f848a660b912bec2aad69cc468965e53721d4fab1078409e7099bb445b1503a5a200fb7e2f1a2dd7a41223f22555f0ba2e65e4bd667b094a219acf28d2d5056ec3e41de9ed17b7bfa7a96a225ad3b958037aeca3d475bbc55344a4a9a46b90384c38395f144c93c63728e9890dbdf39c5b29b1e3d71e8b0678035fc3f119369e27bf41370dee6e0726f1d8d2f663c2733b6cff30be440071483a4c636525bde5ad4b9846a579d2241b0456e68e5fcb4aa54c5a40d36df4d0265661c9eaed14f46a48b8b184d965150b6d44d488aadd65ef5a90acd43cf9b554de2f3bf8b02f9b79b4743b606f543980ca11532f7a54c0d82f1ec5dcdc2ba5bdc3b07a0332b3284d8d92e61a889789d78b531e5d25339bd25ed0a7d2134c547f0c9d05d6514a9bfe80a5b6f1c59e2f29f5f82e57cba742b0d6775532d11aaf70eca803d7f453dd15b0ec4d8db4af4e2f28f8ccbf4ca820cfd4a40bf018578f43fb0c31c1d54e34fef052e2148bfc9d549fcc2ad725f8b10ca7d72d91c138473d20e720f9bf5124d61c081e2c716979c05402907e0ce27fe5e5e58eea236fc7c5da8155bcac17e4e7e032067d25a9e4a72334b99100efda705e253ed764803632a82c6d7ec1a06d1a68d7607782f88865f5901141872581fee4e15371a094aea22fde35eacacc8c3c68e5cefcd9f5db1d327e25d84862bce5ba3175120b8bce1f15a68a9f5927e05f4ce2d5793102874a0aa0adf28f8b4fbda0cf4742fd90d5a5b2bcdccb578ae4df12fda56373b1a0fa38c0a9bd4f187937413def7e7546ea5388e51e9047e85c82f223c8c850dc4e3f62d7ebbcfee3abb7ec87f40fdd984a5a0cffbf9f63747854b17b360fe94de5c62fd20ce1a2d7e006e30ed080fcf632bf70e5bdfb328672f07691c9f9d652089212d489a3e4a61bd2e7dfb8c534002a43926a513a2e3dbe4be6bb4f46afbd2c02ff8db6e147f11e4233ba98e1e6284eb913115b347356ee76fecc8d50667ab5dd2f94cfcfcfa1d2eec2408285e6e9ee26f83e4148d8a510d766e28f4f778ca892bec41fdd01d26003d860e16a8126e4dfc2f54a1067f308a4b5cd725c9abd2be306b583851f99eb1a4cb7616b403477fb5c065796c1d63f9a7851639814f254f9bb378e3e3d5b27e1c4e5f02eaae8ad09bb79977544d1f8c9c70dbdaa31f5149d99af0bcdce9b3a5f3e80b9075ae5dbcc375811cf384e399ffe5016dbfbd9a912e82462aabff6183f1bfdb617785d35faed8fc005545f48f7936e1dc5d60be79011bfd6a1ea94131feadf1a1b2fb10b3a5640ea460aabc24b2e8d3e9c7f7b7d6a4ea368c76b532d8dc286aeb6326bea1fda87b157dd61ebe25462dd58cc67a1f8d1dff77b627fcb0d8144ee08971cac654c2320403614a260c062485d894a6534046118a11430669cab2310159102741401028a60162e8208ec21034b1c7f35bb2363f080429a8fcdbd02b018f064388d4635efdf948b3de19283a6b7d9adc3ce3a96b6642f001814fba4612e050f6a0565f434ca8b46a34c76532b8a9043a0a78933cd57677d9ab85946812f0b03bf8a73e9bfef0b0335a4689134420e4d15bb6047e7568c22714ef4af3e9abdf29afc4b51a40000570d31a7eccdb775dfc952a63a4f81f4815125fc33b0d8adeb29b0938ef74165de818a53bf6bb130961c070ba19e7d13c6c0f5ecd992fc14ee12b13822eabab2bc80587bb384f1d39f634a07be0103e7adac0e10ad3bf3d4293d04cbd808b2a0d54ca4335f32a9d634e84cb7657400825d60b746e8dfac1940fd21d5c42a04d434bdb95de4e3302f4eb2a4119f6b7e2e1d89f09595621e9af545f17136957e284327928f591397bf6a4d7ce3f90d669734796406f22aa6a8b3ad6e48c5698c730cb2402de5e82376b8966eeac7256ca5f8dc685328fd00aea54134d3bc99ff6f0742dcbd439b488446c93509a5279e76949aec98c11110962df4e9ebedfbb3e50696cbb449f331e6911ffec1f7e544f204d7309ce9d35b36a0012f29de2a77f7c891e806847ebfdca485d8fb6a3365a3963ea3011b3f9c840ce60509e6f0b67fddef69fb8a9fc62c69d595cee5b2df203a1bf092e7f0d745ef2224b2480774bd160ae05d227a841f316f3af2b6357635ea0f80e967a0bb4eaeac495379bcaff713cea48b3cdbfa2732e73a1b3c14fe37ca8dcd91407591d8c53f7effcc942cf5fd76d7d7bbd739435a356ff9d5e17a1c4da74b6f5ae207b7bf0a71a18a0bd0512585287e037b031d5989716934ac27607d46f8b92a434cd84f1b08b49a6fa537db8c540e1a3d804e53de85e1c7c0d07a70dd0add3e895c9f9811e19a0bbb4e98e2ff8e6f6ac87d97ca88a5a9c1978f18be74ad3b64d4699ad30af12bb0e508c4faff108fa36739d4ed7229151edcd831424c5f5e903258e82b01fe0d6eb320d6d987eb6b7ccf98bb18f963c8d1ffca9850d1abfc862171db7b26242c8be3d8acaf18085ad3122c7f9d1ccb340b4c5bdb9ee8829d50f4e5ca2ad5876d1d6450b1540dce6229fe0404f1e4b42c35ae2d1929b45edaac855b74ceac7f3820fcf4e46035fcb80931fe439e793b9affbcdc7825aa01a6abc5b77d6c6f4ebae0cc2dea8536f099a41594307dafcf98ff925ecc829e7ac4e271875aea27a113c9bc063f3a094423531af7fdebeb917612b833513aa8eedfab81238937a0bc9316aa00e466e593aa1b456a07e52d896e735e0b1cc90b053ff9b40489b1f2efa8c93f427b0b994fa6ae37bbc649ae2cd19283a167ac7c2447b3a6aee724fcc61cb251c9ef2a43343fb0faa9db507b8adb9e5da971c527a683bb35f16cee348ee5cd4e82923884960b52d8dda8acf5e43024704cd18fa64c3c601d3fc58c83769a1423cbff884df3511cbdc04c99a8a6ce5c5b0837e53e682a4fdd9516b3109a42b318076a3845a18c0f8a332140f23498fd94a6db5670956caaf2661d231996e254a0269a8d40b6a0e02d2f5877908047c38685788f9ad24357cb79eaaa7e62a97d11ad2bfb1c9eede800b712c057ff171ea88c15b7bae7b978366442ecbfe58ff6393a7ea30c4fa107e4b7a9f7c890e6daecc04fa5f0689cc607cbd76926a706f0d0d34c7c72d01a0ba79c0696a558a2b200f36199be2e37cd370c5a9f067d24880c91fb612ee9031cca8b48308d1c9c0071d276e68f16a3e0549ee2028f501eca82cbfac36a8bfb801e4674839f37a3e4d2e2003c20346d00c35cc1bc1fb6c36d0fec8bab3b1f1fa39999a4e16b97b1d812fa32176403ebadc4e2b392d0f3bc0fdb34f727dc01fd499848eb3eefd831ccef93ce4ec7c3e97e4de32964b47b53c5ff5b8630968eba2dc23db8b780c6493bdc9ff43949106d5fd171608033a20bbbae6a9f82db33f4c0a06b98f174e395c7ab163d648c8a7c2de1c4f32be67e1d13eb8fc5169652e9392fab59893569e32aa8060c725acd24cc65871e1aec09e801ae845efef991af9bb69b5b3ca6c3b5b74bd3cca6a9a6eb3017cad6d9d725dbda8e9227597f28a8208fdb25483a7f1d4f9753c398f647685523331c3a4e8000d4c6f264485b6cb83d1bba3c4779c330b81094053a30c00c988c709a9a24815f5d3052522ebcf1eaf8acf08e64bf5aac5443fbe7ece3aebfa7bfc8d99bd10845100b0c61e4c2c91c9bc310a56c4e88cab4b38786ba9ddc189fa3f468d689b4bc79c2f198322ccfe07daa7b059ea68fe6c0e1748f69e66e0a8be898749e42487b15f6d03170b6ea420534e8f7bb57e7c32bc8bd50152b49de51406ebb25bd418dcdfb0da679af3cf4450e12e9fdd125e2302712da4875f1feb4bab3bf8178b61db8d7fd523c57d15ab06b7186087ffded9a7004815bdef054a40ade40a1c960fd0bdae01f09788803f35d2e99f3275a36466e67ef8f220d705833120dd8808899199f197c803a2547846fcf70a55e0c4c139497493f422eacc49fd520408f2228b633fc05b1652aa3aaeb453f65aa534aad3ca8473b8ed8a9c85c0c4857f65972b27a0b39c9b2189929ea21ba199fa7ed433ebf0d563cacf30ffa9be60961768dfaec8d3707c624055df5435b4b01afa7890b22631639f6e20ac1d62bc8a04d23c20edaf4f70688bc0d07db1c6d94597eecceeda54501951b50e008e20c9818ca81c2c1d6381f014f55c4aacbcc7065dd33cb767ef764adae12bd35f9413e2576c7ecee55e12ed522935a7a03db2a068f3f0141479e447156334923328714b851f09f4da874269293cfb978439d72110fe78f5910d96f17702fc7d9721de5b2f8a9c0714338a226dfa1ec9319af0a675db0544f12b2a223a1cbf24729f3452ea4f334b3edf324b4a2318ffc2ff0d9dbf232005bba4c7132300d429f9e5a14c88eb49e15525b26d2e29e3e1cbd39b9a08ed01bd8c279ed38e3ca0277ec5ecff008a7db63d8fc40f1a540641829feb0705e6d987cb7df355442eff981fcdf73d3cf44899b533d02e5fa356394fd1b29bdf23817b6b70f94308e156849d263f031aa46d38198beced4f85a13a815fbbcae79661ff83529aa81665de8058cb6701964053316cde7ac288e2370261b38568f1697247139a39f8ec98e5f456d4b94c624fcb7c0c76beeeaeb940a50a9677d5df57aabab297439ee554d538cdda489aa139468829fbe5b8cfa6ff3a60ef53a78b7bdaaf09fb830a0ba1e17bdb5ade507f1792271a8cb0ff0f2f483047ed3b1ccaf73685ba1f787bddb08ceb3fa66d1255f13815c82e3be515a67b892910a7674889d8528404cbbd3998777485a0fda96e70b7d3ba44bed5f1bacabd0abe719ce3cd3fcb29ed3a1b9c4ff6b4be5da94546b9276e1c1716aa848ed70bed0042c7098e7dbaa0d5794feb76359940b8a9df8ceb8abb1655205baf8a566bf11e6f9181d2b2b62b5e38a81842698741024979ff7533efc5f1f111d6fd604257201c1863b58f42824463f2a316df40082bcb216e852274a991bc8ffe78f96fa9fc9e0388c85b3eaff3622ae39f07c1817841147cfe8df394008e2bf374df7deb3949f07b3bba058faeae5177ac8955931395a2001317372523f7e0b7a3fd7001aba6d0446f88689e67712331352603837a64f666f2fd47584cd70c6db7faf7bfff5f1faa877a954c2a200678521e4343a108845fc65039b7ca271e8cedc092770c787f81b1d9e5ce0ffb71a7c2705d7cd15058347ebceba53b2296df54cf7c827a376523d07350ba9a908701bb68946039a4b1fe5ee643517cf8c5386dfb8df5bb33679a58d1c469ee89f0057505e23ea50883cb9bce08fd7efbaf8cf29bbf8c178224b7b2358eefe3bd1de262fe7440e7340e90b5532dd78c02ac3937b947a3c6a0e97c96005d8d9ed59603b1cb50cd2ebbcb9748350366c4c45023b7135d935a1a5ae7a323a97e0ad2767c95c32c55d4c7e949c810bf84596845353f4cc9f3ab716bd6f8cf3450dc1cb22751cf33860387d6fce5320a7e303f66aa9828539caa22add1e03126be458dcb279e36796fb971629a1b5843020dd55f5140315d6592c86d405f1646321e5f569d1b2a53cf1a96b9dec7f59c8559cb82f94a851e5384e382a1a8e0c8926852d1c571607c518b3bb9132dff1974093553fd3b19f4fb87a93ca2289ae90462e975ff6a040f544daf508ff7630b6d4e71e7fe6372b619930609e51767e99d68b9101d2d93980089f4cb548db34c64ba2f034af15c8ae240c9860cfdc0e68b3c51f6eae28e1abb89c8c07b24a5aab01950280808901514040480a83b27559bd92e0c82abf680e75bba3fdb624ac863256f35a154311cbca3ed0c70ad53530079a010679a4bb50f012a0887f7b745f3ac02a2375cfbf2e6a29720a0c56288bed3924ba650d15f027682bb4fb12a705dc0ebd356aab996d4f1bebd1344e672ffdd36179f4f421474f147f4b12c60c89fb10c806c27a6df63bf402670f8714b9955b0a8d775158cf77be744af8152c38dac60410c00c009a54226a7d4b0d6e03644d6c6a617165be58a28e8e14e08f81434e9bb463c5e40c5d8462c88bf73285ddc7787dff7113ce9c139fec7bdd9a8e310757c488af07135292da559c04744b09c8624c5c314f74650bd9d6805b9001d71fdcab6adacae4b5d20401ea88731fb4738540e9626d55294e49809df42894ed30324f2d321d5a4e577faf3d643515fdcd7d5f56552d4d837a201219d38f63f0a6bb0529c096868c1e7adc9297b409750e0c25af68a43d2cff82fac5f40b8a2c0f0df9a5a7abb88be513c2be918459b7ba09bd915d8b28d690bb074796fe85afcb40784cfddcb4369cc79c0b5e3f157c7b90384a7684e61a42edf6c775da7c23f0ad1830984398e4114887953c362ea9f4e10caf6b3e98f44713c1b2c5fbae2c4a7f221bb319306c1f64e87e7f4715436f9af5b408d821550ca292da0ef30b573c1df1a86c4b5c8a0fece7076da67ddefa677551d4616c3ad8f8324a1d1bb52dff20fe9105ed9857d01f73bba98365d6ea771cd11567b6bbc91c9b662eecd07d64640b32cbcb7fe619abb9ff6995e52e7946452c7a6f8a6ccac901b8d57bde1847283cd0309b2e498f9642fe3e06730021e55bcd01c0207db4f53ddb3d94cb34512bb8890bd2d94eff99e228b95897f5340e10353762184e112fc8a0f3f1aa852d2bf560f6a24acf9bb6d85411bf5b90501c8cfd075085fe2cf69d19fdc3ae3d3009c6f9f712a2551792bc3829f3f0adf697388a8c61d10d854aa82e07ee34d6965bff5cef4c7f78775d32269b49368a1497e00e8972c9bfa37015d9051676a3b7711c15588d03e93d7baf9169f6438718a46aa14937fd73d2c3c100d7ecebb6c669879e716e1784fd48684df9d39c353332b18902050c505cf822bad36ed39c2f8b80336cd9e15b22fcf78cf0b0e1f7e5873ee000b1e4a3f672b9dfb3eef787d9b3e91ac62ff9e8cdedd7f3081e320d9ef55957c6d8d0042576968d2fab1f702baea2c581fa478f8a6ed93a2970e35e67b4b315a454e1c9747271a256fd457775a4090f5cf01f9144e3ef4327abc87188690868c21a27e02087465ccb645d9aec1dfc82f6774ecab0f65dc4b25c7d5e3056f0cc2909ddca451d7949fa5e30f910287bacc959e3d5935551dd776b4a53a9af3b7663e8ef972d22f00a96b06e635a1ed8c397a1e0b237eb0959a8a26318e364e3e68f739d6cce009e78948f87140b51626de457e14f305267c53373aebc3bf73dc2d37d7a498906fa93e80fcad463b1a6e4fc28c4e06b7582587e0820d760317df7bf572111ac72f07da180c5f5c4eaee297ef68aeca4c90ec324f24ab889ce0f50f507f9e2b8f1b5da16e0504013d496d887793590df1e10afb2ca853ef55ff3f90fcc078b9c370b86e95ccb507051aa8a018c47c72e26444feef922d34afb8e6ed091f48b24664c1a2b1788f1708e24e9c0d1fe0564ca9d016b9cc5f3b09fa2e62e580650541cd7d907eb344f7cf4e2a2eecc3d5ab897ba3adc37dde5b83ceef3e13b0eed3f0a4e335ef0008b3bd018036a2683667158fc3d3009ea7a641df0f073839db5e3a2c9c47ac766b53265db12e1a3b9b238c20c84d1700f14b4e4f62e299012d87c58c9cc730a2154cf0a55109d07d133fc3c3c71252e036ed6c7a07aeee9c1759be60bd380a2f4c91b8854fa8f4d38e84ee9f45dad4335bf379d0c72b6d5c32b7b5535451d0bf0645fd7ddbb1590341559ea4624c235f281aeae3c46702049ab5d09141843e3831876a01627a03993795bcdd482f34c59b7141a4608af40aff5be18d3f4d5a5fdb0aee1ea1b6fe256e01b5433d9cbe284f727cd2e36ff5a7c3f3a459b3ede7f48ce7d7950a67d123d2fa26fecbcf6e213b5c5a4d17c43c1b32c600f247e5b5a0c4a4febd844e81df214b83fbfabf18573a841b47a575d00f384a194a531546ebf436fd6721dff246ce6867538994d06d2f586ace692442ded47dbef5341d02b62fde75fd7968223055cd97b5996fa1e29f40d60aa833217a881457b7301a38d06bf1686d9dc71cae6de01968f722999260e089471724c6a549501760add7a7d4ee0b4884c2587d32f284f6bc05e83f00523d86b5db39224f28dc39128cc85a71d1b3b7f42e2163375cb744a37158e3fb97e534d064b1623b77f472b95ad3b1c7908b8ea45b4140fe20a48dc2bf370737f506b01352ab8b5bc1c76c9aa26815acd510418fab44dc3a20fa76b4829cb8d52ea61f995ad492daca519b36e1dba50c389b70ae9e7d50288a53c1c576990c21f50ee9dcdf0d4905849589d2bb30f09e571fe4cfd086bcc8c45d99afc8d3327bda744f5678bfa177eda2a7f00b40c305636924cdfb7e16025cf7bfea131582b502b9790b65caa0c456aa07f53021112a67b0ced03dff4f38133569e650a15311793376e2cda6b19037e1174f8e07ab8633cd45ce82edce7155810e38968ad2028bbb9dc2b690a287151071d03f19863b6d577c2ee20d9c9ef6a6298e5462c06b844bb448415bdd709b22c08ae6c42b04aca33ce1e5c13bbc569ffee962259806c81824432676d65ce506af29578dabc0e904f1e01b0321955160cca6182bbe5fa6e058844845c1f710b4ae832035adf8014289521d8acadd37a20ef4800f3d7c80b23e39f3da71e59f7dced4b8a86c09e25c0286729c9d42ffa9680594596f8823d01920da81a6c06b022e0af60720313f1055d883cdee899ce139e3fc29e6f9f36ab189581248f43270122a5f38ae3f11ab964a55ccb3f2e1b00443c1a89478ae2ef55cfb6a835673a0c4c482090641b15e1feeef0ef27ecdf6dfbce43da30e2e92e77ceffb667364c279887e31205991dc0c5d4b2a8ff9fb5cf61b201886db092cf1c57c47b98b5b7afbd99113a2dcc22e7f4adae7506420efdfced58017b52da82d37e45e501d8dac401639c3d11fa5ed51e86da44489b4b020a3a53a842d77ffa09e5ef07b0d53b401ed1e35ed8f8c94018b4338f04c103a36f9e0a7f844818cdb9e2a3dd80f4e049fbf7a97572609f9d63fd4451ae8e5a0eaa2fed9f771568796ed2cd479fdc79a1bba0c016b2fbef8573ede420e625c62c5ab600849da922cf8c8031e0bf9247036d73ec69d8a8ac2b7aafcf7acdbd8b6b7a87ae527014ff99231c156ec7880facb205a4d96f55818051e167fdd2bdc7a128c6815b186a1604d8f6c864006ee86050f163cfcd3ddaf51fffd8b1e670adc6917fd41400399f278f4b342cb23b60491dbef65b2948ae90d3714d5041b59eff067830e12a0ba4627a13aa37cc980bf78a44703918a042cae34b341d18b64243bfa5e99205f3db3743c8c1757a5be2fbfebab7ab49e8c6a8eefea05f942370a3b462dfcdd30385c108a3e3dcc81dbefc092077a9a0f0b39ab07a465990f551d9b3fd45f4e8624ffc32a002747a7d014baf8e7cc0d229b6ba3701bcbf94e40be9561b32b7d70eefd4ef7e21b54f57468a61372a3794d21bcd24962923e2dfc6db48e9ab5962f69c999f7ce9d7d2c0933b2b199bb71761cfad9fbb905f68cac49c9712fd46b411c315c7b4cd66c87dd04cbe3ab7d186e986ffbe323a04ee32de3a5121577a58fe83ec991126df707c8b5d175ef0d1493b44755a2419c7f5b287c019d819a84a1a3f94a4eb21d0878c9eb8a996c06768109ba8790dbfb8e4e40ae81ce1214c8994ada6377d55d8188ffbb46dcb8b84ebda0dcb8e17c4fc4e21262ec529098d74e9206720be69c09bb58ba28472e93dd6a9c009390db7e855a1e36d451da9a10eeeaf228ca6c37a08d1dd2b49cf408461dd7e3e2a30c481f1f265e1ec8a084b3f14286e49e90885a70192012489f989848ace936bf7904e78c8c090b982b0eca7c38f7f7260be8fe5596178b5c4befee99df1162bc3c3b283c9ae5dfc77e7ec99f75f38b7ee17871e85607ae7ff35499ef78e826d1fc7964efe26c7b25976d8c5fdc8d4f84acc2b17456ebe54c5dd077af6252ec8c7b2a3f00323c16f4281938d825c659f35e1d9d30ce2f16128a7ee8c6b4f27864c611dc5c30bd4e20b02922b31b0d7463075c69ee2f634697e059ba66ac9d5bdc83313fb6bf09268301a99533c1281b3898123d670d53806e8681989707969ed169fc48772b28d38209f089fa859682bfc35a3afcd78dfac03f0e6ad2c6f5e3b48fc37f0c95eb70ad655cbe3c088868e20b234c520c02ccc3a453cc2f5f4d59e68fae0dbf58c4dcf724e63a98050433ecff258cfdc7a0be44bfe8fed75eec391df784fbecffe28bae9b8dc5fcfa87be72ed1fff0f4282bdc3e83f494691fdc38c9af4f61f1862b337ae2ec3d76c2c7b1dd2eff56626f8e28ad5349efde82a9b1497af7c26ec480b7c63278689b525e10c70ee6ab59fd9c59dbc2516ebbe36460a2151bf8ba6a79e1a83db4ec23bf52c8a8751b92c2b5b6ce03769d465aeb0785925057c5004787ebf8d8b13facbc3858b7fa54aad9b372e11da696a9f31e272c25cdd48ba67d1609ac2dc3c3aa7756c0e54566fe49d4cd6167913c9abc76d17ac513868868abd6d5ebd2f57428c366df787667eb0ef477014443ecc1e3ae8a9797897a855e3139a17f1c063e5bc42e28842a732ab976cb69356cb36b7d78fbd6997fa2a151d9d1dbf39ed64575cb18585a843963e737a1a72b7871626886a1a3dcf516b36486abdb99fb3dfbf0f22cc7fba210fa2b9f160e82ab2b1093313262446028986fea6a19723fda6a33bfaddfbb0c240d0dd6739f303c03f173f536f986305ff1915a9db504f7b689f4108712c6d6b2159f89d9c1f8e0d0af5f93932db518c173dcc18edd67516d4b8765aa83acf3cfa2a12b0f87f23ebbe305c89fbbadc2a8a528c54d2ebd85291ef46f42822e7384aaf44ee01600c5bddcfa46e532e038df64761b207de4f0b993d2ef5608e9a06d04575c08e011fd815d53516ab4ac489388e526e1068fc543133eabd9f25de9acf76b0aec878e576180f6c865f6c72a18096596ae103e06153fa5b331a5450f065f1e9be584c80051d56d86d51fd18a75b67fe08007bfe678e0053069fc8e060e2a71f2b5ce9183fbdc529fc2c68413ba8400e34e5ff16ead6dc9d45edd5aa2b95c5b996ba40f6cbe2847934d2a80f88685e1fbf281ec28f0b7a2d19de6c2f6e448b340c577d7285aee9ac301534b3ae1cffd4a0db0dbdf538702d8f80c8a03aaeb556dc084c8d9804fedaecbf59fbe8f58258e3b62322b81b7fb060a2daa118a0f13ac780d53c51a18f6965caa3209e75225accaad5e249c03820320cddc73e216feb1ad0c3559a4bc89991a44e84e2949dd60d603d73a020387850083e88e0c298074006d939dd20aca4854f99f0471bc57017114928a20245225653d295ac7b85c4523b67389882837f885fd3a7326fbf7f3cc4991c23d084ce221bf0b3ba26e8ee91e31cf61604455df1555a0f5b2ec4714cd240003119e7ffb2afc48d4c474afe9b8844ee8a0ef2254695a6486d33987a6c9aca87e7f0dbd90819d2a28cf1c4449d5f2f43290b118c40570885cf45747a80de914096d04321bedbaa10bc6b62c52b9765341392e3e288665d0b2e4dca2d25b3fafabd7ae6ed5d748013b8939deaf390cd3dcac9d95123bbc47ac0b64ca058ab6048458105c80e886b34c51d4693e9e57357f6074efd577489b2f0fb94a123ac1625a0e5c5999d4754348501fb9369e354c0e9aa6d432daeef609f5535a58958f3f4da581d21d69d5435ef5d8abc9fa5b79b9c26a54bba9339e2f49fd79164d9fbb3b56bdce01b15ecad9ed3460438de0d745da4c4b03ddf64f24c61eaff1bf71487c518759375ddef935305f41b7503e8b240ac99393c1479c4d96fa55c920dcbade3420501473ae6ddfa8419f9e995abca60046ad7689366e9f9423aa94c4d492142033bb1407c169a531311d3d9637fb927ee302bc50af4f1bf259339cba97beda9658457fa4355a7e5ea2e33a558ebffdaf5bafacbcbce880f88adf626c3164a4df493bebcd87af7d961a26ed5f47517b2ead0124647e62127031411a9791c460a5712cbb0c90c077e27fc90085f8cac92b743a6621c0fbd17934cc2d9501969a4b4eb570388dd2dbc168f50d81d1df5fb9f477ee5d4f2f2559e18fae6a33bab3ae905454a0c5e5a7c0ef443ad46820c0cf2c1cf463d0633fba3891f5a3653066bbeb817b628077534686531632851b2170a8a0dcee59c62a851baf1bca65c324e653418f5459d990b425544a043e3f91680ef808f06b5ab628518e02b21a18f0a01d0db144052cb400589a2e086b8c697ae970c907e1020ae6d7f303d65bc0c6015a5082c94d50fe55e499f0e60c78107a84c118e5a54395a44ab1d7f60655d3d9d06d48a5cf51982a03fb97d59b17b2907f5cc5de527a985fb42a8a0ef60e4a8d4e5f4be33cae2daab5b8fab0b9428d47286ae79c6a5588187c6967e40ba08d527021c32ae1560aef76a4548c9ddd23c3176382fd9b0d21602edb05f5c7a38fa2bad98c8cb4ac6780ea87da0bb3ee00206a0e269aee3ca10b675af2d3c27fa50561e8770bf9b03f1b03e00f58630de3a582cd0f231337f9f865a85aa4ce557df68e77bf998a6bf94d590fd00622d88bcbf93eb040b9aaab39d946ae21ffb11e7995435e29225c4518b761ad06556dc6a0169e2b1cda2e5ab1c5c68fb95fe0da39ae1a2bea54273720e479c3396c5b424de0520e68128ddeb8d82d34fb5d9db6086c94a9f0b7650601e406dea04bc817c7b334b2fdd4a79416d7d6b3b6160a038a9059d8f998a5b4b0c845f9470d6fdb6ca36359cc5fb0ae40df274eec0d2bef92143181e564cd2675c6262be7250ac96299f63d58ba79fa0facdfebab54aacc28fa10f0df95b0a1117134f8fa9c8fdc3705f51389287c12c2d3ed5dea88eb9ec9551b8fcd71cd4f1acc1d1f7eb15fad03f423daa1aed3a77b14765a501d807dd9c031a6b96e7184a0e6ff01bed06a7b214f54dc2a5b38984eb4c98fda391085c60441febfe20e0c276270986fe4122661b5ff7959b4b1ea46c092d923881a408bc9015cb1aa634d05c0ffad21f5cd141afade0effe702086c0e23bc9038e9726e4cca8f14f38c64b0768b4a30d438324401eca61aa2fdacacdcea456e23c4a4d91fcd5ef961bf79dcdb71e0f785bbb0f6adf666edba5847e1d62b9fcb16b904d7ff03ee21a7f2f015ab437ac33ccb6fd14b06e57da8ce2ad7d1e11fab2f26cf8d781766605e95d36d26074effb14ea63c9b0c37d1f3a02934ce0b2c6e48536b291e2acdc25f359ff0b1e43e387c86d403e0ed66ed1434f2e2dac0efa56f9d4d72f52d37b59c6ef12f1fdf0e702e90d186bdcd40c034a457256c2eaaba4b658e8d0d2b6db352199493d438fa594000000000000000000000000000000000000000000000000000000000000f902c0f8dd941c479675ad559dc151f6ec7ed3fbf8cee79582b6f8c6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a10aa54071443520884ed767b0684edf43acec528b7da83ab38ce60126562660f90141948315177ab297ba92a06054ce80a67ed4dbd7ed3af90129a00000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000aa0b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103a0360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d05a0a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a873f9d06a0f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f37921f95f89b94e64a54e2533fd126c2e452c5fab544d80e2e4eb5f884a00000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000005a0e85fd79f89ff278fc57d40aecb7947873df9f0beac531c8f71a98f630e1eab62a07686888b19bb7b75e46bb1aa328b65150743f4899443d722f0adf8e252ccda4101a09f555619c4ed056b4f2385e5b6fb5a874d040bef66d6998283e391bd9a91221ca062ede1de03d21b277fe9406c914f83f0461057e1782c0a71d03cb10b950cda4a", + "0x02f8b101088402faf080850cce4166008301ec7b948707f238936c12c309bfc2b9959c35828acfc51280b844b3dd411d0000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b300000000000000000000000000000000000000000000032a4fb7a05fba004f1ac001a0e9e0c4385db7f0f7254952e6ab4ffcf866ca32826d7ff6b03b0155bd828437c2a0686ecffd2315b97178a90308e3ad0dfdfbc05b2338f7a744f839f0db594d61e6", + "0x02f90332014b8402faf080850ab5d04c008301cf9494d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef00000000000000000000000000000000000000000000000000000000000151e7000000000000000000000000ae0d376d7a0c05a7d78ce1d6990adcbeba67314700000000000000000000000000000000000000000000000324e964b3eca8000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011013ee13788b544e1cd9d4551b99fb67908c0af827367536a61c6577c08697943e2324bd61b8e4a36f2d1f3430cbe7ec39761d78043880041cf1bb61c108c8956a5aeedbe0687653aab42caa3d0242025d1b2397fe9caf1d9009a41af910168adb3788cea6ec4d59e48145c770ea33fccb805b64a9de0d222f3269e43650725efe0e8fee352be90eeb0db1aab9246705d45e3f6f474286c92b39c29d24e1540cbac6b511830578ec7670b4dff6193e87227dfc43a90f6646d4387c88db7fc37c4448445a78ffda7155f56089e57902f63c1c27d8e2ab2ed652e6d34499f7d191bc7bf9f7f765a5bc763a11afba72bfef3197e2a0ea92ae1518867da46e04e482db871b72a8cda4f4b6b15160104fadd87ffc251bae62d115fdd86cd63d640da0342ff59f2bb35f6825ce36c0c017d146b7d459e6b820ccb581d72dd281dd3dee0ad9751a222f9fc2a6abe41b9070595ef766eb6e478f38a433a495d4d0a0fa8f02765177d6493d379f8243cc6871811f8ad9c00a8e42218bdb8ec55dd8d7ed4be8c76c1c930a16790a27d5c56e6136892ff1bb31c5eb678bd7b29adccea97cd67d7fed8664df0b0ef45be009c7182631961ee883d8102e542af6eadd5a3098ed1866b8614da6d5761eba4253b79baf01b17cf793a6056a1204b3457acc3cc6264b2f1729c555dd226f68ac9786871adb4125748b57f44524ee6f108c017fa8db8340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec001a0666e3c97d134e6014f44091c633aa6566c713483482d9927a32b4861683f0074a03a2e8e0b3499c7e001295c9892ca060e1d1e0db7639116d13786116a320d6687", + "0x02f87901822f558402faf080850cce41660082c401940000000000a39bb272e79075ade125fd351887ac888ac7230489e8000084d0e30db0c080a09b87636ac160fb01cb7a14d27348b6cce0a9ce42785838be6d63c893aa82baa3a0112163d1c9448411fc3c1c864f441df6ab0da54d20d2c618651dfca39d47193d", + "0x02f902fc018203058402e40d20850fcff91b8d8302ed05943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad88011c37937e080000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2aad700000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000594907df5a164abc86983000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000055a380d134d722006a5ce2d510562e1239d225b1c001a033bd3211f98ccc049ae4f90d948e326815d684251207cbd2c3eba6a06460b4bda069ebb2026ac1c3a4d3b6112c5ffa3db8fe6176180534d32e07e5a8a1791ea97f", + "0x02f8b30182048784028f297e850a5899c27c830186a094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000f46fb27ec20ae6171b6484109b21ae9b723af74300000000000000000000000000000000000000000000000000000000017d7840c001a04a1c91c977440c133d353f3952196deb01a28aad1102174c50ffbe64d35a8d62a03794e47ac37354b4b516bab988a5ada1773c75fddbf0c607022af88d63daecd1", + "0x02f8b1013284027ae63b850a5899c27c83012d7a94b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb00000000000000000000000038647bcda8340a7ec10703ca423a7a632e5e8ea400000000000000000000000000000000000000000000000657b3801b80b40000c001a05b447cd2f77bb71cd6c3bb3b6d2fa2c08f1cbfd798b5b37fc220b04aaddc981aa04f4a33fea11833f4aebec8cda4b19f51f43c86b16f706198881b56cb8ecace7d", + "0x02f872010c84027ae63b850a5899c27c82520894813c16051667ded55e2cb86f63b6cc81218972b18701ca2ae5fc73cb80c001a0e3191e3e9a4fae9cbe054c71d271c74ad640fdfc8badff7c6827d4d73551f507a0468eb101f8746dfb264f07f0fb08af9977299f1f7d60097842c324ea00cdffb8", + "0x02f903b2018084027ae63b850a5899c27c8301f10694c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d0000000000000000000000000000000000000000000000a004bb4a965d8e000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000a004bbaf28b6a3a44a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000012791fb7a91b1b3c60815bf9bbbe54cdf00f2d3f084e77ac99942e036d3e01bd8057786c6928d7d897c1e7ec93b1d836084c3398014f766b0a4e857403dc95468703d7f29aa1ed31f46c0028ae2d565629c4a97798a8b976da0370d21fb95bbf47ce46f8f26a32c8449fcfd5c25a474469dd181689ce67188f3631258302ec94723efee3ee6093afd90c7dcaae7ecdc5639a9bff58587c6c52762594b635d3e8320c5922da3e335b38871f1225273aca5f1da9f1ca0be1f54594f9e4219f5c3fb96be551d7209903fc8512fc0e62917dce5a2c5639e173a61a7c9990f128638bea62b8f696c075a0d7480fdd0d8bc03d0834d2f5a86fc7c64e1f45a419bdbd4df3d038d5b291a1f627517cc2d75ca3e4bb5c2c3b28d68a0cb2c662b10e264f10fae687a10f3943c38de5f59624cb400f4b82a0b985ce78f9742ddee7d548aacc59b091ae32988a1af9bd4d0a68cd651be3e9a68ccfbd49e4fe4babfba1c8a009c639a5d127dbd4c142bb36f6b82c1d115684578f978c9b1c11c1478f5b5117e2754d4d89aa46b18ae213bb25157ee5fb8b20d88fe2b2e81f2629c93de9173cd7c8fd5e17bd6e2dbbe8a56472070b4af2c009dab576ece1cadc7355caca63d7af7b7dbb4216f2389571e08cbec5b3e3986681d0b9d88f13a47cc9a55aac7f7419d6411ee03323e3dc5c6c2e77f3d93d20d7e729991fae4bb544fda4ab659e5a01c5ecef3f38904031cbedf8f8d77f7533385b9176d0ebe964055755bea7fdd7a73b3bdd1e5318b1af41fa68346461d94bc4793ebd12fd81ce5d0b74b62d096838eac080a0cd94731ce42773b6b1b5830149d4e003d99dc8384ce6fae6a8e485ff843e6967a0243b33856f7db715612632e73a78a4fd53a0b31e962f2203489ad71dc54c0937", + "0x02f8b1012484027ae63b850a5899c27c830171bd94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb00000000000000000000000067d39ecddeb6a55c036bdf0295979a7b6bb5a7b3000000000000000000000000000000000000000000000000000000037ba039c0c001a02fffd250246b9daac1283d8113918fb1fe98afae9e83930bc616a5d5cd6d5fdca068d90ce7f7a39c23e5a8732f75cd0a140c8e44e1e34e162a844298c5f5751716", + "0x02f903b2010784027ae63b850a5899c27c8301f10694c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d00000000000000000000000000000000000000000000008b6dab94f5c0b00000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000008b80d8228c84f7b00c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000012c79d53c9a7a164161311911a3c33533c2c74ffbb4b88cf164e68779319dab8dd241012219023151cd4226dbcb1270eaddf920dec8919949f260f5375fd90c7ee208b31641e1d918ec4816b92a8b870b0410def69d5269974e9a40c65a5f48b76d7446741c70712ec3bc408c00315acba7df1a43d9e98d484b21546a68866bb06b08c33db93023668ac1a958153c3b519ce4488cfe2c1a9a27295d03618d262704cb60fc535d433cefba8d4e97c07e054749cd93d61b1fcf19419b702d8a0c786c2f1db2f6bff80bcb997960c0d03a323641bd0f37d6375d2a8740594be1810499813bb36a917a3801d1ed4228a19de027d3cd10c64e12398c8e836a4e25c01fd6b643f5d9ef94bb41ab758c49cc538e1510573fef366310385c2ffa1683237ae8e2981597c63559b53e7563e9b6917feacbc507590fcbcef99899f1aa9b7ba9a04ee2bdbb631e63e0dd22288842600cfcb55d8cc971725b082745bdad690cf40411952d1ef65dcb635cfcac9e2f74543cbeccae33aa05191f1422bc9085e9c43ae7ba5306728c30ee2345a3e3e81d025fce344f8e7e1f2b4a7b79c52ad7f6f327f5520e52bfea7881a8a82b097985d1012e306bad81a7f4ac189081dcf5d9de582d335e95c2a827957891e92ae6e48698388ab48babaadcefbb51b3c7515d2dfe613bfdf5deb667a1f9ae577ae021a46608d9a140d92c6e79a344f8b9d198102f8c71d637bbd325b87ab4c094dd4ef5df9a1d62c6dea6d0f573c21dbfb086bf7fbc617f85f57eb6ae6a910db84ffd7eea166608f0587b82a0d02fa84ac8abd81c001a0ecb9a0106aba31dafbedfe0c77a5054a867ec350ceaafde6655330e17c51aad9a05472964a01241224b46789835b7bb2eddb2659a3e1e3aff00539c7d9456e822f", + "0x02f90334018206c884027ae63b850a5899c27c8301350a94d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000016440000000000000000000000000c6cb96cc1727ec701e5483c565195b01e3c1da2b00000000000000000000000000000000000000000000000fe2311b9e95740000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000118732a908110171cdd152f0a3fc1abdfedd326cc62d279c4f28a9b5595ce81215f864fd8afddb03cbcc72cc8bdbac50ebb3ad793ea229920c2e0a33fa3d31403168e65f5a67a47911aeebae614c59384d9b710e06aeb53f8b397a05c84c12e037c758d2c4672089b0b54ef8003e632bf4ceab8f16fcf3f60aec362b30d52cc44b5ff0a66ce5a0cddee227f20435920ee5354c1a27f3a71113aeb5e4124dbeb7e9f684b97327d4179b5cc4f84d7bbe1a7016bcfb84c0d07c56698884b96b4a6d8a8e757818983df1d3b28746cd8d29174466c10786844bb9200baccbaaba67578cda6b884a929165392c4c002206bd42d59137e97cca3fe6a31099161f5f5e28307902cfd27c9a729e8cb6dc30a9180273dfa3d67a2b0bdfe98d15d80068eea87d55d80453cd5dd41b0a179fe877b90d8d8e6a44423ff131890fe611ed2ca7ee67a31f3ed77bb9215bacf9b47da600d53e372ebd97552ba37731a731b2b490c83e21a90b94a8d5891299de2a8fe58144ac34ba0b0f5226bbe54fd2cffaaba4bfcd67e931175e5b4c8b0a956f3d164cde10179a7583ba29bee3eadbc2acd1f0d6df9677a941d7cbbd94ffdf154c6736b146b862f9de6449d0d550ac055f19596abe3817ee8a14f49b7efe1f8351d9e474eca711776c9d4b2f80a01e0889a1e8a3497dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec001a0f413a42bbb6c7766e0bca787f8fd339bc0e9fdb5a170f37a469e15fd3e51f47ca064ba5cee705f894a66816f51749e824c6d06c5d61e63511889f1ccf2b656a6a7", + "0x02f8d1011484027ae63b850a5899c27c8302d57d94401f6c983ea34274ec46f84d70b31c151321188b80b8648b9e4f930000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0000000000000000000000000bdff5cc1df5fff6b01c4a8b0b8271328e92742da0000000000000000000000000000000000000000000000056bc75e2d63100000c001a07b84b299752ff51bbe9044c23d2e00eae36dcddf553f0c9b7ae8b15ef15d4d76a071178b276c2229e62a6c13d780d7fec337f50a25166d1ac649dfa85c1df34826", + "0x02f8b0012484027ae63b850a5899c27c82cb1a94b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000007c26a37ff4c8ba0c1b6168962357af069f5cf5c40000000000000000000000000000000000000000000000019274b259f6540000c080a03e9792907cc384488940415cd89f881a489e7de53941e6dce224e9cfd9eb16c3a046e768ba26b8d79b7efee4ef9630e1d5cb9c347ed2a5d99c9bca7a246bbeb9de", + "0x02f897015084027ae63b850a5899c27c83015f9094abea9132b05a70803a4e85094fd0e1800777fbef876a94d74f430000a42d2da8060000000000000000000000002fcf7eaeae8a981300e290f1cd38435a25fd8972c080a02abca7a9bc2e5893ef08421b904b44d7ff98ac11696ad65953a87dd0580fe644a00b6d8abce4d09e0d056aa4e07f752e899327d0f497dffd5f1175a6d75e1f250a", + "0x02f8b20181ac84027ae63b850a5899c27c8301120894badff0ef41d2a68f22de21eabca8a59aaf495cf080b844095ea7b3000000000000000000000000216b4b4ba9f3e719726886d34a177484278bfcae000000000000000000000000000000000000000000095e57656aad8fb25f4000c001a0888717178b845b5ba2021bfb48eed6373c9c1b35ab3c3199e9fe4c08c475ab7ba012497eceaa72947f3704b314f9599a88cde11852e59453994c02d0c13a5e317c", + "0x02f891018202f984025c1cf785138daa3288829b7194c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280a42e1a7d4d000000000000000000000000000000000000000000000000004bbe6d529c8000c001a0a31ac549502c1065a233d3a8b2701c0696c5b5b72742d9ccc9d4c5ac4ef6d82ba0131dc6fd75219cd0c8d4403420a60acf2a3e5f666557031aa8bb2546da343cfb", + "0x02f8b301820488840255f2e1850a9a1ae67e830186a094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000caff156bae012babafc155b87e8c7cbcc94fa73a0000000000000000000000000000000000000000000000000000000001312d00c001a08d3dbf07a9abe69f705971bfe4a9fb84f212464c0c2eb37a68b721b4361fbd7ea07351f95594f96ee8a2710879d90e0df71697ad94b0e5c6657a907ab6c9a3aa92", + "0x02f8b1014d840255f2e1850a7a35820083012e8894b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb000000000000000000000000a8f02eefbf996f74830b833ee15c8eb1480bf1fc000000000000000000000000000000000000000000000096684ed80d4a7d0176c080a03c04f09647d9697264f6046da50039823f3d3919f495cca499cd2b317a021188a07ba1f490e5f3a5f1e39a6e9cf52f74566960dab3094273e3ac530a0d414fbf3d", + "0x02f8b30182048984024402a2850a6d274f32830186a094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb00000000000000000000000078680dbc25dee0c01b0897b8439345ce1683e3560000000000000000000000000000000000000000000000000000000002160ec0c001a0e7b7ddb074a2e81fe9221c661c7f04db1ef9c4cf3ed9f2bce1dee0e4bfdf3a69a03afa2e314f35665969eacf3c6380e976efee109d8fbe53a9f5eca43bd0bd755d", + "0x02f8b0011d84024402a2850e14ddd80982b66194c5190e7fec4d97a3a3b1ab42dfedac608e2d079380b844095ea7b30000000000000000000000006131b5fae19ea4f9d964eac0408e4408b66337b5000000000000000000000000000000000000000000002f00399d4efa8be7bed4c001a06757aca218063c654b6963a2c5d00be2285f3d4dde4269f3f1be64365444b50fa071369dee66f770103d6f530b337cdbcb9b29172e8fd02bde63443a4721c410b9", + "0x02f90379010284024402a1850df0ccb90c8301e7479469460570c93f9de5e2edbc3052bf10125f0ca22d872386f26fc10000b90304b17d0e6e00000000000000000000000000000000c18702f6e8994fa8929ccb3bc11c16150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232bff5f46c000000000000000000000000000000000000000000000000000000000000000032b00000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e097c54bd6e689850ba559f911d839513a146c6c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004d0e30db000000000000000000000000000000000000000000000000000000000c080a0c8fb0e9523d2e14a5c7cda5cf77e992406b00ee1e1c0858077570bce1cdc1e7da06ca7f945f2022058e7e8bc32d8863edac3c0207c1b5c9f9d4b6fca11bde37c2d", + "0x02f9035b0124840237ddc9851363ec0bf783034dbc94881d40237659c251811cec9c364ef91dc08d300c8761e9ac8a028000b902e65f575529000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061e9ac8a02800000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d696300000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004521c9ad6a3d4230803ab752ed238be11f8b342f00000000000000000000000000000000000000000000000000610e596dec14000000000000000000000000000000000000000000001038ba11f47e80675858e900000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000db531c166c00000000000000000000000000f326e4de8f66a0bdc0970b79e0924e33c79f1915000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80502b1c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000610e596dec14000000000000000000000000000000000000000000001038ba11f47e80675858e80000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000180000000000000003b6d0340394cb9e147b8b288e38615ae04f442a037bcb99fab4991fe00000000000000000000000000000000000000000000000000fac080a02b8db4a6d4b2518400cb078e9c533f9c38b4209ef428ec341a41abe79342dcf7a046d12b626a1bc12d40f0e35738e7ec00cc8b4eac46505e3c401f992c26b0c3f8", + "0x02f8b00161840237ddc98513004a65eb82b70e94ac5b038058bcd0424c9c252c6487c25f032e5ddc80b844095ea7b3000000000000000000000000881d40237659c251811cec9c364ef91dc08d300cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0aa10d5e5fc7223177ccf4d506104043b308579c83627e5e1a651b658bf4f2b82a079f7bc679ec874485ecc88bfbe609f96448b935648e389391d82c743cb3fadb7", + "0x02f903740162840237ddc98513004a65eb83048f5194881d40237659c251811cec9c364ef91dc08d300c80b903065f5755290000000000000000000000000000000000000000000000000000000000000080000000000000000000000000ac5b038058bcd0424c9c252c6487c25f032e5ddc0000000000000000000000000000000000000000000003fce4ee0d0a3114dfff00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d6963000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000ac5b038058bcd0424c9c252c6487c25f032e5ddc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fce4ee0d0a3114dfff0000000000000000000000000000000000000000000000000175054bc1384109000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000035c251d8ca8a4000000000000000000000000f326e4de8f66a0bdc0970b79e0924e33c79f1915000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e80502b1c5000000000000000000000000ac5b038058bcd0424c9c252c6487c25f032e5ddc0000000000000000000000000000000000000000000003fce4ee0d0a3114dfff0000000000000000000000000000000000000000000000000178503ced89c7950000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000003b6d03403802acec89594353c0cfafeb97b3368a1544edeec0000000000000003b6d034006da0fd433c1a5d7a4faa01111c044910a184553ab4991fe00000000000000000000000000000000000000000000000001e1c001a07df4ef996d2f377e92dbf974c93ba5d74f94542eb104dc18b88ff68fc8f3a38aa051944af075a6e0a09438dd4849ae54cd295cd863da47b470f39b37a43de82873", + "0x02f8b00153840237ddc9851363ec0bf782b71294761d38e5ddf6ccf6cf7c55759d5210750b5d60f380b844095ea7b3000000000000000000000000881d40237659c251811cec9c364ef91dc08d300cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0d5fd4213ed6462f0020c5e17ac04d843b370c575cf30b998df33dfe1f1ac3b90a043e40f0efa5162262927d66562caf3ebf52eb5575b4da17d4840723696b241ea", + "0x02f903540154840237ddc9851363ec0bf78304d71b94881d40237659c251811cec9c364ef91dc08d300c80b902e65f5755290000000000000000000000000000000000000000000000000000000000000080000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f300000000000000000000000000000000000000000684bb78722fdca33b5d149c00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d6963000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f3000000000000000000000000b528edbef013aff855ac3c50b381f253af13b99700000000000000000000000000000000000000000684bb78722fdca33b5d149c00000000000000000000000000000000000000000000000c9df82cee9a43adef000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002acf35c9a3f4c5c3f4c78ef5fb64c3ee82f07c45000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8e449022e00000000000000000000000000000000000000000684bb78722fdca33b5d149c00000000000000000000000000000000000000000000000c9df82cee9a43adee00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000381fe4eb128db1621647ca00965da3f9e09f4fac800000000000000000000000d1a47332acad7498af1efdba16158e11317eca4aab4991fe0000000000000000000000000000000000000000000000000121c001a0deddaecb2790f66ea83aaf2c329b4892f04fd90c0f3590986d9fe27946b5f000a02a67a210d147b633543787a213f370a2f7bf1c3b5ebdddbc2ab2b907f431fba7", + "0x02f8b1018186840237ddc98513becee03782b9e6949625ce7753ace1fa1865a47aae2c5c2ce441856980b844095ea7b3000000000000000000000000881d40237659c251811cec9c364ef91dc08d300cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a0bbd2417497a0a84e6021ac253cfb25b3877190ca4dd54ded96dfb2c54045294ea00a8ccb7e0717172be7fc98eb2ea9837125955c02dd7ea3bbf817cb08f5e9eb46", + "0x02f90355018187840237ddc98513becee03783035a6d94881d40237659c251811cec9c364ef91dc08d300c80b902e65f57552900000000000000000000000000000000000000000000000000000000000000800000000000000000000000009625ce7753ace1fa1865a47aae2c5c2ce44185690000000000000000000000000000000000000000000001175e20984c25dc799700000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d69630000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000009625ce7753ace1fa1865a47aae2c5c2ce441856900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001175e20984c25dc799700000000000000000000000000000000000000000000000001fe184bad716b8e000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000049839213ec5fc000000000000000000000000f326e4de8f66a0bdc0970b79e0924e33c79f1915000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c80502b1c50000000000000000000000009625ce7753ace1fa1865a47aae2c5c2ce44185690000000000000000000000000000000000000000000001175e20984c25dc7997000000000000000000000000000000000000000000000000020298fe8b769e380000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000140000000000000003b6d034048200057593487b93311b03c845afda306a90e2aab4991fe00000000000000000000000000000000000000000000000000e6c080a059274d263200b58de64bd5b6b4e2870a5d31980fde9b7a609e243e607d46d12ba028ddc7178997f8f8b9bef8dee39edc73128e15f2e2f39f391794d3411b3444eb", + "0x02f90232013c8402321261850a7a3582008302208794af9ba9f9d7db062a119371ea923ed274e398116380b901c4d4dfd6bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000065f2ad0e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000041681f92e2672de5ccc985a0df77bfa70dc9724ac089e41aef7b1a6076b5811ea9518483a459ca5d247c3146c3505e053e3d690b9b6f22ca23eee349f4de123f871c00000000000000000000000000000000000000000000000000000000000000c001a0fb6c12ed3d1af23643dcd7c9a647aa22097674678e44fbea34b2b0a1149260b0a07486831acf77cfa39a2f60e3fb91cd16ca6dabc29848e1d4825b592d15578d15", + "0x02f8b101058402321261850f1740c9c7830176f794d1d2eb1b1e90b638588728b4130137d262c87cae80b844a9059cbb00000000000000000000000028c85b08a2454ef405b845e3d108baf5d8d6801f0000000000000000000000000000000000000000000000000000002540be4000c080a03fedc0abf2edd7ede2b85515ccb1ee771b508ab7379619f47dd3d33bc2e847d1a07297b706f5b35f8953d9ca97027432a0680e146f68a53baa6007177cc133205a", + "0x02f873012e8402321261850f87688ceb8252089463b6d51c562a9e2fb2650c28c05d27b11bbcae2288016345785d8a000080c080a0612dff6683243894502490cf89854b3caf33f00764aab02789e52cc26b5f430ba07b245fe3d7ace87946b836e244551e3d7d33a64b394bfcae5e0521596eaafc0c", + "0x02f8b2018204e98402321261850f1740c9c782b73494bf7bc9e63635dc11b335d52b0349d0100a53a1a780b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba300000000000000000000000000000000000000000000000000008d0a10c782e0c080a0eaf6bbaf2779a49ce771c0ed11563f5748230d2f0f47558be738e332f1100a28a045c11052b00a265c9bb02efdc66dfc858a908ef4d58fc628f8c0edc89687171b", + "0x02f87201198402321261850f1740c9c7825208949129fe4b97011d32b35281fe35c05d2fd36773e2875ffceeda38d67780c001a0d3676e754d5e0129f4fff2c026f22d183771abc22143fda675e0ecb960b765dda057674cbfe8a53020105b740243d675a240bd46da34de8453fec627420a735fed", + "0x02f87201328402321261850fae8bdf9a825208949664d678323cf4a682787ca7e9a2335e4730cdf687121acc68ebfb8c80c080a0e8e1a87d79920d8c2bbfd3e1f3a8911e715aa570ae8176e4a1c5b8ffbc8725b9a0093feabcff683bc7ede046b7eec213a9e1d63b850406126952df6b0024318b17", + "0x02f8b101628402321261850f1740c9c78301107a94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000c66ea10b13d6d8de3fd2d76bbd3e180cb675d4e10000000000000000000000000000000000000000000000000000000253e6f6e0c001a0a5a4289bff6268cd720a5ed72b37259be39144f21a2f837b00c03ff0e1914fb5a04ba55a9752bd2bc6245641fe1718ca2bd0f5aa454a1b4537b849a30af9fc1dd5", + "0x02f896010e8402321261850f665f461d82b2789400000000000e1a99dddd5610111884278bdbda1d872386f26fc10000a4497ecfc5746172616e74756c333030330000000000000000000000000000000000000000c080a0aab15b74e697c021bdd41ab7c3349610f30e6caa18b378cd6d8232f1809ecd81a020c8c4d08051ba6b7ebbf59fb66d6a342db393f699a543d384d1a7e004669f71", + "0x02f903b201358402321261850f665f461d8301f10894c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d00000000000000000000000000000000000000000000007649553f44be58000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000764de477a6da2c66dd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000122b9301f12211091b5c1439304c70ac05b9f731e4b92755e5b4dbb87d890840f857eff4b70c6b9355c6cbdaf703b95e55d08aadcfa2a9098881fb337310cfd4cd0a110fe6777b61957ad3dac33eb927038d72bd0cf174a4aa2b5175bf371b2c45fda40e189bb1d92070b809e2aebfb3ce647a7b9f1d20d2a42cf5d35d92c1dc91be3058238dba0224dc1aa0d2b878f84fbeb44c7efe01b4513c29e2fd111a22689b0552d665418aa10950d1af733f89963b93f7bb13d7e98a43ebbe27c267ced2693613bb2698a7faecf270600b396f443b8adcffb83e1c52220a4ff2936540187f9e8c9e3746eee08d3b0b785853ca6deade552f8c7047b088123db7d71c0c68bd8adae3ff0991e54e12f875737f233a101e9f9c432a35c29ca5f5e5406b973972753f61b1d1a1d53e57cb49ac4ba169ade3c9f832cfe9ca051e7ede3a33fd142a15c1ebb77497f2693f6d6f1c1a6ca12b7375776a1048963d8d68dbd8fff367b009585a7687772a860b48bb4c14475230a654fb77e00f0b892ec571cceab002616c23c7359f7394255e917c6f10afad171615c27142b5362c58c805e91554d5c99568fe3f7a990d0f00b2714b7105fecfa26db4a56489b71f088208342c09247751e549c0b5d29e5f473b4ce26846c3973dc05e90bae1daa1156eb69fb68c9d08a7d0a6af883df133f4dda40a2bf9d18ea6e9b3b90b30974c74803005be777e854f5656ba40bc7ae01e2b8cb95cffecd7cc1fa7a3a3e69fa5faf5d26f1771383bdd1e5318b1af41fa68346461d94bc4793ebd12fd81ce5d0b74b62d096838eac001a0fd3b957de505fb31d475834c4002bf2f7e30f3d0cde973d7190f63ab1265ce73a031aa05fe24c95420ad65d3646968a7c8ba10ed8c098a01053fd52d774defe80e", + "0x02f87201028402321261850f665f461d8252089484b2d08156c84c4b13e3bf2063ca67de2c4c134487dd2fe856e049a780c080a050eb5301a47738ac132057ff095d8faed6cb9851b6542458cd1ddfd3677f4e81a02e60ad73e18be1a79cd123f0786ee8678db91f54b1842e68a8dd65dae28c8159", + "0x02f878012a8402321261850f665f461d830181c0941f75881dc0707b5236f739b5b64a87c211294abb883782dace9d90000084d0e30db0c001a08ff2d140a8f881038cbaca7841060ae30b7a0287f8a67acbc13ce75cbe124eb5a0704a4495b1ee4bab7706891891975e8d1c3dd4c4cf1961f213264907298fce86", + "0x02f902fa01088402321261850f665f461d83033622943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad8802c68af0bb140000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2ac9f00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000010be622fe2c756a700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f05897cfe3ce9bbbfe0751cbe6b1b2c686848dcbc001a0d135dc7244e37da9e1c2a04b15b14cc9eb737e9cbf71d2eef98bca360349eb99a07091c3c0e4a7b0f096a2bc27c2f91e520e3fc34ba7383f9a67e7016dde75cbde", + "0x02f8b30182048a8402321261850b2e2b96d4830186a094dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000092064b31442367f069493f51ed4d14e032d6bb9000000000000000000000000000000000000000000000000000000000200b200c001a0888c2a41170e984ba0fede837f2a07cfbb16d3cebfad4fb21e7da4a5375f4e8aa07c40d7fa2e7837f609ecefdcf29f364c8e27f1c934aef3ae662fc4eff1d8f190", + "0x02f901130182018f8402321261850f1740c9c7830184c8945954ab967bc958940b7eb73ee84797dc8a2afbb980b8a4381b46820000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000060bc000000000000000000000000000000000000000000000000000000000000665a000000000000000000000000000000000000000000000000000000000000080cc080a0d6e97ab62a9e2e044fc02ae5218db2757bf45897a1ee026cc303db9c1d8d09a0a05382552b59535ecd7bedc1e4da05aa24855f0776fcda86fa4e79e4493f4ad23e", + "0x02f8b1010d8402321261850f87688ceb830163db946982508145454ce325ddbe47a25d4ec3d231193380b844a9059cbb0000000000000000000000007727bb09f657285e725622dfac1fbbc4cc4d53d5000000000000000000000000000000000000000000958d7fe0d736a62fa70000c001a0f01b03a797aeb89befb1c7140e083b7cbeb4395ceba8189c1ce0f2afab48ce4ca011136de86153e7c87766c59d296f4cd6b7600f241f88718a0e21caa04f82a36a", + "0x02f8b001038402321261850f665f461d82b9e4948881562783028f5c1bcb985d2283d5e170d8888880b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a02c4f89ac1bbc03e4461cb9929bdf07b55eb85324e18d5d7a93ee51d227fb2ab6a071b2f31fe8281fe87d1548211bfe53ea7f78d70733209c298758af43aec406ff", + "0x02f9043201548402321261850f665f461d8306f60d943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b903c43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2ac9f00000000000000000000000000000000000000000000000000000000000000020a080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000443459d45c30a03f90037d011cbe22e2183d3b12000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661a375100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b15900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000418acf0eed453892c33c18956611fd7a453fe67a59c15fd5c282901aa18408b2490a64767efe3bc039078bd51e6523fc1b0a4c865573e251143aed0de81888d1d81b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000005347391d799baea63a00000000000000000000000000000000000000000000000000000000bfd3336d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000443459d45c30a03f90037d011cbe22e2183d3b12000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7c001a0950ce9740b1731bc910d705f2f8d7ac4fda429b7d655b8b2a28f3fd35598806fa01ee72c60f665e808ea7abdf5689a53a2dd9f87ea32c7545d92cda728b0392064", + "0x02f9033201808402321261850f665f461d8301351f94d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000014b19000000000000000000000000a63226a58bc0a378345e1622d511fef821a59b0400000000000000000000000000000000000000000000000324e964b3eca800000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001194390f2af59eaddfeb83a00f3fb4cab380b45172291136b83fd65f440631df09c269d1e7bac8c3bad9dcdc53e93fb917005b8ba8460400614616102cb366e9d660a930137e79674b56407ec34603eb2de1de0f2e71ef4e14e10d136b0877205c134c47fccece94b8cb074c85e89f114ed00742cfdfb597fee4ce7df3a6fb3886c48cec8b35efcf717891800b365e63d0e671d78109237a781f2a68076e2f70b6f4248d05bbc39284bcdc74880596219f6339797f60b8a37b26bb551eb97061e5507ec8848681e807efebd3b96ba7eea42c9b927eee9bb1ab064bc16f92a6d1554766b12352d059d144d019d9874b20ed0bc28fe4d4840ab773e5f26bed046f701839fa2ea0726ec1e2ef4bc3a210984aba417da6ad2ba67cfcb41564cbe89b9a8c24af951808954788e3be16411bb7d2e53581e4e957bffaabdbe4677a74938c88903050e582f4a73ac9f7d26b7de55baa5fae65de19fbb7f810cd5caa79cdbbe9055d2b141476a1d8c3885d7bda017ec8dd69549650f4740cea4896f8452a6e09fbe6ad021b6bb92e73c49e57f4128f03b034b3919d0a71c72f6a584a153ae1591b25fbbf6e15798754c79aa53f46bb2c72ba25bd77457c639d37bf351fb0973817ee8a14f49b7efe1f8351d9e474eca711776c9d4b2f80a01e0889a1e8a3497dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec001a0f1a5877f11434609b67135e6df4fed2711197927b2f950d430f1f6133630317ca00fb410b65167655b67813c5f2fae1f0f0c638619df7c0dca84cea9ac249f5108", + "0x02f8b101068402321261850f665f461d83013157940581ddf7a136c6837429a46c6cb7b388a3e5297180b844a22cb4650000000000000000000000001e0049783f008a0085193e00003d00cd54003c710000000000000000000000000000000000000000000000000000000000000001c080a0f8a54ccda0ece2e5a204929251e1012df3edadc269518bdff0e7f7f4ca593249a016e81a85f7393e612d7da187e900eb91049de308c465ab3af66053df1a152b80", + "0x02f8b101038402321261850f665f461d830108179477e06c9eccf2e797fd462a92b6d7642ef85b0a4480b844095ea7b30000000000000000000000006131b5fae19ea4f9d964eac0408e4408b66337b5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a084e06bf2909bb553f239c628069e6c20635360500dd4173d5028ebd6524ff83fa05e04527a3c783d15e137489a74cd4bf68b7913f13cf5b0743df3c68b01563040", + "0x02f901f201058402321261850f1740c9c783020f0394762340b8a40cdd5bfc3edd94265899fda345d0e380b9018423dc86580000000000000000000000001ee2019472703d22dbcac3145801fd514394045a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000f0ef0e6a1fd61f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000c080a0fa014677216ad9bcb693bab30b366a9c2f8ab1247b20f480c6da1afb0e32533aa051687ec70efb085d30d94cccbc8a9a45e6609e8718ad8e7b079edce0911936bf", + "0x02f8b101018402321261850f665f461d83012e8894b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb0000000000000000000000009c036b0d0b39a0a411c0cd7df36211695103b65700000000000000000000000000000000000000000000008f4c4a17ac4a4fb00cc080a08d8c6c2c49aeae62f43940c12e58f5536ba7fbdc220c314ab497e75239bd678ba07c22d1c0bfe6d99cc349129d477f1964117e93f08a8cae3ae50d7bb02b849f11", + "0x02f9033201078402321261850f1740c9c78301352e94d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000013814000000000000000000000000eb661f50946347553a806e9aaee5bcfb9c8fc58300000000000000000000000000000000000000000000000cbd47b6eaa8cc000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011b6b3ac0e6e42cf52b27202f6b03f9a3f2437bf5461304be35cc6b5ec4b21dfc0b4ed981b6908b70a43ff47851a37ca3257ac71c9dd8f38721784acf084bc62b7ea012460b205f5377bf2139e6804712c97f1dc6a360f19de92560c3e6d4971fb4a1de7b45fe51e2561b7410d9d3c068473cedaa81b54079e987ae664e6594ffb4fba75bbf5238ea11efdab4216f81103a5b4d2774dadabe17e661979086f6c38ce9e370619b475db925c715d75616759dc6bc50ab8e165d9ba012fe327063ae7e89d04777570f1d8d5f7d81cab855a0de5458fdb08350fb9c296bd4f24e1542f787c6412a2a82fc3a92835edb61bb023ce0f6c83fb7dcb9cecfb47183f58d30c8947ad445981bf9ed186485f714321853be4db42ce142369baa0790512b4e5ab9630148f919b4cb1785db3b6c3cc321a6c3e9167dcce46616075dcfb83a694c407ad21985c0a7b220c77ec1c4d2ba832cd5e2b80964ba4b60ced2b5967de3919578d7be013075f6f887937e87075ad37f49a82d0be743328564015ddc49e3faa3a2daa97f744d166ab5c9b170efc3e9fcf70d2dc968e4cba43ba29ed414753c8439869e225fee3df7bead8c9c011e7e36996bef45fc334cec3a7b3dd000cc2801845c13f25cbba3d726231691cc1678de0936fe89df8d408c9bc344d58d0ae0a46e70d0e09debcd1ba9ca8ff28fa3dcc7b1318cdac64c0b387c56304d964a2f86643f31da169680b58a8548f4d3144a13fdb0eb53a2844abdea2d4a0c76a82ddc080a0b0cb26b52bd73f1dfec7e0e428942e18fa7a7f9dd925b84c6e5d9add528b987ba06b1d2869e0ebe01dc7d0a4837a15c88cd2c9c130d5e6f1a45627f658d5c9a716", + "0x02f87301108402321261850f665f461d82520894fc1c0057ad6a3a645cccd87dfc720bc5cc1137d18803311fc80a57000080c001a0127ff81d34a94405b5521e4afba7f4ea406e9458640d10342364e6d254073696a05cf94fcd762510fb197cc9077483bd4b223d87265bbec688658a3bce0a072f56", + "0x02f8b20181888402321261850f665f461d83010ad694a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb000000000000000000000000f860c6f05b8b4ec01713f7b633e449d7842fe8d600000000000000000000000000000000000000000000000000000009df3ca800c080a0faa297d6e8ed0deffa1c0ae96c6ac7677eccf6963a7fec95970904fe5fc305f9a00d24e3bcaf3b750b5491f5efe90d1d6a5cd8dd519fd8ef6608f6a257a1e4555e", + "0x02f8b20182015e8402321261850f665f461d82d477949caae40dcf950afea443119e51e821d6fe2437ca80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3000000000000000000000000000000000000000000000068a021666bf7e80000c080a0c49ff78e1ba68873b04719c0f3fba1bd8066327297575c2776073660fca27639a033d9e60e2da790459e57e8d9379a14b396d18c130697cea37b1a73362a7abaa6", + "0x02f8b3018207788402321261850f665f461d83010ed994dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000000cafe46342839aebfe3c1681858a63e7e001d12400000000000000000000000000000000000000000000000000000000c7ee7f3dc001a046371ed81f873bfb11de0d4395f81d2eee06539c322d325f10d41904ad7dbef3a05bab90e3a2258871f3f5feb86c8c3fb15126b04b3be7afbde919f4dd1a74e4a5", + "0x02f903340182026b8402321261850fae8bdf9a8301352394d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef00000000000000000000000000000000000000000000000000000000000054d2000000000000000000000000360b74a47f58405bdecf33811b1f2ca37dc6632000000000000000000000000000000000000000000000001e3fce3b96dbf80000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000117643c34564ee65554b935216a2fceeb1f20a5fa2c7ba3e0ad43d12495b0f2c779da74ed53b314419f0ee67673bc7d7c69faeeb8e6e145a3bab84e18546ccf9c388a670d0a3dd378436388898006318c7b29cc7b32e8e4d21e53d12415b8036e5b19ca4dfb85c3d81a67894640d96d9d04c35c25f6c7f2f0d4617511af7341d8b0f89e3d06b6b60eabea0c10c26f6c2f0ae052eee97dc56979d10934d667254f8ce58e2dbe02ac61991b93dd27420057aa9a5b788d2e6b26980e5b99ed22d62ccffcad20cb3a231eb9207b9d5ee49f21e33cc9fc9b49f5298ef95210b73031edff1de20088c7d63878caf5894054b43cbe49f36c335e2197241558d0f9320257667aca37604c499f561893e445d902b7350939f1d1c88cd4b50f402be2109027d457494fb896986cfe3f181244b524cde7eeb2d276a549017e92ccd0ab84e8579f2eaacc6dba099e82f6f93ad3d883a6a716e2fa31b35e9bceb0facfb2cb0129d7945c56895971f627fe10741a146767da1ac6d8523026e96448b5ba6cf8b2622cff34b45f6af108a4107137de77c7f9c0b613280b7edc9e12445fe2d195f2fed4cf815d551368b549329d7b042ede0c28c494ad193986346b46361f9af93ae17715588c2b8020767b738ded790362d7cc47224f2cf2342d412a9bf1d274da0ce7dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec080a011ab8a91c7641ba407d70b75dd58cf4bdc6c93f53019e2aa831e270c81979d5da04637e3711453560bbd56160381a063fa4f003e11f85de2c0291c52fc9931c65f", + "0x02f902fa0181958402321261850f665f461d8302e771943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad872386f26fc10000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000002fb15de259f41666d587900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb86982508145454ce325ddbe47a25d4ec3d2311933000000000000000000000000000000000000000000c001a0238952662913d078c6cc41f5c08a8ff28d7b9fbcb358bd419c882da293ae4fb6a062697ccd2dff92d0838a87f9a47000ee37c210fb12f0ce361706ed820459b624", + "0x02f902940182015e8402321261850fae8bdf9a83049f81943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b902243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb7000000000000000000000000000000000000000000000000000000000000000108000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000050d75868eb5367a808c00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000009c7d4fb43919def524c1a9d92fe836169eaf0615c080a04b0829056df8d5a983429457be58ed9eafb0b5f8981135af1a046e703ec613fba024b45dcb081ad974933469c511b1b473a82f6492f182433ef647c219b0169d67", + "0x02f9033201148402321261850fae8bdf9a8301351694d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000004c340000000000000000000000003080feedb94968cff5d729fb55b45c247ea0c2d300000000000000000000000000000000000000000000000324e964b3eca8000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011195b88203e4a838c3fb718e9c2cc16171d7b93cbfdcad09802188cf5acb2e8df6dd3e179fd476ca82414a6fb0402eb7e932871ff012e5acfe1682f6b1499ae29c1a734e4ba86efb452dbe3461e05c012708c648e33ff37cb9089d1ab8d0e3be68f6282c330423e1ef0039c384b96852eec776f20e32e2d7b5115e12ad6d06aa3ff426b08be3f4f00af57a3395f9e053a61b393ab060171dec92875c40efef1eb724ccbe9c6841f384292df597a050035e18db429f9bbcad88e66cbc50826d518f68208432406e8a3bc5214b9512a2879b0509efce80e9418149c93824ba5e089764d0168ff19e33702a6db13ccdab0faaeb78f06b164ba03733d50d19673b03baf510202f9fb2fa0341e20fbcccda0dd2c451ea8e8075ccaeed299da743b0d8478230e05e4cc67202d1fb5ed9cabbf75fb682fc5691e856a992e862676316e7505957b9a137898a6e3540b9ce378d86f6bf7bd68b963cb8eb6dc40a3941024ab4e0d0d831d1cd2d01aa888afbc977b387fefa75dd096c01e5a0e8090fce0f5085ef2cb32893e0a26c5d7f075f7ffa6f7fe9ea3258030ca715d74316c694bac6e9407c090febb3a91a6e3f839b6a54c1bcfcfc56dfba4d0ca8a3535168fa5b3b0866b8614da6d5761eba4253b79baf01b17cf793a6056a1204b3457acc3cc6264b2f1729c555dd226f68ac9786871adb4125748b57f44524ee6f108c017fa8db8340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec080a0a5b9c63ba5e1623e80d1e7ae86eb0e7e5fc524562675cc605bc457e71c257a81a03136b1acd168a591260c63c5978d2bcb8c57e25f9155ac3d6a970f17eacd5f93", + "0x02f8b901018402321261850fae8bdf9a83045f7f94d5ef0650ac086c630040981b604a0da99db03a8d8802c68af0bb140000b8442c65169e00000000000000000000000000000000000000000000000000000000000003530000000000000000000000000000000000000000000000000000000000000000c001a0365520ff5101529d569acb144a236b6a38a78e8fe965cd519ce0cf27eff2a1fea04882d68d6a99ca87973c6e964e4124eba2178f3790d1e3fefe97e43f2298ca03", + "0x02f87301048402321261850fae8bdf9a825208949508050753dc8290f0ee277b4fa4a6f6ef4a21ab880640b1c362f9253680c001a0eb00cad830ec22a2c8a0a31b15d2ea7464941fea00ab79aaa6870f9dbfaa18a5a01560f042fb9119ad01f0c43afaae30a4dc4618523e04064240f068f9821df739", + "0x02f8b001438402321261850fae8bdf9a82b5fe940ab87046fbb341d058f17cbc4c1133f25a20a52f80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba30000000000000000000000000000000000000000000000000054f7866df32245c080a0778a20e2115ae2a7eac6c0de139fa6becb66b25dcc2592d3cd6d9355850e79d2a02f7a10195e35556da897c41fedbda5f9e414536c7edca6f7e4f567cb1d50e5a1", + "0x02f872010b8402321261850f665f461d8252089463c138ab7ae4e23838e144bbe30b1e57c1fb13b787354a6ba7a1800080c080a04f5ee5b0dd901bb31c48d8cc04e8d007f0ce2638338d30ef77df5969b0ee6d44a0422780cb971372138b8e98f841bf86081279726a0aba9ee6d0944a6e57fcf619", + "0x02f8b101048402321261850fae8bdf9a83012e8894b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb000000000000000000000000d539cbbc9b94ed0aa45ec11e8899ebecc4c3775100000000000000000000000000000000000000000000008df0a9582533a3062ac001a0446fd470dd2c2026ce8aad395e47ce5440816dd65beb06c325fca6dec73e10e6a032aaaa2f4091277f3b0250ab91868cf5cfc21cfafc3475542212c7297223b895", + "0x02f87201458402321261850f665f461d825208947035779ecce3e39c8a2d9b93e56c455f9d374a6a871aa535d3d0c00080c001a0fc5fa7e99a4312edfefcd871bbd93ed8f5764fb8eee2528209ec1ba2c071d163a02ee13da09ee628e447e7069891355a29cd038565909307eeb001b48dfe0ebd64", + "0x02f87301138402321261850f665f461d82520894740b03827195bc8514794228e198553d05da958388010bbda1790ca00080c080a019ad73040edff4b600feb890f422b67ec8c85d6b8a20688eb79d894a3ff41daba0427f80bfab9117fe63fde57cda3ccc006db04feff7f2ccc375a28ed4b9509e0a", + "0x02f902fa01078402321261850f665f461d83033913943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad88013fbe85edc90000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acab00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000013fbe85edc90000000000000000000000000000000000000000000000000019875e1fc7e1612a2400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000040e9187078032afe1a30cfcf76e4fe3d7ab5c6c5c080a0a55c8c8017fb1c975aa1b70377a47a6a5f9fa6c89592a46ff4abf56f7c15881ea071390df75d19121e064ff54aa7a4273a28571351cb087bee86e8a8aaffdc8300", + "0x02f9011901808402321261850fae8bdf9a83061bf794daf1695c41327b61b9b9965ac6a5843a3198cf07880e05113270345b6db8a48b886bf20000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000d38c590f5b6d0000000000000000000000000000000000000000000000000000000000000014fe80d2652aa4ca20af5d837942e8914ef0cfb4e3000000000000000000000000c080a0760619a801b84b6895b003ef6ba2297c57fa99ae12ed38ac693d5c706913116ea030884a4619c877166355130809ca2389ff434e44bbfa602091535d181104fd27", + "0x02f8770181868402321261850f665f461d82b16a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2877c58508723800084d0e30db0c001a08a7489c7a293d32745bef66a0520f35b8bd4e3163e65f8178d1ba90430cbfb64a0455b4911858d8c37b35a02bb38d307f2ba552a5340dd909bd353d847c5ad932c", + "0x02f87301078402321261850f1740c9c7825208943215cbe32ea8ed8b814020d37679a1f3c1556a3d880de0b6b3a764000080c001a07f7583133d837914da04ad9ef2061992dd3e8be6d185e5c285872d4f4746b265a07716f7d4db4b8131bc9fda79c8cdaa7fffb5279158b7efc76d642c899cf709a6", + "0x02f902fa01808402321261850fae8bdf9a8302d7f3943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad880214e8348c4f0000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acab00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000214e8348c4f0000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000214e8348c4f00000000000000000000000000000000000000000000009fbb4a25ab41e66571749d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006e1649cef61fa17d647b9324d905c33fea71d020c080a0cddfcf6fe79417317dc0211e40f9ff1c3330f5b71035e6ec37a95b87d361abe1a00c369af641631aaee98f57f0ff8ad8788c608eafb962c20ac931c2f426bef1fd", + "0x02f8b1010a8402321261850e39ef311283010c1d94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb000000000000000000000000aa6f6b7cf8933c693d4f6db5ae1cc09ba46f040e00000000000000000000000000000000000000000000000000000000e1e56addc001a0d3506d0ae42af70ad1980d0427c536576d577c9178399ef129214ab5cbfa489ca0486c96e76a64be007467182af020afe697c31c8f38c00eccbf95607f28b5563b", + "0x02f8b001018402321261850fae8bdf9a82c95794b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb000000000000000000000000bdacd9db71c5d6693c459999011a42ef2338b9a70000000000000000000000000000000000000000000000821a476ac5f4ebdbcec080a0d62805f6da63d7748d6bf6580759260b0547e4b4f534d4b3bc9a0095afda522fa0488c353d4585e031f930c0f6d3b7b59b5a864298eca842d97bc1d540a463736a", + "0x02f87201188402321261850fae8bdf9a8252089441b4340518e7cf5c3b1c8aaa3cf12eb30f55ae3c8731406966e33d5980c080a04aa7eb08cee25ced72d3671b4ee325baf481425e8b4cd8ea6d6bef667bed825ea00e43cd2d919503b5cac05529d0e71d67bc4863ba4754d1a907876c74aab8b24d", + "0x02f87201268402321261850fae8bdf9a8252089417eb0db3ff2833bb8378ba07c2181182e043942f87581b77f66e000080c001a009c0527ea340cb11878b4a5131a382a7ed709102fac5ba1d7c71d593334d4831a02710b1644acfaa2d0d4c61220ea69b66545e0631a21fb1f7703331faba61e846", + "0x02f8af01548402321261850f665f461d82d5e8940fa0ed0cbe0412379cd181320c93448968c76c1c80b844095ea7b30000000000000000000000001111111254eeb25477b68fb85ed929f73a960582ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a0bbeaed1d2b16360bf416147f0c48880145f7c5b0047f62308e64b1bfb766d81b9fbbd0da1aae8d6ffa9bec0cc9996bee8ad52df23a3d5d5e9bbb7ea74d0ddb2a", + "0x02f872014a8402321261850fae8bdf9a82520894cdb464940593849637aeaef6dcee5bf84870e9ef8758d15e1762800080c080a0df64057ec01746587788e568dd88b08b359021909560a1c644af381d6e954321a0026f09f973356426576b3d1478b366b2ba2db214efc5948d890bf6ba6f8a728c", + "0x02f890012b8402321261850fae8bdf9a83012dfe94ddcf9101a653053caabb692de87e1f13396be09280a45926651d0000000000000000000000006521a22e4412450924294f8a46693ef4c7832bf8c080a0c4ca739952648435b50647e81ebe61150a130e8f1fdb8d7a862a9c1a14fa5e33a03eb3f4c186199c85874b4e770988b50574a5894597d833da03878469094b2a67", + "0x02f903b201098402321261850fae8bdf9a8301f0ee94c059a531b4234d05e9ef4ac51028f7e6156e2cce80b90344e1c8455d0000000000000000000000000000000000000000000000a6db469844dd54000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000a6db5cde0771dcf5b400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000012cdd74b9d5714df3629f3fcd00641d8d316e40279bc811e185f456a7808d155e36e52c93b17649808499dca6e9e56eef3a9683b8d153b8133f1dae24848d5aed7cdb2691f7d62ada7d47dce8a1f5ce763919ea139a6d50bb38767f4b00d9ff0c73cfc26e4af3c94e82c9393007e1dfc8a612143a7f63aab14622c2ea2248870d07f8ac339415f28673e70d865819abce96771946d9fd402d66c3a9dca92e7ac442e51f21b9ed332a971e452b7f4cc3e3572dacf58ef25d7691ddc797791c5379da7882dd925b43f381e0c13236402659c1496eb56a743375a3e46e7c84cfa25bbe0e4eb21c8aec1ea433c4435ddaed13c853e8fcb78ee48463b9b609cceea517dc2e6d92165ef7efc5f930d1d027d54b76a415d792516da7972a240898f2aa05cc7287899fa7801130a5cfe51000b39fc6274ec55e225c31b7bedf517a7853d95ce6f2dbb05e6f0f7c08b1309f9a611c1a4b497f62c72b491cb136b69985104c83a63eb04969561d7c36aef460924d0218bd47aab003dcfcb9f518e80f9eae339203ec2b486c6acd2e21b0bb2702207d3a21b35d4fb613114ee252ad6a97c953d7d39df87016ace7efeb8480eadf4df45f07bfeb149c2ccb6b25acbe0ca7ee734df4398f883c3ec5f9daa4a132dfa3bf9e0aa65c2fb4fefade4e7b7ba796d20dcaa9c4e09daa1573e7616f99d98baeb8da41b5022cae119a423c520f47a9a9f35dce35d50a6905ba18322eb5c4416a44e1e083d961e1e3f483dceeddb7251b8e8fbc617f85f57eb6ae6a910db84ffd7eea166608f0587b82a0d02fa84ac8abd81c080a0aced45c5a93c26c891be8df1ff0a9a48304722009579db27ccb96006d31e8629a04ada4f98c7048a3af2df6ef759c86ad77a1489f5703e8de8cb3924c3d6881519", + "0x02f90334011d8402321261850fae8bdf9a83038e3594881d40237659c251811cec9c364ef91dc08d300c80b902c65f57552900000000000000000000000000000000000000000000000000000000000000800000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000001a93c600000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d69630000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000001a583e0000000000000000000000000000000000000000000000000000000049ce731d00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000003b880000000000000000000000002acf35c9a3f4c5c3f4c78ef5fb64c3ee82f07c45000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8e449022e00000000000000000000000000000000000000000000000000000000001a583e0000000000000000000000000000000000000000000000000000000049ce731c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000009a772018fbd77fcd2d25657e5c547baff3fd7d16ab4991fe00000000000000000000000000000000000000000000000000dbc080a0052aa2e2c98da00b5eb229fd856fe757a30e3343c88ab8f41dcf8092e0eb523fa066445249fd428f61e36a064bb5661f8d71e8e0e28ecbfbb16648d5f776d526a6", + "0x02f8b10181dc8402321261850fae8bdf9a82b56294c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280b844095ea7b3000000000000000000000000367e59b559283c8506207d75b0c5d8c66c4cd4b7000000000000000000000000000000000000000000000000002e2f6e5e148000c001a0809603385b6eff734fbcedeece19358442c2140fe8f7f927db0626e2ad29116fa0505d09de9e5a2f1ae0e5740a0b518c47278abb398e2726bd47fcb47bc6edaefc", + "0x02f902fa01088402321261850e39ef311283034cf2943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad8804463c5e3ed20000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acc300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000004463c5e3ed200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000004463c5e3ed20000000000000000000000000000000000000000000000000049eb04a6aa2488eb2d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d584a1edb3a70b3b07963f9a3ea5399e38b136c080a01f3c164efc72911c467fa444708a983edb6753bc1c2f38944a8e21f033e2b724a06da500c1a4f8eb0d601dfe4ed057dd0b01932e630b2e8ab97f13b54c8bb80030", + "0x02f87301168402321261850fae8bdf9a8252089494e23ef804909b4c85d90489aaada343bafb93b488017508f1956a800080c001a0a581e17beea46b95ce6d4d415e864bce39a63580817e83dc6c1ecb7229301003a01de35e5fd95f86fa37bcd2d79d29ea1ec2e0a24056aea2aacf91d1b2bd203767", + "0x02f9033201138402321261850fae8bdf9a8301350b94d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000009e8a00000000000000000000000064f8f38c4e39db50f76809acbf946bd6768818a6000000000000000000000000000000000000000000000007ea2832757708000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011459ea156e342e9957607f69e5470ecc5750e233afdba5d26c09030180b09da68603d47bb83621572e33c6844d33c22ac6d9aee8d5e1df7aef7e9bb1d46f865af97e740e3096213cb9ac6046ac8c61367d74cae92196249bed25bf9dab3b14e812c67d0a792097b6b04157c69853966a55f7647ba08909f37952cf89bb3b2dd128f74a429e5306e7995f593c421da51e04d4bd0ec06844152144a84829b95b13d2a959f83fe00fb9fcdbcee3830f1eb3b4fc0577e442970ffe4242501f6e072bff5a862cff38ae60778ae4b561ed9a3fc4fdaa2d3424198a3ef80e5f8c2836211b1f9d7d013ded25f0395e37a937d83965dd2b8db715805cad78958f053f40900abc2decfd6081a33a7a8e2e1836f94ef10a167146f67afa9b85d8daa37aa36ba4870774461ab6eadbafd2c2abdb849249ccd5af4144df5443ebf2dfd342e553f789a8a5986783c101f8ef7e11a253d87a07ed759ef2f71e05bbfe394f43e68284e9248e641ac65ef0d5fdb167961f5e76aa1d90d2eb49580b5470dafb3019a3cd786957bb72b9c8b91cdd7cdd256f1f7a3c401d12ee4f26e629afc69ffb97c8ee4df041f6d001a4c29f64bcb7dc7037b295e66ea154b33e6058d3ef6551f90fc7391105bbfc6265234e9cebeffa9b2e702d2341a1364e88c56b2fde302cbd6fdb2f1729c555dd226f68ac9786871adb4125748b57f44524ee6f108c017fa8db8340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec001a0c99925d1128e1289f412238946c5b481ab27e59fe9b07d81dec02a78270c493da0572e4d32df8e4524232dc684686367909abd423091dc0783e1792daaeeb23e27", + "0x02f8da018203518402321261850e39ef31128303f0369445e563c39cddba8699a90078f42353a57509543a87023ce4e8c9728db8642556e453000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000010c97e6672ea772e6417b8cf679f4751f4006a80000000000000000000000000000000000000000000000000000007ff2fb10a2c080a0800719cd161e4acc2fc714942f46e0f45974d107a20609a69403bb44e8e4432ba05d41cc8ca167f8f5b3e6ed3907026ce84be5b384c0fe17df1e234f300f5f9644", + "0x02f87201018402321261850fae8bdf9a8252089440d6bb06eaaf0bd7515b484990874d74c9f7f1ea8703468b8360cd4880c001a0591cc2128d0b836f61ce7ad5591243f23aed0bbb644346ab3cf0faa5b6e81847a06faa75e33018613337c391be9ba715dfdd4bc8edd84689f50086978b467d417e", + "0x02f902f201588402321261850fae8bdf9a8302d102943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2af1b0000000000000000000000000000000000000000000000000000000000000002000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000bc437a25d298be5d000000000000000000000000000000000000000000000000d92dc384510bb70500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002b7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0000064c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000d92dc384510bb705c080a0d5b0f49bd4594272a90dc96fc681c68dbb3aa2790bf00bb94a66b32ec9a72e4ca007b2aa900824a87c39aeb6de0952886529208513d69dda2aef071c023145efa2", + "0x02f8b001218402321261850e39ef311282b8f3947865ec47bef9823ad0010c4970ed90a5e8107e5380b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba30000000000000000000000000000000000000000000009a2c7453e23bfcbcf5ac080a0cec872d692a946f01c84c45013b8f29b1b43c0e73cc67d6e4c7545b013955b36a00845f954b1e99117e79d15325fad9352c5a35f71f2aa51f8508c6b0fb071eb94", + "0x02f8b20181e88402321261850fae8bdf9a83034129941fde0d2f44539789256d94d1784a86bf77d66dd080b844e2bbb1580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5949f4826178dc0c001a019e33ac01e4b6135deec9db4707428e16e9dfc9512061c923fde0f7ce836449da032a26b7be24065311f39efceadde5b10eeff49a4e9dbf78ae9395a095899576c", + "0x02f902fb01820bea8402321261850e39ef311283024cc3943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad881bc16d674ec80000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acc300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000025381c2ccdc3c8eab7b6f590600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001ce270557c1f68cfb577b856766310bf8b47fd9cc001a04a470a8d5731aa8dbf3097cea4a6dcd9c2bffc97b29d0b39892709a5b95ce2e49f1c17299853f33cf2bf3554b6b51bdd22eb18c1df6d22e393a639bd943db58b", + "0x02f8b101018402321261850e39ef311283012e7694b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb000000000000000000000000019f57fe47ee03764ec59e62512bde462bcbfb9300000000000000000000000000000000000000000000009ebb79bcfd6b808000c001a02c310cc3f06fc46e1b5dd7353bf6ee48f4766d1bdcda2e321807dd654aadd55fa020cce70e17f0b0195a71428854d13f44f6934955a6171bb120af149c5a2f168f", + "0x02f87201688402321261850fae8bdf9a82520894b5046b48d661d23262f00192c802dee3b167d4618710d807fba35dbc80c001a00afbb3c2fe4aeaa879871d537868ea6ea70ba36b0dd072eb1edfccf79316bf28a05cec9fac287501cc4bff0b9e7e07850647222d7be48f4cc46c397abab0bdcf7d", + "0x02f8710181d38402321261850ba43b7400830747ed949e87a268d42b0aba399c121428fce2c626ea01ff8084f9fc0d07c001a07544666461b880044a9fc37bbc7881c9a0a52ddb441aa751b5b612fe9fdfe8d0a05aa76d304d32185eb7b639d8ce415533da40d666c5734366c58803dd024ffd30", + "0x02f8b101038402321261850f665f461d8301771c94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000003e62edf533e5e24d759500a181d1a91358b91f0d00000000000000000000000000000000000000000000000000000000b2d05e00c001a01c7616624043c0604cb53f6e7e92afac9951bb2a8ec76b588b473b5c8cd41845a07c37c73160dcdd4aab110ad23a5cb635599ded0b788bbae64acd8a0cd8286726", + "0x02f8b101048402321261850e39ef311283012e8894b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb00000000000000000000000080aef925cdacbdc872c86767e2127876f135603400000000000000000000000000000000000000000000008df2be4059bff2062ac001a07870f8bda58efb84836fbdd5ee18243dc6b490b0e62dc18421b002b4fa4ef060a0386f94ec97920be5c6973f9610af782ddaa582d159505bd5b0f8d83749a44792", + "0x02f87201018402321261850f665f461d82520894520d450e6888eccd6feab7ff7e0877f848a88b5c878686273f1dec0080c080a0643531f92d8b90845906b743483541a3f2ee552eb07fad8540b32f5d5c21425ea0405d0110a52158aa742e7bd30c57688c5e771e95021537ecfa14005287748dd6", + "0x02f8b3018201458402321261850fae8bdf9a83011340944c9edd5852cd905f086c759e8383e09bff1e68b380b844095ea7b30000000000000000000000008707f238936c12c309bfc2b9959c35828acfc512ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0dff9745d53eb7ba30969d879635db561f9e1de02187bda51e8fbbdc52ba82c4aa0598533e3de1be5bdf61f20031991708a7329c58d8dcd5a2ba8883706b604e34c", + "0x02f902fc018201ae8402321261850fae8bdf9a8303a887943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad88018de76816d80000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acc300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000018de76816d8000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000018de76816d8000000000000000000000000000000000000000000000000000000000126fc0ec1a300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000055a8f6c6b3aa58ad6d1f26f6afeded78f32e19f4c001a0e9c37333cc67dc844f0c0d9601858a218a4ea7a88031bddd9d8825b53b57f7c0a054800436e1d309c9e0e24af54e760cbaeac078e7cc828f6f3841671a3b918116", + "0x02f8b001428402321261850f1740c9c782dc2994a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844095ea7b300000000000000000000000002950460e2b9529d0e00284a5fa2d7bdf3fa4d7200000000000000000000000000000000000000000000000000000004a817c800c080a0ecd1ef10f6a488aa9e47a55ca4b386617aeb0f05b132504cceadf93cbadaf782a0682ea66910c9794b9cc5ba164bc82244513e767a5448c3a3e479490e07faee29", + "0x02f8b101808402321261850f665f461d8301312b94d9016a907dc0ecfa3ca425ab20b6b785b42f237380b844a9059cbb00000000000000000000000090512978adfae4214f93cf1fd9a2f8cbeb787d48000000000000000000000000000000000000000000001503c1c8c53e5e3c0000c001a00b75bf0fee9f057d9238c9cfeb683b35064d390751ef2893260ebcce73167662a05da2a183650767de2471f7e82682bcc6b0d022a8a73432b8d6d195d8a68ac75e", + "0x02f909fb01819a8402321261850e39ef31128301d8c49400000000000000adc04c56bf30ac9d3c0aaf14dc80b9098cfd9f1e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000070effa80cdcef37d51bdf4d21687aea75a0197b000000000000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065f01a44000000000000000000000000000000000000000000000000000000006613dbdc0000000000000000000000000000000000000000000000000000000000000000360c6ebe0000000000000000000000000000000000000000bf53845b1aac54050000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd27000000000000000000000000000000000000000000000000000000000002dc743000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019faae14eb88000000000000000000000000000000000000000000000000000019faae14eb88000000000000000000000000000070effa80cdcef37d51bdf4d21687aea75a0197b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8bdb97852000000000000000000000000000000000000000000000000000000b8bdb978520000000000000000000000000000000a26b00c1f0df003000390027140000faa7190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022a392c68f60000000000000000000000000000000000000000000000000000022a392c68f60000000000000000000000000006c093fe8bc59e1e0cae2ec10f0b717d3d182056b000000000000000000000000070effa80cdcef37d51bdf4d21687aea75a0197b000000000000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065eb0b6c000000000000000000000000000000000000000000000000000000006613dbdc0000000000000000000000000000000000000000000000000000000000000000360c6ebe0000000000000000000000000000000000000000ae0ac953653ac3130000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd27000000000000000000000000000000000000000000000000000000000002dc743000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f1ad4c03f8000000000000000000000000000000000000000000000000000045f1ad4c03f8000000000000000000000000000070effa80cdcef37d51bdf4d21687aea75a0197b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000001f161421c8e0000000000000000000000000000000a26b00c1f0df003000390027140000faa719000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d423c655aa000000000000000000000000000000000000000000000000000005d423c655aa0000000000000000000000000006c093fe8bc59e1e0cae2ec10f0b717d3d182056b00000000360c6ebec080a0f914337603ed396f49309eb469913d540bf8b219865b54d9f0bd6fca858dc4f8a059cbfa1bbfab5e2a64c869035ba9bb9ed4b38c65c8e9d56729b2b887da0848d8", + "0x02f902fc0182011a8402321261850fae8bdf9a8303850f943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad88089aaeb710be0000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000089aaeb710be000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000089aaeb710be00000000000000000000000000000000000000000000000000021fd8d54c8a1a6aa900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000092f419fb7a750aed295b0ddf536276bf5a40124fc080a02ca1283699af78c33a3495a916e6d2c80952a207d5b6b1926680c8189db422f1a075019e52fd77798dbf46645ec64a3ab0cc7a210d1b2af04b9a01a249f3a46cbc", + "0x02f9033201038402321261850e39ef31128301353194d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef00000000000000000000000000000000000000000000000000000000000187ed000000000000000000000000f4911146e6cdcc96ae815b56b8388298c537738200000000000000000000000000000000000000000000000657b3801b80b400000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001142bbdf020b113cf51b28f72251e1b3e56af83da9c0048420be1c2270b1ab3c46e509b711b43f1232760657f7251da5ecd0179d570b573da53980346917fc49c3ec343469e6cf9e24d3051c5a6c4984530ee0c901aeb1cdcbeb4253532843b95dce9231699f13e37785baf293bcb31782e86a18d029eb3b38f04786be62c1c32c403345924a187b9a26fd82a08b0bf266f98a6fd9911e5da8b1dd0b16ce1df0ea8468f44289d07a72c1c4f870094d10788d0fc84d8ea6a967cf0b7f61d4ce72aab9b8aac9c5cccb7e2808a1e689ec061ef63333593533be416dfaaf74b9f90c5aa83c6ff7ba48fb889e7d24d2a36f49754e03788b8b36c31706f71e2db2d2235e2c6d99045e917b4d3dda6d9e293b307ae53327b1820a3cf8a0c67605a5f289a2928682849565f421514661d8715330ad1a241928bf8d83523495ec2c4ebcc795a631ddd37b735aee465dea76255e51aea695a97df82ec9785ffb0435d4c45ef64e9248e641ac65ef0d5fdb167961f5e76aa1d90d2eb49580b5470dafb3019a3cd786957bb72b9c8b91cdd7cdd256f1f7a3c401d12ee4f26e629afc69ffb97c8ee4df041f6d001a4c29f64bcb7dc7037b295e66ea154b33e6058d3ef6551f90fc7391105bbfc6265234e9cebeffa9b2e702d2341a1364e88c56b2fde302cbd6fdb2f1729c555dd226f68ac9786871adb4125748b57f44524ee6f108c017fa8db8340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec080a06f23a1578049eb8f39cee2f5e7ab89755d486ca0f2bb392985845e4c4cf50de5a005c159f86dd33eb5fbbc258a91909e2c5a367d5a0838c8c05df21c0dd56ebdc6", + "0x02f90414018202ab8402321261850fae8bdf9a83039e7d943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b903a43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2acb700000000000000000000000000000000000000000000000000000000000000020a080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000661a376900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad0000000000000000000000000000000000000000000000000000000065f2b17100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000417ffcaddf095b0303ee401928a659fc673ce89f80aeeef0cc0c940335de8bc5f05c9e9888d3f054c1662a4a4504bdbd088d49d4b4e56f7f5b9a7c124e4e8e26401b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000002ee250abdfbfc88c000000000000000000000000000000000000000000006362d1c07eb49eb6f68000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000007e128e823d2b9b22edbda43820aa1a72de99613c001a00aa1cfdd24173f8776d9857822e57c41b9f134bc674988e8f15f8d52d93b16bda00d033b3fb17d3278c05148bec2223404932e8a662d6b969a4b0ce78dff568c62", + "0x02f87201078402321261850fae8bdf9a825208948f9a34c5655d655e0c72cc2ac2baff6237ec9eae8732f2c07088bd1a80c001a0716bf0fb605692dccf06dad462b78f51e4259d49af321ea21642482da596eb15a075df8c5132be45ef1575c56959f8b660204b79a5654044a8351a1059d1af2acf", + "0x02f87301808402321261850fae8bdf9a82520894adb6505de4bf5f7e87aa54eb1586518f81ca0bc88806f05b59d3b2000080c080a03feaceae0bc6a141cedcac08f607562e6614693e2102f97b4273b0233947245fa0020fc611bd8310bd2caf5af4aee7be7fae83e67d82f8c643614748e162837486", + "0x02f8b101378402321261850e39ef311283012d7a94b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000006559ed7d1e4c8eadd407b99743a04041b947f3ea000000000000000000000000000000000000000000000014b550a013c7380000c080a0a6fda06cb1ad38960010baaa8e7c4e96991887ec17dd57c044e98bb1d72d15f6a03a93c21f8104f447a94373429ecfcd0328ee4c5c40502a07189f6daeefdc89a2", + "0x02f9033201808402321261850fae8bdf9a8301352194d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef0000000000000000000000000000000000000000000000000000000000015e12000000000000000000000000bdca2d6d76fa87f07da633bed8aa5cd99f54147300000000000000000000000000000000000000000000000324e964b3eca800000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001174faf49ba37521b6299a3e122ffd0c10f1cb000b089bf1f3ca1d896634420e0691d721072dba71ae5aa4ab9ce65c43ac04be3884f2c58e67935e85d27afb9af6cec04ef55922a0b77226360667129b02d0aa526ebe84b4eec5065ac6a7a333f33e55412762011e4b76339829004ad810d11c3abf195f033ca723d9f1afe020a7fe6742148d063a197db588ffe6f1f98308511193cd1250041921bd29c43642a873e2796b2e2b2b4c199648bd88333d05da6d9d31e581323c5dc91984bb2578edc41d6274dc9d1831cc5d28ffca4132232e3943c7bddc8c466177e72e1f1340f9b46b02646e19bdf59d0d52c54d4c615453fc49575b3bafb7fe2c766e53f30e960306f3f0072da85007681ae3604fed525fb716fb74c09dd3a161c5d5338a15a5514fe5f0afdadb1a2e80520463204153130876ae643e71ddfc06db3fc9fc8c03ba74cd8b2f9eccd6cba6389f38e034aeca7d8689cb1654506a5098b9022733994e77e2b564c62994d516b9cd40d483a9f948b20974ee4745b46f8c6eeaa31b67cff34b45f6af108a4107137de77c7f9c0b613280b7edc9e12445fe2d195f2fed4cf815d551368b549329d7b042ede0c28c494ad193986346b46361f9af93ae17715588c2b8020767b738ded790362d7cc47224f2cf2342d412a9bf1d274da0ce7dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec080a0faa5d5268e85876488a433c7ca598406ea6290ca654ec1ab81f940d92c7d4cb2a01d57b38c084d14169ddfaccd7aa759cada15caac60636d439c5b9b5a54477f55", + "0x02f8b10112840220b02a850ef8b4cd3b830131f4947d29a64504629172a429e64183d6673b9dacbfce80b844a9059cbb0000000000000000000000002451b9dcf9b1279f560a9f586899c8e6c2d0d91c000000000000000000000000000000000000000000000002f6d89368268eaacac080a00d764ca9ae21e18e30e5fbe5f8dcf3a29de9878fbbf07afaf857c695e88cd148a02456f3d685688211923cb9c212ebd4a83b6af84506c5e908734085701d3a1dad", + "0x02f8730102840220b029850b68c6e97282520894aee4d040e7d1f3e6f4e007c45d288c4b7bd82d98880275aa22c24bca3e80c001a093b213f5aea575ae7d2473c51f7e174a54079008ed490b2768fc2c0583e49bada07dfbb0bf9f03bd8aec322d58568fbff79ecada55453fac8e5ce338c72961fd6b", + "0x02f902f90180840220b029850b2e2b96d483031c87943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad876a94d74f430000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065f2ac9300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000000002394e7f30500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000014fee680690900ba0cccfc76ad70fd1b95d10e16c001a0dedd004eaed6394dbb0ace2360ad8aeca6761edd5c37942e22e95d002e2f5ba0a05cd64b717110f7a325753d35e090440ff008a16c4c1e219a3eb296a95dd1d704", + "0x02f8b10102840220b029850b2e2b96d4830221649406450dee7fd2fb8e39061434babcfc05599a6fb880b8441c5603050000000000000000000000001bd63db8c10a2ce6e5b446307eb4844138abfc320000000000000000000000000000000000000000000000000000000000000064c080a056cba33abbf6f0687c5395725cd3fb8b8cedf8f69a0238829264ff5b683d70cea0253e6ed353b10fba09ee59b257251955d3621710e6ed2d8e8f30e68186c0f8e6", + "0x02f903320128840220b029850ab5d04c008301351894d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef00000000000000000000000000000000000000000000000000000000000087b90000000000000000000000005623caecbf58946a0d48ff9318fa2557182240ab00000000000000000000000000000000000000000000000657b3801b80b4000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000011c46b990f036ae2d0bbc6f92afbef84165af0752306b24f59fab076ade5e33a5bb726ec2f8d8c06c8ae03285ff6187f299427706dd771227879fde474093dc2349d5ae5b08451bdc4e4cda8dff3f969a3450bbb5b85ca063750ce970dc5c45e3c7ee42591b0a66796986b0b98b1e47553393523eea18031c24ff7846394351ccb3d712b4046720470c6efeaaf6da20396728830864e458d115bf88a29e3982af2ed93ff9975f5c637adfdbaffa3969289b0cff21a73d5231e19397e6d9ae0c727eb3d2dd45dcf6dd79cfc42f7c84a46d38c4b047067cd029a20cb587d6ffa5c0b10a92d06fef594506e64c6ebb47736315b9db59c71d8b280845419e9e3b9006c5de4e53809eb97fb41bd529c09e512d8a72f7272f197ef95b352aaeba30140aea49b85e2162932173820a2b7154b9e0426201f0083910ab53ab7319ac686a56ea2260872ca3292b36fd35b2c10ce42a040de5744769e8e38cdbf33e75f449986bc2ce833985f7494bb689e96d7e4e4d3d7abe974050379da073c7b9796b00261ebb67e5256edc37569e7e11581c7e07b8d53d41a78984e41a812276041dbbdcbe65e3e9fd7ef63acd4ce98bc0621334261f731945adf4118d41eaaa662eeca3f1845c13f25cbba3d726231691cc1678de0936fe89df8d408c9bc344d58d0ae0a46e70d0e09debcd1ba9ca8ff28fa3dcc7b1318cdac64c0b387c56304d964a2f86643f31da169680b58a8548f4d3144a13fdb0eb53a2844abdea2d4a0c76a82ddc001a08707ba7d8a4348edac70661692dfc15d93998f970314f5952e03ea9ed637b07ba0571ab50ff584286e9020318ac277cfac528c7c6a038e37364f022f2f9619d143", + "0x02f90234018207bf840220b029850b68c6e9728302208794af9ba9f9d7db062a119371ea923ed274e398116380b901c4d4dfd6bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065f2ab75000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000415a4ea69da68b9aacdadba48b130c887c2285ec857221ba923063a0b0bfbccfa801484944382b81aee3537c71b763893b6385a363f2395e9ecc7f3ecafa899fbe1b00000000000000000000000000000000000000000000000000000000000000c080a0d234d32bdc0d78898539df7f6abe9c13342ed4b36cab9fbc5ff9d23385a844e3a0017d643dfda52cb190cf237999797e46e405dec578497470e4e185c7f9e7928d", + "0x02f8b10102840220b029850b68c6e97283012e6294b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb0000000000000000000000003996989b5ecb2e968e9cbabf1666aaeae21173fc0000000000000000000000000000000000000000000000914e05bea1d5080000c001a0a5c46c0bac56c65f6de1518e77158ade4e4e64c89c1e50bca25271413ffc6d7ca033d8a84aba11a9409fe9891ba8fb23334c22020bf9f62c078f3edd9c0cc272e7", + "0x02f90332010a840220b029850b68c6e9728301351594d4b812dd7134f632c947ca11a2fb0f49082a248380b902c42e7ba6ef000000000000000000000000000000000000000000000000000000000000cb9000000000000000000000000081a10688b294747d4cbc97c3cbcde68dd81b79fc00000000000000000000000000000000000000000000000b1cf24ddd0b140000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000118931c013269fa3868e5ebb9f99a2e634fb1b5500c953ea97325c997d3788aa715f1ff830392a163d437f6c1fc55e596da7d7b1571c001b47262fd979992ab1c972c01fdc16a5a86df15b6278833290870f4a02a990b99f2ddbc0423ac60bac0d50a3e859b29dd14f494ab8a77ac7aa36e39e0d9a39db658daa4c2994b391f75dea97cbb74734d1739d758e528c3de92aeaf9e191f9439fc2f59accf5cbae8eb10e8f84a19a8e363db712a02051654e15ae78ae31c8585180234e40ba9a0698f1c0fd87dfbaf9df473f78f39ddafcad6f2eead4fe54824f8bc3dba6df6fc327807fe9125520aa869739d06ee7e4169e75871e4325e2b642790c7b3a8090cfef4188fe4b376d05bc1d12a1bc91367d4a3eec9b43d3a66afb8aa29c443828e197e473bf64a203c428b430b04056ff7a1d5aec62aebc5f5df8c4260f29d8b342ab081e31b1fe1d272506080926e8adcc56748a87e4ffdb8e78688e89ff7a7e518aa921a90b94a8d5891299de2a8fe58144ac34ba0b0f5226bbe54fd2cffaaba4bfcd67e931175e5b4c8b0a956f3d164cde10179a7583ba29bee3eadbc2acd1f0d6df9677a941d7cbbd94ffdf154c6736b146b862f9de6449d0d550ac055f19596abe3817ee8a14f49b7efe1f8351d9e474eca711776c9d4b2f80a01e0889a1e8a3497dbbba44476a13c02cfed0b524896278c0bfc2ede44fcc65c1b9efe49e33a5ae340559eadadb3e2ca3d8f89f796bebe7b6ab26f40914495b23cb29e64b2dd29ec080a0e8238473c8e41ebfe341df72d402c8c0b35edaa96fa9393586b2ef1cc4057a16a0166dc8645fb72d8818cc7dff6bfe393b3e4a0cdfd959fa7377e7cb879c762c6a", + "0x02f8b00104840220b029850b68c6e97282b68c946982508145454ce325ddbe47a25d4ec3d231193380b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba300000000000000000000000000000000000000000528a0c1763c7ee5b9ef0000c001a0664178682c745e9b3f397333f97dc61599ff9ede8299bdfc15b8bf868dcc2e14a03a497d31c3c1bc9b12577d2d111916ac7a4f0eb2307950fbfe205bc5aa5ef3c5", + "0x02f8b1010c840220b029850ba43b740083012e7694b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb0000000000000000000000002fdc20f6fa8241734a75128c5fefad18abff48770000000000000000000000000000000000000000000000948751d51b30617400c001a066098701097d00d5fd400901979998b94f436f08bd4d50d07d534ea16a123741a064bd8771fbf422264534adb9f40722af08e4721235d1d39b9e0dee2c38cb00c4", + "0x02f902f401820161840220b029850b9e3d482e83048d0b94c36442b4a4522e871399cd717abdd847ab11fe8880b90284ac9650d8000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000084fc6f7865000000000000000000000000000000000000000000000000000000000009cd19000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c000000000000000000000000000000000000000000000000022bdf74a5001413000000000000000000000000f333087c317f6c7eab71af59d894edf55f79feb8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064df2ab5bb000000000000000000000000767fe9edc9e0df98e07454847909b5e959d7ca0e0000000000000000000000000000000000000000000000002fac65a3525eac0d000000000000000000000000f333087c317f6c7eab71af59d894edf55f79feb800000000000000000000000000000000000000000000000000000000c001a0437d3d1e56edeeb5d6dbffabb5de5b3fe60ce3c72bee37dd22df1cadff2cc2f3a02c3b6770de93dd30bddc41a06229448576b643da3a9d592cb0632b1dafdf1c7f", + "0x02f8b0010184021058f5850a8a2aa89482c95794b131f4a55907b10d1f0a50d8ab8fa09ec342cd7480b844a9059cbb0000000000000000000000009dcf825b01b3635623d901aef85cf431f09f79fe00000000000000000000000000000000000000000000007bcce5b6ed1332dbcec001a02308e4661a772da3b543bfabef345ef466e09dad64c74ad0867d8f2b8074e885a034911fc9e300f431b0fac2f0b9b0b21dec47655ad9b545d3a2efe83f56c01548", + "0x02f8b10181ae8401fa70b88516cf46e34882c8f094b528edbef013aff855ac3c50b381f253af13b99780b844a9059cbb0000000000000000000000004a300e437f98009b4a089bc9b4abdc135a7147d000000000000000000000000000000000000000000000000cbd47b6eaa8cc0000c001a02261daca00b379393cbb2fe127b15d8778a4b7e36430eb335b2bc16a1c194feca010a19a518c45589b5c4ade62ac228a50920722d5b7360f0d333c523437336185", + "0x02f8b00181a383e4e1c0850de7dc35bf82cb1c94614577036f0a024dbc1c88ba616b394dd65d105a80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a02703d70b06b6e19a6db9be9479616e6623784db3b46ff994e360e8e572a59777a0248227295e09c5937b8a0a740bff7bb218f3e0b42bf9f195693c9e9466d554fb", + "0x02f8f2018216218398968085111ade37ac830301339477f0de655885dcf6b6942ea5b3de171dfd3f5da980b884eeb858b5000000000000000000000000000000000000000000000000000000000000997e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000083bc1b65fb8397718c9ff6a786ec9d0117a0b6e1000000000000000000000000000000000000000000000000001c60d39552429cc080a04e9b2f821a25e502f584ac52716daa3837db0a353a5b61895067474c2b203a65a07220680fd91ce369e32cb25d85eabb51bcc001a83593e17a4f89e14ae2abcca6", + "0x02f876018309fe9383989680851510cd35be83015f90943a72e72939c80ab9413ad9c6ca790ed46b184a17880484a65efe3c000080c001a0f48c69a77f0fa660f97d4f64cdbbbdb5948e987a15088100a81562c069418126a059ffe793bf3e17d0d02fda78bc12adafd5b22d647a20f42f2570855dd076be73", + "0x02f8740183051017839896808515699cce3e82520894f48e53fa5cadd0728aaca90ee7e1c6132020993787175f60d3e2c15c80c080a0534c6a9d9aaeda4e9704b80b44339c040885f0d6bc5106c8c141aa487d7a841da06515ff0bebf9cf9c5a5fcee0f0dd7673bfce41f5b0e91cb0550a7e8ce7cdf818", + "0x02f87201830bbc2a80850a5254153d827d0094388c818ca8b9251b393131c08a736a67ccb19297880185a6d6be627f3280c080a038cbd7a4589d49f061b88da94c6d16e085faed4ea61f60a744d781bea95862a3a061eb4b1dc235a3fdb04c589150326d7e49089439428c22ced7bc7ddb559edd37" + ], + "withdrawals": [ + { + "index": "38350022", + "validator_index": "171011", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18545672" + }, + { + "index": "38350023", + "validator_index": "171012", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18561699" + }, + { + "index": "38350024", + "validator_index": "171013", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "62582115" + }, + { + "index": "38350025", + "validator_index": "171014", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18489815" + }, + { + "index": "38350026", + "validator_index": "171015", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18546820" + }, + { + "index": "38350027", + "validator_index": "171016", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18534476" + }, + { + "index": "38350028", + "validator_index": "171017", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18539498" + }, + { + "index": "38350029", + "validator_index": "171018", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18573549" + }, + { + "index": "38350030", + "validator_index": "171019", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18486098" + }, + { + "index": "38350031", + "validator_index": "171020", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18511761" + }, + { + "index": "38350032", + "validator_index": "171021", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18501732" + }, + { + "index": "38350033", + "validator_index": "171022", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "62418961" + }, + { + "index": "38350034", + "validator_index": "171023", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18490087" + }, + { + "index": "38350035", + "validator_index": "171024", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18515931" + }, + { + "index": "38350036", + "validator_index": "171025", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18534555" + }, + { + "index": "38350037", + "validator_index": "171026", + "address": "0x8626354048f90faafc212c07ec7f3613406b1b32", + "amount": "18550274" + } + ], + "blob_gas_used": "131072", + "excess_blob_gas": "0" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [ + "0x97d62d4572935295f909f243714201d9221215bfcc91af6546d28d2e52040577a77957256c530ca25974f6a814511b1a" + ] + } +} diff --git a/build/checksums.txt b/build/checksums.txt index 03a53946df..06de819c70 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,61 +5,123 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz -# version:golang 1.21.6 +# version:golang 1.23.1 # https://go.dev/dl/ -124926a62e45f78daabbaedb9c011d97633186a33c238ffc1e25320c02046248 go1.21.6.src.tar.gz -31d6ecca09010ab351e51343a5af81d678902061fee871f912bdd5ef4d778850 go1.21.6.darwin-amd64.tar.gz -0ff541fb37c38e5e5c5bcecc8f4f43c5ffd5e3a6c33a5d3e4003ded66fcfb331 go1.21.6.darwin-arm64.tar.gz -a1d1a149b34bf0f53965a237682c6da1140acabb131bf0e597240e4a140b0e5e go1.21.6.freebsd-386.tar.gz -de59e1217e4398b1522eed8dddabab2fa1b97aecbdca3af08e34832b4f0e3f81 go1.21.6.freebsd-amd64.tar.gz -05d09041b5a1193c14e4b2db3f7fcc649b236c567f5eb93305c537851b72dd95 go1.21.6.linux-386.tar.gz -3f934f40ac360b9c01f616a9aa1796d227d8b0328bf64cb045c7b8c4ee9caea4 go1.21.6.linux-amd64.tar.gz -e2e8aa88e1b5170a0d495d7d9c766af2b2b6c6925a8f8956d834ad6b4cacbd9a go1.21.6.linux-arm64.tar.gz -6a8eda6cc6a799ff25e74ce0c13fdc1a76c0983a0bb07c789a2a3454bf6ec9b2 go1.21.6.linux-armv6l.tar.gz -e872b1e9a3f2f08fd4554615a32ca9123a4ba877ab6d19d36abc3424f86bc07f go1.21.6.linux-ppc64le.tar.gz -92894d0f732d3379bc414ffdd617eaadad47e1d72610e10d69a1156db03fc052 go1.21.6.linux-s390x.tar.gz -65b38857135cf45c80e1d267e0ce4f80fe149326c68835217da4f2da9b7943fe go1.21.6.windows-386.zip -27ac9dd6e66fb3fd0acfa6792ff053c86e7d2c055b022f4b5d53bfddec9e3301 go1.21.6.windows-amd64.zip -b93aff8f3c882c764c66a39b7a1483b0460e051e9992bf3435479129e5051bcd go1.21.6.windows-arm64.zip +6ee44e298379d146a5e5aa6b1c5b5d5f5d0a3365eabdd70741e6e21340ec3b0d go1.23.1.src.tar.gz +f17f2791717c15728ec63213a014e244c35f9c8846fb29f5a1b63d0c0556f756 go1.23.1.aix-ppc64.tar.gz +dd9e772686ed908bcff94b6144322d4e2473a7dcd7c696b7e8b6d12f23c887fd go1.23.1.darwin-amd64.pkg +488d9e4ca3e3ed513ee4edd91bef3a2360c65fa6d6be59cf79640bf840130a58 go1.23.1.darwin-amd64.tar.gz +be34b488157ec69d94e26e1554558219a2c90789bcb7e3686965a7f9c8cfcbe7 go1.23.1.darwin-arm64.pkg +e223795ca340e285a760a6446ce57a74500b30e57469a4109961d36184d3c05a go1.23.1.darwin-arm64.tar.gz +6af626176923a6ae6c5de6dc1c864f38365793c0e4ecd0d6eab847bdc23953e5 go1.23.1.dragonfly-amd64.tar.gz +cc957c1a019702e6cdc2e257202d42799011ebc1968b6c3bcd6b1965952607d5 go1.23.1.freebsd-386.tar.gz +a7d57781c50bb80886a8f04066791956d45aa3eea0f83070c5268b6223afb2ff go1.23.1.freebsd-amd64.tar.gz +c7b09f3fef456048e596db9bea746eb66796aeb82885622b0388feee18f36a3e go1.23.1.freebsd-arm.tar.gz +b05cd6a77995a0c8439d88df124811c725fb78b942d0b6dd1643529d7ba62f1f go1.23.1.freebsd-arm64.tar.gz +56236ae70be1613f2915943b94f53c96be5bffc0719314078facd778a89bc57e go1.23.1.freebsd-riscv64.tar.gz +8644c52df4e831202114fd67c9fcaf1f7233ad27bf945ac53fa7217cf1a0349f go1.23.1.illumos-amd64.tar.gz +cdee2f4e2efa001f7ee75c90f2efc310b63346cfbba7b549987e9139527c6b17 go1.23.1.linux-386.tar.gz +49bbb517cfa9eee677e1e7897f7cf9cfdbcf49e05f61984a2789136de359f9bd go1.23.1.linux-amd64.tar.gz +faec7f7f8ae53fda0f3d408f52182d942cc89ef5b7d3d9f23ff117437d4b2d2f go1.23.1.linux-arm64.tar.gz +6c7832c7dcd8fb6d4eb308f672a725393403c74ee7be1aeccd8a443015df99de go1.23.1.linux-armv6l.tar.gz +649ce3856ddc808c00b14a46232eab0bf95e7911cdf497010b17d76656f5ca4e go1.23.1.linux-loong64.tar.gz +201911048f234e5a0c51ec94b1a11d4e47062fee4398b1d2faa6c820dc026724 go1.23.1.linux-mips.tar.gz +2bce3743df463915e45d2612f9476ffb03d0b3750b1cb3879347de08715b5fc6 go1.23.1.linux-mips64.tar.gz +54e301f266e33431b0703136e0bbd4cf02461b1ecedd37b7cbd90cb862a98e5f go1.23.1.linux-mips64le.tar.gz +8efd495e93d17408c0803595cdc3bf13cb28e0f957aeabd9cc18245fb8e64019 go1.23.1.linux-mipsle.tar.gz +52bd68689095831ad9af7160844c23b28bb8d0acd268de7e300ff5f0662b7a07 go1.23.1.linux-ppc64.tar.gz +042888cae54b5fbfd9dd1e3b6bc4a5134879777fe6497fc4c62ec394b5ecf2da go1.23.1.linux-ppc64le.tar.gz +1a4a609f0391bea202d9095453cbfaf7368fa88a04c206bf9dd715a738664dc3 go1.23.1.linux-riscv64.tar.gz +47dc49ad45c45e192efa0df7dc7bc5403f5f2d15b5d0dc74ef3018154b616f4d go1.23.1.linux-s390x.tar.gz +fbfbd5efa6a5d581ea7f5e65015f927db0e52135cab057e43d39d5482da54b61 go1.23.1.netbsd-386.tar.gz +e96e1cc5cf36113ee6099d1a7306b22cd9c3f975a36bdff954c59f104f22b853 go1.23.1.netbsd-amd64.tar.gz +c394dfc06bfc276a591209a37e09cd39089ec9a9cc3db30b94814ce2e39eb1d4 go1.23.1.netbsd-arm.tar.gz +b3b35d64f32821a68b3e2994032dbefb81978f2ec3f218c7a770623b82d36b8e go1.23.1.netbsd-arm64.tar.gz +3c775c4c16c182e33c2c4ac090d9a247a93b3fb18a3df01d87d490f29599faff go1.23.1.openbsd-386.tar.gz +5edbe53b47c57b32707fd7154536fbe9eaa79053fea01650c93b54cdba13fc0f go1.23.1.openbsd-amd64.tar.gz +c30903dd8fa98b8aca8e9db0962ce9f55502aed93e0ef41e5ae148aaa0088de1 go1.23.1.openbsd-arm.tar.gz +12da183489e58f9c6b357bc1b626f85ed7d4220cab31a49d6a49e6ac6a718b67 go1.23.1.openbsd-arm64.tar.gz +9cc9aad37696a4a10c31dcec9e35a308de0b369dad354d54cf07406ac6fa7c6f go1.23.1.openbsd-ppc64.tar.gz +e1d740dda062ce5a276a0c3ed7d8b6353238bc8ff405f63e2e3480bfd26a5ec5 go1.23.1.openbsd-riscv64.tar.gz +da2a37f9987f01f096859230aa13ecc4ad2e7884465bce91004bc78c64435d65 go1.23.1.plan9-386.tar.gz +fd8fff8b0697d55c4a4d02a8dc998192b80a9dc2a057647373d6ff607cad29de go1.23.1.plan9-amd64.tar.gz +52efbc5804c1c86ba7868aa8ebbc31cc8c2a27b62a60fd57944970d48fc67525 go1.23.1.plan9-arm.tar.gz +f54205f21e2143f2ada1bf1c00ddf64590f5139d5c3fb77cc06175f0d8cc7567 go1.23.1.solaris-amd64.tar.gz +369a17f0cfd29e5c848e58ffe0d772da20abe334d1c7ca01dbcd55bb3db0b440 go1.23.1.windows-386.msi +ab866f47d7be56e6b1c67f1d529bf4c23331a339fb0785f435a0552d352cb257 go1.23.1.windows-386.zip +e99dac215ee437b9bb8f8b14bbfe0e8756882c1ed291f30818e8363bc9c047a5 go1.23.1.windows-amd64.msi +32dedf277c86610e380e1765593edb66876f00223df71690bd6be68ee17675c0 go1.23.1.windows-amd64.zip +23169c79dc6b54e0dffb25be6b67425ad9759392a58309bc057430a9bf4c8f6a go1.23.1.windows-arm.msi +1a57615a09f13534f88e9f2d7efd5743535d1a5719b19e520eef965a634f8efb go1.23.1.windows-arm.zip +313e1a543931ad8735b4df8969e00f5f4c2ef07be21f54015ede961a70263d35 go1.23.1.windows-arm64.msi +64ad0954d2c33f556fb1018d62de091254aa6e3a94f1c8a8b16af0d3701d194e go1.23.1.windows-arm64.zip -# version:golangci 1.55.2 +# version:golangci 1.59.0 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.55.2/ -632e96e6d5294fbbe7b2c410a49c8fa01c60712a0af85a567de85bcc1623ea21 golangci-lint-1.55.2-darwin-amd64.tar.gz -234463f059249f82045824afdcdd5db5682d0593052f58f6a3039a0a1c3899f6 golangci-lint-1.55.2-darwin-arm64.tar.gz -2bdd105e2d4e003a9058c33a22bb191a1e0f30fa0790acca0d8fbffac1d6247c golangci-lint-1.55.2-freebsd-386.tar.gz -e75056e8b082386676ce23eba455cf893931a792c0d87e1e3743c0aec33c7fb5 golangci-lint-1.55.2-freebsd-amd64.tar.gz -5789b933facaf6136bd23f1d50add67b79bbcf8dfdfc9069a37f729395940a66 golangci-lint-1.55.2-freebsd-armv6.tar.gz -7f21ab1008d05f32c954f99470fc86a83a059e530fe2add1d0b7d8ed4d8992a7 golangci-lint-1.55.2-freebsd-armv7.tar.gz -33ab06139b9219a28251f10821da94423db30285cc2af97494cbb2a281927de9 golangci-lint-1.55.2-illumos-amd64.tar.gz -57ce6f8ce3ad6ee45d7cc3d9a047545a851c2547637834a3fcb086c7b40b1e6b golangci-lint-1.55.2-linux-386.tar.gz -ca21c961a33be3bc15e4292dc40c98c8dcc5463a7b6768a3afc123761630c09c golangci-lint-1.55.2-linux-amd64.tar.gz -8eb0cee9b1dbf0eaa49871798c7f8a5b35f2960c52d776a5f31eb7d886b92746 golangci-lint-1.55.2-linux-arm64.tar.gz -3195f3e0f37d353fd5bd415cabcd4e263f5c29d3d0ffb176c26ff3d2c75eb3bb golangci-lint-1.55.2-linux-armv6.tar.gz -c823ee36eb1a719e171de1f2f5ca3068033dce8d9817232fd10ed71fd6650406 golangci-lint-1.55.2-linux-armv7.tar.gz -758a5d2a356dc494bd13ed4c0d4bf5a54a4dc91267ea5ecdd87b86c7ca0624e7 golangci-lint-1.55.2-linux-loong64.tar.gz -2c7b9abdce7cae802a67d583cd7c6dca520bff6d0e17c8535a918e2f2b437aa0 golangci-lint-1.55.2-linux-mips64.tar.gz -024e0a15b85352cc27271285526e16a4ab66d3e67afbbe446c9808c06cb8dbed golangci-lint-1.55.2-linux-mips64le.tar.gz -6b00f89ba5506c1de1efdd9fa17c54093013a294fefd8b9b31534db626a672ee golangci-lint-1.55.2-linux-ppc64le.tar.gz -0faa0d047d9bf7b703ed3ea65b6117043c93504f9ca1de25ae929d3901c73d4a golangci-lint-1.55.2-linux-riscv64.tar.gz -30dec9b22e7d5bb4e9d5ccea96da20f71cd7db3c8cf30b8ddc7cb9174c4d742a golangci-lint-1.55.2-linux-s390x.tar.gz -5a0ede48f79ad707902fdb29be8cd2abd8302dc122b65ebae3fdfc86751c7698 golangci-lint-1.55.2-netbsd-386.tar.gz -95af20a2e617126dd5b08122ece7819101070e1582a961067ce8c41172f901ad golangci-lint-1.55.2-netbsd-amd64.tar.gz -94fb7dacb7527847cc95d7120904e19a2a0a81a0d50d61766c9e0251da72ab9d golangci-lint-1.55.2-netbsd-armv6.tar.gz -ca906bce5fee9619400e4a321c56476fe4a4efb6ac4fc989d340eb5563348873 golangci-lint-1.55.2-netbsd-armv7.tar.gz -45b442f69fc8915c4500201c0247b7f3f69544dbc9165403a61f9095f2c57355 golangci-lint-1.55.2-windows-386.zip -f57d434d231d43417dfa631587522f8c1991220b43c8ffadb9c7bd279508bf81 golangci-lint-1.55.2-windows-amd64.zip -fd7dc8f4c6829ee6fafb252a4d81d2155cd35da7833665cbb25d53ce7cecd990 golangci-lint-1.55.2-windows-arm64.zip -1892c3c24f9e7ef44b02f6750c703864b6dc350129f3ec39510300007b2376f1 golangci-lint-1.55.2-windows-armv6.zip -a5e68ae73d38748b5269fad36ac7575e3c162a5dc63ef58abdea03cc5da4522a golangci-lint-1.55.2-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v1.59.0/ +418acf7e255ddc0783e97129c9b03d9311b77826a5311d425a01c708a86417e7 golangci-lint-1.59.0-darwin-amd64.tar.gz +5f6a1d95a6dd69f6e328eb56dd311a38e04cfab79a1305fbf4957f4e203f47b6 golangci-lint-1.59.0-darwin-arm64.tar.gz +8899bf589185d49f747f3e5db9f0bde8a47245a100c64a3dd4d65e8e92cfc4f2 golangci-lint-1.59.0-freebsd-386.tar.gz +658212f138d9df2ac89427e22115af34bf387c0871d70f2a25101718946a014f golangci-lint-1.59.0-freebsd-amd64.tar.gz +4c6395ea40f314d3b6fa17d8997baab93464d5d1deeaab513155e625473bd03a golangci-lint-1.59.0-freebsd-armv6.tar.gz +ff37da4fbaacdb6bbae70fdbdbb1ba932a859956f788c82822fa06bef5b7c6b3 golangci-lint-1.59.0-freebsd-armv7.tar.gz +439739469ed2bda182b1ec276d40c40e02f195537f78e3672996741ad223d6b6 golangci-lint-1.59.0-illumos-amd64.tar.gz +940801d46790e40d0a097d8fee34e2606f0ef148cd039654029b0b8750a15ed6 golangci-lint-1.59.0-linux-386.tar.gz +3b14a439f33c4fff83dbe0349950d984042b9a1feb6c62f82787b598fc3ab5f4 golangci-lint-1.59.0-linux-amd64.tar.gz +c57e6c0b0fa03089a2611dceddd5bc5d206716cccdff8b149da8baac598719a1 golangci-lint-1.59.0-linux-arm64.tar.gz +93149e2d3b25ac754df9a23172403d8aa6d021a7e0d9c090a12f51897f68c9a0 golangci-lint-1.59.0-linux-armv6.tar.gz +d10ac38239d9efee3ee87b55c96cdf3fa09e1a525babe3ffdaaf65ccc48cf3dc golangci-lint-1.59.0-linux-armv7.tar.gz +047338114b4f0d5f08f0fb9a397b03cc171916ed0960be7dfb355c2320cd5e9c golangci-lint-1.59.0-linux-loong64.tar.gz +5632df0f7f8fc03a80a266130faef0b5902d280cf60621f1b2bdc1aef6d97ee9 golangci-lint-1.59.0-linux-mips64.tar.gz +71dd638c82fa4439171e7126d2c7a32b5d103bfdef282cea40c83632cb3d1f4b golangci-lint-1.59.0-linux-mips64le.tar.gz +6cf9ea0d34e91669948483f9ae7f07da319a879344373a1981099fbd890cde00 golangci-lint-1.59.0-linux-ppc64le.tar.gz +af0205fa6fbab197cee613c359947711231739095d21b5c837086233b36ad971 golangci-lint-1.59.0-linux-riscv64.tar.gz +a9d2fb93f3c688ebccef94f5dc96c0b07c4d20bf6556cddebd8442159b0c80f6 golangci-lint-1.59.0-linux-s390x.tar.gz +68ab4c57a847b8ace9679887f2f8b2b6760e57ee29dcde8c3f40dd8bb2654fa2 golangci-lint-1.59.0-netbsd-386.tar.gz +d277b8b435c19406d00de4d509eadf5a024a5782878332e9a1b7c02bb76e87a7 golangci-lint-1.59.0-netbsd-amd64.tar.gz +83211656be8dcfa1545af4f92894409f412d1f37566798cb9460a526593ad62c golangci-lint-1.59.0-netbsd-arm64.tar.gz +6c6866d28bf79fa9817a0f7d2b050890ed109cae80bdb4dfa39536a7226da237 golangci-lint-1.59.0-netbsd-armv6.tar.gz +11587566363bd03ca586b7df9776ccaed569fcd1f3489930ac02f9375b307503 golangci-lint-1.59.0-netbsd-armv7.tar.gz +466181a8967bafa495e41494f93a0bec829c2cf715de874583b0460b3b8ae2b8 golangci-lint-1.59.0-windows-386.zip +3317d8a87a99a49a0a1321d295c010790e6dbf43ee96b318f4b8bb23eae7a565 golangci-lint-1.59.0-windows-amd64.zip +b3af955c7fceac8220a36fc799e1b3f19d3b247d32f422caac5f9845df8f7316 golangci-lint-1.59.0-windows-arm64.zip +6f083c7d0c764e5a0e5bde46ee3e91ae357d80c194190fe1d9754392e9064c7e golangci-lint-1.59.0-windows-armv6.zip +3709b4dd425deadab27748778d08e03c0f804d7748f7dd5b6bb488d98aa031c7 golangci-lint-1.59.0-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # # This version is fine to be old and full of security holes, we just use it -# to build the latest Go. Don't change it. If it ever becomes insufficient, -# we need to switch over to a recursive builder to jump across supported -# versions. +# to build the latest Go. Don't change it. # -# version:ppa-builder 1.19.6 +# version:ppa-builder-1 1.19.6 # https://go.dev/dl/ d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz + +# version:ppa-builder-2 1.21.9 +# https://go.dev/dl/ +58f0c5ced45a0012bce2ff7a9df03e128abcc8818ebabe5027bb92bafe20e421 go1.21.9.src.tar.gz + +# version:protoc 27.1 +# https://github.com/protocolbuffers/protobuf/releases/ +# https://github.com/protocolbuffers/protobuf/releases/download/v27.1/ +8809c2ec85368c6b6e9af161b6771a153aa92670a24adbe46dd34fa02a04df2f protoc-27.1-linux-aarch_64.zip +5d21979a6d27475e810b76b88863d1e784fa01ffb15e511a3ec5bd1924d89426 protoc-27.1-linux-ppcle_64.zip +84d8852750ed186dc4a057a1a86bcac409be5362d6af04770f42367fee6b7bc1 protoc-27.1-linux-s390_64.zip +2f028796ff5741691650e0eea290e61ff2f1c0d87f8d31fe45ef47fd967cef0c protoc-27.1-linux-x86_32.zip +8970e3d8bbd67d53768fe8c2e3971bdd71e51cfe2001ca06dacad17258a7dae3 protoc-27.1-linux-x86_64.zip +03b7af1bf469e7285dc51976ee5fa99412704dbd1c017105114852a37b165c12 protoc-27.1-osx-aarch_64.zip +f14d3973cf13283d07c520ed6f4c12405ad41b9efd18089a1c74897037d742b5 protoc-27.1-osx-universal_binary.zip +8520d944f3a3890fa296a3b3b0d4bb18337337e2526bbbf1b507eeea3c2a1ec4 protoc-27.1-osx-x86_64.zip +6263718ff96547b8392a079f6fdf02a4156f2e8d13cd51649a0d03fb7afa2de8 protoc-27.1-win32.zip +da531c51ccd1290d8d34821f0ce4e219c7fbaa6f9825f5a3fb092a9d03fe6206 protoc-27.1-win64.zip + +# version:protoc-gen-go 1.34.2 +# https://github.com/protocolbuffers/protobuf-go/releases/ +# https://github.com/protocolbuffers/protobuf-go/releases/download/v1.34.2/ +9b48d8f90add02e8e94e14962fed74e7ce2b2d6bda4dd42f1f4fbccf0f766f1a protoc-gen-go.v1.34.2.darwin.amd64.tar.gz +17aca7f948dbb624049030cf841e35895cf34183ba006e721247fdeb95ff2780 protoc-gen-go.v1.34.2.darwin.arm64.tar.gz +a191849433fd489f1d44f37788d762658f3f5fb225f3a85d4ce6ba32666703ed protoc-gen-go.v1.34.2.linux.386.tar.gz +b87bc134dee55576a842141bf0ed27761c635d746780fce5dee038c6dd16554f protoc-gen-go.v1.34.2.linux.amd64.tar.gz +63d400167e75ab9f6690688f6fdc6a9455aa20bc1faa71e32149dbd322f7f198 protoc-gen-go.v1.34.2.linux.arm64.tar.gz +56e7675816db6e62be4f833a51544d5716b8420c462515579e05ca8444ab06ed protoc-gen-go.v1.34.2.windows.386.zip +abafd39612177dd4e9a65207cadd5374a9352d8611e8e040f8462fcfa3010daf protoc-gen-go.v1.34.2.windows.amd64.zip diff --git a/build/ci.go b/build/ci.go index 31ffa4a7b6..c78e330823 100644 --- a/build/ci.go +++ b/build/ci.go @@ -39,16 +39,17 @@ package main import ( "bytes" + "crypto/sha256" "encoding/base64" "flag" "fmt" + "io" "log" "os" "os/exec" "path" "path/filepath" "runtime" - "strconv" "strings" "time" @@ -117,23 +118,13 @@ var ( debEthereum, } - // Distros for which packages are created. - // Note: vivid is unsupported because there is no golang-1.6 package for it. - // Note: the following Ubuntu releases have been officially deprecated on Launchpad: - // wily, yakkety, zesty, artful, cosmic, disco, eoan, groovy, hirsuite, impish, - // kinetic, lunar - debDistroGoBoots = map[string]string{ - "trusty": "golang-1.11", // 14.04, EOL: 04/2024 - "xenial": "golang-go", // 16.04, EOL: 04/2026 - "bionic": "golang-go", // 18.04, EOL: 04/2028 - "focal": "golang-go", // 20.04, EOL: 04/2030 - "jammy": "golang-go", // 22.04, EOL: 04/2032 - "mantic": "golang-go", // 23.10, EOL: 07/2024 - } - - debGoBootPaths = map[string]string{ - "golang-1.11": "/usr/lib/go-1.11", - "golang-go": "/usr/lib/go", + // Distros for which packages are created + debDistros = []string{ + "xenial", // 16.04, EOL: 04/2026 + "bionic", // 18.04, EOL: 04/2028 + "focal", // 20.04, EOL: 04/2030 + "jammy", // 22.04, EOL: 04/2032 + "noble", // 24.04, EOL: 04/2034 } // This is where the tests should be unpacked. @@ -167,8 +158,8 @@ func main() { doLint(os.Args[2:]) case "archive": doArchive(os.Args[2:]) - case "docker": - doDocker(os.Args[2:]) + case "dockerx": + doDockerBuildx(os.Args[2:]) case "debsrc": doDebianSource(os.Args[2:]) case "nsis": @@ -177,6 +168,8 @@ func main() { doPurge(os.Args[2:]) case "sanitycheck": doSanityCheck() + case "generate": + doGenerate() default: log.Fatal("unknown command ", os.Args[1]) } @@ -248,6 +241,10 @@ func doInstall(cmdline []string) { // buildFlags returns the go tool flags for building. func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (flags []string) { var ld []string + // See https://github.com/golang/go/issues/33772#issuecomment-528176001 + // We need to set --buildid to the linker here, and also pass --build-id to the + // cgo-linker further down. + ld = append(ld, "--buildid=none") if env.Commit != "" { ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitCommit="+env.Commit) ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitDate="+env.Date) @@ -260,7 +257,11 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string) ( if runtime.GOOS == "linux" { // Enforce the stacksize to 8M, which is the case on most platforms apart from // alpine Linux. - extld := []string{"-Wl,-z,stack-size=0x800000"} + // See https://sourceware.org/binutils/docs-2.23.1/ld/Options.html#Options + // regarding the options --build-id=none and --strip-all. It is needed for + // reproducible builds; removing references to temporary files in C-land, and + // making build-id reproducably absent. + extld := []string{"-Wl,-z,stack-size=0x800000,--build-id=none,--strip-all"} if staticLinking { extld = append(extld, "-static") // Under static linking, use of certain glibc features must be @@ -308,7 +309,7 @@ func doTest(cmdline []string) { gotest := tc.Go("test") // CI needs a bit more time for the statetests (default 10m). - gotest.Args = append(gotest.Args, "-timeout=20m") + gotest.Args = append(gotest.Args, "-timeout=30m") // Enable CKZG backend in CI. gotest.Args = append(gotest.Args, "-tags=ckzg") @@ -362,6 +363,130 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string { return filepath.Join(cachedir, base) } +// hashAllSourceFiles iterates all files under the top-level project directory +// computing the hash of each file (excluding files within the tests +// subrepo) +func hashAllSourceFiles() (map[string]common.Hash, error) { + res := make(map[string]common.Hash) + err := filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error { + if strings.HasPrefix(path, filepath.FromSlash("tests/testdata")) { + return filepath.SkipDir + } + if !d.Type().IsRegular() { + return nil + } + // open the file and hash it + f, err := os.OpenFile(path, os.O_RDONLY, 0666) + if err != nil { + return err + } + hasher := sha256.New() + if _, err := io.Copy(hasher, f); err != nil { + return err + } + res[path] = common.Hash(hasher.Sum(nil)) + return nil + }) + if err != nil { + return nil, err + } + return res, nil +} + +// hashSourceFiles iterates the provided set of filepaths (relative to the top-level geth project directory) +// computing the hash of each file. +func hashSourceFiles(files []string) (map[string]common.Hash, error) { + res := make(map[string]common.Hash) + for _, filePath := range files { + f, err := os.OpenFile(filePath, os.O_RDONLY, 0666) + if err != nil { + return nil, err + } + hasher := sha256.New() + if _, err := io.Copy(hasher, f); err != nil { + return nil, err + } + res[filePath] = common.Hash(hasher.Sum(nil)) + } + return res, nil +} + +// compareHashedFilesets compares two maps (key is relative file path to top-level geth directory, value is its hash) +// and returns the list of file paths whose hashes differed. +func compareHashedFilesets(preHashes map[string]common.Hash, postHashes map[string]common.Hash) []string { + updates := []string{} + for path, postHash := range postHashes { + preHash, ok := preHashes[path] + if !ok || preHash != postHash { + updates = append(updates, path) + } + } + return updates +} + +func doGoModTidy() { + targetFiles := []string{"go.mod", "go.sum"} + preHashes, err := hashSourceFiles(targetFiles) + if err != nil { + log.Fatal("failed to hash go.mod/go.sum", "err", err) + } + tc := new(build.GoToolchain) + c := tc.Go("mod", "tidy") + build.MustRun(c) + postHashes, err := hashSourceFiles(targetFiles) + updates := compareHashedFilesets(preHashes, postHashes) + for _, updatedFile := range updates { + fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile) + } + if len(updates) != 0 { + log.Fatal("go.sum and/or go.mod were updated by running 'go mod tidy'") + } +} + +// doGenerate ensures that re-generating generated files does not cause +// any mutations in the source file tree: i.e. all generated files were +// updated and committed. Any stale generated files are updated. +func doGenerate() { + var ( + tc = new(build.GoToolchain) + cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.") + verify = flag.Bool("verify", false, "check whether any files are changed by go generate") + ) + + protocPath := downloadProtoc(*cachedir) + protocGenGoPath := downloadProtocGenGo(*cachedir) + + var preHashes map[string]common.Hash + if *verify { + var err error + preHashes, err = hashAllSourceFiles() + if err != nil { + log.Fatal("failed to compute map of source hashes", "err", err) + } + } + + c := tc.Go("generate", "./...") + pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")} + c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator))) + build.MustRun(c) + + if !*verify { + return + } + // Check if files were changed. + postHashes, err := hashAllSourceFiles() + if err != nil { + log.Fatal("error computing source tree file hashes", "err", err) + } + updates := compareHashedFilesets(preHashes, postHashes) + for _, updatedFile := range updates { + fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile) + } + if len(updates) != 0 { + log.Fatal("One or more generated files were updated by running 'go generate ./...'") + } +} + // doLint runs golangci-lint on requested packages. func doLint(cmdline []string) { var ( @@ -376,6 +501,8 @@ func doLint(cmdline []string) { linter := downloadLinter(*cachedir) lflags := []string{"run", "--config", ".golangci.yml"} build.MustRunCommandWithOutput(linter, append(lflags, packages...)...) + + doGoModTidy() fmt.Println("You have achieved perfection.") } @@ -407,6 +534,96 @@ func downloadLinter(cachedir string) string { return filepath.Join(cachedir, base, "golangci-lint") } +// protocArchiveBaseName returns the name of the protoc archive file for +// the current system, stripped of version and file suffix. +func protocArchiveBaseName() (string, error) { + switch runtime.GOOS + "-" + runtime.GOARCH { + case "windows-amd64": + return "win64", nil + case "windows-386": + return "win32", nil + case "linux-arm64": + return "linux-aarch_64", nil + case "linux-386": + return "linux-x86_32", nil + case "linux-amd64": + return "linux-x86_64", nil + case "darwin-arm64": + return "osx-aarch_64", nil + case "darwin-amd64": + return "osx-x86_64", nil + default: + return "", fmt.Errorf("no prebuilt release of protoc available for this system (os: %s, arch: %s)", runtime.GOOS, runtime.GOARCH) + } +} + +// downloadProtocGenGo downloads protoc-gen-go, which is used by protoc +// in the generate command. It returns the full path of the directory +// containing the 'protoc-gen-go' executable. +func downloadProtocGenGo(cachedir string) string { + csdb := build.MustLoadChecksums("build/checksums.txt") + version, err := build.Version(csdb, "protoc-gen-go") + if err != nil { + log.Fatal(err) + } + baseName := fmt.Sprintf("protoc-gen-go.v%s.%s.%s", version, runtime.GOOS, runtime.GOARCH) + archiveName := baseName + if runtime.GOOS == "windows" { + archiveName += ".zip" + } else { + archiveName += ".tar.gz" + } + + url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf-go/releases/download/v%s/%s", version, archiveName) + + archivePath := path.Join(cachedir, archiveName) + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) + } + extractDest := filepath.Join(cachedir, baseName) + if err := build.ExtractArchive(archivePath, extractDest); err != nil { + log.Fatal(err) + } + extractDest, err = filepath.Abs(extractDest) + if err != nil { + log.Fatal("error resolving absolute path for protoc", "err", err) + } + return extractDest +} + +// downloadProtoc downloads the prebuilt protoc binary used to lint generated +// files as a CI step. It returns the full path to the directory containing +// the protoc executable. +func downloadProtoc(cachedir string) string { + csdb := build.MustLoadChecksums("build/checksums.txt") + version, err := build.Version(csdb, "protoc") + if err != nil { + log.Fatal(err) + } + baseName, err := protocArchiveBaseName() + if err != nil { + log.Fatal(err) + } + + fileName := fmt.Sprintf("protoc-%s-%s", version, baseName) + archiveFileName := fileName + ".zip" + url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf/releases/download/v%s/%s", version, archiveFileName) + archivePath := filepath.Join(cachedir, archiveFileName) + + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) + } + extractDest := filepath.Join(cachedir, fileName) + if err := build.ExtractArchive(archivePath, extractDest); err != nil { + log.Fatal(err) + } + extractDest, err = filepath.Abs(extractDest) + if err != nil { + log.Fatal("error resolving absolute path for protoc", "err", err) + } + return extractDest +} + // Release Packaging func doArchive(cmdline []string) { var ( @@ -514,10 +731,9 @@ func maybeSkipArchive(env build.Environment) { } // Builds the docker images and optionally uploads them to Docker Hub. -func doDocker(cmdline []string) { +func doDockerBuildx(cmdline []string) { var ( - image = flag.Bool("image", false, `Whether to build and push an arch specific docker image`) - manifest = flag.String("manifest", "", `Push a multi-arch docker image for the specified architectures (usually "amd64,arm64")`) + platform = flag.String("platform", "", `Push a multi-arch docker image for the specified architectures (usually "linux/amd64,linux/arm64")`) upload = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`) ) flag.CommandLine.Parse(cmdline) @@ -552,129 +768,26 @@ func doDocker(cmdline []string) { case strings.HasPrefix(env.Tag, "v1."): tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), "v" + params.Version} } - // If architecture specific image builds are requested, build and push them - if *image { - build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:TAG", *upload), ".") - build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:alltools-TAG", *upload), "-f", "Dockerfile.alltools", ".") - - // Tag and upload the images to Docker Hub - for _, tag := range tags { - gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, runtime.GOARCH) - toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, runtime.GOARCH) - - // If the image already exists (non version tag), check the build - // number to prevent overwriting a newer commit if concurrent builds - // are running. This is still a tiny bit racey if two published are - // done at the same time, but that's extremely unlikely even on the - // master branch. - for _, img := range []string{gethImage, toolImage} { - if exec.Command("docker", "pull", img).Run() != nil { - continue // Generally the only failure is a missing image, which is good - } - buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput() - if err != nil { - log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum)) - } - buildnum = bytes.TrimSpace(buildnum) - - if len(buildnum) > 0 && len(env.Buildnum) > 0 { - oldnum, err := strconv.Atoi(string(buildnum)) - if err != nil { - log.Fatalf("Failed to parse old image build number: %v", err) - } - newnum, err := strconv.Atoi(env.Buildnum) - if err != nil { - log.Fatalf("Failed to parse current build number: %v", err) - } - if oldnum > newnum { - log.Fatalf("Current build number %d not newer than existing %d", newnum, oldnum) - } else { - log.Printf("Updating %s from build %d to %d", img, oldnum, newnum) - } - } - } - build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:TAG", *upload), gethImage) - build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:alltools-TAG", *upload), toolImage) - build.MustRunCommand("docker", "push", gethImage) - build.MustRunCommand("docker", "push", toolImage) - } - } - // If multi-arch image manifest push is requested, assemble it - if len(*manifest) != 0 { - // Since different architectures are pushed by different builders, wait - // until all required images are updated. - var mismatch bool - for i := 0; i < 2; i++ { // 2 attempts, second is race check - mismatch = false // hope there's no mismatch now - - for _, tag := range tags { - for _, arch := range strings.Split(*manifest, ",") { - gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, arch) - toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, arch) - - for _, img := range []string{gethImage, toolImage} { - if out, err := exec.Command("docker", "pull", img).CombinedOutput(); err != nil { - log.Printf("Required image %s unavailable: %v\nOutput: %s", img, err, out) - mismatch = true - break - } - buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput() - if err != nil { - log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum)) - } - buildnum = bytes.TrimSpace(buildnum) - - if string(buildnum) != env.Buildnum { - log.Printf("Build number mismatch on %s: want %s, have %s", img, env.Buildnum, buildnum) - mismatch = true - break - } - } - if mismatch { - break - } - } - if mismatch { - break - } - } - if mismatch { - // Build numbers mismatching, retry in a short time to - // avoid concurrent fails in both publisher images. If - // however the retry failed too, it means the concurrent - // builder is still crunching, let that do the publish. - if i == 0 { - time.Sleep(30 * time.Second) - } - continue - } - break - } - if mismatch { - log.Println("Relinquishing publish to other builder") - return - } - // Assemble and push the Geth manifest image - for _, tag := range tags { - gethImage := fmt.Sprintf("%s:%s", *upload, tag) - - var gethSubImages []string - for _, arch := range strings.Split(*manifest, ",") { - gethSubImages = append(gethSubImages, gethImage+"-"+arch) - } - build.MustRunCommand("docker", append([]string{"manifest", "create", gethImage}, gethSubImages...)...) - build.MustRunCommand("docker", "manifest", "push", gethImage) - } - // Assemble and push the alltools manifest image - for _, tag := range tags { - toolImage := fmt.Sprintf("%s:alltools-%s", *upload, tag) - - var toolSubImages []string - for _, arch := range strings.Split(*manifest, ",") { - toolSubImages = append(toolSubImages, toolImage+"-"+arch) - } - build.MustRunCommand("docker", append([]string{"manifest", "create", toolImage}, toolSubImages...)...) - build.MustRunCommand("docker", "manifest", "push", toolImage) + // Need to create a mult-arch builder + build.MustRunCommand("docker", "buildx", "create", "--use", "--name", "multi-arch-builder", "--platform", *platform) + + for _, spec := range []struct { + file string + base string + }{ + {file: "Dockerfile", base: fmt.Sprintf("%s:", *upload)}, + {file: "Dockerfile.alltools", base: fmt.Sprintf("%s:alltools-", *upload)}, + } { + for _, tag := range tags { // latest, stable etc + gethImage := fmt.Sprintf("%s%s", spec.base, tag) + build.MustRunCommand("docker", "buildx", "build", + "--build-arg", "COMMIT="+env.Commit, + "--build-arg", "VERSION="+params.VersionWithMeta, + "--build-arg", "BUILDNUM="+env.Buildnum, + "--tag", gethImage, + "--platform", *platform, + "--push", + "--file", spec.file, ".") } } } @@ -703,8 +816,8 @@ func doDebianSource(cmdline []string) { } // Download and verify the Go source packages. var ( - gobootbundle = downloadGoBootstrapSources(*cachedir) - gobundle = downloadGoSources(*cachedir) + gobootbundles = downloadGoBootstrapSources(*cachedir) + gobundle = downloadGoSources(*cachedir) ) // Download all the dependencies needed to build the sources and run the ci script srcdepfetch := tc.Go("mod", "download") @@ -717,17 +830,19 @@ func doDebianSource(cmdline []string) { // Create Debian packages and upload them. for _, pkg := range debPackages { - for distro, goboot := range debDistroGoBoots { + for _, distro := range debDistros { // Prepare the debian package with the go-ethereum sources. - meta := newDebMetadata(distro, goboot, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables) + meta := newDebMetadata(distro, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables) pkgdir := stageDebianSource(*workdir, meta) // Add bootstrapper Go source code - if err := build.ExtractArchive(gobootbundle, pkgdir); err != nil { - log.Fatalf("Failed to extract bootstrapper Go sources: %v", err) - } - if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".goboot")); err != nil { - log.Fatalf("Failed to rename bootstrapper Go source folder: %v", err) + for i, gobootbundle := range gobootbundles { + if err := build.ExtractArchive(gobootbundle, pkgdir); err != nil { + log.Fatalf("Failed to extract bootstrapper Go sources: %v", err) + } + if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, fmt.Sprintf(".goboot-%d", i+1))); err != nil { + log.Fatalf("Failed to rename bootstrapper Go source folder: %v", err) + } } // Add builder Go source code if err := build.ExtractArchive(gobundle, pkgdir); err != nil { @@ -763,21 +878,26 @@ func doDebianSource(cmdline []string) { } } -// downloadGoBootstrapSources downloads the Go source tarball that will be used +// downloadGoBootstrapSources downloads the Go source tarball(s) that will be used // to bootstrap the builder Go. -func downloadGoBootstrapSources(cachedir string) string { +func downloadGoBootstrapSources(cachedir string) []string { csdb := build.MustLoadChecksums("build/checksums.txt") - gobootVersion, err := build.Version(csdb, "ppa-builder") - if err != nil { - log.Fatal(err) - } - file := fmt.Sprintf("go%s.src.tar.gz", gobootVersion) - url := "https://dl.google.com/go/" + file - dst := filepath.Join(cachedir, file) - if err := csdb.DownloadFile(url, dst); err != nil { - log.Fatal(err) + + var bundles []string + for _, booter := range []string{"ppa-builder-1", "ppa-builder-2"} { + gobootVersion, err := build.Version(csdb, booter) + if err != nil { + log.Fatal(err) + } + file := fmt.Sprintf("go%s.src.tar.gz", gobootVersion) + url := "https://dl.google.com/go/" + file + dst := filepath.Join(cachedir, file) + if err := csdb.DownloadFile(url, dst); err != nil { + log.Fatal(err) + } + bundles = append(bundles, dst) } - return dst + return bundles } // downloadGoSources downloads the Go source tarball. @@ -855,10 +975,7 @@ type debPackage struct { } type debMetadata struct { - Env build.Environment - GoBootPackage string - GoBootPath string - + Env build.Environment PackageName string // go-ethereum version being built. Note that this @@ -886,21 +1003,19 @@ func (d debExecutable) Package() string { return d.BinaryName } -func newDebMetadata(distro, goboot, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata { +func newDebMetadata(distro, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata { if author == "" { // No signing key, use default author. author = "Ethereum Builds " } return debMetadata{ - GoBootPackage: goboot, - GoBootPath: debGoBootPaths[goboot], - PackageName: name, - Env: env, - Author: author, - Distro: distro, - Version: version, - Time: t.Format(time.RFC1123Z), - Executables: exes, + PackageName: name, + Env: env, + Author: author, + Distro: distro, + Version: version, + Time: t.Format(time.RFC1123Z), + Executables: exes, } } diff --git a/build/deb/ethereum/deb.control b/build/deb/ethereum/deb.control index 3b759f2d04..333e954c17 100644 --- a/build/deb/ethereum/deb.control +++ b/build/deb/ethereum/deb.control @@ -2,7 +2,7 @@ Source: {{.Name}} Section: science Priority: extra Maintainer: {{.Author}} -Build-Depends: debhelper (>= 8.0.0), {{.GoBootPackage}} +Build-Depends: debhelper (>= 8.0.0), golang-go Standards-Version: 3.9.5 Homepage: https://ethereum.org Vcs-Git: https://github.com/ethereum/go-ethereum.git diff --git a/build/deb/ethereum/deb.rules b/build/deb/ethereum/deb.rules index daca793e55..3287e15ff0 100644 --- a/build/deb/ethereum/deb.rules +++ b/build/deb/ethereum/deb.rules @@ -7,7 +7,7 @@ # Launchpad rejects Go's access to $HOME, use custom folders export GOCACHE=/tmp/go-build export GOPATH=/tmp/gopath -export GOROOT_BOOTSTRAP={{.GoBootPath}} +export GOROOT_BOOTSTRAP=/usr/lib/go override_dh_auto_clean: # Don't try to be smart Launchpad, we know our build rules better than you @@ -19,8 +19,9 @@ override_dh_auto_build: # # We're also shipping the bootstrapper as of Go 1.20 as it had minimum version # requirements opposed to older versions of Go. - (mv .goboot ../ && cd ../.goboot/src && ./make.bash) - (mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot ./make.bash) + (mv .goboot-1 ../ && cd ../.goboot-1/src && ./make.bash) + (mv .goboot-2 ../ && cd ../.goboot-2/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-1 ./make.bash) + (mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-2 ./make.bash) # We can't download external go modules within Launchpad, so we're shipping the # entire dependency source cache with go-ethereum. diff --git a/build/tools/tools.go b/build/tools/tools.go index 506e26eeff..e9e2241d2f 100644 --- a/build/tools/tools.go +++ b/build/tools/tools.go @@ -22,6 +22,6 @@ package tools import ( // Tool imports for go:generate. _ "github.com/fjl/gencodec" - _ "github.com/golang/protobuf/protoc-gen-go" _ "golang.org/x/tools/cmd/stringer" + _ "google.golang.org/protobuf/cmd/protoc-gen-go" ) diff --git a/build/update-license.go b/build/update-license.go index 70e2de06c7..f548a5995b 100644 --- a/build/update-license.go +++ b/build/update-license.go @@ -46,13 +46,12 @@ import ( "path/filepath" "regexp" "runtime" + "slices" "strconv" "strings" "sync" "text/template" "time" - - "golang.org/x/exp/slices" ) var ( @@ -292,8 +291,8 @@ func writeAuthors(files []string) { } } // Write sorted list of authors back to the file. - slices.SortFunc(list, func(a, b string) bool { - return strings.ToLower(a) < strings.ToLower(b) + slices.SortFunc(list, func(a, b string) int { + return strings.Compare(strings.ToLower(a), strings.ToLower(b)) }) content := new(bytes.Buffer) content.WriteString(authorsFileHeader) diff --git a/cmd/clef/README.md b/cmd/clef/README.md index cf09265136..a73ffd5b45 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -29,7 +29,7 @@ GLOBAL OPTIONS: --loglevel value log level to emit to the screen (default: 4) --keystore value Directory for the keystore (default: "$HOME/.ethereum/keystore") --configdir value Directory for Clef configuration (default: "$HOME/.clef") - --chainid value Chain id to use for signing (1=mainnet, 5=Goerli) (default: 1) + --chainid value Chain id to use for signing (1=mainnet, 17000=Holesky) (default: 1) --lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength --nousb Disables monitoring for and managing USB hardware wallets --pcscdpath value Path to the smartcard daemon (pcscd) socket file (default: "/run/pcscd/pcscd.comm") @@ -225,8 +225,8 @@ Response - `value` [number:optional]: amount of Wei to send with the transaction - `data` [data:optional]: input data - `nonce` [number]: account nonce - 1. method signature [string:optional] - - The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected. + 2. method signature [string:optional] + - The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected. #### Result diff --git a/cmd/clef/consolecmd_test.go b/cmd/clef/consolecmd_test.go index c8b37f5b92..a5b324c53f 100644 --- a/cmd/clef/consolecmd_test.go +++ b/cmd/clef/consolecmd_test.go @@ -27,9 +27,8 @@ import ( // TestImportRaw tests clef --importraw func TestImportRaw(t *testing.T) { t.Parallel() - keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) + keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) - t.Cleanup(func() { os.Remove(keyPath) }) t.Run("happy-path", func(t *testing.T) { t.Parallel() @@ -68,9 +67,8 @@ func TestImportRaw(t *testing.T) { // TestListAccounts tests clef --list-accounts func TestListAccounts(t *testing.T) { t.Parallel() - keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) + keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) - t.Cleanup(func() { os.Remove(keyPath) }) t.Run("no-accounts", func(t *testing.T) { t.Parallel() @@ -97,9 +95,8 @@ func TestListAccounts(t *testing.T) { // TestListWallets tests clef --list-wallets func TestListWallets(t *testing.T) { t.Parallel() - keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) + keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) - t.Cleanup(func() { os.Remove(keyPath) }) t.Run("no-accounts", func(t *testing.T) { t.Parallel() diff --git a/cmd/clef/main.go b/cmd/clef/main.go index f9b00e4a12..dde4ae853f 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -100,7 +100,7 @@ var ( chainIdFlag = &cli.Int64Flag{ Name: "chainid", Value: params.MainnetChainConfig.ChainID.Int64(), - Usage: "Chain id to use for signing (1=mainnet, 5=Goerli)", + Usage: "Chain id to use for signing (1=mainnet, 17000=Holesky)", } rpcPortFlag = &cli.IntFlag{ Name: "http.port", @@ -552,7 +552,7 @@ func listWallets(c *cli.Context) error { // accountImport imports a raw hexadecimal private key via CLI. func accountImport(c *cli.Context) error { if c.Args().Len() != 1 { - return errors.New(" must be given as first argument.") + return errors.New(" must be given as first argument") } internalApi, ui, err := initInternalApi(c) if err != nil { diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md index 112dae6512..cc4a645596 100644 --- a/cmd/clef/rules.md +++ b/cmd/clef/rules.md @@ -9,14 +9,14 @@ It enables usecases like the following: The two main features that are required for this to work well are; -1. Rule Implementation: how to create, manage and interpret rules in a flexible but secure manner -2. Credential managements and credentials; how to provide auto-unlock without exposing keys unnecessarily. +1. Rule Implementation: how to create, manage, and interpret rules in a flexible but secure manner +2. Credential management and credentials; how to provide auto-unlock without exposing keys unnecessarily. The section below deals with both of them ## Rule Implementation -A ruleset file is implemented as a `js` file. Under the hood, the ruleset-engine is a `SignerUI`, implementing the same methods as the `json-rpc` methods +A ruleset file is implemented as a `js` file. Under the hood, the ruleset engine is a `SignerUI`, implementing the same methods as the `json-rpc` methods defined in the UI protocol. Example: ```js @@ -27,7 +27,7 @@ function asBig(str) { return new BigNumber(str) } -// Approve transactions to a certain contract if value is below a certain limit +// Approve transactions to a certain contract if the value is below a certain limit function ApproveTx(req) { var limit = big.Newint("0xb1a2bc2ec50000") var value = asBig(req.transaction.value); @@ -70,7 +70,7 @@ The Otto vm has a few [caveats](https://github.com/robertkrimen/otto): Additionally, a few more have been added * The rule execution cannot load external javascript files. -* The only preloaded library is [`bignumber.js`](https://github.com/MikeMcl/bignumber.js) version `2.0.3`. This one is fairly old, and is not aligned with the documentation at the github repository. +* The only preloaded library is [`bignumber.js`](https://github.com/MikeMcl/bignumber.js) version `2.0.3`. This one is fairly old, and is not aligned with the documentation at the GitHub repository. * Each invocation is made in a fresh virtual machine. This means that you cannot store data in global variables between invocations. This is a deliberate choice -- if you want to store data, use the disk-backed `storage`, since rules should not rely on ephemeral data. * Javascript API parameters are _always_ an object. This is also a design choice, to ensure that parameters are accessed by _key_ and not by order. This is to prevent mistakes due to missing parameters or parameter changes. * The JS engine has access to `storage` and `console`. @@ -88,8 +88,8 @@ Some security precautions can be made, such as: ##### Security of implementation -The drawbacks of this very flexible solution is that the `signer` needs to contain a javascript engine. This is pretty simple to implement, since it's already -implemented for `geth`. There are no known security vulnerabilities in, nor have we had any security-problems with it so far. +The drawback of this very flexible solution is that the `signer` needs to contain a javascript engine. This is pretty simple to implement since it's already +implemented for `geth`. There are no known security vulnerabilities in it, nor have we had any security problems with it so far. The javascript engine would be an added attack surface; but if the validation of `rulesets` is made good (with hash-based attestation), the actual javascript cannot be considered an attack surface -- if an attacker can control the ruleset, a much simpler attack would be to implement an "always-approve" rule instead of exploiting the js vm. The only benefit @@ -105,7 +105,7 @@ It's unclear whether any other DSL could be more secure; since there's always th ## Credential management -The ability to auto-approve transaction means that the signer needs to have necessary credentials to decrypt keyfiles. These passwords are hereafter called `ksp` (keystore pass). +The ability to auto-approve transactions means that the signer needs to have the necessary credentials to decrypt keyfiles. These passwords are hereafter called `ksp` (keystore pass). ### Example implementation @@ -127,8 +127,8 @@ The `vault.dat` would be an encrypted container storing the following informatio ### Security considerations -This would leave it up to the user to ensure that the `path/to/masterseed` is handled in a secure way. It's difficult to get around this, although one could -imagine leveraging OS-level keychains where supported. The setup is however in general similar to how ssh-keys are stored in `.ssh/`. +This would leave it up to the user to ensure that the `path/to/masterseed` is handled securely. It's difficult to get around this, although one could +imagine leveraging OS-level keychains where supported. The setup is however, in general, similar to how ssh-keys are stored in `.ssh/`. # Implementation status @@ -149,7 +149,7 @@ function big(str) { // Time window: 1 week var window = 1000* 3600*24*7; -// Limit : 1 ether +// Limit: 1 ether var limit = new BigNumber("1e18"); function isLimitOk(transaction) { @@ -163,7 +163,7 @@ function isLimitOk(transaction) { if (stored != "") { txs = JSON.parse(stored) } - // First, remove all that have passed out of the time-window + // First, remove all that has passed out of the time window var newtxs = txs.filter(function(tx){return tx.tstamp > windowstart}); console.log(txs, newtxs.length); @@ -174,7 +174,7 @@ function isLimitOk(transaction) { console.log("ApproveTx > Sum so far", sum); console.log("ApproveTx > Requested", value.toNumber()); - // Would we exceed weekly limit ? + // Would we exceed the weekly limit ? return sum.plus(value).lt(limit) } diff --git a/cmd/devp2p/README.md b/cmd/devp2p/README.md index 284dfe0a45..ad2985b4b0 100644 --- a/cmd/devp2p/README.md +++ b/cmd/devp2p/README.md @@ -44,7 +44,7 @@ set to standard output. The following filters are supported: - `-limit ` limits the output set to N entries, taking the top N nodes by score - `-ip ` filters nodes by IP subnet - `-min-age ` filters nodes by 'first seen' time -- `-eth-network ` filters nodes by "eth" ENR entry +- `-eth-network ` filters nodes by "eth" ENR entry - `-les-server` filters nodes by LES server support - `-snap` filters nodes by snap protocol support diff --git a/cmd/devp2p/discv4cmd.go b/cmd/devp2p/discv4cmd.go index 45bcdcd367..3b5400ca3a 100644 --- a/cmd/devp2p/discv4cmd.go +++ b/cmd/devp2p/discv4cmd.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "net" + "net/http" "strconv" "strings" "time" @@ -28,9 +29,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" "github.com/urfave/cli/v2" ) @@ -45,6 +48,7 @@ var ( discv4ResolveJSONCommand, discv4CrawlCommand, discv4TestCommand, + discv4ListenCommand, }, } discv4PingCommand = &cli.Command{ @@ -75,6 +79,14 @@ var ( Flags: discoveryNodeFlags, ArgsUsage: "", } + discv4ListenCommand = &cli.Command{ + Name: "listen", + Usage: "Runs a discovery node", + Action: discv4Listen, + Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{ + httpAddrFlag, + }), + } discv4CrawlCommand = &cli.Command{ Name: "crawl", Usage: "Updates a nodes.json file with random nodes found in the DHT", @@ -131,6 +143,10 @@ var ( Usage: "Enode of the remote node under test", EnvVars: []string{"REMOTE_ENODE"}, } + httpAddrFlag = &cli.StringFlag{ + Name: "rpc", + Usage: "HTTP server listening address", + } ) var discoveryNodeFlags = []cli.Flag{ @@ -154,6 +170,27 @@ func discv4Ping(ctx *cli.Context) error { return nil } +func discv4Listen(ctx *cli.Context) error { + disc, _ := startV4(ctx) + defer disc.Close() + + fmt.Println(disc.Self()) + + httpAddr := ctx.String(httpAddrFlag.Name) + if httpAddr == "" { + // Non-HTTP mode. + select {} + } + + api := &discv4API{disc} + log.Info("Starting RPC API server", "addr", httpAddr) + srv := rpc.NewServer() + srv.RegisterName("discv4", api) + http.DefaultServeMux.Handle("/", srv) + httpsrv := http.Server{Addr: httpAddr, Handler: http.DefaultServeMux} + return httpsrv.ListenAndServe() +} + func discv4RequestRecord(ctx *cli.Context) error { n := getNodeArg(ctx) disc, _ := startV4(ctx) @@ -362,3 +399,23 @@ func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { } return nodes, nil } + +type discv4API struct { + host *discover.UDPv4 +} + +func (api *discv4API) LookupRandom(n int) (ns []*enode.Node) { + it := api.host.RandomNodes() + for len(ns) < n && it.Next() { + ns = append(ns, it.Node()) + } + return ns +} + +func (api *discv4API) Buckets() [][]discover.BucketNode { + return api.host.TableBuckets() +} + +func (api *discv4API) Self() *enode.Node { + return api.host.Self() +} diff --git a/cmd/devp2p/dns_cloudflare.go b/cmd/devp2p/dns_cloudflare.go index a3cc69cf19..b8aded7b0d 100644 --- a/cmd/devp2p/dns_cloudflare.go +++ b/cmd/devp2p/dns_cloudflare.go @@ -88,7 +88,8 @@ func (c *cloudflareClient) checkZone(name string) error { if !strings.HasSuffix(name, "."+zone.Name) { return fmt.Errorf("CloudFlare zone name %q does not match name %q to be deployed", zone.Name, name) } - needPerms := map[string]bool{"#zone:edit": false, "#zone:read": false} + // Necessary permissions for Cloudlare management - Zone:Read, DNS:Read, Zone:Edit, DNS:Edit + needPerms := map[string]bool{"#zone:edit": false, "#zone:read": false, "#dns_records:read": false, "#dns_records:edit": false} for _, perm := range zone.Permissions { if _, ok := needPerms[perm]; ok { needPerms[perm] = true diff --git a/cmd/devp2p/dns_route53.go b/cmd/devp2p/dns_route53.go index 21a32f9414..a6125b8263 100644 --- a/cmd/devp2p/dns_route53.go +++ b/cmd/devp2p/dns_route53.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "slices" "strconv" "strings" "time" @@ -32,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/urfave/cli/v2" - "golang.org/x/exp/slices" ) const ( diff --git a/cmd/devp2p/enrcmd.go b/cmd/devp2p/enrcmd.go index c5a97c8411..c9b692612f 100644 --- a/cmd/devp2p/enrcmd.go +++ b/cmd/devp2p/enrcmd.go @@ -183,8 +183,8 @@ var attrFormatters = map[string]func(rlp.RawValue) (string, bool){ } func formatAttrRaw(v rlp.RawValue) (string, bool) { - s := hex.EncodeToString(v) - return s, true + content, _, err := rlp.SplitString(v) + return hex.EncodeToString(content), err == nil } func formatAttrString(v rlp.RawValue) (string, bool) { diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go index e8b3725b17..2b503d62df 100644 --- a/cmd/devp2p/internal/ethtest/chain.go +++ b/cmd/devp2p/internal/ethtest/chain.go @@ -26,7 +26,8 @@ import ( "io" "math/big" "os" - "path" + "path/filepath" + "slices" "sort" "strings" @@ -40,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) // Chain is a lightweight blockchain-like store which can read a hivechain @@ -56,21 +56,21 @@ type Chain struct { // NewChain takes the given chain.rlp file, and decodes and returns // the blocks from the file. func NewChain(dir string) (*Chain, error) { - gen, err := loadGenesis(path.Join(dir, "genesis.json")) + gen, err := loadGenesis(filepath.Join(dir, "genesis.json")) if err != nil { return nil, err } gblock := gen.ToBlock() - blocks, err := blocksFromFile(path.Join(dir, "chain.rlp"), gblock) + blocks, err := blocksFromFile(filepath.Join(dir, "chain.rlp"), gblock) if err != nil { return nil, err } - state, err := readState(path.Join(dir, "headstate.json")) + state, err := readState(filepath.Join(dir, "headstate.json")) if err != nil { return nil, err } - accounts, err := readAccounts(path.Join(dir, "accounts.json")) + accounts, err := readAccounts(filepath.Join(dir, "accounts.json")) if err != nil { return nil, err } diff --git a/cmd/devp2p/internal/ethtest/conn.go b/cmd/devp2p/internal/ethtest/conn.go index c4f1bb1ff4..991c1a6c15 100644 --- a/cmd/devp2p/internal/ethtest/conn.go +++ b/cmd/devp2p/internal/ethtest/conn.go @@ -53,7 +53,8 @@ func (s *Suite) dial() (*Conn, error) { // dialAs attempts to dial a given node and perform a handshake using the given // private key. func (s *Suite) dialAs(key *ecdsa.PrivateKey) (*Conn, error) { - fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", s.Dest.IP(), s.Dest.TCP())) + tcpEndpoint, _ := s.Dest.TCPEndpoint() + fd, err := net.Dial("tcp", tcpEndpoint.String()) if err != nil { return nil, err } diff --git a/cmd/devp2p/internal/ethtest/engine.go b/cmd/devp2p/internal/ethtest/engine.go index ea4fc76e6f..0e94efa5bd 100644 --- a/cmd/devp2p/internal/ethtest/engine.go +++ b/cmd/devp2p/internal/ethtest/engine.go @@ -22,7 +22,7 @@ import ( "io" "net/http" "os" - "path" + "path/filepath" "time" "github.com/ethereum/go-ethereum/common" @@ -38,7 +38,7 @@ type EngineClient struct { // NewEngineClient creates a new engine client. func NewEngineClient(dir, url, jwt string) (*EngineClient, error) { - headfcu, err := os.ReadFile(path.Join(dir, "headfcu.json")) + headfcu, err := os.ReadFile(filepath.Join(dir, "headfcu.json")) if err != nil { return nil, fmt.Errorf("failed to read headfcu: %w", err) } diff --git a/cmd/devp2p/internal/ethtest/snap.go b/cmd/devp2p/internal/ethtest/snap.go index 64e0633585..4f1b6f8656 100644 --- a/cmd/devp2p/internal/ethtest/snap.go +++ b/cmd/devp2p/internal/ethtest/snap.go @@ -32,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" - "golang.org/x/crypto/sha3" ) func (c *Conn) snapRequest(code uint64, msg any) (any, error) { @@ -648,7 +647,7 @@ The server should reject the request.`, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8}}, }, nBytes: 5000, - expHashes: []common.Hash{common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")}, + expHashes: []common.Hash{types.EmptyCodeHash}, }, { @@ -905,7 +904,7 @@ func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error { // that the serving node is missing var ( bytecodes = res.Codes - hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher = crypto.NewKeccakState() hash = make([]byte, 32) codes = make([][]byte, len(req.Hashes)) ) @@ -964,7 +963,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error { // Cross reference the requested trienodes with the response to find gaps // that the serving node is missing - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher := crypto.NewKeccakState() hash := make([]byte, 32) trienodes := res.Nodes if got, want := len(trienodes), len(tc.expHashes); got != want { diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index d9efe26244..5cb9fa0297 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -754,8 +754,8 @@ func makeSidecar(data ...byte) *types.BlobTxSidecar { ) for i := range blobs { blobs[i][0] = data[i] - c, _ := kzg4844.BlobToCommitment(blobs[i]) - p, _ := kzg4844.ComputeBlobProof(blobs[i], c) + c, _ := kzg4844.BlobToCommitment(&blobs[i]) + p, _ := kzg4844.ComputeBlobProof(&blobs[i], c) commitments = append(commitments, c) proofs = append(proofs, p) } @@ -849,7 +849,16 @@ func (s *Suite) TestBlobViolations(t *utesting.T) { if code, _, err := conn.Read(); err != nil { t.Fatalf("expected disconnect on blob violation, got err: %v", err) } else if code != discMsg { - t.Fatalf("expected disconnect on blob violation, got msg code: %d", code) + if code == protoOffset(ethProto)+eth.NewPooledTransactionHashesMsg { + // sometimes we'll get a blob transaction hashes announcement before the disconnect + // because blob transactions are scheduled to be fetched right away. + if code, _, err = conn.Read(); err != nil { + t.Fatalf("expected disconnect on blob violation, got err on second read: %v", err) + } + } + if code != discMsg { + t.Fatalf("expected disconnect on blob violation, got msg code: %d", code) + } } conn.Close() } diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go index c8479fd3aa..a1b1f89e6c 100644 --- a/cmd/devp2p/internal/ethtest/suite_test.go +++ b/cmd/devp2p/internal/ethtest/suite_test.go @@ -20,7 +20,7 @@ import ( crand "crypto/rand" "fmt" "os" - "path" + "path/filepath" "testing" "time" @@ -34,12 +34,12 @@ import ( "github.com/ethereum/go-ethereum/p2p" ) -func makeJWTSecret() (string, [32]byte, error) { +func makeJWTSecret(t *testing.T) (string, [32]byte, error) { var secret [32]byte if _, err := crand.Read(secret[:]); err != nil { return "", secret, fmt.Errorf("failed to create jwt secret: %v", err) } - jwtPath := path.Join(os.TempDir(), "jwt_secret") + jwtPath := filepath.Join(t.TempDir(), "jwt_secret") if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil { return "", secret, fmt.Errorf("failed to prepare jwt secret file: %v", err) } @@ -47,7 +47,7 @@ func makeJWTSecret() (string, [32]byte, error) { } func TestEthSuite(t *testing.T) { - jwtPath, secret, err := makeJWTSecret() + jwtPath, secret, err := makeJWTSecret(t) if err != nil { t.Fatalf("could not make jwt secret: %v", err) } @@ -75,7 +75,7 @@ func TestEthSuite(t *testing.T) { } func TestSnapSuite(t *testing.T) { - jwtPath, secret, err := makeJWTSecret() + jwtPath, secret, err := makeJWTSecret(t) if err != nil { t.Fatalf("could not make jwt secret: %v", err) } diff --git a/cmd/devp2p/internal/ethtest/transaction.go b/cmd/devp2p/internal/ethtest/transaction.go index 80b5d80745..cbbbbce8d9 100644 --- a/cmd/devp2p/internal/ethtest/transaction.go +++ b/cmd/devp2p/internal/ethtest/transaction.go @@ -102,7 +102,7 @@ func (s *Suite) sendTxs(t *utesting.T, txs []*types.Transaction) error { } } - return fmt.Errorf("timed out waiting for txs") + return errors.New("timed out waiting for txs") } func (s *Suite) sendInvalidTxs(t *utesting.T, txs []*types.Transaction) error { diff --git a/cmd/devp2p/internal/v4test/framework.go b/cmd/devp2p/internal/v4test/framework.go index 9286594181..958fb71179 100644 --- a/cmd/devp2p/internal/v4test/framework.go +++ b/cmd/devp2p/internal/v4test/framework.go @@ -53,16 +53,18 @@ func newTestEnv(remote string, listen1, listen2 string) *testenv { if err != nil { panic(err) } - if node.IP() == nil || node.UDP() == 0 { + if !node.IPAddr().IsValid() || node.UDP() == 0 { var ip net.IP var tcpPort, udpPort int - if ip = node.IP(); ip == nil { + if node.IPAddr().IsValid() { + ip = node.IPAddr().AsSlice() + } else { ip = net.ParseIP("127.0.0.1") } if tcpPort = node.TCP(); tcpPort == 0 { tcpPort = 30303 } - if udpPort = node.TCP(); udpPort == 0 { + if udpPort = node.UDP(); udpPort == 0 { udpPort = 30303 } node = enode.NewV4(node.Pubkey(), ip, tcpPort, udpPort) @@ -110,7 +112,7 @@ func (te *testenv) localEndpoint(c net.PacketConn) v4wire.Endpoint { } func (te *testenv) remoteEndpoint() v4wire.Endpoint { - return v4wire.NewEndpoint(te.remoteAddr, 0) + return v4wire.NewEndpoint(te.remoteAddr.AddrPort(), 0) } func contains(ns []v4wire.Node, key v4wire.Pubkey) bool { diff --git a/cmd/devp2p/internal/v5test/discv5tests.go b/cmd/devp2p/internal/v5test/discv5tests.go index 56624a0ca8..7dbd3c3be5 100644 --- a/cmd/devp2p/internal/v5test/discv5tests.go +++ b/cmd/devp2p/internal/v5test/discv5tests.go @@ -19,6 +19,7 @@ package v5test import ( "bytes" "net" + "slices" "sync" "time" @@ -266,7 +267,7 @@ func (s *Suite) TestFindnodeResults(t *utesting.T) { n := bn.conn.localNode.Node() expect[n.ID()] = n d := uint(enode.LogDist(n.ID(), s.Dest.ID())) - if !containsUint(dists, d) { + if !slices.Contains(dists, d) { dists = append(dists, d) } } diff --git a/cmd/devp2p/internal/v5test/framework.go b/cmd/devp2p/internal/v5test/framework.go index 10856a50bc..92a5048150 100644 --- a/cmd/devp2p/internal/v5test/framework.go +++ b/cmd/devp2p/internal/v5test/framework.go @@ -252,12 +252,3 @@ func checkRecords(records []*enr.Record) ([]*enode.Node, error) { } return nodes, nil } - -func containsUint(ints []uint, x uint) bool { - for i := range ints { - if ints[i] == x { - return true - } - } - return false -} diff --git a/cmd/devp2p/main.go b/cmd/devp2p/main.go index 8461a8b9b5..66974bba58 100644 --- a/cmd/devp2p/main.go +++ b/cmd/devp2p/main.go @@ -66,9 +66,15 @@ func commandHasFlag(ctx *cli.Context, flag cli.Flag) bool { for _, name := range names { set[name] = struct{}{} } - for _, fn := range ctx.FlagNames() { - if _, ok := set[fn]; ok { - return true + for _, ctx := range ctx.Lineage() { + if ctx.Command != nil { + for _, f := range ctx.Command.Flags { + for _, name := range f.Names() { + if _, ok := set[name]; ok { + return true + } + } + } } } return false diff --git a/cmd/devp2p/nodeset.go b/cmd/devp2p/nodeset.go index 7360dc5bcf..4fa862de14 100644 --- a/cmd/devp2p/nodeset.go +++ b/cmd/devp2p/nodeset.go @@ -21,11 +21,11 @@ import ( "encoding/json" "fmt" "os" + "slices" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/p2p/enode" - "golang.org/x/exp/slices" ) const jsonIndent = " " diff --git a/cmd/devp2p/nodesetcmd.go b/cmd/devp2p/nodesetcmd.go index d0ba0517ba..e1f8cc053e 100644 --- a/cmd/devp2p/nodesetcmd.go +++ b/cmd/devp2p/nodesetcmd.go @@ -19,7 +19,7 @@ package main import ( "errors" "fmt" - "net" + "net/netip" "sort" "strconv" "strings" @@ -205,11 +205,11 @@ func trueFilter(args []string) (nodeFilter, error) { } func ipFilter(args []string) (nodeFilter, error) { - _, cidr, err := net.ParseCIDR(args[0]) + prefix, err := netip.ParsePrefix(args[0]) if err != nil { return nil, err } - f := func(n nodeJSON) bool { return cidr.Contains(n.N.IP()) } + f := func(n nodeJSON) bool { return prefix.Contains(n.N.IPAddr()) } return f, nil } diff --git a/cmd/devp2p/rlpxcmd.go b/cmd/devp2p/rlpxcmd.go index aa7d065818..118731fd6c 100644 --- a/cmd/devp2p/rlpxcmd.go +++ b/cmd/devp2p/rlpxcmd.go @@ -77,7 +77,11 @@ var ( func rlpxPing(ctx *cli.Context) error { n := getNodeArg(ctx) - fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", n.IP(), n.TCP())) + tcpEndpoint, ok := n.TCPEndpoint() + if !ok { + return errors.New("node has no TCP endpoint") + } + fd, err := net.Dial("tcp", tcpEndpoint.String()) if err != nil { return err } @@ -105,7 +109,7 @@ func rlpxPing(ctx *cli.Context) error { } return fmt.Errorf("received disconnect message: %v", msg[0]) default: - return fmt.Errorf("invalid message code %d, expected handshake (code zero)", code) + return fmt.Errorf("invalid message code %d, expected handshake (code zero) or disconnect (code one)", code) } return nil } diff --git a/cmd/era/main.go b/cmd/era/main.go index e27d8ccec6..8b57fd695c 100644 --- a/cmd/era/main.go +++ b/cmd/era/main.go @@ -18,10 +18,11 @@ package main import ( "encoding/json" + "errors" "fmt" "math/big" "os" - "path" + "path/filepath" "strconv" "strings" "time" @@ -175,14 +176,14 @@ func open(ctx *cli.Context, epoch uint64) (*era.Era, error) { if epoch >= uint64(len(entries)) { return nil, fmt.Errorf("epoch out-of-bounds: last %d, want %d", len(entries)-1, epoch) } - return era.Open(path.Join(dir, entries[epoch])) + return era.Open(filepath.Join(dir, entries[epoch])) } // verify checks each era1 file in a directory to ensure it is well-formed and // that the accumulator matches the expected value. func verify(ctx *cli.Context) error { if ctx.Args().Len() != 1 { - return fmt.Errorf("missing accumulators file") + return errors.New("missing accumulators file") } roots, err := readHashes(ctx.Args().First()) @@ -203,7 +204,7 @@ func verify(ctx *cli.Context) error { } if len(entries) != len(roots) { - return fmt.Errorf("number of era1 files should match the number of accumulator hashes") + return errors.New("number of era1 files should match the number of accumulator hashes") } // Verify each epoch matches the expected root. @@ -211,7 +212,7 @@ func verify(ctx *cli.Context) error { // Wrap in function so defers don't stack. err := func() error { name := entries[i] - e, err := era.Open(path.Join(dir, name)) + e, err := era.Open(filepath.Join(dir, name)) if err != nil { return fmt.Errorf("error opening era1 file %s: %w", name, err) } @@ -308,7 +309,7 @@ func checkAccumulator(e *era.Era) error { func readHashes(f string) ([]common.Hash, error) { b, err := os.ReadFile(f) if err != nil { - return nil, fmt.Errorf("unable to open accumulators file") + return nil, errors.New("unable to open accumulators file") } s := strings.Split(string(b), "\n") // Remove empty last element, if present. diff --git a/cmd/ethkey/README.md b/cmd/ethkey/README.md index bfddd14677..a7f5316f45 100644 --- a/cmd/ethkey/README.md +++ b/cmd/ethkey/README.md @@ -50,4 +50,4 @@ contains the password. ## JSON -In case you need to output the result in a JSON format, you shall by using the `--json` flag. +In case you need to output the result in a JSON format, you shall use the `--json` flag. diff --git a/cmd/evm/README.md b/cmd/evm/README.md index 25647c18a9..f95b6b4d7b 100644 --- a/cmd/evm/README.md +++ b/cmd/evm/README.md @@ -14,15 +14,15 @@ The `evm t8n` tool is a stateless state transition utility. It is a utility which can 1. Take a prestate, including - - Accounts, - - Block context information, - - Previous blockshashes (*optional) + - Accounts, + - Block context information, + - Previous blockshashes (*optional) 2. Apply a set of transactions, 3. Apply a mining-reward (*optional), 4. And generate a post-state, including - - State root, transaction root, receipt root, - - Information about rejected transactions, - - Optionally: a full or partial post-state dump + - State root, transaction root, receipt root, + - Information about rejected transactions, + - Optionally: a full or partial post-state dump ### Specification diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index c5d836e0ea..d5cd8d8e3d 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -26,7 +26,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/tests" "github.com/urfave/cli/v2" @@ -51,7 +51,7 @@ func blockTestCmd(ctx *cli.Context) error { return errors.New("path-to-test argument required") } - var tracer vm.EVMLogger + var tracer *tracing.Hooks // Configure the EVM logger if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(&logger.Config{ @@ -86,7 +86,7 @@ func blockTestCmd(ctx *cli.Context) error { continue } test := tests[name] - if err := test.Run(false, rawdb.HashScheme, tracer, func(res error, chain *core.BlockChain) { + if err := test.Run(false, rawdb.HashScheme, false, tracer, func(res error, chain *core.BlockChain) { if ctx.Bool(DumpFlag.Name) { if state, _ := chain.State(); state != nil { fmt.Println(string(state.Dump(nil))) diff --git a/cmd/evm/internal/t8ntool/block.go b/cmd/evm/internal/t8ntool/block.go index a2dc473437..37a6db9ffc 100644 --- a/cmd/evm/internal/t8ntool/block.go +++ b/cmd/evm/internal/t8ntool/block.go @@ -160,7 +160,7 @@ func (i *bbInput) ToBlock() *types.Block { if i.Header.Difficulty != nil { header.Difficulty = i.Header.Difficulty } - return types.NewBlockWithHeader(header).WithBody(i.Txs, i.Ommers).WithWithdrawals(i.Withdrawals) + return types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: i.Txs, Uncles: i.Ommers, Withdrawals: i.Withdrawals}) } // SealBlock seals the given block using the configured engine. @@ -242,7 +242,7 @@ func readInput(ctx *cli.Context) (*bbInput, error) { if headerStr == stdinSelector || ommersStr == stdinSelector || txsStr == stdinSelector || cliqueStr == stdinSelector { decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(inputData); err != nil { - return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) + return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err)) } } if cliqueStr != stdinSelector && cliqueStr != "" { diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 1decb81934..d404771946 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -17,7 +17,9 @@ package t8ntool import ( + "encoding/json" "fmt" + "io" "math/big" "github.com/ethereum/go-ethereum/common" @@ -28,9 +30,11 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -62,6 +66,8 @@ type ExecutionResult struct { WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` + RequestsHash *common.Hash `json:"requestsRoot,omitempty"` + DepositRequests *types.Deposits `json:"depositRequests,omitempty"` } type ommer struct { @@ -119,7 +125,7 @@ type rejectedTx struct { // Apply applies a set of transactions to a pre-state func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIt txIterator, miningReward int64, - getTracerFn func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)) (*state.StateDB, *ExecutionResult, []byte, error) { + getTracerFn func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error)) (*state.StateDB, *ExecutionResult, []byte, error) { // Capture errors for BLOCKHASH operation, if we haven't been supplied the // required blockhashes var hashError error @@ -192,7 +198,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig) core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb) } - + if pre.Env.BlockHashes != nil && chainConfig.IsPrague(new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) { + var ( + prevNumber = pre.Env.Number - 1 + prevHash = pre.Env.BlockHashes[math.HexOrDecimal64(prevNumber)] + evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig) + ) + core.ProcessParentBlockHash(prevHash, evm, statedb) + } for i := 0; txIt.Next(); i++ { tx, err := txIt.Tx() if err != nil { @@ -222,11 +235,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, continue } } - tracer, err := getTracerFn(txIndex, tx.Hash()) + tracer, traceOutput, err := getTracerFn(txIndex, tx.Hash()) if err != nil { return nil, nil, nil, err } - vmConfig.Tracer = tracer + if tracer != nil { + vmConfig.Tracer = tracer.Hooks + } statedb.SetTxContext(tx.Hash(), txIndex) var ( @@ -236,6 +251,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, ) evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig) + if tracer != nil && tracer.OnTxStart != nil { + tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + } // (ret []byte, usedGas uint64, failed bool, err error) msgResult, err := core.ApplyMessage(evm, msg, gaspool) if err != nil { @@ -243,6 +261,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) gaspool.SetGas(prevGas) + if tracer != nil { + if tracer.OnTxEnd != nil { + tracer.OnTxEnd(nil, err) + } + if err := writeTraceResult(tracer, traceOutput); err != nil { + log.Warn("Error writing tracer output", "err", err) + } + } continue } includedTxs = append(includedTxs, tx) @@ -285,6 +311,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, //receipt.BlockNumber receipt.TransactionIndex = uint(txIndex) receipts = append(receipts, receipt) + if tracer != nil { + if tracer.Hooks.OnTxEnd != nil { + tracer.Hooks.OnTxEnd(receipt, nil) + } + if err = writeTraceResult(tracer, traceOutput); err != nil { + log.Warn("Error writing tracer output", "err", err) + } + } } txIndex++ @@ -300,7 +334,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, var ( blockReward = big.NewInt(miningReward) minerReward = new(big.Int).Set(blockReward) - perOmmer = new(big.Int).Div(blockReward, big.NewInt(32)) + perOmmer = new(big.Int).Rsh(blockReward, 5) ) for _, ommer := range pre.Env.Ommers { // Add 1/32th for each ommer included @@ -309,21 +343,19 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, reward := big.NewInt(8) reward.Sub(reward, new(big.Int).SetUint64(ommer.Delta)) reward.Mul(reward, blockReward) - reward.Div(reward, big.NewInt(8)) - statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward)) + reward.Rsh(reward, 3) + statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward), tracing.BalanceIncreaseRewardMineUncle) } - statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward)) + statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward), tracing.BalanceIncreaseRewardMineBlock) } // Apply withdrawals for _, w := range pre.Env.Withdrawals { // Amount is in gwei, turn into wei amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei)) - statedb.AddBalance(w.Address, uint256.MustFromBig(amount)) + statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal) } // Commit block - statedb.Finalise(chainConfig.IsEIP158(vmContext.BlockNumber)) - statedb.AccountsIntermediateRoot() - root, _, err := statedb.Commit(vmContext.BlockNumber.Uint64(), nil) + root, _, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber)) if err != nil { return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err)) } @@ -347,9 +379,31 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, execRs.CurrentExcessBlobGas = (*math.HexOrDecimal64)(&excessBlobGas) execRs.CurrentBlobGasUsed = (*math.HexOrDecimal64)(&blobGasUsed) } + if chainConfig.IsPrague(vmContext.BlockNumber, vmContext.Time) { + // Parse the requests from the logs + var allLogs []*types.Log + for _, receipt := range receipts { + allLogs = append(allLogs, receipt.Logs...) + } + requests, err := core.ParseDepositLogs(allLogs, chainConfig) + if err != nil { + return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err)) + } + // Calculate the requests root + h := types.DeriveSha(requests, trie.NewStackTrie(nil)) + execRs.RequestsHash = &h + // Get the deposits from the requests + deposits := make(types.Deposits, 0) + for _, req := range requests { + if dep, ok := req.Inner().(*types.Deposit); ok { + deposits = append(deposits, dep) + } + } + execRs.DepositRequests = &deposits + } // Re-create statedb instance with new root upon the updated database // for accessing latest states. - statedb, err = state.New(root, statedb.Database(), nil) + statedb, err = state.New(root, statedb.Database()) if err != nil { return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err)) } @@ -358,21 +412,20 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB { - sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) - statedb, _ := state.New(types.EmptyRootHash, sdb, nil) + tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) + sdb := state.NewDatabase(tdb, nil) + statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) statedb.SetNonce(addr, a.Nonce) - statedb.SetBalance(addr, uint256.MustFromBig(a.Balance)) + statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance) for k, v := range a.Storage { statedb.SetState(addr, k, v) } } // Commit and re-open to start with a clean state. - statedb.Finalise(false) - statedb.AccountsIntermediateRoot() - root, _, _ := statedb.Commit(0, nil) - statedb, _ = state.New(root, sdb, nil) + root, _, _ := statedb.Commit(0, false) + statedb, _ = state.New(root, sdb) return statedb } @@ -402,3 +455,16 @@ func calcDifficulty(config *params.ChainConfig, number, currentTime, parentTime } return ethash.CalcDifficulty(config, currentTime, parent) } + +func writeTraceResult(tracer *tracers.Tracer, f io.WriteCloser) error { + defer f.Close() + result, err := tracer.GetResult() + if err != nil || result == nil { + return err + } + err = json.NewEncoder(f).Encode(result) + if err != nil { + return err + } + return nil +} diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index c2eca8cc21..f2606c86d1 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -50,6 +50,10 @@ var ( Name: "trace.returndata", Usage: "Enable return data output in traces", } + TraceEnableCallFramesFlag = &cli.BoolFlag{ + Name: "trace.callframes", + Usage: "Enable call frames output in traces", + } OutputBasedir = &cli.StringFlag{ Name: "output.basedir", Usage: "Specifies where output files are placed. Will be created if it does not exist.", diff --git a/cmd/evm/internal/t8ntool/tracewriter.go b/cmd/evm/internal/t8ntool/tracewriter.go deleted file mode 100644 index 86747c72f9..0000000000 --- a/cmd/evm/internal/t8ntool/tracewriter.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package t8ntool - -import ( - "encoding/json" - "io" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth/tracers" - "github.com/ethereum/go-ethereum/log" -) - -// traceWriter is an vm.EVMLogger which also holds an inner logger/tracer. -// When the TxEnd event happens, the inner tracer result is written to the file, and -// the file is closed. -type traceWriter struct { - inner vm.EVMLogger - f io.WriteCloser -} - -// Compile-time interface check -var _ = vm.EVMLogger((*traceWriter)(nil)) - -func (t *traceWriter) CaptureTxEnd(restGas uint64) { - t.inner.CaptureTxEnd(restGas) - defer t.f.Close() - - if tracer, ok := t.inner.(tracers.Tracer); ok { - result, err := tracer.GetResult() - if err != nil { - log.Warn("Error in tracer", "err", err) - return - } - err = json.NewEncoder(t.f).Encode(result) - if err != nil { - log.Warn("Error writing tracer output", "err", err) - return - } - } -} - -func (t *traceWriter) CaptureTxStart(gasLimit uint64) { t.inner.CaptureTxStart(gasLimit) } -func (t *traceWriter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.inner.CaptureStart(env, from, to, create, input, gas, value) -} - -func (t *traceWriter) CaptureEnd(output []byte, gasUsed uint64, err error) { - t.inner.CaptureEnd(output, gasUsed, err) -} - -func (t *traceWriter) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - t.inner.CaptureEnter(typ, from, to, input, gas, value) -} - -func (t *traceWriter) CaptureExit(output []byte, gasUsed uint64, err error) { - t.inner.CaptureExit(output, gasUsed, err) -} - -func (t *traceWriter) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - t.inner.CaptureState(pc, op, gas, cost, scope, rData, depth, err) -} -func (t *traceWriter) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - t.inner.CaptureFault(pc, op, gas, cost, scope, depth, err) -} - -func (t *traceWriter) CaptureSystemTxEnd(intrinsicGas uint64) { - t.inner.CaptureSystemTxEnd(intrinsicGas) -} diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index 8533b78637..7f66ba4d85 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -86,7 +86,7 @@ func Transaction(ctx *cli.Context) error { if txStr == stdinSelector { decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(inputData); err != nil { - return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) + return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err)) } // Decode the body of already signed transactions body = common.FromHex(inputData.TxRlp) diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 3f3c7fc1f9..d5d0890d98 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -20,14 +20,16 @@ import ( "encoding/json" "errors" "fmt" + "io" "math/big" "os" - "path" + "path/filepath" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -80,7 +82,7 @@ type input struct { } func Transition(ctx *cli.Context) error { - var getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { return nil, nil } + var getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) { return nil, nil, nil } baseDir, err := createBasedir(ctx) if err != nil { @@ -95,28 +97,40 @@ func Transition(ctx *cli.Context) error { EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name), Debug: true, } - getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { - traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String()))) + getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) { + traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String()))) if err != nil { - return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) } - return &traceWriter{logger.NewJSONLogger(logConfig, traceFile), traceFile}, nil + var l *tracing.Hooks + if ctx.Bool(TraceEnableCallFramesFlag.Name) { + l = logger.NewJSONLoggerWithCallFrames(logConfig, traceFile) + } else { + l = logger.NewJSONLogger(logConfig, traceFile) + } + tracer := &tracers.Tracer{ + Hooks: l, + // jsonLogger streams out result to file. + GetResult: func() (json.RawMessage, error) { return nil, nil }, + Stop: func(err error) {}, + } + return tracer, traceFile, nil } } else if ctx.IsSet(TraceTracerFlag.Name) { var config json.RawMessage if ctx.IsSet(TraceTracerConfigFlag.Name) { config = []byte(ctx.String(TraceTracerConfigFlag.Name)) } - getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { - traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String()))) + getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) { + traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String()))) if err != nil { - return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) } tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config) if err != nil { - return nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err)) + return nil, nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err)) } - return &traceWriter{tracer, traceFile}, nil + return tracer, traceFile, nil } } // We need to load three things: alloc, env and transactions. May be either in @@ -135,7 +149,7 @@ func Transition(ctx *cli.Context) error { if allocStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector { decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(inputData); err != nil { - return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) + return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err)) } } if allocStr != stdinSelector { @@ -167,7 +181,7 @@ func Transition(ctx *cli.Context) error { // Set the chain id chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name)) - if txIt, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil { + if txIt, err = loadTransactions(txStr, inputData, chainConfig); err != nil { return err } if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil { @@ -203,7 +217,7 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { return nil } if env.ParentBaseFee == nil || env.Number == 0 { - return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section")) + return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'parentBaseFee' in env section")) } env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{ Number: new(big.Int).SetUint64(env.Number - 1), @@ -282,7 +296,7 @@ func (g Alloc) OnAccount(addr *common.Address, dumpAccount state.DumpAccount) { balance, _ := new(big.Int).SetString(dumpAccount.Balance, 0) var storage map[common.Hash]common.Hash if dumpAccount.Storage != nil { - storage = make(map[common.Hash]common.Hash) + storage = make(map[common.Hash]common.Hash, len(dumpAccount.Storage)) for k, v := range dumpAccount.Storage { storage[k] = common.HexToHash(v) } @@ -302,7 +316,7 @@ func saveFile(baseDir, filename string, data interface{}) error { if err != nil { return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err)) } - location := path.Join(baseDir, filename) + location := filepath.Join(baseDir, filename) if err = os.WriteFile(location, b, 0644); err != nil { return NewError(ErrorIO, fmt.Errorf("failed writing output: %v", err)) } diff --git a/cmd/evm/internal/t8ntool/tx_iterator.go b/cmd/evm/internal/t8ntool/tx_iterator.go index 8f28dc7022..d4ebb4b399 100644 --- a/cmd/evm/internal/t8ntool/tx_iterator.go +++ b/cmd/evm/internal/t8ntool/tx_iterator.go @@ -112,7 +112,7 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran return signedTxs, nil } -func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (txIterator, error) { +func loadTransactions(txStr string, inputData *input, chainConfig *params.ChainConfig) (txIterator, error) { var txsWithKeys []*txWithKey if txStr != stdinSelector { data, err := os.ReadFile(txStr) @@ -127,7 +127,7 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa return newRlpTxIterator(body), nil } if err := json.Unmarshal(data, &txsWithKeys); err != nil { - return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err)) + return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshalling txs-file: %v", err)) } } else { if len(inputData.TxRlp) > 0 { diff --git a/cmd/evm/internal/t8ntool/utils.go b/cmd/evm/internal/t8ntool/utils.go index 8ec38c7618..42f5471e7b 100644 --- a/cmd/evm/internal/t8ntool/utils.go +++ b/cmd/evm/internal/t8ntool/utils.go @@ -33,7 +33,7 @@ func readFile(path, desc string, dest interface{}) error { defer inFile.Close() decoder := json.NewDecoder(inFile) if err := decoder.Decode(dest); err != nil { - return NewError(ErrorJson, fmt.Errorf("failed unmarshaling %s file: %v", desc, err)) + return NewError(ErrorJson, fmt.Errorf("failed unmarshalling %s file: %v", desc, err)) } return nil } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index c3e6a4af91..f9a2a075d0 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -152,6 +152,7 @@ var stateTransitionCommand = &cli.Command{ t8ntool.TraceEnableMemoryFlag, t8ntool.TraceDisableStackFlag, t8ntool.TraceEnableReturnDataFlag, + t8ntool.TraceEnableCallFramesFlag, t8ntool.OutputBasedir, t8ntool.OutputAllocFlag, t8ntool.OutputResultFlag, diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 274b4ab625..c9923dab02 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm/runtime" "github.com/ethereum/go-ethereum/eth/tracers/logger" @@ -116,7 +117,7 @@ func runCmd(ctx *cli.Context) error { } var ( - tracer vm.EVMLogger + tracer *tracing.Hooks debugLogger *logger.StructLogger statedb *state.StateDB chainConfig *params.ChainConfig @@ -130,7 +131,7 @@ func runCmd(ctx *cli.Context) error { tracer = logger.NewJSONLogger(logconfig, os.Stdout) } else if ctx.Bool(DebugFlag.Name) { debugLogger = logger.NewStructLogger(logconfig) - tracer = debugLogger + tracer = debugLogger.Hooks() } else { debugLogger = logger.NewStructLogger(logconfig) } @@ -154,14 +155,13 @@ func runCmd(ctx *cli.Context) error { }) defer triedb.Close() genesis := genesisConfig.MustCommit(db, triedb) - sdb := state.NewDatabaseWithNodeDB(db, triedb) - statedb, _ = state.New(genesis.Root(), sdb, nil) + sdb := state.NewDatabase(triedb, nil) + statedb, _ = state.New(genesis.Root(), sdb) chainConfig = genesisConfig.Config if ctx.String(SenderFlag.Name) != "" { sender = common.HexToAddress(ctx.String(SenderFlag.Name)) } - statedb.CreateAccount(sender) if ctx.String(ReceiverFlag.Name) != "" { receiver = common.HexToAddress(ctx.String(ReceiverFlag.Name)) @@ -221,6 +221,7 @@ func runCmd(ctx *cli.Context) error { Time: genesisConfig.Timestamp, Coinbase: genesisConfig.Coinbase, BlockNumber: new(big.Int).SetUint64(genesisConfig.Number), + BaseFee: genesisConfig.BaseFee, BlobHashes: blobHashes, BlobBaseFee: blobBaseFee, EVMConfig: vm.Config{ @@ -271,9 +272,17 @@ func runCmd(ctx *cli.Context) error { output, leftOverGas, stats, err := timedExec(bench, execFunc) if ctx.Bool(DumpFlag.Name) { - statedb.IntermediateRoot(true) - statedb.Commit(genesisConfig.Number, nil) - fmt.Println(string(statedb.Dump(nil))) + root, _, err := statedb.Commit(genesisConfig.Number, true) + if err != nil { + fmt.Printf("Failed to commit changes %v\n", err) + return err + } + dumpdb, err := state.New(root, sdb) + if err != nil { + fmt.Printf("Failed to open statedb %v\n", err) + return err + } + fmt.Println(string(dumpdb.Dump(nil))) } if ctx.Bool(DebugFlag.Name) { diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 458d809ad8..4514367e8a 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -63,11 +63,11 @@ func stateTestCmd(ctx *cli.Context) error { cfg.Tracer = logger.NewJSONLogger(config, os.Stderr) case ctx.Bool(DebugFlag.Name): - cfg.Tracer = logger.NewStructLogger(config) + cfg.Tracer = logger.NewStructLogger(config).Hooks() } // Load the test content from the input file if len(ctx.Args().First()) != 0 { - return runStateTest(ctx.Args().First(), cfg, ctx.Bool(MachineFlag.Name), ctx.Bool(DumpFlag.Name)) + return runStateTest(ctx.Args().First(), cfg, ctx.Bool(DumpFlag.Name)) } // Read filenames from stdin and execute back-to-back scanner := bufio.NewScanner(os.Stdin) @@ -76,7 +76,7 @@ func stateTestCmd(ctx *cli.Context) error { if len(fname) == 0 { return nil } - if err := runStateTest(fname, cfg, ctx.Bool(MachineFlag.Name), ctx.Bool(DumpFlag.Name)); err != nil { + if err := runStateTest(fname, cfg, ctx.Bool(DumpFlag.Name)); err != nil { return err } } @@ -84,7 +84,7 @@ func stateTestCmd(ctx *cli.Context) error { } // runStateTest loads the state-test given by fname, and executes the test. -func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error { +func runStateTest(fname string, cfg vm.Config, dump bool) error { src, err := os.ReadFile(fname) if err != nil { return err @@ -105,11 +105,9 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error { if tstate.StateDB != nil { root = tstate.StateDB.IntermediateRoot(false) result.Root = &root - if jsonOut { - fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root) - } + fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root) if dump { // Dump any state to aid debugging - cpy, _ := state.New(root, tstate.StateDB.Database(), nil) + cpy, _ := state.New(root, tstate.StateDB.Database()) dump := cpy.RawDump(nil) result.State = &dump } diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 363b48c3ff..3f3da8be63 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -17,9 +17,12 @@ package main import ( + "bufio" "encoding/json" "fmt" + "io" "os" + "path/filepath" "reflect" "strings" "testing" @@ -231,7 +234,7 @@ func TestT8n(t *testing.T) { { // Test post-merge transition base: "./testdata/24", input: t8nInput{ - "alloc.json", "txs.json", "env.json", "Merge", "", + "alloc.json", "txs.json", "env.json", "Paris", "", }, output: t8nOutput{alloc: true, result: true}, expOut: "exp.json", @@ -239,7 +242,7 @@ func TestT8n(t *testing.T) { { // Test post-merge transition where input is missing random base: "./testdata/24", input: t8nInput{ - "alloc.json", "txs.json", "env-missingrandom.json", "Merge", "", + "alloc.json", "txs.json", "env-missingrandom.json", "Paris", "", }, output: t8nOutput{alloc: false, result: false}, expExitCode: 3, @@ -249,7 +252,7 @@ func TestT8n(t *testing.T) { { // Test base fee calculation base: "./testdata/25", input: t8nInput{ - "alloc.json", "txs.json", "env.json", "Merge", "", + "alloc.json", "txs.json", "env.json", "Paris", "", }, output: t8nOutput{alloc: true, result: true}, expOut: "exp.json", @@ -324,6 +327,115 @@ func TestT8n(t *testing.T) { } } +func lineIterator(path string) func() (string, error) { + data, err := os.ReadFile(path) + if err != nil { + return func() (string, error) { return err.Error(), err } + } + scanner := bufio.NewScanner(strings.NewReader(string(data))) + return func() (string, error) { + if scanner.Scan() { + return scanner.Text(), nil + } + if err := scanner.Err(); err != nil { + return "", err + } + return "", io.EOF // scanner gobbles io.EOF, but we want it + } +} + +// TestT8nTracing is a test that checks the tracing-output from t8n. +func TestT8nTracing(t *testing.T) { + t.Parallel() + tt := new(testT8n) + tt.TestCmd = cmdtest.NewTestCmd(t, tt) + for i, tc := range []struct { + base string + input t8nInput + expExitCode int + extraArgs []string + expectedTraces []string + }{ + { + base: "./testdata/31", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Cancun", "", + }, + extraArgs: []string{"--trace"}, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"}, + }, + { + base: "./testdata/31", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Cancun", "", + }, + extraArgs: []string{"--trace.tracer", ` +{ + result: function(){ + return "hello world" + }, + fault: function(){} +}`}, + expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json"}, + }, + { + base: "./testdata/32", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Paris", "", + }, + extraArgs: []string{"--trace", "--trace.callframes"}, + expectedTraces: []string{"trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl"}, + }, + } { + args := []string{"t8n"} + args = append(args, tc.input.get(tc.base)...) + // Place the output somewhere we can find it + outdir := t.TempDir() + args = append(args, "--output.basedir", outdir) + args = append(args, tc.extraArgs...) + + var qArgs []string // quoted args for debugging purposes + for _, arg := range args { + if len(arg) == 0 { + qArgs = append(qArgs, `""`) + } else { + qArgs = append(qArgs, arg) + } + } + tt.Logf("args: %v\n", strings.Join(qArgs, " ")) + tt.Run("evm-test", args...) + t.Log(string(tt.Output())) + + // Compare the expected traces + for _, traceFile := range tc.expectedTraces { + haveFn := lineIterator(filepath.Join(outdir, traceFile)) + wantFn := lineIterator(filepath.Join(tc.base, traceFile)) + + for line := 0; ; line++ { + want, wErr := wantFn() + have, hErr := haveFn() + if want != have { + t.Fatalf("test %d, trace %v, line %d\nwant: %v\nhave: %v\n", + i, traceFile, line, want, have) + } + if wErr != nil && hErr != nil { + break + } + if wErr != nil { + t.Fatal(wErr) + } + if hErr != nil { + t.Fatal(hErr) + } + t.Logf("%v\n", want) + } + } + if have, want := tt.ExitStatus(), tc.expExitCode; have != want { + t.Fatalf("test %d: wrong exit code, have %d, want %d", i, have, want) + } + } +} + type t9nInput struct { inTxs string stFork string diff --git a/cmd/evm/testdata/31/README.md b/cmd/evm/testdata/31/README.md new file mode 100644 index 0000000000..305e4f52da --- /dev/null +++ b/cmd/evm/testdata/31/README.md @@ -0,0 +1 @@ +This test does some EVM execution, and can be used to test the tracers and trace-outputs. diff --git a/cmd/evm/testdata/31/alloc.json b/cmd/evm/testdata/31/alloc.json new file mode 100644 index 0000000000..bad5481c4a --- /dev/null +++ b/cmd/evm/testdata/31/alloc.json @@ -0,0 +1,16 @@ +{ + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x016345785d8a0000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0x1111111111111111111111111111111111111111" : { + "balance" : "0x1", + "code" : "0x604060406040604000", + "nonce" : "0x00", + "storage" : { + } + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/31/env.json b/cmd/evm/testdata/31/env.json new file mode 100644 index 0000000000..09b5f12d88 --- /dev/null +++ b/cmd/evm/testdata/31/env.json @@ -0,0 +1,20 @@ +{ + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentNumber" : "0x01", + "currentTimestamp" : "0x03e8", + "currentGasLimit" : "0x1000000000", + "previousHash" : "0xe4e2a30b340bec696242b67584264f878600dce98354ae0b6328740fd4ff18da", + "currentDataGasUsed" : "0x2000", + "parentTimestamp" : "0x00", + "parentDifficulty" : "0x00", + "parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "parentBeaconBlockRoot" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "currentRandom" : "0x0000000000000000000000000000000000000000000000000000000000020000", + "withdrawals" : [ + ], + "parentBaseFee" : "0x08", + "parentGasUsed" : "0x00", + "parentGasLimit" : "0x1000000000", + "parentExcessBlobGas" : "0x1000", + "parentBlobGasUsed" : "0x2000" +} \ No newline at end of file diff --git a/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json new file mode 100644 index 0000000000..cd4bc1ab64 --- /dev/null +++ b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json @@ -0,0 +1 @@ +"hello world" diff --git a/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl new file mode 100644 index 0000000000..26e5c7ee4e --- /dev/null +++ b/cmd/evm/testdata/31/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl @@ -0,0 +1,6 @@ +{"pc":0,"op":96,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":96,"gas":"0x13495","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":4,"op":96,"gas":"0x13492","gasCost":"0x3","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":96,"gas":"0x1348f","gasCost":"0x3","memSize":0,"stack":["0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":8,"op":0,"gas":"0x1348c","gasCost":"0x0","memSize":0,"stack":["0x40","0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"STOP"} +{"output":"","gasUsed":"0xc"} diff --git a/cmd/evm/testdata/31/txs.json b/cmd/evm/testdata/31/txs.json new file mode 100644 index 0000000000..473c1526f4 --- /dev/null +++ b/cmd/evm/testdata/31/txs.json @@ -0,0 +1,14 @@ +[ + { + "gas": "0x186a0", + "gasPrice": "0x600", + "input": "0x", + "nonce": "0x0", + "to": "0x1111111111111111111111111111111111111111", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + } +] diff --git a/cmd/evm/testdata/32/README.md b/cmd/evm/testdata/32/README.md new file mode 100644 index 0000000000..508ac970dd --- /dev/null +++ b/cmd/evm/testdata/32/README.md @@ -0,0 +1 @@ +This test does some EVM execution, and can be used to test callframes emitted by the tracer when they are enabled. diff --git a/cmd/evm/testdata/32/alloc.json b/cmd/evm/testdata/32/alloc.json new file mode 100644 index 0000000000..0cd4493955 --- /dev/null +++ b/cmd/evm/testdata/32/alloc.json @@ -0,0 +1,30 @@ +{ + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x0de0b6b3a7640000", + "code": "0x600060006000600060007310000000000000000000000000000000000000015af1600155600060006000600060007310000000000000000000000000000000000000025af16002553d600060003e600051600355", + "storage": { + "0x01": "0x0100", + "0x02": "0x0100", + "0x03": "0x0100" + } + }, + "0x1000000000000000000000000000000000000001": { + "nonce": "0x00", + "balance": "0x29a2241af62c0000", + "code": "0x6103e8ff", + "storage": {} + }, + "0x1000000000000000000000000000000000000002": { + "nonce": "0x00", + "balance": "0x4563918244f40000", + "code": "0x600060006000600060647310000000000000000000000000000000000000015af1600f0160005260206000fd", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x6124fee993bc0000", + "code": "0x", + "storage": {} + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/32/env.json b/cmd/evm/testdata/32/env.json new file mode 100644 index 0000000000..4f0833e711 --- /dev/null +++ b/cmd/evm/testdata/32/env.json @@ -0,0 +1,12 @@ +{ + "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentGasLimit": "71794957647893862", + "currentNumber": "1", + "currentTimestamp": "1000", + "currentRandom": "0", + "currentDifficulty": "0", + "blockHashes": {}, + "ommers": [], + "currentBaseFee": "7", + "parentUncleHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/cmd/evm/testdata/32/trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl b/cmd/evm/testdata/32/trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl new file mode 100644 index 0000000000..b6c5237baa --- /dev/null +++ b/cmd/evm/testdata/32/trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl @@ -0,0 +1,61 @@ +{"from":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","to":"0x8a0a19589531694250d570040a0c4b74576919b8","gas":"0x74f18","value":"0x0","type":"CALL"} +{"pc":0,"op":96,"gas":"0x74f18","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":96,"gas":"0x74f15","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":4,"op":96,"gas":"0x74f12","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":96,"gas":"0x74f0f","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":8,"op":96,"gas":"0x74f0c","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":10,"op":115,"gas":"0x74f09","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH20"} +{"pc":31,"op":90,"gas":"0x74f06","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x1000000000000000000000000000000000000001"],"depth":1,"refund":0,"opName":"GAS"} +{"pc":32,"op":241,"gas":"0x74f04","gasCost":"0x731f1","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x1000000000000000000000000000000000000001","0x74f04"],"depth":1,"refund":0,"opName":"CALL"} +{"from":"0x8a0a19589531694250d570040a0c4b74576919b8","to":"0x1000000000000000000000000000000000000001","gas":"0x727c9","value":"0x0","type":"CALL"} +{"pc":0,"op":97,"gas":"0x727c9","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH2"} +{"pc":3,"op":255,"gas":"0x727c6","gasCost":"0x7f58","memSize":0,"stack":["0x3e8"],"depth":2,"refund":0,"opName":"SELFDESTRUCT"} +{"from":"0x1000000000000000000000000000000000000001","to":"0x00000000000000000000000000000000000003e8","gas":"0x0","value":"0x29a2241af62c0000","type":"SELFDESTRUCT"} +{"output":"","gasUsed":"0x0"} +{"output":"","gasUsed":"0x7f5b"} +{"pc":33,"op":96,"gas":"0x6c581","gasCost":"0x3","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":35,"op":85,"gas":"0x6c57e","gasCost":"0x1388","memSize":0,"stack":["0x1","0x1"],"depth":1,"refund":0,"opName":"SSTORE"} +{"pc":36,"op":96,"gas":"0x6b1f6","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":38,"op":96,"gas":"0x6b1f3","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":40,"op":96,"gas":"0x6b1f0","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":42,"op":96,"gas":"0x6b1ed","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":44,"op":96,"gas":"0x6b1ea","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":46,"op":115,"gas":"0x6b1e7","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH20"} +{"pc":67,"op":90,"gas":"0x6b1e4","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x1000000000000000000000000000000000000002"],"depth":1,"refund":0,"opName":"GAS"} +{"pc":68,"op":241,"gas":"0x6b1e2","gasCost":"0x69744","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0x1000000000000000000000000000000000000002","0x6b1e2"],"depth":1,"refund":0,"opName":"CALL"} +{"from":"0x8a0a19589531694250d570040a0c4b74576919b8","to":"0x1000000000000000000000000000000000000002","gas":"0x68d1c","value":"0x0","type":"CALL"} +{"pc":0,"op":96,"gas":"0x68d1c","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":96,"gas":"0x68d19","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":4,"op":96,"gas":"0x68d16","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":96,"gas":"0x68d13","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":8,"op":96,"gas":"0x68d10","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":10,"op":115,"gas":"0x68d0d","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x64"],"depth":2,"refund":0,"opName":"PUSH20"} +{"pc":31,"op":90,"gas":"0x68d0a","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x64","0x1000000000000000000000000000000000000001"],"depth":2,"refund":0,"opName":"GAS"} +{"pc":32,"op":241,"gas":"0x68d08","gasCost":"0x67363","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x64","0x1000000000000000000000000000000000000001","0x68d08"],"depth":2,"refund":0,"opName":"CALL"} +{"from":"0x1000000000000000000000000000000000000002","to":"0x1000000000000000000000000000000000000001","gas":"0x658d3","value":"0x64","type":"CALL"} +{"pc":0,"op":97,"gas":"0x658d3","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH2"} +{"pc":3,"op":255,"gas":"0x658d0","gasCost":"0x1388","memSize":0,"stack":["0x3e8"],"depth":3,"refund":0,"opName":"SELFDESTRUCT"} +{"from":"0x1000000000000000000000000000000000000001","to":"0x00000000000000000000000000000000000003e8","gas":"0x0","value":"0x64","type":"SELFDESTRUCT"} +{"output":"","gasUsed":"0x0"} +{"output":"","gasUsed":"0x138b"} +{"pc":33,"op":96,"gas":"0x65eed","gasCost":"0x3","memSize":0,"stack":["0x1"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":35,"op":1,"gas":"0x65eea","gasCost":"0x3","memSize":0,"stack":["0x1","0xf"],"depth":2,"refund":0,"opName":"ADD"} +{"pc":36,"op":96,"gas":"0x65ee7","gasCost":"0x3","memSize":0,"stack":["0x10"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":38,"op":82,"gas":"0x65ee4","gasCost":"0x6","memSize":0,"stack":["0x10","0x0"],"depth":2,"refund":0,"opName":"MSTORE"} +{"pc":39,"op":96,"gas":"0x65ede","gasCost":"0x3","memSize":32,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":41,"op":96,"gas":"0x65edb","gasCost":"0x3","memSize":32,"stack":["0x20"],"depth":2,"refund":0,"opName":"PUSH1"} +{"pc":43,"op":253,"gas":"0x65ed8","gasCost":"0x0","memSize":32,"stack":["0x20","0x0"],"depth":2,"refund":0,"opName":"REVERT"} +{"pc":43,"op":253,"gas":"0x65ed8","gasCost":"0x0","memSize":32,"stack":[],"depth":2,"refund":0,"opName":"REVERT","error":"execution reverted"} +{"output":"0000000000000000000000000000000000000000000000000000000000000010","gasUsed":"0x2e44","error":"execution reverted"} +{"pc":69,"op":96,"gas":"0x67976","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":71,"op":85,"gas":"0x67973","gasCost":"0x1388","memSize":0,"stack":["0x0","0x2"],"depth":1,"refund":4800,"opName":"SSTORE"} +{"pc":72,"op":61,"gas":"0x665eb","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":4800,"opName":"RETURNDATASIZE"} +{"pc":73,"op":96,"gas":"0x665e9","gasCost":"0x3","memSize":0,"stack":["0x20"],"depth":1,"refund":4800,"opName":"PUSH1"} +{"pc":75,"op":96,"gas":"0x665e6","gasCost":"0x3","memSize":0,"stack":["0x20","0x0"],"depth":1,"refund":4800,"opName":"PUSH1"} +{"pc":77,"op":62,"gas":"0x665e3","gasCost":"0x9","memSize":0,"stack":["0x20","0x0","0x0"],"depth":1,"refund":4800,"opName":"RETURNDATACOPY"} +{"pc":78,"op":96,"gas":"0x665da","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":4800,"opName":"PUSH1"} +{"pc":80,"op":81,"gas":"0x665d7","gasCost":"0x3","memSize":32,"stack":["0x0"],"depth":1,"refund":4800,"opName":"MLOAD"} +{"pc":81,"op":96,"gas":"0x665d4","gasCost":"0x3","memSize":32,"stack":["0x10"],"depth":1,"refund":4800,"opName":"PUSH1"} +{"pc":83,"op":85,"gas":"0x665d1","gasCost":"0x1388","memSize":32,"stack":["0x10","0x3"],"depth":1,"refund":4800,"opName":"SSTORE"} +{"pc":84,"op":0,"gas":"0x65249","gasCost":"0x0","memSize":32,"stack":[],"depth":1,"refund":4800,"opName":"STOP"} +{"output":"","gasUsed":"0xfccf"} diff --git a/cmd/evm/testdata/32/txs.json b/cmd/evm/testdata/32/txs.json new file mode 100644 index 0000000000..0530fd60e6 --- /dev/null +++ b/cmd/evm/testdata/32/txs.json @@ -0,0 +1,17 @@ +[ + { + "type": "0x0", + "chainId": "0x0", + "nonce": "0x0", + "gasPrice": "0xa", + "gas": "0x7a120", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x0", + "input": "0x", + "v": "0x1c", + "r": "0x9a207ad45b7fc2aa5f8e72a30487f2b0bc489778e6d022f19036efdf2a922a17", + "s": "0x640d4da05078b5a4aa561f1b4d58176ea828bfa0f88d27d14459c1d789e1a1eb", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + } +] \ No newline at end of file diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 140d256870..9b1911bc60 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -129,6 +129,8 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.MetricsInfluxDBBucketFlag, utils.MetricsInfluxDBOrganizationFlag, utils.TxLookupLimitFlag, + utils.VMTraceFlag, + utils.VMTraceJsonConfigFlag, utils.TransactionHistoryFlag, utils.StateHistoryFlag, }, utils.DatabaseFlags), @@ -271,37 +273,36 @@ func initGenesis(ctx *cli.Context) error { v := ctx.Uint64(utils.OverrideVerkle.Name) overrides.OverrideVerkle = &v } - for _, name := range []string{"chaindata", "lightchaindata"} { - chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false, false, false, false) - if err != nil { - utils.Fatalf("Failed to open database: %v", err) - } - defer chaindb.Close() + name := "chaindata" + chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false, false, false, false) + if err != nil { + utils.Fatalf("Failed to open database: %v", err) + } + defer chaindb.Close() - // if the trie data dir has been set, new trie db with a new state database - if ctx.IsSet(utils.MultiDataBaseFlag.Name) { - statediskdb, dbErr := stack.OpenDatabaseWithFreezer(name+"/state", 0, 0, "", "", false, false, false, false) - if dbErr != nil { - utils.Fatalf("Failed to open separate trie database: %v", dbErr) - } - chaindb.SetStateStore(statediskdb) - blockdb, err := stack.OpenDatabaseWithFreezer(name+"/block", 0, 0, "", "", false, false, false, false) - if err != nil { - utils.Fatalf("Failed to open separate block database: %v", err) - } - chaindb.SetBlockStore(blockdb) - log.Warn("Multi-database is an experimental feature") + // if the trie data dir has been set, new trie db with a new state database + if ctx.IsSet(utils.MultiDataBaseFlag.Name) { + statediskdb, dbErr := stack.OpenDatabaseWithFreezer(name+"/state", 0, 0, "", "", false, false, false, false) + if dbErr != nil { + utils.Fatalf("Failed to open separate trie database: %v", dbErr) } - - triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) - defer triedb.Close() - - _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + chaindb.SetStateStore(statediskdb) + blockdb, err := stack.OpenDatabaseWithFreezer(name+"/block", 0, 0, "", "", false, false, false, false) if err != nil { - utils.Fatalf("Failed to write genesis block: %v", err) + utils.Fatalf("Failed to open separate block database: %v", err) } - log.Info("Successfully wrote genesis state", "database", name, "hash", hash.String()) + chaindb.SetBlockStore(blockdb) + log.Warn("Multi-database is an experimental feature") } + + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) + defer triedb.Close() + + _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + if err != nil { + utils.Fatalf("Failed to write genesis block: %v", err) + } + log.Info("Successfully wrote genesis state", "database", name, "hash", hash.String()) return nil } @@ -483,36 +484,29 @@ func dumpGenesis(ctx *cli.Context) error { // dump whatever already exists in the datadir stack, _ := makeConfigNode(ctx) - for _, name := range []string{"chaindata", "lightchaindata"} { - db, err := stack.OpenDatabase(name, 0, 0, "", true) - if err != nil { - if !os.IsNotExist(err) { - return err - } - continue - } - // set the separate state & block database - if stack.CheckIfMultiDataBase() && err == nil { - stateDiskDb := utils.MakeStateDataBase(ctx, stack, true, false) - db.SetStateStore(stateDiskDb) - blockDb := utils.MakeBlockDatabase(ctx, stack, true, false) - db.SetBlockStore(blockDb) - } - genesis, err := core.ReadGenesis(db) - if err != nil { - utils.Fatalf("failed to read genesis: %s", err) - } - db.Close() + db, err := stack.OpenDatabase("chaindata", 0, 0, "", true) + if err != nil { + return err + } + defer db.Close() - if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil { - utils.Fatalf("could not encode stored genesis: %s", err) - } - return nil + // set the separate state & block database + if stack.CheckIfMultiDataBase() && err == nil { + stateDiskDb := utils.MakeStateDataBase(ctx, stack, true, false) + db.SetStateStore(stateDiskDb) + blockDb := utils.MakeBlockDatabase(ctx, stack, true, false) + db.SetBlockStore(blockDb) + } + + genesis, err = core.ReadGenesis(db) + if err != nil { + utils.Fatalf("failed to read genesis: %s", err) } - if ctx.IsSet(utils.DataDirFlag.Name) { - utils.Fatalf("no existing datadir at %s", stack.Config().DataDir) + + if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil { + utils.Fatalf("could not encode stored genesis: %s", err) } - utils.Fatalf("no network preset provided, and no genesis exists in the default datadir") + return nil } @@ -574,7 +568,7 @@ func importChain(ctx *cli.Context) error { fmt.Printf("Import done in %v.\n\n", time.Since(start)) // Output pre-compaction stats mostly to see the import trashing - showLeveldbStats(db) + showDBStats(db) // Print the memory statistics used by the importing mem := new(runtime.MemStats) @@ -597,7 +591,7 @@ func importChain(ctx *cli.Context) error { } fmt.Printf("Compaction done in %v.\n\n", time.Since(start)) - showLeveldbStats(db) + showDBStats(db) return importErr } @@ -681,7 +675,7 @@ func importHistory(ctx *cli.Context) error { return fmt.Errorf("no era1 files found in %s", dir) } if len(networks) > 1 { - return fmt.Errorf("multiple networks found, use a network flag to specify desired network") + return errors.New("multiple networks found, use a network flag to specify desired network") } network = networks[0] } @@ -751,21 +745,20 @@ func importPreimages(ctx *cli.Context) error { return nil } -func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, ethdb.Database, common.Hash, error) { +func parseDumpConfig(ctx *cli.Context, stack *node.Node, db ethdb.Database) (*state.DumpConfig, common.Hash, error) { + var header *types.Header if ctx.NArg() > 1 { - return nil, nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg()) + return nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg()) } - db := utils.MakeChainDatabase(ctx, stack, true, false) scheme, err := rawdb.ParseStateScheme(ctx.String(utils.StateSchemeFlag.Name), db) if err != nil { - return nil, nil, common.Hash{}, err + return nil, common.Hash{}, err } if scheme == rawdb.PathScheme { fmt.Println("You are using geth dump in path mode, please use `geth dump-roothash` command to get all available blocks.") } - header := &types.Header{} if ctx.NArg() == 1 { arg := ctx.Args().First() if hashish(arg) { @@ -773,17 +766,17 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, eth if number := rawdb.ReadHeaderNumber(db, hash); number != nil { header = rawdb.ReadHeader(db, hash, *number) } else { - return nil, nil, common.Hash{}, fmt.Errorf("block %x not found", hash) + return nil, common.Hash{}, fmt.Errorf("block %x not found", hash) } } else { number, err := strconv.ParseUint(arg, 10, 64) if err != nil { - return nil, nil, common.Hash{}, err + return nil, common.Hash{}, err } if hash := rawdb.ReadCanonicalHash(db, number); hash != (common.Hash{}) { header = rawdb.ReadHeader(db, hash, number) } else { - return nil, nil, common.Hash{}, fmt.Errorf("header for block %d not found", number) + return nil, common.Hash{}, fmt.Errorf("header for block %d not found", number) } } } else { @@ -794,14 +787,14 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, eth if stateRoot := triedb.Head(); stateRoot != (common.Hash{}) { header.Root = stateRoot } else { - return nil, nil, common.Hash{}, errors.New("no top state root hash in path db") + return nil, common.Hash{}, errors.New("no top state root hash in path db") } } else { header = rawdb.ReadHeadHeader(db) } } if header == nil { - return nil, nil, common.Hash{}, errors.New("no head block found") + return nil, common.Hash{}, errors.New("no head block found") } startArg := common.FromHex(ctx.String(utils.StartKeyFlag.Name)) @@ -814,10 +807,9 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, eth start = crypto.Keccak256Hash(startArg) log.Info("Converting start-address to hash", "address", common.BytesToAddress(startArg), "hash", start.Hex()) default: - return nil, nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg) + return nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg) } - - var conf = &state.DumpConfig{ + conf := &state.DumpConfig{ SkipCode: ctx.Bool(utils.ExcludeCodeFlag.Name), SkipStorage: ctx.Bool(utils.ExcludeStorageFlag.Name), OnlyWithAddresses: !ctx.Bool(utils.IncludeIncompletesFlag.Name), @@ -828,14 +820,17 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, eth log.Info("State dump configured", "block", header.Number, "hash", header.Hash().Hex(), "skipcode", conf.SkipCode, "skipstorage", conf.SkipStorage, "start", hexutil.Encode(conf.Start), "limit", conf.Max, "state scheme", conf.StateScheme) - return conf, db, header.Root, nil + return conf, header.Root, nil } func dump(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - conf, db, root, err := parseDumpConfig(ctx, stack) + db := utils.MakeChainDatabase(ctx, stack, true, false) + defer db.Close() + + conf, root, err := parseDumpConfig(ctx, stack, db) if err != nil { return err } @@ -843,7 +838,7 @@ func dump(ctx *cli.Context) error { triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup defer triedb.Close() - state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil) + state, err := state.New(root, state.NewDatabase(triedb, nil)) if err != nil { return err } diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 7ab27cd3c3..7cc54b662c 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -76,8 +76,8 @@ var tomlSettings = toml.Config{ }, MissingField: func(rt reflect.Type, field string) error { id := fmt.Sprintf("%s.%s", rt.String(), field) - if deprecated(id) { - log.Warn("Config field is deprecated and won't have an effect", "name", id) + if deprecatedConfigFields[id] { + log.Warn(fmt.Sprintf("Config field '%s' is deprecated and won't have any effect.", id)) return nil } var link string @@ -88,6 +88,19 @@ var tomlSettings = toml.Config{ }, } +var deprecatedConfigFields = map[string]bool{ + "ethconfig.Config.EVMInterpreter": true, + "ethconfig.Config.EWASMInterpreter": true, + "ethconfig.Config.TrieCleanCacheJournal": true, + "ethconfig.Config.TrieCleanCacheRejournal": true, + "ethconfig.Config.LightServ": true, + "ethconfig.Config.LightIngress": true, + "ethconfig.Config.LightEgress": true, + "ethconfig.Config.LightPeers": true, + "ethconfig.Config.LightNoPrune": true, + "ethconfig.Config.LightNoSyncServe": true, +} + type ethstatsConfig struct { URL string `toml:",omitempty"` } @@ -302,7 +315,7 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) { cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name) } if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) { - cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name) + log.Warn("Expensive metrics are collected by default, please remove this flag", "flag", utils.MetricsEnabledExpensiveFlag.Name) } if ctx.IsSet(utils.MetricsHTTPFlag.Name) { cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name) @@ -342,21 +355,6 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) { } } -func deprecated(field string) bool { - switch field { - case "ethconfig.Config.EVMInterpreter": - return true - case "ethconfig.Config.EWASMInterpreter": - return true - case "ethconfig.Config.TrieCleanCacheJournal": - return true - case "ethconfig.Config.TrieCleanCacheRejournal": - return true - default: - return false - } -} - func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error { scryptN := keystore.StandardScryptN scryptP := keystore.StandardScryptP diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 59c0e0015e..a365b1018a 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -103,17 +103,17 @@ func TestAttachWelcome(t *testing.T) { "--http", "--http.port", httpPort, "--ws", "--ws.port", wsPort) t.Run("ipc", func(t *testing.T) { - waitForEndpoint(t, ipc, 3*time.Second) + waitForEndpoint(t, ipc, 4*time.Second) testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) }) t.Run("http", func(t *testing.T) { endpoint := "http://127.0.0.1:" + httpPort - waitForEndpoint(t, endpoint, 3*time.Second) + waitForEndpoint(t, endpoint, 4*time.Second) testAttachWelcome(t, geth, endpoint, httpAPIs) }) t.Run("ws", func(t *testing.T) { endpoint := "ws://127.0.0.1:" + wsPort - waitForEndpoint(t, endpoint, 3*time.Second) + waitForEndpoint(t, endpoint, 4*time.Second) testAttachWelcome(t, geth, endpoint, httpAPIs) }) geth.Kill() diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index 282f035bb4..7666b2ce62 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -35,10 +35,12 @@ import ( "github.com/ethereum/go-ethereum/console/prompt" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" @@ -91,6 +93,7 @@ Remove blockchain and state databases`, dbHbss2PbssCmd, dbTrieGetCmd, dbTrieDeleteCmd, + dbInspectHistoryCmd, }, } dbInspectCmd = &cli.Command{ @@ -286,6 +289,28 @@ WARNING: This is a low-level operation which may cause database corruption!`, Description: `This commands will read current offset from kvdb, which is the current offset and starting BlockNumber of ancientStore, will also displays the reserved number of blocks in ancientStore `, } + dbInspectHistoryCmd = &cli.Command{ + Action: inspectHistory, + Name: "inspect-history", + Usage: "Inspect the state history within block range", + ArgsUsage: "
[OPTIONAL ]", + Flags: flags.Merge([]cli.Flag{ + utils.SyncModeFlag, + &cli.Uint64Flag{ + Name: "start", + Usage: "block number of the range start, zero means earliest history", + }, + &cli.Uint64Flag{ + Name: "end", + Usage: "block number of the range end(included), zero means latest history", + }, + &cli.BoolFlag{ + Name: "raw", + Usage: "display the decoded raw state value (otherwise shows rlp-encoded value)", + }, + }, utils.NetworkFlags, utils.DatabaseFlags), + Description: "This command queries the history of the account or storage slot within the specified block range", + } ) func removeDB(ctx *cli.Context) error { @@ -303,11 +328,18 @@ func removeDB(ctx *cli.Context) error { ancientDir = config.Node.ResolvePath(ancientDir) } // Delete state data - statePaths := []string{rootDir, filepath.Join(ancientDir, rawdb.StateFreezerName)} + statePaths := []string{ + rootDir, + filepath.Join(ancientDir, rawdb.MerkleStateFreezerName), + filepath.Join(ancientDir, rawdb.VerkleStateFreezerName), + } confirmAndRemoveDB(statePaths, "state data", ctx, removeStateDataFlag.Name) // Delete ancient chain - chainPaths := []string{filepath.Join(ancientDir, rawdb.ChainFreezerName)} + chainPaths := []string{filepath.Join( + ancientDir, + rawdb.ChainFreezerName, + )} confirmAndRemoveDB(chainPaths, "ancient chain", ctx, removeChainDataFlag.Name) return nil } @@ -572,17 +604,13 @@ func checkStateContent(ctx *cli.Context) error { return nil } -func showLeveldbStats(db ethdb.KeyValueStater) { - if stats, err := db.Stat("leveldb.stats"); err != nil { +func showDBStats(db ethdb.KeyValueStater) { + stats, err := db.Stat() + if err != nil { log.Warn("Failed to read database stats", "error", err) - } else { - fmt.Println(stats) - } - if ioStats, err := db.Stat("leveldb.iostats"); err != nil { - log.Warn("Failed to read database iostats", "error", err) - } else { - fmt.Println(ioStats) + return } + fmt.Println(stats) } func dbStats(ctx *cli.Context) error { @@ -592,12 +620,12 @@ func dbStats(ctx *cli.Context) error { db := utils.MakeChainDatabase(ctx, stack, true, false) defer db.Close() - showLeveldbStats(db) + showDBStats(db) if stack.CheckIfMultiDataBase() { fmt.Println("show stats of state store") - showLeveldbStats(db.StateStore()) + showDBStats(db.StateStore()) fmt.Println("show stats of block store") - showLeveldbStats(db.BlockStore()) + showDBStats(db.BlockStore()) } return nil @@ -611,13 +639,12 @@ func dbCompact(ctx *cli.Context) error { defer db.Close() log.Info("Stats before compaction") - showLeveldbStats(db) - + showDBStats(db) if stack.CheckIfMultiDataBase() { fmt.Println("show stats of state store") - showLeveldbStats(db.StateStore()) + showDBStats(db.StateStore()) fmt.Println("show stats of block store") - showLeveldbStats(db.BlockStore()) + showDBStats(db.BlockStore()) } log.Info("Triggering compaction") @@ -638,12 +665,12 @@ func dbCompact(ctx *cli.Context) error { } log.Info("Stats after compaction") - showLeveldbStats(db) + showDBStats(db) if stack.CheckIfMultiDataBase() { fmt.Println("show stats of state store after compaction") - showLeveldbStats(db.StateStore()) + showDBStats(db.StateStore()) fmt.Println("show stats of block store after compaction") - showLeveldbStats(db.BlockStore()) + showDBStats(db.BlockStore()) } return nil } @@ -717,7 +744,7 @@ func dbTrieGet(ctx *cli.Context) error { log.Info("Could not decode the value", "error", err) return err } - nodeVal, hash := rawdb.ReadAccountTrieNode(db, pathKey) + nodeVal, hash := rawdb.ReadAccountTrieNodeAndHash(db, pathKey) log.Info("TrieGet result ", "PathKey", common.Bytes2Hex(pathKey), "Hash: ", hash, "node: ", trie.NodeString(hash.Bytes(), nodeVal)) } else if ctx.NArg() == 2 { owner, err = hexutil.Decode(ctx.Args().Get(0)) @@ -731,7 +758,7 @@ func dbTrieGet(ctx *cli.Context) error { return err } - nodeVal, hash := rawdb.ReadStorageTrieNode(db, common.BytesToHash(owner), pathKey) + nodeVal, hash := rawdb.ReadStorageTrieNodeAndHash(db, common.BytesToHash(owner), pathKey) log.Info("TrieGet result ", "PathKey: ", common.Bytes2Hex(pathKey), "Owner: ", common.BytesToHash(owner), "Hash: ", hash, "node: ", trie.NodeString(hash.Bytes(), nodeVal)) } } else if scheme == rawdb.HashScheme { @@ -1351,3 +1378,145 @@ func hbss2pbss(ctx *cli.Context) error { } return nil } + +func inspectAccount(db *triedb.Database, start uint64, end uint64, address common.Address, raw bool) error { + stats, err := db.AccountHistory(address, start, end) + if err != nil { + return err + } + fmt.Printf("Account history:\n\taddress: %s\n\tblockrange: [#%d-#%d]\n", address.Hex(), stats.Start, stats.End) + + from := stats.Start + for i := 0; i < len(stats.Blocks); i++ { + var content string + if len(stats.Origins[i]) == 0 { + content = "" + } else { + if !raw { + content = fmt.Sprintf("%#x", stats.Origins[i]) + } else { + account := new(types.SlimAccount) + if err := rlp.DecodeBytes(stats.Origins[i], account); err != nil { + panic(err) + } + code := "" + if len(account.CodeHash) > 0 { + code = fmt.Sprintf("%#x", account.CodeHash) + } + root := "" + if len(account.Root) > 0 { + root = fmt.Sprintf("%#x", account.Root) + } + content = fmt.Sprintf("nonce: %d, balance: %d, codeHash: %s, root: %s", account.Nonce, account.Balance, code, root) + } + } + fmt.Printf("#%d - #%d: %s\n", from, stats.Blocks[i], content) + from = stats.Blocks[i] + } + return nil +} + +func inspectStorage(db *triedb.Database, start uint64, end uint64, address common.Address, slot common.Hash, raw bool) error { + // The hash of storage slot key is utilized in the history + // rather than the raw slot key, make the conversion. + slotHash := crypto.Keccak256Hash(slot.Bytes()) + stats, err := db.StorageHistory(address, slotHash, start, end) + if err != nil { + return err + } + fmt.Printf("Storage history:\n\taddress: %s\n\tslot: %s\n\tblockrange: [#%d-#%d]\n", address.Hex(), slot.Hex(), stats.Start, stats.End) + + from := stats.Start + for i := 0; i < len(stats.Blocks); i++ { + var content string + if len(stats.Origins[i]) == 0 { + content = "" + } else { + if !raw { + content = fmt.Sprintf("%#x", stats.Origins[i]) + } else { + _, data, _, err := rlp.Split(stats.Origins[i]) + if err != nil { + fmt.Printf("Failed to decode storage slot, %v", err) + return err + } + content = fmt.Sprintf("%#x", data) + } + } + fmt.Printf("#%d - #%d: %s\n", from, stats.Blocks[i], content) + from = stats.Blocks[i] + } + return nil +} + +func inspectHistory(ctx *cli.Context) error { + if ctx.NArg() == 0 || ctx.NArg() > 2 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + var ( + address common.Address + slot common.Hash + ) + if err := address.UnmarshalText([]byte(ctx.Args().Get(0))); err != nil { + return err + } + if ctx.NArg() > 1 { + if err := slot.UnmarshalText([]byte(ctx.Args().Get(1))); err != nil { + return err + } + } + // Load the databases. + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true, false) + defer db.Close() + + triedb := utils.MakeTrieDatabase(ctx, stack, db, false, false, false) + defer triedb.Close() + + var ( + err error + start uint64 // the id of first history object to query + end uint64 // the id (included) of last history object to query + ) + // State histories are identified by state ID rather than block number. + // To address this, load the corresponding block header and perform the + // conversion by this function. + blockToID := func(blockNumber uint64) (uint64, error) { + header := rawdb.ReadHeader(db, rawdb.ReadCanonicalHash(db, blockNumber), blockNumber) + if header == nil { + return 0, fmt.Errorf("block #%d is not existent", blockNumber) + } + id := rawdb.ReadStateID(db, header.Root) + if id == nil { + first, last, err := triedb.HistoryRange() + if err == nil { + return 0, fmt.Errorf("history of block #%d is not existent, available history range: [#%d-#%d]", blockNumber, first, last) + } + return 0, fmt.Errorf("history of block #%d is not existent", blockNumber) + } + return *id, nil + } + // Parse the starting block number for inspection. + startNumber := ctx.Uint64("start") + if startNumber != 0 { + start, err = blockToID(startNumber) + if err != nil { + return err + } + } + // Parse the ending block number for inspection. + endBlock := ctx.Uint64("end") + if endBlock != 0 { + end, err = blockToID(endBlock) + if err != nil { + return err + } + } + // Inspect the state history. + if slot == (common.Hash{}) { + return inspectAccount(triedb, start, end, address, ctx.Bool("raw")) + } + return inspectStorage(triedb, start, end, address, slot, ctx.Bool("raw")) +} diff --git a/cmd/geth/exportcmd_test.go b/cmd/geth/exportcmd_test.go index 9570b1ffd2..d08c890734 100644 --- a/cmd/geth/exportcmd_test.go +++ b/cmd/geth/exportcmd_test.go @@ -28,8 +28,7 @@ import ( // TestExport does a basic test of "geth export", exporting the test-genesis. func TestExport(t *testing.T) { t.Parallel() - outfile := fmt.Sprintf("%v/testExport.out", os.TempDir()) - defer os.Remove(outfile) + outfile := fmt.Sprintf("%v/testExport.out", t.TempDir()) geth := runGeth(t, "--datadir", initGeth(t), "export", outfile) geth.WaitExit() if have, want := geth.ExitStatus(), 0; have != want { diff --git a/cmd/geth/logging_test.go b/cmd/geth/logging_test.go index b5ce03f4b8..4293a860ec 100644 --- a/cmd/geth/logging_test.go +++ b/cmd/geth/logging_test.go @@ -73,6 +73,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) { if err != nil { t.Fatal(err) } + defer readFile.Close() wantLines := split(readFile) haveLines := split(bytes.NewBuffer(haveB)) for i, want := range wantLines { @@ -109,6 +110,7 @@ func TestJsonLogging(t *testing.T) { if err != nil { t.Fatal(err) } + defer readFile.Close() wantLines := split(readFile) haveLines := split(bytes.NewBuffer(haveB)) for i, wantLine := range wantLines { @@ -199,9 +201,8 @@ func TestFileOut(t *testing.T) { var ( have, want []byte err error - path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63()) + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) ) - t.Cleanup(func() { os.Remove(path) }) if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil { t.Fatal(err) } @@ -220,9 +221,8 @@ func TestRotatingFileOut(t *testing.T) { var ( have, want []byte err error - path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63()) + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) ) - t.Cleanup(func() { os.Remove(path) }) if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil { t.Fatal(err) } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 899d839596..ff0a46b3dd 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -44,6 +44,7 @@ import ( // Force-load the tracer engines to trigger registration _ "github.com/ethereum/go-ethereum/eth/tracers/js" + _ "github.com/ethereum/go-ethereum/eth/tracers/live" _ "github.com/ethereum/go-ethereum/eth/tracers/native" "github.com/urfave/cli/v2" @@ -146,6 +147,7 @@ var ( utils.MinerEtherbaseFlag, utils.MinerExtraDataFlag, utils.MinerRecommitIntervalFlag, + utils.MinerNewPayloadTimeoutFlag, // deprecated utils.MinerDelayLeftoverFlag, // utils.MinerNewPayloadTimeout, utils.NATFlag, @@ -163,6 +165,8 @@ var ( utils.DeveloperGasLimitFlag, utils.DeveloperPeriodFlag, utils.VMEnableDebugFlag, + utils.VMTraceFlag, + utils.VMTraceJsonConfigFlag, utils.NetworkIdFlag, utils.EthStatsURLFlag, utils.NoCompactionFlag, @@ -183,6 +187,14 @@ var ( utils.LogDebugFlag, utils.LogBacktraceAtFlag, utils.BlobExtraReserveFlag, + utils.BeaconApiFlag, + utils.BeaconApiHeaderFlag, + utils.BeaconThresholdFlag, + utils.BeaconNoFilterFlag, + utils.BeaconConfigFlag, + utils.BeaconGenesisRootFlag, + utils.BeaconGenesisTimeFlag, + utils.BeaconCheckpointFlag, }, utils.NetworkFlags, utils.DatabaseFlags) rpcFlags = []cli.Flag{ @@ -349,8 +361,8 @@ func prepare(ctx *cli.Context) { // If we're a full node on mainnet without --cache specified, bump default cache allowance if !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) { // Make sure we're not on any supported preconfigured testnet either - if !ctx.IsSet(utils.DeveloperFlag.Name) && - !ctx.IsSet(utils.ChapelFlag.Name) { + if !ctx.IsSet(utils.ChapelFlag.Name) && + !ctx.IsSet(utils.DeveloperFlag.Name) { // Nope, we're really on mainnet. Bump that cache up! log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096) ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index 040736a0d7..a2b6ee66b4 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -48,7 +48,7 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" - cli "github.com/urfave/cli/v2" + "github.com/urfave/cli/v2" ) var ( @@ -151,7 +151,7 @@ data, and verifies that all snapshot storage data has a corresponding account. }, { Name: "inspect-account", - Usage: "Check all snapshot layers for the a specific account", + Usage: "Check all snapshot layers for the specific account", ArgsUsage: "
", Action: checkAccount, Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), @@ -870,7 +870,10 @@ func dumpState(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - conf, db, root, err := parseDumpConfig(ctx, stack) + db := utils.MakeChainDatabase(ctx, stack, true, false) + defer db.Close() + + conf, root, err := parseDumpConfig(ctx, stack, db) if err != nil { return err } diff --git a/cmd/geth/testdata/clique.json b/cmd/geth/testdata/clique.json index b54b4a7d3b..36f5c31057 100644 --- a/cmd/geth/testdata/clique.json +++ b/cmd/geth/testdata/clique.json @@ -8,6 +8,7 @@ "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, + "terminalTotalDifficultyPassed": true, "clique": { "period": 5, "epoch": 30000 diff --git a/cmd/geth/testdata/vcheck/vulnerabilities.json b/cmd/geth/testdata/vcheck/vulnerabilities.json index bee0e66dd8..31a34de6be 100644 --- a/cmd/geth/testdata/vcheck/vulnerabilities.json +++ b/cmd/geth/testdata/vcheck/vulnerabilities.json @@ -166,5 +166,37 @@ "severity": "Low", "CVE": "CVE-2022-29177", "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" + }, + { + "name": "DoS via malicious p2p message", + "uid": "GETH-2023-01", + "summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.", + "description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm", + "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" + ], + "introduced": "v1.10.0", + "fixed": "v1.12.1", + "published": "2023-09-06", + "severity": "High", + "CVE": "CVE-2023-40591", + "check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$" + }, + { + "name": "DoS via malicious p2p message", + "uid": "GETH-2024-01", + "summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.", + "description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652", + "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" + ], + "introduced": "v1.10.0", + "fixed": "v1.13.15", + "published": "2024-05-06", + "severity": "High", + "CVE": "CVE-2024-32972", + "check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" } ] diff --git a/cmd/geth/verkle.go b/cmd/geth/verkle.go index e962dcdd84..132f5eb722 100644 --- a/cmd/geth/verkle.go +++ b/cmd/geth/verkle.go @@ -28,8 +28,8 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" - "github.com/gballet/go-verkle" - cli "github.com/urfave/cli/v2" + "github.com/ethereum/go-verkle" + "github.com/urfave/cli/v2" ) var ( diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go deleted file mode 100644 index a0f5f0d288..0000000000 --- a/cmd/p2psim/main.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -// p2psim provides a command-line client for a simulation HTTP API. -// -// Here is an example of creating a 2 node network with the first node -// connected to the second: -// -// $ p2psim node create -// Created node01 -// -// $ p2psim node start node01 -// Started node01 -// -// $ p2psim node create -// Created node02 -// -// $ p2psim node start node02 -// Started node02 -// -// $ p2psim node connect node01 node02 -// Connected node01 to node02 -package main - -import ( - "context" - "encoding/json" - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/internal/flags" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" - "github.com/ethereum/go-ethereum/rpc" - "github.com/urfave/cli/v2" -) - -var client *simulations.Client - -var ( - // global command flags - apiFlag = &cli.StringFlag{ - Name: "api", - Value: "http://localhost:8888", - Usage: "simulation API URL", - EnvVars: []string{"P2PSIM_API_URL"}, - } - - // events subcommand flags - currentFlag = &cli.BoolFlag{ - Name: "current", - Usage: "get existing nodes and conns first", - } - filterFlag = &cli.StringFlag{ - Name: "filter", - Value: "", - Usage: "message filter", - } - - // node create subcommand flags - nameFlag = &cli.StringFlag{ - Name: "name", - Value: "", - Usage: "node name", - } - servicesFlag = &cli.StringFlag{ - Name: "services", - Value: "", - Usage: "node services (comma separated)", - } - keyFlag = &cli.StringFlag{ - Name: "key", - Value: "", - Usage: "node private key (hex encoded)", - } - - // node rpc subcommand flags - subscribeFlag = &cli.BoolFlag{ - Name: "subscribe", - Usage: "method is a subscription", - } -) - -func main() { - app := flags.NewApp("devp2p simulation command-line client") - app.Flags = []cli.Flag{ - apiFlag, - } - app.Before = func(ctx *cli.Context) error { - client = simulations.NewClient(ctx.String(apiFlag.Name)) - return nil - } - app.Commands = []*cli.Command{ - { - Name: "show", - Usage: "show network information", - Action: showNetwork, - }, - { - Name: "events", - Usage: "stream network events", - Action: streamNetwork, - Flags: []cli.Flag{ - currentFlag, - filterFlag, - }, - }, - { - Name: "snapshot", - Usage: "create a network snapshot to stdout", - Action: createSnapshot, - }, - { - Name: "load", - Usage: "load a network snapshot from stdin", - Action: loadSnapshot, - }, - { - Name: "node", - Usage: "manage simulation nodes", - Action: listNodes, - Subcommands: []*cli.Command{ - { - Name: "list", - Usage: "list nodes", - Action: listNodes, - }, - { - Name: "create", - Usage: "create a node", - Action: createNode, - Flags: []cli.Flag{ - nameFlag, - servicesFlag, - keyFlag, - }, - }, - { - Name: "show", - ArgsUsage: "", - Usage: "show node information", - Action: showNode, - }, - { - Name: "start", - ArgsUsage: "", - Usage: "start a node", - Action: startNode, - }, - { - Name: "stop", - ArgsUsage: "", - Usage: "stop a node", - Action: stopNode, - }, - { - Name: "connect", - ArgsUsage: " ", - Usage: "connect a node to a peer node", - Action: connectNode, - }, - { - Name: "disconnect", - ArgsUsage: " ", - Usage: "disconnect a node from a peer node", - Action: disconnectNode, - }, - { - Name: "rpc", - ArgsUsage: " []", - Usage: "call a node RPC method", - Action: rpcNode, - Flags: []cli.Flag{ - subscribeFlag, - }, - }, - }, - }, - } - if err := app.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func showNetwork(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - network, err := client.GetNetwork() - if err != nil { - return err - } - w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0) - defer w.Flush() - fmt.Fprintf(w, "NODES\t%d\n", len(network.Nodes)) - fmt.Fprintf(w, "CONNS\t%d\n", len(network.Conns)) - return nil -} - -func streamNetwork(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - events := make(chan *simulations.Event) - sub, err := client.SubscribeNetwork(events, simulations.SubscribeOpts{ - Current: ctx.Bool(currentFlag.Name), - Filter: ctx.String(filterFlag.Name), - }) - if err != nil { - return err - } - defer sub.Unsubscribe() - enc := json.NewEncoder(ctx.App.Writer) - for { - select { - case event := <-events: - if err := enc.Encode(event); err != nil { - return err - } - case err := <-sub.Err(): - return err - } - } -} - -func createSnapshot(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - snap, err := client.CreateSnapshot() - if err != nil { - return err - } - return json.NewEncoder(os.Stdout).Encode(snap) -} - -func loadSnapshot(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - snap := &simulations.Snapshot{} - if err := json.NewDecoder(os.Stdin).Decode(snap); err != nil { - return err - } - return client.LoadSnapshot(snap) -} - -func listNodes(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodes, err := client.GetNodes() - if err != nil { - return err - } - w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0) - defer w.Flush() - fmt.Fprintf(w, "NAME\tPROTOCOLS\tID\n") - for _, node := range nodes { - fmt.Fprintf(w, "%s\t%s\t%s\n", node.Name, strings.Join(protocolList(node), ","), node.ID) - } - return nil -} - -func protocolList(node *p2p.NodeInfo) []string { - protos := make([]string, 0, len(node.Protocols)) - for name := range node.Protocols { - protos = append(protos, name) - } - return protos -} - -func createNode(ctx *cli.Context) error { - if ctx.NArg() != 0 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - config := adapters.RandomNodeConfig() - config.Name = ctx.String(nameFlag.Name) - if key := ctx.String(keyFlag.Name); key != "" { - privKey, err := crypto.HexToECDSA(key) - if err != nil { - return err - } - config.ID = enode.PubkeyToIDV4(&privKey.PublicKey) - config.PrivateKey = privKey - } - if services := ctx.String(servicesFlag.Name); services != "" { - config.Lifecycles = strings.Split(services, ",") - } - node, err := client.CreateNode(config) - if err != nil { - return err - } - fmt.Fprintln(ctx.App.Writer, "Created", node.Name) - return nil -} - -func showNode(ctx *cli.Context) error { - if ctx.NArg() != 1 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodeName := ctx.Args().First() - node, err := client.GetNode(nodeName) - if err != nil { - return err - } - w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0) - defer w.Flush() - fmt.Fprintf(w, "NAME\t%s\n", node.Name) - fmt.Fprintf(w, "PROTOCOLS\t%s\n", strings.Join(protocolList(node), ",")) - fmt.Fprintf(w, "ID\t%s\n", node.ID) - fmt.Fprintf(w, "ENODE\t%s\n", node.Enode) - for name, proto := range node.Protocols { - fmt.Fprintln(w) - fmt.Fprintf(w, "--- PROTOCOL INFO: %s\n", name) - fmt.Fprintf(w, "%v\n", proto) - fmt.Fprintf(w, "---\n") - } - return nil -} - -func startNode(ctx *cli.Context) error { - if ctx.NArg() != 1 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodeName := ctx.Args().First() - if err := client.StartNode(nodeName); err != nil { - return err - } - fmt.Fprintln(ctx.App.Writer, "Started", nodeName) - return nil -} - -func stopNode(ctx *cli.Context) error { - if ctx.NArg() != 1 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodeName := ctx.Args().First() - if err := client.StopNode(nodeName); err != nil { - return err - } - fmt.Fprintln(ctx.App.Writer, "Stopped", nodeName) - return nil -} - -func connectNode(ctx *cli.Context) error { - if ctx.NArg() != 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - args := ctx.Args() - nodeName := args.Get(0) - peerName := args.Get(1) - if err := client.ConnectNode(nodeName, peerName); err != nil { - return err - } - fmt.Fprintln(ctx.App.Writer, "Connected", nodeName, "to", peerName) - return nil -} - -func disconnectNode(ctx *cli.Context) error { - args := ctx.Args() - if args.Len() != 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodeName := args.Get(0) - peerName := args.Get(1) - if err := client.DisconnectNode(nodeName, peerName); err != nil { - return err - } - fmt.Fprintln(ctx.App.Writer, "Disconnected", nodeName, "from", peerName) - return nil -} - -func rpcNode(ctx *cli.Context) error { - args := ctx.Args() - if args.Len() < 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - nodeName := args.Get(0) - method := args.Get(1) - rpcClient, err := client.RPCClient(context.Background(), nodeName) - if err != nil { - return err - } - if ctx.Bool(subscribeFlag.Name) { - return rpcSubscribe(rpcClient, ctx.App.Writer, method, args.Slice()[3:]...) - } - var result interface{} - params := make([]interface{}, len(args.Slice()[3:])) - for i, v := range args.Slice()[3:] { - params[i] = v - } - if err := rpcClient.Call(&result, method, params...); err != nil { - return err - } - return json.NewEncoder(ctx.App.Writer).Encode(result) -} - -func rpcSubscribe(client *rpc.Client, out io.Writer, method string, args ...string) error { - namespace, method, _ := strings.Cut(method, "_") - ch := make(chan interface{}) - subArgs := make([]interface{}, len(args)+1) - subArgs[0] = method - for i, v := range args { - subArgs[i+1] = v - } - sub, err := client.Subscribe(context.Background(), namespace, ch, subArgs...) - if err != nil { - return err - } - defer sub.Unsubscribe() - enc := json.NewEncoder(out) - for { - select { - case v := <-ch: - if err := enc.Encode(v); err != nil { - return err - } - case err := <-sub.Err(): - return err - } - } -} diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 4b57164665..fc66e11dca 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -27,7 +27,7 @@ import ( "io" "os" "os/signal" - "path" + "path/filepath" "runtime" "strings" "syscall" @@ -245,13 +245,13 @@ func readList(filename string) ([]string, error) { // starting from genesis. func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, network string) error { if chain.CurrentSnapBlock().Number.BitLen() != 0 { - return fmt.Errorf("history import only supported when starting from genesis") + return errors.New("history import only supported when starting from genesis") } entries, err := era.ReadDir(dir, network) if err != nil { return fmt.Errorf("error reading %s: %w", dir, err) } - checksums, err := readList(path.Join(dir, "checksums.txt")) + checksums, err := readList(filepath.Join(dir, "checksums.txt")) if err != nil { return fmt.Errorf("unable to read checksums.txt: %w", err) } @@ -268,7 +268,7 @@ func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, networ ) for i, filename := range entries { err := func() error { - f, err := os.Open(path.Join(dir, filename)) + f, err := os.Open(filepath.Join(dir, filename)) if err != nil { return fmt.Errorf("unable to open era: %w", err) } @@ -425,7 +425,7 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er ) for i := first; i <= last; i += step { err := func() error { - filename := path.Join(dir, era.Filename(network, int(i/step), common.Hash{})) + filename := filepath.Join(dir, era.Filename(network, int(i/step), common.Hash{})) f, err := os.Create(filename) if err != nil { return fmt.Errorf("could not create era file: %w", err) @@ -458,7 +458,7 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er return fmt.Errorf("export failed to finalize %d: %w", step/i, err) } // Set correct filename with root. - os.Rename(filename, path.Join(dir, era.Filename(network, int(i/step), root))) + os.Rename(filename, filepath.Join(dir, era.Filename(network, int(i/step), root))) // Compute checksum of entire Era1. if _, err := f.Seek(0, io.SeekStart); err != nil { @@ -481,7 +481,7 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er } } - os.WriteFile(path.Join(dir, "checksums.txt"), []byte(strings.Join(checksums, "\n")), os.ModePerm) + os.WriteFile(filepath.Join(dir, "checksums.txt"), []byte(strings.Join(checksums, "\n")), os.ModePerm) log.Info("Exported blockchain to", "dir", dir) diff --git a/cmd/utils/export_test.go b/cmd/utils/export_test.go index 84ba8d0c31..b70d2451c6 100644 --- a/cmd/utils/export_test.go +++ b/cmd/utils/export_test.go @@ -29,18 +29,12 @@ import ( // TestExport does basic sanity checks on the export/import functionality func TestExport(t *testing.T) { - f := fmt.Sprintf("%v/tempdump", os.TempDir()) - defer func() { - os.Remove(f) - }() + f := fmt.Sprintf("%v/tempdump", t.TempDir()) testExport(t, f) } func TestExportGzip(t *testing.T) { - f := fmt.Sprintf("%v/tempdump.gz", os.TempDir()) - defer func() { - os.Remove(f) - }() + f := fmt.Sprintf("%v/tempdump.gz", t.TempDir()) testExport(t, f) } @@ -97,22 +91,16 @@ func testExport(t *testing.T, f string) { } } -// testDeletion tests if the deletion markers can be exported/imported correctly +// TestDeletionExport tests if the deletion markers can be exported/imported correctly func TestDeletionExport(t *testing.T) { - f := fmt.Sprintf("%v/tempdump", os.TempDir()) - defer func() { - os.Remove(f) - }() + f := fmt.Sprintf("%v/tempdump", t.TempDir()) testDeletion(t, f) } // TestDeletionExportGzip tests if the deletion markers can be exported/imported // correctly with gz compression. func TestDeletionExportGzip(t *testing.T) { - f := fmt.Sprintf("%v/tempdump.gz", os.TempDir()) - defer func() { - os.Remove(f) - }() + f := fmt.Sprintf("%v/tempdump.gz", t.TempDir()) testDeletion(t, f) } @@ -171,10 +159,7 @@ func testDeletion(t *testing.T, f string) { // TestImportFutureFormat tests that we reject unsupported future versions. func TestImportFutureFormat(t *testing.T) { t.Parallel() - f := fmt.Sprintf("%v/tempdump-future", os.TempDir()) - defer func() { - os.Remove(f) - }() + f := fmt.Sprintf("%v/tempdump-future", t.TempDir()) fh, err := os.OpenFile(f, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) if err != nil { t.Fatal(err) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5c174dbee7..d30d3d851d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -21,6 +21,7 @@ import ( "context" "crypto/ecdsa" "encoding/hex" + "encoding/json" "errors" "fmt" "math" @@ -40,10 +41,12 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/beacon/fakebeacon" + bparams "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -394,6 +397,58 @@ var ( Value: ethconfig.Defaults.TransactionHistory, Category: flags.StateCategory, } + // Beacon client light sync settings + BeaconApiFlag = &cli.StringSliceFlag{ + Name: "beacon.api", + Usage: "Beacon node (CL) light client API URL. This flag can be given multiple times.", + Category: flags.BeaconCategory, + } + BeaconApiHeaderFlag = &cli.StringSliceFlag{ + Name: "beacon.api.header", + Usage: "Pass custom HTTP header fields to the remote beacon node API in \"key:value\" format. This flag can be given multiple times.", + Category: flags.BeaconCategory, + } + BeaconThresholdFlag = &cli.IntFlag{ + Name: "beacon.threshold", + Usage: "Beacon sync committee participation threshold", + Value: bparams.SyncCommitteeSupermajority, + Category: flags.BeaconCategory, + } + BeaconNoFilterFlag = &cli.BoolFlag{ + Name: "beacon.nofilter", + Usage: "Disable future slot signature filter", + Category: flags.BeaconCategory, + } + BeaconConfigFlag = &cli.StringFlag{ + Name: "beacon.config", + Usage: "Beacon chain config YAML file", + Category: flags.BeaconCategory, + } + BeaconGenesisRootFlag = &cli.StringFlag{ + Name: "beacon.genesis.gvroot", + Usage: "Beacon chain genesis validators root", + Category: flags.BeaconCategory, + } + BeaconGenesisTimeFlag = &cli.Uint64Flag{ + Name: "beacon.genesis.time", + Usage: "Beacon chain genesis time", + Category: flags.BeaconCategory, + } + BeaconCheckpointFlag = &cli.StringFlag{ + Name: "beacon.checkpoint", + Usage: "Beacon chain weak subjectivity checkpoint block hash", + Category: flags.BeaconCategory, + } + BlsyncApiFlag = &cli.StringFlag{ + Name: "blsync.engine.api", + Usage: "Target EL engine API URL", + Category: flags.BeaconCategory, + } + BlsyncJWTSecretFlag = &cli.StringFlag{ + Name: "blsync.jwtsecret", + Usage: "Path to a JWT secret to use for target engine API endpoint", + Category: flags.BeaconCategory, + } // Transaction pool settings TxPoolLocalsFlag = &cli.StringFlag{ Name: "txpool.locals", @@ -605,12 +660,6 @@ var ( Value: ethconfig.Defaults.Miner.DelayLeftOver, Category: flags.MinerCategory, } - MinerNewPayloadTimeout = &cli.DurationFlag{ - Name: "miner.newpayload-timeout", - Usage: "Specify the maximum time allowance for creating a new payload", - Value: ethconfig.Defaults.Miner.NewPayloadTimeout, - Category: flags.MinerCategory, - } // Account settings UnlockedAccountFlag = &cli.StringFlag{ @@ -643,7 +692,16 @@ var ( Usage: "Record information useful for VM and contract debugging", Category: flags.VMCategory, } - + VMTraceFlag = &cli.StringFlag{ + Name: "vmtrace", + Usage: "Name of tracer which should record internal VM operations (costly)", + Category: flags.VMCategory, + } + VMTraceJsonConfigFlag = &cli.StringFlag{ + Name: "vmtrace.jsonconfig", + Usage: "Tracer configuration (JSON)", + Category: flags.VMCategory, + } // API options. RPCGlobalGasCapFlag = &cli.Uint64Flag{ Name: "rpc.gascap", @@ -756,7 +814,7 @@ var ( } HTTPPathPrefixFlag = &cli.StringFlag{ Name: "http.rpcprefix", - Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", Value: "", Category: flags.APICategory, } @@ -914,8 +972,9 @@ var ( DiscoveryV5Flag = &cli.BoolFlag{ Name: "discovery.v5", Aliases: []string{"discv5"}, - Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", + Usage: "Enables the V5 discovery mechanism", Category: flags.NetworkingCategory, + Value: true, } NetrestrictFlag = &cli.StringFlag{ Name: "netrestrict", @@ -980,12 +1039,6 @@ var ( Usage: "Enable metrics collection and reporting", Category: flags.MetricsCategory, } - MetricsEnabledExpensiveFlag = &cli.BoolFlag{ - Name: "metrics.expensive", - Usage: "Enable expensive metrics collection and reporting", - Category: flags.MetricsCategory, - } - // MetricsHTTPFlag defines the endpoint for a stand-alone metrics HTTP endpoint. // Since the pprof service enables sensitive/vulnerable behavior, this allows a user // to enable a public-OK metrics endpoint without having to worry about ALSO exposing @@ -1245,7 +1298,7 @@ func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) { // // 1. --bootnodes flag // 2. Config file -// 3. Network preset flags (e.g. --goerli) +// 3. Network preset flags (e.g. --holesky) // 4. default to mainnet nodes func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { urls := params.MainnetBootnodes @@ -1801,6 +1854,18 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) { } } +func setBlobPool(ctx *cli.Context, cfg *blobpool.Config) { + if ctx.IsSet(BlobPoolDataDirFlag.Name) { + cfg.Datadir = ctx.String(BlobPoolDataDirFlag.Name) + } + if ctx.IsSet(BlobPoolDataCapFlag.Name) { + cfg.Datacap = ctx.Uint64(BlobPoolDataCapFlag.Name) + } + if ctx.IsSet(BlobPoolPriceBumpFlag.Name) { + cfg.PriceBump = ctx.Uint64(BlobPoolPriceBumpFlag.Name) + } +} + func setMiner(ctx *cli.Context, cfg *miner.Config) { if ctx.IsSet(MinerExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name)) @@ -1820,8 +1885,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) { if ctx.Bool(VotingEnabledFlag.Name) { cfg.VoteEnable = true } - if ctx.IsSet(MinerNewPayloadTimeout.Name) { - cfg.NewPayloadTimeout = ctx.Duration(MinerNewPayloadTimeout.Name) + if ctx.IsSet(MinerNewPayloadTimeoutFlag.Name) { + log.Warn("The flag --miner.newpayload-timeout is deprecated and will be removed, please use --miner.recommit") + cfg.Recommit = ctx.Duration(MinerNewPayloadTimeoutFlag.Name) } if ctx.Bool(DisableVoteAttestationFlag.Name) { cfg.DisableVoteAttestation = true @@ -1907,6 +1973,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { setEtherbase(ctx, cfg) setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.TxPool) + setBlobPool(ctx, &cfg.BlobPool) setMiner(ctx, &cfg.Miner) setRequiredBlocks(ctx, cfg) setLes(ctx, cfg) @@ -2186,13 +2253,15 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { Fatalf("Could not read genesis from database: %v", err) } if !genesis.Config.TerminalTotalDifficultyPassed { - Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficultyPassed must be true in developer mode") + Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficultyPassed must be true") } if genesis.Config.TerminalTotalDifficulty == nil { - Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be specified.") + Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be specified") + } else if genesis.Config.TerminalTotalDifficulty.Cmp(big.NewInt(0)) != 0 { + Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be 0") } - if genesis.Difficulty.Cmp(genesis.Config.TerminalTotalDifficulty) != 1 { - Fatalf("Bad developer-mode genesis configuration: genesis block difficulty must be > terminalTotalDifficulty") + if genesis.Difficulty.Cmp(big.NewInt(0)) != 0 { + Fatalf("Bad developer-mode genesis configuration: difficulty must be 0") } } chaindb.Close() @@ -2225,6 +2294,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } cfg.BlobExtraReserve = extraReserve } + // VM tracing config. + if ctx.IsSet(VMTraceFlag.Name) { + if name := ctx.String(VMTraceFlag.Name); name != "" { + var config string + if ctx.IsSet(VMTraceJsonConfigFlag.Name) { + config = ctx.String(VMTraceJsonConfigFlag.Name) + } + + cfg.VMTrace = name + cfg.VMTraceJsonConfig = config + } + } } // SetDNSDiscoveryDefaults configures DNS discovery with the given URL if @@ -2244,7 +2325,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) { // RegisterEthService adds an Ethereum client to the stack. // The second return value is the full node instance. -func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend, *eth.Ethereum) { +func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (*eth.EthAPIBackend, *eth.Ethereum) { backend, err := eth.New(stack, cfg) if err != nil { Fatalf("Failed to register the Ethereum service: %v", err) @@ -2254,7 +2335,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend } // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node. -func RegisterEthStatsService(stack *node.Node, backend ethapi.Backend, url string) { +func RegisterEthStatsService(stack *node.Node, backend *eth.EthAPIBackend, url string) { if err := ethstats.New(stack, backend, backend.Engine(), url); err != nil { Fatalf("Failed to register the Ethereum Stats service: %v", err) } @@ -2488,8 +2569,6 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly, disableFree break } chainDb = remotedb.New(client) - case ctx.String(SyncModeFlag.Name) == "light": - chainDb, err = stack.OpenDatabase("lightchaindata", cache, handles, "", readonly) default: chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly, disableFreeze, false, false) // set the separate state database @@ -2649,13 +2728,28 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh if ctx.IsSet(TriesInMemoryFlag.Name) { cache.TriesInMemory = ctx.Uint64(TriesInMemoryFlag.Name) } - vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)} - + vmcfg := vm.Config{ + EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name), + } + if ctx.IsSet(VMTraceFlag.Name) { + if name := ctx.String(VMTraceFlag.Name); name != "" { + var config json.RawMessage + if ctx.IsSet(VMTraceJsonConfigFlag.Name) { + config = json.RawMessage(ctx.String(VMTraceJsonConfigFlag.Name)) + } + t, err := tracers.LiveDirectory.New(name, config) + if err != nil { + Fatalf("Failed to create tracer %q: %v", name, err) + } + vmcfg.Tracer = t + } + } // Disable transaction indexing/unindexing by default. chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil, nil) if err != nil { Fatalf("Can't create BlockChain: %v", err) } + return chain, chainDb } diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index 243abd8311..eb86fa92fc 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -47,6 +47,7 @@ var DeprecatedFlags = []cli.Flag{ LightNoSyncServeFlag, LogBacktraceAtFlag, LogDebugFlag, + MinerNewPayloadTimeoutFlag, } var ( @@ -89,36 +90,32 @@ var ( LightServeFlag = &cli.IntFlag{ Name: "light.serve", Usage: "Maximum percentage of time allowed for serving LES requests (deprecated)", - Value: ethconfig.Defaults.LightServ, - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } LightIngressFlag = &cli.IntFlag{ Name: "light.ingress", Usage: "Incoming bandwidth limit for serving light clients (deprecated)", - Value: ethconfig.Defaults.LightIngress, - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } LightEgressFlag = &cli.IntFlag{ Name: "light.egress", Usage: "Outgoing bandwidth limit for serving light clients (deprecated)", - Value: ethconfig.Defaults.LightEgress, - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } LightMaxPeersFlag = &cli.IntFlag{ Name: "light.maxpeers", Usage: "Maximum number of light clients to serve, or light servers to attach to (deprecated)", - Value: ethconfig.Defaults.LightPeers, - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } LightNoPruneFlag = &cli.BoolFlag{ Name: "light.nopruning", Usage: "Disable ancient light chain data pruning (deprecated)", - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } LightNoSyncServeFlag = &cli.BoolFlag{ Name: "light.nosyncserve", Usage: "Enables serving light clients before syncing (deprecated)", - Category: flags.LightCategory, + Category: flags.DeprecatedCategory, } // Deprecated November 2023 LogBacktraceAtFlag = &cli.StringFlag{ @@ -132,6 +129,18 @@ var ( Usage: "Prepends log messages with call-site location (deprecated)", Category: flags.DeprecatedCategory, } + // Deprecated February 2024 + MinerNewPayloadTimeoutFlag = &cli.DurationFlag{ + Name: "miner.newpayload-timeout", + Usage: "Specify the maximum time allowance for creating a new payload (deprecated)", + Value: ethconfig.Defaults.Miner.Recommit, + Category: flags.DeprecatedCategory, + } + MetricsEnabledExpensiveFlag = &cli.BoolFlag{ + Name: "metrics.expensive", + Usage: "Enable expensive metrics collection and reporting (deprecated)", + Category: flags.DeprecatedCategory, + } ) // showDeprecated displays deprecated flags that will be soon removed from the codebase. diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index 084d137a99..6ec2459d29 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -22,7 +22,7 @@ import ( "io" "math/big" "os" - "path" + "path/filepath" "strings" "testing" @@ -99,7 +99,7 @@ func TestHistoryImportAndExport(t *testing.T) { } // Read checksums. - b, err := os.ReadFile(path.Join(dir, "checksums.txt")) + b, err := os.ReadFile(filepath.Join(dir, "checksums.txt")) if err != nil { t.Fatalf("failed to read checksums: %v", err) } @@ -109,7 +109,7 @@ func TestHistoryImportAndExport(t *testing.T) { entries, _ := era.ReadDir(dir, "mainnet") for i, filename := range entries { func() { - f, err := os.Open(path.Join(dir, filename)) + f, err := os.Open(filepath.Join(dir, filename)) if err != nil { t.Fatalf("error opening era file: %v", err) } @@ -162,8 +162,7 @@ func TestHistoryImportAndExport(t *testing.T) { } // Now import Era. - freezer := t.TempDir() - db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false, false) + db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "",, "", false, false, false, false, false) if err != nil { panic(err) } diff --git a/common/bitutil/bitutil.go b/common/bitutil/bitutil.go index cd3e72169f..a18a6d18ee 100644 --- a/common/bitutil/bitutil.go +++ b/common/bitutil/bitutil.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Adapted from: https://golang.org/src/crypto/cipher/xor.go +// Adapted from: https://go.dev/src/crypto/subtle/xor_generic.go // Package bitutil implements fast bitwise operations. package bitutil diff --git a/common/bitutil/bitutil_test.go b/common/bitutil/bitutil_test.go index 307bf731f7..12f3fe24a6 100644 --- a/common/bitutil/bitutil_test.go +++ b/common/bitutil/bitutil_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Adapted from: https://golang.org/src/crypto/cipher/xor_test.go +// Adapted from: https://go.dev/src/crypto/subtle/xor_test.go package bitutil diff --git a/common/lru/basiclru.go b/common/lru/basiclru.go index a429157fe5..7386c77840 100644 --- a/common/lru/basiclru.go +++ b/common/lru/basiclru.go @@ -115,9 +115,7 @@ func (c *BasicLRU[K, V]) Peek(key K) (value V, ok bool) { // Purge empties the cache. func (c *BasicLRU[K, V]) Purge() { c.list.init() - for k := range c.items { - delete(c.items, k) - } + clear(c.items) } // Remove drops an item from the cache. Returns true if the key was present in cache. @@ -174,7 +172,7 @@ func (l *list[T]) init() { l.root.prev = &l.root } -// push adds an element to the front of the list. +// pushElem adds an element to the front of the list. func (l *list[T]) pushElem(e *listElem[T]) { e.prev = &l.root e.next = l.root.next diff --git a/common/math/big.go b/common/math/big.go index 013c0ba4b6..d9748d01a3 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -54,7 +54,7 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 { // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error { - if len(input) > 0 && input[0] == '"' { + if len(input) > 1 && input[0] == '"' { input = input[1 : len(input)-1] } return i.UnmarshalText(input) @@ -224,7 +224,7 @@ func ReadBits(bigint *big.Int, buf []byte) { } } -// U256 encodes as a 256 bit two's complement number. This operation is destructive. +// U256 encodes x as a 256 bit two's complement number. This operation is destructive. func U256(x *big.Int) *big.Int { return x.And(x, tt256m1) } @@ -255,14 +255,15 @@ func S256(x *big.Int) *big.Int { // // Courtesy @karalabe and @chfast func Exp(base, exponent *big.Int) *big.Int { + copyBase := new(big.Int).Set(base) result := big.NewInt(1) for _, word := range exponent.Bits() { for i := 0; i < wordBits; i++ { if word&1 == 1 { - U256(result.Mul(result, base)) + U256(result.Mul(result, copyBase)) } - U256(base.Mul(base, base)) + U256(copyBase.Mul(copyBase, copyBase)) word >>= 1 } } diff --git a/common/math/big_test.go b/common/math/big_test.go index 803b5e1cc6..ee8f09e7b4 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -180,9 +180,9 @@ func BenchmarkByteAtOld(b *testing.B) { func TestReadBits(t *testing.T) { check := func(input string) { want, _ := hex.DecodeString(input) - int, _ := new(big.Int).SetString(input, 16) + n, _ := new(big.Int).SetString(input, 16) buf := make([]byte, len(want)) - ReadBits(int, buf) + ReadBits(n, buf) if !bytes.Equal(buf, want) { t.Errorf("have: %x\nwant: %x", buf, want) } diff --git a/common/math/integer.go b/common/math/integer.go index db17426ffd..5defa75f28 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -46,7 +46,7 @@ type HexOrDecimal64 uint64 // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error { - if len(input) > 0 && input[0] == '"' { + if len(input) > 1 && input[0] == '"' { input = input[1 : len(input)-1] } return i.UnmarshalText(input) @@ -54,11 +54,11 @@ func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler. func (i *HexOrDecimal64) UnmarshalText(input []byte) error { - int, ok := ParseUint64(string(input)) + n, ok := ParseUint64(string(input)) if !ok { return fmt.Errorf("invalid hex or decimal integer %q", input) } - *i = HexOrDecimal64(int) + *i = HexOrDecimal64(n) return nil } diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 59bda72fa7..ebe53d5e6b 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -17,11 +17,11 @@ package prque import ( + "cmp" "container/heap" "time" "github.com/ethereum/go-ethereum/common/mclock" - "golang.org/x/exp/constraints" ) // LazyQueue is a priority queue data structure where priorities can change over @@ -33,7 +33,7 @@ import ( // // If the upper estimate is exceeded then Update should be called for that item. // A global Refresh function should also be called periodically. -type LazyQueue[P constraints.Ordered, V any] struct { +type LazyQueue[P cmp.Ordered, V any] struct { clock mclock.Clock // Items are stored in one of two internal queues ordered by estimated max // priority until the next and the next-after-next refresh. Update and Refresh @@ -50,12 +50,12 @@ type LazyQueue[P constraints.Ordered, V any] struct { } type ( - PriorityCallback[P constraints.Ordered, V any] func(data V) P // actual priority callback - MaxPriorityCallback[P constraints.Ordered, V any] func(data V, until mclock.AbsTime) P // estimated maximum priority callback + PriorityCallback[P cmp.Ordered, V any] func(data V) P // actual priority callback + MaxPriorityCallback[P cmp.Ordered, V any] func(data V, until mclock.AbsTime) P // estimated maximum priority callback ) // NewLazyQueue creates a new lazy queue -func NewLazyQueue[P constraints.Ordered, V any](setIndex SetIndexCallback[V], priority PriorityCallback[P, V], maxPriority MaxPriorityCallback[P, V], clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue[P, V] { +func NewLazyQueue[P cmp.Ordered, V any](setIndex SetIndexCallback[V], priority PriorityCallback[P, V], maxPriority MaxPriorityCallback[P, V], clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue[P, V] { q := &LazyQueue[P, V]{ popQueue: newSstack[P, V](nil), setIndex: setIndex, diff --git a/common/prque/prque.go b/common/prque/prque.go index 0e8c9f897f..cb0d9f3580 100755 --- a/common/prque/prque.go +++ b/common/prque/prque.go @@ -18,22 +18,21 @@ package prque import ( + "cmp" "container/heap" - - "golang.org/x/exp/constraints" ) -// Priority queue data structure. -type Prque[P constraints.Ordered, V any] struct { +// Prque is a priority queue data structure. +type Prque[P cmp.Ordered, V any] struct { cont *sstack[P, V] } // New creates a new priority queue. -func New[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { +func New[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { return &Prque[P, V]{newSstack[P, V](setIndex)} } -// Pushes a value with a given priority into the queue, expanding if necessary. +// Push a value with a given priority into the queue, expanding if necessary. func (p *Prque[P, V]) Push(data V, priority P) { heap.Push(p.cont, &item[P, V]{data, priority}) } @@ -44,14 +43,14 @@ func (p *Prque[P, V]) Peek() (V, P) { return item.value, item.priority } -// Pops the value with the greatest priority off the stack and returns it. +// Pop the value with the greatest priority off the stack and returns it. // Currently no shrinking is done. func (p *Prque[P, V]) Pop() (V, P) { item := heap.Pop(p.cont).(*item[P, V]) return item.value, item.priority } -// Pops only the item from the queue, dropping the associated priority value. +// PopItem pops only the item from the queue, dropping the associated priority value. func (p *Prque[P, V]) PopItem() V { return heap.Pop(p.cont).(*item[P, V]).value } @@ -61,17 +60,17 @@ func (p *Prque[P, V]) Remove(i int) V { return heap.Remove(p.cont, i).(*item[P, V]).value } -// Checks whether the priority queue is empty. +// Empty checks whether the priority queue is empty. func (p *Prque[P, V]) Empty() bool { return p.cont.Len() == 0 } -// Returns the number of element in the priority queue. +// Size returns the number of element in the priority queue. func (p *Prque[P, V]) Size() int { return p.cont.Len() } -// Clears the contents of the priority queue. +// Reset clears the contents of the priority queue. func (p *Prque[P, V]) Reset() { *p = *New[P, V](p.cont.setIndex) } diff --git a/common/prque/sstack.go b/common/prque/sstack.go index 5dcd1d9dd0..6865a51e23 100755 --- a/common/prque/sstack.go +++ b/common/prque/sstack.go @@ -10,13 +10,13 @@ package prque -import "golang.org/x/exp/constraints" +import "cmp" // The size of a block of data const blockSize = 4096 // A prioritized item in the sorted stack. -type item[P constraints.Ordered, V any] struct { +type item[P cmp.Ordered, V any] struct { value V priority P } @@ -29,7 +29,7 @@ type SetIndexCallback[V any] func(data V, index int) // Internal sortable stack data structure. Implements the Push and Pop ops for // the stack (heap) functionality and the Len, Less and Swap methods for the // sortability requirements of the heaps. -type sstack[P constraints.Ordered, V any] struct { +type sstack[P cmp.Ordered, V any] struct { setIndex SetIndexCallback[V] size int capacity int @@ -40,7 +40,7 @@ type sstack[P constraints.Ordered, V any] struct { } // Creates a new, empty stack. -func newSstack[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] { +func newSstack[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] { result := new(sstack[P, V]) result.setIndex = setIndex result.active = make([]*item[P, V], blockSize) @@ -49,7 +49,7 @@ func newSstack[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *ssta return result } -// Pushes a value onto the stack, expanding it if necessary. Required by +// Push a value onto the stack, expanding it if necessary. Required by // heap.Interface. func (s *sstack[P, V]) Push(data any) { if s.size == s.capacity { @@ -69,7 +69,7 @@ func (s *sstack[P, V]) Push(data any) { s.size++ } -// Pops a value off the stack and returns it. Currently no shrinking is done. +// Pop a value off the stack and returns it. Currently no shrinking is done. // Required by heap.Interface. func (s *sstack[P, V]) Pop() (res any) { s.size-- @@ -85,18 +85,18 @@ func (s *sstack[P, V]) Pop() (res any) { return } -// Returns the length of the stack. Required by sort.Interface. +// Len returns the length of the stack. Required by sort.Interface. func (s *sstack[P, V]) Len() int { return s.size } -// Compares the priority of two elements of the stack (higher is first). +// Less compares the priority of two elements of the stack (higher is first). // Required by sort.Interface. func (s *sstack[P, V]) Less(i, j int) bool { return s.blocks[i/blockSize][i%blockSize].priority > s.blocks[j/blockSize][j%blockSize].priority } -// Swaps two elements in the stack. Required by sort.Interface. +// Swap two elements in the stack. Required by sort.Interface. func (s *sstack[P, V]) Swap(i, j int) { ib, io, jb, jo := i/blockSize, i%blockSize, j/blockSize, j%blockSize a, b := s.blocks[jb][jo], s.blocks[ib][io] @@ -107,7 +107,7 @@ func (s *sstack[P, V]) Swap(i, j int) { s.blocks[ib][io], s.blocks[jb][jo] = a, b } -// Resets the stack, effectively clearing its contents. +// Reset the stack, effectively clearing its contents. func (s *sstack[P, V]) Reset() { *s = *newSstack[P, V](s.setIndex) } diff --git a/common/types.go b/common/types.go index aadca87f82..fdb25f1b34 100644 --- a/common/types.go +++ b/common/types.go @@ -468,10 +468,21 @@ func (d *Decimal) UnmarshalJSON(input []byte) error { if !isString(input) { return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))} } - if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil { + if i, err := strconv.ParseUint(string(input[1:len(input)-1]), 10, 64); err == nil { *d = Decimal(i) return nil } else { return err } } + +type PrettyBytes []byte + +// TerminalString implements log.TerminalStringer, formatting a string for console +// output during logging. +func (b PrettyBytes) TerminalString() string { + if len(b) < 7 { + return fmt.Sprintf("%x", b) + } + return fmt.Sprintf("%#x...%x (%dB)", b[:3], b[len(b)-3:], len(b)) +} diff --git a/common/types_test.go b/common/types_test.go index cec689ea39..11247b117b 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -21,6 +21,7 @@ import ( "database/sql/driver" "encoding/json" "fmt" + "math" "math/big" "reflect" "strings" @@ -595,3 +596,29 @@ func BenchmarkPrettyDuration(b *testing.B) { } b.Logf("Post %s", a) } + +func TestDecimalUnmarshalJSON(t *testing.T) { + // These should error + for _, tc := range []string{``, `"`, `""`, `"-1"`} { + if err := new(Decimal).UnmarshalJSON([]byte(tc)); err == nil { + t.Errorf("input %s should cause error", tc) + } + } + // These should succeed + for _, tc := range []struct { + input string + want uint64 + }{ + {`"0"`, 0}, + {`"9223372036854775807"`, math.MaxInt64}, + {`"18446744073709551615"`, math.MaxUint64}, + } { + have := new(Decimal) + if err := have.UnmarshalJSON([]byte(tc.input)); err != nil { + t.Errorf("input %q triggered error: %v", tc.input, err) + } + if uint64(*have) != tc.want { + t.Errorf("input %q, have %d want %d", tc.input, *have, tc.want) + } + } +} diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 9e1c39b99a..7e5155e1e5 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" @@ -229,7 +230,7 @@ func (beacon *Beacon) VerifyUncles(chain consensus.ChainReader, block *types.Blo // (c) the extradata is limited to 32 bytes func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error { // Ensure that the header's extra-data section is of a reasonable size - if len(header.Extra) > 32 { + if len(header.Extra) > int(params.MaximumExtraDataSize) { return fmt.Errorf("extra-data longer than 32 bytes (%d)", len(header.Extra)) } // Verify the seal parts. Ensure the nonce and uncle hash are the expected value. @@ -369,7 +370,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. // Convert amount from gwei to wei. amount := new(uint256.Int).SetUint64(w.Amount) amount = amount.Mul(amount, uint256.NewInt(params.GWei)) - state.AddBalance(w.Address, amount) + state.AddBalance(w.Address, amount, tracing.BalanceIncreaseWithdrawal) } // No block reward which is issued by consensus layer instead. return nil @@ -380,7 +381,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, []*types.Receipt, error) { // FinalizeAndAssemble is different with Prepare, it can be used in both block generation. if !beacon.IsPoSHeader(header) { - return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil) + return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, withdrawals) } shanghai := chain.Config().IsShanghai(header.Number, header.Time) if shanghai { @@ -399,7 +400,39 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea // Assign the final state root to header. header.Root = state.IntermediateRoot(true) - return types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil)), receipts, nil + // Assemble the final block. + block := types.NewBlock(header, &types.Body{Transactions: txs, Uncles: uncles, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil)) + + // Create the block witness and attach to block. + // This step needs to happen as late as possible to catch all access events. + if chain.Config().IsVerkle(header.Number, header.Time) { + keys := state.AccessEvents().Keys() + + // Open the pre-tree to prove the pre-state against + parent := chain.GetHeaderByNumber(header.Number.Uint64() - 1) + if parent == nil { + return nil, nil, fmt.Errorf("nil parent header for block %d", header.Number) + } + + preTrie, err := state.Database().OpenTrie(parent.Root) + if err != nil { + return nil, nil, fmt.Errorf("error opening pre-state tree root: %w", err) + } + + vktPreTrie, okpre := preTrie.(*trie.VerkleTrie) + vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie) + if okpre && okpost { + if len(keys) > 0 { + verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys, vktPreTrie.FlatdbNodeResolver) + if err != nil { + return nil, nil, fmt.Errorf("error generating verkle proof for block %d: %w", header.Number, err) + } + block = block.WithWitness(&types.ExecutionWitness{StateDiff: stateDiff, VerkleProof: verkleProof}) + } + } + } + + return block, receipts, nil } // Seal generates a new sealing request for the given input block and pushes diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index ddacbc2e6e..a8174e9c5d 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -31,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" - lru "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" @@ -604,8 +604,8 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * // Assign the final state root to header. header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) - // Assemble and return the final block for sealing - return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)), receipts, nil + // Assemble and return the final block for sealing. + return types.NewBlock(header, &types.Body{Transactions: txs, Uncles: uncles}, receipts, trie.NewStackTrie(nil)), receipts, nil } // Authorize injects a private key into the consensus engine to mint new blocks diff --git a/consensus/clique/clique_test.go b/consensus/clique/clique_test.go index f479ac6169..804845e421 100644 --- a/consensus/clique/clique_test.go +++ b/consensus/clique/clique_test.go @@ -31,11 +31,11 @@ import ( ) // This test case is a repro of an annoying bug that took us forever to catch. -// In Clique PoA networks (Görli, etc), consecutive blocks might have -// the same state root (no block subsidy, empty block). If a node crashes, the -// chain ends up losing the recent state and needs to regenerate it from blocks -// already in the database. The bug was that processing the block *prior* to an -// empty one **also completes** the empty one, ending up in a known-block error. +// In Clique PoA networks, consecutive blocks might have the same state root (no +// block subsidy, empty block). If a node crashes, the chain ends up losing the +// recent state and needs to regenerate it from blocks already in the database. +// The bug was that processing the block *prior* to an empty one **also +// completes** the empty one, ending up in a known-block error. func TestReimportMirroredState(t *testing.T) { // Initialize a Clique chain with a single signer var ( diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index a97115121b..d0b15e9489 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -19,6 +19,8 @@ package clique import ( "bytes" "encoding/json" + "maps" + "slices" "time" "github.com/ethereum/go-ethereum/common" @@ -28,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "golang.org/x/exp/slices" ) // Vote represents a single vote that an authorized signer made to modify the @@ -108,28 +109,16 @@ func (s *Snapshot) store(db ethdb.Database) error { // copy creates a deep copy of the snapshot, though not the individual votes. func (s *Snapshot) copy() *Snapshot { - cpy := &Snapshot{ + return &Snapshot{ config: s.config, sigcache: s.sigcache, Number: s.Number, Hash: s.Hash, - Signers: make(map[common.Address]struct{}), - Recents: make(map[uint64]common.Address), - Votes: make([]*Vote, len(s.Votes)), - Tally: make(map[common.Address]Tally), - } - for signer := range s.Signers { - cpy.Signers[signer] = struct{}{} + Signers: maps.Clone(s.Signers), + Recents: maps.Clone(s.Recents), + Votes: slices.Clone(s.Votes), + Tally: maps.Clone(s.Tally), } - for block, signer := range s.Recents { - cpy.Recents[block] = signer - } - for address, tally := range s.Tally { - cpy.Tally[address] = tally - } - copy(cpy.Votes, s.Votes) - - return cpy } // validVote returns whether it makes sense to cast the specified vote in the diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go index 3d72ebe70c..05ec22137a 100644 --- a/consensus/clique/snapshot_test.go +++ b/consensus/clique/snapshot_test.go @@ -21,6 +21,7 @@ import ( "crypto/ecdsa" "fmt" "math/big" + "slices" "testing" "github.com/ethereum/go-ethereum/common" @@ -30,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "golang.org/x/exp/slices" ) // testerAccountPool is a pool to maintain currently active tester accounts, diff --git a/consensus/consensus.go b/consensus/consensus.go index eef9d50d42..1cf2da8abc 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -147,14 +147,6 @@ type Engine interface { Close() error } -// PoW is a consensus engine based on proof-of-work. -type PoW interface { - Engine - - // Hashrate returns the current mining hashrate of a PoW consensus engine. - Hashrate() float64 -} - type PoSA interface { Engine diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index db730fab29..0f3c537fb2 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" @@ -527,7 +528,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) // Header seems complete, assemble into a block and return - return types.NewBlock(header, txs, uncles, receipts, trie.NewStackTrie(nil)), receipts, nil + return types.NewBlock(header, &types.Body{Transactions: txs, Uncles: uncles}, receipts, trie.NewStackTrie(nil)), receipts, nil } func (ethash *Ethash) Delay(_ consensus.ChainReader, _ *types.Header, _ *time.Duration) *time.Duration { @@ -573,16 +574,10 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { return hash } -// Some weird constants to avoid constant memory allocs for them. -var ( - u256_8 = uint256.NewInt(8) - u256_32 = uint256.NewInt(32) -) - -// AccumulateRewards credits the coinbase of the given block with the mining +// accumulateRewards credits the coinbase of the given block with the mining // reward. The total reward consists of the static block reward and rewards for // included uncles. The coinbase of each uncle block is also rewarded. -func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { +func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, header *types.Header, uncles []*types.Header) { // Select the correct block reward based on chain progression blockReward := FrontierBlockReward if config.IsByzantium(header.Number) { @@ -600,11 +595,11 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header r.AddUint64(uNum, 8) r.Sub(r, hNum) r.Mul(r, blockReward) - r.Div(r, u256_8) - state.AddBalance(uncle.Coinbase, r) + r.Rsh(r, 3) + stateDB.AddBalance(uncle.Coinbase, r, tracing.BalanceIncreaseRewardMineUncle) - r.Div(blockReward, u256_32) + r.Rsh(blockReward, 5) reward.Add(reward, r) } - state.AddBalance(header.Coinbase, reward) + stateDB.AddBalance(header.Coinbase, reward, tracing.BalanceIncreaseRewardMineBlock) } diff --git a/consensus/merger.go b/consensus/merger.go deleted file mode 100644 index ffbcbf2b85..0000000000 --- a/consensus/merger.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package consensus - -import ( - "fmt" - "sync" - - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -// transitionStatus describes the status of eth1/2 transition. This switch -// between modes is a one-way action which is triggered by corresponding -// consensus-layer message. -type transitionStatus struct { - LeftPoW bool // The flag is set when the first NewHead message received - EnteredPoS bool // The flag is set when the first FinalisedBlock message received -} - -// Merger is an internal help structure used to track the eth1/2 transition status. -// It's a common structure can be used in both full node and light client. -type Merger struct { - db ethdb.KeyValueStore - status transitionStatus - mu sync.RWMutex -} - -// NewMerger creates a new Merger which stores its transition status in the provided db. -func NewMerger(db ethdb.KeyValueStore) *Merger { - var status transitionStatus - blob := rawdb.ReadTransitionStatus(db) - if len(blob) != 0 { - if err := rlp.DecodeBytes(blob, &status); err != nil { - log.Crit("Failed to decode the transition status", "err", err) - } - } - return &Merger{ - db: db, - status: status, - } -} - -// ReachTTD is called whenever the first NewHead message received -// from the consensus-layer. -func (m *Merger) ReachTTD() { - m.mu.Lock() - defer m.mu.Unlock() - - if m.status.LeftPoW { - return - } - m.status = transitionStatus{LeftPoW: true} - blob, err := rlp.EncodeToBytes(m.status) - if err != nil { - panic(fmt.Sprintf("Failed to encode the transition status: %v", err)) - } - rawdb.WriteTransitionStatus(m.db, blob) - log.Info("Left PoW stage") -} - -// FinalizePoS is called whenever the first FinalisedBlock message received -// from the consensus-layer. -func (m *Merger) FinalizePoS() { - m.mu.Lock() - defer m.mu.Unlock() - - if m.status.EnteredPoS { - return - } - m.status = transitionStatus{LeftPoW: true, EnteredPoS: true} - blob, err := rlp.EncodeToBytes(m.status) - if err != nil { - panic(fmt.Sprintf("Failed to encode the transition status: %v", err)) - } - rawdb.WriteTransitionStatus(m.db, blob) - log.Info("Entered PoS stage") -} - -// TDDReached reports whether the chain has left the PoW stage. -func (m *Merger) TDDReached() bool { - m.mu.RLock() - defer m.mu.RUnlock() - - return m.status.LeftPoW -} - -// PoSFinalized reports whether the chain has entered the PoS stage. -func (m *Merger) PoSFinalized() bool { - m.mu.RLock() - defer m.mu.RUnlock() - - return m.status.EnteredPoS -} diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go index e21a44f63d..45669d0bce 100644 --- a/consensus/misc/dao.go +++ b/consensus/misc/dao.go @@ -22,6 +22,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" @@ -81,7 +82,7 @@ func ApplyDAOHardFork(statedb *state.StateDB) { // Move every DAO account and extra-balance account funds into the refund contract for _, addr := range params.DAODrainList() { - statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr)) - statedb.SetBalance(addr, new(uint256.Int)) + statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), tracing.BalanceIncreaseDaoContract) + statedb.SetBalance(addr, new(uint256.Int), tracing.BalanceDecreaseDaoAccount) } } diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index a06067b25b..9da22e5f78 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/systemcontracts" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -1441,7 +1442,7 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * wg.Done() }() go func() { - blk = types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)) + blk = types.NewBlock(header, &types.Body{Transactions: txs}, receipts, trie.NewStackTrie(nil)) wg.Done() }() wg.Wait() @@ -1814,8 +1815,8 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he rewards := new(uint256.Int) rewards = rewards.Rsh(balance, systemRewardPercent) if rewards.Cmp(common.U2560) > 0 { - state.SetBalance(consensus.SystemAddress, balance.Sub(balance, rewards)) - state.AddBalance(coinbase, rewards) + state.SetBalance(consensus.SystemAddress, balance.Sub(balance, rewards), tracing.BalanceChangeUnspecified) + state.AddBalance(coinbase, rewards, tracing.BalanceChangeUnspecified) err := p.distributeToSystem(rewards.ToBig(), state, header, chain, txs, receipts, receivedTxs, usedGas, mining) if err != nil { return err @@ -1828,8 +1829,8 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he if balance.Cmp(common.U2560) <= 0 { return nil } - state.SetBalance(consensus.SystemAddress, common.U2560) - state.AddBalance(coinbase, balance) + state.SetBalance(consensus.SystemAddress, common.U2560, tracing.BalanceChangeUnspecified) + state.AddBalance(coinbase, balance, tracing.BalanceChangeUnspecified) log.Trace("distribute to validator contract", "block hash", header.Hash(), "amount", balance) return p.distributeToValidator(balance.ToBig(), val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) } diff --git a/console/console_test.go b/console/console_test.go index a13be6a99d..6e14e09729 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -152,8 +152,7 @@ func (env *tester) Close(t *testing.T) { } // Tests that the node lists the correct welcome message, notably that it contains -// the instance name, coinbase account, block number, data directory and supported -// console modules. +// the instance name, block number, data directory and supported console modules. func TestWelcome(t *testing.T) { tester := newTester(t, nil) defer tester.Close(t) @@ -174,7 +173,10 @@ func TestWelcome(t *testing.T) { t.Fatalf("console output missing sync status: have\n%s\nwant also %s", output, want) } if want := fmt.Sprintf("datadir: %s", tester.workspace); !strings.Contains(output, want) { - t.Fatalf("console output missing coinbase: have\n%s\nwant also %s", output, want) + t.Fatalf("console output missing datadir: have\n%s\nwant also %s", output, want) + } + if want := "modules: "; !strings.Contains(output, want) { + t.Fatalf("console output missing modules: have\n%s\nwant also %s", output, want) } } diff --git a/core/asm/asm.go b/core/asm/asm.go index 294eb6ffaa..ff41ff5315 100644 --- a/core/asm/asm.go +++ b/core/asm/asm.go @@ -66,7 +66,7 @@ func (it *instructionIterator) Next() bool { it.op = vm.OpCode(it.code[it.pc]) if it.op.IsPush() { - a := uint64(it.op) - uint64(vm.PUSH1) + 1 + a := uint64(it.op) - uint64(vm.PUSH0) u := it.pc + 1 + a if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u { it.error = fmt.Errorf("incomplete push instruction at %v", it.pc) diff --git a/core/asm/lexer.go b/core/asm/lexer.go index 6dd3d7ab16..dd5ab9cfeb 100644 --- a/core/asm/lexer.go +++ b/core/asm/lexer.go @@ -129,7 +129,7 @@ func (l *lexer) ignore() { l.start = l.pos } -// Accepts checks whether the given input matches the next rune +// accept checks whether the given input matches the next rune func (l *lexer) accept(valid string) bool { if strings.ContainsRune(valid, l.next()) { return true diff --git a/core/block_validator.go b/core/block_validator.go index 6b292ddbe4..a7031869ac 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -43,15 +43,13 @@ func EnableRemoteVerifyManager(remoteValidator *remoteVerifyManager) BlockValida type BlockValidator struct { config *params.ChainConfig // Chain configuration options bc *BlockChain // Canonical block chain - engine consensus.Engine // Consensus engine used for validating remoteValidator *remoteVerifyManager } // NewBlockValidator returns a new block validator which is safe for re-use -func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine, opts ...BlockValidatorOption) *BlockValidator { +func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, opts ...BlockValidatorOption) *BlockValidator { validator := &BlockValidator{ config: config, - engine: engine, bc: blockchain, } @@ -73,7 +71,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // Header validity is known at this point. Here we verify that uncles, transactions // and withdrawals given in the block body match the header. header := block.Header() - if err := v.engine.VerifyUncles(v.bc, block); err != nil { + if err := v.bc.engine.VerifyUncles(v.bc, block); err != nil { return err } if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash { @@ -162,35 +160,56 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // ValidateState validates the various changes that happen after a state transition, // such as amount of used gas, the receipt roots and the state root itself. -func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { +func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, res *ProcessResult, stateless bool) error { + if res == nil { + return fmt.Errorf("nil ProcessResult value") + } header := block.Header() - if block.GasUsed() != usedGas { - return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas) + if block.GasUsed() != res.GasUsed { + return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), res.GasUsed) } // Validate the received block's bloom with the one derived from the generated receipts. // For valid blocks this should always validate to true. validateFuns := []func() error{ func() error { - rbloom := types.CreateBloom(receipts) + rbloom := types.CreateBloom(res.Receipts) if rbloom != header.Bloom { return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom) } return nil }, - func() error { - receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil)) + } + // In stateless mode, return early because the receipt and state root are not + // provided through the witness, rather the cross validator needs to return it. + if !stateless { + validateFuns = append(validateFuns, func() error { + // The receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, Rn]])) + receiptSha := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil)) if receiptSha != header.ReceiptHash { return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha) } return nil - }, + }) + validateFuns = append(validateFuns, func() error { + // Validate the parsed requests match the expected header value. + if header.RequestsHash != nil { + depositSha := types.DeriveSha(res.Requests, trie.NewStackTrie(nil)) + if depositSha != *header.RequestsHash { + return fmt.Errorf("invalid deposit root hash (remote: %x local: %x)", *header.RequestsHash, depositSha) + } + } + return nil + }) + validateFuns = append(validateFuns, func() error { + // Validate the state root against the received state root and throw + // an error if they don't match. + if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { + return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error()) + } + return nil + }) } - validateFuns = append(validateFuns, func() error { - if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { - return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error()) - } - return nil - }) + validateRes := make(chan error, len(validateFuns)) for _, f := range validateFuns { tmpFunc := f diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 1ab82ea0be..ba157feee3 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -94,7 +94,6 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) { preBlocks []*types.Block postBlocks []*types.Block engine consensus.Engine - merger = consensus.NewMerger(rawdb.NewMemoryDatabase()) ) if isClique { var ( @@ -155,12 +154,10 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) { preHeaders := make([]*types.Header, len(preBlocks)) for i, block := range preBlocks { preHeaders[i] = block.Header() - t.Logf("Pre-merge header: %d", block.NumberU64()) } postHeaders := make([]*types.Header, len(postBlocks)) for i, block := range postBlocks { postHeaders[i] = block.Header() - t.Logf("Post-merge header: %d", block.NumberU64()) } // Run the header checker for blocks one-by-one, checking for both valid and invalid nonces chain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) @@ -186,11 +183,6 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) { } chain.InsertChain(preBlocks[i : i+1]) } - - // Make the transition - merger.ReachTTD() - merger.FinalizePoS() - // Verify the blocks after the merging for i := 0; i < len(postBlocks); i++ { _, results := engine.VerifyHeaders(chain, []*types.Header{postHeaders[i]}) @@ -209,7 +201,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) { t.Fatalf("post-block %d: unexpected result returned: %v", i, result) case <-time.After(25 * time.Millisecond): } - chain.InsertBlockWithoutSetHead(postBlocks[i]) + chain.InsertBlockWithoutSetHead(postBlocks[i], false) } // Verify the blocks with pre-merge blocks and post-merge blocks diff --git a/core/blockchain.go b/core/blockchain.go index 1d3ffb12e7..0867afdd14 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -42,7 +42,9 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/systemcontracts" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" @@ -75,26 +77,26 @@ var ( chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil) - accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) - accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) - accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil) - accountCommitTimer = metrics.NewRegisteredTimer("chain/account/commits", nil) + accountReadTimer = metrics.NewRegisteredResettingTimer("chain/account/reads", nil) + accountHashTimer = metrics.NewRegisteredResettingTimer("chain/account/hashes", nil) + accountUpdateTimer = metrics.NewRegisteredResettingTimer("chain/account/updates", nil) + accountCommitTimer = metrics.NewRegisteredResettingTimer("chain/account/commits", nil) - storageReadTimer = metrics.NewRegisteredTimer("chain/storage/reads", nil) - storageHashTimer = metrics.NewRegisteredTimer("chain/storage/hashes", nil) - storageUpdateTimer = metrics.NewRegisteredTimer("chain/storage/updates", nil) - storageCommitTimer = metrics.NewRegisteredTimer("chain/storage/commits", nil) + storageReadTimer = metrics.NewRegisteredResettingTimer("chain/storage/reads", nil) + storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil) + storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil) - snapshotAccountReadTimer = metrics.NewRegisteredTimer("chain/snapshot/account/reads", nil) - snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil) - snapshotCommitTimer = metrics.NewRegisteredTimer("chain/snapshot/commits", nil) + accountReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/account/single/reads", nil) + storageReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/storage/single/reads", nil) - triedbCommitTimer = metrics.NewRegisteredTimer("chain/triedb/commits", nil) + snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil) + triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil) - blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) - blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) - blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) - blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) + blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil) + blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil) + blockCrossValidationTimer = metrics.NewRegisteredResettingTimer("chain/crossvalidation", nil) + blockExecutionTimer = metrics.NewRegisteredResettingTimer("chain/execution", nil) + blockWriteTimer = metrics.NewRegisteredResettingTimer("chain/write", nil) blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil) blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) @@ -117,7 +119,6 @@ const ( txLookupCacheLimit = 1024 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 - TriesInMemory = 128 maxBeyondBlocks = 2048 prefetchTxNumber = 100 @@ -173,11 +174,12 @@ type CacheConfig struct { } // triedbConfig derives the configures for trie database. -func (c *CacheConfig) triedbConfig() *triedb.Config { +func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config { config := &triedb.Config{ Cache: c.TrieCleanLimit, Preimages: c.Preimages, NoTries: c.NoTries, + IsVerkle: isVerkle, } if c.StateScheme == rawdb.HashScheme { config.HashDB = &hashdb.Config{ @@ -253,7 +255,7 @@ type BlockChain struct { lastWrite uint64 // Last block when the state was flushed flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state triedb *triedb.Database // The database handler for maintaining trie nodes. - stateCache state.Database // State database to reuse between imports (contains state cache) + statedb *state.CachingDB // State database to reuse between imports (contains state cache) triesInMemory uint64 txIndexer *txIndexer // Transaction indexer, might be nil if not enabled @@ -285,6 +287,8 @@ type BlockChain struct { bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] receiptsCache *lru.Cache[common.Hash, []*types.Receipt] blockCache *lru.Cache[common.Hash, *types.Block] + + txLookupLock sync.RWMutex txLookupCache *lru.Cache[common.Hash, txLookup] sidecarsCache *lru.Cache[common.Hash, types.BlobSidecars] @@ -313,6 +317,7 @@ type BlockChain struct { // monitor doubleSignMonitor *monitor.DoubleSignMonitor + logger *tracing.Hooks } // NewBlockChain returns a fully initialised block chain using information @@ -333,7 +338,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis diffLayerChanCache, _ := exlru.New(diffLayerCacheLimit) // Open trie database with provided config - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig()) + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(genesis != nil && genesis.IsVerkle())) // Setup the genesis block, commit the provided genesis specification // to database if the genesis block is not present yet, or load the @@ -377,19 +382,20 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis vmConfig: vmConfig, diffQueue: prque.New[int64, *types.DiffLayer](nil), diffQueueBuffer: make(chan *types.DiffLayer), + logger: vmConfig.Tracer, } - bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit)) - bc.forker = NewForkChoice(bc, shouldPreserve) - bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb) - bc.validator = NewBlockValidator(chainConfig, bc, engine) - bc.prefetcher = NewStatePrefetcher(chainConfig, bc, engine) - bc.processor = NewStateProcessor(chainConfig, bc, engine) - var err error bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) if err != nil { return nil, err } + bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit)) + bc.forker = NewForkChoice(bc, shouldPreserve) + bc.statedb = state.NewDatabase(bc.triedb, nil) + bc.validator = NewBlockValidator(chainConfig, bc) + bc.prefetcher = NewStatePrefetcher(chainConfig, bc.hc) + bc.processor = NewStateProcessor(chainConfig, bc.hc) + bc.genesisBlock = bc.GetBlockByNumber(0) if bc.genesisBlock == nil { return nil, ErrNoGenesis @@ -498,19 +504,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // it in advance. bc.engine.VerifyHeader(bc, bc.CurrentHeader()) - // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain - for hash := range BadHashes { - if header := bc.GetHeaderByHash(hash); header != nil { - // get the canonical block corresponding to the offending header's number - headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) - // make sure the headerByNumber (if present) is in our current canonical chain - if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { - log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) - if err := bc.SetHead(header.Number.Uint64() - 1); err != nil { - return nil, err - } - log.Error("Chain rewind was successful, resuming normal operation") + if bc.logger != nil && bc.logger.OnBlockchainInit != nil { + bc.logger.OnBlockchainInit(chainConfig) + } + if bc.logger != nil && bc.logger.OnGenesisBlock != nil { + if block := bc.CurrentBlock(); block.Number.Uint64() == 0 { + alloc, err := getGenesisState(bc.db, block.Hash()) + if err != nil { + return nil, fmt.Errorf("failed to get genesis state: %w", err) } + if alloc == nil { + return nil, errors.New("live blockchain tracer requires genesis alloc to be set") + } + bc.logger.OnGenesisBlock(bc.genesisBlock, alloc) } } @@ -534,6 +540,9 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis AsyncBuild: !bc.cacheConfig.SnapshotWait, } bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root, int(bc.cacheConfig.TriesInMemory), bc.NoTries()) + + // Re-initialize the state database with snapshot + bc.statedb = state.NewDatabase(bc.triedb, bc.snaps) } // do options before start any routine for _, option := range options { @@ -567,6 +576,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } rawdb.WriteChainConfig(db, genesisHash, chainConfig) } + // Start tx indexer if it's enabled. if txLookupLimit != nil { bc.txIndexer = newTxIndexer(*txLookupLimit, bc) @@ -580,7 +590,7 @@ func (bc *BlockChain) GetVMConfig() *vm.Config { } func (bc *BlockChain) NoTries() bool { - return bc.stateCache.NoTries() + return bc.statedb.NoTries() } func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts, block *types.Block) { @@ -1104,7 +1114,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha // touching the header chain altogether, unless the freezer is broken if repair { if target, force := updateFn(bc.db.BlockStore(), bc.CurrentBlock()); force { - bc.hc.SetHead(target.Number.Uint64(), updateFn, delFn) + bc.hc.SetHead(target.Number.Uint64(), nil, delFn) } } else { // Rewind the chain to the requested head and keep going backwards until a @@ -1362,7 +1372,7 @@ func (bc *BlockChain) Stop() { if !bc.cacheConfig.TrieDirtyDisabled { triedb := bc.triedb var once sync.Once - for _, offset := range []uint64{0, 1, bc.TriesInMemory() - 1} { + for _, offset := range []uint64{0, 1, state.TriesInMemory - 1} { if number := bc.CurrentBlock().Number.Uint64(); number > offset { recent := bc.GetBlockByNumber(number - offset) log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) @@ -1393,6 +1403,10 @@ func (bc *BlockChain) Stop() { } } } + // Allow tracers to clean-up and release resources. + if bc.logger != nil && bc.logger.OnClose != nil { + bc.logger.OnClose() + } // Close the trie database, release all the held resources as the last step. if err := bc.triedb.Close(); err != nil { log.Error("Failed to close trie database", "err", err) @@ -1572,8 +1586,8 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Delete block data from the main database. var ( - canonHashes = make(map[common.Hash]struct{}) blockBatch = bc.db.BlockStore().NewBatch() + canonHashes = make(map[common.Hash]struct{}, len(blockChain)) ) for _, block := range blockChain { canonHashes[block.Hash()] = struct{}{} @@ -1737,11 +1751,11 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error { // writeBlockWithState writes block, metadata and corresponding state data to the // database. -func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) error { +func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, statedb *state.StateDB) error { // Calculate the total difficulty of the block ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) if ptd == nil { - state.StopPrefetcher() + statedb.StopPrefetcher() return consensus.ErrUnknownAncestor } // Make sure no inconsistent state is leaked during insertion @@ -1763,9 +1777,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. rawdb.WriteBlobSidecars(blockBatch, block.Hash(), block.NumberU64(), block.Sidecars()) } if bc.db.StateStore() != nil { - rawdb.WritePreimages(bc.db.StateStore(), state.Preimages()) + rawdb.WritePreimages(bc.db.StateStore(), statedb.Preimages()) } else { - rawdb.WritePreimages(blockBatch, state.Preimages()) + rawdb.WritePreimages(blockBatch, statedb.Preimages()) } if err := blockBatch.Write(); err != nil { log.Crit("Failed to write block into disk", "err", err) @@ -1789,7 +1803,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. return nil } - triedb := bc.stateCache.TrieDB() + triedb := bc.statedb.TrieDB() // If we're running an archive node, always flush if bc.cacheConfig.TrieDirtyDisabled { return triedb.Commit(block.Root(), false) @@ -1800,7 +1814,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Flush limits are not considered for the first TriesInMemory blocks. current := block.NumberU64() - if current <= bc.TriesInMemory() { + if current <= state.TriesInMemory { return nil } // If we exceeded our memory allowance, flush matured singleton nodes to disk @@ -1812,7 +1826,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. triedb.Cap(limit - ethdb.IdealBatchSize) } // Find the next state trie we need to commit - chosen := current - bc.triesInMemory + chosen := current - state.TriesInMemory flushInterval := time.Duration(bc.flushInterval.Load()) // If we exceeded out time allowance, flush an entire trie to disk if bc.gcproc > flushInterval { @@ -1831,8 +1845,8 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. } else { // If we're exceeding limits but haven't reached a large enough memory gap, // warn the user that the system is becoming unstable. - if chosen < bc.lastWrite+bc.triesInMemory && bc.gcproc >= 2*flushInterval { - log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", flushInterval, "optimum", float64(chosen-bc.lastWrite)/float64(bc.triesInMemory)) + if chosen < bc.lastWrite+state.TriesInMemory && bc.gcproc >= 2*flushInterval { + log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", flushInterval, "optimum", float64(chosen-bc.lastWrite)/float64(state.TriesInMemory)) } // Flush an entire trie and restart the counters triedb.Commit(header.Root, true) @@ -1860,7 +1874,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. return nil } // Commit all cached state changes into underlying memory database. - _, diffLayer, err := state.Commit(block.NumberU64(), tryCommitTrieDB) + _, diffLayer, err := statedb.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), tryCommitTrieDB) if err != nil { return err } @@ -2007,7 +2021,9 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { return 0, errChainStopped } defer bc.chainmu.Unlock() - return bc.insertChain(chain, true) + + _, n, err := bc.insertChain(chain, true, false) // No witness collection for mass inserts (would get super large) + return n, err } // insertChain is the internal implementation of InsertChain, which assumes that @@ -2018,10 +2034,10 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { // racey behaviour. If a sidechain import is in progress, and the historic state // is imported, but then new canon-head is added before the actual sidechain // completes, then the historic state could be pruned again -func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) { +func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness bool) (*stateless.Witness, int, error) { // If the chain is terminating, don't even bother starting up. if bc.insertStopped() { - return 0, nil + return nil, 0, nil } if len(chain) > 0 { @@ -2050,7 +2066,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) // check block data available first if bc.chainConfig.Parlia != nil { if index, err := CheckDataAvailableInBatch(bc, chain); err != nil { - return index, err + return nil, index, err } } @@ -2080,7 +2096,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) for block != nil && bc.skipBlock(err, it) { reorg, err = bc.forker.ReorgNeededWithFastFinality(current, block.Header()) if err != nil { - return it.index, err + return nil, it.index, err } if reorg { // Switch to import mode if the forker says the reorg is necessary @@ -2108,7 +2124,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) for block != nil && bc.skipBlock(err, it) { log.Debug("Writing previously known block", "number", block.Number(), "hash", block.Hash()) if err := bc.writeKnownBlock(block); err != nil { - return it.index, err + return nil, it.index, err } lastCanon = block @@ -2122,19 +2138,19 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) if setHead { // First block is pruned, insert as sidechain and reorg only if TD grows enough log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash()) - return bc.insertSideChain(block, it) + return bc.insertSideChain(block, it, makeWitness) } else { // We're post-merge and the parent is pruned, try to recover the parent state log.Debug("Pruned ancestor", "number", block.Number(), "hash", block.Hash()) - _, err := bc.recoverAncestors(block) - return it.index, err + _, err := bc.recoverAncestors(block, makeWitness) + return nil, it.index, err } // First block is future, shove it (and all children) to the future queue (unknown ancestor) case errors.Is(err, consensus.ErrFutureBlock) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())): for block != nil && (it.index == 0 || errors.Is(err, consensus.ErrUnknownAncestor)) { log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash()) if err := bc.addFutureBlock(block); err != nil { - return it.index, err + return nil, it.index, err } block, err = it.next() } @@ -2142,7 +2158,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) stats.ignored += it.remaining() // If there are any still remaining, mark as ignored - return it.index, err + return nil, it.index, err // Some other error(except ErrKnownBlock) occurred, abort. // ErrKnownBlock is allowed here since some known blocks @@ -2151,20 +2167,18 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) bc.futureBlocks.Remove(block.Hash()) stats.ignored += len(it.chain) bc.reportBlock(block, nil, err) - return it.index, err + return nil, it.index, err } + // Track the singleton witness from this chain insertion (if any) + var witness *stateless.Witness + for ; block != nil && err == nil || errors.Is(err, ErrKnownBlock); block, err = it.next() { // If the chain is terminating, stop processing blocks if bc.insertStopped() { log.Debug("Abort during block processing") break } - // If the header is a banned one, straight out abort - if BadHashes[block.Hash()] { - bc.reportBlock(block, nil, ErrBannedHash) - return it.index, ErrBannedHash - } // If the block is known (in the middle of the chain), it's a special case for // Clique blocks where they can share state among each other, so importing an // older block might complete the state of the subsequent one. In this case, @@ -2195,16 +2209,22 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) "hash", block.Hash(), "number", block.NumberU64()) } if err := bc.writeKnownBlock(block); err != nil { - return it.index, err + return nil, it.index, err } stats.processed++ - + if bc.logger != nil && bc.logger.OnSkippedBlock != nil { + bc.logger.OnSkippedBlock(tracing.BlockEvent{ + Block: block, + TD: bc.GetTd(block.ParentHash(), block.NumberU64()-1), + Finalized: bc.CurrentFinalBlock(), + Safe: bc.CurrentSafeBlock(), + }) + } // We can assume that logs are empty here, since the only way for consecutive // Clique blocks to have the same state is if there are no transactions. lastCanon = block continue } - // Retrieve the parent block and it's state to execute on top start := time.Now() parent := it.previous() @@ -2212,22 +2232,39 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) } - statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps) + statedb, err := state.NewWithSharedPool(parent.Root, bc.statedb) if err != nil { - return it.index, err + return nil, it.index, err } bc.updateHighestVerifiedHeader(block.Header()) + statedb.SetLogger(bc.logger) + + // If we are past Byzantium, enable prefetching to pull in trie node paths + // while processing transactions. Before Byzantium the prefetcher is mostly + // useless due to the intermediate root hashing after each transaction. + if bc.chainConfig.IsByzantium(block.Number()) { + // Generate witnesses either if we're self-testing, or if it's the + // only block being inserted. A bit crude, but witnesses are huge, + // so we refuse to make an entire chain of them. + if bc.vmConfig.StatelessSelfValidation || (makeWitness && len(chain) == 1) { + witness, err = stateless.NewWitness(block.Header(), bc) + if err != nil { + return nil, it.index, err + } + } + statedb.StartPrefetcher("chain", witness) + } - // Enable prefetching to pull in trie node paths while processing transactions - statedb.StartPrefetcher("chain") interruptCh := make(chan struct{}) // For diff sync, it may fallback to full sync, so we still do prefetch - if len(block.Transactions()) >= prefetchTxNumber { + if !bc.cacheConfig.TrieCleanNoPrefetch && len(block.Transactions()) >= prefetchTxNumber { // do Prefetch in a separate goroutine to avoid blocking the critical path - // 1.do state prefetch for snapshot cache throwaway := statedb.CopyDoPrefetch() - go bc.prefetcher.Prefetch(block, throwaway, &bc.vmConfig, interruptCh) + // Disable tracing for prefetcher executions. + vmCfg := bc.vmConfig + vmCfg.Tracer = nil + go bc.prefetcher.Prefetch(block, throwaway, &vmCfg, interruptCh) // 2.do trie prefetch for MPT trie node cache // it is for the big state trie tree, prefetch based on transaction's From/To address. @@ -2235,88 +2272,29 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) go throwaway.TriePrefetchInAdvance(block, signer) } - // Process block using the parent state as reference point - statedb.SetExpectedStateRoot(block.Root()) - pstart := time.Now() - statedb, receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig) - close(interruptCh) // state prefetch can be stopped - if err != nil { - bc.reportBlock(block, receipts, err) - statedb.StopPrefetcher() - return it.index, err - } - ptime := time.Since(pstart) - - // Validate the state using the default validator - vstart := time.Now() - if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil { - log.Error("validate state failed", "error", err) - bc.reportBlock(block, receipts, err) - statedb.StopPrefetcher() - return it.index, err - } - vtime := time.Since(vstart) - proctime := time.Since(start) // processing + validation - - // Update the metrics touched during block processing and validation - accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing) - storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing) - snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete(in processing) - snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete(in processing) - accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation) - storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation) - accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation) - storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete(in validation) - triehash := statedb.AccountHashes + statedb.StorageHashes // The time spent on tries hashing - trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update - trieRead := statedb.SnapshotAccountReads + statedb.AccountReads // The time spent on account read - trieRead += statedb.SnapshotStorageReads + statedb.StorageReads // The time spent on storage read - blockExecutionTimer.Update(ptime - trieRead) // The time spent on EVM processing - blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation - - // Write the block to the chain and get the status. - var ( - wstart = time.Now() - status WriteStatus - ) - if !setHead { - // Don't set the head, only insert the block - err = bc.writeBlockWithState(block, receipts, statedb) - } else { - status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false) - } + // The traced section of block import. + res, err := bc.processBlock(block, statedb, start, setHead, interruptCh) if err != nil { - return it.index, err + return nil, it.index, err } - - // Update the metrics touched during block commit - accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them - storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them - snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them - triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them - - blockWriteTimer.Update(time.Since(wstart) - statedb.AccountCommits - statedb.StorageCommits - statedb.SnapshotCommits - statedb.TrieDBCommits) - blockInsertTimer.UpdateSince(start) - // Report the import stats before returning the various results stats.processed++ - stats.usedGas += usedGas + stats.usedGas += res.usedGas var snapDiffItems, snapBufItems common.StorageSize if bc.snaps != nil { snapDiffItems, snapBufItems, _ = bc.snaps.Size() } trieDiffNodes, trieBufNodes, trieImmutableBufNodes, _ := bc.triedb.Size() - stats.report(chain, it.index, snapDiffItems, snapBufItems, trieDiffNodes, trieBufNodes, trieImmutableBufNodes, status == CanonStatTy) + stats.report(chain, it.index, snapDiffItems, snapBufItems, trieDiffNodes, trieBufNodes, trieImmutableBufNodes, res.status == CanonStatTy) if !setHead { // After merge we expect few side chains. Simply count // all blocks the CL gives us for GC processing time - bc.gcproc += proctime - - return it.index, nil // Direct block insertion of a single block + bc.gcproc += res.procTime + return witness, it.index, nil // Direct block insertion of a single block } - switch status { + switch res.status { case CanonStatTy: log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), @@ -2326,7 +2304,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) lastCanon = block // Only count canonical blocks for GC processing time - bc.gcproc += proctime + bc.gcproc += res.procTime case SideStatTy: log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), @@ -2348,20 +2326,19 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) // Any blocks remaining here? The only ones we care about are the future ones if block != nil && errors.Is(err, consensus.ErrFutureBlock) { if err := bc.addFutureBlock(block); err != nil { - return it.index, err + return nil, it.index, err } block, err = it.next() for ; block != nil && errors.Is(err, consensus.ErrUnknownAncestor); block, err = it.next() { if err := bc.addFutureBlock(block); err != nil { - return it.index, err + return nil, it.index, err } stats.queued++ } } stats.ignored += it.remaining() - - return it.index, err + return witness, it.index, err } func (bc *BlockChain) updateHighestVerifiedHeader(header *types.Header) { @@ -2380,6 +2357,129 @@ func (bc *BlockChain) GetHighestVerifiedHeader() *types.Header { return bc.highestVerifiedHeader.Load() } +// blockProcessingResult is a summary of block processing +// used for updating the stats. +type blockProcessingResult struct { + usedGas uint64 + procTime time.Duration + status WriteStatus +} + +// processBlock executes and validates the given block. If there was no error +// it writes the block and associated state to database. +func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, start time.Time, setHead bool, interruptCh chan struct{}) (_ *blockProcessingResult, blockEndErr error) { + statedb.SetExpectedStateRoot(block.Root()) + + if bc.logger != nil && bc.logger.OnBlockStart != nil { + td := bc.GetTd(block.ParentHash(), block.NumberU64()-1) + bc.logger.OnBlockStart(tracing.BlockEvent{ + Block: block, + TD: td, + Finalized: bc.CurrentFinalBlock(), + Safe: bc.CurrentSafeBlock(), + }) + } + if bc.logger != nil && bc.logger.OnBlockEnd != nil { + defer func() { + bc.logger.OnBlockEnd(blockEndErr) + }() + } + + // Process block using the parent state as reference point + pstart := time.Now() + res, err := bc.processor.Process(block, statedb, bc.vmConfig) + close(interruptCh) // state prefetch can be stopped + if err != nil { + bc.reportBlock(block, res, err) + statedb.StopPrefetcher() + return nil, err + } + ptime := time.Since(pstart) + + // Validate the state using the default validator + vstart := time.Now() + if err := bc.validator.ValidateState(block, statedb, res, false); err != nil { + bc.reportBlock(block, res, err) + statedb.StopPrefetcher() + return nil, err + } + vtime := time.Since(vstart) + + // If witnesses was generated and stateless self-validation requested, do + // that now. Self validation should *never* run in production, it's more of + // a tight integration to enable running *all* consensus tests through the + // witness builder/runner, which would otherwise be impossible due to the + // various invalid chain states/behaviors being contained in those tests. + xvstart := time.Now() + if witness := statedb.Witness(); witness != nil && bc.vmConfig.StatelessSelfValidation { + log.Warn("Running stateless self-validation", "block", block.Number(), "hash", block.Hash()) + + // Remove critical computed fields from the block to force true recalculation + context := block.Header() + context.Root = common.Hash{} + context.ReceiptHash = common.Hash{} + + task := types.NewBlockWithHeader(context).WithBody(*block.Body()) + + // Run the stateless self-cross-validation + crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, task, witness) + if err != nil { + return nil, fmt.Errorf("stateless self-validation failed: %v", err) + } + if crossStateRoot != block.Root() { + return nil, fmt.Errorf("stateless self-validation root mismatch (cross: %x local: %x)", crossStateRoot, block.Root()) + } + if crossReceiptRoot != block.ReceiptHash() { + return nil, fmt.Errorf("stateless self-validation receipt root mismatch (cross: %x local: %x)", crossReceiptRoot, block.ReceiptHash()) + } + } + xvtime := time.Since(xvstart) + proctime := time.Since(start) // processing + validation + cross validation + + // Update the metrics touched during block processing and validation + accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing) + storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing) + if statedb.AccountLoaded != 0 { + accountReadSingleTimer.Update(statedb.AccountReads / time.Duration(statedb.AccountLoaded)) + } + if statedb.StorageLoaded != 0 { + storageReadSingleTimer.Update(statedb.StorageReads / time.Duration(statedb.StorageLoaded)) + } + accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation) + storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation) + accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation) + triehash := statedb.AccountHashes // The time spent on tries hashing + trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update + blockExecutionTimer.Update(ptime - (statedb.AccountReads + statedb.StorageReads)) // The time spent on EVM processing + blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation + blockCrossValidationTimer.Update(xvtime) // The time spent on stateless cross validation + + // Write the block to the chain and get the status. + var ( + wstart = time.Now() + status WriteStatus + ) + if !setHead { + // Don't set the head, only insert the block + err = bc.writeBlockWithState(block, res.Receipts, statedb) + } else { + status, err = bc.writeBlockAndSetHead(block, res.Receipts, res.Logs, statedb, false) + } + if err != nil { + return nil, err + } + // Update the metrics touched during block commit + accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them + storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them + snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them + triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them + + blockWriteTimer.Update(time.Since(wstart) - max(statedb.AccountCommits, statedb.StorageCommits) /* concurrent */ - statedb.SnapshotCommits - statedb.TrieDBCommits) + blockInsertTimer.UpdateSince(start) + + return &blockProcessingResult{usedGas: res.GasUsed, procTime: proctime, status: status}, nil +} + // insertSideChain is called when an import batch hits upon a pruned ancestor // error, which happens when a sidechain with a sufficiently old fork-block is // found. @@ -2387,7 +2487,7 @@ func (bc *BlockChain) GetHighestVerifiedHeader() *types.Header { // The method writes all (header-and-body-valid) blocks to disk, then tries to // switch over to the new chain if the TD exceeded the current chain. // insertSideChain is only used pre-merge. -func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (int, error) { +func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, makeWitness bool) (*stateless.Witness, int, error) { var ( externTd *big.Int lastBlock = block @@ -2424,7 +2524,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i // If someone legitimately side-mines blocks, they would still be imported as usual. However, // we cannot risk writing unverified blocks to disk when they obviously target the pruning // mechanism. - return it.index, errors.New("sidechain ghost-state attack") + return nil, it.index, errors.New("sidechain ghost-state attack") } } if externTd == nil { @@ -2435,7 +2535,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i if !bc.HasBlock(block.Hash(), block.NumberU64()) { start := time.Now() if err := bc.writeBlockWithoutState(block, externTd); err != nil { - return it.index, err + return nil, it.index, err } log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), @@ -2452,12 +2552,12 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i // blocks to regenerate the required state reorg, err := bc.forker.ReorgNeededWithFastFinality(current, lastBlock.Header()) if err != nil { - return it.index, err + return nil, it.index, err } if !reorg { localTd := bc.GetTd(current.Hash(), current.Number.Uint64()) log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd) - return it.index, err + return nil, it.index, err } // Gather all the sidechain hashes (full blocks may be memory heavy) var ( @@ -2468,7 +2568,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i for parent != nil && !bc.HasState(parent.Root) { if bc.stateRecoverable(parent.Root) { if err := bc.triedb.Recover(parent.Root); err != nil { - return 0, err + return nil, 0, err } break } @@ -2478,7 +2578,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1) } if parent == nil { - return it.index, errors.New("missing parent") + return nil, it.index, errors.New("missing parent") } // Import all the pruned blocks to make the state available var ( @@ -2502,30 +2602,30 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i // memory here. if len(blocks) >= 2048 || memory > 64*1024*1024 { log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64()) - if _, err := bc.insertChain(blocks, true); err != nil { - return 0, err + if _, _, err := bc.insertChain(blocks, true, false); err != nil { + return nil, 0, err } blocks, memory = blocks[:0], 0 // If the chain is terminating, stop processing blocks if bc.insertStopped() { log.Debug("Abort during blocks processing") - return 0, nil + return nil, 0, nil } } } if len(blocks) > 0 { log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64()) - return bc.insertChain(blocks, true) + return bc.insertChain(blocks, true, makeWitness) } - return 0, nil + return nil, 0, nil } // recoverAncestors finds the closest ancestor with available state and re-execute // all the ancestor blocks since that. // recoverAncestors is only used post-merge. // We return the hash of the latest block that we could correctly validate. -func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error) { +func (bc *BlockChain) recoverAncestors(block *types.Block, makeWitness bool) (common.Hash, error) { // Gather all the sidechain hashes (full blocks may be memory heavy) var ( hashes []common.Hash @@ -2568,7 +2668,7 @@ func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error) if bc.chainConfig.IsCancun(b.Number(), b.Time()) { b = b.WithSidecars(bc.GetSidecarsByHash(b.Hash())) } - if _, err := bc.insertChain(types.Blocks{b}, false); err != nil { + if _, _, err := bc.insertChain(types.Blocks{b}, false, makeWitness && i == 0); err != nil { return b.ParentHash(), err } } @@ -2689,14 +2789,14 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error { // rewind the canonical chain to a lower point. log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain)) } - // Reset the tx lookup cache in case to clear stale txlookups. - // This is done before writing any new chain data to avoid the - // weird scenario that canonical chain is changed while the - // stale lookups are still cached. - bc.txLookupCache.Purge() + // Acquire the tx-lookup lock before mutation. This step is essential + // as the txlookups should be changed atomically, and all subsequent + // reads should be blocked until the mutation is complete. + bc.txLookupLock.Lock() - // Insert the new chain(except the head block(reverse order)), - // taking care of the proper incremental order. + // Insert the new chain segment in incremental order, from the old + // to the new. The new chain head (newChain[0]) is not inserted here, + // as it will be handled separately outside of this function for i := len(newChain) - 1; i >= 1; i-- { // Insert the block in the canonical way, re-writing history bc.writeHeadBlock(newChain[i]) @@ -2737,6 +2837,11 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error { if err := blockBatch.Write(); err != nil { log.Crit("Failed to delete useless indexes use block batch", "err", err) } + // Reset the tx lookup cache to clear stale txlookup cache. + bc.txLookupCache.Purge() + + // Release the tx-lookup lock after mutation. + bc.txLookupLock.Unlock() // Send out events for logs from the old canon chain, and 'reborn' // logs from the new canon chain. The number of logs can be very @@ -2783,14 +2888,14 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error { // The key difference between the InsertChain is it won't do the canonical chain // updating. It relies on the additional SetCanonical call to finalize the entire // procedure. -func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block) error { +func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness bool) (*stateless.Witness, error) { if !bc.chainmu.TryLock() { - return errChainStopped + return nil, errChainStopped } defer bc.chainmu.Unlock() - _, err := bc.insertChain(types.Blocks{block}, false) - return err + witness, _, err := bc.insertChain(types.Blocks{block}, false, makeWitness) + return witness, err } // SetCanonical rewinds the chain to set the new head block as the specified @@ -2804,7 +2909,7 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) { // Re-execute the reorged chain in case the head state is missing. if !bc.HasState(head.Root()) { - if latestValidHash, err := bc.recoverAncestors(head); err != nil { + if latestValidHash, err := bc.recoverAncestors(head, false); err != nil { return latestValidHash, err } log.Info("Recovered head state", "number", head.Number(), "hash", head.Hash()) @@ -2992,7 +3097,11 @@ func (bc *BlockChain) skipBlock(err error, it *insertIterator) bool { // reportBlock logs a bad block error. // bad block need not save receipts & sidecars. -func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { +func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err error) { + var receipts types.Receipts + if res != nil { + receipts = res.Receipts + } rawdb.WriteBadBlock(bc.db, block) log.Error(summarizeBadBlock(block, receipts, bc.Config(), err)) } @@ -3049,7 +3158,10 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header) (int, error) { return 0, err } -func (bc *BlockChain) TriesInMemory() uint64 { return bc.triesInMemory } +func (bc *BlockChain) HeadChain() *HeaderChain { + return bc.hc +} +func (bc *BlockChain) TriesInMemory() uint64 { return state.TriesInMemory } func EnablePersistDiff(limit uint64) BlockChainOption { return func(chain *BlockChain) (*BlockChain, error) { @@ -3058,7 +3170,7 @@ func EnablePersistDiff(limit uint64) BlockChainOption { } } -func EnableBlockValidator(chainConfig *params.ChainConfig, engine consensus.Engine, mode VerifyMode, peers verifyPeers) BlockChainOption { +func EnableBlockValidator(chainConfig *params.ChainConfig, _ consensus.Engine, mode VerifyMode, peers verifyPeers) BlockChainOption { return func(bc *BlockChain) (*BlockChain, error) { if mode.NeedRemoteVerify() { vm, err := NewVerifyManager(bc, peers, mode == InsecureVerify) @@ -3066,7 +3178,7 @@ func EnableBlockValidator(chainConfig *params.ChainConfig, engine consensus.Engi return nil, err } go vm.mainLoop() - bc.validator = NewBlockValidator(chainConfig, bc, engine, EnableRemoteVerifyManager(vm)) + bc.validator = NewBlockValidator(chainConfig, bc, EnableRemoteVerifyManager(vm)) } return bc, nil } diff --git a/core/blockchain_insert.go b/core/blockchain_insert.go index 263074275b..15a5200ae6 100644 --- a/core/blockchain_insert.go +++ b/core/blockchain_insert.go @@ -178,7 +178,7 @@ func (it *insertIterator) current() *types.Header { return it.chain[it.index].Header() } -// first returns the first block in the it. +// first returns the first block in it. func (it *insertIterator) first() *types.Block { return it.chain[0] } diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 44fbe2e20e..eb8fdfd987 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -309,6 +309,9 @@ func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, max // transaction indexing is already finished. The transaction is not existent // from the node's perspective. func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction, error) { + bc.txLookupLock.RLock() + defer bc.txLookupLock.RUnlock() + // Short circuit if the txlookup already in the cache, retrieve otherwise if item, exist := bc.txLookupCache.Get(hash); exist { return item.lookup, item.transaction, nil @@ -351,7 +354,7 @@ func (bc *BlockChain) HasState(hash common.Hash) bool { if bc.NoTries() { return bc.snaps != nil && bc.snaps.Snapshot(hash) != nil } - _, err := bc.stateCache.OpenTrie(hash) + _, err := bc.statedb.OpenTrie(hash) return err == nil } @@ -384,12 +387,9 @@ func (bc *BlockChain) stateRecoverable(root common.Hash) bool { // If the code doesn't exist in the in-memory cache, check the storage with // new code scheme. func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) { - type codeReader interface { - ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) - } // TODO(rjl493456442) The associated account address is also required // in Verkle scheme. Fix it once snap-sync is supported for Verkle. - return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash) + return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash) } // State returns a new mutable state based on the current HEAD block. @@ -399,7 +399,7 @@ func (bc *BlockChain) State() (*state.StateDB, error) { // StateAt returns a new mutable state based on a particular point in time. func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { - stateDb, err := state.New(root, bc.stateCache, bc.snaps) + stateDb, err := state.New(root, bc.statedb) if err != nil { return nil, err } @@ -438,7 +438,7 @@ func (bc *BlockChain) Processor() Processor { // StateCache returns the caching database underpinning the blockchain instance. func (bc *BlockChain) StateCache() state.Database { - return bc.stateCache + return bc.statedb } // GasLimit returns the gas limit of the current HEAD block. diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 170fbf3689..ceec32be08 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -22,7 +22,7 @@ package core import ( "math/big" - "path" + "path/filepath" "testing" "time" @@ -1759,12 +1759,12 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme string) { // It's hard to follow the test case, visualize the input - //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump(true)) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(tt.dump(false)) // Create a temporary persistent database datadir := t.TempDir() - ancient := path.Join(datadir, "ancient") + ancient := filepath.Join(datadir, "ancient") db, err := rawdb.Open(rawdb.OpenOptions{ Directory: datadir, @@ -1841,10 +1841,14 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s } // Force run a freeze cycle type freezer interface { - Freeze(threshold uint64) error + Freeze() error Ancients() (uint64, error) } - db.(freezer).Freeze(tt.freezeThreshold) + if tt.freezeThreshold < uint64(tt.canonicalBlocks) { + final := uint64(tt.canonicalBlocks) - tt.freezeThreshold + chain.SetFinalized(canonblocks[int(final)-1].Header()) + } + db.(freezer).Freeze() // Set the simulated pivot block if tt.pivotBlock != nil { @@ -1915,11 +1919,11 @@ func TestIssue23496(t *testing.T) { func testIssue23496(t *testing.T, scheme string) { // It's hard to follow the test case, visualize the input - //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) // Create a temporary persistent database datadir := t.TempDir() - ancient := path.Join(datadir, "ancient") + ancient := filepath.Join(datadir, "ancient") db, err := rawdb.Open(rawdb.OpenOptions{ Directory: datadir, diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 3faa19226c..c4e63bb855 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -22,7 +22,7 @@ package core import ( "fmt" "math/big" - "path" + "path/filepath" "strings" "testing" "time" @@ -1963,12 +1963,12 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) { func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme string) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) // fmt.Println(tt.dump(false)) // Create a temporary persistent database datadir := t.TempDir() - ancient := path.Join(datadir, "ancient") + ancient := filepath.Join(datadir, "ancient") db, err := rawdb.Open(rawdb.OpenOptions{ Directory: datadir, @@ -2050,14 +2050,18 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme dbconfig.HashDB = hashdb.Defaults } chain.triedb = triedb.NewDatabase(chain.db, dbconfig) - chain.stateCache = state.NewDatabaseWithNodeDB(chain.db, chain.triedb) + chain.statedb = state.NewDatabase(chain.triedb, chain.snaps) // Force run a freeze cycle type freezer interface { - Freeze(threshold uint64) error + Freeze() error Ancients() (uint64, error) } - db.(freezer).Freeze(tt.freezeThreshold) + if tt.freezeThreshold < uint64(tt.canonicalBlocks) { + final := uint64(tt.canonicalBlocks) - tt.freezeThreshold + chain.SetFinalized(canonblocks[int(final)-1].Header()) + } + db.(freezer).Freeze() // Set the simulated pivot block if tt.pivotBlock != nil { diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index b2dbe5cb2a..696e510997 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -24,7 +24,7 @@ import ( "fmt" "math/big" "os" - "path" + "path/filepath" "strings" "testing" "time" @@ -63,7 +63,7 @@ type snapshotTestBasic struct { func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Block) { // Create a temporary persistent database datadir := t.TempDir() - ancient := path.Join(datadir, "ancient") + ancient := filepath.Join(datadir, "ancient") db, err := rawdb.Open(rawdb.OpenOptions{ Directory: datadir, @@ -222,8 +222,8 @@ type snapshotTest struct { func (snaptest *snapshotTest) test(t *testing.T) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump()) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(snaptest.dump()) chain, blocks := snaptest.prepare(t) // Restart the chain normally @@ -245,8 +245,8 @@ type crashSnapshotTest struct { func (snaptest *crashSnapshotTest) test(t *testing.T) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump()) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(snaptest.dump()) chain, blocks := snaptest.prepare(t) // Pull the plug on the database, simulating a hard crash @@ -297,8 +297,8 @@ type gappedSnapshotTest struct { func (snaptest *gappedSnapshotTest) test(t *testing.T) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump()) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(snaptest.dump()) chain, blocks := snaptest.prepare(t) // Insert blocks without enabling snapshot if gapping is required. @@ -342,8 +342,8 @@ type setHeadSnapshotTest struct { func (snaptest *setHeadSnapshotTest) test(t *testing.T) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump()) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(snaptest.dump()) chain, blocks := snaptest.prepare(t) // Rewind the chain if setHead operation is required. @@ -371,8 +371,8 @@ type wipeCrashSnapshotTest struct { func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) { // It's hard to follow the test case, visualize the input - // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - // fmt.Println(tt.dump()) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) + // fmt.Println(snaptest.dump()) chain, blocks := snaptest.prepare(t) // Firstly, stop the chain properly, with all snapshot journal diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 8d1b8bc453..00f5999ecb 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -52,8 +52,6 @@ import ( var ( canonicalSeed = 1 forkSeed = 2 - - TestTriesInMemory = 128 ) // newCanonical creates a chain database, and injects a deterministic canonical @@ -166,19 +164,19 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { } return err } - statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil) + statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.statedb) if err != nil { return err } statedb.SetExpectedStateRoot(block.Root()) - statedb, receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{}) + res, err := blockchain.processor.Process(block, statedb, vm.Config{}) if err != nil { - blockchain.reportBlock(block, receipts, err) + blockchain.reportBlock(block, res, err) return err } - err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas) + err = blockchain.validator.ValidateState(block, statedb, res, false) if err != nil { - blockchain.reportBlock(block, receipts, err) + blockchain.reportBlock(block, res, err) return err } @@ -670,108 +668,6 @@ func testReorg(t *testing.T, first, second []int64, td int64, full bool, scheme } } -// Tests that the insertion functions detect banned hashes. -func TestBadHeaderHashes(t *testing.T) { - testBadHashes(t, false, rawdb.HashScheme) - testBadHashes(t, false, rawdb.PathScheme) -} - -func TestBadBlockHashes(t *testing.T) { - testBadHashes(t, true, rawdb.HashScheme) - testBadHashes(t, true, rawdb.PathScheme) -} - -func testBadHashes(t *testing.T, full bool, scheme string) { - // Create a pristine chain and database - genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme) - if err != nil { - t.Fatalf("failed to create pristine chain: %v", err) - } - defer blockchain.Stop() - - // Create a chain, ban a hash and try to import - if full { - blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 3, ethash.NewFaker(), genDb, 10) - - BadHashes[blocks[2].Header().Hash()] = true - defer func() { delete(BadHashes, blocks[2].Header().Hash()) }() - - _, err = blockchain.InsertChain(blocks) - } else { - headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 3, ethash.NewFaker(), genDb, 10) - - BadHashes[headers[2].Hash()] = true - defer func() { delete(BadHashes, headers[2].Hash()) }() - - _, err = blockchain.InsertHeaderChain(headers) - } - if !errors.Is(err, ErrBannedHash) { - t.Errorf("error mismatch: have: %v, want: %v", err, ErrBannedHash) - } -} - -// Tests that bad hashes are detected on boot, and the chain rolled back to a -// good state prior to the bad hash. -func TestReorgBadHeaderHashes(t *testing.T) { - testReorgBadHashes(t, false, rawdb.HashScheme) - testReorgBadHashes(t, false, rawdb.PathScheme) -} -func TestReorgBadBlockHashes(t *testing.T) { - testReorgBadHashes(t, true, rawdb.HashScheme) - testReorgBadHashes(t, true, rawdb.PathScheme) -} - -func testReorgBadHashes(t *testing.T, full bool, scheme string) { - // Create a pristine chain and database - genDb, gspec, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme) - if err != nil { - t.Fatalf("failed to create pristine chain: %v", err) - } - // Create a chain, import and ban afterwards - headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 4, ethash.NewFaker(), genDb, 10) - blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 4, ethash.NewFaker(), genDb, 10) - - if full { - if _, err = blockchain.InsertChain(blocks); err != nil { - t.Errorf("failed to import blocks: %v", err) - } - if blockchain.CurrentBlock().Hash() != blocks[3].Hash() { - t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash()) - } - BadHashes[blocks[3].Header().Hash()] = true - defer func() { delete(BadHashes, blocks[3].Header().Hash()) }() - } else { - if _, err = blockchain.InsertHeaderChain(headers); err != nil { - t.Errorf("failed to import headers: %v", err) - } - if blockchain.CurrentHeader().Hash() != headers[3].Hash() { - t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash()) - } - BadHashes[headers[3].Hash()] = true - defer func() { delete(BadHashes, headers[3].Hash()) }() - } - blockchain.Stop() - - // Create a new BlockChain and check that it rolled back the state. - ncm, err := NewBlockChain(blockchain.db, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) - if err != nil { - t.Fatalf("failed to create new chain manager: %v", err) - } - if full { - if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { - t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) - } - if blocks[2].Header().GasLimit != ncm.GasLimit() { - t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit) - } - } else { - if ncm.CurrentHeader().Hash() != headers[2].Hash() { - t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash()) - } - } - ncm.Stop() -} - // Tests chain insertions in the face of one entity containing an invalid nonce. func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false, rawdb.HashScheme) @@ -899,7 +795,7 @@ func testFastVsFullChains(t *testing.T, scheme string) { t.Fatalf("failed to insert receipt %d: %v", n, err) } // Freezer style fast import the chain. - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -989,12 +885,12 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) { BaseFee: big.NewInt(params.InitialBaseFee), } ) - height := uint64(1024) + height := uint64(64) _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) // makeDb creates a db instance for testing. makeDb := func() ethdb.Database { - db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(),"", "", false, false, false, false, false) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -1826,7 +1722,7 @@ func TestTrieForkGC(t *testing.T) { Config: params.TestChainConfig, BaseFee: big.NewInt(params.InitialBaseFee), } - genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) + genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) // Generate a bunch of fork blocks, each side forking from the canonical chain forks := make([]*types.Block, len(blocks)) @@ -1854,7 +1750,7 @@ func TestTrieForkGC(t *testing.T) { } } // Dereference all the recent tries and ensure no past trie is left in - for i := 0; i < TriesInMemory; i++ { + for i := 0; i < state.TriesInMemory; i++ { chain.TrieDB().Dereference(blocks[len(blocks)-1-i].Root()) chain.TrieDB().Dereference(forks[len(blocks)-1-i].Root()) } @@ -1878,11 +1774,11 @@ func testLargeReorgTrieGC(t *testing.T, scheme string) { BaseFee: big.NewInt(params.InitialBaseFee), } genDb, shared, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) - original, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) - competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) + original, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) + competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) // Import the shared chain and the original canonical one - db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) defer db.Close() chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil) @@ -1918,7 +1814,7 @@ func testLargeReorgTrieGC(t *testing.T, scheme string) { } // In path-based trie database implementation, it will keep 128 diff + 1 disk // layers, totally 129 latest states available. In hash-based it's 128. - states := TestTriesInMemory + states := state.TriesInMemory if scheme == rawdb.PathScheme { states = states + 1 } @@ -1947,7 +1843,7 @@ func testBlockchainRecovery(t *testing.T, scheme string) { funds = big.NewInt(1000000000) gspec = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{address: {Balance: funds}}} ) - height := uint64(1024) + height := uint64(64) _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) // Import the chain as a ancient-first node and ensure all pointers are updated @@ -2022,7 +1918,7 @@ func testInsertReceiptChainRollback(t *testing.T, scheme string) { } // Set up a BlockChain that uses the ancient store. - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "",, "", false, false, false, false, false) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2086,13 +1982,13 @@ func testLowDiffLongChain(t *testing.T, scheme string) { } // We must use a pretty long chain to ensure that the fork doesn't overtake us // until after at least 128 blocks post tip - genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 6*TriesInMemory, func(i int, b *BlockGen) { + genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 6*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) b.OffsetTime(-9) }) // Import the canonical chain - diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) defer diskdb.Close() chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil) @@ -2106,7 +2002,7 @@ func testLowDiffLongChain(t *testing.T, scheme string) { } // Generate fork chain, starting from an early block parent := blocks[10] - fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 8*TriesInMemory, func(i int, b *BlockGen) { + fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 8*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) @@ -2142,7 +2038,6 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // Generate a canonical chain to act as the main dataset chainConfig := *params.TestChainConfig var ( - merger = consensus.NewMerger(rawdb.NewMemoryDatabase()) engine = beacon.New(ethash.NewFaker()) key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key.PublicKey) @@ -2166,13 +2061,11 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // Activate the transition since genesis if required if mergePoint == 0 { mergeBlock = 0 - merger.ReachTTD() - merger.FinalizePoS() // Set the terminal total difficulty in the config gspec.Config.TerminalTotalDifficulty = big.NewInt(0) } - genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { + genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*state.TriesInMemory, func(i int, gen *BlockGen) { tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key) if err != nil { t.Fatalf("failed to create tx: %v", err) @@ -2187,9 +2080,9 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon t.Fatalf("block %d: failed to insert into chain: %v", n, err) } - lastPrunedIndex := len(blocks) - TestTriesInMemory - 1 + lastPrunedIndex := len(blocks) - state.TriesInMemory - 1 lastPrunedBlock := blocks[lastPrunedIndex-1] - firstNonPrunedBlock := blocks[len(blocks)-TestTriesInMemory] + firstNonPrunedBlock := blocks[len(blocks)-state.TriesInMemory] // Verify pruning of lastPrunedBlock if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) { @@ -2202,8 +2095,6 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // Activate the transition in the middle of the chain if mergePoint == 1 { - merger.ReachTTD() - merger.FinalizePoS() // Set the terminal total difficulty in the config ttd := big.NewInt(int64(len(blocks))) ttd.Mul(ttd, params.GenesisDifficulty) @@ -2218,7 +2109,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // Generate fork chain, make it longer than canon parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock parent := blocks[parentIndex] - fork, _ := GenerateChain(gspec.Config, parent, engine, genDb, 2*TriesInMemory, func(i int, b *BlockGen) { + fork, _ := GenerateChain(gspec.Config, parent, engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) if int(b.header.Number.Uint64()) >= mergeBlock { b.SetPoS() @@ -2252,9 +2143,9 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // [ Cn, Cn+1, Cc, Sn+3 ... Sm] // ^ ^ ^ pruned func TestPrunedImportSide(t *testing.T) { - //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) - //glogger.Verbosity(3) - //log.Root().SetHandler(log.Handler(glogger)) + // glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false)) + // glogger.Verbosity(3) + // log.SetDefault(log.NewLogger(glogger)) testSideImport(t, 3, 3, -1) testSideImport(t, 3, -3, -1) testSideImport(t, 10, 0, -1) @@ -2263,9 +2154,9 @@ func TestPrunedImportSide(t *testing.T) { } func TestPrunedImportSideWithMerging(t *testing.T) { - //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) - //glogger.Verbosity(3) - //log.Root().SetHandler(log.Handler(glogger)) + // glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false)) + // glogger.Verbosity(3) + // log.SetDefault(log.NewLogger(glogger)) testSideImport(t, 3, 3, 0) testSideImport(t, 3, -3, 0) testSideImport(t, 10, 0, 0) @@ -2309,7 +2200,7 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) { b.OffsetTime(-9) // A higher difficulty }) // Import the shared chain and the original canonical one - chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2480,7 +2371,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i } }) // Import the shared chain and the original canonical one - chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2861,7 +2752,7 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) { BaseFee: big.NewInt(params.InitialBaseFee), } // Generate and import the canonical chain - _, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*TriesInMemory, nil) + _, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, nil) chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil) if err != nil { @@ -2874,9 +2765,9 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) { } // In path-based trie database implementation, it will keep 128 diff + 1 disk // layers, totally 129 latest states available. In hash-based it's 128. - states := TestTriesInMemory + states := state.TriesInMemory if scheme == rawdb.PathScheme { - states = TestTriesInMemory + 1 + states = state.TriesInMemory + 1 } lastPrunedIndex := len(blocks) - states - 1 lastPrunedBlock := blocks[lastPrunedIndex] @@ -3761,7 +3652,7 @@ func TestSetCanonical(t *testing.T) { } func testSetCanonical(t *testing.T, scheme string) { - //log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) var ( key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -3772,18 +3663,19 @@ func testSetCanonical(t *testing.T, scheme string) { Alloc: types.GenesisAlloc{address: {Balance: funds}}, BaseFee: big.NewInt(params.InitialBaseFee), } - signer = types.LatestSigner(gspec.Config) - engine = ethash.NewFaker() + signer = types.LatestSigner(gspec.Config) + engine = ethash.NewFaker() + chainLength = 10 ) // Generate and import the canonical chain - _, canon, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { + _, canon, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) { tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key) if err != nil { panic(err) } gen.AddTx(tx) }) - diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) + diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) defer diskdb.Close() chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil) @@ -3797,7 +3689,7 @@ func testSetCanonical(t *testing.T, scheme string) { } // Generate the side chain and import them - _, side, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { + _, side, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) { tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1), params.TxGas, gen.header.BaseFee, nil), signer, key) if err != nil { panic(err) @@ -3805,7 +3697,7 @@ func testSetCanonical(t *testing.T, scheme string) { gen.AddTx(tx) }) for _, block := range side { - err := chain.InsertBlockWithoutSetHead(block) + _, err := chain.InsertBlockWithoutSetHead(block, false) if err != nil { t.Fatalf("Failed to insert into chain: %v", err) } @@ -3836,8 +3728,8 @@ func testSetCanonical(t *testing.T, scheme string) { verify(side[len(side)-1]) // Reset the chain head to original chain - chain.SetCanonical(canon[TriesInMemory-1]) - verify(canon[TriesInMemory-1]) + chain.SetCanonical(canon[chainLength-1]) + verify(canon[chainLength-1]) } // TestCanonicalHashMarker tests all the canonical hash markers are updated/deleted @@ -4324,7 +4216,7 @@ func TestEIP3651(t *testing.T) { b.AddTx(tx) }) - chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr)}, nil, nil) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr).Hooks()}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -4489,3 +4381,90 @@ func makeMockTx(config *params.ChainConfig, signer types.Signer, key *ecdsa.Priv tx, _ := types.SignTx(types.NewTx(raw), signer, key) return tx, sidecar } + +func TestEIP6110(t *testing.T) { + var ( + engine = beacon.NewFaker() + + // A sender who makes transactions, has some funds + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key.PublicKey) + funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + config = *params.AllEthashProtocolChanges + gspec = &Genesis{ + Config: &config, + Alloc: types.GenesisAlloc{ + addr: {Balance: funds}, + config.DepositContractAddress: { + // Simple deposit generator, source: https://gist.github.com/lightclient/54abb2af2465d6969fa6d1920b9ad9d7 + Code: common.Hex2Bytes("6080604052366103aa575f603067ffffffffffffffff811115610025576100246103ae565b5b6040519080825280601f01601f1916602001820160405280156100575781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061007d5761007c6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f602067ffffffffffffffff8111156100c7576100c66103ae565b5b6040519080825280601f01601f1916602001820160405280156100f95781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061011f5761011e6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff811115610169576101686103ae565b5b6040519080825280601f01601f19166020018201604052801561019b5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f815181106101c1576101c06103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f606067ffffffffffffffff81111561020b5761020a6103ae565b5b6040519080825280601f01601f19166020018201604052801561023d5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610263576102626103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff8111156102ad576102ac6103ae565b5b6040519080825280601f01601f1916602001820160405280156102df5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610305576103046103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f8081819054906101000a900460ff168092919061035090610441565b91906101000a81548160ff021916908360ff160217905550507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c585858585856040516103a09594939291906104d9565b60405180910390a1005b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f60ff82169050919050565b5f61044b82610435565b915060ff820361045e5761045d610408565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6104ab82610469565b6104b58185610473565b93506104c5818560208601610483565b6104ce81610491565b840191505092915050565b5f60a0820190508181035f8301526104f181886104a1565b9050818103602083015261050581876104a1565b9050818103604083015261051981866104a1565b9050818103606083015261052d81856104a1565b9050818103608083015261054181846104a1565b9050969550505050505056fea26469706673582212208569967e58690162d7d6fe3513d07b393b4c15e70f41505cbbfd08f53eba739364736f6c63430008190033"), + Nonce: 0, + Balance: big.NewInt(0), + }, + }, + } + ) + + gspec.Config.BerlinBlock = common.Big0 + gspec.Config.LondonBlock = common.Big0 + gspec.Config.TerminalTotalDifficulty = common.Big0 + gspec.Config.TerminalTotalDifficultyPassed = true + gspec.Config.ShanghaiTime = u64(0) + gspec.Config.CancunTime = u64(0) + gspec.Config.PragueTime = u64(0) + signer := types.LatestSigner(gspec.Config) + + _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { + for i := 0; i < 5; i++ { + txdata := &types.DynamicFeeTx{ + ChainID: gspec.Config.ChainID, + Nonce: uint64(i), + To: &config.DepositContractAddress, + Gas: 500000, + GasFeeCap: newGwei(5), + GasTipCap: big.NewInt(2), + AccessList: nil, + Data: []byte{}, + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key) + b.AddTx(tx) + } + }) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{DisableStack: true}, os.Stderr).Hooks()}, nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + defer chain.Stop() + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + block := chain.GetBlockByNumber(1) + if len(block.Requests()) != 5 { + t.Fatalf("failed to retrieve deposits: have %d, want %d", len(block.Requests()), 5) + } + + // Verify each index is correct. + for want, req := range block.Requests() { + d, ok := req.Inner().(*types.Deposit) + if !ok { + t.Fatalf("expected deposit object") + } + if got := int(d.PublicKey[0]); got != want { + t.Fatalf("invalid pubkey: have %d, want %d", got, want) + } + if got := int(d.WithdrawalCredentials[0]); got != want { + t.Fatalf("invalid withdrawal credentials: have %d, want %d", got, want) + } + if d.Amount != uint64(want) { + t.Fatalf("invalid amounbt: have %d, want %d", d.Amount, want) + } + if got := int(d.Signature[0]); got != want { + t.Fatalf("invalid signature: have %d, want %d", got, want) + } + if d.Index != uint64(want) { + t.Fatalf("invalid index: have %d, want %d", d.Index, want) + } + } +} diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go index 840d0fca20..4c15c50ad9 100644 --- a/core/bloombits/matcher.go +++ b/core/bloombits/matcher.go @@ -599,6 +599,9 @@ func (s *MatcherSession) deliverSections(bit uint, sections []uint64, bitsets [] // of the session, any request in-flight need to be responded to! Empty responses // are fine though in that case. func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) { + waitTimer := time.NewTimer(wait) + defer waitTimer.Stop() + for { // Allocate a new bloom bit index to retrieve data for, stopping when done bit, ok := s.allocateRetrieval() @@ -607,6 +610,7 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan } // Bit allocated, throttle a bit if we're below our batch limit if s.pendingSections(bit) < batch { + waitTimer.Reset(wait) select { case <-s.quit: // Session terminating, we can't meaningfully service, abort @@ -614,7 +618,7 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan s.deliverSections(bit, []uint64{}, [][]byte{}) return - case <-time.After(wait): + case <-waitTimer.C: // Throttling up, fetch whatever is available } } diff --git a/core/bloombits/scheduler.go b/core/bloombits/scheduler.go index 5fa6248110..e4503be3f1 100644 --- a/core/bloombits/scheduler.go +++ b/core/bloombits/scheduler.go @@ -25,7 +25,7 @@ import ( // request represents a bloom retrieval task to prioritize and pull from the local // database or remotely from the network. type request struct { - section uint64 // Section index to retrieve the a bit-vector from + section uint64 // Section index to retrieve the bit-vector from bit uint // Bit index within the section to retrieve the vector of } diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go index f099609015..bf3bde756c 100644 --- a/core/chain_indexer_test.go +++ b/core/chain_indexer_test.go @@ -228,7 +228,7 @@ func (b *testChainIndexBackend) Process(ctx context.Context, header *types.Heade b.t.Error("Unexpected call to Process") // Can't use Fatal since this is not the test's goroutine. // Returning error stops the chainIndexer's updateLoop - return errors.New("Unexpected call to Process") + return errors.New("unexpected call to Process") case b.processCh <- header.Number.Uint64(): } return nil diff --git a/core/chain_makers.go b/core/chain_makers.go index 29306c5222..c80eb77c40 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/triedb" + "github.com/ethereum/go-verkle" "github.com/holiman/uint256" ) @@ -368,6 +369,17 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse gen(i, b) } if b.engine != nil { + var requests types.Requests + if config.IsPrague(b.header.Number, b.header.Time) { + for _, r := range b.receipts { + d, err := ParseDepositLogs(r.Logs, config) + if err != nil { + panic(fmt.Sprintf("failed to parse deposit log: %v", err)) + } + requests = append(requests, d...) + } + } + block, _, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals) if err != nil { panic(err) @@ -384,7 +396,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } // Write state changes to db - root, _, err := statedb.Commit(b.header.Number.Uint64(), nil) + root, _, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number)) if err != nil { panic(fmt.Sprintf("state write error: %v", err)) } @@ -401,7 +413,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse defer triedb.Close() for i := 0; i < n; i++ { - statedb, err := state.New(parent.Root(), state.NewDatabaseWithNodeDB(db, triedb), nil) + statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, nil)) if err != nil { panic(err) } @@ -452,6 +464,111 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, return db, blocks, receipts } +func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, trdb *triedb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { + if config == nil { + config = params.TestChainConfig + } + proofs := make([]*verkle.VerkleProof, 0, n) + keyvals := make([]verkle.StateDiff, 0, n) + cm := newChainMaker(parent, config, engine) + + genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { + b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} + b.header = cm.makeHeader(parent, statedb, b.engine) + + // TODO uncomment when proof generation is merged + // Save pre state for proof generation + // preState := statedb.Copy() + + // TODO uncomment when the 2935 PR is merged + // if config.IsPrague(b.header.Number, b.header.Time) { + // if !config.IsPrague(b.parent.Number(), b.parent.Time()) { + // Transition case: insert all 256 ancestors + // InsertBlockHashHistoryAtEip2935Fork(statedb, b.header.Number.Uint64()-1, b.header.ParentHash, chainreader) + // } else { + // ProcessParentBlockHash(statedb, b.header.Number.Uint64()-1, b.header.ParentHash) + // } + // } + // Execute any user modifications to the block + if gen != nil { + gen(i, b) + } + body := &types.Body{ + Transactions: b.txs, + Uncles: b.uncles, + Withdrawals: b.withdrawals, + } + block, _, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, body.Transactions, body.Uncles, b.receipts, body.Withdrawals) + if err != nil { + panic(err) + } + + // Write state changes to db + root, _, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number)) + if err != nil { + panic(fmt.Sprintf("state write error: %v", err)) + } + if err = triedb.Commit(root, false); err != nil { + panic(fmt.Sprintf("trie write error: %v", err)) + } + + proofs = append(proofs, block.ExecutionWitness().VerkleProof) + keyvals = append(keyvals, block.ExecutionWitness().StateDiff) + + return block, b.receipts + } + + for i := 0; i < n; i++ { + statedb, err := state.New(parent.Root(), state.NewDatabase(trdb, nil)) + if err != nil { + panic(err) + } + block, receipts := genblock(i, parent, trdb, statedb) + + // Post-process the receipts. + // Here we assign the final block hash and other info into the receipt. + // In order for DeriveFields to work, the transaction and receipt lists need to be + // of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be + // extra ones, so we just trim the lists here. + receiptsCount := len(receipts) + txs := block.Transactions() + if len(receipts) > len(txs) { + receipts = receipts[:len(txs)] + } else if len(receipts) < len(txs) { + txs = txs[:len(receipts)] + } + var blobGasPrice *big.Int + if block.ExcessBlobGas() != nil { + blobGasPrice = eip4844.CalcBlobFee(*block.ExcessBlobGas()) + } + if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { + panic(err) + } + + // Re-expand to ensure all receipts are returned. + receipts = receipts[:receiptsCount] + + // Advance the chain. + cm.add(block, receipts) + parent = block + } + return cm.chain, cm.receipts, proofs, keyvals +} + +func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { + db := rawdb.NewMemoryDatabase() + cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme) + cacheConfig.SnapshotLimit = 0 + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) + defer triedb.Close() + genesisBlock, err := genesis.Commit(db, triedb) + if err != nil { + panic(err) + } + blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, n, gen) + return db, blocks, receipts, proofs, keyvals +} + func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { time := parent.Time() + 10 // block time is fixed at 10 seconds header := &types.Header{ @@ -521,7 +638,7 @@ func makeBlockChain(chainConfig *params.ChainConfig, parent *types.Block, n int, return blocks } -// makeBlockChain creates a deterministic chain of blocks from genesis +// makeBlockChainWithGenesis creates a deterministic chain of blocks from genesis func makeBlockChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine, seed int) (ethdb.Database, []*types.Block) { db, blocks, _ := GenerateChainWithGenesis(genesis, engine, n, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index a2ec9e6507..6241f3fb69 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -43,12 +43,11 @@ func TestGeneratePOSChain(t *testing.T) { bb = common.Address{0xbb} funds = big.NewInt(0).Mul(big.NewInt(1337), big.NewInt(params.Ether)) config = *params.AllEthashProtocolChanges - asm4788 = common.Hex2Bytes("3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") gspec = &Genesis{ Config: &config, Alloc: types.GenesisAlloc{ address: {Balance: funds}, - params.BeaconRootsAddress: {Balance: common.Big0, Code: asm4788}, + params.BeaconRootsAddress: {Code: params.BeaconRootsCode}, }, BaseFee: big.NewInt(params.InitialBaseFee), Difficulty: common.Big1, diff --git a/core/data_availability.go b/core/data_availability.go index 2953c8c369..92fc42fd03 100644 --- a/core/data_availability.go +++ b/core/data_availability.go @@ -44,7 +44,7 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobSidecar) error // Blob commitments match with the hashes in the transaction, verify the // blobs themselves via KZG for i := range sidecar.Blobs { - if err := kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { + if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { return fmt.Errorf("invalid blob %d: %v", i, err) } } diff --git a/core/error.go b/core/error.go index ca0f0b9d00..088ce0f620 100644 --- a/core/error.go +++ b/core/error.go @@ -26,9 +26,6 @@ var ( // ErrKnownBlock is returned when a block to import is already known locally. ErrKnownBlock = errors.New("block already known") - // ErrBannedHash is returned if a block to import is on the banned list. - ErrBannedHash = errors.New("banned hash") - // ErrNoGenesis is returned when there is no Genesis Block. ErrNoGenesis = errors.New("genesis not found in chain") @@ -73,6 +70,11 @@ var ( // than init code size limit. ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") + // ErrInsufficientBalanceWitness is returned if the transaction sender has enough + // funds to cover the transfer, but not enough to pay for witness access/modification + // costs for the transaction + ErrInsufficientBalanceWitness = errors.New("insufficient funds to cover witness access costs for transaction") + // ErrInsufficientFunds is returned if the total cost of executing a transaction // is higher than the balance of the user's account. ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") diff --git a/core/evm.go b/core/evm.go index 73f6d7bc20..5d3c454d7c 100644 --- a/core/evm.go +++ b/core/evm.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/holiman/uint256" @@ -58,7 +59,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common if header.ExcessBlobGas != nil { blobBaseFee = eip4844.CalcBlobFee(*header.ExcessBlobGas) } - if header.Difficulty.Cmp(common.Big0) == 0 { + if header.Difficulty.Sign() == 0 { random = &header.MixDigest } return vm.BlockContext{ @@ -136,6 +137,6 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *uint256.Int) bool { // Transfer subtracts amount from sender and adds amount to recipient using the given Db func Transfer(db vm.StateDB, sender, recipient common.Address, amount *uint256.Int) { - db.SubBalance(sender, amount) - db.AddBalance(recipient, amount) + db.SubBalance(sender, amount, tracing.BalanceChangeTransfer) + db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer) } diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go index 1000b18530..f2c2a0887a 100644 --- a/core/forkid/forkid.go +++ b/core/forkid/forkid.go @@ -24,13 +24,13 @@ import ( "math" "math/big" "reflect" + "slices" "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "golang.org/x/exp/slices" ) var ( diff --git a/core/genesis.go b/core/genesis.go index e06938f327..89fc2d41ae 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -45,7 +46,7 @@ import ( var errGenesisNoConfig = errors.New("genesis has no chain configuration") -// Deprecated: use types.GenesisAccount instead. +// Deprecated: use types.Account instead. type GenesisAccount = types.Account // Deprecated: use types.GenesisAlloc instead. @@ -126,14 +127,14 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { } // Create an ephemeral in-memory database for computing hash, // all the derived states will be discarded to not pollute disk. - db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), config) - statedb, err := state.New(types.EmptyRootHash, db, nil) + db := rawdb.NewMemoryDatabase() + statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb.NewDatabase(db, config), nil)) if err != nil { return common.Hash{}, err } for addr, account := range *ga { if account.Balance != nil { - statedb.AddBalance(addr, uint256.MustFromBig(account.Balance)) + statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } statedb.SetCode(addr, account.Code) statedb.SetNonce(addr, account.Nonce) @@ -141,26 +142,26 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { statedb.SetState(addr, key, value) } } - statedb.IntermediateRoot(false) - root, _, err := statedb.Commit(0, nil) + root, _, err := statedb.Commit(0, false) return root, err } -// flushAlloc is very similar with hash, but the main difference is all the generated -// states will be persisted into the given database. Also, the genesis state -// specification will be flushed as well. -func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *triedb.Database, blockhash common.Hash) error { +// flushAlloc is very similar with hash, but the main difference is all the +// generated states will be persisted into the given database. +func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) { triedbConfig := triedb.Config() if triedbConfig != nil { triedbConfig.NoTries = false } - statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil) + statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb, nil)) if err != nil { - return err + return common.Hash{}, err } for addr, account := range *ga { if account.Balance != nil { - statedb.AddBalance(addr, uint256.MustFromBig(account.Balance)) + // This is not actually logged via tracer because OnGenesisBlock + // already captures the allocations. + statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } statedb.SetCode(addr, account.Code) statedb.SetNonce(addr, account.Nonce) @@ -168,24 +169,44 @@ func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *triedb.Databa statedb.SetState(addr, key, value) } } - statedb.IntermediateRoot(false) - root, _, err := statedb.Commit(0, nil) + root, _, err := statedb.Commit(0, false) if err != nil { - return err + return common.Hash{}, err } // Commit newly generated states into disk if it's not empty. if root != types.EmptyRootHash { if err := triedb.Commit(root, true); err != nil { - return err + return common.Hash{}, err } } - // Marshal the genesis state specification and persist. - blob, err := json.Marshal(ga) - if err != nil { - return err + return root, nil +} + +func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.GenesisAlloc, err error) { + blob := rawdb.ReadGenesisStateSpec(db, blockhash) + if len(blob) != 0 { + if err := alloc.UnmarshalJSON(blob); err != nil { + return nil, err + } + + return alloc, nil + } + + // Genesis allocation is missing and there are several possibilities: + // the node is legacy which doesn't persist the genesis allocation or + // the persisted allocation is just lost. + // - supported networks(mainnet, testnets), recover with defined allocations + // - private network, can't recover + var genesis *Genesis + switch blockhash { + case params.MainnetGenesisHash: + genesis = DefaultGenesisBlock() + } + if genesis != nil { + return genesis.Alloc, nil } - rawdb.WriteGenesisStateSpec(db, blockhash, blob) - return nil + + return nil, nil } // field type overrides for gencodec @@ -275,6 +296,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g } else { log.Info("Writing custom genesis block") } + applyOverrides(genesis.Config) block, err := genesis.Commit(db, triedb) if err != nil { @@ -413,6 +435,11 @@ func (g *Genesis) ToBlock() *types.Block { if err != nil { panic(err) } + return g.toBlockWithRoot(root) +} + +// toBlockWithRoot constructs the genesis block with the given genesis state root. +func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { head := &types.Header{ Number: new(big.Int).SetUint64(g.Number), Nonce: types.EncodeNonce(g.Nonce), @@ -444,7 +471,10 @@ func (g *Genesis) ToBlock() *types.Block { } } } - var withdrawals []*types.Withdrawal + var ( + withdrawals []*types.Withdrawal + requests types.Requests + ) if conf := g.Config; conf != nil { num := big.NewInt(int64(g.Number)) if conf.Parlia == nil && conf.IsShanghai(num, g.Timestamp) { @@ -473,15 +503,18 @@ func (g *Genesis) ToBlock() *types.Block { head.BlobGasUsed = new(uint64) } } + if conf.IsPrague(num, g.Timestamp) { + head.RequestsHash = &types.EmptyRequestsHash + requests = make(types.Requests, 0) + } } - return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals) + return types.NewBlock(head, &types.Body{Withdrawals: withdrawals, Requests: requests}, nil, trie.NewStackTrie(nil)) } // Commit writes the block and state of a genesis specification to the database. // The block is committed as the canonical head block. func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) { - block := g.ToBlock() - if block.Number().Sign() != 0 { + if g.Number != 0 { return nil, errors.New("can't commit genesis block with number > 0") } config := g.Config @@ -491,15 +524,22 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo if err := config.CheckConfigForkOrder(); err != nil { return nil, err } - if config.Clique != nil && len(block.Extra()) < 32+crypto.SignatureLength { + if config.Clique != nil && len(g.ExtraData) < 32+crypto.SignatureLength { return nil, errors.New("can't start clique chain without signers") } - // All the checks has passed, flushAlloc the states derived from the genesis - // specification as well as the specification itself into the provided - // database. - if err := flushAlloc(&g.Alloc, db, triedb, block.Hash()); err != nil { + // flush the data to disk and compute the state root + root, err := flushAlloc(&g.Alloc, triedb) + if err != nil { + return nil, err + } + block := g.toBlockWithRoot(root) + + // Marshal the genesis state specification and persist. + blob, err := json.Marshal(g.Alloc) + if err != nil { return nil, err } + rawdb.WriteGenesisStateSpec(db, block.Hash(), blob) rawdb.WriteTd(db.BlockStore(), block.Hash(), block.NumberU64(), block.Difficulty()) rawdb.WriteBlock(db.BlockStore(), block) rawdb.WriteReceipts(db.BlockStore(), block.Hash(), block.NumberU64(), nil) @@ -575,7 +615,7 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { Config: &config, GasLimit: gasLimit, BaseFee: big.NewInt(params.InitialBaseFee), - Difficulty: big.NewInt(1), + Difficulty: big.NewInt(0), Alloc: map[common.Address]types.Account{ common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 @@ -586,6 +626,10 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b + // Pre-deploy EIP-4788 system contract + params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, + // Pre-deploy EIP-2935 history contract. + params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, }, } if faucet != nil { diff --git a/core/genesis_alloc.go b/core/genesis_alloc.go index 96d696ad64..765d70525a 100644 --- a/core/genesis_alloc.go +++ b/core/genesis_alloc.go @@ -22,7 +22,6 @@ package core // nolint: misspell const mainnetAllocData = "\xfa\x04]X\u0793\r\x83b\x011\x8e\u0189\x9agT\x06\x908'\x80t2\x80\x89\n\u05ce\xbcZ\xc6 \x00\x00\u0793\x17bC\x0e\xa9\u00e2nWI\xaf\xdbp\xda_x\u077b\x8c\x89\n\u05ce\xbcZ\xc6 \x00\x00\u0793\x1d\x14\x80K9\x9cn\xf8\x0edWoev`\x80O\xec\v\x89\u3bb5sr@\xa0\x00\x00\u07932@5\x87\x94{\x9f\x15b*h\xd1\x04\xd5M3\xdb\xd1\u0349\x043\x87Oc,\xc6\x00\x00\u0793I~\x92\xcd\xc0\xe0\xb9c\xd7R\xb2)j\u02c7\u0682\x8b$\x89\n\x8fd\x9f\xe7\xc6\x18\x00\x00\u0793K\xfb\xe1Tk\xc6\xc6[\\~\xaaU0K8\xbb\xfe\xc6\u04c9lk\x93[\x8b\xbd@\x00\x00\u0793Z\x9c\x03\xf6\x9d\x17\xd6l\xbb\x8a\xd7!\x00\x8a\x9e\xbb\xb86\xfb\x89lk\x93[\x8b\xbd@\x00\x00\u0793]\x0e\xe8\x15^\xc0\xa6\xffh\bU,\xa5\xf1k\xb5\xbe2:\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u0793v\"\xd8J#K\xb8\xb0x#\x0f\u03c4\xb6z\u9a2c\xae\x89%\xe1\xccQ\x99R\xf8\x00\x00\u0793{\x9f\xc3\x19\x05\xb4\x99K\x04\xc9\xe2\xcf\xdc^'pP?B\x89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u0793\u007fJ#\xca\x00\xcd\x04=%\u0088\x8c\x1a\xa5h\x8f\x81\xa3D\x89)\xf0\xa9[\xfb\xf7)\x00\x00\u0793\x869\u06bb\u3bac\x88{]\xc0\xe4>\x13\xbc\u0487\xd7l\x89\x10\xd0\xe3\xc8}n,\x00\x00\u0793\x89P\x86y\xab\xf8\xc7\x1b\xf6x\x16\x87\x12\x0e>j\x84XM\x89a\x94\x04\x9f0\xf7 \x00\x00\u0793\x8f\xc7\u02ed\xff\xbd\r\u007f\xe4O\x8d\xfd`\xa7\x9dr\x1a\x1c\x9c\x8965\u026d\xc5\u07a0\x00\x00\u0793\x95`\xa3\xdebxh\xf9\x1f\xa8\xbf\xe1\xc1\xb7\xaf\xaf\b\x18k\x89\x1cg\xf5\xf7\xba\xa0\xb0\x00\x00\u0793\x96\x97G\xf7\xa5\xb3\x06E\xfe\x00\xe4I\x01CZ\xce$\xcc7\x89\\(=A\x03\x94\x10\x00\x00\u0793\x9am}\xb3&g\x9bw\xc9\x03\x91\xa7Gm#\x8f;\xa3>\x89\n\xdaUGK\x814\x00\x00\u0793\x9e\xef\n\b\x86\x05n?i!\x18S\xb9\xb7E\u007f7\x82\u4262\xa8x\x06\x9b(\xe0\x00\x00\u0793\x9f\xdb\xf4N\x1fJcb\xb7i\u00daG_\x95\xa9l+\u01c9\x1e\x93\x12\x83\xcc\xc8P\x00\x00\u07d3\xa5y\u007fR\xc9\u054f\x18\x9f6\xb1\xd4]\x1b\xf6\x04\x1f/k\x8a\x01'\u0473F\x1a\xcd\x1a\x00\x00\u0793\xaaS\x81\xb2\x13\x8e\xbe\xff\xc1\x91\xd5\xd8\u00d1u;p\x98\u04895\xab\xb0\x9f\xfe\u07b6\x80\x00\u0793\xaa\xda%\xea\"\x86p\x9a\xbbB-A\x92?\u04c0\xcd\x04\u01c9#=\xf3)\x9far\x00\x00\u0793\xac\xbf\xb2\xf2ZT\x85\xc79\xefp\xa4N\xee\xeb|e\xa6o\x89\x05k\xc7^-c\x10\x00\x00\u07d3\xac\xc6\xf0\x82\xa4B\x82\x87d\xd1\x1fX\u0589J\xe4\b\xf0s\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u0793\xb2w\xb0\x99\xa8\xe8f\xca\x0e\xc6[\u02c7(O\xd1B\xa5\x82\x89j\xcb=\xf2~\x1f\x88\x00\x00\u0753\xbd\xd4\x01:\xa3\x1c\x04al+\xc9x_'\x88\xf9\x15g\x9b\x88\xb9\xf6]\x00\xf6<\x00\x00\u0793\xc2}c\xfd\xe2K\x92\xee\x8a\x1e~\xd5\xd2m\x8d\xc5\xc8;\x03\x89lk\x93[\x8b\xbd@\x00\x00\u0553\xc4\x0f\xe2\tT#P\x9b\x9f\u0677T21X\xaf#\x10\xf3\x80\u0793\xd7^\xd6\fwO\x8b:ZQs\xfb\x183\xadq\x05\xa2\u0649l\xb7\xe7Hg\xd5\xe6\x00\x00\u07d3\u05cd\x89\xb3_G'\x16\xec\xea\xfe\xbf`\x05'\u04e1\xf9i\x8a\x05\xe0T\x9c\x962\xe1\xd8\x00\x00\u0793\xda\xe2{5\v\xae \xc5e!$\xaf]\x8b\\\xba\x00\x1e\xc1\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u0793\xdc\x01\xcb\xf4Ix\xa4.\x8d\xe8\xe46\xed\xf9B\x05\u03f6\xec\x89O\x0f\xeb\xbc\u068c\xb4\x00\x00\u07d3\u607c-\x10\xdbb\u0785\x84\x83$I\"P4\x8e\x90\xbf\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d3\xf4c\xe17\xdc\xf6%\xfb\U000fc8de\u0298\u04b9h\xcf\u007f\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4\x01\x00\a9K\x8bue\xa1e\x8a\xf8\x8c\xe4cI\x915\u05b7\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x01\r\xf1\xdfK\xed#v\r-\x1c\x03x\x15\x86\xdd\xf7\x91\x8eT\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94\x01\x0fJ\x98\u07e1\xd9y\x9b\xf5\u01d6\xfbU\x0e\xfb\xe7\xec\xd8w\x8a\x01\xb2\xf2\x92#b\x92\xc7\x00\x00\u07d4\x01\x15PW\x00/k\r\x18\xac\xb98\x8d;\xc8\x12\x9f\x8fz \x89H\xa4\xa9\x0f\xb4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x01k`\xbbmg\x92\x8c)\xfd\x03\x13\xc6f\u068f\x16\x98\xd9\u0149lk\x93[\x8b\xbd@\x00\x00\u07d4\x01l\x85\xe1a;\x90\x0f\xa3W\xb8(;\x12\x0ee\xae\xfc\xdd\b\x89+]\x97\x84\xa9|\xd5\x00\x00\u07d4\x01\x84\x92H\x8b\xa1\xa2\x924\"G\xb3\x18U\xa5Y\x05\xfe\xf2i\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\x01\x8f \xa2{'\xecD\x1a\xf7#\xfd\x90\x99\xf2\u02f7\x9dbc\x89uy*\x8a\xbd\xef|\x00\x00\u07d4\x01\x91\xebT~{\xf6\x97k\x9b\x1bWuFv\x1d\xe6V\"\xe2\x89lkLM\xa6\u077e\x00\x00\u07d4\x01\x9dp\x95y\xffK\xc0\x9f\xdc\xdd\xe41\xdc\x14G\xd2\xc2`\xbc\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x01\xa2Z_Z\xf0\x16\x9b0\x86L;\xe4\xd7V<\xcdD\xf0\x9e\x89M\x85<\x8f\x89\b\x98\x00\x00\xe0\x94\x01\xa7\xd9\xfa}\x0e\xb1\x18\\g\xe5M\xa8<.u\xdbi\u37ca\x01\x9dJ\xdd\xd0\u063c\x96\x00\x00\u07d4\x01\xa8\x18\x13ZAB\x10\xc3|b\xb6%\xac\xa1\xa5F\x11\xac6\x89\x0e\x189\x8ev\x01\x90\x00\x00\u07d4\x01\xb1\xca\xe9\x1a;\x95Y\xaf\xb3<\xdcmh\x94B\xfd\xbf\xe07\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x01\xb5\xb5\xbcZ\x11\u007f\xa0\x8b4\xed\x1d\xb9D\x06\bYz\xc5H\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x01\xbb\xc1Og\xaf\x069\xaa\xb1D\x1ej\b\xd4\xceqb\t\x0f\x89F\xfc\xf6\x8f\xf8\xbe\x06\x00\x00\xe0\x94\x01\xd08\x15\xc6\x1fAkq\xa2a\n-\xab\xa5\x9f\xf6\xa6\xde[\x8a\x02\x05\xdf\xe5\v\x81\xc8.\x00\x00\u07d4\x01\u0559\xee\r_\x8c8\xab-9.,e\xb7L<\xe3\x18 \x89\x1b\xa5\xab\xf9\xe7y8\x00\x00\u07d4\x01\xe4\x05!\x12%0\u066c\x91\x11<\x06\xa0\x19\vmc\x85\v\x89Hz\x9a0E9D\x00\x00\u07d4\x01\xe6A]X{\x06T\x90\xf1\xed\u007f!\xd6\xe0\xf3\x86\xeegG\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x01\xe8d\xd3Tt\x1bB>oB\x85\x17$F\x8ct\xf5\xaa\x9c\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x01\xed_\xba\x8d.\xabg:\xec\x04-0\xe4\xe8\xa6\x11\xd8\xc5Z\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x01\xfb\x8e\xc1$%\xa0O\x81>F\xc5L\x05t\x8c\xa6\xb2\x9a\xa9\x89\x0e\x15s\x03\x85F|\x00\x00\u07d4\x01\xff\x1e\xb1\u07adP\xa7\xf2\xf9c\x8f\xde\xe6\xec\xcf:{*\u0209 \x86\xac5\x10R`\x00\x00\u07d4\x02\x03b\u00ed\xe8x\u0290\u05b2\u0609\xa4\xccU\x10\xee\xd5\xf3\x898\x88\xe8\xb3\x11\xad\xb3\x80\x00\u07d4\x02\x03\xae\x01\xd4\xc4\x1c\xae\x18e\xe0K\x1f[S\xcd\xfa\xec\xae1\x896\x89\xcd\u03b2\x8c\xd7\x00\x00\u07d4\x02\b\x93a\xa3\xfetQ\xfb\x1f\x87\xf0\x1a-\x86fS\xdc\v\a\x89\x02*\xc7H2\xb5\x04\x00\x00\u07d4\x02\x1fi\x04=\xe8\x8cI\x17\xca\x10\xf1\x84(\x97\xee\xc0X\x9c|\x89kD\u03f8\x14\x87\xf4\x00\x00\u07d4\x02)\x0f\xb5\xf9\xa5\x17\xf8(E\xac\xde\xca\x0f\xc8F\x03\x9b\xe23\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x029\xb4\xf2\x1f\x8e\x05\xcd\x01Q++\xe7\xa0\xe1\x8am\x97F\a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x02Gr\x12\xff\xddu\xe5\x15VQ\xb7e\x06\xb1dfq\xa1\xeb\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\x02J\t\x8a\xe7\x02\xbe\xf5@l\x9c\"\xb7\x8b\xd4\xeb,\u01e2\x93\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x02K\xdd,{\xfdP\x0e\xe7@O\u007f\xb3\xe9\xfb1\xdd \xfb\u0449\t\xc2\x00vQ\xb2P\x00\x00\u07d4\x02Sg\x96\x03\x04\xbe\xee4Y\x11\x18\xe9\xac-\x13X\xd8\x02\x1a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x02V\x14\x9f[Pc\xbe\xa1N\x15f\x1f\xfbX\xf9\xb4Y\xa9W\x89&)\xf6n\fS\x00\x00\x00\u07d4\x02`=z;\xb2\x97\xc6|\x87~]4\xfb\u0579\x13\xd4\xc6:\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x02a\xad:\x17*\xbf\x13\x15\xf0\xff\xec2p\x98j\x84\t\xcb%\x89\v\b!;\u03cf\xfe\x00\x00\u07d4\x02d2\xaf7\xdcQ\x13\xf1\xf4mH\nM\u0c80R#~\x89\x13I\xb7\x86\xe4\v\xfc\x00\x00\u07d4\x02f\xab\x1ck\x02\x16#\v\x93\x95D=_\xa7^hEh\u018965\u026d\xc5\u07a0\x00\x00\u07d4\x02u\x1d\u018c\xb5\xbdsp'\xab\xf7\u0777s\x90\xcdw\xc1k\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x02w\x8e9\x0f\xa1u\x10\xa3B\x8a\xf2\x87\fBsT}8l\x8a\x03lw\x80\x18\x8b\xf0\xef\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x037|\x0eUkd\x01\x03(\x9aa\x89\u1baecI4g\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x03IcM\u00a9\xe8\f?w!\xee+PF\xae\xaa\xed\xfb\xb5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x03U\xbc\xac\xbd!D\x1e\x95\xad\xee\xdc0\xc1r\x18\u0224\b\u0389\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x03n\xef\xf5\xba\x90\xa6\x87\x9a\x14\xdf\xf4\xc5\x04;\x18\xca\x04`\u0249\x05k\xc7^-c\x10\x00\x00\xe0\x94\x03qKA\u04a6\xf7Q\x00\x8e\xf8\xddM+)\xae\u02b8\xf3n\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x03r\xe8RX.\t44J\x0f\xed!x0M\xf2]F(\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x03r\xeeU\b\xbf\x81c\xed(N^\xef\x94\xceMsg\xe5\"\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x03}\xd0V\xe7\xfd\xbdd\x1d\xb5\xb6\xbe\xa2\xa8x\n\x83\xfa\u1009\a\x96\xe3\xea?\x8a\xb0\x00\x00\xe0\x94\x03\x83#\xb1\x84\xcf\xf7\xa8*\xe2\u1f67y?\xe41\x9c\xa0\xbf\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x03\x87y\xca-\xbef>c\xdb?\xe7V\x83\xea\x0e\xc6.#\x83\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94\x03\x8eE\xea\xdd=\x88\xb8\u007f\xe4\u06b0fh\x05\"\xf0\xdf\xc8\xf9\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x03\x92T\x9ar\u007f\x81eT)\u02d2\x8bR\x9f%\xdfM\x13\x85\x89\x01lC\xa0\xee\xa0t\x00\x00\u07d4\x03\x94\xb9\x0f\xad\xb8`O\x86\xf4?\xc1\xe3]1$\xb3*Y\x89\x89)j\xa1@'\x8ep\x00\x00\u0794\x03\x9ezN\xbc(N,\xcdB\xb1\xbd\xd6\v\xd6Q\x1c\x0fw\x06\x88\xf0\x15\xf2W6B\x00\x00\u07d4\x03\x9e\xf1\xceR\xfeyc\xf1f\u0562u\u0131\x06\x9f\xe3\xa82\x89\x15\xaf9\u4ab2t\x00\x00\u07d4\x03\xa2l\xfcL\x181op\u055e\x9e\x1ay\xee>\x8b\x96/L\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x03\xaab(\x81#m\xd0\xf4\x94\f$\xc3$\xff\x8b{~!\x86\x89\xadx\xeb\u016cb\x00\x00\x00\u07d4\x03\xafz\xd9\xd5\"<\xf7\xc8\xc1? \xdfg\xeb\xe5\xff\u017bA\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x03\xb0\xf1|\xd4F\x9d\xdc\u03f7\xdai~\x82\xa9\x1a_\x9ewt\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x03\xb4\x1bQ\xf4\x1d\xf2\r\xd2y\xba\xe1\x8c\x12w_w\xadw\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x03\xbe[F)\xae\xfb\xbc\xab\x9d\xe2m9Wl\xb7\xf6\x91\xd7d\x89\n\xdf0\xbap\u0217\x00\x00\u07d4\x03\xc6G\xa9\xf9)\xb0x\x1f\xe9\xae\x01\u02a3\xe1\x83\xe8vw~\x89\x18*\xb7\xc2\f\xe5$\x00\x00\u07d4\x03\xc9\x1d\x92\x946\x03\xe7R >\x054\x0eV`\x13\xb9\x00E\x89+|\xc2\xe9\xc3\"\\\x00\x00\u07d4\x03\xcbLOE\x16\xc4\xffy\xa1\xb6$O\xbfW.\x1c\u007f\xeay\x89\x94\x89#z\u06daP\x00\x00\u07d4\x03\u02d8\u05ec\xd8\x17\u079d\x88m\"\xfa\xb3\xf1\xb5}\x92\xa6\b\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\x03\u031d-!\xf8k\x84\xac\x8c\xea\xf9q\u06e7\x8a\x90\xe6%p\x89WG=\x05\u06ba\xe8\x00\x00\u07d4\x03\xd1rO\xd0\x0eT\xaa\xbc\xd2\xde*\x91\xe8F+\x10I\xdd:\x89\x8f\x1d\\\x1c\xae7@\x00\x00\u07d4\x03\xde\xdf\xcd\v<.\x17\xc7\x05\xda$\x87\x90\uf626\xbdWQ\x89Hz\x9a0E9D\x00\x00\u07d4\x03\u8c04SuW\xe7\t\xea\xe2\xe1\u1966\xbc\xe1\xef\x83\x14\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x03\xeam&\u0400\xe5z\xee9&\xb1\x8e\x8e\xd7:N[(&\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x03\xeb<\xb8`\xf6\x02\x8d\xa5T\xd3D\xa2\xbbZP\n\xe8\xb8o\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x03\xeb\xc6?\xdaf`\xa4e\x04^#_\xben\\\xf1\x95s_\x89\a\xb0l\xe8\u007f\xddh\x00\x00\xe0\x94\x03\xefj\xd2\x0f\xf7\xbdO\x00+\xacX\xd4uD\u03c7\x9a\xe7(\x8a\x01u\xc7X\u0439n\\\x00\x00\u07d4\x03\xf7\xb9 \b\x81:\xe0\xa6v\xeb!(\x14\xaf\xab5\"\x10i\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x04\x11p\xf5\x81\u0780\xe5\x8b*\x04\\\x8f|\x14\x93\xb0\x01\xb7\u02c90\xc8\xeca2\x89\nZ\xa8P\t\xe3\x9c\x00\x00\u07d4\x04i\xe8\xc4@E\v\x0eQ&&\xfe\x81~gT\xa8\x15(0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x04m'K\x1a\xf6\x15\xfbPZvJ\xd8\u0767p\xb1\xdb/=\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x04}Z&\u05ed\x8f\x8ep`\x0fp\xa3\x98\u076a\x1c-\xb2o\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x04~\x87\xc8\xf7\xd1\xfc\xe3\xb0\x13S\xa8Xb\xa9H\xac\x04\x9f>\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4\x04\u007f\x9b\xf1R\x9d\xaf\x87\xd4\a\x17^o\x17\x1b^Y\xe9\xff>\x89#<\x8f\xe4'\x03\xe8\x00\x00\xe0\x94\x04\x85'2\xb4\xc6R\xf6\xc2\u53b3e\x87\xe6\nb\xda\x14\u06ca\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x04\x8a\x89p\xeaAE\xc6MU\x17\xb8\xde[F\xd0YZ\xad\x06\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x04\x9c]K\xc6\xf2]NEli{R\xa0x\x11\xcc\u045f\xb1\x89\x10D\x00\xa2G\x0eh\x00\x00\u07d4\x04\xa1\xca\xda\x1c\xc7Q\b/\xf8\u0692\x8e<\xfa\x00\b \xa9\xe9\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x04\xa8\n\xfa\xd5>\xf1\xf8Ae\xcf\xd8R\xb0\xfd\xf1\xb1\xc2K\xa8\x89\x03$\xe9d\xb3\xec\xa8\x00\x00\u07d4\x04\xaa\xfc\x8a\xe5\xceoI\x03\u021d\u007f\xac\x9c\xb1\x95\x12\"Gw\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x04\xbaK\xb8q@\x02,!Jo\xacB\xdbZ\x16\u0755@E\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x04\xba\x8a?\x03\xf0\x8b\x89P\x95\x99M\xdaa\x9e\u06ac\xee>z\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x04\xc2\xc6K\xb5L>\xcc\xd0U\x85\xe1\x0e\xc6\xf9\x9a\f\xdb\x01\xa3\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x04\xceE\xf6\x00\xdb\x18\xa9\u0405\x1b)\xd99>\xbd\xaa\xfe=\u0149\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x04\u05b8\xd4\u0686t\a\xbb\x99wI\u07bb\xcd\xc0\xb3XS\x8a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x04\xd78\x96\xcfe\x93\xa6\x91\x97*\x13\xa6\xe4\x87\x1f\xf2\xc4+\x13\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x04\xd8*\xf9\xe0\x1a\x93m\x97\xf8\xf8Y@\xb9p\xf9\xd4\u06d96\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x04\xe5\xf5\xbc|\x92?\xd1\xe3\x175\xe7.\xf9h\xfdg\x11\fn\x89WU\x1d\xbc\x8ebL\x00\x00\u07d4\x04\xec\xa5\x01c\n\xbc\xe3R\x18\xb1t\x95k\x89\x1b\xa2^\xfb#\x8966\x9e\xd7t}&\x00\x00\u07d4\x05\x05\xa0\x8e\"\xa1\t\x01Z\"\xf6\x850STf*U1\u0549\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\u07d4\x05\x14\x95L\xe8\x81\xc807\x03d\x00\x89lO\xd1\xee$nx\x00\x00\u07d4\x05\x1dBBv\xb2\x129fQ\x86\x13=e;\xb8\xb1\x86/\x89\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x05!\xbc:\x9f\x87\x11\xfe\xcb\x10\xf5\a\x97\xd7\x10\x83\xe3A\ub749\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x05#mL\x90\xd0e\xf9\u34c3X\xaa\xff\xd7w\xb8j\xecI\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x05*X\xe05\xf1\xfe\x9c\xdd\x16\x9b\xcf \x97\x03E\xd1+\x9cQ\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4\x05.\xab\x1fa\xb6\xd4U\x17(?A\xd1D\x18$\x87\x87I\u0409\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x053n\x9ar'(\xd9c\xe7\xa1\xcf'Y\xfd\x02tS\x0f\u02891\xa2D?\x88\x8ay\x80\x00\u07d4\x054q\u035aA\x92[9\x04\xa5\xa8\xff\xca6Y\xe04\xbe#\x89\n\xd2\x01\xa6yO\xf8\x00\x00\u07d4\x056\x1d\x8e\xb6\x94\x1dN\x90\xfb~\x14\x18\xa9Z2\xd5%w2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x05B:T\xc8\xd0\xf9p~pAs\xd9#\xb9F\xed\xc8\xe7\x00\x89\x06\xea\x03\u00bf\x8b\xa5\x80\x00\u07d4\x05D\f[\a;R\x9bH) \x9d\xff\x88\t\x0e\a\xc4\xf6\xf5\x89E\u04977\xe2/ \x00\x00\u07d4\x05Z\xb6X\xc6\xf0\xedO\x87^\xd6t.K\xc7)-\x1a\xbb\xf0\x89\x04\x86\u02d7\x99\x19\x1e\x00\x00\u07d4\x05[\xd0,\xaf\x19\xd6 +\xbc\u0703m\x18{\xd1\xc0\x1c\xf2a\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x05^\xacO\x1a\xd3\xf5\x8f\v\xd0$\u058e\xa6\r\xbe\x01\u01af\xb3\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x05fQU\xccI\xcb\xf6\xaa\xbd\u056e\x92\xcb\xfa\xad\x82\xb8\xc0\xc1\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x05f\x86\a\x8f\xb6\xbc\xf9\xba\n\x8a\x8d\xc6:\x90o_\xea\xc0\xea\x89\x1b\x18\x1eK\xf24<\x00\x00\u07d4\x05iks\x91k\xd3\x03>\x05R\x1e2\x11\xdf\xec\x02n\x98\xe4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x05k\x15F\x89O\x9a\x85\xe2\x03\xfb3m\xb5i\xb1l%\xe0O\x89\t.\xdb\t\xff\b\u0600\x00\u07d4\x05yI\xe1\xca\x05pF\x9eL\xe3\u0190\xaea:k\x01\xc5Y\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x05}\u049f-\x19\xaa=\xa4#'\xeaP\xbc\xe8o\xf5\xc9\x11\u0649\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x05\u007f\u007f\x81\xcdz@o\xc4Y\x94@\x8bPI\x91,Vdc\x89\\(=A\x03\x94\x10\x00\x00\u07d4\x05\x91]N\"Zf\x81b\xae\xe7\xd6\xc2_\xcf\xc6\xed\x18\xdb\x03\x89\x03\x98\xc3ry%\x9e\x00\x00\u07d4\x05\x96\xa2}\xc3\xee\x11_\xce/\x94\xb4\x81\xbc z\x9e&\x15%\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x05\xa80rC\x02\xbc\x0fn\xbd\xaa\x1e\xbe\xee\xb4nl\xe0\v9\x89\x05V\xf6L\x1f\xe7\xfa\x00\x00\u07d4\x05\xae\u007f\u053b\u0300\xca\x11\xa9\n\x1e\u01e3\x01\xf7\xcc\u0303\u06c91T\xc9r\x9d\x05x\x00\x00\u07d4\x05\xbbd\xa9\x16\xbef\xf4`\xf5\xe3\xb6C2\x11\r \x9e\x19\xae\x89\u3bb5sr@\xa0\x00\x00\xe0\x94\x05\xbfO\xcf\xe7r\xe4[\x82dC\x85.l5\x13P\xcer\xa2\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94\x05\xc6@\x04\xa9\xa8&\xe9N^N\xe2g\xfa*v2\xddNo\x8a\x03m\xc4.\xbf\xf9\v\u007f\x80\x00\xe0\x94\x05\xc76\xd3e\xaa7\xb5\xc0\xbe\x9c\x12\u022d\\\xd9\x03\xc3,\xf9\x8a\x01E^{\x80\n\x86\x88\x00\x00\xe0\x94\x05\xcbl;\x00r\xd3\x11ga\xb52\xb2\x18D;S\xe8\xf6\u014a\x1e\x02\xc3\xd7\xfc\xa9\xb6(\x00\x00\u07d4\x05\xd0\xf4\xd7(\xeb\xe8.\x84\xbfYu\x15\xadA\xb6\v\xf2\x8b9\x89\u3bb5sr@\xa0\x00\x00\u07d4\x05\u058d\xada\u04fb\u07f3\xf7y&\\IGJ\xff?\xcd0\x89\x02\"\xc5]\xc1Q\x9d\x80\x00\u07d4\x05\xe6q\xdeU\xaf\xec\x96K\aM\xe5t\xd5\x15\x8d]!\xb0\xa3\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x05\xe9{\tI,\u058fc\xb1+\x89.\xd1\xd1\x1d\x15,\x0e\u02897\b\xba\xed=h\x90\x00\x00\u07d4\x05\xf3c\x1fVd\xbd\xad]\x012\xc88\x8d6\xd7\u0612\t\x18\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x06\t\xd8:l\xe1\xff\u0276\x90\xf3\xe9\xa8\x1e\x98>\x8b\xdcM\x9d\x8a\x0e\u04b5%\x84\x1a\xdf\xc0\x00\x00\u07d4\x06\x1e\xa4\x87|\u0409D\xebd\u0096n\x9d\xb8\xde\xdc\xfe\xc0k\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x06%\xd0`V\x96\x8b\x00\"\x06\xff\x91\x98\x01@$+\xfa\xa4\x99\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x06(\xbf\xbeU5x/\xb5\x88@k\xc9f`\xa4\x9b\x01\x1a\xf5\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d4\x061\u044b\xbb\xbd0\xd9\xe1s+\xf3n\xda\xe2\u0389\x01\xab\x80\x89\xa3\xf9\x88U\xec9\x90\x00\x00\u07d4\x061\xdc@\xd7NP\x95\xe3r\x9e\xdd\xf4\x95D\xec\xd49og\x89\b\xacr0H\x9e\x80\x00\x00\xe0\x94\x067Y\xdd\x1cN6.\xb1\x93\x98\x95\x1f\xf9\xf8\xfa\xd1\xd3\x10h\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x06_\xf5u\xfd\x9c\x16\xd3\xcbo\u058f\xfc\x8fH?\xc3.\xc85\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x06a\x8e\x9dWb\xdfb\x02\x86\x01\xa8\x1dD\x87\u05a0\xec\xb8\x0e\x89Hz\x9a0E9D\x00\x00\xe0\x94\x06fG\xcf\xc8]#\xd3v\x05W= \x8c\xa1T\xb2D\xd7l\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x06xeJ\xc6v\x1d\xb9\x04\xa2\xf7\xe8Y^\xc1\xea\xacsC\b\x89/\x98\xb2\x9c(\x18\xf8\x00\x00\u07d4\x06\x86\n\x93RYU\xffbI@\xfa\xdc\xff\xb8\xe1I\xfdY\x9c\x89lh\xcc\u041b\x02,\x00\x00\xe0\x94\x06\x8c\xe8\xbdn\x90*E\u02c3\xb5\x15A\xb4\x0f9\xc4F\x97\x12\x8a\x01\x1c\x0f\x9b\xadJF\xe0\x00\x00\u07d4\x06\x8e)\xb3\xf1\x91\xc8\x12\xa699\x18\xf7\x1a\xb93\xaehG\xf2\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x06\x8eeWf\xb9D\xfb&6\x19e\x87@\xb8P\xc9J\xfa1\x89\x01\xe8\u007f\x85\x80\x9d\xc0\x00\x00\u0794\x06\x96N-\x17\xe9\x18\x9f\x88\xa8 96\xb4\n\xc9nS<\x06\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x06\x99L\xd8:\xa2d\n\x97\xb2`\vA3\x9d\x1e\r>\xdel\x89\r\x8drkqw\xa8\x00\x00\u07d4\x06\x9e\u042bz\xa7}\xe5q\xf1a\x06\x05\x1d\x92\xaf\xe1\x95\xf2\u0409\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x06\xac&\xad\x92\u02c5\x9b\u0550]\xdc\xe4&j\xa0\xecP\xa9\u0149*\x03I\x19\u07ff\xbc\x00\x00\u07d4\x06\xb0\xc1\xe3\u007fZ^\u013b\xf5\b@T\x8f\x9d:\xc0(\x88\x97\x89\xd8\u0602\u148e}\x00\x00\u07d4\x06\xb0\xff\x83@s\xcc\xe1\xcb\xc9\xeaU~\xa8{`Yc\u8d09\x10CV\x1a\x88)0\x00\x00\xe0\x94\x06\xb1\x06d\x9a\xa8\xc4!\xdd\xcd\x1b\x8c2\xcd\x04\x18\xcf0\xda\x1f\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x06\xb5\xed\xe6\xfd\xf1\xd6\xe9\xa3G!7\x9a\xea\xa1|q=\xd8*\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x06\xcb\xfa\b\xcd\xd4\xfb\xa77\xba\xc4\a\xbe\x82$\xf4\xee\xf3X(\x89 +\xe5\xe88.\x8b\x80\x00\u07d4\x06\xd6\xcb0\x84\x81\xc36\xa6\xe1\xa2%\xa9\x12\xf6\xe65Y@\xa1\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\x06\xdc\u007f\x18\xce\xe7\xed\xab[yS7\xb1\xdfj\x9e\x8b\u062eY\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x06\xf6\x8d\xe3\xd79\xdbA\x12\x1e\xac\xf7y\xaa\xda=\xe8v!\a\x89\x01\x84\x93\xfb\xa6N\xf0\x00\x00\u07d4\x06\xf7\u070d\x1b\x94b\xce\xf6\xfe\xb13h\xa7\xe3\x97K\t\u007f\x9f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\a\x01\xf9\xf1G\xecHhV\xf5\xe1\xb7\x1d\xe9\xf1\x17\xe9\x9e!\x05\x89\te\xdaq\u007f\u0578\x00\x00\u07d4\a\r]6L\xb7\xbb\xf8\"\xfc,\xa9\x1a5\xbd\xd4A\xb2\x15\u0549lk\x93[\x8b\xbd@\x00\x00\xe0\x94\a\x1d\xd9\r\x14\xd4\x1fO\xf7\xc4\x13\xc2B8\xd35\x9c\xd6\x1a\a\x8a\a\xb5?y\xe8\x88\xda\xc0\x00\x00\u07d4\a&\xc4.\x00\xf4T\x04\x83n\xb1\xe2\x80\xd0s\xe7\x05\x96\x87\xf5\x89X\x00>?\xb9G\xa3\x80\x00\xe0\x94\a'\xbe\n*\x00! H\xb5R\x0f\xbe\xfb\x95>\xbc\x9dT\xa0\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\a)\xa8\xa4\xa5\xba#\xf5y\xd0\x02[\x1a\xd0\xf8\xa0\xd3\\\xdf\u048a\x02\r\u058a\xaf2\x89\x10\x00\x00\u07d4\a)\xb4\xb4|\t\xeb\x16\x15\x84d\u022a\u007f\xd9i\vC\x889\x89lh\xcc\u041b\x02,\x00\x00\u0794\a4\xa0\xa8\x1c\x95b\xf4\xd9\xe9\xe1\n\x85\x03\xda\x15\xdbF\xd7n\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\a\xa7\xef[G\x00\x00\xe0\x94\ap\xc6\x1b\xe7\x87r#\f\xb5\xa3\xbb$)\xa7&\x14\xa0\xb36\x8a\x01n\u0899\xb7\x13A\x80\x00\u07d4\ar><0\xe8\xb71\xeeEj)\x1e\xe0\u7630 Jw\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\as\xee\xac\xc0P\xf7G \xb4\xa1\xbdW\x89[\x1c\xce\xebI]\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\a\x80\r/\x80h\xe4H\u01daOi\xb1\xf1^\xf6\x82\xaa\xe5\xf6\x8a\x04\x1b\xad\x15^e\x12 \x00\x00\u07d4\a\xa8\xda\xde\xc1BW\x1a}S\xa4)pQxm\a,\xbaU\x89\x01;m\xa1\x13\x9b\u0680\x00\u07d4\a\xaf\x93\x8c\x127\xa2|\x900\tM\xcf$\aP$n=,\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\a\xb1\xa3\x06\xcbC\x12\xdffH,,\xaer\xd1\xe0a@\x0f\u034a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\a\xb7\xa5p3\xf8\xf1\x130\xe4f^\x18]#N\x83\xec\x14\v\x89\xea~\xe9*\f\x9a\v\x80\x00\u07d4\a\xbc,\xc8\xee\xdc\x01\x97\a\x00\xef\xc9\xc4\xfb6s^\x98\xcdq\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\a\xd4\x12\x17\xba\u0725\xe0\xe6\x03'\xd8E\xa3FO\x0f'\xf8J\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\a\xd43N\u00c5\xe8\xaaT\xee\xda\xea\xdb0\x02/\f\u07e4\xab\x89\x8e\x91\xd5 \xf2\xeby\x00\x00\u07d4\a\xda\xe6\"c\r\x1168\x193\u04adk\"\xb89\xd8!\x02\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\a\xdc+\xf8;\u01af\x19\xa8B\xff\xeaf\x1a\xf5\xb4\x1bg\xfd\xa1\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\a\u070c\x8b\x92z\xdb\xed\xfa\x8f]c\x9bCR5\x1f/6\u0489\x11\n\xed;U0\xdb\x00\x00\u07d4\a\xdd\xd0B,\x86\xefe\xbf\f\u007f\xc3E(b\xb1\"\x8b\b\xb8\x89o\xf5\u04aa\x8f\x9f\xcf\x00\x00\u07d4\a\xe1\x16,\xea\xe3\xcf!\xa3\xf6-\x10Y\x900.0\u007fN;\x89R\xf1\x03\xed\xb6k\xa8\x00\x00\u07d4\a\xe2\xb4\xcd\xee\xd9\u0407\xb1.Um\x9ew\f\x13\xc0\x99a_\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\a\xfe\xefT\xc16\x85\b)\xba\xdcKI\xc3\xf2\xa7<\x89\xfb\x9e\x89\x06hZ\xc1\xbf\xe3,\x00\x00\u07d4\b\x05FP\x8a=&\x82\u0239\x88O\x13c{\x88G\xb4M\xb3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\b\t\bv\xba\xad\xfe\xe6\\=6;\xa5S\x12t\x8c\xfa\x87=\x89\\*\x997\x1c\xff\xe1\x00\x00\u07d4\b\x16o\x021?\xea\u12f0D\xe7\x87|\x80\x8bU\xb5\xbfX\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\b)\xd0\xf7\xbb|Dl\xfb\xb0\u07ad\xb29M\x9d\xb7$\x9a\x87\x89\x02,\xa3X|\xf4\xeb\x00\x00\u07d4\b0m\xe5\x19\x81\u7b21\x85hY\xb7\xc7xijki\xf9\x89\xadx\xeb\u016cb\x00\x00\x00\xe0\x94\b7S\x9b_jR*H,\xdc\u04e9\xbbpC\xaf9\xbd\u048a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\b8\xa7v\x8d\x9c*\u028b\xa2y\xad\xfe\xe4\xb1\xf4\x91\xe3&\xf1\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\bA\x16R\xc8qq6\t\xaf\x00b\xa8\xa1(\x1b\xf1\xbb\xcf\u0649K\xe4\xe7&{j\xe0\x00\x00\xe0\x94\bM\x102Tu\x9b4<\xb2\xb9\xc2\xd8\xff\x9e\x1a\xc5\xf1E\x96\x8a\x01\x9b\xff/\xf5yh\xc0\x00\x00\u07d4\bPO\x05d?\xabY\x19\xf5\xee\xa5Y%\u05e3\xed}\x80z\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\b[J\xb7]\x83b\xd9\x14C\\\xed\xee\x1d\xaa+\x1e\xe1\xa2;\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\b[\xa6_\xeb\xe2>\xef\xc2\xc8\x02fj\xb1&#\x82\xcf\u0114\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\bt\x98\xc0FFh\xf3\x11P\xf4\xd3\u013c\u0765\"\x1b\xa1\x02\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\bw\uebabx\xd5\xc0\x0e\x83\xc3+-\x98\xfay\xadQH/\x89\x17\xd2-q\xdab&\x00\x00\u0794\b\x93j7\u07c5\xb3\xa1X\xca\xfd\x9d\xe0!\xf5\x817h\x13G\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\b\xa9\xa4N\x1fA\xde=\xbb\xa7\xa3c\xa3\xabA,\x12L\xd1^\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\b\xb7\xbd\u03d4MUp\x83\x8b\xe7\x04`$:\x86\x94HXX\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\b\xb8E6\xb7L\x8c\x01T=\xa8\x8b\x84\u05cb\xb9WG\xd8\"\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\b\xc2\xf26\xacJ\xdc\xd3\xfd\xa9\xfb\xc6\xe4S\"S\xf9\xda;\xec\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\b\xc8\x02\xf8wX4\x9f\xa0>k\xc2\xe2\xfd\a\x91\x19~\ua689lk\x93[\x8b\xbd@\x00\x00\u07d4\b\xc9\U0007fd89\xfd\xf8\x04\xd7i\xf8!#6\x02\x15\xaf\xf9;\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\b\xca\u0215&A\xd8\xfcRn\xc1\xabO-\xf8&\xa5\xe7q\x0f\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94\b\xcc\xdaP\xe4\xb2j\x0f\xfc\x0e\xf9.\x92\x051\a\x06\xbe\xc2\u01ca\x01Iul8W\xc6\x00\x00\x00\u07d4\b\u0406M\xc3/\x9a\xcb6\xbfN\xa4G\xe8\xddg&\x90j\x15\x89lnY\xe6|xT\x00\x00\u07d4\b\xd4&\u007f\xeb\x15\u0697\x00\xf7\xcc\xc3\xc8J\x89\x18\xbf\x17\xcf\u0789a\t=|,m8\x00\x00\xe0\x94\b\xd41\x1c\x9c\x1b\xba\xf8\u007f\xab\xe1\xa1\xd0\x14c\x82\x8d]\x98\u038a\x13\x0e\xe8\xe7\x17\x90D@\x00\x00\u07d4\b\xd5N\x83\xadHj\x93L\xfa\xea\u20e3>\xfd\"|\x0e\x99\x898S\x05\x83$^\xdc\x00\x00\u07d4\b\xd9~\xad\xfc\xb7\xb0d\xe1\xcc\xd9\u0217\x9f\xbe\xe5\xe7z\x97\x19\x89\x0el]\xa8\xd6z\xc1\x80\x00\u07d4\b\xda:z\x0fE!a\u03fc\xec1\x1b\xb6\x8e\xbf\xde\xe1~\x88\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\b\xe3\x8e\xe0\xceH\xc9\xcad\\\x10\x19\xf7;SUX\x1cV\xe6\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\b\xef?\xa4\xc4<\xcd\xc5{\"\xa4\xb9\xb23\x1a\x82\xe58\x18\xf2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\t\td\x8c\x18\xa3\xce[\xaez\x04~\xc2\xf8h\xd2L\u0768\x1d\x89\xcf\x15&@\xc5\xc80\x00\x00\u07d4\t\f\xd6{`\xe8\x1dT\xe7\xb5\xf6\a\x8f>\x02\x1b\xa6[\x9a\x1e\x8965\u026d\xc5\u07a0\x00\x00\u07d4\t\f\xeb\xef),>\xb0\x81\xa0_\u062a\xf7\u04db\xf0{\x89\u0509\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\t\x0f\xa96{\xdaW\xd0\xd3%:\n\x8f\xf7l\xe0\xb8\xe1\x9as\x8965\u026d\xc5\u07a0\x00\x00\u07d4\t\x14n\xa3\x88Qv\xf0w\x82\xe1\xfe0\xdc\xe3\xce$\u011e\x1f\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\t!`_\x99\x16N;\xcc(\xf3\x1c\xae\xcex\x971\x82V\x1d\x89+\ai*\x90e\xa8\x00\x00\xe0\x94\t&\x1f\x9a\xcbE\x1c7\x88\x84O\f\x14Q\xa3[\xadP\x98\xe3\x8a\x01\u056d'P) `\x00\x00\xe0\x94\t'\"\x04\x92\x19K.\u069f\u013b\xe3\x8f%\u0581\xdf\xd3l\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u0794\t*\xcbbK\b\xc0U\x10\x18\x9b\xbb\xe2\x1ee$\xd6D\u032d\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\t.\x81UX@-g\xf9\rk\xfem\xa0\xb2\xff\xfa\x91EZ\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\tP0\xe4\xb8&\x92\xdc\xf8\xb8\u0411$\x94\xb9\xb3x\xec\x93(\x89H\xa4zu\x80\x00\u07d4\t\x89\xc2\x00D\v\x87\x89\x91\xb6\x9d`\x95\xdf\xe6\x9e3\xa2.p\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\t\x90\xe8\x1c\u05c5Y\x9e\xa26\xbd\x19f\xcfRc\x02\xc3[\x9c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\t\x98\xd8'1\x15\xb5j\xf4%\xff\xc8>!\x8c\x1e\n\xfe\x89(\u01c8\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\t\xaeI\xe3\u007f\x12\x1d\xf5\xdc\x15\x8c\xfd\xe8\x06\xf1s\xa0k\f\u007f\x89\xd80\x9e&\xab\xa1\xd0\x00\x00\u07d4\t\xaf\xa7;\xc0G\xefF\xb9w\xfd\x97c\xf8r\x86\xa6\xbeh\u0189\x1b/\xb5\xe8\xf0jf\x00\x00\u07d4\t\xb4f\x86\x96\xf8j\b\x0f\x8b\xeb\xb9\x1d\xb8\xe6\xf8p\x15\x91Z\x89#\x8f\xf7\xb3O`\x01\x00\x00\xe0\x94\t\xb5\x9b\x86\x98\xa7\xfb\xd3\xd2\xf8\xc7:\x00\x89\x88\xde>@k+\x8a\bxg\x83&\xea\xc9\x00\x00\x00\xe0\x94\t\xb7\xa9\x88\xd1?\xf8\x91\x86so\x03\xfd\xf4au\xb5=\x16\xe0\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\t\xc1w\xf1\xaeD$\x11\u076c\xf1\x87\xd4m\xb9V\x14\x83`\xe7\x8a\x01\xe5.3l\xde\"\x18\x00\x00\xe0\x94\t\u020f\x91~Mj\xd4s\xfa\x12\u93a3\xc4G*^\xd6\u068a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\t\u0438\xcd\a|i\xd9\xf3-\x9c\xcaC\xb3\xc2\b\xa2\x1e\u050b\x89\b!\xd2!\xb5)\x1f\x80\x00\xe0\x94\t\xd6\xce\xfdu\xb0\u0133\xf8\xf1\u0587\xa5\"\xc9a#\xf1\xf59\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\t\xe47\xd4H\x86\x12(\xa22\xb6.\xe8\xd3ye\xa9\x04\ud70a\x04\x98\xcf@\x1d\xf8\x84.\x80\x00\u07d4\t\xee\x12\xb1\xb4+\x05\xaf\x9c\xf2\a\xd5\xfc\xac%[.\xc4\x11\xf2\x89\x031\xcd\xddG\xe0\xfe\x80\x00\u07d4\t\xf3\xf6\x01\xf6\x05D\x11@Xl\xe0eo\xa2J\xa5\xb1\u066e\x89Sswo\xe8\xc4T\x00\x00\u07d4\t\xf9W[\xe5}\x00G\x93\u01e4\ub137\x15\x87\xf9|\xbbj\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\n\x06P\x86\x1fx^\xd8\xe4\xbf\x10\x05\xc4P\xbb\xd0n\xb4\x8f\xb6\x89\xa6A;y\x14N~\x00\x00\u07d4\n\x06\xfa\xd7\xdc\u05e4\x92\xcb\xc0S\xee\xab\xdei4\xb3\x9d\x867\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\n\a}\xb1?\xfe\xb0\x94\x84\xc2\x17p\x9dX\x86\xb8\xbf\x9cZ\x8b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\n\x0e\u0366cow\x16\xef\x19saF\x87\xfd\x89\xa8 \xa7\x06\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\n)\xa8\xa4\xd5\xfd\x95\x00u\xff\xb3Mw\xaf\xeb-\x82;\u0589\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\n*\u0795\xb2\xe8\xc6m\x8a\xe6\xf0\xbad\xcaW\u05c3\xbemD\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\n+O\xc5\xd8\x1a\xceg\xdcK\xba\x03\xf7\xb4UA=F\xfe=\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\n-\xcbzg\x17\x01\u06f8\xf4\x95r\x80\x88&Xs5l\x8e\x89\b?\x16\xce\b\xa0l\x00\x00\u07d4\n=\xe1U\xd5\xec\xd8\xe8\x1c\x1f\xf9\xbb\xf07\x83\x01\xf8\xd4\xc6#\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\nG\xad\x90Y\xa2I\xfc\x93k&b5=\xa6\x90_u\u00b9\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\nH)ov1p\x8c\x95\u04b7Iu\xbcJ\xb8\x8a\xc19*\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94\nJ\x01\x19\x95\u0181\xbc\x99\x9f\xddyuN\x9a2J\xe3\xb3y\x8a\b\xc1\x9a\xb0n\xb8\x9a\xf6\x00\x00\u07d4\nX\xfd\xddq\x89\x8d\xe7s\xa7O\xda\xe4^{\xd8N\xf46F\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\n[y\xd8\xf2;d\x83\xdb\u2f6ab\xb1\x06L\xc7cf\xae\x89j\u0202\x10\tR\u01c0\x00\u07d4\ne.*\x8bw\xbd\x97\xa7\x90\xd0\xe9\x13a\u0248\x90\u06f0N\x8965\u026d\xc5\u07a0\x00\x00\u07d4\nn\xber;n\xd1\xf9\xa8ji\xdd\xdah\xdcGF\\+\x1b\x89@=-\xb5\x99\xd5\xe4\x00\x00\u07d4\nw\xe7\xf7+C{WO\x00\x12\x8b!\xf2\xac&Q3R\x8c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\n\x91\u007f;\\\xb0\xb8\x83\x04\u007f\u0676Y=\xbc\xd5W\xf4S\xb9\x8965\u026d\xc5\u07a0\x00\x00\u07d4\n\x93\x1bD\x9e\xa8\xf1,\xdb\xd5\xe2\xc8\xccv\xba\xd2\xc2|\x069\x89\x01?\x9e\x8cy\xfe\x05\x80\x00\u0794\n\x98\x04\x13x\x03\xbahh\xd9:U\xf9\x98_\xcdT\x04Q\u4239\x8b\xc8)\xa6\xf9\x00\x00\u07d4\n\x9a\xb2c\x8b\x1c\xfdeM%\u06b0\x18\xa0\xae\xbd\u07c5\xfdU\x89\x01.\x8c\xb5\xfeLJ\x80\x00\u07d4\n\xb3f\xe6\xe7\u056b\xbc\xe6\xb4JC\x8di\xa1\u02bb\x90\xd13\x89\x11X\xe4`\x91=\x00\x00\x00\u07d4\n\xb4(\x1e\xbb1\x85\x90\xab\xb8\x9a\x81\xdf\a\xfa:\xf9\x04%\x8a\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u0794\n\xb5\x9d9\a\x02\xc9\xc0Y\xdb\x14\x8e\xb4\xf3\xfc\xfa}\x04\xc7\xe7\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\n\xbf\xb3\x9b\x11HmyW(f\x19[\xa2lc\vg\x84\u06ca\x19\xba\x877\xf9i(\xf0\x00\x00\u07d4\n\u029aV&\x91;\b\xcf\u0266m@P\x8d\xceR\xb6\x0f\x87\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\n\xd3\xe4M<\x00\x1f\xa2\x90\xb3\x93ap0TA\b\xacn\xb9\x89j\xbd\xa0\xbc0\xb2\u07c0\x00\u07d4\n\xec.Bn\xd6\xcc\f\xf3\xc2I\xc1\x89~\xacG\xa7\xfa\xa9\xbd\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\n\xf6_\x14xNU\xa6\xf9Vg\xfds%*\x1c\x94\a-*\x89\nv;\x8e\x02\xd4O\x80\x00\u07d4\n\xf6\xc8\xd59\xc9mP%\x9e\x1b\xa6q\x9e\x9c\x80`\xf3\x88\u008965\u026d\xc5\u07a0\x00\x00\u07d4\v\x069\x0f$7\xb2\x0e\u0123\xd3C\x1b2y\xc6X>^\u05c9\n\x84Jt$\xd9\xc8\x00\x00\u07d4\v\v8b\x11*\xee\u00e04\x92\xb1\xb0_D\x0e\xcaT%n\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\v\x0e\x05[(\xcb\xd0=\xc5\xffD\xaad\xf3\xdc\xe0O^c\xfb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v\x11\x9d\xf9\x9ck\x8d\xe5\x8a\x1e,?)zgD\xbfU\"w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v\x14\x89\x19\x99\xa6\\\x9e\xf73\b\xef\xe3\x10\f\xa1\xb2\x0e\x81\x92\x89+^:\xf1k\x18\x80\x00\x00\u07d4\v!\x13PE4d*\x1d\xaf\x10.\xee\x10\xb9\xeb\xdev\xe2a\x89\x94,\xdd|\x95\xf2\xbd\x80\x00\xe0\x94\v(\x8aZ\x8bu\xf3\xdcA\x91\xeb\x04W\xe1\xc8=\xbd M%\x8a\x01\a\x14\xe7{\xb4:\xb4\x00\x00\u07d4\v6\x9e\x00.\x1bLy\x13\xfc\xf0\x0f-^\x19\u0141eG\x8f\x89\x03\u007fe\x16(\x8c4\x00\x00\u07d4\vC\xbd#\x91\x02U\x81\u0615l\xe4*\a%y\u02ff\xcb\x14\x89\x01\x04\xe7\x04d\xb1X\x00\x00\u07d4\vP|\xf5SV\x8d\xaa\xf6U\x04\xaeN\xaa\x17\xa8\xea<\xdb\xf5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v]f\xb1<\x87\xb3\x92\xe9M\x91\xd5\xf7l\rE\nU(C\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v^ \x11\xeb\xc2Z\x00\u007f!6)`I\x8a\xfb\x8a\xf2\x80\xfb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\vd\x9d\xa3\xb9j\x10,\xdcm\xb6R\xa0\xc0}e\xb1\xe4C\xe6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\vi \xa6K6;\x8d]\x90\x80$\x94\xcfVKT|C\r\x89A\rXj \xa4\xc0\x00\x00\u07d4\vp\x11\x01\xa4\x10\x9f\x9c\xb3`\xdcW\xb7tBg=^Y\x83\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\vq\xf5T\x12$i\uf5ce/\x1f\xef\xd7\u02f4\x10\x98'r\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\xe0\x94\v{\xb3B\xf0\x1b\u0248\x8ej\x9a\xf4\xa8\x87\xcb\xf4\xc2\xdd,\xaf\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\v}3\x93q\xe5\xbeg'\xe6\xe31\xb5\x82\x1f\xa2K\u06ddZ\x89.\u007f\x81\x86\x82b\x01\x00\x00\u07d4\v\u007f\xc9\xdd\xf7\x05v\xf63\x06i\xea\xaaq\xb6\xa81\xe9\x95(\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\v\x80\xfcp(,\xbd\xd5\xfd\xe3[\xf7\x89\x84\xdb;\xdb\x12\x01\x88\x8968\x02\x1c\xec\u06b0\x00\x00\u07d4\v\x92M\xf0\a\xe9\xc0\x87\x84\x17\xcf\xe6;\x97n\xa1\xa3\x82\xa8\x97\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\v\x93\xfc\xa4\xa4\xf0\x9c\xac \xdb`\xe0e\xed\xcc\xcc\x11\u0976\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\v\x9d\xf8\x0f\xbe# \t\xda\xcf\n\xa8\xca\u0153v\xe2Gb\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v\xa6\xe4j\xf2Z\x13\xf5qi%Z4\xa4\xda\xc7\xce\x12\xbe\x04\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\v\xa8p[\xf5\\\xf2\x19\xc0\x95k^?\xc0\x1cDt\xa6\xcd\xc1\x89\x05%\xe0Y]Mk\x80\x00\u07d4\v\xafn\u0379\x1a\xcb6\x06\xa85|\v\xc4\xf4\\\xfd-~o\x8965\u026d\xc5\u07a0\x00\x00\u07d4\v\xb0_r$\xbbX\x04\x85eV\xc0~\xea\xdb\ud1fa\x8f|\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\v\xb0\xc1&\x82\xa2\xf1\\\x9bWA\xb28\\\xbeA\xf04\x06\x8e\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\v\xb2\\\xa7\u0448\xe7\x1eMi={\x17\a\x17\xd6\xf8\xf0\xa7\n\x89\x12C\x02\xa8/\xad\xd7\x00\x00\u07d4\v\xb2e\x0e\xa0\x1a\xcau[\xc0\xc0\x17\xb6K\x1a\xb5\xa6m\x82\xe3\x89Hz\x9a0E9D\x00\x00\u07d4\v\xb5Lr\xfdf\x10\xbf\xa463\x97\xe0 8K\x02+\fI\x89Hz\x9a0E9D\x00\x00\u07d4\v\xb7\x16\n\xba)7b\xf8sO>\x03&\xff\u0264\xca\xc1\x90\x8965\u026d\xc5\u07a0\x00\x00\u07d4\v\xc9\\\xb3-\xbbWL\x83/\xa8\x17J\x815m8\xbc\x92\xac\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v\xd6}\xbd\xe0z\x85n\xbd\x89;^\xdcO:[\xe4 &\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\v\xdb\xc5L\u023d\xbb\xb4\x02\xa0\x89\x11\xe2#*T`\u0386k\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\v\xddX\xb9n|\x91m\xd2\xfb05o*\xeb\xfa\xaf\x1d\x860\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\v\u1f39\x03C\xfa\xe501s\xf4a\xbd\x91JH9\x05l\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\v\xe1\xfd\xf6&\xeea\x89\x10-p\xd1;1\x01,\x95\xcd\x1c\u0589lk\x93[\x8b\xbd@\x00\x00\u07d4\v\xe2\xb9J\xd9P\xa2\xa6&@\xc3[\xfc\xcdlg\xda\xe4P\xf6\x89i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94\v\u681eC\a\xfeH\xd4\x12\xb8\u0461\xa8(M\xceHba\x8a\x04\x0f\xbf\xf8\\\x0180\x00\x00\u07d4\v\xef\xb5G\a\xf6\x1b,\x9f\xb0G\x15\xab\x02n\x1b\xb7 B\xbd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\v\xf0dB\x8f\x83bg\"\xa7\xb5\xb2j\x9a\xb2\x04!\xa7r>\x89\a?u\u0460\x85\xba\x00\x00\u07d4\v\xfb\xb6\x92]\xc7^R\xcf&\x84\"K\xbe\x05P\xfe\xa6\x85\u04c9j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\f\b\x80\x06\xc6K0\xc4\u076f\xbc6\xcb_\x05F\x9e\xb6(4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\f s\xbaD\xd3\u077d\xb69\xc0N\x19\x109\xa7\x17\x16#\u007f\x89M\x85<\x8f\x89\b\x98\x00\x00\xe0\x94\f\",|A\u0270H\xef\xcc\xe0\xa22CCb\xe1-g;\x8a\x02\x1e\x83Yivw8\x00\x00\xe0\x94\f(\b\xb9Q\ud787-{2y\x0f\xccY\x94\xaeA\xff\u070a\x15\x99n[<\u05b3\xc0\x00\x00\u07d4\f(\x84~O\t\xdf\xce_\x9b%\xaf|NS\x0fY\u0200\xfe\x8965\u026d\xc5\u07a0\x00\x00\u07d4\f-\\\x92\x058\xe9S\u02af$\xf0s\u007fUL\u0192wB\x8965\u026d\xc5\u07a0\x00\x00\u07d4\f0\xca\xcc?r&\x9f\x8bO\x04\xcf\a=+\x05\xa8=\x9a\u0449lyt\x12?d\xa4\x00\x00\u07d4\f29\xe2\xe8A$-\xb9\x89\xa6\x15\x18\xc2\"G\xe8\xc5R\b\x89\x0eJ\xf6G\x174d\x00\x00\xe0\x94\fH\r\xe9\xf7F\x10\x02\x90\x8bI\xf6\x0f\xc6\x1e+b\xd3\x14\v\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\fH\xaeb\xd1S\x97\x88\xeb\xa0\x13\xd7^\xa6\vd\xee\xbaN\x80\x89w\xfb\xdcC\xe00\x99\x80\x00\u07d4\fU\x89\xa7\xa8\x9b\x9a\xd1[\x02u\x190AYH\xa8u\xfb\xef\x89\x06\u0519\xeclc8\x00\x00\u07d4\fg\x03=\xd8\xee\u007f\f\x8a\xe54\xd4*Q\xf7\xd9\xd4\xf7\x97\x8f\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\fhE\xbfA\xd5\xee'<>\u6d70\u059fo\xd5\xea\xbb\xf7\x89\xa2\xa1\xb9h.X\t\x00\x00\xe0\x94\f\u007f\x86\x9f\x8e\x90\xd5?\xdc\x03\u8c81\x9b\x01k\x9d\x18\xeb&\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\f\x86\x92\xee\xff*S\xd6\xd1h\x8e\xd5j\x9d\u06fdh\u06bb\xa1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\f\x8ff\xc6\x01{\xce[ 4r\x04\xb6\x02\xb7C\xba\u05cd`\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\f\x8f\xd7w^T\xa6\xd9\u0263\xbf\x89\x0ev\x1fewi?\xf0\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\f\x92Z\xd5\xeb5,\x8e\xf7m\f\"-\x11[\a\x91\xb9b\xa1\x89\xacc]\u007f\xa3N0\x00\x00\u07d4\f\x96~0a\xb8zu>\x84P~\xb6\t\x86x,\x8f0\x13\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\f\xa1*\xb0\xb9fl\xf0\xce\xc6g\x1a\x15)/&SGj\xb2\x8a,x'\xc4-\"\xd0|\x00\x00\u07d4\f\xa6p\xeb,\x8b\x96\u02e3y!\u007fY)\u00b8\x92\xf3\x9e\xf6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\f\xae\x10\x8em\xb9\x9b\x9ecxv\xb0d\xc60>\u068ae\u0209\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\f\xbd\x92\x1d\xbe\x12\x15c\xb9\x8ahq\xfe\xcb\x14\xf1\xcc~\x88\u05c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\f\xbf\x87p\xf0\xd1\b.\\ \u016e\xad4\xe5\xfc\xa9\xaez\xe2\x8965\u026d\xc5\u07a0\x00\x00\u07d4\f\xc6\u007f\x82s\xe1\xba\xe0\x86\u007f\xd4.\x8b\x81\x93\xd7&y\xdb\xf8\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\f\u05a1A\x91\x8d\x12k\x10m\x9f.\xbfi\xe1\x02\xdeM2w\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\f\xda\x12\xbfr\xd4a\xbb\xc4y\xeb\x92\xe6I\x1d\x05~kZ\u044a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\f\u0716\v\x99\x8c\x14\x19\x98\x16\r\xc1y\xb3l\x15\u0484p\xed\x89\x1b\x1bk\u05efd\xc7\x00\x00\xe0\x94\f\xfb\x17#5\xb1l\x87\xd5\x19\xcd\x14uS\r W\u007f^\x0e\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\r\x1f*Wq>\xbcn\x94\xde)\x84n\x88D\xd3vfWc\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\r2e\xd3\u7f79=^\x8e\x8b\x1c\xa4\u007f!\ny>\u030e\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\r5@\x8f\"ef\x11o\xb8\xac\u06a9\xe2\xc9\u055bvh?\x892\xf5\x1e\u06ea\xa30\x00\x00\u07d4\rU\x1e\xc1\xa2\x13<\x98\x1d_\u01a8\xc8\x17?\x9e|OG\xaf\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\r]\x98V\\d|\xa5\xf1w\xa2\xad\xb9\xd3\x02/\xac(\u007f!\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\re\x80\x14\xa1\x99\x06\x1c\xf6\xb3\x943\x14\x03\x03\xc2\x0f\xfdNZ\x8a\x01\xbc\x85\xdc*\x89\xbb \x00\x00\u07d4\rg\x87\x06\xd07\x18\u007f>\"\xe6\xf6\x9b\x99\xa5\x92\xd1\x1e\xbcY\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\ri\x10\f9\\\xe6\xc5\xea\xad\xf9]\x05\xd8r\x83~\xde\xdd!\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\rt~\u559b\xf7\x9dW8\x1do\xe3\xa2@l\xd0\xd8\xce'\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\r\x80#\x92\x9d\x91r4\xae@Q+\x1a\xab\xb5\xe8\xa4Q'q\x89\b\x05\xe9\x9f\xdc\xc5\xd0\x00\x00\xe0\x94\r\x8a\xab\x8ft\xea\x86,\xdfvh\x05\x00\x9d?>B\xd8\xd0\v\x8a\x01;\x80\xb9\x9cQ\x85p\x00\x00\u07d4\r\x8c@\xa7\x9e\x18\x99O\xf9\x9e\xc2Q\xee\x10\u0408\u00d1.\x80\x89\x066d\xfc\u04bb\xc4\x00\x00\u07d4\r\x8e\xd7\xd0\xd1V83\x0e\xd7\xe4\xea\u032b\x8aE\x8dus~\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\r\x92X/\u06e0^\xab\xc3\xe5\x158\xc5m\xb8\x817\x85\xb3(\x89\nZ\xa8P\t\xe3\x9c\x00\x00\u07d4\r\x94C\xa7\x94h\xa5\xbb\xf7\xc1\xe5\xb9\x15\xb3d\x87\xf9\x16\x1f\x19\x84m\x10\x1431\x8a\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\r\xbdA|7+\x8b\r\x01\xbc\xd9Dpk\xd3.`\xae(\u0449\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\r\xc1\x00\xb1\a\x01\x1c\u007f\xc0\xa13\x96\x12\xa1l\xce\xc3(R\b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\r\u03dd\x8c\x98\x04E\x9fd|\x14\x13\x8e\xd5\x0f\xadV;AT\x89\t`\xdbwh\x1e\x94\x00\x00\u07d4\r\xcf\xe87\xea\x1c\xf2\x8ce\xfc\xce\u00fe\xf1\xf8NY\xd1P\xc0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\r\xd4\xe6t\xbb\xad\xb1\xb0\u0702D\x98q=\xce;QV\xda)\x89\t79SM(h\x00\x00\u07d4\r\xfb\u0501pP\xd9\x1d\x9db\\\x02\x05<\xf6\x1a>\xe2\x85r\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\x0e\x02N\u007f\x02\x9cj\xaf:\x8b\x91\x0f^\b\bs\xb8W\x95\xaa\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x0e\tdl\x99\xafC\x8e\x99\xfa'L\xb2\xf9\xc8V\xcbe\xf76\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x0e\f\x9d\x00^\xa0\x16\u0095\xcdy\\\xc9!>\x87\xfe\xbc3\xeb\x89\n\xbb\xcdN\xf3wX\x00\x00\u07d4\x0e\rf3\xdb\x1e\f\u007f#Jm\xf1c\xa1\x0e\n\xb3\x9c \x0f\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x0e\x11\xd7z\x89w\xfa\xc3\r&\x84E\xe51\x14\x9b1T\x1a$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x0e\x12=}\xa6\xd1\xe6\xfa\xc2\u072d\xd2p)$\v\xb3\x90R\xfe\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x0e\x18\x01\xe7\vbb\x86\x1b\x114\u033c9\x1fV\x8a\xfc\x92\xf7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x0e \x94\xac\x16T\xa4k\xa1\xc4\u04e4\v\xb8\xc1}\xa7\U000d6209\x13h?\u007f<\x15\xd8\x00\x00\u07d4\x0e!\xaf\x1b\x8d\xbf'\xfc\xf6?7\xe0G\xb8z\x82\\\xbe|'\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x0e.PJ-\x11\"\xb5\xa9\xfe\xee\\\xb1E\x1b\xf4\u00ac\xe8{\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x0e/\x8e(\xa6\x81\xf7|X;\xd0\xec\xde\x16cK\xdd~\x00\u0349\x05'8\xf6Y\xbc\xa2\x00\x00\u07d4\x0e2\x02\x19\x83\x8e\x85\x9b/\x9f\x18\xb7.=@s\xcaP\xb3}\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x0e3\xfc\xbb\xc0\x03Q\v\xe3W\x85\xb5*\x9c]!k\xc0\x05\xf4\x89e\xea=\xb7UF`\x00\x00\u07d4\x0e6\x96\xcf\x1fB\x17\xb1c\u047c\x12\xa5\xeas\x0f\x1c2\xa1J\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x0e9\x0fD\x05=\xdf\xce\xf0\xd6\b\xb3^M\x9c,\xbe\x98q\xbb\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x0e:(\xc1\u07ef\xb0P[\xdc\xe1\x9f\xe0%\xf5\x06\xa6\xd0\x1c\xeb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x0e=\xd7\xd4\xe4)\xfe90\xa6A@5\xf5+\xdcY\x9dxM\x89\x02,\xa3X|\xf4\xeb\x00\x00\u07d4\x0eGey\x03Rek\xc6Vh,$\xfc^\xf3\xe7j#\u01c9\x02\x86\xd7\xfc\f\xb4\xf5\x00\x00\u07d4\x0eI\x88\x00Dqw\xb8\u022f\xc3\xfd\xfa\u007fi\xf4\x05\x1b\xb6)\x89t\x05\xb6\x9b\x8d\xe5a\x00\x00\u07d4\x0ek\xaa\xa3\u07b9\x89\xf2\x89b\x00vf\x86\x18\xe9\xac3(e\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x0el\xd6d\xad\x9c\x1e\xd6K\xf9\x87I\xf4\x06D\xb6&\xe3y,\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\xe0\x94\x0em\xfdU;.\x87=*\xec\x15\xbd_\xbb?\x84r\xd8\u04d4\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\x0en\xc3\x137bq\xdf\xf5T#\xabT\"\xcc:\x8b\x06\xb2+\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x0en\u0399\x11\x1c\xad\x19a\xc7H\xed=\xf5\x1e\xddi\u04a3\xb1\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\x0e\x83\xb8PH\x1a\xb4MI\xe0\xa2)\xa2\xe4d\x90,iS\x9b\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x0e\x89\xed\xdd?\xa0\xd7\x1d\x8a\xb0\xff\x8d\xa5X\x06\x86\xe3\xd4\xf7O\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x0e\x90\x96\xd3C\xc0`\xdbX\x1a\x12\x01\x12\xb2x`~\xc6\xe5+\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x0e\x9cQ\x18d\xa1w\xf4\x9b\xe7\x82\x02w?`H\x9f\xe0NR\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x0e\xa2\xa2\x101+>\x86~\xe0\xd1\xcch,\xe1\xd6f\xf1\x8e\u054a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x0e\xb1\x89\xef,-Wb\xa9c\u05b7\xbd\xf9i\x8e\xa8\u7d0a\x89Hz\x9a0E9D\x00\x00\xe0\x94\x0e\xb5\xb6b\xa1\xc7\x18`\x8f\xd5/\f%\xf97\x880\x17\x85\x19\x8a\x01J7(\x1aa.t\x00\x00\xe0\x94\x0e\xc4f\x96\xff\xac\x1fX\x00_\xa8C\x98$\xf0\x8e\xed\x1d\xf8\x9b\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x0e\xc5\n\xa8#\xf4e\xb9FK\v\xc0\u0125w$\xa5U\xf5\u058a\f\x83\xd1Bj\u01f1\xf0\x00\x00\u07d4\x0e\xc50\x8b1(.!\x8f\xc9\xe7Y\xd4\xfe\xc5\xdb7\b\xce\u01096C\xaady\x86\x04\x00\x00\u07d4\x0e\xcc\xf6\x17\x84O\xd6\x1f\xbab\xcb\x0eD[z\u018b\xcc\x1f\xbe\x89\x14\xfeO\xe65e\xc6\x00\x00\u07d4\x0e\u04fb:N\xb5T\xcf\u0297\x94}WU\a\xcd\xfdm!\u0609\x1d\xb3 _\xcc#\u0540\x00\u07d4\x0e\xd7l,;]P\xff\x8f\xb5\v>\xea\xcdh\x15\x90\xbe\x1c-\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x0e\u0680\xf4\xed\aJ\xeaiz\xed\xdf(;c\xdb\xca=\xc4\u0689lk\x93[\x8b\xbd@\x00\x00\u07d4\x0e\xddKX\x0f\xf1\x0f\xe0lJ\x03\x11b9\xef\x96b+\xae5\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\x0e\xe3\x91\xf0^\u038a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x0f\x92\x9c\xf8\x95\xdb\x01z\xf7\x9f>\xad\"\x16\xb1\xbdi\xc3}\u01c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x0f\xa0\x10\xce\fs\x1d;b\x8e6\xb9\x1fW\x13\x00\u477e\xab\x8963\x03\"\xd5#\x8c\x00\x00\u07d4\x0f\xa5\xd8\u0173\xf2\x94\xef\u0515\xabi\xd7h\xf8\x18rP\x85H\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x0f\xa6\u01f0\x97=\v\xae)@T\x0e$}6'\xe3|\xa3G\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x0f\xad\x05P|\u070f$\xb2\xbeL\xb7\xfa]\x92}\u06d1\x1b\x88\x89\xa2\xdf\x13\xf4A\xf0\t\x80\x00\u07d4\x0f\xb5\xd2\xc6s\xbf\xb1\xdd\xca\x14\x1b\x98\x94\xfdm?\x05\xdag \x89\x05k\xc7^-c\x10\x00\x00\u07d4\x0f\u0260\xe3AE\xfb\xfd\xd2\xc9\u04a4\x99\xb6\x17\u05e0)i\xb9\x89\t\xc2\x00vQ\xb2P\x00\x00\xe0\x94\x0f\xcf\xc4\x06P\b\xcf\xd3#0_b\x86\xb5zM\xd7\xee\xe2;\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x0f\xdde@#\x95\u07db\u045f\xeeE\a\xefSE\xf7E\x10L\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x0f\xecN\xe0\xd7\xca\x18\x02\x90\xb6\xbd \xf9\x99#B\xf6\x0f\xf6\x8d\x89\x12 \u007f\x0e\xdc\xe9q\x80\x00\u07d4\x0f\ue06c3\x1e\xfd\x8f\x81\x16\x1cW8+\xb4P{\xb9\xeb\xec\x89\x15\xaf\x88\r\x8c\u06c3\x00\x00\u07d4\x0f\xfe\xa0mq\x13\xfbj\xec(i\xf4\xa9\u07f0\x90\a\xfa\xce\xf4\x89\f8F\x81\xb1\xe1t\x00\x00\u07d4\x10\tq\x98\xb4\xe7\xee\x91\xff\x82\xcc/;\xd9_\xeds\xc5@\xc0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x10\vM\tw\xfc\xba\xd4\u07bd^d\xa0Iz\xea\xe5\x16\x8f\xab\x89\x11\f\x90s\xb5$Z\x00\x00\xe0\x94\x10\x1a\nd\xf9\xaf\xccD\x8a\x8a\x13\rM\xfc\xbe\xe8\x957\xd8T\x8a\x037\xfe_\xea\xf2\u0440\x00\x00\u07d4\x10,G}i\xaa\u06e9\xa0\xb0\xf6+tY\xe1\u007f\xbb\x1c\x15a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x101\xe0\xec\xb5I\x85\xae!\xaf\x17\x93\x95\r\xc8\x11\x88\x8f\xde|\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x104d\x14\xbe\xc6\xd3\xdc\xc4NP\xe5MT\u00b8\xc3sN>\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x108\x98X\xb8\x00\xe8\xc0\xec2\xf5\x1e\xd6\x1a5YF\xcc@\x9b\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x10Y\xcb\xc6>6\xc4>\x88\xf3\x00\b\xac\xa7\xce\x05\x8e\ua816\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\x10n\xd5\xc7\x19\xb5&\x14w\x89\x04%\xaeuQ\xdcY\xbd%\\\x8a\x02\x89jX\xc9[\xe5\x88\x00\x00\u07d4\x10q\x1c=\xda21x\x85\xf0\xa2\xfd\x8a\xe9.\x82\x06\x9b\r\v\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x10sy\xd4\xc4gFO#[\xc1\x8eU\x93\x8a\xad>h\x8a\u05c9\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94\x10v!-Ou\x8c\x8e\xc7\x12\x1c\x1c}t%I&E\x92\x84\x8a\ai[Y\xb5\xc1{L\x00\x00\u07d4\x10x\xd7\xf6\x1b\x0eV\xc7N\xe6c[.\x18\x19\xef\x1e=\x87\x85\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x10z\x03\xcf\bB\xdb\u07b0a\x8f\xb5\x87\xcai\x18\x9e\xc9/\xf5\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x10\x80\xc1\xd85\x8a\x15\xbc\x84\xda\xc8%\x89\u0392\xb9\x81\x89t\xc1\xfa\xb8\xad\xb4T\x00\x00\u07d4\x10\xe1\xe37x\x85\xc4-}\xf2\x18R.\xe7vh\x87\xc0^j\x89\x10C\xc4<\xde\x1d9\x80\x00\u07d4\x10\u342d+\xa3=\x82\xb3s\x88\u041cED\u01b0\"]\xe5\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x10\xf4\xbf\xf0\u02a5\x02|\nj-\xcf\xc9R\x82M\xe2\x94\t\t\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x11\x00\x1b\x89\xed\x87>:\xae\xc1\x15V4\xb4h\x16C\x98c#\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x11\x027\u03d1\x17\xe7g\x92/\u0121\xb7\x8dyd\u0682\xdf \x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x11\x11\xe5\xdb\xf4^o\x90mb\x86o\x17\b\x10\x17\x88\xdd\xd5q\x89F{\xe6S>\xc2\xe4\x00\x00\xe0\x94\x11\x17+'\x8d\xddD\xee\xa2\xfd\xf4\xcb\x1d\x16\x96#\x91\xc4S\u064a\xc6/=\x9b\xfdH\x95\xf0\x00\x00\u07d4\x11&4\xb4\xec0\xffxn\x02AY\xf7\x96\xa5y9\xea\x14N\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x110l}WX\x867x\x0f\xc9\xfd\xe8\xe9\x8e\xcb\x00\x8f\x01d\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\x116\x12\xbc;\xa0\xeeH\x98\xb4\x9d\xd2\x023\x90_/E\x8fb\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\x11A_\xaba\xe0\xdf\u0539\x06v\x14\x1aUz\x86\x9b\xa0\xbd\xe9\x89o\x05\xb5\x9d; \x00\x00\x00\u07d4\x11L\xbb\xbfo\xb5*\xc4\x14\xbe~\xc6\x1f{\xb7\x14\x95\xce\x1d\xfa\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x11L\xfe\xfeP\x17\r\xd9z\xe0\x8f\nDTIx\u0159T\x8d\x89.\u0207\xe7\xa1J\x1c\x00\x00\u07d4\x11a\b\xc1 \x84a.\xed\xa7\xa9=\xdc\xf8\xd2`.'\x9e\\\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x11d\u02aa\x8c\u0157z\xfe\x1f\xad\x8a}`(\xce-W)\x9b\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x11gZ%UF\a\xa3\xb6\xc9*\x9e\xe8\xf3ou\xed\xd3\xe36\x89\b\xa9\xab\xa5W\xe3l\x00\x00\u07d4\x11j\t\xdff\xcb\x15\x0e\x97W\x8e)\u007f\xb0n\x13\x04\f\x89<\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x11o\xef^`\x16B\xc9\x18\u02c9\x16\x0f\xc2);\xa7\x1d\xa96\x89+|\xc2\xe9\xc3\"\\\x00\x00\u07d4\x11xP\x1f\xf9J\xdd\x1cX\x81\xfe\x88a6\xf6\xdf\xdb\xe6\x1a\x94\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\x11y\xc6\r\xbd\x06\x8b\x15\v\aM\xa4\xbe#\x03; \u0185X\x89$\xdc\xe5M4\xa1\xa0\x00\x00\u07d4\x11}\x9a\xa3\xc4\xd1;\xee\x12\xc7P\x0f\t\xf5\xdd\x1cf\xc4e\x04\x89\v*\xd3\x04\x90\xb2x\x00\x00\xe0\x94\x11}\xb867\u007f\xe1TU\xe0,.\xbd\xa4\v\x1c\xebU\x1b\x19\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x11\x8c\x18\xb2\xdc\xe1p\xe8\xf4Eu;\xa5\xd7Q<\xb7cm-\x8a\x01\xdd\f\x88_\x9a\r\x80\x00\x00\u07d4\x11\x8f\xbdu;\x97\x929Z\xefzMx\xd2c\xcd\u02ab\xd4\xf7\x8963\x03\"\xd5#\x8c\x00\x00\xe0\x94\x11\x92\x83x\xd2}U\xc5 \xce\xed\xf2L\xeb\x1e\x82-\x89\r\xf0\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x11\x9a\xa6M[}\x18\x1d\xae\x9d<\xb4I\x95\\\x89\xc1\xf9c\xfa\x89%\xf2s\x93=\xb5p\x00\x00\xe0\x94\x11\xc05\x8a\xa6G\x9d\xe2\x18f\xfe!\a\x19$\xb6^p\xf8\xb9\x8a\a\xb5?y\xe8\x88\xda\xc0\x00\x00\xe0\x94\x11\xd2$z\"\x1ep\xc2\xd6m\x17\xee\x13\x8d8\xc5_\xfb\x86@\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x11\u05c4JG\x1e\xf8\x9a\x8d\x87uUX<\xee\xbd\x149\xea&\x8a\x02#i\u6e80\u0188\x00\x00\u07d4\x11\xdda\x85\u0668\xd7=\xdf\u06a7\x1e\x9bwtC\x1cM\xfe\u008965\u026d\xc5\u07a0\x00\x00\u07d4\x11\xe7\x99~\u0750E\x03\xd7}\xa6\x03\x8a\xb0\xa4\xc84\xbb\xd5c\x89\x15\b\x94\xe8I\xb3\x90\x00\x00\u07d4\x11\xec\x00\xf8I\xb61\x9c\xf5\x1a\xa8\u074ff\xb3U)\xc0\xbew\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x11\ufe22\x04Q\x16\x1bdJ\x8c\u03bb\xc1\xd3C\xa3\xbb\xcbR\x89\xadx\xeb\u016cb\x00\x00\x00\xe0\x94\x11\xfe\xfb]\xc1\xa4Y\x8a\xa7\x12d\fQwu\u07e1\xd9\x1f\x8c\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x12\x0f\x9d\xe6\xe0\xaf~\xc0*\a\xc6\t\u0284G\xf1W\xe64L\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\x12\x10\xf8\v\u06c2l\x17Tb\xab\a\x16\xe6\x9eF\xc2J\xd0v\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x12\x13N\u007fk\x01{\xf4\x8e\x85Z9\x9c\xa5\x8e.\x89/\xa5\u020965\u026d\xc5\u07a0\x00\x00\u07d4\x12\x170t\x98\x01S\xae\xaaK\r\xcb\xc7\x13.\xad\xce\xc2\x1bd\x89\r\x02\xabHl\xed\xc0\x00\x00\u07d4\x12\x1f\x85[p\x14\x9a\xc84s\xb9po\xb4MG\x82\x8b\x98;\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x12'\xe1\nM\xbf\x9c\xac\xa3\x1b\x17\x80#\x9fUv\x15\xfc5\xc1\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x12-\xcf\xd8\x1a\u0779}\x1a\x0eI%\u0135I\x80n\x9f;\xeb\x89R 5\xccn\x01!\x00\x00\u07d4\x12/V\x12%I\xd1h\xa5\xc5\xe2g\xf5&b\xe5\xc5\xcc\xe5\u0209\n\ad\a\xd3\xf7D\x00\x00\xe0\x94\x121o\xc7\xf1x\xea\xc2.\xb2\xb2Z\xed\xea\xdf=u\xd0\x01w\x8a\x04<3\xbe\x05\xf6\xbf\xb9\x80\x00\xe0\x94\x127Y\xf33\xe1>0i\xe2\x03KO\x059\x89\x18\x11\x9d6\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x12\\\xc5\xe4\xd5k+\xcc.\xe1\xc7\t\xfb\x9eh\xfb\x17t@\xbd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x12c#\x88\xb2v^\xe4E+P\x16\x1d\x1f\xff\xd9\x1a\xb8\x1fJ\x89(\x1d\x90\x1fO\xdd\x10\x00\x00\u07d4\x12h\x97\xa3\x11\xa1J\xd4;x\xe0\x92\x01\x00\xc4Bk\xfdk\u07494\xc7&\x89?-\x94\x80\x00\u07d4\x12m\x91\xf7\xad\x86\u07bb\x05W\xc6\x12\xca'n\xb7\xf9m\x00\xa1\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x12}?\xc5\x00;\xf6<\r\x83\xe99W\x83e\x15\xfd'\x90E\x89\x06\x10\xc9\".nu\x00\x00\xe0\x94\x12}\xb1\xca\xdf\x1bw\x1c\xbdtu\xe1\xb2ri\x0fU\x8c\x85e\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\x12\x84\xf0\xce\xe9\xd2\xff)\x89\xb6Ut\xd0o\xfd\x9a\xb0\xf7\xb8\x05\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x12\x8b\x90\x8f\xe7C\xa44 =\xe2\x94\xc4A\xc7\xe2\n\x86\xeag\x89&\xab\x14\xe0\xc0\xe1<\x00\x00\xe0\x94\x12\x93\u01cc}jD;\x9dt\xb0\xba^\xe7\xbbG\xfdA\x85\x88\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\x12\x96\xac\xde\xd1\xe0c\xaf9\xfe\x8b\xa0\xb4\xb6=\xf7\x89\xf7\x05\x17\x89\x05k\xf9\x1b\x1ae\xeb\x00\x00\u07d4\x12\xaa}\x86\xdd\xfb\xad0\x16\x92\xfe\xac\x8a\b\xf8A\xcb!\\7\x89\amA\xc6$\x94\x84\x00\x00\xe0\x94\x12\xaf\xbc\xba\x14'\xa6\xa3\x9e{\xa4\x84\x9fz\xb1\xc45\x8a\xc3\x1b\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x12\xb5\xe2\x89E\xbb)i\xf9\xc6Lc\xcc\x05\xb6\xf1\xf8\xd6\xf4\u054a\x01\xa2\x9e\x86\x91;t\x05\x00\x00\u0794\x12\u03cb\x0eFR\x13!\x1a[S\u07f0\xdd'\x1a(,\x12\u0248\xd2\xf1?w\x89\xf0\x00\x00\u07d4\x12\xd2\a\x90\xb7\xd3\xdb\u060c\x81\xa2y\xb8\x12\x03\x9e\x8a`;\u0409V\xf9\x85\u04c6D\xb8\x00\x00\xe0\x94\x12\xd6\re\xb7\xd9\xfcH\x84\v\xe5\xf8\x91\xc7E\xcev\xeeP\x1e\x8a\x04\x85\xe58\x8d\fv\x84\x00\x00\u0794\x12\xd9\x1a\x92\xd7O\xc8a\xa7)dm\xb1\x92\xa1%\xb7\x9fSt\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\x12\u992d*\xd5t\x84\xddp\x05e\xbd\xdbFB;\u067d1\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4\x12\xf3,\n\x1f-\xaa\xb6v\xfei\xab\xd9\xe0\x185-L\xcdE\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\x12\xf4`\xaedl\xd2x\x0f\xd3\\P\xa6\xafK\x9a\xcc\xfa\x85\u018965\u026d\xc5\u07a0\x00\x00\u07d4\x12\xff\xc1\x12\x86\x05\xcb\f\x13p\x9ar\x90Po&\x90\x97q\x93\x89\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4\x13\x03$F\xe7\xd6\x10\xaa\x00\xec\x8cV\u0275t\xd3l\xa1\xc0\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x13\x1cy,\x19}\x18\xbd\x04]p$\x93|\x1f\x84\xb6\x0fD8\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x13\x1d\xf8\xd30\xeb|\xc7\x14}\nUWo\x05\u078d&\xa8\xb7\x89\n1\x06+\xee\xedp\x00\x00\u07d4\x13\x1f\xae\xd1%a\xbbz\xee\x04\xe5\x18Z\xf8\x02\xb1\xc3C\x8d\x9b\x89\v\xdf\x0e\u0733\x90\xc9\xc8V\b\xb7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x13!\xcc\xf2\x979\xb9t\xe5\xa5\x16\xf1\x8f:\x846q\xe3\x96B\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x13'\xd7Y\xd5n\n\xb8z\xf3~\xcfc\xfe\x01\xf3\x10\xbe\x10\n\x89#\xbc<\xdbh\xa1\x80\x00\x00\u07d4\x13)\xdd\x19\xcdK\xaa\x9f\xc6C\x10\xef\xec\xea\xb2!\x17%\x1f\x12\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x137\x1f\x92\xa5n\xa88\x1eC\x05\x9a\x95\x12\x8b\xdcMC\u0166\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x13O\x15\xe1\xe3\x9cSCY0\xaa\xed\xf3\xe0\xfeV\xfd\xe8C\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x13Ac\xbe\x9f\xbb\xe1\xc5in\xe2U\xe9\v\x13%C\x95\xc3\x18\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x13\\\xec\xd9U\xe5y\x83pv\x920\x15\x93\x03\u0671\x83\x9ff\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x13]\x17\x19\xbf\x03\xe3\xf8f1$y\xfe3\x81\x18\xcd8~p\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x13^\xb8\xc0\xe9\xe1\x01\xde\xed\xec\x11\xf2\xec\xdbf\xae\x1a\xae\x88g\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x13`\xe8}\xf2Li\xeemQ\xc7nsv\u007f\xfe\x19\xa2\x13\x1c\x89\x04\xfc\xc1\xa8\x90'\xf0\x00\x00\u07d4\x13l\x83K\xf1\x112m s\x95)[.X>\xa7\xf35r\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x13mKf+\xbd\x10\x80\xcf\xe4D[\x0f\xa2\x13\x86D5\xb7\xf1\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x13oI\a\u02b4\x1e'\bK\x98E\x06\x9f\xf2\xfd\f\x9a\xdey\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x13t\xfa\xcd{?\x8dhd\x9d`\xd4U\x0e\xe6\x9f\xf0HA3\x89\x0e\x9e\xd6\xe1\x11r\xda\x00\x00\u07d4\x13|\xf3A\xe8Ql\x81X\x14\xeb\xcds\xe6V\x9a\xf1L\xf7\xbc\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x13\x84\x8bF\xeau\xbe\xb7\xea\xa8_Y\xd8f\xd7\u007f\xd2L\xf2\x1a\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\x13\x9d51\u0252*\xd5bi\xf60\x9a\xa7\x89\xfb$\x85\xf9\x8c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x13\x9eG\x97d\xb4\x99\xd6f \x8cJ\x8a\x04z\x97\x041c\u0749 w!*\xffm\xf0\x00\x00\u07d4\x13\xa5\xee\xcb80]\xf9Iq\xef-\x9e\x17\x9a\xe6\u03ba\xb37\x89\x11\u3ac3\x95\xc6\xe8\x00\x00\u07d4\x13\xac\xad\xa8\x98\n\xff\xc7PI!\xbe\x84\xebID\xc8\xfb\xb2\xbd\x89V\u04aa:\\\t\xa0\x00\x00\u07d4\x13\xb9\xb1\a\x15qL\t\xcf\xd6\x10\u03dc\x98F\x05\x1c\xb1\xd5\x13\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x13\xce3-\xffe\xa6\xab\x938\x97X\x8a\xa2>\x00\t\x80\xfa\x82\x89\x0e\x02\x056\xf0(\xf0\x00\x00\u07d4\x13\xd6z~%\xf2\xb1,\u06c5XP\t\xf8\xac\u011b\x96s\x01\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x13\xde\xe0>7\x99\x95-\a8\x84=K\xe8\xfc\n\x80?\xb2\x0e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x13\xe0/\xb4H\xd6\xc8J\xe1}\xb3\x10\xad(m\x05a`\u0695\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x13\xe3!r\x8c\x9cWb\x80X\xe9?\xc8f\xa02\xdd\v\u0690\x89&\xbc\xca#\xfe.\xa2\x00\x00\u07d4\x13\xec\x81\"\x84\x02n@\x9b\xc0f\xdf\xeb\xf9\u0564\xa2\xbf\x80\x1e\x89WG=\x05\u06ba\xe8\x00\x00\xe0\x94\x14\x01)\xea\xa7f\xb5\xa2\x9f[:\xf2WND\t\xf8\xf6\xd3\xf1\x8a\x01Z\xf1\u05cbX\xc4\x00\x00\x00\u07d4\x14\x05\x18\xa3\x19K\xad\x13P\xb8\x94\x9ee\x05e\u07bem\xb3\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x14\x06\x85M\x14\x9e\b\x1a\xc0\x9c\xb4\xcaV\r\xa4c\xf3\x120Y\x89Hz\x9a0E9D\x00\x00\u07d4\x14\f\xa2\x8f\xf3;\x9ff\xd7\xf1\xfc\x00x\xf8\xc1\xee\xf6\x9a\x1b\xc0\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\x14\x0f\xbaX\xdb\xc0H\x03\xd8L!0\xf0\x19x\xf9\xe0\xc71)\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\x14\x1a^9\xee/h\n`\x0f\xbfo\xa2\x97\u0790\xf3\"\\\u074a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x14%N\xa1&\xb5-\x01B\xda\n~\x18\x8c\xe2U\xd8\xc4qx\x89*\x03I\x19\u07ff\xbc\x00\x00\u07d4\x14+\x87\xc5\x04?\xfbZ\x91\xdf\x18\xc2\xe1\t\xce\xd6\xfeJq\u06c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x14\x87\xf5\xa5$\u0288Q^\x8a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4\x14\xa75 f6D\x04\xdbP\xf0\xd0\u05cduJ\"\x19\x8e\xf4\x89e\xea=\xb7UF`\x00\x00\u07d4\x14\xab\x16K;RL\x82\u05ab\xfb\xc0\u0783\x11&\xae\x8d\x13u\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x14\xb1`>\xc6+ \x02 3\xee\xc4\xd6\xd6eZ\xc2J\x01Z\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94\x14\xc6;\xa2\u0731\xddM\xf3=\u06b1\x1cO\x00\a\xfa\x96\xa6-\x8a\x03HA\xb6\x05z\xfa\xb0\x00\x00\xe0\x94\x14\xcd\u077c\x8b\t\xe6gZ\x9e\x9e\x05\t\x1c\xb9\"8\u00de\x1e\x8a\x01\x14x\xb7\xc3\n\xbc0\x00\x00\u07d4\x14\xd0\n\xad9\xa0\xa7\u045c\xa0SP\xf7\xb07'\xf0\x8d\xd8.\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x14\xee\xc0\x9b\xf0>5+\xd6\xff\x1b\x1e\x87k\xe6d\xce\xff\xd0\u03c9\x01\x16\xdc:\x89\x94\xb3\x00\x00\u07d4\x14\xf2!\x15\x95\x18x;\u0127\x06go\xc4\xf3\xc5\xee@X)\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x14\xfc\xd19\x1e}s/Avl\xda\u0344\xfa\x1d\xeb\x9f\xfd\u0489lk\x93[\x8b\xbd@\x00\x00\u07d4\x15\x0e=\xbc\xbc\xfc\x84\xcc\xf8\x9bsBwc\xa5e\xc2>`\u0409\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\x15\x18b{\x885\x1f\xed\xe7\x96\xd3\xf3\b3d\xfb\u0508{\f\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u0794\x15\"J\xd1\xc0\xfa\xceF\xf9\xf5V\xe4wJ0%\xad\x06\xbdR\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\x15/+\xd2)\xdd\xf3\xcb\x0f\xda\xf4U\xc1\x83 \x9c\x0e\x1e9\xa2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x15/N\x86\x0e\xf3\xee\x80jP'w\xa1\xb8\xdb\xc9\x1a\x90vh\x89 \x86\xac5\x10R`\x00\x00\u07d4\x15<\b\xaa\x8b\x96\xa6\x11\xefc\xc0%>*C4\x82\x9eW\x9d\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\x15<\xf2\x84,\xb9\u0787l'o\xa6Gg\u0468\xec\xf5s\xbb\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x15>\xf5\x8a\x1e.z>\xb6\xb4Y\xa8\n\xb2\xa5G\xc9A\x82\xa2\x8a\x14T+\xa1*3|\x00\x00\x00\u07d4\x15DY\xfa/!1\x8e44D\x97\x89\xd8&\xcd\xc1W\f\xe5\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x15G\xb9\xbfz\xd6bt\xf3A8'#\x1b\xa4\x05\ue308\xc1\x8a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u07d4\x15H\xb7p\xa5\x11\x8e\u0787\u06e2\xf6\x903\u007fam\u60eb\x89\x1c\x99V\x85\u0fc7\x00\x00\u07d4\x15R\x83P\xe0\xd9g\n.\xa2\u007f{J3\xb9\xc0\xf9b\x1d!\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\x15[7y\xbbmV4./\u0681{[-\x81\xc7\xf4\x13'\x89\x02\xb8\xaa:\al\x9c\x00\x00\u07d4\x15e\xaf\x83~\xf3\xb0\xbdN+#V\x8dP#\xcd4\xb1d\x98\x89\x15Q\xe9rJ\u013a\x00\x00\u07d4\x15f\x91\x80\xde\u2558\x86\x9b\b\xa7!\xc7\xd2LL\x0e\xe6?\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x15r\xcd\xfa\xb7*\x01\u0396\x8ex\xf5\xb5D\x8d\xa2\x98S\xfb\u074a\x01\x12blI\x06\x0f\xa6\x00\x00\xe0\x94\x15uY\xad\xc5Wd\xccm\xf7\x93#\t%4\xe3\xd6dZf\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x15x\xbd\xbc7\x1bM$8E3\x05V\xff\xf2\xd5\xefM\xffg\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x15~\xb3\xd3\x11;\u04f5\x97qM:\x95N\xdd\x01\x89\x82\xa5\u02c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x15\x84\xa2\xc0f\xb7\xa4U\xdb\u05ae(\a\xa73N\x83\xc3_\xa5\x89\a\f\x1c\xc7;\x00\xc8\x00\x00\u07d4\x15\x87F\x86\xb6s=\x10\xd7\x03\xc9\xf9\xbe\xc6\xc5.\xb8b\x8dg\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x15\x8a\ra\x92S\xbfD2\xb5\xcd\x02\u01f8b\xf7\u00b7V6\x89\a[\xac|[\x12\x18\x80\x00\u07d4\x15\x98\x12y\x82\xf2\xf8\xad;k\x8f\xc3\xcf'\xbfax\x01\xba+\x89\t`\xdbwh\x1e\x94\x00\x00\xe0\x94\x15\x9a\xdc\xe2z\xa1\vG#d)\xa3JZ\xc4,\xad[d\x16\x8a\x06\xbf\x90\xa9n\xdb\xfaq\x80\x00\u07d4\x15\xa0\xae\xc3\u007f\xf9\xff=T\t\xf2\xa4\xf0\xc1!*\xac\xcb\x02\x96\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x15\xaaS\r\xc3iX\xb4\xed\xb3\x8e\xeem\xd9\xe3\xc7}L\x91E\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x15\xac\xb6\x15h\xecJ\xf7\xea(\x198a\x81\xb1\x16\xa6\xc5\xeep\x8a\x06\x90\x83l\n\xf5\xf5`\x00\x00\u07d4\x15\xb9o0\xc2;\x86d\xe7I\x06Q\x06k\x00\xc49\x1f\xbf\x84\x89\x16B\xe9\xdfHv)\x00\x00\u07d4\x15\xc7\xed\xb8\x11\x8e\xe2{4\"\x85\xebY&\xb4z\x85[\u01e5\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x15\u0654hPz\xa0A?\xb6\r\xca*\xdc\u007fV\x9c\xb3kT\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x15\u06f4\x8c\x980\x97d\xf9\x9c\xed6\x92\xdc\xca5\xee0k\xac\x8a\x1f\u00c4+\xd1\xf0q\xc0\x00\x00\xe0\x94\x15\u072f\xcc+\xac\xe7\xb5[T\xc0\x1a\x1cQF&\xbfa\xeb\u060a\x01\xfd\x934\x94\xaa_\xe0\x00\x00\u07d4\x15\u3d44\x05kb\xc9s\xcf^\xb0\x96\xf1s>T\xc1\\\x91\x892\xc7Z\x02#\xdd\xf3\x00\x00\u07d4\x15\xeb\xd1\xc7\xca\u04af\xf1\x92u\xc6W\xc4\xd8\b\xd0\x10\xef\xa0\xf5\x89\n\xdf0\xbap\u0217\x00\x00\u07d4\x15\xee\x0f\xc6>\xbf\x1b\x1f\u011d{\xb3\x8f\x88c\x82:.\x17\u0489g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x15\xf1\xb3R\x11\rh\x90\x1d\x8fg\xaa\xc4jl\xfa\xfe\x03\x14w\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x15\xf2\xb7\xb1d2\xeeP\xa5\xf5[A#/c4\xedX\xbd\xc0\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x16\x01\x9aM\xaf\xabC\xf4\u067fAc\xfa\xe0\x84}\x84\x8a\xfc\xa2\x89\x01[\xc7\x019\xf7J\x00\x00\u07d4\x16\x02&\xef\xe7\xb5:\x8a\xf4b\xd1\x17\xa0\x10\x80\x89\xbd\xec\xc2\u0449\n\xdf0\xbap\u0217\x00\x00\u07d4\x16\f\xebo\x98\x0e\x041_S\xc4\xfc\x98\x8b+\xf6\x9e(M}\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\xe0\x94\x16\x1c\xafZ\x97*\u0383y\xa6\u0420J\xe6\xe1c\xfe!\xdf+\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\x16\x1d&\xefgY\xba[\x9f \xfd\xcdf\xf1a2\xc3RA^\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16!\x10\xf2\x9e\xac_}\x02\xb5C\xd8\xdc\u057bY\xa5\xe3;s\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x16+\xa5\x03'b\x14\xb5\t\xf9u\x86\xbd\x84!\x10\xd1\x03\xd5\x17\x8a\x01\xe7\xff\u0609\\\"h\x00\x00\u07d4\x16-v\xc2\xe6QJ:\xfbo\xe3\xd3\u02d3\xa3\\Z\xe7\x83\xf1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16;\xadJ\x12+E}d\xe8\x15\nA>\xaeM\a\x02>k\x89\x01\x04\xe7\x04d\xb1X\x00\x00\u07d4\x16<\u023e\"vF\xcb\tq\x91Y\xf2\x8e\u041c]\xc0\xdc\xe0\x89Hz\x9a0E9D\x00\x00\u07d4\x16=\xcas\xd7\xd6\xea?>`b2*\x874\x18\f\vx\uf25ft \x03\xcb}\xfc\x00\x00\u07d4\x16Mz\xac>\xec\xba\uc86dQ\x91\xb7S\xf1s\xfe\x12\xec3\x89(VR\xb8\xa4hi\x00\x00\u07d4\x16Rl\x9e\u07d4>\xfaOm\x0f\v\xae\x81\xe1\x8b1\xc5@y\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\x16S\x05\xb7\x872.%\xdcj\xd0\xce\xfelo3Fx\xd5i\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16e\xab\x179\xd7\x11\x19\xeea2\xab\xbd\x92j'\x9f\xe6yH\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\x16k\xf6\u06b2-\x84\x1bHl8\xe7\xbaj\xb3:\x14\x87\ud30a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x16v\x99\xf4\x8ax\xc6\x15Q%\x15s\x99X\x993\x12WO\a\x89\x02\x1d;\xd5^\x80<\x00\x00\u07d4\x16x\xc5\xf2\xa5\"92%\x19ca\x89OS\xccu/\xe2\xf3\x89h\xf3e\xae\xa1\xe4@\x00\x00\u07d4\x16|\xe7\xdee\xe8G\bYZRT\x97\xa3\xeb^ZfPs\x89\x1f1Gsfo\xc4\x00\x00\u07d4\x16~>:\xe2\x003HE\x93\x92\xf7\xdf\xceD\xaf|!\xadY\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x16\x80\xce\xc5\x02\x1e\xe90P\xf8\xae\x12rQ\x83\x9et\xc1\xf1\xfd\x8a\x02\xc6\x14a\xe5\xd7C\u0580\x00\u07d4\x16\x81j\xac\x0e\xde\r-<\xd4B\xday\xe0c\x88\x0f\x0f\x1dg\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x16\x8bP\x19\xb8\x18i\x16D\x83_\xe6\x9b\xf2)\xe1q\x12\xd5,\x8a\x05\xed\xe2\x0f\x01\xa4Y\x80\x00\x00\u07d4\x16\x8b\xde\xc8\x18\xea\xfcm)\x92\xe5\xefT\xaa\x0e\x16\x01\xe3\xc5a\x8967Pz0\xab\xeb\x00\x00\u07d4\x16\x8d0\xe5?\xa6\x81\t+R\xe9\xba\xe1Z\r\xcbA\xa8\u027b\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x16\x9b\xbe\xfcA\xcf\xd7\xd7\u02f8\xdf\xc60 \xe9\xfb\x06\u0515F\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16\xa5\x8e\x98]\xcc\xd7\a\xa5\x94\u0453\xe7\u0327\x8b]\x02xI\x89I\xb9\u029aiC@\x00\x00\u07d4\x16\xa9\xe9\xb7:\u92c6M\x17(y\x8b\x87f\xdb\xc6\xea\x8d\x12\x893\xe7\xb4K\r\xb5\x04\x00\x00\u07d4\x16\xaaR\xcb\vUG#\xe7\x06\x0f!\xf3'\xb0\xa6\x83\x15\xfe\xa3\x89\r\x8drkqw\xa8\x00\x00\u07d4\x16\xab\xb8\xb0!\xa7\x10\xbd\u01ce\xa54\x94\xb2\x06\x14\xffN\xaf\xe8\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\x16\xaf\xa7\x87\xfc\x9f\x94\xbd\xffiv\xb1\xa4/C\n\x8b\xf6\xfb\x0f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16\xba\xe5\xd2N\xff\x91w\x8c\u064bM:\x1c\xc3\x16/D\xaaw\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\x16\xbc@!Z\xbb\u066e](\v\x95\xb8\x01\vE\x14\xff\x12\x92\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x16\xbeu\u9299Z9R\"\xd0\v\u05df\xf4\xb6\xe68\u144a\a\x9f\x90\\o\xd3N\x80\x00\x00\u07d4\x16\xc1\xbf[}\xc9\xc8<\x17\x9e\xfa\xcb\xcf.\xb1t\xe3V\x1c\xb3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x16\u01f3\x1e\x8c7b\x82\xac\"qr\x8c1\xc9^5\xd9R\u00c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x16\xf3\x13\u03ca\xd0\x00\x91J\n\x17m\u01a44+y\xec%8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x16\xff\xac\x84\x03)@\xf0\x12\x1a\tf\x8b\x85\x8a~y\xff\xa3\xbb\x89\xd2J\xdan\x10\x87\x11\x00\x00\xe0\x94\x17\x03\xb4\xb2\x92\xb8\xa9\xde\xdd\xed\xe8\x1b\xb2]\x89\x17\x9fdF\xb6\x8a\x04+e\xa4U\xe8\xb1h\x00\x00\u07d4\x17\x04\x93\x11\x10\x1d\x81~\xfb\x1de\x91\x0ff6b\xa6\x99\u024c\x89lh\xcc\u041b\x02,\x00\x00\u07d4\x17\x04\xce\xfc\xfb\x131\xeczx8\x8b)9>\x85\xc1\xafy\x16\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x17\n\x88\xa8\x99\u007f\x92\xd287\x0f\x1a\xff\xde\xe64pP\xb0\x13\x89\xa2\xacw5\x14\x880\x00\x00\u07d4\x17\x10\x8d\xab,P\xf9\x9d\xe1\x10\u1cf3\xb4\u0342\xf5\xdf(\xe7\x895 ;g\xbc\xca\xd0\x00\x00\xe0\x94\x17\x12[Y\xacQ\xce\xe0)\xe4\xbdx\xd7\xf5\x94}\x1e\xa4\x9b\xb2\x8a\x04\xa8\x9fT\xef\x01!\xc0\x00\x00\u07d4\x17\x1a\u0660K\xed\u0238a\xe8\xedK\xdd\xf5qx\x13\xb1\xbbH\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x17\x1c\xa0*\x8bmb\xbfL\xa4~\x90i\x14\a\x98a\x97,\xb2\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x17\"\xc4\xcb\xe7\n\x94\xb6U\x9dBP\x84\xca\xee\xd4\xd6\xe6n!\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x17X\vvotSR\\\xa4\u01a8\x8b\x01\xb5\x05p\xea\b\x8c\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x17X\x9al\x00jT\xca\xd7\x01\x03\x12:\xae\n\x82\x13_\u07b4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x17Z\x18::#_\xfb\xb0;\xa85gRg\"\x94\x17\xa0\x91\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\x17_\xee\xea*\xa4\xe0\xef\xda\x12\xe1X\x8d/H2\x90\xed\xe8\x1a\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x17e6\x1c.\xc2\xf86\x16\u0383c\xaa\xe2\x10%\xf2Vo@\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x17gR\\_Z\"\xed\x80\xe9\xd4\xd7q\x0f\x03b\u049e\xfa3\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x17v%`\xe8*\x93\xb3\xf5\"\xe0\xe5$\xad\xb8a,:tp\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x17}\xaex\xbc\x01\x13\xd8\u04dcD\x02\xf2\xa6A\xae*\x10Z\xb8\x89b\x92BV \xb4H\x00\x00\xe0\x94\x17\x84\x94\x8b\xf9\x98H\u021eDV8PM\u0598'\x1bY$\x8a\x01GLA\r\x87\xba\xee\x00\x00\u07d4\x17\x88\u069bW\xfd\x05\xed\xc4\xff\x99\xe7\xfe\xf3\x01Q\x9c\x8a\n\x1e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x17\x8e\xafk\x85T\xc4]\xfd\xe1kx\xce\f\x15\u007f.\xe3\x13Q\x89\x11X\xe4`\x91=\x00\x00\x00\u07d4\x17\x96\x1dc;\xcf \xa7\xb0)\xa7\xd9K}\xf4\xda.\xc5B\u007f\x89\fo\xf0p\U000532c0\x00\u07d4\x17\x96\xbc\xc9{\x8a\xbcq\u007fKJ|k\x106\xea!\x82c\x9f\x89\x13A\xf9\x1c\xd8\xe3Q\x00\x00\u07d4\x17\x99=1*\xa1\x10iW\x86\x8fjU\xa5\xe8\xf1/w\xc8C\x89\x18e\xe8\x14\xf4\x14.\x80\x00\u07d4\x17\x9a\x82^\x0f\x1fn\x98S\tf\x84e\xcf\xfe\xd46\xf6\xae\xa9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x17\xb2\xd6\xcfe\xc6\xf4\xa3G\xdd\xc6W&U5M\x8aA+)\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x17\xb8\a\xaf\xa3\xdd\xd6G\xe7#T.{R\xfe\xe3\x95'\xf3\x06\x89\x15\xaf@\xff\xa7\xfc\x01\x00\x00\u07d4\x17\xc0G\x86W\xe1\xd3\xd1z\xaa3\x1d\xd4)\xce\u03d1\xf8\xae]\x8964\xfb\x9f\x14\x89\xa7\x00\x00\u07d4\x17\xc0\xfe\xf6\x98l\xfb.@A\xf9\x97\x9d\x99@\xb6\x9d\xff=\xe2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x17\u0511\x8d\xfa\xc1]w\xc4\u007f\x9e\xd4\x00\xa8P\x19\rd\xf1Q\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x17\xd5!\xa8\xd9w\x90#\xf7\x16M#<;d \xff\xd2#\xed\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x17\xd91\xd4\xc5b\x94\u073ew\xc8e[\xe4i_\x00mJ<\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x17\xdfIQ\x8ds\xb1)\xf0\xda6\xb1\u0274\f\xb6d \xfd\u01ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x17\xe4\xa0\xe5+\xac>\xe4N\xfe\tT\xe7S\u0538]dN\x05\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x17\xe5\x84\xe8\x10\xe5gp,a\xd5]CK4\u0375\xee0\xf6\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x17\xe8.px\xdcO\xd9\xe8y\xfb\x8aPf\u007fS\xa5\xc5E\x91\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x17\xe8o;[0\xc0\xbaY\xf2\xb2\xe8XB[\xa8\x9f\n\x10\xb0\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x17\xee\x9fT\xd4\xdd\xc8Mg\x0e\xff\x11\xe5Je\x9f\xd7/DU\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\xe0\x94\x17\xefJ\xcc\x1b\xf1G\xe3&t\x9d\x10\xe6w\xdc\xff\xd7o\x9e\x06\x8a\bwQ\xf4\xe0\xe1\xb50\x00\x00\u07d4\x17\xf1F2\xa7\xe2\x82\v\xe6\xe8\xf6\u07c25X(=\xad\xab-\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x17\xf5#\xf1\x17\xbc\x9f\xe9x\xaaH\x1e\xb4\xf5V\x17\x117\x1b\u0209li\xf7>)\x13N\x00\x00\u07d4\x17\xfd\x9bU\x1a\x98\xcba\xc2\xe0\u007f\xbfA\xd3\xe8\u02650\u02e5\x89\x01v\x8c0\x81\x93\x04\x80\x00\u07d4\x18\x04x\xa6U\u05cd\x0f;\fO +aH[\xc4\x00/\u0549lk\x93[\x8b\xbd@\x00\x00\u07d4\x18\x13l\x9d\xf1g\xaa\x17\xb6\xf1\x8e\"\xa7\x02\u020fK\u0082E\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x18\x15'\x9d\xff\x99R\xda;\xe8\xf7rI\xdb\xe2\"C7{\xe7\x8a\x01\x01|\xb7n{&d\x00\x00\u07d4\x18\x1f\xbb\xa8R\xa7\xf5\x01x\xb1\xc7\xf0>\xd9\xe5\x8dT\x16))\x89$\x1a\x9bOaz(\x00\x00\xe0\x94\x18'\x03\x9f\tW\x02\x94\b\x8f\xdd\xf0G\x16\\3\u65a4\x92\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\x18-\xb8R\x93\xf6\x06\u8248\xc3pL\xb3\xf0\xc0\xbb\xbf\xcaZ\x89\a?u\u0460\x85\xba\x00\x00\u07d4\x18H\x00<%\xbf\u052a\x90\xe7\xfc\xb5\u05f1k\xcd\f\xff\xc0\u060965\u026d\xc5\u07a0\x00\x00\xe0\x94\x18JO\v\xebq\xff\xd5X\xa6\xb6\xe8\xf2(\xb7\x87\x96\xc4\xcf>\x8a\x02\x8a\x85t%Fo\x80\x00\x00\xe0\x94\x18M\x86\xf3Fj\xe6h;\x19r\x99\x82\xe7\xa7\u1903G\xb2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x18Q\xa0c\xcc\xdb0T\x90w\xf1\xd19\xe7-\xe7\x97\x11\x97\u0549lk\x93[\x8b\xbd@\x00\x00\u07d4\x18UF\xe8v\x8dPhs\x81\x8a\xc9u\x1c\x1f\x12\x11j;\xef\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x18X\xcf\x11\xae\xa7\x9fS\x98\xad+\xb2\"g\xb5\xa3\xc9R\xeat\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\xe0\x94\x18Z\u007f\u012c\xe3h\xd23\xe6 \xb2\xa4Y5f\x12\x92\xbd\xf2\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x18d\xa3\u01f4\x81UD\x8cT\u020cp\x8f\x16g\tsm1\x89\a?u\u0460\x85\xba\x00\x00\u07d4\x18j\xfd\xc0\x85\xf2\xa3\xdc\xe4a^\xdf\xfb\xad\xf7\x1a\x11x\x0fP\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x18k\x95\xf8\xe5\xef\xfd\xdc\xc9O\x1a1[\xf0)];\x1e\xa5\x88\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x18}\x9f\f\a\xf8\xebt\xfa\xaa\xd1^\xbc{\x80Dt\x17\xf7\x82\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x18\x95\xa0\xebJCrr/\xcb\u016f\xe6\x93o(\x9c\x88\xa4\x19\x891T\xc9r\x9d\x05x\x00\x00\u07d4\x18\x99\xf6\x9fe;\x05\xa5\xa6\xe8\x1fH\a\x11\u041b\xbf\x97X\x8c\x89i\xfb\x13=\xf7P\xac\x00\x00\u07d4\x18\xa6\xd2\xfcR\xbes\b@#\xc9\x18\x02\xf0[\xc2JK\xe0\x9f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x18\xb0@|\xda\xd4\xceR`\x06#\xbd^\x1fj\x81\xaba\xf0&\x89\x11Q\xcc\xf0\xc6T\u0180\x00\u07d4\x18\xb8\xbc\xf9\x83!\xdaa\xfbN>\xac\xc1\xecT\x17'-\xc2~\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4\x18\xc6r:gS)\x9c\xb9\x14G}\x04\xa3\xbd!\x8d\xf8\xc7u\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x18\xe1\x13\xd8\x17|i\x1aa\xbexXR\xfa[\xb4z\uef6f\x89Hz\x9a0E9D\x00\x00\xe0\x94\x18\xe4\xceGH;S\x04\n\u06eb5\x17,\x01\xefdPn\f\x8a\x01\xe7\xe4\x17\x1b\xf4\u04e0\x00\x00\xe0\x94\x18\xe52C\x98\x1a\xab\xc8v}\xa1\fsD\x9f\x13\x91V\x0e\xaa\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x18\xfa\x86%\xc9\u0704>\x00\x15\x9e\x892\xf5\x1e\u06ea\xa30\x00\x00\xe0\x94\x193\xe34\xc4\x0f:\u02ed\f\v\x85\x11X i$\xbe\xca:\x8a\x01\x99^\xaf\x01\xb8\x96\x18\x80\x00\xe0\x94\x197\xc5\xc5\x15\x05uS\u033dF\u0546dU\xcef)\x02\x84\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\u07d4\x19:\xc6Q\x83e\x18\x00\xe25\x80\xf8\xf0\xea\u04fbY~\xb8\xa4\x89\x02\xb6*\xbc\xfb\x91\n\x00\x00\u07d4\x19=7\xed4}\x1c/N55\r\x9aDK\xc5|\xa4\xdbC\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94\x19@\u0713d\xa8R\x16_GAN'\xf5\x00$E\xa4\xf1C\x8a\x02L-\xffj<|H\x00\x00\u07d4\x19E\xfe7\u007f\xe6\u0537\x1e>y\x1fo\x17\xdb$<\x9b\x8b\x0f\x89vy\u7fb9\x886\x00\x00\u07d4\x19Jk\xb3\x02\xb8\xab\xa7\xa5\xb5y\u07d3\xe0\xdf\x15t\x96v%\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x19L\ubd12\x98\x82\xbf;K\xf9\x86L+\x1b\x0fb\u0083\xf9\x89\x1e\xf8aS\x1ft\xaa\x00\x00\u07d4\x19O\xf4J\xef\xc1{\xd2\x0e\xfdz LG\xd1b\f\x86\xdb]\x89\xa2\x99\th\u007fj\xa4\x00\x00\xe0\x94\x19O\xfex\xbb\xf5\xd2\r\u044a\x1f\x01\xdaU.\x00\xb7\xb1\x1d\xb1\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\x19S1>*\xd7F#\x9c\xb2'\x0fH\xaf4\u063b\x9cDe\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x19W\x1a+\x8f\x81\u01bc\xf6j\xb3\xa1\x00\x83)V\x17\x15\x00\x03\x89\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\xe0\x94\x19h}\xaa9\xc3h\x13\x9bn{\xe6\r\xc1u:\x9f\f\xbe\xa3\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x19l\x02!\nE\n\xb0\xb3cpe_qz\xa8{\xd1\xc0\x04\x89\x0e\x10\xac\xe1W\xdb\xc0\x00\x00\u07d4\x19n\x85\xdf~s+J\x8f\x0e\xd06#\xf4\u06dd\xb0\xb8\xfa1\x89\x01%\xb9/\\\xef$\x80\x00\u07d4\x19s+\xf9s\x05]\xbd\x91\xa4S:\u06a2\x14\x9a\x91\u04c3\x80\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x19vr\xfd9\xd6\xf2F\xcef\xa7\x90\xd1:\xa9\"\xd7\x0e\xa1\t\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x19y\x8c\xbd\xa7\x15\ua69b\x9dj\xab\x94,U\x12\x1e\x98\xbf\x91\x89A\rXj \xa4\xc0\x00\x00\u07d4\x19\x8b\xfc\xf1\xb0z\xe3\b\xfa,\x02\x06\x9a\xc9\xda\xfeq5\xfbG\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x19\x8e\xf1\xec2Z\x96\xcc5Lrf\xa08\xbe\x8b\\U\x8fg\x8a\x80\xd1\xe47>\u007f!\xda\x00\x00\xe0\x94\x19\x91\x8a\xa0\x9e}IN\x98\xff\xa5\xdbP5\b\x92\xf7\x15j\u018a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x19\xb3k\f\x87\xeafN\xd8\x03\x18\xdcw\xb6\x88\xdd\xe8}\x95\xa5\x89i\x9fI\x98\x020=\x00\x00\u07d4\x19\u07d4E\xa8\x1c\x1b=\x80J\xea\xebon NB6f?\x89\x02\x06\xd9NjI\x87\x80\x00\u07d4\x19\xe5\u07a37\n,tj\xae4\xa3|S\x1fA\xda&N\x83\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x19\xe7\xf3\xeb{\xf6\u007f5\x99 \x9e\xbe\b\xb6*\xd32\u007f\x8c\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\x19\xe9Nb\x00P\xaa\xd7f\xb9\xe1\xba\xd91#\x83\x12\u053fI\x89\x81\xe3-\xf9r\xab\xf0\x00\x00\u07d4\x19\xec\xf2\xab\xf4\f\x9e\x85{%/\xe1\xdb\xfd=L]\x8f\x81n\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x19\xf5\xca\xf4\xc4\x0ei\b\x81<\aE\xb0\xae\xa9Xm\x9d\xd91\x89#\xfe\xd9\xe1\xfa+`\x00\x00\u07d4\x19\xf6C\xe1\xa8\xfa\x04\xae\x16\x00`(\x13\x833\xa5\x9a\x96\u0787\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x19\xf9\x9f,\vF\u0389\x06\x87]\xc9\xf9\n\xe1\x04\xda\xe3U\x94\x89\xf4WZ]M\x16*\x00\x00\u07d4\x19\xff$O\xcf\xe3\xd4\xfa/O\u065f\x87\xe5[\xb3\x15\xb8\x1e\xb6\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1a\x04\xce\xc4 \xadC\"\x15$mw\xfe\x17\x8d3\x9e\u0435\x95\x89\x11!a\x85\u009fp\x00\x00\xe0\x94\x1a\x04\xd58\x9e\xb0\x06\xf9\u0388\f0\xd1SS\xf8\xd1\x1cK1\x8a\x03\x9d\x84\xb2\x18m\xc9\x10\x00\x00\u07d4\x1a\bA\xb9*\u007fpuV\x9d\xc4b~kv\u02b0Z\u0791\x89Rf<\u02b1\xe1\xc0\x00\x00\xe0\x94\x1a\b]C\xec\x92AN\xa2{\x91O\xe7g\xb6\xd4k\x1e\xefD\x8a\x06A\xe8\xa15c\xd8\xf8\x00\x00\u07d4\x1a\t\xfd\xc2\u01e2\x0e#WK\x97\u019e\x93\u07bag\xd3r \x89lO\xd1\xee$nx\x00\x00\u07d4\x1a\n\x1d\u07f01\xe5\xc8\xcc\x1dF\xcf\x05\x84-P\xfd\xdcq0\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x1a\x1c\x9a&\xe0\xe0$\x18\xa5\xcfh}\xa7Z'\\b,\x94@\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x1a \x1bC'\u03a7\xf3\x99\x04bF\xa3\xc8~n\x03\xa3\u0368\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1a$4\xccwD\"\u050dS\u055c]V,\u0384\a\xc9K\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4\x1a%\xe1\u017c~_P\xec\x16\xf8\x88_!\x0e\xa1\xb98\x80\x0e\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x1a&\x94\xec\a\xcf^Mh\xba@\xf3\xe7\xa1LS\xf3\x03\x8cn\x8966\xcd\x06\xe2\xdb:\x80\x00\u07d4\x1a5 E5\x82\xc7\x18\xa2\x1cB7[\xc5\as%RS\xe1\x89*\xd3s\xcef\x8e\x98\x00\x00\xe0\x94\x1a7n\x1b-/Y\ai\xbb\x85\x8dEu2\rN\x14\x99p\x8a\x01\x06q%v9\x1d\x18\x00\x00\u07d4\x1a:3\x0eO\xcbi\xdb\xef^i\x01x;\xf5\x0f\xd1\xc1SB\x89\u3bb5sr@\xa0\x00\x00\u07d4\x1aN\u01a0\xae\u007fZ\x94'\xd2=\xb9rL\r\f\xff\xb2\xab/\x89\t\xb4\x1f\xbf\x9e\n\xec\x00\x00\u07d4\x1aP^b\xa7N\x87\xe5wG>O:\xfa\x16\xbe\xdd<\xfaR\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x1a^\xe53\xac\xbf\xb3\xa2\xd7m[hRw\xb7\x96\xc5j\x05+\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1adJP\xcb\u00ae\xe8#\xbd+\xf2C\xe8%\xbeMG\xdf\x02\x89\x05k\xe0<\xa3\xe4}\x80\x00\u07d4\x1apD\xe28?\x87\b0[I[\xd1\x17k\x92\xe7\xef\x04:\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1ay\xc7\xf4\x03\x9cg\xa3\x9du\x13\x88L\xdc\x0e,4\"$\x90\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1a\x89\x89\x9c\xbe\xbd\xbbd\xbb&\xa1\x95\xa6<\bI\x1f\u035e\xee\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x1a\x8a\\\xe4\x14\u079c\xd1r\x93~7\xf2\u055c\xffq\xceW\xa0\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x1a\x95\xa8\xa8\b.FR\xe4\x17\r\xf9'\x1c\xb4\xbbC\x05\xf0\xb2\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\x1a\x95\u0277Tk]\x17\x86\u00c5\x8f\xb1#dF\xbc\f\xa4\u0389j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x1a\x98~?\x83\xdeu\xa4/\x1b\xde|\x99|\x19!{J_$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1a\x9ep/8]\xcd\x10^\x8b\x9f\xa4(\xee\xa2\x1cW\xffR\x8a\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x1a\xa1\x02\x1fU\n\xf1X\xc7Gf\x8d\xd1;F1`\xf9Z@\x89O\xb0Y\x1b\x9b08\x00\x00\u07d4\x1a\xa2v\x99\xca\u068d\u00e7oy3\xaaf\xc7\x19\x19\x04\x0e\x88\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x1a\xa4\x02p\xd2\x1e\\\u0786\xb61m\x1a\xc3\xc53IKy\xed\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1a\xb5:\x11\xbc\xc6=\u07ea@\xa0+\x9e\x18d\x96\u037b\x8a\xff\x89l?*\xac\x80\f\x00\x00\x00\u07d4\x1a\xbcN%;\b\n\xebCy\x84\xab\x05\xbc\xa0\x97\x9a\xa4>\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1a\xc0\x89\u00fcM\x82\xf0j \x05\x1a\x9ds-\xc0\xe74\xcba\x89%\xf6\x9dc\xa6\xce\x0e\x00\x00\xe0\x94\x1a\xd4V>\xa5xk\xe1\x15\x995\xab\xb0\xf1\u0547\x9c>sr\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x1a\xd7- \xa7n\u007f\xcckv@X\xf4\x8dA}Io\xa6\u0349lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x1a\xda\xf4\xab\xfa\x86}\xb1\u007f\x99\xafj\xbe\xbfpz<\xf5]\xf6\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x1a\xf6\x03C6\x0e\v-u%R\x107W \xdf!\xdb\\}\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1a\xfc\u0145\x89l\xd0\xed\xe1)\xee-\xe5\xc1\x9e\xa8\x11T\vd\x89\xaf*\xba\f\x8e[\xef\x80\x00\u07d4\x1b\x05\xeajj\u022f|\xb6\xa8\xb9\x11\xa8\xcc\xe8\xfe\x1a*\xcf\u0209lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\v1\xaf\xffKm\xf3e:\x94\xd7\xc8yx\xae5\xf3J\xae\x89\x139\x10E?\xa9\x84\x00\x00\u07d4\x1b\r\ah\x17\xe8\u058e\xe2\xdfN\x1d\xa1\xc1\x14-\x19\x8cD5\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\x1b\x13\ro\xa5\x1d\\H\xec\x8d\x1dR\u070a\"{\xe8s\\\x8a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b#\u02c6cUHq\xfb\xbe\r\x9e`9~\xfbo\xae\xdc>\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1b&9X\x8bU\xc3D\xb0#\xe8\xde_\xd4\b{\x1f\x04\x03a\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\x1b9 \xd0\x01\xc4>r\xb2N|\xa4o\x0f\xd6\xe0\xc2\n_\xf2\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x1b<\xb8\x1eQ\x01\x1bT\x9dx\xbfr\v\r\x92J\xc7c\xa7\u008av\x95\xa9, \xd6\xfe\x00\x00\x00\u07d4\x1bC#,\xcdH\x80\xd6\xf4o\xa7Q\xa9l\xd8$s1XA\x89\x04V9\x18$O@\x00\x00\u07d4\x1bK\xbc\xb1\x81e!\x1b&[(\a\x16\xcb?\x1f!!v\xe8\x89\x19\x9a\xd3}\x03\xd0`\x80\x00\u07d4\x1bM\a\xac\u04c1\x83\xa6\x1b\xb2x=+{\x17\x8d\xd5\x02\xac\x8d\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1bckzIo\x04MsYYn5:\x10F\x16Cok\x89\x13\x88\xea\x95\xc3?\x1d\x00\x00\u07d4\x1bd\x95\x89\x12@\xe6NYD\x93\xc2f!q\xdb^0\xce\x13\x89\tX\x87\u0595\xedX\x00\x00\u07d4\x1bf\x10\xfbh\xba\xd6\xed\x1c\xfa\xa0\xbb\xe3:$\xeb.\x96\xfa\xfb\x89\b=lz\xabc`\x00\x00\u07d4\x1by\x903\xefm\xc7\x12x\"\xf7EB\xbb\"\xdb\xfc\t\xa3\b\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x1b~\xd9t\xb6\xe24\u0381$t\x98B\x9a[\u0520\xa2\xd19\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\x82o\xb3\xc0\x12\xb0\xd1Y\u253a[\x8aI\x9f\xf3\xc0\xe0<\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\x8a\xa0\x16\f\u05df\x00_\x88Q\nqI\x13\xd7\n\u04fe3\x89\n\xef\xfb\x83\a\x9a\xd0\x00\x00\xe0\x94\x1b\x8b\xd6\xd2\xec\xa2\x01\x85\xa7\x8e}\x98\xe8\xe1\x85g\x8d\xacH0\x8a\x03\x89O\x0eo\x9b\x9fp\x00\x00\u07d4\x1b\x9b-\u0096\x0eL\xb9@\x8ft\x05\x82|\x9bY\a\x16\x12\xfd\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x1b\xa9\"\x8d8\x87'\xf3\x89\x15\x0e\xa0;s\xc8-\xe8\xeb.\t\x8a\x01\x89t\xfb\xe1w\xc9(\x00\x00\u07d4\x1b\xa9\xf7\x99~S\x87\xb6\xb2\xaa\x015\xac$R\xfe6\xb4\xc2\r\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\u07d4\x1b\xba\x03\xffkJ\u057f\x18\x18J\xcb!\xb1\x88\xa3\x99\xe9\xebJ\x89a\t=|,m8\x00\x00\u07d4\x1b\xbc\x19\x9eXg\x90\xbe\x87\xaf\xed\xc8I\xc0G&t\\]{\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x1b\xbc`\xbc\xc8\x0e\\\xdc5\xc5Aj\x1f\n@\xa8=\xae\x86{\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\xc4L\x87a#\x1b\xa1\xf1\x1f_\xaa@\xfaf\x9a\x01>\x12\u0389\v\tR\xc4Z\xea\xad\x00\x00\u07d4\x1b\xcf4A\xa8f\xbd\xbe\x960\t\xce3\xc8\x1c\xbb\x02a\xb0,\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\x1b\u048c\xd5\u01ca\xeeQ5|\x95\xc1\xef\x925\xe7\xc1\x8b\xc8T\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\xd8\xeb\xaavt\xbb\x18\u1458\xdb$OW\x03\x13\a_C\x89\b!\xab\rD\x14\x98\x00\x00\u07d4\x1b\xd9\t\xac\rJ\x11\x02\xec\x98\xdc\xf2\u0329j\n\xdc\u05e9Q\x89\x01\x16Q\xac>zu\x80\x00\u07d4\x1b\xe3T,6\x13hte\xf1Zp\xae\xeb\x81f+e\u0328\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1b\xeaM\xf5\x12/\xaf\u07b3`~\xdd\xda\x1e\xa4\xff\u06da\xbf*\x89\x12\xc1\xb6\xee\xd0=(\x00\x00\u07d4\x1b\xecM\x02\u0385\xfcH\xfe\xb6$\x89\x84\x1d\x85\xb1pXj\x9b\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\x1b\xf9t\u0650OE\u0381\xa8E\xe1\x1e\xf4\xcb\xcf'\xafq\x9e\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\x1c\x04VI\xcdS\xdc#T\x1f\x8e\xd4\xd3A\x81(\b\xd5\u075c\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\x1c\x12\x8b\xd6\u0365\xfc\xa2uu\xe4\xb4;2S\xc8\xc4\x17*\xfe\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1c\x13\u04c67\xb9\xa4|\xe7\x9d7\xa8oP\xfb@\x9c\x06\a(\x89Hz\x9a0E9D\x00\x00\u07d4\x1c \x10\xbdf-\xf4\x17\xf2\xa2q\x87\x9a\xfb\x13\xefL\x88\xa3\xae\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x1c%z\u0525Q\x05\xea;X\xed7K\x19\x8d\xa2f\xc8_c\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x1c.6\a\xe1'\xca\xca\x0f\xbd\\YH\xad\xad}\xd80\xb2\x85\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\x1c5l\xfd\xb9_\xeb\xb7\x14c;(\xd5\xc12\u0744\xa9\xb46\x89\x01Z\xf1\u05cbX\xc4\x00\x00\u07d4\x1c5\xaa\xb6\x88\xa0\u034e\xf8.vT\x1b\xa7\xac9R\u007ft;\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x1c>\xf0]\xae\x9d\xcb\u0509\xf3\x02D\bf\x9d\xe2D\xc5*\x02\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x1cJ\xf0\xe8c\xd2el\x865\xbco\xfe\xc8\u0759(\x90\x8c\xb5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1c`\x19\x93x\x92\a\xf9e\xbb\x86\\\xbbL\xd6W\xcc\xe7o\xc0\x89\x05T\x1ap7P?\x00\x00\u07d4\x1cc\xfa\x9e,\xbb\xf21a\xda3\xa1\xda}\xf7\r\x1b\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1c\xb6\xb2\xd7\xcf\xc5Y\xb7\xf4\x1eoV\xab\x95\xc7\xc9X\xcd\x0eL\x89Hz\x9a0E9D\x00\x00\u07d4\x1c\xc1\xd3\xc1O\x0f\xb8d\x0e6rM\xc42)\xd2\xeaz\x1eH\x89\\(=A\x03\x94\x10\x00\x00\u07d4\x1c\xc9\bv\x00A\t\xcdy\xa3\u07a8f\u02c4\n\xc3d\xba\x1b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1c\xd1\xf0\xa3\x14\u02f2\x00\xde\n\f\xb1\xef\x97\xe9 p\x9d\x97\u0089lk\x93[\x8b\xbd@\x00\x00\u0794\x1c\xdaA\x1b\xd5\x16;\xae\xca\x1eU\x85c`\x1c\xe7 \xe2N\xe1\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x1c\xe8\x1d1\xa7\x920\"\xe1%\xbfH\xa3\xe06\x93\xb9\x8d\xc9\u0749lk\x93[\x8b\xbd@\x00\x00\u07d4\x1c\xeb\xf0\x98]\u007fh\n\xaa\x91\\D\xccb\xed\xb4\x9e\xab&\x9e\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x1c\xedg\x15\xf8b\xb1\xff\x86\x05\x82\x01\xfc\xceP\x82\xb3nb\xb2\x8a\x01j^`\xbe\xe2s\xb1\x00\x00\u07d4\x1c\xf0L\xb1C\x80\x05\x9e\xfd?#\x8be\u057e\xb8j\xfa\x14\u0609\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1c\xf1\x05\xab#\x02;ULX>\x86\u05d2\x11y\xee\x83\x16\x9f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x1c\xf2\xebz\x8c\xca\u00ad\xea\xef\x0e\xe8sG\xd55\u04f9@X\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1c\xfc\xf7Q\u007f\f\bE\x97 \x94+dz\u0452\xaa\x9c\x88(\x89+^:\xf1k\x18\x80\x00\x00\xe0\x94\x1d\t\xad$\x12i\x1c\u0141\xc1\xab6\xb6\xf9CL\xd4\xf0\x8bT\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\x1d\x15|Xv\xc5\xca\xd5S\xc9\x12\xca\xf6\xce-Rw\xe0\\s\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x1d&\x15\xf8\xb6\xcaP\x12\xb6c\xbd\u0414\xb0\xc5\x13|w\x8d\u07ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x1d)\u01ea\xb4+ H\u04b2R%\u0518\u06e6z\x03\xfb\xb2\x89\n\u05ce\xbcZ\xc6 \x00\x00\u0794\x1d4\x1f\xa5\xa3\xa1\xbd\x05\x1f}\xb8\a\xb6\xdb/\u01faO\x9bE\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x1d4N\x96%g\xcb'\xe4M\xb9\xf2\xfa\u01f6\x8d\xf1\xc1\xe6\xf7\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\x1d6h0c\xb7\xe9\xeb\x99F-\xab\xd5i\xbd\xdc\xe7\x16\x86\xf2\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1d7aky?\x94\x91\x188\xac\x8e\x19\xee\x94I\u07d2\x1e\u0109QP\xae\x84\xa8\xcd\xf0\x00\x00\xe0\x94\x1d9[0\xad\xda\x1c\xf2\x1f\t\x1aOJ{u3q\x18\x94A\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\x1dEXn\xb8\x03\xca!\x90e\v\xf7H\xa2\xb1t1+\xb5\a\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x1dW.\xdd-\x87\xca'\x1ag\x14\xc1Z;7v\x1d\u0320\x05\x89\x06\xeb\xd5*\x8d\xdd9\x00\x00\u07d4\x1dc0\x97\xa8R%\xa1\xffC!\xb1)\x88\xfd\xd5\\+8D\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x1di\xc8=(\xff\x04t\xce\xeb\xea\xcb:\xd2'\xa1D\xec\u78ca\x01(\xcc\x03\x92\nb\u0480\x00\u07d4\x1d\x96\xbc\u0544W\xbb\xf1\xd3\u00a4o\xfa\xf1m\xbf}\x83hY\x89\tIr\t\xd8F~\x80\x00\u07d4\x1d\x9ej\xaf\x80\x19\xa0_#\x0e]\xef\x05\xaf]\x88\x9b\xd4\xd0\xf2\x89\a?u\u0460\x85\xba\x00\x00\u07d4\x1d\xab\x17.\xff\xa6\xfb\xeeSL\x94\xb1~yN\xda\xc5OU\xf8\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x1d\xb9\xac\x9a\x9e\xae\xec\nR7W\x05\fq\xf4rx\xc7-P\x89Hz\x9a0E9D\x00\x00\u07d4\x1d\xbe\x8e\x1c+\x8a\x00\x9f\x85\xf1\xad<\xe8\r.\x055\x0e\u3709\aW\rn\x9e\xbb\xe4\x00\x00\u07d4\x1d\xc7\xf7\xda\xd8]\xf5?\x12q\x15$\x03\xf4\xe1\xe4\xfd\xb3\xaf\xa0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1d\u03bc\xb7em\xf5\u072a3h\xa0U\xd2/\x9e\xd6\xcd\xd9@\x89\x1b\x18\x1eK\xf24<\x00\x00\xe0\x94\x1d\xd7tA\x84J\xfe\x9c\xc1\x8f\x15\xd8\xc7{\xcc\xfbe^\xe04\x8a\x01\x06\xebEW\x99D\x88\x00\x00\u07d4\x1d\xde\xfe\xfd5\xab\x8fe\x8b$q\xe5G\x90\xbc\x17\xaf\x98\u07a4\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1d\xee\xc0\x1a\xbe\\\r\x95-\xe9\x10l=\xc3\x069\xd8P\x05\u0589lk\x93[\x8b\xbd@\x00\x00\u07d4\x1d\xf6\x91\x16rg\x9b\xb0\xef5\t\x03\x8c\f'\xe3\x94\xfd\xfe0\x89\x1dF\x01b\xf5\x16\xf0\x00\x00\u07d4\x1d\xfa\xee\ar\x12\xf1\xbe\xaf\x0eo/\x18@Sz\xe1T\xad\x86\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x1e\x06\r\xc6\xc5\xf1\u02cc\xc7\xe1E.\x02\xee\x16u\b\xb5eB\x8a\x02\xb1O\x02\xc8d\xc7~\x00\x00\xe0\x94\x1e\x13\xecQ\x14,\ubde2`\x83A,<\xe3QD\xbaV\xa1\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x1e\x1aH(\x11\x9b\xe3\t\xbd\x88#nMH+PM\xc5W\x11\x89\xa00\xdc\xeb\xbd/L\x00\x00\u07d4\x1e\x1a\ud178leb\u02cf\xa1\xebo\x8f;\xc9\u072eny\x89\xf4\xd2\u0744%\x9b$\x00\x00\u07d4\x1e\x1ccQwj\xc3\x10\x919~\xcf\x16\x00-\x97\x9a\x1b-Q\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x1e\x1dz_$h\xb9N\xa8&\x98-\xbf!%yR*\xb7\xdf\n\u02ac\x9e\xee\xd3Y09\xe5\xacuy\x8a+\x14F\xddj\xef\xe4\x1c\x00\x00\u07d4\x1e{^M\x1fW+\xec\xf2\xc0\x0f\xc9\f\xb4v{Jn3\u0509\x06\x1f\xc6\x10u\x93\xe1\x00\x00\u07d4\x1e\x8eh\x9b\x02\x91|\xdc)$]\f\x9ch\xb0\x94\xb4\x1a\x9e\u0589lk\x93[\x8b\xbd@\x00\x00\u07d4\x1e\xa34\xb5u\b\a\xeat\xaa\u016b\x86\x94\xec_(\xaaw\u03c9\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\u07d4\x1e\xa4qU\x04\u01af\x10{\x01\x94\xf4\xf7\xb1\xcbo\xcc\xcdoK\x89 \x041\x97\xe0\xb0'\x00\x00\u07d4\x1e\xa4\x92\xbc\xe1\xad\x10~3\u007fK\u0527\xac\x9a{\xab\xcc\u036b\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x1e\xa6\xbf/\x15\xae\x9c\x1d\xbcd\u06a7\xf8\xeaM\r\x81\xaa\xd3\xeb\x89\u3bb5sr@\xa0\x00\x00\u07d4\x1e\xb4\xbfs\x15j\x82\xa0\xa6\x82 \x80\xc6\xed\xf4\x9cF\x9a\xf8\xb9\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94\x1e\xba\xcbxD\xfd\xc3\"\xf8\x05\x90O\xbf\x19b\x80-\xb1S|\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x1e\xc4\xecKw\xbf\x19\u0411\xa8h\xe6\xf4\x91T\x18\x05A\xf9\x0e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1e\xd0n\xe5\x16b\xa8lcE\x88\xfbb\xdcC\xc8\xf2~|\x17\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1e\u063b?\x06w\x8b\x03\x9e\x99a\xd8\x1c\xb7\x1as\xe6x|\x8e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x1e\xda\bNye\x00\xba\x14\xc5\x12\x1c\r\x90\x84of\xe4\xbeb\x89\x1c\xfd\xd7F\x82\x16\xe8\x00\x00\u07d4\x1e\xeel\xbe\xe4\xfe\x96\xadaZ\x9c\xf5\x85zdy@\u07ccx\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4\x1e\xf2\u073f\xe0\xa5\x00A\x1d\x95n\xb8\u0213\x9c=l\xfef\x9d\x89*\x11)\u0413g \x00\x00\xe0\x94\x1e\xf5\xc9\xc76P\u03fb\xde\\\x88U1\xd4'\xc7\xc3\xfeUD\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x1f\x04\x12\xbf\xed\u0356N\x83}\t,q\xa5\xfc\xba\xf3\x01&\xe2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1f\x17O@\xa0Dr4\xe6fS\x91Mu\xbc\x00>V\x90\u0709\b\xacr0H\x9e\x80\x00\x00\u07d4\x1f!\x86\xde\xd2>\f\xf9R\x16\x94\xe4\xe1dY>i\n\x96\x85\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x1f*\xfc\n\xed\x11\xbf\xc7\x1ew\xa9\ae{6\xeav\xe3\xfb\x99\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u0794\x1f9Y\xfc)\x11\x10\xe8\x822\xc3kvg\xfcx\xa3ya?\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x1f=\xa6\x8f\xe8~\xafC\xa8)\xabm~\u0166\xe0\t\xb2\x04\xfb\x89\x1e\x16\x01u\x8c,~\x00\x00\u07d4\x1fI\xb8m\r9EY\x06\x98\xa6\xaa\xf1g<7u\\\xa8\r\x89%\xf2s\x93=\xb5p\x00\x00\u07d4\x1f_;4\xbd\x13K'\x81\xaf\xe5\xa0BJ\u0144l\xde\xfd\x11\x89\x05]\xe6\xa7y\xbb\xac\x00\x00\u07d4\x1fo\x0004\x97R\x06\x1c\x96\a+\xc3\xd6\xeb5I \x8dk\x89\x01K\x8d\xe1\xeb\x88\u06c0\x00\u07d4\x1f}\x8e\x86\xd6\xee\xb0%E\xaa\xd9\x0e\x912{\xd3i\xd7\xd2\xf3\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1f\x81\x16\xbd\n\xf5W\x0e\xaf\fV\u011cz\xb5\xe3zX\x04X\x89lk\x93[\x8b\xbd@\x00\x00\u0794\x1f\x88\xf8\xa13\x8f\xc7\xc1\tv\xab\xcd?\xb8\u04c5T\xb5\uc708\xb9\xf6]\x00\xf6<\x00\x00\u07d4\x1f\x9c2hE\x8d\xa3\x01\xa2\xbeZ\xb0\x82W\xf7{\xb5\xa9\x8a\xa4\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x1f\xa21\x9f\xed\x8c-F*\xdf.\x17\xfe\xecjo0Qn\x95\x89\x06\xca\xe3\x06!\xd4r\x00\x00\u07d4\x1f\xb4c\xa08\x99\x83\xdf}Y?{\xddmxI\u007f\xed\x88y\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x1f\xb7\xbd1\r\x95\xf2\xa6\u067a\xaf\x8a\x8aC\n\x9a\x04E:\x8b\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x1f\xcc|\xe6\xa8HX\x95\xa3\x19\x9e\x16H\x1fr\xe1\xf7b\xde\xfe\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x1f\xcf\xd1\xd5\u007f\x87\"\x90V\f\xb6-`\x0e\x1d\xef\xbe\xfc\xcc\x1c\x89P\xc5\xe7a\xa4D\b\x00\x00\u0794\x1f\u0496\xbe\x03\xads|\x92\xf9\u0186\x9e\x8d\x80\xa7\x1cW\x14\xaa\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\x1f\xdd\xd8_\u024b\xe9\xc4\x04Ya\xf4\x0f\x93\x80^\xccEI\xe5\x89\b\xe3\xf5\v\x17<\x10\x00\x00\u07d4 \x01\xbe\xf7{f\xf5\x1e\x15\x99\xb0/\xb1\x10\x19J\x00\x99\xb7\x8d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4 \x02d\xa0\x9f\x8ch\xe3\xe6b\x97\x95(\x0fV%O\x86@\u0409\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4 \x03qy\a\xa7%`\xf40\u007f\x1b\xee\xccT6\xf4=!\xe7\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4 \r\xfc\vq\xe3Y\xb2\xb4eD\n6\xa6\xcd\xc3Rw0\a\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4 \x13L\xbf\xf8\x8b\xfa\xdcFkR\xec\ua9d8W\x89\x1d\x83\x1e\x8965\u026d\xc5\u07a0\x00\x00\u07d4 \x14&\x1f\x01\b\x9fSyV0\xba\x9d\xd2O\x9a4\xc2\xd9B\x89Hz\x9a0E9D\x00\x00\u07d4 \x16\x89]\xf3,\x8e\xd5G\x82iF\x84#\xae\xa7\xb7\xfb\xceP\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4 \x18\x1cKA\xf6\xf9r\xb6iX!_\x19\xf5p\xc1]\xdf\xf1\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4 \x18d\xa8\xf7\x84\xc2'{\v|\x9e\xe74\xf7\xb3w\xea\xb6H\x89\xf2(\x14\x00\xd1\xd5\xec\x00\x00\u07d4 \xb8\x1a\xe59&\xac\xe9\xf7\xd7AZ\x05\f\x03\x1dX_ \x89\x12\u007f\x19\xe8>\xb3H\x00\x00\xe0\x94 \x1d\x9e\xc1\xbc\v\x89-C\xf3\xeb\xfa\xfb,\x00\x00\u07d4 \xa1RV\xd5\f\xe0X\xbf\x0e\xacC\xaaS:\xa1n\u0273\x80\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4 \xa2\x9cPy\xe2k?\x181\x8b\xb2\xe5\x0e\x8e\x8b4n[\xe8\x89\x1b\x1a\xb3\x19\xf5\xecu\x00\x00\u07d4 \xa8\x16\x80\xe4e\xf8\x87\x90\xf0\aO`\xb4\xf3_]\x1ej\xa5\x89Ea\x80'\x8f\fw\x80\x00\u07d4 \xb9\xa9\u6f48\x80\u0659J\xe0\r\u0439(*\v\xea\xb8\x16\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4 \u0084\xba\x10\xa2\b0\xfc=i\x9e\xc9}-\xfa'\xe1\xb9^\x89lk\x93[\x8b\xbd@\x00\x00\u07d4 \xd1A\u007f\x99\xc5i\u3fb0\x95\x85e0\xfe\x12\xd0\xfc\uaa89@\x15\xf9K\x11\x83i\x80\x00\u07d4 \u074f\u02f4n\xa4o\u3066\x8b\x8c\xa0\xea[\xe2\x1f\u9949lk\x93[\x8b\xbd@\x00\x00\xe0\x94 \xff>\u078c\xad\xb5\xc3{H\xcb\x14X\x0f\xb6^#\t\n{\x8a\b\xe4\xd3\x16\x82v\x86@\x00\x00\xe0\x94!\x008\x1d`\xa5\xb5J\xdc\t\u0456\x83\xa8\xf6\u057bK\xfb\u02ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94!\x18\xc1\x16\xab\f\xdfo\xd1\x1dT\xa40\x93\a\xb4w\xc3\xfc\x0f\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94!\x1b)\xce\xfcy\xae\x97gD\xfd\xeb\u03bd<\xbb2\xc5\x13\x03\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4! l\xe2.\xa4\x80\xe8Y@\xd3\x13\x14\xe0\xd6ONM:\x04\x8965\u026d\xc5\u07a0\x00\x00\u07d4!2\xc0Qj.\x17\x17J\xc5G\xc4;{\x00 \xd1\xebLY\x895e\x9e\xf9?\x0f\xc4\x00\x00\xe0\x94!@\x8bMz,\x0en\xcaAC\xf2\xca\u037b\u033a\x12\x1b\u060a\x04<3\xc1\x93ud\x80\x00\x00\u07d4!Kt9U\xa5\x12\xden\r\x88j\x8c\xbd\x02\x82\xbe\xe6\u04a2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4!L\x89\u017d\x8e}\"\xbcWK\xb3^H\x95\x02\x11\xc6\xf7v\x89\x01\x06T\xf2X\xfd5\x80\x00\xe0\x94!Ti\x14\xdf\u04ef*\xddA\xb0\xff>\x83\xff\xdat\x14\xe1\xe0\x8a\x01C\x95\xe78ZP.\x00\x00\u07d4!X.\x99\xe5\x02\xcb\xf3\xd3\xc2;\xdf\xfbv\xe9\x01\xacmV\xb2\x89\x05k\xc7^-c\x10\x00\x00\u07d4!Y$\b\x13\xa70\x95\xa7\xeb\xf7\u00f3t>\x80(\xae_\t\x89lk\x93[\x8b\xbd@\x00\x00\u07d4!`\xb4\xc0,\xac\n\x81\u0791\b\xdeCE\x90\xa8\xbf\xe6\x875\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94!nA\x86N\xf9\x8f\x06\r\xa0\x8e\xca\xe1\x9a\xd1\x16j\x17\xd06\x8a\x016\x9f\xb9a(\xacH\x00\x00\u07d4!\x84o/\xdfZA\xed\x8d\xf3n^\xd8TM\xf7Y\x88\xec\xe3\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94!\xa6\xdbe'F{\xc6\xda\xd5K\xc1n\x9f\xe2\x95;g\x94\xed\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4!\xa6\xfe\xb6\xab\x11\xc7f\xfd\xd9w\xf8\xdfA!\x15_G\xa1\xc0\x89\x03\x19\xcf8\xf1\x00X\x00\x00\u07d4!\xb1\x82\xf2\xda+8D\x93\xcf_5\xf8=\x9d\x1e\xe1O*!\x89lk\x93[\x8b\xbd@\x00\x00\u07d4!\xbf\xe1\xb4\\\xac\xdebt\xfd\x86\b\u0661x\xbf>\xebn\u0709l\xee\x06\u077e\x15\xec\x00\x00\u07d4!\xc0s\x80HOl\xbc\x87$\xad2\xbc\x86L;Z\xd5\x00\xb7\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94!\u00e8\xbb\xa2g\xc8\u0322{\x1a\x9a\xfa\xba\xd8o`z\xf7\b\x8a\x01\xe4\xa3lI\u06580\x00\x00\u07d4!\xcem[\x90\x18\xce\xc0J\u0596yD\xbe\xa3\x9e\x800\xb6\xb8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4!\xd0'\x05\xf3\xf6I\x05\xd8\x0e\xd9\x14y\x13\xea\x8cs\a\u0595\x89I\xed\xb1\xc0\x98\x876\x00\x00\u07d4!\xd1?\f@$\xe9g\xd9G\a\x91\xb5\x0f\"\xde:\xfe\xcf\x1b\x89\xf1Z\xd3^.1\xe5\x00\x00\xe0\x94!\xdb\u06c1z\r\x84\x04\u01bd\xd6\x15\x047N\x9cC\xc9!\x0e\x8a\x02\x1e\x18\xb9\xe9\xabE\xe4\x80\x00\xe0\x94!\xdf\x1e\xc2KNK\xfey\xb0\xc0\x95\u03ba\xe1\x98\xf2\x91\xfb\u044a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94!\xdf-\u036ft\xb2\xbf\x804\x04\xddM\xe6\xa3^\xab\xec\x1b\xbd\x8a\x01w\"J\xa8D\xc7 \x00\x00\u07d4!\xe2\x19\u021c\xa8\xac\x14\xaeL\xbaa0\xee\xb7}\x9em9b\x89*\u035f\xaa\xa08\xee\x00\x00\u07d4!\xe5\u04ba\xe9\x95\xcc\xfd\b\xa5\xc1k\xb5$\xe1\xf60D\x8f\x82\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4!\xe5\xd7s 0L \x1c\x1eS\xb2a\xa1#\u0421\x06>\x81\x89\x04\xb6\xfa\x9d3\xddF\x00\x00\xe0\x94!\xea\xe6\xfe\xff\xa9\xfb\xf4\u0347OG9\xac\xe50\u033eY7\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4!\xec\xb2\u07e6Wy\xc7Y-\x04\x1c\xd2\x10Z\x81\xf4\xfdNF\x8965\u026d\xc5\u07a0\x00\x00\u07d4!\uff20\x9b5\x80\xb9\x8es\xf5\xb2\xf7\xf4\xdc\v\xf0,R\x9c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4!\xfd\v\xad\xe5\xf4\xeftt\xd0X\xb7\xf3\xd8T\xcb\x13\x00RN\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94!\xfdG\xc5%`\x12\x19\x8f\xa5\xab\xf11\xc0mj\xa1\x96_u\x8a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4!\xfdl]\x97\xf9\xc6\x00\xb7h!\xdd\xd4\xe7v5\x0f\xce+\xe0\x89lj\u04c2\xd4\xfba\x00\x00\u07d4\"\r\u018d\xf0\x19\xb6\xb0\u033f\xfbxKZZ\xb4\xb1]@`\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\"\x0e+\x92\xc0\xf6\xc9\x02\xb5\x13\xd9\xf1\xe6\xfa\xb6\xa8\xb0\xde\xf3\u05c9+^:\xf1k\x18\x80\x00\x00\u07d4\"V\x1cY1\x14560\x9c\x17\xe82X{b\\9\v\x9a\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\"W\xfc\xa1jn\\*d|<)\xf3l\xe2)\xab\x93\xb1~\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\"]5\xfa\xed\xb3\x91\u01fc-\xb7\xfa\x90q\x16\x04\x05\x99m\x00\x89\t\x18T\xfc\x18bc\x00\x00\u07d4\"_\x9e\xb3\xfbo\xf3\xe9\xe3\xc8D~\x14\xa6n\x8dO7y\xf6\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\"r\x18n\xf2}\xcb\xe2\xf5\xfc70P\xfd\xae\u007f*\xce#\x16\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d4\"s\xba\u05fcNHv\"\xd1u\xefzf\x98\x8bj\x93\xc4\xee\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\"v&K\xec\x85&\xc0\xc0\xf2pgz\xba\xf4\xf0\xe4A\xe1g\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\"\x82B\xf83n\xec\xd8$.\x1f\x00\x0fA\x93~q\xdf\xfb\xbf\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\"\x84*\xb80\xdaP\x99\x13\xf8\x1d\xd1\xf0O\x10\xaf\x9e\xdd\x1cU\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\"\x94O\xbc\xa9\xb5yc\bN\xb8M\xf7\xc8_\xb9\xbc\u07f8V\x89\xfc\x11\x8f\uf43a8\x80\x00\u07d4\"\x9c\xc4q\x1bbu^\xa2\x96DZ\u00f7\u007f\xc63\x82\x1c\xf2\x89\x02#\xe8\xb0R\x192\x80\x00\u0794\"\x9eC\r\xe2\xb7OD&Q\xdd\u0377\x01v\xbc\x05L\xadT\x88\xbb\xf9\x81\xbcJ\xaa\x80\x00\u07d4\"\x9fO\x1a*OT\atP[G\a\xa8\x1d\xe4D\x10%[\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\"\x9f\xf8\v\xf5p\x80\t\xa9\xf79\xe0\xf8\xb5`\x91@\x16\u0566\x89\x12\x11\xec\xb5m\x13H\x80\x00\u07d4\"\xa2X\x12\xabV\xdc\xc4#\x17^\xd1\u062d\xac\xce3\xcd\x18\x10\x89dI\xe8NG\xa8\xa8\x00\x00\xe0\x94\"\xb9j\xb2\xca\xd5]\xb1\x00\xb50\x01\xf9\xe4\xdb7\x81\x04\xc8\a\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\"\xbd\xff\xc2@\xa8\x8f\xf7C\x1a\xf3\xbf\xf5\x0e\x14\xda7\xd5\x18>\x8965\u026d\xc5\u07a0\x00\x00\u07d4\"\xce4\x91Y\xee\xb1D\xef\x06\xff&6X\x8a\xefy\xf6(2\x89\n1\x06+\xee\xedp\x00\x00\u07d4\"\xdbU\x9f,<\x14u\xa2\xe6\xff\xe8:YyY\x91\x96\xa7\xfa\x8965\u026d\xc5\u07a0\x00\x00\u07d4\"\xe1QX\xb5\xee>\x86\xeb\x032\xe3\u6a6cl\u0675^\u0349\b\xacr0H\x9e\x80\x00\x00\u07d4\"\xe2H\x8e-\xa2jI\xae\x84\xc0\x1b\xd5K!\xf2\x94x\x91\u0189]\u0212\xaa\x111\xc8\x00\x00\u07d4\"\xe5\x12\x14\x9a\x18\xd3i\xb7\x86\xc9\xed\xab\xaf\x1d\x89N\xe0.g\x14a\\\x00\x00\u07d4\"\xeb}\xb0\xbaV\xb0\xf8\xb8\x16\u0332\x06\xe6\x15\xd9)\x18[\r\x89\x04])s~\"\xf2\x00\x00\u07d4\"\xee\xd3'\xf8\xeb\x1d\x138\xa3\xcb{\x0f\x8aK\xaaY\a\u0355\x89\x01E]_Hw\b\x80\x00\xe0\x94\"\xf0\x04\u07cd\xe9\xe6\xeb\xf5#\u032c\xe4W\xac\xcb&\xf9r\x81\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u0794\"\xf2\xdc\xffZ\u05cc>\xb6\x85\v\\\xb9Q\x12{e\x95\"\u623e -j\x0e\xda\x00\x00\u07d4\"\xf3\xc7y\xddy\x02>\xa9*x\xb6\\\x1a\x17\x80\xf6-\\J\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\"\xfe\x88M\x907)\x1bMR\xe6(Z\xe6\x8d\xea\v\xe9\xff\xb5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#\x06\u07d3\x1a\x94\rX\xc0\x16e\xfaM\b\x00\x80,\x02\xed\xfe\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94#\t\xd3@\x91D[22Y\v\xd7\x0fO\x10\x02[,\x95\t\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4#\x12\x00F\xf6\x83!\x02\xa7R\xa7fVi\x1c\x86>\x17\u5709\x11\xe0\xe4\xf8\xa5\v\xd4\x00\x00\u07d4#\x1a\x15\xac\xc1\x99\u021f\xa9\xcb\"D\x1c\xc7\x030\xbd\xcc\xe6\x17\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4#\x1d\x94\x15]\xbc\xfe*\x93\xa3\x19\xb6\x17\x1fc\xb2\v\u04b6\xfa\x89\xcf\x14{\xb9\x06\xe2\xf8\x00\x00\u07d4#(2\xcdYw\xe0\nL0\xd0\x16?.$\xf0\x88\xa6\xcb\t\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4#,m\x03\xb5\xb6\xe6q\x1e\xff\xf1\x90\xe4\x9c(\xee\xf3l\x82\xb0\x89Hz\x9a0E9D\x00\x00\xe0\x94#,\xb1\xcdI\x99<\x14J?\x88\xb3a\x1e#5i\xa8k\u058a\x03L`lB\u042c`\x00\x00\u07d4#,\xe7\x82Pb%\xfd\x98`\xa2\xed\xc1Jz0Gsm\xa2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4#/R]U\x85\x9b}N`\x8d H\u007f\xaa\xdb\x00)15\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94#4\u0150\u01e4\x87i\x100E\u0176SL\x8a4i\xf4J\x8a\x03\xb1\x99\a=\xf7-\xc0\x00\x00\u07d4#7n\u02bftl\xe53!\xcfB\xc8fI\xb9+g\xb2\xff\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#7\x8fB\x92m\x01\x84\xb7\x93\xb0\xc8'\xa6\xdd>=3O\u0349\x03\t'\xf7L\x9d\xe0\x00\x00\u07d4#8B\xb1\xd0i/\xd1\x11@\xcfZ\u0364\xbf\x960\xba\xe5\xf8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#9\xe9I(p\xaf\xea%7\xf3\x89\xac/\x83\x83\x02\xa3<\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#;\xdd\xdd]\xa9HR\xf4\xad\xe8\xd2\x12\x88V\x82\xd9\ak\u0189\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4#OF\xba\xb7?\xe4]1\xbf\x87\xf0\xa1\xe0Fa\x99\xf2\ubb09\x1aJ\xba\"\\ t\x00\x00\u07d4#U\x1fV\x97_\xe9+1\xfaF\x9cI\xeaf\xeefb\xf4\x1e\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4#V\x95B\xc9}V`\x18\xc9\a\xac\xfc\xf3\x91\xd1@g\xe8~\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94#_\xa6l\x02^\xf5T\x00p\xeb\xcf\r7-\x81w\xc4g\xab\x8a\a\x12\x9e\x1c\xdf7>\xe0\x00\x00\xe0\x94#r\xc4\xc1\u0253\x9fz\xafl\xfa\xc0@\x90\xf0\x04t\x84\n\t\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4#s\f5z\x91\x02nD\xb1\xd0\xe2\xfc*Q\xd0q\xd8\xd7{\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4#v\xad\xa9\x033\xb1\u0441\bL\x97\xe6E\xe8\x10\xaa[v\xf1\x89(\xa8WBTf\xf8\x00\x00\u07d4#x\xfdC\x82Q\x1e\x96\x8e\u0452\x10g7\xd3$\xf4T\xb55\x8965\u026d\xc5\u07a0\x00\x00\u07d4#\x82\xa9\u050e\xc8>\xa3e(\x90\xfd\x0e\u7710{[-\xc1\x89\a?u\u0460\x85\xba\x00\x00\u07d4#\x83\xc2\"\xe6~\x96\x91\x90\xd3!\x9e\xf1M\xa3xP\xe2lU\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#\x8akv5%/RDHl\n\xf0\xa7: s\x85\xe09\x89JD\x91\xbdm\xcd(\x00\x00\u07d4#\x9as>k\x85Z\u0152\xd6c\x15a\x86\xa8\xa1t\xd2D\x9e\x89X\xbe7X\xb2A\xf6\x00\x00\xe0\x94#\xab\t\xe7?\x87\xaa\x0f;\xe0\x13\x9d\xf0\xc8\xebk\xe5cO\x95\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94#\xab\xd9\xe9>yW\xe5\xb66\xbeey\x05\x1c\x15\xe5\xce\v\x0e\x8a\x03\xa3\xc8\xf7\xcb\xf4,8\x00\x00\u07d4#\xb1\u0111\u007f\xbd\x93\xee=H8\x93\x06\x95s\x84\xa5Il\xbf\x89\xd8\xd8X?\xa2\xd5/\x00\x00\xe0\x94#\xba8d\xdaX=\xabV\xf4 \x87<7g\x96\x90\xe0/\x00\x8a\x02\x13BR\r_\xec \x00\x00\u07d4#\xc5Z\xebW9\x87o\n\xc8\xd7\xeb\xea\x13\xber\x96\x85\xf0\x00\x89Hz\x9a0E9D\x00\x00\u07d4#\u025b\xa0\x87D\x8e\x19\xc9p\x1d\xf6n\f\xabR6\x831\xfa\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#\xcc\xc3\u01ac\xd8\\.F\fO\xfd\xd8+\xc7]\xc8I\xea\x14\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4#\xcd%\x98\xa2\x0e\x14\x9e\xad*\u0593yWn\xce\xdb`\u3389lk\x93[\x8b\xbd@\x00\x00\u07d4#\u07cfH\xee\x00\x92V\xeay~\x1f\xa3i\xbe\xeb\xcfk\xc6c\x89|\xd3\xfa\xc2m\x19\x81\x80\x00\u07d4#\xe2\u01a8\xbe\x8e\n\u03e5\xc4\xdf^6\x05\x8b\xb7\u02ecZ\x81\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#\xeaf\x9e5d\x81\x9a\x83\xb0\xc2l\x00\xa1m\x9e\x82olF\x89M\x8dl\xa9h\xca\x13\x00\x00\u07d4#\xebo\xd8Vq\xa9\x06:\xb7g\x8e\xbe&Z \xf6\x1a\x02\xb3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4#\xf9\xec\xf3\xe5\xdd\u0723\x88\x15\xd3\xe5\x9e\xd3K[\x90\xb4\xa3S\x89\v\x17\x81\xa3\xf0\xbb \x00\x00\u07d4#\xfa~\xb5\x1aH\"\x95\x98\xf9~v+\xe0\x86\x96R\xdf\xfcf\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94$\x03\x05rs\x13\xd0\x1esT,w_\xf5\x9d\x11\xcd5\xf8\x19\x8a\x01A\x88Vf\x80\u007f\\\x80\x00\u07d4$\x04k\x91\u069ba\xb6)\u02cb\x8e\xc0\xc3Q\xa0~\a\x03\xe4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4$\x0eU\x9e'J\xae\xf0\xc2X\x99\x8c\x97\x9fg\x1d\x11s\xb8\x8b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94$\x13aU\x9f\xee\xf8\x0e\xf170!S\xbd\x9e\xd2\xf2]\xb3\xef\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94$;;\xcaj)\x93Y\xe8\x86\xce3\xa3\x03A\xfa\xfeMW=\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4$<\x84\xd1$ W\f\xc4\xef;\xab\xa1\xc9Y\u0083$\x95 \x89\u007f\x1fi\x93\xa8S\x04\x00\x00\xe0\x94$CJ>2\xe5N\xcf'/\xe3G\v_oQ/gU \x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4$HYo\x91\xc0\x9b\xaa0\xbc\x96\x10j-7\xb5p^](\x89lk\x93[\x8b\xbd@\x00\x00\u0794$Xn\xc5E\x175\xee\xaa\xebG\r\xc8sj\xaeu/\x82\xe5\x88\xf4?\xc2\xc0N\xe0\x00\x00\u07d4$X\xd6U_\xf9\x8a\x12\x9c\xce@7\x95=\x00 n\xffB\x87\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4$b\x91\x16[Y3-\xf5\xf1\x8c\xe5\u0248V\xfa\xe9X\x97\u0589\\(=A\x03\x94\x10\x00\x00\u07d4$g\u01a5\u0196\xed\xe9\xa1\xe5B\xbf\x1a\xd0k\xccK\x06\xac\xa0\x89\x01\x00\xbd3\xfb\x98\xba\x00\x00\u07d4$v\xb2\xbbu\x1c\xe7H\xe1\xa4\xc4\xff{#\v\xe0\xc1]\"E\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4$z\n\x11\xc5\u007f\x03\x83\xb9I\xdeT\vf\xde\xe6\x86\x04\xb0\xa1\x899\xfb\xae\x8d\x04-\xd0\x00\x00\u07d4$\x87\xc3\u013e\x86\xa2r=\x91|\x06\xb4XU\x01p\xc3\xed\xba\x8965\u026d\xc5\u07a0\x00\x00\u07d4$\x89\xac\x12i4\xd4\u05a9M\xf0\x87C\xda{v\x91\xe9y\x8e\x8965\u026d\xc5\u07a0\x00\x00\u07d4$\x9d\xb2\x9d\xbc\x19\xd1#]\xa7)\x8a\x04\b\x1c1WB\u9b09a\xac\xff\x81\xa7\x8a\xd4\x00\x00\u07d4$\xa4\xeb6\xa7\xe4\x98\xc3o\x99\x97\\\x1a\x8dr\x9f\u05b3\x05\u05c9\r\xfcx!\x0e\xb2\xc8\x00\x00\u07d4$\xa7P\xea\xe5\x87G\x11\x11m\xd7\xd4{q\x86\u0399\r1\x03\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4$\xaa\x11Q\xbbv_\xa3\xa8\x9c\xa5\x0e\xb6\xe1\xb1\xc7\x06A\u007f\u0509\xa8\r$g~\xfe\xf0\x00\x00\u0794$\xac\xa0\x8d[\xe8^\xbb\x9f12\xdf\xc1\xb6 \x82N\xdf\xed\xf9\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4$\xb2\xbe\x11\x8b\x16\u0632\x17Gi\xd1{L\xf8O\a\u0294m\x89lk\x93[\x8b\xbd@\x00\x00\u07d4$\xb8\xb4F\u07bd\x19G\x95]\u0404\xf2\xc5D\x933F\u04ed\x89\xeaim\x90@9\xbd\x80\x00\u07d4$\xb9^\xbe\xf7\x95\x00\xba\xa0\xed\xa7.w\xf8wA]\xf7\\3\x891T\xc9r\x9d\x05x\x00\x00\u07d4$\xb9\xe6dOk\xa4\xcd\xe1&'\r\x81\xf6\xab`\xf2\x86\xdf\xf4\x89\a?u\u0460\x85\xba\x00\x00\u07d4$\xbdY\x04\x05\x90\x91\xd2\xf9\xe1-j&\xa0\x10\xca\"\xab\x14\xe8\x89e\xea=\xb7UF`\x00\x00\u07d4$\xc0\u020bT\xa3TG\t\x82\x8a\xb4\xab\x06\x84\x05Y\xf6\xc5\u2250\xf54`\x8ar\x88\x00\x00\u07d4$\xc1\x17\xd1\u04b3\xa9z\xb1\x1aFy\u025awJ\x9e\xad\xe8\u044965\u026d\xc5\u07a0\x00\x00\u07d4$\xcf\xf0\xe93j\x9f\x80\xf9\xb1\u02d6\x8c\xafk\x1d\x1cI2\xa4\x89\n\xdaUGK\x814\x00\x00\u07d4$\u06aa\xdd\xf7\xb0k\xbc\ua6c0Y\x00\x85\xa8\x85gh+N\x89\x11K \x15\u04bb\xd0\x00\x00\u07d4$\xdc\xc2K\xd9\xc7!\f\xea\u03f3\r\xa9\x8a\xe0JM{\x8a\xb9\x8965\u026d\xc5\u07a0\x00\x00\u07d4$\xf7E\r\xdb\xf1\x8b\x02\x0f\xeb\x1a 2\xd9\xd5Kc>\xdf7\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4$\xfcs\xd2\a\x93\t\x8e\t\u076bW\x98Pb$\xfa\x1e\x18P\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4$\xfd\x9al\x87L/\xab?\xf3n\x9a\xfb\xf8\xce\r2\xc7\u0792\x89Hz\x9a0E9D\x00\x00\u07d4%\n@\xce\xf3 #\x97\xf2@F\x95H\xbe\xb5bj\xf4\xf2<\x89\x05\x03\xb2\x03\xe9\xfb\xa2\x00\x00\u07d4%\niC\av\xf64w\x03\xf9R\x97\x83\x95Za\x97\xb6\x82\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4%\x0e\xb7\xc6o\x86\x9d\xdfI\u0685\xf39>\x98\f\x02\x9a\xa44\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4%\x10j\xb6u]\xf8mkc\xa1\x87p;\f\xfe\xa0\u5520\x89\x01|@Z\xd4\x1d\xb4\x00\x00\xe0\x94%\x18_2Z\xcf-dP\x06\x98\xf6\\v\x9d\xdfh0\x16\x02\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4%\x1c\x12r,hy\"y\x92\xa3\x04\xeb5v\xcd\x18CN\xa5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4%\x1eh8\xf7\xce\u0173\x83\xc1\xd9\x01F4\x12t\xda\xf8\xe5\x02\x89\a\xff\x1c\xcbua\xdf\x00\x00\u07d4%%\x9d\x97Z!\xd8:\xe3\x0e3\xf8\x00\xf5?7\u07e0\x198\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4%({\x81_\\\x828\ns\xb0\xb1?\xba\xf9\x82\xbe$\xc4\u04c9\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94%+eU\xaf\u0700\xf2\xd9m\x97-\x17\u06c4\xeaZ\xd5!\xac\x8a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4%8S)6\x81<\x91\xe6S(O\x01|\x80\u00f8\xf8\xa3o\x89l\x87T\xc8\xf3\f\b\x00\x00\xe0\x94%>2\xb7N\xa4I\n\xb9&\x06\xfd\xa0\xaa%{\xf2=\u02cb\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94%?\x1et*,\uc1b0\u05f3\x06\xe5\xea\xcbl\xcb/\x85T\x8a\x04>^\xde\x1f\x87\x8c \x00\x00\u07d4%A1J\v@\x8e\x95\xa6\x94DIwq*Pq5\x91\xab\x89X\x9e\x1a]\xf4\u05f5\x00\x00\u07d4%L\x1e\xccc\f(w\u0780\x95\xf0\xa8\u06e1\xe8\xbf\x1fU\f\x89\\(=A\x03\x94\x10\x00\x00\u07d4%Z\xbc\x8d\b\xa0\x96\xa8\x8f=j\xb5_\xbcsR\xbd\u0739\u0389\x04t6\x821>\u0780\x00\u07d4%[\xdddt\u0302b\xf2j\"\u00cfE\x94\x0e\x1c\ue99b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4%`\xb0\x9b\x89\xa4\xaehI\xedZ<\x99XBf1qDf\x89\\(=A\x03\x94\x10\x00\x00\u07d4%a\xa18\xdc\xf8;\xd8\x13\xe0\xe7\xf1\bd+\xe3\xde=o\x05\x8964\xf4\x84\x17@\x1a\x00\x00\u0794%a\xec\x0f7\x92\x18\xfe^\xd4\xe0(\xa3\xf7D\xaaAuLr\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u0794%b\x92\xa1\x91\xbd\xda4\xc4\xdakk\u0591G\xbfu\u2a6b\x88\xc2\xff.\r\xfb\x03\x80\x00\u07d4%i~\xf2\f\u032ap\xd3-7o\x82r\xd9\xc1\a\f=x\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4%o\xa1P\u0307\xb5\x05j\a\xd0\x04\xef\xc8E$s\x9eb\xb5\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4%r\x1c\x87\xb0\xdc!7|r\x00\xe5$\xb1J\"\xf0\xafi\xfb\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4%\x899\xbb\xf0\f\x9d\xe9\xafS8\xf5\xd7\x14\xab\xf6\xd0\xc1\xc6q\x89T\x06\x923\xbf\u007fx\x00\x00\xe0\x94%\x90\x12hp\xe0\xbd\xe8\xa6c\xab\x04\nr\xa5W=\x8dA\u008a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4%\x9e\xc4\xd2e\xf3\xabSk|p\xfa\x97\xac\xa1Bi,\x13\xfc\x89\x01\x1b\x1b[\xea\x89\xf8\x00\x00\xe0\x94%\xa5\x00\xee\xeczf*\x84\x15R\xb5\x16\x8bp{\r\xe2\x1e\x9e\x8a\x02\x1f/o\x0f\xc3\xc6\x10\x00\x00\xe0\x94%\xa5\xa4M8\xa2\xf4Lj\x9d\xb9\u037ck\x1e.\x97\xab\xb5\t\x8a\x03\x99\x92d\x8a#\u0220\x00\x00\u07d4%\xa7L*\xc7]\u023a\xa8\xb3\x1a\x9c|\xb4\xb7\x82\x9b$V\u0689lk\x93[\x8b\xbd@\x00\x00\xe0\x94%\xad\xb8\xf9o9I,\x9b\xb4|^\u0708bNF\aV\x97\x8a\x05\xa9\x94\v\xc5hyP\x00\x00\u07d4%\xae\xe6\x8d\t\xaf\xb7\x1d\x88\x17\xf3\xf1\x84\xecV/x\x97\xb74\x89lk\x93[\x8b\xbd@\x00\x00\u07d4%\xb0S;\x81\xd0*a{\x92)\xc7\xec]o/g.[Z\x8965\u026d\xc5\u07a0\x00\x00\u07d4%\xb7\x8c\x9f\xad\x85\xb43C\xf0\xbf\xcd\x0f\xac\x11\u0254\x9c\xa5\xeb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4%\xbcI\xef(\x8c\xd1e\xe5%\xc6a\xa8\x12\u03c4\xfb\xec\x8f3\x89\x12Y!\xae\xbd\xa9\xd0\x00\x00\u07d4%\xbd\xfa>\xe2o8Ia{#\x00bX\x8a\x97\xe3\xca\xe7\x01\x8965\xe6\x19\xbb\x04\xd4\x00\x00\u07d4%\xc1\xa3~\xe5\xf0\x82e\xa1\xe1\r=\x90\xd5G)U\xf9x\x06\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4%\xc6\xe7O\xf1\xd9(\u07d8\x13z\xf4\u07c40\xdf$\xf0|\u05c9\x15$VU\xb1\x02X\x00\x00\xe0\x94%\xcf\xc4\xe2\\5\xc1;i\xf7\xe7}\xbf\xb0\x8b\xafXuk\x8d\x8a\bxg\x83&\xea\xc9\x00\x00\x00\xe0\x94%\xda\u0515\xa1\x1a\x86\xb9\xee\xec\xe1\xee\xec\x80^W\xf1W\xfa\xff\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\xe0\x94%\xe07\xf0\n\x18'\v\xa5\xec4 \"\x9d\xdb\n,\u33e2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4%\xe6a\xc99\x86:\xcc\x04No\x17\xb5i\x8c\xce7\x9e\xc3\u0309JD\x91\xbdm\xcd(\x00\x00\u07d4&\x04\x8f\xe8M\x9b\x01\nb\xe71b~I\xbc.\xb7?@\x8f\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4&\x06\u00f3\xb4\xca\x1b\t\x14\x98`,\xb1\x97\x8b\xf3\xb9R!\xc0\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4&\n#\x0eDe\a~\v\x14\xeeDB\xa4\x82\u0570\xc9\x14\xbf\x89Z\xf6\x06\xa0k[\x11\x80\x00\u07d4&\r\xf8\x94:\x8c\x9a]\xbayE2\u007f\xd7\xe0\x83|\x11\xad\a\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4&\x14\xf4-]\xa8D7ux\xe6\xb4H\xdc$0[\xef+\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4&\x15\x10\x0e\xa7\xe2[\xba\x9b\xcat`X\xaf\xbb\xb4\xff\xbeBD\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4&\x15u\xe9\xcfY\xc8\"o\xa7\xaa\xf9\x1d\xe8o\xb7\x0fZ\u00ee\x89\x10C\xa4CjR?\x00\x00\xe0\x94&\x1e\x0f\xa6LQ\x13te\xee\xcf[\x90\xf1\x97\xf7\x93\u007f\xdb\x05\x8a\x03\xcf\xc8.7\xe9\xa7@\x00\x00\u07d4&*\x8b\xfd}\x9d\xc5\xdd:\u05c1a\xb6\xbbV\b$76U\x89?j\x83\x84\a+v\x00\x00\xe0\x94&*\xedK\xc0\xf4\xa4\xb2\xc6\xfb5y>\x83ZI\x18\x9c\xdf\xec\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94&-\xc16L\xcfm\xf8\\C&\x8e\xe1\x82UM\xaei.)\x8a\x01\v /\xect\xce\xd8\x00\x00\u07d4&8\x140\x9d\xe4\xe65\xcfX^\r6Tw\xfc@\xe6l\xf7\x89\a\xea(2uw\b\x00\x00\u07d4&9\xee\xe9\x87<\xee\xc2o\u0314T\xb5H\xb9\xe7\xc5J\xa6\\\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94&>W\xda\xcb\xe0\x14\x9f\x82\xfee\xa2fH\x98\x86o\xf5\xb4c\x8a\b\v\xfb\xef\xcb_\v\xc0\x00\x00\u07d4>\x19\xc0m_\x14z\xa5\x97$\x8e\xb4l\xf7\xbe\xfad\xa5\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4&L\xc8\bj\x87\x10\xf9\x1b!r\t\x05\x91,\u05d6J\xe8h\x89\x01s\x17\x90SM\xf2\x00\x00\xe0\x94&S\x83\u058bR\xd04\x16\x1b\xfa\xb0\x1a\xe1\xb0G\x94/\xbc2\x8a\x04rq\xde\xe2\rt\\\x00\x00\u07d4&Y\xfa\xcb\x1e\x83CeS\xb5\xb4)\x89\xad\xb8\a_\x99S\xed\x89\x01\x97evw\x1a^\x00\x00\xe0\x94&o-\xa7\xf0\b^\xf3\xf3\xfa\t\xba\xee#+\x93\xc7D\xdb.\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4&qH\xfdr\xc5Ob\nY/\xb9'\x991\x9c\xc4S+\\\x89\x169\u46fa\x16(\x00\x00\xe0\x94&xJ\u0791\u0228:\x8e9e\x8c\x8d\x82wA<\u0319T\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4&z~n\x82\xe1\xb9\x1dQ\xde\u0776D\xf0\xe9m\xbb\x1f\u007f~\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4&\x80q=@\x80\x8e*P\xed\x011P\xa2\xa6\x94\xb9j\u007f\x1d\x89a\t=|,m8\x00\x00\u07d4&\x97\xb39\x81;\f-\x96K$q\xeb\x1c`oN\u02d6\x16\x89>\x8e\xf7\x95\u0610\xc8\x00\x00\u07d4&\xa6\x8e\xab\x90Z\x8b=\xce\x00\xe3\x170\x82%\u06b1\xb9\xf6\xb8\x89kV\x05\x15\x82\xa9p\x00\x00\u07d4&\xb1\x1d\x06e\x88\xcet\xa5r\xa8Zc(s\x92\x12\xaa\x8b@\x89lk\x93[\x8b\xbd@\x00\x00\u07d4&\xba\xbfB\xb2g\xfd\xcf8a\xfd\xd4#j^GHH\xb3X\x8965\u026d\xc5\u07a0\x00\x00\u07d4&\xc0\x05Kp\r:|-\xcb\xe2uh\x9dOL\xad\x16\xa35\x89lk\x93[\x8b\xbd@\x00\x00\u07d4&\xc2\xff\xc3\x0e\xfd\xc5'>v\x18:\x16\xc2i\x8dnS\x12\x86\x89*\x11)\u0413g \x00\x00\u07d4&\u025f\x88I\u0240+\x83\xc8a!\u007f\xd0z\x9e\x84\u0377\x9d\x89\x10CV\x1a\x88)0\x00\x00\u07d4&\xcf\xff\xd0R\x15+\xb3\xf9W\xb4x\xd5\xf9\x8b#:|+\x92\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4&\u0521h\x91\xf5)\"x\x92\x17\xfc\u0606\xf7\xfc\xe2\x96\xd4\x00\x89lk\x93[\x8b\xbd@\x00\x00\u07d4&\xd4\xec\x17\xd5\u03b2\u0214\xbd\u015d\nji]\xad+C\u0309\x9f\x1fxv\x1d4\x1a\x00\x00\u07d4&\xe8\x01\xb6,\x82q\x91\xddh\xd3\x1a\x01\x19\x90\x94\u007f\xd0\xeb\xe0\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4&\xe9\xe2\xadr\x97\x02bd\x17\xef%\xde\r\xc8\x00\xf7\xa7y\xb3\x8965\u026d\xc5\u07a0\x00\x00\u07d4&\xf9\xf7\xce\xfd~9K\x9d9$A+\xf2\u0083\x1f\xaf\x1f\x85\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94&\xfe\x17L\xbfRfP\xe0\xcd\x00\x9b\xd6\x12e\x02\u038ehM\x8a\x02w\x01s8\xa3\n\xe0\x00\x00\xe0\x94&\xff\nQ\xe7\xce\u0384\x00'ix\xdb\xd6#n\xf1b\xc0\xe6\x8a\x15.\x18V'T\nP\x00\x00\u07d4'\x10\x1a\x0fV\u04da\x88\u0168O\x9b2L\xdd\xe3>\\\xb6\x8c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4'\x14L\xa9\xa7w\x1a\x83j\xd5\x0f\x80?d\xd8i\xb2\xae+ \x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4'\x14i\x13V:\xa7E\xe2X\x840\xd94\x8e\x86\xea|5\x10\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4'\x1d=H\x1c\xb8\x8evq\xad!iI\xb66^\x060=\xe0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4' \xf9\xcaBn\xf2\xf2\xcb\xd2\xfe\xcd9\x92\fO\x1a\x89\xe1m\x89lk\x93[\x8b\xbd@\x00\x00\u07d4'*\x13\x1aZejz:\xca5\u023d \"\"\xa7Y\"X\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4'D\xffgFA!\xe3Z\xfc)\"\x17qd\xfa/\xcb\x02g\x89\x05k\xc7^-c\x10\x00\x00\u07d4'J=w\x1a=p\x97\x96\xfb\xc4\xd5\xf4\x8f\xce/\xe3\x8cy\u0589\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4'Mi\x17\x0f\xe7\x14\x14\x01\x88+\x88j\xc4a\x8cj\xe4\x0e\u06c93\xc5I\x901r\f\x00\x00\u07d4'R\x1d\xeb;n\xf1An\xa4\u01c1\xa2\xe5\u05f3n\xe8\x1ca\x89lk\x93[\x8b\xbd@\x00\x00\u07d4'Xu\xffO\xbb\f\xf3\xa40!1'H\u007fv\b\xd0L\xba\x89\x1b\x1c\x01\x0evmX\x00\x00\u07d4'j\x00n0(\xec\xd4L\xdbb\xba\nw\u0394\xeb\xd9\xf1\x0f\x89a\x94\x04\x9f0\xf7 \x00\x00\u07d4'k\x05!\xb0\xe6\x8b'}\xf0\xbb2\xf3\xfdH2cP\xbf\xb2\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4'o\xd7\xd2O\x8f\x88?Zz()[\xf1qQ\u01e8K\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4'p\xf1N\xfb\x16]\u07bay\xc1\v\xb0\xaf1\xc3\x1eY3L\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4'vw\xab\xa1\xe5,;S\xbf\xa2\a\x1dN\x85\x9a\n\xf7\xe8\xe1\x8965\u026d\xc5\u07a0\x00\x00\u07d4'\x82Ff\xd2x\xd7\x04#\xf0=\xfe\x1d\u01e3\xf0/C\u2d4966\xc2^f\xec\xe7\x00\x00\u07d4'\x83\f_`#\xaf\xaa\xf7\x97Egl J\x0f\xac\u0360\xba\x89\r\x02\xabHl\xed\xc0\x00\x00\xe0\x94'\x84\x90?\x1d|\x1b\\\xd9\x01\xf8\x87]\x14\xa7\x9b<\xbe*V\x8a\x04\xbd\xa7\xe9\xd7J\xd5P\x00\x00\u07d4'\x8c\v\xdec\x0e\u00d3\xb1\xe7&\u007f\xc9\xd7\xd9p\x19\xe4\x14[\x89lk\x93[\x8b\xbd@\x00\x00\u07d4'\x98q\x10\"\x1a\x88\b&\xad\xb2\xe7\xab^\xcax\xc6\xe3\x1a\xec\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94'\xac\a;\xe7\x9c\xe6W\xa9:\xa6\x93\xeeC\xbf\x0f\xa4\x1f\xef\x04\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4'\xb1iN\xaf\xa1e\xeb\xd7\xcc{\u025et\x81J\x95\x14\x19\u0709+^:\xf1k\x18\x80\x00\x00\u07d4'\xb6(\x16\xe1\xe3\xb8\u045by\xd1Q=]\xfa\x85[\f:*\x89\x05j\xf5\xc1\xfdiP\x80\x00\u07d4'\xbf\x94<\x163\xfe2\xf8\xbc\xcc\xdbc\x02\xb4\a\xa5rND\x892\xf8Lm\xf4\b\xc0\x80\x00\u07d4'\xbf\x9fD\xba}\x05\xc35@\u00e5;\xb0,\xbb\xff\xe7\xc3\u0189lk\x93[\x8b\xbd@\x00\x00\u07d4'\xc2\xd7\xcaPM\xaa=\x90f\xdc\t\x13}\xc4/:\xaa\xb4R\x89 \x86\xac5\x10R`\x00\x00\u07d4'\xd1X\xac=>\x11\t\xabnW\x0e\x90\xe8]8\x92\xcdv\x80\x89\x05k\xc7^-c\x10\x00\x00\u07d4'\xe69\x89\xca\x1e\x90;\xc6 \xcf\x1b\x9c?g\xb9\xe2\xaee\x81\x89Hz\x9a0E9D\x00\x00\xe0\x94'\xf0<\xf1\xab\xc5\xe1\xb5\x1d\xbcDK(\x9eT,\x9d\u07f0\xe6\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4'\xfc\x85\xa4\x9c\xff\x90\xdb\xcf\xda\u071d\xdd@\u05b9\xa2!\nl\x89\x05k\xc7^-c\x10\x00\x00\u07d4(\x05A^\x1d\u007f\xde\xc6\xde\u07f8\x9eR\x1d\x10Y-t<\x10\x89\x05k\xc7^-c\x10\x00\x00\u07d4(\a>\xfc\x17\xd0\\\xab1\x95\xc2\xdb3+a\x98Gw\xa6\x12\x8965\u026d\xc5\u07a0\x00\x00\u07d4(\x12P\xa2\x91!'\nN\xe5\u05cd$\xfe\xaf\xe8,p\xba:\x8965\u026d\xc5\u07a0\x00\x00\u07d4(\x13\xd2c\xfc_\xf2G\x9e\x97\x05\x95\u05b6\xb5`\xf8\xd6\xd6\u0449lk\x93[\x8b\xbd@\x00\x00\u07d4(.\x80\xa5T\x87ZVy\x9f\xa0\xa9\u007fU\x10\u7557LN\x8965\u026d\xc5\u07a0\x00\x00\u07d4(3\x96\xce<\xac9\x8b\xcb\xe7\"\u007f2>x\xff\x96\u0407g\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4(4\x9f~\xf9t\xeaU\xfe6\xa1X;4\xce\xc3\xc4Pe\xf0\x89\f\xb63\u051eeY\x00\x00\u07d4(6\x120F\xb2\x84\xe5\xef\x10+\xfd\"\xb1v^P\x81\x16\xad\x89\x16S\xfb\xb5\xc4'\xe4\x00\x00\u07d4(<#\x14(<\x92\u0530d\xf0\xae\xf9\xbbRF\xa7\x00\u007f9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4(>\x11 7I\xb1\xfaO2\xfe\xbbq\xe4\x9d\x13Y\x198*\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94(>bR\xb4\xef\xcfFT9\x1a\xcbu\xf9\x03\u015bx\xc5\xfb\x8a\x02\x8a\x85t%Fo\x80\x00\x00\xe0\x94(Q\x0en\xff\x1f\xc8)\xb6WoC(\xbc98\xecze\x80\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4(X\xac\xac\xaf!\xea\x81\u02b7Y\x8f\xdb\xd8kE.\x9e\x8e\x15\x89$\x1a\x9bOaz(\x00\x00\u07d4(Z\xe5\x1b\x95\x00\u014dT\x13e\xd9ui\xf1K\xb2\xa3p\x9b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4(f\xb8\x1d\xec\xb0.\xe7\n\xe2P\xce\xe5\xcd\xc7{Y\u05f6y\x89lk\x93[\x8b\xbd@\x00\x00\u07d4(i\x06\xb6\xbdIr\xe3\xc7\x16U\xe0K\xaf6&\f|\xb1S\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4(k\x18ma\xea\x1f\u05cd\x990\xfe\x12\xb0e7\xb0\\=Q\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94(t\xf3\xe2\x98]_{@f'\xe1{\xaaw+\x01\xab\u031e\x8a\x01F\x05\x04\x10v_8\x00\x00\xe0\x94(|\xf9\u0410.\xf8\x19\xa7\xa5\xf1ID[\xf1w^\xe8\xc4|\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4(\x81\x8e\x18\xb6\x10\x00\x13!\xb3\x1d\xf6\xfe}(\x15\u036d\xc9\xf5\x8965\u026d\xc5\u07a0\x00\x00\u07d4(\x86\x83$3~\x11\xba\x10l\xb4\x81\u0696/:\x84S\x80\x8d\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94(\x90K\xb7\xc40)C\xb7\t\xb1Myp\xe4+\x83$\u184a\x02\x1f\x97\x84j\a-~\x00\x00\u07d4(\x95\xe8\t\x99\xd4\x06\xadY.+&'7\xd3_}\xb4\xb6\x99\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4(\x96r\x80!N!\x8a\x12\f]\xda7\x04\x1b\x11\x1e\xa3mt\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4(\xa3\xda\t\xa8\x19H\x19\xae\x19\x9f.m\x9d\x13\x04\x81~(\xa5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4(\xab\x16_\xfbi\xed\xa0\xc5I\xae8\xe9\x82o_\u007f\x92\xf8S\x89FM\xf6\xd7\xc8DY\x00\x00\u07d4(\xb7u\x85\xcb=U\xa1\x99\xab)\x1d:\x18\u018f\u8684\x8a\x89j@v\xcfy\x95\xa0\x00\x00\xe0\x94(\xd4\xeb\xf4\x1e=\x95\xf9\xbb\x9a\x89u#\\\x1d\x009>\x80\x00\u07d4)\nV\xd4\x1fn\x9e\xfb\xdc\xea\x03B\u0dd2\x9a\x8c\xdf\xcb\x05\x89\x12\xa5\xf5\x81h\xee`\x00\x00\u07d4)\x15bK\xcbg\x917\xb8\xda\xe9\xabW\xd1\x1bI\x05\xea\xeeK\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4)\x1e\xfe\x00\x81\xdc\xe8\xc1G\x99\xf7\xb2\xa46\x19\xc0\u00f3\xfc\x1f\x89A\rXj \xa4\xc0\x00\x00\u07d4)\x1f\x92\x9c\xa5\x9bT\xf8D>=Mu\xd9]\xee$<\xefx\x89\x1b\x1a\b\x927\a=\x00\x00\xe0\x94))\x8c\xcb\xdf\xf6\x89\xf8\u007f\xe4\x1a\xa6\xe9\x8f\u07f5=\xea\xf3z\x8a\x041\\2\xd7\x1a\x9e`\x00\x00\u07d4)/\"\x8b\n\x94t\x8c\x8e\xeca-$o\x98\x93c\xe0\x8f\b\x89\n\ad\a\xd3\xf7D\x00\x00\u07d4)3\x84\xc4+o\x8f)\x05\xceR\xb7 \\\"t7la+\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4)4\xc0\xdf{\xbc\x17+l\x18k\vrTz\u038b\xf7TT\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4)<#\x06\xdf6\x04\xaeO\xda\r z\xbasog\xde\a\x92\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94)I\xfd\x1d\xef\\v\xa2\x86\xb3\x87$$\x80\x9a\a\xdb9f\xf3\x8a\x01\x1b\xd9\x06\u06a0\xc9C\x80\x00\u07d4)OIK?.\x14\xa3\xf8\xab\x00\x00\x00\u07d4)U\xc3W\xfd\x8fu\xd5\x15\x9a=\xfai\u0178z5\x9d\ua309lk\x93[\x8b\xbd@\x00\x00\u07d4)a\xfb9\x1ca\x95|\xb5\xc9\xe4\a\u0762\x938\u04f9,\x80\x8964\xfb\x9f\x14\x89\xa7\x00\x00\u07d4)h\x1d\x99\x12\xdd\xd0~\xaa\xbb\x88\xd0]\x90\xf7f\xe8bA}\x8965\u026d\xc5\u07a0\x00\x00\u07d4)kq\xc0\x01X\x19\xc2B\xa7\x86\x1eo\xf7\xed\xed\x8a_q\xe3\x89lh\xcc\u041b\x02,\x00\x00\u07d4)mf\xb5!W\x1aNA\x03\xa7\xf5b\xc5\x11\xe6\xaas-\x81\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4)o\x00\xde\x1d\u00fb\x01\xd4z\x8c\xcd\x1e]\x1d\u0661\xebw\x91\x8965\u026d\xc5\u07a0\x00\x00\u07d4)s\x85\xe8\x864FV\x85\xc21\xa3\x14\xa0\xd5\xdc\xd1F\xaf\x01\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4)v=\xd6\u069a|\x16\x11s\x88\x83!\ub9b6<\x8f\xb8E\x89\x11\xc7\xea\x16.x \x00\x00\u07d4)yt\x11t\xa8\xc1\xea\v\u007f\x9e\xdfe\x81w\x85\x94\x17\xf5\x12\x89\x19\x01\x96l\x84\x96\x83\x80\x00\u07d4)z\x88\x92\x1b_\xca\x10\u5edd\xed`\x02T7\xae\"\x16\x94\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94)}]\xbe\"//\xb5%1\xac\xbd\v\x01=\xc4F\xacsh\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4)\x82N\x94\xccCH\xbc\x962y\xdc\xdfG9\x17\x152L\u04c9i*\xe8\x89p\x81\xd0\x00\x00\u07d4)\x82\xd7j\x15\xf8G\xddA\xf1\x92*\xf3h\xfeg\x8d\x0eh\x1e\x89\x05k\xc7^-c\x10\x00\x00\u07d4)\x88\x87\xba\xb5|[\xa4\xf0aR)\xd7R_\xa1\x13\xb7\ua249\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94)\x8e\xc7kD\r\x88\a\xb3\xf7\x8b_\x90\x97\x9b\xeeB\xedC\u06ca\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4)\x93h`\x90B\xa8X\xd1\xec\xdf\x1f\xc0\xad\xa5\xea\xce\xca)\u03c9lk\x93[\x8b\xbd@\x00\x00\u07d4)\x9e\v\xcaU\xe0i\u0785\x04\xe8\x9a\xcan\xca!\u04ca\x9a]\x89\x03\x027\x9b\xf2\xca.\x00\x00\u07d4)\xac+E\x84T\xa3l~\x96\xc7:\x86g\"*\x12$,q\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94)\xad\u03c3\xb6\xb2\n\u01a44\xab\xb1\x99<\xbd\x05\xc6\x0e\xa2\xe4\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94)\xae\xf4\x8d\xe8\xc9\xfb\xadK\x9eL\xa9pyzU3\xebr-\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4)\xb3\xf5a\xeezn%\x94\x1e\x98\xa52[x\xad\u01d7\x85\xf3\x89\x05k\xc7^-c\x10\x00\x00\u07d4)\xbd\xc4\xf2\x8d\xe0\x18\x0fC<&\x94\xebt\xf5PL\xe9C7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4)\u0300M\x92+\xe9\x1fY\t\xf3H\xb0\xaa\xa5\xd2\x1b`x0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94)\xda>5\xb2;\xb1\xf7/\x8e\"X\xcf\u007fU3Y\xd2K\xac\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94)\xe6y\x90\xe1\xb6\xd5.\x10U\xff\xe0I\xc51\x95\xa8\x15B\u03ca\x04<3\xc1\x93ud\x80\x00\x00\u07d4)\uab82v\x17b\xf4\xd2\xdbS\xa9\u018b\x0fk\vmNf\x89lk\x93[\x8b\xbd@\x00\x00\u07d4)\xeb~\xef\xda\xe9\xfe\xb4I\xc6?\xf5\xf2y\xd6u\x10\xeb\x14\"\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4)\xf0\xed\xc6\x038\xe7\x11 \x85\xa1\xd1\x14\u068cB\u038fU\u0589\xa0Z\u007f\x0f\xd8%x\x00\x00\u07d4)\xf8\xfb\xa4\xc3\ar\xb0W\xed\xbb\xe6*\xe7B\f9\x05r\xe1\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94)\xf9(l\x0es\x8d\x17!\xa6\x91\u01b9Z\xb3\u0667\x97\xed\xe8\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4*\b^%\xb6Hb\xf5\xe6\x8dv\x8e+\x0fz\x85)\x85\x8e\xee\x89k\x88:\xcdWf\xcd\x00\x00\u07d4**\xb6\xb7Lz\xf1\xd9Gk\xb5\xbc\xb4RG\x97\xbe\xdc5R\x8965\u026d\xc5\u07a0\x00\x00\u07d4*9\x19\nO\u0783\u07f3\xdd\xcbL_\xbb\x83\xaclIu\\\x8965\u026d\xc5\u07a0\x00\x00\u07d4*@\r\xff\x85\x94\xder(\xb4\xfd\x15\xc3#\"\xb7[\xb8}\xa8\x89\x051\xa1\u007f`z-\x00\x00\xe0\x94*D\xa7!\x8f\xe4Me\xa1\xb4\xb7\xa7\u0671\xc2\xc5,\x8c>4\x8a\r-\x06\xc3\x05\xa1\xebW\x80\x00\u07d4*F\xd3Swqv\xff\x8e\x83\xff\xa8\x00\x1fOp\xf9s:\xa5\x89\x05\xbf\v\xa6cOh\x00\x00\u07d4*Y_\x16\xee\xe4\xcb\f\x17\u0662\xd99\xb3\xc1\x0flgrC\x89;\xa1\x91\v\xf3A\xb0\x00\x00\u07d4*Y\xe4~\xa5\xd8\xf0\xe7\xc0(\xa3\xe8\xe0\x93\xa4\x9c\x1bP\xb9\xa3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4*[\xa9\xe3L\u054d\xa5L\x9a'\x12f:;\xe2t\xc8\xe4{\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94*^:@\xd2\xcd\x03%vm\xe7:=g\x18\x96\xb3b\xc7;\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94*cY\x0e\xfe\x99\x86\xc3\xfe\xe0\x9b\n\n3\x8b\x15\xbe\xd9\x1f!\x8a\x01^\x1cN\x05\xee&\xd0\x00\x00\u07d4*gf\n\x13h\xef\xcdbn\xf3k+\x1b`\x19\x80\x94\x1c\x05\x89\a?u\u0460\x85\xba\x00\x00\u07d4*t+\x89\x10\x94\x1e\t2\x83\n\x1d\x96\x92\xcf\u0484\x94\xcf@\x89\x1b\x1a\xb3\x19\xf5\xecu\x00\x00\u07d4*tl\xd4@'\xaf>\xbd7\xc3x\xc8^\xf7\xf7T\xab_(\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4*\x81\xd2|\xb6\xd4w\x0f\xf4\xf3\u0123\xba\x18\xe5\xe5\u007f\aQ|\x89lk\x93[\x8b\xbd@\x00\x00\u07d4*\x91\xa9\xfe\xd4\x1b}\x0e\\\xd2\xd81X\xd3\xe8\xa4\x1a\x9a-q\x89i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94*\x9cW\xfe{k\x13\x8a\x92\rgo{\x1a%\x10\x80\xff\xb9\x8a4\xf0\x86\xf3\xb3;h@\x00\x00\u07d4+p\x1d\x16\xc0\xd3\xcc\x1eL\xd8TE\xe6\xad\x02\ue92c\x01-\x89 \x86\xac5\x10R`\x00\x00\xe0\x94+q|\xd42\xa3#\xa4e\x909\x84\x8d;\x87\xde&\xfc\x95F\x8ai\xe1\r\xe7fv\u0400\x00\x00\u07d4+t\xc3s\xd0K\xfb\x0f\xd6\n\x18\xa0\x1a\x88\xfb\xe8Gp\u5309\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4+w\xa4\u060c\rV\xa3\xdb\xe3\xba\xe0J\x05\xf4\xfc\u0477W\xe1\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94+\x84\x88\xbd-<\x19z=&\x15\x18\x15\xb5\xa7\x98\xd2qh\u070a\x01j\x1f\x9f_\xd7\xd9`\x00\x00\u07d4+\x8a\r\xee\\\xb0\xe1\xe9~\x15\xcf\xcan\x19\xad!\xf9\x95\ufb49\x1bUC\x8d\x9a$\x9b\x00\x00\xe0\x94+\x8f\xe4\x16n#\xd1\x19c\xc0\x93+\x8a\u078e\x01E\xea\ap\x8a\t(\x96R\x9b\xad\u0708\x00\x00\xe0\x94+\x99\xb4.OBa\x9e\xe3k\xaa~J\xf2\xd6^\xac\xfc\xba5\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4+\xab\x0f\xbe(\u0544 \xb5 6w\n\x12\xf9\x95*\xeai\x11\x89\xcf\x15&@\xc5\xc80\x00\x00\u07d4+\xad\xe9\x1d\x15E\x17b\x0f\u05349\xac\x97\x15zA\x02\xa9\xf7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4+\xaf\x8dn\"\x11t\x12H \xeeI+\x94Y\xecO\xad\xaf\xbb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4+\xaf\xbf\x9e\x9e\xd2\xc2\x19\xf7\xf2y\x13t\xe7\xd0\\\xb0gw\xe7\x89\v\xed\x1d\x02c\xd9\xf0\x00\x00\xe0\x94+\xb3f\xb9\xed\xcb\r\xa6\x80\xf0\xe1\v;n(t\x81\x90\xd6\u00ca\x01:b\u05f5v@d\x00\x00\xe0\x94+\xb6\xf5x\xad\xfb\u7ca1\x16\xb3UO\xac\xf9\x96\x98\x13\xc3\x19\x8a\x01\x91'\xa19\x1e\xa2\xa0\x00\x00\u07d4+\xbeb\xea\xc8\f\xa7\xf4\xd6\xfd\xee~}\x8e(\xb6:\xcfw\x0e\x89\x81\xe3-\xf9r\xab\xf0\x00\x00\u07d4+\xbeg*\x18WP\x8fc\x0f*^\xdbV=\x9e\x9d\xe9(\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4+\xc4)\xd6\x18\xa6jL\xf8-\xbb-\x82N\x93V\xef\xfa\x12j\x89lj\xccg\u05f1\xd4\x00\x00\u07d4+\xd2R\xe0\xd72\xff\x1d|x\xf0\xa0.l\xb2T#\xcf\x1b\x1a\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4+\xdd\x03\xbe\xbb\xee';l\xa1\x05\x9b4\x99\x9a[\xbda\xbby\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4,\x04\x11\\>R\x96\x1b\r\xc0\xb0\xbf1\xfb\xa4ToYf\xfd\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94,\x06\u0752+aQJ\xaf\xed\xd8D\x88\xc0\u008em\xcf\x0e\x99\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94,\f\xc3\xf9QH,\u0222\x92X\x15hN\xb9\xf9N\x06\x02\x00\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4,\x0e\xe14\u0633aE\xb4{\xee\u7bcd'8\xdb\xda\b\xe8\x89\n\xe5os\x0em\x84\x00\x00\u07d4,\x0f[\x9d\xf46%y\x8e~\x03\xc1\xa5\xfdjm\t\x1a\xf8+\x89\x01\xb0\xfc\xaa\xb2\x000\x00\x00\u07d4,\x12\x8c\x95\xd9W!Q\x01\xf0C\u074f\u0142EmA\x01m\x89-C\xf3\xeb\xfa\xfb,\x00\x00\u07d4,\x18\x00\xf3_\xa0->\xb6\xff[%(_^J\xdd\x13\xb3\x8d\x891\"\u04ed\xaf\xde\x10\x00\x00\u07d4,\x1c\x19\x11N=m\xe2xQHK\x8d'\x15\xe5\x0f\x8a\x10e\x89\x05k\xc7^-c\x10\x00\x00\u07d4,\x1c\xc6\xe1\x8c\x15$\x88\xba\x11\xc2\xcc\x1b\xce\xfa-\xf3\x06\xab\u0449Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94,\x1d\xf8\xa7oH\xf6\xb5K\u03dc\xafV\xf0\xee\x1c\xf5z\xb3=\x8a\x02$\u007fu\x00\x89\xdaX\x00\x00\u07d4,!G\x94z\xe3?\xb0\x98\xb4\x89\xa5\xc1k\xff\xf9\xab\xcdN*\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4,#OP\\\xa8\xdc\xc7}\x9b~\x01\xd2W\xc3\x18\xcc\x199m\x89\x05k\xc7^-c\x10\x00\x00\u07d4,$(\xe4\xa6it\xed\xc8\"\xd5\xdb\xfb$\x1b'(\aQX\x89lk\x93[\x8b\xbd@\x00\x00\u07d4,-\x15\xff9V\x1c\x1br\xed\xa1\xcc\x02\u007f\xfe\xf27C\xa1D\x89\u0500\xed\x9e\xf3+@\x00\x00\u07d4,-\xb2\x8c3\t7^\xea1\x82\x1b\x84\xd4\b\x93\x0e\xfa\x1a\u01c9lk\x93[\x8b\xbd@\x00\x00\u07d4,Z-\n\xbd\xa0;\xbe!W\x81\xb4\xff)l\x8ca\xbd\xba\xf6\x89\x01\xa8\xe5oH\xc0\"\x80\x00\u07d4,[}{\x19Z7\x1b\xf9\xab\u0774/\xe0O/\x1d\x9a\x99\x10\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4,]\xf8ffj\x19K&\u03bb@~J\x1f\xd7> \x8d^\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94,`?\xf0\xfe\x93alCW>\xf2y\xbf\xea@\x88\x8dj\xe7\x8a\x01\x00\xf4\xb6\xd6gW\x90\x00\x00\xe0\x94,hF\xa1\xaa\x99\x9a\"F\xa2\x87\x05`\x00\xbaM\u02e8\xe6=\x8a\x02\x1f/o\x0f\xc3\xc6\x10\x00\x00\u0794,j\xfc\xd4\x03|\x1e\xd1O\xa7O\xf6u\x8e\tE\xa1\x85\xa8\xe8\x88\xf4?\xc2\xc0N\xe0\x00\x00\u07d4,ki\x9d\x9e\xad4\x9f\x06\u007fEq\x1a\aJd\x1d\xb6\xa8\x97\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4,o\\\x12L\u01c9\xf8\xbb9\x8e?\x88\x97Q\xbcK`-\x9e\x89\x01Y\xf2\v\xed\x00\xf0\x00\x00\u07d4,\x83\xae\xb0/\xcf\x06}e\xa4p\x82\xfd\x97x3\xab\x1c\uc449\b'8#%\x8a\xc0\x00\x00\xe0\x94,\x89\xf5\xfd\xca=\x15T\t\xb68\xb9\x8at.U\xebFR\xb7\x8a\x14\u06f2\x19\\\xa2(\x90\x00\x00\u07d4,\x96HI\xb1\xf6\x9c\xc7\u03a4D%8\xed\x87\xfd\xf1l\xfc\x8f\x89lk\x93[\x8b\xbd@\x00\x00\u0794,\x9f\xa7,\x95\xf3}\b\xe9\xa3`\t\u7930\u007f)\xba\xd4\x1a\x88\xdfn\xb0\xb2\xd3\xca\x00\x00\u07d4,\xafk\xf4\xec}Z\x19\xc5\xe0\x89z^\xeb\x01\x1d\xce\xceB\x10\x89\a\x93H5\xa01\x16\x00\x00\u07d4,\xb4\xc3\xc1k\xb1\xc5^|kz\x19\xb1'\xa1\xac\x93\x90\xcc\t\x89\xb8'\x94\xa9$O\f\x80\x00\xe0\x94,\xb5IZPS6\xc2FT\x10\xd1\xca\xe0\x95\xb8\xe1\xba\\\u074a\x04<3\xc1\x93ud\x80\x00\x00\u07d4,\xb6\x15\a:@\xdc\u06d9\xfa\xa8HW.\x98{;\x05n\xfb\x89+X\xad\u06c9\xa2X\x00\x00\u07d4,\xbam]\r\xc2\x04\xea\x8a%\xad\xa2\xe2oVu\xbd_/\u0709H#\xef}\u06da\xf3\x80\x00\u07d4,\xbb\fs\u07d1\xb9\x17@\xb6i;wJ}\x05\x17~\x8eX\x89dI\xe8NG\xa8\xa8\x00\x00\u07d4,\xcbfIM\n\xf6\x89\xab\xf9H=6]x$D\xe7\u07ad\x8965\u026d\xc5\u07a0\x00\x00\u07d4,\xcc\x1f\x1c\xb5\xf4\xa8\x00.\x18k \x88]\x9d\xbc\x03\f\b\x94\x89lk\x93[\x8b\xbd@\x00\x00\u07d4,\u03c0\xe2\x18\x98\x12^\xb4\xe8\a\u0342\xe0\x9b\x9d(Y/n\x89lk\x93[\x8b\xbd@\x00\x00\u07d4,\u0456\x94\u0452j\x0f\xa9\x18\x9e\u07ba\xfcg\x1c\xf1\xb2\u02a5\x8965\u026d\xc5\u07a0\x00\x00\u07d4,\u04d34\xac~\xacyrW\xab\xe3sa\x95\xf5\xb4\xb5\xce\x0f\x89\x05kGx^7&\x00\x00\u07d4,\u05de\xb5 '\xb1,\x18\x82\x8e>\xaa\xb2\x96\x9b\xfc\u0487\xe9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4,\xd8xfV\x8d\xd8\x1a\xd4}\x9d:\u0404nZePss\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4,\xdb9De\x06\x16\xe4|\xb1\x82\xe0`2/\xa1Hyx\u0389b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4,\xe1\x1a\x92\xfa\xd0$\xff+>\x87\xe3\xb5B\xe6\xc6\r\xcb\u0656\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4-\x03&\xb2?\x04\t\xc0\xc0\xe9#hc\xa13\aZ\x94\xba\x18\x89\vg\x9b\xe7[\xe6\xae\x00\x00\u07d4-\r\xecQ\xa6\xe8s0\xa6\xa8\xfa*\x0fe\u060dJ\xbc\xdfs\x89\n\ad\a\xd3\xf7D\x00\x00\u07d4-#vkok\x05s}\xad\x80\xa4\x19\xc4\x0e\xdaMw\x10>\x89\xcf\x15&@\xc5\xc80\x00\x00\u07d4-+\x03#Y\xb3c\x96O\xc1\x1aQ\x82c\xbf\xd0T1\xe8g\x89\b\x1c\x1d\xf7b\x9ep\x00\x00\u07d4-4\x80\xbf\be\aJr\xc7u\x9e\xe5\x13{Mp\xc5\x1c\xe9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4-5\xa9\xdfbu\u007f\u007f\xfa\xd1\x04\x9a\xfb\x06\xcaJ\xfcFLQ\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4-@U\x8b\x06\xf9\n9#\x14U\x92\x12;gt\xe4n1\xf4\x8965\u026d\xc5\u07a0\x00\x00\u07d4-Bi\x12\xd0Y\xfa\xd9t\v.9\n.\xea\xc0To\xf0\x1b\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4-S-\xf4\xc69\x11\xd1\u0391\xf6\xd1\xfc\xbf\xf7\x96\x0fx\xa8\x85\x89Z\x85\x96\x8aXx\u0680\x00\u07d4-S\x91\xe98\xb3HX\u03d6[\x84\x051\xd5\xef\xdaA\v\t\x89K\xe4\xe7&{j\xe0\x00\x00\xe0\x94-[B\xfcY\xeb\xda\r\xfdf\xae\x91K\u008c\x1b\nn\xf8:\x8a+\u0235\x9f\xdc\xd86c\x80\x00\u07d4-]s5\xac\xb06+G\u07e3\xa8\xa4\xd3\xf5\x94\x95D\u04c0\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94-a\xbf\xc5hs\x92<+\x00\t]\xc3\xea\xa0\xf5\x90\u062e\x0f\x8a\x04ef\xdf\xf8\xceU`\x00\x00\u07d4-e\x11\xfdz8\x00\xb2hT\xc7\xec9\xc0\u0735\xf4\xc4\xe8\xe8\x89\x15\xad\u077a/\x9ew\x00\x00\u07d4-}\\@\u076f\xc4P\xb0Jt\xa4\u06bc+\xb5\xd6e\x00.\x89lk\x93[\x8b\xbd@\x00\x00\u07d4-\x89\xa8\x00jO\x13z \xdc+\xecF\xfe.\xb3\x12\xea\x96T\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4-\x8cR2\x9f8\u04a2\xfa\x9c\xba\xf5\u0143\xda\xf1I\v\xb1\x1c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4-\x8e\x06\x18\x92\xa5\xdc\xce!\x96j\xe1\xbb\a\x88\xfd>\x8b\xa0Y\x89\r\x8e\\\xe6\x17\xf2\xd5\x00\x00\u07d4-\x8e[\xb8\xd3R\x16\x95\xc7~|\x83N\x02\x91\xbf\xac\xeet\b\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4-\x90\xb4\x15\xa3\x8e.\x19\xcd\xd0/\U000ed069z\xf7\xcb\xf6r\x89\x05\xf3\xc7\xf6A1\xe4\x00\x00\u07d4-\x9b\xado\x1e\xe0*p\xf1\xf1=\xef\\\u0332z\x9a'@1\x89a\t=|,m8\x00\x00\u07d4-\x9c_\xec\u04b4O\xbbj\x1e\xc72\xea\x05\x9fO\x1f\x9d+\\\x896\xca2f\x1d\x1a\xa7\x00\x00\xe0\x94-\xa6\x17iP\t\xccW\xd2j\u0510\xb3*]\xfb\xeb\x93N^\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4-\xa7k|9\xb4 \u323a,\x10 \xb0\x85k\x02pd\x8a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4-\u01ddn\u007fU\xbc\xe2\xe2\xd0\xc0*\xd0|\uca3bR\x93T\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\xe0\x94-\xca\x0eD\x9a\xb6F\xdb\xdf\u04d3\xa9fb\x96\v\u02b5\xae\x1e\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4-\xd3%\xfd\xff\xb9{\x19\x99R\x84\xaf\xa5\xab\xdbWJ\x1d\xf1j\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4-\xd5x\xf7@}\xfb\xd5H\xd0^\x95\xcc\u00dcHT)bj\x89\u3bb5sr@\xa0\x00\x00\u07d4-\xd8\xee\xef\x87\x19J\xbc,\xe7X]\xa1\xe3[|\xeax\f\xb7\x8965\xc6 G9\u0640\x00\u07d4-\xdf@\x90Wi\xbc\xc4&\xcb,)8\xff\xe0w\xe1\u8758\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4-\xe0\x96D\x00\u0082\xbd\u05ca\x91\x9ck\xf7|k_yay\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94-\xe3\x1a\xfd\x18\x9a\x13\xa7o\xf6\xfes\xea\xd9\xf7K\xb5\u0126)\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4-\xec\x982\x9d\x1f\x96\u00e5\x9c\xaay\x81uTR\xd4\xdaI\u0549\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94-\ue422\x8f\x19-gj\x87s#+V\xf1\x8f#\x9e/\xad\x8a\x03\xef\xa7\xe7G\xb6\u046d\x00\x00\xe0\x94.\b\x80\xa3E\x96#\a \xf0Z\xc8\xf0e\xaf\x86\x81\u0736\u008a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4.\fW\xb4qP\xf9Z\xa6\xa7\xe1j\xb9\xb1\xcb\xf5C(\x97\x9a\x89\x05k\xc7^-c\x10\x00\x00\u07d4.\x10\x91\v\xa6\xe0\xbc\x17\xe0UUf\x14\u02c7\t\x0fM~[\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94.$\xb5\x97\x87;\xb1A\xbd\xb27\xea\x8aZ\xb7Gy\x9a\xf0-\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4.(\x10\xde\xe4J\xe4\xdf\xf3\xd8cB\xab\x12fW\xd6S\xc36\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4.,\xbdz\xd8%G\xb4\xf5\xff\x8b:\xb5o\x94*dE\xa3\xb0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4.-~\xa6k\x9fG\xd8\xccR\xc0\x1cR\xb6\u147c}G\x86\x89\xd8\xd4`,&\xbfl\x00\x00\u07d4.C\x93H\u07caBw\xb2*v\x84W\xd1\x15\x8e\x97\xc4\t\x04\x89*\x1e\x9f\xf2o\xbfA\x00\x00\xe0\x94.F\xfc\xeej;\xb1E\xb5\x94\xa2C\xa3\x91?\xce]\xado\xba\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u0794.G\xf2\x87\xf4\x98#7\x13\x85\r1&\x82<\xc6}\xce\xe2U\x88\u029d\x9e\xa5X\xb4\x00\x00\u07d4.N\u1b99j\xa0\xa1\xd9$(\xd0fR\xa6\xbe\xa6\xd2\xd1]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4.R\x91+\xc1\x0e\xa3\x9dT\xe2\x93\xf7\xae\u05b9\x9a\x0fLs\xbe\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4.a\x9fW\xab\xc1\u91ea\x93j\xe3\xa2&Ib\xe7\xeb-\x9a\x89(\xfb\x9b\x8a\x8aSP\x00\x00\u07d4.d\xa8\xd7\x11\x11\xa2/L]\xe1\xe09\xb36\xf6\x8d9\x8a|\x89lk\x93[\x8b\xbd@\x00\x00\u07d4.i3T=O,\xc0\vSP\xbd\x80h\xba\x92C\u05be\xb0\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94.~\x05\xe2\x9e\u0767\xe4\xae%\xc5\x175C\xef\xd7\x1fm=\x80\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4.\u007fFU \xec5\xcc#\u058eue\x1b\xb6h\x95D\xa1\x96\x898\xec[r\x1a\x1a&\x80\x00\u07d4.\x8e\xb3\nqn_\xe1\\t#>\x03\x9b\xfb\x11\x06\xe8\x1d\x12\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94.\x98$\xb5\xc12\x11\x1b\xca$\xdd\xfb\xa7\xe5u\xa5\xcdr\x96\xc1\x8a\x03\xa4\x84Qnm\u007f\xfe\x00\x00\u07d4.\xa5\xfe\xe6?3z7nK\x91\x8e\xa8!H\xf9MH\xa6&\x89e\x0f\x8e\r\u0493\xc5\x00\x00\u07d4.\xafN*F\xb7\x89\xcc\u0088\xc8\xd1\xd9)N?\xb0\x858\x96\x89lk\x93[\x8b\xbd@\x00\x00\u07d4.\xaf\xf9\xf8\xf8\x110d\u04d5z\xc6\xd6\xe1\x1e\xeeB\xc8\x19]\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4.\xba\fn\xe5\xa1\x14\\\x1cW9\x84\x96:`]\x88\nz \x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4.\xc9X\"\xeb\x88{\xc1\x13\xb4q*M\xfd\u007f\x13\xb0\x97\xb5\xe7\x8965\u026d\xc5\u07a0\x00\x00\u07d4.\xcaj<]\x9fD\x9d\tV\xbdC\xfa{M{\xe8CYX\x89lk\xdaip\x9c\xc2\x00\x00\xe0\x94.\xca\xc5\x04\xb23\x86n\xb5\xa4\xa9\x9e{\u0490\x13Y\xe4;=\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4.\xeb\xf5\x942\xb5(\x92\xf98\v\xd1@\xaa\x99\xdc\xf8\xad\f\x0f\x89\b=lz\xabc`\x00\x00\u07d4.\xee\xd5\x04q\xa1\xa2\xbfS\xee0\xb1#.n\x9d\x80\xef\x86m\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4.\xefk\x14\x17\u05f1\x0e\xcf\xc1\x9b\x12:\x8a\x89\xe7>RlX\x89 \x86\xac5\x10R`\x00\x00\u07d4.\xf8i\xf05\vW\xd54x\xd7\x01\xe3\xfe\xe5)\xbc\x91\x1cu\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4.\xf9\xe4eqj\xca\u03f8\xc8%/\xa8\xe7\xbcyi\xeb\xf6\u4255\x9e\xb1\xc0\xe4\xae \x00\x00\xe0\x94.\xfcLd}\xacj\xca\xc3Uw\xad\"\x17X\xfe\xf6ao\xaa\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4/\x13eu&\xb1w\xca\xd5G\u00d0\x8c\x84\x0e\xffd{E\u0649?v\x84\x9c\xf1\xee,\x80\x00\u07d4/\x18}ZpMZ3\x8c[(v\xa0\x90\xdc\xe9d(N)\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94/%#\u0303O\x00\x86\x05$\x02bb\x96gQ\x86\xa8\u508a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4/(*\xbb\xb6\u0523\xc3\xcd;\\\xa8\x12\xf7d>\x800_\x06\x89dI\xe8NG\xa8\xa8\x00\x00\u07d4/+\xba\x1b\x17\x96\x82\x1avo\xced\xb8O(\xech\xf1Z\xea\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4/1]\x90\x16\xe8\xee_Sf\x81 /\x90\x84\xb02TMM\x898<\xd1+\x9e\x86<\x00\x00\u07d4/M\xa7SC\x0f\xc0\x9es\xac\xbc\xcd\xcd\xe9\xdad\u007f+]7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4/P\x80\xb8?~-\xc0\xa1\xdd\x11\xb0\x92\xad\x04+\xffx\x8fL\x89\xb4\xf8\xfby#\x1d+\x80\x00\u07d4/a\uf941\x9dp_+\x1eN\xe7T\xae\xb8\xa8\x19Pju\x89O%\x91\xf8\x96\xa6P\x00\x00\xe0\x94/f\xbf\xbf\"b\xef\u030d+\xd0DO\u0170ib\x98\xff\x1e\x8a\x02\x1a\xd95\xf7\x9fv\xd0\x00\x00\u07d4/m\xce\x130\u015e\xf9!`!TW-MK\xac\xbd\x04\x8a\x8965\u026d\xc5\u07a0\x00\x00\u07d4/}2\x90\x85\x1b\xe5\u01b4\xb4?}Et2\x9fa\xa7\x92\u00c9\x05k\xc7^-c\x10\x00\x00\u07d4/\x858\x17\xaf\u04f8\xf3\xb8n\x9f`\xeew\xb5\xd9ws\xc0\xe3\x89N\xae\xeaD\xe3h\xb9\x00\x00\u07d4/\xa4\x91\xfbY \xa6WN\xbd(\x9f9\xc1\xb2C\r-\x9aj\x89lk\x93[\x8b\xbd@\x00\x00\u07d4/\xb5f\xc9K\xbb\xa4\xe3\xcbg\xcd\xda}_\xadq1S\x91\x02\x89lk\x93[\x8b\xbd@\x00\x00\u07d4/\xbbPJ]\xc5'\xd3\xe3\xeb\x00\x85\xe2\xfc<}\xd58\xcbz\x89C\u00b1\x8a\xec<\n\x80\x00\u07d4/\xbc\x85y\x8aX5\x98\xb5\"\x16mn\x9d\xda\x12\x1db}\xbc\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4/\xbc\xef3\x84\xd4 \xe4\xbfa\xa0f\x99\x90\xbcpT\U00065bc9lk\x93[\x8b\xbd@\x00\x00\xe0\x94/\xc8.\xf0v\x93#A&Oaz\f\x80\xddW\x1ej\xe99\x8a\x01\x84$\xf5\xf0\xb1\xb4\xe0\x00\x00\u07d4/\u075by\u07cd\xf50\xadc\xc2\x0eb\xafC\x1a\xe9\x92\x16\xb8\x89\x01#n\xfc\xbc\xbb4\x00\x00\u07d4/\xe0\x02?W\"e\x0f:\x8a\xc0\x10\t\x12^t\xe3\xf8.\x9b\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4/\xe0\xccBKS\xa3\x1f\t\x16\xbe\b\xec\x81\xc5\v\xf8\xea\xb0\xc1\x89 \x86\xac5\x10R`\x00\x00\u07d4/\xe1:\x8d\a\x85\u0787X\xa5\xe4\x18v\xc3n\x91l\xf7Pt\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4/\xea\x1b/\x83O\x02\xfcT3?\x8a\x80\x9f\x048\xe5\x87\n\xa9\x89\x01\x18T\xd0\xf9\xce\xe4\x00\x00\u07d4/\xee6\xa4\x9e\xe5\x0e\xcfqo\x10G\x91VFw\x9f\x8b\xa0?\x899B\"\xc4\u0686\xd7\x00\x00\u07d4/\xef\x81G\x8aK.\x80\x98\xdb_\xf3\x87\xba!S\xf4\xe2+y\x896'\xe8\xf7\x127<\x00\x00\u07d4/\xf1`\xc4Or\xa2\x99\xb5\xec-q\xe2\x8c\xe5Dm/\u02ef\x89\x13\x84\x00\xec\xa3d\xa0\x00\x00\u07d4/\xf1\xcaU\xfd\x9c\xec\x1b\x1f\xe9\U00029af7LQ<\x1e*\xaa\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94/\xf5\u02b1,\r\x95\u007f\xd33\xf3\x82\xee\xb7Q\a\xa6L\xb8\xe8\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94/\xf80\xcfU\xfb\x00\u0560\xe05\x14\xfe\xcdD1K\xd6\xd9\xf1\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4/\xfe\x93\xec\x1aV6\xe9\xee4\xafp\xdf\xf5&\x82\xe6\xffpy\x89lk\x93[\x8b\xbd@\x00\x00\u07d40\x03y\x88p&q\xac\xbe\x89,\x03\xfeW\x88\xaa\x98\xaf(z\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d40$\x8dX\xe4\x14\xb2\x0f\xed:lH+Y\xd9\xd8\xf5\xa4\xb7\xe2\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4019\xbcYd\x03\xd5\u04d3\x1fwLf\u013aFtT\u06c9\\%\xe1J\xea(?\x00\x00\u079408\x00\x87xie\x14\x9e\x81B;\x15\xe3\x13\xba2\xc5\u01c3\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d40:0\xacB\x86\xae\x17\xcfH=\xad{\x87\fk\xd6M{J\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d40?\xba\xeb\xbeF\xb3[n[t\x94j_\x99\xbc\x15\x85\xca\xe7\x89/\x9a\xc0i_[\xba\x00\x00\u07d40ADZ3\xba\x15\x87A\x16\r\x9c4N\xb8\x8e\\0o\x94\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d40H\x01d\xbc\xd8It\xeb\xc0\xd9\f\x9b\x9a\xfa\xb6&\xcd\x1cs\x89+^:\xf1k\x18\x80\x00\x00\u07d40N\u019atTW!\xd71j\xefM\u03f4\x1a\u015e\xe2\xf0\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x940Q\x182\x91\x8d\x804\xa7\xbe\xe7.\xf2\xbf\xeeD\x0e\u02fc\xf6\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d40Q?\u029f6\xfdx\x8c\xfe\xa7\xa3@\xe8m\xf9\x82\x94\xa2D\x89\x18;_\x03\xb1G\x9c\x00\x00\u07d40U\xef\xd2`)\xe0\xd1\x1b\x93\r\xf4\xf5;\x16,\x8c?\xd2\u0389\x1b\x1a\b\x927\a=\x00\x00\u07d40]&\xc1\v\xdc\x10?k\x9c!'.\xb7\xcb-\x91\b\xc4~\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d40_x\xd6\x18\xb9\x90\xb4)[\xac\x8a-\xfa&(\x84\xf8\x04\xea\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x940d\x89\x9a\x96\x1a>\x1d\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d40\x98\xb6]\xb9>\xca\xca\xf75\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d40\uc4d2$J!\b\u0247\xbc\\\xdd\xe0\ud7c3z\x81{\x89T\x99%\xf6\xc9\xc5%\x00\x00\xe0\x940\xed\x11\xb7{\xc1~^f\x94\u023c[nG\x98\xf6\x8d\x9c\xa7\x8a\x1eo\xb3B\x1f\xe0)\x9e\x00\x00\u07d40\xf7\xd0%\xd1o{\xee\x10U\x80Ho\x9fV\x1c{\xae?\xef\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x940\xfb\xe5\x88_\x9f\xcc\xe9\xea^\u06c2\xedJ\x11\x96\xdd%\x9a\xed\x8a\x01\x19\xe4\u007f!8\x1f@\x00\x00\u07d41\x04}p?c\xb94$\xfb\xbdn/\x1f\x9et\xde\x13\xe7\t\x89\x9a\x81f\xf7\u6ca7\x80\x00\u07d411?\xfdc[\xf2\xf32HA\xa8\x8c\a\xed\x14aD\xce\xeb\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d41Y\xe9\fH\xa9\x15\x90J\xdf\u24b2/\xa5\xfd^ryk\x896\xaf\xe9\x8f&\x06\x10\x00\x00\u07d41]\xb7C\x9f\xa1\u0574#\xaf\xa7\xddq\x98\xc1\xcft\xc9\x18\xbc\x89 \x86\xac5\x10R`\x00\x00\u07d41^\xf2\xdab\x0f\xd30\xd1.\xe5]\xe5\xf3)\xa6\x96\xe0\xa9h\x89\b!\xab\rD\x14\x98\x00\x00\u07d41n\x92\xa9\x1b\xbd\xa6\x8b\x9e/\x98\xb3\xc0H\x93N<\xc0\xb4\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d41n\xb4\xe4}\xf7\x1bB\xe1mo\xe4h%\xb72{\xaf1$\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d41q\x87~\x9d\x82\f\xc6\x18\xfc\t\x19\xb2\x9e\xfd3?\xdaI4\x8965\u026d\xc5\u07a0\x00\x00\u07d41|\xf4\xa2<\xb1\x91\xcd\xc5c\x12\u009d\x15\xe2\x10\xb3\xb9\xb7\x84\x89\a\xcef\xc5\x0e(@\x00\x00\u07d41\x8b.\xa5\xf0\xaa\xa8y\xc4\xd5\xe5H\xac\x9d\x92\xa0\xc6t\x87\xb7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d41\x8cv\xec\xfd\x8a\xf6\x8dpUSR\xe1\xf6\x01\xe3Y\x88\x04-\x89\x1b1\x19.h\xc7\xf0\x00\x00\u07d41\x8f\x1f\x8b\xd2 \xb0U\x8b\x95\xfb3\x10\x0f\xfd\xbbd\r|\xa6\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d41\xaa;\x1e\xbe\x8cM\xbc\xb6\xa7\b\xb1\xd7H1\xe6\x0eIv`\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d41\xab\b\x89f\xec\xc7\"\x92X\xf6\t\x8f\xceh\xcf9\xb3\x84\x85\x8965\u026d\xc5\u07a0\x00\x00\xe0\x941\xadM\x99F\xef\t\xd8\xe9\x88\xd9F\xb1\"\u007f\x91A\x90\x176\x8a\x04\xd8S\xc8\xf8\x90\x89\x80\x00\x00\xe0\x941\xb4;\x01]\x00\x81d~h\x00\x00\u07d424\x86\xcad\xb3uGO\xb2\xb7Y\xa9\xe7\xa15\x85\x9b\xd9\xf6\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d427I\xa3\xb9q\x95\x9eF\u0234\x82-\xca\xfa\xf7\xaa\xf9\xbdn\x89\x01\x16q\xa5\xb2Ep\x00\x00\u07d42:\xadA\xdfKo\xc8\xfe\u038c\x93\x95\x8a\xa9\x01\xfah\bC\x894\x95tD\xb8@\xe8\x00\x00\xe0\x942;<\xfe>\xe6+\xbd\xe2\xa2a\xe5<\xb3\xec\xc0X\x10\xf2\u018a\x02\ub3b1\xa1r\u0738\x00\x00\u07d42?\xca^\xd7\u007fi\x9f\x9d\x990\xf5\xce\xef\xf8\xe5oY\xf0<\x89Hz\x9a0E9D\x00\x00\u07d42H\\\x81\x87(\xc1\x97\xfe\xa4\x87\xfb\xb6\xe8)\x15\x9e\xba\x83p\x899!\xb4\x13\xbcN\xc0\x80\x00\xe0\x942P\xe3\xe8X\xc2j\xde\u032d\xf3jVc\xc2*\xa8LAp\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x942Y\xbd/\xdd\xfb\xbco\xba\u04f6\xe8t\xf0\xbb\xc0,\xda\x18\xb5\x8a\x02\x84`VI[\r\x18\x80\x00\u07d42uIo\xd4\u07491\xfdi\xfb\n\v\x04\xc4\xd1\xff\x87\x9e\xf5\x89\x18-~L\xfd\xa08\x00\x00\u07d42{\xb4\x9euOo\xb4\xf73\xc6\xe0o9\x89\xb4\xf6]K\xee\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d42\x82y\x1do\xd7\x13\xf1\xe9OK\xfdV^\xaax\xb3\xa0Y\x9d\x89Hz\x9a0E9D\x00\x00\u07d42\x83\xeb\u007f\x917\xdd9\xbe\xd5_\xfek\x8d\xc8E\xf3\xe1\xa0y\x89\x03\x97\n\xe9!Ux\x00\x00\u07d42\x86\t\x97\xd70\xb2\xd8;s$\x1a%\xd3f}Q\xc9\b\xef\x89\x1b\x1a\b\x927\a=\x00\x00\xe0\x942\x86\u047cez1,\x88G\xd9<\xb3\xcbyP\xf2\xb0\xc6\xe3\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x942\xa2\r\x02\x8e,b\x18\xb9\xd9[D\\w\x15$cj\"\xef\x8a\x02\x02\xfe\xfb\xf2\xd7\xc2\xf0\x00\x00\u07d42\xa7\x06\x91%\\\x9f\xc9y\x1aOu\u0238\x1f8\x8e\n%\x03\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d42\xb7\xfe\xeb\xc5\u015b\xf6^\x86\x1cL\v\xe4*v\x11\xa5T\x1a\x89w\u9aa8R\\\x10\x00\x00\xe0\x942\xba\x9a}\x04#\xe0:R_\xe2\xeb\xebf\x1d \x85w\x8b\u060a\x04<3\xc1\x93ud\x80\x00\x00\u07d42\xbb.\x96\x93\xe4\xe0\x854M/\r\xbdF\xa2\x83\u3807\xfd\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x942\xc2\xfd\u2daa\xbb\x80\u5ba2\xb9I\xa2\x17\xf3\xcb\t\"\x83\x8a\x010a`\xaf\xdf 7\x80\x00\u07d42\xd9P\xd5\xe9>\xa1\u0574\x8d\xb4qO\x86{\x03 \xb3\x1c\x0f\x897\b\xba\xed=h\x90\x00\x00\u07d42\u06f6qlT\xe81e\x82\x9aJ\xbb6uxI\xb6\xe4}\x8965\u026d\xc5\u07a0\x00\x00\u07d42\xebd\xbe\x1b]\xed\xe4\b\u01bd\xef\xben@\\\x16\xb7\xed\x02\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d42\xef\\\xdcg\x1d\xf5V*\x90\x1a\xee]\xb7\x16\xb9\xbev\xdc\xf6\x89lk\x93[\x8b\xbd@\x00\x00\u07d42\xf2\x9e\x87'\xa7LkC\x01\xe3\xff\xff\x06\x87\xc1\xb8p\xda\xe9\x8965\u026d\xc5\u07a0\x00\x00\u07d42\xfa\x0e\x86\xcd\b}\u058di1\x90\xf3-\x931\t\t\xedS\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d42\xfb\xee\xd6\xf6&\xfc\xdf\xd5\x1a\xca\xfbs\v\x9e\xef\xf6\x12\xf5d\x89lk\x93[\x8b\xbd@\x00\x00\u07943\x00\xfb\x14\x9a\xde\xd6[\u02e6\xc0N\x9c\u05b7\xa0;\x89;\xb1\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x943\x01\xd9\xca/;\xfe\x02by\xcdh\x19\xf7\x9a)=\x98\x15n\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\xe0\x943\b\xb04f\xc2z\x17\xdf\xe1\xaa\xfc\xeb\x81\xe1m)4Vo\x8a\x03\x99\x92d\x8a#\u0220\x00\x00\u07943\x1a\x1c&\xcci\x94\xcd\xd3\xc1K\xec\xe2v\xff\xffK\x9d\xf7|\x88\xfaz\xed\xdfO\x06\x80\x00\xe0\x943&\xb8\x8d\xe8\x06\x18DT\xc4\v'\xf3\t\xd9\xddm\u03f9x\x8a\x03\xca\\f\u067cD0\x00\x00\xe0\x943)\xeb;\xafCE\xd6\x00\xce\xd4\x0en\x99ueo\x117B\x8a\x01\x0f\b\xed\xa8\xe5U\t\x80\x00\u07d432\r\xd9\x0f+\xaa\x11\r\xd34\x87*\x99\x8f\x14\x84&E<\x8965f3\xeb\xd8\xea\x00\x00\u07d436\xc3\xefn\x8bP\xee\x90\xe07\xb1d\xb7\xa8\xea_\xaa\xc6]\x89\x0e\u0223\xa7\x1c\"T\x00\x00\xe0\x9438\fo\xffZ\xcd&Q0\x96)\u06daq\xbf? \u017a\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d43:\xd1Yd\x01\xe0Z\xea-6\xcaG1\x8e\xf4\xcd,\xb3\u07c9\x9d\xc0\\\xce(\u00b8\x00\x00\u07d43C@\xeeK\x9c\u0701\xf8P\xa7Q\x16\xd5\x0e\u9d98%\xbf\x89lk\x93[\x8b\xbd@\x00\x00\u07d43H\x1e\x85n\xbe\u050e\xa7\b\xa2t&\xef(\xe8g\xf5|\u0449\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x943V[\xa9\xda,\x03\xe7x\xce\x12)O\b\x1d\xfe\x81\x06M$\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07943X\x1c\xee#0\x88\xc0\x86\r\x94N\f\xf1\u03ab\xb8&\x1c.\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d43XX\xf7I\xf1i\u02bc\xfeR\xb7\x96\xe3\xc1\x1e\xc4~\xa3\u0089\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x943^\"\x02[zw\u00e0t\u01cb\x8e=\xfe\a\x13A\x94n\x8a\x02'\xcas\n\xb3\xf6\xac\x00\x00\u07d43b\x9b\xd5/\x0e\x10{\xc0q\x17ld\xdf\x10\x8fdw}I\x89\x01\xcf\xddth!n\x80\x00\u07d43{;\u07c6\xd7\x13\xdb\xd0{]\xbf\xcc\x02+z{\x19F\xae\x89\xd7\xc1\x98q\x0ef\xb0\x00\x00\u07d43|\xfe\x11W\xa5\u0191 \x10\xddV\x153y\x17i\u00b6\xa6\x8965\u026d\xc5\u07a0\x00\x00\u07d43\xb36\xf5\xba^\xdb{\x1c\xcc~\xb1\xa0\u0644\xc1#\x1d\x0e\u0709lk\x93[\x8b\xbd@\x00\x00\u07d43\xc4\a\x13;\x84\xb3\xcaL=\xed\x1fFX\x90\f8\x10\x16$\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\xe0\x943\xd1r\xab\a\\Q\xdb\x1c\xd4\n\x8c\xa8\xdb\xff\r\x93\xb8C\xbb\x8a\x016x\x05\x10\xd1-\xe3\x80\x00\u07d43\xe9\xb7\x18#\x95.\x1ff\x95\x8c'\x8f\u008b\x11\x96\xa6\u0164\x89\x05k\xc7^-c\x10\x00\x00\u07d43\xeakxU\xe0[\a\xab\x80\u06b1\xe1M\xe9\xb6I\xe9\x9bl\x89\x1c\xd6\xfb\xadW\xdb\xd0\x00\x00\u07d43\xf1R#1\rD\u078bf6h_:L=\x9cVU\xa5\x89\r\x94b\xc6\xcbKZ\x00\x00\u07d43\xf4\xa6G\x1e\xb1\xbc\xa6\xa9\xf8[;Hr\xe1\aU\xc8+\xe1\x89lk\x93[\x8b\xbd@\x00\x00\u07d43\xfbWzM!O\xe0\x10\xd3,\xca|>\xed\xa6?\x87\xce\xef\x8965\u026d\xc5\u07a0\x00\x00\u07d43\xfdq\x8f\v\x91\xb5\xce\u020a]\xc1^\xec\xf0\xec\xef\xa4\xef=\x89\x17r$\xaa\x84Lr\x00\x00\u07d44\x14\x80\u030c\xb4v\xf8\xd0\x1f\xf3\b\x12\xe7\xc7\x0e\x05\xaf\xaf]\x89lk\x93[\x8b\xbd@\x00\x00\u07d44'-^ut1]\xca\u9afd1{\xac\x90(\x9dGe\x89b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x9440\xa1c\x81\xf8i\xf6\xeaT#\x91XU\xe8\x00\x885%\xa9\x8a\x03\xca\\f\u067cD0\x00\x00\u07d441\x86%\x81\x8e\xc1?\x11\x83Z\xe9sS\xce7}oY\n\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d449<]\x91\xb9\xdeYr\x03\xe7[\xacC\t\xb5\xfa=(\u00c9\n\x84Jt$\xd9\xc8\x00\x00\u07d449\x99\x8b$|\xb4\xbf\x8b\xc8\nm+5'\xf1\xdf\xe9\xa6\u0489\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d44C}\x14ed\v\x13l\xb5\x84\x1c?\x93O\x9b\xa0\xb7\t}\x89\t`\xdbwh\x1e\x94\x00\x00\u07d44J\x8d\xb0\x86\xfa\xedN\xfc7\x13\x1b:\"\xb0x-\xadp\x95\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x944fM\"\x0f\xa7\xf3yX\x02J32\u0584\xbc\xc6\xd4\u023d\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d44f\xf6~9cl\x01\xf4;:!\xa0\xe8R\x93%\xc0\x86$\x89-\xb1\x16vP\xac\xd8\x00\x00\u07d44\x856\x1e\xe6\xbf\x06\xefe\b\xcc\xd2=\x94d\x1f\x81M>/\x89lk\x93[\x8b\xbd@\x00\x00\u07d44\x85\xf6!%d3\xb9\x8aB\x00\xda\xd8W\xef\xe5Y7\uc609lk\x93[\x8b\xbd@\x00\x00\u07d44\x95\x8aF\xd3\x0e0\xb2s\xec\xc6\xe5\xd3X\xa2\x12\xe50~\x8c\x89lk\x93[\x8b\xbd@\x00\x00\u07d44\x97\xddf\xfd\x11\x80q\xa7\x8c,\xb3n@\xb6e\x1c\xc8%\x98\x89\x05\xf1\x01kPv\xd0\x00\x00\xe0\x944\x9a\x81k\x17\xab='\xbb\xc0\xae\x00Q\xf6\xa0p\xbe\x1f\xf2\x9d\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d44\x9d,\x91\x8f\u041e(\a1\x8ef\xceC)\t\x17k\xd5\v\x89<\xb7\x1fQ\xfcU\x80\x00\x00\u07d44\xa0C\x1f\xff^\xad\x92\u007f\xb6`\f\x1e\xa8\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d44\xff&\xeb`\xa8\u0469ZH\x9f\xae\x13n\xe9\x1dNX\bL\x89 \x86\xac5\x10R`\x00\x00\u07d44\xffX)R\xff$E\x8f{\x13\xd5\x1f\vO\x98p\"\xc1\xfe\x89\x98\x06\xde=\xa6\xe9x\x00\x00\u07d45\x10k\xa9N\x85c\u0533\xcb<\\i,\x10\xe6\x04\xb7\xce\u0609lk\x93[\x8b\xbd@\x00\x00\xe0\x945\x14_b\x03\x97\u019c\xb8\xe0\tb\x96\x1f\x0fH\x86d9\x89\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d45\x14t0\xc3\x10e\x00\u77e2\xf5\x02F.\x94p<#\xb1\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x945\x17\x87\x845\x05\xf8\xe4\xef\xf4ef\xcc\u695fM\x1c_\xe7\x8a\x01\xf5q\x89\x87fKH\x00\x00\xe0\x945\x1f\x16\xe5\xe0sZ\xf5gQ\xb0\xe2%\xb2B\x11q9@\x90\x8a\x02\xd4\xca\x05\xe2\xb4<\xa8\x00\x00\xe0\x945$\xa0\x00#N\xba\xaf\a\x89\xa14\xa2\xa4\x178<\xe5(*\x8a\x011yU\x94}\x8e,\x00\x00\u07d45&\xee\xce\x1ak\xdc>\xe7\xb4\x00\xfe\x93[HF?1\xbe\u05c9\x04w\x87\x9bm\x140\x00\x00\u07d45*x_J\x92\x162PL\xe5\xd0\x15\xf8\xd7FO\xa3\xdb\x14\xe7r\x92\x13\u03aa7\x8c\t^\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d45\xaf\x04\n\f\xc23zv\xaf(\x81T\xc7V\x1e\x1a#3I\x8965\u026d\xc5\u07a0\x00\x00\u07d45\xb0>\xa4$W6\xf5{\x85\xd2\xebyb\x8f\x03m\xdc\xd7\x05\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d45\xbd$he\xfa\xb4\x90\xac\bz\xc1\xf1\xd4\xf2\xc1\r\f\xda\x03\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x945\xbff\x88R/5Fz\u007fu0#\x14\xc0+\xa1v\x80\x0e\x8a\x03\xafA\x82\x02\xd9T\xe0\x00\x00\u07d45\u022d\xc1\x11%C+;w\xac\xd6F%\xfeX\xeb\xee\x9df\x89lk\x93[\x8b\xbd@\x00\x00\u07d45\u0497\x0fI\xdc\xc8\x1e\xa9\xeep~\x9c\x8a\n\xb2\xa8\xbbtc\x89N\x10\x03\xb2\x8d\x92\x80\x00\x00\u07d45\xe0\x96\x12\r\xea\xa5\xc1\xec\xb1d^,\u02cbN\xdb\xd9)\x9a\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d45\xea!c\xa3\x8c\u07da\x12?\x82\xa5\xec\x00%\x8d\xae\v\xc7g\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d45\xf1\xda\x12{\x837o\x1b\x88\xc8*3Y\xf6z^g\xddP\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d45\xf2\x94\x9c\xf7\x8b\xc2\x19\xbbO\x01\x90|\xf3\xb4\xb3\u04c6T\x82\x89\x0f\xb5\xc8l\x92\xe44\x00\x00\u07d45\xf5\x86\x01I\xe4\xbb\xc0K\x8a\u0172r\xbeU\xad\x1a\xcaX\xe0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d46\x02E\x8d\xa8omj\x9d\x9e\xb0=\xaf\x97\xfeV\x19\xd4B\xfa\x89lk\x93[\x8b\xbd@\x00\x00\u07d46\x057-\x93\xa9\x01\t\x88\x01\x8f\x9f1]\x03.\u0448\x0f\xa1\x89\x1b\x1b\xcfQ\x89j}\x00\x00\u07d46\x16\xd4H\x98_]2\xae\xfa\x8b\x93\xa9\x93\xe0\x94\xbd\x85I\x86\x89\v\"\u007fc\xbe\x81<\x00\x00\u07d46\x16\xfbF\xc8\x15x\xc9\xc8\xebM;\xf8\x80E\x1a\x887\x9d}\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d46\x1cu\x93\x16\x96\xbc=B}\x93\xe7lw\xfd\x13\xb2A\xf6\xf4\x89\x1d\xc5\xd8\xfc&m\xd6\x00\x00\u07d46\x1d\x9e\xd8\v[\xd2|\xf9\xf1\"o&u2X\xee_\x9b?\x89\xbfi\x14\xba}r\xc2\x00\x00\u07d46\x1f;\xa9\xed\x95kw\x0f%}6r\xfe\x1f\xf9\xf7\xb0$\f\x89 \x86\xac5\x10R`\x00\x00\u07d46\"|\u07e0\xfd;\x9d~jtF\x85\xf5\xbe\x9a\xa3f\xa7\xf0\x89\n\xc2s\x0e\xe9\xc6\xc1\x80\x00\u07d46/\xbc\xb1\x06b7\n\x06\x8f\xc2e&\x02\xa2Wy7\xcc\xe6\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d460\xc5\xe5e\u03aa\x8a\x0f\x0f\xfe2\x87^\xae*l\xe6<\x19\x89\t7r+7t\xd0\x00\x00\u07d463\x9f\x84\xa5\u00b4L\xe5=\xfd\xb6\xd4\xf9}\xf7\x82\x12\xa7\u07c9\x11o\x18\xb8\x17\x15\xa0\x00\x00\u07d464:\xec\xa0{n\u054a\x0eb\xfaN\xcbI\x8a\x12O\xc9q\x89\x10CV\x1a\x88)0\x00\x00\u07d46au@4\x81\xe0\xab\x15\xbbQF\x15\u02f9\x89\xeb\u018f\x82\x89lk\x93[\x8b\xbd@\x00\x00\u07d46ro;\x88Z$\xf9)\x96\u0681b^\u022d\x16\xd8\xcb\xe6\x89S\xafu\u0441HW\x80\x00\xe0\x946s\x95C\x99\xf6\u07feg\x18\x18%\x9b\xb2x\xe2\xe9.\xe3\x15\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d46u\x8e\x04\x9c\u064b\u03a1\"w\xa6v\xf9)sb\x89\x00#\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d46\u007fY\u0302yS)8NA\xe1(1\x15\xe7\x91\xf2j\x01\x89lk\x93[\x8b\xbd@\x00\x00\u07d46\x81\x0f\xf9\xd2\x13\xa2q\xed\xa2\xb8\xaay\x8b\xe6T\xfaK\xbe\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d46\x8cT\x14\xb5k\x84U\x17\x1f\xbf\ab \xc1\u02e4\xb5\xca1\x89\x1e>\xf9\x11\xe8=r\x00\x00\xe0\x946\x90$k\xa3\xc8\x06y\xe2.\xacD\x12\xa1\xae\xfc\xe6\xd7\u0342\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d46\x92\x8bU\xbc\x86\x15\t\xd5\x1c\x8c\xf1\xd5F\xbf\xecn>\x90\xaf\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d46\x98\"\xf5W\x8b@\xdd\x1fDqpk\"\u0357\x13R\xdak\x89\x12\xc1\xb6\xee\xd0=(\x00\x00\u07d46\x9e\xf7a\x19_:7>$\xec\xe6\xcd\"R\x0f\xe0\xb9\xe8n\x89\x1c\xff\xaf\xc9M\xb2\b\x80\x00\u07d46\xa0\x8f\xd6\xfd\x1a\xc1|\xe1^\xd5~\xef\xb1*+\u2048\xbf\x89Hz\x9a0E9D\x00\x00\u07d46\xa0\xe6\x1e\x1b\xe4\u007f\xa8~0\xd3(\x88\xee\x030\x90\x1c\xa9\x91\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x946\xb2\xc8^:\xee\xeb\xb7\rc\u0124s\f\xe2\xe8\xe8\x8a6$\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x946\xbfC\xff5\u07d0\x90\x88$3l\x9b1\xce3\x06~/P\x8aIr\x15\x10\xc1\xc1\xe9H\x00\x00\u07d46\xbf\xe1\xfa;{p\xc1r\xeb\x04/h\x19\xa8\x97%\x95A>\x8965\u026d\xc5\u07a0\x00\x00\xe0\x946\xc5\x10\xbf\x8dnV\x9b\xf2\xf3}G&]\xbc\xb5\x02\xff+\u038a\x06ZM\xa2]0\x16\xc0\x00\x00\xe0\x946\xd8]\xc3h1V\xe6;\xf8\x80\xa9\xfa\xb7x\x8c\xf8\x14:'\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d46\u07cf\x88<\x12s\xec\x8a\x17\x1fz3\xcf\xd6I\xb1\xfe`u\x89\fRHJ\xc4\x16\x89\x00\x00\xe0\x946\xe1Va\f\xd8\xffd\xe7\x80\u061d\x00T8\\\xa7gU\xaa\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d46\xfe\xc6,,B^!\x9b\x18D\x8a\xd7W\x00\x9d\x8cT\x02o\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d47\x00\xe3\x02t$\xd99\xdb\xde]B\xfbx\xf6\xc4\xdb\xec\x1a\x8f\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d47\x02\xe7\x04\xcc!at9\xadN\xa2zW\x14\xf2\xfd\xa1\xe92\x8965\u026d\xc5\u07a0\x00\x00\u07d47\x035\fMo\xe374,\xdd\xc6[\xf1\xe28k\xf3\xf9\xb2\x89m\x81!\xa1\x94\xd1\x10\x00\x00\xe0\x947\b\xe5\x9d\xe6\xb4\x05P\x88x)\x02\xe0W\x9cr\x01\xa8\xbfP\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d47\x126~^U\xa9mZ\x19\x16\x8fn\xb2\xbc~\x99q\xf8i\x8965\u026d\xc5\u07a0\x00\x00\u07d47\x19Zc]\xccb\xf5jq\x80I\xd4~\x8f\x9f\x96\x83(\x91\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d47'4\x1f&\xc1 \x01\xe3x@^\xe3\x8b-\x84d\xecq@\x89lk\x93[\x8b\xbd@\x00\x00\u07d47.E:kb\x9f'g\x8c\u022e\xb5\xe5|\xe8^\xc0\xae\xf9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d474\xcb\x18t\x91\xed\xe7\x13\xae[;-\x12(J\xf4k\x81\x01\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d477!n\xe9\x1f\x17w2\xfbX\xfa@\x97&r\a\xe2\xcfU\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d47M;\xbb\x057Q\xf9\xf6\x8d\xdb\a\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d48r\xf4\x8d\xc5\xe3\xf8\x17\xbck*\xd2\xd00\xfc^\x04q\x19=\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d48~\xea\xfdk@\t\u07af\x8b\u0578Zr\x98:\x8d\xcc4\x87\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d48\x81\xde\xfa\xe1\xc0{<\xe0Lx\xab\xe2k\f\u070ds\xf0\x10\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d48\x83\xbe\xcc\b\xb9\xbeh\xad;\b6\xaa\u00f6 \xdc\x00\x17\xef\x89lk\x93[\x8b\xbd@\x00\x00\u07d48\x85\xfe\xe6q\a\xdc:\xa9\x8a\x1d\x99:t\xdf\\\xd7T\xb9\x8dR\x9a\x89a\t=|,m8\x00\x00\u07d48\xe4m\xe4E<8\xe9A\xe7\x93\x0fC0O\x94\xbb{+\xe8\x89l\xb7\xe7Hg\xd5\xe6\x00\x00\u07d48\xe7\u06e8\xfdO\x1f\x85\r\xbc&I\xd8\xe8O\tR\xe3\xeb<\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d48\xe8\xa3\x1a\xf2\xd2e\xe3\x1a\x9f\xff-\x8fF(m\x12E\xa4g\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d48\xeao[Z{\x88AuQ\xb4\x12=\xc1'\xdf\xe94-\xa6\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d48\xee\xc6\xe2\x17\xf4\xd4\x1a\xa9 \xe4$\xb9RQ\x97\x04\x1c\xd4\u0189\xf0\r%\xeb\x92.g\x00\x00\xe0\x948\xf3\x87\xe1\xa4\xedJs\x10n\xf2\xb4b\xe4t\xe2\xe3\x14:\u040a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d49\x11a\xb0\xe4<0 f\u898d,\xe7\xe1\x99\xec\xdb\x1dW\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x949\x15\uad6b.Yw\xd0u\xde\xc4}\x96\xb6\x8bK\\\xf5\x15\x8a\r\a\x01\x81\x85\x12\x0f@\x00\x00\u07d49\x1aw@\\\t\xa7+^\x846#z\xaa\xf9]h\xda\x17\t\x89\x02\xa9&J\xf3\u0479\x00\x00\u07d49\x1f \x17m\x126\rrMQG\n\x90p6uYJM\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d49$3\xd2\u0383\xd3\xfbJv\x02\u0323\xfa\xcaN\xc1@\xa4\xb0\x89\x02\xc3\xc4e\xcaX\xec\x00\x00\xe0\x949?x;\\\u06c6\"\x1b\xf0)O\xb7\x14\x95\x9c{E\x89\x9c\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d49?\xf4%^\\e\x8f.\u007f\x10\xec\xbd)%rg\x1b\xc2\u0489lk\x93[\x8b\xbd@\x00\x00\u07d49A2`\x0fAU\xe0\u007fME\xbc>\xb8\xd9\xfbr\xdc\u05c4\x89\x9fn\x92\xed\xea\a\xd4\x00\x00\u07d49Q\xe4\x8e<\x86\x9ekr\xa1C\xb6\xa4Ph\u0379\xd4f\u0409\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x949T\xbd\xfe\v\xf5\x87\u0195\xa3\x05\xd9$L=[\xdd\xda\u027b\x8a\x04\x10'\x83'\xf9\x85`\x80\x00\u07d49]m%U \xa8\xdb)\xab\xc4}\x83\xa5\u06ca\x1a}\xf0\x87\x89\x05k\xc7^-c\x10\x00\x00\u07d49ck%\x81\x1b\x17j\xbf\xcf\xee\xcad\xbc\x87E/\x1f\xdf\xf4\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d49i\xb4\xf7\x1b\xb8u\x1e\xdeC\xc0\x166:zaOv\x11\x8e\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x949x/\xfe\x06\xacx\x82*<:\x8a\xfe0^P\xa5a\x88\u038a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d49zn\xf8v:\x18\xf0\x0f\xac!~\x05\\\r0\x94\x10\x10\x11\x89lk\x93[\x8b\xbd@\x00\x00\u07d49|\u06cc\x80\xc6yP\xb1\x8deB)a\x0e\x93\xbf\xa6\xee\x1a\x89?\x95\xc8\xe0\x82\x15!\x00\x00\u07d49\x82O\x8b\xce\xd1v\xfd>\xa2.\u01a4\x93\xd0\xcc\xc3?\xc1G\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d49\x93l'\x19E\v\x94 \xcc%\"\u03d1\xdb\x01\xf2'\xc1\xc1\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d49\x95\xe0\x96\xb0\x8aZrh\x00\xfc\xd1}\x9cd\xc6N\b\x8d+\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d49\x9a\xa6\xf5\xd0x\xcb\tp\x88+\u0259 \x06\xf8\xfb\xdf4q\x8965\u026d\xc5\u07a0\x00\x00\u07d49\xaa\x05\xe5m}28T!\u03d36\xe9\r=\x15\xa9\xf8Y\x89\x01h\u048e?\x00(\x00\x00\u07d49\xaa\xf0\x85M\xb6\xeb9\xbc{.C\x84jv\x17\x1c\x04E\u0789dI\xe8NG\xa8\xa8\x00\x00\u07d49\xb1\xc4q\xae\x94\xe1!dE.\x81\x1f\xbb\xe2\xb3\xcdru\xac\x89lk\x93[\x8b\xbd@\x00\x00\u07d49\xb2\x992t\x90\xd7/\x9a\x9e\xdf\xf1\x1b\x83\xaf\xd0\xe9\xd3\xc4P\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d49\xba\u018d\x94xY\xf5\x9e\x92&\b\x9c\x96\xd6.\x9f\xbe<\u0789\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x949\xbf\xd9xh\x9b\xec\x04\x8f\xc7v\xaa\x15$\u007f^\x1d|9\xa2\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d49\xc7s6|\x88%\xd3YlhoB\xbf\r\x141\x9e?\x84\x89\a?u\u0460\x85\xba\x00\x00\u07d49\u05291@,\fy\xc4W\x18o$\u07c7)\u03d5p1\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d49\xd6\xca\xca\"\xbc\xcdjr\xf8~\xe7\u05b5\x9e\v\xde!\xd7\x19\x89l\x87T\xc8\xf3\f\b\x00\x00\u07d49\xe0\xdbM`V\x8c\x80\v\x8cU\x00\x02l%\x94\xf5v\x89`\x8965\u026d\xc5\u07a0\x00\x00\xe0\x949\xeeO\xe0\x0f\xbc\xeddph\xd4\xf5|\x01\xcb\"\xa8\v\xcc\u044a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d49\xf1\x983\x1eK!\xc1\xb7`\xa3\x15_J\xb2\xfe\x00\xa7F\x19\x89lk\x93[\x8b\xbd@\x00\x00\u07d49\xf4Fc\xd9%a\t\x1b\x82\xa7\r\xcfY=u@\x05\x97:\x89\n\u05cb.\xdc!Y\x80\x00\u07d4:\x03U\x94\xc7GGmB\xd1\xee\x96l6\"L\xdd\"I\x93\x89\x13J\xf7Ei\xf9\xc5\x00\x00\u07d4:\x04W(G\xd3\x1e\x81\xf7v\\\xa5\xbf\xc9\xd5W\x15\x9f6\x83\x89\a6-\r\xab\xea\xfd\x80\x00\xe0\x94:\x06\xe3\xbb\x1e\xdc\xfd\fD\xc3\aM\xe0\xbb`k\x04\x98\x94\xa2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u0794:\x10\x88\x8b~\x14\x9c\xae',\x010,2}\n\xf0\x1a\v$\x88\xeb\xec!\xee\x1d\xa4\x00\x00\u07d4:1\b\xc1\u6023;3l!\x13\x134@\x9d\x97\xe5\xad\xec\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4:6\x8e\xfeJ\u05c6\xe2c\x95\xec\x9f\u01adi\x8c\xae)\xfe\x01\x89\"E\x89\x96u\xf9\xf4\x00\x00\u07d4:=\xd1\x04\xcd~\xb0O!\x93/\xd43\xeaz\xff\u04d3i\xf5\x89\x13aO#\xe2B&\x00\x00\u07d4:B\x97\xda\xc4.\x1eO\xb8\xcb1\xec\xddC\xaew<\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94:\x99`&m\xf6I cS\x8a\x99\xf4\x87\xc9P\xa3\xa5\uc78a\x05\x15\n\xe8J\x8c\xdf\x00\x00\x00\u07d4:\x9b\x11\x10)\xce\x1f \xc9\x10\x9czt\xee\xee\xf3OO.\xb2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4:\x9eTA\xd4K$;\xe5[u\x02z\x1c\ub7ac\xf5\r\xf2\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94:\xa0z4\xa1\xaf\u0216}=\x13\x83\xb9kb\u03d6\xd5\xfa\x90\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94:\xa4,!\xb9\xb3\x1c>'\xcc\xd1~\t\x9a\xf6y\xcd\xf5i\a\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4:\xa9H\xea\x029wU\xef\xfb/\x9d\xc99-\xf1\x05\x8f~3\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\u07d4:\xad\xf9\x8ba\xe5\u0216\xe7\xd1\x00\xa39\x1d2P\"]a\u07c9\f\xafg\x007\x01h\x00\x00\u07d4:\xaeHr\xfd\x90\x93\xcb\xca\xd1@o\x1e\x80x\xba\xb5\x03Y\xe2\x89\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4:\xbb\x8a\xdf\xc6\x04\xf4\x8dY\x84\x81\x1d\u007f\x1dR\xfe\xf6u\x82p\x89\xf2\x97\x19\xb6o\x11\f\x00\x00\u07d4:\xc2\xf0\xff\x16\x12\xe4\xa1\xc3F\xd53\x82\xab\xf6\u0622[\xaaS\x89lk\x93[\x8b\xbd@\x00\x00\u07d4:\xc9\xdczCj\xe9\x8f\xd0\x1cz\x96!\xaa\x8e\x9d\v\x8bS\x1d\x89a\t=|,m8\x00\x00\xe0\x94:\xd0aI\xb2\x1cU\xff\x86|\xc3\xfb\x97@\u04bc\xc7\x10\x121\x8a)\xb7d2\xb9DQ \x00\x00\u07d4:\xd7\x02C\u060b\xf0@\x0fW\xc8\xc1\xfdW\x81\x18H\xaf\x16*\x89.\x9e\xe5\u00c6S\xf0\x00\x00\u07d4:\xd9\x15\xd5P\xb7#AV \xf5\xa9\xb5\xb8\x8a\x85\xf3\x82\xf05\x8965\u026d\xc5\u07a0\x00\x00\u07d4:\xe1`\xe3\xcd`\xae1\xb9\xd6t-h\xe1Nv\xbd\x96\xc5\x17\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4:\xe6+\xd2q\xa7`c\u007f\xady\xc3\x1c\x94\xffb\xb4\xcd\x12\xf7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4:\xeaN\x82\xd2@\x02H\xf9\x98q\xa4\x1c\xa2W\x06\r:\"\x1b\x8965\u026d\xc5\u07a0\x00\x00\u07d4:\xf6[>(\x89ZJ\x00\x11S9\x1d\x1ei\xc3\x1f\xb9\xdb9\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4;\a\xdbZ5\u007fZ\xf2HL\xbc\x9dw\xd7;\x1f\xd0Q\x9f\u01c9\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4;\n\u032fK`|\xfea\xd1s4\xc2\x14\xb7\\\xde\xfd\xbd\x89\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;\x13c\x1a\x1b\x89\xcbVeH\x89\x9a\x1d`\x91\\\xdc\xc4 [\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;\x15\x90\x99\aR\a\u0180vc\xb1\xf0\xf7\xed\xa5J\xc8\xcc\xe3\x89j\xc4\xe6[i\xf9-\x80\x00\u07d4;\x197\xd5\u74f8\x9bc\xfb\x8e\xb5\xf1\xb1\xc9\xcak\xa0\xfa\x8e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;\"\xda*\x02q\xc8\xef\xe1\x02S'scji\xb1\xc1~\t\x89\x1b6\xa6DJ>\x18\x00\x00\u07d4;\"\u07a3\xc2_\x1bY\u01fd'\xbb\x91\u04e3\xea\xec\xef9\x84\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94;#g\xf8IK_\xe1\x8dh<\x05]\x89\x99\x9c\x9f=\x1b4\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4;,E\x99\x0e!GDQ\xcfOY\xf0\x19U\xb31\xc7\xd7\u0249lk\x93[\x8b\xbd@\x00\x00\xe0\x94;A\x00\xe3\ns\xb0\xc74\xb1\x8f\xfa\x84&\u045b\x191/\x1a\x8a\v\xb5\u046ap\n\xfd\x90\x00\x00\u07d4;B\xa6m\x97\x9fX(4tz\x8b`B\x8e\x9bN\xec\xcd#\x89!\xa1\u01d0\xfa\xdcX\x00\x00\u07d4;Gh\xfdq\xe2\xdb,\xbe\u007f\xa0PH<'\xb4\xeb\x93\x1d\xf3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;Vj\x8a\xfa\u0456\x82\xdc,\xe8g\x9a<\xe4D\xa5\xb0\xfdO\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94;\\%\x1d\u007f\u05c9;\xa2\t\xfeT\x1c\xec\xd0\xce%:\x99\r\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4;^\x8b\x17w\xca\x18A\x896\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94;\x93\xb1a6\xf1\x1e\xaf\x10\x99l\x95\x99\r;'9\xcc\xea_\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4;\xabK\x01\xa7\xc8K\xa1?\uea70\xbb\x19\x1bw\xa3\xaa\u0723\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4;\xb55\x98\xcc \xe2\x05]\xc5S\xb0I@J\u0277\xdd\x1e\x83\x89!W\x1d\xf7|\x00\xbe\x00\x00\u07d4;\xbc\x13\xd0J\xcc\xc0pz\xeb\u072e\xf0\x87\u0438~\v^\u327e\xd1\xd0&=\x9f\x00\x00\x00\u07d4;\xc6\xe3\xeezV\u038f\x14\xa3u2Y\x0fcqk\x99f\xe8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;\xc8]ls[\x9c\xdaK\xba_H\xb2K\x13\xe7\x0600{\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4;\xd6$\xb5H\xcbe\x976\x90~\u062a<\fp^$\xb5u\x89lk\x93[\x8b\xbd@\x00\x00\u07d4;\u0660m\x1b\xd3lN\xdd'\xfc\r\x1f[\b\x8d\xda\xe3\xc7*\x89\x1b\x1azB\v\xa0\r\x00\x00\u0794;\u077c\x814\xf7}UY\u007f\xc9|&\xd2f\x98\t\x06\x04\ub23e -j\x0e\xda\x00\x00\xe0\x94;\xf8n\u0623\x15>\xc93xj\x02\xac\t\x03\x01\x85^Wk\x8a_J\x8c\x83u\xd1U@\x00\x00\u07d4;\xfb\u04c4|\x17\xa6\x1c\xf3\xf1{R\xf8\ub879`\xb3\U000df262\xa1]\tQ\x9b\xe0\x00\x00\u07d4<\x03\xbb\xc0#\xe1\xe9?\xa3\xa3\xa6\xe4(\xcf\f\xd8\xf9^\x1e\u0189Rf<\u02b1\xe1\xc0\x00\x00\u07d4<\f=\ufb1c\xeaz\xcc1\x9a\x96\xc3\v\x8e\x1f\xed\xabEt\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4<\x15\xb3Q\x1d\xf6\xf04.sH\u0309\xaf9\xa1h\xb7s\x0f\x8965\u026d\xc5\u07a0\x00\x00\u07d4<\x1f\x91\xf3\x01\xf4\xb5e\xbc\xa2GQ\xaa\x1fv\x13\"p\x9d\u0749a\t=|,m8\x00\x00\xe0\x94<(l\xfb0\x14n_\u05d0\xc2\xc8T\x15RW\x8d\xe34\u060a\x02)\x1b\x11\xaa0n\x8c\x00\x00\u07d4<2.a\x1f\u06c2\rG\xc6\xf8\xfcd\xb6\xfa\xd7L\xa9_^\x89\r%\x8e\xce\x1b\x13\x15\x00\x00\u07d4\xa5\xe5\xbfb\xbb\u0309\x05V\xf6L\x1f\xe7\xfa\x00\x00\u07d4<\x86\x9c\tie#\xce\xd8$\xa0pAF\x05\xbbv#\x1f\xf2\x8965\u026d\xc5\u07a0\x00\x00\u07d4<\x92V\x19\u02731DF?\x057\u06165\x87\x06\xc5 \xb0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4<\x98YK\xf6\x8bW5\x1e\x88\x14\xae\x9em\xfd-%J\xa0o\x89\x10CV\x1a\x88)0\x00\x00\u07d4<\xad\xeb=>\xed?b1\x1dRU>p\xdfJ\xfc\xe5o#\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94<\xae\xdbS\x19\xfe\x80eC\xc5nP!\xd3r\xf7\x1b\xe9\x06.\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4<\xaf\xaf^bPV\x15\x06\x8a\xf8\xeb\"\xa1:\u0629\xe5Pp\x89lf\x06E\xaaG\x18\x00\x00\u07d4<\xb1y\xcbH\x01\xa9\x9b\x95\u00f0\xc3$\xa2\xbd\xc1\x01\xa6S`\x89\x01h\u048e?\x00(\x00\x00\u07d4<\xb5a\u0386BK5\x98\x91\xe3d\xec\x92_\xfe\xff'}\xf7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4<\xcbq\xaah\x80\xcb\v\x84\x01-\x90\xe6\a@\xec\x06\xac\u05cf\x89lk\x93[\x8b\xbd@\x00\x00\u07d4<\xce\xf8\x86yW9G\xe9I\x97y\x8a\x1e2~\b`:e\x89+\xc9\x16\u059f;\x02\x00\x00\xe0\x94<\xd1\xd9s\x1b\xd5H\xc1\xddo\u03a6\x1b\xebu\xd9\x17T\xf7\u04ca\x01\x16\x1d\x01\xb2\x15\xca\xe4\x80\x00\u07d4<\u04e6\xe95y\xc5mIAq\xfcS>z\x90\xe6\xf5\x94d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4<\u05b7Y<\xbe\xe7x0\xa8\xb1\x9d\b\x01\x95\x8f\xcdK\xc5z\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4<\xd7\xf7\xc7\xc257\x80\xcd\xe0\x81\xee\xecE\x82+%\xf2\x86\f\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4<\xe1\u0717\xfc\u05f7\xc4\u04e1\x8aI\xd6\xf2\xa5\xc1\xb1\xa9\x06\u05c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4<\xea0*G*\x94\x03y\xdd9\x8a$\xea\xfd\xba\u07c8\xady\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94<\xec\xa9k\xb1\xcd\xc2\x14\x02\x9c\xbc^\x18\x1d9\x8a\xb9M=A\x8a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4<\xf4\x84RO\xbd\xfa\xda\xe2m\xc1\x85\xe3++c\x0f\xd2\xe7&\x89\x18TR\xcb*\x91\xc3\x00\x00\u07d4<\xf9\xa1\xd4e\xe7\x8bp9\xe3iDx\xe2b{6\xfc\xd1A\x89J`S*\xd5\x1b\xf0\x00\x00\u07d4<\xfb\xf0fVYpc\x9e\x13\r\xf2\xa7\xd1k\x0e\x14\xd6\t\x1c\x89\\(=A\x03\x94\x10\x00\x00\xe0\x94=\th\x8d\x93\xad\a\xf3\xab\xe6\x8cr'#\xcdh\t\x90C^\x8a\x06ZL\xe9\x9fv\x9en\x00\x00\u07d4=1X{_\u0546\x98Ex\x87%\xa6c)\nI\xd3g\x8c\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4=?\xadI\xc9\xe5\xd2u\x9c\x8e\x8eZzM`\xa0\xdd\x13V\x92\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4=WO\xcf\x00\xfa\xe1\u064c\u023f\x9d\u07e1\xb3\x95;\x97A\xbc\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4=Z\x8b+\x80\xbe\x8b5\xd8\xec\xf7\x89\xb5\xedz\au\xc5\al\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4=f\xcdK\xd6M\\\x8c\x1b^\xea(\x1e\x10m\x1cZ\xad#s\x89i\xc4\xf3\xa8\xa1\x10\xa6\x00\x00\u0794=j\xe0S\xfc\xbc1\x8do\xd0\xfb\xc3S\xb8\xbfT.h\r'\x88\xc6s\xce<@\x16\x00\x00\u07d4=o\xf8,\x93w\x05\x9f\xb3\r\x92\x15r?`\xc7u\u0211\xfe\x89\r\x8e\\\xe6\x17\xf2\xd5\x00\x00\u07d4=y\xa8S\xd7\x1b\xe0b\x1bD\xe2\x97Yel\xa0u\xfd\xf4\t\x89lk\x93[\x8b\xbd@\x00\x00\u07d4=~\xa5\xbf\x03R\x81\x00\xed\x8a\xf8\xae\xd2e>\x92\x1bng%\x8965\u026d\xc5\u07a0\x00\x00\u07d4=\x81?\xf2\xb6\xedW\xb97\u06bf+8\x1d\x14\x8aA\x1f\xa0\x85\x89\x05k\xc7^-c\x10\x00\x00\u07d4=\x88\x143\xf0J}\r'\xf8ID\xe0\x8aQ-\xa3UR\x87\x89A\rXj \xa4\xc0\x00\x00\u07d4=\x89\xe5\x05\xcbF\xe2\x11\xa5?2\xf1g\xa8w\xbe\xc8\u007fK\n\x89\x01[5W\xf1\x93\u007f\x80\x00\xe0\x94=\x8d\a#r\x1es\xa6\xc0\xd8`\xaa\x05W\xab\xd1L\x1e\xe3b\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4=\x8f9\x88\x1b\x9e\xdf\xe9\x12'\xc3?\xa4\xcd\xd9\x1eg\x85D\xb0\x89\x04\xab\a\xbaC\xad\xa9\x80\x00\u07d4=\x9dk\xe5\u007f\xf8>\x06Y\x85fO\x12VD\x83\xf2\xe6\x00\xb2\x89n\xac\xe4?#\xbd\x80\x00\x00\u07d4=\xa3\x9c\xe3\xefJz9f\xb3.\xe7\xeaN\xbc#5\xa8\xf1\x1f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4=\xaa\x01\u03b7\x0e\xaf\x95\x91\xfaR\x1b\xa4\xa2~\xa9\xfb\x8e\xdeJ\x89Zc\xd2\u027cvT\x00\x00\u07d4=\xb5\xfejh\xbd6\x12\xac\x15\xa9\x9aa\xe5U\x92\x8e\xec\xea\xf3\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4=\xb9\xed\u007f\x02L~&7/\xea\xcf+\x05\b\x03D^8\x10\x89E\xb1H\xb4\x99j0\x00\x00\u07d4=\xbf\r\xbf\xd7x\x90\x80\x053\xf0\x9d\xea\x83\x01\xb9\xf0%\u04a6\x8965\u026d\xc5\u07a0\x00\x00\u07d4=\xce\U0005c18b\x15\xd3N\xdaBn\xc7\xe0K\x18\xb6\x01p\x02\x89lh\xcc\u041b\x02,\x00\x00\xe0\x94=\xd1.Uj`76\xfe\xbaJo\xa8\xbdJ\xc4]f*\x04\x8a#u{\x91\x83\xe0x(\x00\x00\u07d4=\u078b\x15\xb3\u033a\xa5x\x01\x12\xc3\xd6t\xf3\x13\xbb\xa6\x80&\x89`\x1dQZ>O\x94\x00\x00\xe0\x94=\xde\xdb\xe4\x89#\xfb\xf9\xe56\xbf\x9f\xfb\aG\xc9\xcd\u04de\xef\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d4=\xea\xe43'\x91?b\x80\x8f\xaa\x1bbv\xa2\xbdch\xea\u0649lk\x93[\x8b\xbd@\x00\x00\u07d4=\xf7b\x04\x9e\u068a\u0192}\x90Lz\xf4/\x94\xe5Q\x96\x01\x89lk\x93[\x8b\xbd@\x00\x00\u07d4>\x04\r@\u02c0\xba\x01%\xf3\xb1_\xde\xfc\xc8?0\x05\xda\x1b\x898E$\xccp\xb7x\x00\x00\u07d4>\v\x8e\xd8n\xd6i\xe1'#\xafur\xfb\xac\xfe\x82\x9b\x1e\x16\x89QM\xe7\xf9\xb8\x12\xdc\x00\x00\xe0\x94>\f\xbejm\xcba\xf1\x10\xc4[\xa2\xaa6\x1d\u007f\xca\xd3\xdas\x8a\x01\xb2\u07dd!\x9fW\x98\x00\x00\u07d4>\x19KN\xce\xf8\xbbq\x1e\xa2\xff$\xfe\xc4\xe8{\xd02\xf7\u0449\x8b\x9d\xc1\xbc\x1a\x03j\x80\x00\xe0\x94>\x1b\"0\xaf\xbb\xd3\x10\xb4\x92jLwmZ\u705cf\x1d\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4>\x1cS0\x0eL\x16\x89\x12\x16<~\x99\xb9]\xa2h\xad(\n\x896b2\\\u044f\xe0\x00\x00\u07d4>\x1c\x96 c\xe0\xd5)YA\xf2\x10\u0723\xabS\x1e\xec\x88\t\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4>,\xa0\xd24\xba\xf6\a\xadFj\x1b\x85\xf4\xa6H\x8e\xf0\n\xe7\x89\x04\xda!\xa3H=V\x80\x00\u07d4>/&#^\x13zs$\xe4\xdc\x15K]\xf5\xafF\xea\x1aI\x89\x017\xaa\xd8\x03-\xb9\x00\x00\xe0\x94>1a\xf1\xea/\xbf\x12ny\xda\x18\x01\u0695\x12\xb3y\x88\u024a\nm\xd9\f\xaeQ\x14H\x00\x00\xe0\x94>6\xc1rS\xc1\x1c\xf3\x89t\xed\r\xb1\xb7Y\x16\r\xa67\x83\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4><\u04fe\xc0e\x91\xd64o%Kb\x1e\xb4\x1c\x89\x00\x8d1\x895\u07fe\u069f74\x00\x00\u07d4>E\xbdU\u06d0`\xec\xed\x92;\xb9\xcbs<\xb3W?\xb51\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4>M\x13\xc5Z\x84\xe4n\xd7\xe9\u02d0\xfd5^\x8a\u0651\u33c965\u026d\xc5\u07a0\x00\x00\u07d4>N\x92e\"<\x9782L\xf2\v\xd0`\x06\xd0\a>\u06cc\x89\a?u\u0460\x85\xba\x00\x00\xe0\x94>O\xbdf\x10\x15\xf6F\x1e\xd6s\\\xef\xef\x01\xf3\x14E\xde:\x8a\x03n4)\x98\xb8\xb0 \x00\x00\xe0\x94>S\xff!\a\xa8\u07be3(I:\x92\xa5\x86\xa7\xe1\xf4\x97X\x8a\x04\xe6\x9c*q\xa4\x05\xab\x00\x00\u07d4>Z9\xfd\xdap\xdf\x11&\xab\r\u011asx1\x1aSz\x1f\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\xe0\x94>Z\xbd\t\xceZ\xf7\xba\x84\x87\xc3Y\xe0\xf2\xa9:\x98k\v\x18\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4>\\\xb8\x92\x8cAx%\xc0:;\xfc\xc5!\x83\xe5\xc9\x1eB\u05c9\xe71\xd9\xc5,\x96/\x00\x00\u07d4>^\x93\xfbL\x9c\x9d\x12F\xf8\xf2G5\x8e\"\xc3\xc5\xd1{j\x89\b!\xab\rD\x14\x98\x00\x00\u07d4>a\x83P\xfa\x01ez\xb0\xef>\xba\xc8\xe3p\x12\xf8\xfc+o\x89\x98\x06\xde=\xa6\xe9x\x00\x00\u07d4>c\xce;$\xca(e\xb4\u0166\x87\xb7\xae\xa3Y~\xf6\xe5H\x89lk\x93[\x8b\xbd@\x00\x00\u07d4>f\xb8GiVj\xb6yE\xd5\xfa\x8175V\xbc\u00e1\xfa\x89\b=lz\xabc`\x00\x00\xe0\x94>v\xa6-\xb1\x87\xaat\xf68\x17S;0l\xea\xd0\xe8\u03be\x8a\x06\x9bZ\xfa\xc7P\xbb\x80\x00\x00\u07d4>z\x96k]\xc3W\xff\xb0~\x9f\xe0g\xc4W\x91\xfd\x8e0I\x89\x034-`\xdf\xf1\x96\x00\x00\xe0\x94>\x81w!u#~\xb4\xcb\xe0\xfe-\xca\xfd\xad\xff\xebj\x19\x99\x8a\x01\xdd\f\x88_\x9a\r\x80\x00\x00\u07d4>\x83I\xb6\u007fWED\x9fe\x93g\u066dG\x12\xdb[\x89Z\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4>\x83TO\x00\x82U%r\u01c2\xbe\xe5\xd2\x18\xf1\xef\x06J\x9d\x89\x05l\xd5_\xc6M\xfe\x00\x00\u07d4>\x84\xb3\\[\"ePpa\xd3\vo\x12\xda\x03?\xe6\xf8\xb9\x89a\t=|,m8\x00\x00\u07d4>\x86A\xd4\x87E\xba2/_\xd6\xcbP\x12N\xc4f\x88\u01e6\x9a\u007f\xae\x8a\x01\n\xfc\x1a\xde;N\xd4\x00\x00\u07d4>\x91N0\x18\xac\x00D\x93A\u011d\xa7\x1d\x04\xdf\xee\xedb!\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4>\x94\x10\u04f9\xa8~\xd5\xe4Q\xa6\xb9\x1b\xb8\x92?\xe9\x0f\xb2\xb5\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4>\x94\xdfS\x13\xfaR\x05p\xef#+\xc31\x1d_b/\xf1\x83\x89lk\x93[\x8b\xbd@\x00\x00\u0794>\x9b4\xa5\u007f3u\xaeY\xc0\xa7^\x19\u0136A\"\x8d\x97\x00\x88\xf8i\x93)g~\x00\x00\u07d4>\xad\xa8\xc9/V\x06~\x1b\xb7<\xe3x\xdaV\xdc,\xdf\xd3e\x89w\xcd\xe9:\xeb\rH\x00\x00\xe0\x94>\xaf\by\xb5\xb6\xdb\x15\x9bX\x9f\x84W\x8bjt\xf6\xc1\x03W\x8a\x01\x898\xb6q\xfae\xa2\x80\x00\u07d4>\xaf1k\x87a]\x88\xf7\xad\xc7|X\xe7\x12\xedMw\x96k\x89\x05m\xbcL\xee$d\x80\x00\u07d4>\xb8\xb3;!\xd2<\u0686\xd8(\x88\x84\xabG\x0e\x16F\x91\xb5\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4>\xb9\xef\x06\xd0\xc2Y\x04\x03\x19\x94~\x8czh\x12\xaa\x02S\u0609\t\r\x97/22<\x00\x00\u07d4>\u030e\x16h\xdd\xe9\x95\xdcW\x0f\xe4\x14\xf4B\x11\xc54\xa6\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4>\u03752\xe3\x97W\x96b\xb2\xa4aA\u73c25\x93j_\x89\x03\x9f\xba\xe8\xd0B\xdd\x00\x00\u07d4>\xeeo\x1e\x966\vv\x89\xb3\x06\x9a\xda\xf9\xaf\x8e\xb6\f\u404965\u026d\xc5\u07a0\x00\x00\xe0\x94?\b\u066d\x89O\x81>\x8e!H\xc1`\xd2K5:\x8et\xb0\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4?\f\x83\xaa\xc5qybsN\\\xea\xea\xec\u04db(\xad\x06\xbe\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94?\x10\x80\x02\x82\u0477\xdd\u01cf\xa9-\x820\aN\x1b\xf6\xae\xae\x8a\x01\n\xfc\x1a\xde;N\xd4\x00\x00\u07d4?\x123qO M\xe9\xdeN\xe9m\a;6\x8d\x81\x97\x98\x9f\x89\x02\x17\xc4\x10t\xe6\xbb\x00\x00\u07d4?\x17:\xa6\xed\xf4i\u0445\xe5\x9b\xd2j\xe4#k\x92\xb4\xd8\xe1\x89\x11X\xe4`\x91=\x00\x00\x00\u07d4?\x1b\xc4 \xc5<\x00,\x9e\x90\x03|D\xfej\x8e\xf4\xdd\xc9b\x89\t`\xdbwh\x1e\x94\x00\x00\u07d4?#a\b\xee\xc7\"\x89\xba\u00e6\\\u0483\xf9^\x04\x1d\x14L\x8964\xbf9\xab\x98x\x80\x00\u07d4?-\xa0\x93\xbb\x16\xeb\x06O\x8b\xfa\x9e0\xb9)\xd1_\x8e\x1cL\x89lk\x93[\x8b\xbd@\x00\x00\u07d4?-\xd5]\xb7\xea\xb0\xeb\xeee\xb3>\xd8 ,\x1e\x99.\x95\x8b\x89,s\xc97t,P\x00\x00\u07d4?/8\x14\x91y|\xc5\xc0\u0502\x96\xc1O\xd0\xcd\x00\xcd\xfa-\x89+\x95\xbd\xcc9\xb6\x10\x00\x00\u07d4?0\u04fc\x9f`\"2\xbcrB\x88\xcaF\xcd\v\a\x88\xf7\x15\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4?<\x8ea\xe5`L\xef\x06\x05\xd46\xdd\"\xac\u0346\"\x17\xfc\x89Hz\x9a0E9D\x00\x00\u07d4??F\xb7\\\xab\xe3{\xfa\u0307`(\x1fCA\xca\u007fF=\x89 \xacD\x825\xfa\xe8\x80\x00\u07d4?G)c\x19x\x83\xbb\xdaZ\x9b}\xfc\xb2-\xb1\x14@\xad1\x89\x1a\x19d<\xb1\xef\xf0\x80\x00\u07d4?L\xd19\x9f\x8a4\xed\u06da\x17\xa4q\xfc\x92+Xp\xaa\xfc\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4?U\x1b\xa9<\xd5F\x93\xc1\x83\xfb\x9a\xd6\re\xe1`\x96s\u0249lk\x93[\x8b\xbd@\x00\x00\xe0\x94?bzv\x9ej\x95\x0e\xb8p\x17\xa7\u035c\xa2\bq\x13h1\x8a\x02\ub3b1\xa1r\u0738\x00\x00\u07d4?m\xd3e\x0e\xe4(\u0737u\x95S\xb0\x17\xa9j\x94(j\u0249Hz\x9a0E9D\x00\x00\u07d4?tr7\x80o\xed?\x82\x8ahR\xeb\bg\xf7\x90'\xaf\x89\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4?u\xaea\xcc\x1d\x80Be;[\xae\xc4D>\x05\x1c^z\xbd\x89\x05-T(\x04\xf1\xce\x00\x00\u07d4?\xb7\u0457\xb3\xbaO\xe0E\xef\xc2=P\xa1E\x85\xf5X\u0672\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94?\xbc\x1eE\x18\xd74\x00\xc6\xd0F5\x949\xfbh\xea\x1aI\xf4\x8a\x03y\v\xb8U\x13v@\x00\x00\u07d4?\xbe\xd6\xe7\xe0\u029c\x84\xfb\xe9\xeb\u03ddN\xf9\xbbIB\x81e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4?\u043bGy\x8c\xf4L\u07feM3=\xe67\xdfJ\x00\xe4\\\x89\x05lUy\xf7\"\x14\x00\x00\xe0\x94?\xe4\x0f\xbd\x91\x9a\xad(\x18\xdf\x01\xeeM\xf4lF\x84*\xc59\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4?\xe8\x01\xe6\x135\xc5\x14\r\xc7\xed\xa2\xefR\x04F\nP\x120\x89lk\x93[\x8b\xbd@\x00\x00\u07d4?\xf86\xb6\xf5{\x90\x1bD\f0\xe4\xdb\xd0e\xcf7\xd3\u050c\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4?\xfc\xb8p\xd4\x02=%]Qg\u0625\a\xce\xfc6kh\xba\x89#4^\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4@s\xfaI\xb8q\x17\u02d0\x8c\xf1\xabQ-\xa7T\xa92\xd4w\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4@\x8ai\xa4\a\x15\xe1\xb3\x13\xe15N`\b\x00\xa1\xe6\xdc\x02\xa5\x89\x01\u7e11\u0312T\x00\x00\u07d4@\x9b\xd7P\x85\x82\x1c\x1d\xe7\f\xdc;\x11\xff\xc3\xd9#\xc7@\x10\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4@\x9dZ\x96.\xde\uefa1x\x01\x8c\x0f8\xb9\u0372\x13\xf2\x89\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4@\xa31\x19[\x97s%\u00aa(\xfa/B\xcb%\xec<%<\x89lk\x93[\x8b\xbd@\x00\x00\u07d4@\xa7\xf7(g\xa7\u0706w\v\x16+uW\xa44\xedP\xcc\xe9\x8965\u026d\xc5\u07a0\x00\x00\u07d4@\xab\n>\x83\xd0\u022c\x93f\x91\x05 \xea\xb1w+\xac;\x1a\x894\xf1\f-\xc0^|\x00\x00\u07d4@\xabf\xfe!>\xa5l:\xfb\x12\xc7[\xe3?\x8e2\xfd\b]\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94@\xadt\xbc\v\xce*E\xe5/6\xc3\u07bb\x1b:\xda\x1bv\x19\x8a\x01p\x16-\xe1\t\xc6X\x00\x00\u07d4@\u03c9\x05\x91\xea\u484f\x81*)T\xcb)_c3'\xe6\x89\x02\x9b\xf76\xfcY\x1a\x00\x00\u07d4@\u03d0\xef[v\x8c]\xa5\x85\x00,\xcb\xe6avP\xd8\xe87\x8963\x03\"\xd5#\x8c\x00\x00\xe0\x94@\xd4]\x9dv%\xd1QV\xc92\xb7q\xca{\x05'\x13\tX\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4@\xdb\x1b\xa5\x85\xce4S\x1e\xde\xc5IHI9\x13\x81\xe6\xcc\u04c9a\t=|,m8\x00\x00\xe0\x94@\xdfI^\xcf?\x8bL\xef*l\x18\x99W$\x8f\u813c+\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4@\xe0\xdb\xf3\xef\uf404\xea\x1c\xd7\xe5\x03\xf4\v;J\x84C\xf6\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4@\xe2D\n\xe1B\u02006j\x12\xc6\xd4\x10/K\x844\xb6*\x8965\u026d\xc5\u07a0\x00\x00\u07d4@\xe3\u0083\xf7\xe2M\xe0A\f\x12\x1b\xee`\xa5`\u007f>)\xa6\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94@\xeaPD\xb2\x04\xb20v\xb1\xa5\x80;\xf1\xd3\f\x0f\x88\x87\x1a\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\xe0\x94@\xed\xdbD\x8di\x0e\xd7.\x05\xc2%\xd3O\xc85\x0f\xa1\xe4\u014a\x01{x\x83\xc0i\x16`\x00\x00\xe0\x94@\xf4\xf4\xc0ls,\xd3[\x11\x9b\x89;\x12~}\x9d\aq\xe4\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4A\x01\x0f\u023a\xf8C}\x17\xa0Ci\x80\x9a\x16\x8a\x17\xcaV\xfb\x89\x05k\xc7^-c\x10\x00\x00\u07d4A\x03)\x96q\xd4gc\x97\x8f\xa4\xaa\x19\xee4\xb1\xfc\x95'\x84\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4A\x03<\x1bm\x05\xe1\u0289\xb0\x94\x8f\xc6DS\xfb\xe8z\xb2^\x89Hz\x9a0E9D\x00\x00\u07d4A\t\x8a\x81E#\x17\xc1\x9e>\xef\v\xd1#\xbb\xe1x\xe9\xe9\u0289\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4A\x16\x10\xb1x\xd5a}\xfa\xb94\u0493\xf5\x12\xa9>\\\x10\xe1\x89\t79SM(h\x00\x00\u07d4A\x1c\x83\x1c\xc6\xf4O\x19e\xecWW\xabN[<\xa4\xcf\xfd\x1f\x89\x17\n\x0fP@\xe5\x04\x00\x00\xe0\x94A*h\xf6\xc6EU\x9c\xc9w\xfcId\x04z \x1d\x1b\xb0\xe2\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4A?K\x02f\x9c\xcf\xf6\x80k\xc8&\xfc\xb7\xde\xca;\x0e\xa9\xbc\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4AE\x99\t.\x87\x9a\xe2Sr\xa8MsZ\xf5\xc4\xe5\x10\xcdm\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4AHV\x12\xd04F\xecL\x05\xe5$NV?\x1c\xba\xe0\xf1\x97\x894\x95tD\xb8@\xe8\x00\x00\u07d4A]\tj\xb0b\x93\x18?<\x03=%\xf6\xcfqx\xac;\u01c9\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4Af\xfc\b\u0285\xf7f\xfd\xe81F\x0e\x9d\xc9<\x0e!\xaal\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94Ag\x84\xaf`\x960\xb0p\u051a\x8b\xcd\x12#\\d(\xa4\b\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4Ag\xcdH\xe73A\x8e\x8f\x99\xff\xd14\x12\x1cJJ\xb2x\u0109\xc5S%\xcat\x15\xe0\x00\x00\u07d4Al\x86\xb7 \x83\xd1\xf8\x90}\x84\xef\xd2\xd2\u05c3\xdf\xfa>\xfb\x89lj\xccg\u05f1\xd4\x00\x00\u07d4AsA\x9d\\\x9fc)U\x1d\xc4\xd3\xd0\u03ac\x1bp\x1b\x86\x9e\x89\x04\xc5>\xcd\xc1\x8a`\x00\x00\u07d4At\xfa\x1b\xc1*;q\x83\u02eb\xb7z\vYU{\xa5\xf1\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4Axj\x10\xd4G\xf4\x84\xd32D\u0337\xfa\u034bB{[\x8c\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94Az<\u0454\x96S\nmB\x04\u00f5\xa1|\xe0\xf2\a\xb1\xa5\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4A~N&\x88\xb1\xfdf\xd8!R\x9eF\xedOB\xf8\xb3\xdb=\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94A\x9aq\xa3l\x11\xd1\x05\xe0\xf2\xae\xf5\xa3\xe5\x98\a\x8e\x85\xc8\v\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94A\x9b\xdes\x16\xcc\x1e\u0495\u0205\xac\xe3B\u01db\xf7\xee3\xea\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4A\xa2\xf2\xe6\xec\xb8c\x94\xec\x0e3\x8c\x0f\xc9~\x9cU\x83\xde\u0489l\xee\x06\u077e\x15\xec\x00\x00\u07d4A\xa8\u0083\x00\x81\xb1\x02\xdfn\x011e|\a\xabc[T\u0389lj\xccg\u05f1\xd4\x00\x00\u07d4A\xa8\xe26\xa3\x0emc\xc1\xffdM\x13*\xa2\\\x89S~\x01\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4A\xa9\xa4\x04\xfc\x9f[\xfe\xe4\x8e\xc2e\xb1%#3\x8e)\xa8\xbf\x89\x15\b\x94\xe8I\xb3\x90\x00\x00\u07d4A\xad6\x9fu\x8f\xef8\xa1\x9a\xa3\x14\x93y\x83,\x81\x8e\xf2\xa0\x8966\x9e\xd7t}&\x00\x00\u07d4A\xb2\xd3O\xde\v\x10)&+Ar\xc8\x1c\x15\x90@[\x03\xae\x8965\u026d\xc5\u07a0\x00\x00\u07d4A\xb2\xdb\u05dd\u069b\x86Ojp0'T\x19\u00dd>\xfd;\x89\xadx\xeb\u016cb\x00\x00\x00\u07d4A\xc3\xc26u4\xd1;\xa2\xb3?\x18\\\xdb\xe6\xacC\xc2\xfa1\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4A\u02d8\x96D_p\xa1\n\x14!R\x96\xda\xf6\x14\xe3,\xf4\u0549g\x8a\x93 b\xe4\x18\x00\x00\u07d4A\xcey\x95\t5\xcf\xf5[\xf7\x8eL\xce\xc2\xfec\x17\x85\u06d5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4A\u04f71\xa3&\xe7hX\xba\xa5\xf4\xbd\x89\xb5{6\x93#C\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\xe0\x94A\xe4\xa2\x02u\xe3\x9b\xdc\xef\xebe\\\x03\"tKvQ@\u008a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4A\xed-\x8ep\x81H,\x91\x9f\xc2=\x8f\x00\x91\xb3\xc8,F\x85\x89F:\x1ev[\u05ca\x00\x00\xe0\x94A\xf2~tK\u049d\xe2\xb0Y\x8f\x02\xa0\xbb\x9f\x98\xe6\x81\ua90a\x01\xa4\xab\xa2%\xc2\a@\x00\x00\u07d4A\xf4\x89\xa1\xect{\u009c>_\x9d\x8d\xb9xw\xd4\u0474\xe9\x89\a?u\u0460\x85\xba\x00\x00\u07d4B\x0f\xb8n}+Q@\x1f\xc5\xe8\xc7 \x15\xde\xcbN\xf8\xfc.\x8965\u026d\xc5\u07a0\x00\x00\u07d4B\x16\x84\xba\xa9\xc0\xb4\xb5\xf5S8\xe6\xf6\xe7\xc8\xe1F\xd4\x1c\xb7\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4B9\x96Y\xac\xa6\xa5\xa8c\xea\"E\xc93\xfe\x9a5\xb7\x88\x0e\x89n\xce2\xc2l\x82p\x00\x00\xe0\x94B;\xcaG\xab\xc0\fpW\xe3\xad4\xfc\xa6>7_\xbd\x8bJ\x8a\x03\xcf\xc8.7\xe9\xa7@\x00\x00\u07d4B<1\a\xf4\xba\xceANI\x9cd9\nQ\xf7F\x15\xca^\x89lk\x93[\x8b\xbd@\x00\x00\u07d4B<\xc4YL\xf4\xab\xb66\x8d\xe5\x9f\u04b1#\a4a!C\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94BD\xf13\x11X\xb9\xce&\xbb\xe0\xb9#k\x92\x03\xca5\x144\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u0794BQw\xebt\xad\n\x9d\x9aWR\"\x81G\xeemcV\xa6\u6239\x8b\xc8)\xa6\xf9\x00\x00\u07d4BW%\xc0\xf0\x8f\b\x11\xf5\xf0\x06\xee\xc9\x1c\\\\\x12k\x12\xae\x89\b!\xab\rD\x14\x98\x00\x00\xe0\x94BX\xfdf/\xc4\xce2\x95\xf0\xd4\xed\x8f{\xb1D\x96\x00\xa0\xa9\x8a\x01lE.\xd6\b\x8a\xd8\x00\x00\xe0\x94B\\\x18\x16\x86\x8fww\xcc+\xa6\xc6\u048c\x9e\x1eylR\xb3\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4B\\3\x8a\x13%\xe3\xa1W\x8e\xfa)\x9eW\u0646\xebGO\x81\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94BbY\xb0\xa7Vp\x1a\x8bf5(R!V\xc0(\x8f\x0f$\x8a\x02\x18\xae\x19k\x8dO0\x00\x00\u07d4Bm\x15\xf4\a\xa0\x115\xb1:kr\xf8\xf2R\v51\xe3\x02\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4Box\xf7\r\xb2Y\xac\x854\x14[)4\xf4\xef\x10\x98\xb5\u0609\x13\x84\x00\xec\xa3d\xa0\x00\x00\u07d4Bs-\x8e\xf4\x9f\xfd\xa0K\x19x\x0f\xd3\xc1\x84i\xfb7A\x06\x89\x17\v\x00\xe5\u4a7e\x00\x00\u07d4Bt\x17\xbd\x16\xb1\xb3\xd2-\xbb\x90-\x8f\x96W\x01o$\xa6\x1c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Btj\xee\xa1O'\xbe\xff\f\r\xa6BS\xf1\xe7\x97\x18\x90\xa0\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4B{F*\xb8NP\x91\xf4\x8aF\xeb\f\u0712\xdd\xcb&\xe0x\x89lk\x93[\x8b\xbd@\x00\x00\u07d4B~GQ\u00fa\xbex\xcf\xf8\x83\b\x86\xfe\xbc\x10\xf9\x90\x8dt\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94B~\xc6h\xac\x94\x04\xe8\x95\u0306\x15\x11\xd1b\nI\x12\xbe\x98\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4B\x80\xa5\x8f\x8b\xb1\v\x94@\u0794\xf4+OY! \x82\x01\x91\x89lk\x93[\x8b\xbd@\x00\x00\u07d4B\x8a\x1e\xe0\xed3\x1dyR\u033e\x1cyt\xb2\x85+\u0453\x8a\x89w\xb7JN\x8d\xe5e\x00\x00\u0794B\x9c\x06\xb4\x87\xe8Tj\xbd\xfc\x95\x8a%\xa3\xf0\xfb\xa5?o\x00\x88\xbbdJ\xf5B\x19\x80\x00\xe0\x94B\xa9\x8b\xf1`'\xceX\x9cN\xd2\xc9X1\xe2rB\x05\x06N\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4B\xc6\xed\xc5\x15\xd3UW\x80\x8d\x13\xcdD\xdc\xc4@\v%\x04\xe4\x89\n\xba\x14\u015b\xa72\x00\x00\u07d4B\xce\xcf\u0492\x10y\xc2\xd7\xdf?\b\xb0z\xa3\xbe\xee^!\x9a\x8965\u026d\xc5\u07a0\x00\x00\u07d4B\u04669\x9b0\x16\xa8Y\u007f\x8bd\t'\xb8\xaf\xbc\xe4\xb2\x15\x89\xa1\x8b\xce\xc3H\x88\x10\x00\x00\u07d4B\xd3I@\xed\xd2\xe7\x00]F\xe2\x18\x8eL\xfe\u0383\x11\xd7M\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4B\u04e5\xa9\x01\xf2\xf6\xbd\x93V\xf1\x12\xa7\x01\x80\xe5\xa1U\v`\x892$\xf4'#\xd4T\x00\x00\u07d4B\u05b2c\xd9\xe9\xf4\x11lA\x14$\xfc\x99Ux;\xa1\xc5\x1b\x81\x0f\xc4g\u057aM\xeaB\xf7\xa9\x88^i\x8a\bxg\x83&\xea\xc9\x00\x00\x00\xe0\x94C>\xb9J3\x90\x86\xed\x12\u067d\xe9\xcd\x1dE\x86\x03\xc9}\u058a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4CI\"Zb\xf7\n\xeaH\n\x02\x99\x15\xa0\x1eSy\xe6O\xa5\x89\x8c\xd6~#4\xc0\xd8\x00\x00\u07d4CT\"\x1eb\xdc\t\xe6@d6\x16:\x18^\xf0m\x11J\x81\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94CTC\xb8\x1d\xfd\xb9\xbd\x8cg\x87\xbc%\x18\xe2\xd4~W\xc1_\x8a\x01C\x8d\x93\x97\x88\x1e\xf2\x00\x00\u07d4Ca\u0504o\xaf\xb3w\xb6\xc0\xeeI\xa5\x96\xa7\x8d\xdf5\x16\xa3\x89\xc2\x12z\xf8X\xdap\x00\x00\xe0\x94Cd0\x9a\x9f\xa0p\x95`\x0fy\xed\xc6Q \xcd\xcd#\xdcd\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4Cg\xaeK\f\xe9d\xf4\xa5J\xfdK\\6\x84\x96\xdb\x16\x9e\x9a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Ct\x89(\xe8\xc3\xecD6\xa1\u0412\xfb\xe4:\xc7I\xbe\x12Q\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4Cv{\xf7\xfd*\xf9[r\xe91-\xa9D<\xb1h\x8eCC\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94Cy\x838\x8a\xb5\x9aO\xfc!_\x8e\x82iF\x10)\xc3\xf1\xc1\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4C\x89\x8cI\xa3MP\x9b\xfe\xd4\xf7`A\xee\x91\xca\xf3\xaaj\xa5\x89\x10CV\x1a\x88)0\x00\x00\u07d4C\x8c/T\xff\x8eb\x9b\xab6\xb1D+v\v\x12\xa8\x8f\x02\xae\x89lk\x93[\x8b\xbd@\x00\x00\u07d4C\x98b\x8e\xa6c-9>\x92\x9c\xbd\x92\x84d\xc5h\xaaJ\f\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4C\x9d//Q\x10\xa4\u054b\x17W\x93P\x15@\x87@\xfe\xc7\xf8\x89\u03e5\xc5\x15\x0fL\x88\x80\x00\u07d4C\x9d\xee?vy\xff\x100s?\x93@\xc0\x96hkI9\v\x89lk\x93[\x8b\xbd@\x00\x00\u07d4C\xb0y\xba\xf0ry\x99\xe6k\xf7C\u057c\xbfwl;\t\"\x89lk\x93[\x8b\xbd@\x00\x00\u07d4C\xbc-M\xdc\xd6X;\xe2\u01fc\tK(\xfbr\xe6+\xa8;\x89lk\x93[\x8b\xbd@\x00\x00\u07d4C\xc7\xeb\u0173\xe7\xaf\x16\xf4}\xc5az\xb1\x0e\x0f9\xb4\xaf\xbb\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4C\u02d6R\x81\x8coMg\x96\xb0\xe8\x94\t0ly\xdbcI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4C\xcc\b\xd0s*\xa5\x8a\xde\xf7a\x9b\xedFU\x8a\xd7wAs\x89\xf0\xe7\u0730\x12*\x8f\x00\x00\xe0\x94C\u0567\x1c\xe8\xb8\xf8\xae\x02\xb2\xea\xf8\xea\xf2\xca(@\xb9?\xb6\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u0794C\xdb\u007f\xf9Z\bm(\ubff8/\xb8\xfb_#\n^\xbc\u0348\xdfn\xb0\xb2\xd3\xca\x00\x00\u07d4C\xe7\xec\x84cX\xd7\xd0\xf97\xad\x1c5\v\xa0i\u05ffr\xbf\x89\x06p\xaeb\x92\x14h\x00\x00\u07d4C\xf1o\x1eu\xc3\xc0j\x94x\xe8\u0157\xa4\n<\xb0\xbf\x04\u0309\x9d\xf7\u07e8\xf7`H\x00\x00\u07d4C\xf4p\xede\x9e)\x91\xc3u\x95~]\xde\u017d\x1d8\"1\x89\x05k\xc7^-c\x10\x00\x00\u07d4C\xf7\xe8n8\x1e\xc5\x1e\u0110m\x14v\u02e9z=\xb5\x84\xe4\x8965\u026d\xc5\u07a0\x00\x00\u07d4C\xff8t>\xd0\xcdC0\x8c\x06e\t\u030e~r\xc8b\xaa\x89i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94C\xff\x88S\xe9\x8e\xd8@k\x95\x00\n\u0684\x83b\u05a09*\x8a\x04\xae\v\x1cM.\x84\xd0\x00\x00\u07d4D\t\x88f\xa6\x9bh\xc0\xb6\xbc\x16\x82)\xb9`5\x87\x05\x89g\x89\n1\x06+\xee\xedp\x00\x00\u07d4D\x19\xaca\x8d]\xea|\xdc`w o\xb0}\xbd\xd7\x1c\x17\x02\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4D\x1aR\x00\x16a\xfa\xc7\x18\xb2\u05f3Q\xb7\xc6\xfbR\x1az\xfd\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94D\x1a\u0282c\x13$\xac\xbf\xa2F\x8b\xda2[\xbdxG{\xbf\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4D\x1f7\xe8\xa0)\xfd\x02H/(\x9cI\xb5\xd0m\x00\xe4\b\xa4\x89\x12\x11\xec\xb5m\x13H\x80\x00\u07d4D \xaa5F[\xe6\x17\xad$\x98\xf3p\xde\n<\xc4\xd20\xaf\x89lk\x93[\x8b\xbd@\x00\x00\u07d4D#/\xf6m\xda\xd1\xfd\x84\x12f8\x006\xaf\xd7\xcf}\u007fB\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4D%\rGn\x06$\x84\xe9\b\n9g\xbf:Js*\xd7?\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4D)\xa2\x9f\xee\x19\x84Pg,\f\x1d\a1b%\v\xecdt\x896*\xaf\x82\x02\xf2P\x00\x00\u07d4D5RS\xb2wH\xe3\xf3O\xe9\xca\xe1\xfbq\x8c\x8f$\x95)\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4D8\xe8\x80\xcb'f\xb0\xc1\u03ae\xc9\xd2A\x8f\u03b9R\xa0D\x89\a?\xa0s\x90?\b\x00\x00\u07d4DL\xafy\xb7\x138\ue6a7\xc73\xb0*\u02a7\xdc\x02YH\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4D\\\xb8\xde^=\xf5 \xb4\x99\xef\u0240\xf5+\xff@\xf5\\v\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94Dj\x809\xce\u03dd\xceHy\xcb\xca\xf3I;\xf5E\xa8\x86\x10\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4Dt)\x9d\x0e\xe0\x90\u0710x\x9a\x14\x86H\x9c=\rd^m\x8965\u026d\xc5\u07a0\x00\x00\u07d4D\x8b\xf4\x10\xad\x9b\xbc/\xec\xc4P\x8d\x87\xa7\xfc.K\x85a\xad\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4D\x90\x1e\r\x0e\b\xac=^\x95\xb8\xec\x9d^\x0f\xf5\xf1.\x03\x93\x89\x16\xa1\xf9\xf5\xfd}\x96\x00\x00\xe0\x94D\x93\x12<\x02\x1e\xce;3\xb1\xa4R\xc9&\x8d\xe1@\a\xf9\u04ca\x01je\x02\xf1Z\x1eT\x00\x00\xe0\x94D\x9a\xc4\xfb\xe3\x83\xe3g8\x85^6JW\xf4q\xb2\xbf\xa11\x8a)\xb7d2\xb9DQ \x00\x00\u07d4D\xa0\x1f\xb0J\xc0\xdb,\xce]\xbe(\x1e\x1cF\xe2\x8b9\xd8x\x89lj\xccg\u05f1\xd4\x00\x00\u07d4D\xa6=\x18BE\x87\xb9\xb3\a\xbf\xc3\xc3d\xae\x10\xcd\x04\xc7\x13\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94D\xa8\x98\x9e20\x81!\xf7$f\x97\x8d\xb3\x95\xd1\xf7l:K\x8a\x01\x88P)\x9fB\xb0j\x00\x00\u07d4D\xc1\x11\v\x18\x87\x0e\xc8\x11x\xd9=!X8\xc5Q\u050ed\x89\n\xd6\xf9\x85\x93\xbd\x8f\x00\x00\u07d4D\xc1Ge\x12|\xde\x11\xfa\xb4l],\xf4\u0532\x89\x00#\xfd\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94D\xc5N\xaa\x8a\xc9@\xf9\xe8\x0f\x1et\xe8/\xc1O\x16v\x85j\x8a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4D\xcdwSZ\x89?\xa7\xc4\xd5\xeb:$\x0ey\u0419\xa7--\x89,s\xc97t,P\x00\x00\u07d4D\u07faP\xb8)\xbe\xcc_O\x14\u0470J\xab3 \xa2\x95\xe5\x8965\u026d\xc5\u07a0\x00\x00\u07d4D\xe2\xfd\xc6y\xe6\xbe\xe0\x1e\x93\xefJ:\xb1\xbc\xce\x01*\xbc|\x89\x16=\x19I\x00\xc5E\x80\x00\xe0\x94D\xf6/*\xaa\xbc)\xad:k\x04\xe1\xffo\x9c\xe4R\xd1\xc1@\x8a\x03\x99\x92d\x8a#\u0220\x00\x00\u07d4D\xff\xf3{\xe0\x1a8\x88\u04f8\xb8\u1200\xa7\xdd\xef\xee\xea\u04c9\x0e\f[\xfc}\xae\x9a\x80\x00\u07d4E\x06\xfe\x19\xfaK\x00k\xaa9\x84R\x9d\x85\x16\xdb++P\xab\x89lk\x93[\x8b\xbd@\x00\x00\u07d4E\x1b6\x99G[\xed]y\x05\xf8\x90Z\xa3Eo\x1e\u05c8\xfc\x89\x8a\xc7#\x04\x89\xe8\x00\x00\x00\u0794E\x1bpp%\x9b\u06e2q\x00\xe3n#B\x8aS\xdf\xe3\x04\u9239\x8b\xc8)\xa6\xf9\x00\x00\u07d4E'+\x8fb\xe9\xf9\xfa\x8c\xe0D \u1ba3\xeb\xa9hn\xac\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94E+d\u06ce\xf7\xd6\u07c7\u01c8c\x9c\"\x90\xbe\x84\x82\xd5u\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4E>5\x9a3\x97\x94LZ'Z\xb1\xa2\xf7\n^Z?i\x89\x89\r\x02\xabHl\xed\xc0\x00\x00\u07d4EI\xb1Yy%_~e\xe9\x9b\rV\x04\u06d8\xdf\xca\u023f\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4EKa\xb3D\xc0\xef\x96Qy#\x81U\xf2w\u00c2\x9d\v8\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94EO\x01A\xd7!\xd3<\xbd\xc4\x10\x18\xbd\x01\x11\x9a\xa4xH\x18\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4ES3\x90\xe3@\xfe\r\xe3\xb3\xcf_\xb9\xfc\x8e\xa5R\xe2\x9eb\x89O%\x91\xf8\x96\xa6P\x00\x00\u07d4ES\x96\xa4\xbb\u067a\u8bdf\xb7\xc4\xd6MG\x1d\xb9\xc2E\x05\x89\b\xbaR\xe6\xfcE\xe4\x00\x00\u07d4E[\x92\x96\x92\x1at\xd1\xfcAa\u007fC\xb80>o>\xd7l\x89\u3bb5sr@\xa0\x00\x00\u07d4E\\\xb8\xee9\xff\xbcu#1\xe5\xae\xfcX\x8e\xf0\xeeY4T\x8965F:x\r\xef\x80\x00\u07d4Ej\u0b24\x8e\xbc\xfa\xe1f\x06\x02PR_c\x96^v\x0f\x89\x10CV\x1a\x88)0\x00\x00\u07d4Eo\x8dtf\x82\xb2$g\x93I\x06M\x1b6\x8c|\x05\xb1v\x89\u0213\u041c\x8fQP\x00\x00\u07d4Ep)\xc4i\xc4T\x8d\x16\x8c\xec>e\x87.D(\xd4+g\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Eq\xdeg+\x99\x04\xba\xd8t6\x92\xc2\x1cO\xdc\xeaL.\x01\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4Ex\x1b\xbew\x14\xa1\xc8\xf7;\x1cty!\xdfO\x84'\x8bp\x89lk\x93[\x8b\xbd@\x00\x00\u07d4E{\xce\xf3}\xd3\xd6\v-\xd0\x19\xe3\xfea\xd4k?\x1erR\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94E\x8e<\u025e\x94xD\xa1\x8ejB\x91\x8f\xef~\u007f_^\xb3\x8a\a\xb5?y\xe8\x88\xda\xc0\x00\x00\u07d4E\x93\x93\xd6:\x06>\xf3r\x1e\x16\xbd\x9f\xdeE\ue77dw\xfb\x89j\xba\u05a3\xc1S\x05\x00\x00\u07d4E\xa5p\xdc\xc2\t\f\x86\xa6\xb3\xea)\xa6\bc\xdd\xe4\x1f\x13\xb5\x89\f\x9a\x95\xee)\x86R\x00\x00\u07d4E\xa8 \xa0g/\x17\xdct\xa0\x81\x12\xbcd?\xd1\x16w6\u00c9\n\xd6\xc4;(\x15\xed\x80\x00\u07d4E\xb4q\x05\xfeB\xc4q-\xcen*!\xc0[\xff\xd5\xeaG\xa9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4E\xbb\x82\x96R\u063f\xb5\x8b\x85'\xf0\xec\xb6!\u009e!.\u00c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94E\xc0\u045f\v\x8e\x05O\x9e\x8986\xd5\xec\xaey\x01\xaf(\x12\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4E\xc4\xec\xb4\xee\x89\x1e\xa9\x84\xa7\xc5\xce\xfd\x8d\xfb\x001\v(P\x89kV\x05\x15\x82\xa9p\x00\x00\u07d4E\u028d\x95f\b\xf9\xe0\n/\x99t\x02\x86@\x88\x84ef\x8f\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94E\u0298b\x00;N@\xa3\x17\x1f\xb5\xca\xfa\x90(\xca\xc8\xde\x19\x8a\x02\ub3b1\xa1r\u0738\x00\x00\u07d4E\xd1\xc9\xee\xdf|\xabA\xa7y\x05{y9_T(\xd8\x05(\x89lk\x93[\x8b\xbd@\x00\x00\u07d4E\u0535M7\xa8\xcfY\x98!#_\x06/\xa9\xd1p\xed\u8909\x11\x90g;_\u0690\x00\x00\xe0\x94E\xdb\x03\xbc\xcf\u05a5\xf4\xd0&k\x82\xa2*6\x87\x92\xc7}\x83\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4E\xe3\xa9>r\x14J\u0686\f\xbcV\xff\x85\x14Z\xda8\xc6\u0689WG=\x05\u06ba\xe8\x00\x00\u07d4E\u6378\u06fa\xba_\xc2\xcb3|b\xbc\xd0\xd6\x1b\x05\x91\x89\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94E\u6379L}\n\xb7\xacA\x85zq\xd6qG\x87\x0fNq\x8aT\xb4\v\x1f\x85+\xda\x00\x00\x00\u07d4E\xf4\xfc`\xf0\x8e\xac\xa1\x05\x98\xf03c)\x80\x1e<\x92\xcbF\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4F\rSU\xb2\xce\xebnb\x10}\x81\xe5\x12p\xb2k\xf4V \x89l\xb7\xe7Hg\xd5\xe6\x00\x00\xe0\x94F\"O2\xf4\xec\xe5\u0206p\x90\xd4@\x9dU\xe5\v\x18C-\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4F'\xc6\x06\x84&q\xab\u0782\x95\xee]\xd9L\u007fT\x954\xf4\x89\x0f\x89_\xbd\x872\xf4\x00\x00\u07d4F+g\x8bQ\xb5\x84\xf3\xedz\xda\a\v\\\u065c\v\xf7\xb8\u007f\x89\x05k\xc7^-c\x10\x00\x00\u07d4FM\x9c\x89\xcc\xe4\x84\xdf\x00\x02w\x19\x8e\xd8\a_\xa65r\u0449\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4FPNj!Z\xc8;\xcc\xf9V\xbe\xfc\x82\xabZg\x93q\u0209\x1c!(\x05\u00b4\xa5\x00\x00\xe0\x94FQ\xdcB\x0e\b\xc3);'\xd2Ix\x90\xebP\":\xe2\xf4\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4FS\x1e\x8b\x1b\xde\t\u007f\u07c4\x9dm\x11\x98\x85`\x8a\x00\x8d\xf7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4Fb\x92\xf0\xe8\rC\xa7\x87t'u\x90\xa9\xebE\x96\x12\x14\xf4\x894\x95tD\xb8@\xe8\x00\x00\xe0\x94Fb\xa1v^\xe9!\x84-\u0708\x89\x8d\x1d\xc8bu\x97\xbd~\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4Fe\xe4s\x96\xc7\u06d7\xeb*\x03\xd9\bc\xd5\u053a1\x9a\x94\x89 \x86\xac5\x10R`\x00\x00\u07d4Fo\xdak\x9bX\xc5S'P0j\x10\xa2\xa8\xc7h\x10;\a\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4Fq$\xae\u007fE/&\xb3\xd5t\xf6\b\x88\x94\xfa]\x1c\xfb;\x89\x92^\x06\xee\xc9r\xb0\x00\x00\u0794Fr*6\xa0\x1e\x84\x1d\x03\xf7\x80\x93^\x91}\x85\u0566z\xbd\x88\xce\xc7o\x0eqR\x00\x00\u07d4Fw\x9aVV\xff\x00\xd7>\xac:\xd0\u00cbl\x850\x94\xfb@\x89\f\x82S\xc9lj\xf0\x00\x00\u07d4Fw\xb0N\x03C\xa3!1\xfdj\xbb9\xb1\xb6\x15k\xba=[\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4F}Y\x88$\x9ahaG\x16e\x98@\xed\n\xe6\xf6\xf4W\xbc\x89\x15\x01\xa4\x8c\xef\xdf\xde\x00\x00\u07d4F~\x0e\xd5O;v\xae\x066\x17n\aB\b\x15\xa0!sn\x89lk\x93[\x8b\xbd@\x00\x00\u07d4F~\xa1\x04E\x82~\xf1\xe5\x02\xda\xf7k\x92\x8a \x9e\r@2\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94F\u007f\xbfAD\x16\x00u\u007f\xe1X0\xc8\xcd_O\xfb\xbb\xd5`\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94F\x93Xp\x932\xc8+\x88~ \xbc\xdd\xd0\"\x0f\x8e\u06e7\u040a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u07d4F\x97\xba\xaf\x9c\xcb`?\xd3\x040h\x9dCTE\xe9\u024b\xf5\x89\n\xd2\x01\xa6yO\xf8\x00\x00\u07d4F\xa3\v\x8a\x80\x891!tE\xc3\xf5\xa9>\x88,\x03E\xb4&\x89\r\x8d\xb5\xeb\u05f2c\x80\x00\u07d4F\xa40\xa2\u0528\x94\xa0\u062a?\xea\xc6\x156\x14\x15\xc3\xf8\x1f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4F\xaaP\x18pg~\u007f\nPHv\xb4\xe8\x80\x1a\n\xd0\x1cF\x89+^:\xf1k\x18\x80\x00\x00\u07d4F\xbf\u0172\a\xeb \x13\xe2\xe6\x0fw_\xec\xd7\x18\x10\u0159\f\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4F\xc1\xaa\"D\xb9\u0229W\u028f\xacC\x1b\x05\x95\xa3\xb8h$\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4F\xd8\x061(B\x03\xf6(\x8e\xcdNWX\xbb\x9dA\xd0]\xbe\x89lk\x93[\x8b\xbd@\x00\x00\u07d4G\n\xc5\xd1\xf3\xef\xe2\x8f8\x02\xaf\x92[W\x1ec\x86\x8b9}\x89lk\x93[\x8b\xbd@\x00\x00\u07d4G\x10\x10\xdaI/@\x18\x83;\b\x8d\x98r\x90\x1e\x06\x12\x91t\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4G\x12T\x02e\xcb\xee\u00c4p\"\u015f\x1b1\x8dC@\n\x9e\x89\xbd\xbcA\xe04\x8b0\x00\x00\xe0\x94G\x14\u03e4\xf4k\u05bdps}u\x87\x81\x97\xe0\x8f\x88\xe61\x8a\x02\u007f>\u07f3Nn@\x00\x00\u07d4G H\xcc`\x9a\xeb$!e\uaa87\x05\x85\f\xf3\x12]\xe0\x8965\u026d\xc5\u07a0\x00\x00\u07d4G!\x92)\xe8\xcdVe\x9ae\u00a9C\xe2\u075a\x8fK\xfd\x89\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d4G7\xd0B\xdcj\xe7>\xc7:\xe2Qz\u03a2\xfd\xd9d\x87\u014965\u026d\xc5\u07a0\x00\x00\u07d4GAX\xa1\xa9\xdci<\x13?e\xe4{\\:\xe2\xf7s\xa8o\x89\n\xdaUGK\x814\x00\x00\u07d4GE\xab\x18\x1a6\xaa\x8c\xbf\"\x89\xd0\xc4Qe\xbc~\xbe#\x81\x89\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4GPf\xf9\xad&eQ\x96\xd5SS'\xbb\xeb\x9by)\xcb\x04\x89\xa4\xccy\x95c\u00c0\x00\x00\xe0\x94GR!\x8eT\xdeB?\x86\xc0P\x193\x91z\xea\b\xc8\xfe\u054a\x04<3\xc1\x93ud\x80\x00\x00\u07d4GZa\x93W-JNY\u05fe\t\u02d6\r\u074cS\x0e/\x89$,\xf7\x8c\xdf\a\xff\x80\x00\u07d4Gd\x8b\xed\x01\xf3\xcd2I\bNc]\x14\u06a9\xe7\xec<\x8a\x89\n\x84Jt$\xd9\xc8\x00\x00\u07d4Gh\x84\x10\xff%\xd6T\xd7.\xb2\xbc\x06\xe4\xad$\xf83\xb0\x94\x89\b\xb2\x8da\xf3\u04ec\x00\x00\u07d4GkU\x99\b\x9a?\xb6\xf2\x9clr\xe4\x9b.G@\ua00d\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4Gs\x0f_\x8e\xbf\x89\xacr\xef\x80\xe4l\x12\x19P8\xec\xdcI\x89\xabM\xcf9\x9a:`\x00\x00\xe0\x94G{$\xee\u80deO\u045d\x12P\xbd\vfEyJa\u028a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4G\x81\xa1\nM\xf5\uef02\xf4\xcf\xe1\a\xba\x1d\x8av@\xbdf\x89a\t=|,m8\x00\x00\u07d4G\x88Z\xba\xbe\xdfM\x92\x8e\x1c\x88\x83\xa6a\x9cl(\x11\x84\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94G\xe2]\xf8\x82%8\xa8Yk(\xc67\x89kM\x14<5\x1d\x8a\x11\v\xe9\xeb$\xb8\x81P\x00\x00\u07d4G\xf4ik\xd4b\xb2\r\xa0\x9f\xb8>\xd2\x03\x98\x18\xd7v%\xb3\x89\b\x13\xcaV\x90m4\x00\x00\u07d4G\xfe\xf5\x85\x84FRH\xa0\x81\r`F>\xe9>Zn\xe8\u04c9\x0fX\xcd>\x12i\x16\x00\x00\u07d4G\xffo\xebC! `\xbb\x15\x03\u05e3\x97\xfc\b\xf4\xe7\x03R\x89lk\x93[\x8b\xbd@\x00\x00\u07d4G\xff\xf4,g\x85Q\xd1A\xebu\xa6\xee9\x81\x17\xdf>J\x8d\x89\x05k\xea\xe5\x1f\xd2\xd1\x00\x00\u07d4H\x01\x0e\xf3\xb8\xe9^?0\x8f0\xa8\xcb\u007fN\xb4\xbf`\xd9e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4H\n\xf5 v\x00\x9c\xa77\x81\xb7\x0eC\xb9Y\x16\xa6\"\x03\xab\x892\x19r\xf4\b=\x87\x80\x00\u07d4H\x0f1\xb9\x891\x1eA$\u01a7F_ZD\tM6\xf9\u04097\x90\xbb\x85Q7d\x00\x00\xe0\x94H\x11\x15)j\xb7\xdbRI/\xf7\xb6G\xd63)\xfb\\\xbck\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d4H\x1e:\x91\xbf\xdc/\x1c\x84(\xa0\x11\x9d\x03\xa4\x16\x01A~\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4H(\xe4\xcb\xe3N\x15\x10\xaf\xb7,+\ueb0aE\x13\xea\xeb\u0649\u0556{\xe4\xfc?\x10\x00\x00\xe0\x94H)\x82\xac\x1f\x1cm\x17!\xfe\xec\u0679\xc9l\xd9I\x80PU\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4H0,1\x1e\xf8\xe5\xdcfAX\xddX<\x81\x19Mn\rX\x89\xb6gl\xe0\xbc\xcb\\\x00\x00\u07d4H;\xa9\x904\xe9\x00\xe3\xae\xdfaI\x9d;+\xce9\xbe\xb7\xaa\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4HT\x8bK\xa6+\xcb/\r4\xa8\x8d\u019ah\x0eS\x9c\xf0F\x89\x05l\xf1\u02fbt2\x00\x00\u07d4Hc\x84\x979&Zc\xb0\xa2\xbf#jY\x13\xe6\xf9Y\xce\x15\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d4He\x9d\x8f\x8c\x9a/\xd4Oh\u06a5]#\xa6\b\xfb\xe5\x00\u0709lk\x93[\x8b\xbd@\x00\x00\xe0\x94Hf\x9e\xb5\xa8\x01\u0637_\xb6\xaaX\xc3E\x1bpX\xc2C\xbf\x8a\x06\x8dB\xc18\u06b9\xf0\x00\x00\u07d4Hjl\x85\x83\xa8D\x84\xe3\xdfC\xa1#\x83\u007f\x8c~#\x17\u0409\x11\x87\xc5q\xab\x80E\x00\x00\u07d4Hz\xdf}p\xa6t\x0f\x8dQ\xcb\xddh\xbb?\x91\u0125\xceh\x89\x03\x9f\xba\xe8\xd0B\xdd\x00\x00\u07d4H~\x10\x85\x02\xb0\xb1\x89\uf70cm\xa4\xd0\xdbba\xee\xc6\xc0\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94H\x88\xfb%\xcdP\u06f9\xe0H\xf4\x1c\xa4}x\xb7\x8a'\xc7\u064a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u0794H\x934\u00b6\x95\xc8\xee\a\x94\xbd\x86B\x17\xfb\x9f\xd8\xf8\xb15\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4H\xa3\r\xe1\xc9\x19\xd3\xfd1\x80\xe9}_+*\x9d\xbd\x96M-\x89\x02b\x9ff\xe0\xc50\x00\x00\u07d4H\xbf\x14\u05f1\xfc\x84\xeb\xf3\xc9k\xe1/{\xce\x01\xaai\xb0>\x89\x06\x81U\xa46v\xe0\x00\x00\u07d4H\xc2\ue465\aV\xd8\u039a\xbe\xebu\x89\xd2,o\xee]\xfb\x89\xae\x8ez\v\xb5u\xd0\x00\x00\u07d4H\xc5\u0197\v\x91a\xbb\x1c{z\xdf\xed\x9c\xde\u078a\x1b\xa8d\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94H\xd2CKz}\xbb\xff\b\";c\x87\xb0]\xa2\xe5\t1&\x8a\x03\xcf\xc8.7\xe9\xa7@\x00\x00\u07d4H\xd4\xf2F\x8f\x96?\u05da\x00a\x98\xbbg\x89]-Z\xa4\u04c9K\xe4\xe7&{j\xe0\x00\x00\u07d4H\xe0\xcb\xd6\u007f\x18\xac\xdbzb\x91\xe1%M\xb3.\trs\u007f\x89\x05k\xe0<\xa3\xe4}\x80\x00\u07d4H\xf6\n5HO\xe7y+\u030a{c\x93\xd0\u0761\xf6\xb7\x17\x89\xc3(\t>a\xee@\x00\x00\u07d4H\xf8\x83\xe5g\xb46\xa2{\xb5\xa3\x12M\xbc\x84\xde\xc7u\xa8\x00\x89)\xd7n\x86\x9d\u0340\x00\x00\xe0\x94I\x01E\xaf\xa8\xb5E\"\xbb!\xf3R\xf0m\xa5\xa7\x88\xfa\x8f\x1d\x8a\x01\xf4lb\x90\x1a\x03\xfb\x00\x00\u07d4I\t\xb3\x19\x98\xea\xd4\x14\xb8\xfb\x0e\x84k\xd5\xcb\xde995\xbe\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4I\x12\xd9\x02\x93\x16v\xff9\xfc4\xfe<<\xc8\xfb!\x82\xfaz\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4I\x13o\xe6\xe2\x8btS\xfc\xb1kk\xbb\u9aac\xba\x837\xfd\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94I\x15a\u06cbo\xaf\xb9\x00~b\xd0P\u0082\xe9,Kk\u020a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4I\x18]\xd7\xc262\xf4lu\x94s\ubb96`\b\xcd5\x98\x89\r\xc5_\xdb\x17d{\x00\x00\u07d4I,\xb5\xf8a\xb1\x87\xf9\xdf!\xcdD\x85\xbe\xd9\vP\xff\xe2-\x89\x1b\x19\xe5\vD\x97|\x00\x00\u07d4I-\xe4j\xaf\x8f\x1dp\x8dY\u05da\xf1\xd0:\xd2\xcb`\x90/\x89lk\x93[\x8b\xbd@\x00\x00\u07d4I.p\xf0M\x18@\x8c\xb4\x1e%`70Pk5\xa2\x87k\x89\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4I:g\xfe#\xde\xccc\xb1\r\xdau\xf3(v\x95\xa8\x1b\u056b\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4I=H\xbd\xa0\x15\xa9\xbf\xcf\x16\x03\x93n\xabh\x02L\xe5Q\xe0\x89\x018\xa3\x88\xa4<\x00\x00\x00\xe0\x94IBV\xe9\x9b\x0f\x9c\xd6\xe5\xeb\xca8\x99\x862R\x90\x01e\u020a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4IM\xecM^\xe8\x8a'q\xa8\x15\xf1\xeerd\x94/\xb5\x8b(\x89lk\x93[\x8b\xbd@\x00\x00\u07d4I[d\x1b\x1c\u07a3b\u00f4\u02fd\x0f\\\xc5\v\x1e\x17k\x9c\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94Ih\xa2\xce\xdbEuU\xa19)Z\xea(wnT\x00<\x87\x8a\x02#\x1a\xef\u0266b\x8f\x00\x00\u07d4Im6U4S\n_\xc1W|\nRA\u02c8\xc4\xdapr\x89a\t=|,m8\x00\x00\xe0\x94In1\x95\x92\xb3A\xea\xcc\xd7x\u0767\xc8\x19mT\xca\xc7u\x8a\x01\xf5q\x89\x87fKH\x00\x00\u07d4IoXC\xf6\xd2L\u064d%^L#\xd1\xe1\xf0#\"uE\x89_\x17\x9f\u0526\xee\t\x80\x00\xe0\x94Ip\u04ec\xf7+[\x1f2\xa7\x00<\xf1\x02\xc6N\xe0TyA\x8a\x1d\xa5jK\b5\xbf\x80\x00\x00\u07d4Iw\xa7\x93\x9d\t9h\x94U\xce&9\xd0\xeeZL\xd9\x10\xed\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4Iy\x19N\xc9\xe9}\xb9\xbe\xe84;|w\xd9\xd7\xf3\xf1\u071f\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4Iy4c\xe1h\x10\x83\u05ab\xd6\xe7%\u057b\xa7E\xdc\xcd\xe8\x89\x1d\x98\xe9LNG\x1f\x00\x00\u07d4I\x81\xc5\xfff\xccN\x96\x80%\x1f\xc4\xcd/\xf9\a\xcb2xe\x89(\xa8WBTf\xf8\x00\x00\u07d4I\x89\u007f\xe92\xbb\xb3\x15L\x95\u04fc\xe6\xd9;ms)\x04\u0749\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4I\x89\xe1\xab^|\xd0\aF\xb3\x93\x8e\xf0\xf0\xd0d\xa2\x02[\xa5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4I\x8a\xbd\xeb\x14\xc2k{r4\xd7\x0f\u03ae\xf3a\xa7m\xffr\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4I\xa6E\xe0f}\xfd{2\xd0u\xcc$g\u074ch\t\a\u0109\a\x06\x01\x95\x8f\u02dc\x00\x00\xe0\x94I\xb7N\x16\x92e\xf0\x1a\x89\xecL\x90r\u0164\xcdr\xe4\xe85\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d4I\xbd\xbc{\xa5\xab\xeb\xb68\x9e\x91\xa3(R \xd3E\x1b\xd2S\x8965\u026d\xc5\u07a0\x00\x00\u07d4I\xc9A\xe0\xe5\x01\x87&\xb7)\x0f\xc4s\xb4q\xd4\x1d\xae\x80\u0449\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94I\xc9w\x1f\xca\x19\u0579\xd2E\u0211\xf8\x15\x8f\xe4\x9fG\xa0b\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4I\xcf\x1eT\xbe61\x06\xb9 r\x9d-\v\xa4o\bg\x98\x9a\x89\x0e\x87?D\x13<\xb0\x00\x00\u07d4I\xd2\u008e\xe9\xbcT^\xaa\xf7\xfd\x14\xc2|@s\xb4\xbb_\x1a\x89O\xe9\xb8\x06\xb4\r\xaf\x00\x00\u07d4I\xdd\xee\x90.\x1d\f\x99\u0471\x1a\xf3\u030a\x96\xf7\x8eM\xcf\x1a\x89\n\u03a5\xe4\xc1\x8cS\x00\x00\u07d4I\xf0(9[Z\x86\xc9\xe0\u007fwxc\x0eL.=7:w\x89\x06\xa7JP8\u06d1\x80\x00\xe0\x94J\x19 5\xe2a\x9b$\xb0p\x9dVY\x0e\x91\x83\xcc\xf2\xc1\u064a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4J@S\xb3\x1d\x0e\xe5\u06ef\xb1\xd0k\u05ec\u007f\xf3\",G\u0589K\xe4\xe7&{j\xe0\x00\x00\u07d4JC\x01p\x15-\xe5\x17&3\u0742b\xd1\a\xa0\xaf\xd9j\x0f\x89\xabM\xcf9\x9a:`\x00\x00\u07d4JG\xfc>\x17\u007fVz\x1e8\x93\xe0\x00\xe3k\xba#R\n\xb8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4JR\xba\xd2\x03W\"\x8f\xaa\x1e\x99k\xedy\f\x93gK\xa7\u0409Hz\x9a0E9D\x00\x00\u07d4JS\xdc\xdbV\xceL\xdc\xe9\xf8.\xc0\xeb\x13\xd6sR\xe7\u020b\x89\u3bb5sr@\xa0\x00\x00\u07d4J_\xae;\x03r\xc20\xc1%\xd6\xd4p\x14\x037\xab\x91VV\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4Jq\x90a\xf5(T\x95\xb3{\x9d~\xf8\xa5\x1b\a\xd6\u6b2c\x89\n\xd4\xc81j\v\f\x00\x00\u07d4Js8\x92\x98\x03\x1b\x88\x16\u0329FB\x1c\x19\x9e\x18\xb3C\u0589\"8h\xb8y\x14o\x00\x00\u07d4Js]\"G\x927m3\x13g\xc0\x93\xd3\x1c\x87\x944\x15\x82\x89f\xff\xcb\xfd^Z0\x00\x00\u07d4Jt\x94\xcc\xe4HU\u0300X(B\xbe\x95\x8a\r\x1c\x00r\ue242\x1a\xb0\xd4AI\x80\x00\x00\u07d4Ju\xc3\xd4\xfao\u033d]\u0567\x03\xc1Sy\xa1\xe7\x83\u9dc9b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x94J\x81\xab\xe4\x98L|k\xefc\u0598 \xe5WC\xc6\x1f \x1c\x8a\x03d\x01\x00N\x9a\xa3G\x00\x00\u07d4J\x82iO\xa2\x9d\x9e!2\x02\xa1\xa2\t(]\xf6\xe7E\xc2\t\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4J\x83\\%\x82LG\xec\xbf\u01d49\xbf?\\4\x81\xaau\u0349K\xe4\xe7&{j\xe0\x00\x00\u07d4J\x91\x802C\x91Y\xbb1[g%\xb6\x83\r\xc86\x97s\x9f\x89\x12\xa3.\xf6x3L\x00\x00\u07d4J\x97\xe8\xfc\xf4c^\xa7\xfc^\x96\xeeQu.\u00c8qk`\x89\x1d\x99E\xab+\x03H\x00\x00\u07d4J\x9a&\xfd\n\x8b\xa1\x0f\x97}\xa4\xf7|1\x90\x8d\xabJ\x80\x16\x89a\t=|,m8\x00\x00\u07d4J\xa1H\xc2\xc34\x01\xe6j+Xnew\u0132\x92\xd3\xf2@\x89\v\xb8`\xb2\x85\xf7t\x00\x00\u07d4J\xa6\x93\xb1\"\xf3\x14H*G\xb1\x1c\xc7|h\xa4\x97\x87ab\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4J\xb2\xd3O\x04\x83O\xbftyd\x9c\xab\x92=,G%\xc5S\x89\xbe\xd1\xd0&=\x9f\x00\x00\x00\u07d4J\xc0vs\xe4/d\xc1\xa2^\xc2\xfa-\x86\xe5\xaa+4\xe09\x89lk\x93[\x8b\xbd@\x00\x00\u07d4J\u016c\xad\x00\v\x88w!L\xb1\xae\x00\xea\u0263}Y\xa0\xfd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4J\u0250ZL\xb6\xab\x1c\xfdbTn\xe5\x91s\x00\xb8|O\u07897\b\xba\xed=h\x90\x00\x00\u07d4J\u03e9\xd9N\xdaf%\xc9\u07e5\xf9\xf4\xf5\xd1\a\xc4\x03\x1f\u07c9\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4J\xd0G\xfa\xe6~\xf1b\xfeh\xfe\xdb\xc2};e\xca\xf1\f6\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4J\xd9]\x18\x8dddp\x9a\xdd%U\xfbM\x97\xfe\x1e\xbf1\x1f\x89\x12\xc1\xb6\xee\xd0=(\x00\x00\u07d4J\xdb\xf4\xaa\xe0\xe3\xefD\xf7\xddM\x89\x85\u03ef\tn\u010e\x98\x89\b!\xab\rD\x14\x98\x00\x00\u07d4J\xe2\xa0M9\t\xefENTL\xcf\xd6\x14\xbf\xef\xa7\x10\x89\xae\x89\x18\x01\x15\x9d\xf1\xee\xf8\x00\x00\xe0\x94J\xe90\x82\xe4Q\x87\xc2a`\xe6g\x92\xf5\u007f\xad5Q\xc7:\x8a\x04\x96\x15 \xda\xff\x82(\x00\x00\u07d4J\xf0\xdb\a{\xb9\xba^D>!\xe1H\xe5\x9f7\x91\x05\u0152\x89 \x86\xac5\x10R`\x00\x00\u07d4K\x06\x19\xd9\u062a1:\x951\xac}\xbe\x04\xca\rjZ\u0476\x89lk\x93[\x8b\xbd@\x00\x00\u07d4K\v\u062c\xfc\xbcS\xa6\x01\v@\xd4\u040d\xdd-\x9dib-\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4K\x19\xeb\f5K\xc199`\xeb\x06\x06;\x83\x92o\rg\xb2\x89\x01\x92t\xb2Y\xf6T\x00\x00\u07d4K)C|\x97\xb4\xa8D\xbeq\u0323\xb6H\xd4\xca\x0f\u075b\xa4\x89\b$q\x984\u03ec\x00\x00\u07d4K1\xbfA\xab\xc7\\\x9a\xe2\u034f\u007f5\x16;n+tPT\x89\x14\xb5P\xa0\x13\xc78\x00\x00\u07d4K:|\u00e7\u05f0\x0e\xd5(\"!\xa6\x02Y\xf2[\xf6S\x8a\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94K:\xab3^\xbb\xfa\xa8p\xccM`^}.t\xc6h6\x9f\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4K\xcd\xc1\x8a`\x00\x00\u07d4K`\xa3\xe2S\xbf8\xc8\xd5f \x10\xbb\x93\xa4s\xc9e\xc3\xe5\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4Kt\xf5\xe5\x8e.\xdfv\xda\xf7\x01Q\x96J\v\x8f\x1d\xe0f<\x89\x11\x90\xaeID\xba\x12\x00\x00\u07d4Kv!f\xdd\x11\x18\xe8Ci\xf8\x04\xc7_\x9c\xd6W\xbfs\f\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4Ky.)h>\xb5\x86\u353b3Rl`\x01\xb3\x97\x99\x9e\x89 \x86\xac5\x10R`\x00\x00\u07d4K\x90N\x93K\xd0\u030b p_\x87\x9e\x90[\x93\xea\f\xcc0\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94K\x92\x06\xbakT\x9a\x1a\u007f\x96\x9e\x1d]\xba\x86u9\xd1\xfag\x8a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4K\x98N\xf2lWn\x81Z.\xae\xd2\xf5\x17\u007f\a\u06f1\xc4v\x89T\x91YV\xc4\t`\x00\x00\u07d4K\x9e\x06\x8f\xc4h\tv\xe6\x15\x04\x91)\x85\xfd\\\xe9K\xab\r\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4K\xa0\xd9\xe8\x96\x01w+IhG\xa2\xbbC@\x18g\x87\xd2e\x8965\u026d\xc5\u07a0\x00\x00\u07d4K\xa5:\xb5I\xe2\x01m\xfa\"<\x9e\u0563\x8f\xad\x91(\x8d\a\x89K\xe4\xe7&{j\xe0\x00\x00\xe0\x94K\xa8\xe0\x11\u007f\xc0\xb6\xa3\xe5k$\xa3\xa5\x8f\xe6\xce\xf4B\xff\x98\x8a\x011\xbe\xb9%\xff\xd3 \x00\x00\u07d4K\xac\x84j\xf4\x16\x9f\x1d\x95C\x1b4\x1d\x88\x00\xb2!\x80\xaf\x1a\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4K\xb6\xd8k\x83\x14\xc2-\x8d7\xeaQm\x00\x19\xf1V\xaa\xe1-\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94K\xb9e\\\xfb*6\xea|cz{\x85\x9bJ1T\xe2n\xbe\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\xe0\x94K\xbc\xbf8\xb3\xc9\x01c\xa8K\x1c\u04a9;X\xb2\xa34\x8d\x87\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94K\xd6\xdd\f\xff#@\x0e\x170\xba{\x89E\x04W}\x14\xe7J\x8a+\xa0\xcc\xdd\xd0\xdfs\xb0\x00\x00\u07d4K\xe8b\x8a\x81T\x87N\x04\x8d\x80\xc1B\x18\x10\"\xb1\x80\xbc\xc1\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4K\xe9\rA!)\u0564\xd0BCa\xd6d\x9dNG\xa6#\x16\x897\b\xba\xed=h\x90\x00\x00\xe0\x94K\xea(\x8e\xeaB\u0115^\xb9\xfa\xad*\x9f\xafG\x83\xcb\u076c\x8a\x06\x18\xbe\x16c\u012fI\x00\x00\u07d4K\xf4G\x97\x99\xef\x82\xee\xa2\tC7OV\xa1\xbfT\x00\x1e^\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4K\xf8\xbf\x1d5\xa211Wd\xfc\x80\x01\x80\x9a\x94\x92\x94\xfcI\x89\x03\x9f\xba\xe8\xd0B\xdd\x00\x00\u07d4K\xf8\xe2oL'\x90\xdae3\xa2\xac\x9a\xba\xc3\u019a\x19\x943\x89\n\u05ce\xbcZ\xc6 \x00\x00\u0794L\n\xcaP\x8b<\xaf^\xe0(\xbcp}\xd1\xe8\x00\xb88\xf4S\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94L\v\x15\x15\xdf\xce\u05e1>\x13\xee\x12\xc0\xf5#\xaePO\x03+\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4L\x13\x98\f2\xdc\xf3\x92\vx\xa4\xa7\x903\x12\x90|\x1b\x12?\x89\x03A\x00\x15\xfa\xae\f\x00\x00\u07d4L\x15y\xaf3\x12\xe4\xf8\x8a\xe9\x95\xcc9W\xd2R\xce\v\xf0\xc8}[O\"4g.p\x89\x87\x86x2n\xac\x90\x00\x00\u07d4LB1y\x82i\x1d\x10\x89\x05k\xc7^-c\x10\x00\x00\u07d4LZ\xfe@\xf1\x8f\xfcH\u04e1\xae\xc4\x1f\u009d\xe1y\xf4\u0497\x89lk\x93[\x8b\xbd@\x00\x00\u07d4L[=\xc0\xe2\xb96\x0f\x91(\x9b\x1f\xe1<\xe1,\x0f\xbd\xa3\xe1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Lfk\x86\xf1\xc5\ue324\x12\x85\xf5\xbd\xe4\xf7\x90R\b\x14\x06\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4Lik\xe9\x9f:i\x04@\xc3CjY\xa7\xd7\xe97\u05ba\r\x89\xbb\x91%T\"c\x90\x00\x00\u07d4Lj$\x8f\xc9}p]\xefI\\\xa2\aY\x16\x9e\xf0\xd3dq\x89)3\x1eeX\xf0\xe0\x00\x00\u07d4Lj\x9d\xc2\u02b1\n\xbb.|\x13p\x06\xf0\x8f\ucd77y\xe1\x89\x1b\r\x04 /G\xec\x00\x00\u07d4Lk\x93\xa3\xbe\xc1cIT\f\xbf\xca\xe9l\x96!\xd6dP\x10\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Lu\x98\x13\xad\x13\x86\xbe\xd2\u007f\xfa\xe9\xe4\x81^60\u0323\x12\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94Lv\f\xd9\xe1\x95\xeeO-k\xce%\x00\xff\x96\xda|C\ue44a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4Lv{e\xfd\x91\x16\x1fO\xbd\xccji\xe2\xf6\xadq\x1b\xb9\x18\x89'\b\x01\xd9F\xc9@\x00\x00\u07d4L~.+w\xad\f\xd6\xf4J\xcb(a\xf0\xfb\x8b(u\x0e\xf9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4L\x85\xed6/$\xf6\xb9\xf0L\xdf\xcc\xd0\"\xaeSQG\u02f9\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4L\x93[\xb2Pw\x8b0\x9b==\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4L\xee\x90\x1bJ\u0231V\xc5\xe2\xf8\xa6\xf1\xbe\xf5r\xa7\xdc\xeb~\x8965\u026d\xc5\u07a0\x00\x00\u07d4L\xef\xbe#\x98\xe4}R\u73743L\x8bivu\U00053b89\xd9o\u0390\u03eb\xcc\x00\x00\u07d4L\xf5S{\x85\x84/\x89\xcf\xee5\x9e\xaeP\x0f\xc4I\xd2\x11\x8f\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94M\bG\x1dh\x00z\xff*\xe2y\xbc^?\xe4\x15o\xbb\xe3\u078a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4M \x01\x10\x12@\b\xd5ov\x98\x12VB\f\x94jo\xf4\\\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4M$\xb7\xacG\xd2\xf2}\xe9\tt\xba=\xe5\xea\xd2\x03TK\u0349\x05k\xc7^-c\x10\x00\x00\u0794M)\xfcR:,\x16)S!!\u0699\x98\u9d6b\x9d\x1bE\x88\xdbD\xe0I\xbb,\x00\x00\u07d4M8\xd9\x0f\x83\xf4Q\\\x03\xccx2j\x15M5\x8b\u0602\xb7\x89\n\ad\a\xd3\xf7D\x00\x00\u07d4ML\xf5\x80t)a^0\xcd\xfa\xce\x1eZ\xaeM\xad0U\xe6\x89 \x86\xac5\x10R`\x00\x00\u07d4MW\xe7\x16\x87l\f\x95\xef^\xae\xbd5\xc8\xf4\x1b\x06\x9bk\xfe\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94Mg\U000ab159\xfe\xf5\xfcA9\x99\xaa\x01\xfd\u007f\xcep\xb4=\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4Mn\x8f\xe1\t\xcc\xd2\x15\x8eM\xb1\x14\x13/\xe7_\xec\u023e[\x89\x01[5W\xf1\x93\u007f\x80\x00\xe0\x94Mq\xa6\xeb=\u007f2~\x184'\x8e(\v\x03\x9e\xdd\xd3\x1c/\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4M|\xfa\xa8L\xb31\x06\x80\n\x8c\x80/\xb8\xaaF8\x96\u0159\x89a\t=|,m8\x00\x00\u07d4M\x80\x10\x93\xc1\x9c\xa9\xb8\xf3B\xe3<\xc9\xc7{\xbdL\x83\x12\u03c9\x12\xb3\xe7\xfb\x95\u0364\x80\x00\u07d4M\x82\x88\x94u/o%\x17]\xaf!w\tD\x87\x95Ko\x9f\x89O!+\xc2\u011c\x83\x80\x00\xe0\x94M\x82\xd7p\f\x12;\xb9\x19A\x9b\xba\xf0Fy\x9ck\x0e,f\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4M\x83m\x9d;\x0e,\xbdM\xe0PYo\xaaI\f\xff\xb6\r]\x89\x10CV\x1a\x88)0\x00\x00\u07d4M\x86\x97\xaf\x0f\xbf,\xa3n\x87h\xf4\xaf\"\x135phZ`\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4M\x92y\x96 )\xa8\xbdEc\x977\xe9\x8bQ\x1e\xff\aL!\x89Hz\x9a0E9D\x00\x00\u07d4M\x93io\xa2HY\xf5\u0493\x9a\xeb\xfaT\xb4\xb5\x1a\xe1\xdc\u0309\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4M\x9cw\xd0u\f^o\xbc$\u007f/\u05d2thl\xb3S\u0589\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4M\xa5\xed\u0188\xb0\xcbb\xe1@=\x17\x00\xd9\u0739\x9f\xfe?\u04c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94M\xa8\x03\ai\x84K\xc3A\x86\xb8\\\xd4\xc74\x88I\xffI\xe9\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4M\xb1\xc4:\x0f\x83M}\x04x\xb8\x96\ag\xec\x1a\xc4L\x9a\xeb\x89/Q\x810V'7\x00\x00\u07d4M\xb2\x12\x84\xbc\xd4\xf7\x87\xa7Ue\x00\xd6\xd7\xd8\xf3f#\xcf5\x89i(7Ow\xa3c\x00\x00\u07d4M\xc3\xda\x13\xb2\xb4\xaf\xd4O]\r1\x89\xf4D\xd4\xdd\xf9\x1b\x1b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4M\u013f^u\x89\xc4{(7\x8du\x03\u03d6H\x80a\u06fd\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4M\xc9\u057bK\x19\xce\u0354\xf1\x9e\xc2] \x0e\xa7/%\xd7\xed\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94M\xcd\x11\x81X\x18\xae)\xb8]\x016sI\xa8\xa7\xfb\x12\xd0k\x8a\x01\xacB\x86\x10\x01\x91\xf0\x00\x00\u07d4M\xcfb\xa3\xde?\x06\x1d\xb9\x14\x98\xfda\x06\x0f\x1fc\x98\xffs\x89lj\xccg\u05f1\xd4\x00\x00\u07d4M\xd11\xc7J\x06\x8a7\xc9\n\xde\xd4\xf3\t\xc2@\x9fdx\u04c9\x15\xaf9\u4ab2t\x00\x00\xe0\x94M\u0767Xk\"7\xb0S\xa7\xf3(\x9c\xf4`\xdcW\xd3z\t\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4M\xe3\xfe4\xa6\xfb\xf64\xc0Q\x99\u007fG\xcc\u007fHy\x1fX$\x89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u07d4M\xf1@\xbaye\x85\xddT\x891[\xcaK\xbah\n\u06f8\x18\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4N\x02\ay\xb5\xdd\xd3\xdf\"\x8a\x00\xcbH\xc2\xfc\x97\x9d\xa6\xae8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4N\v\xd3$s\xc4\xc5\x1b\xf2VT\xde\xf6\x9fy|k)\xa22\x89V\xc9]\xe8\xe8\xca\x1d\x00\x00\u07d4N\"%\xa1\xbbY\xbc\x88\xa21ft\xd33\xb9\xb0\xaf\xcafU\x89\bg\x0e\x9e\xc6Y\x8c\x00\x00\u07d4N#\x10\x19\x1e\xad\x8d;\xc6H\x98s\xa5\xf0\xc2\xeck\x87\u1f8965\u026d\xc5\u07a0\x00\x00\u07d4N#-S\xb3\u6f8f\x89Sa\xd3\x1c4\xd4v+\x12\xc8.\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4N+\xfaJFo\x82g\x1b\x80\x0e\xeeBj\xd0\f\a\x1b\xa1p\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4N>\xda\u0506M\xabd\xca\xe4\xc5Azvw@S\xdcd2\x89 \b\xfbG\x8c\xbf\xa9\x80\x00\u07d4NC\x18\xf5\xe1>\x82JT\xed\xfe0\xa7\xedO&\xcd=\xa5\x04\x89lk\x93[\x8b\xbd@\x00\x00\u07d4N[w\xf9\x06aY\xe6\x15\x93?-\xdatw\xfaNG\xd6H\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94Nf\x00\x80b\x89EJ\u03630\xa2\xa3U`\x10\u07ec\xad\xe6\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4Ns\xcf#y\xf1$\x86\x0fs\xd6\xd9\x1b\xf5\x9a\xcc\\\xfc\x84[\x89\x02,\xa3X|\xf4\xeb\x00\x00\xe0\x94Nz\xa6~\x12\x18>\xf9\xd7F\x8e\xa2\x8a\xd29\xc2\xee\xf7\x1bv\x8a\x01\n\xfc\x1a\xde;N\xd4\x00\x00\xe0\x94N{TGM\x01\xfe\xfd8\x8d\xfc\xd5;\x9ff&$A\x8a\x05\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94N\x89.\x80\x81\xbf6\xe4\x88\xfd\xdb;&0\xf3\xf1\xe8\xda0\u048a\x02\x8a\xba0u$Q\xfc\x00\x00\xe0\x94N\x8amcH\x9c\xcc\x10\xa5\u007f\x88_\x96\xeb\x04\xec\xbbT`$\x8a\x03\xea\xe3\x13\x0e\u0316\x90\x00\x00\u07d4N\x8eG\xae;\x1e\xf5\f\x9dT\xa3\x8e\x14 \x8c\x1a\xbd6\x03\u0089y(\xdb\x12vf\f\x00\x00\u0794N\x90\u03312X\xac\xaa\x9fO\xeb\xc0\xa3B\x92\xf9Y\x91\xe20\x88\xdbD\xe0I\xbb,\x00\x00\u07d4N\xa5n\x11\x12d\x1c\x03\x8d\x05e\xa9\u0096\xc4c\xaf\xef\xc1~\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\xe0\x94N\xa7\x0f\x041?\xaee\xc3\xff\"J\x05\\=-\xab(\xdd\u07ca\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4N\xb1EKW8\x05\u022c\xa3~\xde\xc7\x14\x9aA\xf6\x12\x02\xf4\x89\x10CV\x1a\x88)0\x00\x00\u07d4N\xb8{\xa8x\x8e\xba\r\xf8~[\x9b\xd5\n\x8eE6\x80\x91\xc1\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4N\xbcV)\xf9\xa6\xa6k,\xf36:\u0109\\\x03H\u8fc7\x8967\tlK\xcci\x00\x00\u07d4N\xc7h)^\xea\xba\xfcB\x95\x84\x15\xe2+\xe2\x16\xcd\xe7v\x18\x89\x03;\x1d\xbc9\xc5H\x00\x00\u07d4N\xcc\x19\x94\x8d\xd9\u0347\xb4\xc7 \x1a\xb4\x8eu\x8f(\xe7\xccv\x89\x1b\x1d\xaba\u04ead\x00\x00\u07d4N\xd1M\x81\xb6\v#\xfb%\x05M\x89%\u07e5s\u072eah\x89\x12nr\xa6\x9aP\xd0\x00\x00\xe0\x94N\xe1<\rA \vF\u045d\xee\\K\xce\xc7\x1d\x82\xbb\x8e8\x8a\x01\xab\xee\x13\u033e\ufbc0\x00\u07d4N\xea\xd4\n\xad\x8cs\xef\b\xfc\x84\xbc\n\x92\xc9\t/j6\xbf\x89\x01s\x17\x90SM\xf2\x00\x00\u07d4N\xeb\xe8\f\xb6\xf3\xaeY\x04\xf6\xf4\xb2\x8d\x90\u007f\x90q\x89\xfc\xab\x89lj\xccg\u05f1\xd4\x00\x00\u07d4N\xeb\xf1 ]\f\xc2\f\xeel\u007f\x8f\xf3\x11_V\u050f\xba&\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4N\xf1\xc2\x14c:\xd9\xc0p;N#t\xa2\xe3>>B\x92\x91\x89Hz\x9a0E9D\x00\x00\u07d4N\xfc\xd9\u01df\xb43L\xa6${\n3\xbd\x9c\xc32\b\xe2r\x89Hz\x9a0E9D\x00\x00\xe0\x94O\x06$k\x8dK\u0496a\xf4>\x93v\"\x01\u0486\x93Z\xb1\x8a\x01\x059O\xfcF6\x11\x00\x00\u07d4O\x15+/\xb8e\x9dCwn\xbb\x1e\x81g:\xa8Ai\xbe\x96\x89lk\x93[\x8b\xbd@\x00\x00\u07d4O\x17\u007f\x9dV\x95=\xedq\xa5a\x1f93\"\xc3\x02y\x89\\\x89\rU\uf422\xda\x18\x00\x00\u07d4O\x1a-\xa5JLm\xa1\x9d\x14$\x12\xe5n\x81WA\xdb#%\x89\x05k\xc7^-c\x10\x00\x00\u07d4O#\xb6\xb8\x17\xff\xa5\xc6d\xac\xda\u05db\xb7\xb7&\xd3\n\xf0\xf9\x89_h\xe8\x13\x1e\u03c0\x00\x00\xe0\x94O&i\f\x99+z1*\xb1.\x13\x85\xd9J\xcdX(\x8e{\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4O+G\xe2wZ\x1f\xa7\x17\x8d\xad\x92\x98Z[\xbeI;\xa6\u0589\n\u05ce\xbcZ\xc6 \x00\x00\u07d4O:HT\x91\x11E\xea\x01\xc6D\x04K\xdb.Z\x96\n\x98/\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4O?,g0i\xac\x97\xc2\x026\a\x15)\x81\xf5\xcd`c\xa0\x89 \x86\xac5\x10R`\x00\x00\xe0\x94OJ\x9b\xe1\f\xd5\xd3\xfb]\xe4\x8c\x17\xbe)o\x89V\x90d[\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4OR\xadap\xd2[*.\x85\x0e\xad\xbbRA?\xf20>\u007f\x89\xa4\xccy\x95c\u00c0\x00\x00\u07d4OX\x01\xb1\xeb0\xb7\x12\u0620WZ\x9aq\xff\x96]O4\xeb\x89\x10CV\x1a\x88)0\x00\x00\u07d4O]\xf5\xb9CW\u0794\x86\x04\xc5\x1bx\x93\xcd\xdf`v\xba\xad\x89\xcb\xd4{n\xaa\x8c\xc0\x00\x00\u07d4Od\xa8^\x8e\x9a@I\x8c\fu\xfc\xeb\x037\xfbI\b>^\x8965\u026d\xc5\u07a0\x00\x00\u07d4Og9m%S\xf9\x98x_pN\a\xa69\x19}\u0454\x8d\x89\x10DrR\x1b\xa78\x00\x00\u07d4OmG7\u05e9@8$\x87&H\x86i|\xf7c\u007f\x80\x15\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4Os0\toy\xed&N\xe0\x12\u007f]0\xd2\xf7?!\xcb\u007f\x04\x89\x04\x82\xfe&\f\xbc\xa9\x00\x00\u07d4O\xeeP\xc5\xf9\x88 k\t\xa5sF\x9f\xb1\u0434.\xbbm\u0389l\xee\x06\u077e\x15\xec\x00\x00\u07d4O\xf6v\xe2\u007fh\x1a\x98-\x8f\xd9\xd2\x0ed\x8b=\xce\x05\xe9E\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4O\xf6\u007f\xb8\u007fn\xfb\xa9'\x990\u03fd\x1bz4L\u057a\x8bN\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94PFf\u03891\x17^\x11\xa5\xed\x11\xc1\u072a\x06\xe5\u007fNf\x8a\x02\u007f>\u07f3Nn@\x00\x00\u0794PXM\x92\x06\xa4l\xe1\\0\x11\x17\xee(\xf1\\0\xe6\x0eu\x88\xb9\xf6]\x00\xf6<\x00\x00\xe0\x94PZ3\xa1\x864\xddH\x00i)\x13N\x00\x00\u07d4P\u0286\xb5\xeb\x1d\x01\x87M\xf8\xe5\xf3IE\u051cl\x1a\xb8H\x8965\u026d\xc5\u07a0\x00\x00\u07d4P\u0357\xe97\x8b\\\xf1\x8f\x179c#l\x99Q\xeft8\xa5\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4P\u073c'\xbc\xad\x98@\x93\xa2\x12\xa9\xb4\x17\x8e\xab\xe9\x01ua\x89\a\xe3by\v\\\xa4\x00\x00\u07d4P\xe10#\xbd\x9c\xa9j\xd4\xc5?\xdf\xd4\x10\xcbk\x1fB\v\u07c9\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94P\xe1\xc8\xec\x98A[\xefD&\x18p\x87\x99C{\x86\xe6\xc2\x05\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4P\xf8\xfaK\xb9\xe2g|\x99\nN\xe8\xcep\xdd\x15#%\x1eO\x89\x01i=#\x16Ok\x00\x00\u07d4P\xfb6\xc2q\a\xee,\xa9\xa3#n'F\u0321\x9a\xcekI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4P\xfe\xf2\x96\x95U\x88\u02aet\xc6.\xc3*#\xa4T\xe0\x9a\xb8\x89A\x1d\xff\xab\xc5\a8\x00\x00\u07d4Q\x02\xa4\xa4 w\xe1\x1cX\xdfGs\u3b14F#\xa6m\x9f\x89lp\x15\xfdR\xed@\x80\x00\u07d4Q\x03\x93w\xee\xd0\xc5s\xf9\x86\xc5\xe8\xa9_\xb9\x9aY\xe93\x0f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4Q\x03\xbc\t\x93>\x99!\xfdS\xdcSo\x11\xf0]\rG\x10}\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94Q\x04\xec\xc0\xe30\xdd\x1f\x81\xb5\x8a\xc9\u06f1\xa9\xfb\xf8\x8a<\x85\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4Q\r\x81Y\u0314Wh\xc7E\a\x90\xba\a>\xc0\xd9\xf8\x9e0\x89\x8a\xc7#\x04\x89\xe8\x00\x00\x00\u07d4Q\x0e\xdaV\x01I\x9a\r^\x1a\x00k\xff\xfd\x836r\xf2\xe2g\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Q\x12dF\xab=\x802U~\x8e\xbaeY}u\xfa\u0701\\\x89\x11t\xa5\xcd\xf8\x8b\xc8\x00\x00\xe0\x94Q\x18U}`\r\x05\xc2\xfc\xbf8\x06\xff\xbd\x93\xd0 %\xd70\x8a\x02g\u04ebd#\xf5\x80\x00\x00\u07d4Q\x1e\x0e\xfb\x04\xacN?\xf2\xe6U\x0eI\x82\x95\xbf\xcdV\xff\u0549$=M\x18\"\x9c\xa2\x00\x00\u07d4Q!\x16\x81{\xa9\xaa\xf8C\xd1P|e\xa5\xead\n{\x9e\xec\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4Q&F\ri,q\u026fo\x05WM\x93\x99\x83h\xa27\x99\x89\x02\u0465\x1c~\x00P\x00\x00\u07d4Q'\u007f\xe7\xc8\x1e\xeb\xd2R\xa0=\xf6\x9ak\x9f2n'\"\a\x89\x03@.y\u02b4L\x80\x00\u07d4Q)oPD'\r\x17pvF\x12\x9c\x86\xaa\xd1d^\xad\xc1\x89H|r\xb3\x10\xd4d\x80\x00\xe0\x94Q+\x91\xbb\xfa\xa9\xe5\x81\xefh?\xc9\r\x9d\xb2*\x8fI\xf4\x8b\x8aA\xa5\"8m\x9b\x95\xc0\x00\x00\u07d4Q5\xfb\x87W`\f\xf4tTbR\xf7M\xc0tm\x06&,\x89lk\x93[\x8b\xbd@\x00\x00\u07d4QF2\xef\xbdd,\x04\xdel\xa3B1]@\u0750\xa2\u06e6\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4QKu\x12\u026e^\xa6<\xbf\x11q[c\xf2\x1e\x18\u0496\xc1\x89lj\xccg\u05f1\xd4\x00\x00\u07d4QS\xa0\xc3\u0211(\x81\xbf\x1c5\x01\xbfd\xb4VI\xe4\x82\"\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94QVQ\xd6\xdbO\xaf\x9e\xcd\x10:\x92\x1b\xbb\xbej\xe9p\xfd\u050a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94Q_0\xbc\x90\xcd\xf4W~\xe4}e\u05c5\xfb\xe2\xe87\u01bc\x8a\x02'\x1b^\x01\x8b\xa0X\x00\x00\u07d4Q`\xeda.\x1bH\xe7??\xc1[\xc42\x1b\x8f#\xb8\xa2K\x89\x1e\x82kB(e\xd8\x00\x00\u07d4Qa\xfdI\xe8G\xf6tU\xf1\u023bz\xbb6\xe9\x85&\r\x03\x89A\rXj \xa4\xc0\x00\x00\u07d4QiT\x02_\xca&\b\xf4}\xa8\x1c!^\xed\xfd\x84J\t\xff\x89\x14\xb5P\xa0\x13\xc78\x00\x00\u07d4Qi\xc6\n\xeeL\xee\u0444\x9a\xb3mfL\xff\x97\x06\x1e\x8e\xa8\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4Q|uC\r\xe4\x01\xc3A\x03&\x86\x11'\x90\xf4mM6\x9e\x89\x15\b\x94\xe8I\xb3\x90\x00\x00\u07d4Q|\xd7`\x8e]\r\x83\xa2kq\u007f6\x03\xda\xc2'}\u00e4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Q\x86]\xb1H\x88\x19Q\xf5\x12Qq\x0e\x82\xb9\xbe\r~\xad\xb2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Q\x89\x1b,\xcd\xd2\xf5\xa4K*\x8b\u011a]\x9b\xcadw%\x1c\x89\x10\xce\x1d=\x8c\xb3\x18\x00\x00\u07d4Q\x8c\xef'\xb1\x05\x82\xb6\xd1OiH=\u06a0\xdd<\x87\xbb\\\x89 \x86\xac5\x10R`\x00\x00\u07d4Q\xa6\xd6'\xf6j\x89#\u060d`\x94\xc4qS\x80\xd3\x05|\xb6\x89>s\xd2z5\x94\x1e\x00\x00\u07d4Q\xa8\xc2\x166\x02\xa3.\xe2L\xf4\xaa\x97\xfd\x9e\xa4\x14QiA\x89\x03h\xf7\xe6\xb8g,\x00\x00\u07d4Q\xb4u\x8e\x9e\x14P\xe7\xafBh\xc3\u01f1\xe7\xbdo\\uP\x8965\u026d\xc5\u07a0\x00\x00\u07d4Q\u028b\xd4\xdcdO\xacG\xafgUc\u0540J\r\xa2\x1e\xeb\x89*\xb7\xb2`\xff?\xd0\x00\x00\u07d4Q\xd2K\xc3so\x88\xddc\xb7\" &\x88f0\xb6\ub1cd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Q\u05cb\x17\x8dp~9n\x87\x10\x96\\OA\xb1\xa1\xd9\x17\x9d\x89\x05\xfe\xe2\"\x04\x1e4\x00\x00\u07d4Q\xe3/\x14\xf4\xca^(|\xda\xc0W\xa7y^\xa9\xe0C\x99S\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4Q\xe4?\xe0\xd2\\x(`\xaf\x81\xea\x89\xddy<\x13\xf0\u02f1\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4Q\xe7\xb5\\/\x98 \xee\xd78\x846\x1bPf\xa5\x9boE\u0189lk\x93[\x8b\xbd@\x00\x00\xe0\x94Q\xea\x1c\t4\xe3\xd0@\"\ud715\xa0\x87\xa1P\xefp^\x81\x8a\x01Tp\x81\xe7\"M \x00\x00\u07d4Q\xee\f\xca;\xcb\x10\xcd>\x987\"\xce\xd8I=\x92l\bf\x8965f3\xeb\xd8\xea\x00\x00\xe0\x94Q\xf4f:\xb4O\xf7\x93E\xf4'\xa0\xf6\xf8\xa6\u0225?\xf24\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4Q\xf5^\xf4~dV\xa4\x18\xab2\xb9\"\x1e\xd2}\xbaf\b\xee\x89\u3bb5sr@\xa0\x00\x00\xe0\x94Q\xf9\xc42\xa4\xe5\x9a\xc8b\x82\u05ad\xabL.\xb8\x91\x91`\xeb\x8ap;[\x89\u00e6\xe7@\x00\x00\u07d4R\x0ff\xa0\xe2e\u007f\xf0\xacA\x95\xf2\xf0d\xcf/\xa4\xb2BP\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4R\x10#T\xa6\xac\xa9]\x8a.\x86\xd5\u07bd\xa6\xdei4`v\x89lk\x93[\x8b\xbd@\x00\x00\u07d4R\x13\xf4Y\xe0x\xad:\xb9Z\t #\x9f\xcf\x163\xdc\x04\u0289\x8c\xf2\x18|*\xfb\x18\x80\x00\u07d4R\x15\x18;\x8f\x80\xa9\xbc\x03\xd2l\xe9\x12\a\x83*\r9\xe6 \x8965\u026d\xc5\u07a0\x00\x00\xe0\x94R!Cx\xb5@\x04\x05j|\xc0\x8c\x89\x13'y\x8a\u01b2H\x8a\x037\xfe_\xea\xf2\u0440\x00\x00\xe0\x94R##\xaa\xd7\x1d\xbc\x96\xd8Z\xf9\x0f\bK\x99\xc3\xf0\x9d\ucdca\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4R>\x14\r\xc8\x11\xb1\x86\xde\xe5\xd6\u020b\xf6\x8e\x90\xb8\xe0\x96\xfd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4R?mdi\x0f\xda\u0354(SY\x1b\xb0\xff \xd3em\x95\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4RO\xb2\x10R,^#\xbbg\u07ff\x8c&\xaaam\xa4\x99U\x8965b\xa6m4#\x80\x00\u07d4RU\xdci\x15ZE\xb9p\xc6\x04\xd3\x00G\xe2\xf50i\x0e\u007f\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4R`\xdcQ\xee\a\xbd\u06ab\xab\xb9\xeetK9<\u007fG\x93\xa6\x89\x01\xd8f_\xa5\xfaL\x00\x00\u07d4Rg\xf4\xd4\x12\x92\xf3p\x86<\x90\u05d3)i\x03\x846%\u01c9K\xe4\xe7&{j\xe0\x00\x00\u07d4Rk\xb53\xb7n \xc8\xee\x1e\xbf\x12?\x1e\x9f\xf4\x14\x8e@\xbe\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4Rl\xb0\x9c\u3b63g.\xec\x1d\xebF [\xe8\x9aKV>\x89\x85\xcaa[\xf9\xc0\x10\x00\x00\u07d4Rs\x8c\x90\xd8`\xe0L\xb1/I\x8d\x96\xfd\xb5\xbf6\xfc4\x0e\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4Rz\x8c\xa1&\x863\xa6\xc99\xc5\xde\x1b\x92\x9a\ue4ae\xac\x8d\x890\xca\x02O\x98{\x90\x00\x00\u07d4R\x81\x01\xceF\xb7 \xa2!M\u036ef\x18\xa51w\xff\xa3w\x89\x1b\x96\x12\xb9\xdc\x01\xae\x00\x00\xe0\x94R\x81s4s\xe0\r\x87\xf1\x1e\x99U\u5275\x9fJ\u008ez\x8a\x8b\xd6/\xf4\xee\xc5Y \x00\x00\u07d4R\x98\xab\x18*\x195\x9f\xfc\xec\xaf\xd7\u0475\xfa!-\xed\xe6\u0749\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4R\x9a\xa0\x02\u0196*:\x85E\x02\u007f\u0630_\"\xb5\xbf\x95d\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4R\x9e\x82O\xa0rX+@2h:\xc7\xee\xcc\x1c\x04\xb4\xca\xc1\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94R\xa5\xe4\xdeC\x93\xee\xcc\xf0X\x1a\xc1\x1bR\u0183\xc7n\xa1]\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4R\xb4%|\xf4\x1bn(\x87\x8dP\xd5{\x99\x91O\xfa\x89\x87:\x89\xd5\r\u026a,Aw\x00\x00\u07d4R\xb8\xa9Y&4\xf70\v|\\Y\xa34[\x83_\x01\xb9\\\x89lk\x93[\x8b\xbd@\x00\x00\u07d4R\xbd\u066fYx\x85\v\xc2A\x10q\x8b7#u\x9bC~Y\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4R\xcd @;\xa7\xed\xa6\xbc0z=c\xb5\x91\x1b\x81|\x12c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794R\u04c0Q\x1d\xf1\x9d^\u0080{\xbc\xb6vX\x1bg\xfd7\xa3\x88\xb9\xf6]\x00\xf6<\x00\x00\xe0\x94R\xe1s\x13P\xf9\x83\xcc,A\x89\x84/\xde\x06\x13\xfa\xd5\f\xe1\x8a\x02w\x01s8\xa3\n\xe0\x00\x00\u07d4R\xe4g\x832\x9av\x93\x01\xb1u\x00\x9d4gh\xf4\xc8~\xe4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4R\xf0X\xd4aG\xe9\x00m)\xbf,\t0J\xd1\xcd\xddn\x15\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4R\xf1T#2<$\xf1\x9a\xe2\xabg7\x17\"\x9d?t}\x9b\x897\xa04\xcb\xe8\xe3\xf3\x80\x00\u07d4R\xf8\xb5\t\xfe\xe1\xa8t\xabo\x9d\x876\u007f\xbe\xaf\x15\xac\x13\u007f\x8965\u026d\xc5\u07a0\x00\x00\u07d4R\xfbF\xac]\x00\xc3Q\x8b,:\x1c\x17}D/\x81eU_\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4S\x00w\xc9\xf7\xb9\a\xff\x9c\xec\fw\xa4\x1ap\xe9\x02\x9a\xddJ\x89lk\x93[\x8b\xbd@\x00\x00\u07d4S\x03\x19\xdb\n\x8f\x93\xe5\xbb}M\xbfH\x161O\xbe\xd86\x1b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4S\x04}\u022c\x90\x83\xd9\x06r\xe8\xb3G<\x10\f\xcd'\x83#\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4S\va\xe4/9Bm$\b\xd4\bR\xb9\xe3J\xb5\xeb\xeb\u0149\x0e~\xeb\xa3A\vt\x00\x00\u07d4S\x0f\xfa\u00fc4\x12\xe2\xec\x0e\xa4{y\x81\xc7p\xf5\xbb/5\x89\a?u\u0460\x85\xba\x00\x00\u07d4S\x17\xec\xb0#\x05,\xa7\xf5e+\xe2\xfa\x85L\xfeEc\xdfM\x89\x1b\x1a\xb3\x19\xf5\xecu\x00\x00\u07d4S\x19M\x8a\xfa>\x885\x02v~\xdb\xc3\x05\x86\xaf3\xb1\x14\u04c9lk\x93[\x8b\xbd@\x00\x00\u07d4S*}\xa0\xa5\xadt\aF\x8d;\xe8\xe0~i\xc7\xddd\xe8a\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4S-2\xb0\x0f0[\xcc$\xdc\xefV\x81}b/4\xfb,$\x89a\x94\x04\x9f0\xf7 \x00\x00\u07d4S4DX@\x82\xeb\xa6T\xe1\xad0\xe1Is\\o{\xa9\"\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4S8\xefp\xea\xc9\u075a\xf5\xa0P;^\xfa\xd1\x03\x9eg\xe7%\x89\x90\xf54`\x8ar\x88\x00\x00\xe0\x94S9oJ&\u00b4`D\x960lTB\xe7\xfc\xba'.6\x8a\x04?/\b\xd4\x0eZ\xfc\x00\x00\xe0\x94S:s\xa4\xa2\"\x8e\xee\x05\xc4\xff\xd7\x18\xbb\xf3\xf9\xc1\xb1)\xa7\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4S<\x06\x92\x8f\x19\u0429V\xcc(\x86k\xf6\xc8\xd8\xf4\x19\x1a\x94\x89\x0f\xd8\xc1C8\xe60\x00\x00\u07d4S@e6\x1c\xb8T\xfa\xc4+\xfb\\\x9f\xcd\xe0`J\xc9\x19\u0689lk\x93[\x8b\xbd@\x00\x00\u07d4SC\u007f\xec\xf3J\xb9\xd45\xf4\u07b8\xca\x18\x15\x19\xe2Y 5\x89\n1\x06+\xee\xedp\x00\x00\u07d4SR\x01\xa0\xa1\xd74\"\x80\x1fU\xde\xd4\u07ee\xe4\xfb\xaan;\x89\x02&!\x1fy\x15B\x80\x00\xe0\x94S`\x81\x05\xceK\x9e\x11\xf8k\xf4\x97\xff\xca;x\x96{_\x96\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4SnM\x80)\xb7?Uy\u0723>p\xb2N\xba\x89\xe1\x1d~\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4Sp\rS%MC\x0f\"x\x1aJv\xa4c\x93;]k\b\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94S\u007f\x9dM1\xefp\x83\x9d\x84\xb0\xd9\u0377+\x9a\xfe\xdb\xdf5\x8a\x0e\u04b5%\x84\x1a\xdf\xc0\x00\x00\xe0\x94S\x81D\x85\x03\xc0\xc7\x02T+\x1d\xe7\xcc_\xb5\xf6\xab\x1c\xf6\xa5\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94S\x94.yI\xd6x\x8b\xb7\x80\xa7\xe8\xa0y'\x81\xb1aK\x84\x8a\x03]\xebFhO\x10\xc8\x00\x00\u07d4S\x95\xa4E]\x95\xd1x\xb4S*\xa4r[\x19?\xfeQ)a\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94S\x98\x9e\xd30V?\xd5}\xfe\u027d4<7`\xb0y\x93\x90\x8a\x01P\x89N\x84\x9b9\x00\x00\x00\u07d4S\xa2Dg(\x95H\x0fJ+\x1c\xdf}\xa5\xe5\xa2B\xecM\xbc\x8965\u026d\xc5\u07a0\x00\x00\u07d4S\xa7\x14\xf9\x9f\xa0\x0f\xefu\x8e#\xa2\xe7F2m\xad$|\xa7\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4S\xaf2\xc2/\uf640?\x17\x8c\xf9\v\x80/\xb5q\xc6\x1c\xb9\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4S\xc0\xbb\u007f\u020e\xa4\"\xd2\xef~T\x0e-\x8f(\xb1\xbb\x81\x83\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94S\xc5\xfe\x01\x19\xe1\xe8Hd\f\xee0\xad\ua594\x0f*]\x8b\x8a\x04\x9a\xda_\xa8\xc1\f\x88\x00\x00\u07d4S\xc9\xec\xa4\ts\xf6;\xb5\x92{\xe0\xbcj\x8a\x8b\xe1\x95\x1ft\x89lk\x93[\x8b\xbd@\x00\x00\u07d4S\u0388\xe6lZ\xf2\U0009bf4fY*V\xa3\xd1_ l2\x89\a\xa2\x8c1\xcc6\x04\x00\x00\u07d4S\xce\xc6\u0200\x92\xf7V\xef\xe5o}\xb1\x12(\xa2\xdbE\xb1\"\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4S\xe3[\x12#\x1f\x19\xc3\xfdwL\x88\xfe\xc8\xcb\xee\xdf\x14\b\xb2\x89\x1b\xc1mgN\xc8\x00\x00\x00\u07d4S\xe4\xd9im\xcb?M{?p\u072aN\xec\xb7\x17\x82\xff\\\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4S\xfa\xf1e\xbe\x03\x1e\xc1\x830\xd9\xfc\xe5\xbd\x12\x81\xa1\xaf\b\u06c9\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4T\n\x18\x19\xbd|5\x86\x1ey\x18\x04\xe5\xfb\xb3\xbc\x97\u026b\xb1\x89N\xd7\xda\xc6B0 \x00\x00\xe0\x94T\f\a(\x02\x01N\xf0\xd5a4Z\xecH\x1e\x8e\x11\xcb5p\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94T\f\xf2=\xd9\\MU\x8a'\x9dw\x8d+75\xb3\x16A\x91\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4T\x10`\xfcX\xc7P\xc4\x05\x12\xf83i\xc0\xa63@\xc1\"\xb6\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4T\x13\xc9\u007f\xfaJn*{\xba\x89a\u071f\u03850\xa7\x87\u05c965\u026d\xc5\u07a0\x00\x00\u07d4T\x1d\xb2\n\x80\xcf;\x17\xf1b\x1f\x1b?\xf7\x9b\x88/P\xde\xf3\x8965\u026d\xc5\u07a0\x00\x00\u07d4T.\x80\x96\xba\xfb\x88\x16&\x06\x00.\x8c\x8a>\u0458\x14\xae\xac\x89lk\x93[\x8b\xbd@\x00\x00\u07d4T1\v:\xa8\x87\x03\xa7%\u07e5}\xe6\xe6F\x93Qd\x80,\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4T1\xb1\u0447Q\xb9\x8f\xc9\u220a\xc7u\x9f\x155\xa2\xdbG\x89lk\x93[\x8b\xbd@\x00\x00\u07d4T1\xcaB~ae\xa6D\xba\xe3&\xbd\tu\n\x17\x8ce\r\x89lk\x93[\x8b\xbd@\x00\x00\u07d4T5\xc6\xc1y3\x17\xd3,\xe1;\xbaLO\xfe\xb9s\xb7\x8a\u0709\r\x8ek\x1c\x12\x85\xef\x00\x00\xe0\x94T6)\xc9\\\xde\xf4(\xad7\xd4S\u02958\xa9\xf9\t\x00\xac\x8a\t(\x96R\x9b\xad\u0708\x00\x00\u07d4T9\x1bM\x17mGl\xea\x16N_\xb55\u0197\x00\xcb%5\x89\x05l\xd5_\xc6M\xfe\x00\x00\xe0\x94T:\x8c\x0e\xfb\x8b\xcd\x15\xc5C\u29a4\xf8\aYv1\xad\xef\x8a\x01?\x80\xe7\xe1O-D\x00\x00\u07d4T?\x8cgN$b\xd8\xd5\u06a0\xe8\x01\x95\xa8p\x8e\x11\xa2\x9e\x89\x03wX\x83;:z\x00\x00\xe0\x94TK[5\x1d\x1b\xc8.\x92\x97C\x99H\xcfHa\xda\u026e\x11\x8a\x04\xa8\x9fT\xef\x01!\xc0\x00\x00\u07d4TM\xdaB\x1d\xc1\xebs\xbb$\xe3\xe5j$\x80\x13\xb8|\x0fD\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4TW\\1\x14u\x1e\x14o\xfe\u00c7nE\xf2\x0e\xe8AJ\u07ba\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4T\xb4B\x9b\x18/\x03w\xbe~bi9\xc5\xdbd@\xf7]z\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4T\xbc\xb8\xe7\xf7<\xda=s\xf4\u04cb-\bG\xe6\x00\xba\r\xf8\x89:pAX\x82\xdf\x18\x00\x00\u07d4T\xc9>\x03\xa9\xb2\xe8\xe4\xc3g(5\xa9\xeev\xf9a[\xc1N\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4T\u0388'YV\xde\xf5\xf9E\x8e;\x95\xde\xca\xcdH@!\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4T\xdb^\x06\xb4\x81]1\xcbV\xa8q\x9b\xa3:\xf2\xd7>rR\x89$R\x1e*0\x17\xb8\x00\x00\xe0\x94T\xe0\x12\x83\u030b8E8\xdddgp\xb3W\xc9`\xd6\xca\u034a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4T\xecs\x00\xb8\x1a\xc8C3\xed\x1b\x03<\xd5\u05e39r\xe24\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4T\xfe\xbc\xce \xfez\x90\x98\xa7U\xbd\x90\x98\x86\x02\xa4\x8c\b\x9e\x89\"\xb1\xc8\xc1\"z\x00\x00\x00\u07d4U\n\xad\xae\x12!\xb0z\xfe\xa3\x9f\xba.\xd6.\x05\u5df5\xf9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4U\f0o\x81\xef]\x95\x80\xc0l\xb1\xab \x1b\x95\xc7H\xa6\x91\x89$\x17\xd4\xc4p\xbf\x14\x00\x00\xe0\x94U\x19\x99\xdd\xd2\x05V3'\xb9\xb50xZ\xcf\xf9\xbcs\xa4\xba\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4U\x1ew\x84w\x8e\xf8\xe0H\xe4\x95\xdfI\xf2aO\x84\xa4\xf1\u0709 \x86\xac5\x10R`\x00\x00\xe0\x94U)\x83\na\xc1\xf1<\x19~U\v\xed\xdf\u05bd\x19\\\x9d\x02\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4U)\x87\xf0e\x1b\x91[.\x1eS(\xc1!\x96\rK\xddj\xf4\x89a\t=|,m8\x00\x00\u07d4U;k\x1cW\x05\x0e\x88\xcf\f1\x06{\x8dL\xd1\xff\x80\xcb\t\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4U?7\xd9$fU\x0e\x9f\xd7u\xaet6-\xf00\x17\x912\x89lk\x93[\x8b\xbd@\x00\x00\u07d4UC6\xeeN\xa1U\xf9\xf2O\x87\xbc\xa9\xcar\xe2S\xe1,\u0489\x05k\xc7^-c\x10\x00\x00\u0794UC\xddm\x16\x9e\xec\x8a!;\xbfz\x8a\xf9\xff\xd1]O\xf7Y\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4UG\xfd\xb4\xae\x11\x95>\x01)+x\a\xfa\x92#\xd0\xe4`j\x89\x05]\x11}\xcb\x1d&\x00\x00\u07d4UR\xf4\xb3\xed>\x1d\xa7\x9a/x\xbb\x13\xe8\xaeZh\xa9\xdf;\x8965\u026d\xc5\u07a0\x00\x00\u07d4U\\\xa9\xf0\\\xc14\xabT\xae\x9b\xea\x1c?\xf8z\xa8Q\x98\u0289\x05k\xc7^-c\x10\x00\x00\xe0\x94U]\x8d<\xe1y\x8a\u0290'T\xf1d\xb8\xbe*\x022\x9cl\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4U]\xf1\x93\x90\xc1m\x01)\x87r\xba\xe8\xbc:\x11R\x19\x9c\xbd\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4U^\xbe\x84\u06a4+\xa2V\xeax\x91\x05\xce\u0136\x93\xf1/\x18\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94U\u007f^e\xe0\xda3\x99\x82\x19\xadN\x99W\x05E\xb2\xa9\xd5\x11\x8a\x02U\x9c\xbb\x98XB@\x00\x00\u07d4U\x83` h\x83\xdd\x1bmJYc\x9eV)\xd0\xf0\xc6u\u0409lk\x93[\x8b\xbd@\x00\x00\u07d4U\x84B0P\xe3\xc2\x05\x1f\v\xbd\x8fD\xbdm\xbc'\xec\xb6,\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4U\x85)CI)p\xf8\xd6)\xa1Sf\xcd\xda\x06\xa9OE\x13\x89lk\x93[\x8b\xbd@\x00\x00\u0794U\x86d\x86\xec\x16\x8fy\xdb\xe0\u1af1\x88d\u0649\x91\xae,\x88\xdfn\xb0\xb2\xd3\xca\x00\x00\u07d4U\x8cTd\x9a\x8an\x94r+\xd6\xd2\x1d\x14qOqx\x054\x89lk\x93[\x8b\xbd@\x00\x00\u07d4U\x91\x940O\x14\xb1\xb9:\xfeDO\x06$\xe0S\xc2:\x00\t\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4U\x93\xc9\u0536ds\x0f\xd9<\xa6\x01Q\xc2\\.\xae\xd9<;\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4U\x97\x06\xc32\xd2\ay\xc4_\x8am\x04ji\x91Y\xb7I!\x89\x14\x9bD.\x85\xa3\u03c0\x00\u07d4U\x98\xb3\xa7\x9aH\xf3+\x1f_\xc9\x15\xb8{d]\x80]\x1a\xfe\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4U\xa3\xdfW\xb7\xaa\xec\x16\xa1b\xfdS\x16\xf3[\xec\b(!\u03c9j\xcb=\xf2~\x1f\x88\x00\x00\u07d4U\xa4\xca\xc0\u02cbX-\x9f\xef8\xc5\xc9\xff\xf9\xbdS\t=\x1f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4U\xa6\x1b\x10\x94\x80\xb5\xb2\xc4\xfc\xfd\xef\x92\xd9\x05\x84\x16\f\r5\x89\x02lVM+S\xf6\x00\x00\u07d4U\xaa]1>\xbb\bM\xa0\xe7\x80\x10\x91\u2792\xc5\xde\u00ea\x89lk\x93[\x8b\xbd@\x00\x00\u07d4U\xab\x99\xb0\xe0\xe5]{\xb8t\xb7\xcf\xe84\xdec\x1c\x97\xec#\x897\xe9\x8c\xe3h\x99\xe4\x00\x00\u07d4U\xaf\t/\x94\xbajy\x91\x8b\f\xf99\xea\xb3\xf0\x1b?Q\u01c9\b \xd5\xe3\x95v\x12\x00\x00\u07d4U\xc5dfAf\xa1\xed\xf3\x91>\x01i\xf1\xcdE\x1f\xdb]\f\x89\x82\x17\xeaIP\x8el\x00\x00\xe0\x94U\xcaj\xbey\xea$\x97\xf4o\u06f804`\x10\xfeF\x9c\xbe\x8a\x016\x9f\xb9a(\xacH\x00\x00\u07d4U\xca\xffK\xba\x04\xd2 \u0265\xd2\x01\x86r\xec\x85\xe3\x1e\xf8>\x89lk\x93[\x8b\xbd@\x00\x00\u07d4U\xd0W\xbc\xc0K\xd0\xf4\xaf\x96BQ:\xa5\t\v\xb3\xff\x93\xfe\x89;\xfeE,\x8e\xddL\x00\x00\u07d4U\xd4.\xb4\x95\xbfF\xa64\x99{_.\xa3b\x81I\x18\u2c09\x05\xc0\xd2e\xb5\xb2\xa8\x00\x00\u07d4U\u069d\xcd\xcaa\xcb\xfe\x1f\x13<{\xce\xfc\x86{\x9c\x81\"\xf9\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4U\xe2 \x87bb\xc2\x18\xafOVxG\x98\xc7\xe5]\xa0\x9e\x91\x89\a=\x99\xc1VE\xd3\x00\x00\u07d4U\xfd\b\u0440d\xbd ,\x0e\xc3\xd2\xcc\xe0\xce\v\x9d\x16\x9cM\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4V\x00s\nU\xf6\xb2\x0e\xbd$\x81\x1f\xaa=\xe9m\x16b\xab\xab\x89e\xea=\xb7UF`\x00\x00\u07d4V\x03$\x1e\xb8\xf0\x8fr\x1e4\x8c\x9d\x9a\xd9/H\u342a$\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4V\x056yJ\x9e+\x00I\xd1\x023\xc4\x1a\xdc_A\x8a&J\x8965\u026d\xc5\u07a0\x00\x00\u07d4V\aY\x00Y\xa9\xfe\xc1\x88\x11I\xa4K6\x94\x9a\xef\x85\xd5`\x89lk\x93[\x8b\xbd@\x00\x00\u07d4V\v\xec\xdfR\xb7\x1f=\x88'\xd9'a\x0f\x1a\x98\x0f3qo\x89\x17GMp_V\u0400\x00\xe0\x94V\r\xa3~\x95m\x86/\x81\xa7_\u0540\xa7\x13\\\x1b$cR\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94V\x0f\xc0\x8d\a\x9f\x04~\xd8\xd7\xdfuU\x1a\xa55\x01\xf5p\x13\x8a\x01\x9b\xff/\xf5yh\xc0\x00\x00\u07d4V\x1b\xe9)\x9b>k>c\xb7\x9b\t\x16\x9d\x1a\x94\x8a\xe6\xdb\x01\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94V \xe3\xedy-/\x185\xfe_UA}Q\x11F\fj\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4V \xf4m\x14Q\xc25=bC\xa5\u0534'\x13\v\xe2\xd4\a\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94V!\x05\xe8+\t\x975\xdeI\xf6&\x92\u0307\xcd8\xa8\xed\u034a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94V*\x8d\u02fe\xee\xf7\xb3`h]'0;\u059e\tJ\xcc\xf6\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4V+\xce\u04ca\xb2\xabl\b\x0f;\x05A\xb8Enp\x82K?\x89\"\xca5\x87\xcfN\xb0\x00\x00\xe0\x94V+\xe9Z\xba\x17\xc57\x1f\u2e82\x87\x99\xb1\xf5]!w\u058a\b\x16\xd3~\x87\xb9\xd1\xe0\x00\x00\u07d4V/\x16\u05da\xbf\xce\u00d4>4\xb2\x0f\x05\xf9{\xdf\u0366\x05\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4V7=\xaa\xb4c\x16\xfd~\x15v\xc6\x1ej\xff\xcbeY\xdd\u05c9\v\xacq]\x14l\x9e\x00\x00\u07d4V9v8\xbb<\xeb\xf1\xf6 byK^\xb9B\xf9\x16\x17\x1d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4V:\x03\xab\x9cV\xb6\x00\xf6\xd2[f\f!\xe1c5Qzu\x8965\u026d\xc5\u07a0\x00\x00\u07d4V<\xb8\x80<\x1d2\xa2['\xb6A\x14\x85+\xd0M\x9c \u0349\v\x14\x9e\xad\n\xd9\xd8\x00\x00\u07d4VXc\x91\x04\fW\xee\xc6\xf5\xaf\xfd\x8c\u052b\xde\x10\xb5\n\u0309\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4Vl\x10\xd68\u8e0bG\xd6\xe6\xa4\x14Iz\xfd\xd0\x06\x00\u0509\x05k9Bc\xa4\f\x00\x00\u07d4Vl(\xe3L8\b\xd9vo\xe8B\x1e\xbfO+\x1cO}w\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4V\x8d\xf3\x18Vi\x9b\xb5\xac\xfc\x1f\xe1\u0580\u07d9`\xcaCY\x89J\xcfUR\xf3\xb2I\x80\x00\u07d4V\x91\xdd/gE\xf2\x0e\"\xd2\xe1\u0479U\xaa)\x03\xd6VV\x89j\xc5\xc6-\x94\x86\a\x00\x00\u07d4V\xa1\xd6\r@\xf5\u007f0\x8e\xeb\xf0\x87\xde\xe3\xb3\u007f\x1e|,\xba\x89>\u072e\xc8-\x06\xf8\x00\x00\u07d4V\xac \xd6;\xd8\x03Y\\\xec\x03m\xa7\xed\x1d\xc6n\n\x9e\a\x89\x03w*S\xcc\xdce\x80\x00\u07d4V\xb6\xc2=\xd2\uc434r\x8f;\xb2\xe7d\xc3\xc5\f\x85\xf1D\x8965\u026d\xc5\u07a0\x00\x00\u07d4V\xdf\x05\xba\xd4l?\x00\xaeGn\xcf\x01{\xb8\xc8w8?\xf1\x89\n\xb1]\xaa\xefp@\x00\x00\u07d4V\xee\x19\u007fK\xbf\x9f\x1b\x06b\xe4\x1c+\xbd\x9a\xa1\xf7\x99\xe8F\x8965\u026d\xc5\u07a0\x00\x00\u07d4V\xf4\x93\xa3\xd1\b\xaa\xa2\u044d\x98\x92/\x8e\xfe\x16b\u03f7=\x89m\x81!\xa1\x94\xd1\x10\x00\x00\u07d4V\xfc\x1a{\xad@G#|\xe1\x16\x14b\x96#\x8e\a\x8f\x93\xad\x89\t\xa6?\b\xeac\x88\x00\x00\u07d4V\xfe\xbf\x9e\x10\x03\xaf\x15\xb1\xbdI\a\xec\b\x9aJ\x1b\x91\xd2h\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4W\x17\u0313\x01Q\x1dJ\x81\xb9\xf5\x83\x14\x8b\xee\xd3\xd3\u0303\t\x89\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\u07d4W\x17\xf2\xd8\xf1\x8f\xfc\xc0\xe5\xfe$}:B\x19\x03|:d\x9c\x89\u063beI\xb0+\xb8\x00\x00\u07d4W\x19P\xea,\x90\xc1B}\x93\x9da\xb4\xf2\xdeL\xf1\u03ff\xb0\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4W\x19\xf4\x9br\r\xa6\x88V\xf4\xb9\xe7\b\xf2VE\xbd\xbcKA\x89\"\xb1\xc8\xc1\"z\x00\x00\x00\u07d4W*\xc1\xab\xa0\xde#\xaeA\xa7\xca\xe1\xdc\bB\u062b\xfc\x10;\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94W-\xd8\xcd?\xe3\x99\xd1\xd0\xec(\x121\xb7\xce\xfc \xb9\u4eca\x023\xc8\xfeBp>\x80\x00\x00\xe0\x94WI!\x83\x8c\xc7}l\x98\xb1}\x90::\xe0\xee\r\xa9[\u040a\vS(\x17\x8a\xd0\xf2\xa0\x00\x00\u07d4WJ\xd95S\x90\u421e\xf4*\xcd\x13\x8b*'\xe7\x8c\x00\xae\x89Tg\xb72\xa9\x134\x00\x00\u07d4WM\xe1\xb3\xf3\x8d\x91XF\xae7\x18VJZ\xda \xc2\xf3\xed\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94W\\\x00\u0081\x82\x10\u0085U\xa0\xff)\x01\x02\x89\xd3\xf8#\t\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94Ws\xb6\x02g!\xa1\xdd\x04\xb7\x82\x8c\xd6+Y\x1b\xfb4SL\x8a\x05\xb7\xacES\xdez\xe0\x00\x00\xe0\x94WwD\x1c\x83\xe0?\v\xe8\xdd4\v\xdechP\x84|b\v\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4Wx\xff\u071b\x94\u0165\x9e\"N\xb9e\xb6\u0790\xf2\"\xd1p\x89\x12-\u007f\xf3f\x03\xfc\x00\x00\u07d4Wz\xee\xe8\u053c\b\xfc\x97\xab\x15n\xd5\u007f\xb9p\x92Sf\xbe\x89\x12\r\xf1\x14rX\xbf\x00\x00\u07d4W{-\a\xe9\xcfRJ\x18\u04c9\x15Vak\x96\x06g\x00\x00\u07d4W\xd5\xfd\x0e=0I3\x0f\xfc\xdc\xd0 Ei\x17e{\xa2\u0689k\xf2\x01\x95\xf5T\xd4\x00\x00\u07d4W\u0754q\xcb\xfa&'\t\xf5\U00106f37t\xc5\xf5'\xb8\xf8\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4W\xdf#\xbe\xbd\xc6^\xb7_\ub732\xfa\xd1\xc0si++\xaf\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4X\x00\u03410\x83\x9e\x94I]-\x84\x15\xa8\xea,\x90\xe0\xc5\u02c9\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94X\x03\xe6\x8b4\xda\x12\x1a\xef\b\xb6\x02\xba\u06ef\xb4\xd1$\x81\u028a\x03\xcf\xc8.7\xe9\xa7@\x00\x00\xe0\x94X\x16\xc2hww\xb6\xd7\u04a2C-Y\xa4\x1f\xa0Y\xe3\xa4\x06\x8a\x1cO\xe4:\xdb\n^\x90\x00\x00\u07d4X\x1a:\xf2\x97\xef\xa4Cj)\xaf\x00r\x92\x9a\xbf\x98&\xf5\x8b\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94X\x1b\x9f\xd6\xea\xe3r\xf3P\x1fB\xeb\x96\x19\xee\xc8 \xb7\x8a\x84\x8a\x04+\xe2\xc0\f\xa5;\x8d\x80\x00\u07d4X\x1b\xdf\x1b\xb2v\xdb\u0746\xae\xdc\xdb9z\x01\xef\xc0\xe0\f[\x8965\u026d\xc5\u07a0\x00\x00\u07d4X\x1f4\xb5#\xe5\xb4\x1c\t\xc8|)\x8e)\x9c\xbc\x0e)\xd0f\x89=X3\xaa\xfd9u\x80\x00\xe0\x94X$\xa7\xe2(8'q40\x8c_KP\u06b6^C\xbb1\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4X+pf\x9c\x97\xaa\xb7\u0581H\xd8\xd4\xe9\x04\x11\xe2\x81\rV\x8965f3\xeb\xd8\xea\x00\x00\u07d4X.|\xc4o\x1d{Nn\x9d\x95\x86\x8b\xfd7\x05s\x17\x8fL\x89lk\x93[\x8b\xbd@\x00\x00\u07d4X>\x83\xbaU\xe6~\x13\xe0\xe7o\x83\x92\xd8s\xcd!\xfb\xf7\x98\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4Xi\xfb\x86}q\xf18\u007f\x86;i\x8d\t\xfd\xfb\x87\u011b\\\x89\u01bb\xf8X\xb3\x16\b\x00\x00\u07d4X}hI\xb1h\xf6\xc33+z\xba\xe7\xeblB\xc3\u007fH\xbf\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4X\x87\xdcj3\xdf\xedZ\xc1\xed\xef\xe3^\xf9\x1a!b1\xac\x96\x89\r\x8drkqw\xa8\x00\x00\xe0\x94X\x8e\u0650\xa2\xaf\xf4J\x94\x10]X\xc3\x05%w5\xc8h\xac\x8a\x03h\xc8b:\x8bM\x10\x00\x00\u07d4X\xae-\xdc_L\x8a\u0697\xe0l\x00\x86\x17\x17g\xc4#\xf5\u05c9WG=\x05\u06ba\xe8\x00\x00\u07d4X\xae\xd6gJ\xff\xd9\xf6B3'*W\x8d\xd98k\x99\xc2c\x89\xb8Pz\x82\a( \x00\x00\xe0\x94X\xb8\b\xa6[Q\xe63\x89i\xaf\xb9^\xc7\a5\xe4Q\xd5&\x8a\bxK\xc1\xb9\x83z8\x00\x00\u07d4X\xb8\xae\x8fc\xef5\xed\ab\xf0\xb6#=J\xc1Nd\xb6M\x89lk\x93[\x8b\xbd@\x00\x00\u07d4X\xba\x15ie\x0e[\xbb\xb2\x1d5\xd3\xe1u\xc0\u05b0\xc6Q\xa9\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4X\xc5U\xbc)<\xdb\x16\xc66.\xd9z\xe9U\v\x92\xea\x18\x0e\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4X\xc6P\xce\xd4\v\xb6VA\xb8\xe8\xa9$\xa09\xde\xf4hT\u07c9\x01\x00\xbd3\xfb\x98\xba\x00\x00\u07d4X\xc9\aT\xd2\xf2\n\x1c\xb1\xdd3\x06%\xe0KE\xfaa\x9d\\\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94X\xe2\xf1\x12#\xfc\x827\xf6\x9d\x99\xc6(\x9c\x14\x8c\x06\x04\xf7B\x8a\x05\x15\n\xe8J\x8c\xdf\x00\x00\x00\u07d4X\xe5T\xaf=\x87b\x96 \xdaa\xd58\xc7\xf5\xb4\xb5LJ\xfe\x89FP\x9diE4r\x80\x00\u07d4X\xe5\xc9\xe3D\xc8\x06e\r\xac\xfc\x90M3\xed\xbaQ\a\xb0\u0789\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4X\xe6a\u043as\xd6\xcf$\t\x9aUb\xb8\b\xf7\xb3g;h\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94X\xf0[&%`P<\xa7a\xc6\x18\x90\xa4\x03_Lsr\x80\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4X\xfb\x94sd\xe7iWe6\x1e\xbb\x1e\x80\x1f\xfb\x8b\x95\xe6\u0409\n\u05ce\xbcZ\xc6 \x00\x00\u07d4Y\x01\x81\xd4E\x00{\u0407Z\xaf\x06\x1c\x8dQ\x159\x00\x83j\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Y\x02\xe4J\xf7i\xa8rF\xa2\x1e\a\x9c\b\xbf6\xb0n\xfe\xb3\x8965\u026d\xc5\u07a0\x00\x00\u07d4Y\n\xcb\xda7)\f\r>\xc8O\xc2\x00\rv\x97\xf9\xa4\xb1]\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94Y\f\xcbY\x11\xcfx\xf6\xf6\"\xf55\xc4t7_J\x12\xcf\u03ca\x04<3\xc1\x93ud\x80\x00\x00\u07d4Y\x10\x10m\xeb\u0491\xa1\u0340\xb0\xfb\xbb\x8d\x8d\x9e\x93\xa7\xcc\x1e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Y\x16\x17I\xfe\xdc\xf1\xc7!\xf2 -\x13\xad\xe2\xab\xcfF\v=\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94Y\x1b\xef1q\xd1\u0155w\x17\xa4\xe9\x8d\x17\xeb\x14,!NV\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4Y <\xc3u\x99\xb6H1*|\xc9\xe0m\xac\xb5\x89\xa9\xaej\x89\b\x0fyq\xb6@\x0e\x80\x00\u07d4Y&\x81q\xb83\xe0\xaa\x13\xc5KR\xcc\xc0B.O\xa0:\ub262\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94Y'w&\x1e;\xd8R\u010e\u0295\xb3\xa4L[\u007f-B,\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4Y0Dg\x0f\xae\xff\x00\xa5[Z\xe0Q\xeb{\xe8p\xb1\x16\x94\x89\a?u\u0460\x85\xba\x00\x00\xe0\x94Y;E\xa1\x86J\xc5\xc7\xe8\xf0\u02ae\xba\r\x87<\xd5\xd1\x13\xb2\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4Y_^\xdajV\xf1N%\xe0\xc6\xf3\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4Z\x1a3ib\xd6\xe0\xc601\u0303\u01a5\u01a6\xf4G\x8e\u02c965\u026d\xc5\u07a0\x00\x00\u07d4Z\x1d--\x1dR\x03\x04\xb6 \x88IW\x047\xeb0\x91\xbb\x9f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4Z&s1\xfa\xcb&-\xaa\xec\xd9\xddc\xa9p\f_RY\u07c9\x05k\xc7^-c\x10\x00\x00\xe0\x94Z(WU9\x1e\x91NX\x02_\xaaH\xcch_O\xd4\xf5\xb8\x8a\x05\x81v{\xa6\x18\x9c@\x00\x00\u07d4Z)\x16\xb8\xd2\xe8\xcc\x12\xe2\a\xabFMC>#p\xd8#\u0649lk\x93[\x8b\xbd@\x00\x00\u07d4Z+\x1c\x85:\xeb(\xc4U9\xafv\xa0\n\xc2\u0628$(\x96\x89\x01Z\xf1\u05cbX\xc4\x00\x00\u07d4Z-\xaa\xb2\\1\xa6\x1a\x92\xa4\xc8,\x99%\xa1\xd2\xefXX^\x89\f8\r\xa9\u01d5\f\x00\x00\u07d4Z0\xfe\xac7\xac\x9fr\u05f4\xaf\x0f+\xc79R\xc7O\xd5\u00c9lk\x93[\x8b\xbd@\x00\x00\u07d4ZTh\xfa\\\xa2&\xc7S.\xcf\x06\xe1\xbc\x1cE\"]~\u0249g\x8a\x93 b\xe4\x18\x00\x00\u07d4ZVR\x857JI\xee\xddPL\x95}Q\bt\xd0\x04U\xbc\x89\x05k\xc7^-c\x10\x00\x00\u07d4Z^\xe8\xe9\xbb\x0e\x8a\xb2\xfe\xcbK3\u0494x\xbeP\xbb\xd4K\x89*\x11)\u0413g \x00\x00\xe0\x94Z_\x85\b\xda\x0e\xbe\xbb\x90\xbe\x903\xbdM\x9e'A\x05\xae\x00\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4Z`q\xbc\xeb\xfc\xbaJ\xb5\u007fM\xb9o\u01e6\x8b\xec\xe2\xba[\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Z`\xc9$\x16(s\xfc~\xa4\xda\u007f\x97.5\x01g7`1\x89\x04\x87\xf2w\xa8\x85y\x80\x00\u07d4Zf\x86\xb0\xf1~\a\xed\xfcY\xb7Y\xc7}[\xef\x16M8y\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4Zp\x10o \xd6?\x87Re\xe4\x8e\r5\xf0\x0e\x17\xd0+\u0249\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794Zt\xbab\xe7\xc8\x1a4t\xe2}\x89O\xed3\xdd$\xad\x95\xfe\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94Zw5\x00}p\xb0hD\u0699\x01\xcd\xfa\xdb\x11\xa2X,/\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4Z\x82\xf9l\u0537\xe2\xd9=\x10\xf3\x18]\xc8\xf4=Ku\xaai\x89lc?\xba\xb9\x8c\x04\x00\x00\u07d4Z\x87\xf04\xe6\xf6\x8fNt\xff\xe6\fd\x81\x946\x03l\xf7\u05c9\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94Z\x89\x11U\xf5\x0eB\aCt\xc79\xba\xad\xf7\xdf&Q\x15:\x8a\x01\x02\xdao\xd0\xf7:<\x00\x00\u07d4Z\x9c\x8bi\xfcaMiVI\x99\xb0\r\xcbB\xdbg\xf9~\x90\x89\xb9\xe6\x15\xab\xad:w\x80\x00\xe0\x94Z\xaf\x1c1%Jn\x00_\xba\u007fZ\xb0\xecy\xd7\xfc+c\x0e\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4Z\xb1\xa5aSH\x00\x1c|w]\xc7WHf\x9b\x8b\xe4\xde\x14\x89%jr\xfb)\xe6\x9c\x00\x00\xe1\x94Z\xbf\xec%\xf7L\u06047c\x1aw1\x90i2wcV\xf9\x8b\t\xd8<\xc0\u07e1\x11w\xff\x80\x00\u07d4Z\u0090\x8b\x0f9\x8c\r\xf5\xba\xc2\xcb\x13\xcas\x14\xfb\xa8\xfa=\x89\n\xd4\xc81j\v\f\x00\x00\xe0\x94Z\u025a\u05c1j\xe9\x02\x0f\xf8\xad\xf7\x9f\xa9\x86\x9b|\xeaf\x01\x8a\x04ri\x8bA;C \x00\x00\u07d4Z\xd1,^\xd4\xfa\x82~!P\u03e0\u058c\n\xa3{\x17i\xb8\x89+^:\xf1k\x18\x80\x00\x00\xe0\x94Z\xd5\xe4 uV\x13\x88o5\xaaV\xac@>\xeb\xdf\xe4\xb0\u040a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4Z\xdew\xfd\x81\xc2\\\n\xf7\x13\xb1\a\x02v\x8c\x1e\xb2\xf9u\xe7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4Z\xe6N\x85;\xa0\xa5\x12\x82\u02cd\xb5.Aa^|\x9fs?\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Z\xed\x0el\xfe\x95\xf9\u0580\xc7dr\xa8\x1a+h\n\u007f\x93\xe2\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4Z\xef\x16\xa2&\xddh\a\x1f$\x83\xe1\xdaBY\x83\x19\xf6\x9b,\x89lk\x93[\x8b\xbd@\x00\x00\u07d4Z\xf4j%\xac\t\xcbsakS\xb1O\xb4/\xf0\xa5\x1c\u0772\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4Z\xf7\xc0r\xb2\u016c\xd7\x1cv\xad\xdc\xceS\\\xf7\xf8\xf95\x85\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94Z\xfd\xa9@\\\x8e\x976QEt\u0692\x8d\xe6tV\x01\t\x18\x8a\x01E\xb8\xb0#\x9aF\x92\x00\x00\u07d4[\x06\xd1\xe6\x93\f\x10Ti+y\xe3\xdb\xe6\xec\xceS\x96d \x89\v\"\u007fc\xbe\x81<\x00\x00\u07d4[%\xca\xe8m\xca\xfa*`\xe7r61\xfc_\xa4\x9c\x1a\xd8}\x89\x87\fXQ\x0e\x85 \x00\x00\u07d4[(|~sB\x99\xe7'bo\x93\xfb\x11\x87\xa6\rPW\xfe\x89\x05|\xd94\xa9\x14\xcb\x00\x00\u07d4[)\f\x01\x96|\x81.M\xc4\xc9\v\x17L\x1b@\x15\xba\xe7\x1e\x89\b \xeb4\x8dR\xb9\x00\x00\u07d4[+d\xe9\xc0X\u30a8\xb2\x99\"N\xec\xaa\x16\xe0\x9c\x8d\x92\x89\b\xbaR\xe6\xfcE\xe4\x00\x00\xe0\x94[./\x16\x18U.\xab\r\xb9\x8a\xddUc|)Q\xf1\xfb\x19\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4[0`\x8cg\x8e\x1a\xc4d\xa8\x99L;3\xe5\xcd\xf3Iq\x12\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4[36\x96\xe0L\xca\x16\x92\xe7\x19\x86W\x9c\x92\rk)\x16\xf9\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94[C\rw\x96\x96\xa3e?\xc6\x0et\xfb\u02ec\xf6\xb9\u00ba\xf1\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4[Cse\xae:\x9a/\xf9|h\xe6\xf9\nv \x18\x8c}\x19\x89l\x87T\xc8\xf3\f\b\x00\x00\u07d4[I\xaf\xcduDx8\xf6\xe7\xce\u068d!w}O\xc1\xc3\xc0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4[L\f`\xf1\x0e\u0489K\xdbB\xd9\xdd\x1d!\x05\x87\x81\n\r\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4[N\xa1m\xb6\x80\x9b\x03R\u0536\xe8\x1c9\x13\xf7jQ\xbb2\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4[[\xe0\xd8\xc6rv\xba\xab\xd8\xed\xb3\rH\xeaud\v\x8b)\x89,\xb1\xf5_\xb7\xbe\x10\x00\x00\u07d4[]Qp)2\x15b\x11\x1bC\bm\v\x045\x91\x10\x9ap\x89\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\xe0\x94[]\x8c\x8e\xedl\x85\xac!Va\xde\x02fv\x82?\xaa\n\f\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4[mU\xf6q)g@\\e\x91)\xf4\xb1\xde\t\xac\xf2\xcb{\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4[p\u011c\u024b=\xf3\xfb\xe2\xb1Y\u007f\\\x1bcG\xa3\x88\xb7\x894\x95tD\xb8@\xe8\x00\x00\u07d4[sn\xb1\x83Sb\x9b\u0796v\xda\xdd\x16P4\xce^\xcch\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4[u\x9f\xa1\x10\xa3\x1c\x88F\x9fT\xd4K\xa3\x03\xd5}\xd3\xe1\x0f\x89[F\xdd/\x0e\xa3\xb8\x00\x00\u07d4[w\x84\xca\xea\x01y\x9c\xa3\x02'\x82vg\xce |\\\xbcv\x89lk\x93[\x8b\xbd@\x00\x00\u07d4[x\xec\xa2\u007f\xbd\xeao&\xbe\xfb\xa8\x97+)^x\x146K\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94[\x80\v\xfd\x1b>\u0525}\x87Z\xed&\xd4/\x1aw\b\xd7*\x8a\x01Z\x82\xd1\u057b\x88\xe0\x00\x00\u07d4[\x85\xe6\x0e*\xf0TO/\x01\xc6N 2\x90\x0e\xbd8\xa3\u01c9lk\x93[\x8b\xbd@\x00\x00\u07d4[\xa2\xc6\xc3]\xfa\xec)h&Y\x19\x04\xd5DFJ\xea\xbd^\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94[\xafmt\x96 \x80>\x83H\xaf7\x10\xe5\xc4\xfb\xf2\x0f\u0214\x8a\x01\x0f@\x02a]\xfe\x90\x00\x00\u07d4[\xc1\xf9U\a\xb1\x01\x86B\xe4\\\xd9\xc0\xe2'3\xb9\xb1\xa3&\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94[\xd25GG\u007fm\t\u05f2\xa0\x05\xc5\xeee\fQ\fV\u05ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4[\xd2J\xac6\x12\xb2\f`\x9e\xb4gy\xbf\x95i\x84\a\xc5|\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4[\u0586-Q}M\xe4U\x9dN\xec\n\x06\xca\xd0^/\x94n\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4[\xe0EQ*\x02n?\x1c\xeb\xfdZ~\xc0\xcf\xc3o-\xc1k\x89\x06\x81U\xa46v\xe0\x00\x00\xe0\x94[\xf9\xf2\"nZ\xea\xcf\x1d\x80\xae\nY\xc6\xe3\x808\xbc\x8d\xb5\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4[\xfa\xfe\x97\xb1\xdd\x1dq+\xe8mA\xdfy\x89SE\x87Z\x87\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\\\x0f.Q7\x8fk\r{\xabas1X\vn9\xad<\xa5\x8a\x02\bj\xc3Q\x05&\x00\x00\x00\u07d4\\)\xf9\xe9\xa5#\xc1\xf8f\x94H\xb5\\H\xcb\xd4|%\xe6\x10\x894F\xa0\xda\xd0L\xb0\x00\x00\xe0\x94\\0\x8b\xacHW\xd3;\xae\xa0t\xf3\x95m6!\xd9\xfa(\xe1\x8a\x01\x0f\b\xed\xa8\xe5U\t\x80\x00\u07d4\\1*V\u01c4\xb1\"\t\x9bvM\x05\x9c!\xec\xe9^\x84\u0289\x05&c\u032b\x1e\x1c\x00\x00\u07d4\\1\x99m\xca\xc0\x15\xf9\xbe\x98[a\x1fF\x870\xef$M\x90\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\\24W\xe1\x87v\x1a\x82v\xe3Y\xb7\xb7\xaf?;n=\xf6\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\\<\x1cd[\x91uC\x11;>l\x1c\x05M\xa1\xfet+\x9a\x89+^:\xf1k\x18\x80\x00\x00\u0794\\=\x19D\x1d\x19l\xb4Cf \xfc\xad\u007f\xbby\xb2\x9ex\x88\xc6s\xce<@\x16\x00\x00\u07d4\\?V\u007f\xaf\xf7\xba\u0475\x12\x00\"\xe8\xcb\u02a8+I\x17\xb3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\\Ch\x91\x8a\xced\t\u01de\u0280\u036a\xe49\x1d+bN\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\\FA\x97y\x1c\x8a=\xa3\xc9%Co'z\xb1;\xf2\xfa\xa2\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\\H\x81\x16\\\xb4+\xb8.\x979l\x8e\xf4J\xdb\xf1s\xfb\x99\x89\x05\xfe\xe2\"\x04\x1e4\x00\x00\xe0\x94\\H\x92\x90z\a \xdfo\xd3A>c\xffv}k9\x80#\x8a\x02\xcb\x00\x9f\u04f5y\x0f\x80\x00\u07d4\\O$\xe9\x94\ud3c5\x0e\xa7\x81\x8fG\x1c\x8f\xac;\xcf\x04R\x89]\x80h\x8d\x9e1\xc0\x00\x00\u07d4\\T\x19V\\:\xadNqN\a92\x8e5!\u024f\x05\u0309\x1c\x9fx\u0489>@\x00\x00\u07d4\\a6\xe2\x18\xde\na\xa17\xb2\xb3\x96-*a\x12\xb8\t\u05c9\x0f\xf3\u06f6_\xf4\x86\x80\x00\xe0\x94\\a\xaby\xb4\b\xdd2)\xf6bY7\x05\xd7/\x1e\x14{\xb8\x8a\x04\xd0$=4\x98\u0344\x00\x00\u07d4\\m\x04\x1d\xa7\xafD\x87\xb9\xdcH\xe8\xe1\xf6\af\u0425m\xbc\x89O\a\n\x00>\x9ct\x00\x00\u07d4\\o6\xaf\x90\xab\x1aeln\xc8\xc7\xd5!Q'b\xbb\xa3\xe1\x89lh\xcc\u041b\x02,\x00\x00\u07d4\\{\x9e\u01e2C\x8d\x1eD*\x86\x0f\x8a\x02\x1e\x18\x99\xf07z\xea\x00\x00\u07d4\\\xcc\xf1P\x8b\xfd5\xc2\x050\xaad%\x00\xc1\r\xeee\xea\xed\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\u07d4\\\xcer\xd0h\xc7\xc3\xf5[\x1d(\x19T^w1|\xae\x82@\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\\\xd0\xe4u\xb5D!\xbd\xfc\f\x12\xea\x8e\b+\u05e5\xaf\nj\x89\x032\xca\x1bg\x94\f\x00\x00\u07d4\\\u0548\xa1N\xc6H\xcc\xf6G)\xf9\x16z\xa7\xbf\x8b\xe6\xeb=\x8965\u026d\xc5\u07a0\x00\x00\u07d4\\\u062f`\xdee\xf2M\xc3\xceW0\xba\x92e0\"\xdcYc\x89a\t=|,m8\x00\x00\u07d4\\\xdcG\b\xf1O@\xdc\xc1Zy_}\xc8\xcb\v\u007f\xaa\x9en\x89\x1d\x1c_>\xda \xc4\x00\x00\u07d4\\\u0d86,\u0391b\xe8~\bI\xe3\x87\xcb]\xf4\xf9\x11\x8c\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94\\\xe2\xe7\u03aa\xa1\x8a\xf0\xf8\xaa\xfa\u007f\xba\xd7L\u021e<\xd46\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\\\xe4@h\xb8\xf4\xa3\xfey\x9ej\x83\x11\xdb\xfd\xed\xa2\x9d\xee\x0e\x89lk\x93[\x8b\xbd@\x00\x00\u0794\\\xeb\xe3\v*\x95\xf4\xae\xfd\xa6ee\x1d\xc0\xcf~\xf5u\x81\x99\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\\\xf1\x8f\xa7\u0227\xc0\xa2\xb3\xd5\xef\u0459\x0fd\xdd\xc5i$,\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\\\xf4N\x10T\reqd#\xb1\xbc\xb5B\xd2\x1f\xf8:\x94\u034a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\\\xf8\xc0>\xb3\xe8r\xe5\x0f|\xfd\f/\x8d;?,\xb5\x18:\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\\\xfa\x8dV\x85ue\x8c\xa4\xc1\xa5\x93\xacL]\x0eD\xc6\aE\x89\x0f\xc6o\xae7F\xac\x00\x00\u07d4\\\xfa\x98w\xf7\x19\u01dd\x9eIJ\b\xd1\xe4\x1c\xf1\x03\xfc\x87\u0249\n\u05ce\xbcZ\xc6 \x00\x00\u07d4]\x1d\xc38{G\xb8E\x1eU\x10l\f\xc6}m\xc7+\u007f\v\x89lk\x93[\x8b\xbd@\x00\x00\u07d4]#\x1ap\xc1\xdf\xeb6\n\xbd\x97\xf6\x16\xe2\xd1\r9\xf3\u02b5\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4]$\xbd\xbc\x1cG\xf0\xeb\x83\xd1(\xca\xe4\x8a\xc3\xf4\xb5\x02bt\a\xda'/g\x81Jk\xec\u0509\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4]\x83\xb2\x1b\xd2q#`Ckg\xa5\x97\xee3x\xdb>z\xe4\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94]\x87+\x12.\x99N\xf2|q\xd7\u07b4W\xbfeB\x9e\xcal\x8a\x01\xb1\xad\xed\x81\u04d4\x10\x80\x00\xe0\x94]\x8d1\xfa\xa8d\xe2!Y\xcdoQu\xcc\xec\xc5?\xa5Mr\x8a\x05\xb6\x96\xb7\r\xd5g\x10\x00\x00\xe0\x94]\x95\x8a\x9b\u0449\u0098_\x86\u014a\x8ci\xa7\xa7\x88\x06\xe8\u068a\x02(\xf1o\x86\x15x`\x00\x00\u07d4]\xa2\xa9\xa4\xc2\xc0\xa4\xa9$\xcb\xe0\xa5:\xb9\xd0\xc6'\xa1\u03e0\x89'\xbf8\xc6TM\xf5\x00\x00\u07d4]\xa4\u0288\x93\\'\xf5\\1\x10H\x84\x0eX\x9e\x04\xa8\xa0I\x89\x04V9\x18$O@\x00\x00\u07d4]\xa5G\x85\u027d0W\\\x89\u07b5\x9d A\xd2\n9\xe1{\x89j\xa2\t\xf0\xb9\x1de\x80\x00\xe0\x94]\xb6\x9f\xe9>o\xb6\xfb\xd4P\x96k\x97#\x8b\x11\n\xd8'\x9a\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4]\xb7\xbb\xa1\xf9W?$\x11]\x8c\x8cb\xe9\u0388\x95\x06\x8e\x9f\x89\x02\xb5\xaa\xd7,e \x00\x00\xe0\x94]\xb8D\x00W\x00i\xa9W<\xab\x04\xb4\u6d955\xe2\x02\xb8\x8a\x02\r\u058a\xaf2\x89\x10\x00\x00\u07d4]\xc3m\xe55\x94P\xa1\xec\t\xcb\fD\xcf+\xb4+:\xe45\x89<\x94m\x89;3\x06\x00\x00\u07d4]\xc6\xf4_\xef&\xb0n3\x021?\x88M\xafH\xe2to\xb9\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94]\u0376\xb8zP\xa9\xde\x02C\x80\x00\x00\u07d4^Q\xb8\xa3\xbb\t\xd3\x03\xea|\x86\x05\x15\x82\xfd`\x0f\xb3\xdc\x1a\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794^X\xe2U\xfc\x19\x87\n\x040_\xf2\xa0F1\xf2\xff)K\xb1\x88\xf4?\xc2\xc0N\xe0\x00\x00\u07d4^ZD\x19t\xa8=t\u0187\xeb\xdcc?\xb1\xa4\x9e{\x1a\u05c9\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4^eE\x8b\xe9d\xaeD\x9fqw7\x04\x97\x97f\xf8\x89\x87a\x89\x1c\xa7\xccs[o|\x00\x00\u07d4^g\u07c9i\x10\x1a\u06bd\x91\xac\xcdk\xb1\x99\x12t\xaf\x8d\xf2\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4^n\x97G\xe1b\xf8\xb4\\en\x0fl\xaez\x84\xba\xc8\x0eN\x89lk\x93[\x8b\xbd@\x00\x00\u07d4^s\x1bU\xce\xd4R\xbb??\xe8q\xdd\xc3\xed~\xe6Q\n\x8f\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4^t\xed\x80\xe9eW\x88\xe1\xbb&\x97R1\x96g\xfeuNZ\x89\x03\t'\xf7L\x9d\xe0\x00\x00\u07d4^w.'\xf2\x88\x00\xc5\r\u0697;\xb3>\x10v.n\xea \x89a\t=|,m8\x00\x00\u07d4^{\x8cT\xdcW\xb0@ bq\x9d\xee~\xf5\xe3~\xa3]b\x89\x9b\xf9\x81\x0f\xd0\\\x84\x00\x00\u07d4^\u007fp7\x87uX\x9f\xc6j\x81\xd3\xf6S\xe9T\xf5U`\ub243\xf2\x89\x18\x1d\x84\xc8\x00\x00\xe0\x94^\x80n\x84W0\xf8\a>l\xc9\x01\x8e\xe9\x0f\\\x05\xf9\t\xa3\x8a\x02\x01\xe9m\xac\u03af \x00\x00\u07d4^\x8eM\xf1\x8c\xf0\xafw\tx\xa8\u07cd\xac\x90\x93\x15\x10\xa6y\x89lk\x93[\x8b\xbd@\x00\x00\u07d4^\x90\xc8Xw\x19\x87V\xb06l\x0e\x17\xb2\x8eR\xb4FPZ\x89\x14JJ\x18\xef\xebh\x00\x00\u07d4^\x95\xfe_\xfc\xf9\x98\xf9\xf9\xac\x0e\x9a\x81\u06b8>\xadw\x00=\x89\x1dB\xc2\r2y\u007f\x00\x00\u07d4^\xad)\x03z\x12\x89dx\xb1)j\xb7\x14\xe9\u02d5B\x8c\x81\x89\x03\xe0C\a-@n\x00\x00\u07d4^\xb3q\xc4\a@lB{;}\xe2q\xad<\x1e\x04&\x95y\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4^\u037a\xea\xb9\x10o\xfe]{Q\x96\x96`\x9a\x05\xba\ub16d\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4^\xd0\xd63\x85Y\xefD\xdcza\xed\xeb\x89?\xa5\xd8?\xa1\xb5\x89\v\xed\x1d\x02c\xd9\xf0\x00\x00\xe0\x94^\u04fb\xc0R@\xe0\u04d9\xebm\xdf\xe6\x0fb\xdeM\x95\t\xaf\x8a)\x14\xc0$u\xf9\xd6\xd3\x00\x00\u0594^\xd3\xf1\xeb\xe2\xaegV\xb5\xd8\xdc\x19\xca\xd0,A\x9a\xa5w\x8b\x80\u07d4^\xd5a\x15\xbde\x05\xa8\x82s\xdf\\V\x83\x94p\xd2J-\xb7\x89\x03\x8ee\x91\xeeVf\x80\x00\xe0\x94^\xf8\xc9a\x86\xb3y\x84\xcb\xfe\x04\u0158@n;\n\xc3\x17\x1f\x8a\x01\xfd\x934\x94\xaa_\xe0\x00\x00\u07d4^\xfb\xdf\xe58\x99\x99c<&`Z[\xfc,\x1b\xb5\x95\x93\x93\x89\x03\xc0W\xc9\\\xd9\b\x00\x00\xe0\x94_\x13\x15F1Fm\xcb\x13S\u0210\x93*|\x97\xe0\x87\x8e\x90\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4_\x16z\xa2B\xbcL\x18\x9a\xde\xcb:\u0127\xc4R\xcf\x19/\u03c9lkLM\xa6\u077e\x00\x00\xe0\x94_\x1c\x8a\x04\xc9\rs[\x8a\x15)\t\xae\xaeco\xb0\xce\x16e\x8a\x01{x'a\x8cZ7\x00\x00\u07d4_#\xba\x1f7\xa9lE\xbcI\x02YS\x8aT\u008b\xa3\xb0\u0549A\rXj \xa4\xc0\x00\x00\u07d4_&\xcf4Y\x9b\xc3n\xa6{\x9ez\x9f\x9bC0\xc9\xd5B\xa3\x8965\u026d\xc5\u07a0\x00\x00\u07d4_)\xc9\xdev]\xde%\x85*\xf0}3\xf2\xceF\x8f\xd2\t\x82\x89lk\x93[\x8b\xbd@\x00\x00\u07d4_/\a\xd2\u0597\xe8\xc5g\xfc\xfd\xfe\x02\x0fI\xf3`\xbe!9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4_2\x1b=\xaa\xa2\x96\xca\xdf)C\x9f\x9d\xab\x06*K\xff\xed\u0589\x04p%\x90>\xa7\xae\x00\x00\u07d4_3:;#\x10vZ\r\x182\xb9\xbeL\n\x03pL\x1c\t\x8965\u026d\xc5\u07a0\x00\x00\u07d4_4K\x01\xc7\x19\x1a2\xd0v*\xc1\x88\xf0\xec-\xd4`\x91\x1d\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94_6>\n\xb7G\xe0-\x1b;f\xab\xb6\x9e\xa5<{\xafR:\x8a\x02w\x01s8\xa3\n\xe0\x00\x00\u07d4_7[\x86`\f@\u0328\xb2gkz\x1a\x1d\x16D\xc5\xf5,\x89\x04F\x18\xd7Lb?\x00\x00\u07d4_>\x1eg9\xb0\xc6\"\x00\xe0\n\x006\x91\xd9\xef\xb28\u061f\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4_H?\xfb\x8fh\n\xed\xf2\xa3\x8fx3\xaf\xdc\xdeY\xb6\x1eK\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94_J\xceL\x1c\xc13\x91\xe0\x1f\x00\xb1\x98\xe1\xf2\v_\x91\xcb\xf5\x8a\x01\x0f\x0f\xa8\xb9\u04c1\x1a\x00\x00\xe0\x94_R\x12\x82\xe9\xb2x\u070c\x03Lr\xafS\xee)\xe5D=x\x8a\x01as-/\x8f:\xe0\x00\x00\u07d4_h\xa2L~\xb4\x11vgs{39?\xb3\xc2\x14\x8aS\xb6\x89\x02\xce\u0791\x8dE<\x00\x00\u07d4_p\x8e\xaf9\xd8#\x94lQ\xb3\xa3\u9df3\xc0\x03\xe2cA\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4_t.H~:\xb8\x1a\xf2\xf9J\xfd\xbe\x1b\x9b\x8f\\\u0301\xbc\x89u\xc4E\xd4\x11c\xe6\x00\x00\u07d4_t\xed\x0e$\xff\x80\u0672\u0124K\xaa\x99uB\x8c\u05b95\x89\xa1\x8b\xce\xc3H\x88\x10\x00\x00\u07d4_v\xf0\xa3\x06&\x9cx0k=e\r\xc3\xe9\xc3p\x84\xdba\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4_w\xa1\a\xab\x12&\xb3\xf9_\x10\ue0ee\xfcl]\xff>\u0709\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4_{;\xba\xc1m\xab\x83\x1aJ\x0f\xc5;\fT\x9d\xc3l1\u0289i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94_\x93\xff\x83't\xdbQ\x14\xc5[\xb4\xbfD\xcc\U000f53d0?\x8a(\xa9\xc9\x1a&4X)\x00\x00\u07d4_\x96\x16\xc4{Jg\xf4\x06\xb9Z\x14\xfeo\xc2h9o\x17!\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4_\x98\x109\xfc\xf5\x02%\xe2\xad\xf7bu!\x12\xd1\xcc&\xb6\xe3\x89\x1b\x1aAj!S\xa5\x00\x00\u07d4_\x99\u070eI\xe6\x1dW\xda\xef`j\xcd\xd9\x1bMp\a2j\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4_\xa6\x1f\x15-\xe6\x125\x16\xc7Q$)y(_yj\u01d1\x89\v\x0f\x11\x97)c\xb0\x00\x00\u07d4_\xa7\xbf\xe0C\x88a'\xd4\x01\x1d\x83V\xa4~\x94yc\xac\xa8\x89b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x94_\xa8\xa5Nh\x17lO\xe2\xc0\x1c\xf6q\xc5\x15\xbf\xbd\xd5(\xa8\x8aE\xe1U\xfa\x01\x10\xfa@\x00\x00\u07d4_\xad\x96\x0fk,\x84V\x9c\x9fMG\xbf\x19\x85\xfc\xb2\xc6]\xa6\x8965f3\xeb\xd8\xea\x00\x00\u07d4_\xc6\xc1\x14&\xb4\xa1\xea\xe7\xe5\x1d\xd5\x12\xad\x10\x90\xc6\xf1\xa8[\x89\x93\xfe\\W\xd7\x10h\x00\x00\u07d4_\u0344Th\x96\xdd\b\x1d\xb1\xa3 \xbdM\x8c\x1d\xd1R\x8cL\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4_\u0368G\xaa\xf8\xd7\xfa\x8b\xca\b\x02\x9c\xa2\x84\x91f\xaa\x15\xa3\x89!\u02b8\x12Y\xa3\xbf\x00\x00\u07d4_\xd1\xc3\xe3\x17x'l\xb4.\xa7@\xf5\xea\xe9\xc6A\xdb\xc7\x01\x89\n\x84Jt$\xd9\xc8\x00\x00\u07d4_\xd3\xd6w~\xc2b\n\xe8:\x05R\x8e\xd4%\a-<\xa8\xfd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4_\xd9s\xaf6j\xa5\x15|Te\x9b\u03f2|\xbf\xa5\xac\x15\u0589\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4_\xe7w\x03\x80\x8f\x82>l9\x93R\x10\x8b\xdb,R|\xb8|\x89j@v\xcfy\x95\xa0\x00\x00\xe0\x94_\xecI\xc6e\xe6N\xe8\x9d\xd4A\xeet\x05n\x1f\x01\xe9(p\x8a\x01V\x9b\x9es4t\xc0\x00\x00\u07d4_\xf3&\xcd`\xfd\x13k$^)\xe9\bzj\u04e6R\u007f\r\x89e\xea=\xb7UF`\x00\x00\u07d4_\xf9=\xe6\xee\x05L\xadE\x9b-^\xb0\xf6\x87\x03\x89\xdf\xcbt\x89\v\xed\x1d\x02c\xd9\xf0\x00\x00\u07d4`\x06\xe3m\x92\x9b\xf4]\x8f\x16#\x1b\x12j\x01\x1a\xe2\x83\xd9%\x89\t\x8a}\x9b\x83\x14\xc0\x00\x00\u07d4`!\xe8Z\x88\x14\xfc\xe1\xe8*A\xab\xd1\u04f2\xda\xd2\xfa\xef\xe0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4`8t\n\xe2\x8df\xba\x93\xb0\xbe\bH+2\x05\xa0\xf7\xa0{\x89\x11!a\x85\u009fp\x00\x00\u07d4`?/\xabz\xfbn\x01{\x94v`i\xa4\xb4;8\x96I#\x89Y\xd2\xdb$\x14\u0699\x00\x00\u07d4`B'm\xf2\x98?\xe2\xbcGY\xdc\x19C\xe1\x8f\xdb\xc3Ow\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4`B\xc6D\xba\xe2\xb9o%\xf9M1\xf6x\xc9\r\xc9f\x90\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4`L\xdf\x18b\x8d\xbf\xa82\x91\x94\xd4x\xddR\x01\xee\xccK\xe7\x89\x01?0j$\t\xfc\x00\x00\u07d4`N\x94w\xeb\xf4r|t[\u02bb\xed\xcbl\xcf)\x99@\"\x8966\x9e\xd7t}&\x00\x00\u07d4`gm\x1f\xa2\x1f\xca\x05\"\x97\xe2K\xf9c\x89\u0171*p\u05c9\r\x17|Zzh\xd6\x00\x00\u07d4`gn\x92\u044b\x00\x05\t\xc6\x1d\xe5@\xe6\xc5\u0776v\xd5\t\x89A\rXj \xa4\xc0\x00\x00\u07d4`o\x17q!\xf7\x85\\!\xa5\x06#0\xc8v\"d\xa9{1\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4`\x86B6\x93\r\x04\xd8@+]\xcb\xeb\x80\u007f<\xafa\x1e\xa2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4`\xabq\xcd&\xeamnY\xa7\xa0\xf6'\xee\a\x9c\x88^\xbb\xf6\x89\x01s\x17\x90SM\xf2\x00\x00\u07d4`\xaf\x0e\xe1\x18D<\x9b7\xd2\xfe\xadw\xf5\xe5!\u07be\x15s\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4`\xb3X\xcb=\xbe\xfa7\xf4}\xf2\xd76X@\u068e;\u024c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4`\xb8\u05b7;ySO\xb0\x8b\xb8\xcb\xce\xfa\xc7\xf3\x93\xc5{\xfe\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4`\xbeo\x95?*M%\xb6%o\xfd$#\xac\x148%.N\x89\b!\xab\rD\x14\x98\x00\x00\u0794`\xc3qO\xdd\xdbcFY\u48b1\xeaB\xc4r\x8c\u01f8\xba\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4`\xcc=D^\xbd\xf7j}z\xe5q\u0197\x1d\xffh\u0305\x85\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94`\xd5fq@\xd1&\x14\xb2\x1c\x8e^\x8a3\b.2\xdf\xcf#\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4`\xde\"\xa1Pt2\xa4{\x01\xcch\xc5*\v\xf8\xa2\xe0\u0418\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4`\xe0\xbd\u0422Y\xbb\x9c\xb0\x9d?7\xe5\u034b\x9d\xac\uafca\x89JD\x91\xbdm\xcd(\x00\x00\u07d4`\xe3\xccC\xbc\xdb\x02j\xadu\x9cpf\xf5U\xbb\xf2\xacf\xf5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4a\x04+\x80\xfd`\x95\u0478{\xe2\xf0\x0f\x10\x9f\xab\xaf\xd1W\xa6\x89\x05k\xc7^-c\x10\x00\x00\u07d4a\a\xd7\x1d\xd6\xd0\xee\xfb\x11\xd4\xc9\x16@L\xb9\x8cu>\x11}\x89lk\x93[\x8b\xbd@\x00\x00\u07d4a\x0f\xd6\xeeN\xeb\xab\x10\xa8\xc5]\vK\xd2\xe7\xd6\xef\x81qV\x89\x01\x15\x95a\x06]]\x00\x00\u07d4a\x14\xb0\xea\xe5Wi\x03\xf8\v\xfb\x98\x84-$\xed\x92#\u007f\x1e\x89\x05k\xc7^-c\x10\x00\x00\u07d4a!\xaf9\x8a[-\xa6\x9fe\xc68\x1a\xec\x88\u039c\xc6D\x1f\x89\"\xb1\xc8\xc1\"z\x00\x00\x00\u07d4a&g\xf1r\x13[\x95\v,\xd1\xde\x10\xaf\xde\xcehW\xb8s\x8965\u026d\xc5\u07a0\x00\x00\u07d4a,\xed\x8d\xc0\u071e\x89\x9e\xe4oyb33\x15\xf3\xf5^D\x89\x12^5\xf9\xcd=\x9b\x00\x00\u07d4a4\xd9B\xf07\xf2\xcc=BJ#\f`=g\xab\xd3\xed\xf7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4a:\xc5;\xe5e\xd4e6\xb8 q[\x9b\x8d:\xe6\x8aK\x95\x89\xcb\xd4{n\xaa\x8c\xc0\x00\x00\u07d4a?\xabD\xb1k\xbeUMD\xaf\xd1x\xab\x1d\x02\xf3z\ua949lk\x93[\x8b\xbd@\x00\x00\u07d4aN\x8b\xef=\xd2\u015bY\xa4\x14Vt@\x10\x185\x18\x84\xea\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4aQ\x84d\xfd\u0637<\x1b\xb6\xacm\xb6\x00eI8\xdb\xf1z\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4aT}7nSi\xbc\xf9x\xfc\x16,1\xc9\b\"3\xb8%\xd0%\xbe?{\x10V\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4a\x91\xdd\u0276J\x8e\b\x90\xb427\t\u05e0|H\xb9*d\x89*\x03I\x19\u07ff\xbc\x00\x00\u07d4a\x96\xc3\xd3\xc0\x90\x8d%Cf\xb7\xbc\xa5WE\"-\x9dM\xb1\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4a\x9f\x17\x14E\xd4+\x02\xe2\xe0p\x04\xad\x8a\xfeiO\xa5=j\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4a\xad\xf5\x92\x9a^)\x81hN\xa2C\xba\xa0\x1f}\x1f^\x14\x8a\x89\x05\xfa\xbfl\x98O#\x00\x00\u07d4a\xb1\xb8\xc0\x12\xcdLx\xf6\x98\xe4p\xf9\x02V\xe6\xa3\x0fH\u0749\n\u05ce\xbcZ\xc6 \x00\x00\u07d4a\xb3\xdf.\x9e\x9f\xd9h\x13\x1f\x1e\x88\xf0\xa0\xeb[\xd7eFM\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4a\xb9\x02\u0166s\x88X&\x82\r\x1f\xe1EI\xe4\x86_\xbd\u0089\x12$\xef\xed*\u1440\x00\u07d4a\xb9\x05\xdef?\xc1s\x86R;:(\xe2\xf7\xd07\xa6U\u0349\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4a\xba\x87\xc7~\x9bYm\xe7\xba\x0e2o\xdd\xfe\xec!c\xeff\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4a\xbf\x84\u056b\x02oX\xc8s\xf8o\xf0\xdf\u0282\xb5W3\xae\x89lk\x93[\x8b\xbd@\x00\x00\u07d4a\xc4\xee|\x86LMk^7\xea\x131\xc2\x03s\x9e\x82k/\x89\x01\xa15;8*\x91\x80\x00\u07d4a\xc80\xf1eG\x18\xf0u\u032b\xa3\x16\xfa\xac\xb8[}\x12\v\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4a\xc8\xf1\xfaC\xbf\x84i\x99\xec\xf4{+2M\xfbkc\xfe:\x89+^:\xf1k\x18\x80\x00\x00\u07d4a\xc9\xdc\u8c98\x1c\xb4\x0e\x98\xb0@+\xc3\xeb(4\x8f\x03\xac\x89\n\xac\xac\u0679\xe2+\x00\x00\u07d4a\u03a7\x1f\xa4d\xd6*\a\x06?\x92\v\f\xc9\x17S\x973\u0609Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4a\xd1\x01\xa03\xee\x0e.\xbb1\x00\xed\xe7f\xdf\x1a\xd0$IT\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4a\xedU\x96\u0197 \u007f=U\xb2\xa5\x1a\xa7\xd5\x0f\a\xfa\t\xe8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4a\xff\x8eg\xb3M\x9e\xe6\xf7\x8e\xb3o\xfe\xa1\xb9\xf7\xc1W\x87\xaf\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4b\x05\xc2\xd5dtp\x84\x8a8@\xf3\x88~\x9b\x01]4u\\\x89a\x94\x04\x9f0\xf7 \x00\x00\u07d4b(\xad\xe9^\x8b\xb1}\x1a\xe2;\xfb\x05\x18AMI~\x0e\xb8\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94b)\xdc\xc2\x03\xb1\xed\xcc\xfd\xf0n\x87\x91\fE*\x1fMzr\x8a\x06\xe1\xd4\x1a\x8f\x9e\xc3P\x00\x00\u0794b+\xe4\xb4T\x95\xfc\xd91C\xef\xc4\x12\u0599\xd6\xcd\xc2=\u0148\xf0\x15\xf2W6B\x00\x00\u07d4b3\x1d\xf2\xa3\xcb\xee5 \xe9\x11\u07a9\xf7>\x90_\x89%\x05\x89lk\x93[\x8b\xbd@\x00\x00\u07d4bVD\xc9Z\x87>\xf8\xc0l\u06de\x9fm\x8dv\x80\x04=b\x89a\x94\x04\x9f0\xf7 \x00\x00\u07d4be\xb2\xe7s\x0f6\xb7v\xb5-\f\x9d\x02\xad\xa5]\x8e<\xb6\x8965\u026d\xc5\u07a0\x00\x00\u07d4bh\n\x15\xf8\u0338\xbd\xc0/s`\xc2Z\xd8\u03f5{\x8c\u034965\u026d\xc5\u07a0\x00\x00\u07d4b\x94\xea\xe6\xe4 \xa3\xd5`\n9\xc4\x14\x1f\x83\x8f\xf8\xe7\xccH\x89\xa00\xdc\xeb\xbd/L\x00\x00\u07d4b\x97\x1b\xf2cL\xee\v\xe3\u0249\x0fQ\xa5`\x99\u06f9Q\x9b\x89#\x8f\xd4,\\\xf0@\x00\x00\u07d4b\x9b\xe7\xab\x12jS\x98\xed\xd6\u069f\x18D~x\u0192\xa4\xfd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4b\xb4\xa9\"nah\a\x1el\xbea\x11\xfe\xf0\xbcc\x8a\x03\xba\x19\x10\xbf4\x1b\x00\x00\x00\xe0\x94c\n\x91:\x901\xc9I*\xbdLA\u06f1PT\xcf\xecD\x16\x8a\x014X\xdbg\xaf5\xe0\x00\x00\xe0\x94c\fRs\x12mQ|\xe6q\x01\x81\x1c\xab\x16\xb8SL\xf9\xa8\x8a\x01\xfe\xcc\xc6%s\xbb\u04c0\x00\u07d4c\x100\xa5\xb2{\a(\x8aEio\x18\x9e\x11\x14\xf1*\x81\xc0\x89\x1b\x1azB\v\xa0\r\x00\x00\u07d4c\x10\xb0 \xfd\x98\x04IW\x99P\x92\t\x0f\x17\xf0NR\xcd\xfd\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4c+\x91I\xd7\x01x\xa7364'^\x82\u0555?'\x96{\x89%\xf2s\x93=\xb5p\x00\x00\u07d4c,\xec\xb1\f\xfc\xf3\x8e\u0246\xb4;\x87p\xad\xec\xe9 \x02!\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4c1\x02\x8c\xbbZ!H[\xc5\x1bVQB\x99;\xdb%\x82\xa9\x89\x1c\xfd\xd7F\x82\x16\xe8\x00\x00\u07d4c3O\xcf\x17E\x84\x0eK\tJ;\xb4\v\xb7o\x96\x04\xc0L\x89\u05e5\xd7\x03\xa7\x17\xe8\x00\x00\u07d4c4\nWqk\xfac\xebl\xd13r\x12\x02W[\xf7\x96\xf0\x89\va\xe0\xa2\f\x12q\x80\x00\u07d4cN\xfc$7\x11\a\xb4\xcb\xf0?y\xa9=\xfd\x93\xe41\xd5\xfd\x89B5\x82\xe0\x8e\xdc\\\x80\x00\xe0\x94c\\\x00\xfd\xf05\xbc\xa1_\xa3a\r\xf38N\x0f\xb7\x90h\xb1\x8a\x01\xe7\xe4\x17\x1b\xf4\u04e0\x00\x00\u07d4ca.xb\xc2{X|\xfbm\xaf\x99\x12\xcb\x05\x1f\x03\n\x9f\x89\x02[\x19\u053f\xe8\xed\x00\x00\u07d4cfgU\xbdA\xb5\x98i\x97x<\x13\x040\b$+<\xb5\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4c{\xe7\x1b:\xa8\x15\xffE=VB\xf70tE\vd\xc8*\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94c}g\xd8\u007fXo\nZG\x9e \xee\x13\xea1\n\x10\xb6G\x8a\n:Y&\xaf\xa1\xe70\x00\x00\u07d4c\u007fXi\xd6\xe4i_\x0e\xb9\xe2s\x11\u0107\x8a\xff33\x80\x89j\xc0Nh\xaa\xec\x86\x00\x00\u07d4c\x97|\xad}\r\xcd\xc5+\x9a\xc9\xf2\xff\xa16\xe8d(\x82\xb8\x89\x04\x10\u0546\xa2\nL\x00\x00\u07d4c\xa6\x1d\xc3\n\x8e;0\xa7c\xc4!<\x80\x1c\xbf\x98s\x81x\x8965\u026d\xc5\u07a0\x00\x00\u07d4c\xacT\\\x99\x12C\xfa\x18\xae\xc4\x1dOoY\x8eUP\x15\u0709 \x86\xac5\x10R`\x00\x00\u07d4c\xb9uMu\xd1-8@9\xeci\x06<\v\xe2\x10\xd5\xe0\u3252\v\x86\f\xc8\xec\xfd\x80\x00\u07d4c\xbbfO\x91\x17\x03v(YM\xa7\xe3\xc5\b\x9f\xd6\x18\xb5\xb5\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4c\u00a3\xd25\xe5\xee\xab\xd0\u0526\xaf\u06c9\xd9F'9d\x95\x89CN\xf0[\x9d\x84\x82\x00\x00\u07d4c\xc8\xdf\xde\v\x8e\x01\xda\xdc.t\x8c\x82L\xc06\x9d\U00010cc9\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4c\xd5Z\u065b\x917\xfd\x1b \xcc+O\x03\xd4,\xba\xdd\xf34\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4c\xd8\x00H\x87u\x96\xe0\u0084\x89\xe6P\xcdJ\xc1\x80\tjI\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\xe0\x94c\xe4\x14`>\x80\xd4\xe5\xa0\xf5\xc1\x87t FB%\x82\b\xe4\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94c\xe8\x8e.S\x9f\xfbE\x03\x86\xb4\xe4g\x89\xb2#\xf5GlE\x8a\x01U\x17\nw\x8e%\xd0\x00\x00\u07d4c\xef/\xbc=\xaf^\xda\xf4\xa2\x95b\x9c\xcf1\xbc\xdf@8\xe5\x89O%\x91\xf8\x96\xa6P\x00\x00\u07d4c\xf0\xe5\xa7R\xf7\x9fg\x12N\xedc:\xd3\xfd'\x05\xa3\x97\u0509\u0556{\xe4\xfc?\x10\x00\x00\xe0\x94c\xf5\xb5=y\xbf.A\x14\x89Re0\"8E\xfa\xc6\xf6\x01\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4c\xfc\x93\x00\x13\x05\xad\xfb\u0278])\xd9)\x1a\x05\xf8\xf1A\v\x8965\u026d\xc5\u07a0\x00\x00\u0794c\xfek\xccK\x8a\x98P\xab\xbeu\x8070\xc92%\x1f\x14[\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4d\x03\xd0bT\x96\x90\xc8\xe8\xb6>\xaeA\xd6\xc1\tGn%\x88\x89lk\x93[\x8b\xbd@\x00\x00\u07d4d\x04+\xa6\x8b\x12\xd4\xc1Qe\x1c\xa2\x81;sR\xbdV\xf0\x8e\x89 \x86\xac5\x10R`\x00\x00\u0794d\x05\xdd\x13\xe9:\xbc\xff7~p\x0e<\x1a\x00\x86\xec\xa2})\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94d\n\xbam\xe9\x84\xd9E\x177x\x03p^\xae\xa7\t_J\x11\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4d\v\xf8t\x15\xe0\xcf@s\x01\xe5Y\x9ah6m\xa0\x9b\xba\u0209\x1a\xbc\x9fA`\x98\x15\x80\x00\u07d4d \xf8\xbc\xc8\x16JaR\xa9\x9dk\x99i0\x05\xcc\xf7\xe0S\x8965f3\xeb\xd8\xea\x00\x00\u07d4d$\x1axD)\x0e\n\xb8U\xf1\u052au\xb5SE\x03\"$\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4d&J\xed\xd5-\xca\xe9\x18\xa0\x12\xfb\xcd\f\x03\x0e\xe6\xf7\x18!\x8965\u026d\xc5\u07a0\x00\x00\u07d4d7\x0e\x87 &E\x12Z5\xb2\a\xaf\x121\xfb`r\xf9\xa7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4d=\x9a\xee\u0531\x80\x94~\u04b9 |\xceL=\xdcU\xe1\xf7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4dC\xb8\xaec\x9d\xe9\x1c\xf7\xf0p\xa5G\x03\xb7\x18NH'l\\\x00w\xefK4\x89\x11X\xe4`\x91=\x00\x00\x00\xe0\x94d\xe2\xde! \v\x18\x99\u00e0\xc0e;P@\x13m\r\xc8B\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4d\xec\x8a[t?4y\xe7\a\xda\xe9\xee \u076aO@\xf1\u0649\n\u05ce\xbcZ\xc6 \x00\x00\u07d4e\x03\x86\v\x19\x10\b\xc1U\x83\xbf\u0201X\t\x93\x01v((\x8965\u026d\xc5\u07a0\x00\x00\u07d4e\x051\x911\x9e\x06z%\xe66\x1dG\xf3\u007fc\x18\xf84\x19\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4e\t;#\x9b\xbf\xba#\xc7w\\\xa7\xdaZ\x86H\xa9\xf5L\xf7\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4e\t\xee\xb14~\x84/\xfbA>7\x15^,\xbcs\x82s\xfd\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94e\vBUU\xe4\xe4\xc5\x17\x18\x14h6\xa2\xc1\xeew\xa5\xb4!\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4e\f\xf6}\xb0`\xcc\xe1uh\xd5\xf2\xa4#h|Idv\t\x89\x05k\xc7^-c\x10\x00\x00\u07d4e\x10\xdfB\xa5\x99\xbc\xb0\xa5\x19\u0329a\xb4\x88u\x9aogw\x89lk\x93[\x8b\xbd@\x00\x00\u07d4e6u\xb8B\xd7\u0634a\xf7\"\xb4\x11|\xb8\x1d\xac\x8ec\x9d\x89\x01\xae6\x1f\xc1E\x1c\x00\x00\u07d4eK~\x80\x87\x99\xa8=r\x87\xc6w\x06\xf2\xab\xf4\x9aId\x04\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94eORHG\xb3\xa6\xac\xc0\xd3\xd5\xf1\xf3b\xb6\x03\xed\xf6_\x96\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4eY4\u068etN\xaa=\xe3M\xbb\xc0\x89LN\xda\va\xf2\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4e]\\\xd7H\x96)\xe2ANIb?\xabb\xa1~M6\x11\x89\x05\fL\xb2\xa1\f`\x00\x00\u07d4e\xaf\x8d\x8b[\x1d\x1e\xed\xfaw\xbc\xbc\x96\xc1\xb13\xf83\x06\u07c9\x05P\x05\xf0\xc6\x14H\x00\x00\u07d4e\xaf\x90\x87\xe0QgqT\x97\u0265\xa7I\x18\x94\x89\x00M\xef\x89-C\xf3\xeb\xfa\xfb,\x00\x00\u0794e\xb4/\xae\xcc\x1e\u07f1B\x83\u0297\x9a\xf5E\xf6;0\xe6\f\x88\xfc\x93c\x92\x80\x1c\x00\x00\u0794e\xd3>\xb3\x9c\xdadS\xb1\x9ea\xc1\xfeM\xb91p\xef\x9d4\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4e\xd8\xddN%\x1c\xbc\x02\x1f\x05\xb0\x10\xf2\xd5\xdcR\f8r\xe0\x89-CW\x9a6\xa9\x0e\x00\x00\u07d4e\xea&\xea\xbb\xe2\xf6L\xcc\xcf\xe0h)\xc2]F7R\x02%\x89%\xf2s\x93=\xb5p\x00\x00\u07d4e\xeag\xad?\xb5j\xd5\xfb\x948}\u04ce\xb3\x83\x00\x1d|h\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94e\xeb\xae\xd2~\u06dd\xcc\x19W\xae\xe5\xf4R\xac!\x05\xa6\\\x0e\x8a\t7\u07ed\xae%\u26c0\x00\u07d4e\xee \xb0m\x9a\u0549\xa7\xe7\xce\x04\xb9\xf5\xf7\x95\xf4\x02\xae\u0389lk\x93[\x8b\xbd@\x00\x00\u07d4e\xf544m/\xfbx\u007f\xa9\xcf\x18]t[\xa4)\x86\xbdn\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94e\xf5\x87\x0f&\xbc\xe0\x89g}\xfc#\xb5\x00\x1e\xe4\x92H4(\x8a\x01\x12\xb1\xf1U\xaa2\xa3\x00\x00\u07d4e\xfd\x02\xd7\x04\xa1*M\xac\xe9G\x1b\x06E\xf9b\xa8\x96q\u0209\x01\x8d\x1c\xe6\xe4'\u0340\x00\u07d4e\xff\x87O\xaf\xceM\xa3\x18\xd6\xc9=W\xe2\u00ca\rs\xe8 \x8968\x02\x1c\xec\u06b0\x00\x00\xe0\x94f\x05W\xbbC\xf4\xbe:\x1b\x8b\x85\xe7\xdf{<[\xcdT\x80W\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4f\b,u\xa8\xde1\xa59\x13\xbb\xd4M\xe3\xa07O\u007f\xaaA\x89O%\x91\xf8\x96\xa6P\x00\x00\u07d4f\x11\xceY\xa9\x8b\a*\xe9Y\xdcI\xadQ\x1d\xaa\xaa\xa1\x9dk\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4f \x1b\xd2'\xaem\u01bd\xfe\xd5\xfb\u0781\x1f\xec\xfe^\x9d\u0649 >\x9e\x84\x92x\x8c\x00\x00\u07d4f#4\x81G$\x93[y1\xdd\xcaa\x00\xe0\rFw'\u0349\"\x88&\x9d\a\x83\xd4\x00\x00\u07d4f'O\xea\x82\xcd0\xb6\u009b#5\x0eOO=1\nX\x99\x89p7\x05P\xab\x82\x98\x00\x00\u07d4f,\xfa\x03\x8f\xab7\xa0\x17E\xa3d\u1e41'\xc5\x03tm\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4f5\xb4oq\x1d-\xa6\xf0\xe1cp\u034e\xe4>\xfb,-R\x89lk\x93[\x8b\xbd@\x00\x00\u07d4f6\x04\xb0P0F\xe6$\xcd&\xa8\xb6\xfbGB\xdc\xe0*o\x89\x03\x8b\x9by~\xf6\x8c\x00\x00\u07d4f6\u05ecczH\xf6\x1d8\xb1L\xfdHe\xd3m\x14(\x05\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4f@\xcc\xf0SU\\\x13\n\xe2\xb6Vd~\xa6\xe3\x167\xb9\xab\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4fBK\xd8x[\x8c\xb4a\x10*\x90\x02\x83\xc3]\xfa\a\xefj\x89\x02.-\xb2ff\xfc\x80\x00\u07d4fL\xd6}\xcc\u026c\x82(\xb4\\U\u06cdvU\ve\x9c\u0709\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4fNC\x11\x98p\xaf\x10zD\x8d\xb1'\x8b\x04H8\xff\u036f\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4fQso\xb5\x9b\x91\xfe\xe9\xc9:\xa0\xbdn\xa2\xf7\xb2Pa\x80\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4f[\x00\x0f\vw'P\xcc\x89k\x91\x8a\xacIK\x16\x80\x00\xe0\x94g]\\\xaa`\x9b\xf7\n\x18\xac\xa5\x80F]\x8f\xb71\r\x1b\xbb\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4gc F\u0732ZT\x93i(\xa9oB?3 \xcb\ud489lk\x93[\x8b\xbd@\x00\x00\u07d4ge\xdf%(\x0e\x8eO8\u0531\xcfDo\xc5\xd7\xebe\x9e4\x89\x05k\xc7^-c\x10\x00\x00\u07d4gv\xe13\xd9\xdc5L\x12\xa9Q\b{c\x96P\xf59\xa43\x89\x06\x81U\xa46v\xe0\x00\x00\u07d4g\x85Q<\xf72\xe4~\x87g\ap\xb5A\x9b\xe1\f\xd1\xfct\x89lk\x93[\x8b\xbd@\x00\x00\u07d4g\x947\xea\xcfCxx\xdc)=H\xa3\x9c\x87\xb7B\x1a!l\x89\x03\u007f\x81\x82\x1d\xb2h\x00\x00\u07d4g\x9b\x9a\x10\x990Q~\x89\x99\t\x9c\xcf*\x91LL\x8d\xd94\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4g\xa8\x0e\x01\x90r\x1f\x949\rh\x02r\x9d\xd1,1\xa8\x95\xad\x89lk\x13u\xbc\x91V\x00\x00\u07d4g\xb8\xa6\xe9\x0f\xdf\n\x1c\xacD\x17\x930\x1e\x87P\xa9\xfayW\x890\x84\x9e\xbe\x166\x9c\x00\x00\u07d4g\xbc\x85\xe8}\xc3LN\x80\xaa\xfa\x06k\xa8\u049d\xbb\x8eC\x8e\x89\x15\xd1\xcfAv\xae\xba\x00\x00\u07d4g\xc9&\t>\x9b\x89'\x938\x10\u0642\"\xd6.+\x82\x06\xbb\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4g\xcf\xdanp\xbfvW\u04d0Y\xb5\x97\x90\xe5\x14Z\xfd\xbea\x89#\x05\r\tXfX\x00\x00\u07d4g\u0582\xa2\x82\xefs\xfb\x8dn\x90q\xe2aOG\xab\x1d\x0f^\x8965\u026d\xc5\u07a0\x00\x00\u07d4g\u05a8\xaa\x1b\xf8\xd6\xea\xf78N\x99=\xfd\xf1\x0f\n\xf6\x8aa\x89\n\xbc\xbbW\x18\x97K\x80\x00\u07d4g\u0692.\xff\xa4r\xa6\xb1$\xe8N\xa8\xf8k$\xe0\xf5\x15\xaa\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4g\xdf$-$\r\u0538\a\x1dr\xf8\xfc\xf3[\xb3\x80\x9dq\xe8\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4g\xee@n\xa4\xa7\xaej:8\x1e\xb4\xed\xd2\xf0\x9f\x17KI(\x898)c_\th\xb0\x00\x00\u07d4g\xf2\xbbx\xb8\xd3\xe1\x1f|E\x8a\x10\xb5\xc8\xe0\xa1\xd3tF}\x89a\t=|,m8\x00\x00\u07d4g\xfcR}\xce\x17\x85\xf0\xfb\x8b\xc7\xe5\x18\xb1\xc6i\xf7\xec\u07f5\x89\r\x02\xabHl\xed\xc0\x00\x00\u07d4h\x02}\x19U\x8e\xd73\x9a\b\xae\xe8\xde5Y\xbe\x06>\xc2\xea\x89lk\x93[\x8b\xbd@\x00\x00\u07d4h\x06@\x83\x8b\xd0zD{\x16\x8dm\x92;\x90\xcflC\xcd\u0289]\u0212\xaa\x111\xc8\x00\x00\u07d4h\a\xdd\u020d\xb4\x89\xb03\xe6\xb2\xf9\xa8\x15SW\x1a\xb3\xc8\x05\x89\x01\x9f\x8euY\x92L\x00\x00\xe0\x94h\rY\x11\xed\x8d\xd9\xee\xc4\\\x06\f\"?\x89\xa7\xf6 \xbb\u054a\x04<3\xc1\x93ud\x80\x00\x00\u07d4h\x11\xb5L\u0456c\xb1\x1b\x94\xda\x1d\xe2D\x82\x85\u035fh\u0649;\xa1\x91\v\xf3A\xb0\x00\x00\u07d4h\x19\f\xa8\x85\xdaB1\x87L\x1c\xfbB\xb1X\n!s\u007f8\x89\xcf\x15&@\xc5\xc80\x00\x00\xe0\x94h(\x97\xbcO\x8e\x89\x02\x91 \xfc\xff\xb7\x87\xc0\x1a\x93\xe6A\x84\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4h)^\x8e\xa5\xaf\xd9\t?\xc0\xa4e\xd1W\x92+]*\xe24\x89\x01\x15NS!}\xdb\x00\x00\u07d4h.\x96'oQ\x8d1\xd7\xe5n0\u07f0\t\xc1!\x82\x01\xbd\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4h5\xc8\xe8\xb7J,\xa2\xae?J\x8d\x0fk\x95J>*\x83\x92\x89\x03B\x9c3]W\xfe\x00\x00\u07d4h63\x01\n\x88hk\xeaZ\x98\xeaS\xe8y\x97\xcb\xf7>i\x89\x05k9Bc\xa4\f\x00\x00\u07d4h=\xba6\xf7\xe9O@\xeaj\xea\ry\xb8\xf5!\xdeU\an\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4hA\x9cm\xd2\xd3\xceo\u02f3\xc7>/\xa0y\xf0`Q\xbd\xe6\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4hG;z}\x96Y\x04\xbe\u06e5V\u07fc\x17\x13l\xd5\xd44\x89\x05k\xc7^-c\x10\x00\x00\u07d4hG\x82[\xde\xe8$\x0e(\x04,\x83\xca\xd6B\U000868fd\u0709QP\xae\x84\xa8\xcd\xf0\x00\x00\xe0\x94hJD\xc0i3\x9d\b\xe1\x9auf\x8b\u06e3\x03\xbe\x85S2\x8a\x0e\u04b5%\x84\x1a\xdf\xc0\x00\x00\u07d4hS\x1fM\u0680\x8fS vz\x03\x114(\xca\f\xe2\xf3\x89\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4hy'\xe3\x04\x8b\xb5\x16*\xe7\xc1\\\xf7k\xd1$\xf9I{\x9e\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94h\x80\x9a\xf5\xd52\xa1\x1c\x1aMn2\xaa\xc7\\LR\xb0\x8e\xad\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4h\x86\xad\xa7\xbb\xb0a{\u0684!\x91\u018c\x92.\xa3\xa8\xac\x82\x89>\xe2;\xde\x0e} \x00\x00\xe0\x94h\x88>\x15.V`\xfe\xe5\x96&\xe7\xe3\xb4\xf0Q\x10\xe6\"/\x8a\v\x94c;\xe9u\xa6*\x00\x00\u07d4h\x8aV\x9e\x96U$\xeb\x1d\n\xc3\xd3s>\xab\x90\x9f\xb3\xd6\x1e\x89G\x8e\xae\x0eW\x1b\xa0\x00\x00\xe0\x94h\x8e\xb3\x85;\xbc\xc5\x0e\xcf\xee\x0f\xa8\u007f\n\xb6\x93\u02bd\xef\x02\x8a\x06\xb1\n\x18@\x06G\xc0\x00\x00\u07d4h\xa7B_\xe0\x9e\xb2\x8c\xf8n\xb1y>A\xb2\x11\xe5{\u058d\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4h\xa8l@#\x88\xfd\xdcY\x02\x8f\xecp!\u933f\x83\x0e\xac\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\xe0\x94h\xac\u06a9\xfb\x17\xd3\xc3\t\x91\x1aw\xb0_S\x91\xfa\x03N\xe9\x8a\x01\xe5.3l\xde\"\x18\x00\x00\u07d4h\xad\xdf\x01\x9dk\x9c\xabp\xac\xb1?\v1\x17\x99\x9f\x06.\x12\x89\x02\xb5\x12\x12\xe6\xb7\u0200\x00\u07d4h\xb3\x186\xa3\n\x01j\xda\x15{c\x8a\xc1]\xa7?\x18\xcf\u0789\x01h\u048e?\x00(\x00\x00\xe0\x94h\xb6\x85G\x88\xa7\xc6Il\xdb\xf5\xf8K\x9e\xc5\xef9+x\xbb\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4h\xc0\x84\x90\u021b\xf0\u05b6\xf3 \xb1\xac\xa9\\\x83\x12\xc0\x06\b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4h\xc7\xd1q\x1b\x01\x1a3\xf1o\x1fU\xb5\xc9\x02\xcc\xe9p\xbd\u05c9\b=lz\xabc`\x00\x00\u07d4h\xc8y\x1d\xc3B\xc3sv\x9e\xa6\x1f\xb7\xb5\x10\xf2Q\xd3 \x88\x8965\u026d\xc5\u07a0\x00\x00\u07d4h\u07d4|I[\ubbb8\u8273\xf9S\xd53\x87K\xf1\x06\x89\x1d\x99E\xab+\x03H\x00\x00\u07d4h\xe8\x02'@\xf4\xaf)\xebH\xdb2\xbc\xec\xdd\xfd\x14\x8d=\xe3\x8965\u026d\xc5\u07a0\x00\x00\u07d4h\xecy\u057eqUql@\x94\x1cy\u05cd\x17\u079e\xf8\x03\x89\x1b#8w\xb5 \x8c\x00\x00\u07d4h\xee\xc1\u222c1\xb6\xea\xba~\x1f\xbdO\x04\xadW\x9ak]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4h\xf5%\x92\x1d\xc1\x1c2\x9buO\xbf>R\x9f\xc7#\xc84\u0349WG=\x05\u06ba\xe8\x00\x00\u07d4h\xf7\x19\xae4+\xd7\xfe\xf1\x8a\x05\u02f0/pZ\u04ce\u0572\x898\xeb\xad\\\u0710(\x00\x00\xe0\x94h\xf7W<\xd4W\xe1L\x03\xfe\xa4>0-04|\x10p\\\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4h\xf8\xf4QU\xe9\x8cP)\xa4\xeb\u0175'\xa9.\x9f\xa81 \x89\xf0{D\xb4\a\x93 \x80\x00\u07d4h\xfe\x13W!\x8d\tXI\xcdW\x98B\u012a\x02\xff\x88\x8d\x93\x89lk\x93[\x8b\xbd@\x00\x00\u07d4i\x02(\xe4\xbb\x12\xa8\u0535\u09d7\xb0\xc5\xcf*u\t\x13\x1e\x89e\xea=\xb7UF`\x00\x00\u07d4i\x05\x94\xd3\x06a<\xd3\xe2\xfd$\xbc\xa9\x99J\u064a=s\xf8\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94i\a2ir\x9ed\x14\xb2n\xc8\xdc\x0f\xd95\xc7;W\x9f\x1e\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\xe0\x94i\x19\xdd^]\xfb\x1a\xfa@G\x03\xb9\xfa\xea\x8c\xee5\xd0\rp\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4i4\x92\xa5\xc5\x13\x96\xa4\x82\x88\x16i\xcc\xf6\xd8\xd7y\xf0\tQ\x89\x12\xbfPP:\xe3\x03\x80\x00\u07d4i=\x83\xbe\tE\x9e\xf89\v.0\xd7\xf7\u008d\xe4\xb4(N\x89lk\x93[\x8b\xbd@\x00\x00\u07d4iQp\x83\xe3\x03\xd4\xfb\xb6\xc2\x11E\x14!]i\xbcF\xa2\x99\x89\x05k\xc7^-c\x10\x00\x00\u07d4iUPel\xbf\x90\xb7]\x92\xad\x91\"\xd9\r#\xcah\xcaM\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94iX\xf8;\xb2\xfd\xfb'\xce\x04\t\xcd\x03\xf9\xc5\xed\xbfL\xbe\u074a\x04<3\xc1\x93ud\x80\x00\x00\u0794i[\x0fRBu7\x01\xb2d\xa6pq\xa2\u0708\b6\xb8\u06c8\u3601\x1b\xech\x00\x00\xe0\x94i[L\xce\bXV\xd9\xe1\xf9\xff>y\x94 #5\x9e_\xbc\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94if\x06:\xa5\xde\x1d\xb5\xc6q\xf3\xddi\x9dZ\xbe!>\xe9\x02\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4it\u0224\x14\u03ae\xfd<.M\xfd\xbe\xf40V\x8d\x9a\x96\v\x89\x12\x1e\xa6\x8c\x11NQ\x00\x00\xe0\x94iximQP\xa9\xa2cQ?\x8ft\u0196\xf8\xb19|\xab\x8a\x01g\xf4\x82\xd3\u0171\xc0\x00\x00\xe0\x94iy{\xfb\x12\u027e\u0582\xb9\x1f\xbcY5\x91\xd5\xe4\x027(\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94i\u007fUSk\xf8Z\xdaQ\x84\x1f\x02\x87b:\x9f\x0e\u041a\x17\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4i\x82\xfe\x8a\x86~\x93\xebJ\v\xd0QX\x93\x99\xf2\xec\x9aR\x92\x89lk\x93[\x8b\xbd@\x00\x00\u07d4i\x8a\x8ao\x01\xf9\xabh/c|yi\xbe\x88_lS\x02\xbf\x89\x01\r:\xa56\xe2\x94\x00\x00\u07d4i\x8a\xb9\xa2\xf33\x81\xe0|\fGC=\r!\xd6\xf36\xb1'\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4i\x94\xfb21\xd7\xe4\x1dI\x1a\x9dh\xd1\xfaL\xae,\xc1Y`\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4i\x9c\x9e\xe4q\x95Q\x1f5\xf8b\xcaL\"\xfd5\xae\x8f\xfb\xf4\x89\x04V9\x18$O@\x00\x00\u07d4i\x9f\xc6\u058aGuW<\x1d\u036e\xc80\xfe\xfdP9|N\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4i\xaf(\xb0tl\xac\r\xa1p\x84\xb99\x8c^6\xbb:\r\xf2\x896w\x03n\xdf\n\xf6\x00\x00\u07d4i\xb8\x0e\xd9\x0f\x84\x83J\xfa?\xf8.\xb9dp;V\tw\u0589\x01s\x17\x90SM\xf2\x00\x00\xe0\x94i\xb8\x1dY\x81\x14\x1e\u01e7\x14\x10`\xdf\u03cf5\x99\xff\xc6>\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4i\xbc\xfc\x1dC\xb4\xba\x19\xde{'K\xdf\xfb5\x13\x94\x12\xd3\u05c95e\x9e\xf9?\x0f\xc4\x00\x00\u07d4i\xbd%\xad\xe1\xa34lY\xc4\xe90\xdb*\x9dq^\xf0\xa2z\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4i\xc0\x8dtGT\xdep\x9c\xe9n\x15\xae\r\x1d9[:\"c\x8965\u026d\xc5\u07a0\x00\x00\u07d4i\xc2\xd85\xf1>\xe9\x05\x80@\x8ej2\x83\xc8\u0326\xa44\xa2\x89#\x8f\xd4,\\\xf0@\x00\x00\u07d4i\xc9N\a\u0129\xbe3\x84\xd9]\xfa<\xb9)\x00Q\x87;{\x89\x03\xcbq\xf5\x1f\xc5X\x00\x00\u07d4i\xcb>!S\x99\x8d\x86\xe5\xee \xc1\xfc\u0466\xba\uec86?\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4i\u04ddQ\b\x89\xe5R\xa3\x96\x13[\xfc\xdb\x06\xe3~8v3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94i\u064f8\xa3\xba=\xbc\x01\xfa\\,\x14'\xd8b\x83//p\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94i\xe2\xe2\xe7\x040|\xcc[\\\xa3\xf1d\xfe\xce.\xa7\xb2\xe5\x12\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4i\xffB\x90t\u02dblc\xbc\x91B\x84\xbc\xe5\xf0\xc8\xfb\xf7\u0409\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4i\xff\x89\x01\xb5Av?\x81|_)\x98\xf0-\xcf\xc1\xdf)\x97\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4j\x02:\xf5}XM\x84^i\x876\xf10\u06dd\xb4\r\xfa\x9a\x89\x05[ \x1c\x89\x00\x98\x00\x00\u07d4j\x04\xf5\xd5?\xc0\xf5\x15\xbe\x94+\x8f\x12\xa9\xcbz\xb0\xf3\x97x\x89\xa9\xaa\xb3E\x9b\xe1\x94\x00\x00\u07d4j\x05\xb2\x1cO\x17\xf9\xd7?_\xb2\xb0\u02c9\xffSV\xa6\xcc~\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\xe0\x94j\x0f\x05`f\xc2\xd5f(\x85\x02s\xd7\xec\xb7\xf8\xe6\xe9\x12\x9e\x8a\x01\x0f\r)<\u01e5\x88\x00\x00\u07d4j\x13\xd5\xe3,\x1f\xd2m~\x91\xffn\x051`\xa8\x9b,\x8a\xad\x89\x02\xe6/ \xa6\x9b\xe4\x00\x00\u07d4j.\x86F\x9a[\xf3|\xee\x82\xe8\x8bL8c\x89](\xfc\xaf\x89\x1c\"\x92f8[\xbc\x00\x00\u07d4j6\x94BL|\u01b8\xbc\u067c\u02baT\f\xc1\xf5\xdf\x18\u05c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94jB\u0297\x1cex\u056d\xe2\x95\xc3\xe7\xf4\xad3\x1d\xd3BN\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4jD\xaf\x96\xb3\xf02\xaed\x1b\xebg\xf4\xb6\xc83B\xd3|]\x89\x01\x92t\xb2Y\xf6T\x00\x00\u07d4jL\x89\a\xb6\x00$\x80W\xb1\xe4cT\xb1\x9b\u0705\x9c\x99\x1a\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4jQNbB\xf6\xb6\x8c\x13~\x97\xfe\xa1\u73b5U\xa7\xe5\xf7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4jS\xd4\x1a\xe4\xa7R\xb2\x1a\xbe\xd57FI\x95:Q=\xe5\xe5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4jaY\aJ\xb5s\xe0\xeeX\x1f\x0f=\xf2\u05a5\x94b\x9bt\x89\x10\xce\x1d=\x8c\xb3\x18\x00\x00\u07d4jc7\x83?\x8fjk\xf1\f\xa7\xec!\xaa\x81\x0e\xd4D\xf4\u02c97\xbd$4\\\xe8\xa4\x00\x00\u07d4jcS\xb9qX\x9f\x18\xf2\x95\\\xba(\xab\xe8\xac\xcejWa\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4jc\xfc\x89\xab\xc7\xf3n(-\x80x{{\x04\xaf\xd6U>q\x89\b\xacr0H\x9e\x80\x00\x00\u07d4jg\x9e7\x8f\xdc\xe6\xbf\xd9\u007f\xe6/\x04)Z$\xb9\x8965\u026d\xc5\u07a0\x00\x00\u07d4j\x8c\xea-\xe8J\x8d\xf9\x97\xfd?\x84\xe3\b=\x93\xdeW\u0369\x89\x05k\xe0<\xa3\xe4}\x80\x00\xe0\x94j\x97Xt;`>\xea:\xa0RKB\x88\x97#\xc4\x159H\x8a\x02#\x85\xa8'\xe8\x15P\x00\x00\u07d4j\xa5s/;\x86\xfb\x8c\x81\xef\xbek[G\xb5cs\v\x06\u020965\u026d\xc5\u07a0\x00\x00\u07d4j\xb3#\xaePV\xed\nE0r\u016b\xe2\xe4/\xcf]q9\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4j\xb5\xb4\xc4\x1c\u0778)i\f/\xda\u007f \xc8^b\x9d\xd5\u0549d\u052fqL2\x90\x00\x00\u07d4j\xc4\x0fS-\xfe\xe5\x11\x81\x17\u04ad5-\xa7}Om\xa2\u0209\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4j\xc4\u053e-\xb0\u065d\xa3\xfa\xaa\xf7RZ\xf2\x82\x05\x1dj\x90\x89\x04X\xcaX\xa9b\xb2\x80\x00\u07d4j\xcd\u0723\xcd+I\x90\xe2\\\xd6\\$\x14\x9d\t\x12\t\x9ey\x89\xa2\xa1\xe0|\x9fl\x90\x80\x00\u07d4j\xd9\v\xe2R\xd9\xcdFM\x99\x81%\xfa\xb6\x93\x06\v\xa8\xe4)\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4j\u0753!\x93\xcd8IJ\xa3\xf0:\xec\xccKz\xb7\xfa\xbc\xa2\x89\x04\xdbs%Gc\x00\x00\x00\xe0\x94j\xe5\u007f'\x91|V*\x13*M\x1b\xf7\xec\n\u01c5\x83)&\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4j\xeb\x9ftt.\xa4\x91\x81=\xbb\xf0\xd6\xfc\xde\x1a\x13\x1dM\xb3\x89\x17\xe5T0\x8a\xa00\x00\x00\u07d4j\xf25\u04bb\xe0P\xe6)\x16\x15\xb7\x1c\xa5\x82\x96X\x81\x01B\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4j\xf6\xc7\xee\x99\xdf'\x1b\xa1[\xf3\x84\xc0\xb7d\xad\xcbM\xa1\x82\x8965f3\xeb\xd8\xea\x00\x00\u07d4j\xf8\xe5Yih,q_H\xadO\xc0\xfb\xb6~\xb5\x97\x95\xa3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4j\xf9@\xf6>\u0278\xd8v'*\u0296\xfe\xf6\\\xda\xce\xcd\ua262\xa1]\tQ\x9b\xe0\x00\x00\u07d4j\xf9\xf0\xdf\uebbb_d\xbf\x91\xabw\x16i\xbf\x05)US\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4j\xff\x14f\xc2b6u\xe3\xcb\x0eu\xe4#\xd3z%\xe4B\xeb\x89]\u0212\xaa\x111\xc8\x00\x00\xe0\x94k\r\xa2Z\xf2g\u05c3l\"k\xca\xe8\xd8r\xd2\xceR\xc9A\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4k\x10\xf8\xf8\xb3\xe3\xb6\r\xe9\n\xa1-\x15_\x9f\xf5\xff\xb2,P\x89lk\x93[\x8b\xbd@\x00\x00\u07d4k\x17Y\x8a\x8e\xf5Oyz\xe5\x15\u0336Q}\x18Y\xbf\x80\x11\x89\x05k\xc7^-c\x10\x00\x00\u07d4k \xc0\x80`jy\xc7;\xd8\xe7[\x11qzN\x8d\xb3\xf1\u00c9\x10?sX\x03\xf0\x14\x00\x00\u07d4k\"\x84D\x02!\xce\x16\xa88-\xe5\xff\x02)G\"i\xde\xec\x8965\u026d\xc5\u07a0\x00\x00\u07d4k0\xf1\x829\x10\xb8m:\xcbZj\xfc\x9d\xef\xb6\xf3\xa3\v\xf8\x89\u3bb5sr@\xa0\x00\x00\u07d4k8\u0784\x1f\xad\u007fS\xfe\x02\xda\x11[\xd8j\xaff$f\xbd\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4kK\x99\xcb?\xa9\xf7\xb7L\u3903\x17\xb1\xcd\x13\t\n\x1az\x89\x03\x1b2~i]\xe2\x00\x00\u07d4kZ\xe7\xbfx\xecu\xe9\f\xb5\x03\xc7x\xcc\u04f2KO\x1a\xaf\x89+^:\xf1k\x18\x80\x00\x00\u07d4kc\xa2\u07f2\xbc\xd0\xca\xec\x00\"\xb8\x8b\xe3\f\x14Q\xeaV\xaa\x89+\xdbk\xf9\x1f\u007fL\x80\x00\u07d4kew\xf3\x90\x9aMm\xe0\xf4\x11R-Ep8d\x004\\\x89e\xea=\xb7UF`\x00\x00\u07d4kr\xa8\xf0a\xcf\xe6\x99j\xd4G\xd3\xc7,(\xc0\xc0\x8a\xb3\xa7\x89\xe7\x8cj\u01d9\x12b\x00\x00\u07d4kv\rHw\xe6\xa6'\xc1\xc9g\xbe\xe4Q\xa8P}\xdd\u06eb\x891T\xc9r\x9d\x05x\x00\x00\u07d4k\x83\xba\xe7\xb5e$EXU[\xcfK\xa8\xda \x11\x89\x1c\x17\x89lk\x93[\x8b\xbd@\x00\x00\u07d4k\x92]\xd5\xd8\xeda2\xabm\b`\xb8,D\xe1\xa5\x1f\x1f\xee\x89P; >\x9f\xba \x00\x00\xe0\x94k\x94a]\xb7Pej\u00cc~\x1c\xf2\x9a\x9d\x13g\u007fN\x15\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4k\x95\x1aC'N\xea\xfc\x8a\t\x03\xb0\xaf.\xc9+\xf1\xef\xc89\x89\x05k\xc7^-c\x10\x00\x00\u07d4k\x99%!\xec\x85#p\x84\x8a\u0597\xcc-\xf6Nc\xcc\x06\xff\x8965\u026d\xc5\u07a0\x00\x00\u07d4k\xa8\xf7\xe2_\xc2\xd8qa\x8e$\xe4\x01\x84\x19\x917\xf9\xf6\xaa\x89\x15\xafd\x86\x9ak\xc2\x00\x00\u07d4k\xa9\xb2\x1b5\x10k\xe1Y\xd1\xc1\xc2ez\xc5l\u049f\xfdD\x89\xf2\xdc}G\xf1V\x00\x00\x00\u07d4k\xafz*\x02\xaex\x80\x1e\x89\x04\xadz\xc0Q\b\xfcV\xcf\xf6\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94k\xb2\xac\xa2?\xa1bm\x18\xef\xd6w\u007f\xb9}\xb0-\x8e\n\xe4\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4k\xb4\xa6a\xa3:q\xd4$\u051b\xb5\xdf(b.\xd4\xdf\xfc\xf4\x89\",\x8e\xb3\xfff@\x00\x00\u07d4k\xb5\b\x13\x14j\x9a\xddB\xee\"\x03\x8c\x9f\x1fti\xd4\u007fG\x89\n\xdaUGK\x814\x00\x00\u07d4k\xbc?5\x8af\x8d\u0461\x1f\x03\x80\xf3\xf71\bBj\xbdJ\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4k\xbd\x1eq\x93\x90\xe6\xb9\x10C\xf8\xb6\xb9\u07c9\x8e\xa8\x00\x1b4\x89llO\xa6\xc3\xdaX\x80\x00\u07d4k\xc8Z\xcdY(r.\xf5\tS1\xee\x88\xf4\x84\xb8\u03c3W\x89\t\xc2\x00vQ\xb2P\x00\x00\u07d4k\xd3\xe5\x9f#\x9f\xaf\xe4wk\xb9\xbd\xddk\ue0fa]\x9d\x9f\x8965\u026d\xc5\u07a0\x00\x00\u07d4k\xd4W\xad\xe0Qy]\xf3\xf2F\\89\xae\xd3\xc5\xde\xe9x\x8964\xbf9\xab\x98x\x80\x00\u07d4k\xe1c\x13d>\xbc\x91\xff\x9b\xb1\xa2\xe1\x16\xb8T\xea\x93:E\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4k\xe7Y^\xa0\xf0hH\x9a'\x01\xecFI\x15\x8d\xdcC\xe1x\x89lk\x93[\x8b\xbd@\x00\x00\u07d4k\xe9\x03\x0e\xe6\xe2\xfb\u0111\xac\xa3\xde@\"\xd3\x01w+{}\x89\x01s\x17\x90SM\xf2\x00\x00\xe0\x94k\xec1\x1a\xd0P\b\xb4\xaf5<\x95\x8c@\xbd\x06s\x9a?\xf3\x8a\x03w\xf6*\x0f\nbp\x00\x00\u07d4k\xf7\xb3\xc0e\xf2\xc1\xe7\xc6\xeb\t+\xa0\xd1Pf\xf3\x93\u0478\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4k\xf8o\x1e/+\x802\xa9\\Mw8\xa1\t\xd3\xd0\xed\x81\x04\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4l\x05\xe3N^\xf2\xf4.\u041d\xef\xf1\x02l\xd6k\xcbi`\xbb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4l\b\xa6\xdc\x01s\xc74)U\xd1\xd3\xf2\xc0e\xd6/\x83\xae\u01c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4l\n\xe9\xf0C\xc84\xd4Bq\xf14\x06Y=\xfe\tO8\x9f\x89RD*\xe13\xb6*\x80\x00\u07d4l\f\xc9\x17\xcb\xee}|\t\x97c\xf1Nd\xdf}4\xe2\xbf\t\x89\r\x8drkqw\xa8\x00\x00\xe0\x94l\x0eq/@\\Yr_\xe8)\xe9wK\xf4\xdf\u007fM\xd9e\x8a\f(h\x88\x9c\xa6\x8aD\x00\x00\xe0\x94l\x10\x12\x05\xb3#\xd7uD\xd6\xdcR\xaf7\xac\xa3\xce\xc6\xf7\xf1\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4l\x15\xec5 \xbf\x8e\xbb\xc8 \xbd\x0f\xf1\x97x7T\x94\u03dd\x89l\xb7\xe7Hg\xd5\xe6\x00\x00\xe0\x94l\x1d\xdd3\xc8\x19f\u0706!w`q\xa4\x12\x94\x82\xf2\xc6_\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4l%2\u007f\x8d\u02f2\xf4^V\x1e\x86\xe3]\x88P\xe5:\xb0Y\x89;\xcd\xf9\xba\xfe\xf2\xf0\x00\x00\u07d4l.\x9b\xe6\u052bE\x0f\xd1%1\xf3?\x02\x8caFt\xf1\x97\x89\xc2\x12z\xf8X\xdap\x00\x00\u07d4l5\x9eX\xa1=Ex\xa93\x8e3\\g\xe7c\x9f_\xb4\u05c9\v\xd1[\x94\xfc\x8b(\x00\x00\u07d4l=\x18pA&\xaa\x99\xee3B\xce`\xf5\xd4\xc8_\x18g\u0349\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4lGK\xc6jTx\x00f\xaaOQ.\xef\xa7s\xab\xf9\x19\u01c9\x05\x18\x83\x15\xf7v\xb8\x00\x00\u07d4lNBn\x8d\xc0\x05\u07e3Ql\xb8\xa6\x80\xb0.\ua56e\x8e\x89Hz\x9a0E9D\x00\x00\u07d4lR\xcf\b\x95\xbb5\xe6V\x16\x1eM\xc4j\xe0\xe9m\xd3\xe6,\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4lT\"\xfbK\x14\xe6\u064b`\x91\xfd\xecq\xf1\xf0\x86@A\x9d\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4l\\:T\u0367\xc2\xf1\x18\xed\xbaCN\xd8\x1en\xbb\x11\xddz\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4lc\xf8EV\u0490\xbf\u0359\xe44\ue657\xbf\xd7yWz\x89lk\x93[\x8b\xbd@\x00\x00\u07d4lc\xfc\x85\x02\x9a&T\u05db+\xeaM\xe3I\xe4REw\u0149#\xc7W\a+\x8d\xd0\x00\x00\u07d4led\xe5\xc9\xc2N\xaa\xa7D\xc9\xc7\xc9h\xc9\xe2\xc9\xf1\xfb\xae\x89I\x9bB\xa2\x119d\x00\x00\xe0\x94lg\xd6\xdb\x1d\x03Ql\x12\x8b\x8f\xf24\xbf=I\xb2m)A\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4lg\xe0\u05f6.*\bPiE\xa5\xdf\xe3\x82c3\x9f\x1f\"\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4lj\xa0\xd3\vdr\x19\x90\xb9PJ\x86?\xa0\xbf\xb5\xe5}\xa7\x89\x92^\x06\xee\xc9r\xb0\x00\x00\u07d4lqJX\xff\xf6\xe9}\x14\xb8\xa5\xe3\x05\xeb$@eh\x8b\xbd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4l\x80\rKI\xba\a%\x04`\xf9\x93\xb8\xcb\xe0\v&j%S\x89\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\u07d4l\x80\x8c\xab\xb8\xff_\xbbc\x12\xd9\xc8\xe8J\xf8\xcf\x12\xef\bu\x89\xd8\xd8X?\xa2\xd5/\x00\x00\xe0\x94l\x82 )!\x8a\xc8\xe9\x8a&\f\x1e\x06@)4\x889\x87[\x8a\x01\x0f\x97\xb7\x87\xe1\xe3\b\x00\x00\u07d4l\x84\u02e7|m\xb4\xf7\xf9\x0e\xf1=^\xe2\x1e\x8c\xfc\u007f\x83\x14\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94l\x86\x87\xe3Aw\x10\xbb\x8a\x93U\x90!\xa1F\x9ej\x86\xbcw\x8a\x02[-\xa2x\xd9k{\x80\x00\xe0\x94l\x88,'s,\xef\\|\x13\xa6\x86\xf0\xa2\xeawUZ\u0089\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4l\xa5\xde\x00\x81}\xe0\xce\xdc\xe5\xfd\x00\x01(\xde\xde\x12d\x8b<\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4l\xa6\xa12\xce\x1c\u0488\xbe\xe3\x0e\xc7\xcf\xef\xfb\x85\xc1\xf5\nT\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94l\xb1\x1e\xcb2\xd3\u0382\x96\x011\x066\xf5\xa1\f\xf7\u03db_\x8a\x04?\u851c8\x01\xf5\x00\x00\u07d4l\xc1\xc8x\xfal\u078a\x9a\v\x83\x11$~t\x1eFB\xfem\x895e\x9e\xf9?\x0f\xc4\x00\x00\xe0\x94l\xcb\x03\xac\xf7\xf5<\xe8z\xad\xcc!\xa9\x93-\xe9\x15\xf8\x98\x04\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4l\xd2\x12\xae\xe0N\x01?=*\xba\u04a0#`k\xfb\\j\u01c9lj\xccg\u05f1\xd4\x00\x00\u07d4l\xd2(\xdcq!i0\u007f\xe2|\xebtw\xb4\x8c\xfc\x82r\xe5\x89\x044\xea\x94\u06caP\x00\x00\u07d4l\xe1\xb0\xf6\xad\xc4pQ\xe8\xab8\xb3\x9e\xdbA\x86\xb0;\xab\u0309Ay\x97\x94\xcd$\xcc\x00\x00\u07d4l\xea\xe3s=\x8f\xa4=l\xd8\f\x1a\x96\xe8\xeb\x93\x10\x9c\x83\xb7\x89\x10'\x94\xad \xdah\x00\x00\u07d4m\x05i\xe5U\x8f\xc7\xdf'f\xf2\xba\x15\u070a\xef\xfc[\xebu\x89\xd8\xe6\x00\x1el0+\x00\x00\u07d4m\x12\x0f\f\xaa\xe4O\xd9K\xca\xfeU\xe2\xe2y\uf5ba\\z\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4m\x14V\xff\xf0\x10N\xe8D\xa31G7\x8438\xd2L\xd6l\x89\a\xb0l\xe8\u007f\xddh\x00\x00\u07d4m \xef\x97\x04g\nP\v\xb2i\xb5\x83.\x85\x98\x02\x04\x9f\x01\x89\a\f\x1c\xc7;\x00\xc8\x00\x00\xe0\x94m/\x97g4\xb9\xd0\a\r\x18\x83\xcfz\u02b8\xb3\xe4\x92\x0f\xc1\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4m9\xa9\u93c1\xf7i\xd7:\xad,\xea\xd2v\xac\x13\x87\xba\xbe\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4m;x6\xa2\xb9\u0619r\x1aM#{R#\x85\xdc\xe8\xdf\u034966\xc2^f\xec\xe7\x00\x00\u07d4m?+\xa8V\u033b\x027\xfava\x15k\x14\xb0\x13\xf2\x12@\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94m@\b\xb4\xa8\x88\xa8&\xf2H\xeej\v\r\xfd\xe9\xf92\x10\xb9\x8a\x01'\xfc\xb8\xaf\xae \xd0\x00\x00\u07d4m@\xca'\x82m\x97s\x1b>\x86\xef\xfc\u05f9*Aa\xfe\x89\x89lk\x93[\x8b\xbd@\x00\x00\u07d4mD\x97J1\u0447\xed\xa1m\xddG\xb9\xc7\xecP\x02\xd6\x1f\xbe\x892\xf5\x1e\u06ea\xa30\x00\x00\xe0\x94mK\\\x05\xd0j \x95~\x17H\xabm\xf2\x06\xf3C\xf9/\x01\x8a\x02\x1f6\x06\x99\xbf\x82_\x80\x00\xe0\x94mL\xbf=\x82\x84\x83:\xe9\x93D0>\b\xb4\xd6\x14\xbf\xda;\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4mY\xb2\x1c\xd0\xe2t\x88\x04\u066b\xe0d\xea\u00be\xf0\xc9_'\x89lk\x93[\x8b\xbd@\x00\x00\u07d4mc\u04ce\xe8\xb9\x0e\x0en\xd8\xf1\x92\xed\xa0Q\xb2\u05a5\x8b\xfd\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4mf4\xb5\xb8\xa4\x01\x95\xd9I\x02z\xf4\x82\x88\x02\t,\ued89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94m}\x1c\x94\x95\x11\xf8\x83\x03\x80\x8c`\xc5\xea\x06@\xfc\xc0&\x83\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4m\x84m\xc1&W\xe9\x1a\xf2P\bQ\x9c>\x85\u007fQp}\u0589\xf8\xd3\v\xc9#B\xf8\x00\x00\u07d4m\x91\x93\x99k\x19F\x17!\x11\x06\xd1c^\xb2l\u0136ll\x89\x15\xaa\x1e~\x9d\xd5\x1c\x00\x00\u07d4m\x99\x97P\x98\x82\x02~\xa9G#\x14$\xbe\xde\xde)e\u043a\x89l\x81\u01f3\x11\x95\xe0\x00\x00\u07d4m\xa0\xed\x8f\x1di3\x9f\x05\x9f*\x0e\x02G\x1c\xb4O\xb8\u00fb\x892\xbc8\xbbc\xa8\x16\x00\x00\u07d4m\xb7+\xfdC\xfe\xf4e\xcaV2\xb4Z\xabra@N\x13\xbf\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94m\xbe\x8a\xbf\xa1t(\x06&9\x817\x1b\xf3\xd3U\x90\x80kn\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4m\xc3\xf9+\xaa\x1d!\u06b78+\x892a\xa05o\xa7\xc1\x87\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4m\xc7\x05:q\x86\x16\xcf\u01cb\xeec\x82\xeeQ\xad\xd0\xc7\x030\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94m\xcc~d\xfc\xaf\xcb\xc2\xdcl\x0e^f,\xb3G\xbf\xfc\xd7\x02\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4m\xda_x\x8alh\x8d\u07d2\x1f\xa3\x85.\xb6\xd6\xc6\xc6)f\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4m\xdb`\x92w\x9dXB\xea\xd3x\xe2\x1e\x81 \xfdLk\xc12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4m\xdf\xefc\x91U\u06ab\n\\\xb4\x95:\xa8\u016f\xaa\x88\x04S\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4m\xe0/-\xd6~\xfd\xb794\x02\xfa\x9e\xaa\xcb\xcfX\x9d.V\x89@\x13\x8b\x91~\u07f8\x00\x00\u07d4m\u4d418\\\xf7\xfc\x9f\xe8\xc7}\x13\x1f\xe2\xeew$\xc7j\x89})\x97s=\xcc\xe4\x00\x00\u07d4m\xe4\xd1R\x19\x18/\xaf:\xa2\xc5\xd4\xd2Y_\xf20\x91\xa7'\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4m\xed\xf6.t?M,*K\x87\xa7\x87\xf5BJz\xeb9<\x89\t\xc2\x00vQ\xb2P\x00\x00\u07d4m\xf2Of\x85\xa6/y\x1b\xa37\xbf?\xf6~\x91\xf3\u053c:\x89ukI\xd4\nH\x18\x00\x00\u07d4m\xf5\xc8O{\x90\x9a\xab>a\xfe\x0e\xcb\x1b;\xf2`\"*\u0489\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4m\xff\x90\xe6\xdc5\x9d%\x90\x88+\x14\x83\xed\xbc\xf8\x87\xc0\xe4#\x8965\u026d\xc5\u07a0\x00\x00\u07d4n\x01\xe4\xadV\x9c\x95\xd0\a\xad\xa3\r^-\xb1(\x88I\"\x94\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\a;f\u0478\xc6gD\u0600\x96\xa8\u0759\xec~\x02(\u0689\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\x0e\xe7\x06\x12\xc9v(}I\x9d\u07e6\xc0\xdc\xc1,\x06\xde\xea\x89\a\v\u0579V!F\x00\x00\xe0\x94n\x12\xb5\x1e\"[JCr\xe5\x9a\u05e2\xa1\xa1>\xa3\u04e17\x8a\x03\x00F\xc8\xccw_\x04\x00\x00\u07d4n\x1a\x04l\xaf[JW\xf4\xfdK\xc1sb!&\xb4\xe2\xfd\x86\x89a\t=|,m8\x00\x00\u07d4n\x1e\xa4\xb1\x83\xe2R\u027bwg\xa0\x06\u05346\x96\u02ca\xe9\x89\x0f\xf3x<\x85\xee\u0400\x00\u07d4n%[p\n\xe7\x13\x8aK\xac\xf2(\x88\xa9\xe2\xc0\n(^\xec\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n'\n\xd5)\xf1\xf0\xb8\xd9\xcbm$'\xec\x1b~-\xc6Jt\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4n.\xab\x85\u0709\xfe)\xdc\n\xa1\x852G\u06b4:R=V\x89\x04V9\x18$O@\x00\x00\u07d4n:Q\xdbt=3M/\xe8\x82$\xb5\xfe|\x00\x8e\x80\xe6$\x89\x05\xbf\v\xa6cOh\x00\x00\u07d4nL*\xb7\xdb\x02i9\xdb\u04fch8J\xf6`\xa6\x18\x16\xb2\x89\t\r\x97/22<\x00\x00\u07d4nM.9\u0203f)\u5d07\xb1\x91\x8af\x9a\xeb\u07556\x8965\u026d\xc5\u07a0\x00\x00\u07d4n\\-\x9b\x1cTj\x86\xee\xfd]\nQ \xc9\xe4\xe70\x19\x0e\x89\n\xd2\x01\xa6yO\xf8\x00\x00\u07d4n`\xae\u19cf\x8e\u068bBLs\xe3S5J\xe6|0B\x89\xbd5\xa4\x8d\x99\x19\xe6\x00\x00\u07d4nd\xe6\x12\x9f\"N7\x8c\x0ensj~z\x06\xc2\x11\xe9\xec\x8965\u026d\xc5\u07a0\x00\x00\u07d4nm[\xbb\xb9\x05;\x89\xd7D\xa2s\x16\u00a7\xb8\xc0\x9bT}\x891Rq\n\x02>m\x80\x00\u07d4nr\xb2\xa1\x18j\x8e)\x16T;\x1c\xb3jh\x87\x0e\xa5\u0457\x89\n\x15D\xbe\x87\x9e\xa8\x00\x00\u07d4nv\x1e\xaa\x0f4_w{TA\xb7:\x0f\xa5\xb5k\x85\xf2-\x89lk\x93[\x8b\xbd@\x00\x00\u07d4ny\xed\u0504[\anL\u060d\x18\x8bnC-\xd9?5\xaa\x893\xc5I\x901r\f\x00\x00\u07d4n\x82\x12\xb7\"\xaf\xd4\b\xa7\xa7>\xd3\xe29^\xe6EJ\x030\x89\b\x9e\x91y\x94\xf7\x1c\x00\x00\u07d4n\x84\x87m\xbb\x95\xc4\vfV\xe4+\xa9\xae\xa0\x8a\x99;T\u0709;\xbc`\xe3\xb6\u02fe\x00\x00\u07d4n\x84\xc2\xfd\x18\xd8\tW\x14\xa9h\x17\x18\x9c\xa2\x1c\xcab\xba\xb1\x89\x12{lp&!\u0340\x00\u07d4n\x86m\x03-@Z\xbd\xd6\\\xf6QA\x1d\x807\x96\xc2#\x11\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94n\x89\x9eY\xa9\xb4\x1a\xb7\xeaA\xdfu\x17\x86\x0f*\xcbY\xf4\xfd\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4n\x89\xc5\x1e\xa6\xde\x13\xe0l\xdct\x8bg\xc4A\x0f\u9f2b\x03\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\x8a&h\x9fz/\xde\xfd\x00\x9c\xba\xaaS\x10%4P\u06ba\x89o!7\x17\xba\xd8\xd3\x00\x00\u07d4n\x96\xfa\xed\xa3\x05C\x02\xc4_X\xf1a2L\x99\xa3\xee\xbbb\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4n\xb0\xa5\xa9\xae\x96\xd2,\xf0\x1d\x8f\xd6H;\x9f8\xf0\x8c,\x8b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\xb3\x81\x96\x17@@X&\x8f\f<\xff5\x96\xbf\xe9\x14\x8c\x1c\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94n\xb5W\x8ak\xb7\xc3!S\x19[\r\x80 \xa6\x91HR\xc0Y\x8a\x8b\u00ab\xf4\x02!\xf4\x80\x00\x00\u07d4n\xbb^iW\xaa\x82\x1e\xf6Y\xb6\x01\x8a9:PL\xaeDP\x89lk\x93[\x8b\xbd@\x00\x00\u07d4n\xbc\xf9\x95\u007f_\xc5\u916d\xd4u\";\x04\xb8\xc1Jz\xed\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4n\xc3e\x95q\xb1\x1f\x88\x9d\xd49\xbc\xd4\xd6u\x10\xa2[\xe5~\x89\x06\xaa\xf7\xc8Qm\f\x00\x00\u07d4n\u021b9\xf9\xf5'jU>\x8d\xa3\x0en\xc1z\xa4~\xef\u01c9\x18BO_\v\x1bN\x00\x00\u07d4n\xc9m\x13\xbd\xb2M\u01e5W)?\x02\x9e\x02\xddt\xb9zU\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\xca\xef\xa6\xfc>\xe54bm\xb0,o\x85\xa0\u00d5W\x1ew\x89 \x86\xac5\x10R`\x00\x00\u07d4n\u04a1+\x02\xf8\u0188\u01f5\u04e6\xea\x14\xd66\x87\u06b3\xb6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4n\u0604E\x9f\x80\x9d\xfa\x10\x16\xe7p\xed\xaf>\x9f\xefF\xfa0\x89\xb8R\xd6x \x93\xf1\x00\x00\xe0\x94n\xdf\u007fR\x83r\\\x95>\xe6C\x17\xf6a\x88\xaf\x11\x84\xb03\x8a\x01\xb4d1\x1dE\xa6\x88\x00\x00\u07d4n\xe8\xaa\xd7\xe0\xa0e\u0605-|;\x9an_\xdcK\xf5\f\x00\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4n\xef\u0705\x0e\x87\xb7\x15\xc7'\x91w<\x03\x16\xc3U\x9bX\xa4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4n\xf9\xe8\u0276!}Vv\x9a\xf9}\xbb\x1c\x8e\x1b\x8b\xe7\x99\u0489\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4n\xfb\xa8\xfb*\u0176s\a)\xa9r\xec\"D&\xa2\x87\u00ed\x89\x0fY\x85\xfb\xcb\xe1h\x00\x00\xe0\x94n\xfd\x90\xb55\xe0\v\xbd\x88\x9f\xda~\x9c1\x84\xf8y\xa1Q\u06ca\x02#\x85\xa8'\xe8\x15P\x00\x00\u07d4o\x05\x16f\xcbO{\u04b1\x90r!\xb8)\xb5U\u05e3\xdbt\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4o\x0e\xdd#\xbc\xd8_`\x15\xf9(\x9c(\x84\x1f\xe0L\x83\xef\xeb\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4o\x13zq\xa6\xf1\x97\xdf,\xbb\xf0\x10\u073d\x89a\t=|,m8\x00\x00\u07d4p\x10\xbe-\xf5{\u042b\x9a\xe8\x19l\xd5\n\xb0\xc5!\xab\xa9\xf9\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4p#\xc7\tV\xe0J\x92\xd7\x00%\xaa\u0497\xb59\xaf5Xi\x89lk\x93[\x8b\xbd@\x00\x00\u07d4p%\x96]+\x88\xda\x19}DY\xbe=\xc98cD\xcc\x1f1\x89l\xb7\xe7Hg\xd5\xe6\x00\x00\u07d4p(\x02\xf3m\x00%\x0f\xabS\xad\xbc\u0596\xf0\x17oc\x8aI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4pH\x19\xd2\xe4Mn\xd1\xda%\xbf\u0384\u011f\u0322V\x13\xe5\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4pJn\xb4\x1b\xa3O\x13\xad\xdd\xe7\xd2\xdb}\xf0I\x15\u01e2!\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4pJ\xb1\x15\r^\x10\xf5\xe3I\x95\b\xf0\xbfpe\x0f\x02\x8dK\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4pJ\xe2\x1dv-n\x1d\xde(\xc25\xd11\x04Yr6\xdb\x1a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4pM$<)x\xe4l,\x86\xad\xbe\xcd$n;)_\xf63\x89m\x12\x1b\xeb\xf7\x95\xf0\x00\x00\u07d4pM]\xe4\x84m9\xb5<\xd2\x1d\x1cI\xf0\x96\xdb\\\x19\xba)\x89\b=lz\xabc`\x00\x00\u07d4p]\xdd85T\x82\xb8\xc7\u04f5\x15\xbd\xa1P\r\xd7\u05e8\x17\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94pan(\x92\xfa&\x97\x05\xb2\x04k\x8f\xe3\xe7/\xa5X\x16\u04ca\x04<3\xc1\x93ud\x80\x00\x00\u07d4pg\x0f\xbb\x05\xd30\x14DK\x8d\x1e\x8ew\x00%\x8b\x8c\xaam\x89lk\x93[\x8b\xbd@\x00\x00\u07d4p\x81\xfak\xaa\xd6\u03f7\xf5\x1b,\xca\x16\xfb\x89p\x99\x1ad\xba\x89\f\xae\xc0\x05\xf6\xc0\xf6\x80\x00\xe0\x94p\x85\xae~~M\x93!\x97\xb5\u01c5\x8c\x00\xa3gF&\xb7\xa5\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4p\x86\xb4\xbd\xe3\xe3]J\xeb$\xb8%\xf1\xa2\x15\xf9\x9d\x85\xf7E\x89lh\xcc\u041b\x02,\x00\x00\u07d4p\x8a*\xf4%\u03b0\x1e\x87\xff\xc1\xbeT\xc0\xf52\xb2\x0e\xac\u0589\aE\u0503\xb1\xf5\xa1\x80\x00\u07d4p\x8e\xa7\a\xba\xe45\u007f\x1e\xbe\xa9Y\u00e2P\xac\u05aa!\xb3\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u0794p\x8f\xa1\x1f\xe3=\x85\xad\x1b\xef\u02ee8\x18\xac\xb7\x1fj}~\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4p\x9101\x16\xd5\xf28\x9b##\x8bMej\x85\x96\u0644\u04c9;N~\x80\xaaX3\x00\x00\u07d4p\x99\xd1/n\xc6V\x89\x9b\x04\x9avW\x06]b\x99h\x92\u0209\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4p\x9f\xe9\xd2\xc1\xf1\xceB |\x95\x85\x04J`\x89\x9f5\x94/\x89lk\x93[\x8b\xbd@\x00\x00\u07d4p\xa05I\xaaah\xe9~\x88\xa5\b3\nZ\v\xeatq\x1a\x89Hz\x9a0E9D\x00\x00\u07d4p\xa4\x06}D\x8c\xc2]\xc8\xe7\x0ee\x1c\xea|\xf8N\x92\x10\x9e\x89\t\x8a}\x9b\x83\x14\xc0\x00\x00\u07d4p\xab4\xbc\x17\xb6o\x9c;c\xf1Q'O*r|S\x92c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4p\xc2\x13H\x8a\x02\f<\xfb9\x01N\xf5\xbad\x04rK\u02a3\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4p\xd2^\xd2\u022d\xa5\x9c\b\x8c\xf7\r\xd2+\xf2\u06d3\xac\xc1\x8a\x899GEE\u4b7c\x00\x00\u07d4p\xe5\xe9\xdas_\xf0w$\x9d\u02da\xaf=\xb2\xa4\x8d\x94\x98\xc0\x8965\u026d\xc5\u07a0\x00\x00\u07d4p\xfe\xe0\x8b\x00\xc6\xc2\xc0Jp\xc0\xce=\x92\u03ca\x01Z\xf1\u05cbX\xc4\x00\x00\x00\u0794q\v\xe8\xfd^)\x18F\x8b\u2abe\xa8\r\x82\x845\u05d6\x12\x88\xf4?\xc2\xc0N\xe0\x00\x00\u07d4q\x13]\x8f\x05\x96<\x90ZJ\a\x92)\t#Z\x89jR\ua262\xa1]\tQ\x9b\xe0\x00\x00\u07d4q\x1e\xcfw\xd7\x1b=\x0e\xa9\\\xe4u\x8a\xfe\u0379\xc11\a\x9d\x89)3\x1eeX\xf0\xe0\x00\x00\u07d4q!?\xca14\x04 N\u02e8q\x97t\x1a\xa9\xdf\xe9c8\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94q+vQ\x02\x14\xdcb\x0fl:\x1d\u049a\xa2+\xf6\xd2\x14\xfb\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4q/\xf77\n\x13\xed6\ts\xfe\u071f\xf5\xd2\xc9:P^\x9e\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4q3\x84:x\xd99\u019dD\x86\xe1\x0e\xbc{`*4\x9f\xf7\x89\x11\xd5\xca\xcc\xe2\x1f\x84\x00\x00\u07d4qH\xae\xf32a\xd8\x03\x1f\xac?q\x82\xff5\x92\x8d\xafT\u0649\xdeB\xee\x15D\u0750\x00\x00\u07d4qcu\x8c\xbblLR^\x04\x14\xa4\n\x04\x9d\xcc\xcc\xe9\x19\xbb\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4qh\xb3\xbb\x8c\x16s!\u067d\xb0#\xa6\xe9\xfd\x11\xaf\u026f\u0649a\t=|,m8\x00\x00\u07d4qirN\xe7\"q\xc54\xca\xd6B\x0f\xb0N\xe6D\u02c6\xfe\x89\x16<+@\u06e5R\x00\x00\u07d4qj\xd3\xc3:\x9b\x9a\n\x18\x96sW\x96\x9b\x94\xee}*\xbc\x10\x89\x1a!\x17\xfeA*H\x00\x00\xe0\x94qk\xa0\x1e\xad*\x91'\x065\xf9_%\xbf\xaf-\xd6\x10\xca#\x8a\ty\xe7\x01 V\xaax\x00\x00\u07d4qmP\u0320\x1e\x93\x85\x00\xe6B\x1c\xc0p\xc3P|g\u04c7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4qv,cg\x8c\x18\xd1\xc67\x8c\xe0h\xe6f8\x13\x15\x14~\x89lk\x93[\x8b\xbd@\x00\x00\u07d4qxL\x10Q\x17\xc1\xf6\x895y\u007f\xe1Y\xab\xc7NC\xd1j\x89l\x81\u01f3\x11\x95\xe0\x00\x00\xe0\x94qyro\\q\xae\x1bm\x16\xa6\x84(\x17Nk4\xb26F\x8a\x01\x8e\xa2P\t|\xba\xf6\x00\x00\xe0\x94q|\xf9\xbe\xab680\x8d\xed~\x19^\f\x86\x13-\x16?\xed\x8a\x032n\xe6\xf8e\xf4\"\x00\x00\u07d4q\x80\xb8>\xe5WC\x17\xf2\x1c\x80r\xb1\x91\u0615\xd4aS\u00c9\x18\xef\xc8J\xd0\u01f0\x00\x00\u07d4q\x94kq\x17\xfc\x91^\xd1\a8_B\u065d\xda\xc62I\u0089lk\x93[\x8b\xbd@\x00\x00\xe0\x94q\x9e\x89\x1f\xbc\xc0\xa3>\x19\xc1-\xc0\xf0 9\xca\x05\xb8\x01\u07ca\x01OU8F:\x1bT\x00\x00\u07d4q\xc7#\n\x1d5\xbd\u0581\x9e\u0539\xa8\x8e\x94\xa0\xeb\a\x86\u0749\uc80b5=$\x14\x00\x00\u07d4q\xd2\xccm\x02W\x8ce\xf7\r\xf1\x1bH\xbe\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4r\x83\xcdFu\xdaX\u0116UaQ\xda\xfd\x80\xc7\xf9\x95\xd3\x18\x89)3\x1eeX\xf0\xe0\x00\x00\u07d4r\x86\xe8\x9c\xd9\u078fz\x8a\x00\xc8o\xfd\xb59\x92\u0752Q\u0449i*\xe8\x89p\x81\xd0\x00\x00\u07d4r\x8f\x9a\xb0\x80\x15}\xb3\a1V\xdb\xca\x1a\x16\x9e\xf3\x17\x94\a\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4r\x94\xc9\x18\xb1\xae\xfbM%\x92~\xf9\u05d9\xe7\x1f\x93\xa2\x8e\x85\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94r\x94\uc763\x10\xbckK\xbd\xf5C\xb0\xefE\xab\xfc>\x1bM\x8a\x04\xa8\x9fT\xef\x01!\xc0\x00\x00\u07d4r\x9a\xadF'tNS\xf5\xd6c\t\xaatD\x8b:\xcd\xf4o\x89lk\x93[\x8b\xbd@\x00\x00\u07d4r\xa2\xfc\x86u\xfe\xb9r\xfaA\xb5\r\xff\u06fa\xe7\xfa*\u07f7\x89\x9a\xb4\xfcg\xb5(\xc8\x00\x00\u07d4r\xa8&\b&)G&\xa7[\xf3\x9c\u066a\x9e\a\xa3\xea\x14\u0349lk\x93[\x8b\xbd@\x00\x00\u07d4r\xb0Yb\xfb*\u0549\xd6Z\xd1j\"U\x9e\xba\x14X\xf3\x87\x89\a?u\u0460\x85\xba\x00\x00\u07d4r\xb5c?\xe4w\xfeT.t/\xac\xfdi\f\x13xT\xf2\x16\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4r\xb7\xa0=\xda\x14\u029cf\x1a\x1dF\x9f\xd376\xf6s\xc8\xe8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4r\xb9\x04D\x0e\x90\xe7 \u05ac\x1c*\u05dc2\x1d\xcc\x1c\x1a\x86\x89T\x06\x923\xbf\u007fx\x00\x00\xe0\x94r\xb9\nM\xc0\x97#\x94\x92\u0179w}\xcd\x1eR\xba+\xe2\u008a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4r\xbb'\u02d9\xf3\xe2\xc2\u03d0\xa9\x8fp}0\xe4\xa2\x01\xa0q\x89X\xe7\x92n\xe8X\xa0\x00\x00\xe0\x94r\xc0\x83\xbe\xad\xbd\xc2'\xc5\xfbC\x88\x15\x97\xe3.\x83\xc2`V\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4r\xcd\x04\x8a\x11\x05tH)\x83I-\xfb\x1b\xd2yB\xa6\x96\xba\x89lk\x93[\x8b\xbd@\x00\x00\u07d4r\xd0=M\xfa\xb3P\f\xf8\x9b\x86\x86o\x15\xd4R\x8e\x14\xa1\x95\x89\xf3K\x82\xfd\x8e\x91 \x00\x00\u07d4r\u06bb[n\ud799\xbe\x91X\x88\xf6V\x80V8\x16\b\xf8\x89\vL\x96\xc5,\xb4\xfe\x80\x00\u07d4r\xfbI\u009d#\xa1\x89P\u0132\xdc\r\xdfA\x0fS-oS\x89lk\x93[\x8b\xbd@\x00\x00\u07d4r\xfe\xaf\x12EyR9Td[\u007f\xaf\xff\x03x\xd1\xc8$.\x8965\u026d\xc5\u07a0\x00\x00\u07d4s\x01\xdcL\xf2mq\x86\xf2\xa1\x1b\xf8\xb0\x8b\xf2)F?d\xa3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4s\x04G\xf9|\xe9\xb2_\"\xba\x1a\xfb6\xdf'\xf9Xk\ub6c9,s\xc97t,P\x00\x00\u07d4s\x06\xde\x0e(\x8bV\xcf\u07d8~\xf0\xd3\xcc)f\a\x93\xf6\u0749\x1b\x8a\xbf\xb6.\xc8\xf6\x00\x00\xe0\x94s\r\x87c\u01a4\xfd\x82J\xb8\xb8Y\x16\x1e\xf7\xe3\xa9j\x12\x00\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4s\x12\x81sH\x95(\x01.v\xb4\x1a^(\u018b\xa4\xe3\xa9\u050965\u026d\xc5\u07a0\x00\x00\u07d4s\x13F\x12\bETUFTE\xa4Y\xb0l7s\xb0\xeb0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4s/\xea\xd6\x0f{\xfd\u05a9\xde\u0101%\xe3s]\xb1\xb6eO\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4sB#\xd2\u007f\xf2>Y\x06\xca\xed\"YW\x01\xbb4\x83\f\xa1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4sG>r\x11Q\x10\xd0\xc3\xf1\x17\b\xf8nw\xbe+\xb0\x98<\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4sRXm\x02\x1a\xd0\xcfw\xe0\xe9(@JY\xf3t\xffE\x82\x89\xb8Pz\x82\a( \x00\x00\u07d4sU\v\xebs+\xa9\u076f\xdaz\xe4\x06\xe1\x8f\u007f\xeb\x0f\x8b\xb2\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4s[\x97\xf2\xfc\x1b\xd2K\x12\an\xfa\xf3\xd1(\x80s\xd2\f\x8c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4s^2\x86f\xedV7\x14+3\x06\xb7|\xccT`\xe7,=\x89j\xb8\xf3xy\u0251\x00\x00\u07d4sc\u0350\xfb\xab[\xb8\u011a\xc2\x0f\xc6,9\x8f\xe6\xfbtL\x89lk\x93[\x8b\xbd@\x00\x00\u07d4skDP=\xd2\xf6\xddTi\xffL[-\xb8\xeaO\xece\u0409\x11\x04\xeeu\x9f!\xe3\x00\x00\xe0\x94sk\xf1@,\x83\x80\x0f\x89>X1\x92X*\x13N\xb52\xe9\x8a\x02\x1e\x19\u0493\xc0\x1f&\x00\x00\xe0\x94s\x8c\xa9M\xb7\u038b\xe1\xc3\x05l\u0598\x8e\xb3v5\x9f3S\x8a\x05f[\x96\xcf5\xac\xf0\x00\x00\u07d4s\x91K\"\xfc/\x13\x15\x84$}\x82\xbeO\ucfd7\x8a\u053a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4s\x93'\t\xa9\u007f\x02\u024eQ\xb0\x911(e\x12#\x85\xae\x8e\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4s\x93\xcb\xe7\xf9\xba!e\xe5\xa7U5\x00\xb6\xe7]\xa3\xc3:\xbf\x89\x05k\xc7^-c\x10\x00\x00\u07d4s\xb4\u0519\xde?8\xbf5\xaa\xf7i\xa6\xe3\x18\xbcm\x126\x92\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94s\xbe\xddo\xda{\xa3'!\x85\b{cQ\xfc\x13=HN7\x8a\x01\x12&\xbf\x9d\xceYx\x00\x00\u07d4s\xbf\xe7q\x0f1\u02b9I\xb7\xa2`O\xbfR9\xce\xe7\x90\x15\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94s\u03c0\xae\x96\x88\xe1X\x0eh\xe7\x82\xcd\b\x11\xf7\xaaIM,\x8a\x01\xa4\xab\xa2%\xc2\a@\x00\x00\xe0\x94s\xd7&\x9f\xf0l\x9f\xfd3uL\xe5\x88\xf7J\x96j\xbb\xbb\xba\x8a\x01e\xc9fG\xb3\x8a \x00\x00\u07d4s\xd8\xfe\xe3\u02c6M\xce\"\xbb&\u029c/\bm^\x95\xe6;\x8965\u026d\xc5\u07a0\x00\x00\u07d4s\xdf<>yU\xf4\xf2\xd8Y\x83\x1b\xe3\x80\x00\xb1\ak8\x84\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4s\u48b6\f\U0010e2ef+w~\x17Z[\x1eM\f-\x8f\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94t\n\xf1\xee\xfd3e\u05cb\xa7\xb1,\xb1\xa6s\xe0j\arF\x8a\x04+\xf0kx\xed;P\x00\x00\xe0\x94t\v\xfdR\xe0\x16g\xa3A\x9b\x02\x9a\x1b\x8eEWj\x86\xa2\u06ca\x03\x8e\xba\xd5\xcd\xc9\x02\x80\x00\x00\u07d4t\x0fd\x16\x14w\x9d\u03e8\x8e\xd1\xd4%\xd6\r\xb4*\x06\f\xa6\x896\"\xc6v\b\x10W\x00\x00\u07d4t\x12\u027c0\xb4\xdfC\x9f\x021\x00\xe69$\x06j\xfdS\xaf\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4t\x16\x93\xc3\x03vP\x85\x13\b \xcc+c\xe9\xfa\x92\x13\x1b\x89A\rXj \xa4\xc0\x00\x00\u07d4t!\xce[\xe3\x81s\x8d\u0703\xf0&!\x97O\xf0hly\xb8\x89Xx\x8c\xb9K\x1d\x80\x00\x00\u07d4t1j\xdf%7\x8c\x10\xf5v\u0574\x1aoG\xfa\x98\xfc\xe3=\x89\x128\x13\x1e\\z\xd5\x00\x00\u07d4t6Q\xb5^\xf8B\x9d\xf5\f\xf8\x198\xc2P\x8d\xe5\u0207\x0f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4t=\xe5\x00&\xcag\xc9M\xf5O\x06b`\xe1\xd1J\xcc\x11\xac\x89lk\x93[\x8b\xbd@\x00\x00\u07d4tE /\ft)z\x00N\xb3rj\xa6\xa8-\xd7\xc0/\xa1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4tK\x03\xbb\xa8X*\xe5I\x8e-\xc2-\x19\x94\x94g\xabS\xfc\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4tL\fw\xba\u007f#i \xd1\xe44\xde]\xa3>H\xeb\xf0,\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4tP\xff\u007f\x99\xea\xa9\x11bu\u07ach\xe4(\xdf[\xbc\u0639\x89lk\x93[\x8b\xbd@\x00\x00\u07d4tV\u0172\xc5Cn>W\x10\b\x93?\x18\x05\xcc\xfe4\xe9\xec\x8965\u026d\xc5\u07a0\x00\x00\u07d4tZ\u04eb\xc6\xee\xeb$qh\x9bS\x9ex\x9c\xe2\xb8&\x83\x06\x89=A\x94\xbe\xa0\x11\x92\x80\x00\xe0\x94tZ\xec\xba\xf9\xbb9\xb7Jg\xea\x1c\xe6#\xde6\x84\x81\xba\xa6\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4t\\\xcf-\x81\x9e\u06fd\u07a8\x11{\\I\xed<*\x06n\x93\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4tb\u021c\xaa\x9d\x8dx\x91\xb2T]\xef!otd\u057b!\x89\x05\xea\xedT\xa2\x8b1\x00\x00\u07d4td\x8c\xaa\xc7H\xdd\x13\\\xd9\x1e\xa1L(\xe1\xbdM\u007f\xf6\xae\x89\xa8\r$g~\xfe\xf0\x00\x00\xe0\x94tq\xf7.\xeb0\x06$\xeb(.\xabM\x03r\x00\x00\x00\xe0\x94t\x84\xd2k\xec\xc1\xee\xa8\xc61^\xc3\xee\nE\x01\x17\u0706\xa0\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4t\x86:\xce\xc7]\x03\xd5>\x86\x0ed\x00/,\x16^S\x83w\x8965\u026d\xc5\u07a0\x00\x00\u07d4t\x89\u030a\xbeu\u0364\xef\r\x01\xce\xf2`^G\xed\xa6z\xb1\x89\a?u\u0460\x85\xba\x00\x00\u07d4t\x8c(^\xf1#?\xe4\xd3\x1c\x8f\xb17\x833r\x1c\x12\xe2z\x89lk\x93[\x8b\xbd@\x00\x00\u07d4t\x90\x87\xac\x0fZ\x97\xc6\xfa\xd0!S\x8b\xf1\xd6\u0361\x8e\r\xaa\x8965\u026d\xc5\u07a0\x00\x00\u07d4t\x95\xaex\xc0\xd9\x02a\xe2\x14\x0e\xf2\x061\x04s\x1a`\xd1\xed\x89\x01\xdbPq\x89%!\x00\x00\u07d4t\x9aJv\x8b_#rH\x93\x8a\x12\xc6#\x84{\xd4\xe6\x88\u0709\x03\xe73b\x87\x14 \x00\x00\u07d4t\x9a\xd6\xf2\xb5pk\xbe/h\x9aD\u0136@\xb5\x8e\x96\xb9\x92\x89\x05k\xc7^-c\x10\x00\x00\u07d4t\xa1\u007f\x06K4N\x84\xdbce\u0695\x91\xff\x16(%vC\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4t\xae\xec\x91]\xe0\x1c\u019b,\xb5\xa65o\xee\xa1FX\xc6\u0149\f\x9a\x95\xee)\x86R\x00\x00\u07d4t\xaf\xe5I\x02\xd6\x15x%v\xf8\xba\xac\x13\xac\x97\f\x05\x0fn\x89\t\xa1\xaa\xa3\xa9\xfb\xa7\x00\x00\u07d4t\xb7\xe0\"\x8b\xae\xd6YW\xae\xbbM\x91m3:\xae\x16O\x0e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4t\xbcJ^ E\xf4\xff\x8d\xb1\x84\xcf:\x9b\f\x06Z\xd8\a\u0489lk\x93[\x8b\xbd@\x00\x00\u07d4t\xbc\xe9\xec86-l\x94\u032c&\xd5\xc0\xe1:\x8b;\x1d@\x8965&A\x04B\xf5\x00\x00\u07d4t\xbfzZ\xb5\x92\x93\x14\x9b\\`\xcf6Bc\xe5\xeb\xf1\xaa\r\x89\x06G\f>w\x1e<\x00\x00\xe0\x94t\xc7<\x90R\x8a\x15s6\xf1\xe7\xea b\n\xe5?\xd2G(\x8a\x01\xe6:.S\x8f\x16\xe3\x00\x00\u07d4t\u0464\xd0\xc7RN\x01\x8dN\x06\xed;d\x80\x92\xb5\xb6\xaf,\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94t\xd3f\xb0{/VG}|pw\xaco\xe4\x97\xe0\xebeY\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4t\xd3zQt{\xf8\xb7q\xbf\xbfC\x9493\xd1\x00\xd2\x14\x83\x8965\u026d\xc5\u07a0\x00\x00\u07d4t\xd6q\u065c\xbe\xa1\xabW\x90cu\xb6?\xf4+PE\x1d\x17\x8965\u026d\xc5\u07a0\x00\x00\u07d4t\xeb\xf4BVF\xe6\u03c1\xb1\t\xce{\xf4\xa2\xa6=\x84\x81_\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4t\xed3\xac\xf4?5\xb9\x8c\x920\xb9\xe6d.\xcbS0\x83\x9e\x89$\xf6\xdf\xfbI\x8d(\x00\x00\u07d4t\xef(i\xcb\xe6\b\x85`E\xd8\xc2\x04\x11\x18W\x9f\"6\xea\x89\x03<\xd6E\x91\x95n\x00\x00\u07d4t\xfcZ\x99\xc0\xc5F\x05\x03\xa1;\x05\tE\x9d\xa1\x9c\xe7\u0350\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4u\v\xbb\x8c\x06\xbb\xbf$\bC\xccux.\xe0/\b\xa9tS\x89-C\xf3\xeb\xfa\xfb,\x00\x00\u07d4u\x14\xad\xbd\xc6?H?0M\x8e\x94\xb6\u007f\xf30\x9f\x18\v\x82\x89!\u0120n-\x13Y\x80\x00\u0794u\x17\xf1l(\xd12\xbb@\xe3\xba6\u01ae\xf11\xc4b\xda\x17\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4u\x1a,\xa3Nq\x87\xc1c\u048e6\x18\xdb(\xb1<\x19m&\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94u\x1a\xbc\xb6\xcc\x030Y\x91\x18\x15\xc9o\u04516\n\xb0D-\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4u&\xe4\x82R\x9f\n\x14\xee\u0248q\xdd\xdd\x0er\x1b\f\u0662\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4u)\xf3y{\xb6\xa2\x0f~\xa6I$\x19\xc8L\x86vA\xd8\x1c\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94u*^\xe22a,\xd3\x00_\xb2n[Y}\xe1\x9fwk\xe6\x8a\x01'\xfc\xb8\xaf\xae \xd0\x00\x00\u07d4u,\x9f\xeb\xf4/f\xc4x{\xfa~\xb1|\xf53;\xbaPp\x89j\x99\xf2\xb5O\xddX\x00\x00\u07d4u930F\u07b1\xef\x8e\u07b9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94u\xc1\xad#\xd2?$\xb3\x84\xd0\xc3\x14\x91w\xe8f\x97a\r!\x8a\x01\\[\xcdl(\x8b\xbd\x00\x00\u07d4u\xc2\xff\xa1\xbe\xf5I\x19\xd2\t\u007fz\x14-.\x14\xf9\xb0JX\x89\x90\xf3XP@2\xa1\x00\x00\u07d4u\xd6|\xe1N\x8d)\xe8\xc2\xff\u3051{\x93\v\x1a\xff\x1a\x87\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4u\xde~\x93R\xe9\v\x13\xa5\x9aXx\xff\xec\u01c3\x1c\xacM\x82\x89\x94\x89#z\u06daP\x00\x00\u07d4u\xf7S\x9d0\x9e\x909\x98\x9e\xfe.\x8b-\xbd\x86Z\r\xf0\x88\x89\x85[[\xa6\\\x84\xf0\x00\x00\u07d4v\b\xf47\xb3\x1f\x18\xbc\vd\u04c1\xae\x86\xfd\x97\x8e\u05f3\x1f\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94v\x0f\xf35N\x0f\u0793\x8d\x0f\xb5\xb8,\xef[\xa1\\=)\x16\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4v\x1an6,\x97\xfb\xbd|Yw\xac\xba-\xa7F\x876_I\x89\t\xf7J\xe1\xf9S\xd0\x00\x00\u07d4v\x1el\xae\xc1\x89\xc20\xa1b\xec\x00e0\x19>g\u03dd\x19\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94v\x1f\x8a:*\U00028f7e\x1d\xa0\t2\x1f\xb2\x97d\xebb\xa1\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4v)\x98\xe1\xd7R'\xfc\xedzp\xbe\x10\x9aL\vN\xd8d\x14\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4v-o0\u06b9\x915\xe4\xec\xa5\x1dRC\xd6\xc8b\x11\x02\u0549\x0fI\x89A\xe6d(\x00\x00\u07d4v3\x1e0yl\xe6d\xb2p\x0e\rASp\x0e\u0706\x97w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4v8\x86\xe33\xc5o\xef\xf8[\xe3\x95\x1a\xb0\xb8\x89\xce&.\x95\x89lk\x93[\x8b\xbd@\x00\x00\u07d4v:|\xba\xb7\rzd\u0427\xe5)\x80\xf6\x81G%\x93I\f\x89 \x86\xac5\x10R`\x00\x00\u07d4v>\xec\u0c0a\u021e2\xbf\xa4\xbe\xcev\x95\x14\xd8\xcb[\x85\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4v@\xa3\u007f\x80R\x98\x15\x15\xbc\xe0x\u0693\xaf\xa4x\x9bW4\x89lk\x93[\x8b\xbd@\x00\x00\u0794vA\xf7\xd2j\x86\xcd\xdb+\xe10\x81\x81\x0e\x01\xc9\xc8E\x89dI\xe8NG\xa8\xa8\x00\x00\xe0\x94vO\xc4mB\x8bm\xbc\"\x8a\x0f_U\xc9P\x8cw.\xab\x9f\x8a\x05\x81v{\xa6\x18\x9c@\x00\x00\u07d4vPn\xb4\xa7\x80\xc9Q\xc7J\x06\xb0=;\x83b\xf0\x99\x9dq\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94v[\xe2\xe1/b\x9ecI\xb9}!\xb6*\x17\xb7\xc80\xed\xab\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94vb\x81P\xe2\x99[['\x9f\xc8>\r\xd5\xf1\x02\xa6q\xdd\x1c\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4vk7Y\xe8yN\x92m\xacG=\x91:\x8f\xb6\x1a\xd0\xc2\u0249\x04\xb0m\xbb\xb4\x0fJ\x00\x00\u07d4vp\xb0/,<\xf8\xfdOG0\xf38\x1aq\xeaC\x1c3\u01c9\x0e~\xeb\xa3A\vt\x00\x00\u07d4vz\x03eZ\xf3`\x84\x1e\x81\r\x83\xf5\xe6\x1f\xb4\x0fL\xd1\x13\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4vz\u0190y\x1c.#E\x10\x89\xfelp\x83\xfeU\u07b6+\x89,s\xc97t,P\x00\x00\u07d4v\u007f\xd7y}Qi\xa0_sd2\x1c\x19\x84:\x8c4\x8e\x1e\x89\x01\x04\xe7\x04d\xb1X\x00\x00\u0794v\x84o\r\xe0;Zv\x97\x1e\xad)\x8c\xdd\b\x84:K\xc6\u0188\xd7\x1b\x0f\u088e\x00\x00\xe0\x94v\x84\x98\x93N7\xe9\x05\xf1\xd0\xe7{D\xb5t\xbc\xf3\xecJ\xe8\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4v\x8c\xe0\u06a0)\xb7\xde\xd0\"\xe5\xfcWM\x11\xcd\xe3\xec\xb5\x17\x89\x11t\xa5\xcd\xf8\x8b\xc8\x00\x00\xe0\x94v\x93\xbd\xebo\xc8+[\xcar\x13U\"1u\xd4z\bKM\x8a\x04\xa8\x9fT\xef\x01!\xc0\x00\x00\u07d4v\xaa\xf8\xc1\xac\x01/\x87R\xd4\xc0\x9b\xb4f\a\xb6e\x1d\\\xa8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4v\xab\x87\xddZ\x05\xad\x83\x9aN/\xc8\xc8Z\xa6\xba\x05d\x170\x89lk\x93[\x8b\xbd@\x00\x00\u07d4v\xaf\xc2%\xf4\xfa0}\xe4\x84U+\xbe\x1d\x9d?\x15\aLJ\x89\xa2\x90\xb5\u01ed9h\x00\x00\xe0\x94v\xbe\xca\xe4\xa3\x1d6\xf3\xcbW\u007f*CYO\xb1\xab\xc1\xbb\x96\x8a\x05C\xa9\xce\x0e\x132\xf0\x00\x00\u07d4v\xc2u5\xbc\xb5\x9c\xe1\xfa-\x8c\x91\x9c\xab\xebJk\xba\x01\u0449lk\x93[\x8b\xbd@\x00\x00\u07d4v\xca\"\xbc\xb8y\x9eS'\u012a*}\tI\xa1\xfc\xce_)\x89R\xa0?\"\x8cZ\xe2\x00\x00\u07d4v\xca\u0108\x11\x1aO\u0555\xf5h\xae:\x85\x87p\xfc\x91]_\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94v\u02dc\x8bi\xf48vu\u0102S\xe24\xcb~\rt\xa4&\x8a\x01\x90\xf4H.\xb9\x1d\xae\x00\x00\u07d4v\xf8:\xc3\xda0\xf7\t&(\xc73\x9f \x8b\xfc\x14,\xb1\ue25a\x18\xff\xe7B}d\x00\x00\xe0\x94v\xf9\xad=\x9b\xbd\x04\xae\x05\\\x14w\xc0\xc3^u\x92\xcb* \x8a\b\x83?\x11\xe3E\x8f \x00\x00\u07d4v\xff\xc1W\xadk\xf8\xd5m\x9a\x1a\u007f\u077c\x0f\xea\x01\n\xab\xf4\x8965\u026d\xc5\u07a0\x00\x00\u07d4w\x02\x8e@\x9c\xc4:;\xd3=!\xa9\xfcS\xec`n\x94\x91\x0e\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4w\f/\xb2\u0128\x17S\xac\x01\x82\xeaF\x0e\xc0\x9c\x90\xa5\x16\xf8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4w\r\x98\xd3\x1bCS\xfc\xee\xe8V\fL\u03c0>\x88\xc0\xc4\xe0\x89 \x86\xac5\x10R`\x00\x00\xe0\x94w\x13\xab\x807A\x1c\t\xbah\u007fo\x93d\xf0\xd3#\x9f\xac(\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4w\x15\a\xae\xeej%]\xc2\u035d\xf5QT\x06-\b\x97\xb2\x97\x89\x12\x1e\xa6\x8c\x11NQ\x00\x00\u07d4w\x19\x88\x87\x95\xadtY$\xc7W`\u0771\x82}\xff\xd8\u0368\x89lkLM\xa6\u077e\x00\x00\u07d4w'\xaf\x10\x1f\n\xab\xa4\xd2:\x1c\xaf\xe1|n\xb5\u06b1\xc6\u0709lk\x93[\x8b\xbd@\x00\x00\u07d4w,)\u007f\n\u0454H.\xe8\xc3\xf06\xbd\xeb\x01\xc2\x01\xd5\u0309\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94w0o\xfe.J\x8f<\xa8&\xc1\xa2I\xf7!-\xa4:\xef\xfd\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4w1A\x12}\x8c\xf3\x18\xae\xbf\x886Z\xdd=U'\xd8[j\x8966\u05ef^\u024e\x00\x00\u07d4wF\xb6\xc6i\x9c\x8f4\xca'h\xa8 \xf1\xff\xa4\xc2\a\xfe\x05\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4wQ\xf3c\xa0\xa7\xfd\x053\x19\b\t\u076f\x93@\xd8\xd1\x12\x91\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4wW\xa4\xb9\xcc=\x02G\u032a\xeb\x99\t\xa0\xe5n\x1d\xd6\xdc\u0089\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4w\\\x10\xc9>\r\xb7 [&CE\x823\xc6O\xc3?\xd7[\x89lk\x93[\x8b\xbd@\x00\x00\u07d4wa~\xbcK\xeb\xc5\xf5\xdd\xeb\x1bzp\xcd\xebj\xe2\xff\xa0$\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4wiC\xff\xb2\xef\\\xdd5\xb8<(\xbc\x04k\xd4\xf4gp\x98\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94wp\x1e,I=\xa4|\x1bX\xf4!\xb5I]\xeeE\xbe\xa3\x9b\x8a\x01H\xf6I\xcfaB\xa5\x80\x00\u07d4wy\x8f \x12W\xb9\xc3R\x04\x95pW\xb5Ft\xae\xfaQ\u07c9\b\x13\xcaV\x90m4\x00\x00\u07d4w\x8cC\xd1\x1a\xfe;Xo\xf3t\x19-\x96\xa7\xf2=+\x9b\u007f\x89\x8b\xb4\xfc\xfa;}k\x80\x00\u07d4w\x8cy\xf4\xde\x19S\xeb\u0398\xfe\x80\x06\xd5:\x81\xfbQ@\x12\x8963\x03\"\xd5#\x8c\x00\x00\u07d4w\x92t\xbf\x18\x03\xa36\xe4\u04f0\r\u0753\xf2\xd4\xf5\xf4\xa6.\x8965\u026d\xc5\u07a0\x00\x00\u07d4w\xa1q\"\xfa1\xb9\x8f\x17\x11\xd3*\x99\xf0>\xc3&\xf3=\b\x89\\(=A\x03\x94\x10\x00\x00\u07d4w\xa3I\a\xf3\x05\xa5L\x85\xdb\t\xc3c\xfd\xe3\xc4~j\xe2\x1f\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4w\xa7i\xfa\xfd\xec\xf4\xa68v-[\xa3\x96\x9d\xf61 \xa4\x1d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4w\xbekd\xd7\xc73\xa46\xad\xec^\x14\xbf\x9a\xd7@+\x1bF\x8965\u026d\xc5\u07a0\x00\x00\u07d4w\xbf\xe9<\u0367P\x84~A\xa1\xaf\xfe\xe6\xb2\u0696\xe7!N\x89\x10CV\x1a\x88)0\x00\x00\u07d4w\u0126\x97\xe6\x03\xd4+\x12\x05l\xbb\xa7a\xe7\xf5\x1d\x04C\xf5\x89$\xdc\xe5M4\xa1\xa0\x00\x00\u07d4w\xcc\x02\xf6#\xa9\u03d8S\t\x97\xeag\xd9\\;I\x18Y\xae\x89Is\x03\xc3n\xa0\xc2\x00\x00\u07d4w\xd4?\xa7\xb4\x81\xdb\xf3\xdbS\f\xfb\xf5\xfd\xce\xd0\xe6W\x181\x89lk\x93[\x8b\xbd@\x00\x00\u07d4w\xda^lr\xfb6\xbc\xe1\xd9y\x8f{\xcd\xf1\u044fE\x9c.\x89\x016\x95\xbbl\xf9>\x00\x00\u07d4w\xf4\xe3\xbd\xf0V\x88<\xc8r\x80\xdb\xe6@\xa1\x8a\r\x02\xa2\a\x89\n\x81\x99:+\xfb[\x00\x00\u0794w\xf6\t\u0287 \xa0#&,U\xc4o-&\xfb90\xaci\x88\xf0\x15\xf2W6B\x00\x00\u07d4w\xf8\x1b\x1b&\xfc\x84\xd6\u0797\uf2df\xbdr\xa310\xccJ\x8965\u026d\xc5\u07a0\x00\x00\u07d4x\x19\xb0E\x8e1N+S\xbf\xe0\f8I_\u0539\xfd\xf8\u0589\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4x\x1b\x15\x01dz.\x06\xc0\xedC\xff\x19\u007f\xcc\xec5\xe1p\v\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4x/R\xf0\xa6v\xc7w\x16\xd5t\xc8\x1e\xc4hO\x9a\x02\n\x97\x89.\x14\xe2\x06\xb70\xad\x80\x00\u07d4x5]\xf0\xa20\xf8=\x03,p1TAM\xe3\xee\u06b5W\x89lk\x93[\x8b\xbd@\x00\x00\u07d4x6\xf7\xefk\u01fd\x0f\xf3\xac\xafD\x9c\x84\xddk\x1e,\x93\x9f\x89\xe0\x8d\xe7\xa9,\xd9|\x00\x00\u07d4x7\xfc\xb8v\xda\x00\xd1\xeb;\x88\xfe\xb3\xdf?\xa4\x04/\xac\x82\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4x>\uc2a5\xda\xc7{.f#\xedQ\x98\xa41\xab\xba\xee\a\x89\x17\xda:\x04\u01f3\xe0\x00\x00\u07d4x\\\x8e\xa7t\xd70D\xa74\xfay\n\x1b\x1et>w\xed|\x89\f\xf1Rd\f\\\x83\x00\x00\u07d4x`\xa3\xde8\xdf8*\xe4\xa4\xdc\xe1\x8c\f\a\xb9\x8b\xce=\xfa\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94xcCq\xe1s\x04\xcb\xf39\xb1E*L\xe48\xdcvL\u038a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4xd\u0719\x9f\xe4\xf8\xe0\x03\xc0\xf4=\xec\u00da\xae\x15\"\xdc\x0f\x89\x05\x1e\x10+\xd8\xec\xe0\x00\x00\u07d4xtj\x95\x8d\xce\xd4\xc7d\xf8vP\x8cAJh4,\uce49\x02\xbe7O\xe8\xe2\xc4\x00\x00\xe0\x94x}1?\xd3k\x05>\xee\xae\xdb\xcet\xb9\xfb\x06x32\x89\x8a\x05\xc0X\xb7\x84'\x19`\x00\x00\u07d4x\x85\x9c[T\x8bp\r\x92\x84\xce\xe4\xb6c=GJ\x8a\x04{\x92\xc4\x15B$-\n\b\xc7\x0f\x99\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4x\u03c36\xb3(\xdb=\x87\x81:G+\x9e\x89\xb7^\f\xf3\xbc\x8965\u026d\xc5\u07a0\x00\x00\u07d4x\xd4\xf8\xc7\x1c\x1eh\xa6\x9a\x98\xf5/\xcbE\u068a\xf5n\xa1\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4x\xdf&\x81\xd6\xd6\x02\xe2!B\xd5A\x16\u07a1]EIW\xaa\x89\x10'\x94\xad \xdah\x00\x00\u07d4x\xe0\x8b\xc53A<&\u2473\x14?\xfa|\u026f\xb9{x\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4x\xe8?\x80\xb3g\x8cz\nN>\x8c\x84\xdc\xcd\xe0dBbw\x89a\t=|,m8\x00\x00\u07d4x\xf5\xc7G\x85\xc5f\x8a\x83\x80r\x04\x8b\xf8\xb4SYM\u06ab\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4y\x0f\x91\xbd]\x1c\\\xc4s\x9a\xe9\x13\x00\u06c9\xe1\xc10<\x93\x89lk\x93[\x8b\xbd@\x00\x00\u07d4y\x17\u5f42\xa9y\x0f\xd6P\xd0C\xcd\xd90\xf7y\x963\u06c9\xd8\xd4`,&\xbfl\x00\x00\u07d4y\x19\xe7b\u007f\x9b}T\xea;\x14\xbbM\xd4d\x9fO9\xde\xe0\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4y\x1f`@\xb4\xe3\xe5\r\xcf5S\xf1\x82\u0357\xa9\x060\xb7]\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4y0\xc2\xd9\xcb\xfa\x87\xf5\x10\xf8\xf9\x87w\xff\x8a\x84H\xcaV)\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4yE)\u041d\x01rq5\x970\x02pu\xb8z\xd8=\xaen\x89\x10\xce\x1d=\x8c\xb3\x18\x00\x00\u07d4yKQ\u00deS\xd9\xe7b\xb0a;\x82\x9aD\xb4r\xf4\xff\xf3\x89$5\xe0dxA\u0300\x00\xe0\x94yU\x1c\xed\xe3v\xf7G\xe3ql\x8dy@\rvm.\x01\x95\x8a\t\xcb7\xaf\xa4\xffxh\x00\x00\u07d4y^\xbc&&\xfc9\xb0\xc8b\x94\xe0\xe87\xdc\xf5#U0\x90\x8965\u026d\xc5\u07a0\x00\x00\u07d4yn\xbb\xf4\x9b>6\xd6v\x94\xady\xf8\xff6vz\xc6\xfa\xb0\x89\x03K\xc4\xfd\xde'\xc0\x00\x00\u07d4yo\x87\xbaaz)0\xb1g\v\xe9.\xd1(\x1f\xb0\xb3F\xe1\x89\x06\xf5\xe8o\xb5((\x00\x00\u07d4yt'\xe3\xdb\xf0\xfe\xaez%\x06\xf1-\xf1\xdc@2n\x85\x05\x8965\u026d\xc5\u07a0\x00\x00\u07d4yu\x10\xe3\x86\xf5c\x93\xce\xd8\xf4w7\x8aDLHO}\xad\x8965\u026d\xc5\u07a0\x00\x00\u07d4y{\xb7\xf1W\xd9\xfe\xaa\x17\xf7m\xa4\xf7\x04\xb7M\xc1\x03\x83A\x89\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4y\x88\x90\x131\xe3\x87\xf7\x13\xfa\u03b9\x00\\\xb9\xb6Q6\xeb\x14\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4y\x89\u041f8&\xc3\u5bccu*\x81\x15r:\x84\xd8\tp\x89\x16\x86\xf8aL\xf0\xad\x00\x00\xe0\x94y\x95\xbd\x8c\xe2\xe0\xc6{\xf1\u01e51\xd4w\xbc\xa1\xb2\xb9ua\x8a\x01BH\xd6\x17\x82\x9e\xce\x00\x00\u07d4y\xae\xb3Ef\xb9t\xc3ZX\x81\xde\xc0 \x92}\xa7\xdf]%\x89lk\x93[\x8b\xbd@\x00\x00\u07d4y\xb1 \xeb\x88\x06s#!(\x8fgZ'\xa9\"_\x1c\xd2\ub245\xa0\xbf7\xde\xc9\xe4\x00\x00\u07d4y\xb4\x8d-a7\u00c5Ma\x1c\x01\xeaBBz\x0fY{\xb7\x89\nZ\xa8P\t\xe3\x9c\x00\x00\u07d4y\xb8\xaa\xd8y\xdd0V~\x87x\xd2\xd21\xc8\xf3z\xb8sN\x89lk\x93[\x8b\xbd@\x00\x00\u07d4y\xbf/{n2\x8a\xaf&\xe0\xbb\t?\xa2-\xa2\x9e\xf2\xf4q\x89a\t=|,m8\x00\x00\u07d4y\xc10\xc7b\xb8v[\x19\u04ab\u0260\x83\xab\x8f:\xady@\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4y\xc1\xbe\x19q\x1fs\xbe\xe4\xe61j\xe7T\x94Y\xaa\u03a2\xe0\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4y\xc6\x00/\x84R\xca\x15\u007f\x13\x17\xe8\n/\xaf$GUY\xb7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4y\xca\xc6IO\x11\xef'\x98t\x8c\xb52\x85\xbd\x8e\"\xf9|\u0689lk\x93[\x8b\xbd@\x00\x00\u07d4y\u03e9x\n\xe6\xd8{,1\x88?\t'i\x86\u021ag5\x8965\u026d\xc5\u07a0\x00\x00\u07d4y\u06e2VG-\xb4\xe0X\xf2\xe4\xcd\xc3\xeaN\x8aBw83\x89O%\x91\xf8\x96\xa6P\x00\x00\u07d4y\xed\x10\xcf\x1fm\xb4\x82\x06\xb5\t\x19\xb9\xb6\x97\b\x1f\xbd\xaa\xf3\x89lk\x93[\x8b\xbd@\x00\x00\u0794y\xf0\x8e\x01\xce\t\x88\xe6<\u007f\x8f)\b\xfa\xdeC\xc7\xf9\xf5\u0248\xfc\x93c\x92\x80\x1c\x00\x00\u07d4y\xfdmH1Pf\xc2\x04\xf9e\x18i\xc1\tl\x14\xfc\x97\x81\x89lk\x93[\x8b\xbd@\x00\x00\u0794y\xff\xb4\xac\x13\x81*\vx\u0123{\x82u\">\x17k\xfd\xa5\x88\xf0\x15\xf2W6B\x00\x00\u07d4z\x05\x89\xb1C\xa8\xe5\xe1\a\u026cf\xa9\xf9\xf8Yz\xb3\u7ac9Q\xe92\xd7n\x8f{\x00\x00\u07d4z\nx\xa9\xcc9?\x91\xc3\xd9\xe3\x9ak\x8c\x06\x9f\a^k\xf5\x89Hz\x9a0E9D\x00\x00\u07d4z\x13p\xa7B\xec&\x87\xe7a\xa1\x9a\u0167\x942\x9e\xe6t\x04\x89\xa2\xa12ga\xe2\x92\x00\x00\xe0\x94z-\xfcw\x0e$6\x811\xb7\x84w\x95\xf2\x03\xf3\xd5\r[V\x8a\x02i\xfe\xc7\xf06\x1d \x00\x00\u07d4z3\x83N\x85\x83s>-R\xae\xadX\x9b\u046f\xfb\x1d\xd2V\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94z6\xab\xa5\xc3\x1e\xa0\xca~'{\xaa2\xecF\u0393\xcfu\x06\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94z8\x11\"\xba\xday\x1az\xb1\xf6\x03}\xac\x80C'S\xba\xad\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94zH\xd8w\xb6:\x8f\x8f\x93\x83\xe9\xd0\x1eS\xe8\fR\x8e\x95_\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4zO\x9b\x85\x06\x90\xc7\xc9F\x00\xdb\xee\f\xa4\xb0\xa4\x11\xe9\xc2!\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4zc\x86\x9f\xc7g\xa4\u01b1\xcd\x0e\x06I\xf3cL\xb1!\xd2K\x89\x043\x87Oc,\xc6\x00\x00\u07d4zg\xdd\x04:PO\xc2\xf2\xfcq\x94\xe9\xbe\xcfHL\xec\xb1\xfb\x89\r\x8drkqw\xa8\x00\x00\xe0\x94zk&\xf48\u0663RD\x91U\xb8\x87l\xbd\x17\xc9\u065bd\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4zmx\x1cw\u013a\x1f\xca\xdfhsA\xc1\xe3\x17\x99\xe9='\x89\x0e\u0683\x8cI)\b\x00\x00\u07d4zph\xe1\xc37\\\x0eY\x9d\xb1\xfb\xe6\xb2\xea#\xb8\xf4\a\u0489lk\x93[\x8b\xbd@\x00\x00\u07d4zt\xce\xe4\xfa\x0fcp\xa7\x89O\x11l\xd0\f\x11G\xb8>Y\x89+^:\xf1k\x18\x80\x00\x00\u07d4zy\xe3\x0f\xf0W\xf7\n=\x01\x91\xf7\xf5?v\x157\xaf}\xff\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94zzO\x80sW\xa4\xbb\xe6\x8e\x1a\xa8\x0692\x10\xc4\x11\u0333\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4z\x85c\x86y\x01 o?+\xf0\xfa>\x1c\x81\t\u02bc\u0345\x89\amA\xc6$\x94\x84\x00\x00\xe0\x94z\x87\x97i\n\xb7{Tp\xbf|\f\x1b\xbaa%\b\xe1\xac}\x8a\x01\xe0\x92\x96\xc37\x8d\xe4\x00\x00\u07d4z\x8c\x89\xc0\x14P\x9dV\u05f6\x810f\x8f\xf6\xa3\xec\xecsp\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94z\x94\xb1\x99\x92\u03b8\xcec\xbc\x92\xeeKZ\xde\xd1\fM\x97%\x8a\x03\x8d\x1a\x80d\xbbd\xc8\x00\x00\u07d4z\xa7\x9a\xc0C\x16\u030d\b\xf2\x00e\xba\xa6\xd4\x14(\x97\xd5N\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4z\xadM\xbc\u04ec\xf9\x97\u07d3XiV\xf7+d\u062d\x94\xee\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94z\xb2V\xb2\x04\x80\n\xf2\x017\xfa\xbc\xc9\x16\xa22Xu%\x01\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4z\xbaV\xf6:H\xbc\b\x17\u05b9p9\x03\x9az\xd6/\xae.\x89 \x86\xac5\x10R`\x00\x00\xe0\x94z\xbb\x10\xf5\xbd\x9b\xc3;\x8e\xc1\xa8-d\xb5[k\x18wuA\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4z\u010d@\xc6d\u031am\x89\xf1\xc5\xf5\xc8\n\x1cp\xe7D\u6263\x10b\xbe\xee\xd7\x00\x00\x00\u07d4z\u014fo\xfcO\x81\a\xaen07\x8eN\x9f\x99\xc5\u007f\xbb$\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4z\xd3\xf3\aao\x19\u0731C\xe6DM\xab\x9c<3a\x1fR\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4z\xd8,\xae\xa1\xa8\xb4\xed\x051\x9b\x9c\x98p\x17<\x81N\x06\xee\x89!d\xb7\xa0J\u0220\x00\x00\u07d4z\xde]f\xb9D\xbb\x86\f\x0e\xfd\xc8bv\u054fFS\xf7\x11\x89lk\x93[\x8b\xbd@\x00\x00\u07d4z\xdf\xed\xb0m\x91\xf3\xccs\x90E\v\x85U\x02p\x88<{\xb7\x89\x11x\xfa@Q]\xb4\x00\x00\u07d4z\xe1\xc1\x9eS\xc7\x1c\xeeLs\xfa\xe2\xd7\xfcs\xbf\x9a\xb5\u348965\u026d\xc5\u07a0\x00\x00\u07d4z\xe6Y\xeb;\xc4hR\xfa\x86\xfa\xc4\xe2\x1cv\x8dP8\x89E\x89\x0f\x81\f\x1c\xb5\x01\xb8\x00\x00\u07d4z\xea%\xd4+&\x12(n\x99\xc56\x97\u01bcA\x00\xe2\u06ff\x89lk\x93[\x8b\xbd@\x00\x00\u07d4z\xef{U\x1f\v\x9cF\xe7U\xc0\xf3\x8e[:s\xfe\x11\x99\xf5\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4{\v1\xffn$t^\xad\x8e\u067b\x85\xfc\v\xf2\xfe\x1dU\u0509+^:\xf1k\x18\x80\x00\x00\xe0\x94{\x0f\xea\x11v\xd5!Y3:\x14<)IC\xda6\xbb\u0774\x8a\x01\xfc}\xa6N\xa1L\x10\x00\x00\u07d4{\x11g<\xc0\x19bk)\f\xbd\xce&\x04o~m\x14\x1e!\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4{\x12!b\xc9\x13\xe7\x14l\xad\v~\xd3z\xff\xc9*\v\xf2\u007f\x89Q\xaf\tk#\x01\u0440\x00\u07d4{\x1b\xf5:\x9c\xbe\x83\xa7\u07a44W\x9f\xe7*\xac\x8d*\f\u0409\n\xd4\xc81j\v\f\x00\x00\u07d4{\x1d\xaf\x14\x89\x1b\x8a\x1e\x1b\xd4)\u0633k\x9aJ\xa1\u066f\xbf\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4{\x1f\xe1\xabM\xfd\x00\x88\xcd\xd7\xf6\x01c\xefY\xec*\xee\x06\xf5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4{%\xbb\x9c\xa8\xe7\x02!~\x933\"RP\xe5<6\x80MH\x89e\xea=\xb7UF`\x00\x00\u07d4{'\xd0\xd1\xf3\xdd<\x14\x02\x94\xd0H\x8bx>\xbf@\x15'}\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94{@\a\xc4^ZW?\u06f6\xf8\xbdtk\xf9J\xd0J<&\x8a\x038!\xf5\x13]%\x9a\x00\x00\u07d4{C\xc7\xee\xa8\xd6#U\xb0\xa8\xa8\x1d\xa0\x81\xc6Dk3\xe9\xe0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4{M*8&\x90i\xc1\x85Ww\rY\x1d$\xc5\x12\x1f^\x83\x89%\xf2s\x93=\xb5p\x00\x00\xe0\x94{au\xec\x9b\xef\xc78$\x955\xdd\xde4h\x8c\xd3n\xdf%\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94{f\x12hy\x84M\xfa4\xfee\xc9\xf2\x88\x11\u007f\xef\xb4I\xad\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4{j\x84q\x8d\xd8nc3\x84)\xac\x81\x1d|\x8a\x86\x0f!\xf1\x89a\t=|,m8\x00\x00\xe0\x94{q,z\xf1\x16v\x00jf\xd2\xfc\\\x1a\xb4\xc4y\xce`7\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4{s$-u\u029a\xd5X\xd6P)\r\xf1v\x92\xd5L\u0638\x89lnY\xe6|xT\x00\x00\u07d4{v\x1f\xeb\u007f\u03e7\xde\xd1\xf0\xeb\x05\x8fJ`\v\xf3\xa7\b\u02c9\xf9]\xd2\xec'\xcc\xe0\x00\x00\xe0\x94{\x82|\xae\u007f\xf4t\t\x18\xf2\xe00\xab&\u02d8\xc4\xf4l\xf5\x8a\x01\x94hL\v9\xde\x10\x00\x00\xe0\x94{\x892\x86B~r\xdb!\x9a!\xfcM\xcd_\xbfY(<1\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4{\x92&\xd4o\xe7Q\x94\v\xc4\x16\xa7\x98\xb6\x9c\xcf\r\xfa\xb6g\x89\u3bb5sr@\xa0\x00\x00\u07d4{\x98\xe2<\xb9k\xee\xe8\n\x16\x80i\ube8f \xed\xd5\\\u03c9\v\xa0\xc9\x15\x87\xc1J\x00\x00\u07d4{\xb0\xfd\xf5\xa6c\xb5\xfb\xa2\x8d\x9c\x90*\xf0\xc8\x11\xe2R\xf2\x98\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4{\xb9W\x1f9K\v\x1a\x8e\xbaVd\xe9\u0635\xe8@g{\xea\x89\x01\x11du\x9f\xfb2\x00\x00\xe0\x94{\xb9\x84\xc6\u06f9\xe2y\x96j\xfa\xfd\xa5\x9c\x01\xd0&'\xc8\x04\x8a\x01\xb4d1\x1dE\xa6\x88\x00\x00\u07d4{\xbb\xec^p\xbd\xea\u063b2\xb4(\x05\x98\x8e\x96H\xc0\xaa\x97\x8966\u05ef^\u024e\x00\x00\u07d4{\xca\x1d\xa6\xc8\nf\xba\xa5\xdbZ\u0245A\u013e'kD}\x89$\xcf\x04\x96\x80\xfa<\x00\x00\u07d4{\u0772\xee\x98\xde\x19\xeeL\x91\xf6a\xee\x8eg\xa9\x1d\x05K\x97\x8965\u026d\xc5\u07a0\x00\x00\u0794{\xe2\xf7h\f\x80-\xa6\x15L\x92\xc0\x19J\xe72Qzqi\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4{\xe7\xf2Eiq\x88;\x9a\x8d\xbeL\x91\xde\xc0\x8a\xc3N\x88b\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4{\xe8\u0334\xf1\x1bf\xcan\x1dW\xc0\xb59b!\xa3\x1b\xa5:\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94{\xeb\x81\xfb/^\x91Rk*\xc9y^v\u019b\xcf\xf0K\xc0\x8a\x0e\xb2.yO\n\x8d`\x00\x00\u07d4|\b\x83\x05L-\x02\xbcz\x85+\x1f\x86\xc4'w\xd0\xd5\xc8V\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4|\x0f^\a C\xc9\xeet\x02B\x19~x\xccK\x98\xcd\xf9`\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4|\x1d\xf2JO\u007f\xb2\u01f4r\xe0\xbb\x00l\xb2}\xcd\x16AV\x8965\u026d\xc5\u07a0\x00\x00\u07d4|)\xd4}W\xa73\xf5k\x9b!pc\xb5\x13\xdc;1Y#\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4|+\x96\x03\x88JO.FN\u03b9}\x17\x93\x8d\x82\x8b\xc0,\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4|8,\x02\x96a.N\x97\xe4@\xe0-8q';U\xf5;\x89\n\xb6@9\x12\x010\x00\x00\u07d4|>\xb7\x13\xc4\xc9\xe08\x1c\xd8\x15L|\x9a}\xb8d\\\xde\x17\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4|D\x01\xae\x98\xf1.\xf6\xde9\xae$\u03df\xc5\x1f\x80\xeb\xa1k\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4|E\xf0\xf8D*V\xdb\u04dd\xbf\x15\x99\x95A\\R\xedG\x9b\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94|S-\xb9\xe0\xc0l&\xfd@\xac\xc5j\xc5\\\x1e\xe9-<:\x8a?\x87\bW\xa3\xe0\xe3\x80\x00\x00\u07d4|`\xa0_zJ_\x8c\xf2xC\x916.uZ\x83A\xefY\x89f\x94\xf0\x18*7\xae\x00\x00\u07d4|`\xe5\x1f\v\xe2(\xe4\xd5o\xdd)\x92\xc8\x14\xdaw@\u01bc\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4|i$\xd0|>\xf5\x89\x19f\xfe\nxV\xc8{\xef\x9d 4\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94|\x8b\xb6Zo\xbbI\xbdA3\x96\xa9\xd7\xe3\x10S\xbb\xb3z\xa9\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94|\x9a\x11\f\xb1\x1f%\x98\xb2\xb2\x0e,\xa4\x002^A\xe9\xdb3\x8a\x05\x81v{\xa6\x18\x9c@\x00\x00\u07d4|\xbc\xa8\x8f\xcaj\x00`\xb9`\x98\\\x9a\xa1\xb0%4\xdc\"\b\x89\x19\x12z\x13\x91\xea*\x00\x00\u07d4|\xbe\xb9\x992\xe9~n\x02\x05\x8c\xfcb\u0432k\xc7\u0325+\x89lk\x93[\x8b\xbd@\x00\x00\u07d4|\xc2Jj\x95\x8c \xc7\xd1$\x96`\xf7Xb&\x95\v\r\x9a\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4|\xd2\x0e\u0335\x18\xb6\f\xab\t[r\x0fW\x15p\u02aaD~\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4|\xd5\xd8\x1e\xab7\xe1\x1ebv\xa3\xa1\t\x12Q`~\r~8\x89\x03hM^\xf9\x81\xf4\x00\x00\u07d4|\xdft!9E\x95=\xb3\x9a\xd0\xe8\xa9x\x1a\xddy.M\x1d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4|\xe4hdF\U000547be\xd6r\x15\xeb\rZ\x1d\xd7,\x11\xb8\x89x9\xd3!\xb8\x1a\xb8\x00\x00\u07d4|\xefMC\xaaA\u007f\x9e\xf8\xb7\x87\xf8\xb9\x9dS\xf1\xfe\xa1\ue209g\x8a\x93 b\xe4\x18\x00\x00\u07d4}\x03P\xe4\v3\x8d\xdasfa\x87+\xe3?\x1f\x97R\xd7U\x89\x02\xb4\xf5\xa6\U00051500\x00\xe0\x94}\x04\xd2\xed\xc0X\xa1\xaf\xc7a\xd9\u025a\xe4\xfc\\\x85\xd4\u0226\x8aB\xa9\xc4g\\\x94g\xd0\x00\x00\u07d4}\v%^\xfbW\xe1\x0fp\b\xaa\"\xd4\x0e\x97R\xdf\xcf\x03x\x89\x01\x9f\x8euY\x92L\x00\x00\xe0\x94}\x13\xd6pX\x84\xab!W\u074d\xccpF\xca\xf5\x8e\xe9K\xe4\x8a\x1d\r\xa0|\xbb>\xe9\xc0\x00\x00\u07d4}'>c~\xf1\xea\u0101\x11\x94\x13\xb9\x1c\x98\x9d\xc5\xea\xc1\"\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4}*R\xa7\xcf\f\x846\xa8\xe0\a\x97kl&\xb7\"\x9d\x1e\x15\x89\x17\xbf\x06\xb3*$\x1c\x00\x00\u07d4}4\x805i\xe0\v\u05b5\x9f\xff\b\x1d\xfa\\\n\xb4\x19zb\x89\\\xd8|\xb7\xb9\xfb\x86\x00\x00\u07d4}4\xffY\xae\x84\nt\x13\u01baL[\xb2\xba,u\xea\xb0\x18\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4}9(R\xf3\xab\xd9/\xf4\xbb[\xb2l\xb6\bt\xf2\xbeg\x95\x8966\xc2^f\xec\xe7\x00\x00\u07d4}DRg\u015a\xb8\u04a2\xd9\xe7\t\x99\x0e\th%\x80\u011f\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94}U\x13\x97\xf7\x9a)\x88\xb0d\xaf\xd0\xef\xeb\xee\x80,w!\xbc\x8a\bW\xe0\xd6\xf1\xdav\xa0\x00\x00\u07d4}Z\xa3?\xc1KQ\x84\x1a\x06\x90n\xdb+\xb4\x9c*\x11ri\x89\x10D\x00\xa2G\x0eh\x00\x00\xe0\x94}]/s\x94\x9d\xad\xda\bV\xb2\x06\x98\x9d\xf0\a\x8dQ\xa1\xe5\x8a\x02\xc4:H\x1d\xf0M\x01wb\xed\xcb\\\xaab\x9bZ\x89\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4~\x8f\x96\xcc)\xf5{\tu\x12\f\xb5\x93\xb7\u0743=`kS\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4~\x97*\x8a|*D\xc9;!Cl8\xd2\x1b\x92R\xc3E\xfe\x89a\t=|,m8\x00\x00\u07d4~\x99\u07fe\x98\x9d;\xa5)\u0457Q\xb7\xf41\u007f\x89S\xa3\xe2\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4~\xa0\xf9n\xe0\xa5s\xa30\xb5h\x97v\x1f=L\x010\xa8\xe3\x89Hz\x9a0E9D\x00\x00\u0794~\xa7\x91\xeb\xab\x04E\xa0\x0e\xfd\xfcNJ\x8e\x9a~ue\x13m\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4~\xab\xa05\xe2\xaf7\x93\xfdtgK\x10%@\xcf\x19\n\u0779\x89E\x02l\x83[`D\x00\x00\xe0\x94~\xb4\xb0\x18\\\x92\xb6C\x9a\b\xe72!h\xcb5<\x8awJ\x8a\x02'\x19l\xa0I\x83\xca\x00\x00\xe0\x94~\xbd\x95\xe9\xc4p\xf7(5\x83\xdcn\x9d,M\xce\v\ua3c4\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4~\u0425\xa8G\xbe\xf9\xa9\xda|\xba\x1dd\x11\xf5\xc3\x161&\x19\x89\x02(\xeb7\xe8u\x1d\x00\x00\u07d4~\xda\xfb\xa8\x98K\xafc\x1a\x82\vk\x92\xbb\xc2\xc56U\xf6\xbd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4~\xdb\x02\xc6\x1a\"r\x87a\x1a\xd9Pici\xccNdzh\x89\x0e\u0683\x8cI)\b\x00\x00\u07d4~\xe5\u0280]\xce#\xaf\x89\xc2\xd4D\xe7\xe4\af\xc5Lt\x04\x89\r\v\xd4\x12\xed\xbd\x82\x00\x00\xe0\x94~\xe6\x04\u01e9\xdc)\t\xce2\x1d\u6e72OWgWuU\x8a\x01+\xf9\u01d8\\\xf6-\x80\x00\u07d4~\xf1o\xd8\xd1[7\x8a\x0f\xba0k\x8d\x03\u0758\xfc\x92a\x9f\x89%\xf2s\x93=\xb5p\x00\x00\u07d4~\xf9\x8bR\xbe\xe9S\xbe\xf9\x92\xf3\x05\xfd\xa0'\xf8\x91\x1cXQ\x89\x1b\xe7\" i\x96\xbc\x80\x00\u07d4~\xfc\x90vj\x00\xbcR7,\xac\x97\xfa\xbd\x8a<\x83\x1f\x8e\u0349\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4~\xfe\xc0\xc6%<\xaf9\u007fq(|\x1c\a\xf6\xc9X+[\x86\x89\x1a,\xbc\xb8O0\u0540\x00\u07d4\u007f\x01\xdc|7G\xca`\x8f\x98=\xfc\x8c\x9b9\xe7U\xa3\xb9\x14\x89\v8l\xad_zZ\x00\x00\u07d4\u007f\x06b\xb4\x10)\x8c\x99\xf3\x11\u04e1EJ\x1e\xed\xba/\xeav\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\u007f\x06\u021dY\x80\u007f\xa6\v\xc6\x016\xfc\xf8\x14\u02ef%C\xbd\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u007f\v\x90\xa1\xfd\u050f'\xb2h\xfe\xb3\x83\x82\xe5]\xdbP\xef\x0f\x892\xf5\x1e\u06ea\xa30\x00\x00\u07d4\u007f\x0e\xc3\u06c0F\x92\xd4\xd1\xea2E6Z\xab\x05\x90\a[\u0109\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u007f\x0f\x04\xfc\xf3zS\xa4\xe2N\xden\x93\x10Nx\xbe\x1d<\x9e\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u007f\x13\xd7`I\x8dq\x93\xcahY\xbc\x95\xc9\x018d#\xd7l\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\u007f\x15\n\xfb\x1aw\u00b4Y(\xc2h\xc1\u9f74d\x1dG\u0609lk\x93[\x8b\xbd@\x00\x00\u07d4\u007f\x16\x19\x98\x8f7\x15\xe9O\xf1\xd2S&-\xc5X\x1d\xb3\xde\x1c\x890\xca\x02O\x98{\x90\x00\x00\u07d4\u007f\x1c\x81\xee\x16\x97\xfc\x14K|\v\xe5I;V\x15\xae\u007f\xdd\u0289\x1b\x1d\xaba\u04ead\x00\x00\u07d4\u007f#\x82\xff\xd8\xf89VFy7\xf9\xbar7F#\xf1\x1b8\x89 \x86\xac5\x10R`\x00\x00\u07d4\u007f7\t9\x1f?\xbe\xba5\x92\xd1u\xc7@\xe8z\tT\x1d\x02\x89\x1a\x05V\x90\xd9\u06c0\x00\x00\u07d4\u007f8\x9c\x12\xf3\xc6\x16OdFVlwf\x95\x03\xc2y%'\x89\x05V\xf6L\x1f\xe7\xfa\x00\x00\xe0\x94\u007f:\x1eE\xf6~\x92\u0200\xe5s\xb43y\xd7\x1e\xe0\x89\xdbT\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\u007f=r\x03\u0224G\xf7\xbf6\u060a\xe9\xb6\x06*^\xeex\xae\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\u007fF\xbb%F\r\xd7\xda\xe4!\x1c\xa7\xf1Z\xd3\x12\xfc}\xc7\\\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\u007fI\xe7\xa4&\x98\x82\xbd\x87\"\u0526\xf5f4v)b@y\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u007fI\xf2\a&G\x1a\xc1\u01e8>\xf1\x06\xe9w\\\xebf%f\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4\u007fK^'\x85x\xc0F\xcc\xea\xf6W0\xa0\xe0h2\x9e\u0576\x89e\xea=\xb7UF`\x00\x00\u07d4\u007fOY;a\x8c3\v\xa2\xc3\xd5\xf4\x1e\xce\xeb\x92\xe2~Bl\x89\x96n\xdcuk|\xfc\x00\x00\u07d4\u007fT\x14\x91\u04ac\x00\xd2a/\x94\xaa\u007f\v\xcb\x01FQ\xfb\u0509\x14b\fW\xdd\xda\xe0\x00\x00\u07d4\u007fZ\xe0Z\xe0\xf8\xcb\xe5\xdf\xe7!\xf0D\u05e7\xbe\xf4\xc2y\x97\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\u007f`:\xec\x17Y\xea_\a\xc7\xf8\xd4\x1a\x14(\xfb\xba\xf9\xe7b\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u007falo\x00\x8a\u07e0\x82\xf3M\xa7\xd0e\x04`6\x80u\xfb\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u007fa\xfal\xf5\xf8\x98\xb4@\xda\u016b\xd8`\rmi\x1f\xde\xf9\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\xe0\x94\u007fe\\g\x89\xed\xdfE\\\xb4\xb8\x80\x99r\x0698\x9e\ubb0a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\u007fk(\u0204!\xe4\x85~E\x92\x81\u05c4ai$\x89\xd3\xfb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u007fn\xfboC\x18\x87m.\xe6$\xe2u\x95\xf4DF\xf6\x8e\x93\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\u007fq\x92\xc0\xdf\x1c}\xb6\xd9\xede\xd7\x11\x84\xd8\xe4\x15Z\x17\xba\x89\x04Sr\x8d3\x94,\x00\x00\u07d4\u007fz:!\xb3\xf5\xa6]\x81\xe0\xfc\xb7\xd5-\xd0\n\x1a\xa3m\xba\x89\x05k\xc7^-c\x10\x00\x00\u07d4\u007f\x8d\xbc\xe1\x80\xed\x9cV65\xaa\xd2\xd9{L\xbcB\x89\x06\u0649\x90\xf54`\x8ar\x88\x00\x00\xe0\x94\u007f\x99=\xdb~\x02\u0082\xb8\x98\xf6\x15_h\x0e\xf5\xb9\xaf\xf9\a\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\u007f\x9f\x9bV\xe4(\x9d\xfbX\xe7\x0f\xd5\xf1*\x97\xb5m5\u01a5\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u007f\xa3~\xd6x\x87u\x1aG\x1f\x0e\xb3\x06\xbeD\xe0\xdb\xcd`\x89\x899vt\u007f\xe1\x1a\x10\x00\x00\u07d4\u007f\xaa0\xc3\x15\x19\xb5\x84\xe9rP\xed*<\xf38^\xd5\xfdP\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u007f\xcf[\xa6fo\x96lTH\xc1{\xf1\xcb\v\xbc\xd8\x01\x9b\x06\x89\x05k\xc3\u042e\xbeI\x80\x00\xe0\x94\u007f\xd6y\xe5\xfb\r\xa2\xa5\xd1\x16\x19M\xcbP\x83\x18\xed\u0140\xf3\x8a\x01c\x9eI\xbb\xa1b\x80\x00\x00\u07d4\u007f\u06e01\u01cf\x9c\tmb\xd0Z6\x9e\uac3c\xccU\u5257\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\u007f\xdb\u00e8D\xe4\r\x96\xb2\xf3\xa652.`e\xf4\xca\x0e\x84\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u007f\xdf\u020dx\xbf\x1b(Z\xc6O\x1a\xdb5\xdc\x11\xfc\xb09Q\x89|\x06\xfd\xa0/\xb06\x00\x00\u07d4\u007f\xea\x19b\xe3]b\x05\x97h\xc7I\xbe\u0756\u02b90\xd3x\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u007f\xef\x8c8w\x9f\xb3\a\xeco\x04K\xeb\xe4\u007f<\xfa\xe7\x96\xf1\x89\t#@\xf8l\xf0\x9e\x80\x00\u07d4\u007f\xf0\xc6?p$\x1b\xec\xe1\x9bs~SA\xb1+\x10\x901\u0609\x12\xc1\xb6\xee\xd0=(\x00\x00\xe0\x94\u007f\xfa\xbf\xbc9\f\xbeC\u0389\x18\x8f\bh\xb2}\xcb\x0f\f\xad\x8a\x01YQ\x82\"K&H\x00\x00\xe0\x94\u007f\xfd\x02\xed7\fp`\xb2\xaeS\xc0x\xc8\x01!\x90\u07fbu\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u0794\x80\x02*\x12\a\xe9\x10\x91\x1f\xc9(I\xb0i\xab\f\xda\xd0C\u04c8\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\x80\t\xa7\xcb\u0452\xb3\xae\u052d\xb9\x83\xd5(ER\xc1ltQ\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x80\x0e}c\x1cnW:\x903/\x17\xf7\x1f_\u045bR\x8c\xb9\x89\b=lz\xabc`\x00\x00\u07d4\x80\x15m\x10\ufa320\u0254\x10c\r7\xe2i\xd4\t<\xea\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x80\x172\xa4\x81\u00c0\xe5~\xd6-l)\u0799\x8a\xf3\xfa;\x13\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x80\x1de\xc5\x18\xb1\x1d\x0e?OG\x02!Ap\x13\xc8\xe5>\u0149\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x80&CZ\xacr\x8dI{\x19\xb3\xe7\xe5|(\xc5c\x95O+\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\x80-\xc3\xc4\xff-}\x92^\u215fJ\x06\u05fa`\xf10\x8c\x89\x05P\x94\f\x8f\xd3L\x00\x00\u07d4\x800\xb1\x11\u0198?\x04\x85\u076c\xa7b$\xc6\x18\x064x\x9f\x89\x04V9\x18$O@\x00\x00\u07d4\x805\xbc\xff\xae\xfd\xee\xea5\x83\fI}\x14(\x9d6 #\u0789\x10CV\x1a\x88)0\x00\x00\u07d4\x805\xfeNkj\xf2z\u44a5xQ^\x9d9\xfao\xa6[\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x80C\xed\"\xf9\x97\u58a4\xc1n6D\x86\xaed\x97V\x92\u0109=I\x04\xff\xc9\x11.\x80\x00\u07d4\x80C\xfd\u043cL\x97=\x16c\xd5_\xc15P\x8e\xc5\xd4\xf4\xfa\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x80L\xa9IrcOc:Q\xf3V\v\x1d\x06\xc0\xb2\x93\xb3\xb1\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x80R-\u07d4N\xc5.'\xd7$\xedL\x93\xe1\xf7\xbe`\x83\u0589\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x80Y\x1aB\x17\x9f4\xe6M\x9d\xf7]\xcdF;(hoUt\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x80\\\xe5\x12\x97\xa0y;\x81 g\xf0\x17\xb3\xe7\xb2\u07db\xb1\xf9\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\x80]\x84o\xb0\xbc\x02\xa73r&\u0585\xbe\x9e\xe7s\xb9\x19\x8a\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4\x80c7\x9a{\xf2\u02d2:\x84\xc5\t>h\xda\xc7\xf7T\x81\u0149\x11v\x10.n2\xdf\x00\x00\u07d4\x80hTX\x8e\xcc\xe5AI_\x81\u008a)\x03s\xdf\x02t\xb2\x89\x1f\x8c\xdf\\n\x8dX\x00\x00\u07d4\x80oD\xbd\xebh\x807\x01^\x84\xff!\x80I\xe3\x823*3\x89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u07d4\x80tF\x18\xde9jT1\x97\xeeH\x94\xab\xd0c\x98\xdd|'\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x80w\xc3\xe4\xc4EXn\tL\xe1\x02\x93\u007f\xa0[s{V\x8c\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x80\x90\u007fY1H\xb5|F\xc1w\xe2=%\xab\u012a\xe1\x83a\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x80\x97s\x16\x94NYB\xe7\x9b\x0e:\xba\u04cd\xa7F\be\x19\x89\x02\x1auJm\xc5(\x00\x00\xe0\x94\x80\xa0\xf6\xcc\x18l\xf6 \x14\x00sn\x06Z9\x1fR\xa9\xdfJ\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x80\xab\xecZ\xa3n\\\x9d\t\x8f\x1b\x94(\x81\xbdZ\xca\u0196=\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x80\xb2=8\v\x82\\F\xe098\x99\xa8UVF-\xa0\u1309lk\x93[\x8b\xbd@\x00\x00\u07d4\x80\xb4-\xe1p\xdb\xd7#\xf4T\xe8\x8fw\x16E-\x92\x98P\x92\x89\x10F#\xc0v-\xd1\x00\x00\u07d4\x80\xb7\x9f3\x83\x90\u047a\x1b77\xa2\x9a\x02W\xe5\xd9\x1e\a1\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x80\xbf\x99^\u063a\x92p\x1d\x10\xfe\u011f\x9e}\x01M\xbe\xe0&\x89\x1f\x047\xca\x1a~\x12\x80\x00\u07d4\x80\xc0N\xfd1\x0fD\x04\x83\xc7?tK[\x9edY\x9c\xe3\xec\x89A\rXj \xa4\xc0\x00\x00\u07d4\x80\u00e9\xf6\x95\xb1m\xb1Yr\x86\u0473\xa8\xb7il9\xfa'\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x80\xc5>\xe7\xe35\u007f\x94\xce\rxh\x00\x9c \x8bJ\x13\x01%\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x80\xcc!\xbd\x99\xf3\x90\x05\u014f\xe4\xa4H\x90\x92 !\x8ff\u02c966\xc9yd6t\x00\x00\u07d4\x80\xd5\xc4\fY\xc7\xf5N\xa3\xa5_\xcf\xd1uG\x1e\xa3P\x99\xb3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x80\xda/\u0762\x9a\x9e'\xf9\xe1\x15\x97^i\xae\x9c\xfb\xf3\xf2~\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x80\xe7\xb3 R0\xa5f\xa1\xf0a\xd9\"\x81\x9b\xb4\xd4\u04a0\xe1\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\x80\xea\x1a\xcc\x13n\xcaKh\xc8B\xa9Z\xdfk\u007f\xee~\xb8\xa2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x80\xf0z\xc0\x9e{,<\n=\x1e\x94\x13\xa5D\xc7:A\xbe\u02c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x81\r\xb2Vu\xf4^\xa4\xc7\xf3\x17\u007f7\xce)\xe2-g\x99\x9c\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x81\x13\x9b\xfd\u0326V\xc40 ?r\x95\x8cT;e\x80\xd4\f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x81\x14a\xa2\xb0\u0290\xba\xda\xc0j\x9e\xa1nx{3\xb1\x96\u0309\b\xe3\xf5\v\x17<\x10\x00\x00\u07d4\x81\x16M\xeb\x10\x81J\xe0\x83\x91\xf3,\bf{bH\xc2}z\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\x81\x18i1\x18A7\xd1\x19*\u020c\xd3\xe1\xe5\xd0\xfd\xb8jt\x89\x9d5\x95\xab$8\xd0\x00\x00\u0794\x81*U\xc4<\xae\xdcYr\x187\x90\x00\xceQ\rT\x886\xfd\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x81.\xa7\xa3\xb2\xc8n\xed2\xffO,sQL\xc6;\xac\xfb\u038965\u026d\xc5\u07a0\x00\x00\u07d4\x814\xdd\x1c\x9d\xf0\xd6\u0225\x81$&\xbbU\xc7a\u0283\x1f\b\x89\x06\xa2\x16\v\xb5|\xcc\x00\x00\u07d4\x81A5\u068f\x98\x11\aW\x83\xbf\x1a\xb6pb\xaf\x8d>\x9f@\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x81I\x8c\xa0{\x0f/\x17\xe8\xbb\xc7\xe6\x1a\u007fJ\xe7\xbef\xb7\x8b\x89\x05\x81\xfb\xb5\xb3;\xb0\x00\x00\u07d4\x81Um\xb2sI\xab\x8b'\x00ID\xedP\xa4n\x94\x1a\x0f_\x89\u063beI\xb0+\xb8\x00\x00\u07d4\x81U\xfalQ\xeb1\xd8\bA-t\x8a\xa0\x86\x10P\x18\x12/\x89e\xea=\xb7UF`\x00\x00\xe0\x94\x81V6\v\xbd7\ta\xce\xcakf\x91\xd7P\x06\xad L\xf2\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x81a\xd9@\xc3v\x01\x00\xb9\b\x05)\xf8\xa6\x03%\x03\x0fn\u0709\x10CV\x1a\x88)0\x00\x00\xe0\x94\x81d\xe7\x83\x14\xae\x16\xb2\x89&\xccU=,\xcb\x16\xf3V'\r\x8a\x01\xca\x13N\x95\xfb2\xc8\x00\x00\u07d4\x81e\u02b0\xea\xfbZ2\x8f\xc4\x1a\xc6M\xaeq[.\xef,e\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x81h\xed\xce\u007f)a\xcf)[\x9f\xcdZE\xc0l\xde\xdan\xf5\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x81m\x97r\xcf\x119\x91\x16\xcc\x1er\xc2lgt\xc9\xed\xd79\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x81s\xc85djg.\x01R\xbe\x10\xff\xe8Ab\xdd%nL\x89\x1a\xab\xdf!E\xb40\x00\x00\u07d4\x81t\x93\u035b\xc6#p*$\xa5o\x9f\x82\xe3\xfdH\xf3\xcd1\x89\x9eK#\xf1-L\xa0\x00\x00\u07d4\x81y\xc8\tp\x18,\u0177\xd8*M\xf0n\xa9M\xb6:%\xf3\x89'o%\x9d\xe6k\xf4\x00\x00\u07d4\x81z\xc3;\xd8\xf8GVsr\x95\x1fJ\x10\u05e9\x1c\xe3\xf40\x89\n\xd7\xc4\x06\xc6m\xc1\x80\x00\xe0\x94\x81\x8f\xfe'\x1f\u00d75e\xc3\x03\xf2\x13\xf6\xd2\u0689\x89~\xbd\x8a\x016\xe0SB\xfe\u1e40\x00\u07d4\x81\x97\x94\x81!s.c\xd9\xc1H\x19N\xca\xd4n0\xb7I\u0209\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x81\x9a\xf9\xa1\xc2s2\xb1\xc3i\xbb\xda\x1b=\xe1\xc6\xe93\xd6@\x89\x11\t\xe6T\xb9\x8fz\x00\x00\xe0\x94\x81\x9c\u06a506x\xef|\xecY\u050c\x82\x16:\xcc`\xb9R\x8a\x03\x13QT_y\x81l\x00\x00\u07d4\x81\x9e\xb4\x99\vZ\xbaUG\t=\xa1+k<\x10\x93\xdfmF\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x81\xa8\x81\x96\xfa\xc5\xf2<>\x12\xa6\x9d\xecK\x88\x0e\xb7\xd9s\x10\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x81\xbc\xcb\xff\x8fD4~\xb7\xfc\xa9['\xce|\x95$\x92\xaa\xad\x89\b@\xc1!e\xddx\x00\x00\u07d4\x81\xbdu\xab\xd8e\xe0\xc3\xf0J\vO\xdb\xcbt\xd3@\x82\xfb\xb7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x81\xc1\x8c*#\x8d\xdcL\xba#\n\a-\xd7\xdc\x10\x1eb\x02s\x89Hz\x9a0E9D\x00\x00\u07d4\x81\xc9\xe1\xae\xe2\xd36]S\xbc\xfd\u0356\xc7\xc58\xb0\xfd~\xec\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\x81\u03edv\t\x13\xd3\xc3\"\xfc\xc7{I\u00ae9\a\xe7On\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94\x81\xd6\x19\xffW&\xf2@_\x12\x90Lr\xeb\x1e$\xa0\xaa\xeeO\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x81\xef\u25aev\xc8`\xd1\xc5\xfb\xd3=G\xe8\u0399\x96\xd1W\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x81\xf8\xde,(=_\u052f\xbd\xa8]\xed\xf9v\x0e\xab\xbb\xb5r\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x82\f\x19)\x11\x96P[e\x05\x9d\x99\x14\xb7\t\v\xe1\u06c7\u0789\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\x82\x1c\xb5\xcd\x05\xc7\uf41f\xe1\xbe`s=\x89c\xd7`\xdcA\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x82\x1dy\x8a\xf1\x99\x89\u00ee[\x84\xa7\xa7(<\xd7\xfd\xa1\xfa\xbe\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x82\x1e\xb9\t\x94\xa2\xfb\xf9K\xdc23\x91\x02\x96\xf7o\x9b\xf6\xe7\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x82$\x9f\xe7\x0fa\u01b1o\x19\xa3$\x84\x0f\xdc\x02\x021\xbb\x02\x8a\x02\x036\xb0\x8a\x93c[\x00\x00\u07d4\x82(\xeb\xc0\x87H\x0f\xd6EG\xca(\x1f^\xac\xe3\x04\x14S\xb9\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94\x82)\u03b9\xf0\xd7\b9I\x8dD\xe6\xab\xed\x93\xc5\xca\x05\x9f]\x8a\x1a\x1c\x1b<\x98\x9a \x10\x00\x00\u07d4\x82.\xdf\xf66V:a\x06\xe5.\x9a%\x98\xf7\xe6\xd0\xef'\x82\x89\x01\xf4\xf9i=B\u04c0\x00\u07d4\x822\x19\xa2Yv\xbb*\xa4\xaf\x8b\xadA\xac5&\xb4\x936\x1f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x822\xd1\xf9t.\u07cd\xd9'\xda5;*\xe7\xb4\xcb\xceu\x92\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\x824\xf4c\u0444\x85P\x1f\x8f\x85\xac\xe4\x97,\x9bc-\xbc\u0309lk\x93[\x8b\xbd@\x00\x00\u07d4\x827htg7\xcem\xa3\x12\xd5>TSN\x10o\x96|\xf3\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x82;\xa7dr8\xd1\x13\xbc\xe9\x96JC\u0420\x98\x11\x8b\xfeM\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x82@t1(\x06\xdaGHCBf\xee\x00!@\u305a\u0089Q\xb1\u04c3\x92a\xac\x00\x00\u07d4\x82C\x8f\u04b3*\x9b\xddgKI\xd8\xcc_\xa2\xef\xf9x\x18G\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x82HW(\xd0\xe2\x81V7X\xc7Z\xb2~\xd9\u80a0\x00-\x89\a\xf8\b\xe9)\x1el\x00\x00\u07d4\x82K<\x19)]~\xf6\xfa\xa7\xf3t\xa4y\x84\x86\xa8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x82Q5\x8c\xa4\xe0`\u0775Y\xcaX\xbc\v\u077e\xb4\a\x02\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x82Q5\xb1\xa7\xfc\x16\x05aL\x8a\xa4\u042cm\xba\u040fH\x0e\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4\x82S\t\xa7\xd4]\x18\x12\xf5\x1en\x8d\xf5\xa7\xb9ol\x90\x88\x87\x89\x804\xf7\u0671f\xd4\x00\x00\u07d4\x82Z\u007fN\x10\x94\x9c\xb6\xf8\x96Bh\xf1\xfa_W\xe7\x12\xb4\u0109\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x82a\xfa#\f\x90\x1dC\xffW\x9fG\x80\u04d9\xf3\x1e`v\xbc\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x82b\x16\x9baXp\x13N\xb4\xacl_G\x1ck\xf2\xf7\x89\xfc\x89\x19\x12z\x13\x91\xea*\x00\x00\u07d4\x82c\xec\xe5\xd7\t\xe0\u05eeq\u0328h\xed7\xcd/\xef\x80{\x895\xab\x02\x8a\xc1T\xb8\x00\x00\xe0\x94\x82l\xe5y\x052\xe0T\x8ca\x02\xa3\r>\xac\x83k\xd68\x8f\x8a\x03\xcf\xc8.7\xe9\xa7@\x00\x00\u07d4\x82n\xb7\xcds\x19\xb8-\xd0z\x1f;@\x90q\xd9n9g\u007f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x82u1\xa6\u0141z\xe3_\x82\xb0\v\x97T\xfc\xf7LU\xe22\x89\xc3(\t>a\xee@\x00\x00\u0794\x82u\xcdhL6y\u0548}\x03fN3\x83E\xdc<\xdd\xe1\x88\xdbD\xe0I\xbb,\x00\x00\u07d4\x82\x84\x92;b\u62ff|+\x9f4\x14\xd1>\xf6\xc8\x12\xa9\x04\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\x82\x8b\xa6Q\u02d3\x0e\xd9xqV)\x9a=\xe4L\u040br\x12\x89Hz\x9a0E9D\x00\x00\u07d4\x82\xa1\\\xef\x1dl\x82`\xea\xf1Y\xea?\x01\x80\xd8g}\xce\x1c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x82\xa8\xb9kl\x9e\x13\xeb\xec\x1e\x9f\x18\xac\x02\xa6\x0e\xa8\x8aH\xff\x89lk\x8c@\x8es\xb3\x00\x00\u07d4\x82\xa8\u02ff\xdf\xf0+.8\xaeK\xbf\xca\x15\xf1\xf0\xe8;\x1a\xea\x89\x04\x9b\x99\x1c'\xefm\x80\x00\u07d4\x82\xe4F\x1e\xb9\xd8I\xf0\x04\x1c\x14\x04!\x9eBr\u0110\n\xb4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x82\xe5w\xb5\x15\xcb+\b`\xaa\xfe\x1c\xe0\x9aY\xe0\x9f\xe7\xd0@\x89 \x86\xac5\x10R`\x00\x00\u07d4\x82\xea\x01\xe3\xbf.\x83\x83nqpN\"\xa2q\x93w\xef\xd9\u00c9\xa4\xccy\x95c\u00c0\x00\x00\u07d4\x82\xf2\xe9\x91\xfd2L_]\x17v\x8e\x9fa3]\xb61\x9dl\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x82\xf3\x9b'X\xaeB'{\x86\u059fu\xe6(\xd9X\xeb\u02b0\x8a\bxg\x83&\xea\xc9\x00\x00\x00\xe0\x94\x82\xf8T\xc9\xc2\xf0\x87\xdf\xfa\x98Z\xc8 \x1ebl\xa5Fv\x86\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\x82\xffqo\xdf\x03>\xc7\xe9B\xc9\t\u0643\x18g\xb8\xb6\xe2\xef\x89a\t=|,m8\x00\x00\u07d4\x83\b\xed\n\xf7\xf8\xa3\xc1u\x1f\xaf\xc8w\xb5\xa4*\xf7\xd3X\x82\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x83\x1cD\xb3\b@G\x18K*\xd2\x18h\x06@\x907P\xc4]\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x83!\x05\x83\xc1jN\x1e\x1d\xac\x84\xeb\xd3~=\x0f|W\ub909lk\x93[\x8b\xbd@\x00\x00\u07d4\x83,T\x17k\xdfC\xd2\u027c\u05f8\b\xb8\x95V\xb8\x9c\xbf1\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x833\x16\x98]Gt+\xfe\xd4\x10`J\x91\x95<\x05\xfb\x12\xb0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x834vK{9zNW\x8fP6M`\xceD\x89\x9b\xff\x94\x89\x05\x03\xb2\x03\xe9\xfb\xa2\x00\x00\xe0\x94\x83;j\x8e\xc8\xda@\x81\x86\xac\x8a}*m\xd6\x15#\xe7\u0384\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\x83=?\xaeT*\xd5\xf8\xb5\f\xe1\x9b\xde+\xecW\x91\x80\u020c\x89\x12\xc1\xb6\xee\xd0=(\x00\x00\xe0\x94\x83=\xb4,\x14\x16<{\xe4\u02b8j\u0153\xe0bf\u0599\u054a$\xe4\r+iC\xef\x90\x00\x00\xe0\x94\x83V;\xc3d\ud060\xc6\xda;V\xffI\xbb\xf2g\x82z\x9c\x8a\x03\xab\x91\xd1{ \xdeP\x00\x00\u07d4\x83zd]\xc9\\IT\x9f\x89\x9cN\x8b\u03c7S$\xb2\xf5|\x89 \x8c9J\xf1\u0208\x00\x00\u07d4\x83\x8b\xd5e\xf9\x9f\xdeH\x05?y\x17\xfe3<\xf8J\xd5H\xab\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x83\x90\x8a\xa7G\x8am\x1c\x9b\x9b\x02\x81\x14\x8f\x8f\x9f$+\x9f\u0709lk\x93[\x8b\xbd@\x00\x00\u07d4\x83\x92\xe57vq5x\x01[\xffI@\xcfC\x84\x9d}\u02e1\x89\bM\xf05]V\x17\x00\x00\xe0\x94\x83\x97\xa1\xbcG\xac\xd6GA\x81Y\xb9\x9c\xeaW\xe1\xe6S-n\x8a\x01\xf1\x0f\xa8'\xb5P\xb4\x00\x00\u07d4\x83\x98\xe0~\xbc\xb4\xf7_\xf2\x11m\xe7|\x1c*\x99\xf3\x03\xa4\u03c9\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x83\xa3\x14\x883\xd9dI\x84\xf7\xc4u\xa7\x85\a\x16\ufd00\xff\x89\xb8Pz\x82\a( \x00\x00\u07d4\x83\xa4\x02C\x8e\x05\x19w=TH2k\xfba\xf8\xb2\f\xf5-\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d4\x83\xa9;[\xa4\x1b\xf8\x87 \xe4\x15y\f\xdc\vg\xb4\xaf4\u0109\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x83\xc2=\x8aP!$\xee\x15\x0f\b\xd7\x1d\xc6rt\x10\xa0\xf9\x01\x8a\a3\x1f;\xfef\x1b\x18\x00\x00\u07d4\x83\u0217\xa8Ki^\xeb\xe4fy\xf7\xda\x19\xd7vb\x1c&\x94\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x83\xd52\u04cdm\xee?`\xad\u018b\x93a3\u01e2\xa1\xb0\u0749\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x83\xdb\xf8\xa1(S\xb4\n\xc6\x19\x96\xf8\xbf\x1d\xc8\xfd\xba\xdd\xd3)\x894\x95tD\xb8@\xe8\x00\x00\u07d4\x83\xdb\xfd\x8e\xda\x01\xd0\u078e\x15\x8b\x16\u0413_\xc28\n]\u01c9 \x86\xac5\x10R`\x00\x00\u07d4\x83\xe4\x80U2|(\xb5\x93o\xd9\xf4D~s\xbd\xb2\xdd3v\x89\x90\xf54`\x8ar\x88\x00\x00\xe0\x94\x83\xfeZ\x1b2\x8b\xaeD\a\x11\xbe\xafj\xad`&\xed\xa6\xd2 \x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x84\x00\x8ar\xf8\x03o?\xeb\xa5B\xe3Px\xc0W\xf3*\x88%\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x84\x0e\xc8>\xa96!\xf04\xe7\xbb7b\xbb\x8e)\xde\xd4\xc4y\x89\x87\x86x2n\xac\x90\x00\x00\xe0\x94\x84\x11E\xb4H@\xc9F\xe2\x1d\xbc\x19\x02d\xb8\xe0\xd5\x02\x93i\x8a?\x87\bW\xa3\xe0\xe3\x80\x00\x00\u07d4\x84#!\a\x93+\x12\xe01\x86X5%\xce\x02:p>\xf8\u0649lk\x93[\x8b\xbd@\x00\x00\u07d4\x84$O\xc9ZiW\xed|\x15\x04\xe4\x9f0\xb8\xc3^\xcaKy\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x841'}{\xdd\x10E}\xc0\x17@\x8c\x8d\xbb\xbdAJ\x8d\xf3\x89\x02\"\xc8\xeb?\xf6d\x00\x00\u07d4\x847Z\xfb\xf5\x9b:\x1da\xa1\xbe2\xd0u\xe0\xe1ZO\xbc\xa5\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x84;\xd3P/E\xf8\xbcM\xa3p\xb3#\xbd\xac?\xcf_\x19\xa6\x89P\x03\x9dc\xd1\x1c\x90\x00\x00\u07d4\x84P34c\rw\xf7AG\xf6\x8b.\bf\x13\xc8\xf1\xad\xe9\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\x84R\x03u\x0fqH\xa9\xaa&)!\xe8mC\xbfd\x19t\xfd\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x84a\xec\u0126\xa4^\xb1\xa5\xb9G\xfb\x86\xb8\x80i\xb9\x1f\xcdo\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x84g^\x91wrmE\xea\xa4k9\x92\xa3@\xba\u007fq\f\x95\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x84hl{\xadv,T\xb6g\u055f\x90\x94<\xd1M\x11z&\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x84\x89\xf6\xad\x1d\x9a\x94\xa2\x97x\x91V\x89\x9d\xb6AT\xf1\u06f5\x89\x13t\a\xc0<\x8c&\x80\x00\u07d4\x84\x8c\x99Jy\x00?\xe7\xb7\xc2l\xc62\x12\xe1\xfc/\x9c\x19\xeb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x84\x8f\xbd)\xd6|\xf4\xa0\x13\xcb\x02\xa4\xb1v\xef$N\x9e\u6349\x01\x17*ck\xbd\xc2\x00\x00\u07d4\x84\x94\x9d\xbaU\x9ac\xbf\xc8E\xde\xd0n\x9f-\x9b\u007f\x11\xef$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x84\x9a\xb8\a\x90\xb2\x8f\xf1\xff\u05ba9N\xfctc\x10\\6\xf7\x89\x01\xe0+\xe4\xael\x84\x00\x00\u07d4\x84\x9b\x11oYc\x01\xc5\u063bb\xe0\xe9z\x82H\x12n9\xf3\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x84\xa7L\xee\xcf\xf6\\\xb9;/\x94\x9dw>\xf1\xad\u007f\xb4\xa2E\x89\x05\n\x9bDF\x85\xc7\x00\x00\u07d4\x84\xaa\xc7\xfa\x19\u007f\xf8\\0\xe0;zS\x82\xb9W\xf4\x1f:\xfb\x89\b\x8b#\xac\xff\u0650\x00\x00\u07d4\x84\xaf\x1b\x15sB\xd5Ch&\r\x17\x87b0\xa54\xb5K\x0e\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\x84\xb0\xeek\xb87\u04e4\xc4\xc5\x01\x1c:\"\x8c\x0e\u06b4cJ\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x84\xb4\xb7Nf#\xba\x9d\x15\x83\xe0\u03feId?\x168AI\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x84\xb6\xb6\xad\xbe/[>-h,f\xaf\x1b\u0110S@\xc3\xed\x89!\x92\xf8\xd2\"\x15\x00\x80\x00\xe0\x94\x84\xb9\x1e.)\x02\xd0^+Y\x1bA\b;\u05fe\xb2\xd5,t\x8a\x02\x15\xe5\x12\x8bE\x04d\x80\x00\u07d4\x84\xbc\xbf\"\xc0\x96\a\xac\x844\x1d.\xdb\xc0;\xfb\x179\xd7D\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x84\xbf\xce\xf0I\x1a\n\xe0iK7\u03ac\x02E\x84\xf2\xaa\x04g\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x84\xcb}\xa0P-\xf4\\\xf5a\x81{\xbd#b\xf4Q\xbe\x02\u0689Hz\x9a0E9D\x00\x00\u07d4\x84\xccxx\xda`_\xdb\x01\x9f\xab\x9bL\xcf\xc1Wp\x9c\u0765\x89Hy\x85\x13\xaf\x04\xc9\x00\x00\u07d4\x84\xdb\x14Y\xbb\x00\x81.\xa6~\xcb=\xc1\x89\xb7!\x87\xd9\xc5\x01\x89\b\x11\xb8\xfb\u0685\xab\x80\x00\u07d4\x84\u9516\x80\xbe\xcehA\xb9\xa7\xe5%\r\b\xac\xd8}\x16\u0349\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x84\xe9\u03c1f\xc3j\xbf\xa4\x90S\xb7\xa1\xad@6 &\x81\xef\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x84\xec\x06\xf2G\x00\xfeBAL\xb9\x89|\x15L\x88\xde/a2\x89Hz\x9a0E9D\x00\x00\xe0\x94\x84\xf5\"\xf0R\x0e\xbaR\xdd\x18\xad!\xfaK\x82\x9f+\x89\u02d7\x8a\x01\fQ\x06\xd5\x13O\x13\x00\x00\u07d4\x85\v\x9d\xb1\x8f\xf8K\xf0\xc7\xdaI\xea7\x81\xd9 \x90\xad~d\x89\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\u07d4\x85\x10\xee\x93O\f\xbc\x90\x0e\x10\a\xeb8\xa2\x1e*Q\x01\xb8\xb2\x89\x05\xbf\v\xa6cOh\x00\x00\u07d4\x85\x16\xfc\xafw\u0213\x97\x0f\xcd\x1a\x95\x8b\xa9\xa0\x0eI\x04@\x19\x89\n\xa3\xeb\x16\x91\xbc\xe5\x80\x00\u07d4\x85\x1a\xa9\x1c\x82\xf4/\xad]\xd8\xe8\xbb^\xa6\x9c\x8f:Yw\u0449\b\x0eV\x1f%xy\x80\x00\u07d4\x85\x1c\rb\xbeF5\xd4w~\x805\xe3~K\xa8Q|a2\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x85\x1d\u00ca\xdbE\x93r\x9av\xf3:\x86\x16\u06b6\xf5\xf5\x9aw\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x852I\b\x97\xbb\xb4\u038b\u007fk\x83~L\xba\x84\x8f\xbe\x99v\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x85>j\xba\xf4Di\xc7/\x15\x1dN\"8\x19\xac\xedN7(\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x85F\x91\xceqO2\\\xedU\xceY(\u039b\xa1/\xac\u0478\x89\xedp\xb5\xe9\xc3\xf2\xf0\x00\x00\u07d4\x85L\fF\x9c$k\x83\xb5\u0473\xec\xa4C\xb3\x9a\xf5\xee\x12\x8a\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\x85]\x9a\xef,9\xc6#\r\t\u025e\xf6II\x89\xab\u61c5\x89\b\xbaR\xe6\xfcE\xe4\x00\x00\u07d4\x85c\u0113a\xb6%\xe7hw\x1c\x96\x15\x1d\xbf\xbd\x1c\x90iv\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x85fa\t\x01\xaa\xce8\xb82D\xf3\xa9\xc810jg\xb9\u0709\xb0\x82\x13\xbc\xf8\xff\xe0\x00\x00\xe0\x94\x85j\xa2<\x82\xd7![\xec\x8dW\xf6\n\xd7^\xf1O\xa3_D\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x85nZ\xb3\xf6L\x9a\xb5k\x00\x93\x93\xb0\x16d\xfc\x03$\x05\x0e\x89a\t=|,m8\x00\x00\u07d4\x85n\xb2\x04$\x1a\x87\x83\x0f\xb2)\x03\x13C\xdc0\x85OX\x1a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x85s,\x06\\\xbdd\x11\x99A\xae\xd40\xacYg\vlQ\u0109'\xa5sb\xab\n\x0e\x80\x00\xe0\x94\x85x\xe1\x02\x12\xca\x14\xff\a2\xa8$\x1e7F}\xb8V2\xa9\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x85y\xda\xdf\x1a9Z4q\xe2\vov=\x9a\x0f\xf1\x9a?o\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x85\u007f\x10\v\x1aY0\"^\xfc~\x90 \u05c3'\xb4\x1c\x02\u02c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x85\x94mV\xa4\xd3q\xa93hS\x96\x90\xb6\x0e\xc8%\x10tT\x89]\u0212\xaa\x111\xc8\x00\x00\xe0\x94\x85\x99\xcb\u0566\xa9\xdc\u0539f\xbe8}iw]\xa5\xe3C'\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x86$_Yf\x91\t>\xce?=<\xa2&>\xac\xe8\x19A\u0649\n1\x06+\xee\xedp\x00\x00\u07d4\x86%i!\x1e\x8cc'\xb5A^:g\xe5s\x8b\x15\xba\xafn\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\x86)}s\x0f\xe0\xf7\xa9\xee$\xe0\x8f\xb1\b{1\xad\xb3\x06\xa7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x86D\xcc(\x1b\xe32\xcc\xce\xd3m\xa4\x83\xfb*\aF\u067a.\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x86I\x9a\x12(\xff-~\xe3\au\x93dPo\x8e\x8c\x83\a\xa5\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x86K\xecPi\xf8U\xa4\xfdX\x92\xa6\xc4I\x1d\xb0|\x88\xff|\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x86W\n\xb2Y\u0271\xc3,\x97) /w\xf5\x90\xc0}\xd6\x12\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x86c\xa2A\xa0\xa8\x9ep\xe1\x82\xc8E\xe2\x10\\\x8a\xd7&K\u03ca\x03#\xb1=\x83\x98\xf3#\x80\x00\u07d4\x86g\xfa\x11U\xfe\xd72\u03f8\u0725\xa0\xd7e\xce\r\a\x05\xed\x89\x04n\xc9e\u00d3\xb1\x00\x00\u07d4\x86h\xaf\x86\x8a\x1e\x98\x88_\x93\u007f&\x15\xde\xd6u\x18\x04\xeb-\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x86t\nFd\x8e\x84Z]\x96F\x1b\x18\t\x1f\xf5{\xe8\xa1o\x8a\x14\xc0\x974\x85\xbf9@\x00\x00\xe0\x94\x86~\xbaVt\x8aY\x045\r,\xa2\xa5\u039c\xa0\vg\n\x9b\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x86\x80dt\xc3X\x04}\x94\x06\xe6\xa0\u007f@\x94[\xc82\x8eg\x8a\x01u.\xb0\xf7\x01=\x10\x00\x00\u07d4\x86\x88=T\xcd9\x15\xe5I\tU0\xf9\xab\x18\x05\xe8\xc5C-\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x86\x8c#\xbe\x874f\xd4\xc7L\"\n\x19\xb2E\xd1x~\x80\u007f\x89J\x13\xbb\xbd\x92\u020e\x80\x00\xe0\x94\x86\x92O\xb2\x11\xaa\xd2<\xf5\xce`\x0e\n\xae\x80c\x96D@\x87\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x86\x93\u9e3e\x94B^\xefyi\xbci\xf9\xd4/|\xadg\x1e\x8967\tlK\xcci\x00\x00\xe0\x94\x86\x9f\x1a\xa3\x0eDU\xbe\xb1\x82 \x91\xde\\\xad\xecy\xa8\xf9F\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x86\xa1\xea\xde\xeb0F\x13E\xd9\xefk\xd0R\x16\xfa$|\r\f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x86\xa5\xf8%\x9e\u0570\x9e\x18\x8c\xe3F\xee\x92\xd3J\xa5\u0753\xfa\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x86\xb7\xbdV<\uad86\xf9bD\xf9\xdd\xc0*\u05f0\xb1K\u008a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x86\u008bVx\xaf7\xd7'\xec\x05\xe4Dw\x90\xf1_q\xf2\xea\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x86\xc4\xce\x06\u066c\x18[\xb1H\xd9o{z\xbes\xf4A\x00m\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x86\xc8\xd0\u0642\xb59\xf4\x8f\x980\xf9\x89\x1f\x9d`z\x94&Y\x8a\x02\xce\xd3wa\x82O\xb0\x00\x00\u07d4\x86\xc94\xe3\x8eS\xbe;3\xf2t\xd0S\x9c\xfc\xa1Y\xa4\xd0\u04494\x95tD\xb8@\xe8\x00\x00\xe0\x94\x86\xca\x01E\x95~k\r\xfe6\x87_\xbez\r\xecU\xe1z(\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x86\u02af\xac\xf3*\xa01|\x03*\xc3k\xab\xed\x97G\x91\xdc\x03\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x86\u0377\xe5\x1a\xc4Gr\xbe6\x90\xf6\x1d\x0eYvn\x8b\xfc\x18\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x86\xdfs\xbd7\u007f,\t\xdec\xc4]g\xf2\x83\xea\xef\xa0\xf4\xab\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x86\xe3\xfe\x86\xe9=\xa4\x86\xb1Bf\xea\xdf\x05l\xbf\xa4\xd9\x14C\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x86\xe8g\x0e'Y\x8e\xa0\x9c8\x99\xabw\x11\u04f9\xfe\x90\x1c\x17\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x86\xefd&!\x19I\xcc7\xf4\xc7^xP6\x9d\f\xf5\xf4y\x8a\x02\xd6_2\xea\x04Z\xf6\x00\x00\u07d4\x86\xf0]\x19\x06>\x93i\xc6\x00N\xb3\xf1#\x94:|\xffN\xab\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x86\xf2>\x9c\n\xaf\u01cb\x9c@M\xcd`3\x9a\x92[\xff\xa2f\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x86\xf4\xf4\n\u0644\xfb\xb8\t3\xaebn\x0eB\xf93?\xddA\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x86\xf9\\[\x11\xa2\x93\x94\x0e5\xc0\xb8\x98\u0637_\b\xaa\xb0m\x8a\x06D\xe3\xe8u\xfc\xcft\x00\x00\u07d4\x86\xff\xf2 \xe5\x93\x05\xc0\x9fH8`\xd6\xf9N\x96\xfb\xe3/W\x89\x02S[j\xb4\xc0B\x00\x00\u07d4\x87\a\x96\xab\xc0\u06c4\xaf\x82\xdaR\xa0\xedhsM\xe7\xe66\xf5\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x87\x0f\x15\xe5\u07cb\x0e\xab\xd0%iSz\x8e\xf9;Vx\\B\x89\x15\b\x94\xe8I\xb3\x90\x00\x00\u07d4\x87\x181`\xd1r\xd2\xe0\x84\xd3'\xb8k\xcb|\x1d\x8eg\x84\xef\x89\xd8\xd8X?\xa2\xd5/\x00\x00\xe0\x94\x87\x1b\x8a\x8bQ\u07a1\x98\x9aY!\xf1>\xc1\xa9U\xa5\x15\xadG\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x87%\xe8\xc7S\xb3\xac\xbf\u0725_I\x13\\3\x91\x99\x10`)\n\xa7\xf6\u0338\xf8Zx\u06c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x87Pa\xee\x12\xe8 \x04\x1a\x01\x94,\xb0\xe6[\xb4'\xb0\x00`\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\x87XJ?a;\xd4\xfa\xc7L\x1ex\v\x86\xd6\xca\xeb\x89\f\xb2\x89\\(=A\x03\x94\x10\x00\x00\u07d4\x87d\xd0'\"\x00\t\x96\xec\xd4u\xb43)\x8e\x9fT\v\x05\xbf\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x87l?!\x8bGv\xdf<\xa9\xdb\xfb'\r\xe1R\xd9N\xd2R\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x87u\xa6\x10\xc5\x02\xb9\xf1\xe6\xadL\xda\u06cc\xe2\x9b\xffu\xf6\xe4\x89 \x86\xac5\x10R`\x00\x00\u07d4\x87vN6w\xee\xf6\x04\xcb\u015a\xed$\xab\xdcVk\t\xfc%\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94\x87\x87\xd1&w\xa5\xec)\x1eW\xe3\x1f\xfb\xfa\xd1\x05\xc32K\x87\x8a\x02\xa2N\xb52\b\xf3\x12\x80\x00\u07d4\x87\x94\xbfG\xd5E@\xec\xe5\xc7\"7\xa1\xff\xb5\x11\u0777Gb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x87\xa5>\xa3\x9fY\xa3[\xad\xa85%!dU\x94\xa1\xa7\x14\u02c9g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x87\xa7\xc5\b\xefqX-\u0665Cr\xf8\x9c\xb0\x1f%/\xb1\x80\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x87\xaf%\xd3\xf6\xf8\xee\xa1S\x13\xd5\xfeEW\xe8\x10\xc5$\xc0\x83\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\x87\xb1\x0f\x9c(\x00\x98\x17\x9a+v\xe9\u0390\xbea\xfc\x84M\r\x89Hz\x9a0E9D\x00\x00\u07d4\x87\xbf|\xd5\u0629)\xe1\u01c5\xf9\xe5D\x91\x06\xac#$c\u0249\x047\xb1\x1f\xccEd\x00\x00\u07d4\x87\u0118\x17\t4\xb8#=\x1a\xd1\xe7i1}\\G_/@\x897\b\xba\xed=h\x90\x00\x00\u07d4\x87\xcf6\xad\x03\xc9\xea\xe9\x05:\xbbRB\u0791\x17\xbb\x0f*\v\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x87\u05ec\x06S\xcc\xc6z\xa9\xc3F\x9e\xefCR\x19?}\xbb\x86\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\xe0\x94\x87\xe3\x06+#!\xe9\u07f0\x87\\\u311c\x9b.5\"\xd5\n\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x87\xe6\x03N\xcf#\xf8\xb5c\x9d_\x0e\xa7\n\"S\x8a\x92\x04#\x89\x11\xc7\xea\x16.x \x00\x00\u07d4\x87\xefm\x8bj|\xbf\x9b\\\x8c\x97\xf6~\xe2\xad\u00a7;?w\x89\n\xdd\x1b\xd2<\x00L\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x88F\x92\x8dh2\x89\xa2\xd1\x1d\xf8\xdbz\x94t\x98\x8e\xf0\x13H\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x88I\x80\xebEe\xc1\x04\x83\x17\xa8\xf4\u007f\u06f4a\x96[\u4049\xd8\xd6\x11\x9a\x81F\x05\x00\x00\xe0\x94\x88Jz9\u0411n\x05\xf1\xc2B\xdfU`\u007f7\u07cc_\u068a\x04\xf4\x84<\x15|\x8c\xa0\x00\x00\u07d4\x88T\x93\xbd\xa3j\x042\x97eF\xc1\xdd\xceq\xc3\xf4W\x00!\x89\v\xbfQ\r\xdf\xcb&\x00\x00\xe0\x94\x88`\x9e\nF[n\x99\xfc\xe9\a\x16mW\xe9\xda\b\x14\xf5\u020a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x88m\n\x9e\x17\xc9\xc0\x95\xaf.\xa25\x8b\x89\xecpR\x12\ue509\x01\x84\x93\xfb\xa6N\xf0\x00\x00\u07d4\x88y~Xg^\xd5\xccL\x19\x98\a\x83\xdb\xd0\xc9V\bQS\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x88|\xacA\xcdpo3E\xf2\xd3J\xc3N\x01u*nY\t\x89 F\\\ue7617\x00\x00\u07d4\x88\x88\x8aW\xbd\x96\x87\xcb\xf9P\xae\xea\u03d7@\xdc\xc4\xd1\xefY\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u0794\x88\x89D\x83\x16\xcc\xf1N\xd8m\xf8\xe2\xf4x\xdcc\xc43\x83@\x88\xd2\xf1?w\x89\xf0\x00\x00\u07d4\x88\x8c\x16\x14I3\x19|\xac&PM\xd7n\x06\xfdf\x00\u01c9\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x88\x8e\x94\x91p\x83\xd1R +S\x1699\x86\x9d'\x11u\xb4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x88\x90\x87\xf6o\xf2\x84\xf8\xb5\xef\xbd)I;pg3\xab\x14G\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\x88\x95\xebrb&\xed\xc3\xf7\x8c\u01a5\x15\a{2\x96\xfd\xb9^\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x88\x97Z_\x1e\xf2R\x8c0\v\x83\xc0\xc6\a\xb8\xe8}\u0593\x15\x89\x04\x86\u02d7\x99\x19\x1e\x00\x00\u07d4\x88\x9d\xa4\x0f\xb1\xb6\x0f\x9e\xa9\xbdzE>XL\xf7\xb1\xb4\xd9\xf7\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x88\x9d\xa6b\xebJ\n*\x06\x9d+\xc2K\x05\xb4\xee.\x92\xc4\x1b\x89Z,\x8cTV\xc9\xf2\x80\x00\u07d4\x88\xa1\"\xa28,R91\xfbQ\xa0\u032d;\xeb[rY\u00c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x88\xa2\x15D0\xc0\xe4\x11G\xd3\xc1\xfe\u3cf0\x06\xf8Q\xed\xbd\x8965f3\xeb\xd8\xea\x00\x00\u07d4\x88\xb2\x17\u0337\x86\xa2T\xcfM\xc5\u007f]\x9a\xc3\xc4U\xa3\x04\x83\x892$\xf4'#\xd4T\x00\x00\xe0\x94\x88\xbcC\x01.\xdb\x0e\xa9\xf0b\xacCxC%\n9\xb7\x8f\xbb\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x88\xc2Qj|\xdb\t\xa6'mr\x97\xd3\x0fZM\xb1\xe8K\x86\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x88\xc3ad\rki7;\b\x1c\xe0\xc43\xbdY\x02\x87\xd5\xec\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\x88\xd5A\xc8@\xceC\xce\xfb\xafm\x19\xafk\x98Y\xb5s\xc1E\x89\t79SM(h\x00\x00\u07d4\x88\xde\x13\xb0\x991\x87|\x91\rY1e\xc3d\u0221d\x1b\u04c9\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x88\xde\u017d?N\xba-\x18\xb8\xaa\xce\xfa{r\x15H\xc3\x19\xba\x89JD\x91\xbdm\xcd(\x00\x00\u07d4\x88\xe6\xf9\xb2G\xf9\x88\xf6\xc0\xfc\x14\xc5o\x1d\xe5>\u019dC\u0309\x05k\xc7^-c\x10\x00\x00\u07d4\x88\xee\u007f\x0e\xfc\x8fw\x8ckh~\xc3+\xe9\xe7\xd6\xf0 \xb6t\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x88\xf1\x04_\x19\xf2\xd3\x19\x18\x16\xb1\xdf\x18\xbbn\x145\xad\x1b8\x89\r\x02\xabHl\xed\xc0\x00\x00\xe0\x94\x89\x00\x9e\a\xe3\xfahc\xa7x\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x89Wr~r\xcfb\x90 \xf4\xe0^\xdfy\x9a\xa7E\x80b\u0409wC\"\x17\xe6\x83`\x00\x00\u07d4\x89]iN\x88\v\x13\xcc\u0404\x8a\x86\xc5\xceA\x1f\x88Gk\xbf\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4\x89^\xc5TVD\u0dc30\xff\xfa\xb8\xdd\xea\xc9\xe83\x15l\x89 \x86\xac5\x10R`\x00\x00\u07d4\x89`\tRj,{\f\t\xa6\xf6:\x80\xbd\U0009d707\u079c\x89\xbb\xb8k\x82#\xed\xeb\x00\x00\u07d4\x89g\u05f9\xbd\xb7\xb4\xae\xd2.e\xa1]\xc8\x03\xcbz!?\x10\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x89n3\\\xa4z\xf5yb\xfa\x0fM\xbf>E\xe6\x88\u02e5\x84\x89J/\xc0\xab`R\x12\x00\x00\u07d4\x89s\xae\xfd^\xfa\xee\x96\t]\x9e(\x8fj\x04l\x977KC\x89\a\xa4\u0120\xf32\x14\x00\x00\u07d4\x89\x8cr\xddseX\xef\x9eK\xe9\xfd\xc3O\xefT\xd7\xfc~\b\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x89\x9b<$\x9f\fK\x81\xdfu\xd2\x12\x00M=m\x95/\xd2#\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x89\xab\x13\xee&mw\x9c5\xe8\xbb\x04\u034a\x90\xcc!\x03\xa9[\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4\x89\xc43\xd6\x01\xfa\xd7\x14\xdaci0\x8f\xd2l\x1d\u0254+\xbf\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x89\xd7[\x8e\b1\xe4o\x80\xbc\x17A\x88\x18N\x00o\xde\x0e\xae\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x89\u3d5a\x15\x86G7\u0513\xc1\xd2<\xc5=\xbf\x8d\xcb\x13b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x89\xfc\x8eM8k\r\v\xb4\xa7\a\xed\xf3\xbdV\r\xf1\xad\x8fN\x89\xa00\xdc\xeb\xbd/L\x00\x00\u07d4\x89\xfe\xe3\r\x17(\xd9l\xec\xc1\u06b3\xda.w\x1a\xfb\u03eaA\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\x8a\x1c\u016c\x11\x1cI\xbf\xcf\xd8H\xf3}\xd7h\xaae\u0208\x02\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x8a \xe5\xb5\xce\xe7\xcd\x1fU\x15\xba\xce;\xf4\xf7\u007f\xfd\xe5\xcc\a\x89\x04V9\x18$O@\x00\x00\xe0\x94\x8a!}\xb3\x8b\xc3_!_\xd9)\x06\xbeBCo\xe7\xe6\xed\x19\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x8a$:\n\x9f\xeaI\xb89TwE\xff-\x11\xaf?K\x05\"\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\x8a$}\x18e\x10\x80\x9fq\xcf\xfcEYG\x1c9\x10\x85\x81!\x89a\t=|,m8\x00\x00\u07d4\x8a4p(-^**\xef\u05e7P\x94\xc8\"\xc4\xf5\xae\uf289\r(\xbc`dx\xa5\x80\x00\u07d4\x8a6\x86\x9a\xd4x\x99|\xbfm\x89$\xd2\n<\x80\x18\xe9\x85[\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x8aC\x14\xfba\u0353\x8f\xc3>\x15\xe8\x16\xb1\x13\U000ac267\xfb\x89\x17vNz\xede\x10\x00\x00\u07d4\x8aOJ\u007fR\xa3U\xba\x10_\xca r\xd3\x06_\xc8\xf7\x94K\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x8aX1(,\xe1Jezs\r\xc1\x88&\xf7\xf9\xb9\x9d\xb9h\x89\uaf8a[A\xc16\x00\x00\u07d4\x8a_\xb7W\x93\xd0C\xf1\xbc\xd48\x85\xe07\xbd0\xa5(\xc9'\x89\x13Snm.\x9a\xc2\x00\x00\u07d4\x8af\xab\xbc-0\xce!\xa83\xb0\u06ceV\x1dQ\x05\xe0\xa7,\x89%\xf1\xde\\v\xac\xdf\x00\x00\u07d4\x8atl]g\x06G\x11\xbf\xcah[\x95\xa4\xfe)\x1a'\x02\x8e\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x8ax\n\xb8z\x91E\xfe\x10\xed`\xfaGjt\n\xf4\u02b1\u0489\x12\x1b.^ddx\x00\x00\u07d4\x8az\x06\xbe\x19\x9a:X\x01\x9d\x84j\xc9\xcb\xd4\xd9]\xd7W\u0789\xa2\xa4#\x94BV\xf4\x00\x00\u07d4\x8a\x81\x01\x14\xb2\x02]\xb9\xfb\xb5\x00\x99\xa6\xe0\u02de.\xfak\u0709g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x8a\x86\xe4\xa5\x1c\x01;\x1f\xb4\xc7k\xcf0f|x\xd5.\xed\xef\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8a\x9e\u029cZ\xba\x8e\x13\x9f\x80\x03\xed\xf1\x16:\xfbp\xaa:\xa9\x89#\xc7W\a+\x8d\xd0\x00\x00\u07d4\x8a\xb89\xae\xaf*\xd3|\xb7\x8b\xac\xbb\xb63\xbc\xc5\xc0\x99\xdcF\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8a\u021b\u06780\x1ek\x06w\xfa%\xfc\xf0\xf5\x8f\f\u01f6\x11\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x8a\xdcS\xef\x8c\x18\xed0Qx]\x88\xe9\x96\xf3\xe4\xb2\x0e\xcdQ\x8a\b\xe4\xd3\x16\x82v\x86@\x00\x00\u07d4\x8a\xe6\xf8\vp\xe1\xf2<\x91\xfb\u0569f\xb0\xe4\x99\xd9]\xf82\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\x8a\xe9\uf30a\x8a\u07e6\xaby\x8a\xb2\xcd\xc4\x05\b*\x1b\xbbp\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8a\xf6&\xa5\xf3'\xd7Pe\x89\xee\xb7\x01\x0f\xf9\xc9D` \u0489K\xe4\xe7&{j\xe0\x00\x00\xe0\x94\x8b\x01\xda4\xd4p\xc1\xd1\x15\xac\xf4\xd8\x11\xe1\x01\xdb\x1e\x14\xec\xc7\xd3\"\xc7+\x8c\x04s\x89\x18\xb2j1>\x8a\xe9\x00\x00\xe0\x94\x8bH\xe1\x9d9\xdd5\xb6nn\x1b\xb6\xb9\xc6W\xcb,\xf5\x9d\x04\x8a\x03\xc7U\xac\x9c\x02J\x01\x80\x00\xe0\x94\x8bP^(q\xf7\u07b7\xa68\x95 \x8e\x82'\u072a\x1b\xff\x05\x8a\f\xf6\x8e\xfc0\x8dy\xbc\x00\x00\u07d4\x8bW\xb2\xbc\x83\u030dM\xe31 N\x89?/;\x1d\xb1\a\x9a\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x8b\\\x91K\x12\x8b\xf1i\\\b\x89#\xfaF~y\x11\xf3Q\xfa\x89\x05V\xf6L\x1f\xe7\xfa\x00\x00\xe0\x94\x8b_)\xcc/\xaa&,\xde\xf3\x0e\xf5T\xf5\x0e\xb4\x88\x14n\xac\x8a\x01;hp\\\x97 \x81\x00\x00\u07d4\x8bpV\xf6\xab\xf3\xb1\x18\xd0&\xe9D\xd5\xc0sC<\xa4Q\u05c965\xc6 G9\u0640\x00\u07d4\x8bqE\"\xfa(9b\x04p\xed\xcf\fD\x01\xb7\x13f=\xf1\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x8bt\xa7\xcb\x1b\xb8\u014f\xce&tf\xa3\x03X\xad\xafR\u007fa\x8a\x02\xe2WxN%\xb4P\x00\x00\u07d4\x8b~\x9fo\x05\xf7\xe3dv\xa1n>q\x00\xc9\x03\x1c\xf4\x04\xaf\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8b\x81\x15ni\x869\x94<\x01\xa7Rr\xad=5\x85\x1a\xb2\x82\x89\x12\xb3\x16_e\xd3\xe5\x00\x00\u07d4\x8b\x95w\x92\x00S\xb1\xa0\x01\x890M\x88\x80\x10\xd9\xef,\xb4\xbf\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x8b\x98A\x86.w\xfb\xbe\x91\x94p\x93U\x83\xa9<\xf0'\xe4P\x89llS4B\u007f\x1f\x00\x00\u07d4\x8b\x99}\xbc\a\x8a\xd0)a5]\xa0\xa1Y\xf2\x92~\xd4=d\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94\x8b\x9f\xda}\x98\x1f\xe9\xd6B\x87\xf8\\\x94\xd8?\x90t\x84\x9f\u030a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\x8b\xb0!/2\x95\xe0)\u02b1\xd9a\xb0A3\xa1\x80\x9e{\x91\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8b\xbe\xac\xfc)\xcf\xe94\x02\xdb\xd6j\x1a\xcbvv\x85c7\xb9;\xf0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8b\xf3s\xd0v\x81L\xbcW\xe1\xc6\xd1j\x82\u017e\x13\xc7=7\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x8c\x10#\xfd\xe1WM\xb8\xbbT\xf1s\x96p\x15|\xa4}\xa6R\x8a\x01y\u03da\u00e1\xb1w\x00\x00\u07d4\x8c\x1f\xbe_\n\xea5\x9cZ\xa1\xfa\b\u0209T\x12\u028e\x05\xa6\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8c\"B`U\xb7o\x11\xf0\xa2\xde\x1a\u007f\x81\x9aa\x96\x85\xfe`\x89kV\x05\x15\x82\xa9p\x00\x00\u07d4\x8c+}\x8b`\x8d(\xb7\u007f\\\xaa\x9c\xd6E$*\x82>L\u0649b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\x8c/\xbe\ue3ac\xc5\xc5\xd7|\x16\xab\xd4b\ue701E\xf3K\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\x8c:\x9e\xe7\x1fr\x9f#l\xba8g\xb4\u05dd\x8c\xee\xe2]\xbc\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x8cP\xaa*\x92\x12\xbc\xdeVA\x8a\xe2a\xf0\xb3^z\x9d\xbb\x82\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x8cT\xc7\xf8\xb9\x89nu\xd7\xd5\xf5\xc7`%\x86\x99\x95qB\xad\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x8c]\x16\xede\xe3\xed~\x8b\x96\u0297+\xc8as\xe3P\v\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8cj\xa8\x82\xee2,\xa8HW\x8c\x06\xcb\x0f\xa9\x11\xd3`\x83\x05\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\x8cj\xe7\xa0Z\x1d\xe5u\x82\xae'h Bv\xc0\xffG\xed\x03\x8a,\v\xb3\xdd0\xc4\xe2\x00\x00\x00\u07d4\x8co\x9fN[z\xe2v\xbfXI{\u05ff*}%$_d\x89\x93\xfe\\W\xd7\x10h\x00\x00\u07d4\x8cu\x95n\x8f\xedP\xf5\xa7\xdd|\xfd'\xda \x0fgF\xae\xa6\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8c|\xb4\xe4\x8b%\x03\x1a\xa1\xc4\xf9)%\xd61\xa8\xc3\xed\xc7a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8c\u007f\xa5\xca\xe8/\xed\xb6\x9a\xb1\x89\xd3\xff'\xae \x92\x93\xfb\x93\x89\x15\xaf\x88\r\x8c\u06c3\x00\x00\xe0\x94\x8c\x81A\x0e\xa85L\xc5\xc6\\A\xbe\x8b\xd5\xdes<\v\x11\x1d\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\x8c\x83\xd4$\xa3\xcf$\xd5\x1f\x01\x92=\xd5J\x18\u05b6\xfe\xde{\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8c\x90\n\x826\xb0\x8c+e@]9\xd7_ \x06*ua\xfd\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4\x8c\x93\xc3\xc6\u06dd7q}\xe1e\u00e1\xb4\xfeQ\x95,\b\u0789\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x8c\x99\x95\x91\xfdr\xefq\x11\xef\xcaz\x9e\x97\xa25k;\x00\n\x89\xddd\xe2\xaa\ngP\x00\x00\u07d4\x8c\xa6\x98\x97F\xb0n2\xe2Hta\xb1\u0399j':\xcf\u05c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x8c\xb3\xaa?\xcd!(T\xd7W\x8f\xcc0\xfd\xed\xe6t*1*\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x8c\xc0\xd7\xc0\x16\xfaz\xa9P\x11J\xa1\xdb\tH\x82\xed\xa2t\xea\x89\b\xa9\xab\xa5W\xe3l\x00\x00\u07d4\x8c\xc6R\xdd\x13\xe7\xfe\x14\u06bb\xb3m]2\r\xb9\xff\xee\x8aT\x89a\t=|,m8\x00\x00\u07d4\x8c\u02bf%\a\u007f:\xa4\x15E4MS\xbe\x1b+\x9c3\x90\x00\x89[\xe8f\xc5b\xc5D\x00\x00\u07d4\x8c\xcf:\xa2\x1a\xb7BWj\xd8\xc4\"\xf7\x1b\xb1\x88Y\x1d\ua28965\u026d\xc5\u07a0\x00\x00\u07d4\x8c\xd0\xcd\"\xe6 \xed\xa7\x9c\x04a\xe8\x96\xc9\xd1b)\x12K_z\xfb\xec\x89\a?u\u0460\x85\xba\x00\x00\u07d4\x8c\xe2/\x9f\xa3rD\x9aB\x06\x10\xb4z\xe0\xc8\xd5eH\x122\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x8c\u451d\x8a\x16T-B<\x17\x98Ng9\xfar\u03b1w\x8a\x05K@Y&\xf4\xa6=\x80\x00\u07d4\x8c\xe5\xe3\xb5\xf5\x91\xd5\uc8ca\xbf\"\x8f.<5\x13K\xda\xc0\x89}\xc3[\x84\x89|8\x00\x00\xe0\x94\x8c\xee8\xd6YW\x88\xa5n?\xb9F4\xb3\xff\xe1\xfb\xdb&\u058a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x8c\xee\xa1^\xec;\xda\xd8\x02?\x98\xec\xf2[+\x8f\xef'\xdb)\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8c\xf3To\xd1\u0363=X\x84_\xc8\xfc\xfe\u02bc\xa7\xc5d*\x89\x1f\x1e9\x93,\xb3'\x80\x00\u07d4\x8c\xf6\xda\x02\x04\xdb\u0106\vF\xad\x97?\xc1\x11\x00\x8d\x9e\fF\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x8c\xfe\xde\xf1\x98\xdb\n\x91C\xf0\x91)\xb3\xfdd\u073b\x9bIV\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8d\x04\xa5\xeb\xfb]\xb4\t\xdb\x06\x17\xc9\xfaV1\xc1\x92\x86\x1fJ\x894\x95tD\xb8@\xe8\x00\x00\u07d4\x8d\x06\xe4d$\\\xadaI9\xe0\xaf\bE\xe6\xd70\xe2\x03t\x89\n\u070a(\xf3\xd8}\x80\x00\u07d4\x8d\a\xd4-\x83\x1c-|\x83\x8a\xa1\x87+:\xd5\xd2w\x17h#\x89\x12\xee\x1f\x9d\xdb\xeeh\x00\x00\u07d4\x8d\v\x9e\xa5?\xd2cA^\xac\x119\x1f|\xe9\x12V\xb9\xfb\x06`\xf6\xf0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8dy\\_JV\x89\xadb\u0696\x16q\xf0(\x06R\x86\xd5T\x89o\x05\xb5\x9d; \x00\x00\x00\u07d4\x8d\u007f>a)\x9c-\xb9\xb9\xc0H|\xf6'Q\x9e\xd0\n\x91#\x89^t\xa8P^\x80\xa0\x00\x00\xe0\x94\x8d\x89\x17\v\x92\xb2\xbe,\b\xd5|H\xa7\xb1\x90\xa2\xf1Fr\x0f\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\x8d\x93\xda\u01c5\xf8\x8f\x1a\x84\xbf\x92}Se+E\xa1T\xcc\u0749\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\x8d\x99R\u043bN\xbf\xa0\xef\xd0\x1a:\xa9\xe8\xe8\u007f\x05%t.\x89\xbb\x91%T\"c\x90\x00\x00\u07d4\x8d\x9a\fp\xd2& B\xdf\x10\x17\xd6\xc3\x03\x13 $w'\x12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8d\x9e\xd7\xf4U0X\xc2ox6\xa3\x80-0d\xeb\x1b6=\x89\x04\xe1\x00;(\xd9(\x00\x00\u07d4\x8d\xa1\x17\x8fU\xd9wr\xbb\x1d$\x11\x1a@JO\x87\x15\xb9]\x89/\x9a\xc3\xf6\xde\x00\x80\x80\x00\u07d4\x8d\xa1\xd3Y\xbal\xb4\xbc\xc5}zCw \xd5]\xb2\xf0\x1cr\x89\x04V9\x18$O@\x00\x00\u07d4\x8d\xab\x94\x8a\xe8\x1d\xa3\x01\xd9r\xe3\xf6\x17\xa9\x12\xe5\xa7Sq.\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x8d\xad\xdfR\xef\xbdt\u0695\xb9i\xa5GoO\xbb\xb5c\xbf\u0489-C\xf3\xeb\xfa\xfb,\x00\x00\u07d4\x8d\xb1\x85\xfe\x1bp\xa9Jj\b\x0e~#\xa8\xbe\xdcJ\xcb\xf3K\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x8d\xb5\x8e@n -\xf9\xbcpl\xb43\xe1\x94\xf4\x0f\x82\xb4\x0f\xaa\xdb\x1f\x8b\x85a\x16\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x8d\xc1\xd5\x11\x1d\t\xaf%\xfd\xfc\xacE\\|\xec(>mgu\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8d\u0504\xff\x8a0sd\xebf\xc5%\xa5q\xaa\xc7\x01\xc5\xc3\x18\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8d\u05a9\xba\xe5\u007fQ\x85I\xad\xa6wFo\ua2b0O\u0674\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8d\xde<\xb8\x11\x85h\xefE\x03\xfe\x99\x8c\xcd\xf56\xbf\x19\xa0\x98\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8d\xde`\xeb\b\xa0\x99\xd7\u06a3V\u06aa\xb2G\r{\x02Zk\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94\x8d\xf39!Kj\u0472Fc\xceq`4t\x9dn\xf88\u064a\x02TO\xaaw\x80\x90\xe0\x00\x00\xe0\x94\x8d\xf5=\x96\x19\x14q\xe0Y\xdeQ\xc7\x18\xb9\x83\xe4\xa5\x1d*\xfd\x8a\x06\u01b95\xb8\xbb\xd4\x00\x00\x00\u07d4\x8d\xfb\xaf\xbc\x0e[\\\x86\xcd\x1a\u0597\xfe\xea\x04\xf41\x88\u0796\x89\x15%+\u007f_\xa0\xde\x00\x00\u07d4\x8e\a;\xad%\xe4\"\x18a_J\x0ek.\xa8\xf8\xde\"0\xc0\x89\x82=b\x9d\x02k\xfa\x00\x00\u07d4\x8e\x0f\xee8hZ\x94\xaa\xbc\xd7\u0385{k\x14\t\x82Ou\xb8\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x8e#\xfa\xcd\x12\xc7e\xc3j\xb8\x1am\xd3M\x8a\xa9\xe6\x89\x18\xae\x89\t\x11\u418d\xba\x9b\x00\x00\xe0\x94\x8e/\x904\xc9%G\x19\u00ceP\u026ad0^\u0596\xdf\x1e\x8a\x01\x00N.E\xfb~\xe0\x00\x00\u07d4\x8e2@\xb0\x81\x0e\x1c\xf4\a\xa5\x00\x80G@\u03cdad2\xa4\x89\x02/fU\xef\v8\x80\x00\u07d4\x8eHj\x04B\xd1q\xc8`[\xe3H\xfe\xe5~\xb5\b^\xff\r\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8eaV3k\xe2\u037e2\x14\r\xf0\x8a+\xa5_\u0425\x84c\x89\x04\t\x9e\x1dcW\x18\x00\x00\u07d4\x8eg\b\x15\xfbg\xae\xae\xa5{\x86SN\xdc\x00\xcd\xf5d\xfe\u5272\xe4\xb3#\xd9\xc5\x10\x00\x00\u07d4\x8emt\x85\xcb\u942c\xc1\xad\x0e\xe9\xe8\xcc\xf3\x9c\f\x93D\x0e\x893\xc5I\x901r\f\x00\x00\xe0\x94\x8et\xe0\u0477~\xbc\x82:\xca\x03\xf1\x19\x85L\xb1 '\xf6\u05ca\x16\xb3R\xda^\x0e\xd3\x00\x00\x00\u07d4\x8ex\xf3QE}\x01oJ\xd2u^\xc7BN\\!\xbamQ\x89\a\xea(2uw\b\x00\x00\u07d4\x8ey6\u0552\x00\x8f\xdcz\xa0N\xde\xebuZ\xb5\x13\u06f8\x9d\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x8e\u007f\xd28H\xf4\xdb\a\x90j}\x10\xc0K!\x80;\xb0\x82'\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8e\x92\xab\xa3\x8er\xa0\x98\x17\v\x92\x95\x92FSz.UV\xc0\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\x8e\x98ve$\xb0\xcf'G\xc5\r\xd4;\x95gYM\x971\u0789lD\xb7\xc2a\x82(\x00\x00\u07d4\x8e\x9b5\xadJ\n\x86\xf7XDo\xff\xde4&\x9d\x94\f\xea\u0349\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8e\x9c\b\xf78f\x1f\x96v#n\xff\x82\xbaba\xdd?H\"\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x8e\x9cB\x92f\xdf\x05~\xfax\xdd\x1d_w\xfc@t*\xd4f\x89\x10D.\u0475l|\x80\x00\u07d4\x8e\xa6V\xe7\x1e\xc6Q\xbf\xa1|ZWY\xd8`1\xcc5\x99w\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x8e\xae)CU\x98\xba\x8f\x1c\x93B\x8c\xdb>+M1\a\x8e\x00\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8e\xb1\xfb\xe4\xe5\xd3\x01\x9c\xd7\xd3\r\xae\x9c\r[Lv\xfbc1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8e\xb5\x17t\xaf k\x96k\x89\t\xc4Z\xa6r'H\x80,\f\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x8e\xb8\xc7\x19\x82\xa0\x0f\xb8Bu)2S\xf8\x04ED\xb6kI\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\x8e\xcb\u03ec\xbf\xaf\xe9\xf0\f9\"\xa2N,\xf0\x02gV\xca \x8a\x011\xbe\xb9%\xff\xd3 \x00\x00\u07d4\x8e\u03b2\xe1$Sl[_\xfcd\x0e\xd1O\xf1^\u0668\xcbq\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8e\u042f\x11\xff(p\xda\x06\x81\x00J\xfe\x18\xb0\x13\xf7\xbd8\x82\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u0794\x8e\xd1Cp\x1f/r(\x0f\xd0J{Ad(\x19y\xea\x87\u0248\xc2I\xfd\xd3'x\x00\x00\u07d4\x8e\xd1R\x8bD~\xd4)y\x02\xf69\xc5\x14\u0414J\x88\xf8\u0209\n\xc6\xe7z\xb6c\xa8\x00\x00\u07d4\x8e\xd4(L\x0fGD\x9c\x15\xb8\u0673$]\u8fb6\u0380\xbf\x89+^:\xf1k\x18\x80\x00\x00\xe0\x94\x8e\xde~=\xc5\aI\xc6\xc5\x0e.(\x16\x84x\xc3M\xb8\x19F\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4\x8e\xe5\x843}\xdb\xc8\x0f\x9e4\x98\xdfU\xf0\xa2\x1e\xac\xb5\u007f\xb1\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x8e\xeb\xec\x1ab\xc0\x8b\x05\xa7\xd1\u0551\x80\xaf\x9f\xf0\u044e?6\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x8e\xf4\u0622\xc2o\xf7\x14\xb6u\x89\x19\x80\x1c\x83\xb6\xc7\xc0\x00\x00\u07d4\x8fM\x1dAi>F,\xf9\x82\xfd\x81\u042ap\x1d:St\u0249\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8fM\x1e~Ea(J4\xfe\xf9g<\r4\xe1*\xf4\xaa\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8fO\xb1\xae\xa7\xcd\x0fW\x0e\xa5\xe6\x1b@\xa4\xf4Q\vbd\xe4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x8fV\x1bA\xb2\t\xf2H\u0229\x9f\x85\x87\x887bP`\x9c\xf3\x89\\(=A\x03\x94\x10\x00\x00\xe0\x94\x8fX\xd84\x8f\xc1\xdcN\r\xd84;eC\xc8W\x04^\xe9@\x8a\x02\xe3\x03\x8d\xf4s\x03(\x00\x00\u07d4\x8f`\x89_\xbe\xbb\xb5\x01\u007f\xcb\xff<\u0763\x97)+\xf2[\xa6\x89\x17D\x06\xff\x9fo\u0480\x00\u07d4\x8fd\xb9\xc1$m\x85x1d1\a\xd3U\xb5\xc7_\xef]O\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\x8ff\x0f\x8b.L|\u00b4\xac\x9cG\xed(P\x8d_\x8f\x86P\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x8fi\xea\xfd\x023\xca\xdb@Y\xabw\x9cF\xed\xf2\xa0PnH\x89`\xf0f \xa8IE\x00\x00\xe0\x94\x8fq~\xc1U/LD\x00\x84\xfb\xa1\x15J\x81\xdc\x00>\xbd\xc0\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\x8f\x8a\xcb\x10v\a8\x84y\xf6K\xaa\xab\xea\x8f\xf0\a\xad\xa9}\x8a\x05\xc6\xf3\b\n\xd4#\xf4\x00\x00\u07d4\x8f\x8c\xd2n\x82\xe7\xc6\xde\xfd\x02\u07ed\a\x97\x90!\xcb\xf7\x15\f\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x8f\x8f7\u042d\x8f3]*q\x01\xb4\x11V\xb6\x88\xa8\x1a\x9c\xbe\x89\x03\xcbq\xf5\x1f\xc5X\x00\x00\u07d4\x8f\x92\x84O(*\x92\x99\x9e\u5d28\xd7s\xd0kiM\xbd\x9f\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\x8f\xact\x8fxJ\x0f\xedh\u06e43\x19\xb4*u\xb4d\x9cn\x891T\xc9r\x9d\x05x\x00\x00\u07d4\x8f\u0665\xc3:}\x9e\xdc\xe0\x99{\xdfw\xab0d$\xa1\x1e\xa9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x8f\xef\xfa\xdb8z\x15G\xfb(M\xa9\xb8\x14\u007f>|m\xc6\u0689-b{\xe4S\x05\b\x00\x00\u07d4\x8f\xf4`Ehw#\xdc3\xe4\u0419\xa0i\x04\xf1\ubd44\u0709lk\x93[\x8b\xbd@\x00\x00\u07d4\x8f\xfa\x06!\"\xac0t\x18\x82\x1a\u06d3\x11\aZ7\x03\xbf\xa3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x8f\xfe2)\x97\xb8\xe4\x04B-\x19\xc5J\xad\xb1\x8f[\xc8\u9dc9\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x90\x01\x94\u0131\aC\x05\u045d\xe4\x05\xb0\xacx(\x0e\xca\xf9g\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x90\x03\xd2p\x89\x1b\xa2\xdfd=\xa84\x15\x83\x195E\xe3\xe0\x00\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x90\x05z\xf9\xaaf0~\xc9\xf03\xb2\x97$\u04f2\xf4\x1e\xb6\xf9\x8a\x19\xd1\u05aa\xdb,R\xe8\x00\x00\u07d4\x90\x0f\v\x8e5\xb6h\xf8\x1e\xf2R\xb18U\xaaP\a\xd0\x12\xe7\x89\x17\n\x0fP@\xe5\x04\x00\x00\u07d4\x90\x18\xcc\x1fH\xd20\x8e%*\xb6\b\x9f\xb9\x9a|\x1dV\x94\x10\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x90\x1d\x99\xb6\x99\xe5\u0191\x15\x19\xcb v\xb4\xc7c0\xc5M\"\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x90-t\xa1W\xf7\u04b9\xa37\x8b\x1fVp70\xe0:\x17\x19\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x904\x13\x87\x8a\xea;\xc1\bc\t\xa3\xfev\x8beU\x9e\x8c\xab\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x90If\xcc\"\x13\xb5\xb8\xcb[\xd6\b\x9e\xf9\xcd\xdb\xef~\xdf\u0309lk\x93[\x8b\xbd@\x00\x00\u07d4\x90L\xaaB\x9ca\x9d\x94\x0f\x8egA\x82j\r\xb6\x92\xb1\x97(\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x90R\xf2\xe4\xa3\xe3\xc1-\xd1\xc7\x1b\xf7\x8aN\xc3\x04=\u020b~\x89\x0e~\xeb\xa3A\vt\x00\x00\u0794\x90U&V\x8a\xc1#\xaf\xc0\xe8J\xa7\x15\x12O\xeb\xe8=\xc8|\x88\xf8i\x93)g~\x00\x00\u07d4\x90\x92\x91\x87\a\xc6!\xfd\xbd\x1d\x90\xfb\x80\xebx\u007f\xd2osP\x89\x85[[\xa6\\\x84\xf0\x00\x00\u07d4\x90\x9b^v:9\xdc\u01d5\"=s\xa1\u06f7\xd9L\xa7Z\u0209lk\x93[\x8b\xbd@\x00\x00\u07d4\x90\xac\xce\xd7\xe4\x8c\b\u01b94dm\xfa\n\xdf)\u0714\aO\x89\x03\vK\x15{\xbdI\x00\x00\u07d4\x90\xb1\xf3p\xf9\xc1\xeb\v\xe0\xfb\x8e+\x8a\xd9jAcq\u074a\x890\xca\x02O\x98{\x90\x00\x00\u07d4\x90\xb6/\x13\x1a_)\xb4UqQ>\xe7\xa7J\x8f\v#\"\x02\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\x90\xbdb\xa0P\x84Ra\xfaJ\x9f|\xf2A\xeac\v\x05\ufe09\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x90\xc4\x1e\xba\x00\x8e \xcb\xe9'\xf3F`?\u0206\x98\x12Yi\x89\x02F\xdd\xf9yvh\x00\x00\u07d4\x90\u0480\x9a\xe1\xd1\xff\xd8\xf6>\xda\x01\xdeI\xddU-\xf3\u047c\x89\u063beI\xb0+\xb8\x00\x00\u07d4\x90\xdc\t\xf7\x17\xfc*[i\xfd`\xba\b\xeb\xf4\v\xf4\xe8$l\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\x90\xe3\x00\xacqE\x1e@\x1f\x88\u007fnw(\x85\x16G\xa8\x0e\a\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x90\xe3Z\xab\xb2\xde\xef@\x8b\xb9\xb5\xac\xefqDW\xdf\xdebr\x89\x05l\xd5_\xc6M\xfe\x00\x00\u07d4\x90\xe7\a\x0fM\x03?\xe6\x91\f\x9e\xfeZ'\x8e\x1f\xc6#M\xef\x89\x05q8\b\x19\xb3\x04\x00\x00\u07d4\x90\xe9>M\xc1q!HyR36\x14\x00+\xe4#VI\x8e\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x90\u9a68.\u06a8\x14\u0084\xd22\xb6\u9e90p\x1dIR\x89\x05k\xe0<\xa3\xe4}\x80\x00\u07d4\x90\xf7t\xc9\x14}\u0790\x85=\xdcC\xf0\x8f\x16\xd4U\x17\x8b\x8c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x90\xfcS{!\x06Xf\n\x83\xba\xa9\xacJ\x84\x02\xf6WF\xa8\x89e\xea=\xb7UF`\x00\x00\u07d4\x91\x05\n\\\xff\xad\xed\xb4\xbbn\xaa\xfb\xc9\xe5\x014(\xe9l\x80\x89\\(=A\x03\x94\x10\x00\x00\u07d4\x91\x05\x17d\xafk\x80\x8eB\x12\xc7~0\xa5W.\xaa1pp\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x91\v}Wz~9\xaa#\xac\xf6*\xd7\xf1\xef4)4\xb9h\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x91\x0e\x99eC4Lh\x15\xfb\x97\u0367\xafK\x86\x98vZ[\x89\x05\x9a\xf6\x98)\xcfd\x00\x00\u07d4\x91\x1f\xee\xa6\x1f\xe0\xedP\u0179\xe5\xa0\xd6`q9\x9d(\xbd\u0189\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\x91\x1f\xf23\xe1\xa2\x11\xc0\x17,\x92\xb4l\xf9\x97\x03\x05\x82\xc8:\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x91 \xe7\x11s\xe1\xba\x19\xba\x8f\x9fO\xdb\u072a4\xe1\u05bbx\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x91!\x17\x12q\x9f+\bM;8u\xa8Pi\xf4f61A\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x91#\x04\x11\x8b\x80G=\x9e\x9f\xe3\xeeE\x8f\xbea\x0f\xfd\xa2\xbb\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x91Tky\xec\xf6\x9f\x93kZV\x15\b\xb0\xd7\xe5\f\u0159/\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\x91V\u0440)5\x0eG\x04\b\xf1_\x1a\xa3\xbe\x9f\x04\ng\u018965\u026d\xc5\u07a0\x00\x00\u07d4\x91b\x0f>\xb3\x04\xe8\x13\u048b\x02\x97Ume\xdcN]\u5a89\xcf\x15&@\xc5\xc80\x00\x00\xe0\x94\x91k\xf7\xe3\xc5E\x92\x1d2\x06\xd9\x00\xc2O\x14\x12|\xbd^p\x8a\x03\xd0\u077c}\xf2\xbb\x10\x00\x00\u0794\x91l\xf1}qA(\x05\xf4\xaf\xc3DJ\v\x8d\xd1\xd93\x9d\x16\x88\xc6s\xce<@\x16\x00\x00\u07d4\x91{\x8f\x9f:\x8d\t\xe9 ,R\u009erA\x96\xb8\x97\xd3^\x89\b\xbaR\xe6\xfcE\xe4\x00\x00\u07d4\x91\x89g\x91\x8c\u0617\xdd\x00\x05\xe3m\xc6\u0203\xefC\x8f\xc8\u01c9\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\x91\x89\x8e\xab\x8c\x05\xc0\"(\x83\xcdM\xb2;w\x95\xe1\xa2J\u05c9lk\x93[\x8b\xbd@\x00\x00\u0794\x91\x91\xf9F\x98!\x05\x16\xcfc!\xa1B\a\x0e Yvt\xed\x88\xee\x9d[\xe6\xfc\x11\x00\x00\u07d4\x91\xa4\x14\x9a,{\x1b:g\xea(\xaf\xf3G%\u0fcdu$\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\x91\xa7\x87\xbcQ\x96\xf3HW\xfe\f7/M\xf3v\xaa\xa7f\x13\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x91\xa8\xba\xae\xd0\x12\xea.c\x80;Y=\r\f*\xabL[\n\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\x91\xac\\\xfeg\xc5J\xa7\xeb\xfb\xa4HflF\x1a;\x1f\xe2\xe1\x89\x15\xc94\x92\xbf\x9d\xfc\x00\x00\u07d4\x91\xbb?y\x02+\xf3\xc4S\xf4\xff%n&\x9b\x15\xcf,\x9c\xbd\x89RX\\\x13\xfe:\\\x00\x00\u07d4\x91\xc7^<\xb4\xaa\x89\xf3F\x19\xa1d\xe2\xa4x\x98\xf5gM\x9c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x91\xc8\f\xaa\b\x1b85\x1d*\x0e\x0e\x00\xf8\n4\xe5dt\xc1\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x91\xccF\xaa7\x9f\x85jf@\xdc\xcdZd\x8ay\x02\xf8I\u0649\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x91\u04a9\xee\x1am\xb2\x0fS\x17\u0327\xfb\xe218\x95\u06ce\xf8\x8a\x01\xcc\u00e5/0n(\x00\x00\u07d4\x91\xd6n\xa6(\x8f\xaaK=`l*\xa4\\{k\x8a%'9\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x91\u06f6\xaa\xad\x14\x95\x85\xbeG7\\]m\xe5\xff\t\x19\x15\x18\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x91\xe8\x81\x06R\xe8\xe6\x16\x15%\xd6;\xb7u\x1d\xc2\x0fg`v\x89'Mej\xc9\x0e4\x00\x00\u07d4\x91\xf5\x16\x14l\xda (\x17\x19\x97\x80`\u01beAI\x06|\x88\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x91\xf6$\xb2J\x1f\xa5\xa0V\xfeW\x12)\xe77\x9d\xb1K\x9a\x1e\x8a\x02\x8a\x85\x17\xc6i\xb3W\x00\x00\xe0\x94\x91\xfe\x8aLad\u07cf\xa6\x06\x99]k\xa7\xad\xca\xf1\u0213\u038a\x03\x99\x92d\x8a#\u0220\x00\x00\u07d4\x92\x1fRa\xf4\xf6\x12v\a\x06\x89&%\xc7^{\u0396\xb7\b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92!\xc9\xce\x01#&et\x10\x96\xac\a#Y\x03\xad\x1f\xe2\xfc\x89\x06\xdbc3U\"b\x80\x00\u07d4\x92%\x988`\xa1\xcbF#\xc7$\x80\xac\x16'+\f\x95\xe5\xf5\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x92%\xd4jZ\x80\x949$\xa3\x9e[\x84\xb9m\xa0\xacE\x05\x81\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x92* \u01da\x1d:&\xdd8)g{\xf1\xd4\\\x8fg+\xb6\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x92C\x8eR\x03\xb64o\xf8\x86\xd7\xc3b\x88\xaa\xcc\xccx\xce\u028965\u026d\xc5\u07a0\x00\x00\u07d4\x92C\xd7v-w({\x12c\x86\x88\xb9\x85N\x88\xa7i\xb2q\x8965\u026d\xc5\u07a0\x00\x00\u0794\x92K\xcez\x85<\x97\v\xb5\xec{\xb7Y\xba\xeb\x9ct\x10\x85{\x88\xbe -j\x0e\xda\x00\x00\u07d4\x92N\xfam\xb5\x95\xb7\x93\x13'~\x881\x96%\akX\n\x10\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92U\x82&\xb3\x84bl\xadH\xe0\x9d\x96k\xf19^\xe7\xea]\x89\x12\x1e\xa6\x8c\x11NQ\x00\x00\u07d4\x92`\x82\xcb~\xedK\x19\x93\xad$ZGrg\xe1\xc3<\xd5h\x89\x14Jt\xba\u07e4\xb6\x00\x00\u07d4\x92b\t\xb7\xfd\xa5N\x8d\u06dd\x9eM=\x19\xeb\u070e\x88\u009f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92h\xd6&FV6\x11\xdc;\x83*0\xaa#\x94\xc6F\x13\xe3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92i\x8e4Sx\xc6-\x8e\xda\x18M\x946j\x14K\f\x10[\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\x92y:\u0173rhwJq0\xde+\xbd3\x04\x05f\x17s\x89\x02,\xa3X|\xf4\xeb\x00\x00\xe0\x94\x92y\xb2\"\x8c\xec\x8f{M\xda?2\x0e\x9a\x04f\xc2\xf5\x85\u028a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x92|\xb7\xdc\x18p6\xb5B{\xc7\xe2\x00\xc5\xecE\f\x1d'\u0509\v\xb5\x9a'\x95<`\x00\x00\u07d4\x92|\u00bf\xda\x0e\b\x8d\x02\xef\xf7\v8\xb0\x8a\xa5<\xc3\tA\x89do`\xa1\xf9\x866\x00\x00\xe0\x94\x92\x84\xf9m\xdbG\xb5\x18n\xe5X\xaa12M\xf56\x1c\x0fs\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\x92\x9d6\x8e\xb4j-\x1f\xbd\xc8\xff\xa0`~\xdeK\xa8\x8fY\xad\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92\xa7\u0166Cb\xe9\xf8B\xa2=\xec\xa2\x105\x85\u007f\x88\x98\x00\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\x92\xa8\x98\xd4o\x19q\x9c8\x12j\x8a<'\x86z\xe2\xce\u5589lk\x93[\x8b\xbd@\x00\x00\u07d4\x92\xa9q\xa79y\x9f\x8c\xb4\x8e\xa8G]r\xb2\xd2GAr\xe6\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x92\xaa\xe5\x97h\xed\xdf\xf8<\xfe`\xbbQ.s\n\x05\xa1a\u05c9\\\x97xA\fv\u0440\x00\u07d4\x92\xad\x1b=u\xfb\xa6}Tf=\xa9\xfc\x84\x8a\x8a\xde\x10\xfag\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92\xae[|~\xb4\x92\xff\x1f\xfa\x16\xddB\xad\x9c\xad@\xb7\xf8\u0709.\xe4IU\b\x98\xe4\x00\x00\u07d4\x92\xc0\xf5s\xec\xcfb\xc5H\x10\xeek\xa8\xd1\xf1\x13T+0\x1b\x89\xb7ro\x16\u0331\xe0\x00\x00\u07d4\x92\xc1?\xe0\xd6\u0387\xfdP\xe0=\uf7e6@\x05\t\xbdps\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x92\xc9L( \xdf\xcfqV\xe6\xf10\x88\xec\u754b6v\xfd\x89\x05-T(\x04\xf1\xce\x00\x00\u07d4\x92\xcf\xd6\x01\x88\xef\u07f2\xf8\xc2\xe7\xb1i\x8a\xbb\x95&\xc1Q\x1f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x92\u062d\x9aMah;\x80\u0526g.\x84\xc2\rbB\x1e\x80\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x92\u0725\xe1\x02\xb3\xb8\x1b`\xf1\xa5\x04cIG\xc3t\xa8\x8c\u02c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x92\xe454\x0e\x9d%<\x00%c\x89\xf5+\x06}U\x97Nv\x89\x0e\x87?D\x13<\xb0\x00\x00\xe0\x94\x92\xe49(\x16\xe5\xf2\xef_\xb6X7\xce\xc2\xc22\\\xc6I\"\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x92\xe6X\x1e\x1d\xa1\xf9\xb8F\xe0\x93G3=\xc8\x18\xe2\u04acf\x89\xc5S%\xcat\x15\xe0\x00\x00\u07d4\x93\x1d\xf3M\x12%\xbc\xd4\"Nch\r\\L\t\xbc\xe75\xa6\x89\x03\xaf\xb0\x87\xb8v\x90\x00\x00\u07d4\x93\x1f\xe7\x12\xf6B\a\xa2\xfdP\"r\x88CT\x8b\xfb\x8c\xbb\x05\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x93#_4\r(c\xe1\x8d/LR\x99e\x16\x13\x8d\"\x02g\x89\x04\x00.D\xfd\xa7\xd4\x00\x00\u07d4\x93%\x82U\xb3|\u007fX\xf4\xb1\x06s\xa92\xdd:\xfd\x90\xf4\xf2\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x93(\xd5\\\xcb?\xceS\x1f\x19\x93\x823\x9f\x0eWn\xe8@\xa3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x93)\xff\xdc&\x8b\xab\u0788t\xb3f@l\x81D[\x9b-5\x89\x16\xe6/\x8cs\f\xa1\x80\x00\u07d4\x93+\x9c\x04\xd4\r*\xc80\x83\xd9B\x98\x16\x9d\xae\x81\xab.\u0409lk\x93[\x8b\xbd@\x00\x00\u07d4\x9346\xc8G&U\xf6L:\xfa\xaf|Lb\x1c\x83\xa6+8\x8965\u026d\xc5\u07a0\x00\x00\u0794\x93;\xf3?\x82\x99p+:\x90&B\xc3>\v\xfa\xea\\\x1c\xa3\x88\xd2\xf1?w\x89\xf0\x00\x00\u07d4\x93@4\\\xa6\xa3\uaf77sc\xf2X`C\xf2\x948\xce\v\x89\x1c\xc8\x05\xda\r\xff\xf1\x00\x00\xe0\x94\x93@\xb5\xf6x\xe4^\xe0^\xb7\b\xbbz\xbbn\xc8\xf0\x8f\x1bk\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x93J\xf2\x1b~\xbf\xa4g\xe2\xce\xd6Z\xa3N\xdd:\x0e\xc7\x132\x8a\a\x80\x1f>\x80\xcc\x0f\xf0\x00\x00\xe0\x94\x93PiDJj\x98M\xe2\bNFi*\xb9\x9fg\x1f\xc7'\x8a\x01\xe7\xe4\x17\x1b\xf4\u04e0\x00\x00\xe0\x94\x93P~\x9e\x81\x19\xcb\xce\u068a\xb0\x87\xe7\xec\xb0q8=i\x81\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\x93g\x8a\x00\x00\xe0\x94\x93m\xcf\x00\x01\x94\xe3\xbf\xf5\n\u0174$:;\xa0\x14\xd6a\u060a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x93o8\x13\xf5\xf6\xa1;\x8eO\xfe\xc8?\xe7\xf8&\x18jq\u0349\x1c0s\x1c\xec\x03 \x00\x00\u07d4\x93t\x86\x9dJ\x99\x11\xee\x1e\xafU\x8b\xc4\u00b6>\xc6:\xcf\u074965\u026d\xc5\u07a0\x00\x00\u07d4\x93uc\u0628\x0f\u05657\xb0\xe6m \xa0%%\xd5\u0606`\x89\x87\x86x2n\xac\x90\x00\x00\u07d4\x93v\xdc\xe2\xaf.\xc8\xdc\xdat\x1b~sEfF\x81\xd96h\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x93\x86\x8d\xdb*yM\x02\xeb\xda/\xa4\x80|v\xe3`\x98X\u0709m\xee\x15\xfc|$\xa7\x80\x00\xe0\x94\x93\x9cC\x13\xd2(\x0e\xdf^\a\x1b\xce\xd8F\x06?\n\x97]T\x8a\x19i6\x89t\xc0[\x00\x00\x00\xe0\x94\x93\xa6\xb3\xabB0\x10\xf9\x81\xa7H\x9dJ\xad%\xe2b\\WA\x8a\x04F\x80\xfej\x1e\xdeN\x80\x00\u07d4\x93\xaa\x8f\x92\xeb\xff\xf9\x91\xfc\x05^\x90ne\x1a\xc7h\xd3+\u02092\xf5\x1e\u06ea\xa30\x00\x00\u07d4\x93\xb4\xbf?\xdf\xf6\xde?NV\xbamw\x99\xdcK\x93\xa6T\x8f\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4\x93\xbc}\x9aJ\xbdD\u023b\xb8\xfe\x8b\xa8\x04\xc6\x1a\xd8\xd6Wl\x89\xd8\xd6\x11\x9a\x81F\x05\x00\x00\u07d4\x93\xc2\xe6N]\xe5X\x9e\xd2P\x06\xe8C\x19n\xe9\xb1\xcf\v>\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94\x93\u020e-\x88b\x1e0\xf5\x8a\x95\x86\xbe\xd4\t\x89\x99\xebg\u074a\x06\x9bZ\xfa\xc7P\xbb\x80\x00\x00\u07d4\x93\xe0\xf3~\xcd\xfb\x00\x86\xe3\xe8b\xa9p4D{\x1eM\xec\x1a\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\xe0\x94\x93\xe3\x03A\x1a\xfa\xf6\xc1\a\xa4A\x01\u026c[6\xe9\xd6S\x8b\x8a\r\xf9\xdd\xfe\xcd\x03e@\x00\x00\u07d4\x93\xf1\x8c\xd2R`@v\x14\x88\xc5\x13\x17M\x1eycv\x8b,\x89\x82\xff\xac\x9a\u0553r\x00\x00\u07d4\x94\x0fqQ@P\x9f\xfa\xbf\x97EF\xfa\xb3\x90\"\xa4\x19R\u0489K\xe4\xe7&{j\xe0\x00\x00\u07d4\x94,k\x8c\x95[\xc0\u0608\x12g\x8a#g%\xb3'9\xd9G\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\x94=7\x86JJS}5\xc8\u0657#\xcdd\x06\xce%b\xe6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x94C\x9c\xa9\xcc\x16\x9ay\u0520\x9c\xae^gvJo\x87\x1a!\x89\r\x02\xabHl\xed\xc0\x00\x00\xe0\x94\x94D\x9c\x01\xb3*\u007f\xa5Z\xf8\x10OB\xcd\xd8D\xaa\x8c\xbc@\x8a\x03\x81\x11\xa1\xf4\xf0<\x10\x00\x00\xe0\x94\x94E\xba\\0\xe9\x89a\xb8`$a\xd08]@\xfb\xd8\x03\x11\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x94O\a\xb9o\x90\xc5\xf0\xd7\xc0\u0140S1I\xf3\xf5\x85\xa0x\x89\x04\x02\xf4\xcf\xeeb\xe8\x00\x00\u07d4\x94T\xb3\xa8\xbf\xf9p\x9f\xd0\u1407~l\xb6\u0219t\xdb\u0589\x90\xf54`\x8ar\x88\x00\x00\u07d4\x94]\x96\xeaW>\x8d\xf7&+\xbf\xa5r\"\x9bK\x16\x01k\x0f\x89\vX\x9e\xf9\x14\xc1B\x00\x00\u07d4\x94^\x18v\x9d~\xe7'\xc7\x01?\x92\xde$\xd1\x17\x96\u007f\xf3\x17\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x94a'\x81\x03;W\xb1F\xeet\xe7S\xc6r\x01\u007fS\x85\xe4\x89\xc3(\t>a\xee@\x00\x00\xe0\x94\x94dJ\xd1\x16\xa4\x1c\xe2\xca\u007f\xbe\xc6\t\xbd\xefs\x8a*\xc7\u01ca\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x94p\xcc6YE\x86\x82\x18!\xc5\u0256\xb6\xed\xc8;mZ2\x89\x01M\x11 \u05f1`\x00\x00\xe0\x94\x94u\xc5\x10\xec\x9a&\x97\x92GtL=\x8c;\x0e\v_D\u04ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x94~\x11\xe5\xea)\ro\u00f3\x80H\x97\x9e\f\xd4N\xc7\xc1\u007f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x94\x83\u064f\x14\xa3?\xdc\x11\x8d@9U\u00995\xed\xfc_p\x89\x18\xea;4\xefQ\x88\x00\x00\u07d4\x94\x911\xf2\x89C\x92\\\xfc\x97\xd4\x1e\f\xea\v&)s\xa70\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\x94\x9f\x84\xf0\xb1\xd7\u0127\xcfI\xee\u007f\x8b,J\x13M\xe3(x\x89%\"H\u07b6\xe6\x94\x00\x00\u07d4\x94\x9f\x8c\x10{\xc7\xf0\xac\xea\xa0\xf1pR\xaa\xdb\xd2\xf9s+.\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x94\xa7\u0368\xf4\x81\xf9\u061dB\xc3\x03\xae\x162\xb3\xb7\t\xdb\x1d\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x94\xa9\xa7\x16\x911| d'\x1bQ\xc95?\xbd\xed5\x01\xa8\x89\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4\x94\xadK\xad\x82K\xd0\ub7a4\x9cX\u03bc\xc0\xff^\b4k\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\x94\xbb\xc6}\x13\xf8\x9e\xbc\xa5\x94\xbe\x94\xbcQp\x92\f0\xd9\xf3\x89\x04X\xff\xa3\x15\nT\x00\x00\u07d4\x94\xbe:\xe5Ob\xd6c\xb0\xd4\u031e\x1e\xa8\xfe\x95V\ua7bf\x89\x01C\x13,\xa8C\x18\x00\x00\xe0\x94\x94\xc0U\xe8X5z\xaa0\xcf A\xfa\x90Y\xce\x16J\x1f\x91\x8a\x04<%\xe0\xdc\xc1\xbd\x1c\x00\x00\xe0\x94\x94\xc7B\xfdz\x8by\x06\xb3\xbf\xe4\xf8\x90O\xc0\xbe\\v\x803\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x94\xcaV\xdew\u007f\xd4S\x17\u007f^\x06\x94\xc4x\xe6j\xff\x8a\x84\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x94\xd8\x10t\xdbZ\xe1\x97\u04bb\x13s\xab\x80\xa8}\x12\x1cK\u04ca\x01\xfd\x934\x94\xaa_\xe0\x00\x00\u07d4\x94\u06c0xs\x86\n\xac=Z\xea\x1e\x88^R\xbf\xf2\x86\x99T\x89\xae\x8ez\v\xb5u\xd0\x00\x00\u07d4\x94\xe1\xf5\u02db\x8a\xba\xce\x03\xa1\xa6B\x82VU;i\f#U\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x94\xef\x8b\xe4Pw\xc7\xd4\xc5e'@\u0794jbbOq?\x89\x05l\xf5Y:\x18\xf8\x80\x00\u07d4\x94\xf1?\x9f\b6\xa3\xee$7\xa8I\"\u0498M\xc0\xf7\xd5;\x89\xa2\xa02\x9b\u00ca\xbe\x00\x00\u07d4\x94\xf8\xf0W\xdb~`\xe6u\xad\x94\x0f\x15X\x85\u0464w4\x8e\x89\x15\xbeat\xe1\x91.\x00\x00\xe0\x94\x94\xfc\u03ad\xfe\\\x10\x9c^\xae\xafF-C\x871B\u020e\"\x8a\x01\x045a\xa8\x82\x93\x00\x00\x00\u07d4\x95\x03N\x16!\x86Q7\xcdG9\xb3F\xdc\x17\xda:'\xc3N\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\x95\fh\xa4\t\x88\x15M#\x93\xff\xf8\xda|\u0369\x96\x14\xf7,\x89\xf9AF\xfd\x8d\xcd\xe5\x80\x00\xe0\x94\x95\x0f\xe9\xc6\xca\xd5\f\x18\xf1\x1a\x9e\xd9\xc4W@\xa6\x18\x06\x12\u040a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x95!\x83\xcf\u04ce5.W\x9d6\xde\xce\u0171\x84P\xf7\xfb\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x95'\x8b\b\xde\xe7\xc0\xf2\xc8\xc0\xf7\"\xf9\xfc\xbb\xb9\xa5$\x1f\u0689\x82\x93\t\xf6O\r\xb0\x00\x00\u07d4\x95,W\xd2\xfb\x19Q\a\xd4\xcd\\\xa3\x00wA\x19\u07ed/x\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x955r\xf0\xeam\xf9\xb1\x97\xca\xe4\x0eK\x8e\xcc\x05lCq\u014965\u026d\xc5\u07a0\x00\x00\u07d4\x95>\xf6R\xe7\xb7i\xf5=nxjX\x95/\xa9>\xe6\xab\u725b\ny\x1f\x12\x110\x00\x00\u07d4\x95DpF1;/:^\x19\xb9H\xfd;\x8b\xed\xc8,q|\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x95]\xb3\xb7C`\xb9\xa2hg~s\u03a8!f\x8a\xf6\xfa\u038a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4\x95`\xe8\xacg\x18\xa6\xa1\xcd\xcf\xf1\x89\xd6\x03\xc9\x06>A=\xa6\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x95g\xa0\u0781\x1d\xe6\xff\t[~\xe6N\u007f\x1b\x83\xc2a[\x80\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\x95h\x1c\xda\xe6\x9b I\xce\x10\x1e2\\u\x98\x92\xca\xc3\xf8\x11\x89\x9a\xe9*\x9b\xc9L@\x00\x00\xe0\x94\x95h\xb7\xdeuV(\xaf5\x9a\x84T=\xe25\x04\xe1^A\xe6\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x95i\xc6:\x92\x84\xa8\x05bm\xb3\xa3.\x9d#c\x93GaQ\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x95\x80\x9e\x8d\xa3\xfb\xe4\xb7\xf2\x81\xf0\xb8\xb1q_B\x0f}}c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x95\x9fW\xfd\xedj\xe3y\x13\xd9\x00\xb8\x1e_H\xa7\x93\"\xc6'\x89\r\xdb&\x10GI\x11\x80\x00\u07d4\x95\x9f\xf1\u007f\x1dQ\xb4s\xb4@\x10\x05'U\xa7\xfa\x8cu\xbdT\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x95\xa5w\xdc.\xb3\xael\xb9\xdf\xc7z\xf6\x97\xd7\xef\xdf\xe8\x9a\x01\x89\a_a\x0fp\xed \x00\x00\u07d4\x95\xcbm\x8acy\xf9J\xba\x8b\x88ViV,MD\x8eV\xa7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x95\xd5PB{ZQLu\x1ds\xa0\xf6\u049f\xb6]\"\xed\x10\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x95\u064d\f\x10i\x90\x8f\x06zR\xac\xac+\x8bSM\xa3z\xfd\x89oY\xb60\xa9)p\x80\x00\xe0\x94\x95\xdfN4E\xd7f&$\u010e\xbat\u03de\nS\xe9\xf72\x8a\v\xdb\xc4\x1e\x03H\xb3\x00\x00\x00\u07d4\x95\xe6\xa5K-_g\xa2JHu\xafu\x10|\xa7\xea\x9f\xd2\xfa\x89Hz\x9a0E9D\x00\x00\xe0\x94\x95\xe6\xf9=\xac\"\x8b\xc7XZ%sZ\xc2\xd0v\xcc:@\x17\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x95\xe7ad$\xcd\ta\xa7\x17'$t7\xf0\x06\x92r(\x0e\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x95\xe8\n\x82\xc2\f\xbe= `$,\xb9-sX\x10\xd04\xa2\x89\x01\xc3.F?\u0539\x80\x00\u07d4\x95\xf6-\x02C\xed\xe6\x1d\xad\x9a1e\xf59\x05'\rT\xe2B\x89WG=\x05\u06ba\xe8\x00\x00\u07d4\x95\xfbZ\xfb\x14\xc1\uf6b7\xd1y\xc5\xc3\x00P?\xd6j^\xe2\x89\x01\xda\xf7\xa0+\r\xbe\x80\x00\u07d4\x96\x10Y\"\x02\u0082\xab\x9b\u0628\x84Q\x8b>\v\xd4u\x817\x89\x0e\x87?D\x13<\xb0\x00\x00\xe0\x94\x96\x1cY\xad\xc7E\x05\u0446M\x1e\xcf\u02ca\xfa\x04\x12Y<\x93\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\x96,\r\xec\x8a=FK\xf3\x9b\x12\x15\xea\xfd&H\n\xe4\x90\u0349l\x82\xe3\xea\xa5\x13\xe8\x00\x00\u07d4\x96,\xd2*\x8e\xdf\x1eONU\xb4\xb1]\xdb\xfb]\x9dT\x19q\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x963K\xfe\x04\xff\xfaY\x02\x13\xea\xb3e\x14\xf38\xb8d\xb76\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x967\xdc\x12r=\x9cxX\x85B\uac02fO?\x03\x8d\x9d\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x96N\xabK'kL\u0618>\x15\xcar\xb1\x06\x90\x0f\xe4\x1f\u0389\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x96b\xee\x02\x19&h+1\xc5\xf2\x00\xceEz\xbe\xa7ll\xe9\x89$Y\x0e\x85\x89\xebj\x00\x00\xe0\x94\x96l\x04x\x1c\xb5\xe6}\xde25\xd7\xf8b\x0e\x1a\xb6c\xa9\xa5\x8a\x10\r P\xdacQ`\x00\x00\u07d4\x96pv\xa8w\xb1\x8e\xc1ZA[\xb1\x16\xf0n\xf3&E\u06e3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x96{\xfa\xf7bC\u0379@\t\xae<\x8d5\x05\xe9\xc0\x80EK\xe0\xe8\x19\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x96\x92A\x91\xb7\xdfe[3\x19\xdcma7\xf4\x81\xa7:\x0f\xf3\x89\xd9\xec\xb4\xfd \x8eP\x00\x00\u07d4\x96\x96\x05!83\x8cr/\x11@\x81\\\xf7t\x9d\r;:t\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x96\xa5_\x00\xdf\xf4\x05\xdcM\xe5\xe5\x8cW\xf6\xf6\xf0\xca\xc5]/\x89jf\x167\x9c\x87\xb5\x80\x00\u07d4\x96\xaaW?\xed/#4\x10\u06eeQ\x80\x14[#\xc3\x1a\x02\xf0\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\x96\xadW\x9b\xbf\xa8\u06ce\xbe\xc9\u0486\xa7.Fa\xee\xd8\xe3V\x89:\v\xa4+\xeca\x83\x00\x00\u07d4\x96\xb44\xfe\x06W\xe4*\u0302\x12\xb6\x86Q9\xde\xde\x15\x97\x9c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x96\xb9\x06\xear\x9fFU\xaf\xe3\xe5}5'|\x96}\xfa\x15w\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x96\xd6-\xfdF\b\u007fb@\x9d\x93\xdd`a\x88\xe7\x0e8\x12W\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x96\xd9\u0328\xf5^\xea\x00@\xecn\xb3H\xa1wK\x95\xd9>\xf4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x96\xe7\xc0\xc9\u057f\x10\x82\x1b\xf1@\xc5X\xa1E\xb7\xca\xc2\x13\x97\x899>\xf1\xa5\x12|\x80\x00\x00\u07d4\x96\xeaj\u021a+\xac\x954{Q\u06e6=\x8b\xd5\xeb\xde\xdc\xe1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x96\xea\xfb\xf2\xfboM\xb9\xa46\xa7LE\xb5eDR\xe28\x19\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x96\xebR>\x83/P\n\x01}\xe1>\xc2\u007f]6lV\x0e\xff\x89\x10\xac\u03baC\xee(\x00\x00\u07d4\x96\xf0F*\xe6\xf8\xb9`\x88\xf7\xe9\u018ct\xb9\u062d4\xb3G\x89a\t=|,m8\x00\x00\u07d4\x96\xf8 P\vp\xf4\xa3\xe3#\x9da\x9c\xff\x8f\" u\xb15\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x96\xfeY\xc3\u06f3\xaa|\xc8\xcbbH\fe\xe5nb\x04\xa7\xe2\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x96\xffoP\x99h\xf3l\xb4,\xbaH\xdb2\xf2\x1fVv\xab\xf8\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x97\t8R*\xfb^\x8f\x99Hs\xc9\xfb\xdc&\xe3\xb3~1L\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x97\n\xbdS\xa5O\xcaJd) |\x18-MW\xbb9\u0520\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x97\r\x8b\x8a\x00\x16\xd1C\x05O\x14\x9f\xb3\xb8\xe5P\xdc\a\x97\u01c965\u026d\xc5\u07a0\x00\x00\u07d4\x97,/\x96\xaa\x00\u03ca/ Z\xbc\xf8\x93|\fu\xf5\xd8\u0649\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x97?N6\x1f\xe5\xde\u0358\x9dL\x8f}|\xc9y\x908]\xaf\x89\x15\x0f\x85C\xa3\x87B\x00\x00\u07d4\x97M\x05A\xabJG\xec\u007fu6\x9c\x00i\xb6J\x1b\x81w\x10\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u0794\x97M/\x17\x89_)\x02\x04\x9d\xea\xae\xcf\t\xc3\x04e\a@-\x88\xcc\x19\u00947\xab\x80\x00\u07d4\x97R\xd1O^\x10\x93\xf0qq\x1c\x1a\xdb\xc4\xe3\xeb\x1e\\W\xf3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x97V\xe1v\xc9\xefi>\xe1\xee\u01b9\xf8\xb1Q\xd3\x13\xbe\xb0\x99\x89A\rXj \xa4\xc0\x00\x00\u07d4\x97_7d\xe9{\xbc\xcfv|\xbd;y[\xa8m\x8b\xa9\x84\x0e\x89\x12\xc1\xb6\xee\xd0=(\x00\x00\xe0\x94\x97j\x18Sj\xf4\x18tBc\b\x87\x1b\xcd\x15\x12\xa7u\xc9\xf8\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x97n<\xea\xf3\xf1\xafQ\xf8\u009a\xff]\u007f\xa2\x1f\x03\x86\xd8\xee\x89\r\x02\xabHl\xed\xc0\x00\x00\xe0\x94\x97w\xcca\xcfuk\xe3\xb3\xc2\f\xd4I\x1ci\xd2u\xe7\xa1 \x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x97\x81\v\xaf\xc3~\x840c2\xaa\xcb5\xe9*\xd9\x11\xd2=$\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x97\x8cC\f\xe45\x9b\x06\xbc,\xdf\\)\x85\xfc\x95\x0eP\xd5\u0209\x1a\x05V\x90\xd9\u06c0\x00\x00\u07d4\x97\x95\xf6C\x19\xfc\x17\xdd\x0f\x82a\xf9\xd2\x06\xfbf\xb6L\xd0\u0249\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x97\x99\xca!\xdb\xcfi\xbf\xa1\xb3\xf7+\xacQ\xb9\xe3\xcaX|\xf9\x89\\(=A\x03\x94\x10\x00\x00\u07d4\x97\x9c\xbf!\xdf\xec\x8a\xce?\x1c\x19m\x82\u07d6%4\xdf9O\x89\x99\x91\xd4x\xddM\x16\x00\x00\u07d4\x97\x9dh\x1ca}\xa1o!\xbc\xac\xa1\x01\xed\x16\xed\x01Z\xb6\x96\x89e\xea=\xb7UF`\x00\x00\u07d4\x97\x9f0\x15\x8bWK\x99\x9a\xab4\x81\a\xb9\xee\xd8[\x1f\xf8\xc1\x894\x95tD\xb8@\xe8\x00\x00\u07d4\x97\xa8o\x01\xce?|\xfdDA3\x0e\x1c\x9b\x19\xe1\xb1\x06\x06\xef\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x97\xb9\x1e\xfesP\xc2\xd5~~@k\xab\x18\xf3a{\xcd\xe1J\x8a\x02\x1e\x19\x99\xbb\xd5\u04be\x00\x00\u07d4\x97\xd0\xd9r^;p\xe6u\x841s\x93\x8e\xd3q\xb6,\u007f\xac\x89\t79SM(h\x00\x00\u07d4\x97\xd9\xe4jv\x04\u05f5\xa4\xeaN\xe6\x1aB\xb3\xd25\x0f\xc3\xed\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x97\xdc&\xecg\n1\xe0\"\x1d*u\xbc]\xc9\xf9\f\x1fo\u0509\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94\x97\xde!\xe4!\xc3\u007f\xe4\xb8\x02_\x9aQ\xb7\xb3\x90\xb5\xdfx\x04\x8a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4\x97\xe2\x89s\xb8`\xc5g@(\x00\xfb\xb6<\xe3\x9a\x04\x8a=y\x89\x05B%:\x12l\xe4\x00\x00\u07d4\x97\xe5\xcca'\xc4\xf8\x85\xbe\x02\xf4KB\xd1\u0230\xac\x91\u44c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x97\xf1\xfeL\x80\x83\xe5\x96!*\x18w(\xdd\\\xf8\n1\xbe\u0149\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\x97\xf7v\x06W\xc1\xe2\x02u\x90\x86\x96>\xb4!\x1c_\x819\xb9\x8a\n\x8a\t\u007f\xcb=\x17h\x00\x00\xe0\x94\x97\xf9\x9bk\xa3\x13F\u0358\xa9\xfeL0\x8f\x87\u0165\x8cQQ\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x98\n\x84\xb6\x86\xfc1\xbd\xc8<\"\x10XTjq\xb1\x1f\x83\x8a\x89*AUH\xaf\x86\x81\x80\x00\u07d4\x98\x10\xe3J\x94\xdbn\xd1V\xd08\x9a\x0e+\x80\xf4\xfdk\n\x8a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x98\x1d\xdf\x04\x04\xe4\xd2-\xdaUj\a&\xf0\v-\x98\xab\x95i\x8965f3\xeb\xd8\xea\x00\x00\xe0\x94\x98\x1fq'u\xc0\xda\xd9u\x18\xff\xed\xcbG\xb9\xad\x1dl'b\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\x984h!\x80\xb9\x82\xd1f\xba\u06dd\x9d\x1d\x9b\xbf\x01m\x87\xee\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x986\xb4\xd3\x04sd\x1a\xb5j\xee\xe1\x92Bv\x1drrQx\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x989sB\xec_=L\xb8w\xe5N\xf5\xd6\xf1\xd3fs\x1b\u050a\x01@a\xb9\xd7z^\x98\x00\x00\xe0\x94\x98Fd\x886\xa3\a\xa0W\x18O\xd5\x1fb\x8a_\x8c\x12B|\x8a\x04\vi\xbfC\xdc\xe8\xf0\x00\x00\xe0\x94\x98Jy\x85\xe3\xcc~\xb5\xc96\x91\xf6\xf8\xcc{\x8f$]\x01\xb2\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x98]p\xd2\a\x89+\xed9\x85\x90\x02N$!\xb1\xcc\x11\x93Y\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x98m\xf4~v\xe4\u05e7\x89\xcd\xee\x91<\u0243\x16P\x93l\x9d\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\x98t\x80?\xe1\xf3\xa06^y\"\xb1Bp\xea\xeb\x03,\xc1\xb5\x89<\xf5\x92\x88$\xc6\xc2\x00\x00\u07d4\x98ub4\x95\xa4l\xdb\xf2YS\x0f\xf88\xa1y\x9e\u00c9\x91\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x98v\x18\xc8VV |{\xac\x15\a\xc0\xff\xef\xa2\xfbd\xb0\x92\x89\x03}\xfeC1\x89\xe3\x80\x00\u07d4\x98|\x9b\xcdn?9\x90\xa5+\xe3\xed\xa4q\f'Q\x8fOr\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x98\x82\x96|\xeeh\u04a89\xfa\u062bJ|=\xdd\xf6\xc0\xad\u0209Hx\xbe\x1f\xfa\xf9]\x00\x00\u07d4\x98\x85\\}\xfb\xee3SD\x90J\x12\xc4\fs\x17\x95\xb1:T\x899\xfb\xae\x8d\x04-\xd0\x00\x00\u07d4\x98\x9c\f\xcf\xf6T\xda\x03\xae\xb1\x1a\xf7\x01\x05Ea\xd6)~\x1d\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x98\xa0\xe5Lm\x9d\u023e\x96'l\xeb\xf4\xfe\xc4`\xf6#]\x85\x89j\u0202\x10\tR\u01c0\x00\u07d4\x98\xb7i\xcc0\\\xec\xfbb\x9a\x00\xc9\a\x06\x9d~\xf9\xbc:\x12\x89\x01h\u048e?\x00(\x00\x00\xe0\x94\x98\xbaN\x9c\xa7/\xdd\xc2\fi\xb49ov\xf8\x18?z*N\x8a\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\x00\u07d4\x98\xbeimQ\xe3\x90\xff\x1cP\x1b\x8a\x0fc1\xb6(\xdd\u016d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x98\xbe\u04e7.\xcc\xfb\xaf\xb9#H\x92\x93\xe4)\xe7\x03\xc7\xe2[\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x98\xbfJ\xf3\x81\v\x84#\x87\xdbp\xc1MF\t\x96&\x00=\x10\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x98\xc1\x0e\xbf,O\x97\u02e5\xa1\xab?*\xaf\xe1\xca\xc4#\xf8\u02c9\x10CV\x1a\x88)0\x00\x00\u07d4\x98\xc1\x9d\xba\x81\v\xa6\x11\xe6\x8f/\x83\xee\x16\xf6\xe7tO\f\x1f\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x98\xc5IJ\x03\xac\x91\xa7h\xdf\xfc\x0e\xa1\xdd\u0b3f\x88\x90\x19\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\x98\xd2\x04\xf9\b_\x8c\x8e}\xe2>X\x9bd\xc6\xef\xf6\x92\xccc\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x98\xd3s\x19\x92\xd1\xd4\x0e\x12\x11\xc7\xf75\xf2\x18\x9a\xfa\a\x02\xe0\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x98\xe2\xb6\xd6\x06\xfd-i\x91\xc9\xd6\xd4\a\u007f\xdf?\xddE\x85\u06890\xdf\x1ao\x8a\xd6(\x00\x00\u07d4\x98\xe3\xe9\v(\xfc\xca\ue087y\xb8\xd4\nUh\xc4\x11n!\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\x98\xe6\xf5G\u06c8\xe7_\x1f\x9c\x8a\xc2\xc5\xcf\x16'\xbaX\v>\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x98\xf4\xaf:\xf0\xae\xde_\xaf\xdcB\xa0\x81\xec\xc1\xf8\x9e<\xcf \x8a\x01\xfd\x934\x94\xaa_\xe0\x00\x00\u07d4\x98\xf6\xb8\xe6!=\xbc\x9aU\x81\xf4\xcc\xe6e_\x95%+\xdb\a\x89\x11Xr\xb0\xbc\xa40\x00\x00\u07d4\x99\te\r\u05719{\x8b\x8b\x0e\xb6\x94\x99\xb2\x91\xb0\xad\x12\x13\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x99\x11s`\x19G\xc2\bJb\xd69R~\x96\x15\x12W\x9a\xf9\x89 \x86\xac5\x10R`\x00\x00\u07d4\x99\x12\x9d[<\f\xdeG\xea\r\xefM\xfc\a\r\x1fJY\x95'\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x99\x17\u058dJ\xf3A\xd6Q\xe7\xf0\a\\m\xe6\xd7\x14Nt\t\x8a\x012\xd4Gl\b\xe6\xf0\x00\x00\u07d4\x99\x1a\xc7\xcap\x97\x11_& ^\xee\x0e\xf7\xd4\x1e\xb4\xe3\x11\xae\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794\x99#e\xd7d\xc5\xce5@9\xdd\xfc\x91.\x02:u\xb8\xe1h\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x99&F\xac\x1a\u02ab\xf5\u076b\xa8\xf9B\x9a\xa6\xa9Nt\x96\xa7\x8967Pz0\xab\xeb\x00\x00\u07d4\x99&\x83'\xc3s3.\x06\xc3\xf6\x16B\x87\xd4U\xb9\xd5\xfaK\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99(\xffqZ\xfc:+`\xf8\xebL\u013aN\xe8\u06b6\u5749\x17\xda:\x04\u01f3\xe0\x00\x00\u07d4\x992\xef\x1c\x85\xb7Z\x9b*\x80\x05}P\x874\xc5\x10\x85\xbe\u0309\x02\xb8?\xa50\x1dY\x00\x00\xe0\x94\x99?\x14ax`^f\xd5\x17\xbex.\xf0\xb3\xc6\x1aN\x19%\x8a\x01|\x1f\x055\u05e5\x83\x00\x00\xe0\x94\x99A7\x04\xb1\xa3.p\xf3\xbc\ri\u0748\x1c8VkT\u02ca\x05\xcckiF1\xf7\x12\x00\x00\u07d4\x99AR\xfc\x95\xd5\xc1\u028b\x88\x11:\xbb\xadMq\x0e@\xde\xf6\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x99D\xfe\xe9\xd3JJ\x88\x00#\u01c92\xc0\vY\xd5\xc8*\x82\x89(\xa8\xa5k6\x90\a\x00\x00\u07d4\x99L\u00b5\"~\xc3\xcf\x04\x85\x12F|A\xb7\xb7\xb7H\x90\x9f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99q\xdf`\xf0\xaef\xdc\xe9\xe8\xc8N\x17\x14\x9f\t\xf9\xc5/d\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x99v\x94~\xff_j\xe5\xda\b\xddT\x11\x92\xf3x\xb4(\xff\x94\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x99}e\x92\xa3\x15\x89\xac\xc3\x1b\x99\x01\xfb\xeb<\xc3\xd6[2\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99\x82\xa5\x89\x0f\xfbT\x06\u04ec\xa8\u04bf\xc1\xddp\xaa\xa8\n\xe0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99\x87\x8f\x9dn\n~\u066e\u01c2\x97\xb78y\xa8\x01\x95\xaf\xe0\x89\xd7\xc1\x98q\x0ef\xb0\x00\x00\u07d4\x99\x8c\x1f\x93\xbc\xdbo\xf2<\x10\xd0\u0712G(\xb7;\xe2\xff\x9f\x896[\xf3\xa43\xea\xf3\x00\x00\u07d4\x99\x91aL[\xaaG\xddl\x96\x87FE\xf9z\xdd,=\x83\x80\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x99\x92J\x98\x16\xbb}\xdf?\xec\x18D\x82\x8e\x9a\xd7\xd0k\xf4\xe6\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\x99\x99vh\xf7\xc1\xa4\xff\x9e1\xf9\x97z\xe3\"K\u02c8z\x85\x89\x0f\xc969(\x01\xc0\x00\x00\u07d4\x99\x9cI\xc1t\xca\x13\xbc\x83l\x1e\n\x92\xbf\xf4\x8b'\x15C\u0289\xb1\xcf$\xdd\u0431@\x00\x00\u07d4\x99\xa4\xde\x19\xde\u05d0\b\xcf\xdc\xd4]\x01M.XK\x89\x14\xa8\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\x99\xa9k\xf2$.\xa1\xb3\x9e\xceo\xcc\r\x18\xae\xd0\f\x01y\xf3\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x99\xb0\x18\x93+\xca\xd3U\xb6y+%]\xb6p-\xec\x8c\xe5\u0749\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\x99\xb7C\xd1\xd9\xef\xf9\r\x9a\x194\xb4\xdb!\xd5\x19\u061bJ8\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x99\xb8\xc8$\x86\x9d\xe9\xed$\xf3\xbf\xf6\x85L\xb6\xddE\xcc?\x9f\x89e\xea=\xb7UF`\x00\x00\u07d4\x99\xc0\x17L\xf8N\a\x83\xc2 \xb4\xebj\xe1\x8f\xe7\x03\x85J\u04c9py\xa2W=\fx\x00\x00\u07d4\x99\xc1\xd9\xf4\fj\xb7\xf8\xa9/\xce/\xdc\xe4zT\xa5\x86\xc5?\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\x99\xc26\x14\x1d\xae\xc87\xec\xe0O\xda\xee\x1d\x90\u03cb\xbd\xc1\x04\x89ve\x16\xac\xac\r \x00\x00\u07d4\x99\xc3\x1f\xe7HX7\x87\xcd\xd3\xe5%\xb2\x81\xb2\x18\x96\x179\xe3\x897\b\xba\xed=h\x90\x00\x00\u07d4\x99\xc4u\xbf\x02\xe8\xb9!J\xda_\xad\x02\xfd\xfd\x15\xba6\\\f\x89 \t\xc5\u023fo\xdc\x00\x00\u07d4\x99\u0203%\x85F\xcc~N\x97\x1fR.8\x99\x18\xda^\xa6:\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x99\xc9\xf9>E\xfe<\x14\x18\xc3S\xe4\u016c8\x94\xee\xf8\x12\x1e\x89\x05\x85\xba\xf1E\x05\v\x00\x00\xe0\x94\x99\xd1W\x9c\xd4&\x82\xb7dN\x1dOq(D\x1e\xef\xfe3\x9d\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\x99\u0475\x85\x96_@jB\xa4\x9a\x1c\xa7\x0fv\x9evZ?\x98\x8a\x03\x89O\x0eo\x9b\x9fp\x00\x00\u07d4\x99\xdf\xd0PL\x06\xc7C\xe4e4\xfd{U\xf1\xf9\xc7\xec3)\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99\xf4\x14|\xcck\u02c0\u0304.i\xf6\xd0\x0e0\xfaA3\u0649\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\x99\xf7\u007f\x99\x8b \xe0\xbc\xdc\xd9\xfc\x83\x86ARl\xf2Y\x18\xef\x89a\t=|,m8\x00\x00\u07d4\x99\xfa\xd5\x008\xd0\xd9\xd4\xc3\xfb\xb4\xbc\xe0V\x06\xec\xad\xcdQ!\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x99\xfe\r \x12(\xa7S\x14VU\xd4(\xeb\x9f\xd9I\x85\xd3m\x89i \xbf\xf3QZ:\x00\x00\u07d4\x9a\a\x9c\x92\xa6)\xca\x15\xc8\xca\xfa.\xb2\x8d[\xc1z\xf8(\x11\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x9a\r<\xee=\x98\x92\xea;7\x00\xa2\u007f\xf8A@\xd9\x02T\x93\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\x9a$\u038dH\\\xc4\xc8nI\u07b3\x90\"\xf9,t0\xe6~\x89Fy\x1f\xc8N\a\xd0\x00\x00\u07d4\x9a,\xe4;]\x89\u0593k\x8e\x8c5G\x91\xb8\xaf\xff\x96$%\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9a9\x01bS^9\x88w\xe4\x16x}b9\xe0uN\x93|\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9a=\xa6P#\xa10 \xd2!E\xcf\xc1\x8b\xab\x10\xbd\x19\xceN\x89\x18\xbfn\xa3FJ:\x00\x00\xe0\x94\x9a>+\x1b\xf3F\xdd\a\v\x02sW\xfe\xacD\xa4\xb2\xc9}\xb8\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9aL\xa8\xb8!\x17\x89NC\xdbr\xb9\xfax\xf0\xb9\xb9:\xce\t\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\x9aR.R\xc1\x95\xbf\xb7\xcf_\xfa\xae\u06d1\xa3\xbath\x16\x1d\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9aZ\xf3\x1c~\x063\x9a\u0234b\x8d|M\xb0\xce\x0fE\u0224\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u0794\x9ac?\xcd\x11,\xce\xebv_\xe0A\x81ps*\x97\x05\u7708\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x9ac\u0445\xa7\x91)\xfd\xab\x19\xb5\x8b\xb61\xea6\xa4 TN\x89\x02F\xdd\xf9yvh\x00\x00\u07d4\x9ag\b\u0778\x90<(\x9f\x83\xfe\x88\x9c\x1e\xdc\xd6\x1f\x85D#\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9ao\xf5\xf6\xa7\xaf{z\xe0\xed\x9c \xec\xecP#\u0481\xb7\x86\x89\x8a\x12\xb9\xbdjg\xec\x00\x00\xe0\x94\x9a\x82\x82m<)H\x1d\xcc+\u0495\x00G\xe8\xb6\x04\x86\xc38\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x9a\x8e\xcaA\x89\xffJ\xa8\xff~\u0536\xb7\x03\x9f\t\x02!\x9b\x15\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9a\x95;[\xccp\x93y\xfc\xb5Y\u05f9\x16\xaf\u06a5\f\xad\u0309\x05k\xc7^-c\x10\x00\x00\u07d4\x9a\x99\v\x8a\xebX\x8d~\xe7\xec.\xd8\xc2\xe6Os\x82\xa9\xfe\xe2\x89\x01\xd1'\xdbi\xfd\x8b\x00\x00\u07d4\x9a\x9d\x1d\xc0\xba\xa7}n \xc3\xd8I\u01c8b\xdd\x1c\x05L\x87\x89/\xb4t\t\x8fg\xc0\x00\x00\xe0\x94\x9a\xa4\x8cf\xe4\xfbJ\u0419\x93N2\x02.\x82t'\xf2w\xba\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9a\xa80\x8fB\x91\x0eZ\xde\t\xc1\xa5\xe2\x82\xd6\xd9\x17\x10\xbd\xbf\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9a\xaa\xfa\x00gd~\u0659\x06kzL\xa5\xb4\xb3\xf3\xfe\xaao\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9a\xb9\x88\xb5\x05\xcf\xee\x1d\xbe\x9c\u044e\x9bTs\xb9\xa2\xd4\xf56\x89\x11X\xe4`\x91=\x00\x00\x00\u07d4\x9a\xb9\x8dm\xbb\x1e\xaa\xe1mE\xa0EhT\x1a\xd3\xd8\xfe\x06\u0309\x0e\xc5\x04d\xfe#\xf3\x80\x00\xe0\x94\x9a\xba+^'\xffx\xba\xaa\xb5\xcd\u0248\xb7\xbe\x85\\\xeb\xbd\u038a\x02\x1e\f\x00\x13\a\n\xdc\x00\x00\u07d4\x9a\xc4\xdaQ\xd2x\"\xd1\xe2\b\xc9n\xa6J\x1e[U)\x97#\x89\x05lUy\xf7\"\x14\x00\x00\u0794\x9a\xc8S\x97y*i\u05cf(k\x86C*\a\xae\u03b6\x0ed\x88\xc6s\xce<@\x16\x00\x00\xe0\x94\x9a\xc9\a\xee\x85\xe6\xf3\xe2#E\x99\x92\xe2V\xa4?\xa0\x8f\xa8\xb2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9a\xd4\u007f\xdc\xf9\u0354-(\xef\xfd[\x84\x11[1\xa6X\xa1>\x89\xb2Y\xec\x00\xd5;(\x00\x00\u07d4\x9a\xdb\u04fc{\n\xfc\x05\xd1\xd2\xed\xa4\x9f\xf8c\x93\x9cH\xdbF\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4\x9a\xdfE\x8b\xff5\x99\xee\xe1\xa2c\x98\x85\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\x9a\xf9\xdb\xe4t\"\xd1w\xf9E\xbd\xea\xd7\xe6\xd8)05b0\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x9a\xfaSkLf\xbc8\xd8u\u0133\x00\x99\xd9&\x1f\xdb8\xeb\x89\v*\x8f\x84*w\xbc\x80\x00\u07d4\x9b\x06\xad\x84\x1d\xff\xbeL\xcfF\xf1\x03\x9f\u00c6\xf3\xc3!Dn\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9b\x11h\u078a\xb6KGU/3\x89\x80\n\x9c\xc0\x8bFf\u03c9]\u0212\xaa\x111\xc8\x00\x00\u07d4\x9b\x18\x11\xc3\x05\x1fF\xe6d\xaeK\xc9\xc8$\u0445\x92\xc4WJ\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4\x9b\x18G\x86U\xa4\x85\x1c\xc9\x06\xe6`\xfe\xaca\xf7\xf4\u023f\xfc\x89\xe2G\x8d8\x90}\x84\x00\x00\u07d4\x9b\"\xa8\r\\{3t\xa0[D`\x81\xf9}\n4\a\x9e\u007f\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x9b+\xe7\xf5gT\xf5\x05\xe3D\x1a\x10\xf7\xf0\xe2\x0f\xd3\xdd\xf8I\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\x9b2\xcfOQ\x15\xf4\xb3J\x00\xa6La}\xe0c\x875C#\x89\x05\xb8\x1e\u0608 |\x80\x00\u07d4\x9bC\u0739_\xde1\x80u\xa5g\xf1\xe6\xb5v\x17\x05^\xf9\xe8\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\x9bDO\xd37\xe5\xd7R\x93\xad\xcf\xffp\xe1\xea\x01\xdb\x022\"\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9bH$\xff\x9f\xb2\xab\xdaUM\xeeO\xb8\xcfT\x91eW\x061\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9bL'\x15x\f\xa4\xe9\x9e`\xeb\xf2\x19\xf1Y\f\x8c\xadP\n\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\x9bY\xeb!;\x1eue\xe4PG\xe0N\xa07O\x10v-\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9b\\9\xf7\xe0\xac\x16\x8c\x8e\xd0\xed4\x04w\x11}\x1bh.\xe9\x89\x05P\x05\xf0\xc6\x14H\x00\x00\u07d4\x9b^\xc1\x8e\x83\x13\x88}\xf4a\u0490.\x81\xe6z\x8f\x11;\xb1\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9bd\xd3\u034d+s\xf6hA\xb5\xc4k\xb6\x95\xb8\x8a\x9a\xb7]\x89\x01 :Ov\f\x16\x80\x00\u07d4\x9be\x8f\xb3a\xe0F\xd4\xfc\xaa\x8a\xefm\x02\xa9\x91\x11\"6%\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9bfA\xb1>\x17/\xc0r\xcaK\x83'\xa3\xbc(\xa1[f\xa9\x89\x06\x81U\xa46v\xe0\x00\x00\xe0\x94\x9bh\xf6t\x16\xa6;\xf4E\x1a1\x16L\x92\xf6r\xa6\x87Y\xe9\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4\x9bw6i\xe8}v\x01\x8c\t\x0f\x82U\xe5D\t\xb9\u0728\xb2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9bw\xeb\xce\xd7\xe2\x15\xf0\x92\x0e\x8c+\x87\x00$\xf6\xec\xb2\xff1\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9b|\x88\x10\xcc|\u021e\x80Nm>8\x12\x18PG(w\xfe\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9b\xa5=\xc8\xc9^\x9aG/\xeb\xa2\xc4\xe3,\x1d\xc4\xdd{\xabF\x89Hz\x9a0E9D\x00\x00\xe0\x94\x9b\xac\xd3\xd4\x0f;\x82\xac\x91\xa2d\xd9\u060d\x90\x8e\xac\x86d\xb9\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x9b\xb7`\xd5\u0089\xa3\xe1\xdb\x18\xdb\tSE\xcaA;\x9aC\u0089\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\x9b\xb7b\x04\x18j\xf2\xf6;\xe7\x91h`\x16\x87\xfc\x9b\xadf\x1f\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x9b\xb9\xb0*&\xbf\xe1\xcc\xc3\xf0\xc6!\x9e&\x1c9\u007f\xc5\xcax\x89Hz\x9a0E9D\x00\x00\u07d4\x9b\xc5s\xbc\xda#\xb8\xb2o\x90s\xd9\f#\x0e\x8eq\xe0'\v\x896/u\xa40]\f\x00\x00\u07d4\x9b\xd7\u00caB\x100JMe>\xde\xff\x1b<\xe4_\xcexC\x89\x0fI\x89A\xe6d(\x00\x00\xe0\x94\x9b\u0600h\xe10u\xf3\xa8\xca\xc4d\xa5\xf9I\xd6\xd8\x18\xc0\xf6\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x9b\xd9\x05\xf1q\x9f\u01ec\xd0\x15\x9dM\xc1\xf8\xdb/!G#8\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9b\xdb\u071b\x9741\xd1<\x89\xa3\xf9u~\x9b;bu\xbf\u01c9\x1b\x1a}\u03caD\u04c0\x00\u07d4\x9b\xe3\xc3)\xb6*(\xb8\xb0\x88l\xbd\x8b\x99\xf8\xbc\x93\f\xe3\xe6\x89\x04\t\xe5+H6\x9a\x00\x00\xe0\x94\x9b\xf5\x8e\xfb\xea\a\x84\xeb\x06\x8a\xde\u03e0\xbb!P\x84\xc7:5\x8a\x01:k+VHq\xa0\x00\x00\u07d4\x9b\xf6r\xd9y\xb3fR\xfcR\x82Tzjk\xc2\x12\xaeCh\x89#\x8f\xd4,\\\xf0@\x00\x00\xe0\x94\x9b\xf7\x03\xb4\x1c6$\xe1_@T\x96#\x90\xbc\xba0R\xf0\xfd\x8a\x01H>\x01S<.<\x00\x00\u07d4\x9b\xf7\x1f\u007f\xb57\xacT\xf4\xe5\x14\x94\u007f\xa7\xffg(\xf1m/\x89\x01\u03c4\xa3\n\n\f\x00\x00\u07d4\x9b\xf9\xb3\xb2\xf2<\xf4a\xebY\x1f(4\v\xc7\x19\x93\x1c\x83d\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x9b\xfce\x9c\x9c`\x1e\xa4*k!\xb8\xf1p\x84\xec\x87\xd7\x02\x12\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9b\xff\xf5\r\xb3jxUU\xf0vR\xa1S\xb0\xc4+\x1b\x8bv\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9c\x05\xe9\xd0\xf0u\x8eyS\x03q~1\xda!<\xa1W\u618965\u026d\xc5\u07a0\x00\x00\u07d4\x9c\x1bw\x1f\t\xaf\x88*\xf0d0\x83\xde*\xa7\x9d\xc0\x97\xc4\x0e\x89\x86p\xe9\xece\x98\xc0\x00\x00\u07d4\x9c(\xa2\xc4\b`\x91\xcb]\xa2&\xa6W\xce2H\xe8\xea{o\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\u07d4\x9c/\xd5@\x89\xaff]\xf5\x97\x1ds\xb8\x04a`9dsu\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9c4@\x98\xbaaZ9\x8f\x11\xd0\t\x90[\x17|D\xa7\xb6\x02\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9c=\x06\x92\xce\xee\xf8\n\xa4\x96\\\xee\xd2b\xff\xc7\xf0i\xf2\u0709\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9c@\\\xf6\x97\x95a8\x06^\x11\xc5\xf7U\x9eg$[\u0465\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x9cE *%\xf6\xad\x00\x11\xf1\x15\xa5\xa7\"\x04\xf2\xf2\x19\x88f\x8a\x01\x0f\xcf:b\xb0\x80\x98\x00\x00\xe0\x94\x9cI\xde\xffG\b_\xc0\x97\x04\u02a2\u0728\u0087\xa9\xa17\u068a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\x9cK\xbc\xd5\xf1dJo\aX$\xdd\xfe\x85\xc5q\u05ab\xf6\x9c\x89a\x94\x04\x9f0\xf7 \x00\x00\u07d4\x9cRj\x14\x06\x83\xed\xf1C\x1c\xfa\xa1(\xa95\xe2\xb6\x14\u060b\x89\x06\x04o7\xe5\x94\\\x00\x00\xe0\x94\x9cT\xe4\xedG\x9a\x85h)\u01bbB\u069f\vi*u\xf7(\x8a\x01\x97\xa8\xf6\xddU\x19\x80\x00\x00\xe0\x94\x9cX\x1a`\xb6\x10(\xd94\x16y)\xb2-p\xb3\x13\xc3O\u040a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\x9c\\\xc1\x11\t,\x12!\x16\xf1\xa8_N\xe3\x14\bt\x1a}/\x89\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\u07d4\x9ck\u0264k\x03\xaeT\x04\xf0C\xdf\xcf!\x88>A\x10\xcc3\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x9cx\x96?\xbc&<\t\xbdr\xe4\xf8\xde\xf7J\x94u\xf7\x05\\\x8a\x02\ub3b1\xa1r\u0738\x00\x00\u07d4\x9cx\xfb\xb4\xdfv\x9c\xe2\xc1V\x92\f\xfe\xdf\xda\x03:\x0e%J\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x9c{m\xc5\x19\x0f\xe2\x91)c\xfc\xd5yh>\xc79Q\x16\xb0\x89*\x11)\u0413g \x00\x00\u07d4\x9c\x80\xbc\x18\xe9\xf8\u0516\x8b\x18]\xa8\u01df\xa6\xe1\x1f\xfc>#\x89\r\x02\xabHl\xed\xc0\x00\x00\xe0\x94\x9c\x98\xfd\xf1\xfd\u034b\xa8\xf4\u0170L:\xe8X~\xfd\xf0\xf6\xe6\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\x9c\x99\xa1\u0691\u0552\v\xc1N\f\xb9\x14\xfd\xf6+\x94\u02c3X\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\x9c\x99\xb6&\x06(\x1b\\\xef\xab\xf3aV\xc8\xfeb\x83\x9e\xf5\xf3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x9c\x9a\a\xa8\xe5|1r\xa9\x19\xefdx\x94tI\x0f\r\x9fQ\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9c\x9d\xe4G$\xa4\x05M\xa0\xea\xa6\x05\xab\u0300&hw\x8b\xea\x89\n\xd7\xd5\xca?\xa5\xa2\x00\x00\u07d4\x9c\x9f;\x8a\x81\x1b!\xf3\xff?\xe2\x0f\xe9p\x05\x1c\xe6j\x82O\x89>\xc2\u07bc\a\u053e\x00\x00\xe0\x94\x9c\x9f\x89\xa3\x91\x0fj*\xe8\xa9\x10G\xa1z\xb7\x88\xbd\xde\xc1p\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9c\xa0B\x9f\x87O\x8d\xce\xe2\xe9\xc0b\xa9\x02\n\x84*Xz\xb9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9c\xa4.\u7838\x98\xf6\xa5\xcc`\xb5\xa5\u05f1\xbf\xa3\xc321\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9c\xb2\x8a\xc1\xa2\n\x10o\u007f76\x92\xc5\xceLs\xf172\xa1\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9c\xcd\u0732\xcf\u00b2[\br\x9a\n\x98\xd9\xe6\xf0 .\xa2\xc1\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9c\xe2\u007f$^\x02\xd1\xc3\x12\xc1\xd5\x00x\x8c\x9d\xefv\x90E;\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9c\xe56;\x13\xe8#\x8a\xa4\xdd\x15\xac\u0432\xe8\xaf\xe0\x872G\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\x9c\xf2\x92\x8b\xee\xf0\x9a@\xf9\xbf\xc9S\xbe\x06\xa2Q\x11a\x82\xfb\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x9d\x06\x91\x97\xd1\xdeP\x04Z\x18o^\xc7D\xac@\u8bd1\u0189lk\x93[\x8b\xbd@\x00\x00\u07d4\x9d\x0e}\x92\xfb0XS\u05d8&;\xf1^\x97\xc7+\xf9\xd7\xe0\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9d\x0f4~\x82k}\u03aa\xd2y\x06\n5\xc0\x06\x1e\xcf3K\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9d u\x17B,\xc0\xd6\r\xe7\xc27\tzMO\xce \x94\f\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\x9d%\n\xe4\xf1\x10\xd7\x1c\xaf\u01f0\xad\xb5.\x8d\x9a\xcbfy\xb8\x8a\x02\x15mn\x99r\x13\xc0\x00\x00\xe0\x94\x9d+\xfc6\x10o\x03\x82P\xc0\x18\x01hW\x85\xb1l\x86\xc6\r\x8aPw\xd7]\xf1\xb6u\x80\x00\x00\xe0\x94\x9d0\xcb#{\xc0\x96\xf1p6\xfc\x80\xdd!\xcah\x99,\xa2\u064a\x06n\xe71\x8f\u070f0\x00\x00\u07d4\x9d2\x96.\xa9\x97\x00\xd92(\xe9\xdb\xda\xd2\xcc7\xbb\x99\xf0~\x89\xb4c+\xed\xd4\xde\xd4\x00\x00\u07d4\x9d4\xda\xc2[\xd1X(\xfa\xef\xaa\xf2\x8fq\aS\xb3\x9e\x89\u0709;\x1cV\xfe\xd0-\xf0\x00\x00\u07d4\x9d6\x91e\xfbp\xb8\x1a:v_\x18\x8f\xd6\f\xbe^{\th\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9d@\xe0\x12\xf6\x04%\xa3@\xd8-\x03\xa1\xc7W\xbf\xab\xc7\x06\xfb\x89\t4o:\xdd\u020d\x80\x00\u07d4\x9dAt\xaaj\xf2\x84v\xe2)\xda\xdbF\x18\b\b\xc6u\x05\xc1\x89B\x1a\xfd\xa4.\u0597\x00\x00\u07d4\x9dB\x133\x9a\x01U\x18avL\x87\xa9<\xe8\xf8_\x87\x95\x9a\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9dF\f\x1b7\x9d\xdb\x19\xa8\xc8[LgG\x05\r\xdf\x17\xa8u\x89\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4\x9dG\xba[L\x85\x05\xad\x8d\xa4)4(\va\xa0\xe1\xe8\xb9q\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9dM2\x11w%n\xbd\x9a\xfb\xda0A5\xd5\x17\xc3\xdcV\x93\x89!d\xb7\xa0J\u0220\x00\x00\u07d4\x9dO\xf9\x89\xb7\xbe\u066b\x10\x9d\x10\xc8\xc7\xe5_\x02\xd7g4\xad\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\x9dQ\x15C\xb3\xd9\xdc`\xd4\u007f\t\u051d\x01\xb6\u0118\xd8 x\x8a\x02a\x97\xb9Qo\u00d4\x00\x00\u07d4\x9dn\u03e0:\xf2\xc6\xe1D\xb7\xc4i*\x86\x95\x1e\x90.\x9e\x1f\x89\xa2\xa5\xaa`\xad$?\x00\x00\u07d4\x9dvU\xe9\xf3\xe5\xba]n\x87\xe4\x12\xae\xbe\x9e\xe0\u0512G\ue24e\t1\x1c\x1d\x80\xfa\x00\x00\u07d4\x9dx1\xe84\xc2\v\x1b\xaaiz\xf1\xd8\xe0\xc6!\u016f\xff\x9a\x89\x04\xb0m\xbb\xb4\x0fJ\x00\x00\u07d4\x9dx\xa9u\xb7\xdb^M\x8e(\x84\\\xfb\xe7\xe3\x14\x01\xbe\r\u0649H\xa40k\xa2\u5e5c\x8ahX\u02f5,\f\xf75\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94\x9d\u007f\xdapp\xbf>\xe9\xbb\u0664\x1fU\xca\u0505J\xe6\xc2,\x8a\x02U\u02e3\xc4o\xcf\x12\x00\x00\u07d4\x9d\x81\xae\xa6\x9a\xedj\xd0p\x89\xd6\x14E4\x8c\x17\xf3K\xfc[\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x9d\x91\x1f6\x82\xf3/\xe0y.\x9f\xb6\xff<\xfcG\xf5\x89\xfc\xa5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9d\x91;]3\x9c\x95\xd8wEV%c\xfe\xa9\x8b#\xc6\f\u0109\tA0,\u007fM#\x00\x00\u07d4\x9d\x93\xfa\xb6\xe2(E\xf8\xf4Z\aIo\x11\xdeqS\r\xeb\u01c9lO\xd1\xee$nx\x00\x00\u07d4\x9d\x99\xb1\x89\xbb\u0664\x8f\xc2\xe1n\x8f\u0363;\xb9\x9a1{\xbb\x89=\x16\xe1\vm\x8b\xb2\x00\x00\u07d4\x9d\x9cN\xfe\x9fC9\x89\xe2;\xe9@I!S)\xfaU\xb4\u02c9\r\u3c89\x03\u01b5\x80\x00\u07d4\x9d\x9eW\xfd\xe3\x0ePh\xc0>I\x84\x8e\xdc\xe3C\xb7\x02\x83X\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\x9d\xa30\"@\xaf\x05\x11\xc6\xfd\x18W\xe6\u07779Ow\xabk\x89\xa8\r$g~\xfe\xf0\x00\x00\u07d4\x9d\xa4\xec@pw\xf4\xb9p{-\x9d.\xde^\xa5(+\xf1\u07c9\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9d\xa6\t\xfa:~l\xf2\xcc\x0ep\u036b\xe7\x8d\xc4\xe3\x82\xe1\x1e\x89A\rXj \xa4\xc0\x00\x00\xe0\x94\x9d\xa6\x1c\xcdb\xbf\x86\x06V\xe02]qW\xe2\xf1`\xd9;\xb5\x8a\x01\x0f\f\xa9V\xf8y\x9e\x00\x00\xe0\x94\x9d\xa6\xe0u\x98\x9ct\x19\tL\xc9\xf6\xd2\u44d3\xbb\x19\x96\x88\x8a\x02Y\xbbq\u056d\xf3\xf0\x00\x00\u07d4\x9d\xa8\xe2,\xa1\x0eg\xfe\xa4NR^GQ\xee\xac6\xa3\x11\x94\x89\x0e\x189\x8ev\x01\x90\x00\x00\u07d4\x9d\xb2\xe1\\\xa6\x81\xf4\xc6`H\xf6\xf9\xb7\x94\x1e\u040b\x1f\xf5\x06\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9d\xc1\x0f\xa3\x8f\x9f\xb0h\x10\xe1\x1f`\x17>\xc3\xd2\xfdju\x1e\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\x9d\xd2\x19f$\xa1\xdd\xf1J\x9d7^_\a\x15+\xaf\"\xaf\xa2\x89A\xb0^$c\xa5C\x80\x00\u07d4\x9d\xd4k\x1cm?\x05\u279co\x03~\xed\x9aYZ\xf4\xa9\xaa\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x9d\xdd5^cN\xe9\x92~K\u007fl\x97\xe7\xbf:/\x1ehz\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\x9d\xe2\n\xe7j\xa0\x82c\xb2\x05\xd5\x14$a\x96\x1e$\b\xd2f\x89\r\xa93\xd8\xd8\xc6p\x00\x00\u07d4\x9d\xe2\v\xc3~\u007fH\xa8\x0f\xfdz\xd8O\xfb\xf1\xa1\xab\xe1s\x8c\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9d\xe78m\xde@\x1c\xe4\xc6{q\xb6U?\x8a\xa3N\xa5\xa1}\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\x9d\xeb9\x02z\xf8w\x99+\x89\xf2\xecJ\x1f\x82.\xcd\xf1&\x93\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x9d\xef\xe5j\x0f\xf1\xa1\x94}\xba\t#\xf7\xdd%\x8d\x8f\x12\xfaE\x8a\x05\xb1*\ufbe8\x04\x00\x00\x00\u07d4\x9d\xf0W\xcd\x03\xa4\xe2~\x8e\x03/\x85y\x85\xfd\u007f\x01\xad\xc8\u05c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x9d\xf3*P\x1c\vx\x1c\x02\x81\x02/B\xa1)?\xfd{\x89*\x8a\x01\xe7\xe4\x17\x1b\xf4\u04e0\x00\x00\u07d4\x9e\x01vZ\xff\b\xbc\"\x05P\xac\xa5\xea.\x1c\xe8\u5c19#\x8965\u026d\xc5\u07a0\x00\x00\u07d4\x9e \xe5\xfd6\x1e\xab\xcfc\x89\x1f[\x87\xb0\x92h\xb8\xeb7\x93\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9e#,\b\xc1M\xc1\xa6\xed\v\x8a;(h\x97{\xa5\xc1}\x10\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9e#\xc5\u4dc2\xb0\n_\xad\U0006eb47\xda\xcf[\x03g\xa1\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9e59\x90q\xa4\xa1\x01\xe9\x19M\xaa?\t\xf0J\v_\x98p\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9e>\xb5\t'\x8f\xe0\xdc\xd8\xe0\xbb\xe7\x8a\x19N\x06\xb6\x809C\x892\xf5\x1e\u06ea\xa30\x00\x00\u07d4\x9eBrrQk>g\xd4\xfc\xbf\x82\xf5\x93\x90\xd0L\x8e(\xe5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\x9eL\xec5:\xc3\u3043^<\t\x91\xf8\xfa\xa5\xb7\u0428\xe6\x8a\x02\x1e\x18\xb9\xe9\xabE\xe4\x80\x00\u07d4\x9eX\x11\xb4\v\xe1\xe2\xa1\xe1\u048c;\at\xac\xde\n\t`=\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\x9eZ1\x1d\x9fi\x89\x8a|j\x9dc`h\x048\xe6z{/\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4\x9e| P\xa2'\xbb\xfd`\x93~&\x8c\xea>h\xfe\xa8\xd1\xfe\x89\x05k\xc7^-c\x10\x00\x00\u07d4\x9e\u007fe\xa9\x0e\x85\b\x86{\xcc\xc9\x14%j\x1e\xa5t\xcf\a\xe3\x89C8t\xf62\xcc`\x00\x00\xe0\x94\x9e\x81D\xe0\x8e\x89dx\x11\xfekr\xd4E\u05a5\xf8\n\xd2D\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9e\x8fd\xdd\xcd\u9e34Q\xba\xfa\xa25\xa9\xbfQ\x1a%\xac\x91\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\x9e\x95\x1fm\xc5\xe3R\xaf\xb8\xd0B\x99\xd2G\x8aE\x12Y\xbfV\x89\x03\xe7A\x98\x81\xa7:\x00\x00\u07d4\x9e\x96\r\xcd\x03\u057a\x99\xcb\x11]\x17\xffL\t$\x8a\xd4\u043e\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9e\xafj2\x8a@v\x02N\xfakg\xb4\x8b!\xee\xdc\xc0\xf0\xb8\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\x9e\xb1\xffqy\x8f(\xd6\xe9\x89\xfa\x1e\xa0X\x8e'\xba\x86\xcb}\x89\a\xa1\xfe\x16\x02w\x00\x00\x00\u07d4\x9e\xb2\x81\xc3'\x19\xc4\x0f\xdb>!m\xb0\xf3\u007f\xbcs\xa0&\xb7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\x9e\xb3\xa7\xcb^g&Bz:6\x1c\xfa\x8dad\xdb\u043a\x16\x89+\x95\xbd\xcc9\xb6\x10\x00\x00\u07d4\x9e\xb7\x83N\x17\x1dA\xe0i\xa7yG\xfc\xa8v\"\xf0\xbaNH\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\x9e\xc0>\x02\u51f7v\x9d\xefS\x84\x13\xe9\u007f~U\xbeq\u060a\x04+\xf0kx\xed;P\x00\x00\u07d4\x9e\u02eb\xb0\xb2'\x82\xb3uD)\xe1uz\xab\xa0K\x81\x18\x9f\x89,\xa7\xbb\x06\x1f^\x99\x80\x00\u07d4\x9e\xce\x14\x00\x80\t6\xc7\xc6H_\xcd\xd3b`\x17\u041a\xfb\xf6\x89\x10\xce\x1d=\x8c\xb3\x18\x00\x00\u07d4\x9e\xd4\xe6?ReB\xd4O\xdd\xd3MY\xcd%8\x8f\xfdk\u0689\u049b4\xa4cH\x94\x00\x00\u07d4\x9e\xd8\x0e\xda\u007fU\x05M\xb9\xfbR\x82E\x16\x88\xf2k\xb3t\xc1\x89\x10CV\x1a\x88)0\x00\x00\u07d4\x9e\u0710\xf4\xbe!\be!J\xb5\xb3^Z\x8d\xd7t\x15'\x9d\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9e\u07acL\x02k\x93\x05M\u0171\xd6a\fo9`\xf2\xads\x89A\rXj \xa4\xc0\x00\x00\u07d4\x9e\xe9?3\x9eg&\xece\xee\xa4O\x8aK\xfe\x10\xda=2\x82\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\x9e\xe9v\f\xc2s\xd4pj\xa0\x83u\xc3\xe4o\xa20\xaf\xf3\u054a\x01\xe5.3l\xde\"\x18\x00\x00\u07d4\x9e\xeb\a\xbd+x\x90\x19^}F\xbd\xf2\a\x1bf\x17QM\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\x9e\xefD-)\x1aD}t\xc5\xd2S\u011e\xf3$\xea\xc1\xd8\xf0\x89\xb9f\b\xc8\x10;\xf0\x00\x00\u07d4\x9e\xf1\x89k\x00|2\xa1Q\x14\xfb\x89\xd7=\xbdG\xf9\x12+i\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9f\x01w\x06\xb80\xfb\x9c0\ufc20\x9fPk\x91WEu4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9f\x10\xf2\xa0F;e\xae0\xb0p\xb3\xdf\x18\xcfF\xf5\x1e\x89\xbd\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\x9f\x19\xfa\u0223$7\xd8\n\u0183z\v\xb7\x84\x17)\xf4\x97.\x89#=\xf3)\x9far\x00\x00\u07d4\x9f\x1a\xa8\xfc\xfc\x89\xa1\xa52\x8c\xbdcD\xb7\x1f'\x8a,\xa4\xa0\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\x9f!0,\xa5\tk\xeat\x02\xb9\x1b\x0f\xd5\x06%O\x99\x9a=\x89C\x97E\x1a\x00=\xd8\x00\x00\u07d4\x9f'\x1d(U\x00\xd78F\xb1\x8fs>%\u074bO]J\x8b\x89'#\xc3F\xae\x18\b\x00\x00\u07d4\x9f4\x97\xf5\xef_\xe60\x95\x83l\x00N\xb9\xce\x02\xe9\x01;K\x89\"V\x86\x1b\xf9\xcf\b\x00\x00\xe0\x94\x9f:t\xfd^~\xdc\xc1\x16)\x93\x17\x13\x81\u02f62\xb7\xcf\xf0\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\x9fF\xe7\xc1\xe9\a\x8c\xae\x860Z\xc7\x06\v\x01F}f\x85\xee\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\x9fIl\xb2\x06\x95c\x14M\b\x11g{\xa0\xe4q:\nAC\x89<\xd2\xe0\xbfc\xa4H\x00\x00\u07d4\x9fJq\x95\xac|\x15\x1c\xa2X\xca\xfd\xa0\u02b0\x83\xe0I\xc6\x02\x89SS\x8c2\x18\\\xee\x00\x00\u07d4\x9fJ\xc9\xc9\xe7\xe2L\xb2DJ\x04T\xfa[\x9a\xd9\xd9-8S\x89-C\xf3\xeb\xfa\xfb,\x00\x00\u07d4\x9f_D\x02kWjJ\xdbA\xe9YaV\x1dA\x03\x9c\xa3\x91\x89\r\x8drkqw\xa8\x00\x00\u07d4\x9f`{?\x12F\x9fDa!\u03bf4u5kq\xb42\x8c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\x9fa\xbe\xb4o^\x85=\n\x85!\xc7Dnh\xe3L}\ts\x89\x1e[\x8f\xa8\xfe*\xc0\x00\x00\u07d4\x9fd\xa8\xe8\xda\xcfJ\xde0\xd1\x0fMY\xb0\xa3\u056b\xfd\xbft\x8966\x9e\xd7t}&\x00\x00\u07d4\x9ff.\x95'A!\xf1wVncm#\x96L\xf1\xfdho\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9fj2*mF\x99\x81Bj\xe8D\x86]~\xe0\xbb\x15\u01f3\x89\x02\xb5\xeeW\x92\x9f\u06c0\x00\u07d4\x9fy\x86\x92J\xeb\x02h|\xd6A\x89\x18\x9f\xb1g\xde\xd2\xdd\\\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\x9fz\x03\x92\xf8Ws.0\x04\xa3u\xe6\xb1\x06\x8dI\xd801\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9f\x82E\u00eb}\x171d\x86\x1c\u04d9\x1b\x94\xf1\xba@\xa9:\x89\x9b\ny\x1f\x12\x110\x00\x00\u07d4\x9f\x83\xa2\x93\xc3$\xd4\x10l\x18\xfa\xa8\x88\x8fd\u0499\x05L\xa0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\x9f\x86\xa0f\xed\xb6\x1f\xcbXV\u0793\xb7\\\x8cy\x18d\xb9{\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\x9f\x98\xeb4\xd4iy\xb0\xa6\u078b\x05\xaaS:\x89\xb8%\xdc\xf1\x89\x04\xb0m\xbb\xb4\x0fJ\x00\x00\xe0\x94\x9f\x9f\xe0\xc9_\x10\xfe\xe8z\xf1\xaf r6\xc8\xf3aN\xf0/\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\x9f\xae\xa1\xc5\xe8\x1ez\xcb?\x17\xf1\xc3Q\xee.\u0649\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa0\b\x01\x98c\xc1\xa7|\x14\x99\xeb9\xbb\u05ff-\u05e3\x1c\xb9\x89\amA\xc6$\x94\x84\x00\x00\u07d4\xa0\t\xbf\ao\x1b\xa3\xfaW\u04a7!r\x18\xbe\xd5VZzz\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa0\x1e\x94v\u07c4C\x18%\xc86\xe8\x80:\x97\xe2/\xa5\xa0\u034a\x01EB\xba\x12\xa37\xc0\x00\x00\u0794\xa0\x1f\x12\xd7\x0fD\xaa{\x11;(\\\"\xdc\xdbE\x874T\xa7\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xa0\x1f\u0450j\x90\x85\x06\xde\xda\xe1\xe2\b\x12\x88r\xb5n\u7489\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xa0\"\x82@\xf9\x9e\x1d\xe9\xcb2\xd8,\x0f/\xa9\xa3\xd4K\v\xf3\x89V\xbcu\xe2\xd61\x00\x00\x00\xe0\x94\xa0+\xdedahn\x19\xace\f\x97\r\x06r\xe7m\xcbO\u008a\x01\xe0\x92\x96\xc37\x8d\xe4\x00\x00\u07d4\xa0,\x1e4\x06O\x04u\xf7\xfa\x83\x1c\xcb%\x01L:\xa3\x1c\xa2\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\xa0-\u01aa2\x8b\x88\r\u97acTh#\xfc\xcfw@G\xfb\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xa0.?\x8fYY\xa7\xaa\xb7A\x86\x12\x12\x9bp\x1c\xa1\xb8\x00\x10\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa04\u007f\n\x98wc\x90\x16\\\x16m2\x96;\xf7M\xcd\n/\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa05\xa3e$x\xf8-\xbdm\x11_\xaa\x8c\xa9F\xec\x9eh\x1d\x89\x05\xf4\xe4-\u052f\xec\x00\x00\u07d4\xa0:=\xc7\xc53\xd1tB\x95\xbe\x95]a\xaf?R\xb5\x1a\xf5\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xa0E\x9e\xf3i:\xac\xd1d|\xd5\u0612\x989 L\xefS\xbe\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa0O*\xe0*\xdd\x14\xc1/\xafe\xcb%\x90\"\u0403\n\x8e&\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xa0l\xd1\xf3\x969l\ndFFQ\xd7\xc2\x05\xef\xaf8|\xa3\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xa0ri\x1c\x8d\xd7\xcdB7\xffr\xa7\\\x1a\x95\x06\xd0\xce[\x9e\x89\x14\x0e\xc8\x0f\xa7\xee\x88\x00\x00\u07d4\xa0r\u03beb\xa9\xe9\xf6\x1c\xc3\xfb\xf8\x8a\x9e\xfb\xfe>\x9a\x8dp\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xa0v\x82\x00\v\x1b\xcf0\x02\xf8\\\x80\xc0\xfa)I\xbd\x1e\x82\xfd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa0z\xa1mt\xae\u8a63(\x8dR\xdb\x15Q\u0553\x882\x97\x89 \x86\xac5\x10R`\x00\x00\u07d4\xa0\x8d![[j\xacHa\xa2\x81\xac~@\vx\xfe\xf0L\xbf\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa0\x95\x19p\xdf\u0403/\xb8;\xda\x12\xc25E\xe7\x90Aul\x89 \x86\xac5\x10R`\x00\x00\u07d4\xa0\x9fM^\xaae\xa2\xf4\xcbu\nI\x924\x01\xda\u5410\xaf\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\xe0\x94\xa0\xa0\xe6R\x04T\x1f\u029b/\xb2\x82\u0355\x13\x8f\xae\x16\xf8\t\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa0\xaa_\x02\x01\xf0M;\xbe\xb8\x98\x13/|\x11g\x94f\xd9\x01\x89\x01\xfb\xedR\x15\xbbL\x00\x00\u07d4\xa0\xaa\xdb\xd9P\x97\"p_m#X\xa5\u01df7\x97\x0f\x00\xf6\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa0\xb7q\x95\x1c\xe1\xde\xee6:\xe2\xb7q\xb7>\a\u0135\xe8\x00\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xa0\xde\\`\x1eif5\u0198\xb7\xae\x9c\xa4S\x9f\u01f9A\xec\x89\x12\xc3\xcb\xd7\x04\xc9w\x00\x00\u07d4\xa0\xe8\xbaf\x1bH\x15L\xf8C\xd4\u00a5\xc0\xf7\x92\xd5(\xee)\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xa0\xfc~S\xc5\xeb\xd2z*\xbd\xacE&\x1f\x84\xab;Q\xae\xfb\x89\xa3\x13\xda\xec\x9b\xc0\xd9\x00\x00\xe0\x94\xa0\xff[L\xf0\x16\x02~\x83#I}D(\xd3\xe5\xa8;\x87\x95\x8a\x01e\x98\xd3\xc8>\xc0B\x00\x00\u07d4\xa1\x06F[\xbd\x19\u1dbc\xe5\r\x1b\x11W\xdcY\tZ60\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xa1\x06\xe6\x92>\xddS\u028e\xd6P\x96\x8a\x91\b\xd6\xcc\xfd\x96p\x8a\x02\x02\xfe\x15\x05\xaf\uc240\x00\u07d4\xa1\t\u12f0\xa3\x9c\x9e\xf8/\xa1\x95\x97\xfc^\xd8\xe9\xebmX\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4\xa1\x1a\x03\u013b&\xd2\x1e\xffg}]U\\\x80\xb2TS\xeez\x89\x03\xcb'Y\xbcA\x0f\x80\x00\u07d4\xa1\x1e\xff\xabl\xf0\xf5\x97,\xff\xe4\xd5e\x96\xe9\x89h\x14J\x8f\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4\xa1 M\xad_V\a(\xa3\\\r\x8f\u01d4\x81\x05{\xf7s\x86\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa1&#\xe6)\u07d3\tg\x04\xb1`\x84\xbe,\u061dV-\xa4\x8a\x01\xcc\xc92E\x11\xe4P\x00\x00\xe0\x94\xa1*l-\x98]\xaf\x0eO_ z\xe8Q\xaa\xf7)\xb32\u034a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\xa13m\xfb\x96\xb6\xbc\xbeK>\xdf2\x05\xbeW#\xc9\x0f\xadR\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xa1;\x9d\x82\xa9\x9b<\x9b\xbaZ\xe7.\xf2\x19\x9e\xdc};\xb3l\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\xa1<\xfe\x82mm\x18A\u072eD;\xe8\u00c7Q\x816\xb5\xe8\x8a\x1d\xa5jK\b5\xbf\x80\x00\x00\xe0\x94\xa1C.\xd2\u01b7wz\x88\xe8\xd4m8\x8epG\u007f \x8c\xa5\x8a\x01\xb1\xa7\xe4\x13\xa1\x96\xc5\x00\x00\u07d4\xa1D\xf6\xb6\x0fr\xd6J!\xe30\xda\xdbb\u0619\n\xde+\t\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa1P%\xf5\x95\xac\xdb\xf3\x11\x0fw\u017f$G~eH\xf9\xe8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1X\x14\x8a.\x0f>\x92\xdc,\xe3\x8f\xeb\xc2\x01\a\xe3%<\x96\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1a`\x85\x1d+\x9c4\x9b\x92\xe4o\x82\x9a\xbf\xb2\x10\x945\x95\x89a\t=|,m8\x00\x00\u07d4\xa1f\xf9\x11\xc6D\xac2\x13\u049e\x0e\x1a\xe0\x10\xf7\x94\u056d&\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1m\x9e=c\x98aY\xa8\x00\xb4h7\xf4^\x8b\xb9\x80\xee\v\x89n\x11u\xdaz\xd1 \x00\x00\u07d4\xa1pp\xc2\xe9\u0169@\xa4\xec\x0eIT\xc4\xd7\xd6C\xbe\x8fI\x89lk\x17\x03;6\x1c\x80\x00\u07d4\xa1|\x9eC#\x06\x95\x18\x18\x9dR\a\xa0r\x8d\u02d20j?\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa1\x83`\xe9\x85\xf2\x06.\x8f\x8e\xfe\x02\xad,\xbc\x91\xad\x9aZ\xad\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xa1\x91\x14\x05\xcfn\x99\x9e\xd0\x11\xf0\xdd\xcd*O\xf7\u008f%&\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xa1\x92i\x80\a\xcc\x11\xaa`=\"\x1d_\xee\xa0v\xbc\xf7\xc3\r\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1\x92\xf0j\xb0R\xd5\xfd\u007f\x94\xee\xa81\x8e\x82x\x15\xfegz\x89\a\x1f\x8a\x93\xd0\x1eT\x00\x00\u07d4\xa1\x99\x81D\x96\x8a\\p\xa6AUT\xce\xfe\u0082F\x90\u0125\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa1\xa1\xf0\xfam \xb5\nyO\x02\xefR\b\\\x9d\x03j\xa6\u028965\u026d\xc5\u07a0\x00\x00\u07d4\xa1\xae\x8dE@\xd4\xdbo\xdd\xe7\x14oA[C\x1e\xb5\\y\x83\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xa1\xb4|M\x0e\xd6\x01\x88B\xe6\xcf\xc8c\n\u00e3\x14.^k\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xa1\xc4\xf4Z\x82\xe1\xc4x\xd8E\b.\xb1\x88u\xc4\xeae9\xab\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xa1\xdc\xd0\xe5\xb0Z\x97|\x96#\xe5\xae/Y\xb9\xad\xa2\xf3>1\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xa1\xe48\n;\x1ft\x96s\xe2p\"\x99\x93\xeeU\xf3Vc\xb4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1\xf1\x93\xa0Y/\x1f\xeb\x9f\xdf\xc9\n\xa8\x13xN\xb8\x04q\u0249K\xe4\xe7&{j\xe0\x00\x00\u07d4\xa1\xf2\x85@P\xf8re\x8e\xd8.R\xb0\xad{\xbc\x1c\xb9!\xf6\x89m\x03\x17\xe2\xb3&\xf7\x00\x00\u07d4\xa1\xf5\xb8@\x14\rZ\x9a\xce\xf4\x02\xac<\u00c8jh\xca\xd2H\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa1\xf7e\xc4O\xe4_y\x06w\x94HD\xbeO-B\x16_\xbd\x89\xc7\xe9\xcf\xdev\x8e\xc7\x00\x00\u07d4\xa1\xf7\xdd\xe1\xd78\xd8\xcdg\x9e\xa1\xee\x96[\xee\"K\xe7\xd0M\x89=\x18DP\xe5\xe9<\x00\x00\u07d4\xa1\xf8\u063c\xf9\x0ew\u007f\x19\xb3\xa6Iu\x9a\xd9P'\xab\xdf\u00c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa2\x02TrB\x80onp\xe7@X\xd6\xe5)-\xef\xc8\xc8\u0509l\x87T\xc8\xf3\f\b\x00\x00\u07d4\xa2\r\a\x1b\x1b\x000cI}y\x90\xe1$\x9d\xab\xf3l5\xf7\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa2\r\x8f\xf6\f\xaa\xe3\x1d\x02\xe0\xb6e\xfaC]v\xf7|\x94B\x89\x1a\x8a\x90\x9d\xfc\xef@\x00\x00\u07d4\xa2\x11\xda\x03\xcc\x0e1\xec\xceS\t\x99\x87\x18QU(\xa0\x90\u07c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa2\x14B\xab\x054\n\xdeh\xc9\x15\xf3\xc39\x9b\x99U\xf3\xf7\xeb\x89*\x03I\x19\u07ff\xbc\x00\x00\u07d4\xa2\"\"Y\u075c>=\xed\x12p\x84\xf8\b\xe9*\x18\x870,\x89\b\xc83\x9d\xaf\xedH\x00\x00\u07d4\xa2*\xde\r\xdb\\n\xf8\xd0\u034d\xe9M\x82\xb1\x10\x82\xcb.\x91\x897KW\xf3\xce\xf2p\x00\x00\u07d4\xa2L:\xb6!\x81\xe9\xa1[x\xc4b\x1eL|X\x81'\xbe&\x89\b\xcd\xe4:\x83\xd31\x00\x00\u07d4\xa2W\xadYK\u0603(\xa7\xd9\x0f\xc0\xa9\a\u07d5\xee\xca\xe3\x16\x89\x1c7\x86\xff8F\x93\x00\x00\u07d4\xa2[\bd7\xfd!\x92\u0420\xf6On\xd0D\xf3\x8e\xf3\xda2\x89\x12)\x0f\x15\x18\v\xdc\x00\x00\u07d4\xa2v\xb0X\u02d8\u060b\xee\xdbg\xe5CPl\x9a\r\x94p\u0609\x90\xaa\xfcv\xe0/\xbe\x00\x00\u07d4\xa2\x82\xe9i\xca\xc9\xf7\xa0\xe1\xc0\u0350\xf5\xd0\xc48\xacW\r\xa3\x89\"\a\xeb\x89\xfc'8\x00\x00\xe0\x94\xa2\x91\xe9\u01d9\rU-\u046e\x16\u03bc?\xca4,\xba\xf1\u044a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xa2\x93\x19\xe8\x10i\xe5\xd6\r\xf0\x0f=\xe5\xad\xee5\x05\xec\xd5\xfb\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xa2\x96\x8f\xc1\xc6K\xac\vz\xe0\u058b\xa9I\x87Mm\xb2S\xf4\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xa2\x9d[\xdat\xe0\x03GHr\xbdX\x94\xb8\x853\xffd\u00b5\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa2\x9df\x1acv\xf6m\vt\xe2\xfe\x9d\x8f&\xc0$~\xc8L\x89\xdf3\x04\a\x9c\x13\xd2\x00\x00\u07d4\xa2\xa45\xdeD\xa0\x1b\xd0\ucc9eD\xe4vD\xe4j\f\xdf\xfb\x89\x1b\x1dDZz\xff\xe7\x80\x00\u07d4\xa2\xac\xe4\u0253\xbb\x1eS\x83\xf8\xact\xe1y\x06n\x81O\x05\x91\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xa2\xb7\x01\xf9\xf5\xcd\u041eK\xa6+\xae\xba\u3a02W\x10X\x85\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa2\u0145O\xf1Y\x9f\x98\x89,W%\xd2b\xbe\x1d\xa9\x8a\xad\xac\x89\x11\t\xff30\x10\xe7\x80\x00\u07d4\xa2\xc7\xea\xff\xdc,\x9d\x93sE l\x90\x9aR\u07f1LG\x8f\x89\a\xc0\x86\x0eZ\x80\xdc\x00\x00\u07d4\xa2\u04aabk\t\xd6\xd4\xe4\xb1?\u007f\xfcZ\x88\xbdz\xd3gB\x89\xfb\x80xPuS\x83\x00\x00\u07d4\xa2\u04cd\xe1\xc79\x06\xf6\xa7\xcan\xfe\xb9|\xf6\xf6\x9c\xc4!\xbe\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa2\xdce\xee%kY\xa5\xbdy)wO\x90K5\x8d\U000ed84a\x04\x83\xbc\xe2\x8b\xeb\t\xf8\x00\x00\u07d4\xa2\xe0h:\x80]\xe6\xa0^\xdb/\xfb\xb5\xe9o\x05p\xb67\u00c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa2\u1e2a\x90\x0e\x9c\x13\x9b?\xa1\"5OaV\xd9*\x18\xb1\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xa2\u2d54\x1e\f\x01\x94K\xfe\x1d_\xb4\xe8\xa3K\x92,\u03f1\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa2\xe4`\xa9\x89\xcb\x15V_\x9e\u0327\xd1!\xa1\x8eN\xb4\x05\xb6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa2\xec\xce,I\xf7*\t\x95\xa0\xbd\xa5z\xac\xf1\xe9\xf0\x01\xe2*\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xa2\xf4r\xfeO\"\xb7}\xb4\x89!\x9e\xa4\x02=\x11X*\x93)\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xa2\xf7\x98\xe0w\xb0}\x86\x12N\x14\a\xdf2\x89\r\xbbKcy\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa2\xf8k\xc0a\x88N\x9e\xef\x05d\x0e\xddQ\xa2\xf7\xc0Yli\x89llD\xfeG\xec\x05\x00\x00\u07d4\xa2\xfa\x17\xc0\xfbPl\xe4\x94\x00\x8b\x95W\x84\x1c?d\x1b\x8c\xae\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa3\x04X\x8f\r\x85\f\xd8\u04cfv\xe9\xe8<\x1b\xf6>3>\u0789\x02(V\x01!l\x8c\x00\x00\u07d4\xa3\x05\x8cQszN\x96\xc5_.\xf6\xbd{\xb3X\x16~\u00a7\x89 \xdb:\xe4H\x1a\u0500\x00\u07d4\xa3\t\xdfT\u02bc\xe7\f\x95\xec03\x14\x9c\xd6g\x8ao\xd4\u03c9\f\x1f\x12\xc7Q\x01X\x00\x00\u07d4\xa3\nER\x0eR\x06\xd9\x00@p\xe6\xaf>{\xb2\xe8\xddS\x13\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xa3\x0e\n\xcbSL\x9b0\x84\xe8P\x1d\xa0\x90\xb4\xeb\x16\xa2\xc0\u0349lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3 0\x95\xed\xb7\x02\x8ehq\xce\n\x84\xf5HE\x9f\x830\n\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa3!\t\x1d0\x18\x06By\xdb9\x9d+*\x88\xa6\xf4@\xae$\x89\xadx\xeb\u016cb\x00\x00\x00\u07d4\xa3#-\x06\x8dP\x06I\x03\xc9\xeb\xc5c\xb5\x15\xac\u0237\xb0\x97\x89l\x87T\xc8\xf3\f\b\x00\x00\xe0\x94\xa3$\x1d\x89\n\x92\xba\xf5)\b\xdcJ\xa0Irk\xe4&\xeb\u04ca\x04<-\xa6a\xca/T\x00\x00\u07d4\xa3)F&\xec)\x84\xc4;C\xdaM]\x8eFi\xb1\x1dKY\x896\xa4\xcfcc\x19\xc0\x00\x00\u07d4\xa3,\xf7\xdd\xe2\f=\xd5g\x9f\xf5\xe3%\x84\\p\u0156&b\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa39\xa3\xd8\xca(\x0e'\xd2A[&\xd1\xfcy2(\xb6`C\x896\U00086577\x8f\xf0\x00\x00\u07d4\xa3<\xb4P\xf9[\xb4n%\xaf\xb5\x0f\xe0_\xee\xe6\xfb\x8c\xc8\xea\x89*\x11)\u0413g \x00\x00\u07d4\xa3?p\xdaru\xef\x05q\x04\u07e7\xdbd\xf4r\xe9\xf5\xd5S\x89\x04YF\xb0\xf9\xe9\xd6\x00\x00\u07d4\xa3@v\xf8K\xd9\x17\xf2\x0f\x83B\u024b\xa7\x9eo\xb0\x8e\xcd1\x89\u3bb5sr@\xa0\x00\x00\u07d4\xa3C\x0e\x1fd\u007f2\x1e\xd3G9V##\xc7\xd6#A\vV\x8964\xfb\x9f\x14\x89\xa7\x00\x00\u07d4\xa3O\x9dV\x8b\xf7\xaf\xd9L*[\x8a_\xf5\\f\xc4\by\x99\x89\x84}P;\"\x0e\xb0\x00\x00\u07d4\xa3V\x06\xd5\x12 \xee\u007f!F\xd4\x11X.\xe4\xeeJEYn\x89\u062a\xbe\b\v\xc9@\x00\x00\u07d4\xa3VU\x1b\xb7}OE\xa6\xd7\xe0\x9f\n\b\x9ey\u0322I\u02c9\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\xa3\\\x19\x13,\xac\x195Wj\xbf\xedl\x04\x95\xfb\a\x88\x1b\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3e\x91\x8b\xfe?&'\xb9\xf3\xa8gu\xd8un\x0f\u0629K\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xa3n\r\x94\xb9Sd\xa8&q\xb6\b\xcb-72Ea)\t\x89\b!\xd2!\xb5)\x1f\x80\x00\u07d4\xa3u\xb4\xbc$\xa2N\x1fyu\x93\xcc0+/3\x10c\xfa\\\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa3v\"\xac\x9b\xbd\xc4\xd8+u\x01]t[\x9f\x8d\xe6Z(\uc25d\xc0\\\xce(\u00b8\x00\x00\xe0\x94\xa3y\xa5\a\fP=/\xac\x89\xb8\xb3\xaf\xa0\x80\xfdE\xedK\xec\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\xa3\x80-\x8ae\x9e\x89\xa2\xc4~\x90T0\xb2\xa8'\x97\x89P\xa7\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa3\x83\x06\xcbp\xba\xa8\u4446\xbdh\xaap\xa8=$/)\a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3\x84vi\x1d4\x94.\xeak/v\x88\x92#\x04}\xb4az\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3\x87\xceN\x96\x1axG\xf5`\a\\d\xe1YkVA\xd2\x1c\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\xa3\x87\xec\xde\x0e\xe4\xc8\a\x94\x99\xfd\x8e\x03G;\u060a\xd7R*\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xa3\x88:$\xf7\xf1f _\x1aj\x99I\al&\xa7nqx\x89b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x94\xa3\x8b[\xd8\x1a\x9d\xb9\u04b2\x1d^\xc7\xc6\x05R\xcd\x02\xedV\x1b\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xa3\x90\xca\x12+\x85\x01\xee>^\a\xa8\xcaKA\x9f~M\xae\x15\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xa3\x93*1\xd6\xffu\xfb;\x12q\xac\xe7\u02a7\xd5\xe1\xff\x10Q\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xa3\x94\xadO\xd9\xe6S\x0eo\\S\xfa\xec\xbe\u0781\xcb\x17-\xa1\x8a\x01/\x93\x9c\x99\xed\xab\x80\x00\x00\u07d4\xa3\x97\x9a\x92v\n\x13Z\xdfi\xd7/u\xe1gu_\x1c\xb8\u00c9\x05k\xc7^-c\x10\x00\x00\xe0\x94\xa3\x9b\xfe\xe4\xae\u027du\xbd\"\u01b6r\x89\x8c\xa9\xa1\xe9]2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa3\xa2b\xaf\u0493h\x19#\b\x92\xfd\xe8O-ZYJ\xb2\x83\x89e\xea=\xb7UF`\x00\x00\u07d4\xa3\xa2\xe3\x19\xe7\u04e1D\x8bZ\xa2F\x89S\x16\f-\xbc\xbaq\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3\xa5{\a\x16\x13(\x04\xd6\n\xac(\x11\x97\xff+=#{\x01\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xa3\xa9>\xf9\xdb\xea&6&=\x06\xd8I/jA\u0790|\"\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94\xa3\xae\x18y\x00}\x80\x1c\xb5\xf3RqjM\u063a'!\xde=\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xa3\xba\r:6\x17\xb1\xe3\x1bNB,\xe2i\xe8s\x82\x8d]i\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\u07d4\xa3\xbc\x97\x9bp\x80\t/\xa1\xf9/n\x0f\xb3G\u2359PE\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\xa3\xbf\xf1\u07e9\x97\x16h6\f\r\x82\x82\x842\xe2{\xf5Ng\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xa3\xc1J\xce(\xb1\x92\u02f0b\x14_\u02fdXi\xc6rq\xf6\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa3\xc3:\xfc\x8c\xb4pN#\x15=\xe2\x04\x9d5\xaeq3$r\x89+X\xad\u06c9\xa2X\x00\x00\u07d4\xa3\u0430<\xff\xbb&\x9fyj\u009d\x80\xbf\xb0}\xc7\u01ad\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa3\u0543\xa7\xb6[#\xf6\vy\x05\xf3\xe4\xaab\xaa\xc8\u007fB'\x898\xbe\xfa\x12mZ\x9f\x80\x00\u07d4\xa3\xdb6J3-\x88K\xa9;&\x17\xaeM\x85\xa1H\x9b\xeaG\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xa3\xe0Q\xfbtJ\xa3A\f;\x88\xf8\x99\xf5\xd5\u007f\x16\x8d\xf1-\x89\xa00\xdc\xeb\xbd/L\x00\x00\u07d4\xa3\xe3\xa6\xeaP\x95s\xe2\x1b\xd0#\x9e\xce\x05#\xa7\xb7\u061b/\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xa3\xf4\xad\x14\xe0\xbbD\xe2\xce,\x145\x9cu\xb8\xe72\xd3pT\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa3\xfa\xccP\x19\\\vI3\xc8X\x97\xfe\xcc[\xbd\x99\\4\xb8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa4\x03Z\xb1\xe5\x18\b!\xf0\xf3\x80\xf1\x13\x1bs\x87\xc8\u0641\u0349\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa4\n\xa2\xbb\xce\fr\xb4\xd0\xdf\xff\xccBq[+T\xb0\x1b\xfa\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa4\x19\xa9\x84\x14#c&uuV`\x894\x0e\xea\x0e\xa2\b\x19\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\xa4!\u06f8\x9b:\aA\x90\x84\xad\x10\xc3\xc1]\xfe\x9b2\xd0\u008a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xa4\"\xe4\xbf\v\xf7AG\u0309[\xed\x8f\x16\xd3\xce\xf3BaT\x89\x12\xef?b\xee\x116\x80\x00\u07d4\xa4%\x9f\x83E\xf7\u3a37+\x0f\xec,\xf7^2\x1f\xdaM\u0089g\x8a\x93 b\xe4\x18\x00\x00\u07d4\xa4)\b\xe7\xfeS\x98\n\x9a\xbf@D\xe9W\xa5Kp\u973e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa4)\xfa\x88s\x1f\xdd5\x0e\x8e\xcdn\xa5B\x96\xb6HO\u6549j\xc5\xc6-\x94\x86\a\x00\x00\xe0\x94\xa40\x99]\xdb\x18[\x98e\xdb\xe6%9\xad\x90\xd2.Ks\u008a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa46\xc7TS\xcc\xcaJ\x1f\x1bb\xe5\u0123\r\x86\xdd\xe4\xbeh\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xa47\xfen\xc1\x03\u028d\x15\x8fc\xb34\"N\u032c[>\xa3\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa4;m\xa6\xcbz\xacW\x1d\xff'\xf0\x9d9\xf8F\xf57i\xb1\x89\x14\x99\x8f2\xacxp\x00\x00\u07d4\xa4;\x81\xf9\x93V\xc0\xaf\x14\x1a\x03\x01\rw\xbd\x04,q\xc1\xee\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa4>\x19G\xa9$+5Ua\xc3\n\x82\x9d\xfe\uc881Z\xf8\x89\xd2=\x99\x96\x9f\u0591\x80\x00\u07d4\xa4H\x9aP\xea\xd5\xd5DZ{\xeeM-U6\u00a7lA\xf8\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa4O\xe8\x00\xd9o\xca\xd7;qp\xd0\xf6\x10\u02cc\x06\x82\xd6\u0389\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa4T2\xa6\xf2\xac\x9dVW{\x93\x8a7\xfa\xba\xc8\xcc|F\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa4f\xd7p\u0618\xd8\xc9\xd4\x05\xe4\xa0\xe5Q\xef\xaf\xcd\xe5<\xf9\x89\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\xe0\x94\xa4g\a1\x17X\x93\xbb\xcf\xf4\xfa\x85\u0397\xd9O\xc5\x1cK\xa8\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa4kC\x87\xfbM\xcc\xe0\x11\xe7nMsT}D\x81\xe0\x9b\xe5\x89Hz\x9a0E9D\x00\x00\u07d4\xa4l\xd27\xb6>\xeaC\x8c\x8e;e\x85\xf6y\xe4\x86\b2\xac\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa4wy\u063c\x1c{\xce\x0f\x01\x1c\xcb9\xefh\xb8T\xf8\u078f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa4\x82kl8\x82\xfa\xd0\xed\\\x8f\xbb%\xcc@\xccO3u\x9f\x89p\x1bC\xe3D3\xd0\x00\x00\u07d4\xa4\x87Y(E\x8e\xc2\x00]\xbbW\x8c\\\xd35\x80\xf0\xcf\x14R\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa4\x9fR:\xa5\x13d\xcb\xc7\u0655\x16=4\xebY\r\xed/\b\x89\x90'B\x1b*\x9f\xbc\x00\x00\u07d4\xa4\xa4\x9f\v\xc8h\x8c\xc9\xe6\xdc\x04\xe1\xe0\x8dR\x10&\xe6Ut\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa4\xa7\xd3\x06\xf5\x10\xcdX5\x94(\xc0\xd2\xf7\xc3`\x9dVt\u05c9\xb5\x8c\xb6\x1c<\xcf4\x00\x00\u07d4\xa4\xa8:\a8y\x9b\x97\x1b\xf2\xdep\x8c.\xbf\x91\x1c\xa7\x9e\xb2\x89 \x86\xac5\x10R`\x00\x00\u07d4\xa4\xb0\x9d\xe6\xe7\x13\xdciTnv\xef\n\xcf@\xb9O\x02A\xe6\x89\x11}\xc0b~\xc8p\x00\x00\xe0\x94\xa4\u04b4)\xf1\xadSI\xe3\x17\x04\x96\x9e\xdc_%\xee\x8a\xca\x10\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xa4\xd6\xc8.\u076eYG\xfb\xe9\xcd\xfb\xd5H\xae3\xd9\x1aq\x91\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa4\xda4E\r\"\xec\x0f\xfc\xed\xe0\x00K\x02\xf7\x87.\xe0\xb7:\x89\x05\x0fafs\xf0\x83\x00\x00\xe0\x94\xa4\xddY\xab^Q}9\x8eI\xfaS\u007f\x89\x9f\xedL\x15\xe9]\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xa4\xe6#E\x1e~\x94\xe7\u86e5\xed\x95\u0228:b\xff\xc4\xea\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa4\xed\x11\xb0r\u061f\xb16u\x9f\u019bB\x8cH\xaa]L\xed\x89\x0e?\x15'\xa0<\xa8\x00\x00\u07d4\xa4\xfb\x14@\x9ag\xb4V\x88\xa8Y>\\\xc2\xcfYl\xedo\x11\x89a\t=|,m8\x00\x00\xe0\x94\xa5\x14\xd0\x0e\xddq\b\xa6\xbe\x83\x9ac\x8d\xb2AT\x18\x17A\x96\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\xe0\x94\xa5\"\xde~\xb6\xae\x12PR*Q13\xa9;\xd4(IG\\\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xa5$\xa8\xcc\xccIQ\x8d\x17\n2\x82p\xa2\xf8\x813\xfb\xaf]\x89\x0f\xf7\x02-\xac\x10\x8a\x00\x00\u07d4\xa59\xb4\xa4\x01\xb5\x84\xdf\xe0\xf3D\xb1\xb4\"\xc6UC\x16~.\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xa5>\xadT\xf7\x85\n\xf2\x148\xcb\xe0z\xf6\x86'\x9a1[\x86\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa5C\xa0f\xfb2\xa8f\x8a\xa0sj\f\x9c\xd4\rx\t\x87'\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa5gw\vj\xe3 \xbd\xdeP\xf9\x04\xd6c\xe7F\xa6\x1d\xac\xe6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa5h\xdbMW\xe4\xd6tb\xd73\u019a\x9e\x0f\xe2n!\x83'\x89;k\xff\x92f\xc0\xae\x00\x00\u07d4\xa5i\x8059\x1eg\xa4\x90\x13\xc0\x00 yY1\x14\xfe\xb3S\x89\r\x02\xabHl\xed\xc0\x00\x00\u07d4\xa5p\":\xe3\u02a8QA\x8a\x98C\xa1\xacU\xdbH$\xf4\xfd\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa5s`\xf0\x02\xe0\xd6M-tE}\x8c\xa4\x85~\xe0\v\xcd\u07c9\x123\xe22\xf6\x18\xaa\x00\x00\u07d4\xa5u\xf2\x89\x1d\xcf\u0368<\\\xf0\x14t\xaf\x11\xee\x01\xb7-\u0089\x05l\xd5_\xc6M\xfe\x00\x00\u07d4\xa5x;\xf342\xff\x82\xacI\x89\x85\xd7\xd4`\xaeg\xec6s\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xa5\x87MuF5\xa7b\xb3\x81\xa5\xc4\u01d2H:\xf8\xf2=\x1d\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94\xa5\xa4\"\u007fl\xf9\x88%\xc0\u057a\xffS\x15u,\xcc\x1a\x13\x91\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa5\xabK\xd3X\x8fF\xcb'.V\xe9=\xee\u04c6\xba\x8bu=\x89HB\xf0A\x05\x87,\x80\x00\xe0\x94\xa5\xba\xd8e\t\xfb\xe0\xe0\xe3\xc0\xe9?m8\x1f\x1a\xf6\xe9\u0501\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xa5\xc36\b;\x04\xf9G\x1b\x8cn\xd76y\xb7Mf\xc3c\uc263e\nL\x9d \xe2\x00\x00\u07d4\xa5\xcd\x129\x92\x19K4\xc4x\x13\x140;\x03\xc5IH\xf4\xb9\x89l\xfc\xc3\xd9\x1d\xa5c\x00\x00\u07d4\xa5\u0578\xb6-\x00-\xef\x92A7\x10\xd1;o\xf8\xd4\xfc}\u04c9\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xa5\xd9ni}F5\x8d\x11\x9a\xf7\x81\x9d\xc7\b\u007fj\xe4\u007f\xef\x8a\x03\x17\xbe\xe8\xaf3\x15\xa7\x80\x00\u07d4\xa5\xde^CO\xdc\xddh\x8f\x1c1\xb6\xfbQ,\xb1\x96rG\x01\x89+^:\xf1k\x18\x80\x00\x00\u07d4\xa5\xe0\xfc<:\xff\xed=\xb6q\tG\xd1\xd6\xfb\x01\u007f>'m\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa5\xe9;I\xea|P\x9d\xe7\xc4Ml\xfe\xdd\xefY\x10\u07aa\xf2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa5\xe9\xcdKt%]\"\xb7\u0672z\xe8\xddC\xedn\xd0%+\x89)\x8d\xb2\xf5D\x11\u0640\x00\xe0\x94\xa5\xf0\a{5\x1flP\\\xd5\x15\u07e6\xd2\xfa\u007f\\L\u0487\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xa5\xf0u\xfd@\x135W{f\x83\u0081\xe6\xd1\x01C-\xc6\xe0\x89\x91Hx\xa8\xc0^\xe0\x00\x00\u07d4\xa5\xfe,\xe9\u007f\x0e\x8c8V\xbe\r\xe5\xf4\u0732\xce]8\x9a\x16\x89\x01=\xb0\xb8\xb6\x86>\x00\x00\u07d4\xa5\xffb\"-\x80\xc0\x13\xce\xc1\xa0\xe8\x85\x0e\xd4\xd3T\xda\xc1m\x89\vA\a\\\x16\x8b\x18\x00\x00\u07d4\xa6\t\xc2m\xd3P\xc25\xe4K+\x9c\x1d\xdd\xcc\u0429\xd9\xf87\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa6\f\x12\tuO]\x87\xb1\x81\xdaO\b\x17\xa8\x18Y\xef\x9f\u0609\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\xe0\x94\xa6\x10\x1c\x96\x1e\x8e\x1c\x15y\x8f\xfc\xd0\xe3 \x1dw\x86\xec7:\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xa6\x13Ei\x96@\x8a\xf1\xc2\xe9>\x17w\x88\xabU\x89^+2\x8a\x01Y\x19\xffG|\x88\xb8\x00\x00\u07d4\xa6\x18\x87\x81\x8f\x91J \xe3\x10w)\v\x83qZk-n\xf9\x89e\xea=\xb7UF`\x00\x00\u07d4\xa6\x1aT\xdfxJD\xd7\x1bw\x1b\x871u\t!\x13\x81\xf2\x00\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa6\x1c\u06ed\xf0K\x1eT\u0203\xde`\x05\xfc\xdf\x16\xbe\xb8\xeb/\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xa69\xac\xd9k1\xbaS\xb0\u0407c\"\x9e\x1f\x06\xfd\x10^\x9d\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa6BP\x10\x04\xc9\x0e\xa9\xc9\xed\x19\x98\xba\x14\nL\xd6,o_\x89\r\x94\xfb\x8b\x10\xf8\xb1\x80\x00\u07d4\xa6D\xed\x92,\xc27\xa3\xe5\u0117\x9a\x99Tw\xf3nP\xbcb\x89\x1f\xa7=\x84]~\x96\x00\x00\u07d4\xa6F\xa9\\moY\xf1\x04\xc6T\x1dw`uz\xb3\x92\xb0\x8c\x89\u3bb5sr@\xa0\x00\x00\xe0\x94\xa6HL\u0184\xc4\xc9\x1d\xb5>\xb6\x8aM\xa4Zjk\xda0g\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xa6N_\xfbpL,\x919\xd7~\xf6\x1d\x8c\u07e3\x1dz\x88\xe9\x89\a\xc0\x86\x0eZ\x80\xdc\x00\x00\xe0\x94\xa6T&\xcf\xf3x\xed#%5\x13\xb1\x9fIm\xe4_\xa7\u13ca\x01\x86P\x12|\xc3\u0700\x00\x00\u07d4\xa6jIc\xb2\u007f\x1e\xe1\x93+\x17+\xe5\x96N\r:\xe5KQ\x89\t`\xdbwh\x1e\x94\x00\x00\u07d4\xa6\u007f8\x81\x95eB:\xa8_>:\xb6\x1b\xc7c\u02eb\x89\u0749sw\xb0\"\u01be\b\x00\x00\u07d4\xa6\x8c14E\xc2-\x91\x9e\xe4l\xc2\xd0\xcd\xff\x04:uX%\x89\x04\x13t\xfd!\xb0\u0600\x00\u07d4\xa6\x8e\f0\u02e3\xbcZ\x88>T\x03 \xf9\x99\xc7\xcdU\x8e\\\x89a\x9237b\xa5\x8c\x80\x00\u07d4\xa6\x90\xf1\xa4\xb2\n\xb7\xba4b\x86 \u079c\xa0@\xc4<\x19c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa6\x9d|\xd1}HB\xfe\x03\xf6*\x90\xb2\xfb\xf8\xf6\xaf{\xb3\x80\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xa6\xa0\x82R\xc8YQw\xcc.`\xfc'Y>#y\xc8\x1f\xb1\x89\x01\x16Q\xac>zu\x80\x00\u07d4\xa6\xa0\xdeB\x1a\xe5Om\x17(\x13\b\xf5dm/9\xf7w]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa6\xb2\xd5s)s`\x10,\a\xa1\x8f\xc2\x1d\xf2\xe7I\x9f\xf4\xeb\x89\xd9o\u0390\u03eb\xcc\x00\x00\xe0\x94\xa6\xc9\x10\xceMIJ\x91\x9c\u036a\xa1\xfc;\x82\xaat\xba\x06\u03ca\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xa6\u3ea3\x8e\x10J\x1e'\xa4\xd8(i\xaf\xb1\xc0\xaen\xff\x8d\x89\x01\x11@\ueb4bq\x00\x00\u07d4\xa6\xee\xbb\xe4d\u04d1\x87\xbf\x80\u029c\x13\xd7 '\xec[\xa8\xbe\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xa6\xf6+\x8a=\u007f\x11\"\a\x01\xab\x9f\xff\xfc\xb3'\x95\x9a'\x85\x89\x1bn)\x1f\x18\u06e8\x00\x00\u07d4\xa6\xf93\a\xf8\xbc\xe01\x95\xfe\u0387 C\xe8\xa0?{\xd1\x1a\x89\x9csK\xadQ\x11X\x00\x00\u07d4\xa7\x01\xdfy\xf5\x94\x90\x1a\xfe\x14DH^k \u00fd\xa2\xb9\xb3\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa7\x02L\xfdt,\x1e\xc1<\x01\xfe\xa1\x8d0B\xe6_\x1d]\xee\x8a\x02c\x11\x9a(\xab\u0430\x80\x00\u07d4\xa7\x18\xaa\xadY\xbf9\\\xba+#\xe0\x9b\x02\xfe\f\x89\x81bG\x8960<\x97\xe4hx\x00\x00\u07d4\xa7$|S\xd0Y\xeb|\x93\x10\xf6(\xd7\xfclj\nw?\b\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xa7%7c\xcfJu\u07d2\xca\x1evm\xc4\xee\x8a'E\x14{\x8a\x02F7p\xe9\n\x8fP\x00\x00\u07d4\xa7.\xe6f\u0133^\x82\xa5\x06\x80\x8bD<\xeb\xd5\xc62\xc7\u0749+^:\xf1k\x18\x80\x00\x00\u07d4\xa7DD\xf9\x0f\xbbT\xe5o:\u0276\xcf\u032aH\x19\xe4aJ\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa7GC\x9a\xd0\u04d3\xb5\xa08a\xd7r\x962m\u8edd\xb9\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xa7`{BW;\xb6\xf6\xb4\xd4\xf2<~*&\xb3\xa0\xf6\xb6\xf0\x89WG=\x05\u06ba\xe8\x00\x00\xe0\x94\xa7i)\x89\n{G\xfb\x85\x91\x96\x01lo\u0742\x89\u03b7U\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u0794\xa7kt?\x98\x1bi0r\xa11\xb2+\xa5\x10\x96\\/\xef\u05c8\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xa7m?\x15bQ\xb7,\f\xcfKG\xa39<\xbdoI\xa9\u0149Hz\x9a0E9D\x00\x00\u07d4\xa7t(\xbc\xb2\xa0\xdbv\xfc\x8e\xf1\xe2\x0eF\x1a\n2\u016c\x15\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\xa7u\x8c\xec\xb6\x0e\x8faL\u0396\x13~\xf7+O\xbd\awJ\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xa7w^J\xf6\xa2:\xfa \x1f\xb7\x8b\x91^Q\xa5\x15\xb7\xa7(\x89\x06\x81U\xa46v\xe0\x00\x00\u07d4\xa7\u007f>\u1793\x88\xbb\xbb\"\x15\xc6#\x97\xb9e`\x13#`\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xa7\x85\x9f\xc0\u007fun\xa7\xdc\xeb\xbc\xcdB\xf0X\x17X-\x97?\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa7\x96lH\x9fLt\x8az\u902a'\xa5t%\x17g\xca\xf9\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xa7\xa3\xbba9\xb0\xad\xa0\f\x1f\u007f\x1f\x9fV\u0654\xbaM\x1f\xa8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa7\xa3\xf1S\xcd\u00c8!\xc2\f]\x8c\x82A\xb2\x94\xa3\xf8+$\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xa7\xa5\x17\u05ed5\x82\v\t\u0517\xfa~U@\xcd\xe9IXS\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xa7\xc9\u04c8\xeb\xd8s\xe6k\x17\x13D\x83\x97\xd0\xf3\u007f\x8b\u04e8\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xa7\u073b\xa9\xb9\xbfgb\xc1EAlPjq\u3d17 \x9c\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xa7\xe7O\v\xdb'\x8f\xf0\xa8\x05\xa6Ha\x8e\xc5+\x16o\xf1\xbe\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xa7\xe87r\xbc \x0f\x90\x06\xaa*&\r\xba\xa8H=\xc5+0\x89\vB\xd56f7\xe5\x00\x00\xe0\x94\xa7\xef5\u0387\xed\xa6\u008d\xf2HxX\x15\x05>\xc9zPE\x8a\x01\x0f\f\xe9I\xe0\x0f\x93\x00\x00\u07d4\xa7\xf9\"\f\x80G\x82k\xd5\xd5\x18?Ngjmw\xbf\xed6\x89\bPh\x97k\xe8\x1c\x00\x00\u07d4\xa8\a\x10O'\x03\xd6y\xf8\u07af\xc4B\xbe\xfe\x84\x9eB\x95\v\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa8\f\xb1s\x8b\xac\b\xd4\xf9\xc0\x8bM\xef\xf5\x15T_\xa8XO\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xa8\x19\xd2\xec\xe1\"\xe0(\xc8\xe8\xa0J\x06M\x02\xb9\x02\x9b\b\xb9\x8965\u026d\xc5\u07a0\x00\x00\u0794\xa8%\xfdZ\xbby&\xa6|\xf3k\xa2F\xa2K\xd2{\xe6\xf6\xed\x88\xf4?\xc2\xc0N\xe0\x00\x00\u07d4\xa8(U9\x86\x9d\x88\xf8\xa9aS7Uq}~\xb6Uv\xae\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xa83\x82\xb6\xe1Rg\x97J\x85P\xb9\x8fqv\xc1\xa3S\xf9\xbe\x89\xbf\xfd\xaf/\xc1\xb1\xa4\x00\x00\xe0\x94\xa8DlG\x81\xa77\xacC(\xb1\xe1[\x8a\v?\xbb\x0f\xd6h\x8a\x04\x87\x94\xd1\xf2F\x19*\x00\x00\u07d4\xa8E[A\x17e\u0590\x1e1\x1erd\x03\t\x1eB\xc5f\x83\x89\xb7:\xec;\xfe\x14P\x00\x00\xe0\x94\xa8f\x13\xe6\u0124\xc9\xc5_\\\x10\xbc\xda2\x17]\u02f4\xaf`\x8a\x02C\xd6\xc2\xe3k\xe6\xae\x00\x00\u07d4\xa8m\xb0}\x9f\x81/G\x96b-@\xe0=\x13Xt\xa8\x8at\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa8\u007fz\xbdo\xa3\x11\x94(\x96x\xef\xb6<\xf5\x84\xee^*a\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xa8\x80\u2a3f\x88\xa1\xa8&H\xb4\x01W\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa8\x9d\xf3HY\xed\xd7\xc8 \u06c8w@\xd8\xff\x9e\x15\x15|{\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa8\xa4<\x00\x91\x00al\xb4\xaeN\x03?\x1f\xc5\xd7\xe0\xb6\xf1R\x89\u0548\xd0x\xb4?M\x80\x00\u07d4\xa8\xa7\b\xe8O\x82\u06c6\xa3U\x02\x19;Ln\xe9\xa7n\xbe\x8f\x897\b\xba\xed=h\x90\x00\x00\xe0\x94\xa8\xa7\xb6\x8a\u06b4\xe3\xea\xdf\xf1\x9f\xfaX\xe3J?\xce\xc0\xd9j\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xa8\xa8\xdb\xdd\x1a\x85\u047e\xee%i\xe9\x1c\xccM\t\xae\u007fn\xa1\x8a\x01:k+VHq\xa0\x00\x00\u07d4\xa8\xac\xa7H\xf9\xd3\x12\xect\u007f\x8bex\x14&\x94\xc7\xe9\xf3\x99\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa8\xb6[\xa3\x17\x1a?w\xa65\v\x9d\xaf\x1f\x8dU\xb4\xd2\x01\xeb\x89(b\xf3\xb0\xd2\"\x04\x00\x00\u07d4\xa8\xbe\xb9\x1c+\x99\u0216J\xa9[kJ\x18K\x12i\xfc4\x83\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u0794\xa8\xc0\xb0/\xaf\x02\xcbU\x19\u0768\x84\xde{\xbc\x8c\x88\xa2\u0681\x88\xe7\xc2Q\x85\x05\x06\x00\x00\u07d4\xa8\xc1\u05aaA\xfe=e\xf6{\xd0\x1d\xe2\xa8f\xed\x1e\u066eR\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4\xa8\xca\xfa\xc3\"\x80\xd0!\x02\v\xf6\xf2\xa9x(\x83\u05ea\xbe\x12\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xa8\xdb\v\x9b \x14S3A<;\fb\xf5\xf5.\u0544\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa8\xf3\u007f\n\xb3\xa1\xd4H\xa9\xe3\xce@\x96_\x97\xa6F\b:4\x89\x11\xe0\xe4\xf8\xa5\v\xd4\x00\x00\u07d4\xa8\xf8\x9d\xd5\xccnd\u05f1\xee\xac\xe0\a\x02\x02,\xd7\xd2\xf0=\x89%\xf2s\x93=\xb5p\x00\x00\xe0\x94\xa9\x04v\xe2\xef\xdf\xeeO8{\x0f2\xa5\x06x\xb0\xef\xb5s\xb5\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa9\x14PF\xfa6(\xcf_\xd4\xc6\x13\x92{\xe51\xe6\xdb\x1f\u0749\x06\x12O\xee\x99;\xc0\x00\x00\u07d4\xa9\x14\u0375q\xbf\xd9=d\xdaf\xa4\xe1\b\xea\x13NP\xd0\x00\x89M\x878\x99G\x13y\x80\x00\xe0\x94\xa9\x1aZ{4\x1f\x99\xc55\x14N \xbe\x9ck;\xb4\u008eM\x8a\x01&u:\xa2$\xa7\v\x00\x00\u07d4\xa9%%Q\xa6$\xaeQ7\x19\u06beR\a\xfb\xef\xb2\xfdwI\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xa9'\u050b\xb6\u02c1K\xc6\t\xcb\u02a9\x15\x1f]E\x9a'\xe1\x89\x0e\xb95\t\x00d\x18\x00\x00\u07d4\xa9)\u023dq\xdb\f0\x8d\xac\x06\b\n\x17G\xf2\x1b\x14e\xaa\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xa9K\xbb\x82\x14\u03cd\xa0\xc2\xf6h\xa2\xacs\xe8bHR\x8dK\x894\n\xad!\xb3\xb7\x00\x00\x00\u07d4\xa9Q\xb2D\xffP\u03eeY\x1d^\x1a\x14\x8d\xf6\xa98\xef*\x1a\x89^\x00\x15\x84\xdf\xcfX\x00\x00\u07d4\xa9`\xb1\xca\xdd;\\\x1a\x8el\xb3\xab\xca\xf5.\xe7\xc3\xd9\xfa\x88\x89R\x8b\xc3T^Rh\x00\x00\u07d4\xa9a\x17\x1fSB\xb1s\xddp\xe7\xbf\xe5\xb5\xca#\x8b\x13\xbc\u0749\xb8'\x94\xa9$O\f\x80\x00\u07d4\xa9u\xb0w\xfc\xb4\u030e\xfc\xbf\x83\x84Y\xb6\xfa$:AY\u0589\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\xa9{\xeb:H\xc4_\x15((L\xb6\xa9_}\xe4S5\x8e\u018a\x06\x90\x83l\n\xf5\xf5`\x00\x00\u07d4\xa9~\a!DI\x9f\xe5\xeb\xbd5J\xcc~~\xfbX\x98]\b\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\xa9\x86v/zO)O.\v\x172y\xad,\x81\xa2\"4X\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xa9\x8f\x10\x985\xf5\xea\xcd\x05Cd|4\xa6\xb2i\xe3\x80/\xac\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xa9\x97\xdf\u01d8j'\x05\bH\xfa\x1cd\u05e7\xd6\xe0z\u0322\x89\a\xc0\x86\x0eZ\x80\xdc\x00\x00\u07d4\xa9\x99\x91\u03bd\x98\xd9\xc88\xc2_zt\x16\xd9\xe2D\xca%\r\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xa9\xa1\xcd\xc3;\xfd7o\x1c\rv\xfbl\x84\xb6\xb4\xac'Mh\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xa9\xa8\xec\xa1\x1a#\xd6F\x89\xa2\xaa>A}\xbb=3k\xb5\x9a\x89\x0e4S\xcd;g\xba\x80\x00\u07d4\xa9\xac\xf6\x00\b\x1b\xb5[\xb6\xbf\xba\xb1\x81_\xfcN\x17\xe8Z\x95\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xa9\xad\x19&\xbcf\xbd\xb31X\x8e\xa8\x197\x88SM\x98,\x98\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4\xa9\xaf!\xac\xbeH/\x811\x89j\"\x806\xbaQ\xb1\x94S\u00c9\x02\xb5\xe0!\x98\f\xc1\x80\x00\xe0\x94\xa9\xb2\xd2\xe0IN\xab\x18\xe0}7\xbb\xb8V\xd8\x0e\x80\xf8L\u04ca\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xa9\xbaoA;\x82\xfc\xdd\xf3\xaf\xfb\xbd\u0412\x87\xdc\xf5\x04\x15\u0289\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xa9\xbe\x88\xad\x1eQ\x8b\v\xbb\x02J\xb1\xd8\xf0\xe7?y\x0e\fv\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\xa9\xbf\xc4\x10\xdd\xdb q\x1eE\xc0s\x87\xea\xb3\n\x05N\x19\xac\x89>\x99`\x1e\xdfNS\x00\x00\u07d4\xa9\u0522\xbc\xbe[\x9e\bi\xd7\x0f\x0f\xe2\xe1\u05aa\xcdE\xed\u0149\n\xc6\xe7z\xb6c\xa8\x00\x00\xe0\x94\xa9\xd6KO;\xb7\x85\a\"\xb5\x8bG\x8b\xa6\x917^\"NB\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xa9\xd6\xf8q\xcax\x1au\x9a \xac:\u06d7,\xf1()\xa2\b\x892$\xf4'#\xd4T\x00\x00\xe0\x94\xa9\xdc\x04$\u0196\x9dy\x83X\xb3\x93\xb1\x93:\x1fQ\xbe\xe0\n\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xa9\xe1\x94f\x1a\xacpN\xe9\u07a0C\x97N\x96\x92\xde\xd8J]\x89\x1a&\xa5\x14\"\xa0p\x00\x00\u07d4\xa9\xe2\x837\xe65q\x93\xd9\xe2\xcb#k\x01\xbeD\xb8\x14'\u07c9wC\"\x17\xe6\x83`\x00\x00\u07d4\xa9\xe6\xe2^ekv%Xa\x9f\x14z!\x98[\x88t\xed\xfe\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xa9\xe9\xdb\xcez,\xb06\x94y\x98\x97\xbe\xd7\xc5M\x15_\u06a8\x89\n\xb5\xae\x8f\u025de\x80\x00\u07d4\xa9\xed7{}n\xc2Yq\xc1\xa5\x97\xa3\xb0\xf3\xbe\xadW\u024f\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xaa\x02\x00\xf1\xd1~\x9cT\xda\x06G\xbb\x969]W\xa7\x858\u06099>\xf1\xa5\x12|\x80\x00\x00\u07d4\xaa\f\xa3ss7\x17\x8a\f\xaa\xc3\t\x9cXK\x05lV0\x1c\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4\xaa\x13kG\x96+\xb8\xb4\xfbT\r\xb4\xcc\xf5\xfd\xd0B\xff\xb8\u03c9\x1b\x1bk\u05efd\xc7\x00\x00\xe0\x94\xaa\x14B-o\n\xe5\xa7X\x19N\xd1W\x80\xc88\xd6\u007f\x1e\xe1\x8a\x06\t2\x05lD\x9d\xe8\x00\x00\u07d4\xaa\x16&\x9a\xac\x9c\r\x800h\xd8/\u01d1Q\xda\xdd3Kf\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xaa\x16p&\u04da\xb7\xa8V5\x94N\xd9\xed\xb2\xbf\xeb\xa1\x18P\x8a\x01\xc1\xd5\xe2\x1bO\xcfh\x00\x00\u07d4\xaa\x1b7h\xc1m\x82\x1fX\x0ev\xc8\xe4\xc8\xe8m}\u01c8S\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xaa\x1d\xf9.Q\xdf\xf7\v\x19s\xe0\xe9$\xc6b\x87\xb4\x94\xa1x\x89\x1c\xf8J0\xa0\xa0\xc0\x00\x00\u07d4\xaa,g\x00\x96\xd3\xf990S%B~\xb9U\xa8\xa6\r\xb3\u0149l\x95Y\x06\x99#-\x00\x00\u07d4\xaa15\xcbT\xf1\x02\xcb\xef\xe0\x9e\x96\x10:\x1ayg\x18\xffT\x89\x03\"\"\xd9\xc31\x94\x00\x00\u07d4\xaa2\x1f\xdb\xd4I\x18\r\xb8\xdd\xd3O\x0f\xe9\x06\xec\x18\xee\t\x14\x89%\"H\u07b6\xe6\x94\x00\x00\xe0\x94\xaa9%\xdc\"\v\xb4\xae!w\xb2\x880x\xb6\xdc4l\xa1\xb2\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xaa?)`\x1a\x131t^\x05\xc4(0\xa1^q\x93\x8ab7\x89\\(=A\x03\x94\x10\x00\x00\xe0\x94\xaaG\xa4\xff\xc9y622\u025b\x99\xfa\xda\x0f'4\xb0\xae\xee\x8a\x01\xb8H\x9d\xf4\xdb\xff\x94\x00\x00\u07d4\xaaI=?O\xb8fI\x1c\xf8\xf8\x00\xef\xb7\xe22N\xd7\xcf\xe5\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xaaV\xa6]\u012b\xb7/\x11\xba\xe3+o\xbb\aDG\x91\xd5\u0249(\x94\xe9u\xbfIl\x00\x00\xe0\x94\xaaZ\xfc\xfd\x83\t\xc2\u07dd\x15\xbe^jPN}pf$\u014a\x01<\xf4\"\xe3\x05\xa17\x80\x00\u07d4\xaa\x8e\xb0\x82;\a\xb0\xe6\xd2\n\xad\xda\x0e\x95\xcf85\xbe\x19.\x89\x01\xbc\x16\xd6t\xec\x80\x00\x00\u07d4\xaa\x91#~t\r%\xa9/\u007f\xa1F\xfa\xa1\x8c\xe5m\xc6\xe1\xf3\x892$\xf4'#\xd4T\x00\x00\u07d4\xaa\x96\x0e\x10\xc5#\x91\xc5N\x158|\xc6z\xf8'\xb51m\u0309lk\x93[\x8b\xbd@\x00\x00\u07d4\xaa\x9b\xd4X\x955\xdb'\xfa+\xc9\x03\xca\x17\xd6y\xddeH\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xaa\xa8\xde\xfe\x11\xe3a?\x11\x06\u007f\xb9\x83bZ\b\x99Z\x8d\xfc\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xaa\xaa\xe6\x8b2\x14\x02\xc8\xeb\xc14h\xf3A\xc6<\f\xf0?\u0389Rf<\u02b1\xe1\xc0\x00\x00\u07d4\xaa\xad\x1b\xaa\xdeZ\xf0N+\x17C\x9e\x93Y\x87\xbf\x8c+\xb4\xb9\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xaa\xb0\n\xbfX(\xd7\xeb\xf2kG\u03ac\u0378\xba\x032Qf\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xaa\xbd\xb3\\\x15\x14\x98J\x03\x92\x13y?3E\xa1h\xe8\x1f\xf1\x89\x10\xca\u0216\xd29\x00\x00\x00\u07d4\xaa\xca`\xd9\xd7\x00\u7156\xbb\xbb\xb1\xf1\xe2\xf7\x0fF'\xf9\u060965\xbbw\xcbK\x86\x00\x00\u07d4\xaa\xce\u0629V;\x1b\xc3\x11\xdb\xdf\xfc\x1a\xe7\xf5u\x19\xc4D\f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xaa\u04b7\xf8\x10f\x95\a\x8el\x13\x8e\xc8\x1at\x86\xaa\xca\x1e\xb2\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xaa\xe6\x1eC\xcb\r\f\x96\xb3\x06\x99\xf7~\x00\xd7\x11\u0423\x97\x9b\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xaa\xe72\xed\xa6Y\x88\u00e0\f\u007fG/5\x1cF;\x1c\x96\x8e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xaa\xf0#\xfe\U0009091b\xb7\x8b\xb7\xab\xc9]f\x9cP\xd5(\xb0\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xaa\xf5\xb2\a\xb8\x8b\r\xe4\xac@\xd7G\xce\xe0n\x17-\xf6\xe7E\x8a\x06\xa7\xb7\x1d\u007fQ\u0410\x00\x00\u07d4\xaa\xf9\xeeK\x88lm\x1e\x95Io\xd2t#[\xf4\xec\xfc\xb0}\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xaa\xfb{\x01:\xa1\xf8T\x1c~2{\xf6P\xad\xbd\x19L \x8f\x89I\x9e\t-\x01\xf4x\x00\x00\xe0\x94\xab\t\x863\xee\xee\f\xce\xfd\xf62\xf9WTV\xf6\u0740\xfc\x86\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xab\f\xedv.\x16a\xfa\xe1\xa9*\xfb\x14\b\x88\x94\x13yH%\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94\xab\x14\xd2!\xe3=TF)\x19\x8c\u0416\xedc\u07e2\x8d\x9fG\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xab \x9f\u0729y\u0426G\x01\n\xf9\xa8\xb5/\xc7\xd2\r\x8c\u044a\x01\xee\xe2S,|-\x04\x00\x00\u07d4\xab'\xbax\xc8\xe5\xe3\xda\xef1\xad\x05\xae\xf0\xff\x03%r\x1e\b\x89\x19^\xce\x00n\x02\xd0\x00\x00\u07d4\xab(q\xe5\a\u01fe9eI\x8e\x8f\xb4b\x02Z\x1a\x1cBd\x89*\x03I\x19\u07ff\xbc\x00\x00\u07d4\xab8a\"o\xfe\xc1(\x91\x87\xfb\x84\xa0\x8e\xc3\xed\x042d\xe8\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xab=\x86\xbc\x82\x92~\f\xd4!\xd1F\xe0\u007f\x91\x93'\xcd\xf6\xf9\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94\xab>b\xe7z\x8b\"^A\x15\x92\xb1\xaf0\aR\xfeA$c\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\xab>x)K\xa8\x86\xa0\xcf\xd5\xd3H\u007f\xb3\xa3\a\x8d3\x8dn\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xab@\x04\xc0@?~\xab\xb0\xeaXo!!V\xc4 =g\xf1\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xabAo\xe3\rX\xaf\xe5\xd9EL\u007f\xce\u007f\x83\v\xccu\x03V\x89\x0657\x01\xc6\x05\u06c0\x00\u07d4\xabEr\xfb\xb1\xd7+W]i\xecj\xd1s3\x87>\x85R\xfc\x89lj\xc5L\xdahG\x00\x00\u07d4\xabZy\x01av2\ts\xe8\xcd8\xf67U0\x02%1\xc0\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xab]\xfc\x1e\xa2\x1a\xdcB\u03cc?n6\x1e$?\xd0\xdaa\xe5\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xabke\xea\xb8\xdf\xc9\x17\xec\x02Q\xb9\xdb\x0e\u03e0\xfa\x03(I\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xabp\x91\x93.K\u00dd\xbbU#\x80\u0293O\xd7\x16m\x1en\x89\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4\xabt\x16\xff2%IQ\u02fcbN\xc7\xfbE\xfc~\u02a8r\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\xab|B\xc5\xe5-d\x1a\a\xadu\t\x9cb\x92\x8b\u007f\x86b/\x89\x126\x1a\xa2\x1d\x14\xba\x00\x00\u07d4\xab}T\xc7\xc6W\x0e\xfc\xa5\xb4\xb8\xcep\xf5*Ws\xe5\xd5;\x89\x0f(:\xbe\x9d\x9f8\x00\x00\u07d4\xab~\v\x83\xed\x9aBLm\x1ejo\x87\xa4\xdb\xf0d\t\xc7\u0589\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\xab\x84\xa0\xf1G\xad&T\x00\x00+\x85\x02\x9aA\xfc\x9c\xe5\u007f\x85\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xab\x93\xb2n\xce\n\n\xa2\x13e\xaf\xed\x1f\xa9\xae\xa3\x1c\xd5Dh\x89W+{\x98sl \x00\x00\u07d4\xab\x94\x8aJ\xe3y\\\xbc\xa11&\xe1\x92S\xbd\xc2\x1d:\x85\x14\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xab\x9a\xd3n\\t\xce.\x969\x9fW\x83\x941\xd0\u77d6\xab\x89\b\xe3\xf5\v\x17<\x10\x00\x00\u07d4\xab\xb2\xe6\xa7*@\xban\xd9\b\u037c\xec\x91\xac\xfdwx0\xd1dcG\x8a\xe0\xfcw \x89\a?u\u0460\x85\xba\x00\x00\xe0\x94\xab\u071f\x1b\xcfM\x19\xee\x96Y\x100\xe7r\xc340/}\x83\x8a\b~^\x11\xa8\x1c\xb5\xf8\x00\x00\u07d4\xab\xde\x14{*\xf7\x89\ua946T~f\xc4\xfa&d\xd3(\xa4\x89\rk`\x81\xf3L\x12\x80\x00\xe0\x94\xab\xe0|\xedj\xc5\xdd\xf9\x91\xef\xf6\xc3\xda\"jt\x1b\xd2C\xfe\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xab\xf1/\xa1\x9e\x82\xf7lq\x8f\x01\xbd\xca\x00\x03gE#\xef0\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xab\xf7(\u03d3\x12\xf2!(\x02NpF\xc2Q\xf5\xdcY\x01\xed\x8a\x06A\xe8\xa15c\xd8\xf8\x00\x00\u07d4\xab\xf8\xff\xe0p\x8a\x99\xb5(\xcc\x1e\xd4\xe9\xceK\r\x060\xbe\x8c\x89z\xb5\u00ae\xee\xe68\x00\x00\u07d4\xab\xfc\xf5\xf2P\x91\xceW\x87_\xc6t\xdc\xf1\x04\xe2\xa7=\xd2\xf2\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xab\xfe\x93d%\xdc\u01f7K\x95P\x82\xbb\xaa\xf2\xa1\x1dx\xbc\x05\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xac\x02OYO\x95X\xf0ICa\x8e\xb0\xe6\xb2\xeeP\x1d\xc2r\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xac\x12*\x03\xcd\x05\x8c\x12._\xe1{\x87/Hw\xf9\u07d5r\x89j\xc5\xc6-\x94\x86\a\x00\x00\u07d4\xac\x14.\xda\x11W\xb9\xa9\xa6C\x90\xdf~j\xe6\x94\xfa\u0249\x05\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xac\x1d\xfc\x98Kq\xa1\x99)\xa8\x1d\x81\xf0J|\xbb\x14\a7\x03\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xac!\xc1\xe5\xa3\xd7\xe0\xb5\x06\x81g\x9d\xd6\u01d2\xdb\u0287\xde\u02ca\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\xac(\x89\xb5\x96o\f\u007f\x9e\xdbB\x89\\\xb6\x9d\x1c\x04\xf9#\xa2\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xac(\xb5\xed\xea\x05\xb7o\x8c_\x97\bEA'|\x96ijL\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xac,\x8e\t\xd0d\x93\xa68XC{\xd2\v\xe0\x19bE\x03e\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\xac.vm\xac?d\x8fcz\xc6q?\u0770h\xe4\xa4\xf0M\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94\xac9\x00)\x8d\xd1M|\xc9mJ\xbbB\x8d\xa1\xba\xe2\x13\xff\xed\x8a\x05<\xa1)t\x85\x1c\x01\x00\x00\u07d4\xac=\xa5&\xcf\u0388)s\x02\xf3LI\xcaR\r\xc2q\xf9\xb2\x89+^:\xf1k\x18\x80\x00\x00\u07d4\xacD`\xa7nm\xb2\xb9\xfc\xd1R\xd9\xc7q\x8d\x9a\xc6\xed\x8co\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xacJ\xcf\xc3n\xd6\tJ'\xe1\x18\xec\xc9\x11\xcdG>\x8f\xb9\x1f\x89a\x91>\x14@<\f\x00\x00\u07d4\xacL\xc2V\xaet\xd6$\xac\xe8\r\xb0x\xb2 \u007fW\x19\x8fk\x89lyt\x12?d\xa4\x00\x00\u07d4\xacN\xe9\xd5\x02\xe7\xd2\xd2\xe9\x9eY\xd8\xca}_\x00\xc9KM\u058965\u026d\xc5\u07a0\x00\x00\u07d4\xacR\xb7~\x15fH\x14\xf3\x9eO'\x1b\xe6A0\x8d\x91\xd6\u0309\v\xed\x1d\x02c\xd9\xf0\x00\x00\u07d4\xacY\x99\xa8\x9d-\u0486\u0568\fm\xee~\x86\xaa\xd4\x0f\x9e\x12\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\xac_br1H\r\r\x950.m\x89\xfc2\xcb\x1dO\xe7\xe3\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xac`\x8e+\xac\x9d\xd2\a(\u0494~\xff\xbb\xbf\x90\n\x9c\xe9K\x8a\x01EK\r\xb3uh\xfc\x00\x00\u07d4\xacm\x02\xe9\xa4k7\x9f\xacJ\u0271\u05f5\xd4{\xc8P\xce\x16\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xacoh\xe87\xcf\x19a\xcb\x14\xabGDm\xa1h\xa1m\u0789\x89Hz\x9a0E9D\x00\x00\u07d4\xacw\xbd\xf0\x0f\u0558[]\xb1+\xbe\xf8\x008\n\xbc*\x06w\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xac~\x03p'#\xcb\x16\xee'\xe2-\u0438\x15\xdc-\\\xae\x9f\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\xac\x8bP\x9a\xef\xea\x1d\xbf\xaf+\xb35\x00\xd6W\vo\xd9mQ\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xac\x8e\x87\xdd\xda^x\xfc\xbc\xb9\xfa\u007f\xc3\xce\x03\x8f\x9f}.4\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xac\x9f\xffh\xc6\x1b\x01\x1e\xfb\xec\xf08\xedr\u06d7\xbb\x9er\x81\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\xac\xa1\xe6\xbcd\xcc1\x80\xf6 \xe9M\u0171\xbc\xfd\x81X\xe4]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xac\xa2\xa883\v\x170-\xa71\xd3\r\xb4\x8a\x04\xf0\xf2\a\xc1\x89Hz\x9a0E9D\x00\x00\u07d4\xac\xaa\xdd\xcb\xf2\x86\xcb\x0e!]\xdaUY\x8f\u007f\xf0\xf4\xad\xa5\u018965\u026d\xc5\u07a0\x00\x00\u07d4\xac\xb9C8UK\u0108\u0308\xae-\x9d\x94\b\rk\u07c4\x10\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xac\xbc-\x19\xe0l;\xab\xbb[o\x05+k\xf7\xfc7\xe0r)\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xac\xbd\x18U\x89\xf7\xa6\x8ag\xaaK\x1b\xd6Pw\xf8\xc6NN!\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xac\xc0bp,Ya]4D\xefb\x14\xb8\x86+\x00\x9a\x02\xed\x89QO\xcb$\xff\x9cP\x00\x00\u07d4\xac\xc0\x90\x9f\xda.\xa6\xb7\xb7\xa8\x8d\xb7\xa0\xaa\xc8h\t\x1d\xdb\xf6\x89\x013v_\x1e&\u01c0\x00\u07d4\xac\xc1\u01c7\x86\xabM+;'q5\xb5\xba\x12>\x04\x00Hk\x89\x04E\x91\xd6\u007f\xec\xc8\x00\x00\u07d4\xac\xc4j*U\\t\xde\u0522\xbd\tN\x82\x1b\x97\x84;@\xc0\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xac\u015f;0\xce\xff\xc5da\xcc[\x8d\xf4\x89\x02$\x0e\x0e{\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xac\xce\x01\xe0\xa7\x06\x10\xdcp\xbb\x91\xe9\x92o\xa9\x95\u007f7/\xba\x89\x1d\x1c_>\xda \xc4\x00\x00\u07d4\xac\xd8\u0751\xf7\x14vLEg|c\xd8R\xe5n\xb9\xee\xce.\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xac\u2af6;\x06\x04@\x9f\xbd\xe3\xe7\x16\u0487mD\xe8\xe5\u0749\b=lz\xabc`\x00\x00\xe0\x94\xac\xec\x91\xefiA\xcfc\v\xa9\xa3\u71e0\x12\xf4\xa2\xd9\x1d\u050a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4\xad\nJ\xe4x\xe9cn\x88\xc6\x04\xf2B\xcfT9\xc6\xd4V9\x89\xbe\xd1\xd0&=\x9f\x00\x00\x00\u07d4\xad\x17\x99\xaa\xd7`+E@\u0343/\x9d\xb5\xf1\x11P\xf1hz\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xad\x1dh\xa08\xfd%\x86\x06~\xf6\xd15\xd9b\x8ey\xc2\xc9$\x89\xfe\t\xa5'\x9e*\xbc\x00\x00\u07d4\xad*\\\x00\xf9#\xaa\xf2\x1a\xb9\xf3\xfb\x06n\xfa\n\x03\xde/\xb2\x8965\xbbw\xcbK\x86\x00\x00\u07d4\xad5e\xd5+h\x8a\xdd\xed\b\x16\x8b-8r\xd1}\n&\xae\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xad7|\xd2^\xb5>\x83\xae\t\x1a\n\x1d+E\x16\xf4\x84\xaf\u0789i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94\xadAM)\xcb~\xe9s\xfe\xc5N\"\xa3\x88I\x17\x86\xcfT\x02\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\xadD5~\x01~$OGi1\u01f8\x18\x9e\xfe\xe8\n]\n\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xadW\xaa\x9d\x00\xd1\fC\x9b5\xef\xcc\v\xec\xac.9U\xc3\x13\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xadY\xa7\x8e\xb9\xa7J\u007f\xbd\xae\xfa\xfa\x82\xea\u0684u\xf0\u007f\x95\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xadZ\x8dV\x01L\xfc\xb3`\xf4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xadr\x81!\x87?\x04V\xd0Q\x8b\x80\xabe\x80\xa2\x03pe\x95\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xads,\x97e\x93\xee\xc4x;N.\xcdy9yx\v\xfe\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xad}\xd0S\x85\x9e\xdf\xf1\xcbo\x9d*\xcb\xedm\xd5\xe32Bo\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xad\x80\xd8e\xb8\\4\xd2\xe6IK.z\xef\xeak\x9a\xf1\x84\u06c9\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xad\x8b\xfe\xf8\u018aH\x16\xb3\x91o5\xcb{\xfc\xd7\xd3\x04\tv\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xad\x8eH\xa3wi]\xe0\x146:R:(\xb1\xa4\fx\xf2\b\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xad\x91\n#\u0585\x06\x13eJ\xf7\x863z\u04a7\bh\xacm\x89lh\xcc\u041b\x02,\x00\x00\u07d4\xad\x92~\x03\xd1Y\x9ax\xca+\xf0\xca\u04a1\x83\xdc\xebq\xea\xc0\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94\xad\x92\xca\x06n\xdb|q\x1d\xfc[\x16a\x92\xd1\xed\xf8\xe7q\x85\x8a\a\x9f\x90\\o\xd3N\x80\x00\x00\u07d4\xad\x94#_\u00f3\xf4z$\x13\xaf1\u8111I\b\xef\fE\x89\x1b\x1b\x01B\xd8\x15\x84\x00\x00\u07d4\xad\x9e\x97\xa0H/5:\x05\xc0\xf7\x92\xb9w\xb6\xc7\xe8\x11\xfa_\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xad\x9fL\x89\n;Q\x1c\xeeQ\xdf\xe6\xcf\xd7\xf1\t;vA,\x89\x1bv|\xbf\xeb\f\xe4\x00\x00\u07d4\xad\xaa\x0eT\x8c\x03Z\xff\xedd\xcag\x8a\x96?\xab\xe9\xa2k\xfd\x89\x03\xcbq\xf5\x1f\xc5X\x00\x00\u07d4\xad\xb9H\xb1\xb6\xfe\xfe }\xe6^\x9b\xbc-\xe9\x8e`]\vW\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xad\xc1\x9e\xc85\xaf\xe3\u5347\u0713\xa8\xa9!<\x90E\x13&\x89j\xdb\xe54\"\x82\x00\x00\x00\u07d4\xad\xc8\"\x8e\xf9(\xe1\x8b*\x80}\x00\xfb1\xfcgX\x15\xaa\x00\x00\u07d4\xad\xff\r\x1d\v\x97G\x1ev\u05c9\xd2\u470at\xf9\xbdT\xff\x89e\xea=\xb7UF`\x00\x00\u07d4\xae\x06,D\x86\x18d0u\xdez\x0004-\xce\xd6=\xba\u05c9,\xc6\u034c\u0082\xb3\x00\x00\xe0\x94\xae\x10\xe2z\x01O\r0k\xaf&mH\x97\u021a\xee\xe2\xe9t\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xae\x12k8,\xf2W\xfa\xd7\xf0\xbc}\x16)~T\xccrg\u0689\x10CV\x1a\x88)0\x00\x00\u07d4\xae\x13\xa0\x85\x11\x11\x0f2\xe5;\xe4\x12xE\xc8C\xa1\xa5|{\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xae\x17\x9aF\r\xb6c&t=$\xe6u#\xa5{$m\xaf\u007f\x8a\x01\x00\a\xae|\xe5\xbb\xe4\x00\x00\u07d4\xae\"(ey\x90y\xaa\xf4\xf0gJ\f\u06ab\x02\xa6\xd5p\xff\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xae#\x9a\xcf\xfdN\xbe.\x1b\xa5\xb4\x17\x05r\xdcy\xcce3\xec\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xae/\x9c\x19\xacv\x13e\x94C#\x93\xb0G\x1d\b\x90!d\u04c9%\xdf\x05\u01a8\x97\xe4\x00\x00\u07d4\xae4\x86\x1d4\"S\x19O\xfcfR\xdf\xdeQ\xabD\xca\xd3\xfe\x89\x19F\bhc\x16\xbd\x80\x00\u07d4\xae6\xf7E!!\x91>\x80\x0e\x0f\xcd\x1ae\xa5G\x1c#\x84o\x89\b\xe3\xf5\v\x17<\x10\x00\x00\u07d4\xae?\x98\xa4C\xef\xe0\x0f>q\x1dR]\x98\x94\u071aa\x15{\x89\x10\x04\xe2\xe4_\xb7\xee\x00\x00\xe0\x94\xaeG\xe2`\x9c\xfa\xfe6\x9df\xd4\x15\xd99\xde\x05\b\x1a\x98r\x8a\x05\xba\xec\xf0%\xf9\xb6P\x00\x00\u07d4\xaeO\x12.5\xc0\xb1\xd1\xe4\x06\x92\x91E|\x83\xc0\u007f\x96_\xa3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xaePU\x81L\xb8\xbe\f\x11{\xb8\xb1\xc8\u04b6;F\x98\xb7(\x89\x01\xbc\x93.\xc5s\xa3\x80\x00\u07d4\xaeS\x8cs\u0173\x8d\x8dXM~\xbd\xad\xef\xb1\\\xab\xe4\x83W\x896'\xe8\xf7\x127<\x00\x00\u07d4\xaeW\xcc\x12\x9a\x96\xa8\x99\x81\xda\xc6\r/\xfb\x87}]\xc5\xe42\x89<:#\x94\xb3\x96U\x00\x00\u07d4\xaeZ\xa1\xe6\u00b6\x0fo\xd3\xef\xe7!\xbbJq\x9c\xbe=o]\x89+$\u01b5Z^b\x00\x00\u07d4\xae\\\x9b\xda\xd3\xc5\u0221\"\x04D\xae\xa5\xc2)\xc1\x83\x9f\x1dd\x89\x19\xe2\xa4\xc8\x18\xb9\x06\x00\x00\u07d4\xae\\\xe35Z{\xa9\xb32v\f\tP\u00bcE\xa8_\xa9\xa0\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xae]\"\x1a\xfc\xd3\u0493U\xf5\b\xea\xdf\xca@\x8c\xe3<\xa9\x03\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xaec[\xf781\x11\x9d-)\xc0\xd0O\xf8\xf8\xd8\u0425zF\x89Hz\x9a0E9D\x00\x00\xe0\x94\xaed\x81U\xa6X7\x0f\x92\x9b\xe3\x84\xf7\xe0\x01\x04~I\xddF\x8a\x02\xdf$\xae2\xbe D\x00\x00\xe0\x94\xaeo\fs\xfd\xd7|H\x97'Q!t\u0675\x02\x96a\x1cL\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xaep\xe6\x9d,J\n\xf8\x18\x80{\x1a'\x05\xf7\x9f\u0435\xdb\u01095e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\xaew9\x12N\xd1S\x05%\x03\xfc\x10\x14\x10\xd1\xff\xd8\xcd\x13\xb7\x8964\xfb\x9f\x14\x89\xa7\x00\x00\u07d4\xaex\xbb\x84\x919\xa6\xba8\xae\x92\xa0\x9ai`\x1c\xc4\xcbb\u0449\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xae\x84\"\x10\xf4M\x14\u0124\u06d1\xfc\x9d;;P\x01O{\xf7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xae\x84.\x81\x85\x8e\xcf\xed\xf6Plhm\xc2\x04\xac\x15\xbf\x8b$\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xae\x89T\xf8\xd6\x16m\xe5\a\xcfa)}\x0f\xc7\xcak\x9eq(\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xae\x9e\xcdk\u0755.\xf4\x97\xc0\x05\n\u0aca\x82\xa9\x18\x98\u0389\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4\xae\x9f\\?\xbb\xe0\u027c\xbf\x1a\xf8\xfft\xea(\v:]\x8b\b\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\xae\xad\x88\u0589Ak\x1c\x91\xf26D!7[}\x82\xd0RR\n\xfb\\Wm\x9f~\xb9>\u048a\r\xd0A \xba\t\xcf\xe6\x00\x00\u07d4\xae\xc2\u007f\xf5\xd7\xf9\xdd\u0691\x18?F\xf9\xd5%C\xb6\xcd+/\x89\x18e\x01'\xcc=\xc8\x00\x00\u07d4\xae\xe4\x9dh\xad\xed\xb0\x81\xfdCpZ_x\xc7x\xfb\x90\xdeH\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xae\xf5\xb1\"X\xa1\x8d\xec\a\xd5\xec.1et\x91\x9dy\xd6\u0589lk\x93[\x8b\xbd@\x00\x00\u07d4\xae\xfc\xfe\x88\xc8&\xcc\xf11\xd5N\xb4\ua7b8\x0ea\xe1\xee%\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\xaf\x06\xf5\xfam\x12\x14\xecC\x96}\x1b\xd4\xdd\xe7J\xb8\x14\xa98\x89\x04\xc5>\xcd\xc1\x8a`\x00\x00\u07d4\xaf\x11H\xefl\x8e\x10=u0\xef\xc9\x16y\u026c'\x00\t\x93\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xaf >\"\x9d~mA\x9d\xf47\x8e\xa9\x87\x15Q_c\x14\x85\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94\xaf X\xc7(,\xf6|\x8c<\xf90\x13<\x89a|\xe7])\x8a\x01w\"J\xa8D\xc7 \x00\x00\u07d4\xaf&\xf7\u01bfE> x\xf0\x89S\u4c80\x04\xa2\xc1\xe2\t\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xaf0\x87\xe6.\x04\xbf\x90\rZT\xdc>\x94bt\u0692B;\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xaf6\x14\u0736\x8a6\xe4ZN\x91\x1ebybG\"-Y[\x89z\x81\x06_\x11\x03\xbc\x00\x00\u07d4\xaf6\x15\u01c9\u0431\x15*\xd4\xdb%\xfe]\xcf\"(\x04\xcfb\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xaf<\xb5\x96Y3\xe7\xda\u0603i;\x9c>\x15\xbe\xb6\x8aHs\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xafD\x93\xe8R\x1c\xa8\x9d\x95\xf5&|\x1a\xb6?\x9fEA\x1e\x1b\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xafL\xf4\x17\x85\x16\x1fW\x1d\f\xa6\x9c\x94\xf8\x02\x1fA)N\u028a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\xafR\x9b\xdbE\x9c\xc1\x85\xbe\xe5\xa1\u014b\xf7\xe8\xcc\xe2\\\x15\r\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xafg\xfd>\x12\u007f\xd9\xdc6\xeb?\xcdj\x80\u01feOu2\xb2\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4\xafw\x1094Z40\x01\xbc\x0f\x8aY#\xb1&\xb6\rP\x9c\x895e\x9e\xf9?\x0f\xc4\x00\x00\xe0\x94\xaf\u007fy\xcbAZ\x1f\xb8\u06fd\tF\a\xee\x8dA\xfb|Z;\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xaf\x87\xd27\x1e\xf3x\x95\u007f\xbd\x05\xba/\x1df\x93\x1b\x01\u2e09%\xf2s\x93=\xb5p\x00\x00\u07d4\xaf\x88\x0f\xc7V}U\x95\xca\xcc\xe1\\?\xc1L\x87B\xc2l\x9e\x89\a?u\u0460\x85\xba\x00\x00\u07d4\xaf\x8e\x1d\xcb1L\x95\r6\x87CM0\x98X\xe1\xa8s\x9c\u0509\x0e~\xeb\xa3A\vt\x00\x00\u07d4\xaf\x99-\xd6i\xc0\x88>U\x15\xd3\xf3\x11*\x13\xf6\x17\xa4\xc3g\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xaf\xa1\u056d8\xfe\xd4GY\xc0[\x89\x93\xc1\xaa\r\xac\xe1\x9f@\x89\x04V9\x18$O@\x00\x00\xe0\x94\xaf\xa59XnG\x19\x17J;F\xb9\xb3\xe6c\xa7\u0475\xb9\x87\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xaf\xa6\x94n\xff\xd5\xffS\x15O\x82\x01\x02S\xdfG\xae(\f\u0309j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xaf\xc8\xeb\u860b\xd4\x10Z\xccL\x01\x8eTj\x1e\x8f\x9cx\x88\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xaf\xcc}\xbb\x83V\xd8B\xd4:\xe7\xe2<\x84\"\xb0\"\xa3\b\x03\x8a\x06o\xfc\xbf\xd5\xe5\xa3\x00\x00\x00\u07d4\xaf\xd0\x19\xff6\xa0\x91U4ki\x97H\x15\xa1\xc9\x12\xc9\n\xa4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xaf\xda\xc5\xc1\xcbV\xe2E\xbfp3\x00f\xa8\x17\uabecL\u0449\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xaf\xdd\x1bxab\xb81~ \xf0\xe9y\xf4\xb2\xceHmv]\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xaf\xf1\x04Z\xdf'\xa1\xaa2\x94a\xb2M\xe1\xba\u950ai\x8b\x89\x01\u03c4\xa3\n\n\f\x00\x00\u07d4\xaf\xf1\a\x96\v~\xc3N\u0590\xb6e\x02M`\x83\x8c\x19\x0fp\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xaf\xf1\x1c\xcfi\x93\x04\xd5\xf5\x86*\xf8`\x83E\x1c&\xe7\x9a\xe5\x89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u07d4\xaf\xf1at\nm\x90\x9f\xe9\x9cY\xa9\xb7yE\xc9\x1c\xc9\x14H\x89\x03@\xaa\xd2\x1b;p\x00\x00\xe0\x94\xaf\xfc\x99\xd5\ubd28O\xe7x\x8d\x97\xdc\xe2t\xb08$\x048\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xaf\xfe\xa0G7\"\xcb\u007f\x0e\x0e\x86\xb9\xe1\x18\x83\xbfB\x8d\x8dT\x89i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94\xb0\t\x96\xb0Vn\xcb>rC\xb8\"y\x88\u0733R\xc2\x18\x99\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xb0\x1e8\x9b(\xa3\x1d\x8eI\x95\xbd\xd7\xd7\xc8\x1b\xee\xab\x1eA\x19\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb0-\x06(s3EE\u03a2\x92\x18\xe4\x05w`Y\x0ft#\x89\xac\xb6\xa1\xc7\xd9:\x88\x00\x00\u07d4\xb0/\xa2\x93\x87\xec\x12\xe3\u007fi\"\xacL\xe9\x8c[\t\xe0\xb0\x0f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb06\x91k\xda\u03d4\xb6\x9eZ\x8ae`)u\xeb\x02a\x04\u0749\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xb0A1\x0f\xe9\xee\u0586L\xed\u053e\xe5\x8d\xf8\x8e\xb4\xed<\xac\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xb0U\xafL\xad\xfc\xfd\xb4%\xcfe\xbad1\a\x8f\a\xec\u056b\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xb0W\x11S\xdb\x1cN\u05ec\xae\xfe\x13\xec\xdf\xdbr\xe7\xe4\xf0j\x8a\x11\f\xffyj\xc1\x95 \x00\x00\u07d4\xb0n\xab\t\xa6\x10\u01a5=V\xa9F\xb2\xc44\x87\xac\x1d[-\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb0rI\xe0U\x04J\x91U5\x9a@)7\xbb\xd9T\xfeH\xb6\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xb0v\x182\x8a\x90\x13\a\xa1\xb7\xa0\xd0X\xfc\xd5xn\x9er\xfe\x8a\x06gI]JC0\xce\x00\x00\u07d4\xb0y\xbbM\x98f\x14:m\xa7*\xe7\xac\x00\"\x06)\x811\\\x89)3\x1eeX\xf0\xe0\x00\x00\u07d4\xb0{\xcc\bZ\xb3\xf7)\xf2D\x00Ah7\xb6\x996\xba\x88s\x89lm\x84\xbc\xcd\xd9\xce\x00\x00\u07d4\xb0{\xcf\x1c\xc5\xd4F.Q$\xc9e\xec\xf0\xd7\r\xc2z\xcau\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\xb0|\xb9\xc1$\x05\xb7\x11\x80uC\u0113De\xf8\u007f\x98\xbd-\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xb0\u007f\u07af\xf9\x1dD`\xfel\xd0\u8870\xbd\x8d\"\xa6.\x87\x8a\x01\x1d%)\xf3SZ\xb0\x00\x00\xe0\x94\xb0\x9f\xe6\xd44\x9b\x99\xbc7\x93\x80T\x02-T\xfc\xa3f\xf7\xaf\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\xe0\x94\xb0\xaa\x00\x95\f\x0e\x81\xfa2\x10\x17>r\x9a\xaf\x16:'\xcdq\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xb0\xacN\xfff\x80\xee\x14\x16\x9c\xda\xdb\xff\xdb0\x80Om%\xf5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb0\xb3j\xf9\xae\xee\u07d7\xb6\xb0\"\x80\xf1\x14\xf19\x84\xea2`\x895e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\xb0\xb7y\xb9K\xfa<.\x1fX{\u031c~!x\x92\"7\x8f\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\xb0\xba\xeb0\xe3\x13wlLm$t\x02\xbaAg\xaf\u0361\u0309j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xb0\xbb)\xa8a\xea\x1dBME\xac\u053f\u0112\xfb\x8e\xd8\t\xb7\x89\x04V9\x18$O@\x00\x00\xe0\x94\xb0\xc1\xb1w\xa2 \xe4\x1f|t\xd0|\u0785i\xc2\x1cu\xc2\xf9\x8a\x01/\x93\x9c\x99\xed\xab\x80\x00\x00\u07d4\xb0\xc7\xceL\r\xc3\u00bb\xb9\x9c\xc1\x85{\x8aE_a\x17\x11\u0389\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb0\xce\xf8\xe8\xfb\x89\x84\xa6\x01\x9f\x01\xc6y\xf2r\xbb\xe6\x8f\\w\x89\b=lz\xabc`\x00\x00\xe0\x94\xb0\xd3+\xd7\xe4\u6577\xb0\x1a\xa3\xd0Ao\x80U}\xba\x99\x03\x8a\x03s\x9f\xf0\xf6\xe6\x130\x00\x00\xe0\x94\xb0\xd3\u0247+\x85\x05n\xa0\xc0\xe6\xd1\xec\xf7\xa7~<\u6ac5\x8a\x01\x0f\b\xed\xa8\xe5U\t\x80\x00\u07d4\xb0\xe4i\u0206Y8\x15\xb3IV8Y]\xae\xf0f_\xaeb\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xb0\xe7`\xbb\a\xc0\x81wsE\xe0W\x8e\x8b\u0218\"mN;\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb1\x040\x04\xec\x19A\xa8\xcfO+\x00\xb1W\x00\u076co\xf1~\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb1\x05\xdd=\x98|\xff\xd8\x13\xe9\xc8P\n\x80\xa1\xad%}V\u0189lj\xccg\u05f1\xd4\x00\x00\u07d4\xb1\x0f\u04a6G\x10/\x88\x1ft\xc9\xfb\xc3}\xa62\x94\x9f#u\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\xb1\x15\xee:\xb7d\x1e\x1a\xa6\xd0\x00\xe4\x1b\xfc\x1e\xc7!\f/2\x8a\x02\xc0\xbb=\xd3\fN \x00\x00\u07d4\xb1\x17\x8a\xd4s\x83\xc3\x1c\x814\xa1\x94\x1c\xbc\xd4t\xd0bD\xe2\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xb1\x17\x95\x89\u1779\xd4\x15W\xbb\xec\x1c\xb2L\xcc-\xec\x1c\u007f\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xb1\x19\u76a9\xb9\x16Re\x81\xcb\xf5!\xefGJ\xe8M\xcf\xf4\x89O\xba\x10\x01\xe5\xbe\xfe\x00\x00\u07d4\xb1\x1f\xa7\xfb'\n\xbc\xdfZ.\xab\x95\xaa0\u013566\uffc9+^:\xf1k\x18\x80\x00\x00\u07d4\xb1$\xbc\xb6\xff\xa40\xfc\xae.\x86\xb4_'\xe3\xf2\x1e\x81\xee\b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb1)\xa5\xcbq\x05\xfe\x81\v\u0615\xdcr\x06\xa9\x91\xa4TT\x88\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\xe0\x94\xb1.\xd0{\x8a8\xadU\x066?\xc0z\vmy\x996\xbd\xaf\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xb14\xc0\x049\x1a\xb4\x99(x3zQ\xec$/B(WB\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb1?\x93\xaf0\xe8\xd7fs\x81\xb2\xb9[\xc1\xa6\x99\xd5\xe3\xe1)\x89\x16\u012b\xbe\xbe\xa0\x10\x00\x00\u07d4\xb1E\x92\x85\x86>\xa2\xdb7Y\xe5F\u03b3\xfb7a\xf5\x90\x9c\x89<\xd7*\x89@\x87\xe0\x80\x00\u07d4\xb1F\xa0\xb9%U<\xf0o\xca\xf5J\x1bM\xfe\xa6!)\aW\x89lnY\xe6|xT\x00\x00\xe0\x94\xb1Jz\xaa\x8fI\xf2\xfb\x9a\x81\x02\u05bb\xe4\u010a\xe7\xc0o\xb2\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xb1K\xbe\xffpr\tu\xdca\x91\xb2\xa4O\xf4\x9f&r\x87<\x89\a\xc0\x86\x0eZ\x80\xdc\x00\x00\xe0\x94\xb1L\xc8\xde3\xd63\x826S\x9aH\x90 \xceFU\xa3+\u018a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xb1M\xdb\x03\x86\xfb`c\x98\xb8\xccGVZ\xfa\xe0\x0f\xf1\xd6j\x89\xa1*\xff\b>f\xf0\x00\x00\u07d4\xb1S\xf8(\xdd\amJ|\x1c%t\xbb-\xee\x1aD\xa3\x18\xa8\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb1T\x0e\x94\xcf\xf3F\\\xc3\u0447\xe7\xc8\u3f6f\x98FY\u2262\x15\xe4C\x90\xe33\x00\x00\u07d4\xb1X\xdbC\xfab\xd3\x0ee\xf3\u041b\xf7\x81\u01f6sr\uba89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u07d4\xb1ar_\xdc\xed\xd1yR\xd5{#\xef([~K\x11i\xe8\x89\x02\xb6\xdf\xed6d\x95\x80\x00\u07d4\xb1dy\xba\x8e}\xf8\xf6>\x1b\x95\xd1I\u0345)\xd75\xc2\u0689-\xe3:j\xac2T\x80\x00\u07d4\xb1f\xe3}.P\x1a\xe7<\x84\x14+_\xfbZ\xa6U\xddZ\x99\x89l]\xb2\xa4\xd8\x15\xdc\x00\x00\u07d4\xb1\x83\xeb\xeeO\xcbB\xc2 \xe4wt\xf5\x9dlT\xd5\xe3*\xb1\x89V\xf7\xa9\xc3<\x04\xd1\x00\x00\u07d4\xb1\x88\a\x84D\x02~8g\x98\xa8\xaehi\x89\x19\xd5\xcc#\r\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\xb1\x89j7\xe5\u0602Z-\x01vZ\xe5\xdeb\x99w\u0783R\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb1\x8eg\xa5\x05\n\x1d\xc9\xfb\x19\t\x19\xa3=\xa88\xefDP\x14\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb1\xa2\xb4:t3\xdd\x15\v\xb8\"'\xedQ\x9c\u05b1B\u04c2\x89\x94mb\rtK\x88\x00\x00\u07d4\xb1\xc0\u040b6\xe1\x84\xf9\x95*@7\xe3\xe5:f}\a\nN\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb1\xc3(\xfb\x98\xf2\xf1\x9a\xb6do\n|\x8cVo\xdaZ\x85@\x89\x87\x86x2n\xac\x90\x00\x00\xe0\x94\xb1\xc7Qxi9\xbb\xa0\xd6q\xa6w\xa1X\u01ab\xe7&^F\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xb1\xcdK\xdf\xd1\x04H\x9a\x02n\u025dYs\a\xa0By\xf1s\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xb1\u03d4\xf8\t\x15\x05\x05_\x01\n\xb4\xba\u0196\xe0\xca\x0fg\xa1\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xb1\u05b0\x1b\x94\xd8T\xfe\x8b7J\xa6^\x89\\\xf2*\xa2V\x0e\x892\xf5\x1e\u06ea\xa30\x00\x00\xe0\x94\xb1\u06e5%\v\xa9bWU$n\x06yg\xf2\xad/\a\x91\u078a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4\xb1\xe2\u0755\xe3\x9a\xe9w\\U\xae\xb1?\x12\xc2\xfa#0S\xba\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb1\xe6\xe8\x10\xc2J\xb0H\x8d\xe9\xe0\x1eWH7\x82\x9f|w\u0409\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb1\xe9\xc5\xf1\xd2\x1eauzk.\xe7Y\x13\xfcZ\x1aA\x01\u00c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xb2\x03\u049elV\xb9&\x99\u0139-\x1fo\x84d\x8d\xc4\u03fc\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb2\x16\xdcY\xe2|=ry\xf5\xcd[\xb2\xbe\u03f2`n\x14\u0649\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb2\x1byy\xbf|\\\xa0\x1f\xa8-\xd6@\xb4\x1c9\xe6\u01bcu\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xb2#\xbf\x1f\xbf\x80H\\\xa2\xb5V}\x98\xdb{\xc3SM\xd6i\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb2-PU\xd9b15\x96\x1ej\xbd'<\x90\xde\xea\x16\xa3\xe7\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xb2-\xad\xd7\xe1\xe0R2\xa927\xba\xed\x98\xe0\u07d2\xb1\x86\x9e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb24\x03_uDF<\xe1\xe2+\xc5S\x06F\x84\xc5\x13\xcdQ\x89\r\x89\xfa=\u010d\xcf\x00\x00\u07d4\xb2G\u03dcr\xecH*\xf3\xea\xa7Ye\x8fy=g\nW\f\x891p\x8a\xe0\x04T@\x00\x00\u07d4\xb2ghA\xee\x9f-1\xc1r\xe8#\x03\xb0\xfe\x9b\xbf\x9f\x1e\t\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb2y\xc7\xd3U\u0088\x03\x92\xaa\u046a!\xee\x86|;5\a\u07c9D[\xe3\xf2\uf1d4\x00\x00\u07d4\xb2|\x1a$ L\x1e\x11\x8du\x14\x9d\xd1\t1\x1e\a\xc0s\xab\x89\xa8\r$g~\xfe\xf0\x00\x00\u07d4\xb2\x81\x81\xa4X\xa4@\xf1\u01bb\x1d\xe8@\x02\x81\xa3\x14\x8fL5\x89\x14b\fW\xdd\xda\xe0\x00\x00\xe0\x94\xb2\x82E\x03|\xb1\x92\xf7W\x85\u02c6\xcb\xfe|\x93\r\xa2X\xb0\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\xb2\x87\xf7\xf8\xd8\u00c7,\x1bXk\xcd}\n\xed\xbf~s'2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb2\x8b\xb3\x9f4fQ|\xd4o\x97\x9c\xf5\x96S\xee}\x8f\x15.\x89\x18e\x01'\xcc=\xc8\x00\x00\u07d4\xb2\x8d\xbf\xc6I\x98\x94\xf7:q\xfa\xa0\n\xbe\x0fK\xc9\u045f*\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xb2\x96\x8f}5\xf2\b\x87\x161\xc6h{?=\xae\xab\xc6al\x89\bu\xc4\u007f(\x9fv\x00\x00\u07d4\xb2\x9f[|\x190\xd9\xf9z\x11^\x06pf\xf0\xb5M\xb4K;\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb2\xa1D\xb1\xeag\xb9Q\x0f\"g\xf9\xda9\xd3\xf9=\xe2fB\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb2\xa2\xc2\x11\x16\x12\xfb\x8b\xbb\x8e}\xd97\x8dg\xf1\xa3\x84\xf0P\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xb2\xa4\x98\xf0;\xd7\x17\x8b\u0627\x89\xa0\x0fR7\xafy\xa3\xe3\xf8\x8a\x04\x1b\xad\x15^e\x12 \x00\x00\u07d4\xb2\xaa/\x1f\x8e\x93\xe7\x97\x13\xd9,\xea\x9f\xfc\xe9\xa4\n\xf9\xc8-\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb2\xb5\x16\xfd\u045e\u007f8d\xb6\xd2\xcf\x1b%*AV\xf1\xb0;\x89\x02\xe9\x83\xc7a\x15\xfc\x00\x00\u07d4\xb2\xb7\u0374\xffKa\u0577\xce\v\"p\xbb\xb5&\x97C\xec\x04\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb2\xbd\xbe\u07d5\x90\x84v\xd7\x14\x8a7\f\u0193t6(\x05\u007f\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb2\xbf\xaaX\xb5\x19l\\\xb7\xf8\x9d\xe1_G\x9d\x188\xdeq=\x89\x01#n\xfc\xbc\xbb4\x00\x00\u07d4\xb2\xc5>\xfa3\xfeJ:\x1a\x80 \\s\xec;\x1d\xbc\xad\x06\x02\x89h\x01\u06b3Y\x18\x93\x80\x00\xe0\x94\xb2\xd06\x05\x15\xf1}\xab\xa9\x0f\u02ec\x82\x05\xd5i\xb9\x15\u05ac\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xb2\xd1\xe9\x9a\xf9\x121\x85\x8epe\xdd\x19\x183\r\xc4\xc7G\u054a\x03\x89O\x0eo\x9b\x9fp\x00\x00\u07d4\xb2\u066b\x96d\xbc\xf6\xdf <4o\u0192\xfd\x9c\xba\xb9 ^\x89\x17\xbex\x97`e\x18\x00\x00\u07d4\xb2\u0777\x86\xd3yN'\x01\x87\xd0E\x1a\xd6\u0237\x9e\x0e\x87E\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb2\xe0\x85\xfd\xdd\x14h\xba\aA['NsN\x11#\u007f\xb2\xa9\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xb2\xe9\xd7k\xf5\x0f\xc3k\xf7\u04d4Kc\xe9\u0288\x9bi\x99h\x89\x902\xeab\xb7K\x10\x00\x00\xe0\x94\xb2\xf9\xc9r\xc1\xe9swU\xb3\xff\x1b0\x88s\x83\x969[&\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xb2\xfc\x84\xa3\xe5\nP\xaf\x02\xf9M\xa08>\u055fq\xff\x01\u05ca\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4\xb3\x05\v\xef\xf9\xde3\xc8\x0e\x1f\xa1R%\xe2\x8f,A:\xe3\x13\x89%\xf2s\x93=\xb5p\x00\x00\u07d4\xb3\x11\x96qJH\xdf\xf7&\xea\x943\xcd)\x12\xf1\xa4\x14\xb3\xb3\x89\x91Hx\xa8\xc0^\xe0\x00\x00\xe0\x94\xb3\x14[tPm\x1a\x8d\x04|\xdc\xdcU9*{SPy\x9a\x8a\x1bb)t\x1c\r=]\x80\x00\u07d4\xb3 \x83H6\xd1\xdb\xfd\xa9\xe7\xa3\x18M\x1a\xd1\xfdC \xcc\xc0\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb3#\u073f.\xdd\xc58.\u4efb \x1c\xa3\x93\x1b\xe8\xb48\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xb3$\x00\xfd\x13\xc5P\t\x17\xcb\x03{)\xfe\"\xe7\xd5\"\x8f-\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xb3%gL\x01\xe3\xf7)\rR&3\x9f\xbe\xacg\xd2!'\x9f\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\xb3(%\xd5\xf3\xdb$\x9e\xf4\xe8\\\xc4\xf31S\x95\x89v\u8f09\x1b-\xf9\xd2\x19\xf5y\x80\x00\u07d4\xb3*\xf3\xd3\xe8\xd0u4I&To.2\x88{\xf9;\x16\xbd\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb3/\x1c&\x89\xa5\xcey\xf1\xbc\x97\v1XO\x1b\xcf\"\x83\xe7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb3<\x03#\xfb\xf9\xc2l\x1d\x8a\xc4N\xf7C\x91\u0400F\x96\u0689\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xb3O\x04\xb8\xdbe\xbb\xa9\xc2n\xfcL\xe6\xef\xc5\x04\x81\xf3\xd6]\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xb3U}9\xb5A\x1b\x84D__T\xf3\x8fb\xd2qM\x00\x87\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xb3X\xe9|p\xb6\x05\xb1\xd7\xd7)\u07f6@\xb4<^\xaf\xd1\xe7\x8a\x04<3\xc1\x93ud\x80\x00\x00\u0794\xb3^\x8a\x1c\r\xac~\x0ef\u06ecsjY*\xbdD\x01%a\x88\xcf\xceU\xaa\x12\xb3\x00\x00\xe0\x94\xb3fx\x94\xb7\x86<\x06\x8a\xd3D\x87?\xcf\xf4\xb5g\x1e\x06\x89\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xb3qw1\xda\xd6Q2\xday-\x87`0\xe4j\xc2'\xbb\x8a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb3s\x1b\x04l\x8a\u0195\xa1'\xfdy\u0425\xd5\xfaj\xe6\xd1.\x89lO\xd1\xee$nx\x00\x00\u07d4\xb3|+\x9fPc{\xec\xe0\u0295\x92\b\xae\xfe\xe6F;\xa7 \x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb3\x88\xb5\xdf\xec\xd2\xc5\u4d56W|d%V\xdb\xfe'xU\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb3\x8cNS{]\xf90\xd6Zt\xd0C\x83\x1dkH[\xbd\xe4\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xb3\x919Wa\x94\xa0\x86a\x95\x15\x1f3\xf2\x14\n\xd1\u0306\u03ca\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xb3\x9fL\x00\xb2c\f\xab}\xb7)^\xf4=G\xd5\x01\xe1\u007f\u05c9\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb3\xa6K\x11vrOT\t\xe1AJ5#f\x1b\xae\xe7KJ\x89\x01ch\xffO\xf9\xc1\x00\x00\u07d4\xb3\xa6\xbdA\xf9\xd9\xc3 \x1e\x05\v\x87\x19\x8f\xbd\xa3\x994\"\x10\x89\xc4a\xe1\xdd\x10)\xb5\x80\x00\u07d4\xb3\xa8\xc2\xcb}5\x8eW9\x94\x1d\x94[\xa9\x04Z\x02:\x8b\xbb\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb3\xaeT\xfb\xa0\x9d>\xe1\u05bd\xd1\xe9W\x929\x19\x02L5\xfa\x89\x03\x8d,\xeee\xb2*\x80\x00\u07d4\xb3\xb7\xf4\x93\xb4J,\x8d\x80\xecx\xb1\xcd\xc7Ze+s\xb0l\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb3\xc2(s\x1d\x18m-\xed[_\xbe\x00Lfl\x8eF\x9b\x86\x89\x01\x92t\xb2Y\xf6T\x00\x00\u07d4\xb3\xc2``\x9b\x9d\xf4\t^l]\xff9\x8e\xeb^-\xf4\x99\x85\x89\r\xc5_\xdb\x17d{\x00\x00\u07d4\xb3\xc6[\x84Z\xbal\xd8\x16\xfb\xaa\xe9\x83\xe0\xe4l\x82\xaa\x86\"\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb3\xc9H\x11\xe7\x17[\x14\x8b(\x1c\x1a\x84[\xfc\x9b\xb6\xfb\xc1\x15\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb3\xe2\x0e\xb4\xde\x18\xbd\x06\x02!h\x98\x94\xbe\u5bb2SQ\xee\x89\x03\xfc\x80\xcc\xe5\x16Y\x80\x00\u07d4\xb3\xe3\xc49\x06\x98\x80\x15f\x00\u0089.D\x8dA6\xc9-\x9b\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\xe0\x94\xb3\xf8*\x87\xe5\x9a9\xd0\u0480\x8f\aQ\xebr\xc22\x9c\xdc\u014a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xb3\xfc\x1dh\x81\xab\xfc\xb8\xbe\xcc\v\xb0!\xb8\xb7;r3\u0751\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\xb4\x05\x94\xc4\xf3fN\xf8I\u0326\"{\x8a%\xaai\t%\xee\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb4\x1e\xaf]Q\xa5\xba\x1b\xa3\x9b\xb4\x18\u06f5O\xabu\x0e\xfb\x1f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb4$\u058d\x9d\r\x00\xce\xc1\x93\x8c\x85N\x15\xff\xb8\x80\xba\x01p\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb4%bs\x96+\xf61\xd0\x14U\\\xc1\xda\r\xcc1akI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb40g\xfep\u0675Ys\xbaX\xdcd\xdd\u007f1\x1eUBY\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb46W\xa5\x0e\xec\xbc0w\xe0\x05\xd8\xf8\xd9O7xv\xba\u0509\x01\xec\x1b:\x1f\xf7Z\x00\x00\u07d4\xb4<'\xf7\xa0\xa1\"\bK\x98\xf4\x83\x92%A\u0203l\xee,\x89&\u009eG\u0104L\x00\x00\xe0\x94\xb4A5v\x86\x9c\b\xf9Q*\xd3\x11\xfe\x92Y\x88\xa5-4\x14\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xb4F\x05U$q\xa6\xee\xe4\u06abq\xff;\xb4\x13&\xd4s\xe0\x89-~=Q\xbaS\xd0\x00\x00\u07d4\xb4GW\x1d\xac\xbb>\u02f6\xd1\xcf\v\f\x8f88\xe5#$\xe2\x89\x01\xa3\x18f\u007f\xb4\x05\x80\x00\u07d4\xb4G\x83\xc8\xe5{H\a\x93\xcb\u059aE\xd9\f{O\fH\xac\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb4H\x15\xa0\xf2\x8eV\x9d\x0e\x92\x1aJ\u078f\xb2d%&Iz\x89\x03\x027\x9b\xf2\xca.\x00\x00\u07d4\xb4Im\xdb'y\x9a\"$W\xd79y\x11g(\u8844[\x89\x8d\x81\x9e\xa6_\xa6/\x80\x00\xe0\x94\xb4RL\x95\xa7\x86\x0e!\x84\x02\x96\xa6\x16$@\x19B\x1cJ\xba\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xb4\\\xca\r6\x82fbh<\xf7\u0432\xfd\xach\u007f\x02\xd0\u010965\u026d\xc5\u07a0\x00\x00\u0794\xb4d@\u01d7\xa5V\xe0L}\x91\x04f\x04\x91\xf9k\xb0v\xbf\x88\xce\xc7o\x0eqR\x00\x00\u07d4\xb4j\u0386^,P\xeaF\x98\xd2\x16\xabE]\xffZ\x11\xcdr\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb4m\x11\x82\xe5\xaa\xca\xff\r&\xb2\xfc\xf7/<\x9f\xfb\xcd\xd9}\x89\xaa*`<\xdd\u007f,\x00\x00\u07d4\xb4\x89!\xc9h}U\x10tE\x84\x93n\x88\x86\xbd\xbf-\xf6\x9b\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb4\x98\xbb\x0fR\x00\x05\xb6!jD%\xb7Z\xa9\xad\xc5-b+\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xb4\xb1\x1d\x10\x9f`\x8f\xa8\xed\xd3\xfe\xa9\xf8\xc3\x15d\x9a\xeb=\x11\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xb4\xb1K\xf4TU\u042b\b\x035\x8bu$\xa7+\xe1\xa2\x04[\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xb4\xb1\x85\xd9C\xee+Xc\x1e3\xdf\xf5\xafhT\xc1y\x93\xac\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb4\xbf$\u02c3hk\xc4i\x86\x9f\xef\xb0D\xb9\tqi\x93\xe2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb4\xc2\x00@\xcc\u0661\xa3(=\xa4\u0522\xf3e\x82\bC\xd7\xe2\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb4\xc8\x17\x0f{*\xb56\xd1\u0662[\xdd :\xe1(\x8d\xc3\u0549\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb4\xd8/.i\x94?}\xe0\xf5\xf7t8y@o\xac.\x9c\xec\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\xb4\xddF\f\xd0\x16rZd\xb2.\xa4\xf8\xe0n\x06gN\x03>\x8a\x01#\x1b\xb8t\x85G\xa8\x00\x00\u07d4\xb4\xddT\x99\xda\xeb%\a\xfb-\xe1\"\x97s\x1dLr\xb1k\xb0\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xb5\x04l\xb3\xdc\x1d\xed\xbd6E\x14\xa2\x84\x8eD\xc1\xdeN\xd1G\x8a\x03{}\x9b\xb8 @^\x00\x00\xe0\x94\xb5\b\xf9\x87\xb2\xde4\xaeL\xf1\x93\u0785\xbf\xf6\x13\x89b\x1f\x88\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xb5\tU\xaan4\x15q\x98f\b\xbd\u0211\xc2\x13\x9fT\f\u07c9j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xb5\f\x14\x9a\x19\x06\xfa\xd2xo\xfb\x13Z\xabP\x177\xe9\xe5o\x89\x15\b\x94\xe8I\xb3\x90\x00\x00\u07d4\xb5\f\x9fW\x89\xaeD\xe2\xdc\xe0\x17\xc7\x14\xca\xf0\f\x83\x00\x84\u0089\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\xb5\x14\x88,\x97\x9b\xb6B\xa8\r\u04c7T\u0578\xc8)m\x9a\a\x893\xc5I\x901r\f\x00\x00\u07d4\xb5\x1d\u0734\xddN\x8a\xe6\xbe3m\xd9eIq\xd9\xfe\xc8kA\x89\x16\xd4d\xf8=\u2500\x00\u07d4\xb5\x1eU\x8e\xb5Q/\xbc\xfa\x81\xf8\u043d\x93\x8cy\xeb\xb5$+\x89&\u009eG\u0104L\x00\x00\u07d4\xb5#\xff\xf9t\x98q\xb3S\x88C\x887\xf7\xe6\xe0\u07a9\xcbk\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xb5-\xfbE\xde]t\xe3\xdf \x832\xbcW\x1c\x80\x9b\x8d\xcf2\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xb55\xf8\u06c7\x9f\xc6\u007f\xecX\x82J\\\xbenT\x98\xab\xa6\x92\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\xb57\xd3jp\xee\xb8\xd3\xe5\xc8\r\xe8\x15\"\\\x11X\u02d2\u0109QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\xb5;\xcb\x17L%\x184\x8b\x81\x8a\xec\xe0 6E\x96Fk\xa3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5I>\xf1srDE\xcf4\\\x03]'\x9b\xa7Y\xf2\x8dQ\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb5S\xd2]kT!\xe8\x1c*\xd0^\v\x8b\xa7Q\xf8\xf0\x10\xe3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5Tt\xbaX\xf0\xf2\xf4\x0el\xba\xbe\xd4\xea\x17n\x01\x1f\xca\u0589j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xb5U\xd0\x0f\x91\x90\xcc6w\xae\xf3\x14\xac\xd7?\xdc99\x92Y\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5W\xab\x949\xefP\xd27\xb5S\xf0%\b6JFj\\\x03\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb5jx\x00(\x03\x9c\x81\xca\xf3{gu\xc6 \u7195Gd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5j\u04ae\xc6\xc8\xc3\xf1\x9e\x15\x15\xbb\xb7\u0751(RV\xb69\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb5t\x13\x06\n\xf3\xf1N\xb4y\x06_\x1e\x9d\x19\xb3uz\xe8\u0309\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xb5uI\xbf\xbc\x9b\xdd\x18\xf76\xb2&P\xe4\x8as`\x1f\xa6\\\x89\x18-~L\xfd\xa08\x00\x00\xe0\x94\xb5w\xb6\xbe\xfa\x05N\x9c\x04\x04a\x85P\x94\xb0\x02\xd7\xf5{\u05ca\x18#\xf3\xcfb\x1d#@\x00\x00\u07d4\xb5{\x04\xfa#\xd1 ?\xae\x06\x1e\xacEB\xcb`\xf3\xa5v7\x89\nZ\xa8P\t\xe3\x9c\x00\x00\u07d4\xb5\x87\f\xe3B\xd43C36s\x03\x8bGd\xa4n\x92_>\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb5\x87\xb4J,\xa7\x9eK\xc1\u074b\xfd\xd4: qP\xf2\xe7\xe0\x89\",\x8e\xb3\xfff@\x00\x00\u07d4\xb5\x89gm\x15\xa0DH4B0\xd4\xff'\xc9^\xdf\x12,I\x8965\u026d\xc5\u07a0\x00\x00\u0794\xb5\x8bR\x86^\xa5]\x806\xf2\xfa\xb2`\x98\xb3R\u0283~\x18\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xb5\x90k\n\u9881X\xe8\xacU\x0e9\xda\bn\xe3\x15v#\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb5\xa4g\x96\x85\xfa\x14\x19l.\x920\xc8\xc4\xe3;\xff\xbc\x10\xe2\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xb5\xa5\x89\u075f@q\u06f6\xfb\xa8\x9b?]]\xae}\x96\xc1c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5\xa6\x06\xf4\xdd\u02f9G\x1e\xc6\u007fe\x8c\xaf+\x00\xees\x02^\x89\xeaun\xa9*\xfct\x00\x00\u07d4\xb5\xadQW\u0769!\xe6\xba\xfa\u0350\x86\xaes\xae\x1fa\x1d?\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb5\xad\xd1\u701f}\x03\x06\x9b\xfe\x88;\n\x93\"\x10\xbe\x87\x12\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb5\xba)\x91|x\xa1\xd9\xe5\xc5\xc7\x13fl\x1eA\x1d\u007fi:\x89\xa8\r$g~\xfe\xf0\x00\x00\u07d4\xb5\xc8\x16\xa8(<\xa4\xdfh\xa1\xa7=c\xbd\x80&\x04\x88\xdf\b\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb5\xca\xc5\xed\x03G}9\v\xb2g\xd4\xeb\xd4a\x01\xfb\xc2\xc3\u0689\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xb5\u037cA\x15@oR\u5a85\xd0\xfe\xa1p\u0497\x9c\u01fa\x89Hz\x9a0E9D\x00\x00\u0794\xb5\u0653M{)+\xcf`;(\x80t\x1e\xb7`(\x83\x83\xa0\x88\xe7\xc2Q\x85\x05\x06\x00\x00\u07d4\xb5\xddP\xa1]\xa3Ih\x89\nS\xb4\xf1?\xe1\xaf\b\x1b\xaa\xaa\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb5\xfa\x81\x84\xe4>\xd3\u0e2b\x91!da\xb3R\x8d\x84\xfd\t\x89\x91Hx\xa8\xc0^\xe0\x00\x00\u07d4\xb5\xfb~\xa2\xdd\xc1Y\x8bfz\x9dW\xdd9\xe8Z8\xf3]V\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xb6\x00B\x97R\xf3\x99\xc8\r\a4tK\xae\n\x02.\xcag\u0189\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb6\x00\xfe\xabJ\xa9lSu\x04\xd9`W\"1Ai,\x19:\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xb6\x04|\u07d3-\xb3\xe4\x04_Iv\x12#AS~\u0556\x1e\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb6\x15\xe9@\x14>\xb5\u007f\x87X\x93\xbc\x98\xa6\x1b=a\x8c\x1e\x8c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xb6\x1c4\xfc\xac\xdap\x1aZ\xa8p$Y\u07b0\u4b83\x8d\xf8\x8a\aiZ\x92\xc2\ro\xe0\x00\x00\xe0\x94\xb60d\xbd3U\xe6\xe0~-7p$\x12Z3wlJ\xfa\x8a\b7Z*\xbc\xca$@\x00\x00\u07d4\xb65\xa4\xbcq\xfb(\xfd\xd5\xd2\xc3\"\x98:V\u0084Bni\x89\t79SM(h\x00\x00\u07d4\xb6F\u07d8\xb4\x94BtkaR\\\x81\xa3\xb0K\xa3\x10bP\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xb6YA\xd4LP\xd2Ffg\r6Gf\xe9\x91\xc0.\x11\u0089 \x86\xac5\x10R`\x00\x00\xe0\x94\xb6[\u05c0\xc7CA\x15\x16 'VR#\xf4NT\x98\xff\x8c\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4\xb6d\x11\xe3\xa0-\xed\xb7&\xfay\x10}\xc9\v\xc1\xca\xe6MH\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb6fu\x14.1\x11\xa1\xc2\xea\x1e\xb2A\x9c\xfaB\xaa\xf7\xa24\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xb6o\x92\x12K^c\x03XY\xe3\x90b\x88i\xdb\u07a9H^\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\xb6rsJ\xfc\xc2$\xe2\xe6\t\xfcQ\xd4\xf0Ys'D\xc9H\x89\x10\x04\xe2\xe4_\xb7\xee\x00\x00\xe0\x94\xb6w\x1b\v\xf3B\u007f\x9a\xe7\xa9>|.a\xeec\x94\x1f\xdb\b\x8a\x03\xfb&i)T\xbf\xc0\x00\x00\u07d4\xb6z\x80\xf1p\x19}\x96\xcd\xccJ\xb6\u02e6'\xb4\xaf\xa6\xe1,\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\xb6\x88\x99\xe7a\rL\x93\xa255\xbc\xc4H\x94[\xa1fo\x1c\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb6\xa8)3\xc9\xea\u06bd\x98\x1e]m`\xa6\x81\x8f\xf8\x06\xe3k\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xb6\xaa\u02cc\xb3\v\xab*\xe4\xa2BF&\xe6\xe1+\x02\xd0F\x05\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xb6\xb3J&?\x10\xc3\xd2\xec\xeb\n\xccU\x9a{*\xb8\\\xe5e\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb6\xbf\xe1\xc3\xef\x94\xe1\x84o\xb9\xe3\xac\xfe\x9bP\xc3\xe9\x06\x923\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xb6\xcdt2\xd5\x16\x1b\xe7\x97h\xadE\xde>Dz\a\x98 c\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb6\xceM\xc5`\xfcs\xdci\xfbzb\xe3\x88\xdb~r\xeavO\x894]\xf1i\xe9\xa3X\x00\x00\u07d4\xb6\xde\u03c2\x96\x98\x19\xba\x02\xde)\xb9\xb5\x93\xf2\x1bd\xee\xda\x0f\x89(\x1d\x90\x1fO\xdd\x10\x00\x00\xe0\x94\xb6\xe6\xc3\"+ko\x9b\xe2\x87]*\x89\xf1'\xfbd\x10\x0f\xe2\x8a\x01\xb2\x1dS#\xcc0 \x00\x00\u07d4\xb6\xe8\xaf\xd9=\xfa\x9a\xf2\u007f9\xb4\xdf\x06\ag\x10\xbe\xe3\u07eb\x89\x01Z\xf1\u05cbX\xc4\x00\x00\xe0\x94\xb6\xf7\x8d\xa4\xf4\xd0A\xb3\xbc\x14\xbc[\xa5\x19\xa5\xba\f2\xf1(\x8a$}\xd3,?\xe1\x95\x04\x80\x00\xe0\x94\xb6\xfb9xbP\b\x14&\xa3B\xc7\rG\xeeR\x1e[\xc5c\x8a\x03-&\xd1.\x98\v`\x00\x00\u07d4\xb7\r\xba\x93\x91h+J6Nw\xfe\x99%c\x01\xa6\xc0\xbf\x1f\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb7\x16#\xf3Q\a\xcft1\xa8?\xb3\xd2\x04\xb2\x9e\u0c67\xf4\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xb7\x1a\x13\xba\x8e\x95\x16{\x803\x1bR\u059e7\x05O\xe7\xa8&\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb7\x1bb\xf4\xb4H\xc0+\x12\x01\xcb^9J\xe6'\xb0\xa5`\xee\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xb7\" \xad\xe3d\xd06\x9f--\xa7\x83\xcaGM{\x9b4\u0389\x1b\x1a\xb3\x19\xf5\xecu\x00\x00\xe0\x94\xb7#\r\x1d\x1f\xf2\xac\xa3f\x969\x14\xa7\x9d\xf9\xf7\xc5\xea,\x98\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94\xb7$\n\U000af433<\b\xae\x97d\x10>5\xdc\xe3c\x84(\x8a\x01\xca\xdd/\xe9hnc\x80\x00\u07d4\xb7'\xa9\xfc\x82\xe1\xcf\xfc\\\x17_\xa1HZ\x9b\xef\xa2\u037d\u04496'\xe8\xf7\x127<\x00\x00\u07d4\xb7,*\x01\x1c\r\xf5\x0f\xbbn(\xb2\n\xe1\xaa\xd2\x17\x88g\x90\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb78-7\xdb\x03\x98\xacrA\f\xf9\x81=\xe9\xf8\xe1\uc36d\x8966\xc2^f\xec\xe7\x00\x00\u07d4\xb7;O\xf9\x9e\xb8\x8f\u061b\vmW\xa9\xbc3\x8e\x88o\xa0j\x89\x01\xbc\x16\xd6t\xec\x80\x00\x00\u07d4\xb7=jwU\x9c\x86\xcfet$)\x039K\xac\xf9n5p\x89\x04\xf1\xa7|\xcd;\xa0\x00\x00\u07d4\xb7Cr\xdb\xfa\x18\x1d\xc9$/9\xbf\x1d71\xdf\xfe+\xda\u03c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xb7G\x9d\xabP\"\xc4\xd5\u06ea\xf8\xde\x17\x1bN\x95\x1d\u0464W\x89\x04V9\x18$O@\x00\x00\u07d4\xb7I\xb5N\x04\u0571\x9b\xdc\xed\xfb\x84\xdaw\x01\xabG\x8c'\xae\x89\x91Hx\xa8\xc0^\xe0\x00\x00\u07d4\xb7N\xd2f`\x01\xc1c3\xcfz\xf5\x9eJ=H`6;\x9c\x89\n~\xbd^Cc\xa0\x00\x00\u07d4\xb7QI\xe1\x85\xf6\xe3\x92pWs\x90s\xa1\x82*\xe1\xcf\r\xf2\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\xb7S\xa7_\x9e\xd1\v!d:\n=\xc0Qz\xc9k\x1a@h\x89\x15\xc8\x18[,\x1f\xf4\x00\x00\xe0\x94\xb7V\xadR\xf3\xbft\xa7\xd2LgG\x1e\b\x87Ci6PL\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xb7Wn\x9d1M\xf4\x1e\xc5Pd\x94):\xfb\x1b\xd5\xd3\xf6]\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb7X\x89o\x1b\xaa\x86O\x17\xeb\xed\x16\xd9S\x88o\xeeh\xaa\xe6\x8965\u026d\xc5\u07a0\x00\x00\u0794\xb7h\xb5#N\xba:\x99h\xb3Mm\xdbH\x1c\x84\x19\xb3e]\x88\xcf\xceU\xaa\x12\xb3\x00\x00\u07d4\xb7\x82\xbf\xd1\xe2\xdep\xf4gdo\x9b\xc0\x9e\xa5\xb1\xfc\xf4P\xaf\x89\x0e~\xeb\xa3A\vt\x00\x00\xe0\x94\xb7\xa2\xc1\x03r\x8bs\x05\xb5\xaen\x96\x1c\x94\xee\x99\xc9\xfe\x8e+\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\xb7\xa3\x1a|8\xf3\xdb\t2.\xae\x11\xd2'!A\xea\"\x99\x02\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb7\xa6y\x1c\x16\xebN!b\xf1Ke7\xa0+=c\xbf\xc6\x02\x89*Rc\x91\xac\x93v\x00\x00\u07d4\xb7\xa7\xf7|4\x8f\x92\xa9\xf1\x10\fk\xd8)\xa8\xacm\u007f\u03d1\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xb7\xc0w\x94ft\xba\x93A\xfbLtz]P\xf5\xd2\xdad\x15\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xb7\xc0\xd0\xcc\vM4-@b\xba\xc6$\xcc\xc3\xc7\f\xc6\xda?\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xb7\xc9\xf1+\x03\x8esCm\x17\xe1\xc1/\xfe\x1a\xec\u0373\xf5\x8c\x89\x1dF\x01b\xf5\x16\xf0\x00\x00\u07d4\xb7\xcck\x1a\xcc2\u0632\x95\xdfh\xed\x9d^`\xb8\xf6L\xb6{\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xb7\xcehK\t\xab\xdaS8\x9a\x87Si\xf7\x19X\xae\xac;\u0749lk\x93[\x8b\xbd@\x00\x00\u07d4\xb7\xd1.\x84\xa2\xe4\u01264Z\xf1\xdd\x1d\xa9\xf2PJ*\x99n\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xb7\xd2R\xee\x94\x02\xb0\xee\xf1D)_\x0ei\xf0\xdbXl\bq\x89#\xc7W\a+\x8d\xd0\x00\x00\xe0\x94\xb7\u0541\xfe\n\xf1\xec8?;\xce\x00\xaf\x91\x99\xf3\xcf_\xe0\xcc\xe2\x8c\xd1J\x89\xcf\x15&@\xc5\xc80\x00\x00\u07d4\xb8R\x18\xf3B\xf8\x01.\u069f'Nc\xce!R\xb2\xdc\xfd\xab\x89\xa8\r$g~\xfe\xf0\x00\x00\u07d4\xb8UP\x10wn<\\\xb3\x11\xa5\xad\xee\xfe\x9e\x92\xbb\x9ad\xb9\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xb8_&\xdd\x0er\xd9\u009e\xba\xf6\x97\xa8\xafwG,+X\xb5\x8a\x02\x85\x19\xac\xc7\x19\fp\x00\x00\u07d4\xb8_\xf0>{_\xc4\"\x98\x1f\xae^\x99A\xda\xcb\u06bau\x84\x89Hz\x9a0E9D\x00\x00\xe0\x94\xb8f\a\x02\x1bb\xd3@\xcf&R\xf3\xf9_\xd2\xdcgi\x8b\u07ca\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xb8}\xe1\xbc\u0492i\xd5!\xb8v\x1c\u00dc\xfbC\x19\xd2\xea\u054965\u026d\xc5\u07a0\x00\x00\u07d4\xb8\u007fSv\xc2\xde\vl\xc3\xc1y\xc0`\x87\xaaG=kFt\x89Hz\x9a0E9D\x00\x00\u07d4\xb8\x84\xad\u060d\x83\xdcVJ\xb8\xe0\xe0,\xbd\xb69\x19\xae\xa8D\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb8\x8a7\xc2\u007fx\xa6\x17\xd5\xc0\x91\xb7\u0577:7a\xe6_*\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb8\x94x\"\u056c\u79ad\x83&\xe9T\x96\"\x1e\v\xe6\xb7=\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb8\x9c\x03n\xd7\u0112\x87\x99!\xbeA\xe1\f\xa1i\x81\x98\xa7L\x89b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x94\xb8\x9fF2\xdfY\t\xe5\x8b*\x99d\xf7O\xeb\x9a;\x01\xe0\u014a\x04\x88u\xbc\xc6\xe7\xcb\xeb\x80\x00\u07d4\xb8\xa7\x9c\x84\x94^G\xa9\xc3C\x86\x83\u05b5\x84,\xffv\x84\xb1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xb8\xa9y5'Y\xba\t\xe3Z\xa5\x93]\xf1u\xbf\xf6x\xa1\b\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xb8\xab9\x80[\xd8!\x18Ol\xbd=$s4{\x12\xbf\x17\\\x89\x06hZ\xc1\xbf\xe3,\x00\x00\xe0\x94\xb8\xac\x11}\x9f\r\xba\x80\x90\x14E\x82:\x92\x11\x03\xa51o\x85Zew\x9d\x1b\x8a\x05\x15\n\xe8J\x8c\xdf\x00\x00\x00\u07d4\xb9\xe9\f\x11\x92\xb3\xd5\xd3\xe3\xab\a\x00\xf1\xbfe_]\xd44z\x89\x1b\x19\xe5\vD\x97|\x00\x00\u07d4\xb9\xfd83\xe8\x8e|\xf1\xfa\x98y\xbd\xf5Z\xf4\xb9\x9c\xd5\xce?\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xba\x02I\xe0\x1d\x94[\xef\x93\xee^\xc6\x19%\xe0<\\\xa5\t\xfd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xba\x0f9\x02;\xdb)\xeb\x18b\xa9\xf9\x05\x9c\xab]0nf/\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xba\x10\xf2vB\x90\xf8uCCr\xf7\x9d\xbfq8\x01\u02ac\x01\x893\xc5I\x901r\f\x00\x00\u07d4\xba\x151\xfb\x9ey\x18\x96\xbc\xf3\xa8\x05X\xa3Y\xf6\xe7\xc1D\xbd\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\xba\x17m\xbe2I\xe3E\xcdO\xa9g\xc0\xed\x13\xb2LG\u5189\x15\xae\xf9\xf1\xc3\x1c\u007f\x00\x00\xe0\x94\xba\x1f\x0e\x03\u02da\xa0!\xf4\xdc\xeb\xfa\x94\xe5\u0209\xc9\u01fc\x9e\x8a\x06\u0450\xc4u\x16\x9a \x00\x00\u07d4\xba\x1f\xca\xf2#\x93~\xf8\x9e\x85gU\x03\xbd\xb7\xcaj\x92\x8bx\x89\"\xb1\xc8\xc1\"z\x00\x00\x00\xe0\x94\xba$\xfcCgS\xa79\xdb,\x8d@\xe6\xd4\xd0LR\x8e\x86\xfa\x8a\x02\xc0\xbb=\xd3\fN \x00\x00\u07d4\xbaB\xf9\xaa\xceL\x18E\x04\xab\xf5BWb\xac\xa2oq\xfb\u0709\x02\a\a}\u0627\x9c\x00\x00\u07d4\xbaF\x9a\xa5\u00c6\xb1\x92\x95\u0521\xb5G;T\x03S9\f\x85\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbad@\xae\xb3s{\x8e\xf0\xf1\xaf\x9b\f\x15\xf4\xc2\x14\xff\xc7\u03c965\u026d\xc5\u07a0\x00\x00\xe0\x94\xbam1\xb9\xa2a\xd6@\xb5\u07a5\x1e\xf2\x16,1\t\xf1\uba0a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xbap\xe8\xb4u\x9c\f<\x82\xcc\x00\xacN\x9a\x94\xdd[\xaf\xb2\xb8\x890C\xfa3\xc4\x12\xd7\x00\x00\u07d4\xba\x8ac\xf3\xf4\r\u4a03\x88\xbcP!/\xea\x8e\x06O\xbb\x86\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xba\x8eF\u059d.#C\xd8l`\xd8,\xf4, A\xa0\xc1\u0089\x05k\xc7^-c\x10\x00\x00\u07d4\xba\xa4\xb6L+\x15\xb7\x9f_ BF\xfdp\xbc\xbd\x86\xe4\xa9*\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xba\u0212,J\xcc},\xb6\xfdY\xa1N\xb4\\\xf3\xe7\x02!K\x89+^:\xf1k\x18\x80\x00\x00\u07d4\xba\xd25\xd5\b]\u01f0h\xa6|A&w\xb0>\x186\x88L\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xba\xd4B^\x17\x1c>r\x97^\xb4j\xc0\xa0\x15\xdb1Z]\x8f\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xba\xdc*\xef\x9fYQ\xa8\u05cak5\xc3\u0433\xa4\xe6\xe2\xe79\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xba\xdeCY\x9e\x02\xf8OL0\x14W\x1c\x97k\x13\xa3le\xab\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xba\xe9\xb8/r\x99c\x14\be\x9d\xd7N\x89\x1c\xb8\xf3\x86\x0f\xe5\x89j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94\xbb\x03f\xa7\u03fd4E\xa7\r\xb7\xfeZ\xe3H\x85uO\xd4h\x8a\x01M\xef,B\xeb\xd6@\x00\x00\u07d4\xbb\aj\xac\x92 \x80i\xea1\x8a1\xff\x8e\xeb\x14\xb7\xe9\x96\xe3\x89\b\x13\xcaV\x90m4\x00\x00\u07d4\xbb\bW\xf1\xc9\x11\xb2K\x86\u0227\x06\x81G?\u6aa1\xcc\xe2\x89\x05k\xc7^-c\x10\x00\x00\u0794\xbb\x19\xbf\x91\u02edt\xcc\xeb_\x81\x1d\xb2~A\x1b\xc2\xea\x06V\x88\xf4?\xc2\xc0N\xe0\x00\x00\xe0\x94\xbb'\u01a7\xf9\x10uGZ\xb2)a\x90@\xf8\x04\xc8\xeczj\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xbb7\x1cr\xc9\xf01l\xea+\xd9\xc6\xfb\xb4\a\x9ewT)\xef\x89_h\xe8\x13\x1e\u03c0\x00\x00\xe0\x94\xbb;\x01\v\x18\xe6\xe2\xbe\x115\x87\x10&\xb7\xba\x15\xea\x0f\xde$\x8a\x02 |\x800\x9bwp\x00\x00\xe0\x94\xbb;\x90\x05\xf4o\xd2\xca;0\x16%\x99\x92\x8cw\xd9\xf6\xb6\x01\x8a\x01\xb1\xae\u007f+\x1b\xf7\xdb\x00\x00\u07d4\xbb?\xc0\xa2\x9c\x03Mq\b\x12\xdc\xc7u\xc8\u02b9\u048diu\x899\xd4\xe8D\xd1\xcf_\x00\x00\u07d4\xbbH\xea\xf5\x16\xce-\xec>A\xfe\xb4\xc6y\xe4\x95vA\x16O\x89\xcf\x15&@\xc5\xc80\x00\x00\u07d4\xbbKJKT\x80p\xffAC,\x9e\b\xa0\xcao\xa7\xbc\x9fv\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\u07d4\xbbV\xa4\x04r<\xff \xd0hT\x88\xb0Z\x02\xcd\xc3Z\xac\xaa\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xbba\x8e%\"\x1a\u0667@\xb2\x99\xed\x14\x06\xbc94\xb0\xb1m\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbba\xa0K\xff\xd5|\x10G\rE\u00d1\x03\xf6FP4v\x16\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbbh#\xa1\xbd\x81\x9f\x13QU8&J-\xe0R\xb4D\"\b\x89\x01ch\xffO\xf9\xc1\x00\x00\u07d4\xbbl(J\xac\x8ai\xb7\\\u0770\x0f(\xe1EX;V\xbe\u0389lk\x93[\x8b\xbd@\x00\x00\u07d4\xbbu\xcbPQ\xa0\xb0\x94KFs\xcau*\x97\x03\u007f|\x8c\x15\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbb\x99;\x96\xee\x92Z\xda}\x99\u05c6W=?\x89\x18\f\u3a89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbb\xa3\u0180\x04$\x8eH\x95s\xab\xb2t6w\x06k$\u0227\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbb\xa4\xfa\xc3\xc4 9\xd8(\xe7B\xcd\xe0\xef\xff\xe7t\x94\x1b9\x89lj\u04c2\xd4\xfba\x00\x00\u07d4\xbb\xa8\xab\"\xd2\xfe\xdb\xcf\xc6?hL\b\xaf\xdf\x1c\x17P\x90\xb5\x89\x05_)\xf3~N;\x80\x00\u07d4\xbb\xa9v\xf1\xa1!_u\x12\x87\x18\x92\xd4_pH\xac\xd3V\u0209lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xbb\xab\x00\v\x04\b\xed\x01Z7\xc0GG\xbcF\x1a\xb1N\x15\x1b\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xbb\xab\xf6d;\xebK\xd0\x1c\x12\v\xd0Y\x8a\t\x87\xd8)g\u0449\xb52\x81x\xad\x0f*\x00\x00\u07d4\xbb\xb4\xee\x1d\x82\xf2\xe1VD,\xc938\xa2\xfc(o\xa2\x88d\x89JD\x91\xbdm\xcd(\x00\x00\u07d4\xbb\xb5\xa0\xf4\x80,\x86H\x00\x9e\x8ai\x98\xaf5,\u0787TO\x89\x05-T(\x04\xf1\xce\x00\x00\u07d4\xbb\xb6C\xd2\x18{6J\xfc\x10\xa6\xfd6\x8d}U\xf5\r\x1a<\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbb\xb8\xff\xe4?\x98\u078e\xae\x18F#\xaeRd\xe4$\u0438\u05c9\x05\xd5?\xfd\xe9(\b\x00\x00\u07d4\xbb\xbdn\u02f5u(\x91\xb4\u03b3\xcc\xe7:\x8fGpY7o\x89\x01\xf3\x99\xb1C\x8a\x10\x00\x00\u07d4\xbb\xbf9\xb1\xb6y\x95\xa4\"APO\x97\x03\u04a1JQV\x96\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xbb\xc8\xea\xffc~\x94\xfc\u014d\x91\xdb\\\x89\x12\x1d\x06\xe1/\xff\x98\x80\x00\u07d4\xbc\u065e\xdc!`\xf2\x10\xa0^:\x1f\xa0\xb0CL\xed\x00C\x9b\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbc\u07ec\xb9\xd9\x02<4\x17\x18.\x91\x00\xe8\xea\x1d73\x93\xa3\x89\x034-`\xdf\xf1\x96\x00\x00\u07d4\xbc\xe1>\"2*\u03f3U\xcd!\xfd\r\xf6\f\xf9:\xdd&\u0189\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xbc\xe4\x04u\xd3E\xb0q-\xeep=\x87\xcdvW\xfc\u007f;b\x8a\x01\xa4 \xdb\x02\xbd}X\x00\x00\u07d4\xbc\xed\xc4&|\u02c9\xb3\x1b\xb7d\xd7!\x11q\x00\x8d\x94\xd4M\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbc\xfc\x98\xe5\xc8+j\xdb\x18\n?\xcb\x12\v\x9av\x90\xc8j?\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xbd\x04;g\xc6>`\xf8A\xcc\xca\x15\xb1)\xcd\xfee\x90\xc8\xe3\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbd\x04\u007f\xf1\xe6\x9c\u01b2\x9a\xd2d\x97\xa9\xa6\xf2z\x90?\xc4\u0749.\xe4IU\b\x98\xe4\x00\x00\u07d4\xbd\b\xe0\xcd\xde\xc0\x97\xdby\x01\ua05a=\x1f\xd9\u0789Q\xa2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xbd\t\x12l\x89\x1cJ\x83\x06\x80Y\xfe\x0e\x15ylFa\xa9\xf4\x89+^:\xf1k\x18\x80\x00\x00\u07d4\xbd\f\\\u05d9\xeb\u0106B\xef\x97\xd7N\x8eB\x90d\xfe\u4489\x11\xac(\xa8\xc7)X\x00\x00\u07d4\xbd\x17\xee\xd8+\x9a%\x92\x01\x9a\x1b\x1b<\x0f\xba\xd4\\@\x8d\"\x89\r\x8drkqw\xa8\x00\x00\u07d4\xbd\x18\x037\v\u0771)\xd29\xfd\x16\xea\x85&\xa6\x18\x8a\u5389\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xbd+p\xfe\xcc7d\x0fiQO\xc7\xf3@IF\xaa\xd8k\x11\x89A\rXj \xa4\xc0\x00\x00\u07d4\xbd0\x97\xa7\x9b<\r.\xbf\xf0\xe6\xe8j\xb0\xed\xad\xbe\xd4p\x96\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4\xbd2]@)\xe0\xd8r\x9fm9\x9cG\x82$\xae\x9ez\xe4\x1e\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\xbdC*9\x16$\x9bG$):\xf9\x14nI\xb8(\n\u007f*\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xbdG\xf5\xf7n;\x93\x0f\xd9HR\t\xef\xa0\xd4v=\xa0uh\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbdK`\xfa\xect\n!\xe3\a\x13\x91\xf9j\xa54\xf7\xc1\xf4N\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\xbdK\u0571\"\xd8\xef{|\x8f\x06gE\x03 \xdb!\x16\x14.\x89 \x86\xac5\x10R`\x00\x00\u07d4\xbdQ\xee.\xa1C\u05f1\u05b7~~D\xbd\xd7\xda\x12\U00105b09G~\x06\u0332\xb9(\x00\x00\u07d4\xbdY\tN\aO\x8dy\x14*\xb1H\x9f\x14\x8e2\x15\x1f \x89\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xbdZ\x8c\x94\xbd\x8b\xe6G\x06D\xf7\f\x8f\x8a3\xa8\xa5\\cA\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbd^G:\xbc\xe8\xf9zi2\xf7|/\xac\xaf\x9c\xc0\xa0\x05\x14\x89<\x92X\xa1\x06\xa6\xb7\x00\x00\u07d4\xbd_F\u02ab,=K(\x93\x96\xbb\xb0\u007f *\x06\x11>\xd4\xc3\xfb\xa1\xa8\x91;\x19@~\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbd\x9eV\xe9\x02\xf4\xbe\x1f\xc8v\x8d\x808\xba\xc6>*\u02ff\x8e\x8965f3\xeb\xd8\xea\x00\x00\u07d4\xbd\xa4\xbe1~~K\xed\x84\xc0I^\xee2\xd6\a\xec8\xcaR\x89}2'yx\xefN\x80\x00\u07d4\xbd\xb6\v\x82:\x11s\xd4Z\a\x92$_\xb4\x96\xf1\xfd3\x01\u03c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xbd\xba\xf6CM@\xd65[\x1e\x80\xe4\f\u012b\x9ch\xd9a\x16\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xbd\xc0,\xd43\f\x93\xd6\xfb\xdaOm\xb2\xa8]\xf2/C\xc23\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbd\xc4aF+c\"\xb4b\xbd\xb3?\"y\x9e\x81\b\xe2A}\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\xbd\xc79\xa6\x99p\v.\x8e,JL{\x05\x8a\x0eQ=\u07be\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbd\xc7Hs\xaf\x92+\x9d\xf4t\x85;\x0f\xa7\xff\v\xf8\xc8&\x95\x89\xd8\xc9F\x00c\xd3\x1c\x00\x00\u07d4\xbd\xca*\x0f\xf3E\x88\xafb_\xa8\xe2\x8f\xc3\x01Z\xb5\xa3\xaa\x00\x89~\xd7?w5R\xfc\x00\x00\u07d4\xbd\xd3%N\x1b:m\xc6\xcc,i}Eq\x1a\xca!\xd5\x16\xb2\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xbd\u07e3M\x0e\xbf\x1b\x04\xafS\xb9\x9b\x82IJ\x9e=\x8a\xa1\x00\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xbd\xe4\xc7?\x96\x9b\x89\xe9\u03aef\xa2\xb5\x18DH\x0e\x03\x8e\x9a\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xbd\xe9xj\x84\xe7[H\xf1\x8erm\u05cdp\xe4\xaf>\xd8\x02\x8a\x016\x9f\xb9a(\xacH\x00\x00\u07d4\xbd\xed\x11a/\xb5\xc6\u0699\xd1\xe3\x0e2\v\xc0\x99Tf\x14\x1e\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xbd\xed~\a\xd0q\x1ehM\xe6Z\u0232\xabW\xc5\\\x1a\x86E\x89 \t\xc5\u023fo\xdc\x00\x00\u07d4\xbd\xf6\x93\xf83\xc3\xfeG\x17S\x18G\x88\xebK\xfeJ\xdc?\x96\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xbd\xf6\xe6\x8c\f\xd7X@\x80\xe8G\xd7,\xbb#\xaa\xd4j\xeb\x1d\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xbe\n/8_\t\xdb\xfc\xe9g2\xe1+\xb4\n\xc3I\x87\x1b\xa8\x89WL\x11^\x02\xb8\xbe\x00\x00\u07d4\xbe\f*\x80\xb9\xde\bK\x17(\x94\xa7l\xf4szOR\x9e\x1a\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xbe\x1c\xd7\xf4\xc4r\a\th\xf3\xbd\xe2h6k!\xee\xea\x83!\x89\xe9\x1a|\u045f\xa3\xb0\x00\x00\u07d4\xbe#F\xa2\u007f\xf9\xb7\x02\x04OP\r\xef\xf2\xe7\xff\xe6\x82EA\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xbe$q\xa6\u007f`G\x91\x87r\xd0\xe3h9%^\xd9\u0591\xae\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xbe+\"\x80R7h\xea\x8a\xc3\\\xd9\xe8\x88\xd6\nq\x93\x00\u0509lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xbe+2nx\xed\x10\xe5P\xfe\xe8\xef\xa8\xf8\a\x03\x96R/Z\x8a\bW\xe0\xd6\xf1\xdav\xa0\x00\x00\xe0\x94\xbe0Zyn3\xbb\xf7\xf9\xae\xaee\x12\x95\x90f\xef\xda\x10\x10\x8a\x02M\xceT\xd3J\x1a\x00\x00\x00\u07d4\xbeG\x8e\x8e=\xdek\xd4\x03\xbb-\x1ce|C\x10\xee\x19'#\x89\x1a\xb2\xcf|\x9f\x87\xe2\x00\x00\u07d4\xbeN}\x98?.*ck\x11\x02\xecp9\xef\xeb\xc8B\u9349\x03\x93\xef\x1aQ'\xc8\x00\x00\u07d4\xbeO\xd0sap\"\xb6\u007f\\\x13I\x9b\x82\u007fv69\xe4\xe3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbeRZ3\xea\x91aw\xf1r\x83\xfc\xa2\x9e\x8b5\v\u007fS\v\x89\x8f\x01\x9a\xafF\xe8x\x00\x00\u07d4\xbeS2/C\xfb\xb5\x84\x94\xd7\xcc\xe1\x9d\xda'+$P\xe8'\x89\n\xd7\u03afB\\\x15\x00\x00\u07d4\xbeS\x82F\xddNo\f \xbfZ\xd17<;F:\x13\x1e\x86\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbeZ`h\x99\x98c\x9a\xd7[\xc1\x05\xa3qt>\xef\x0fy@\x89\x1b2|s\xe1%z\x00\x00\u07d4\xbe\\\xba\x8d7By\x86\xe8\xca&\x00\xe8X\xbb\x03\xc3YR\x0f\x89\xa00\xdc\xeb\xbd/L\x00\x00\u07d4\xbe`\x03~\x90qJK\x91~a\xf1\x93\xd84\x90g\x03\xb1:\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xbec:77\xf6\x849\xba\xc7\xc9\nR\x14 X\ue38ao\x894\n\xad!\xb3\xb7\x00\x00\x00\xe0\x94\xbee\x9d\x85\xe7\xc3O\x883\xea\u007fH\x8d\xe1\xfb\xb5\xd4\x14\x9b\xef\x8a\x01\xeb\xd2:\xd9\u057br\x00\x00\u07d4\xbes'M\x8cZ\xa4J<\xbe\xfc\x82c\xc3{\xa1!\xb2\n\u04c9\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xbe\x86\u0430C\x84\x19\u03b1\xa081\x927\xbaR\x06\xd7.F\x8964\xfb\x9f\x14\x89\xa7\x00\x00\u07d4\xbe\x8d\u007f\x18\xad\xfe]l\xc7u9I\x89\xe1\x93\f\x97\x9d\x00}\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbe\x91\x86\xc3JRQJ\xbb\x91\a\x86\x0fgO\x97\xb8!\xbd[\x89\x1b\xa0\x1e\xe4\x06\x03\x10\x00\x00\u07d4\xbe\x93W\x93\xf4[p\xd8\x04]&T\xd8\xdd:\xd2K[a7\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4\xbe\x98\xa7\u007f\xd4\x10\x97\xb3OY\xd7X\x9b\xaa\xd0!e\x9f\xf7\x12\x890\xca\x02O\x98{\x90\x00\x00\u07d4\xbe\x9b\x8c4\xb7\x8e\xe9G\xff\x81G.\xdaz\xf9\xd2\x04\xbc\x84f\x89\b!\xab\rD\x14\x98\x00\x00\u07d4\xbe\xa0\r\xf1pg\xa4:\x82\xbc\x1d\xae\xca\xfbl\x140\x0e\x89\xe6\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xbe\xa0\xaf\xc9:\xae!\b\xa3\xfa\xc0Yb;\xf8o\xa5\x82\xa7^\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xbe\xb35\x8cP\u03dfu\xff\xc7mD<,\u007fU\aZ\x05\x89\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\xbe\xb4\xfd1UYC`E\u0739\x9dI\xdc\xec\x03\xf4\fB\u0709lk\x93[\x8b\xbd@\x00\x00\u07d4\xbe\xc2\xe6\xde9\xc0|+\xaeUj\u03fe\xe2\xc4r\x8b\x99\x82\xe3\x89\x1f\x0f\xf8\xf0\x1d\xaa\xd4\x00\x00\u07d4\xbe\xc6d\x0fI\t\xb5\x8c\xbf\x1e\x80cB\x96\x1d`u\x95\tl\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xbe\xc8\xca\xf7\xeeIF\x8f\xeeU.\xff:\xc5#N\xb9\xb1}B\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbe\xce\xf6\x1c\x1cD+\xef|\xe0Ks\xad\xb2I\xa8\xba\x04~\x00\x896;V\u00e7T\xc8\x00\x00\u0794\xbe\xd4d\x9d\xf6F\u2052)\x03-\x88hUo\xe1\xe0S\u04c8\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\xbe\xd4\xc8\xf0\x06\xa2|\x1e_|\xe2\x05\xdeu\xf5\x16\xbf\xb9\xf7d\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\xbe\xe8\u0430\bB\x19T\xf9-\x00\r9\x0f\xb8\xf8\xe6X\xea\xee\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbe\xec\u05af\x90\f\x8b\x06J\xfc\xc6\a?-\x85\u055a\xf1\x19V\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xbe\xef\x94!8y\xe0&\"\x14+\xeaa)\tx\x93\x9a`\u05ca\x016\x85{2\xad\x86\x04\x80\x00\xe0\x94\xbe\xf0}\x97\xc3H\x1f\x9dj\xee\x1c\x98\xf9\xd9\x1a\x18\n2D+\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xbe\xfbD\x8c\f_h?\xb6~\xe5p\xba\xf0\xdbV\x86Y\x97Q\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xbf\x05\a\f,4!\x93\x11\xc4T\x8b&\x14\xa48\x81\r\xedm\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbf\x05\xff^\xcf\r\xf2\u07c8wY\xfb\x82t\xd928\xac&}\x89+^:\xf1k\x18\x80\x00\x00\xe0\x94\xbf\t\xd7pH\xe2p\xb6b3\x0e\x94\x86\xb3\x8bC\xcdx\x14\x95\x8a\\S\x9b{\xf4\xff(\x80\x00\x00\u07d4\xbf\x17\xf3\x97\xf8\xf4o\x1b\xaeE\u0447\x14\x8c\x06\xee\xb9Y\xfaM\x896I\u0156$\xbb0\x00\x00\u07d4\xbf\x186A\xed\xb8\x86\xce`\xb8\x19\x02a\xe1OB\xd9<\xce\x01\x89\x01[5W\xf1\x93\u007f\x80\x00\u07d4\xbf*\xeaZ\x1d\xcfn\u04f5\xe829D\xe9\x83\xfe\xdf\u046c\xfb\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xbf@\x96\xbcT}\xbf\xc4\xe7H\t\xa3\x1c\x03\x9e{8\x9d^\x17\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\xbfI\xc1H\x981eg\u0637\t\xc2\xe5\x05\x94\xb3f\xc6\u04cc\x89'\xbf8\xc6TM\xf5\x00\x00\u07d4\xbfLs\xa7\xed\xe7\xb1d\xfe\a!\x14\x846T\xe4\xd8x\x1d\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\xbfP\xce.&K\x9f\xe2\xb0h0az\xed\xf5\x02\xb25\x1bE\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbfY\xae\xe2\x81\xfaC\xfe\x97\x19CQ\xa9\x85~\x01\xa3\xb8\x97\xb2\x89 \x86\xac5\x10R`\x00\x00\u07d4\xbfh\u048a\xaf\x1e\xee\xfe\xf6F\xb6^\x8c\xc8\u0450\xf6\xc6\u069c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xbfi%\xc0\aQ\x00\x84@\xa6s\x9a\x02\xbf+l\u06ab^:\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xbfw\x01\xfcb%\u0561x\x15C\x8a\x89A\xd2\x1e\xbc]\x05\x9d\x89e\xea=\xb7UF`\x00\x00\u07d4\xbf\x8b\x80\x05\xd66\xa4\x96d\xf7Bu\xefBC\x8a\xcde\xac\x91\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbf\x92A\x8a\fl1$M\"\x02`\xcb>\x86}\u05f4\xefI\x89\x05i\x00\xd3<\xa7\xfc\x00\x00\u07d4\xbf\x9a\xcdDE\xd9\xc9UF\x89\u02bb\xba\xb1\x88\x00\xff\x17A\u008965\u026d\xc5\u07a0\x00\x00\u07d4\xbf\x9f'\x1fz~\x12\xe3m\xd2\xfe\x9f\xac\xeb\xf3\x85\xfeaB\xbd\x89\x03f\xf8O{\xb7\x84\x00\x00\u07d4\xbf\xa8\xc8X\xdf\x10,\xb1$!\x00\x8b\n1\xc4\xc7\x19\n\xd5`\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xbf\xae\xb9\x10ga}\u03cbD\x17+\x02\xafaVt\x83]\xba\x89\b\xb5\x9e\x88H\x13\b\x80\x00\xe0\x94\xbf\xb0\xea\x02\xfe\xb6\x1d\xec\x9e\"\xa5\a\tY3\x02\x99\xc40r\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xbf\xbc\xa4\x18\xd3R\x9c\xb3\x93\b\x10b\x03*n\x11\x83\u01b2\u070a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xbf\xbe\x05\u831c\xbb\xcc\x0e\x92\xa4\x05\xfa\xc1\xd8]\xe2H\xee$\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xbf\xbf\xbc\xb6V\u0099+\xe8\xfc\u0782\x19\xfb\xc5J\xad\u055f)\x8a\x02\x1e\x18\xd2\xc8!\xc7R\x00\x00\u07d4\xbf\xc5z\xa6f\xfa\u239f\x10zI\xcbP\x89\xa4\xe2!Q\u074965\u026d\xc5\u07a0\x00\x00\u07d4\xbf\u02d70$c\x04p\r\xa9\vAS\xe7\x11Ab.\x1cA\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xbf\xd9<\x90\u009c\a\xbc_\xb5\xfcI\xae\xeaU\xa4\x0e\x13O5\x8a\x05\xed\xe2\x0f\x01\xa4Y\x80\x00\x00\xe0\x94\xbf\xe3\xa1\xfcn$\xc8\xf7\xb3%\x05`\x99\x1f\x93\u02e2\u03c0G\x8a\x10\xf0\xcf\x06M\u0552\x00\x00\x00\u07d4\xbf\u6f30\xf0\xc0xRd3$\xaa]\xf5\xfdb%\xab\xc3\u0289\x04\t\xe5+H6\x9a\x00\x00\u07d4\xbf\xf5\xdfv\x994\xb8\x94<\xa9\x13}\x0e\xfe\xf2\xfen\xbb\xb3N\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xbf\xfbi)$\x1fx\x86\x93'>p\"\xe6\x0e>\xab\x1f\xe8O\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc0\x06O\x1d\x94t\xab\x91]V\x90l\x9f\xb3 \xa2\xc7\t\x8c\x9b\x89\x13h?\u007f<\x15\xd8\x00\x00\u07d4\xc0\a\xf0\xbd\xb6\xe7\x00\x92\x02\xb7\xaf>\xa9\t\x02i|r\x14\x13\x89\xa2\xa0\xe4>\u007f\xb9\x83\x00\x00\u07d4\xc0\n\xb0\x80\xb6C\xe1\u00ba\xe3c\xe0\u0455\xde.\xff\xfc\x1cD\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u0794\xc0 wD\x9a\x13Jz\xd1\xef~M\x92z\xff\xec\ueb75\xae\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xc0$q\xe3\xfc.\xa0S&\x15\xa7W\x1dI2\x89\xc1<6\xef\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc0-n\xad\xea\xcf\x1bx\xb3\u0285\x03\\c{\xb1\xce\x01\xf4\x90\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc03\xb12Z\n\xf4Tr\xc2U'\x85;\x1f\x1c!\xfa5\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\xc03\xbe\x10\xcbHa;\xd5\xeb\xcb3\xedI\x02\xf3\x8bX0\x03\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xc04[3\xf4\x9c\xe2\u007f\xe8,\xf7\xc8M\x14\x1ch\xf5\x90\xcev\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc0=\xe4*\x10\x9bezd\xe9\"$\xc0\x8d\xc1'^\x80\u0672\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc0@i\u07f1\x8b\tlxg\xf8\xbe\xe7zm\xc7Gz\xd0b\x89\x90\xf54`\x8ar\x88\x00\x00\xe0\x94\xc0A?Z|-\x9aK\x81\b(\x9e\xf6\xec\xd2qx\x15$\xf4\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\xc0C\xf2E-\u02d6\x02\xefb\xbd6\x0e\x03=\xd29q\xfe\x84\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc0OK\xd4\x04\x9f\x04F\x85\xb8\x83\xb6)Y\xaec\x1df~5\x8a\x01;\x80\xb9\x9cQ\x85p\x00\x00\u07d4\xc0V\u053dk\xf3\u02ec\xace\xf8\xf5\xa0\xe3\x98\v\x85'@\xae\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xc0[t\x06 \xf1s\xf1nRG\x1d\u00cb\x9cQJ\v\x15&\x89\a\x96\xe3\xea?\x8a\xb0\x00\x00\u07d4\xc0i\xef\x0e\xb3B\x99\xab\xd2\xe3-\xab\xc4yD\xb2r3H$\x89\x06\x81U\xa46v\xe0\x00\x00\u07d4\xc0l\xeb\xbb\xf7\xf5\x14\x9af\xf7\xeb\x97k>G\xd5e\x16\xda/\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc0r^\u00bd\xc3:\x1d\x82`q\u07a2\x9db\xd48Z\x8c%\x8a\b\xa0\x85\x13F:\xa6\x10\x00\x00\u07d4\xc0~8g\xad\xa0\x96\x80z\x05\x1al\x9c4\xcc;?J\xd3J\x89`\xf0f \xa8IE\x00\x00\u07d4\xc0\x89^\xfd\x05m\x9a:\x81\xc3\xdaW\x8a\xda1\x1b\xfb\x93V\u03c9\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc0\x90\xfe#\xdc\xd8k5\x8c2\xe4\x8d*\xf9\x10$%\x9fef\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc0\x9af\x17*\xea7\r\x9ac\xda\x04\xffq\xff\xbb\xfc\xff\u007f\x94\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc0\x9e<\xfc\x19\xf6\x05\xff>\xc9\xc9\xc7\x0e%@\xd7\xee\x97Cf\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc0\xa0*\xb9N\xbeV\xd0E\xb4\x1bb\x9b\x98F.:\x02J\x93\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xc0\xa3\x93\b\xa8\x0e\x9e\x84\xaa\xaf\x16\xac\x01\xe3\xb0\x1dt\xbdk-\x89\afM\xddL\x1c\v\x80\x00\u07d4\xc0\xa6\u02edwi*=\x88\xd1A\xefv\x9a\x99\xbb\x9e<\x99Q\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xc0\xa7\xe8C]\xff\x14\xc2Uws\x9d\xb5\\$\u057fW\xa3\u064a\nm\xd9\f\xaeQ\x14H\x00\x00\u07d4\xc0\xae\x14\xd7$\x83./\xce'x\xde\u007f{\x8d\xaf{\x12\xa9>\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc0\xaf\xb7\u0637\x93p\xcf\xd6c\u018c\u01b9p*7\u035e\xff\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc0\xb0\xb7\xa8\xa6\xe1\xac\xdd\x05\xe4\u007f\x94\xc0\x96\x88\xaa\x16\u01ed\x8d\x89\x03{m\x02\xacvq\x00\x00\xe0\x94\xc0\xb3\xf2D\xbc\xa7\xb7\xde[H\xa5>\u06dc\xbe\xab\vm\x88\xc0\x8a\x01;\x80\xb9\x9cQ\x85p\x00\x00\u07d4\xc0\xc0M\x01\x06\x81\x0e>\xc0\xe5J\x19\U000ab157\xe6\x9aW=\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\xc0\xca2w\x94.tE\x87K\xe3\x1c\xeb\x90)rqO\x18#\x89\r\x8drkqw\xa8\x00\x00\u07d4\xc0\u02ed<\xcd\xf6T\xda\"\xcb\xcf\\xe\x97\xca\x19U\xc1\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc0\xcb\xf6\x03/\xa3\x9e|F\xffw\x8a\x94\xf7\xd4E\xfe\"\xcf0\x89\x10\xce\x1d=\x8c\xb3\x18\x00\x00\u07d4\xc0\xe0\xb9\x03\b\x8e\fc\xf5=\xd0iWTR\xaf\xf5$\x10\u00c9\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xc0\xe4W\xbdV\xec6\xa1$k\xfa20\xff\xf3\x8eY&\xef\"\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xc0\xed\rJ\xd1\r\xe045\xb1S\xa0\xfc%\xde;\x93\xf4R\x04\x89\xabM\xcf9\x9a:`\x00\x00\u07d4\xc0\xf2\x9e\xd0\af\x11\xb5\xe5^\x13\x05G\xe6\x8aH\xe2m\xf5\u4262\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xc1\x13(x#\\]\u06e5\xd9\xf3\"\x8bR6\xe4p \xdco\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc1\x17\r\xba\xad\xb3\xde\xe6\x19\x8e\xa5D\xba\xec\x93%\x18`\xfd\xa5\x89A\rXj \xa4\xc0\x00\x00\xe0\x94\xc1&W=\x87\xb0\x17ZR\x95\xf1\xdd\a\xc5u\u03cc\xfa\x15\xf2\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xc1'\xaa\xb5\x90e\xa2\x86D\xa5k\xa3\xf1^.\xac\x13\xda)\x95\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xc1+\u007f@\u07da/{\xf9\x83f\x14\"\xab\x84\xc9\xc1\xf5\bX\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xc1,\xfb{=\xf7\x0f\xce\xca\x0e\xde&5\x00\xe2xs\xf8\xed\x16\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc1/\x88\x1f\xa1\x12\xb8\x19\x9e\xcb\xc7>\xc4\x18W\x90\xe6\x14\xa2\x0f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc18Lnq~\xbeK#\x01NQ\xf3\x1c\x9d\xf7\xe4\xe2[1\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc1C\x8c\x99\xddQ\xef\x1c\xa88j\xf0\xa3\x17\xe9\xb0AEx\x88\x89\f\x1d\xaf\x81\u0623\xce\x00\x00\u07d4\xc1c\x12(\xef\xbf*.:@\x92\xee\x89\x00\xc69\xed4\xfb\u02093\xc5I\x901r\f\x00\x00\u07d4\xc1u\xbe1\x94\xe6iB-\x15\xfe\xe8\x1e\xb9\xf2\xc5lg\xd9\u0249\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc1\x82v\x86\xc0\x16\x94\x85\xec\x15\xb3\xa7\xc8\xc0\x15\x17\xa2\x87M\xe1\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xc1\x8a\xb4g\xfe\xb5\xa0\xaa\xdf\xff\x91#\x0f\xf0VFMx\xd8\x00\x89lk\x93[\x8b\xbd@\x00\x00\u0794\xc1\x95\x05CUM\x8aq0\x03\xf6b\xbba,\x10\xadL\xdf!\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xc1\xa4\x1aZ'\x19\x92&\xe4\xc7\xeb\x19\x8b\x03\x1bY\x19o\x98B\x89\nZ\xa8P\t\xe3\x9c\x00\x00\u07d4\xc1\xb2\xa0\xfb\x9c\xadE\xcdi\x91\x92\xcd'T\v\x88\xd38By\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc1\xb2\xaa\x8c\xb2\xbfb\xcd\xc1:G\xec\xc4e\u007f\xac\xaa\x99_\x98\x8967\x93\xfa\x96\u6980\x00\u07d4\xc1\xb5\x00\x01\x1c\xfb\xa9]|\xd66\xe9^l\xbfagFK%\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc1\xb9\xa5pM5\x1c\xfe\x98?y\xab\xee\xc3\u06fb\xae;\xb6)\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc1\xcb\xd2\xe23*RL\xf2\x19\xb1\r\x87\x1c\xcc \xaf\x1f\xb0\xfa\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xc1\xcd\xc6\x01\xf8\x9c\x04(\xb3\x13\x02\u0447\xe0\xdc\b\xad}\x1cW\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xc1\u052f8\xe9\xbay\x90@\x89HI\xb8\xa8!\x93u\xf1\xacx\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc1\xe1@\x9c\xa5,%CQ4\xd0\x06\u00a6\xa8T-\xfbrs\x89\x01\xdd\x1eK\xd8\xd1\xee\x00\x00\u07d4\xc1\xeb\xa5hJ\xa1\xb2L\xbac\x15\x02c\xb7\xa9\x13\x1a\xee\u008d\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc1\xec\x81\xdd\x12=K|-\u0674\xd48\xa7\a,\x11\u0707L\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc1\xf3\x9b\xd3]\xd9\xce\xc37\xb9oG\xc6w\x81\x81`\xdf7\xb7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794\xc1\xff\xad\a\u06d6\x13\x8cK*S\x0e\xc1\xc7\xde)\xb8\xa0Y,\x88\xf4?\xc2\xc0N\xe0\x00\x00\xe0\x94\xc2\x1f\xa6d:\x1f\x14\xc0)\x96\xadqD\xb7Y&\xe8~\xcbK\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc24\nL\xa9L\x96x\xb7IL<\x85%(\xed\xe5\xeeR\x9f\x89\x02\xa3k\x05\xa3\xfd|\x80\x00\u07d4\xc29\xab\u07ee>\x9a\xf5E\u007fR\xed+\x91\xfd\n\xb4\xd9\xc7\x00\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc2;/\x92\x1c\xe4\xa3z%\x9e\u4b4b!X\xd1]fOY\x89\x01`\x89\x95\xe8\xbd?\x80\x00\u07d4\xc2C\x99\xb4\xbf\x86\xf73\x8f\xbfd^;\"\xb0\u0dd79\x12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc2L\u03bc#D\xcc\xe5d\x17\xfbhL\xf8\x16\x13\xf0\xf4\xb9\xbd\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\xc2Rf\xc7gf2\xf1>\xf2\x9b\xe4U\ud50a\xddVw\x92\x89Hz\x9a0E9D\x00\x00\u07d4\xc2\\\xf8&U\f\x8e\xaf\x10\xaf\"4\xfe\xf9\x04\u0779R\x13\xbe\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc2f?\x81E\xdb\xfe\xc6\xc6F\xfc\\I\x96\x13E\xde\x1c\x9f\x11\x89%g\xacp9+\x88\x00\x00\u07d4\xc2pEh\x854+d\vL\xfc\x1bR\x0e\x1aTN\xe0\xd5q\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xc2sv\xf4]!\xe1^\xde;&\xf2e_\xce\xe0,\xcc\x0f*\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xc2w\x97q\xf0Smy\xa8p\x8fi1\xab\xc4K05\u964a\x047\u04ca\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xc2\xc1>r\xd2h\xe7\x15\r\u01d9\xe7\xc6\xcf\x03\u0209T\xce\u05c9%\xf2s\x93=\xb5p\x00\x00\u07d4\xc2\xcb\x1a\xda]\xa9\xa0B8s\x81G\x93\xf1aD\xef6\xb2\xf3\x89HU~;p\x17\xdf\x00\x00\u07d4\xc2\xd1w\x8e\xf6\xee_\xe4\x88\xc1E\xf3Xkn\xbb\xe3\xfb\xb4E\x89>\x1f\xf1\xe0;U\xa8\x00\x00\xe0\x94\xc2\xd9\xee\xdb\xc9\x01\x92c\xd9\xd1l\u016e\a-\x1d=\xd9\xdb\x03\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc2\xe0XJq4\x8c\xc3\x14\xb7; )\xb6#\v\x92\u06f1\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc2\xe2\u0518\xf7\r\xcd\bY\xe5\v\x02:q\nmK!3\xbd\x8989\x11\xf0\f\xbc\xe1\x00\x00\u07d4\xc2\xed_\xfd\u046d\xd8U\xa2i/\xe0b\xb5\xd6\x18t#`\u0509A\rXj \xa4\xc0\x00\x00\u07d4\xc2\xee\x91\xd3\xefX\xc9\u0465\x89\x84N\xa1\xae1%\xd6\u017ai\x894\x95tD\xb8@\xe8\x00\x00\u07d4\xc2\xfa\xfd\xd3\n\xcbmg\x06\xe9)<\xb0&A\xf9\xed\xbe\a\xb5\x89Q\x00\x86\vC\x0fH\x00\x00\u07d4\xc2\xfd\v\xf7\xc7%\xef>\x04~Z\xe1\u009f\xe1\x8f\x12\xa7)\x9c\x89Hz\x9a0E9D\x00\x00\u07d4\xc2\xfe}us\x1fcm\xcd\t\xdb\xda\x06q9;\xa0\xc8*}\x89wC\"\x17\xe6\x83`\x00\x00\u07d4\xc3\x10z\x9a\xf32-R8\xdf\x012A\x911b\x959W}\x89\x1a\xb4\xe4d\xd4\x141\x00\x00\xe0\x94\xc3\x11\v\xe0\x1d\xc9sL\xfcn\x1c\xe0\u007f\x87\xd7}\x13E\xb7\xe1\x8a\x01\x0f\f\xe9I\xe0\x0f\x93\x00\x00\u07d4\xc3 8\xcaR\xae\xe1\x97E\xbe\\1\xfc\xdcT\x14\x8b\xb2\xc4\u0409\x02\xb5\xaa\xd7,e \x00\x00\u07d4\xc3%\xc3R\x80\x1b\xa8\x83\xb3\"l_\xeb\r\xf9\xea\xe2\xd6\xe6S\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\xc3.\xc7\xe4*\xd1l\xe3\xe2UZ\xd4\xc5C\x06\xed\xa0\xb2gX\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc32\xdfP\xb1<\x014\x90\xa5\xd7\xc7]\xbf\xa3f\u0687\xb6\u0589\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc3:\u0373\xba\x1a\xab'P{\x86\xb1]g\xfa\xf9\x1e\xcfb\x93\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc3>\u0393Z\x8fN\xf98\xea~\x1b\xac\x87\u02d2]\x84\x90\u028a\a\x03\x8c\x16x\x1fxH\x00\x00\u07d4\xc3@\xf9\xb9\x1c&r\x8c1\xd1!\xd5\xd6\xfc;\xb5m=\x86$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc3F\xcb\x1f\xbc\xe2\xab(]\x8eT\x01\xf4-\xd7#M7\xe8m\x89\x04\x86\u02d7\x99\x19\x1e\x00\x00\xe0\x94\xc3H=n\x88\xac\x1fJ\xe7<\xc4@\x8dl\x03\xab\xe0\xe4\x9d\u028a\x03\x99\x92d\x8a#\u0220\x00\x00\xe0\x94\xc3H\xfcZF\x13#\xb5{\xe3\x03\u02c96\x1b\x99\x19\x13\xdf(\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xc3N;\xa12.\xd0W\x11\x83\xa2O\x94 N\xe4\x9c\x18fA\x89\x03'\xaf\uf927\xbc\x00\x00\xe0\x94\xc3[\x95\xa2\xa3s|\xb8\xf0\xf5\x96\xb3E$\x87+\xd3\r\xa24\x8a\x01\x98\xbe\x85#^-P\x00\x00\xe0\x94\xc3c\x1cv\x98\xb6\xc5\x11\x19\x89\xbfE''\xb3\xf99Zm\xea\x8a\x02C'X\x96d\x1d\xbe\x00\x00\u07d4\xc3l\vc\xbf\xd7\\/\x8e\xfb\x06\b\x83\xd8h\xcc\xcdl\xbd\xb4\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94\xc3uk\xcd\xcc~\xect\xed\x89j\xdf\xc35'Y0&n\b\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\u00c4\xacn\xe2|9\xe2\xf2x\xc2 \xbd\xfa[\xae\xd6&\xd9\u04c9 \x86\xac5\x10R`\x00\x00\u07d4\u00e0F\xe3\u04b2\xbfh\x14\x88\x82n2\xd9\xc0aQ\x8c\xfe\x8c\x89\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\u07d4\u00e9\"j\xe2u\xdf,\xab1+\x91\x10@cJ\x9c\x9c\x9e\xf6\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u00f9(\xa7o\xadex\xf0O\x05U\xe69R\xcd!\xd1R\n\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc3\xc2)s)\xa6\xfd\x99\x11~T\xfcj\xf3y\xb4\xd5VT~\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xc3\xc3\xc2Q\rg\x80 HZcs]\x13\a\xecL\xa60+\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc3\xcbk6\xafD?,n%\x8bJ9U:\x81\x87G\x81\x1f\x89WG=\x05\u06ba\xe8\x00\x00\xe0\x94\xc3\xdbVW\xbbr\xf1\rX\xf21\xfd\xdf\x11\x98\n\xffg\x86\x93\x8a\x01@a\xb9\xd7z^\x98\x00\x00\xe0\x94\xc3\u06df\xb6\xf4lH\n\xf3De\u05d7S\xb4\xe2\xb7Jg\u038a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc3\xddX\x908\x860;\x92\x86%%z\xe1\xa0\x13\xd7\x1a\xe2\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc3\xe0G\x1cd\xff5\xfaR2\xcc1!\xd1\u04cd\x1a\x0f\xb7\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\xc3\xe2\f\x96\u07cdN8\xf5\v&Z\x98\xa9\x06\xd6\x1b\xc5\x1aq\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc3\u31f0<\xe9\\\xcf\xd7\xfaQ\u0744\x01\x83\xbcCS(\t\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc3\xf8\xf6r\x95\xa5\xcd\x04\x93d\xd0]#P&#\xa3\xe5.\x84\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xc4\x01\xc4'\xcc\xcf\xf1\r\xec\xb8d /6\xf5\x80\x83\"\xa0\xa8\x89\xb4{Q\xa6\x9c\xd4\x02\x00\x00\u07d4\xc4\b\x8c\x02_>\x85\x01?T9\xfb4@\xa1s\x01\xe5D\xfe\x89~\t\xdbM\x9f?4\x00\x00\u07d4\xc4\x14a\xa3\u03fd2\u0246UU\xa4\x8117\xc0v1#`\x8965\xc6 G9\u0640\x00\u07d4\xc4 8\x8f\xbe\xe8J\xd6V\xddh\xcd\xc1\xfb\xaa\x93\x92x\v4\x89\n-\xcac\xaa\xf4\u0140\x00\u07d4\xc4\"P\xb0\xfeB\xe6\xb7\xdc\xd5\u0210\xa6\xf0\u020f__\xb5t\x89\b\x1e\xe4\x82SY\x84\x00\x00\u07d4\xc4-j\xebq\x0e:P\xbf\xb4Ml1\t)i\xa1\x1a\xa7\xf3\x89\b\"c\xca\xfd\x8c\xea\x00\x00\xe0\x94\xc4@\xc7\xca/\x96Kir\xeffJ\"a\xdd\xe8\x92a\x9d\x9c\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xc4K\xde\xc8\xc3l\\h\xba\xa2\xdd\xf1\xd41i2)rlC\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xc4OJ\xb5\xbc`9|s~\xb0h3\x91\xb63\xf8\xa2G\x1b\x12\x1c\xa4\x89 .h\xf2\u00ae\xe4\x00\x00\u07d4\xc4h\x1es\xbb\x0e2\xf6\xb7& H1\xffi\xba\xa4\x87~2\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xc4k\xbd\xefv\xd4\xca`\xd3\x16\xc0\u007f]\x1ax\x0e;\x16_~\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc4}a\v9\x92P\xf7\x0e\xcf\x13\x89\xba\xb6),\x91&O#\x89\x0f\xa7\xe7\xb5\xdf<\xd0\x00\x00\u07d4\u0100;\xb4\a\xc7b\xf9\vu\x96\xe6\xfd\u1513\x1ev\x95\x90\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u0106Q\xc1\xd9\xc1k\xffL\x95T\x88l??&C\x1foh\x89#\xab\x95\x99\xc4?\b\x00\x00\u07d4\u0109\xc8?\xfb\xb0%*\xc0\xdb\xe3R\x12\x17c\x0e\x0fI\x1f\x14\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u010bi<\xac\xef\xdb\xd6\xcb]x\x95\xa4.1\x962~&\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u0113H\x9eV\u00fd\xd8)\x00}\xc2\xf9VA)\x06\xf7k\xfa\x89\x02\xa7\x91H\x8eqT\x00\x00\u07d4\u0116\u02f0E\x9aj\x01`\x0f\u0149\xa5Z2\xb4T!\u007f\x9d\x89\x0e\u0683\x8cI)\b\x00\x00\u07d4\u011c\xfa\xa9g\xf3\xaf\xbfU\x03\x10a\xfcL\xef\x88\xf8]\xa5\x84\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u0136\xe5\xf0\x9c\xc1\xb9\r\xf0x\x03\xce=M\x13vj\x9cF\xf4\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\u013e\xc9c\b\xa2\x0f\x90\u02b1\x83\x99\u0113\xfd=\x06Z\xbfE\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\xe0\x94\xc4\xc0\x1a\xfc>\x0f\x04R!\xda\x12\x84\u05c7\x85tD/\xb9\xac\x8a\x01\x92\xb5\u0249\x02J\x19\xc1\xbdo\x12\x80\x00\xe0\x94\xc5\x00\xb7 sN\xd2)8\u05cc^H\xb2\xba\x93g\xa5u\xba\x8a\a\x12\x9e\x1c\xdf7>\xe0\x00\x00\u07d4\xc5\x0f\xe4\x15\xa6A\xb0\x85lNu\xbf\x96\x05\x15D\x1a\xfa5\x8d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc5\x13L\xfb\xb1\xdfz \xb0\xedpWb.\xee\u0480\x94}\xad\x89\xcd\xff\x97\xfa\xbc\xb4`\x00\x00\xe0\x94\xc5\x17\xd01\\\x87\x88\x13\xc7\x17\u132f\xa1\xea\xb2eN\x01\u068a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xc5\x18y\x9aY%Wb\x13\xe2\x18\x96\xe0S\x9a\xbb\x85\xb0Z\xe3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc5\"\xe2\x0f\xbf\x04\xed\u007fk\x05\xa3{G\x18\xd6\xfc\xe0\x14.\x1a\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc5$\bmF\xc8\x11+\x12\x8b/\xafo|}\x81`\xa88l\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xc5-\x1a\fs\u00a1\xbe\x84\x91Q\x85\xf8\xb3O\xaa\n\xdf\x1d\xe3\x89K\xe4\xea\xb3\xfa\x0f\xa6\x80\x00\xe0\x94\xc55\x94\xc7\u03f2\xa0\x8f(L\xc9\u05e6;\xbd\xfc\v1\x972\x8a\nk#(\xff:b\xc0\x00\x00\u07d4\xc57I(\xcd\xf1\x93pTC\xb1L\xc2\r\xa4#G<\xd9\u03c9\a}\x10P\x9b\xb3\xaf\x80\x00\u07d4\xc58\xa0\xff(*\xaa_Ku\u03f6,p\x03~\xe6}O\xb5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc5;P\xfd;+r\xbclC\v\xaf\x19JQU\x85\u04d8m\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xc5=y\xf7\u02dbp\x95/\xd3\x0f\xceX\xd5K\x9f\vY\xf6G\x8a\x01\x13\xe2\xd6tCE\xf8\x00\x00\u07d4\xc5I\u07c3\xc6\xf6^\xec\x0f\x1d\u0260\x93J\\_:P\xfd\x88\x89\x9d\xc0\\\xce(\u00b8\x00\x00\u07d4\xc5P\x05\xa6\xc3~\x8c\xa7\xe5C\xce%\x99s\xa3\xca\u0396\x1aJ\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc5U\xb91V\xf0\x91\x01#\x80\x00\xe0\x94\u0166)\xa3\x96%R\u02ce\xde\u0609cj\xaf\xbd\f\x18\xcee\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u016e\x86\xb0\xc6\xc7\xe3\x90\x0f\x13h\x10\\VS\u007f\xaf\x8dt>\x89\n1\x06+\xee\xedp\x00\x00\u07d4\u0170\t\xba\xea\xf7\x88\xa2v\xbd5\x81:\xd6[@\v\x84\x9f;\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u0175l\xd24&|(\xe8\x9cok\"f\xb0\x86\xa1/\x97\f\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xc5\u01a4\x99\x8a3\xfe\xb7dCz\x8b\xe9)\xa7;\xa3J\ad\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\xe0\x94\xc5\xc7=a\xcc\xe7\xc8\xfeL\x8f\xce)\xf3\x90\x92\xcd\x19>\x0f\xff\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xc5\xc7Y\vV!\xec\xf85\x85\x88\u079bh\x90\xf2baC\U000498a1]\tQ\x9b\xe0\x00\x00\u07d4\xc5\xcd\xce\xe0\xe8]\x11}\xab\xbfSj?@i\xbfD?T\xe7\x89j\xc5\xc6-\x94\x86\a\x00\x00\u07d4\xc5\u050c\xa2\xdb/\x85\xd8\xc5U\xcb\x0e\x9c\xfe\x82i6x?\x9e\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xc5\xde\x12\x03\xd3\xcc,\xea1\xc8.\xe2\xdeY\x16\x88\a\x99\xea\xfd\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xc5\xe4\x88\xcf+Vw\x939q\xf6L\xb8 -\xd0WR\xa2\xc0\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc5\xe8\x12\xf7o\x15\xf2\xe1\xf2\xf9\xbcH#H<\x88\x04cog\x89\x03\xf5\x14\x19:\xbb\x84\x00\x00\u07d4\xc5\u94d34\xf1%.\u04ba&\x81D\x87\xdf\u0498+1(\x89\x03\xcbq\xf5\x1f\xc5X\x00\x00\u07d4\xc5\xebB)^\x9c\xad\xea\xf2\xaf\x12\xde\u078a\x8dS\xc5y\xc4i\x89\xcf\x15&@\xc5\xc80\x00\x00\xe0\x94\xc5\xed\xbb\xd2\xca\x03WeJ\xd0\xeaG\x93\xf8\xc5\xce\xcd0\xe2T\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xc5\xf6K\xab\xb7\x031B\xf2\x0eF\u05eab\x01\xed\x86\xf6q\x03\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc5\xf6\x87qrF\u068a \r \xe5\u9f2c`\xb6\u007f8a\x89\x01\x8d\x99?4\xae\xf1\x00\x00\u07d4\xc6\x04[<5\vL\xe9\xca\fkuO\xb4\x1ai\xb9~\x99\x00\x892$\xf4'#\xd4T\x00\x00\u07d4\xc6\v\x04eN\x00;F\x83\x04\x1f\x1c\xbdk\u00cf\xda|\xdb\u0589lk\x93[\x8b\xbd@\x00\x00\u07d4\xc6\x14F\xb7T\xc2N;\x16B\xd9\xe5\x17e\xb4\xd3\xe4k4\xb6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc6\x18R\x13!\xab\xaf[&Q:J\x95(\bo\"\n\xdco\x89\x01v\xb3D\xf2\xa7\x8c\x00\x00\u07d4\xc6#FW\xa8\a8A&\xf8\x96\x8c\xa1p\x8b\xb0{\xaaI<\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc6%\xf8\u024d'\xa0\x9a\x1b\u02bdQ(\xb1\u00a9HV\xaf0\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xc65^\xc4v\x8cp\xa4\x9a\xf6\x95\x13\u0343\xa5\xbc\xa7\xe3\xb9\u034a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xc6:\xc4\x17\x99.\x9f\x9b`8n\xd9S\xe6\xd7\xdf\xf2\xb0\x90\xe8\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\xc6<\u05c8!\x18\xb8\xa9\x1e\aML\x8fK\xa9\x18Q0;\x9a\x89\x0e\x189\x8ev\x01\x90\x00\x00\u07d4\xc6R\x87\x1d\x19$\"\u01bc#_\xa0c\xb4J~\x1dC\u3149\bg\x0e\x9e\xc6Y\x8c\x00\x00\xe0\x94\xc6gD\x1e\u007f)y\x9a\xbaadQ\xd5;?H\x9f\x9e\x0fH\x8a\x02\xf2\x9a\xceh\xad\u0740\x00\x00\u07d4\xc6j\xe4\xce\xe8\u007f\xb352\x19\xf7\u007f\x1dd\x86\u0140(\x032\x89\x01\x9a\x16\xb0o\xf8\xcb\x00\x00\u07d4\xc6t\xf2\x8c\x8a\xfd\a?\x8by\x96\x91\xb2\xf0XM\xf9B\xe8D\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u0197\xb7\x04w\u02b4.+\x8b&f\x81\xf4\xaesu\xbb%A\x8a\x01.W2\xba\xba\\\x98\x00\x00\u07d4\u019b\x85U9\xce\x1b\x04qG(\xee\xc2Z7\xf3g\x95\x1d\xe7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u019b\xe4@\x13Mb\x80\x98\x01D\xa9\xf6M\x84t\x8a7\xf3I\x89&\u009eG\u0104L\x00\x00\u07d4\u019df<\x8d`\x90\x83\x91\xc8\xd26\x19\x153\xfd\xf7wV\x13\x89\x1aJ\xba\"\\ t\x00\x00\u0794\u01a2\x86\xe0e\xc8_:\xf7H\x12\xed\x8b\u04e8\xce]%\xe2\x1d\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\u01a3\x0e\xf5\xbb3 \xf4\r\xc5\xe9\x81#\rR\xae:\xc1\x93\"\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\u01ae(}\xdb\xe1\x14\x9b\xa1m\xdc\xcaO\xe0j\xa2\uaa48\xa9\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xc6\xc7\xc1\x917\x98\x97\u075c\x9d\x9a3\x83\x9cJ_b\xc0\x89\r\x89\xd8\xd8T\xb2$0h\x80\x00\xe0\x94\xc6\xcdh\xec56,Z\xd8L\x82\xadN\xdc#!%\x91-\x99\x8a\x05\xe0T\x9c\x962\xe1\xd8\x00\x00\u07d4\xc6\u0615N\x8f?\xc53\xd2\xd20\xff\x02\\\xb4\xdc\xe1O4&\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xc6\xdb\u06de\xfd^\xc1\xb3xn\x06q\xeb\"y\xb2S\xf2\x15\xed\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc6\xdf u\xeb\xd2@\xd4Hi\u00bek\u07c2\xe6=N\xf1\xf5\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc6\xe2\xf5\xaf\x97\x9a\x03\xfdr:\x1bn\xfar\x83\x18\u03dc\x18\x00\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\xc6\xe3$\xbe\xeb[6v^\xcdFB`\xf7\xf2`\x06\xc5\xc6.\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc6\xe4\xcc\fr\x83\xfc\x1c\x85\xbcH\x13\xef\xfa\xafr\xb4\x98#\xc0\x89\x0f\x03\x1e\xc9\xc8}\xd3\x00\x00\xe0\x94\xc6\xee5\x93B)i5)\xdcA\u067bq\xa2IfX\xb8\x8e\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\xc6\xfb\x1e\xe3t\x17\u0400\xa0\xd0H\x92;\u06ba\xb0\x95\xd0w\u0189\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc7\x05'\xd4D\u0110\xe9\xfc?\\\xc4Nf\xebO0k8\x0f\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc7\r\x85mb\x1e\xc1E0<\nd\x00\xcd\x17\xbb\xd6\xf5\xea\xf7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xc7\x0f\xa4Uv\xbf\x9c\x86_\x988\x93\x00,AI&\xf6\x10)\x89\x15\xb4\xaa\x8e\x97\x02h\x00\x00\u07d4\xc7\x11E\xe5)\u01e7\x14\xe6y\x03\xeeb\x06\xe4\xc3\x04+g'\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4\xc7\x1b*=q5\u04a8_\xb5\xa5q\u073ei^\x13\xfcC\u034965\u026d\xc5\u07a0\x00\x00\u07d4\xc7\x1f\x1du\x87?3\u0732\xddK9\x87\xa1-\a\x91\xa5\xce'\x897\b\xba\xed=h\x90\x00\x00\u07d4\xc7\x1f\x92\xa3\xa5J{\x8c/^\xa4C\x05\xfc\u02c4\xee\xe21H\x89\x02\xb5\x9c\xa11\xd2\x06\x00\x00\u07d4\xc7!\xb2\xa7\xaaD\xc2\x12\x98\xe8P9\xd0\x0e.F\x0eg\v\x9c\x89\a\xa1\xfe\x16\x02w\x00\x00\x00\u07d4\xc7,\xb3\x01%\x8e\x91\xbc\b\x99\x8a\x80]\u0452\xf2\\/\x9a5\x89 \t\xc5\u023fo\xdc\x00\x00\xe0\x94\xc76\x8b\x97\t\xa5\xc1\xb5\x1c\n\xdf\x18ze\xdf\x14\xe1+}\xba\x8a\x02\x02o\xc7\u007f\x03\u5b80\x00\u07d4\xc79%\x9e\u007f\x85\xf2e\x9b\xef_`\x9e\xd8k=Yl \x1e\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xc7>!\x12(\"\x15\xdc\ab\xf3+~\x80}\xcd\x1az\xae>\x8a\x01v\f\xbcb;\xb3P\x00\x00\xe0\x94\xc7If\x80B\xe7\x11#\xa6H\x97^\b\xedc\x82\xf8>\x05\xe2\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\xc7J9\x95\xf8\a\xde\x1d\xb0\x1a.\xb9\xc6.\x97\xd0T\x8fio\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc7Pl\x10\x19\x12\x1f\xf0\x8a,\x8c\x15\x91\xa6^\xb4\xbd\xfbJ?\x89 \x86\xac5\x10R`\x00\x00\u07d4\xc7\\7\xce-\xa0k\xbc@\b\x11Y\u01ba\x0f\x97n9\x93\xb1\x89:y#\x15\x1e\xcfX\x00\x00\u07d4\xc7]\"Y0j\xec}\xf0\"v\x8ci\x89\x9ae!\x85\xdb\u0109\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc7`\x97\x1b\xbc\x18\x1cj|\xf7tA\xf2BG\u045c\xe9\xb4\u03c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xc7a0\xc7<\xb9!\x028\x02\\\x9d\xf9]\v\xe5J\xc6\u007f\xbe\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\xc7e\xe0\x04v\x81\tG\x81j\xf1B\xd4m.\u7f28\xccO\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc7g^VG\xb9\xd8\xda\xf4\xd3\xdf\xf1\xe5R\xf6\xb0qT\xac8\x89\t\xc2\x00vQ\xb2P\x00\x00\u07d4\xc7{\x01\xa6\xe9\x11\xfa\x98\x8d\x01\xa3\xab3dk\xee\xf9\xc18\xf3\x89'\x1bo\xa5\xdb\xe6\xcc\x00\x00\u07d4\u01c3z\u0420\xbf\x14\x18i7\xac\xe0lUF\xa3j\xa5OF\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u01d8\x06\x03+\xc7\xd8(\xf1\x9a\u01a6@\u018e=\x82\x0f\xa4B\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u01d9\xe3N\x88\xff\x88\xbe}\xe2\x8e\x15\xe4\xf2\xa6=\v3\xc4\u02c9\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\u01ddPb\u01d6\xddwa\xf1\xf1>U\x8ds\xa5\x9f\x82\xf3\x8b\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\u01e0\x18\xf0\x96\x8aQ\xd1\xf6`<\\I\xdcT[\xcb\x0f\xf2\x93\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u01ef\xf9\x19)yt\x89UZ/\xf1\xd1M\\iZ\x10\x83U\x8965\u026d\xc5\u07a0\x00\x00\u0794\u01f1\xc8>c ?\x95G&>\xf6(.}\xa3;n\xd6Y\x88\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\u01f3\x9b\x06\x04Q\x00\f\xa1\x04\x9b\xa1T\xbc\xfa\x00\xff\x8a\xf2b\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\u01ff\x17\xc4\xc1\x1f\x98\x94\x1fP~w\bO\xff\xbd-\xbd=\xb5\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\u01ff.\xd1\xed1)@\xeej\xde\xd1Qn&\x8eJ`HV\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xc7\xd4O\xe3,\u007f\x8c\xd5\xf1\xa9t'\xb6\xcd:\xfc\x9eE\x02>\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xc7\xd5\xc7\x05@\x81\xe9\x18\xech{Z\xb3n\x97=\x18\x13)5\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\xc7\xde^\x8e\xaf\xb5\xf6+\x1a\n\xf2\x19\\\xf7\x93\u01c9L\x92h\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xc7\xe30\xcd\f\x89\n\u025f\xe7q\xfc\xc7\xe7\xb0\t\xb7A=\x8a\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc7\xea\xc3\x1a\xbc\xe6\xd5\xf1\u07a4\"\x02\xb6\xa6t\x15=\xb4z)\x89 \t\xc5\u023fo\xdc\x00\x00\xe0\x94\xc7\xecb\xb8\x04\xb1\xf6\x9b\x1e0p\xb5\xd3b\xc6/\xb3\t\xb0p\x8a\x02\xc4k\xf5A`f\x11\x00\x00\u07d4\xc7\xf7+\xb7X\x01k7G\x14\u0509\x9b\xce\"\xb4\xae\xc7\n1\x89:&\xc9G\x8f^-\x00\x00\u0794\xc8\v6\u047e\xaf\xba_\xccdM`\xacnF\xed)'\xe7\u0708\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\xc8\x11\xc2\xe9\xaa\x1a\xc3F.\xba^\x88\xfc\xb5\x12\x0e\x9fn,\xa2\x89K\xe6\u0607\xbd\x87n\x00\x00\u07d4\xc8\x17\xdf\x1b\x91\xfa\xf3\x0f\xe3%\x15qr|\x97\x11\xb4]\x8f\x06\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xc8\x1f\xb7\xd2\x0f\u0480\x01\x92\xf0\xaa\xc1\x98\xd6\u05a3}?\xcb}\x89\x0e\x11I3\x1c-\xde\x00\x00\u07d4\xc8 \xc7\x11\xf0w\x05'8\a\xaa\xaam\xe4M\x0eKH\xbe.\x89\bg\x0e\x9e\xc6Y\x8c\x00\x00\u07d4\xc8#\x1b\xa5\xa4\x11\xa1>\"+)\xbf\xc1\b?v1X\xf2&\x8967\tlK\xcci\x00\x00\u07d4\xc86\xe2Jo\xcf)\x94;6\b\xe6b)\n!_e)\xea\x89\x0f\xd4Pd\xea\xee\x10\x00\x00\xe0\x94\xc8;\xa6\u0755I\xbe\x1d2\x87\xa5\xa6T\xd1\x06\xc3Lk]\xa2\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\xc8>\x9djX%;\uefb7\x93\xe6\xf2\x8b\x05JXI\x1bt\x89\x0fF\u00b6\xf5\xa9\x14\x00\x00\u07d4\xc8A\x88O\xa4x_\xb7s\xb2\x8e\x97\x15\xfa\xe9\x9aQ40]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc8M\x9b\xea\n{\x9f\x14\x02 \xfd\x8b\x90\x97\u03ff\xd5\xed\xf5d\x89\x06\xab\x9e\u0091\xad}\x80\x00\u07d4\xc8RB\x8d+Xd\x97\xac\xd3\fV\xaa\x13\xfbU\x82\xf8D\x02\x893B\xd6\r\xff\x19`\x00\x00\u07d4\xc8S![\x9b\x9f-,\xd0t\x1eX^\x98{_\xb8\f!.\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\xc8S%\uaca5\x9b>\xd8c\xc8j_)\x06\xa0B)\xff\xa9\x89\x19=\u007f}%=\xe0\x00\x00\u07d4\xc8^\xf2}\x82\x04\x03\x80_\xc9\xed%\x9f\xffd\xac\xb8\xd64j\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc8akN\xc0\x91(\xcd\xff9\xd6\u4e6c\x86\xee\xc4q\xd5\xf2\x89\x01\r:\xa56\xe2\x94\x00\x00\xe0\x94\xc8a\x90\x90K\x8d\a\x9e\xc0\x10\xe4b\xcb\xff\xc9\b4\xff\xaa\\\x8a\x02#\x85\xa8'\xe8\x15P\x00\x00\u07d4\xc8q\r~\x8bZ;\u059aB\xfe\x0f\xa8\xb8|5\u007f\xdd\xcd\u0209\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc8sR\u06e5\x82\xee f\xb9\xc0\x02\xa9b\xe0\x03\x13Ox\xb1\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xc8|w\xe3\xc2J\xde\xcd\xcd\x108\xa3\x8bV\xe1\x8d\xea\u04f7\x02\x8a\x01\xdd\f\x88_\x9a\r\x80\x00\x00\u07d4\xc8}:\xe3\u0607\x04\u066b\x00\t\xdc\xc1\xa0\x06q1\xf8\xba<\x89j\xc5\xc6-\x94\x86\a\x00\x00\xe0\x94\u0201N4R>8\xe1\xf9'\xa7\xdc\xe8FjDz\t6\x03\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u0202U\xed\xdc\xf5!\xc6\xf8\x1d\x97\xf5\xa4!\x81\xc9\a=N\xf1\x89\x0f\u00d0D\xd0\n*\x80\x00\u07d4\u0205\xa1\x8a\xab\xf4T\x1b{{~\xcd0\xf6\xfa\u619d\x95i\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u020c\xa1\xe6\xe5\xf4\xd5X\xd17\x80\xf4\x88\xf1\rJ\xd3\x13\r4\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\u020e\xecT\xd3\x05\xc9(\xcc(H\xc2\xfe\xe251\xac\xb9mI\x89lj\u04c2\xd4\xfba\x00\x00\xe0\x94\u021c\xf5\x04\xb9\xf3\xf85\x18\x1f\xd8BO\\\xcb\xc8\xe1\xbd\xdf}\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u0222\xc4\xe5\x9e\x1c\u007f\xc5H\x05X\x048\xae\xd3\xe4J\xfd\xf0\x0e\x89\x02b\x9ff\xe0\xc50\x00\x00\u07d4\u022aI\u301f\b\x99\xf2\x8a\xb5~gCp\x9dXA\x903\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4\u022b\x1a<\xf4l\xb8\xb0d\xdf.\"-9`s\x94 2w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0231\x85\x05%\xd9F\xf2\xae\x84\xf3\x17\xb1Q\x88\xc56\xa5\u0706\x89\x91\x8d\xdc:B\xa3\xd4\x00\x00\u07d4\xc8\xd4\xe1Y\x9d\x03\xb7\x98\t\xe0\x13\n\x8d\u00c4\b\xf0^\x8c\u04c9\x9f\xad\x06$\x12y\x16\x00\x00\u07d4\xc8\xdd'\xf1k\xf2$P\xf5w\x1b\x9f\xe4\xedO\xfc\xb3\t6\xf4\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xc8\xdezVL\u007f@\x12\xa6\xf6\xd1\x0f\u040fG\x89\x0f\xbf\a\u0509\x10CV\x1a\x88)0\x00\x00\u07d4\xc8\xe2\xad\xebT^I\x9d\x98,\f\x11sc\u03b4\x89\u0171\x1f\x895e\x9e\xf9?\x0f\xc4\x00\x00\xe0\x94\xc8\xe5X\xa3\xc5i~o\xb2:%\x94\u0200\xb7\xa1\xb6\x8f\x98`\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xc8\xf2\xb3 \xe6\xdf\xd7\t\x06\u0157\xba\xd2\xf9P\x13\x12\u01c2Y\x89Q\x93K\x8b:W\xd0\x00\x00\u07d4\xc9\x03\x00\xcb\x1d@w\xe6\xa6\xd7\xe1i\xa4`F\x8c\xf4\xa4\x92\u05c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xc9\f7e\x15k\u028eH\x97\xab\x80$\x19\x15<\xbeR%\xa9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xc9\x10\xa9pUl\x97\x16\xeaS\xaff\xdd\xef\x93\x141$\x91=\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\xe0\x94\xc9\x12{\u007ff)\xee\x13\xfc?`\xbc/Dg\xa2\aE\xa7b\x8a\x03|\x9a\xa4\xe7\xceB\x1d\x80\x00\u07d4\xc9\x1b\xb5b\xe4+\xd4a0\xe2\u04eeFR\xb6\xa4\ub1bc\x0f\x89\x1dF\x01b\xf5\x16\xf0\x00\x00\xe0\x94\xc90\x88y\x05m\xfe\x13\x8e\xf8 \x8fy\xa9\x15\u01bc~p\xa8\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xc94\xbe\xca\xf7\x1f\"_\x8bJK\xf7\xb1\x97\xf4\xac\x9604\\\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc9?\xbd\xe8\xd4m+\xcc\x0f\xa9\xb3;\u063a\u007f\x80B\x12Ue\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xc9@\x89U:\xe4\xc2,\xa0\x9f\xbc\x98\xf5pu\xcf.\u0155\x04\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xc9A\x10\xe7\x1a\xfeW\x8a\xa2\x18\xe4\xfc(d\x03\xb03\n\u038d\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xc9F\u056c\xc14n\xba\nry\xa0\xac\x1dF\\\x99m\x82~\x8a\x03x=T_\xdf\n\xa4\x00\x00\u07d4\xc9J(\xfb20\xa9\xdd\xfa\x96Nw\x0f,\xe3\xc2S\xa7\xbeO\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xc9JXR\x03\xda{\xba\xfd\x93\xe1X\x84\xe6`\u0531\xea\xd8T\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\xc9O|5\xc0'\xd4}\xf8\xefO\x9d\xf8Z\x92H\xa1}\xd2;\x89\x01\x9f\x8euY\x92L\x00\x00\u07d4\xc9Q\x90\f4\x1a\xbb\xb3\xba\xfb\xf7\xee )7pq\xdb\xc3j\x89\x11\xc2]\x00M\x01\xf8\x00\x00\u07d4\xc9S\xf94\xc0\xeb-\x0f\x14K\u06b0\x04\x83\xfd\x81\x94\x86\\\xe7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc9f&r\x8a\xaaLO\xb3\xd3\x1c&\xdf:\xf3\x10\b\x17\x10\u0449\xb5\x0f\u03ef\xeb\xec\xb0\x00\x00\u07d4\xc9gQel\n\x8e\xf45{sD2!4\xb9\x83PJ\u0289lk\x93[\x8b\xbd@\x00\x00\u07d4\u0240Hh\u007f+\xfc\u027d\x90\xed\x18slW\xed\xd3R\xb6]\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u0241\xd3\x12\u0487\xd5X\x87\x1e\u0757:\xbbv\xb9y\xe5\xc3^\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u0242Xmc\xb0\xd7L \x1b\x1a\xf8A\x83r\xe3\fv\x16\xbe\x89\x05k\xc7^-c\x10\x00\x00\u07d4\u0249CO\x82Z\xaf\x9cU/h^\xba|\x11\xdbJ_\xc7:\x89\x1b(\u014d\x96\x96\xb4\x00\x00\u07d4\u0249\xee\xc3\a\u80db\x9dr7\xcf\xda\b\x82)b\xab\u41c9\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\u0252\xbeY\xc6r\x1c\xafN\x02\x8f\x9e\x8f\x05\xc2\\UQ[\u0509\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u0255{\xa9L\x1b)\xe5'~\xc3f\"pI\x04\xc6=\xc0#\x89h>\xfcg\x82d,\x00\x00\xe0\x94\u025a\x9c\xd6\xc9\xc1\xbe54\xee\u0352\xec\xc2/\\8\xe9Q[\x8a\x01\x05Y;:\x16\x9dw\x00\x00\xe0\x94\u026c\x01\xc3\xfb\t)\x03?\f\xcc~\x1a\xcf\uaae7\x94]G\x8a\x02\xa3j\x9e\x9c\xa4\xd2\x03\x80\x00\u07d4\u0276\x98\xe8\x98\xd2\rMO@\x8eNM\x06\x19\"\xaa\x85c\a\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\u0276\xb6\x86\x11\x16\x91\xeej\xa1\x97\xc7#\x1a\x88\xdc`\xbd)]\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc9\u01ec\v\u0753B\xb5\xea\xd46\t#\xf6\x8cr\xa6\xbac:\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xc9\xc8\r\xc1.{\xab\x86\xe9I\xd0\x1eL>\xd3_+\x9b\xba_\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xc9\xd7dF\u056a\xdf\xf8\vh\xb9\x1b\b\u035b\xc8\xf5U\x1a\xc1\x89&\xb4\xbd\x91\x10\xdc\xe8\x00\x00\xe0\x94\xc9\u073b\x05oM\xb7\xd9\xda9\x93b\x02\u017d\x820\xb3\xb4w\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xc9\xe0&\b\x06h(\x84\x8a\xeb(\xc76r\xa1)%\x18\x1fM\x89\x1b\x1bk\u05efd\xc7\x00\x00\u07d4\xca\x042\xcb\x15{Qy\xf0.\xbb\xa5\xc9\u0475O\xecM\x88\u028965\u026d\xc5\u07a0\x00\x00\u07d4\xca\x12,\xf0\U00094216\xb7HC\xf4\x9a\xfe\u043a\x16\x18\xee\u05c9\x1e[\x8f\xa8\xfe*\xc0\x00\x00\xe0\x94\xca\"\u0363`m\xa5\xca\xd0\x13\xb8\aG\x06\xd7\xe9\xe7!\xa5\f\x8a\x01q\x81\xc6\xfa9\x81\x94\x00\x00\u07d4\xca#\xf6-\xff\rd`\x03lb\xe8@\xae\xc5W~\v\xef\u0489\a\xa1\xfe\x16\x02w\x00\x00\x00\u07d4\xca%\xff4\x93L\x19B\xe2*N{\xd5o\x14\x02\x1a\x1a\xf0\x88\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xca7?\xe3\xc9\x06\xb8\xc6U\x9e\xe4\x9c\xcd\a\xf3|\xd4\xfbRf\x89a\t=|,m8\x00\x00\u07d4\xcaA\u032c0\x17 R\xd5\"\xcd//\x95}$\x81S@\x9f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xcaB\x88\x01N\xdd\xc5c/_\xac\xb5\xe3\x85\x17\xa8\xf8\xbc]\x98\x89\x12nr\xa6\x9aP\xd0\x00\x00\u07d4\xcaB\x88c\xa5\xca06\x98\x92\xd6\x12\x18>\xf9\xfb\x1a\x04\xbc\xea\x89Rf<\u02b1\xe1\xc0\x00\x00\u07d4\xcaI\xa5\xf5\x8a\xdb\xef\xae#\xeeY\xee\xa2A\xcf\x04\x82b.\xaa\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4\xcaL\xa9\xe4w\x9dS\x0e\u02ec\xd4~j\x80X\xcf\xdee\u064f\x89+^:\xf1k\x18\x80\x00\x00\u07d4\xcae~\xc0o\xe5\xbc\t\xcf#\xe5*\xf7\xf8\f\xc3h\x9en\u07890\xca\x02O\x98{\x90\x00\x00\u07d4\xcaf\xb2(\x0f\xa2\x82\u0176v1\xceU+b\xeeU\xad\x84t\x89j\xc4\"\xf54\x92\x88\x00\x00\xe0\x94\xcal\x81\x8b\xef\xd2Q6\x1e\x02t@h\xbe\x99\u062a`\xb8J\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xcap\xf4\u077f\x06\x9d!C\xbdk\xbc\u007fikRx\x9b2\u7262\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94\xcatuvDjL\x8f0\xb0\x83@\xfe\xe1\x98\xdec\xec\x92\u03ca\x01|\x8e\x12\x06r*0\x00\x00\u07d4\xca{\xa3\xffSl~_\x0e\x158\x00\xbd8=\xb81)\x98\xe0\x89\t1\xac=k\xb2@\x00\x00\xe0\x94\u0282v\xc4w\xb4\xa0{\x80\x10{\x845\x94\x18\x96\a\xb5;\xec\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\u0284\t\b>\x01\xb3\x97\xcf\x12\x92\x8a\x05\xb6\x84U\xceb\x01\u07c9V\xbcu\xe2\xd61\x00\x00\x00\u07d4\u0298\u01d8\x8e\xfa\b\xe9%\uf719ER\x03&\xe9\xf4;\x99\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u029a\x04*j\x80o\xfc\x92\x17\x95\x00\xd2D)\xe8\xabR\x81\x17\x89;\xa1\x91\v\xf3A\xb0\x00\x00\u07d4\u029d\xec\x02\x84\x1a\xdf\\\xc9 WjQ\x87\xed\u04bdCJ\x18\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u029f\xaa\x17T/\xaf\xbb8\x8e\xab!\xbcL\x94\u89f3G\x88\x89lk\x8f\xce\r\x18y\x80\x00\xe0\x94\u02aah\xeel\xdf\r4EJv\x9b\r\xa1H\xa1\xfa\xaa\x18e\x8a\x01\x87.\x1d\xe7\xfeR\xc0\x00\x00\u07d4\u02ad\x9d\xc2\rX\x9c\xe4(\xd8\xfd\xa3\xa9\xd5:`{y\x88\xb5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\u02b0\xd3,\xf3v\u007f\xa6\xb3S|\x842\x8b\xaa\x9fPE\x816\x8a\x01\xe5\xb8\xfa\x8f\xe2\xac\x00\x00\x00\u07d4\u02b9\xa3\x01\xe6\xbdF\xe9@5P(\xec\xcd@\xceMZ\x1a\u00c9\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\u02b9\xa9z\xda\x06\\\x87\x81nh`\xa8\xf1Bo\xe6\xb3\xd7u\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\u02ba\xb6'N\xd1P\x89s~({\xe8x\xb7W\x93Hd\xe2\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\u02bd\xaf5OG \xa4f\xa7d\xa5(\xd6\x0e:H*9<\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xca\xcbg^\t\x96#T\x04\ufbfb.\u02c1R'\x1bU\xe0\x89%\xf2s\x93=\xb5p\x00\x00\u07d4\xca\xd1O\x9e\xbb\xa7f\x80\xeb\x83k\a\x9c\u007f{\xaa\xf4\x81\xedm\x89\f\xef={\xd7\xd04\x00\x00\xe0\x94\xca\xe3\xa2S\xbc\xb2\xcfN\x13\xba\x80\u0098\xab\x04\x02\xda|*\xa0\x8a\x01$\xbc\r\u0752\xe5`\x00\x00\u07d4\xca\xef\x02{\x1a\xb5\x04\xc7?A\xf2\xa1\ty\xb4t\xf9~0\x9f\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xca\xf4H\x1d\x9d\xb7\x8d\xc4\xf2_{J\u023d;\x1c\xa0\x10k1\x8a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94\xca\xfd\xe8U\x86L%\x98\xda<\xaf\xc0Z\u064d\U00089380H\x8a\x03\x00\xa8\xed\x96\xffJ\x94\x00\x00\xe0\x94\xcb\r\xd7\xcfN]\x86a\xf6\x02\x89C\xa4\xb9\xb7\\\x91D6\xa7\x8a\x19i6\x89t\xc0[\x00\x00\x00\u07d4\xcb\x1b\xb6\xf1\xda^\xb1\rH\x99\xf7\xe6\x1d\x06\xc1\xb0\x0f\u07f5-\x898E$\xccp\xb7x\x00\x00\u07d4\xcb=vl\x98?\x19+\xce\xca\xc7\x0fN\xe0=\xd9\xffqMQ\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xcbB\xb4N\xb5\xfd`\xb5\x83~O\x9e\xb4rgR=\x1a\"\x9c\x89.\xe4IU\b\x98\xe4\x00\x00\u07d4\xcbG\xbd0\u03e8\xecTh\xaa\xa6\xa9FB\xce\xd9\xc8\x19\xc8\u0509\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xcbH\xfe\x82e\u066fU\xebp\x06\xbc3VE\xb0\xa3\xa1\x83\xbe\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xcbJ\x91M+\xb0)\xf3._\xef\\#LO\xec--\xd5w\x89a\x94\x04\x9f0\xf7 \x00\x00\xe0\x94\xcbJ\xbf\u0082\xae\xd7n]W\xaf\xfd\xa5B\xc1\xf3\x82\xfc\xac\xf4\x8a\x01\xb9\x0f\x11\xc3\x18?\xaa\x00\x00\u07d4\xcbJ\xd0\xc7#\xdaF\xabV\xd5&\xda\f\x1d%\xc7=\xaf\xf1\n\x89\x1b\xa5\xab\xf9\xe7y8\x00\x00\u07d4\xcbK\xb1\xc6#\xba(\xdcB\xbd\xaa\xa6\xe7N\x1d*\xa1%l*\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xcbPXt\x12\x82#\x04\xeb\u02e0}\xab:\x0f\t\xff\xfe\u4189JD\x91\xbdm\xcd(\x00\x00\u07d4\xcbX\x99\v\u0350\u03ffm\x8f\t\x86\xf6\xfa`\x02v\xb9N-\x8964\xbf9\xab\x98x\x80\x00\u07d4\xcbh\xaeZ\xbe\x02\xdc\xf8\xcb\u016aq\x9c%\x81FQ\xaf\x8b\x85\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xcbty\x10\x9bC\xb2fW\xf4F_M\x18\xc6\xf9t\xbe_B\x89b\xa9\x92\xe5:\n\xf0\x00\x00\xe0\x94\xcb}+\x80\x89\xe91,\u026e\xaa's\xf3S\b\xecl*{\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u02c6\xed\xbc\x8b\xbb\x1f\x911\x02+\xe6IV^\xbd\xb0\x9e2\xa1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u02d3\x19\x9b\x9c\x90\xbcI\x15\xbd\x85\x9e=B\x86m\xc8\xc1\x87I\x89\f\x90\xdf\a\xde\xf7\x8c\x00\x00\u07d4\u02d4\xe7o\xeb\xe2\b\x11g3\xe7n\x80]H\xd1\x12\xec\x9f\u028965\u026d\xc5\u07a0\x00\x00\u07d4\u02dbQ\x03\xe4\u0389\xafOd\x91aP\xbf\xf9\xee\u02df\xaa\\\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u02e2\\zP<\xc8\xe0\xd0Iq\xca\x05\xc7b\xf9\xb7b\xb4\x8b\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u02e2\x88\xcd<\x1e\xb4\u055d\xdb\x06\xa6B\x1c\x14\xc3E\xa4{$\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u02f3\x18\x9eK\xd7\xf4_\x17\x8b\x1c0\xc7n&1MJK\n\x89\x0f\xfe\vg|e\xa9\x80\x00\xe0\x94\u02f7\xbe\x17\x95?,\u0313\u1f19\x80[\xf4U\x11CNL\x8a\n\xae[\x9d\xf5m/ \x00\x00\xe0\x94\xcb\xc0KM\x8b\x82\xca\xf6p\x99o\x16\f6)@\xd6o\xcf\x1a\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xcb\u07974\xb8\xe6\xaaS\x8c)\x1dm\u007f\xac\xed\xb0\xf38\xf8W\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xcb\xe1\xb9H\x86M\x84t\xe7e\x14XX\xfc\xa4U\x0fxK\x92\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xcb\xe5/\xc53\xd7\xdd`\x8c\x92\xa2`\xb3|?E\u07b4\xeb3\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xcb\xe8\x10\xfe\x0f\xec\xc9dGJ\x1d\xb9w(\xbc\x87\xe9s\xfc\xbd\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xcb\xf1j\x0f\xe2tRX\xcdR\xdb+\xf2\x19T\xc9u\xfcj\x15\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94\xcb\xf3\u007f\xf8T\xa2\xf1\xceS\x93D\x94wx\x92\xd3\xeceW\x82\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xcb\xfaj\xf6\u0083\xb0F\xe2w,`c\xb0\xb2\x15S\xc4\x01\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcb\xfav\xdb\x04\xce8\xfb ]7\xb8\xd3w\xcf\x13\x80\xda\x03\x17\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4\xcc\x03I\x85\xd3\xf2\x8c-9\xb1\xa3K\xce\xd4\u04f2\xb6\xca#N\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\xcc\x04\x8d\u01f9]\xca%\xdf&\xee\xfac\x9d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcc+_D\x8f5(\xd3\xfeA\xcc}\x1f\xa9\xc0\xdcv\xf1\xb7v\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\xcc-\x04\xf0\xa4\x01q\x89\xb3@\xcaw\x19\x86A\xdc\xf6Ek\x91\x89\u0556{\xe4\xfc?\x10\x00\x00\xe0\x94\xccA\x9f\u0651+\x85\x13VY\xe7z\x93\xbc=\xf1\x82\xd4Q\x15\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xccE\xfb:U[\xad\x80{8\x8a\x03W\xc8U _|u\xe8\x89.\xe4IU\b\x98\xe4\x00\x00\u07d4\xccHAM*\xc4\xd4*Yb\xf2\x9e\xeeD\x97\t/C\x13R\x89\b\xbaR\xe6\xfcE\xe4\x00\x00\u07d4\xccJ/,\xf8l\xf3\xe43u\xf3`\xa4sF\x91\x19_\x14\x90\x89I\x15\x05;\xd1)\t\x80\x00\u07d4\xccO\x0f\xf2\xae\xb6}T\xce;\xc8\xc6Q\v\x9a\xe8>\x9d2\x8b\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xccO\xaa\xc0\v\xe6b\x8f\x92\xefk\x8c\xb1\xb1\xe7j\xac\x81\xfa\x18\x89\v\"\xa2\xea\xb0\xf0\xfd\x00\x00\xe0\x94\xccO\xebr\u07d8\xff5\xa18\xe0\x17a\xd1 ?\x9b~\xdf\n\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\xcc`oQ\x13\x97\xa3\x8f\u01c7+\u04f0\xbd\x03\xc7\x1b\xbdv\x8b\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xcc`\xf86\xac\xde\xf3T\x8a\x1f\xef\u0321>\u01a97\xdbD\xa0\x89\x04\xb0m\xbb\xb4\x0fJ\x00\x00\u07d4\xccl\x03\xbd`>\t\xdeT\xe9\xc4\u056cmA\xcb\xceqW$\x89\x05V\xf6L\x1f\xe7\xfa\x00\x00\u07d4\xccl-\xf0\x0e\x86\xec\xa4\x0f!\xff\xda\x1ag\xa1i\x0fG|e\x89\xabM\xcf9\x9a:`\x00\x00\xe0\x94\xccm{\x12\x06\x1b\xc9m\x10M`me\xff\xa3+\x006\xeb\a\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xccs\xdd5kIy\xb5y\xb4\x01\xd4\xccz1\xa2h\xdd\xceZ\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xccu\x8d\a\x1d%\xa62\n\xf6\x8c]\xc9\xc4\xf6\x95[\xa9E \x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xcc{\x04\x81\xcc2\xe6\xfa\xef#\x86\xa0p\"\xbc\xb6\xd2\u00f4\xfc\x89\xabM\xcf9\x9a:`\x00\x00\xe0\x94\u0314;\xe1\",\xd1@\n#\x99\xdd\x1bE\x94E\xcfmT\xa9\x8a\x02\xa7@\xaee6\xfc\x88\x00\x00\u07d4\u0315\x19\xd1\xf3\x98_k%^\xad\xed\x12\xd5bJ\x97'!\xe1\x8965\u026d\xc5\u07a0\x00\x00\u0794\u031a\xc7\x15\xcdo&\x10\xc5+XgdV\x88B\x97\x01\x8b)\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\u0320{\xb7\x94W\x1dJ\xcf\x04\x1d\xad\x87\xf0\xd1\xef1\x85\xb3\x19\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u032b\xc6\x04\x8aSFD$\xfc\xf7n\xeb\x9en\x18\x01\xfa#\u0509\x02\xab{&\x0f\xf3\xfd\x00\x00\u07d4\u032e\r=\x85*}\xa3\x86\x0f\x066\x15L\nl\xa3\x16(\u0509\x05\xc6\xd1+k\xc1\xa0\x00\x00\u07d4\xcc\xca$\xd8\xc5mn,\a\xdb\bn\xc0~X[\xe2g\xac\x8d\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xcc\xd5!\x13-\x98l\xb9hi\x84&\"\xa7\u0762l>\xd0W\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcc\xf49u\xb7k\xfes_\xec<\xb7\xd4\xdd$\xf8\x05\xba\tb\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\xcc\xf6*f?\x13S\xba.\xf8\xe6R\x1d\xc1\xec\xb6s\xec\x8e\xf7\x89\b=lz\xabc`\x00\x00\u07d4\xcc\xf7\x11\r\x1b\u0667K\xfd\x1d}}-\x9dU`~{\x83}\x890\xca\x02O\x98{\x90\x00\x00\u07d4\xcc\xfdrW`\xa6\x88#\xff\x1e\x06/L\xc9~\x13`\xe8\u0657\x89\x15\xacV\xed\xc4\xd1,\x00\x00\u07d4\xcd\x02\x0f\x8e\xdf\xcfRG\x98\xa9\xb7:d\x034\xbb\xf7/\x80\xa5\x89\a?u\u0460\x85\xba\x00\x00\u07d4\xcd\x06\xf8\xc1\xb5\u037d(\xe2\xd9kcF\xc3\xe8Z\x04\x83\xba$\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xcd\a.n\x183\x13y\x95\x19m{\xb1r_\xef\x87a\xf6U\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xcd\n\x16\x1b\xc3g\xae\t'\xa9*\xac\x9c\xf6\xe5\bg\x14\xef\u0289lk\x93[\x8b\xbd@\x00\x00\u07d4\xcd\n\xf3GN\"\xf0i\xec4\a\x87\r\xd7pD=[\x12\xb0\x89\x8e^\xb4\xeew\xb2\xef\x00\x00\u07d4\xcd\v\x02W\u70e3\xd2\xc2\u3e9dny\xb7^\xf9\x80$\u0509\x9f\xad\x06$\x12y\x16\x00\x00\u07d4\xcd\x10,\xd6\xdb=\xf1J\u05af\x0f\x87\xc7$y\x86\x1b\xfc=$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcd\x1ef\xedS\x9d\xd9/\xc4\v\xba\xa1\xfa\x16\u078c\x02\xc1ME\x89\fw\xe4%hc\xd8\x00\x00\u07d4\xcd\x1e\xd2c\xfb\xf6\xf6\xf7\xb4\x8a\xef\x8fs=2\x9dC\x82\xc7\u01c9\x01\x00\xbd3\xfb\x98\xba\x00\x00\u07d4\xcd*6\xd7S\xe9\xe0\xed\x01*XMqh\aX{A\xd5j\x89\x0e+\xa7[\v\x1f\x1c\x00\x00\u07d4\xcd2\xa4\xa8\xa2\u007f\x1c\xc69T\xaacOxW\x05s4\u01e3\x89:\xd1fWlr\xd4\x00\x00\u07d4\xcd5\xff\x01\x0e\xc5\x01\xa7!\xa1\xb2\xf0z\x9c\xa5\x87}\xfc\xf9Z\x89\xd9o\u0390\u03eb\xcc\x00\x00\u07d4\xcdC\x06\xd7\xf6\x94z\xc1tMN\x13\xb8\xef2\xcbe~\x1c\x00\x89\x1b\x1a\xb3\x19\xf5\xecu\x00\x00\u07d4\xcdC%\x8bs\x92\xa90\x83\x9aQ\xb2\xef\x8a\xd24\x12\xf7Z\x9f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcdI\xbf\x18^p\xd0E\a\x99\x9f\x92\xa4\xdeDU1('\u040965\u026d\xc5\u07a0\x00\x00\u07d4\xcdU\x10\xa2B\u07f0\x18=\xe9%\xfb\xa8f\xe3\x12\xfa\xbc\x16W\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\xcdVj\u05f8\x83\xf0\x1f\u04d9\x8a\x9aX\xa9\xde\xe4rM\u0725\x89\x030\xae\x185\xbe0\x00\x00\xe0\x94\xcdY\xf3\xdd\xe7~\t\x94\v\xef\xb6\xeeX\x03\x19e\xca\xe7\xa36\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xcdr]p\xbe\x97\xe6w\xe3\xc8\xe8\\\v&\xef1\xe9\x95PE\x89Hz\x9a0E9D\x00\x00\xe0\x94\xcd~G\x90\x94d\xd8q\xb9\xa6\xdcv\xa8\xe9\x19]\xb3H^z\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\xcd~\xce\bkKa\x9b;6\x93R\xee8\xb7\x1d\xdb\x06C\x9a\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xcd\u007f\t\xd7\xedf\xd0\u00cb\u016dN2\xb7\xf2\xb0\x8d\xc1\xb3\r\x89>;\xb3M\xa2\xa4p\x00\x00\u07d4\u0355)I+\\)\xe4u\xac\xb9A@+=;\xa5\x06\x86\xb0\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u0355\xfaB=o\xc1 'J\xac\xde\x19\xf4\xee\xb7f\xf1\x04 \x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\u035bL\xefs9\f\x83\xa8\xfdq\u05f5@\xa7\xf9\u03cb\x8c\x92\x89\x04\xe1\x00;(\xd9(\x00\x00\u07d4\u0361t\x11\t\xc0&[?\xb2\xbf\x8d^\xc9\u00b8\xa34kc\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u0361\xb8\x86\u39d5\u027aw\x91N\n/\xe5go\x0f\\\u03c9\x05\xbf`\xeaB\xc2\x04\x00\x00\u07d4\u0364S\x0fK\x9b\xc5\t\x05\xb7\x9d\x17\u008f\xc4o\x954\x9b\u07c93\x10\xe0I\x11\xf1\xf8\x00\x00\u07d4\u036bF\xa5\x90 \x80do\xbf\x95B\x04 J\xe8\x84\x04\x82+\x89\x1d\x8a\x96\xe5\xc6\x06\xeb\x00\x00\u07d4\u0375\x97)\x900\x18?n-#\x853\xf4d*\xa5\x87T\xb6\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xcd\xd5\u0601\xa76,\x90p\a;\u07fcu\xe7$S\xacQ\x0e\x89-\xa5\x18\xea\xe4\x8e\xe8\x00\x00\u07d4\xcd\xd6\rs\xef\xaa\xd8s\u027b\xfb\x17\x8c\xa1\xb7\x10Z\x81\xa6\x81\x89\x01\xbc\x16\xd6t\xec\x80\x00\x00\u07d4\xcd\xd9\xef\xacMm`\xbdq\xd9U\x85\xdc\xe5\u0557\x05\xc15d\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xcd\xe3m\x81\xd1(\u015d\xa1Ee!\x93\xee\u00bf\xd9e\x86\xef\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xcd\xea8o\x9d\x0f\xd8\x04\xd0(\x18\xf27\xb7\xd9\xfavF\xd3^\x89\xa3I\xd3m\x80\xecW\x80\x00\u07d4\xcd\xec\xf5gT3\u0370\xc2\xe5Zh\xdb]\x8b\xbexA\x9d\u0489\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xcd\xfd\x82\x173\x97%\xd7\xeb\xac\x11\xa66U\xf2e\xef\xf1\xcc=\x8a\x01\x0f\fid\x10\xe3\xa9\x00\x00\u07d4\xce\a\x9fQ\x88wt\xd8\x02\x1c\xb3\xb5u\xf5\x8f\x18\xe9\xac\xf9\x84\x89\t\xc2\x00vQ\xb2P\x00\x00\u07d4\xce\x18\x84\u077b\xb8\xe1\x0eM\xbanD\xfe\xee\u00a7\xe5\xf9/\x05\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xce\x1b\f\xb4j\xae\xcf\u05db\x88\f\xad\x0f-\u068a\x8d\xed\u0431\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xce&\xf9\xa50_\x83\x81\tCT\xdb\xfc\x92fN\x84\xf9\x02\xb5\x89\fz\xaa\xb0Y\x1e\xec\x00\x00\u07d4\xce-\xea\xb5\x1c\n\x9a\xe0\x9c\xd2\x12\xc4\xfaL\xc5+S\xcc\r\xec\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xce.\r\xa8\x93F\x99\xbb\x1aU>U\xa0\xb8\\\x16\x945\xbe\xa3\x8a\x01\x0f\fid\x10\xe3\xa9\x00\x00\u07d4\xce:a\xf0F\x1b\x00\x93^\x85\xfa\x1e\xad\x82\xc4^Zd\u0508\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xceK\x06]\xbc\xb20G 2b\xfbH\xc1\x18\x83d\x97tp\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xceS\xc8\xcd\xd7B\x96\xac\xa9\x87\xb2\xbc\x19\u00b8u\xa4\x87I\u0409\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xce^\x04\xf0\x18Ci\xbc\xfa\x06\xac\xa6o\xfa\x91\xbfY\xfa\x0f\xb9\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xce^\xb6:{\xf4\xfb\xc2\xf6\u4ea0\u018a\xb1\xcbL\xf9\x8f\xb4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xceb\x12Z\xde\xc37\n\xc5!\x10\x95:Nv\v\xe9E\x1e;\x89\b=lz\xabc`\x00\x00\xe0\x94\xceq\bmL`%T\xb8-\xcb\xfc\xe8\x8d cMS\xccM\x8a\t(\x96R\x9b\xad\u0708\x00\x00\u07d4\u038akmP3\xb1I\x8b\x1f\xfe\xb4\x1aAU\x04\x05\xfa\x03\xa2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u0397\x86\xd3q/\xa2\x00\xe9\xf6\x857\xee\xaa\x1a\x06\xa6\xf4ZK\x89a\t=|,m8\x00\x00\u07d4\u039d!\u0192\xcd<\x01\xf2\x01\x1fP_\x87\x006\xfa\x8fl\u0489\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\u03a2\x89f#\xf4\x91\x02\x87\xa2\xbd\u017e\x83\xae\xa3\xf2\xe6\xde\b\x8a\x01\xfbZ7Q\xe4\x90\xdc\x00\x00\u07d4\u03a3JM\xd9=\u066e\xfd9\x90\x02\xa9}\x99z\x1bK\x89\u0349QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\u03a4?pu\x81k`\xbb\xfc\u62d9:\xf0\x88\x12p\xf6\u0109lk\x93[\x8b\xbd@\x00\x00\u07d4\u03a8t3AS<\xb2\xf0\xb9\xc6\xef\xb8\xfd\xa8\rw\x16(%\x89\x05k\xc7^-c\x10\x00\x00\u07d4\u03b0\x89\xec\x8ax3~\x8e\xf8\x8d\xe1\x1bI\xe3\u0751\x0ft\x8f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u03b3=x\xe7Tz\x9d\xa2\xe8}Q\xae\xc5\xf3D\x1c\x87\x92:\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u03b3\x898\x1dH\xa8\xaeO\xfcH:\u043b^ L\xfd\xb1\xec\x89('\xe6\xe4\xddb\xba\x80\x00\u07d4\xce\xc6\xfce\x85?\x9c\xce_\x8e\x84Fv6.\x15y\x01_\x02\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xce\xd3\u01fe\x8d\xe7XQ@\x95*\xebP\x1d\xc1\xf8v\ucbf0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xce\xd8\x1e\xc3S?\xf1\xbf\xeb\xf3\xe3\x84>\xe7@\xad\x11u\x8d>\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xce\u0733\xa1\u0584?\xb6\xbe\xf6Ca}\xea\U000cf398\xdd_\x89\x19\xe2\xa4\xc8\x18\xb9\x06\x00\x00\u07d4\xce\xe6\x99\xc0pzx6%+)/\x04|\xe8\xad(\x9b/U\x89\x11\x9a\x1e!\xaaiV\x00\x00\u07d4\xce\xedG\xca[\x89\x9f\xd1b?!\xe9\xbdM\xb6Z\x10\u5c1d\x89\a8w@L\x1e\xee\x00\x00\u07d4\xce\xf7tQ\u07e2\xc6C\xe0\v\x15mlo\xf8N#s\xebf\x89\n1\x06+\xee\xedp\x00\x00\u07d4\xcf\x11i\x04\x1c\x17E\xe4[\x17$5\xa2\xfc\x99\xb4\x9a\xce+\x00\x89\x01\xbb\x88\xba\xab-|\x00\x00\xe0\x94\xcf\x15v\x12vN\x0f\u0596\xc8\xcb_\xba\x85\xdfL\r\xdc<\xb0\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u0794\xcf\x1b\xdby\x9b.\xa6<\xe14f\x8b\xdc\x19\x8bT\x84\x0f\x18\v\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xcf\"\x88\xefN\xbf\x88\xe8m\xb1=\x8a\x0e\v\xf5*\x05e\x82\u00c9\x89Po\xbf\x97@t\x00\x00\u07d4\xcf&Ni%\x13\t\x06\xc4\xd7\xc1\x85\x91\xaaA\xb2\xa6\u007foX\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcf&\xb4{\xd04\xbcP\x8elK\xcf\xd6\xc7\xd3\x004\x92Wa\x89a\x94\x04\x9f0\xf7 \x00\x00\xe0\x94\xcf.*\xd65\xe9\x86\x1a\xe9\\\xb9\xba\xfc\xca\x03kR\x81\xf5\u038a\at2!~h6\x00\x00\x00\u07d4\xcf.s@B\xa3U\xd0_\xfb.9\x15\xb1h\x11\xf4Zi^\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcf4\x8f/\xe4{~A<\az{\xaf:u\xfb\xf8B\x86\x92\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xcf?\x91(\xb0r\x03\xa3\xe1\r}WU\xc0\u012b\xc6\xe2\xca\u008a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xcf?\xbf\xa1\xfd2\u05e6\xe0\xe6\xf8\xefN\xabW\xbe4\x02\\L\x899\xa1\xc0\xf7YMH\x00\x00\u07d4\xcfAftn\x1d;\xc1\xf8\xd0qK\x01\xf1~\x8ab\xdf\x14d\x896w\x03n\xdf\n\xf6\x00\x00\u07d4\xcfO\x118\xf1\xbdk\xf5\xb6\u0505\xcc\xe4\xc1\x01\u007f\u02c5\xf0}\x89/\u043cw\xc3+\xff\x00\x00\u07d4\xcfZo\x9d\xf7Uy\xc6D\xf7\x94q\x12\x15\xb3\rw\xa0\xce@\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcf^\x0e\xac\u0473\x9d\x06U\xf2\xf7u5\xeff\b\xeb\x95\v\xa0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xcfhM\xfb\x83\x04r\x93U\xb5\x83\x15\xe8\x01\x9b\x1a\xa2\xad\x1b\xac\x89\x17r$\xaa\x84Lr\x00\x00\u07d4\xcfi@\x81\xc7m\x18\xc6L\xa7\x13\x82\xbe\\\xd6;<\xb4v\xf8\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xcfnR\xe6\xb7t\x80\xb1\x86~\xfe\xc6Dm\x9f\xc3\xcc5w\xe8\x89\f\t\x01\xf6\xbd\x98y\x00\x00\u07d4\u03c8: 2\x96g\xea\"j\x1e\x9a\x92*\x12\xf2\x1f\xaa\x03\x81V\x91\x8cO\u02dc\x89\x04E\x91\xd6\u007f\xec\xc8\x00\x00\u07d4\xcf\xf7\xf8\x9aMB\x19\xa3\x82\x95%\x131V\x82\x10\xff\xc1\xc14\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xcf\xf8\xd0k\x00\xe3\xf5\f\x19\x10\x99\xadV\xbaj\xe2eq\u0348\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xcf\xfcI\xc1x~\ubcb5l\xab\xe9$\x04\xb66\x14}EX\x8a\x013\xe00\x8f@\xa3\u0680\x00\u07d4\xd0\bQ;'`J\x89\xba\x17c\xb6\xf8L\u6233F\x94[\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd0\x0f\x06r\x86\xc0\xfb\u0402\xf9\xf4\xa6\x10\x83\xecv\u07b3\xce\xe6\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd0\x15\xf6\xfc\xb8M\xf7\xbbA\x0e\x8c\x8f\x04\x89J\x88\x1d\xca\xc27\x898E$\xccp\xb7x\x00\x00\u07d4\xd0\x1a\xf9\x13O\xafRW\x17N\x8by\x18oB\xee5Nd-\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd0!\b\u04ae<\xab\x10\xcb\xcf\x16W\xaf\">\x02|\x82\x10\xf6\x89lm\x84\xbc\xcd\xd9\xce\x00\x00\u07d4\xd0*\xfe\u03ce.\u00b6*\u022d Aa\xfd\x1f\xaew\x1d\x0e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd01\x919\xfb\xab.\x8e*\xcc\xc1\xd9$\u0531\x1d\xf6ilZ\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd07\xd2\x15\xd1\x1d\x1d\xf3\xd5O\xbd2\x1c\u0495\xc5F^';\x89K\xe4\xe7&{j\xe0\x00\x00\u07d4\xd0:-\xa4\x1e\x86\x8e\xd3\xfe\xf5t[\x96\xf5\xec\xa4b\xffo\u0689\xa2\xa1]\tQ\x9b\xe0\x00\x00\xe0\x94\xd0?\xc1eWj\xae\xd5%\xe5P,\x8e\x14\x0f\x8b.\x86\x969\x8a\x01sV\u0633%\x01\xc8\x00\x00\u07d4\xd0C\xa0\x11\xecBp\xee~\u0239hsu\x15\xe5\x03\xf80(\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd0K\x86\x1b=\x9a\xccV:\x90\x16\x89\x94\x1a\xb1\xe1\x86\x11a\xa2\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd0ZD|\x91\x1d\xbb'[\xfb.Z7\xe5\xa7\x03\xa5o\x99\x97\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd0_\xfb+t\xf8g O\xe51e;\x02H\xe2\x1c\x13TN\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd0bX\x81q\u03d9\xbb\xebX\xf1&\xb8p\xf9\xa3r\x8da\xec\x89\xf3\xf2\v\x8d\xfai\xd0\x00\x00\u07d4\xd0c\x8e\xa5q\x89\xa6\xa6\x99\x02J\u05ccq\xd99\xc1\xc2\xff\x8c\x89\x8e\xaeVg\x10\xfc \x00\x00\xe0\x94\xd0d\x8aX\x1b5\b\xe15\xa2\x93]\x12\xc9epE\xd8q\u028a\x01\xb2\u07dd!\x9fW\x98\x00\x00\u07d4\xd0q\x19)f\xebi\xc3R\x0f\xca:\xa4\xdd\x04)~\xa0KN\x89\x05\xf6\x8e\x811\xec\xf8\x00\x00\u07d4\xd0q\x85 \xea\xe0\xa4\xd6-p\xde\x1b\xe0\xcaC\x1c^\xea$\x82\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd0w]\xba*\xf4\xc3\n:x6Y9\xcdq\xc2\xf9\u0795\u0489i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xd0{\xe0\xf9\t\x97\xca\xf9\x03\u022c\x1dS\xcd\xe9\x04\xfb\x19\aA\x8968\x908\xb6\x99\xb4\x00\x00\u07d4\xd0~Q\x18d\xb1\u03d9i\xe3V\x06\x02\x82\x9e2\xfcNq\xf5\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\u0400\x94\x98\xc5H\x04z\x1e**\xa6\xa2\x9c\xd6\x1a\x0e\xe2h\xbd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0402'_tZ,\xac\x02v\xfb\xdb\x02\u0532\xa3\xab\x17\x11\xfe\x89\x01\xa0Ui\r\x9d\xb8\x00\x00\u07d4\u040f\xc0\x9a\x000\xfd\t(\xcd2\x11\x98X\x01\x82\xa7j\xae\x9f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u0413\xe8)\x81\x9f\xd2\xe2[\x978\x00\xbb=XA\xdd\x15-\x05\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u0414J\xa1\x85\xa13pa\xae \u071d\xd9l\x83\xb2\xbaF\x02\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\u0416V[|t\a\xd0e6X\x03U\xfd\xd6\xd29\x14J\xa1\x89\r\x8drkqw\xa8\x00\x00\u07d4\u041c\xb2\xe6\b-i:\x13\xe8\xd2\xf6\x8d\xd1\u0744a\xf5X@\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u0426\xc6\xf9\xe9\u0133\x83\xd7\x16\xb3\x1d\xe7\x8dVAM\xe8\xfa\x91\x89\x10CV\x1a\x88)0\x00\x00\u07d4\u0427 \x9b\x80\xcf`\xdbb\xf5}\n]}R\x1ai`fU\x89\b\xacr0H\x9e\x80\x00\x00\xe0\x94\u0428\xab\xd8\n\x19\x9bT\xb0\x8be\xf0\x1d \x9c'\xfe\xf0\x11[\x8a\x01a\xc6&\xdca\xa2\xef\x80\x00\xe0\x94\u042b\xccp\xc0B\x0e\x0e\x17/\x97\xd4;\x87\xd5\xe8\f3n\xa9\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u042es]\x91^\x94hf\xe1\xfe\xa7~^\xa4f\xb5\xca\xdd\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0431\x1do+\u0394^\fjP \u00f5'S\xf8\x03\xf9\u0449\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xd0\xc1\x01\xfd\x1f\x01\xc6?k\x1d\x19\xbc\x92\r\x9f\x93#\x14\xb16\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xd0\xc5Z\xbf\x97o\xdc=\xb2\xaf\u9f99\u0519HMWl\x02\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd0\u0422\xadE\xf5\x9a\x9d\xcc\u0195\xd8_%\xcaF\xed1\xa5\xa3\x89-\x89W}}@ \x00\x00\u07d4\xd0\xd6,G\xea`\xfb\x90\xa3c\x92\t\xbb\xfd\xd4\xd93\x99\x1c\u0189\n\x84Jt$\xd9\xc8\x00\x00\u07d4\xd0\xdbEax o\\D0\xfe\x00Pc\x90<=zI\xa7\x89&I\x1eE\xa7S\xc0\x80\x00\u07d4\xd0\xe1\x94\xf3K\x1d\xb6\t(\x85\t\xcc\xd2\xe7;a1\xa2S\x8b\x8965f3\xeb\xd8\xea\x00\x00\u07d4\xd0\xe3^\x04vF\xe7Y\xf4Qp\x93\xd6@\x86BQ\u007f\bM\x89\u054f\xa4h\x18\xec\u02c0\x00\u07d4\xd0\xeeM\x02\xcf$8,0\x90\xd3\xe9\x95`\xde6xs\\\u07c9\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\xd0\xf0OR\x10\x9a\xeb\xec\x9a{\x1e\x932v\x1e\x9f\xe2\xb9{\xb5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd0\xf9Yx\x11\xb0\xb9\x92\xbb}7W\xaa%\xb4\xc2V\x1d2\xe2\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd1\x03\x02\xfa\xa1\x92\x9a2i\x04\xd3v\xbf\v\x8d\xc9:\xd0LL\x89a\t=|,m8\x00\x00\xe0\x94\xd1\x10\r\xd0\x0f\xe2\xdd\xf1\x81c\xad\x96M\vi\xf1\xf2\xe9e\x8a\x8a\x01C\x12\tU\xb2Pk\x00\x00\u07d4\xd1\x16\xf3\xdc\xd5\xdbtK\xd0\b\x88v\x87\xaa\x0e\xc9\xfdr\x92\xaa\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd1\x19A|Fs,\xf3M\x1a\x1a\xfby\xc3\xe7\xe2\u034e\xec\xe4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd1-w\xae\x01\xa9-5\x11{\xacpZ\xac\u0642\xd0.t\xc1\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xd15yK\x14\x9a\x18\xe1G\xd1nb\x1ai1\xf0\xa4\n\x96\x9a\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xd1C%8\xe3[vd\x95j\u4563*\xbd\xf0A\xa7\xa2\x1c\x8a\x04+\xf0kx\xed;P\x00\x00\u07d4\xd1C\x82g#\x17\x04\xfcr\x80\xd5c\xad\xf4v8D\xa8\a\"\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd1S\x8e\x9a\x87\u5729\xec\x8eX&\xa5\xb7\x93\xf9\x9f\x96\xc4\u00c965\u026d\xc5\u07a0\x00\x00\xe0\x94\xd1d\x85\x03\xb1\xcc\u0178\xbe\x03\xfa\x1e\xc4\xf3\xee&~j\xdf{\x8a\x01;\xef\xbfQ\xee\xc0\x90\x00\x00\xe0\x94\xd1h,!Y\x01\x8d\xc3\xd0\u007f\b$\n\x8c`m\xafe\xf8\xe1\x8a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xd1q\xc3\xf2%\x8a\xef5\xe5\x99\xc7\xda\x1a\xa0s\x00#M\xa9\xa6\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd1w\x8c\x13\xfb\xd9h\xbc\b<\xb7\xd1\x02O\xfe\x1fI\xd0,\xaa\x89\xd9\xec\xb4\xfd \x8eP\x00\x00\u07d4\xd1\u007f\xbe\"\xd9\x04b\xed7(\x06p\xa2\xea\v0\x86\xa0\xd6\u0589\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4\u0441\x1cU\x97i\x80\xf0\x83\x90\x1d\x8a\r\xb2i\"-\xfb\\\xfe\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\u044e\xb9\xe1\u0485\u06be\x93\xe5\u053a\xe7k\xee\xfeC\xb5!\xe8\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\u0453\xe5\x83\xd6\a\x05c\xe7\xb8b\xb9aJG\u9509\xf3\xe5\x8965f3\xeb\xd8\xea\x00\x00\u07d4\u0457\x8f.4@\u007f\xab\x1d\xc2\x18=\x95\xcf\xdab`\xb3Y\x82\x89*\xb7\xb2`\xff?\xd0\x00\x00\u07d4\u045c\xaf9\xbb7\u007f\xdf,\xf1\x9b\xd4\xfbRY\x1c&1\xa6<\x8965\u026d\xc5\u07a0\x00\x00\u0794\u0463\x96\xdc\u06b2\xc7IA0\xb3\xfd0x 4\r\xfd\x8c\x1f\x88\xf9\"P\xe2\xdf\xd0\x00\x00\xe0\x94\u0467\x1b-\bX\xe82p\b]\x95\xa3\xb1T\x96P\x03^#\x8a\x03'\xbb\t\xd0j\xa8P\x00\x00\u07d4\u046c\xb5\xad\xc1\x189s%\x8dk\x85$\xff\xa2\x8f\xfe\xb2=\xe3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u0473\u007f\x03\xcb\x10t$\xe9\xc4\xddW\\\xcdOL\xeeW\xe6\u0349lk\x93[\x8b\xbd@\x00\x00\u07d4\u0475\xa4T\xac4\x05\xbbAy \x8cl\x84\xde\x00k\u02db\xe9\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd1\xc4YT\xa6+\x91\x1a\xd7\x01\xff.\x90\x13\x1e\x8c\xeb\x89\xc9\\\x89K\x91\xa2\xdeE~\x88\x00\x00\u07d4\xd1\xc9np\xf0Z\xe0\xe6\xcd`!\xb2\b7P\xa7q|\xdeV\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd1\u0571\u007f\xfe-{\xbby\xcc}y0\xbc\xb2\xe5\x18\xfb\x1b\xbf\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xd1\xda\f\x8f\xb7\xc2\x10\xe0\xf2\xeca\x8f\x85\xbd\xae}>sK\x1c\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xd1\xddy\xfb\x15\x81`\xe5\xb4\xe8\xe2?1.j\x90\u007f\xbcMN\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd1\xdeZ\xad:_\xd8\x03\U00071bb6\x10<\xb8\xe1O\xe7#\xb7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd1\xe1\xf2\xb9\xc1l0\x98t\xde\xe7\xfa\xc3&u\xaf\xf1)\u00d8\x89\x03\xf2M\x8eJ\x00p\x00\x00\xe0\x94\xd1\xe5\xe24\xa9\xf4Bf\xa4\xa6$\x1a\x84\u05e1\xa5Z\u0567\xfe\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xd1\xeaMr\xa6{[>\x0f1UY\xf5+\xd0aMq0i\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd1\xee\x90YW\xfe|\xc7\x0e\xc8\xf2\x86\x8bC\xfeG\xb1?\xeb\xff\x89\x02b\x9ff\xe0\xc50\x00\x00\u07d4\xd1\xf1iM\"g\x1bZ\xadj\x94\x99\\6\x9f\xbea3go\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd1\xf4\xdc\x1d\u06ca\xbb\x88H\xa8\xb1N%\xf3\xb5Z\x85\x91\xc2f\x89\r\x8drkqw\xa8\x00\x00\u07d4\xd1\xfe\u042e\xe6\xf5\xdf\xd7\xe2Wi%L<\xfa\xd1Z\xde\u032a\x89'\x92\xc8\xfcKS(\x00\x00\u07d4\xd2\x05\x1c\xb3\xcbg\x04\xf0T\x8c\u0210\xab\n\x19\xdb4\x15\xb4*\x89\x12\x1b.^ddx\x00\x00\u07d4\xd2\x06\xaa\u07736\xd4^yr\xe9<\xb0uG\x1d\x15\x89{]\x89 \x86\xac5\x10R`\x00\x00\u07d4\xd2\tH+\xb5I\xab\xc4w{\xeam\u007fe\x00b\xc9\xc5z\x1c\x89\x11e\x1a\xc3\xe7\xa7X\x00\x00\u07d4\xd2\r\xcb\vxh+\x94\xbc0\x00(\x14H\xd5W\xa2\v\xfc\x83\x890\x84\x9e\xbe\x166\x9c\x00\x00\u07d4\xd2\x10{57&\u00e2\xb4ef\xea\xa7\xd9\xf8\v]!\xdb\xe3\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd2\x11\xb2\x1f\x1b\x12\xb5\ta\x81Y\r\xe0~\xf8\x1a\x89S~\xad\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd2\x18\xef\xb4\u06d8\x1c\xddjy\u007fK\u050c|&)<\xeb@\x89\xa1Fk1\xc6C\x1c\x00\x00\xe0\x94\xd2\x1asA\xeb\x84\xfd\x15\x10T\xe5\u31fb%\xd3nI\x9c\t\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\xe0\x94\xd2$\xf8\x80\xf9G\x9a\x89\xd3/\t\xe5+\u9432\x88\x13\\\xef\x8a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u07d4\xd2/\f\xa4\xcdG\x9ef\x17u\x05;\xccI\xe3\x90\xf6p\u074a\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd21\x92\x975\x13!\x02G\x1b\xa5\x90\a\xb6dL\xc0\xc1\xde>\x8967\tlK\xcci\x00\x00\u07d4\xd25\xd1\\\xb5\xec\xee\xbba)\x9e\x0e\x82\u007f\xa8'H\x91\x1d\x89\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd2:$\xd7\xf9F\x83C\xc1C\xa4\x1ds\xb8\x8f|\xbec\xbe^\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd2=z\xff\xac\xdc>\x9f=\xaez\xfc\xb4\x00oX\xf8\xa4F\x00\x89\xc3(\t>a\xee@\x00\x00\u07d4\xd2C\x18L\x80\x1e]y\xd2\x06?5x\u06ee\x81\u7ce9\u02c9k\u0722h\x1e\x1a\xba\x00\x00\u07d4\xd2KfD\xf49\xc8\x05\x1d\xfcd\u04c1\xb8\xc8lu\xc1u8\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xd2K\xf1--\xdfE}\xec\xb1xt\xef\xde R\xb6\\\xbbI\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\xe0\x94\xd2Q\xf9\x03\xae\x18rrY\xee\xe8A\xa1\x89\xa1\xf5i\xa5\xfdv\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xd2R\x96\v\v\xf6\xb2\x84\x8f\u07ad\x80\x13m\xb5\xf5\a\xf8\xbe\x02\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xd2X\x1aU\xce#\xab\x10\u062d\x8cD7\x8fY\a\x9b\xd6\xf6X\x8a\x01\xdd\f\x88_\x9a\r\x80\x00\x00\u07d4\xd2Z\xec\xd7\xeb\x8b\xd64[\x06;]\xbd'\x1cw\xd3QD\x94\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xd2|#O\xf7\xac\xca\xce=\x99g\b\xf8\xf9\xb0Ip\xf9}6\x89Hz\x9a0E9D\x00\x00\u07d4\u0482\x98RM\xf5\xecK$\xb0\xff\xb9\u07c5\x17\n\x14Z\x9e\xb5\x89\x0f\x98\xa3\xb9\xb37\xe2\x00\x00\xe0\x94\u0483\xb8\xed\xb1\n%R\x8aD\x04\xde\x1ce\xe7A\r\xbc\xaag\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\u0484\xa5\x03\x82\xf8:am9\xb8\xa9\xc0\xf3\x96\xe0\ubfe9]\x8966\xc2^f\xec\xe7\x00\x00\u07d4\u0488\xe7\xcb{\xa9\xf6 \xab\x0ftR\xe5\bc=\x1cZ\xa2v\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\u049d\xc0\x8e\xfb\xb3\xd7.&?x\xabv\x10\xd0\"m\xe7k\x00\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\u04a00\xac\x89R2_\x9e\x1d\xb3x\xa7\x14\x85\xa2N\x1b\a\xb2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u04a4y@CG\xc5T:\xab)*\xe1\xbbJo\x15\x83W\xfa\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\u04a5\xa0$#\nW\xcc\xc6fv\v\x89\xb0\xe2l\xaf\u0449\u01ca\n\x96YZ\\n\x8a?\x80\x00\u07d4\u04a8\x03'\xcb\xe5\\L{\xd5\x1f\xf9\xdd\xe4\xcad\x8f\x9e\xb3\xf8\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\u04a8Oug\\b\xd8\f\x88ulB\x8e\xee+\xcb\x18T!\x89A\rXj \xa4\xc0\x00\x00\u07d4\u04ab\xd8J\x18\x10\x93\xe5\xe2)\x13oB\xd85\xe8#]\xe1\t\x89\x05k\xe0<\xa3\xe4}\x80\x00\u07d4\u04ac\r:X`^\x1d\x0f\x0e\xb3\xde%\xb2\xca\xd1)\xed`X\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u04bfg\xa7\xf3\xc6\xceV\xb7\xbeAg]\xbb\xad\xfe~\xa9:3\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xd2\xdb\xeb\xe8\x9b\x03W\xae\xa9\x8b\xbe\x8eIc8\u07bb(\xe8\x05\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd2\xe2\x1e\xd5hh\xfa\xb2\x8e\tG\x92z\xda\xf2\x9f#\xeb\xadl\x89l\x18O\x13U\xd0\xe8\x00\x00\u07d4\xd2\xe8\x17s\x8a\xbf\x1f\xb4\x86X?\x80\xc3P1\x8b\xed\x86\f\x80\x89\r\x02\xce\xcf_]\x81\x00\x00\u07d4\xd2\xed\xd1\xdd\xd6\xd8m\xc0\x05\xba\xebT\x1d\"\xb6@\xd5\xc7\xca\xe5\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd2\xf1\x99\x8e\x1c\xb1X\f\xecOl\x04}\xcd=\xce\xc5L\xf7<\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd2\xf2A%]\xd7\xc3\xf7<\a\x040q\xec\b\xdd\xd9\xc5\xcd\xe5\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd2\xffg \x16\xf6;/\x859\x8fJo\xed\xbb`\xa5\r<\u0389\x12\x91$o[sJ\x00\x00\u07d4\xd3\rLC\xad\xcfU\xb2\xcbS\u0583#&A4I\x8d\x89\u038965\u026d\xc5\u07a0\x00\x00\u07d4\xd3\x0e\xe9\xa1+Mh\xab\xac\xe6\xba\u029a\u05ff\\\xd1\xfa\xf9\x1c\x89QO\xcb$\xff\x9cP\x00\x00\u07d4\xd3\x11\x8e\xa3\xc85\x05\xa9\u0613\xbbg\xe2\xde\x14-Sz>\xe7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd3\x11\xbc\u05eaN\x9bO8?\xf3\xd0\u05b6\xe0~!\xe3p]\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd3\x15\xde\xea\x1d\x8c\x12q\xf9\xd11\x12c\xabG\xc0\a\xaf\xb6\xf5\x89\x03\xc8\x1dNeK@\x00\x00\u07d4\xd3+,y\xc3dx\xc5C\x19\x01\xf6\xd7\x00\xb0M\xbe\x9b\x88\x10\x89\x15w\x9a\x9d\xe6\xee\xb0\x00\x00\u07d4\xd3+EVF\x14Ql\x91\xb0\u007f\xa9\xf7-\xcfx|\xceN\x1c\x89\x0f\xc6o\xae7F\xac\x00\x00\u07d4\xd30r\x811\xfe\x8e:\x15Hz4W<\x93E~*\xfe\x95\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd31\xc8#\x82Z\x9eRc\xd0R\u0611]M\xcd\xe0z\\7\x89\x1e\x93\x12\x83\xcc\xc8P\x00\x00\u07d4\xd33btE\xf2\u05c7\x90\x1e\xf3;\xb2\xa8\xa3g^'\xff\xec\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xd3<\xf8+\xf1LY&@\xa0\x86\b\x91L#py\u057e4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd3Mp\x8ds\x98\x02E3\xa5\xa2\xb20\x9b\x19\xd3\xc5Qq\xbb\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xd3N\x03\xd3j+\xd4\u045a_\xa1b\x18\xd1\xd6\x1e?\xfa\v\x15\x89\x11X\xe4`\x91=\x00\x00\x00\u07d4\xd3Pu\xcaa\xfeY\xd1#\x96\x9c6\xa8-\x1a\xb2\xd9\x18\xaa8\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\xd3g\x00\x9a\xb6X&;b\xc23:\x1c\x9eA@I\x8e\x13\x89\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd3g\x9aG\xdf-\x99\xa4\x9b\x01\u024d\x1c>\f\x98|\xe1\xe1X\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\xe0\x94\u04cf\xa2\xc4\xcc\x14z\xd0j\u0562\xf7Uy(\x1f\"\xa7\xcc\x1f\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\u04da]\xa4`9+\x94\v\u01ee8\xf1e\u007f\x8a\x01f\xc5H\b\x89\xdbw\x00\x00\xe0\x94\xd3\xd6\xe9\xfb\x82T/\u049e\xd9\xea6\t\x89\x1e\x15\x13\x96\xb6\xf7\x8a\voX\x8a\xa7\xbc\xf5\xc0\x00\x00\xe0\x94\xd3\xda\u0476\u040dE\x81\u032ee\xa8s-\xb6\xaci\xf0\u019e\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xd3\xdf;S\xcb;GU\xdeT\xe1\x80E\x1c\xc4L\x9e\x8a\u0a89#\u0114\t\xb9w\x82\x80\x00\u07d4\xd3\xf8s\xbd\x99V\x13W\x89\xab\x00\xeb\xc1\x95\xb9\"\xe9K%\x9d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd4\x02\xb4\xf6\xa0\x99\xeb\xe7\x16\xcb\x14\xdfOy\xc0\xcd\x01\xc6\a\x1b\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xd4\r\x00U\xfd\x9a8H\x8a\xff\x92?\xd0=5\xecF\xd7\x11\xb3\x8a\x01\x0f\b\xed\xa8\xe5U\t\x80\x00\u07d4\xd4\x0e\xd6j\xb3\xce\xff$\xca\x05\xec\xd4q\ufd12\xc1__\xfa\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd4\x18\x87\v\xc2\xe4\xfa{\x8aa!\xae\br\xd5RG\xb6%\x01\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xd4\x1d\u007f\xb4\x9f\xe7\x01\xba\xac%qpBl\u0273\x8c\xa3\xa9\xb2\x89\t\x8a}\x9b\x83\x14\xc0\x00\x00\u07d4\xd4 U\x92\x84@U\xb3\u01e1\xf8\f\xef\xe3\xb8\xebP\x9b\xcd\xe7\x89\t\xb3\xbf\xd3B\xa9\xfc\x80\x00\u07d4\xd4+ \xbd\x03\x11`\x8bf\xf8\xa6\xd1[*\x95\xe6\xde'\u017f\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd44O}\\\xade\xd1~\\-\x0es#\x94=ob\xfe\x92\x89\x0e~\xeb\xa3A\vt\x00\x00\u07d4\xd4>\xe48\xd8=\xe9\xa3ub\xbbN(l\xb1\xbd\x19\xf4\x96M\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd4C4\xb4\xe2:\x16\x9a\f\x16\xbd!\xe8f\xbb\xa5-\x97\x05\x87\x89\x8c\xf2?\x90\x9c\x0f\xa0\x00\x00\xe0\x94\xd4M\x81\xe1\x8fF\xe2\u03f5\xc1\xfc\xf5\x04\x1b\xc8V\x97g\xd1\x00\x8a\a\xb4B\xe6\x84\xf6Z\xa4\x00\x00\u07d4\xd4OJ\xc5\xfa\xd7k\xdc\x157\xa3\xb3\xafdr1\x9bA\r\x9d\x89V\xbcu\xe2\xd61\x00\x00\x00\u07d4\xd4O^\xdf+\xcf$3\xf2\x11\xda\xdd\f\xc4P\xdb\x1b\x00\x8e\x14\x89\x0e~\xeb\xa3A\vt\x00\x00\xe0\x94\xd4Oj\u00d2;_\xd71\xa4\xc4YD\xecO~\xc5*j\xe4\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xd4[3A\xe8\xf1\\\x802\x93 \u00d7~;\x90\xe7\x82j~\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xd4]]\xaa\x13\x8d\xd1\xd3t\xc7\x1b\x90\x19\x91h\x11\xf4\xb2\nN\x89\x1f9\x9b\x148\xa1\x00\x00\x00\u07d4\xd4`\xa4\xb9\b\xdd+\x05gY\xb4\x88\x85\vf\xa88\xfcw\xa8\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xd4g\xcf\x06L\bq\x98\x9b\x90\u0632\xeb\x14\xcc\xc6;6\b#\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd4k\xaea\xb0'\xe5\xbbB.\x83\xa3\xf9\xc9?<\x8f\xc7}'\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd4o\x82#E)\x82\xa1\xee\xa0\x19\xa8\x81n\xfc-o\xc0\ah\x89\amA\xc6$\x94\x84\x00\x00\u07d4\xd4uG\u007f\xa5c\x90\xd30\x17Q\x8dg\x11\x02\u007f\x05\U0008dfc9k\x11\x133\xd4\xfdL\x00\x00\u07d4\xd4|$.\xdf\xfe\xa0\x91\xbcT\xd5}\xf5\xd1\xfd\xb91\x01Gl\x89\x9d\xf7\u07e8\xf7`H\x00\x00\u07d4\xd4}\x86\x85\xfa\xee\x14|R\x0f\u0646p\x91u\xbf/\x88k\xef\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd4\u007fP\u07c9\xa1\xcf\xf9e\x13\xbe\xf1\xb2\xae:)q\xac\xcf,\x89-\x89W}}@ \x00\x00\u07d4\u0502\xe7\xf6\x8eA\xf28\xfeQx)\xde\x15G\u007f\xe0\xf6\xdd\x1d\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u0507\x9f\xd1+\x1f:'\xf7\xe1\tv\x1b#\xca4\xfa#\x06K\x1c\xaf\x00Qn(pJ\x82\xa4\xf8\x89Hz\x9a0E9D\x00\x00\u07d4\xd5\x00\xe4\xd1\u0242K\xa9\xf5\xb65\u03e3\xa8\xc2\u00cb\xbdL\xed\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xd5\b\u04dcp\x91oj\xbcL\xc7\xf9\x99\xf0\x11\xf0w\x10X\x02\x89\x05rM$\xaf\xe7\u007f\x00\x00\u07d4\xd5\x0f\u007f\xa0>8\x98v\u04d0\x8b`\xa57\xa6pc\x04\xfbV\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xd5\x13\xa4P\x80\xff/\xeb\xe6,\u0545J\xbe)\xeeDg\xf9\x96\x89\bN\x13\xbcO\xc5\xd8\x00\x00\u07d4\xd5'o\f\xd5\xff\xd5\xff\xb6?\x98\xb5p=U\x94\xed\xe0\x83\x8b\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xd5)KfbB0;m\xf0\xb1\u020d7B\x9b\xc8\xc9e\xaa\x89\x10M\r\x00\u04b7\xf6\x00\x00\u07d4\xd5*\xec\xc6I98\xa2\x8c\xa1\xc3g\xb7\x01\xc2\x15\x98\xb6\xa0.\x89;\xa1\x91\v\xf3A\xb0\x00\x00\u07d4\xd5\x99x\xee \xa3\x8c?I\x8dc\xd5\u007f1\xa3\x9fj\x06\x8a\x022\xb3o\xfcg*\xb0\x00\x00\u07d4\u05568\xd3\xc5\xfa\xa7q\x1b\xf0\x85t_\x9d[\xdc#\u0518\u0609lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u055d\x92\xd2\xc8p\x19\x80\xcc\a<7]r\n\xf0dt<\f\x8a\x04\x05\xfd\xf7\u5bc5\xe0\x00\x00\u07d4\u0567\xbe\xc32\xad\xde\x18\xb3\x10KW\x92Tj\xa5\x9b\x87\x9bR\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0571\x17\xec\x11n\xb8FA\x89a\xeb~\xdbb\x9c\xd0\xddi\u007f\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\u0572\x84\x04\x010\xab\xf7\xc1\xd1cq#q\xcc~(\xadf\u0689j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u0579\xd2w\u062a\xd2\x06\x97\xa5\x1fv\xe2\tx\x99k\xff\xe0U\x89\a\xc3\xfe<\aj\xb5\x00\x00\u07d4\u057d^\x84U\xc10\x16\x93W\xc4q\xe3\u6077\x99jrv\x89-\x9e(\x8f\x8a\xbb6\x00\x00\u07d4\xd5\u02e5\xb2k\xea]s\xfa\xbb\x1a\xba\xfa\xcd\xef\x85\xde\xf3h\u0309\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd5\xceU\u0476/YC\xc0?\x89\b\xe3\x1f\xe1h\x9d\x8a\x00\x00\u07d4\xd6\x06Q\xe3\x93x4#\xe5\xcc\x1b\xc5\xf8\x89\xe4N\xf7\xea$>\x89\x15\x9ev7\x11)\xc8\x00\x00\u07d4\xd6\t\xbfO\x14n\xeak\r\xc8\xe0m\xdc\xf4D\x8a\x1f\xcc\xc9\xfa\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd6\t\xec\v\xe7\r\n\xd2ong\xc9\xd4v+R\xeeQ\x12,\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd6\nRX\a(R\r\xf7Tk\xc1\xe2\x83)\x17\x88\u06ee\f\x8964\x89\xef?\xf0\xd7\x00\x00\u07d4\xd6\v$s!\xa3*Z\xff\xb9k\x1e'\x99'\xccXM\xe9C\x89z\xd0 \xd6\xdd\xd7v\x00\x00\u07d4\xd6\x11\x02v\xcf\xe3\x1eB\x82ZW\u007fkC]\xbc\xc1\f\xf7d\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xd6\x12Y{\xc3\x17C\u01c63\xf63\xf29\xb1\xe9Bk\xd9%\x8a\x10\x17\xf7\u07d6\xbe\x17\x80\x00\x00\u07d4\xd6#J\xafE\xc6\xf2.f\xa2%\xff\xb9:\xddb\x9bN\xf8\x0f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd6.\u06d6\xfc\u259a\xaflT^\x96|\xf1\xc0\xbc\x80R\x05\x89\x04\xa5eSjZ\u0680\x00\u07d4\xd60\v2\x15\xb1\x1d\xe7b\xec\xdeKp\xb7\x92}\x01)\x15\x82\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd69]\xb5\xa4\xbbf\xe6\x0fL\xfb\xcd\xf0\x05{\xb4\xd9xb\xe2\x891T\xc9r\x9d\x05x\x00\x00\xe0\x94\xd6J-P\xf8\x85\x857\x18\x8a$\xe0\xf5\r\xf1h\x1a\xb0~\u05ca\b7Z*\xbc\xca$@\x00\x00\u07d4\xd6X\n\xb5\xedL}\xfaPo\xa6\xfed\xad\\\xe1)pw2\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd6Y\x8b\x13\x86\xe9<\\\u02d6\x02\xffK\xbb\xec\xdb\xd3p\x1d\u0109\f%\xf4\xec\xb0A\xf0\x00\x00\u07d4\xd6dM@\xe9\v\xc9\u007f\xe7\xdf\xe7\u02bd2i\xfdW\x9b\xa4\xb3\x89\b\x9e\x91y\x94\xf7\x1c\x00\x00\xe0\x94\xd6g\f\x03m\xf7T\xbeC\xda\u074fP\xfe\xea(\x9d\x06\x1f\u058a\x01D\xa2\x904H\xce\xf7\x80\x00\u07d4\xd6hR:\x90\xf0)=e\xc58\xd2\xddlWg7\x10\x19n\x89\x02$,0\xb8S\xee\x00\x00\u07d4\xd6j\xb7\x92\x94\aL\x8bb}\x84-\xabA\xe1}\xd7\f]\xe5\x8965\u026d\xc5\u07a0\x00\x00\u0794\xd6j\xcc\r\x11\xb6\x89\u03a6\xd9\xea_\xf4\x01L\"J]\xc7\u0108\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xd6m\xdf\x11Y\xcf\"\xfd\x8czK\xc8\u0540wV\xd43\xc4>\x89wC\"\x17\xe6\x83`\x00\x00\u07d4\u0587\xce\xc0\x05\x90\x87\xfd\xc7\x13\xd4\xd2\xd6^w\xda\xef\xed\xc1_\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\u0588\xe7\x85\u024f\x00\xf8K:\xa1S3U\u01e2X\xe8yH\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u05a2.Y\x8d\xab\u04ce\xa6\xe9X\xbdy\u050d\u0756\x04\xf4\u07c965\u026d\xc5\u07a0\x00\x00\u07d4\u05a7\xacM\xe7\xb5\x10\xf0\xe8\xdeQ\x9d\x97?\xa4\xc0\x1b\xa84\x00\x89e\xea=\xb7UF`\x00\x00\u07d4\u05ac\xc2 \xba.Q\xdf\xcf!\xd4C6\x1e\xeav\\\xbd5\u0609\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u05ac\xff\u043f\u065c8.{\xd5o\xf0\xe6\x14J\x9eR\xb0\x8e\x89\b\xacr0H\x9e\x80\x00\x00\u07d4\xd6\xc0\u043c\x93\xa6.%qtp\x0e\x10\xf0$\u0232?\x1f\x87\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xd6\xcf\\\x1b\u03dd\xa6b\xbc\xea\"U\x90P\x99\xf9\xd6\xe8M\u030a\x01\u011eB\x01W\xd9\xc2\x00\x00\u07d4\xd6\xd05r\xa4RE\xdb\xd46\x8cO\x82\xc9W\x14\xbd!g\xe2\x89?\x00\xc3\xd6f\x86\xfc\x00\x00\u07d4\xd6\xd6wiX\xee#\x14:\x81\xad\xad\xeb\b8 \t\xe9\x96\u0089\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xd6\xd9\xe3\x0f\bB\x01*qv\xa9\x17\xd9\xd2\x04\x8c\xa0s\x87Y\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd6\xe0\x9e\x98\xfe\x13\x003!\x04\xc1\xca4\xfb\xfa\xc5T6N\u0649lk\x93[\x8b\xbd@\x00\x00\u07d4\xd6\xe8\xe9z\u90db\x9e\xe5\a\xee\xdb(\xed\xfbtw\x03\x149\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd6\uea18\u052e+q\x80'\xa1\x9c\xe9\xa5\xebs\x00\xab\xe3\u0289\x01}J\xce\xeec\u06c0\x00\xe0\x94\xd6\xf1\xe5[\x16\x94\b\x9e\xbc\xb4\xfe}x\x82\xaaf\u0217av\x8a\x04<#\xbd\xbe\x92\x9d\xb3\x00\x00\u07d4\xd6\xf4\xa7\xd0N\x8f\xaf \xe8\xc6\ub15c\xf7\xf7\x8d\xd2=z\x15\x89\a$\xde\xd1\xc7H\x14\x00\x00\u07d4\xd6\xfc\x04F\u01a8\xd4\n\xe3U\x1d\xb7\xe7\x01\xd1\xfa\x87nJI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd7\x03\u01a4\xf1\x1d`\x19Ey\u054c'f\xa7\xef\x16\xc3\n)\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd7\x05%\x19uj\xf4%\x90\xf1S\x91\xb7#\xa0?\xa5d\xa9Q\x89\xfa61H\r\x01\xfd\x80\x00\u07d4\xd7\na+\xd6\u0769\xea\xb0\xdd\xdc\xffJ\xafA\"\u04cf\xea\xe4\x89\x1dF\x01b\xf5\x16\xf0\x00\x00\u07d4\xd7\n\xd2\xc4\xe9\uefe67\xefV\xbdHj\u04a1\xe5\xbc\xe0\x93\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd7\x14\f\x8eZC\a\xfa\xb0\xcc'\xba\u0752\x95\x01\x8b\xf8yp\x89\x05\xf1\x01kPv\xd0\x00\x00\u07d4\xd7\x16J\xa2a\xc0\x9a\u0672\xb5\x06\x8dE>\xd8\xebj\xa10\x83\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xd7\x1eC\xa4Qw\xadQ\xcb\xe0\xf7!\x84\xa5\xcbP9\x17(Z\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd7\x1f\xb10\xf0\x15\fVRi\xe0\x0e\xfbC\x90+R\xa4U\xa6\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd7\"W8\xdc\xf3W\x848\xf8\xe7\u0233\x83~B\xe0J&/\x89\x18+\x8c\ubec3\xaa\x00\x00\u07d4\xd7'MP\x80M\x9cw\u0693\xfaH\x01V\xef\xe5{\xa5\x01\u0789i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xd71\xbbk_<79^\t\u03ac\xcd\x14\xa9\x18\xa6\x06\a\x89\x89\u0556{\xe4\xfc?\x10\x00\x00\xe0\x94\xd7>\xd2\u0645\xb5\xf2\x1bU\xb2td;\xc6\xda\x03\x1d\x8e\u074d\x8a\nm\xd9\f\xaeQ\x14H\x00\x00\u07d4\xd7D\xac~S\x10\xbeijc\xb0\x03\xc4\v\xd097\x05a\u0189Z\x87\xe7\xd7\xf5\xf6X\x00\x00\xe0\x94\xd7Jn\x8dj\xab4\u0385\x97h\x14\xc12{\xd6\xea\a\x84\u048a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xd7ZP*[gr\x87G\x0fe\u016aQ\xb8|\x10\x15\x05r\x8910\xb4dc\x85t\x00\x00\u07d4\xd7m\xba\xeb\xc3\rN\xf6{\x03\xe6\xe6\xec\xc6\xd8N\x00MP-\x89mv\xb9\x18\x8e\x13\x85\x00\x00\u07d4\xd7q\xd9\xe0\u028a\b\xa1\x13wW1CN\xb3'\x05\x99\xc4\r\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xd7x\x8e\xf2\x86X\xaa\x06\xccS\xe1\xf3\xf0\xdeX\xe5\xc3q\xbex\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\xd7x\x92\xe2';#]v\x89\xe40\xe7\xae\ud73c\xe8\xa1\xf3\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u05c1\xf7\xfc\t\x18F\x11V\x85p\xb4\x98n,r\x87+~\u0409\x01\x15\x95a\x06]]\x00\x00\u07d4\u05c5\xa8\xf1\x8c8\xb9\xbcO\xfb\x9b\x8f\xa8\xc7r{\xd6B\xee\x1c\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u05ce\xcd%\xad\xc8k\xc2\x05\x1d\x96\xf6Sd\x86kB\xa4&\xb7\x89\xd20X\xbf/&\x12\x00\x00\xe0\x94\u05cf\x84\xe3\x89D\xa0\xe0%_\xae\xceH\xbaIP\u053d9\u048a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\u05d4\x83\xf6\xa8DO%I\xd6\x11\xaf\xe0,C-\x15\xe1\x10Q\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u05d85\xe4\x04\xfb\x86\xbf\x84_\xba\t\rk\xa2^\f\x88f\xa6\x89\x82\x1a\xb0\xd4AI\x80\x00\x00\u07d4\u05da\xff\x13\xba-\xa7]F$\f\xac\n$g\xc6V\x94\x98#\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\u05dd\xb5\xabCb\x1az=\xa7\x95\xe5\x89)\xf3\xdd%\xafg\u0649lj\xccg\u05f1\xd4\x00\x00\u07d4\u05e1C\x1e\xe4S\xd1\xe4\x9a\x05P\xd1%hy\xb4\xf5\xd1\x02\x01\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4\u05ed\t\xc6\xd3&WhSU\xb5\xc6\uc39fW\xb4\ube42\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u05f7@\xdf\xf8\xc4Wf\x8f\xdft\xf6\xa2f\xbf\xc1\u0737#\xf9\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xd7\u0080>\u05f0\xe0\x83sQA\x1a\x8ef7\xd1h\xbc[\x05\x8a\x06A\xda\xf5\xc9\x1b\xd95\x80\x00\u07d4\xd7\xc6&]\xea\x11\x87l\x90;q\x8eL\u062b$\xfe&[\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\xd7\xca\u007f\xdc\xfe\xbeE\x88\xef\xf5B\x1d\x15\"\xb6\x13(\xdf{\xf3\x89\xd8\xe6\x00\x1el0+\x00\x00\u07d4\xd7\u037dA\xff\xf2\r\xf7'\xc7\vbU\xc1\xbav\x06\x05Th\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd7\xd1W\xe4\xc0\xa9d7\xa6\u0485t\x1d\xd2>\xc46\x1f\xa3k\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd7\xd2\xc6\xfc\xa8\xad\x1fu9R\x10\xb5}\xe5\xdf\xd6s\x939\t\x89\x12nr\xa6\x9aP\xd0\x00\x00\xe0\x94\xd7\xd3\xc7Y Y\x048\xb8,>\x95\x15\xbe.\xb6\xedz\x8b\x1a\x8a\f\xb4\x9bD\xba`-\x80\x00\x00\u07d4\xd7\xd7\xf2\u02a4b\xa4\x1b;0\xa3J\xeb;\xa6\x10\x10\xe2bo\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd7\xe7J\xfd\xba\xd5^\x96\u03bcZ7O,\x8bv\x86\x80\xf2\xb0\x89\x05]\xe6\xa7y\xbb\xac\x00\x00\xe0\x94\xd7\xeb\x901b'\x1c\x1a\xfa5\xfei\xe3s\"\u0224\u049b\x11\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xd7\xeb\u0779\xf99\x87w\x9bh\x01U7T8\xdbe\xaf\xcbj\x89\x05t\x1a\xfe\xff\x94L\x00\x00\u07d4\xd7\xef4\x0ef\xb0\u05ef\xcc\xe2\n\x19\xcb{\xfc\x81\xda3\xd9N\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xd7\xf3p\u053e\xd9\xd5|oI\u0259\xder\x9e\xe5i\xd3\xf4\xe4\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd7\xfa_\xfb`H\xf9o\xb1\xab\xa0\x9e\xf8{\x1c\x11\xddp\x05\xe4\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd8\x06\x9f\x84\xb5!I?G\x15\x03\u007f2&\xb2_3\xb6\x05\x86\x89g\x8a\x93 b\xe4\x18\x00\x00\u0794\xd8\x15\xe1\xd9\xf4\xe2\xb5\xe5~4\x82k|\xfd\x88\x81\xb8Th\x90\x88\xf0\x15\xf2W6B\x00\x00\u07d4\xd8\x1b\xd5K\xa2\xc4Jok\xeb\x15a\u058b\x80\xb5DNm\u0189?\x17\r~\xe4\"\xf8\x9c\x80-1({\x96q\xe8\x1c\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\xd8K\x92/xA\xfcWt\xf0\x0e\x14`J\xe0\xdfB\xc8U\x1e\x89\xd9o\u0390\u03eb\xcc\x00\x00\u07d4\xd8U\xb0<\xcb\x02\x9awG\xb1\xf0s\x03\xe0\xa6dy59\u0209lk\x93[\x8b\xbd@\x00\x00\u07d4\xd8_\u07af*a\xf9]\xb9\x02\xf9\xb5\xa5<\x9b\x8f\x92f\u00ec\x89l\xf6Z~\x90G(\x00\x00\u07d4\xd8q^\xf9\x17o\x85\v.0\xeb\x8e8'\a\xf7w\xa6\xfb\xe9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd8t\xb9\u07eeEj\x92\x9b\xa3\xb1\xa2~W,\x9b,\xec\u07f3\x89\t79SM(h\x00\x00\u07d4\u0613\n9\xc7sW\xc3\n\u04e0`\xf0\v\x06\x04c1\xfdb\x89,s\xc97t,P\x00\x00\u07d4\u061b\xc2q\xb2{\xa3\xabib\xc9JU\x90\x06\xae8\xd5\xf5j\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0637}\xb9\xb8\x1b\xbe\x90B{b\xf7\x02\xb2\x01\xff\u009f\xf6\x18\x892m\x1eC\x96\xd4\\\x00\x00\u07d4\xd8\xcdd\xe0(N\xecS\xaaF9\xaf\xc4u\b\x10\xb9\u007f\xabV\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd8\xd6C\x84$\x9bwg\x94\x06;V\x98x\xd5\xe3\xb50\xa4\xb2\x89\t\xa0C\u0432\xf9V\x80\x00\u07d4\xd8\xd6T \xc1\x8c#'\xccZ\xf9t%\xf8W\xe4\xa9\xfdQ\xb3\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xd8\xe5\xc9g^\xf4\xde\xed&k\x86\x95o\xc4Y\x0e\xa7\u0522}\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xd8\xe8GB\x92\xe7\xa0Q`L\xa1d\xc0pw\x83\xbb(\x85\xe8\x8a\x02\xd4\xca\x05\xe2\xb4<\xa8\x00\x00\u07d4\xd8\xebxP>\xc3\x1aT\xa9\x016x\x1a\xe1\t\x00Lt2W\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd8\xee\xf4\xcfK\xeb\x01\xee \xd1\x11t\x8ba\xcbM?d\x1a\x01\x89\x94\x89#z\u06daP\x00\x00\u07d4\xd8\xf4\xba\xe6\xf8M\x91\rm}Z\xc9\x14\xb1\xe6\x83r\xf9A5\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xd8\xf6 6\xf0;v5\xb8X\xf1\x10?\x8a\x1d\x90\x19\xa8\x92\xb6\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\xd8\xf6e\xfd\x8c\xd5\u00bc\xc6\xdd\xc0\xa8\xaeR\x1eM\u01aa``\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xd8\xf9$\fU\xcf\xf05RB\x80\xc0\x9e\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xd8\xfe\b\x8f\xff\u0394\x8fQ7\xee#\xb0\x1d\x95\x9e\x84\xacB#\x89\f[T\xa9O\xc0\x17\x00\x00\u07d4\xd9\x0f0\t\xdbC~N\x11\u01c0\xbe\u0209os\x8de\xef\r\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd9\x10;\xb6\xb6zU\xa7\xfe\xce-\x1a\xf6-E|!x\x94m\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd9\x13\xf0w\x19Iu\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xd9D\u0226\x9f\xf2\xca\x12Ii\f\x12)\xc7\x19/6%\x10b\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xd9JW\x88*Rs\x9b\xbe*\x06G\xc8\f$\xf5\x8a+O\x1c\x89H\xb5N*\xdb\xe1+\x00\x00\xe0\x94\xd9SB\x95<\x8a!\xe8\xb65\xee\xfa\u01c1\x9b\xea0\xf1pG\x8a\x13\xf0l\u007f\xfe\xf0]@\x00\x00\u07d4\xd9\\\x90\xff\xbeT\x84\x86G\x80\xb8gIJ\x83\u0212V\xd6\xe4\x89X\xe7\x92n\xe8X\xa0\x00\x00\u07d4\xd9g\x11T\x0e.\x99\x83C\xd4\xf5\x90\xb6\xfc\x8f\xac;\xb8\xb3\x1d\x89_Z@h\xb7\x1c\xb0\x00\x00\u07d4\xd9j\xc2Pt\t\u01e3\x83\xab.\xee\x18\"\xa5\xd78\xb3kV\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xd9m\xb3;{Z\x95\f>\xfa-\xc3\x1b\x10\xba\x10\xa52\uf1c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xd9wYe\xb7\x16Gfu\xa8\xd5\x13\xeb\x14\xbb\xf7\xb0|\xd1J\x8a\x01\x13.m-#\xc5\xe4\x00\x00\u07d4\xd9{\xc8J\xbdG\xc0[\xbfE{.\xf6Y\xd6\x1c\xa5\xe5\u43c9\x06\x9d\x17\x11\x9d\u0168\x00\x00\u07d4\xd9\u007fE&\u07a9\xb1c\xf8\xe8\xe3:k\u03d2\xfb\x90}\xe6\xec\x89\x0feJ\xafM\xb2\xf0\x00\x00\u07d4\xd9\u007f\xe6\xf5?*X\xf6\xd7mu*\xdft\xa8\xa2\xc1\x8e\x90t\x89\x10\xcd\xf9\xb6\x9aCW\x00\x00\u07d4\u0659\x99\xa2I\r\x94\x94\xa50\xca\xe4\xda\xf3\x85T\xf4\xddc>\x89\x06\x81U\xa46v\xe0\x00\x00\u07d4\u065d\xf7B\x1b\x93\x82\xe4,\x89\xb0\x06\xc7\xf0\x87p*\aW\xc0\x89\x1a\x05V\x90\xd9\u06c0\x00\x00\xe0\x94\u0677\x83\xd3\x1d2\xad\xc5\x0f\xa3\xea\u02a1]\x92\xb5h\xea\xebG\x8a\a3\xaf\x907L\x1b(\x00\x00\u07d4\xd9\xd3p\xfe\xc65v\xab\x15\xb3\x18\xbf\x9eX6M\u00a3U*\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xd9\xd4/\xd1>\xbdK\xf6\x9c\xac^\x9c~\x82H:\xb4m\xd7\xe9\x8a\x01!\xeah\xc1\x14\xe5\x10\x00\x00\u07d4\xd9\xe2~\xb0}\xfcq\xa7\x06\x06\f\u007f\a\x928\u0293\xe8\x859\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xd9\xe3\x85~\xfd\x1e *D\x17p\xa7w\xa4\x9d\xccE\xe2\xe0\u04c9\f\x1d\xaf\x81\u0623\xce\x00\x00\u07d4\xd9\xec.\xfe\x99\xff\\\xf0\r\x03\xa81{\x92\xa2J\xefD\x1f~\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xd9\xec\x8f\xe6\x9bw\x16\xc0\x86Z\xf8\x88\xa1\x1b+\x12\xf7 \xed3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xd9\xf1\xb2d\b\xf0\xecg\xad\x1d\ro\xe2.\x85\x15\xe1t\x06$\x89\x01M\x11 \u05f1`\x00\x00\u07d4\xd9\xf5G\xf2\xc1\xde\x0e\u064aS\xd1a\xdfWc]\xd2\x1a\x00\xbd\x89\x05V\xf6L\x1f\xe7\xfa\x00\x00\u07d4\xd9\xff\x11]\x01&l\x9fs\xb0c\xc1\xc28\xef5e\xe6;6\x89$\xdc\xe5M4\xa1\xa0\x00\x00\u07d4\xda\x06\x04N)#&\xffil\x0091h\xceF\xff\xac9\xec\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xda*\x14\xf9r@\x15\u05d0\x14\xed\x8eY\th\x1dYaH\xf1\x89\x02\xa1\x0f\x0f\x8a\x91\xab\x80\x00\u07d4\xda*\u054ew\xde\xdd\xed\xe2\x18vF\xc4e\x94Z\x8d\xc3\xf6A\x89#\xc7W\a+\x8d\xd0\x00\x00\u07d4\xda0\x17\xc1P\xdd\r\xce\u007f\u03c8\x1b\nH\xd0\xd1\xc7V\xc4\u01c9\x05k\xf9\x1b\x1ae\xeb\x00\x00\u07d4\xda4\xb2\xea\xe3\v\xaf\xe8\xda\xec\xcd\xe8\x19\xa7\x94\u0349\xe0\x95I\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xdaJ_U\u007f;\xab9\n\x92\xf4\x9b\x9b\x90\n\xf3\fF\xae\x80\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xdaPU7S\u007f\xfb3\xc4\x15\xfe\xc6Ni\xba\xe0\x90\xc5\xf6\x0f\x89\b\xacr0H\x9e\x80\x00\x00\u07d4\xdai\x8dd\xc6\\\u007f+,rS\x05\x9c\xd3\u0441\u0619\xb6\xb7\x89\x10\x04\xe2\xe4_\xb7\xee\x00\x00\u07d4\xdaw2\xf0/.'.\xaf(\u07d7.\xcc\r\xde\xed\x9c\xf4\x98\x89\v \xbf\xbfig\x89\x00\x00\u07d4\xdaz\xd0%\xeb\xde%\xd2\"C\u02c3\x0e\xa1\xd3\xf6JVc#\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\u0685]SG\u007fP^\xc4\xc8\xd5\u8ed1\x80\u04c6\x81\x11\x9c\x8a\x01/\x93\x9c\x99\xed\xab\x80\x00\x00\u07d4\u0687^N/<\xab\xe4\xf3~\x0e\xae\xd7\xd1\xf6\xdc\xc6\xff\xefC\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u068b\xbe\xe1\x82\xe4U\xd2\t\x8a\xcb3\x8amE\xb4\xb1~\u0636\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0698.\x96C\xff\xec\xe7#\aZ@\xfewnZ\xce\x04\xb2\x9b\x89\b\xb8\xb6\u0259\x9b\xf2\x00\x00\u07d4\u069fUF\tF\u05ff\xb5p\xdd\xecu|\xa5w;XB\x9a\x89\x1b\x84]v\x9e\xb4H\x00\x00\u07d4\u06a1\xbdz\x91H\xfb\x86\\\xd6\x12\xdd5\xf1b\x86\x1d\x0f;\u0709\xa68\xabr\xd9,\x13\x80\x00\xe0\x94\u06a6<\xbd\xa4]\u0507\xa3\xf1\xcdJtj\x01\xbb^\x06\v\x90\x8a\x01\x04\x16\u0670*\x89$\x00\x00\u07d4\u06a7v\xa6uDi\u05f9&z\x89\xb8g%\xe7@\xda\x0f\xa0\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\u06ac\x91\xc1\xe8Y\xd5\xe5~\xd3\bKP \x0f\x97f\xe2\xc5+\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\u06ac\xda\xf4\"&\xd1\\\xb1\u03d8\xfa\x15\x04\x8c\u007fL\xee\xfei\x89\x10CV\x1a\x88)0\x00\x00\xe0\x94\u06b6\xbc\u06c3\xcf$\xa0\xae\x1c\xb2\x1b;[\x83\xc2\xf3\x82I'\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\u06bb\b\x89\xfc\x04)&\xb0^\xf5{% \x91\n\xbcKAI\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u06bc\"PB\xa6Y,\xfa\x13\xeb\xe5N\xfaA\x04\bx\xa5\xa2\x89\x0e\x11\xfa\xd5\xd8\\\xa3\x00\x00\u07d4\xda\xc0\xc1w\xf1\x1c\\>>x\xf2\xef\xd6c\xd12!H\x85t\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xda\xd16\xb8\x81x\xb4\x83zlx\x0f\xeb\xa2&\xb9\x85i\xa9L\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xda\xdb\xfa\xfd\x8bb\xb9*$\xef\xd7RV\u0743\xab\xdb\u05fb\u06c9\x01\x11du\x9f\xfb2\x00\x00\u07d4\xda\xdc\x00\xaby'`\xaa4\x15i\xfa\x9f\xf5\x98&\x84\x85JJ2\x8an\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xda\xe7 \x1e\xab\x8c\x063\x02\x93\ri9)\xd0\u007f\x95\xe7\x19b\x89\x91\xae\xc0(\xb4\x19\x81\x00\x00\u07d4\xda\xed\u052d\x10{'\x1e\x89Hl\xbf\x80\xeb\xd6!\u0757Ex\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdb\x04\xfa\xd9\u011f\x9e\x88\v\xeb\x8f\xcf\x1d:8\x90\u4cc4o\x89CZ\xe6\xcc\fX\xe5\x00\x00\u07d4\xdb\f\u01cft\u0642{\u070ads'n\xb8O\u0717b\x12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdb\x12\x93\xa5\x06\xe9\f\xad*Y\xe1\xb8V\x1f^f\x96\x1ag\x88\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdb\x19\xa3\x98\"06\x8f\x01w!\x9c\xb1\f\xb2Y\u0372%|\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdb#\xa6\xfe\xf1\xaf{X\x1ew,\xf9\x18\x82\u07b2Qo\xc0\xa7\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xdb$O\x97\xd9\xc4K\x15\x8a@\xed\x96\x06\xd9\xf7\xbd8\x9131\x89\x05\x87\x88\u02d4\xb1\xd8\x00\x00\u07d4\xdb(\x8f\x80\xff\xe22\u00baG\u0314\xc7c\xcfo\u0278+\r\x89\x04\x9b\x9c\xa9\xa6\x944\x00\x00\u07d4\xdb*\f\x9a\xb6M\xf5\x8d\u07f1\u06ec\xf8\xba\r\x89\xc8[1\xb4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xdb4t^\u0785v\xb4\x99\xdb\x01\xbe\xb7\xc1\xec\u0685\xcfJ\xbe\x89\x04V9\x18$O@\x00\x00\u07d4\xdb?%\x8a\xb2\xa3\xc2\xcf3\x9cD\x99\xf7ZK\xd1\xd3G.\x9e\x89QP\xae\x84\xa8\xcd\xf0\x00\x00\u07d4\xdbK\xc8;\x0ek\xaa\xdb\x11V\xc5\xcf\x06\xe0\xf7!\x80\x8cR\u01c9/\xb4t\t\x8fg\xc0\x00\x00\u07d4\xdbc\x12-\xe7\x03}\xa4\x97\x151\xfa\u9bc5\x86x\x86\u0192\x89\x0f\x04%\xb0d\x1f4\x00\x00\u07d4\xdbl*s\xda\xc7BJ\xb0\xd01\xb6ga\x12%f\xc0\x10C\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xdbnV\f\x9b\xc6 \u053e\xa3\xa9MG\xf7\x88\v\xf4\u007f-_\x89\x04\xda\x0f\xdf\xcf\x05v\x00\x00\u07d4\xdbo\xf7\x1b=\xb0\x92\x8f\x83\x9e\x05\xa72;\xfbW\u049c\x87\xaa\x891T\xc9r\x9d\x05x\x00\x00\u07d4\xdbsF\vY\xd8\xe8PE\xd5\xe7R\xe6%Y\x87^BP.\x8963\x03\"\xd5#\x8c\x00\x00\u07d4\xdbw\xb8\x8d\xcbq/\xd1~\xe9\x1a[\x94t\x8dr\f\x90\xa9\x94\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdb}@7\b\x1fle\xf9Gk\x06\x87\xd9\u007f\x1e\x04M\n\x1d\x89#\xc7W\a+\x8d\xd0\x00\x00\xe0\x94\u06c8.\xac\xed\xd0\xef\xf2cQ\x1b1*\u06fcY\u01b8\xb2[\x8a\x01\xedO\xdez\"6\xb0\x00\x00\u07d4\u06d3q\xb3\fL\x84NY\xe0>\x92K\xe6\x06\xa98\xd1\xd3\x10\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u06e4ym\f\xebM:\x83k\x84\xc9o\x91\n\xfc\x10?[\xa0\x89\t\b\xf4\x93\xf77A\x00\x00\u07d4\u06ed\xc6\x1e\xd5\xf0F\n\u007f\x18\xe5\x1b/\xb2aM\x92d\xa0\xe0\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\u06f6\xacH@'\x04\x16B\xbb\xfd\x8d\x80\xf9\xd0\xc1\xcf3\xc1\xeb\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u06fc\xbby\xbfG\x9aB\xadq\xdb\u02b7{Z\u07ea\x87,X\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\xdb\xc1\xce\x0eI\xb1\xa7\x05\xd2. 7\xae\xc8x\xee\ru\xc7\x03\x89\r\x8drkqw\xa8\x00\x00\u07d4\xdb\xc1\xd0\xee+\xabS\x11@\xde\x13w\"\xcd6\xbd\xb4\xe4q\x94\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xdb\u015e\u0609s\u07ad1\b\x84\":\xf4\x97c\xc0P0\xf1\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u0794\xdb\xc6ie\xe4&\xff\x1a\xc8z\xd6\xebx\xc1\xd9Rq\x15\x8f\x9f\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xdb\xcb\xcdzW\ua7724\x9b\x87\x8a\xf3K\x1a\xd6B\xa7\xf1\u0449\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xdb\xd5\x1c\xdf,;\xfa\xcd\xff\x10b!\xde.\x19\xadmB\x04\x14\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xdb\xd7\x1e\xfaK\x93\u0209\xe7e\x93\xde`\x9c;\x04\u02ef\xbe\b\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xdb\xf5\xf0a\xa0\xf4\x8e^ia\x879\xa7}.\xc1\x97h\xd2\x01\x89\b=lz\xabc`\x00\x00\u07d4\xdb\xf8\xb19g\xf5Q%'-\xe0V%6\xc4P\xbaVU\xa0\x89n\xf5x\xf0n\f\xcb\x00\x00\u07d4\xdb\xfb\x1b\xb4d\xb8\xa5\x8eP\r.\xd8\u0797,E\xf5\xf1\xc0\xfb\x89V\xbcu\xe2\xd61\x00\x00\x00\xe0\x94\xdc\x06~\xd3\xe1-q\x1e\xd4u\xf5\x15n\xf7\xe7\x1a\x80\xd94\xb9\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\xdc\b\u007f\x93\x90\xfb\x9e\x97j\xc2:\xb6\x89TJ\tB\xec !\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xdc\x1e\xb9\xb6\xe6CQ\xf5d$P\x96E\xf8>y\xee\xe7l\xf4\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xdc\x1f\x19ya_\b!@\xb8\xbbx\xc6{'\xa1\x94'\x13\xb1\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\xdc#\xb2`\xfc\xc2n}\x10\xf4\xbd\x04J\xf7\x94W\x94`\xd9\u0689\x1b\x1bk\u05efd\xc7\x00\x00\u07d4\xdc)\x11\x97E\xd23s \xdaQ\xe1\x91\x00\xc9H\u0640\xb9\x15\x89\b\xacr0H\x9e\x80\x00\x00\u07d4\xdc-\x15\xa6\x9fk\xb3;$j\xef@E\aQ\xc2\xf6uj\u0489l4\x10\x80\xbd\x1f\xb0\x00\x00\u07d4\xdc=\xaeY\xed\x0f\xe1\x8bXQ\x1eo\xe2\xfbi\xb2\x19h\x94#\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xdc?\x0evr\xf7\x1f\xe7R[\xa3\v\x97U\x18: \xb9\x16j\x8a\x02\b\x9c\xf5{[>\x96\x80\x00\xe0\x94\xdcCE\u0581.\x87\n\xe9\fV\x8cg\xd2\xc5g\u03f4\xf0<\x8a\x01k5-\xa5\xe0\xed0\x00\x00\u07d4\xdcD'[\x17\x15\xba\xea\x1b\x03EsZ)\xacB\xc9\xf5\x1bO\x89?\x19\xbe\xb8\xdd\x1a\xb0\x00\x00\u07d4\xdcF\xc13%\u034e\xdf\x020\xd0h\x89d\x86\xf0\a\xbfN\xf1\x89Hz\x9a0E9D\x00\x00\u07d4\xdcQ\xb2\u071d$z\x1d\x0e[\xc3l\xa3\x15oz\xf2\x1f\xf9\xf6\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xdcS\x05\xb4\x02\n\x06\xb4\x9de||\xa3L5\xc9\x1c_,V\x8a\x01}\xf6\xc1\r\xbe\xba\x97\x00\x00\u07d4\xdcW4[8\xe0\xf0g\u0263\x1d\x9d\xea\xc5'Z\x10\x94\x93!\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xdcWG}\xaf\xa4/p\\\u007f\xe4\x0e\xae\x9c\x81un\x02%\xf1\x89\x1b\x1b\x81(\xa7An\x00\x00\u07d4\xdc_Z\xd6c\xa6\xf2c2}d\xca\xc9\xcb\x13=,\x96\x05\x97\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdcp:_7\x94\xc8Ml\xb3TI\x18\xca\xe1J5\u00fdO\x89dI\xe8NG\xa8\xa8\x00\x00\xe0\x94\xdcs\x8f\xb2\x17\u03ad/iYL\b\x17\r\xe1\xaf\x10\xc4\x19\xe3\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xdcv\xe8[\xa5\v\x9b1\xec\x1e& \xbc\xe6\xe7\xc8\x05\x8c\x0e\xaf\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\u0703\xb6\xfd\rQ!1 G\a\xea\xf7.\xa0\xc8\u027e\xf9v\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u070c)\x12\xf0\x84\xa6\u0444\xaasc\x85\x13\u033c2n\x01\x02\x89F3\xbc6\xcb\xc2\xdc\x00\x00\u07d4\u0711\x1c\xf7\xdc]\u04016Vg\x05(\xe93\x8eg\x03G\x86\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0730;\xfal\x111#NV\xb7\xea|Or\x14\x87Tkz\x89Hz\x9a0E9D\x00\x00\xe0\x94\u0736M\xf47X\xc7\u03d7O\xa6`HO\xbbq\x8f\x8cg\xc1\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xdc\xc5-\x8f\x8d\x9f\xc7B\xa8\xb8'g\xf0US\x87\xc5c\xef\xff\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xdc\xcb7\x0e\u058a\xa9\"(0C\xef|\xad\x1b\x9d@?\xc3J\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xdc\u0324 E\xec>\x16P\x8b`?\xd96\xe7\xfd}\xe5\xf3j\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xdc\xd1\fU\xbb\x85OuD4\xf1!\x9c,\x9a\x98\xac\xe7\x9f\x03\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\xdc\u057c\xa2\x00S\x95\xb6u\xfd\xe5\x03VY\xb2k\xfe\xfcI\xee\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xdc\u06fdN&\x04\xe4\x0e\x17\x10\xccg0(\x9d\xcc\xfa\u04c9-\x89\xf9]\xd2\xec'\xcc\xe0\x00\x00\u07d4\xdc\xe3\f1\xf3\xcafr\x1e\xcb!<\x80\x9a\xabV\x1d\x9bR\xe4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdc\xf39eS\x13\x80\x161h\xfc\x11\xf6~\x89\xc6\xf1\xbc\x17\x8a\x89\x12'v\x854\x06\xb0\x80\x00\u07d4\xdc\xf6\xb6W&n\x91\xa4\xda\xe6\x03=\xda\xc1S2\u074d+4\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xdc\xf9q\x9b\xe8|oFum\xb4\x89\x1d\xb9\xb6\x11\xd2F\x9cP\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xdc\xff\xf3\xe8\xd2<*4\xb5k\u0473\xbdE\u01d3tC\"9\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xdd\x04\xee\xe7N\v\xf3\f?\x8dl,\u007fR\xe0Q\x92\x10\u07d3\x89\x04V9\x18$O@\x00\x00\xe0\x94\xdd&\xb4)\xfdC\xd8N\xc1y\x82S$\xba\u057f\xb9\x16\xb3`\x8a\x01\x16\xbf\x95\xbc\x842\x98\x00\x00\u07d4\xdd*#:\xde\xdef\xfe\x11&\xd6\xc1h#\xb6*\x02\x1f\xed\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xdd+\u07e9\x17\xc1\xf3\x10\xe6\xfa5\xaa\x8a\xf1i9\xc23\xcd}\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xdd5\xcf\xdb\u02d93\x95Sz\xec\xc9\xf5\x90\x85\xa8\xd5\u0776\xf5\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xddG\x18\x9a>d9qg\xf0b\x0eHEe\xb7b\xbf\xbb\xf4\x89dI\xe8NG\xa8\xa8\x00\x00\u07d4\xddM\xd6\xd3`3\xb0co\u030d\t8`\x9fM\xd6OJ\x86\x89\x03@\xaa\xd2\x1b;p\x00\x00\u07d4\xddO_\xa2\x11\x1d\xb6\x8fk\xde5\x89\xb60)9[i\xa9-\x89\b\x96=\xd8\xc2\xc5\xe0\x00\x00\xe0\x94\xddc\x04/%\xed2\x88J\xd2n:\xd9Y\xeb\x94\xea6\xbfg\x8a\x04\x84\xd7\xfd\xe7\u0553\xf0\x00\x00\u07d4\xdde\xf6\xe1qc\xb5\xd2\x03d\x1fQ\xcc{$\xb0\x0f\x02\xc8\xfb\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xddl\x06!\x93\xea\xc2=/\xdb\xf9\x97\xd5\x06:4k\xb3\xb4p\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xdd{\u0366Y$\xaa\xa4\x9b\x80\x98J\xe1su\x02X\xb9(G\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xdd\u007f\xf4A\xbao\xfe6q\xf3\xc0\u06bb\xff\x18#\xa5\x043p\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u0742T\x12\x1an\x94/\xc9\b(\xf2C\x1fQ\x1d\xad\u007f2\u6263\x9b)\xe1\xf3`\xe8\x00\x00\xe0\x94\u074a\xf9\xe7vR#\xf4DoD\xd3\xd5\t\x81\x9a==\xb4\x11\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\u0755\xdb\xe3\x0f\x1f\x18w\xc5\xddv\x84\xae\xef0*\xb6\x88Q\x92\x8a\x01\xc5\xd8\xd6\xeb>2P\x00\x00\xe0\x94\u0756|L_\x8a\xe4~&o\xb4\x16\xaa\u0456N\xe3\xe7\xe8\u00ca\x01\xa4 \xdb\x02\xbd}X\x00\x00\u07d4\u075bHZ;\x1c\xd3:j\x9cb\xf1\xe5\xbe\xe9'\x01\x85m%\x89\f3\x83\xed\x03\x1b~\x80\x00\xe0\x94\u0763q\xe6\x00\xd3\x06\x88\xd4q\x0e\b\x8e\x02\xfd\xf2\xb9RM_\x8a\x01w\"J\xa8D\xc7 \x00\x00\u07d4\u0764\xed*X\xa8\xdd \xa72u4{X\rq\xb9[\xf9\x9a\x89\x15\xa1<\xc2\x01\xe4\xdc\x00\x00\xe0\x94\u0764\xff}\xe4\x91\u0187\xdfEt\xdd\x1b\x17\xff\x8f$k\xa3\u044a\x04&\x84\xa4\x1a\xbf\xd8@\x00\x00\u07d4\u076bkQ\xa9\x03\v@\xfb\x95\xcf\vt\x8a\x05\x9c$\x17\xbe\u01c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94\u076bu\xfb/\xf9\xfe\u02c8\xf8\x94vh\x8e+\x00\xe3g\xeb\xf9\x8a\x04\x1b\xad\x15^e\x12 \x00\x00\xe0\x94\u076b\xf1<<\x8e\xa4\xe3\xd7=x\xecqz\xfa\xfaC\x0eTy\x8a\b\xcf#\xf9\t\xc0\xfa\x00\x00\x00\u07d4\u076c1*\x96UBj\x9c\f\x9e\xfa?\xd8%Y\xefE\x05\xbf\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\u076ck\xf4\xbb\xdd}Y}\x9chm\x06\x95Y;\xed\xcc\xc7\xfa\x89.\xe4IU\b\x98\xe4\x00\x00\xe0\x94\u077d+\x93,v;\xa5\xb1\xb7\xae;6.\xac>\x8d@\x12\x1a\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\u077d\xdd\x1b\xbd8\xff\xad\xe00]0\xf0 (\xd9.\x9f:\xa8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\u077e\xe6\xf0\x94\xea\xe64 \xb0\x03\xfbGW\x14*\xeal\xd0\xfd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdd\u059c[\x9b\xf5\xebZ9\xce\xe7\xc34\x1a\x12\r\x97?\xdb4\x89k\xc1K\x8f\x8e\x1b5\x00\x00\xe0\x94\xdd\xdd{\x9en\xab@\x9b\x92&:\xc2r\u0680\x1bfO\x8aW\x8ai\xe1\r\xe7fv\u0400\x00\x00\u07d4\xdd\xe6p\xd0\x169fuv\xa2-\xd0]2F\xd6\x1f\x06\xe0\x83\x89\x01s\x17\x90SM\xf2\x00\x00\xe0\x94\xdd\xe7zG@\xba\b\xe7\xf7?\xbe:\x16t\x91)1t.\xeb\x8a\x044\xfeMC\x82\xf1\u0500\x00\u07d4\xdd\xe8\xf0\xc3\x1bt\x15Q\x1d\xce\xd1\xcd}F2>K\xd1\"2\x89WG=\x05\u06ba\xe8\x00\x00\u07d4\xdd\xe9i\xae\xf3N\xa8z\u0099\xb7Y~)+J\x01U\u030a\x89\x102\xf2YJ\x01s\x80\x00\u07d4\xdd\xf0\xcc\xe1\xfe\x99m\x91v5\xf0\a\x12\xf4\x05 \x91\xdf\xf9\xea\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xdd\xf3\xadv58\x10\xbej\x89\xd71\xb7\x87\xf6\xf1q\x88a+\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xdd\xf5\x81\n\x0e\xb2\xfb.22;\xb2\u0255\t\xab2\x0f$\xac\x8a\x03\xca\\f\u067cD0\x00\x00\xe0\x94\xdd\xf9\\\x1e\x99\xce/\x9fV\x98\x05|\x19\xd5\xc9@'\xeeJn\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u0794\xdd\xfa\xfd\xbc|\x90\xf12\x0eT\xb9\x8f7F\x17\xfb\xd0\x1d\x10\x9f\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\xdd\xfc\xca\x13\xf94\xf0\u03fe#\x1d\xa109\xd7\x04u\xe6\xa1\u040968\"\x16`\xa5\xaa\x80\x00\u07d4\xde\x02~\xfb\xb3\x85\x03\"n\xd8q\t\x9c\xb3\v\xdb\x02\xaf\x135\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xde\x06\xd5\xeawzN\xb1G^`]\xbc\xbfCDN\x807\xea\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\xde\a\xfb[zFN;\xa7\xfb\xe0\x9e\x9a\xcb'\x1a\xf53\x8cX\x89\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\xde\x11!\x82\x9c\x9a\b(@\x87\xa4?\xbd/\xc1\x14*23\xb4\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xde\x17kR\x84\xbc\xee:\x83\x8b\xa2Og\xfc|\xbfg\u05ce\xf6\x89\x02\t\xce\b\xc9b\xb0\x00\x00\u07d4\xde!\"\x93\xf8\xf1\xd21\xfa\x10\xe6\tG\rQ,\xb8\xff\xc5\x12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xde0\xe4\x9eZ\xb3\x13!M/\x01\u072b\u0389@\xb8\x1b\x1cv\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xde3\xd7\b\xa3\xb8\x9e\x90\x9e\xafe;0\xfd\u00e5\xd5\u0334\xb3\x89\t\x9c\x88\"\x9f\xd4\xc2\x00\x00\u07d4\xde7B\x99\xc1\xd0}ySs\x85\x19\x0fD.\xf9\xca$\x06\x1f\x89\a?u\u0460\x85\xba\x00\x00\u07d4\xdeB\xfc\xd2L\xe4#\x93\x830CgY_\x06\x8f\fa\a@\x89\x02r*p\xf1\xa9\xa0\x00\x00\u07d4\xdeP\x86\x8e\xb7\xe3\xc7\x197\xecs\xfa\x89\u074b\x9e\xe1\rE\xaa\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xdeU\xde\x04X\xf8P\xb3~Mx\xa6A\xdd.\xb2\u074f8\u0389\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xde[\x00_\xe8\u06ae\x8d\x1f\x05\xde>\xda\x04 f\xc6\xc4i\x1c\x89;\xa1\x91\v\xf3A\xb0\x00\x00\u07d4\xdea-\a$\xe8N\xa4\xa7\xfe\xaa=!B\xbd^\xe8-2\x01\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xdem61\x06\xccb8\xd2\xf0\x92\xf0\xf07!6\xd1\xcdP\u018a\x01!\xeah\xc1\x14\xe5\x10\x00\x00\u07d4\xde}\xee\"\x0f\x04W\xa7\x18}V\xc1\xc4\x1f.\xb0\n\xc5`!\x89\"%\xf3\x9c\x85\x05*\x00\x00\u07d4\u0782\u030dJ\x1b\xb1\xd9CC\x92\x96[>\x80\xba\xd3\xc0=O\x89P\x18nu\u0797\xa6\x00\x00\u07d4\u0797\xf43\a\x00\xb4\x8cImC|\x91\xca\x1d\xe9\u0130\x1b\xa4\x89\x9d\xcc\x05\x15\xb5n\f\x00\x00\u07d4\u079e\xffLy\x88\x11\xd9h\xdc\xcbF\r\x9b\x06\x9c\xf3\x02x\xe0\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\u07b1\xbc4\xd8mJM\xde%\x80\u063e\xaf\aN\xb0\xe1\xa2D\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\u07b2I]j\xca{*j-\x13\x8bn\x1aB\xe2\xdc1\x1f\u0749lk\x93[\x8b\xbd@\x00\x00\u07d4\u07b9rTGL\r/Zyp\xdc\xdb/R\xfb\x10\x98\xb8\x96\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u07b9\xa4\x9aC\x870 \xf0u\x91\x85\xe2\v\xbbL\U000c1ecf\x89\vx\xed\xb0\xbf.^\x00\x00\u07d4\u07bb\u0743\x1e\x0f \xaen7\x82R\xde\xcd\xf9/|\xf0\xc6X\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xde\xc3\xee\xc2d\nu,Fn+~~\u616f\xe9\xacA\xf4\x89G\u0257SYk(\x80\x00\u07d4\xde\xc8#s\xad\xe8\xeb\xcf*\xcbo\x8b\xc2AM\u05eb\xb7\rw\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xde\u0221\xa8\x98\xf1\xb8\x95\xd80\x1f\xe6J\xb3\xad]\xe9A\xf6\x89\x89*\xb4\xf6~\x8as\x0f\x80\x00\u07d4\xde\u025e\x97/\xcaqwP\x8c\x8e\x1aG\xac\"\xd7h\xac\xab|\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xde\xd8w7\x84\a\xb9Nx\x1cN\xf4\xaf|\xfc[\xc2 \xb5\x16\x89\x141y\xd8i\x11\x02\x00\x00\u07d4\xde\xe9B\xd5\xca\xf5\xfa\xc1\x14!\xd8k\x01\vE\x8e\\9)\x90\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xde\xee&\x89\xfa\x90\x06\xb5\x9c\xf2\x85#}\xe5;:\u007f\xd0\x148\x89\x18ey\xf2\x9e %\x00\x00\u07d4\xde\xfd\xdf\u055b\x8d,\x15N\xec\xf5\xc7\xc1g\xbf\v\xa2\x90]>\x89\x05\x12\xcb^&GB\x00\x00\u07d4\xde\xfe\x91A\xf4pE\x99\x15\x9d{\"=\xe4+\xff\xd8\x04\x96\xb3\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xdf\t\x8f^N=\xff\xa5\x1a\xf27\xbd\xa8e,Os\ud726\x89\x1b6\xa6DJ>\x18\x00\x00\xe0\x94\xdf\r\ba{\xd2R\xa9\x11\u07cb\xd4\x1a9\xb8=\u07c0\x96s\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xdf\x0f\xf1\xf3\xd2z\x8e\xc9\xfb\x8fk\f\xb2T\xa6;\xba\x82$\xa5\x89\xec\xc5 )E\xd0\x02\x00\x00\u07d4\xdf\x1f\xa2\xe2\x0e1\x98^\xbe,\x0f\f\x93\xb5L\x0f\xb6z&K\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xdf!\x1c\xd2\x12\x88\xd6\xc5o\xaef\xc3\xffTb]\u0531T'\x89\x87\x86\xcdvN\x1f,\x00\x00\u07d4\xdf#k\xf6\xab\xf4\xf3)7\x95\xbf\f(q\x8f\x93\u3c73k\x89Hz\x9a0E9D\x00\x00\u07d4\xdf1\x02_VI\xd2\xc6\xee\xa4\x1e\u04fd\xd3G\x1ay\x0fu\x9a\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xdf7\xc2.`:\xed\xb6\nbrS\xc4}\x8b\xa8f\xf6\xd9r\x8a\x05\x15\n\xe8J\x8c\xdf\x00\x00\x00\u07d4\xdf;r\u017dq\u0501N\x88\xa6#!\xa9=@\x11\xe3W\x8b\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xdf?W\xb8\xeed4\xd0G\"=\xeft\xb2\x0fc\xf9\xe4\xf9U\x89\r\x94b\xc6\xcbKZ\x00\x00\u07d4\xdfD\xc4\u007f\xc3\x03\xacv\xe7O\x97\x19L\xcag\xb5\xbb<\x02?\x89 \t\xc5\u023fo\xdc\x00\x00\u07d4\xdfG\xa6\x1brSQ\x93\xc5a\xcc\xccu\xc3\xf3\xce\b\x04\xa2\x0e\x89\x15\x93\\\vN=x\x00\x00\u07d4\xdfG\xa8\xef\x95\xf2\xf4\x9f\x8eoX\x18AT\x14]\x11\xf7'\x97\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\xdfS\x003F\xd6\\^zdk\xc04\xf2\xb7\xd3/\xcb\xe5j\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xdfW5:\xaf\xf2\xaa\xdb\n\x04\xf9\x01N\x8d\xa7\x88N\x86X\x9c\x89\bH\x86\xa6nO\xb0\x00\x00\u07d4\xdf`\xf1\x8c\x81*\x11\xedN'v\xe7\xa8\x0e\xcf^S\x05\xb3\u05890\xca\x02O\x98{\x90\x00\x00\u07d4\xdfd\x85\xc4)z\xc1R\xb2\x89\xb1\x9d\xde2\xc7~\xc4\x17\xf4}\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xdff\n\x91\u06b9\xf70\xf6\x19\rP\xc89\x05aP\aV\u0289lk\x93[\x8b\xbd@\x00\x00\u07d4\xdfn\xd6\x00jj\xbe\x88n\xd3=\x95\xa4\xde(\xfc\x12\x189'\x891T\xc9r\x9d\x05x\x00\x00\u07d4\u07c5\x10y>\xee\x81\x1c-\xab\x1c\x93\xc6\xf4G?0\xfb\xef[\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u07cdH\xb1\xeb\a\xb3\xc2\x17y\x0el-\xf0M\xc3\x19\xe7\xe8H\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\u07e6\xb8\xb8\xad1\x84\xe3W\xda()Q\u05d1a\u03f0\x89\xbc\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\u07ef1\xe6\"\xc0=\x9e\x18\xa0\u0778\xbe`\xfb\xe3\xe6a\xbe\n\x8a\x02\x1e\x17\x1a>\xc9\xf7,\x00\x00\u07d4\u07f1bn\xf4\x8a\x1d}uR\xa5\xe0)\x8f\x1f\xc2:;H-\x89\\\xe8\x95\u0754\x9e\xfa\x00\x00\xe0\x94\u07f4\u052d\xe5/\u0301\x8a\xccz,k\xb2\xb0\x02$e\x8fx\x8a\x01\xa4 \xdb\x02\xbd}X\x00\x00\u07d4\u07fdB2\xc1|@z\x98\r\xb8\u007f\xfb\u036060\xe5\xc4Y\x89\x1d\xfc\u007f\x92I#S\x00\x00\u07d4\xdf\xcb\xdf\tEN\x1a^J@\xd3\xee\xf7\xc5\xcf\x1c\xd3\u0794\x86\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xdf\xdb\xce\xc1\x01K\x96\xda!X\xcaQ>\x9c\x8d;\x9a\xf1\xc3\u0409lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xdf\xde\xd2WK'\xd1a:}\x98\xb7\x15\x15\x9b\r\x00\xba\xab(\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xdf\xdfC9P\x8b\x0fnZ\xb1\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe0\x06\x04b\xc4\u007f\xf9g\x9b\xae\xf0qY\xca\xe0\x8c)\xf2t\xa9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\r\x15;\x106\x91C\xf9\u007fT\xb8\xd4\xca\"\x9e\xb3\xe8\xf3$\x89\b=lz\xabc`\x00\x00\u07d4\xe0\x12\xdbE8'\xa5\x8e\x16\xc16V\b\xd3n\xd6Xr\x05\a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\x15G\xbaB\xfc\xaf\xaf\x93\x93\x8b\xec\xf7i\x9ft)\n\xf7O\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\x16\xdc\x13\x8e%\x81[\x90\xbe?\xe9\xee\xe8\xff\xb2\xe1\x05bO\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe0\x18Y\xf2B\xf1\xa0\xec`/\xa8\xa3\xb0\xb5v@\xec\x89\a^\x89\x1e\x16,\x17{\xe5\xcc\x00\x00\xe0\x94\xe0 \xe8cb\xb4\x87u(6\xa6\xde\v\xc0,\xd8\u061a\x8bj\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xe0#\xf0\x9b(\x87a,|\x9c\xf1\x98\x8e::`+3\x94\u0249lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0'\"\x13\xe8\xd2\xfd>\x96\xbdb\x17\xb2KK\xa0\x1bapy\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe0+t\xa4v(\xbe1[\x1fv\xb3\x15\x05J\xd4J\xe9qo\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xe02 \u0197\xbc\u048f&\xef\vt@J\x8b\xeb\x06\xb2\xba{\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xe05/\u07c1\x9b\xa2e\xf1L\x06\xa61\\J\xc1\xfe\x13\x1b.\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe08\x8a\xed\xdd?\xe2\xadV\xf8WH\xe8\x0eq\n4\xb7\xc9.\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe0<\x00\xd0\x03\x88\xec\xbfO&=\n\xc7x\xbbA\xa5z@\u064966\xc9yd6t\x00\x00\u07d4\xe0I \xdcn\xcc\x1dn\xcc\bO\x88\xaa\n\xf5\u06d7\xbf\x89:\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\xe0Ir\xa8<\xa4\x11+\xc8q\xc7-J\xe1al/\a(\u06c9\x0e\x81\xc7\u007f)\xa3/\x00\x00\u07d4\xe0O\xf5\xe5\xa7\u2bd9]\x88W\xce\x02\x90\xb5:+\x0e\xda]\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xe0P)\xac\xeb\axg[\xef\x17A\xab,\u0493\x1e\xf7\xc8K\x8a\x01\x0f\r\xba\xe6\x10\tR\x80\x00\u07d4\xe0V\xbf?\xf4\x1c&%o\xefQqf\x12\xb9\u04da\u0799\x9c\x89\x05k\xe7W\xa1.\n\x80\x00\u07d4\xe0a\xa4\xf2\xfcw\xb2\x96\u045a\xda#\x8eI\xa5\u02ce\xcb\xfap\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xe0f>\x8c\xd6g\x92\xa6A\xf5nP\x03f\x01G\x88\x0f\x01\x8e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0f\x8f\xa8,\x14\xd6\xe8\xd9:S\x11>\xf2\x86/\xa8\x15\x81\xbc\x89//9\xfclT\x00\x00\x00\u07d4\xe0i\xc0\x173R\xb1\v\xf6\x83G\x19\xdb[\xed\x01\xad\xf9{\xbc\x89\x01\x064\xf8\xe52;\x00\x00\u07d4\xe0l)\xa8\x15\x17\xe0\u0507\xb6\u007f\xb0\xb6\xaa\xbcOW6\x83\x88\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\xe0l\xb6)G\x04\xee\xa7C|/\xc3\xd3\as\xb7\xbf8\x88\x9a\x89\x01\x16\xdc:\x89\x94\xb3\x00\x00\u07d4\xe0q7\xae\r\x11m\x0353\xc4\uad16\xf8\xa9\xfb\tV\x9c\x89K\xe4\xe7&{j\xe0\x00\x00\xe0\x94\xe0v\xdb0\xabHoy\x19N\xbb\xc4]\x8f\xab\x9a\x92B\xf6T\x8a\x01\x06`~4\x94\xba\xa0\x00\x00\u07d4\xe0~\xbb\xc7\xf4\xdaAnB\xc8\xd4\xf8B\xab\xa1b3\xc1%\x80\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\x81\xca\x1fH\x82\xdb`C\u0569\x19\a\x03\xfd\xe0\xab;\xf5m\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe0\x83\xd3Hc\xe0\xe1\u007f\x92ky(\xed\xff1~\x99\x8e\x9cK\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe0\x8b\x9a\xbak\xd9\u048b\xc2\x05gy\xd2\xfb\xf0\xf2\x85Z=\x9d\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\x8b\u009c+H\xb1i\xff+\xdc\x16qLXnl\xb8\\\u03c9\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe0\x8c`11\x06\xe3\xf93O\xe6\xf7\xe7bM!\x110\xc0w\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xe0\x9ch\xe6\x19\x98\xd9\xc8\x1b\x14\xe4\xee\x80+\xa7\xad\xf6\xd7L\u06c9\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xe0\x9f\xeauZ\xee\x1aD\xc0\xa8\x9f\x03\xb5\u07b7b\xba3\x00o\x89;\xa2\x89\xbc\x94O\xf7\x00\x00\xe0\x94\xe0\xa2T\xac\t\xb9r[\xeb\xc8\xe4`C\x1d\xd0s.\xbc\xab\xbf\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xe0\xaai6UU\xb7?(#3\xd1\xe3\f\x1b\xbd\a(T\xe8\x8a\x01{x\x83\xc0i\x16`\x00\x00\u07d4\xe0\xba\u064e\ue598\xdb\xf6\xd7`\x85\xb7\x92=\xe5uN\x90m\x89\t\r\x97/22<\x00\x00\u07d4\xe0\u012b\x90r\xb4\xe6\xe3eJI\xf8\xa8\xdb\x02jK3\x86\xa9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\u0380\xa4a\xb6H\xa5\x01\xfd\v\x82F\x90\u0206\x8b\x0eM\xe8\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe0\xcfi\x8a\x053'\xeb\xd1k}w\x00\t/\xe2\xe8T$F\x89\x05*4\u02f6\x1fW\x80\x00\xe0\x94\xe0\xd21\xe1D\xec\x91\a8l|\x9b\x02\xf1p,\xea\xa4\xf7\x00\x8a\x01\x0f\r\xba\xe6\x10\tR\x80\x00\u07d4\xe0\xd7kqf\xb1\xf3\xa1+@\x91\xee+)\u078c\xaa}\a\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xe0\xe0\xb2\xe2\x9d\xdes\xafu\x98~\xe4Dl\x82\x9a\x18\x9c\x95\xbc\x89\b\x13\xcaV\x90m4\x00\x00\xe0\x94\xe0\xe9xu=\x98/\u007f\x9d\x1d#\x8a\x18\xbdH\x89\xae\xfeE\x1b\x8a\x02\r\u058a\xaf2\x89\x10\x00\x00\u07d4\xe0\xf3r4|\x96\xb5_}C\x06\x03K\xeb\x83&o\xd9\tf\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe0\xf9\x03\xc1\xe4\x8a\xc4!\xabHR\x8f=J&H\b\x0f\xe0C\x897\b\xba\xed=h\x90\x00\x00\u07d4\xe0\xff\v\xd9\x15D9\u0125\xb7#>)\x1d}\x86\x8a\xf5?3\x89\x15y!jQ\xbb\xfb\x00\x00\xe0\x94\xe1\n\xc1\x9cTo\xc2T|a\xc19\xf5\xd1\xf4Zff\u0570\x8a\x01\x02\xdao\xd0\xf7:<\x00\x00\xe0\x94\xe1\fT\x00\x88\x11?\xa6\xec\x00\xb4\xb2\u0202O\x87\x96\xe9n\u010a2\x0fE\t\xab\x1e\xc7\xc0\x00\x00\xe0\x94\xe1\x17:$})\xd8#\x8d\xf0\x92/M\xf2Z\x05\xf2\xafw\u00ca\bx\xc9]V\x0f0G\x80\x00\xe0\x94\xe1 >\xb3\xa7#\xe9\x9c\" \x11|\xa6\xaf\xebf\xfaBOa\x8a\x02\x00\uf49e2V\xfe\x00\x00\xe0\x94\xe11\xf8~\xfc^\xf0~C\xf0\xf2\xf4\xa7G\xb5Q\xd7P\xd9\xe6\x8a\x04<%\xe0\xdc\xc1\xbd\x1c\x00\x00\u07d4\xe13N\x99\x83y\xdf\xe9\x83\x17pby\x1b\x90\xf8\x0e\xe2-\x8d\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe15@\xec\xee\x11\xb2\x12\xe8\xb7u\u070eq\xf3t\xaa\xe9\xb3\xf8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe1;=+\xbf\u073c\x87r\xa23\x15rL\x14%\x16|V\x88\x897\xf3y\x14\x1e\xd0K\x80\x00\u07d4\xe1D=\xbd\x95\xccA#\u007fa:HEi\x88\xa0Oh2\x82\x89\xd8\xd8X?\xa2\xd5/\x00\x00\u07d4\xe1F\x17\xf6\x02%\x01\xe9~{>-\x886\xaaa\xf0\xff-\xba\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe1I\xb5rl\xafm^\xb5\xbf*\xccA\xd4\xe2\xdc2\x8d\u1089i*\xe8\x89p\x81\xd0\x00\x00\xe0\x94\xe1T\xda\xea\xdbTX8\xcb\u01aa\fUu\x19\x02\xf5(h*\x8a\x01\n\xfc\x1a\xde;N\xd4\x00\x00\u07d4\xe1l\xe3Ya\xcdt\xbdY\r\x04\u012dJ\x19\x89\xe0V\x91\u0189\a\xea(2uw\b\x00\x00\u07d4\xe1r\xdf\xc8\xf8\f\xd1\xf8\u03459\xdc&\b \x14\xf5\xa8\xe3\u8262\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xe1w\xe0\xc2\x01\xd35\xba9V\x92\x9cW\x15\x88\xb5\x1cR#\xae\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe1x\x12\xf6l^e\x94\x1e\x18lF\x92+n{/\x0e\xebF\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xe1\x80\u079e\x86\xf5{\xaf\xac\u05d0O\x98&\xb6\xb4\xb2c7\xa3\x89-\x04\x1dpZ,`\x00\x00\xe0\x94\xe1\x92H\x9b\x85\xa9\x82\xc1\x882F\xd9\x15\xb2)\xcb\x13 \u007f8\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xe1\x95\xbb\xc6,{tD\x04\x0e\xb9\x96#\x96Ovg\xb3v\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe2\x06\xfbs$\xe9\u07b7\x9e\x19\x904\x96\u0596\x1b\x9b\xe5f\x03\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xe2\aW\x8e\x1fM\u06cf\xf6\u0546{9X-q\xb9\x81*\u0149\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\xe2\b\x81*h@\x98\xf3\xdaN\xfej\xba%bV\xad\xfe?\xe6\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe2\tT\xd0\xf4\x10\x8c\x82\xd4\u0732\x14\x8d&\xbb\xd9$\xf6\xdd$\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xe2\v\xb9\xf3\x96d\x19\xe1K\xbb\xaa\xaag\x89\xe9$\x96\u03e4y\x89\xbb\xd8%\x03\aRv\x00\x00\u07d4\xe2\r\x1b\xcbq(m\xc7\x12\x8a\x9f\xc7\xc6\xed\u007fs8\x92\xee\xf5\x896d\xf8\xe7\xc2J\xf4\x00\x00\u0794\xe2\x19\x12\x15\x98?3\xfd3\xe2,\u0522I\x00T\xdaS\xfd\u0708\xdbD\xe0I\xbb,\x00\x00\u07d4\xe2\x19\x8c\x8c\xa1\xb3\x99\xf7R\x15a\xfdS\x84\xa7\x13/\xbaHk\x897\b\xba\xed=h\x90\x00\x00\xe0\x94\xe2\x1cw\x8e\xf2\xa0\xd7\xf7Q\xea\x8c\aM\x1f\x81\"C\x86>N\x8a\x01\x1f\xc7\x0e,\x8c\x8a\xe1\x80\x00\xe0\x94\xe2)\xe7F\xa8?,\xe2S\xb0\xb0>\xb1G$\x11\xb5~W\x00\x8a\x016\x9f\xb9a(\xacH\x00\x00\u07d4\xe2+ \xc7x\x94F;\xafwL\xc2V\u057d\u06ff}\xdd\t\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe20\xfe\x1b\xff\x03\x18m\x02\x19\xf1]LH\x1b}Y\xbe(j\x89\x01\xfdt\x1e\x80\x88\x97\x00\x00\u07d4\xe27\xba\xa4\xdb\u0252n2\xa3\xd8]\x12d@-T\xdb\x01/\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe2A\t\xbe/Q=\x87I\x8e\x92j(d\x99uO\x9e\u051e\x890\x0e\xa8\xad\x1f'\xca\x00\x00\u07d4\xe2Fh<\u025d\xb7\u0125+\u02ec\xaa\xb0\xb3/k\xfc\x93\u05c9lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe2Z\x16{\x03\x1e\x84am\x0f\x01?1\xbd\xa9]\xcccP\xb9\x8a\x02\x8c*\xaa\u0243\xd0]\u0187st\xa8\xf4F\xee\xe9\x89\n\xb6@9\x12\x010\x00\x00\u07d4\xe2\x8b\x06\"Y\xe9n\xeb<\x8dA\x04\x94?\x9e\xb3%\x89<\xf5\x89Hz\x9a0E9D\x00\x00\xe0\x94\u237c\x8e\xfd^Ajv.\xc0\xe0\x18\x86K\xb9\xaa\x83({\x8a\x051\xf2\x00\xab>\x03\n\x80\x00\u07d4\xe2\x90K\x1a\xef\xa0V9\x8bb4\xcb5\x81\x12\x88\xd76\xdbg\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\u274a\xe4R\xdc\xf3\xb6\xacd^c\x04\t8UQ\xfa\xae\n\x89\x04Z\r\xa4\xad\xf5B\x00\x00\u07d4\xe2\xbb\xf8FA\xe3T\x1fl3\xe6\xedh:cZp\xbd\xe2\xec\x89\x1bA<\xfc\xbfY\xb7\x80\x00\u07d4\xe2\xcf6\n\xa22\x9e\xb7\x9d+\xf7\xca\x04\xa2z\x17\xc52\xe4\u0609\x05\x87\x88\u02d4\xb1\xd8\x00\x00\u07d4\xe2\xdf#\xf6\xea\x04\xbe\xcfJ\xb7\x01t\x8d\xc0\x961\x84U\\\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xe2\xe1\\`\xdd8\x1e:K\xe2Pq\xab$\x9aL\\Rd\u0689\u007fk\u011b\x81\xb57\x00\x00\u07d4\xe2\xe2nN\x1d\xcf0\xd0H\xccn\u03ddQ\xec\x12\x05\xa4\xe9&\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xe2\xeei\x1f#~\xe6R\x9beW\xf2\xfc\xdd=\xcf\fY\xecc\x8a\x01'r\x9c\x14h| \x00\x00\u07d4\xe2\xef\xa5\xfc\xa7\x958\xce`h\xbf1\xd2\xc5\x16\xd4\xd5<\b\xe5\x89\a\x1c\xc4\b\xdfc@\x00\x00\xe0\x94\xe2\xef\u0429\xbc@~\xce\x03\xd6~\x8e\xc8\xe9\u0483\xf4\x8d*I\x8a\x02\x99\xb3;\xf9\u0144\xe0\x00\x00\u07d4\xe2\xf4\r5\x8f^?\xe7F>\xc7\x04\x80\xbd.\u04d8\xa7\x06;\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe2\xf98=X\x10\xea{C\x18+\x87\x04\xb6+'\xf5\x92]9\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe2\xff\x9e\xe4\xb6\xec\xc1AA\xcct\xcaR\xa9\xe7\xa2\xee\x14\xd9\b\x89K\xe4\xe7&{j\xe0\x00\x00\xe0\x94\xe3\x02\x12\xb2\x01\x1b\xb5k\xdb\xf1\xbc5i\x0f:N\x0f\xd9\x05\xea\x8a\x01\xb2\u07dd!\x9fW\x98\x00\x00\u07d4\xe3\x03\x16\u007f=I`\xfe\x88\x1b2\x80\n+J\xef\xf1\xb0\x88\u0509lk\x93[\x8b\xbd@\x00\x00\u07d4\xe3\x04\xa3/\x05\xa87btJ\x95B\x97o\xf9\xb7#\xfa1\xea\x89Ur\xf2@\xa3F \x00\x00\u07d4\xe3\bCR\x04y7d\xf5\xfc\xbee\xebQ\x0fZtJeZ\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe3\t\x97L\xe3\x9d`\xaa\xdf.ig2Q\xbf\x0e\x04v\n\x10\x89\r\xc5_\xdb\x17d{\x00\x00\u07d4\xe3\x1bN\xef\x18L$\xab\t\x8e6\xc8\x02qK\xd4t=\xd0\u0509\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe3!\xbbJ\x94j\xda\xfd\xad\xe4W\x1f\xb1\\\x00C\u04de\xe3_\x89Udu8+L\x9e\x00\x00\u07d4\xe3&<\xe8\xafm\xb3\xe4gXE\x02\xedq\t\x12^\xae\"\xa5\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe3+\x1cG%\xa1\x87TI\u93d7\x0e\xb3\xe5@b\xd1X\x00\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe3/\x95vmW\xb5\xcdK\x172\x89\u0587o\x9edU\x81\x94\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xe38@\u063c\xa7\u0698\xa6\xf3\u0416\xd8=\xe7\x8bp\xb7\x1e\xf8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe38\xe8Y\xfe.\x8c\x15UHH\xb7\\\xae\u0368w\xa0\xe82\x89a\xac\xff\x81\xa7\x8a\xd4\x00\x00\u07d4\xe3=\x98\x02 \xfa\xb2Y\xafj\x1fK8\xcf\x0e\xf3\xc6\xe2\xea\x1a\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe3=\xf4\u0380\u0336*v\xb1+\xcd\xfc\xec\xc4b\x89\x97:\xa9\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xe3?\xf9\x87T\x1d\xde\\\xde\u0a29m\xcc?3\xc3\xf2L\u008a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xe3A\v\xb7U|\xf9\x1dy\xfai\xd0\xdf\xea\n\xa0u@&Q\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe3Ad-@\u04af\xce.\x91\a\xc6py\xacz&`\bl\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe3TS\xee\xf2\xcc2\x89\x10CR\x8d\t\x84i\x80\x00\xe0\x94\xe5\x10\xd6y\u007f\xba=f\x93\x83Z\x84N\xa2\xadT\x06\x91\x97\x1b\x8a\x03\xae9\xd4s\x83\xe8t\x00\x00\u07d4\xe5\x14!\xf8\xee\"\x10\xc7\x1e\xd8p\xfea\x82v\u0215J\xfb\xe9\x89Hz\x9a0E9D\x00\x00\u07d4\xe5\x1e\xb8~\u007f\xb71\x1fR(\xc4y\xb4\x8e\u0247\x881\xacL\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5!V1\xb1BH\xd4Z%R\x96\xbe\xd1\xfb\xfa\x030\xff5\x89G\x03\xe6\xebR\x91\xb8\x00\x00\xe0\x94\xe5(\xa0\xe5\xa2g\xd6g\xe99:e\x84\xe1\x9b4\u071b\xe9s\x8a\x01/\x93\x9c\x99\xed\xab\x80\x00\x00\u07d4\xe54%\xd8\xdf\x1f\x11\xc3A\xffX\xae_\x148\xab\xf1\xcaS\u03c9\x11t\xa5\xcd\xf8\x8b\xc8\x00\x00\u07d4\xe5No\x9c\xffV\xe1\x9cF\x1e\xb4T\xf9\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe5A\x02SM\xe8\xf2>\xff\xb0\x93\xb3\x12B\xad;#?\xac\xfd\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xe5E\xee\x84\xeaH\xe5d\x16\x1e\x94\x82\u055b\xcf@j`,\xa2\x89dI\xe8NG\xa8\xa8\x00\x00\u07d4\xe5H\x1a\u007f\xedB\xb9\x01\xbb\xed x\x9b\u052d\xe5\r_\x83\xb9\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5Y\xb5\xfd3{\x9cUr\xa9\xbf\x9e\x0f%!\xf7\xd4F\xdb\xe4\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe5\\\x80R\n\x1b\x0fu[\x9a,\xd3\xce!Ov%e>\x8a\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe5mC\x13$\xc9)\x11\xa1t\x9d\xf2\x92p\x9c\x14\xb7ze\u034a\x01\xbc\x85\xdc*\x89\xbb \x00\x00\u07d4\xe5})\x95\xb0\xeb\xdf?<\xa6\xc0\x15\xeb\x04&\r\xbb\x98\xb7\u0189lk\x93[\x8b\xbd@\x00\x00\u07d4\u51f1j\xbc\x8at\b\x1e6\x13\xe1CB\xc03u\xbf\bG\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\x89\xfav\x98M\xb5\xec@\x04\xb4n\u8954\x92\xc3\aD\u0389\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\xe5\x8d\xd228\xeen\xa7\xc2\x13\x8d8]\xf5\x00\xc3%\xf3v\xbe\x89b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xe5\x95?\xeaIq\x04\xef\x9a\xd2\xd4\xe5\x84\x1c'\x1f\a5\x19\u0089&)\xf6n\fS\x00\x00\x00\xe0\x94\u5587\x97F\x8e\xf7g\x10\x1bv\x1dC\x1f\xce\x14\xab\xff\u06f4\x8a\x01\xb3\xd9i\xfaA\x1c\xa0\x00\x00\u07d4\xe5\x97\xf0\x83\xa4i\xc4Y\x1c=+\x1d,w'\x87\xbe\xfe'\xb2\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\u07d4\xe5\x9b;\xd3\x00\x89?\x97#>\xf9G\xc4or\x17\xe3\x92\xf7\xe9\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe5\xa3e4<\xc4\xeb\x1ew\x03h\xe1\xf1\x14Jw\xb82\xd7\xe0\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe5\xa3\xd7\xeb\x13\xb1\\\x10\x01w#m\x1b\xeb0\xd1~\xe1T \x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\xaa\v\x83;\xb9\x16\xdc\x19\xa8\xddh?\x0e\xde$\x1d\x98\x8e\xba\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\u5def\x14i\x86\xc0\xff\x8f\x85\xd2.l\xc34\a}\x84\xe8$\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\xb8&\x19l\x0e\x1b\xc1\x11\x9b\x02\x1c\xf6\xd2Y\xa6\x10\u0256p\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe5\xb9o\u026c\x03\xd4H\xc1a:\xc9\x1d\x15\x97\x81E\xdb\xdf\u0449\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\u5e40\u048e\xec\xe2\xc0o\xcal\x94s\x06\x8b7\u0526\xd6\xe9\x89%\xaf\u058c\xac+\x90\x00\x00\u07d4\u5eb4\xf0\xaf\u0629\u0463\x81\xb4Wa\xaa\x18\xf3\xd3\xcc\xe1\x05\x89Q\xbf\xd7\xc18x\xd1\x00\x00\u07d4\xe5\xbc\u020c;%on\xd5\xfeU\x0eJ\x18\x19\x8b\x943V\xad\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\xbd\xf3OL\xccH>L\xa50\xcc|\xf2\xbb\x18\xfe\xbe\x92\xb3\x89\x06\xd85\xa1\v\xbc\xd2\x00\x00\u07d4\xe5\u0713I\xcbR\xe1a\x19a\"\u03c7\xa3\x896\xe2\xc5\u007f4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\xe38\x00\xa1\xb2\xe9k\xde\x101c\n\x95\x9a\xa0\a\xf2nQ\x89Hz\x9a0E9D\x00\x00\u07d4\xe5\xe3~\x19@\x8f,\xfb\xec\x834\x9d\u0501S\xa4\xa7\x95\xa0\x8f\x89\u3bb5sr@\xa0\x00\x00\u07d4\xe5\xed\xc7>bo]4A\xa4U9\xb5\xf7\xa3\x98\u0153\xed\xf6\x89.\xe4IU\b\x98\xe4\x00\x00\u07d4\xe5\xed\xf8\x12?$\x03\xce\x1a\x02\x99\xbe\xcfz\xactM\a_#\x89\n\xdaUGK\x814\x00\x00\u07d4\xe5\xf8\xefm\x97\x066\xb0\u072aO \x0f\xfd\xc9\xe7Z\xf1t\x1c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe5\xfb1\xa5\xca\xeej\x96\xde9;\xdb\xf8\x9f\xbee\xfe\x12[\xb3\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe5\xfb\xe3I\x84\xb67\x19o3\x1cg\x9d\f\fG\xd84\x10\xe1\x89llD\xfeG\xec\x05\x00\x00\u07d4\xe6\tU\xdc\v\xc1V\xf6\xc4\x18I\xf6\xbdwk\xa4K\x0e\xf0\xa1\x89\x10C\x16'\xa0\x93;\x00\x00\u07d4\xe6\nU\xf2\u07d9m\u00ee\xdbil\b\xdd\xe09\xb2d\x1d\xe8\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe6\x11[\x13\xf9y_~\x95e\x02\xd5\aEg\u06b9E\xcek\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xe6\x1f(\t\x15\xc7t\xa3\x1d\"<\xf8\f\x06\x92f\xe5\xad\xf1\x9b\x89/\xb4t\t\x8fg\xc0\x00\x00\u07d4\xe6/\x98e\a\x12\xeb\x15\x87S\xd8)r\xb8\u9723\xf6\x18w\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe6/\x9d|d\xe8\xe2cZ\xeb\x88=\xd7;\xa6\x84\xee|\x10y\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xe6>xt\x14\xb9\x04\x84x\xa5\a35\x9e\xcd\xd7\xe3dz\xa6\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xe6FfXr\xe4\v\rz\xa2\xff\x82r\x9c\xaa\xba[\xc3\u8789\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe6N\xf0\x12e\x8dT\xf8\xe8`\x9cN\x90#\xc0\x9f\xe8e\xc8;\x89\x01\x84\x93\xfb\xa6N\xf0\x00\x00\u07d4\xe6On\x1dd\x01\xb5l\akd\xa1\xb0\x86}\v/1\rN\x89\x02\u02edq\xc5:\xe5\x00\x00\u07d4\xe6g\xf6R\xf9W\u008c\x0ef\u04364\x17\xc8\f\x8c\x9d\xb8x\x89 \x9d\x92/RY\xc5\x00\x00\xe0\x94\xe6w\xc3\x1f\xd9\xcbr\x00u\u0724\x9f\x1a\xbc\xcdY\xec3\xf74\x8a\x01\xa6\u05be\xb1\xd4.\xe0\x00\x00\u07d4\xe6|,\x16e\u02038h\x81\x87b\x9fI\xe9\x9b`\xb2\u04fa\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xe6\x9al\xdb:\x8a}\xb8\xe1\xf3\f\x8b\x84\xcds\xba\xe0+\xc0\xf8\x8a\x03\x94\xfd\xc2\xe4R\xf6q\x80\x00\u07d4\xe6\x9d\x1c7\x8bw\x1e\x0f\xef\xf0Q\xdbi\xd9f\xacgy\xf4\xed\x89\x1d\xfaj\xaa\x14\x97\x04\x00\x00\u07d4\xe6\x9f\xcc&\xed\"_{.7\x984\xc5$\xd7\f\x175\u5f09lk\x93[\x8b\xbd@\x00\x00\u07d4\xe6\xa3\x01\x0f\x02\x01\xbc\x94\xffg\xa2\xf6\x99\xdf\xc2\x06\xf9\xe7gB\x89/\xa7\xcb\xf6dd\x98\x00\x00\u07d4\xe6\xa6\xf6\xddop\xa4V\xf4\xec\x15\xefz\xd5\xe5\u06f6\x8b\xd7\u0709\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe6\xb2\x0f\x98\n\xd8S\xad\x04\xcb\xfc\x88|\xe6`\x1ck\xe0\xb2L\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\u6cec?]M\xa5\xa8\x85}\v?0\xfcK+i+w\u05c9O%\x91\xf8\x96\xa6P\x00\x00\u07d4\xe6\xb9T_~\u0406\xe5R\x92F9\xf9\xa9\xed\xbb\xd5T\v>\x89\xcb\xd4{n\xaa\x8c\xc0\x00\x00\xe0\x94\xe6\xbc\xd3\n\x8f\xa18\xc5\xd9\xe5\xf6\xc7\xd2\u0680i\x92\x81-\u034a7\x0e\xa0\xd4|\xf6\x1a\x80\x00\x00\u07d4\xe6\xc8\x1f\xfc\xec\xb4~\xcd\xc5\\\vq\xe4\x85_>^\x97\xfc\x1e\x89\x12\x1e\xa6\x8c\x11NQ\x00\x00\u07d4\xe6\xcb&\vqmL\n\xb7&\xee\xeb\a\xc8pr\x04\xe2v\xae\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe6\xcb?1$\xc9\xc9\xcc84\xb1'K\xc33dV\xa3\x8b\xac\x89\x17+\x1d\xe0\xa2\x13\xff\x00\x00\xe0\x94\xe6\xd2\"\t\xff\u0438u\t\xad\xe3\xa8\xe2\xefB\x98y\u02c9\xb5\x8a\x03\xa7\xaa\x9e\x18\x99\xca0\x00\x00\u07d4\xe6\u051f\x86\xc2(\xf4sg\xa3^\x88l\xaa\xcb'\x1eS\x94)\x89\x16^\xc0\x9d\xa7\xa1\x98\x00\x00\u07d4\xe6\xe6!\xea\xab\x01\xf2\x0e\xf0\x83k|\xadGFL\xb5\xfd<\x96\x89\x11!\x93B\xaf\xa2K\x00\x00\u07d4\xe6\xe8\x861{jf\xa5\xb4\xf8\x1b\xf1d\xc58\xc2d5\x17e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe6\u98ddu\x0f\xe9\x949N\xb6\x82\x86\xe5\xeab\xa6\x99x\x82\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xe6\xec\\\xf0\u011b\x9c1~\x1epc\x15\uf7b7\xc0\xbf\x11\xa7\x8a\x03\xa4i\xf3F~\x8e\xc0\x00\x00\u07d4\xe6\xf5\xebd\x9a\xfb\x99Y\x9cAK'\xa9\xc9\xc8U5\u007f\xa8x\x89\x90\xf54`\x8ar\x88\x00\x00\xe0\x94\xe6\xfe\n\xfb\x9d\xce\xdd7\xb2\xe2,E\x1b\xa6\xfe\xabg4\x803\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xe7\x10\xdc\u041b\x81\x01\xf9C{\xd9}\xb9\ns\xef\x99=\v\xf4\x89\x14\xee6\xc0Z\xc2R\x00\x00\u07d4\xe7'\xe6~\xf9\x11\xb8\x1fl\xf9\xc7?\xcb\xfe\xbc+\x02\xb5\xbf\u0189lk\x93[\x8b\xbd@\x00\x00\u07d4\xe7.\x1d3\\\u009a\x96\xb9\xb1\xc0/\x00:\x16\xd9q\xe9\v\x9d\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xe71\x1c\x953\xf0\t,rH\xc9s\x9b[,\x86J4\xb1\u0389\x97\xf9}l\xc2m\xfe\x00\x00\u07d4\xe7;\xfe\xad\xa6\xf0\xfd\x01o\xbc\x84>\xbc\xf6\xe3p\xa6[\xe7\f\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xe7<\xcfCg%\xc1Q\xe2U\xcc\xf5!\f\xfc\xe5\xa4?\x13\xe3\x89\x01\x15NS!}\xdb\x00\x00\u07d4\xe7B\xb1\xe6\x06\x9a\x8f\xfc'\f\xc6\x1f\xa1d\xac\x15SE\\\x10]\x04\x88~\x14\x89\x06\x96\xd8Y\x00 \xbb\x00\x00\u07d4\xe7\\\x1f\xb1w\b\x9f>X\xb1\x06y5\xa6Yn\xf1s\u007f\xb5\x89\x05j\x87\x9f\xa7uG\x00\x00\u07d4\xe7\\;8\xa5\x8a?3\xd5V\x90\xa5\xa5\x97f\xbe\x18^\x02\x84\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe7a\xd2\u007f\xa3P,\xc7k\xb1\xa6\bt\x0e\x14\x03\u03dd\xfci\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\u07d4\xe7f\xf3O\xf1o<\xfc\xc9s!r\x1fC\xdd\xf5\xa3\x8b\f\xf4\x89T\x06\x923\xbf\u007fx\x00\x00\u07d4\xe7m\x94Z\xa8\x9d\xf1\xe4W\xaa4+1\x02\x8a^\x910\xb2\u03897\b\xba\xed=h\x90\x00\x00\u07d4\xe7s^\xc7e\x18\xfcj\xa9-\xa8qZ\x9e\xe3\xf6%x\x8f\x13\x89lM\x16\v\xaf\xa1\xb7\x80\x00\xe0\x94\xe7z\x89\xbdE\xdc\x04\xee\xb4\xe4\x1d{Ykp~nQ\xe7L\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xe7}}\uac96\u0234\xfa\a\xca;\xe1\x84\x16=Zm`l\x89\x05\x049\x04\xb6q\x19\x00\x00\u07d4\xe7\u007f\xeb\xab\xdf\b\x0f\x0f]\xca\x1d?Wf\xf2\xa7\x9c\x0f\xfa|\x89K\"\x9d(\xa8Ch\x00\x00\xe0\x94\u7025c\x06\xba\x1ek\xb31\x95,\"S\x9b\x85\x8a\xf9\xf7}\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\xe7\x81\xecs-@\x12\x02\xbb\x9b\xd18`\x91\r\xd6\u009a\xc0\xb6\x89C8t\xf62\xcc`\x00\x00\u07d4\xe7\x84\xdc\xc8s\xaa\x8c\x15\x13\xec&\xff6\xbc\x92\xea\xc6\xd4\xc9h\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe7\x91-L\xf4V,W=\xdc[q\xe3s\x10\xe3x\xef\x86\u0249\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\xe7\x91\u0545\xb8\x996\xb2])\x8f\x9d5\xf9\xf9\xed\xc2Z)2\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe7\x924\x9c\xe9\xf6\xf1O\x81\xd0g@\x96\xbe\xfa\x1f\x92!\xcd\xea\x89[]#J\r\xb48\x80\x00\u07d4\xe7\x96\xfdN\x83\x9bL\x95\xd7Q\x0f\xb7\xc5\xc7+\x83\xc6\xc3\xe3\u01c9\x1b\xc43\xf2?\x83\x14\x00\x00\xe0\x94\xe7\xa4/Y\xfe\xe0t\xe4\xfb\x13\xea\x9eW\xec\xf1\xccH(\"I\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xe7\xa4V\f\x84\xb2\x0e\x0f\xb5LIg\f)\x03\xb0\xa9lB\xa4\x89 j\xea\u01e9\x03\x98\x00\x00\u07d4\xe7\xa8\xe4q\xea\xfby\x8fET\xccnRg0\xfdV\xe6,}\x8965\u026d\xc5\u07a0\x00\x00\u07d4\u7f82\xc6Y<\x1e\xed\xdd*\xe0\xb1P\x01\xff \x1a\xb5{/\x89\x01\t\x10\xd4\xcd\xc9\xf6\x00\x00\u07d4\xe7\u01b5\xfc\x05\xfct\x8e[C\x81rdI\xa1\xc0\xad\x0f\xb0\xf1\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe7\xd1u$\xd0\v\xad\x82I|\x0f'\x15jd\u007f\xf5\x1d'\x92\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xe7\xd2\x13\x94\u007f\u02d0J\xd78H\v\x1e\xed/\\2\x9f'\xe8\x89\x01\x03\u00f1\xd3\xe9\xc3\x00\x00\u07d4\xe7\xd6$\x06 \xf4,^\u06f2\xed\xe6\xae\xc4=\xa4\xed\x9bWW\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe7\xda`\x9d@\xcd\xe8\x0f\x00\xce[O\xfbj\xa9\u04304\x94\xfc\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe7\xf0oi\x9b\xe3\x1cD\vC\xb4\xdb\x05\x01\xec\x0e%&\x16D\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe7\xf4\xd7\xfeoV\x1f\u007f\xa1\xda0\x05\xfd6TQ\xad\x89\u07c9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe7\xfd\x8f\xd9Y\xae\xd2v~\xa7\xfa\x96\f\xe1\xdbS\xaf\x80%s\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe8\x0e\u007f\xef\x18\xa5\xdb\x15\xb0\x14s\xf3\xadkx\xb2\xa2\xf8\xac\u0649\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xe8\x13\u007f\xc1\xb2\xec|\xc7\x10:\xf9!\x89\x9bJ9\xe1\xd9Y\xa1\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4\xe8\x1c-4l\n\xdfL\xc5g\b\xf69K\xa6\xc8\u0226J\x1e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe8,X\xc5yC\x1bg5F\xb5:\x86E\x9a\xca\xf1\u079b\x93\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xe84\xc6C\x18 \\\xa7\xddJ!\xab\xcb\b&l\xb2\x1f\xf0,\x8965\xc6 G9\u0640\x00\u07d4\xe86\x04\xe4\xffk\xe7\xf9o`\x18\xd3\xec0r\xecR]\xffk\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\xe0\x94\xe8E\xe3\x87\xc4\xcb\u07d8\"\x80\xf6\xaa\x01\xc4\x0eK\xe9X\u0772\x8a\x05K@\xb1\xf8R\xbd\xa0\x00\x00\u07d4\xe8H\xca~\xbf\xf5\xc2O\x9b\x9c1g\x97\xa4;\xf7\xc3V)-\x89\x06.\x11\\\x00\x8a\x88\x00\x00\u07d4\xe8KU\xb5%\xf1\x03\x9etK\x91\x8c\xb33$\x92\xe4^\xcaz\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe8O\x80v\xa0\xf2\x96\x9e\xcd3>\xef\x8d\xe4\x10B\x98b\x91\xf2\x89\x17k4O*x\xc0\x00\x00\u07d4\xe8d\xfe\xc0~\xd1!Je1\x1e\x11\xe3)\xde\x04\r\x04\xf0\xfd\x89Y\u0283\xf5\xc4\x04\x96\x80\x00\u07d4\xe8}\xba\xc66\xa3w!\xdfT\xb0\x8a2\xefIY\xb5\xe4\xff\x82\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xe8~\x9b\xbf\xbb\xb7\x1c\x1at\ft\xc7#Bm\xf5]\x06=\u064a\x01\xb1\x92\x8c\x00\u01e68\x00\x00\u07d4\xe8~\xacm`+A\t\xc9g\x1b\xf5{\x95\f,\xfd\xb9\x9dU\x89\x02\xb4\xf2\x19r\xec\xce\x00\x00\xe0\x94\u807b\xbeir-\x81\xef\xec\xaaH\u0455*\x10\xa2\xbf\xac\x8f\x8a\x03c\\\x9a\xdc]\xea\x00\x00\x00\u07d4\xe8\x92Is\x8b~\xce\xd7\xcbfjf\xe4s\xbcv\x82/U\t\x8d\x89\xb9\x1c\u0149lk\x93[\x8b\xbd@\x00\x00\u07d4\xe8\xc3\u04f0\xe1\u007f\x97\xd1\xe7V\xe6\x84\xf9N\x14p\xf9\x9c\x95\xa1\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xe8\xc3\xf0E\xbb}8\xc9\xd2\U000d5c3a\x84\x92\xb2S#\t\x01\x8a\x01\xe7\xe4\x17\x1b\xf4\u04e0\x00\x00\u07d4\xe8\xccC\xbcO\x8a\xcf9\xbf\xf0N\xbf\xbfB\xaa\xc0j2\x84p\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xe8\xd9B\xd8/\x17^\xcb\x1c\x16\xa4\x05\xb1\x01C\xb3\xf4k\x96:\x89\x1e\xd2\xe8\xffm\x97\x1c\x00\x00\u07d4\xe8\u077e\xd72\xeb\xfeu@\x96\xfd\xe9\bk\x8e\xa4\xa4\xcd\xc6\x16\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe8\xder^\xca]\xef\x80_\xf7\x94\x1d1\xac\x1c.4-\xfe\x95\x89\x85~\ro\x1d\xa7j\x00\x00\u07d4\xe8\xe9\x85\x05\x86\xe9OR\x99\xabIK\xb8!\xa5\xf4\f\x00\xbd\x04\x89\xcf\x15&@\xc5\xc80\x00\x00\xe0\x94\xe8\xea\u047b\x90\xcc\u00ee\xa2\xb0\xdc\u0175\x80VUFU\xd1\u054a\x01\xa4\xab\xa2%\xc2\a@\x00\x00\u07d4\xe8\xea\xf1)D\t-\xc3Y\x9b9S\xfa|\xb1\xc9v\x1c\xc2F\x89a\x94\x04\x9f0\xf7 \x00\x00\xe0\x94\xe8\xedQ\xbb\xb3\xac\xe6\x9e\x06\x02K3\xf8hD\xc4sH\u06de\x8a\"\xf9\xea\x89\xf4\xa7\xd6\xc4\x00\x00\u07d4\xe8\xef\x10\r|\xe0\x89X2\xf2g\x8d\xf7-J\u03cc(\xb8\xe3\x89\x1b\x1bk\u05efd\xc7\x00\x00\u07d4\xe8\xf2\x99i\xe7\\e\xe0\x1c\xe3\xd8aT }\n\x9e|v\xf2\x89\xa2/\xa9\xa7:'\x19\x80\x00\u07d4\xe8\xfc6\xb0\x13\x1e\xc1 \xac\x9e\x85\xaf\xc1\f\xe7\vV\u0636\xba\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe9\n5L\xec\x04\u059e]\x96\xdd\xc0\xc5\x13\x8d=3\x15\n\xa0\x89\x1b\x1a}\u03caD\u04c0\x00\xe0\x94\xe9\x13>}1\x84]_+f\xa2a\x87\x92\xe8i1\x1a\xcff\x8a\x05\x17\xc0\xcb\xf9\xa3\x90\x88\x00\x00\u07d4\xe9\x1d\xac\x01\x95\xb1\x9e7\xb5\x9bS\xf7\xc0\x17\xc0\xb29[\xa4L\x89e\xea=\xb7UF`\x00\x00\u07d4\xe9\x1f\xa0\xba\xda\u0779\xa9~\x88\xd3\xf4\xdb|U\u05bbt0\xfe\x89\x14b\fW\xdd\xda\xe0\x00\x00\u07d4\xe9#\xc0aw\xb3B~\xa4H\xc0\xa6\xff\x01\x9bT\xccT\x8d\x95\x89\x01\xf7\x80\x01Fg\xf2\x80\x00\xe0\x94\xe9=G\xa8\u0288]T\fNRo%\xd5\xc6\xf2\xc1\b\u0138\x8a\x17\xda:\x04\u01f3\xe0\x00\x00\x00\u07d4\xe9E\x8fh\xbb',\xb5g:\x04\xf7\x81\xb4\x03Uo\u04e3\x87\x89\x03N\x8b\x88\xce\xe2\xd4\x00\x00\u07d4\xe9IA\xb6\x03`\x19\xb4\x01j0\xc1\x03}Zi\x03\xba\xba\xad\x89*H\xac\xabb\x04\xb0\x00\x00\u07d4\xe9I[\xa5\x84'(\xc0\ud5fe7\xd0\xe4\"\xb9\x8di ,\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xe9M\xed\x99\u0735r\xb9\xbb\x1d\u02e3/m\xee\x91\xe0W\x98N\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\xe0\x94\xe9QyR}\uc951l\xa9\xa3\x8f!\\\x1e\x9c\xe77\xb4\u024a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xe9U\x91\x85\xf1f\xfc\x95\x13\xccq\x11aD\xce-\xeb\x0f\x1dK\x8a\x04<3\xc1\x93ud\x80\x00\x00\u0794\xe9^\x92\xbb\xc6\xde\a\xbf:f\x0e\xbf_\xeb\x1c\x8a5'\xe1\u0148\xfc\x93c\x92\x80\x1c\x00\x00\xe0\x94\xe9e\u06a3@9\xf7\xf0\xdfb7Z7\u5acar\xb3\x01\xe7\x8a\x01\x03\xfd\xde\u0373\xf5p\x00\x00\u07d4\xe9i\xea\x15\x95\xed\xc5\u0127\a\xcf\xde8\t)c2Q\xa2\xb0\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xe9k\x18N\x1f\x0fT\x92J\xc8t\xf6\v\xbfDptF\xb7+\x89\x9d\xcc\x05\x15\xb5n\f\x00\x00\xe0\x94\xe9m}L\xdd\x15U:NM1mmd\x80\xca<\xea\x1e8\x8a\x02\x95]\x02\xe1\xa15\xa0\x00\x00\u07d4\xe9n-8\x13\xef\xd1\x16_\x12\xf6\x02\xf9\u007fJb\x90\x9d\x1b;\xc0\xe9\xaa\"\u007f\x90\x89'\xcaK\xd7\x19\xf0\xb8\x00\x00\u07d4\xea,\x19}&\xe9\x8b\r\xa8>\x1br\u01c7a\x8c\x97\x9d=\xb0\x89\x01\x11du\x9f\xfb2\x00\x00\xe0\x94\xea7y\xd1J\x13\xf6\u01c5f\xbc\xde@5\x91A:b9\u06ca)\xb7d2\xb9DQ \x00\x00\u07d4\xeaN\x80\x9e&j\xe5\xf1<\xdb\u33dd\x04V\xe68m\x12t\x89\xf3\xf2\v\x8d\xfai\xd0\x00\x00\xe0\x94\xeaS\xc9T\xf4\xed\x97\xfdH\x10\x11\x1b\u06b6\x9e\xf9\x81\xef%\xb9\x8a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u07d4\xeaS\xd2ed\x85\x9d\x9e\x90\xbb\x0eS\xb7\xab\xf5`\xe0\x16,8\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xea`Ci\x12\xdek\xf1\x87\u04e4r\xff\x8fS3\xa0\xf7\xed\x06\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xea`T\x9e\xc7U?Q\x1d!I\xf2\xd4fl\xbd\x92C\xd9<\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xeaf\xe7\xb8M\u037f6\xee\xa3\xe7[\x858*u\xf1\xa1]\x96\x89]\xbc\x91\x91&o\x11\x80\x00\u07d4\xeahlPW\t<\x17\x1cf\u06d9\xe0\x1b\x0e\xce\xcb0\x86\x83\x89\x14\u0768],\xe1G\x80\x00\u07d4\xeaj\xfe,\xc9(\xac\x83\x91\xeb\x1e\x16_\xc4\x00@\xe3t!\u7262\u007f\xa0c\xb2\xe2\xe6\x80\x00\u07d4\xeay\x05}\xab\xef^d\xe7\xb4O\u007f\x18d\x8e~S7\x18\u0489\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xea|Mm\xc7)\xcdk\x15|\x03\xad#|\xa1\x9a \x93F\u00c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xea\x81h\xfb\xf2%\xe7\x86E\x9c\xa6\xbb\x18\xd9c\xd2kPS\t\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xea\x81\u02868T\f\xd9\xd4\xd7=\x06\x0f,\xeb\xf2$\x1f\xfc>\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xea\x83\x17\x19yYB@A\xd9\xd7\xc6z>\xce\x1d\xbbx\xbbU\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\xea\x85'\xfe\xbf\xa1\xad\xe2\x9e&A\x93)\u04d3\xb9@\xbb\xb7\u0709lj\xccg\u05f1\xd4\x00\x00\u07d4\xea\x8f0\xb6\xe4\xc5\xe6R\x90\xfb\x98d%\x9b\u0159\x0f\xa8\ue289\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xea\x94\xf3(\b\xa2\uf29b\xf0\x86\x1d\x1d$\x04\xf7\xb7\xbe%\x8a\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xea\xa4\\\xea\x02\xd8},\xc8\xfd\xa9CN-\x98[\xd4\x03\x15\x84\x89h\x1f\xc2\xccn+\x8b\x00\x00\xe0\x94\uac3d\x14\x83\t\x18l\xf8\xcb\xd1;r2\xd8\tZ\u02c3:\x8a\x02C\x9a\x88\x1cjq|\x00\x00\u07d4\uaed0\xd3y\x89\xaa\xb3\x1f\xea\xe5G\xe0\xe6\xf3\x99\x9c\xe6\xa3]\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xea\xc0\x82~\xff\fn?\xf2\x8a}JT\xf6\\\xb7h\x9d{\x99\x89\x9a\xd9\u67ddGR\x00\x00\u07d4\xea\xc1H(&\xac\xb6\x11\x1e\x19\xd3@\xa4_\xb8QWk\xed`\x89\x01\xbe\x8b\xab\x04\u067e\x80\x00\xe0\x94\xea\xc1{\x81\xedQ\x91\xfb\b\x02\xaaT3s\x13\x83A\a\xaa\xa4\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xea\u00efW\x84\x92\u007f\u9958\xfcN\xec8\xb8\x10/7\xbcX\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xea\u01b9\x88BT.\xa1\v\xb7O&\xd7\xc7H\x8fi\x8bdR\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xea\xc7h\xbf\x14\xb8\xf9C.i\xea\xa8*\x99\xfb\xeb\x94\xcd\f\x9c\x8a\x14\u06f2\x19\\\xa2(\x90\x00\x00\u07d4\xea\xd2\x1c\x1d\xec\u03ff\x1c\\\xd9f\x88\xa2Gki\xba\a\xceJ\x89\x03\xf2M\x8eJ\x00p\x00\x00\u07d4\xea\xd4\xd2\xee\xfbv\xab\xaeU3\x96\x1e\xdd\x11@\x04\x06\xb2\x98\xfc\x89\xd2U\xd1\x12\xe1\x03\xa0\x00\x00\u07d4\xea\xd6Rb\xed]\x12-\xf2\xb2u\x14\x10\xf9\x8c2\xd1#\x8fQ\x89\x05\x83\x17\xedF\xb9\xb8\x00\x00\u07d4\xea\xd7P\x16\u3801Pr\xb6\xb1\b\xbc\xc1\xb7\x99\xac\xf08>\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xea\xea#\xaa\x05r\x00\xe7\xc9\xc1^\x8f\xf1\x90\xd0\xe6l\f\x0e\x83\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xea\xed\x16\xea\xf5\u06ab[\xf0)^^\a\u007fY\xfb\x82U\x90\v\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xea\xed\xcck\x8bib\xd5\xd9(\x8c\x15lW\x9dG\xc0\xa9\xfc\xff\x89\x04\x9b\x9c\xa9\xa6\x944\x00\x00\u07d4\xea\xf5#\x88Tn\xc3Z\xcaolc\x93\xd8\xd6\t\xde:K\xf3\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xeb\x10E\x8d\xac\xa7\x9eJk$\xb2\x9a\x8a\x8a\xdaq\x1b\u007f.\xb6\x89\u063beI\xb0+\xb8\x00\x00\u07d4\xeb\x1c\xea{E\u047dM\x0e*\x00{\u04ff\xb3Tu\x9e,\x16\x89\n\xbb\xcdN\xf3wX\x00\x00\u07d4\xeb%H\x1f\u035c\"\x1f\x1a\xc7\xe5\xfd\x1e\u0353\a\xa1b\x15\xb8\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\xe0\x94\xeb.\xf3\u04cf\xe6R@<\xd4\xc9\xd8^\xd7\xf0h,\xd7\xc2\u078a\t\x0fSF\b\xa7(\x80\x00\x00\xe0\x94\xeb;\xddY\xdc\u0765\xa9\xbb*\xc1d\x1f\xd0!\x80\xf5\xf3e`\x8a\x01e\xc9fG\xb3\x8a \x00\x00\u07d4\xeb<\xe7\xfc8\x1cQ\xdb}_\xbdi/\x8f\x9e\x05\x8aLp=\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xebE?Z:\xdd\u074a\xb5gP\xfa\xdb\x0f\xe7\xf9M\x9c\x89\xe7\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xebO\x00\xe2\x836\xea\t\x94%\x88\ueb12\x18\x11\xc5\"\x14<\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xebR\xab\x10U4\x922\x9c\x1cT\x83:\xe6\x10\xf3\x98\xa6[\x9d\x89\b=lz\xabc`\x00\x00\u07d4\xebW\r\xba\x97R'\xb1\xc4-n\x8d\xea,V\u026d\x96\x06p\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xebc\x94\xa7\xbf\xa4\u0489\x11\u0565\xb2>\x93\xf3^4\f\"\x94\x89\x04:w\xaa\xbd\x00x\x00\x00\u07d4\xebh\x10i\x1d\x1a\xe0\u045eG\xbd\"\u03be\u0cfa'\xf8\x8a\x89\x87\x85c\x15\xd8x\x15\x00\x00\u07d4\xebvBL\x0f\u0557\xd3\xe3A\xa9d*\xd1\xee\x11\x8b+W\x9d\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xeb| +F+|\u0145]t\x84u_n&\xefC\xa1\x15\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xeb\x83\\\x1a\x91\x18\x17\x87\x8a3\xd1gV\x9e\xa3\xcd\u04c7\xf3(\x8965\u026d\xc5\u07a0\x00\x00\u07d4\ub268\x82g\t\t\xcf7~\x9ex(n\xe9{\xa7\x8dF\u0089+|\xc2\xe9\xc3\"\\\x00\x00\xe0\x94\xeb\x90\u01d3\xb3S\x97a\xe1\xc8\x14\xa2\x96q\x14\x86\x92\x19>\xb4\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xeb\x9c\xc9\xfe\bi\xd2\u06b5,\u01ea\xe8\xfdW\xad\xb3_\x9f\xeb\x89j\x93\xbb\x17\xaf\x81\xf8\x00\x00\xe0\x94\ub8c8\xb0\xda'\xc8{\x1c\xc0\xea\xc6\xc5{,Z\vE\x9c\x1a\x8a\x01p\xa0\xf5\x04\x0eP@\x00\x00\u07d4\xeb\xaa!m\xe9\xccZC\x03\x17\a\xd3o\xe6\u057e\xdc\x05\xbd\xf0\x89j\xc5\xc6-\x94\x86\a\x00\x00\u07d4\xeb\xac+D\b\xefT1\xa1;\x85\b\xe8bP\x98!\x14\xe1E\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xeb\xb6,\xf8\xe2,\x88K\x1b(\xc6\xfa\x88\xfb\xbc\x17\x93\x8a\xa7\x87\x89+By\x84\x03\u0278\x00\x00\u07d4\xeb\xb7\xd2\xe1\x1b\u01b5\x8f\n\x8dE\xc2\xf6\xde0\x10W\n\u0211\x89\x01s\x17\x90SM\xf2\x00\x00\u07d4\xeb\xbbO,=\xa8\xbe>\xb6-\x1f\xfb\x1f\x95\x02a\u03d8\xec\u0689lk\x93[\x8b\xbd@\x00\x00\u07d4\xeb\xbdM\xb9\x01\x99R\u058b\x1b\x0fm\x8c\xf0h<\x008{\xb5\x89\x12\x04\x01V=}\x91\x00\x00\u07d4\xeb\xbe\xeb%\x91\x84\xa6\xe0\x1c\xcc\xfc\"\a\xbb\u0603xZ\xc9\n\x89!\x9b\xc1\xb0G\x83\xd3\x00\x00\u07d4\xeb\xd3V\x15j81#4=H\x84;\xff\xeda\x03\xe8f\xb3\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xeb\xd3{%ec\xe3\fo\x92\x89\xa8\xe2p/\bR\x88\b3\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xeb\xe4l\xc3\xc3L2\xf5\xad\xd6\xc3\x19[\xb4\x86\xc4q>\xb9\x18\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xeb\xff\x84\xbb\xefB0q\xe6\x04\xc3a\xbb\xa6w\xf5Y=\xefN\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xec\t'\xba\xc7\xdc6f\x9c(5J\xb1\xbe\x83\xd7\xee\xc3\t4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xec\x0e\x18\xa0\x1d\xc4\xdc]\xaa\xe5g\xc3\xfaL\u007f\x8f\x9bY\x02\x05\x89\x11\x1f\xfe@JA\xe6\x00\x00\xe0\x94\xec\x116,\xec\x81\t\x85\xd0\xeb\xbd{sE\x14D\x98[6\x9f\x8a\x06ZNIWpW1\x80\x00\u07d4\xec,\xb8\xb97\x8d\xff1\xae\xc3\xc2.\x0em\xad\xff1J\xb5\u0749lk\x93[\x8b\xbd@\x00\x00\u07d4\xec0\xad\u0749[\x82\xee1\x9eT\xfb\x04\xcb+\xb09q\xf3k\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xec;\x8bX\xa1'\x03\xe5\x81\xce_\xfd~!\xc5}\x1e\\f?\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xecHg\xd2\x17Z\xb5\xb9F\x93aYUFUF\x84\u0364`\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xecM\b\xaa.GIm\u0287\"]\xe3?+@\xa8\xa5\xb3o\x89\b\x90\xb0\xc2\xe1O\xb8\x00\x00\u07d4\xecX\xbc\r\f \xd8\xf4\x94efAS\xc5\xc1\x96\xfeY\u6f89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xec[\x19\x8a\x00\u03f5Z\x97\xb5\xd56D\xcf\xfa\x8a\x04\u04abE\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xec]\xf2'\xbf\xa8]z\xd7kBn\x1c\xee\x96;\xc7\xf5\x19\u074965\u026d\xc5\u07a0\x00\x00\xe0\x94\xec_\xea\xfe!\f\x12\xbf\u0265\xd0Y%\xa1#\xf1\xe7?\xbe\xf8\x8a`\x8f\xcf=\x88t\x8d\x00\x00\x00\u07d4\xeci\x04\xba\xe1\xf6\x97\x90Y\x17\t\xb0`\x97\x83s?%s\xe3\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\xe0\x94\xecs\x11L^@o\u06fe\t\xb4\xfab\x1b\xd7\x0e\xd5N\xa1\xef\x8a\x050%\xcd!o\xceP\x00\x00\u07d4\xecs\x83=\xe4\xb8\x10\xbb\x02x\x10\xfc\x8fi\xf5D\xe8<\x12\u044965\u026d\xc5\u07a0\x00\x00\u07d4\xecu\xb4\xa4u\x13\x12\v\xa5\xf8`9\x81O\x19\x98\xe3\x81z\u00c9\t\xb0\xbc\xe2\xe8\xfd\xba\x00\x00\u07d4\xecv\xf1.W\xa6U\x04\x03?,\v\xceo\xc0;\xd7\xfa\n\u0109\xc2\x12z\xf8X\xdap\x00\x00\u0794\xec\x80\x14\xef\xc7\xcb\xe5\xb0\xceP\xf3V,\xf4\xe6\u007f\x85\x93\xcd2\x88\xf0\x15\xf2W6B\x00\x00\u07d4\xec\x82\xf5\r\x06G_hM\xf1\xb3\x92\xe0\r\xa3A\xaa\x14TD\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xec\x83\xe7\x98\u00d6\xb7\xa5^*\"$\xab\u0343K'\xeaE\x9c\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xec\x89\xf2\xb6x\xa1\xa1[\x914\xec^\xb7\fjb\a\x1f\xba\xf9\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xec\x8c\x1d{j\xac\xcdB\x9d\xb3\xa9\x1e\xe4\xc9\xeb\x1c\xa4\xf6\xf7<\x89\xe6d\x99\"\x88\xf2(\x00\x00\xe0\x94\xec\x98Q\xbd\x91rpa\x02g\xd6\x05\x18\xb5M<\xa2\xb3[\x17\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xec\x99\xe9]\xec\xe4o\xff\xfb\x17^\xb6@\x0f\xbe\xbb\b\ue6d5\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xec\xa5\xf5\x87\x92\xb8\xc6-*\xf5Vq~\xe3\xee0(\xbeM\u0389lk\x93[\x8b\xbd@\x00\x00\u07d4\xec\xabZ\xba[\x82\x8d\xe1pS\x81\xf3\x8b\xc7D\xb3+\xa1\xb47\x892\xf5\x1e\u06ea\xa30\x00\x00\u07d4\xec\xaf3P\xb7\xce\x14M\x06\x8b\x18`\x10\x85,\x84\xdd\f\xe0\xf0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xec\xb9LV\x8b\xfeY\xad\xe6Pd_O&0lsl\xac\xe4\x89\x0e~\xeb\xa3A\vt\x00\x00\xe0\x94\xec\xbeB^g\r9\tN \xfbVC\xa9\xd8\x18\xee\xd26\u078a\x01\x0f\f\xf0d\xddY \x00\x00\xe0\x94\xec\xbe^\x1c\x9a\u04b1\xdc\xcf\n0_\xc9R/Fi\xdd:\xe7\x8a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xec\xcfz\x04W\xb5f\xb3F\xcag:\x18\x0fDA0!j\u00c9\x05k\xc7^-c\x10\x00\x00\u07d4\xec\u0466(\x025\x1aAV\x8d#\x030\x04\xac\xc6\xc0\x05\xa5\u04c9\x02\xb5\xe3\xaf\x16\xb1\x88\x00\x00\u07d4\xec\xd2v\xafd\u01dd\x1b\u0669+\x86\xb5\u835a\x95\xeb\x88\xf8\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xec\u0506\xfc\x19g\x91\xb9,\xf6\x12\xd3HaO\x91VH\x8b~\x8a\x02\x8a\x85t%Fo\x80\x00\x00\u07d4\xec\xda\xf92)\xb4^\xe6r\xf6]\xb5\x06\xfb^\xca\x00\xf7\xfc\xe6\x89W\x01\xf9m\xcc@\xee\x80\x00\u07d4\xec\xe1\x11g\vV<\u037e\xbc\xa5#\x84)\x0e\xcdh\xfe\\\x92\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xec\xe1\x15&\x82\xb7Y\x8f\xe2\xd1\xe2\x1e\xc1U3\x88T5\xac\x85\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xec\xe1)\bw\xb5\x83\xe3a\xa2\xd4\x1b\x00\x93F\xe6'N%8\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xec\xf0]\a\xea\x02n~\xbfIA\x00#5\xba\xf2\xfe\xd0\xf0\x02\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xec\xf2L\xdd|\"\x92\x8cD\x1eiM\xe4\xaa1\xb0\xfa\xb5\x97x\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xec\xfd\x00M\x02\xf3l\xd4\u0634\xa8\xc1\xa9S;j\xf8\\\xd7\x16\x8a\x01\x0fA\xac\xb4\xbb;\x9c\x00\x00\xe0\x94\xed\x02\x06\xcb#1Q(\xf8\xca\xff&\xf6\xa3\v\x98Tg\xd0\"\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xed\x10e\xdb\u03dds\xc0O\xfcy\b\x87\r\x88\x14h\xc1\xe12\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xed\x12vQ;o\u0186(\xa7A\x85\xc2\xe2\f\xbb\xcax\x17\xbf\x89\nZ\xa8P\t\xe3\x9c\x00\x00\xe0\x94\xed\x12\xa1\xba\x1f\xb8\xad\xfc\xb2\r\xfa\x19X.RZ\xa3\xb7E$\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\xed\x16\xce9\xfe\xef;\xd7\xf5\xd1b\x04^\x0fg\xc0\xf0\x00F\xbb\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xed\x1a\\C\xc5t\xd4\xe94)\x9b$\xf1G,\u071f\xd6\xf0\x10\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xed\x1b$\xb6\x91-Q\xb34\xac\r\xe6\xe7q\xc7\xc0EF\x95\xea\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xed\x1f\x1e\x11Z\r`\xce\x02\xfb%\xdf\x01M(\x9e:\f\xbe}\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xed10\\1\x9f\x92s\u04d3m\x8f[/q\u9c72)c\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xed2z\x14\xd5\u03ed\u0641\x03\xfc\t\x99q\x8d~\xd7\x05(\xea\x89N\x10\x03\xb2\x8d\x92\x80\x00\x00\u07d4\xed<\xbc7\x82\u03bdg\x98\x9b0\\A3\xb2\xcd\xe3\"\x11\xeb\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xed@\x14S\x8c\xeefJ/\xbc\xb6\xdcf\x9fz\xb1m\v\xa5|\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xedA\u188f\\\xaa\x848\x80\xefN\x8b\b\xbdl3\x14\x1e\u07c9*\xd5\xdd\xfaz\x8d\x83\x00\x00\xe0\x94\xedK\xe0J\x05-z\u0333\xdc\u03901\x9d\xba@ \xab,h\x8a\a\xf3zp\xea\xf3b\x17\x80\x00\xe0\x94\xedR\xa2\xcc\bi\u071e\x9f\x84+\u0415|G\xa8\xe9\xb0\xc9\xff\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\xed[LA\xe7b\xd9B@Cs\xca\xf2\x1e\xd4a]%\xe6\xc1\x89m-O=\x95%\xb4\x00\x00\u07d4\xed`\u012bnT\x02\x061~5\x94zc\xa9\xcak\x03\xe2\u02c9\x03\x1a\u066d\vF\u007f\x80\x00\u07d4\xedd\x1e\x066\x8f\xb0\xef\xaa\x17\x03\xe0\x1f\xe4\x8fJhS\t\xeb\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xedfC\xc0\xe8\x88K-2\x11\x857\x85\xa0\x8b\xf8\xf3>\u049f\x89Hz\x9a0E9D\x00\x00\xe0\x94\xedp\xa3|\xdd\x1c\xbd\xa9tm\x93\x96X\xae*a\x81(\x85x\x8a\x02\bj\xc3Q\x05&\x00\x00\x00\u07d4\xedsFvn\x1agm\r\x06\xec\x82\x18g\xa2v\xa0\x83\xbf1\x89\u064a\t1\xcc-I\x00\x00\u07d4\xed\x86&\x16\xfc\xbf\xb3\xbe\xcbt\x06\xf7<\\\xbf\xf0\f\x94\aU\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xed\x9e\x03\f\xa7\\\xb1\u049e\xa0\x1d\rL\xdf\xdc\xcd8D\xb6\xe4\x89\x01\xac\xc1\x16\u03ef\xb1\x80\x00\xe0\x94\ud7bc\u02e4/\x98\x15\xe7\x823&m\xd6\xe85\xb6\xaf\xc3\x1b\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\ud7f1\xf5\xaf/\xbf\u007f\xfcP)\xce\xe4+p\xff\\'[\xf5\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\u07d4\xed\xa4\xb2\xfaY\u0584\xb2z\x81\r\xf8\x97\x8as\xdf0\x8ac\u0089\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xed\xb4s59y\xa2\x06\x87\x9d\xe1D\xc1\n:\xcf\x12\xa7'OV9a\xf57R\x9d\x89\xc7\u0789lk\x93[\x8b\xbd@\x00\x00\u07d4\xeer\x88\xd9\x10\x86\xd9\xe2\xeb\x91\x00\x14\u066b\x90\xa0-x\u00a0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xee|=\xed|(\xf4Y\xc9/\xe1;M\x95\xba\xfb\xab\x026}\x89%\xf2s\x93=\xb5p\x00\x00\xe0\x94\xee\x86} \x91k\xd2\xe9\xc9\xec\xe0\x8a\xa0C\x85\xdbf|\x91.\x8a\n\x96\x81c\xf0\xa5{@\x00\x00\u07d4\ue25b\x02\xcb\xcb99\xcda\xde\x13B\xd5\x04\x82\xab\xb6\x852\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xee\x90m}_\x17H%\x81t\xbeL\xbc8\x93\x03\x02\xab{B\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\ue5ea\x8a\u019e\xdfz\x98}mp\x97\x9f\x8e\xc1\xfb\xcaz\x94\x89\x14b\fW\xdd\xda\xe0\x00\x00\u07d4\xee\xa1\xe9y\x88\xdeu\xd8!\xcd(\xadh\"\xb2,\u0398\x8b1\x89\x1c0s\x1c\xec\x03 \x00\x00\xe0\x94\xee\u048c?\x06\x8e\tJ0K\x85<\x95\nh\t\xeb\xcb\x03\xe0\x8a\x03\xa9\u057a\xa4\xab\xf1\xd0\x00\x00\u07d4\xee\u04c4\xef-A\xd9\xd2\x03\x97NW\xc1#(\xeav\x0e\b\xea\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xee\xdflB\x80\xe6\xeb\x05\xb94\xac\xe4(\xe1\x1dB1\xb5\x90[\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xee\xe7a\x84~3\xfda\u0653\x87\xee\x14b\x86\x94\u047f\xd5%\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xee\xe9\xd0Rn\xda\x01\xe41\x16\xa3\x952-\u0689pW\x8f9\x8a\x02\x1e\x19\x99\xbb\xd5\u04be\x00\x00\u07d4\xee\xf1\xbb\xb1\xe5\xa8?\u0782H\xf8\x8e\xe3\x01\x8a\xfa-\x132\xeb\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xee\xfb\xa1-\xfc\x99gB\xdby\x04d\xca}';\xe6\xe8\x1b>\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xee\xfd\x05\xb0\xe3\xc4\x17\xd5[3C\x06\x04\x86\xcd\xd5\xe9*\xa7\xa6\x89M\x85<\x8f\x89\b\x98\x00\x00\u07d4\xef\r\xc7\xddzS\xd6\x12r\x8b\xcb\u04b2|\x19\xddM}fo\x89&A\x1c[5\xf0Z\x00\x00\u07d4\xef\x11RR\xb1\xb8E\u0345\u007f\x00-c\x0f\x1bo\xa3zNP\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xef\x1c\x04w\xf1\x18M`\xac\u02b3t\xd3tUz\n>\x10\xf3\x89\b=lz\xabc`\x00\x00\u07d4\xef,4\xbbH}7b\xc3\u0327\x82\xcc\xddz\x8f\xbb\n\x991\x89\t\xc2\x00vQ\xb2P\x00\x00\u07d4\xef5\xf6\u0531\a^j\xa19\x15\x1c\x97K/FX\xf7\x058\x89<;\xc3?\x94\xe5\r\x80\x00\u07d4\xef9\u0291s\xdf\x15S\x1ds\xe6\xb7*hKQ\xba\x0f+\xb4\x89V\xa0\xb4un\xe28\x00\x00\u07d4\xefF<&y\xfb'\x91d\xe2\f=&\x915\x87s\xa0\xad\x95\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xefG\xcf\a>6\xf2q\xd5\"\xd7\xfaNq \xadP\a\xa0\xbc\x89\x87\x86x2n\xac\x90\x00\x00\u07d4\xefa\x15[\xa0\t\xdc\u07be\xf1\v(\xd9\xda=\x1b\xc6\xc9\xce\u0509\x034-`\xdf\xf1\x96\x00\x00\u0794\xefix\x1f2\xff\xce34o,\x9a\xe3\xf0\x84\x93\xf3\xe8/\x89\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xefv\xa4\u034f\xeb\xcb\u0278\x18\xf1x(\xf8\xd94s\xf3\xf3\u02c9\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\uf4c1\x8fhM\xb0\xc3g^\xc8\x132\xb3\x18>\xcc(\xa4\x95\x89T\x06\x923\xbf\u007fx\x00\x00\xe0\x94\xef\x9fY\xae\xdaA\x8c\x14\x94h-\x94\x1a\xabI$\xb5\xf4\x92\x9a\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\uf9b1\xf0\xdb`57\x82h\x91\xb8\xb4\xbc\x169\x84\xbb@\u03495e\x9e\xf9?\x0f\xc4\x00\x00\u07d4\xef\xbdR\xf9}\xa5\xfd:g:F\xcb\xf30D{~\x8a\xad\\\x89\x05l<\x9b\x80\xa0\xa6\x80\x00\xe0\x94\xef\xc8\xcf\x19c\u0269Rg\xb2(\xc0\x86#\x98\x89\xf4\xdf\xd4g\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xef\u02ae\x9f\xf6M,\xd9[RI\xdc\xff\xe7\xfa\xa0\xa0\xc0\xe4M\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\xef\xcc\xe0k\xd6\b\x9d\x0eE\x8e\xf5a\xf5\xa6\x89H\n\xfep\x00\x89 \x86\xac5\x10R`\x00\x00\u07d4\xef\xe0g]\xa9\x8a]\xdap\u0356\x19k\x87\xf4\xe7&\xb43H\x89?\x19\xbe\xb8\xdd\x1a\xb0\x00\x00\u07d4\xef\xe8\xff\x87\xfc&\x0e\agc\x8d\xd5\xd0/\xc4g.\x0e\xc0m\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xef\xeb\x19\x97\xaa\xd2w\xcc3C\x0ea\x11\xed\tCY@H\xb8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xef\xee\xa0\x10uo\x81\xdaK\xa2[r\x17\x87\xf0X\x17\v\uff49\x01\u009c\x9c\xf7p\xef\x00\x00\u07d4\xef\xf5\x1dr\xad\xfa\xe1C\xed\xf3\xa4+\x1a\xecU\xa2\xcc\xdd\v\x90\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xef\xf8kQ#\xbc\xdc\x17\xedL\xe8\xe0[~\x12\xe5\x13\x93\xa1\xf7\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xef\xfc\x15\u41f1\xbe\xda\n\x8d\x13%\xbd\xb4\x17\"@\xdcT\n\x89\x03\x8599\xee\xe1\xde\x00\x00\xe0\x94\xf0\x11\x95\xd6W\xef<\x94.l\xb89I\xe5\xa2\v\\\xfa\x8b\x1e\x8a\x05ts\xd0]\xab\xae\x80\x00\x00\u07d4\xf0'\x96)Q\x01gB\x88\xc1\xd94g\x05=\x04\"\x19\xb7\x94\x89(\x1d\x90\x1fO\xdd\x10\x00\x00\u07d4\xf09h={=\"[\xc7\xd8\u07ed\xefc\x164A\xbeA\xe2\x89\x01\xdd\x1eK\xd8\xd1\xee\x00\x00\u07d4\xf0Jj7\x97\b\xb9B\x8dr*\xa2\xb0kw\xe8\x895\u03c9\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xf0M,\x91\xef\xb6\xe9\xc4_\xfb\xe7KCL\x8c_+\x02\x8f\x1f\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf0W\xaaf\xcav~\xde\x12J\x1c[\x9c\xc5\xfc\x94\xef\v\x017\x89p\xa2K\u02b6\xf4]\x00\x00\u07d4\xf0[\xa8\u05f6\x859\xd930\v\xc9(\x9c=\x94t\xd0A\x9e\x89\x06\xda'\x02M\xd9`\x00\x00\u07d4\xf0\\\xee\xabeA\x05dp\x99Qw<\x84E\xad\x9fN\u01d7\x89\x10C\x16'\xa0\x93;\x00\x00\xe0\x94\xf0_\xcdL\rs\xaa\x16~US\xc8\xc0\xd6\xd4\xf2\xfa\xa3\x97W\x8a\x02\xd2\xd6l1p\xb2\x98\x00\x00\u07d4\xf0g\xe1\xf1\u0583UjL\xc4\xfd\f\x03\x13#\x9f2\xc4\xcf\u060965\u026d\xc5\u07a0\x00\x00\u07d4\xf0g\xfb\x10\u07f2\x93\u962b\xe5d\xc0U\xe34\x8f\x9f\xbf\x1e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf0h\xdf\xe9]\x15\xcd:\u007f\x98\xff\xa6\x88\xb44hB\xbe&\x90\x89D\n\xd8\x19\xe0\x97L\x00\x00\xe0\x94\xf0j\x85J<]\xc3m\x1cI\xf4\xc8}m\xb33\xb5~J\u074a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xf0y\xe1\xb1&_P\xe8\u0229\x8e\xc0\u01c1^\xb3\xae\xac\x9e\xb4\x89\x01\x16\xdc:\x89\x94\xb3\x00\x00\xe0\x94\xf0{\xd0\xe5\xc2\xcei\xc7\u0127$\xbd&\xbb\xfa\x9d*\x17\xca\x03\x8a\x01@a\xb9\xd7z^\x98\x00\x00\xe0\x94\xf0\x83*k\xb2U\x03\xee\xcaC[\xe3\x1b\v\xf9\x05\xca\x1f\xcfW\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\xf0\x9b>\x87\xf9\x13\xdd\xfdW\xae\x80I\xc71\u06e9\xb66\xdf\u00c9 \xf5\xb1\uab4d\x80\x00\x00\u07d4\xf0\xb14\v\x99oo\v\xf0\xd9V\x1c\x84\x9c\xaf\u007fD0\xbe\xfa\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf0\xb1\xf9\xe2x2\xc6\xdei\x14\xd7\n\xfc#\x8ct\x99\x95\xac\xe4\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xf0\xb4i\xea\xe8\x9d@\f\xe7\xd5\xd6j\x96\x95\x03p6\xb8\x89\x03\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xf0\xb9\u0583\u03a1+\xa6\x00\xba\xac\xe2\x19\xb0\xb3\xc9~\x8c\x00\xe4\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf0\xbe\x0f\xafMy#\xfcDF\"\u0458\f\xf2\u0650\xaa\xb3\a\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf0\xc0\x81\xdaR\xa9\xae6d*\xdf^\b _\x05\xc5Ah\xa6\x89\x06\x04o7\xe5\x94\\\x00\x00\u07d4\xf0\xc7\r\rm\xabvc\xaa\x9e\xd9\xce\xeaV~\xe2\u01b0'e\x89qC\x8a\u0167\x91\xa0\x80\x00\u07d4\xf0\xcb\xef\x84\xe1ic\x00\x98\xd4\xe3\x01\xb2\x02\b\xef\x05\x84j\u0249\x0e\v\x83EPkN\x00\x00\u07d4\xf0\xd2\x16c\u0630\x17n\x05\xfd\xe1\xb9\x0e\xf3\x1f\x850\xfd\xa9_\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\xf0\xd5\xc3\x1c\xcbl\xbe0\xc7\xc9\xea\x19\xf2h\xd1Y\x85\x1f\x8c\x9c\x8a\x03\x89O\x0eo\x9b\x9fp\x00\x00\u07d4\xf0\xd6L\xf9\xdf\tt\x113\xd1pH_\xd2K\x00P\x11\xd5 \x89\x1b\b\x93A\xe1O\xcc\x00\x00\u07d4\xf0\xd8X\x10^\x1bd\x81\x01\xac?\x85\xa0\xf8\"+\xf4\xf8\x1dj\x89 \x86\xac5\x10R`\x00\x00\u07d4\xf0\xdcC\xf2\x05a\x91'P{+\x1c\x1c\xfd\xf3-(1\t \x89\x10^\xb7\x9b\x94\x17\b\x80\x00\u07d4\xf0\xe1\u07e4*\u07ac/\x17\xf6\xfd\xf5\x84\xc9Hb\xfdV3\x93\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf0\xe2d\x9c~j?,]\xfe3\xbb\xfb\xd9'\xca<5\nX\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf0\xe7\xfb\x9eB\nS@\xd56\xf4\x04\b4O\xea\xef\xc0j\xef\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf1\x04b\xe5\x8f\xcc\a\U000d5121\x87c\x94Q\x16~\x85\x92\x01\x89\t4\xdd]3\xbc\x97\x00\x00\xe0\x94\xf1\x06a\xff\x94\x14\x0f >zH%rCy8\xbe\xc9\xc3\xf7\x8a\x04<3\xc1\x93ud\x80\x00\x00\u0794\xf1\x14\xff\r\x0f$\xef\xf8\x96\xed\xdeTq\u07a4\x84\x82J\x99\xb3\x88\xbe -j\x0e\xda\x00\x00\u07d4\xf1\x16\xb0\xb4h\x0fS\xabr\xc9h\xba\x80.\x10\xaa\x1b\xe1\x1d\u0209\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xf1\x1c\xf5\xd3cto\xeehd\xd3\xca3m\xd8\x06y\xbb\x87\xae\x8a\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xf1\x1e\x01\u01e9\xd1$\x99\x00_M\xaew\x16\tZ4\x17bw\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xf1;\b0\x93\xbaVN-\xc61V\x8c\xf7T\r\x9a\x0e\xc7\x19\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xf1O\x0e\xb8m\xb0\xebhu?\x16\x91\x8e]K\x80t7\xbd>\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf1Qx\xff\xc4:\xa8\a\x0e\xce2~\x93\x0f\x80\x9a\xb1\xa5O\x9d\x89\n\xb6@9\x12\x010\x00\x00\u07d4\xf1V\xdc\v*\x98\x1e[U\xd3\xf2\xf0;\x814\xe31\u06ed\xb7\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf1]\x9dZ!\xb1\x92\x9ey\x03q\xa1\u007f\x16\xd9_\fie\\\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf1^\x18,O\xbb\xady\xbd\x934\"B\xd4\xdc\xcf+\xe5\x89%\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xf1bM\x98\ve3o\xea\u0166\xd5A%\x00\\\xfc\xf2\xaa\u02c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xf1g\xf5\x86\x8d\xcfB3\xa7\x83\x06\th,\xaf-\xf4\xb1\xb8\a\x89\x81\xe5B\xe1\xa78?\x00\x00\u07d4\xf1m\xe1\x89\x1d\x81\x96F\x13\x95\xf9\xb16&[;\x95F\xf6\xef\x89\x01\xb2\x8e\x1f\x98\xbb\u0380\x00\u07d4\xf1z\x92\xe06\x1d\xba\xce\xcd\xc5\xde\r\x18\x94\x95Z\xf6\xa9\xb6\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf1z\xdbt\x0fE\u02fd\xe3\tN~\x13qo\x81\x03\xf5c\xbd\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf1\x8b\x14\xcb\xf6iC6\xd0\xfe\x12\xac\x1f%\xdf-\xa0\xc0]\xbb\x89\xd8\xd4`,&\xbfl\x00\x00\u07d4\xf1\x9b98\x9dG\xb1\x1b\x8a,?\x1d\xa9\x12M\xec\xff\xbe\xfa\xf7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf1\x9f\x195\b9>M*\x12{ \xb2\x03\x1f9\xc8%\x81\u0189\xbd\xbdz\x83\xbd/l\x00\x00\u07d4\xf1\xa1\xf3 @yd\xfd<\x8f.,\u0224X\r\xa9O\x01\xea\x89ll!wU|D\x00\x00\u07d4\xf1\xb4\xec\xc65%\xf7C,=\x83O\xfe+\x97\x0f\xbe\xb8r\x12\x89\xa2\xa2@h\xfa\u0340\x00\x00\u07d4\U000753ef\xfa\x87\x94\xf5\n\xf8\xe8\x83\t\u01e6&TU\xd5\x1a\x8963\x03\"\xd5#\x8c\x00\x00\u07d4\xf1\xc8\u0129A\xb4b\x8c\rl0\xfd\xa5dR\u065c~\x1bd\x89N\x8c\xea\x1e\xdeu\x04\x00\x00\u07d4\xf1\xda@so\x99\xd5\xdf;\x06\x8a]t_\xaf\xc6F?\u0271\x89\x06\x96\xca#\x05\x8d\xa1\x00\x00\u07d4\xf1\u070a\xc8\x10B\xc6z\x9c\\c2!\xa8\xf76>e\x87\f\x9f(t$\u04a9`\x89J\xcfX\xe0rW\x10\x00\x00\u07d4\xf2B\u0684]B\u053fw\x9a\x00\xf2\x95\xb4\aP\xfeI\xea\x13\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf2RY\xa5\xc99\xcd%\x96l\x9bc\x03\xd3s\x1cS\u077cL\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf2^Lp\xbcFV2\u021eV%\xa82\xa7r/k\xff\xab\x89\xf3K\x82\xfd\x8e\x91 \x00\x00\u07d4\xf2k\xce\xdc\xe3\xfe\xad\u03a3\xbc>\x96\xeb\x10@\xdf\xd8\xff\u1809*\x03I\x19\u07ff\xbc\x00\x00\u07d4\xf2py%v\xf0]QD\x93\xff\xd1\xf5\xe8K\xecK-\xf8\x10\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf2s,\xf2\xc1;\x8b\xb8\xe7I*\x98\x8f_\x89\xe3\x82s\xdd\u0209 \x86\xac5\x10R`\x00\x00\xe0\x94\xf2t.hY\xc5i\xd5\xf2\x10\x83Q\xe0\xbfM\xca5*H\xa8\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xf2\x81:d\xc5&]\x02\x025\u02dc1\x9bl\x96\xf9\x06\xc4\x1e\x89\x12\xf99\u025e\u06b8\x00\x00\u07d4\xf2\x87\xffR\xf4a\x11z\xdb>\x1d\xaaq\x93-\x14\x93\xc6_.\x89\xc5S%\xcat\x15\xe0\x00\x00\u07d4\xf2\xab\x11au\x02D\xd0\xec\xd0H\xee\r>Q\xab\xb1C\xa2\xfd\x89B\xfe+\x90ss\xbc\x00\x00\u07d4\xf2\xb4\xab,\x94'\xa9\x01^\xf6\xee\xff\xf5\xed\xb6\x019\xb7\x19\u0449&\u06d9*;\x18\x00\x00\x00\u07d4\xf2\xc0>*8\x99\x8c!d\x87`\xf1\xe5\xae~\xa3\a}\x85\"\x89\x8f?q\x93\xab\a\x9c\x00\x00\u0794\xf2\u0090N\x9f\xa6d\xa1\x1e\xe2VV\xd8\xfd,\xc0\u0665\"\xa0\x88\xb9\x8b\xc8)\xa6\xf9\x00\x00\u07d4\xf2\xc3b\xb0\xef\x99\x1b\xc8/\xb3nf\xffu\x93*\xe8\u0742%\x89\x04\x02\xf4\xcf\xeeb\xe8\x00\x00\u07d4\xf2\xd0\xe9\x86\xd8\x14\xea\x13\xc8\xf4f\xa0S\x8cS\u0712&Q\xf0\x89J\xcfX\xe0rW\x10\x00\x00\xe0\x94\xf2\u04775w$\xecL\x03\x18[\x87\x9bc\xf5~&X\x91S\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xf2\xd5v<\xe0s\x12~,\xed\xdeo\xab\xa7\x86\xc7<\xa9AA\x8a\x01\xacB\x86\x10\x01\x91\xf0\x00\x00\xe0\x94\xf2\u055c\x89#u\x90s\xd6\xf4\x15\xaa\xf8\xeb\x06_\xf2\U000f614a\x01\xab,\xf7\xc9\xf8~ \x00\x00\u07d4\xf2\xe9\x9f\\\xbb\x83kz\xd3bGW\x1a0,\xbeKH\x1ci\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf2\xed>w%J\u02c3#\x1d\xc0\x86\x0e\x1a\x11$+\xa6'\u06c9kV\x05\x15\x82\xa9p\x00\x00\xe0\x94\xf2\xed\xde7\xf9\xa8\u00dd\u07a2My\xf4\x01WW\xd0k\xf7\x86\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xf2\xef\xe9e`\xc9\xd9{r\xbd6DxC\x88\\\x1d\x90\xc21\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf2\xfb\xb6\u0607\xf8\xb8\xcc:\x86\x9a\xba\x84\u007f=\x1fd\xfcc\x97\xaae\xfbS\xa8\xf0z\x0f\x89:\xae0\xe8\xbc\xee\x89|\xf28\x1fa\x9f\x15\x00\x00\u07d4\xf3@\x83\xec\xea8P\x17\xaa@\xbd\xd3^\xf7\xef\xfbL\xe7v-\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xf3F\xd7\u0792t\x1c\b\xfcX\xa6M\xb5[\x06-\xde\x01-\x14\x89\x0f\xffk\x1fv\x1em\x00\x00\xe0\x94\xf3U\xd3\xec\f\xfb\x90}\x8d\xbb\x1b\xf3FNE\x81(\x19\v\xac\x8a\x01\v\x04n\u007f\r\x80\x10\x00\x00\u07d4\xf3m\xf0/\xbd\x89`sG\xaf\xce)i\xb9\xc4#jX\xa5\x06\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf3s\xe9\u06ac\f\x86u\xf5;yz\x16\x0fo\xc04\xaek#\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf3{BeG\xa1d-\x8032H\x14\xf0\xed\xe3\x11O\xc2\x12\x89\x15\xbeat\xe1\x91.\x00\x00\u07d4\xf3{\xf7\x8cXu\x15G\x11\xcbd\r7\xeam(\xcf\xcb\x12Y\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xf3\x82\xdfX1U\xd8T\x8f?\x93D\f\xd5\xf6\x8c\xb7\x9d`&\x8a8u}\x02\u007f\xc1\xfd\\\x00\x00\xe0\x94\xf3\x82\xe4\xc2\x04\x10\xb9Q\b\x9e\x19\xba\x96\xa2\xfe\xe3\xd9\x1c\xce~\x8a\x01\x11\xfaV\xee\u00a88\x00\x00\xe0\x94\xf3\x8al\xa8\x01hS~\x97M\x14\xe1\xc3\xd19\x90\xa4L,\x1b\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\u07d4\xf3\x9a\x9dz\xa3X\x1d\xf0~\xe4'\x9a\xe6\xc3\x12\xef!\x036X\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf3\xb6h\xb3\xf1M\x92\x0e\xbc7\x90\x92\u06d8\x03\x1bg\xb2\x19\xb3\x89\n\xd6\xee\xdd\x17\xcf;\x80\x00\u07d4\U000fe679\x10<\xe7U\n\xa7O\xf1\xdb\x18\xe0\x9d\xfe2\xe0\x05\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf3\xc1\xab\u049d\xc5{A\xdc\x19-\x0e8M\x02\x1d\xf0\xb4\xf6\u0509\x97\xae\f\u07cf\x86\xf8\x00\x00\u07d4\xf3\xc4qm\x1e\xe5'\x9a\x86\xd0\x16:\x14a\x81\x81\xe1a6\u01c965\u026d\xc5\u07a0\x00\x00\xe0\x94\xf3\u030b\xcbU\x94e\xf8\x1b\xfeX;\u05eb\n#\x06E;\x9e\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xf3\u0588\xf0k\xbd\xbfP\xf9\x93,AE\xcb\xe4\x8e\xcd\xf6\x89\x04\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf3\xdb\xcf\x13Z\u02dd\xee\x1aH\x9cY<\x02O\x03\u00bb\xae\u0389lk\x93[\x8b\xbd@\x00\x00\u07d4\xf3\xde_&\xefj\xde\xd6\xf0m;\x91\x13F\xeep@\x1d\xa4\xa0\x89\x13:\xb3}\x9f\x9d\x03\x00\x00\u07d4\xf3\xdfc\xa9q\x99\x93308;>\xd7W\v\x96\u0101#4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf3\xe7OG\f}:?\x003x\x0fv\xa8\x9f>\xf6\x91\xe6\u02c9\xa3\xcf\xe61\xd1Cd\x00\x00\u07d4\xf3\xeb\x19H\xb9Q\xe2-\xf1ax)\xbf;\x8d\x86\x80\xeckh\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf3\xf1\xfa9\x18\xca4\xe2\xcf~\x84g\v\x1fM\x8e\xca\x16\r\xb3\x89$\xdc\xe5M4\xa1\xa0\x00\x00\u07d4\xf3\xf2O\u009e @?\xc0\xe8\xf5\xeb\xbbU4&\xf7\x82p\xa2\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf3\xfar5R\xa5\xd0Q.+b\xf4\x8d\xca{+\x81\x050[\x89\amA\xc6$\x94\x84\x00\x00\u07d4\xf3\xfeQ\xfd\xe3D\x13\xc73\x18\xb9\xc8T7\xfe~\x82\x0fV\x1a\x896b2\\\u044f\xe0\x00\x00\u07d4\xf4\x00\xf9=_\\~?\xc3\x03\x12\x9a\xc8\xfb\f/xd\a\xfa\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf4\v\x13O\xea\"\u01b2\x9c\x84W\xf4\x9f\x00\x0f\x9c\xdax\x9a\u06c9 \x86\xac5\x10R`\x00\x00\u07d4\xf4\x15W\xdf\u07f1\xa1\xbd\xce\xfe\xfe.\xba\x1e!\xfe\nJ\x99B\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf4\x17z\r\x85\u050b\x0e&B\x11\xce*\xa2\xef\xd3\xf1\xb4\u007f\b\x89\xc2\xcc\xca&\xb7\xe8\x0e\x80\x00\u07d4\xf4/\x90R1\xc7p\xf0\xa4\x06\xf2\xb7h\x87\u007f\xb4\x9e\xee\x0f!\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xf42\xb9\u06ef\x11\xbd\xbds\xb6Q\x9f\xc0\xa9\x04\x19\x87q\xaa\u0189\b=lz\xabc`\x00\x00\u07d4\xf4=\xa3\xa4\xe3\xf5\xfa\xb1\x04\u029b\xc1\xa0\xf7\xf3\xbbJV\xf3Q\x89lj\xccg\u05f1\xd4\x00\x00\xe0\x94\xf4G\x10\x8b\x98\xdfd\xb5~\x87\x103\x88\\\x1a\xd7\x1d\xb1\xa3\xf9\x8a\x01v\xf4\x9e\xad4\x83P\x80\x00\u07d4\xf4O\x85Q\xac\xe93r\a\x12\xc5\u0111\u0376\xf2\xf9Qsl\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u0794\xf4V\x05Z\x11\xab\x91\xfff\x8e.\xc9\"\x96\x1f*#\xe3\xdb%\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xf4V\xa7[\xb9\x96U\xa7A,\xe9}\xa0\x81\x81m\xfd\xb2\xb1\xf2\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf4[\x1d\xcb.A\xdc'\xff\xa0$\u06ad\xf6\x19\xc1\x11u\xc0\x87\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xf4c\xa9\f\xb3\xf1>\x1f\x06CB66\xbe\xab\x84\xc1#\xb0m\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xf4h\x90n~\xdffJ\xb0\u063e=\x83\xebz\xb3\xf7\xff\xdcx\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xf4i\x80\u3929\u049ajn\x90`E7\xa3\x11K\xcb(\x97\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf4kk\x9c|\xb5R\x82\x9c\x1d=\xfd\x8f\xfb\x11\xaa\xba\xe7\x82\xf6\x89\x01#n\xfc\xbc\xbb4\x00\x00\u07d4\xf4v\xe1&\u007f\x86$|\xc9\b\x81o.z\xd58\x8c\x95-\xb0\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf4v\xf2\xcbr\b\xa3.\x05\x1f\xd9N\xa8f)\x92c\x82\x87\xa2\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xf4{\xb14\xda0\xa8\x12\xd0\x03\xaf\x8d\u0338\x88\xf4K\xbfW$\x8a\x01\x19Y\xb7\xfe3\x95X\x00\x00\u07d4\xf4\x83\xf6\a\xa2\x1f\xcc(\x10\n\x01\x8cV\x8f\xfb\xe1@8\x04\x10\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf4\x8e\x1f\x13\xf6\xafM\x84\xb3q\xd7\xdeK'=\x03\xa2c'\x8e\x89 \x86\xac5\x10R`\x00\x00\xe0\x94\xf4\x9cG\xb3\xef\xd8knj[\xc9A\x8d\x1f\x9f\xec\x81Ki\xef\x8a\x04<3\xc1\x93ud\x80\x00\x00\xe0\x94\xf4\x9fo\x9b\xaa\xbc\x01\x8c\x8f\x8e\x11\x9e\x01\x15\xf4\x91\xfc\x92\xa8\xa4\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xf4\xa3g\xb1f\u0499\x1a+\xfd\xa9\xf5dc\xa0\x9f%,\x1b\x1d\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf4\xa5\x1f\xceJ\x1d[\x94\xb0q\x83\x89\xbaNx\x14\x13\x9c\xa78\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xf4\xa9\xd0\f\xef\xa9{zX\xef\x94\x17\xfcbg\xa5\x06\x909\xee\x89\x01.\x89(\u007f\xa7\x84\x00\x00\u07d4\xf4\xaa\xa3\xa6\x16>7\x06W{I\xc0v~\x94\x8ah\x1e\x16\xee\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf4\xb1bn$\xf3\v\xca\xd9'!\xb2\x93r\x89U\xa6\xe7\x9c\xcd\x1d0\x00\x00\u07d4\xf5U\xa2{\xb1\xe2\xfdN,\u01c4\xca\ue493\x9f\xc0n/\u0249lk\x93[\x8b\xbd@\x00\x00\u07d4\xf5X\xa2\xb2\xdd&\u0755\x93\xaa\xe0E1\xfd<<\u00c5Kg\x89\n\xbb\xcdN\xf3wX\x00\x00\u07d4\xf5`H\xdd!\x81\u0523od\xfc\xec\xc6!T\x81\xe4*\xbc\x15\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf5dB\xf6\x0e!i\x13\x95\u043f\xfa\xa9\x19M\xca\xff\x12\u2dc9\x0e\x189\x8ev\x01\x90\x00\x00\u07d4\xf5yqJE\xeb\x8fR\xc3\xd5{\xbd\xef\xd2\xc1[./\x11\u07c9T\x91YV\xc4\t`\x00\x00\u07d4\xf5\x93\xc6R\x85\xeek\xbdf7\U000fe3c9\xad@\u0509\xf6U\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xf5\x98\xdb.\t\xa8\xa5\xee}r\r+\\C\xbb\x12m\x11\xec\u0089\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xf5\x9d\xab\x1b\xf8\xdf\x112~a\xf9\xb7\xa1KV:\x96\xec5T\x8a\x01EB\xba\x12\xa37\xc0\x00\x00\xe0\x94\xf5\x9f\x9f\x02\xbb\u024e\xfe\t~\xab\xb7\x82\x10\x97\x90!\x89\x8b\xfd\x8a\x02\x1e\x17\x1a>\xc9\xf7,\x00\x00\u07d4\xf5\xa5E\x9f\xcd\xd5\xe5\xb2s\x83\r\xf8\x8e\xeaL\xb7}\xda\u07f9\x89\x04\t\xe5+H6\x9a\x00\x00\u07d4\xf5\xa7gj\xd1H\xae\x9c\x1e\xf8\xb6\xf5\xe5\xa0\xc2\xc4s\xbe\x85\v\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf5\xb0h\x98\x9d\xf2\x9c%5w\xd0@Z\xden\x0eu(\xf8\x9e\x89WG=\x05\u06ba\xe8\x00\x00\u07d4\xf5\xb6\xe9\x06\x1aN\xb0\x96\x16\aw\xe2gb\xcfH\xbd\u0635]\x89\r\xc5_\xdb\x17d{\x00\x00\u07d4\xf5\xcf\xfb\xbabN~\xb3!\xbc\x83\xc6\f\xa6\x81\x99\xb4\xe3fq\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf5\xd1ER\xb1\xdc\xe0\xd6\xdc\x1f2\r\xa6\xff\u02231\xcdo\f\x89Hz\x9a0E9D\x00\x00\xe0\x94\xf5\xd6\x1a\xc4\u0295G^[{\xff\xd5\xf2\xf6\x90\xb3\x16u\x96\x15\x8a\x06\x92\xae\x88\x97\b\x1d\x00\x00\x00\u07d4\xf5\xd9\xcf\x00\xd6X\xddEQzH\xa9\xd3\xf5\xf63T\x1aS=\x89\x06O_\xdfIOx\x00\x00\u07d4\xf5\xea\xdc\xd2\u0478ez\x12\x1f3\xc4X\xa8\xb1>v\xb6U&\x89\r\x8b\x0fZZ\xc2J\x00\x00\u07d4\xf6\a\xc2\x15\r>\x1b\x99\xf2O\xa1\xc7\xd5@\xad\xd3\\N\xbe\x1e\x89\xa7\xf1\xaa\a\xfc\x8f\xaa\x00\x00\u07d4\xf6\v\xd75T>k\xfd.\xa6\xf1\x1b\xffbs@\xbc\x03Z#\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf6\f\x1bE\xf1d\xb9X\x0e 'Z\\9\xe1\xd7\x1e5\xf8\x91\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xf6\x0fb\xd797\x95?\xef5\x16\x9e\x11\xd8r\xd2\xea1~\xec\x8a\x01!\xeah\xc1\x14\xe5\x10\x00\x00\u07d4\xf6\x12\x83\xb4\xbd\x85\x04\x05\x8c\xa3`\u94d9\x9bb\xcb\xc8\xcdg\x89\r\xd2\xd5\xfc\xf3\xbc\x9c\x00\x00\u07d4\xf6\x17\xb9g\xb9\xbdH_v\x95\xd2\xefQ\xfbw\x92\u0618\xf5\x00\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf6\x18\u0671\x04A\x14\x80\xa8c\xe6#\xfcU#-\x1aOH\xaa\x89\x0eh\x9emD\xb1f\x80\x00\u07d4\xf6\"\u5126b>\xaa\xf9\x9f+\xe4\x9eS\x80\xc5\xcb\xcf\\\u0609\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf62\xad\xffI\r\xa4\xb7-\x126\xd0KQ\x0ft\xd2\xfa\xa3\u0349K\xe4\xe7&{j\xe0\x00\x00\u07d4\xf69\xac1\u069fg'\x1b\xd1\x04\x02\xb7eN\\\xe7c\xbdG\x89\x15\xaf\x0fB\xba\xf9&\x00\x00\u07d4\xf6:W\x9b\xc3\xea\u00a9I\x04\x10\x12\x8d\xbc\xeb\xe6\xd9\u0782C\x89P\xc5\xe7a\xa4D\b\x00\x00\u07d4\xf6E\xdd|\x89\x00\x93\xe8\xe4\u022a\x92\xa6\xbb55\"\xd3\u0718\x89\aC\x9f\xa2\t\x9eX\x00\x00\xe0\x94\xf6H\xea\x89\xc2u%q\x01r\x94Ny\xed\xff\x84x\x03\xb7u\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xf6JJ\xc8\xd5@\xa9(\x9ch\xd9`\xd5\xfb|\xc4Zw\x83\x1c\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf6N\xcf!\x17\x93\x1cmSZ1\x1eO\xfe\xae\xf9\u0514\x05\xb8\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\xf6O\xe0\x93\x9a\x8d\x1e\xea*\x0e\u035a\x970\xfdyX\xe31\t\x89\x01\x1d\xe1\xe6\xdbE\f\x00\x00\u07d4\xf6V\x16\xbe\x9c\x8by~t\x15\"|\x918\xfa\xa0\x89\x17B\u05c9*\xd3s\xcef\x8e\x98\x00\x00\u07d4\xf6W\xfc\xbeh.\xb4\xe8\xdb\x15.\u03c9$V\x00\vQ=\x15\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xf6X\x19\xacL\xc1L\x13\u007f\x05\xddyw\xc7\xda\xe0\x8d\x1aJ\xb5\x89\x05\x87\x88\u02d4\xb1\xd8\x00\x00\u07d4\xf6{\xb8\xe2\x11\x8b\xbc\u0550'fn\xed\xf6\x94>\xc9\xf8\x80\xa5\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf6\x84d\xbfd\xf2A\x13V\xe4\xd3%\x0e\xfe\xfe\\P\xa5\xf6[\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf6\x86x[\x89r\va\x14_\ua017\x8dj\u030e\v\xc1\x96\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf6\x8c^3\xfa\x97\x13\x9d\xf5\xb2\xe68\x86\xce4\xeb\xf3\u45dc\x89\xb3\xfaAi\xe2\xd8\xe0\x00\x00\u07d4\xf6\xa8cWW\xc5\xe8\xc14\xd2\r\x02\x8c\xf7x\u03c6\t\xe4j\x89O\x1dw/\xae\xc1|\x00\x00\u07d4\xf6\xb7\x82\xf4\xdc\xd7E\xa6\xc0\xe2\xe00`\x0e\x04\xa2K%\xe5B\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\xe0\x94\xf6\xbc7\xb1\u04a3x\x8dX\x9bm\xe2\x12\xdc\x17\x13\xb2\xf6\u738a\x01\x0f\f\xf0d\xddY \x00\x00\u07d4\xf6\xc3\u010a\x1a\xc0\xa3G\x99\xf0M\xb8n\u01e9u\xfewh\xf3\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf6\xd2]?=\x84m#\x9fR_\xa8\xca\xc9{\xc45x\u06ec\x890\x92\u007ft\xc9\xde\x00\x00\x00\u07d4\xf6\xea\xacp2\u0512\xef\x17\xfd`\x95\xaf\xc1\x1dcOV\xb3\x82\x89\x1b\x1bk\u05efd\xc7\x00\x00\xe0\x94\xf6\xea\xd6}\xbf[~\xb13X\xe1\x0f6\x18\x9dS\xe6C\xcf\u03ca\bxg\x83&\xea\xc9\x00\x00\x00\u07d4\xf6\xf1\xa4C\t\x05\x1ck%\xe4}\xff\x90\x9b\x17\x9b\xb9\xabY\x1c\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xf7\x03(\xef\x97b_\xe7E\xfa\xa4\x9e\xe0\xf9\u052a;\r\xfbi\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf7\n\x99\x8aq{3\x8d\x1d\u0658T@\x9b\x1a3\x8d\ue930\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf7\rcz\x84\\\x06\xdbl\u0711\xe67\x1c\xe7\xc48\x8ab\x8e\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf7\x15R\x13D\x98\x92tK\xc6\x0f.\x04@\a\x88\xbd\x04\x1f\u0749\x03\x9f\xba\xe8\xd0B\xdd\x00\x00\xe0\x94\xf7\x1bE4\xf2\x86\xe40\x93\xb1\xe1^\xfe\xa7I\xe7Y{\x8bW\x8a\x16\x1c\x13\xd34\x1c\x87(\x00\x00\u07d4\xf74\xec\x03rM\xde\xe5\xbbRy\xaa\x1a\xfc\xf6\x1b\f\xb4H\xa1\x89\xe5\xbf,\u0270\x97\x80\x00\x00\u07d4\xf76\u0716v\x00\x128\x8f\xe8\x8bf\xc0n\xfeW\xe0\xd7\xcf\n\x89q\xd7Z\xb9\xb9 P\x00\x00\u07d4\xf7:\xc4l ;\xe1S\x81\x11\xb1Q\xec\x82 \u01c6\xd8AD\x89\x0f\xf77x\x17\xb8+\x80\x00\u07d4\xf7=\xd9\xc1B\xb7\x1b\xce\x11\xd0n0\xe7\xe7\xd02\xf2\uc71e\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf7A\x8a\xa0\xe7\x13\xd2H\"\x87v\xb2\xe7CB\"\xaeu\u3949lk\x93[\x8b\xbd@\x00\x00\u07d4\xf7Nn\x14S\x82\xb4\u06c2\x1f\xe0\xf2\u0643\x88\xf4V\t\u019f\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xf7P\f\x16o\x8b\xea/\x824v\x06\xe5\x02K\xe9\xe4\xf4\u0399\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf7W\xfc\x87 \xd3\xc4\xfaRw\a^`\xbd\\A\x1a\xeb\xd9w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf7[\xb3\x9cy\x97y\xeb\xc0J3m&\r\xa61F\xed\x98\u0409\x01Z\xf1\u05cbX\xc4\x00\x00\xe0\x94\xf7h\xf3!\xfdd3\xd9kO5M<\xc1e,\x172\xf5\u007f\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xf7oi\xce\xe4\xfa\xa0\xa6;0\xae\x1ex\x81\xf4\xf7\x15ep\x10\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf7w6\x1a=\u062bb\xe5\xf1\xb9\xb0GV\x8c\xc0\xb5UpL\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf7|{\x84QI\xef\xba\x19\xe2a\xbc|u\x15y\b\xaf\xa9\x90\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf7\u007f\x95\x87\xffz-r\x95\xf1\xf5q\u0206\xbd3\x92jR|\x89lh\xcc\u041b\x02,\x00\x00\u07d4\xf7\x82X\xc1$\x81\xbc\xdd\u06f7*\x8c\xa0\xc0C\tra\xc6\u0149\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf7\x98\xd1m\xa4\xe4`\xc4`\xcdH_\xae\x0f\xa0Y\x97\b\ub08965\u026d\xc5\u07a0\x00\x00\u07d4\xf7\xa1\xad\xe2\xd0\xf5)\x12=\x10U\xf1\x9b\x17\x91\x9fV!Ng\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf7\xac\xff\x93K\x84\xda\ti\xdc7\xa8\xfc\xf6C\xb7\xd7\xfb\xedA\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xf7\xb1Q\xcc^W\x1c\x17\xc7e9\xdb\xe9\x96L\xbbo\xe5\xdey\x89tq|\xfbh\x83\x10\x00\x00\u07d4\xf7\xb2\x9b\x82\x19\\\x88-\xabx\x97\u00ae\x95\xe7w\x10\xf5xu\x89w5Aa2\xdb\xfc\x00\x00\u07d4\xf7\xbcLD\x91\rZ\xed\xd6n\xd25U8\xa6\xb1\x93\xc3a\xec\x89\x05A\xde,-\x8db\x00\x00\u07d4\xf7\xc0\f\xdb\x1f\x02\x03\x10\u056c\xab{Ij\xaaD\xb7y\b^\x89Z\x87\xe7\xd7\xf5\xf6X\x00\x00\u07d4\xf7\xc1\xb4C\x96\x8b\x11{]\u0677UW/\xcd9\xca^\xc0K\x89\x18\xb9h\u0092\xf1\xb5\x00\x00\xe0\x94\xf7\xc5\x0f\x92*\xd1ka\xc6\u047a\xa0E\xed\x81h\x15\xba\u010f\x8a\x02\xa99j\x97\x84\xad}\x00\x00\u07d4\xf7\xc7\b\x01Pq\xd4\xfb\n:*\t\xa4]\x15c\x96\xe34\x9e\x89\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xf7\xcb\u06e6\xbel\xfeh\xdb\xc2<+\x0f\xf50\xee\x05\"o\x84\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf7\xd0\xd3\x10\xac\xea\x18@a8\xba\xaa\xbb\xfe\x05q\xe8\r\xe8_\x89Hz\x9a0E9D\x00\x00\u07d4\xf7\u05ef LV\xf3\x1f\xd9C\x98\xe4\r\xf1\x96K\u063f\x12<\x89\b!\xd2!\xb5)\x1f\x80\x00\u07d4\xf7\xdc%\x11\x96\xfb\u02f7|\x94}|\x19F\xb0\xffe\x02\x1c\xea\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xf7\xe4Z\x12\xaaq\x1cp\x9a\xce\xfe\x95\xf3;xa-*\xd2*\x8a\x0e\x06U\xe2\xf2k\xc9\x18\x00\x00\u07d4\xf7\xf4\x89\x8cLRm\x95_!\xf0U\xcbnG\xb9\x15\xe5\x19d\x89|\b`\xe5\xa8\r\xc0\x00\x00\u07d4\xf7\xf9\x1ez\xcb[\x81)\xa3\x06\x87|\xe3\x16\x8eoC\x8bf\xa1\x89\t\x8a}\x9b\x83\x14\xc0\x00\x00\u07d4\xf7\xfcE\xab\xf7oP\x88\xe2\u5d68\xd12\xf2\x8aMN\xc1\xc0\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\x06:\xf4\xcc\x1d\xd9a\x9a\xb5\u063f\xf3\xfc\xd1\xfa\xa8H\x82!\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\bnBf\x1e\xa9)\xd2\u0761\xablt\x8c\xe3\x05]\x11\x1e\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xf8\bw\x86\xb4-\xa0N\xd6\xd1\xe0\xfe&\xf6\xc0\xee\xfe\x1e\x9fZ\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xf8\r6\x19p/\xa5\x83\x8cH9\x18Y\xa89\xfb\x9c\xe7\x16\x0f\x89l\a\xa7\u0471np\x00\x00\u07d4\xf8\x14y\x9fm\xdfM\xcb)\xc7\xee\x87\x0eu\xf9\xcc-52m\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xf8\x15\xc1\n\x03-\x13\xc3K\x89v\xfan;\xd2\xc9\x13\x1a\x8b\xa9\x89Hz\x9a0E9D\x00\x00\u07d4\xf8\x16\"\xe5WW\xda\xeafu\x97]\xd958\xda}\x16\x99\x1e\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8$\xee3\x1eJ\xc3\xccXv\x939[W\xec\xf6%\xa6\xc0\u0089V\xc9]\xe8\xe8\xca\x1d\x00\x00\u07d4\xf8'\xd5n\xd2\xd3' \u052b\xf1\x03\xd6\xd0\xefM;\xcdU\x9b\x89\x01l\x80\x06W\x91\xa2\x80\x00\u07d4\xf8)\x85\x91R>P\xb1\x03\xf0\xb7\x01\xd6#\xcb\xf0\xf7EV\xf6\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf8H\xfc\xe9\xaba\x1c}\x99 n#\xfa\u019a\u0508\xb9O\xe1\x89\x02\xa1\x12\x9d\t6r\x00\x00\u07d4\xf8O\t\n\xdf?\x8d\xb7\u1533P\xfb\xb7u\x00i\x9ff\xfd\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf8Q\xb0\x10\xf63\xc4\n\xf1\xa8\xf0js\ubeabe\az\xb5\x89\xee\x86D/\xcd\x06\xc0\x00\x00\u07d4\xf8X\x17\x1a\x04\xd3W\xa1;IA\xc1n~U\xdd\u0514\x13)\x89\x02F\xa5!\x8f*\x00\x00\x00\u07d4\xf8[\xab\x1c\xb3q\x0f\xc0_\xa1\x9f\xfa\xc2.gR\x1a\v\xa2\x1d\x89l\x955\u007f\xa6\xb3l\x00\x00\u07d4\xf8j>\xa8\a\x1fp\x95\xc7\u06ca\x05\xaePz\x89)\u06f8v\x89\x126\xef\xcb\u02f3@\x00\x00\u07d4\xf8pL\x16\xd2\xfd[\xa3\xa2\xc0\x1d\x0e\xb2\x04\x84\xe6\xec\xfa1\t\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf8p\x99_\xe1\xe5\"2\x1duC7\xa4\\\f\x9d{8\x95\x1c\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf8s\xe5ze\xc9;n\x18\xcbu\xf0\xdc\a}[\x893\xdc\\\x89\n\xad\xec\x98?\xcf\xf4\x00\x00\u07d4\xf8ua\x9d\x8a#\xe4]\x89\x98\u0444\u0500\xc0t\x89p\x82*\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf8{\xb0{(\x9d\xf70\x1eT\xc0\xef\xdaj,\xf2\x91\xe8\x92\x00\x89K\xe4\xe7&{j\xe0\x00\x00\u0794\xf8\x89\x00\xdbsyU\xb1Q\x9b\x1a}\x17\n\x18\x86L\xe5\x90\xeb\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xf8\x8bX\xdb7B\vFL\v\xe8\x8bE\xee+\x95)\x0f\x8c\xfa\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xf8\x96+u\xdb]$\xc7\xe8\xb7\xce\xf1\x06\x8c>g\u03bb0\xa5\x89\x0f-\xc7\xd4\u007f\x15`\x00\x00\u07d4\xf8\xa0e\xf2\x87\xd9\x1dw\xcdbj\xf3\x8f\xfa\"\r\x9bU*+\x89g\x8a\x93 b\xe4\x18\x00\x00\u07d4\xf8\xa4\x9c\xa29\f\x1fm\\\x0ebQ;\a\x95qt?|\u0189\xa2\xa1]\tQ\x9b\xe0\x00\x00\u07d4\xf8\xa5\f\xee.h\x8c\xee\u3b24\u0522\x97%\xd4\a,\u0103\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\xacJ9\xb5<\x110x \x97;D\x13e\xcf\xfeYof\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\xae\x85{g\xa4\xa2\x89:?\xbe|z\x87\xff\x1c\x01\u01a6\xe7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xf8\xbf\x9c\x04\x87NZw\xf3\x8fL8R~\x80\xc6v\xf7\xb8\x87\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\xc7\xf3J8\xb3\x18\x01\xdaC\x064w\xb1+'\xd0\xf2\x03\xff\x89\x1a\u04ba\xbao\xefH\x00\x00\u07d4\xf8\xca3l\x8e\x91\xbd \xe3\x14\xc2\v-\xd4`\x8b\x9c\x8b\x94Y\x89-\u071b\u0173,x\x00\x00\u07d4\xf8\xd1t$\xc7g\xbe\xa3\x12\x05s\x9a+W\xa7'r\x14\uef89\x02F\xdd\xf9yvh\x00\x00\u07d4\xf8\xd5-\xcc_\x96\xcc(\x00{>\u02f4\t\xf7\xe2*dl\xaa\x89\b\x16\x90\xe1\x81(H\x00\x00\u07d4\xf8\xdc\xe8g\xf0\xa3\x9c[\xef\x9e\xeb\xa6\t\"\x9e\xfa\x02g\x8bl\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf8\xf2&\x14*B\x844\xab\x17\xa1\x86J%\x97\xf6J\xab/\x06\x89\tY\x8b/\xb2\xe9\xf2\x80\x00\u07d4\xf8\xf6d^\r\xeedK=\xad\x81\xd5q\uf6ef\x84\x00!\xad\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf9\x01\xc0\x0f\xc1\u06c8\xb6\x9cK\xc3%+\\\xa7\x0e\xa6\xee\\\xf6\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xf9=[\xcb\x06D\xb0\xcc\xe5\xfc\u0763C\xf5\x16\x8f\xfa\xb2\x87}\x89\vb\a\xb6}&\xf9\x00\x00\u07d4\xf9W\x0e\x92L\x95\u07bbpa6\x97\x92\xcf.\xfe\u00a8-^\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xf9d \x86\xb1\xfb\xaea\xa6\x80M\xbe_\xb1^\xc2\u04b57\xf4\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf9d\x88i\x85\x90\xdc;,UVB\xb8q4\x8d\xfa\x06z\u0549\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf9d\u064d(\x170\xba5\xb2\xe3\xa3\x14yn{B\xfe\xdfg\x89S\xb0\x87`\x98\xd8\f\x00\x00\u07d4\xf9e\ri\x89\xf1\x99\xab\x1c\xc4ycm\xed0\xf2A\x02\x1fe\x89.\x14\x1e\xa0\x81\xca\b\x00\x00\xe0\x94\xf9h\x83X$Y\x90\x8c\x82v'\xe8o(\xe6F\xf9\xc7\xfcz\x8a\x01\u0127\x877\xcd\u03f8\x00\x00\u07d4\xf9kL\x00voSsj\x85t\xf8\"\xe6GL/!\xda-\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xf9r\x9dH(,\x9e\x87\x16m^\xef-\x01\xed\xa9\xdb\xf7\x88!\x89\x05k\x83\xdd\xc7(T\x80\x00\u07d4\xf9v~N\xcbJY\x80Ru\b\u05fe\xc3\xd4^Ld\x9c\x13\x89g\x8a\x93 b\xe4\x18\x00\x00\xe0\x94\xf9x\xb0%\xb6B3U\\\xc3\xc1\x9a\xda\u007fA\x99\xc94\x8b\xf7\x8aT\xb4\v\x1f\x85+\xda\x00\x00\x00\u07d4\xf9{V\xeb\u0577z\xbc\x9f\xba\u02eb\u0514\xb9\xd2\xc2!\xcd\x03\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xf9\x81\x1f\xa1\x9d\xad\xbf\x02\x9f\x8b\xfeV\x9a\xdb\x18\"\x8c\x80H\x1a\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xf9\x82Ps\fLa\xc5\u007f\x12\x985\xf2h\b\x94yEB\xf3\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xf9\x894gr\x99^\xc1\x90o\xaf\xfe\xba*\u007f\xe7\u079ck\xab\x8a\x01je\x02\xf1Z\x1eT\x00\x00\u07d4\xf9\x98\xca4\x11s\nl\xd1\x0etU\xb0A\x0f\xb0\xf6\xd3\xff\x80\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xf9\x9a\xeeDKW\x83\xc0\x93\xcf\xff\xd1\xc4c,\xf9\x90\x9f\xbb\x91\x1d/\x81\x92\xf8B\t\x89\x90\xf54`\x8ar\x88\x00\x00\u07d4\xf9\xbf\xb5\x9dS\x8a\xfcHt\xd4\xf5\x94\x1b\b\xc9s\x0e8\xe2K\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\u07d4\xf9\xdd#\x90\b\x18/\xb5\x19\xfb0\xee\xdd \x93\xfe\xd1c\x9b\xe8\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xf9\u07ba\xec\xb5\xf39\xbe\xeaH\x94\xe5 K\xfa4\r\x06\u007f%\x89ZB\x84Fs\xb1d\x00\x00\xe0\x94\xf9\xe3tG@lA!\x97\xb2\u2bbc\x00\x1dn0\u024c`\x8a\x01\xc4y\xbbCI\xc0\xee\x00\x00\u07d4\xf9\xe7\"/\xaa\xf0\xf4\xda@\xc1\u0124\x0607:\t\xbe\u05f6\x89\x9bO\u0730\x94V$\x00\x00\u07d4\xf9\xec\xe0\"\xbc\xcd,\x924i\x11\xe7\x9d\xd5\x03\x03\xc0\x1e\x01\x88\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfa\x00\xc3v\xe8\x9c\x05\u81c1z\x9d\xd0t\x8d\x96\xf3A\xaa\x89\x89\x10M\r\x00\u04b7\xf6\x00\x00\u07d4\xfa\f\x1a\x98\x8c\x8a\x17\xad5(\xeb(\xb3@\x9d\xaaX\"_&\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xfa\x10_\x1a\x11\xb6\xe4\xb1\xf5`\x12\xa2y\"\xe2\xac-\xa4\x81/\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\xfa\x14/\xe4~\u0697\xe6P;8k\x18\xa2\xbe\xdds\u0335\xb1\x89.\x15:\xd8\x15H\x10\x00\x00\u07d4\xfa\x14\xb5f#J\xbe\xe70B\xc3\x1d!qq\x82\u02e1J\xa1\x89\x11\xc7\xea\x16.x \x00\x00\u07d4\xfa\x19\xd6\xf7\xa5\x0fO\a\x98\x93\xd1g\xbf\x14\xe2\x1d\x00s\u0456\x89\x1c\xbb:?\xf0\x8d\b\x00\x00\u07d4\xfa\x1f\x19q\xa7u\xc3PO\xefPy\xf6@\xc2\u013c\xe7\xac\x05\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfa'\x9b\xfd\x87g\xf9V\xbf\u007f\xa0\xbdV`\x16\x8d\xa7V\x86\xbd\x89\x90\xf54`\x8ar\x88\x00\x00\xe0\x94\xfa'\xccI\xd0\vl\x98s6\xa8u\xae9\xdaX\xfb\x04\x1b.\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xfa(2\x99`=\x87X\xe8\u02b0\x82\x12],\x8f}DT)\x8a\x01[\xca\xcb\x1e\x05\x01\xae\x80\x00\u07d4\xfa+\xbc\xa1]?\u37ca2\x8e\x91\xf9\r\xa1Oz\xc6%=\x89\n\u05ce\xbcZ\xc6 \x00\x00\xe0\x94\xfa/\u049d\x03\xfe\xe9\xa0x\x93\xdf:&\x9fV\xb7/.\x1ed\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xfa3U2\x85\xa9sq\x9a\r_\x95o\xf8a\xb2\u061e\xd3\x04\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfa:\fK\x90?n\xa5.\xa7\xab{\x88c\xb6\xa6\x16\xadfP\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfa:\x1a\xa4H\x8b5\x1a\xa7V\f\xf5\xeec\n/\xd4\\2\"\x89/\xa4~j\xa74\r\x00\x00\u07d4\xfaA\tq\xad\"\x9c06\xf4\x1a\u03c5/*\u0259(\x19P\x89\u0633\x11\xa8\xdd\xfa|\x00\x00\u07d4\xfaD\xa8U\xe4\x04\xc8m\f\xa8\xef3$%\x1d\xfb4\x9cS\x9e\x89T\"S\xa1&\xce@\x00\x00\xe0\x94\xfaR\x01\xfe\x13B\xaf\x110{\x91B\xa0A$<\xa9./\t\x8a 8\x11j:\xc0C\x98\x00\x00\xe0\x94\xfa`\x86\x8a\xaf\xd4\xffL\\W\x91K\x8e\u054bBWs\u07e9\x8a\x01\xcf\xe5\xc8\b\xf3\x9f\xbc\x00\x00\u07d4\xfag\xb6{O7\xa0\x15\t\x15\x11\x0e\xde\a;\x05\xb8S\xbd\xa2\x89#\x19\xba\x94sq\xad\x00\x00\u07d4\xfah\xe0\xcb>\xdfQ\xf0\xa6\xf2\x11\u0272\xcb^\a<\x9b\xff\xe6\x89\x0f\xc969(\x01\xc0\x00\x00\xe0\x94\xfaj7\xf0\x18\xe9yg\x93\u007f\xc5\xe8a{\xa1\u05c6\xdd_w\x8a\x04<0\xfb\b\x84\xa9l\x00\x00\u07d4\xfav\x06C[5l\xee%{\xd2\xfc\xd3\xd9\xea\xcb<\xd1\xc4\xe1\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xfaz\xdff\v\x8d\x99\xce\x15\x93=|_\a/<\xbe\xb9\x9d3\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4\xfa\x86\xca'\xbf(T\u0648p\x83\u007f\xb6\xf6\xdf\xe4\xbfdS\xfc\x89\x11u~\x85%\xcf\x14\x80\x00\u07d4\xfa\x8c\xf4\xe6'i\x8c]W\x88\xab\xb7\x88\x04\x17\xe7P#\x13\x99\x89\xe6\x1a6\x96\xee\xf6\x10\x00\x00\u07d4\xfa\x8e;\x1f\x13C9\x00s}\xaa\xf1\xf6)\x9cH\x87\xf8[_\x89&\u009eG\u0104L\x00\x00\u07d4\xfa\x9e\xc8\xef\xe0\x86\x86\xfaX\xc1\x813Xr\xbai\x85`\ucac9lj\xccg\u05f1\xd4\x00\x00\u07d4\xfa\xad\x90]\x84|{#A\x8a\xee\xcb\xe3\xad\u06cd\xd3\xf8\x92J\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xfa\xae\xba\x8f\xc0\xbb\xdaU<\xa7.0\xef=s.&\xe8 A\x89H\x8d(*\xaf\xc9\xf6\x80\x00\u07d4\xfa\xb4\x87P\r\xf2\x0f\xb8>\xbe\xd9\x16y\x1dV\x17r\xad\xbe\xbf\x89lkLM\xa6\u077e\x00\x00\u07d4\xfa\xc5\u0294u\x80x\xfb\xfc\xcd\x19\xdb5X\xda~\u8827h\x897(\xa6+\r\xcf\xf6\x00\x00\u07d4\xfa\xd9j\xb6\xacv\x8a\xd5\t\x94R\xacGw\xbd\x1aG\xed\u010f\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xfa\xe7g\x19\xd9~\xacA\x87\x04(\xe9@'\x9d\x97\xddW\xb2\xf6\x8a\x14\u06f2\x19\\\xa2(\x90\x00\x00\u07d4\xfa\u8053pG\x89Zf\f\xf2)v\x0f'\xe6h(\xd6C\x89\t\xdd\xc1\xe3\xb9\x01\x18\x00\x00\u07d4\xfa\xe9,\x13p\xe9\u115a]\xf8;V\xd0\xf5\x86\xaa;@L\x89\x05\u0174\xf3\xd8C\x98\x00\x00\xe0\x94\xfa\xf5\xf0\xb7\xb6\xd5X\xf5\t\r\x9e\xa1\xfb-B%\x9cX`x\x8a\x01Z\xff\xb8B\fkd\x00\x00\xe0\x94\xfb\x12o\x0e\xc7i\xf4\x9d\xce\xfc\xa2\xf2\x00(dQX0\x84\xb8\x8a\x01\x0f\xcb\xc25\x03\x96\xbf\x00\x00\xe0\x94\xfb\x13^\xb1Z\x8b\xacr\xb6\x99\x154*`\xbb\xc0k~\a|\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xfb\"<\x1e\"\xea\xc1&\x9b2\xee\x15jS\x85\x92.\xd3o\xb8\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfb7\xcfkO\x81\xa9\xe2\"\xfb\xa2.\x9b\xd2KP\x98\xb73\u03c9\x02\x1auJm\xc5(\x00\x00\u07d4\xfb8`\xf4\x12\x1cC.\xbd\xc8\xecj\x031\xb1\xb7\ty.\x90\x89 \x8c9J\xf1\u0208\x00\x00\u07d4\xfb9\x18\x9a\xf8v\xe7b\xc7\x1dl>t\x18\x93\xdf\"l\xed\u0589\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xfb:\v\rkjq\x8fo\xc0)*\x82]\xc9$z\x90\xa5\u0409\n\xd6\xdd\x19\x9e\x97[\x00\x00\xe0\x94\xfb?\xa1\xac\b\xab\xa9\xcc;\xf0\xfe\x9dH8 h\x8fe\xb4\x10\x8a\x06ZM\xa2]0\x16\xc0\x00\x00\u07d4\xfb?\xe0\x9b\xb86\x86\x15)\xd7Q\x8d\xa2v5\xf58PV\x15\x89K\xe3\x92\x16\xfd\xa0p\x00\x00\xe0\x94\xfbQ%\xbf\x0f^\xb0\xb6\xf0 \xe5k\xfc/\xdf=@,\t~\x8a\x01@a\xb9\xd7z^\x98\x00\x00\u07d4\xfbU\x18qL\xef\xc3m\x04\x86]\xe5\x91^\xf0\xffG\xdf\xe7C\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfb_\xfa\xa0\xf7aW&5x\x91GX\x18\x93\x9d 7\u03d6\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfbh\\\x15\xe49\x96^\xf6&\xbf\r\x83L\u0468\x9f+V\x95\x89\u0556{\xe4\xfc?\x10\x00\x00\u07d4\xfbtK\x95\x1d\tK1\x02b\xc8\xf9\x86\xc8`\u07da\xb1\xdee\x89\x02\xd1\xc5\x15\xf1\xcbJ\x80\x00\u07d4\xfby\xab\u06d2\\U\xb9\xf9\x8e\xfe\xefd\xcf\xc9\xeba\xf5\x1b\xb1\x89a@\xc0V\xfb\n\xc8\x00\x00\u07d4\xfb\x81\x13\xf9M\x91s\xee\xfdZ0s\xf5\x16\x80:\x10\xb2\x86\xae\x89\x04V9\x18$O@\x00\x00\u07d4\xfb\x84,\xa2\xc5\xef\x139\x17\xa26\xa0\u052c@i\x01\x10\xb08\x89\x10\x96\x9ab\xbe\x15\x88\x00\x00\u07d4\xfb\x91\xfb\x1aiUS\xf0\u018e!'m\xec\xf0\xb89\t\xb8m\x89\x05l\x006\x17\xafx\x00\x00\u07d4\xfb\x94s\xcfw\x125\n\x1f\xa09Rs\xfc\x80V\aR\xe4\xfb\x89\x06\xaf!\x98\xba\x85\xaa\x00\x00\xe0\x94\xfb\x94\x9cd\u007f\xdc\xfd%\x14\xc7\u054e1\xf2\x8aS-\x8cX3\x8a\x04<3\xc1\x93ud\x80\x00\x00\u07d4\xfb\xa5HmS\xc6\xe2@IBA\xab\xf8~C\xc7`\rA:\x89k\xbfaIIH4\x00\x00\u07d4\xfb\xb1a\xfe\x87_\t)\nK&+\xc6\x01\x10\x84\x8f\r\"&\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfb\xbb\xeb\u03fe#^W\xdd#\x06\xad\x1a\x9e\u0141\xc7\xf9\xf4\x8f\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\xfb\xc0\x1d\xb5NG\xcd\xc3\xc48iJ\xb7\x17\xa8V\xc2?\xe6\xe9\x8a\x01\xcaqP\xab\x17OG\x00\x00\xe0\x94\xfb\xcf\xccJ{\x0f&\xcf&\xe9\xf33!2\xe2\xfcj#\af\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xfb\xe7\x16\"\xbc\xbd1\xc1\xa3iv\xe7\xe5\xf6p\xc0\u007f\xfe\x16\u0789\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xfb\xed\xe3,4\x9f3\x00\xefL\xd3;M\xe7\xdc\x18\xe4C\xd3&\x89\xabM\xcf9\x9a:`\x00\x00\u07d4\xfb\xf2\x04\xc8\x13\xf86\xd89b\u01c7\fx\b\xca4\u007f\xd3>\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xfb\xf7Y3\xe0\x1bu\xb1T\xef\x06i\ak\xe8\u007fb\xdf\xfa\xe1\x8a\x10\x84cr\xf2I\xd4\xc0\x00\x00\u07d4\xfc\x00\x96\xb2\x1e\x95\xac\xb8\xd6\x19\xd1v\xa4\xa1\xd8\xd5)\xba\xdb\xef\x89\x14\xd9i;\xcb\xec\x02\x80\x00\xe0\x94\xfc\x00\xa4 \xa3a\a\xdf\xd5\xf4\x95\x12\x8a_\u5af2\xdb\x0f4\x8a\x01C\x17\x9d\x86\x91\x10 \x00\x00\xe0\x94\xfc\x01\x8ai\n\xd6tm\xbe:\u03d7\x12\xdd\xcaR\xb6%\x009\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\u07d4\xfc\x02s@3\xe5\u007fpQ~\n\xfc~\xe6$a\xf0o\xad\x8e\x89\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\xfc\x0e\xe6\xf7\u00b3qJ\xe9\x91lEVf\x05\xb6V\xf3$A\x89_h\xe8\x13\x1e\u03c0\x00\x00\u07d4\xfc\x10\xb7\xa6{2h\xd53\x1b\xfbj\x14\xde\xf5\xeaJ\x16,\xa3\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xfc\x15\u02d9\xa8\xd1\x03\v\x12w\n\xdd\x03:y\xee\r\f\x90\x8c\x89\x12\xfa\x00\xbdR\xe6$\x00\x00\u07d4\xfc)R\xb4\u011f\xed\u043c\x05(\xa3\bI^mj\x1cq\u0589lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xfc,\x1f\x88\x96\x1d\x01\x9c>\x9e\xa30\t\x15.\x06\x93\xfb\xf8\x8a\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\xe0\x94\xfc6\x11\x05\u0750\xf9\xed\xe5fI\x9di\xe9\x13\x03\x95\xf1*\u020aS\xa4\xfe/ N\x80\xe0\x00\x00\u07d4\xfc7/\xf6\x92|\xb3\x96\xd9\xcf)\x805\x00\x11\r\xa62\xbcR\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfc9\xbeA\tK\x19\x97\xd2\x16\x9e\x82d\xc2\u00fa\xa6\u025b\u0109lk\x93[\x8b\xbd@\x00\x00\u07d4\xfc=\"k\xb3jX\xf5&V\x88W\xb0\xbb\x12\xd1\t\xec\x93\x01\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfcC\x82\x9a\u01c7\xff\x88\xaa\xf1\x83\xba5*\xad\xbfZ\x15\xb1\x93\x89\u05ac\n+\x05R\xe0\x00\x00\u07d4\xfcI\xc1C\x9aA\u05b3\xcf&\xbbg\xe06R$\xe5\xe3\x8f_\x8966\u05ef^\u024e\x00\x00\u07d4\xfcU\x00\x82Q\x05\xcfq*1\x8a^\x9c;\xfci\u021d\f\x12\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\xe0\x94\xfcf\xfa\xba'\u007fK]\xe6J\xd4^\xb1\x9c1\xe0\f\xed>\u054a\x011\xbe\xb9%\xff\xd3 \x00\x00\xe0\x94\xfc~\"\xa5\x03\xecZ\xbe\x9b\b\xc5\v\xd1I\x99\xf5 \xfaH\x84\x8a\x01ZG}\xfb\xe1\xea\x14\x80\x00\u07d4\xfc\x82\x15\xa0\xa6\x99\x13\xf6*C\xbf\x1c\x85\x90\xb9\xdd\xcd\r\x8d\u06c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xfc\x98\x9c\xb4\x87\xbf\x1a}\x17\xe4\xc1\xb7\u0137\xaa\xfd\xdak\n\x8d\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\xe0\x94\xfc\x9b4td\xb2\xf9\x92\x9d\x80~\x03\x9d\xaeH\xd3\u064d\xe3y\x8a\x02\xf6\xf1\a\x80\xd2,\xc0\x00\x00\u07d4\xfc\xa4;\xbc#\xa0\xd3!\xba\x9eF\xb9)s\\\xe7\xd8\xef\f\x18\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfc\xa7>\xff\x87q\xc0\x10;\xa3\xcc\x1a\x9c%\x94H\xc7*\xbf\v\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfc\xad\xa3\x00(?k\xcc\x13J\x91Eg`\xb0\xd7}\xe4\x10\xe0\x89lk\x93[\x8b\xbd@\x00\x00\xe0\x94\xfc\xbc\\q\xac\xe7\x97AE\v\x01,\xf6\xb8\xd3\xf1}\xb6\x8ap\x8a\x02\x05\xb4\u07e1\xeetx\x00\x00\u07d4\xfc\xbd\x85\xfe\xeajuO\xcf4ID\x9e7\xff\x97\x84\xf7w<\x89\xa7J\xdai\xab\xd7x\x00\x00\xe0\x94\xfc\xc9\u0524&.z\x02z\xb7Q\x91\x10\xd8\x02\u0115\xce\xea9\x8a\x01YQ\x82\"K&H\x00\x00\xe0\x94\xfc\xcd\r\x1e\xce\xe2z\xdd\xea\x95\xf6\x85z\xee\xc8\u01e0K(\xee\x8a\x02\x1e\x19\xe0\u027a\xb2@\x00\x00\xe0\x94\xfc\u0434\x82|\xd2\b\xff\xbf^u\x9d\xba\x8c<\xc6\x1d\x8c,<\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xfc\xe0\x89c\\\xe9z\xba\xc0kD\x81\x9b\xe5\xbb\n>.\v7\x89\x05\x03\x92\nv0\xa7\x80\x00\u07d4\xfc\xf1\x99\xf8\xb8T\"/\x18.N\x1d\t\x9dN2>*\xae\x01\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfc\xfc:P\x04\xd6xa?\v6\xa6B&\x9a\u007f7\x1c?j\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfd\x19\x1a5\x15}x\x13s\xfbA\x1b\xf9\xf2R\x90\x04|^\xef\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfd\x1f\xaa4{\x0f\u0300L-\xa8l6\xd5\xf1\u044bp\x87\xbb\x89\x02\xd6\xeb$z\x96\xf6\x00\x00\u07d4\xfd\x1f\xb5\xa8\x9a\x89\xa7!\xb8yph\xfb\xc4\u007f>\x9dR\xe1I\x89\f\u0435\x83\u007f\xc6X\x00\x00\u07d4\xfd OOJ\xba%%\xbar\x8a\xfd\xf7\x87\x92\xcb\u07b75\xae\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfd'W\xcc5Q\xa0\x95\x87\x8d\x97\x87V\x15\xfe\fj2\xaa\x8a\x89 m\xb1R\x99\xbe\xac\x00\x00\u07d4\xfd(r\u045eW\x85<\xfa\x16\xef\xfe\x93\u0431\xd4{O\x93\xfb\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xfd))'\x1e\x9d \x95\xa2dv~{\r\xf5.\xa0\xd1\xd4\x00\x89\xa2\xa1\xeb%\x1bZ\xe4\x00\x00\u07d4\xfd7z8Rr\x90\f\xb46\xa3\xbbyb\xcd\xff\xe9?]\xad\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfd@$+\xb3Jp\x85^\xf0\xfd\x90\xf3\x80-\xec!6\xb3'\x89h\xa8u\a>)$\x00\x00\xe0\x94\xfdE,9i\xec\xe3\x80\x1cT \xf1\xcd\u02a1\xc7\x1e\xd2=\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\u07d4\xfdKU\x1fo\xdb\u0366\xc5\x11\xb5\xbb7\"P\xa6\xb7\x83\xe54\x89\x01\x1d\xe1\xe6\xdbE\f\x00\x00\u07d4\xfdK\x98\x95X\xae\x11\xbe\f;6\xe2\xd6\xf2\xa5J\x93C\xca.\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfdM\xe8\xe3t\x8a(\x9c\xf7\xd0`Q}\x9d88\x8d\xb0\x1f\xb8\x89\r\x8drkqw\xa8\x00\x00\u07d4\xfdZc\x15\u007f\x91O\u04d8\uac5c\x13}\xd9U\v\xb7q\\\x89\x05k\xc7^-c\x10\x00\x00\u07d4\xfd`\u04b5\xaf=5\xf7\xaa\xf0\u00d3\x05.y\xc4\xd8#\u0645\x89\x03\x0e\xb5\r.\x14\b\x00\x00\u07d4\xfdhm\xe5?\xa9\u007f\x99c\x9e%hT\x97 \xbcX\x8c\x9e\xfc\x89j\xc5\xc6-\x94\x86\a\x00\x00\u07d4\xfd~\u078fR@\xa0eA\xebi\x9dx,/\x9a\xfb!p\xf6\x89Hz\x9a0E9D\x00\x00\u07d4\xfd\x81+\u019f\xb1p\xefW\xe22~\x80\xaf\xfd\x14\xf8\xe4\xb6\u0489lk\x93[\x8b\xbd@\x00\x00\u07d4\xfd\x88\xd1\x14\"\x0f\b\x1c\xb3\xd5\xe1[\xe8\x15*\xb0sfWj\x89\x10CV\x1a\x88)0\x00\x00\u07d4\xfd\x91\x856\xa8\xef\xa6\xf6\xce\xfe\x1f\xa1\x159\x95\xfe\xf5\xe3=;\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xfd\x92\x0fr&\x82\xaf\xb5\xafE\x1b\x05D\xd4\xf4\x1b;\x9dWB\x89~R\x05j\x12?<\x00\x00\u07d4\xfd\x95y\xf1\x19\xbb\xc8\x19\xa0+a\u3348\x03\xc9B\xf2M2\x89\x05\xb9~\x90\x81\xd9@\x00\x00\u07d4\xfd\xa0\xce\x153\a\a\xf1\v\xce2\x01\x17- \x18\xb9\xdd\xeat\x89\x02\xd0A\xd7\x05\xa2\xc6\x00\x00\xe0\x94\xfd\xa3\x04(\x19\xaf>f)\x00\xe1\xb9+CX\xed\xa6\xe9%\x90\x8a\x19\a\xa2\x84\u054fc\xe0\x00\x00\u07d4\xfd\xa6\x81\x0e\xa5\xac\x98]o\xfb\xf1\xc5\x11\xf1\xc1B\xed\xcf\xdd\xf7\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xfd\xb39D\xf26\x06\x15\xe5\xbe#\x95w\u0221\x9b\xa5-\x98\x87\x89 \x9d\x92/RY\xc5\x00\x00\u07d4\xfd\xbaSY\xf7\xec;\xc7p\xacI\x97]\x84N\xc9qbV\xf1\x8965\u026d\xc5\u07a0\x00\x00\xe0\x94\xfd\xc4\xd4vZ\x94/[\xf9i1\xa9\xe8\xccz\xb8\xb7W\xffL\x8a\x12lG\x8a\x0e>\xa8`\x00\x00\xe0\x94\xfd\xcd]\x80\xb1\x05\x89zW\xab\xc4xev\x8b)\x00RB\x95\x8a\x01Z\xf1\u05cbX\xc4\x00\x00\x00\u0794\xfd\xd1\x19_y}O5q}\x15\xe6\xf9\x81\n\x9a?\xf5T`\x88\xfc\x93c\x92\x80\x1c\x00\x00\u07d4\xfd\xd5\x02\xa7N\x81;\u03e3U\xce\xda<\x17ojhq\xaf\u007f\x89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xfd\u357c\vm\\\xbbL\x1d\x8f\xea>\vK\xffc^\x9d\xb7\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfd\xea\xac*\xcf\x1d\x13\x8e\x19\xf2\xfc?\x9f\xb7E\x92\xe3\ud04a\x89$=M\x18\"\x9c\xa2\x00\x00\u07d4\xfd\xec\xc8-\xdf\xc5a\x92\xe2oV<=h\xcbTJ\x96\xbf\xed\x89\x17\xda:\x04\u01f3\xe0\x00\x00\u07d4\xfd\xf4#C\x01\x9b\v\fk\xf2`\xb1s\xaf\xab~E\xb9\xd6!\x89lj\xccg\u05f1\xd4\x00\x00\u07d4\xfd\xf4I\xf1\b\xc6\xfbOZ+\b\x1e\xed~E\u645eM%\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfd\xfda4\xc0J\x8a\xb7\xeb\x16\xf0\x06C\xf8\xfe\xd7\u06aa\ucc89\x15\xaf\x1dx\xb5\x8c@\x00\x00\u07d4\xfe\x00\xbfC\x99\x11\xa5S\x98-\xb68\x03\x92E\xbc\xf02\xdb\u0709\x15[\xd90\u007f\x9f\xe8\x00\x00\u07d4\xfe\x01n\xc1~\xc5\xf1\x0e;\xb9\x8f\xf4\xa1\xed\xa0E\x15v\x82\xab\x89\x14_T\x02\xe7\xb2\xe6\x00\x00\u07d4\xfe\x0e0\xe2\x14)\rt=\xd3\x0e\xb0\x82\xf1\xf0\xa5\"Z\xdea\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xfe!\v\x8f\x04\xdcmOv!j\xcf\xcb\u055b\xa8;\xe9\xb60\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfe\"\xa0\xb3\x88f\x8d\x1a\xe2d>w\x1d\xac\xf3\x8aCB#\u0309\xd8\xdb^\xbd{&8\x00\x00\u07d4\xfe6&\x88\x84_\xa2D\u0300~K\x110\xeb7A\xa8\x05\x1e\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfe8'\xd5v0\u03c7a\xd5\x12y{\v\x85\x8eG\x8b\xbd\x12\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfeA\x8bB\x1a\x9cm76\x02y\x04u\xd20>\x11\xa7Y0\x897\b\xba\xed=h\x90\x00\x00\u07d4\xfeBI\x12yP\xe2\xf8\x96\xec\x0e~.=\x05Z\xab\x10U\x0f\x89$=M\x18\"\x9c\xa2\x00\x00\xe0\x94\xfeM\x84\x03!o\xd5qW+\xf1\xbd\xb0\x1d\x00W\x89x\u0588\x8a\x02\x15\xf85\xbcv\x9d\xa8\x00\x00\u07d4\xfeS\xb9I\x89\u0619d\xda aS\x95&\xbb\xe9y\xdd.\xa9\x89h\xa8u\a>)$\x00\x00\u07d4\xfeT\x9b\xbf\xe6G@\x18\x98\x92\x93%8\u06afF\u04b6\x1dO\x89\x02+\x1c\x8c\x12'\xa0\x00\x00\xe0\x94\xfea]\x97\\\b\x87\xe0\xc9\x11>\xc7)\x84 \xa7\x93\xaf\x8b\x96\x8a\x01\xb1\xaeMn.\xf5\x00\x00\x00\u07d4\xfee\xc4\x18\x8dy\"Wi\td D\xfd\xc5#\x95V\x01e\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xfei\u007f\xf2,\xa5G\xbf\xc9^3\xd9`\xda`\\gc\xf3[\x89G\xd4\x11\x9f\xd9`\x94\x00\x00\u07d4\xfej\x89[y\\\xb4\xbf\x85\x90=<\xe0\x9cZ\xa49S\u04ff\x89\xb8Pz\x82\a( \x00\x00\u07d4\xfeo_B\xb6\x19;\x1a\xd1b\x06\u4bf5#\x9dM}\xb4^\x89]\u0212\xaa\x111\xc8\x00\x00\u07d4\xfep\x11\xb6\x98\xbf3q\x13-tE\xb1\x9e\xb5\xb0\x945j\xee\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfe\x80\xe9#-\xea\xff\x19\xba\xf9\x98i\x88:K\xdf\x00\x04\xe5<\x89.b\xf2\ni\xbe@\x00\x00\u07d4\xfe\x8en6eW\r\xffz\x1b\xdaiz\xa5\x89\xc0\xb4\xe9\x02J\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfe\x8f\x1f\u072b\u007f\xbe\u0266\xa3\xfc\xc5\aa\x96\x00P\\6\xa3\x89\x01\x11du\x9f\xfb2\x00\x00\u07d4\xfe\x91\xec\xcf+\xd5f\xaf\xa1\x16\x96\xc5\x04\x9f\xa8Lic\nR\x89i*\xe8\x89p\x81\xd0\x00\x00\u07d4\xfe\x96\xc4\xcd8\x15b@\x1a\xa3*\x86\xe6[\x9dR\xfa\x8a\xee'\x89\x8f\x1d\\\x1c\xae7@\x00\x00\u07d4\xfe\x98\xc6d\xc3\xe4G\xa9^i\xbdX!q\xb7\x17n\xa2\xa6\x85\x89\xd8\xd7&\xb7\x17z\x80\x00\x00\u07d4\xfe\x9a\xd1.\xf0]m\x90&\x1f\x96\xc84\n\x03\x81\x97M\xf4w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfe\x9c\x0f\xff\xef\xb8\x03\b\x12V\xc0\xcfMfY\xe6\xd3>\xb4\xfb\x89R\xd5B\x80O\x1c\xe0\x00\x00\u07d4\xfe\x9c\xfc;\xb2\x93\u0772\x85\xe6%\xf3X/t\xa6\xb0\xa5\xa6\u0349j\xcb=\xf2~\x1f\x88\x00\x00\xe0\x94\xfe\x9e\x11\x97\u05d7JvH\xdc\u01e01\x12\xa8\x8e\xdb\xc9\x04]\x8a\x01\n\xfc\x1a\xde;N\xd4\x00\x00\xe0\x94\xfe\xac\xa2\xactbK\xf3H\xda\u0258QC\xcf\xd6R\xa4\xbeU\x8a\x05\x89\u007f\u02f0)\x14\b\x80\x00\u07d4\xfe\xad\x18\x03\xe5\xe77\xa6\x8e\x18G-\x9a\xc7\x15\xf0\x99L\u00be\x89\x1b\x1a\xe4\xd6\xe2\xefP\x00\x00\u07d4\xfe\xb8\xb8\xe2\xafqj\xe4\x1f\xc7\xc0K\xcf)T\x01VF\x1ek\x89TQt\xa5(\xa7z\x00\x00\u07d4\xfe\xb9-0\xbf\x01\xff\x9a\x19\x01flUsS+\xfa\a\xee\xec\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xfe\xbc1s\xbc\x90r\x13cT\x00+{O\xb3\xbf\xc5?\"\xf1\x89\x14\x0e\xc8\x0f\xa7\xee\x88\x00\x00\u07d4\xfe\xbdH\xd0\xff\xdb\xd5el\xd5\xe6\x866:a\x14R(\xf2y\x89\x97\xc9\xceL\xf6\xd5\xc0\x00\x00\u07d4\xfe\xbd\x9f\x81\xcfx\xbd_\xb6\u0139\xa2K\xd4\x14\xbb\x9b\xfaLN\x89k\xe1\x0f\xb8\xedn\x13\x80\x00\u07d4\xfe\xc0o\xe2{D\u01c4\xb29n\xc9/{\x92:\xd1~\x90w\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xfe\xc1NT\x85\xde+>\xef^t\xc4aF\u06ceEN\x035\x89\t\xb4\x1f\xbf\x9e\n\xec\x00\x00\u07d4\xfe\xd8Gm\x10\u0544\xb3\x8b\xfag7`\x0e\xf1\x9d5\xc4\x1e\u0609b\xa9\x92\xe5:\n\xf0\x00\x00\u07d4\xfe\xef;n\xab\xc9J\xff\xd31\f\x1cM\x0ee7^\x13\x11\x19\x89\x01\x15\x8eF\t\x13\xd0\x00\x00\u07d4\xfe\xf0\x9dp$?9\xed\x8c\xd8\x00\xbf\x96QG\x9e\x8fJ\xca<\x89\n\u05ce\xbcZ\xc6 \x00\x00\u07d4\xfe\xf3\xb3\u07ad\x1ai&\u051a\xa3+\x12\xc2*\xf5M\x9f\xf9\x85\x8965\u026d\xc5\u07a0\x00\x00\u07d4\xff\v|\xb7\x1d\xa9\xd4\xc1\xean\xcc(\xeb\xdaPLc\xf8/\u04498\x8a\x88]\xf2\xfcl\x00\x00\u07d4\xff\f\xc6\u73c9lk\x93[\x8b\xbd@\x00\x00\u07d4\xff'&)AH\xb8lx\xa97$\x97\xe4Y\x89\x8e\xd3\xfe\xe3\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xff=\xedz@\u04ef\xf0\u05e8\xc4_\xa6\x13j\xa0C=\xb4W\x89lh\xcc\u041b\x02,\x00\x00\u07d4\xff>\xeeW\xc3Mm\xae\x97\r\x8b1\x11\x17\xc55\x86\xcd5\x02\x89\\(=A\x03\x94\x10\x00\x00\u07d4\xff>\xf6\xba\x15\x1c!\xb5\x99\x86\xaed\xf6\xe8\"\x8b\u0262\xc73\x89lk\x93[\x8b\xbd@\x00\x00\u07d4\xffA\xd9\xe1\xb4\xef\xfe\x18\u0630\xd1\xf6?\xc4%_\xb4\xe0l=\x89Hz\x9a0E9D\x00\x00\u07d4\xffE\xcb4\xc9(6M\x9c\xc9\u063b\x0074ta\x8f\x06\xf3\x89\x05k\xc7^-c\x10\x00\x00\xe0\x94\xffI\xa7u\x81N\xc0\x00Q\xa7\x95\xa8u\xde$Y.\xa4\x00\u050a*Z\x05\x8f\u0095\xed\x00\x00\x00\u07d4\xffJ@\x8fP\xe9\xe7!F\xa2\x8c\xe4\xfc\x8d\x90'\x1f\x11n\x84\x89j\xcb=\xf2~\x1f\x88\x00\x00\u07d4\xffM\x9c\x84\x84\xc4\x10T\x89H\xa4\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xe0\x94L*\xe4\x82Y5\x05\xf0\x16<\xde\xfc\a>\x81\xc6<\xdaA\a\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\xa8\xe8\xf1G2e\x8eKQ\xe8q\x191\x05:\x8ai\xba\xf2\xb1\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe1\x94\u0665\x17\x9f\t\x1d\x85\x05\x1d<\x98'\x85\xef\xd1E\\\uc199\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe1\x94\u08bdBX\xd2v\x887\xba\xa2j(\xfeq\xdc\a\x9f\x84\u01cbJG\xe3\xc1$H\xf4\xad\x00\x00\x00" const sepoliaAllocData = "\xf9\x01\xee\u0791i\x16\xa8{\x823?BE\x04f#\xb27\x94\xc6\\\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe1\x94\x10\xf5\xd4XT\xe08\a\x14\x85\xac\x9e@#\b\u03c0\xd2\xd2\xfe\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\u0794y\x9d2\x9e_X4\x19\x16|\xd7\"\x96$\x85\x92n3\x8fJ\x88\r\u0db3\xa7d\x00\x00\xe0\x94|\xf5\xb7\x9b\xfe)\x1ag\xab\x02\xb3\x93\xe4V\xcc\xc4\xc2f\xf7S\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\x8b\u007f\tw\xbbO\x0f\xbepv\xfa\"\xbc$\xac\xa0CX?^\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xa2\xa6\xd949\x14O\xfeM'\xc9\xe0\x88\xdc\u0637\x83\x94bc\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xaa\xec\x869DA\xf9\x15\xbc\xe3\xe6\xab9\x99w\xe9\x90o;i\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\u1532\x1c3\xde\x1f\xab?\xa1T\x99\xc6+Y\xfe\f\xc3%\x00 \u044bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\xbc\x11)Y6\xaay\u0554\x13\x9d\xe1\xb2\xe1&)AO;\u06ca\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xbe\xef2\xca[\x9a\x19\x8d'\xb4\xe0/LpC\x9f\xe6\x03V\u03ca\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\xd7\xd7lX\xb3\xa5\x19\xe9\xfal\xc4\xd2-\xc0\x17%\x9b\u011f\x1e\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\xd7\xed\xdbx\xed)[<\x96)$\x0e\x89$\xfb\x8d\x88t\xdd\u060a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\u0665\x17\x9f\t\x1d\x85\x05\x1d<\x98'\x85\xef\xd1E\\\uc199\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xe2\xe2e\x90(\x147\x84\xd5W\xbc\xeco\xf3\xa0r\x10H\x88\n\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xf4|\xae\x1c\xf7\x9c\xa6u\x8b\xfcx}\xbd!\u6f7eq\x12\xb8\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00" const holeskyAllocData = "\xf9,\x85\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\x7f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\u0791i\x16\xa8{\x823?BE\x04f#\xb27\x94\xc6\\\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94\v\xe9I\x92\x8f\xf1\x99\xc9\xeb\xa9\xe1\x10\xdb!\n\xa5\xc9N\xfa\u040b|\x13\xbcK,\x13\x8e\u0344h\xa0\x03\x7f\x05\x8a\x9d\xaf\xady\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xf9!2\x94BBBBBBBBBBBBBBBBBBBB\x80\xf9!\x19\x80\xb9\x18\xd6`\x80`@R`\x046\x10a\x00?W`\x005`\xe0\x1c\x80c\x01\xff\u0267\x14a\x00DW\x80c\"\x89Q\x18\x14a\x00\xa4W\x80cb\x1f\xd10\x14a\x01\xbaW\x80c\xc5\xf2\x89/\x14a\x02DW[`\x00\x80\xfd[4\x80\x15a\x00PW`\x00\x80\xfd[Pa\x00\x90`\x04\x806\x03` \x81\x10\x15a\x00gW`\x00\x80\xfd[P5\x7f\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16a\x02kV[`@\x80Q\x91\x15\x15\x82RQ\x90\x81\x90\x03` \x01\x90\xf3[a\x01\xb8`\x04\x806\x03`\x80\x81\x10\x15a\x00\xbaW`\x00\x80\xfd[\x81\x01\x90` \x81\x01\x815d\x01\x00\x00\x00\x00\x81\x11\x15a\x00\xd5W`\x00\x80\xfd[\x82\x01\x83` \x82\x01\x11\x15a\x00\xe7W`\x00\x80\xfd[\x805\x90` \x01\x91\x84`\x01\x83\x02\x84\x01\x11d\x01\x00\x00\x00\x00\x83\x11\x17\x15a\x01\tW`\x00\x80\xfd[\x91\x93\x90\x92\x90\x91` \x81\x01\x905d\x01\x00\x00\x00\x00\x81\x11\x15a\x01'W`\x00\x80\xfd[\x82\x01\x83` \x82\x01\x11\x15a\x019W`\x00\x80\xfd[\x805\x90` \x01\x91\x84`\x01\x83\x02\x84\x01\x11d\x01\x00\x00\x00\x00\x83\x11\x17\x15a\x01[W`\x00\x80\xfd[\x91\x93\x90\x92\x90\x91` \x81\x01\x905d\x01\x00\x00\x00\x00\x81\x11\x15a\x01yW`\x00\x80\xfd[\x82\x01\x83` \x82\x01\x11\x15a\x01\x8bW`\x00\x80\xfd[\x805\x90` \x01\x91\x84`\x01\x83\x02\x84\x01\x11d\x01\x00\x00\x00\x00\x83\x11\x17\x15a\x01\xadW`\x00\x80\xfd[\x91\x93P\x91P5a\x03\x04V[\x00[4\x80\x15a\x01\xc6W`\x00\x80\xfd[Pa\x01\xcfa\x10\xb5V[`@\x80Q` \x80\x82R\x83Q\x81\x83\x01R\x83Q\x91\x92\x83\x92\x90\x83\x01\x91\x85\x01\x90\x80\x83\x83`\x00[\x83\x81\x10\x15a\x02\tW\x81\x81\x01Q\x83\x82\x01R` \x01a\x01\xf1V[PPPP\x90P\x90\x81\x01\x90`\x1f\x16\x80\x15a\x026W\x80\x82\x03\x80Q`\x01\x83` \x03a\x01\x00\n\x03\x19\x16\x81R` \x01\x91P[P\x92PPP`@Q\x80\x91\x03\x90\xf3[4\x80\x15a\x02PW`\x00\x80\xfd[Pa\x02Ya\x10\xc7V[`@\x80Q\x91\x82RQ\x90\x81\x90\x03` \x01\x90\xf3[`\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x16\x7f\x01\xff\u0267\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x80a\x02\xfeWP\x7f\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x16\x7f\x85d\t\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14[\x92\x91PPV[`0\x86\x14a\x03]W`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`&\x81R` \x01\x80a\x18\x05`&\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[` \x84\x14a\x03\xb6W`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`6\x81R` \x01\x80a\x17\x9c`6\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[``\x82\x14a\x04\x0fW`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`)\x81R` \x01\x80a\x18x`)\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[g\r\u0db3\xa7d\x00\x004\x10\x15a\x04pW`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`&\x81R` \x01\x80a\x18R`&\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[c;\x9a\xca\x004\x06\x15a\x04\xcdW`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`3\x81R` \x01\x80a\x17\xd2`3\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[c;\x9a\xca\x004\x04g\xff\xff\xff\xff\xff\xff\xff\xff\x81\x11\x15a\x055W`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`'\x81R` \x01\x80a\x18+`'\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[``a\x05@\x82a\x14\xbaV[\x90P\x7fd\x9b\xbcb\xd0\xe3\x13B\xaf\xeaN\\\xd8-@I\xe7\xe1\xee\x91/\xc0\x88\x9a\xa7\x90\x80;\xe3\x908\u0149\x89\x89\x89\x85\x8a\x8aa\x05u` Ta\x14\xbaV[`@\x80Q`\xa0\x80\x82R\x81\x01\x89\x90R\x90\x81\x90` \x82\x01\x90\x82\x01``\x83\x01`\x80\x84\x01`\xc0\x85\x01\x8e\x8e\x80\x82\x847`\x00\x83\x82\x01R`\x1f\x01\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x16\x90\x91\x01\x87\x81\x03\x86R\x8c\x81R` \x01\x90P\x8c\x8c\x80\x82\x847`\x00\x83\x82\x01\x81\x90R`\x1f\x90\x91\x01\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x16\x90\x92\x01\x88\x81\x03\x86R\x8cQ\x81R\x8cQ` \x91\x82\x01\x93\x91\x8e\x01\x92P\x90\x81\x90\x84\x90\x84\x90[\x83\x81\x10\x15a\x06HW\x81\x81\x01Q\x83\x82\x01R` \x01a\x060V[PPPP\x90P\x90\x81\x01\x90`\x1f\x16\x80\x15a\x06uW\x80\x82\x03\x80Q`\x01\x83` \x03a\x01\x00\n\x03\x19\x16\x81R` \x01\x91P[P\x86\x81\x03\x83R\x88\x81R` \x01\x89\x89\x80\x82\x847`\x00\x83\x82\x01\x81\x90R`\x1f\x90\x91\x01\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x16\x90\x92\x01\x88\x81\x03\x84R\x89Q\x81R\x89Q` \x91\x82\x01\x93\x91\x8b\x01\x92P\x90\x81\x90\x84\x90\x84\x90[\x83\x81\x10\x15a\x06\xefW\x81\x81\x01Q\x83\x82\x01R` \x01a\x06\xd7V[PPPP\x90P\x90\x81\x01\x90`\x1f\x16\x80\x15a\a\x1cW\x80\x82\x03\x80Q`\x01\x83` \x03a\x01\x00\n\x03\x19\x16\x81R` \x01\x91P[P\x9dPPPPPPPPPPPPPP`@Q\x80\x91\x03\x90\xa1`\x00`\x02\x8a\x8a`\x00`\x80\x1b`@Q` \x01\x80\x84\x84\x80\x82\x847\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x94\x16\x91\x90\x93\x01\x90\x81R`@\x80Q\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x81\x84\x03\x01\x81R`\x10\x90\x92\x01\x90\x81\x90R\x81Q\x91\x95P\x93P\x83\x92P` \x85\x01\x91P\x80\x83\x83[` \x83\x10a\a\xfcW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\a\xbfV[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\bYW=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\bnW`\x00\x80\xfd[PQ\x90P`\x00`\x02\x80a\b\x84`@\x84\x8a\x8ca\x16\xfeV[`@Q` \x01\x80\x83\x83\x80\x82\x847\x80\x83\x01\x92PPP\x92PPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\b\xf8W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\b\xbbV[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\tUW=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\tjW`\x00\x80\xfd[PQ`\x02a\t{\x89`@\x81\x8da\x16\xfeV[`@Q`\x00\x90` \x01\x80\x84\x84\x80\x82\x847\x91\x90\x91\x01\x92\x83RPP`@\x80Q\x80\x83\x03\x81R` \x92\x83\x01\x91\x82\x90R\x80Q\x90\x94P\x90\x92P\x82\x91\x84\x01\x90\x80\x83\x83[` \x83\x10a\t\xf4W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\t\xb7V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\nQW=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\nfW`\x00\x80\xfd[PQ`@\x80Q` \x81\x81\x01\x94\x90\x94R\x80\x82\x01\x92\x90\x92R\x80Q\x80\x83\x03\x82\x01\x81R``\x90\x92\x01\x90\x81\x90R\x81Q\x91\x92\x90\x91\x82\x91\x84\x01\x90\x80\x83\x83[` \x83\x10a\n\xdaW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\n\x9dV[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\v7W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\vLW`\x00\x80\xfd[PQ`@\x80Q` \x81\x01\x85\x81R\x92\x93P`\x00\x92`\x02\x92\x83\x92\x87\x92\x8f\x92\x8f\x92\x01\x83\x83\x80\x82\x847\x80\x83\x01\x92PPP\x93PPPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\v\xd9W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\v\x9cV[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\f6W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\fKW`\x00\x80\xfd[PQ`@Q\x86Q`\x02\x91\x88\x91`\x00\x91\x88\x91` \x91\x82\x01\x91\x82\x91\x90\x86\x01\x90\x80\x83\x83[` \x83\x10a\f\xa9W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\flV[`\x01\x83` \x03a\x01\x00\n\x03\x80\x19\x82Q\x16\x81\x84Q\x16\x80\x82\x17\x85RPPPPPP\x90P\x01\x83g\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16g\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x81R`\x18\x01\x82\x81R` \x01\x93PPPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\rNW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\r\x11V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\r\xabW=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\r\xc0W`\x00\x80\xfd[PQ`@\x80Q` \x81\x81\x01\x94\x90\x94R\x80\x82\x01\x92\x90\x92R\x80Q\x80\x83\x03\x82\x01\x81R``\x90\x92\x01\x90\x81\x90R\x81Q\x91\x92\x90\x91\x82\x91\x84\x01\x90\x80\x83\x83[` \x83\x10a\x0e4W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\r\xf7V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\x0e\x91W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\x0e\xa6W`\x00\x80\xfd[PQ\x90P\x85\x81\x14a\x0f\x02W`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`T\x81R` \x01\x80a\x17H`T\x919``\x01\x91PP`@Q\x80\x91\x03\x90\xfd[` Tc\xff\xff\xff\xff\x11a\x0f`W`@Q\x7f\b\xc3y\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81R`\x04\x01\x80\x80` \x01\x82\x81\x03\x82R`!\x81R` \x01\x80a\x17'`!\x919`@\x01\x91PP`@Q\x80\x91\x03\x90\xfd[` \x80T`\x01\x01\x90\x81\x90U`\x00[` \x81\x10\x15a\x10\xa9W\x81`\x01\x16`\x01\x14\x15a\x0f\xa0W\x82`\x00\x82` \x81\x10a\x0f\x91W\xfe[\x01UPa\x10\xac\x95PPPPPPV[`\x02`\x00\x82` \x81\x10a\x0f\xafW\xfe[\x01T\x84`@Q` \x01\x80\x83\x81R` \x01\x82\x81R` \x01\x92PPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\x10%W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\x0f\xe8V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\x10\x82W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\x10\x97W`\x00\x80\xfd[PQ\x92P`\x02\x82\x04\x91P`\x01\x01a\x0fnV[P\xfe[PPPPPPPV[``a\x10\xc2` Ta\x14\xbaV[\x90P\x90V[` T`\x00\x90\x81\x90\x81[` \x81\x10\x15a\x12\xf0W\x81`\x01\x16`\x01\x14\x15a\x11\xe6W`\x02`\x00\x82` \x81\x10a\x10\xf5W\xfe[\x01T\x84`@Q` \x01\x80\x83\x81R` \x01\x82\x81R` \x01\x92PPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\x11kW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\x11.V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\x11\xc8W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\x11\xddW`\x00\x80\xfd[PQ\x92Pa\x12\xe2V[`\x02\x83`!\x83` \x81\x10a\x11\xf6W\xfe[\x01T`@Q` \x01\x80\x83\x81R` \x01\x82\x81R` \x01\x92PPP`@Q` \x81\x83\x03\x03\x81R\x90`@R`@Q\x80\x82\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\x12kW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\x12.V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\x12\xc8W=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\x12\xddW`\x00\x80\xfd[PQ\x92P[`\x02\x82\x04\x91P`\x01\x01a\x10\xd1V[P`\x02\x82a\x12\xff` Ta\x14\xbaV[`\x00`@\x1b`@Q` \x01\x80\x84\x81R` \x01\x83\x80Q\x90` \x01\x90\x80\x83\x83[` \x83\x10a\x13ZW\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\x13\x1dV[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x95\x90\x95\x16\x92\x01\x91\x82RP`@\x80Q\x80\x83\x03\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x01\x81R`\x18\x90\x92\x01\x90\x81\x90R\x81Q\x91\x95P\x93P\x83\x92\x85\x01\x91P\x80\x83\x83[` \x83\x10a\x14?W\x80Q\x82R\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x90\x92\x01\x91` \x91\x82\x01\x91\x01a\x14\x02V[Q\x81Q` \x93\x84\x03a\x01\x00\n\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x19\x90\x92\x16\x91\x16\x17\x90R`@Q\x91\x90\x93\x01\x94P\x91\x92PP\x80\x83\x03\x81\x85Z\xfa\x15\x80\x15a\x14\x9cW=`\x00\x80>=`\x00\xfd[PPP`@Q=` \x81\x10\x15a\x14\xb1W`\x00\x80\xfd[PQ\x92PPP\x90V[`@\x80Q`\b\x80\x82R\x81\x83\x01\x90\x92R``\x91` \x82\x01\x81\x806\x837\x01\x90PP\x90P`\xc0\x82\x90\x1b\x80`\a\x1a`\xf8\x1b\x82`\x00\x81Q\x81\x10a\x14\xf4W\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x06\x1a`\xf8\x1b\x82`\x01\x81Q\x81\x10a\x157W\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x05\x1a`\xf8\x1b\x82`\x02\x81Q\x81\x10a\x15zW\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x04\x1a`\xf8\x1b\x82`\x03\x81Q\x81\x10a\x15\xbdW\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x03\x1a`\xf8\x1b\x82`\x04\x81Q\x81\x10a\x16\x00W\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x02\x1a`\xf8\x1b\x82`\x05\x81Q\x81\x10a\x16CW\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x01\x1a`\xf8\x1b\x82`\x06\x81Q\x81\x10a\x16\x86W\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SP\x80`\x00\x1a`\xf8\x1b\x82`\a\x81Q\x81\x10a\x16\xc9W\xfe[` \x01\x01\x90~\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x19\x16\x90\x81`\x00\x1a\x90SPP\x91\x90PV[`\x00\x80\x85\x85\x11\x15a\x17\rW\x81\x82\xfd[\x83\x86\x11\x15a\x17\x19W\x81\x82\xfd[PP\x82\x01\x93\x91\x90\x92\x03\x91PV\xfeDepositContract: merkle tree fullDepositContract: reconstructed DepositData does not match supplied deposit_data_rootDepositContract: invalid withdrawal_credentials lengthDepositContract: deposit value not multiple of gweiDepositContract: invalid pubkey lengthDepositContract: deposit value too highDepositContract: deposit value too lowDepositContract: invalid signature length\xa2dipfsX\"\x12 \x1d\xd2o7\xa6!p0\t\xab\xf1nw\u6713\xdcP\u01dd\xb7\xf6\xcc7T>>\x0e=\xec\u0717dsolcC\x00\x06\v\x003\xf9\b<\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\xa0\xf5\xa5\xfdB\xd1j 0'\x98\xefn\xd3\t\x97\x9bC\x00=# \xd9\xf0\xe8\xea\x981\xa9'Y\xfbK\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\xa0\xdbV\x11N\x00\xfd\xd4\xc1\xf8\\\x89+\xf3Z\u0268\x92\x89\xaa\xec\xb1\xeb\u0429l\xde`jt\x8b]q\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xa0\u01c0\t\xfd\xf0\x7f\xc5j\x11\xf1\"7\x06X\xa3S\xaa\xa5B\xedc\xe4LK\xc1_\xf4\xcd\x10Z\xb3<\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\xa0Sm\x98\x83\x7f-\xd1e\xa5]^\xea\xe9\x14\x85\x95Dr\xd5o$m\xf2V\xbf<\xae\x195*\x12<\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xa0\x9e\xfd\xe0R\xaa\x15B\x9f\xae\x05\xba\xd4\u0431\xd7\xc6M\xa6M\x03\u05e1\x85JX\x8c,\xb8C\f\r0\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xa0\u060d\xdf\xee\xd4\x00\xa8uU\x96\xb2\x19B\xc1I~\x11L0.a\x18)\x0f\x91\xe6w)v\x04\x1f\xa1\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xa0\x87\xeb\r\u06e5~5\xf6\u0486g8\x02\xa4\xafYu\xe2%\x06\xc7\xcfLd\xbbk\xe5\xee\x11R\x7f,\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xa0&\x84dv\xfd_\xc5J]C8Qg\xc9QD\xf2d?S<\xc8[\xb9\xd1kx/\x8d}\xb1\x93\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xa0Pm\x86X-%$\x05\xb8@\x01\x87\x92\xca\u04bf\x12Y\xf1\xefZ\xa5\xf8\x87\xe1<\xb2\xf0\tOQ\xe1\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\xa0\xff\xff\n\xd7\xe6Yw/\x954\xc1\x95\xc8\x15\xef\xc4\x01N\xf1\xe1\xda\xedD\x04\xc0c\x85\xd1\x11\x92\xe9+\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xa0l\xf0A'\xdb\x05D\x1c\xd83\x10zR\xbe\x85(h\x89\x0eC\x17\xe6\xa0*\xb4v\x83\xaau\x96B \xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\xa0\xb7\xd0_\x87_\x14\x00'\xefQ\x18\xa2${\xbb\x84\u038f/\x0f\x11#b0\x85\xda\xf7\x96\f2\x9f_\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xa0\xdfj\xf5\xf5\xbb\xdbk\xe9\uf2a6\x18\u4fc0s\x96\bg\x17\x1e)go\x8b(M\xeaj\b\xa8^\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\xa0\xb5\x8d\x90\x0f^\x18.\x01t\u0285\x18.\xec\x9f:\t\xf6\xa6\xc0\xdfcw\xa5\x10\xd7\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xa01 o\xa8\nP\xbbj\xbe)\bPX\xf1b\x12!*`\xee\xc8\xf0I\xfe\u02d2\xd8\xc8\xe0\xa8K\xc0\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xa0!5+\xfe\xcb\xed\xdd\u94c3\x9faL=\xac\n>\xe3uC\xf9\xb4\x12\xb1a\x99\xdc\x15\x8e#\xb5D\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\xa0a\x9e1'$\xbbm|1S\xed\x9d\xe7\x91\xd7d\xa3f\xb3\x89\xaf\x13\u014b\xf8\xa8\xd9\x04\x81\xa4ge\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\xa0|\xdd)\x86&\x82Pb\x8d\f\x10\xe3\x85\u014ca\x91\xe6\xfb\xe0Q\x91\xbc\xc0O\x13?,\xear\xc1\xc4\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xa0\x84\x890\xbd{\xa8\xca\xc5Fa\a!\x13\xfb'\x88i\xe0{\xb8X\x7f\x919)37M\x01{\xcb\xe1\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xa0\x88i\xff,\"\xb2\x8c\xc1\x05\x10\u06452\x92\x803(\xbeO\xb0\xe8\x04\x95\u8ecd'\x1f[\x88\x966\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa0\xb5\xfe(\xe7\x9f\x1b\x85\x0f\x86X$l\u9da1\u7d1f\xc0m\xb7\x14>\x8f\xe0\xb4\xf2\xb0\xc5R:\\\xf8B\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xa0\x98^\x92\x9fp\xaf(\u043d\u0469\n\x80\x8f\x97\x7fY||w\x8cH\x9e\x98\u04fd\x89\x10\xd3\x1a\xc0\xf7\xe1\x94F#\x96\u677f\xa4U\xf4\x05\xf4\u0742\xf3\x01J\xf8\x00;r\x8b\xa5o\xa5\xb9\x90\x19\xa5\xc8\x00\x00\x00\xe0\x94I\xdf<\xca&p\xeb\rY\x11F\xb1cY\xfe3nGo)\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94K\xc6V\xb3M\xe28\x96\xfa`i\u0246/5[t\x04\x01\xaf\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe0\x94M\v\x04\xb4\x05\u01b6,|\xfc:\xe5GYt~,\vFb\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94MIl\xcc(\x05\x8b\x1dt\xb7\xa1\x95Af>!\x15O\x9c\x84\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94P\x9avg\xac\x8d\x03 \xe3ar\xc1\x92Pja\x88\xaa\x84\xf6\x8b|\x13\xbcK,\x13\xfa<]\xc1\xaa\x19;\xc6\x03=\xfd\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94jz\xa9\xb8\x82\xd5\v\xb7\xbc]\xa1\xa2Dq\x9c\x99\xf1/\x06\xa3\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94l\xc99|;8s\x9d\xac\xbf\xaah\xea\xd5\xf5\xd7{\xa5\xf4U\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94s\xb2\xe0\xe5E\x10#\x9e\"\u0313o\vJm\xe1\xac\xf0\xab\u078bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94v,\xa6,\xa2T\x9a\xd8\x06v;:\xa1\xea1|B\x9b\xdb\u068a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94w\x8f_\x13\u013ex\xa3\xa4\xd7\x14\x1b\xcb&\x99\x97\x02\xf4\a\u03cbR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\x83M\xbfZ\x03\xe2\x9c%\xbcUE\x9c\u039c\x02\x1e\xeb\xe6v\xad\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\x87]%\xeeK\xc6\x04\xc7\x1b\xafb6\xa8H\x8f\"9\x9b\xedK\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\u150d\xf7\x87\x8d5q\xbe\xf5\xe5\xa7D\xf9b\x87\xc8\xd2\x03\x86\xd7Z\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\x9eAZ\to\xf7vP\u0712]\xeaTe\x85\xb4\xad\xb3\"\xb6\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xa0vke\xa4\xf7\xb1\xday\xa1\xafy\xaciTV\uf886D\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xa2\x9b\x14JD\x9eAJG,`\u01ea\xf1\xaa\xff\xe3)\x02\x1d\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xa5S\x95Vk\vT9[2F\xf9j\v\xdcK\x8aH=\xf9\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xac\x9b\xa7/\xb6\x1a\xa7\xc3\x1a\x95\xdf\n\x8bn\xbaoA\xef\x87^\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xb0I\x8c\x15\x87\x9d\xb2\xeeTq\u0512l_\xaa%\u0260\x96\x83\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xb0J\xef*=-\x86\xb0\x10\x06\xcc\xd43\x9a.\x94=\x9cd\x80\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\u1531\x9f\xb4\xc1\xf2\x802~`\xed7\xb1\xdcn\xe7u3S\x93\x14\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\xbb\x97{.\xe8\xa1\x11\u05c8\xb3G}$ x\u04387\xe7+\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xc2\x1c\xb9\u025c1m\x18c\x14/}\xd8m\xd5Im\x81\xa8\u058a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xc4s\xd4\x12\xdcR\xe3I\x86\"\t\x92L\x89\x81\xb2\xeeB\ah\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\u010e#\xc5\xf6\xe1\xea\v\xae\xf6S\a4\xed\u00d6\x8fy\xaf.\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe1\x94\xc6\xe2E\x99\x91\xbf\xe2|\xcam\x86r/5\xda#\xa1\xe4\u02d7\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\xc9\xca+\xa9\xa2}\xe1\xdbX\x9d\x8c3\xab\x8e\u07e2\x11\x1b1\xfb\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xd1\xf7~L\x1cE\x18n\x86S\u0109\xf9\x0e\x00\x8asYr\x96\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe2\x94\u04d9NM2\x02\xdd#\xc8I}\x7fu\xbf\x16G\xd1\xda\x1b\xb1\x8c\x01\x9d\x97\x1eO\xe8@\x1et\x00\x00\x00\xe0\x94\u0726\u9d0e\xa8j\xeb\xfd\xf9\x92\x99I\x12@B)kn4\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xe0\x99\x1e\x84@A\xbeo\x11\xb9\x9d\xa5\xb1\x14\xb6\xbc\xf8N\xbdW\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\u08bdBX\xd2v\x887\xba\xa2j(\xfeq\xdc\a\x9f\x84\u01cbR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00\xe0\x94\xea(\xd0\x02\x04/\u0649\x8d\r\xb0\x16\xbe\x97X\xee\xaf\xe3\\\x1e\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe0\x94\xef\xa7EO\x11\x16\x80yu\xa4u\vFi^\x96xP\xde]\x8a\xd3\xc2\x1b\xce\xcc\xed\xa1\x00\x00\x00\xe1\x94\xfb\xfdo\xa9\xf7:\u01a0X\xe0\x12Y\x03L(\x00\x1b\xef\x82G\x8bR\xb7\xd2\xdc\xc8\f\xd2\xe4\x00\x00\x00" diff --git a/core/genesis_test.go b/core/genesis_test.go index 4b280bcf13..356a0f326e 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -318,25 +318,25 @@ func TestVerkleGenesisCommit(t *testing.T) { }, } - expected := common.Hex2Bytes("14398d42be3394ff8d50681816a4b7bf8d8283306f577faba2d5bc57498de23b") + expected := common.FromHex("4a83dc39eb688dbcfaf581d60e82de18f875e38786ebce5833342011d6fef37b") got := genesis.ToBlock().Root().Bytes() if !bytes.Equal(got, expected) { t.Fatalf("invalid genesis state root, expected %x, got %x", expected, got) } db := rawdb.NewMemoryDatabase() - triedb := triedb.NewDatabase(db, &triedb.Config{IsVerkle: true, PathDB: pathdb.Defaults}) + triedb := triedb.NewDatabase(db, triedb.VerkleDefaults) block := genesis.MustCommit(db, triedb) if !bytes.Equal(block.Root().Bytes(), expected) { - t.Fatalf("invalid genesis state root, expected %x, got %x", expected, got) + t.Fatalf("invalid genesis state root, expected %x, got %x", expected, block.Root()) } // Test that the trie is verkle if !triedb.IsVerkle() { t.Fatalf("expected trie to be verkle") } - - if !rawdb.ExistsAccountTrieNode(db, nil) { + vdb := rawdb.NewTable(db, string(rawdb.VerklePrefix)) + if !rawdb.HasAccountTrieNode(vdb, nil) { t.Fatal("could not find node") } } diff --git a/core/headerchain.go b/core/headerchain.go index 87404fbd6a..c2d1bf4aa3 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -17,12 +17,9 @@ package core import ( - crand "crypto/rand" "errors" "fmt" - "math" "math/big" - mrand "math/rand" "sync/atomic" "time" @@ -43,45 +40,41 @@ const ( numberCacheLimit = 2048 ) -// HeaderChain implements the basic block header chain logic that is shared by -// core.BlockChain and light.LightChain. It is not usable in itself, only as -// a part of either structure. +// HeaderChain implements the basic block header chain logic. It is not usable +// in itself, but rather an internal structure of core.Blockchain. // // HeaderChain is responsible for maintaining the header chain including the // header query and updating. // -// The components maintained by headerchain includes: (1) total difficulty -// (2) header (3) block hash -> number mapping (4) canonical number -> hash mapping -// and (5) head header flag. +// The data components maintained by HeaderChain include: // -// It is not thread safe either, the encapsulating chain structures should do -// the necessary mutex locking/unlocking. +// - total difficulty +// - header +// - block hash -> number mapping +// - canonical number -> hash mapping +// - head header flag. +// +// It is not thread safe, the encapsulating chain structures should do the +// necessary mutex locking/unlocking. type HeaderChain struct { config *params.ChainConfig chainDb ethdb.Database genesisHeader *types.Header - currentHeader atomic.Value // Current head of the header chain (may be above the block chain!) - currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time) + currentHeader atomic.Pointer[types.Header] // Current head of the header chain (maybe above the block chain!) + currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time) headerCache *lru.Cache[common.Hash, *types.Header] tdCache *lru.Cache[common.Hash, *big.Int] // most recent total difficulties numberCache *lru.Cache[common.Hash, uint64] // most recent block numbers procInterrupt func() bool - - rand *mrand.Rand - engine consensus.Engine + engine consensus.Engine } // NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points // to the parent's interrupt semaphore. func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) { - // Seed a fast but crypto originating random generator - seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64)) - if err != nil { - return nil, err - } hc := &HeaderChain{ config: config, chainDb: chainDb, @@ -89,7 +82,6 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c tdCache: lru.NewCache[common.Hash, *big.Int](tdCacheLimit), numberCache: lru.NewCache[common.Hash, uint64](numberCacheLimit), procInterrupt: procInterrupt, - rand: mrand.New(mrand.NewSource(seed.Int64())), engine: engine, } hc.genesisHeader = hc.GetHeaderByNumber(0) @@ -344,14 +336,6 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header) (int, error) { return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, chain[i-1].Number, parentHash.Bytes()[:4], i, chain[i].Number, hash.Bytes()[:4], chain[i].ParentHash[:4]) } - // If the header is a banned one, straight out abort - if BadHashes[chain[i].ParentHash] { - return i - 1, ErrBannedHash - } - // If it's the last header in the cunk, we need to check it too - if i == len(chain)-1 && BadHashes[chain[i].Hash()] { - return i, ErrBannedHash - } } // Start the parallel verifier abort, results := hc.engine.VerifyHeaders(hc, chain) @@ -591,7 +575,7 @@ func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash { // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. func (hc *HeaderChain) CurrentHeader() *types.Header { - return hc.currentHeader.Load().(*types.Header) + return hc.currentHeader.Load() } // SetCurrentHeader sets the in-memory head header marker of the canonical chan diff --git a/core/mkalloc.go b/core/mkalloc.go index 12c40c14fb..cc4955f038 100644 --- a/core/mkalloc.go +++ b/core/mkalloc.go @@ -30,12 +30,12 @@ import ( "fmt" "math/big" "os" + "slices" "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) type allocItem struct { @@ -101,6 +101,7 @@ func main() { if err != nil { panic(err) } + defer file.Close() if err := json.NewDecoder(file).Decode(g); err != nil { panic(err) } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index af3cb01cee..d11c57546e 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -19,9 +19,9 @@ package rawdb import ( "bytes" "encoding/binary" - "errors" "fmt" "math/big" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) // Support Multi-Database Based on Data Pattern, the Chaindata will be divided into three stores: BlockStore, StateStore, and ChainStore, @@ -756,27 +755,6 @@ func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { return nil } -// DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc. -func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error { - logIndex := uint(0) - if len(txs) != len(receipts) { - return errors.New("transaction and receipt count mismatch") - } - for i := 0; i < len(receipts); i++ { - txHash := txs[i].Hash() - // The derived log fields can simply be set from the block and transaction - for j := 0; j < len(receipts[i].Logs); j++ { - receipts[i].Logs[j].BlockNumber = number - receipts[i].Logs[j].BlockHash = hash - receipts[i].Logs[j].TxHash = txHash - receipts[i].Logs[j].TxIndex = uint(i) - receipts[i].Logs[j].Index = logIndex - logIndex++ - } - } - return nil -} - // ReadLogs retrieves the logs for all transactions in a block. In case // receipts is not found, a nil is returned. // Note: ReadLogs does not derive unstored log fields. @@ -814,7 +792,7 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { if body == nil { return nil } - return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithWithdrawals(body.Withdrawals) + return types.NewBlockWithHeader(header).WithBody(*body) } // WriteBlock serializes a block into the database, header and body separately. @@ -1003,7 +981,11 @@ func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block { } for _, bad := range badBlocks { if bad.Header.Hash() == hash { - return types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles).WithWithdrawals(bad.Body.Withdrawals) + block := types.NewBlockWithHeader(bad.Header) + if bad.Body != nil { + block = block.WithBody(*bad.Body) + } + return block } } return nil @@ -1022,7 +1004,11 @@ func ReadAllBadBlocks(db ethdb.Reader) []*types.Block { } var blocks []*types.Block for _, bad := range badBlocks { - blocks = append(blocks, types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles).WithWithdrawals(bad.Body.Withdrawals)) + block := types.NewBlockWithHeader(bad.Header) + if bad.Body != nil { + block = block.WithBody(*bad.Body) + } + blocks = append(blocks, block) } return blocks } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 8c76141369..869958b520 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -728,7 +728,7 @@ func makeTestBlocks(nblock int, txsPerBlock int) []*types.Block { Number: big.NewInt(int64(i)), Extra: []byte("test block"), } - blocks[i] = types.NewBlockWithHeader(header).WithBody(txs, nil) + blocks[i] = types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs}) blocks[i].Hash() // pre-cache the block hash } return blocks @@ -919,7 +919,7 @@ func TestDeriveLogFields(t *testing.T) { }), } // Create the corresponding receipts - receipts := []*receiptLogs{ + receipts := []*types.Receipt{ { Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x11})}, @@ -943,9 +943,7 @@ func TestDeriveLogFields(t *testing.T) { // Derive log metadata fields number := big.NewInt(1) hash := common.BytesToHash([]byte{0x03, 0x14}) - if err := deriveLogFields(receipts, hash, number.Uint64(), txs); err != nil { - t.Fatal(err) - } + types.Receipts(receipts).DeriveFields(params.TestChainConfig, hash, number.Uint64(), 0, big.NewInt(0), big.NewInt(0), txs) // Iterate over all the computed fields and check that they're correct logIndex := uint(0) diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go index a209026fa9..016880d5e4 100644 --- a/core/rawdb/accessors_indexes_test.go +++ b/core/rawdb/accessors_indexes_test.go @@ -76,7 +76,7 @@ func TestLookupStorage(t *testing.T) { tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) txs := []*types.Transaction{tx1, tx2, tx3} - block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newTestHasher()) + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher()) // Check that no transactions entries are in a pristine database for i, tx := range txs { diff --git a/core/rawdb/accessors_snapshot.go b/core/rawdb/accessors_snapshot.go index 3c82b3f731..5cea581fcd 100644 --- a/core/rawdb/accessors_snapshot.go +++ b/core/rawdb/accessors_snapshot.go @@ -92,20 +92,20 @@ func DeleteAccountSnapshot(db ethdb.KeyValueWriter, hash common.Hash) { } } -// ReadStorageSnapshot retrieves the snapshot entry of an storage trie leaf. +// ReadStorageSnapshot retrieves the snapshot entry of a storage trie leaf. func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) []byte { data, _ := db.Get(storageSnapshotKey(accountHash, storageHash)) return data } -// WriteStorageSnapshot stores the snapshot entry of an storage trie leaf. +// WriteStorageSnapshot stores the snapshot entry of a storage trie leaf. func WriteStorageSnapshot(db ethdb.KeyValueWriter, accountHash, storageHash common.Hash, entry []byte) { if err := db.Put(storageSnapshotKey(accountHash, storageHash), entry); err != nil { log.Crit("Failed to store storage snapshot", "err", err) } } -// DeleteStorageSnapshot removes the snapshot entry of an storage trie leaf. +// DeleteStorageSnapshot removes the snapshot entry of a storage trie leaf. func DeleteStorageSnapshot(db ethdb.KeyValueWriter, accountHash, storageHash common.Hash) { if err := db.Delete(storageSnapshotKey(accountHash, storageHash)); err != nil { log.Crit("Failed to delete storage snapshot", "err", err) diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index 886c1c469b..043426cf20 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -24,7 +24,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "golang.org/x/crypto/sha3" ) // HashScheme is the legacy hash-based state scheme with which trie nodes are @@ -50,7 +49,7 @@ const PathScheme = "path" type hasher struct{ sha crypto.KeccakState } var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} }, + New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} }, } func newHasher() *hasher { @@ -65,9 +64,9 @@ func (h *hasher) release() { hasherPool.Put(h) } -// ReadAccountTrieNode retrieves the account trie node and the associated node +// ReadAccountTrieNodeAndHash retrieves the account trie node and the associated node // hash with the specified node path. -func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) { +func ReadAccountTrieNodeAndHash(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) { data, err := db.Get(accountTrieNodeKey(path)) if err != nil { return nil, common.Hash{} @@ -77,21 +76,15 @@ func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.H return data, h.hash(data) } -// HasAccountTrieNode checks the account trie node presence with the specified -// node path and the associated node hash. -func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte, hash common.Hash) bool { - data, err := db.Get(accountTrieNodeKey(path)) - if err != nil { - return false - } - h := newHasher() - defer h.release() - return h.hash(data) == hash +// ReadAccountTrieNode retrieves the account trie node with the specified node path. +func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte { + data, _ := db.Get(accountTrieNodeKey(path)) + return data } -// ExistsAccountTrieNode checks the presence of the account trie node with the +// HasAccountTrieNode checks the presence of the account trie node with the // specified node path, regardless of the node hash. -func ExistsAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool { +func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool { has, err := db.Has(accountTrieNodeKey(path)) if err != nil { return false @@ -113,9 +106,9 @@ func DeleteAccountTrieNode(db ethdb.KeyValueWriter, path []byte) { } } -// ReadStorageTrieNode retrieves the storage trie node and the associated node +// ReadStorageTrieNodeAndHash retrieves the storage trie node and the associated node // hash with the specified node path. -func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) { +func ReadStorageTrieNodeAndHash(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) { data, err := db.Get(storageTrieNodeKey(accountHash, path)) if err != nil { return nil, common.Hash{} @@ -125,21 +118,15 @@ func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path return data, h.hash(data) } -// HasStorageTrieNode checks the storage trie node presence with the provided -// node path and the associated node hash. -func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte, hash common.Hash) bool { - data, err := db.Get(storageTrieNodeKey(accountHash, path)) - if err != nil { - return false - } - h := newHasher() - defer h.release() - return h.hash(data) == hash +// ReadStorageTrieNode retrieves the storage trie node with the specified node path. +func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) []byte { + data, _ := db.Get(storageTrieNodeKey(accountHash, path)) + return data } -// ExistsStorageTrieNode checks the presence of the storage trie node with the +// HasStorageTrieNode checks the presence of the storage trie node with the // specified account hash and node path, regardless of the node hash. -func ExistsStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool { +func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool { has, err := db.Has(storageTrieNodeKey(accountHash, path)) if err != nil { return false @@ -198,10 +185,18 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c case HashScheme: return HasLegacyTrieNode(db, hash) case PathScheme: + var blob []byte if owner == (common.Hash{}) { - return HasAccountTrieNode(db, path, hash) + blob = ReadAccountTrieNode(db, path) + } else { + blob = ReadStorageTrieNode(db, owner, path) + } + if len(blob) == 0 { + return false } - return HasStorageTrieNode(db, owner, path, hash) + h := newHasher() + defer h.release() + return h.hash(blob) == hash // exists but not match default: panic(fmt.Sprintf("Unknown scheme %v", scheme)) } @@ -209,43 +204,35 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c // ReadTrieNode retrieves the trie node from database with the provided node info // and associated node hash. -// hashScheme-based lookup requires the following: -// - hash -// -// pathScheme-based lookup requires the following: -// - owner -// - path func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) []byte { switch scheme { case HashScheme: return ReadLegacyTrieNode(db, hash) case PathScheme: - var ( - blob []byte - nHash common.Hash - ) + var blob []byte if owner == (common.Hash{}) { - blob, nHash = ReadAccountTrieNode(db, path) + blob = ReadAccountTrieNode(db, path) } else { - blob, nHash = ReadStorageTrieNode(db, owner, path) + blob = ReadStorageTrieNode(db, owner, path) } - if nHash != hash { + if len(blob) == 0 { return nil } + h := newHasher() + defer h.release() + if h.hash(blob) != hash { + return nil // exists but not match + } return blob default: panic(fmt.Sprintf("Unknown scheme %v", scheme)) } } -// WriteTrieNode writes the trie node into database with the provided node info -// and associated node hash. -// hashScheme-based lookup requires the following: -// - hash +// WriteTrieNode writes the trie node into database with the provided node info. // -// pathScheme-based lookup requires the following: -// - owner -// - path +// hash-scheme requires the node hash as the identifier. +// path-scheme requires the node owner and path as the identifier. func WriteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, node []byte, scheme string) { switch scheme { case HashScheme: @@ -261,14 +248,10 @@ func WriteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash } } -// DeleteTrieNode deletes the trie node from database with the provided node info -// and associated node hash. -// hashScheme-based lookup requires the following: -// - hash +// DeleteTrieNode deletes the trie node from database with the provided node info. // -// pathScheme-based lookup requires the following: -// - owner -// - path +// hash-scheme requires the node hash as the identifier. +// path-scheme requires the node owner and path as the identifier. func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, scheme string) { switch scheme { case HashScheme: @@ -286,10 +269,9 @@ func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, has // ReadStateScheme reads the state scheme of persistent state, or none // if the state is not present in database. -func ReadStateScheme(db ethdb.Reader) string { - // Check if state in path-based scheme is present - blob, _ := ReadAccountTrieNode(db.StateStoreReader(), nil) - if len(blob) != 0 { +func ReadStateScheme(db ethdb.Database) string { + // Check if state in path-based scheme is present. + if HasAccountTrieNode(db.StateStoreReader(), nil) { return PathScheme } // The root node might be deleted during the initial snap sync, check @@ -297,6 +279,16 @@ func ReadStateScheme(db ethdb.Reader) string { if id := ReadPersistentStateID(db.StateStoreReader()); id != 0 { return PathScheme } + // Check if verkle state in path-based scheme is present. + vdb := NewTable(db, string(VerklePrefix)) + if HasAccountTrieNode(vdb, nil) { + return PathScheme + } + // The root node of verkle might be deleted during the initial snap sync, + // check the persistent state id then. + if id := ReadPersistentStateID(vdb); id != 0 { + return PathScheme + } // In a hash-based scheme, the genesis state is consistently stored // on the disk. To assess the scheme of the persistent state, it // suffices to inspect the scheme of the genesis state. @@ -304,8 +296,7 @@ func ReadStateScheme(db ethdb.Reader) string { if header == nil { return "" // empty datadir } - blob = ReadLegacyTrieNode(db.StateStoreReader(), header.Root) - if len(blob) == 0 { + if !HasLegacyTrieNode(db.StateStoreReader(), header.Root) { return "" // no state in disk } return HashScheme @@ -344,6 +335,10 @@ func ParseStateScheme(provided string, disk ethdb.Database) (string, error) { log.Info("State scheme set to already existing disk db", "scheme", stored) return stored, nil // reuse scheme of persistent scheme } + // If state scheme is specified, ensure it's valid. + if provided != HashScheme && provided != PathScheme { + return "", fmt.Errorf("invalid state scheme %s", provided) + } // If state scheme is specified, ensure it's compatible with // persistent state. if stored == "" || provided == stored { diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index ee71dc7cd6..2f67650ead 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -16,7 +16,11 @@ package rawdb -import "path/filepath" +import ( + "path/filepath" + + "github.com/ethereum/go-ethereum/ethdb" +) // The list of table names of chain freezer. const ( @@ -74,14 +78,29 @@ var stateFreezerNoSnappy = map[string]bool{ // The list of identifiers of ancient stores. var ( - ChainFreezerName = "chain" // the folder name of chain segment ancient store. - StateFreezerName = "state" // the folder name of reverse diff ancient store. + ChainFreezerName = "chain" // the folder name of chain segment ancient store. + MerkleStateFreezerName = "state" // the folder name of state history ancient store. + VerkleStateFreezerName = "state_verkle" // the folder name of state history ancient store. ) // freezers the collections of all builtin freezers. -var freezers = []string{ChainFreezerName, StateFreezerName} +var freezers = []string{ChainFreezerName, MerkleStateFreezerName, VerkleStateFreezerName} -// NewStateFreezer initializes the freezer for state history. -func NewStateFreezer(ancientDir string, readOnly bool, offset uint64) (*ResettableFreezer, error) { - return NewResettableFreezer(filepath.Join(ancientDir, StateFreezerName), "eth/db/state", readOnly, offset, stateHistoryTableSize, stateFreezerNoSnappy) +// NewStateFreezer initializes the ancient store for state history. +// +// - if the empty directory is given, initializes the pure in-memory +// state freezer (e.g. dev mode). +// - if non-empty directory is given, initializes the regular file-based +// state freezer. +func NewStateFreezer(ancientDir string, verkle bool, readOnly bool, offset uint64) (ethdb.ResettableAncientStore, error) { + if ancientDir == "" { + return NewMemoryFreezer(readOnly, stateFreezerNoSnappy), nil + } + var name string + if verkle { + name = filepath.Join(ancientDir, VerkleStateFreezerName) + } else { + name = filepath.Join(ancientDir, MerkleStateFreezerName) + } + return newResettableFreezer(name, "eth/db/state", readOnly, offset, stateHistoryTableSize, stateFreezerNoSnappy) } diff --git a/core/rawdb/ancient_utils.go b/core/rawdb/ancient_utils.go index 33e1e02bfc..21036e694e 100644 --- a/core/rawdb/ancient_utils.go +++ b/core/rawdb/ancient_utils.go @@ -92,8 +92,8 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { } infos = append(infos, info) - case StateFreezerName: - if ReadStateScheme(db) != PathScheme || db.StateStore() != nil { + case MerkleStateFreezerName, VerkleStateFreezerName: + if db.StateStore() != nil { continue } datadir, err := db.AncientDatadir() @@ -101,7 +101,7 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { return nil, err } - file, err := os.Open(filepath.Join(datadir, StateFreezerName)) + file, err := os.Open(filepath.Join(datadir, MerkleStateFreezerName)) if err != nil { return nil, err } @@ -112,13 +112,13 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { continue } - f, err := NewStateFreezer(datadir, true, 0) + f, err := NewStateFreezer(datadir, freezer == VerkleStateFreezerName, true, 0) if err != nil { - return nil, err + continue // might be possible the state freezer is not existent } defer f.Close() - info, err := inspect(StateFreezerName, stateFreezerNoSnappy, f) + info, err := inspect(freezer, stateFreezerNoSnappy, f) if err != nil { return nil, err } @@ -148,7 +148,7 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy } - case StateFreezerName: + case MerkleStateFreezerName, VerkleStateFreezerName: if multiDatabase { path, tables = filepath.Join(filepath.Dir(ancient)+"/state/ancient", freezerName), stateFreezerNoSnappy } else { @@ -174,7 +174,7 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s } func ResetStateFreezerTableOffset(ancient string, virtualTail uint64) error { - path, tables := filepath.Join(ancient, StateFreezerName), stateFreezerNoSnappy + path, tables := filepath.Join(ancient, MerkleStateFreezerName), stateFreezerNoSnappy for name, disableSnappy := range tables { log.Info("Handle table", "name", name, "disableSnappy", disableSnappy) diff --git a/core/rawdb/ancienttest/testsuite.go b/core/rawdb/ancienttest/testsuite.go new file mode 100644 index 0000000000..70de263c04 --- /dev/null +++ b/core/rawdb/ancienttest/testsuite.go @@ -0,0 +1,325 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ancienttest + +import ( + "bytes" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/testrand" +) + +// TestAncientSuite runs a suite of tests against an ancient database +// implementation. +func TestAncientSuite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { + // Test basic read methods + t.Run("BasicRead", func(t *testing.T) { basicRead(t, newFn) }) + + // Test batch read method + t.Run("BatchRead", func(t *testing.T) { batchRead(t, newFn) }) + + // Test basic write methods + t.Run("BasicWrite", func(t *testing.T) { basicWrite(t, newFn) }) + + // Test if data mutation is allowed after db write + t.Run("nonMutable", func(t *testing.T) { nonMutable(t, newFn) }) +} + +func basicRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { + var ( + db = newFn([]string{"a"}) + data = makeDataset(100, 32) + ) + defer db.Close() + + db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < len(data); i++ { + op.AppendRaw("a", uint64(i), data[i]) + } + return nil + }) + db.TruncateTail(10) + db.TruncateHead(90) + + // Test basic tail and head retrievals + tail, err := db.Tail() + if err != nil || tail != 10 { + t.Fatal("Failed to retrieve tail") + } + ancient, err := db.Ancients() + if err != nil || ancient != 90 { + t.Fatal("Failed to retrieve ancient") + } + + // Test the deleted items shouldn't be reachable + var cases = []struct { + start int + limit int + }{ + {0, 10}, + {90, 100}, + } + for _, c := range cases { + for i := c.start; i < c.limit; i++ { + exist, err := db.HasAncient("a", uint64(i)) + if err != nil { + t.Fatalf("Failed to check presence, %v", err) + } + if exist { + t.Fatalf("Item %d is already truncated", uint64(i)) + } + _, err = db.Ancient("a", uint64(i)) + if err == nil { + t.Fatal("Error is expected for non-existent item") + } + } + } + + // Test the items in range should be reachable + for i := 10; i < 90; i++ { + exist, err := db.HasAncient("a", uint64(i)) + if err != nil { + t.Fatalf("Failed to check presence, %v", err) + } + if !exist { + t.Fatalf("Item %d is missing", uint64(i)) + } + blob, err := db.Ancient("a", uint64(i)) + if err != nil { + t.Fatalf("Failed to retrieve item, %v", err) + } + if !bytes.Equal(blob, data[i]) { + t.Fatalf("Unexpected item content, want: %v, got: %v", data[i], blob) + } + } + + // Test the items in unknown table shouldn't be reachable + exist, err := db.HasAncient("b", uint64(0)) + if err != nil { + t.Fatalf("Failed to check presence, %v", err) + } + if exist { + t.Fatal("Item in unknown table shouldn't be found") + } + _, err = db.Ancient("b", uint64(0)) + if err == nil { + t.Fatal("Error is expected for unknown table") + } +} + +func batchRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { + var ( + db = newFn([]string{"a"}) + data = makeDataset(100, 32) + ) + defer db.Close() + + db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), data[i]) + } + return nil + }) + db.TruncateTail(10) + db.TruncateHead(90) + + // Test the items in range should be reachable + var cases = []struct { + start uint64 + count uint64 + maxSize uint64 + expStart int + expLimit int + }{ + // Items in range [10, 90) with no size limitation + { + 10, 80, 0, 10, 90, + }, + // Items in range [10, 90) with 32 size cap, single item is expected + { + 10, 80, 32, 10, 11, + }, + // Items in range [10, 90) with 31 size cap, single item is expected + { + 10, 80, 31, 10, 11, + }, + // Items in range [10, 90) with 32*80 size cap, all items are expected + { + 10, 80, 32 * 80, 10, 90, + }, + // Extra items above the last item are not returned + { + 10, 90, 0, 10, 90, + }, + } + for i, c := range cases { + batch, err := db.AncientRange("a", c.start, c.count, c.maxSize) + if err != nil { + t.Fatalf("Failed to retrieve item in range, %v", err) + } + if !reflect.DeepEqual(batch, data[c.expStart:c.expLimit]) { + t.Fatalf("Case %d, Batch content is not matched", i) + } + } + + // Test out-of-range / zero-size retrieval should be rejected + _, err := db.AncientRange("a", 0, 1, 0) + if err == nil { + t.Fatal("Out-of-range retrieval should be rejected") + } + _, err = db.AncientRange("a", 90, 1, 0) + if err == nil { + t.Fatal("Out-of-range retrieval should be rejected") + } + _, err = db.AncientRange("a", 10, 0, 0) + if err == nil { + t.Fatal("Zero-size retrieval should be rejected") + } + + // Test item in unknown table shouldn't be reachable + _, err = db.AncientRange("b", 10, 1, 0) + if err == nil { + t.Fatal("Item in unknown table shouldn't be found") + } +} + +func basicWrite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { + var ( + db = newFn([]string{"a", "b"}) + dataA = makeDataset(100, 32) + dataB = makeDataset(100, 32) + ) + defer db.Close() + + // The ancient write to tables should be aligned + _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), dataA[i]) + } + return nil + }) + if err == nil { + t.Fatal("Unaligned ancient write should be rejected") + } + + // Test normal ancient write + size, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), dataA[i]) + op.AppendRaw("b", uint64(i), dataB[i]) + } + return nil + }) + if err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } + wantSize := int64(6400) + if size != wantSize { + t.Fatalf("Ancient write size is not expected, want: %d, got: %d", wantSize, size) + } + + // Write should work after head truncating + db.TruncateHead(90) + _, err = db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 90; i < 100; i++ { + op.AppendRaw("a", uint64(i), dataA[i]) + op.AppendRaw("b", uint64(i), dataB[i]) + } + return nil + }) + if err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } + + // Write should work after truncating everything + db.TruncateTail(0) + _, err = db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), dataA[i]) + op.AppendRaw("b", uint64(i), dataB[i]) + } + return nil + }) + if err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } +} + +func nonMutable(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { + db := newFn([]string{"a"}) + defer db.Close() + + // We write 100 zero-bytes to the freezer and immediately mutate the slice + db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + data := make([]byte, 100) + op.AppendRaw("a", uint64(0), data) + for i := range data { + data[i] = 0xff + } + return nil + }) + // Now read it. + data, err := db.Ancient("a", uint64(0)) + if err != nil { + t.Fatal(err) + } + for k, v := range data { + if v != 0 { + t.Fatalf("byte %d != 0: %x", k, v) + } + } +} + +// TestResettableAncientSuite runs a suite of tests against a resettable ancient +// database implementation. +func TestResettableAncientSuite(t *testing.T, newFn func(kinds []string) ethdb.ResettableAncientStore) { + t.Run("Reset", func(t *testing.T) { + var ( + db = newFn([]string{"a"}) + data = makeDataset(100, 32) + ) + defer db.Close() + + db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), data[i]) + } + return nil + }) + db.TruncateTail(10) + db.TruncateHead(90) + + // Ancient write should work after resetting + db.Reset() + db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + for i := 0; i < 100; i++ { + op.AppendRaw("a", uint64(i), data[i]) + } + return nil + }) + }) +} + +func makeDataset(size, value int) [][]byte { + var vals [][]byte + for i := 0; i < size; i += 1 { + vals = append(vals, testrand.Bytes(value)) + } + return vals +} diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index 3a18281100..0e66516036 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -47,33 +47,47 @@ var ( missFreezerEnvErr = errors.New("missing freezer env error") ) -// chainFreezer is a wrapper of freezer with additional chain freezing feature. -// The background thread will keep moving ancient chain segments from key-value -// database to flat files for saving space on live database. +// chainFreezer is a wrapper of chain ancient store with additional chain freezing +// feature. The background thread will keep moving ancient chain segments from +// key-value database to flat files for saving space on live database. type chainFreezer struct { - threshold atomic.Uint64 // Number of recent blocks not to freeze (params.FullImmutabilityThreshold apart from tests) + ethdb.AncientStore // Ancient store for storing cold chain segment - *Freezer quit chan struct{} wg sync.WaitGroup trigger chan chan struct{} // Manual blocking freeze trigger, test determinism + threshold atomic.Uint64 // Number of recent blocks not to freeze (params.FullImmutabilityThreshold apart from tests) + freezeEnv atomic.Value waitEnvTimes int multiDatabase bool } -// newChainFreezer initializes the freezer for ancient chain data. +// newChainFreezer initializes the freezer for ancient chain segment. +// +// - if the empty directory is given, initializes the pure in-memory +// state freezer (e.g. dev mode). +// - if non-empty directory is given, initializes the regular file-based +// state freezer. func newChainFreezer(datadir string, namespace string, readonly bool, offset uint64, multiDatabase bool) (*chainFreezer, error) { - freezer, err := NewChainFreezer(datadir, namespace, readonly, offset) + var ( + err error + freezer ethdb.AncientStore + ) + if datadir == "" { + freezer = NewMemoryFreezer(readonly, chainFreezerNoSnappy) + } else { + freezer, err = NewFreezer(datadir, namespace, readonly, offset, freezerTableSize, chainFreezerNoSnappy) + } if err != nil { return nil, err } cf := chainFreezer{ - Freezer: freezer, - quit: make(chan struct{}), - trigger: make(chan chan struct{}), + AncientStore: freezer, + quit: make(chan struct{}), + trigger: make(chan chan struct{}), } cf.threshold.Store(params.FullImmutabilityThreshold) return &cf, nil @@ -87,7 +101,7 @@ func (f *chainFreezer) Close() error { close(f.quit) } f.wg.Wait() - return f.Freezer.Close() + return f.AncientStore.Close() } // readHeadNumber returns the number of chain head block. 0 is returned if the @@ -199,7 +213,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { log.Debug("Current full block not old enough to freeze", "err", err) continue } - frozen = f.frozen.Load() + frozen, _ := f.Ancients() // no error will occur, safe to ignore // Short circuit if the blocks below threshold are already frozen. if frozen != 0 && frozen-1 >= threshold { @@ -242,7 +256,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { } number = ReadHeaderNumber(nfdb, hash) threshold = f.threshold.Load() - frozen = f.frozen.Load() + frozen, _ := f.Ancients() // no error will occur, safe to ignore switch { case number == nil: log.Error("Current full block number unavailable", "hash", hash) @@ -294,7 +308,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { backoff = true continue } - // Batch of blocks have been frozen, flush them before wiping from leveldb + // Batch of blocks have been frozen, flush them before wiping from key-value store if err := f.Sync(); err != nil { log.Crit("Failed to flush frozen tables", "err", err) } @@ -314,7 +328,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { // Wipe out side chains also and track dangling side chains var dangling []common.Hash - frozen = f.frozen.Load() // Needs reload after during freezeRange + frozen, _ = f.Ancients() // Needs reload after during freezeRange for number := first; number < frozen; number++ { // Always keep the genesis block in active database if number != 0 { @@ -531,7 +545,6 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash } return nil }) - return hashes, err } diff --git a/core/rawdb/chain_iterator_test.go b/core/rawdb/chain_iterator_test.go index 78b0a82e10..390424f673 100644 --- a/core/rawdb/chain_iterator_test.go +++ b/core/rawdb/chain_iterator_test.go @@ -34,7 +34,7 @@ func TestChainIterator(t *testing.T) { var block *types.Block var txs []*types.Transaction to := common.BytesToAddress([]byte{0x11}) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) // Empty genesis block + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) // Empty genesis block WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) for i := uint64(1); i <= 10; i++ { @@ -60,7 +60,7 @@ func TestChainIterator(t *testing.T) { }) } txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher()) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) } @@ -111,7 +111,7 @@ func TestIndexTransactions(t *testing.T) { to := common.BytesToAddress([]byte{0x11}) // Write empty genesis block - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) @@ -138,7 +138,7 @@ func TestIndexTransactions(t *testing.T) { }) } txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher()) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) } diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 5049ade332..1f8db78ec9 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "os" - "path" "path/filepath" "strings" "time" @@ -35,11 +34,14 @@ import ( "github.com/olekukonko/tablewriter" ) -// freezerdb is a database wrapper that enables freezer data retrievals. +// freezerdb is a database wrapper that enables ancient chain segment freezing. type freezerdb struct { - ancientRoot string ethdb.KeyValueStore ethdb.AncientStore + + readOnly bool + ancientRoot string + ethdb.AncientFreezer diffStore ethdb.KeyValueStore stateStore ethdb.Database @@ -155,7 +157,7 @@ func (frdb *freezerdb) HasSeparateBlockStore() bool { // a freeze cycle completes, without having to sleep for a minute to trigger the // automatic background run. func (frdb *freezerdb) Freeze(threshold uint64) error { - if frdb.AncientStore.(*chainFreezer).readonly { + if frdb.readOnly { return errReadOnly } // Set the freezer threshold to a temporary value @@ -163,6 +165,7 @@ func (frdb *freezerdb) Freeze(threshold uint64) error { frdb.AncientStore.(*chainFreezer).threshold.Store(old) }(frdb.AncientStore.(*chainFreezer).threshold.Load()) frdb.AncientStore.(*chainFreezer).threshold.Store(threshold) + // Trigger a freeze cycle and block until it's done trigger := make(chan struct{}, 1) frdb.AncientStore.(*chainFreezer).trigger <- trigger @@ -326,12 +329,6 @@ func (db *nofreezedb) AncientOffSet() uint64 { return 0 } -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (db *nofreezedb) MigrateTable(kind string, convert convertLegacyFn) error { - return errNotSupported -} - // AncientDatadir returns an error as we don't have a backing chain freezer. func (db *nofreezedb) AncientDatadir() (string, error) { return "", errNotSupported @@ -432,11 +429,6 @@ func (db *emptyfreezedb) ReadAncients(fn func(reader ethdb.AncientReaderOp) erro } func (db *emptyfreezedb) AncientOffSet() uint64 { return 0 } -// MigrateTable returns nil for pruned db that we don't have a backing chain freezer. -func (db *emptyfreezedb) MigrateTable(kind string, convert convertLegacyFn) error { - return nil -} - // AncientDatadir returns nil for pruned db that we don't have a backing chain freezer. func (db *emptyfreezedb) AncientDatadir() (string, error) { return "", nil @@ -473,8 +465,8 @@ func resolveChainFreezerDir(ancient string) string { // sub folder, if not then two possibilities: // - chain freezer is not initialized // - chain freezer exists in legacy location (root ancient folder) - chain := path.Join(ancient, ChainFreezerName) - state := path.Join(ancient, StateFreezerName) + chain := filepath.Join(ancient, ChainFreezerName) + state := filepath.Join(ancient, MerkleStateFreezerName) if common.FileExist(chain) { return chain } @@ -493,6 +485,14 @@ func resolveChainFreezerDir(ancient string) string { // storage. The passed ancient indicates the path of root ancient directory // where the chain freezer can be opened. func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData, multiDatabase bool) (ethdb.Database, error) { + // Create the idle freezer instance. If the given ancient directory is empty, + // in-memory chain freezer is used (e.g. dev mode); otherwise the regular + // file-based freezer is created. + chainFreezerDir := ancient + if chainFreezerDir != "" { + chainFreezerDir = resolveChainFreezerDir(chainFreezerDir) + } + var offset uint64 // The offset of ancientDB should be handled differently in different scenarios. if isLastOffset { @@ -636,7 +636,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st WriteAncientType(db, EntireFreezerType) } // Freezer is consistent with the key-value database, permit combining the two - if !disableFreeze && !frdb.readonly { + if !disableFreeze && readonly { frdb.wg.Add(1) go func() { frdb.freeze(db) @@ -944,6 +944,10 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { cliqueSnaps stat parliaSnaps stat + // Verkle statistics + verkleTries stat + verkleStateLookups stat + // Les statistic chtTrieNodes stat bloomTrieNodes stat @@ -1013,6 +1017,24 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { bytes.HasPrefix(key, BloomTrieIndexPrefix) || bytes.HasPrefix(key, BloomTriePrefix): // Bloomtrie sub bloomTrieNodes.Add(size) + + // Verkle trie data is detected, determine the sub-category + case bytes.HasPrefix(key, VerklePrefix): + remain := key[len(VerklePrefix):] + switch { + case IsAccountTrieNode(remain): + verkleTries.Add(size) + case bytes.HasPrefix(remain, stateIDPrefix) && len(remain) == len(stateIDPrefix)+common.HashLength: + verkleStateLookups.Add(size) + case bytes.Equal(remain, persistentStateIDKey): + metadata.Add(size) + case bytes.Equal(remain, trieJournalKey): + metadata.Add(size) + case bytes.Equal(remain, snapSyncStatusFlagKey): + metadata.Add(size) + default: + unaccounted.Add(size) + } default: var accounted bool for _, meta := range [][]byte{ @@ -1143,6 +1165,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { {"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()}, {"Key-Value store", "Path trie account nodes", accountTries.Size(), accountTries.Count()}, {"Key-Value store", "Path trie storage nodes", storageTries.Size(), storageTries.Count()}, + {"Key-Value store", "Verkle trie nodes", verkleTries.Size(), verkleTries.Count()}, + {"Key-Value store", "Verkle trie state lookups", verkleStateLookups.Size(), verkleStateLookups.Count()}, {"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()}, {"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()}, {"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()}, @@ -1213,8 +1237,8 @@ func DeleteTrieState(db ethdb.Database) error { ) prefixKeys := map[string]func([]byte) bool{ - string(trieNodeAccountPrefix): IsAccountTrieNode, - string(trieNodeStoragePrefix): IsStorageTrieNode, + string(TrieNodeAccountPrefix): IsAccountTrieNode, + string(TrieNodeStoragePrefix): IsStorageTrieNode, string(stateIDPrefix): func(key []byte) bool { return len(key) == len(stateIDPrefix)+common.HashLength }, } diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index dbdb7c937e..c442c58a84 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -56,15 +56,13 @@ var ( // freezerTableSize defines the maximum size of freezer data files. const freezerTableSize = 2 * 1000 * 1000 * 1000 -// Freezer is a memory mapped append-only database to store immutable ordered -// data into flat files: +// Freezer is an append-only database to store immutable ordered data into +// flat files: // -// - The append-only nature ensures that disk writes are minimized. -// - The memory mapping ensures we can max out system memory for caching without -// reserving it for go-ethereum. This would also reduce the memory requirements -// of Geth, and thus also GC overhead. +// - The append-only nature ensures that disk writes are minimized. +// - The in-order data ensures that disk reads are always optimized. type Freezer struct { - frozen atomic.Uint64 // Number of blocks already frozen + frozen atomic.Uint64 // Number of items already frozen tail atomic.Uint64 // Number of the first stored item in the freezer // This lock synchronizes writers and the truncate operation, as well as @@ -79,12 +77,6 @@ type Freezer struct { offset uint64 // Starting BlockNumber in current freezer } -// NewChainFreezer is a small utility method around NewFreezer that sets the -// default parameters for the chain storage. -func NewChainFreezer(datadir string, namespace string, readonly bool, offset uint64) (*Freezer, error) { - return NewFreezer(datadir, namespace, readonly, offset, freezerTableSize, chainFreezerNoSnappy) -} - // NewFreezer creates a freezer instance for maintaining immutable ordered // data according to the given parameters. // @@ -192,7 +184,7 @@ func openAdditionTable(datadir, name string, readMeter, writeMeter metrics.Meter return newTable(datadir, name, readMeter, writeMeter, sizeGauge, maxTableSize, disableSnappy, readonly) } -// Close terminates the chain freezer, unmapping all the data files. +// Close terminates the chain freezer, closing all the data files. func (f *Freezer) Close() error { f.writeLock.Lock() defer f.writeLock.Unlock() @@ -551,118 +543,6 @@ func gcKvStore(db ethdb.KeyValueStore, ancients []common.Hash, first uint64, fro log.Info("Deep froze chain segment", context...) } -// convertLegacyFn takes a raw freezer entry in an older format and -// returns it in the new format. -type convertLegacyFn = func([]byte) ([]byte, error) - -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (f *Freezer) MigrateTable(kind string, convert convertLegacyFn) error { - if f.readonly { - return errReadOnly - } - f.writeLock.Lock() - defer f.writeLock.Unlock() - - table, ok := f.tables[kind] - if !ok { - return errUnknownTable - } - // forEach iterates every entry in the table serially and in order, calling `fn` - // with the item as argument. If `fn` returns an error the iteration stops - // and that error will be returned. - forEach := func(t *freezerTable, offset uint64, fn func(uint64, []byte) error) error { - var ( - items = t.items.Load() - batchSize = uint64(1024) - maxBytes = uint64(1024 * 1024) - ) - for i := offset; i < items; { - if i+batchSize > items { - batchSize = items - i - } - data, err := t.RetrieveItems(i, batchSize, maxBytes) - if err != nil { - return err - } - for j, item := range data { - if err := fn(i+uint64(j), item); err != nil { - return err - } - } - i += uint64(len(data)) - } - return nil - } - // TODO(s1na): This is a sanity-check since as of now no process does tail-deletion. But the migration - // process assumes no deletion at tail and needs to be modified to account for that. - if table.itemOffset.Load() > 0 || table.itemHidden.Load() > 0 { - return errors.New("migration not supported for tail-deleted freezers") - } - ancientsPath := filepath.Dir(table.index.Name()) - // Set up new dir for the migrated table, the content of which - // we'll at the end move over to the ancients dir. - migrationPath := filepath.Join(ancientsPath, "migration") - newTable, err := newFreezerTable(migrationPath, kind, table.noCompression, false) - if err != nil { - return err - } - var ( - batch = newTable.newBatch(f.offset) - out []byte - start = time.Now() - logged = time.Now() - offset = newTable.items.Load() - ) - if offset > 0 { - log.Info("found previous migration attempt", "migrated", offset) - } - // Iterate through entries and transform them - if err := forEach(table, offset, func(i uint64, blob []byte) error { - if i%10000 == 0 && time.Since(logged) > 16*time.Second { - log.Info("Processing legacy elements", "count", i, "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } - out, err = convert(blob) - if err != nil { - return err - } - if err := batch.AppendRaw(i, out); err != nil { - return err - } - return nil - }); err != nil { - return err - } - if err := batch.commit(); err != nil { - return err - } - log.Info("Replacing old table files with migrated ones", "elapsed", common.PrettyDuration(time.Since(start))) - // Release and delete old table files. Note this won't - // delete the index file. - table.releaseFilesAfter(0, true) - - if err := newTable.Close(); err != nil { - return err - } - files, err := os.ReadDir(migrationPath) - if err != nil { - return err - } - // Move migrated files to ancients dir. - for _, f := range files { - // This will replace the old index file as a side-effect. - if err := os.Rename(filepath.Join(migrationPath, f.Name()), filepath.Join(ancientsPath, f.Name())); err != nil { - return err - } - } - // Delete by now empty dir. - if err := os.Remove(migrationPath); err != nil { - return err - } - return nil -} - // TruncateTableTail will truncate certain table to new tail func (f *Freezer) TruncateTableTail(kind string, tail uint64) (uint64, error) { if f.readonly { diff --git a/core/rawdb/freezer_memory.go b/core/rawdb/freezer_memory.go new file mode 100644 index 0000000000..7702685ff8 --- /dev/null +++ b/core/rawdb/freezer_memory.go @@ -0,0 +1,447 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +// memoryTable is used to store a list of sequential items in memory. +type memoryTable struct { + name string // Table name + items uint64 // Number of stored items in the table, including the deleted ones + offset uint64 // Number of deleted items from the table + data [][]byte // List of rlp-encoded items, sort in order + size uint64 // Total memory size occupied by the table + lock sync.RWMutex +} + +// newMemoryTable initializes the memory table. +func newMemoryTable(name string) *memoryTable { + return &memoryTable{name: name} +} + +// has returns an indicator whether the specified data exists. +func (t *memoryTable) has(number uint64) bool { + t.lock.RLock() + defer t.lock.RUnlock() + + return number >= t.offset && number < t.items +} + +// retrieve retrieves multiple items in sequence, starting from the index 'start'. +// It will return: +// - at most 'count' items, +// - if maxBytes is specified: at least 1 item (even if exceeding the maxByteSize), +// but will otherwise return as many items as fit into maxByteSize. +// - if maxBytes is not specified, 'count' items will be returned if they are present +func (t *memoryTable) retrieve(start uint64, count, maxBytes uint64) ([][]byte, error) { + t.lock.RLock() + defer t.lock.RUnlock() + + var ( + size uint64 + batch [][]byte + ) + // Ensure the start is written, not deleted from the tail, and that the + // caller actually wants something. + if t.items <= start || t.offset > start || count == 0 { + return nil, errOutOfBounds + } + // Cap the item count if the retrieval is out of bound. + if start+count > t.items { + count = t.items - start + } + for n := start; n < start+count; n++ { + index := n - t.offset + if len(batch) != 0 && maxBytes != 0 && size+uint64(len(t.data[index])) > maxBytes { + return batch, nil + } + batch = append(batch, t.data[index]) + size += uint64(len(t.data[index])) + } + return batch, nil +} + +// truncateHead discards any recent data above the provided threshold number. +func (t *memoryTable) truncateHead(items uint64) error { + t.lock.Lock() + defer t.lock.Unlock() + + // Short circuit if nothing to delete. + if t.items <= items { + return nil + } + if items < t.offset { + return errors.New("truncation below tail") + } + t.data = t.data[:items-t.offset] + t.items = items + return nil +} + +// truncateTail discards any recent data before the provided threshold number. +func (t *memoryTable) truncateTail(items uint64) error { + t.lock.Lock() + defer t.lock.Unlock() + + // Short circuit if nothing to delete. + if t.offset >= items { + return nil + } + if t.items < items { + return errors.New("truncation above head") + } + t.data = t.data[items-t.offset:] + t.offset = items + return nil +} + +// commit merges the given item batch into table. It's presumed that the +// batch is ordered and continuous with table. +func (t *memoryTable) commit(batch [][]byte) error { + t.lock.Lock() + defer t.lock.Unlock() + + for _, item := range batch { + t.size += uint64(len(item)) + } + t.data = append(t.data, batch...) + t.items += uint64(len(batch)) + return nil +} + +// memoryBatch is the singleton batch used for ancient write. +type memoryBatch struct { + data map[string][][]byte + next map[string]uint64 + size map[string]int64 +} + +func newMemoryBatch() *memoryBatch { + return &memoryBatch{ + data: make(map[string][][]byte), + next: make(map[string]uint64), + size: make(map[string]int64), + } +} + +func (b *memoryBatch) reset(freezer *MemoryFreezer) { + b.data = make(map[string][][]byte) + b.next = make(map[string]uint64) + b.size = make(map[string]int64) + + for name, table := range freezer.tables { + b.next[name] = table.items + } +} + +// Append adds an RLP-encoded item. +func (b *memoryBatch) Append(kind string, number uint64, item interface{}) error { + if b.next[kind] != number { + return errOutOrderInsertion + } + blob, err := rlp.EncodeToBytes(item) + if err != nil { + return err + } + b.data[kind] = append(b.data[kind], blob) + b.next[kind]++ + b.size[kind] += int64(len(blob)) + return nil +} + +// AppendRaw adds an item without RLP-encoding it. +func (b *memoryBatch) AppendRaw(kind string, number uint64, blob []byte) error { + if b.next[kind] != number { + return errOutOrderInsertion + } + b.data[kind] = append(b.data[kind], common.CopyBytes(blob)) + b.next[kind]++ + b.size[kind] += int64(len(blob)) + return nil +} + +// commit is called at the end of a write operation and writes all remaining +// data to tables. +func (b *memoryBatch) commit(freezer *MemoryFreezer) (items uint64, writeSize int64, err error) { + // Check that count agrees on all batches. + items = math.MaxUint64 + for name, next := range b.next { + if items < math.MaxUint64 && next != items { + return 0, 0, fmt.Errorf("table %s is at item %d, want %d", name, next, items) + } + items = next + } + // Commit all table batches. + for name, batch := range b.data { + table := freezer.tables[name] + if err := table.commit(batch); err != nil { + return 0, 0, err + } + writeSize += b.size[name] + } + return items, writeSize, nil +} + +// MemoryFreezer is an ephemeral ancient store. It implements the ethdb.AncientStore +// interface and can be used along with ephemeral key-value store. +type MemoryFreezer struct { + items uint64 // Number of items stored + tail uint64 // Number of the first stored item in the freezer + readonly bool // Flag if the freezer is only for reading + lock sync.RWMutex // Lock to protect fields + tables map[string]*memoryTable // Tables for storing everything + writeBatch *memoryBatch // Pre-allocated write batch +} + +// NewMemoryFreezer initializes an in-memory freezer instance. +func NewMemoryFreezer(readonly bool, tableName map[string]bool) *MemoryFreezer { + tables := make(map[string]*memoryTable) + for name := range tableName { + tables[name] = newMemoryTable(name) + } + return &MemoryFreezer{ + writeBatch: newMemoryBatch(), + readonly: readonly, + tables: tables, + } +} + +// HasAncient returns an indicator whether the specified data exists. +func (f *MemoryFreezer) HasAncient(kind string, number uint64) (bool, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + if table := f.tables[kind]; table != nil { + return table.has(number), nil + } + return false, nil +} + +// Ancient retrieves an ancient binary blob from the in-memory freezer. +func (f *MemoryFreezer) Ancient(kind string, number uint64) ([]byte, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + t := f.tables[kind] + if t == nil { + return nil, errUnknownTable + } + data, err := t.retrieve(number, 1, 0) + if err != nil { + return nil, err + } + return data[0], nil +} + +// AncientRange retrieves multiple items in sequence, starting from the index 'start'. +// It will return +// - at most 'count' items, +// - if maxBytes is specified: at least 1 item (even if exceeding the maxByteSize), +// but will otherwise return as many items as fit into maxByteSize. +// - if maxBytes is not specified, 'count' items will be returned if they are present +func (f *MemoryFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + t := f.tables[kind] + if t == nil { + return nil, errUnknownTable + } + return t.retrieve(start, count, maxBytes) +} + +// Ancients returns the ancient item numbers in the freezer. +func (f *MemoryFreezer) Ancients() (uint64, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.items, nil +} + +// ItemAmountInAncient returns the actual length of current freezer. +func (f *MemoryFreezer) ItemAmountInAncient() (uint64, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.items, nil +} + +// Ancients returns the ancient item numbers in the freezer. +func (f *MemoryFreezer) AncientOffSet() uint64 { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.tail +} + +// Tail returns the number of first stored item in the freezer. +// This number can also be interpreted as the total deleted item numbers. +func (f *MemoryFreezer) Tail() (uint64, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.tail, nil +} + +// AncientSize returns the ancient size of the specified category. +func (f *MemoryFreezer) AncientSize(kind string) (uint64, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + if table := f.tables[kind]; table != nil { + return table.size, nil + } + return 0, errUnknownTable +} + +// ReadAncients runs the given read operation while ensuring that no writes take place +// on the underlying freezer. +func (f *MemoryFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) { + f.lock.RLock() + defer f.lock.RUnlock() + + return fn(f) +} + +// ModifyAncients runs the given write operation. +func (f *MemoryFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (writeSize int64, err error) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.readonly { + return 0, errReadOnly + } + // Roll back all tables to the starting position in case of error. + defer func(old uint64) { + if err == nil { + return + } + // The write operation has failed. Go back to the previous item position. + for name, table := range f.tables { + err := table.truncateHead(old) + if err != nil { + log.Error("Freezer table roll-back failed", "table", name, "index", old, "err", err) + } + } + }(f.items) + + // Modify the ancients in batch. + f.writeBatch.reset(f) + if err := fn(f.writeBatch); err != nil { + return 0, err + } + item, writeSize, err := f.writeBatch.commit(f) + if err != nil { + return 0, err + } + f.items = item + return writeSize, nil +} + +// TruncateHead discards any recent data above the provided threshold number. +// It returns the previous head number. +func (f *MemoryFreezer) TruncateHead(items uint64) (uint64, error) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.readonly { + return 0, errReadOnly + } + old := f.items + if old <= items { + return old, nil + } + for _, table := range f.tables { + if err := table.truncateHead(items); err != nil { + return 0, err + } + } + f.items = items + return old, nil +} + +// TruncateTail discards any recent data below the provided threshold number. +func (f *MemoryFreezer) TruncateTail(tail uint64) (uint64, error) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.readonly { + return 0, errReadOnly + } + old := f.tail + if old >= tail { + return old, nil + } + for _, table := range f.tables { + if err := table.truncateTail(tail); err != nil { + return 0, err + } + } + f.tail = tail + return old, nil +} + +// Sync flushes all data tables to disk. +func (f *MemoryFreezer) Sync() error { + return nil +} + +// Close releases all the sources held by the memory freezer. It will panic if +// any following invocation is made to a closed freezer. +func (f *MemoryFreezer) Close() error { + f.lock.Lock() + defer f.lock.Unlock() + + f.tables = nil + f.writeBatch = nil + return nil +} + +// Reset drops all the data cached in the memory freezer and reset itself +// back to default state. +func (f *MemoryFreezer) Reset() error { + f.lock.Lock() + defer f.lock.Unlock() + + tables := make(map[string]*memoryTable) + for name := range f.tables { + tables[name] = newMemoryTable(name) + } + f.tables = tables + f.items, f.tail = 0, 0 + return nil +} + +func (f *MemoryFreezer) TruncateTableTail(kind string, tail uint64) (uint64, error) { + //TODO implement me + panic("implement me") +} + +func (f *MemoryFreezer) ResetTable(kind string, startAt uint64, onlyEmpty bool) error { + //TODO implement me + panic("not supported") +} diff --git a/crypto/bls12381/utils.go b/core/rawdb/freezer_memory_test.go similarity index 54% rename from crypto/bls12381/utils.go rename to core/rawdb/freezer_memory_test.go index de8bf495fe..e71de0f629 100644 --- a/crypto/bls12381/utils.go +++ b/core/rawdb/freezer_memory_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 The go-ethereum Authors +// Copyright 2024 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,32 +14,28 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package bls12381 +package rawdb import ( - "errors" - "math/big" + "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb/ancienttest" + "github.com/ethereum/go-ethereum/ethdb" ) -func bigFromHex(hex string) *big.Int { - return new(big.Int).SetBytes(common.FromHex(hex)) -} - -// decodeFieldElement expects 64 byte input with zero top 16 bytes, -// returns lower 48 bytes. -func decodeFieldElement(in []byte) ([]byte, error) { - if len(in) != 64 { - return nil, errors.New("invalid field element length") - } - // check top bytes - for i := 0; i < 16; i++ { - if in[i] != byte(0x00) { - return nil, errors.New("invalid field element top bytes") +func TestMemoryFreezer(t *testing.T) { + ancienttest.TestAncientSuite(t, func(kinds []string) ethdb.AncientStore { + tables := make(map[string]bool) + for _, kind := range kinds { + tables[kind] = true + } + return NewMemoryFreezer(false, tables) + }) + ancienttest.TestResettableAncientSuite(t, func(kinds []string) ethdb.ResettableAncientStore { + tables := make(map[string]bool) + for _, kind := range kinds { + tables[kind] = true } - } - out := make([]byte, 48) - copy(out[:], in[16:]) - return out, nil + return NewMemoryFreezer(false, tables) + }) } diff --git a/core/rawdb/freezer_meta_test.go b/core/rawdb/freezer_meta_test.go index ba1a95e453..409e811026 100644 --- a/core/rawdb/freezer_meta_test.go +++ b/core/rawdb/freezer_meta_test.go @@ -22,10 +22,11 @@ import ( ) func TestReadWriteFreezerTableMeta(t *testing.T) { - f, err := os.CreateTemp(os.TempDir(), "*") + f, err := os.CreateTemp(t.TempDir(), "*") if err != nil { t.Fatalf("Failed to create file %v", err) } + defer f.Close() err = writeMetadata(f, newMetadata(100)) if err != nil { t.Fatalf("Failed to write metadata %v", err) @@ -43,10 +44,11 @@ func TestReadWriteFreezerTableMeta(t *testing.T) { } func TestInitializeFreezerTableMeta(t *testing.T) { - f, err := os.CreateTemp(os.TempDir(), "*") + f, err := os.CreateTemp(t.TempDir(), "*") if err != nil { t.Fatalf("Failed to create file %v", err) } + defer f.Close() meta, err := loadMetadata(f, uint64(100)) if err != nil { t.Fatalf("Failed to read metadata %v", err) diff --git a/core/rawdb/freezer_resettable.go b/core/rawdb/freezer_resettable.go index dfefc6a45e..388ad4a7a6 100644 --- a/core/rawdb/freezer_resettable.go +++ b/core/rawdb/freezer_resettable.go @@ -30,16 +30,17 @@ const tmpSuffix = ".tmp" // freezerOpenFunc is the function used to open/create a freezer. type freezerOpenFunc = func() (*Freezer, error) -// ResettableFreezer is a wrapper of the freezer which makes the +// resettableFreezer is a wrapper of the freezer which makes the // freezer resettable. -type ResettableFreezer struct { - freezer *Freezer - opener freezerOpenFunc - datadir string - lock sync.RWMutex +type resettableFreezer struct { + readOnly bool + freezer *Freezer + opener freezerOpenFunc + datadir string + lock sync.RWMutex } -// NewResettableFreezer creates a resettable freezer, note freezer is +// newResettableFreezer creates a resettable freezer, note freezer is // only resettable if the passed file directory is exclusively occupied // by the freezer. And also the user-configurable ancient root directory // is **not** supported for reset since it might be a mount and rename @@ -48,7 +49,7 @@ type ResettableFreezer struct { // // The reset function will delete directory atomically and re-create the // freezer from scratch. -func NewResettableFreezer(datadir string, namespace string, readonly bool, offset uint64, maxTableSize uint32, tables map[string]bool) (*ResettableFreezer, error) { +func newResettableFreezer(datadir string, namespace string, readonly bool, offset uint64, maxTableSize uint32, tables map[string]bool) (*resettableFreezer, error) { if err := cleanup(datadir); err != nil { return nil, err } @@ -59,10 +60,11 @@ func NewResettableFreezer(datadir string, namespace string, readonly bool, offse if err != nil { return nil, err } - return &ResettableFreezer{ - freezer: freezer, - opener: opener, - datadir: datadir, + return &resettableFreezer{ + readOnly: readonly, + freezer: freezer, + opener: opener, + datadir: datadir, }, nil } @@ -70,10 +72,13 @@ func NewResettableFreezer(datadir string, namespace string, readonly bool, offse // recreate the freezer from scratch. The atomicity of directory deletion // is guaranteed by the rename operation, the leftover directory will be // cleaned up in next startup in case crash happens after rename. -func (f *ResettableFreezer) Reset() error { +func (f *resettableFreezer) Reset() error { f.lock.Lock() defer f.lock.Unlock() + if f.readOnly { + return errReadOnly + } if err := f.freezer.Close(); err != nil { return err } @@ -93,7 +98,7 @@ func (f *ResettableFreezer) Reset() error { } // Close terminates the chain freezer, unmapping all the data files. -func (f *ResettableFreezer) Close() error { +func (f *resettableFreezer) Close() error { f.lock.RLock() defer f.lock.RUnlock() @@ -102,7 +107,7 @@ func (f *ResettableFreezer) Close() error { // HasAncient returns an indicator whether the specified ancient data exists // in the freezer -func (f *ResettableFreezer) HasAncient(kind string, number uint64) (bool, error) { +func (f *resettableFreezer) HasAncient(kind string, number uint64) (bool, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -110,7 +115,7 @@ func (f *ResettableFreezer) HasAncient(kind string, number uint64) (bool, error) } // Ancient retrieves an ancient binary blob from the append-only immutable files. -func (f *ResettableFreezer) Ancient(kind string, number uint64) ([]byte, error) { +func (f *resettableFreezer) Ancient(kind string, number uint64) ([]byte, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -123,7 +128,7 @@ func (f *ResettableFreezer) Ancient(kind string, number uint64) ([]byte, error) // - if maxBytes is specified: at least 1 item (even if exceeding the maxByteSize), // but will otherwise return as many items as fit into maxByteSize. // - if maxBytes is not specified, 'count' items will be returned if they are present. -func (f *ResettableFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { +func (f *resettableFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -131,7 +136,7 @@ func (f *ResettableFreezer) AncientRange(kind string, start, count, maxBytes uin } // Ancients returns the length of the frozen items. -func (f *ResettableFreezer) Ancients() (uint64, error) { +func (f *resettableFreezer) Ancients() (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -139,7 +144,7 @@ func (f *ResettableFreezer) Ancients() (uint64, error) { } // Tail returns the number of first stored item in the freezer. -func (f *ResettableFreezer) Tail() (uint64, error) { +func (f *resettableFreezer) Tail() (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -147,7 +152,7 @@ func (f *ResettableFreezer) Tail() (uint64, error) { } // AncientSize returns the ancient size of the specified category. -func (f *ResettableFreezer) AncientSize(kind string) (uint64, error) { +func (f *resettableFreezer) AncientSize(kind string) (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -156,7 +161,7 @@ func (f *ResettableFreezer) AncientSize(kind string) (uint64, error) { // ReadAncients runs the given read operation while ensuring that no writes take place // on the underlying freezer. -func (f *ResettableFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) { +func (f *resettableFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) { f.lock.RLock() defer f.lock.RUnlock() @@ -164,7 +169,7 @@ func (f *ResettableFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) ( } // ItemAmountInAncient returns the actual length of current ancientDB. -func (f *ResettableFreezer) ItemAmountInAncient() (uint64, error) { +func (f *resettableFreezer) ItemAmountInAncient() (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -172,7 +177,7 @@ func (f *ResettableFreezer) ItemAmountInAncient() (uint64, error) { } // AncientOffSet returns the offset of current ancientDB. -func (f *ResettableFreezer) AncientOffSet() uint64 { +func (f *resettableFreezer) AncientOffSet() uint64 { f.lock.RLock() defer f.lock.RUnlock() @@ -180,7 +185,7 @@ func (f *ResettableFreezer) AncientOffSet() uint64 { } // ModifyAncients runs the given write operation. -func (f *ResettableFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (writeSize int64, err error) { +func (f *resettableFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (writeSize int64, err error) { f.lock.RLock() defer f.lock.RUnlock() @@ -189,7 +194,7 @@ func (f *ResettableFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) // TruncateHead discards any recent data above the provided threshold number. // It returns the previous head number. -func (f *ResettableFreezer) TruncateHead(items uint64) (uint64, error) { +func (f *resettableFreezer) TruncateHead(items uint64) (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -198,7 +203,7 @@ func (f *ResettableFreezer) TruncateHead(items uint64) (uint64, error) { // TruncateTail discards any recent data below the provided threshold number. // It returns the previous value -func (f *ResettableFreezer) TruncateTail(tail uint64) (uint64, error) { +func (f *resettableFreezer) TruncateTail(tail uint64) (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -206,7 +211,7 @@ func (f *ResettableFreezer) TruncateTail(tail uint64) (uint64, error) { } // TruncateTableTail will truncate certain table to new tail -func (f *ResettableFreezer) TruncateTableTail(kind string, tail uint64) (uint64, error) { +func (f *resettableFreezer) TruncateTableTail(kind string, tail uint64) (uint64, error) { f.lock.RLock() defer f.lock.RUnlock() @@ -214,7 +219,7 @@ func (f *ResettableFreezer) TruncateTableTail(kind string, tail uint64) (uint64, } // ResetTable will reset certain table with new start point -func (f *ResettableFreezer) ResetTable(kind string, startAt uint64, onlyEmpty bool) error { +func (f *resettableFreezer) ResetTable(kind string, startAt uint64, onlyEmpty bool) error { f.lock.RLock() defer f.lock.RUnlock() @@ -222,22 +227,13 @@ func (f *ResettableFreezer) ResetTable(kind string, startAt uint64, onlyEmpty bo } // Sync flushes all data tables to disk. -func (f *ResettableFreezer) Sync() error { +func (f *resettableFreezer) Sync() error { f.lock.RLock() defer f.lock.RUnlock() return f.freezer.Sync() } -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (f *ResettableFreezer) MigrateTable(kind string, convert convertLegacyFn) error { - f.lock.RLock() - defer f.lock.RUnlock() - - return f.freezer.MigrateTable(kind, convert) -} - // cleanup removes the directory located in the specified path // has the name with deletion marker suffix. func cleanup(path string) error { diff --git a/core/rawdb/freezer_resettable_test.go b/core/rawdb/freezer_resettable_test.go index 57eff54fcc..cfd9efb832 100644 --- a/core/rawdb/freezer_resettable_test.go +++ b/core/rawdb/freezer_resettable_test.go @@ -33,7 +33,7 @@ func TestResetFreezer(t *testing.T) { {1, bytes.Repeat([]byte{1}, 2048)}, {2, bytes.Repeat([]byte{2}, 2048)}, } - f, _ := NewResettableFreezer(t.TempDir(), "", false, 0, 2048, freezerTestTableDef) + f, _ := newResettableFreezer(t.TempDir(), "", false, 0, 2048, freezerTestTableDef) defer f.Close() f.ModifyAncients(func(op ethdb.AncientWriteOp) error { @@ -87,7 +87,7 @@ func TestFreezerCleanup(t *testing.T) { {2, bytes.Repeat([]byte{2}, 2048)}, } datadir := t.TempDir() - f, _ := NewResettableFreezer(datadir, "", false, 2048, 0, freezerTestTableDef) + f, _ := newResettableFreezer(datadir, "", false, 2048, 0, freezerTestTableDef) f.ModifyAncients(func(op ethdb.AncientWriteOp) error { for _, item := range items { op.AppendRaw("test", item.id, item.blob) @@ -98,7 +98,7 @@ func TestFreezerCleanup(t *testing.T) { os.Rename(datadir, tmpName(datadir)) // Open the freezer again, trigger cleanup operation - f, _ = NewResettableFreezer(datadir, "", false, 2048, 0, freezerTestTableDef) + f, _ = newResettableFreezer(datadir, "", false, 2048, 0, freezerTestTableDef) f.Close() if _, err := os.Lstat(tmpName(datadir)); !os.IsNotExist(err) { diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go index 3dec88db9c..04e0d7570a 100644 --- a/core/rawdb/freezer_test.go +++ b/core/rawdb/freezer_test.go @@ -22,11 +22,10 @@ import ( "fmt" "math/big" "math/rand" - "os" - "path" "sync" "testing" + "github.com/ethereum/go-ethereum/core/rawdb/ancienttest" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" @@ -275,7 +274,7 @@ func TestFreezerReadonlyValidate(t *testing.T) { } require.NoError(t, f.Close()) - // Re-openening as readonly should fail when validating + // Re-opening as readonly should fail when validating // table lengths. _, err = NewFreezer(dir, "", true, 0, 2049, tables) if err == nil { @@ -479,87 +478,6 @@ func checkAncientCount(t *testing.T, f *Freezer, kind string, n uint64) { } } -func TestRenameWindows(t *testing.T) { - var ( - fname = "file.bin" - fname2 = "file2.bin" - data = []byte{1, 2, 3, 4} - data2 = []byte{2, 3, 4, 5} - data3 = []byte{3, 5, 6, 7} - dataLen = 4 - ) - - // Create 2 temp dirs - dir1 := t.TempDir() - dir2 := t.TempDir() - - // Create file in dir1 and fill with data - f, err := os.Create(path.Join(dir1, fname)) - if err != nil { - t.Fatal(err) - } - f2, err := os.Create(path.Join(dir1, fname2)) - if err != nil { - t.Fatal(err) - } - f3, err := os.Create(path.Join(dir2, fname2)) - if err != nil { - t.Fatal(err) - } - if _, err := f.Write(data); err != nil { - t.Fatal(err) - } - if _, err := f2.Write(data2); err != nil { - t.Fatal(err) - } - if _, err := f3.Write(data3); err != nil { - t.Fatal(err) - } - if err := f.Close(); err != nil { - t.Fatal(err) - } - if err := f2.Close(); err != nil { - t.Fatal(err) - } - if err := f3.Close(); err != nil { - t.Fatal(err) - } - if err := os.Rename(f.Name(), path.Join(dir2, fname)); err != nil { - t.Fatal(err) - } - if err := os.Rename(f2.Name(), path.Join(dir2, fname2)); err != nil { - t.Fatal(err) - } - - // Check file contents - f, err = os.Open(path.Join(dir2, fname)) - if err != nil { - t.Fatal(err) - } - defer f.Close() - defer os.Remove(f.Name()) - buf := make([]byte, dataLen) - if _, err := f.Read(buf); err != nil { - t.Fatal(err) - } - if !bytes.Equal(buf, data) { - t.Errorf("unexpected file contents. Got %v\n", buf) - } - - f, err = os.Open(path.Join(dir2, fname2)) - if err != nil { - t.Fatal(err) - } - defer f.Close() - defer os.Remove(f.Name()) - if _, err := f.Read(buf); err != nil { - t.Fatal(err) - } - if !bytes.Equal(buf, data2) { - t.Errorf("unexpected file contents. Got %v\n", buf) - } -} - func TestFreezerCloseSync(t *testing.T) { t.Parallel() f, _ := newFreezerForTesting(t, map[string]bool{"a": true, "b": true}) @@ -581,3 +499,22 @@ func TestFreezerCloseSync(t *testing.T) { t.Fatalf("want %v, have %v", have, want) } } + +func TestFreezerSuite(t *testing.T) { + ancienttest.TestAncientSuite(t, func(kinds []string) ethdb.AncientStore { + tables := make(map[string]bool) + for _, kind := range kinds { + tables[kind] = true + } + f, _ := newFreezerForTesting(t, tables) + return f + }) + ancienttest.TestResettableAncientSuite(t, func(kinds []string) ethdb.ResettableAncientStore { + tables := make(map[string]bool) + for _, kind := range kinds { + tables[kind] = true + } + f, _ := newResettableFreezer(t.TempDir(), "", false, 2048, tables) + return f + }) +} diff --git a/core/rawdb/prunedfreezer.go b/core/rawdb/prunedfreezer.go index c772ca7630..122f8fe267 100644 --- a/core/rawdb/prunedfreezer.go +++ b/core/rawdb/prunedfreezer.go @@ -155,12 +155,6 @@ func (f *prunedfreezer) AncientOffSet() uint64 { return atomic.LoadUint64(&f.frozen) } -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (f *prunedfreezer) MigrateTable(kind string, convert convertLegacyFn) error { - return errNotSupported -} - // AncientDatadir returns an error as we don't have a backing chain freezer. func (f *prunedfreezer) AncientDatadir() (string, error) { return "", errNotSupported diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index b7075733d8..36fdc9a4a3 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -130,10 +130,17 @@ var ( diffLayerPrefix = []byte("d") // diffLayerPrefix + hash -> diffLayer // Path-based storage scheme of merkle patricia trie. - trieNodeAccountPrefix = []byte("A") // trieNodeAccountPrefix + hexPath -> trie node - trieNodeStoragePrefix = []byte("O") // trieNodeStoragePrefix + accountHash + hexPath -> trie node + TrieNodeAccountPrefix = []byte("A") // TrieNodeAccountPrefix + hexPath -> trie node + TrieNodeStoragePrefix = []byte("O") // TrieNodeStoragePrefix + accountHash + hexPath -> trie node stateIDPrefix = []byte("L") // stateIDPrefix + state root -> state id + // VerklePrefix is the database prefix for Verkle trie data, which includes: + // (a) Trie nodes + // (b) In-memory trie node journal + // (c) Persistent state ID + // (d) State ID lookups, etc. + VerklePrefix = []byte("v") + PreimagePrefix = []byte("secure-key-") // PreimagePrefix + hash -> preimage configPrefix = []byte("ethereum-config-") // config prefix for the db genesisPrefix = []byte("ethereum-genesis-") // genesis state prefix for the db @@ -286,15 +293,15 @@ func stateIDKey(root common.Hash) []byte { return append(stateIDPrefix, root.Bytes()...) } -// accountTrieNodeKey = trieNodeAccountPrefix + nodePath. +// accountTrieNodeKey = TrieNodeAccountPrefix + nodePath. func accountTrieNodeKey(path []byte) []byte { - return append(trieNodeAccountPrefix, path...) + return append(TrieNodeAccountPrefix, path...) } -// storageTrieNodeKey = trieNodeStoragePrefix + accountHash + nodePath. +// storageTrieNodeKey = TrieNodeStoragePrefix + accountHash + nodePath. func storageTrieNodeKey(accountHash common.Hash, path []byte) []byte { - buf := make([]byte, len(trieNodeStoragePrefix)+common.HashLength+len(path)) - n := copy(buf, trieNodeStoragePrefix) + buf := make([]byte, len(TrieNodeStoragePrefix)+common.HashLength+len(path)) + n := copy(buf, TrieNodeStoragePrefix) n += copy(buf[n:], accountHash.Bytes()) copy(buf[n:], path) return buf @@ -315,16 +322,16 @@ func IsLegacyTrieNode(key []byte, val []byte) bool { // account trie node in path-based state scheme, and returns the resolved // node path if so. func ResolveAccountTrieNodeKey(key []byte) (bool, []byte) { - if !bytes.HasPrefix(key, trieNodeAccountPrefix) { + if !bytes.HasPrefix(key, TrieNodeAccountPrefix) { return false, nil } // The remaining key should only consist a hex node path // whose length is in the range 0 to 64 (64 is excluded // since leaves are always wrapped with shortNode). - if len(key) >= len(trieNodeAccountPrefix)+common.HashLength*2 { + if len(key) >= len(TrieNodeAccountPrefix)+common.HashLength*2 { return false, nil } - return true, key[len(trieNodeAccountPrefix):] + return true, key[len(TrieNodeAccountPrefix):] } // IsAccountTrieNode reports whether a provided database entry is an account @@ -338,20 +345,20 @@ func IsAccountTrieNode(key []byte) bool { // trie node in path-based state scheme, and returns the resolved account hash // and node path if so. func ResolveStorageTrieNode(key []byte) (bool, common.Hash, []byte) { - if !bytes.HasPrefix(key, trieNodeStoragePrefix) { + if !bytes.HasPrefix(key, TrieNodeStoragePrefix) { return false, common.Hash{}, nil } // The remaining key consists of 2 parts: // - 32 bytes account hash // - hex node path whose length is in the range 0 to 64 - if len(key) < len(trieNodeStoragePrefix)+common.HashLength { + if len(key) < len(TrieNodeStoragePrefix)+common.HashLength { return false, common.Hash{}, nil } - if len(key) >= len(trieNodeStoragePrefix)+common.HashLength+common.HashLength*2 { + if len(key) >= len(TrieNodeStoragePrefix)+common.HashLength+common.HashLength*2 { return false, common.Hash{}, nil } - accountHash := common.BytesToHash(key[len(trieNodeStoragePrefix) : len(trieNodeStoragePrefix)+common.HashLength]) - return true, accountHash, key[len(trieNodeStoragePrefix)+common.HashLength:] + accountHash := common.BytesToHash(key[len(TrieNodeStoragePrefix) : len(TrieNodeStoragePrefix)+common.HashLength]) + return true, accountHash, key[len(TrieNodeStoragePrefix)+common.HashLength:] } // IsStorageTrieNode reports whether a provided database entry is a storage diff --git a/core/rawdb/table.go b/core/rawdb/table.go index 7fc182b7c5..8df61abaed 100644 --- a/core/rawdb/table.go +++ b/core/rawdb/table.go @@ -153,12 +153,6 @@ func (t *table) Sync() error { return t.db.Sync() } -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (t *table) MigrateTable(kind string, convert convertLegacyFn) error { - return t.db.MigrateTable(kind, convert) -} - // AncientDatadir returns the ancient datadir of the underlying database. func (t *table) AncientDatadir() (string, error) { return t.db.AncientDatadir() @@ -187,9 +181,9 @@ func (t *table) NewIterator(prefix []byte, start []byte) ethdb.Iterator { } } -// Stat returns a particular internal stat of the database. -func (t *table) Stat(property string) (string, error) { - return t.db.Stat(property) +// Stat returns the statistic data of the database. +func (t *table) Stat() (string, error) { + return t.db.Stat() } // Compact flattens the underlying data store for the given key range. In essence, @@ -264,13 +258,6 @@ func (t *table) NewBatchWithSize(size int) ethdb.Batch { return &tableBatch{t.db.NewBatchWithSize(size), t.prefix} } -// NewSnapshot creates a database snapshot based on the current state. -// The created snapshot will not be affected by all following mutations -// happened on the database. -func (t *table) NewSnapshot() (ethdb.Snapshot, error) { - return t.db.NewSnapshot() -} - func (t *table) SetupFreezerEnv(env *ethdb.FreezerEnv) error { return nil } diff --git a/core/state/access_events.go b/core/state/access_events.go new file mode 100644 index 0000000000..7f67df64eb --- /dev/null +++ b/core/state/access_events.go @@ -0,0 +1,291 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "maps" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/utils" + "github.com/holiman/uint256" +) + +// mode specifies how a tree location has been accessed +// for the byte value: +// * the first bit is set if the branch has been read +// * the second bit is set if the branch has been edited +type mode byte + +const ( + AccessWitnessReadFlag = mode(1) + AccessWitnessWriteFlag = mode(2) +) + +var zeroTreeIndex uint256.Int + +// AccessEvents lists the locations of the state that are being accessed +// during the production of a block. +type AccessEvents struct { + branches map[branchAccessKey]mode + chunks map[chunkAccessKey]mode + + pointCache *utils.PointCache +} + +func NewAccessEvents(pointCache *utils.PointCache) *AccessEvents { + return &AccessEvents{ + branches: make(map[branchAccessKey]mode), + chunks: make(map[chunkAccessKey]mode), + pointCache: pointCache, + } +} + +// Merge is used to merge the access events that were generated during the +// execution of a tx, with the accumulation of all access events that were +// generated during the execution of all txs preceding this one in a block. +func (ae *AccessEvents) Merge(other *AccessEvents) { + for k := range other.branches { + ae.branches[k] |= other.branches[k] + } + for k, chunk := range other.chunks { + ae.chunks[k] |= chunk + } +} + +// Keys returns, predictably, the list of keys that were touched during the +// buildup of the access witness. +func (ae *AccessEvents) Keys() [][]byte { + // TODO: consider if parallelizing this is worth it, probably depending on len(ae.chunks). + keys := make([][]byte, 0, len(ae.chunks)) + for chunk := range ae.chunks { + basePoint := ae.pointCache.Get(chunk.addr[:]) + key := utils.GetTreeKeyWithEvaluatedAddress(basePoint, &chunk.treeIndex, chunk.leafKey) + keys = append(keys, key) + } + return keys +} + +func (ae *AccessEvents) Copy() *AccessEvents { + cpy := &AccessEvents{ + branches: maps.Clone(ae.branches), + chunks: maps.Clone(ae.chunks), + pointCache: ae.pointCache, + } + return cpy +} + +// AddAccount returns the gas to be charged for each of the currently cold +// member fields of an account. +func (ae *AccessEvents) AddAccount(addr common.Address, isWrite bool) uint64 { + var gas uint64 + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite) + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite) + return gas +} + +// MessageCallGas returns the gas to be charged for each of the currently +// cold member fields of an account, that need to be touched when making a message +// call to that account. +func (ae *AccessEvents) MessageCallGas(destination common.Address) uint64 { + var gas uint64 + gas += ae.touchAddressAndChargeGas(destination, zeroTreeIndex, utils.BasicDataLeafKey, false) + return gas +} + +// ValueTransferGas returns the gas to be charged for each of the currently +// cold balance member fields of the caller and the callee accounts. +func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address) uint64 { + var gas uint64 + gas += ae.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, utils.BasicDataLeafKey, true) + gas += ae.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BasicDataLeafKey, true) + return gas +} + +// ContractCreateCPreheck charges access costs before +// a contract creation is initiated. It is just reads, because the +// address collision is done before the transfer, and so no write +// are guaranteed to happen at this point. +func (ae *AccessEvents) ContractCreatePreCheckGas(addr common.Address) uint64 { + var gas uint64 + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, false) + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, false) + return gas +} + +// ContractCreateInitGas returns the access gas costs for the initialization of +// a contract creation. +func (ae *AccessEvents) ContractCreateInitGas(addr common.Address) uint64 { + var gas uint64 + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, true) + gas += ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, true) + return gas +} + +// AddTxOrigin adds the member fields of the sender account to the access event list, +// so that cold accesses are not charged, since they are covered by the 21000 gas. +func (ae *AccessEvents) AddTxOrigin(originAddr common.Address) { + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.BasicDataLeafKey, true) + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.CodeHashLeafKey, false) +} + +// AddTxDestination adds the member fields of the sender account to the access event list, +// so that cold accesses are not charged, since they are covered by the 21000 gas. +func (ae *AccessEvents) AddTxDestination(addr common.Address, sendsValue bool) { + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, sendsValue) + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, false) +} + +// SlotGas returns the amount of gas to be charged for a cold storage access. +func (ae *AccessEvents) SlotGas(addr common.Address, slot common.Hash, isWrite bool) uint64 { + treeIndex, subIndex := utils.StorageIndex(slot.Bytes()) + return ae.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite) +} + +// touchAddressAndChargeGas adds any missing access event to the access event list, and returns the cold +// access cost to be charged, if need be. +func (ae *AccessEvents) touchAddressAndChargeGas(addr common.Address, treeIndex uint256.Int, subIndex byte, isWrite bool) uint64 { + stemRead, selectorRead, stemWrite, selectorWrite, selectorFill := ae.touchAddress(addr, treeIndex, subIndex, isWrite) + + var gas uint64 + if stemRead { + gas += params.WitnessBranchReadCost + } + if selectorRead { + gas += params.WitnessChunkReadCost + } + if stemWrite { + gas += params.WitnessBranchWriteCost + } + if selectorWrite { + gas += params.WitnessChunkWriteCost + } + if selectorFill { + gas += params.WitnessChunkFillCost + } + return gas +} + +// touchAddress adds any missing access event to the access event list. +func (ae *AccessEvents) touchAddress(addr common.Address, treeIndex uint256.Int, subIndex byte, isWrite bool) (bool, bool, bool, bool, bool) { + branchKey := newBranchAccessKey(addr, treeIndex) + chunkKey := newChunkAccessKey(branchKey, subIndex) + + // Read access. + var branchRead, chunkRead bool + if _, hasStem := ae.branches[branchKey]; !hasStem { + branchRead = true + ae.branches[branchKey] = AccessWitnessReadFlag + } + if _, hasSelector := ae.chunks[chunkKey]; !hasSelector { + chunkRead = true + ae.chunks[chunkKey] = AccessWitnessReadFlag + } + + // Write access. + var branchWrite, chunkWrite, chunkFill bool + if isWrite { + if (ae.branches[branchKey] & AccessWitnessWriteFlag) == 0 { + branchWrite = true + ae.branches[branchKey] |= AccessWitnessWriteFlag + } + + chunkValue := ae.chunks[chunkKey] + if (chunkValue & AccessWitnessWriteFlag) == 0 { + chunkWrite = true + ae.chunks[chunkKey] |= AccessWitnessWriteFlag + } + // TODO: charge chunk filling costs if the leaf was previously empty in the state + } + return branchRead, chunkRead, branchWrite, chunkWrite, chunkFill +} + +type branchAccessKey struct { + addr common.Address + treeIndex uint256.Int +} + +func newBranchAccessKey(addr common.Address, treeIndex uint256.Int) branchAccessKey { + var sk branchAccessKey + sk.addr = addr + sk.treeIndex = treeIndex + return sk +} + +type chunkAccessKey struct { + branchAccessKey + leafKey byte +} + +func newChunkAccessKey(branchKey branchAccessKey, leafKey byte) chunkAccessKey { + var lk chunkAccessKey + lk.branchAccessKey = branchKey + lk.leafKey = leafKey + return lk +} + +// CodeChunksRangeGas is a helper function to touch every chunk in a code range and charge witness gas costs +func (ae *AccessEvents) CodeChunksRangeGas(contractAddr common.Address, startPC, size uint64, codeLen uint64, isWrite bool) uint64 { + // note that in the case where the copied code is outside the range of the + // contract code but touches the last leaf with contract code in it, + // we don't include the last leaf of code in the AccessWitness. The + // reason that we do not need the last leaf is the account's code size + // is already in the AccessWitness so a stateless verifier can see that + // the code from the last leaf is not needed. + if (codeLen == 0 && size == 0) || startPC > codeLen { + return 0 + } + + endPC := startPC + size + if endPC > codeLen { + endPC = codeLen + } + if endPC > 0 { + endPC -= 1 // endPC is the last bytecode that will be touched. + } + + var statelessGasCharged uint64 + for chunkNumber := startPC / 31; chunkNumber <= endPC/31; chunkNumber++ { + treeIndex := *uint256.NewInt((chunkNumber + 128) / 256) + subIndex := byte((chunkNumber + 128) % 256) + gas := ae.touchAddressAndChargeGas(contractAddr, treeIndex, subIndex, isWrite) + var overflow bool + statelessGasCharged, overflow = math.SafeAdd(statelessGasCharged, gas) + if overflow { + panic("overflow when adding gas") + } + } + return statelessGasCharged +} + +// BasicDataGas adds the account's basic data to the accessed data, and returns the +// amount of gas that it costs. +// Note that an access in write mode implies an access in read mode, whereas an +// access in read mode does not imply an access in write mode. +func (ae *AccessEvents) BasicDataGas(addr common.Address, isWrite bool) uint64 { + return ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite) +} + +// CodeHashGas adds the account's code hash to the accessed data, and returns the +// amount of gas that it costs. +// in write mode. If false, the charged gas corresponds to an access in read mode. +// Note that an access in write mode implies an access in read mode, whereas an access in +// read mode does not imply an access in write mode. +func (ae *AccessEvents) CodeHashGas(addr common.Address, isWrite bool) uint64 { + return ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite) +} diff --git a/core/state/access_events_test.go b/core/state/access_events_test.go new file mode 100644 index 0000000000..10630b3181 --- /dev/null +++ b/core/state/access_events_test.go @@ -0,0 +1,141 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/utils" +) + +var ( + testAddr [20]byte + testAddr2 [20]byte +) + +func init() { + for i := byte(0); i < 20; i++ { + testAddr[i] = i + testAddr[2] = 2 * i + } +} + +func TestAccountHeaderGas(t *testing.T) { + ae := NewAccessEvents(utils.NewPointCache(1024)) + + // Check cold read cost + gas := ae.BasicDataGas(testAddr, false) + if want := params.WitnessBranchReadCost + params.WitnessChunkReadCost; gas != want { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) + } + + // Check warm read cost + gas = ae.BasicDataGas(testAddr, false) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } + + // Check cold read costs in the same group no longer incur the branch read cost + gas = ae.CodeHashGas(testAddr, false) + if gas != params.WitnessChunkReadCost { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) + } + + // Check cold write cost + gas = ae.BasicDataGas(testAddr, true) + if want := params.WitnessBranchWriteCost + params.WitnessChunkWriteCost; gas != want { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) + } + + // Check warm write cost + gas = ae.BasicDataGas(testAddr, true) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } + + // Check a write without a read charges both read and write costs + gas = ae.BasicDataGas(testAddr2, true) + if want := params.WitnessBranchReadCost + params.WitnessBranchWriteCost + params.WitnessChunkWriteCost + params.WitnessChunkReadCost; gas != want { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) + } + + // Check that a write followed by a read charges nothing + gas = ae.BasicDataGas(testAddr2, false) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } + + // Check that reading a slot from the account header only charges the + // chunk read cost. + gas = ae.SlotGas(testAddr, common.Hash{}, false) + if gas != params.WitnessChunkReadCost { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) + } +} + +// TestContractCreateInitGas checks that the gas cost of contract creation is correctly +// calculated. +func TestContractCreateInitGas(t *testing.T) { + ae := NewAccessEvents(utils.NewPointCache(1024)) + + var testAddr [20]byte + for i := byte(0); i < 20; i++ { + testAddr[i] = i + } + + // Check cold read cost, without a value + gas := ae.ContractCreateInitGas(testAddr) + if want := params.WitnessBranchWriteCost + params.WitnessBranchReadCost + 2*params.WitnessChunkWriteCost + 2*params.WitnessChunkReadCost; gas != want { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) + } + + // Check warm read cost + gas = ae.ContractCreateInitGas(testAddr) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } +} + +// TestMessageCallGas checks that the gas cost of message calls is correctly +// calculated. +func TestMessageCallGas(t *testing.T) { + ae := NewAccessEvents(utils.NewPointCache(1024)) + + // Check cold read cost, without a value + gas := ae.MessageCallGas(testAddr) + if want := params.WitnessBranchReadCost + params.WitnessChunkReadCost; gas != want { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) + } + + // Check that reading the basic data and code hash of the same account does not incur the branch read cost + gas = ae.BasicDataGas(testAddr, false) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } + gas = ae.CodeHashGas(testAddr, false) + if gas != params.WitnessChunkReadCost { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } + + // Check warm read cost + gas = ae.MessageCallGas(testAddr) + if gas != 0 { + t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + } +} diff --git a/core/state/access_list.go b/core/state/access_list.go index 4194691345..90e5590748 100644 --- a/core/state/access_list.go +++ b/core/state/access_list.go @@ -17,6 +17,11 @@ package state import ( + "fmt" + "maps" + "slices" + "strings" + "github.com/ethereum/go-ethereum/common" ) @@ -55,18 +60,12 @@ func newAccessList() *accessList { } // Copy creates an independent copy of an accessList. -func (a *accessList) Copy() *accessList { +func (al *accessList) Copy() *accessList { cp := newAccessList() - for k, v := range a.addresses { - cp.addresses[k] = v - } - cp.slots = make([]map[common.Hash]struct{}, len(a.slots)) - for i, slotMap := range a.slots { - newSlotmap := make(map[common.Hash]struct{}, len(slotMap)) - for k := range slotMap { - newSlotmap[k] = struct{}{} - } - cp.slots[i] = newSlotmap + cp.addresses = maps.Clone(al.addresses) + cp.slots = make([]map[common.Hash]struct{}, len(al.slots)) + for i, slotMap := range al.slots { + cp.slots[i] = maps.Clone(slotMap) } return cp } @@ -134,3 +133,35 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) { func (al *accessList) DeleteAddress(address common.Address) { delete(al.addresses, address) } + +// Equal returns true if the two access lists are identical +func (al *accessList) Equal(other *accessList) bool { + if !maps.Equal(al.addresses, other.addresses) { + return false + } + return slices.EqualFunc(al.slots, other.slots, + func(m map[common.Hash]struct{}, m2 map[common.Hash]struct{}) bool { + return maps.Equal(m, m2) + }) +} + +// PrettyPrint prints the contents of the access list in a human-readable form +func (al *accessList) PrettyPrint() string { + out := new(strings.Builder) + var sortedAddrs []common.Address + for addr := range al.addresses { + sortedAddrs = append(sortedAddrs, addr) + } + slices.SortFunc(sortedAddrs, common.Address.Cmp) + for _, addr := range sortedAddrs { + idx := al.addresses[addr] + fmt.Fprintf(out, "%#x : (idx %d)\n", addr, idx) + if idx >= 0 { + slotmap := al.slots[idx] + for h := range slotmap { + fmt.Fprintf(out, " %#x\n", h) + } + } + } + return out.String() +} diff --git a/core/state/database.go b/core/state/database.go index cae5f46ac2..e1de50c596 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -20,10 +20,10 @@ import ( "errors" "fmt" - "github.com/crate-crypto/go-ipa/banderwagon" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -40,38 +40,38 @@ const ( // Cache size granted for caching clean code. codeCacheSize = 64 * 1024 * 1024 - // commitmentSize is the size of commitment stored in cache. - commitmentSize = banderwagon.UncompressedSize - - // Cache item granted for caching commitment results. - commitmentCacheItems = 64 * 1024 * 1024 / (commitmentSize + common.AddressLength) + // Number of address->curve point associations to keep. + pointCacheSize = 4096 ) // Database wraps access to tries and contract code. type Database interface { + // Reader returns a state reader associated with the specified state root. + Reader(root common.Hash) (Reader, error) + // OpenTrie opens the main account trie. OpenTrie(root common.Hash) (Trie, error) // OpenStorageTrie opens the storage trie of an account. OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error) - // CopyTrie returns an independent copy of the given trie. - CopyTrie(Trie) Trie - // ContractCode retrieves a particular contract's code. ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) // ContractCodeSize retrieves a particular contracts code's size. ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) - // DiskDB returns the underlying key-value disk database. - DiskDB() ethdb.KeyValueStore + // PointCache returns the cache holding points used in verkle tree key computation + PointCache() *utils.PointCache // TrieDB returns the underlying trie database for managing trie nodes. TrieDB() *triedb.Database // NoTries returns whether the database has tries storage. NoTries() bool + + // Snapshot returns the underlying state snapshot. + Snapshot() *snapshot.Tree } // Trie is a Ethereum Merkle Patricia trie. @@ -98,7 +98,7 @@ type Trie interface { // UpdateAccount abstracts an account write to the trie. It encodes the // provided account object with associated algorithm and then updates it // in the trie with provided address. - UpdateAccount(address common.Address, account *types.StateAccount) error + UpdateAccount(address common.Address, account *types.StateAccount, codeLen int) error // UpdateStorage associates key with value in the trie. If value has length zero, // any existing value is deleted from the trie. The value bytes must not be modified @@ -127,7 +127,11 @@ type Trie interface { // The returned nodeset can be nil if the trie is clean(nothing to commit). // Once the trie is committed, it's not usable anymore. A new trie must // be created with new root and updated trie database for following usage - Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) + Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) + + // Witness returns a set containing all trie nodes that have been accessed. + // The returned map could be nil if the witness is empty. + Witness() map[string]struct{} // NodeIterator returns an iterator that returns nodes of the trie. Iteration // starts at the key after the given start key. And error will be returned @@ -142,58 +146,76 @@ type Trie interface { // nodes of the longest existing prefix of the key (at least the root), ending // with the node that proves the absence of the key. Prove(key []byte, proofDb ethdb.KeyValueWriter) error -} -// NewDatabase creates a backing store for state. The returned database is safe for -// concurrent use, but does not retain any recent trie nodes in memory. To keep some -// historical state in memory, use the NewDatabaseWithConfig constructor. -func NewDatabase(db ethdb.Database) Database { - return NewDatabaseWithConfig(db, nil) + // IsVerkle returns true if the trie is verkle-tree based + IsVerkle() bool } -// NewDatabaseWithConfig creates a backing store for state. The returned database -// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a -// large memory cache. -func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database { - noTries := config != nil && config.NoTries - - return &cachingDB{ - disk: db, - codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), - triedb: triedb.NewDatabase(db, config), - noTries: noTries, - } +// CachingDB is an implementation of Database interface. It leverages both trie and +// state snapshot to provide functionalities for state access. It's meant to be a +// long-live object and has a few caches inside for sharing between blocks. +type CachingDB struct { + disk ethdb.KeyValueStore + triedb *triedb.Database + noTries bool + snap *snapshot.Tree + codeCache *lru.SizeConstrainedCache[common.Hash, []byte] + codeSizeCache *lru.Cache[common.Hash, int] + pointCache *utils.PointCache } -// NewDatabaseWithNodeDB creates a state database with an already initialized node database. -func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database { +// NewDatabase creates a state database with the provided data sources. +func NewDatabase(triedb *triedb.Database, snap *snapshot.Tree) *CachingDB { noTries := triedb != nil && triedb.Config() != nil && triedb.Config().NoTries - return &cachingDB{ - disk: db, - codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), + return &CachingDB{ + disk: triedb.Disk(), triedb: triedb, noTries: noTries, + snap: snap, + codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), + codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), + pointCache: utils.NewPointCache(pointCacheSize), } } -type cachingDB struct { - disk ethdb.KeyValueStore - codeSizeCache *lru.Cache[common.Hash, int] - codeCache *lru.SizeConstrainedCache[common.Hash, []byte] - triedb *triedb.Database - noTries bool +// NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching +// db by using an ephemeral memory db with default config for testing. +func NewDatabaseForTesting() *CachingDB { + return NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) +} + +// Reader returns a state reader associated with the specified state root. +func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { + var readers []Reader + + // Set up the state snapshot reader if available. This feature + // is optional and may be partially useful if it's not fully + // generated. + if db.snap != nil { + sr, err := newStateReader(stateRoot, db.snap) + if err == nil { + readers = append(readers, sr) // snap reader is optional + } + } + // Set up the trie reader, which is expected to always be available + // as the gatekeeper unless the state is corrupted. + tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache) + if err != nil { + return nil, err + } + readers = append(readers, tr) + + return newMultiReader(readers...) } // OpenTrie opens the main account trie at a specific root hash. -func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { +func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { if db.noTries { return trie.NewEmptyTrie(), nil } if db.triedb.IsVerkle() { - return trie.NewVerkleTrie(root, db.triedb, utils.NewPointCache(commitmentCacheItems)) + return trie.NewVerkleTrie(root, db.triedb, db.pointCache) } tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) if err != nil { @@ -203,7 +225,7 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { } // OpenStorageTrie opens the storage trie of an account. -func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { +func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { if db.noTries { return trie.NewEmptyTrie(), nil } @@ -221,27 +243,12 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre return tr, nil } -func (db *cachingDB) NoTries() bool { +func (db *CachingDB) NoTries() bool { return db.noTries } -// CopyTrie returns an independent copy of the given trie. -func (db *cachingDB) CopyTrie(t Trie) Trie { - if t == nil { - return nil - } - switch t := t.(type) { - case *trie.StateTrie: - return t.Copy() - case *trie.EmptyTrie: - return t.Copy() - default: - panic(fmt.Errorf("unknown trie type %T", t)) - } -} - // ContractCode retrieves a particular contract's code. -func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) { +func (db *CachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) { code, _ := db.codeCache.Get(codeHash) if len(code) > 0 { return code, nil @@ -258,7 +265,7 @@ func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) // ContractCodeWithPrefix retrieves a particular contract's code. If the // code can't be found in the cache, then check the existence with **new** // db scheme. -func (db *cachingDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) { +func (db *CachingDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) { code, _ := db.codeCache.Get(codeHash) if len(code) > 0 { return code, nil @@ -273,7 +280,7 @@ func (db *cachingDB) ContractCodeWithPrefix(address common.Address, codeHash com } // ContractCodeSize retrieves a particular contracts code's size. -func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) { +func (db *CachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) { if cached, ok := db.codeSizeCache.Get(codeHash); ok { return cached, nil } @@ -281,12 +288,31 @@ func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) return len(code), err } -// DiskDB returns the underlying key-value disk database. -func (db *cachingDB) DiskDB() ethdb.KeyValueStore { - return db.disk -} - // TrieDB retrieves any intermediate trie-node caching layer. -func (db *cachingDB) TrieDB() *triedb.Database { +func (db *CachingDB) TrieDB() *triedb.Database { return db.triedb } + +// PointCache returns the cache of evaluated curve points. +func (db *CachingDB) PointCache() *utils.PointCache { + return db.pointCache +} + +// Snapshot returns the underlying state snapshot. +func (db *CachingDB) Snapshot() *snapshot.Tree { + return db.snap +} + +// mustCopyTrie returns a deep-copied trie. +func mustCopyTrie(t Trie) Trie { + switch t := t.(type) { + case *trie.StateTrie: + return t.Copy() + case *trie.EmptyTrie: + return t.Copy() + case *trie.VerkleTrie: + return t.Copy() + default: + panic(fmt.Errorf("unknown trie type %T", t)) + } +} diff --git a/core/state/iterator.go b/core/state/iterator.go index dc84ce689b..83c552ca1a 100644 --- a/core/state/iterator.go +++ b/core/state/iterator.go @@ -46,7 +46,7 @@ type nodeIterator struct { Error error // Failure set in case of an internal error in the iterator } -// newNodeIterator creates an post-order state node iterator. +// newNodeIterator creates a post-order state node iterator. func newNodeIterator(state *StateDB) *nodeIterator { return &nodeIterator{ state: state, diff --git a/core/state/iterator_test.go b/core/state/iterator_test.go index 73cc22490b..26456d7a89 100644 --- a/core/state/iterator_test.go +++ b/core/state/iterator_test.go @@ -35,7 +35,7 @@ func testNodeIteratorCoverage(t *testing.T, scheme string) { db, sdb, ndb, root, _ := makeTestState(scheme) ndb.Commit(root, false) - state, err := New(root, sdb, nil) + state, err := New(root, sdb) if err != nil { t.Fatalf("failed to create state trie at %x: %v", root, err) } diff --git a/core/state/journal.go b/core/state/journal.go index 198c8da554..70b6be07a1 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -17,10 +17,21 @@ package state import ( + "fmt" + "maps" + "slices" + "sort" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" ) +type revision struct { + id int + journalIndex int +} + // journalEntry is a modification entry in the state change journal that can be // reverted on demand. type journalEntry interface { @@ -29,6 +40,9 @@ type journalEntry interface { // dirtied returns the Ethereum address modified by this journal entry. dirtied() *common.Address + + // copy returns a deep-copied journal entry. + copy() journalEntry } // journal contains the list of state modifications applied since the last state @@ -37,6 +51,9 @@ type journalEntry interface { type journal struct { entries []journalEntry // Current changes tracked by the journal dirties map[common.Address]int // Dirty accounts and the number of changes + + validRevisions []revision + nextRevisionId int } // newJournal creates a new initialized journal. @@ -47,6 +64,40 @@ func newJournal() *journal { } } +// reset clears the journal, after this operation the journal can be used anew. +// It is semantically similar to calling 'newJournal', but the underlying slices +// can be reused. +func (j *journal) reset() { + j.entries = j.entries[:0] + j.validRevisions = j.validRevisions[:0] + clear(j.dirties) + j.nextRevisionId = 0 +} + +// snapshot returns an identifier for the current revision of the state. +func (j *journal) snapshot() int { + id := j.nextRevisionId + j.nextRevisionId++ + j.validRevisions = append(j.validRevisions, revision{id, j.length()}) + return id +} + +// revertToSnapshot reverts all state changes made since the given revision. +func (j *journal) revertToSnapshot(revid int, s *StateDB) { + // Find the snapshot in the stack of valid snapshots. + idx := sort.Search(len(j.validRevisions), func(i int) bool { + return j.validRevisions[i].id >= revid + }) + if idx == len(j.validRevisions) || j.validRevisions[idx].id != revid { + panic(fmt.Errorf("revision id %v cannot be reverted", revid)) + } + snapshot := j.validRevisions[idx].journalIndex + + // Replay the journal to undo changes and remove invalidated snapshots + j.revert(s, snapshot) + j.validRevisions = j.validRevisions[:idx] +} + // append inserts a new modification entry to the end of the change journal. func (j *journal) append(entry journalEntry) { j.entries = append(j.entries, entry) @@ -84,44 +135,129 @@ func (j *journal) length() int { return len(j.entries) } +// copy returns a deep-copied journal. +func (j *journal) copy() *journal { + entries := make([]journalEntry, 0, j.length()) + for i := 0; i < j.length(); i++ { + entries = append(entries, j.entries[i].copy()) + } + return &journal{ + entries: entries, + dirties: maps.Clone(j.dirties), + validRevisions: slices.Clone(j.validRevisions), + nextRevisionId: j.nextRevisionId, + } +} + +func (j *journal) logChange(txHash common.Hash) { + j.append(addLogChange{txhash: txHash}) +} + +func (j *journal) createObject(addr common.Address) { + j.append(createObjectChange{account: addr}) +} + +func (j *journal) createContract(addr common.Address) { + j.append(createContractChange{account: addr}) +} + +func (j *journal) destruct(addr common.Address) { + j.append(selfDestructChange{account: addr}) +} + +func (j *journal) storageChange(addr common.Address, key, prev, origin common.Hash) { + j.append(storageChange{ + account: addr, + key: key, + prevvalue: prev, + origvalue: origin, + }) +} + +func (j *journal) transientStateChange(addr common.Address, key, prev common.Hash) { + j.append(transientStorageChange{ + account: addr, + key: key, + prevalue: prev, + }) +} + +func (j *journal) refundChange(previous uint64) { + j.append(refundChange{prev: previous}) +} + +func (j *journal) balanceChange(addr common.Address, previous *uint256.Int) { + j.append(balanceChange{ + account: addr, + prev: previous.Clone(), + }) +} + +func (j *journal) setCode(address common.Address) { + j.append(codeChange{account: address}) +} + +func (j *journal) nonceChange(address common.Address, prev uint64) { + j.append(nonceChange{ + account: address, + prev: prev, + }) +} + +func (j *journal) touchChange(address common.Address) { + j.append(touchChange{ + account: address, + }) + if address == ripemd { + // Explicitly put it in the dirty-cache, which is otherwise generated from + // flattened journals. + j.dirty(address) + } +} + +func (j *journal) accessListAddAccount(addr common.Address) { + j.append(accessListAddAccountChange{addr}) +} + +func (j *journal) accessListAddSlot(addr common.Address, slot common.Hash) { + j.append(accessListAddSlotChange{ + address: addr, + slot: slot, + }) +} + type ( // Changes to the account trie. createObjectChange struct { - account *common.Address + account common.Address } - resetObjectChange struct { - account *common.Address - prev *stateObject - prevdestruct bool - prevAccount []byte - prevStorage map[common.Hash][]byte - - prevAccountOriginExist bool - prevAccountOrigin []byte - prevStorageOrigin map[common.Hash][]byte + // createContractChange represents an account becoming a contract-account. + // This event happens prior to executing initcode. The journal-event simply + // manages the created-flag, in order to allow same-tx destruction. + createContractChange struct { + account common.Address } selfDestructChange struct { - account *common.Address - prev bool // whether account had already self-destructed - prevbalance *uint256.Int + account common.Address } // Changes to individual accounts. balanceChange struct { - account *common.Address + account common.Address prev *uint256.Int } nonceChange struct { - account *common.Address + account common.Address prev uint64 } storageChange struct { - account *common.Address - key, prevalue common.Hash + account common.Address + key common.Hash + prevvalue common.Hash + origvalue common.Hash } codeChange struct { - account *common.Address - prevcode, prevhash []byte + account common.Address } // Changes to other state values. @@ -131,69 +267,69 @@ type ( addLogChange struct { txhash common.Hash } - addPreimageChange struct { - hash common.Hash - } touchChange struct { - account *common.Address + account common.Address } + // Changes to the access list accessListAddAccountChange struct { - address *common.Address + address common.Address } accessListAddSlotChange struct { - address *common.Address - slot *common.Hash + address common.Address + slot common.Hash } + // Changes to transient storage transientStorageChange struct { - account *common.Address + account common.Address key, prevalue common.Hash } ) func (ch createObjectChange) revert(s *StateDB) { - delete(s.stateObjects, *ch.account) - delete(s.stateObjectsDirty, *ch.account) + delete(s.stateObjects, ch.account) } func (ch createObjectChange) dirtied() *common.Address { - return ch.account + return &ch.account } -func (ch resetObjectChange) revert(s *StateDB) { - s.setStateObject(ch.prev) - if !ch.prevdestruct { - delete(s.stateObjectsDestruct, ch.prev.address) - } - if ch.prevAccount != nil { - s.accounts[ch.prev.addrHash] = ch.prevAccount - } - if ch.prevStorage != nil { - s.storages[ch.prev.addrHash] = ch.prevStorage - } - if ch.prevAccountOriginExist { - s.accountsOrigin[ch.prev.address] = ch.prevAccountOrigin - } - if ch.prevStorageOrigin != nil { - s.storagesOrigin[ch.prev.address] = ch.prevStorageOrigin +func (ch createObjectChange) copy() journalEntry { + return createObjectChange{ + account: ch.account, } } -func (ch resetObjectChange) dirtied() *common.Address { - return ch.account +func (ch createContractChange) revert(s *StateDB) { + s.getStateObject(ch.account).newContract = false +} + +func (ch createContractChange) dirtied() *common.Address { + return nil +} + +func (ch createContractChange) copy() journalEntry { + return createContractChange{ + account: ch.account, + } } func (ch selfDestructChange) revert(s *StateDB) { - obj := s.getStateObject(*ch.account) + obj := s.getStateObject(ch.account) if obj != nil { - obj.selfDestructed = ch.prev - obj.setBalance(ch.prevbalance) + obj.selfDestructed = false } } func (ch selfDestructChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch selfDestructChange) copy() journalEntry { + return selfDestructChange{ + account: ch.account, + } } var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") @@ -202,49 +338,89 @@ func (ch touchChange) revert(s *StateDB) { } func (ch touchChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch touchChange) copy() journalEntry { + return touchChange{ + account: ch.account, + } } func (ch balanceChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setBalance(ch.prev) + s.getStateObject(ch.account).setBalance(ch.prev) } func (ch balanceChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch balanceChange) copy() journalEntry { + return balanceChange{ + account: ch.account, + prev: new(uint256.Int).Set(ch.prev), + } } func (ch nonceChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setNonce(ch.prev) + s.getStateObject(ch.account).setNonce(ch.prev) } func (ch nonceChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch nonceChange) copy() journalEntry { + return nonceChange{ + account: ch.account, + prev: ch.prev, + } } func (ch codeChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) + s.getStateObject(ch.account).setCode(types.EmptyCodeHash, nil) } func (ch codeChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch codeChange) copy() journalEntry { + return codeChange{account: ch.account} } func (ch storageChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) + s.getStateObject(ch.account).setState(ch.key, ch.prevvalue, ch.origvalue) } func (ch storageChange) dirtied() *common.Address { - return ch.account + return &ch.account +} + +func (ch storageChange) copy() journalEntry { + return storageChange{ + account: ch.account, + key: ch.key, + prevvalue: ch.prevvalue, + } } func (ch transientStorageChange) revert(s *StateDB) { - s.setTransientState(*ch.account, ch.key, ch.prevalue) + s.setTransientState(ch.account, ch.key, ch.prevalue) } func (ch transientStorageChange) dirtied() *common.Address { return nil } +func (ch transientStorageChange) copy() journalEntry { + return transientStorageChange{ + account: ch.account, + key: ch.key, + prevalue: ch.prevalue, + } +} + func (ch refundChange) revert(s *StateDB) { s.refund = ch.prev } @@ -253,6 +429,12 @@ func (ch refundChange) dirtied() *common.Address { return nil } +func (ch refundChange) copy() journalEntry { + return refundChange{ + prev: ch.prev, + } +} + func (ch addLogChange) revert(s *StateDB) { logs := s.logs[ch.txhash] if len(logs) == 1 { @@ -267,12 +449,10 @@ func (ch addLogChange) dirtied() *common.Address { return nil } -func (ch addPreimageChange) revert(s *StateDB) { - delete(s.preimages, ch.hash) -} - -func (ch addPreimageChange) dirtied() *common.Address { - return nil +func (ch addLogChange) copy() journalEntry { + return addLogChange{ + txhash: ch.txhash, + } } func (ch accessListAddAccountChange) revert(s *StateDB) { @@ -285,21 +465,30 @@ func (ch accessListAddAccountChange) revert(s *StateDB) { (addr) at this point, since no storage adds can remain when come upon a single (addr) change. */ - if s.accessList != nil { - s.accessList.DeleteAddress(*ch.address) - } + s.accessList.DeleteAddress(ch.address) } func (ch accessListAddAccountChange) dirtied() *common.Address { return nil } -func (ch accessListAddSlotChange) revert(s *StateDB) { - if s.accessList != nil { - s.accessList.DeleteSlot(*ch.address, *ch.slot) +func (ch accessListAddAccountChange) copy() journalEntry { + return accessListAddAccountChange{ + address: ch.address, } } +func (ch accessListAddSlotChange) revert(s *StateDB) { + s.accessList.DeleteSlot(ch.address, ch.slot) +} + func (ch accessListAddSlotChange) dirtied() *common.Address { return nil } + +func (ch accessListAddSlotChange) copy() journalEntry { + return accessListAddSlotChange{ + address: ch.address, + slot: ch.slot, + } +} diff --git a/core/state/metrics.go b/core/state/metrics.go index 64c651461e..fb45bc4b84 100644 --- a/core/state/metrics.go +++ b/core/state/metrics.go @@ -19,6 +19,8 @@ package state import "github.com/ethereum/go-ethereum/metrics" var ( + accountReadMeters = metrics.NewRegisteredMeter("state/read/accounts", nil) + storageReadMeters = metrics.NewRegisteredMeter("state/read/storage", nil) accountUpdatedMeter = metrics.NewRegisteredMeter("state/update/account", nil) storageUpdatedMeter = metrics.NewRegisteredMeter("state/update/storage", nil) accountDeletedMeter = metrics.NewRegisteredMeter("state/delete/account", nil) @@ -27,11 +29,4 @@ var ( storageTriesUpdatedMeter = metrics.NewRegisteredMeter("state/update/storagenodes", nil) accountTrieDeletedMeter = metrics.NewRegisteredMeter("state/delete/accountnodes", nil) storageTriesDeletedMeter = metrics.NewRegisteredMeter("state/delete/storagenodes", nil) - - slotDeletionMaxCount = metrics.NewRegisteredGauge("state/delete/storage/max/slot", nil) - slotDeletionMaxSize = metrics.NewRegisteredGauge("state/delete/storage/max/size", nil) - slotDeletionTimer = metrics.NewRegisteredResettingTimer("state/delete/storage/timer", nil) - slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil) - slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", nil) - slotDeletionSkip = metrics.NewRegisteredGauge("state/delete/storage/skip", nil) ) diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index f4820c06b2..397d9ea646 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" @@ -155,10 +156,10 @@ func NewAllPruner(db ethdb.Database) (*Pruner, error) { } func (p *Pruner) PruneAll(genesis *core.Genesis) error { - return pruneAll(p.db, genesis) + return p.pruneAll(p.db, genesis) } -func pruneAll(maindb ethdb.Database, g *core.Genesis) error { +func (p *Pruner) pruneAll(maindb ethdb.Database, g *core.Genesis) error { var pruneDB ethdb.Database if maindb != nil && maindb.StateStore() != nil { pruneDB = maindb.StateStore() @@ -232,17 +233,16 @@ func pruneAll(maindb ethdb.Database, g *core.Genesis) error { } log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart))) } - statedb, _ := state.New(common.Hash{}, state.NewDatabase(maindb), nil) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(triedb.NewDatabase(maindb, nil), p.snaptree)) for addr, account := range g.Alloc { - statedb.AddBalance(addr, uint256.MustFromBig(account.Balance)) + statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceChangeUnspecified) statedb.SetCode(addr, account.Code) statedb.SetNonce(addr, account.Nonce) for key, value := range account.Storage { statedb.SetState(addr, key, value) } } - root := statedb.IntermediateRoot(false) - statedb.Commit(0, nil) + root, _, _ := statedb.Commit(0, false) statedb.Database().TrieDB().Commit(root, true) log.Info("State pruning successful", "pruned", size, "elapsed", common.PrettyDuration(time.Since(start))) return nil @@ -612,11 +612,10 @@ func (p *Pruner) Prune(root common.Hash) error { // is the presence of root can indicate the presence of the // entire trie. if !rawdb.HasLegacyTrieNode(trienodedb, root) { - // The special case is for clique based networks(goerli - // and some other private networks), it's possible that two - // consecutive blocks will have same root. In this case snapshot - // difflayer won't be created. So HEAD-127 may not paired with - // head-127 layer. Instead the paired layer is higher than the + // The special case is for clique based networks, it's possible + // that two consecutive blocks will have same root. In this case + // snapshot difflayer won't be created. So HEAD-127 may not paired + // with head-127 layer. Instead the paired layer is higher than the // bottom-most diff layer. Try to find the bottom-most snapshot // layer with state available. // diff --git a/core/state/reader.go b/core/state/reader.go new file mode 100644 index 0000000000..6bddefc2a7 --- /dev/null +++ b/core/state/reader.go @@ -0,0 +1,313 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "errors" + "maps" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/utils" + "github.com/ethereum/go-ethereum/triedb" +) + +// Reader defines the interface for accessing accounts and storage slots +// associated with a specific state. +type Reader interface { + // Account retrieves the account associated with a particular address. + // + // - Returns a nil account if it does not exist + // - Returns an error only if an unexpected issue occurs + // - The returned account is safe to modify after the call + Account(addr common.Address) (*types.StateAccount, error) + + // Storage retrieves the storage slot associated with a particular account + // address and slot key. + // + // - Returns an empty slot if it does not exist + // - Returns an error only if an unexpected issue occurs + // - The returned storage slot is safe to modify after the call + Storage(addr common.Address, slot common.Hash) (common.Hash, error) + + // Copy returns a deep-copied state reader. + Copy() Reader +} + +// stateReader is a wrapper over the state snapshot and implements the Reader +// interface. It provides an efficient way to access flat state. +type stateReader struct { + snap snapshot.Snapshot + buff crypto.KeccakState +} + +// newStateReader constructs a flat state reader with on the specified state root. +func newStateReader(root common.Hash, snaps *snapshot.Tree) (*stateReader, error) { + snap := snaps.Snapshot(root) + if snap == nil { + return nil, errors.New("snapshot is not available") + } + return &stateReader{ + snap: snap, + buff: crypto.NewKeccakState(), + }, nil +} + +// Account implements Reader, retrieving the account specified by the address. +// +// An error will be returned if the associated snapshot is already stale or +// the requested account is not yet covered by the snapshot. +// +// The returned account might be nil if it's not existent. +func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error) { + ret, err := r.snap.Account(crypto.HashData(r.buff, addr.Bytes())) + if err != nil { + return nil, err + } + if ret == nil { + return nil, nil + } + acct := &types.StateAccount{ + Nonce: ret.Nonce, + Balance: ret.Balance, + CodeHash: ret.CodeHash, + Root: common.BytesToHash(ret.Root), + } + if len(acct.CodeHash) == 0 { + acct.CodeHash = types.EmptyCodeHash.Bytes() + } + if acct.Root == (common.Hash{}) { + acct.Root = types.EmptyRootHash + } + return acct, nil +} + +// Storage implements Reader, retrieving the storage slot specified by the +// address and slot key. +// +// An error will be returned if the associated snapshot is already stale or +// the requested storage slot is not yet covered by the snapshot. +// +// The returned storage slot might be empty if it's not existent. +func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { + addrHash := crypto.HashData(r.buff, addr.Bytes()) + slotHash := crypto.HashData(r.buff, key.Bytes()) + ret, err := r.snap.Storage(addrHash, slotHash) + if err != nil { + return common.Hash{}, err + } + if len(ret) == 0 { + return common.Hash{}, nil + } + // Perform the rlp-decode as the slot value is RLP-encoded in the state + // snapshot. + _, content, _, err := rlp.Split(ret) + if err != nil { + return common.Hash{}, err + } + var value common.Hash + value.SetBytes(content) + return value, nil +} + +// Copy implements Reader, returning a deep-copied snap reader. +func (r *stateReader) Copy() Reader { + return &stateReader{ + snap: r.snap, + buff: crypto.NewKeccakState(), + } +} + +// trieReader implements the Reader interface, providing functions to access +// state from the referenced trie. +type trieReader struct { + root common.Hash // State root which uniquely represent a state + db *triedb.Database // Database for loading trie + buff crypto.KeccakState // Buffer for keccak256 hashing + mainTrie Trie // Main trie, resolved in constructor + subRoots map[common.Address]common.Hash // Set of storage roots, cached when the account is resolved + subTries map[common.Address]Trie // Group of storage tries, cached when it's resolved +} + +// trieReader constructs a trie reader of the specific state. An error will be +// returned if the associated trie specified by root is not existent. +func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCache) (*trieReader, error) { + var ( + tr Trie + err error + ) + if !db.IsVerkle() { + tr, err = trie.NewStateTrie(trie.StateTrieID(root), db) + } else { + tr, err = trie.NewVerkleTrie(root, db, cache) + } + if err != nil { + return nil, err + } + return &trieReader{ + root: root, + db: db, + buff: crypto.NewKeccakState(), + mainTrie: tr, + subRoots: make(map[common.Address]common.Hash), + subTries: make(map[common.Address]Trie), + }, nil +} + +// Account implements Reader, retrieving the account specified by the address. +// +// An error will be returned if the trie state is corrupted. An nil account +// will be returned if it's not existent in the trie. +func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) { + account, err := r.mainTrie.GetAccount(addr) + if err != nil { + return nil, err + } + if account == nil { + r.subRoots[addr] = types.EmptyRootHash + } else { + r.subRoots[addr] = account.Root + } + return account, nil +} + +// Storage implements Reader, retrieving the storage slot specified by the +// address and slot key. +// +// An error will be returned if the trie state is corrupted. An empty storage +// slot will be returned if it's not existent in the trie. +func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { + var ( + tr Trie + found bool + value common.Hash + ) + if r.db.IsVerkle() { + tr = r.mainTrie + } else { + tr, found = r.subTries[addr] + if !found { + root, ok := r.subRoots[addr] + + // The storage slot is accessed without account caching. It's unexpected + // behavior but try to resolve the account first anyway. + if !ok { + _, err := r.Account(addr) + if err != nil { + return common.Hash{}, err + } + root = r.subRoots[addr] + } + var err error + tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.HashData(r.buff, addr.Bytes()), root), r.db) + if err != nil { + return common.Hash{}, err + } + r.subTries[addr] = tr + } + } + ret, err := tr.GetStorage(addr, key.Bytes()) + if err != nil { + return common.Hash{}, err + } + value.SetBytes(ret) + return value, nil +} + +// Copy implements Reader, returning a deep-copied trie reader. +func (r *trieReader) Copy() Reader { + tries := make(map[common.Address]Trie) + for addr, tr := range r.subTries { + tries[addr] = mustCopyTrie(tr) + } + return &trieReader{ + root: r.root, + db: r.db, + buff: crypto.NewKeccakState(), + mainTrie: mustCopyTrie(r.mainTrie), + subRoots: maps.Clone(r.subRoots), + subTries: tries, + } +} + +// multiReader is the aggregation of a list of Reader interface, providing state +// access by leveraging all readers. The checking priority is determined by the +// position in the reader list. +type multiReader struct { + readers []Reader // List of readers, sorted by checking priority +} + +// newMultiReader constructs a multiReader instance with the given readers. The +// priority among readers is assumed to be sorted. Note, it must contain at least +// one reader for constructing a multiReader. +func newMultiReader(readers ...Reader) (*multiReader, error) { + if len(readers) == 0 { + return nil, errors.New("empty reader set") + } + return &multiReader{ + readers: readers, + }, nil +} + +// Account implementing Reader interface, retrieving the account associated with +// a particular address. +// +// - Returns a nil account if it does not exist +// - Returns an error only if an unexpected issue occurs +// - The returned account is safe to modify after the call +func (r *multiReader) Account(addr common.Address) (*types.StateAccount, error) { + var errs []error + for _, reader := range r.readers { + acct, err := reader.Account(addr) + if err == nil { + return acct, nil + } + errs = append(errs, err) + } + return nil, errors.Join(errs...) +} + +// Storage implementing Reader interface, retrieving the storage slot associated +// with a particular account address and slot key. +// +// - Returns an empty slot if it does not exist +// - Returns an error only if an unexpected issue occurs +// - The returned storage slot is safe to modify after the call +func (r *multiReader) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { + var errs []error + for _, reader := range r.readers { + slot, err := reader.Storage(addr, slot) + if err == nil { + return slot, nil + } + errs = append(errs, err) + } + return common.Hash{}, errors.Join(errs...) +} + +// Copy implementing Reader interface, returning a deep-copied state reader. +func (r *multiReader) Copy() Reader { + var readers []Reader + for _, reader := range r.readers { + readers = append(readers, reader.Copy()) + } + return &multiReader{readers: readers} +} diff --git a/core/state/snapshot/context.go b/core/state/snapshot/context.go index 67d7e41a03..8a19960501 100644 --- a/core/state/snapshot/context.go +++ b/core/state/snapshot/context.go @@ -46,7 +46,7 @@ type generatorStats struct { storage common.StorageSize // Total account and storage slot size(generation or recovery) } -// Log creates an contextual log with the given message and the context pulled +// Log creates a contextual log with the given message and the context pulled // from the internally maintained statistics. func (gs *generatorStats) Log(msg string, root common.Hash, marker []byte) { var ctx []interface{} diff --git a/core/state/snapshot/conversion.go b/core/state/snapshot/conversion.go index 8a7017a27d..3a0d6e342f 100644 --- a/core/state/snapshot/conversion.go +++ b/core/state/snapshot/conversion.go @@ -365,15 +365,15 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou } func stackTrieGenerate(db ethdb.KeyValueWriter, scheme string, owner common.Hash, in chan trieKV, out chan common.Hash) { - options := trie.NewStackTrieOptions() + var onTrieNode trie.OnTrieNode if db != nil { - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { + onTrieNode = func(path []byte, hash common.Hash, blob []byte) { rawdb.WriteTrieNode(db, owner, path, hash, blob, scheme) - }) + } } - t := trie.NewStackTrie(options) + t := trie.NewStackTrie(onTrieNode) for leaf := range in { t.Update(leaf.key[:], leaf.value) } - out <- t.Commit() + out <- t.Hash() } diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index c12dd4c3ea..ea77b649fd 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "math/rand" + "slices" "sync" "sync/atomic" "time" @@ -29,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" bloomfilter "github.com/holiman/bloomfilter/v2" - "golang.org/x/exp/slices" ) var ( diff --git a/core/state/snapshot/disklayer.go b/core/state/snapshot/disklayer.go index 1556439f23..708f21e3b7 100644 --- a/core/state/snapshot/disklayer.go +++ b/core/state/snapshot/disklayer.go @@ -80,6 +80,14 @@ func (dl *diskLayer) Accounts() (map[common.Hash]*types.SlimAccount, error) { return nil, nil } +// markStale sets the stale flag as true. +func (dl *diskLayer) markStale() { + dl.lock.Lock() + defer dl.lock.Unlock() + + dl.stale = true +} + // Account directly retrieves the account associated with a particular hash in // the snapshot slim data format. func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) { @@ -181,3 +189,18 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro func (dl *diskLayer) Update(blockHash common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte) *diffLayer { return newDiffLayer(dl, blockHash, destructs, accounts, storage) } + +// stopGeneration aborts the state snapshot generation if it is currently running. +func (dl *diskLayer) stopGeneration() { + dl.lock.RLock() + generating := dl.genMarker != nil + dl.lock.RUnlock() + if !generating { + return + } + if dl.genAbort != nil { + abort := make(chan *generatorStats) + dl.genAbort <- abort + <-abort + } +} diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index 5b20d9e275..dc48cc0d76 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -360,10 +360,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefi for i, key := range result.keys { snapTrie.Update(key, result.vals[i]) } - root, nodes, err := snapTrie.Commit(false) - if err != nil { - return false, nil, err - } + root, nodes := snapTrie.Commit(false) if nodes != nil { tdb.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil) tdb.Commit(root, false) @@ -634,16 +631,10 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er accMarker = nil return nil } - // Always reset the initial account range as 1 whenever recover from the - // interruption. TODO(rjl493456442) can we remove it? - var accountRange = accountCheckRange - if len(accMarker) > 0 { - accountRange = 1 - } origin := common.CopyBytes(accMarker) for { id := trie.StateTrieID(dl.root) - exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, types.FullAccountRLP) + exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountCheckRange, onAccount, types.FullAccountRLP) if err != nil { return err // The procedure it aborted, either by external signal or internal error. } @@ -655,7 +646,6 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er ctx.removeStorageLeft() break } - accountRange = accountCheckRange } return nil } diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index da93ebc875..891111973a 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -210,7 +210,7 @@ func (t *testHelper) makeStorageTrie(owner common.Hash, keys []string, vals []st if !commit { return stTrie.Hash() } - root, nodes, _ := stTrie.Commit(false) + root, nodes := stTrie.Commit(false) if nodes != nil { t.nodes.Merge(nodes) } @@ -218,7 +218,7 @@ func (t *testHelper) makeStorageTrie(owner common.Hash, keys []string, vals []st } func (t *testHelper) Commit() common.Hash { - root, nodes, _ := t.accTrie.Commit(true) + root, nodes := t.accTrie.Commit(true) if nodes != nil { t.nodes.Merge(nodes) } diff --git a/core/state/snapshot/iterator_binary.go b/core/state/snapshot/iterator_binary.go index 22184b2545..edf471213f 100644 --- a/core/state/snapshot/iterator_binary.go +++ b/core/state/snapshot/iterator_binary.go @@ -68,7 +68,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator { parent, ok := dl.parent.(*diffLayer) if !ok { // If the storage in this layer is already destructed, discard all - // deeper layers but still return an valid single-branch iterator. + // deeper layers but still return a valid single-branch iterator. a, destructed := dl.StorageIterator(account, common.Hash{}) if destructed { l := &binaryIterator{ @@ -92,7 +92,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator { return l } // If the storage in this layer is already destructed, discard all - // deeper layers but still return an valid single-branch iterator. + // deeper layers but still return a valid single-branch iterator. a, destructed := dl.StorageIterator(account, common.Hash{}) if destructed { l := &binaryIterator{ diff --git a/core/state/snapshot/iterator_fast.go b/core/state/snapshot/iterator_fast.go index 0502d9cf85..fa0daea7ba 100644 --- a/core/state/snapshot/iterator_fast.go +++ b/core/state/snapshot/iterator_fast.go @@ -19,13 +19,13 @@ package snapshot import ( "bytes" "fmt" + "slices" "sort" "github.com/ethereum/go-ethereum/common" - "golang.org/x/exp/slices" ) -// weightedIterator is a iterator with an assigned weight. It is used to prioritise +// weightedIterator is an iterator with an assigned weight. It is used to prioritise // which account or storage slot is the correct one if multiple iterators find the // same one (modified in multiple consecutive blocks). type weightedIterator struct { diff --git a/core/state/snapshot/iterator_test.go b/core/state/snapshot/iterator_test.go index 54614427a5..daa8cdcc54 100644 --- a/core/state/snapshot/iterator_test.go +++ b/core/state/snapshot/iterator_test.go @@ -815,7 +815,7 @@ func TestStorageIteratorDeletions(t *testing.T) { verifyIterator(t, 2, snaps.Snapshot(common.HexToHash("0x06")).(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) } -// BenchmarkAccountIteratorTraversal is a bit a bit notorious -- all layers contain the +// BenchmarkAccountIteratorTraversal is a bit notorious -- all layers contain the // exact same 200 accounts. That means that we need to process 2000 items, but // only spit out 200 values eventually. // diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index b55d4d1df7..717ff197a9 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -265,24 +265,11 @@ func (t *Tree) Disable() { for _, layer := range t.layers { switch layer := layer.(type) { case *diskLayer: - - layer.lock.RLock() - generating := layer.genMarker != nil - layer.lock.RUnlock() - if !generating { - // Generator is already aborted or finished - break - } - // If the base layer is generating, abort it - if layer.genAbort != nil { - abort := make(chan *generatorStats) - layer.genAbort <- abort - <-abort - } - // Layer should be inactive now, mark it as stale - layer.lock.Lock() - layer.stale = true - layer.lock.Unlock() + // TODO this function will hang if it's called twice. Will + // fix it in the following PRs. + layer.stopGeneration() + layer.markStale() + layer.Release() case *diffLayer: // If the layer is a simple diff, simply mark as stale @@ -679,6 +666,9 @@ func diffToDisk(bottom *diffLayer) *diskLayer { // Release releases resources func (t *Tree) Release() { + t.lock.RLock() + defer t.lock.RUnlock() + if dl := t.disklayer(); dl != nil { dl.Release() } @@ -740,16 +730,11 @@ func (t *Tree) Rebuild(root common.Hash) { for _, layer := range t.layers { switch layer := layer.(type) { case *diskLayer: - // If the base layer is generating, abort it and save - if layer.genAbort != nil { - abort := make(chan *generatorStats) - layer.genAbort <- abort - <-abort - } - // Layer should be inactive now, mark it as stale - layer.lock.Lock() - layer.stale = true - layer.lock.Unlock() + // TODO this function will hang if it's called twice. Will + // fix it in the following PRs. + layer.stopGeneration() + layer.markStale() + layer.Release() case *diffLayer: // If the layer is a simple diff, simply mark as stale @@ -842,13 +827,15 @@ func (t *Tree) disklayer() *diskLayer { case *diskLayer: return layer case *diffLayer: + layer.lock.RLock() + defer layer.lock.RUnlock() return layer.origin default: panic(fmt.Sprintf("%T: undefined layer", snap)) } } -// diskRoot is a internal helper function to return the disk layer root. +// diskRoot is an internal helper function to return the disk layer root. // The lock of snapTree is assumed to be held already. func (t *Tree) diskRoot() common.Hash { disklayer := t.disklayer() @@ -861,8 +848,8 @@ func (t *Tree) diskRoot() common.Hash { // generating is an internal helper function which reports whether the snapshot // is still under the construction. func (t *Tree) generating() (bool, error) { - t.lock.Lock() - defer t.lock.Unlock() + t.lock.RLock() + defer t.lock.RUnlock() layer := t.disklayer() if layer == nil { @@ -873,10 +860,10 @@ func (t *Tree) generating() (bool, error) { return layer.genMarker != nil, nil } -// DiskRoot is a external helper function to return the disk layer root. +// DiskRoot is an external helper function to return the disk layer root. func (t *Tree) DiskRoot() common.Hash { - t.lock.Lock() - defer t.lock.Unlock() + t.lock.RLock() + defer t.lock.RUnlock() return t.diskRoot() } diff --git a/core/state/state_object.go b/core/state/state_object.go index 3f2c8e9786..ce8397152f 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -19,40 +19,24 @@ package state import ( "bytes" "fmt" - "io" + "maps" "sync" "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/holiman/uint256" ) -type Code []byte - -func (c Code) String() string { - return string(c) //strings.Join(Disassemble(c), " ") -} - type Storage map[common.Hash]common.Hash -func (s Storage) String() (str string) { - for key, value := range s { - str += fmt.Sprintf("%X : %X\n", key, value) - } - return -} - func (s Storage) Copy() Storage { - cpy := make(Storage, len(s)) - for key, value := range s { - cpy[key] = value - } - return cpy + return maps.Clone(s) } // StateObject represents an Ethereum account which is being modified. @@ -69,28 +53,38 @@ type stateObject struct { data types.StateAccount // Account data with all mutations applied in the scope of block // Write caches. - trie Trie // storage trie, which becomes non-nil on first access - code Code // contract bytecode, which gets set when code is loaded + trie Trie // storage trie, which becomes non-nil on first access + code []byte // contract bytecode, which gets set when code is loaded sharedOriginStorage *sync.Map // Point to the entry of the stateObject in sharedPool - originStorage Storage // Storage cache of original entries to dedup rewrites - pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block - dirtyStorage Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction + originStorage Storage // Storage entries that have been accessed within the current block + dirtyStorage Storage // Storage entries that have been modified within the current transaction + pendingStorage Storage // Storage entries that have been modified within the current block + + // uncommittedStorage tracks a set of storage entries that have been modified + // but not yet committed since the "last commit operation", along with their + // original values before mutation. + // + // Specifically, the commit will be performed after each transaction before + // the byzantium fork, therefore the map is already reset at the transaction + // boundary; however post the byzantium fork, the commit will only be performed + // at the end of block, this set essentially tracks all the modifications + // made within the block. + uncommittedStorage Storage // Cache flags. dirtyCode bool // true if the code was updated - // Flag whether the account was marked as self-destructed. The self-destructed account - // is still accessible in the scope of same transaction. + // Flag whether the account was marked as self-destructed. The self-destructed + // account is still accessible in the scope of same transaction. selfDestructed bool - // Flag whether the account was marked as deleted. A self-destructed account - // or an account that is considered as empty will be marked as deleted at - // the end of transaction and no longer accessible anymore. - deleted bool - - // Flag whether the object was created in the current transaction - created bool + // This is an EIP-6780 flag indicating whether the object is eligible for + // self-destruct according to EIP-6780. The flag could be set either when + // the contract is just created within the current transaction, or when the + // object was previously existent and is being deployed as a contract within + // the current transaction. + newContract bool } // empty returns whether the account is considered empty. @@ -100,10 +94,7 @@ func (s *stateObject) empty() bool { // newObject creates a state object. func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject { - var ( - origin = acct - created = acct == nil // true if the account was not existent - ) + origin := acct if acct == nil { acct = types.NewEmptyStateAccount() } @@ -123,60 +114,49 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s originStorage: make(Storage), pendingStorage: make(Storage), dirtyStorage: make(Storage), - created: created, + uncommittedStorage: make(Storage), } } -// EncodeRLP implements rlp.Encoder. -func (s *stateObject) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, &s.data) -} - func (s *stateObject) markSelfdestructed() { s.selfDestructed = true } func (s *stateObject) touch() { - s.db.journal.append(touchChange{ - account: &s.address, - }) - if s.address == ripemd { - // Explicitly put it in the dirty-cache, which is otherwise generated from - // flattened journals. - s.db.journal.dirty(s.address) - } + s.db.journal.touchChange(s.address) } -// getTrie returns the associated storage trie. The trie will be opened -// if it's not loaded previously. An error will be returned if trie can't -// be loaded. +// getTrie returns the associated storage trie. The trie will be opened if it's +// not loaded previously. An error will be returned if trie can't be loaded. +// +// If a new trie is opened, it will be cached within the state object to allow +// subsequent reads to expand the same trie instead of reloading from disk. func (s *stateObject) getTrie() (Trie, error) { if s.trie == nil { - // Try fetching from prefetcher first - // if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil { - // When the miner is creating the pending state, there is no prefetcher - // s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root) - // } - // if s.trie == nil { tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root, s.db.trie) if err != nil { return nil, err } s.trie = tr - // } } return s.trie, nil } -// GetState retrieves a value from the account storage trie. -func (s *stateObject) GetState(key common.Hash) common.Hash { - // If we have a dirty value for this state entry, return it - value, dirty := s.dirtyStorage[key] - if dirty { - return value +// getPrefetchedTrie returns the associated trie, as populated by the prefetcher +// if it's available. +// +// Note, opposed to getTrie, this method will *NOT* blindly cache the resulting +// trie in the state object. The caller might want to do that, but it's cleaner +// to break the hidden interdependency between retrieving tries from the db or +// from the prefetcher. +func (s *stateObject) getPrefetchedTrie() Trie { + // If there's nothing to meaningfully return, let the user figure it out by + // pulling the trie from disk. + if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsVerkle()) || s.db.prefetcher == nil { + return nil } - // Otherwise return the entry's original value - return s.GetCommittedState(key) + // Attempt to retrieve the trie from the prefetcher + return s.db.prefetcher.trie(s.addrHash, s.data.Root) } func (s *stateObject) getOriginStorage(key common.Hash) (common.Hash, bool) { @@ -204,6 +184,25 @@ func (s *stateObject) setOriginStorage(key common.Hash, value common.Hash) { } // GetCommittedState retrieves a value from the committed account storage trie. +// GetState retrieves a value associated with the given storage key. +func (s *stateObject) GetState(key common.Hash) common.Hash { + value, _ := s.getState(key) + return value +} + +// getState retrieves a value associated with the given storage key, along with +// its original value. +func (s *stateObject) getState(key common.Hash) (common.Hash, common.Hash) { + origin := s.GetCommittedState(key) + value, dirty := s.dirtyStorage[key] + if dirty { + return value, origin + } + return origin, origin +} + +// GetCommittedState retrieves the value associated with the specific key +// without any mutations caused in the current execution. func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { // If we have a pending write or clean cached, return that if value, pending := s.pendingStorage[key]; pending { @@ -220,45 +219,24 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { // have been handles via pendingStorage above. // 2) we don't have new values, and can deliver empty response back if _, destructed := s.db.stateObjectsDestruct[s.address]; destructed { + s.originStorage[key] = common.Hash{} // track the empty slot as origin value return common.Hash{} } - // If no live objects are available, attempt to use snapshots - var ( - enc []byte - err error - value common.Hash - ) - if s.db.snap != nil { - start := time.Now() - enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) - if metrics.EnabledExpensive { - s.db.SnapshotStorageReads += time.Since(start) - } - if len(enc) > 0 { - _, content, _, err := rlp.Split(enc) - if err != nil { - s.db.setError(err) - } - value.SetBytes(content) - } + s.db.StorageLoaded++ + + start := time.Now() + value, err := s.db.reader.Storage(s.address, key) + if err != nil { + s.db.setError(err) + return common.Hash{} } - // If the snapshot is unavailable or reading from it fails, load from the database. - if s.db.snap == nil || err != nil { - start := time.Now() - tr, err := s.getTrie() - if err != nil { - s.db.setError(err) - return common.Hash{} - } - val, err := tr.GetStorage(s.address, key.Bytes()) - if metrics.EnabledExpensive { - s.db.StorageReads += time.Since(start) - } - if err != nil { - s.db.setError(err) - return common.Hash{} + s.db.StorageReads += time.Since(start) + + // Schedule the resolved storage slots for prefetching if it's enabled. + if s.db.prefetcher != nil && s.data.Root != types.EmptyRootHash { + if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, [][]byte{key[:]}, true); err != nil { + log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err) } - value.SetBytes(val) } s.setOriginStorage(key, value) return value @@ -266,40 +244,69 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { // SetState updates a value in account storage. func (s *stateObject) SetState(key, value common.Hash) { - // If the new value is the same as old, don't set - prev := s.GetState(key) + // If the new value is the same as old, don't set. Otherwise, track only the + // dirty changes, supporting reverting all of it back to no change. + prev, origin := s.getState(key) if prev == value { return } // New value is different, update and journal the change - s.db.journal.append(storageChange{ - account: &s.address, - key: key, - prevalue: prev, - }) - s.setState(key, value) + s.db.journal.storageChange(s.address, key, prev, origin) + s.setState(key, value, origin) + if s.db.logger != nil && s.db.logger.OnStorageChange != nil { + s.db.logger.OnStorageChange(s.address, key, prev, value) + } } -func (s *stateObject) setState(key, value common.Hash) { +// setState updates a value in account dirty storage. The dirtiness will be +// removed if the value being set equals to the original value. +func (s *stateObject) setState(key common.Hash, value common.Hash, origin common.Hash) { + // Storage slot is set back to its original value, undo the dirty marker + if value == origin { + delete(s.dirtyStorage, key) + return + } s.dirtyStorage[key] = value } // finalise moves all dirty storage slots into the pending area to be hashed or // committed later. It is invoked at the end of every transaction. -func (s *stateObject) finalise(prefetch bool) { +func (s *stateObject) finalise() { slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) for key, value := range s.dirtyStorage { - s.pendingStorage[key] = value - if value != s.originStorage[key] { + if origin, exist := s.uncommittedStorage[key]; exist && origin == value { + // The slot is reverted to its original value, delete the entry + // to avoid thrashing the data structures. + delete(s.uncommittedStorage, key) + } else if exist { + // The slot is modified to another value and the slot has been + // tracked for commit, do nothing here. + } else { + // The slot is different from its original value and hasn't been + // tracked for commit yet. + s.uncommittedStorage[key] = s.GetCommittedState(key) slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure } + // Aggregate the dirty storage slots into the pending area. It might + // be possible that the value of tracked slot here is same with the + // one in originStorage (e.g. the slot was modified in tx_a and then + // modified back in tx_b). We can't blindly remove it from pending + // map as the dirty slot might have been committed already (before the + // byzantium fork) and entry is necessary to modify the value back. + s.pendingStorage[key] = value } - if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { - s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch) + if s.db.prefetcher != nil && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { + if err := s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch, false); err != nil { + log.Error("Failed to prefetch slots", "addr", s.address, "slots", len(slotsToPrefetch), "err", err) + } } if len(s.dirtyStorage) > 0 { s.dirtyStorage = make(Storage) } + // Revoke the flag at the end of the transaction. It finalizes the status + // of the newly-created object as it's no longer eligible for self-destruct + // by EIP-6780. For non-newly-created objects, it's a no-op. + s.newContract = false } // updateTrie is responsible for persisting cached storage changes into the @@ -308,116 +315,85 @@ func (s *stateObject) finalise(prefetch bool) { // loading or updating of the trie, an error will be returned. Furthermore, // this function will return the mutated storage trie, or nil if there is no // storage change at all. +// +// It assumes all the dirty storage slots have been finalized before. func (s *stateObject) updateTrie() (Trie, error) { - // Make sure all dirty slots are finalized into the pending storage area - s.finalise(false) - + // Short circuit if nothing was accessed, don't trigger a prefetcher warning + if len(s.uncommittedStorage) == 0 { + // Nothing was written, so we could stop early. Unless we have both reads + // and witness collection enabled, in which case we need to fetch the trie. + if s.db.witness == nil || len(s.originStorage) == 0 { + return s.trie, nil + } + } + // Retrieve a pretecher populated trie, or fall back to the database. This will + // block until all prefetch tasks are done, which are needed for witnesses even + // for unmodified state objects. + tr := s.getPrefetchedTrie() + if tr != nil { + // Prefetcher returned a live trie, swap it out for the current one + s.trie = tr + } else { + // Fetcher not running or empty trie, fallback to the database trie + var err error + tr, err = s.getTrie() + if err != nil { + s.db.setError(err) + return nil, err + } + } // Short circuit if nothing changed, don't bother with hashing anything - if len(s.pendingStorage) == 0 { + if len(s.uncommittedStorage) == 0 { return s.trie, nil } - // Track the amount of time wasted on updating the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { - s.db.MetricsMux.Lock() - s.db.StorageUpdates += time.Since(start) - s.db.MetricsMux.Unlock() - }(time.Now()) - } - // The snapshot storage map for the object + // Perform trie updates before deletions. This prevents resolution of unnecessary trie nodes + // in circumstances similar to the following: + // + // Consider nodes `A` and `B` who share the same full node parent `P` and have no other siblings. + // During the execution of a block: + // - `A` is deleted, + // - `C` is created, and also shares the parent `P`. + // If the deletion is handled first, then `P` would be left with only one child, thus collapsed + // into a shortnode. This requires `B` to be resolved from disk. + // Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved. var ( - storage map[common.Hash][]byte - origin map[common.Hash][]byte - hasher = crypto.NewKeccakState() + deletions []common.Hash + used = make([][]byte, 0, len(s.uncommittedStorage)) ) - tr, err := s.getTrie() - if err != nil { - s.db.setError(err) - return nil, err - } - // Insert all the pending storage updates into the trie - usedStorage := make([][]byte, 0, len(s.pendingStorage)) - dirtyStorage := make(map[common.Hash][]byte) - for key, value := range s.pendingStorage { + for key, origin := range s.uncommittedStorage { // Skip noop changes, persist actual changes - if value == s.originStorage[key] { + value, exist := s.pendingStorage[key] + if value == origin { + log.Error("Storage update was noop", "address", s.address, "slot", key) continue } - var v []byte - if value != (common.Hash{}) { - value := value - v = common.TrimLeftZeroes(value[:]) + if !exist { + log.Error("Storage slot is not found in pending area", s.address, "slot", key) + continue } - dirtyStorage[key] = v - } - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - for key, value := range dirtyStorage { - if len(value) == 0 { - if err := tr.DeleteStorage(s.address, key[:]); err != nil { - s.db.setError(err) - } - s.db.StorageDeleted += 1 - } else { - if err := tr.UpdateStorage(s.address, key[:], value); err != nil { - s.db.setError(err) - } - s.db.StorageUpdated += 1 + if (value != common.Hash{}) { + if err := tr.UpdateStorage(s.address, key[:], common.TrimLeftZeroes(value[:])); err != nil { + s.db.setError(err) + return nil, err } - // Cache the items for preloading - usedStorage = append(usedStorage, common.CopyBytes(key[:])) - } - }() - // If state snapshotting is active, cache the data til commit - wg.Add(1) - go func() { - defer wg.Done() - s.db.StorageMux.Lock() - // The snapshot storage map for the object - storage = s.db.storages[s.addrHash] - if storage == nil { - storage = make(map[common.Hash][]byte, len(dirtyStorage)) - s.db.storages[s.addrHash] = storage - } - // Cache the original value of mutated storage slots - origin = s.db.storagesOrigin[s.address] - if origin == nil { - origin = make(map[common.Hash][]byte) - s.db.storagesOrigin[s.address] = origin + s.db.StorageUpdated.Add(1) + } else { + deletions = append(deletions, key) } - s.db.StorageMux.Unlock() - for key, value := range dirtyStorage { - khash := crypto.HashData(hasher, key[:]) - - // rlp-encoded value to be used by the snapshot - var encoded []byte - if len(value) != 0 { - encoded, _ = rlp.EncodeToBytes(value) - } - storage[khash] = encoded // encoded will be nil if it's deleted - - // Track the original value of slot only if it's mutated first time - prev := s.originStorage[key] - s.originStorage[key] = common.BytesToHash(value) // fill back left zeroes by BytesToHash - if _, ok := origin[khash]; !ok { - if prev == (common.Hash{}) { - origin[khash] = nil // nil if it was not present previously - } else { - // Encoding []byte cannot fail, ok to ignore the error. - b, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(prev[:])) - origin[khash] = b - } - } + // Cache the items for preloading + used = append(used, common.CopyBytes(key[:])) // Copy needed for closure + } + for _, key := range deletions { + if err := tr.DeleteStorage(s.address, key[:]); err != nil { + s.db.setError(err) + return nil, err } - }() - wg.Wait() - + s.db.StorageDeleted.Add(1) + } if s.db.prefetcher != nil { - s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage) + s.db.prefetcher.used(s.addrHash, s.data.Root, used) } - s.pendingStorage = make(Storage) // reset pending map + s.uncommittedStorage = make(Storage) // empties the commit markers return tr, nil } @@ -432,52 +408,89 @@ func (s *stateObject) updateRoot() { }() // Flush cached storage mutations into trie, short circuit if any error - // is occurred or there is not change in the trie. + // is occurred or there is no change in the trie. tr, err := s.updateTrie() if err != nil || tr == nil { return } - // Track the amount of time wasted on hashing the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { - s.db.MetricsMux.Lock() - s.db.StorageHashes += time.Since(start) - s.db.MetricsMux.Unlock() - }(time.Now()) - } s.data.Root = tr.Hash() } -// commit obtains a set of dirty storage trie nodes and updates the account data. -// The returned set can be nil if nothing to commit. This function assumes all -// storage mutations have already been flushed into trie by updateRoot. -func (s *stateObject) commit() (*trienode.NodeSet, error) { - // Short circuit if trie is not even loaded, don't bother with committing anything - if s.trie == nil { - s.origin = s.data.Copy() - return nil, nil +// commitStorage overwrites the clean storage with the storage changes and +// fulfills the storage diffs into the given accountUpdate struct. +func (s *stateObject) commitStorage(op *accountUpdate) { + var ( + buf = crypto.NewKeccakState() + encode = func(val common.Hash) []byte { + if val == (common.Hash{}) { + return nil + } + blob, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(val[:])) + return blob + } + ) + for key, val := range s.pendingStorage { + // Skip the noop storage changes, it might be possible the value + // of tracked slot is same in originStorage and pendingStorage + // map, e.g. the storage slot is modified in tx_a and then reset + // back in tx_b. + if val == s.originStorage[key] { + continue + } + hash := crypto.HashData(buf, key[:]) + if op.storages == nil { + op.storages = make(map[common.Hash][]byte) + } + op.storages[hash] = encode(val) + if op.storagesOrigin == nil { + op.storagesOrigin = make(map[common.Hash][]byte) + } + op.storagesOrigin[hash] = encode(s.originStorage[key]) + + // Overwrite the clean value of storage slots + s.originStorage[key] = val } - // Track the amount of time wasted on committing the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) + s.pendingStorage = make(Storage) +} + +// commit obtains the account changes (metadata, storage slots, code) caused by +// state execution along with the dirty storage trie nodes. +// +// Note, commit may run concurrently across all the state objects. Do not assume +// thread-safe access to the statedb. +func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) { + // commit the account metadata changes + op := &accountUpdate{ + address: s.address, + data: types.SlimAccountRLP(s.data), + } + if s.origin != nil { + op.origin = types.SlimAccountRLP(*s.origin) + } + // commit the contract code if it's modified + if s.dirtyCode { + op.code = &contractCode{ + hash: common.BytesToHash(s.CodeHash()), + blob: s.code, + } + s.dirtyCode = false // reset the dirty flag } - // The trie is currently in an open state and could potentially contain - // cached mutations. Call commit to acquire a set of nodes that have been - // modified, the set can be nil if nothing to commit. - root, nodes, err := s.trie.Commit(false) - if err != nil { - return nil, err + // Commit storage changes and the associated storage trie + s.commitStorage(op) + if len(op.storages) == 0 { + // nothing changed, don't bother to commit the trie + s.origin = s.data.Copy() + return op, nil, nil } + root, nodes := s.trie.Commit(false) s.data.Root = root - - // Update original account data after commit s.origin = s.data.Copy() - return nodes, nil + return op, nodes, nil } // AddBalance adds amount to s's balance. // It is used to add funds to the destination account of a transfer. -func (s *stateObject) AddBalance(amount *uint256.Int) { +func (s *stateObject) AddBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { // EIP161: We must check emptiness for the objects such that the account // clearing (0,0,0 objects) can take effect. if amount.IsZero() { @@ -486,23 +499,23 @@ func (s *stateObject) AddBalance(amount *uint256.Int) { } return } - s.SetBalance(new(uint256.Int).Add(s.Balance(), amount)) + s.SetBalance(new(uint256.Int).Add(s.Balance(), amount), reason) } // SubBalance removes amount from s's balance. // It is used to remove funds from the origin account of a transfer. -func (s *stateObject) SubBalance(amount *uint256.Int) { +func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { if amount.IsZero() { return } - s.SetBalance(new(uint256.Int).Sub(s.Balance(), amount)) + s.SetBalance(new(uint256.Int).Sub(s.Balance(), amount), reason) } -func (s *stateObject) SetBalance(amount *uint256.Int) { - s.db.journal.append(balanceChange{ - account: &s.address, - prev: new(uint256.Int).Set(s.data.Balance), - }) +func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { + s.db.journal.balanceChange(s.address, s.data.Balance) + if s.db.logger != nil && s.db.logger.OnBalanceChange != nil { + s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason) + } s.setBalance(amount) } @@ -512,22 +525,23 @@ func (s *stateObject) setBalance(amount *uint256.Int) { func (s *stateObject) deepCopy(db *StateDB) *stateObject { obj := &stateObject{ - db: db, - address: s.address, - addrHash: s.addrHash, - origin: s.origin, - data: s.data, + db: db, + address: s.address, + addrHash: s.addrHash, + origin: s.origin, + data: s.data, + code: s.code, + originStorage: s.originStorage.Copy(), + pendingStorage: s.pendingStorage.Copy(), + dirtyStorage: s.dirtyStorage.Copy(), + uncommittedStorage: s.uncommittedStorage.Copy(), + dirtyCode: s.dirtyCode, + selfDestructed: s.selfDestructed, + newContract: s.newContract, } if s.trie != nil { - obj.trie = db.db.CopyTrie(s.trie) - } - obj.code = s.code - obj.dirtyStorage = s.dirtyStorage.Copy() - obj.originStorage = s.originStorage.Copy() - obj.pendingStorage = s.pendingStorage.Copy() - obj.selfDestructed = s.selfDestructed - obj.dirtyCode = s.dirtyCode - obj.deleted = s.deleted + obj.trie = mustCopyTrie(s.trie) + } return obj } @@ -542,7 +556,7 @@ func (s *stateObject) Address() common.Address { // Code returns the contract code associated with this object, if any. func (s *stateObject) Code() []byte { - if s.code != nil { + if len(s.code) != 0 { return s.code } if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { @@ -560,7 +574,7 @@ func (s *stateObject) Code() []byte { // or zero if none. This method is an almost mirror of Code, but uses a cache // inside the database to avoid loading codes seen recently. func (s *stateObject) CodeSize() int { - if s.code != nil { + if len(s.code) != 0 { return len(s.code) } if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { @@ -574,12 +588,11 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - prevcode := s.Code() - s.db.journal.append(codeChange{ - account: &s.address, - prevhash: s.CodeHash(), - prevcode: prevcode, - }) + s.db.journal.setCode(s.address) + if s.db.logger != nil && s.db.logger.OnCodeChange != nil { + // TODO remove prevcode from this callback + s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) + } s.setCode(codeHash, code) } @@ -590,10 +603,10 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { } func (s *stateObject) SetNonce(nonce uint64) { - s.db.journal.append(nonceChange{ - account: &s.address, - prev: s.data.Nonce, - }) + s.db.journal.nonceChange(s.address, s.data.Nonce) + if s.db.logger != nil && s.db.logger.OnNonceChange != nil { + s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce) + } s.setNonce(nonce) } diff --git a/core/state/state_test.go b/core/state/state_test.go index c19f2c9138..df96882856 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -23,37 +23,36 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" ) type stateEnv struct { - db ethdb.Database state *StateDB } func newStateEnv() *stateEnv { - db := rawdb.NewMemoryDatabase() - sdb, _ := New(types.EmptyRootHash, NewDatabase(db), nil) - return &stateEnv{db: db, state: sdb} + sdb, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) + return &stateEnv{state: sdb} } func TestDump(t *testing.T) { db := rawdb.NewMemoryDatabase() - tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) - sdb, _ := New(types.EmptyRootHash, tdb, nil) - s := &stateEnv{db: db, state: sdb} + triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) + tdb := NewDatabase(triedb, nil) + sdb, _ := New(types.EmptyRootHash, tdb) + s := &stateEnv{state: sdb} // generate a few entries obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) - obj1.AddBalance(uint256.NewInt(22)) + obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) - obj3.SetBalance(uint256.NewInt(44)) + obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) // write some of them to the trie s.state.updateStateObject(obj1) @@ -63,7 +62,7 @@ func TestDump(t *testing.T) { root, _, _ := s.state.Commit(0, nil) // check that DumpToCollector contains the state objects that are in trie - s.state, _ = New(root, tdb, nil) + s.state, _ = New(root, tdb) got := string(s.state.Dump(nil)) want := `{ "root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2", @@ -102,27 +101,26 @@ func TestDump(t *testing.T) { func TestIterativeDump(t *testing.T) { db := rawdb.NewMemoryDatabase() - tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) - sdb, _ := New(types.EmptyRootHash, tdb, nil) - s := &stateEnv{db: db, state: sdb} + triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) + tdb := NewDatabase(triedb, nil) + sdb, _ := New(types.EmptyRootHash, tdb) + s := &stateEnv{state: sdb} // generate a few entries obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) - obj1.AddBalance(uint256.NewInt(22)) + obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) - obj3.SetBalance(uint256.NewInt(44)) + obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) obj4 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x00})) - obj4.AddBalance(uint256.NewInt(1337)) + obj4.AddBalance(uint256.NewInt(1337), tracing.BalanceChangeUnspecified) // write some of them to the trie s.state.updateStateObject(obj1) s.state.updateStateObject(obj2) - s.state.Finalise(false) - s.state.AccountsIntermediateRoot() - root, _, _ := s.state.Commit(0, nil) - s.state, _ = New(root, tdb, nil) + root, _, _ := s.state.Commit(0, false) + s.state, _ = New(root, tdb) b := &bytes.Buffer{} s.state.IterativeDump(nil, json.NewEncoder(b)) @@ -199,108 +197,20 @@ func TestSnapshotEmpty(t *testing.T) { s.state.RevertToSnapshot(s.state.Snapshot()) } -func TestSnapshot2(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - stateobjaddr0 := common.BytesToAddress([]byte("so0")) - stateobjaddr1 := common.BytesToAddress([]byte("so1")) - var storageaddr common.Hash - - data0 := common.BytesToHash([]byte{17}) - data1 := common.BytesToHash([]byte{18}) - - state.SetState(stateobjaddr0, storageaddr, data0) - state.SetState(stateobjaddr1, storageaddr, data1) +func TestCreateObjectRevert(t *testing.T) { + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) + addr := common.BytesToAddress([]byte("so0")) + snap := state.Snapshot() - // db, trie are already non-empty values - so0 := state.getStateObject(stateobjaddr0) - so0.SetBalance(uint256.NewInt(42)) + state.CreateAccount(addr) + so0 := state.getStateObject(addr) + so0.SetBalance(uint256.NewInt(42), tracing.BalanceChangeUnspecified) so0.SetNonce(43) so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) - so0.selfDestructed = false - so0.deleted = false state.setStateObject(so0) - state.Finalise(false) - state.AccountsIntermediateRoot() - root, _, _ := state.Commit(0, nil) - state, _ = New(root, state.db, state.snaps) - - // and one with deleted == true - so1 := state.getStateObject(stateobjaddr1) - so1.SetBalance(uint256.NewInt(52)) - so1.SetNonce(53) - so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) - so1.selfDestructed = true - so1.deleted = true - state.setStateObject(so1) - - so1 = state.getStateObject(stateobjaddr1) - if so1 != nil { - t.Fatalf("deleted object not nil when getting") - } - - snapshot := state.Snapshot() - state.RevertToSnapshot(snapshot) - - so0Restored := state.getStateObject(stateobjaddr0) - // Update lazily-loaded values before comparing. - so0Restored.GetState(storageaddr) - so0Restored.Code() - // non-deleted is equal (restored) - compareStateObjects(so0Restored, so0, t) - - // deleted should be nil, both before and after restore of state copy - so1Restored := state.getStateObject(stateobjaddr1) - if so1Restored != nil { - t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored) - } -} - -func compareStateObjects(so0, so1 *stateObject, t *testing.T) { - if so0.Address() != so1.Address() { - t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address) - } - if so0.Balance().Cmp(so1.Balance()) != 0 { - t.Fatalf("Balance mismatch: have %v, want %v", so0.Balance(), so1.Balance()) - } - if so0.Nonce() != so1.Nonce() { - t.Fatalf("Nonce mismatch: have %v, want %v", so0.Nonce(), so1.Nonce()) - } - if so0.data.Root != so1.data.Root { - t.Errorf("Root mismatch: have %x, want %x", so0.data.Root[:], so1.data.Root[:]) - } - if !bytes.Equal(so0.CodeHash(), so1.CodeHash()) { - t.Fatalf("CodeHash mismatch: have %v, want %v", so0.CodeHash(), so1.CodeHash()) - } - if !bytes.Equal(so0.code, so1.code) { - t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code) - } - - if len(so1.dirtyStorage) != len(so0.dirtyStorage) { - t.Errorf("Dirty storage size mismatch: have %d, want %d", len(so1.dirtyStorage), len(so0.dirtyStorage)) - } - for k, v := range so1.dirtyStorage { - if so0.dirtyStorage[k] != v { - t.Errorf("Dirty storage key %x mismatch: have %v, want %v", k, so0.dirtyStorage[k], v) - } - } - for k, v := range so0.dirtyStorage { - if so1.dirtyStorage[k] != v { - t.Errorf("Dirty storage key %x mismatch: have %v, want none.", k, v) - } - } - if len(so1.originStorage) != len(so0.originStorage) { - t.Errorf("Origin storage size mismatch: have %d, want %d", len(so1.originStorage), len(so0.originStorage)) - } - for k, v := range so1.originStorage { - if so0.originStorage[k] != v { - t.Errorf("Origin storage key %x mismatch: have %v, want %v", k, so0.originStorage[k], v) - } - } - for k, v := range so0.originStorage { - if so1.originStorage[k] != v { - t.Errorf("Origin storage key %x mismatch: have %v, want none.", k, v) - } + state.RevertToSnapshot(snap) + if state.Exist(addr) { + t.Error("Unexpected account after revert") } } diff --git a/core/state/statedb.go b/core/state/statedb.go index b1eeb2e8f1..9b413b1f3f 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -20,37 +20,53 @@ package state import ( "errors" "fmt" - "runtime" - "sort" + "maps" + "math/big" + "slices" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" + "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" + "golang.org/x/sync/errgroup" ) +const defaultNumOfSlots = 100 + +// TriesInMemory represents the number of layers that are kept in RAM. +const TriesInMemory = 128 + +type mutationType int + const ( - defaultNumOfSlots = 100 - // storageDeleteLimit denotes the highest permissible memory allocation - // employed for contract storage deletion. - storageDeleteLimit = 512 * 1024 * 1024 + update mutationType = iota + deletion ) -type revision struct { - id int - journalIndex int +type mutation struct { + typ mutationType + applied bool +} + +func (m *mutation) copy() *mutation { + return &mutation{typ: m.typ, applied: m.applied} +} + +func (m *mutation) isDelete() bool { + return m.typ == deletion } // StateDB structs within the ethereum protocol are used to store anything @@ -70,33 +86,32 @@ type StateDB struct { prefetcher *triePrefetcher trie Trie noTrie bool - hasher crypto.KeccakState - snaps *snapshot.Tree // Nil if snapshot is not available - snap snapshot.Snapshot // Nil if snapshot is not available + logger *tracing.Hooks + reader Reader // originalRoot is the pre-state root, before any changes were made. // It will be updated when the Commit is called. originalRoot common.Hash expectedRoot common.Hash // The state root in the block header - stateRoot common.Hash // The calculation result of IntermediateRoot fullProcessed bool - // These maps hold the state changes (including the corresponding - // original value) that occurred in this **block**. - AccountMux sync.Mutex // Mutex for accounts access - StorageMux sync.Mutex // Mutex for storages access - accounts map[common.Hash][]byte // The mutated accounts in 'slim RLP' encoding - storages map[common.Hash]map[common.Hash][]byte // The mutated slots in prefix-zero trimmed rlp format - accountsOrigin map[common.Address][]byte // The original value of mutated accounts in 'slim RLP' encoding - storagesOrigin map[common.Address]map[common.Hash][]byte // The original value of mutated slots in prefix-zero trimmed rlp format - - // This map holds 'live' objects, which will get modified while processing - // a state transition. - stateObjects map[common.Address]*stateObject - stateObjectsPending map[common.Address]struct{} // State objects finalized but not yet written to the trie - stateObjectsDirty map[common.Address]struct{} // State objects modified in the current execution - stateObjectsDestruct map[common.Address]*types.StateAccount // State objects destructed in the block along with its previous value + // This map holds 'live' objects, which will get modified while + // processing a state transition. + stateObjects map[common.Address]*stateObject + + // This map holds 'deleted' objects. An object with the same address + // might also occur in the 'stateObjects' map due to account + // resurrection. The account value is tracked as the original value + // before the transition. This map is populated at the transaction + // boundaries. + stateObjectsDestruct map[common.Address]*stateObject + + // This map tracks the account mutations that occurred during the + // transition. Uncommitted mutations belonging to the same account + // can be merged into a single one which is equivalent from database's + // perspective. This map is populated at the transaction boundaries. + mutations map[common.Address]*mutation storagePool *StoragePool // sharedPool to store L1 originStorage of stateObjects writeOnSharedStorage bool // Write to the shared origin storage of a stateObject while reading from the underlying storage layer. @@ -122,45 +137,43 @@ type StateDB struct { preimages map[common.Hash][]byte // Per-transaction access list - accessList *accessList + accessList *accessList + accessEvents *AccessEvents // Transient storage transientStorage transientStorage // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. - journal *journal - validRevisions []revision - nextRevisionId int + journal *journal + + // State witness if cross validation is needed + witness *stateless.Witness // Measurements gathered during execution for debugging purposes // MetricsMux should be used in more places, but will affect on performance, so following meteration is not accruate - MetricsMux sync.Mutex - AccountReads time.Duration - AccountHashes time.Duration - AccountUpdates time.Duration - AccountCommits time.Duration - StorageReads time.Duration - StorageHashes time.Duration - StorageUpdates time.Duration - StorageCommits time.Duration - SnapshotAccountReads time.Duration - SnapshotStorageReads time.Duration - SnapshotCommits time.Duration - TrieDBCommits time.Duration - - AccountUpdated int - StorageUpdated int - AccountDeleted int - StorageDeleted int - - // Testing hooks - onCommit func(states *triestate.Set) // Hook invoked when commit is performed + MetricsMux sync.Mutex + AccountReads time.Duration + AccountHashes time.Duration + AccountUpdates time.Duration + AccountCommits time.Duration + StorageReads time.Duration + StorageUpdates time.Duration + StorageCommits time.Duration + SnapshotCommits time.Duration + TrieDBCommits time.Duration + + AccountLoaded int // Number of accounts retrieved from the database during the state transition + AccountUpdated int // Number of accounts updated during the state transition + AccountDeleted int // Number of accounts deleted during the state transition + StorageLoaded int // Number of storage slots retrieved from the database during the state transition + StorageUpdated atomic.Int64 // Number of storage slots updated during the state transition + StorageDeleted atomic.Int64 // Number of storage slots deleted during the state transition } // NewWithSharedPool creates a new state with sharedStorge on layer 1.5 -func NewWithSharedPool(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) { - statedb, err := New(root, db, snaps) +func NewWithSharedPool(root common.Hash, db Database) (*StateDB, error) { + statedb, err := New(root, db) if err != nil { return nil, err } @@ -169,37 +182,33 @@ func NewWithSharedPool(root common.Hash, db Database, snaps *snapshot.Tree) (*St } // New creates a new state from a given trie. -func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) { +func New(root common.Hash, db Database) (*StateDB, error) { + tr, err := db.OpenTrie(root) + if err != nil { + return nil, err + } + reader, err := db.Reader(root) + if err != nil { + return nil, err + } sdb := &StateDB{ db: db, + trie: tr, originalRoot: root, - snaps: snaps, - accounts: make(map[common.Hash][]byte), - storages: make(map[common.Hash]map[common.Hash][]byte), - accountsOrigin: make(map[common.Address][]byte), - storagesOrigin: make(map[common.Address]map[common.Hash][]byte), + reader: reader, stateObjects: make(map[common.Address]*stateObject, defaultNumOfSlots), - stateObjectsPending: make(map[common.Address]struct{}, defaultNumOfSlots), - stateObjectsDirty: make(map[common.Address]struct{}, defaultNumOfSlots), - stateObjectsDestruct: make(map[common.Address]*types.StateAccount, defaultNumOfSlots), + stateObjectsDestruct: make(map[common.Address]*stateObject, defaultNumOfSlots), + mutations: make(map[common.Address]*mutation, defaultNumOfSlots), logs: make(map[common.Hash][]*types.Log), preimages: make(map[common.Hash][]byte), journal: newJournal(), accessList: newAccessList(), transientStorage: newTransientStorage(), - hasher: crypto.NewKeccakState(), - } - - if sdb.snaps != nil { - sdb.snap = sdb.snaps.Snapshot(root) - } - - tr, err := db.OpenTrie(root) - if err != nil { - return nil, err } _, sdb.noTrie = tr.(*trie.EmptyTrie) - sdb.trie = tr + if db.TrieDB().IsVerkle() { + sdb.accessEvents = NewAccessEvents(db.PointCache()) + } return sdb, nil } @@ -226,27 +235,27 @@ func (s *StateDB) TransferPrefetcher(prev *StateDB) { s.prefetcherLock.Unlock() } +// SetLogger sets the logger for account update hooks. +func (s *StateDB) SetLogger(l *tracing.Hooks) { + s.logger = l +} + // StartPrefetcher initializes a new trie prefetcher to pull in nodes from the // state trie concurrently while the state is mutated so that when we reach the // commit phase, most of the needed data is already hot. -func (s *StateDB) StartPrefetcher(namespace string) { +func (s *StateDB) StartPrefetcher(namespace string, witness *stateless.Witness) { if s.noTrie { return } - s.prefetcherLock.Lock() - defer s.prefetcherLock.Unlock() - if s.prefetcher != nil { - s.prefetcher.close() - s.prefetcher = nil - } - if s.snap != nil { - parent := s.snap.Parent() - if parent != nil { - s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, parent.Root(), namespace) - } else { - s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, common.Hash{}, namespace) - } - } + + // Terminate any previously running prefetcher + s.StopPrefetcher() + + // Enable witness collection if requested + s.witness = witness + + s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, common.Hash{}, namespace, witness == nil) + } // StopPrefetcher terminates a running prefetcher and reports any leftover stats @@ -288,7 +297,7 @@ func (s *StateDB) TriePrefetchInAdvance(block *types.Block, signer types.Signer) } if len(addressesToPrefetch) > 0 { - prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch) + prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch, true) } } @@ -319,11 +328,14 @@ func (s *StateDB) Error() error { } func (s *StateDB) AddLog(log *types.Log) { - s.journal.append(addLogChange{txhash: s.thash}) + s.journal.logChange(s.thash) log.TxHash = s.thash log.TxIndex = uint(s.txIndex) log.Index = s.logSize + if s.logger != nil && s.logger.OnLog != nil { + s.logger.OnLog(log) + } s.logs[s.thash] = append(s.logs[s.thash], log) s.logSize++ } @@ -350,10 +362,7 @@ func (s *StateDB) Logs() []*types.Log { // AddPreimage records a SHA3 preimage seen by the VM. func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) { if _, ok := s.preimages[hash]; !ok { - s.journal.append(addPreimageChange{hash: hash}) - pi := make([]byte, len(preimage)) - copy(pi, preimage) - s.preimages[hash] = pi + s.preimages[hash] = slices.Clone(preimage) } } @@ -364,14 +373,14 @@ func (s *StateDB) Preimages() map[common.Hash][]byte { // AddRefund adds gas to the refund counter func (s *StateDB) AddRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) + s.journal.refundChange(s.refund) s.refund += gas } // SubRefund removes gas from the refund counter. // This method will panic if the refund counter goes below zero func (s *StateDB) SubRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) + s.journal.refundChange(s.refund) if gas > s.refund { panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund)) } @@ -420,7 +429,7 @@ func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash { return common.Hash{} } -// TxIndex returns the current transaction index set by Prepare. +// TxIndex returns the current transaction index set by SetTxContext. func (s *StateDB) TxIndex() int { return s.txIndex } @@ -457,7 +466,7 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash { return common.Hash{} } -// GetState retrieves a value from the given account's storage trie. +// GetState retrieves the value associated with the specific key. func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { stateObject := s.getStateObject(addr) if stateObject != nil { @@ -466,7 +475,8 @@ func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { return common.Hash{} } -// GetCommittedState retrieves a value from the given account's committed storage trie. +// GetCommittedState retrieves the value associated with the specific key +// without any mutations caused in the current execution. func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { stateObject := s.getStateObject(addr) if stateObject != nil { @@ -493,25 +503,25 @@ func (s *StateDB) HasSelfDestructed(addr common.Address) bool { */ // AddBalance adds amount to the account associated with addr. -func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int) { +func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { - stateObject.AddBalance(amount) + stateObject.AddBalance(amount, reason) } } // SubBalance subtracts amount from the account associated with addr. -func (s *StateDB) SubBalance(addr common.Address, amount *uint256.Int) { +func (s *StateDB) SubBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { - stateObject.SubBalance(amount) + stateObject.SubBalance(amount, reason) } } -func (s *StateDB) SetBalance(addr common.Address, amount *uint256.Int) { +func (s *StateDB) SetBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { - stateObject.SetBalance(amount) + stateObject.SetBalance(amount, reason) } } @@ -540,20 +550,28 @@ func (s *StateDB) SetState(addr common.Address, key, value common.Hash) { // storage. This function should only be used for debugging and the mutations // must be discarded afterwards. func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { - // SetStorage needs to wipe existing storage. We achieve this by pretending - // that the account self-destructed earlier in this block, by flagging - // it in stateObjectsDestruct. The effect of doing so is that storage lookups - // will not hit disk, since it is assumed that the disk-data is belonging + // SetStorage needs to wipe the existing storage. We achieve this by marking + // the account as self-destructed in this block. The effect is that storage + // lookups will not hit the disk, as it is assumed that the disk data belongs // to a previous incarnation of the object. // - // TODO(rjl493456442) this function should only be supported by 'unwritable' - // state and all mutations made should all be discarded afterwards. - if _, ok := s.stateObjectsDestruct[addr]; !ok { - s.stateObjectsDestruct[addr] = nil + // TODO (rjl493456442): This function should only be supported by 'unwritable' + // state, and all mutations made should be discarded afterward. + obj := s.getStateObject(addr) + if obj != nil { + if _, ok := s.stateObjectsDestruct[addr]; !ok { + s.stateObjectsDestruct[addr] = obj + } } - stateObject := s.getOrNewStateObject(addr) + newObj := s.createObject(addr) for k, v := range storage { - stateObject.SetState(k, v) + newObj.SetState(k, v) + } + // Inherit the metadata of original object if it was existent + if obj != nil { + newObj.SetCode(common.BytesToHash(obj.CodeHash()), obj.code) + newObj.SetNonce(obj.Nonce()) + newObj.SetBalance(obj.Balance(), tracing.BalanceChangeUnspecified) } } @@ -567,13 +585,17 @@ func (s *StateDB) SelfDestruct(addr common.Address) { if stateObject == nil { return } - s.journal.append(selfDestructChange{ - account: &addr, - prev: stateObject.selfDestructed, - prevbalance: new(uint256.Int).Set(stateObject.Balance()), - }) - stateObject.markSelfdestructed() - stateObject.data.Balance = new(uint256.Int) + // Regardless of whether it is already destructed or not, we do have to + // journal the balance-change, if we set it to zero here. + if !stateObject.Balance().IsZero() { + stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct) + } + // If it is already marked as self-destructed, we do not need to add it + // for journalling a second time. + if !stateObject.selfDestructed { + s.journal.destruct(addr) + stateObject.markSelfdestructed() + } } func (s *StateDB) Selfdestruct6780(addr common.Address) { @@ -581,8 +603,7 @@ func (s *StateDB) Selfdestruct6780(addr common.Address) { if stateObject == nil { return } - - if stateObject.created { + if stateObject.newContract { s.SelfDestruct(addr) } } @@ -595,11 +616,7 @@ func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) if prev == value { return } - s.journal.append(transientStorageChange{ - account: &addr, - key: key, - prevalue: prev, - }) + s.journal.transientStateChange(addr, key, prev) s.setTransientState(addr, key, value) } @@ -623,120 +640,64 @@ func (s *StateDB) updateStateObject(obj *stateObject) { if s.noTrie { return } - // Track the amount of time wasted on updating the account from the trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) - } + // Encode the account and update the account trie addr := obj.Address() - if err := s.trie.UpdateAccount(addr, &obj.data); err != nil { + if err := s.trie.UpdateAccount(addr, &obj.data, len(obj.code)); err != nil { s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err)) } if obj.dirtyCode { s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code) } - - // Track the original value of mutated account, nil means it was not present. - // Skip if it has been tracked (because updateStateObject may be called - // multiple times in a block). - if _, ok := s.accountsOrigin[obj.address]; !ok { - if obj.origin == nil { - s.accountsOrigin[obj.address] = nil - } else { - s.accountsOrigin[obj.address] = types.SlimAccountRLP(*obj.origin) - } - } } // deleteStateObject removes the given object from the state trie. -func (s *StateDB) deleteStateObject(obj *stateObject) { +func (s *StateDB) deleteStateObject(addr common.Address) { if s.noTrie { return } - // Track the amount of time wasted on deleting the account from the trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) - } + // Delete the account from the trie - addr := obj.Address() if err := s.trie.DeleteAccount(addr); err != nil { s.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err)) } } // getStateObject retrieves a state object given by the address, returning nil if -// the object is not found or was deleted in this execution context. If you need -// to differentiate between non-existent/just-deleted, use getDeletedStateObject. +// the object is not found or was deleted in this execution context. func (s *StateDB) getStateObject(addr common.Address) *stateObject { - if obj := s.getDeletedStateObject(addr); obj != nil && !obj.deleted { - return obj - } - return nil -} - -// getDeletedStateObject is similar to getStateObject, but instead of returning -// nil for a deleted state object, it returns the actual object with the deleted -// flag set. This is needed by the state journal to revert to the correct s- -// destructed object instead of wiping all knowledge about the state object. -func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { // Prefer live objects if any is available if obj := s.stateObjects[addr]; obj != nil { return obj } - // If no live objects are available, attempt to use snapshots - var data *types.StateAccount - if s.snap != nil { - start := time.Now() - acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())) - if metrics.EnabledExpensive { - s.SnapshotAccountReads += time.Since(start) - } - if err == nil { - if acc == nil { - return nil - } - data = &types.StateAccount{ - Nonce: acc.Nonce, - Balance: acc.Balance, - CodeHash: acc.CodeHash, - Root: common.BytesToHash(acc.Root), - } - if len(data.CodeHash) == 0 { - data.CodeHash = types.EmptyCodeHash.Bytes() - } - if data.Root == (common.Hash{}) { - data.Root = types.EmptyRootHash - } - } + // Short circuit if the account is already destructed in this block. + if _, ok := s.stateObjectsDestruct[addr]; ok { + return nil } + s.AccountLoaded++ - // If snapshot unavailable or reading from it failed, load from the database - if data == nil { - if s.trie == nil { - tr, err := s.db.OpenTrie(s.originalRoot) - if err != nil { - s.setError(errors.New("failed to open trie tree")) - return nil - } - s.trie = tr - } - start := time.Now() - var err error - data, err = s.trie.GetAccount(addr) - if metrics.EnabledExpensive { - s.AccountReads += time.Since(start) - } - if err != nil { - s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err)) - return nil - } - if data == nil { - return nil + start := time.Now() + acct, err := s.reader.Account(addr) + if err != nil { + s.setError(fmt.Errorf("getStateObject (%x) error: %w", addr.Bytes(), err)) + return nil + } + s.AccountReads += time.Since(start) + + // Short circuit if the account is not found + if acct == nil { + return nil + } + // Schedule the resolved account for prefetching if it's enabled. + if s.prefetcher != nil { + if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, [][]byte{addr[:]}, true); err != nil { + log.Error("Failed to prefetch account", "addr", addr, "err", err) } } // Insert into the live set - obj := newObject(s, addr, data) + obj := newObject(s, addr, acct) s.setStateObject(obj) + s.AccountLoaded++ return obj } @@ -746,69 +707,40 @@ func (s *StateDB) setStateObject(object *stateObject) { // getOrNewStateObject retrieves a state object or create a new state object if nil. func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject { - stateObject := s.getStateObject(addr) - if stateObject == nil { - stateObject, _ = s.createObject(addr) + obj := s.getStateObject(addr) + if obj == nil { + obj = s.createObject(addr) } - return stateObject + return obj } -// createObject creates a new state object. If there is an existing account with -// the given address, it is overwritten and returned as the second return value. -func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { - prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that! - newobj = newObject(s, addr, nil) - if prev == nil { - s.journal.append(createObjectChange{account: &addr}) - } else { - // The original account should be marked as destructed and all cached - // account and storage data should be cleared as well. Note, it must - // be done here, otherwise the destruction event of "original account" - // will be lost. - _, prevdestruct := s.stateObjectsDestruct[prev.address] - if !prevdestruct { - s.stateObjectsDestruct[prev.address] = prev.origin - } - // There may be some cached account/storage data already since IntermediateRoot - // will be called for each transaction before byzantium fork which will always - // cache the latest account/storage data. - prevAccount, ok := s.accountsOrigin[prev.address] - s.journal.append(resetObjectChange{ - account: &addr, - prev: prev, - prevdestruct: prevdestruct, - prevAccount: s.accounts[prev.addrHash], - prevStorage: s.storages[prev.addrHash], - prevAccountOriginExist: ok, - prevAccountOrigin: prevAccount, - prevStorageOrigin: s.storagesOrigin[prev.address], - }) - delete(s.accounts, prev.addrHash) - delete(s.storages, prev.addrHash) - delete(s.accountsOrigin, prev.address) - delete(s.storagesOrigin, prev.address) - } - s.setStateObject(newobj) - if prev != nil && !prev.deleted { - return newobj, prev - } - return newobj, nil +// createObject creates a new state object. The assumption is held there is no +// existing account with the given address, otherwise it will be silently overwritten. +func (s *StateDB) createObject(addr common.Address) *stateObject { + obj := newObject(s, addr, nil) + s.journal.createObject(addr) + s.setStateObject(obj) + return obj } -// CreateAccount explicitly creates a state object. If a state object with the address -// already exists the balance is carried over to the new account. -// -// CreateAccount is called during the EVM CREATE operation. The situation might arise that -// a contract does the following: -// -// 1. sends funds to sha(account ++ (nonce + 1)) -// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) -// -// Carrying over the balance ensures that Ether doesn't disappear. +// CreateAccount explicitly creates a new state object, assuming that the +// account did not previously exist in the state. If the account already +// exists, this function will silently overwrite it which might lead to a +// consensus bug eventually. func (s *StateDB) CreateAccount(addr common.Address) { - newObj, prev := s.createObject(addr) - if prev != nil { - newObj.setBalance(prev.data.Balance) + s.createObject(addr) +} + +// CreateContract is used whenever a contract is created. This may be preceded +// by CreateAccount, but that is not required if it already existed in the +// state due to funds sent beforehand. +// This operation sets the 'newContract'-flag, which is required in order to +// correctly handle EIP-6780 'delete-in-same-transaction' logic. +func (s *StateDB) CreateContract(addr common.Address) { + obj := s.getStateObject(addr) + if !obj.newContract { + obj.newContract = true + s.journal.createContract(addr) } } @@ -829,79 +761,53 @@ func (s *StateDB) copyInternal(doPrefetch bool) *StateDB { // Copy all the basic fields, initialize the memory ones state := &StateDB{ db: s.db, - trie: s.db.CopyTrie(s.trie), + trie: mustCopyTrie(s.trie), // noTrie:s.noTrie, + reader: s.reader.Copy(), // expectedRoot: s.expectedRoot, - // stateRoot: s.stateRoot, originalRoot: s.originalRoot, - // fullProcessed: s.fullProcessed, - accounts: make(map[common.Hash][]byte), - storages: make(map[common.Hash]map[common.Hash][]byte), - accountsOrigin: make(map[common.Address][]byte), - storagesOrigin: make(map[common.Address]map[common.Hash][]byte), + // fullProcessed: s.fullProcessed, stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), - stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), - stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), - stateObjectsDestruct: make(map[common.Address]*types.StateAccount, len(s.stateObjectsDestruct)), + stateObjectsDestruct: make(map[common.Address]*stateObject, len(s.stateObjectsDestruct)), + mutations: make(map[common.Address]*mutation, len(s.mutations)), + dbErr: s.dbErr, storagePool: s.storagePool, // writeOnSharedStorage: s.writeOnSharedStorage, refund: s.refund, + thash: s.thash, + txIndex: s.txIndex, logs: make(map[common.Hash][]*types.Log, len(s.logs)), logSize: s.logSize, - preimages: make(map[common.Hash][]byte, len(s.preimages)), - journal: newJournal(), - hasher: crypto.NewKeccakState(), - - // In order for the block producer to be able to use and make additions - // to the snapshot tree, we need to copy that as well. Otherwise, any - // block mined by ourselves will cause gaps in the tree, and force the - // miner to operate trie-backed only. - snaps: s.snaps, - snap: s.snap, - } - // Copy the dirty states, logs, and preimages - for addr := range s.journal.dirties { - // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), - // and in the Finalise-method, there is a case where an object is in the journal but not - // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for - // nil - if object, exist := s.stateObjects[addr]; exist { - // Even though the original object is dirty, we are not copying the journal, - // so we need to make sure that any side-effect the journal would have caused - // during a commit (or similar op) is already applied to the copy. - state.stateObjects[addr] = object.deepCopy(state) - - state.stateObjectsDirty[addr] = struct{}{} // Mark the copy dirty to force internal (code/state) commits - state.stateObjectsPending[addr] = struct{}{} // Mark the copy pending to force external (account) commits - } + preimages: maps.Clone(s.preimages), + + // Do we need to copy the access list and transient storage? + // In practice: No. At the start of a transaction, these two lists are empty. + // In practice, we only ever copy state _between_ transactions/blocks, never + // in the middle of a transaction. However, it doesn't cost us much to copy + // empty lists, so we do it anyway to not blow up if we ever decide copy them + // in the middle of a transaction. + accessList: s.accessList.Copy(), + transientStorage: s.transientStorage.Copy(), + journal: s.journal.copy(), } - // Above, we don't copy the actual journal. This means that if the copy - // is copied, the loop above will be a no-op, since the copy's journal - // is empty. Thus, here we iterate over stateObjects, to enable copies - // of copies. - for addr := range s.stateObjectsPending { - if _, exist := state.stateObjects[addr]; !exist { - state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) - } - state.stateObjectsPending[addr] = struct{}{} + if s.witness != nil { + state.witness = s.witness.Copy() } - for addr := range s.stateObjectsDirty { - if _, exist := state.stateObjects[addr]; !exist { - state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) - } - state.stateObjectsDirty[addr] = struct{}{} + if s.accessEvents != nil { + state.accessEvents = s.accessEvents.Copy() } - // Deep copy the destruction markers. - for addr, value := range s.stateObjectsDestruct { - state.stateObjectsDestruct[addr] = value + // Deep copy cached state objects. + for addr, obj := range s.stateObjects { + state.stateObjects[addr] = obj.deepCopy(state) + } + // Deep copy destructed state objects. + for addr, obj := range s.stateObjectsDestruct { + state.stateObjectsDestruct[addr] = obj.deepCopy(state) + } + // Deep copy the object state markers. + for addr, op := range s.mutations { + state.mutations[addr] = op.copy() } - // Deep copy the state changes made in the scope of block - // along with their original values. - state.accounts = copySet(s.accounts) - state.storages = copy2DSet(s.storages) - state.accountsOrigin = copySet(s.accountsOrigin) - state.storagesOrigin = copy2DSet(s.storagesOrigin) - // Deep copy the logs occurred in the scope of block for hash, logs := range s.logs { cpy := make([]*types.Log, len(logs)) @@ -911,53 +817,17 @@ func (s *StateDB) copyInternal(doPrefetch bool) *StateDB { } state.logs[hash] = cpy } - // Deep copy the preimages occurred in the scope of block - for hash, preimage := range s.preimages { - state.preimages[hash] = preimage - } - // Do we need to copy the access list and transient storage? - // In practice: No. At the start of a transaction, these two lists are empty. - // In practice, we only ever copy state _between_ transactions/blocks, never - // in the middle of a transaction. However, it doesn't cost us much to copy - // empty lists, so we do it anyway to not blow up if we ever decide copy them - // in the middle of a transaction. - if s.accessList != nil { - state.accessList = s.accessList.Copy() - } - state.transientStorage = s.transientStorage.Copy() - - state.prefetcher = s.prefetcher - if s.prefetcher != nil && !doPrefetch { - // If there's a prefetcher running, make an inactive copy of it that can - // only access data but does not actively preload (since the user will not - // know that they need to explicitly terminate an active copy). - state.prefetcher = state.prefetcher.copy() - } return state } // Snapshot returns an identifier for the current revision of the state. func (s *StateDB) Snapshot() int { - id := s.nextRevisionId - s.nextRevisionId++ - s.validRevisions = append(s.validRevisions, revision{id, s.journal.length()}) - return id + return s.journal.snapshot() } // RevertToSnapshot reverts all state changes made since the given revision. func (s *StateDB) RevertToSnapshot(revid int) { - // Find the snapshot in the stack of valid snapshots. - idx := sort.Search(len(s.validRevisions), func(i int) bool { - return s.validRevisions[i].id >= revid - }) - if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { - panic(fmt.Errorf("revision id %v cannot be reverted", revid)) - } - snapshot := s.validRevisions[idx].journalIndex - - // Replay the journal to undo changes and remove invalidated snapshots - s.journal.revert(s, snapshot) - s.validRevisions = s.validRevisions[:idx] + s.journal.revertToSnapshot(revid, s) } // GetRefund returns the current value of the refund counter. @@ -982,36 +852,32 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { continue } if obj.selfDestructed || (deleteEmptyObjects && obj.empty()) { - obj.deleted = true + delete(s.stateObjects, obj.address) + s.markDelete(addr) + // If ether was sent to account post-selfdestruct it is burnt. + if bal := obj.Balance(); s.logger != nil && s.logger.OnBalanceChange != nil && obj.selfDestructed && bal.Sign() != 0 { + s.logger.OnBalanceChange(obj.address, bal.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestructBurn) + } // We need to maintain account deletions explicitly (will remain // set indefinitely). Note only the first occurred self-destruct // event is tracked. if _, ok := s.stateObjectsDestruct[obj.address]; !ok { - s.stateObjectsDestruct[obj.address] = obj.origin + s.stateObjectsDestruct[obj.address] = obj } - // Note, we can't do this only at the end of a block because multiple - // transactions within the same block might self destruct and then - // resurrect an account; but the snapshotter needs both events. - delete(s.accounts, obj.addrHash) // Clear out any previously updated account data (may be recreated via a resurrect) - delete(s.storages, obj.addrHash) // Clear out any previously updated storage data (may be recreated via a resurrect) - delete(s.accountsOrigin, obj.address) // Clear out any previously updated account data (may be recreated via a resurrect) - delete(s.storagesOrigin, obj.address) // Clear out any previously updated storage data (may be recreated via a resurrect) } else { - obj.finalise(true) // Prefetch slots in the background + obj.finalise() + s.markUpdate(addr) } - obj.created = false - s.stateObjectsPending[addr] = struct{}{} - s.stateObjectsDirty[addr] = struct{}{} - // At this point, also ship the address off to the precacher. The precacher // will start loading tries, and when the change is eventually committed, // the commit-phase will be a lot faster addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure } - prefetcher := s.prefetcher - if prefetcher != nil && len(addressesToPrefetch) > 0 { - prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch) + if s.prefetcher != nil && len(addressesToPrefetch) > 0 { + if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch, false); err != nil { + log.Error("Failed to prefetch addresses", "addresses", len(addressesToPrefetch), "err", err) + } } // Invalidate journal because reverting across transactions is not allowed. s.clearJournalAndRefund() @@ -1023,70 +889,95 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // Finalise all the dirty storage states and write them into the tries s.Finalise(deleteEmptyObjects) - s.AccountsIntermediateRoot() - return s.StateIntermediateRoot() -} - -func (s *StateDB) AccountsIntermediateRoot() { - tasks := make(chan func()) - finishCh := make(chan struct{}) - defer close(finishCh) - wg := sync.WaitGroup{} - for i := 0; i < runtime.NumCPU(); i++ { - go func() { - for { - select { - case task := <-tasks: - task() - case <-finishCh: - return - } - } - }() - } - - // Although naively it makes sense to retrieve the account trie and then do - // the contract storage and account updates sequentially, that short circuits - // the account prefetcher. Instead, let's process all the storage updates - // first, giving the account prefetches just a few more milliseconds of time - // to pull useful data from disk. - for addr := range s.stateObjectsPending { - if obj := s.stateObjects[addr]; !obj.deleted { - wg.Add(1) - tasks <- func() { - obj.updateRoot() - // Cache the data until commit. Note, this update mechanism is not symmetric - // to the deletion, because whereas it is enough to track account updates - // at commit time, deletions need tracking at transaction boundary level to - // ensure we capture state clearing. - s.AccountMux.Lock() - s.accounts[obj.addrHash] = types.SlimAccountRLP(obj.data) - s.AccountMux.Unlock() + // If there was a trie prefetcher operating, terminate it async so that the + // individual storage tries can be updated as soon as the disk load finishes. + if s.prefetcher != nil { + defer s.StopPrefetcher() + } + // Process all storage updates concurrently. The state object update root + // method will internally call a blocking trie fetch from the prefetcher, + // so there's no need to explicitly wait for the prefetchers to finish. + var ( + start = time.Now() + workers errgroup.Group + ) + if s.db.TrieDB().IsVerkle() { + // Whilst MPT storage tries are independent, Verkle has one single trie + // for all the accounts and all the storage slots merged together. The + // former can thus be simply parallelized, but updating the latter will + // need concurrency support within the trie itself. That's a TODO for a + // later time. + workers.SetLimit(1) + } + for addr, op := range s.mutations { + if op.applied || op.isDelete() { + continue + } + obj := s.stateObjects[addr] // closure for the task runner below + workers.Go(func() error { + if s.db.TrieDB().IsVerkle() { + obj.updateTrie() + } else { + obj.updateRoot() - wg.Done() + // If witness building is enabled and the state object has a trie, + // gather the witnesses for its specific storage trie + if s.witness != nil && obj.trie != nil { + s.witness.AddState(obj.trie.Witness()) + } + } + return nil + }) + } + // If witness building is enabled, gather all the read-only accesses. + // Skip witness collection in Verkle mode, they will be gathered + // together at the end. + if s.witness != nil && !s.db.TrieDB().IsVerkle() { + // Pull in anything that has been accessed before destruction + for _, obj := range s.stateObjectsDestruct { + // Skip any objects that haven't touched their storage + if len(obj.originStorage) == 0 { + continue + } + if trie := obj.getPrefetchedTrie(); trie != nil { + s.witness.AddState(trie.Witness()) + } else if obj.trie != nil { + s.witness.AddState(obj.trie.Witness()) + } + } + // Pull in only-read and non-destructed trie witnesses + for _, obj := range s.stateObjects { + // Skip any objects that have been updated + if _, ok := s.mutations[obj.address]; ok { + continue + } + // Skip any objects that haven't touched their storage + if len(obj.originStorage) == 0 { + continue + } + if trie := obj.getPrefetchedTrie(); trie != nil { + s.witness.AddState(trie.Witness()) + } else if obj.trie != nil { + s.witness.AddState(obj.trie.Witness()) } } } - wg.Wait() -} - -func (s *StateDB) StateIntermediateRoot() common.Hash { - // If there was a trie prefetcher operating, it gets aborted and irrevocably - // modified after we start retrieving tries. Remove it from the statedb after - // this round of use. - // - // This is weird pre-byzantium since the first tx runs with a prefetcher and - // the remainder without, but pre-byzantium even the initial prefetcher is - // useless, so no sleep lost. - prefetcher := s.prefetcher - defer s.StopPrefetcher() + workers.Wait() + s.StorageUpdates += time.Since(start) // Now we're about to start to write changes to the trie. The trie is so far // _untouched_. We can check with the prefetcher, if it can give us a trie // which has the same root, but also has some content loaded into it. - if prefetcher != nil { - if trie := prefetcher.trie(common.Hash{}, s.originalRoot); trie != nil { + // + // Don't check prefetcher if verkle trie has been used. In the context of verkle, + // only a single trie is used for state hashing. Replacing a non-nil verkle tree + // here could result in losing uncommitted changes from storage. + start = time.Now() + if s.prefetcher != nil { + if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil { + log.Error("Failed to retrieve account pre-fetcher trie") + } else { s.trie = trie } } @@ -1097,33 +988,59 @@ func (s *StateDB) StateIntermediateRoot() common.Hash { } s.trie = tr } - - usedAddrs := make([][]byte, 0, len(s.stateObjectsPending)) + // Perform updates before deletions. This prevents resolution of unnecessary trie nodes + // in circumstances similar to the following: + // + // Consider nodes `A` and `B` who share the same full node parent `P` and have no other siblings. + // During the execution of a block: + // - `A` self-destructs, + // - `C` is created, and also shares the parent `P`. + // If the self-destruct is handled first, then `P` would be left with only one child, thus collapsed + // into a shortnode. This requires `B` to be resolved from disk. + // Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved. + var ( + usedAddrs [][]byte + deletedAddrs []common.Address + ) if !s.noTrie { - for addr := range s.stateObjectsPending { - if obj := s.stateObjects[addr]; obj.deleted { - s.deleteStateObject(obj) + for addr, op := range s.mutations { + if op.applied { + continue + } + op.applied = true + + if op.isDelete() { + deletedAddrs = append(deletedAddrs, addr) } else { - s.updateStateObject(obj) + s.updateStateObject(s.stateObjects[addr]) + s.AccountUpdated += 1 } usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure } - if prefetcher != nil { - prefetcher.used(common.Hash{}, s.originalRoot, usedAddrs) + for _, deletedAddr := range deletedAddrs { + s.deleteStateObject(deletedAddr) + s.AccountDeleted += 1 } - } + s.AccountUpdates += time.Since(start) - if len(s.stateObjectsPending) > 0 { - s.stateObjectsPending = make(map[common.Address]struct{}) + if s.prefetcher != nil { + s.prefetcher.used(common.Hash{}, s.originalRoot, usedAddrs) + } } // Track the amount of time wasted on hashing the account trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) + defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) + + hash := s.trie.Hash() + + // If witness building is enabled, gather the account trie witness + if s.witness != nil { + s.witness.AddState(s.trie.Witness()) } + if s.noTrie { return s.expectedRoot } else { - return s.trie.Hash() + return hash } } @@ -1133,496 +1050,428 @@ func (s *StateDB) StateIntermediateRoot() common.Hash { func (s *StateDB) SetTxContext(thash common.Hash, ti int) { s.thash = thash s.txIndex = ti - s.accessList = nil // can't delete this line now, because StateDB.Prepare is not called before processsing a system transaction + s.accessList = nil // can't delete this line now, because StateDB.Prepare is not called before processing a system transaction } func (s *StateDB) clearJournalAndRefund() { - if len(s.journal.entries) > 0 { - s.journal = newJournal() - s.refund = 0 - } - s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries + s.journal.reset() + s.refund = 0 } // fastDeleteStorage is the function that efficiently deletes the storage trie // of a specific account. It leverages the associated state snapshot for fast // storage iteration and constructs trie node deletion markers by creating // stack trie with iterated slots. -func (s *StateDB) fastDeleteStorage(addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { - iter, err := s.snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{}) +func (s *StateDB) fastDeleteStorage(snaps *snapshot.Tree, addrHash common.Hash, root common.Hash) (map[common.Hash][]byte, *trienode.NodeSet, error) { + iter, err := snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{}) if err != nil { - return false, 0, nil, nil, err + return nil, nil, err } defer iter.Release() var ( - size common.StorageSize nodes = trienode.NewNodeSet(addrHash) slots = make(map[common.Hash][]byte) ) - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { + stack := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { nodes.AddNode(path, trienode.NewDeleted()) - size += common.StorageSize(len(path)) }) - stack := trie.NewStackTrie(options) for iter.Next() { - if size > storageDeleteLimit { - return true, size, nil, nil, nil - } slot := common.CopyBytes(iter.Slot()) if err := iter.Error(); err != nil { // error might occur after Slot function - return false, 0, nil, nil, err + return nil, nil, err } - size += common.StorageSize(common.HashLength + len(slot)) slots[iter.Hash()] = slot if err := stack.Update(iter.Hash().Bytes(), slot); err != nil { - return false, 0, nil, nil, err + return nil, nil, err } } if err := iter.Error(); err != nil { // error might occur during iteration - return false, 0, nil, nil, err + return nil, nil, err } if stack.Hash() != root { - return false, 0, nil, nil, fmt.Errorf("snapshot is not matched, exp %x, got %x", root, stack.Hash()) + return nil, nil, fmt.Errorf("snapshot is not matched, exp %x, got %x", root, stack.Hash()) } - return false, size, slots, nodes, nil + return slots, nodes, nil } // slowDeleteStorage serves as a less-efficient alternative to "fastDeleteStorage," // employed when the associated state snapshot is not available. It iterates the // storage slots along with all internal trie nodes via trie directly. -func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { +func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (map[common.Hash][]byte, *trienode.NodeSet, error) { tr, err := s.db.OpenStorageTrie(s.originalRoot, addr, root, s.trie) if err != nil { - return false, 0, nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err) + return nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err) } // skip deleting storages for EmptyTrie if _, ok := tr.(*trie.EmptyTrie); ok { - return false, 0, nil, nil, nil + return nil, nil, nil } it, err := tr.NodeIterator(nil) if err != nil { - return false, 0, nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err) + return nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err) } var ( - size common.StorageSize nodes = trienode.NewNodeSet(addrHash) slots = make(map[common.Hash][]byte) ) for it.Next(true) { - if size > storageDeleteLimit { - return true, size, nil, nil, nil - } if it.Leaf() { slots[common.BytesToHash(it.LeafKey())] = common.CopyBytes(it.LeafBlob()) - size += common.StorageSize(common.HashLength + len(it.LeafBlob())) continue } if it.Hash() == (common.Hash{}) { continue } - size += common.StorageSize(len(it.Path())) nodes.AddNode(it.Path(), trienode.NewDeleted()) } if err := it.Error(); err != nil { - return false, 0, nil, nil, err + return nil, nil, err } - return false, size, slots, nodes, nil + return slots, nodes, nil } // deleteStorage is designed to delete the storage trie of a designated account. -// It could potentially be terminated if the storage size is excessively large, -// potentially leading to an out-of-memory panic. The function will make an attempt -// to utilize an efficient strategy if the associated state snapshot is reachable; -// otherwise, it will resort to a less-efficient approach. -func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, map[common.Hash][]byte, *trienode.NodeSet, error) { +// The function will make an attempt to utilize an efficient strategy if the +// associated state snapshot is reachable; otherwise, it will resort to a less +// efficient approach. +func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (map[common.Hash][]byte, *trienode.NodeSet, error) { var ( - start = time.Now() - err error - aborted bool - size common.StorageSize - slots map[common.Hash][]byte - nodes *trienode.NodeSet + err error + slots map[common.Hash][]byte + nodes *trienode.NodeSet ) // The fast approach can be failed if the snapshot is not fully // generated, or it's internally corrupted. Fallback to the slow // one just in case. - if s.snap != nil { - aborted, size, slots, nodes, err = s.fastDeleteStorage(addrHash, root) + snaps := s.db.Snapshot() + if snaps != nil { + slots, nodes, err = s.fastDeleteStorage(snaps, addrHash, root) } - if s.snap == nil || err != nil { - aborted, size, slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root) + if snaps == nil || err != nil { + slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root) } if err != nil { - return false, nil, nil, err - } - if metrics.EnabledExpensive { - if aborted { - slotDeletionSkip.Inc(1) - } - n := int64(len(slots)) - - slotDeletionMaxCount.UpdateIfGt(int64(len(slots))) - slotDeletionMaxSize.UpdateIfGt(int64(size)) - - slotDeletionTimer.UpdateSince(start) - slotDeletionCount.Mark(n) - slotDeletionSize.Mark(int64(size)) + return nil, nil, err } - return aborted, slots, nodes, nil + return slots, nodes, nil } // handleDestruction processes all destruction markers and deletes the account -// and associated storage slots if necessary. There are four possible situations -// here: +// and associated storage slots if necessary. There are four potential scenarios +// as following: // -// - the account was not existent and be marked as destructed -// -// - the account was not existent and be marked as destructed, -// however, it's resurrected later in the same block. -// -// - the account was existent and be marked as destructed -// -// - the account was existent and be marked as destructed, -// however it's resurrected later in the same block. +// (a) the account was not existent and be marked as destructed +// (b) the account was not existent and be marked as destructed, +// however, it's resurrected later in the same block. +// (c) the account was existent and be marked as destructed +// (d) the account was existent and be marked as destructed, +// however it's resurrected later in the same block. // // In case (a), nothing needs be deleted, nil to nil transition can be ignored. -// // In case (b), nothing needs be deleted, nil is used as the original value for // newly created account and storages -// // In case (c), **original** account along with its storages should be deleted, // with their values be tracked as original value. -// // In case (d), **original** account along with its storages should be deleted, // with their values be tracked as original value. -func (s *StateDB) handleDestruction(nodes *trienode.MergedNodeSet) (map[common.Address]struct{}, error) { - // Short circuit if geth is running with hash mode. This procedure can consume - // considerable time and storage deletion isn't supported in hash mode, thus - // preemptively avoiding unnecessary expenses. - incomplete := make(map[common.Address]struct{}) - if s.db.TrieDB().Scheme() == rawdb.HashScheme { - return incomplete, nil - } - for addr, prev := range s.stateObjectsDestruct { - // The original account was non-existing, and it's marked as destructed - // in the scope of block. It can be case (a) or (b). - // - for (a), skip it without doing anything. - // - for (b), track account's original value as nil. It may overwrite - // the data cached in s.accountsOrigin set by 'updateStateObject'. - addrHash := crypto.Keccak256Hash(addr[:]) +func (s *StateDB) handleDestruction() (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) { + var ( + nodes []*trienode.NodeSet + buf = crypto.NewKeccakState() + deletes = make(map[common.Hash]*accountDelete) + ) + for addr, prevObj := range s.stateObjectsDestruct { + prev := prevObj.origin + + // The account was non-existent, and it's marked as destructed in the scope + // of block. It can be either case (a) or (b) and will be interpreted as + // null->null state transition. + // - for (a), skip it without doing anything + // - for (b), the resurrected account with nil as original will be handled afterwards if prev == nil { - if _, ok := s.accounts[addrHash]; ok { - s.accountsOrigin[addr] = nil // case (b) - } continue } - // It can overwrite the data in s.accountsOrigin set by 'updateStateObject'. - s.accountsOrigin[addr] = types.SlimAccountRLP(*prev) // case (c) or (d) + // The account was existent, it can be either case (c) or (d). + addrHash := crypto.HashData(buf, addr.Bytes()) + op := &accountDelete{ + address: addr, + origin: types.SlimAccountRLP(*prev), + } + deletes[addrHash] = op - // Short circuit if the storage was empty. + // Short circuit if the origin storage was empty. if prev.Root == types.EmptyRootHash { continue } - // Remove storage slots belong to the account. - aborted, slots, set, err := s.deleteStorage(addr, addrHash, prev.Root) + // Remove storage slots belonging to the account. + slots, set, err := s.deleteStorage(addr, addrHash, prev.Root) if err != nil { - return nil, fmt.Errorf("failed to delete storage, err: %w", err) - } - // The storage is too huge to handle, skip it but mark as incomplete. - // For case (d), the account is resurrected might with a few slots - // created. In this case, wipe the entire storage state diff because - // of aborted deletion. - if aborted { - incomplete[addr] = struct{}{} - delete(s.storagesOrigin, addr) - continue - } - if s.storagesOrigin[addr] == nil { - s.storagesOrigin[addr] = slots - } else { - // It can overwrite the data in s.storagesOrigin[addrHash] set by - // 'object.updateTrie'. - for key, val := range slots { - s.storagesOrigin[addr][key] = val - } - } - if err := nodes.Merge(set); err != nil { - return nil, err + return nil, nil, fmt.Errorf("failed to delete storage, err: %w", err) } + op.storagesOrigin = slots + + // Aggregate the associated trie node changes. + nodes = append(nodes, set) } - return incomplete, nil + return deletes, nodes, nil } -// Once the state is committed, tries cached in stateDB (including account -// trie, storage tries) will no longer be functional. A new state instance -// must be created with new root and updated database for accessing post- -// commit states. -// -// The associated block number of the state transition is also provided -// for more chain context. -func (s *StateDB) Commit(block uint64, postCommitFunc func() error) (common.Hash, *types.DiffLayer, error) { +// GetTrie returns the account trie. +func (s *StateDB) GetTrie() Trie { + return s.trie +} + +// commit gathers the state mutations accumulated along with the associated +// trie changes, resetting all internal flags with the new state as the base. +func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) { // Short circuit in case any database failure occurred earlier. if s.dbErr != nil { s.StopPrefetcher() - return common.Hash{}, nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) + return nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) } // Finalize any pending changes and merge everything into the tries - var ( - diffLayer *types.DiffLayer - incomplete map[common.Address]struct{} - nodes = trienode.NewMergedNodeSet() - ) + s.IntermediateRoot(deleteEmptyObjects) - if s.snap != nil { - diffLayer = &types.DiffLayer{} + // Short circuit if any error occurs within the IntermediateRoot. + if s.dbErr != nil { + return nil, fmt.Errorf("commit aborted due to database error: %v", s.dbErr) } - - commmitTrie := func() error { - commitErr := func() error { - if s.stateRoot = s.StateIntermediateRoot(); s.fullProcessed && s.expectedRoot != s.stateRoot { - log.Error("Invalid merkle root", "remote", s.expectedRoot, "local", s.stateRoot) - return fmt.Errorf("invalid merkle root (remote: %x local: %x)", s.expectedRoot, s.stateRoot) - } - - var err error - // Handle all state deletions first - incomplete, err = s.handleDestruction(nodes) - if err != nil { - return err + // Commit objects to the trie, measuring the elapsed time + var ( + accountTrieNodesUpdated int + accountTrieNodesDeleted int + storageTrieNodesUpdated int + storageTrieNodesDeleted int + + lock sync.Mutex // protect two maps below + nodes = trienode.NewMergedNodeSet() // aggregated trie nodes + updates = make(map[common.Hash]*accountUpdate, len(s.mutations)) // aggregated account updates + + // merge aggregates the dirty trie nodes into the global set. + // + // Given that some accounts may be destroyed and then recreated within + // the same block, it's possible that a node set with the same owner + // may already exists. In such cases, these two sets are combined, with + // the later one overwriting the previous one if any nodes are modified + // or deleted in both sets. + // + // merge run concurrently across all the state objects and account trie. + merge = func(set *trienode.NodeSet) error { + if set == nil { + return nil } + lock.Lock() + defer lock.Unlock() - tasks := make(chan func()) - type taskResult struct { - err error - nodeSet *trienode.NodeSet + updates, deletes := set.Size() + if set.Owner == (common.Hash{}) { + accountTrieNodesUpdated += updates + accountTrieNodesDeleted += deletes + } else { + storageTrieNodesUpdated += updates + storageTrieNodesDeleted += deletes } - taskResults := make(chan taskResult, len(s.stateObjectsDirty)) - tasksNum := 0 - finishCh := make(chan struct{}) - - threads := gopool.Threads(len(s.stateObjectsDirty)) - wg := sync.WaitGroup{} - for i := 0; i < threads; i++ { - wg.Add(1) - go func() { - defer wg.Done() - for { - select { - case task := <-tasks: - task() - case <-finishCh: - return - } - } - }() + return nodes.Merge(set) + } + ) + // Given that some accounts could be destroyed and then recreated within + // the same block, account deletions must be processed first. This ensures + // that the storage trie nodes deleted during destruction and recreated + // during subsequent resurrection can be combined correctly. + deletes, delNodes, err := s.handleDestruction() + if err != nil { + return nil, err + } + for _, set := range delNodes { + if err := merge(set); err != nil { + return nil, err + } + } + // Handle all state updates afterwards, concurrently to one another to shave + // off some milliseconds from the commit operation. Also accumulate the code + // writes to run in parallel with the computations. + var ( + start = time.Now() + root common.Hash + workers errgroup.Group + ) + // Schedule the account trie first since that will be the biggest, so give + // it the most time to crunch. + // + // TODO(karalabe): This account trie commit is *very* heavy. 5-6ms at chain + // heads, which seems excessive given that it doesn't do hashing, it just + // shuffles some data. For comparison, the *hashing* at chain head is 2-3ms. + // We need to investigate what's happening as it seems something's wonky. + // Obviously it's not an end of the world issue, just something the original + // code didn't anticipate for. + workers.Go(func() error { + if !s.noTrie { + // Write the account trie changes, measuring the amount of wasted time + newroot, set := s.trie.Commit(true) + root = newroot + if s.fullProcessed && s.expectedRoot != root { + log.Error("Invalid merkle root", "remote", s.expectedRoot, "local", root) + return fmt.Errorf("invalid merkle root (remote: %x local: %x)", s.expectedRoot, root) } - for addr := range s.stateObjectsDirty { - if obj := s.stateObjects[addr]; !obj.deleted { - tasks <- func() { - // Write any storage changes in the state object to its storage trie - if !s.noTrie { - if set, err := obj.commit(); err != nil { - taskResults <- taskResult{err, nil} - return - } else { - taskResults <- taskResult{nil, set} - } - } else { - taskResults <- taskResult{nil, nil} - } - } - tasksNum++ - } + if err := merge(set); err != nil { + return err } - - for i := 0; i < tasksNum; i++ { - res := <-taskResults - if res.err != nil { - close(finishCh) - return res.err - } - // Merge the dirty nodes of storage trie into global set. It is possible - // that the account was destructed and then resurrected in the same block. - // In this case, the node set is shared by both accounts. - if res.nodeSet != nil { - if err := nodes.Merge(res.nodeSet); err != nil { - return err - } - } + s.AccountCommits = time.Since(start) + } + return nil + }) + // Schedule each of the storage tries that need to be updated, so they can + // run concurrently to one another. + // + // TODO(karalabe): Experimentally, the account commit takes approximately the + // same time as all the storage commits combined, so we could maybe only have + // 2 threads in total. But that kind of depends on the account commit being + // more expensive than it should be, so let's fix that and revisit this todo. + for addr, op := range s.mutations { + if op.isDelete() { + continue + } + // Write any contract code associated with the state object + obj := s.stateObjects[addr] + if obj == nil { + return nil, errors.New("missing state object") + } + // Run the storage updates concurrently to one another + workers.Go(func() error { + // Write any storage changes in the state object to its storage trie + update, set, err := obj.commit() + if err != nil { + return err } - close(finishCh) - - if !s.noTrie { - root, set, err := s.trie.Commit(true) - if err != nil { - return err - } - // Merge the dirty nodes of account trie into global set - if set != nil { - if err := nodes.Merge(set); err != nil { - return err - } - } + if err := merge(set); err != nil { + return err + } + lock.Lock() + updates[obj.addrHash] = update + s.StorageCommits = time.Since(start) // overwrite with the longest storage commit runtime + lock.Unlock() + return nil + }) + } + // Wait for everything to finish and update the metrics + if err := workers.Wait(); err != nil { + return nil, err + } + accountReadMeters.Mark(int64(s.AccountLoaded)) + storageReadMeters.Mark(int64(s.StorageLoaded)) + accountUpdatedMeter.Mark(int64(s.AccountUpdated)) + storageUpdatedMeter.Mark(s.StorageUpdated.Load()) + accountDeletedMeter.Mark(int64(s.AccountDeleted)) + storageDeletedMeter.Mark(s.StorageDeleted.Load()) + accountTrieUpdatedMeter.Mark(int64(accountTrieNodesUpdated)) + accountTrieDeletedMeter.Mark(int64(accountTrieNodesDeleted)) + storageTriesUpdatedMeter.Mark(int64(storageTrieNodesUpdated)) + storageTriesDeletedMeter.Mark(int64(storageTrieNodesDeleted)) + + // Clear the metric markers + s.AccountLoaded, s.AccountUpdated, s.AccountDeleted = 0, 0, 0 + s.StorageLoaded = 0 + s.StorageUpdated.Store(0) + s.StorageDeleted.Store(0) + + // Clear all internal flags and update state root at the end. + s.mutations = make(map[common.Address]*mutation) + s.stateObjectsDestruct = make(map[common.Address]*stateObject) + + origin := s.originalRoot + if root == (common.Hash{}) { + root = types.EmptyRootHash + } + s.originalRoot = root + return newStateUpdate(origin, root, deletes, updates, nodes), nil +} - origin := s.originalRoot - if origin == (common.Hash{}) { - origin = types.EmptyRootHash - } +// commitAndFlush is a wrapper of commit which also commits the state mutations +// to the configured data stores. +func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateUpdate, error) { + ret, err := s.commit(deleteEmptyObjects) + if err != nil { + return nil, err + } - if root != origin { - start := time.Now() - set := triestate.New(s.accountsOrigin, s.storagesOrigin, incomplete) - if err := s.db.TrieDB().Update(root, origin, block, nodes, set); err != nil { - return err - } - s.originalRoot = root - if metrics.EnabledExpensive { - s.TrieDBCommits += time.Since(start) - } - if s.onCommit != nil { - s.onCommit(set) - } - } + snaps := s.db.Snapshot() + if snaps != nil { + ret.diffLayer = &types.DiffLayer{} + } + // Commit dirty contract code if any exists + if db := s.db.TrieDB().Disk(); db != nil && len(ret.codes) > 0 { + batch := db.NewBatch() + for _, code := range ret.codes { + rawdb.WriteCode(batch, code.hash, code.blob) + if snaps != nil { + ret.diffLayer.Codes = append(ret.diffLayer.Codes, types.DiffCode{ + Hash: code.hash, + Code: code.blob, + }) } + } - if postCommitFunc != nil { - err := postCommitFunc() - if err != nil { - return err - } - } - wg.Wait() - return nil - }() - - return commitErr - } - - commitFuncs := []func() error{ - func() error { - codeWriter := s.db.DiskDB().NewBatch() - for addr := range s.stateObjectsDirty { - if obj := s.stateObjects[addr]; !obj.deleted { - // Write any contract code associated with the state object - if obj.code != nil && obj.dirtyCode { - rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) - obj.dirtyCode = false - if s.snap != nil { - diffLayer.Codes = append(diffLayer.Codes, types.DiffCode{ - Hash: common.BytesToHash(obj.CodeHash()), - Code: obj.code, - }) - } - if codeWriter.ValueSize() > ethdb.IdealBatchSize { - if err := codeWriter.Write(); err != nil { - return err - } - codeWriter.Reset() - } - } - } + if err := batch.Write(); err != nil { + return nil, err + } + } + if !ret.empty() { + // If snapshotting is enabled, update the snapshot tree with this new version + if snap := s.db.Snapshot(); snap != nil && snap.Snapshot(ret.originRoot) != nil { + start := time.Now() + ret.diffLayer.Destructs, ret.diffLayer.Accounts, ret.diffLayer.Storages = ret.SnapToDiffLayer() + if err := snap.Update(ret.root, ret.originRoot, ret.destructs, ret.accounts, ret.storages); err != nil { + log.Warn("Failed to update snapshot tree", "from", ret.originRoot, "to", ret.root, "err", err) } - if codeWriter.ValueSize() > 0 { - if err := codeWriter.Write(); err != nil { - log.Crit("Failed to commit dirty codes", "error", err) - return err - } - } - return nil - }, - func() error { - // If snapshotting is enabled, update the snapshot tree with this new version - if s.snap != nil { - if metrics.EnabledExpensive { - defer func(start time.Time) { s.SnapshotCommits += time.Since(start) }(time.Now()) - } - diffLayer.Destructs, diffLayer.Accounts, diffLayer.Storages = s.SnapToDiffLayer() - // Only update if there's a state transition (skip empty Clique blocks) - if parent := s.snap.Root(); parent != s.expectedRoot { - err := s.snaps.Update(s.expectedRoot, parent, s.convertAccountSet(s.stateObjectsDestruct), s.accounts, s.storages) - - if err != nil { - log.Warn("Failed to update snapshot tree", "from", parent, "to", s.expectedRoot, "err", err) - } - - // Keep n diff layers in the memory - // - head layer is paired with HEAD state - // - head-1 layer is paired with HEAD-1 state - // - head-(n-1) layer(bottom-most diff layer) is paired with HEAD-(n-1)state - go func() { - if err := s.snaps.Cap(s.expectedRoot, s.snaps.CapLimit()); err != nil { - log.Warn("Failed to cap snapshot tree", "root", s.expectedRoot, "layers", s.snaps.CapLimit(), "err", err) - } - }() + // Keep 128 diff layers in the memory, persistent layer is 129th. + // - head layer is paired with HEAD state + // - head-1 layer is paired with HEAD-1 state + // - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state + go func() { + if err := snap.Cap(ret.root, TriesInMemory); err != nil { + log.Warn("Failed to cap snapshot tree", "root", ret.root, "layers", TriesInMemory, "err", err) } + }() + s.SnapshotCommits += time.Since(start) + } + // If trie database is enabled, commit the state update as a new layer + if db := s.db.TrieDB(); db != nil { + start := time.Now() + set := triestate.New(ret.accountsOrigin, ret.storagesOrigin) + if err := db.Update(ret.root, ret.originRoot, block, ret.nodes, set); err != nil { + return nil, err } - return nil - }, - } - - defer s.StopPrefetcher() - commitFuncs = append(commitFuncs, commmitTrie) - commitRes := make(chan error, len(commitFuncs)) - for _, f := range commitFuncs { - // commitFuncs[0] and commitFuncs[1] both read map `stateObjects`, but no conflicts - tmpFunc := f - go func() { - commitRes <- tmpFunc() - }() - } - for i := 0; i < len(commitFuncs); i++ { - r := <-commitRes - if r != nil { - return common.Hash{}, nil, r + s.TrieDBCommits += time.Since(start) } } + s.reader, _ = s.db.Reader(s.originalRoot) + return ret, err +} - root := s.stateRoot - s.snap = nil - if root == (common.Hash{}) { - root = types.EmptyRootHash - } - // Clear all internal flags at the end of commit operation. - s.accounts = make(map[common.Hash][]byte) - s.storages = make(map[common.Hash]map[common.Hash][]byte) - s.accountsOrigin = make(map[common.Address][]byte) - s.storagesOrigin = make(map[common.Address]map[common.Hash][]byte) - s.stateObjectsDirty = make(map[common.Address]struct{}) - s.stateObjectsDestruct = make(map[common.Address]*types.StateAccount) - return root, diffLayer, nil -} - -func (s *StateDB) SnapToDiffLayer() ([]common.Address, []types.DiffAccount, []types.DiffStorage) { - destructs := make([]common.Address, 0, len(s.stateObjectsDestruct)) - for account := range s.stateObjectsDestruct { - destructs = append(destructs, account) - } - accounts := make([]types.DiffAccount, 0, len(s.accounts)) - for accountHash, account := range s.accounts { - accounts = append(accounts, types.DiffAccount{ - Account: accountHash, - Blob: account, - }) +// Commit writes the state mutations into the configured data stores. +// +// Once the state is committed, tries cached in stateDB (including account +// trie, storage tries) will no longer be functional. A new state instance +// must be created with new root and updated database for accessing post- +// commit states. +// +// The associated block number of the state transition is also provided +// for more chain context. +func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, postCommitFuncs ...func() error) (common.Hash, *types.DiffLayer, error) { + ret, err := s.commitAndFlush(block, deleteEmptyObjects) + if err != nil { + return common.Hash{}, nil, err } - storages := make([]types.DiffStorage, 0, len(s.storages)) - for accountHash, storage := range s.storages { - keys := make([]common.Hash, 0, len(storage)) - values := make([][]byte, 0, len(storage)) - for k, v := range storage { - keys = append(keys, k) - values = append(values, v) + for _, postFunc := range postCommitFuncs { + err := postFunc() + if err != nil { + return common.Hash{}, nil, err } - storages = append(storages, types.DiffStorage{ - Account: accountHash, - Keys: keys, - Vals: values, - }) } - return destructs, accounts, storages + return ret.root, ret.diffLayer, nil } // Prepare handles the preparatory steps for executing a state transition with. @@ -1639,7 +1488,10 @@ func (s *StateDB) SnapToDiffLayer() ([]common.Address, []types.DiffAccount, []ty // - Add coinbase to access list (EIP-3651) // - Reset transient storage (EIP-1153) func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) { - if rules.IsBerlin { + if rules.IsEIP2929 && rules.IsEIP4762 { + panic("eip2929 and eip4762 are both activated") + } + if rules.IsEIP2929 { // Clear out any leftover from previous executions al := newAccessList() s.accessList = al @@ -1672,7 +1524,7 @@ func (s *StateDB) AddAddressToAccessList(addr common.Address) { s.accessList = newAccessList() } if s.accessList.AddAddress(addr) { - s.journal.append(accessListAddAccountChange{&addr}) + s.journal.accessListAddAccount(addr) } } @@ -1687,13 +1539,10 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { // scope of 'address' without having the 'address' become already added // to the access list (via call-variant, create, etc). // Better safe than sorry, though - s.journal.append(accessListAddAccountChange{&addr}) + s.journal.accessListAddAccount(addr) } if slotMod { - s.journal.append(accessListAddSlotChange{ - address: &addr, - slot: &slot, - }) + s.journal.accessListAddSlot(addr, slot) } } @@ -1717,41 +1566,43 @@ func (s *StateDB) GetStorage(address common.Address) *sync.Map { return s.storagePool.getStorage(address) } -// convertAccountSet converts a provided account set from address keyed to hash keyed. -func (s *StateDB) convertAccountSet(set map[common.Address]*types.StateAccount) map[common.Hash]struct{} { - ret := make(map[common.Hash]struct{}, len(set)) - for addr := range set { - obj, exist := s.stateObjects[addr] - if !exist { - ret[crypto.Keccak256Hash(addr[:])] = struct{}{} - } else { - ret[obj.addrHash] = struct{}{} - } +func (s *StateDB) GetSnap() snapshot.Snapshot { + snaps := s.db.Snapshot() + if snaps != nil { + return snaps.Snapshot(s.originalRoot) } - return ret + return nil } -func (s *StateDB) GetSnap() snapshot.Snapshot { - return s.snap +// markDelete is invoked when an account is deleted but the deletion is +// not yet committed. The pending mutation is cached and will be applied +// all together +func (s *StateDB) markDelete(addr common.Address) { + if _, ok := s.mutations[addr]; !ok { + s.mutations[addr] = &mutation{} + } + s.mutations[addr].applied = false + s.mutations[addr].typ = deletion } -// copySet returns a deep-copied set. -func copySet[k comparable](set map[k][]byte) map[k][]byte { - copied := make(map[k][]byte, len(set)) - for key, val := range set { - copied[key] = common.CopyBytes(val) +func (s *StateDB) markUpdate(addr common.Address) { + if _, ok := s.mutations[addr]; !ok { + s.mutations[addr] = &mutation{} } - return copied + s.mutations[addr].applied = false + s.mutations[addr].typ = update } -// copy2DSet returns a two-dimensional deep-copied set. -func copy2DSet[k comparable](set map[k]map[common.Hash][]byte) map[k]map[common.Hash][]byte { - copied := make(map[k]map[common.Hash][]byte, len(set)) - for addr, subset := range set { - copied[addr] = make(map[common.Hash][]byte, len(subset)) - for key, val := range subset { - copied[addr][key] = common.CopyBytes(val) - } - } - return copied +// PointCache returns the point cache used by verkle tree. +func (s *StateDB) PointCache() *utils.PointCache { + return s.db.PointCache() +} + +// Witness retrieves the current state witness being collected. +func (s *StateDB) Witness() *stateless.Witness { + return s.witness +} + +func (s *StateDB) AccessEvents() *AccessEvents { + return s.accessEvents } diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 06a1aed153..f6be37b086 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -31,11 +31,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" @@ -61,7 +61,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction { name: "SetBalance", fn: func(a testAction, s *StateDB) { - s.SetBalance(addr, uint256.NewInt(uint64(a.args[0]))) + s.SetBalance(addr, uint256.NewInt(uint64(a.args[0])), tracing.BalanceChangeUnspecified) }, args: make([]int64, 1), }, @@ -73,7 +73,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction args: make([]int64, 1), }, { - name: "SetState", + name: "SetStorage", fn: func(a testAction, s *StateDB) { var key, val common.Hash binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) @@ -95,7 +95,9 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction { name: "CreateAccount", fn: func(a testAction, s *StateDB) { - s.CreateAccount(addr) + if !s.Exist(addr) { + s.CreateAccount(addr) + } }, }, { @@ -177,13 +179,24 @@ func (test *stateTest) run() bool { roots []common.Hash accountList []map[common.Address][]byte storageList []map[common.Address]map[common.Hash][]byte - onCommit = func(states *triestate.Set) { - accountList = append(accountList, copySet(states.Accounts)) - storageList = append(storageList, copy2DSet(states.Storages)) + copyUpdate = func(update *stateUpdate) { + accounts := make(map[common.Address][]byte, len(update.accountsOrigin)) + for key, val := range update.accountsOrigin { + accounts[key] = common.CopyBytes(val) + } + accountList = append(accountList, accounts) + + storages := make(map[common.Address]map[common.Hash][]byte, len(update.storagesOrigin)) + for addr, subset := range update.storagesOrigin { + storages[addr] = make(map[common.Hash][]byte, len(subset)) + for key, val := range subset { + storages[addr][key] = common.CopyBytes(val) + } + } + storageList = append(storageList, storages) } disk = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults}) - sdb = NewDatabaseWithNodeDB(disk, tdb) byzantium = rand.Intn(2) == 0 ) defer disk.Close() @@ -203,12 +216,10 @@ func (test *stateTest) run() bool { if i != 0 { root = roots[len(roots)-1] } - state, err := New(root, sdb, snaps) + state, err := New(root, NewDatabase(tdb, snaps)) if err != nil { panic(err) } - state.onCommit = onCommit - for i, action := range actions { if i%test.chunk == 0 && i != 0 { if byzantium { @@ -225,14 +236,15 @@ func (test *stateTest) run() bool { } else { state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary } - nroot, _, err := state.Commit(0, nil) // call commit at the block boundary + nroot, _, err := state.Commit(0, true) // call commit at the block boundary if err != nil { panic(err) } - if nroot == root { - return true // filter out non-change state transition + if ret.empty() { + return true } - roots = append(roots, nroot) + copyUpdate(ret) + roots = append(roots, ret.root) } for i := 0; i < len(test.actions); i++ { root := types.EmptyRootHash diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index aab219561d..fd316c4bc9 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -20,9 +20,11 @@ import ( "bytes" "encoding/binary" "fmt" + "maps" "math" "math/rand" "reflect" + "slices" "strings" "sync" "testing" @@ -31,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" @@ -49,13 +52,14 @@ func TestUpdateLeaks(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(db, nil) + sdb = NewDatabase(tdb, nil) ) - state, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(db, tdb), nil) + state, _ := New(types.EmptyRootHash, sdb) // Update it with some accounts for i := byte(0); i < 255; i++ { addr := common.BytesToAddress([]byte{i}) - state.AddBalance(addr, uint256.NewInt(uint64(11*i))) + state.AddBalance(addr, uint256.NewInt(uint64(11*i)), tracing.BalanceChangeUnspecified) state.SetNonce(addr, uint64(42*i)) if i%2 == 0 { state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i})) @@ -86,11 +90,11 @@ func TestIntermediateLeaks(t *testing.T) { finalDb := rawdb.NewMemoryDatabase() transNdb := triedb.NewDatabase(transDb, nil) finalNdb := triedb.NewDatabase(finalDb, nil) - transState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(transDb, transNdb), nil) - finalState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(finalDb, finalNdb), nil) + transState, _ := New(types.EmptyRootHash, NewDatabase(transNdb, nil)) + finalState, _ := New(types.EmptyRootHash, NewDatabase(finalNdb, nil)) modify := func(state *StateDB, addr common.Address, i, tweak byte) { - state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak))) + state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified) state.SetNonce(addr, uint64(42*i+tweak)) if i%2 == 0 { state.SetState(addr, common.Hash{i, i, i, 0}, common.Hash{}) @@ -166,11 +170,11 @@ func TestIntermediateLeaks(t *testing.T) { // https://github.com/ethereum/go-ethereum/pull/15549. func TestCopy(t *testing.T) { // Create a random state test to copy and modify "independently" - orig, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + orig, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) for i := byte(0); i < 255; i++ { obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) - obj.AddBalance(uint256.NewInt(uint64(i))) + obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified) orig.updateStateObject(obj) } orig.Finalise(false) @@ -187,9 +191,9 @@ func TestCopy(t *testing.T) { copyObj := copy.getOrNewStateObject(common.BytesToAddress([]byte{i})) ccopyObj := ccopy.getOrNewStateObject(common.BytesToAddress([]byte{i})) - origObj.AddBalance(uint256.NewInt(2 * uint64(i))) - copyObj.AddBalance(uint256.NewInt(3 * uint64(i))) - ccopyObj.AddBalance(uint256.NewInt(4 * uint64(i))) + origObj.AddBalance(uint256.NewInt(2*uint64(i)), tracing.BalanceChangeUnspecified) + copyObj.AddBalance(uint256.NewInt(3*uint64(i)), tracing.BalanceChangeUnspecified) + ccopyObj.AddBalance(uint256.NewInt(4*uint64(i)), tracing.BalanceChangeUnspecified) orig.updateStateObject(origObj) copy.updateStateObject(copyObj) @@ -227,6 +231,78 @@ func TestCopy(t *testing.T) { } } +// TestCopyWithDirtyJournal tests if Copy can correct create a equal copied +// stateDB with dirty journal present. +func TestCopyWithDirtyJournal(t *testing.T) { + db := NewDatabaseForTesting() + orig, _ := New(types.EmptyRootHash, db) + + // Fill up the initial states + for i := byte(0); i < 255; i++ { + obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) + obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified) + obj.data.Root = common.HexToHash("0xdeadbeef") + orig.updateStateObject(obj) + } + root, _ := orig.Commit(0, true) + orig, _ = New(root, db) + + // modify all in memory without finalizing + for i := byte(0); i < 255; i++ { + obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) + obj.SubBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified) + orig.updateStateObject(obj) + } + cpy := orig.Copy() + + orig.Finalise(true) + for i := byte(0); i < 255; i++ { + root := orig.GetStorageRoot(common.BytesToAddress([]byte{i})) + if root != (common.Hash{}) { + t.Errorf("Unexpected storage root %x", root) + } + } + cpy.Finalise(true) + for i := byte(0); i < 255; i++ { + root := cpy.GetStorageRoot(common.BytesToAddress([]byte{i})) + if root != (common.Hash{}) { + t.Errorf("Unexpected storage root %x", root) + } + } + if cpy.IntermediateRoot(true) != orig.IntermediateRoot(true) { + t.Error("State is not equal after copy") + } +} + +// TestCopyObjectState creates an original state, S1, and makes a copy S2. +// It then proceeds to make changes to S1. Those changes are _not_ supposed +// to affect S2. This test checks that the copy properly deep-copies the objectstate +func TestCopyObjectState(t *testing.T) { + db := NewDatabaseForTesting() + orig, _ := New(types.EmptyRootHash, db) + + // Fill up the initial states + for i := byte(0); i < 5; i++ { + obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) + obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified) + obj.data.Root = common.HexToHash("0xdeadbeef") + orig.updateStateObject(obj) + } + orig.Finalise(true) + cpy := orig.Copy() + for _, op := range cpy.mutations { + if have, want := op.applied, false; have != want { + t.Fatalf("Error in test itself, the 'done' flag should not be set before Commit, have %v want %v", have, want) + } + } + orig.Commit(0, true) + for _, op := range cpy.mutations { + if have, want := op.applied, false; have != want { + t.Fatalf("Error: original state affected copy, have %v want %v", have, want) + } + } +} + func TestSnapshotRandom(t *testing.T) { config := &quick.Config{MaxCount: 1000} err := quick.Check((*snapshotTest).run, config) @@ -269,14 +345,14 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "SetBalance", fn: func(a testAction, s *StateDB) { - s.SetBalance(addr, uint256.NewInt(uint64(a.args[0]))) + s.SetBalance(addr, uint256.NewInt(uint64(a.args[0])), tracing.BalanceChangeUnspecified) }, args: make([]int64, 1), }, { name: "AddBalance", fn: func(a testAction, s *StateDB) { - s.AddBalance(addr, uint256.NewInt(uint64(a.args[0]))) + s.AddBalance(addr, uint256.NewInt(uint64(a.args[0])), tracing.BalanceChangeUnspecified) }, args: make([]int64, 1), }, @@ -288,7 +364,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { args: make([]int64, 1), }, { - name: "SetState", + name: "SetStorage", fn: func(a testAction, s *StateDB) { var key, val common.Hash binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) @@ -300,6 +376,12 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "SetCode", fn: func(a testAction, s *StateDB) { + // SetCode can only be performed in case the addr does + // not already hold code + if c := s.GetCode(addr); len(c) > 0 { + // no-op + return + } code := make([]byte, 16) binary.BigEndian.PutUint64(code, uint64(a.args[0])) binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) @@ -310,7 +392,30 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "CreateAccount", fn: func(a testAction, s *StateDB) { - s.CreateAccount(addr) + if !s.Exist(addr) { + s.CreateAccount(addr) + } + }, + }, + { + name: "CreateContract", + fn: func(a testAction, s *StateDB) { + if !s.Exist(addr) { + s.CreateAccount(addr) + } + contractHash := s.GetCodeHash(addr) + emptyCode := contractHash == (common.Hash{}) || contractHash == types.EmptyCodeHash + storageRoot := s.GetStorageRoot(addr) + emptyStorage := storageRoot == (common.Hash{}) || storageRoot == types.EmptyRootHash + if s.GetNonce(addr) == 0 && emptyCode && emptyStorage { + s.CreateContract(addr) + // We also set some code here, to prevent the + // CreateContract action from being performed twice in a row, + // which would cause a difference in state when unrolling + // the journal. (CreateContact assumes created was false prior to + // invocation, and the journal rollback sets it to false). + s.SetCode(addr, []byte{1}) + } }, }, { @@ -426,7 +531,7 @@ func (test *snapshotTest) String() string { func (test *snapshotTest) run() bool { // Run all actions and create snapshots. var ( - state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + state, _ = New(types.EmptyRootHash, NewDatabaseForTesting()) snapshotRevs = make([]int, len(test.snapshots)) sindex = 0 checkstates = make([]*StateDB, len(test.snapshots)) @@ -464,10 +569,14 @@ func forEachStorage(s *StateDB, addr common.Address, cb func(key, value common.H if err != nil { return err } - it := trie.NewIterator(trieIt) + var ( + it = trie.NewIterator(trieIt) + visited = make(map[common.Hash]bool) + ) for it.Next() { key := common.BytesToHash(s.trie.GetKey(it.Key)) + visited[key] = true if value, dirty := so.dirtyStorage[key]; dirty { if !cb(key, value) { return nil @@ -507,6 +616,10 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) + // Check newContract-flag + if obj := state.getStateObject(addr); obj != nil { + checkeq("IsNewContract", obj.newContract, checkstate.getStateObject(addr).newContract) + } // Check storage. if obj := state.getStateObject(addr); obj != nil { forEachStorage(state, addr, func(key, value common.Hash) bool { @@ -515,12 +628,49 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { forEachStorage(checkstate, addr, func(key, value common.Hash) bool { return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value) }) + other := checkstate.getStateObject(addr) + // Check dirty storage which is not in trie + if !maps.Equal(obj.dirtyStorage, other.dirtyStorage) { + print := func(dirty map[common.Hash]common.Hash) string { + var keys []common.Hash + out := new(strings.Builder) + for key := range dirty { + keys = append(keys, key) + } + slices.SortFunc(keys, common.Hash.Cmp) + for i, key := range keys { + fmt.Fprintf(out, " %d. %v %v\n", i, key, dirty[key]) + } + return out.String() + } + return fmt.Errorf("dirty storage err, have\n%v\nwant\n%v", + print(obj.dirtyStorage), + print(other.dirtyStorage)) + } + } + // Check transient storage. + { + have := state.transientStorage + want := checkstate.transientStorage + eq := maps.EqualFunc(have, want, + func(a Storage, b Storage) bool { + return maps.Equal(a, b) + }) + if !eq { + return fmt.Errorf("transient storage differs ,have\n%v\nwant\n%v", + have.PrettyPrint(), + want.PrettyPrint()) + } } if err != nil { return err } } - + if !checkstate.accessList.Equal(state.accessList) { // Check access lists + return fmt.Errorf("AccessLists are wrong, have \n%v\nwant\n%v", + checkstate.accessList.PrettyPrint(), + state.accessList.PrettyPrint()) + } if state.GetRefund() != checkstate.GetRefund() { return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", state.GetRefund(), checkstate.GetRefund()) @@ -529,19 +679,34 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v", state.GetLogs(common.Hash{}, 0, common.Hash{}), checkstate.GetLogs(common.Hash{}, 0, common.Hash{})) } + if !maps.Equal(state.journal.dirties, checkstate.journal.dirties) { + getKeys := func(dirty map[common.Address]int) string { + var keys []common.Address + out := new(strings.Builder) + for key := range dirty { + keys = append(keys, key) + } + slices.SortFunc(keys, common.Address.Cmp) + for i, key := range keys { + fmt.Fprintf(out, " %d. %v\n", i, key) + } + return out.String() + } + have := getKeys(state.journal.dirties) + want := getKeys(checkstate.journal.dirties) + return fmt.Errorf("dirty-journal set mismatch.\nhave:\n%v\nwant:\n%v\n", have, want) + } return nil } func TestTouchDelete(t *testing.T) { s := newStateEnv() s.state.getOrNewStateObject(common.Address{}) - s.state.Finalise(false) - s.state.AccountsIntermediateRoot() - root, _, _ := s.state.Commit(0, nil) - s.state, _ = New(root, s.state.db, s.state.snaps) + root, _, _ := s.state.Commit(0, false) + s.state, _ = New(root, s.state.db) snapshot := s.state.Snapshot() - s.state.AddBalance(common.Address{}, new(uint256.Int)) + s.state.AddBalance(common.Address{}, new(uint256.Int), tracing.BalanceChangeUnspecified) if len(s.state.journal.dirties) != 1 { t.Fatal("expected one dirty state object") @@ -555,9 +720,9 @@ func TestTouchDelete(t *testing.T) { // TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy. // See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512 func TestCopyOfCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) addr := common.HexToAddress("aaaa") - state.SetBalance(addr, uint256.NewInt(42)) + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) if got := state.Copy().GetBalance(addr).Uint64(); got != 42 { t.Fatalf("1st copy fail, expected 42, got %v", got) @@ -572,17 +737,17 @@ func TestCopyOfCopy(t *testing.T) { // // See https://github.com/ethereum/go-ethereum/issues/20106. func TestCopyCommitCopy(t *testing.T) { - tdb := NewDatabase(rawdb.NewMemoryDatabase()) - state, _ := New(types.EmptyRootHash, tdb, nil) + tdb := NewDatabaseForTesting() + state, _ := New(types.EmptyRootHash, tdb) // Create an account and check if the retrieved balance is correct addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") skey := common.HexToHash("aaa") sval := common.HexToHash("bbb") - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie + state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetState(addr, skey, sval) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) @@ -625,10 +790,8 @@ func TestCopyCommitCopy(t *testing.T) { t.Fatalf("second copy committed storage slot mismatch: have %x, want %x", val, sval) } // Commit state, ensure states can be loaded from disk - state.Finalise(false) - state.AccountsIntermediateRoot() - root, _, _ := state.Commit(0, nil) - state, _ = New(root, tdb, nil) + root, _, _ := state.Commit(0, false) + state, _ = New(root, tdb) if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { t.Fatalf("state post-commit balance mismatch: have %v, want %v", balance, 42) } @@ -648,16 +811,16 @@ func TestCopyCommitCopy(t *testing.T) { // // See https://github.com/ethereum/go-ethereum/issues/20106. func TestCopyCopyCommitCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) // Create an account and check if the retrieved balance is correct addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") skey := common.HexToHash("aaa") sval := common.HexToHash("bbb") - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie + state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetState(addr, skey, sval) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) @@ -715,18 +878,19 @@ func TestCopyCopyCommitCopy(t *testing.T) { } } -// TestCommitCopy tests the copy from a committed state is not functional. +// TestCommitCopy tests the copy from a committed state is not fully functional. func TestCommitCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + db := NewDatabaseForTesting() + state, _ := New(types.EmptyRootHash, db) // Create an account and check if the retrieved balance is correct addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") - skey := common.HexToHash("aaa") - sval := common.HexToHash("bbb") + skey1, skey2 := common.HexToHash("a1"), common.HexToHash("a2") + sval1, sval2 := common.HexToHash("b1"), common.HexToHash("b2") - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie + state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetState(addr, skey1, sval1) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) @@ -734,27 +898,38 @@ func TestCommitCopy(t *testing.T) { if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) } - if val := state.GetState(addr, skey); val != sval { - t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval) + if val := state.GetState(addr, skey1); val != sval1 { + t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval1) } - if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) { + if val := state.GetCommittedState(addr, skey1); val != (common.Hash{}) { t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } - // Copy the committed state database, the copied one is not functional. - state.Finalise(true) - state.AccountsIntermediateRoot() - state.Commit(0, nil) + root, _, _ := state.Commit(0, true) + + state, _ = New(root, db) + state.SetState(addr, skey2, sval2) + state.Commit(1, true) + + // Copy the committed state database, the copied one is not fully functional. copied := state.Copy() - if balance := copied.GetBalance(addr); balance.Cmp(uint256.NewInt(0)) != 0 { + if balance := copied.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { t.Fatalf("unexpected balance: have %v", balance) } - if code := copied.GetCode(addr); code != nil { + if code := copied.GetCode(addr); !bytes.Equal(code, []byte("hello")) { t.Fatalf("unexpected code: have %x", code) } - if val := copied.GetState(addr, skey); val != (common.Hash{}) { + // Miss slots because of non-functional trie after commit + if val := copied.GetState(addr, skey1); val != sval1 { + t.Fatalf("unexpected storage slot: have %x", val) + } + if val := copied.GetCommittedState(addr, skey1); val != sval1 { t.Fatalf("unexpected storage slot: have %x", val) } - if val := copied.GetCommittedState(addr, skey); val != (common.Hash{}) { + // Slots cached in the stateDB, available after commit + if val := copied.GetState(addr, skey2); val != sval2 { + t.Fatalf("unexpected storage slot: have %x", sval1) + } + if val := copied.GetCommittedState(addr, skey2); val != sval2 { t.Fatalf("unexpected storage slot: have %x", val) } } @@ -769,29 +944,25 @@ func TestCommitCopy(t *testing.T) { // first, but the journal wiped the entire state object on create-revert. func TestDeleteCreateRevert(t *testing.T) { // Create an initial state with a single contract - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) addr := common.BytesToAddress([]byte("so")) - state.SetBalance(addr, uint256.NewInt(1)) + state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified) - state.Finalise(false) - state.AccountsIntermediateRoot() - root, _, _ := state.Commit(0, nil) - state, _ = New(root, state.db, state.snaps) + root, _, _ := state.Commit(0, false) + state, _ = New(root, state.db) // Simulate self-destructing in one transaction, then create-reverting in another state.SelfDestruct(addr) state.Finalise(true) id := state.Snapshot() - state.SetBalance(addr, uint256.NewInt(2)) + state.SetBalance(addr, uint256.NewInt(2), tracing.BalanceChangeUnspecified) state.RevertToSnapshot(id) - state.Finalise(true) - state.AccountsIntermediateRoot() // Commit the entire state and make sure we don't crash and have the correct state - root, _, _ = state.Commit(0, nil) - state, _ = New(root, state.db, state.snaps) + root, _, _ = state.Commit(0, true) + state, _ = New(root, state.db) if state.getStateObject(addr) != nil { t.Fatalf("self-destructed contract came alive") @@ -822,16 +993,16 @@ func testMissingTrieNodes(t *testing.T, scheme string) { CleanCacheSize: 0, }}) // disable caching } - db := NewDatabaseWithNodeDB(memDb, tdb) + db := NewDatabase(tdb, nil) var root common.Hash - state, _ := New(types.EmptyRootHash, db, nil) + state, _ := New(types.EmptyRootHash, db) addr := common.BytesToAddress([]byte("so")) { - state.SetBalance(addr, uint256.NewInt(1)) + state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified) state.SetCode(addr, []byte{1, 2, 3}) a2 := common.BytesToAddress([]byte("another")) - state.SetBalance(a2, uint256.NewInt(100)) + state.SetBalance(a2, uint256.NewInt(100), tracing.BalanceChangeUnspecified) state.SetCode(a2, []byte{1, 2, 4}) state.Finalise(false) state.AccountsIntermediateRoot() @@ -841,7 +1012,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) { tdb.Commit(root, false) } // Create a new state on the old root - state, _ = New(root, db, nil) + state, _ = New(root, db) // Now we clear out the memdb it := memDb.NewIterator(nil, nil) for it.Next() { @@ -858,7 +1029,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) { t.Errorf("expected %d, got %d", exp, got) } // Modify the state - state.SetBalance(addr, uint256.NewInt(2)) + state.SetBalance(addr, uint256.NewInt(2), tracing.BalanceChangeUnspecified) state.Finalise(false) state.AccountsIntermediateRoot() root, _, err := state.Commit(0, nil) @@ -876,9 +1047,8 @@ func TestStateDBAccessList(t *testing.T) { return common.HexToHash(a) } - memDb := rawdb.NewMemoryDatabase() - db := NewDatabase(memDb) - state, _ := New(types.EmptyRootHash, db, nil) + db := NewDatabaseForTesting() + state, _ := New(types.EmptyRootHash, db) state.accessList = newAccessList() verifyAddrs := func(astrings ...string) { @@ -1047,9 +1217,9 @@ func TestFlushOrderDataLoss(t *testing.T) { // Create a state trie with many accounts and slots var ( memdb = rawdb.NewMemoryDatabase() - triedb = triedb.NewDatabase(memdb, nil) - statedb = NewDatabaseWithNodeDB(memdb, triedb) - state, _ = New(types.EmptyRootHash, statedb, nil) + tdb = triedb.NewDatabase(memdb, triedb.HashDefaults) + statedb = NewDatabase(tdb, nil) + state, _ = New(types.EmptyRootHash, statedb) ) for a := byte(0); a < 10; a++ { state.CreateAccount(common.Address{a}) @@ -1062,15 +1232,15 @@ func TestFlushOrderDataLoss(t *testing.T) { if err != nil { t.Fatalf("failed to commit state trie: %v", err) } - triedb.Reference(root, common.Hash{}) - if err := triedb.Cap(1024); err != nil { + tdb.Reference(root, common.Hash{}) + if err := tdb.Cap(1024); err != nil { t.Fatalf("failed to cap trie dirty cache: %v", err) } - if err := triedb.Commit(root, false); err != nil { + if err := tdb.Commit(root, false); err != nil { t.Fatalf("failed to commit state trie: %v", err) } // Reopen the state trie from flushed disk and verify it - state, err = New(root, NewDatabase(memdb), nil) + state, err = New(root, NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil)) if err != nil { t.Fatalf("failed to reopen state trie: %v", err) } @@ -1084,9 +1254,8 @@ func TestFlushOrderDataLoss(t *testing.T) { } func TestStateDBTransientStorage(t *testing.T) { - memDb := rawdb.NewMemoryDatabase() - db := NewDatabase(memDb) - state, _ := New(types.EmptyRootHash, db, nil) + db := NewDatabaseForTesting() + state, _ := New(types.EmptyRootHash, db) key := common.Hash{0x01} value := common.Hash{0x02} @@ -1117,73 +1286,37 @@ func TestStateDBTransientStorage(t *testing.T) { } } -func TestResetObject(t *testing.T) { - var ( - disk = rawdb.NewMemoryDatabase() - tdb = triedb.NewDatabase(disk, nil) - db = NewDatabaseWithNodeDB(disk, tdb) - snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash, 128, false) - state, _ = New(types.EmptyRootHash, db, snaps) - addr = common.HexToAddress("0x1") - slotA = common.HexToHash("0x1") - slotB = common.HexToHash("0x2") - ) - // Initialize account with balance and storage in first transaction. - state.SetBalance(addr, uint256.NewInt(1)) - state.SetState(addr, slotA, common.BytesToHash([]byte{0x1})) - state.IntermediateRoot(true) - - // Reset account and mutate balance and storages - state.CreateAccount(addr) - state.SetBalance(addr, uint256.NewInt(2)) - state.SetState(addr, slotB, common.BytesToHash([]byte{0x2})) - root := state.IntermediateRoot(true) - state.SetExpectedStateRoot(root) - state.Commit(0, nil) - - // Ensure the original account is wiped properly - snap := snaps.Snapshot(root) - slot, _ := snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotA.Bytes())) - if len(slot) != 0 { - t.Fatalf("Unexpected storage slot") - } - slot, _ = snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotB.Bytes())) - if !bytes.Equal(slot, []byte{0x2}) { - t.Fatalf("Unexpected storage slot value %v", slot) - } -} - func TestDeleteStorage(t *testing.T) { var ( disk = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(disk, nil) - db = NewDatabaseWithNodeDB(disk, tdb) snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash, 128, false) - state, _ = New(types.EmptyRootHash, db, snaps) + db = NewDatabase(tdb, snaps) + state, _ = New(types.EmptyRootHash, db) addr = common.HexToAddress("0x1") ) // Initialize account and populate storage - state.SetBalance(addr, uint256.NewInt(1)) + state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified) state.CreateAccount(addr) for i := 0; i < 1000; i++ { slot := common.Hash(uint256.NewInt(uint64(i)).Bytes32()) value := common.Hash(uint256.NewInt(uint64(10 * i)).Bytes32()) state.SetState(addr, slot, value) } - root, _, _ := state.Commit(0, nil) + root, _, _ := state.Commit(0, true) // Init phase done, create two states, one with snap and one without - fastState, _ := New(root, db, snaps) - slowState, _ := New(root, db, nil) + fastState, _ := New(root, NewDatabase(tdb, snaps)) + slowState, _ := New(root, NewDatabase(tdb, nil)) obj := fastState.getOrNewStateObject(addr) storageRoot := obj.data.Root - _, _, fastNodes, err := fastState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) + _, fastNodes, err := fastState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) if err != nil { t.Fatal(err) } - _, _, slowNodes, err := slowState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) + _, slowNodes, err := slowState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) if err != nil { t.Fatal(err) } @@ -1194,7 +1327,7 @@ func TestDeleteStorage(t *testing.T) { t.Fatal("delete should have empty hashes") } if len(n.Blob) != 0 { - t.Fatal("delete should have have empty blobs") + t.Fatal("delete should have empty blobs") } a = append(a, fmt.Sprintf("%x", path)) }) @@ -1206,3 +1339,47 @@ func TestDeleteStorage(t *testing.T) { t.Fatalf("difference found:\nfast: %v\nslow: %v\n", fastRes, slowRes) } } + +func TestStorageDirtiness(t *testing.T) { + var ( + disk = rawdb.NewMemoryDatabase() + tdb = triedb.NewDatabase(disk, nil) + db = NewDatabase(tdb, nil) + state, _ = New(types.EmptyRootHash, db) + addr = common.HexToAddress("0x1") + checkDirty = func(key common.Hash, value common.Hash, dirty bool) { + obj := state.getStateObject(addr) + v, exist := obj.dirtyStorage[key] + if exist != dirty { + t.Fatalf("Unexpected dirty marker, want: %t, got: %t", dirty, exist) + } + if v != value { + t.Fatalf("Unexpected storage slot, want: %t, got: %t", value, v) + } + } + ) + state.CreateAccount(addr) + + // the storage change is noop, no dirty marker + state.SetState(addr, common.Hash{0x1}, common.Hash{}) + checkDirty(common.Hash{0x1}, common.Hash{}, false) + + // the storage change is valid, dirty marker is expected + snap := state.Snapshot() + state.SetState(addr, common.Hash{0x1}, common.Hash{0x1}) + checkDirty(common.Hash{0x1}, common.Hash{0x1}, true) + + // the storage change is reverted, dirtiness should be revoked + state.RevertToSnapshot(snap) + checkDirty(common.Hash{0x1}, common.Hash{}, false) + + // the storage is reset back to its original value, dirtiness should be revoked + state.SetState(addr, common.Hash{0x1}, common.Hash{0x1}) + snap = state.Snapshot() + state.SetState(addr, common.Hash{0x1}, common.Hash{}) + checkDirty(common.Hash{0x1}, common.Hash{}, false) + + // the storage change is reverted, dirty value should be set back + state.RevertToSnapshot(snap) + checkDirty(common.Hash{0x1}, common.Hash{0x1}, true) +} diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go new file mode 100644 index 0000000000..0b73e823d9 --- /dev/null +++ b/core/state/stateupdate.go @@ -0,0 +1,169 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/trie/trienode" +) + +// contractCode represents a contract code with associated metadata. +type contractCode struct { + hash common.Hash // hash is the cryptographic hash of the contract code. + blob []byte // blob is the binary representation of the contract code. +} + +// accountDelete represents an operation for deleting an Ethereum account. +type accountDelete struct { + address common.Address // address is the unique account identifier + origin []byte // origin is the original value of account data in slim-RLP encoding. + storagesOrigin map[common.Hash][]byte // storagesOrigin stores the original values of mutated slots in prefix-zero-trimmed RLP format. +} + +// accountUpdate represents an operation for updating an Ethereum account. +type accountUpdate struct { + address common.Address // address is the unique account identifier + data []byte // data is the slim-RLP encoded account data. + origin []byte // origin is the original value of account data in slim-RLP encoding. + code *contractCode // code represents mutated contract code; nil means it's not modified. + storages map[common.Hash][]byte // storages stores mutated slots in prefix-zero-trimmed RLP format. + storagesOrigin map[common.Hash][]byte // storagesOrigin stores the original values of mutated slots in prefix-zero-trimmed RLP format. +} + +// stateUpdate represents the difference between two states resulting from state +// execution. It contains information about mutated contract codes, accounts, +// and storage slots, along with their original values. +type stateUpdate struct { + originRoot common.Hash // hash of the state before applying mutation + root common.Hash // hash of the state after applying mutation + destructs map[common.Hash]struct{} // destructs contains the list of destructed accounts + accounts map[common.Hash][]byte // accounts stores mutated accounts in 'slim RLP' encoding + accountsOrigin map[common.Address][]byte // accountsOrigin stores the original values of mutated accounts in 'slim RLP' encoding + storages map[common.Hash]map[common.Hash][]byte // storages stores mutated slots in 'prefix-zero-trimmed' RLP format + storagesOrigin map[common.Address]map[common.Hash][]byte // storagesOrigin stores the original values of mutated slots in 'prefix-zero-trimmed' RLP format + codes map[common.Address]contractCode // codes contains the set of dirty codes + nodes *trienode.MergedNodeSet // Aggregated dirty nodes caused by state changes + + destructsAddrs map[common.Address]struct{} + diffLayer *types.DiffLayer // snapshot diffLayer generated by current block + +} + +// empty returns a flag indicating the state transition is empty or not. +func (sc *stateUpdate) empty() bool { + return sc.originRoot == sc.root +} + +// newStateUpdate constructs a state update object, representing the differences +// between two states by performing state execution. It aggregates the given +// account deletions and account updates to form a comprehensive state update. +func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet) *stateUpdate { + var ( + destructs = make(map[common.Hash]struct{}) + accounts = make(map[common.Hash][]byte) + accountsOrigin = make(map[common.Address][]byte) + storages = make(map[common.Hash]map[common.Hash][]byte) + storagesOrigin = make(map[common.Address]map[common.Hash][]byte) + codes = make(map[common.Address]contractCode) + destructsAddrs = make(map[common.Address]struct{}) + ) + // Due to the fact that some accounts could be destructed and resurrected + // within the same block, the deletions must be aggregated first. + for addrHash, op := range deletes { + addr := op.address + destructs[addrHash] = struct{}{} + destructsAddrs[addr] = struct{}{} + accountsOrigin[addr] = op.origin + if len(op.storagesOrigin) > 0 { + storagesOrigin[addr] = op.storagesOrigin + } + } + // Aggregate account updates then. + for addrHash, op := range updates { + // Aggregate dirty contract codes if they are available. + addr := op.address + if op.code != nil { + codes[addr] = *op.code + } + // Aggregate the account changes. The original account value will only + // be tracked if it's not present yet. + accounts[addrHash] = op.data + if _, found := accountsOrigin[addr]; !found { + accountsOrigin[addr] = op.origin + } + // Aggregate the storage changes. The original storage slot value will + // only be tracked if it's not present yet. + if len(op.storages) > 0 { + storages[addrHash] = op.storages + } + if len(op.storagesOrigin) > 0 { + origin := storagesOrigin[addr] + if origin == nil { + storagesOrigin[addr] = op.storagesOrigin + continue + } + for key, slot := range op.storagesOrigin { + if _, found := origin[key]; !found { + origin[key] = slot + } + } + storagesOrigin[addr] = origin + } + } + return &stateUpdate{ + originRoot: types.TrieRootHash(originRoot), + root: types.TrieRootHash(root), + destructs: destructs, + accounts: accounts, + accountsOrigin: accountsOrigin, + storages: storages, + storagesOrigin: storagesOrigin, + codes: codes, + nodes: nodes, + destructsAddrs: destructsAddrs, + } +} + +func (sc *stateUpdate) SnapToDiffLayer() ([]common.Address, []types.DiffAccount, []types.DiffStorage) { + destructs := make([]common.Address, 0, len(sc.destructsAddrs)) + for account := range sc.destructsAddrs { + destructs = append(destructs, account) + } + accounts := make([]types.DiffAccount, 0, len(sc.accounts)) + for accountHash, account := range sc.accounts { + accounts = append(accounts, types.DiffAccount{ + Account: accountHash, + Blob: account, + }) + } + storages := make([]types.DiffStorage, 0, len(sc.storages)) + for accountHash, storage := range sc.storages { + keys := make([]common.Hash, 0, len(storage)) + values := make([][]byte, 0, len(storage)) + for k, v := range storage { + keys = append(keys, k) + values = append(values, v) + } + storages = append(storages, types.DiffStorage{ + Account: accountHash, + Keys: keys, + Vals: values, + }) + } + return destructs, accounts, storages +} diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 211b0be9f6..e21485ef02 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -52,8 +53,8 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c } db := rawdb.NewMemoryDatabase() nodeDb := triedb.NewDatabase(db, config) - sdb := NewDatabaseWithNodeDB(db, nodeDb) - state, _ := New(types.EmptyRootHash, sdb, nil) + sdb := NewDatabase(nodeDb, nil) + state, _ := New(types.EmptyRootHash, sdb) // Fill it with some arbitrary data var accounts []*testAccount @@ -61,7 +62,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c obj := state.getOrNewStateObject(common.BytesToAddress([]byte{i})) acc := &testAccount{address: common.BytesToAddress([]byte{i})} - obj.AddBalance(uint256.NewInt(uint64(11 * i))) + obj.AddBalance(uint256.NewInt(uint64(11*i)), tracing.BalanceChangeUnspecified) acc.balance = uint256.NewInt(uint64(11 * i)) obj.SetNonce(uint64(42 * i)) @@ -95,7 +96,7 @@ func checkStateAccounts(t *testing.T, db ethdb.Database, scheme string, root com config.PathDB = pathdb.Defaults } // Check root availability and state contents - state, err := New(root, NewDatabaseWithConfig(db, &config), nil) + state, err := New(root, NewDatabase(triedb.NewDatabase(db, &config), nil)) if err != nil { t.Fatalf("failed to create state trie at %x: %v", root, err) } @@ -121,7 +122,7 @@ func checkStateConsistency(db ethdb.Database, scheme string, root common.Hash) e if scheme == rawdb.PathScheme { config.PathDB = pathdb.Defaults } - state, err := New(root, NewDatabaseWithConfig(db, config), nil) + state, err := New(root, NewDatabase(triedb.NewDatabase(db, config), nil)) if err != nil { return err } diff --git a/core/state/transient_storage.go b/core/state/transient_storage.go index 66e563efa7..e63db39eba 100644 --- a/core/state/transient_storage.go +++ b/core/state/transient_storage.go @@ -17,6 +17,10 @@ package state import ( + "fmt" + "slices" + "strings" + "github.com/ethereum/go-ethereum/common" ) @@ -30,10 +34,19 @@ func newTransientStorage() transientStorage { // Set sets the transient-storage `value` for `key` at the given `addr`. func (t transientStorage) Set(addr common.Address, key, value common.Hash) { - if _, ok := t[addr]; !ok { - t[addr] = make(Storage) + if value == (common.Hash{}) { // this is a 'delete' + if _, ok := t[addr]; ok { + delete(t[addr], key) + if len(t[addr]) == 0 { + delete(t, addr) + } + } + } else { + if _, ok := t[addr]; !ok { + t[addr] = make(Storage) + } + t[addr][key] = value } - t[addr][key] = value } // Get gets the transient storage for `key` at the given `addr`. @@ -53,3 +66,27 @@ func (t transientStorage) Copy() transientStorage { } return storage } + +// PrettyPrint prints the contents of the access list in a human-readable form +func (t transientStorage) PrettyPrint() string { + out := new(strings.Builder) + var sortedAddrs []common.Address + for addr := range t { + sortedAddrs = append(sortedAddrs, addr) + slices.SortFunc(sortedAddrs, common.Address.Cmp) + } + + for _, addr := range sortedAddrs { + fmt.Fprintf(out, "%#x:", addr) + var sortedKeys []common.Hash + storage := t[addr] + for key := range storage { + sortedKeys = append(sortedKeys, key) + } + slices.SortFunc(sortedKeys, common.Hash.Cmp) + for _, key := range sortedKeys { + fmt.Fprintf(out, " %X : %X\n", key, storage[key]) + } + } + return out.String() +} diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go index 91e6ca40b1..cc436d76a5 100644 --- a/core/state/trie_prefetcher.go +++ b/core/state/trie_prefetcher.go @@ -50,12 +50,15 @@ type prefetchMsg struct { // // Note, the prefetcher's API is not thread safe. type triePrefetcher struct { + verkle bool // Flag whether the prefetcher is in verkle mode db Database // Database to fetch trie nodes through root common.Hash // Root hash of the account trie for metrics rootParent common.Hash // Root has of the account trie from block before the prvious one, designed for pipecommit mode fetches map[string]Trie // Partially or fully fetched tries. Only populated for inactive copies fetchers map[string]*subfetcher // Subfetchers for each trie + noreads bool // Whether to ignore state-read-only prefetch requests + abortChan chan *subfetcher // to abort a single subfetcher and its children closed int32 closeMainChan chan struct{} // it is to inform the mainLoop @@ -80,15 +83,18 @@ type triePrefetcher struct { } // newTriePrefetcher -func newTriePrefetcher(db Database, root, rootParent common.Hash, namespace string) *triePrefetcher { +func newTriePrefetcher(db Database, root, rootParent common.Hash, namespace string, noreads bool) *triePrefetcher { prefix := triePrefetchMetricsPrefix + namespace p := &triePrefetcher{ + verkle: db.TrieDB().IsVerkle(), db: db, root: root, rootParent: rootParent, fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map abortChan: make(chan *subfetcher, abortChanSize), + noreads: noreads, + closeMainChan: make(chan struct{}), closeMainDoneChan: make(chan struct{}), prefetchChan: make(chan *prefetchMsg, concurrentChanSize), @@ -157,42 +163,40 @@ func (p *triePrefetcher) mainLoop() { <-child.term } - if metrics.EnabledExpensive { - switch fetcher.root { - case p.root: - p.accountLoadMeter.Mark(int64(len(fetcher.seen))) - p.accountDupMeter.Mark(int64(fetcher.dups)) - p.accountSkipMeter.Mark(int64(len(fetcher.tasks))) - fetcher.lock.Lock() - for _, key := range fetcher.used { - delete(fetcher.seen, string(key)) - } - fetcher.lock.Unlock() - p.accountWasteMeter.Mark(int64(len(fetcher.seen))) - - case p.rootParent: - p.accountStaleLoadMeter.Mark(int64(len(fetcher.seen))) - p.accountStaleDupMeter.Mark(int64(fetcher.dups)) - p.accountStaleSkipMeter.Mark(int64(len(fetcher.tasks))) - fetcher.lock.Lock() - for _, key := range fetcher.used { - delete(fetcher.seen, string(key)) - } - fetcher.lock.Unlock() - p.accountStaleWasteMeter.Mark(int64(len(fetcher.seen))) + switch fetcher.root { + case p.root: + p.accountLoadMeter.Mark(int64(len(fetcher.seen))) + p.accountDupMeter.Mark(int64(fetcher.dups)) + p.accountSkipMeter.Mark(int64(len(fetcher.tasks))) + fetcher.lock.Lock() + for _, key := range fetcher.used { + delete(fetcher.seen, string(key)) + } + fetcher.lock.Unlock() + p.accountWasteMeter.Mark(int64(len(fetcher.seen))) + + case p.rootParent: + p.accountStaleLoadMeter.Mark(int64(len(fetcher.seen))) + p.accountStaleDupMeter.Mark(int64(fetcher.dups)) + p.accountStaleSkipMeter.Mark(int64(len(fetcher.tasks))) + fetcher.lock.Lock() + for _, key := range fetcher.used { + delete(fetcher.seen, string(key)) + } + fetcher.lock.Unlock() + p.accountStaleWasteMeter.Mark(int64(len(fetcher.seen))) - default: - p.storageLoadMeter.Mark(int64(len(fetcher.seen))) - p.storageDupMeter.Mark(int64(fetcher.dups)) - p.storageSkipMeter.Mark(int64(len(fetcher.tasks))) + default: + p.storageLoadMeter.Mark(int64(len(fetcher.seen))) + p.storageDupMeter.Mark(int64(fetcher.dups)) + p.storageSkipMeter.Mark(int64(len(fetcher.tasks))) - fetcher.lock.Lock() - for _, key := range fetcher.used { - delete(fetcher.seen, string(key)) - } - fetcher.lock.Unlock() - p.storageWasteMeter.Mark(int64(len(fetcher.seen))) + fetcher.lock.Lock() + for _, key := range fetcher.used { + delete(fetcher.seen, string(key)) } + fetcher.lock.Unlock() + p.storageWasteMeter.Mark(int64(len(fetcher.seen))) } } close(p.closeMainDoneChan) @@ -233,7 +237,7 @@ func (p *triePrefetcher) copy() *triePrefetcher { // if the triePrefetcher is active, fetches will not be used in mainLoop // otherwise, inactive triePrefetcher is readonly, it won't modify fetches for root, fetch := range p.fetches { - fetcherCopied.fetches[root] = p.db.CopyTrie(fetch) + fetcherCopied.fetches[root] = mustCopyTrie(fetch) } return fetcherCopied } @@ -265,15 +269,23 @@ func (p *triePrefetcher) copy() *triePrefetcher { } // prefetch schedules a batch of trie items to prefetch. -func (p *triePrefetcher) prefetch(owner common.Hash, root common.Hash, addr common.Address, keys [][]byte) { +func (p *triePrefetcher) prefetch(owner common.Hash, root common.Hash, addr common.Address, keys [][]byte, read bool) error { + // If the state item is only being read, but reads are disabled, return + if read && p.noreads { + return nil + } + // If the prefetcher is an inactive one, bail out if p.fetches != nil { - return + return nil } + select { case <-p.closeMainChan: // skip closed trie prefetcher + // TODO: ignore whether it's terminated? case p.prefetchChan <- &prefetchMsg{owner, root, addr, keys}: } + return nil } // trie returns the trie matching the root hash, or nil if the prefetcher doesn't @@ -286,7 +298,7 @@ func (p *triePrefetcher) trie(owner common.Hash, root common.Hash) Trie { if trie == nil { return nil } - return p.db.CopyTrie(trie) + return mustCopyTrie(trie) } // use lock instead of request to mainLoop by chan to get the fetcher for performance concern. @@ -316,9 +328,6 @@ func (p *triePrefetcher) trie(owner common.Hash, root common.Hash) Trie { // used marks a batch of state items used to allow creating statistics as to // how useful or wasteful the prefetcher is. func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte) { - if !metrics.EnabledExpensive { - return - } // If the prefetcher is an inactive one, bail out if p.fetches != nil { return @@ -330,7 +339,7 @@ func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte id := p.trieID(owner, root) if fetcher := p.fetchers[id]; fetcher != nil { fetcher.lock.Lock() - fetcher.used = used + fetcher.used = append(fetcher.used, used...) fetcher.lock.Unlock() } p.fetchersMutex.RUnlock() @@ -339,6 +348,12 @@ func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte // trieID returns an unique trie identifier consists the trie owner and root hash. func (p *triePrefetcher) trieID(owner common.Hash, root common.Hash) string { + // The trie in verkle is only identified by state root + if p.verkle { + return p.root.Hex() + } + // The trie in merkle is either identified by state root (account trie), + // or identified by the owner and trie root (storage trie) trieID := make([]byte, common.HashLength*2) copy(trieID, owner.Bytes()) copy(trieID[common.HashLength:], root.Bytes()) @@ -459,7 +474,7 @@ func (sf *subfetcher) peek() Trie { if sf.trie == nil { return nil } - return sf.db.CopyTrie(sf.trie) + return mustCopyTrie(sf.trie) } } @@ -474,27 +489,48 @@ func (sf *subfetcher) abort() { // no need to wait <-sf.term here, will check sf.term later } +// openTrie resolves the target trie from database for prefetching. +func (sf *subfetcher) openTrie() error { + // Open the verkle tree if the sub-fetcher is in verkle mode. Note, there is + // only a single fetcher for verkle. + if sf.db.TrieDB().IsVerkle() { + tr, err := sf.db.OpenTrie(sf.state) + if err != nil { + log.Warn("Trie prefetcher failed opening verkle trie", "root", sf.root, "err", err) + return err + } + sf.trie = tr + return nil + } + // Open the merkle tree if the sub-fetcher is in merkle mode + if sf.owner == (common.Hash{}) { + tr, err := sf.db.OpenTrie(sf.state) + if err != nil { + log.Warn("Trie prefetcher failed opening account trie", "root", sf.root, "err", err) + return err + } + sf.trie = tr + return nil + } + tr, err := sf.db.OpenStorageTrie(sf.state, sf.addr, sf.root, nil) + if err != nil { + log.Warn("Trie prefetcher failed opening storage trie", "root", sf.root, "err", err) + return err + } + sf.trie = tr + return nil +} + // loop waits for new tasks to be scheduled and keeps loading them until it runs // out of tasks or its underlying trie is retrieved for committing. func (sf *subfetcher) loop() { // No matter how the loop stops, signal anyone waiting that it's terminated defer close(sf.term) - // Start by opening the trie and stop processing if it fails - var trie Trie var err error - if sf.owner == (common.Hash{}) { - trie, err = sf.db.OpenTrie(sf.root) - } else { - trie, err = sf.db.OpenStorageTrie(sf.state, sf.addr, sf.root, nil) - } - if err != nil { - log.Debug("Trie prefetcher failed opening trie", "root", sf.root, "err", err) + if err := sf.openTrie(); err != nil { return } - sf.trie = trie - - // Trie opened successfully, keep prefetching items for { select { case <-sf.wake: @@ -528,7 +564,7 @@ func (sf *subfetcher) loop() { case ch := <-sf.copy: // Somebody wants a copy of the current trie, grant them - ch <- sf.db.CopyTrie(sf.trie) + ch <- mustCopyTrie(sf.trie) default: // No termination request yet, prefetch the next entry @@ -548,7 +584,7 @@ func (sf *subfetcher) loop() { case ch := <-sf.copy: // Somebody wants a copy of the current trie, grant them - ch <- sf.db.CopyTrie(sf.trie) + ch <- mustCopyTrie(sf.trie) case <-sf.stop: // Termination is requested, abort and leave remaining tasks diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index 4ef450dbfb..ba4fbe0dd7 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -23,21 +23,25 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" + "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" ) func filledStateDB() *StateDB { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) // Create an account and check if the retrieved balance is correct addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") skey := common.HexToHash("aaa") sval := common.HexToHash("bbb") - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie + state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetState(addr, skey, sval) // Change the storage trie for i := 0; i < 100; i++ { sk := common.BigToHash(big.NewInt(int64(i))) state.SetState(addr, sk, sk) // Change the storage trie @@ -120,3 +124,47 @@ func TestCopyClose(t *testing.T) { t.Fatal("Copy trie should not return nil") } } + +func TestVerklePrefetcher(t *testing.T) { + disk := rawdb.NewMemoryDatabase() + db := triedb.NewDatabase(disk, triedb.VerkleDefaults) + sdb := NewDatabase(db, nil) + + state, err := New(types.EmptyRootHash, sdb) + if err != nil { + t.Fatalf("failed to initialize state: %v", err) + } + // Create an account and check if the retrieved balance is correct + addr := testrand.Address() + skey := testrand.Hash() + sval := testrand.Hash() + + state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie + state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetState(addr, skey, sval) // Change the storage trie + root, _ := state.Commit(0, true) + + state, _ = New(root, sdb) + sRoot := state.GetStorageRoot(addr) + fetcher := newTriePrefetcher(sdb, root, "", false) + + // Read account + fetcher.prefetch(common.Hash{}, root, common.Address{}, [][]byte{ + addr.Bytes(), + }, false) + + // Read storage slot + fetcher.prefetch(crypto.Keccak256Hash(addr.Bytes()), sRoot, addr, [][]byte{ + skey.Bytes(), + }, false) + + fetcher.terminate(false) + accountTrie := fetcher.trie(common.Hash{}, root) + storageTrie := fetcher.trie(crypto.Keccak256Hash(addr.Bytes()), sRoot) + + rootA := accountTrie.Hash() + rootB := storageTrie.Hash() + if rootA != rootB { + t.Fatal("Two different tries are retrieved") + } +} diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 5e616b29e5..53df5babb6 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -17,7 +17,6 @@ package core import ( - "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -32,16 +31,14 @@ const checkInterval = 10 // data from disk before the main block processor start executing. type statePrefetcher struct { config *params.ChainConfig // Chain configuration options - bc *BlockChain // Canonical block chain - engine consensus.Engine // Consensus engine used for block rewards + chain *HeaderChain // Canonical block chain } // NewStatePrefetcher initialises a new statePrefetcher. -func NewStatePrefetcher(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *statePrefetcher { +func NewStatePrefetcher(config *params.ChainConfig, chain *HeaderChain) *statePrefetcher { return &statePrefetcher{ config: config, - bc: bc, - engine: engine, + chain: chain, } } @@ -63,7 +60,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c newStatedb.EnableWriteOnSharedStorage() } gaspool := new(GasPool).AddGas(block.GasLimit()) - blockContext := NewEVMBlockContext(header, p.bc, nil) + blockContext := NewEVMBlockContext(header, p.chain, nil) evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, *cfg) // Iterate over and process the individual transactions for { @@ -72,7 +69,8 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c tx := transactions[txIndex] // Convert the transaction into an executable message and pre-cache its sender msg, err := TransactionToMessage(tx, signer, header.BaseFee) - msg.SkipAccountChecks = true + msg.SkipNonceChecks = true + msg.SkipFromEOACheck = true if err != nil { return // Also invalid block, bail out } @@ -112,7 +110,7 @@ func (p *statePrefetcher) PrefetchMining(txs TransactionsByPriceAndNonce, header newStatedb.EnableWriteOnSharedStorage() } gaspool := new(GasPool).AddGas(gasLimit) - blockContext := NewEVMBlockContext(header, p.bc, nil) + blockContext := NewEVMBlockContext(header, p.chain, nil) evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) // Iterate over and process the individual transactions for { @@ -120,7 +118,8 @@ func (p *statePrefetcher) PrefetchMining(txs TransactionsByPriceAndNonce, header case tx := <-startCh: // Convert the transaction into an executable message and pre-cache its sender msg, err := TransactionToMessage(tx, signer, header.BaseFee) - msg.SkipAccountChecks = true + msg.SkipNonceChecks = true + msg.SkipFromEOACheck = true if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index 9ef227ccc2..11d1df3445 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -38,16 +38,14 @@ import ( // StateProcessor implements Processor. type StateProcessor struct { config *params.ChainConfig // Chain configuration options - bc *BlockChain // Canonical block chain - engine consensus.Engine // Consensus engine used for block rewards + chain *HeaderChain // Canonical header chain } // NewStateProcessor initialises a new StateProcessor. -func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { +func NewStateProcessor(config *params.ChainConfig, chain *HeaderChain) *StateProcessor { return &StateProcessor{ config: config, - bc: bc, - engine: engine, + chain: chain, } } @@ -58,7 +56,7 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // Process returns the receipts and logs accumulated during the process and // returns the amount of gas that was used in the process. If any of the // transactions failed to execute due to insufficient gas it will return an error. -func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*state.StateDB, types.Receipts, []*types.Log, uint64, error) { +func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) { var ( usedGas = new(uint64) header = block.Header() @@ -66,34 +64,39 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg blockNumber = block.Number() allLogs []*types.Log gp = new(GasPool).AddGas(block.GasLimit()) + receipts = make([]*types.Receipt, 0) ) - var receipts = make([]*types.Receipt, 0) // Mutate the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } - lastBlock := p.bc.GetBlockByHash(block.ParentHash()) + lastBlock := p.chain.GetHeaderByHash(block.ParentHash()) if lastBlock == nil { - return statedb, nil, nil, 0, errors.New("could not get parent block") + return nil, errors.New("could not get parent block") } if !p.config.IsFeynman(block.Number(), block.Time()) { // Handle upgrade build-in system contract code - systemcontracts.UpgradeBuildInSystemContract(p.config, blockNumber, lastBlock.Time(), block.Time(), statedb) + systemcontracts.UpgradeBuildInSystemContract(p.config, blockNumber, lastBlock.Time, block.Time(), statedb) } var ( - context = NewEVMBlockContext(header, p.bc, nil) - vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) + context vm.BlockContext signer = types.MakeSigner(p.config, header.Number, header.Time) txNum = len(block.Transactions()) + err error ) + context = NewEVMBlockContext(header, p.chain, nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) } + if p.config.IsPrague(block.Number(), block.Time()) { + ProcessParentBlockHash(block.ParentHash(), vmenv, statedb) + } // Iterate over and process the individual transactions - posa, isPoSA := p.engine.(consensus.PoSA) + posa, isPoSA := p.chain.engine.(consensus.PoSA) commonTxs := make([]*types.Transaction, 0, txNum) // initialise bloom processors @@ -107,7 +110,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if isPoSA { if isSystemTx, err := posa.IsSystemTransaction(tx, block.Header()); err != nil { bloomProcessors.Close() - return statedb, nil, nil, 0, err + return nil, err } else if isSystemTx { systemTxs = append(systemTxs, tx) continue @@ -116,21 +119,21 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if p.config.IsCancun(block.Number(), block.Time()) { if len(systemTxs) > 0 { // systemTxs should be always at the end of block. - return statedb, nil, nil, 0, fmt.Errorf("normal tx %d [%v] after systemTx", i, tx.Hash().Hex()) + return nil, fmt.Errorf("normal tx %d [%v] after systemTx", i, tx.Hash().Hex()) } } msg, err := TransactionToMessage(tx, signer, header.BaseFee) if err != nil { bloomProcessors.Close() - return statedb, nil, nil, 0, err + return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } statedb.SetTxContext(tx.Hash(), i) - receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, bloomProcessors) + receipt, err := ApplyTransactionWithEVM(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, bloomProcessors) if err != nil { bloomProcessors.Close() - return statedb, nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) + return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } commonTxs = append(commonTxs, tx) receipts = append(receipts, receipt) @@ -140,22 +143,47 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // Fail if Shanghai not enabled and len(withdrawals) is non-zero. withdrawals := block.Withdrawals() if len(withdrawals) > 0 && !p.config.IsShanghai(block.Number(), block.Time()) { - return nil, nil, nil, 0, errors.New("withdrawals before shanghai") + return nil, errors.New("withdrawals before shanghai") + } + + // Read requests if Prague is enabled. + var requests types.Requests + if p.config.IsPrague(block.Number(), block.Time()) { + requests, err = ParseDepositLogs(allLogs, p.config) + if err != nil { + return nil, err + } } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - err := p.engine.Finalize(p.bc, header, statedb, &commonTxs, block.Uncles(), withdrawals, &receipts, &systemTxs, usedGas) + err = p.chain.engine.Finalize(p.chain, header, statedb, &commonTxs, block.Uncles(), withdrawals, &receipts, &systemTxs, usedGas) if err != nil { - return statedb, receipts, allLogs, *usedGas, err + return nil, err } for _, receipt := range receipts { allLogs = append(allLogs, receipt.Logs...) } - return statedb, receipts, allLogs, *usedGas, nil + return &ProcessResult{ + Receipts: receipts, + Requests: requests, + Logs: allLogs, + GasUsed: *usedGas, + }, nil } -func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, receiptProcessors ...ReceiptProcessor) (*types.Receipt, error) { +// ApplyTransactionWithEVM attempts to apply a transaction to the given state database +// and uses the input parameters for its environment similar to ApplyTransaction. However, +// this method takes an already created EVM instance as input. +func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, receiptProcessors ...ReceiptProcessor) (receipt *types.Receipt, err error) { + if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil { + evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + if evm.Config.Tracer.OnTxEnd != nil { + defer func() { + evm.Config.Tracer.OnTxEnd(receipt, err) + }() + } + } // Create a new context to be used in the EVM environment. txContext := NewEVMTxContext(msg) evm.Reset(txContext, statedb) @@ -175,9 +203,14 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta } *usedGas += result.UsedGas + return MakeReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root, receiptProcessors...), nil +} + +// MakeReceipt generates the receipt object for a transaction given its execution result. +func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte, receiptProcessors ...ReceiptProcessor) *types.Receipt { // Create a new receipt for the transaction, storing the intermediate root and gas used // by the tx. - receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: *usedGas} + receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: usedGas} if result.Failed() { receipt.Status = types.ReceiptStatusFailed } else { @@ -192,10 +225,16 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta } // If the transaction created a contract, store the creation address in the receipt. - if msg.To == nil { + if tx.To() == nil { receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) } + // Merge the tx-local access event into the "block-local" one, in order to collect + // all values, so that the witness can be built. + if statedb.GetTrie().IsVerkle() { + statedb.AccessEvents().Merge(evm.AccessEvents) + } + // Set the receipt logs and create the bloom filter. receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) receipt.BlockHash = blockHash @@ -204,7 +243,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta for _, receiptProcessor := range receiptProcessors { receiptProcessor.Apply(receipt) } - return receipt, err + return receipt } // ApplyTransaction attempts to apply a transaction to the given state database @@ -225,7 +264,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo vm.EVMInterpreterPool.Put(ite) vm.EvmPool.Put(vmenv) }() - return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, receiptProcessors...) + return ApplyTransactionWithEVM(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, receiptProcessors...) } // ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root @@ -237,6 +276,14 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat return } } + if tracer := vmenv.Config.Tracer; tracer != nil { + if tracer.OnSystemCallStart != nil { + tracer.OnSystemCallStart() + } + if tracer.OnSystemCallEnd != nil { + defer tracer.OnSystemCallEnd() + } + } // If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with // the new root @@ -254,3 +301,46 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat _, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) statedb.Finalise(true) } + +// ProcessParentBlockHash stores the parent block hash in the history storage contract +// as per EIP-2935. +func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.StateDB) { + if tracer := vmenv.Config.Tracer; tracer != nil { + if tracer.OnSystemCallStart != nil { + tracer.OnSystemCallStart() + } + if tracer.OnSystemCallEnd != nil { + defer tracer.OnSystemCallEnd() + } + } + + msg := &Message{ + From: params.SystemAddress, + GasLimit: 30_000_000, + GasPrice: common.Big0, + GasFeeCap: common.Big0, + GasTipCap: common.Big0, + To: ¶ms.HistoryStorageAddress, + Data: prevHash.Bytes(), + } + vmenv.Reset(NewEVMTxContext(msg), statedb) + statedb.AddAddressToAccessList(params.HistoryStorageAddress) + _, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + statedb.Finalise(true) +} + +// ParseDepositLogs extracts the EIP-6110 deposit values from logs emitted by +// BeaconDepositContract. +func ParseDepositLogs(logs []*types.Log, config *params.ChainConfig) (types.Requests, error) { + deposits := make(types.Requests, 0) + for _, log := range logs { + if log.Address == config.DepositContractAddress { + d, err := types.UnpackIntoDeposit(log.Data) + if err != nil { + return nil, fmt.Errorf("unable to parse deposit data: %v", err) + } + deposits = append(deposits, types.NewRequest(d)) + } + } + return deposits, nil +} diff --git a/core/state_processor_test.go b/core/state_processor_test.go index f87997c7ed..2d84b0c1ce 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -18,6 +18,7 @@ package core import ( "crypto/ecdsa" + "encoding/binary" "errors" "math/big" "testing" @@ -30,11 +31,14 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/triedb" + "github.com/ethereum/go-verkle" "github.com/holiman/uint256" "golang.org/x/crypto/sha3" ) @@ -424,8 +428,202 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } } // Assemble and return the final block for sealing + body := &types.Body{Transactions: txs} if config.IsShanghai(header.Number, header.Time) { - return types.NewBlockWithWithdrawals(header, txs, nil, receipts, []*types.Withdrawal{}, trie.NewStackTrie(nil)) + body.Withdrawals = []*types.Withdrawal{} } - return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)) + return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)) +} + +var ( + code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`) + intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, true, true, true, true) + // A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness + // will not contain that copied data. + // Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985 + codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`) + intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, true, true, true, true) +) + +func TestProcessVerkle(t *testing.T) { + var ( + config = ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(params.EthashConfig), + ShanghaiTime: u64(0), + VerkleTime: u64(0), + TerminalTotalDifficulty: common.Big0, + TerminalTotalDifficultyPassed: true, + // TODO uncomment when proof generation is merged + // ProofInBlocks: true, + } + signer = types.LatestSigner(config) + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain + coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") + gspec = &Genesis{ + Config: config, + Alloc: GenesisAlloc{ + coinbase: GenesisAccount{ + Balance: big.NewInt(1000000000000000000), // 1 ether + Nonce: 0, + }, + }, + } + ) + // Verkle trees use the snapshot, which must be enabled before the + // data is saved into the tree+database. + // genesis := gspec.MustCommit(bcdb, triedb) + cacheConfig := DefaultCacheConfigWithScheme("path") + cacheConfig.SnapshotLimit = 0 + blockchain, _ := NewBlockChain(bcdb, cacheConfig, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil) + defer blockchain.Stop() + + txCost1 := params.TxGas + txCost2 := params.TxGas + contractCreationCost := intrinsicContractCreationGas + + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */ + 739 /* execution costs */ + codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ + params.WitnessChunkReadCost + /* SLOAD in constructor */ + params.WitnessChunkWriteCost + /* SSTORE in constructor */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ + params.WitnessChunkReadCost + /* SLOAD in constructor */ + params.WitnessChunkWriteCost + /* SSTORE in constructor */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */ + 15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */ + 4844 /* execution costs */ + blockGasUsagesExpected := []uint64{ + txCost1*2 + txCost2, + txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, + } + _, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + gen.SetPoS() + + // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over) + tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + + // Add two contract creations in block #2 + if i == 1 { + tx, _ = types.SignTx(types.NewContractCreation(6, big.NewInt(16), 3000000, big.NewInt(875000000), code), signer, testKey) + gen.AddTx(tx) + + tx, _ = types.SignTx(types.NewContractCreation(7, big.NewInt(0), 3000000, big.NewInt(875000000), codeWithExtCodeCopy), signer, testKey) + gen.AddTx(tx) + } + }) + + // Check proof for both blocks + err := verkle.Verify(proofs[0], gspec.ToBlock().Root().Bytes(), chain[0].Root().Bytes(), statediffs[0]) + if err != nil { + t.Fatal(err) + } + err = verkle.Verify(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), statediffs[1]) + if err != nil { + t.Fatal(err) + } + + t.Log("verified verkle proof, inserting blocks into the chain") + + endnum, err := blockchain.InsertChain(chain) + if err != nil { + t.Fatalf("block %d imported with error: %v", endnum, err) + } + + for i := 0; i < 2; i++ { + b := blockchain.GetBlockByNumber(uint64(i) + 1) + if b == nil { + t.Fatalf("expected block %d to be present in chain", i+1) + } + if b.Hash() != chain[i].Hash() { + t.Fatalf("block #%d not found at expected height", b.NumberU64()) + } + if b.GasUsed() != blockGasUsagesExpected[i] { + t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed()) + } + } +} + +func TestProcessParentBlockHash(t *testing.T) { + var ( + chainConfig = params.MergedTestChainConfig + hashA = common.Hash{0x01} + hashB = common.Hash{0x02} + header = &types.Header{ParentHash: hashA, Number: big.NewInt(2), Difficulty: big.NewInt(0)} + parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1), Difficulty: big.NewInt(0)} + coinbase = common.Address{} + ) + test := func(statedb *state.StateDB) { + statedb.SetNonce(params.HistoryStorageAddress, 1) + statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode) + statedb.IntermediateRoot(true) + + vmContext := NewEVMBlockContext(header, nil, &coinbase) + evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + ProcessParentBlockHash(header.ParentHash, evm, statedb) + + vmContext = NewEVMBlockContext(parent, nil, &coinbase) + evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + ProcessParentBlockHash(parent.ParentHash, evm, statedb) + + // make sure that the state is correct + if have := getParentBlockHash(statedb, 1); have != hashA { + t.Errorf("want parent hash %v, have %v", hashA, have) + } + if have := getParentBlockHash(statedb, 0); have != hashB { + t.Errorf("want parent hash %v, have %v", hashB, have) + } + } + t.Run("MPT", func(t *testing.T) { + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + test(statedb) + }) + t.Run("Verkle", func(t *testing.T) { + db := rawdb.NewMemoryDatabase() + cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme) + cacheConfig.SnapshotLimit = 0 + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) + statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil)) + test(statedb) + }) +} + +func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash { + ringIndex := number % params.HistoryServeWindow + var key common.Hash + binary.BigEndian.PutUint64(key[24:], ringIndex) + return statedb.GetState(params.HistoryStorageAddress, key) } diff --git a/core/state_transition.go b/core/state_transition.go index f3f7b0f976..2d936516c5 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto/kzg4844" @@ -69,7 +70,7 @@ func (result *ExecutionResult) Revert() []byte { } // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { +func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { // Set the starting gas for the raw transaction var gas uint64 if isContractCreation && isHomestead { @@ -143,27 +144,31 @@ type Message struct { BlobGasFeeCap *big.Int BlobHashes []common.Hash - // When SkipAccountChecks is true, the message nonce is not checked against the - // account nonce in state. It also disables checking that the sender is an EOA. + // When SkipNonceChecks is true, the message nonce is not checked against the + // account nonce in state. // This field will be set to true for operations like RPC eth_call. - SkipAccountChecks bool + SkipNonceChecks bool + + // When SkipFromEOACheck is true, the message sender is not checked to be an EOA. + SkipFromEOACheck bool } // TransactionToMessage converts a transaction into a Message. func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) { msg := &Message{ - Nonce: tx.Nonce(), - GasLimit: tx.Gas(), - GasPrice: new(big.Int).Set(tx.GasPrice()), - GasFeeCap: new(big.Int).Set(tx.GasFeeCap()), - GasTipCap: new(big.Int).Set(tx.GasTipCap()), - To: tx.To(), - Value: tx.Value(), - Data: tx.Data(), - AccessList: tx.AccessList(), - SkipAccountChecks: false, - BlobHashes: tx.BlobHashes(), - BlobGasFeeCap: tx.BlobGasFeeCap(), + Nonce: tx.Nonce(), + GasLimit: tx.Gas(), + GasPrice: new(big.Int).Set(tx.GasPrice()), + GasFeeCap: new(big.Int).Set(tx.GasFeeCap()), + GasTipCap: new(big.Int).Set(tx.GasTipCap()), + To: tx.To(), + Value: tx.Value(), + Data: tx.Data(), + AccessList: tx.AccessList(), + SkipNonceChecks: false, + SkipFromEOACheck: false, + BlobHashes: tx.BlobHashes(), + BlobGasFeeCap: tx.BlobGasFeeCap(), } // If baseFee provided, set gasPrice to effectiveGasPrice. if baseFee != nil { @@ -236,13 +241,14 @@ func (st *StateTransition) to() common.Address { func (st *StateTransition) buyGas() error { mgval := new(big.Int).SetUint64(st.msg.GasLimit) - mgval = mgval.Mul(mgval, st.msg.GasPrice) + mgval.Mul(mgval, st.msg.GasPrice) balanceCheck := new(big.Int).Set(mgval) if st.msg.GasFeeCap != nil { balanceCheck.SetUint64(st.msg.GasLimit) balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) - balanceCheck.Add(balanceCheck, st.msg.Value) } + balanceCheck.Add(balanceCheck, st.msg.Value) + if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { if blobGas := st.blobGasUsed(); blobGas > 0 { // Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap @@ -265,18 +271,22 @@ func (st *StateTransition) buyGas() error { if err := st.gp.SubGas(st.msg.GasLimit); err != nil { return err } - st.gasRemaining += st.msg.GasLimit + + if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil { + st.evm.Config.Tracer.OnGasChange(0, st.msg.GasLimit, tracing.GasChangeTxInitialBalance) + } + st.gasRemaining = st.msg.GasLimit st.initialGas = st.msg.GasLimit mgvalU256, _ := uint256.FromBig(mgval) - st.state.SubBalance(st.msg.From, mgvalU256) + st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy) return nil } func (st *StateTransition) preCheck() error { // Only check transactions that are not fake msg := st.msg - if !msg.SkipAccountChecks { + if !msg.SkipNonceChecks { // Make sure this transaction's nonce is correct. stNonce := st.state.GetNonce(msg.From) if msgNonce := msg.Nonce; stNonce < msgNonce { @@ -289,6 +299,8 @@ func (st *StateTransition) preCheck() error { return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax, msg.From.Hex(), stNonce) } + } + if !msg.SkipFromEOACheck { // Make sure the sender is an EOA codeHash := st.state.GetCodeHash(msg.From) if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash { @@ -382,13 +394,6 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { return nil, err } - if tracer := st.evm.Config.Tracer; tracer != nil { - tracer.CaptureTxStart(st.initialGas) - defer func() { - tracer.CaptureTxEnd(st.gasRemaining) - }() - } - var ( msg = st.msg sender = vm.AccountRef(msg.From) @@ -413,8 +418,19 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if st.gasRemaining < gas { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas) } + if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { + t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas) + } st.gasRemaining -= gas + if rules.IsEIP4762 { + st.evm.AccessEvents.AddTxOrigin(msg.From) + + if targetAddr := msg.To; targetAddr != nil { + st.evm.AccessEvents.AddTxDestination(*targetAddr, msg.Value.Sign() != 0) + } + } + // Check clause 6 value, overflow := uint256.FromBig(msg.Value) if overflow { @@ -464,16 +480,21 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { fee.Mul(fee, effectiveTipU256) // consensus engine is parlia if st.evm.ChainConfig().Parlia != nil { - st.state.AddBalance(consensus.SystemAddress, fee) + st.state.AddBalance(consensus.SystemAddress, fee, tracing.BalanceIncreaseRewardTransactionFee) // add extra blob fee reward if rules.IsCancun { blobFee := new(big.Int).SetUint64(st.blobGasUsed()) blobFee.Mul(blobFee, st.evm.Context.BlobBaseFee) blobFeeU256, _ := uint256.FromBig(blobFee) - st.state.AddBalance(consensus.SystemAddress, blobFeeU256) + st.state.AddBalance(consensus.SystemAddress, blobFeeU256, tracing.BalanceIncreaseRewardTransactionFee) } } else { - st.state.AddBalance(st.evm.Context.Coinbase, fee) + st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee) + + // add the coinbase to the witness iff the fee is greater than 0 + if rules.IsEIP4762 && fee.Sign() != 0 { + st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true) + } } return &ExecutionResult{ @@ -490,12 +511,21 @@ func (st *StateTransition) refundGas(refundQuotient uint64) uint64 { if refund > st.state.GetRefund() { refund = st.state.GetRefund() } + + if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && refund > 0 { + st.evm.Config.Tracer.OnGasChange(st.gasRemaining, st.gasRemaining+refund, tracing.GasChangeTxRefunds) + } + st.gasRemaining += refund // Return ETH for remaining gas, exchanged at the original rate. remaining := uint256.NewInt(st.gasRemaining) - remaining = remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice)) - st.state.AddBalance(st.msg.From, remaining) + remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice)) + st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn) + + if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && st.gasRemaining > 0 { + st.evm.Config.Tracer.OnGasChange(st.gasRemaining, 0, tracing.GasChangeTxLeftOverReturned) + } // Also return remaining gas to the block gas counter so it is // available for the next transaction. diff --git a/core/stateless.go b/core/stateless.go new file mode 100644 index 0000000000..5b37d5020e --- /dev/null +++ b/core/stateless.go @@ -0,0 +1,80 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/triedb" +) + +// ExecuteStateless runs a stateless execution based on a witness, verifies +// everything it can locally and returns the state root and receipt root, that +// need the other side to explicitly check. +// +// This method is a bit of a sore thumb here, but: +// - It cannot be placed in core/stateless, because state.New prodces a circular dep +// - It cannot be placed outside of core, because it needs to construct a dud headerchain +// +// TODO(karalabe): Would be nice to resolve both issues above somehow and move it. +func ExecuteStateless(config *params.ChainConfig, block *types.Block, witness *stateless.Witness) (common.Hash, common.Hash, error) { + // Sanity check if the supplied block accidentally contains a set root or + // receipt hash. If so, be very loud, but still continue. + if block.Root() != (common.Hash{}) { + log.Error("stateless runner received state root it's expected to calculate (faulty consensus client)", "block", block.Number()) + } + if block.ReceiptHash() != (common.Hash{}) { + log.Error("stateless runner received receipt root it's expected to calculate (faulty consensus client)", "block", block.Number()) + } + // Create and populate the state database to serve as the stateless backend + memdb := witness.MakeHashDB() + db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil)) + if err != nil { + return common.Hash{}, common.Hash{}, err + } + // Create a blockchain that is idle, but can be used to access headers through + chain := &HeaderChain{ + config: config, + chainDb: memdb, + headerCache: lru.NewCache[common.Hash, *types.Header](256), + engine: beacon.New(ethash.NewFaker()), + } + processor := NewStateProcessor(config, chain) + validator := NewBlockValidator(config, nil) // No chain, we only validate the state, not the block + + // Run the stateless blocks processing and self-validate certain fields + res, err := processor.Process(block, db, vm.Config{}) + if err != nil { + return common.Hash{}, common.Hash{}, err + } + if err = validator.ValidateState(block, db, res, true); err != nil { + return common.Hash{}, common.Hash{}, err + } + // Almost everything validated, but receipt and state root needs to be returned + receiptRoot := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil)) + stateRoot := db.IntermediateRoot(config.IsEIP158(block.Number())) + return stateRoot, receiptRoot, nil +} diff --git a/core/stateless/database.go b/core/stateless/database.go new file mode 100644 index 0000000000..f54c123dda --- /dev/null +++ b/core/stateless/database.go @@ -0,0 +1,67 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stateless + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" +) + +// MakeHashDB imports tries, codes and block hashes from a witness into a new +// hash-based memory db. We could eventually rewrite this into a pathdb, but +// simple is better for now. +// +// Note, this hashdb approach is quite strictly self-validating: +// - Headers are persisted keyed by hash, so blockhash will error on junk +// - Codes are persisted keyed by hash, so bytecode lookup will error on junk +// - Trie nodes are persisted keyed by hash, so trie expansion will error on junk +// +// Acceleration structures built would need to explicitly validate the witness. +func (w *Witness) MakeHashDB() ethdb.Database { + var ( + memdb = rawdb.NewMemoryDatabase() + hasher = crypto.NewKeccakState() + hash = make([]byte, 32) + ) + // Inject all the "block hashes" (i.e. headers) into the ephemeral database + for _, header := range w.Headers { + rawdb.WriteHeader(memdb, header) + } + // Inject all the bytecodes into the ephemeral database + for code := range w.Codes { + blob := []byte(code) + + hasher.Reset() + hasher.Write(blob) + hasher.Read(hash) + + rawdb.WriteCode(memdb, common.BytesToHash(hash), blob) + } + // Inject all the MPT trie nodes into the ephemeral database + for node := range w.State { + blob := []byte(node) + + hasher.Reset() + hasher.Write(blob) + hasher.Read(hash) + + rawdb.WriteLegacyTrieNode(memdb, common.BytesToHash(hash), blob) + } + return memdb +} diff --git a/core/stateless/encoding.go b/core/stateless/encoding.go new file mode 100644 index 0000000000..5f4cb0ea3c --- /dev/null +++ b/core/stateless/encoding.go @@ -0,0 +1,76 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stateless + +import ( + "io" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// toExtWitness converts our internal witness representation to the consensus one. +func (w *Witness) toExtWitness() *extWitness { + ext := &extWitness{ + Headers: w.Headers, + } + ext.Codes = make([][]byte, 0, len(w.Codes)) + for code := range w.Codes { + ext.Codes = append(ext.Codes, []byte(code)) + } + ext.State = make([][]byte, 0, len(w.State)) + for node := range w.State { + ext.State = append(ext.State, []byte(node)) + } + return ext +} + +// fromExtWitness converts the consensus witness format into our internal one. +func (w *Witness) fromExtWitness(ext *extWitness) error { + w.Headers = ext.Headers + + w.Codes = make(map[string]struct{}, len(ext.Codes)) + for _, code := range ext.Codes { + w.Codes[string(code)] = struct{}{} + } + w.State = make(map[string]struct{}, len(ext.State)) + for _, node := range ext.State { + w.State[string(node)] = struct{}{} + } + return nil +} + +// EncodeRLP serializes a witness as RLP. +func (w *Witness) EncodeRLP(wr io.Writer) error { + return rlp.Encode(wr, w.toExtWitness()) +} + +// DecodeRLP decodes a witness from RLP. +func (w *Witness) DecodeRLP(s *rlp.Stream) error { + var ext extWitness + if err := s.Decode(&ext); err != nil { + return err + } + return w.fromExtWitness(&ext) +} + +// extWitness is a witness RLP encoding for transferring across clients. +type extWitness struct { + Headers []*types.Header + Codes [][]byte + State [][]byte +} diff --git a/core/stateless/witness.go b/core/stateless/witness.go new file mode 100644 index 0000000000..aecfad1d52 --- /dev/null +++ b/core/stateless/witness.go @@ -0,0 +1,122 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stateless + +import ( + "errors" + "maps" + "slices" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// HeaderReader is an interface to pull in headers in place of block hashes for +// the witness. +type HeaderReader interface { + // GetHeader retrieves a block header from the database by hash and number, + GetHeader(hash common.Hash, number uint64) *types.Header +} + +// Witness encompasses the state required to apply a set of transactions and +// derive a post state/receipt root. +type Witness struct { + context *types.Header // Header to which this witness belongs to, with rootHash and receiptHash zeroed out + + Headers []*types.Header // Past headers in reverse order (0=parent, 1=parent's-parent, etc). First *must* be set. + Codes map[string]struct{} // Set of bytecodes ran or accessed + State map[string]struct{} // Set of MPT state trie nodes (account and storage together) + + chain HeaderReader // Chain reader to convert block hash ops to header proofs + lock sync.Mutex // Lock to allow concurrent state insertions +} + +// NewWitness creates an empty witness ready for population. +func NewWitness(context *types.Header, chain HeaderReader) (*Witness, error) { + // When building witnesses, retrieve the parent header, which will *always* + // be included to act as a trustless pre-root hash container + var headers []*types.Header + if chain != nil { + parent := chain.GetHeader(context.ParentHash, context.Number.Uint64()-1) + if parent == nil { + return nil, errors.New("failed to retrieve parent header") + } + headers = append(headers, parent) + } + // Create the wtness with a reconstructed gutted out block + return &Witness{ + context: context, + Headers: headers, + Codes: make(map[string]struct{}), + State: make(map[string]struct{}), + chain: chain, + }, nil +} + +// AddBlockHash adds a "blockhash" to the witness with the designated offset from +// chain head. Under the hood, this method actually pulls in enough headers from +// the chain to cover the block being added. +func (w *Witness) AddBlockHash(number uint64) { + // Keep pulling in headers until this hash is populated + for int(w.context.Number.Uint64()-number) > len(w.Headers) { + tail := w.Headers[len(w.Headers)-1] + w.Headers = append(w.Headers, w.chain.GetHeader(tail.ParentHash, tail.Number.Uint64()-1)) + } +} + +// AddCode adds a bytecode blob to the witness. +func (w *Witness) AddCode(code []byte) { + if len(code) == 0 { + return + } + w.Codes[string(code)] = struct{}{} +} + +// AddState inserts a batch of MPT trie nodes into the witness. +func (w *Witness) AddState(nodes map[string]struct{}) { + if len(nodes) == 0 { + return + } + w.lock.Lock() + defer w.lock.Unlock() + + maps.Copy(w.State, nodes) +} + +// Copy deep-copies the witness object. Witness.Block isn't deep-copied as it +// is never mutated by Witness +func (w *Witness) Copy() *Witness { + cpy := &Witness{ + Headers: slices.Clone(w.Headers), + Codes: maps.Clone(w.Codes), + State: maps.Clone(w.State), + chain: w.chain, + } + if w.context != nil { + cpy.context = types.CopyHeader(w.context) + } + return cpy +} + +// Root returns the pre-state root from the first header. +// +// Note, this method will panic in case of a bad witness (but RLP decoding will +// sanitize it and fail before that). +func (w *Witness) Root() common.Hash { + return w.Headers[0].Root +} diff --git a/core/tracing/CHANGELOG.md b/core/tracing/CHANGELOG.md new file mode 100644 index 0000000000..e8aa3a9e2e --- /dev/null +++ b/core/tracing/CHANGELOG.md @@ -0,0 +1,99 @@ +# Changelog + +All notable changes to the tracing interface will be documented in this file. + +## [Unreleased] + +### Modified types + +- `GasChangeReason` has been extended with the following reasons which will be enabled only post-Verkle. There shouldn't be any gas changes with those reasons prior to the fork. + - `GasChangeWitnessContractCollisionCheck` flags the event of adding to the witness when checking for contract address collision. + +## [v1.14.4] + +This release contained only minor extensions to the tracing interface. + +### Modified types + +- `GasChangeReason` has been extended with the following reasons that will only be active post-Verkle. + - `GasChangeWitnessContractInit` flags the event of adding to the witness during the contract creation initialization step. + - `GasChangeWitnessContractCreation` flags the event of adding to the witness during the contract creation finalization step. + - `GasChangeWitnessCodeChunk` flags the event of adding one or more contract code chunks to the witness. + +## [v1.14.3] + +There have been minor backwards-compatible changes to the tracing interface to explicitly mark the execution of **system** contracts. As of now the only system call updates the parent beacon block root as per [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788). Other system calls are being considered for the future hardfork. + +### New methods + +- `OnSystemCallStart()`: This hook is called when EVM starts processing a system call. Note system calls happen outside the scope of a transaction. This event will be followed by normal EVM execution events. +- `OnSystemCallEnd()`: This hook is called when EVM finishes processing a system call. + +## [v1.14.0] + +There has been a major breaking change in the tracing interface for custom native tracers. JS and built-in tracers are not affected by this change and tracing API methods may be used as before. This overhaul has been done as part of the new live tracing feature ([#29189](https://github.com/ethereum/go-ethereum/pull/29189)). To learn more about live tracing please refer to the [docs](https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing). + +**The `EVMLogger` interface which the tracers implemented has been removed.** It has been replaced by a new struct `tracing.Hooks`. `Hooks` keeps pointers to event listening functions. Internally the EVM will use these function pointers to emit events and can skip an event if the tracer has opted not to implement it. In fact this is the main reason for this change of approach. Another benefit is the ease of adding new hooks in future, and dynamically assigning event receivers. + +The consequence of this change can be seen in the constructor of a tracer. Let's take the 4byte tracer as an example. Previously the constructor return an instance which satisfied the interface. Now it should return a pointer to `tracers.Tracer` (which is now also a struct as opposed to an interface) and explicitly assign the event listeners. As a side-benefit the tracers will not have to provide empty implementation of methods just to satisfy the interface: + +```go +func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { + t := &fourByteTracer{ + ids: make(map[string]int), + } + return t, nil + +} +``` + +And now: + +```go +func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) { + t := &fourByteTracer{ + ids: make(map[string]int), + } + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.onTxStart, + OnEnter: t.onEnter, + }, + GetResult: t.getResult, + Stop: t.stop, + }, nil +} +``` + +### Event listeners + +If you have sharp eyes you might have noticed the new names for `OnTxStart` and `OnEnter`, previously called `CaptureTxStart` and `CaptureEnter`. Indeed there have been various modifications to the signatures of the event listeners. All method names now follow the `On*` pattern instead of `Capture*`. However the modifications are not limited to the names. + +#### New methods + +The live tracing feature was half about adding more observability into the state of the blockchain. As such there have been a host of method additions. Please consult the [Hooks](./hooks.go) struct for the full list of methods. Custom tracers which are invoked through the API (as opposed to "live" tracers) can benefit from the following new methods: + +- `OnGasChange(old, new uint64, reason GasChangeReason)`: This hook tracks the lifetime of gas within a transaction and its subcalls. It will first track the initial purchase of gas with ether, then the following consumptions and refunds of gas until at the end the rest is returned. +- `OnBalanceChange(addr common.Address, prev, new *big.Int, reason BalanceChangeReason)`: This hook tracks the balance changes of accounts. Where possible a reason is provided for the change (e.g. a transfer, gas purchase, withdrawal deposit etc). +- `OnNonceChange(addr common.Address, prev, new uint64)`: This hook tracks the nonce changes of accounts. +- `OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte)`: This hook tracks the code changes of accounts. +- `OnStorageChange(addr common.Address, slot common.Hash, prev, new common.Hash)`: This hook tracks the storage changes of accounts. +- `OnLogChange(log *types.Log)`: This hook tracks the logs emitted by the EVM. + +#### Removed methods + +The hooks `CaptureStart` and `CaptureEnd` have been removed. These hooks signaled the top-level call frame of a transaction. The relevant info will be now emitted by `OnEnter` and `OnExit` which are emitted for every call frame. They now contain a `depth` parameter which can be used to distinguish the top-level call frame when necessary. The `create bool` parameter to `CaptureStart` can now be inferred from `typ byte` in `OnEnter`, i.e. `vm.OpCode(typ) == vm.CREATE`. + +#### Modified methods + +- `CaptureTxStart` -> `OnTxStart(vm *VMContext, tx *types.Transaction, from common.Address)`. It now emits the full transaction object as well as `from` which should be used to get the sender address. The `*VMContext` is a replacement for the `*vm.EVM` object previously passed to `CaptureStart`. +- `CaptureTxEnd` -> `OnTxEnd(receipt *types.Receipt, err error)`. It now returns the full receipt object. +- `CaptureEnter` -> `OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)`. The new `depth int` parameter indicates the call stack depth. It is 0 for the top-level call. Furthermore, the location where `OnEnter` is called in the EVM is now made a soon as a call is started. This means some specific error cases that were not before calling `OnEnter/OnExit` will now do so, leading some transaction to have an extra call traced. +- `CaptureExit` -> `OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool)`. It has the new `depth` parameter, same as `OnEnter`. The new `reverted` parameter indicates whether the call frame was reverted. +- `CaptureState` -> `OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error)`. `op` is of type `byte` which can be cast to `vm.OpCode` when necessary. A `*vm.ScopeContext` is not passed anymore. It is replaced by `tracing.OpContext` which offers access to the memory, stack and current contract. +- `CaptureFault` -> `OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error)`. Similar to above. + +[unreleased]: https://github.com/ethereum/go-ethereum/compare/v1.14.8...master +[v1.14.0]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0 +[v1.14.3]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.3 +[v1.14.4]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.4 diff --git a/core/tracing/gen_balance_change_reason_stringer.go b/core/tracing/gen_balance_change_reason_stringer.go new file mode 100644 index 0000000000..d3a515a12d --- /dev/null +++ b/core/tracing/gen_balance_change_reason_stringer.go @@ -0,0 +1,37 @@ +// Code generated by "stringer -type=BalanceChangeReason -output gen_balance_change_reason_stringer.go"; DO NOT EDIT. + +package tracing + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[BalanceChangeUnspecified-0] + _ = x[BalanceIncreaseRewardMineUncle-1] + _ = x[BalanceIncreaseRewardMineBlock-2] + _ = x[BalanceIncreaseWithdrawal-3] + _ = x[BalanceIncreaseGenesisBalance-4] + _ = x[BalanceIncreaseRewardTransactionFee-5] + _ = x[BalanceDecreaseGasBuy-6] + _ = x[BalanceIncreaseGasReturn-7] + _ = x[BalanceIncreaseDaoContract-8] + _ = x[BalanceDecreaseDaoAccount-9] + _ = x[BalanceChangeTransfer-10] + _ = x[BalanceChangeTouchAccount-11] + _ = x[BalanceIncreaseSelfdestruct-12] + _ = x[BalanceDecreaseSelfdestruct-13] + _ = x[BalanceDecreaseSelfdestructBurn-14] +} + +const _BalanceChangeReason_name = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurn" + +var _BalanceChangeReason_index = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400} + +func (i BalanceChangeReason) String() string { + if i >= BalanceChangeReason(len(_BalanceChangeReason_index)-1) { + return "BalanceChangeReason(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _BalanceChangeReason_name[_BalanceChangeReason_index[i]:_BalanceChangeReason_index[i+1]] +} diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go new file mode 100644 index 0000000000..882eb52837 --- /dev/null +++ b/core/tracing/hooks.go @@ -0,0 +1,316 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tracing + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" +) + +// OpContext provides the context at which the opcode is being +// executed in, including the memory, stack and various contract-level information. +type OpContext interface { + MemoryData() []byte + StackData() []uint256.Int + Caller() common.Address + Address() common.Address + CallValue() *uint256.Int + CallInput() []byte + ContractCode() []byte +} + +// StateDB gives tracers access to the whole state. +type StateDB interface { + GetBalance(common.Address) *uint256.Int + GetNonce(common.Address) uint64 + GetCode(common.Address) []byte + GetState(common.Address, common.Hash) common.Hash + Exist(common.Address) bool + GetRefund() uint64 +} + +// VMContext provides the context for the EVM execution. +type VMContext struct { + Coinbase common.Address + BlockNumber *big.Int + Time uint64 + Random *common.Hash + // Effective tx gas price + GasPrice *big.Int + ChainConfig *params.ChainConfig + StateDB StateDB +} + +// BlockEvent is emitted upon tracing an incoming block. +// It contains the block as well as consensus related information. +type BlockEvent struct { + Block *types.Block + TD *big.Int + Finalized *types.Header + Safe *types.Header +} + +type ( + /* + - VM events - + */ + + // TxStartHook is called before the execution of a transaction starts. + // Call simulations don't come with a valid signature. `from` field + // to be used for address of the caller. + TxStartHook = func(vm *VMContext, tx *types.Transaction, from common.Address) + + // TxEndHook is called after the execution of a transaction ends. + TxEndHook = func(receipt *types.Receipt, err error) + + // EnterHook is invoked when the processing of a message starts. + // + // Take note that EnterHook, when in the context of a live tracer, can be invoked + // outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls, + // see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information. + EnterHook = func(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) + + // ExitHook is invoked when the processing of a message ends. + // `revert` is true when there was an error during the execution. + // Exceptionally, before the homestead hardfork a contract creation that + // ran out of gas when attempting to persist the code to database did not + // count as a call failure and did not cause a revert of the call. This will + // be indicated by `reverted == false` and `err == ErrCodeStoreOutOfGas`. + // + // Take note that ExitHook, when in the context of a live tracer, can be invoked + // outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls, + // see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information. + ExitHook = func(depth int, output []byte, gasUsed uint64, err error, reverted bool) + + // OpcodeHook is invoked just prior to the execution of an opcode. + OpcodeHook = func(pc uint64, op byte, gas, cost uint64, scope OpContext, rData []byte, depth int, err error) + + // FaultHook is invoked when an error occurs during the execution of an opcode. + FaultHook = func(pc uint64, op byte, gas, cost uint64, scope OpContext, depth int, err error) + + // GasChangeHook is invoked when the gas changes. + GasChangeHook = func(old, new uint64, reason GasChangeReason) + + /* + - Chain events - + */ + + // BlockchainInitHook is called when the blockchain is initialized. + BlockchainInitHook = func(chainConfig *params.ChainConfig) + + // CloseHook is called when the blockchain closes. + CloseHook = func() + + // BlockStartHook is called before executing `block`. + // `td` is the total difficulty prior to `block`. + BlockStartHook = func(event BlockEvent) + + // BlockEndHook is called after executing a block. + BlockEndHook = func(err error) + + // SkippedBlockHook indicates a block was skipped during processing + // due to it being known previously. This can happen e.g. when recovering + // from a crash. + SkippedBlockHook = func(event BlockEvent) + + // GenesisBlockHook is called when the genesis block is being processed. + GenesisBlockHook = func(genesis *types.Block, alloc types.GenesisAlloc) + + // OnSystemCallStartHook is called when a system call is about to be executed. Today, + // this hook is invoked when the EIP-4788 system call is about to be executed to set the + // beacon block root. + // + // After this hook, the EVM call tracing will happened as usual so you will receive a `OnEnter/OnExit` + // as well as state hooks between this hook and the `OnSystemCallEndHook`. + // + // Note that system call happens outside normal transaction execution, so the `OnTxStart/OnTxEnd` hooks + // will not be invoked. + OnSystemCallStartHook = func() + + // OnSystemCallEndHook is called when a system call has finished executing. Today, + // this hook is invoked when the EIP-4788 system call is about to be executed to set the + // beacon block root. + OnSystemCallEndHook = func() + + /* + - State events - + */ + + // BalanceChangeHook is called when the balance of an account changes. + BalanceChangeHook = func(addr common.Address, prev, new *big.Int, reason BalanceChangeReason) + + // NonceChangeHook is called when the nonce of an account changes. + NonceChangeHook = func(addr common.Address, prev, new uint64) + + // CodeChangeHook is called when the code of an account changes. + CodeChangeHook = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) + + // StorageChangeHook is called when the storage of an account changes. + StorageChangeHook = func(addr common.Address, slot common.Hash, prev, new common.Hash) + + // LogHook is called when a log is emitted. + LogHook = func(log *types.Log) +) + +type Hooks struct { + // VM events + OnTxStart TxStartHook + OnTxEnd TxEndHook + OnEnter EnterHook + OnExit ExitHook + OnOpcode OpcodeHook + OnFault FaultHook + OnGasChange GasChangeHook + // Chain events + OnBlockchainInit BlockchainInitHook + OnClose CloseHook + OnBlockStart BlockStartHook + OnBlockEnd BlockEndHook + OnSkippedBlock SkippedBlockHook + OnGenesisBlock GenesisBlockHook + OnSystemCallStart OnSystemCallStartHook + OnSystemCallEnd OnSystemCallEndHook + // State events + OnBalanceChange BalanceChangeHook + OnNonceChange NonceChangeHook + OnCodeChange CodeChangeHook + OnStorageChange StorageChangeHook + OnLog LogHook +} + +// BalanceChangeReason is used to indicate the reason for a balance change, useful +// for tracing and reporting. +type BalanceChangeReason byte + +//go:generate go run golang.org/x/tools/cmd/stringer -type=BalanceChangeReason -output gen_balance_change_reason_stringer.go + +const ( + BalanceChangeUnspecified BalanceChangeReason = 0 + + // Issuance + // BalanceIncreaseRewardMineUncle is a reward for mining an uncle block. + BalanceIncreaseRewardMineUncle BalanceChangeReason = 1 + // BalanceIncreaseRewardMineBlock is a reward for mining a block. + BalanceIncreaseRewardMineBlock BalanceChangeReason = 2 + // BalanceIncreaseWithdrawal is ether withdrawn from the beacon chain. + BalanceIncreaseWithdrawal BalanceChangeReason = 3 + // BalanceIncreaseGenesisBalance is ether allocated at the genesis block. + BalanceIncreaseGenesisBalance BalanceChangeReason = 4 + + // Transaction fees + // BalanceIncreaseRewardTransactionFee is the transaction tip increasing block builder's balance. + BalanceIncreaseRewardTransactionFee BalanceChangeReason = 5 + // BalanceDecreaseGasBuy is spent to purchase gas for execution a transaction. + // Part of this gas will be burnt as per EIP-1559 rules. + BalanceDecreaseGasBuy BalanceChangeReason = 6 + // BalanceIncreaseGasReturn is ether returned for unused gas at the end of execution. + BalanceIncreaseGasReturn BalanceChangeReason = 7 + + // DAO fork + // BalanceIncreaseDaoContract is ether sent to the DAO refund contract. + BalanceIncreaseDaoContract BalanceChangeReason = 8 + // BalanceDecreaseDaoAccount is ether taken from a DAO account to be moved to the refund contract. + BalanceDecreaseDaoAccount BalanceChangeReason = 9 + + // BalanceChangeTransfer is ether transferred via a call. + // it is a decrease for the sender and an increase for the recipient. + BalanceChangeTransfer BalanceChangeReason = 10 + // BalanceChangeTouchAccount is a transfer of zero value. It is only there to + // touch-create an account. + BalanceChangeTouchAccount BalanceChangeReason = 11 + + // BalanceIncreaseSelfdestruct is added to the recipient as indicated by a selfdestructing account. + BalanceIncreaseSelfdestruct BalanceChangeReason = 12 + // BalanceDecreaseSelfdestruct is deducted from a contract due to self-destruct. + BalanceDecreaseSelfdestruct BalanceChangeReason = 13 + // BalanceDecreaseSelfdestructBurn is ether that is sent to an already self-destructed + // account within the same tx (captured at end of tx). + // Note it doesn't account for a self-destruct which appoints itself as recipient. + BalanceDecreaseSelfdestructBurn BalanceChangeReason = 14 +) + +// GasChangeReason is used to indicate the reason for a gas change, useful +// for tracing and reporting. +// +// There is essentially two types of gas changes, those that can be emitted once per transaction +// and those that can be emitted on a call basis, so possibly multiple times per transaction. +// +// They can be recognized easily by their name, those that start with `GasChangeTx` are emitted +// once per transaction, while those that start with `GasChangeCall` are emitted on a call basis. +type GasChangeReason byte + +const ( + GasChangeUnspecified GasChangeReason = 0 + + // GasChangeTxInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only + // one such gas change per transaction. + GasChangeTxInitialBalance GasChangeReason = 1 + // GasChangeTxIntrinsicGas is the amount of gas that will be charged for the intrinsic cost of the transaction, there is + // always exactly one of those per transaction. + GasChangeTxIntrinsicGas GasChangeReason = 2 + // GasChangeTxRefunds is the sum of all refunds which happened during the tx execution (e.g. storage slot being cleared) + // this generates an increase in gas. There is at most one of such gas change per transaction. + GasChangeTxRefunds GasChangeReason = 3 + // GasChangeTxLeftOverReturned is the amount of gas left over at the end of transaction's execution that will be returned + // to the chain. This change will always be a negative change as we "drain" left over gas towards 0. If there was no gas + // left at the end of execution, no such even will be emitted. The returned gas's value in Wei is returned to caller. + // There is at most one of such gas change per transaction. + GasChangeTxLeftOverReturned GasChangeReason = 4 + + // GasChangeCallInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only + // one such gas change per call. + GasChangeCallInitialBalance GasChangeReason = 5 + // GasChangeCallLeftOverReturned is the amount of gas left over that will be returned to the caller, this change will always + // be a negative change as we "drain" left over gas towards 0. If there was no gas left at the end of execution, no such even + // will be emitted. + GasChangeCallLeftOverReturned GasChangeReason = 6 + // GasChangeCallLeftOverRefunded is the amount of gas that will be refunded to the call after the child call execution it + // executed completed. This value is always positive as we are giving gas back to the you, the left over gas of the child. + // If there was no gas left to be refunded, no such even will be emitted. + GasChangeCallLeftOverRefunded GasChangeReason = 7 + // GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE. + GasChangeCallContractCreation GasChangeReason = 8 + // GasChangeContractCreation is the amount of gas that will be burned for a CREATE2. + GasChangeCallContractCreation2 GasChangeReason = 9 + // GasChangeCallCodeStorage is the amount of gas that will be charged for code storage. + GasChangeCallCodeStorage GasChangeReason = 10 + // GasChangeCallOpCode is the amount of gas that will be charged for an opcode executed by the EVM, exact opcode that was + // performed can be check by `OnOpcode` handling. + GasChangeCallOpCode GasChangeReason = 11 + // GasChangeCallPrecompiledContract is the amount of gas that will be charged for a precompiled contract execution. + GasChangeCallPrecompiledContract GasChangeReason = 12 + // GasChangeCallStorageColdAccess is the amount of gas that will be charged for a cold storage access as controlled by EIP2929 rules. + GasChangeCallStorageColdAccess GasChangeReason = 13 + // GasChangeCallFailedExecution is the burning of the remaining gas when the execution failed without a revert. + GasChangeCallFailedExecution GasChangeReason = 14 + // GasChangeWitnessContractInit flags the event of adding to the witness during the contract creation initialization step. + GasChangeWitnessContractInit GasChangeReason = 15 + // GasChangeWitnessContractCreation flags the event of adding to the witness during the contract creation finalization step. + GasChangeWitnessContractCreation GasChangeReason = 16 + // GasChangeWitnessCodeChunk flags the event of adding one or more contract code chunks to the witness. + GasChangeWitnessCodeChunk GasChangeReason = 17 + // GasChangeWitnessContractCollisionCheck flags the event of adding to the witness when checking for contract address collision. + GasChangeWitnessContractCollisionCheck GasChangeReason = 18 + + // GasChangeIgnored is a special value that can be used to indicate that the gas change should be ignored as + // it will be "manually" tracked by a direct emit of the gas change event. + GasChangeIgnored GasChangeReason = 0xFF +) diff --git a/core/txindexer_test.go b/core/txindexer_test.go index d078046355..220b0db298 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -18,7 +18,6 @@ package core import ( "math/big" - "os" "testing" "github.com/ethereum/go-ethereum/common" @@ -211,8 +210,7 @@ func TestTxIndexer(t *testing.T) { }, } for _, c := range cases { - frdir := t.TempDir() - db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, false) + db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false, false, false, false, false) rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) // Index the initial blocks from ancient store @@ -238,6 +236,5 @@ func TestTxIndexer(t *testing.T) { verify(db, 0, indexer) db.Close() - os.RemoveAll(frdir) } } diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index a30f0e1417..a9800b9039 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -411,7 +411,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres if p.head.ExcessBlobGas != nil { blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(*p.head.ExcessBlobGas)) } - p.evict = newPriceHeap(basefee, blobfee, &p.index) + p.evict = newPriceHeap(basefee, blobfee, p.index) // Pool initialized, attach the blob limbo to it to track blobs included // recently but not yet finalized @@ -482,7 +482,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error { log.Error("Rejecting duplicate blob pool entry", "id", id, "hash", tx.Hash()) return errors.New("duplicate blob entry") } - sender, err := p.signer.Sender(tx) + sender, err := types.Sender(p.signer, tx) if err != nil { // This path is impossible unless the signature validity changes across // restarts. For that ever improbable case, recover gracefully by ignoring @@ -570,7 +570,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 ids []uint64 nonces []uint64 ) - for txs[0].nonce < next { + for len(txs) > 0 && txs[0].nonce < next { ids = append(ids, txs[0].id) nonces = append(nonces, txs[0].nonce) @@ -896,7 +896,7 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]* // and accumulate the transactors and transactions for rem.NumberU64() > add.NumberU64() { for _, tx := range rem.Transactions() { - from, _ := p.signer.Sender(tx) + from, _ := types.Sender(p.signer, tx) discarded[from] = append(discarded[from], tx) transactors[from] = struct{}{} @@ -908,7 +908,7 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]* } for add.NumberU64() > rem.NumberU64() { for _, tx := range add.Transactions() { - from, _ := p.signer.Sender(tx) + from, _ := types.Sender(p.signer, tx) included[from] = append(included[from], tx) inclusions[tx.Hash()] = add.NumberU64() @@ -921,7 +921,7 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]* } for rem.Hash() != add.Hash() { for _, tx := range rem.Transactions() { - from, _ := p.signer.Sender(tx) + from, _ := types.Sender(p.signer, tx) discarded[from] = append(discarded[from], tx) transactors[from] = struct{}{} @@ -931,7 +931,7 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]* return nil, nil } for _, tx := range add.Transactions() { - from, _ := p.signer.Sender(tx) + from, _ := types.Sender(p.signer, tx) included[from] = append(included[from], tx) inclusions[tx.Hash()] = add.NumberU64() @@ -944,7 +944,7 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]* } // Generate the set of transactions per address to pull back into the pool, // also updating the rest along the way - reinject := make(map[common.Address][]*types.Transaction) + reinject := make(map[common.Address][]*types.Transaction, len(transactors)) for addr := range transactors { // Generate the set that was lost to reinject into the pool lost := make([]*types.Transaction, 0, len(discarded[addr])) @@ -1131,7 +1131,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error { ExistingCost: func(addr common.Address, nonce uint64) *big.Int { next := p.state.GetNonce(addr) if uint64(len(p.index[addr])) > nonce-next { - return p.index[addr][int(tx.Nonce()-next)].costCap.ToBig() + return p.index[addr][int(nonce-next)].costCap.ToBig() } return nil }, @@ -1142,7 +1142,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error { // If the transaction replaces an existing one, ensure that price bumps are // adhered to. var ( - from, _ = p.signer.Sender(tx) // already validated above + from, _ = types.Sender(p.signer, tx) // already validated above next = p.state.GetNonce(from) ) if uint64(len(p.index[from])) > tx.Nonce()-next { @@ -1170,11 +1170,11 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error { ) switch { case tx.GasFeeCapIntCmp(minGasFeeCap.ToBig()) < 0: - return fmt.Errorf("%w: new tx gas fee cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap, p.config.PriceBump) + return fmt.Errorf("%w: new tx gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap, p.config.PriceBump) case tx.GasTipCapIntCmp(minGasTipCap.ToBig()) < 0: - return fmt.Errorf("%w: new tx gas tip cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap, p.config.PriceBump) + return fmt.Errorf("%w: new tx gas tip cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap, p.config.PriceBump) case tx.BlobGasFeeCapIntCmp(minBlobGasFeeCap.ToBig()) < 0: - return fmt.Errorf("%w: new tx blob gas fee cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap, p.config.PriceBump) + return fmt.Errorf("%w: new tx blob gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap, p.config.PriceBump) } } return nil @@ -1241,7 +1241,7 @@ func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error return errs } -// Add inserts a new blob transaction into the pool if it passes validation (both +// add inserts a new blob transaction into the pool if it passes validation (both // consensus validity and pool restrictions). func (p *BlobPool) add(tx *types.Transaction) (err error) { // The blob pool blocks on adding a transaction. This is because blob txs are @@ -1619,6 +1619,7 @@ func (pool *BlobPool) SubscribeReannoTxsEvent(ch chan<- core.ReannoTxsEvent) eve // Nonce returns the next nonce of an account, with all transactions executable // by the pool already applied on top. func (p *BlobPool) Nonce(addr common.Address) uint64 { + // We need a write lock here, since state.GetNonce might write the cache. p.lock.Lock() defer p.lock.Unlock() @@ -1631,8 +1632,8 @@ func (p *BlobPool) Nonce(addr common.Address) uint64 { // Stats retrieves the current pool stats, namely the number of pending and the // number of queued (non-executable) transactions. func (p *BlobPool) Stats() (int, int) { - p.lock.Lock() - defer p.lock.Unlock() + p.lock.RLock() + defer p.lock.RUnlock() var pending int for _, txs := range p.index { diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index aff8609171..426cd57e63 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -27,19 +27,17 @@ import ( "path/filepath" "sync" "testing" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" @@ -48,31 +46,20 @@ import ( ) var ( - emptyBlob = kzg4844.Blob{} + emptyBlob = new(kzg4844.Blob) emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) ) -// Chain configuration with Cancun enabled. -// -// TODO(karalabe): replace with params.MainnetChainConfig after Cancun. -var testChainConfig *params.ChainConfig - -func init() { - testChainConfig = new(params.ChainConfig) - *testChainConfig = *params.MainnetChainConfig - - testChainConfig.CancunTime = new(uint64) - *testChainConfig.CancunTime = uint64(time.Now().Unix()) -} - // testBlockChain is a mock of the live chain for testing the pool. type testBlockChain struct { config *params.ChainConfig basefee *uint256.Int blobfee *uint256.Int statedb *state.StateDB + + blocks map[uint64]*types.Block } func (bc *testBlockChain) Config() *params.ChainConfig { @@ -80,7 +67,7 @@ func (bc *testBlockChain) Config() *params.ChainConfig { } func (bc *testBlockChain) CurrentBlock() *types.Header { - // Yolo, life is too short to invert mist.CalcBaseFee and misc.CalcBlobFee, + // Yolo, life is too short to invert misc.CalcBaseFee and misc.CalcBlobFee, // just binary search it them. // The base fee at 5714 ETH translates into the 21000 base gas higher than @@ -142,8 +129,15 @@ func (bc *testBlockChain) CurrentFinalBlock() *types.Header { } } -func (bt *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { - return nil +func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { + // This is very yolo for the tests. If the number is the origin block we use + // to init the pool, return an empty block with the correct starting header. + // + // If it is something else, return some baked in mock data. + if number == bc.config.LondonBlock.Uint64()+1 { + return types.NewBlockWithHeader(bc.CurrentBlock()) + } + return bc.blocks[number] } func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { @@ -182,14 +176,14 @@ func makeAddressReserver() txpool.AddressReserver { // the blob pool. func makeTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, key *ecdsa.PrivateKey) *types.Transaction { blobtx := makeUnsignedTx(nonce, gasTipCap, gasFeeCap, blobFeeCap) - return types.MustSignNewTx(key, types.LatestSigner(testChainConfig), blobtx) + return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx) } // makeUnsignedTx is a utility method to construct a random blob transaction // without signing it. func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64) *types.BlobTx { return &types.BlobTx{ - ChainID: uint256.MustFromBig(testChainConfig.ChainID), + ChainID: uint256.MustFromBig(params.MainnetChainConfig.ChainID), Nonce: nonce, GasTipCap: uint256.NewInt(gasTipCap), GasFeeCap: uint256.NewInt(gasFeeCap), @@ -198,7 +192,7 @@ func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap BlobHashes: []common.Hash{emptyBlobVHash}, Value: uint256.NewInt(100), Sidecar: &types.BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: []kzg4844.Blob{*emptyBlob}, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, @@ -230,13 +224,17 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) { for hash := range seen { t.Errorf("indexed transaction hash #%x missing from lookup table", hash) } - // Verify that transactions are sorted per account and contain no nonce gaps + // Verify that transactions are sorted per account and contain no nonce gaps, + // and that the first nonce is the next expected one based on the state. for addr, txs := range pool.index { for i := 1; i < len(txs); i++ { if txs[i].nonce != txs[i-1].nonce+1 { t.Errorf("addr %v, tx %d nonce mismatch: have %d, want %d", addr, i, txs[i].nonce, txs[i-1].nonce+1) } } + if txs[0].nonce != pool.state.GetNonce(addr) { + t.Errorf("addr %v, first tx nonce mismatch: have %d, want %d", addr, txs[0].nonce, pool.state.GetNonce(addr)) + } } // Verify that calculated evacuation thresholds are correct for addr, txs := range pool.index { @@ -332,7 +330,7 @@ func TestOpenDrops(t *testing.T) { // Insert a transaction with a bad signature to verify that stale junk after // potential hard-forks can get evicted (case 2) tx := types.NewTx(&types.BlobTx{ - ChainID: uint256.MustFromBig(testChainConfig.ChainID), + ChainID: uint256.MustFromBig(params.MainnetChainConfig.ChainID), GasTipCap: new(uint256.Int), GasFeeCap: new(uint256.Int), Gas: 0, @@ -544,26 +542,26 @@ func TestOpenDrops(t *testing.T) { store.Close() // Create a blob pool out of the pre-seeded data - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) - statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) statedb.SetNonce(crypto.PubkeyToAddress(filler.PublicKey), 3) - statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), uint256.NewInt(1000000)) + statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2) - statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000)) - statedb.AddBalance(crypto.PubkeyToAddress(duplicater.PublicKey), uint256.NewInt(1000000)) - statedb.AddBalance(crypto.PubkeyToAddress(repeater.PublicKey), uint256.NewInt(1000000)) + statedb.AddBalance(crypto.PubkeyToAddress(underpayer.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(outpricer.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(duplicater.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(crypto.PubkeyToAddress(repeater.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) statedb.Finalise(true) statedb.AccountsIntermediateRoot() statedb.Commit(0, nil) chain := &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(params.InitialBaseFee), blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice), statedb: statedb, @@ -677,14 +675,14 @@ func TestOpenIndex(t *testing.T) { store.Close() // Create a blob pool out of the pre-seeded data - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) - statedb.AddBalance(addr, uint256.NewInt(1_000_000_000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) statedb.Finalise(true) statedb.AccountsIntermediateRoot() statedb.Commit(0, nil) chain := &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(params.InitialBaseFee), blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice), statedb: statedb, @@ -779,16 +777,16 @@ func TestOpenHeap(t *testing.T) { store.Close() // Create a blob pool out of the pre-seeded data - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) - statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000)) - statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000)) - statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) statedb.Finalise(true) statedb.AccountsIntermediateRoot() statedb.Commit(0, nil) chain := &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(1050), blobfee: uint256.NewInt(105), statedb: statedb, @@ -861,16 +859,16 @@ func TestOpenCap(t *testing.T) { // with a high cap to ensure everything was persisted previously for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} { // Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) - statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000)) - statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000)) - statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) statedb.Finalise(true) statedb.AccountsIntermediateRoot() statedb.Commit(0, nil) chain := &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(1050), blobfee: uint256.NewInt(105), statedb: statedb, @@ -917,13 +915,12 @@ func TestOpenCap(t *testing.T) { func TestAdd(t *testing.T) { log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) - // seed is a helper tumpe to seed an initial state db and pool + // seed is a helper tuple to seed an initial state db and pool type seed struct { balance uint64 nonce uint64 txs []*types.BlobTx } - // addtx is a helper sender/tx tuple to represent a new tx addition type addtx struct { from string @@ -934,6 +931,7 @@ func TestAdd(t *testing.T) { tests := []struct { seeds map[string]seed adds []addtx + block []addtx }{ // Transactions from new accounts should be accepted if their initial // nonce matches the expected one from the statedb. Higher or lower must @@ -1259,6 +1257,25 @@ func TestAdd(t *testing.T) { }, }, }, + // Tests issue #30518 where a refactor broke internal state invariants, + // causing included transactions not to be properly accounted and thus + // account states going our of sync with the chain. + { + seeds: map[string]seed{ + "alice": { + balance: 1000000, + txs: []*types.BlobTx{ + makeUnsignedTx(0, 1, 1, 1), + }, + }, + }, + block: []addtx{ + { + from: "alice", + tx: makeUnsignedTx(0, 1, 1, 1), + }, + }, + }, } for i, tt := range tests { // Create a temporary folder for the persistent backend @@ -1273,19 +1290,19 @@ func TestAdd(t *testing.T) { keys = make(map[string]*ecdsa.PrivateKey) addrs = make(map[string]common.Address) ) - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) for acc, seed := range tt.seeds { // Generate a new random key/address for the seed account keys[acc], _ = crypto.GenerateKey() addrs[acc] = crypto.PubkeyToAddress(keys[acc].PublicKey) // Seed the state database with this account - statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance)) + statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance), tracing.BalanceChangeUnspecified) statedb.SetNonce(addrs[acc], seed.nonce) // Sign the seed transactions and store them in the data store for _, tx := range seed.txs { - signed := types.MustSignNewTx(keys[acc], types.LatestSigner(testChainConfig), tx) + signed := types.MustSignNewTx(keys[acc], types.LatestSigner(params.MainnetChainConfig), tx) blob, _ := rlp.EncodeToBytes(signed) store.Put(blob) } @@ -1297,7 +1314,7 @@ func TestAdd(t *testing.T) { // Create a blob pool out of the pre-seeded dats chain := &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(1050), blobfee: uint256.NewInt(105), statedb: statedb, @@ -1310,14 +1327,40 @@ func TestAdd(t *testing.T) { // Add each transaction one by one, verifying the pool internals in between for j, add := range tt.adds { - signed, _ := types.SignNewTx(keys[add.from], types.LatestSigner(testChainConfig), add.tx) + signed, _ := types.SignNewTx(keys[add.from], types.LatestSigner(params.MainnetChainConfig), add.tx) if err := pool.add(signed); !errors.Is(err, add.err) { t.Errorf("test %d, tx %d: adding transaction error mismatch: have %v, want %v", i, j, err, add.err) } verifyPoolInternals(t, pool) } - // Verify the pool internals and close down the test verifyPoolInternals(t, pool) + + // If the test contains a chain head event, run that and gain verify the internals + if tt.block != nil { + // Fake a header for the new set of transactions + header := &types.Header{ + Number: big.NewInt(int64(chain.CurrentBlock().Number.Uint64() + 1)), + BaseFee: chain.CurrentBlock().BaseFee, // invalid, but nothing checks it, yolo + } + // Inject the fake block into the chain + txs := make([]*types.Transaction, len(tt.block)) + for j, inc := range tt.block { + txs[j] = types.MustSignNewTx(keys[inc.from], types.LatestSigner(params.MainnetChainConfig), inc.tx) + } + chain.blocks = map[uint64]*types.Block{ + header.Number.Uint64(): types.NewBlockWithHeader(header).WithBody(types.Body{ + Transactions: txs, + }), + } + // Apply the nonce updates to the state db + for _, tx := range txs { + sender, _ := types.Sender(types.LatestSigner(params.MainnetChainConfig), tx) + chain.statedb.SetNonce(sender, tx.Nonce()+1) + } + pool.Reset(chain.CurrentBlock(), header) + verifyPoolInternals(t, pool) + } + // Close down the test pool.Close() } } @@ -1336,10 +1379,10 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) { var ( basefee = uint64(1050) blobfee = uint64(105) - signer = types.LatestSigner(testChainConfig) - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) + signer = types.LatestSigner(params.MainnetChainConfig) + statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) chain = &testBlockChain{ - config: testChainConfig, + config: params.MainnetChainConfig, basefee: uint256.NewInt(basefee), blobfee: uint256.NewInt(blobfee), statedb: statedb, @@ -1362,7 +1405,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) { if err != nil { b.Fatal(err) } - statedb.AddBalance(addr, uint256.NewInt(1_000_000_000)) + statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) pool.add(tx) } statedb.Finalise(true) diff --git a/core/txpool/blobpool/evictheap.go b/core/txpool/blobpool/evictheap.go index bc4543a352..5e285e6c53 100644 --- a/core/txpool/blobpool/evictheap.go +++ b/core/txpool/blobpool/evictheap.go @@ -17,13 +17,13 @@ package blobpool import ( - "bytes" "container/heap" "math" - "sort" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" + "golang.org/x/exp/maps" ) // evictHeap is a helper data structure to keep track of the cheapest bottleneck @@ -35,7 +35,7 @@ import ( // The goal of the heap is to decide which account has the worst bottleneck to // evict transactions from. type evictHeap struct { - metas *map[common.Address][]*blobTxMeta // Pointer to the blob pool's index for price retrievals + metas map[common.Address][]*blobTxMeta // Pointer to the blob pool's index for price retrievals basefeeJumps float64 // Pre-calculated absolute dynamic fee jumps for the base fee blobfeeJumps float64 // Pre-calculated absolute dynamic fee jumps for the blob fee @@ -46,23 +46,18 @@ type evictHeap struct { // newPriceHeap creates a new heap of cheapest accounts in the blob pool to evict // from in case of over saturation. -func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index *map[common.Address][]*blobTxMeta) *evictHeap { +func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index map[common.Address][]*blobTxMeta) *evictHeap { heap := &evictHeap{ metas: index, - index: make(map[common.Address]int), + index: make(map[common.Address]int, len(index)), } // Populate the heap in account sort order. Not really needed in practice, // but it makes the heap initialization deterministic and less annoying to // test in unit tests. - addrs := make([]common.Address, 0, len(*index)) - for addr := range *index { - addrs = append(addrs, addr) - } - sort.Slice(addrs, func(i, j int) bool { return bytes.Compare(addrs[i][:], addrs[j][:]) < 0 }) - - for _, addr := range addrs { - heap.index[addr] = len(heap.addrs) - heap.addrs = append(heap.addrs, addr) + heap.addrs = maps.Keys(index) + slices.SortFunc(heap.addrs, common.Address.Cmp) + for i, addr := range heap.addrs { + heap.index[addr] = i } heap.reinit(basefee, blobfee, true) return heap @@ -94,8 +89,8 @@ func (h *evictHeap) Len() int { // Less implements sort.Interface as part of heap.Interface, returning which of // the two requested accounts has a cheaper bottleneck. func (h *evictHeap) Less(i, j int) bool { - txsI := (*(h.metas))[h.addrs[i]] - txsJ := (*(h.metas))[h.addrs[j]] + txsI := h.metas[h.addrs[i]] + txsJ := h.metas[h.addrs[j]] lastI := txsI[len(txsI)-1] lastJ := txsJ[len(txsJ)-1] diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go index 01b136551c..1cf577cb00 100644 --- a/core/txpool/blobpool/evictheap_test.go +++ b/core/txpool/blobpool/evictheap_test.go @@ -37,17 +37,17 @@ func verifyHeapInternals(t *testing.T, evict *evictHeap) { seen := make(map[common.Address]struct{}) for i, addr := range evict.addrs { seen[addr] = struct{}{} - if _, ok := (*evict.metas)[addr]; !ok { + if _, ok := evict.metas[addr]; !ok { t.Errorf("heap contains unexpected address at slot %d: %v", i, addr) } } - for addr := range *evict.metas { + for addr := range evict.metas { if _, ok := seen[addr]; !ok { t.Errorf("heap is missing required address %v", addr) } } - if len(evict.addrs) != len(*evict.metas) { - t.Errorf("heap size %d mismatches metadata size %d", len(evict.addrs), len(*evict.metas)) + if len(evict.addrs) != len(evict.metas) { + t.Errorf("heap size %d mismatches metadata size %d", len(evict.addrs), len(evict.metas)) } // Ensure that all accounts are present in the heap order index and no extras have := make([]common.Address, len(evict.index)) @@ -159,7 +159,7 @@ func TestPriceHeapSorting(t *testing.T) { }} } // Create a price heap and check the pop order - priceheap := newPriceHeap(uint256.NewInt(tt.basefee), uint256.NewInt(tt.blobfee), &index) + priceheap := newPriceHeap(uint256.NewInt(tt.basefee), uint256.NewInt(tt.blobfee), index) verifyHeapInternals(t, priceheap) for j := 0; j < len(tt.order); j++ { @@ -218,7 +218,7 @@ func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) { }} } // Create a price heap and reinit it over and over - heap := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), &index) + heap := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), index) basefees := make([]*uint256.Int, b.N) blobfees := make([]*uint256.Int, b.N) @@ -278,7 +278,7 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { }} } // Create a price heap and overflow it over and over - evict := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), &index) + evict := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), index) var ( addrs = make([]common.Address, b.N) metas = make([]*blobTxMeta, b.N) diff --git a/core/txpool/blobpool/limbo.go b/core/txpool/blobpool/limbo.go index ec754f6894..32381a3936 100644 --- a/core/txpool/blobpool/limbo.go +++ b/core/txpool/blobpool/limbo.go @@ -60,7 +60,7 @@ func newLimbo(datadir string) (*limbo, error) { fails = append(fails, id) } } - store, err := billy.Open(billy.Options{Path: datadir}, newSlotter(), index) + store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, newSlotter(), index) if err != nil { return nil, err } diff --git a/core/txpool/blobpool/priority.go b/core/txpool/blobpool/priority.go index a8332bd9b0..7ae7f92def 100644 --- a/core/txpool/blobpool/priority.go +++ b/core/txpool/blobpool/priority.go @@ -23,8 +23,8 @@ import ( "github.com/holiman/uint256" ) -// log2_1_125 is used in the eviction priority calculation. -var log2_1_125 = math.Log2(1.125) +// log1_125 is used in the eviction priority calculation. +var log1_125 = math.Log(1.125) // evictionPriority calculates the eviction priority based on the algorithm // described in the BlobPool docs for both fee components. @@ -57,8 +57,8 @@ func evictionPriority1D(basefeeJumps float64, txfeeJumps float64) int { // dynamicFeeJumps calculates the log1.125(fee), namely the number of fee jumps // needed to reach the requested one. We only use it when calculating the jumps -// between 2 fees, so it doesn't matter from what exact number with returns. -// it returns the result from (0, 1, 1.125). +// between 2 fees, so it doesn't matter from what exact number it returns. +// It returns the result from (0, 1, 1.125). // // This method is very expensive, taking about 75ns on a very recent laptop CPU, // but the result does not change with the lifetime of a transaction, so it can @@ -67,7 +67,7 @@ func dynamicFeeJumps(fee *uint256.Int) float64 { if fee.IsZero() { return 0 // can't log2 zero, should never happen outside tests, but don't choke } - return math.Log2(fee.Float64()) / log2_1_125 + return math.Log(fee.Float64()) / log1_125 } // intLog2 is a helper to calculate the integral part of a log2 of an unsigned diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 0d5a1fb183..b89d06dd06 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -39,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" + "golang.org/x/exp/maps" ) const ( @@ -1840,7 +1841,7 @@ func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } type accountSet struct { accounts map[common.Address]struct{} signer types.Signer - cache *[]common.Address + cache []common.Address } // newAccountSet creates a new address set with an associated signer for sender @@ -1888,20 +1889,14 @@ func (as *accountSet) addTx(tx *types.Transaction) { // reuse. The returned slice should not be changed! func (as *accountSet) flatten() []common.Address { if as.cache == nil { - accounts := make([]common.Address, 0, len(as.accounts)) - for account := range as.accounts { - accounts = append(accounts, account) - } - as.cache = &accounts + as.cache = maps.Keys(as.accounts) } - return *as.cache + return as.cache } // merge adds all addresses from the 'other' set into 'as'. func (as *accountSet) merge(other *accountSet) { - for addr := range other.accounts { - as.accounts[addr] = struct{}{} - } + maps.Copy(as.accounts, other.accounts) as.cache = nil } diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index c8d3a76b83..1377479da1 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -21,8 +21,8 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" @@ -50,7 +50,7 @@ func fillPool(t testing.TB, pool *LegacyPool) { nonExecutableTxs := types.Transactions{} for i := 0; i < 384; i++ { key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(10000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(10000000000), tracing.BalanceChangeUnspecified) // Add executable ones for j := 0; j < int(pool.config.AccountSlots); j++ { executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key)) @@ -79,7 +79,7 @@ func TestTransactionFutureAttack(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig config.GlobalQueue = 100 @@ -92,7 +92,7 @@ func TestTransactionFutureAttack(t *testing.T) { // Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops { key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), tracing.BalanceChangeUnspecified) futureTxs := types.Transactions{} for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ { futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 100000, big.NewInt(500), key)) @@ -116,7 +116,7 @@ func TestTransactionFutureAttack(t *testing.T) { func TestTransactionFuture1559(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) @@ -129,7 +129,7 @@ func TestTransactionFuture1559(t *testing.T) { // Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops { key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), tracing.BalanceChangeUnspecified) futureTxs := types.Transactions{} for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ { futureTxs = append(futureTxs, dynamicFeeTx(1000+uint64(j), 100000, big.NewInt(200), big.NewInt(101), key)) @@ -149,7 +149,7 @@ func TestTransactionFuture1559(t *testing.T) { func TestTransactionZAttack(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver()) @@ -183,7 +183,7 @@ func TestTransactionZAttack(t *testing.T) { for j := 0; j < int(pool.config.GlobalQueue); j++ { futureTxs := types.Transactions{} key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), tracing.BalanceChangeUnspecified) futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 21000, big.NewInt(500), key)) pool.addRemotesSync(futureTxs) } @@ -191,7 +191,7 @@ func TestTransactionZAttack(t *testing.T) { overDraftTxs := types.Transactions{} { key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), tracing.BalanceChangeUnspecified) for j := 0; j < int(pool.config.GlobalSlots); j++ { overDraftTxs = append(overDraftTxs, pricedValuedTransaction(uint64(j), 600000000000, 21000, big.NewInt(500), key)) } @@ -217,7 +217,7 @@ func TestTransactionZAttack(t *testing.T) { func BenchmarkFutureAttack(b *testing.B) { // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig config.GlobalQueue = 100 @@ -228,7 +228,7 @@ func BenchmarkFutureAttack(b *testing.B) { fillPool(b, pool) key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000)) + pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), uint256.NewInt(100000000000), tracing.BalanceChangeUnspecified) futureTxs := types.Transactions{} for n := 0; n < b.N; n++ { diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 53c62b9bd3..b7566acae9 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -31,8 +31,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -87,7 +87,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { } func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { - return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) + return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil)) } func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { @@ -160,7 +160,7 @@ func setupPool() (*LegacyPool, *ecdsa.PrivateKey) { } func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed)) key, _ := crypto.GenerateKey() @@ -251,10 +251,10 @@ func (c *testChain) State() (*state.StateDB, error) { // a state change between those fetches. stdb := c.statedb if *c.trigger { - c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) // simulate that the new head block included tx0 and tx1 c.statedb.SetNonce(c.address, 2) - c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether)) + c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified) *c.trigger = false } return stdb, nil @@ -269,12 +269,12 @@ func TestStateChangeDuringReset(t *testing.T) { var ( key, _ = crypto.GenerateKey() address = crypto.PubkeyToAddress(key.PublicKey) - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) trigger = false ) // setup pool with 2 transaction in it - statedb.SetBalance(address, new(uint256.Int).SetUint64(params.Ether)) + statedb.SetBalance(address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified) blockchain := &testChain{newTestBlockChain(params.TestChainConfig, 1000000000, statedb, new(event.Feed)), address, &trigger} tx0 := transaction(0, 100000, key) @@ -308,7 +308,7 @@ func TestStateChangeDuringReset(t *testing.T) { func testAddBalance(pool *LegacyPool, addr common.Address, amount *big.Int) { pool.mu.Lock() - pool.currentState.AddBalance(addr, uint256.MustFromBig(amount)) + pool.currentState.AddBalance(addr, uint256.MustFromBig(amount), tracing.BalanceChangeUnspecified) pool.mu.Unlock() } @@ -468,8 +468,8 @@ func TestChainFork(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.AddBalance(addr, uint256.NewInt(100000000000000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified) pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed)) <-pool.requestReset(nil, nil) @@ -497,8 +497,8 @@ func TestDoubleNonce(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.AddBalance(addr, uint256.NewInt(100000000000000)) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified) pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed)) <-pool.requestReset(nil, nil) @@ -697,7 +697,7 @@ func TestPostponing(t *testing.T) { t.Parallel() // Create the pool to test the postponing with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -910,7 +910,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1003,7 +1003,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) { evictionInterval = time.Millisecond * 100 // Create the pool to test the non-expiration enforcement - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1189,7 +1189,7 @@ func TestPendingGlobalLimiting(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1291,7 +1291,7 @@ func TestCapClearsFromAll(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1326,7 +1326,7 @@ func TestPendingMinimumAllowance(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1375,7 +1375,7 @@ func TestRepricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -1495,7 +1495,7 @@ func TestMinGasPriceEnforced(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed)) txPoolConfig := DefaultConfig @@ -1668,7 +1668,7 @@ func TestRepricingKeepsLocals(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -1743,7 +1743,7 @@ func TestUnderpricing(t *testing.T) { testTxPoolConfig.OverflowPoolSlots = 5 // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -1858,7 +1858,7 @@ func TestStableUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -2103,7 +2103,7 @@ func TestDeduplication(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -2170,7 +2170,7 @@ func TestReplacement(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -2420,7 +2420,7 @@ func testJournaling(t *testing.T, nolocals bool) { os.Remove(journal) // Create the original pool to inject transaction into the journal - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) config := testTxPoolConfig @@ -2521,7 +2521,7 @@ func TestStatusCheck(t *testing.T) { t.Parallel() // Create the pool to test the status retrievals with - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed)) pool := New(testTxPoolConfig, blockchain) @@ -2760,7 +2760,7 @@ func BenchmarkMultiAccountBatchInsert(b *testing.B) { for i := 0; i < b.N; i++ { key, _ := crypto.GenerateKey() account := crypto.PubkeyToAddress(key.PublicKey) - pool.currentState.AddBalance(account, uint256.NewInt(1000000)) + pool.currentState.AddBalance(account, uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) tx := transaction(uint64(0), 100000, key) batches[i] = tx } diff --git a/core/txpool/legacypool/list.go b/core/txpool/legacypool/list.go index 582ef85d07..64f2d76b06 100644 --- a/core/txpool/legacypool/list.go +++ b/core/txpool/legacypool/list.go @@ -20,6 +20,7 @@ import ( "container/heap" "math" "math/big" + "slices" "sort" "sync" "sync/atomic" @@ -28,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" - "golang.org/x/exp/slices" ) var txSortedMapPool = sync.Pool{ diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 0864d9a740..6415e2a10d 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -33,7 +33,7 @@ import ( var ( // blobTxMinBlobGasPrice is the big.Int version of the configured protocol - // parameter to avoid constucting a new big integer for every transaction. + // parameter to avoid constructing a new big integer for every transaction. blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice) ) @@ -128,7 +128,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } sidecar := tx.BlobTxSidecar() if sidecar == nil { - return fmt.Errorf("missing sidecar in blob transaction") + return errors.New("missing sidecar in blob transaction") } // Ensure the number of items in the blob transaction and various side // data match up before doing any expensive validations @@ -169,7 +169,7 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err // Blob commitments match with the hashes in the transaction, verify the // blobs themselves via KZG for i := range sidecar.Blobs { - if err := kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { + if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { return fmt.Errorf("invalid blob %d: %v", i, err) } } @@ -208,7 +208,7 @@ type ValidationOptionsWithState struct { // rules without duplicating code and running the risk of missed updates. func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, opts *ValidationOptionsWithState) error { // Ensure the transaction adheres to nonce ordering - from, err := signer.Sender(tx) // already validated (and cached), but cleaner to check + from, err := types.Sender(signer, tx) // already validated (and cached), but cleaner to check if err != nil { log.Error("Transaction sender recovery failed", "err", err) return err diff --git a/core/types.go b/core/types.go index 09c15940c3..1c322c15ce 100644 --- a/core/types.go +++ b/core/types.go @@ -29,9 +29,8 @@ type Validator interface { // ValidateBody validates the given block's content. ValidateBody(block *types.Block) error - // ValidateState validates the given statedb and optionally the receipts and - // gas used. - ValidateState(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error + // ValidateState validates the given statedb and optionally the process result. + ValidateState(block *types.Block, state *state.StateDB, res *ProcessResult, stateless bool) error // RemoteVerifyManager return remoteVerifyManager of validator. RemoteVerifyManager() *remoteVerifyManager @@ -58,5 +57,13 @@ type Processor interface { // Process processes the state changes according to the Ethereum rules by running // the transaction messages using the statedb and applying any rewards to both // the processor (coinbase) and any included uncles. - Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*state.StateDB, types.Receipts, []*types.Log, uint64, error) + Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) +} + +// ProcessResult contains the values computed by Process. +type ProcessResult struct { + Receipts types.Receipts + Requests types.Requests + Logs []*types.Log + GasUsed uint64 } diff --git a/core/types/account.go b/core/types/account.go index bb0f4ca02e..52ce184cda 100644 --- a/core/types/account.go +++ b/core/types/account.go @@ -52,7 +52,7 @@ type accountMarshaling struct { } // storageJSON represents a 256 bit byte array, but allows less than 256 bits when -// unmarshaling from hex. +// unmarshalling from hex. type storageJSON common.Hash func (h *storageJSON) UnmarshalText(text []byte) error { diff --git a/core/types/block.go b/core/types/block.go index c7619f3f76..a95224277e 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -23,6 +23,7 @@ import ( "io" "math/big" "reflect" + "slices" "sync/atomic" "time" @@ -31,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-verkle" ) type VerifyStatus struct { @@ -86,6 +88,13 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) } +// ExecutionWitness represents the witness + proof used in a verkle context, +// to provide the ability to execute a block statelessly. +type ExecutionWitness struct { + StateDiff verkle.StateDiff `json:"stateDiff"` + VerkleProof *verkle.VerkleProof `json:"verkleProof"` +} + //go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go //go:generate go run ../../rlp/rlpgen -type Header -out gen_header_rlp.go @@ -121,6 +130,9 @@ type Header struct { // ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers. ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + + // RequestsHash was added by EIP-7685 and is ignored in legacy headers. + RequestsHash *common.Hash `json:"requestsRoot" rlp:"optional"` } // field type overrides for gencodec @@ -182,10 +194,11 @@ func (h *Header) SanityCheck() error { // EmptyBody returns true if there is no additional 'body' to complete the header // that is: no transactions, no uncles and no withdrawals. func (h *Header) EmptyBody() bool { - if h.WithdrawalsHash != nil { - return h.TxHash == EmptyTxsHash && *h.WithdrawalsHash == EmptyWithdrawalsHash - } - return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash + var ( + emptyWithdrawals = h.WithdrawalsHash == nil || *h.WithdrawalsHash == EmptyWithdrawalsHash + emptyRequests = h.RequestsHash == nil || *h.RequestsHash == EmptyReceiptsHash + ) + return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash && emptyWithdrawals && emptyRequests } // EmptyReceipts returns true if there are no receipts for this header/block. @@ -204,6 +217,7 @@ type Body struct { Transactions []*Transaction Uncles []*Header Withdrawals []*Withdrawal `rlp:"optional"` + Requests []*Request `rlp:"optional"` } // Block represents an Ethereum block. @@ -228,10 +242,16 @@ type Block struct { uncles []*Header transactions Transactions withdrawals Withdrawals + requests Requests + + // witness is not an encoded part of the block body. + // It is held in Block in order for easy relaying to the places + // that process it. + witness *ExecutionWitness // caches - hash atomic.Value - size atomic.Value + hash atomic.Pointer[common.Hash] + size atomic.Uint64 // These fields are used by package eth to track // inter-peer block relay. @@ -248,18 +268,26 @@ type extblock struct { Txs []*Transaction Uncles []*Header Withdrawals []*Withdrawal `rlp:"optional"` + Requests []*Request `rlp:"optional"` } // NewBlock creates a new block. The input data is copied, changes to header and to the // field values will not affect the block. // -// The values of TxHash, UncleHash, ReceiptHash and Bloom in header -// are ignored and set to values derived from the given txs, uncles -// and receipts. -func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher TrieHasher) *Block { - b := &Block{header: CopyHeader(header)} +// The body elements and the receipts are used to recompute and overwrite the +// relevant portions of the header. +func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block { + if body == nil { + body = &Body{} + } + var ( + b = NewBlockWithHeader(header) + txs = body.Transactions + uncles = body.Uncles + withdrawals = body.Withdrawals + requests = body.Requests + ) - // TODO: panic if len(txs) != len(receipts) if len(txs) == 0 { b.header.TxHash = EmptyTxsHash } else { @@ -285,27 +313,29 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []* } } - return b -} - -// NewBlockWithWithdrawals creates a new block with withdrawals. The input data is copied, -// changes to header and to the field values will not affect the block. -// -// The values of TxHash, UncleHash, ReceiptHash and Bloom in header are ignored and set to -// values derived from the given txs, uncles and receipts. -func NewBlockWithWithdrawals(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, withdrawals []*Withdrawal, hasher TrieHasher) *Block { - b := NewBlock(header, txs, uncles, receipts, hasher) - if withdrawals == nil { b.header.WithdrawalsHash = nil } else if len(withdrawals) == 0 { b.header.WithdrawalsHash = &EmptyWithdrawalsHash + b.withdrawals = Withdrawals{} + } else { + hash := DeriveSha(Withdrawals(withdrawals), hasher) + b.header.WithdrawalsHash = &hash + b.withdrawals = slices.Clone(withdrawals) + } + + if requests == nil { + b.header.RequestsHash = nil + } else if len(requests) == 0 { + b.header.RequestsHash = &EmptyRequestsHash + b.requests = Requests{} } else { - h := DeriveSha(Withdrawals(withdrawals), hasher) - b.header.WithdrawalsHash = &h + h := DeriveSha(Requests(requests), hasher) + b.header.RequestsHash = &h + b.requests = slices.Clone(requests) } - return b.WithWithdrawals(withdrawals) + return b } // CopyHeader creates a deep copy of a block header. @@ -340,6 +370,10 @@ func CopyHeader(h *Header) *Header { cpy.ParentBeaconRoot = new(common.Hash) *cpy.ParentBeaconRoot = *h.ParentBeaconRoot } + if h.RequestsHash != nil { + cpy.RequestsHash = new(common.Hash) + *cpy.RequestsHash = *h.RequestsHash + } return &cpy } @@ -350,7 +384,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error { if err := s.Decode(&eb); err != nil { return err } - b.header, b.uncles, b.transactions, b.withdrawals = eb.Header, eb.Uncles, eb.Txs, eb.Withdrawals + b.header, b.uncles, b.transactions, b.withdrawals, b.requests = eb.Header, eb.Uncles, eb.Txs, eb.Withdrawals, eb.Requests b.size.Store(rlp.ListSize(size)) return nil } @@ -362,13 +396,14 @@ func (b *Block) EncodeRLP(w io.Writer) error { Txs: b.transactions, Uncles: b.uncles, Withdrawals: b.withdrawals, + Requests: b.requests, }) } // Body returns the non-header content of the block. // Note the returned data is not an independent copy. func (b *Block) Body() *Body { - return &Body{b.transactions, b.uncles, b.withdrawals} + return &Body{b.transactions, b.uncles, b.withdrawals, b.requests} } // Accessors for body data. These do not return a copy because the content @@ -377,6 +412,7 @@ func (b *Block) Body() *Body { func (b *Block) Uncles() []*Header { return b.uncles } func (b *Block) Transactions() Transactions { return b.transactions } func (b *Block) Withdrawals() Withdrawals { return b.withdrawals } +func (b *Block) Requests() Requests { return b.requests } func (b *Block) Transaction(hash common.Hash) *Transaction { for _, transaction := range b.transactions { @@ -439,11 +475,14 @@ func (b *Block) BlobGasUsed() *uint64 { return blobGasUsed } +// ExecutionWitness returns the verkle execution witneess + proof for a block +func (b *Block) ExecutionWitness() *ExecutionWitness { return b.witness } + // Size returns the true RLP encoded storage size of the block, either by encoding // and returning it, or returning a previously cached value. func (b *Block) Size() uint64 { - if size := b.size.Load(); size != nil { - return size.(uint64) + if size := b.size.Load(); size > 0 { + return size } c := writeCounter(0) rlp.Encode(&c, b) @@ -502,21 +541,25 @@ func (b *Block) WithSeal(header *Header) *Block { uncles: b.uncles, withdrawals: b.withdrawals, sidecars: b.sidecars, + requests: b.requests, + witness: b.witness, } } -// WithBody returns a copy of the block with the given transaction and uncle contents. -func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block { +// WithBody returns a new block with the original header and a deep copy of the +// provided body. +func (b *Block) WithBody(body Body) *Block { block := &Block{ header: b.header, - transactions: make([]*Transaction, len(transactions)), - uncles: make([]*Header, len(uncles)), - withdrawals: b.withdrawals, + transactions: slices.Clone(body.Transactions), + uncles: make([]*Header, len(body.Uncles)), + withdrawals: slices.Clone(body.Withdrawals), sidecars: b.sidecars, + requests: slices.Clone(body.Requests), + witness: b.witness, } - copy(block.transactions, transactions) - for i := range uncles { - block.uncles[i] = CopyHeader(uncles[i]) + for i := range body.Uncles { + block.uncles[i] = CopyHeader(body.Uncles[i]) } return block } @@ -528,6 +571,8 @@ func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block { transactions: b.transactions, uncles: b.uncles, sidecars: b.sidecars, + requests: b.requests, + witness: b.witness, } if withdrawals != nil { block.withdrawals = make([]*Withdrawal, len(withdrawals)) @@ -543,6 +588,8 @@ func (b *Block) WithSidecars(sidecars BlobSidecars) *Block { transactions: b.transactions, uncles: b.uncles, withdrawals: b.withdrawals, + requests: b.requests, + witness: b.witness, } if sidecars != nil { block.sidecars = make(BlobSidecars, len(sidecars)) @@ -551,15 +598,27 @@ func (b *Block) WithSidecars(sidecars BlobSidecars) *Block { return block } +func (b *Block) WithWitness(witness *ExecutionWitness) *Block { + return &Block{ + header: b.header, + transactions: b.transactions, + uncles: b.uncles, + withdrawals: b.withdrawals, + sidecars: b.sidecars, + requests: b.requests, + witness: witness, + } +} + // Hash returns the keccak256 hash of b's header. // The hash is computed on the first call and cached thereafter. func (b *Block) Hash() common.Hash { if hash := b.hash.Load(); hash != nil { - return hash.(common.Hash) + return *hash } - v := b.header.Hash() - b.hash.Store(v) - return v + h := b.header.Hash() + b.hash.Store(&h) + return h } type Blocks []*Block diff --git a/core/types/block_test.go b/core/types/block_test.go index 68b278289f..2193696cfe 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -197,7 +197,7 @@ func TestEIP2718BlockEncoding(t *testing.T) { func TestUncleHash(t *testing.T) { uncles := make([]*Header, 0) h := CalcUncleHash(uncles) - exp := common.HexToHash("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") + exp := EmptyUncleHash if h != exp { t.Fatalf("empty uncle hash is wrong, got %x != %x", h, exp) } @@ -255,7 +255,7 @@ func makeBenchBlock() *Block { Extra: []byte("benchmark uncle"), } } - return NewBlock(header, txs, uncles, receipts, blocktest.NewHasher()) + return NewBlock(header, &Body{Transactions: txs, Uncles: uncles}, receipts, blocktest.NewHasher()) } func TestRlpDecodeParentHash(t *testing.T) { diff --git a/core/types/deposit.go b/core/types/deposit.go new file mode 100644 index 0000000000..172acc36ed --- /dev/null +++ b/core/types/deposit.go @@ -0,0 +1,103 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rlp" +) + +//go:generate go run github.com/fjl/gencodec -type Deposit -field-override depositMarshaling -out gen_deposit_json.go + +// Deposit contains EIP-6110 deposit data. +type Deposit struct { + PublicKey [48]byte `json:"pubkey"` // public key of validator + WithdrawalCredentials common.Hash `json:"withdrawalCredentials"` // beneficiary of the validator funds + Amount uint64 `json:"amount"` // deposit size in Gwei + Signature [96]byte `json:"signature"` // signature over deposit msg + Index uint64 `json:"index"` // deposit count value +} + +// field type overrides for gencodec +type depositMarshaling struct { + PublicKey hexutil.Bytes + WithdrawalCredentials hexutil.Bytes + Amount hexutil.Uint64 + Signature hexutil.Bytes + Index hexutil.Uint64 +} + +// Deposits implements DerivableList for requests. +type Deposits []*Deposit + +// Len returns the length of s. +func (s Deposits) Len() int { return len(s) } + +// EncodeIndex encodes the i'th deposit to s. +func (s Deposits) EncodeIndex(i int, w *bytes.Buffer) { + rlp.Encode(w, s[i]) +} + +// UnpackIntoDeposit unpacks a serialized DepositEvent. +func UnpackIntoDeposit(data []byte) (*Deposit, error) { + if len(data) != 576 { + return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data)) + } + var d Deposit + // The ABI encodes the position of dynamic elements first. Since there are 5 + // elements, skip over the positional data. The first 32 bytes of dynamic + // elements also encode their actual length. Skip over that value too. + b := 32*5 + 32 + // PublicKey is the first element. ABI encoding pads values to 32 bytes, so + // despite BLS public keys being length 48, the value length here is 64. Then + // skip over the next length value. + copy(d.PublicKey[:], data[b:b+48]) + b += 48 + 16 + 32 + // WithdrawalCredentials is 32 bytes. Read that value then skip over next + // length. + copy(d.WithdrawalCredentials[:], data[b:b+32]) + b += 32 + 32 + // Amount is 8 bytes, but it is padded to 32. Skip over it and the next + // length. + d.Amount = binary.LittleEndian.Uint64(data[b : b+8]) + b += 8 + 24 + 32 + // Signature is 96 bytes. Skip over it and the next length. + copy(d.Signature[:], data[b:b+96]) + b += 96 + 32 + // Amount is 8 bytes. + d.Index = binary.LittleEndian.Uint64(data[b : b+8]) + + return &d, nil +} + +func (d *Deposit) requestType() byte { return DepositRequestType } +func (d *Deposit) encode(b *bytes.Buffer) error { return rlp.Encode(b, d) } +func (d *Deposit) decode(input []byte) error { return rlp.DecodeBytes(input, d) } +func (d *Deposit) copy() RequestData { + return &Deposit{ + PublicKey: d.PublicKey, + WithdrawalCredentials: d.WithdrawalCredentials, + Amount: d.Amount, + Signature: d.Signature, + Index: d.Index, + } +} diff --git a/core/types/deposit_test.go b/core/types/deposit_test.go new file mode 100644 index 0000000000..ed2e18445d --- /dev/null +++ b/core/types/deposit_test.go @@ -0,0 +1,93 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "encoding/binary" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +var ( + depositABI = abi.ABI{Methods: map[string]abi.Method{"DepositEvent": depositEvent}} + bytesT, _ = abi.NewType("bytes", "", nil) + depositEvent = abi.NewMethod("DepositEvent", "DepositEvent", abi.Function, "", false, false, []abi.Argument{ + {Name: "pubkey", Type: bytesT, Indexed: false}, + {Name: "withdrawal_credentials", Type: bytesT, Indexed: false}, + {Name: "amount", Type: bytesT, Indexed: false}, + {Name: "signature", Type: bytesT, Indexed: false}, + {Name: "index", Type: bytesT, Indexed: false}}, nil, + ) +) + +// FuzzUnpackIntoDeposit tries roundtrip packing and unpacking of deposit events. +func FuzzUnpackIntoDeposit(f *testing.F) { + for _, tt := range []struct { + pubkey string + wxCred string + amount string + sig string + index string + }{ + { + pubkey: "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + wxCred: "2222222222222222222222222222222222222222222222222222222222222222", + amount: "3333333333333333", + sig: "444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444", + index: "5555555555555555", + }, + } { + f.Add(common.FromHex(tt.pubkey), common.FromHex(tt.wxCred), common.FromHex(tt.amount), common.FromHex(tt.sig), common.FromHex(tt.index)) + } + + f.Fuzz(func(t *testing.T, p []byte, w []byte, a []byte, s []byte, i []byte) { + var ( + pubkey [48]byte + wxCred [32]byte + amount [8]byte + sig [96]byte + index [8]byte + ) + copy(pubkey[:], p) + copy(wxCred[:], w) + copy(amount[:], a) + copy(sig[:], s) + copy(index[:], i) + + want := Deposit{ + PublicKey: pubkey, + WithdrawalCredentials: wxCred, + Amount: binary.LittleEndian.Uint64(amount[:]), + Signature: sig, + Index: binary.LittleEndian.Uint64(index[:]), + } + out, err := depositABI.Pack("DepositEvent", want.PublicKey[:], want.WithdrawalCredentials[:], amount[:], want.Signature[:], index[:]) + if err != nil { + t.Fatalf("error packing deposit: %v", err) + } + got, err := UnpackIntoDeposit(out[4:]) + if err != nil { + t.Errorf("error unpacking deposit: %v", err) + } + if !reflect.DeepEqual(want, *got) { + t.Errorf("roundtrip failed: want %v, got %v", want, got) + } + }) +} diff --git a/core/types/gen_deposit_json.go b/core/types/gen_deposit_json.go new file mode 100644 index 0000000000..a65691188f --- /dev/null +++ b/core/types/gen_deposit_json.go @@ -0,0 +1,70 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package types + +import ( + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var _ = (*depositMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (d Deposit) MarshalJSON() ([]byte, error) { + type Deposit struct { + PublicKey hexutil.Bytes `json:"pubkey"` + WithdrawalCredentials hexutil.Bytes `json:"withdrawalCredentials"` + Amount hexutil.Uint64 `json:"amount"` + Signature hexutil.Bytes `json:"signature"` + Index hexutil.Uint64 `json:"index"` + } + var enc Deposit + enc.PublicKey = d.PublicKey[:] + enc.WithdrawalCredentials = d.WithdrawalCredentials[:] + enc.Amount = hexutil.Uint64(d.Amount) + enc.Signature = d.Signature[:] + enc.Index = hexutil.Uint64(d.Index) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (d *Deposit) UnmarshalJSON(input []byte) error { + type Deposit struct { + PublicKey *hexutil.Bytes `json:"pubkey"` + WithdrawalCredentials *hexutil.Bytes `json:"withdrawalCredentials"` + Amount *hexutil.Uint64 `json:"amount"` + Signature *hexutil.Bytes `json:"signature"` + Index *hexutil.Uint64 `json:"index"` + } + var dec Deposit + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.PublicKey != nil { + if len(*dec.PublicKey) != len(d.PublicKey) { + return errors.New("field 'pubkey' has wrong length, need 48 items") + } + copy(d.PublicKey[:], *dec.PublicKey) + } + if dec.WithdrawalCredentials != nil { + if len(*dec.WithdrawalCredentials) != len(d.WithdrawalCredentials) { + return errors.New("field 'withdrawalCredentials' has wrong length, need 32 items") + } + copy(d.WithdrawalCredentials[:], *dec.WithdrawalCredentials) + } + if dec.Amount != nil { + d.Amount = uint64(*dec.Amount) + } + if dec.Signature != nil { + if len(*dec.Signature) != len(d.Signature) { + return errors.New("field 'signature' has wrong length, need 96 items") + } + copy(d.Signature[:], *dec.Signature) + } + if dec.Index != nil { + d.Index = uint64(*dec.Index) + } + return nil +} diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index fb1f915d01..322c5d5642 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -36,6 +36,7 @@ func (h Header) MarshalJSON() ([]byte, error) { BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + RequestsHash *common.Hash `json:"requestsRoot" rlp:"optional"` Hash common.Hash `json:"hash"` } var enc Header @@ -59,6 +60,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.BlobGasUsed = (*hexutil.Uint64)(h.BlobGasUsed) enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) enc.ParentBeaconRoot = h.ParentBeaconRoot + enc.RequestsHash = h.RequestsHash enc.Hash = h.Hash() return json.Marshal(&enc) } @@ -86,6 +88,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + RequestsHash *common.Hash `json:"requestsRoot" rlp:"optional"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { @@ -163,5 +166,8 @@ func (h *Header) UnmarshalJSON(input []byte) error { if dec.ParentBeaconRoot != nil { h.ParentBeaconRoot = dec.ParentBeaconRoot } + if dec.RequestsHash != nil { + h.RequestsHash = dec.RequestsHash + } return nil } diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go index ed6a1a002c..c79aa8a250 100644 --- a/core/types/gen_header_rlp.go +++ b/core/types/gen_header_rlp.go @@ -42,7 +42,8 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { _tmp3 := obj.BlobGasUsed != nil _tmp4 := obj.ExcessBlobGas != nil _tmp5 := obj.ParentBeaconRoot != nil - if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 { + _tmp6 := obj.RequestsHash != nil + if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 { if obj.BaseFee == nil { w.Write(rlp.EmptyString) } else { @@ -52,34 +53,41 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { w.WriteBigInt(obj.BaseFee) } } - if _tmp2 || _tmp3 || _tmp4 || _tmp5 { + if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 { if obj.WithdrawalsHash == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.WithdrawalsHash[:]) } } - if _tmp3 || _tmp4 || _tmp5 { + if _tmp3 || _tmp4 || _tmp5 || _tmp6 { if obj.BlobGasUsed == nil { w.Write([]byte{0x80}) } else { w.WriteUint64((*obj.BlobGasUsed)) } } - if _tmp4 || _tmp5 { + if _tmp4 || _tmp5 || _tmp6 { if obj.ExcessBlobGas == nil { w.Write([]byte{0x80}) } else { w.WriteUint64((*obj.ExcessBlobGas)) } } - if _tmp5 { + if _tmp5 || _tmp6 { if obj.ParentBeaconRoot == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.ParentBeaconRoot[:]) } } + if _tmp6 { + if obj.RequestsHash == nil { + w.Write([]byte{0x80}) + } else { + w.WriteBytes(obj.RequestsHash[:]) + } + } w.ListEnd(_tmp0) return w.Flush() } diff --git a/core/types/hashes.go b/core/types/hashes.go index 43e9130fd1..cbd197072e 100644 --- a/core/types/hashes.go +++ b/core/types/hashes.go @@ -41,6 +41,9 @@ var ( // EmptyWithdrawalsHash is the known hash of the empty withdrawal set. EmptyWithdrawalsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + // EmptyRequestsHash is the known hash of the empty requests set. + EmptyRequestsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + // EmptyVerkleHash is the known hash of an empty verkle trie. EmptyVerkleHash = common.Hash{} ) diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index a7b2644471..fc51eb11a5 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -343,7 +343,7 @@ func TestReceiptJSON(t *testing.T) { r := Receipt{} err = r.UnmarshalJSON(b) if err != nil { - t.Fatal("error unmarshaling receipt from json:", err) + t.Fatal("error unmarshalling receipt from json:", err) } } } @@ -360,7 +360,7 @@ func TestEffectiveGasPriceNotRequired(t *testing.T) { r2 := Receipt{} err = r2.UnmarshalJSON(b) if err != nil { - t.Fatal("error unmarshaling receipt from json:", err) + t.Fatal("error unmarshalling receipt from json:", err) } } diff --git a/core/types/request.go b/core/types/request.go new file mode 100644 index 0000000000..7b1cade26e --- /dev/null +++ b/core/types/request.go @@ -0,0 +1,157 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "errors" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + ErrRequestTypeNotSupported = errors.New("request type not supported") + errShortTypedRequest = errors.New("typed request too short") +) + +// Request types. +const ( + DepositRequestType = 0x00 +) + +// Request is an EIP-7685 request object. It represents execution layer +// triggered messages bound for the consensus layer. +type Request struct { + inner RequestData +} + +// Type returns the EIP-7685 type of the request. +func (r *Request) Type() byte { + return r.inner.requestType() +} + +// Inner returns the inner request data. +func (r *Request) Inner() RequestData { + return r.inner +} + +// NewRequest creates a new request. +func NewRequest(inner RequestData) *Request { + req := new(Request) + req.inner = inner.copy() + return req +} + +// Requests implements DerivableList for requests. +type Requests []*Request + +// Len returns the length of s. +func (s Requests) Len() int { return len(s) } + +// EncodeIndex encodes the i'th request to s. +func (s Requests) EncodeIndex(i int, w *bytes.Buffer) { + s[i].encode(w) +} + +// RequestData is the underlying data of a request. +type RequestData interface { + requestType() byte + encode(*bytes.Buffer) error + decode([]byte) error + copy() RequestData // creates a deep copy and initializes all fields +} + +// EncodeRLP implements rlp.Encoder +func (r *Request) EncodeRLP(w io.Writer) error { + buf := encodeBufferPool.Get().(*bytes.Buffer) + defer encodeBufferPool.Put(buf) + buf.Reset() + if err := r.encode(buf); err != nil { + return err + } + return rlp.Encode(w, buf.Bytes()) +} + +// encode writes the canonical encoding of a request to w. +func (r *Request) encode(w *bytes.Buffer) error { + w.WriteByte(r.Type()) + return r.inner.encode(w) +} + +// MarshalBinary returns the canonical encoding of the request. +func (r *Request) MarshalBinary() ([]byte, error) { + var buf bytes.Buffer + err := r.encode(&buf) + return buf.Bytes(), err +} + +// DecodeRLP implements rlp.Decoder +func (r *Request) DecodeRLP(s *rlp.Stream) error { + kind, size, err := s.Kind() + switch { + case err != nil: + return err + case kind == rlp.List: + return fmt.Errorf("untyped request") + case kind == rlp.Byte: + return errShortTypedRequest + default: + // First read the request payload bytes into a temporary buffer. + b, buf, err := getPooledBuffer(size) + if err != nil { + return err + } + defer encodeBufferPool.Put(buf) + if err := s.ReadBytes(b); err != nil { + return err + } + // Now decode the inner request. + inner, err := r.decode(b) + if err == nil { + r.inner = inner + } + return err + } +} + +// UnmarshalBinary decodes the canonical encoding of requests. +func (r *Request) UnmarshalBinary(b []byte) error { + inner, err := r.decode(b) + if err != nil { + return err + } + r.inner = inner + return nil +} + +// decode decodes a request from the canonical format. +func (r *Request) decode(b []byte) (RequestData, error) { + if len(b) <= 1 { + return nil, errShortTypedRequest + } + var inner RequestData + switch b[0] { + case DepositRequestType: + inner = new(Deposit) + default: + return nil, ErrRequestTypeNotSupported + } + err := inner.decode(b[1:]) + return inner, err +} diff --git a/core/types/transaction.go b/core/types/transaction.go index b91f8b10b8..d04a91e206 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -57,9 +57,9 @@ type Transaction struct { time time.Time // Time first seen locally (spam avoidance) // caches - hash atomic.Value - size atomic.Value - from atomic.Value + hash atomic.Pointer[common.Hash] + size atomic.Uint64 + from atomic.Pointer[sigCache] } // NewTx creates a new transaction. @@ -456,6 +456,26 @@ func (tx *Transaction) WithoutBlobTxSidecar() *Transaction { return cpy } +// WithBlobTxSidecar returns a copy of tx with the blob sidecar added. +func (tx *Transaction) WithBlobTxSidecar(sideCar *BlobTxSidecar) *Transaction { + blobtx, ok := tx.inner.(*BlobTx) + if !ok { + return tx + } + cpy := &Transaction{ + inner: blobtx.withSidecar(sideCar), + time: tx.time, + } + // Note: tx.size cache not carried over because the sidecar is included in size! + if h := tx.hash.Load(); h != nil { + cpy.hash.Store(h) + } + if f := tx.from.Load(); f != nil { + cpy.from.Store(f) + } + return cpy +} + // SetTime sets the decoding time of a transaction. This is used by tests to set // arbitrary times and by persistent transaction pools when loading old txs from // disk. @@ -472,7 +492,7 @@ func (tx *Transaction) Time() time.Time { // Hash returns the transaction hash. func (tx *Transaction) Hash() common.Hash { if hash := tx.hash.Load(); hash != nil { - return hash.(common.Hash) + return *hash } var h common.Hash @@ -481,15 +501,15 @@ func (tx *Transaction) Hash() common.Hash { } else { h = prefixedRlpHash(tx.Type(), tx.inner) } - tx.hash.Store(h) + tx.hash.Store(&h) return h } // Size returns the true encoded storage size of the transaction, either by encoding // and returning it, or returning a previously cached value. func (tx *Transaction) Size() uint64 { - if size := tx.size.Load(); size != nil { - return size.(uint64) + if size := tx.size.Load(); size > 0 { + return size } // Cache miss, encode and cache. @@ -546,11 +566,11 @@ func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) { } } -// TxDifference returns a new set which is the difference between a and b. +// TxDifference returns a new set of transactions that are present in a but not in b. func TxDifference(a, b Transactions) Transactions { keep := make(Transactions, 0, len(a)) - remove := make(map[common.Hash]struct{}) + remove := make(map[common.Hash]struct{}, b.Len()) for _, tx := range b { remove[tx.Hash()] = struct{}{} } @@ -564,7 +584,7 @@ func TxDifference(a, b Transactions) Transactions { return keep } -// HashDifference returns a new set which is the difference between a and b. +// HashDifference returns a new set of hashes that are present in a but not in b. func HashDifference(a, b []common.Hash) []common.Hash { keep := make([]common.Hash, 0, len(a)) diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 9e26642f75..73011e238b 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -64,21 +64,24 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint // Use this in transaction-handling code where the current block number is unknown. If you // have the current block number available, use MakeSigner instead. func LatestSigner(config *params.ChainConfig) Signer { + var signer Signer if config.ChainID != nil { - if config.CancunTime != nil { - return NewCancunSigner(config.ChainID) - } - if config.LondonBlock != nil { - return NewLondonSigner(config.ChainID) - } - if config.BerlinBlock != nil { - return NewEIP2930Signer(config.ChainID) - } - if config.EIP155Block != nil { - return NewEIP155Signer(config.ChainID) + switch { + case config.CancunTime != nil: + signer = NewCancunSigner(config.ChainID) + case config.LondonBlock != nil: + signer = NewLondonSigner(config.ChainID) + case config.BerlinBlock != nil: + signer = NewEIP2930Signer(config.ChainID) + case config.EIP155Block != nil: + signer = NewEIP155Signer(config.ChainID) + default: + signer = HomesteadSigner{} } + } else { + signer = HomesteadSigner{} } - return HomesteadSigner{} + return signer } // LatestSignerForChainID returns the 'most permissive' Signer available. Specifically, @@ -89,10 +92,13 @@ func LatestSigner(config *params.ChainConfig) Signer { // configuration are unknown. If you have a ChainConfig, use LatestSigner instead. // If you have a ChainConfig and know the current block number, use MakeSigner instead. func LatestSignerForChainID(chainID *big.Int) Signer { - if chainID == nil { - return HomesteadSigner{} + var signer Signer + if chainID != nil { + signer = NewCancunSigner(chainID) + } else { + signer = HomesteadSigner{} } - return NewCancunSigner(chainID) + return signer } // SignTx signs the transaction using the given signer and private key. @@ -107,13 +113,7 @@ func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, err // SignNewTx creates a transaction and signs it. func SignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) (*Transaction, error) { - tx := NewTx(txdata) - h := s.Hash(tx) - sig, err := crypto.Sign(h[:], prv) - if err != nil { - return nil, err - } - return tx.WithSignature(s, sig) + return SignTx(NewTx(txdata), s, prv) } // MustSignNewTx creates a transaction and signs it. @@ -134,8 +134,7 @@ func MustSignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) *Transaction // signing method. The cache is invalidated if the cached signer does // not match the signer used in the current call. func Sender(signer Signer, tx *Transaction) (common.Address, error) { - if sc := tx.from.Load(); sc != nil { - sigCache := sc.(sigCache) + if sigCache := tx.from.Load(); sigCache != nil { // If the signer used to derive from in a previous // call is not the same as used current, invalidate // the cache. @@ -148,7 +147,7 @@ func Sender(signer Signer, tx *Transaction) (common.Address, error) { if err != nil { return common.Address{}, err } - tx.from.Store(sigCache{signer: signer, from: addr}) + tx.from.Store(&sigCache{signer: signer, from: addr}) return addr, nil } @@ -466,11 +465,11 @@ func (s EIP155Signer) Hash(tx *Transaction) common.Hash { // homestead rules. type HomesteadSigner struct{ FrontierSigner } -func (s HomesteadSigner) ChainID() *big.Int { +func (hs HomesteadSigner) ChainID() *big.Int { return nil } -func (s HomesteadSigner) Equal(s2 Signer) bool { +func (hs HomesteadSigner) Equal(s2 Signer) bool { _, ok := s2.(HomesteadSigner) return ok } @@ -493,11 +492,11 @@ func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { // frontier rules. type FrontierSigner struct{} -func (s FrontierSigner) ChainID() *big.Int { +func (fs FrontierSigner) ChainID() *big.Int { return nil } -func (s FrontierSigner) Equal(s2 Signer) bool { +func (fs FrontierSigner) Equal(s2 Signer) bool { _, ok := s2.(FrontierSigner) return ok } @@ -579,6 +578,6 @@ func deriveChainId(v *big.Int) *big.Int { } return new(big.Int).SetUint64((v - 35) / 2) } - v = new(big.Int).Sub(v, big.NewInt(35)) - return v.Div(v, big.NewInt(2)) + vCopy := new(big.Int).Sub(v, big.NewInt(35)) + return vCopy.Rsh(vCopy, 1) } diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 76a010d2e5..eed13ee205 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "math/big" "reflect" "testing" @@ -344,6 +345,41 @@ func TestTransactionCoding(t *testing.T) { } } +func TestLegacyTransaction_ConsistentV_LargeChainIds(t *testing.T) { + chainId := new(big.Int).SetUint64(13317435930671861669) + + txdata := &LegacyTx{ + Nonce: 1, + Gas: 1, + GasPrice: big.NewInt(2), + Data: []byte("abcdef"), + } + + key, err := crypto.GenerateKey() + if err != nil { + t.Fatalf("could not generate key: %v", err) + } + + tx, err := SignNewTx(key, NewEIP2930Signer(chainId), txdata) + if err != nil { + t.Fatalf("could not sign transaction: %v", err) + } + + // Make a copy of the initial V value + preV, _, _ := tx.RawSignatureValues() + preV = new(big.Int).Set(preV) + + if tx.ChainId().Cmp(chainId) != 0 { + t.Fatalf("wrong chain id: %v", tx.ChainId()) + } + + v, _, _ := tx.RawSignatureValues() + + if v.Cmp(preV) != 0 { + t.Fatalf("wrong v value: %v", v) + } +} + func encodeDecodeJSON(tx *Transaction) (*Transaction, error) { data, err := json.Marshal(tx) if err != nil { @@ -378,7 +414,7 @@ func assertEqual(orig *Transaction, cpy *Transaction) error { } if orig.AccessList() != nil { if !reflect.DeepEqual(orig.AccessList(), cpy.AccessList()) { - return errors.New("access list wrong!") + return errors.New("access list wrong") } } return nil @@ -515,10 +551,7 @@ func TestYParityJSONUnmarshalling(t *testing.T) { test := test t.Run(fmt.Sprintf("txType=%d: %s", txType, test.name), func(t *testing.T) { // Copy the base json - testJson := make(map[string]interface{}) - for k, v := range baseJson { - testJson[k] = v - } + testJson := maps.Clone(baseJson) // Set v, yParity and type if test.v != "" { diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index 158d76e6f1..435cb8872e 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -191,6 +191,12 @@ func (tx *BlobTx) withoutSidecar() *BlobTx { return &cpy } +func (tx *BlobTx) withSidecar(sideCar *BlobTxSidecar) *BlobTx { + cpy := *tx + cpy.Sidecar = sideCar + return &cpy +} + func (tx *BlobTx) encode(b *bytes.Buffer) error { if tx.Sidecar == nil { return rlp.Encode(b, tx) diff --git a/core/types/tx_blob_test.go b/core/types/tx_blob_test.go index c7fe3dc321..975e685f04 100644 --- a/core/types/tx_blob_test.go +++ b/core/types/tx_blob_test.go @@ -63,7 +63,7 @@ func TestBlobTxSize(t *testing.T) { } var ( - emptyBlob = kzg4844.Blob{} + emptyBlob = new(kzg4844.Blob) emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) ) @@ -76,7 +76,7 @@ func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction { func createEmptyBlobTxInner(withSidecar bool) *BlobTx { sidecar := &BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: []kzg4844.Blob{*emptyBlob}, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, } diff --git a/core/types/withdrawal.go b/core/types/withdrawal.go index d1ad918f98..6f99e53b56 100644 --- a/core/types/withdrawal.go +++ b/core/types/withdrawal.go @@ -18,6 +18,7 @@ package types import ( "bytes" + "reflect" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -48,6 +49,12 @@ type Withdrawals []*Withdrawal // Len returns the length of s. func (s Withdrawals) Len() int { return len(s) } +var withdrawalSize = int(reflect.TypeOf(Withdrawal{}).Size()) + +func (s Withdrawals) Size() int { + return withdrawalSize * len(s) +} + // EncodeIndex encodes the i'th withdrawal to w. Note that this does not check for errors // because we assume that *Withdrawal will only ever contain valid withdrawals that were either // constructed by decoding or via public API in this package. diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go index 398861f8ae..471d2b4ffb 100644 --- a/core/vm/analysis_test.go +++ b/core/vm/analysis_test.go @@ -93,9 +93,7 @@ func BenchmarkJumpdestOpAnalysis(bench *testing.B) { bits := make(bitvec, len(code)/8+1+4) b.ResetTimer() for i := 0; i < b.N; i++ { - for j := range bits { - bits[j] = 0 - } + clear(bits) codeBitmapInternal(code, bits) } } diff --git a/core/vm/common.go b/core/vm/common.go index 90ba4a4ad1..ba75950e37 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -63,6 +63,18 @@ func getData(data []byte, start uint64, size uint64) []byte { return common.RightPadBytes(data[start:end], int(size)) } +func getDataAndAdjustedBounds(data []byte, start uint64, size uint64) (codeCopyPadded []byte, actualStart uint64, sizeNonPadded uint64) { + length := uint64(len(data)) + if start > length { + start = length + } + end := start + size + if end > length { + end = length + } + return common.RightPadBytes(data[start:end], int(size)), start, end - start +} + // toWordSize returns the ceiled word size required for memory expansion. func toWordSize(size uint64) uint64 { if size > math.MaxUint64-31 { diff --git a/core/vm/contract.go b/core/vm/contract.go index eab3a17447..525a605df4 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -18,6 +18,7 @@ package vm import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/metrics" lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" @@ -67,6 +68,9 @@ type Contract struct { CodeAddr *common.Address Input []byte + // is the execution frame represented by this object a contract deployment + IsDeployment bool + Gas uint64 value *uint256.Int } @@ -175,14 +179,28 @@ func (c *Contract) Caller() common.Address { } // UseGas attempts the use gas and subtracts it and returns true on success -func (c *Contract) UseGas(gas uint64) (ok bool) { +func (c *Contract) UseGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) (ok bool) { if c.Gas < gas { return false } + if logger != nil && logger.OnGasChange != nil && reason != tracing.GasChangeIgnored { + logger.OnGasChange(c.Gas, c.Gas-gas, reason) + } c.Gas -= gas return true } +// RefundGas refunds gas to the contract +func (c *Contract) RefundGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) { + if gas == 0 { + return + } + if logger != nil && logger.OnGasChange != nil && reason != tracing.GasChangeIgnored { + logger.OnGasChange(c.Gas, c.Gas+gas, reason) + } + c.Gas += gas +} + // Address returns the contracts address func (c *Contract) Address() common.Address { return c.self.Address() diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 38a6cac24d..4ba8c6feb0 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -22,17 +22,22 @@ import ( "encoding/binary" "errors" "fmt" + "maps" "math/big" "github.com/prysmaticlabs/prysm/v5/crypto/bls" "golang.org/x/crypto/ripemd160" + "github.com/consensys/gnark-crypto/ecc" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" - "github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bn256" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/secp256k1" @@ -50,31 +55,34 @@ type PrecompiledContract interface { Run(input []byte) ([]byte, error) // Run runs the precompiled contract } +// PrecompiledContracts contains the precompiled contracts supported at the given fork. +type PrecompiledContracts map[common.Address]PrecompiledContract + // PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum // contracts used in the Frontier and Homestead releases. -var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, +var PrecompiledContractsHomestead = PrecompiledContracts{ + common.BytesToAddress([]byte{0x1}): &ecrecover{}, + common.BytesToAddress([]byte{0x2}): &sha256hash{}, + common.BytesToAddress([]byte{0x3}): &ripemd160hash{}, + common.BytesToAddress([]byte{0x4}): &dataCopy{}, } // PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum // contracts used in the Byzantium release. -var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, - common.BytesToAddress([]byte{6}): &bn256AddByzantium{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{}, - common.BytesToAddress([]byte{8}): &bn256PairingByzantium{}, +var PrecompiledContractsByzantium = PrecompiledContracts{ + common.BytesToAddress([]byte{0x1}): &ecrecover{}, + common.BytesToAddress([]byte{0x2}): &sha256hash{}, + common.BytesToAddress([]byte{0x3}): &ripemd160hash{}, + common.BytesToAddress([]byte{0x4}): &dataCopy{}, + common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false}, + common.BytesToAddress([]byte{0x6}): &bn256AddByzantium{}, + common.BytesToAddress([]byte{0x7}): &bn256ScalarMulByzantium{}, + common.BytesToAddress([]byte{0x8}): &bn256PairingByzantium{}, } // PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum // contracts used in the Istanbul release. -var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ +var PrecompiledContractsIstanbul = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -89,7 +97,7 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{101}): &iavlMerkleProofValidate{}, } -var PrecompiledContractsNano = map[common.Address]PrecompiledContract{ +var PrecompiledContractsNano = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -104,7 +112,7 @@ var PrecompiledContractsNano = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{101}): &iavlMerkleProofValidateNano{}, } -var PrecompiledContractsMoran = map[common.Address]PrecompiledContract{ +var PrecompiledContractsMoran = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -119,7 +127,7 @@ var PrecompiledContractsMoran = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{101}): &iavlMerkleProofValidateMoran{}, } -var PrecompiledContractsPlanck = map[common.Address]PrecompiledContract{ +var PrecompiledContractsPlanck = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -136,7 +144,7 @@ var PrecompiledContractsPlanck = map[common.Address]PrecompiledContract{ // PrecompiledContractsLuban contains the default set of pre-compiled Ethereum // contracts used in the Luban release. -var PrecompiledContractsLuban = map[common.Address]PrecompiledContract{ +var PrecompiledContractsLuban = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -155,7 +163,7 @@ var PrecompiledContractsLuban = map[common.Address]PrecompiledContract{ // PrecompiledContractsPlato contains the default set of pre-compiled Ethereum // contracts used in the Plato release. -var PrecompiledContractsPlato = map[common.Address]PrecompiledContract{ +var PrecompiledContractsPlato = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -174,21 +182,21 @@ var PrecompiledContractsPlato = map[common.Address]PrecompiledContract{ // PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum // contracts used in the Berlin release. -var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, - common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - common.BytesToAddress([]byte{9}): &blake2F{}, +var PrecompiledContractsBerlin = PrecompiledContracts{ + common.BytesToAddress([]byte{0x1}): &ecrecover{}, + common.BytesToAddress([]byte{0x2}): &sha256hash{}, + common.BytesToAddress([]byte{0x3}): &ripemd160hash{}, + common.BytesToAddress([]byte{0x4}): &dataCopy{}, + common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{0x9}): &blake2F{}, } // PrecompiledContractsHertz contains the default set of pre-compiled Ethereum // contracts used in the Hertz release. -var PrecompiledContractsHertz = map[common.Address]PrecompiledContract{ +var PrecompiledContractsHertz = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -207,7 +215,7 @@ var PrecompiledContractsHertz = map[common.Address]PrecompiledContract{ // PrecompiledContractsFeynman contains the default set of pre-compiled Ethereum // contracts used in the Feynman release. -var PrecompiledContractsFeynman = map[common.Address]PrecompiledContract{ +var PrecompiledContractsFeynman = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -228,7 +236,7 @@ var PrecompiledContractsFeynman = map[common.Address]PrecompiledContract{ // PrecompiledContractsCancun contains the default set of pre-compiled Ethereum // contracts used in the Cancun release. -var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ +var PrecompiledContractsCancun = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -250,7 +258,7 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ // PrecompiledContractsHaber contains the default set of pre-compiled Ethereum // contracts used in the Haber release. -var PrecompiledContractsHaber = map[common.Address]PrecompiledContract{ +var PrecompiledContractsHaber = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, @@ -274,25 +282,49 @@ var PrecompiledContractsHaber = map[common.Address]PrecompiledContract{ // PrecompiledContractsP256Verify contains the precompiled Ethereum // contract specified in EIP-7212. This is exported for testing purposes. -var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{ +var PrecompiledContractsP256Verify = PrecompiledContracts{ common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, } -// PrecompiledContractsBLS contains the set of pre-compiled Ethereum -// contracts specified in EIP-2537. These are exported for testing purposes. -var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{10}): &bls12381G1Add{}, - common.BytesToAddress([]byte{11}): &bls12381G1Mul{}, - common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{}, - common.BytesToAddress([]byte{13}): &bls12381G2Add{}, - common.BytesToAddress([]byte{14}): &bls12381G2Mul{}, - common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{}, - common.BytesToAddress([]byte{16}): &bls12381Pairing{}, - common.BytesToAddress([]byte{17}): &bls12381MapG1{}, - common.BytesToAddress([]byte{18}): &bls12381MapG2{}, +// PrecompiledContractsPrague contains the set of pre-compiled Ethereum +// contracts used in the Prague release. +var PrecompiledContractsPrague = PrecompiledContracts{ + common.BytesToAddress([]byte{0x01}): &ecrecover{}, + common.BytesToAddress([]byte{0x02}): &sha256hash{}, + common.BytesToAddress([]byte{0x03}): &ripemd160hash{}, + common.BytesToAddress([]byte{0x04}): &dataCopy{}, + common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{0x09}): &blake2F{}, + common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{}, + common.BytesToAddress([]byte{0x0c}): &bls12381G1Mul{}, + common.BytesToAddress([]byte{0x0d}): &bls12381G1MultiExp{}, + common.BytesToAddress([]byte{0x0e}): &bls12381G2Add{}, + common.BytesToAddress([]byte{0x0f}): &bls12381G2Mul{}, + common.BytesToAddress([]byte{0x10}): &bls12381G2MultiExp{}, + common.BytesToAddress([]byte{0x11}): &bls12381Pairing{}, + common.BytesToAddress([]byte{0x12}): &bls12381MapG1{}, + common.BytesToAddress([]byte{0x13}): &bls12381MapG2{}, + + common.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, + common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidateHertz{}, + common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{}, + common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{}, + + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, } +var PrecompiledContractsBLS = PrecompiledContractsPrague + +var PrecompiledContractsVerkle = PrecompiledContractsPrague + var ( + PrecompiledAddressesPrague []common.Address PrecompiledAddressesHaber []common.Address PrecompiledAddressesCancun []common.Address PrecompiledAddressesFeynman []common.Address @@ -348,11 +380,56 @@ func init() { for k := range PrecompiledContractsHaber { PrecompiledAddressesHaber = append(PrecompiledAddressesHaber, k) } + for k := range PrecompiledContractsPrague { + PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k) + } +} + +func activePrecompiledContracts(rules params.Rules) PrecompiledContracts { + switch { + case rules.IsVerkle: + return PrecompiledContractsVerkle + case rules.IsPrague: + return PrecompiledContractsPrague + case rules.IsHaber: + return PrecompiledContractsHaber + case rules.IsCancun: + return PrecompiledContractsCancun + case rules.IsFeynman: + return PrecompiledContractsFeynman + case rules.IsHertz: + return PrecompiledContractsHertz + case rules.IsBerlin: + return PrecompiledContractsBerlin + case rules.IsPlato: + return PrecompiledContractsPlato + case rules.IsLuban: + return PrecompiledContractsLuban + case rules.IsPlanck: + return PrecompiledContractsPlanck + case rules.IsMoran: + return PrecompiledContractsMoran + case rules.IsNano: + return PrecompiledContractsNano + case rules.IsIstanbul: + return PrecompiledContractsIstanbul + case rules.IsByzantium: + return PrecompiledContractsByzantium + default: + return PrecompiledContractsHomestead + } +} + +// ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration. +func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts { + return maps.Clone(activePrecompiledContracts(rules)) } -// ActivePrecompiles returns the precompiles enabled with the current configuration. +// ActivePrecompiles returns the precompile addresses enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsPrague: + return PrecompiledAddressesPrague case rules.IsHaber: return PrecompiledAddressesHaber case rules.IsCancun: @@ -387,17 +464,20 @@ func ActivePrecompiles(rules params.Rules) []common.Address { // - the returned bytes, // - the _remaining_ gas, // - any error that occurred -func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error) { +func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.Hooks) (ret []byte, remainingGas uint64, err error) { gasCost := p.RequiredGas(input) if suppliedGas < gasCost { return nil, 0, ErrOutOfGas } + if logger != nil && logger.OnGasChange != nil { + logger.OnGasChange(suppliedGas, suppliedGas-gasCost, tracing.GasChangeCallPrecompiledContract) + } suppliedGas -= gasCost output, err := p.Run(input) return output, suppliedGas, err } -// ECRECOVER implemented as a native contract. +// ecrecover implemented as a native contract. type ecrecover struct{} func (c *ecrecover) RequiredGas(input []byte) uint64 { @@ -491,10 +571,7 @@ type bigModExp struct { var ( big1 = big.NewInt(1) big3 = big.NewInt(3) - big4 = big.NewInt(4) big7 = big.NewInt(7) - big8 = big.NewInt(8) - big16 = big.NewInt(16) big20 = big.NewInt(20) big32 = big.NewInt(32) big64 = big.NewInt(64) @@ -520,13 +597,13 @@ func modexpMultComplexity(x *big.Int) *big.Int { case x.Cmp(big1024) <= 0: // (x ** 2 // 4 ) + ( 96 * x - 3072) x = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(x, x), big4), + new(big.Int).Rsh(new(big.Int).Mul(x, x), 2), new(big.Int).Sub(new(big.Int).Mul(big96, x), big3072), ) default: // (x ** 2 // 16) + (480 * x - 199680) x = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(x, x), big16), + new(big.Int).Rsh(new(big.Int).Mul(x, x), 4), new(big.Int).Sub(new(big.Int).Mul(big480, x), big199680), ) } @@ -564,7 +641,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { adjExpLen := new(big.Int) if expLen.Cmp(big32) > 0 { adjExpLen.Sub(expLen, big32) - adjExpLen.Mul(big8, adjExpLen) + adjExpLen.Lsh(adjExpLen, 3) } adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) // Calculate the gas cost of the operation @@ -577,9 +654,9 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { // def mult_complexity(x): // ceiling(x/8)^2 // - // where is x is max(length_of_MODULUS, length_of_BASE) - gas = gas.Add(gas, big7) - gas = gas.Div(gas, big8) + //where is x is max(length_of_MODULUS, length_of_BASE) + gas.Add(gas, big7) + gas.Rsh(gas, 3) gas.Mul(gas, gas) gas.Mul(gas, math.BigMax(adjExpLen, big1)) @@ -675,7 +752,7 @@ func runBn256Add(input []byte) ([]byte, error) { return res.Marshal(), nil } -// bn256Add implements a native elliptic curve point addition conforming to +// bn256AddIstanbul implements a native elliptic curve point addition conforming to // Istanbul consensus rules. type bn256AddIstanbul struct{} @@ -891,26 +968,24 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) { return nil, errBLS12381InvalidInputLength } var err error - var p0, p1 *bls12381.PointG1 - - // Initialize G1 - g := bls12381.NewG1() + var p0, p1 *bls12381.G1Affine // Decode G1 point p_0 - if p0, err = g.DecodePoint(input[:128]); err != nil { + if p0, err = decodePointG1(input[:128]); err != nil { return nil, err } // Decode G1 point p_1 - if p1, err = g.DecodePoint(input[128:]); err != nil { + if p1, err = decodePointG1(input[128:]); err != nil { return nil, err } + // No need to check the subgroup here, as specified by EIP-2537 + // Compute r = p_0 + p_1 - r := g.New() - g.Add(r, p0, p1) + p0.Add(p0, p1) // Encode the G1 point result into 128 bytes - return g.EncodePoint(r), nil + return encodePointG1(p0), nil } // bls12381G1Mul implements EIP-2537 G1Mul precompile. @@ -929,24 +1004,26 @@ func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) { return nil, errBLS12381InvalidInputLength } var err error - var p0 *bls12381.PointG1 - - // Initialize G1 - g := bls12381.NewG1() + var p0 *bls12381.G1Affine // Decode G1 point - if p0, err = g.DecodePoint(input[:128]); err != nil { + if p0, err = decodePointG1(input[:128]); err != nil { return nil, err } + // 'point is on curve' check already done, + // Here we need to apply subgroup checks. + if !p0.IsInSubGroup() { + return nil, errBLS12381G1PointSubgroup + } // Decode scalar value e := new(big.Int).SetBytes(input[128:]) // Compute r = e * p_0 - r := g.New() - g.MulScalar(r, p0, e) + r := new(bls12381.G1Affine) + r.ScalarMultiplication(p0, e) // Encode the G1 point into 128 bytes - return g.EncodePoint(r), nil + return encodePointG1(r), nil } // bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. @@ -979,31 +1056,34 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) { if len(input) == 0 || len(input)%160 != 0 { return nil, errBLS12381InvalidInputLength } - var err error - points := make([]*bls12381.PointG1, k) - scalars := make([]*big.Int, k) - - // Initialize G1 - g := bls12381.NewG1() + points := make([]bls12381.G1Affine, k) + scalars := make([]fr.Element, k) // Decode point scalar pairs for i := 0; i < k; i++ { off := 160 * i t0, t1, t2 := off, off+128, off+160 // Decode G1 point - if points[i], err = g.DecodePoint(input[t0:t1]); err != nil { + p, err := decodePointG1(input[t0:t1]) + if err != nil { return nil, err } + // 'point is on curve' check already done, + // Here we need to apply subgroup checks. + if !p.IsInSubGroup() { + return nil, errBLS12381G1PointSubgroup + } + points[i] = *p // Decode scalar value - scalars[i] = new(big.Int).SetBytes(input[t1:t2]) + scalars[i] = *new(fr.Element).SetBytes(input[t1:t2]) } // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) - r := g.New() - g.MultiExp(r, points, scalars) + r := new(bls12381.G1Affine) + r.MultiExp(points, scalars, ecc.MultiExpConfig{}) // Encode the G1 point to 128 bytes - return g.EncodePoint(r), nil + return encodePointG1(r), nil } // bls12381G2Add implements EIP-2537 G2Add precompile. @@ -1022,26 +1102,25 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) { return nil, errBLS12381InvalidInputLength } var err error - var p0, p1 *bls12381.PointG2 - - // Initialize G2 - g := bls12381.NewG2() - r := g.New() + var p0, p1 *bls12381.G2Affine // Decode G2 point p_0 - if p0, err = g.DecodePoint(input[:256]); err != nil { + if p0, err = decodePointG2(input[:256]); err != nil { return nil, err } // Decode G2 point p_1 - if p1, err = g.DecodePoint(input[256:]); err != nil { + if p1, err = decodePointG2(input[256:]); err != nil { return nil, err } + // No need to check the subgroup here, as specified by EIP-2537 + // Compute r = p_0 + p_1 - g.Add(r, p0, p1) + r := new(bls12381.G2Affine) + r.Add(p0, p1) // Encode the G2 point into 256 bytes - return g.EncodePoint(r), nil + return encodePointG2(r), nil } // bls12381G2Mul implements EIP-2537 G2Mul precompile. @@ -1060,24 +1139,26 @@ func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) { return nil, errBLS12381InvalidInputLength } var err error - var p0 *bls12381.PointG2 - - // Initialize G2 - g := bls12381.NewG2() + var p0 *bls12381.G2Affine // Decode G2 point - if p0, err = g.DecodePoint(input[:256]); err != nil { + if p0, err = decodePointG2(input[:256]); err != nil { return nil, err } + // 'point is on curve' check already done, + // Here we need to apply subgroup checks. + if !p0.IsInSubGroup() { + return nil, errBLS12381G2PointSubgroup + } // Decode scalar value e := new(big.Int).SetBytes(input[256:]) // Compute r = e * p_0 - r := g.New() - g.MulScalar(r, p0, e) + r := new(bls12381.G2Affine) + r.ScalarMultiplication(p0, e) // Encode the G2 point into 256 bytes - return g.EncodePoint(r), nil + return encodePointG2(r), nil } // bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. @@ -1110,31 +1191,34 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) { if len(input) == 0 || len(input)%288 != 0 { return nil, errBLS12381InvalidInputLength } - var err error - points := make([]*bls12381.PointG2, k) - scalars := make([]*big.Int, k) - - // Initialize G2 - g := bls12381.NewG2() + points := make([]bls12381.G2Affine, k) + scalars := make([]fr.Element, k) // Decode point scalar pairs for i := 0; i < k; i++ { off := 288 * i t0, t1, t2 := off, off+256, off+288 - // Decode G1 point - if points[i], err = g.DecodePoint(input[t0:t1]); err != nil { + // Decode G2 point + p, err := decodePointG2(input[t0:t1]) + if err != nil { return nil, err } + // 'point is on curve' check already done, + // Here we need to apply subgroup checks. + if !p.IsInSubGroup() { + return nil, errBLS12381G2PointSubgroup + } + points[i] = *p // Decode scalar value - scalars[i] = new(big.Int).SetBytes(input[t1:t2]) + scalars[i] = *new(fr.Element).SetBytes(input[t1:t2]) } // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) - r := g.New() - g.MultiExp(r, points, scalars) + r := new(bls12381.G2Affine) + r.MultiExp(points, scalars, ecc.MultiExpConfig{}) // Encode the G2 point to 256 bytes. - return g.EncodePoint(r), nil + return encodePointG2(r), nil } // bls12381Pairing implements EIP-2537 Pairing precompile. @@ -1157,9 +1241,10 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { return nil, errBLS12381InvalidInputLength } - // Initialize BLS12-381 pairing engine - e := bls12381.NewPairingEngine() - g1, g2 := e.G1, e.G2 + var ( + p []bls12381.G1Affine + q []bls12381.G2Affine + ) // Decode pairs for i := 0; i < k; i++ { @@ -1167,53 +1252,125 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { t0, t1, t2 := off, off+128, off+384 // Decode G1 point - p1, err := g1.DecodePoint(input[t0:t1]) + p1, err := decodePointG1(input[t0:t1]) if err != nil { return nil, err } // Decode G2 point - p2, err := g2.DecodePoint(input[t1:t2]) + p2, err := decodePointG2(input[t1:t2]) if err != nil { return nil, err } // 'point is on curve' check already done, // Here we need to apply subgroup checks. - if !g1.InCorrectSubgroup(p1) { + if !p1.IsInSubGroup() { return nil, errBLS12381G1PointSubgroup } - if !g2.InCorrectSubgroup(p2) { + if !p2.IsInSubGroup() { return nil, errBLS12381G2PointSubgroup } - - // Update pairing engine with G1 and G2 points - e.AddPair(p1, p2) + p = append(p, *p1) + q = append(q, *p2) } // Prepare 32 byte output out := make([]byte, 32) // Compute pairing and set the result - if e.Check() { + ok, err := bls12381.PairingCheck(p, q) + if err == nil && ok { out[31] = 1 } return out, nil } +func decodePointG1(in []byte) (*bls12381.G1Affine, error) { + if len(in) != 128 { + return nil, errors.New("invalid g1 point length") + } + // decode x + x, err := decodeBLS12381FieldElement(in[:64]) + if err != nil { + return nil, err + } + // decode y + y, err := decodeBLS12381FieldElement(in[64:]) + if err != nil { + return nil, err + } + elem := bls12381.G1Affine{X: x, Y: y} + if !elem.IsOnCurve() { + return nil, errors.New("invalid point: not on curve") + } + + return &elem, nil +} + +// decodePointG2 given encoded (x, y) coordinates in 256 bytes returns a valid G2 Point. +func decodePointG2(in []byte) (*bls12381.G2Affine, error) { + if len(in) != 256 { + return nil, errors.New("invalid g2 point length") + } + x0, err := decodeBLS12381FieldElement(in[:64]) + if err != nil { + return nil, err + } + x1, err := decodeBLS12381FieldElement(in[64:128]) + if err != nil { + return nil, err + } + y0, err := decodeBLS12381FieldElement(in[128:192]) + if err != nil { + return nil, err + } + y1, err := decodeBLS12381FieldElement(in[192:]) + if err != nil { + return nil, err + } + + p := bls12381.G2Affine{X: bls12381.E2{A0: x0, A1: x1}, Y: bls12381.E2{A0: y0, A1: y1}} + if !p.IsOnCurve() { + return nil, errors.New("invalid point: not on curve") + } + return &p, err +} + // decodeBLS12381FieldElement decodes BLS12-381 elliptic curve field element. // Removes top 16 bytes of 64 byte input. -func decodeBLS12381FieldElement(in []byte) ([]byte, error) { +func decodeBLS12381FieldElement(in []byte) (fp.Element, error) { if len(in) != 64 { - return nil, errors.New("invalid field element length") + return fp.Element{}, errors.New("invalid field element length") } // check top bytes for i := 0; i < 16; i++ { if in[i] != byte(0x00) { - return nil, errBLS12381InvalidFieldElementTopBytes + return fp.Element{}, errBLS12381InvalidFieldElementTopBytes } } - out := make([]byte, 48) - copy(out[:], in[16:]) - return out, nil + var res [48]byte + copy(res[:], in[16:]) + + return fp.BigEndian.Element(&res) +} + +// encodePointG1 encodes a point into 128 bytes. +func encodePointG1(p *bls12381.G1Affine) []byte { + out := make([]byte, 128) + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[16:]), p.X) + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[64+16:]), p.Y) + return out +} + +// encodePointG2 encodes a point into 256 bytes. +func encodePointG2(p *bls12381.G2Affine) []byte { + out := make([]byte, 256) + // encode x + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[16:16+48]), p.X.A0) + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[80:80+48]), p.X.A1) + // encode y + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[144:144+48]), p.Y.A0) + fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[208:208+48]), p.Y.A1) + return out } // bls12381MapG1 implements EIP-2537 MapG1 precompile. @@ -1226,7 +1383,7 @@ func (c *bls12381MapG1) RequiredGas(input []byte) uint64 { func (c *bls12381MapG1) Run(input []byte) ([]byte, error) { // Implements EIP-2537 Map_To_G1 precompile. - // > Field-to-curve call expects `64` bytes an an input that is interpreted as a an element of the base field. + // > Field-to-curve call expects an `64` bytes input that is interpreted as an element of the base field. // > Output of this call is `128` bytes and is G1 point following respective encoding rules. if len(input) != 64 { return nil, errBLS12381InvalidInputLength @@ -1238,17 +1395,11 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) { return nil, err } - // Initialize G1 - g := bls12381.NewG1() - // Compute mapping - r, err := g.MapToCurve(fe) - if err != nil { - return nil, err - } + r := bls12381.MapToG1(fe) // Encode the G1 point to 128 bytes - return g.EncodePoint(r), nil + return encodePointG1(&r), nil } // bls12381MapG2 implements EIP-2537 MapG2 precompile. @@ -1261,36 +1412,27 @@ func (c *bls12381MapG2) RequiredGas(input []byte) uint64 { func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { // Implements EIP-2537 Map_FP2_TO_G2 precompile logic. - // > Field-to-curve call expects `128` bytes an an input that is interpreted as a an element of the quadratic extension field. + // > Field-to-curve call expects an `128` bytes input that is interpreted as an element of the quadratic extension field. // > Output of this call is `256` bytes and is G2 point following respective encoding rules. if len(input) != 128 { return nil, errBLS12381InvalidInputLength } // Decode input field element - fe := make([]byte, 96) c0, err := decodeBLS12381FieldElement(input[:64]) if err != nil { return nil, err } - copy(fe[48:], c0) c1, err := decodeBLS12381FieldElement(input[64:]) if err != nil { return nil, err } - copy(fe[:48], c1) - - // Initialize G2 - g := bls12381.NewG2() // Compute mapping - r, err := g.MapToCurve(fe) - if err != nil { - return nil, err - } + r := bls12381.MapToG2(bls12381.E2{A0: c0, A1: c1}) // Encode the G2 point to 256 bytes - return g.EncodePoint(r), nil + return encodePointG2(&r), nil } // blsSignatureVerify implements bls signature verification precompile. diff --git a/core/vm/contracts_fuzz_test.go b/core/vm/contracts_fuzz_test.go index 87c1fff7cc..1e5cc80074 100644 --- a/core/vm/contracts_fuzz_test.go +++ b/core/vm/contracts_fuzz_test.go @@ -36,7 +36,7 @@ func FuzzPrecompiledContracts(f *testing.F) { return } inWant := string(input) - RunPrecompiledContract(p, input, gas) + RunPrecompiledContract(p, input, gas, nil) if inHave := string(input); inWant != inHave { t.Errorf("Precompiled %v modified input data", a) } diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 1a9314a59f..b48970caf0 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -101,7 +101,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) { in := common.Hex2Bytes(test.Input) gas := p.RequiredGas(in) t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) { - if res, _, err := RunPrecompiledContract(p, in, gas); err != nil { + if res, _, err := RunPrecompiledContract(p, in, gas, nil); err != nil { t.Error(err) } else if common.Bytes2Hex(res) != test.Expected { t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res)) @@ -123,7 +123,7 @@ func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) { gas := p.RequiredGas(in) - 1 t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) { - _, _, err := RunPrecompiledContract(p, in, gas) + _, _, err := RunPrecompiledContract(p, in, gas, nil) if err.Error() != "out of gas" { t.Errorf("Expected error [out of gas], got [%v]", err) } @@ -140,7 +140,7 @@ func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing in := common.Hex2Bytes(test.Input) gas := p.RequiredGas(in) t.Run(test.Name, func(t *testing.T) { - _, _, err := RunPrecompiledContract(p, in, gas) + _, _, err := RunPrecompiledContract(p, in, gas, nil) if err.Error() != test.ExpectedError { t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err) } @@ -172,7 +172,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { bench.ResetTimer() for i := 0; i < bench.N; i++ { copy(data, in) - res, _, err = RunPrecompiledContract(p, data, reqGas) + res, _, err = RunPrecompiledContract(p, data, reqGas, nil) } bench.StopTimer() elapsed := uint64(time.Since(start)) @@ -329,6 +329,8 @@ func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f12 func TestPrecompiledPointEvaluation(t *testing.T) { testJson("pointEvaluation", "0a", t) } +func BenchmarkPrecompiledPointEvaluation(b *testing.B) { benchJson("pointEvaluation", "0a", b) } + func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "f0a", b) } func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "f0b", b) } func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "f0c", b) } @@ -385,7 +387,7 @@ func BenchmarkPrecompiledBLS12381G1MultiExpWorstCase(b *testing.B) { Name: "WorstCaseG1", NoBenchmark: false, } - benchmarkPrecompiled("0c", testcase, b) + benchmarkPrecompiled("f0c", testcase, b) } // BenchmarkPrecompiledBLS12381G2MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas. @@ -406,7 +408,7 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { Name: "WorstCaseG2", NoBenchmark: false, } - benchmarkPrecompiled("0f", testcase, b) + benchmarkPrecompiled("f0f", testcase, b) } // Benchmarks the sample inputs from the P256VERIFY precompile. diff --git a/core/vm/eips.go b/core/vm/eips.go index 9f06b2818f..edd6ec8d0a 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -18,9 +18,11 @@ package vm import ( "fmt" + "math" "sort" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) @@ -37,6 +39,7 @@ var activators = map[int]func(*JumpTable){ 1884: enable1884, 1344: enable1344, 1153: enable1153, + 4762: enable4762, } // EnableEIP enables the given EIP on the config. @@ -319,3 +322,214 @@ func enable6780(jt *JumpTable) { maxStack: maxStack(1, 0), } } + +func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + var ( + stack = scope.Stack + a = stack.pop() + memOffset = stack.pop() + codeOffset = stack.pop() + length = stack.pop() + ) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = math.MaxUint64 + } + addr := common.Address(a.Bytes20()) + code := interpreter.evm.StateDB.GetCode(addr) + contract := &Contract{ + Code: code, + self: AccountRef(addr), + } + paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64()) + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { + scope.Contract.Gas = 0 + return nil, ErrOutOfGas + } + scope.Memory.Set(memOffset.Uint64(), length.Uint64(), paddedCodeCopy) + + return nil, nil +} + +// opPush1EIP4762 handles the special case of PUSH1 opcode for EIP-4762, which +// need not worry about the adjusted bound logic when adding the PUSHDATA to +// the list of access events. +func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + var ( + codeLen = uint64(len(scope.Contract.Code)) + integer = new(uint256.Int) + ) + *pc += 1 + if *pc < codeLen { + scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) + + if !scope.Contract.IsDeployment && *pc%31 == 0 { + // touch next chunk if PUSH1 is at the boundary. if so, *pc has + // advanced past this boundary. + contractAddr := scope.Contract.Address() + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false) + if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { + scope.Contract.Gas = 0 + return nil, ErrOutOfGas + } + } + } else { + scope.Stack.push(integer.Clear()) + } + return nil, nil +} + +func makePushEIP4762(size uint64, pushByteSize int) executionFunc { + return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + var ( + codeLen = len(scope.Contract.Code) + start = min(codeLen, int(*pc+1)) + end = min(codeLen, start+pushByteSize) + ) + scope.Stack.push(new(uint256.Int).SetBytes( + common.RightPadBytes( + scope.Contract.Code[start:end], + pushByteSize, + )), + ) + + if !scope.Contract.IsDeployment { + contractAddr := scope.Contract.Address() + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false) + if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { + scope.Contract.Gas = 0 + return nil, ErrOutOfGas + } + } + + *pc += size + return nil, nil + } +} + +func enable4762(jt *JumpTable) { + jt[SSTORE] = &operation{ + dynamicGas: gasSStore4762, + execute: opSstore, + minStack: minStack(2, 0), + maxStack: maxStack(2, 0), + } + jt[SLOAD] = &operation{ + dynamicGas: gasSLoad4762, + execute: opSload, + minStack: minStack(1, 1), + maxStack: maxStack(1, 1), + } + + jt[BALANCE] = &operation{ + execute: opBalance, + dynamicGas: gasBalance4762, + minStack: minStack(1, 1), + maxStack: maxStack(1, 1), + } + + jt[EXTCODESIZE] = &operation{ + execute: opExtCodeSize, + dynamicGas: gasExtCodeSize4762, + minStack: minStack(1, 1), + maxStack: maxStack(1, 1), + } + + jt[EXTCODEHASH] = &operation{ + execute: opExtCodeHash, + dynamicGas: gasExtCodeHash4762, + minStack: minStack(1, 1), + maxStack: maxStack(1, 1), + } + + jt[EXTCODECOPY] = &operation{ + execute: opExtCodeCopyEIP4762, + dynamicGas: gasExtCodeCopyEIP4762, + minStack: minStack(4, 0), + maxStack: maxStack(4, 0), + memorySize: memoryExtCodeCopy, + } + + jt[CODECOPY] = &operation{ + execute: opCodeCopy, + constantGas: GasFastestStep, + dynamicGas: gasCodeCopyEip4762, + minStack: minStack(3, 0), + maxStack: maxStack(3, 0), + memorySize: memoryCodeCopy, + } + + jt[SELFDESTRUCT] = &operation{ + execute: opSelfdestruct6780, + dynamicGas: gasSelfdestructEIP4762, + constantGas: params.SelfdestructGasEIP150, + minStack: minStack(1, 0), + maxStack: maxStack(1, 0), + } + + jt[CREATE] = &operation{ + execute: opCreate, + constantGas: params.CreateNGasEip4762, + dynamicGas: gasCreateEip3860, + minStack: minStack(3, 1), + maxStack: maxStack(3, 1), + memorySize: memoryCreate, + } + + jt[CREATE2] = &operation{ + execute: opCreate2, + constantGas: params.CreateNGasEip4762, + dynamicGas: gasCreate2Eip3860, + minStack: minStack(4, 1), + maxStack: maxStack(4, 1), + memorySize: memoryCreate2, + } + + jt[CALL] = &operation{ + execute: opCall, + dynamicGas: gasCallEIP4762, + minStack: minStack(7, 1), + maxStack: maxStack(7, 1), + memorySize: memoryCall, + } + + jt[CALLCODE] = &operation{ + execute: opCallCode, + dynamicGas: gasCallCodeEIP4762, + minStack: minStack(7, 1), + maxStack: maxStack(7, 1), + memorySize: memoryCall, + } + + jt[STATICCALL] = &operation{ + execute: opStaticCall, + dynamicGas: gasStaticCallEIP4762, + minStack: minStack(6, 1), + maxStack: maxStack(6, 1), + memorySize: memoryStaticCall, + } + + jt[DELEGATECALL] = &operation{ + execute: opDelegateCall, + dynamicGas: gasDelegateCallEIP4762, + minStack: minStack(6, 1), + maxStack: maxStack(6, 1), + memorySize: memoryDelegateCall, + } + + jt[PUSH1] = &operation{ + execute: opPush1EIP4762, + constantGas: GasFastestStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } + for i := 1; i < 32; i++ { + jt[PUSH1+OpCode(i)] = &operation{ + execute: makePushEIP4762(uint64(i+1), i+1), + constantGas: GasFastestStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } + } +} diff --git a/core/vm/errors.go b/core/vm/errors.go index fbbf19e178..e5efc952d4 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -19,6 +19,7 @@ package vm import ( "errors" "fmt" + "math" ) // List evm execution errors @@ -29,8 +30,8 @@ var ( ErrInsufficientBalance = errors.New("insufficient balance for transfer") ErrContractAddressCollision = errors.New("contract address collision") ErrExecutionReverted = errors.New("execution reverted") - ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") ErrMaxCodeSizeExceeded = errors.New("max code size exceeded") + ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") ErrInvalidJump = errors.New("invalid jump destination") ErrWriteProtection = errors.New("write protection") ErrReturnDataOutOfBounds = errors.New("return data out of bounds") @@ -71,3 +72,122 @@ type ErrInvalidOpCode struct { } func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) } + +// rpcError is the same interface as the one defined in rpc/errors.go +// but we do not want to depend on rpc package here so we redefine it. +// +// It's used to ensure that the VMError implements the RPC error interface. +type rpcError interface { + Error() string // returns the message + ErrorCode() int // returns the code +} + +var _ rpcError = (*VMError)(nil) + +// VMError wraps a VM error with an additional stable error code. The error +// field is the original error that caused the VM error and must be one of the +// VM error defined at the top of this file. +// +// If the error is not one of the known error above, the error code will be +// set to VMErrorCodeUnknown. +type VMError struct { + error + code int +} + +func VMErrorFromErr(err error) error { + if err == nil { + return nil + } + + return &VMError{ + error: err, + code: vmErrorCodeFromErr(err), + } +} + +func (e *VMError) Error() string { + return e.error.Error() +} + +func (e *VMError) Unwrap() error { + return e.error +} + +func (e *VMError) ErrorCode() int { + return e.code +} + +const ( + // We start the error code at 1 so that we can use 0 later for some possible extension. There + // is no unspecified value for the code today because it should always be set to a valid value + // that could be VMErrorCodeUnknown if the error is not mapped to a known error code. + + VMErrorCodeOutOfGas = 1 + iota + VMErrorCodeCodeStoreOutOfGas + VMErrorCodeDepth + VMErrorCodeInsufficientBalance + VMErrorCodeContractAddressCollision + VMErrorCodeExecutionReverted + VMErrorCodeMaxCodeSizeExceeded + VMErrorCodeInvalidJump + VMErrorCodeWriteProtection + VMErrorCodeReturnDataOutOfBounds + VMErrorCodeGasUintOverflow + VMErrorCodeInvalidCode + VMErrorCodeNonceUintOverflow + VMErrorCodeStackUnderflow + VMErrorCodeStackOverflow + VMErrorCodeInvalidOpCode + + // VMErrorCodeUnknown explicitly marks an error as unknown, this is useful when error is converted + // from an actual `error` in which case if the mapping is not known, we can use this value to indicate that. + VMErrorCodeUnknown = math.MaxInt - 1 +) + +func vmErrorCodeFromErr(err error) int { + switch { + case errors.Is(err, ErrOutOfGas): + return VMErrorCodeOutOfGas + case errors.Is(err, ErrCodeStoreOutOfGas): + return VMErrorCodeCodeStoreOutOfGas + case errors.Is(err, ErrDepth): + return VMErrorCodeDepth + case errors.Is(err, ErrInsufficientBalance): + return VMErrorCodeInsufficientBalance + case errors.Is(err, ErrContractAddressCollision): + return VMErrorCodeContractAddressCollision + case errors.Is(err, ErrExecutionReverted): + return VMErrorCodeExecutionReverted + case errors.Is(err, ErrMaxCodeSizeExceeded): + return VMErrorCodeMaxCodeSizeExceeded + case errors.Is(err, ErrInvalidJump): + return VMErrorCodeInvalidJump + case errors.Is(err, ErrWriteProtection): + return VMErrorCodeWriteProtection + case errors.Is(err, ErrReturnDataOutOfBounds): + return VMErrorCodeReturnDataOutOfBounds + case errors.Is(err, ErrGasUintOverflow): + return VMErrorCodeGasUintOverflow + case errors.Is(err, ErrInvalidCode): + return VMErrorCodeInvalidCode + case errors.Is(err, ErrNonceUintOverflow): + return VMErrorCodeNonceUintOverflow + + default: + // Dynamic errors + if v := (*ErrStackUnderflow)(nil); errors.As(err, &v) { + return VMErrorCodeStackUnderflow + } + + if v := (*ErrStackOverflow)(nil); errors.As(err, &v) { + return VMErrorCodeStackOverflow + } + + if v := (*ErrInvalidOpCode)(nil); errors.As(err, &v) { + return VMErrorCodeInvalidOpCode + } + + return VMErrorCodeUnknown + } +} diff --git a/core/vm/evm.go b/core/vm/evm.go index 676b7cc3f2..bcdc9253b3 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -17,6 +17,7 @@ package vm import ( + "errors" "math/big" "sync" "sync/atomic" @@ -24,6 +25,8 @@ import ( "github.com/holiman/uint256" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" @@ -46,36 +49,7 @@ type ( ) func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { - var precompiles map[common.Address]PrecompiledContract - switch { - case evm.chainRules.IsHaber: - precompiles = PrecompiledContractsHaber - case evm.chainRules.IsCancun: - precompiles = PrecompiledContractsCancun - case evm.chainRules.IsFeynman: - precompiles = PrecompiledContractsFeynman - case evm.chainRules.IsHertz: - precompiles = PrecompiledContractsHertz - case evm.chainRules.IsPlato: - precompiles = PrecompiledContractsPlato - case evm.chainRules.IsLuban: - precompiles = PrecompiledContractsLuban - case evm.chainRules.IsPlanck: - precompiles = PrecompiledContractsPlanck - case evm.chainRules.IsMoran: - precompiles = PrecompiledContractsMoran - case evm.chainRules.IsNano: - precompiles = PrecompiledContractsNano - case evm.chainRules.IsBerlin: - precompiles = PrecompiledContractsBerlin - case evm.chainRules.IsIstanbul: - precompiles = PrecompiledContractsIstanbul - case evm.chainRules.IsByzantium: - precompiles = PrecompiledContractsByzantium - default: - precompiles = PrecompiledContractsHomestead - } - p, ok := precompiles[addr] + p, ok := evm.precompiles[addr] return p, ok } @@ -105,10 +79,11 @@ type BlockContext struct { // All fields can change between transactions. type TxContext struct { // Message information - Origin common.Address // Provides information for ORIGIN - GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set) - BlobHashes []common.Hash // Provides information for BLOBHASH - BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set + Origin common.Address // Provides information for ORIGIN + GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set) + BlobHashes []common.Hash // Provides information for BLOBHASH + BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set + AccessEvents *state.AccessEvents // Capture all state accesses for this tx } // EVM is the Ethereum Virtual Machine base object and provides @@ -145,23 +120,13 @@ type EVM struct { // available gas is calculated in gasCall* according to the 63/64 rule and later // applied in opCall*. callGasTemp uint64 + // precompiles holds the precompiled contracts for the current epoch + precompiles map[common.Address]PrecompiledContract } // NewEVM returns a new EVM. The returned EVM is not thread safe and should // only ever be used *once*. func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { - // If basefee tracking is disabled (eth_call, eth_estimateGas, etc), and no - // gas prices were specified, lower the basefee to 0 to avoid breaking EVM - // invariants (basefee < feecap) - if config.NoBaseFee { - if txCtx.GasPrice.BitLen() == 0 { - blockCtx.BaseFee = new(big.Int) - } - if txCtx.BlobFeeCap != nil && txCtx.BlobFeeCap.BitLen() == 0 { - blockCtx.BlobBaseFee = new(big.Int) - } - } - evm := EvmPool.Get().(*EVM) evm.Context = blockCtx evm.TxContext = txCtx @@ -172,15 +137,25 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig evm.abort.Store(false) evm.callGasTemp = 0 evm.depth = 0 - + evm.precompiles = activePrecompiledContracts(evm.chainRules) evm.interpreter = NewEVMInterpreter(evm) return evm } +// SetPrecompiles sets the precompiled contracts for the EVM. +// This method is only used through RPC calls. +// It is not thread-safe. +func (evm *EVM) SetPrecompiles(precompiles PrecompiledContracts) { + evm.precompiles = precompiles +} + // Reset resets the EVM with a new transaction context.Reset // This is not threadsafe and should only be done very cautiously. func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { + if evm.chainRules.IsEIP4762 { + txCtx.AccessEvents = state.NewAccessEvents(statedb.PointCache()) + } evm.TxContext = txCtx evm.StateDB = statedb } @@ -206,6 +181,13 @@ func (evm *EVM) Interpreter() *EVMInterpreter { // the necessary steps to create accounts and reverses the state in case of an // execution error or failed value transfer. func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { + // Capture the tracer start/end events in debug mode + if evm.Config.Tracer != nil { + evm.captureBegin(evm.depth, CALL, caller.Address(), addr, input, gas, value.ToBig()) + defer func(startGas uint64) { + evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) + }(gas) + } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -216,48 +198,35 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } snapshot := evm.StateDB.Snapshot() p, isPrecompile := evm.precompile(addr) - debug := evm.Config.Tracer != nil if !evm.StateDB.Exist(addr) { - if !isPrecompile && evm.chainRules.IsEIP158 && value.IsZero() { - // Calling a non existing account, don't do anything, but ping the tracer - if debug { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value.ToBig()) - evm.Config.Tracer.CaptureEnd(ret, 0, nil) - } else { - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value.ToBig()) - evm.Config.Tracer.CaptureExit(ret, 0, nil) - } + if !isPrecompile && evm.chainRules.IsEIP4762 { + // add proof of absence to witness + wgas := evm.AccessEvents.AddAccount(addr, false) + if gas < wgas { + evm.StateDB.RevertToSnapshot(snapshot) + return nil, 0, ErrOutOfGas } + gas -= wgas + } + + if !isPrecompile && evm.chainRules.IsEIP158 && value.IsZero() { + // Calling a non-existing account, don't do anything. return nil, gas, nil } evm.StateDB.CreateAccount(addr) } evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) - // Capture the tracer start/end events in debug mode - if debug { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value.ToBig()) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.Config.Tracer.CaptureEnd(ret, startGas-gas, err) - }(gas) - } else { - // Handle tracer events for entering and exiting a call frame - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value.ToBig()) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - } - if isPrecompile { - ret, gas, err = RunPrecompiledContract(p, input, gas) + ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer) } else { // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. code := evm.StateDB.GetCode(addr) + if witness := evm.StateDB.Witness(); witness != nil { + witness.AddCode(code) + } if len(code) == 0 { ret, err = nil, nil // gas is unchanged } else { @@ -271,11 +240,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } } // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally + // above we revert to the snapshot and consume any gas remaining. Additionally, // when we're in homestead this also counts for code storage gas errors. if err != nil { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) + } + gas = 0 } // TODO: consider clearing up unused snapshots: @@ -293,6 +266,13 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // CallCode differs from Call in the sense that it executes the given address' // code with the caller as context. func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { + // Invoke tracer hooks that signal entering/exiting a call frame + if evm.Config.Tracer != nil { + evm.captureBegin(evm.depth, CALLCODE, caller.Address(), addr, input, gas, value.ToBig()) + defer func(startGas uint64) { + evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) + }(gas) + } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -306,22 +286,17 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, } var snapshot = evm.StateDB.Snapshot() - // Invoke tracer hooks that signal entering/exiting a call frame - if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value.ToBig()) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - // It is allowed to call precompiles, even via delegatecall if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunPrecompiledContract(p, input, gas) + ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer) } else { addrCopy := addr // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, AccountRef(caller.Address()), value, gas) + if witness := evm.StateDB.Witness(); witness != nil { + witness.AddCode(evm.StateDB.GetCode(addrCopy)) + } contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas @@ -329,6 +304,10 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, if err != nil { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) + } + gas = 0 } } @@ -341,31 +320,33 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // DelegateCall differs from CallCode in the sense that it executes the given address' // code with the caller as context and the caller is set to the caller of the caller. func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, ErrDepth - } - var snapshot = evm.StateDB.Snapshot() - // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { // NOTE: caller must, at all times be a contract. It should never happen // that caller is something other than a Contract. parent := caller.(*Contract) // DELEGATECALL inherits value from parent call - evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig()) + evm.captureBegin(evm.depth, DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig()) defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) + evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) } + // Fail if we're trying to execute above the call depth limit + if evm.depth > int(params.CallCreateDepth) { + return nil, gas, ErrDepth + } + var snapshot = evm.StateDB.Snapshot() // It is allowed to call precompiles, even via delegatecall if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunPrecompiledContract(p, input, gas) + ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer) } else { addrCopy := addr // Initialise a new contract and make initialise the delegate values contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() + if witness := evm.StateDB.Witness(); witness != nil { + witness.AddCode(evm.StateDB.GetCode(addrCopy)) + } contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas @@ -373,6 +354,9 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by if err != nil { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) + } gas = 0 } } @@ -384,6 +368,13 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // Opcodes that attempt to perform such modifications will result in exceptions // instead of performing the modifications. func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { + // Invoke tracer hooks that signal entering/exiting a call frame + if evm.Config.Tracer != nil { + evm.captureBegin(evm.depth, STATICCALL, caller.Address(), addr, input, gas, nil) + defer func(startGas uint64) { + evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) + }(gas) + } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -399,18 +390,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, // but is the correct thing to do and matters on other networks, in tests, and potential // future scenarios - evm.StateDB.AddBalance(addr, new(uint256.Int)) - - // Invoke tracer hooks that signal entering/exiting a call frame - if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } + evm.StateDB.AddBalance(addr, new(uint256.Int), tracing.BalanceChangeTouchAccount) if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunPrecompiledContract(p, input, gas) + ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer) } else { // At this point, we use a copy of address. If we don't, the go compiler will // leak the 'contract' to the outer scope, and make allocation for 'contract' @@ -419,6 +402,9 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas) + if witness := evm.StateDB.Witness(); witness != nil { + witness.AddCode(evm.StateDB.GetCode(addrCopy)) + } contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally @@ -429,6 +415,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte if err != nil { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) + } + gas = 0 } } @@ -448,7 +438,13 @@ func (c *codeAndHash) Hash() common.Hash { } // create creates a new contract using code as deployment code. -func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) { +func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) { + if evm.Config.Tracer != nil { + evm.captureBegin(evm.depth, typ, caller.Address(), address, codeAndHash.code, gas, value.ToBig()) + defer func(startGas uint64) { + evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) + }(gas) + } // Depth check execution. Fail if we're trying to execute above the // limit. if evm.depth > int(params.CallCreateDepth) { @@ -462,80 +458,115 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, return nil, common.Address{}, gas, ErrNonceUintOverflow } evm.StateDB.SetNonce(caller.Address(), nonce+1) - // We add this to the access list _before_ taking a snapshot. Even if the creation fails, - // the access-list change should not be rolled back - if evm.chainRules.IsBerlin { + + // Charge the contract creation init gas in verkle mode + if evm.chainRules.IsEIP4762 { + statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address) + if statelessGas > gas { + return nil, common.Address{}, 0, ErrOutOfGas + } + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, gas-statelessGas, tracing.GasChangeWitnessContractCollisionCheck) + } + gas = gas - statelessGas + } + + // We add this to the access list _before_ taking a snapshot. Even if the + // creation fails, the access-list change should not be rolled back. + if evm.chainRules.IsEIP2929 { evm.StateDB.AddAddressToAccessList(address) } - // Ensure there's no existing contract already at the designated address + // Ensure there's no existing contract already at the designated address. + // Account is regarded as existent if any of these three conditions is met: + // - the nonce is non-zero + // - the code is non-empty + // - the storage is non-empty contractHash := evm.StateDB.GetCodeHash(address) - if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) { + storageRoot := evm.StateDB.GetStorageRoot(address) + if evm.StateDB.GetNonce(address) != 0 || + (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code + (storageRoot != (common.Hash{}) && storageRoot != types.EmptyRootHash) { // non-empty storage + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution) + } return nil, common.Address{}, 0, ErrContractAddressCollision } - // Create a new account on the state + // Create a new account on the state only if the object was not present. + // It might be possible the contract code is deployed to a pre-existent + // account with non-zero balance. snapshot := evm.StateDB.Snapshot() - evm.StateDB.CreateAccount(address) + if !evm.StateDB.Exist(address) { + evm.StateDB.CreateAccount(address) + } + // CreateContract means that regardless of whether the account previously existed + // in the state trie or not, it _now_ becomes created as a _contract_ account. + // This is performed _prior_ to executing the initcode, since the initcode + // acts inside that account. + evm.StateDB.CreateContract(address) + if evm.chainRules.IsEIP158 { evm.StateDB.SetNonce(address, 1) } + // Charge the contract creation init gas in verkle mode + if evm.chainRules.IsEIP4762 { + statelessGas := evm.AccessEvents.ContractCreateInitGas(address) + if statelessGas > gas { + return nil, common.Address{}, 0, ErrOutOfGas + } + if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil { + evm.Config.Tracer.OnGasChange(gas, gas-statelessGas, tracing.GasChangeWitnessContractInit) + } + gas = gas - statelessGas + } evm.Context.Transfer(evm.StateDB, caller.Address(), address, value) // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, AccountRef(address), value, gas) contract.SetCodeOptionalHash(&address, codeAndHash) + contract.IsDeployment = true - if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value.ToBig()) - } else { - evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value.ToBig()) + ret, err = evm.initNewContract(contract, address, value) + if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { + evm.StateDB.RevertToSnapshot(snapshot) + if err != ErrExecutionReverted { + contract.UseGas(contract.Gas, evm.Config.Tracer, tracing.GasChangeCallFailedExecution) } } + return ret, address, contract.Gas, err +} +// initNewContract runs a new contract's creation code, performs checks on the +// resulting code that is to be deployed, and consumes necessary gas. +func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) { ret, err := evm.interpreter.Run(contract, nil, false) + if err != nil { + return ret, err + } // Check whether the max code size has been exceeded, assign err if the case. - if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { - err = ErrMaxCodeSizeExceeded + if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { + return ret, ErrMaxCodeSizeExceeded } // Reject code starting with 0xEF if EIP-3541 is enabled. - if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon { - err = ErrInvalidCode + if len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon { + return ret, ErrInvalidCode } - // if the contract creation ran successfully and no errors were returned - // calculate the gas required to store the code. If the code could not - // be stored due to not enough gas set an error and let it be handled - // by the error checking condition below. - if err == nil { + if !evm.chainRules.IsEIP4762 { createDataGas := uint64(len(ret)) * params.CreateDataGas - if contract.UseGas(createDataGas) { - evm.StateDB.SetCode(address, ret) - } else { - err = ErrCodeStoreOutOfGas + if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) { + return ret, ErrCodeStoreOutOfGas } - } - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { - evm.StateDB.RevertToSnapshot(snapshot) - if err != ErrExecutionReverted { - contract.UseGas(contract.Gas) + } else { + if len(ret) > 0 && !contract.UseGas(evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) { + return ret, ErrCodeStoreOutOfGas } } - if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, err) - } else { - evm.Config.Tracer.CaptureExit(ret, gas-contract.Gas, err) - } - } - return ret, address, contract.Gas, err + evm.StateDB.SetCode(address, ret) + return ret, nil } // Create creates a new contract using code as deployment code. @@ -556,3 +587,44 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment * // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } + +func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) { + tracer := evm.Config.Tracer + if tracer.OnEnter != nil { + tracer.OnEnter(depth, byte(typ), from, to, input, startGas, value) + } + if tracer.OnGasChange != nil { + tracer.OnGasChange(0, startGas, tracing.GasChangeCallInitialBalance) + } +} + +func (evm *EVM) captureEnd(depth int, startGas uint64, leftOverGas uint64, ret []byte, err error) { + tracer := evm.Config.Tracer + if leftOverGas != 0 && tracer.OnGasChange != nil { + tracer.OnGasChange(leftOverGas, 0, tracing.GasChangeCallLeftOverReturned) + } + var reverted bool + if err != nil { + reverted = true + } + if !evm.chainRules.IsHomestead && errors.Is(err, ErrCodeStoreOutOfGas) { + reverted = false + } + if tracer.OnExit != nil { + tracer.OnExit(depth, ret, startGas-leftOverGas, VMErrorFromErr(err), reverted) + } +} + +// GetVMContext provides context about the block being executed as well as state +// to the tracers. +func (evm *EVM) GetVMContext() *tracing.VMContext { + return &tracing.VMContext{ + Coinbase: evm.Context.Coinbase, + BlockNumber: evm.Context.BlockNumber, + Time: evm.Context.Time, + Random: evm.Context.Random, + GasPrice: evm.TxContext.GasPrice, + ChainConfig: evm.ChainConfig(), + StateDB: evm.StateDB, + } +} diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 4b141d8f9a..d294324b08 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -18,6 +18,7 @@ package vm import ( "errors" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -310,9 +311,12 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m return 0, err } size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { + if overflow { return 0, ErrGasUintOverflow } + if size > params.MaxInitCodeSize { + return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size) + } // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow moreGas := params.InitCodeWordGas * ((size + 31) / 32) if gas, overflow = math.SafeAdd(gas, moreGas); overflow { @@ -326,9 +330,12 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, return 0, err } size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { + if overflow { return 0, ErrGasUintOverflow } + if size > params.MaxInitCodeSize { + return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size) + } // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow moreGas := (params.InitCodeWordGas + params.Keccak256WordGas) * ((size + 31) / 32) if gas, overflow = math.SafeAdd(gas, moreGas); overflow { @@ -376,7 +383,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize } else if !evm.StateDB.Exist(address) { gas += params.CallNewAccountGas } - if transfersValue { + if transfersValue && !evm.chainRules.IsEIP4762 { gas += params.CallValueTransferGas } memoryGas, err := memoryGasCost(mem, memorySize) @@ -387,7 +394,14 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { return 0, ErrGasUintOverflow } - + if evm.chainRules.IsEIP4762 { + if transfersValue { + gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) + if overflow { + return 0, ErrGasUintOverflow + } + } + } evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) if err != nil { return 0, err @@ -395,6 +409,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { return 0, ErrGasUintOverflow } + return gas, nil } @@ -407,12 +422,22 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory gas uint64 overflow bool ) - if stack.Back(2).Sign() != 0 { + if stack.Back(2).Sign() != 0 && !evm.chainRules.IsEIP4762 { gas += params.CallValueTransferGas } if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { return 0, ErrGasUintOverflow } + if evm.chainRules.IsEIP4762 { + address := common.Address(stack.Back(1).Bytes20()) + transfersValue := !stack.Back(2).IsZero() + if transfersValue { + gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) + if overflow { + return 0, ErrGasUintOverflow + } + } + } evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) if err != nil { return 0, err diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index 4a2545b6ed..babe9a5b6a 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -18,6 +18,7 @@ package vm import ( "bytes" + "errors" "math" "math/big" "sort" @@ -25,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -85,7 +85,7 @@ func TestEIP2200(t *testing.T) { for i, tt := range eip2200Tests { address := common.BytesToAddress([]byte("contract")) - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) statedb.SetCode(address, hexutil.MustDecode(tt.input)) statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original})) @@ -98,7 +98,7 @@ func TestEIP2200(t *testing.T) { vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int)) - if err != tt.failure { + if !errors.Is(err, tt.failure) { t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) } if used := tt.gaspool - gas; used != tt.used { @@ -137,7 +137,7 @@ func TestCreateGas(t *testing.T) { var gasUsed = uint64(0) doCheck := func(testGas int) bool { address := common.BytesToAddress([]byte("contract")) - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) statedb.SetCode(address, hexutil.MustDecode(tt.code)) statedb.Finalise(true) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index b8055de6bc..35d6393fba 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -20,6 +20,7 @@ import ( "math" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" @@ -172,11 +173,7 @@ func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek() - if z.IsZero() { - z.Clear() - } else { - z.AddMod(&x, &y, z) - } + z.AddMod(&x, &y, z) return nil, nil } @@ -235,7 +232,7 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { offset, size := scope.Stack.pop(), scope.Stack.peek() - data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) + data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) if interpreter.hasher == nil { interpreter.hasher = crypto.NewKeccakState() @@ -249,7 +246,6 @@ func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( if evm.Config.EnablePreimageRecording { evm.StateDB.AddPreimage(interpreter.hasherBuf, data) } - size.SetBytes(interpreter.hasherBuf[:]) return nil, nil } @@ -305,7 +301,7 @@ func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext ) dataOffset64, overflow := dataOffset.Uint64WithOverflow() if overflow { - dataOffset64 = 0xffffffffffffffff + dataOffset64 = math.MaxUint64 } // These values are checked for overflow during gas cost calculation memOffset64 := memOffset.Uint64() @@ -344,6 +340,10 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() + address := slot.Bytes20() + if witness := interpreter.evm.StateDB.Witness(); witness != nil { + witness.AddCode(interpreter.evm.StateDB.GetCode(address)) + } slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) return nil, nil } @@ -363,9 +363,9 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ if overflow { uint64CodeOffset = math.MaxUint64 } + codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64()) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - return nil, nil } @@ -382,7 +382,11 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) uint64CodeOffset = math.MaxUint64 } addr := common.Address(a.Bytes20()) - codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) + code := interpreter.evm.StateDB.GetCode(addr) + if witness := interpreter.evm.StateDB.Witness(); witness != nil { + witness.AddCode(code) + } + codeCopy := getData(code, uint64CodeOffset, length.Uint64()) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) return nil, nil @@ -438,6 +442,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( num.Clear() return nil, nil } + var upper, lower uint64 upper = interpreter.evm.Context.BlockNumber.Uint64() if upper < 257 { @@ -446,7 +451,11 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( lower = upper - 256 } if num64 >= lower && num64 < upper { - num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) + res := interpreter.evm.Context.GetHash(num64) + if witness := interpreter.evm.StateDB.Witness(); witness != nil { + witness.AddBlockHash(num64) + } + num.SetBytes(res[:]) } else { num.Clear() } @@ -493,7 +502,7 @@ func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { v := scope.Stack.peek() - offset := int64(v.Uint64()) + offset := v.Uint64() v.SetBytes(scope.Memory.GetPtr(offset, 32)) return nil, nil } @@ -574,6 +583,86 @@ func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte return nil, nil } +func opSwap1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap1() + return nil, nil +} + +func opSwap2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap2() + return nil, nil +} + +func opSwap3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap3() + return nil, nil +} + +func opSwap4(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap4() + return nil, nil +} + +func opSwap5(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap5() + return nil, nil +} + +func opSwap6(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap6() + return nil, nil +} + +func opSwap7(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap7() + return nil, nil +} + +func opSwap8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap8() + return nil, nil +} + +func opSwap9(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap9() + return nil, nil +} + +func opSwap10(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap10() + return nil, nil +} + +func opSwap11(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap11() + return nil, nil +} + +func opSwap12(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap12() + return nil, nil +} + +func opSwap13(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap13() + return nil, nil +} + +func opSwap14(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap14() + return nil, nil +} + +func opSwap15(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap15() + return nil, nil +} + +func opSwap16(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.swap16() + return nil, nil +} + func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { if interpreter.readOnly { return nil, ErrWriteProtection @@ -581,16 +670,17 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b var ( value = scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop() - input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) + input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64()) gas = scope.Contract.Gas ) if interpreter.evm.chainRules.IsEIP150 { gas -= gas / 64 } + // reuse size int for stackvalue stackvalue := size - scope.Contract.UseGas(gas) + scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation) res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value) // Push item on the stack based on the returned error. If the ruleset is @@ -605,7 +695,8 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b stackvalue.SetBytes(addr.Bytes()) } scope.Stack.push(&stackvalue) - scope.Contract.Gas += returnGas + + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) if suberr == ErrExecutionReverted { interpreter.returnData = res // set REVERT data to return data buffer @@ -623,12 +714,13 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] endowment = scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop() salt = scope.Stack.pop() - input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) + input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64()) gas = scope.Contract.Gas ) + // Apply EIP150 gas -= gas / 64 - scope.Contract.UseGas(gas) + scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation2) // reuse size int for stackvalue stackvalue := size res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, @@ -640,7 +732,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] stackvalue.SetBytes(addr.Bytes()) } scope.Stack.push(&stackvalue) - scope.Contract.Gas += returnGas + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) if suberr == ErrExecutionReverted { interpreter.returnData = res // set REVERT data to return data buffer @@ -660,7 +752,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) // Get the arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) + args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) if interpreter.readOnly && !value.IsZero() { return nil, ErrWriteProtection @@ -679,7 +771,8 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt if err == nil || err == ErrExecutionReverted { scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - scope.Contract.Gas += returnGas + + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) interpreter.returnData = ret return ret, nil @@ -695,7 +788,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) + args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) if !value.IsZero() { gas += params.CallStipend @@ -711,7 +804,8 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ if err == nil || err == ErrExecutionReverted { scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - scope.Contract.Gas += returnGas + + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) interpreter.returnData = ret return ret, nil @@ -727,7 +821,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) + args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) if err != nil { @@ -739,7 +833,8 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext if err == nil || err == ErrExecutionReverted { scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - scope.Contract.Gas += returnGas + + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) interpreter.returnData = ret return ret, nil @@ -755,7 +850,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) + args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) if err != nil { @@ -767,7 +862,8 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) if err == nil || err == ErrExecutionReverted { scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - scope.Contract.Gas += returnGas + + scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) interpreter.returnData = ret return ret, nil @@ -775,14 +871,14 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { offset, size := scope.Stack.pop(), scope.Stack.pop() - ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) + ret := scope.Memory.GetCopy(offset.Uint64(), size.Uint64()) return ret, errStopToken } func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { offset, size := scope.Stack.pop(), scope.Stack.pop() - ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) + ret := scope.Memory.GetCopy(offset.Uint64(), size.Uint64()) interpreter.returnData = ret return ret, ErrExecutionReverted @@ -802,11 +898,15 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext } beneficiary := scope.Stack.pop() balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) - interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) + interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address()) if tracer := interpreter.evm.Config.Tracer; tracer != nil { - tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) - tracer.CaptureExit([]byte{}, 0, nil) + if tracer.OnEnter != nil { + tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) + } + if tracer.OnExit != nil { + tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false) + } } return nil, errStopToken } @@ -817,12 +917,16 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon } beneficiary := scope.Stack.pop() balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) - interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance) - interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) + interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct) + interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address()) if tracer := interpreter.evm.Config.Tracer; tracer != nil { - tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) - tracer.CaptureExit([]byte{}, 0, nil) + if tracer.OnEnter != nil { + tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) + } + if tracer.OnExit != nil { + tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false) + } } return nil, errStopToken } @@ -843,7 +947,7 @@ func makeLog(size int) executionFunc { topics[i] = addr.Bytes32() } - d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) + d := scope.Memory.GetCopy(mStart.Uint64(), mSize.Uint64()) interpreter.evm.StateDB.AddLog(&types.Log{ Address: scope.Contract.Address(), Topics: topics, @@ -875,21 +979,17 @@ func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by // make push instruction function func makePush(size uint64, pushByteSize int) executionFunc { return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - codeLen := len(scope.Contract.Code) - - startMin := codeLen - if int(*pc+1) < startMin { - startMin = int(*pc + 1) - } - - endMin := codeLen - if startMin+pushByteSize < endMin { - endMin = startMin + pushByteSize - } - - integer := new(uint256.Int) - scope.Stack.push(integer.SetBytes(common.RightPadBytes( - scope.Contract.Code[startMin:endMin], pushByteSize))) + var ( + codeLen = len(scope.Contract.Code) + start = min(codeLen, int(*pc+1)) + end = min(codeLen, start+pushByteSize) + ) + scope.Stack.push(new(uint256.Int).SetBytes( + common.RightPadBytes( + scope.Contract.Code[start:end], + pushByteSize, + )), + ) *pc += size return nil, nil @@ -903,13 +1003,3 @@ func makeDup(size int64) executionFunc { return nil, nil } } - -// make swap instruction function -func makeSwap(size int64) executionFunc { - // switch n + 1 otherwise n would be swapped with n - size++ - return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.swap(int(size)) - return nil, nil - } -} diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 8653864d11..a3f9ee81d1 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -27,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -582,7 +581,7 @@ func BenchmarkOpMstore(bench *testing.B) { func TestOpTstore(t *testing.T) { var ( - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{}) stack = newstack() mem = NewMemory() @@ -643,7 +642,7 @@ func BenchmarkOpKeccak256(bench *testing.B) { } } -func TestCreate2Addreses(t *testing.T) { +func TestCreate2Addresses(t *testing.T) { type testcase struct { origin string salt string diff --git a/core/vm/interface.go b/core/vm/interface.go index 25bfa06720..5f42643565 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -20,17 +20,21 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) // StateDB is an EVM database for full state querying. type StateDB interface { CreateAccount(common.Address) + CreateContract(common.Address) - SubBalance(common.Address, *uint256.Int) - AddBalance(common.Address, *uint256.Int) + SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) + AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) GetBalance(common.Address) *uint256.Int GetNonce(common.Address) uint64 @@ -48,6 +52,7 @@ type StateDB interface { GetCommittedState(common.Address, common.Hash) common.Hash GetState(common.Address, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) + GetStorageRoot(addr common.Address) common.Hash GetTransientState(addr common.Address, key common.Hash) common.Hash SetTransientState(addr common.Address, key, value common.Hash) @@ -72,6 +77,10 @@ type StateDB interface { // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform // even if the feature/fork is not active yet AddSlotToAccessList(addr common.Address, slot common.Hash) + + // PointCache returns the point cache used in computations + PointCache() *utils.PointCache + Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) RevertToSnapshot(int) @@ -79,6 +88,8 @@ type StateDB interface { AddLog(*types.Log) AddPreimage(common.Hash, []byte) + + Witness() *stateless.Witness } // CallContext provides a basic interface for the EVM calling conventions. The EVM diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 43a565c21e..62ffd3bced 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -17,12 +17,15 @@ package vm import ( + "fmt" "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/holiman/uint256" ) var EVMInterpreterPool = sync.Pool{ @@ -33,11 +36,12 @@ var EVMInterpreterPool = sync.Pool{ // Config are the configuration options for the Interpreter type Config struct { - Tracer EVMLogger // Opcode logger - NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) - NoRecursion bool // Disables call, callcode, delegate call and create - EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages - ExtraEips []int // Additional EIPS that are to be enabled + Tracer *tracing.Hooks + NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) + EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages + ExtraEips []int // Additional EIPS that are to be enabled + + StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose) } // ScopeContext contains the things that are per-call, such as stack and memory, @@ -48,6 +52,50 @@ type ScopeContext struct { Contract *Contract } +// MemoryData returns the underlying memory slice. Callers must not modify the contents +// of the returned data. +func (ctx *ScopeContext) MemoryData() []byte { + if ctx.Memory == nil { + return nil + } + return ctx.Memory.Data() +} + +// StackData returns the stack data. Callers must not modify the contents +// of the returned data. +func (ctx *ScopeContext) StackData() []uint256.Int { + if ctx.Stack == nil { + return nil + } + return ctx.Stack.Data() +} + +// Caller returns the current caller. +func (ctx *ScopeContext) Caller() common.Address { + return ctx.Contract.Caller() +} + +// Address returns the address where this scope of execution is taking place. +func (ctx *ScopeContext) Address() common.Address { + return ctx.Contract.Address() +} + +// CallValue returns the value supplied with this call. +func (ctx *ScopeContext) CallValue() *uint256.Int { + return ctx.Contract.Value() +} + +// CallInput returns the input/calldata with this call. Callers must not modify +// the contents of the returned data. +func (ctx *ScopeContext) CallInput() []byte { + return ctx.Contract.Input +} + +// ContractCode returns the code of the contract being executed. +func (ctx *ScopeContext) ContractCode() []byte { + return ctx.Contract.Code +} + // EVMInterpreter represents an EVM interpreter type EVMInterpreter struct { evm *EVM @@ -65,6 +113,9 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { // If jump table was not initialised we set the default one. var table *JumpTable switch { + case evm.chainRules.IsVerkle: + // TODO replace with proper instruction set when fork is specified + table = &verkleInstructionSet case evm.chainRules.IsCancun: table = &cancunInstructionSet case evm.chainRules.IsShanghai: @@ -162,22 +213,25 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( res []byte // result of the opcode execution function debug = in.evm.Config.Tracer != nil ) - // Don't move this deferred function, it's placed before the capturestate-deferred method, - // so that it gets executed _after_: the capturestate needs the stacks before + // Don't move this deferred function, it's placed before the OnOpcode-deferred method, + // so that it gets executed _after_: the OnOpcode needs the stacks before // they are returned to the pools defer func() { returnStack(stack) + mem.Free() }() contract.Input = input if debug { - defer func() { - if err != nil { - if !logged { - in.evm.Config.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - } else { - in.evm.Config.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err) - } + defer func() { // this deferred method handles exit-with-error + if err == nil { + return + } + if !logged && in.evm.Config.Tracer.OnOpcode != nil { + in.evm.Config.Tracer.OnOpcode(pcCopy, byte(op), gasCopy, cost, callContext, in.returnData, in.evm.depth, VMErrorFromErr(err)) + } + if logged && in.evm.Config.Tracer.OnFault != nil { + in.evm.Config.Tracer.OnFault(pcCopy, byte(op), gasCopy, cost, callContext, in.evm.depth, VMErrorFromErr(err)) } }() } @@ -190,6 +244,14 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // Capture pre-execution values for tracing. logged, pcCopy, gasCopy = false, pc, contract.Gas } + + if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment { + // if the PC ends up in a new "chunk" of verkleized code, charge the + // associated costs. + contractAddr := contract.Address() + contract.Gas -= in.evm.TxContext.AccessEvents.CodeChunksRangeGas(contractAddr, pc, 1, uint64(len(contract.Code)), false) + } + // Get the operation from the jump table and validate the stack to ensure there are // enough stack items available to perform the operation. op = contract.GetOp(pc) @@ -201,9 +263,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( } else if sLen > operation.maxStack { return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack} } - if !contract.UseGas(cost) { + if !contract.UseGas(cost, in.evm.Config.Tracer, tracing.GasChangeIgnored) { return nil, ErrOutOfGas } + if operation.dynamicGas != nil { // All ops with a dynamic memory usage also has a dynamic gas cost. var memorySize uint64 @@ -228,21 +291,36 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( var dynamicCost uint64 dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize) cost += dynamicCost // for tracing - if err != nil || !contract.UseGas(dynamicCost) { + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrOutOfGas, err) + } + if !contract.UseGas(dynamicCost, in.evm.Config.Tracer, tracing.GasChangeIgnored) { return nil, ErrOutOfGas } + // Do tracing before memory expansion if debug { - in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - logged = true + if in.evm.Config.Tracer.OnGasChange != nil { + in.evm.Config.Tracer.OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode) + } + if in.evm.Config.Tracer.OnOpcode != nil { + in.evm.Config.Tracer.OnOpcode(pc, byte(op), gasCopy, cost, callContext, in.returnData, in.evm.depth, VMErrorFromErr(err)) + logged = true + } } if memorySize > 0 { mem.Resize(memorySize) } } else if debug { - in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - logged = true + if in.evm.Config.Tracer.OnGasChange != nil { + in.evm.Config.Tracer.OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode) + } + if in.evm.Config.Tracer.OnOpcode != nil { + in.evm.Config.Tracer.OnOpcode(pc, byte(op), gasCopy, cost, callContext, in.returnData, in.evm.depth, VMErrorFromErr(err)) + logged = true + } } + // execute the operation res, err = operation.execute(&pc, in, callContext) if err != nil { diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go index ff4977d728..a1369648da 100644 --- a/core/vm/interpreter_test.go +++ b/core/vm/interpreter_test.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -43,7 +42,7 @@ func TestLoopInterrupt(t *testing.T) { } for i, tt := range loopInterruptTests { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) statedb.SetCode(address, common.Hex2Bytes(tt)) statedb.Finalise(true) diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 70c543f14d..5fbde1804a 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -57,6 +57,7 @@ var ( mergeInstructionSet = newMergeInstructionSet() shanghaiInstructionSet = newShanghaiInstructionSet() cancunInstructionSet = newCancunInstructionSet() + verkleInstructionSet = newVerkleInstructionSet() ) // JumpTable contains the EVM opcodes supported at a given fork. @@ -80,6 +81,12 @@ func validate(jt JumpTable) JumpTable { return jt } +func newVerkleInstructionSet() JumpTable { + instructionSet := newCancunInstructionSet() + enable4762(&instructionSet) + return validate(instructionSet) +} + func newCancunInstructionSet() JumpTable { instructionSet := newShanghaiInstructionSet() enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) @@ -885,97 +892,97 @@ func newFrontierInstructionSet() JumpTable { maxStack: maxDupStack(16), }, SWAP1: { - execute: makeSwap(1), + execute: opSwap1, constantGas: GasFastestStep, minStack: minSwapStack(2), maxStack: maxSwapStack(2), }, SWAP2: { - execute: makeSwap(2), + execute: opSwap2, constantGas: GasFastestStep, minStack: minSwapStack(3), maxStack: maxSwapStack(3), }, SWAP3: { - execute: makeSwap(3), + execute: opSwap3, constantGas: GasFastestStep, minStack: minSwapStack(4), maxStack: maxSwapStack(4), }, SWAP4: { - execute: makeSwap(4), + execute: opSwap4, constantGas: GasFastestStep, minStack: minSwapStack(5), maxStack: maxSwapStack(5), }, SWAP5: { - execute: makeSwap(5), + execute: opSwap5, constantGas: GasFastestStep, minStack: minSwapStack(6), maxStack: maxSwapStack(6), }, SWAP6: { - execute: makeSwap(6), + execute: opSwap6, constantGas: GasFastestStep, minStack: minSwapStack(7), maxStack: maxSwapStack(7), }, SWAP7: { - execute: makeSwap(7), + execute: opSwap7, constantGas: GasFastestStep, minStack: minSwapStack(8), maxStack: maxSwapStack(8), }, SWAP8: { - execute: makeSwap(8), + execute: opSwap8, constantGas: GasFastestStep, minStack: minSwapStack(9), maxStack: maxSwapStack(9), }, SWAP9: { - execute: makeSwap(9), + execute: opSwap9, constantGas: GasFastestStep, minStack: minSwapStack(10), maxStack: maxSwapStack(10), }, SWAP10: { - execute: makeSwap(10), + execute: opSwap10, constantGas: GasFastestStep, minStack: minSwapStack(11), maxStack: maxSwapStack(11), }, SWAP11: { - execute: makeSwap(11), + execute: opSwap11, constantGas: GasFastestStep, minStack: minSwapStack(12), maxStack: maxSwapStack(12), }, SWAP12: { - execute: makeSwap(12), + execute: opSwap12, constantGas: GasFastestStep, minStack: minSwapStack(13), maxStack: maxSwapStack(13), }, SWAP13: { - execute: makeSwap(13), + execute: opSwap13, constantGas: GasFastestStep, minStack: minSwapStack(14), maxStack: maxSwapStack(14), }, SWAP14: { - execute: makeSwap(14), + execute: opSwap14, constantGas: GasFastestStep, minStack: minSwapStack(15), maxStack: maxSwapStack(15), }, SWAP15: { - execute: makeSwap(15), + execute: opSwap15, constantGas: GasFastestStep, minStack: minSwapStack(16), maxStack: maxSwapStack(16), }, SWAP16: { - execute: makeSwap(16), + execute: opSwap16, constantGas: GasFastestStep, minStack: minSwapStack(17), maxStack: maxSwapStack(17), diff --git a/core/vm/logger.go b/core/vm/logger.go deleted file mode 100644 index 9abaf7b736..0000000000 --- a/core/vm/logger.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -// EVMLogger is used to collect execution traces from an EVM transaction -// execution. CaptureState is called for each step of the VM with the -// current VM state. -// Note that reference types are actual VM data structures; make copies -// if you need to retain them beyond the current call. -type EVMLogger interface { - // Transaction level - CaptureTxStart(gasLimit uint64) - CaptureTxEnd(restGas uint64) - CaptureSystemTxEnd(intrinsicGas uint64) - // Top call frame - CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) - CaptureEnd(output []byte, gasUsed uint64, err error) - // Rest of call frames - CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) - CaptureExit(output []byte, gasUsed uint64, err error) - // Opcode level - CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) - CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) -} diff --git a/core/vm/memory.go b/core/vm/memory.go index e0202fd7c0..1ddd8d1ead 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -17,9 +17,17 @@ package vm import ( + "sync" + "github.com/holiman/uint256" ) +var memoryPool = sync.Pool{ + New: func() any { + return &Memory{} + }, +} + // Memory implements a simple memory model for the ethereum virtual machine. type Memory struct { store []byte @@ -28,7 +36,18 @@ type Memory struct { // NewMemory returns a new memory model. func NewMemory() *Memory { - return &Memory{} + return memoryPool.Get().(*Memory) +} + +// Free returns the memory to the pool. +func (m *Memory) Free() { + // To reduce peak allocation, return only smaller memory instances to the pool. + const maxBufferSize = 16 << 10 + if cap(m.store) <= maxBufferSize { + m.store = m.store[:0] + m.lastGasCost = 0 + memoryPool.Put(m) + } } // Set sets offset + size to value @@ -66,32 +85,25 @@ func (m *Memory) Resize(size uint64) { } // GetCopy returns offset + size as a new slice -func (m *Memory) GetCopy(offset, size int64) (cpy []byte) { +func (m *Memory) GetCopy(offset, size uint64) (cpy []byte) { if size == 0 { return nil } - if len(m.store) > int(offset) { - cpy = make([]byte, size) - copy(cpy, m.store[offset:offset+size]) - - return - } - + // memory is always resized before being accessed, no need to check bounds + cpy = make([]byte, size) + copy(cpy, m.store[offset:offset+size]) return } // GetPtr returns the offset + size -func (m *Memory) GetPtr(offset, size int64) []byte { +func (m *Memory) GetPtr(offset, size uint64) []byte { if size == 0 { return nil } - if len(m.store) > int(offset) { - return m.store[offset : offset+size] - } - - return nil + // memory is always resized before being accessed, no need to check bounds + return m.store[offset : offset+size] } // Len returns the length of the backing slice diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index f420a24105..1cdaaba516 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -21,6 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/params" ) @@ -38,16 +39,10 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { cost = uint64(0) ) // Check slot presence in the access list - if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent { + if _, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent { cost = params.ColdSloadCostEIP2929 // If the caller cannot afford the cost, this change will be rolled back evm.StateDB.AddSlotToAccessList(contract.Address(), slot) - if !addrPresent { - // Once we're done with YOLOv2 and schedule this for mainnet, might - // be good to remove this panic here, which is just really a - // canary to have during testing - panic("impossible case: address was not present in access list during sstore op") - } } value := common.Hash(y.Bytes32()) @@ -169,7 +164,7 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc { evm.StateDB.AddAddressToAccessList(addr) // Charge the remaining difference here already, to correctly calculate available // gas for call - if !contract.UseGas(coldCost) { + if !contract.UseGas(coldCost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { return 0, ErrOutOfGas } } diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go new file mode 100644 index 0000000000..722d5ed2ce --- /dev/null +++ b/core/vm/operations_verkle.go @@ -0,0 +1,155 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/params" +) + +func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas := evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), true) + if gas == 0 { + gas = params.WarmStorageReadCostEIP2929 + } + return gas, nil +} + +func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas := evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), false) + if gas == 0 { + gas = params.WarmStorageReadCostEIP2929 + } + return gas, nil +} + +func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + address := stack.peek().Bytes20() + gas := evm.AccessEvents.BasicDataGas(address, false) + if gas == 0 { + gas = params.WarmStorageReadCostEIP2929 + } + return gas, nil +} + +func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + address := stack.peek().Bytes20() + if _, isPrecompile := evm.precompile(address); isPrecompile { + return 0, nil + } + gas := evm.AccessEvents.BasicDataGas(address, false) + if gas == 0 { + gas = params.WarmStorageReadCostEIP2929 + } + return gas, nil +} + +func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + address := stack.peek().Bytes20() + if _, isPrecompile := evm.precompile(address); isPrecompile { + return 0, nil + } + gas := evm.AccessEvents.CodeHashGas(address, false) + if gas == 0 { + gas = params.WarmStorageReadCostEIP2929 + } + return gas, nil +} + +func makeCallVariantGasEIP4762(oldCalculator gasFunc) gasFunc { + return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := oldCalculator(evm, contract, stack, mem, memorySize) + if err != nil { + return 0, err + } + if _, isPrecompile := evm.precompile(contract.Address()); isPrecompile { + return gas, nil + } + witnessGas := evm.AccessEvents.MessageCallGas(contract.Address()) + if witnessGas == 0 { + witnessGas = params.WarmStorageReadCostEIP2929 + } + return witnessGas + gas, nil + } +} + +var ( + gasCallEIP4762 = makeCallVariantGasEIP4762(gasCall) + gasCallCodeEIP4762 = makeCallVariantGasEIP4762(gasCallCode) + gasStaticCallEIP4762 = makeCallVariantGasEIP4762(gasStaticCall) + gasDelegateCallEIP4762 = makeCallVariantGasEIP4762(gasDelegateCall) +) + +func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + beneficiaryAddr := common.Address(stack.peek().Bytes20()) + if _, isPrecompile := evm.precompile(beneficiaryAddr); isPrecompile { + return 0, nil + } + contractAddr := contract.Address() + statelessGas := evm.AccessEvents.BasicDataGas(contractAddr, false) + if contractAddr != beneficiaryAddr { + statelessGas += evm.AccessEvents.BasicDataGas(beneficiaryAddr, false) + } + // Charge write costs if it transfers value + if evm.StateDB.GetBalance(contractAddr).Sign() != 0 { + statelessGas += evm.AccessEvents.BasicDataGas(contractAddr, true) + if contractAddr != beneficiaryAddr { + statelessGas += evm.AccessEvents.BasicDataGas(beneficiaryAddr, true) + } + } + return statelessGas, nil +} + +func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := gasCodeCopy(evm, contract, stack, mem, memorySize) + if err != nil { + return 0, err + } + var ( + codeOffset = stack.Back(1) + length = stack.Back(2) + ) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = math.MaxUint64 + } + _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) + if !contract.IsDeployment { + gas += evm.AccessEvents.CodeChunksRangeGas(contract.Address(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + } + return gas, nil +} + +func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + // memory expansion first (dynamic part of pre-2929 implementation) + gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize) + if err != nil { + return 0, err + } + addr := common.Address(stack.peek().Bytes20()) + wgas := evm.AccessEvents.BasicDataGas(addr, false) + if wgas == 0 { + wgas = params.WarmStorageReadCostEIP2929 + } + var overflow bool + // We charge (cold-warm), since 'warm' is already charged as constantGas + if gas, overflow = math.SafeAdd(gas, wgas); overflow { + return 0, ErrGasUintOverflow + } + return gas, nil +} diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 46f2bb5d5f..f83ed682cd 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -21,7 +21,6 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -57,24 +56,33 @@ type Config struct { // sets defaults on the config func setDefaults(cfg *Config) { if cfg.ChainConfig == nil { + var ( + shanghaiTime = uint64(0) + cancunTime = uint64(0) + ) cfg.ChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: new(big.Int), - DAOForkBlock: new(big.Int), - DAOForkSupport: false, - EIP150Block: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: new(big.Int), - ByzantiumBlock: new(big.Int), - ConstantinopleBlock: new(big.Int), - PetersburgBlock: new(big.Int), - IstanbulBlock: new(big.Int), - MuirGlacierBlock: new(big.Int), - BerlinBlock: new(big.Int), - LondonBlock: new(big.Int), - } + ChainID: big.NewInt(1), + HomesteadBlock: new(big.Int), + DAOForkBlock: new(big.Int), + DAOForkSupport: false, + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: new(big.Int), + ByzantiumBlock: new(big.Int), + ConstantinopleBlock: new(big.Int), + PetersburgBlock: new(big.Int), + IstanbulBlock: new(big.Int), + MuirGlacierBlock: new(big.Int), + BerlinBlock: new(big.Int), + LondonBlock: new(big.Int), + ArrowGlacierBlock: nil, + GrayGlacierBlock: nil, + TerminalTotalDifficulty: big.NewInt(0), + TerminalTotalDifficultyPassed: true, + MergeNetsplitBlock: nil, + ShanghaiTime: &shanghaiTime, + CancunTime: &cancunTime} } - if cfg.Difficulty == nil { cfg.Difficulty = new(big.Int) } @@ -101,6 +109,10 @@ func setDefaults(cfg *Config) { if cfg.BlobBaseFee == nil { cfg.BlobBaseFee = big.NewInt(params.BlobTxMinBlobGasprice) } + // Merge indicators + if t := cfg.ChainConfig.ShanghaiTime; cfg.ChainConfig.TerminalTotalDifficultyPassed || (t != nil && *t == 0) { + cfg.Random = &(common.Hash{}) + } } // Execute executes the code using the input as call data during the execution. @@ -115,7 +127,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { setDefaults(cfg) if cfg.State == nil { - cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) } var ( address = common.BytesToAddress([]byte("contract")) @@ -123,6 +135,9 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { sender = vm.AccountRef(cfg.Origin) rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) + if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil { + cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) + } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) // - reset transient storage(eip 1153) @@ -149,13 +164,16 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { setDefaults(cfg) if cfg.State == nil { - cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) } var ( vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) + if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil { + cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) + } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) // - reset transient storage(eip 1153) @@ -184,6 +202,9 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er statedb = cfg.State rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) + if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil { + cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) + } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) // - reset transient storage(eip 1153) diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index b9e3c8ed66..9046dad5fe 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -17,9 +17,11 @@ package runtime import ( + "encoding/binary" "fmt" "math/big" "os" + "strconv" "strings" "testing" @@ -28,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/asm" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -38,7 +39,6 @@ import ( // force-load js tracers to trigger registration _ "github.com/ethereum/go-ethereum/eth/tracers/js" - "github.com/holiman/uint256" ) func TestDefaults(t *testing.T) { @@ -104,8 +104,8 @@ func TestExecute(t *testing.T) { } func TestCall(t *testing.T) { - state, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - address := common.HexToAddress("0x0a") + state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + address := common.HexToAddress("0xaa") state.SetCode(address, []byte{ byte(vm.PUSH1), 10, byte(vm.PUSH1), 0, @@ -160,7 +160,7 @@ func BenchmarkCall(b *testing.B) { } func benchmarkEVM_Create(bench *testing.B, code string) { var ( - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) sender = common.BytesToAddress([]byte("sender")) receiver = common.BytesToAddress([]byte("receiver")) ) @@ -213,6 +213,70 @@ func BenchmarkEVM_CREATE2_1200(bench *testing.B) { benchmarkEVM_Create(bench, "5b5862124f80600080f5600152600056") } +func BenchmarkEVM_SWAP1(b *testing.B) { + // returns a contract that does n swaps (SWAP1) + swapContract := func(n uint64) []byte { + contract := []byte{ + byte(vm.PUSH0), // PUSH0 + byte(vm.PUSH0), // PUSH0 + } + for i := uint64(0); i < n; i++ { + contract = append(contract, byte(vm.SWAP1)) + } + return contract + } + + state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + contractAddr := common.BytesToAddress([]byte("contract")) + + b.Run("10k", func(b *testing.B) { + contractCode := swapContract(10_000) + state.SetCode(contractAddr, contractCode) + + for i := 0; i < b.N; i++ { + _, _, err := Call(contractAddr, []byte{}, &Config{State: state}) + if err != nil { + b.Fatal(err) + } + } + }) +} + +func BenchmarkEVM_RETURN(b *testing.B) { + // returns a contract that returns a zero-byte slice of len size + returnContract := func(size uint64) []byte { + contract := []byte{ + byte(vm.PUSH8), 0, 0, 0, 0, 0, 0, 0, 0, // PUSH8 0xXXXXXXXXXXXXXXXX + byte(vm.PUSH0), // PUSH0 + byte(vm.RETURN), // RETURN + } + binary.BigEndian.PutUint64(contract[1:], size) + return contract + } + + state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + contractAddr := common.BytesToAddress([]byte("contract")) + + for _, n := range []uint64{1_000, 10_000, 100_000, 1_000_000} { + b.Run(strconv.FormatUint(n, 10), func(b *testing.B) { + b.ReportAllocs() + + contractCode := returnContract(n) + state.SetCode(contractAddr, contractCode) + + for i := 0; i < b.N; i++ { + ret, _, err := Call(contractAddr, []byte{}, &Config{State: state}) + if err != nil { + b.Fatal(err) + } + if uint64(len(ret)) != n { + b.Fatalf("expected return size %d, got %d", n, len(ret)) + } + } + }) + } +} + func fakeHeader(n uint64, parentHash common.Hash) *types.Header { header := types.Header{ Coinbase: common.HexToAddress("0x00000000000000000000000000000000deadbeef"), @@ -328,7 +392,7 @@ func TestBlockhash(t *testing.T) { func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) { cfg := new(Config) setDefaults(cfg) - cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) cfg.GasLimit = gas if len(tracerCode) > 0 { tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil) @@ -336,14 +400,10 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode b.Fatal(err) } cfg.EVMConfig = vm.Config{ - Tracer: tracer, + Tracer: tracer.Hooks, } } - var ( - destination = common.BytesToAddress([]byte("contract")) - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) + destination := common.BytesToAddress([]byte("contract")) cfg.State.CreateAccount(destination) eoa := common.HexToAddress("E0") { @@ -363,12 +423,12 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode //cfg.State.CreateAccount(cfg.Origin) // set the receiver's (the executing contract) code for execution. cfg.State.SetCode(destination, code) - vmenv.Call(sender, destination, nil, gas, uint256.MustFromBig(cfg.Value)) + Call(destination, nil, cfg) b.Run(name, func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - vmenv.Call(sender, destination, nil, gas, uint256.MustFromBig(cfg.Value)) + Call(destination, nil, cfg) } }) } @@ -511,7 +571,7 @@ func TestEip2929Cases(t *testing.T) { code, ops) Execute(code, nil, &Config{ EVMConfig: vm.Config{ - Tracer: logger.NewMarkdownLogger(nil, os.Stdout), + Tracer: logger.NewMarkdownLogger(nil, os.Stdout).Hooks(), ExtraEips: []int{2929}, }, }) @@ -664,7 +724,7 @@ func TestColdAccountAccessCost(t *testing.T) { tracer := logger.NewStructLogger(nil) Execute(tc.code, nil, &Config{ EVMConfig: vm.Config{ - Tracer: tracer, + Tracer: tracer.Hooks(), }, }) have := tracer.StructLogs()[tc.step].GasCost @@ -725,7 +785,7 @@ func TestRuntimeJSTracer(t *testing.T) { byte(vm.CREATE), byte(vm.POP), }, - results: []string{`"1,1,952855,6,12"`, `"1,1,952855,6,0"`}, + results: []string{`"1,1,952853,6,12"`, `"1,1,952853,6,0"`}, }, { // CREATE2 @@ -741,7 +801,7 @@ func TestRuntimeJSTracer(t *testing.T) { byte(vm.CREATE2), byte(vm.POP), }, - results: []string{`"1,1,952846,6,13"`, `"1,1,952846,6,0"`}, + results: []string{`"1,1,952844,6,13"`, `"1,1,952844,6,0"`}, }, { // CALL @@ -812,20 +872,20 @@ func TestRuntimeJSTracer(t *testing.T) { byte(vm.PUSH1), 0, byte(vm.RETURN), } - depressedCode := []byte{ + suicideCode := []byte{ byte(vm.PUSH1), 0xaa, byte(vm.SELFDESTRUCT), } main := common.HexToAddress("0xaa") for i, jsTracer := range jsTracers { for j, tc := range tests { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.SetCode(main, tc.code) statedb.SetCode(common.HexToAddress("0xbb"), calleeCode) statedb.SetCode(common.HexToAddress("0xcc"), calleeCode) statedb.SetCode(common.HexToAddress("0xdd"), calleeCode) statedb.SetCode(common.HexToAddress("0xee"), calleeCode) - statedb.SetCode(common.HexToAddress("0xff"), depressedCode) + statedb.SetCode(common.HexToAddress("0xff"), suicideCode) tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil) if err != nil { @@ -835,7 +895,7 @@ func TestRuntimeJSTracer(t *testing.T) { GasLimit: 1000000, State: statedb, EVMConfig: vm.Config{ - Tracer: tracer, + Tracer: tracer.Hooks, }}) if err != nil { t.Fatal("didn't expect error", err) @@ -861,7 +921,7 @@ func TestJSTracerCreateTx(t *testing.T) { exit: function(res) { this.exits++ }}` code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)} - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil) if err != nil { t.Fatal(err) @@ -869,7 +929,7 @@ func TestJSTracerCreateTx(t *testing.T) { _, _, _, err = Create(code, &Config{ State: statedb, EVMConfig: vm.Config{ - Tracer: tracer, + Tracer: tracer.Hooks, }}) if err != nil { t.Fatal(err) diff --git a/core/vm/stack.go b/core/vm/stack.go index e1a957e244..879dc9aa6d 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -30,7 +30,7 @@ var stackPool = sync.Pool{ // Stack is an object for basic stack operations. Items popped to the stack are // expected to be changed and modified. stack does not take care of adding newly -// initialised objects. +// initialized objects. type Stack struct { data []uint256.Int } @@ -64,8 +64,53 @@ func (st *Stack) len() int { return len(st.data) } -func (st *Stack) swap(n int) { - st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] +func (st *Stack) swap1() { + st.data[st.len()-2], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-2] +} +func (st *Stack) swap2() { + st.data[st.len()-3], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-3] +} +func (st *Stack) swap3() { + st.data[st.len()-4], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-4] +} +func (st *Stack) swap4() { + st.data[st.len()-5], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-5] +} +func (st *Stack) swap5() { + st.data[st.len()-6], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-6] +} +func (st *Stack) swap6() { + st.data[st.len()-7], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-7] +} +func (st *Stack) swap7() { + st.data[st.len()-8], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-8] +} +func (st *Stack) swap8() { + st.data[st.len()-9], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-9] +} +func (st *Stack) swap9() { + st.data[st.len()-10], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-10] +} +func (st *Stack) swap10() { + st.data[st.len()-11], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-11] +} +func (st *Stack) swap11() { + st.data[st.len()-12], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-12] +} +func (st *Stack) swap12() { + st.data[st.len()-13], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-13] +} +func (st *Stack) swap13() { + st.data[st.len()-14], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-14] +} +func (st *Stack) swap14() { + st.data[st.len()-15], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-15] +} +func (st *Stack) swap15() { + st.data[st.len()-16], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-16] +} +func (st *Stack) swap16() { + st.data[st.len()-17], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-17] } func (st *Stack) dup(n int) { diff --git a/core/vm/testdata/precompiles/blsG1Add.json b/core/vm/testdata/precompiles/blsG1Add.json index 184d765aa1..14a6b16df8 100644 --- a/core/vm/testdata/precompiles/blsG1Add.json +++ b/core/vm/testdata/precompiles/blsG1Add.json @@ -3,728 +3,728 @@ "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", "Name": "bls_g1add_(g1+g1=2*g1)", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d280000000000000000000000000000000009ece308f9d1f0131765212deca99697b112d61f9be9a5f1f3780a51335b3ff981747a0b2ca2179b96d2c0c9024e522400000000000000000000000000000000032b80d3a6f5b09f8a84623389c5f80ca69a0cddabc3097f9d9c27310fd43be6e745256c634af45ca3473b0590ae30d1", "Expected": "0000000000000000000000000000000010e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc0000000000000000000000000000000016ba437edcc6551e30c10512367494bfb6b01cc6681e8a4c3cd2501832ab5c4abc40b4578b85cbaffbf0bcd70d67c6e2", "Name": "bls_g1add_(2*g1+3*g1=5*g1)", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", "Name": "bls_g1add_(inf+g1=g1)", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g1add_(inf+inf=inf)", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7", "Expected": "000000000000000000000000000000001466e1373ae4a7e7ba885c5f0c3ccfa48cdb50661646ac6b779952f466ac9fc92730dcaed9be831cd1f8c4fefffd5209000000000000000000000000000000000c1fb750d2285d4ca0378e1e8cdbf6044151867c34a711b73ae818aee6dbe9e886f53d7928cc6ed9c851e0422f609b11", "Name": "matter_g1_add_0", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed2000000000000000000000000000000000441e7f7f96198e4c23bd5eb16f1a7f045dbc8c53219ab2bcea91d3a027e2dfe659feac64905f8b9add7e4bfc91bec2b0000000000000000000000000000000005fc51bb1b40c87cd4292d4b66f8ca5ce4ef9abd2b69d4464b4879064203bda7c9fc3f896a3844ebc713f7bb20951d95", "Expected": "0000000000000000000000000000000016b8ab56b45a9294466809b8e858c1ad15ad0d52cfcb62f8f5753dc94cee1de6efaaebce10701e3ec2ecaa9551024ea600000000000000000000000000000000124571eec37c0b1361023188d66ec17c1ec230d31b515e0e81e599ec19e40c8a7c8cdea9735bc3d8b4e37ca7e5dd71f6", "Name": "matter_g1_add_1", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f00000000000000000000000000000000114c3f11ba0b47551fa28f09f148936d6b290dc9f2d0534a83c32b0b849ab921ce6bcaa4ff3c917707798d9c74f2084f00000000000000000000000000000000149dc028207fb04a7795d94ea65e21f9952e445000eb954531ee519efde6901675d3d2446614d243efb77a9cfe0ca3ae", "Expected": "0000000000000000000000000000000002ce7a08719448494857102da464bc65a47c95c77819af325055a23ac50b626df4732daf63feb9a663d71b7c9b8f2c510000000000000000000000000000000016117e87e9b55bd4bd5763d69d5240d30745e014b9aef87c498f9a9e3286ec4d5927df7cd5a2e54ac4179e78645acf27", "Name": "matter_g1_add_2", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4000000000000000000000000000000000c3d564ac1fe12f18f528c3750583ab6af8973bff3eded7bb4778c32805d9b17846cc7c687af0f46bc87de7748ab72980000000000000000000000000000000002f164c131cbd5afc85692c246157d38dc4bbb2959d2edfa6daf0a8b17c7a898aad53b400e8bdc2b29bf6688ee863db7", "Expected": "0000000000000000000000000000000015510826f50b88fa369caf062ecdf8b03a67e660a35b219b44437a5583b5a9adf76991dce7bff9afc50257f847299504000000000000000000000000000000000a83e879895a1b47dbd6cd25ce8b719e7490cfe021614f7539e841fc2f9c09f071e386676de60b6579aa4bf6d37b13dd", "Name": "matter_g1_add_3", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d30000000000000000000000000000000019fe3a64361fea14936ff0b3e630471494d0c0b9423e6a004184a2965221c18849b5ed0eb2708a587323d8d6c6735a90000000000000000000000000000000000340823d314703e5efeb0a65c23069199d7dfff8793aaacb98cdcd6177fc8e61ab3294c57bf13b4406266715752ef3e6", "Expected": "00000000000000000000000000000000010b1c96d3910f56b0bf54da5ae8c7ab674a07f8143b61fed660e7309e626dc73eaa2b11886cdb82e2b6735e7802cc860000000000000000000000000000000002dabbbedd72872c2c012e7e893d2f3df1834c43873315488d814ddd6bfcca6758a18aa6bd02a0f3aed962cb51f0a222", "Name": "matter_g1_add_4", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90000000000000000000000000000000001461565b03a86df363d1854b4af74879115dffabeddfa879e2c8db9aa414fb291a076c3bdf0beee82d9c094ea8dc381a000000000000000000000000000000000e19d51ab619ee2daf25ea5bfa51eb217eabcfe0b5cb0358fd2fa105fd7cb0f5203816b990df6fda4e0e8d541be9bcf6", "Expected": "000000000000000000000000000000000cb40d0bf86a627d3973f1e7846484ffd0bc4943b42a54ff9527c285fed3c056b947a9b6115824cabafe13cd1af8181c00000000000000000000000000000000076255fc12f1a9dbd232025815238baaa6a3977fd87594e8d1606caec0d37b916e1e43ee2d2953d75a40a7ba416df237", "Name": "matter_g1_add_5", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b0000000000000000000000000000000019cabba3e09ad34cc3d125e0eb41b527aa48a4562c2b7637467b2dbc71c373897d50eed1bc75b2bde8904ece5626d6e400000000000000000000000000000000056b0746f820cff527358c86479dc924a10b9f7cae24cd495625a4159c8b71a8c3ad1a15ebf22d3561cd4b74e8a6e48b", "Expected": "000000000000000000000000000000000e115e0b61c1f1b25cc10a7b3bd21cf696b1433a0c366c2e1bca3c26b09482c6eced8c8ecfa69ce6b9b3b4419779262e00000000000000000000000000000000077b85daf61b9f947e81633e3bc64e697bc6c1d873f2c21e5c4c3a11302d4d5ef4c3ff5519564729aaf2a50a3c9f1196", "Name": "matter_g1_add_6", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a0000000000000000000000000000000011f649ee35ff8114060fc5e4df9ac828293f6212a9857ca31cb3e9ce49aa1212154a9808f1e763bc989b6d5ba7cf09390000000000000000000000000000000019af81eca7452f58c1a6e99fab50dc0d5eeebc7712153e717a14a31cffdfd0a923dbd585e652704a174905605a2e8b9d", "Expected": "000000000000000000000000000000000013e37a8950a659265b285c6fb56930fb77759d9d40298acac2714b97b83ec7692a7d1c4ccb83f074384db9eedd809c0000000000000000000000000000000003215d524d6419214568ba42a31502f2a58a97d0139c66908e9d71755f5a7666567aafe30ea84d89308f06768f28a648", "Name": "matter_g1_add_7", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795000000000000000000000000000000000d713e148769fac2efd380886f8566c6d4662dd38317bb7e68744c4339efaedbab88435ce3dc289afaa7ecb37df37a5300000000000000000000000000000000129d9cd031b31c77a4e68093dcdbb585feba786207aa115d9cf120fe4f19ca31a0dca9c692bd0f53721d60a55c333129", "Expected": "00000000000000000000000000000000029405b9615e14bdac8b5666bbc5f3843d4bca17c97bed66d164f1b58d2a148f0f506d645d665a40e60d53fe29375ed400000000000000000000000000000000162761f1712814e474beb2289cc50519253d680699b530c2a6477f727ccc75a19681b82e490f441f91a3c611eeb0e9e2", "Name": "matter_g1_add_8", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a1900000000000000000000000000000000006d92bcb599edca426ff4ceeb154ebf133c2dea210c7db0441f74bd37c8d239149c8b5056ace0bfefb1db04b42664f530000000000000000000000000000000008522fc155eef6d5746283808091f91b427f2a96ac248850f9e3d7aadd14848101c965663fd4a63aea1153d71918435a", "Expected": "000000000000000000000000000000000cfaa8df9437c0b6f344a0c8dcbc7529a07aec0d7632ace89af6796b6b960b014f78dd10e987a993fb8a95cc909822ec0000000000000000000000000000000007475f115f6eb35f78ba9a2b71a44ccb6bbc1e980b8cd369c5c469565f3fb798bc907353cf47f524ba715deaedf379cb", "Name": "matter_g1_add_9", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac9430000000000000000000000000000000016380d03b7c5cc3301ffcb2cf7c28c9bde54fc22ba2b36ec293739d8eb674678c8e6461e34c1704747817c8f8341499a000000000000000000000000000000000ec6667aa5c6a769a64c180d277a341926376c39376480dc69fcad9a8d3b540238eb39d05aaa8e3ca15fc2c3ab696047", "Expected": "0000000000000000000000000000000011541d798b4b5069e2541fa5410dad03fd02784332e72658c7b0fa96c586142a967addc11a7a82bfcee33bd5d07066b900000000000000000000000000000000195b3fcb94ab7beb908208283b4e5d19c0af90fca4c76268f3c703859dea7d038aca976927f48839ebc7310869c724aa", "Name": "matter_g1_add_10", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e00000000000000000000000000000000065eb0770ab40199658bf87db6c6b52cd8c6c843a3e40dd60433d4d79971ff31296c9e00a5d553df7c81ade533379f4b0000000000000000000000000000000017a6f6137ddd90c15cf5e415f040260e15287d8d2254c6bfee88938caec9e5a048ff34f10607d1345ba1f09f30441ef4", "Expected": "0000000000000000000000000000000006b0853b3d41fc2d7b27da0bb2d6eb76be32530b59f8f537d227a6eb78364c7c0760447494a8bba69ef4b256dbef750200000000000000000000000000000000166e55ba2d20d94da474d4a085c14245147705e252e2a76ae696c7e37d75cde6a77fea738cef045182d5e628924dc0bb", "Name": "matter_g1_add_11", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b0000000000000000000000000000000006a3f7eb0e42567210cc1ba5e6f8c42d02f1eef325b6483fef49ba186f59ab69ca2284715b736086d2a0a1f0ea224b40000000000000000000000000000000000bc08427fda31a6cfbe657a8c71c73894a33700e93e411d42f1471160c403b939b535070b68d60a4dc50e47493da63dc", "Expected": "000000000000000000000000000000000c35d4cd5d43e9cf52c15d46fef521666a1e1ab9f0b4a77b8e78882e9fab40f3f988597f202c5bd176c011a56a1887d4000000000000000000000000000000000ae2b5c24928a00c02daddf03fade45344f250dcf4c12eda06c39645b4d56147cb239d95b06fd719d4dc20fe332a6fce", "Name": "matter_g1_add_12", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a578768100000000000000000000000000000000068e79aea45b7199ec4b6f26e01e88ec76533743639ce76df66937fff9e7de3edf6700d227f10f43e073afcc63e2eddc00000000000000000000000000000000039c0b6d9e9681401aeb57a94cedc0709a0eff423ace9253eb00ae75e21cabeb626b52ef4368e6a4592aed9689c6fca4", "Expected": "0000000000000000000000000000000013bad27dafa20f03863454c30bd5ae6b202c9c7310875da302d4693fc1c2b78cca502b1ff851b183c4b2564c5d3eb4dc0000000000000000000000000000000000552b322b3d672704382b5d8b214c225b4f7868f9c5ae0766b7cdb181f97ed90a4892235915ffbc0daf3e14ec98a606", "Name": "matter_g1_add_13", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f7680000000000000000000000000000000000adac9bb98bb6f35a8f941dbff39dfd307b6a4d5756ccae103c814564e3d3993a8866ff91581ccdd7686c1dce0b19f700000000000000000000000000000000083d235e0579032ca47f65b6ae007ce8ffd2f1a890ce3bc45ebd0df6673ad530d2f42125d543cb0c51ba0c28345729d8", "Expected": "000000000000000000000000000000000b5513e42f5217490f395a8cb3673a4fc35142575f770af75ecf7a4fcd97eee215c4298fc4feab51915137cbdb814839000000000000000000000000000000000e9d4db04b233b0b12a7ff620faefef906aeb2b15481ce1609dad50eb6a7d0c09a850375599c501296219fb7b288e305", "Name": "matter_g1_add_14", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931d000000000000000000000000000000000d5bb4fa8b494c0adf4b695477d4a05f0ce48f7f971ef53952f685e9fb69dc8db1603e4a58292ddab7129bb5911d6cea0000000000000000000000000000000004a568c556641f0e0a2f44124b77ba70e4e560d7e030f1a21eff41eeec0d3c437b43488c535cdabf19a70acc777bacca", "Expected": "000000000000000000000000000000000c27ef4ebf37fd629370508f4cd062b74faa355b305d2ee60c7f4d67dd741363f18a7bbd368cdb17e848f372a5e33a6f0000000000000000000000000000000000ed833df28988944115502f554636e0b436cccf845341e21191e82d5b662482f32c24df492da4c605a0f9e0f8b00604", "Name": "matter_g1_add_15", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000091ee883cb9ea2c933f6645f0f4c535a826d95b6da6847b4fe2349342bd4bd496e0dd546df7a7a17a4b9fb8349e5064f000000000000000000000000000000000902d7e72242a5e6b068ca82d0cb71dc0f51335dbd302941045319f9a06777518b56a6e0b0b0c9fd8f1edf6b114ad331", "Expected": "00000000000000000000000000000000122cce99f623944dfebffcdf6b0a0a3696162f35053e5952dddc2537421c60da9fe931579d1c4fc2e31082b6c25f96b500000000000000000000000000000000011366ffa91dc0b7da8b7c1839ea84d49299310f5c1ca244012eed0dd363dbcf4ad5813b8e3fb49361ef05ea8cb18ffe", "Name": "matter_g1_add_16", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debe0000000000000000000000000000000000d3d4f11bc79b8425b77d25698b7e151d360ebb22c3a6afdb227de72fe432dcd6f0276b4fd3f1fcc2da5b59865053930000000000000000000000000000000015ac432071dc23148765f198ed7ea2234662745a96032c215cd9d7cf0ad8dafb8d52f209983fe98aaa2243ecc2073f1b", "Expected": "000000000000000000000000000000000113ccf11264ff04448f8c58b279a6a49acb386750c2051eab2c90fa8b8e03d7c5b9e87eccf36b4b3f79446b80be7b1d0000000000000000000000000000000004358a1fabfe803f4c787a671196b593981a837ee78587225fb21d5a883b98a15b912862763b94d18b971cb7e37dbcf0", "Name": "matter_g1_add_17", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb600000000000000000000000000000000034f725766897ed76394145da2f02c92c66794a51fd5ae07bd7cc60c013d7a48ebf1b07faf669dfed74d82d07e48d1150000000000000000000000000000000018f4926a3d0f740988da25379199ecb849250239ad7efcfef7ffaa43bc1373166c0448cc30dcdbd75ceb71f76f883ea7", "Expected": "00000000000000000000000000000000167336aeeb9e447348156936849d518faee314c291c84d732fa3c1bd3951559230d94230e37a08e28e689e9d1fef05770000000000000000000000000000000005366535f7a68996e066ab80c55bb372a15fb0ed6634585b88fe7cafbf818fbfebbf6f6ddd9ca0ff72137594a1e84b35", "Name": "matter_g1_add_18", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154b00000000000000000000000000000000079e5a154cf84190b6c735bc8cd968559182166568649b813732e4fb4c5c428c8b38e8265d4ef04990c49aa1381f51c8000000000000000000000000000000000ae08e682ef92b4986a5ac5d4f094ad0919c826a97efe8d8120a96877766eae5828803804a0cae67df9822fd18622aae", "Expected": "000000000000000000000000000000000a3d66cf87b1ce8c5683d71a6de4bf829d094041240f56d9071aa84ff189a06940e8e1935127e23a970c78ca73c28bf6000000000000000000000000000000000b2adda87740873c0c59e3ebde44d33834773f0fe69e2f5e7ede99c4f928978a5caaede7262e45fd22136a394b3f7858", "Name": "matter_g1_add_19", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af0000000000000000000000000000000008cefd0fd289d6964a962051c2c2ad98dab178612663548370dd5f007c5264fece368468d3ca8318a381b443c68c4cc7000000000000000000000000000000000708d118d44c1cb5609667fd51df9e58cacce8b65565ef20ad1649a3e1b9453e4fb37af67c95387de008d4c2114e5b95", "Expected": "0000000000000000000000000000000004b2311897264fe08972d62872d3679225d9880a16f2f3d7dd59412226e5e3f4f2aa8a69d283a2dc5b93e022293f0ee1000000000000000000000000000000000f03e18cef3f9a86e6b842272f2c7ee48d0ad23bfc7f1d5a9a796d88e5d5ac31326db5fe90de8f0690c70ae6e0155039", "Name": "matter_g1_add_20", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719290000000000000000000000000000000008e5afc16d909eb9d8bdaaf229ad291f34f7baf5247bbd4cc938278f1349adb4b0f0aacd14799c01d0ca2ed38c937d600000000000000000000000000000000006cf972c64e20403c82fee901c90eaa5547460d57cce2565fd091ff9bc55e24584595c9182298f148882d6949c36c9d5", "Expected": "000000000000000000000000000000000caf46f480ae2ea8e700f7913c505d5150c4629c9137e917357d2a4ba8a7a1c63b8f6e2978293755952fbed7f0ad8d6d0000000000000000000000000000000002e62e715b72eebbc7c366a2390318f73e69203a9533e72340aab568f65105129ffc9889a8bc00a692494d93688c7ec0", "Name": "matter_g1_add_21", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac0000000000000000000000000000000013a6439e0ec0fabe93f6c772e102b96b1f692971d7181c386f7f8a360daca6e5f99772e1a736f1e72a17148d90b08efe0000000000000000000000000000000010f27477f3171dcf74498e940fc324596ef5ec6792be590028c2963385d84ef8c4bbb12c6eb3f06b1afb6809a2cb0358", "Expected": "000000000000000000000000000000000dea57d1fc19f994e6bdda9478a400b0ada23aed167bfe7a16ef79b6aa020403a04d554303c0b2a9c5a38f85cf6f3800000000000000000000000000000000000b8d76ccd41ba81a835775185bbf1d6bf94b031d94d5c78b3b97beb24cf246b0c25c4c309e2c06ae9896ed800169eeee", "Name": "matter_g1_add_22", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff320000000000000000000000000000000005728a219d128bc0a1f851f228e2bf604a72400c393cfb0d3484456b6b28a2c5061198656f0e106bbe257d849be159040000000000000000000000000000000011f6d08baa91fb2c8b36191d5b2318e355f8964cc8112838394ba1ded84b075de58d90452601dcfc9aa8a275cfec695d", "Expected": "0000000000000000000000000000000012e6d6c518c15cfd3020181ff3f829e29140b3b507b99251cc7f31795128adec817750296bce413bac18b9a80f69ca5000000000000000000000000000000000131ee9b748f6f1eb790adeb9edd0e79d89a9908368f5a6bb82ee0c913061cdfffe75d9ba411a49aa3f9194ee6d4d08a9", "Name": "matter_g1_add_23", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f200000000000000000000000000000000171696781ba195f330241584e42fb112adf9b8437b54ad17d410892b45c7d334e8734e25862604d1b679097590b8ab0a000000000000000000000000000000001879328fdf0d1fb79afd920e0b0a386828be5b8e0e6024dfeea800ffcb5c65f9044061af26d639d4dcc27bcb5ba1481a", "Expected": "00000000000000000000000000000000111c416d5bd018a77f3317e3fbf4b03d8e19658f2b810dc9c17863310dfb09e1c4ffdbb7c98951d357f1c3d93c5d0745000000000000000000000000000000000af0a252bff336d5eb3a406778557ef67d91776a9c788be9a76cff7727f519a70fc7809f1a50a58d29185cb9722624fd", "Name": "matter_g1_add_24", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c2000000000000000000000000000000000231b0d6189a4faad082ce4a69398c1734fcf35d222b7bce22b14571033a1066b049ae3cd3bd6c8cec5bec743955cdd600000000000000000000000000000000037375237fb71536564ea693ab316ae11722aadd7cab12b17b926c8a31bd13c4565619e8c894bffb960e632896856bbe", "Expected": "000000000000000000000000000000000d2b9c677417f4e9b38af6393718f55a27dbd23c730796c50472bc476ebf52172559b10f6ceb81e644ec2d0a41b3bb01000000000000000000000000000000001697f241ff6eceb05d9ada4be7d7078ecbbffa64dd4fb43ead0692eef270cb7cc31513ee4bf38a1b1154fe008a8b836a", "Name": "matter_g1_add_25", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd10000000000000000000000000000000015653d1c5184736cdc78838be953390d12b307d268b394136b917b0462d5e31b8f1b9d96cce8f7a1203c2cae93db6a4000000000000000000000000000000000060efeece033ac711d500c1156e4b6dce3243156170c94bc948fd7beae7b28a31463a44872ca22ca49dc5d4d4dd27d1c", "Expected": "0000000000000000000000000000000003996050756117eeab27a5e4fa9acdde2a1161d6fbfff2601a1c7329f900e93a29f55a8073f85be8f7c2a4d0323e95cc00000000000000000000000000000000010b195a132c1cba2f1a6a73f2507baa079e9b5cb8894ea78bebc16d4151ee56fe562b16e2741f3ab1e8640cdad83180", "Name": "matter_g1_add_26", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc0000000000000000000000000000000018adb42928304cbc310a229306a205e7c21cdb31b9e5daf0ff6bb9437acee80cd8cf02b35dab823155d60f8a83fde5cc0000000000000000000000000000000018b57460c81cab43235be79c8c90dcda40fafcaf69e4e767133aee56308a6df07eac71275597dd8ed6607ffb9151ed9a", "Expected": "0000000000000000000000000000000003c7a7ee3d1b73cf1f0213404363bf3c0de4425ab97d679ed51448e877b7537400f148f14eba588ed241fea34e56d465000000000000000000000000000000000c581b5070e6bb8582b7ee2cd312dfeb5aaf0b0da95cf5a22a505ffba21fc204e26a5e17311d1f47113653ff13349f57", "Name": "matter_g1_add_27", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da00000000000000000000000000000000001da65df8574a864ab454e5f2fa929405501bb73c3162a600979a1145586079361c89839cc0c5a07f1135c94bf059f9c0000000000000000000000000000000002560df402c0550662a2c4c463ad428ab6e60297fbc42a6484107e397ae016b58494d1c46ac4952027aa8c0896c50be3", "Expected": "000000000000000000000000000000000d7a539b679e5858271a6f9cf20108410eb5d5d2b1a905e09a8aa20318efbe9175450385d78389f08f836f5634f7a2f0000000000000000000000000000000000fb624e5f6c4c814b7d73eb63b70237c5de7d90d19ac81cac776d86171a8d307d3cc8c56da14f444fe8cf329ab7e63dd", "Name": "matter_g1_add_28", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e0530000000000000000000000000000000005311c11f4d0bb8542f3b60247c1441656608e5ac5c363f4d62127cecb88800a771767cf23a0e7c45f698ffa5015061f0000000000000000000000000000000018f7f1d23c8b0566a6a1fcb58d3a5c6fd422573840eb04660c3c6ba65762ed1becc756ac6300e9ce4f5bfb962e963419", "Expected": "0000000000000000000000000000000000849bbc7b0226b18abbcb4c9a9e78dca2f5f75a2cbb983bd95ff3a95b427b1a01fd909ce36384c49eb88ffb8ff77bb000000000000000000000000000000000087d8d28d92305b5313ca533a6b47f454ddce1c2d0fa3574b255128ef0b145fa4158beb07e4f0d50d6b7b90ea8a8ea8a", "Name": "matter_g1_add_29", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265e000000000000000000000000000000000c8e293f730253128399e5c39ab18c3f040b6cd9df10d794a28d2a428a9256ea1a71cf53022bd1be11f501805e0ddda40000000000000000000000000000000003e60c2291be46900930f710969f79f27e76cf710efefc243236428db2fed93719edeeb64ada0edf6346a0411f2a4cb8", "Expected": "00000000000000000000000000000000191084201608f706ea1f7c51dd5b593dda87b15d2c594b52829db66ce3beab6b30899d1d285bdb9590335949ceda5f050000000000000000000000000000000000d3460622c7f1d849658a20a7ae7b05e5afae1f01e871cad52ef632cc831b0529a3066f7b81248a7728d231e51fc4ad", "Name": "matter_g1_add_30", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc80000000000000000000000000000000013267db8fdf8f488a2806fead5cffdcbb7b1b4b7681a2b67d322cd7f5985c65d088c70cdc2638e679ed678cae3cc63c80000000000000000000000000000000007757233ad6d38d488c3d9d8252b41e4ab7ee54e4ef4bbf171402df57c14f9977dd3583c6c8f9b5171b368d61f082447", "Expected": "000000000000000000000000000000000c06fef6639ab7dceb44dc648ca6a7d614739e40e6486ee9fc01ecc55af580d98abc026c630a95878da7b6d5701d755c0000000000000000000000000000000007c9a7f2bc7fa1f65c9e3a1e463eb4e3283e47bb5490938edb12abf6c8f5a9b56d8ce7a81a60df67db8c399a9a1df1d4", "Name": "matter_g1_add_31", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff17000000000000000000000000000000001975bc52669187f27a86096ae6bf2d60178706105d15bce8fe782759f14e449bc97cb1570e87eec5f12214a9ae0e0170000000000000000000000000000000000ca6106d6e6487a3b6f00fc2af769d21cb3b83b5dc03db19e4824fc28fd9b3d9f7a986e79f05c02b3a914ff26c7a78d6", "Expected": "0000000000000000000000000000000002fbf4fba68ae416b42a99f3b26916dea464d662cebce55f4545481e5ab92d3c40f3e189504b54db4c9cd51ecdd60e8d0000000000000000000000000000000008e81e094c6d4ded718ef63c5edfacb2d258f48ccfa37562950c607299bb2dca18e680a620dff8c72dedc89b4e9d4759", "Name": "matter_g1_add_32", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f00000000000000000000000000000000109f6168a719add6ea1a14f9dc95345e325d6b0e56da2f4ecff8408536446894069fa61e81bdaebfc96b13b402fad865000000000000000000000000000000001806aa27c576f4c4fa8a6db49d577cd8f257a8450e89b061cbc7773c0b5434f06bacf12b479abf6847f537c4cbefcb46", "Expected": "0000000000000000000000000000000014e0bd4397b90a3f96240daf835d5fb05da28a64538f4bf42d9e7925a571f831c6e663910aa37dcc265ddd7938d83045000000000000000000000000000000001695d405d4f8ba385ebf4ad25fb3f34c65977217e90d6e5ed5085b3e5b0b143194f82e6c25766d28ad6c63114ca9dcdf", "Name": "matter_g1_add_33", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af0000000000000000000000000000000019d3623a7866933e2d73214ceb2e56097a1b047db5943c3ecb846890aa02250126e90fc76a729a952cef895bd154cc7d000000000000000000000000000000000e87c376bbd695a356ef72226ac7ef6a550d99e9693d8485770a686e568ae28c038ee201d3f2ea38362046236ade91cd", "Expected": "000000000000000000000000000000000ffeab47985bd9b3e10ce27c6636bbda336dcf540cd37eccc3faec2adff2d97dd126633bd83a7d3c8c73c3623bdf0ba2000000000000000000000000000000001992eca4b1e924b360d57ca98b543ab496a8b55bd288d23f03bcc1b22f6bc76d95b12f47c3e305812097253c73b876dd", "Name": "matter_g1_add_34", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c300000000000000000000000000000000163aaecf83d6c77a5d7417e73f5cf9d71a6aedfd194b2f3b53c608d06a228190f4f79ac57b029d77504c72744df4ecc0000000000000000000000000000000000416e6f9ca188d16daa2c28acd6a594f8fcb990eaa26e60ca2a34dfcad7ad76c425b241acedf674d48d298d0df0f824d", "Expected": "000000000000000000000000000000001812bcb26fa05e0ab5176e703699ab16f5ef8917a33a9626ae6ff20f2a6f4a9d5e2afe3a11f57061cbaa992e1f30477f000000000000000000000000000000000680acf0b632cb48017cb80baa93753d030aa4b49957178d8a10d1d1a27bbdc89ac6811a91868b2c181c5c0b9b6caf86", "Name": "matter_g1_add_35", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000000aba7362eee717d03ef2d4f0fef2763822115fcc8fb9e2e8243683b6c1cde799ebc78f23812e557de2cc38e2b4a2e56700000000000000000000000000000000170833db69b3f067cf5c4c4690857e6711c9e3fcad91ca7cd045e9d2f38c7b31236960e8718f5dd4c8bfb4de76c6c9b9", "Expected": "00000000000000000000000000000000196ffe76a4b726fa8dd720cc1cd04c040724cb18ec10915e312eaa90d124100b08f0ce3a7fc888f46914319a3d7581f4000000000000000000000000000000000e2612357059ca6dbb64efb98ef19370560c9e83e2aad7ab2d9015e2444fe4d8c796b5577584aac9f63258beb5ae863c", "Name": "matter_g1_add_36", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da8257721808000000000000000000000000000000000a98ae36c690f2e3be8100f43678be5a1064390e210328dd23f61f5a496b87398db2798580edeabc6273fb9537fa12880000000000000000000000000000000009aedf77bb969592c6552ae0121a1c74de78ba222b6cd08623c7a34708a12763b5ff7969cf761ccd25adc1b65da0f02d", "Expected": "00000000000000000000000000000000072334ec8349fc38b99d6dea0b4259c03cd96c1438c90ef0da6321df2495892de031a53c23838ca2b260774fa09b5461000000000000000000000000000000000e4535767c2477c4f87c087540c836eeffcd0c45960841f9c3561a8a5f8e61ab98b183b11192b8e7ea1c9c7717336243", "Name": "matter_g1_add_37", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e00000000000000000000000000000000015c3c056ec904ce865d073f8f70ef2d4b5adb5b9238deaa5e167d32f45cad4901aa6d87efa2338c633e7853ce4c19185000000000000000000000000000000000a15f1aa6e662f21d7127351a1655821c943c4cf590e3c9e60c9ab968b4a835f87fb8d87eee6331ee4e194e5f1ea91f4", "Expected": "000000000000000000000000000000000140fb6dcf872d0a3bff3e32a0cb4a7fb7e60ee4fb476bb120c4ce068e169d72e1c167d7fda321280d5855983d5a9af800000000000000000000000000000000108f54a4ec3ba26dd614f4d94c5c82652583906986158ad40ffea54c17703fa4b0bd7806633e1c0318d06e8dc7d41cde", "Name": "matter_g1_add_38", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb000000000000000000000000000000000307841cb33e0f188103a83334a828fa864cea09c264d5f4343246f64ab244add4610c9ccd64c001816e5074fe84013f000000000000000000000000000000000e15bbeb6fff7f1435097828f5d64c448bbc800f31a5b7428436dcffd68abc92682f2b01744d7c60540e0cd1b57ab5d4", "Expected": "000000000000000000000000000000000a1b50660ed9120fff1e5c4abb401e4691a09f41780ca188cea4b1c2d77002f08ce28eb1caa41ee3fe73169e3651bb7f00000000000000000000000000000000125439ac3b45c698a98063ab911364bd3c6dd2a69435d00d6edf89fc5566b33038e960a125e5e52141abb605587942fe", "Name": "matter_g1_add_39", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000013866438b089d39de5a3ca2a624d72c241a54cbdcf5b2a67ebdd2db8373b112a814e74662bd52e37748ffbfc21782a5000000000000000000000000000000000d55454a22d5c2ef82611ef9cb6533e2f08668577764afc5bb9b7dfe32abd5d333147774fb1001dd24889775de57d305", "Expected": "000000000000000000000000000000000037b4e8846b423335711ac12f91e2419de772216509d6b9deb9c27fd1c1ee5851b3e032bf3bcac3dd8e93f3dce8a91b00000000000000000000000000000000113a1bf4be1103e858c3be282effafd5e2384f4d1073350f7073b0a415ecf9e7a3bfb55c951c0b2c25c6bab35454ecf0", "Name": "matter_g1_add_40", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f180320000000000000000000000000000000017440fd557df23286da15f9a96bb88cfbc79589b1c157af13baf02c65227dc0a5bdec6f2f300083ff91dae395ed8cb75000000000000000000000000000000000ad09b4290842cc599d346110fdb39ededbb1d651568579564e274465f07b8f77eeaf00fece0c10db69c2125de8ab394", "Expected": "0000000000000000000000000000000007c158b4e21566742f7e4e39a672bd383e27864505acef4ef8c26f8b0a9db418f9c088b555b8e9eb25acf9859b1207b40000000000000000000000000000000016e06a1ace89f992d582af0de7662ef91c0a98f574306f6f6d0d8d5e80166638d2deef70105cce2e9b20faa9d6315510", "Name": "matter_g1_add_41", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f0000000000000000000000000000000000d7ccc3a4efdfe1a92a88e453933b8216016091f1b9d575faf18a5b3abf90daf077813167a3f4acce7359472dee544bb00000000000000000000000000000000128008c075ab176100e755cbb8de5b9ff0e9a78114f862d26ed030d9c1d1dea1c21ec8ae4d82a84d3ff5ae4c1cd6f339", "Expected": "000000000000000000000000000000000b84f9de79c748e37797c629cb78b86b4b736b199f161b30147b5dacf6eabe0b54afce40d5dacfe9a8ee8da5ef5b49de0000000000000000000000000000000010277ad094bb9a3b96379b1366dd90125b51a21ebeb4f776a81d9d9c1f37ab58c32a884a26fa32c83783ed0eef42b820", "Name": "matter_g1_add_42", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e00000000000000000000000000000000008da4a93d5ffcdaa0adc736a59f0c187ae3bf11ecb5e9e6f6aedea976a47757739042200b4c4593c2dd5db555425531000000000000000000000000000000000a6fdb2d4160c6c35223daa6fa10d0b1073de07fe4f2eba28e65ed049ff8d8852ed0538b30759fe7a0d944009ddf9a6f", "Expected": "000000000000000000000000000000000d740bd1effd8674250618af0358ad0b83bbc787f0264af9c2ada72fa5431be909e82155da1de0211f46fb307e9949f0000000000000000000000000000000000ddf62c91d587a14b64feef07da52c081b40fbbf9a0f2eae8b66022e0850fc94de6a467e7e4f580c7f2c806f6c6ed8cf", "Name": "matter_g1_add_43", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d790000000000000000000000000000000003258d7931a1d72ab6344c7e96c0dbd435a7909fe68cc679c08ca9b62f7a6a04863082cbcfdbe9a736625d895e4f3bdb0000000000000000000000000000000009ee3e470e2b2cebc955ba3444b7e478f887138e36c13bd68490689122627269ea5e7ce22dd9c69792394a24187103d6", "Expected": "000000000000000000000000000000000af674691f5d87655f0066188fac5013f31b4169a0181d3feb7ac3beae0d9a3429d4125f099ee344f644a2de8b941f9f00000000000000000000000000000000042a9603b8e4a6c37d59ede3a1398f5f80c5298da66de575a204ee28811d9f7c7c0dd40cef3769bd72a2156b9eb620c8", "Name": "matter_g1_add_44", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e820000000000000000000000000000000001833807f1ced52399305419450355499a63411837ee61ad681559d59561db18511eb1e8ad3161e7fe30016b560d18b8f00000000000000000000000000000000198b11b31586e17964a4a4ccdee85703163d2106481833e71f26327a589bafb43578d08d87f6cb19c7a04b4ca92392bf", "Expected": "000000000000000000000000000000001081c3359a0fadfe7850ce878182859e3dd77028772da7bcac9f6451ac6455739c22627889673db626bbea70aa3648d50000000000000000000000000000000000f4e8766f976fa49a0b05ef3f06f56d92fe6452ff05c3fac455f9c16efadf1b81a44d2921bed73511dda81d6fc7478e", "Name": "matter_g1_add_45", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000007dc719ae9e3f1e11d3ed4747a546a7b973ccb1967adb1b3066645a8bde9632bcfa3530e768f088ddbc022b169e67cbf000000000000000000000000000000000bbf9cf884b19c84045da1cead7dcd9fdbf39d764ff1ad60d83ed1e4fd0ce0554f0fb618203952cf02a7c4ba466c66b8", "Expected": "000000000000000000000000000000000f60d66fd1ed5eb04f9619d6458c522cc49f5ace111aff2b61903b112559972f80ac615591463abf2b944c4f99d4c03e000000000000000000000000000000000001a1abfa869be2cda6bd7e05454a8735e1b638db7e1b3715708539c2d14ade53069c7e68b36d3b08cff80837028b7d", "Name": "matter_g1_add_46", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd0000000000000000000000000000000014b78c66c4acecdd913ba73cc4ab573c64b404a9494d29d4a2ba02393d9b8fdaba47bb7e76d32586df3a00e03ae2896700000000000000000000000000000000025c371cd8b72592a45dc521336a891202c5f96954812b1095ba2ea6bb11aad7b6941a44d68fe9b44e4e5fd06bd541d4", "Expected": "0000000000000000000000000000000015b164c854a2277658f5d08e04887d896a082c6c20895c8809ed4b349da8492d6fa0333ace6059a1f0d37e92ae9bad30000000000000000000000000000000001510d176ddba09ab60bb452188c2705ef154f449bed26abf0255897673a625637b5761355b17676748f67844a61d4e9f", "Name": "matter_g1_add_47", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe900000000000000000000000000000000104ee0990ba4194916f670f44e254200971b67a18ed45b25c17be49df66e4f9b934bac8c1552ecc25bdaa3af55952076000000000000000000000000000000000591094d9d89afe025ca1832d7f3e60444f83e72403a434b42216b6c4213980d29e4ef0c64ae497006de550c1faa9425", "Expected": "0000000000000000000000000000000006db0cc24ffec8aa11aecc43e9b76a418daac51d51f3de437090c1bcaabace19f7f8b5ceb6277d6b32b7f3b239a90c4700000000000000000000000000000000069e01f60ca7468c6b9a247c79d18cf3d88bf5d1d62c76abf9237408edeba05dea744205ac5b501920f519bb847bb711", "Name": "matter_g1_add_48", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a0000000000000000000000000000000004840d028d0c0f056aeb37b7a8505325081e9822ef26046f2da72f2155c20987dd51f4b5577c5395e24288b71d2ce5140000000000000000000000000000000015f231a233e997633c1d6492e0df358fb658ae29d0f53928c8a0578484c899a699178ca3223772210063aa08991c3fff", "Expected": "000000000000000000000000000000000fa72bf2d7d564cc4982b9f2cdca743d2ac14f0f1be4218dbafb8b93a9277e55273487a5d2857fd3f731ac4ee469a6a1000000000000000000000000000000000fce44f886453c6ca5ebde9af41d2be92d1126e9897d72978a179dd7eebeed6242b6e9718604ab0c9369529a0426a575", "Name": "matter_g1_add_49", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece1738220000000000000000000000000000000004877b97faa1d05d61ab65001110bf190d442cabcd6d4d1b9c1f0e513309aebd278f84a80354dfdef875769d00ec2c7500000000000000000000000000000000187066cccb5008bc2ffd0bcd1b227a5a0fe0cd4984316ba3cfd5113c4632a04c56cbda8d48993bd0dd50e9b7ce2b7ee9", "Expected": "0000000000000000000000000000000019ecd38afacc6b281b2515270157328e18039d51574bae0f7e0ef16c3f6da89f55ddee9e3bbb450ad51fe11edfd9f18d00000000000000000000000000000000088a5e292761bbf7a914a9f723de099035e91bd3c1fe9cd50728a4ceaa4fd3953683f30aa8e70ba0eb23919092aa9e22", "Name": "matter_g1_add_50", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000001881f5aba0603b0a256e03e5dc507598dd63682ce80a29e0fa141b2afdadf6168e98221e4ee45d378cee0416baaadc49000000000000000000000000000000000070d255101319dd3a0f8ca3a0856188428c09de15475d6b70d70a405e45ab379a5b1f2e55f84bd7fe5dd12aeedce670", "Expected": "0000000000000000000000000000000011ccd455d5e3eba94567a17bcd777559b4ff1afa66fd6f05f99c69937404290a2f1c83cfd6c2c25886ebff4934332c0e0000000000000000000000000000000010920aa3d5974df25530610ef466adce3d51fd6a508d4b1111739c586dfd7ba9040836e075fd812fe111d92f25b67f51", "Name": "matter_g1_add_51", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf000000000000000000000000000000000b53e5339f25bcd31afd091362874b5042c0b762ed7425341331630addbc4dccc299936e1acdf89823c36867d46c6f28000000000000000000000000000000000fc3c6b522268511dd52826dd1aee707413d925ee51aeb0e5d69c0e3eb697fabbc14783b5007e240cc0c53c299a40ada", "Expected": "00000000000000000000000000000000060773b9b8f3babdba3db27089b7be3e6e287a635dbae19576039d34ae18a0e6413278bfa280570f6329ae05cdb693fd00000000000000000000000000000000075fb9527f99a8c8db41e67baaf1deafffd2c134badb1b3478a26b5501b31dca858fad6f0d52f412d5631ecfa72eece4", "Name": "matter_g1_add_52", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000001693f4ebab3fed548784264196fb01cf55311399f47cdad74a9543bda5d1ca682a00ee04bb0b3954d5a0f00ceef97a750000000000000000000000000000000017f4019c23bd68e84d889857c417b17aa96c780fec3c1ed6ca75100cc70c97a8bb8272ad4c6de896d76dc2a1b09c7a61", "Expected": "000000000000000000000000000000000a3ea8afdc83794f18f9a9427bcd60a355196925d38fdf74ab09d4a08279647b2da6f1fbe30948a785497d6c6dddc2a9000000000000000000000000000000001263c88f1ca3e574cafac21641432d45ee01e1b05eba95716565922abe28c7f0fb004c255afcbfa10cf7959bbe6b00d7", "Name": "matter_g1_add_53", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000005d5602e05499a435effff3812744b582b0cd7c68f1c88faa3c268515c8b14f3c041b8ae322fe526b2406e7c25d84e61000000000000000000000000000000001038eaf49e74e19111e4456ebba01dc4d22c7e23a303d5dec821da832e90a1b07b1a6b8034137f1bfdcddeb58053a170", "Expected": "0000000000000000000000000000000019258ea5023ce73343dcd201ec9be68ec1ee1cb4e5b9964309d801c2bc523343c8ebc4f8393a403c7881e5928f29db14000000000000000000000000000000001423bf52daefb432162ce2bd9ef78b256ff3b24d0a84766b87119489fd56ecf6156b2884c8a7e1220e493469723cd7f8", "Name": "matter_g1_add_54", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000002626f28d421d9d1c28f5e1eb5a51ada9610dbdd62cd33c4078d2fdfc18dbd092e2847cf705ba5fcd8c1a60c1cc34a3b0000000000000000000000000000000001f7b8cfdb7e406c920f5fdecae45fb4be736f209480ccb455f972c6b1a1aebdd5ba116903c46ded72ce37cd8836e871", "Expected": "00000000000000000000000000000000081d674f5b9c7c64673c39fe33f4f3d77271e826dcb4dfd2591062e47c931237e8539ef9c886c9e112eccc50da4f63fd00000000000000000000000000000000141b700695839110ed4ced5f8a3f4fd64a8086805358ab4a5abd2705592e616cd95ff01271212ca9014dcb68d8157ba0", "Name": "matter_g1_add_55", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df91000000000000000000000000000000000259e307eacb1bc45a13811b02a7aeaaf4dc2bb405dcd88069bb6ec1c08a78905516169bd3440a36921764df0ef3a85b000000000000000000000000000000001263372b675124f6cc19ca16842ba069c5697dbf57730875fe72c864a81189d7d16fe126b5d24953a0524f96dbac5183", "Expected": "000000000000000000000000000000001908aa3a640817e31a4213156fbd4fd39ab39eb931091670a0e06399def71a689e67286f90d38ce9f97cb85f6488d9c8000000000000000000000000000000000764e46b6b82aa2f8862d28e9d543a751a9de855645377b9633cc098c2110ec6ed4fd30f0044ea5868c93f950f6cfd24", "Name": "matter_g1_add_56", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000a138203c916cb8425663db3bbff37f239a5745be885784b8e035a4f40c47954c48873f6d5aa06d579e213282fe789fa0000000000000000000000000000000016897b8adbc3a3a0dccd809f7311ba1f84f76e218c58af243c0aa29a1bb150ed719191d1ced802d4372e717c1c97570a", "Expected": "0000000000000000000000000000000004ad79769fd10081ebaaed9e2131de5d8738d9ef143b6d0fa6e106bd82cfd53bbc9fab08c422aa03d03896a0fb2460d0000000000000000000000000000000000bb79356c2d477dfbcb1b0e417df7cb79affbe151c1f03fa60b1372d7d82fd53b2160afdd88be1bf0e9dc99596366055", "Name": "matter_g1_add_57", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e29460000000000000000000000000000000019f60f2cf585bdbc36947f760a15fa16c54cf46435cc5707def410202a3f4fa61b577ab2481e058b0345982d3e3d1666000000000000000000000000000000000a70b7bbc55e1f3e11e9eb7efd79d4e396742de48d911ddff8dd0a7cf10422423d5e68021948e1448e92c2e07c194776", "Expected": "000000000000000000000000000000000a87e7e115ccdf3c2c1a2716491d449c3f8329e73d264088f4af444d43cf05f8be0410da273ce7eeb32969830195b7e70000000000000000000000000000000010a973d6e4bd85105bf311eb0dcfdc0a5d38dba1c099206b60f2e2df4791fd58846bf19d83769506e1561212920b4895", "Name": "matter_g1_add_58", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000109bd6e0636a7f96ffe2ce8e109171efaacfcd60189c7050259ddedd15dd257e11f2585bbd84e4a3f4d8fc5fbc0289cf0000000000000000000000000000000019b420d778da53aed81b48f2c9b9eb399e771edd5e124a41577452b409ca2503e2798cd25d791f489352fc7b7268ae23", "Expected": "00000000000000000000000000000000162bd29f2de10002c1c446bd9583e89751fb91703ad564e7951d41673e28d214729aa9b4b9875c397989df197c912d5f0000000000000000000000000000000004d393181871c93714afab6c33c16f68ec391fbfcad606ac65cc1d070949c099e21f710e2fe0dd4e4f50f99ea2167a7e", "Name": "matter_g1_add_59", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000012bb529b45ad7875784b62a7281d025002f15e7f86cc33555e7472df60da2cb15d37c8bf628142818c0711ee9047fb4d000000000000000000000000000000000baa801623312d95e2b51ce86373fea516007e468f265d974c2327c1779830db180bed6dbe8a64f0959aad26eaafb8d9", "Expected": "0000000000000000000000000000000010c4b328d264893099d89ba81b0765d0642bf36b0ac043be090c7b4f7987d21a906228c3c208c4ec5123d577efb0771f0000000000000000000000000000000016d08ce3bf755da7d4bae5f4b06b37845c17a717329c547e941be93325a04e9a5095d3f6e6c6f9ec3b1a740f59d88919", "Name": "matter_g1_add_60", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000002c9e50f37ff0db2676637be8a6275fce7948ae700df1e9e6a0861a8af942b6032cca2c3be8b8d95d4b4b36171b4b0d400000000000000000000000000000000050f1a9b2416bbda35bac9c8fdd4a91c12e7ee8e035973f79bd35e418fd88fa603761e2b36736c13f1d7a582984bd15e", "Expected": "000000000000000000000000000000000f798f8d5c21cbce7e9cfcbb708c3800bf5c22773ec5b44590cdbb6f720ccddf05a9f5d5e6a51f704f7c295c291df29f000000000000000000000000000000001483903fde5a968dba6924dfac3933cd39f757e2f89120f4ca9d03aaaf9e18252bdb5c5d3939471666b8a42aeb31b4ed", "Name": "matter_g1_add_61", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec000000000000000000000000000000000332cdc97c1611c043dac5fd0014cfeaee4879fee3f1ad36cddf43d76162108e2dc71f181407171da0ceec4165bcd9760000000000000000000000000000000015b96a13732a726bad5860446a8f7e3f40458e865229bd924181aa671d16b2df2171669a3faa3977f0ee27920a2c5270", "Expected": "0000000000000000000000000000000001c762175f885a8d7cb0be11866bd370c97fb50d4277ab15b5531dacd08da0145e037d82be3a46a4ee4116305b807de6000000000000000000000000000000000bb6c4065723eaf84d432c9fde8ce05f80de7fe3baed26cf9d1662939baac9320da69c7fe956acdd085f725178fe1b97", "Name": "matter_g1_add_62", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c50000000000000000000000000000000003ebca978ea429eedad3a2c782816929724fc7529fbf78ea5738f2ca049aab56c1773f625df2698433d55db7f5fc8ca2000000000000000000000000000000000d2477f57b21ed471a40566f99b7c2d84ce6b82eaf83a6c87a7c21f3242959c8423d4113b7fd8449277b363303bb17b0", "Expected": "00000000000000000000000000000000071dc0f985703bd8335093779de651b524c02faca5fc967766abd3f6f59176d2046d7a14d18c0b757b8c9802e44ebcd300000000000000000000000000000000154e5cb66be8979ee276e8e0f240557e3f7dc074c497293af589256652da21d66a6e6b00ca5bfa6f89963fbd5bc6cf48", "Name": "matter_g1_add_63", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001461afe277bf0e1754c12a8aabbe60262758941281f23496c2eeb714f8c01fd3793faf15139ae173be6c3ff5d534d2bc00000000000000000000000000000000148ad14901be55baa302fa166e5d81cc741d67a98a7052618d77294c12aea56e2d04b7e497662debc714096c433e844e", "Expected": "0000000000000000000000000000000012c4dd169f55dfb5634bc4866f7cbd110648b5392ace6042b5f64aba3278f24085227521b7834864f00d01ec9998dd6800000000000000000000000000000000102d7a495850195424677853da01d70caeb6c0af5270bcfffbc2d4252c0f3680518cd8d2a0a6dbbbc7b52923a5b26562", "Name": "matter_g1_add_64", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002218b4498c91e0fe66417fe835e03c2896d858a10338e92a461c9d76bcecd66df209771ae02c7dcace119596018f83c000000000000000000000000000000001990233c0bae1c21ba9b0e18e09b03aeb3680539c2b2ef8c9a95a3e94cf6e7c344730bf7a499d0f9f1b77345926fef2d", "Expected": "0000000000000000000000000000000010c50bd0f5169ebd65ee1f9cd2341fa18dd5254b33d2f7da0c644327677fe99b5d655dd5bfdb705b50d4df9cfce33d1400000000000000000000000000000000088e47ffbbc80c69ec3c5f2abe644a483f62df3e7c17aa2ff025553d1aaf3c884a44506eff069f4c41d622df84bbafa1", "Name": "matter_g1_add_65", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f7000000000000000000000000000000000160e0f540d64a3cedba9cf1e97b727be716bbfa97fbf980686c86e086833dc7a3028758be237de7be488e1c1c368fe100000000000000000000000000000000108250b265bd78f5e52f14ef11515d80af71e4d201389693a5c3ef202cf9d974628421d73666ead30481547582f7abaf", "Expected": "00000000000000000000000000000000168af33c85ae6e650375ed29b91218198edd9135683f6a1428211acdcbf16bdf86f0a95575e47ee0969587a10fa9f3c90000000000000000000000000000000012d9f5d692c870b3da951b6d07797c186a8ddc89b9f08a1c0b8f0f119f10ca0b155e8df5424cf48900ad3bf09ce6872a", "Name": "matter_g1_add_66", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d20000000000000000000000000000000002fa19b32a825608ab46b5c681c16ae23ebefd804bb06079059e3f2c7686fe1a74c9406f8581d29ff78f39221d995bfd000000000000000000000000000000000b41ea8a18c64de43301320eaf52d923a1f1d36812c92c6e8b34420eff031e05a037eed47b9fe701fd6a03eb045f2ca7", "Expected": "000000000000000000000000000000000b99587f721a490b503a973591b2bb76152919269d80347aeba85d2912b864a3f67b868c34aee834ecc8cd82ac1373db0000000000000000000000000000000007767bb0ca3047eee40b83bf14d444e63d98e9fc6c4121bdf04ea7148bcfaf3819b70dcebd9a941134e5c649da8f8d80", "Name": "matter_g1_add_67", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000002a540b681a6113a54249c0bbb47faf7c79e8da746260f71fbf83e60f18c17e5d6c8a7474badafee646fe74217a86ca4000000000000000000000000000000000fe2db7736129b35dc4958ffd0de7115359857fb9480b03a751c4fceb9ae1b2b05855398badffc517ae52c67f6394e2a", "Expected": "000000000000000000000000000000000bc719a8397a035fc3587d32d7ef4b4cfd63d4a5619ab78301d59659208f86df9e247e5d12650acc51a3bca3827063a900000000000000000000000000000000150d5519380a65b1909b0d84da374484675d99b00b254d03e423e634a012b286e3fe074e9b0a7bb24ff52d327249a01b", "Name": "matter_g1_add_68", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e787900000000000000000000000000000000019d917eb431ce0c066f80742fe7b48f5e008cffa55ee5d02a2a585cc7a105a32bbf47bdff44f8a855ade38184a8279e0000000000000000000000000000000012ee762e29d91a4fc70bc7a2fb296a1dcdd05c90368286cca352b3d5fffc76e3b838e14ea005773c461075beddf414d8", "Expected": "0000000000000000000000000000000008197403ab10f32d873974c937ef4c27fbdb0f505c4df8ac96504705d4851cf951fb0263335e477063884527b21edf160000000000000000000000000000000005396f1affa20ca8530b519a4d5d400969f0c8c8731ecc0944e8086388e89a7ff7c16d9a2a90780972c4762b88a0f0af", "Name": "matter_g1_add_69", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000d280fe0b8297311751de20adf5e2d9e97f0c1bfe0cd430514cfddbafd5cdcb8c61bd8af4176cc3394f51f2de64b152400000000000000000000000000000000039f511e890187f28c7a0b2bd695ae665e89b0544c325a44b9109da52cc6908d81e1a27163a353ab275d683860c2e007", "Expected": "0000000000000000000000000000000002baea63055f72646189bdd133153dd83026f95afad5ce2cffbee3f74c8d47d5480094b2b58b0936c78aa33cd9a8f72f0000000000000000000000000000000013e600456a2d76f5a760059e0ba987b881c6bc10d6161f388d7a9d8b2031921054edfec46afbd80b1364d8e8f6a5a7a2", "Name": "matter_g1_add_70", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000015bad24d12b5d68558e961a17dbc3e1686e1b918e6192ebe6f3f71c925177e61d0162e018ac81126099effa0cadfa185000000000000000000000000000000000de73182569184b3d79dcfa8c27f46ec7a31fe8a3fd73fe26eec37a088461192bdbcf4d4b37b33b6177d6fde015d1631", "Expected": "000000000000000000000000000000000ced641c930387432d512861eefbf2d6131017154f99a0d3d24da880dfd2aaae91c2d9634053fab8b85fc11a7884d30600000000000000000000000000000000122071c0e87fae5031c850dccc4777c3ec9d8463bbc4ed84364d4261bc9d38f696a4320d53eea926a75ed9fcc9789a07", "Name": "matter_g1_add_71", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b256730000000000000000000000000000000015cdf7dafedce64aba34e1f18c57b28f297629c07ee96b732029b545cf5ea6afdf926daa6a48d1250c67aa2a8b797d370000000000000000000000000000000004867352f86267dbe8e32806e4ed02f1487e036051068f8e06d02e8dea6d3773b422e065d2db27c89ea69246d0185351", "Expected": "000000000000000000000000000000000e2c633351d627a075acd1e373bec96ba41b047f0307201f4b7c9978c1a72243d0b18113604cc421b8f66d76ec9b1360000000000000000000000000000000000844e258d602bf9aaa35ce46c4c91c80dd9337053d8ab22c1163a0571fcd1488a2ef57476e2b66dd9c26963b28284d11", "Name": "matter_g1_add_72", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000077eb801bcde78e9dd73b58d2429a907ea0f5600a8005093d471be373bba23ea70bf828c766ccced6a46db84b440053f00000000000000000000000000000000101af9df2939089d72e42fe2dc3de3e32be8f4526a2263ebd872d0080ed4a152107bb3d2f56176bf72d5ae8bd0c30a3f", "Expected": "0000000000000000000000000000000010205c6be10a5fc5390b0e5ae47a8a822c8e9a7a96f113d081cde477ec0de7bf0e8385e61780b2335e4297edb35bcc6d000000000000000000000000000000001796af180463ed70cf330791c8201ee3f0fe52993f64819291bda33017285fcc3a515669b3d48a411276c849fa021f6f", "Name": "matter_g1_add_73", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a0000000000000000000000000000000019b09bb7dddd11c5d0e304dac120b920601dd3a3505e478c88850cc701c17eb02aa7bfb20e4017a62fc4fb544d4f9e8f00000000000000000000000000000000048ad536cf89576d4cce83ef065bc16c47f1a28ae27bd71d30d8f2177a9c6f8b2ed0cdf872ead71bc5a1252bccb4a7e0", "Expected": "000000000000000000000000000000000fb047098a1996a625cd19021f81ea79895e038756878d8772aaee9b6bbb66930e474dcc04579ad58f4877b742a890900000000000000000000000000000000017da74a4caefc55794a36eda7938371f42265cc1f2d87d41883152db82873daeb59642e8e663afddd4f24536a1f52b3f", "Name": "matter_g1_add_74", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa30000000000000000000000000000000005f84f9afa2a4a80ea1be03770cb26ac94bec65cf9cb3412a07683df41bb267c2b561b744b34779635218527484633e30000000000000000000000000000000013ce1d1764961d1b0dff236c1f64eabec2ce5a8526edf6b0bccb9ea412e5a91880db24510435cf297fcc1b774b318b65", "Expected": "000000000000000000000000000000000f4ca788dc52b7c8c0cb3419ab62c26db9fb434321fc6830837333c2bb53b9f31138eecccc3c33461297f99a810e24ad0000000000000000000000000000000006785d4f9cdf42264c00fdc4452883b9050eb56e2f6e46c7b8fc8d937dfe4d3ad5072d969a47c4811b36d3887256d0b9", "Name": "matter_g1_add_75", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000f0dd7a15dfc39dc2df47cf09761498b0b363157d8443356e768567f5a6d5913c2a67f12d93df2dcf50756bb686836b100000000000000000000000000000000055914dbda5b115222e738d94fbd430440c99bcc6d2c6cf7225c77756ffadf765b2d83447d395e876b5f6134563ed914", "Expected": "000000000000000000000000000000000ac0f0f62202d09cede55ca77b7344b46fd831b41015eb357cac07f0fa49c2564c2e9d5c591630226677446a9100757c000000000000000000000000000000000ca21d0128ef933fc1a48c1b4967f56912513e63a416d86ad40c0a4590b2edf88e4e8a286338b8b176d8b341ea480277", "Name": "matter_g1_add_76", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb211000000000000000000000000000000000a6ff5f01a97c0f3c89ac0a460861dc9040f00693bfae22d81ea9a46b6c570436f0688ed0deef5cdcc5e2142f195b5c000000000000000000000000000000000193a17880edffe5b2ebedf0dc25e479cac3b136db9b6b24009ea0a9ca526d6dd9714d10d64c999d4334baa081b9f2fbe", "Expected": "000000000000000000000000000000000b728d4ae4b45fae9a9e242524e95e44f175356726da50f46236f690eec17fdd5edce5df1253383378dc8f9c1fee98ae00000000000000000000000000000000131d28a5eab968c45ddc86b82f220dcdeab7c009c7c61986ee4e55045c024e1bcbe76a4e35000b5699ccec5858ba427e", "Name": "matter_g1_add_77", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a000000000000000000000000000000000b35fcf625cde78fba1b70904acb97d7eb449d968e8013855d44292e9c3b0df3cfbcace6f292ec3c7717e25490bb4c67000000000000000000000000000000000af57abd87df55034c32dbe68bd1c0b47139fc2c3a8887b7c151e57b57c9002070337c8dcb2ce2687f9f007d48dd68c1", "Expected": "00000000000000000000000000000000178a19966b5b0fa70c138be7f5ea51d5399c7b8dcc5171cbef82ecb1451aeccbd1ed29170a27f404ebf6daa2ec99bd69000000000000000000000000000000000b1b748494806175030f6b5e2977c58982bd6ec6662d69237f0521351653c772a40035f2504ac8949fb448a901379fd6", "Name": "matter_g1_add_78", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b00000000000000000000000000000000177a51fcc81580ccb7a8873fa93eaf860ca8fedde13cdf3eb53f11e66a1c1e934b82ee9251f711c5c479f33a22770c47000000000000000000000000000000000a0edc9a58f4bb414aa0aeec7bfa6076fb62bdbaee987192c18855adf4e813e7103b943e1dddc24754acfa90600a5750", "Expected": "0000000000000000000000000000000019195049a2d457709e284c84c72a211224efc4d7d46d25c9a537eea94149b06506df02a2a4e0a6428263e9605eaaacb500000000000000000000000000000000061139f9a70ce7cd87ed3a701163bde247382295f557b47a3a0a880d2780f015e8ac753eb3243f9ad138f92c3a2257c5", "Name": "matter_g1_add_79", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d000000000000000000000000000000001552982822e0b64a6204b27da0e192873bb5bd2997784ff0b6ed53801b402501a665c17f0a379fd946ab1adfae43c6af000000000000000000000000000000000938359655fe135dd2a390f83e27273feb68387ba94f2b6f7c15389f8272d64231ebe9c8271de90ff2358d935359ba85", "Expected": "00000000000000000000000000000000168f958a40e85341d90012e134976d1a5839e807948410cc0c81a50961552c052bb784c50da4c734f6aa583777c22b28000000000000000000000000000000000d26998bac6ec11bc5fcf6fe7262c984d6500cd5b21af979048b940e20054f8d759f8a011f3e09d01d10f9cf8ab150e1", "Name": "matter_g1_add_80", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d50000000000000000000000000000000000d94885dcc21b0b98821b6861a4d094e9eb5d5adcf7ca4275c5b759abbf9a9910f3b38073183d54a0569ecbbc1e9826400000000000000000000000000000000034a54b4bbb3f128608a866f5f5c554cf6ad7899f6650ca663a5bd5f1a3e4471e35a2440644c0e4e0a56080936b46d12", "Expected": "000000000000000000000000000000000d4734ab1bbcf9e30cf142a7aa9e8cde1b3c88d92397b8d7d48c7a7402561feee58a810abf67776e1890489efe7f8ec20000000000000000000000000000000005be9e4af0c0c183c43601339f162345f7c013f5941167cd925057e91c4641e19091a20123a36f2e803142833c0bc1ef", "Name": "matter_g1_add_81", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000014f16cbb17e7f63284d8a75968a4c8fc8ee7f37233ed656d696477c507c23e7c7eaf54001f44c93deb14c298aa6f94c00000000000000000000000000000000169bde83e861889c50b2138c76531a5866235d515a6fee4da7aaf8e8b903f2848a9fe7bbd55eac7f1c58ce3a88e7249d", "Expected": "000000000000000000000000000000001400f774b2d932c6b990da6e1b3493685e8f51d429e0c53e9af1b4a2d3876781b790bca4a1bc28ce0240ea21be24a2350000000000000000000000000000000004993fcf5723b7e02095d4ba73ff3194bbe36027bc9099b57084c91c7e7d50b76331bfb06d3c678d3e401bc3f7fcc577", "Name": "matter_g1_add_82", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000009acc4b4678b4b645fde47d1b75a5dda8caf6696ad2bf312dd5c12d7f3ab50b95152f5fe59842650c8a1a785f345c3ab000000000000000000000000000000000b672989004fe54f4d645e40cd29a21418151134fd2b90a68185040ceff141ced7f7ece1fdd9137c32589fa04b105a0e", "Expected": "000000000000000000000000000000000fcb0ab180a69b0a230d9dba98099fdce4969f82fc7e7ad93352a7c8dd448bb0ba9c7d62f53d5dc80506bc36190d9bc700000000000000000000000000000000047b7306f4a53c21d42993c50f2365486d02dac495f2dee4f8971a4af308396fce6c90f3cfde857bf7a2c6bf5d0d8aa7", "Name": "matter_g1_add_83", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f6000000000000000000000000000000000198e12ade128447a240e03e024183c401d605cab1ed81f0f5bb7bc4c7cc9c889a2a01f59c0e37a0767a927719e5a95d000000000000000000000000000000001946e39fee9b76ce552108b339b9b24d11e43d3275ac19d2d4bc745c409bdc3f7c473a60c4d3a4d2cc3b598ae0d66880", "Expected": "00000000000000000000000000000000050b45f896fa40099cda8b1f20ab88644915c16f926589cd709e00149b12922347fa7122175424cd44e8875f217b9ad7000000000000000000000000000000001122b7e9b1509efe5616368b14085bdd36fb7adb85cd5a7f23e327548986f5298c045a602b6ee1265d53a4432a4a3c0e", "Name": "matter_g1_add_84", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac47388620000000000000000000000000000000009c48aa2681b3005b24075bb3a122ac100cbaca872f761f4398edaba9dd9da6d04d4a4925028297dfe5f77c2b0b5c821000000000000000000000000000000000ea95c646fb68aa458e69c267a6ca640a6a24d40bdca0161246e4521d13c46facfc1ac86dfc0a804cfa6665cebeec822", "Expected": "0000000000000000000000000000000005325a499aec678ada9eb673d366fe0475e885d5188e2fb687a96949e8f782852fba962197976b868ec083c512bfb66b000000000000000000000000000000000c4d6fcacc8d82401882bee355b37930d83e3cea2e4a7bc133e65a3e0af919b25fc3f30c333873da9406845ce42dbb87", "Name": "matter_g1_add_85", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae80000000000000000000000000000000008e8799a6cc0339e94e861692c81eee53e8a7b326523d5344b416bfbce04290585ef56018834cfd93d234bfa2943369f000000000000000000000000000000000fa1b01aab0878adad693ec769fb68640931c355b3802c51d4a3772300be5b16ceecdc8328a229b3b9f3639170db96f8", "Expected": "000000000000000000000000000000000685ec14da61c48bcb697966aca9e27601db43f0fb1f32e026fb33738eecfbb7012aa1ca3acf36a21fa846730245add70000000000000000000000000000000003fc52a1c3342b12271bbc178545bb20e96e8f1fde673e51f3d27ab5cb42e60aca49c6077e0f687be59b2d25cda9718e", "Name": "matter_g1_add_86", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000bb3a76287fb98fe668cb0a5de603c768340ee6b7f9f686a22da3a86926d8734d2c565c41f94f08fa3ef0e665f4ccb520000000000000000000000000000000016c02dbfb307c96d5b9c144672fe62f3e9cd78991844f246945ee484cbdef2a4c1b001a017cafb3acc57b35f7c08dc44", "Expected": "00000000000000000000000000000000021796fd6ef624eed7049b8a5c50415cc86104b2367f2966eb3a9f5b7c4833b9470ef558457426f87756d526d94d8dfe000000000000000000000000000000000f492dca3f0a89102b503d7a7d5b197946348e195954d23b8ab9ab7704b3bccecaa2123b8386662f95cd4cfdbbb7a64d", "Name": "matter_g1_add_87", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f00000000000000000000000000000000127420ff97df415e336cf3e24c39c161fad630c45c7ccef80f1831c4f5ed54da12f2c49a161e72bc70285fa0498e46d00000000000000000000000000000000013e605c21014f72364f8bff392ce64a10078ea537237fa282d5dd252ba1677b84b8c15d7925e54a4ab36f1feb13d3064", "Expected": "000000000000000000000000000000000ae916770455b0a63717e81802f5a7fcfbcc3e260b7adeca02a61a520c338d495eea29c4f070fd6efc1b8d23eb285e4c00000000000000000000000000000000134784e092744df573ba78f7d6f3cf1ed19491a0fc7ddfa02d3ca043bcf102fd40c33ac44b03a947308e3cc7af41c2df", "Name": "matter_g1_add_88", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab40000000000000000000000000000000016f41e8b098839944adc12481e5f965657a4faedd4f4cdea51a9597a6a0356989e791a686d3d2ee6232ab93683259c6b000000000000000000000000000000000d27b4a56b2cc2216e61eb41061f9a586a704652704906f7fe0eab869ba00d34205ea66f7a02d337d08b916598494e52", "Expected": "0000000000000000000000000000000012842c9d7f4309f6e40124a071d317f5597de419db0d5a8e5324a517f7b61dfdeea2fb4503ad7cdd8deb8aaa5c412554000000000000000000000000000000000ace4d9f98ee6e8a4416ef14d64f26dc49e102e69eced46ef829a352e58e8c1a7e1f083e3f4fc07f24ccd1685dedf215", "Name": "matter_g1_add_89", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000019e7c8d182e3b674dfa21539613f7de5d4872d4f4732307a5c6d95ada7e81a01bc25bda34e0b46634e0b0b32cd47e8ec0000000000000000000000000000000008149237de73ab46d5c20dfd85b07f593c0caf2e2e364335450e3ebb478a9f6b9ac0af89174dffd92eda2783a5271f01", "Expected": "000000000000000000000000000000000875289fdaead079a283aafe4de7035c88662642b6bba389b17583f8e3b5801dada6e46bd897af961997665e6ed4a55700000000000000000000000000000000050a6b9c1db35865df0a042d27a042ff4b8d3bec2fba6a3a28a71c5a574620dc05cda0e70932ce9b8966e4592220c147", "Name": "matter_g1_add_90", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a6000000000000000000000000000000000c0f33f2d76366af661d6fa58a8b5aab207d35ce03899e495f7ddccedf201d9816f270468b207413a2ca70380c798fc60000000000000000000000000000000002a7dc7e2b163e65cadf93b5d682982288c8f36d08b1db8e0b1cb40cd3c7231f3f1672da42b4679f35db2076a8de5b42", "Expected": "0000000000000000000000000000000019ea92820dcd442358db359146797aa82beff6154946b1ea14dccae05e8252b776b817dc044a20764e3514cd22799c0b000000000000000000000000000000000ed929fef2cb11e8b6b9b5d52bfde82080eda747f0c82f33b9cb87019476f0c128e6b918a4486172dee2884ba538ae5d", "Name": "matter_g1_add_91", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000118fb45274a6b0ca9fe2654821e3b30caa46444f7c64b1921cf16dfd56a43916947d4fb6968d718a59a30ed38d65ce3000000000000000000000000000000000110e8e73e640bbea6927cd770baaf887c8e0e0c58260bca489c39b6dd7a24ab8c0c0a2495133d8ff8c7afb9790b37faa", "Expected": "0000000000000000000000000000000009452bd0a167683e30c673ffd4e750c66a81edf309a8d2d6dd915c358b30b0ffc001c4165b1b17bf157a0f966bfd91d00000000000000000000000000000000015df0b1ee359dd3e35a7b2c33edbb8e92b18804ae3359a369c6a529f5561298e6be9a3498c9477f33353124af7e91968", "Name": "matter_g1_add_92", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000005dcb54cdf9635db275540c16307fc9f07b4ca5cd91e3977e4b95b58e8103e40ed9fa74752b2a43d95b6acb6f5fcbf440000000000000000000000000000000007ef8457752a47864ef2698176a53990e4822421ecf83b2716251e3ce69151ab2767d4a6611a0a6e0e40a57164ffb94e", "Expected": "0000000000000000000000000000000011f1ac702a06699dd64b63ebdd8b5381578f63b603c63c3a47413fe764af239ab7024712320f3ea3daefa6bd3cd3dfe9000000000000000000000000000000000918bb83a22b4fc66247e007c17155c4c2ec6326131c10fe04a5f9b82ddeca3d21c7c397a70a3949fda4d766540c85ff", "Name": "matter_g1_add_93", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c35850000000000000000000000000000000006d3335e092616363e94436bb68be89667c706564ba687f4a3494fcf7da62fd9ad8ae68cb76524926c261983711a14ad000000000000000000000000000000000f085a3d013592c402a380e2e8d9019864a775e7b8e8b94603c8cc1eb1def1e91075fd5675f76534397e2a7d76c2331e", "Expected": "000000000000000000000000000000000344951ccb5e60d1838f7793fcf8b765f5f252b69e1cfdb4bd3c20692c8ffa01afbda6950974a65f6ac74afb9da5942e0000000000000000000000000000000014f5f0e6b99a04d1c5c2adf96c53dd41f8c01aab8db4f0e6d7fc5eab27f6c03c429632db4e1c21467c09d8a54066a4d3", "Name": "matter_g1_add_94", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b0000000000000000000000000000000019e2ed6e9757e2339d013078fac91c966045f7a1416a56135d75e603c2021a8bebf4acbf6c0d5ba911f66510e9a7ad1a0000000000000000000000000000000008b8585444ffb3bd4fb6ee23e8128142aa72fd574a506151a0eea8979cbd694e03897caba63771b0490d46063bc5bb57", "Expected": "000000000000000000000000000000000a449fb0da911c544887b24860bc5fcaaf054041cc80f16bbb44c796520bee454d0d06f84fd5aa179a44fd4fac9f144a000000000000000000000000000000000fca81401349089caaef9156a86c64271c77235c9efd136dcfad9894450b076cb3dd1a05bfa1e62ef904435eee5d2250", "Name": "matter_g1_add_95", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b767f399e4ebea34fd6b6b7f32a77f4a36841a12fc79e68910a963175d28cb634eeb8dc6e0533c662223c36b728cce2000000000000000000000000000000000cb3827fd6ac2c84f24f64789adac53439b4eba89409e12fbca0917faa6b7109aa831d16ca03191a124738228095ed65000000000000000000000000000000000f4a256b4288386545957a3ba28278c0ce69a8a412febfed1f952ca13e673822bacb6b7751ea75893b680ea363aab66400000000000000000000000000000000152379d006e74798199f83b0c6c22a98440ef653d7f0a8c5e3026bcdabec8be59a3cc291ba05860bd0639c5c5f5bee26", "Expected": "000000000000000000000000000000000c427721953e139d4f12ad2a3f8f91a4caa49875a87001b619c8a6e909a7da8ddd9dd026bf56d5f85d49fd17527106a800000000000000000000000000000000018add2816914ef51a289e707ba0224fcf0b7bcfa4001487e90dbdce53f1b596e1f5872de32fcee6f63bce4484ccbef7", "Name": "matter_g1_add_96", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150b75e9e9c03ada40b607f3d648bd6c40269aba3a1a992986dc005c9fde80bb1605266add0819641a0ca702d67bceed00000000000000000000000000000000083b43df032654f2dce90c8049ae4872a39f9cd860f08512930f43898e0f1e5625a5620818788797f3ca68134bc27d220000000000000000000000000000000012dae9aee13ed6ad52fe664bf7d2d0a1f134f0951d0d7ce5184e223bde164f6860967f9aaaa44fa6654d77d026c52d2a000000000000000000000000000000000f71889d64ec2f7da7319994883eb8bd1c753e6cdd3495036b630c35f07118a1bc10568c411ecbdf468a9cdaa9b4811b", "Expected": "000000000000000000000000000000000275b8efb3a3e43e2a24d0cda238154520f0a2b265f168bfc502b9cd4a07b930756961ae7e4fe3f01a5473d36ce3356200000000000000000000000000000000113403d5a968f01ba127dd8ef6c8d7b783a10d039a6b69c617032eba7122e9297f3ce2360c829ae64fdc9794695bf173", "Name": "matter_g1_add_97", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cba419694214e95a3605a9b748854d16c8e6e1ee151c907487d8189acfac1361b790a5e78f43593152027295adf8df400000000000000000000000000000000110813ff6e0ddf3427e2a514d3f0bfbadcaf9dbf039e0f93fb9643d1e62bc2469fe84cd9ff0d585bdd1037255bbe54850000000000000000000000000000000004e9dd69012ab596b5d3f1f8e4593b448685fcec4ab3394008178b137b762ddf9150cbb8dbb74c8af45bd8baab9a6c4f000000000000000000000000000000001132b66a2127885774062732127951f051c9c3c9b5aba02406e3f3cd4ecfe2dbf6614ebaca3bfe9efbe4f6e5b15ba0f5", "Expected": "000000000000000000000000000000000594c808954bb930bd038806500c9e3fd6460a83554e945baeeec2354a3805f046c76aea62c249080f16ae8e70f8fa6b00000000000000000000000000000000046924a32fb3f2df9a52615e45eeea2fa3ac0e2ccd38458194ada6b4d993ecdc0f441e41d0ea37599254a06aef68b9ae", "Name": "matter_g1_add_98", - "Gas": 600, + "Gas": 500, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b50000000000000000000000000000000017a81b957a12adf474a2913e8636f169ea9cd10be62c16b88f95f5caf661f158a032a9f7d249fdf2765caa1564bed0570000000000000000000000000000000017fbf2abc62dc2678b65d509e19c9c9c5d961c72565649a078da8dff98be6236ef314e9ff8022f639ff565353345c230", "Expected": "00000000000000000000000000000000002c8bc5f39b2c9fea01372429e92a9c945fad152da67174f4e478fdead734d50f6e2da867c235f1f2f11bdfee67d2a7000000000000000000000000000000000c1dd27aad9f5d48c4824da3071daedf0c7a0e2a0b0ed39c50c9d25e61334a9c96765e049542ccaa00e0eccb316eec08", "Name": "matter_g1_add_99", - "Gas": 600, + "Gas": 500, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/blsG1MultiExp.json b/core/vm/testdata/precompiles/blsG1MultiExp.json index 62b91f6f4d..b708f3c0a6 100644 --- a/core/vm/testdata/precompiles/blsG1MultiExp.json +++ b/core/vm/testdata/precompiles/blsG1MultiExp.json @@ -719,5 +719,271 @@ "Name": "matter_g1_multiexp_99", "Gas": 64128, "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000002c7919b322a84cb1e6164043d745a53535edad9ef74533d3155900d4e1d63674b2616d87ca8b3dac6def99441cf196c00000000000000000000000000000000069f2ddefcadf0463b0c40e389837d1079781e04ccd8262623d5df6fb1989973ef6fcb8628b978a088e4f043f54d54391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000012ae6bd01e522bdc8854237da1cff327a09d34683811398bb58a45b5672fc93aea9903e14edaa4a6af3b2b58db051c3000000000000000000000000000000000abb87e947116b3d95dfcde9327f0711ea7dc52cc16c056faf0a325e36955efe4da65c9c8ee9a89b60fac7fafaf49c85", + "Name": "g1msm-1-jwasinger", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000044c8141f453400b5eaecd905a163ff950775a1a147e68eaccff25dff1d77c0fe9b2abf8311cf04993a615c1209a2a20000000000000000000000000000000000e6728c19f90dcbb3477112effe8bc4d65eff34814c2945170c7843d72702b90a1d97adc9a1a857e95f69a9ce56d2d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015011119f24cc9325aa4b578d9fa3430ccba523ca0bf0359b221b172afa32a8c80135bce8e04cb774f3cd04999409cff0000000000000000000000000000000012978dda7d55bca7498a4c797bec5d170cbc90f739b1e20985262d422ea154ff35cf5c71bc23791efb5148fbdc47d63f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000179c5193a1eec7522458270c65d4fefe0cf72774498687925a47b21e7060975d02de34832fb709ae8ce98b396a9b8eb00000000000000000000000000000000004d522468140afde2f3d40841e020b0b240a817ff4ee1cfd13c62497f0d9446132dd5c0f36ba226a397721ba4a6e7be6", + "Name": "g1msm-2-jwasinger", + "Gas": 21312, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000002aa3a1c6386bc21eeac062fbe70da8f9079003a574805cf997d0f08332dc3dccc22d1ccfd81d29178b5aa01bd803bb50000000000000000000000000000000011954af068b6e7b16ff453bf139793eb909c438237339eecf79daa48d9f9a84b3732e6ada9e1fe1ef96081f3015a39541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005125a08621bff979dd62adeea6e90adf736f2e70141adbe90c01eeab94e2929cddc80d1ccc3ff186a582d79e33e22c40000000000000000000000000000000007cb53875e527241ce7d2770c949bf188dbbd7babbd14fa26f9b5ac59fe13c6e2a1d667a8315e9612297e764e1428e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066aeb84c4d25bbaf0e73d578b1d155092d4d02b75602b92ad1a8b2300a1c00389ada213ee3783d8d7c1814ba4349040000000000000000000000000000000000791699767760030bea023b1cc91edc9773ad9921fdc7a1e404504ad29260bfa3376f894fff311fc0acc3a1c2f04ca541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000010870702934c1136e6c4318a49b9b0ee08aaa292732ac268a49defe1ff4b5214104341e13de106456bd2c707f69c0b48000000000000000000000000000000001294117a4266ece3fe724937ecba3d967c90adbfd2f6605ae3b339e0c38c8b58bba5effec32cd9d69b0cecba57d17015", + "Name": "g1msm-3-jwasinger", + "Gas": 27504, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000b37533d0cda25930ea84e22c2230909934eeb4e79b9852dda61c1a0c69f3319e62a5e13c60d18ee669d041d51c22f66000000000000000000000000000000000ee646d305d99b163a19ee00840178ad7ac7e45a5eb835ce05392b91488e67134196fec73928bfdd90870ffd9e94468f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f278dfbf249949bb514f3498727173a6cbc4aa6e11df04ea2f3bada502d42a35791ca308fa1fb5d8083e0cf439ae21000000000000000000000000000000000851116ebe6e0e0fcb7ef115ebe78625e9d3a4e4a12a484edfc4da17ca15e53c4f1b3e72248b335d379d4f3d0186e6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040357c69d7eb9f119f5251ae29490b2f01d3c5cb8e00db82b955cd55a498c1c6e380866b7ea02c9511beaf506fdb17000000000000000000000000000000001329d35a79127fc02f35e82388b86a0faffd3edee776406107c9f67554f980fd6710147f824e863da461c1e7033d79171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fe52e1443ea05bf9476cdd5e80f36740071113800b57cb9214046e2624a7718307e2ff6252a6434e93e5af6b4129900000000000000000000000000000000016709f07278a749668d8f08f29d460a753ec56c2a66825df0760d2ff7a0a4cba14e4354cac8bf0dc967b698bcf49ea9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000ebbd670bc84bffe83659958ca5a3220517b9468cc7de5aca79be564e30f0a4ad3a01e44c79e63d8342dea2b3f1c9be20000000000000000000000000000000012f8dfc5099c08287030bc56d90e114fcfb92df8c88a4827f026560120c257333a7b33f07846d1161032bb8d6f9d6548", + "Name": "g1msm-4-jwasinger", + "Gas": 30768, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000f519184d70784b4c70107842da9a1d76d7b4f3c6cd2155f03e53dd212f2ee04330cb418b0a05378c1b51d45d52be79e00000000000000000000000000000000146f7821be5dda33e7139ec78a9454c534a125c6be4332b1490fc26d0134880fa8dc0ce14476648863ccb49ff3c223001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a35dbd7a31c32387dcc0f38545d6af66aea9f56fe527eacfd5793a0f0134b40ab4788b25ff1284c4791ffe59791dd400000000000000000000000000000000071263be3524fa82a2dc52f8d536e6617dff4677264eddde49d0e828d12d23d196fe36e0f10967e5060d5b3478d32eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036583b6b6387f9c6d0526bf1073ec996661a730e64203b4aafbfb0342e048fed94137da221fb8d6190ae717310b351a000000000000000000000000000000000ceed361a9188277704b38dc066675db2ad4e85d2a11686d215dd6c579ce3f79397c30814d0ce3fb79f4d535b16c3daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001426901693fa83ce2c198d983f76d56f9992f640c760bb77755eb61a9212a7588c6ce53d1ed61a8f2c13a29f376189a20000000000000000000000000000000010a0bcc9b806ca9dd97d01c475d00cc8a9d506a630b5dc973cc31de2685fdd4bbb13b89543b4b7ab288a9b24a9faa1661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b486024be34d0438e7de92e8dc8bad0a24c85cfb89bd9f19bc9ac45fbb3c8dea6b8186f5527d38885bb50ee580aa1500000000000000000000000000000000044672326b50c038267ceb004718a6a3b95ccc0963fc858e2cde28e72fba67b4b5b65c9dcc0729bca2835d0859edc47f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000113448507e722b0ef404d34e2f1d8c4060c8fb4fcb83c8abfa7c74155e6f2e0e3f9def3716c0361c74d920a216292f2e000000000000000000000000000000000af9c4da1ba373f9baec6f382a69de22ca92e3244ee14a913dd439b25309852a0e8f3fd7f35252473aa5520af6f4bc7a", + "Name": "g1msm-5-jwasinger", + "Gas": 35640, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000194200dc14a9804a1a5c1753c0841a5a0e3dc16fa991c11943d8d71bcbf04aa26b6ad3947c4f10bdfa4377f06c07335d000000000000000000000000000000000bb95b9656a97f5207aabffbacfffa9c309911822ac3a9468d9525e3896d1570de2d011df4ad894b1192cbbc8d385bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b4986439468970c29ae3a584d0ed1581436ceb93afb782c30a0f33caccd1343d694347664edce63749435bd13fa48e000000000000000000000000000000000a6ec59c4515d6e90c62df123b5c60e635c1782bf7bf0f55eb041ab40549ae194f9f4cc3da33698c5a7ec9c5f5730bc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf32778d314765c5bffdbf6f98c21ded79d1a00cf1253d98c89bf181edaf5932dcb12a976c0fbe0d532c0bc396c202000000000000000000000000000000000f8f7041e2c8bb02ddae783648a3d0dbe878de4aa64cf3f7bd730c74e44ed976e1232dbb8475fa16fe7c4af5b15682ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044a18bcbb3e43bdabc51eec762e63fae7d7f3f5a31263efec1a51f82dd9b9da23b69ac8fbb505402b3970b94238184c000000000000000000000000000000000382bd8abf1ac4d697fee371ba0f775206ad1976054d1b28ec007f70cd0aa57ef6eb1068de195749b7a72e304ad074d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054f97b674dfc0f5660725badc1a269ddcb36f55cc03c4c8b29bd1f780883cbff14b8bfe18ab17746dde676cba1ed0a800000000000000000000000000000000174d7653690b4dc6b1d4b46cb6253472320db0288b95775bc9db08caffc4c9ace957f2c275b1c518e733e926d81b99241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4b24d59b070d2e5983e10b17a3b4f780a19c9df891cb558a1e3b479608ae87b9762351c108b6263b261287c589777400000000000000000000000000000000057af5e5f9bb829c81c9b860f61b6ad4a4980b9271662be215737664b5caa7dabe9525336b82bc7f4aeb24d8e30f755f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000ff76ea5fba3727d3b233bb6a0125eb3ed0ced6ac365775209ec6b3bacd8642987afe18b4eb25ee8d74ba8013b07152a00000000000000000000000000000000159e4abfa29b89b4ab4a6dd26751018c52fd42ff8562500e52f72ee2ec1360763604d1fdea5c81e168234ec90f063214", + "Name": "g1msm-6-jwasinger", + "Gas": 39384, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000009244bb564d4cf8cedab0e183f70d316b674dd86e57073a94fe3b1ac13af3da384bce888f770be42d80b2ae70bf5c5000000000000000000000000000000000007f0fd12e870c65d30e620616828ef081b6afab6d44b111fd90a3229b6578458945e6ba73d0860095a3f69d8aff620981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151c24f97272d9bcdea3c4b817b6b95e2854ecd828f5ffc811ada89412072cf595269e525f41e0d74fda87b207750423000000000000000000000000000000000555a9169c7e3c650546b343abb8d883bc6ff6c61f23ba519f96aefd1f2e5da92d02c7026cda4a61938ca1f610a8d2291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017101412f7727228e6fcc870dc23f45d052fa9e090971b4b5861daf47147ff60506d4535488ef5a39ec80b67d4ce3ab300000000000000000000000000000000190d8b757ffb078d8ff89746715fcae23b50d520c7ccf5225a64cda87fecfb6cbeef015c647d988af11f8843cf36eedd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006b6da29cac72094979726a0804ded3ae24c3db9f8573d7e7b97312dc3346acbc22af61722623da04a59b8aa4379c9b00000000000000000000000000000000162f33dd2cc52527ef11bad3d8ccfe74d562254002134a8c00b7b1a7335b8970e8fd9d2d394de099c82ed2d89c41257b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3ad6734f481c70b66f457dad66007bac60ad2c0e6e1439a55f413c6dfb8ba79c7b923f5863d3481b6f42659a81155000000000000000000000000000000000252ff4f00e375cc206e0b210b92a5f911336bb09fa628ee23ee336fea20e4ae783b7f37a671119fec0b8459c84e8bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099c0ce5941241bce6ab831eaf85ce2f37995a1e07c36d1415c7399bde2c7c124e9164326568171525df2a698a500f3e000000000000000000000000000000000d20866e5f4573ceb2986d0f0996237a6c743b4cb822331cea394a06f75e47f37f562bad478e559a9700ac3968a0c4161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f7f0920242ccd38b2c3f489dd45eb8e9d4f20e37b212bc8d8dbe912dbf81d35a8a25d5d4d8a1e84083edf8412105ff0000000000000000000000000000000007b5340e1decdbf119317ee913265a31d861656a167839fde1f674c81c96b0160f2afcdbda43f8546ab0b723f087a3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000066d2afb5420710cceae2f3e0be2a8bf0a8578dbbe31651949df004128d9c90160c844c8c0e872908449078b97bec633000000000000000000000000000000000aa07ad23d5f73608bbaeb5617d3efac71120608879542e5d76d86e6771bc8aeb2160627ddef8b7665d031bec6b29e09", + "Name": "g1msm-7-jwasinger", + "Gas": 42000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000002eca26466a23e459022e6137af74828a4a043de76fd42739c291c77658117d4ccea4ed95a0e2d83cf8cbcb855fea1cd000000000000000000000000000000000a4dbb9da003acf2aa0498b88ce7a5dae8f6bcdeaa65e635c951ecb0f3de61ebd7d72317b9852741de03ae709c2be4571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090988fb4f98c8bd6f61551c4a95db33b0c25861a60bc98a7dce6e67f9258ba4086606990779b18db37af56566aee62c000000000000000000000000000000000d5bf1b2efa7711fb7a91dc7ae1941a06b424ed878e2db9726f710c676623f200c688a0160f2b848988cdafd0e26995f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018504266b12b76c706908d9d3fc124e43f0264c165bed121b3fe61a2279d86b7c2e9c2dd549b92979f06bcc41162342200000000000000000000000000000000049c310741619781ac34e1949d360a99430807175b5de87a00f0babc56427ac2f7168b3e69e006993887af60d56a7b7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162b1a58359f1f12175e02a456a604b68680b97362cf4eff8b3c62e7d6aef60729b5a9cbce9e462623088387c749cdd30000000000000000000000000000000008593e3170dce9d621ee58fe4c598144688b59ef4d5f5c886d0d395995d16c980f826dab9710fa6df84b271c0f099cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bcd8d6460badd9c853a99e6892dd12efb7592090ef876761db4ce696008743dc90b14eaa57936d8f4d29951eba4201000000000000000000000000000000000db8d628d6a4dc0d431e26de35179f8800975e1c3c8b633c8255c3a9024a3d25d4c96bcb062d1d56e4ed185d2bf77e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f89e93e5de6b266657886ac70580d52e3c16dfcf153c89a898e53ac914ff02adfcd3c31aabe90115d09230dfcb3bd3000000000000000000000000000000000a7ef19765b329ab16a780e40b09560af6e47130c9235166694bab7cc772938c7778ed329a2db45b385859308ed1357a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eae4de441b8d7ec46ac27808424284b797f0957d74b129ee36ed68b507cdc3d37065bd36cc7fa2a7522b20b6ffc464b00000000000000000000000000000000069783912b0317702031455240075555ce6fe238df76cf8753cac98c5151e408f38a3f097ae79c43f7955d508e84dc9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d2823148c233c00121672db578930084bbbf8c33b048f0c9a26167494e698ce7c6c6f0e0aa1c3e4ce53f2df52dd7100000000000000000000000000000000062c22f57f1c4b60d9919ff827df171aaf43dd8aef6195a1ee3f33d3c25e040dbc4ad52c93ddd4b847087d62a209d59f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000004ef10c8626b08ff21c61076b379ca4a4253dff9c1531182008b9e21b90c5be30aaf2d80849643d89cf068f9e79e1a1c000000000000000000000000000000001038dab69904dc709cd72a67542aeccebbb45b1f6dddbf59e5ecca6380bf77cd9fa2731109043748e163cc64f070e7d8", + "Name": "g1msm-8-jwasinger", + "Gas": 43488, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000093f799d21b03bb0396b88f50cc0b1ad84a1b1c6fd6031d84a80f3fdf3a8e72c0ef09499dffb90c681ad769e0d0756bf0000000000000000000000000000000006ee1909818c0b316df9d7a26f65a917ce144e3bb117e7352af708042d692056c2e462deebc5545452c2edf09b5ad9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b536901fecc0449e4ddad02561de8fdd99b1f83dd74555c4ee03e9c809320b467fd0d3c035f5dc11014475e8fa0a63000000000000000000000000000000000c82e5b5985ade16e31f91180d8863aface2572c580a442055866990e3a7149ea3cb36053b64326928734ea67f5fb71f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d5956a92d615a4dcd439c1c2ec61157805b30b6f6976b5b6e6b4cdbcba9d109e42eea22e0b3c39bd09e4c0f29e7d60000000000000000000000000000000002906bb6f7b0061b73cad18f81a9c4ec5fabcc283cdb55321d19ccd877873bcbd753c1178023dabc49f30578c76480cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4e6a79ea06e3f2edf0ad18aa44b43e970336ba44cb563c7d10d3a4e32fd6a2353079f57cd702e951c7c339369b375a00000000000000000000000000000000116bfb996e4eaf4776a5609f49f53013b170c90e6544e3c08cb1416774868301e8046ad72087efbfae352a8490c498d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e9357f0b3845eaa905e4f7b4eddd22da9832abde56041d2267271cf9298c9cde217d8d18892856b53d782812a5b48e000000000000000000000000000000000a7381cf76b51a880a95341720109622e289a01e3dd79527f2338b7f94c7802c64fbdcc251fde45a76ff423d0c1342631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009610461d9ab363ed7004b567a28ab93c46faaee8dd648bd833c774ed5537d7aae3fbe9ecc8677afdcf1f898512dfcf30000000000000000000000000000000006f93c06b24123a25d836fef217aab76923f1aa8d0c382c996ef1b9644b295d896525a6279845a0cb65eb1ee506228d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e04a45349aa28f6255864f8bab0885f1d80d7148a979f8501950b04121df1aefcc424a378fa07e6d0c67ad06065df40000000000000000000000000000000017d0468f16ed765b21730dc9ff4fc17b6564cbadf6c1e42d7e3d0f4b1b1d16ad1702464f69275e05ed95697c9621a1b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ac61fd4d99d9091a3333542063f5d21499a6c658dbb08f70dea7d4c3d8876be7804ac44e545ba8b27b6834518f720c000000000000000000000000000000001273a718507114158268dd9c27f951dd49dd5db3ae8ec4e5894c1b6710a53b00ddaed67767266a600ce4347473da311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034da7f8a1e35fc4e5bb23225f8a7cfff284733bc337f38034f7580dbd46cec87462d12e7465a77e555fa6690a2669d8000000000000000000000000000000000a482a1d6322f5a9c9a7f1ced8115d72bc82f1e15a5557380cf5ed772bbc818c247d73864bc82fa3c4d6dd558ac97f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000006a4260eb4ac7d806b4388d435bcd66b1184dea4ea6f13d70f2f272e122df4216a1b867520a5f4b2482c09b2bd7b55a10000000000000000000000000000000017727f0f9b7f1f49ebb8c2434ce1c028ead44f88ec2c9e8d7e39f4fe708d5487f2fe7a879bec6fa8a2926b4b8ffdc69d", + "Name": "g1msm-9-jwasinger", + "Gas": 47304, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000016705211c92899c825453eed6736a6e28583f896d9877bc8a876408ebb287b1683af65277bad546f7bd282029e45ef110000000000000000000000000000000010cabcae88300a6593f82511ea4105fe172aeafb34a0b4456714352a0a1fadaaf1310d38a8e29abdeb6aae8cf53a77ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019df8e0065b8726e509ca5a161e89423ee15976ff3b85e2915a1e495ab24a7c773d4da0e33f72c17d9c7b33ab6fb47bf0000000000000000000000000000000011f71bde9c996b4f96da6731e17ba1e226970c4671df38ebf322d151b8e9e1a9bfb2cf45420740f8233519d66b0c4e101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e23874b2f986fc78a10735e22c7816f1ff782cda99abe24dd89470aafbdad09dc539f21de39dfdbcdb1749701d08c6e0000000000000000000000000000000011d2be3742e3b1544a225fd9d2ee057c65079d8fa7b1573e835a17e0e1819d8e791bf790c4df21903d6b9e0092bb0c421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001846b75fc5fc7d5c1963e78544c8b1391c9d72f99c00c60bdbc113734729322da87c4f7adc16b72420be166da80013cc000000000000000000000000000000000a4cb50cd41b11ea6e1b6743114499ad436a0b42f7fa852237df2f0efc0e9fe60534e6cdc5992e29bb92a25d39722d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000481a03f574bdd12deee516a98e29f6588c85e7e78103a5a3c0992f61fdf1c359e5bfa819feefb3660321952a28c9893000000000000000000000000000000001395bdb7c6513d9cf92034f43d85239f2faf0c0e203b68120256463392a41005b3c95053aa29450c330273b218c2efb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d22b452c7228b55056e1dde2680370bdd0fc832adbf5a84f1b3148e0d7cda9f43dca5e93e23e9f9292a244cad202ee000000000000000000000000000000000303af535724493f64ca6814db8e1b36efad4b80cd2ef9bdd892b0b31674a786402c948ac41f3e05496fe34e2b40edfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105e0994b703afc218288a7ce70f5b1914cf40e4b5d048772616a31d787041ff82146577b615e396c20944c8c861deb60000000000000000000000000000000011b34269219b44742111dfbbc4dbe1edd369d839b814c3230986056a67b16b8b0866bccd9527ad031f9dfc5583d17c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706305ee8421e2b0440bcda446d3ee12d5b2113407039f3bb05a86ad993bf49a1a7304fc05e696dd653aba612417000000000000000000000000000000000000c29b5f70d4d3cadb847e1656217a5d0ae4c7a3a30c2765f420ceeca98aa51dc8c637ffd3ded037cfcca0f8f2853ed8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a170c581f42bc25d5d65c23027257a60a6695e4d651dfe04bd6f2bc9af9f259975e9422be97f34e692aef84d43994880000000000000000000000000000000012ea6518a398181e54ee077a69a0aaffb0f3efb536b9acd6fc84f4e0a08e9526252d0f1a1b58830fa91188a4137891251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bda8c576c73f6cb981dfe5be4a06fbf5179a5fae4b116acc77d51eb058e1cfc5bd6d0731dde2c08d35924c6392527e000000000000000000000000000000000c39549eda06719155da7e24b8e2017d13646be8798350b533c5d7572f1f789f7f9df6feab49b82863795f0b71ab08681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000028b7cc37f804fb553158bfe8f5fc08935931f7efccea159fcd9c91e443803c7833868bf09a2c94a7a91ba2cf8ea4f3300000000000000000000000000000000123bce0576a8a414657356a85c8245c80f0df437c91430826929da7b86ee404dd52bf7c3f452052d4f5541764b117f15", + "Name": "g1msm-10-jwasinger", + "Gas": 50760, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000009521928d219edc9ad62c5af4e79632dd5f7dd2b2937fec1c3a255a9f57b5ca03a64c34583fb39006a0649f6efc23f6c00000000000000000000000000000000074f86277eddfcdef246f7e09f40314c73c0f986e112cbbb54d28e5059d699ad75523023ab9da78d076a4945f995ef851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f804a2cc57817f1e0c423f2a33db2e40a4104dce5c37ebf4386a92ef9c180796f211e0fdbb40159d0ba089f9b2259e0000000000000000000000000000000013369d33037d63bba45803f952617f2eae07fa4de6752c5ecee6da3ca4bae3ed651f1c5934622b7ad95c4f3aa87eb1b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054d18d6f239a706252d62f06e2258a781fe4d75691e145c86ed333e7471fdb2ea123ca5bd9ce9adebb06d750b612295000000000000000000000000000000000b03b3cc5adafa59ee58745acd8d49a36b3af0fabc1e0014d99871c8fd06247af2077259f05ee400c14d7ed387367d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ce65ffb1806ad6597457aa70e78b55a8e725f59dd5d72b48c39820c35821142f5fd5dad2ef7e42747cc3595a7e016c0000000000000000000000000000000015942a64bdf367c5ba728b57e0c4086323e3d3ead5431a7ffb1e98939b5017e1d9a2632009656155063e177a5e4f998f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a55a5f3a2177a5eee23598914faf60d4a99c8e0ecd4a2d152a13c9961ed14ec5ab7a200b2b02e319f83e3f8b9753f40000000000000000000000000000000006c8b88804eed3823bc58dc0362f007f91fdcd067473a519c3e17e33ae43b327540022e6b9dceed47af398dac835bf321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d197fceca7aff1f830d14631ecc87b482bcd268840b5cbf99b3f8b94c5a65e4229b47fa3bc66e5565ea82e9df266a49000000000000000000000000000000001696d53e95438eb1fc68131067f15b0e9b771f4d2cbc6731bdeecac36c4ab15764ddc6cf0c2a22c600abd7bcc3561c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057f04f02a1c1ed32b1d33d6b12c8c762d937803bb752793be5f34fb30267ab1fa73c54ccab2391ab1aae3e3dfdac3370000000000000000000000000000000002701e4c990328f2fdfb76f0660592a5c683401e4c9ab170754372d3c76fede1e4616228e96228964b9e5bd0d4e3c6e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5710e3385836d44b714df25b0dbdcdf198707ad0bb4ce7a85d827aa477d64990b025a4783c3ab42580d993da91f24a000000000000000000000000000000000210bd6f2003df037efd9212039b424f672ffed8dcd6986cf33d2b21b56625b32982cecef98b0802ba004ca1a0226df21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106a24548ec98c349e31d5acdcb6e1378af44ffd2fed05a4fd41611b7a23c577856675c0a7d9169b4a36fe521eb9fc33000000000000000000000000000000001495cd8531f9c25f2093d14e7df3251b06657afa0a8745f690603d295db20db226bc3e21943d576e0d87c58a5f9846a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136199fdbec21b92f6a23cab8cb33e4e5d2faf21f3cc8a279426ab64e86b34fa7d8b36903d3d48c44804b727fc01d78100000000000000000000000000000000128817bea4280c89efe1d6b3b9bc9ee1901d12c50b7b980c9a46727ec6ddcf09582d29068b46d603a8f143938248fbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000734f72a55f3ef3f66aeb4fbc045da7d6a80efec8f4256938362180721e9258f0da6c7423a8b6506645aa7bdf0e8e60b00000000000000000000000000000000125e4757ee88db9d2a943e18dbde7933f96dfa76f787c355c58665e7bc6b260abb954b7ead5255dc020e9b699e39bd6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000043bfe6fec13ed186bc5550ecb89f3b2de12f10288a59bf8c0e219b64a4f3da72e6e38dcee195ce0e573af09605b2b280000000000000000000000000000000003383e3d2840e642f81bf1df6915dd3c37b810bceb15543de997e0199a5852fb2b971d11a1f634d9e8ac81e29a00c316", + "Name": "g1msm-11-jwasinger", + "Gas": 53856, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000ce81adf86a553fbd4454974cea6c989c19c447af5f874f469c0d5355039c05a2aa2b298860af6cf23a24d11e7bb613c0000000000000000000000000000000006539b7fa1ff62255ef80c43d26dcb71685e86c8a1d088d53e254866aeba20ca53457be749306b21d56d6086475fb8ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007067fe2a228f0842ecbb7a6388e78405dbd9a1022db031a9a0f58f11928dc34913b7ab13a596adf51c51082e722acdb000000000000000000000000000000000505db0adf1c0e5faec9596d5555f810037b9ad5a2ae1b5668fd72f52228447625a2012e7189522d2e1d7524f73d81521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131c26aae83661017a32e22ce388f12d362609d4ca93c5266486f601bb0ade1c2cc6d798ef4d1645268d538e330e6014000000000000000000000000000000000e8c93332bc07915ad1057913c698b924c3f4237c7532ed9592923235c540381455aff3d28030510f0e114a5b5c8a66e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018157dd5c5df467282b2ea8dbf696fb9637bced360d82c569014ecaf7b350062ac7ceae22d5fe5f25bc6cf2868308ccb000000000000000000000000000000000394672c48d0590cf33287fd741ff1d366cb3461ad9511d33f4fb12b3059fed7f1c2884e7fba65b932081b49b969868e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c0e480bcf4a92835b46822d796af998318ba860d8940c542009e95a4ee1bc92c97150ca8dd4eae157de0b39f4fff8e00000000000000000000000000000000010f3cec81c5979d5c9e622fe42fbfd7ad7f1e7b406e1e49c1b7632a1aaf4b1aa79c02714480806db4f4b6361443f5711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055042f2406721cde522648f08fd1eae26913fa68d0d481eb8f4dca1b0b6fff5b09e3e17cd997c122dc53f09dbf04c6d000000000000000000000000000000000ab21421a4d6895b91a5df00cbfbb6d05f83a8562959861ef4be796c40e2a6be10e6612e34e71800abc9493a2ea341a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff19df95e0f477f6b6c16c7256b9910dfd857892232b8d87e1de9bbd4799b69b2e976078001f7f9f39afda0a747134800000000000000000000000000000000021d1057956fdb34b36dee4f6ec4bd9edcdf3e11d8c50b9ef0daec7b444ba649d7da7d6718f137425f894609487652091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fee161b3767735eb98ca6159fa9b125f17fdb1cc135a9b6c751ef1d22dcea595b47ad76a0d2f8b5b7713874c9ed668a00000000000000000000000000000000196a79fc2c12a25d2702a0efd1804c4e176e046484f34f1064e6e2dcb3ab217895ee0dca2d4c6ffd737fabb9d98f40c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ad6467b9e249333f8cc744c7fe0a87fb6d6d0d9f538d5a6c344a1f07b4c2a0869e968ed041c4df33667081b318c66200000000000000000000000000000000043643b7310c753a2b48da33bccced892c57e1b8146db9ad746621bc014bbf489efe8dcebd247d590846b6791ee02d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e001b324581503e1b1e18e13300b3c7616ebfbe9723cf71375da30de5e2374140f7aa6dda50e482a05325a278722bea000000000000000000000000000000001520e9dd009ee5086839b348b715f7ac8bb9bd20e24b1b52bf4660561cafec72fab7acc2bc4227e79be4b12cc16901e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018029c4dcddb7546219af291e66698484890a979498a95010cccb0ca818a83476a07b9aa4cfce30484eee2964fecd27700000000000000000000000000000000100a2e6f3666d850c10ba8990509e73983ff6085c2568ef092129566f82ab2771da25d6f491ef9bbc2b878ae61df82b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e80fc17b09a759f6f7447f5102b672717dc20d776caf07062129a000177ad2349e6a6639af4dbf68e5300474cc9ae2b000000000000000000000000000000001838e2d26a29b8d019e7be2703ee8b9baabc76013126223877ab067abbe1508bc0b171d130e2dd36d9d40327e63712a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000253e15fdb9bcbef253872cb21bc3d6dffc855311b6c03caa4de21966c467859a368f349d836ecd8b92f9902529456b90000000000000000000000000000000019bed0c957c26977f215587aeaf1d757b8895d1104202ef8f1d3026386bcab1ce917dd336a37194105406881b306f15f", + "Name": "g1msm-12-jwasinger", + "Gas": 56736, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008721597853b86a7ba46a406fbdd1c3d1adc764499ba1c1ae652cf45c79ee91c0e95eb081053e866d0d48241f8cf941100000000000000000000000000000000051fb8a8cbb17baae38fa575ce2a46c6597c7fabef6f449bd8c011a4c57483ad0aeea99b61c5ab68226c167223b19ec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a928423212136a0c5d5b7fbeb33b30d1f1b0dcfd736e93e65b614572ebeb219a9a0328b2a33b61f99d714889b3dc6920000000000000000000000000000000006a889cc23060006da36b44834981542580e9bfdd482ad8f13e4af4c2df01e70a0d39a37119ab510b4aabdd83da591861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044dd71853073f677b058e3f22316b12a375837b04d5b03d2e21a25b9d7c8afde35c35a0b83990262e8b2a66a9c6f0f1000000000000000000000000000000001657a16ebf87ac7df3ee4f8adeddcdd4db1de13c6b69a1f7cc45610ef44a9deab66409af49e616f251740570494c12771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000275ab91e7bf0fae793ea07679c98bc5c15bbfb3cf6e3ff0ced124dbb33a7ce844cfe2d842cb47a5092389c58e1e63800000000000000000000000000000000002543d8d5a5f7add0f96378fb27b3fa1adce7af9517659590b8034a4c930f1b773a01827c1678a9ee89b131ceddc5bed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001021429aa92759eb6a5e783a9eba40302929b289ab019ba22ad9c960caaf68e5edea94ee00064fe1b43d638895172ba30000000000000000000000000000000004cc0c70306fb9a0b9d13adc00ccaf6e1d25600be21422782a4bc3c7344413dea62ce71ce774aa9c34633ed042b151f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000810a1164551bfd6bce1e1cc2e349a3ec0522385e274ee8ec9a1fd3fe12e855c1848db0d01f5481353831767e75893650000000000000000000000000000000003cd90e71e5a8ac70d17eaa4d6d1c453c6afd9b91d4fb37a4c404919555790d35594a278e12e9f128dadecd5af68a0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177205ed88acbb6c36e82a124bafd3c84bef87f13ec82edc52fde2914e0222e028dbb9b93c426a6a5abfed569c6863c70000000000000000000000000000000005e98c22e98c416920c9f8e87b2ba6312347d9aa9774a0075e926f888351712190fcca351d96f68b9636aab48489013b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b512074899ca5cb6b9ab5a7d5967b6af8a28108728a8da935ec8be0ab8873b79516243b24c097acc0d06aa17c91740000000000000000000000000000000017b9a0b0b74d7161bed182e70f69a863bd2e048039d2d8c5e2ef6694fe0ccef2d868c914b44af30b2c08e39518695ac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030f5def86b5299699e89c754eb046147987eb5197c314aaa546fe9142f24af8dbd582ae28716013a9c843fe36e2527100000000000000000000000000000000130c289b7077149950c7d05b8379709f59d3d6adf8649d46b0ead5f723da9a0d99aa0df2aa1157d3fb978d8fb0037d2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecbd2e088f2b710997439a9bdafced514445b29a638e0e3a2fcc239448111579c8497415d4addf4bea3d369f0bb0a42000000000000000000000000000000001657cfee90ff4e0701a3f58ad4ed35475bf711b8042ce8c8335083998302c3d5a36854049ba55bd991fdcc5c2d7589aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a0f91b5cf9eeb4e090ad121a2a8ee8b8d0680fe5b151a7a1fbe7ab85a19988fc1007b9ca9ca5d972e71f6ed22bba9100000000000000000000000000000000128383913c7b86b788f155f4e36fc8125e4d561e4a0b80869b014c9d3cb100deb37f2978fab2f9cd5406c43cc06aff191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c00d041e667c436cfb822bc8f8a743b05ae2799bfb2d32452ed7b3dd2b45270bab82e7db730f50af6e0373d49a0ca95000000000000000000000000000000000b09b5a34537aa0a47a65d2833413169549e23a888baa11c65a2f15152946ed1d0204fbb5bbe03a8cd7fbb8ba56a90961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006551944aa88d457cdf9ae02f55309be73b67132901705ac168ca993d23aa2c81ba431b68eaae98dfbeb300e819f81a3000000000000000000000000000000000e9286c999dd43f0977aed6f68daa60d91063193836b981cdf183e39bf5b8df18e1bf5263ec9443961b08b3ec6348a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000f9aa7c02a39a03692c818203ba7190ebeac8daf7036b9955b7e98c45efdbcbab5eeb042cb06890babbf2c8b0bd7fe8a000000000000000000000000000000000215e04a2f337c247da4c8c1f2e0652fe50e15fab12418620e03ba840614ff54457b31632889c1aecdf6eb8deaf3d2b8", + "Name": "g1msm-13-jwasinger", + "Gas": 59124, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000164e9d07cbf6f92dac7bb20a6d60834979dadbec525fc9ae6a0ff8b23ad9d4c22edba6b93aa10bcc2b5a948fdc581d2b00000000000000000000000000000000086ed6d730ea2f98f6e3a2056672acb46c1952eec136d1ccf3d02a13107f71fd9160736267f2b093abb781f9e91d417d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007484ab08ddcc18eb8e7f9b5cb9e48ddfa36f92c69526dd01e85c273dfd0e705cfba697fc5cc93cce3b7701f830a9618000000000000000000000000000000001000cc4aa41ffdeccb61a3558f69a348645b2dbacc259273cd7da2a2f05fe90d46c4a9bddeb734829c850af7f902ad721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017d1f7e469754ed995feb9b181dfcaa60468d8fb3c169130e71d50c730d88b6aef2a77d58b660bf1478e029f82e0bf8000000000000000000000000000000001862a54a708da0ba82a5696bfc69e5dbf7fcc4fae7816e937bdafc70e0dcf1f91657975e8c55310b5ff032193f4429631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2aaae336a281d5f7599926e10aad8451a629af6f2f9a33a01d506b8f0f7b710c34c8922c499f689ec136597be60c360000000000000000000000000000000006262b6cd9b4a241f3cb5ac8494b71da1b6e7af3e2beb5719aa60572586b7df23b57663452aee9393984c84c7c2313321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d222b477873d394f07dd8eb04d69bc2ba437b0d0bd53f6ea137f1f826ba89f1e1f2047e60a05f10eeedf0b0c7056f000000000000000000000000000000000dc97f5761d0b791cfaafc45ecb868f49a47f28ecfde4249f60956d5b2ac72a4388804860b7e2d64b4dbe7d33539cdeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001143a6c321182045d735b3eef8799d7a782191b5c4e5ea0a7d1df67e70bd32570889219d776679bfe4aa700f54a993be000000000000000000000000000000000dfa65fdd47a2afa608e080172f1506504056f01b0712551e5bb9b354ccd5f0760796a76270e4331f3074fa1467772891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019af409ca1ce865d84802ce41f280626c43f7d7747ec82ee9eba82f5c9f47d9329cbaed9cd33de32b635d08dc48d9cd3000000000000000000000000000000000646a4f6069d1cd3045aeafd75ca6b0ad637987da41dc53989ff75be2eb55b9959c711dab9a78147115a48ef23ab0b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010719d70a7e3d0a90420eca3eea4ba27f127b892b62d1002014b65caa879a575cd3e3c714fc47e2bd2f8190327360de8000000000000000000000000000000001685b6fae8cc481a2860f659dff86baa5d557ce7209f231ea7258eb2dbd0ff202ce85a37575821227051ff8f596c273c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017931e6f7f77b3506919f09514dcb1915fef15d8e82a9d4ff1f8a97e34c3fdc0f02857cfdde23acf57c9cebd381d63a70000000000000000000000000000000012350eabea534e4c6bdd0b9630120c07db7d8d610da988363929db7621c3e02b44b9b80120925ca7a3c87f0df06eee461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac190f7cfd3d4ca30f8c86399992305f530e4b111ee1525621d65492d61f25372fafb6a23faf67cdf08f47268a6203f00000000000000000000000000000000155fbcd718e64c1466884700e5bfdef62fd842df87b8a6fea1903808b32c363ba6acd741da366004e513cfe5102444ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d5134fc78edc9c3eb0b2227b1cb1176296cd8d8d60ff6764279935c7b4dec3d54dafbf37cc2e4f2269015be1326950000000000000000000000000000000015d09a037449ee1b9750eea805ef51ae5d0091f903313867096d3115e1e8986fdd9e24635aa910c36453dccf94ba848e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000951a0bc7bd54c6f32e2238146a32238f017db10bc8da86ce6b817ee2376e6de631ae56488151f34d07b2be60d4494620000000000000000000000000000000017d8b124eccd256dca21877525d3a74da064a9ad7dacd49f7401b03919100b36b9ad1fdb0c3b5cc7f0cdf0a512e2b8951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045f269e23516a34784e41de132269510a328bba7ac6859b14bba872bb4d57761b0c51f4201c1480c5507708a100d3c9000000000000000000000000000000000bb57a30e19ac91c5095e0baad738f626059cc2e44cec6e014e8af95ecde72396ba50d9a98a1733bb0a131a9a6f767421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e91aefc2094d370363f8c727c2802330f3b193f9d14851f0fe669c12c940e82e2eb9758d78daee09b137a4b447404000000000000000000000000000000001380d34ace5e0bece88e5a4c59c83bfff359fa0f617cf74d53cf9ab89cf6d4d72b65897c076ef7851feff9ea6ef62e3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000001203654f7be8ee24e8577d141c7a4b1a35bcfd5dabc6a23ee0ab5579321c01396cef8e5b72fb6436a204eee63bafb47c00000000000000000000000000000000022fccd7d3ab8ce938d46bc1a1e375fc53f6190037959b05ff5056259177da83924f96e2418945be939e8fbb00000471", + "Name": "g1msm-14-jwasinger", + "Gas": 61152, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000671a645b2e6dc9dc0c106d2ed44c7a9faf9ea2d19ec71019d4d7c59d44e2c3c4be27ad2c274cb9f3ecaf0be5c98963b0000000000000000000000000000000017d8a4d07bdd30f263c9bcc64c9caf6cb59b7b7ac0d73b2c641c3e733e5d3177ae17d9f9c76c7f43d1d41171048ab6411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e58c7f079888684c89f863eee960496e00890b1ee49af1acb8a2b2eaff2fc95e0ae4df9114b10279c3db6fa97ef8a500000000000000000000000000000000023ee51d4a8ce170851f42a098da808fd5e37940866d9268e19d053d111bde34081151b6722089f191b319d7befe2ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcb8e9c73b01a863a4b94781f2cf8176e0cec3ebe8d5ac601dd667cb0170a366da1cd390838dcd22a93e734acfe83110000000000000000000000000000000014b2f45b72ba14ae5763bc9a8d37f8dc4b8a2eee94a0704236b228f7a7b43e8e945d8aef9bcbffeee7c7c9d791d4379f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a02c583d179d1dcd43ad57f81d6ab7f0e02aaa840db78f9bf8f9bba802df4d32071f80d7d6228acc092f8401ac5e90000000000000000000000000000000017cef78aeb96b0483d1151d7c12760befbb9e89c569c8c95684d7fbe4ef74595976082f755707d45fdda9c8cbefda8751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001057c7bcb62624b8b85887c2cb3aae0f29aba618ef014820c9a6d4d63e6cc68adcd1486d8f0b87aecd0e800da44f61a00000000000000000000000000000000197cf504149808f5c879138cfd09d7278a333d6e1486020571a5811303d775013c5a2bc040ecf407651c711cb6a66a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fed276bd78e056c71f5750fd39f5612ed523dd4fd1837e465afe530990a193cdfdd339d886e050cc7d666b854279a40000000000000000000000000000000005697b3f45e54f248ac5a7bd7481c1fdbed3a43ae493e469aca1eb571134ca3c47a21afffba7498a0a94651fdffde4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e4db89ede0d42db8d7043ae68c5e9a4a82c04152db6a895462facd84f49a43c519a5d826a22b78c3b7e05611fe4fa50000000000000000000000000000000012a819206705721d30412f76c943c655295840178ebbd558243f2bb645891a030db8fd492593b7c1ce223e76215fdea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001567ba907e1a492d8b02aed55c738c21d24dc27c9de7644226cac21759a6efec47e7e0ee916a6699b25259d4443267f50000000000000000000000000000000003eaf55edb9579b76445b5d799dfa46095aeafbb30deb40bb6f9a0d4265a02c0f85cbe4a91ef023f94303b3e1030af841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029323c61dbe4a0290fc5e5415517bade938418a8710baea714e9726d2ab4b1fdc787a300aa52d79fd09f6acdc6241480000000000000000000000000000000006f9a817ee473e510bfd48f64e0e5af3fe2d1a8f4edb1b2b65c57fd601bc5df06eb6de0e90f968a8e1642d312febe0a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005cff774d5579c4d9aca6063cf700c8d909c398b9a1cab0211762f75d8be55f9d914eb86a68dfe1f4218771e39e2f430000000000000000000000000000000017325b534a0ac721f83f18495256520fbb70d2b14d8127edae5f8a9c27b63c16a2646a4b92f0d5bd18c3158b14e24a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a530d4a54626c8d01b8e52a24dc3bf6bdae5fc8c27e766c8ed7282835fd71a9082f8f27ab39ee79f2e1c9640512ed0000000000000000000000000000000014734e4a53f760b96c4dfa7563ecc977961343920fe0b6ffe2daa606928ff1af5ae7bf1c95ebb11c5b5f796390cae1d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c685f25f539c23945d55b025fa49f006fa406a70101712c34333bf1e931e73a2bf54203e2a481a2441106f5f2170a2000000000000000000000000000000000dbbb1697fe5817a5bf89421dd6afb241a696872c9996c92b6372f258ad3b540ad04ecfa5b86189dbaa25355b4278e441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c4f2b709b765dbb07dfb934e163171632eb1dd02663dd53bd7e203cc4b2368c3a2a53d10bc55597f2f8f1aeb9fcb4000000000000000000000000000000000f6925f067f72c5184281e0b410d38e1b95afea31d28492ff3f22d15ed7f1364793bb0e3570374d0ef411f84feee730b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019584436d1b4154f43b64fa3d870ff809217bf12a3cb9ac364e43e938f2bfb566c056b44df1bdd1c3816ca05bcde3ab6000000000000000000000000000000001741ef532f3869c8fdd586f23e647847bd108e65ba57d35334be69767d436ca75d11f15c1ae1c267ffd6edbc232d33441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0bc8cb8d6834dcb4d69235194033819e2532693324f712f7c1be7b23c16b1e5cf06ac835b88a2895cc96a528769c820000000000000000000000000000000002950db7b91bd972c58dd047ba3621d5c3b83f20e527d45f6c840b4ae9ca226fb00d16d6c4a92c005f9f4d028661062c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000001883c0ea7caeb5a560d871deb72318417e032b6a9c1fc2987e9ae1ef90c8db336ad093e71781352197b806b41229aa500000000000000000000000000000000003854e857850e05ac4083624b4c1de281f2bc308870a2ac28f679840c8c1a5e9ce6bcc8ed4caafd8b40ac3b054f84551", + "Name": "g1msm-15-jwasinger", + "Gas": 62820, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000e36a348a4daa3cf19396d542fdf3f9464daac718f26b31b16752639d4335508551ffc4c36f1e2a2f68157f1fd588af000000000000000000000000000000000171124d2fb1ea2469680158b8a1c830c573e99eb60f83da6b72a9b6bc1aa85c062ba38fa6eff3d5df31d2e64fdb846561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ffa51fe8bce43b78da4a9c27d85061f84baf877567ea9c3cd0790bb129875b435264f8555ec36b15767f88247081db000000000000000000000000000000000f75f654a446c36ecec0c6b516730352ccdd02d82717cd064efa82b58ce45fceaadbbb8fbb2417d162fe7f03239be7a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c5d3d04604deeb36311a8d36b825d7604832cff57ce3855e0ee418256d7bb5aff224a442de20aedd2a306a29ca5f2b0000000000000000000000000000000004217eb8cbac66bf3cb92c125c915caefd81b221930fe022b6c5cf8db4c94cc89decc0826d296ba0b906f22e461da8911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073fa905a9f5b38d5310b606d816c61af5e383c5872ec3e3afc57a628930b4bdef25519fe3463b4756b9d7052fbc93d900000000000000000000000000000000115752501c57c02162fb31325971d58a51c406925e576c6cc641250602bc6a3b54904dd38ba46f533b01f8004a688c7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197df8acc92b88c2395f97fc58a34f5e120fbacea5ae9ffa1bf7dcbb4bf6640d13e92bb99faa3feabb0f5b2610ccbc950000000000000000000000000000000001bc6d7aeab1df541f592cdac4a1366a6e4293ed57922866e1145e7297c5ae28508985127913fa33788913c2e0af77711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff66fb8a9c260d1bbe4ebf4bcd6d079b10d2047ea53ba5d49d119735bfc8e152503ba5106ceb8261f14662874286a640000000000000000000000000000000019a4731c96992eb07d595bb2a3d53e81230a53774c676cdd3e77e14aa2dce9ea9c27652b27c02b8fb3d60ef8c2c95ec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f54c989e66350dc4d79b113236a95aa1bc8ac3f8b0d8a0a1d4b358fcdc8f329c8e73b9f41cd4bf1ab63ab2268282bb00000000000000000000000000000000137e0dbde2a21520fade2ef6ce8405f814db4167f290e628b5e1539ebcee9a0ee8aa83de3f69a920c5a445eb910d447b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063df22d372a24fb60366f793de7bc45dc92dee2594f3a72b1ca8efb7175aa8f68a2ad7fd1ee5853e041d36308db455100000000000000000000000000000000071cd08097bc2002431090993caab712398db07787b88a506d91388bd2abb8463cad6d362b23113dcbdbd808a99ea5ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b9e2a30b12883961a53e70b61095809201ef2aa42c91072ad8e5581cf79fc54cb11981fb67fd654290a6754c99cbb700000000000000000000000000000000147b30badb1544163f0f81f58f35548b72533affc4390a75c11c3a70be34d7915f43e345d171e2ba4000ffaa8602d8f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e5d437f6b8554a4708fc0488314af417a7e4d8af0701d16c69aed13282a52cdea7afc912279102f5251914d09c4e6600000000000000000000000000000000187fa0d3e59f19077d1bb77865061c2a73ae883677b2dcbb651b6c449b586098b40ed82fad839c5cc7bd5ba73d93ad211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bbd8101343653c5ce16b4e721d6315cd180428980f421f291c10e1c6a0f6b5d5ad5874648aa8cd26f9205e0f5b564d00000000000000000000000000000000032f89866615cd2a6781afbd16152d4d08621f4733c6ff60c669402b42886fc47b4f61213b85ebbab14f51696a6cc5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098b50dc9c786d58709c7b7eb63df3d6dbca3a20c30d46a25fdc608dab5fed19a73bf35c7a2c1d39d1592bbee1d593ce0000000000000000000000000000000008b428ddccd19d127e5ae369cc9f674e9cc2d78f08aa99b1889c303e7743261de3077d3e69f10554bb6ab2ada1f76c5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be237a4f8aaac6425cb972a7399bd0c2b0b97e2db05509b12c4ea52de42ac8ceabc28d486eaeff2559c5d62dcd0e5f900000000000000000000000000000000072f19779873895c0cc3d00b1f5d20dd0ccf6645c98a34585fd464537f07c7017c5f54de1fb4587ea0b2e0b7a8f561c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002946ea43fd6327ccf34ebbc0220eefa96478ba18765ee3cabd595c91e63cf27758d0d2f14608ba885b0b422ffb9152d000000000000000000000000000000000db1e990595ae59cf498b8cee67e500439e4bda192754ce46b3b9c515da97fa67472dcdb3fe469231c22aef6931bec971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163ca4a71d926baed3e458f84aa5dd36ce96fbef320dc323aa1ce42f071f2b32376fe2d6c66a86d37ab78a73d788e6030000000000000000000000000000000018d200acf24142deb5675e3eeefcc15040d1359fcb7e8a1515c9dddc661c9d0bf83f0c6a931cd6cc4000c15c752c8f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069ac270cb712656dc8745e060bbdba2cbff9ada910ee1670f2ab86ef5e9b1896670148f4f81b31b070ebcc14f2c0e800000000000000000000000000000000003d7a630148b77baab8be499d06efe3620627c73f5895aefb408c067c36fe9d21c66f7dfd6d84b654b45b84439c009911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000162b81ce43d3df6ff618be50cbf51d0a07c5ca8b5a9488dbe17d740bc07512604c459da7900447c0738d9dfc3a25083d0000000000000000000000000000000016940839cba1b7e8baf9f14cdeb68a7c57acc4e83f71b7a242e066088ec17b5a7e84cc6d1cd73341b74143f91c06427b", + "Name": "g1msm-16-jwasinger", + "Gas": 64128, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000012da2c3b4ca5ed4470f16c540fab8954dbf1a61a9f1d2cc521230451c46ecb6fef6be9335354887d311b480ce3abafc30000000000000000000000000000000011786226634a6969aa8844862316ed6f3d5036429005b7ea60d07c1ddb6558fe8ad6712a44e546412dec471d192881d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bad347bdc7ca3a9ec974353f5ff697c13235625e88fd5d9c775bd05cd7e7afe2d5cf3e64e16ec05300939751bf3f5f00000000000000000000000000000000131b7858197c400514a81047de69af7698d3023b317e08939cde83e2f745e147cb217df4ac61a2db45bdb787cac6675f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061c98a4d974525ab3dd406668795f695600e558f118793562d99debd1cf2df5a4085ff15aa03713a76670056a7fc799000000000000000000000000000000000851b9b59850e846b2fea9904cdb59111ea865e3ea8327678f99ac6ec87f54d484fd005405ca162c07862db8af84494a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000644bd28775e38b03f0c8b252de14f77b090c828d02024bbbf784785b6f2a26edd74fbec2472fade7c6dfc1bd9c80e440000000000000000000000000000000010cb8910d2ee27f535cb5901a8c85c15980c349ceae8656570b0968e28bb9d75343534c1b71a6587950963e3987144d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d39017f9e5ed6e37beb3b4e30558accf607651e60a4baecc45ab694589c24e03889a454e41c5a76d115bdfe3241e49e0000000000000000000000000000000009bfe371fbcc7e8792f6f335e923913d6acfb734930fb23497372d93ae0834c97b176ba56d348cf9f1eb082925ee81941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cb2901b71c727daa7fd854cde13c7eb3468974eb63aaccdfad0fa904b60bb9d395126067e9178694de5f8305fb51ed00000000000000000000000000000000105335168b9088a45810dfe79a25aa0d293f3c6fc5811650b2fe35612f6e0a76e29e155a8c248c1ce841a605a89d003a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cce99b2e7064aded9b77342cd334889a3804ba6679940ca83495d67ca9e77002f49f03f4a075b6cbd72a0623ab0ef20000000000000000000000000000000006a45377cbe41402894d9f885cb08f3691dcb2dd8abe9c79c777fd2e4d4b2449566c0e6501e455c06b9f1b1e4bc4f7831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba10bb924fa67bc3c782d4883e098b4b7225d329ebb28714e9efe77ec99c5723c2c165e577ada70d0fdad537488fa40000000000000000000000000000000011e1632431321ffa835583c20a059423b8fd1b96f0eae8da99bf118e36ecf20e5ae12426ada7b76d968db54c7e3223931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009555a4c6be383a1de08af26a799e431665f0c9ba67d95518fdb8ebe6c55a8e8518a357a451231bccc604af27629e98d0000000000000000000000000000000016b26c561d534d73c21d387e871a6cb5054f3eead42d9389117bb2d9a9de78a6a31218e3275d468e2d0964e41fb5f9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c19f914a91aa669c7877d54333c3bc4038790289f983dd6e6f37a03da63b10a68d67e268edbb9ed7ad20ec1053eb55a00000000000000000000000000000000099bfc7a129366439a71f9f715956abb1ccdfa15931cc5edfe5b75e7d94512ce36890091b7c356b54a23dbee98d1df441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d38bfe2a2d5c692658f4f39d06bed30296b245072f5880439244b378cce4e48eada84892cdf8928f5f02abcb7a1031000000000000000000000000000000000c5d773c622e158a7597c7214e3e7ba0206a66223931d173591e06a7970cd5e173ca7252de2a43a5dccb1674176ef03f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6805dc3edc293e22e9d24bbad770d04b97a0db947897e455fa9c80ccfd67f0f973d546493b36f7295b3d8d5c01f6f000000000000000000000000000000000f3e09dcf7b487b000682ccb0b71c9f98bd133fd682fe7a1cb2f1d83ef0ffc2699987a766e23c5cb6a2080e8540266691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d6c771415df4333b7506f4bb7415f790d066cbfb1ae4907fb7a955447bc1b894274d234747718414da878a6e1e68440000000000000000000000000000000018e5fd07dfb41922f45293f02e247a065ca68b45b20527ee46f67bc6223f2fbcdef418b949838b0dd30d6425a059034e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb4dbc74102f6a4940f6a0f6f4a84f441181d58a20113eccb0549e8b41cc6394c804b81c3b0484bccd8689777664ca5000000000000000000000000000000000bd600bb45ad3aa5c6cd0ca5e133433017226c9110d8abf9d490602364100f34402fe8c07020c0beca1ab0ce548b35351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e84050303b8942b73c9e9e9b80adec1903648a82f353617536c4e2fd5cdc89693afe26916b0350021fc41bd625963260000000000000000000000000000000003ad3c1bdb591a66e9567060a8726a2abb9fb99bab009f4f734fa386c973b0bbc251bc2c9cb525b60fdedb3a172c67ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1a7e82407964f9ec94221a2ad98df7bbf677941d72b93b15f5d706805b1315a08881b1cb00cb2ff1a25a83870df6d000000000000000000000000000000000aa426764c60fefc5a87f6812b2b479dacac2ceae65e1da7249f84f888521e4b691788191d8cafbc75d47489ce8382741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018797757b20f4eabbc0cb3dd28fc503438d988a6e7a7e44d603a4780dc859e426ec7a8b6ee130176778268e4c2512dca0000000000000000000000000000000019666ecbf1b42026cbc1d42b59b325ebf9c57d7664bdc26b93373e827a38fde1bcb9874360df3a902de92137adab275a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000008aaca2307e744151c94ba429dddb0702c0dd9c945782127c387f530e3477885ac3622961311b953e209699bdb9a11f10000000000000000000000000000000008d7175048049787424d019d60ade8f2e973ddeeb54669c32701db4def22e98b1608ca319a49ee28258d4d418eb063d6", + "Name": "g1msm-17-jwasinger", + "Gas": 67320, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017fabdc2a00bd374668c1634f52e6845278f60d24e8ffac5ad1a0305de8d8f633fe66f103fbbf97103725afb5a61baf800000000000000000000000000000000032b04b5d778da193f62daee3964b4470857b4a0f0f5a698e31592b3bbc9ed2ae72cb481fd71ea83e464a2819a06e0a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de6060b7260fa7eac70b2c09526f8ffc5c6704be2c18c47d7c4b11ab11cb243f55bf5dceedd48287dbe00dcc7a5c39d0000000000000000000000000000000011728aaeee67be70faa4d7dc8ea48a60d0c54a9d7722a52b02c9da861f9962d390ef27e1058e8080815e142bff0b36671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f938d3847277090a771785da05e77fb3f51e628fc4ad07f3201380b9a1a7a2deb88ace689c0964ef5ea1d36e56a76960000000000000000000000000000000016aeb91f1b57b83fc4e944b5cc638e2cd2bedf1de3aae51e892bae7121c73704ab2d61fc205d35e404ea94102564a7e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fc12ab9cea6669968b95486b0b66f55f32269bf7992ab80327ea2780060aa979f00a22ba2bfdd579e71a959f6e535b0000000000000000000000000000000017957cb675ecc2a8ec93626d5d345e1ec9742f0b4f706052ae25abdf1cee0474ae893f90a7cbe78b5acfb6be510527db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f682f4c9156f161b794555ee41c58a900bf55ab576768b14eb73f0f3f85da3cca64ce718b7757d6b005e7ad733597f70000000000000000000000000000000000988605131f66453fc09e71c005277d81294186fbeec39c9e36ac832d814787c0119531480b87846782c3b3ef85b2741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d26fcda1fab4b53bc1b09053d31e02f783cd8fe6bcb1ab0053d1fbfe1fb9449ce48b47d3ec409e749fb3ebbf98b4aa00000000000000000000000000000000155d31129b3d2d6b61dbc87b8d2f55e7c6956391d9d08c72af8aaf5d42e8d7008a2c6a43bf526f8699375a140b08280e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000408a2969f1c297e6f21ab6d1a1d5f00e8a40b890e9d8c7b573afc3eeea60259e92cdf0b6dfe3601bb1180795328dfb700000000000000000000000000000000169289d8f7ec09b6d9ab2ef8bf271f19926ed715e1428034ea4806a1ad9dd5edca784f72734f6d5dc69c6c910769617e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e6a9812fb0da1d5f1fcc3ca92cc12cf17d46d40a4329169e01d0024b27383ed28a92fb52eb37ffbdef076dd610dbc5000000000000000000000000000000000de7170b36adc59e538991834696b1f3c876840c5f1bcaabc585243b65e2cf832da4ad78aebddfbd8d947936a0525a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000108e2f1cc4a9c5aa707082f634ee8de51ec9a44897ee7e4cffafa3272dc61b6e30eba030145912ef21b9ec965ccd8b0000000000000000000000000000000012145af2e467ab2148e3a3320e01da20124e0293d3fe89bc6e89d2d37c12ea3bf09ec5073cd0c41f5aafe933e2e5713c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4186cbfdbb3aa860cafa5f6451c07c46156fd91488d32ade115b295adf39396f0c4265937621e18f641b224a7a934c0000000000000000000000000000000007c145ca75a9cd7a67f20535d9a68b56750b180c19a7bd145a0fbad930235d0ef70561eb31076b2c587190893a75b1141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122382f9424b81fb6d0397d07de001ff93666e4f39ad8b514979e65206a949e698b4fa5d1961c852eb6da19193be0a3b0000000000000000000000000000000015903eab7f515deed48be1b2810b4c43d09379e0454cbb2f71a603ffcd1cc7c53b2d4a4bdee50ae8a555050fd9c96a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001818c548104bf6f3f231395f46561a0ebf321039ae7cf3cb54c0b2e901bcd59f38bc488055193f2ead49d8da41e5db2f000000000000000000000000000000000275b44713b2d70ad0ae7e08cbd4933dffaf51915292067e4877887325c220cee554ab9f9138d09259cf223841ed7d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001454d1af22b3950d332726f6674f06e0be4d8fbee8d00da94ef38e6043d6ec0183a7fa685dfc2e7f278c2d66d0754af20000000000000000000000000000000009f7e4b1b73ecc1c4e1aec55b78724568999136ca5d4baf7f2c61f9fe11b80535dee231da6e2b8224958652496bea48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004392c3c6d7d3ca22cb06b5122210c59905284e831fbcf0ad8a1b88fabb2333f4cc4c1d90596ad2adddee0634c1cc899000000000000000000000000000000001469bd6927bb1d191eecd9379dbd5c70e91ecb37ddf09eee67d897008a2fb0c366e6182d259b20d44d6aeb41ca28f9011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001347ee924b4b01057d19146402eebfb789463a9bd60f859d4391d680ad99314da2e44ff5d27ba3ec8d2b3c28119b6ef20000000000000000000000000000000019f63c3cd259ef162fc021c5bdb6fb11b7666830ff50508341b87a054988c293f6ca08cb27f62195cb2c77194e3663bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a3338a8cf177095b53e676d0da6f5c37fc1d42a6ee18a1dd9175b1ffa0137f2fe3b71c21d1794837497763fd46d4a00000000000000000000000000000000061addc73b5f8f6dfc1210d3144bde791ca9761cef3e7cba9e917b3220699b587b535e87dd1af2522a476632419b839c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176afcb9c7400390f1f1bfb074715352d9a4ef4ee3c39795026b8833f6b1f228baee37722fd9985d7f10812a788281de00000000000000000000000000000000018227759040ae68f1f86cc8feea5526d6c318bc3686fbfae7309a423f23e4110015e58d76cb78098b60efbe012d486a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8237343b653c927da00704c1767a65a90391c8af4306e6e7b90b74d5a6f83a90ba31e4e96ab3f7c353a02ae0ef2a5f0000000000000000000000000000000014b0ab4d0f0e252719bfd25223c8586cb77eaf8b6c884357aff57935e2942c5f928276e86cb87774891792366779bf181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000011b3bc4cea81d9afcc344193bc2c22b968375e0143f885b9a9f6125bd36907ab731b062df9978947e8efc9b7d61beff1000000000000000000000000000000000614db843f5d0762fd28dd57bc58fdbf15bc64dc275590d4c120927be89eb9bd9657df2c6c680e5da78f2eceaa0b77c2", + "Name": "g1msm-18-jwasinger", + "Gas": 70416, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000545e436641b75f0f28d4add04f670161de38b9900ad384b29d441742266316fb00ddf89e986685a554412c31fb2cb93000000000000000000000000000000000de13f457a3b61ad0ca17a74c72f3ca6cd10f392bdd2193f4e076ee8b8f48f464c59ec0a3080711bfeba93658f4613831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e26fc4e12be71c6fa4aa4e5934172f0dcfb5bcd3aace8f2203374893b14deac434fffe0451f3e5230a410c7957242b00000000000000000000000000000000088be2171d9ec6d320323efbb6bad2563a854663e987de2ec2a74a7a672f8b50f5d9afeb11e43bda1637a29fb042a3eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ee0dcc1dea9fe89bdf0b62648b82cebd7163e3996f4e48763094615a3f4d8f72cd88858f25c2895502943bf9af8d33000000000000000000000000000000000cc76cd900976bc11b5f6db7836b4895bd54b1bfaca2eeb04f386fa16c31c6b41924cf845f3c79475dc96170d00b17ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f2207838655616df1c25bc1668dd2265b87c2016dd3b03b58938a786e203c7ab46e892eb48e404341e193fda247b80000000000000000000000000000000011851f48e230f3e9e8ea9a8cbb02564a03f17c43e8acb3514c6a4792e3d5d54839abfeeb0e83280178f680a3bc8eba9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000382bb1457e59a6775990fec46996e6eaa15936d918f6e9a1d07ae0a771b4fd47c470d29f91db996a03ac16bcf882040000000000000000000000000000000000efdc8042c7c72a9b7dc6d86710b66e8d19b86f565a73eda25921b1670945aa0e33187e916b6a5911ee4c73d9284e611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030671b2ebe6a301853653c269d81d09624d07a6e029f7360803f1fb3fb17264be900310ac7e06fe09d6b9f95db45176000000000000000000000000000000000e19fefd6cbf2bbafbd97288d994f45a2491a5c6eeb2cab98130759e335ab444cd866e4ea01568da7b67704f7e87f8471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040303c670abd8692a1a313aac605104aa25945d570efd725282a171809ccfc4f5b2af77cbf266c5bad6a281512ae390000000000000000000000000000000000fee9d9029289fa97b02ca86841b5256bb723b89292c27c02e6053d0a0eb6e18a821d3732e3cfcb6be5873312bbb020d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003877ae82810ea962c6cbea466020b96a3a1bc1198d25ad4e274ce1a87deb613adace75e1b092d040f675dcc67b77746000000000000000000000000000000000e3d732ca213b28f8393af748b9a7caac60c122ee374d0f54ff82529eb5838516886c86e92caae6c0f4d540a3af08ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c47600f58e575b527b6af67024a0104cf4ef61ea3f0a26d23d6d41c4f5c9155c5434cf101b7f36a1bcbd7d6ccecd6000000000000000000000000000000000a19e440d6644896362a3e3569f919d6dcd7922da8861b65873559c9d5cd976cb6ddd624284839a8d04edd6095cc6e681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f13a4ac688eb07cd9a19607b6a40694c8b48ec8aa86b097c663d4a4c06cfd9aae625d5809a26d53782053af7bd6e3f000000000000000000000000000000001036583806384109fc75273579762e7ae189dc262f1377f4fde33f9bca8d0ad909ff462f2588204809602498231d1bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eafd2dbda55e2c4a29a28e4ef40723a0c90852ca3e625338aef9f96f07a47d1095337deac16b5d0f6dc3a5a6f0ab493000000000000000000000000000000000dcbc21b74d522e9bece5a57ec1d1c44690dacdde6f3395dda84bbaa3ed5b3f8b5ea822a2d9b9de7955e8c5fa290bb791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce932f1a653a2b17695d7483e57f33bc005382c0c65b21395e9707c1d63bbf23f4e0c7a0d12d5439379bed771fe18760000000000000000000000000000000013e4de35f2982aef82ed31e725645beffa79ba6af402809b07dbd291674906a5d1cd0332aee259c45108a0586e6be4321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012433b7797ea7074096caaa208fdc30f22bfe6dd5c0f3bf151a4423b251aaff64d0526d6d2ac351c9b641e5529d8b01f00000000000000000000000000000000146f24f4801da81a67b87ce77b29fb24b1e3660aa068231e4b2f8e80fc6f9561339e79e8900102d3097894e63b8fcd811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c8fae65a08a0f42cff0aebd9d3cbb88476845ad11953bbd6f1e7bf19ec3d7af5cc375add971f996288c24a0a356d330000000000000000000000000000000013d5b3beba22cb04ef3cb6b50307834785165aacdfbd8b19ccb58e965c92b099ada86fe5bdd5da9cd72e6b165d2a7d811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0d1e21755d4314c7e3f7b562cd55d75bfa76f918d015fd3d7b49805e001f8296ac2ce03f7050b321aaaa9142427c2000000000000000000000000000000000aaf63c91674896079d2bef6d264edad161b290eac2c05696397d703c9a8a051c2ea53bdbacfc97863e387e82033d0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b0933d1f61ac4a7f1cfda77d0453958eb3436a68db47eefe8f55669db2d8f8ae6b98b1f73713bf3662868ad5e6af4b0000000000000000000000000000000006cfa53e31e18ac4b64f934cff5beb679aa72938a8ed658ad795d52a198232b0de5eb588d7d337bb08f48ca7220a40d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000394873c2fed1e467d66af28b85c39949878001c7aaba5bffd73acabd02a8f233fc4c6a89414edbbed15dea9c623e4b4000000000000000000000000000000001465738fba3b7303c46724f02aa6df6d43507f3139290dec66df37329827a038401f72d2b49e3e851897eb6338ad026b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f62ccb47e362803627f0949e5549d16c4061efaa8bf333e000256a765ac28e25ea42753e6b0531f9630b038dc74c17a000000000000000000000000000000000905a3cc7325ea0b436335025d903098fa35de0a786d76704a72632f19f71884a4c340385d251171bd60e98fa21039d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4599b811796aea95742a0ef7638ce8fc848e526411b0df61c4c2c12d3098e5ff3a7b54b91260446e412179be5cd140000000000000000000000000000000005679a86026866c373f351d2880a5ddf043c1c67253353b730f6296abf686b3cca2e34120ecd60938d0b2e2546cc29a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000001474e3fd13fc42af3149453deaf6e64b4ac93960e6537b33a99bb72047296b5291545a1ee0b9b6316c617c61824f51710000000000000000000000000000000002f4de7405d1b9d0a2fd50443b343595c1ca8cbcb1e6459b7508daf11126b589dfe4c68cef3e631462fcdda7885cfc2e", + "Name": "g1msm-19-jwasinger", + "Gas": 73416, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000132bc434e48d473357753c8dd920b2a2d0fe0725b3adc8956c5938214121bf18815ae969c73c438b94a95caaebb7140e0000000000000000000000000000000019e9d07c11ab7aa7257008dbfafcc746146aca49202de5e9c9e0cad4212eedafc71be8487f814adba17ec782a78291471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001122419326f0e185528fbb941e8a27156b6a25a4facca37dd2fffa223eea2a270043ca3a3ff2e4be0da52f94f7ad5b43000000000000000000000000000000000002ae60bafa9af75c09c23174dab8bd4d113170369914920185d02cf5e94eb1f5b2a17826c549f46dbf12490776455e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001326e697127e0d847550c37c641eb2c898180df0f8c50d7704d4bb79da9a43b9733dc1de3c0a67a2dbcef3cfb10dd017000000000000000000000000000000001033931d90f06c0806c6a9c1c1a856f489b82b36d8112e8f7cce07ad1596e2ffc972252c32a155784733611a235d5ed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020b1cd41e31eaa7946dd1bd7668e386016de077c82d17bb0a7543dbf667b8df888438202139fb224413c9e4b395754f0000000000000000000000000000000019aea3f434a98d476f7ef459f556258d762d99165ad0a9a63f8121abe7937917ffc05ff16799934c568df9a7925f26b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011289a42ae2bb1e1bd5e35bd4c251db7c56b44f27d1d5fdb2d225c1100203e6f81bcd876d46c40d7e7d2f032ea1bee880000000000000000000000000000000014426b8868954c77d8c51f90414294b1f3254282fb01073624bfb5e84fa70a6256e0fbbc6a9540f605f4a91fc075a3eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059893d2ceec0ffa31ba4f6ada42199d4da6d846f921bcaaa214448d6a1856c44e0332ce78dfa1a0921e8ecebec58183000000000000000000000000000000001463e0ebdefae0ae7fc100f799effb6947695c6f3bb94d5ec3ff6f27da1ea482a4feccf1ffb0df48099278fd5eb32c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcf0f22a86470f8b7bd74e80edaceeae3919abb65151248bd5781767a8b31993bb6eec0661cc32dff8c1deea2231f4700000000000000000000000000000000099ead44a200eafdacea929ea852cf7c633355c4d32349e8c0fff2689edf576bd22c0eb2082a3819abb1c55161719fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c47dd5fabe2b396544222bbd5dc9b006fc7f24f99e911955725abacdce5f1cb5f571e7c030b20e24a6621e4e47d8700000000000000000000000000000000144796ed5abdb593e359307004e6d9de7534dcd31b837c364a239c4490d97211b411d8945421e980b3a85cc0d5ce6fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e2cfc567cd2a32d5b66f093e9ca8a4bb7f59191b11da962993f66607beefd625e9bd3ec3d3eee36dbb07c1abe5d1ac000000000000000000000000000000001951f4056c957483a2e88e193e40eab2cb6bc4a6d2f6d72fbfb9888e0af35ca44a075bab0e01ec94bf426a4c7b5aa7eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001687c7dbf40f050b409a4143b9c20e5e2c058f1d5926f1c7b29821a659d4da2f2a78c3481da07f6665513e6426c1039000000000000000000000000000000000102eccccbe47b8fa6c3e68176aca5def09aed31de87a69b82d4f484c9e4c34afa3308f7835586e58e56fdc793087cc6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009003c1861ef78913c0d70aa531c8d696089b70ab7bd6c22a2f4b08242c37b71e118e8b6bb23ccd7b5b290d8f305bd000000000000000000000000000000000019cc59172f9f7e1bb75b620192a23faa3af396420a827222d5503917a6ca7eb26092336fc2c0a27b9d70cc24f780d13b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002217a8990d2ec8dd6081b5bb1bd7a5703ded9552f5160500cdfe117ecd70def95394cfeadc5dfb42f444d53200963a8000000000000000000000000000000001942c9b156cd5bc99b299206f609f1680607fbf2cec202c9325147225cc4ac9bf0e10f9cd32dac3881c772224e6827a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018581ed8147813c72000022206150d858252c79a87aea69c829364060e167857c2c454711205f9de6878b86300136f1000000000000000000000000000000000eb5241686b60467221dabc4e2d3e18a92e342058be282f68229f6fb14bd51f68bf6c54843575766b22450a7b760984a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f453559b199ca208db36b21a2c7858f1f3e9d30f2566f9466e2f9ab2ed73ceac05a1f7fb5834a10afe90af55cba569000000000000000000000000000000000abe52048855d574b4cde8c2f35d82a3fd23ea1eefdd49c4731823500bacc933475f24ea3716f836a5a5de81aaec46931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd1f1e263e5b2b6ea604bb7bbc9c272b2adf2f4b450677d1900787000ee88062debc10355892b948660c6ea6375e610000000000000000000000000000000008e449d045bc6ecee6287e98036008dba3060e2b4f6602b199792d7a4bd31bb248c48a0f0ea0f07c3eae96d118a071991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dedd05e4d27fb71dc62af9ac40556ef1077cb8fbae8e9dcf037dbd4ebf71f5a02b2dabec1b0f1ae13b5eb9591ef5bb0000000000000000000000000000000006252be4eb450078f37d845be739239820dcf7a93cb26777e67e16f834edc57ba143c82080c493d557c3c2708f96a3821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006803e53cff8936205d02afb27ee07e924d42d9a12f5da913941b78ecbfd79e716c741393a39c5df008772fa30d0792f000000000000000000000000000000000e59a8cb64ea37db6c7ef92abfe29098b5f897746c19aea732d9a321198186f8157d3781ed7d4b46a867f35b636672741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002998a4c031aba2f5f0b78985fa6de35d7c8b4856a037f5aedfddac9e16b9ddd7a0067eb4676fad62840b4438566819600000000000000000000000000000000107c286b9b4d931bec0212a83ec4c4c4143f4916b64968f0a7f54ad88e8a69444a82f1122cc73f34baa540f775b11d421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f603dec5ab6a3e421c3cb12a4033fe3fc8e10b50428ce09dfe1c3b432f9731da008f4dcaed2edf37ec01690d52efdbd0000000000000000000000000000000011294a5238934fd78c1c28814cdb33b85e004ee59965907f13d3e3ea3a408bb4d0cd14a1937eba8fc3c2d5c53140a9bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016460c4af8ca797cc7d10af7e8c1592bfd749cae62f39a8fac6121e5fec95000e0968293c667bef80d4227a4235e8200000000000000000000000000000000001380bd18d7260e6a37ea44029120fcc0428cead4a259d11ef28b45f8b1a8d6adfa1b264564b5d6b33e45063e72c546cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000154203f424c1170fc65ee9b5eb1115ef77c64f892b5947dacfd3dd728c602ee3198a0050b074482a176db7d04ca5ba7e000000000000000000000000000000000b311a97a9da2e9f71f4f2703857412249ffabc0511d7ebd0a9e1e59a0b51b261b9193d44cd7744ae4e758f6226c6d8f", + "Name": "g1msm-20-jwasinger", + "Gas": 76320, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000015bc64f31d45ffa9185f935d1d118d253dbf222ce5e60141aa3e233b9ba5b55770d3ec5cdeb6892c0e050e4b802423690000000000000000000000000000000015838131709922a7f4d3181a1eacaaeed1e242251fb3079de6bb95627bd9eb16c7bbccfb8b47dce1ab293cdc543e42661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101474b64c5839a3a843e7f36ecdf91835bdd0328a77c0c1517fdaf0b985c5f553d5ce79245f3bbd01f97433b79138e40000000000000000000000000000000018b64f40cf0ded14585325c9ffca9cca458d90eb18cac7ab74a990df3df3a0ef9e76ea8050e9646ac23302d5bf51698d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9ad556cfb7e2785c21be67e9b50bd034338a12d6dabf47734bb4309f350ebb7537e7cf55f262ed8f3d99510a0e9a0000000000000000000000000000000000c4c9f76de44e76066a2b10a9d48c4fb36a5518bf66e9542b033fd185b77262583b005a2cee0e61d75b56264ba16f7c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054e11da7caf079cbb39ab0c386e98b43b99df7505e0388b9891254d24da31987231ead48e8f2d2554fdda5213adf070000000000000000000000000000000000df4bdd692decaca65957b5cc4cd34c33d6b5e85c9ca4a1e820e771fe67efaf0f32aa6872d3ff91bc038e40a9a3b83f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080c27e8389635a1f1219cf420adf5437cb2ba7d2905406d41e1197c9b5280b38ef2ad0bda1673d973dd4bb6b8111d61000000000000000000000000000000000a851fae3033cb150055f8992b1fcabacd86e5de084fe8af29bb06ff22523429f7262a73c20667bb75045732358b05e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953e9e19d7e6a1a540bd5e254df7c72b34b5e58307a2e36931550e1b9dabe8e3207932e3e0d76f0b8f6f2abca06b4c90000000000000000000000000000000015304799d98bec0605238865ec6a9721b59cea7bd3ba721f0ca40e8404d1a55b13bfae47126db16386aa4fe386c187911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001de88b30b2d7963d901f392b1fe38d6b19511fe6360486ff63af6598cf071dbc2ba984d9450a39a0e036606fc2712af000000000000000000000000000000000af2ab4b3000ef303c2230b3b0eca9c6edaf9a7df5e8d4f83678ee0a2024dd462dbd5ec698e60aa118684305aaddd0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148995c67088528f591eeb46892f299148056803a3ef0748a84fedc983963398a71bafebd52e9a7eb25e7e7c25873fef000000000000000000000000000000000a6f1cd26a1d1b284c5ed6274359826af934fb7231de804b6d1b98676fb6038536e96c0d0f6debd6d4ed6284c98e54941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b96d6fdafeb1e1289715f3d7471a367df97a7c34d4b6fb12b0a2e85a5ac495de986232b34718c3d11280afe82c4e77000000000000000000000000000000000b571426280599d2cbc2758ebfc33f3bd21e6a9091700b5d8b6c2e85b9c9cb337da24039e504eb1da866c7c60394d8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007addc01bb8a8c94010407777e504523a6ced10c898594b0e659b886d82c0e5f7af39706875f6143f9b282d75687f02a0000000000000000000000000000000002ed6edd4e0e41bb0d4ee156b2dcfcbe58793701e2170bb98138f25666d1f49fed33ac366e2df79399daf6d4606d47991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000878c2dbfc20804fd2dc4528d742119cdfe06eef72bdbe39c3ebf6416a4fdb2ec7455d731dc37c64a0eee45be6a1636000000000000000000000000000000000711990604ce169bca55b086cc08be5c6ced607aed02bab7ce5e23c9acd1a3c730273ebd9c3e3a9c96049276281d72101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7e0b38723be07408ad4b39b2bef1b60dd259fb58008012639aca83a30925fd7a6c5b2b1fd03c04a3190ce2a659436000000000000000000000000000000000643ae3f4ceb0faf7198855e4c218d2bce3a84eb24e22e7ef04a071f9fe8646349a059cd9f7b9df3d03af8dbd31154ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e26b83f125d67bb590ecdca6fb6cf3d80a7736c4a72c58b5cdf554d9a5ed49524cab86ea90adf3e791c08520a4955c000000000000000000000000000000000960773525a96f28df485c6c2e2cc1fcbb8f61c73cab05944dde96756b488b78601333fc24ebd522445f9a34a07524b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003714bf8581de78482c555daa72e47d180125ccd8e07ee863134f752455c1492b155e1276e3a2c84d6c8a24f772816e40000000000000000000000000000000016810dfe3220e8af10df32e152404a140ce28afda3b0a10e90761de7d0f177e6e0cf8ae1489b98dcab5cfdaea6acd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a49ecd2fe73245fc2cc055afa5d0cfbf8ea242c6a66d19f05b27c9fd0a392992c8671dc554e39522b1bf70db85dc13000000000000000000000000000000000762fbcb583ad96d8e10281d11de847edbb64581ca58fe848abff3fa328a75d522fe8e721411b8aece7d1caf5d5be52a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099b8bb6661ab5395a0a5797beb21479cfa46b67faf6e7faa92e43c692ba3e9241c70c2fb5ebee0211447fdb98cdc46a0000000000000000000000000000000009f193b600485465c6af4b2752927743d0dd265cbdaef29cd441a02e263e17b89056250a3bd31dafa95c04e8fcb1b3661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e12a33e1a5d8bfca57e04504f1a38cb4aa1e5fa166fbaa4c2ca771862ceabca9f61eb64a6e67db45f0c944f6c1efdd000000000000000000000000000000000c84f3f126a8c243e2e551724f3ca237bb3380e5435cac7257bdd4dabd7e8c159aed600cb83b5d0feabce363c5fdd39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87050c11c633f2fd76b328069bb564a20d5ece1d1a214aba046bc34af0408184f7cb42d7ec1f160fe275d9aa197361000000000000000000000000000000000f36a03ea617c050594c8eaf6d3c3f0282c47a1a2c4b696f4dc1007769e9755c1ea2ba3ff1fef0ab060e6efff16646911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3742c60c3363fcdf70d2fbc5f267197d37e60ad718301bbf5bedc81627444c4f498fc141abb87a8f293f799896abde00000000000000000000000000000000163aaacaad32777c6b78e6644dd04f257965714c07c2f9e76843bc8d5a7183eec35a0efcdb8392a4110f2704192d25f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129e170a7c21e69257a01143e3964f38b85c8a1de7739cc72a6f374b2f51fc8d3baa7b5e1e8787d74d6c646be4f3bd9f000000000000000000000000000000000976e14fc451626c1c6b7a464a9cf2033bc2b269f57ec9910b04f15a6b98007aeaae08f82defa96b97fa695307255ba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfc72ccb4083136e8ea2e708d8b6bcfd9eade230ff68794bf0153d01fc5ad16cb650c76ed06f9fd40f5b35e12f7ca4000000000000000000000000000000000ea4fb8b1a6c1f64e0505ef9db75419c1aa9fdd1611e7d361f28a6f8a6e84999cf242e2d212b72bb94f79476a6fc858e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000132e540a9c76a1d0926d857f6ad0bcb8faf82f66ce6d134bbf35281398fc9109d017aff2e445bbb27511843d409d914000000000000000000000000000000000a562ebdbcee78be8efbf730ee30469727ba3a89b690d20614d96ca1885c5cded1c56f8293b9e4cbf4da1552025b395d", + "Name": "g1msm-21-jwasinger", + "Gas": 79128, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000630d8a3899bb020f8f123b8efa6f471cf3bc0a7b24f95adfacd2c6bc3c4342de197eaba0b27861ea6bdcd6555ed5c350000000000000000000000000000000012da1972158eee1aeccc48b4edf597b779dbaabb9ca6001b0f35cc457816e54fef257fcc3d1af536d1d2c115aef5dc2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c0ffd2cd274cb7c146596723a2c26f0c1f339f5d2fe0828d7919ebf977745fbf2f9ca5e7a8e244e3d86a7fece34373000000000000000000000000000000000ed343c846bde6c4fadb4510dfa383c264d605e0717ee8453846963a13e70b1cb97c205fcf9b3d649e83b27e2951f2571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000879c9853c955fb060bdab01a7beb1a09b21596d546d91ef420c0dc53cee445fd91affded5c551653444b0b4ccd15347000000000000000000000000000000000a7a9f59cd134c59f27498b751ee66367940e82e06a2d4952055d6cd4254452e29aea2e4c65b2531c355b9858e3feff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141c76e1e862570f1c1f00fcbbcb661dcb5efbbd5f2d3a908bc0fd9dd4b29b55a220f000c68e772b47b096f93a07dea20000000000000000000000000000000004890da769727d2b81e4946fe454309c39e246125c660cfc1c302141945dfc79cfa96934b908ec31f32bc4fc3f6e6eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bb338d98da77aff4f9252e8e6334532e8a2026b69416f6256b965962a6221ac840968d63de36c5021a3aff774cfdb9000000000000000000000000000000000d101e749765f3d28ed9aac7afaaa87f93d5dbded71236ab703343a8d9147b5078aac46f8a401ffc973a5fc6c39a18301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4bb823ede88102242f1badf202bcb61d49d6639e0984b4b9ea288dafaf62e8e7b288ebea8e2d0625c7b76ea1745b30000000000000000000000000000000000ca87cbaccbcaec6a3a68511df40c7b474b275d46fbcc3efd145538763e6a401eea7f0c1b4bb0b90f740c8ee9057ee5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df536ead3755e616cb8e6459a599488b0ca8501c19f53c373e8684334810e0132d685bf78dbbb0d16ac1ce4bd80a135000000000000000000000000000000000ccecc27365fcfc7176e665861021e4bc363c1f5411423929f1e0f31df2d48f04f9183efb913e4cd97501d0d4a2386081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171e5674010b2608faedf1ba90f343803ee186634deb046b78ccdd0dd99a0f05e735c2367129d141ae5035d1c81d98ab000000000000000000000000000000000b428956ec9d5c44e3dd46a9a5912a3af07fb95a6af109bbb0876cd3ff480f46b563a6bd1a7b180ac697cadea5480df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000681aa8ac7de6c7320c6fb45e15433f62cc6648043424a0565eb9cc65410574f4bdffa41814831c11df9ff791c9f729500000000000000000000000000000000088dcd87e67cc7d354262a7c5bafdf1bd61e301b98c70c01da3ef8a4373db943a7d5e9076ee51656b69903fa7faff4e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e42abd90762c3b0a863753370d477fce663b1d6845854cd78c54446d1a80ca5c5747b4ca4db8585987ecf70fc6a84a0000000000000000000000000000000003940bafe9f66b705be519553931f63291d557274f7ef3dac98c27d2fcc30f82d301ec7ff5bbcbb4975176dc84e772e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118fb540b05580b66fa2ef3792f102c6def24e0f77d3a9c990826122f4b8ddf5f60c232ca1588a054938426b8b1a253e0000000000000000000000000000000001a0f4bc31f1d7c02394a8d1b383a6e50f47b78cbe9e480e00fb6eee16d5192a42bd6687e433629d581010d76ebbc61c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a311f0219808ef67149af64009a0f4822268699a0ba11f4a89a2ab89b9822c5bf8c5b67b0893c38c199e88918a685d000000000000000000000000000000000963d71642f3127c3a25420f2da66df0d13c57682b6df7e6c77648b2438b4b697b8fcb5349fc4fdea9a3d51a449574c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186b60de25c5eb08254868851c057fd10c86bddd7df505bbb307f189480504bcbff2b02dd36f52328229171bf4c6f05700000000000000000000000000000000146b461d08753f4783685385eac0080ded6b7f972a1b7748f55e6e8270974ec164e03e8cb2d2e2f16e943c7a629900021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8c951266013304335955678c9d2d1fc6e4438f3754273009047b494909f9f24c68d4d7d2d4b9f51e25c4ed066a8b00000000000000000000000000000000016dee0cc2fd25e408c69d66325bc0e522327cc3b6b7724f0daa071ea371239b26399d62abb7212d1e9a0bba6cfcbfded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000843e22165aa7dab4ad827e80a21321bfda5b26eafcdb76186953711a214f103cbba3ba112205d9b2d6afa9b8b91111d0000000000000000000000000000000018440a66fd14fcd88072c9bb97d69ce8877e403d99ccbf87cad3fa44b4bca473293e4d83a5128bad90803c93bfddcd021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe2c8d5603c21ebcd6682aeccd9f27e5aaca6e79d4765eeff0c99e032e02df47f87c65a4ae8adfb4b398d44b2b85ad7000000000000000000000000000000000381081b8bd577fd03cca9176a22cd628b9373d1b72db0d7468032c0104a687d0385884ce9f8641f875bdb5af69f9f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e47e2d03142903cb6e8b4772407305ecf81db62359bea545f8f4903b7b804725a34a8461b1fed82a94b7a75eeb594fd000000000000000000000000000000000b2538ac1774e397e80366418a8d13bcfbffaa46c032f82f380853b39306e8f4eca3c4a25ea98abeb1335284d6c9a94b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959f0fc6ed7b3d0a42be318cd059eef5ed6a88f3afefbb52feb2e93a91f56b92ec904e8404a3e82f6a8dba2837c56ed000000000000000000000000000000000d3226cc36bce4d16e24d3e92982bf0222c1f6e1d3d985d3fdf9ae4ec311cbbca95ee1e420a321cda75ba131f3eb90221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f554e09658526373e2a962b8114aa5a6ae4e479a85548fd000b18a1129c5307d97a398b2db4389fe2f327efd16d7c380000000000000000000000000000000019a0ca577212de3617c7999b1a695af1d6e65764796d4abc7113bf906fbe844d993032f3d0244f2b321bb940ca437d371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e0c80927023794ccc27f075907d24bdf1431e2d10d08b6f09bfc278514cfa2224b8292e2701f8b3fb18ac4622b6d19000000000000000000000000000000000f42933ca3a07345d00fe9d479c701d088816659f467d0638db54be0eaaef228ef01e3b94e71a99894138d12de699be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007acd1c87f6f854cb0727d33bc179ea2aad69f822a70b77ad57a2e102e2c6e6eb0e57e0f5389d59b8fd0284d903652ce000000000000000000000000000000000d200877b980c07b191b490ea6c5e733d9a2758a88129676f7c218b00fb14cdc798d7f4dbee7620888dc6318ada63a671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e09285782ba9800a45fbca1b35d11ccb56c617114087eddac54700202b118613e0fce44f6a8c41e77e14f17295e8cc60000000000000000000000000000000019c0d74b25744ffb8301159d5a888d4eddf0090e7798f5053317ae3a55d8c8604a872498b59b22eaeee9960cdcddf91e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000079ce475ca4c6832183c8e35b888f2a4a7970f5c1df2269857b32ee78d541344f40ee22aee21412905032b626575da5f0000000000000000000000000000000010a6f229b07571d0a833040de9c406afbbc9d525499e917e1a1a376d4ab0f5e129265180ff96ea297defe41537e3a99b", + "Name": "g1msm-22-jwasinger", + "Gas": 81840, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000013a1ac003ee6c6a39fc63179be0daa3924071b5f3fbc52bd8ea84146c396bd036dc7fb29aeba4b68044c8ad86525b4ba00000000000000000000000000000000080500a0234da123f16713b8e7bc7ddbc615bbb2dd2009427d1c4f6ad0d66ca403a2df8802c68cd86cdf45b70f4371c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cbe587f05dd76373862ebe0e9328d029fe472ff36635232ec4321ccf89725d258fe7935ac427c3daacc98ae70b1dc700000000000000000000000000000000194dc5b447c63fbd9422713e2bb9c16c75f275dd784872a3854577eb12409c28bfa3beb7548fa55f11415955bf8234591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170796d67b9c300069945dc152754b5e32fba08c369f8fd2cebed503aa12cf36e5365c8ed6a6b741428c6ce36137d9a4000000000000000000000000000000000ab0241542e754c92d1621c99e4e5741dbdcb41d85cc20d1641334526dc411edb1961f32423818d1104a5d499b3506f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097984ea412e6527f0691cdf1eb784adb01382e07f3ce8cae287d5ce8dd9742cfd4e945c2a9dc321cda51b91c9b2b5ab0000000000000000000000000000000009d018f20be4762f7892da5bdb3dd5e4b96faaa042a2edf0cebcafd483ffdbdf961658f461742dfe81814c4c12ca868e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001629134c3a9993123c31b7aa704f4d8041303809f1c2740949db80a25acc93d13f6917197088456e8e26a7a5dc8a215f0000000000000000000000000000000000bf30c5d6cf6dcd953cdfbba1542ab7d90f8356d54f6d1a59c74996bfdf73205dd06ab0218046052d57bbf3384383111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a6e2d4de71f07e950d78063bc0f013c8b61e0a331ab58396a13c6280cf72399a963497956fd1823ad96812603dd10d00000000000000000000000000000000165b322d91def7ec9fe4c01f19495d5dcfa1396f0f72aff2afc8290a512d78a7f25cc7db95323d39677aee224c04572b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5357adc1a74e302ea033a65428d5b5eb62e50d36e268fa19eeb0ca24d9d4057847b3ada23fa957590f68d287078498000000000000000000000000000000000353c8d6455b5b2f86585a8310bd3446249e0adbb168242929baaa86cfe61d8f59a376e8a0f887e2ce5a9bc2f51a2ad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017de9c7f64513d775412007f4d5cc8717d72bfff75f2b4cc079ba0366339456a212e3867f9ce38d8a6f3453d920e7e70000000000000000000000000000000001468a9def6838b2ff3ce0d9604d5d2711996e9238fa30e141e701642e260bc87c88489c163eb414af4a2e60e427746a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003815ea43da1556965c08e84957565c883189d6f6479e00a03f863cea065fbcc94c1c4dd9f7ba35f7e7d14a95ebadcf3000000000000000000000000000000001624b798cb98c5d91db7e0c7ceb664aeb72c2f523382a22f10c3f9d003572fa87ede4a1e77ce52eb0cc4cd8db8b663981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac26829dbd1e983eb58c1f1ab9fb0abcf240c4832c45b3ecd45af900fc77de2262b3c64a3539dc4495a7351478c017800000000000000000000000000000000070054c1fdaa77461f95792b73d8a6394eb227ca3adbe4376de5c4ffabfa8c36a40a51664a72c3887e5f43763cae5e1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000466ffe30dff728f51b6441bac62ae70d7e454c8fa0a17e709637eca99ca365151560ab2f4869437f705e9bf3e2d3fd80000000000000000000000000000000001faa0247b6c248edfac0f5ed644d2cf04d572296f74f26ffa7171f8027bfe9e04a7ecbdf43cd7f5def400017729c5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000549d6b517a824df976f77ec3f141a637403531c5ba87048860fff31ea9f148a2bf35d0b784348242fbafdc034abe1d2000000000000000000000000000000000a97f1c5ccf4f972a0be22a98e696d86e395431e63bf358b4913956e5c80242757dade0a881ba5147b62c00d26b266a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ad7a558af3eecd79d35ad3b4732e840c9250005e6e3381b7139a989a358ab8fb8eb1978e2208b06ac744f20e44624900000000000000000000000000000000020a52094ead196a3066dc9f2073e61c3742d68ac3524f36a056d334a99d9199b7b9c653252853b8eabb1d1b63a78be11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8e0dbcf575f4f3d2438a8cad4a3f8842dfc0f724e965105c68c79919fd00fd072c05be5beb746f9b2c415a09312fbd0000000000000000000000000000000008672784a8f9a247fc78a11bd9183cbf6f53196cd836cc785cd4944a921c4b3f8bdaaa579f004d5ae06689a9a9eb83251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010faa5bd353ac7d8d7760fb01783abc3c184c747a41d48808826ba3eba17e36956a4fae422d3de4e2bc5278d59a811a70000000000000000000000000000000008f7dd420c20dc0f1fd03b806217723f58c497cbcef94cfe8607ee2db2a154b748a7611e7013119626514c159d26bcd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f20b02a8709b06246f9aeb4b440bdc62cf277f7da20a962eff9047fe09626d87456fd69a194c0f137680944197b8ea90000000000000000000000000000000010588e4765722c502ef2dde60c2aaadec00ab9d01cadfe2c384485fb16e3c6cae071b555bf1a2e03a60bb4055f84754d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054f7c7bb1fd20435945897ec5c41f6606d5bde7f0696679327ef4bc813c7e2235ce9a291717c59f3cafbad3ea2b61e000000000000000000000000000000001245b4ae97be92d071cc112e136fdbd6bb686cdd62d2e8fb797b87fa5c9168c6ed49b03906d1c72c7f073888976c2c181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101ddfa4ebcc06050c0b2e3d6cf220c2c170ff474b9b6d844752bbd1e3d0660c361dd61025ce65d679d78510bde481ae000000000000000000000000000000001979fbecf4eefab0730f38548764bdb81efebade794a94f2620d952771e529048bffa392b4eee2469b566596df2f504b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3b8c541a4e71551d38f558c304c93652058526353cb78559cc0360c75944e222e11d11165d1f46421d449b305909c000000000000000000000000000000000a6d16729cbe57b94dd84f8503b00e97d27c7318bd5e8c44f0a1d061f8fd83a44ceb5b74c50f5199d469de439ca07f2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000441c138400d85320df25d3bd4aa3577fabf1ef8ca33f6f961dcfdddde3c6f81ade3c0b93d39c4773f5eefa3a1789990000000000000000000000000000000009c637b4cfb300ebfe5ec2c5d8ba3670b5ce13a4ace2b5c5c1888b51c87ba092fd34ea37be80e86d8de7f8669e1653791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e8d7ab01e13cbb9a1e122d3672609e9c26601512b1a9e866ba7b7674aa0c090cadc8207a8db483b73da6d74af31f19000000000000000000000000000000001768bb77818c8e7b9762980e3135d5eb6cec5ff265838352475f109255fc9fe053d7534f1369ce2b1206761e7421446d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c99e05522447d77726a67fd536efa9d1392d09d59bc5fcd0d7ac6a50153dc430aea09e17dd6e7fd27907449a09ecc000000000000000000000000000000000b6e80c5cc34427959487838223293e93c2f97cdac85f12071c6badb0b42221624e0357f01786d83f6c6b4dd8a57bd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005dddecc56f797e579cee1f00e2513742d4c6d55f00017bf7ddbe37e2e7a52f58200d664f7c821315d40d015f7c06d20000000000000000000000000000000001b83f022f408138178b09c9435fda4b9ff269b22f600b54c572f49d5db7a35d4456c11dba7bcca41514fd331b3bcc051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000017a5d98586eba4ba185cff26b92ba6958dbb31436481ed2a42cd8a3eb2445064aaa96c7698d4fe480a5ff6e2292a2b550000000000000000000000000000000001c16f0114faff885a347386121f32e78e1b17d790e568eba75f487da6bd19e0fc172ef7d751e67dee7066f0d9c8bd0a", + "Name": "g1msm-23-jwasinger", + "Gas": 84456, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000a4738cc3156bb552f729ee495754d1c84fad3c00c42ec3bfd0a54be986cb5b23dfc7b4d502c5c7d661ab0960bb66980000000000000000000000000000000000234fd63c2ba4eb25e226795b29a48fa0ca92d8c40724c4c45fea039d0c13aa978754a97f3bcbfd9543112b821fe280a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fdba950b878a595da471cdff22f8d80ab29992011a8ea25bcfd554fe6b809d28d328014c660d825db1f0863b446aa50000000000000000000000000000000001e4823bafdb73f006c7dd0b765eea8f81cac996ef004eb260e3cbedbacee9d6e8c8c64b366d0e94eec95ced4aadbe411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffa8689df9d14a11c72816983fbcecbcc480671365a7bb6f8006571f4671e777ca42631a671ab4586973e77fb0ce9dc00000000000000000000000000000000191fd2134edd82915a18e7f7804073c52f8d6ae95b6fe6299618e205306ebbf5d9e77805181d96294a7908bd72b5b5f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153a48bf28d40ba06ba0c754d355d616542153b46b383629e5c6993e40cf5b7f6068de7c4c0d0714ed35300200f614ca0000000000000000000000000000000017991aff5596a276252b61be8304a2930f5610c151fd588ad4a12f1e0d718a43d15d5f95ad20618c7092e61f440226ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014bd03750c8fc5ebc4c213b610e2b64da59843e2ad755611b0b3002792a225e7a9abba6037c0c3f878ed84f257c26520000000000000000000000000000000009c7a068c5a405fc6b13d8c70d6d3c426dce9e0518293fc003e74262839616b1054954c22f07b905901274d9de914dd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f6a270bbbc681b924b87c785f5f91db32d0a3261dd2b15db41e020ddcd1b92d3db3aa82d0c050bbd4c90b201b51239000000000000000000000000000000000141f9139c391fbb7f7286ab2a5497abb72f7eb661deb8f9807dbed4b2ada41840e5093c961722567beb2ab52809156b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d625feff25c35e5b1e7dd4b6670c8ab8e1935a781c492c177ecf91a079287a34025473ce7b1fdbcbe38cf7499af47a30000000000000000000000000000000019579322ff08f6e7fe8e4d7e041ebc1c1970ec7b4d132ecb7cc3fdbb5593fb783929b447892d7ea54e97fdc842f214cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b95cb4c25ae1584ad6599c41c5eaf876b070e5b4e63f237c564b993c57e836101fd53e6097f732c31b23bcf5073ddc0000000000000000000000000000000016fde7d3a596fdf26409506527bfae0597768426a47064d6924a05d6d2919a0c93fddf1c84b4027167d1cb07c5c7aacf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074373e9531023a5e7a7c5196affbd7ce392658f5bfb777491a48a1130cd16d2f12f6f57555ee682b2565115815ef0c0000000000000000000000000000000001342e7e3ee8d68f55d49108d150717cd8bffeede5854302f6e90af0a1e44c77320c8bcb2abb2045df1e96ec003b098ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104888376cb8ebb14f1c801fd10381612ece16dfe2cee55988c56ba4a61e0fdedd6c61e59ccad70494a519e9f9d9a533000000000000000000000000000000000ce442c17ac2e16e4fffd181b8faa022381c07a4d22fce9b15b37e41b91765c89c7cb7a696cfc8653b29429267f699581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c9979238ec82876d78c90fef5d7a84c288baa11eeae00a60dd3829e0977f001f0f8708c8da4945fe06548cbac030aa000000000000000000000000000000001129ab96fe4f45a4e5b3a2b3c6ee0232eae5ceba74ebeae5c0fd4b16815806f1e581c7fbbbc6ee56353fd0c4873874bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003943baa286d9359fb89f03bb6c533f7f0d21818785c45fb34b11f6e606970025294b81319ef8a16a24558fc71c1fb4c0000000000000000000000000000000002f1f85a505537efa74ed629ccd6f3924043f1b287a4e657a1963cce358e3129f84fa4da19ed6dc2664297694428019a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b30b28044eb0a55f9eabe957661b280a636d986873e9bd5c762e8410144da9e7ec05d523267a49c9ad72f9da044f6000000000000000000000000000000001013f1703b603277fd0d48bc3c08c1562d13ba0aaa1ac1f415998f2c46eb69528a4552559faca7cfe6f266b9ac2c5bf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064e00e52e0dd1b449245cdb0b1b536a3259b94860528d07f379900acc1015386e6c568a14768c071e40155b22739b290000000000000000000000000000000019135f89a51151dca8766e4e951dc2c163553073f640ff6e1ac7c859a764c3cfa02c731bda9167aa1b06280d945813591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f09862ebf7e8ca39eff96221c4d44f73d5c8e82bba5a43e1265fa0af5095e964797be9da569bc20f05b0d1ddb9e53300000000000000000000000000000000151b33bacefde5f34c1ca6270a4cedf95014a41c3e277becde7a94b0fb8e50e7c5af6bd3801e743d57ce682d480b94831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000103e42bdbdf1f56d007bca4e943f060d7309b334aee1f101c9a22c5e1b15c0e60eaa55fa57c7fbd8732998c0bdc10950000000000000000000000000000000002fce06ea3c574704457431124353b62cadf392c3a842bd329096afc8be9623e1c54a34f6ad29e6fb4b00a82278213f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003abbf94c4e00652e0a8eeb45cd4e96ff3b35e7df8f3f4f1213b474636965e537c3e523c380ac56d08b617ec27d69b8f0000000000000000000000000000000017389987dd424b20ed670a7f45506c9b0a283e133c9a84c070490539fd25d4a803452aa6ba8a434ac2742b1f7bcf850d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018786ff5bba07115a01cf0161fae631a6cc355e9e636b799b0150b72d6c0526b717af9efe17657070db9389939a3f3e10000000000000000000000000000000000d1c1bf3fa884f89eb36f2ca1a035c438d87d2188f6c843218db89cecef0dbdcea2dc07c0d1ec7c203d0fc9b9ceee2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032147e2d14f8dce766db528dc6673545c2009d594e971d42f07c3d9b1401b00d558fd7e3be7c49a9a5ab02df5f8784000000000000000000000000000000000c3baddae6eb4e38c94f3679618f4748a7039f5ef1624c1d78d35628c7bbf8b14f50226598912d5eeb68fb98f15b84071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e459b72271310e5f8e9a42aace59b9aa8cb9d702c01182044e0cb8c2236c30e559acaa68138f09a767b28f5b90de6340000000000000000000000000000000001cc037db3b2ef8298ff3e29b1d9d556c4b3560d1fdde76a2e3aa2cc5e5bb0117a4c1dcf09ddc2f2f4ea794d6bda72971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018845b7230408de355c94d234107b11b635ad3e828997996303f5affc1a246a8865bd8e051bd1f453760236af55d7689000000000000000000000000000000000c61e009626cc3bc33b6857c49a32802748a196a572e6ac6d0ea015a64bcc269b1288bb5f12e614ab981362ab229fdfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f92b8da86be8935032601e475302729625810a789cc7840a9e29164c8d66df555a16b2a40947c42403d24333503ae700000000000000000000000000000000042c8ee47c4ca101a8b6d0d9b8928d853db5e3de885cfa48e39d8a2204751691dc32922f0b3bd14f5197f6e677a45b731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174800ed8fe830ef9e171c8bcfc0af5a3c3a93cd50678a62c318517359345e64cf436374732ed7d1cbc0bc005c84bab7000000000000000000000000000000001501da61cbd8779ff03eaa50fc83db7b7166d7f2185338fe91bb33606e279adfabb6595600854176fcb7a2951da5d7eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e2d4098057e21d22f2279d7deff63cb14d73ca4099fe1511d3f9e714b62dfc1478a12798080df78f30586088df9cb00000000000000000000000000000000117e2de8668dc49d5a4cb01147cf5970687ee334d1368df17dbf99fad6d9fa331acbeb6be770641ebe4c1229cb5697641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000001d946f05084daa8a79841696400f81d374ea47bd4d4eb9f657bd3829e8ec3bf2f7c5507cf629cd323548965842a8bf100000000000000000000000000000000164412723364cfe2ea2cd8590d9d5628a0930f9941021a6251198b092a833825a97d26a68d1aba7778d4ca964911d42f", + "Name": "g1msm-24-jwasinger", + "Gas": 86976, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000235d2408bfa4471db485cd1455cdde3e04827251c064bd4d94d5cedbcd78a245cb84d8ca2f371b0641cfb01025784f000000000000000000000000000000000c34920e6403885dea9afec556c72449f3f1097f23024a991bd3ce06ed598bdb1083b08b114b34980bc1a173ae6ba9141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031eb3fa83089ac3084ecaacb735f0b6c4713f0d231be19def1812c1e589fd44dd436b50a1f4d13f5843676f0da7879f000000000000000000000000000000000ca643ed43a8461dbde574b5d54b1e6fa0598509c44c7595a788f15f7ae2e94bc8eba7847bb6b9b594142d57032dc85b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ad633b5c181526d4499c63b4b2c136896f5dfa0bce582be57cb0e85542d5a217a81c93b9d2bf930119618332207c90000000000000000000000000000000013aa0a2dbc6ef32489879197aff5918c422665e8a1d8ee3859078bc53252cc3207add13e9c1963ec0d197ae2203972c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194bc26b94cb769ce7635982023a42c2a320d5dd0ffd75de1d923f99c57f2f72e15220dbb1606e4c49dec53a738ab54500000000000000000000000000000000032242a58f4b6962b49078790f52deb75d3e71fc0a9133e5bcd4c3200ad62c3de67b3584c83860dec9232e2ef29248e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9eafdb7d3ffc72a3a38d0b41e7c35e3773636902d33b210ae6d27d08cb3d3869abc8ec2972f47bb2c7d602259205f200000000000000000000000000000000059b81a9c06364a4c55ad532131263784196201cc6d8e1518ff012f0568281d92fa1588636b4bf48d8bbaff7fb77b5291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b9cf43c85e5986f363c13da78cd2cb9709dd45ce965467d717f9512eb0cb482cabc220a2d28760a7823f28f624ce5000000000000000000000000000000001687613e9b94fa39bb943c3b4d8d1b94b7ffd19a762fcbb974f3c987e821bb1f275f61bed5817b98dd745c18d5d9bf871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e182430f07126e309b18b1611a773e529ea24da52cf2d5577feb3789cedbe9e35ac6ebe045f34b0a571bcfa92125e0e0000000000000000000000000000000016c4502a44fde0de2a4135efeae38148bad8fe1b07ee6c5b83f5530c2ca4512543a650342c935910f1a852ad0f6058dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc9ecb239c30ab970cd8c616aaa66ab01f4e70dc32e239a4bb09fab9e8a9b1229148b658e2c0ddf3dc4ab7cc93f50630000000000000000000000000000000003b87365410062d007091bfca6df1528122afb1a1dc7fdcf25dc28a023b6cfc320aca7eae1eb0d8b9a05d51eeb3edaeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b8bf43d4dd7cc4e415c8771a9ce73da1806f5c0edeac9c853a48a095d3fd0950585ed6869757ccd12bd6ce268bc65000000000000000000000000000000000dce832d95af32b79b941e8859ea5c418508613392849b8f5b327f1c645c66648a5b80637d2123c02bccb150d6d0fd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e36c36ef164dc542d249e6a38f749c0ea3ae0a1a401cd8026be41e69f43eb14a74df55aaf5ff0e8994c25890a0beb900000000000000000000000000000000023eb730f755ad6728619093eea3eade4d6e263c41fd673c3a502e012637bffbf61041b6a38baaaf8f4fdd276954dd021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009eae87eef73beb3b94052a4567761b797ee6a2d9e6faaf0ca28aa50bc39f3b20671a70d6030cab34d86504ebce75f680000000000000000000000000000000004a92c32ad072ccd5ae26ecf5ff73813c9d7cc2888d40f70f31077775a0f547d140d8ce142e5164c5763e9095e9a0c501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185b76dcf2c4a0190d40dcccb5b8b2d549afee8d0950a33a7b234342e62e1da6bcab0eb5d6383437bdf329367e74f6a400000000000000000000000000000000139f9971b5bfb7aa7a0f0e1913fef4c338599161ca04a2da4a12a1e26f068958081def6b612c58e2306c08f8efdb50b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043d5e7aa03c735e6d81cc70ce636431fb79414ba924dcdae39f71a432507a06ccaf36eb4c8fe868a8d3453c3cf2cf4b000000000000000000000000000000000e261facf6200a1043444c32c2d207eea995e88f4dfc0a8a4ca4a57701bf858f9e938d17705b1016b8976869885410ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000854e02008b6fd4a78fcb704c3c475790e2daf7e4aee6e92e6227efd84123760d7ee01d1992b638392ecc41e8efe5e0b000000000000000000000000000000000e5d6bf1b1c2bfab353273d2ceecee4f8e76bb7f038ba25a142b2cf51f653244154f01f1f684aa04536c6d932bb9f0951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f293d464c06742d0ca894275919e1e30be57d39101fae62ef357fc73d5f11b2e5519bb9ebd51d39594164386b7d951900000000000000000000000000000000188dbf2b794da389421832ab76369c0378943247ba4a6dadffcaf073cf11ab45ac877782d4ccd2a15cf6f4acce0372231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a6c1bab7dc8089f0a62581294bf729808d231d3171be45939e96415c61b3df7216e6fa4be5f59fa080f888ffcc679f000000000000000000000000000000001367797b3a81c3f9db9dfb582f15b5a8a710a8ea6fbc6549247fdc386025b95742e23ce942633974ac18fab6de138de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c31a3bc57625598543c49fc846e5ed4b53ed157ad54f1a114519cabeb797550b7e65711ca5d4bea70050ea70e73290000000000000000000000000000000001693cbba09fd3eb5f1ae522e8f67c99acc4d01a963dcf7653002e9591a3bfe9a59d14a9cf9f56af1b2a4b3ab2444adfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c49e3d2f222ddc28d33c2859c010a33eddd18ad400666c35005ef2fdd4732c27ef0d5fd4f0223254f09f58197401e0000000000000000000000000000000007d1c9c088c987c90a6a63ccbbf73580a8cc92bf372b38448706270a64fe43e8fb904a489f535678931ad71bc4835bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041298fdfa4b33615bfaeb8578cba891cec83ccdf1ac30b3dc66616e9d3b22472a72d7712f0ec92b52308bbba9b5350800000000000000000000000000000000130ee8e36bcbbab76692a295e2f9f308b24c04b2cf73bdd8cdcb3d619965a02fca118a6a6cc1c25747f1b0ba336c776d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9291061ebe11a69f275a5991efe9e508c4dc78652e0e4842ab1e4458f6af284eecbe4967c405078f8236292ff0a800000000000000000000000000000000000a5254fcb787af85ea1547f5e10d6e38c5ef81745c5ff3053eced33b4452338d2fed8619fd39c2255dea2bce7ed68a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5c027704bc592e57f80341f158f72485cc1662d6eb923ee88f533e96eeea1ff482a73e1f9d02ac6a70ebc545c41480000000000000000000000000000000012b00941f661621f3e432b5937ad19ddf53e57673bfb97a22d33fcae2c1897a9191145e09fcf1599ce92d167a1eedbf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862c3d342f3334f4d3861d0f9c225e3580726143db68d219d053bebdeb29014e7cb9aa97c20f50e30829ca4cc2da6c30000000000000000000000000000000007527aca2f0191f57127fe5cbfc8186a82fd3f035fbbaa6874a7086378fc273b81bfa74b448f4298f58e776412d32ffd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b26caab542048631860b7e709505250a9a6703920b278ebb0c142923cb9c6bc6916927821a1821bfac621bdc8cf35c000000000000000000000000000000001241e26cf089857f566b81e5d4b2f51f5da37cfcbe83b3e18bd59a20cacf5b5ca751556bea36cdc7907eba9148f48bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb55f2c57de44ed007d562608368b189ae0828889203c61f233cb34cd39f498417524919907ff416d8ffa13dfaef15000000000000000000000000000000000ba15c6748340796689f986c1cc2667b084d18c271c3b8b1b6f876f52c0164d36e7eb221af8696c79e5f1501a23b6f0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4603c72e1e939f5b45b97a90ebd563c8f4c46bcb81d4e2453581eb0a2689711f1b1f6cb3971407787e1041812fe3a300000000000000000000000000000000155c6b5951ee061964593c14db0a11a1788b1bde3554bb818417f3e043e29276c542c21154872062628dd845b5e0efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000dfd568de7d285f8f6f3ccde0d341833d17e147a8d31349b585dc5ec885d5b4dafe10a530605b07c70f5b3a835592c270000000000000000000000000000000003d34d6b194088fefdaf30ea38a64e606336cad4fdbc3da49982ce5965c3cca0b4b5e5be05f144a819c04a9c064f34f2", + "Name": "g1msm-25-jwasinger", + "Gas": 89400, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000ce9753302dfba17e3a5e4e5e565051db2f842aa61142ac238c420a8592da4f0222b96a6aeb64eb277fb33f296aaaf0400000000000000000000000000000000007b543abc90ee8ba44c789a9746c6617b40c680b94655e3dde5d47092f2b094d77f446dd19ef721145f96ec851b21371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000839fd424c87a71b33c34f86abb6ba1473781919d9cd9f834e1d4dfe66bc9c31366c235e8c3284a565c29f1fe7c293240000000000000000000000000000000006621867beff4c6d93a8f1339e26c5c376fde186395f8369d3b891b03db5890b3d51f0a8f9a79456c81551e2b58027671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114691463c74f51dfc471dae3f0238a5acf3456041504834d8067a1d15931fe3a5dd2a57dc7679ffe9960fdb6257549d0000000000000000000000000000000005565cbba6925b650ed20a68601078246761e5ce98a27485a03187ee5eb520d2fc2e209c4b71cced73bc006069b42c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953e39807f846b1aff5da72d74e8cc979ec6636bd36eeb660759e363f160cd4ddd0f4fdb92f52cc14dd981b5fad09010000000000000000000000000000000001a9a88166a9a18cd215aeb2cd0aaf8442cd7113943bb1b6a79682cac5e2f3b1944e397300e3ddcbbca66f305a5138a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db7f955da72db06382dec5845ca0eda17d403489242cdec8865c6c00d7690b08c25f7dfe76b312e439a01ad3d36679b000000000000000000000000000000000d1341742c79e98a5e70e9c8955d5dc42147e3a88c5519d8671772589151ca669a7ee7f2a22f8a185e13875c23a3ba841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b42f6b3c01b08b48b4b1efa9de673b37c2ce3a79ff77cb8e170455481fa7ab15357b268c9650107b02cc7ddb135e6200000000000000000000000000000000019b49ba5762e50262b8ac78c171795ea2c3786dc804a83c8a316202bbb4e5704a8b1bf36fd4ad0054d15994d1caa98aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a44b1bbadee3913218bd983343cf6e206ffa2227b9b93057ea1ebbf4163bf2df148ec688ba124f59a046738712a6b090000000000000000000000000000000005fa672348e03f87fda45d637da4c4d62ed8790d8ee8f56cbd19b8ffb404c9f66d9777d9aa85ed20656720ffbce8dead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067e195950b5267a0b6c43f51e7ad66676d489e0760f6ffa7ea92156142d63a41edabe8e64787ce4b064ffb11b7bf1bd0000000000000000000000000000000000bd92e95dcc7b62f4eea980324d49fd200003d6433562fd2434a7bd42b5d34c0a731d34cdc80b332311f26461b5005b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001393da3e85fc1e50d8f1f9424de7290b868ecb5b23fa96b543400bd13e172f76f74e107497a93a2ede02493f22254087000000000000000000000000000000001049d8b1d9c88d7a6d97721ccc3060790f1994e43006f1469fd73858e592f31cde817457d68ff9af489e319fecbbf9221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbb2431e80606a506ab625bb598d27d494b3f144638374d416b43ef6af8de9548282bd0a0ad83d5dd707fcc156133eb00000000000000000000000000000000158235a7cf71509cf435cddf76d1a7541fd1c072f9183499f0cc200d971c46c9dc4c3bf4d6071436719e70db726f1b471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028d7287529c7fff128cab1bac5fea6e269ede300c70c651eae2cfdb9285092a4479421edf59d80577224c6958a43a0f0000000000000000000000000000000017cf2ef1ba9830ee8b0baee5defef6ba289d4863979cc956c102cc91f7f1c889c6ecd0b8cb69e997b983ce1d1e3fd4b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096190d31a3bf0aa4f5b0acca903945a8597e39c2e8e5f28e1a86cb9c638c88983ca185ffbfad0a1925af1e581e438cd000000000000000000000000000000001298b5bee0a84caf01386182a7ebc1ce9db8c2edf9271d9c899ee54d6e5c3cdd91d7fa93339d40a1dae99231794968791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f40667791e7e3593edcf82de9b29e0690ad31c6144aa3816f9a30dd058a61686d83979488878559457cbee07f6e330000000000000000000000000000000000e03fa2472b2c17c877c62bf209b4598104e70c8ff8db809d40a8d65167acc51ca18958ae5ba83cdc39bd4404d56a4b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956235f7c535a19d589c7726a8eaab9cfd1e8fc5b4f1f783dc67586c6d5ff688c1a3a57dd8133456549b26e62ca74ac0000000000000000000000000000000015f03253d3e4ca1fd914717bcc1951ca28e98a443e0dd162ba3ef7b6d592174227f143776eebdc58ad4e89caa0812b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e0bd18feb68d0dc33baa0836d9e0503029178b9a757426053523d60b14147985cd9f9d1d3001204150aed625ce63f70000000000000000000000000000000011248797b806a8788446b96dc28514b0f62e5e72e15b889731d1f4a17c2b8a794e64fe98c2a520fc2f7ac0bea03c9ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0278d4e2f05b3b78c3e75cafeda397102630024c97ce0911932b9146d520607f86ce244bad27af14255e0e4146388000000000000000000000000000000000ee07762fdd5797949eb778176fb986e3250a337d46e78394cbf944aa6104e8a7761b5d1b6c461fb1a8deeb73c4a04881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f776e23a46411ec0e8a8a8a15272e283568a389c1e385652b915754d385c38dad7435ae206b641d25d2228765cb1689000000000000000000000000000000000f6c05da2396a75aae5a121870ca31ab26807317888fcc92d8b3582a596bac19efdab82d03248144e7cb1ff22451ff8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000559a5cec51b8fddf3d9ab751a18d2302acbb2c8071a293416c36e7bc65db6e4dc2da898d48d0551676e068ec2c966dd0000000000000000000000000000000019917b3b69815984664f40f4442fe327c630a5809e68362d20a555c086a06001775e4550bfb9601be4f451e4490c8dd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744f7cc4c51c0660db599c584e63f26603d3ac18e789fb8d7e877d47a78d021db04620cfa51baf14e9ffbb1dd35258c000000000000000000000000000000000b0177b67edfc6814805cd51e4b0dbe65e493d5a2ae74f64346c2b5c2b20723497924d8676c927084678fc9fb5f512be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000598b2e5bd540fc6f7fd37140308e3c8e8a20a4ba872e1a12ca156ffec661f46f10378bb68b77f1b050dc08a35aeac55000000000000000000000000000000000e04d91672b1684c2581d249e3e9ed16335403103a9afd4e87c1acbd5919d630352e591e905b4b85deb3e999368e0cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d0e8f69685726e0394c17e79e6070e13d4ac1c84951965f93f6adaaa24d7750efddf5f9b5eccf2afba07b658e1a2fb00000000000000000000000000000000082213946c007b425169cdc7357188157807996c2050cf9c29f2f4e036fe5ecc06102deaf170a59cb13eac96238282941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193691ed496b5b20c3c3cff87edbe09fa34ae312462b0a516cd44568d89d9e4a75d8534e24eb39d489a3188f5caa9d4e00000000000000000000000000000000077b0e6645a6f16391df529ec4a06c26c752deb2445ce7b96bd379063285ff3a0adc7b4becd1c39cd2fdbb739f2074ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008984c29d334e3dcd9d8ba70037ed1d7320747977f564c530773cc76d234d915cd7e40bb5eff489c1f00b2ae49b20ccb000000000000000000000000000000000ce49b8d792706461deed4d79dab50442c5367447cb46ef71fac590beda2898051a05deed8c5225a40001656fb94f1911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c492fa47c395e8b4a39a994c6fe56c7a31e0ba8e10682cffb9d814f17f2a0cd176e048d67d69bb29f6726a9951d1b5000000000000000000000000000000001770a1d263499d3324b522c195d2556f4e9f1c9537f55793d986d9f797bb4a53de66a8939b8c155e13d51f12caa1512d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f6f24e6b2fa011e22e39c8be19e98985a34e4949af5682ab16058b509d9365678c0af4d72ba7adbfff44c84ef79f680000000000000000000000000000000009836ad460387009597a8f843eb9f392e0488a759801db6ad230fcac6d641f9a53779bb2ff9cf20b9743638af501f5881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177d2e51294e9f9ee2061410008c607f408f59b8e48136af8947049d27b30dac84113f72fb2e5f675d5515da960d69720000000000000000000000000000000006e11feb4c3b75f69583c40a5870bab583235888797cd9fbc76bc96d95f2f23f41f25cb68fa985578720f309e19015851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000012998698282eca2a640581744f287effa3e7d8c7a4938371d2d5b85a6b8c6b20963f1d6d8afe9fb413e8bf069522e0df0000000000000000000000000000000005f61450c346340f4534e4c777cde8dbcec7875376e0d7f95da8fc8e840c42d2d4828fbc1e7dbd657d9eefd3164c3a29", + "Name": "g1msm-26-jwasinger", + "Gas": 91728, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000014e55c63149315d5a956d037024beabec83b3b4f7ffefaff95653f9b46281197972bbed6ccd8d58821ae361f86e45df80000000000000000000000000000000001cb2ec6054b8eafa49f129d09a9e465c93517232878f250552ba561dd6fffc6c04fb4db2e478eda5b3db4029a827f3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aa1998a2a4e125b364d96b8ba33328cfa394e99dab85bf94c2acf6fe7c6b9f5731e7e38d5beff058b8b8b8bc7745170000000000000000000000000000000004a2199fc3ebddac9581f3e8a0254f79232b377930459a6dabb4026143776af603bc0078b471c80ac2f9f58402df5e6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c953410c9a9827dc3b388be812413141b8ca8a2fa3bf11570ed0d29de92f71dd36a003d5743365f8c7a82a2f37be2600000000000000000000000000000000114bdf4178449da4b68ba3febfa5f9b94d6c34b542adce263402af54d7656e18c4b20f60cecf9ba5fcc35c71c68eb7dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085185e582bd53f72627be579e19f1e94f07f7bd07989ad2ccb4cbaa9552b8bf9730924d0aa143fadb3f8050c03a882300000000000000000000000000000000015fe1c9a31c606898edca9bfb91be69e97d3058918a4332429faf1d3411d40705db123b42620af654d75430ebc89b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116295fccba781b9e5706293ba518fc7b404d3e1b7b3c33132ca92093590674f2c7e2c1dbae6247c16d18c1c29244cbf000000000000000000000000000000001812649f872b9fca969653d24a441f9f928f67b460db9150c18f9f2912e56a1fee4ec542b8f4999e9e0f5a13a5e06fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002da11bb0a7c2c4c3ad3e515708957352c8c59b0183ac23db8309a861e3eb4ac760591400d869bd5f86ea98832efe39c0000000000000000000000000000000013ec0ed116282892727388958054a4e61b5877fbb05b38999acb824ffa368988bab987d3d2a7a96de0c4654047b984c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6ab795330e0978856ae7f80ad8260b51de25d379071b80758f12d96e514852e6dc5510133f1e716cffeb0d3ef969250000000000000000000000000000000015b9f40759535222ba456c98cc2b52e44b81f63a235220a60fad66e23a19c3df9fdff8aa009c1d4ef6b7600eca65a7351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000277fb70bcfc2579bf87d49d16cfdbc47270629b43e24f052b48637b412e023ea2edaa28f27314038f5cc36bc4b524a90000000000000000000000000000000001a82d0f81e055210e5411c9e8fa38858d8f13787eaeb6cea4d721ef873ab9a65723d2d48bcdb8d3f4e800e4b97b25ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076fd54045e1caa89b6a097ede403e4638109770b6d414008655ab42603fc7d0ae2b61db284cce39af9dbbd0e5b310080000000000000000000000000000000000d5e7740dfcfda6717eb4174073306e2c67c31c12baca5a49c492f26f04ecbcdc03f4cdc3f62f5e62161c735c9fefd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015026ee438cc215e6c1729580030e347baa5f29871e7c60eaa15da9924cca26513565bbc15ab7caff3ecf03b0e586384000000000000000000000000000000000c4f82be20ea6c14998f1e82e84559688e6c69a154b0de775210e68dd94467179f9ea6e8f79a13565170ee75edae188e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e74435b7fd76f82aa66bab892f26464fd524ea6c93c91557a5e975b2c235510d3e62d11f0d91e60aee656a3296141000000000000000000000000000000000ea9d99e3046b1b88ac6a670eed9ce8e79106acbf4e159cfb0684bb9465c7a878a8309d3e4320848dfe0daf6677617291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078ae2283d795e04ca54fd087f128768e4b5eb602d0daf3810711db89136679e20653e21fcd96a8c275c9b65bf18f495000000000000000000000000000000000488dec1c26d2f825173c6af1b8eaed3b8c1e9e3d819caf93f5baf3f1c891dd9343575a0c039e3be63776bd9ab5829271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bc97ee113d2a93fe47d7e99212eb4ca5733b993686601ebe9145ddf8c489dfa89f97a52ac02cb9c093827e759c268800000000000000000000000000000000071ce743eed2f579223db24ed5acbe90bddca3c34482545a9c93e918f102a1834e28e959a04f502a910adbd971bc9ea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ffb10b221a22d846410172c82bff81c3912daaf1662e450b519667c0ed93a48b3e628b251e1a389dc2f73006d6faa00000000000000000000000000000000157778106e5fb1c2335801706f376ae85258839b944d660905722bf082e4554ebea7d06494cbcb3f8963e7172b69d3031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e8d67c3ea9f7bb788c64ff6226b25e3793b44dbe9ebe303e40aa7d66ab842063de1b3dbbc9cedb80b47a08d936f32000000000000000000000000000000000c69123f3e892e39a2afbb86c351447483a1eedd67c5489748b6eb09893fdffb4ded1e9baec8621e62a75b4bd04b3f7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000776d01a68cb383f2bd5b3f73eb7a93da71719980d71c7c9186fc7f5faef395b2d41914d4304a6e522091ea718d3ef3d0000000000000000000000000000000013f3cdc96e12edd8ee64ddc66d846f31637bce17bb057514d9b85d141691ac70e8b2a8e3d725a860d9b67b61734a22d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001280fe93f0a9f901e65b6ad9d345ee799a57f296fdc5b27e861639261528fd5fd737a4e30123d9d46183ed0f49e1881b00000000000000000000000000000000018380f83084be1fcf4bd2a40bed840eb8bbab67dd5508e287bc748652a7fbef1705fe709851ec99742ee07bf6cb6f8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058368b427fc6258d57dc25e1cd004ca96e6d1f05e5377a124c7dd5ef07c4750fb1c47a387bc0b4d785952e150269ae800000000000000000000000000000000185304474b1784ef2d0d38e2825849beda13622b2fec16af6a9aea24ed1344810c00762a44be4dc633ad6ae909caa7751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f05de898077e64f93e001080c93d8a753a487724abf52247ac1fe02167293ba0f775f3935c1a4a6868b5f46f69bfb590000000000000000000000000000000009a9d5285526a730f1f14ab85d00cb7c7e78e48b4cc9c247df7612ee238cd7b42ddcb9dd8031c323d9f0c49df0595e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013654d71309be0b5951d08f8be4b5acf3ce5ab3fd0dc635854f9c919cb7286a9e759d2a52835418b589ceddc6b96583a000000000000000000000000000000000b73df0edcea1f78edbc928b27b34c653aeae8cbc501b3b6001df0a23021b412d6d9f95fa6c56cc5660330e408d5ca7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ce08017ea4e317ad617c9c8c43ec5924e92370aa87db41cce342d351d7b2b67ba16e95793dc293e8ecca1c5a0495f900000000000000000000000000000000023efa50d15316145430a4a7bc87077b79d7a0d4488cf7d4c98bacd7df8565afc00f59f21f67b7cd4e3d4f3df620188d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154307f8674a8bdc2ecc157289270aa431a72f6e2ee1ac83311e4bc2a658350cded79aaca4ea3504a26967a9f296bc460000000000000000000000000000000006a67b4c943607c1dff1b2254ba19c003923314bb7a7e7914034df82daf6e625465411493c56d672e47b55dd6fa3671c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c0a67df6d93799dda1c55f1f1235f1f831b04d69532d6262941beb59e7ea7159d6718a1fd321a953f7bb61f7fd290300000000000000000000000000000000147990a10106a46d3fff1c84987942b4ad845584ecaf0b53512c03f3ef35252d09ecb86e9729c6cc96c9e06e485512141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e894a52fe2e5ada9c9f0355108ec21295bf5ef12e663a199b47d2ed2dc92f25e6a4eb88d0bddcfc7a71f8194e2585720000000000000000000000000000000000cf3a3810b2fad1ba1b9418c92ee99e4f1255674482d76283f07701396cba3a7b21878f687f6374ccf1aa98b4e9184d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba37f285113fafc68a8df3a66b7737e96cbf821559ae1c836ee756b378b77076d76ccb20b3a7c5b5d8720ba496de44b0000000000000000000000000000000004b78e8aec32fbfef577b8bffcd4fab3c3e67f9e054243dbfd5a41ec85c3164d065b482156529ef485120b39ae61a43c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9ec96cd3468c18a6aa7bdde2210c7a05b7199c2f25541349d3fb0a1310a0a61263dd5866c50dc4a77482b9473e4f17000000000000000000000000000000000989801b9af10f39fc6b93831048a936bdb7ba863623ea3058cd63a987d12c000ccc20a6ef661818979b9f31c17deac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018738ecda79624ceb3be685314edaf3b71dfb43227a33dfd4de2c25a7a59750f05222f360d62d4026698be90bd147919000000000000000000000000000000000188c1d2b8e2e67a368bf31b099549f1fd0ece36cf6d5b384bafec94d78fd1f76937ae0edce19b6180c6994f0ccbef9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000142d164fad514c6a9c1eacb3cf1fcdfb03a0c47d06d9353c445b0017338a4e698c1f05fa4050e21e1ca2c154f237cf670000000000000000000000000000000012896d9f1d7a82231f5f220b7cddd7ce926f4aca902d0e95730c74600eca2cf48a328994801a70affdc307029d3f97e5", + "Name": "g1msm-27-jwasinger", + "Gas": 93636, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000b671b6fa1ffef32bc8e4a6d9167eed86bd7de3a83047f8cbda24a60c3f0c89d4d494fa663f3d38292d0d01eb7bbaf450000000000000000000000000000000017cdf30da17cce561475a279d0e02ef333b2964dbc55ac66e7597224c1492b0980f4ef28edf87e2bf2917f62f68fda2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1aa624e925b519767a8bb9bad32fc53a69c7ea706d38a52160ffe422333adbdc6730ce72ed1c54a3a442b59d6ded5a000000000000000000000000000000000fa19e5e45e741056ba3e9f5e902b817c11000469d007bdc5639cee966fbd2b399600fe17bbfb38fb63b0c8a5a9693781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa1d92df06ff59d895fe7c3cdb9ea8efa05ed5f4f27251d25ebf5ac6117c1bdabec5670002f7b0c5ecc526b879d254800000000000000000000000000000000119c68fc18fdf89e2c64937ec8e450db95ef15f7301063b7f32b200d43ea44d654eb71433f80b9d6ca032c126f5aa0171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd4d1adfbab369c4c24d74dfb634283b6a90c2c7fae7143dad5176ad0a5bb722c3f1ff6fedb10555cacb23614ad43e800000000000000000000000000000000099ae14e33d2f94bfa1f647ee91d28548116e1e606fa75bc3133c3cf8c2a0e5f7b8231ff4b8246d169732e226df370cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650df56e0d3ec45fe1dddcb69b0a9552ef6a3ee4f1cbbf3a2ef6da8bf688a7612260008691f72f0583ce6d2138dea510000000000000000000000000000000018a88b162afd631195c1e50b09a76615b4970cb4635e3d0c79f1c83f8a2fe1cd59975d0641baaae7d908d5dc445f7b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001114eddedc8a3dfe331b348942a1dbf2f0b739067bb4665f21a0ba159815f742b0a9c3b81df27b2a033a914924c121e100000000000000000000000000000000118fd3e50660c5fd6660d28366e4d06372e4e59351fef1748f8ae1e1ae0215f026aed79f94f84b8130ec55fae14e9fc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ac987f6255baa1834ef0b7fe702b2929069ffdd70b222cf25427feaa38860aac072345ddc573bb06670478209e8f5000000000000000000000000000000000347a5d0cb6026304f3b6f87d7435fee667c18bc45c93fddf6dcd364bf6b9582a19e6735f60545a57cdb9f7c7def30931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ceb5f626d2360525a960130191a446b071d9d52c27c9756e359ad427c4a3b2369b7fe72de157f2b1a5857ab9a778d3000000000000000000000000000000000216c57834aa41f7e28afff828823e79687cf975634f1e8ebe173c88ed88d94855d8ad987d4701c05069db15003d163c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c6740f73ff431829d7642ada1c6afb4615d26992ee192021723fcb34a7772cd0149ad876b1b755717285f803da8163000000000000000000000000000000000cd1bebbb1cd783d88c6aaa668e7226a3cd83142e2e02032bf91e60c66c9a1ada4356c660fa2e9f9e7e33d481895979e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d032d6a1d26863f7db9ed24e13c3560d15702a8d94fb2c72aea81ad3f7a030c10fdb1940d1fc9b1340ce7c57e61c2e000000000000000000000000000000000145a0fb5f3d605daeff25979a6e14b5585ad3fe23e9f355ff06a15e5ac376d4c936090666c968ed5779fb8f60ea84c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c60c8e2be4bb31c10c464183b1acfdb935d63b4130a407df2e812797161092f1e2fb6f9a1b6430fb3c682ed609df14000000000000000000000000000000000ebf559e9aa921ad6b57cd1cd6a42a424fa8060f8c6a1329784f6e61f458c6dd8ebd89fc3fbb405c458877fa30fdb0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043cfaf034d9911fe9f93dae1bb114b067d03463e535e44d1ca3f19bbb5d68fc03b31f8bb860135387e368f093cea6d90000000000000000000000000000000006074494ce722cb508b4fc234a4e2e666bed50c2232284d52a111c6443060e386e5fdf2de637b7af47f5689c4d6cb5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae7299f95b9fac7a4591f6c72e2d4540671bee843dc603c2f22bddb40704207d3385df1e84e3b16257aa2d7f1385337000000000000000000000000000000000c9f9041058a91edbbc5954a4cd45e4a8428d2dac4f98d78dc569f7cdf34afe6040682e8836684cd54a16bf3c766466d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff5ba8b9486cc75c51856937895485117aabb33d5764a6dd7b0b5d20707f5c118294d937821094c6f0e90c829e93bd300000000000000000000000000000000165d7827869ce6c1c126a14630d2a19c086f04bae51d2308b9da21de83fd7a16e48c023eb379ca2fb95deea59a8ada921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010238de68aed30e74b5cd1d97bdbd38758aa7b5e35a3f9453a06c9f499ca403b03ab0b06548d090ad59a9af89855eca9000000000000000000000000000000000df9288cc4de7fff60bada1582bbc66023ac149cf4c540211ca568d6e495aded85340f18eed6f6767f219e5057ffd5921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cbdc98bccb1f34cebfb31560dd17622c3e61531d53fdc2b93902b7ccbfb6509b28edea43d92835e6ed233979cf5996000000000000000000000000000000000ae6dcfe1a032ca82fe93cc363aac9dff13f08d8336603fb7e908f9ecfae6748a51db4d34e3fb9ead827e8c0a9d7ffa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030651dc35e5ea6553b365e0746aaf7e6b5fdf8d2ddae4eaf0b6ad3d6a79f2ddc6e87e63ee10afcbb404eedaa41cbc720000000000000000000000000000000005a791c706130587a5340b53a5fb8031daed1d7ae980a13843d9bf7f6ac847c62539469e6e079a30cd661ddf43cc29141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8064e76148d1b44438a42afbf4d8f7c0b1edf9aaee022ab2291871641e67fe679645c86bac99b769b0d6a7884753b200000000000000000000000000000000160246a845870954ce70e3d17aba4cdb0b532f8c495d86a416f9c2e600fe5e8fca27c1fccd00343f663c87b2aab78b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f141e47cad23053f311da6cb7734bce848f9e89fa271f319376114b3a6b74c982bf3250edf2b22d1cd2f99d53d1ec300000000000000000000000000000000193a5ee66dc0b1598c0579c49c77c1c3ac99a1441e9891cd9594834866b08949e4ff8fce08825a793a6239a06a3c8ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b923ddb92a060b1dfcae175fdb915e401a91fa8a5cfefd4ad850c1cb505a025d82e342e12f01679baab3b2ff540da00000000000000000000000000000000001019ef43bec2f4c10d8e13cb6144492bbc4e90ce6ced3baba48fb0d127f69c32035ffc44ecd096cb9d2cdc51d6943cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3b6b90ef6b71e7dbb152f874f2626e1732cfe4f89d1ffd66f254a19145e5dacc822950930dc62f4cd1a6c2c0afc0c60000000000000000000000000000000018a6dbf2620aaebdf0fa34869ef0d3dc77ee2ca2a28b4ac3ac8ff7a5d69f451fdb6bb0af67095777c39794df5693bc0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97c90bfafee64bdfa42c46db15c222ee4efc2f2f4e3e4b3a156586df14cf088b442136a41df42b2c2a275626fa7b7f0000000000000000000000000000000013d11eefedd5859a95a8ab5e867253b55ca4e62bb24057fbcaa8f49ae1af9b46cd03a43f734a6b07eee531ad39c817281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019744d870276c2eb01b37c57fdc16d0ac3a887c7fb6607e8439d4d878aa20cc7767e4ef9ced4366bea6b10995231cf5b00000000000000000000000000000000175236f548eed1dbf17ddf14570f517a78502ca360c21c2e274baafe806f15de0126c5e4491ccaf1071e4f57dca1ecf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000113bc3f047153acac2eb9296c68eba801615f4bc68d1f4a031c43c827debc35fda79ed329e2c763e0c4f635fbcbe4250000000000000000000000000000000000119a6fa45488f6bd10771ae34b32a35239eaea4031d3728e97b308f1ba119634bdcf1f5a2763f44d179773f6d537be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e207d65893e94e607181eeed4fc6a5ba830af32e42749eea44e44660fe9136bfb6e27a2d27a75b4002fd96279c374000000000000000000000000000000001253c67e4afe1966c6bb4c0e2c841094d9eac8927650bdb00c8022221f6aeb1d8ef5a4cab294b7f282b7b5955fee95061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000981f51694e12c93146fa131586d647599f9d27f25e6aa32d49396e1aac39b567675254f0ae2444acd6c8645d777e09300000000000000000000000000000000071bca4f2a1cf2684eabef0135d99cc565b5617b46267f943a3f7b8824b7daf5a4ce060730a85a4e07a2436282de9b921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd0877be99bce859fb6af140297be415f8b0f38721f334372123becb4f236a53cf87ae39d6b3efa8e6446a6df7cbf9b00000000000000000000000000000000031cd6cc001854a3dc70afb8cd459a7d18861e1884c15637047eed07d3b2f06c17edd27ebca6e046340981aed8021e241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d19bd27df46dd6806593ce829fc39e158b2508d86dd3c2f29a78ddf091dac53c525e00be9fcf81b5718e63f98d0ac4000000000000000000000000000000001674ae0d75fcadbb00bfc456ca00cd7520be271ca112e8597eddcbe9a140c7c5a2f26eeafa9ac84a06a06056335dbed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000013037f535e801db713c6f08138babd1eb66cefdd9166398cc812af8a5141fe8948a9f7fde4f5c6fc1db3a21f7f51431400000000000000000000000000000000099abeb171ed76775e3316aee3fb60f1b2ceb285a4527eac7c05ab250ca461b7a694b4cb08ae119bca13b213331fae56", + "Name": "g1msm-28-jwasinger", + "Gas": 95760, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000009deaa7bddeda215550f788814fca12048d24493f66c1d261dbbdedb7d1bd4a1e2a7583b7ad301dfc4aec26bd192a46b0000000000000000000000000000000003be9888062363d820bdfb497cb4ddf78b1e9e4224121caae5642d094a8aa578002152f369c3327f286610f62dcf9f2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159fddf9515762e6d689cd76266ea3d5c6303770b9f0ecd71a0a6319e3e17d509eef8ca7f4e948fa2040eae62fb7e83e000000000000000000000000000000000b2319cfad5d7002c083a99ee1c3fdd7094740831338296d3f6847861664636c390f293f655b6b1463c3dbe664901cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e227e03891b9c5a0ec10b75c60b03dbf766287205a75d2d22f0b22a0a7dc7478d7530f61202cfda49186e36ec247de700000000000000000000000000000000194b9cc68bae6984c52f02e946f110b2d0316e1f298ebc96a53f8b7b2e3e06cf9e1ef518ee5bd46b64e689228e6725131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e8fb17b172b7db9854fa58ead9b58f62ad838bb903512131710cc4fc946f878186eb01bfa3021fc8e716a0d2adc8d20000000000000000000000000000000002a2ef05362b53461d16bd2176922514c7a50c076b6427414565a8b41bf1d83d5998df3c3d7cd7d8d1cd6054ab2e6eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170092351854368a668c0e11b768755359fec6c197bc48aaaea04f55c2c5413ff3be56582461d4fd1b3e07a5b776b667000000000000000000000000000000000f71931700a45db435c1f9566699981eb1840d569a72887539375f9f32bee8c4d00221d9cf52ce8a40a83d421bafc7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134d46c376536b5192c36eb24c742e473ebd7690c1153a3d0ef6c1af4b727c2bbd99e3b96fc9bbd9684e7b9037155722000000000000000000000000000000000e6d7f8f63f46f54f28016436b068e4db6145ff45d42c703449223d6a1f6e0ebf40e635631d0ad9f1e9e030fdc7759971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175ba1080101e04501bb4e79024ed203093691ea50a5c2553eae7a3f4a7164844af0b31a60840aa327bed5f98379bd120000000000000000000000000000000003eab303c85225e60655539b73e494b144787c03ea10bedbd919071ed4b32a308a9634393a0db1f6500d16dc25d482901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127fb8e7f0e171fbabbf13f2512cb8656481480aa5a379d5d84f756561714e3de305dbdac5417bd50c183325648a776700000000000000000000000000000000046be9ec841d1f62c3e0ee1d380caa42741197d280867e871ec37403cf962077dfd981091b5c67b97666af7bad119b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f69eab5b387de9a58d76043ef789fbc1a876480294b56f4d377b122ec12d09b3fbb3aeb929d6d3c071aecc9057ffa6f0000000000000000000000000000000000c2c8ba062a054d50516d55e6e9a92d2e92ef797571ddfb2d5769afec873455bb275bfe3ceb20b01fe29ee9cb3156321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ec8ccc94f09d3d64aee1bce7e9cc3b71455b8909ec20e4272e9c3b25df66214e6bc63d0e03df16dbea548783d3f2b000000000000000000000000000000000402a568af12318c840cfd4e0875d0f8989184c9f3beea7f6fe6e6e2c69a2a751b8d70b0f5e237e13c6cc4c208e772ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b38314c062a05375c5b6f945f8b99a81ed1fd4c8c9dded5f9de69e4dc6d49afa505547606c28deb0b49cdfd2eb83b400000000000000000000000000000000166402ae3cb07937c930db5a024f98017c8ec14a78a1c78636c54558a5cc9eab6b9a061f4da0fae92c067783c90629bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673e6cd9cb0fcfd75a8e950344a55a249d4621bb2fea663f5a26e3dda34e792d401b8337d6b0ba47c6dd2d5870d0f520000000000000000000000000000000019947bf5c3efdcc30e489118680fa4a149cee2ad3d2a3342777a5324b5a31dd14beca8b7e0df8f184afaed525a33f6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007301aa9fddc2daf6470cb3dfac1648048a554d91b51ab75797497de3be48200482ce313eede021d3dd0130fb4c3572800000000000000000000000000000000124aedda89f48a4e48110e179060e928dc14ecebe52e5a69ec129e9a531f3324370a38d7f6fd30d02551c6b675dd249f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2455a7896cae11b394cdc78404003fda8cf4d8b430475d64e3b13904ba2086b2702313046955dc5a943ae64b0ec0ab0000000000000000000000000000000012ca266c8bd0471ef9d5f14bc40a52785aac46f9316989100c7521444911ef5455b143e584eb5bcc6e3f11ed46ce81861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ddf235c26358701ba51e8a25e10b8d65f300194d964939887a57d5772c1fc7f49b7261396cd7449add2bdfdb86b660000000000000000000000000000000000bd1f2fbffb103a9e852622e0c08bad882a70cd468e96db6473b57805de72bd3cfc306985d34e5080ca999b4634a90831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011680139072a57ad5035181dede494d4a71f56a543368c63121989c248ebc8b11f5eb03d07485cc55de9f73f5eaabe66000000000000000000000000000000000d4e543d023bbf26c05a2f78ccd29d98e112e69052055e621964e757d93ca42b0ca54b2ca3ca20eab956d84250c2a4c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc35acdfc77f6d37a3dd8badcbc53deffcbb14bf5833722c17fb8e5cfeb2baaf8c59bbf5808e4660fb22978ed6c6dd50000000000000000000000000000000019bfc29a2c827ea2c4e0d34ac661129d93294b80866d9f20e844ee0e1178f26b39c1f0b35359f5b8d3bfd1f7943b145f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf21e612725ba6ba17ec8078796219bd3681f0612deb1185949ddb35a863b7fa7d162e7908f676f9e73d1539d70c68a0000000000000000000000000000000019595810cde3aab9cf6c61d2763794ce83bf315ed87c59e5d8d9adbefac85c100d9f57ce0682cbd8061c90cd58d558e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011032d0bb6344b43f554082567b2ccab9b296c75d0b4662b685b8aa724132fd95aa756f3d4705c3e381d3f6b0ad0de6800000000000000000000000000000000082e15316752ef17a981397684f0f21f83a7d8d5b00dbd47e4151558dc5ecbd159a3bc79d458a11ab0a435cfe0579f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009804eddb57b83075b6eeee8acf7763d775900ae00f32212834cc04ae72da1a019af1c7fa10dff5ab11d7b5a78d0c4930000000000000000000000000000000007245b4f65a1c10cc4a3f8c268858b47a63cb18d28b8b632e3ca8d86cef7adc9f353855cc25294bc4420c8a0d2ca531d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142e37cc5cd8e90ae2f38e6258a1696dcc9bf06310810322a38b912ed79f6ca6e33537f225a40c0284afa8fe3af8dce80000000000000000000000000000000017097a9002f88ca4f4813eab7e7c0a25eb56d9b9884810f509aeaa19945a5fe2319cd143ec05cb07524107c6f95717df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003bab6716625a5ace741ab06ade2a7250364e31e7f494c7b6115bbc6e8d997afe367085fdff6d26b290a456223f179b000000000000000000000000000000000b0dfa444f8c53c60dcdb6792a0eca02467a7a77bd399cfc9df7eeb019e04c16a483dc3a82eb372fc21cc1403a0466c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000625fe83733f861d953ee8e683abd3d89e39014239afd3b2d6f959ab67e24af137ab439dac224fe3a594d1a5af3bdff0000000000000000000000000000000001333ea86ae79fbdc5bd10830d772e5ec989d41efbfc76c02a7c14c0dc3f0fb76a018134aa2cb70a059b3a9975ee791a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d42dfb90abda27a0b9a01f4e7f14cc07c56c59c465e66408c89e55a47a4b5e9173da20882d83ecb73e018209e2d8d83000000000000000000000000000000000a6065ea4636ba4092c4b502c9d95402605054852717d061824cb371f0f318f72494891f11267c8406bd5ccf9fe104ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b161e5409f17c5d34a0e1fcfe849c08fa070b882099754f500fc8315b7e746fed39a42769019620f9b8e05def94cec90000000000000000000000000000000014e1cbe28dc8c05f56e2d914a3ecfae5407ed701197d7bb0931dbf7554110c44354e2427f26338336825259e6cf231c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159256259e24c01fe2f2eb5e5af97c3709dec85e0570d754480f02f7a798f4a21b7eb5f466e447b9f17599e94d15d01e00000000000000000000000000000000121743fd20324d93803cbcd0c984fde68c8cc44dddaccc95853bd0f1e2e4b99c9aa99e40f56bade8b1e8f5032c16dd141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000677ceefab74f7ad376a80aa3697049241c048995c0db22bd4edfb7086d7101efbc3d2a456aa888d5b77c1f1158a016f000000000000000000000000000000000cd78e0050e18b24ca36e1d96f3d074e97a63e63e8199785922cca29f5aa03ec0bc91775e3f4fae78675659c563780131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3a712ecc9ce5e7de1501186ff3d6849656bc254941482f3764fa0d05543a9d297211e23a8d6eec49ef22d01e9dece00000000000000000000000000000000051d20af46f3e036b1d1ac2285adc55b2f179a88c86af304c11989d1d372aef3f1dc73693adece66cc8b1e4c5fd0631d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f4fc7c1050039151ccc59d8e59bf2cb95198200783551bdb21ce91ed00e9db4d5059b4e690dd731048ae53cd54cb700000000000000000000000000000000152a0f7bf648856e76b616559bbd89979fb07e96be084bc395712411b07dfcee27f4576d976ddd4ad645f72548d67e2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000004b5883f1d8f8a4283c7ca03f9b45c7bea0796daf50a62073464c91a10ee4524b842daf754ecb490b0f44641cb57a96a000000000000000000000000000000001199c4d8092a2213f2759f43fb4b755be20494226192421fa1bfab7ecc6c4b8034c84b1a4df2cc2afa563741431b2e9d", + "Name": "g1msm-29-jwasinger", + "Gas": 97788, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000002b9e44e06816cfae20682bc898a1ab484b9b72c9d8178225e7e80a6292718de7324f7feaa05c31120274816feba50ef00000000000000000000000000000000152991e2f52f22d52309b16daa0a056bd77f4419ebb642ae071436b85a53baf89253f2e1a6e9cac132cd42f4cd26c4821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001770f05c6d7767a23e43fbecbb6bf2edc987e2a5b1a4a999185bc55b4292e6e29d4e81f31c218a154f77f033492ce77d0000000000000000000000000000000007a8181cdcb96730435243c4c1221f370f90240dcb1ec9a23f5b944a4132e31289540f989b302a54133f594677f1a90b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a18dc7d24e3de2f4e03557dbfd3112fb4e01510bf0f54a89fc2200ffc0a24d290612e2d9554bdb511f927dd118370400000000000000000000000000000000167556a4f645223c8164671c9a0e2d888d130059bf92a62f470ee5780f365dc5dedb5bb0504d7757467378cd35acbcd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af1ae53c18cff2289065889160c2727e4ba095e1d23b78c1fdd5006d63870afe8ec24e68b5ec7f636d0258a8c013f4800000000000000000000000000000000129110a7b8492de97304f5113e49dc8a26615b25c3284a2c5e6e99d96d6be2806996c0279ac195befd13a4ebe3919c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153b7381c3cab7a5e0e9231544a0f5a2f8ba20b24bfea94ce2b7c6eb4bfeb9cb93320b3aeb7c02c630122e68f436914100000000000000000000000000000000033cc06f57841cb9c915c1b3f493fae8414abd6dd950364d45413996cb261054f28ab34ffa1a36d6eb3b9f3a3992c8191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014748ca48f11509fb638b1d6719cc8f6e5d7568dc4b92e0e0ef5995327bfcc133ee6ea41b7b20bf2b16fdc3bdd3f7fe80000000000000000000000000000000018c9a0fae8ecd9a38d574369b5a00878b42eac3be05afc05775c619d6e86a1a2ee31aa0fe4a08bc6055575681b3c19231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001996bcaa707a0b142491a98eee2dd35d26347ca9c9270fe720c941c02cda6475b072ea3d2b904e7fa1a37dc77cac9e40000000000000000000000000000000009ab9c0b544bee583f597ad2f8134a59d09b4bc45196f33722603fde0f9dc3764aa70608a2590c28163aadd376a990621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1a51eafb917118a8644cd118ed5c63f9d80ba8707fcbb43797cf708cee814f2c40992c7372d00967605e6ec98b57cb000000000000000000000000000000000b7372c79a7a9e35d44d6b90a342656589da8a6942cfca4a059c5961fe0c3440c81cc0407b8c0456651b9b33bb7fa01f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c69c240a6f0b612e3d8adb261683a1a867a1a71c3c898c1e3b7b05ac3baa6a4f8f170c3b672d109dc1dd4628de0e1f0000000000000000000000000000000016800464d803983163817a5c3a9d7e4b9f3e7077119fd2f57a2910a720ceb113557e99958c43a26cd975cc54d5c33e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ed65f5328a5973f6fe40ff54526f3b8f99c4c8c5dcdb1b288679523c5c461eb7c3d274188c9c21547af560b9e6256a0000000000000000000000000000000001d800cf9fca6d5e479f3076c2348d307ec5b0312a23f3ff29eb81c7ffa455e1d056f0a0c2e935384cdebd2765919a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080f917c73fddacc110ebc2a81e46d8991858cbac30a698795ccaca6e808ca7077cdf553e26003e55ae9fe3aeb5c1daf00000000000000000000000000000000046ee199d683b9fbf229cc3212559234268072ed91f0f3e250819642b045ff9d8a177cfcbd619f4e597676c80f47c6f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000240da36871d9e4cd927b3efa64ed43d94fde664c4335e14348c856426a9e0b85f43e5ab1cd609cd625640c6985b16ce000000000000000000000000000000000a4d962530e4ed39f36c20b4dac245122920fd657df7ebde8028e56583a7c8e17f93fc5a2e0ef4a16c97c11d4374780e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132d8d80c77b84d832f55e893151c3241b5b68fc9655fb18dd38234962f085e13e6e5b1a7c7c58655a2295dc4dc8796c0000000000000000000000000000000013f45fe46511c095b215d2d3caae2a8b7223f99f8b8c3f5cd9994e7f3cca6d803ac2a06c268629f9c5af18931764951d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc909ec3514cfb8bd03f18135f91362894f90706eb6ca67ab8f1c9720667f6d51aec157c5ba8456922c995a88ca86e2000000000000000000000000000000000b8425cdec7b0457f6c972a0d83ad623224358ffeff8e9bbef0b1e512cad6f5233bf980752c5af8e04d98cf502b62add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d0eb9d010a8af979cc3b71988ff0d70868dc9ce4f41dd75fcdf22acb9ddc98266b62f56b456211b3b51e16e2aceed0000000000000000000000000000000018e0013024776e7613395787d4477aea7c3e620155a3e72635b62bb372b94e3a2af6371787b014a1ac18e643992aaaea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000432c30f711ec5bbfbb84fb08507cded0979c8ae7b5804d7c32686460772c9bb87dd65bc2b5376bfeb1dcf678531870b0000000000000000000000000000000019e84f906e902bab0816843e4fdc6e4a10d656883b740def861338b0b11d4e623b04f1dbfab240f63e02e63e9d838e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013336ce45daa4bd0debfacda1d9cad393aa07f8b95b75c0beb4d2ab88de66611a588a263706bf0e13c26a8c006dcd0b30000000000000000000000000000000003fc7a4636164719c67166671705649bce7ffd567401a6a739e538eca6a1b36a72fb6039a1a0e1089aa37c74615932061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067478a083a4d8e7d86c09d6317d7d93e21d09c29cd76faef172f36136ada680999349d7457728c9564a8b4f3c2e072d0000000000000000000000000000000013701e2ae6275745e1e548e663bd41bf377b2d9b7ec4c3d5c438d5d8228150b0cb92be4d438d8a74d11c8d7f1bc6ae9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c44e8a073951ac9e5bd70dc54aba2094f32273a793916f0753065171c736ef7db0616d013a3611fb57b9250510f5e4d0000000000000000000000000000000011c67c469c906aad6e3a3e5db0ddb0b4dc714ef7a1c13f2906d8c25bc3324370a42d258ea0084b6b4b596a7f22f149811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d856f7d5e2dd998de8478e2e45b3a5396ed0f706daf47625b22384126d2efcad686804cbeeb93b5661622807d4de320000000000000000000000000000000007a8a1cf20242e1eaa9584ba2a4e8ad4112bbb65b56fabad550c1188ad3b7c28ab6c75cc294691ea1057e8ff1b52f0b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e2c633c5f2ffc73ddab8662f8cdf40daf36a1094c609ae4e8606072eeba5da127560f667df714c844ca17f7f497a2400000000000000000000000000000000120a8f621a65e77945bde8825d2c505bbec453bd992784719a585c0d1273a4dcfb405005eaa90102ca3ee983401ea1551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e45fe2e0b8197ceddeb0b945c0a06eb91e19d75dd9056788b67f74e5ecde895153d46ec8556d5d627a1b8ed4b5c70500000000000000000000000000000000062a544d3ce2bcae0c3fefdc5ab4c05dd289db39f9e6cbca8c805dff41d3afd7eb09dcd292379e90bf23e50070d5534e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176631964f888b65bc3a67da9419badf7bc72ef19f9969a9d405e30c693a81c8bd44345a0cb285666e0e21587a1399de000000000000000000000000000000000707083f74979185ca45e342dee46179acc80d638e0e89c729d30a7dbb0d538466b9946f77cc5d8cb5d8cd13c03a33921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015626f56848b08c84d556e3cd507e8a3aed507f87466f0102df73c878e2ef3453f84b2dfd83a33aeaa4869cddf5a66d90000000000000000000000000000000017157627ca5f1715b8237bf846965539a2510e1b06a44223034c01d19e0183148a38d07f905faab699e39774c63f4df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f0130fecdce0cbcafa3283c5c8b311df2f40512e03d99b2ecade8afa6db400046749d49ad53e044505bd017f40bbd4000000000000000000000000000000000d4a84466e6f880f9dcc59284c61b25540e9f99440c706ac419de9d09b7a0c33a4916746226f34a7775efefcddac14461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881238bdf4f995971c92cb67508ac8a1864a19d347b24ed330f5c19658b4578e35c23e8d5e2877ce2f66fecd70f651100000000000000000000000000000000093d8bce3f8d507c28808e44d09ae83998e2939b488eac4bf20e3fbe36ef1d1577fdbbbe35bb05a7e79b17cef7f238a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8350e06676f343731f9338f3bba71e1230fcd1527c3bee6af55095898b39d99451c94b1343b26423fd4b761469d6e300000000000000000000000000000000042b7665834d7a442a757383898e3ae5ad10cc080aa0e81f4d142d180d9e0d0fed17d3f3b4c52be96b246845c5724dea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040905a0be06f0524c002788ecef03a459f2af0037e186fc2f43c04ad3a46cb17f43cff1a682585e508a4249bee54d5b000000000000000000000000000000000a4a14ba57219c4b04da5761da72324645208c958f463a2940da330cf66d23e95e55eb86d466937f897e920f88884c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088f46102e5082fe9513fd6cc424e25b72fb122c9c27471dc048f3e808d2bdbb775c87784582b6864278368d132ad6690000000000000000000000000000000011a34f3a405cc2aeeb6f8fd5bd39f10922a9c01990329d061bd1d54fafa41555b12e05a3e3f440c83497f24088e75f581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185d0db9e2f0cd4450234c1ede55690a38b66932bc020ea7d7e7780453d94d44c08ff53c8337c1a2a267a325b1196daa0000000000000000000000000000000014430d4ce207e06f1430a8529d888c1a1c317ae6d1fb2d86a45f9d91b06e3899b804b52f838f28abc29a26c665bbb9a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000873e0479b6dfc5ef1712a949670b0d30ecd792018283f9874768cafd3f47e9639ae9eea1ad00955dfaec81f19736aac000000000000000000000000000000001946af1f035da684c8896f8241b3563110975108a6f6300bb1a6fbbc182a3bbe72e2db123b137b4b02bda5a71fb33fc0", + "Name": "g1msm-30-jwasinger", + "Gas": 99720, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000e3c63ba695a3808541c9cd3b8bc01d53a39dc8fadf315497b5094f0a06ff0a7879e1c5f70206d91cac86def9d1647e1000000000000000000000000000000000166e40a7d6c364df834d6a91cc5d27252711f3132f7a369a64689c6b8cf7b0007a041c09bc0f03fd027556fb1ec16371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069ad3b249590107c37ecd8255156c35eaf3306f4cc6d3fb4d12c83d094b7cf63c9c3429c9725996474da7201fe90c1f0000000000000000000000000000000002b4414d4043936fd70f147583836f33cc50021c4fa16721e31ac645fb448b63a4507a6c1c0f82094757803d900ccae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150d059fa0f679366b8c41735776ff08f12431e8dec6de1191c75fda59f6e370f41ef5023a47ffc2710e457fc5430d27000000000000000000000000000000000c49cf896e58ce98d4c55eb75a8c7f5177dfa13e6b2a1f959f338c651743265e7304a588a0639de511c7e5fb10c50fa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca343b85aa2b9a01c60ca4d2587bd3e6109d37123a29cb5b4f7465861f6848d9dd537924969f266a2a640ef0ed2023b0000000000000000000000000000000011f27be05c30a569a87f5aa0762a295fa3e3a061703e54a00b33e7f7c6748f5f913ddb81972ff19c070c6fdf37d927b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006319aa506af95457705cf24da1359a39e6ea13d4e79259b92335bcf3e32296c607d2510c79e081f1b9154cb7a12d6320000000000000000000000000000000002ca4018088e8ad085bf4627725d6165994b65a0e101288689c435ca4fbabc2201537e52e6bb01fe59130a8fad97d8751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bae476ae5a4a4163aafe14884f6558663cfcc8fffb8f660f9385cb6bbacad2476c314ede2c589ab3b185799bcdeafc0000000000000000000000000000000002f2fb93be1463a992996b7f99b0082269a23bae4d48788d2b9b538090253978c46158a7416d56d4dea6678c56168b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c1359809b04eb90e53ff4442cab6f2337d3012008f64498caf44fde802c4a367d9193c878aa93975cc65d3d6ee9dc6000000000000000000000000000000000da070d301687721124cceb59c6e5c0a1bb3cbf114d72ba810a7e122d4fcff1619537a1392b1ecf8d8c5858e0a2806611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f3ad6f481b16825fb081a8c7e15087a8dce28f98b1535de8a39c0a58f1053ca8c31036cfa020b09d4b40c989023c3400000000000000000000000000000000157d3727b52fd6601bc47ed9a4a9d6b41b15475403f2b8ed83e8fca247cbb2f2606e2a91efea8aec72f4f191b8767ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a743a1c0d1532b9b572a44899ed615123d8b9bc17bc923ec52c345a08e9d255844e1cef633e6781cf2850fa93679290000000000000000000000000000000010a1a5f7aad10e9f0a7d0d63fcc3de086a1b3acf61d86c63c930b827b2c9a22936c3fbee946eeb3fc80f10a777958b801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c20bc4089adf1f6561b71eff4911f77613b45d5a11ef3bdf4973348ab9a868a141bc0af1f1cf87ebaccc8dea41d2fd0000000000000000000000000000000008e5e1c309cb32f07e380121aa7523a2677cccd4e6b47fb1e7a440763a5f92c82e65680dc301ddc295d428ddfb887f001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a5d2bfa3bfe7657dea14591234b466d47c07f8775325fc6776cb91f93ea47ecb69026f6d7d70628de0dfa92e060870000000000000000000000000000000012562cbdb7e2a9864b3a322c718fa4c3a59e6c4c7c0fefc32ef0573ab414120e7999f237a0599eb3292fe14f64530b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001479bd549140ea5771a797b50ea9365df7602678ff6ab0cb64144dfd53bae934429fb91c91cee71dca5594761d5c8ba40000000000000000000000000000000001d7f0852112f3f785dcd885f9342a05be6a5548f5ad4b55c705fb448a0ab5070499569372dd247a8e91daf4267136c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c27b584b10530369ec515f7d32c483e7d8bd11c5e60ee20b260edd73d3c67f44322b13c7375fdeadebff8f5a1d5d7300000000000000000000000000000000059b98e9f3dbf54fb476169d1188b260465cb1eff4397c101400924c62314b968fe20525deadb8dedf8ca450445fbc7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7115dc54b90020f826a60dce917acc9ccb4f02920ef9471216fe829f2a464672cc73a3e978f104d04660051c9d123000000000000000000000000000000000197574aceed901f5c790a5fd14e6c0da12494c68fb4acdd0d68c1d3fa0b0cc006081167069849455b3c24790213ca1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086fa8a7ffdd7e54bb287011b00e88faa72a7537cf6197d8bd5e2abb6fce29f696875d2bc0dc4f81173e08a90e4057410000000000000000000000000000000002c803dc574c1a992f5e74e96900f4067f95ab881070ec92de54b177f3f190774fe2b7ad2f642d26d2811cb1dd3bc2471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5cf3b11c32f1099b636e28029e6ab7daf7388460ae327537937c164b505f084931a909b80c6f86d6c933a302cdb4f0000000000000000000000000000000014e68a0d87d9af6cea2346231b1afe2f42c1d724b547d4a2c61c2a4fa12fe03ed1cd425659b37a5e718a14b4ecb6cf531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e812e9174195ed6584edb3e3d58d9fa13e0f762336ebef4669067bce8406d100ba8d750ea5419246a718889102726c0000000000000000000000000000000012d6f62aa832318b7d2bda6e43c4ea0820aaa2e8574595fae4029e88c6ac8727b464dea92bf0b7e6f84bac2ec05a6e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b3e1a579f8970d651341ead810048220a2fb8ea9087cd8ba157002fd01395f22cfb387239de0a6f902f5f410c366ea0000000000000000000000000000000009e7f44a45018c185dbd141c07d829bc6a71dd27e6d33968836aadd1f9fc74396ef922e0833af40485a9b1761089ea7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006569f437dc9b104e587fea00aadcd221c6ce3507dc0ff8a347750306d3e07446b3165b5efdfbd003627df472ce2d3b9000000000000000000000000000000001214fe8fccc3d4ee001230d73fbb27eb333ebc950d6e85ab3175a7e740db710b6dffba3428db52064b4c1e873237b6b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d32223a25964d9ed648e87fad93aec761acb5a3c455ba817b6b4a6b11318543328dd02eb7d680bec8497b9aca7dac3c000000000000000000000000000000001972162a30c9ee4364c409cd843d0f41a82fe7b7484054cb07cdd66cac9216965dd71736b4a5c0e6367fa1ea038fbc501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad4b64141166dcc80987c6b04a32e8bf85f977d53545bf7d6e88caa07b1434799c43f1ebf8d800a6e8ea095ab5807f40000000000000000000000000000000004684fea6eaee9fd39c5c78d46c747e4bf06a9a0d5b66c59a342589a7006a737faadade56744ea332e95feb48fa28b3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195451cedec15c8ec64ab8000d72be6ca7a80192b013b3835ca585025c669b36c0138af4fcdbe280c60b8d59bad8018e000000000000000000000000000000000bdaa74fa5ca31cdee2d39c78147d172f54c421eb2ca4b8c478b3d837e760ba51bcffe324cc32bd4a91e5f9ba6dafaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f2c8eaebe78d583a7b5dd30a6d0ba72e64e57a1dbef4981591902062dd25ea7ecc6b47061bff7b43d14093ed8a9ee0000000000000000000000000000000012684227cdd0689746091ab27c9f93b891f6718525bcef91c7622a6186ab95063b6855c8224946bae4a01ab626f01e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131ed2e8fc9446ef99af754522a4af9fedeaf1f8f4bfcfad5122a0e9152ace72ff79b73600aa997550522adb1cc692f000000000000000000000000000000000059c953e88ef4d699c5aa75c33bcb4535946b2abd081ef40b1179337a860027691114d710acbdc873ca45398554819b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ca086a8eeee058ae8e5b79c54be4b2711ac2a0907a5108c517c1300269686064de1ab4dab9ff7408a990f7580f480000000000000000000000000000000000123fbf931054c4b2db1131c89747f305fae6a9de89ce73a98693a6b25ae1ae81dd30a2ae7d1cf912c5d0a1cadc235ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001407a763736f688006efda863e7b3b18d566cbf7b4c3f67668f6c3f87f1cad250f55730ed04a5432b1f3f36429e0e6aa00000000000000000000000000000000075b3400bfbc3b7091588355f77673b73ff211a91cda2c6983e478378998312697d9041582218c21abb6d741a5906c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005353db0f1023f6a8d7f02a6a13aafcf425176708f3a6b6e18b7428fb1f523a7cb9be23d6b125c4e133e465a7ce9d8f4000000000000000000000000000000000e766e39ac9a4bf922bb52a906a062eccb6310c1e50bae2ae30a8c68cada7a317a8202f7fce5351c62ccb0dbac917abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000124172ed2665f37c89546b903bd525ab25e24f2cdfa3e452ea4be09e5b5d628e7badf34ff4d3454895456e7a3c97c340000000000000000000000000000000018bfc1642e114aac694d20d8d903cb671f803137e14edcc3262931aefb8230176f0232c6444326e552a239d3f07bfc3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082732670056e205dee5040fd99adf4cd93fcf46bc72f0479a3efe73e426167dac3c005940270daf30fa97ad823291e60000000000000000000000000000000016134ed2822a37eb7f14c4e4597efba0b4ab33289ae7898f33627a0a7ac2078e586ce521e02fa039f2e37340dd35b6121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122795b419e10d2cfe52740d69b91c3d1ace2b31cb8a7c67c10bae6a2b02b0412847f653447c53cbf999951abb4422470000000000000000000000000000000005a253270cca0aae4a36c5f3dd8bf60c7f31d336bb9ea7e3cfd42681dc1b71134ea7e6905dac1b0169a7ebe7724253331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001086c589cc0419f2620ce157edc4b011a36c6ef414107032200001a8ca3dbd8954a918ab7fc4dcfdcc52475a0d524c650000000000000000000000000000000015dbc50113ec7cdb433ae00e66bb0631358a9d130c5572bde42a1dc9c5319e6d50914afb6617ecc4b150fd3baba929bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000014bac2a905d41965f5f5a9f82a9002a5b1929980dba64c1e0f8d742481a9448047aaf41daf73eee27ec6127c39b02e09000000000000000000000000000000000e7d2e5665c66f9eeb28b6913aa96813226069589bf3ff50e409eaeef44368908252aabdbb99445734ca0efb417baf58", + "Name": "g1msm-31-jwasinger", + "Gas": 101556, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000019d287c613f97e5264863db37c848e9fea9cbb6546399050b71fc5146419cbf301c94a7537403859cd890bafe01d704a00000000000000000000000000000000069075c0942a4739f6dc9697dca124896d76d9c68b038f20111aa5065e2162303b4b0421eac2f1fc6fe7317fe5a3c2b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aff1c3ddb51b90cff734da0024572efbcbea41269ee918afee86571cb852ba14906c09e4afba2fcb6d1ad5d1527f24000000000000000000000000000000000f2b30cc72dd75ffb17bcf549e8013c277332a65ef1d942317fbb6605e6334ea672e1fc9bfa36ccfafa11ab893d62e791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea336d6bdb60395561ef4336e9937871b8b276d7a12b776e012bc1a3d7d6f3a45320fc0d9ccd8b4b6e3eacd7b1d1b30000000000000000000000000000000007ee33e7f55a1a6a33993f3c661927888220100a0f2651f6256e2625b7e07ee835aa37ea0cd3d06e1b75262b341e29471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000461eae22ddc0592a171370dd15161c63f6ef39d4dc99ebf1af0219a182be0a1cb8ac7f5178a88b36fa192414bed124a0000000000000000000000000000000014176294456404298220604a91aa85093f912ed80d7eac4a4ad176eaea8360b96305cdd003a31523098c848fd0fd0a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1357572dde202679729f062cbe8ddcd5f880515e57f6935dc2574f8db894d1ad0237f1324158047fe1806e84ae79f90000000000000000000000000000000009c72e9fb8d39a2640764aad16190b45ba5c5b72a2d0b1101fb2d389a36f2a3b60f5363dd0fcd228189b507bcc68f8061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041690a78c5acc19caae338ad039529f335b4c38b2dd3c7132d7e49a15a70147e7d290f78bf1d09d9dffc88f19ea2ce6000000000000000000000000000000000632a4ad6a19eeaa934573ef62af519aadb924faa1085ed4f82bc646a320c35afca6c63cd7233f48abee0ee435a158341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003210ba8743da34c3714d8e4dedcdbbb87e7574cea45f23310ef23c4200a93a8905c6ba0c9fa6fca5daf459d50434c7f000000000000000000000000000000000eee68e70c58ccc3d95116ef4b19c3b2d62c32a2e13ab9cfd75adf921b58d0ede75ebc9e9a66a2bc49da86f06c04d2861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beb009c1f2d8442ab9bd865d3180d1d6475ae381deb935f6c963949cf88c1de55b8913765715a4c69a597c7bdf89b49000000000000000000000000000000000333cfda212d316a00c5649f23696f4cdc2ee2558c38992b325155ad60e875cddae143e42bbd2a7dd52b81df8df7db6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a0f0d4e6cd49c5760d94a2cad72e03120320eeed79fc382da9a045a42cceeb9fdca806f702c77e4ece36df808f993b00000000000000000000000000000000003183a92d370f62f9eb69b64394d0da94f09c2d4e6e9dfd9d9144eed5973325390aba00b8c6af1c283c408d62e81c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001534f8f7772d7e6d5abd66005799dbc77abde9de1439fcd8986321ac07caa77937028bdf22f7527f92c39ea1ef38cceb000000000000000000000000000000000b824eb53ef0cbf44daa2d375f98a8b6d867ca2c88e39ebddfb0c0ee0af6b3fc3239a9680156c25e0dbf93abce236f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d0f24f27440c8c574239a37d3a0877424b0d665550ae6cf13d0a1204e64456d6cc1c9aaa5aa02f7cc2ad22022c7dc000000000000000000000000000000000091d6a0d57a6f13e8abe18e009b9191f4c3d5866e20990797809c565b806872f5036a1fa9b7d46e3bd53608970390d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037b2034e4d2cd69c4258fd14ef0859d5747489ca9f153b19fd5a7a97bc7313a49ffc7f26cdfa76490323f49767528250000000000000000000000000000000019537ac731b69d4baeb5a0c8e8a7a3a37cc8b5453dcb4d60cda957f674c17afca037b58bea3a836125926b2dff2ae2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034aa7202b2cb8d81f9ccee4e686fcf31cbaa270dafcd33e5502505a5c561776df863894427f5350c33f358d92e22a130000000000000000000000000000000007bc7421e75228cf41dc5363b4a4fec9bbb5545bb49d6d2b14765eeb411d08996d563878942b98e101049272904c91dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031ff6d2b08541011291ff01bb6f86cdf477cbff3ee55305701f90a24253bcf1ee047e841fb8531487a1c86837c541b30000000000000000000000000000000008aba53c27c7f47a5b19e6dc7f4b34de13550d6e18afd6bd83e6022f808eb8222f8fd5d89449db589f6218c4bff523c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1e64dae2f76e206f6eadef54f3f03e77bc591bc176f461d317e2cedd52f5427b7e664c46013e15fa85174665df03cd0000000000000000000000000000000015e798c6e08b4f2cc00046df6482f6a03135445445972073881593bd5c006906ebb12180ecfb19c94c8c221e3d08e1fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001483d19d713aefc4c8992f3aa1c9b2110031df7b8e3cc0f6c201da6dfa92ba5e814aeb19493decd5667ce46f49cbe3870000000000000000000000000000000016c0edfc485d18c50c176a182ccdfb36dccbf81186b68a7f3b952adb637b205c7e8cf52b65f65f0d24aa4e5846a483691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb7000ca247ae09eaf9bc1b3a0516b64beb46eec7481a9e866bbcc645e51d23dcdf41e3da2d990fbb653c18ad2cb9a80000000000000000000000000000000012f912ea4bca1770e31092451d0c8cebbe39f50f989b8f14274404ae75541505f0eb99a6432f97cd0721c38db4f28ade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004414237707f77a26d31def216ff034450f1b9c149d4dc0ca34389e2ce3144ade9dbb9d23e36c47cbafcd230cfd83f75000000000000000000000000000000000950c4454ba2a112267029c3bddab5b107c7bc034ff5bd1db370464a87b112cc6a580e90b99f8aad74fdbf93b269a7a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073432231f2ca609592f749bfe84985d1ec529f659216fe4741ee6c4937a450ecabf4506be0c11ed16c50c3ae76dbf25000000000000000000000000000000000ac351c2c570aa559bc2f4c53878bb03d9799a5e12f86a17ca1591e66ad8009999b2f88b84bd5ed117834bb534e413401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d090a1f3b7a073c79181f0157cda0fc6f33c65835ac4a3eda8021e794268e337d2e18ed190d877054dd646c1982479000000000000000000000000000000000672bd74371fd932517ba7d754eee24080029feb5abd4b80e5973925dc951268f54d5219edf6f1177c8a3f85d8f39fbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049f166d2ac77bb131818c57d2d01f2a54d06ba21ab2ae6a0c192a5555b3d3c7c5a94732185e336692c86db664ea999d000000000000000000000000000000000dde7f8fb1a09546779cb93a9117528e2ae2219c2d5827b9cca028061fc2ee0a339f72598bc9be7570d1dfca0883c4c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fabdfde35af770c5db7987dda9bfb039fb3b185184588a73ccca1913385fb8adde20aebfb77a2cf4e7241eb8cf5bbb00000000000000000000000000000000184c013fc18dff866d9a96c37e2d09b9922ae57bdfcb689dae1b21b5c11054393d968467a83acc54d230bf8579f738aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc07731aec255a2c7eb59b3c30e31742d7c147673a682d2b7723c78f1b03d735c99122251cb581a10543656fed6910c0000000000000000000000000000000008eaf937126d3e6f96f0927a397347ba551e44e08d2db820bed4911468165ff339c3c7c6fa1be1448ba0332ff65f814a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158049c2547ca8359ede78e9be5c45022de55401e6e4e26716a59ba7f2943bfc9a552c802382c1a16ca2afbf86e3c19c0000000000000000000000000000000002eb661c7bb49e761eae7298f7aa1205257f2834c58063e2344540e0b4801b41234bf4ad8bf74dcb0c638d18f8e4057e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050e0306f649c0f7555a59efcbb6ba944700437f17990fd49405bbe3fe3d13dba545b53391d3e1b985795015cadeadb0000000000000000000000000000000001938e1943cd4a8dd3c9dddf6019e175fa3c4b7aaa511166c0c91eab5af04db8ebcf790b9b8cb367f0384a0463442f6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180075f1a8946376a12e67449b926e3f18a92e473da9947b662be925d71ac6ceedc2b676e04d5eff5d8cb751e5d66ef8000000000000000000000000000000000b2a639a58a562df4ea1ec5eba0ae37b09f8635daf7c04142c36e369db66bcda7263d98d74366a579ff51a567d2652901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e473287982698c7fa5ed63fa65bf3b7ee5809f766a25ff685e130213f45e524b0bddf09d9f3d6a9017aef91f4f071000000000000000000000000000000000e29738d8732958e4bc751a80993149672b0f219558d6b8306efe1609fa20e1f42042e60f0ba7315d2784b6b21e9713f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e06651dffd04bb3d56dbe3b65542b621adc97530820519da7ee240247beb8f8154578efe2090ef55757d801e58b1cf0000000000000000000000000000000001197f3c3ca8da2296f5000f7a72f1ee8e39677d9e90a0d619ce1c8e7de00d7f219bc5dc3f59ce4f3fad4451c17b1afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519f32c067725c6d496a939c245ef1801ce34b28ee4c3038e3655cf55eed1cd1ac36f48fc51a24538e5d92060d750f7000000000000000000000000000000000ef52b70c8c6e4c63b79499ece38cdf9f3919720cd14dbc7e1fe581a4bcc4a228f8901ee848459243b19cfda3a80ce711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014359f9f01fc00fbdfc08b4671bd4e99298696adf985c3515f2164bf1c120c38709f6011853374c455912fe615b287d1000000000000000000000000000000000a312122a9c978d5cae3cad06fa1a70c8f6aa0b56fe6090832620e0ba63f462605b08e743c29c8bba2686c0919ba60171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e205d64b977695df0b229b2b007aac9f0d5b479f32c6aef544a4a1a8ec1dde0cc7676dd757aa03654f359d40478e520000000000000000000000000000000001d6a0f86dba26735bd1cc499ea56e7d081cf66ebbda303f21177a61962e8f11bf92b826d235eb743d22992c46055f541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9052a39858d58148ae6457fefc90e5f14314f8b5be0234628307c08849231ca450f6ecfbbf15d42aff58d04a45372900000000000000000000000000000000137a7708da3b5c47a34ade4a954646f119803a75c2f104e0718037a1243a302e3cad8bf9d3e497f45f625db6c591d34b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebde9522362d2780b0111b02371620fd1c1d9272306be1e31fe140794ef5d883389835c4d96cf9e8428faedba32f53d0000000000000000000000000000000000d0fa8770bb03923bdaf724aa54e88a33bef03b6e40fdccada1dbc73561de3a256ee39a893e0d0f26cf9db1a0fceea11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed325cfb227a8bf4034423c6c4b58f3cdb1bcaf98ba1c13f5d18ea6e425235c4c6ac6171a7531dc23535350625f06c7000000000000000000000000000000000c66b73bb56be0457e25ffec1c691300d57736268b2aea97e5d3851981bbe0c871a092f9682107c14766c986f1a7615f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d50b8e1fb81c5ea2a2ec171d3993110f5387f59a42aa8cfe7c371434d1c7d7d1c4344de18aef2bc2f618d657bbc51d000000000000000000000000000000000451c7e352a055c7e0c77a5a1866938c1602aca90a73325214bb2f6ad99afcd0efcc73de56254911952a2ed6851a908f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f62effaabd8aac2d0d0d664decb0b92138f49c584a5dc0923ada2a88972e2525b1f0ca31460a3dd45ef2930210d6e0000000000000000000000000000000003122d5938764dc5330a4dd4ae42d95855c9f3acb36dd8236cf418f46358aab0a36b0f69dff50680bfe04d4b47fdc5e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014adedd94ffcb8d3911ac2ffb37121c24a32ea64c3e2bfa2cc0846fe373f3f8f87bd5bee6aa1e9ded374dbd903e1ae6e00000000000000000000000000000000159af833584493952edabfc819127d92d1da078de48722f0ecf7a75108383ef0647ece492442e28ae32e0e3546297e9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a1e66148e81194003019a071004eb2a3378c4f52041e035d13e102fecf7f3658a829d3fda7cfe12ae711ee3b688cdf00000000000000000000000000000000182988ded44cfb383a49ddb76345ebc56bd72f33ee544f8b30dfdb3dfab9ab58545e9ea1c4bd756b3805807dab061a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001067a2e1d961764779d809af7784c2791863a648fd179a65177b9d722fdd4fe972d19f09a0705e8195525279f4cb5353000000000000000000000000000000000ac3ce4b221da594af3a39afe25da52a6cc049ba673efd78b58ec4fd9a788da3a66042ce13320aa1e5d51cc02407f2a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e4a27d7495f5dc684dc951a096f9263cd952e51e3f53e1f52e7e50e6ee6363b935cfb1b53284c9594eacc5f927eabc00000000000000000000000000000000125065071bf30a2ed95e71693047645b418181c53843d286ba2e4186a3b46700b3795fbf6e5da1f4c763a28e8c71ba081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519ab0595dcdd9e25eeb9d5056d2107c6333376f203b932d5af00e14825fe04e933068db9d077d2f6227f313358fb59000000000000000000000000000000000578805ab6f48cec24a0284bec90b07da435239d18f838bf6892130569c383cc8382bf4f6816475cb3ba16608285816b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006df40e53e07134dd93d85556b60feb78beeb934b72dccf87784dae43740ea66ade5820f2dbefe0ffaa366eed5a49b0b000000000000000000000000000000000fcc01fe63760bfe6dcc3e11b025b5d89033f4f8f08b18092d13ffbe872e2a9717406bdda38c75ce85f38cab28fac6c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2dbf85fc50d15f9de3033661cae043f902ccb860cac848d47f8ac1b15e96ddc900cb00439da88be21aac59a53084ce000000000000000000000000000000001734b6e92ab54406891fddbebde115100183ff020e7d9338c016443f2f84af0c03e301551cf3cc6a48bd4dbbd02e248b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ed77cf5301448ce2f2bde873c4e17a0875935681603779e11103b78dfb4397674cace35f980c4e6437f96825f8d40b00000000000000000000000000000000066cb5075658461ad959b40560becac0062bf80b7ba524f5b09d7df698dcdd90724306c2f94e68b275680f3ae0d017321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b3a0c322010adb6c2df0a1e22eac991ffcc6bcc6a36f87651379e7296177ee662f3b678367011d87663bdf443579ac0000000000000000000000000000000014d052138e19b50fb48077d0a14485da7eca8bd9ec20fa1dfae63131f39fe0b2f40e9437afad2e4b671efc087e7295771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d9ff4fcc3139399148b3dbd74103fd229386125912a05ffc979e019bc33a36919b306660f78a73c8cebbad46bdbccd00000000000000000000000000000000009dcfdf1b29ac61624b91290a3061a463f65e3c6125481c2b13fcdbc795c786349dc570ed6e171f50f45b4b529deab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d26643d2d05df74e7a711f9065e2e3a9a9b066cbe0670bda48fcc18d53ed1b489d0cb0cc57e03b4982f58fe538163310000000000000000000000000000000017e28402baf6bf55b99ed22696111db518a885f09eb34fe0328d1db7973eb9b05feb9d2a900b57d7195f80c9c001bc391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001570d55bf0b2788bdddb7832954c55f23983a762083c09cf4c9ecfcdd3b8a545c5d57efa6bde8943075c3e35ccbcdc3b0000000000000000000000000000000015f5591d4ef4e98d0ae8c994801b3aa1a1dbd1d15ea202e6a4d854566fadd9264146342796ea96022985e4997f5a39251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055f900ff9e51070c137185a5916bae361c9b2ba410879e7436cdf929db71e8b270576803ab24169e43faf9e2a8ac5290000000000000000000000000000000011a207dd903bfad0a761010ba6eac8d7af0e5ef90f1c0ba6eb5a23b137979eb2c6eb4a7f8105a3fb689e8546e1c9980b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100e9720ee0fafd34c609382edd0162e4fb8e726dfa124be4754046487f58fc6c88b9fa9560102e3c390502261aa0a9c0000000000000000000000000000000004f0592bbfb6e196267ec88bdb856c69522743888733c635006cb1ae1cb69b717705a99159e180527304baeca7fc200f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012906d00532a8dabcf3e2f82a84e0901ca5fe54fbdaa3a449483b9314249c9c948675f4cf2fff3bb4c140593e793079d0000000000000000000000000000000019b2d0379fe758767e27e68a075771cd8c7be6f4bcf423184b736c734041484f97f693d7111fba2e15b38b21144c668c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010802953a917dc7e5f943761716cd6511f1b442266c68dda57f3c78ca4fe600d2dbecb19e81a9bc2083010a960da31be000000000000000000000000000000000569e20a5276ba0c28171c69a4e75c7666ab9b94973df6e81c21bf3ef578b7519eb80fedbf9afb295aa37264448c8c141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166d321bb24093e1c27666d8106419addceeb41db5d2fef2478d700123cd75712fee245de2bb37b3306c7ac4f97b89bf0000000000000000000000000000000014ae98d6c527f4e30404678d29129aced607342527c5d3f7009178f202edd160a90ec5b445f40a60aad113559b89f7501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000605ca7d1c1988922f36d71413b0244870a6254bd4f92d9e223b225e3f6a8290b5d25995fd7051761492077a1f75d7a6000000000000000000000000000000000b5093392868f58f3bf257ac1dc70647bc7028e927591483836c2a5d6063aee02c655082dd02e1d2a7a240e1a39338f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cd9fd2e5bba513545a73c8bbd857ac785edf0967f30951a92c69ec85127edfeca1c756aa569ea02b570f7babd827260000000000000000000000000000000016b9d9264bfdfe024debbb894bb5b3abf2d11b3b463e24c17b5e6dab0dafdcebf57dd6b340f3a1d4be13b7900fcf95a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aaa45232af3598917783b76bdb800c0544a995ed6ad462eb163ba46a370b3a039ab2b069339bbc257ab5b1feeffe74000000000000000000000000000000000c3efaa66469ba0f32afb746bfc2dbd143b26f165bb37aa1b315878b7da55a3c1223fbbe9c89ebfe4af58d6a2233e72c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c5d8e371844b96b1c61fc9af2d6df658155575e3085332e45dac35f50c9c3e4908a925c4dac5f91c49fa31e8d0ddae00000000000000000000000000000000001a0c502108df614c7edc6005b804e3abe834cd4af6b797653eed6f25c83f5eda0514d7ae02cc621aba801dbae9b0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cef840eef6908866876170c57cbad6f43e1849fc86b32e5be23e4f1e2d5e567e4205fd796037c854fa70db32e9809e000000000000000000000000000000000258eaa5ff7ec9958d07751f00e002ea86754151ead1b3e71127f25948b984a081ed98e27743fb7d6ccfa1a3c0ee5d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b136ce45dc2455bfae269d34cad265faeeaf8ba454397fb786cf81618a2c9eaa2d1d6137460d1ff3bd66b7b419b85190000000000000000000000000000000003a1ad64e15375ce747114ca4c6efe485e980e4add3d91a46b019988fa727bcd999168c2c4cd42e02a36a0af4b2641b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4acb6a0cc26f531cb3d228c524cefb593be7d7af241fc74da2544731a40f82fb9d5ca1e0e5dd54d1c6ac61e7a7ea59000000000000000000000000000000000f4707023d123a7aa1069f89b196b8ee012c644760ca0620c478ce00d787e72a7aac53c8f678ffc143a5ef36a3dc36db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002043f97aad2afe0f66cf2b2d899cc4530b8d0a54761f92302bd77cdd2379fe6991825fa665b2ea787d5dfd13523225a000000000000000000000000000000000f9bd1cc0f85d56c96f9a3cb8e3926974f8ce0810208248882a7b2cf4e836b6c6e456968cd0ef9edeece925df6973b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068468e1e951230d33ea026ccf0745876bdabb52a7fddf7204ab8cef66907326fa73a7125c2eb4a889f4a3079ae27438000000000000000000000000000000001359e66cf1805c387d83df607965484ed5fbce48fd246e5ef3d8a92429d2c685787fd307c1a78312d877b15d1000fcce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030e8521a520261d7c7ed184d13ffea6db3c87ee4f23e4baf4caadeff8daf0d895c9bb342ff44e705294affbade43bf700000000000000000000000000000000191ffae9e26f21fa6455937226d4aea09cc99b5bc64998d858d7b1d74d7d0ba59d00fc0eb54d84585863086604f6e5a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000067534ffa2d6d6051b121a910201c2a358cd193ff016b32f27284e327f673e086d683480370ed517e72795c76ad93af00000000000000000000000000000000099668b30065dbfbe8178de2f0215c0e3cfd4a1ce0f8d446d9ea419bdf9fe2a555d83984736264dda2a2f214e4f9f5541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000309210e8ec338e365cc2a6f40c50d52dee090b5b17221647f81349632249530a69c618fb5d7ceb1230be1538be30581000000000000000000000000000000000a25848101deead43085ac381da81c76d6528cd95650c74466c58fbfa4cd63a85ce25dbe6b4dddaa0187aae9861c9247", + "Name": "g1msm-64-jwasinger", + "Gas": 170496, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000c5480b6630e8ea29b9be1f9f5dfee8448bb57e0f2c3dd1525db702c3e491b3c1c41875ccbd038e224d42007f571bafa00000000000000000000000000000000047926913cd01d62be5a15bdff074ee02af49d741c9a8e8f32ca608cbaaef7e491fe2fe2bb0375466d2c9512a015e68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a848aab1c5836b4cf5580353537313468d6d20ff4f7b553ceec8a343da6aeab297e043f6df9f1fb1c05663e5f86ee7000000000000000000000000000000000a6447bb4e711b206608044367d9c9dc079e4d52230b06add2e898cd4b1866fe880edd47cca83329b60f4114a98d933b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000949b16bde26e0863fe55aae62229cfb1c055a4165675150d7661ebfc7bf4f2761479b4cf7b5f71b2c7f633fcc48b3600000000000000000000000000000000001df90ad1bd2ed049867062a13dce7bc9efbb39115fd9428383ce44b0255b0910dd6d1e4df68bc8abf32c994cc43dab81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f559444a4d1acb707f95108cfaca51a38fcf4f503025b125c874ee9043b2e3c03276f7c11a46906f37e8c38af91994000000000000000000000000000000000f97645b0145a62b837afcd0d372c005e948182e2c03fbbd87024f608f647af5ca533b7f81c695fbd85ea75304c176661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4255565aa608df897d02666f5012556fce5bda45314f0e9ee5330bf237987c9ad25a2777d2843d9d741899977afb78000000000000000000000000000000000d226176a17080ed2393c36d00e9850df3d1460d240f639646b667e79f3b72e1c5d7d467031645eb232c056e91268c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101204298425fd8accc314a26759abd07c310c7700bde2af3e64f88016e400f6235eb3541a246dcaddb4d25fb85f73b8000000000000000000000000000000001344f6307bec6a4d65c2a1d0d42410dff37fcc99922d6087506351430365de64abfefce3c8be2712756f822bd730a76d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171da420c3db1c4cc857028c03371c033c6fccd44a655f9821ae81d8d0ffb16d50ba4dab67100ccf7bff93b33768496500000000000000000000000000000000099a94a3cd9060cbefab383d96d5aa1ecd1bb8b8ec4276b27c0761cc883bcec1bc8e72bc1f0643cb0cfc1efb0641731f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5a6e20be3a9b9275fab5f417b8840525788069f1790332fcde430f0a347bd012769eff83e19e0b8098b23e7befca40000000000000000000000000000000009e8b35f122e7f87da4daa98c9166d7ca7cdd3c692a16f9812585e079ed632f7446e08223ef5811c426659141722bce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fcaf99d25414c157900d9c7f6333a630ce5903e14ac13148ba0fcb8acd0b95f74dab5c8cbcac3285517c93ae0093b4000000000000000000000000000000000b976633dc157ea3852629bb8ba64950f2fa1b7af5f1631ad128d05d27259da04a51bd287081f35d90fe6a391e41bddd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001945649b3aca765a4808884c55e6e823c1a5050e42308066af64238b3ba4bc890e9b4b9cdf78590128c16f81f2621c76000000000000000000000000000000000590e08976aaf099aed416d4b34804fe4a0ffa14abe1235209502acc2c034a2a71be3abdd9c76f3ecbac6417fdbee3211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a5a107708e163be101bfb382550e740aa834719f3a786afae31829ab2e22ad8d47cbf8c58cbdf2005df9fe2e503370000000000000000000000000000000011eea93709751f42d0b0af0b2eaa23d13dedfa0223df076c39ea3909ffa39f8157d0787a67d8220d05bdc2c4e425602e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c6b305b492bfcbc964c076ca0723a02d58986c206be46680e557d4f34836440791d7df36f3db1e26c4ad66f28c0eea0000000000000000000000000000000009c266b6060df811d1980b2caad6cc4fa7fe9962ef27bd0fc2d543ea5ad8cc9f9948b9bbbac3ea53c3a2577c1f6daf201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683d7b3e8ca147b372449cde76f2cd083712445f387230fe27013ff8ab56ec2d3f14c56491c7877e8ca8cb0eb9e23d000000000000000000000000000000000087bb3454189c41ddb1c2ab3940ab321b5dd65c4f6d77a18039f3296a40a3a5605d2a1bd866261e55b4dd6994eda77c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055c66f2198b6084c17854de9798919176a2976a2b20832121c4c0617e104ffe0446de55861ed6f53506dc19d5c89ca90000000000000000000000000000000014e5082c30310fce95a4df7f1acade2965e1e32291703b9b3f1ee106397062a4f93119ef60e0f6aaf01a270722d0eb881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d7da98a4419960126f7602ddb2322734198deaa678bef3dc8fa0da48d87b5485b95bc067eb9ecc01b66300c6296d8b0000000000000000000000000000000002e2ba5c2adab840ac9bf4a059666c8f2b94964406056e41deccb029a8803461dad456e96c6bd974197f0d561f164c871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159e13355d7750722aa48972dec63e6b0fab20468ebabcc6a538ee100b844f30081c1fada27cc9114a93d7ed14aa95f6000000000000000000000000000000000488b731423ea5800c2397a288c0446257e47d5e1b3f8cf3a1389926bcc95e78fe5b2dad79b14ff233558780fc54aaa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b445c0e6b0a4bf64ac4b45cbffa9196bae9f293c1c8bb0de4ce96cdacfccd20a5c65fae13461e508289cbc73a6f17390000000000000000000000000000000002175b24a1080f80f50180380488ece7c621f5a31db2b6f292294cbe60d9bebbf90051df5f6cfc9f6bf6c1d26a94e4f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001530640ae99b6f7ae02d567e060fa469fcbd87131253c8cee12d8e891d44ecded5930f631463e6ab37a2afb6b511de160000000000000000000000000000000017acae258af502adc7032283528f93cdcee1d6acfe4dde7cb975c9901967df5489b4a1aaab4dfc80f0253c71ffb4d3d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b989d2e41669309b950d1ffe78e89ac89fa83e31b5dae07ea98281552127332fef3429c25a2c72e6d60c28808e83650000000000000000000000000000000008644b074a3617e5c18af53b663829bfb45fe5a4762be00aecfd261e6204fdcc107ff879a21a06f5c8ae71b1a5b8c1ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc0a0d1d8eff56b7790169dacf460e8e04cb7f0fc6403a6a4076809ec2e9f1d685d95302b27fed5d33f5266fab232110000000000000000000000000000000006c6a8fcb415e40fecce608fa512e19ff3a76ab275dfaf10048593e5e768105d3580219b58b3e207ea0eb102944c0da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001192ac337801cf127720be76f2759775b4ce93cfe1aab197d41c1b7d5e493b9b5ff3551f0131a14c570dbc2dc1b7fc6c00000000000000000000000000000000104df98d3a176363626edb1be59d7bf41a5c65db7d10ed525ffdab53930d117a578e3c82ab3bfe4bc8db5e1c0b71d3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cbf252fe6e6326259358dc3be5326299153dea508e3443497198dd93d65bdff71cad3c62c8b63512286fb079295f3e0000000000000000000000000000000011d12d816fbf1dcb6c3ab25954d3325e23793aaff8d9a67840225eafb9c970b03afecae5d123dde39b46e4834eca7cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24263947f211cc1a43436372fb03aa38c0862b7db7b7b7d4873dab6ec808b09830d756341cd5121a49d0b16f94f37f0000000000000000000000000000000003fc7db117cb0c3bc9d9c87520ac8fd395d4ab9196b9f950368b828d8c471e980c6580f40bd4686d3f9a3990aeb440301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e676ae3eed4902ae9461a2721676f1c2b8f5dd581d297b014e6c902764211c4fe0dee198f993a48b76fcdcaedc3e26000000000000000000000000000000000689bb44e55f2c0e1a13a4715234f061e2f1c23320f928fa34a16dddf82b4daaacb53afbfa52786999e4005e70b33d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131a0d6a8e04ce117d72617b6690f31c1e4cbff089eb11caef1bf5c83c5d7d734202e4957f980fcd3e725209fa36bd91000000000000000000000000000000001405ea86e271b1e9e3e8a15cc11889531a3de0acd7c4615f36b596948a778c60eda6b848e7e2391390571d15aabce5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001937c1a27812904597dc98529aa58c683d42a967084125a9b825cee425ed97ff4e62eba34172d99e7445b2b4301c4100000000000000000000000000000000000c07e417024e855438ea693070b8598518e9718756da1e2dd9289b98c3f9e6e0d4fb44cd6d34106136d4b56a839a43481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153aed91e2393c7214eb89a2fa07b05c9676a468c1bea72eff7c2aa915b68c6da473d685af7eef186e1455c5ee0252ac0000000000000000000000000000000007739bb486df8e3980f99e9ebdaa2df021d912ab0c2c4c5364ac5cfcada2a53af28d61b16fb3f9d152e423dc7f3f9e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d0453b54b297745e37ac3072971e5d9158f5da9cd2832304b563bf0b419f567ee4285cd380e5f4b6e2fb07e3b8ee30000000000000000000000000000000011825d458232f1e4bd05354de1b249f3d1bb6a6c439efc3b89e3871a64f4e23bd96bce719d914a9c998f8d5105874f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010c2c14d8bd7a5ba678290b6f1fe778a89ea3979fb0c854876c463e08ab707094687c1a4b490d70bdab16affa7ecfb6000000000000000000000000000000000fa5b3af935f27cf94f3ac95dc9df7168828662a02e14afe567e99030a8007216452846c2b2a88e7ade88e249fd2b08b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb480355c08747b7c7d0ae67205140d0c23d9e55b27ec71b4509d7f1369229c0f0de34c1c9f0e9f62b48d887718359c0000000000000000000000000000000007c528d3dc229827ce226d57269cd0179b6158a9d595ce03f5186e7ac7e0303e79d223256732a1c0ea8016a2bd0ada841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019853f29c1525a17855e599bc58a3a608114b88161f958befe011128c41bc11eaa4d8a2262a9cbf134f2dee805d53a78000000000000000000000000000000000eaca01e1a371a98f99183818231d64617ab4baa5c8b5f65d7c0dae181cfb22b3ed598ec30fe386bed02181ecd6193e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e9a661bcfc5dd0aecf9ffe76a39d2aa69d7133520bfd11d9035165c172e139b66e6e75371f2d7d8c14ac597a44c3e000000000000000000000000000000000175c348c556914a2b5be9541491d15b8beefc5650671a5c59a3114ea765ad7b3664cb4528be29f3c13a74ae3ea5dcdea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008263f247e53acebb9e8ee2ad62a1570a79592b0818954cace7a42b31d56f9d29a503c6d691a98a95a730c8ab70efa920000000000000000000000000000000015192c3b4811ed3cbd780a99e426fbfb5d4baf2f6356a0e2243f88db2ba040004ba5406210f3af95b55ad4e5559f06ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000830402bb71ba8c3a80a671f43e5895c5408500e86e78c9b2b44cffb1c114a8a540b7ab0289b0480a8e21f63a81ea4c700000000000000000000000000000000163178b27ca33cf677d29544e4703ab318cebcc368621bbeb4d675c54371ab9386ae647932da145e2f14ecddd4709fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000187aea5bf912fd9310f0f33e3a3561251222e5a6f8d5ab3b9343b650833410f7454e4220126dc4cb42ecc1f52ad9bb100000000000000000000000000000000042b88af46faf8ab9238af620b3fa24c843f113abe64e111c1c6dc41b2bd5b12d3b263220bae37ee93f6ace35b551c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070b5c0689bcdc704c21a1c68c30174e6693f85ad1a8911dcae5d54c19f76de872532e7bc32c890d4ed4f1ee91049fb5000000000000000000000000000000000fcf4d51d573613b868ca4c30e97d581a213d731fa4861a88ba08eedf0ab42592fa5bf3d7a0a4bde07039791a508e1781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a47ec3f54f7e5f864079838c7c0598248ec65cedae64cedf0928ca8062c90f6dcaf568093e7f54e422d1d90fc413e05000000000000000000000000000000000c25b6fa4ac33e6500827854763bedddc496bd32fed1648f84ab35f17d28c15b679980cd2a4da94184acc7a31a2dd6ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb57366230a1d93541bc324a8df1ff5ce78e29ddf7fd431da4d4ab9723f364e7ff22fea276a2561fc95f4240af5c6f70000000000000000000000000000000009fb56d7d74acfafff1de7c5d4f6ca88c641f197b7ada7e713716d645b58e749db9d9c44062da7957b0826c0d6f5c2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a20462240b3bf33808f0ce013fcc2926a6c6d747641fcc3108d059e29d6670ee529186a348fb7ea120d5d9ca915fc00000000000000000000000000000000007462373259bb48c1b74e5d9fb44166226482c9e035111ffeaf953c41c1260f7bae9abef840353c280e1785ff143053e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f56ba68c344ad1ffa0a93459cb18b9f0102f2ff64c7f723c4bd50b6c7a3a37fd39d12d324286a4e92c0a3c31412874d000000000000000000000000000000000a2446d990125492368c0f73a19a4bc8d48ea87bc5cd94eea8086d684ddfaa553027073586fb247dac03d53cda512fea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138b3d5074d75dac121b6493a1a1948452fd794d6533175dd09147083891ae20f0dc8885cce542907335eac8227680ce00000000000000000000000000000000097ea343b5b29dc13b45abda615051f3c20fff3e868cace370ca1581ee09e6499a15c6b2aa1db04c1a9addf0ebf7d8601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dbffc6892b2da7856614022847eecf24bf9407dfe083e475bf47a9ccc516d66181abb987370cfc12d330f841e85da400000000000000000000000000000000140be000f7262f4de8aba77c2089c5754e9056cf7d7dd7f3f9697f030dd6317a71fcf185a3bf7ed6e6706cbdf6a379f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d5e397f3052864ab34769de5a1e6f11f70a56bddc16f38090b5276a18f64bc390e6d24f62cdc828c2480843d2353f00000000000000000000000000000000146c37055a35c25ecdff41dbd7072c2896b672abda99df9f586d568647666b3008f1e99c83fee059ccbe6064ec05fcfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa3d2fc424eff0c4c6d5fd28b76f3add6280c8c45317ffb756e92d4215869e209e1b563d62faa0f3615d9d28901f750000000000000000000000000000000005cfdfff01a093011726116319da6c3aad8c5d4670f2690cc714f4c8f517eff9f65c003db9ff38497a2a2e1cb5f28a2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a54b293ea8832f8098f8f837d02a4db2df41ac341ff3eecf6814f0c6ca8e94b7799ebdf10ff3d76c38c5e7785bdef500000000000000000000000000000000093768bab8fd54f3c2de804c7b12d504c8b4b8e09e175371aaf3d439e5acd361e93b9373d4991f2648606c278bc05caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f696927237ec7907f0bfd6e263bccb1c3c83921dc45276afc0a1733fab76f6aa992a95109cb28775f450d650017f450000000000000000000000000000000000597866ac4f8763a2f313242919f176ba631da5653c8bf855b277bb6caf761329a2ff1a15d255863b8be9c89ee5c9d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ace497cce932aabeb3550eb3a16bfa3a3585f07e18ac78576fb2021f7f8905a2843d8daa5f8cd00eeb7a9f6e7a4ec4000000000000000000000000000000000f0381894f0ba7347bc883a3a193e605fad9cb90ed809ed53539ad2ae5d119a0c9f2367bda6f70632a91e58c371ba2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623e86bdca29cb30dfad0404e8f23d4af7dcec514898aefb9369ea54df9801070aa1181df0a4416461061cb01b2256b00000000000000000000000000000000025907568042fb7ed12f60dbe3059545b80b519736b35c44dcfbf2f03991a95e28c42e7cf66eb25712dfbc236fd3484a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178df93ba13f174a15e7fb353112cc6742bd6b02b0a251b129e756b7b9a2f288bd71edf043d63957baceda1132086d00000000000000000000000000000000001340e15f0f105f545335e8887713ecee646d2cbe88703fc45634fb47e5fe3d0fc54f5cc7f5743bab52b701974e96d3ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea00023ef3ae135e56292f9e57214fee8f95c36d83cae2373028bb1c79c7ac56461beb0b2a487227671f94f3223dcba0000000000000000000000000000000004ecbaccfc0d18221b0508e8decd2f768d943c72df434b7b5ad1164d389d029e5af92033462e4d8fc952f921f29924e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066e8d506698a3a6502be6e5161170fc95aa564542b80b2646a17cc8a28ada3e810d8e771f5fe882d1e3e807a8ebf28d0000000000000000000000000000000007ddbf57c8f5b84462cdd6b8f5c35eed611f7d8898a27ca6a10e5905a455b189b7ce261cac235f8c8661ccaa43ee6cc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f23bc58d2e2d3932f2523425ba88bc4f617ebf4a9c43620bc3e5fa004b8fd74d828889282de7bfcd14d7ec1dd1685280000000000000000000000000000000007b97338c3b74026c05b9219be54d263794dec1e88bf32b100560967793100daa796bdc555b23c39db47a6238713ae161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bffac74360b4abe2df341e2186ca5c6dcd1f2d2aa6d007751c3fe137af242dca90a044d78e4147a08869aa6f5c5795f00000000000000000000000000000000174b0ba5580b08c8b98f3b6baed836aef9f5a660ae320a7316de90897e009cbd6cff7401fa8f2f7d8c6e872fc12271081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014e80a5a30447d87159fe0d0423f31ce32ef0d02eada7c26e033192507527dee2de39167e417afb17fd12e7d7a87f6e000000000000000000000000000000000dd14b5e3c83f5f28035327a45e8fd568d6215c6721efc5de6c74e30ea901aeba92a126f33814755dbee8adea1a30d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cfc4e1a1299c5f9dfbf62f172d6315262127b5aeb525d18fb48c0702b5cc56341cbbfc8eba45a3f548fa6c7ecfdf8f0000000000000000000000000000000013bab2a6247dece4c1c0763f59033fee17a6089f0c59c438a76a2cad53d92f8ac2859df64d1bfd31e1ae0f2e0ff8e6ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c62abc02febfccea7074b67eada8e125c914146d429d00d88af296ac95a91d82dcbe23782d127375f2281c4e3b222a000000000000000000000000000000000cb11999c68cc3c22174e87ddc502a77f84e34033bcdf7ca9a4d339de16c72218667ae481e6c77eba593fff22c354a4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470aa725bc9a350efde69e6da97b83a60f62eb46592fa315121d2f2cecc1628c3e0edba70068fe1515ec2a4c6dcfce70000000000000000000000000000000001ffa071cebe850e635d6e6a65d80c58ac33450d8eb7ef4e4a8f854db42bcb3074cb6043d289a76102516a2aa076dade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012385bb137c75bdcfcafacc28a893dfc3610baaba443c3de7ada4f5b7c88f1b8cae01bc6f9ba2a1e58bf861976d727a9000000000000000000000000000000001338663ad434c70a8646786b72c75361ee19afcdd897c731ef5d15085e34f53c3e361972f3622d9bcc1b21c599430e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073d86263ca62df5e3b5cfb9f252ae188c04e163c65cbc25e686f44c44d3ed2e3f9c53a15ede2fa687afd4e7f96f5e860000000000000000000000000000000014b7dce0a57c372ac6c7304a0c370207f937f036acdb20c5da71e3fcb80fd7dbccf2926a2440f9ac982a07d48fe018ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124c5808cd59ec0c8a8b983c5ec7ea83e5deb78834074d9922f481db41d4ff56b9fa43d06fa7790939b19ff6c7a7ec920000000000000000000000000000000010f77bc4cf326c5643fe1e993126f28b50342b8533aa74e0503430efb3904a9a019d64772af771db170947f6b2f879bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c443a3a96a150ee100cd8b2ad210cb74ae3b55e9847baed30db5a77db8d5f2f5f5214a24c991e6736149c949945348000000000000000000000000000000001176754d10b03fdc72defb70965b9c93675ff462840ab847bc86ad0f22db926017d690238d60516e644da12bb28db7151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354b4c8fabfbce771dfee456a6f3ddbac34233941d542f5560dec63850be517642bed05dff650b48a08b3f71bf44e3f00000000000000000000000000000000182d999a39f4cb1ac0a3bd4ea8b9944c42e939d3bb65fe2027a0ebb80185456730e92bbc73efeb37c3e50179bef79bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061181c505d50b7ad186666f440254a45934a07acb7980827ab75351b3cd774955ad809dd01be7823a5cc54f7a8568790000000000000000000000000000000015113397f83bf687bc98ca924243708b1dd630321203cb5c59674898f1d45a1afdc29196c7ddacbcae1a54435421d7361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001382d7b57154c8ae004b9ff7b4d23bb4b078f4d113ba4a74ad6fb3d1a9da1941fe2c48a06df0a3f386d959fc266809c500000000000000000000000000000000060efd96f4cabc14b0551c4ab423ce035bfbbf055248fbadcf51951b6c858ffd831b31a7f7113bce1c6b6f5adad4ed781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9d7391463d8fa2c236804467fb550e75bba19925b182992497df5fd76f667024929ca7b530ba2d9c2db1b8b2e4f0d00000000000000000000000000000000098d659bd1a414f5e5876e4b93c449b944cd192787f7da37d6f76caf235ed7a883e6f9a151bde8cba4b907694b4d96bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055be45ce5724fef196b7f9fdd05ed77b6b6ad1b7c01094ef11c8a34eb06f396dc005fc5e1a4cb0643f4fc568431a9ee0000000000000000000000000000000008c8db9eab64aa258b5feeae6a8643fa01c2d144a8daa38cdb25530eb27309f40bf4d9ab6efba79c28c71483600fbb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047fa198d37144b81772eea5ef6026a142ad55da7141f2e022d3d377d57a003d6c5842101ba37f3594765d858e1e34cb00000000000000000000000000000000030a81129b1ad9d634ae8cfe75e6eafd9e03ac6bb9c77deeef6032bbfb4c78601c540c02d895f9b438f6b4980a4d57a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000dd142bf9ba8b29665fc93aa8267a38da28793bf3713c2abb2c2c2eed031a309cdd0050082c05d47bc5ff8334084d420000000000000000000000000000000002fd0f2f1767f981270a99ce85322cc163b02899b4150cba8613289e9253379a2741a953ec4dfa7e5a5f91abb171584c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000756ade17b13266f113794fe759603940b8575fb0b471fc76b2f5660494f7e6060bb641f41078754b4992855b75d28f20000000000000000000000000000000003d2b76534296b232e9465c87838e1eab335ab56d50fa83c4fe851285ab348c960566087c4999ce3f91a0ef41671dc191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000817b860b283f015efda3c3fc94841ca0f80bd8a51af1aa1627238cab0ccc89f35381152de8d46b1cc4635554b05fb900000000000000000000000000000000091f3c27bba08c11888b9159241eae16159ee9ebac991966e1f8b30793c881e2384002b3f7dc576813ba17c9f8d31d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ac51e7a570b2a76a7ec09f8d30f26536faa7e5653af02b6ab345d3a4bb0bb03e802957636cff8f5cb80260463dedb00000000000000000000000000000000075949c6fea9dd0632b6294906a2b2626fc5ff44db38af721875b854c1f0cf53ea9b52b62ba6c6ba901b341564b40b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013543adfa19cfe28e1a0ecdd22e00fec78dd23c26ade476b03310ff1366e690e9053101d37b1efb5fa7602e7cd190aca00000000000000000000000000000000102ce60bb32672f821bf84da26c840147fd26692afba5fd44f404f3130178a2a4ae6240880a3c752c3a0e9b080fb194a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c62734a97a613f99b322798f0595390c0846e00c44e428d4a27c49067657ce65ea51503d49c873aee4c0be7e1269eab0000000000000000000000000000000014ded13784f741a5bb86affbd116b2076e8850ae7035a7e6bc2a1787e79d728c71d6c5c4ea6e8e11c344ff9bc772cc491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e8297973d21679f615ff0dcb30bea4dc334c54b1281f8477d6994274cb0d88dd695168fe749ec0ba2b87ad2957e4910000000000000000000000000000000006dc6e3e85b2873df12cb062eee346b598015c6ffb8ee977d88c1e527e2d032accbe4cc1b22c9dedb1d998c0c4a9ba161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174c9bda7fa709e34c20f4e6c30a2ee061138e217ec875da0929c24f1f053827e5d9b9587375a72a16e8ac9ec7c58a0400000000000000000000000000000000060297f36587a5101dc81553501dd0b2ee83edbdaa62b0d746412e933f08ad6434efcd9200e7d40b3dcba0956bf5e6511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f948300fd46043100d912c2fcdce98d03aeb922f194c9054d2a3350fbce5aa2acbfef9f68a916bb17372a7728e9181e00000000000000000000000000000000120feeb6b93703157494252c97172ae33665d0bf8a68ce79912bc9f6d2ab38a69adf6a7e6c45f43ae592ddca996593e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094df65b2da7d84c3d7220d02f46a7cba5404393f5417ad3e1861a9e6a3cf33001fa1968787003aa9c61a1dc39a3184200000000000000000000000000000000030e177042970eaeae4dfce6ffcf696e42a9e9e7c0e89ca24b26586006ef0b0e6bd0266df7221092e059f296bece616e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc76c7805aadb1d6ba7baf59063331789e335e0f4766acf70aeaab85cd0a772549e3f74c221c3c3cacc3816d1d13846000000000000000000000000000000001690707236cbaaf153ab847c8c9db49a8012f685f1a6af929884d10ce4faac84d99d1b114a1f31ccfc7447f8f906ab191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1b1a07b76165a39b681a24e1abc6317992ef11eb633a76285aba187bafb87ee3b188464e4312f140d537da0d7c923b000000000000000000000000000000001413de60945b4a97b8c4ac1dfa77f82347f2f362ec2f5bd9901148537a7a3250998c347500fccb3a635afa0ac627d9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f29ddae9bf285ba25616fc47c09602915d4e456c6547895e8c444276de172201b3f929cd00cb3027c91f384f76b8a9300000000000000000000000000000000073eff1f50b49401e64180da721d05efb210e524ee8c2abaad9eb1bbcb08b6b48223c7ed862d7d982f9340caa46fcccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c92ae3dfcec8bd5a900d3c00d865381b79799f285207572c16cc42b32f3950c5e81dea53da59fc6b4e0dbfede33a5d00000000000000000000000000000000026a42dff50043a54ed3ed9f45a6505da23e57d7eeadec17a02e621a34807e793de18e2d18b5ec2a061231cb69288c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030ec12c249fb0864b634f6362bae857bc58126399b288561cc0177aed60f8642a012b21b4ca8f0fade406c8427d6ca3000000000000000000000000000000000c93341af6191ec7f0782829f5ded8f655055018db92c457e0afdf59a0153c5ee4fe3aa44940cf17787db1e5d8b188531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e7f02e6a62131eb674c31f6cf54b60faa76f4a130eaa5d9b68654263393d50d87fdcdd9c2dbf3a6f9c7bf782ac38ce000000000000000000000000000000000475883b0291d994433c68432456713e516f8239b858bb6c69bd2391be2ffdaba67bdc9d2c5de7b8a70cbbadec082f5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d97377679fb476d638e3cf45a53ace740d5fecbe63e779a0fe776395b5ce58e5f613c218b8f2daef86f237a3ccb63680000000000000000000000000000000014b6e926e8a684e456196a1b9863b3244d9435971fad5ae4481097853a2d7acceb076e11bf5fa6aaecb0f5e9a202d5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cf11b7628a09dbdac7f1705ee41f5964da20ba3636131c4b457cfa73dfeee289d594f7e49078c4a6efd6e754f8e88000000000000000000000000000000000b0b5e86eebc0b9b035bf7b81e11dd0ba96c42c779206c6f10aa84deab4086131cf18b5163a165e98aa28ab888d1d4a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d432a0f9d84f09f477478b300a6fb73d628841d25b2798940f46a35869a7c5a709fc36221a25a5486391a2aa9d5e6a9000000000000000000000000000000000e0a014adea49a370b26d7bc92eced309e56805bbab54964ece4cdb88d5e426a799cb79b05df9cedd8d0174dea269b591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076be0a1e3a47d9674ecbcfcee00f25966f31a09d3efdd8b32c6f5223c1360af038e6e9b51cb85522573306ad9d866400000000000000000000000000000000018bf6e9a4cc5f653971378ccfd1d4bb7111b8044ea9a22f599913b77011d044dffb5994dc65315fb63f8e01c2c07a8b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b0e7d820e0ee2b64bdda08de7211ec1aa60780c7d879549d3c9d24fecbc808c9b0ffdeac5845afee43cb6d0ce910c500000000000000000000000000000000144c3e848b78149f4cc7f746a3acd35947867dc8f9ded8e62136ccc089e7dabf4c7990e0efde2588eb5fc27284240a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125de1e555e7179a8c1ac056181c3e65de8ed40b05a33184e342532a29471032a757f58843f22b7239d7dd4170a577880000000000000000000000000000000006ed91ec7fa76fe2762b3fd852c24af455c7e5dfd512b69f4f0a9cc841e6b8330892cd221159dd14809a9fbb8af2061d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ec697fea121a7a857b03c0fc04badfab45be46fb0d1aedcedc3fa2a9bc63a59e2f165971cee7fa44fe6c8b8ebe5bd8000000000000000000000000000000000eb81bada054f66f2f296db5331e9cf6f01d08c322f2314642111647981fc8fa87a0104260f32a7b2626f801285ff4bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d609732c1e4d59dbf1f4de887c425807a0baf6b16d0a276c00fb6eef63a6781ffaa9245a3c92a2afe82ab5d2d63db000000000000000000000000000000000fb962cacb7d9ddca818fd32ca967aa6290b6dea5b7ef25f510ef2568f4c35bcd24ac2dc1b0aa90cb00bf16a0447184f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001268f0f881951ee6e5910590b7ab6a281182c23d76ac5a587f81930e4910108d39e00062b0dca6e222b310e5db291f3d000000000000000000000000000000000e300432392b01194e1254dc24b55435cde006b90fa9ccdbce23df38c70ed542129e4cd9266173ad59cd79b356d569031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eb7626c50f5112686189e79cc02f794eaf95f7d3956272671de3b213b430b0adc27709e05f766ecee13ffd632701d9000000000000000000000000000000001438ca26728331fdcd9f123155110ec0ccf5377083a36f53072b4ecde5bb5629e49b1f950c721d13b9159337f1c654d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147f9a60f39dd3c57535670cbbbe35a2431a0b7057a095f2ec1912b283623bf35c88c72812cbe9bcd6afdfdb8d771b780000000000000000000000000000000006384a53be7a7461b63d44c6d8695cc3c094d740e77b49f83ce139e16a1a52fcd0b955b3222283079f8e34a7828f277c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d7f7647f153ce3359e1a5916609b3c2b2218ed231119863ac6ffc963fd0524918f95abc42657050fcc1b52e031dac0000000000000000000000000000000012e3bd2a080878d8c7997cc7954360c69e655618126869bf9e821c96134570e239cf1086d3d3a848cecfff143be11be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000941ba4790f818a40f9ab6d8eddb472094cf1b871c31546db996440dc44fb40dd53d5e793f8ddfb229a86aede4e2e124000000000000000000000000000000001951350a2daf2b8032c4c86a4459b5aac53bd34eae7f2a205dc196b4e5d5fcc31bc9c927d8ac130419be5196a95faac01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000435b643c0f8649b5022636f417f2c85f3b693ee745ad0fd3cbd0ce49ab92aa4908d2a43d9576e2ee66929b5680520000000000000000000000000000000000014f17faafd9eb0ef53949d3d8bdf6d3ed3e2e62872cb442e1797c5e33b2b74e3498832c81ea7abaf2e9058b536d01dda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001626ec647136e5a3c99addc3da8ddf6441e0fd9755e21eda3fb24c9c97e3e8538612d1bf1fb4d30675d557bf68f9aa39000000000000000000000000000000000fe8a3a9551566cce18353d298d07d0933038d01b20d7d6d1527611ede74ee41d9e377dacfea7f674ffdd653b0b0db431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014066ca915fd121b492a641cfd6775afe8989c295e80f2973d73ede12d308a39e2277430f69da1e7e9668a503d1e2aca0000000000000000000000000000000013e4d7bb49670752dbce18960c68745074bb83d65596bc4b1b5526a8cfacdf29b0ab733d00c68084a6c6b9c4a10e1fca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2b5b1dfa6c862a7d744ceaf5d9a0ac50171c65902d5ea4f8aaff191b16871d111b0df71af9f6cc4c736ef6e07737f80000000000000000000000000000000012faae303cc7671757b7ff54535496b7b9786daf3cf29ac889f3ea9bb02d8ce3e08e7d303792ea6a4fa2cbb70e871a691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb13351c1c0ea62191f374be76af4ee5c22dc16b319370fcf7979f4dc32d827e29372c51effe5af00a5aa90a2e1f3120000000000000000000000000000000011d5d0edc8ed1c32904066960cb45742634a2fd2d6255ef7f684f4209fa11aedf1136e62bed4833f70b5dd6cd2625fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059c9b124468d9b3140d96968ebe941740d83f7f3ec25f30cb60a0e225fda6d602d6d4c24f0616371f3eb0351223ad1a0000000000000000000000000000000005431a5239a2323f7e5d9fb5f1b2d37deecc5b3f36681bc276815c4789f8a64a2df096076b8d71c2afda0ccc1fff2bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065ec66fa8fe5733632d7d1f8e3a33a43253216b6a8553bca343135d9b2a23a006f6888fd3dbe3ff7ffaa11f121579af000000000000000000000000000000000faf956425898eca3bba05de3f2e16b2317c5e5d0859c994ae19ccccb5928dc1bb2f28fbd01bb5e14aa56228b340fecf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123e76aa159de76973189bd61a534478fc3b95e0ee624f274efe88412c586d346c4a80413192c984906fb8ff863e30d6000000000000000000000000000000001184caf5c11bd8c0297be777d4031262359dfff9985f44886d04dd89a313f7ef260c116c09f8271704fd675e86af61021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a970130ea6687b1f78dd35e806e8351c8f94bd4ea11edf443ab123b6d925c8e969d14d3af678191e9a989e857794570000000000000000000000000000000006ba1eac93c64d2f1f4d7becfb4e54e980d06359227f1ee252f7601acb92534721caac1e7577483702daed4794e600461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015eb7dda73051d38bcd81ff2a714aec3d4237c5d249c2dfe371a616a6106f0fc7838f078ec5fcfd9b4a92ab0a74e88590000000000000000000000000000000009b90175986bd7f8d4f59934e43e1dbca0b82ade7b8183c9dfa8a92e402c9661292b14df9397b4682607847c80ced04f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c781c3220e6af8053c37cf618d873b2565412a46a22ffd287f4fbeb53128b650ae27c3bc733dc876032a84aeae5f3d0000000000000000000000000000000018bc178ae0cd72ca2ccda209beb00f0cdab57ffd21de96ebd223e0889259f26cebe46c78155feba7f08fb539503d97fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b0aff8bcd594e93d18dda1dbbd87679b9c3229f31a1870c05db6259effefd4f2acfe7e45deec67abf7ad7d639f9be0000000000000000000000000000000000b0b80f3e69b1d0ff25cb408c60ad7fb4be1cedb7f8b9dd7191c34d4b431fedac16931e7bbac6f1aa56846ea6124a491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c75c201e3566f5339b348afd507f7cf493b06196ed6a0f3d759965ed150d5965b21d7ce9759c4469221a4a2abfad08f0000000000000000000000000000000011e4fd017d8662af3c43c2f44947ecfa4eaaf7f50acd118c31c1cb18b97a079e4c953a2b02fa8b9f578a647eac3504af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d385e2272e1ca0eb0bb277e8fa4d14d389d5afecd2fde5acc190b8064f00db86eb7448f689b715be1c0d12eedc49b1d000000000000000000000000000000000f65219f49edb0cff554a855876d35249506d0b3fa661554cf0eff6669b6ef4378a18fe3db036585fb3be7e10f0ca37b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018442d56243760a3626f5b7229a2781a75c8c065a62e08ff31998e9dfa1219c0deffecfed7b49cfae62b2c85e1bb69a7000000000000000000000000000000000602d343d66a31506854ec098687ca37cae56a8342476e03031c114cbbfb3997fa0242e398dd20b7b03ef101d75d545b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006503251371051bff87953ecab736c79460621aaba525147299564c8dd9786b275f0e1b3dd83e11d88e87d419c3b4905000000000000000000000000000000001000a46855e30b3b2ffd72f274492ed17cc928ebb3e13ec70baeff4085af77ad1da1bf9592f2fe77bb545c1577261a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9cbc1cdf529ba9bc2c73df19215b51c17e4981a56bdf0d70efa0139a5284ba5b83f9e8a2b2e3b9f5520b28f75461400000000000000000000000000000000056083fd07895550ed357268ea99ccb1f8cc1f4162cf1e31f292b211cf390498da96994ab09a41a4ebcc1934f3bbb9081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000552a248cf05063a0c015c9c50780c15aac8503fb97eabea39d919787d0b171aff25d4b54672cd77ad909030c28490d80000000000000000000000000000000019f07da6f9b45c81edd091024573a6d3d6a1d2213e48b3b8d14afeeeede3d8c594ef00f0a513435dd2e6b9be7df915381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010becb4288d7da4afeae7c38544bb4c24e739551b496efb156664ed85e5476e4a25ed5b82406281df62a82bf217d4690000000000000000000000000000000000d7acfa535482f9a996528f183167fe20a5aa8b8807efe26f031ecaba7df0cd4b6c580d55dc10dbb9b4667c57643bf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170e2c50f93455b0bb8dcbb204260a972c069578c826b18f7d582c241ad636cc8f239234dea1e2dd15d9c207d533890800000000000000000000000000000000007a2b7a9519f4f7a83145cf788276cb5f0d4d85a6dc40c920562ad3c55c8349c574cbfee66fe2a8d7d8e34c68cf757e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010859221a09529e649271a611dbe66e0757cdeac80ec9aab8c67ae2288de55164b548e53943d4d89adb6699a2c54fad0000000000000000000000000000000005ecf6b8f62e4979a204e3cbddbf61e541f414f097c68d4bc5f631bcf45399b2ddd5b42d327bc8af9d2f165dfa99f8491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cdc9d8182933d451f6c9c18e1cb4e3a751d0c8cc8bc48d5170370525319bcfe8cd0407fb5b67185d4854e2892352e60000000000000000000000000000000005fa283ceca6e0c8d5efea2b3ffe472473df97974c3ad4fa71c9f7065e67f2d99ea31d6df4ed6ae035e7ffa15583c32c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024efcdd1a52460fcc73fbb1129680875db0c803c99506500b72be4d1e174cd4bb9304ed977f4e421b33690e0d379c0900000000000000000000000000000000095a3da5274e6dfd84075ba4634079e92f51506a9b9c8468109d2ece6a6bc70ee2b23d290618b9755051e0c588b825e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001411f71c1e2cc1c13e7ae6019a3d3d388e8887c330620400cab7d27311c12e00e750311dd57df98d2273bd6a6434483a0000000000000000000000000000000011524602625fab1bff2163e8c604f4cbcf5b60030258eec26769892e1c5fabe3e85db8629dd01415b1286b057820bf6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8df76ffd22184b758f46543acf391431d495195bb6c2b075ba40d4c6600dc4f5e801a3176e690fdecf8bb229e0a57a000000000000000000000000000000000f36ada6593e8794e64e1fd92f3800efcba0890e4cd2d88ee0630a1dc5ee36414fb4f6a130ec000cfb83d3abee51f9341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006303067d821451b8486726356653adf804822e64b48c9f1e638b233609ecfa7de746666b3eaec579bb073a307dfbea20000000000000000000000000000000005963d626a69aaa6f223a0a37484b93570b4b48814cce7fec80cce1d53f3d0195e2cf5243e29d2c0aaebf90aa06b41fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008938e2462116b46660a554da49d142d91911594fafb3f59b8dfd4a2227c6b1740bf73017e9a9d924905c2127279d2fd00000000000000000000000000000000197af39dfdfc069a5b16ba0132ac0eef537eda857129afae5e734d14e7fba757c73c35da7a4235ba869e47b68d1496dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c053bd75501b53040c29f4011040f9b8a788d0d42e08693b34617d14c690f0a7120cecfd05f03277180ba9f8499b90000000000000000000000000000000017c68c5dd28027a224f5b154341dee627b7e6ba5fadbf7dc98c9856d6cbeb83dfc6a6787e65511ddcee8b67585cac9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de018041f374f1af7c62cc274302a993f68a19a4fadc802fe3b4a92b6b99f37092fefb1ecb1707a7934c2ca496de93b000000000000000000000000000000000f15b67bce44bcf7a9ecbef85a1dced3e97b40fef7cd2b50882575a1fbacceb2100b04bc0355e97670b91fe0e4633e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b616be1eff6bc9143ab0abe85cb2b570299d4c1043fbf81953b27bae9dec41724dccc021d5656949ff69ebb3f706090000000000000000000000000000000013f6c8e291c403409364f3c1b11341e2ea5f116382cfb5924bc990fb37eea8b216281c19baae9ba35b302fcf49904f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bd8db07495979ed877083dd762ce13b2c11fcf844a81568a7cbe5fe9d44924aa900608fd99dd3a4b1a6060e8d90a4a00000000000000000000000000000000119f344c29facb2f2c4f4935d306b35f21e06707040240ffb32ccb5edd957250f1d37602b709666a998be8d7f7a48f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fac986db92e9d773839f284ce6d375f6116c8c32cf9107bf0e06c15f8b9047f57662d5e7f48bd0214dd8ea026edbf400000000000000000000000000000000114e3b385de38f6a58b76921a6afcf3044853e9cc1d347bf2242568c29b4181dbdbf84173bb77a36132392af4f29fc1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000013c13e6b9cb5bbe9a8f57821b678c05f59e116fcdabb685efeaacdc1bb104070904957a92db532c1ae19c65feadb8d4e00000000000000000000000000000000016e21f441248197ab403faec9c697f2fce2f87a5fe9075d1fe7e692328b6432e76ab0f2110d60ddc2acd6f8a860d9ec", + "Name": "g1msm-128-jwasinger", + "Gas": 267264, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000009e91d6cfc75742ba2c1bed7bd1b2e1d74bd8d0f8732ee61ff502cb1932cfebee7fe27a8035f4b4d8ddf9cbd9dc66bd00000000000000000000000000000000005c4296ef1764dd57749d77934c658944b76cf80fba6ae676c600fb21fd984d31d1307eaf6bae8683c2c892667dccaa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f2550cd304ed573cce9425b7820918763e6e3c4be889bada5f91f8683493a38a8a3b0ff0d9762847ef148f2e701b8300000000000000000000000000000000125bcaf1a655a70f34598289f2740abc71a6483876f8da1bf3a9c4b43b09082fb759be3c87b181ae6115bd9c01a622d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fed071727d16baee9897951aa81bae719f71b3f5a57c3bf2ed1df6c0e8c9c231f5bf3493ecfdc43acd9b159794f84000000000000000000000000000000000f126d831e2690fe44dacb25bdbc0cfd77d4ea0e8381dc75ef2679ef8e11195ba5b44577ff2f67cf225b48e53a0c3e5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138723907e01c4b012ccd710b00cff2fba5d52893cbcbe834e746d05f064ddaca2ccb9999b81afb3a6212718d6698dba0000000000000000000000000000000005dfbbf4fd639819a752edd0c5967ae0e05685d6d2ae6dbe18a78fa55d50ddab4a6ef6ff63c1841058724605beda37231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7c519124cea54593174d156394310b62ff4685fc72c1462585e8e31c9d56fa566254cd52c92282564673e8c0c4121000000000000000000000000000000000628a202f598542565c9af22387fb1457d52507f21706cfc88ea0f40b03dd70a89b438a2d19ec8be6b2b111e4e0547791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9861b68e9d217d1358e9c41cf5aef75ab0a408c2e47a1de970ed5ea457f86df8bf0c655566fc774c6bc3b21301e511000000000000000000000000000000001258a0c3796ab0188c7dcf621e54242c3e71f9d1fa6a451aba365a9cd173980ddec7f722d89a4a6fce32190544443de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dadf1f558e5b846640b5e238a535e65e20d418498fa1d4ed128bbfb79b6b5798b8b07bef37b3af00856fb0fb839e0270000000000000000000000000000000000e864e2820c1fbe73e623d73c0dc7cfb90327988467f67089953d0ceb6ec488ee858555681423a02078523464bf95d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ac3fedc7a28efb1bdd48744f5f42d1560c61dce1b0c0e9ac0e1c9d890d17e046b6b3c49f7e888628cd29f25fe7174b00000000000000000000000000000000171dfd4e7b34aa68a59ce367a8514997dc0b96c1852f67ec42f40bdaeca3ceed7e6cc45aef4564dea85559765bae28391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001252f5eefb18b7d187ccd99c0911cd64383e2a8bae2853d15b8e823fe08205bd6e87f554408763d75e7cd4806e7e3e20000000000000000000000000000000000779dff3ca853e54e3575799631027f13f296d3f42615fe5ea479977d502dde4dc12c60a6f08dc08382d67d5bd45aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d041d30605eb13d447aa97f40a5ce5d074f843f9ca4276ad1f95dd6c52e83fd846f397629954f8698dc59309c6c6a90000000000000000000000000000000007b898357e809d714b251409ce9e5adcb866fccfd523c44d928c634aa22d54525578c6c69ab4b3d6d235df743a9309e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc8b2445687a1bfa41ccc6df117f00ce020190b8c889c57bbea26ede67309ab3ceb7d1503b928365d236450f85c188a00000000000000000000000000000000134ff7652eec202f0753f7c0150db6d2462e8d488131bb9f434bcf82de101c84beba6cf39471a44ab57de576d730d8e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100f4bc2d1d6f4757a130b6aaf0b83cf777dc06d64f10bc043cb66013e5a0984149ce4b00f7d15a6ae237e263cc8a4180000000000000000000000000000000006508e2ffcbb35e6d29a9ecb827a5dbd19cef07eae5c6e66c70d42642cafde65a731b9b00550d909f0e85932ca9064911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190b5af86dcb6ca6bf424073ff933630a45bc79c7aeb3bf5da575c5a83a0251819867f18aa2f7c2820aaca8a0a1c03e80000000000000000000000000000000010d50abf3a74c81ca45b594f4da4266b051470b1ccb3e2cffce8eb8dd0b942d543236137c760836462972a58859d9f3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088b48cd5839c058b812551c8599b1dbde06a949a49a79e64ae3feabc917694dd8d1eb62dd86167a60510ce224cbcb3100000000000000000000000000000000163989ed7bb5764e628ce7fcd0912adfd73eddb3e1d526605d3e6610d34e0d253d3b8de1311573fe6c0bdfae3e30b00a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e9b448477e778dcdcaa132618b9368838d6a81a22c5815c4ab934ee788ad8eef36cac638462f56ee221e379a71c90d0000000000000000000000000000000016fd8ff7347a7369b75f4ec3aa3b6d358d5152c6ad53f3fdb7413a2d15637703477f63fdc89decfbb301247bdd77ec2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078db71b1a7b706f51203efd009cc9839143d177c192d6ac3fbc19b7c95b23ea40b6256872627e711ec995490de387a6000000000000000000000000000000000017ea4b81ba7181c2cd7e8535273e029101f0985f6d90c5b617e85592b623550211993aef5561b05133707a7e9adc1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000589f057f21692c5c577937f0ae659d36afada2f3655bc86cf1e15eaf229ff8e8308911e60064466bde4db00531393e8000000000000000000000000000000000a1cda4ed81fd0de9757bd96dda3fe7fc07ab09259c41eb5fccc52bf1d85d9cd221a3e1d12aae7298c3bb00fd1db4d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013841fa47194fcb9d9961e35fc5d85b408e6e9de06903c881683fd9a7262a7f9c51b15f579f250b95eb8ae704d0564b20000000000000000000000000000000007a24683313dc89c732b5f04371e75626195614e24e31c7a52867d5d058314d994d14b3e47c584864c0ea83629384e6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744165930396c2bf8ee77fdbecdac747a8400ae0abe03d50b266a5dc7988dbed6aca4a89a6ffbae78bb2ee0beb8673e000000000000000000000000000000001823252d83f64681415d989219bf0e82b1cd449ff8a60feeb5d15a4bbf5452f9baf867941027f8821464c14f7d76292e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bb4ce1f9a6e32914b127765d49d9d1c288c3be7d7b9e4d690c1619f17c62295bf8957704d37f142b0a2ea100b9df2300000000000000000000000000000000063c4591e511c3ac10be9f26a7a15f687ac87efeeffae04c7e15089334650481be8fa8e57ec31fdbf7ebca11f85246d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b6cfaaee9fa077ed35e8ba86bc488719eb8066e84a4fd601a02bd95dbf7436938d58b04cad0ff84749d146bd44218500000000000000000000000000000000014732f98ed3595c4b60a1c485dba08e25f39eaed65ff7b1223d0e6dab1083c6e9588c047c25236358e9f9b3ca761da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001426461fb0f88e1fcbfed8d7cd373f5f687c168ca399b24ca867c071ec8b0080e96aa1a8c1b7729c8d1fc500457910fb0000000000000000000000000000000017d4db9f60f8aaa3e698e9823da9e4bc2c7841542c57a7f26e0f93895e32ad6dbc2faef86adb5282b75c9b75f03ad7911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b155c539c4a6d40bda83aa233244875903c1eec61626860d1bd3392694e19cde9ceba9b80dffb498dab14159571afbf00000000000000000000000000000000051c52b7c12f17933a874393a27353e7781df4e068418992ee61b443be8c270fde69422e8321852a5753f41696f22ce51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001049fc11ffdb03a018ae2b2476cb0c0b889ff9e452e85b9a130ae52ccc57b94bded9c1128795d84c94ed918ed2b927750000000000000000000000000000000001efd8d005b6e2f64cab828593bcffbd55753cc209260d2f41b107ea459f8bf372c513764779b1546a5e0613ff11f4e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134c338761e6f79bc1d912cb1652ed65c6ff29eaca2e214fb6dce1239e40a233942e5daf0bfc4b5e7d4fd1e3f20d9c7e0000000000000000000000000000000002ec9a93bac0d60d03f9d29263048e2be9d8a1b56eee06c8cb7b7adaf5b9db61d48b0a27c2c1be590153551b99cebb341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000172427716505553f3bf0430b64ee829456817c64d036ed4a4d6f3055d4f54b50ba8c5d2bb87238ed6f9a847f0a32da000000000000000000000000000000001044a6b14a66e8266532ebc762e9edbb8f5b2113181fd33f00cf6d97017f42371b5598c02b9eff08dd08a9bb3ae5a6a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b9d55641b649f11ebd12f153d8ee5af82df5f939058a866e958fae0de8befac11e5969785f0d0f2404de1f1337145d0000000000000000000000000000000017db484714aaffd8cc49d547bcc1ea4438fda09d77ceb7fb42c42703fcc7e1f16b27d135fcea829daa9c74865009bedd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000985d307e840645bac5b58e5f614891c9cb6296119c335c1918c3680832ba69d493aca926396329b63856d03d2cdea6f0000000000000000000000000000000013a5918387c44eb0101bd86ce8f1f44fd6c552556f4f94102a7227789d2c120231f39bfb283c079d3b0493fbdc13611d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ae382ca7523572548e370d3072d6ae39f3945f9052bf46a9de76d0d5301617362a0e61ab4ba1974a0df24392d23fa000000000000000000000000000000001263bcc1efb1141245a563ed76d89b3ed3f9246e591514a7af74d7214f82b2f6ab13e3f884dceba86eca834b268a3dc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cf8961be344c7939173095767d5ed54add1572d9be6e18532812611a09703d1a99337c23dd6270974b3a97c1ab7a69000000000000000000000000000000000cb443b5ac9a02b1d9a9b7a971e79b6961cded1d8ae0f8f3a37453d4f57fcee0d560a8cd2cc4a79f62c13074659f8c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001155c09875543a5ca4c7bb05523d6d34f85e0b8f2c72de18379a975b4558b32046442d32491216438773d90b0352595d000000000000000000000000000000000c02d4870f3666e397e85c88d5c17cec476a5d2d0bc179304098d205497483d2d6bd6b5c442e6abb4b7d3115cec54fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f00e5cc6c6659d6bcceccc6bc0a824718f60419533aa3cc626e7e70a005835aa93aa96ed318e8ae5176344629ae9bb0000000000000000000000000000000016fd2f037f3b8ceb958eddd6e1833f154a342c8d6cdc14218ad061a3e73868297b3c9f7c5fdcc3b99da21769608c18511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b783dff1da396ba3b17dad3787f6cf91a56e8e34f5a9c793ee8b55c099c78a68136fd966c3fba8668e1de4d316f1d260000000000000000000000000000000000684bdb5866218f60934245d4bbb1945e878c29bbecc830f9093e5695c67b478ee2a3fd16dab7939cdd77573d2b73d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101d19965c84f1e7ff7fa1082adaeab41b4c879b480c0484f097a41c89201f8f02b1bd7401bae55b871985cbe48a40fd0000000000000000000000000000000016440681fd6d81c2ed2c3a333f41a0d983619e1d490b90e5ab6db5cf5bd2f2cf8d0b278b1d164866beb853b8ca8bf61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d80a542c3ee056786b8ffe8066faf0959af6fc3339e38d76fd0063f3e7862b564d78219b155e6b6d5f310684884cdb50000000000000000000000000000000006d5e88101dc1e8be177becfa5c4b3427da20ed50c9d4ddbb1fa9113a486faa15ced7709a5054f3de3c1716dfa914b881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b8f138c21aa6b5ca9514102c54f4021c3709d74bbd59d1c88cdb6059008fec4793a29ef1f30ad1c0ad36f47a97282f00000000000000000000000000000000170f6b9e271aa35ffc57fbece080ae75098b177acd930446437207e3566273dfb457a51a7eeaceec7abd488526db0f421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189bb1f7b1cf6c26ab48ac23f362c329612e9a074a587def8629f45da18382965088bd5b55a46920cb786927278c014500000000000000000000000000000000068cea32498385a2ab424d187defada8e94719cbc4926e4a307615c4271f05e62704e3fc9f4337f7ef3d83792c0d9bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000131b7a928e347568173f9b4cef4f10991eacb9ad791e75867675d94a94fd095ae99f858be426eebeb3a415a116697e6000000000000000000000000000000000290db9c7336c8d0c114f8de9a3bfedf3ee5d3042ec4c719a72e0122e4adda819fe45d098ec5c3ce1532870ae8f68fbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000682500c65bcf7f4451eaa59335ba78160a2aa6e9335008ecc9ab776e08b25077a9ab5ded4dfc6657fc40e0ab1cde480000000000000000000000000000000000f003e7660f0533b3744d4bc59fa491b31a094ee090283c8d863b2580b668ef40a377b91f9826cc6775248a13a804fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067790cac3713008068ab6fa8e36347148196a9c913368c19f4ae1a110ba0c7a3dedfb7b281b94b36ab9876a3cd5f86900000000000000000000000000000000128b14f59bbd97765419f8e983b6a8c43d9f8561d3f2acf31f0ec9cbe350747cd5cb13040bfdc0b576e6bd5f2f7c2adf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a38c9802cfc7764058ff6f64d45a44c05bf7d66346b8fc300141b1096d574ab3515dc28ff7a410b65f03808fa557fd0000000000000000000000000000000015d0735380fb31d9883cfa3c2d225fa8c7b36b88b980398020c4e44759d3c8ab7749ecc0161051bfb1845eb0562c3cba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e8ca088354bb2ca19d8f0ff18c5cffe5aaa61eb1c61c9afd5c73b1b88dc5f1dfb5bb2f4a2fe0bda7de383b55f569880000000000000000000000000000000009f511e563ec35a9c8f1f6a09d0b4a7404bdddb2dff4f8b3522f142225df634469c7a706097eb3855397c87644d32aa01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162bd802812dbf581d49cd75c8ffc30faff693a792834b5a1a901ce899dedd211e0a21935b26f662675c59152e7ba67d00000000000000000000000000000000173e40ed1645f7288d3ca0767f335f6228583bf09f5ad7da0d76842eac241bb677cd2d01d5aa3e3630d72d4bc0ffff3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010191a0f57724e25482ad1fdeeddfd7e0404ba39538663f115d9e3d26d350a7746dade59fe4ce2cdc883b4f0004ad349000000000000000000000000000000000a72eb26c7f19b209b986421a9e82b8a47e748161422a5eaf49b87da3b1fb221b54bc3273354a7c4946ed17713468b0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0d1ee22c23e348be331c852852e77dc0aa9f5b7c829bee1106791759db9b91087939b0b9393d712998398428faff51000000000000000000000000000000000868983a94cd482c1b84b6904097feac74ea18b420594fac6a9d3894085b6051842329350fcb5516d385312e56d61a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001223b25cf7734f8d041905fb1f714757f3981773a03e189d764ab41dfa6facf6ae82ab98df35c1ac77ada5e32334021d0000000000000000000000000000000006dc5a1632c0e24ab4e16efac750d87672c3846c37cbe6e4ea74f1b4a0513dabd08f7d8f01047e08c4276576c1d801741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007feb788422b265fb997e56e1f64bb8162fbf8950cefee37544ef79ed398af1fad1a71fd2145706643f4f82f8700dad800000000000000000000000000000000082748b4ddca00adf83111a93bbded0284312341e9eadcf1d233c2b921b6bd6b7aa9187d986d013c39c1942bc23f13141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000166489e72e8e55373581aa648485e09ef4f5251630e64af1bbb0d8d47617bb9c9a08795b1e0a0010a8cef03590138200000000000000000000000000000000003cb8347d3a9245101b75267ad1abecc416ec9bfff9b536d44c39b81935e51f7bff88c4d974a8056acf99d1eafe4cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aab686c94471a8db9f7d2d67e11a6d858a09f8370f2198e894d1178eac284f5ee9dcbd77b3b122fed710aac970cb880000000000000000000000000000000018a37b5f7a124154eeffa6489ade64ea2f0844c276cd61706c5f248332c47894d6056fef6f54a66154ebbfe443a143181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138fab32ef71f9428cec3b459d351666b45b719a3c69cab80e9cacd3d74b2fb8d210c8e981bf490e3cd95d2a3c06fec600000000000000000000000000000000003b098b2bf3c7b6465d7ed84ff6d5ed1c6635999cdabae2f0ee816c0d651e510b65733ddffeb78c0e44ad3895f3aa931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017648a870c8d525abefc2146761ef7d9c97cc8f3c63e47072b328d0a9f03e48b1e0b6c77fed044ae2b59d39d63f937a2000000000000000000000000000000000762dd6b582b7e7bd71e7bc972c6d2b8f4a5516f5550d169b27ebef3e5413c3fe71a28cfdd7ebd8ea5d4081eb55740dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c727d1f1bb3c7724277575249899a3075a260bb9c442c875c3b0077e46af3a8aa178da36688072405e2dc2c5a1ac46000000000000000000000000000000001831f3faa4c7c8af825d3cb641b48eba66d60b18f7c56cca205687b85d6e5c87671ac7aa90d5dda24d41fbb87be76ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ed006f031224a211e9638fdab167e15b07ff493d9664570b0ecbac8685a99d713b6359241c0ceed42b16af168df4d300000000000000000000000000000000071404ba9bda8b8e48c54e491dec70794f4c15ba10552dc5fd691e8e67331f9b3285c9077fb97c81670343b7075fba0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b378dba3b5f1271cc51704d521240c9583530268aea0b9f862743085f92ec83b0863bf82ac0598cb2d8f58dcb6745d000000000000000000000000000000001242ce81924702eb9eeb37e50f08e2ae7caf7c34f376e7f14a598cff213415a0441be85c1201d44eca49ddbf000f27481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000656148f8b4f7848f834db3301e155707f19291e62abdc5fdf4931e79e9fff47ea2ec403529df90fca61af9887572ef800000000000000000000000000000000153b4f19741d3f26370c91303bf8f72cc193d3cdcff1a86456f85b9e7b2f5f9366330800d75eb67f5ad3ce00c14aa9241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001901b7685794ad4351707a127afefdca84b240946f9fd1a3c60f243ae91f4f843500909162cbac7feb55c458dc555bcc000000000000000000000000000000000e61f077b23f1545213b807a2f9724b8629761679a34b1d849dee689eec6696f2662f42fa2afd27d5cee29db94fd3e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113ad30041d07a664a93f37399f6516b4773036dbbfb0a2cc82913c14e24b383420bb6e5ebed40e5c86d6a130bdc888b00000000000000000000000000000000197b767c92016117ba3482f1ff8a81ad026820b0bc611056e7b544b10960854516c2c1318de7246315bdbd3d3fc6c7661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000467f63c0011b8e92f1400ada3befa7430e28f2c29ce35f4c7413cdd48181f52cba3aa7dda9de98bfc59b77a02a5d50e000000000000000000000000000000000ee287651052d39cbd1372f9560eef6642693f0217f456d031541f015d0a102ebefadb41609ba29944eea3a7ecb5ebc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027059f3dd2f80f90e5dbd27b45b4adea8eb149682b94fe3e2547dc40b85a8360af82a4d1e86ad1bd93fbfb39e20635b000000000000000000000000000000000e8582313e868c6f0b57490642b467b8c6473671bf297109b142888ad5a5b287cdcb6358112b3f7b3988ceecc51b90e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013aaf6c3889b8e92d8036da2b5b07c2fe17c1c734c85ba70641376d3dae4bcf417eaaea297ee7abf267c705a5ea0bc81000000000000000000000000000000000a3ca51551316a126347d657c2e116554fa28cd514910602bcc5a771695541a011c2dc3312b71a96a2d92ce649804fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1200e27a7198fc6801d9fbd9359150371746857539c69b53983bb90f9a5baf585ed1d6077184539ba35ea8255874d2000000000000000000000000000000000f6892ecdaa1f947a1b7f69ec7a56bb2107819f55a3ec20eb6d4315320e9c89885c6dbfe2e62cf57c57d08d1cb04a4af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07661283e5f7bc46bbd0a62153c5a355cf6e36050f09274d63efa3fbc2d24ff35d0919dd207125ee90f478486936aa00000000000000000000000000000000193568e74edf17b8acb42db4e2359008a044db8b145ae2d133fdcb647b8789e15bc06132b45bffe9a89e914ee5a60fec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd73b4183807ad1cdde370578fa1f70e935350cbc06c98762fad895f22df060e153fcd4dd1186e059b7b14b4798c32d0000000000000000000000000000000018c38b1c4de20cc4d8dd686b2ef25ac9b62f107502827b56ef8b7131e9e57d527b64401d4c9acd52900ed534f690c9a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e0c4ae387a97f1460a893ab362d5300de0ec4190aefacc483670bc7bad31008a2fe995577ce1287bcdf6315698433b0000000000000000000000000000000006f75e65370f74aa194d3b9905c5f5428ecef8387df4f4378860544bd02b6a877a7d51df850e5c75979a6be2100981331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb03782c6a8589ec033f0f74cc7bad4317da68921653d20451dba406130d217bad9faaac6adfc64edff73ef8a579e4000000000000000000000000000000000cda4d57e4c183a95f2a0b3299d12b88a939470fff0a03ab7033082c8afd35fbb0890a7653cf96b7b983fca088793f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e5d564b830effaf39ae666299c542d06bb6701f69126bb1c85264f74d41075ca23598aa2205326334fde7fb8fae953000000000000000000000000000000001008e41b7f47086b0277166992df928c6498de3d548e571237f6bec053b3b15de9d0a4ed6ae9275213c08f5446dc87581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aeb74bf5e5104d6e2785fbd1bcd4f192787a9761532dfb9e8cad3bb8b04f2b09c2d233eab3ace0ba1df92004008c110000000000000000000000000000000005bfdb99c712072015815f981a9e29b7ecb7acd5a061737e12e10d57b5e8ce0a796ae021712052cbc699223850fccb2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c32a2e242c3a4e18449be4394e59241d2e784b2e55198f43642ed6b8f8a23e26c1d3197635e8f00b6073938a047960000000000000000000000000000000000c01a1b4ec8494307a17e3567d230d36dee3e824e30cba162c6dd4803c1f941d001d85b5e75697b185b03fc4ec6c37821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017588178a37f6eac01ead62ebaff0bd219a1e3fdbf51a2b5556fadd86653aa7f9c20cfdd3fc0eaf56e7cdb59bf97b3840000000000000000000000000000000017f4024bed03b7d4d146c06e50e934cc81d17cc11dd2116d90605f41c701491e1d0fedb1a7046e4b918a21139825e6381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001585caef47bec8382370f3cf4527cb89de18e8b7c693485024327bc612618ffa4531a9763244ab59a6538e07ecc7ff1b000000000000000000000000000000000693ff60ef41293e240bcb150de728c92f00ebb70f17ecbcd37c217bfb5b0c61c2a5679642503043d9056952d7ae77c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8805156f94bbc6ecc9095b450826efcca05dc9422becc6d3bef10c0edc9b6e0244743b335dc2fdb830f299a541f26700000000000000000000000000000000028ee1854c89f84df27e7c74ff917d34b8473085d61c5f185d07b7f320aeaadd632731bf8f4d83a9ed07938d29b69e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa106ab9ff11259d25d00557e15e8987d1bd4cdf7a17cce12311d4925693338ff7aa15573b2959f88cf2ed911d78bf000000000000000000000000000000000f89215340f7fa3f6f42c0d7e290849a9c158cd43644379f79960333d5ae03f7e5a30a0106213285780754089c6e36311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d681a270017d3ae542fd2ffc0c157b0c9046af7180b795700c574fb66baff68024d7a0eab053637acf586e7a51e80e0000000000000000000000000000000016d67eed2c7d4c046c7ae8cef0e9fd875bdbf101515f944debef95982308ea619b499dca3e12e04703c2dc94e2adc38e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001edb72c70e852924006367e7454396fd4493037bdafa1b090e450ca5fabf708ea0bc867d80282e5f40f3ed577bd4214000000000000000000000000000000000ce8e5dba23232af6a5455b99e484362146e69621896970872f20fc4d02da46b257c6869bd94f7c031e7351c67c392d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011c39127ae09aed33f7d0897ab27f707c3dfdfb5e90b53d742b29b9c710e7bd1daad7cad25622c7d07cd3b3ea1db7f00000000000000000000000000000000134574d668e065a1a82904c6090c164f9aa4d13e142e3c1d9c3668af9270b5510d0a547c07d6b4fd464bad3d1168f3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebc39442324f7b48f459cb3b2e66445b2a226733fcf4c15a3457ced4a86f721a24c6a0b971df9ee533f5b5e553bc0b20000000000000000000000000000000006a30bdda08dc53b031124a62e383fbb4759d4668485fa6d91c47f3c2b50ef168c4b31817eacd76be45537d46fd3a8bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e9b39f1c875a07d8ca33b078f5856ce6e5071ce26894f41bb80c06d4a71a2613ef6d634e40e0fae4c215a2681f2e5e00000000000000000000000000000000133ba2c86f4b4d11d3d507b7f370d0ee2a11ba47b9267df59f0698e6ea76e73e689b71af427a0347924419c4f05b25d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037856112dc4b0a244c6a298c403fddda9b0173f0aa1861a3a9aa04abcec060992a7fd9aa0a228eb00a29fb0cb79180a000000000000000000000000000000000689b620566eb37b2319df8fdfc3350dec0c56161600846bbfce06743241d3d37ad2c6794c1ac19bad79d8d84abdeed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001844610b6fb106496ef4dd43e4ec4eeff22f2757fabaafc8966fbba3c4adaed6674bea91320c6b29110fe317d40f584d00000000000000000000000000000000151da3c678af1721a174b4878fd3a3b25967dd07d571e7cb439a1fc766642224dbc5081581e12371b9e80040597221091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134911f593df132195f912cf634092cdf7dcf8db33f403f653569fdda145cda1ed48ed545468e23f9c4b6e250b3b7bb300000000000000000000000000000000151a6789bfc6aa3deeb773d8d0a342c19b9e3f72099e1503f37e62fc2482ea63fe39d552f619d7d7287f590e5c3c6e4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3fc0e7918853f0106fcc67e742f54b8f249d7ce45742fcad227cb01b977e014aae58cebe0ac9cd89ef1bfaef338480000000000000000000000000000000005d5d5be7c52ceeda68021c0f6b7410612ede7b731341a18871ac6972893feabda9e5bbe29fde430d4725d2578d449781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc0a2f033a91122c220085f1bb44ab0138e4c4bc39ad9d38309d54dd6f50a0d8e343d74fcf628a661d06568e75b589e000000000000000000000000000000000ea46bd9b4bbc286d7215a1ca0ea49d94dcd0fd69b85e4d1e9aac182149f763359f0fc8e889cfaedcf5c2a6ba00ab25b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ede6ad68613e8bd24c34cdc265f4206f5f75de1ae85bd3b1ff521b73b644b41cbad32175d2a6ec923cbfb15352abfa00000000000000000000000000000000006a85d15436b6889ddb7724f1efe8440c7336e5e3e13992a8ae3ada9982bfd1d80ad580f3f39f5fae55398af07444b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000798a6499923ad1447fb8bec3ea6a63216528e8c5f8726b7f20758813b9324f05fbc01589aeab9dc3ea4f256f1ac477100000000000000000000000000000000167b40122cb049b1e7c783c895264998ede8a17d6fa8e9105370e46eaddadbe0fd813a16a84b8002ac6f49b2c3b3e1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e02fcfebe7190e8d960b7cbe5be85ab0b35577693a472596d6cf292165d93fba7152253e793b889f13ce2c0c40c54400000000000000000000000000000000084386f7af138fe752f87f7ab47b2165bbb4d2d0db2a510aa2da3fe1408fe3c114cfaa3b13b0d25801b80ba923fe2acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156a9db98a271ca9ef8bb182ccbbc031f2b3ba131113afa156f13552e18dad4729085e2574ec16af08a4a01a954558970000000000000000000000000000000018fbbcb500f76b24f65d7a630f6a1137eb1d46491fc6af58a55f6b75383c32eb9fc36da9cd22e3f3aa10f1c417b3f8001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008f82f7c8a4bbb0ba25233155b75d9995beb83f4ffb38e44c7d70155bb7146fe76c504ed453ecf046d97b16a44fde57000000000000000000000000000000000562c7d0f57594c5a73cd0deaa26e82a3ff423d91f1417d6fa8705fdd9f19d940c1dabf497aa775991d54471bd1204ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f593e0c2882addc1e8498b09749ff401643d598515d0919541aa6b5696d19e9cec1461f9cec06f957be1848cd38b110000000000000000000000000000000011cd8c5c2291772d441bbaa70bd58f5664cb7d6a64434dfaf2309de9c56711e5063d3049c3789a590f035b079d01d7551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a09625d73df67266afa74cc90fd328f43ba2edad08371116e84c6c0c79572f2fc6f067199b11fb82ffed501e3498110000000000000000000000000000000009880126bda0918142c283ea98438053d5bdbe175286e939edf84b18906a49f7cc39af1219909a5ba4f5262a8a9e3d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c24190dd4545c6cef2bb30d727df22ecdfdcde2af4feac2d3ee3968330feb5cbd65d4d430482858fd83df53adeb16c0000000000000000000000000000000017edb16ba089e0ff5084ad0c52836ab72c47d77a3deac4884ae547e935a8c779a0073c3654af4c22b0e63e20e7a7b57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d96e767c8cfcb000c12090eb162f83a2f7e006415464a394e5b91475ccfe6a69edab8fff8c91b574b93b07f585e4c12000000000000000000000000000000000b3962482d347c58ec93213633fc413298d3fc47bb290f444b051b6834fa5a733a1bad042b80a7af9832f7471c1c20101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca82c9e56f2f6f72a52b0f9d1c7d9168c5ee97a56d6c82f0eb8e68fd2ebc6464a766500b10acffd541cbbf03863bdb000000000000000000000000000000000ab27d0f3e6b802cb661208c5b9a425634ed9e66803435f9698877d15ee596037160304dfb039dfafe564a76e70fb2761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c11ee4e540b3874a10248903e0da0110eea5fb015c7b22d2053178603dfb6c1249243b474a8c4c5f26dbadbc1553d8f0000000000000000000000000000000015fe4b9ada79296a22d4493919545e5046bf8b95d5a7bdd9a7467f4b4bf723e6c1c64532a4af71d5875c571e9bf0e1f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d85ddb3a738882b83e9508f6a80ea6e97cb995de4d8268d4ece1b6654f6418f447581284f7c22a65ebc66612d47ab7000000000000000000000000000000001387fb103f138d93634c63dec396de6375588d90efc363920129f330ff9c551c435150d00c1386271bb7f72c18c7306e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181508666b83acabb89741ac11762f15af5ff8cca96d3abc5282dd39b8db86be17834b953e66b573ff06b4469321b4b70000000000000000000000000000000009555fc937513fb6395ba881acb3b78e34478d3c058bdc706275c61af6c3711fda5a6005d2965779ed3d5cab7d60f90d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092b32dfb73577b4f52b257b54206811c107697413b7e83398ad4dda90679f262287894c1253abbb1dc362d1d7686473000000000000000000000000000000000594c991cf66afa425315cd658edf27c7d7816638b4391dc01fab3eb38bb5d0e3cef6000c54787507dff64ec226572241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b26a967489f03de80bf04086b9be036100a041a5e093ad4aa80ca24f4690694f42820b54e323b25b5e93b9c2486b1aa0000000000000000000000000000000001b76905be5e662f6b795044e45af7b094589f7de99c24846d69d5cca8f6bdfe35227e0723e736c1859c4618b73441eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f15b3d211d6d0594334d1db06dbd9ed7beffb0268caa64b231a91ebb7c9ca6bc71bd4498d374ea3e9b4bfb8865ab86b000000000000000000000000000000000572946fd085340dae2f378cd4bee414c7bc1f11c30ee6c4b63a69420ff678dfb0b488443d1e8184837ae5fe7d8a1dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec8b3d38331169d99f81f65c1e2821c7522adbc32c2729a4f3e83ebd6865c28118af90ed60be466d69640023bdf8e740000000000000000000000000000000019051e0ec7f090dc5b6dfb57801bf903c607df52b07f47522e3e6ad03d94e0b162a6034288208952d267c2bd38ea70b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eaa40c604a22d37581efa475dd09a71a172659e452ffc14cc9a7bc3d7bb59016b53251c81cf4633d2f8fe1be62ae4180000000000000000000000000000000013a0332d3e348dd4d5706f32601dd82b8e26dfba93ce15a7b90ed622eec5d619cc6173f8a76ac9bfeb8e050c981220c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb8d1fd3f6f5b8f6f8ce288fc0e0d7fd5a9374fc661e2079d6a07b90c15fb52eaa36f24d4b9f5c3ae03eb8b1c1dd8a7000000000000000000000000000000000c851f5df50f57f4055f08a3a97deac8fad3344d3663b43dcab596021a760708dba708b7e258b4641df87541129a58641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d446058be2a0e92c604bf9b27192fdd50bbb405ef6684a477c586ca9ec2a1de7ec1bbd0326fd589a0f9c697ccf93c00000000000000000000000000000000089486826506cf258ede79bc85ed0db995d76bf45ba1e01091848f2743a5e76e67a6b09abedc8a497fa462dbac8cabdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eccd6fa7e83efa3db93ac826a142bc85d86ec367950fb3e5f286fe9eac01ed557b7d3ec36ced2458aa01869f5c309c70000000000000000000000000000000014bf5d4e4f018e21311c0e8d61c6e77e4ff6d5cad68d5707ebc18ff43f411ea8b9e9d5629fea1479802da5f516c6ecfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a80d98ab896e559b1046a518656d0704369ae5b04d8ebc55e17d49a5b9b7a8f6c878229eb52dcf586f0ea7377008c200000000000000000000000000000000158654d92027a1a6ead8d74219112a346777110798967a12015cf838416e08ba90b056274eec7c9bf1de40756b3b42681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5380bd320f492115e48dee6a4a1aaf0e5eb9d9755cbdee02b8a791967996c7e2f61e0cb6eb11d109d8f4601e618192000000000000000000000000000000000b2acd51c6f3ba9ade467f04b015f17a2fe63a1df79dd5eb32c3d35b76b6291cb0acdff95ee7970ce0e3623d7b6ec6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f96d190da3b9d64ff4735ed1ec18d80b3db9bbf85879c7b432cdd2637e02f8032a4c435ff8e8323f2d9f7dcf855170000000000000000000000000000000001dccc8cb1ddcb6ead0fc2a7dd69c4005d7cdbac3cc3f4f9fea2172ca467d34b84890deb6f59da16d99f1495990184c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e98a0734523be174a7ead24fb00f4744b78ccf25adb781971f6223e836b626277b1b9f790e629ed9178d27b3fa5068000000000000000000000000000000000fc7be82199fc6bb2dd1acf882fc00b56542feced159f730f6632516c8c7ece4280e348cd8272a7879362d2be47fbd161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019afd9b0ea8b91a45e5388f0d1aa93472821ba188fcb0d9c1f125e7b2cafe63e7e0b112215028f5a39a6d452637e488100000000000000000000000000000000171a2569a6fc48ece55589cfed029488f2647c92ccb04dc5e7aae7827ef9dd59340a5b995211724b1bffbd619cb5af6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7aca785258feeb285f7b021c68ac1a299d7f10ffc7cb359e9c85e5af932ed48c648f1f03d8cc33a118f0cb413dc0ca0000000000000000000000000000000012910f68f47db2011616e4866c719fddd5b97a6d04b5bca4d6e8d0f545341841b84e670fa4cef62e51f34ba1566c6c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1f1985de79d9e60079d346b872c0ae9e6f76cbb4605ca0d02caf18e5f7964e7422bb4a57c46c628a859f4f9653ce0f0000000000000000000000000000000006d6a2689eb289deb65ca2c88f0fe51cd51a41959c020c5e1c64c1c11850f0734b53618b7f155b2a1c7e9ddd9111da201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d7b8526d7ad427f5aeb8ffbc9e25de927dea01502616390bd06b2685f0378fd4f2aba941adbb4a1339dbda0d82c59f0000000000000000000000000000000014e51b572a0eda530b7e2aa53d0454e88035bb3aa7ca5ab090ff6ae5fad10d619830b187280a991b56302d856832bca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007789c79653451e1715387a738d404353b592acf2ad0c23acee0ec3c533e540b0d60d040b1128e14c64500bb1fd4cf4900000000000000000000000000000000187bb42e981bfd0226b2801fce153ddeb1f658e907cb2422e823ddc8a00db6b7268ab3f497cd67def249c8eec8ce320a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ab44bf22f599738327f737006b3b1877f159ac4fac6cd480dc29785cf9eea6b5076c55dd91fbae5fe019f9fb8bc8c500000000000000000000000000000000153ba01b478d567b660801e6d66fd398c4eb8c74bb65463f3656b13a992a4f1aba52b182c0f4a2c58472e3f92afd14131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c2a9474ecbf5cc2b71588a0c8ff094e3b836f4ea5bab6d7f251c81af4807cec7e595e024284c02bb574f6322551c05000000000000000000000000000000001203298828d31c25f888bf668c76808598f3b1c4941be00e6f253e991230ec662758211a2d72b86680c11174b28a520d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f908c98755408879e791c2137f8f62043ef77ec6d7d71146ba02765b23bfa9728442285d12abeb7e6a29bf1ece0bd2a0000000000000000000000000000000013742633c217a5b4d9167dbcc210def68a400de6832ec3ef87196ffc028cd3c14a66d769c628cbb28b3c23be6d9d64421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbcc5fb48b3eaf70e6f90b9bb8e532c5eff028098aa79f407b55fae65aa91f211eefba01f8bcd7cd7bf995203d9b9c0000000000000000000000000000000018139425d3aba0e05d60d1760a20653493d57b8e177790277b61f13402171bb071fbce50fe10591a342ff123c26d14ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015764e6a821042564779edd5ccf7d11313ed0c5d0c51ab2fd0f082e70bf0a2e4ad4e9d65b1762abaa12da11e8948948d00000000000000000000000000000000089b78c1fe03dd5996cde45a42d32af12065a2c4087c84c812297110ce2efc99c2836c573fb300419cc39efdae55cc6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017579f63003742ebd584f6d8b64ce072b59ed4936a291bb420c74e8cb2e1ee4fd57b040dfcf21e5523a50bb67bc71cde000000000000000000000000000000000019568d1ced5e3e2ac1dddb66efbe06f6e601992e58ece451c8017d39c7cb22909a3be5eb53d046945b938572be63921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025fed6d4aefe93b807feb052e309c16a6c2abdb6f262c5b2edc9112a3daf93c1a449a411eba9252bc620c7cce432b680000000000000000000000000000000003470cb64c67c80543a5fde913a4cfad791dcba741b979424ca99a3eae67c3613ec96daf181867b67c9f67f8f32c05a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b71f61cf73e7dedc1f9eb4539c5dcfd9e7e6e9c8febb07f1dd41c02a7c3621c9bf16a7d500b0e564e7c154cb4a1f050000000000000000000000000000000003e65d6184fcbceab8cd2de4869d11c00e3f3be844cc4fcce2e1afbb37ea9386d313c765be5fe64d212e5410ca6c607f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0aad176008af80ebe2f7150272cb41d04e177c47d4e19449b18f3eac7c7e8c73f12640d8d65c124685e9c68ebd798a0000000000000000000000000000000016e9c506189b410a7129fd3b09cbadbbaf1365fc79735c5a92fc23a34d0893d724486f7fb77fa42ccf1fbfe5d3a00de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e2a8e7f9662bec69014bac4a244d59a48767d2ec18cfdabde96434ca603ba57b16aa687088968ee4a5413824371ca3000000000000000000000000000000000c7e6a5d43abd9b79b84ba78adb287a1e056c498504aabbf948b945c02091a5ee68c9178eaaf9214593c7a3b97ce0b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014679cb7fee2ebd76e64fdd7de0791c60e02569863ae41face922d3d8c05b3ebb8687da928b2a7c73de5ff36b97183b2000000000000000000000000000000000111001c8c56e9c335154be11f802c0f5ea176ffc180101b79b89870099b3778fb618d0b7cb96f3ef2f55f2c08a58c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018141e0e1c276f1b92e6fc3957d673da2e9ac4c4e92f3e6b2cb9e1b64c0a76505b9862b2680174670500fcbb2a4c7a2400000000000000000000000000000000076914dc9b5d9ec395640b1741631481888b112f4ef3ec79f684b2433c4f6b647f113c88647b7843c6c58399e9bd5c001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb18db0c3d7144b5d0239d5f060fc887d07d2402ebab13e25a46e1133396a2db2a3280f4d1c84e38767d5fdc9dc7dc0000000000000000000000000000000000df7d934afa2022b314eb5a9f31d6e817f52e86c7e6b2db809461b58688ed708e48eea6ad318cd0de67d84c1a44f5b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168102b01882931a3448d717fb1d9d8c0a9f218925b01c07b2088fb47cecf02aa95cde3c0f4a6e0b0a83a42915ea41950000000000000000000000000000000015441cc6399728b1dfe1f484394db8711eca75e3655913c92ccd0c3c14487945c57064310928f1bc9aabf0fddd37d9151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001092b458bb934149b213aaaa6cd72eab830b35044e580e14e20c2fed88b06aff58fbb7d99a7b8cf7a4f6f2162278c052000000000000000000000000000000001903143fd8bde295029b371c542255c693e05ec80918d5e1f997094ac3dadcb4803206d9ec40d3dae8b46ed368a43a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047fa31f0fc59feeef84339be0561ab52752ce5efdd893c0a33be5cd3fdb52e0875a6601cc7964969f639d9c217cc46b000000000000000000000000000000000708d187264a0f1866e979dd55a155a10bf171942be62e694fd8f2aa50724bb823e92fdd2a75e5b83d717bdb96a0ec001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010caeb4597bf90ba9e2c13ebc32dfbe6d373996c403104a0cca3da1b1b87e4279d8c4f0bbbccee63b78148f0e2a427660000000000000000000000000000000007840b5d1a03e8ad1fc44f2782ff1194f7ebf173b58d552cd128de5a626a24328c8f03f46c258d04f84b1cf89eff4c0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014878d019d48a83d4a0f69243eaa23698ea5baeacc6d4c0b80d2400f8c3f21f5e68ede1977073bc89f4ca622ee931a2c000000000000000000000000000000001435052d32dc50fd25d648222e9b267b75159b86c5d3eb63e13694cf57510ff8b4c646863751c3f642c4fdfd206bd6c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd35d2c78d784ccc29676a19894739f1911eb6f3438983fe2fd93dd05aff84323129fb293a907369d8a82a9acf82680000000000000000000000000000000011b313a5324e291ecd13e2ed9e34eb97ccfeac01b0fc9f18281960884112d213bb24883800e75b34e8d5a9bca85f16a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083117d9e2d123b55826dac06c97ae4270050f712195533b82bf817aa9b23f060f6799b029823470bac09f55dc42a33e0000000000000000000000000000000004451ddc9eebdfcac9f32406b25822c0e506490298822cacde77258329c76c792c1d7833bf8bcdc7c0b386cd5ba553731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ca66b676a7e7e2ecc63a4a183ddad788fb26516d7f87d8addef08ccce61a67894bc361000b9e4490597940aad3a3bd0000000000000000000000000000000006df0d1b077b7cc5622d39214a1b27666bd93e8d960bd4a6bea9357212a6b0a1bf0a810dd84076927629ced9b18dd6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e673897b850cb9e87fb3ccee9efa6e98476e2cadd7b7ca840e5ede598f63be63e440a2a40f068a25a3663441de715700000000000000000000000000000000185ae2963a37f580a2aee3c91a99e42bf1f6ccceb3068df93158083ede286d344b704de8fb35f152ebe9dcb206a561051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094b8571f5f49f57bb926d87d34884b551da98f8597aff4d82fa37f83dc6d8cead55360791daeb91aefb29eab29aa83700000000000000000000000000000000118aa62a4de452bba339eeb2f4ace3a817bc01fe8effc6c2a23377774f92da374864ed3bc15ac56918d1dce94077eba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ada220d8f2480b6663de8656762885e66310cb0f204c8014a70e380981a2ff72ef920d38a7f701a90f88586a237b450000000000000000000000000000000000291842f0e7e466a796b6a9ae41e0bc658aa0feaf53daf6f7cf6a64157b1e5b166c84a8eac76a0ca80f04d0a83eb8f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d3071b5a14e0052de49d2923632ca54ace073e4f0bde3740328dd483f65d001773dbc80ad92337bed65a10878086b6000000000000000000000000000000000f857ca53062788f39dd9363d2a3862791b6974057dc2edb73a503b187ccc15bd035bace26165b8df1da7dce74cbb9f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1441a8aa4d440b1d62de8191221b83dada7a1e42610c54b2bac0a4f75bd77207e67a329f7204f15639721b2a09f1000000000000000000000000000000000154cbf2cbe73c52a81c1e4a18d34977e3bbe4ca6b52ca8f116fe8d82028e74e78603d1e8cc8e06df9fd0f1345e87c9cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acb2e1bde0c48ff04cb9223607601212b1b31b3a010ddeab08855d86dd3aadc799a04ffc253bdd7b2e492430323bdfd00000000000000000000000000000000133cfb141cdfb5564ab0497fdea57fbaf8f54d8f4f5b4d6af14246ff9b70a6d716e774d828fcb1a4ce8f634e45fb81ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128ec94b779419054f15c038b410269a420d4add8920d6d935f9dc496ca42ae1f097fb665b5234b5cba4adb4159aa38f00000000000000000000000000000000083a43c508253340ab9e7c38c3e5c68d913d5886581d95dab29e12718a8a24aaa6725e9f075d56b9afb227b5fd5ebd781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c7d4326ef2acfccffbf9d578cdf31e38247d1270806a8713226c12d9cbb4b1447c26fc2e4d6b3a43e37eac2dd61ad00000000000000000000000000000000006eaa9b0d1f578f78751493fbcc91aea04316a02a9faaba1edc00a860ef4b1abcfdd3387d822cbc52f5ee98c2b5435171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ce159a4baad76256fa7e33a48131de57b41e6cd437fdf5082791b32ae8a9605a082f1aaf439db221cc3b13dfa3049a000000000000000000000000000000000881aa002831b15937e061a64037d3337bd3c30cf9a0c3cf3281ea9e2705843a541c5675659239383c47612bd2f6647e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b94dcd5e32d9050945b7a38b03ba90d4304e55bad92e85f8d0e52b71f72dd0312149f8f1c56dd99b67d74198f4fc2b00000000000000000000000000000000099540949d887d6b7de20bf785b0e3c36cb12ba44895278a8275b9cfcb7bdb93cd39ebcfa8b7b12ff77d83d5a5bac0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004953535b59a7e1377c4e9c556e9a7d0be26d6839110cf5c278930900a5e56b1fde975cd1492115eba8309ab1d2a69870000000000000000000000000000000014a622f4c6df000339b2d419f0c0e7c90c8452e51f7b4309fc2fa4f124a6688c3029321345f06283cd50a9e0d9602e2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f5739d263695e88b64ffb57212d311d65226e1e4c8aee20239400457ef9ce380f0bd9c21e42bf5d0c4696add35e21000000000000000000000000000000000eaf328b6ed3879a941b00c6693e6bcd8c5a5cbdb51a25fa46f6f8902af98d14fe4a70ba0ff129723a8ed3de16a045601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c16e1c18e5012defd762fd881c556c173e12553a3b3f6109e7ba658a3f2e7ef82ffd16b03e142c4793f1f237ebddd000000000000000000000000000000000b08540c3a4731818e186063891165162306fbf6a6a42c50d4f8fbf31bfee3af7ef9af8a4dee4426f2bf5116b50dc7b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f3744c9aaf28812f8a9dde58452d1bae3efef0f8a99c220ff68c9c1ae5400d6fbbb1566eac35b75ab44aa635f2c205000000000000000000000000000000000ceb294d6401975795ba86bd5555f4bb302454c87121b7dc3288f8dd1277cf0e1e86d4aa83831d0a7f8d08c9b5a51d7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106f02dbb46b3abf05513dae8de2d3145a04afab9744a6ac6f0a6b83fd4840f6a4b1d0ba4278fe01b759f875939f6310000000000000000000000000000000001de555d18d1bacf1aa8a2f9ab69ed1fa98be07cf3ae8edbf7004664a5a00716fedb53b288a443a4c2a5d233975f4dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d8746e8a9f6c2cc53a899348b64c31606aa5f09ee30f23645f0baada13339ffb9df3fffb2f2eac481ee64f56d4f5b400000000000000000000000000000000126a18d223c7578e45618ffcfbaa26b8ba4e494422e0d414c3c3f7016bc36cbe1932dde0f06257039cf309a12b2135661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001782c36ec8c76c3ce1e62d72c978aaa7ed0f58af914614cf539553e9a3a2c8f50a920031d0dcacd27fef1f8b44c064fb000000000000000000000000000000000180d75d21e44e278db8bda9a4c8ffab691dce3216fb67bb2229994e72cd7469a11d6cd2d68dcc8d395b061faf535f6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197e95bcd7bd6e69dede6f0e4a510520c149a5473b500e4080b93f1d24118fd2ca3bf1ba2fa95e36b1efcede53bcbf79000000000000000000000000000000001891bb0ccc02d6f40822c06dafec8ec4daa388e20dcb3cbf9cbc3e579809973fd88151f29c99d9d9290d80289676cd261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000071838afaf2d35710fb72db4b826e745e2a7d69b62a2d134b77d1491bcb412842ebb7c7a73baaeccd7ab1c3f72bae7300000000000000000000000000000000041ab4877f90a8f990da9e50f94a98a082c663dc69c0c7b141f3432e6c7a2d33782e6b28417f8471b3ca0b20199db2cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d4eeecc984742bda5985acbf63b983ab4aa20a6b389e6160bbe820b264cca60494e5143b62e6a60dd0bc795861ada7000000000000000000000000000000000a5977cda7481ee6b56dd55f56dfc4cacb1333ae6e035f3efd2d12ac239edd58dde2abbada97b5595729bcf1bfbcc1b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d7fe3e218b455aedbde7bdf52148206d9f80e497debf0c5be05936e1b456329a96f9663f024309bd29c152752f9a9e0000000000000000000000000000000015fd0e923a208e9af3d2d72f9c86e5164a8d5a0f332d577f757cb50c8f2990ba5e05a7e76287980ab2e508dec25fd6171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156bc719449ea4f74c2758cfd0a003941c49c14b0e2474e0cd777a98a1da8ca78580997a7e7a6de2872a98cdf7080e9e000000000000000000000000000000001013a7b72a6e604ae9b576977c764aa72859d1f5b114ed68d87d3d80421a0ddd7fbaef21881ef505fa5aafbf9b9d416c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efebe540e6e84bdf1615eaed97b1aa5523792ddb86dce3eb7425268b8c0131b392292fd27adff12dca4f50dca9b375c000000000000000000000000000000000832713047ec830c5246195ece0c9232603f3a25a35d7739faafcc6adc8205fc0e2727421298d755407b9636ac6384331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036d25a892cec5981c1cc09e6e20cc45d762dd7f76eb0362008fb21c57e01ca493335503427c10366c9833ef2d52909b0000000000000000000000000000000008ef717a33006f9438fe6f7937cf6f792a68b9f8863a94da8b86be1f82443822ebb0bfad752d83344c61c260f4a61db41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181ed308661abedd37203df1c9851938373ed77285607fe0060842d4d3b33716d2a2900eadf84a26fa2b58683f9a00d5000000000000000000000000000000001514f8b37a835f7eb7ad3e58f47d8f1cb195eff091874a0ff2c40ac43abc535933432ffa87b507f9bd43d61fc93fe3fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c19ebab51333fbae49f552291475635d5b083e107ef6c2481137683b6dfd327c80ccd39ca8177b259dd2195aadc12350000000000000000000000000000000007d67c3351fd98e7964ef3d943d070144d7e7513fc6f4054efa79dc98da25d118f0067fabd554fd926c2744cf8f9f7fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7e62340fc7f0cd528d88cacc87382dc37a65b722995e2d84dfc0304faa039e45a05c3073f4999dc6a05cae7a23cfbe00000000000000000000000000000000166ee356c45c196e762e54da3f5b0c93f461b0727a32fdbbae62b80cd245907106653c9ca5bf245c7a3c7ec3a414a30c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2e1253318087af2808f92420ed811cb56937d7b908ebd3dc71f49ad98519ff1c924d8e0091adf1c74bbef2e4db3cd0000000000000000000000000000000007eeb738b5f83276a9019f66d5e4a8bfbc994044e36c9f6724b499f3d5db20f588f458686ca950614b0ba3a2147cb9b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cd40c7b92d64fcea54dce4baa211a7e2658f96d4c880e6210de566b033246752083c129ed0b224a2c6596f01778049000000000000000000000000000000000da0a56e024bcecf709538114e123f1f1aff7e760ec41b0f87b5e2861266f791bf9f3a32437577b969629720020208581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001042d2a3893612a57f7e69af9d20989e7e629bcb7ff00a3d3504e6ccf91bf2eb86bcd5f69ca4393d7311298f606d69770000000000000000000000000000000013e41c6596c937c8f3bede6fac8cc68516fc7c9a212c09691075ce44253cdd83a5dc2afcc79c9aac86a783a57620c8031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119cbbbe26e50b02c634b54c9059c264602a79cb37e9a3c5be507364a5eb4a20b7285dcc8d2847d06d2e86c126d3c2fa0000000000000000000000000000000008dafcf9ec3af386fd69bb44666ca6af13854344ae066efcce17b35f7c3852466ed7c6946747673769e2d658677998421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000570a2f4bfbf8e65f13da4e047747e148a83428215283051f53920ecb4cbd9b70eda22570e76fa62598aa15539a87fd9000000000000000000000000000000000384faa7e7652c0063a8e37a3f2945d13895ebc691937daff407ab28b62a8a8f5526959867f8b755eec1910b3a4e5b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127f59537d7dba170a2674c33c2fe1db1383aa860854dce31100974cfdbb2dde8e04204a87ec5f6e960aed2409a30249000000000000000000000000000000001945aef5ac94be227cf956fb181fe0daa0938391a88efd8ccf8285855cbccd40616dbbe4143993d088389cd001ea50bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b03e860b7b7d43cef7400dbfa0511cef1a7d01eae78166ff25379c84978e16ee898eba7820c9ab7e44e3e812d67e85000000000000000000000000000000000b47c438438a396972acb9e5af9b6633c6f270a51adfd79e7d6e7e40b011166855d53ef63c3bbee357c4a92165547b071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bb23f8a43eb7d0feb08d17566367516d5b59568d3da44c1656bb4b20473bfa68209a14fc37530e2631652f81f8649e00000000000000000000000000000000072be2314739fdd9dcb9faab9105d6d9ef8be1b88928cfdb7e2c928063e710629b98a8e42209abfb2b0f63cbf2201b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d0eb7dfe296371ec7773493e22a33e6ed1d6a2cdd2f2f6584113e91599e3d13e19d68257818202716b69f32fdb93b0000000000000000000000000000000009404fcc1502530ca43b47e8994f2cdee1366d1b1d18893246c8c041fa5d95381ca3b3255431bc55c93c607b7d36306c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f98a0336cae5d2261df894432856a92c6644b125c9e4f9db4754f96fb40b718ee2f2197565c8a0e2d252fa649b1f20000000000000000000000000000000003444f03d1fab5ce3daaa2d08093c55b3e0870d598e3d838da94c5317da8eafdbcec546ec072ca8748410a4fbceca9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9303b61b8cf50e77ebae5b573b900eaa9aae8d17ef7ee667a0539ae91a51daa4f3c2374d92333bacc6dd77ce570672000000000000000000000000000000000193f02e3384c863ffbad633255079e591a629c623c3c78085be032c96ef188e1f9a6f933a532020dd998f6a316632371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017f96ca7ce16b82a93d1d71d6aa62ec850e132ef9678d67718b95c340489afc93e78ec85aa20a63587561d5cdc039b9000000000000000000000000000000000c8a38b58f0fb4a2b3c2a2b9c896b5212384cca21c9d8e72e1b1162d5557269a02e59310e5276913644ec9b48087a5621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076b3b9141a92bf89f30abde91724f0c28eaebd8b7f1faa51f97d221eb1fa8e0b15bde7904974b7bda4fa08078d917ff000000000000000000000000000000000e840db629377ffff8aa5c8dc28c7d3d478b9f40b0f721bfbe371ff918040fefba316bac4c68159b83a6d448232572fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c16fd7ecc725da1b1918edaee61742ad15aa89a6ce717a876643990cdf60ced8fe427d66eefb497106911cd2d832400000000000000000000000000000000066ff1a339bafb14e44a5b559323a9a4e5976d8a202be7664bd9f9475e771194ebeee02452e62290f471e0bc696af9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001708a9ef760380c5366929b51df68b256fdb47e977dedb3fcbad0b68ffdf1a021da832d2a49271109d02673e203a992b0000000000000000000000000000000009700a0a106abb238a9cbed06f1a4e2f2335f014a33965874ab6e891005d830c328ee0a4bbbb7ce78a21774e110be7691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811994efff8a9fc77e8bd436f9736f8de2a99313c42f753e83bacc3c50952565e47f6194b34665289b9a885cb103a170000000000000000000000000000000003952c2a994987ec10814d22291204488af6f2fee058dd32857e9f0d34b5aff5d1e69522c90743c4e67eb7a64168e9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170784c421f6982ac64dbc33e388c12686810b40357ff1d67ee45edffb0ce01921c97681120c75d81579ddad0d415b3b00000000000000000000000000000000012c62034705f9867db095ee095dcf864e091236ea21d99c776c6854afd116a0bb014fecc719b853dcdb02c4a92654f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000855e63b42a018bf34459599d224ead759d924994a288dc3f5da46c1db4907ad0b210a52526fe58a9733b06763bee73f0000000000000000000000000000000012bfe2e613ce1d6d439a8c95c99ee70f4fec4874f741315d5eddf2ecc3a182bd8415a03f16b1a565f634232f29a26ce71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131b8bf680defed3720bc23c5a169ea75c1b3fb93579b8f1c69837810fdaf6fc756fbac1610a4c13b582540b4a3efc4b00000000000000000000000000000000119136eb6d7b82c4fea39283c5a70886d5a41ff678b40d1d7a72396ed7565145dea39920434db19d0b9dcfc9ee8fb2f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3a031d833baf041f6bbce2c071fdaf4e24d1dcfba811784740a058cf8fdf1ba832db6cfe1fcc57ba2c50255c65f25000000000000000000000000000000001316b3356b0a24b26fcc5984550e0374559418419b89f0d71885b9d3b3f3c62a8f3d518073922f58d532e1d71e6022ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112fe53b450f17e70c37d8e62006e3bd91a6bcd59cb786bd3c76dfe41a19f325b5ec2614d4bd1d3162d2b1c6bd5723490000000000000000000000000000000013c5bfe8ca8f6192bdef003a4c950888f17ab175be4b97c4b0f54deb0a26164186472013f76337cac71adab0fc097c5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014846d8b5cb98364fbc0f079c47f19b63906e69019f6c5f1d6dee1a26ea01821d108e55f0a49da9b06d78123be0a939c00000000000000000000000000000000163e4ef3f792844f81c71af14a4f77e302fbb345cb42822485fe3d9f631675de989e9b9734b86fd7da9987e5f6d56d8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadad68d5e656e82ecbe846a0a045ca495eece2386a5a717ebc96d5be1b88a27c02de4ba337429ab1a8ba4d1c3f70190000000000000000000000000000000006e479435b793ea08c3a9fee22bcc5f833314b201468796d962b22087bd5da013e9c96887eaa8fc9149bcf790d2f2ecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faa486f217fac43e94968b3fc550900d6ce97603377b4663530ba76b029ff8d5a275813c0c1ec08fddbe78cb89b367c0000000000000000000000000000000008fe06558b29bc8512afad09a483e1acef857270cdffcb56f28a06ca28df488f50f9731b462957d3f39fc4290ba5163e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001995f15d1759303e07b4707b582dbf42f48aeecb58dc57d55e1a4b9137fa058e7069eabec01098ecca2ca9c4921d28b700000000000000000000000000000000119d2c2383f07ad7f840d3cc6d9ab8280bc4bcfc8523fa10e44033476788cd693e3b0d5a3b3a2928c401f0da9dae65391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002739a47b2007857f8d143ecdb3d2898853145a6ee13eca6bc9dc8998d5b773ad001f2af597a0cffae6ad5322bbcc9c70000000000000000000000000000000016c3832f1ae3e9fbf62daa00a1e1b4cf46a4335377e58e18604081f8643b315f956d35382fad6ff8f4fe07ebcd60f49f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cf83bb70f9e708f173ec8a18d1f9a31dabf7f4f7c639d08f6f22b48745e68a166bbb54ae6378bd1a829fe2765122ba000000000000000000000000000000000a63a9d81901dbd6378c0e1d47e4819db3781c1025292f7c515cba662ef5f9c7aaa6af978d6b25c066df82a78a8e76e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea6ca775dcaa0f06f305ace5fde12e06431be0c77bb935ac84f32117d2d06bfe513ec85f36a82ab8abc1fb5a3034a780000000000000000000000000000000000562dfb1f521c740f14dc19233b029956a194cfe934eea208e691dc9ad33cd3ddd99db40ce40f268e814575ab4418be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cb9bb5ecc4ca97f9af1bfee0ebd259e2254903db674b019e2c1226c4ba052a9bde09bb5f13161d88860159caf6d22c000000000000000000000000000000000cb31a0e4555f6b22dab7491010d922ed6bc861b34761ce13215fe7d3a6ce061fccbc14da03d546377d1ca0f0ee6911a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042515d2693e5919d019b8afa83b57dcff5cc5b9a4d88513cdea8489618f530231f0ca35ea84a70da0d024c601a656b000000000000000000000000000000000084f0b76cce5f303cfe0453b3da1348cf62451144cb9b4736068cd46c76e678ffe9dae2eb6db1eb59ecd815bd3b50bfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001839b49268eb9a55812af59c055e6f9b68cbcc22418a7603da07aafef2a1748496d10ed3d7b094bcb05e43102f11d3ef000000000000000000000000000000000486ba39834ab8ad14dbb1c43ebafbc7e2ddfa28a6dc0a67d48e1e151b7dca057f84d51857e8506f8310b5ea0ad2adad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e858f93d2724dfea4bd146117990d79efeec5c4f5c927ec493962e451dbad88687015afdcb30c378b334b17ecccf210000000000000000000000000000000019dc97efa35f4766f51cd4f93765795b76893e2d079be7a48862cc93d5421d3ef4184c5e335d7118998724b27dc710291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a2b5196b8be417a7a935d0f12fe31cacee7442557cbbb409551d7050d1572e6cef54a7fbbfc0d9239ecade620cb96f00000000000000000000000000000000130070a2ceb1e7fc87bc4c5ad4df5d2c9e076051630576d88d180d8f9971c710c3e202c95968df62a49dc93b407ccffb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009913aadd0664fa07104972008c26af4869c838f969654c9e13c098121c20dd624af0dc2b53c04c1109d56a5a7e0123c0000000000000000000000000000000017ab6b3890d397f7d798b99eb3235af1dd2c60f5036af3aeec60fd4fe1f41cf36758522859455f40a25a48c3d7aaac161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009de8655c5e7eb0d809ea284ce492b56ddaba2c5df5b36b7e586995f58e77c662d55be0cbb29af139b295063e63ed9720000000000000000000000000000000011a50d3edbbcbc2903f3931a52e87cbe5e4df7a5bc672779e1ea6e0c4d8c963a26cf32ea0d2e195f1db0189b3347747c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e4fc68183cab5d0fc065866d38161a5deade97e6b09a5a54e9a8caaad9e57fba32720e7a51430f6a5041a8e60de7770000000000000000000000000000000015ffd68db1299aebb543c492b392d4233c319c0745d95e59e8984d8f9ec3a4765a4b81df129b7e9045f30fcb5b81cc801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014de7dccebef2d3e9194651c4ef8955b7c6a812202eb46f713f4311327e8268173a6a9f97e5fddf8b5daad46788d34d60000000000000000000000000000000019e5f14b7260ebee35a6b287c034595677263aa6ef2616b3700706aba494e110f8a5ef9891c9d5b74afc2b0a0ed5ef6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ea41bfc4e6077de30416d3f48952a2f2b80c72566e6ae9bdd94c5598f2510e928318393814b4492f51c5b7dfc09af1000000000000000000000000000000000b142bc3d52f95b66af951a3d8447c5c4ef58f9f0a3088dd41d48289f0e8d6b49213c7bd0df73a9efcb8d0ce2d7950891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001983c136dd787b593f9de878c0be2f776aded8189a415f25d8526d5288ead1a3ce133a10199fe6864dfb6e1e583134f8000000000000000000000000000000000178b3a93ff11caed714293b7836331c86a0b2b3c438b3ea094610311cf1ec2ee0e45bf30bd4ac69bf18b059e924e53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8af5f133df392287d690e720465702e3c9adee6885d889b152ec4e75625e9377b08f4f8f64d8165f74872cf4588a9f00000000000000000000000000000000066083df5e8c4bcd053c6b5f51284d71b05b8787955666ee5d4fad5d492fb3a5c51e33a6e5eeaa5b4e807115d620e1e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bdba84864acec670b7b7d1ed243cc84b275da0e77aea36a066c000f5fe8009ffe8f0581c5dce4eaf89a1da646005e000000000000000000000000000000000b65fe86059b9b0a052da0dca59f0a20378a046f04e85a317b3a892adb330f498978036454b8c1e9beb9b563c6c60f771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087a1530d477c9d322ac7e30261875a1c907d67b318fb61e32c2698915beab1ddfbdff81638bf90f1b85915577e7214a000000000000000000000000000000001617618e3c6e4e6c529217acbf8322ad33df61ea43ff23162117462182a8c1943b8b24386bd22ba6f570aebba6634fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091eba09469e5513c33402a796873998d13749f0f0f0768fc0eb75ed32eb76c811f8b76f5c9735fe9c99331a529e73dd0000000000000000000000000000000001d68d0adbe6014c4b085c3f50b57f5b72fda82643ce97c0f82dc92de43214d4a4f67465e0e85be052c2814a09a60ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d10b5843e9290caaea1e3d3d2ea829be24239d80a0367bdd352f35aaf8d0e91ad3bc76cf34087a87b3a807e38c19bd00000000000000000000000000000000002c710ba1de01fab7baa625506b700cd852296f3f2307246de2eaa73a71fff3158bac99a0b0194cfdd12a6bb08013061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bfa8e44c067cf500a2aff79f1c14b7cec731008ce05a39567310c241cf026762cfeccf9810604e098d58aaa262d8cf00000000000000000000000000000000162c993700e788b8274bb799f569a55a0baeea5eab95ad1658c0bcf11cd4909db72db0ce760b0d92c430318795815fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0bbaa3022cf2909cbe0fade6e4f029ac4b4a16fc4f4e6f081cb411113e3fe1bbad3329b3b1b7efca62b558d2f4bf95000000000000000000000000000000000db0976a1997217e90dd351d50586f7fd524481453d4c86392e407c8bff3338cb86d849302158fcd296c9487b19e55e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b013275a0d3f621a6af337a59985cdcbe84af727e1bdcfe30f61ee7ff275d9c414e0069898c07520ffa098d40870a30000000000000000000000000000000001b4e2d52768423046776a009df4aec0c7fadf644f8f76ff82a29ec6f8ded49651df839e8f6e1e381e0740d65dbb611a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001062b55e2cf3ee2034579091a7c8addf917ee680fb43360dbd8c2b2e7c23e71494adffbcfffdd5179e13f7da4f7e359300000000000000000000000000000000038d3cc6f7a3944fea40fd518ee7ff00a4d8b92168e94a8db1db7fa6416ec0f6e904cb6663a6a3c4fa065afb25cd2c601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aaaa8df2662cd690b468ab03bb9c785cbda41d6a7a844ed92d3f73954f7c2dc17b13769ab8c53db83e7e61269ba1bc000000000000000000000000000000000ca26871a313010aa9a86c1901dda8cfb3432c258bd1c96e66624bf54787eff940d2186029a20cad37e7ec428a14e2f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ae936813317c94869bd8317e689f54902d73101b06a5732c09451dd4cd5721107a86aa7bffbeb7d17733ea45c9ce430000000000000000000000000000000018e547e0944c711bdf1c4994f89ac004ef9c04a5a03b20c1ca702b9545537efee7403adecac02a77c41e94015bbd07b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016790efe4b82dcde614b8931d6a25ce417753c1bef2a1ee1692aaeedacb14b444513c15705d8ece891f667d42dc47de80000000000000000000000000000000009b19e232b5f306f8de6e98b31d85b51b7cadea3552ef51d3d92a348889b8e29c887c0a0b1575f35c4382d6d7bfa2f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd6364eb7d0ec0b5258719220fe69feddc47bd17887775019ede05d429f727bc94d2e06ab315f7cb170d9a7b54f97400000000000000000000000000000000019b3b86bfbdbba0924691ec0d66e3327936ce3d0212baf85aae6729bfc6d7d6dde875f8b4facee5842aea557ed93d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017da7037499b229f7d55296fb2e55c6f110103dcf8e12779778302f8f94919658b9ccc4938de416dc1067190701789c60000000000000000000000000000000011b92400daec46980addb5d5900fd411bbf0fa952381d206dd9606f62f07fd3c1cfd3c69c8bf4bda998af0581e8b7db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c638745d19052e7a0c112b0c9009666adb7f805b16aea3e796347d82227aabf9e9a6a60af21b4ae34d5f05f5824aab000000000000000000000000000000000e4722e433c7b7ec0cb22847de4be1eca97ea228ded2eef8c0edbaaa76db27b91d00dfc897a78a37a90e45f4456ef6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d687d732fbdced94d5f9ecbed5fbf98a4f2bf65e16a188f7fef2e126b73eccb9e442685722b0e6d7e7c9a25dbbd8a3000000000000000000000000000000000a2044ddf20de6e19a7e567704edaf1ef0ea83ca30b67d4afc374f34fbcaaf10a2838fc5a1758376f44556efb56378821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bc97dc830b73e6ce7c6a47a0cf1083952e1a4fbc5c24734e6cd28845180a42991c627e7328df68e918fb8972e78fc00000000000000000000000000000000108a958bf9b0284918454bd6ea20c157bafdbf5c9ea4dd0fb3fe85825c93a2cee2e06503d925f0fcf67bac5b023991651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071866b57d50c73f3f4f30dbe016ae24e6c4ef9330077f8851fb8dbac37b4ad20e6a6c48d215b102517699dec4b2b9e1000000000000000000000000000000000aaf064e542c19ab90c9f4d3deb17877fbee0122cd674ff619fc59cae3c28107e04781bf1f2e43e55114402432c9a36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ce088e0cd4b66df3b0366a551a4d54ae76133235ea5a2b3f074266b3d7f84e737867d907e0d014eca7132336dcc85000000000000000000000000000000001320acfa92c87735d34762cfc61bab1eb7f384d07c3f1faa5eebcd8d2dc615bfdbf7ce5c3982b1c5ec2a6cd5dea3ea3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116330d790fc56b0047ce1866dedc3cd3551c6d618fe0f2be69b70f12f024ed625bc9bf366de68644916c8835ddd7f560000000000000000000000000000000000739a3fd6a67bfb45ee45bb95986e2dba04b6aaee0423203d69221364d14830a59493a1c62fa455c6e4d862f745e59e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bebd036b96525ea96cfd47f62e55f92d397cf3a13af0f0a5704a274958ebc8bc7b6063818b6e98fd86578e8c47f8d88000000000000000000000000000000000ccb140931550ca68597346f74b63723f7f9c1f8d63526341b45dc96e34ef4d911c1c7a46ac1b422b8c599739f3914641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb8a00d8168ff3f28294c423fe93740c7f52fcba0604d3e23546c1909a0baf34a61803a3200e34de56bc9fb239a10ff0000000000000000000000000000000015f3fb50ede2c632dedd8644f119ba77ea5e2629f115b83916452edb51d3f7d2f9b16562e4ee6efa5aa6e03e28b595e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179ff44766ad25edcdd58e6a0c1ffb8acedd7f8f4d198b18337e6a08baaaac95649b7bdbb21a256459e196527e2de72a00000000000000000000000000000000078e247cfa9ff9f72a908137996ca3e76954cfe2da0c472c8ca005aa565de7235e1bba3e504dd041ef4b62cf6bd124f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c9301294660ce4eafea209fa7c078be335916c162c721bd4187def32afbfe73b25e3bd721949188594ed654fc7b8ba000000000000000000000000000000000fb41ae7dbd4cd4a837e0d07a2d02bdfd5e40b424e0bd68896166018a20bb15a5ca8e0d0a95cc72c0af53398423439261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018685afc44721f38a2bb7e73e403e1588c09cd9c6370994a72114f0bea4b8bf370f1721e9f25b95dd018bfb6b6938cb9000000000000000000000000000000000ba51632db64e795e68faac8a55d81282f13f1b84e5893c42b5003db4d2faf5c50b53b939e88a4d56e938702d14271401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000534351ed6728390bc67559d92d82709723a271daad3a3c28c716c762de4f3bd39a39d2e34bce0de99d9562e946d48ee000000000000000000000000000000000d730b2f4fd82626364998bae177f20a10c78778550c51e1ddd017e34c905dd43931a05fadb2e5eda1d24cbc94523e291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001363cb7920aab3fa7de8b49bf6bad01f0155d429da7217558362a6c93a8c9c186203cbfb058ccda492beaf8ea1a3c880000000000000000000000000000000012c997698913af7763bcb9d3c4b0249cb3510a39e7ddaa858ba7ca11f343b6b37ed1692fe167e3749303bc55a1e227861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e34b30d9033a4e6e941bd9bbc07b46cdb25990e43c7e86e7384794c28ec1f6866fb3b34a8342affa585caa0beac1b00000000000000000000000000000000014309ce6cdd10197002f7fdcde0e1fe85a7423857e4d0a824c98918ff2222aae394cb87487e9975385749c9c0e34b6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034839d5b9536e5c7ada6bb9169e9ec3326d5a80c7b530cb0e2103bf6dab27d8c3ac5d71ada81f7ed8e067b708fc89da000000000000000000000000000000000b6d9272b74705bdf3a7d707993d427c4d3c8b91902130e3a203694f813018bb74ed2771545da294c6df16de573263071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9f766ece814917946be335caaa13861d35d2f34055197f0666c7319f942e9689def3d6db443309a4f90c88d58ca5e500000000000000000000000000000000169adb818225f5860c52af7c85bfb41360272689359ac73151c00f0d87771f4affe3fe77c3837d20ab4f595dcf49495b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb7cf6eaa5bc485664c166211796b001cb20ec9bec47119838041bb5b0f57bc665bf72b1a34ae6f66645a3af63d9e40000000000000000000000000000000008b02162f4802981cd3302e7db5d844fc7bbff083969248378bf621ef6b25297578e334afb3c8eb8bd99b99f97015b541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8e3fe3ef149a1710ed568f3aa376e9db9215624e0658b6f94ac9e55dc838c2c138d9b86670245deb401856e9593eba0000000000000000000000000000000016c1eb0d36d150b4cffb995fe9488cb831f882597810c87bad036104eebcf3c5f43d7164728990251609a4a712474f231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013747075419153101b76f3dcc1d908568e156208eb48cd4557ce55e7f0e5a1fa84c85b905cc8013d0f85cf3cc8f760b4000000000000000000000000000000001559634aed4491e19eff20314a1d9f88d3166eee4de46c16ab7c3e4a14227d3e20dd779a9ee77d83a6561258255b36461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e282b9dc942f81cb165154e0b5b307d3d3abe6c152d733da0e2a62bb6a6a335a206f4c72d82f1abc19bd82dec666ce0000000000000000000000000000000000ce9821d323eed628e9765e4e7242604eabd6706ddfd722d70ab5a460a04f18774d58c774726a5b131b91bc6466d94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151b426aed83d4246ad6d563ad7926941f4c5400b0759881c928d666622b0661d22394a645d20fb8c839122ededd7c2100000000000000000000000000000000179a0e7a98f30313c1764ab9322563594dc818ddb48ead37734c7905fb71abaea6ce702f7be9cfb70a1b201f377bdf351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167614c4ebae80aa0f54ff8973b477994905f4beda38dd08737cbcb0127449ad9ed2ada115a09f41879ec167617421b60000000000000000000000000000000000cf7d0f80f8b4b47494f7f069fa5685d5c5b11f5eb92b7893d45a854d2016f86c2442a6d06a8f9ecdd8748c548f9e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012980fcbf77c238486272f6aa6feeba05204625f660e13e4dce2429b2301366a82a37f7a7bb73764c1fdd6fefdb9ad0700000000000000000000000000000000086ea68c7da02ccd56754dbc697db4ec452ab17cdd8385d0d1cb71ea0a71dff29362809a67226882fb91820c2d0eb8391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056dcc04b55fc84e63c830aef44e53394439ebf8c6d856d3e444f4cc742abf67a62f16e38e3f4cea21489ca023bef54000000000000000000000000000000000c5fdc98fd1df5ca161965f95db18b52146a94c6b7e7e586695b75c105c28c3703fbf4f1a0a7d01aaae158b1deff97741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bc08628ac314db2d0df80aa1642c1b6b15d9a8fc7a53da181aede785212d2341dabbe616fe13d947b748350585d889000000000000000000000000000000000f6caa39240d5daa0c5cdb3e8aea7698c9e9c43f8d285f610138174bcd7217621ab81e17f3214b63cbca2af012ad73dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35d889006324c7f1a6cc9151446919ac23131a6a4dd9554908d450e9d491e4475027fff69daa1f489a921b7e70d7a3000000000000000000000000000000000a34b4ed032355a44f02a3239c053b3e50915cbc7232cface5d1805a3341d5bb67508b8bb118cf39e5c8c0656b7d2e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013b790df48550951293d76bcb64f351550d4d65fedea23d45260df33f93c395bff8d77810223d9dcf1bd50ee4bc1199000000000000000000000000000000000b9933602717af4ead843cda9fff47b893ac36e63f83dc6df96a158a1c83da1d5f89ec32f8e50ebec374d73bff769d131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001949f9a63fdd03651968d0606a7f7a3bfd02f19fa00af1649bd9721050fc37da32f69ff406ba60fa64655e60d1b633c60000000000000000000000000000000003e075b56327c060e99c72dc198ef9b73aa42869d1f49acb6bb639867a1d71a6bc8f2346f88aba4e47d999516edb1be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e50183d57cc446d088814345100994e2156e524d2cd88f96c1590a2b16462240de058ce245952eac8c93b703935f3840000000000000000000000000000000014cd1af73bbbde453ff3090c57a4b9a3fda8579b3a7f5668ea2a53eb514498c2581303ea49c4e2138724c37b025194ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dffcc8eddb5310ebd4de55be4214ba405bdf21dd11b7614a6a0434b299a619fe7f37c46ce7405ec0bc2ff47fbfcf7000000000000000000000000000000000f8dec31d5dd4a2fffc249d6056f528c2c7ccefc3763b777b082bca726b35126ede3aac894078429931c513c7461f51b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000645a92961374f7c96bf41d4271954ae939bd2b3e07e655e936bfd7b34fd26df29aad00fd3bf11bb0e68c9048ffdf612000000000000000000000000000000000dcdbe596006772dffe0363d79f49597b6c1fcfa433e6ccd399a2043271dce6c1d3b26cb6bc1b7ad87ea3aad232cc9e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176d00b1108d2c0bf814bd25d2f1208fcf704c1bd9fa302c235b08fd3be0a73af960957d27101a0a9cc3e62002e595c90000000000000000000000000000000010df2c7cf154caf0d8c401f689dae28b4b2c21d73ee04133503bee9dcb88a8b645cd3e6aa0733742c4572160c688bee51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d734bd0e4b9b588d5b0a6a87c79ebc7cd43e0e7e90ccb4262aee3f92fc99e92f349c3fd0b3f30f1790d09bbdcf0f7a00000000000000000000000000000000070ff4cdddcafba9adae1966209e6346157b32677dcb70f1bad3efe2d119d6c8812cf77f3dda6ee0594629e1c532c8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2f68cac3b89c938d7a2f19bd9fc2ba53311bcab1631c36d19c7dd0462552ef1bf74cec5bfc5838d9cefe45fcd745e20000000000000000000000000000000018e72b4800497d9e9351f88f50d8ff1a686cca8f2591a6816592d0ce8187fd0ae844638a7392312083382d4410b5a99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f3a5bda48e0d507677b614b98f2f8b53979a47930a5e4b979321391d044a7561a27ae2cecf5b2ee95ae960ee297bc900000000000000000000000000000000062aa4c6b86c68516f9a178761b918b3bfeada8b1d8c48f5dee8058c91c1d17c06dedb6bfff463361a92f79a37448a5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051c0061acc7d4223a1510f33459041726d6997571fcae41250989ac7bcfa790b49fdb3cb78e73d56719423d18760eb70000000000000000000000000000000012244e53e33d59856e3b67600db0c63a8d3948a8d31fdc98bec32e5ae7f0b00516ce7effce4ff686b0776b5dcc6a29751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d29f0db0845d9181ddbcfd45fb8229fb812d69e131de33ee3083a6c8199ed618ea29705a4aa860cfbd602dce349eb70000000000000000000000000000000010bc8a7c3eb7267e17dd7277595449fdb7d6357b2d8b1e5c87140b5a9944cde3bced65db1708db67135398d3fbf16ced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001293d1df5c00da7c245bfba82d0325a11d9e987151cb789f4a31421b053c1768b38c56d510ed65b446c22285833627d2000000000000000000000000000000000d5d0220f7d9ecb1f25eaf14829ae4e67c5f975da95781280fb8d2e8b169af2ec1c431fdcac98af15496cc993bdd122f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002816fad0f46a5bd3d8f3f6efee2aa199e8df44eec89928bfb5d2bd120cd26d5eb83c007c9f0b9819cdb95bb69849bb400000000000000000000000000000000079c91fa657943be028d103bb0306bf2ddb248ad7491266f23a2a5a91efbc39433d6d0be5f0d00616248e110f20fd4401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d907672dd066ff630d1190a35e3a868b85b861846bfd315ff120bcde4f0b299c1ce26ec0dba8f8290e4a4b667a85670000000000000000000000000000000008163bde37562f7f8d288812e2caae49ca9855f1bfe462cb80fb70bb6ebd6d2a80d3923bba8f4aaf1e05ea7412667a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d43a8285c4968a1842e7bd6b3e075fac7a78198915244cd080432705305da10c0b5787bb382028bf9b0918088371d7000000000000000000000000000000001097dbc47ba22944bcb153311cc5affffcf877dc154a764388968cef8de2f39076900225a801302a63b986a4abf41c381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0244bf3dfb9ef5902da6038cda9afa6a2033fa8bdb702a9639eff89075d7591f472def2ba622b328470d28197895f100000000000000000000000000000000111e150ddb83a27f9cea3633e35ee90ca0b1ccb8a2c14c01e527ad419c05ac438a6286d94d8f3c07aef7cc640708a58d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e74c8fb2bc3cbf40f9169e21866fb7490cced691814d830b3a4350c2b53b1deeb5e87e8ea12ff6be263310eeb13274a00000000000000000000000000000000190d5831d2c33bffaf7534a2367b512b2669b671ea5afef7b1c3a7dfdfc6bb53fae01fc5f17c476813094e4d6ea1a1041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000008b9a6d752053eb6de5d4ff58970bba52434cec632207fa534ae0f0029a15982afc805b9421a4c610f163811312f0afb0000000000000000000000000000000017dd2c343fe248bf8d97a1b5ec09bde9e92ea63c24bec6a9453d041099adde402a6ddf798ecb8ea5fb9a962a1575eef0", + "Name": "g1msm-256-jwasinger", + "Gas": 534528, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000187ce84998b854802f88ad4173c436c43970ef8de0065a10fb93036a7b203ba751ced055bba354b63d53d676e47338a00000000000000000000000000000000010b272ac018b886988ef4fd5f835eae94e8cd1cd7fb7a1229f60a2ac25c9612ec73354a3b0aef8b56ee011339b8934a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195ad1965afb993862c149cfd70b3e21253cd38d831867750c7f3cf59dc4f0776d43ae3adfc3fbb7cf72aae22684fb84000000000000000000000000000000000e0502529af1e4b5f8ddf4ec0bcdd0c1f0ce6909634bd3075dfa9bb057756f2644354df49eb23f99905becda751c5d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e554267b1fd3605c0e3250193d91024ed8face3f03a3d52676ac948af6cfdda5aa946fd6bc621b5173e4fc0b6ccd7640000000000000000000000000000000019f966a24b8339d3cc80588e423408e903ed83fa804777dcf464aa582ccb6cb384aff837567768353a3ebdddcf959de51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c045b02230677a23025a7c1da892cc80177735b33aea4047f6464be3d030edf27e30d2a3f51b8f77d5ad046c7fac700000000000000000000000000000000001e34ced0cf1f7393bc4749f085ea25eb786bd20f774049eccfb571ad06f3f1fbe99bce0a45842646e82afd1d8d816e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d885048d8a308ee42d6f6393eaa63554d28a4ef9b33335b475db26d8257df0edddbb933117bba03c9cef836c6d8c900000000000000000000000000000000193a9b9aef41274b9b7098e52702f1e7697112697ac07615c0ef44a91748703f8993eb472ecddf8f79dc0addaed2e6931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001586e2cd55ca73dd3f4f7f2758b2c19bf42b05edaa03f3f9147c2b46731c157dcfa8e164869bc6762e4feb5385edbc450000000000000000000000000000000010b3086c347c86c01c8812c066b77c8ffd89e5537737d800b55f17c795512db134e5e1f2c1205285e8467df183c7cded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001581b16583f0066af82aa49375eef64f82a72fa43a0f129a1f62adeb9ddc44535263120a5cfd57edb58bd394e45ab32e000000000000000000000000000000000bb99e4c6a1d01f700105a0e6d2bae9d81191ee7a3f784dfe32ee632af0f314719676e96cc52037e6de800b2380401011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001161a52455bd3b7fa5e43a574f8dc8b9b5bf7fb684d6dc92b81b73aef325fff67fc79911522018ade6cfc10fde5cb59400000000000000000000000000000000063f97ac26ed3060035d89d9a59e0c1091af88b9ff599a1e0323567a863ed4c3148cfc5969f3689d76bfee26895031b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641a852118cf0a6a05a78463786292daab40116c798b1447131b6713bbb4088ba6a5e01969a689230d8a138d0a05b190000000000000000000000000000000004578810e6099aa9eb274fbff7701273836303fc5ee5e374aa4c3dfba23a349eacbe07b6245ea9853327b6cf7ba0ef1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102847f66d4c2e8690e282ab10b55a8a4dfe0f121b4e157664c83bf45276532798b861049e8901a813c4d9b0d31386f6000000000000000000000000000000000e7cad0243743a13018f0bc944d31edf6f8d7366ce72d0ce60711bcb3102d77b528959120899f8bd83e727948bdfc0351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b2c872a0c874d8e66cb5eaffd36a38d6a7768f96526132939a85da4b428cb887f62daf58c7cac0f4406d1d8a995e560000000000000000000000000000000005eb0768c8127ac70f5f7a9fd30bb0b5f8082c4b20a37d5133666b70673b9e74994f29f9a2eea1e6d9f17555563b95231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d756fb34a2764696f703388f6a7aa59d02a5f36958fd1e0b06498811234532e24b93f8c17b2dc2eb48d0b7c41deee0000000000000000000000000000000011c6d08c56a82cc263b5b9018a3929021b7a5fa3fc9dbef58a02550e32594394644829330b6cc1ecf0498b21a519d2291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c7726054358855fdb12c972ee512657a0702a78f032868958d81545a32372c111436d887f3c445347b616011429e4000000000000000000000000000000000a4ccb54601b7ab6167406924716d5f00d8a57206bc8ecf58fa879ac6e162e6aaf8822fc6d66f6fddc74f207c0b273801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e9de7a193e44172178d6e47008f51ba2452a24d6c19ad436faefc0d39cccc1f9625d3d5c76ee2ff068e72411333a44000000000000000000000000000000000d4df9060e36c437af11f37f35e967486abf67662342909172b350198681e86c6ab296d4e5e9edbf9107f413d3be77501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056b2709578723639db0109371f4821af1f8520163892e5f1d7e365749d4f3ccde6cf214debb0d6e87270d8adea2d8e000000000000000000000000000000000784bd7cec07e59e07441b96000b72da4f5e596a6f38450835354d55ae56c952f0ad441241de05fb643c13bfc8f5f5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a3964d2770792ff55c8a5d0b72ede30853e50801b45aa9b74c83feef7ee388a8a41132c34d383aade574bc48980810000000000000000000000000000000007c4328f2baf080ef97421d89a39f1f1ec08d5d7f644f3abf64d057ee75956796c5ff21ba2da7735bc2f69d756ce881f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e67e08559a66ac77cdc2b4b205a51170b79405762a33adc9da0c05e1ae9f501f627be547ad19fc2a42a5f1d6b2b413000000000000000000000000000000000a171d6f2f15cd97ee575ca2864a0ea1457299745a6ef37d84e08c61a713a33e4adef886bdbf5ac1f8407265b2d913ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001605a9f674d1e5716a47b0a27859fcd4321705d305c5f972ded1a3b6b35d675cfb500d9fe6d58f1321050dadb84e77d600000000000000000000000000000000068ae969912b75a840a0bb553a502b7a0b655f8ea1134217fbe4e5d2114df44f2e7c97887525cb73ef01ab3c59972e901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a141218ef8d853155fd994333f8495469a7b4c5e3eb7360f7b7fd0a1d90e2146c94ed32f4e528bf60f1c83482d734200000000000000000000000000000000034894c3e9e45d1e213c0ade99f2738688dfc7eea763dc9904c4d2003d07273c590c38ac51b6285300335253449e29941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e15285c31e5e54f0a46562005007027bb38066001d2f00ec0015f9da149a477929e40a4988d8f370352b8ee58f3b17000000000000000000000000000000000488a996bc590e150f8a3a78a051a6cdec91a9f96122988c53e7d20cbf2abf38765889256b362fdc663b71ca1f6c3fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178dd54cb644b36ee8808e28325334f0b9b8788c8f5127ef17b3bb71435882f8a35c6aa852492421fd5526b70f4399f900000000000000000000000000000000102980f257a2493a1657104f6f32e14a1e83083def406bc31e1781ca28a41d83e4efab88a3017e655c0fd1d2a28c6b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7550ac358e93dd0758d1e08d9893a126a294a0b28e83c7349d3e5987e7c88936251109ca01cf8aa9c641dd890d450000000000000000000000000000000000e588452a3dfeb04cc361cdc2b71e3197d264b681c7cfd4aed83f4fdde83032b94862abe464d82e8ccaa99f5cd18bba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001725ccf063832c4be0eaea56952ae38a86d1054889ebd870e1c7b5eb49556931310b63938712fd3c95b55d585956b59000000000000000000000000000000001153698ed6d6e5afca492fa1fd9f35f00b5868ed9fdbec1368c303583e4e3927feb52a6f842c00e935f37f73e1373f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dbb8bb33a641073dbd96fb2f0986ab86d78b5a3f003c241556cd50f157a6700c94a731ce02cf3dc9661c5c9d2a289400000000000000000000000000000000158fdc083244605ac4816fb042d957071eca9ac8055c8c788436bd7c1b1d63a486fbb830f99f964d31a7199071087aa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328e58e92e5639e5f1e5b6f252cc8e9543c4fb483cb1457225c0e870c125ff6f5ea76f3f1b908a1a258cffb59fb36d800000000000000000000000000000000042df1dc419c0e4804f7154e64eda8d2c6e59d33df473ee8efc0a28f97bea6add7de509386f50250fe0608176f4bff351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7170e4232dcd331ca554cb3ab76b77cc9fc168c14232ed3d55a87a9051ba62e83ed467ec2326cf5c8f622ca5d769c40000000000000000000000000000000004fceefa8dcc518d02531162876b6176751e41be1d157e552ec6ad96d63a3d6f8c2bb9d090d30449df926d15db900d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d67c5391f1e8cacfa074c0df5343ca99027272ae90bec85eff0ad5cdc254df8736f4f882d0ef9cd0a9139a7220c5ef000000000000000000000000000000000a0d50a8688a5c48bea149d2429d327d8ff974ef8fe9018d3ef76c6bef71e4186f1e5f184a956b6be76dafa868161f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6211f83d0e73f321b9d7996318a452e56df0c3ea9d2b248e0376526f46c5e4c3a30b014e916b3d5c0e92f002e3b7e500000000000000000000000000000000088d117836cb94cb468ceb40e2a31709a25b46e7fff6d065ddb51adf9339fcbc3d8cc046a8847029a40cc08e6a1e58761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e7b33464590ce097932c739177fa679085f1324c993f5d15d4eb913615ac5079457b53a32fc5710cf0f04573c2ebac0000000000000000000000000000000009d86a4905d01b09118dafeb79ee65b3ef30525296c587e48abacc4cfce7901926fe6335f5881c41ca0341e6eef8a6761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7cf3fc44440b4976f5d264fef4f50cb3e79dc8df90a006d0e3ea91bb547ea19ea43ee24a06d27366eaea851ce2dcd4000000000000000000000000000000000049aff14e870c1d28663bfb416900d335f1d58a62faf6c35bedc4677946e1f7ac74eb4f2780d6200674ca73ed9ec64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c2ce9433cb42dcf70d2c99edd97e0702afab3349e91255d3e7e7f1b71085ff7ac422a140d43083eadc71e8b31d2fa100000000000000000000000000000000041b87b4d6fc420a120273a5762ef25fd38d8c9014efad359af8c363cf0eff959b3adbabe1e26de0537c9a56e30cbd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002100fa192aea9b42d0ee1fbf06ea43564f96af80ea70b14dc908a2e323cab7247385ea99e801192a2a192136f5f18d20000000000000000000000000000000019a11c656dfcb9f0bcebf9e37ed7e40d1235a89dea2cd7ec4e9db34c6ad92af7e7b0e82759dd88c9bdfe4ea8d0c1e4a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c6cbee9a045595d488d6d7ada13324e350391c5f7a0b9b7e076e34eeda306e77bbc7c7c26e82eea928293eecbc11a0000000000000000000000000000000001307ec99dc693d57633dc04929db287fa7b90ceebadd28ac4ccad539e97f462562fcda97d36496bf5849e1acd3ad242b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e1d7848271fca7d769adf3d2395a18e00f08c7cd68b38d02907804609200a2327f38afad57dd824667c51d8de83bb3000000000000000000000000000000000ab958637abff351b982c4110abd717226e4c105b046d61ae84d44eb3634ef29c226d5bf5baafce314981de6bb90526c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000171ef222bd35366a7e3338b270c660e614927b23edfca94188690ad6194afef8e27909e9c2c838375258177efb3aa0b0000000000000000000000000000000018c16ccabbaef85432ca28290773c80dd92455c33e5ea9a62ae450364f25e083c444a31a18d113877971e18b9a99a6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6f398867244467c7786dc4ac5d464a31d3787b41e88aa1a419d10acd58277208b4b0d3545490b9c2d713a6cac27c20000000000000000000000000000000017ad1eefc1ac1bf9e0c54a14ab2e14333bd325be2447c0e6ed48fb733019f6c4a8e5f59ffe8768e977489280cd2715e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea993fec56b53ed68f3b61a2278d0f4f3bb6104352efa3df09a6a55991000c6e66ae3fe4b69db84f938f33b59f541f6000000000000000000000000000000000737a52e04dba5fabeac7193d52dd5857c84115581a7db764ea2e78e79fa27f677d3032a05c3045613e3dc7d418174251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090048c31e9e06ce14757b304d3b55e63d19c08dcf06616558eba80419051f23ef82a8ef9e04e109b93305a19a12f2a20000000000000000000000000000000004270beea1b5daa5b6adbe3b3db34d6d673f65789cca2ed0bca5eae56d90ab7d1a1c45ef9e00ce7a866d5fdc71a23cc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e2ba4ae3f07ac233518eac4d9c583cdc3688cb5c9822725dc0e42f88c948404d7e76c37f9ea6537d5c226d3b8db99a0000000000000000000000000000000017cd40cf09067078aadeb41e11fdaab3c7e7f2229eb8f51cdae932f45865f14217988208295fac7491576f00d7f59c7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b381cae23f27665dee91932c327b4c38a439ed08f7a2d4007bff04edf72b7e9617c4427c2b1ccdb01a43294879ef04500000000000000000000000000000000073f42604df8a5757667f534cae4e7f44f853c94f52ea72847be82af09b23af5dfac373577c4d21a095b9b13862497411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018634df6012923147b446c084718d355b329f4a43f8ec2ad46b4fc14bf960679de85a2aa5347e806dcb1cbd44490310a000000000000000000000000000000000640a547b2098b0812dd3ad883eb3b9c53198b487b68594007e084ac70c716229aa53bc8c37b39e96998a0e0cd595c1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097df85fc903cd4288c6b682d581789e386fd74addc36fceb3cdb184536b6c2bf8c01c73aef75baaafe776f6b98bd6890000000000000000000000000000000011069db7f6c46d8ca62b1f67280c3c7afc5bf64dab5292843d8235dfb47b3377b43ba46f8c575086a6b95f730da7487b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168ea9eb33c2d394e8b68a93d01e9c58bc3c3079540363a9a3a7531e5c2ff57889236c1daf71930d0d19f4e89763f73800000000000000000000000000000000044881325d5bc0e981781cc92613ddcdd066e7fd5471d1111c30f6a3754185cc20b50744e276da2d834c5dbaf152908c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3f32651782acbfd8e62ee758cc9d4407428e2176bafccd951fb0cb21323d0fa6a7c8753ba3ca136efdf12e080bc6fe00000000000000000000000000000000037c66bc55dcdf376086e2d2d1499210ffceaf3c73eac4fa98d46e99291319d0903b386fc6047d5456d8df089cf15dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a67b20c5b23e1597a5a1aed5f20523aac6646f80f34b22f5137ba16c88f7194ec6ab3a87d6dcf1aa466778ac7af6bc0000000000000000000000000000000007b5f3e65cd42fef6db9a6969f296f931f83e10912a459377513429f1bf32aa19861dd98e0ebc3ef92396392093fc44f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000153d9bd9b5658cd072674eff31a0916f3b9d1eba2db71f59035ea1b5013d87da5588e09cb4ef129b5b4ee03e84176ee0000000000000000000000000000000010ca3c087b3a78f55e3aa476d9879fbf4cddad4290716984aaf3efaa15837712f2855d825f69a93e5a33b62c8c77baf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c8f72f625afa983ae57929ae0fe74a668719c7e10aeecbbc11137437359a5a0bbb72c3f6dd6b0ea09717d2ac1f3eaf00000000000000000000000000000000017fbf8ca15319ca19bfa4a4e560d9371ba7a5b7680e9fda75e2dcd4e5e87380865a6662f231ce194c6cf3dae38215371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c2f802fcb22774399178729e803da4c26c5a403cd7bb9d40c4bf9699ce55bf62325827e506525dd0fa46e5dd70376200000000000000000000000000000000144ec492ad03b62baab04dfe1f5ba6a30a40ab91947517c1f7fb3eb672abdeee1484e318c44ecc86f0e97f6ef5049c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bfc52aba0aae0cf6c114e69777da40606433b54f1a1db93cda6c656d8ea7586dedfced3a19d4b1f16030fb6d0024490000000000000000000000000000000011f9a04ed4386f64172db388565f8fcc3bb24c1510a629e4866951453d595e4c15de15ee22c583502c87e62e1c4a27631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f629b8d2246854ac5247f6b362e2423dfd04aade69d4d404ef11ddcc631e8e155a9d98f91b2aefd01e8e867fb1e4ab000000000000000000000000000000000c8cfbbfe2d6b43166666746d174d9c15dc8c59f3877d6667642ea7e53a366eb099ccbefaf63662ca09f82719f3e57aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121295886baee2bf7757a1ae44542700a635074461cb43b9f247b8883adb1dd4257b8c507682c7d37089b07f460d65a80000000000000000000000000000000003284d6070f7b568f85beeba1f7ace3707856796f4441050ea2daa2fbaccf3bc963f07aafbfe08e858c2ee861c442c021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b97ae0cc4e755f7c13c398242f0e835819be8cdecd8010731ecfd3dd8b6d7d0af1302889a9e25479ece8c68344ba01b0000000000000000000000000000000011afc7d51d8e91628be8d8dfd2af4e6e5e72e5f8da5b289e7a63415e8a98dfe5cb8125b8214f1bda68e12a9b7d43ffc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146f48c6e54923484e6314dd7b5116a208e0f7129a8bbae36427d2e7949246b4e2dcab61f2e9ae1a2535c64974ee0270000000000000000000000000000000000d162440369cdb5b1159eaa4012d2e00f4a0f06b9bf2e4ffb7ba97ffeb294340561dec66b1abfe36f895c38f41361f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b84c410178ba1e4c4623b5c0f60fa0e75e041867dcea95d7e3b484c2bdff5ee2a1cc471b222868332b1fd23d3e9749000000000000000000000000000000000f942436ddd1747f3102c5ea5152ae2e5430c8ed5debff266d6a90c4dc175e051d9d562406e6ea2217a6959e20c22de51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba526fa92809b114e64fa99314b8181cce9919566b86e95d4833495bb0815b1c444d2a1dd5a77ce1bf86b9b61d936f200000000000000000000000000000000046938538113103942056a627a508c33ba201c3a7a6a57ee69005b26c19da8add6df00eada5b75bff472760b7b89552e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015313865333b896364ec7ca0ced1fe99c52cbed33f93915f3c362d71bb13b8ff1c32b84bc25da68a21bfdf63d9556dd000000000000000000000000000000001703aa367cdfd16e4cf3d117c99222f19f37f59822caf1c97df52d5b813a6a9f6ac58a67a5e35356121dace6d2a7fc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ef0ff059ebc749971114f4bd42f3ad760fb49e45b4691aeef816dbef5f37275260d50e245754750ac16cec8cca45dc0000000000000000000000000000000007963a2e356324a1b46d8bec70642d525dc0a97e6b7830640fbf1a8954291da4a9f5d3bd40fec971c87754369dfa5f0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148c26d5e36ecbf6c961d9c3c84c28c9cdc7545f98e3733180bbc786f3c5cbec1942ba06fecdf9219ffe029d79eef69300000000000000000000000000000000114c67c2d34ba9b9d283fb9db8ca40abf3c0183de46ce17bd2217adbe13baa245e1855a5eabecf2493fb744e1392c80d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000661e1b7916472f79acc694a370b7931f6b6fd13535327d6e757d7ed9bc6255e7244bdf28844db674b989f33f8841280000000000000000000000000000000008c8af13339e01c69275aa77fd84f0735dcb0de73fc33967edae819484f3208726acc4b4a9f31b9829ee8f0c8193b1881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2fa1377b58bb5669c93d4d45c23c3538b55c2d9c270dd899aaa0d7a57da003973d654eb173f92ad07f3facf27c4ac10000000000000000000000000000000009a078170c1625429ef432a1f44173fb2f5dc72f510326ab65ff1bb66b07b3eaf717488e2b2b090387df471e7b9db4df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b6c6021a9832d5936a120895f2761614ec31fdd148974d4eb60309dce03670e9468dc56100db920d036c1d5751a5080000000000000000000000000000000001f8ef08d930ad076e92bc4fdab39dabf566d07a6aa0aa70d66a805ae581b24f7f3d7e39e1ee920c3028da110f03213d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de9befd46cf1ad2849c07238dd7437eacd71d8df36b1f1241b75a17f4d9872b746804814fe10a6f18501a8a4f8cd44000000000000000000000000000000000a4375fa31b0f4c75c73edcf1864c5859058305e0de915e6da682532d37663085c8fbf92f22148deebc84da53fa241c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d45b05acff40a7d8d74ea5f83af1693534ea7b489a065d0cfc735f2a3ab5ad31930f743d0c48556cb3cffc4a6b891190000000000000000000000000000000000ceabc819d92aef6a63c3ee6c50f1f988dee1e5de0b17efac5a1285c5aed0342d9aa89fa641df499af64655ac5861151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120799e4b1f8ddba887942683f441317874515e9fe722bdf5b575fcadf0687eb5ab1c333720841cc6b00a2b4b56ff560000000000000000000000000000000001959e728c8719aab9c9b519033d35f173e904109b7a73996ea4f8a46c3e5834026c5f6c82e3bc39215b6154e61e4176e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c309913cc8fa478f7911cc3ce4b915fd2ac29c2cf0d53cfe00bd04ddd8012e5c73bdebb8081b702c6c2a44e2b7dd1000000000000000000000000000000000e8b7e4d5601690f91a20c1d47ff9f08855944040c54e8b5986ce8fc3c3e53b955e0615e2c2fe04472bcd552ff2e01861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d28c9f1ffab3973a89100405d697c06f98d51d8a91f99415d5690069abeb912a1b7f9429e39cc3198d9d37b0e1c073700000000000000000000000000000000054a4d33d8c0393f98011eb94231f6883054c2b8b702b56d128218a555d0cf3dfb128d0508a22b65017f818d686077a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036af704eef88757e451b0cf390ba0186a961aee2aea7808172cd516e0ea1a929a8a4d591a98bf548ec005f00299f1130000000000000000000000000000000019479829047c50ca69a4b33edc23de1d81c9a98ac2817069b1d3f0d618b47692f580237ba88c5555bc37276739a4d2821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f16db8311ca90b20189e7e437bd3c883e63ee584fb3e747b34c4189355287421dddf4d8c9ab979bd50db29ffd3349f0000000000000000000000000000000018d5c39c167a331d583e16c713761e7f8fa0fb495c7f4e3a2eeb10e949c20b123854f9e31df5af510ef1fd8c058fdf2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43d59d34e97547ab696eed1b99371000d3958cd088cdc4f954c420527d51351efebc7e680624494c4cae548664d735000000000000000000000000000000000a083f701851df77eb70bc05dfae6378d34a8cc466aeefc208b45fabfc192a32d14af9422f93bc8f45321f3f3a11755c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b5ff1022458ded52797f632120e4f25831ece08c68a5b2e4ed600d5ae9ffa0f187eedc442a0889620733ada2835de7000000000000000000000000000000001963c7f98bd579e5c822f7bb3adc50440f1c2f35275beac62e4900bdf918d1eecb2d3de326c5f4727373341eabeb70511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ce068d7e92761743d7d2ef0b0209be2e6af909ab5cb31b00e5051cef08bdebd3703c86d9ddd56f9e4a0550d7f90db0000000000000000000000000000000014f2721e413eec9f9ee73554b1f11c310aefe359c77d792768e1a022b07f3bfd8f0b0d72c73c9480a03535f272b2129b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001691bd31f05952aca41c7c4288d1fa9becafb7dd97195a36412199c4fff9c52581df526ea25a28d897d413383d5becfb000000000000000000000000000000000e8ab7bd4311ab78e76f5d7e5e504cdf6e3d7fa0b31e693bcf2339c406738c553adacca21676b484deaa489d1a47e57d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ef81c5ffcfffb8126b46d73e03a79c2d977f18215f3af5b0e1711c16e6e98a48363024554b5220044591983eb0c4bf0000000000000000000000000000000007566f2197ba1f80150d41b4d6154a71bb93016d5d4f14c3d16dedc5c50e425938e472c16379336a9217c676a3448c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165c9fb380549174c569d0f8cbedd333d873d839fb062545d0fe604272f88bdd0e16a65c9fde4e029048cc041840b96800000000000000000000000000000000016f37e931d1f8ccbacb0a7ef9644a32df6c79d980a7f824502cdccc8ba189f0606ba6f691aa2bec3ab600afd89559051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b28e11fc482195d636514108105c492bd557ca984cc4a02b152a8e4e9d92b338d255f8b4142792b43daf68cad78f7b4000000000000000000000000000000000c571f3828d50183452ed29ac99006e209c99c3ca369d436542493c539e92507d1b356634c14a23e7ae61040118018f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172349944a78777e7ec4f3114aebfe0a6be8b47e136c266539ea9ac83d4554d6465019e8201d6906900d6add7e1b9a400000000000000000000000000000000003e4042ac4353e9100029ae784b1e2af5907f4b80972d37b193d4b8f5f745684492a2f8a8ee310283bf4efb0a4c76c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061158decdb4c556c7339d525f27f9b114078833292d1d829680464e88a0d5b08e75375ed29a8d7cac3c827a24f93055000000000000000000000000000000001731ab9fc78e98371a3eb9618c755bf2e74e96c12e64626b551005d0f80a85bd2d0aa8836ece65df010151530871d8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd41da79f6a65fa52d32d0477b308757a08d1cfc71549ea7c89af17c75fd1bac1d37b051f10d9b21e93ae1f1382dbd7000000000000000000000000000000001110428ee61a888939d6dc767170e84e91e5adf4ff76f4b925925015d2f12b1720378417d81c0576010d7dd494e736371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000848e4fae0756dc12386104c599bdf60e795867798e3ed36b6c46b3eb92bcf7aeedf66438e037dcca22dc2e42b304e3c0000000000000000000000000000000012d635e6936a60a66585d4bd9fbbbeafa024a1897431d4957a35a912e2558b0162538cf8f012c152ffac758f8b691ea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf2e0c027acd16e14c66692a0c264682cd0e59ce492f0d76b3e8b32a381ac1aca628c9efb6a76275d0a5b909ab4fdc00000000000000000000000000000000190bf8ce0cb0c2a0b2e4fc153587087fa8a36f2416dd1a070d6aa374f185d82adcc5b66f66eebf359596da234aea7e251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca28684198a8b3228d9c95cecef7b8c9a741cff807fce559644a7fb2ea41b4a85447fb24420fc31d0127d95a97b8d87000000000000000000000000000000000e02fa43d5db249d3f764a621d40fd4fec3daa9100a51c48c3066ec1f3d8102df994169e66f15326766e521dfbbe8e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3623467b72ed7a387633886b1d7989df973d15c68748828eb8325c8cf1e4eee75f0c57ae36d9909e8036f5dfe2e5e500000000000000000000000000000000117389d123cbb614c27b503458de53fe51daae7381f63aeb04708fc8bef0d30787d380048d97f49c2207f98fc87f83df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015809e7720f15fcbff51ed9e1e808e1d982b9a931e79d4417f03a3330dd64865c9b0bcfc5a5211eb4d6af33b2be9960f00000000000000000000000000000000159cfe3711c51b53c2c53e1dace3587a4ad341b92a5ace2d12e912e1dabc73c41ef1a6e766d67b53907476eec281db4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b8d266b3054059a835d162c69fa93b448eb471e1f1a0132f534fb5e2acdc5319209d54f400dd7b44109909003e200400000000000000000000000000000000174790f3b0b36afb6abd8b03c150ecc8aeaa9ace4d676b82c4d2e5c8279b6b0649d9dfb75990e84bc3864e0bdec660301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49e6661c53f4be8c4c8d23a4accb54bc7ba31eb8366713cb7b2e04ecf8d5b4fa570a591139425337eca656f68a57bc00000000000000000000000000000000085a90a20537be92aa338bd96bbc8a2dcb625004f6fdd1d2ff97ede587be843fc5aeca3dba036ecb9d093819b0b99f501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040505a517e14e7f14d1e2925299ed1ff0541328fba22441aa822879e947a2a8107537a90ee3fc51758e2417f66cf15500000000000000000000000000000000084c14d86e972a21448864aa109f32c85529c7a2c3cf237d94147fc922f2c3f557df05d21a5350229ad9ad9a5b3a53ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dcd08f39a6447c27df658e3ff81ee949b0291cc791853a0a6561ef02a1d654f775dd908fd3bdef520492d9c35d3b0800000000000000000000000000000000135d9b1b8a86b759169cfc2703be8e11568e3212ebabe4b1cfc3ea7eb60915de8cd2b27958899d814479a0252e5706581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bd0d71f9aa7c0d77bb7791bf3af08be3cba4758e059a471ce5b11a3a7cba71b38614692a499f7524ab8bed031e5f4a0000000000000000000000000000000007f12736be3a4220d2600f2aad470e5fcb925148e356316d5040bc61eab7fbe5e05839292ca7f973c409545ae6045b361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016728a052de13a036742bccdb2be7171dcf6e820bc566ba7d3168768e49d0749e536d49676bf548105ebfb1416db84c90000000000000000000000000000000011146cbcdc9b1772b7d4ebe3091a3c98e620ed51ee1d296ba116f7e7d5c864d37c8eda23f0a7fe5972060cff73f3bb901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d8faee7092c5d9217b6926f46b70ef18d9058f0cf3ec93f915922f8f6f6dc7a87524ac76d8540aefc33e71dec493cc000000000000000000000000000000000399784e638cb987cad3bf60b7b7c0d5c0650f94cddf9229b97f385c9270804b47f9856a581bfa100f911a02e87882621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b7fdbd91a9bf084cdd80dc80574fee83e788dad84049fbecf0ab0930e6fd3d2a9fb60e10640436a2df594f9a387458000000000000000000000000000000000e009c7a903d267feb659ccd5d0a2e71aa8c98e668c249eeebb4146f8cd877dc11621b609382d9afeb6e3388cd76db701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8e38fb80aea5e293f3c2de00a002f113d1f4d756f39167951d5160beeb7be34088eae7018b02f9b96fb16613e272bc000000000000000000000000000000001554b36101a403e1c465b2123c9fa80997243b33cb7b0b678d6f578a55a2cb45e94326087c53c6dfc6af9f98d07ffc041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d701748f6dd4710c931efc26ab797bdcc32aaed25cfba60052fb9f01a1663b98592f35a05c6ab67073c73fdd4d3d54000000000000000000000000000000000bde0cbf90b70c9f1e7b9acb4cefba137681e8cc6158dcb51064adaf5af32803f59468b0ffe24e0200c8ba1086539ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a46d294852c301a9c4032fae4630cdf006538467d9789f237527d836c4d41fe98f5f42f1128bbbbc1dd39d5aaed15f000000000000000000000000000000001880b395967f991d7e182a9c110d2b507c92635f5ff7225de8932492e2bd9f311cd9ebb9fec26118bb77c31ee59afe671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cffa994a209df15a27014ca485ecfa96d7208187707d8a64e6bde1059005d957fdb5a6b43ed9a07d83cc730d42d60c00000000000000000000000000000000176a5f0c4b33931db5a3967886f14e2a0f98d99089c21933cca4e0c58b4c4b9b7ce56ed1cf157e34e149311e9d0f5ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a178b204d5a16f860fff3f1486ce3c64478fe7d3e2ed617de627f1c542df555ca2e5c2172f9ca525142bc96d8397a70000000000000000000000000000000000b1888dbb2c1aaa69425ecb6e7da76913f3596103c6081694da24bb35c5c372265783225635a55a9a8889aa69dc18651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032a6cf6330fb308fa9a50d9d57f20eede8d9e9dfb7bd101611d25cc58d69dc43b15552126a77bb535d7941c4f598bf0000000000000000000000000000000014dcbcf503ccfa3f11c4b49f4906915a075c38e74603129b9b7e13a4cb5d61e188f3a2059fe2ca3ec93846631e598a421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d26ac26b584533005d88f8daa715dc635823bf5f4337e2f1b1b3c1b108150d4855c36bce98fd9ab26a477b0d92a464000000000000000000000000000000001717be1d7d622643c1a5f55fe113a8624f23874f8d627d75c27f9619b2bb7e6114017b9657e799eb9b8e33e6b1a575851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fd6942675a9b5ca6b653a0d72508af61c2e1cef60a84ec4b74589c8f1845e640855eff3a860bb51de52690fc9f6f7000000000000000000000000000000001925a16fc58cb484568900df04a38002687ad764a9b0cc45f98e70ab50c6047fff2efe1e5f79bf150d7f404bea4722df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001954e4a93db320ee261d17764ee80d1b6e2364532bcb5fe6ec2c8413b08b41d15061b3d83752dd8a35391ee98add79810000000000000000000000000000000013b54a3476068070d20f9bdc4f22177fdfa3aeef0479cabb1f67911970c4203f196d5459a5ae4642bff23b3d12bb403e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000989ec55503cfb70cf1469a0e0211c06444bf21d0676cd6d0e1d471c105e75191215f447227e354c66812bd550273d78000000000000000000000000000000000fdc9e514828ac56a44e710d98a5076dd481293ff5122d1cfd7e542143b691352c1120043df13d3333db42412ae162651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095c4494dfa724832a953ace7de099875890b60e560add9c425317f5e8c08f46d13282918c3a3088432b861002c84bb20000000000000000000000000000000011bf5919188495b8b82721f81724893f66a0019207f3d5903074b8bacda46fa272cb400e14cc185bef4a5bb5a5f3d11a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508588409e75e8eacb21f6a0929aa89a8751e92c0a0c2810d65c19d49c29408ad2ec7600c482597a0d09ab66126bded000000000000000000000000000000001192f286d4603a3ac2478fa1661753d61c240aeab14b8906d8996094d38d4eacaf936958c1a58b7bd6d1c4a5f211f54b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e1fc0d95f058bdb92cd1950932f9da78dc8a703766ff3bd7fad2f8f5930fb0718953f7c884e1e133e5823f4ea50721000000000000000000000000000000000900f97232b802f0e0ad64ba28b4037aff89c9698e2f283ba87abd0f39788f386a44de47a072ac6398eaee2b518381171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008656dfd42487b616c0d6c1833e94c71bc520535deb5c6bfaad8a12b1cb6288243f00b8b5dfeff090e920155618dcb98000000000000000000000000000000000d920aa0b38b2c316a1bae304bd58f88437c0ac0d83ef2e17f229cce76e452646ef89b79204d8d3d3d1d38c7383a5bde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cd18015b13c87b51e87b5f2feb6ac9b263104880f8c2c1dd6664d7ecb822763c1a332fa52dbeb0f4195bb717db1ae700000000000000000000000000000000063899f04ee4f900c1ac3584d13144fb8db23caeb15b88341b0a30ad7a91706bcf993ce098a4f9d2b085ea305f189d381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d28c1edd08dedf740eca2fb8b61bf3e8e6601de10cf2ea3a67ecf6a3af0e63ca7f2ee4809831c2d294ce24baaf25790000000000000000000000000000000013c4c5d5717648810f3c10be05f8ac34bef23292b23aae0bfc11aa12ed1d71fc55f169fd611dc1796e7ef88b2ef328191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeacf66b2786c63ea50cc28de694b096539c4e13dbee2488f1502740bc88cf17872ac6c7fabb78075e05f0c78e13ab900000000000000000000000000000000020d72f67c9e097a516b896d57134424b4b1366a1b43684e066447fb0ff22c61b92f6dfdc113682d690c103653fcc3e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081aed9143c5a0c0ef52269e1188ac11e610853bd616f3aa7a6f534fb77dee8197b4ba9e1fd64587afaf3b8ad5c860a4000000000000000000000000000000000c55be1a246b598dd66c7924342d660fbf84220ae54c8b96c813dad06a81d509daa590a525cde77c456a99c4a62e0fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa3ef7d5fca8ce684b25f448cb57518a3ea69f7bdceb25101d80977f4ca259a7c340b2454f91c38f5a656bd16f21ce0000000000000000000000000000000002b4d4295ae6a1c977fc89df2a8ad4394a0787c361f4f043ae74881766e01e2c4e60306ab0cd19762353517184bba9061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c6347539caba6812f660f7d5c2bf94cbc933f109a78c87d9652733f4038f9f7c12b5ed7abb6c8dcea7762f95c88fd1000000000000000000000000000000000b24dc3e8788231a33fb3a301c4b949ab0058c3fd318911c5c905813561f6ec0df7b24c646dfc3db258c5c1de854027a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009592a70f5adfa7f9d201fd900d82d3c149f7f4f1271bcc8e365c01e956d7c15197f18a5af4ce2167487741791a65ee200000000000000000000000000000000024e2e045d7103555f75efc12969ea12bbd4196b1bfde2395b945d31fbd6a058fb247874291642bf63cd6b7c8910ac6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f475d96a080180909efe6b50a8182027a14870719af86364ccd0c177de5c9a4538b4f348b21ba0661d18a3d9380591000000000000000000000000000000000700ee3f78150fb3b6caaa34397f06733c34991a224ea661ffa131adbeae8e68341900164aa0e3f4e23692b2312437471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d5bdac2e8bc91a39ee1eb4070c8b9b8a421fec28fcfb5052d586e0e3f7da9c4d18ed56bf1524a4c95ccd0df1d46fb100000000000000000000000000000000187f6b2bde9ffe06b71581b5a9219c5adb2e6f68002aa904c0ddfcf4e0bb01b76b2d256190a02bcd672c6a789cee77d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001912cd2aba1a125004291ae2fb334688001d98986bc8c13cf8a425914a96c30f3dfdeed8284d717d54014a017742188300000000000000000000000000000000183069181922f57f55401cfeb5fdbab9c66c8dd9748a90a995275638012f337d2758edb8d404fccd6b7b25d59e9468d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001182e8bbc392645d1f928bb8c27b41afeff62d50455a792ccb403390155ee8500aa97551618a44c7c7799b59be5ddbcf000000000000000000000000000000000d25607f2671c2d67d54ca544f53b24d788cf9b8baf2ade998f3c0da3220a864dbbb8909144764a3a00615c39606e2851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29d13152b753bff6d91e071c8aee015e1d4fbd2ecc213734355511dddb5bc2b1a2cc39216e574a26ffb69fd8df1f54000000000000000000000000000000000558f91ab90ec9d4b2223daa6922953634099afa363bab7ecb4fcf0d428a0aea1e7698b57657ee221f59c5a0f1a67a5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001194e54f98f875e0f6e3a1471ee6792f82fe0ff719b20d6336eaa56a985b58bb2fd8cd4447a1ef225485a05638c86d170000000000000000000000000000000008f1ef8883a8a5d8afe796d862352136ff1f39ef61e5e51886b1a0ea415d78741fec47ef86643f34a05e907e1d1605431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8e90e5bbc31449fe33804d951e8e8594f31254f19e03b2ddae779cdd0141d6f1e6b1802a5165a260e876ba015039a6000000000000000000000000000000000fbe697a7eb4a06b66c7bcb5cc7ae5990988ab41423008b52782921848e803c86314abf2c5fb154006aac8bbdd42f58a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001231a789e88ceb1842806681e510d8cef71c3ed6e21f7c57405c5b6e3988fce6d8e505c5efda9085db9f31dcd65b388400000000000000000000000000000000013de640a40bb049373f95a74b87e2719b5e729a929e367d945a3ebffb45a5200bc4781fa1b10b9230bdc174e74b38081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835392f9fa067f5c021af0e2b295540018c0cd35ca3a54f540fe0eb0447aa5028066f10f417e909fdac34a76bdb2fb300000000000000000000000000000000100fffc2e520489323092a81dec2efe3fd855333b89c0e6c078274a9900b3925975b1ed17537fee170fb42b8bac092ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019180eea264e00a5441a2867b7f8c9733bcc573fc484b717039048da8f5cd58a79e90fd68686eb41a662aa522c50690500000000000000000000000000000000083fddcee295291ac17c485ac67b1d5a806c3000f4d8a6bdf9c43c1975662427e7e6522888c8000d7448528d472dba261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001813fc185f88462b7df9219e36eec45e97fe25a3bdddcb2a46f63ff1c02cc02975f39328770fe5de003e4fad71f84f4f000000000000000000000000000000001997b61eb0476f4814496a413b6b79e27651bf050a9d250c1fef7d5ab6316d29e60c6683a9eab4f21626c1977be1ea4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006de1d4e040ed66be9d988affb8f214525d51e7e742a60418915c0964964284df2d80e51b9a465b687735baa6ae7f756000000000000000000000000000000000d42ec5817831aaaf04a30edbbf71dacac2d92fd42e5c1d30fe44b0a1baec632bcdb94ce656eb8ec593ef664e82cb6f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e0e30c443c6213c5910d2ae5711db8ba0afcfb82b26fa5572cbd2479488af2be6808689c696e67fc6f3d4813f6083e00000000000000000000000000000000017ec011161492b402350362af79f20590ee156b400e49356618fa8f5d966d2cb4edea0e9fc0a165c0f242bac86512541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d92d2bc19cf3fa68b8a37ee1ca4a7abc1f4875b9f7d543f345fe3e669c21afc885d18954f50bb516039fa3a62db070f000000000000000000000000000000000b043043f55f48fb977b999418d353f48c578ac855cda969ef85aa3b3788dab84c68599d5ba1ccc1f1f2ef539e71a7ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eff1d79133d08684f1b9df108969e01af7c4206d05a4a60f63196fd18f62500dadf194a45732b84f1948cc505123306000000000000000000000000000000000c3df07e231aedc3ecbcf94c7678ea7e1d20d9a32bc4278b0f98feb863396115bff3708b29e482de889183777915204c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056902aaee517efb3b9b432ca72b9afa5f1b735171f29faf052aafc5f16fc1191caa0ab487f540ce54418a549eaeb45e0000000000000000000000000000000012ade4686e4cd9a176f0a659b1a76da7a06e06fe2f1f58e1d1713063051dc3db81710077a322a0141238177e0a826fd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000962e05107935a415c7de6aa361cccd12beede3cf2c28f4f443b65fb06330d7d8665deeed5617623508565d55b4fd83d000000000000000000000000000000000bd69c524cc5dca834feb945417cfe0b37fc7a769a6597ef9f7c8fee4b8c23c04865dff2cfe99b33f54117fc18ffb5e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000586e3f1060a2970f6218faa8eca725cd2f47b35a9c65019be530a12d785d3dd7017ede774aed700471130f07bb593160000000000000000000000000000000013f63245348078b5e9c2522e8f06e54194a0588e9d0e532f75a362e5c1aecc6e0f925938917741539be9729c8d3415a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125ebfd019f418710a871c74fc0aef0ef732ea4f4f597682b1c5b0c2bb2a1d018c05d3722f5bc78df04a8ee20616e870000000000000000000000000000000000cee157262d216cfc91946526471ddba396e755eefe5c3d4917dd88cb5c304410080253bd0321382ce306b756674e9001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed62af3ab11d5219643e84c366d47bf0108cfe09d6474cc4fbbbbaa7ba091568429127a1b0a36d9f98c191fe3feb9e000000000000000000000000000000001041eda4a42df7a2dfd7c7460d4fb4ae6ed0fe9a39fcf9a72e03e5469c070ce316197dab24339de0918e3d89bfefc17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ede3b2d8a3d09b53e446c6bdfad3f431bb58f9b19ef7ba73d83327d36345a9a41f396692406656d90450e2218f60680000000000000000000000000000000016f06ba41d8b8632d36dffb6fb88a98ad03a0c6c12f7886b9f01aea3d2f424124e0ea6af9839a54532e737ddda0ac2f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f55086dec464b616ab7aa8491d694562e9fb77b469c0e63e057569407e0751f25eb5aad8139c4f69e95e12319d95c0000000000000000000000000000000011fbe80430e5aecd7df7c3569480429216fa07a256ae80d2a5713f47299b19954c139220ed2f86e28dbd6b4fbe3a35351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4f00e6bacf98f6f9237f351b99ea307fe9adc23b85021f0ae4a31f2a726f1e6a7f9478d616a34027d66f9dda3233c0000000000000000000000000000000009fd5edca2af19b8e3dd0404922d65986af2ca2c2b9976110d7f520582de9703d5ffd7a3beab648f44a166b7c68b0c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e590ae68e16697edc724f4a2215940450d222cb65046541c7f6d83da33551f13f3db68e9e5eb1fee53068f4fbbb979b0000000000000000000000000000000010e91c9a13fd31f950ba72f98883e3bcc09538678a4fbea63034d525b117560cff911c118219eff6b7767ac001a493ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045275e2a1472b054ac828bf779f331cff064d2e7860bffcef9bd6f07442b44bfd5073a8aea4c87b1cb532c4a644fdc7000000000000000000000000000000000bea98f747139a694722ef5845eb5b1283404ae3885ebcb2d4b502abc12592dfd5ec709c2c1eca054b6996f9f1832b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001022fd83728aee92ef9e6617083ff851494db7f6685db97fd497180e70fda9475fec7cf25692cc7f4c2efa9e6fcf8a6000000000000000000000000000000000dec85bc6e0c0cd8194aaf49eb994884bf8228d72920ae9dc9dabe61ba1dd743f6447dfeed5ecebeb7ee6a301d6f091d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001560830a49bc8664152ecdb5bc3fc62ad7b80b210e7043bfb59895cc106fbc76e3d99a24983e650e47a8ae43d43f4b290000000000000000000000000000000007fa83a37be767def70dbd7a65d01d1052222f192e14716d0c41533379568a66fbf003947e1fafe83d035d18d5ce6c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001339d6ae0f32fe11504fd99b4297db2c51938674c9f58c3f569683f17b771df711735a9882e53d8a5b3a6a7ef0dbfee800000000000000000000000000000000071967edb11258d2852cd79c7e2f231b56e3748d42b9145f3f94cf909cf07e638946a851d0e5b9ae57b64133783562ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003805b77492c9e1a2ca329e4168b3036ce1130f58dd2afb94a6cc0aee114bcfd545f587a4241f9563e6e834a3d7d7490000000000000000000000000000000000df3d393b221d99eab98d605c184d653b993841a6f5461c55ad5619984fb21401528362abb343e9fc45a8152aad569381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ff1365558ac7b62ea3cf8959cee9855ae6e9737c495e97a91983cba11f3de74942e56587fd0db41fe9aab3eb05976a000000000000000000000000000000000b10da32d114e554d57692c81a79c7f1aca9d22b33cea6a4f7815a947b5fbe6ff21a14bc5f22bb47b5b138c89237940e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea59c0a602e25f1f9bb3d16ec0f663a232b22580d12726386af51a14e98bbc1d8b5f03584c255d5fa6a74b631ba1a5b000000000000000000000000000000000bf3b55a38e08b43d65d4eaaded4cc56a84ce12101397d35f0f8b22673044af068cb0f88f6a2f4398c02763fee8522231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dbcac6b6c59dd59a7f9d6c96c9390f7d02b2cdf70b1c94bc376ab255d233c7afb5c4467f413b4890d26811f021576300000000000000000000000000000000104f1e502be45816c22766bae3eca432e84de5a6c0b61353c35ed3969b32f65facaf0b084704bf3030a2e2a458e0f8481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008323909660026ad9abc22dc64ba9ad4b7a33c9cacd214a61244402d0971290dc39785edf65c4288a7b71dd37cd764ce0000000000000000000000000000000002ffb8edeced6150a221cdd9e9a6023715c95f947b77559415fe8231603cb19bc1266ba201c6ce465017082efdc5d0941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dd87b77ac04777e28951c6c81a1eca78a0269e685c7e8b4712c7b2ae819a875261ce59634b567f2370bced488b68190000000000000000000000000000000016583652580d0a3d5066c0ca089ae38669028d778cbb1f53e9c2df2144a10afde8cfcd56b9fe8ee3e943d39a023a97f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a916ee4c064aed3758767e103a0631f89031360ed8d1104eeb6b90dcef90f8b98a2460bf6b219898bc0c57012370d50000000000000000000000000000000018d1e73641e2952354334a3f9d252bf836612c86382ddc190efe837b5cb6ca0082046b24d4eb51a2bc53d4e6f2f578211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c7d04cedab74880e7343b136e84c0f7fd6c12e694d3007a40788d37be17443bdcd49991b3c37ffc0b1c8d1de6ab0470000000000000000000000000000000005c413e4f50bbb1124e56a2cc6ea8bf994b908835e5981fe4c3038c64c1aa62017915a74da9d1d97ee9731409a8f268d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001996d6ef064a9491fcf9f273db107846bd24c11ae20698b39e9db3b58560a0034d22f4bf745f6102a92943bda3767f400000000000000000000000000000000005bf07bdffbc17ece59dc60d3244ade2ce398fe6b1c825b3b9704bc7b2c90f4df6b36b73cf7959e6727dd118597690ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001182ff7f7b75aa47bc8da06ab32ddc64de3142181c0fa58c1beb554c31fd02da591e0ccdc4e539251eb56530a97b3df00000000000000000000000000000000129a39690e1849d55e8e02e50e23272e706c9e33abd8f587dc8b1c66c491df5ddfcde27e0965ae7aea252f8ca27415a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b4c447f4a5d5492f2c9ccbff8282f9c08a0bfdf8cd3c5188b64575b3131cfc5fbd538caca991179cf9f3e78084482a000000000000000000000000000000000f54742b7c7a370e3ef7aa5d08b7ce8445b0bc371333b195f9535e5797a5c2a8bd840bcb4d22269bfec52927fa0c648e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016440aa723e28ff71b637786f55c222a7bf700f9a22b064b839054595c87f00086d6682c66a42f654fe977bb600df059000000000000000000000000000000001296a11fa47488cefb9f2523e260d3fd8833a09e4f33cdea0f36c81cae66b7fc1b7c1a30ada81140bcb496fd2cb6c7f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990c56373cbbc99ae158217134722624434c5eeb12c78200b5dbccc84e49bc19aa92193295bbd944a003696a8e70bfe0000000000000000000000000000000001fe51e9e6999c101efdab04fc3c21aabe8411e827da3fce0de86392aab427be97210b412511af0f43d94954513d5d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c0a53de7a35d8301d2c4934bb5becd473e3a52464fa08070fde9b9f7e0f2980db82f0aefdc280da9e16407e6aff82e0000000000000000000000000000000002f5c5a8f919e0aa524865d98c3f3161a846eadc897df925f737b9959dd03af27d7c9b62f481788f384b61466b9872231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2514dad591944de343dd3d092aecca56a4c73327494bee75c3b491ca8e0ff3789ab29e6c64c7e44de34e39991eca4600000000000000000000000000000000144666355234aa895e8966c8da8e9d6cc2db3c4cd7a61b4090243162f035b459b52a9007236e17bdceec502a5588fdd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b0e5249dd8c3dabce1722229ae81edd8127083cd973aefcac450242714ad7db5a8a8259211ca7a0bf8fbff159b79c000000000000000000000000000000000da31243e1e87dbdb1126a63a181490d8a1d764ab0dc184b0c3f14d3341363ff0d0f5f712737aa08e60058fb0847ce4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f72d14a55b63fe9194cba08280bbc96885e7ad8008e4678fd2c1d90318d47a5e105a181f72fd190637daa109bcceb3000000000000000000000000000000000cdc56eb293932f737bd82c159e930883136d3557a116e7d2d33b14a32abd7a987d410be3bbd1d4de4d9efab5ead634a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c8bda1a6b74c5a43d57d2bcdfab37a5c625d3713532e1895bfc5dc57ca977bbf419da62a5eb88b0603b2dd23348530000000000000000000000000000000008692842047ddab481c7badc87ab2846d75b3fe5fade05f37cf4b049f52b895a3c49cf6410ec9dd7bc627aa2121730c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003523bf22b4836dd845325855628e8022ce5833c57fe0e05361a8bbdf9dcb2a47d5a5bdb4201a01b7d9cdec23d2c08a100000000000000000000000000000000066c3c4fac131c9c6669c7f165b279a45c999124cb84830e5999ee3e67fb9fa54dc72a12c5c35782caa7b6f9f5a649621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4cbf35b5a2fab72a3281c6983072154dd81207f87a2fd428b85b56fc50724d52938a6b1206aec3f30d2af786709d9a0000000000000000000000000000000009c7ac106b64477e81e46dbe4bb780f5eb385e2f8916ce221bea0c7e020d7e72f078525ec19c81faace9ec323a70ba391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057744664ef45a90c2da37a6acd3c46225c2f835ea5caa2b54802cd8f7a31a15540b369fafeedd40a81c2646f6d2b7b30000000000000000000000000000000004884dd879ec6f9a1a28606047699b79d89133b4d55e5bfaa3ce98f8f3f1cec9998eed47f7be34ca490eb77bf8955d261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ed0fd8a30092058b31f545244daffa266fbb0f5f19a58c3fee5f7b707873b8627dd539034f9f721a7b04ef3f92da0000000000000000000000000000000000c55167d77b14c5112002af9adf1be7479e50fc942ebe224d80e4fa1fb1afae468ad92a535483261e1a9d3991f359f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3629c4273ca1226dbfbacb92c8caddb7be13bb8ff529959e75fc97ba710dc9e87a1ca5508a01fd9b3c65488c2048c000000000000000000000000000000000668650db07ef079d46f96f2f544157dee60322216de4c53a9d786660bf59a363378027e669a31f6610795394df64e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d3a8466096b93eb20408b22f2f739eb1b714d42ebcb82839ab20f680316bf11d0b717d6d521000a6f009579aaa4710000000000000000000000000000000012830f60bba15ee65a504dcdf22e3d4eb2413930c89812921509eb1c199a47deb3923c5a9de6c8b2fffcdf6d393740681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f57245779d45d25a4ae8e3d36aaceadc5897523e60046c802a2f4c5d931164e60002e70ede46da7a74891a182b8840000000000000000000000000000000000003c936cf96a9f07cd2f4813ef50deb178d6241022ab7da87f72916e3248c9671a5f33b92ad89552ee8f310076721d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af00eb49059f6f811e8d8b340ae959fb2239aed5f66b40520f7a1c60953ee4ede29ba1342fe2e4d09f3cd13dbe2f245000000000000000000000000000000001868cb18ca0fda70396f99124ba228f8ec1f362702557f450e611593f926568bbffb2b92336c1addf93b57c07db91a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d182918a468f9f11c8d8b8f7b2a5ca48bc9266c39493a717ce93af6a4acd390b53f50e927589cccca8f1821f8a53bb60000000000000000000000000000000016a9cec4e4986091ce3172179ebe61ef902b06886f47e1c2805fb462e994736db1d397db2f02376ad3885bb599b104731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e6910803a2b88c03d36d778274cdad9134899edb6d5a3809c2b93603a748d53be4dacd2f01864a82f97b79c8bca8cb00000000000000000000000000000000031ad6a51a6b1daedaa234778aa78aa1ddd5c5044366c4aeada760ef6441912cc863c178999a497a9b6298679f0551eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014820481162d49a13d95e930ce35471f813ba283649d2e486658667831d013ad5929d2b9be872278815dd79cdf63ef490000000000000000000000000000000015f7b2bb2bd086ffa3c6db139c5e54dc5f8380de1181ceaa21b2b5546ec9821887436d2c788cce696ab731a5b55add941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15694db72b174e9db75e511aaf8974b998519bc1612c9b2f42de7c70e832e84c6e91e315b25786f4e4be62b1bc73c50000000000000000000000000000000006aaa677139fbc25f57c6f071bd47db739689f59fd7321692571da5fb3512482cf543b7c29a383569ff2f11e78b02cde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119449183391aba016def0769281f8c5183042d797ad7be09146f6b19de09c46058f72c8c366eb2e3b55f49e4510e31800000000000000000000000000000000044e2fdb29aebbd197e14d0d6bc7f50385ee6bc7f8c0c491b96acdb2b450703e25942ade2fbbcebc766212f145fca9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010991b7c9f097f734271879ae2d792f9255be74022b883149e36e2b26a8f3a901986c4789e7ea8b2d306715e04cf4693000000000000000000000000000000000605569989f9b2107163c1298801bdf619065b4cca224ea7e054c8db2082a61b45941a6fa0685dc9686b8ed6cb8bad0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054c8061a1e024f45d4088ab6f3db03b5f7e33f80e85983f98639548ac3d3ba315ae4fa51d357304b0df613b142182d100000000000000000000000000000000154963f12c9fa4b4d441b4a5a2a78fd2e48a745c863208dbd9df961f103aa8785e8b75a7b7609a91c2b1fb763bd223a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2426eb525958e5d651f72ae7d62c10ab67beff7bdcb0d05703c8a1e6591deb16dec21673cec2a5f08d3727aac8086c00000000000000000000000000000000083380a8ea30089bfba7f40c8530a12d1d088ada72d3ffa3dc17cd82ae6d8b533bd3a396b1a21410a4c2b922d3c52eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df4e208a645db5e63bbb2f4693b4de328c12770476200aa3c64cc9989dd00690bf915fdfc9e4dcd73167f7a54a95f6b0000000000000000000000000000000004513d54e2ce1a27ffc0242e48db1fed817d9f8fcdf6be0f1b9ba8fd873f6f0709014ab244070b501a93589a6710d1d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc9fa3eb9406ab8067a2426ae1a11b6b2508c14607cda503be45eb6b7fe5ad53b105ad6660687e8bee81e948a57dba0000000000000000000000000000000002fa2289b6784c1a285eaae9fa9a096b140b7003790e3e0fa9178fe2f7a80c7fa0e12e51bea2c7f892d346d8f2c010311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191acd79e783f796ad03f65952227baf1b8dc8eb8fadce09008953b2c48ef8bfc16504c1839ba354450d0d217d5e86480000000000000000000000000000000015fc5b9db2ae4e614e6c64ce64fdd585126fc14357fd0bf9f7303ec1a2c137914554f520a51907a502e0783fd6f2f23c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148233cbc88d035b2d85a24dfa9a2b3aacbcf0e296234be6912a7b8656b7595410e96479f1eb4dffd6e4ea5ffd81aa760000000000000000000000000000000006f227844dd6fe6633457da716e747d8fe0dddb0e37d6659691f145b6e7964c41766c502f50982ca3709987a1f5777d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b86933f94918d5db737efbccb31600c1e979d0c4074c489a6734407407bd4716f0dc79683a1396c81583b2369795aa0000000000000000000000000000000001734f6bf71dd27c41bf909352874658431b71c1e8b477210f1ab32bd4d02e5945909ba3071be6d5c8f6036c5dcf539f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001486ebeccd21eddf6401f5b8f1a4e2613a2b50aa407928cfe76b398f2a060e99d06b2915bd13cabe385493feafcfc191000000000000000000000000000000000df9b94f3e5e3e8b81b32621b4c8feeb1fc199f435237ec2e4b7b2031e3f9efcbe29ecb4ec5ce2dcd96b9326038f70e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098db46a3240d87bdaa8e7c0f04a1479ec6e2781a4bc3b77b19965ad5adcfcd05e6e308ee598cfd11dd46857235efb9200000000000000000000000000000000154d33cb52a8fedfb3dedeb04c036367350f4bde8a444b8acdfb2c1fea527487d40464da50ed6b9b1faa6fcb212aee491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cf952b1761728f9ecf0e71362a8f224d61436c94706377c26c3a702417257d6fa480475a8e30b028baeba728349f03000000000000000000000000000000000333981a3e4121615958623eaf5625d719a07f75bda7242817536977a421750fab513e26b28d416ea16965623cb8ff1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000840ca623954154217c285ccc666033a1b27f34c3a0fead1deb037af2d1a3507d970ea43a04c4e11069717a1691657ae000000000000000000000000000000000e6248ddabf3c3cfe2a787cf898794c4d3106ee504fa91df76f59bf0ebce4b1956e8398a702498aa22868d51e96e39ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f90dffd6fb19d7c9ef0bd14f5bca6df70a0731c9f941d00ad0bd27d15a1708014c3679a8233c5b4354af1398ea478f9000000000000000000000000000000000cd98d818f57650d9c65f1f8484f2d4c8fbb79fd6ed33947b2161dd88f4a3db81f0a3e17f3bd6a0f852e881399897a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ebc1638975768a49a0845cd9a7dc4a23642f0796edb200438e9bef6b46059d9fb9581b8ec3597fbf54eb41453cacc2000000000000000000000000000000000d43bfe311c0d6d77208304ed89dd0ca230551fc4ad1f2b71ec8668ac3968e034b2fe68b78d78ee1732860f30c56808c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e89ba33333114567e974901dd3579c39a7b6940ad1fe1911637296bea356df9582fd86578283e3fa7991e75de0f5e0000000000000000000000000000000000119bab0d071b6a133d121a425aa675c4793a2f073a9d015b50102acc9d295a85b7ed88fd0825e800106af2cd2bca661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a8ef6e7f83ffb640872168eae078e12ddada9f0180754243f880adb340a6f0bedf56fc03246dd6e6346198bfc7d778000000000000000000000000000000000700b9d7a46528bb36029d6074aaff74a09c471cf14efcb5df4b228b2e72bd5192a7d192c83c537fa065b8ddb5f7cb461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcef72389294ca7f3236c24278f3684630338882ca0ba24840ab6c15772e3d103f797508b726f9283a00149c3aa532300000000000000000000000000000000053590dc949e5feb3645b9d93547dade2b4402bbe225303e6ecbef225c6dfc2274f286249b5b44b3021e550e42113d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e9d9a09df7cdd15efc86655dbc4424a5051614e717431320329225b70a8fbfcfd4e421d2dcd4aafc55278c14db611000000000000000000000000000000001605644f41380d8ad746490717893e93f008bbc1e58fc31d2021675656d0b7e27e120de55788eae6003d277286bc90c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ade08845a57faed440537f34b6053f8123eacbef95c73752d9f8c1e20c40ebf390d893c71a903f03befbe3e7d770d710000000000000000000000000000000004340ee2170c0b14a0bec5a2974b5b4339a5e9761fd452f00e04f55c0dc6751ae70620115aeaae9b563b2538533f1f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013766d1cd7d16b169e86dbc089a5763716be6055718cf76d692b5fd413a9c7d99d930465a3fa77979de55c92cd83435500000000000000000000000000000000113710afde43c6f2bcfc7833678dd673e1339cd015bb21643fbc45c3befa56b8d3b8ac4cc3298d2a82b23f1e8fc48a101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024bf65ea632d69db0a2b583ea35ff94df4fbe94b1ae8f69ca5eccb981db64844c3b492f707e1ee4d0b965b9cceb27340000000000000000000000000000000000e66119af9e9480c94a3c95b33149b71d5dc5f32bc6bae9db6b18d589e524deb5ac0726528fba6dc03d04cedabcf8c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037e0c69dfa9afb5b4b5c2d18042d8272d64d4b4d5f122b63dbfcca69b5d7e39517c6fdc2e05d479616dad76f23743e60000000000000000000000000000000004a06847f116d21a179788dbe9048aefd7c560cb10bd46cde111bc96a4ad5547827b3da85e24bae2220cd38b8ff90cbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018778f6fc719f726dc847e3d8ac2b9898fd2a9c71d964c1bbfc23f3adbf59cb57db4ab94421c7959d525661c4f9fc6780000000000000000000000000000000010ffd434170e556e708de926bd4433653b8801b90914ce33d0c85d75cdb9d9bf453b38964612a472231f4fa6866dc9191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018150e7231d9da2339716e770e38ea422340c1defd4f45ff39720193758256d366d46d97c9dbcf5923247990baef4d40000000000000000000000000000000013f384f80e62aea06946d12d4c0ce7d41e79576ad2b92904c79d379bd4d896477cc0851d7411b8b7d8054b214b48059f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a745f94954c7d992d5537e086a4a8ed7b1791851b7c2b73ce9b27753c7484a8fb157501320d2526742c44790aada5bb0000000000000000000000000000000009864abb1d2b1a6da9da3108dcf6be8e342988a56deb1aa744187c23c8442711d695b7d7c8b5e7fce25cbd5df8c223f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f705312d68ce0998ab63df7cdd98ad60cef9d081886e323ee179b6aebcd3bc4ddb0189eae8295ba3b8aa6e45c9746100000000000000000000000000000000088927a267c3dc7a26be02f6086015ebbb7df74d8c262fb9e2c6c7107b10ae3ed0f3c252267dac312159ed34647c8a7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c93720b64e970f3672d13ca5136e089fd6ba66d8131545222f835e3814e3cf11fe103d6c55b1b9aa810323ccd65c6e000000000000000000000000000000000122bca3516253f35e919145e7b24ef7541aa7ab8c581f77aff81d77e410122392937343d2817ab16754135ecb3aaa001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b914b4f2a92ddb540bebd7753103d806602ef55938c96fa4fad0a83cad6091181be2c0fee561e9a2cd4d475ab6e725000000000000000000000000000000000695fe5b0cef4bebaef02847502ec620e4b64eaeec509faeb464f57d1092e1774a5ea4fd6b1eab1f61bd014b7e47b8d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a5090a7fdd5354a3b2b8b87c7f1bbd4c9d4a196b92db76c951de103fbd5ee36fc46d232ff804f2568db4dace1a7c3000000000000000000000000000000000234bbcfae4f7618d506ec54200b24c21ad078b73db7589304841bc43e5a556cc7739b5009d2d8b13ba26e7ddf180d481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190f8da249d05588e675e83e75a9c5b5b12860cfd61b9a09b0158033e26664c1728b0f807808121f5e9e30a50b5ca5460000000000000000000000000000000013056b3dcb76ad2c18913b82df3f64c81710856b9e865f69cde8c2bfe8dacac22a4d0847d79a33c0ec44cbe27b6f7ae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97e79f9e5a3279bc83d24bc246536bb4d8a76f1bc1d9080da4cb3105fc2d86efd505b8d3ff2305d7f9876edb2661e1000000000000000000000000000000000be5791d4d8f30dd9b3d6cf8fb3ecc7ea3918bf2ec08d05e4abe4ab04955b9320fc75e3c4ee5ce51abc3eaaaa7a5237b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a13dd950b7bf1d07c4a56a8f77a0c11c8809cbe1ddb6167d429bfaaf38948e056def9842459d604bbfde48a41b243000000000000000000000000000000000a590c1990cd8652b5db89dd7b36dd4e15d2e0a310beecba92166d4162a2f0338207e801fbaf10eadbe1f21ef5eaf28a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d0fb4f341574f0e177f84a7cf08d1076811536252bd2c2cd589c581c256c7128da35b6faa71b6a168a7f2aed20ddda000000000000000000000000000000000706f968838c569c50d2806d6222992f80161631434d122e1e64430effde2b0639ae6a38b98de09b37171f82117d992e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a33189bb49f4e00bc2bf1f37025acbf63b1d9a267189014783a2e86278904e6e073738ecae36972354dfb2faafb4635000000000000000000000000000000001647d5d26dbee9e82a3ae49bc50f582ceb64fa8ea6f2ef4f8e1c5807a389249e975436e50bda9b14ea38bb896a4ee63c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037fde4659f3ad3a819c4a3d0d84ee44d8dadda75a85a55df0086aa443d9ce36b0d59faee8706980b58bc27218987dd000000000000000000000000000000000191233d0e2eb06b94db74db20d69f74e46106c5f2e0c8b8502bb9d19fd41e78c08f062d1c3943796e7e12906389df3261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f7793014f120a78cc129369c8d046346170dad8256d67c0bfe567d61d5e8be2e8e16951e2c82b30ccb105f9c5c1510000000000000000000000000000000000c76446134c04cb24534a6c25704f249bfd0943ae31794e16ecf4af3c073d0187061549c6c8ba7cce109ec2b841602ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ef47a315b8d7b1a374336bf74712653bdd80bc9b4b0d5ce72ce82a535cc4f8b71e9267247426b9ef388cd8384c97f1000000000000000000000000000000000a6a6e3731bf19700d4c53f5d2f7bad7f5686177cf8a171d63329dfb4d61c4335ba44aecca54a11a25b6aad966e93c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063666d7286006fdf948944493da4b9995ab783a513d4402e609c34fc74dc4ddb7b6bdf20ae075cc170d87d779d86998000000000000000000000000000000001572996ed032223affc2953afa3b0f03a32c1e54400497bb2f8f4c7d49bb8ec85602e4349be1c0682104420286b207841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792280ef2c32b7be58ff701c3ca77164cd230dead833ac3540305bfa093b08f8eb22d3948edfcb4d95fc00914ff2312000000000000000000000000000000000876658c8aadb4cc7b866dcf8377899f2709834adb1c036d5611d45048c48729795431d5decf5918c2349c94d63d1c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bf6dcc0965bd45c35a8580e3c3beb9e93aecbce2c3776b55a3ecb48ca1b56082c87538a1859ac795635cdb4477f244000000000000000000000000000000000e7f564dab4cfe7ead2fcbe8485465ad0ee0a2ebe544afea0a10fe36f616f43febbbf5fc2ac0099c5337bc039fef82f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007382994146d698985317128bd59138f89b596c51a08350bdd025bc5d8ade4adf74000dcbae2ded5660d739373e81b600000000000000000000000000000000026f1b55c2ad1fa0a26f507d9d3fc7d5f6909b53c8599cb16ae16ec63a9ae74e293687673f782aa7c8e6f5257a00849d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3d2daf889e4fe66c7079b3b2e3304a628dce132d01370de654b9119cc7755545b9f991946fe7b5ea6188683e2625a80000000000000000000000000000000017f43f939aeb777418892fe61f2945f7878fb92cc694838d6bdc183ffb8a50d6b54d53abfb1bf7ce793276d08229eb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000255951c3f935f7b3ff36b596308f30a0236a37200026b7553c540c0d3e188f037af8f1b3a4ad6707ec7a8f9a11a82630000000000000000000000000000000014322a8519ad669bccd35f85867cb8e06556174047cc74b21708c9011192d47130434396d4a92860a3769c108bede1f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4f6e3697cfe3138f815f5c5c9a183d171fd20b80d976a2b47780d77512a7efe7b3d3112eccbaabc0ad41fdc0146880000000000000000000000000000000000207443da4a3ba22003f9d046795c0a59fae9985410255e4adb3784ba4c39be67bb6d536d239975adde49f3b476016701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000090b500ddce8d5b6f0afbca4ff335ebb7e87ee14a6293711363d449fdaab9aea4acb15672a829303d8282f3bd1b288000000000000000000000000000000001885ac696ac967b533e81bcdee49622caa9b7a918af0dfb47e9c9d31da81c4738c4a2fd3b9be7113df89198d110737f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f05f942da58d5f645e2c995bf49fbad3b05d682459e182b9a90ab95df5815119df4ae5c8c06c4c364a039e2789bef7000000000000000000000000000000000eade2a2a36d8bfe3112d7890aec737150624bbd79b32c6b932a7d4402af5b89228eada5d8717efaea215714ac3901bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012930b7794c41b2038c045a4b24fa7ed4d518d9517c250802163fb1f3d85e6640a859029e287612b7e2735850ac4d6560000000000000000000000000000000001a99bbdfd991d241c0e2f4394f641bdea725243a5d0077c5a9fe62be31c49494a0840e0b09171d8e20b703322bc9be81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001923986c1bb94ed004bb2708d43a382853cf32c41c904186635019e1b1e0aa794a06203709d6d9d489b07b3e6d2ca6d6000000000000000000000000000000000f5dbbd42a835d0053dc6132dc496f049d9a87e43c8bf906de8d6ec61c939bbd81f2a402dcc9b1bb440c1d57a574cf901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030173ddf3641830d8290288c355e188a03c79fbfa9eecb3ac3b5beaf9c482c6ed21c1089be8cabed679c8a860aa1d7b000000000000000000000000000000001252b7cdef51880f8af24afc6c03be8219fc90d3fd58741c795b58b825a81c41e8fcd341fe2ad3b1f329006c33eecb701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175fadb3b46e2d0da951f1a72c63ca52c2008f3d9b6202ae5d0d2b231019fc4529c39e05df52a29fd2663b11abab2377000000000000000000000000000000000b371979943c306de152ca54342af0166059879c3e6f88a607b80df9b0e7a052b2a9a430506321617e3e8986ea9f35fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008009e0ade21bf039cbd3ba18ef2fc3c131cbe9e67271f9ee654eda01d5b637fc654a3059161e60e526952e16766ea0800000000000000000000000000000000175416490af86eba8c5a2f33cc6ff5d593f7364a2eed074f912cde28f86c247f132d527dd67b1dc9ed5b25bb05759be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052225c752f25a20a8fd60075f49dec9f9f990517fb04b5aeb9274f1cdb00f03f208fcfdbadad27dc331a6bb23e395560000000000000000000000000000000006c60d92cbef15bc696bebb951356de6080346e50c02a6e837dbe3de9208922d0038f47e3e74efa2c2fbd3faed61f7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c76a5fde3bb99046440573fdeee5bfb6a673baff56c2654fac726dc445f999f28b1a47d5df2b4ef19aea5a8e9a2ec100000000000000000000000000000000156f1fab5aad9dec20f87489f353a10945a68db1279f83eaaa7758649fd6370387e31a919f91c4d80501707355e4602c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee80ea62ed531f02d04a6f6322d25f653e5d17c8f8c85a33e149502b34bc6b3d89adf65da1fb64ff7b45535503717b4000000000000000000000000000000000db1d694d6f27247d282adce93d48d866ab4d79746b66413560fc39236480c12af5bf2ce5699f00af74b5701a4ba30f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c316ee4222ed6acafab06a9f8e0cf8e46e33cfad309d65dc255c3a4ccde0098cf942589c9760ed279c5787d2ac8b1a000000000000000000000000000000000d493087bf3fedbd0013426e65c34e44ccc5b0eeda236edf4a09ce724259ee41366b57338fa0676e5e810957803b75c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c395b81c20421afa879f256031e23665a417c6478577e7e88ce0756ada7f657ac241eb02b420213b3e08712fda7dad6000000000000000000000000000000001132fc47984aacb637fbce7b26d14d73818ec4682e6d9dd3fa222729d570a8a174d0e2e85b7e548d5ca61ca1d0971b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3a1fc6b7954459d0729e9e7f717b2edb6a239e8e8f082ddd486dc516132bf5be743ac0a97c6f546968a359c6a3c59a00000000000000000000000000000000164729bf3edf66bd171a8d777389bf29dc4c743aecd2c1fc65045051d201f412b6330cb87c97d32dbb63a4437ab116121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a446d4773e912957146625a34b4306a2cfa95f542a27de5d46fb3147161c7ca402fbcb70b4c0803aaf4765d686345a0000000000000000000000000000000016af2d460f197b9b60cc546625abe0ccb89839e3d77d57bba7ed6b0d36f69f8b13a9c1b972c52f60397a31ddafa9a0081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001033206e7b8568cdc111c648d483d83950191118810d2bf4f35a9d76cf5a9e0bec7940e36df61431d8f3e39b8a6324b100000000000000000000000000000000120e1473687ff3be83835cba7ed113d371c7485f4223eead64d8af33f79bd195e472f63419713570b9d9b422fbeb98a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ff0da677dbdeecd3bc694ef87c73c2d139161d7c7242d7380ed6dfc065534c0b3be6c0d1001eda5f52d623b30f4cb0000000000000000000000000000000004e95ff53cdba08ea69082d52e8fca786efe20113e170b0f0eaba0db07b3f60e42ab74c418bfe26b4438fbfb2649ca1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d512ccf1867ea5b42232c2c9c5440eeaceaf8f1f3d6e12ef7942abd9bf6af99b4a0457247f094fe52667b6bfd185e630000000000000000000000000000000001efcf1508c0472cb287beb7291652c0eec439da10c5b4b00108565c03ac4d8b14b797c376649a5c0c5592bb0b7488b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000861bcbe76b814e02be7b2aa836f91cf44221f3a618758b833321f2719b1cfec7e91844aeedfadb744fdf90561cd9cee0000000000000000000000000000000001ab42f0c2885a5f6d79a02a5d4ebf694bf151ec5573ddce9c3b413e30079ffb88cfbc723fb2f769bd5ff5955d4f6e761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122e8a2e760dbe1678195a5d5d94b9337d7a26a6603054d78f568fcc43d7bb9ec8838b9fc42e7282a7da4d2fc79cb4400000000000000000000000000000000002adfc0e53185bc43e54770a4436ea47e1c06df0471552f4828b3133c8d27f0a9f6ae28f27dfea4e99c9a12e17571e111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009268dc939e3b6a4aa60449536175832c97f39d4ea7d056e2fe8c9768199d6d0a1176059197a51ae91fa5053a67cb7e50000000000000000000000000000000015d2d23f629fd79961295f29fee3c09903dfc6637e7ea60629e6c05cf7d7c47a8e717a733a51864d04807dbdf2c034b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001716dfe8ff07ece1487faf1304ca59855527c2e27ac5f226385e000f149faca8f602774e7f20d8542af73911deff71160000000000000000000000000000000016d2fad8c614bc49f89fc8d26318e92552b0c77f7ba8d755a987e78c1e2c2852cb1a2564e649620721d60da1e3ffd76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa5a7ca5c1b22ae109f232c91413343c878a8258f9ea51daf4488875bc7225fc2351abbf0b0ffaf9cc44430b5ae4fce0000000000000000000000000000000016934ede20892c4ff736e319a48df847dae3deba172e51a84229b14b8651e71c7ef8370cb00559de4665d69d50c53c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527ac8f6492d188a8fbc196287cbf7f49cab49840a35a4f9bc3acec7902b402243d746c05a01cc8f02f3d0f7f4902720000000000000000000000000000000016550e5c0365f9c7e1401f6b80168a02f32b843f9c4e080f53d4e665429125678c540351d44ec0ef5e556da878d121a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cc1d1cddae637453fb11c9a9cc6ab0febb11b0506eb3b6725afd97fed22ba14e6f6796a370f7d1aa5b1d51c5dbdf01000000000000000000000000000000000918f8bfba790d573892369f2770842a307c4018ea53039cbec616c106eb2bb182bde25f2feaa3edd870d61485b39c8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114ab8c0552e1df94ef0a18f67d69c502c7fe773e2bf430e7c3deb3510916bef24910b2ae3d4be8708731861f9cef0c600000000000000000000000000000000137f8539645a6897d5efa34cc6e27f9d6f91a9406b2097f029af20dc2c8a36330c7348abe7c6dca5227ba40e0423b66a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001627f518ec0d2db3e97a1d593199e3c7e328f9960f4bc9522c6351b644ce337e91d62e924e3e1da6c8b25350dfa1ec1a0000000000000000000000000000000005ff49a77c895e0f4e4c249e39020a6033cdbdee00e2e3cfdd7fb260085bee5534e5f5dfca44de90d5520c1538b2ae581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da044c3be9e47f479788432d8113a38808ad6b18504206439573ce02703ecc53b0c5558db38d255c40f1414b393f7d1000000000000000000000000000000000e79a39f8db1a9394fa4844aa6b4ca15a9bdd0470856919b94a32a4fffdb3b3313baa12d5161b2829a9804a1719ed3c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9b542c2898aa6084ae3d08b21ae0de6d195b117d2e62162b06780d3d418aed9bae2d3743e4784d4142e03a748b791600000000000000000000000000000000175500c0dbbbee64aaa03c8defdd78f5787939467247d6f0a9021bfe8152afa8227213fdd5886f4eda4d2f2315ac3b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007383504231e05600c5905635d74a3543e146deb8f39e38c4540c13ea98588a5ed83589f6b705732519c4e7329b599a200000000000000000000000000000000067b481db48deeb9e1a1481cf671ea351fbf461b56476efc71121591471c1600815bfb1b68f6346108d1a0118d73e6f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001608610f70541e945bc94605180769e51020ac8728ed00401246bcb2d59e3ac7d8cb5cccb8138817095ba199380bc3e20000000000000000000000000000000014cda2e886238a8efcdd86f13dd62f6f53a2bb6022b7053da21aa41c7aea656297521394c37b3350b08d042aa74b25521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006723ef861f615c3bdec859e8b1d4b2d1685f7ddb9dc34dcc0c9f71c98b0597fcb086d7c320d329bde59a640e839b204000000000000000000000000000000000d806c4c4848dd50297e57c13cb0cbac3aae0dea76f8966c332203383ae0b8fd07587f9d3ba33adf2650decbd06743c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d300e4dc39fc1c6ac750de943def8f9e6a203fee72de5c562ddf5ecbf91a627af58e18780df265a61a7de240e628cc800000000000000000000000000000000182bd0cf1d22103ef2111539a37b12596fe4f022bf70ac705a14c9cae1b88f817ed881b5bef6a41d90628a04724653a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006959c55e13d0954fa8f3acbbcd779e1b3e31d020f6f4833e8e07493b7819a97ab7bf4a26fea8220fb2e85d3b32e7e1e000000000000000000000000000000000b224266b8d32f8fb68e722ea79268ea81511f7aeb0c1dca82076e1967569c04953507e800b0375216f3d62862aa877d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cea485569b753a820c4dc57860f460204f9bdfe704ab1f773162d6558b403835755657037349d29eea6a9ebe9b727f0000000000000000000000000000000003fd1751c31581d223173ce1ceb252ace9053ac24e9ba49507bae5dd6b288ca717c5f010dbbec669fb3a1f51597e13af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cb545ddd049bb50a0d3deb80b5eb687d8ae6c7eed2ea23feaa65007530a6501d27d3cbb371fed84178daefb1c88cc60000000000000000000000000000000000e5c8d84146f5fe2dc344b1bdd2b4e1738fa95c0e15143d3ba2f24a4de45b1f5ac5765db8d7e75be08b5da8fd4c469a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb1c6e52bb2122ebc123385aa25ba5e39068631a0d5dbe117f2cd8254f44bf4a80c561250348d38c5d41b2a9b4c45c80000000000000000000000000000000003dc0bd091f460be7c904310a2cc019b47c1e5dda048dca4f9a7f307a791daa3167babf71f50732b73ab0ddf7c958a661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086c2f52c7c7f096d18fbcf15d34f349bd365b2cf487b0979092c9f06dfd65a2f07dfb3ba905c39d0dc83a53e28cfd2d000000000000000000000000000000001138563300c37a436a629ac815c00de899e8d93d2470fd94cba04c1db754db56a122e0fa1d29730bdbb1f7f9af4093841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015301c870935047bde609d5d79e44e0821177b4ea9bed8a0657d85d45a129627afad4078e7878af5ecd6eab50159959d0000000000000000000000000000000003e07fd37b82a6f13dd7910db74639103d2396df273a8372b7289b52a9c8c9008bc3afeb668873eb01335da7e15b07561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5eb81b3cbb2d4322fd67747e2b71763677c919421b8178ac71ca15a06735713a87dec3cd293947dee2301cd181587000000000000000000000000000000000de3a2279ec9220fe5a7e6311589aaff3956846238886c9ff9fc61d28724da782da74b30fa6236c80f35907b11e6507d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011373fc32c6ed0d7b0f16ec8042182c8d30d1699dc2a8c33483d1f87f1e9216b616eb97bce398f5e2f09de6235b756d6000000000000000000000000000000001480a2b70280b00966b594bd7f498d19916c64575bc56de592d931e08843b56d5c49ee1baf0075b68ea4f3038c8e70d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d0beb2996217a25d9db5e18f8ceaa777d8041585ed8df4b4d6d6dd791428fd74df5c0657d04ab11ced38fca96d124e0000000000000000000000000000000009909da3932cee823c738aec036e351b12e1c28505fb53e9538a9b513dfb53d963e604268fb0baf6ff7efddfc41e8cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d205dd1a47a70c180978e1ac77f890302ad153e8cfec9d48b4f6c5f5b67e520dd3f8142ae83a998fe772da5db31c8af0000000000000000000000000000000005e5ab712c5d1b4af6828f09d55114f051d4b1f5b56ce4a678ee993b81b91a11fda058947e4de3dd9fa187133ccbe2b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e0b41d3ee2ced148f578cb483ba485953489e48fc4cff20161cf20e28c80a7e24b26491768a105cc7d45a7c5d767400000000000000000000000000000000069ed977784388018f32e886b189f2cc6f36c47ab406764b340889df86ff3f67f4150a2c566cf5456631dbd92ccac8741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100201a018c938e701f3d1aa10451f99c1a1535899328edb0a5308995ab83a4cee32f2dbfa7c84db02ab9f8a046010ba0000000000000000000000000000000018ed320c95751dbe30d5cfcc49770c0641935abf79c86a99d306b9dff726d5128265898bcfe9093845a0088a787c97ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008133282c3d0ca1cef416c581bbddd7fb5fc5df0f80fbedf9dfdb899f6c0130d1f5c0f96a1e087fc990d544dfd5230fc0000000000000000000000000000000010a0c8bba8ffd7afa560f3963bca116513eb60efb243cc0af13f9abf9778409d33c70d2c85616cbeb6c2afe3972f544f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b970a8eadbad775ff1b86278b2c5b97f9496e718f753156915f3c4baf4167ade2454853f283b2953d1b4d90263e73000000000000000000000000000000000ec027ba1760dec118a761d7ebd29e99a95bf760a7fc417687dbd9400105e143e72f5cda842c656d70c5da90365114d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f445b48336af484bd3058e6268ec8ca929730d5c516f3788f2320d890d8f4220592efc35319e57994c0760263976daa000000000000000000000000000000000d12b7f8c91cf6ce977ab40282ef1bef90d4253c833022829964fddd0cff050fb2b9e481dac1c48338f0e3331ff6e09a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d386be120fd7bf268589ee5fbdd8657c5a113628b4c562d672e186af9fcb08bd8d41dc57db75815ea5782902101eb000000000000000000000000000000000dc6758efad8901b429016380454254df80e66c6cfe3e6610c5d42f520fa5687ff093fe1722b3a6b6fd98b2b7883a5af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031fd82a2986a002615bbfadbbd4c5737970c94e7c28f5f03e2534f319c52e3bd1d5205ea75eadea8831e3bb5bf3815c0000000000000000000000000000000004711fa6b10cfcce554ac8c701196d5f0b95e62fd5ba8dc0750fe6c8f3b29a2292101bf037016360508522a7c822da171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009548d26310b6a3186c00ccf9fc8e9f8b6a1ad08f91a6eac3d2daa402a02d3d76d76eb7f3dcf0828e1f78b117ce1de4900000000000000000000000000000000150066f0844ec29cd34ec16a4d67cda0fba6dee9894efc64011307b46c87e56d474b9e2eaea01668f69bc8d7030b1af41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001013b323ff553409aa4877e0ed75882c4bc821a34701a31cb201b673cddbdcd472afcbbdfcd72d8edf955e25c1be06ed0000000000000000000000000000000004cea29593e77cf0763940df148f1238ed21440175cc02f36d388a370ddfac2511517f09d646d73451bc63e22af3f4411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbb0c86907349179c6b00175d14952abd81ecf2e92c5d01874655b0758c1319033a6e065605318a134ab5fdee8e804a00000000000000000000000000000000129712fb3faf7372ee36a5f4567e620d6c7ee4ec424b93bcf4930151355fce2013a58174c7e5015b31d94570124601d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9179138c797fe7d30669dae613e3392bdace34c1a5e326d2a7ff4f0de48063731ff17dcddccfe1227ab408a0f8bc290000000000000000000000000000000005ec6fbe16214443eb937a74bfd9b7385c550630a5ae918d1e40b7334a8e6297e73d22923c97b750d7fa06addb16cbbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca47b69d0b1e84aca371bfa7e1bef12fc24c371157e9d9258922211aabcbb79626e06d2154e633a97ee13ec66ea4bd000000000000000000000000000000001467a42879068bcfb952f1b0ed8403f157ae1b2d65ebb0e4f1c0093c985373f2634c95e9c1a4036c7844024bbd710f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1ce88e6b6f7a46cf6bcecd5cb4d9569eac2f8ae1a5af0dc202917deb10ecf3239a6f22b2651e2f3e5ceade1e68531e000000000000000000000000000000000be8efab103a2fff70cdc8edd9c1e6f7719ec5c8e25e2b7db70b107353cc8126b20347ba20c6b71c90f9a4970648bf251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e2f8b6dc5da2c4cc27e304d82f8f804439e40e46620912d57de9605c32bcca31859cbe153c7c9800b21066113e41420000000000000000000000000000000018f9bf3dd190a2c81e3438ca21198398f25f50d8ae654439b41eb3fdf2d95847c4864e7f37277548ddf2f35e3b56af411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fae158d60280c77c306f1c3c9f687d62e7bffbc4e204214635661218b13bd13f4b57dd20aa5d76db7089511564c8c3000000000000000000000000000000000f8d9f8290b75656116c3a7a61c34583175a2365481b3505ae27cb207d65c7253e49c0811e71119be9fc3d0e951a75291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192c5c6ff96e11e34983fd9f732952788564034ecdcc813419bd1222f74ba01ce6240b13420aebcc3eb3db80cc27f60e00000000000000000000000000000000123a3b848d12f114593a0eaf7a64549fd10b3296210b6c8e49e5f6e39a6272c1673f2e6f0a648731413c6e73e13648ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014695fdc404fd22b3590ba16911230f9596e3204a066a866653b6619ed91f6335f80494311b3de8e0dd6dd4a5dc39ad20000000000000000000000000000000016ea50cac7240ecd1e392078f3031ad74a8727a8749e8a75176713b4d8b1e0325e9b53f831f32fd4f4d3274a6359daa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b2328ed83828937fb21874ccad8fac2a5a3a88b449afa1198a693dbecefe3a9d3028ca041627de8fd580718b102d6200000000000000000000000000000000022b3264387ffbe5e3389b094a5400c0f2395d01254e5496304b82514322c63ee705403c9a9d3c2420facd26f2bc98911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117ea6432046276820b178d163d25ada931929869e4fc677d0931e21e598d2475568b2809b662975a52993ae006c0b3700000000000000000000000000000000154a057406f5d0bfd153625e54e2c48d5c24bea56a7e4608ae16e23fe9e3ea2fcb0083e058ffa08e978c72ad6d5d49b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129350d333454e2492591a58a62fb5f9374b9ef7aeafaf1cbc91806d089538e977ac8aff9c9d1b359b70ae741cb7a1f5000000000000000000000000000000000524e2d162734eb131e54ec7b16eb361a6a06f9ff718dee6a348ec37ddc2660f39977623723035aeede16b245d5b6a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad83a20118c6efadcdf84dfcf9bd1e52193bfa09dfc1cef5a22350721ee4ec10d7950cb0999fecb6896782fbe0dcf2800000000000000000000000000000000175e0b2444b76562acd1a21666efb6b88021f5ca3f0ab5f75299a5782e5715415218dfe1473535cefacb8eb202ab3ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f22c63b01fed2597d923c8ad194ac27b720ab171cd3e1e17e40c7a43c84f8afada0f124a1b8f40700ce5e73e436e6b3000000000000000000000000000000001420de91e4423aa0c96c54d14e4bf234b394b784f5ae5537a58c3f6b58384284ed78c46a1b1a4ccc500cfe87c560d9f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a88f4c44cfc744877f8fb3223897f505e4960c52f5cd777c6ed1e92714408d866784c4dc0367c431f85e5eab1580d4000000000000000000000000000000001709a908199fefa6f8719e9c6a8ac031dcc17fb15d03cd65020738d31ae524d66e807acc9f0bf8b7634e9719b56043f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0474f73442fa9c45fbe3bc1b036f127293a49889833f90272b722e24d5cffce88e736f2c1bb614bde3e304150351110000000000000000000000000000000015a657201c5784629cd43806329d10aa48becc72cfaaa7e52d6f813925d2cfe8929cdfafa1a8ef3b0ee58dec3f1e074d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105d29c690cb37af781da76e2f8ccc5d6b66cdce6e7fa3613191851ed88319d976efa89ded621f784180bb9ee14b86da0000000000000000000000000000000010bcf7d7bdd63e3cf0e12cd168056dedb0f8b59fcf7c3b663c4846a89bad5bc587112c1b90bb9c2c38f9968307a33d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000348f2b0cfa2504daf0f9077b02d77deda23004124c85685c7babf6fcd0d5fa3f3877b2fc66148e82c304c8cc5d3c3d00000000000000000000000000000000090291970f42b4147fd47b340198b2bc4aa169b170c4fb0e4351c777e64696905e5213b0b5f9094be76369ffa54b5aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cdc4bd4dfe5068cc9b34404aa4c781c035d49f4a4d90236b850e0a4c1ae7995dc62883333b9e02d5b0aa4498f92bed0000000000000000000000000000000012ffbcee74ea370333ebbe870e03cbc43b32666781d1b60885505f66c3f21130ab23e6cc8be37958e181b8e858d81a4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000079363264e024174da5289345bf50a7c5be5abd62ced3799752cef0dfa22b19c8047f6307cdc6120c21a829fabb91ca0000000000000000000000000000000018b901b7927ba85d3e90cc07c2c9839200a271913efba5a6edf9ba07d6695b5210ce4f3bec49f8da10f2af561fa55de81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001458b82b2263849914244b4ef7c970bca071f2bfb6d9a32313f6a5a41205219dc95afcc2ff46377b588c90380c0806f200000000000000000000000000000000022f6e218b7739541c28b285876adb5537fbb6be4713c0026da29e891b5aeab267fc410ef4002e3abe8cef67431972441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a0a0397719e7a89dd9efaabc80f74e24c09d5925526acfe84f919ff17e4ff39e6f0619fa1ee83a789c36468fdda515000000000000000000000000000000000860bf1281d1c06f5b5e7425f1b86b8cef0bb5e7b757afebaa8609420da2a497b985929504bca6d574f2c87a8188d1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa37aa765c1922318d5acf6641935f4927bcbc7e4f917ac7dc7384df42dcbc2883ab84b5ae870ef268bda8f646d24b6000000000000000000000000000000001537a1c8125b576bbb29073950daa91fc580ab2ef319bb40e54cb8560ec640c75d25b6c90d57cf4bbb590e2e3ed26bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e10866905ed0fa46718af22c7e7004fc9a28fef1e47b94c90eefcb939a2a91738da44899649d9f0b6e4c48ccfbaed5000000000000000000000000000000000760bdc7d22356c5ba16e10f350c8672e617acf4bed21354cf46cfe93dc4cd4face0b05cd12dd191462efdb370505ca21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001241700077d383a02b1cc9b5da5d02e44490e691209afae8ac8456eb080f2d8b62be77e70dc954a9620b5e86b84e2b6100000000000000000000000000000000125cea27e6046e396f5e57ebc9fd791efff98d018be9a462aa8606f6927839daa3515d0b616300255b282a11c93caf751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085eabe2a8de985811e225eae5020d4ad73f2fe5688a00ed96d7bd1c701ea65d7b33fc9c97d6a4dfbf2bb6893f7d7e2c00000000000000000000000000000000142f2f44c1eb2b253e1be99d50ce655fa0bb1c6df17c6f99922c1638b8ebb20c8cd253ae70302bdd65b9a8b8296e0fb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000142f17d3e62c10c822977c9fe35c49ee6866fee26b28e62a1506219a9463d95ce8ae59ec670429753dc5680a54bcd840000000000000000000000000000000006687b542a29318dc64c656bd6f2aafcfa9175aa44df1bacaef818618f756f48c52894e172f1359c10f7872f8dc483df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108b0a1a167bf043af0e621b6dc41fecb5c6eeef9cc7f1d9b7bd99e9cf64eeda6a0f018d2aea64bd013c38b0d2cab4150000000000000000000000000000000014a366d68cf08921fb6b9cdecd63454d1d698267ad2972a797683ef1ffd958fdefb6f7f341d829574d7f68726dc5e7661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c19b0d8477c1cd8ce1f601e9cf05a89678cd4ecde4863cc36c4d233a5167ad17c7405bb91ed713e22b50f480847172000000000000000000000000000000000f500a824de41fd4278856171322ab43c2c8d74a4adb643f02aacefcb06ad6ce43bce2655433e83e4cac4b59a475bc191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dfddf5797928a83df6e6ddfb4cf504a51095f2e34d412041fa9695e7525725d2662706f3ea5b2d21e42656f7b9252d0000000000000000000000000000000013b8827d2231d6d5fa9d59c19ab34bfccdd511d82f90c6e1cd62863facef0278e3a96497f679515e6d7ea579548f00a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007008a6dde693f9290d0b7d806e888ef719a81741264114aaad9b615b0cc5ef88a9c7ea1767919583d2c16ee29afe36800000000000000000000000000000000041526788120a8944731ecbc368eb905f48df7c4cdc3b428cb0909bbe43ed5bcb9988d269922ed72b1349d5c939c19b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062d699366b776097089be7e9d23764ac1b9a896fe3081eee5f82dab71c47e1c2b25d200d21b50eb539e4ad9be78b05f000000000000000000000000000000000ce929c09c907f21327294fbf27a3c223bf00427b2a960ea06a1f28897f9f9455ea1d4be2643d1356d05a2d1b398946b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135a1a68b382678ee6db7a72f9ec92ab1999f0a98d4455191d01b11ea7cacb2a6d50be8dbf8606d5f99746f7dfcecd99000000000000000000000000000000000802c80689a2fdf0123520934842eee70c99242c9a57b144fc7d37975b896f25d4da814e775bd2d469e2964e105b6e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f48a6d6240d49e81c8f7d61d14bd16dc15b867131fb74ff4d748db2a5f00dd80083b7228333f5a23cb84a79c8a46ad000000000000000000000000000000000a8f7a200ee82845018a7a509ac1d5492db67002d168453573eb1638d604e7d798d06d3db566bbaf985c39185511041e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e7d122cbba97de87d5bdf9833d0cb88f65437343fe3d20fb83f5e6df55a31905754a139726b4b3cc926022a44d6a2a000000000000000000000000000000000fe2ad6aea6648ef2735b5380faefd9146608cbc03b08997ce2e3b08110277c23d536cf3955b602b5e0a17d97bd8efba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e6a5d11f973da9bbe1a789b954d3e4988d511b3a5a4c9e06b51fbd38dd166fed273a883cb34c6b583d6af7fe7d6d1000000000000000000000000000000000a12fb3203f34508da401e5c6e66675f1e8a02bd93028c6aed82a0b0728b67ba9d79068764d84be53a9a4037c4dd9c561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057a93be9a1e826076b39770a04ed192b118e925d652ef5c30a680c3fde7bd1965c95eb073e2981ccf65c20bc79849600000000000000000000000000000000084cec06b43d2a0722bb7ff2987548c954b59b9ec57956fe3ea5e2a1576f05dc3a20a2e83868ec21a4756f7ac11e0e381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b09417d2d269f325e6b879c24b6033970bc9ef59c4b081425602eb1e5aae1d44dff6a7602e5f4508f5124b9899f15000000000000000000000000000000000c682154a4892ba07c4b2fbbe6d13999098dbc66a821373e0006f96977ba8c54f9bedd16de231e13b894e8f774be21811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eb4c8b44a27705c84262966bcd37fc815de13edc10cda7e07057ca5826ec3793f76e6673617296ef9cb7eff2aaf30e00000000000000000000000000000000187dae8659feae1fa7583619a1c5d0f89bfd62efa18004fb5a50c3bcdf1cab09344dafa7c4439355ee1e308453e4146d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185da7dd7ffdd5749648b9c0b9d645ed1236430a2e77f692341b3ce5dcc4e8e53d4c05c575b8db28ba7142d16fb11a6e000000000000000000000000000000000f7b3cb64216841c54ef39f0dba026b1ed303c5b5d053292c306901418806e7ef7f1a8ff0e5fe0f2ae7b98c2032c03e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e0d3a87f704dfa61f0957e23af5a7689e5847d217351ba16747f8fc8bd91d77857998902b7fb9e3cc549f809142e7600000000000000000000000000000000004d757313c4ccb5cef57a9bc7d60aa36589e716bcd38dc7a09044b75b4b6aa3d859cab46f2398ad3a38d8d3edf8126c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073bec0ab8ee9f2bd9a47de1f827455a33cd2cbeb8ee01649b29bf360af72397e6ca8c82e87ea92b32b336327dfe87e9000000000000000000000000000000000fa7b5dc707f726aaace955ba3f7814ff5d653b64840e355fb969aedb171aa84ddb425d374c7a58d92425737c9eaf19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bb7051a27b6a96fe6dd38f63cf589d8a40416b80686317367d7567935a6cfc82b73806d7a51dc9b6ff86153cefdc1100000000000000000000000000000000145c7dfb51de559debe0c84fe4e7937f5fcd7808033fb01d7735d91b4e32b4bbb0fec50bfe2b2f05a290932acd44f97d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc3c9b8eda29c75c88515df46acce45fc86a98736b7c682b05a6988b4005c8a7ed5b95b655cfd7d503f9f751fb583f900000000000000000000000000000000044880c8c319e4ff67363ff921ea2601c97cd3e6417ccb7c5e2f902a4514e4b92bddce19e206d1fa653533faf36992a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007167feba987c31e2c017b63e3c3229ebca10de7300a4cf1eb2945cdb2c5c1bcfecfb5951e71d10ca1b245db37486ace0000000000000000000000000000000014c029288f3b0cf3eff9f81f32b0517ee1ab4caca00c93caf6c615e488b4c73ce204404f6ab719d46f513c09466873d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b240c89f1bbef35f6e1857b718569943d2adbc7776c9f3b8923ef9a49a34ad7908b21d2534b4cdf2c57535d5cf5c3520000000000000000000000000000000010db39a4419af80f0c7cf53736b7932b3d3cdc46f9a984c5ed7cef6beb7dfee5a5f496e7a68f81c17deee60cdf47c03b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142e8b7e9ff592ec6b8ba5303171de48cf692b0f1fa74a1174382ff7b6c1114ae15b4545cb3798303e27b44035ec1b3e00000000000000000000000000000000127be3e21f39b378de086279c2e1e01dab6f6351befc79e47ed92bcb3e02239a6534e1ffc073e448bd18c96ce449ec971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a8a524a83950946221df476e8249a60b4982ce0f12018f8c965272883f1fc8d13f67b698fb418816510557bf93e5d70000000000000000000000000000000016141caad0fab72b16609eb10269a5b9bc1f973c8904193ec0c8106f6bca18f18506e60349556fb761c513b52e43ea511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000856ee5359e38460ffc10b5ee8ec8217ff550a94c8f0d70f2617eb4c3ea12135bc1b69a81ab28696377ed69fc8454d20000000000000000000000000000000000d3bb01c23a038d407bb9e150f237ce4460b78738c1e407634c12c5712c9ce527e17cf51038768b8ca2535df56a9b5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f440e9295635e7ab3ce3a5da6ad0ed6b193d597ab93e858bd2049dfec07ca886c20081626cf484418746f0552c35d8400000000000000000000000000000000049ecdb02de4999c365e244f8e8701ff92a1c43710f1107eef50a25ad2c288fb9a2a906398ea895e267ddc18f6b2736c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a503a2035bb0b055372844bb996b65d15f24b969767241c4bfbb94b02d398ca8a23b1a198b1ff1fd924a8993a306b100000000000000000000000000000000105a846564185baf49b5739cb69aec11ee2af3c17c7abe85b5883c84ee5b1af29af4dc48c0da70da926ab7abff962b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045cf98103239bf0a710e766e4c168f23eea13ff7108753e4b6786c81556b4e5a66d74520a9b20f34faa9608e985cbc30000000000000000000000000000000000cdcebe39676bff5c52c1a539ca57a00d1b6934854c7af0efe9e82be1a7a6cb53dc3118fa47e22179e27f28a4276a891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad6728172a80e56d724d50fb6f784e0d270ea68e1f0740f8a142fe5d439c26a3c7bf935d28caa75811a826e968a1a550000000000000000000000000000000007c792ba9dbb914d3ee487872d983e9d03c9a46b6598936382e43a77a48829092ca64ec605c45041e87c2718ae1f6e231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010569dc5ba25f094c5c773cd9c9dfa6e49eb519005d3c45890ac7b375c3a729e43e2ac826a62e0fd51159a4fbe2384f60000000000000000000000000000000008c0a1aace274b33e3a6c5a15ff84b7a9d72cb05482bbb96d1abccf999b85042d5326689dd6bfd3bc6928bb4c937a2981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc0308b36b6a2fe53358127c25bbf7a83069a390af3c512d31b9550174a9de020ab6153ab081de0589d0336ba91c672000000000000000000000000000000001396d76adb7ba91a26712f65c0cc38db33389a00c776815c195a1f53937f9d5cc10a53b716e47302b987fdebf3edba361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000570d7f6344812e1275c2cb7044a33c8d9d65630c2f8813a3a6417ef81fe9b469674e468974764d447f0e04fa981a6330000000000000000000000000000000003a74f3633f320e4c7c078edcdcb5f268b2a7d33bcfb14f319481ac63df4e9e4c7fd2b0cba0b81dd39e3d6a7c21856781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbece52e8a4360bf8631c80fc09f4ecc74f3f36b17f80d40e484d62a305649f6668bf9ba51cd383d1e370c279be3b6b0000000000000000000000000000000011158a17132f17cdd24e5da3eafbe9fbbaa2270822a1da2243c99bc239e34d74aca0da5b59379e60130650551c48c70e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcec204e3fc7be70649ce455307827708915d541899037e0bd7c59e0e2dfa7e464c4251cd55e217375c89ef36349987000000000000000000000000000000000229a72db2d3a0ccfece3d1a9b08ff6a4d52a7d4eec40abf9bf3c5860134bd1af84f589d091a740e5c3a183ec9aa381f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f74b811aaf9af101496412b823b426085ff8cbe0be16ec146f716b93b67a9d49478e3a61a670e2d926063f4098d8980000000000000000000000000000000009c99bdb057d780ba322fdaf0d64b0ee2e108e9265a9c7a43f547d3e219b072defa51550f0125ba8d4e8ff682c43edec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007528c336fff5a2e805040acf96ad5acf88dccb539ec4e7f7a0fd6af0990d11acd751d8dbe2fed7e6c00af2176402a000000000000000000000000000000000b59ed6d23573e077f8c53f4712a1db38cafa177c283941fc29b5237cef7e06c8388a725a8f0bc34fbca703b9f78790f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008eb9aa9b1c8fbe3ffc605e27753983fdccbfeea0478d2a0701da93263562c42fa7c27b1b1c92fcbc7cc780ece35a8d0000000000000000000000000000000019ddcd894aa3b50240cb1ce805bfcbe90b4838f4471b3bee37ff62544d032fa768663fe05844abb7ca6b7c604ea318551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000246ac97af8d7f651358c7f0146e790764fcc7d4bea68dc283895a397fae670f50f9a8ab2703a8c182420fa0cb9e57df0000000000000000000000000000000001f3dfa895613cfa0fd82bf07b0bf8d31368cf33e21312221c0ae8880c1679fe10179c726e624a9eb78ba41ebc5d285e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093456a46a4fea6ec912ef59379eef2def307badde4eee92b12e2890aff0b1bccb3b11378705b2f1c5849629372e760b000000000000000000000000000000000cb35f5b7eba73af36e6748863d90c2fae7ec578b70cae36d1895a7517d96b04fce7f058b7c115f211c39ef5a012e02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae50ff2c556fcf11784836313ed209c0c248f9f5d0bfc0dcac5e0b5d2c23d54bb2e420bc5260d1a8ea17757837655a500000000000000000000000000000000031a4b0ebd75687920856558f9ba8925cea6aecc2d15bff06bcc093a7cffdf146c74ea81132755b83aa6cb0b5b07744b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029261dfef4a6147b77087c43c2fd4c51f5a8d3dc4b56e47222081db386efe87e0f4ba71e73a3300cdad0ebde51671d4000000000000000000000000000000000afc84590fc84f628ea6b3a7dcae723f453ad02bdb9e16490cba2ed2bed7698aa44222467a7aaa8841603654b038c37e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007da9e1693edfa8b13f6bd775274e6cbe0fa6ca64ab5696e8890de3304f8caf7da0897c5187d31f3af4baa5e8c4f3f0a00000000000000000000000000000000090cd618ba398407b21186a3b654ca74e8b4b81fee9182e59ed85ff36aa7b00fa4746283512cc8d64b314937b8a959321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001281492565b70cc9233c5c51059a3acbdbcdaf61bc5325d5be4464745f6bfffcbdaa9cfc0034d29ac03e44a53fb4c8b80000000000000000000000000000000012728011592f23c7ee53c47c199a6fb00eb2fea611b5f6fb0c91c3b89d0247101dfb5519023661ccd648c3cf6b94ba381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ced9449207cf29b8807e36e521e635e3e911e25e283564199dd50e0ff95a82a64ef2e4a34e2c00e853d24e4c601767000000000000000000000000000000000b9364c31b5f1ce6ff8748909d6ec8e9237a648f876c3a36a79812b108c32b6d571ab2bd809c531db0022ee2cabeecb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caedde99aa3c3248e529c9f885dfbf7c19957adb0a2ba9f38a5a64046b25a7af39666baf072d12d32f29d9c778138c4000000000000000000000000000000000587416adc0a5cfa686487837980c8b2eec281781cc50ef1b90d59b918e00fcbee8b6b55f88bb61fa1eeb1998772848d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ead29df3954bbee044ab074bd5d7869f07f0c016b1d4e9ab97bd9aa9e748a735808db53f47217d57969e7f57dfb557000000000000000000000000000000000c9bb04732fedc62369771135ac46b883bb27c7c5563bb77bf275502a5a344f2c5876d59daa89645a936ee4f593bf0841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7b242f5370170cf80da57bb3bc86a2e602f742c98f428a62dd91cd608d6fb6e119effd1f01cb6bcf0aaaf454fba1ce0000000000000000000000000000000003f64e278d8f22bcf0f648736d175f99f52bfc5429a9c3773626c41fc94dd13fe676a1a2604f71061be0dcc84847556e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014407ce6b6a8dfe423a7e8bd38aeddf8e00f2b19d6a928c07fad41445572deb5ac9b4842a04c8b1ed61a7e80c6cbd04b0000000000000000000000000000000004e6fe54a119ca3066610a55dcdb4b10b7186fac430dd18bff32bcce309042e7fc98ae21f27c09b2b247a00aa6cfc6db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eed44596ca5f7c8797bf9356ceb21008ec86d1063937d2e66375447f33a61a5f296eb7205adea7c4a2dd04169d5666000000000000000000000000000000000a97286030fb6c35945e2acb59eff3892d748b736feadbdae16d44baba3b2dc8be83630456ced4d1e045ff7dc5a68df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c495b8569d3411fcedae08ce202e74a0f6ef89abb0294fdec856fac5c84f3b4c0018c71d0dfe680bf0dcd4cfa7b7d550000000000000000000000000000000000c5279e0dd49b68dd48a2d040ce657178698655a9ee26f21ec798f274a19bdab7d217469566a879b65bec937ee6f8811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123ae1cd645b49b72701d0a904a256cb12c9afd86811caf50580c7e579decc067ad3594785f12b25c1e0f75df36f7391000000000000000000000000000000000add1b25c67f431822ba0718a8bc8f44f5f98c7e97a4d50f532a5000ec14d0470332d65b59173fd5dba1be77727adda61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0b0ce79d88896142137213396a5f8b54a67808b55c94e5dc1e1460004d26ea3f837a06ee511ee2cc0cb71ceee0145300000000000000000000000000000000088984d6f5b9e37345b62befbb2fea981d3d9817fdacab28ad7b0cfbe8d5f94f917db1c461925d1a758fc9275cc7ca4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7e13eb9cc0051482bbea7fb59b3cae0e38b16799996d38beb2e90de973d9bc9187f87efdfbd2624482736c67fd326600000000000000000000000000000000040b46c2dfb63eee17a60ca05b005bdd2b0c30ad63a731471355d89d7909aa3e3e9a5872aa2c900c1dbdb2757c1553a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000311a4bb683804d5d49b6a1bc574df73a2d090faa52e72f9a0bb698609f7aaf59f79c5409433d8e4568a7a775546a6ff00000000000000000000000000000000083cf005c2ded093b12875d111e779caccad2ffe3f8152ef455364d45870d92894fec763b3337da2ddd99097f96024921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce63190c2ebcb124ec63f1ebb3c73d7e570a3ad86b1f4ab20ac5f709b43ce915f95690e49da42df0ecaca2421395acd000000000000000000000000000000000cd5f5bd826f22feac664c5daa0b445831680052c0443869e6a88f14ea204f8778942853dd33779c753253040062a9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196047e249328b2cfc9d5e1c433e36d41ee93de3533f3acbb11090cecd4652895ebb0a5327d26e6edfe0a50b203cba2900000000000000000000000000000000034f8df3e55143ebfb0710a66851c04f2b742cfe3c83816ceeba467890ab05facae0eca6be0d6521d8fa9f73031631d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b09503aa85a030ce334db16dc866b537c03bd828c2f5be724e3286cedff3d4a65f6b114775b4d591f323cb92dc638b600000000000000000000000000000000025843816d5e48807e2659aa59b25f35069f3d9541179fdb0274f5433b752b6b749e7a711b9c5860c67c6e114d9b4ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbf7da5f0139f1d04a9686e21f56054f079bb2c3410001bea4d76b546e72319839a5f8c185e1aca1b10e0390275a020000000000000000000000000000000013bf26b17c026c23b361afe021a993d9da1d2bff873b9b6d0abcb84f095149825f9b942600e05743f35b17b6449e73361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179f8dbd223ca88bb320cd84c66c34e3dbc6fbfa3ae12b0e9c0681b43aa8bfdc1a6a4f068802cb0b087da5bdc4fffecd0000000000000000000000000000000019ef8d91263bbf28a8f0e335323c7419471c677b5df1e461f686c3e61d707c55e2524b83e4e784abddc484b078986f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002172513e2ff4c594a9c16fa585e903777e05642d49fe9ef73e70d34faaf9b7e81a590fa53e42ce163415077b17e38ff0000000000000000000000000000000014350eb03764a955283559957ef67c3a37ff8f87095f0d7954af591c47d88690caf0d8624aa8e9bf02aa8f2e8cfa02231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059a71b9ffd9f4978e80a697697920af2d77bfb61242a51aa6b6aab63f5e247c8a847011383fd7548fc6d49b4138876200000000000000000000000000000000172053ff657ae2ad44388c8ab4d04aad5067e575e86b3176fb6630f38da9eff72f65ff1c39e6c753539ff6f15e4fec401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a0549ae9abe3f5a52d77cad7f0086918348e2609dc9f0623ff5c6ea46f3aff1c0cc50f2aadccfcb3a2a294af75330000000000000000000000000000000007b308c4ea482c5f2f1d651244fbc7ca74185a1b811ace62817341be6476892c19e848315a50cd2bb82a5f726ed8633b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114848e5bc681991e5cda4366ddf182e13305c89ad2b729b0ec92731d473e5aa06df8467e70100a7642df4495f478f000000000000000000000000000000000006bdc557ded0c5711662e8e0057c9c60a37ab1503fa393c1a1b63e1a4dc071500b0bf9405b766b925b0f9a5aa1cf3bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac0bf345e3324bbe63bdeaf3b8f3673b86bccc755195e85112c8f2a7c97957a9a11f08ab4116022ed91e1e5d7a4b7ed0000000000000000000000000000000004e8ce20527ef222fab385e59f423634ebfd2377ad273dfa108ac181af687bb26cc8490184e578fbfb5a709c19d174431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f2fbbc0b1a24022880d2b31290a6690ecdf352d6ed7e7111d67c062b52ebd655eb2d9f909c5c87980b9c7bebced5f0000000000000000000000000000000000fc05357a9fcaf113fd7c4aa9209a2d168d9647ba21ca8bf5e5c812ac602968dc8697efcd5731485eb74e1d997cee9881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2821ba7aa97c542255e9192f851c3b9af3ea45c8d97918ca31aec422fbcc00eea23a4596ad9f36f266215aee26799400000000000000000000000000000000192732fc540be66557b3a81c7956b0566901fd9b7aa37614e326d26f247692910dfb2cfeaf95a68dd8ee2639ea98f4831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9dafaa2a584122879ed712493f1959563b9ed9d5c304544648e446658c727255412d8fc2cb8ebbc5b1963c858e5e100000000000000000000000000000000185033131994263e2f789fbd902f2abd1cea63bd329515f3d11045f3638ab4c9b11f2117b173091578e7ed0c728cf2c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000243d34b81544ab6b1b14dd5a211a974b96f7fc1f569ef3716713351c727b6c7844bafabae8cd44bc80ee2cc0a42f4f6000000000000000000000000000000001642cd6e6c1d7d9f766be080c0781e5061e84d66003430810e29c915c3021fc23993901fee34fe8f18886c2538d3ffd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005adfa462a75b7d89ddcc2bbba8e0d2086cabb05c4060a7d34d3d221c4fe0e20f816f23b79ff4e8599f824fff71ad0df00000000000000000000000000000000196f222466276b99a788952a5e37de4ad41b73dbf3cb8f8cd273235bc1b1375ddea7e452473a02acf386f70110765d6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e3b2257faec3f134aa05a1d2c082ba541dc0166016215bdfab56ca3074a505eade74e62244c8d0c51e7ac2b9ea1365000000000000000000000000000000000315ec81c4ad43cc0e180d78e820c2003900afa5960014642d0ce983a5a7387573e46a917bdcd5aa9de2329069477ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e83cfe8c59e2726acdacb61e3b14378226c452aa785abb06bb605fe007078be179d860f68b0dd0f0622bba8b979b93000000000000000000000000000000000fc31b5b4539b9c894f2a7ce576fa8b1c40e7cc966d009edb94edc9dc4f3bbb3dcb64391fae90d4d00fc12c47d2bdc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de1935ca804ac88ef61f419a7aed1f148290bf2b581e414b79840e4544dd161d6156d2b9392a1da537259a728b85679000000000000000000000000000000000f9b27ff389641d5f23163057a2cf6bf25174a418ced9f89b50aa2a9af13e10536cfecaa5c8e63f5f70fd3662898a7761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c2d0fb963f07f2ca1196823777ea177571f39823a2bf4edab79e6f94ee3231bc9870ec1cd0499c4c9327eba585845b0000000000000000000000000000000003bc14cf8faa822b6daac2d60ac1c421c82a64dd128dc17f0253ed3392069c5a86e615a87a6d194df5d9c635058bd4751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ad4659eb28c45d60bf53ded2e7e9847dbb62f876e38da562e19bfcc29c46c97fa3f06432c1a8f1d0ee0de1d31818c7000000000000000000000000000000000f5a686c72b8e544c11cc607d2506e272185f0da7cb5970ae28bd43e75b603b684b2236e54e2961fae66d7ff500c80101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d0ca629f53eb1eb756ac6c76f9f50a2680c604e351897e7a26fb3344791ced6057c6dbabdf445921cdf76800388abc0000000000000000000000000000000012c7e69ba63134588f30f0cd97e3e957346d42ed7c0fde500e8004e58674dd83040ab0fa115c41ac0080407aa36945761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001703c764bf94f14e4cd32cff19544c1d5207b9920c4ded117b0443b3f1e94531b23566caab388a0ab49b2ec65ab9a435000000000000000000000000000000001809a77c65f10b4e12d88ca6590bf44eb4047a21a5a497f138f2fcbaf8b7a08dab00944a10d244af602a06e219088c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff8fb06bbe836cd3da90a336a2153e206653f6e48e81771d9528f877c9ed408c222854529df091b4945f25392354f9b000000000000000000000000000000000f0940d1b9214ee0137f47b21f998a9e6aa2560dcd58140d3ecc08d48fe9d04757ee832d9a7a5d4fa819712a45fd263d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a3f2553fb2803310a36912b61d2f93942a042cd2df39bc350d3c3667218e5d6f9e92c30ca357e7cb1d6dba48d8162200000000000000000000000000000000173c5bdbfaf7fdf53dc28e781c5c0864f40cb8f6d305ecba5414ff8720417d2e9a90d9ddaa6e83b14efd247b67cfcc301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001035fbc97d4099786b654a5913c3f10d4176391d95e1437b7e88bdc493b0fb640712ffdfa407af1dc6468d59a235a4580000000000000000000000000000000010d99def8571a278f30a5e77e35e39b1a10a282a8157f586ddf1977c7b95e12babdf9ac0d6d9ce9da79c09adf10233031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fe6b5959473c5fef481b4669c5317dfeb7ce53882f3997a729cfeefa2acaf16e6866733b192156e7025adb788a30460000000000000000000000000000000007bdaa0cbeb99d086fb5a9cb84d0dc1318e2771e8451cc5e457ee62754bd9e70e5044bf93a8e43fd1cdab51eb19be36d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000479763c84dfaf62cceb0046b61ee30ac2f8ba7424f2ec3668f77f8840bd57d5d3b28a0b7e045f6ade4a965a123359c700000000000000000000000000000000107339ee00aeea2742777a47062e72d65a35b5509282972c7d0b7ef0b4cfe89514549783a4bc824aa3f40c36a4f29af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de40d1de534205a5d823ee0afecc7bc76d359ab8e97e01a100f62c3b0e30682016627218bf2012b2e839b2cf61a181a0000000000000000000000000000000004f5c1d74ebbc4ef21049afb926d27978e611b21d5ce3b89a70b4f12436c0b7116e33aefaa69be50a37afa41c57dd1d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000390c37942642f2d0a05c7d24f3a3c755154b3a578cb9a3cbf3a8bb78f11e479c101cedbbd91ef55919b91368379d578000000000000000000000000000000000f54122b97242d517429d553d74e426235900d95dc974868ef9957227906c16bee168078568bafb232fd35ca324eb9541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623dd5d7ffb0a226375666a3172a6af5ad38ca13e15225df3db300aca99d7f0256cc2bb5d293280a1efdc4a123a9c75000000000000000000000000000000000695233473669493d02cea4092cf3d063cc5ac01670ba26a9cf23b202dca9fef96c75423296a71b602be96455fdc872e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c404babad3aa816fac104e86291bcaf009d0ed83bb2f27768698b2abca91e2c6d6d52bc692dfe5b53e6e7d28d9e71030000000000000000000000000000000006f4e67532789cf268d0ac32202909122fa27f662ca5c541f810bf0bdcb5e27b8824e1c8c15881ceff1853bad621ff381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000486282c7a2263f6e67887269aff16c84b32366675335f2a49f3edcdd9e2eaa566650e77ce1d36af57ed396f3cfa222a000000000000000000000000000000000a3bfbeffa8d55e34a9c51b400fdbd40ae69dd6092ec5248ae2da0557d75b52a569b5617b683ddf9ad1c26264a5384f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156d305d09e6bd3c6c10a98035b939e21ad210ea39cb78a3a32f8b67767cb09babff9cdbaa9339eeeb7cc182c7d4b8400000000000000000000000000000000120011b3450633d1d02f71da660e278e73941af243fc64ff94082b25c5f7efa776473eef593d61c4c71f9a8d0219d4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008d14b868c9996ced4068f0ad8d77c9c8e87b6090b4a1a07ce47529c12ee6ee2e9ee3254338bc7a74d002c0d0cee19400000000000000000000000000000000148caeeb9064285567e33f54972c2b7be2b327e4f7d64c15cdbb2d65a4a38161753e5af0a36391b03cf8c5d9ffe5dfdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cc30f665dd9a1a1feb17b6ec7ba0043e2b3db35b920283785bade41c0ee86a2a6e5fcb423b4a07e2c1e0d400ebf3f000000000000000000000000000000000152e82d69711ac6e95081f82ade6a739dcb063fda716fba0c04e820febace2abffc031bd9f83d18875e3bd385fde58621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e68a9655a0e70bb32e2adfcfd3a493bc0e376b8778e918ebce9829eb38987e1ab0f9a1ad365a7a60aaffd62c23e41720000000000000000000000000000000001aff8b0de8964cb814383a186fe3c09b4f3bf8d1009e021eba8033c9ba586b4d1bbce42720cfb9aca437bca1c8015e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bd1c66a9eb8a2ddcd00bd889dcc46cb1d02b270612d5cb56f1fc7d421599ee9f33e25400145c7075432e5127d2af470000000000000000000000000000000008e7e9216088e67dfc95fccc8e88ade66fba14280457d2513e792b4e53a94eebf34089c025062594c1aab34b63661b031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea6910ebeddc1951546260427856df51acfab59dea6261c710db5478bd9e9e3a4dd7d281308a4976ce628afba80af900000000000000000000000000000000163c190e3306cc23398dabbac510109d449a565cd6687235dd2ef1a76c95adf722d80e69dfb95a171849f6ba8ab9ed5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2a3646d8e1dcc1fdadf04c767ae49362431ed64154d3e56e0b3c02a229a4333a79834642a81748b429eb51307f9fbc000000000000000000000000000000000ea12605b0baca56cccf5c78756185ecf353950901eec1d9033e698b20494b01ce64bc4e2326d80bc94fd831757488271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091a40ecd412f97305308706b3120156c5d6f3dcf02740269c066dc332440bff4ad20cf779fa1694b22d0e133c3cf01600000000000000000000000000000000007574790f2d963b178bddfdb0813a67a467a1d6671b900e1050773c698868784559ad131931ac21c07d289912116dcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a50a5d6fadf34fe9a09d28ccfc931a919e060241481f4dabfa25f8f8f76ce1c89482fb90de55ac9d71e7196232a6c00000000000000000000000000000000018ed384f6664d8fdc6dde21fdc15f10c9e4171524f13078f6e2baaef0b476655b7c85e63d4fde3bcca52d3dc249a52fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015b022cc99a8fa9078d5a430cc183d177df7a7acd08a4c33cf7e9afe637fef1d9f0da9fcf31ec736da2b50a4f1d9c02000000000000000000000000000000000ef4d20853926038aab325b06f8a0e22b6f13d99b2e7d643f968ad5f340edd50b2aec38f311fa0adc2fd9664cbdc9f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b478861de307c9dd8513491c85972428ea6c5733e8ced606527bd75ece1686adafa4985a9307f1f567494e262b90d5c0000000000000000000000000000000017d2115cc3ed79d2218fd4a7823bd95c4a13536f5f55ead3fd98d056a29518fc3dcf08910b6a02c9b6a4d38f867095b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010464728668166a25c821a9e18e00b293be05cea966942667b9f44ba78c1a185a09e26b8a99dd5e36b58d5d7005570530000000000000000000000000000000002cb2cbea6bd87cbd5a01540c26a36a53612c4a4a2e4f28b6a32494be1d21c09f719e80d0cdc6c182b7c0c166768caa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c4e1319dac24d0b1de9ece94b42d27744a05f70175f6bdbb58280ecf7f94f05d7808e4e30f915199b32ea5f1ba13df00000000000000000000000000000000030bfd7eb2b5e70082a24c9ce64f75982b3f891d205c285728c8ee2a262e6b106fa83874db731f0f3774388af5be6f431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002424f7327ab0dc953a86f88e016ccb440b5d71be20351f52cad07c8d3f0a62b21db21d08639dd8a05b38e5a387ab90a00000000000000000000000000000000013078a8e395c37fad65b5122495b1a2318109e082c71239028dcb4aea8fb0150e76afabdf585b15db646ad715354d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d563e1a4d912e04a903df464452971ed082baf3504f03f668dfb9cd7ad8d8ac123da7f2cfd48599da7ce08a374c72000000000000000000000000000000000704cbb33b24f9eab11a15a322d18bcd31ef541a53ebfd4dfc4ea25869bbb29dee23d2d5352e4b13aad7abc58280e3bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eafe00a2d36979878686a4dab0154305ff2a671e66d3ade8889c39fc1bdbb3ca63c2861479a369e96e52b4d219c087000000000000000000000000000000000bdadeedfe95ed197fc565ed380545c94e338e5dd39177becc510e0d69ec95c42df6a1e0bb8e84175d54656d6045040b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013428ad2774e8a5b64f264f8f7029b1c37cf95cd8cf3915dc82a5009846e534493fb9c0fcac5c7c22d62d9c170882ace0000000000000000000000000000000000f0d0f0b170b0f0c155ba6d354076a37149914ff74b717379cb09843ebbffdd1ea1032d7382cac3bbc84942054ad3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6d1b073120489e79237027b38fd6044e39a346e1b5f08a1ad24c050537beec7d29fcdf9fa02fcc7240df6cd4762adc0000000000000000000000000000000008f0bcfaf2e66f48f9315bc2cfa2cfee31437a8eee5f16586c158eafdf429849d50c73047b04de0aed7333fcf14f8ca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b21e83775497318753c61fc471355b73134e578dada07c1f687e74ecf1de5e92b3f164ee70fa8d034adc67ece3ccaa9000000000000000000000000000000001071c60604806801af0a7e90287738903cf077adfd5effdcb185b034e6875d05aa543a6c31271538492f25908b1458b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e838da7af4138a2b97de5374eecf651155dbffbc289b8ec25d7ffda09b954b8b17420e35146cf8079f25c719ec9de490000000000000000000000000000000011ef6892a27e024d370be5bc24ebc20d7df6712675a88d0d37102a8abef4376024d7e48168cf58c947bd0fe98109ff8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ca508b3a966e983d0ce9e9867cf880ba06cc315bd4727d8a88edf5ed4e027c2ff7aec031b760066c58c453d7734ac400000000000000000000000000000000028b63b094a8d86fbce842a53dd32f9ef5afdae5d9bc34b8cf1cdddd836696d8c675ce6a8e78c870f6ca716360c774741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f86f0b35a28fd5991563a53e7c48e4e286e14fad884913641c4bffbb9d6a6ff4b5c66493028b293aa5982599a069b76000000000000000000000000000000000264a06277f40aa4c028046adb18227df143d9084bb4a78cb04b06abd10fd87a54c4d9d86c279a7c7053b3b0182dc29d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a146ca3a00e52ee2aebe6549c813e0d84eeae207dd7ddc04d9483ca89758e772d9344e13327f3cc0035ed9f9c114f3000000000000000000000000000000000fe02b49ae9af686ba4df1974970d23a451e0677420ce121d0385358e929046b70e84ba628f1bc196c81afdd0362b6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001793650228fe4e9967adefba5a8c4ac11a7a2c67f89fe59859f0df93af9fa7523794a281d91a895c1d5977a42e814d2e00000000000000000000000000000000048822e74234d552aff9b745529c8f944995b99d544cab9ad383ab3c12708062d2e7831daeb21e771e2169de4c7825b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000794b03d2e74bdbe359a83edd7caa80c263166a0957064f1ea9ec777ff4388272582b5327d152fcbdd9ab6026e91028b00000000000000000000000000000000076c7bb97f6a410b55e18243d0bd8a0765aac01bd30f554b70954490635c1209573936f85c47d7bc4f2d3f35542699fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155c15b2dc77537b9bcb990f071c75f443bda672543b32e22bdb38fbb2849479a4d365fa355572bef556d087c06b98f000000000000000000000000000000000175aeb978b7429d7c4ebee3f60562fdc690b66de592fb092d87c602b0920f4e074bd9746810bdcdc86a406def5f86b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f9e536073688c3b5e10d0638bb1fded27316c7d886b1e8d36a10700ed430af1e4dd8f32d1742860cd512fed8ff389b0000000000000000000000000000000008d6d8e782b34ca7fffacf06793b8d298ee7530a1dd23c83642966fafe436a92c72cc323ea587528f41b67f2dd3f9fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb866b97455eb41cee5003358842325b15103faa1c9852de2fc2cc67885c6851871c7a4510991f533d7cfb2233e476000000000000000000000000000000000aed5d8272afcdf0b1ec01c8a3391c424b79b97616b5a4d3305ebc475fa97d4901304d750f9f564f5edbd42f19fd27d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fadfc5038ee177f237b819694e731419d62aebda7e21277d19294a43a51ef9c8f22c366e3a124ecbb8944ba2b9bb890000000000000000000000000000000006fa5acce813fcb979789c1156a9bbdbbf1559644443e680c797fd9dc0bec17a62e10d9ba33704bb50b86fafdba709a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c39ec27d78349f7181cba585a39781d841624c6e57fd208c8a8d0c37847ae461fe6300a8a9257dc7da44ec8cce0053000000000000000000000000000000000e8e00a75f7561475128612bf6ef56e8dc569ff862473a1cd7525659baab6cf744ab159f73dde0fb6c6bd09a18fd0c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006affa0c9c1b768aaf7b1e2260814b77a6f8aa15ed56be64a06763db8878696beacb7dc24ee152975bad425e40d75f8600000000000000000000000000000000090b2128725879a47345e54b7f39a28aea6fe76d768b34662b70c2c633bfa1be1df304686593948f587a94592ebf21f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542c6ed5180ab050b49d31be82a87b7ddd8bbaef7735352648c8568d8d9fe102a2a2899f97f8a7df3fd75736e64b14200000000000000000000000000000000086b6ba7cb58c7423a4cd6f2cdcb449534b53076b39078cf4c935af844157d528f26e60fac3eb3adaca2921f59dadefe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953b1103f5abdfe88860fdd6a3f90250117f64bca5e03c9f5965932ac9ce312c9d2c8d19091bf68f87801f5b543b22300000000000000000000000000000000132be64b57b2e759b146e7760ac1a53ed1a3254390562720667a40c63d32a2331fdef926c4f06cdf64209187541053e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000331758b7be8ff4a64ec908c5140b933796b2a07d637407843bf79bc613c431d66edfcfe684c4dfb4b129d8eb27a874e0000000000000000000000000000000008479ed2b5695566bc3994d682560631d9565568126d77b009702944361a256fe35b4e66b927fce84e5ca994fdf3b6b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e893eb55fb0f55056fdc82b0f6e41d664f67252a265d4b5594815b46f0789373b74fececcc9d2e81ddd04dccb426730000000000000000000000000000000004bbae027113ad216d8328062d96aea8c45874b353ce77d19b2dd14ceba84552fea9fd4c7e222cc946bc07866151d9c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102b42aef6f2adab2f76334e7bb08bdc2b953cb309dcffa31708acb0ddf0b7aa3588e08dd7e86940802b34676164722b000000000000000000000000000000000e0c018f9c43e9770c10b54dd8dde001c46f6a919c283e7fb1f3ba29de335f9dad0ccf4038ee9ad37cf980ac961183361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000933bb077687ee622afc5526562ccbedf07625aff161e6006df1a46e203cfe8731d42a61d11144ec4314ebe84ffd4933000000000000000000000000000000000e83e5102f14bd1a6473eb086c4126d7dfeb4f64d5af12b873f5966f16fa6ce5662f7eb50129545b281baa5b116b0a341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007083de341510837c7bdd0e6f51aa0f6e349675a7d3082602c3b8512ef1394128ae2998f99975cda75e857b5a08d85fa0000000000000000000000000000000002011896213fe4bbe185b8d162198d5ede677f08a6812fb6f0140c96e79d14aa73bc837a05ffac78325b85bea18019a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018080d135b5ca27ed909790a81882ba4ef3a3ede0cb00825f76cb7d7beb119ae0595f0a9acd5a95a5a79507069e73a14000000000000000000000000000000000be82cf3cd5ae1469b8db11d86a2ba976c5bc20cea89390cb79a6c0d611e0da134a7de7f6464ccad24cc1c1d9f40e7561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037302bbe9bb49dea9b0aa5a22a831baf90737ee4cd327b8726365d78f34b4064798a6783e14940a1a773b65149c4319000000000000000000000000000000000a7e7099caf057213b267a02ad5585402e522bfeccb7818637c3305066aa9d28bceeeebd9430207db20fed0b9e08cacb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121cae27647d2e02f3c43923af556a3eda2e5c22220a32e4dd41d100c4d4c31bf35295b9219ee9fe4ab0081dd51bdde000000000000000000000000000000001999191f645cf20ec8515ac5c1c95c84ba80b51ba8834cc12d6507e0200eb554a35a1a179d74ef555cf0c7ac911d8f0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014768f7c76e7166819bffe5f58e8aabaf46b7a1ebe407a5f83e05fbbd3f4609260b690dd09e2d0f03e579bfbc466f50600000000000000000000000000000000135127353681d15b513061d817af122c1e0d8ec5e948be376d2b34a71a3f7c608cbd183166dffd70ca727c8cbedae3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006354c42ca4449a9e9a983795f059a70752cb164e5b9a845b8fbc4edb4f44a0166597ab0293835de7911ed4063f00505000000000000000000000000000000000fb5501b5b733903ef053122257d8adca07bf0e3e333a969206c6386fccf4b4539b5ba9d40755485a633240b3bea207a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a71e8a6655847a09485b049a3d0c23837f6d96cb674e4b94f7799c825edf0389fbd25a7c8e5ec33578ee82f193b6db0000000000000000000000000000000013f9e00df2cf47117fd1468467bdabc00ec60f413e683540d2f0d3ca8289e981effa1a043df028622035627894a891d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006375f88dddd3b804da297692e8bb8b90fa73feaed748194502b9671f1ec826c5fe6a26d7add27cc380fb4028e0ca0ef000000000000000000000000000000000830ea097f451e784aa34e1524a354f57f85cfd63515d3ae1a9906d226ae67563532318bc3172bb69a7d425f312c52a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846a424ff14eca9df30ecaf599ef62aa08d1e5698b64dea21e6eb79d995a35f70b0fd31b9e4ee12e679123208ada404000000000000000000000000000000001424367c38e2ebd6664b8e48a85a2e0cc9b297d94e473161280ccd1027e6ecf41eded5ec81a6a66ecfbfad7d33a097121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd6111af85f5bd4536452f3015c4d2d6beb589017dd4bc13c6bebe9a3af6a8748d3ea6338db6da9fa7f35bc8432e0a40000000000000000000000000000000016b80b7196538399b4bb193ade0e85b76d27f7a68c9a2dbdc2202873c428efc34660fbf69d0997127df6a69f88134b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006acc0cfd0cbd079960c7f9e836cee7caf9cf0f54de368ba7638c825d0d4546ccc9a337bec1887398531753b17bd86e60000000000000000000000000000000018d1d4284057fb9aba6957f579bc7ef6fcce5c6c5aa35a04b31a9aeb5ad19f3200547caee022dd7b295dfff5d3f2704c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101082ae48861dcb8fcf305c400a1cf7233eb0761061b9206e502f47bcad693d6a6219b5689c7a7e7ca7f2fbcbc2a8aa000000000000000000000000000000000c4130c8d3c4fa31b77f988873067cde306f9371cba12715e5fe5c4e186d510549333b53190b85343e8aa4b1f362d26e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000504138e95e37a9c2d4e095d2fec28903c66bebb772066988ce59d2a29f9c3c015508985a7a176def99a2abce4de616600000000000000000000000000000000111e201662e9d65f31510309b23b162188d64426bcb9bf578a03676b575a870122bd1f7c9af82643627234db450337d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f28e792e50d609cf386b1a93c564a9a1c300eca0680ba712542e26f29194bf0766559bee85d56b8f294d3e86d7d15e00000000000000000000000000000000120835cf4f386f2feb77571b73c1e47772bd10737172ab468e8cb6c59e6fe149a65a0685de2f138778942b4cc3e234131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120cbf33df5a672af8dded8c7053d880b3a83f9eeacbe40ca19219511f29d124d89d8a97953e941951b765477e593af4000000000000000000000000000000001107f2c380c782e59a86e94f0e76711c1223cb639f1551183e1edbef1f4333f84cd8f0ae8e723e6ecf212f44061941141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001edee51b8abeb21f54aef507f4724a96f81e3d5ca7437c4803303e5b01ffd2c7de10aa628ebee3decdbd305fb5baf39000000000000000000000000000000000445f8f00c969bae5a6d54d238100c52f7eb4f35736f1d5988897ad5e300696d41c0d7f9193bb04914ff2b0be3e035dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000687a77ef6a60972ad3432cba6b873f6a2b08b48083793fbf4a87c8290adb5172997f94e3296c8306056e07147df370f000000000000000000000000000000000d9cfe84e5801ea837e4ec1cab4544039aa2e3768609b6461bcdab951b3d9d3741dbfaca7b01aa94e7d247455ea7de131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001679c2eb18b050738580fb246c7a55122e488bd2edae779ae6fc7a40656a9f4828b5cfc1ff7021eae2f8fa6c04ad3db900000000000000000000000000000000114c85ccfe5f7a89f2030b1dcc11f938b936eacfd925e83303ac2be460a118fe5d2759595649da30befd8b6a06807d1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001303af356b6b6939dd259500d8cc4b1676bb9171302f0ae4e001b37d6ae1246aa40cdafbf0c34e29ba9ad24b3205701c000000000000000000000000000000001734c4193f4a18589eb6d5b13625840ee2a7a2be7c542146b0d438f51d2d84370a94141ab5c7032407759c06472d3d961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dbd31e8de7318b2e270be60d2dbcd4767fdfd7c960201fed2c7829cf3f584e7ce3b0c258d1072fae11832849bbfdf900000000000000000000000000000000145195dbec54185bc1e6c2e4dff01b5d26b90dc5033e50ce314c5cc64d18bdc4a5308d5d4ee0fc1b4e1105785f74b2d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae8c4563a72f06ffaf04413f8ca804358a17db5e8e3fe0d6b41c2ee838b8c2689085625b25171bc65215e6d2b2b644000000000000000000000000000000000ba2cbaee5414addb5bedc652e178818de954a978973ea7638db701532544d64f48f67d9d3704e77b72d1d500d5b69561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132fccb6c20ac77091c3c5aae6d07cb17ac172acc2892a5263ce108bd8c2969ac7bc4f932837e3caf409207af8d8377e0000000000000000000000000000000001274ebf16c73daeaffd9cf38f01ebf44364c4647f42661a5b92f4d3c9b33cf2b5fae9c4be40a75c9d24b43b63192f601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faf54a39aace8820e9ae36fc2e8f1845a970164ca88d4af5962386039f6f07ac0d48a9f95353c9710fae037513d8a000000000000000000000000000000000011d31bfe8c993a3f6ef42678332cfa8016b8663866302062316c3e79318c54c90ca535b739eaabb78b961a68058898011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010659413c701e67ce4a34cc928a8c087f6c8de05b92d3b0dac75f47fbb1aeecdae1ff45a421c5dc5ee3e3f74589c2700000000000000000000000000000000000f22ac991aff543ce72b98387933547411706e729223163631f485cca3b534a5aea24df5bb53c9ad80805a8f3feb8a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069255de4844a192d0c3c90cdb3ec35ab01d27f1a06f2aa995a18a30435a8eedade9875dc6e605d4897b84b5cdebe57d0000000000000000000000000000000013883849f8a9be30bff9b68f1a0e8129d1c8a59f0afc22d66a40f0144bb3cdb8d796c8ddb290670aaef63a54ca447aec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001300271c3af761784dc724116041acb1018a9cca9199b4a42dd2fa64a3ec73a15d7f5cb12e54f618b39fba8adb1d2231000000000000000000000000000000001704169e0868e4ddaf6f095a2ad8563a3074e5e1f616a8cc2115ac374742fda9e89f673da3d0cd14f73cb735729cd45f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a2fbbdf84b534ae99b01a6aafe4710870d4d5e5ae7e081aab75a552ca1713567cd83fcda0c85c96c3a48a69cb107010000000000000000000000000000000003670f38bbb499b2049ae5bbbb23d4301d6868c34d5210f60c0554d79c68a4b3052b8ca816d1f3c8c98194c5b9ef52381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a8ff87dea01412962ff6f139cec07efbe71d1f82bbc0e1dc16b5e51e96216c78a15baa3ca6b98fb7f9cfc5017d868a000000000000000000000000000000000b117e0415dd33dd550f953f970c429327dbf2765fbb1fbc67ad1452bba0e6ae40359cd282b11b5b8b2a64c64675a5d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dc9ccdea5be610853f3cc3f038a3160dabffd0fb5699e5a6fdb9ee81b18ca380578d93bcbd5756d37865fb01c9887500000000000000000000000000000000155ec6cd23a7b999cc56f3fc478d09f9bd6944160893b10ad1f0c6f6213c22949051f17c24e53373e9a9cc634a32ed181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a838720b32f7ffc4fbf767716da941aea60419a891321633720323908bb2a844d54c7f79aaed6fd89b01dcc12d758fc0000000000000000000000000000000019570dc54a55b7fdb0ad8567a63bb3859990e92a180d72d84abb64a52a41194fbfdb665f3c71006ffc13f8f6e53cb0ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179ce38d8751ee0de1ba4b7a002b21f1735621e47934e999fbefb75e66a7782b8a058120d4bee09dd1fa0c2d23dac328000000000000000000000000000000000594d4a1bef78e6d48597037276ad72f79de664edd41be96701f6bd95ad218d718a98465a3a21288718635e6bed394671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005fe6881494843a51f0c1ebcd282c9752c21df1a4e213f05b8e2a2b20cf78c90fe3e3aa40ef2cba2395309d9754308d000000000000000000000000000000000be839bbc2997c0faa69a0625a243a18ef81912d9331885e5c1f5ab2d3781ed4055b2e5addb8a82b7772a9730fd5ad7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6154e29cc1766b50ff0c7028bdeb6b618e0774e8d2e6e4d1146e968c75d2ae66717a5b556cb95e3ffdf73bb0bcb61900000000000000000000000000000000181f370f3da74defd80351b73e0922a6b1a8be59770b7d419e48ec8ccb5989be41cc9773e9737b8b4adc0a03051bbc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192717b42a44600e9b15c482fca35e5a1b0f9f409773e249d2ba1575b19ed200a54337a21e8937cafcc23fd8d390ff480000000000000000000000000000000001743643b43c9691bc3138e5717f76002f84da6f5c7b6d1d1963c488968cc0667b1130e6b82caee257ae1437163c1c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e539e00b705dd4c5ebdad2bda367f388af1bc17d58f34bef0cfa1bf81053bde78883e45d98ee02836f30ea17cb2bff000000000000000000000000000000001772f1635eaeff8bb5fa403552bf09e93b1b12ac177966402193add71b658c8839d24ac67b812da75d0676cef5526ece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a260e154947659a63c1ed7e77647dfc21810b12779b3a25c6b24b1d2f303b0617eb4642605bdbeaacefbb5c24c7d9300000000000000000000000000000000128f13cf0d57cfdde4838507e43cdb45c777051d332272d99cd969f2d9e217a72960cf790d702e89c778877dd0e759101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2d77c29ebfb8d72da1776fba255d303f7c93bb65a7cf863a82810a37cfded93ee19f963ed29eb4518ae1f7139f30fa000000000000000000000000000000000bfcb2a2ae252e4385f81cb229980c35997afed388e60394edc6eeb9e71bb02e23e3166c0f51a0b8b01626aecdc9179f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ca6288b0ea2c3150e49fba5119a54700c010a45f3bd6a1b0cebdf015378b49d00afb3ae550438c7a11345202240b270000000000000000000000000000000011c138d729d246fef585a7b705583eba764a2c3152473101ef0aeb012303008eee1ff1d3ffc00858eb214b9933fd4d911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f90e4ac0a7b1be67b0e56aa75b125c7f5a80be8e14598f2e2822c506b3c100451047f8fce8d653ce8709a8c786cf0c000000000000000000000000000000001813d56dac08123ca87c630316bd9866aaf5b3a0ce3be06f7a82a5ee63297c8a886b3be7d1523d1d0b506733c80696271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2d784b83fe2ec700ed5795a40c193652af97888ecb6ef72d08392d830129e576154a5541825631b0e61e58881eb37d0000000000000000000000000000000013a9d61b64643b678b9c699fb3d674fd490a914f0ed38a704fa5a56bc3d35e337493d8617898d2b57bf43c6bb29494761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165349a37ebd169f0260c7db05d44ae2a76a44bf5d316deeae16698d4d3d9058c422f1e2d9905801cbbf4f6043bc401b000000000000000000000000000000000c5934f5d1d2647cec611bc7630d2efb7acbf45ee16b55fe905c223bf7e05e6ff79f0c39ff5398f91f5ba9e7cf174d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100d1ee368345f9a87054104064d0f75dfee109ec604f154dee6e1af3b1b08d424fa9e66029731937c2ad851f753d11b00000000000000000000000000000000083210b1726bceac51c24687dc4bb6d4567c6e618209d92334970169830480818dde1d64c5a5a6700c26788d1091e98a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b2c06b3f6f2a1a60089f5342cada61581e2fff1e370b7dbbb5a22077ce22dd04a9ce479c10d11d5666bccd1fe632fb000000000000000000000000000000000b3cbf13819cc2f66fa5545e11d0bb330735f742e3801f5e54631f0369e3bc4727501f6a15edba2e2c1d1fd1ae3276f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dc64798454e1aa7d68f7d9baaf9ba385e8951c4132571bfbdbf2a487803921fd9317f955e7916e535259738ce18e870000000000000000000000000000000005c28c8dc84c1d7b3eb0e29af53860fa91eee0c714a5d4e8de64d78465ca907360ed34d2b64be348c142ba112035e59e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8b0c897519bd76ede3e7c0f4ab79ea126d1d357533aba9f6c23f59824f78aaaefaf060016f6f5560bdc6dc5fb318010000000000000000000000000000000006794bda5513135cd855f6dffcc1a65bf47ececdd17dbdf6e0a1f3e06aecb2a97ba04e91662bb110b21739fb7be34ebd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099c8e51d1a4f7199b54e97ed61a7480b41ad27d5ab206e15ece4b5c7a987fe0471749999ad2c8a744816994d59f19200000000000000000000000000000000009e167a005678b7f292edc4731bb6670c43d0474072a20516d20b70ae81ad1fc3413582a968fc1db40a72d8578e2cd331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000facff84b66610d77f9b78bcfc57f4f61e46cbcaafe72922e7a1e873d633aba2efdab3bf4ee28889492198040a1aa68b0000000000000000000000000000000010ba41684014c1eea90d7abed012bbb7089b634d6723d9b8edfaef9cd6563d88fb8dc3b537a51b38e42cd7bea48a3a221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f3cd92904b1309e7cb1317b8cf38911bfeb4aed1498708aaf23f397653d1fe05713739804152e114a916bf424d22d000000000000000000000000000000000fe7d99ea5ddb1be034b287aa2c8e4423c5dbcbbc7dbf4dca86ba62bd8d8397bc955c68273ab678cdb05ede3b286ac3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000201503d875067ee42d47dd9579885878c296836eb4ee2c38e5f73dd37d25cb78c42224352433e7c86746322d3562081000000000000000000000000000000000776a1c257f995761b0d7fc0285ede92007ef59845adc326f9bd5f768cc072dc5a2a90a458c5ee0655f1a889f93a0a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102d6e00945c7bb47f49efe30c1293538a791f0dd8b072b2cc84aa5947bf6b45f0cdecb3f63160deea6aaa8daec136ae00000000000000000000000000000000015d35b59e1b9177b52414276a2bbf1467581cb889fbdc418ad7127597f7ede72cfe884b58797a22b798c85bac0ab0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026dff238e4beb8a38a0069f24abf65fc9a4c186819577d67acb646c49c21941740c5c947d24ed5df325662acc30f972000000000000000000000000000000000828bfd7419679dceac17308942449122f17cc0b4f81deae5eb3525e96df376cd1259303602a1af03c26343424c71d691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000190201b688466c0cb8a17df1c911d9bdfc87c3587ab75f2841e21f394259d465e454e030727d7f3f026b32b10d4c28000000000000000000000000000000000aee0110214bd92791622bad2ccdbf3db6313d78a8b664e8b5eb375f13dfbb9972c366675f4bc983678df72a705845461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008be8f9ec9e6934d1d33f1f39245e9ca489499d6a75b87ced583424718685d75d48436da9efa52f62a2940f632a5bfd00000000000000000000000000000000017fb5c649143e926f03e481b769c16259523b6799d32a7a024e0a886b3467746db9d8fdbb653ce0d791d005ee3a2c8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155f74735b56df1977767a359aa72cc752e5d2509a36c03cf293be90b56dc0c06adc031869d3b8dccde550c2ea7a66d00000000000000000000000000000000000e2447157d6c989dcd9c1655740d4fef8101edddec11f9ce7f7360f9683705bb6fa93a18b8f55ed11300bb5fa3780221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001600caacef5548d43d540e4de69bf7410c25f1e82bba94aa26cf7a5c8e352d3194791f3a235dbbdf86ac2ee36220aa91000000000000000000000000000000000d16fd83c4036ba7b6ac2a4c6912e1f31770fe2016465c545e3d3efc5382714dcd592430697b88fa9b2ea886bd470f6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001481a31ad1ef049758736efc9455de4e3aba3c2bd2ed0ef029a594edc0329e8ce8fa8c011c0d033535f0b85de81dd634000000000000000000000000000000000de3aea61f123096618ce9bb27146d970b15221e3af62160a7cae9c2ba895a15b012ecbbb116a25a2d114c4843e748d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d646dead28b0d943b76ac13df588d9636e9dc4ffa98b246c59700235add17ea8d3e73b92ccfd34734c6a81b2fec56f00000000000000000000000000000000076cb837003c71b953ed3bb2382737fc48ca20b6662e1a86c26b6721a7880f62c9fe95834115b14d389d80eaa52efc801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018929d6fce2d5bb63b818c2599280bd1d3c88c6e5fed963687970ed51ba2f35b03a6eefb4504c2188da37696b4a3ad470000000000000000000000000000000011fd125043db4f53c2893bae9986f8eb4df977662f8e43c39413ca4e02d2e3063806a8e647008d1b4b98dacb68a1d0db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214e7d85275fffc166c407c36e7136318c3b1354c394cd63cba451a13634ac4665db37f70126b595d7af0db6c3e86e20000000000000000000000000000000000fd57354bbe32061edead22368eb7a482560736865b56a1e8e9b4807d5fe67be7c26855e8b8f1b098407bd12b3519fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e3383a2c836964cf4cf1af0e1dd031a9add1699a52de7405da135b4daa2b245b92cd03ffab4bcdab438889a0143cf0000000000000000000000000000000000a47b9d94e3e6391f4ae43c890b0b376fa476840e9ace40b3521dc8aa28dcdce6aa9c4dc523311b6e783f4ba0be504fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47320c9e5c0a24acc7a390ef285e6f8fc824dcc59b37911159eb710bbb1056b7245544099a4f15c0f45d4c2fa608e9000000000000000000000000000000000e65579a534e6439ffa92cc5db147a383713c99a1c8a4978ed1b23863657e99f417c35382aa959d4dbaab399a2882e591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d816bb18ff5c9134741e176858252250cf8ce0645a5968ad97b8ed887a2bd2b8c9baaf883213fce5bcd0252155d879000000000000000000000000000000000e068ee148faec0073fa4d0d9550d34b3bcc6fb1d1200d79ba83ef96432e443c149c0ce961d260cb295adfc7f333b1551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056c60dadfbcb37fbf6cccc9488993ee231ca3879ac286e9157157e785593b7c4b4b6bac35c12876155480b1ff087e5b000000000000000000000000000000001314e5da6ae7bb509c6fd653c6d7e188935ac1d144fc1ea470663223360a7fc981ded7290ffe5ffd175d7f1a9139fa2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d50f204e4712cd679b3d22df1daef11753c7a7176881206eba212d1c10986e6fba28b6805812dfe57795165d4c16b610000000000000000000000000000000011ac3d389adc7b5ef73dd685a31591bb2c5cd9337cfb89a04b40d1c91e1c3d13da9a6f759fc0066d159e0e720c096d811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d844baaf2c5845ae19bffcbac2b700266fbcfb05af7aae68413c486fadea5dbcb84a254669f8f28a2a96c816030655500000000000000000000000000000000048f871d8257ec42c66946dc1586e56cd7d484122dcd1eb8f80d57d18cbaea74af17cdca248ec2ede4a2715c555dbfe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006333835480b27866874bb645e4edd96627cd3d3a1feb970cf1a0e322e653db5397fe51613d6f551ee7dfdf0e3e8b064000000000000000000000000000000000f427767fb9fa4caa1a40664f2826f11a903aaeb15d21d0ef3d43d4ed2542ab0a9ca9f906154e111e93d49a98514bde41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000240e4c915d9623039391c31698b67774b58bf5e66860a0a3de754bd619ac37c1baed781f4fa03b0706b2866b49c0a6400000000000000000000000000000000194f10c086e0c516d24a04cb9572a22ba6160bcc7e41fc463e8e5014c98b306991ca45062e99c5609e7f1f57d57ea8a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a98a3f2680e9fca1a339f4d6e3aba899b5928455077ea91460459204eb455c4ef30bc96345868a3f8fcc77b6d97f3d0000000000000000000000000000000009ce080aa2996c7e05250d2ad55b5ddc34473ab9835643cfac3c469385559e5f38aadac274a2318a6d908655525181641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001af04544270c96db2c69f66970f78c2df16310dabdec9669fb76a8fb6d77898d4c9e877878e54f1e071594bfc87a30000000000000000000000000000000000d17e6817bfb3d5219ddb6d321ff350c6895634ffb59e34c304311faf3a1baf193a7b2e28ce4027e9397d2e89159be8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d35fa8ceb4006f445a874eae9feb799de300d4804c41e9dac61fd548d9a2b9b17874a952fc2ed3e3c02a6c9bd3655180000000000000000000000000000000000ac704982d1fa04c0a1743f7c1291f32bbf7eb1543a4cbf020bd383f05da9ebfc7a5bfe4e8d84666389026d20d9c30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c4a5c18e9579f40e71c9c7d14621c0eef45415886e859682dfc157b017d8ff95d26abb53ba6eb2473313da54bd19cb0000000000000000000000000000000012e4fd99b3b5716b2809a9b3472824fd3e97a899da85a815f18ba8c82a2dbbfe88be355430fc53abce874c3caa8a5aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089f21496b764dfd698ce3217eabbbf9a52835f4175287c773e071dca489cd5e591cc3e12f2955dba614e2434ec3be930000000000000000000000000000000004b85b8101db1c0b9cad5db76b91b66a627ffa80eef895376c92feb33d932884fbbfaa92ce709b852bdc0aa198ee5ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b16f7b24ad10e7fcd563011dd0aaf91c65c807e24aae60e101f256c529c4a6f629795d77428a8151c335925159c4030000000000000000000000000000000019756b0edfa02a09845def99718820fa83884c738894f3966c185e876b2020265b072f4b6c03898a89f94112a210afe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa0590cf2a5d251280aadc3696e333a5c78708f67b61e2242497862094c1bf81e935cadf77ef6bae9166c757b7bddc000000000000000000000000000000000092a33b018afdae7424d85d3751f223b9daa9bac43b0a39851a77489c57c1e473668423653d3f4ea361536ac54d8ceb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094ba3e7c34d34d089f152718943e611dd6d55f1b87515842ff1159755f54521ad44389706b1ba53a2dd1562b08cf7ef00000000000000000000000000000000142ce57e9546541366ce7105bc08f9aa3fba88c713488ddd9eeee1a01e42f43d21f77c4e78dbf214a1331bf85d7109881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031a0259782fc7858a1693cef18b1f0a417d331f276c09ee24c3a7bda56cec32e9cc928a9ad94dfe73d7c4fd7f880aa00000000000000000000000000000000009aa2f062bbde2a43719802a23681c93b8a30a1f6e831fa5031ed714cced335338d368d4cacf149a8218cf7a1bec7e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a90b55d5b1ea865bff9a24fbe0b2784223af2ac89e650fee9089f6346bf8b68398fcdd65a3692cae226edff9d5d5be0000000000000000000000000000000002318b9ff0110d98075177c441af7cdb8685924d1d0016141502b6cb67235fd2ddd7a8778576eb21570b9d7400f6d2801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000790b91e65e8f72d54620a4a9909461db27a50c3d3c6a617ce012510396c3f5fc40dfcc39dc39b41f2bd4306a16f5b6a00000000000000000000000000000000089ae1065da7c181d410cda0ef8fd73a3eb4f93b18952ca9816819498e4523bd02b320917432de5c16c12cc62fb029261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012239cddf03e892e24cc685fb69ec606436499d89451bed33fbf5fcfde2346a0586bcd1f6d707d856efdd1373067fcd600000000000000000000000000000000030b03acb56905dc505e6a1fca8518c4abee498eec5ab6190a2914994aa43a8e7cae90289d78af17ff8e75e547b1e48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f324fae49476c33145d1e5c7945b2e8ad1480d626238ce79483e041031b7a892234713b396df4cf9c331a2a433052900000000000000000000000000000000094d8615289244960b09f609bc326f6fa65e4df9f18627b9fafafe4e24b078fa068de9dbbe6b873e32987d7689397ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5efaacc23398c3bc7c94494b726605b4c6b50de59200e6fa336fd04d09a021952e27ca9bed41e5ef65e3bf7d485311000000000000000000000000000000000deab38e2665ccf482815f3d873c1cfd5a2ada6cd5242cbf8b63f60e2e132da79a6f4e75d52a22cb8e71fbb578a31be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154bbdfdb9b004ce9d4aca1206616b788bab2e4fc34b2ec238d174d6b4625080f6ae62fc0eb074815ab611f6caf7ff690000000000000000000000000000000017e1892456b287dc447af8326f764a532eb9046f76f3f82779f30966e72cde734199d9cddf7271749659f8b2ec9016a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009903507237c5d0dbc2b9f449d02646e5036270bcfebfa4ea75baeadaca336c73cc2cbb316cbb13d75522807096da592000000000000000000000000000000000e28b6566f0191af4af5e00851aa32517a3b8d11e04135d1ae7f2e846be466d62d4f872f5dae6ec9c88d9050a3ced9161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d901a94f3ba007f50f6ad201f2e3fc987d59bd975af97e8445bdd97ece929e5c4caeb25e6e47263b4de4bdf2643be0b0000000000000000000000000000000001e8baa00a480e4fa4494b4eec0701d0f8a18b29c09c1e195db40c8a32ee3f4696d325138551a881172916463de66dcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131f465d71e863f700c96bffbe7981b1a99cc36e6ef552d20702ab8d05a6159713ef524a3622a527778b751870a541ff000000000000000000000000000000000f4305e3c3bf73987d3a436f5865d254f41bc441ac9f981f4d4c99123247cba9ca25e574fae5e91c390a66b97e4dc1e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175df3d0490b6552bf3586d942d325e3409b536a178bf661d74b09b1b11528295c64b0e6108f972a498a1c7211972497000000000000000000000000000000000285d7d92c26cfcb6490463261441d80b2f7db507661f60c4f2fcfba5395a828fd4cb161caa4807a2324ec32d579695a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a337ef7c201af544735c98b476e399b3a8f8d7d24da93aa71c87ecd9159bec2a27250dbf7266a16070e04a65fc99af3000000000000000000000000000000000d4c907d884a60750a286bea5be8431b34dc2fd176247c454e512399b6619429c5954d0e2e37015f39210d9f34ad58ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3141418dc7c3d920b4632b0d2d130ce96447c23e33147873a0f09b966174ce87bb79693d6a9bcc6b244a94f6e08f2400000000000000000000000000000000009db9a9987602cefdaa31c4d989939416201c8108e3b2018fcb2a16b66f2c6467f58040b94e06d0ab887d9c43d440fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c31630dab0e0267be1e851d53879c25f9d88ac00af0d8f954f49fd9f7710811ef73d765b7dcd5a5f65c69db0e9af4680000000000000000000000000000000007f574e34136fa80d053ae54b09ac88174293ba4c11e2dfff0c2fbd71c629049fbe1ba2d5f273e7f54315e3a5f5379481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125583fdc8108e2fbcb99e7e552df1df1f4cc1391a199367d2d5bfb2f0e668c824e211dd870656069a4acb31f7db287100000000000000000000000000000000000e8c15c242d3b30898490e770cd234a06548b538641c1d6a833b8a78a246a8868ed63a345726c5029a7cc4684cab201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001060e5b2bc5f77f1eaf14eddcfd26a9308d13b301babe482fda07530015b1a3f8e4f40378e35e9d7089429c3681fed7800000000000000000000000000000000040019fabc6d8c43318f76fb0a86c5cb52c80d2353024028c0804d67bbd3d33eb1870647233f9e84e9b9239f5ca48e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151ff39e48f25ddbe062ff19598bfdfb2822b7e95d6bd1da15692837fcc09187c70188aaeaf86321f6f2aff8f80ed15a000000000000000000000000000000001376c76e98c21c36edda629dd0e97a3fe7e4d4afe0290a4fba39b411f756dc5b29eb2923f624b5e28a69ca600548eb0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb951d73ac5738e7017c387608a414e7361b2856c8a1d7c31f1a8c8914ecd567e3d0b83114a74a84f28f0b42fb763e2000000000000000000000000000000000743e58183755d438540fec0de9bef9f59fd38d2fa8b63ae397991f76f9113f5d64571706a703124ac580e6960a2d50f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f25ee7f403ec7c353362d82eb250b37d97c1e261d8ea93aa5d0357e7b89182c3f194f240e1eb3a55595c1808279e40000000000000000000000000000000009f6d611a8299d79c7b95256ec0c486049596696160264217f3c5bffcf510cd2bf9732c4a45daa4b989576c04c6b59211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b0e4bbb5cd184f068cbe77d39bb5ebf6ccfd9ff3005ce2dbc0c97650179beb6757952c17d54e9a56a77f4eab6f970f000000000000000000000000000000000c871aa76217ea83a9cae63fbbe08b82ea2fbbdcb3dd182dd397f25c683e58ae3decdaf0ec30d77fc21e3014608cfdb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079d34ab1059ece3caaeeb1931834221f0d09e9d92003bf7d3f2827e2c1cbaa1c14f59eab12ff64cab4e3e376c3bba2e0000000000000000000000000000000011b1087ad170c12615c61ea76052ceac6fb6e7ceaacce91519975d564e26ef31b8af1a4b423920cafa187df4e0a4d3811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d19a1ca365a0c41c0d2c7bce87479ed493502413eea3b723c5563dd457a9fe3e9b30fd32da7b6e243b828243365fa800000000000000000000000000000000091bbe83570387ee0090988814277a3141afceeb7a22ebf868297d1f6ead99f6e4ce4b4c14f722254917a0941a753ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f7868b12ce590b753053ca5ab698e3bb46b881668fcf5256e676985c0251d645937b124f78b1c6d60012f85e2b57210000000000000000000000000000000018e156282bf224311a9cb5c37f5b473489a985996a2c234ace771cc953de48174119ce057d3716299969baca362305241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bdeb9bf087b5f0d8b0d637d6688f30d9ecf45f2a44fa723cb2080989bb50049a9efa5d03d27bae2bb2ef55784d246b000000000000000000000000000000001629db3d95e96e79ee2daae6466c1bacfc7dacc8142f9006c44c8cb38c07b43847615cc96594e1ede4df6f3497a442be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061e486c3e706f7b661ff29e10086df6ed632c1922f35e6507f84658041230b2547335f3683a66f658b72aa683dc9acc000000000000000000000000000000000e09c23d4e9a4a80d6888ec63df61dd4eb28b0274d2da0ba6b54a958cc1429175ee82c5894247262e78e839f2a720a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000006ea7fb918f8a472f6581b53d78a3474fa2c5ffc3871db3ef30c5f197c5d914b8243293b8d4b010e7e6c0e0ee6fa5670000000000000000000000000000000018be0b8edd63228e5ef968d6f65e63a0aa5b588231e9991fdb61ef429443c57b3a1e3a6d430ad61aab48a08e5a9ca27e", + "Name": "g1msm-512-jwasinger", + "Gas": 1069056, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000113432aee77ba2a2cce46320b0e6b6ea7f1e72d5089189ee383fc282ee68e121464014f2d8cc1ce9589e4681d84389e9000000000000000000000000000000000b77a1adcbd5037e3cd58e0ecaa34fdc5fce2f9cbedaf7842ce88feb585e93f0f44a0c008dd61b97c2de3fceb7e702621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019365a84f7f18cb1f77621838b3fbe27f988954d10b4761b6f7b70fcd97c4044423dd2dcebc4de2e310fe6e0f9ac53590000000000000000000000000000000000098c84ae8985cc5a3b7abc99330028832694f98a7a1be3e20a39471c20b6b956537fbea455f710067ba2adf4fc70db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc2cadb6838504a5f72728d36344461e9c750bbaa5cdec43b4e0cc8357e1b59d5c14096169fbaf73a810a9b5195f4550000000000000000000000000000000010896fbb1229fcb031bc75710f543a108065a58d44c136f7d8d948b9c2b6d3726f1823d16d6263b2df8ea8277d511c8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044561988e8841270f2507a7df77cea2c297400c2fc5d62f589312e9bbb62051a2e7370a5d1e19f114ff4b8c6b9c2f8c00000000000000000000000000000000147510462aecae094f843673231cd3100a2773103c7d295986414b7b8972ccbc4a6de2fc63b47e3749c1c514f57a474e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a3fc99f05b8c637e291a664d62e6144cae845146cbbb9771bf3cd542c2dc2e9a118cf06bf3342e3aef1edd17c4c372000000000000000000000000000000000ee1b77b299a4e94f11da54949508de1db2e6255ac1a66712b8cdba1e85b5ee03a9d471afa089c027333b5f5805ca0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143f9bccd959d294e7c216fd8a036fab7eff35f28bf07d71c7f54d43adc3418ce79223e481a6d1f972fbcff544308d8e0000000000000000000000000000000011f92a6ee225f73eaf8ba36c11d622e87faa14a8a90f56106b92e9a62fbfd45759fda7085b565b12e0b8237d0cd5aa4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c0ef9097e37f2a86731f7c5911ed15039eabd8c27e1d6a64d87a70999c349eec724e13c32cc42578258e0655030f720000000000000000000000000000000007f0a5c7609ff876553752f61451c347a654fd8b031d2850454882c8fa0d7150843310317474ab276ae26e4ff98971501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191fcb881bf42e69891d5ebcaa31c2a3bf5be434aab60d9bc5054c636f94952c78a7a0c11f24c6f81f80818cf008c8ab00000000000000000000000000000000141ecbf1443a22a2f84ef25af0c86b94ea22421813f2611fc3b10d9dbee81f02be6035e6bfe6a584260544ffc5c87eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019481f27232878f7fe934b5ddcb8dcbee6f8188ce95d239016b757e105558f8c2e5544aa2cff848679f51b4963fdab030000000000000000000000000000000012c08ecf9f478bb1bf8ddf2c604dddbc42ad64d38fc7929e0444e9bab55784a3e7ac10bd3243a42b107f1dc6727326841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bcb0e19234cea0c962c31262ed250edf012078bb7239ee2013343a20291465d1e07edf6147660b9438bc67e3fdb808000000000000000000000000000000001694f48838c54e757ffad3cdda14bcdeab8bc262519b66519e0837c5e096985f4de3df7a96b106a9409323fa353d50da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013459fe4bec1150486ab637852e20167b2710237a68cae58d55e05576754d6f24826e6cb70c13bf1bbeb9475f0d724fc0000000000000000000000000000000010e6e256393e308886084f0dafb8aaf62c66a8a047a1988b0cea32da87ff54de090e437ff401928b70d21f6e24e0cdfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084b0283a379c20cb86b5f16a19ecd988d073399a6bd079fce82286084b19f28007b78774be69f2a1bf9e25746b5041a00000000000000000000000000000000066a1eea5139937ae5370c2c2507622bc68f7f8e4caa516a77affe736ef8be22f319d9f37cdb999836e22b01fefcae761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e858a7463c73d1c1459306d0bfae15d798ab6f84cfa69a2631011b7e54d1381ad5cd59e5e9bb21129233258a4e3480000000000000000000000000000000012803cafa2fea7989674d1b9565846ca506112b1a30245f653110ead0f786c9d5f8cf81e7415fb76b4419a08bae40a131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a25429ffa555112ee05a9ff02fff3ca4ea6aa23c22860a3c6892bad0dabab19fc024d2eca336a634529f381ced696f00000000000000000000000000000000083504d5a4e30bf78edcb43efecbf27b4e1825975108f2358634d34b87826c977d5e237bfbd88a7e329efd616ccc386c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000444ff3d3a8059f826623fcf31708ebeba63213568c01cfc5d84c6671d0c1849ef0eddfdc10b84d8f9c92c3ef111a21c000000000000000000000000000000000870a8448d00a3522bae6258e56fcce0a860268cb1a1b4287274c5ce1c46df3cdeb247aa26e9a02ff06f1a78df62a1161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c410231302d2c3fdb6149435322991e113e5e3a35f00418c9c42856cc4334759310476340723e65e41d244b06caa4ea0000000000000000000000000000000003ac8d2af96ce1892e0309ea65ea28dc9080a28048202023e2a1068ae6f77050d10a8e2603a5cad03535dc50162d201b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d93d50d94a9ed3a0df2798d380d726bf0215db6594187626d56f793debd40bb89bb8ec3016be41f4550d3d6f9f982b0000000000000000000000000000000014c63ce8c29eaca6fdd5d2118c741137ab4c3f210460dda3ee7d47025ed041b9857b5bd054d9bab131fbc95bd334be821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bdae65e2cd1ebc8baf215c47eed76ad0e2aa6a3ade22ec8e5576a66cc07d0d95db9b0677fb3d4a4f91e8e491c90cca00000000000000000000000000000000135a9a76d97c9ae1de332044ab9b136ad9d432a37f8ec6b3308fec708afe22d6cee3c6cbdd5b82f9ab9b3ec787b697711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5929dd20f1880ddf606baa8dbde4906e382d12cadb4b04ce8adc06cf2d983cb7491acdcc33414c5f1f26b508d3429f00000000000000000000000000000000035888738296f8fce34181526f2235add4d54942b0c6373fbaef9384cfdd3385d5227862e023d29fb571c2eefe0f5db01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017aec438a6e711bf8c2b38a668f67a6de03c75fedba39576ef5a148cf9e3066717ef402f8cc0b9cce2296e866d59c570000000000000000000000000000000007ed2fc97feec8a3cb20515bf18e1082cd425f2ad0a56a24ecc06f030479b82293a3a12e7c4f8aab615c1f8ba08ca39a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fe02fb54cdfed3c73f51b4c7936a82421d3d28cec40c647b0ec2388abfd917a7fa98d686acc128e1b9a8f61c84077d00000000000000000000000000000000088be45e91eb084b6c04bca12f27b58a21f5fa79955bc8ecec16f2f63d76abf1be188640614dd56cbaf2d7d96ecc8f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf7453ab6722bcfa9b7888785283c2f1316dccad68a3a36fd6f6dabfc984b03da4a27df36101052c54bf9f45ceb59ff000000000000000000000000000000001473e2050368bff88f1393a8f85e91e29b705045f73eada886149c1321d907c3cab9d16e6ce62eb9d0dfb06a3cf5f3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055c06d09464ca260b636297b2a10ac9a51abe2a3eb31a534d0d98f7acd5b9ea6fcc825e9507cc3845d94728d0668c3f00000000000000000000000000000000129ed1aa5219dfc87fcb406c7a8bef68878a718f32b150ac63e9e376d5f5fd93f53ed7e9d59e1963e00695523eab47661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001183182fc93c8593605a39eb4c386d27ab3e0421d092745e2721f3b63a639cd5f339a53135179441760189105b2d9a92000000000000000000000000000000000d7ed44b0fcf1bf597d90c248888cbb8bc18379a8839c1dd8c6ac2c6546ce92a9a9a0f2b178202bb3efda39547ce21bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4f122d6c3d10379f3c218e3e2dde647906d7a6c59b6521a368de00739cba713dddf859d10bf2b50c297799f86956b400000000000000000000000000000000086f9d93d7e92e57ca74f63f9e0bc03e21d1db120c59461e945655e3aba0b40b878dcf20163da835647be19911ecaa781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b21e192894e4fed3ec6ce32d1c88e67dc0de7469b2e0858242320c3961559ce9d1374da0f949a62a68e356a63d63e0000000000000000000000000000000005e40ecf59ad7f944cb4da0c032c431978c15b06f31667cbc84003b6120b4055952347ec829fbc1346b194cdfbb28f771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbac2f436836474a126878b311b14d890d97dc5d652e9abed79149145b9a1000e574eb55508c85d8dd92fc853721d0e000000000000000000000000000000000000be9e25489d986d674a0b670bfb0aead1c2434142025c86fad81d61e8ab31e68b97cb43e980e3ad6cf9c9f1ed2d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fdcb157d80318b592e0648cee81f665de61c6bad4d95e6715d8d47e8f5af8f9d934b114a49182b8a89a0a2220481c7000000000000000000000000000000000bfad6466fc3412296cfd923d7855459a28f6216e18a2b04887b5402456d6a45fa6cc6d2a0f5c990499e9fa2f542b4201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006343b246eb41b2025529103a01fed93b3166fab4a8e443651d0bf5e5bbb76b918aef6b462c20a2a9bf209db2a3029a3000000000000000000000000000000000913538ed2dc347af51cb5ca9d38503dc8a61af0dfda6c6b10915c1a6b71e6b877e78a9c4504e0a8abd92eed45a4f84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140d8df747c9a38f2ab269a09a98f574db42aad68829038e0e6d68084bbdd5bef03416e62cf6a83cef6763f3923d554c0000000000000000000000000000000010897cf20a0a2265f3c6f2b46a209d9392c99e239751840cff7401139770cf79a316a26667694d044e8f56f3aab1f1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104f01786601a06fa2e6ab9b5521345da3affdf308f0700eb3417e68ebd0f470498c897f8bc7dd4865cf462dc8a2782600000000000000000000000000000000157085425016e8a44d2d4dd6690bd51609c7487667938aef9e2467b08b83be4b4337700bae58056563b739ab20aea43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018e8ebc052123fb4c2be29c93d1840eb76d99e24950765860a2a55ef0e91b510cafbb09fc23e899f3abe969869ce20e0000000000000000000000000000000019bed2558f66055a42a9a4d4b8cebaf08b528b4eb07024d1c23d93785e36603cfb398a7bee9b9685b6c7a6af3e5d07961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a98a69c0ec3c50f679ed1a9e2fde094bc4b7ac1ab127d476c27e93ebe4b3f7b772c568b1c6ca112d37b11296fe42980000000000000000000000000000000002bfb6e4f34be8c0d56285583f4ebc50ffe1105ab3d30f5b7eded8b6f7c6bbd239a65544a189f023f37487303d6627711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181165c202d0ade64c98b1fde43221ceb988f360c4d3fc1a507786e9eab4bfa79dc2924fd8bf178b19ed7b6ea5432cc600000000000000000000000000000000189df594b88f707ee4f1412a816aaf71b15fc82fbfbdd282360fcc3aef1e76a71b82237552bc68a36bb67f869eafc6421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177a1edce370c8378fc34354383edd33764fa82f4f83d1f3a03aeebfa34fed482fa7bd6f2de0b208746d12fb7d02b2a6000000000000000000000000000000000d7784702b4e48629c14770b1b2dc2a22b61b65d1abd088210e5d2044cbe1fbdbfa60f241611f4cde3d669b65f166a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d45698f34f675ac31e0b1cee2def586c59504de43a132a859c50454ab3bbc7f030cefbc06b0528c60a3b72b7e14b200000000000000000000000000000000185c4756f344083a8bebe9e418584e4e642f6f16899c4cffa1bdbf1ee8e325fd48931c43e5c76e407912c110c1a5aa7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f6902408cee5588c0a4d930c1a7a5c6b7f958857c354941dc2b6e74b1b173ee92345f8279cf901c6623f9279c0aec0000000000000000000000000000000007daff042757839d806e3eb43bb56bccd6ddfded58b0f7e52a9c31547e03a0f3f813c77411b235359a6ca4183d964ea51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe22b9dad98c514fea304fab0401c0b9fddc0b3bf1ce41cf14f6d50e33c723f5b343743249c3a9cc90753c823f9753000000000000000000000000000000000dbbb8f68acd384127897b4dfea0e609175d82745d0a1680d3b1805047a6f2b404fabf29fd471144c3b73cfc403c19061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022427f2eb79cd3ab6f2ae8451d3e923e8c27c9650d78b94dd04ec634b72465e779730df9ccef798d4a72b6172fbc06d00000000000000000000000000000000155ea660501bb5bb86a4a3b68392f1acc89b5f0fe2a04356432476bcde758e6318c471f08c5a7cb0837be655cdca3ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab6d2a9771d036da214582c737ce30bb695de0c24a512bb24abb52f25637f086a7933589b40de0121552ec066c92a1f00000000000000000000000000000000008762f9d1e83834db8aaf7e267389dcd7fb5c70c9485e306a162a58cd6571224f234e7c1d7003f9ff42773f6dfd72621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bddfc8a21a151c6eba652a098fc5abdd1f81b7e707b95d3ec8d8eb57edb7399671333f6742adb17e314ccf8311503370000000000000000000000000000000007888d52c6c8c847a4b81e2fd49593149b1ba0f4ee23accd4caeba8ecaa4095a1eb3a61fa17bc50c545bebcf77009ebf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e3847cfa6ad889c68c1c09f1ba6a1631e16d92f4457ae2d062f539745cbd8a7a3bcdd80395a4d91dc9967b8c8996060000000000000000000000000000000005040517ef8fc9e4a10343443ca1cddf895a00414b727e2fa032400cd9180b80dcc10d9622ecb76107c19c2555a685c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a08b9d581e8f1d64d2007926baf9212201d2ac9c8fd0be47f995a3506cc9b0e735d5ac40ce3dc774fe1b2718bc7d7dd000000000000000000000000000000000b49b3a823b9cb729509296121d99255e96da30f07857dfad0b99937c8743b1bb9261e0d03a89023cc0bfecc8192fd571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a40653b3a13f5787970933ee2ed85c24999dcb8b6bed5f6bf593a7709c84a71a0d5ac6690258ec1c47351648da58b9000000000000000000000000000000000c6c002db3d832c376a332a7624d7f2e69c718e16edb69e177560914ca42cdd3068123d92176d161f039f7b007ba05341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce4e524e1b89f6dd89488a847db170fbb0bb71c12f4198dea1d9e2254bd6f62393e12d358f0abdf4815b35b831eb5aa00000000000000000000000000000000052cf89e2dabaf87205c0b79f05d0ad6c206d62ebefcc773abd6a2fbd30ef01d7c8e190c54c1d2996173dc64598fa1ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b694d5a6149aa513d1aa60fb0abb78fd70ddcd83ca903a424435228f7388d96eeaccc4f7be48c770f3d9ddd2bb454d000000000000000000000000000000001956dbd36f98408bc3f2f8ce8ba4397ed636b6acb34db868d8bdb65c1bc32e5f3f2ca92f687c400741d2ee0ac1fde1ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f20e939e331a538910f8a17ea8ee13fa92a2936dac48803d076888ea12d19faee92f7a32ac26aba3229e4aa567f0c50000000000000000000000000000000015fd09c6c9084d2e8480ae8be516b77f4ed2158980851717adcd24bf5f907bcc4ce9f7fc0a6a5e087444fd1c1342b30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d3c5159c715f8eac9e65dcb0f178900b6bad14e1e944d86268de2e043ecbcfa807a8912620a7e7c423635d93d458d200000000000000000000000000000000072243dab541568ef69bd010ddefe90791af082efc2172c9e43b378f330ea17c817397fb6f98ee6607a17da9d41c0afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093df04313fd1290d6722e992c00cb5138337270f34c3351a486a4d666233744e2733d8614b7c95dc6938b9001fac32c000000000000000000000000000000000db734a72cd9bcba0d279cb583c521f74dfdc2744708e9910f0f63b3b17f9683cfa8451dba782e350c9557a0676573501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015445ba4fb83941f77be59e0417dd2410b0b9e224e43fd26f043ad2df77a5734e8f5488f0c4548c572b697cba74622d00000000000000000000000000000000014c5050bee65ef4748c465cf01b8b508bd41177330b8ab9ed17b07675f3f3b43a18de0e9f896d17352d7df5cd75be8481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015af83c28bc60242354dc3baa0a79bb1c371d2d494b800be7cad45e86b0461e4b60115e9f623b64da8e613980e222f31000000000000000000000000000000000021c0a80a5dc0c4fea6b1b91fec9ed43415e46d857f1d888c9807a2d535430cfba8de69f447490763877204022cf54d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184eecbda7e39c7859dbba6dc1e9e3e8f87f03c34bb9fbb621f5e92c23d2b0238fc2dfda8a4a1ea615eb78ff86db6af400000000000000000000000000000000113bd9a35f542f0b7ecce296de411d64e04a38759043b9df839bface16e1f0f42338d2591a540649b0b4f5bebf56dc4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000605ecfd75f47c629a38ecabfe4ecc2db77d0ecb9acd4a9ba1b7048af28c3db85eff2dee65aaeec6fb29b9a204cf4e94000000000000000000000000000000001482315d581689fac95b8351fa06e8f2b1cd59cb6b0b563b688c622af938a7cece02e74044298f60c605a430960756ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012240b484e38b76bd60b94a10be77ffbde50dd4fbe7150557124b47bb68286fba69de663cbf3467aa84675b0d486263a00000000000000000000000000000000172695581329d3567fee2e2288108d70ee0b5bec850a737fb00e9c557564542de9cf35255770bed75331991007f92b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f210c70c40d79c0d8184c721a1ade9844ad4494425bc3c1b02d8c968dd234e21ef29bbf36f630506934ba3e93409df00000000000000000000000000000000010c9218dc264a26807ee3493eb8370e5d7efb2866b964088db496900979d3df359099b1e36f6b8afa3e2c1d26e07383a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eeffbc6b3a06c83e21feb005de9e5ba92bd26e0fc1c8e2f7369b77bc494a0af34e751f8ee4abea5c506d141c7c6ff0000000000000000000000000000000000c75e42c02863a339c9220915a34dc2ca2d896943726c84698272ca902707e4a6dc2020d172ce7e5eb1c892b4b0b22c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bd10978f04a6adb74695422f343275ecf332974621989a359505d62537b912af08cdcd63bcda23585102c6108f8052000000000000000000000000000000001292a95520a356c23052dacf5e1373a9be815ad997000178eb6eef7788e283ffcd9c320b8a4fd5b3148335b2be5fed641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001185aea3296220a9ceb68269091ae746eac8558789c0ad155639c18c8463ed6fc085d1f5b21974e6ead398ac16145c780000000000000000000000000000000013527ae006b2fbccc4113802d7f22efbe50d50c6d528a5b99e87186f05f86c5c17b85a747a579c80cfc5a5a94147dbe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079f54abcb22678de04f2239c38b88f96493628648f76bfd3fea2161cc3536b426facedaa35ac353eb486e7c273f97e4000000000000000000000000000000001664209d8878c122e7c02db123d11b51af9d053a36c42a98ac755c50829c3039885da926d5207d5b18b4aa08bd3516501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d35674c08b74967e1e2854034457da8a2f1be3f7da40dfdfa3ee80588d69abb7bd793d49489a65e92a95ee945f7000e000000000000000000000000000000000141322e0aa7557235a45e230f8a28daefb12674a7eb7dbb2c7bbee8ccd95fa447d4e3fb7a6be6e25f31b0a28f71c72d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be8e10b614cd9be2a7db8175aff0eddd4f28286e5d849298b8a48c33dd877dff61bbd2d5ad2d0c9edfa765059a8bd5000000000000000000000000000000000f002dcb7ffa031aef5dbd5e266725e5e2403fdda2f80b08d30aca2709c8c8dd43207ffb18cb046feb793a4a650cd9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196d6359f304311747b27f7280bf90c5d531979a568bbfe3b5ab5320911472c60ee102e9cac69961a5f45815d781a48f0000000000000000000000000000000005f672d6f95db206093ff62db1bda0b6328837e908d809e687e3a3e19eb09f2cf833ea6b5702cdea4d1ba8cb89ddb6451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562c20fd6700d55db0d4acf937e559e1d8e9bec5e614feded03fdaefa3047c4be5fcf0ac69cf3648b2106b10677d48900000000000000000000000000000000086ea0df6f5e8834455806e7ce2cb30e748fb2f69cb0094b7aff152f55d81ca8b5fd0d4efe94dc4da9ce9b73d97b4d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fef2f1f685f6421e706b14d682650dcd23472216da2c666aaedf818d32d08cc6e4bbbf3e9005e00b4b76f9da8ba4df20000000000000000000000000000000002b6dcbed3a686ea536ce33f8e0e197cbc9178eb16bdb69d817a1e18a60524e725aa5c94b6eca4be726830627a0f75591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008915dc5dd3201dda1c54caccc8613a5bf9f6e905cdf8b0db6058567227d8062d357abf7efc219e70eed2237676deea5000000000000000000000000000000000bf05246d535971006f72cbdf9160150a7fc10d65d92c4e5214e818d3cd5e338f6d284b53f09da5e18f3fd0f3eec201b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001499a1182247b508c7cf165ab5311ef642aa661428ec0519ec5eb716b7da5e1b4c0f37e95af75734ad310c3cec7d89ef00000000000000000000000000000000114c1b503c5bcb7e85eb1d7aa6a32864762a0c5802687d954c9557d87c706f761648f483aebd324bf621f3fba09632001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c87e933975b84c5580ae94372fb4a43c908fe00c8b30ba04eec29c1099a8e273a6faa2b3df098ea5a0a2b1dd05f545000000000000000000000000000000000a6dcfbf00e0c0fe0e9801da72f5226886b0795312c30fb3a943a5f3c3299f536ab412b900fa2d60b757e7bdd601b09f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e49b90d0da39fa012fc70345e0c7ef85af8fb5e9e1aeccb7e4af03f2d2717fc43935252fbb7a64d77ef727d33ba280000000000000000000000000000000018a20334a63f2b30461c8bfd565c38de0c960747971df349d6b5ffc91aa57685066ffa32f7e162788391f6c274b663ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c886e44e41bd6c10226622080e9053b6a3770ce7be613686f2066c0f5f1395462ae8bd8f11f3a47a22ba5edf642e8000000000000000000000000000000001260c94683391227bfdc2bdac233bb1d839a4068608560b793b9b3d91ce5c7e96a589f8d9ca4ab57ca25a67a6a308bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc64a86195da7e8e8712a4f0c7f57d77a70d7c3fbba01c8566503f7d15ab739e2a789d3260e2e384e8b7d125ecd549000000000000000000000000000000000421aad94c5f2b46b862c776670b670b4086339e31b08500a8bd7d06fa9965f1cc604feee092a2652a96e7a164c856b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bdb6dd88e0ba4988caa2cb606c9b1e6e98344d805ff5fb4b0014616bb4fe2c0d84f34f9064c9ec971a86103aeae90e0000000000000000000000000000000004c6fce550949da34fb8c104cc89f24ee6bbdf3004a4cec1a3ce58b055da7113ffadd70656bd89ef703652306de51bf21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008344155b08fecbdec477d3bb7f83979057cc5c7dc8aa53a3399398fba15ff5601eb1ffc8a31bd1f8049244b033bc750000000000000000000000000000000000b9fe09e19e8719944a3dbd1aad6d11cd924167767c1c9315a1dfa55dc6600ef7c1b6b9db20553cb123774e12345a80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008ecd8a2b42735d33152aa4c5c11d4d70b56f3bc0cb1555eb4f7697d8ea9c5f8438547c9981dbd87d20e4a21036cbab000000000000000000000000000000001317f8236c13d28ac0e206f4eec23f90c357f7c5ff180ca4b798c8847363ffee3ff9f840603f274eab38fedcc276801a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116977d08deab67c359b70ecf87b407201032b592ce240e9ab103fa3730ef17bb61efc001773ed79f037e0b87e58d17d000000000000000000000000000000000878d259403fb0d999f6d20c2e78d3b1568731796349d7ec0a594c8ff1578ca645e4d93c565979337a58c4a917bca5631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117abd010a56a8aad7f6280008984b524ac6752e8028a4fcb7d5430445f73c11e6dc9a33bd81ce01ba781df85854b06300000000000000000000000000000000105e85b8620528f679109518e41db3235cad73c09f471adb3ffdde641ce6e17a59c9ef26bd656e915f82712c2c001f361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a32e87394abf7b7458bc9f70f64374be673c4008f37147c5526b4597fcb5bca5e5492c13b4599e31a5a3da459e95950000000000000000000000000000000016c8bf3f7cbe1e92aefc8f92f18e62d8617d2d3c49991b5ce2766cd9d76a4c2a5fea1d14a7e6e8b6873a52958624b72c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022694132a2da8e095339a2013fc6901f0d7dfb9ae6dbdb10ce229648c74767bf327ef10f8fe9c07b5479451a22e7d8c00000000000000000000000000000000049702b8cfbf1c6709f49e32c88fbaf2f43c293bbb0052ce0c84cf5aaca448c43083d8f36bc00595fa244ef9d21dc6ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb3e0b3288ece732354a4466e8c0e754dbc266fda9a48c21022ac2666b64fc8cf2d34fb21ae5fc025aa2f80302f93d5000000000000000000000000000000000ce933426c03433b3610bdc3bb587b5ee7b76ae3ed7bf6d657560a0063e0c59682bb0337b627680aec5e93c9f053928c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001257f5e39eb0b6c5360fbdd9310fe5729aa1ab13c294bfc328d8b7841dd56d3dd64ce0e7dd399a0fa7b91fcf660ae864000000000000000000000000000000000361262ebb12e109e6df9f0cd5c1af780e4f0312afe430c129c30bdfd66531e85556fa20000b87c112766e67a7ab27e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001165cf72c679bece8569f396986fd404994bf7ff53a0e6d1d74bcb6b41f552df77ed03cca215da239c90c79b1ce0adac0000000000000000000000000000000001269f0fec516ab43406124d602848f248e4c5331373e4917fb4e0f26da3c882092012a3df63199525962956255c539d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001544727d3e43974c18d9af31eed8c7d63a122d4bf6b1c23183b0a2654ff858f4b2660da0c2c47296644d9bf7a83a6e9b000000000000000000000000000000000ff01a6ad1f7900f0d0fbe75742b7688eebd4c85c7739cb7bd12ca5f6ec57168b7764b5dd0043591ab919e19b64601281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd5845872dd61b9a7a316e041994e7324d1f6fe3461f2050c310a47422f156c9986a4cb2fdef3d358a776648ac9d6b000000000000000000000000000000000f7ca1d07bf33f980aaa4909b655d31f4b5ff5eb47a44c21ac68cd08f8d161cdf15cbfc5c3133232587f5f54f37034b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001478c800c5cee2c9ab44b5d19692e8190d52da3810fd1b47d468cfa7791c182fcd0a015c224b1e17ab969238be5c583100000000000000000000000000000000113abbad4a2f36132c12ae591822f1a73db6cf25f5ab6c57d6d512066bc3806d98454f402ab52ecc644b642dcac69b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29b9fecdaf1e48febe612de51145fe781e1b2b2eed789063fac100c39d6a6d096e8e27fe24b5d3ddab657349826496000000000000000000000000000000001673920727133074499441f8770e82b96a7a0749bcfda944252df4b603829eb5f3b2c93f3ca3ff14660a5a137646b6141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a3b618640c6d2a1d516d542dacdcb7db327ad6cbb41bca7b665a5cbb4994858ac56ee78a0c8ced274e5c6aa3b6eea5000000000000000000000000000000000639b3d87568535dff6312b1169dbb2169b16b99a4008002c145200cc384c1dbf996abb4bfc71e36920d571bcfc08ede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000678889302af0e4bed48df91d0a7770f298cd9fcd215ee2fb52da359b140438c8def6765349b006f879a633a12de5f300000000000000000000000000000000012ec8cfa008747745e883cdffdc1a1d91c828612c6216c92327967c0df663c99d9b756846dd44a55034f37d32be8e8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfa7120f6be86d48d1f82639ce83f3b8cd1e71114102fe9221558e08756a531f969dde5a9fabbb5b78f67a0c652bccf000000000000000000000000000000000d8b59f918abb02b037dba2c59ec48a0ad46729a91c81529b8f2390a7fca8ba67e20874debfd6f86d66a7d748bbd94241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001942d7c60646b7623314a86355cc52a2d4b72a4def9f397a99b5febaee2eea99d6fa7c60d1fd76707eba09a09a48fe63000000000000000000000000000000000aa2ea821df89ee7ba8b490c047386ca995caa2ea201b18c14ab9fc5d174b0d7ebc3b41f950af1c64439424b5f0667af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c9d3923ca8e139254fdf62255ae21159b59452db864855eb0138fe758e904f17f94a19e860df8a96ce167bf1342094000000000000000000000000000000001893a2854dfc30db00204e70fd63b1646b83d0cfd720c3b3a404761af5017de0487faaeab6d8bc8023a5bcbd96440a231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a7fec282b395dfcaac44dbed3a2534ec3686c81d755477af8adc7bb479d27c8066dab16ce0ae6ac2921229f16e4366000000000000000000000000000000001937728fa858ca5e8e7567c1907bc264907700f0b13aa1b491133d5a8a265b35bfa3bdbdadc2f1ad32e6029551565c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d253a6258190bb98a76cb607420d18911ce90c3b923b57805921a96eac0d3b3b1ac736a73182d86e181b6142426b110000000000000000000000000000000008f11dc67689b83bc842002ef9f8157ad55a60012a5e50073751450236570f729ef3a21af881a3a39f8fdd5985aa38511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d64520da7370ef20cfc5d34e9de86622b94c203f712c5eab878ec29d88d75fe913cb81eafaec739aa61ab4c705402f60000000000000000000000000000000004725881b121f87270593873d8e5db53a69f38c10f2756d8ca284b803274981670994d24613649ef2f7301291b90cb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e31638c6795a18435328771a8864e9cc45d35ab9c34e5538d9856bac392c082fc8480af6573eb8c11d451e6e999bc1200000000000000000000000000000000162f9055f0a8594af1b6b4fed3a7ae893936ec1a5ac31679434a6fc724b62e8a7611d352f5da1bc8adadf89d3b26053f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d56ef89cde69dde26d3855b57825c71c6b15e777bef338a009a54411953410b348ae10c26348fe58d67fd903419a8e0000000000000000000000000000000000030ad2c93a64295e83dfad68e46b42bef5720b2bd37bebbb753fe23eb44b15717f23f11bbce3be62272120b03e95b831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100796a5acc9ea29b98914bde8fbc092afe381df3e2a5303f52a82d2e341d60198b82cd058e3dc9c6460d34a217f190b00000000000000000000000000000000163e9b84bf66803994aa89125b625ca132316a47a447b090c82b2e01cec33f932db497b6d05976274f10c6ab79bc6bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124cbd4f1d8096c3a68edc266e859175c6a64d160eebbf16970b1e7d20df90b177bc72271ce61b656a2c1a923277bff90000000000000000000000000000000014d21a86532310dcc3baa2b4e29dd112c176fa8fc5bbd0bf44caeea6d5bc743aeecc158d323cca444ffb4d4d3a0d84811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150f5b302f8cc66868388b7125ef253a29d356c470b2dcae43617165a1c94e4a0fc15c933f9c84d647024a343cf21e98000000000000000000000000000000001628ad346579f572456a6d18f4deb860fe157b8cd991913777979ecaf880ed24092fbd3e74ffde5efe5ceebabc8389ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087048195b3034d172f80216bc932267132a7a2e3ff779a91c37151cfc76a068d134f3acb35166423986f9615a4089b9000000000000000000000000000000000074b8a9137fa3cf060d5d812464f37715b977358648b16e4d81f6c4b0d4a91735c144578c0aab1c7726ae2c73c1d2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c50ba3070753f5978ba0f776699c2e77ccdf30d52adab21c4275c60d6a63749b064423a8bd4e16d73eb143f4655404e000000000000000000000000000000000091249ebb6e00e85ea707c183a703c8c00cdcc0e4ba64acc0b0ed2d3d205ee345b2b6dd5afc3d8448220953779d28c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015355f6e366d86a968481d7c45e2a8ad3f7da657d8bf6460aeda25d4f39444a77aa5749543200b511e833f76ea6876ae0000000000000000000000000000000005ff1d833326d951a961ea01bd075506c695bfe76ee1f14d027424a5d36ba401f77a8c4222a92a78559dffb6c37111f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bd0cb9f23b21cc4d15d23ef10c70aeb1d0f2718fbae3dce33cf1f66cb1058edbda151b5db5ac9a852d706d2a54db9100000000000000000000000000000000019ecc080f51a4beb30fce7d42c2d1ee9d61ba860cfad9b592e4c5ae9c6c7d3e8ac69cd08512ab3f1cf5438e741b451e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e3da9ec34bff4e29669244c11abca81d0c040cd3c706fdbec5601127b314abbd0cc62e45d2ffd14527333b055e1e1e000000000000000000000000000000001011a24543586689c26e0cf913c93165fd8ad0b1fdd16028835a527f0e6f9a1c739b5b9c45a2c6f36425f672a68aaead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f9e6265310af62485751d484f4d6b4636d999c0f13186df9f6f5667db88ad0cbc8c3df0822d99bd7e34728723269e000000000000000000000000000000000003d44a9f265046a8269a00e40b64aad2c18032467ada3c8e2c2071a81f0b44de5b20f100860ff9e27833e8a8c5c77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093e3e54a8ccfb04e580dad28651547153f65e79b1f8ece8ad4bc351eff8dc227da3935a992bb8d965eedc07bfbd4edf000000000000000000000000000000000aac6d8976c746ec4a017c0f23f7b7e05b7c1d6149f5a9b127ed41103bd3588f60836f908cd66d7dcae37672ad2e7f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094f5e996ebf539d3285a9eb723d9ac681735a5a4358f0f7b8acf47e6136ea6e784a62b7ed2dd457e8add31d4012f6160000000000000000000000000000000018578c22c12c1b98ad87518f1aeb60a2aa9e36c8493be9a87ea40197b67c39874c7863d1617a366a8fa1b7ccf2b99a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012132c0296e2db40472f9a41cf9db6dfbe624d77300eef944adefc9fe3b3fc606e45ee819fb0bdc889b9f6ee6d2de8ee0000000000000000000000000000000002ab9ed00be684e9dd0a557793b7458992ca77922d5af6137a68d3f1c50d01807a0f4748f7c31302ddcdb0fcf2f5680a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000921993d69bc3839e44d330ac93814d2413e6aa61705dcfdc78a36ef3c35dc894d7e772bbf746d55e81a8a3e9c88f0730000000000000000000000000000000000d021895fe60087b8b3ee6f18571e16547405e6ccff3f09fa8534fa951544381cf04e151dcc7261a086ceeb1cbf0aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187cffd8ea99a2f6423595312b4dfb671bca3e9196f558cbd603db44a9a991bd9ed489542490faeb7b1089e21b9e70e60000000000000000000000000000000013a58e3ff69ec3306f685687e7d948b0b82b21f1e268deed6ffd242efadc29380b6ebce380e498d9856bc09c1c06f9b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159ddc536ee60deea4508f999dd6e7651a370e7a6df7ec7800c33c975652cc40fe87bd63d31c73dd012ec3aecfa639000000000000000000000000000000000b688511d4289bb6aea32d684998b5d64287c00e3dc96935cb1ba93af8ec18c3d8c81bfa623448643655346739c98ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e940a37b9ae8bca962d55c29598a0990297b73e5983d0656f304a64285211a611c0bef1e984bfe2ebdc138f3ed0ebf00000000000000000000000000000000145b715fc2fa7e7dcdde2b5f1eefe5e90f8b7cacb49b449f3b3a88a9c8040d68fb792839748734a040d47a68386f126e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a171f431570132f33ba146062e03a0c70af4507b5883f8c2dffa0d83922252a0482471dc6e03cce9ba2d76888dfcff00000000000000000000000000000000000afe3d65ecb0ad020605d054dc3bc188ade1fae36d5cedaac1f2a14d9b13eb6b6d259ac9789583ba4ff3b362ef318c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108cc3d110f5d4f071e17d60e4f1c9cab8e5cb97dc9be55f0b14b678e2a242382332b6b6ea4a42a22de65fde8b58a892000000000000000000000000000000001003531937e8e59eb78da52bbd27a2eab4a14c151f404630dcf4e1407a0bfb1b5784a546c66e6228f59a90e99e57728b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001993edb6b661eec274bc5ff4b5bae0a2a31f9b27c0282059e9ef94d86e82043113fad8181a46fc34a20ffeaf2875ea6500000000000000000000000000000000078b75b6ba57a0026ef818f1a7d73790b92086c5e6500accd13393da1328c719a9c745d6a49c42b7ca12620a50c3fdc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005373a30a5d5d9a92fa0252c9a3acd1aff63c84c369f79d0975ed757ef7414918dc68003b6c021f54822af091d4c797f000000000000000000000000000000000ea2591f2b4ea290e71b002ea5aa41c7404a13d9c5d642f79b990777b10a1d94fabed95ee7ef4ef2330cd7e65c82cbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f942e397af95229ceb620556516a04f85a83c56a29f984d880b68902495ab32711246b9605a741f5ca0574b963e8350000000000000000000000000000000001676474b86cc5a0bafde079d612409a28b08d111d38bbcb0009fd252e18295ccd4fded376b330864f56b98c5ee92b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dde37034c8903669be6e1582b8ebface264a8d35bd09f267f52f658959e47867d840c9a33931031cad2d368f9ed97e0000000000000000000000000000000001c8aafe077f3a5fca0fd80f3b37f9ca5c50c90ac4f0b8496fe56511977750e3ba658b07e92fabe9095dc6e0b63da04d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017506008c74c130a90b50be12993ad4ee10582abec46b9e1e80ca7caf69e98f39b5579545b216f758ca68363d680f2040000000000000000000000000000000015367146f27feea78d2c9acf6dd52e11af3bbec205bcd376a13b36bed8aa83f1db4d0d426c6283550dfab6f465f2c1aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041e6a792f5eec48d2c4b064e1dabd7a0f35ee0bdabdec252fee55f3d0756d8b8161b688b03ad430d2a4b4ff006285cd000000000000000000000000000000000e18d655812aa2bf1a7e8fb6be0bd6d590d4f75885a7b0b3d8881dab341b30e414f3695a1160278b3b785588aa1b30df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e799fe6c96c0885a3b67961a246f48ed36d954f0c5da9da4db8cb1336dd5eb0bbb60b6e4d3d84630a7c5ca59e9dfb00000000000000000000000000000000002b41fb9465bcf215d6a49afea7e39153c48ca5f2a80fb6d79ff664cd60466593630279d035495d11d79ce9e868ff19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c9ab0d6e7fcb4a958fabc265b9f854285f4d44faefcd561b0a772b52321e5e1d1e87c7d6f5a0c5fcd4aca8cc098b00000000000000000000000000000000018300bc626c70d70daa6a6d64583a8f1b405efeb8d9a82159824ed4feccf07b8d53bc775fb37142deb1842c6cf6c70d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a22cd8815b1b4fd1d971a8de9e7e1a662a563dfdb0e679086e696c26c165ee4e1cecc11357e9b3f62cc08c7afaa890000000000000000000000000000000000bea2a81db2272817a8f37a3ff5a68b27d9eaa7dbea7ad42c6c1a692a18fec400b305b823ee9680ef899f7efba991d661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a6d76384f54dddb0bcc1edf49a07f62d66be24fefbb9fd8a03e9d57ef9ae49ea4a657e275a25193a8b82d55d999b24000000000000000000000000000000001195f9c0932a2dd5276eac3b429a1b88e8de4fd59a93a31e3fcafd62e117056993585aac01d6d9d4623e562ca35949d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007334a8600f35cdc47b3ccb8dd3bf3c1e8638cb689e74c18aa1ab20665a1a83be890fca284b72f83b2f2919d6c4ee36800000000000000000000000000000000074ecc0f3cb5319725fa51a7a25da1a99f9b1887b28b474fe8afe96b79fc8adecba43b00f961284c75016d24ec20ae0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017598c68a06888687235ba747742c63eb0d35278d68cea25dbbaad96261baee8464791f38c95a742a5ed8521d38615b6000000000000000000000000000000000bee0774fcce2ee5e4d5042746f5cd51f8e150db7a3b9176390ec79c5f6795917e6a91a4f00384b3b0e653e02b64c57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009692752e8ec5c6804cd81a2a940b1fb0c8beea9477d3b1d71d59065e1815787a48be68b0adad8b2023eec2d5790096800000000000000000000000000000000125b8844c69adc040f28a6b0f87451d0a3e486ee595f0deb0e14a7ebbeb71b2a15c89dd5b234ae0d28b05a32cf88d7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8b76a5bca21fede5c356f4721dcfdacf2251edc54af825b8d258e3eccbe42fecf2d4535aa785d86fec18ad376b5b70000000000000000000000000000000004ade7fb5862ce10b71fa32dd9a147677b6d4938aea10ceb16bc2fdd1307cbdb157b4397bc135429d05db959e4e0da2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177c3e18f5e0c493c5e27a7a3f3117e8025ca9ba237a7e3e16425e957657cecc2c4e2a82663810dc0b8d958c08b2123900000000000000000000000000000000154b9d7d0da2dd9c21b99dc45fefa18b1ac6d58e71307001760b74aee99d96ff45e275456062f10f747df3f86e73f1b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079441666569ebc93ce78e14222c756d9ea0dc333953e87d9d8ea5a1dba45cd804f701d68949dfbf54c7e92ed66ee8110000000000000000000000000000000010d6a0368bb41f5545b9d8e3f04641999a2f9060be05358178efd85092ea4c9c3245e99aaf7101665c766b6d1f3f11d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e88dfb7b57a8d56c23c67b7117145696b77e08556534beecc98b74315e1d1a2fdc67a868f883a8ece2a7e3f28dfc9b0000000000000000000000000000000007b5d319c3217e38a5606774e406e8606f7e3e79943f1e13bb7027eb10da9c64412688c28d8d5730739261d5f7f0cffa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000309d4c6ffccb9286a618d535e76264243cb7fd12fde3802faa5684867f1a8c2dea556f3787ce0b64c10dae948f3a3e000000000000000000000000000000000054d3200487e240d6cd3f6ad7fd2221e9707a44354bca6486304a074b8fff6144c75628b14ea6f1478457bce92ac81b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b8cef374aad61039a08af304ae3c0c9ae15a236956361bf369ff83789e9c281428f1be72f2f42fe0a6fb24fcdd7ee70000000000000000000000000000000004d7b094a3c5681def525085d8a4c077b027b7929d1493b470d8c13cb14a355c548544778dbacd7785db03962f9623211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f404c8ed5c65699d7073df9b16292a1149c8eb0a64437ec0dfae1efa93757d4a6bbc741a474dd212742cd70b709de700000000000000000000000000000000074cd8ccc97e3e65ed65dd94699728c6633c37fb77cee4a8d6eb18d2f24947e9c7ae245b515d915bf408025b60f085e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004681afbbe644aacc0ad09b61638c855820cb3b3fa4b40a8a1257965c827bfe134f7eada84789e480d437e8c43978aec000000000000000000000000000000000b48f60c00d97ebf87b729a2eef3ffe070b1cd936476f385c153b61ccdedb26ba46efa489ac96004208a656febd4b42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8ad45921e3e682e756194bfa98dad032ba8f9573769fa1205d6527f299cfa86c05dca7ab3a56bfd8830e11c19bd21a00000000000000000000000000000000129dedd84e87fb73c8f4050acfbfb1f4ae733635054210a069b023ac3a64189c4d877e7f2eeb1f0ef7cee4338ca1a9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132590f0466df7f5e4448d2d41a574c7ce7ef3af602f10e3c531e5ab9756fb6ad60930c22a6a2d6ca8c991b8e087c53a000000000000000000000000000000001082e71cdd210b0970beb839b6f423e0f1812a159f2ad5f6f5d9bfa145fd72a4662f490b005d3b920b8e23c2410824c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164e6e009fbade389f6af86c8644088c672e3f7ff0f797a046327f11e96deb896dd41be4762b318cdb4757eb161408d70000000000000000000000000000000015de30b0e0f5f491ccd80c3ad68a57139cf01e973465437ea383a7133ec0cf594825c580598f1421a5e71fed0e79fb171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165d8432199a33a8d5fd6656a02cafbefbe6bb3d778f6c8608e3e6cde6951af4e24356005780a405c3f23cbeea110556000000000000000000000000000000000526446adbea96925be489cf16d177db5ac1fa93290207f2a924e16ba3b41c7994e2b7bbb1888e38febc96abc12301f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053731c3ffc7d480b4282ed6d70548ffe83e379243ed4cf6d76fbbd2a86ac79cac89789fba3b9ea6c2d964ed53be75cd00000000000000000000000000000000156095a5c2088e1d094f887dd018a16c82520dbedc92c99feb6d7bcb015623cb419a03eba0314c90748a78126dfb045c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001204635e1b70f2e8f047af63341bd3b17b3e18c9568355ad1d69eefbbe95e43f4281cbc07c910cd985afff26cc7477310000000000000000000000000000000010b5235fdd84cf9a525d6b41a47cbb30527122b4a6aae8ebb45e5aeb22c5c90625954237252bb6d703c6c2c4bc5f61431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012649981d089e627dd7d778f859b5e3a6584744477233828882501fbde0a83ebb4b4c89fdae5ead6162a04982c2c9d68000000000000000000000000000000000ce17500bf763fbb1561aa5b5ea38eebe45a6b085a7083950f0656fa0fb3bccc2db5d89293574c8f313aafd7caeb11311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060b4766dee2cb0f6f31282758c0c0be1f2c4af35a76acc4730428f32b31344613660eb074229b5585c0a027ac96ce320000000000000000000000000000000018a24147b522c72b732ba24499315290161a891e4d073338b0a81b7c036811d9f124edda8de0638f11677aeefa3b5b071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000687727795a2cfb3e8db56f11db3d326b9b8a5d8d33677e5c622098449ff7b377c80b01ce5da9612287d9702cc55e2460000000000000000000000000000000018f771e55f21098f5ef5d307283a056ecd40a52e05225a8991f7acaae5ee825515656337ccbe7aac4565c51f59dbb1061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cedc6fd7a81bf936ffa8415c5533eb7007c2f9d8965bf3c0eb84ab218d69c0d395452869ac45aedc654b911156562e000000000000000000000000000000000dcec09bcad8d5e2f1796c7440f0f148ca9fb7c826c7ee6a24ff3d3c6b39bdd61e5efb17661669277ce02b5b7c947f491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124e556ec555df74746e9041edbdcaf8642873960ba3a7ca8c9681e86efb311f772f822139fe1eff8559f94427041b19000000000000000000000000000000000a941d7a0ff924a019b49b7b2514b9002ce34c4192c4e5154669dd3bfbc108f51775fdd08c0b82feea54eb4f156140c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f01e7681ea7f46bf8a486878f82815a4adb186a4f10401505b47f5e2edf029aab2dece056effd88ffd93406ab05b3000000000000000000000000000000000b34d5c705c02ba9ac8f87fbbfa0c8e62a2fe0a1bf0bf013da75540e5b823cfa49f83acc31fd0a8c405e96db1fc0d77c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d598b22b95c491b5088d38ce9d29a7b5c87870e4c80cf4677273d7ea22ec13bbb980c9249caf438333eb41a8fad8cf400000000000000000000000000000000099ee22ddf1831c4ab2c5bd7c5143e535777a5529a33da353ccacf3848c4b8068411572c3b317c5ea4649a4db4c770cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b977843bcbbbe78513556234f5b594a57fb496fa2736908ca83aa3619a28dcff600d5777d4bdd151cc919e43b121087000000000000000000000000000000001830c6874b7e1cd6e0db500389c4064fcc6cda29f9d4bc2381da7ea02c4a77a484beeac065296180740af4e4961f35bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cd1c54522264fa742f30c5f9aa6adfa726dd361c4be2cb79776167fa02a4c4d8aa5b1a0a9821df539abee57ba878d0000000000000000000000000000000004bbc6b409e973d0698f0cb5c4713ebc00a900472c50c2f0b0a487fdbd823b9244c599b31e2e8cd3ec0f6c3db3574a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092aa6698f39c150adaf8d2ed8d0025303a2c50ca48ffbd6067e1e95ef294e1a8d8d9a2b16249929d180ae48c38552c40000000000000000000000000000000015cdf3eba3a21e4c2662dab064fe4ea9f626fcb025fc769405bba09c1ea78bf329d41aaf5e9e3ff422bb76c13465ba661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018212838176bee0c66b0de51d9833a5535e006281741b51631e3f3b08e758cdee7298781cb5f3c2cb2602afb276927e400000000000000000000000000000000034a6acd164cd03a048acbc7bbaec125cb8598cdf4ea526b488d86993de99c144e3162ac0a2fd5c23760189d18c397791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2085e16b94d873e7eb23676a277b699486672f8db2f237f1ba1e80a460067810632da6f511a84a3d4dc7e060a1f2c00000000000000000000000000000000037ff1367a118d74318d553ca51ae6117cc7e399d34ec5453c39818515a9434da6b8c3c571a1123b8d46c00b717a7d7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ff191e2dc8f1f10ae3a43abbe94d33d404eb62a1214fc8dfc67ba5cec860165cf1555d63c2f2d0789d230d60cb8197000000000000000000000000000000000c587ea9984edc3407075dee003510e09eeee3b3dbdefa11a88aec0f6edc2a208c57605c099d5f25c9d0dbf2fbad64421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b04c0f101ec16c9f63ac8c8f5cfc0b3dc7ec0aef97e31e0e84713778062e43804fcb61fb2aa8b3abe4a2debc3716dd0000000000000000000000000000000010f14083f709e95eee3cff8fe691ebe2aa183b3a6132e524690b5bd47191bc4d0aafbb156cb173c1f7c50fffc51f70441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6317f2e4444a3a84161215227ec63c039a9291a7ba6405c6d4029259e39918405ac0655b49103c315abc11c9a6451000000000000000000000000000000000119630288b45808bc42a8b6e0bc767bf98a9cfdc0152d1d6fe01e4716988c14e4fdf3e0680d337cdc3cf7574ca84861e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000700f8256b34086d526811b4eb2021acdca83762a21d82520562054afca6dca950ecf6eefada7fccbeefa317dbc62e4c000000000000000000000000000000000ef74af1ebcd12481cae4e09c6a6477baed85106cb76e64ca011cad457fe4715b050a24f8db20bec82f19f9de4ed2f0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110ebff9433b7e2d6e690191fafe6fc582befed11e9c1cd4d97d1d7426bfcbc7f837e42b52144df14fa579ad1337bf5500000000000000000000000000000000098ad3f3fc63bca3daf8171a56a481f8d6cbcef26610cb1e798cebf47cab358f099f0eb81d5d822decb5a574c2c3ccb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005735add8b3a5bd94087568996d9ba5c6be9bd93f9a19b2700caae5b4b6ea19a3e84f2aded1a21c12b6c15c7bfa4bdfd0000000000000000000000000000000011bdc4febf477b00cdc8f8247ca942d2f4a59907b49b6fe786d3e2c5b18e44677402329f76e8abe0f3f584e1f24b37a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfb88aff16bac6b4741a34a701c1759536de659cdae405794582b0f618fd9f379c023731065f6e6962ec1ab69983e00000000000000000000000000000000000794cd45401b015e8ff2b851e52e21092c3093831efc8f341b8ccc3a450894bd6cb27ec8c21b00991fdd50649e4382fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062d33d68d42e1a064aec9696d07f5a25bcc4df150ef16cb2a6e8918f59854665b5c55bb8ad60f0d9fffd45d5d7b656200000000000000000000000000000000114ede9230708466b5b399850d0f28ea02bb9bc736ac728da2883235b65890609ab1820f117cb8dc16957a929299385f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001041198f0e9c4bdd6a0f3937994aaad238dec9af4668f0a63f0e76107e3a11ec0198319aad0bd1c4d30d6f99d81ea71f000000000000000000000000000000001223bc56216eeeb5b832f107bd5a2da83b21345962a13b8c8441ae3639ade8c33773fd3d8d1055b95e6ead0c8c884b011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006091c489bd76ecdc9238b10e69eefbb5cd69f9ee31d46c42051f90f9cbaf6177619f88063df6d126d2648b3a66366b0000000000000000000000000000000000c516bc163a835e9eeba12f4cdd58af18cde5ef9374f2c100ff2d52065b7494a5d0c5071de5815218e7b00c972fea41e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e136e76168a3e912120df9da5e1d416c08d8e50fa08f3f06d4b86a1e666dc4cd7f56e2314caa8d08e4619d5194400f0000000000000000000000000000000009d4151cbc73027664ae1e52cdd949e521760d6b5a651263d31f8a434c527156b95d1ef15e05e53fee43776933fbd0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2f419701e52135831638544c08f839fab08270c76782fc62a949b2082a0c4bcb0001cc772acd95b5f5fe2c8ee4db10000000000000000000000000000000009a2afde0c4c8a15a387005062a686f41a8b480159adbe868a5178b15b2a910d6c358d0b31862bb9c88c8f6b96d4250f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c287e60355d614684284310069c433c9b61dbb6eb7dd8150edef0c860cdb586d61261cc71aec0a564c33beb6479642f000000000000000000000000000000000338e3f8d90da0d602775c87f206055a28f7ab945554c6f0aced8aa9ac8a86310373f096f0dee09d3f193300fcb2aabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133fd20770b4ed4f8588bdbf4f9aec275be4c8c069e85a102863c316dd560b9d567d2f9ab6bb8f5ecac0d524755bfa94000000000000000000000000000000000ea7ebdf36f867db2687c6e86491469b2123c0f84fb34a658ccc8aafc08155bcbb09a4df85ae837a9068f1bb6db0f5d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a00c47e629d63c68907bf5a69a130f36ad788f6b1d2331c3505ae8ffa462b3259436d42f2bfe3a3ea864dc190e0a6d3000000000000000000000000000000000953bde81b431da8335cb2e30534d4b2cb7f05b1dd3d350a6bb7450afd2c6b0d91e35dbee03356aa58b1fc9bc8add5e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008514da7d76238c42ad53742d4f13125d8ca3bd00ac7dcf4c3b9404db3922f09ec4b5ec61de9d022b307723467b4477d00000000000000000000000000000000149c2541a7eb42225138c36a5763f8d5034e716b50dba1577c3d37f4df6f31fd81fe39a00dcee78ac1df4fc3fa7850c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141e2990bcb25cb1f18ba9bfbc4bd0ba061bc37ee96dc6eb8751c22105224e44d2af6d16024d1ef2d5535cc809ce82290000000000000000000000000000000005f496073893d7d3c4168012a54e71ea417b91864320f63c7a574c30c97b07006810b69b8edf054dbcf6a962597b198e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bac3bcd303d917c8cfca4b9c087d1f154f93ae29ced50456cbbf303cb662a1986f2a63d7ada0202926e8ca4280c5470000000000000000000000000000000000ea18d9f4368ffa578c90710d77e0859bc94eff225c78cc42110ace451d7c4f8b4c63844a7b785184542f116ee6d1591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acdc5db706abd7fcdb6dd73e2a3d6d499de2423a72521f12b99f995141d1aae7c234677d70008fc00f9e964dc89633500000000000000000000000000000000153bb1b64759dda9144624ef2257c973eb5fdfdfe22ec89c79a3d9771cb142516f8bd4193731b6014ac567cdbf47550d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f61b643a8724525c514a319ccb5ed291b0de3262e25ff66fca98dbf54536610256ed1b5d09301e1a17ff14a7f97ca6000000000000000000000000000000000099d3626cd99a35355a75217155a672d355572166a32eacccc93b9cc2bf3db430e330b0bc55f6337431315d040adf101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d21657c37ec0f9c9309b4eb54967a845cdcca244c0a587ba2388f08aea1a5dc7ac8a02623049f640725cdb39fb77b1000000000000000000000000000000000b988219594e66b553454bcfbddafe121a2eb8f5ba9881dd071e51d6d0b2dfe50a94443260c53be2d0b65ff77f0a5bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc0b9b835bf7a249f97ec3322770bb103b5d981e05725c0266bfed44728deab4ccfaa7264a8fc54f11c0269052eebaf0000000000000000000000000000000012ffb67e9bc18e59df74ccb3c3f53add73426b2ad26c218e9ac6cd2ddf8a27927d75da80257467531b353a9242b5e1bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d142a8d34b3818472432fbd9435a46c65e1d5e0807f8e2d531d94b5ac5ac24fe673b359c11ae2cd251623da2f2038800000000000000000000000000000000195202b0744645df948110d29c2499ee55beb7b740f61538af2537aa2c319969e9bd992de2d3f8e63e2807977ea098591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ccbd35a825734e3bf49261c506e86fce7f4c008b9489b19ef43a484f27d828108cd391038cb9ce4164cc63290e71eb0000000000000000000000000000000015217b34803a59641421e67b6e6d1c2f026be006052db8ffc6da58c54eb610bc880ae08afaa3cf320ecb2a5965d27e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e5573f09c71da91ab2a1d9e7b94953cbfa9acc4f14101538041b8ef2b4976b24aed53155460f1a75720bb8e014e0200000000000000000000000000000000187715ad4231d0530ba48ade2c0e42006c6e0c7fdb21f44a7b3a22617d8c4c7a9305ef833d71c82e2baabeb96eb904c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1787f030cfe1fa269dfd71a2005cdbfdfcb4476b9c26552d9af4d355d530e9fb2461bd48604aa702412b9d67fa89b70000000000000000000000000000000006a0930e941eed3893d329b2cd08f14b84002008064c92af32eff752023897625b87c89a69733741fbb9693d5e186ded1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d27fff8a3a76a48288cdfaa4dd9795798c8ded054fffa77ea7a559529d95e78f377292923bda348aea8e8fbc7eb7400000000000000000000000000000000015bd8be0f49e0410139b7e9d7bfd1e5816c01866de37fb46d803fc74401e09a7be398b76bc272230360b70c92e8a755b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de19e7be7ba775ceda719c6e193c75635f2403e8c4616f58970428a5b5e85c1782915af7716c272fb4e5e4243c55aeb0000000000000000000000000000000014dcf7d8252bb17bfab258ec39181b192742e312e8af13f32cabb32b776e907ff33f502ae0951a501d7a28c1dd29a0c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045e37bfd063f81b3e20152add47515c1e70e8cf5b6385a5b999d83351ca71856495b656b654ae1233a5376918c1c28c0000000000000000000000000000000000ecabe67d8112f407e745886fffe27c4792710b285ac5a27c1e779ce58e7a0d12865c0cbb309589792c81ab1a7547c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5d8771c1dbc8ed2565cfa344c73747006bcebb7ac0f48d78f14861d0cf1e93068512219a628a613eddfddaf34aec090000000000000000000000000000000009c56650fe82ba9e775633926f27d959a4439ad3f465829a920a069f420d1fb05920f6b7752a1d81f16db3ff5d7f72231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000392fcc799769ffbbadabbcb0c04ae258be28b47d68acf1792d36be1cc1466c8a7208761ca207f9b5a19351f8155ae9e00000000000000000000000000000000001e08357c781dd0ffc2d5083e80a16f8dde9b573ff27e9001292623a0722e555ec01233fabc006870235dbebf7076fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001294d841cbe0dfef49449253232e67dfd32eef1591b1842323e3ddef7f2c17342dbf1cee16be676fabf5a2349f10c713000000000000000000000000000000000e20c90c3f5fcecdc973fb692b012887e2293de12b8ef052cf5c5e49e07f70f64f65d7ca37f4435d30fc855a05ecee071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c6374269b76cb60cfdb6768b764ab284932a1c26daca6e3e93d7e05b88d27a2eb97f0f294efd12cb3311926e8133f1000000000000000000000000000000001028c20d1d1ec5d4446c2e680d0fa6e2c6882cf9efd5ab4839c964e188b2ab16ca6e4c7e36cc2478fa498cff196c840e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ae61d214f1803b8980db0fed8fa76555e666b5d11830c06dbb89b5328365b6aca79fc3bf388ed711697672ddca956e0000000000000000000000000000000007501b114a731c8d2043a668d7f6adf1f60dbb11bf6d9e8da8a03fd9bb1169b85973ba0890cf90cc0b627a617bc9d1ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089e28ca8426b4b7b70bb3fdb75fe1c06cbdc3a8b818b060c6687dc072e28a60f09bfe4c51cdbef8fc2d418211f455cc00000000000000000000000000000000180b4064223f92335ccb457801b78041e615615a76c0610cc9675e14636faa0851daf52c1301848e1bbfefdf675441991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bb4d6fd9b494a5160c4758e7ad54117314bf8063b53289eb7f535a712cd3f63fefa020f32b6e5ef859cb9a5b37d14d0000000000000000000000000000000008be0b1836d20818a7ade1bd623f973bf7cd5621384f812943240aea1051fa25fa1c392168b9140802126fa0b812bc381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b21fdf5818878be6342ba0f7f088ae448aab0c7f5f2bbefbd595a5f7b9f64b96010f1ba5336ab391e1e5d7705279c5b0000000000000000000000000000000010455779b738b2aa1950bc276d7b8d529739d6bb53783b694a6b0ee9bd0489187e08f3f656c29b7c5c0d11692907ad301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c714dcfe8abc24a662b77f0c9f8403a9e78a7695c7c8d06ccf9775e7a48b005bfceb9c9687378f3f5154bcdd3b2fc800000000000000000000000000000000097e078b4c8d46ce315b1cf845e1caf6ae2ad935d5f780ed9c6925dc03632026d4ffde711c9fc1f97e897fd136e2511f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a819d969c2c51ce6fe4d11cfa9cb8bcce92ff2eb18a4406971f567028a0021d73add7d418cb446d817a674f5b2465740000000000000000000000000000000005d33850ad448d3e5226193768d53dd8162f1e19bdb98d8be7668f70d1b9870a1469cecd91afbf3fffc561d48038ec3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc6f08c1061eceffef89bcbd62a7a946da712c44ee56efe61c9710ceb954e18233e39b7f50bdb1f776592ff44bb38200000000000000000000000000000000153beeb5cd485a611b876e511da4d11e26d745330f09bb017a7ec4f70c31e1fcd5286e59443556eebc6c6f208117ad791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1d603ec12071a0634485dc809c7c8cc913b479260f4a79282c9a265cbdfed95b72fdab30fd2f586c316b9b72862490000000000000000000000000000000011bc6b99e642bf47a5e31e1a5ccbd72ac3d912a9e0b0b3ab3313ba44b8f16ce0e259138dd25dabb689c1ad8d14b899831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001183097b2cbe79a86b8483fc26b246661899a56d528bd1003a5c3c5d57aa154b94c353d4a336c587e1c13ae1c25c5b9100000000000000000000000000000000045d8fc1ef2a1e1240672e8394c9e2b8117b2797e14c9b782e04269d544286431fcf7f4d87485e76417f0f1bdf4363a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ece20a1b4d8f66a4045a2cbfec6ed45e408e9d8c3b5542e3b976bc3ffa0b2c97ac385bfe54e304c2d2f011394a7d5290000000000000000000000000000000013fbe27b8bc30962a4995488d84d69de05e2c94a8ad7244f52667f789b272b5ad79a705700b0e0828edf166b52141b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5ce6f738a81119d99ffa13413c962b1a2cf04b46877c219256c8c149d0fd28cc0bbd12b6c36775cd858746b4ebd2e300000000000000000000000000000000102f7217f8c8cbd4100590f6976d559abe32abfa2be0a2f63e6b7ac436cdee36e74043d43884497b5c450dfcf9b5fcba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dca075dc9cdf21a280e4884bc3ae4bd9959b638130784a665384ee3a3ef8df9d12904edadcbefa2e5754f350f6b519a00000000000000000000000000000000071b25357b1c130d4e4ed392cb5806215211a39cdb288093ea0a7126f415eaef28688ffe37149c06a6959ddf9a63fdca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b96bd57c8d0510aa7b4f6fabbf0bff46ed2ed1db4d37002138c3eaaf28c36cc5b96e6c6992be925e2e83fd1151b6c10000000000000000000000000000000005ede28f7e31154a5d1721d09282e6b214e94ea622f3b28247fadbbb62fb1b737bdcffd912ce5b408bb839960a3b10c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058480cf561f5e23969d79ddf13e2a45a21539f715f393e61b6bdebae469900a3bfe1aa04ad3a57a7034382ac886f78e0000000000000000000000000000000015dbe1c274c90699b2ce386473397e009231197e21b1d39b92a1fd3a0b3b1c600a0579c874617ddfd953b0fbb5b7e14f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6d613ca6b63ca1308ef85a08c0905f80f8f41247a3c5910b102f52354419b11577a0232ce930e5bb6b05850db46e4e00000000000000000000000000000000124ee9c95eaa57ba7b570f44f6bf5d91de7915a540b12758a57a81714ef9785883eb296a28da77362caebb7906dbc2b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034198c1926741c247ed4f0062fa9a4c7699b9e36132f78f67390829c6889f6664b96f32f734f081e3ae7e9377985ed7000000000000000000000000000000000be07da5b50ef7c138c37a0d3e032bd0294211a7c05d1f6ed1b429807819d71ed8adc5e00799ff51ae45f6a79f86e1471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac502794bc463e45bb6c6acacb5c0a83fce0f66bf89b8b4f6aca25a996d1acc9fd39c07b255c3eadd0958598cd6698d0000000000000000000000000000000002483ab2369ef3506d6c5e4119296ed817b8f34b4e730c8248c9be36ac229fd46159538633ae8b47c5dab76091babbe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e1e674ba1336b28ea3218d29d41b1fdde32c9411de3756b0ea3d438babd6dc6560eb10b2c9942338d3110292038e6900000000000000000000000000000000061855a12472342b1cbac1835964dc616ffd9f93f902ba61979c8308f2050b529ba15f13f953ac6a16d6fa18241c96421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ae5d46ffd3a50a4d4696ec50fc4d270bce248bf7da01851ef16bab6911ef178d2f9d54f96d5e5d337e1023468529f0000000000000000000000000000000003040ce18f8674fab288810e50cbc573019ac3912a4b7a3697fa2499472fa18325bb589635d3d8080a551833ed4204541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038749f3f30b38b7f8f1e66bbf316040e8cd594bba6cc77c9e199ec9f77aabc2701296f27a012d53441346ebd4a94bde0000000000000000000000000000000001880e8d0aedf27a2e83979e05e689d9c4894cf2c9c7f7f9a2e4bed8369161a83ea7a71422361435b05d4f817f0324721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028a2aa8b16188a64abe533a1ed42a127daee0537af6086a19f645e249550c88654a908a8bae9b9c0b08a3739af7a9b0000000000000000000000000000000000a5f19d542349cfbb5aabc0db46ae9b380410d8b764c876fe005584d76c0e9539fbe3f69911a244a9b72377711770a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ddbe938ed2d6f512c30a346750bd1d16cbabdde7fa8121c770f4163ba569060efd20dadb69e0c5042069f0108dd05e0000000000000000000000000000000015efd66d5ab30d39d96854eef192f5edaa215d768a24e62c9c3962a6e2eaefb22eb49f9fb8ca6e5dae76e746a5e216c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003340433266f640af71855c912f5bf01cd4c7c7a84cdbbbe127c0a23b3aaf5c6b19f920ee87f2e9c8569d8d913e84b39000000000000000000000000000000000bf472b10d0eed9650ade76bc0fa9f0faf77228576d8b9ba4d641c537c1c4cf0c49c09594317ea8b296201f749bd0a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c523f24ca64afced64381742329aa0fbdd99b2bfa5188bb1cbd9e832532d2a840d24ac4f04777582a50c2d44cf0db9000000000000000000000000000000000080f56c3a7eaac4ccf8b70195b1727c9e484b3507a008c021c516ea7b767697f7467ce2c63f6528db5f9cfa76976e00e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103e2adde90b18d4216df119e0d92ca0a836216073ec8ba609a662305a9a432c77aefee70b8cf32aceafa9f79296917e000000000000000000000000000000001236c5f18e601364fece8eabdda2c8b077d6579353365ed1d5fe928a1a66273b4937756a348d2438d252f38b3914c8d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001388be336fce4954e3d35a4fdc4f7ac156d180dcfdd3d8923a3a78253a6138ea2e5ed0d1b0053442d0d0377d3fb425120000000000000000000000000000000007ebe7540c64011d5d6803fc457678b2821b22586170d35995398e25e943680428209b76ae827f535f3359606e6f0d491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fab9ca1d95d442ae47d58ae7e1bf496a21cdcc5fbd9541b5b64e31def867d3ccc9157ba3b1a050e092a02517dd08fb0000000000000000000000000000000006c033bd390bf274f6f3e4e97035745e40d752a8293258ac7ea62631078d1385a38bb07e6da739f80ee192e8481b96761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7bff0a4a71bc1cbe17645baeaef08a6d0416197eb08a83af05e30772ba1a94fc1655476b6880283645e75194194f0a000000000000000000000000000000000fcb87143e658d0782203676af902cedc4f88f0db642adbf9e4d7327fa71d9131d5041e4e14e1880f2ad6c5847c326d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f5f8281d500cbcee1e83e5474f03465d7229b4f794f03d72fcdd4ff620b955277c385860d00e59d1518f40f2460f70000000000000000000000000000000018c9a5bfcf3d1bb9001f666da2404251c4080d147ea800d84ddf2f9e3ea6cefc5dfc767b40b42220b6e88821746baece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c76242ab146fcd892aec3354e2f1e2dd3546a57f5b1bf5213e69562c50b313a7f82b671718ba3f8cc2222bbe19a3190000000000000000000000000000000019b63bcf8b241edf079c1b311cd76f787c0d832ea98207b50daa92308c5f174205dfb6b1240b078bdf774b8e7c5a395e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ae21924707e7c445af28324527da6758529175ad4c657ba06acbfbf3058ff655901a35e6b77ba94b0ed74756739aa600000000000000000000000000000000030d903cf9ff53bf6a78080637865ee95d8d7428a783cf68aacae1fa4fba67c9d730d6c1363112a53bd1c7b4eb93a8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000407c2e490ab58c7449e03fa2c07a16c17c9029b1ca50fd1b7ffc685bdbe903dcd25edac5a91800b594f32055dd456f30000000000000000000000000000000010f6a8d7ad9bb0188de21a6fed04a58192f70df7331186c4d63b19a40c140af467f1ec8c38ce75e8fcd611583247619b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000820130bc4cefaaaba7ec743b04a8ab78e78397a150c1b2c2e68f59b289939031f9797b6ec04c6e5f308bd97b0a43a5400000000000000000000000000000000044f4f6fa7219652fd2025876b2ff3a61bc68452d43b1643c0ab108bff0d2e8057db0f986685c6e53b17356f9d9a2c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ad2bb7d7aec7e35dfc84ec689e5398e03cd7c9f2c9d0f94a2dffc59488b51bb1f614d8bde3330371c45f2734a9f012000000000000000000000000000000000dab495b318c28aaf23070d5656453b070937a54617908224492a663a639c1a0e2c6b44b40b77eca55e3a94fb1eab80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e89e8c410c7b6cadf1fba733df1f8746b714b14a73701970b88201cc329fa9d4c5ca844b2d7e423ee86824487b432c000000000000000000000000000000000a2ba0d5bb33342b68e12f85d9fce6655fee43c8329e66d4117bf77e224be7842956de28a88e3674bd13985ac59b69de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b00a0f7f8a5e4a41c5218efcd40c269a2f12681666df1d0ea80a2796d419d36e7890cad0093d1df793de3465227a200000000000000000000000000000000018d725e462110c8b8f3df1ca2f7a330ebfc0809faacf65e5da2a5acb9964849fa3cd03a197bc4c00ae1c516630e7c2121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8e3c4cbbab06cae109475c74682a95cf555f57406677c3111fc4a838dc95053fcc72cb57c1fab17d8f0e39f7b88680000000000000000000000000000000014fb8ff2433b0f12aa572415b6a8f808149ad6bf310b610d20cd89b2feadec271db9b86c861fe1e94544d83b9c287ab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b55ad62dcb19931a465a2a57e7c2d47afe192aaa6068e07a4d487bf719c84f1ed08c5a833fed78c515581decca9d650000000000000000000000000000000011ef532555c5cee1075b4ec58edaf29acd27f0e99f1b7684b207a630f281ce886cbcf5c5e86ef0d4979503d414ab6e4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f51cddea6ba1aa1df801993a998344388bd4a13cce582b91907172d10b0ff0356775744234723bfb2ee2da799382d7000000000000000000000000000000000c11e775a7a354e75281c62886cdae96e2b72e4198a586ff76815898e8e7e0dc5a93270e5b567635a2f3ab8e9f2f4a771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a5874ac376ef5b24ed8c3841a0e08cd62c4847beba2189ebc9ee8c7e2b95c700560cf1d6abbd254a8f8c0364aa82c50000000000000000000000000000000012c3123189a6db9904c22426af71321c96475f0bfba28bee1f672e12750b7f61bd56a7e13eee82d1ea112ade3ca399691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ae54d5a38c9f95d63be4f8ba393f8775b277df6e761abdbf03b842d07973c01de9058285723979912201beaee263a900000000000000000000000000000000105c0379dd8926606138fbba9d8ce8b538ae31155b7ceca0a06d3fb09f281d9303308ffe1c3919084c8dcaa06019d0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005af9a1a8c2ac496d1defa3d8c304c60273ab4d63d6a2f634c51c2ccd1221f1787c151ffffc222c0c68fcf4c249608140000000000000000000000000000000007e83b09219b17d506a2b396ecb15e52d857d67b5699144c0d84e81c1e57d2e92eedad9513a6b3e1800a75ab57ae9aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b33d9d1d64833f2b21cbc783a53e0e8de0c93cf39bc6cef3fe69830453f4081872ae91304f498b364a985fef5a576000000000000000000000000000000000fc72ac37889a0e9fe683d679a10958e1afb50b402adcff0020634a692f5188d934f5afc8c7381c9308f92b09dcfef291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f893db85b655221873c0ee4ade715848c4363e354e8e63d3537ef4a81b1b95e48b56b8cff1a3816e14a6c5c6e61a6c000000000000000000000000000000000f8bcf7fcad5a8150eeeb409978295d0eb083d9848dfbe21c040fe5f24a2884327b8e48f640d5416a8c35f1bcdf3dafe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed6ef877f2000f5ed7198fb04f670dac7085315d6c6c861f81805682a3b7f467547843a23d5f6d4b391c16cc6d7bace000000000000000000000000000000000bc3078f0018a97732d0c51e1550cc781f374013d9948f2fc6ba0ccdb801819a4e772eeb529f4c9bfe6d79299995f9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d9ba8f4d630172515ca0a73243cf642704c784d2d250c25bfa32c6d209f63737f6ef40084283fe6d25c0328c1e7bd000000000000000000000000000000000a76cc3ece037a6ee501f553e0383824c52c036f291175e1bd60f30b482aca0d63b45f75c67eb6e90690eeae801da3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a92f71e51a6025045d6c1846bc7bf65a7a906c26676b41544fa3334637e7129742c27e4a2001df5a364bdc39436b9d0000000000000000000000000000000000a73c7452d5f927a7ff165d6168c143166457752bfb52bcea405878ac13ec56413742a0d303ce39e5a647103924140a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f595416adc7d48185f109337ec58f23af7841b9cbd851690e4eee5f8b0e127387c11eca47d1e56794669e4a9e34efc0000000000000000000000000000000010bf7591ad03772ef5b3f7c63f16e5e072ff688c86a920d3a7baebf975b1a2b0d0dc25d6644ea2273218ead256ede37d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a243d8c9f495f39e09550c8664693744f1d3606e851272f1e44af8538700a5ae6edca22120883616963ac2bf757b4800000000000000000000000000000000014e5b2e5cccb3c314c333ead2067a40d92449355d1df4537c8bc6d947b5105152f5b4428ec223d74b029e086480697b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7f5bf1e784d3fb5c536af9f3f37bbf4185b6967840885d3b9a667a5d908d1b0c8147d83fb32848fbc0f419b340bc5e0000000000000000000000000000000014b3a6159fbd99ec09b2588162687afc81fc9fb85baf3c0338511079cc7e4a9ebe609da042541a405f3972fefbe9b7461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac31c65d98d000433dea00e8bdee90211d285a08d7848c8f20a48b170219b0e7ed610ec71b98a514fbe9bb520c16ce700000000000000000000000000000000060f68ae3f5520d8a546f49891b045e0078237b3137b7e8b19b50239dff21b354e9e1ee38babc66fc168f8d808d3695d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031db8ccee1d7807944581f833fedf0b13fb6bb706b2fe8693f7118a52923f2e25e084e287d5c824ed5fee0999a69f960000000000000000000000000000000006a377d46c828120792ebcf9135c12d57edaa5eccde526d2bdee732de2b1ea98505d461b36470d12e05c3747ecb11c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e90412f70480ae3c12c58901a838ada09965ae86e66c6b9326b580e644495781885ddba567686efc06a27908848b4fb00000000000000000000000000000000096e679e4fc99a85396e0eaed159530ac6f8290614eaa505bbc275b1aff9fb47003ea76cfca64bff9a9ec7864925176f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008275d1295e4207f0fd3a67e29bba8050c094cf336fdb42f18a0b77bae48517e7884d725684ebd36c548664be94ba5920000000000000000000000000000000007a8ae5e04573fccb404c20bd28d72a42cb36eed254d41326be3768a14bf88a0e21e2c43d4f48e62502d36bab65333181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9c6d2a1534a35d25162fb552436a952328fabad2d1ccdbbe0b7d70983eb07f8bc5b257627c9012d8ae8b6cf849bcf70000000000000000000000000000000006e6430bf17affa757a8d3b674b47d23fdfde9c1bb02153ce1e31b57b8c323902e0dea29827b42780dc5a8e764746c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001564b3592702066a099b58db02fa3db5c1ae67ea9c7cc7418d21f5d9dc83ff14a7bafe77b5e9e97ab1d6b8588de60719000000000000000000000000000000000b6cd1a87205d8f9e26575c63846e3cb63c61d633af24e72c4849e554f27602a5be8e4ef1c81606259349d8f611d95921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65294210b47f6396a3a4a041fa7add35a7cf4b79e0788104cb450021b100874f4d7367101a7dad30c8660f928314c8000000000000000000000000000000001067d9000fb5aaa48a1b9726ed098ec89dd15751521c51c8630e067048ef1f211d137cbdad303f7bbe0d254b8f32c8c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000afb014945ce49a2427b9bb32d2bdbfd2b178c57b102cb6ed31a0d7163a7f5e5ea283cfb3ec0885f367cafe0ff4333b0000000000000000000000000000000016885b28b43c4fb987371fbccc52e4fd8ebd61681f9e0babe4e3cc3b38a6125f20cc49350278b742002c842c63d53b271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000395a7ff03d0e1aa6b97f7064af5d7b2744d56340c4b7407cef57debcf1ce356a7ae4acfaa4d10ed0bc2b28e59a962ca000000000000000000000000000000000609c9d537420ca2bdc3930e824e31f824c2c6a7a50dd121509c6fdcd66091350d87990abb8b747a363ce8eca6505d721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039418b6ef48761b9b9734fa6cfbf184a490600fa9b014865d3519130b5d04b1ae2e113e798df7962d9fb9ceee6d8cb500000000000000000000000000000000182a765e62feef1720979c9c858e84b883c9da8c4d012885119fff2e61e239dba0df9d822c7ce34603091fe4353786d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000197b9239600648f73e54a3884568eb89010a7d86216eeee7e5f0720be75ee45c084113489408feae1f1c115857cc557000000000000000000000000000000000056c5a8ed91c52f6d7042abc117e392af424268e2ab33e818d726b31fbdb05d223ab4128e19d3da67bb2c887222a43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a461b1c881e59717d8c433ff138f167eca88d7acf383522c5a69fcea248eac0790d83aa023ac77ab1d508096e27cb1000000000000000000000000000000000d92a449470836c6a3fe6be2fab8bba8de526aeb6bd9659b6f5e19941dd5c23c7670a86ff3ad66e6be49f54f56668be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051e27fc21839f6d2f1e210572b3ebf3fd571f0ca2f89b2d236fe1d35ba74b2f3bb582f06eb4e7c6a0c376a9dba605eb000000000000000000000000000000001901957e991930d7e2b51fd5834f6591fb360fff892f9acef74392406a01b1f44bce62f41c035a169c3b92bf5be2a1931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001823765a3d22dfe41a8c5f874ef46c783e4d44239c611f74cf895a25f7b29073090e8257af1cb6ab2c32b2df4eaae311000000000000000000000000000000000f7b25227f7d88b3680f6f6a86af6bb631cabf26a3f5e351e93e081220aa5aed4b93f7938ae15dd90f92d115e136984c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001431f051ef89b344f50575c1f628a5f7140101076dfe09875734aa533d1d8046d6585db2c2692544798195fff3db7600000000000000000000000000000000000460a7faeb7b31d68f8157da6e42e581d67addc3bd837ab5a2cd5736a00e9fcbbbb85e6058236293af9e23d085a3ecfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7b0b10385ac6bd1a0f90ce2a2c6ec87c46db498b235ac27d84c8fe672e8c0cf521e011e7bd87becb6f7e8cf2edffc00000000000000000000000000000000009493bd9ac530f7eea5a8aefca76e2f4be67e15762e935826710f8c0323c9cdc9ebb91db3c7697b4918af117f7e283021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059efcd6a9c84dcc6f4bc76602cd5ab64dad9dfba2920225c0e0cb2c1c5f515c8f28aeb373f5ec3f6f3f4045df03bbb30000000000000000000000000000000017e5f84a2c04965b7098682f77b7753d0341f9b9c4049f4ceb682e1af6c6926b3098d0f2a3bc40152c20cf36ecff37e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008432360a0addb9b833c77a0a33631afab70bc2a7f1f590dd6a992defc8bad4b5a17babd259094ce301ce9d31d39e352000000000000000000000000000000000b06c7fe46c2fc8ef42c96a8b929d0e2c9b86b1e2c01ed96d48add8920b6f449921651176ea804665e6009d8764fcb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bbe46bfb169a9676e997a20aa501983a411c9737be87187f950e2c2e3e6a3755aa765d4fdb5825785f4d3cc60b563200000000000000000000000000000000124c204d7f3c6ea2df9c0074f670335120c50e493556db8efd1ac1d883db5a65bdb76a8d0808c0f5aaab174b6516b8bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001282bf2f514af539142269f649704f1bc1c0ceb67a10b01761332e32966bf796308d3c1bce7c2e7da37b0be8ab2312d000000000000000000000000000000000139fe7c8ecb824225a32da04d83c0a9707298426d8044fec96029bab91961e44c3ec7bfe889806c96b376b3ff63a307e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f6813640addf21856f4629116527d06ba771debdc2151bd56568b2beabdcc45677c67e80d430da463874d0b5fedbfb000000000000000000000000000000000348aa82c874289bd9f2b05bbd52c8eaae58a973dd00fa49d988309086e28dabb4f5b816e1fa9e110beb68cca89a73a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007872f35bdb204b6327dbbd7ad775bda615eb30925daa8ae3c86e13341781d85518884f179efb0adfd90b5a42f7909000000000000000000000000000000000bbd8cd2fe496febc550c9517c2110816f1ef7f5a0b6c1c2a47ce0657efd5551a96d21c08d1ae78de80a1f090c4ac9821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007029c7310093f196832a99df00a350d05fe480a2ea26b23ea13d27b6b0e3e426139cdf74d50205727041061c3ef01df00000000000000000000000000000000037fa92fd0efa979db73ce7a50406aee4336c75bd700dacf4fa30b358e330566e19ce016bf3dfd09dd9522d40502512f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed2181d29feeff1c235b93dfee7bf61dc425a387ea703993459d259b045552eea4239975c4a27532a94793979969520000000000000000000000000000000000c3b7d5669630bb67374d2a7c9aad6b4b408b95cb6492eeb1834ed1d90c0ea7db7c034b8bd668564551b208eec30d8b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000779357704fae49f866d301a1b28bb7536dfc6a420148f7d2954a3832d2cd69f8ff5dd059f8e098e6e138d29cdea9ada000000000000000000000000000000000a27bd6c4dd5c7e226f5099a7b8f38694ac313f94aa78798821ad657b53aa2019cc3a45c8e2f40f357d45f835c8e74011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5a41c18205e368545c7bb4b9e7811c176c7b062729be14b4f8bec23a6e3faa326ebad12315960e285478d01709e4b90000000000000000000000000000000017bafbbe027176ac44165c470f942635b2909a372835d8dff421adbc07799b64825adc9f18a1b333209a052b87041c2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014110ba7bc682a0d4b9fedaeb5ed4ab8ca3f4f321790e0985c28760964fad0e29e0a303020c443735b5457b15bf85a100000000000000000000000000000000186ec37bb3557750f78c2d4b325093956c83f368a8ca7d5157ea7b1e1d8bf14096468b86b1ba850423ff0ff0a4076c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f425375b58829ecfd8d9295b67051e2a2438e97a28ac225543203bad9cf23596944a236f69a55fba7487ec24aade70000000000000000000000000000000014fce889975e94c8b51320b0365e0e38d5f5f8b9a6a163a158cdf05d82debe12ca38e34dd65ac4c1d7351ed3b38b61bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001819da455d89718a9710f8758ecb6e57f932c74bc1c4dd0998a82361e5193f38b9a39203460d2995dd30759ac7224b30000000000000000000000000000000000d7d5bd3fcf8351c77df5cdf7986b9f5f1600e7f704d26794eebfa32678bb724a7e6bd80f0cfd26fc5aef1204913c6871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077480d80988d453047545d67bc6b583f5711a54b5e8d96cfc776b3078e746b17b09e82fb44c389216f53e7da1b89c340000000000000000000000000000000003f04dbaab6be287b9c4136eef637c73759edaff3e1b56d669e8d37be5a06ec01ecc4a680260830c5e02e62aefaadf4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e599ae7604045136712ba67b019de2eaa569c84a4c00909f72ab671691c51cdef6c91c628cd22021efb9cab52503d0e00000000000000000000000000000000165f27c82d3075a3c5dcd926eb3379556895fe850dbbe7fc7911ac8ea9a12d376fc5d825b3af1fc4792ed84ea613b9421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163fa68801225853a6a56a2ab553042d93126c3aec695c437ce7e9ba8d7bd0dffb3f488caea9ee2ae85e15dce6ea825d00000000000000000000000000000000155fbc1fe231127c2e5d17827635d1a2f47cc0071fb2c9ece4dddd74ee0dfb7083a0d5ba7bd9ce1f791353461654bfbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c5d567b869736ae85bfba5112a1126000fed8fbcfb90bc2d90198c6fed9975dac4c994fa8a9203d5ec1375ffdab091000000000000000000000000000000000cab607febf71cbf072bcdd8952d169efe557b94c32f2f5b6211b09d1fde8d74e63dd13204046544c25804e66f2e2f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73be0705865a16d3ba7f2d1828cb8a027af47ae436474a18044be6205383874383a8d83375d7da74f1d8712a0e47ef000000000000000000000000000000000ca6384874e2011bf6cd6d9246e2646c196cadd50f83099c04904df8ad2202a505dfd27fabb5f379ccaa09ca8fbdddbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000652959c0891f96cc7a7111c45987751fab9a770a9359b45631f3788e194be2c2d92b51c9de23001883e4380e765dc25000000000000000000000000000000001685f0dd8a0df83f80b5fea28aa9b13f2a268e85eefc8f0897986557696f3e09b45d39336e8d1519489c2199914a1df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4172d52cdeda6c4ea310036f5cd681766473a8074fe892e5e7c996d2306ba31198ed02052ad760f36cfa44d13356e0000000000000000000000000000000008a78e775c73bc4ae26a816496762a418ad517c7d9363504a9adc6a372b4bbaad89acd98854ef53d9753a5e0fe52e3781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e44553c0cbd43de05c35e6f2fd31b2615e56571ad1cef0c33bc6119a1ebe054f1a0e16e5a6e32839575133819f2508000000000000000000000000000000000a1619b47cd9d769daeed3a03b5fd138e0ca61d3243b738441a9ab1d770c53a67fcdc1258b5841dd207d591607608ecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000378bb1cc2739a7160e6697b64b70cb8da96e51e1237bdd71b0240bc2c9000f70ea79d40adc691f5c3fcc7b29cfc78e400000000000000000000000000000000009c94198f776cc50958978fbca838b5b7b4843c94368afd038271af1d6525f9be0aa3a69334975713dba3ec3d1af9ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5775e28d3d774264be1f83834e20b6fa6edd5abf683f026ae81f1991c3caa1eef33d29bbe73142e0802bdecc63ed85000000000000000000000000000000000ccd2ded7c6997ad3406a03d621a13eb1d52e3472be37346ac2988c083be24763d8f44349accfc47fe6d4b83eb3b91f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018772447d2c1a35f00376cfeda5b719086fe9b4f6736cc1cd5db754b0d52a26efee34dd17fe7fc15bee160670c06e59000000000000000000000000000000000a019fc1101980a85e073e2159368eef1ad0de634e736b2b6f7873d26ef378e518cd08fde3cd8f2cebf21f8ec68bb2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6c66d5e6eb6ee4151597a12cc5b817e271f2eb8ca8055e012efd86cc27072cf0615f93451778f8c2ce5dde551f8e30000000000000000000000000000000001599659829368b02b8b2f86c831dd70cdb5cfcedff2e6b189580d07c7ca67c4873ffa93a3f87d4e9ce5bf68f82648bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085ca8409e7f94c70d2128054afe4b2629b47eb981f7e7bc75dbeaf9758dd8d276aaecf1acfa6e330ec123d6ecbb65bf0000000000000000000000000000000002dd3f77be91036d2bd6e3487455fde3a604e20a415c0d44183ceaaff486b650a13874cde5fb96b71423e1335c3b58d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001357f5a242a559ac54733056ed955f805a64c7e709ddcffd83ee9cca74008ee9b9f7997081eb680e8857c38cbbf6cf300000000000000000000000000000000016d5cad269366bb769278192e58804501ca241cb38bf46813ba03f5a769d08b3abaa409cd196b2df5c984141da9ce65e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150ed8d536c17bbc1781530f2e04c142f8ce0db43882acf5b4af05daba790902603a61195d9b10650fc6d6fc08fe198f0000000000000000000000000000000012fb9a59ed4ed98fea0187f4727d872039a0789361a3790e15de057ec35044eafb34ab6ef43752fde7863bf4099413cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fad1994be876ee6fad506fa19a1fe26d3c4db6575d3676381818de77cd5cfb8323ea50bdf38ec1286291262ff34921000000000000000000000000000000001396fbc29e77693db4c3a87b4f0d748686fb5967903106313bf441d2e102b402e961569f96fed315f5ee76ba105ac6c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019706ae7985bec036ff8dc7a0f2939b3ec7c144022274f4b52abbf6efe6cf7cadaf86e0f890c4406a190c10d98bd4f10000000000000000000000000000000000872caf5dac41c43b614180929c2519932b8936c989e01f73363d08becab6decce3c8b6d9d232f4f8de9f43867e3f7ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123676021903fde800c288c07751d42dcdf66a81f069cb77134bfe2ae46a4a5e16d2ed54ce853723c4dfb16477d6e79400000000000000000000000000000000185b4be8351b73f3c8b8580942903899088f53027c8ab1576f8fa001a7df2b613dbffcc1b6d5c6eb1c35f40600b9b96e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ad1c11de98b6fffdc2e156be6bd2b8c9cdfb078a60cc341a2ca3eda413b40e702d0e7481538d15d24b4948b148f4a60000000000000000000000000000000015e373f5090e22d9a7c860512964aa11917bf752bb38c0e5846bd964ea4fee5f5ff3e54d640f0f8a69e5662520765de41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b76aa7ba46e578af7117d96cef107f2dcc53248842898a8bcac635e54f937c48d4098e31f9425381a533105a7ba6ab000000000000000000000000000000000f6d5e2211f577e0b5359f00879b3ad6efd95c5f74e8bcdbac49d35585c09d8d9b06edc248329fd4227d7996107799f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b3d170bfb363557e6c2c0bcb960abedce7513986e7326788642fbc2440d71263b14609c7337860e1a49211f60e00d00000000000000000000000000000000146a70ea9a69371aba6a3b8f279ecf2b9635218e74a9619da30433bbbb48e71a74c06e79449d96ac4d0d1185589945901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c732970e5e602abd31f1c556685f4675ec100ee4a886b8dbe5be6065a8561a4d4749613e7da5b8b323f66da826b3690000000000000000000000000000000017e322d5c0e73bfff850c1aefe8571c57360a85fbc02babf0959686b26bb810bcdcfee06bdc06cf3e85baeadb11df1181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bf3a9821c43421e8e4e2d9434e2ac0be59acf9f2d9c9911ab999e4d959044ab3cdfddb612a6d9a7f2b4c9af5f9360200000000000000000000000000000000132a3eb5f4300f8101784f3bb53eabad8c63da291c6bef0724c0e8e4c36b7ea07b82958d59eed7d6fe4a528b3320339e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198f80f0845c2afa4ac513de4ff3279095d1f95000e011498a56a51f635817a7ab1e294daca98ca683b8bd44ad913313000000000000000000000000000000000844e125f28c30fa22563808593a3a2c073b937ecd85faf3bd544ee81088c63c1c3eed62876d4649a6852a138dd49b5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb4fb563795e532eff3e3398a9ade2567222eb423d8fc847c1ad52d580417df5eff797af7e2c0cb2c426bcb3e3f50040000000000000000000000000000000016b6f2ed9adc708a7cd01e836b7ec7cdd1fb6d39c0efd0fcab7c0c7ed276c9a613c142b20780d545a2423127ba0589d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006de44339406805bf245e4ebdc61ed32ed3eab98640e8732aef03583914b59a45a05c5215d2d2968e110e6d417d53f8a000000000000000000000000000000000ba92a232bf4220d955eb87897315d33d24e3bc7ae4a8e5d021c72fb189294ec450bcd358b41aff2ac6ecceb943fc62e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f93023d31931a212d519dfdaa5d02bbc0f2cc7a3e0109362f1f0a22e8956fcc4e2de382c3c8f1f7884ccc4eb61a4bd0000000000000000000000000000000019f23824162c49843d9d3879e8698cf7c9099eca223f4a42162d48c38526de97396cb33f7e22d2ac0ce8e3270e63f9391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edb8be521625477270116d95266698f362e615cc5ac18bcecd8b6742777947229900969ee6495f20d4fc27ae57256570000000000000000000000000000000012529ad5e084293db07babcbfe97135a1e55d4f0225fa8dd9f009882cadbf5561abb86e116aa496e95d4ed6a4dc8aec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc71e8386e2b112d2e4aa5ecbf7fdddae64b55e423b946a1599fde2b4fb2feefa318284ef81730f8b11b9d6317bc8a700000000000000000000000000000000124f45012789cb7e361eb705b6ac9164f3a0caebb66efd3e6f1da5636922ec050fb6271431663177d8af6e5a7c3de37a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036e095fad73bcac542ec6a8b613305a193cdaec55366e186999d9ea4d7eef5feb195e8ed2503a5a02ad13037084775000000000000000000000000000000000699c63681350d469b3388d10d6c1b58550ffa7b0726931a1919241ed40b4c89b2b6ee89f9681df59876e0eac26b92911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001311427af3331bdcb1b63b60d9cbbce40a0b51eadcf67423953d4b7877b5abbf0b92b44d4185163a06ad19bd857aafe40000000000000000000000000000000001ffc7120e422d63ff5f54fa025211b329ca2507fe9d6418d71309c0dc3465253a203f5f5da32c25deccdd81cd2f42bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a890bfdc1c8e3a7f558cc7f74aced505c71a66066cee32c6770fa4a5de53123cecc3f5a1963e4fed884d4077a21e440000000000000000000000000000000009280b66c2b596d7744918db6ff9fab9556cc5baa96fdc2a5b3c4e2a3d72a99b1b23010f27f7782888b7c57fccccc7701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118872dac0cbb49bec69d60e7674a063fe23cbd0ddc80dae210e43769885d9f2f07ba4df90d4871807497f543421c00e00000000000000000000000000000000034ee1788085c4b83f683800d761495ddcc4d29c0c0684b0fa469f38905b768d13968df86cc2e6695447c7ac05a241c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126ba4331dcc1eb0f0ab8fba37e000433623d6c85d76e7d1b479957f07b051bfc605666cfd34adf747380de73a74de4500000000000000000000000000000000140ec96822b457b9e0990997d5d04186b770d3d0285b28c271f075529d143c7dc45c01457c3f9d2f77313e6eb8ecd47a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184f21f7c06b6b6ddc4e26ddd55f386560d2d13086df383d1d6d712494a6e4ae316a1389bf4de41f47175c38beaa670b000000000000000000000000000000000359239848314c2dd716497144b99b2e3bbe5adc7556ae0ed751f9c8a3e980a0cb9636609bc5fc7a7d750e12c16b63f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f469110d069df3fd6c014ff5d90e030e312acf08dea6c5bab5dbc6962886d119a8e9554c2c0f953c2b2c35ecb9422000000000000000000000000000000001403c5004fea08c57e325f95c7a8bfbc9552792c186af10436d2a7a1ca38abf193483c90adb5adff22a42d7a98d36bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee3bdc697647dd57523cd1d7f61f0cddbf5c16a1495869f2819a63fe196798858e4f365561f76b50bcf12b5189a5afa000000000000000000000000000000000b675667fbb500f9d0d5037c011fef8261c4bdf19f240d6d2435d8ccd605a942003bb09eea045a23db055015fa07e0b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000756bc58939ecf60a2dd0349362f3cecd757fd6cb0710930e7c6c366d865b8cc90386ab6af6ea77bf95e36544fd102b000000000000000000000000000000000cebef3f301421e4d3a51d0478e3c6828c2d93c8b22bc2d48d43c8fe56727761aa4eb6297f58d875a1a3f6b07907f9b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c33a0be4ec8267b3e1606d1600b5d2b9343810721d68ef83b523744ad352d48f2c07be9203ffcb42567bcd0185cc553000000000000000000000000000000000f01c1a0f42ccad5d28e5ea88e55afa7f5e27764ce8d864aa55de43a62c5184218a51a86c33fe7f6a84300310e7ff4091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015edecc0c0c5ae51f0a100f51c6ffa1449303c00ca20db5bc27f5ec6114e4447b3d15897bdca99443a65177d729068ce0000000000000000000000000000000011e64459cca4411cd2558a15208d8c2f2170fb988e5857dda57fc0d93770d45a187f7b4578d5651f2ce09491e163e8e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121df4a58be6de716b996b3e06ae71f21ffae78f65eb60e0fabbb97185b985eb0f6bdecb3177248e20919d2ca8e19b11000000000000000000000000000000000fd188a625994994ef96b8ba734f1534b5b8c0c4744bd873715f3b701947aa297ed562b4c2002d3d4116f91714178c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dc946d71475881499320dde1727d19e897a096466a318b8047cbd1dc3bc30dad8e6ee17e698db1d1bee0b1796f9c02000000000000000000000000000000000e8a568a3400bd0150e8dec55c1ca3162e09b8fe26d607f34dff4bbde4156806dc58dd990ff47b95b90823ffb69997591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699006917e93918d8b278098692783d16541c816684def1da3a0412dd0b5ec313e4045137e3193a3522eda93dfb70820000000000000000000000000000000012591eac0bf37346da8ae69b4366509383b5327dbdcc728311b715501e2e7ee8d407182957dd3114ca2ed207fee56b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142ee4c1eceb85d789f4d2c55c92eec8e47ef878ace960f63896593f115f95267e4dde607627c1f56fc18db54df7eec20000000000000000000000000000000008048e2696ba3cdb362de917a86095084cbe79ff9a88bf1b2a2b1a75de893f77b232ad8a46872645c908564d49bbafe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021abde2ff40b8060648493bb491bc5246213a619d76053e7f252e0ce1a28acdee1fa785e6a9495e1aea6c1dc03e5022000000000000000000000000000000000d5a48daefc9983a8bb4ac17c9d4b095d1d3037db2cc85d6513123a0cb2daf7597b102722fdfd38aa173ccff444af6cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8875e376437420c269ec540133c5024dfdb14e6ef3af602dd0e3db5d0522c4091e052f49cf99662971bd2bc18054400000000000000000000000000000000176c555ac88b30cf6c536fac890c7a8344ba3a546a1afa1cbbce7d7e0f525c37f0baa782bbbf5e7506c6a1522ff6985e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5b3c7e201e85dbfbe80a4c5da68275059f085d0b5cad13bafd28de796ecfb7de0bcfd8d76d2b0ee49ec9071f52b270000000000000000000000000000000008b107b3bb231c9de8a5fa2c9e9a6e06edf48b0deabd290340cfbfafe5e6b78df342f347d6643142ab817eeeebfc2fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144a740fbfccb1dcb836bdb7a75f59fb5448d8d763902ea6b0019def3ccf7a816b2ab7e3b06d573da2ae23b4ba3dde8d0000000000000000000000000000000017cc01c9e7ea6f5b805eb8080b6cebed6da203076ab2dc63b94dbeada24da0cb66ac1d702a7255fc3bafd64f2966f86f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000743033d7f17b223991e86dcc6397c41961e5f433d529e7b2d70bd802b23a300ef1216c6c2a6a08d02a42b30b1ece6ad0000000000000000000000000000000019379244295f3901b61cb302bd311f942888eb8c8144e16ad3c235f4324ce00d041fe88340f702b975c01017224750ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d471a3b42295c97ad955b5e8dd70593874a1ce5d2caa02caa8312c0041a9e91e150ccbb417e1180c6ab830c4a3615b4000000000000000000000000000000000e6bc984561df57e37468d6671d7875caff1484ab4bed6497ffb7a89d8d80e84d18da64115bcf9f616b8f103e1bc0f1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d3f37ad63642b66ed2261c48e474c513cb754a62e9a14d6c2b5e65e20d818b9de4e82bfc1c7d783c18cc31097c49a300000000000000000000000000000000002c3cfa6cccc44a5f59607352c64be7a25f85a4c827022719b84746e0154dbc44810d2af38d45fd20a178e546bed4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bedd09310652582a972b6c668b7ebec95248e2d80e121a14ec1b004ad2a039e714f16cb3b4f2dce5f1b80e3814a7df8000000000000000000000000000000000dc9b7c86c7ae4a62b06fd73e3b3363ba00b10b9e4517a8994b21365a4ca56a7b967bf846b32a02c7ab616268f7a88031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c1e55e8ce0fd83bfca9a92dd7b07e6119e3f99808ea1e5ed8b4b8ed2d34d23d551ab5e317603026c36b1959f0b8420000000000000000000000000000000000087bab4071035bf9a68232467cdfcca2bba846059137b087a9f4bec2325ab9626451c74c0fa910095dfe8fe4d85f3401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e7143af838b07482810fe089e51a04bb457257b86f85ade1f11a9dea8a5ca8b83dd5e1052214297be23fc218b1d5700000000000000000000000000000000004413957ff81bb49e3e61773bb4c794af304bc91933be8a11f5203527ce7a57489bc97e3220186068b2b5c88d853bdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006be0a42ffb60887309a9886eb1185ac733b91c3a3a11cf44b5de0c9ddc20e5a7851d082982f3f7df0d8e5da64273f32000000000000000000000000000000000f8c8ac95226472a9ca4450d7f845dbcc161dd5e8b589c4a2b999af3ffc8aaa2a6bd9a487c0351b950ca5f57a959070b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6155056136afb4ac4f970944df93ea3b981570ecacef2fe636454ac517da9da4d0d124bbfedd40a215dc3fa565b3560000000000000000000000000000000006e1be9e5aef1ff27b5b0a82075d14433fe3cba0831c145a8f491290e9832b474f4fc343d1c44bc23a8f3a3a8d020f2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154bea7b1b48f22e10b6f3c71d876fe840d441bbccd81ade8e8781df2d960dbc6ee2ecc8fbbb6e6df68830cce3add92f0000000000000000000000000000000004042735cb8a5130597991496fe9964167e86f60a7417d7b7825ee59b3e2e6851a620f64424d9193d9fe56af71578fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6857ce8a394ba8d4bed54de6ee15b513640319be99cfd7b97693695e1270cc4cb1bc6939b3e78d04cba8c574f3a453000000000000000000000000000000000a96877018396e1a439d4e2718d66518e19919d19abd89a730053170f1b9402dd81c79f175a69c10153d52dda53104821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012211e8fdcd093bdfba5de39140cf8c1f502821969daa3c235143360e96c769adc12ecc839aff67bcd14e9d5aa68c2df00000000000000000000000000000000162a49e7a364838b23dad9bb32d839cb9c92a5e8e45c58bf18ebc425c27b8043835e56b2429f8f171851d7ea7e38d3e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e53c67ca7f58bba88dc6862e3522b133c37ab09786faffbf1b6c8fc6d394a02f0aaeef47982234f08b19705377188eb0000000000000000000000000000000009df642dcf69ff4224ae0e9a55b592c0205a2ef81afe9d8b39df732b8298dd6496a4f56ff8ae2d10ec1129a71e8459a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074421114956cc5a2af15df2dec9ce7f0e3ba61dc59f5319755a56595bcfc949d68626829fc333d625468c32f1aa9f5500000000000000000000000000000000065d96088d236eeb78211e3505784487cc7a254730e0843be579f317033a8699891c6fee1f7d64149196abc5bf9f38c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbf699c6947e098aaa9f4fe273dcffab86cbfdb13131ea0bae4b3f3ce134344b75f87992cb9be75ecb1e246e0f72990000000000000000000000000000000000cf4a77292c2be26a87d3bf7307d25a1f77d961b0143de455c940f885f883f5af358440f133069a74d0edac76c0c8ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145397d8dc6523a66d3081398e9799e965c787564cee729636d9b883711576ae85cba0d9d326e1a13df8231dca7eaccf000000000000000000000000000000001490e2a58cf87d08201b662a8dd4945dad713708e976804644ecf4105b25e313ea041aa028eb4ecc58404adb169803f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001268ff3bcb8a780ef75049eb120af32678e220a51e19d8bf09ca680f69770c166d81c401edb00676482e4e14c0eebbe20000000000000000000000000000000007c3836b848f0f3177b13a6d7279a54999e8151eb02f687d676d7943b85bdb4171615a21075d1c3c1a264e09c0217b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145cbfecf805c405e70c17af105e0ce724218fba898a23346ab911be56f551d9fbc4e6d75445466dd0a68f7c0806fed000000000000000000000000000000000624882a3c7d8d9e09c438646d7725ea9f6f0cead1f87e5a118cd73668054793302b84a218d596b88046f57f2dc80e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013217272b0f15aab22edcf834b5eca759d83e2383c0fc0250e1b944dc74507570d0e18da1ea212d30e477cc648faea02000000000000000000000000000000000e50a2713ac88562596d7694034db5c0685c1e13052cd2226f2c7afa41e38c368a849bf12a393c7a50df9c0dc011eb1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004031ceb53b3f4bb8e8afb24a55eba83468a7da43c474d86c28df6857a8e667825a0d0204257690952e75cfe616d2e41000000000000000000000000000000000e0de19d901da10cc9fe49c4cd9fda32ff7588dac593e43e5b672ddc4d6c856e5ac467bb167fd70cb5e7f38d1dab694b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c533a89904e447c5a6999108f0da29d0fd6f2aebe77699f9c993c7b71cd5d79233ce4e83821ad19026a8d7acd31efd9000000000000000000000000000000000364da713f087808476fdcc327137e7e235669a89796b900360ce51b939b847c25f8dba57832a070d5f364ad522cfdf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037dc84e2c648dabfa90ec7f5c12f92b50b1e77eb986896a706fb249571bdf70dca2b2ed4a53e03b163652ba5f7d8cb800000000000000000000000000000000115ac87beed0b14a51da62e21a26a1d83fc824e6e291d102ebac2ba218235e8163e679bba80c4ab08901e9c52978c3571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001815c2dde829f569f1df0d5b7b29452866e783bf8e519d85c106e29c8d89e96fdb10a63b4df4147b7748cf5aedf0bfd00000000000000000000000000000000015ab8f2ea66c2d751f7f914cb0eac2ce2923a6fc612a5f93b197b692f501db2853028b1bfb76344f926603b83bbf000b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e36c68bc2bca54a4e3beb25401933b663e7599797c00b6d870fdeca9c4e1a4554c612568c37b24b3283020d3887323000000000000000000000000000000000b236c73422c4c69a74f5a8d7327bb73b422d7f4ca0866c7d67195afa5cef5ee122bee32045ea5c06f528b654409c4f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001157f02500f6aebd0a26a8fb4ba6bc9f05e761ad5dd8fa3ba177dbd208821e6a06938eef5841dfbb707dcfbf66aeac8e0000000000000000000000000000000018b9ff3d924eb50c376c6e15a0fa0b7383553fcc5ffe8c62df52256e206f497e5fad8c7d22717fe25dc8beeccb3fe21f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015c765d8aaa1a48ef97fd64fab9ec998bb9d58f2ac4addc628e517f88d50c5f2c7248ad7c0cc208fcb0d81b67be195f000000000000000000000000000000001752a28b5f00b7995354e14af907831bf47b591d8698abca0aafc2d13c2457f7a670dcf1aa869572c59fddf7913c31df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a1edf4baf0aa8cb4687e41d76b45d63c31825ab6ca398bfa93f2e4c8ee16ec551cd1d921ad7f32eb47f8747cd8b4b00000000000000000000000000000000012eb6350c10527702bf8e1087a5a518416ceab856b42176e3cb91a1ac10c414e97c0e26c62e739398d0121d68be98f441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c807fd50212c39028c4813f857a0d79b7a1991f1c1234d39d9faea31ff56f864e252d0bdc02699ee4a103cdef9771c00000000000000000000000000000000084a04e67d374e089ad70f1744d0f7d0b406da513f81bd902eff34172f631abd40d528f28d08e60d75b95610bee3dd521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd9a7e0634c87dade48af5d5fe8b412cd18ef5884791555e8c7578c2fc1a090158bfbc22fe79ba1f68e402b03f6aba0000000000000000000000000000000002862528ee1f242c165f4c27075df4e376366330b00706aae5670f44c89ad101f2dcfaf9c5cfb82f0582f5206f101db51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191b47e70106c153e3fbb1c5f357c87fb0354773cf68a7a2a7df9760b3566b2085991859fcf17685bc29f68b534d64440000000000000000000000000000000010fbdfa29ef21f220641470bd3e73d1688776fe8c5077a3823e573aff799fa4263a378e4acafbff41433c5fdb539763f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a0ad12870fe604e27a84c5fb23bbde6aaf57ae4de644ac9b559b1360827fbf99c85280e7eba1bf7a497f849c4a0780000000000000000000000000000000002509ff06932995092c9c7b9b026c08e69c81ba54dad2902fa5930d681b8eec4b7370c98aa4a42968f5f1e2ab17dd2571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b986c21282f87f2f14d2bb9166883c4399f96a72300b97a391c5eb1ab1d72cbe7c9a997122f8335ad1800ddf8f62e0f0000000000000000000000000000000000da13981618ca2f7bc9dc171f60e74ff57df21da80ec36493020d69075d8db8e9a91020757f7493003261991c633e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eca7d4d7313129ce4800576af1b697fdc4fbfa3a5913738c67d6d1b383f52901585db9691ce2821217d8eb2194d8307000000000000000000000000000000000312f82d57916cd0ae1e4da8faee30311da773b2e8e5fc880952aef367bbd56491811b6c6e01305a5c55b7edb7d6259b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001069a0f057410ff71abf433dd28d879fbc83d83777b963cace91ccb7d49497c2ab08e31d57f708d98568650c33abc0fe0000000000000000000000000000000005f01f7b0333297a3197722396e3d0b56edcc0e3caf393a602a71d8520fb86a9ee10c219f1bb193c0c04874848bfc9cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2edf6e6443c88fff071175530e1efdb48bbc951d24449b88fafc714d6faa4237d7777fb6b29cafc02cfbfd02bdb3da0000000000000000000000000000000017ee7ed5d203cf97240d0f0a1eea42036de179a54b61419a13cf6643b6556d3077ad1d532bc7535c5b66c70a87c86b4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000619be43458cc61aa6d06dd850a465c9a21f4527d4ba34660602750ef29a2c331fe083199f3caed0275a67cc89082cbb00000000000000000000000000000000127ea18a27643b8686643e889d11f712f352bb2ee224b2963fad34840f3eec0dee37d28e6169894c5c45adf99e5ce3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d7f15636e7ca9c016d82cbedef1bc35126d38bf8907640ff4e83133f6899ae6adc05830a0b02aaf608dca9e3f51f0000000000000000000000000000000000d43fe091ddc80f4d9f2506a9e4c1e75c7805a94e634bd18a267b1357e1fa9e0e4deb2969d7067db6280504551406d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9e0ea3e9660ac5ea57500cc5bf29fd424114e47f6807bafd1f17e924c947fb29155c041517f159ec4596d13f6862e4000000000000000000000000000000000d3be5e76cfc84d0d9b6efb08d4a99bbf1b58077b3619a0f194c30e1d35ee38272cd47ada08819ed94819ee90088dd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001828908d602186306ef8ce89cfb963f03381cd4c81d503a18518840025028ec7e1b8a8d386db3a38ccfd802ca1dcf98000000000000000000000000000000000d305699635b6db5a40b851617ecdc0b5817bfc44f8582582dc6ed6738e55625537935435507b310c3c4e81e5da008061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154ab34c4819decf5e23bb82cca28ce96663d0ed8b51e4ab95bb98e5ce8d9b398108f872b6e61cf8e33836f7560981c600000000000000000000000000000000105585801dfb130376bff41aead33aa29cbfc475240444ab433c46cff54feccdf7a0dabf1ac273151ad9cefe58e2d0771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128a800b0b2f19de244dfa3dc94790119c44b8fa6a3e4229615b537c89586e1d418a762fd342858ebe6de294d194ee0600000000000000000000000000000000057931bc8a3b17d8a120aeeb1b966e46d84039b998547d09485d8631ce773edce7557f9aea830864c2de8169aef7d67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001007f7600a3d4d66199457f1365f59495fae9201cab61752a094a7cff657772bfd62482de69221ca2636490b62a100d9000000000000000000000000000000000213a019ef9d7fec41304122079c33b7d0a5405aa42561426c39131714e44dbc0ff419feb2e5d26a92da93f1b232ecde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017010a3a78bbfd11e198f3843d88e430da71f413fb35962d9b36fa1a8a829fb9f47cab3bb9b4c5ef64025b40a8593d38000000000000000000000000000000000a127c02042f8e96d29751d4f8a4441be2c5bfb2054a4fa511bc06223aaf2fddb62a0ff5728b6f578d1b8ffc251d30fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c890f992614742590462417177bbdbc2e1a1273bba99181cf2959fea95d54d9f64d5b1136d34f62e401185aa245a2d00000000000000000000000000000000019d8c91b8569eeb2707c221b5bf9211daa1274cac523febe10b7c2a187d3d9f1afc6100e94226e9b5512586073e56bda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010866fb0c77bdab22c854211f853eded9a75b00a389b5cd0895af62ca46a67b74cef149260fd1b38f6d7b6a2417194bd0000000000000000000000000000000013bd86e8eec9d56c659e1e75ff788234f045d86887832ae702ce55240e2957dcb42fb5e2831a854ffeac5e056d420ad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cd04cd812ff178037846c102bf819a4c6abd1040b8f2da0720e790ae5e185895acd379013d9c8cda5eaa491dabb78a00000000000000000000000000000000015109df531c7b44a2f0bc1974e08a74d73544c5110278a862399866d1caf93161ad122a06931d31c572ae9fe3dcef591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001568e628441de2ee69238f1bb58695a8c55a8ae59d7f9d3f424c8c3007069134a9f65ec72c644d6c6d82790557378a400000000000000000000000000000000019fb7aa527b58f83180160977f946dc05a40ad0d46073488cfb0613921524c6eae4c6be89a103c043a0539773506ae301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ef11db3f4279f4be33887d7b6055c62a3ae0e7434e85955cb18243686478f709dc2b4cce44eec020a427bac4c74ed000000000000000000000000000000000b6eda2339e19782b7c6558d9ee1110b1061d904fc6b239eece067bbef122122e5c24e92ad8f90655240ba7827d1c5521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001836767c24d768cdb5240ac0f9b700dc389fa2cefe2b458d3bc99ce381a40bd8d65c0f179e6d3042e2a46e9a9f964f1100000000000000000000000000000000023548a51d397503267a767d7c7b9b590bd15c05b76c529a6a2994ad3d78e3539f8d1db2c080dabcc63d0c7a58276e5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd858559d6e083305f03ccaf363945aa0be4bd1381cc3bd09412becc37bce0b54e30e7278fc63c4c3a6914414faa65f0000000000000000000000000000000004de8fd554804adf28e775b975100cdc3c1db1566d7408c4dbb0b4401f3485a6171150f12fdaf5613f7a5f8187703e301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ce85e6e6cd40dcc83ac267549bc67e0d01001fc5af6175d5f97dba809f1e433c69c123ab71083089e2cdc88a88d32c000000000000000000000000000000000b08fd777f1f88fb30f1fc81a43a825da0cf8f983a94ddbdab75c42549e81d7662d4de1c2bee7bd74ca318e7b17a41f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000114895cb9f757500b7d5cc8ea6ad2b7dff13baa0943e25e42a5ae2769ce484f1fabcb58dfc1ae95820599ab7be718df0000000000000000000000000000000005bba7d46bfcf867e3d5dc6b84ca9c645c90318e7e1c47152a54639c733e86253fe68a1b2b663fa58fb24b8043829f291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012630ef0d437be224ad9bb9b9c567e3a4040799a4f69af73a9f503947cf23f6d5f567cd67f9ec634ed7a088ec02145780000000000000000000000000000000018c4dfc51c3ce162682d1009f7bf7123537efe4676a8a3dc08d79ee626bdf9a876bbea1b5bf39cdbad5f391f60f920851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc6f41294863036193eebeb3e8e5c06620e5888a86aabaf4569fc2eefead888aa17c9643f8b63785f809b7b5d34bba600000000000000000000000000000000016ab14e90cd13a4b2a586f9d34579ccd4aae3b026853915a03349984c3bd8f38f43b4cd4618382942db07dbb07160661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154ea69a7b8cec7219daa470c8d7f38a8668dd9446bcd8c084d014875cd04a04ee3667e36a55fb7501bde672244105fc000000000000000000000000000000001544a6ff55e51ab1cb89031f9028e89a6ac6d015dd686409c3913972fc207a72c3878fb1ea465f7f1b03cdaddfc8f4911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098878c9c736a5321f596d9873f0ca50dd859cae8056c19ee69b629419e5779f6bd45cef6993511bbbb68f40bdf2848600000000000000000000000000000000193103c5cdb3f7d5541b7b3b930ccd1b84a008addb6c0f726774f51207ed1f30680fc59311f70146014eb5f0756cb8eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ef09e8249af0e60c11e76d088671e2f6ac421e9ea0e9e5d4680be885171a698881cfbcc210550fd015222a6d4830a1000000000000000000000000000000000bcef87d0d39b8f828873c909ca31b682d2ace7e5f5744bbf5086801d0f3ae35e1e39266ec683b47668b6458640869b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016b25a4f3091cd3261d7de0027e49e91b8bbd6a464e3dd586a12f1dd77ab75b05e7d1de349cf47d545dbd77cb610eaa00000000000000000000000000000000055f3392c75a8c638a5146a6b001936bf6cc6d1dd39e8009d881ca30c7065595b5c75acb53a9dd72746a880aa06e43d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c229fb295e892fb5fe971d0ff5bc74cc36dfffe0f93d90701d057a43ecc4943e9c3e8ea744a983ee6f5ce49f8c4ae2000000000000000000000000000000000120195ccf1ee4e740e2a0d363aebb4dc36a48f623f70dd8702e2ec308e56f7c80c9f83d86083c7b366ba1e5356e6ecc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbc848e6d74cf58b9e3127cbd9a4aaefc8128fef7e9a43172a3c7522829e3b7fe3fd078a0ab849e2a1ed5b86d417d44000000000000000000000000000000000dcfa794e0f7ad565eac0e7b9f4992e8023471456d34b35dfa0dd8ccef832dd2eac3c9877d0d8a5880ee47577f71fff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143185db8b76f85ad930c40db60c7b92fbaa0e85dbf52fa6e526664b2f33d3a976ed4908d195506921a770d5319f386d0000000000000000000000000000000012b7556f604e32e720d012e274f19ad9a8f99a8204a2de33d99979f0b87fa8a11842b04c99276680815fe413a72470981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f316e66c849299386f00d8db861d9f36a751470700d4873134468401cb71930382ba6f1bdd311b07e9303d22a6a7200000000000000000000000000000000150a097559fb85c34728a9f0e778e4cf1c21e0c51a99f74440bced814f0e4374dfb91da4d54913060c78f9fb2e04d3011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c678fc32fa63b7a7dad518f16df22cfa0798ad21cd01004e0632bda4e90039f4227b5ad4073e926b9fddbc907961af0000000000000000000000000000000005a612500d21a7b4f9852e87052996b888818abdf4fe4465559e74b43164a74a1ad13988e2fff6a49910ba09fb80559a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4ad2a8aa1b661529fffcc23c3e68d5f3aa2ce7c2e396981bd9c4738c91d037856269e1a8c0a3c7b1d836b41ea26640000000000000000000000000000000010abbae874b42673f1f4ce0b12748947bc75b3f14d42676c24ad538845c3bce5bbaff7d5ea119c5f6be951ebb6638a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008175cb8e6134fcfaa4aa15f238e50488b7197afbbb8dd0670f4141d49ff7142dffa3779f8f5bbc9c8e460bd82855e97000000000000000000000000000000000a95fad49bf16d1378b2856f930877644fbfdc016834ec2c1b983592da9ad7ebd67ffd9c334f059f584b26e73afe36ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f869ea7cd4d94c006778223fb70e1ec9d0a87f0ee8b7c240b2dc4234bd01e20912cdcdb33f166a4d706132b394e5927000000000000000000000000000000000185304fde25c4f9859518c888dfa6caaf160b352cefe8c54b1e83b92d3a5489c876695a4c094eef4c9c24990eadaf3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066daa3c6dde4643f10d5862e3641b9aff43a03fc42846f51cc52a0ad325e4d68d9e83be1564c3865c5e8fc872a4e31c000000000000000000000000000000001614a8479a4338d804b785e3ace73e12ce2f04cb07ab493c336efcf78e9e2fe2fa0e35d0693876af10a40ddec21dcaf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012233db40a14d7811f6ecbaa6e24d11555747fac9cf2f36c88b72f44e4075352c511dfb73ac76a47545f342d4f84404c00000000000000000000000000000000122692bdc45fa1c0e8c3be22c9f91884efd19c9c76725e755c0225bcfa6e64f07383577fe69b87596066e18cb59fcd901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d994d57e90500a0884a73d4dabffc7df8aaab82d4585c9b58000f9a44a25560296206365de6944a6790276266ead2e0000000000000000000000000000000016aad68acaff53950f389709377f4f9e6d9409258a1eae4e29b04d094dc266b90288587d7c5b2388c642612b39abfe7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d7c713712fdf7ba3f6d20f522caf6419dd6a3ba43c4aeea8da0d0259f5a2f96a039b98b29d42947391520c2bd137f0000000000000000000000000000000004b2708fb0f84dd3d248073ec80d1e7fc6b6f3134dca5f8ed25a50a7ef73170e146c6c08fc4adc2f662a844d4c8e25861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c2e2d57cc7cec793571e27701bcacc7d3bde470ee8ddeeba0741d15fdac4011548d8afae9eed76a41286446155d40500000000000000000000000000000000195889feaeb2575fb1f663bbacfcc18acedb14df2645ac64a640df667235795817b726db68d69f5d0d63c85cc7cb82de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47827f5723d859693447bf7185ced38cff1ed839846c910a107a42e1a047fbe202e0cbab8844dca58f8d5266df111d00000000000000000000000000000000151f495648457ffcd1e7d7be2e180da1cd38808c1bf9d4aad310bd3486095df2051b99a25fb035fa90796f34b47e98701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aae260574bb6da71056c3c8a5d84200826b6a97abe867855182e8e6e53cbe19325502ded340269453292c3f762585620000000000000000000000000000000003cf6d453f059779c878c3a01d390c995d122bd80d5351092175742cdb4a1ff166f674c457f456518a47876a73d5dfef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ddea6f071371f56a4b2dde2d2f8219cd27216a569de21360824111fcf24f3457ec8e6aa2067811819897e9def6fb7200000000000000000000000000000000121d3a14f0790b17b0c968340ab83b1d784d2c48b09c779ac250d6c269299be964f277d6c66ed59c068adcae41c6ff941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099234473ca20260b0398b2f5ee78c2239436926539c448b43422a0384caae2b334cccc008076c07e9de60e4127eec350000000000000000000000000000000012aac764870bbf5e184823bdd565a27571ef67c46cceb8acd28038abdf3a420366c6736fb225243ab7485ebf52cec86a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6766f7a792838d01dc24e54b65a6da5e052c786d04950800e04e82f6efccddfe911653c9344b61998cafa905b54dae0000000000000000000000000000000018eaee2ceb76ce13300c9f0feff94c55bd7045a53bbe885641664ddba9fe816d6cafb96434019bf5328acf3a337c13741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eebf62e09bfc901443082876fd3cf07bb8c53c0a9aec1eec96cf001f27c856a379e659a85dc9d3f24e12c334347990000000000000000000000000000000005f658ea599eaed57a0e7938399feb863108de0a1f3cac41f432c0fe3300bab4b6bf2f846f3dba035ebca8fe0fea68b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001493580df4755e68bdba31105f2ff22b975b84d1187cbb40c2de99e02be61e78d629d29476b0a2d5cbf2cc0bf3f0829c0000000000000000000000000000000006d2f4206a52f8b1c84e2050a84b98746ff613d3dc3d5273a7d7bee924d343bc760b85b80140393fcfa8085980fa8e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4492c3209920dfb86c1406616ea4919fd725ee4a3f6f8457db5495ac3a225a9d522a46e0d13973adf51f8af3c01707000000000000000000000000000000001252873b9fd0639be7f39cdc8a79701842d3110e4339fb2447e7fcc39c78059bd116c4da60a3a54a57b4dec0a59870481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b3dead7f62ab4c21aee71e55b020c8314bc24a325d8e71da810f706324201f4c96f99d572f118c29d9664852fe664d00000000000000000000000000000000085de1c80296a4a56103c5c47afd9160023e71cdf47426fa26ce7faadc802f4b776412dc4b3af445a13a1de6a4f8fc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013432280dabcb187702a74039f51dec08d36f4856670f7df1c55b9edc0fb091f6956a4785d641c3d39afaef155803ce000000000000000000000000000000000948a4aec824e5219a67bb281f9f907e143e279758597c14ec0e2b3ee9fe1ec9d0ace4bd4cf16ec4e0f75fdbe6e8892f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035c5ffc3596c329582a89967e8c06639b9806b5f741e8cfd2ee13b806906e01742772130f5670ac21af059ef796c177000000000000000000000000000000001028fe8e131bacde6b81cd04f23aab71af6b8885c82e609bb285a8227e11846ba84024fdf99a2f3deaf2f6384d1631021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001875041f25a3300503986e7e0ce56398aa7ced078b229b30886ac544a3f874a22202d4ea91051b50c1de44744876236d0000000000000000000000000000000018c89626221d6ef6e87a40839ab4290306da65fa3ea9838cc0043a151d8cfd09e6ddaa9fc2f0b1e26be6a15ecec31a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8b148fc49ffee4b2239cbf62b55cc7047d6632f2b4ca3e49d7e141fd6a752b2ef24db0850d5ee001df02d32917b2300000000000000000000000000000000077f46d2e90eb6343cd42750b8149a8c530f04bbbd6a3cadd6272ed1ac135bffb7f809388191e04f0517e9a2a2cf6b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001886c741014fa20892453ff11cf4ab340833fd11de79f9f1cd637be12567286b1b7ec1316ab059285dff91e6119b83530000000000000000000000000000000002b5a460276425f38083a161bf429de8824d5d7e6490876595c2ed8860e40732d6c14ea5ca2b12a56c64c1054b4651ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb73ff0e856603f9fd7df55f376ba70bf4d907a29515f5ead5c6a4b07f4e5b923b8a78418d4187fd76778a03475710000000000000000000000000000000000495ee67bebe4fb0ad67dd591c05cf52f983ea6337ef981fc2bcbba94af3a07f10e72651158d01704a54218d7c7d70591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b1a3a01e8ea884762181a21e6d60b8043f30d983d32fe9bc7c4d1626a3881c29ac53f18e0f96953f6fb08b2d245674000000000000000000000000000000000d3574de3d835207863a04ee677559ff0dec0f6ef6fd1017c2e92614670f6a675794df2ae69e6a7dca46033961dd3f2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000930375014bd014ed2041793ec4c9624da85ff3c175cd4c24ff681f0d98d717a6033b2f9a568d483c8c45295278c283500000000000000000000000000000000074ea0c9de9f5bac5eb796f43f09ac55c127199da97cd3c10e115b8ff7132b2f58457e26c2686a4d312e9073d808b7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffb3c93d9a328c17176e83e9b713c5571ef4623515caa1ef14996c61fa1958dd823c149c54063d81356c80851f976c10000000000000000000000000000000007fc21ce2a49e6212d06ee39346a182234d870dee57b561a1695c1ad6971270084d760610368b3b1f365ed0d829e3a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca4d580bb1a6a1ad9fcf2947056f1e8bcfc468532bf22a614dac94f5791f9cd8db4ea371a3c7d896158d7e4c0b0a7ec0000000000000000000000000000000003bb0a5586ace18cee632a266f92f80eaaf41d9157ce11fb709a0f6dce067bf786649394291414d8ed01058e0263804e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012105eba9cc0d1781c546d89d8e0c36aaee958837d78b00a57afb00fef1e962afe7367be0c66ff963cbe5d2252f4a4060000000000000000000000000000000015a23392ba36cf75ad14d9cf6e16eadb52c4ea83b3c7e668bd50c1c08eabebd0b46f47d37f48ca2dd80feba83ae7abbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3568497080900aee6088fc2c1a15e81936d4379ab1a9e93f9056b0c9f1c9b494e41f0f3630556f6ab63ae542d8321a0000000000000000000000000000000011d974c8d02a8a92364d66049e9e49fd4a81faef328cfbf4b471d6fde8a397b50e55d040059f493944134e33889c76231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108939de8775999e594fa333f249b2508db217a0359b6ef1913f2b7e8eb7de4d125f41400a0e42451e63c63bc8fa2f3a00000000000000000000000000000000181097890c21da497449c563a6b79658f92057d3341bfbf0348af59a86c6250592cb913418067d80b4f9966ea03916b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78dafc7e44571c92889f1290817e9deb13fca0befba6d10142d02d5eaf83435127c35c9c0883d8921be43d8bb1bc330000000000000000000000000000000013ec88b3a5c989cce81e016396f74a3e36938ba26502f0566361af474918f8a9ec29a0e3ee8ac04b2235dd380789e2bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28f5d968e7d53dbfa2d05bf017bf4effff65477afb47fc7fe77a402eafa3a199d04f5a9ef5d3441a5da0e9b201c27a0000000000000000000000000000000000d76e939ad10ae63441193699f1ab63876fb06eb9b1fc9a825a3aa3dab34864513bd8a0d1d2fab7e5238498000f71761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000138d6ef41385e1d5bc36821a7793e048a435bd8937cd7c1105b58d406a1783a988547ab4a0a7468e022dfc388eba4f6000000000000000000000000000000000f2daffe9319a4ff8a0f576fe616e160622c1f388b5bf3952f707225243482c0f3583709d8f58b73cd0e8ad0eb0cbae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0aa5ca109ed4e94f2797202b16b62a988ad36556facbfe8fd4dfb9d487e055d67d456eb4542e29b5dada1d465e602800000000000000000000000000000000004607f9ca1ad5fc1698046a1160564ac6787fe944eb7d689d440a49461b67cf9e4f6cbb2d9a7c0f0d50c5153fa792e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018db9f7ddbeb66de80b4c09f7f84892f426003e5461f3b5607b0fd9ac3bc2565403ae59e0f1505c404f44dc07f2f8dcf000000000000000000000000000000000ace3a9b7fab0f174d8358ed3c937da075c41024fc14a68de172f03b1ecbe0054da269c3258462f595795db1e2879dfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b886483d9b0c17899ab7803271308dc30749b57b536ea41377e903b9f59bb072da4d3837fbba18750403de69a0cabd6000000000000000000000000000000000f44967c5b5b5aff09b48765817aeeedb150b2fac543d63d308ed1e290703f10fc8c3ce3033aeecbe54a10bfa0faa0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7219b83db0f9fe6d54bc20ea95b22ccc6b9b0d4fab1d9a1ad77755d6f6e5eb2027139e900d6c4a43ec5e4d81516556000000000000000000000000000000000453587fe3772ee344c90e8beb40f1a6ff512d83ba8afb89b4cd7ed0e2edf2d9a5f09f9dee3902eeb89552354fd33fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e079fbbbdce1c4b6916cd4e286a7546d7d48e2addbc476214cd6d73b8fc7b9e8ef9814222c173b47bf99e5793eceef000000000000000000000000000000000c36cb0b1d61103aee3ba4302c74dc39eb9746ca547aa864176cf555431c2f84c7d89b6b5b91def85bb5c78dd0626da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c13ad4792dd1a367294b6e23ef25bf40c24541708a0aa8732e3e00d3110cacd4ccebc302053a195b6a939af3cb01a30000000000000000000000000000000016e6149eba722cdfb5d093ab07fce6ef56d6905ca701bcd3ea5573016be73d55d02ad45ea8f291a1217509097f0d03951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cef392b1866ee3859cbb6c0984a0f1daf8be64b10ba8df55917b56649634ea6429746110c2279ccf7a6620e529a9f900000000000000000000000000000000002841bb1ec89a8174a530a5be548c5b17f49d28c3abf5ef2fbdace53b26c57f86843611508d3c6f4a26fb4c9ba3d6a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000302211e4f02f5e66d923a1d0099c47d5cbd4a52cc46978e3e159f93434187a88778b8bf6f9ad5209d311184596cd805000000000000000000000000000000000a4130c234052eb553d08b9e8fd5cd3b89a3ec4ab4effe73fec180b807c27cb83a5e8185008994524fdeebce1ef1db571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189e798158758e16e400d73e83c86ee246f7a96850a966a823910f768b043e119cf29bdc1ebf84f11a1c4f4cfc05cb6300000000000000000000000000000000081f772839b0cf02a5e6bf99b72f38e97db853dff6f8db59875c72c08a4228e3083477c86bff5ff1c168375e36c73dd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a4ce739ca82b934419642a96188df95080a5f292b2328a33508aab93df98cc3be4af12bb94df30e1411b8bb73905170000000000000000000000000000000015d55141c4d00b23c8b349bea0d27b74097e15637dd984b3bc8937e2dc5f984e2cc268009c22acbd04e56caf36062b781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9342387c9f761bd6898c0af02588b8d7818e0b2a03202555ef22dbdc4714220f96faf3243ced0f8919ccbc449ddb510000000000000000000000000000000016370ca022f1ea2bcfae1d889ac7e2ce2bfbfd95d86595b4080ec4bb2be3700b15895206efc5c68dbb6fc9bd4f81b6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000435bf7116b62f44a6d85e355b71c3660272fb74aef730f85386bfb38c11b2084d9e72d76863be7fcebf368746df5c0b000000000000000000000000000000000a9f6b1de627a140fe2a8ad7dc21ea25f0a21f528527a48ea961262d609fbd1af60f47931b95236d693141bd6790022a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000530acc675d5c9bd8d592d982af64af7e60a72788e930581cb7293258db1646a4c1ff7c2ccbcff5f606b3fcda4d246ee0000000000000000000000000000000001f7f8bcf4c62cc47de86ce3648b73a7f50bf86db8c2bafaaaae8dd50889428b2ef92dc1f5a1151b3d146b98832f1b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198e840576e44e2338d6ae9928bb4a3c4aea152cae033e221be9720444593f68857b4bbf810b3e16ebac64fcae3fbaa80000000000000000000000000000000017b188bdfc6e4ff1e46fbcaa9af3e1f5c397dd8718a1a2a71ca3c8fba2283335f894bcced59f00d7d97837673a8eca961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e8f8d4cd7ef39895df1f5a1bd3116c25731af66ebf6784ae944a7f0adb6dd420214f93b2d3533f9d3f5c089925bb50000000000000000000000000000000014a43754ad5a364fbc16c04e252a8122f079c224a06921399d400c1bfa47905cb532161aaf834da2cf424623ed328b1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eb791c11d3c4e9259fce002dce0d8c065d777d3a00f6e36a86f734272fa230bf87553e1a805dbeea2124b9d7a4c1ba0000000000000000000000000000000006e16bf7d0e5879c276ad0362e2129281520ec9acc0931bf87f90470fd0d8ca71a75954ec6b8411acb5bf478dac63d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3c008c7bd09f84f9d2e27bbd0ca37a90b4c46023336e22a2f7acd102f1c5c39c61af890cc4b52fc269919b37decdf0000000000000000000000000000000001ed0a323bcada851055acfe683ceb61a05561c12acba4a04f4965a87d07a7ff0b09c35127254a015a8244a39cc3cfc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001243efe3b1f4b9045ce819cb5f05959a629613fde94f21543b68a38c19f478d16b528bd0440e9e952318a6c5bbc4c8ef00000000000000000000000000000000065e968481d8cefe1073f66c80c43a013fd48358e9ff8b2b4fcff50f494169b3b66a2a7f60f281768db5a6292882f3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031a84a336ced048687ebadb75b8c3a199a59e0ad7870c707257b6f3936692235316149106cf706c22fea2fb2dcedbdd00000000000000000000000000000000022d3239fad8fe21adb726dd748b110be09b7fad304fe70b731b9d0c4701b2816992657d5d78e42b484b75a497ee13ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fae5177baad7c4463b6e07a1c1fba7b945d1127b3b3f4e8b20d6977e3adce7c5046424d3e44cce3388c2ceb968e8a00000000000000000000000000000000017f62e94a394e063907298f58ff135fbb741903f2129f40e8ca193f1534b845fe9c9a6f1327a070cc19d71f7a69f5121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd59365a6b49323ba5f8aad6793cffe739ad7ae9b37f65624d2432d7aef2b243063f57094de3dc2f930c1438a3b3254000000000000000000000000000000000299afc35f82281d20db13c62284b66890df7fd76f6c73366c3f076de7c4b4d9c83248e0020e0ab216e4f5bba5a340821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112b890a18520f0b96e61569eb0969705e9833286a4490ecc7074d0195391ee90015c65af09d3f4ebe71b99ed692324500000000000000000000000000000000189c003954a811838e6a270a8853f9dc8d3a677d3c8193fd9689689177fbd33ac17fa299d23b94c9088575f419da0fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c9125f565cdb09ef1d87bcb296c6ca017f7002bc22e85fd9af04c610aac0f6de16cc2b3963aa25f01f3fd3c78d584000000000000000000000000000000000c637e6be49818ef5f5e437bcb4df33868c1f1873f802f52fff10ece9c4728cf0fc2330a6e0afe39a168128a8b1ed4551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c666645475545a5bc6c26156af5a63453538041151ec7e2081c37d9392ca650a8137e974c4d83b29893622f674d5190000000000000000000000000000000011b6d50f414b4e1ea7eef5106f7be76936b0e0b5248064bccf910171bb9ee8778d0f4167cd109c720852181900d8e60c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa96499d1882318fcc1d0f3416edfa957083ed9a513f14beb05ea569e2b89487663c41d1040a55bf2262ddb2054e26d000000000000000000000000000000001383c4ce3b72da8cb914494d7e22e449d395d1479d498fa4a19e4b4ecc7443096d4e74a51dbbc6ac4acce55498b241ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160276faf62d4a300626f8e02715fa8c910f8994ef90bb5e38062732dc86f551b88cc05c30cf4bee73e57d7307b504920000000000000000000000000000000013d0c622a654180e5d6e81555605926c98f5d49da6fd633ab09dba5c2bb89b21857c6b1baa7aa6b203495db441cbd2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001393b7b9c61a6839e421bc9ea04e58caf8937d5afd265c1bbd42cebff6c532efb98862063c9a687166b14e0fe5a4f990000000000000000000000000000000004c68038b8713950c0cabbfbae7e3c339fbae54103aa837ac76de8f90fb796cec3f19a3b744aa966d62b38f493b54bbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006690665c09bb093f55c468e244e68416ddf174a876e928f62524822b345ea2e63a5e32f15919d62d86692ef1b552323000000000000000000000000000000000757039336f92fcbf0598b48e2b6a85acfaac756665dfe2fe5687cd69da931aef0a8feed3a1646eb1000fd64d547340b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ef527aa052e67b3b76703f9d34dde85df8c310760500ce21811e388e3df6ebdd531e233b8eeb5a95a797b0d30965f2000000000000000000000000000000000588cf8566df35e3862dbaf9a1d25567992bab182a99064b8fd713f9ae539dec3cdc653dae0cb75b710db0a9b6b01d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8161373f08de661ec53ab6f8abed34a168420c8e4587e9d51e62b41cb43335ece586ebd0dea13ee508e45ceeb1153f000000000000000000000000000000001352548009c573b6541d01be109f3c1bf7fd99be74465ad82e6e36049f73b2c290ce8ccdd069ae60fc3a644a767ed0021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aaecbd2a4ec8a5b1e0c49bc8a69c4dfcfee1d755ed527f9a7b41f845becf144d42650fbc44a50533fdb801a53ef5720000000000000000000000000000000011c4361c94154abd6e59e6356b68b78e1089d86e802d5827af9a30181c47e0101edc36b51340c4577838300042952b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a51545c855d0610fcf4bab6f3e57be705797bfb5f475d1acc6f55ae5e298b027a8bcef24654240835117947ce56590000000000000000000000000000000001c2acd076537cedf746d080287f561d8a6dfaab226e1a34a4843a16f59e9075c95d1613fab052bad6ea1e2a5ea744311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2cd413075677ec340d96d5a15b2eb37010b3691f07e1feb32c75d3491d5e4c3220209b452fda419dcc0fdde3fefe480000000000000000000000000000000003955d42a6268c6a02b10b763816f404aad938f82479db3df7681a7baa4e57cd7c3a5aebbb5b899b3217b93b734820c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2d5e66ef50c59f164a93764f2462001c0a23733e83bfc7dae7ec123eddad518cd0562fc2f724c55a5617d531bd8e830000000000000000000000000000000018c4741589637af91f8bfef16a0987a6941190b80383e52f7eae196632e8228e86430ac1d1ddb8985e430e04ef7b70f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea1753ae659f01a619056f112a9d0608e39d5929ec158ec75a2450adb8744e305cdb18cd7fb104f0b264b27309f6338000000000000000000000000000000000bdd2554c0540bc39a4e6fca09423c5685b4639bb038b4c4bee83997a69c21e9803c3c8b39cf859fc9c2af47dd8517d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ffc536e194e4cfaa1cd1d1fbad846f0dcd9c3ed3c01598d9eb747bac7d8015a905fd07ca6199434c75ce4f13965fc9000000000000000000000000000000001188472f0a0c4d95a118d680f8086dcb2ce712b6eae605aea66384f690f74a68d0bc295d595cded6348c226ad3a041a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000315216fc29f6cdc99efe569436813eb4d6c87f6ca03da211db92d116ece0f7a80dc18b353e036c52b204179f54b36e1000000000000000000000000000000000fc21011f2c45332a5c6368a0fa53ca5f8fbc56275fe17567416ffe2ddba2508442203d0b65838a732975a04173d968b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015503871cc7a2816ec3fd76d8023dd4107b4f9e2e29d8549181883c9ba143426a35f33879e2d0ba8c4348abe1fef737f000000000000000000000000000000001540f751e970df1decd8b52283648abf103d94923240b78b0fce876a0a1d1868e61d2a72b67f09c3478e258afb7b48c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b6f046c2849a9c77955582720f780e57ed48c1b3fdf07c35d980dbb1ab457d3a304363dd81911b52433d90eafd710000000000000000000000000000000000d295e43978262168226810b1ad87e8aa797633068b6352716cde81463f80c550b6f6663bb23769faa15072cc4b6dee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a2535c1f365c36f4d1bfd0de2fc722f1bdf4b0b37234764cf10391b28e346b3d94e8a54b52b1cf6be2e07a11fc987000000000000000000000000000000000fe3e4ff1fe36fd8d4db31e73159ac147224f544a434a1007e2f76822b4cf2ae3e6c0da66a2f20697518c2cfc84dc80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f0ec7e98e5beb1bc39e6f2cbbcd03924534e55d815f164ec25c0bcf709433c14d367b6aaf658f7ee3a8799583632a3000000000000000000000000000000000a882ae00b1e77e44542540452201e413792d0b3ede3b6d983a8d5c7084dea307fd1f095e4e98f1b6b598567f6f7db871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cca4d54e31926d6ff0a1c1b5f8b8e70898ed901a77e911f65c466ebd1b03e49fb27a503b34c754e31e175aeade61160000000000000000000000000000000000ed720f7031dd9659146d7c9854fefa8569d5d447a70c4941d56aefcd1e477c262dc0d47ee4120d652b35442294ea9da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134989020f041cc6192499089d6ba5a4f5b5621a85631533431dc5ff56a2b51cbf90d8545e1f2b32dbd4b13d7a6a0079000000000000000000000000000000000354bf2e9ff71b817586c69048857e0a3b2da7969cfd4545341dc87106fa33e341c23f93d5b5b44deba1d36b107fad861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035ffbfd73190e458f0bdd1e318fd976ba5fcd4417a90cd6378d252967bacb173b2246d140742ecf6a02bcfb85b2e953000000000000000000000000000000001093a9b1d945f8ae1b90ae397fad6e80994ccdd7b7618e93c651b4beca2c1d6e76bf9153cc783957ffce742dd72f47051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d335dfc7bcbce3b175ae7a1c02bff38917fc0ad4bef773ea8b99fcc3925bf15b6eead654c7849e6b75151b83de901e000000000000000000000000000000000bb724ab3bc1f433e57cbc0881d3cb96bed801f4385b66dd22b4cda1de5e544a0d328ecd64ff11cc3bad82de8b02d63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9b25915cb62750b212a172f77e6dfa372bf7db342033dae59e36ff777482e2695c94e640e1081f63bba6daf3c9dee000000000000000000000000000000001587affab814b03af684eca5e7d559423a3b7515085c0fa2b404c2b87884f239eefabef0da6f8aadfb6579394d4bdba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c97e6b8081c0e0921e353b8ee53bc64b5c99a1268b1379c38c47618b5d4499bf44b8ea8a87f439817041c5790b65c000000000000000000000000000000000013572c1726698694d23f0359b8db9a306592a3ef2f80485e1441b7affbfb9c8e7034992fe5bb911d68cd552c25e390d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e46a966b89db8a14e7aa4249acd0da1d7888adc3530b1b6618f477fc98e1cd053c01485b4dc6238e1c573cc026bdc70000000000000000000000000000000004cff853ec6760ee594be1be1a3c2751b8b6ae0fe10c277109dfb2db019088a18a7a927d05b7a5f164b808aa9fb9d7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8ec641b6322e04124af0effa1a7e291d9d907777a9237184672369fb6554bc5bdc517d40dd447dc594c498f99d75040000000000000000000000000000000008c9bcb5d03a21873066e2459db0c7d209d05b761e788baae5a6aabaffad97c410b6efb9fa51d2dae32ec1ca10bc00531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a98ac2abad8cd8e720332d4e9c6d3687471262baaf2d6ea152b3c1e406a0b5b2204b7a69aecc4934349761846e73b2000000000000000000000000000000000c22c304c66271daac8761383a260140849818d99dc12ca454c01852b80ec96272fdd8b4b251fb76c56a56c5630af8b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9a45f32d9f063f4cec240b142ef27ae2a67e1c621f333848d1ab5c5a09db76bfa2008db9c9f860c3fc1907393d931d0000000000000000000000000000000006d44ae844e7b3d0fae574ad8f2f02920b8a62075b6f95fd147ce34771624f170481466efdf3fee3d17e9fb6c997362b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119dbdb18713f74b168bbab079a88051c2218ce51cfd459e169896cf414d521b146d0e364137a56113b390d1410f9dcc000000000000000000000000000000000f0f7d93357e0b25ce19e07f55c04f6fbef2ce6868cbff9ab299cd501f9561398cc4d2d6b650afbf6beba6104c6aca0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523c20ccc082ef4bbb749377533fe5780199b9553f8d73400b1db6f8c0004377395568f68553f8b35c2cfbf24ce2b560000000000000000000000000000000011929b67b69dfd2ec08a29f8b55c464ccb3ed4d733cca8f0a4fa529fc2e1901e0eae5995eca0adaa3265d50c1c6036c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117f557fd51fafa95eb1a94222b1824582814f0e7e2d32fce81a75453afa515d13921ccf490a84a6820e3d2a9cdb8ac200000000000000000000000000000000100ec56b1379252134438909d27c2e9f7a5eeae278d55395193b6ecd07008cbef1e5fe5b3a09fcc6f0923d9c3a7ee1ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa122f31d2364372c50429abe448583299811cb4412417210cc7df29edeaeb8a112764c37d2c72a87641c357c08e22000000000000000000000000000000000144f778b78658118bbbfec1669c79ac2a1197cc1670c2940a425480963bd92b6480f24ecf1010bd9ab297d04874638981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000220cd8335080d027b450f0cfa7e18dc37c000c97d78ef3e959959b4a1fb7b542112c8c77d90b3101c91421bd3236cb10000000000000000000000000000000019ee1dcbadfdac26a4a41d9b2b5e31297783885bab7582e53d612206a5d9dfdaceb38dfebd0ec6e29b52c2b49cfa2a321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006854471e372695b228c641f9f55507351ca471fe66d1ff9f4bbe079fb95cfb2e6093a621c078ee149cf9a335469c8230000000000000000000000000000000003168b241317420146ba9489ccb8c819b8f4375511059dc042f2d177461b142c4bd666216ed86b10290fc18f7f9878661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ea95c1d37163cd6cfaf0d5f1deae73f9c912b3d2e123ed35957624d71bbfcdf166f016108d0e0451e812f24448532d0000000000000000000000000000000011dfec476c8f20c0e574b2b1fd159b7ce21287aeef5c7f6995e25c51bd9954d4b9c091a6f826c8a4be92eede2bd165001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169c46fb292c189e65a47b312b76261bf36cac0ca3be5541c7798f23334911ebc88d9fd6277c3f1f2a16d82757519f5e0000000000000000000000000000000012fe623fed785fa8e9de9a45f65e055895f7db2380224b467190aa81f74e4074fc3d7ba8ac91f8fb85d3953767c6c6df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150e9b314d3a0ac3a1be87ba743932f984a09b78e5f9db632cdfec067fe4b0ade871840f8f0297c4c7a1e599581ee21d0000000000000000000000000000000019a1c96cff130fe123d8d1498066b880daaef5ab5fea097d16b5584c66ef3c5c0ec1fb4789c728fa4ec2a596ebcf23db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3ad2bf12863cfdb696fb44ada6cc5b8a76aaa7efb66b3c39c0aa371e5d45cf3e5ff7305dc70803a8c4bf25def54a1000000000000000000000000000000001640e7d48ea4e0b3e0cc4340f1dfbe1db3a2065ac0617bbff62b941956ef8dc5d4bcb83ba5f8b0b5c1dc258a92c724191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083835d05a95852733263802f6c7beb1beccd9b9fc94ddaef6f6b1a2c670fc96e599663e626d57ab8573eedd38611f320000000000000000000000000000000009c36872ecc565313208797e99e7e5aa5f272b53665bb01b9a82b4d6ffb2ce0be81e1d26aff58437afb54742486eee6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527f321d4c62001efa64b356c3b2d7b0e28da7844ca9bf9cb96a1d2fbbace50718535f9d18eb66b61b483afeba5898e0000000000000000000000000000000008dee026c050b186a08edf39e79fa108946926550baedbbfc71641f87b8d452dfadc8580b200c1941283afb17792652f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db9a07e76d35265ccc8cd257a7098f8bda290541dd420cc82883f2079b89ed79712e7349889778b6cef5dfd3d13ee9d0000000000000000000000000000000002905cc4e47ac7f7843e581935fa5d5d3d8488fb53eaab120ff93ca98972c56e51b47c792f6cf4e510dffb1dbd7086b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e7f4c53658c0d3534d2c11821fd428803e0f11b0a680c58bc88eee4bace3092ae4b417a794f05eaef8ef0102b031d20000000000000000000000000000000012e78906fe742ec2dfc08f9791f2b674a7ad060bc49d763782f4d1cb0271b8e98c45e0babcde47afc166173b67620a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267484a1a4f12be6b6141604df89ae1162337b592565d461f53bc3b2f741e126f172d183fae70001866bc8566979b70000000000000000000000000000000000e9a61d04bee149e09204a63e751f56609235edbfb68f6652b10b7b29344dff1349c285b921386376edac6693bbdafbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097cbbb3c01cbc448425fd69fe78f8593743e3847c876b14b4807e99e3f309ee8bcc23a866cfdb7f9847a95b3a125959000000000000000000000000000000001500cc80dd5cb23a6d15198e824c48e21609b6946c291d5df64a73dccff0488576f7afa5868592176f43b2cb1b10659b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050548709c01b1fe2db24e2ea82cf86b96aa4ca0ec9667177ca02d270801ff2e43ca3d4e975646d615182e647621d33d000000000000000000000000000000000836c31d07fe2cbcd2e1b4fc3e420f30333b47ded8cfb54e0743a79c74b4111f52f97b9d2eebc7a7aba72a6c8f8e4d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d1f7093308d01b329cc41b58c1076477ba633cdf98e8149daa04aaee9223c35224b9af8012bec80747f55807f1521e000000000000000000000000000000000787045ceaf5e1b4b88baf8a52879e864e8f45334659e759924182536742d065d0996bceb2caeaf21960e84d359923471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152486a4410c3fea665c1144e76b770c87cf71b2bbbac1b620168aeda3d77d62a1b18634a52d0723ba4567b332bca71e0000000000000000000000000000000002aca801c4b02b2e271be6d9ce8a14ea7c0d408e25b4196b48e9110dd6a33b6286248bcab75e8154ccc04c1d129084491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000137a03c96936f51837af098d5056a03edb8ff8a860cd190898df169ee03e9205a0a6fcb0ba148465a233d7c14fb22e600000000000000000000000000000000115dc35f0c7fdae3035612f4575da177729166b2fbcf96ef1180f6a016467d1d084916bc74f5a5d6c20dd0dd79c7b6721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bfce31f7548cce1b28bd18f9ebf9cd4c836a21cbacec66980e246bb5a273acb336953a89f78bd439975443a32a4b310000000000000000000000000000000013a1e301c807025d71a01d7871d1aced1be0bcda89ba469e0c0dae5ac774d18ca810dfd0d7daa670dabd74aa65671a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a530f0de0e981338a062583916942615f97eec6ac86e5280eb1a805017d0fbfd5e36ee29f24ef32f6da394e8c9eea780000000000000000000000000000000003c1563875945f7d13cb66ca1b97db02bd86c2e4ff0415978e416969441b59bc70431b97b69e7babcf03a19e5dbee1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b9b8e3e7005114038b0f993feca08b4792f327270db58047488d0623fabac9ace3607ee678212529ac1ad8c30999850000000000000000000000000000000010baa9583f68adea3f36cc2200220f789820266c73eb71c0969bf2bd3f7817ab02e87d6d8dd036de1dad5c40cbf91aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008338aab668ec52fd250463034ce8be30356b0794e7a774e306303e0a0703be239ed2426010f1b99c674605b6dac42e1000000000000000000000000000000000baf0ee84da8bd17e0ff1a536b85b657374af0c2243e63392ddb4cc24aa399cb42cd089281ddd469b6b3db9869aef2461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d68a480eb0b93dc2698b6446606a05c4baf90e63de0d66932850ec8478759585626dcb4839603e64fef5ba05acb5ae70000000000000000000000000000000005ec3c3ee1ff2c2c4c5d2df8260b46c5b2aeae710a1878e8e8d0014360707158eaf7e31124e8716b1bebe5b862b8fe651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184da928dd10e414f72d6afa28d9375fd364617e1472c8cf118422e89b116e6b11e256af9ff45d750fcc3c132fe6a42a0000000000000000000000000000000002babd65b08448cd63e62b5638285d84eedb936e5d9759aad8bfbb60d5f6bd23f92126d394832172b93a8239a035a9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001087b609ceddb89606ac4628511e2d98d47ca3f68608091b0f3c1dfa7ce8963301e3c23e20d083ce4436d28cbe3095f2000000000000000000000000000000000b2939b319d698287a40cc7e143c79653cede3fada316e375c47282b59128abe8a1b0b5c14484a8c841dfdac7ffeb56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187a4168234cc1e9bf9485be5b0e44213a0619895abb513e2c6870ab242aa4297d48e5236ddc10a42fe02aaf304d16570000000000000000000000000000000009bece883d740b42755a84aa6b875284a24e03f9536390126fc5446adfe5e471652571c3a3f44b84283574157c64757f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103bd13a9c1e2f18da2cb53f41e21012ef3e273e90fd59ccbcd1f29e1d8b519754fcb20e327c30717253a980e65d9ed70000000000000000000000000000000004bbdd5a8d82a22e3dcee5b564cecc86a27ffe8bfccd9afeece9a4ebe6a200a4f37388d0474e4b837efa40bfb3b3b2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f23c45ff324926d487219f736d132dda2e598c93d37ca89fbbf06a45ec39dc55bfefc06462196092e8d9c91d24fbb4000000000000000000000000000000000bd76fe0aafc50ad2f2b3eaefa83b471212393bbe42fa3686280f14aa08d1efd915eac7a91f9df5444032aff9075c6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b00497a6b27d85e36e60ecfb58a0cb3bef3da9f7c9c406fda6a340fcc53521b6a306c7685ac7226b40b3a67d1639f72000000000000000000000000000000000d6d753b57f88e43f18ccf4e170c2208dbad68d427d6524a04f8c437026c60f2e6d7e01d1347d2d5ca956bf2e4d7617e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a4beb361e648dda6728a8bb09cde1a650ba64a9113a6e98f8837111d217b47cc7cefd22ff324fde9a000d0fe7649bd000000000000000000000000000000000252ca803bdfd92b50bfb17dccc81141357f6eaff1db8c012631ba8703a40d159e6fefca388de757f185177d408ee53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176eb51de414c3f20c44fc47dad4f455dbfd38d390aa0dbef462cf63cccfa5e9fe16658bdfe2f1ef8cefabde40d58e230000000000000000000000000000000002e934a56acea15f810ce5ee1cb43ba509d580b1c1006edfbadb374bc7945e96ae36e3f0a3014e68dc863feddd9ea1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e35615506a516c79ea132384f44f7248295e7488b6ebe876c1f0b2c643a6b4391d1d147e24f0402e7a9642d50486a00000000000000000000000000000000077dcc7378977134b9c8edcd541e93534c9f7b5bd365f21c4bb8b23d47aabef0828218d45fa2c9ec5567782422d745ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009849d6ff15bdcb2ecfc60eb6db65a4c4ad25b1ad21cc0654375bf3572a8c63d45328bd1e44b800d8d7e230c6b13eb4a0000000000000000000000000000000006660bc859160aba9c0c252b4298029d409741712b9e6a1ca96babc84c5a19867c584ac8bec76abf85d736b6f56060d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f0ce1722d76f0a15c12911efc53a34c6e3e3f151608d4575c83cd4a59f12f789c6c102d2612798abe03b22bd1605a8000000000000000000000000000000001201f584b81041ad93e44514911b79f7e5c39edff7cfecbedf2804428d89724f25af3fa53c2a254695cbb5002c7dd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002da020244f7c757cde5c6022c0f93aa236ff3705e8016444c0b7f7d91b69f50a3497bcd9385b96e4aa303856b56f0c10000000000000000000000000000000007d195ce92425858dc533e3e1870cbdbb8ee5018e232bf59f92e04923ea93781de29131bfbf248ff4a9c544d76a6c4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6ff1abf3295fe0e78e041cb7c63c69b96382fcae33ed797e99e89ad9ed5582a8525a9a2d50dccbfa90453581e2a18400000000000000000000000000000000027c68ad204e49e6d89dd1779c8b3f8b895d184124d64400b3e0c57bf2bf04ba8208f877dad5aa657fd8f957c99e08581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011629ae32ceab2c017ffe9033097946de821058fe6962ffd6a274da550e88d34ba54c2228cf09b57ac2367053f1aa9fa0000000000000000000000000000000006030322a9b78b69f5aa4821654b60a8daf3be4fb4d5464098edcfdc95eb7471a3414859d64e92d4272e33434a670d1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661127f2685beb77ef99f3102eb26c2cade99a7ffd01bc97613d1de78cd1337a731d340f59a2b20a253caa2f28e1f0e0000000000000000000000000000000016f8ec7a55297fa53175567f6db27629e5a8db628e7de01cca47e01ed90baebdd1cdaa46f6777268cd8b57be8bb813291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d4ff4fe35d883be002d8035b0ecfe4481c540b959993c6e2e97149ffb0ec96e757746b81df7c085d705cdb8a2c076f00000000000000000000000000000000069a65101a04086163329d07762c0418949de15152fedb1151d52b16eecbc11a22723f2fd5b53141257d9dab4f899eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019754449eeacde1d6495a0f65474abab8e25f576b3a4e25cc097abc3eac4f7f9f2814b5640179748fd97c5784486d63d00000000000000000000000000000000134315169556110ce561b8b9c0a0a4eae44c993bd44cd74899e84b40ef1e83a704242cfa38f5831735756040539bef291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d0b134be21a459f69083559fa10e8e9a4d68d0013702fd94a3e78a76e96390e1010093319e2eb7f31bfd3a4e408be0000000000000000000000000000000003c6e935f17deb5aac2597ae6c447c3b92631f8684c6d5c92a16ba6ca88ed5dee095b6e314179482395f4f921dd43e721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caf4b086ff11abccfaaa6e74552940d3cee41af90e1d23d5a0e55c0677cad71d787efcc04c77740ff007f0d471c499a0000000000000000000000000000000015139d9764d9ee1a98c0220afba937ed077045abfb4fd404bedc5335089fd2363aa0de0a314ec94b23d3d5749898cc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b14c325ebea88d29e351bc659edbfe6bfbbc00ea9e32b8e5a6c28d76cfe17e8d26fee00fb63864c5ec8a7eab0a79343000000000000000000000000000000001860303214c6a66823b3746eb2fa70f9849d3c27aeadd498379142c9e6aa77e9791ee96b00463ef5978fd4a4d3fca3ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf5241435628445adbb337f8185704f486792299fbbe151758a5aa3e5f3dd8f0a82afb398fc50411f0fc985b350575000000000000000000000000000000001195a49ac5ad9ad5681374926ad32c47f127fcce8d21e174f49b8e3149c0e8e9e5c47344c91a3f3837d55827ea5ba9531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b6491fe03a73a003b283cf88bd5f752704f60e35708c5036992590c88e44badcce37b9b1cc488de6bc3da91d9d16d0000000000000000000000000000000002668145670c537c8c17e4299b0fd7f36b0d4a618fb2d3d4dd45c89b2f26efb3e41d6f58ae0be33b51a388f4306861d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c688fab75193ac833957d8abb6dda22d83ba4f00fb80bfec5ec45c582c30d59bc430c624a694f4bb58e479ef12e11e000000000000000000000000000000000be0528bf873004b2fcdfb301fb39db430c58d0d3371e1d1466790f3d9611370bad99bddb5c6c883de0468bba7987fab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013afe6fb6699f20d23d877cd680fd371b301b88b8767b982fef24f600adc332b009544bdb81d3363e987aca4e06b2661000000000000000000000000000000000bca69ae19eba82610e098b5163bce9637d4fc2b72151068cb89be885b3afd95ee917ed05be1a395f615116b47f280551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014bd7df1c04680c2c8152a3a14d4046af465fa9bf44a3e207c104ef70038339430cc993ab1450606fb76d8c36acbf610000000000000000000000000000000007058c869c026bb9d9c97f5066f50132abdca048cd5f798df6f4ff6cb557c71d3d81d57e99693eba8a0eb59787a4c95c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061d11040a35d048d5407a5e27ceba815d7ae8fe1508b26c6959df8473201df97d8b2e1b3c06c1de234dc7e3dff3adc20000000000000000000000000000000000bef08a1ca38660d13793e0c99fa6c7756045993baf09ab81d30d44f1cd54ca143b19ed8ef2e7bd02b0ea9797073f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bf580b76515f440fb8a05f4655305e883823b55cd7ae1e7212def104a1e1cd1aa31c68cf4cf26f22dd87b26780ad550000000000000000000000000000000012aa61bbd1c8350374061e89c03b6a86cf3edfa2ffbb9e610edf9ed3804cb4550cc25f9b41ab455811b4e2f056e4408e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dbdb25882adbda085b8ea4dd2953885342e3462a7ecd066f8f338fea19bdf6e9ec93814ac5f8b711074096323322f0000000000000000000000000000000011fb5df973cfd74470dcb73183f96c5593050e723126c80fc8803d3b75eb2060a2621798d1f3c8453ae3f188cc9f1e371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112cb5fa3b9fb1fc89ee11ee37f688da176cd023e04e1f7d4737684d00126fbe55f13576170e5eb065c7ffd553fab8c30000000000000000000000000000000019ba1a470e4a46c18d28aaea87a36548a1bd95fcc24e7f4bca587e10205b1d05659dc54357b2261e1d12b964ce56be601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000356344eee82f8fcdab51d102cc8e53b7a427e2a4142e2952d9c2be17f8f681d25b87ab9fa1ae3c7a86d60819223f387000000000000000000000000000000000a95bcfb8d1851a828097fac5e5b824aaca0c5911279e7e8422603f38496b487183bcbe26e6e7e3e1f817fe5e252cfe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166df75509f895f7f3002a6aaf7cb39abd8204eb770092a055f72272e8c862ead75cbbbf4e7b1e91a0b73388d7ac41f500000000000000000000000000000000017d5100b37ed9e3ff69878ba0bfea7e97b466003b0a2878aa4d26daed1dd583942e84dddf8156e3c08b5f4b805f474a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b160cbfb0b89780d9b80d41933530fc322ec05fcf99d301d55409a23eafed4b781eee5194a86431c3e02f9c1c53f100000000000000000000000000000000130b6a02eff7ecdfe69b311b009e8acdcaa09347c2a5d5a1a55a297caf838397725a7a1d3e54b4b91efb604408cc4d691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001675d89cbf8d80ba0273726e2ec5078f2cc5960a658faae0c0b53e37515c4e36d3fa7524f76731f67cba8ed98efb1450000000000000000000000000000000007591218ad18dc21e32a5e8d60b95ad5a4aebd8225fd37f7290d667a4011f83c13007e7b0248cd9287e54899378857641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003025554c64d04935ee950d0373a7ced5f1b93b47a75464977ace64c49c54fafcd8267a0d0b02057e56979cb048b588b00000000000000000000000000000000023a38c812e4b43a983304859facfcd81bd77bbfa5466bdc08d89802ddf5a333fc2127fd14badf4d634f5b56f9215e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbfb23bf71919f8592bf47a561c3bf4a684a043c4de8633c83e09cdd2bd54cc44d9d757459369dc4c4d673531600c200000000000000000000000000000000022277fc57a9f666e1bfd219ff8a35c44225ffdbf061836c2be356a70d81cffa4b15683ad4290a4939cda40ccfa28dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ec8b080de41e822826c0fc7a10d43c785f55cc679eea24ee750b6a99dba5f7679985732e4b5d2cdc74c44ae9f8a5b20000000000000000000000000000000010efcd6dc9c3e3f138bc8fcc3f214840eae0eccf11610a2849422121c3b40afa91e246597acc865ba5ccb2c7108cef661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cb80db85717dfece6f892960a2ce946e23040c1de19d731dc1152441fccad7995ffa85e7f97907d15860927dc3c92600000000000000000000000000000000083f43e28109c6bda83551e99c3c773141d0cdcd52b25be4710058697e223f3b191776551ebfc3bb70474b85395d32301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123e422d66b0a35e525993ce1d0e433537c2f63455bf4adba3dc7ca19c5698a84209c9535cfc4cf12e89b4900b6e955a0000000000000000000000000000000002407e3a00ba556d181c154f3a3bf508ae9e94887178cae0f4f109d0f062ba74b114450b1efcdbea0adf526832b516a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175d88638cdf5d3d108cf673e85984eced797c6ec29d6e91f25ee4cb226db699ef4924835bf0ef6e224c8cdaff10bd010000000000000000000000000000000016a742bfade9b1d5197edf1a92508a6cafb42fc21937c7e14a70df63d4728029b8a2fec421e9c5bb1cf42788e1b1fee61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb6fc23f64d4a4642e059bc002cd6d5bf5013b0e97aef710bdbc6dedd5844d7ef69707ed5cb45776a245b4fae0dfda000000000000000000000000000000000ea56ab05e8a0e07ec52a8e3ae3111eb66e2a4e783ae7386c722f6a9590fd0f3587374af19dce45080d51f7512a2d44f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a17e93ee388f3446a31ffd62f7dafdb68116fe470e1077f082b564267db94ac58844e46c035ad4684ffbc5dc8b38bf00000000000000000000000000000000158ecec76da484c88a4b2019b53cc1013cf0e8064f38a971a0811e99ed4bc76fdadd2282623988533b783170f9c2c3731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001532dcd042faba6cbdf0d92314e19ea3e7b04eb69060df3e33c8a61bff2e16f1f3443dbfbac75459925e1f7922d31fac0000000000000000000000000000000016a0b073c2550a25a4e8c49939f40acb2df7b1c2810a45989e418a70b9d290fa33eb365b7366dcb26250a987d59453c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dbc1bbe213176c3182e5b12776276569f92451772b3113461499cc91b28ec2b467b26e3af5d2cc4ed7fa57bf2c19900000000000000000000000000000000011f955e74761379a12f4a5238873a2359bcd29cde3655789af8ee8f994d0322d0b707f6838b693161e94fddb694dd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d3cc124698a9f9c6affce4fc9926c704b89ba96c7533ef3d1bd65ed6824d39da21e7810fc468f9e975d126075547d1000000000000000000000000000000001069bde8914471c1d289954ec5f3156df7be0913103feac97356442bfe0b5ee6c9ec12bb6815a41ec3245921173961771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001378058b1a1724b510f0393bccca4dd9989b6ecede5c46c6386b7332f8087aa7942ddab6c0c4b9d4e6e5922d63ac48a5000000000000000000000000000000000a2511fb1f905fd37699c69dbff6488b798fa9b15da1d2b28c86593874c3a3cae4cff27236f9748da0268bbb968130c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146b1e6c7de5f518f98d0ffe762310b488c83853f25155d00785d9363132e408778d08228745dbff902bc6158fdddf00000000000000000000000000000000000cf80071d9f7bc01af9ea66a18b22efab74fed5f72ca23dc3ab45fbd13aebd362259e4b8cc9cb314e6208271b299aa771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ded09d54723382d622f1c46b2cbca4f192e471694d002b2888b0e8a7998453512f9d9d5584c43435957babe023eae2000000000000000000000000000000000a39c495e6193c5c81824654d9d24ddf7a138f192a372a9ded8c85a301f0218a5c5030eacfb670f727fced455b4008b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b1a8e823d6cfc4936bf33b7c31f5b55b0baa13b2f74c32c5dd7d10e56e44db11c3ff74a3b702e07930f4aa9ccaac4e0000000000000000000000000000000003cd8c9f55f9cc806bfb7f0ca1fc948755448379be58f105db0b1e00076d93d5b69f88a92423522faea500c0cc3c93f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd048161b967fe4e49a879519de96512a08e827f0a07130b7686cb13a4f897636d7edfc3105359d482406bea7fc5964000000000000000000000000000000000e1e7e1a9cb9df5ea4ed18a03fb97bd5ab2733271534e01d85541c7d2e194cf8fd2826341f022d867cdcd667c865fb151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6654dc9029f77afffe0ec46bdcbb06fe6806c90077cf5fe49c92bee504b9d0a78fa1249b23c962e3db008a635ba41000000000000000000000000000000000a013a0b600ca6d1c36fed4233b0882c7a6c41357b8fc4502ef6aa130de8e11c4818e47b4108d2e17c52b79f762f78bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196491f1d774a42f6aae2e8d15b66837a5e98aabbfa03ced3e8e763f639aaa64172d9599777e2ff7170b00696371c5ce0000000000000000000000000000000007092f0a6c93d78534f9d6e8c5445d83799ed09836ef70985b9092252c095a58e14250fced8302bf12c4811fdce7c8b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026336d6e3d381ced708743f1db8fb5ee35ba43ecbead926a11f2517e08da9edc6888427516a5f3dd47b2647f096d2fe00000000000000000000000000000000003068696dd7f5e459dba5e5e4075c02b2fa48190ff9d5396ee5d61e48cdcca1decb1600b49c0ae522423bc85a3a63f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e168d302bdf4454eee0ade9ded73d08dec3dcc48af91e04da62d8a125c9ca3433f56da8c9f0e69b4e0a817b0f68f8b20000000000000000000000000000000005c451271aaa1ce53ad1e02a30cd98d9c01082de714d6cddf396fb094f3d244ac89b96742d0b022e473bd44a4f2234a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011293d77d4573c256006a6eb009f1514a4a71111f197345adc9538b11349feb3522b72b321797f38faa86bcfa75b14a00000000000000000000000000000000014fb17949003003721ac0a0473a264896ef3f2f29700e287943f4b2e7cf8650403c96cb792fc4e117c67ed11d22669de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b0eb17e3da101d72ff13c213a4ec6c2d332d551aa60851554ab072d5425b54a722c4d565653583bf1fd3d4be0657af000000000000000000000000000000000fa031122cf8f2f47c09ae0f13d57529c00b11602f5abdfba29763876c7da68af66f399bb0535d50ff43de70bd18ca7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c6a736ecd1e15cafc4a18aa045278b4f1e9d5f13d814ecf5d9a935be7b60cce6535285e41af019b30d02d154d68400000000000000000000000000000000000827e76a1f090a27c8eba82fd2e9989cfff806fd4cdc141d1083692d1933cdf1f0715b6f58257dc3bfe7ba1ced693a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012385eeb308b2ed0fb55a8dabb9113f9112e7f583a9df0143cf9f2c54d68603e9589385fe7e1f87e71fc56b95c82be8c0000000000000000000000000000000003ff8b8d87dbb388005f440ff1dc0f2fe9f558ecb4fbd9507adcdf7046cba89bd9957b26123965837f857a9d24ca7c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2136386c2da6731f5676282dc12efe43e9f06ba00e990c9ce7f8868a1f74f534ed2a95767cd922fa6b7cc63006a6b7000000000000000000000000000000000230fb3c2f7c30d920e4606483041dca9d5d6d7e958b1748e175acaa4ff11698c95fbe8cdde55b11653e39f8ab80250f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012482cd18ee4291b129ecd222e3670b1f647e255e1ee047e6603f8581f08d291105a4aaee1bf9d6ee3f2a86a9c1b0d7500000000000000000000000000000000076ac013586e0b49b89501244e680472d34c957a9b6426e8e94fe06496a4fed6d6e943003f375ab518154d805b5b6cee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a37f4b6be8bd5536e314fe727608cafd7796fa6e9608a7346e7d9265b02f357ed2542def824f78f68f603b1d00d4240000000000000000000000000000000007e63cae5b6d6cf6faa6fdc54c61a84586184fba9038c29063d298ec44ed03b930b8d16018c74cf253f5955cda7aae8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048e75e3a9e7c0fa8cf19fabad9986f7f9168b782f63a1a68ae2985fb11541943126900cc0dabd92b3becca7e9aadbf200000000000000000000000000000000115e86d8b51f0471e32c442327c2d4853b4864f3e9a7e8c6b8fc4460f276935c1209b334bed29a52dd57b5c8b57d61021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721519040d82fac82cedc1ec2a601395981bbec0c912200a3ee98f201971854c960ab595f2597ea6ceb39063141c0dd0000000000000000000000000000000010d3ddbe76fa2457ffe6fc29dc4e6947e88b567f40fe65eb2b96a7d5762e2afcbda36cb77a87b4c3ae1c77314d84ebd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086b02ce230d01e47756694b58ca50bc3b820828d236ac9958de2495792ad15ba5df97813a831c8e368e97caa7c4530d000000000000000000000000000000000f4560347c1e60e4cfb04727887642ffe7e0df57286c80a1f181f0d4c2b02eb5759efa7415f396c31d9a4a0128644dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f86f3dbb2dd837b654bdb8fe4262cdd9a008115ee3da9cc8d83b73d6bdf63c058d0c16ee0d3fc8e51d5b168da15f28000000000000000000000000000000000cc2f7b2060ef7e209bd0dfae9230ca23111e56209bd347d7fc9af8072ca023df949421a84998f646da422f0953436091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862a70ed619e2495b101d2489b511d36c4c9378c4834789e951686e78e2a21fa7e1c2f173172c5d6271ee03eb024110000000000000000000000000000000000b26d1db8d11569c58c050c0b114b056e97f5a794826173cce7a2a72407f6d6b201c67f3602a1ba94c19702ec7646f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a2f58466336fadb11a413d080bfeca1e596e7a5c37ff724f890c810017343da132798ae2af73ef664a8c11c49aee92000000000000000000000000000000000b3d92cde2a7acc50a207b88c18e41d2a40d6486fc51da825ff57af2af628a80ba3e7eb6919e3009aff61f710e58c8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134eaeb0a3a8df81b98c2376a9050138b0814f9c93a9801a516bab050fe0cc2e556cab4b404fc877848ba0dbb17f8b4e0000000000000000000000000000000012cc987b68c23eac2fc83d041ff8017b1b95370653252fb3d1b65ee7a0bec3b566756fc3cd792a7886c9bfd9f8b6de251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147f37edf3a2ffa922540a15274d2c380c7b211e9cd51211088fb3933810eb87b690fd44dddeb0d3921e8fdeeba2a2c900000000000000000000000000000000028b84c811691f54b1b649e2d1dd699098f9af455e1a1fccbd82e372189789524320f1853e13cb17d0ddc1551d3e71e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca72fb85d44d7740c1c0faebb2d74d9fc8e7164f1e53785702288e5824fd737750d85c7d9337ff7dd35f8451cddaf650000000000000000000000000000000008a7099ca90a27268bac9dcc887cbc63d6f11b9d423b2ce6b62cdd17462acfbe5c42fa0d4f04c8fa64c1c5a13ad6cd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088100c1de0d9babcf472bdd6fbc379b1e999ca6fc5186fe122dd6523a8610819f81aeb2c3df3dc58f83982f4ba0f4e70000000000000000000000000000000009da08b462a86f22c5484b83ba67a2c0ee1844814d1337fc4c0a614debffe1c5fc4ece775e558075266675bbf1e991511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87ee0fe488e4bda38ea601a2232a195c1aa1f56c5d59c8c7b720ccf87fc4fa39f7acdf6b1069b50401b9f3a260296c000000000000000000000000000000000e7802e1f70aafcd367fc240f99927571030e05f98484d3c74f039a71b1b8e934edb1de9ae48717fb455c93099c6a0fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026fc7c314fd0c23f5c602d1e1a3ab7e0178c51138ef38be09d420ee60e063b1ab5e184a5e501815674b353a0c2e8733000000000000000000000000000000000e6aaf1a7c59ac9c6a144fd9edd2fedf782551f3b3e747b821b0cfbb2bd805d83b90ce5d7474fc8d416d81ed9060796a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001442bec21467b6c437bb5108d77ff3584d66c075a762ca69ff818f88f6f8e257caac99baef71fa958d4efd64cc0b4d810000000000000000000000000000000013bffaa69639c9ba77656a9a425d9a9d11b98fa5fffab4f4aeffc75c0bd68bfe8897ffca397409978b7f7da2fb5872041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d3af812f430b93f6e89f4780c31b4a99b0a463ac1a8328f452b722f20e13be81011755f977d20f7d4394167ef1159a00000000000000000000000000000000197e1c6f4fd6537f0d9dcd8ead3cf2b2dd7f5425b63afb0dbc4cd93d15da5cd2872ed418d515c8391d7b5b797c2f706e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026f51847bf0e79f98cbb53fdf3ffc76e1e96b63f1aefe7469144f1559ed0b859bad4caedd71e51d23434712145002bd0000000000000000000000000000000012ef18e777edb9219952ef871d150ef1b856373a94ece8c54e717d28695326adbafe159f9109051357d72f833613cc901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000406076c4046d54e0a146ddaa49e86c29f81254bdc7cdf4581326be86d5477adfbb2b92236a80a1e4501e2c1c4f13fd7000000000000000000000000000000000183e9df29a652fe095cbb8a97546266c0bea118ef3e9455fc72464c066d55f70aa53c3eb4ed0355ce417d404f5cdec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb61235c5b0bea0440ef96cc83f29f1e3d6d86f3cada4ce25abab5d177463cfddf5e906ec5d86cc38df57299c8559400000000000000000000000000000000185de092b387f1f1123396c0dcdafcbde7649dfb644f0288d951b55c1cf6f71b0a6476dd6808a7a69cc9d9f768fe68ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118cc245bd1c84053aff9e79c1232221cfb7936458c307c82b7000f7885c268ccd5db94474488152d50e0531e7c4b301000000000000000000000000000000000d93fb909a0d7100ffb4d9035772ed6159cb3c974a77ed02ec2af89b4360ae849cfb7c6cc2d79353dec0e2a084f44a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001579cf597c2054362c5f3a4ff3e7016a1c161c65d04b0b94714e13486b7e33618c4956f355782b266e0d111f04d71cfd000000000000000000000000000000000ce7c37b7b7a216dcccad16a2697f2188e15a2c9d1b028fa5caa121834daec6b7b70dc8b57a719d8b3205b43f49354731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041b53b795c1fe7da922e5095e5c76f21f95afabc06ad7e259cf6a5d18e35e1b45d33fdea2429edf7f4f68dbba1087880000000000000000000000000000000000a21b8114c58988bb79516392bc32da970c94cdc0cfe4e2a4cd7d275f63ff0f548ab1b5b3d1e1418da69f23fab871d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099ff7fb67387860fd9e99daa4906c5424099530f78b4aa7022643b338c8b375b574f5a96db3598f32d560dc94afb181000000000000000000000000000000000d04a2ea930b54b8df5447a6f069f8dec98bf05a5ac80395453b951fd82124bf9201d7ab705a850a2c7533fcccb5a52b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afdf98f08ab187c95699eadfabfa355c627ae96a84816834ae72ad22d0b7df03c3ef11586ea8e65f37cdb7c694b8d3f00000000000000000000000000000000079ec8bc973c18b73365a675f18a5b231cf072340984d008e23f762caf91f2492f4c579d8a809f07359e5b221b9c24301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e28896db18eef129bbc7a3377b6bd0042699c2465a10af2c21c9b87834a13454c10a5b5d3d05f19d78eabe2b1f20f1600000000000000000000000000000000157577cd0718dad72affb164d77dfa6be75605415fd8eca516a6dbe9bec71e5ec29e67a822aedb27f80b4aec13c102391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0761222611a4347d456c407a14820111f325c2a3bd7fd8b169917977c1abcdd6b05436b3592b53c2066d156dc29ee0000000000000000000000000000000005cd038a534cc6d5ebc484bf8345431dcf6208c225fac852b2e57f9f535880fff78bf946e16a5dea7ea9805ada0ef6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4ff468d06274778eef35bcebbb209e487efcc91e39fad64e2a73376b6a5eeab73d05ba2a1cfd53e30dab93b9a0942c00000000000000000000000000000000032b70cd9d2a72b79ed23213a3b6636949ff9a715cf234adc5f43fb7c16586b472a869db68827926752c931a17e85bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046b158395e8167943347e13dfa67c3b469d1607e37e2b761faa4b8134e13d26f574c996fc2689e795e8203ef6192633000000000000000000000000000000000f9c57070af6e0bc38726e8ecf940ca232703b68c584dd2436fcda0a33e1d8f9b1b0ab0c8abe6e3591a3fa95ff8489021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa64e13e0f68575ca656dde9ec9437b036b7c0699d6bb18ac799d2aaec8918be741d979f98aaf8f80a81242beb4dd9c00000000000000000000000000000000051d8a24c7eff9fa07b093e5a081ad4af9f6b3cd85e3d26d64bf63e6f75b6269846c683c7d48ed93e7b474bc84d29df91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192011d5687efcded8884908b0ac6b74b9aafe343ded3e40f4528febf8a3e3a0d648dee6e9af88ebc166db9f136a11c00000000000000000000000000000000116198fd19a29a732f7e7c3839110f77728e1ea62b684ff08e9da771586d43cfe4ae2a0684720def1f17a4ab63d75ad11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ae24b92623d0d8690e889f21014fb4292dd80e8cc69c725653c97a5f77e3e4d99c996ddc4e96bf2f8bd5d7fe5528e000000000000000000000000000000000ef14d2cd881bc59c6907c7c28a7fe467e8b8af15b8e6dc25d9d204e399edfd7a74ae94c9b107db9e5498d583d0a02a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b033cfc76447cd2f03c73e328cdf3d9e938aab4cb4f0a0235286a143947192c860317f40d1cc9125d23cffa06a5e7300000000000000000000000000000000149fe74424ebd76ea9c2707b011c955abdabd2b7209f17a29d766e90a566384468dad2fb799e22588500c3e9fd62d8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016142f4a416993a61d5487b5a4f176d6961d616e6b0c9c927e9e95112b8f005f7e792b804f09034cd08dab7bc2335dd500000000000000000000000000000000100ff54db712de35c5480cd8959db494313a5047a61c38facb63325c37c4d76010e3ed8659665094b99ca928bc2ebbea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198526ac6830bd04258f1ed50b30c3f2dd1dc4cf1de23ca36a4847e603e48ca16480eb4c54b0610ca23f392ac3027424000000000000000000000000000000000d564f52835f8c8a996389fd94a38e9400377b1af8869b0a9a79f05525f398410621f8e7624f0d8d97e5474a7833c7e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001221a62c653abf1608545c83dca12c701994b93fe7339d33a5b63b70f228b543c6a04da4518a251a77b7803c75b6761f000000000000000000000000000000000d88b9ca9cf7ca600b7aaefca23ae8138412db207343e83f6630cd1e5a58a13391a38436e8137fb0a3bd3035d16af16a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067eca475e997c320c14eaea437d331975d622b8874e5ed3f3398a361860ad071aa3cf1b6d5ce9284ba0b3ec99df16150000000000000000000000000000000001b25057218907f7d5121a70cff5e218e1b0f31d473fc4b2895fd1533b9a6ce32d27d6201227000d8ff682cc5b388e331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000302f831861ba0523836c7c38516afe94ed8e282ded74db20b62269bf875ecd7b0e7a5c1fbcaa142c632985dbfaa8ed60000000000000000000000000000000007f3b4001d2beabf82894ff03105a2246e19611a208ccde36760bc7f6952d6165f9f350e982696c08eb93141545bcd071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccf05262fbac12e459384c3cf1119b8c8cb87c9ff310f609972f17e9885c74824a010d5c32059b662faa049e7fb8e590000000000000000000000000000000002043adcfa8af733cad7e56a7db5dbdf28774426d135f67460f83bb801355e0ad5bac3bdd76d12786a37f9de896b84101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140de0f8e8bea89821003f5543c164611fec949a620f0debc533fefdd20fa8a3a288fddb01076011c500bde22a1e10d20000000000000000000000000000000002343a8d00d0ebcf1536ec7f5ab42aeedbe8ea4bc6045e5da7396674bd90acdd81bebde4044552334cdd7952854af19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cad9de3c4c006cd9487dcad2c9fb3c2b1f72c8a662af444aafbd905208fbc8a092dc11e1cf45bc269238a2b8e4df3700000000000000000000000000000000027902f309de9626424bb328c376d6c8c00b5336deff3d9b22baa3e4b1794a5099d3587e3e1db5c2d2046b0c257ade551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077a58bc41bae6c9267c0b4b464824c19892689a657cac1dc4c6705bb2fa2f025231e82b337612a4d97c069e2975db19000000000000000000000000000000000f72b8af3528582c2ef07b158ef2192f0c2c6d1850c6cdf848537b87acdfe7cfbfeb8530119d26762fc8c30d1d5592701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077ea9cc66cf5a2336478c321251abc32a16644527a101e584cab8512442d280fe107832878c5a9691bc31dda59211390000000000000000000000000000000002ff2bc4c6a3682a1aed7ad5dd5974728837fc49ef13dae3b0153f23fb3ec5b386627c455b3d7d440c8f0559023098431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba68b6e85bb5d59d2d9e5969f86fd3b2ee974b38c644efb63feed9e4fff7c99ca7d0349fd85b0570dd2debce89cc831000000000000000000000000000000000b12cbbf373b3403668f2fe259d4dbafd8164fe7b8c840151e3e02976bc03524913f89e62b873a3b9dbff387623578801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001133bf2779e6131aa0f4584c8afac7e091d3ee30473ac174e31b2d3dceb21acaa66817b53b3ad073bac57a1ccd12d2ff000000000000000000000000000000001422994f22d9e35d732ec4292bec2f088211687d7f2b75377b1dcd9486fff6ff59993216424fb66c462f09d84cc943e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006aedc27632ae723ad76d439527a5b1c00533f303f607dabdbe92d4f51e8f78393b82f71d7f1b6b8e7fc8e9bd9ee256000000000000000000000000000000000895f619e5a9663b10698aff460fc820e3e1b2951ca5adce707f762085bb874f6ac4b2c93c6e372281fa366968daf2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d07038a24b8a30620254d30b2fe33b78e2e630b84c60209ee626cab5d3f5fe633448380e599cc973a2863c5b0ec1d700000000000000000000000000000000140b50a2324e0fbfe35bb30cc56a59aa5c7a6ad8d7abfa95c7e190adb462bd561ffcf24ff4fabb1a29c229cd550628421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000563e01f19ac216aba65a3c08b48375d677383df3a523c8c4eefa9003e90a878014c6b21695bc654e153cd39eb0b98460000000000000000000000000000000005240b2f7ba245679e9747ac4785961b0563f25fc30170d466a17a869736f6e27751abe58b4ea25a40809199e921be581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126ff2c36696633c84576158b367a813087887793b17d2402a73dc270a52d4c157293ccc2f1ae05f3229547491573c900000000000000000000000000000000016de49862a53a78ac4ccfc58b805860d6aa5f64938267330a61b47149011020f73e7b47a8711aa03900e1fdd3857c5591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110c34c1d59c26fa98e23fa5623a5c11c599e10b28933b240368ec37122a286ba2aa6d06941bf5be48e9593f2e10de6b0000000000000000000000000000000017f8dbffa28376eaa130ec1292ddae4e1bc5a89912b85e81760080e73a915ba05908df61c83cd9ea7290a058933853ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caeeb19a559a61cf10693f536a0c7910a1b0d17a9a1af27dee0e9781c9fb3b9d9f060c34b277e2bdb245a019d97de650000000000000000000000000000000008d3258a6bd9e305fb5b0c7b122e73d42cca9f408938782c62f4f9bf985ca498d719f14720050062157317d416b4f5011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242a215a778e8634c5de9869ba376a45a3102144a931106395eacdf6dedf176668faf8fa3f1c9bbf3da91f2026d4df0000000000000000000000000000000000be0e93b43b5cfd1131eeaa429284fff00071f216aaeecccb09eee8e16b0d1c8369f11b29a0e852a2edfa1d12f462f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011477ee937f1038f11629ad107692793bd57987949c437c0d22c60fa9f6a702a7205f4cd7112d01c22a6c4c35a3cbf8f0000000000000000000000000000000002b615d83f669b47fb930904b95889a16ce7556a85740e9b17cbddac3782b40c861de8403e24b8835bcfc3ce66a9439d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e251580a4ad87fcb221ae10ca50acfcf0ae0b04e61bc89c599b256ce226ba58a9dee7d870f1127fad0eb06433dfa110000000000000000000000000000000016ad82672935ea4357c28e8e68a04c94dddeb2a87bae29115beaf5463db32aacc3313fff13041a3735611ef9a806fd661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990cf8b986b039aaed5b3148b5e64e2d2a7878a829dd3f47a42ab0dfc7d5f2f73af754493fd70bc8b2f06dfa93de5ed0000000000000000000000000000000010e4ece74a0211dcd65cbcccaf7ecc5bfed268cfd9913ecd46d4c36fe70d28b8630b90ad7cd1007a8a6e2ddabf349c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a4b0486177ae05b3c3434c2a6f418788a9985e71a0f0bc1f2364b3958874aa535b178dbc321e5b8c8accf7fe485c170000000000000000000000000000000019055decb137c1dfaf7a80dbd99a36f7558643a55f0796fb374d484e842d1c53d315c1d4048009c2e3a2ff61a5a507aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bfd0833ea70b619d3a7802d22c48d69152b8f87ee456ec7034a80c62d57a7adf24289e0c4f2b2ca53721010ac89ec0000000000000000000000000000000008209ab9f56c17737110f8bd25dc0d6048d8dc98b053c07a8819d09df3a1979ea333e96328c05535b15ff003438aa60a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aefe07618e05395d7ef6f84f0dff137ed97c6045b3418032f7cefe643b1d8190ddd00c515b0be39955e810bc3f9fbe000000000000000000000000000000000f1a67966b1f94853569c13e061fade6f2ec0768c89d8947c377102e8afe186a6dd9297cb05716e6fc2010d35c49e22a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de26424f245824b162cdf016bf5a7a2fb39b11b120145e61d9e36c37f425cca3806ce67ae0f502609266a1a1abb5da4000000000000000000000000000000000e4b2f7c92e791e5c1458e0d28cca80c389592ddd4e2b1652a4f8d9808441e969f4bdb0a17510d658abab9c2ef0126a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdd1c0a0ae9b58ad4461395a643b5ffd5e8f17221dfe11aeeb3ea447e7f8c15d699271f12c8255c61ba39e2adc22d9f000000000000000000000000000000000b426f2bf81287c64af3032a93ac6d66b5835aa50d9a58340adea4d05189d2d3e7fe3b4849b311a4bad36af9d0b8b7df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f250f17235c0f8ce8a3aa846d7b4a21a2a12afcc0e864df154a8a4deab299cc82fecb3c0cd0aa4a907741e5892c1840000000000000000000000000000000009fb45d5dd81e18e4d79c089b406856cdb956163916a0ce206bf02a4f7e59fa765f1a0496ee1e8816fd3d6e83708617c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094dec66fd6c404091599d8c5707e285abfb74f8cf7deb4813f04e6103b49603bbb3ea33ebfb607c1b41361e5a9b40660000000000000000000000000000000002c43d7dd2744e3503799781f00d5276c43a8dcb5e0d13c8d26aafb0ca8742b1228f07b0587648d36982df61700a75481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cced53c4c1bcf32b7b1b4d6b393f88eabf6030123dacab45589d1c5ce05a0f4748b03c7ca4f9b69bd8a209037227406000000000000000000000000000000000cd6d52e37d01a8cae2a554159e48f195a66704d2e3a074283a82389d729f8975aa152fac8254ed1bafd222e18ce810a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a249aa25d58f85df35b24e3748e0782067de47b9486dd9e9fed035e9f5cbfed8cf855ff1d92d2fea7697af9bf7e980000000000000000000000000000000001212542c7d3a5f2701087dbee68eeb70eba74aee461a8d50eeabc3acd75b00e57021780babcc7733930d7319d431a7141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452e5ae053f59b7d7469eb6bcc02bec43495a6108c9d82e9eb8e3f753300a9de73505022ee042f54740c848e4b791fa0000000000000000000000000000000019aad1914e4a083b3175493cc71e3d2a217a2a53c9a0651577b7206a5ec337135ed606e12e74a7a77e8489e50bbbe1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb0dab493e4a49a35de125f487e15fc682cd65ef1d828e053959a3b9c4593db52d0eeae7623d993c7200cc4ec11bab0000000000000000000000000000000002d37a38d18740adcf20d900b967abd2a351ae0071694f42134ad0a02f4beabedc0beca28a82ed5fb2d68a1c7456f68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e798d1da2bb8a0ac6195cb38b64216b08de09d862261466a8237a1baa9dc43473bfe88d2a4fa29b3bf86ef9b2f0c5000000000000000000000000000000000fc213b0bc63334eb19dbfa75cfb931a1d45e264c4ec1ac8788b6d10d84203eb767d9257542517362e70af2df7870ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5031cc04d61f37230de8b3891b235fd1d99699e605cef5b2b3cd0ddfa37e73ea6c46bac98172dabb1eb0f3a29cc4dd0000000000000000000000000000000011cb1096b4f7e8aae4719071e251d416d75beb400c3d38d65814c501b2190bdcfb278a58bd7648f0878bc628da0ae01a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f8e3d5c0647040c97680f1ff18d498914738bcd1f19c6d2bd1a145a39a46212929a37b59b50200b4a778ab30a7a1df00000000000000000000000000000000125151b058639b0e843671e2f03aa164887a7953963cc345827269519eb75fb97751092039ed4eed02fb0b009283ed441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7bfd0d277d96603a189e91e5aeb54c5e27b1011617810038fc70c3f4fa4433712785f9fdb159ae52560f4e9782fd6a000000000000000000000000000000000097671df6ba0bd058e25258049b8e7ae654cf0d6880adea55f7271cd05619febc3338508056259c3548d680611eba7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b8c137d7b1989addcdae3c61ec4e2b03eecb72449018df3654c182271c4b87d643fcefe224cbf3822313bd4478da3500000000000000000000000000000000170a8203907101521500161e30432b12e6c606f168706bf348b068564926b3cee82de01ef6c8279cd17e6335d44625bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131423b93ff65fc78c6eb057bb4b82c0c6c76bc8effab1eb8ccc685600e98eddd691301ac040dfb4685938bee3607d42000000000000000000000000000000000ae9a39de24083333b8eb4ee5c915d26d47747e19438c88a6f46e9c0578b54bf6b46c389fcd8b8489789d46c8dd862d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d38f07a8859d00a18780484bc61fb7e69d1300a8a6dd43cbe6812ab2eb358624d675768615798e44f63b925e9586ca0000000000000000000000000000000009937dbd99108644ded74e25453ce7dc61681d5951f71cce3b0f30a1396be3bc711ce74f597c42b43a31c441852318611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3f5373af9130984eb844c41982868ffab4e78451c914debe415f85e54853dc3b9e007b4bc070393b72b6ad31f893b0000000000000000000000000000000018c9bf39ab48634ef64f524c0890998355393b8ef3e47835d1183f22d8ab1c21f082961ff64513a31d8b030c86aab8cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171a3c23e36c24c840f12e0ee556eebce10fc8bff3544de7573daf980f2150761dd859f0fc7f5b4c28580533a5dbd2f200000000000000000000000000000000036ee10e8606b22681eca0ae22e82c8658d1b74fd9e67d015ce51e3c1a5431b12043049197bd1bcdfd67fbd616f8d9251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015b60d487564e0c5d891ab55dfa66b97d89cfb6a82b042752fd2f3febed1f3f05f126a2acce31b479bd4792ce849b7a00000000000000000000000000000000079a3c8264dc09a4e0c079dedebd6ea74be6f583c4c709a6723f80006b9034b9d1ab33288f42d75ffd032bced45279c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a685de9d665ddcdee62c1e46d2c23eb14af57c0456b0f2e1f87036336e02e4b1586d9fbfa1d220694a9fce9b1f2589d0000000000000000000000000000000016efb020d23d4af065b1faa35cff126fd559673558c3521464d11444d36d53b51b4d2d57200dc3edac61850c93c934a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004945befbb3cdf1a402c35e52a4f98af64374b16955c89874de5c94de6172c80d1b5ef45f452f5695ba69f2b6c98fa4700000000000000000000000000000000198708aa1e6ea62e206936266887630689901fae676d20ab9710301474b6d9ab7300cef1b2fa7c29fd5ac7edc183d7b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3afb4e51ff5b7490de6443043a5fd09602744582b7e09b8df37bae921036832311c813e61b5f251d8c2b2a75279a97000000000000000000000000000000001967679d4deb5b5eba52707d29db1f7b7497fff4a6b8a466f5032530847b3961d92b66659e2f00af76ac4d8c0f47d9411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c6b6ad61911fad0c2176f4831fdd904479fccf095c87fd3a4f03284a358fc7cbaa990e1c7cc4f5c7b97708ea0dd6800000000000000000000000000000000181ff59a9d5eaa24551dbb8aa41650148b898b790118cdcaaafbc9a6601eccb4d073b0103b30a1ad7e86a71aa5a8f9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150da3842fb9828f472e7e6e8d8dae087dc6675fdaf5cab1d18b3599fdfd1b1aa3738e99cbe532178ed4f35bd3302bcc0000000000000000000000000000000009361016c5b9298429686f05f0e6ac31422c85d0a0e9df3e8f978bd211a2a448ddc272118c859da42e9005e46b7c6b7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774244d0644a14f92fbb056cd22c2b3eabf8f68b464d71eb07c6bfb77d455240c3278f647d7b1bb5ba3bec64ee96b6e0000000000000000000000000000000000febf6fde372aede0d8770246bf1ec6c19e8497c8cbc7efc778bf068bc008426e560fc405c35b7e5c50421bd3ba86241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109a51d9e8ccc37d4b9f4d13398705e21a5758a8cd35c52030ebccbb9bc9e9f39d2b923c39e5b812493e4a7ddb62f15b0000000000000000000000000000000005083b394ea0b910be8d4b6cead97d3db3e5d7bdf0c6c85316db9199e5ec7ea11f9c8c0547863fc2e99df74f7d36fc911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001607dbab442113facb723e44541206374b6481ae149e0bc02ec8c7d8a63b78a985bac16f8a8160571a17d5b6265e197f0000000000000000000000000000000016526ce3598223f4dd5700496cbf1a40a9bb9c4e57919ee550b704bc075b5898249f2b4bc4db916fa259980d3416b7911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133dfc469ddd7b2bd54313e716990aaa96452228fc5059e4b31793a5031d664fa83b4535497b1d9c5d2ec5e8267aadd80000000000000000000000000000000014a3978a8f93c805833223798353f84f6be8fe2eecae8efd765aba76ce0b425a1a923fb9ea6be3e9d7539645f415b5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c82768c6bfab385d9b159e5700c82afd6c3f9c278223cb05fa5f560dde74e6469b2191828f2ee28d0c494f67e58f770000000000000000000000000000000016b6c3bf3d54f70748fb2ca87403e28dc1ef8f8e1a307c93cde10147b64fd48cf38305aca587e48b4738e76593cf11d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ea26a395949cf53468899d9ce5e9f8f25ee897b153418f221c3b7d0c0cc6e7c5badf322eb5782fde997b867084511b0000000000000000000000000000000015ffd14c42b08749579c3023e01e57c66ec60e973f8393a8fe1cc0fe521786c536a229d735f7af4b628a21f40f9a54331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0e02f5a5c565c87bb4bb97f69ba851865c255a28621e3c1d8d39c91a5c78544d7dbbf9cc12e49cf99496c928c5f57b000000000000000000000000000000000a52c5d0ed4be22a71a8a1b46b7657d552d3bbb1961fb53b63df75f6a57a540a7480627acb036ec151bc8448805cee0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003274aa4c02bc485433000c2dfce9d2f1ab44f86bac34d83783173dd120e4c13875786cfb4920074b8ecdcd2c61951270000000000000000000000000000000011e9c9884851a9fe4f4657f68fd7b09f365090cf5e4d43feb98b95ef4a130fc226c373d32b8c89d60aa90de019f2be1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a2899996b6bdc626a62bbcfc5d2bc3f0d95b7fb8d4438ed75536bc3dfcb393877bd2c6b9fbc0d9f2b80d862ef475ca0000000000000000000000000000000008b73eee57266cc61259ce83f53dab0a2b7d4e32518ba022a9337f248eb3f81dc2a0df069b8856c9fe1bcc0c7f8711281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002edbddcc30581691c513db0786ec43efe1fe7bc477e94a38cfbec6e38b5b5eb127eff6f4a1321491ca1b038e95e58b300000000000000000000000000000000082a9ae9c695869ba96858055172ee5a4a96a7a0c87752da598be88ff563441a2817719900f1b55cf50e2f45a1886fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c4333a1d3851ee7172165b101ee9527e4835b127cc372b0e1c9bc428bfe631cff04b19aca7371cf9d34a4600804dac0000000000000000000000000000000015618e3c00134ab36feb79a09b4ebf369a3ac662c4a5affe95b34ba3f037b2d2f71d9bcb0c99878c33304ae670e702f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114253ca63a94decd5d8b5d548dd17f2212f46b670f37555789fbc8ca996f541e84ccf3867c651e538800b66f4ab22b4000000000000000000000000000000000143139321cc48d95aa54d419873406e776dac6e72abf439e1bd022d04d06ce6845f350ff792e87e78a552ba0b2595b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180014cabdee922106b29d197f87102ccb508fd58e3f1dc4e0ae3ab0d7871f26a81cc33fef3a0d9c80192941a37204ed0000000000000000000000000000000010dc3f6debc11ce1d4e00cda5a2b0fe7ee99ce0d42496ffb6a39c468c5ce99ae45788490a66d0d2bf5d30d1905432d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6a1c7c280b998e03cdbdc5bcdb45845e3ac4e902e3e0d36dfc144f6a43807809848cfe2f2a4442f44f98749ba0173300000000000000000000000000000000041ca7a24242c2523816457f0fc422fd61b050b66242bdeedabb065655cd4f96ef0444da0f5569ce0930b2d8777888b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b29559be9c39450a939adac805032cef8ba1f96cbaf2471ce2d4cee4e12ea908591cb04b8a5c556cb13b49fb0a03610000000000000000000000000000000001552e0d859c5ff13a2b2ea5638ddc6852d459b7235adba1d9ece5337563db1ef770fa9f1cf934de7b25b9f6ba5bc2a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195aa4e6d9d38437f8aa7c0ab3a0b4223daa17bfdd4c10cffd3e3456ce0edf76fa0609d29ff212d13aa52512f7308e78000000000000000000000000000000000d1d5cb791811d9f55ae09e7e5fd6bd861b0cd27c96adf82d1017dc1551b4955c7e7b3265a8d381e99b231051a82fc2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a1570f4140505804d5e0296512bf1f5e0dcc905d3319a687d4271687cc811241cb3bf1ffa4922c3fc206b826bc94780000000000000000000000000000000008b6b4598a843a47ce3f2a35ca41399140159c2d5fc9b957eb8867cdb810844cdf3c0d4946a95ec027497b0325793df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167600db1a9daa481cedbe0fcf1072f6278d3a3ae3c440bf4da08982c1b254fc735c3b219c9c98605e1992f32f76079b00000000000000000000000000000000181a0400f3cf861cba151595b98a637d6530f73c7bdb0078ae010e8b8b6970edb2d5b578fccafa0130a308e5aaddf60f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddb2876bbbeb37e50c4d70c296845d2501c13636fa0ba4f6ecddb6629865824b17f5fbd32366ca1032c23cb6f5598ab0000000000000000000000000000000007cff62339543fe6a550ee20e0603c266e09a30834d31165e2b7d9e63be328e7dafbfd74838d961d6a2c73f074884f0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112381896388f90d65520fdc925c7893980f0f05f93334d312486234e0c4e7b8106cfb4f42b80b49ce11e9214bb0833f0000000000000000000000000000000002d53bb9e60e1ef98e353205f61a2e42a3503358c8d92242392a28ba6be2b18560e142734348dca32fd693033224b21a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539505d4cc65aff5b9bb9bfbfbe3b9da5abdd007aa24515d9326e6b754fbb60480f1b362f90ca44fcbba01377d1c5f4000000000000000000000000000000000b3f19a0283a444885a2247213f341c6fef72c80fed62267b812cdacbbf90bcd82af8f4eb1875d9669cef6ea0f3a0f0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006388d0d25d15b28dd926d9f3c3a9fdf56940489aac2c0a0d54f03c2e2699ef4a9d5ead9f71e5cb8c550c5443a3da8b0000000000000000000000000000000016bc859ce8d49a91aa2a703bb2d7be212912cac8b1e48b8910686c1cb92bf7c4ae8300864c011f184b95041a64dab8e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78916b232617ba4043d3ab46a12ff26442d529aedd991257571b5afd27a13497e801bfecfec7e8ea87abc67515ebb20000000000000000000000000000000008ff2f32d68630778bddf9be2b3d0656e2a5d2d9216f37459c69270eeb33a5cf6237e7187aded023deaaba577f7a9c3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142bda0f29d6c1c59c613914b18c455d4032c10063e11aa5b34eb29840f506fecf36f3c967e1c974ec354f2ce530c8c900000000000000000000000000000000101c60718bb92eab7825f6582fd13c8f18d6036de3e00e5ae84ffe9fad68c3934a0746923eb4fdfc797889c40ce2dd7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ee757ed311336856ba53ac652a67bcbc692fa7648f86ba7a9ad58d61ed24615782db8759daeda40d5c6c68aa397a000000000000000000000000000000000118c983952339eb74c4c84d111d118bdc9febe779b83209a0fc18463ef52560b4405742717295c4bd22b61a5917dc6731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2a41d496de0909db486ae7ca58bfc00a21c2bc9feceac02af82dd6456ee23f13209359e4951eb48f7e7e6730a4467b0000000000000000000000000000000005ba9d86b1d877256cfa13a9e4b4bfbe97d68dbe2dbdc6b4ee94c3eea5c94c648581ba85a1b98062b4d2247546ad6f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc177c333583e0b5e0cb32bb9bbf8a4c1429cdf36fd9289ab267f56a67f911f028966ddf48e18ec38b0b167fd5987990000000000000000000000000000000002f074558961335e8ee08cf740df85560b8effa31f3feb0a323714fbdabc41a46873100f2b089305779b20143244150c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9fd245055c428d23ca6ff3431508ab12b97f04aadec9a2abd52227d0dfe24d06094f440d94001deba94c77f5f74f00000000000000000000000000000000003ae73396d6a8e4b44dc563d09e02e22aeda4c6b94376597ab077a0fce443ad07887300adb331ed08f6977c4c6b4bb731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d473f29191cdbdf0ca0ee6ce8ae97ebb1e6fe037f7dbd72b4e25254eb356ee5a5a0fca6ad46c3baf79d860b7df3cf10000000000000000000000000000000009b175841a596dab5f7c7ccc502c2725dc1026776125bb25e781464a0f56aeb68211c2b1e08284085a500be2fe4fce6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001534d435f1e1355fe59ad34b4a49c134a73f72239211d0bcd2e99f73875470e994e4d27384dda9a9386b0b0411580ed30000000000000000000000000000000003b9d7ea495baf120907b57b62a2ddf555f1eac696a8b7117e6fd995e1b4428986028c6777d3cdf66c888c1ad22d0fa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ccf42c61f487c5846577553a8f859abc0032329ade6b1bf46af1487feff12ff2f07b607ec4fe5911d25b364a740af000000000000000000000000000000001176865521d72193e29435b1e2c4938de6634d1aa67b129041e3793a1fe2fe1359c4ea1ca40dee75b0ae3b0f652cd3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000547e5fffe8e658de2fb5e3dee8aac138c2ba0a134dfd547b4a5d033b23d322b9ec7fe8d677abcbb12104b7ac93b78fc0000000000000000000000000000000006a0a850573ff1bf3ae82aa8cf4642883dddad2a8d298ae0c9d6d0264cc61d7cfcc794047f93dfa1e3f3865cd9d192f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d52ad8fa14e7251acd6961a82fff5589a9ca9cc1480a1a374ff51a2ccce11a77dc479dc91267508a7c1643cb7999e2e0000000000000000000000000000000008e9af828b3bacbb6a6b8b120245f9a396aa33a374fab868e952e935c7449f3794afaea8c9914820a9942862c1951ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000732e4e0135648f4c84b6630eaffcb8ebc0cc1d16c0bb3503f54ae42c21f2eccd5e7500750a0cf718f1066f4bd4917e6000000000000000000000000000000000fafca10b5b321edab833df1ce4f507b3d340de10f4ab9dca5a624fcbacbf83027ac8ce611c9b12bb26625df8b8a23ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b5e652b6aa0d9c690f0da08927b34edf4ea38fcc3688cf403560d6ac85420e6e82a1671a5f8e1aab71cab365f314b40000000000000000000000000000000001b4dea1697b91d70dd336e6995324a774795e30e3c489b517abd785d2b7476684d5ddecd46c9ac8040bd36ad66ac0df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abd338e96cc47d6bfe6fbad6b5570128b3062a96b3788e660a686ff500dd31198313f8aae952026bcc4813636a71443000000000000000000000000000000000571d5dedfc87c1c511359f3e92937c31bc8b2f9ce2ebf0cdec8650264b48675070592a8f75b0915c5073abe92bbeb941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001676ca539d13baace8f9b334cab59efdf25a6051074e55a3d0d0d5b295c8f32a78d3b74ebe0631ccd04c4228251d731c00000000000000000000000000000000175c364a04c2b998791aeab7194951d2e59e0b2d68e5c11fec8d7efd3008b1e12208779ad3d84c294d677e1baa191d8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aca2ffc34b424998c4dd93fca3b0353fd0d742a83f3fd1075b34ad7fe7346812e0f3ef387cc02304de6d8a9387a004a0000000000000000000000000000000008edfe6a171773b2c3cebb0dc1608b747c0ebcfa1dfeb17932e7e86b5930c4d1774b5d496573526d2cf0f91fc04f64b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019769dacd1a79fbdd91b6a9c790e1e65f48df7551df4376237338c930f594c2e357d3c10c6565448fb8b154914f43a1300000000000000000000000000000000064dea8e3b87ca7c6e0c50c9a3fe0266be84fa7e32cb05ec6d92cd47a604b85691830abd3aedac60e14ee857f17392951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037f9f3d931309ad77e19bd41985423c99330c1a429497e5686d7548cc9ca64d5ce11750bf9d3518b4a7d0e457a192a20000000000000000000000000000000004d950e3aa80f8da86a900490328dad8d3b6c91f5ae69bd331bc753bcd304c8dc6426df32b92ff014d6d1e6081ed718a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f261ff25dc59cd58f178bd2ec11bba46af97081348cd36f5b9abc25cabf919e4634e5c13decca152b4ee9a19fc38cf8000000000000000000000000000000000e41fc18b3a98db5d642badadbb3cee7a51caa75bb30336668865fac6cb1d829b5d803e0cd563e13cf7eeb729f2539131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc80b9aa9c19f224c9656f8b286d463b2df493238efafdc2b0d19855a7c69a53df3c8fb067d5300c98d78bedfc2bdf000000000000000000000000000000001081013c98b98c58873eb5accbb1c65b6b4a2fd62717e0b472a10d990ee93d0d6243e99a14eec096ac0c5b448eaef0591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e11281788bc7c587e7eac90cd2128c2139a472548db402263d57e3bb25cf989df4cf180ae60e4af3d5f06e9286f1800000000000000000000000000000000004b7d1048343fef29c6caa0b3b99d56830298d53a5ff21c08b0f42cf092a53dc3c1af3bfc7be1203d965a65f17c7ebd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018db196508e915adbc208a8e865d6fa3c42ad9555040fc4cdaefc449e8f4e491176e046e295d34049353cddbce1665fd0000000000000000000000000000000008e2fc2335f9837b0d6644315d4e268a0fd2e4f7d8bd2ec7cd6f331df01733128ba7f37d3078d662a3ee3419434cb3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014783c4a9297709af354e5bde16c7b9ed06667c414eb58b1fd76bda9841fa79471fa3103738735dee7577c7462204b890000000000000000000000000000000019accae5e488a5e5bd43ab907967aeb56b53b89988915fb23f69d3613601d0048bfa9e962155de644aa5c4e6bcd28f811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000039fbbc7f3071e4a65d0cffaab8400b12a4e65a388eb1095a410d59d54397f07208edaaabb1e035ed7c1beb2f5d9177000000000000000000000000000000000c4050242a0a68e3a96741ae12e2135a4f9a760bfc704802d6f8f3fbf4c81f33e988d66939fb0e413c2f6bf36b4835bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c879e3d837e11c02c1717ced2528daeb49cc9c7339f2b15a78df1cae041de196c310839e0442cb2fb1e19530a8e7e9000000000000000000000000000000000b9934df03dd15cfbf7a08b897cffb899115e15c2da20e9a6150f1ee9561a5d1c2c126147d77320fc90bb08589a7019a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c3abbe331e153cac15fd6879e28c11eaaf795a93d0f4effbb96c0060810a3560080d3aa1b829ed7715ab121ad383be0000000000000000000000000000000003cf6e75502c72cf4af90aaf8335cd9c5b9ca58ea7344fbd39c1c2f86ca8ea05b34508021bd75a28fd890c49eb3a84b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000908154c46cd9010bd1ed652929ecc2f80c3d6d5e21ffc779935b3c2ee68b05a414e774f832625c5a237a72fa31ed19b000000000000000000000000000000000ee02036cd21a78a9e3fda568e23142493ffd40af6a44241f2dcf0398d6c5d741ac7e2e059b1b60aea7d27920661b3651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000746175511538463411609ebae42d55665532e27f7cc72fa41acdbdec00dab96300fdad67f5f97435b47075937e860a8000000000000000000000000000000001897b46a0fe8a4ee0f7a5aa675952fcd895f62fed550fd12bc093f9bf9472191c62c399c17b9ed2c86f38e9c09aead561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126a14415234f7b7f4961ce08c1e2f5c18aaf6a5643fe8cdd35483645ea8e5040b3279516e1e5392a0915d50848523aa000000000000000000000000000000000b1ca84dc81bd18c355046c637a06f6fad3e79f5e1bb464ebae2f9146e71420a9ca10e82577f33b40204f74e18315bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ed2143f8ff2ceee5f7c0ec019624c60dff32ead310363a3a6a2a4302ba533c012e1f221165eec387811e42b94d79f700000000000000000000000000000000138077561a3a47b50df6012a1b12dee3942435cf456becc9f5f2a02f0bb07e3f722c081b4c94d6289f11eea5783f78181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174785e6ee2dc015edadc2c06fa12f7b52605e2d350a2031d85bae750ef1e668fe728ce6993b7fbe4712abf10df46dbf000000000000000000000000000000001344e109ff7dc1be4e0ff92c56c24d87c1ad7ada62dbb6403650ae810b0911b4d72bfb568621fa0547645e3ac0836bc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000950ddcadd811589052a27c9202cfb690815643addad28ce53fd3603ac27487fb921b6eb78bc8a55ebee0cab5c5aaa770000000000000000000000000000000009435f3b84da69e4b390476099a29e5d9689203ea903fe85a083e9b8f69d9c2f3e8bfdd15d8718dda149b3e102a9a8781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d8c5bffb0270ee86dfa6fae368ff227f02cfd651656d2689413ca4fdf7d4508b172606ec79f96d858003ae4039252c00000000000000000000000000000000114fc1a76cf7e00a13d5a6a48e30a40bbd9e18afcddae1e438111c154ea45cd18f0c43c55cbec6b65e192bf164b3f5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000645d299d8e43acb8c4ed68875f1894dbb62d92c303d1a8f17397c6196f96d2023143fb9b7ffa654679444bb44606eca0000000000000000000000000000000010a962a86dba6e7aeb3924fdc8e1bcb71ddf261783cc78ea32632e22c8ea0e4d880cf476bf01c5bb0c9edad819d9b8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129064f29ba660f2beacbcaac8edf9db069ea9040af0c1328beabd4f22aa0775460ada37c8b977adf413a5fdaf9726af000000000000000000000000000000000015945e9a1cc0c7dc44e004a0d7e37104243c455583c650ba89b16d4a3e937713165d74d7e1ba27431eb84668bc152a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165b3b0755376540131bc9dabcf5f2eecb5313ddbe3175a5833aca0e2708ad3ab4608743f142f290cf48289af685daca0000000000000000000000000000000016925fdf22bf307f4c79df436fc6f703cbbc62222c5999cab66b3647c7932362a1899d1e4648f12235e4cc94bda8606f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001125721eb65720484c8e4ce025a5747852282ffaa074b6dfd02db5fcf35242a115118cad1d9a9353a52327f698125000000000000000000000000000000000006fc88222f75bd46d256cd51b0d7e831822f3364fb95a95fadc7fc03568a756f2194a1471b67a0d1c7223396f48ecd2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c28094f7effaaa5063b3248ad3716fe28021ab275ba03042f79eb8591b56a6c8847a865ea72139ce3d3ea16ba88fe1b0000000000000000000000000000000003c5daf1698b71e496f4ce285d543916f6733a1d680975b3111b37ccf58a456187256d001b4259b4582b7713725c3f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a70c414a4b2b1d016bf3264011b61e3ff595fb13c39ff274f71d36de4b3eef313b688d19ffcc5ca74342abb9c095b6c000000000000000000000000000000000c8818c5f90a43da2b6b83aa90643a158dfc28393e2f4931cdd38e7a3447c9404c5e16f7156ee0c64f126754ef1153201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001743d262f73919d0208a68816e52625edb7b29dd72452f14efdbdd8fdafd9d85c8bd45170a072bf3c66e4e8a18a14eb3000000000000000000000000000000000232146218c7cf14a78cf16e040732c329fea13128b401a382b0f937af555034d79ffd5e4a546a1db52f295b3d28ac281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015069740b395f97f5253898ada3660600e80f9aa0413b9e175d7168771c3e3e42f288480710210aac610feb22b1594f20000000000000000000000000000000015582ffef832ddd6a4c006598852eb3613775948e2c558ebfdf24c444403ea32383ea248076b1040ec0b3c29a166be481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a282da2e9cbf23a606d0b824d9833600b80d89607cab48b7ed0326243ff90b70a9b6e1ad13d6e25f2fd82462d43e4ab0000000000000000000000000000000000dd79dffb171851c22641e80b1cd4a44d5fc9f07e58e54d24a361aaab1a8ed330fbd8cb8884a52e4a20e348ae0903871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006fa5999ccaab6901669249cca9ae06bfd7a571e09b58bf8284ac27a884ece77bfaadd3726682fe7ba9665a1f4c52f90000000000000000000000000000000017a4801d1cd9a59e9377b8286ee006136cc97662afdfb00e57fc0ff294f7f2641cf0d56afd6b2197827c4797740e0b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aca47435916ca93d4e0b461b1c03d23a786cea4940ea36cbcb4eab2bc9a624e56369891e6fb118b40953fa53a0c983000000000000000000000000000000000f679d5aeffee26dc4c200b1f948308ea011e1c1f2aa3b55924f576a9f4a0792e44519ec92a7a7bbd31f31b0c82c89551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023e5d1f2834b61c8cd56ddd41b00b9009de594ed77480f20498bfec01aff6276b39cd8bbbc872a011d3c79dc10cf8ba00000000000000000000000000000000103dd30d89064d91c77101c101f5d6e026255c4029ec39f43023b929fe4309c1ed072c5318399902376e38567c3392601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306989696e4b04f85681594ce571923228801e99f3e464a3b1623b4f977079ebda82c0651cc23cbe80c8d881f1eb48b000000000000000000000000000000000c0081810b38f1834da22452d289ba62195a3d429ae39565e7b85fea00102c40ab20b0ac6bedffc01446bf01d05f5c1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcb596eb18d3f69bc65152705082d10ce3f25925a314c0bd12d9e0c5ddfb874223771cf95a4a7b7176361501c4c2ad70000000000000000000000000000000014b954c6a8092830afeb67b969189f51bf94a2da7a3bcd9b7b42c0e238f3ffc435ff9b989a3b39d9ca0dec769c3b6b8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bd4b3bb2e4781d4df164f6bf4123c38325e4de0bc86edc41ec56d66bc2746255d1575005c3e242f0a12d1f017b089f0000000000000000000000000000000001f821dca34b5975aa61ffbc793cce09c2e277be72aa7bdd32158167e9703865db0f14c24c82831498178750954ffcae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c9d9a961b2dab955ef5aae435c7e96f3b0f37c686215256f6a75e656bfd9d47b0260da0ae0e2b7f4944350b52db459000000000000000000000000000000000af14a1b1553646662a418f824aecec052ac5e3eaba4747e4a1ec8b7b8f32f5e2c78233672d7924352db9f512428b24c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002af4be64b52ae057b7dfa1b96a8ad8844678b538e70051d38aa1d7a7c36a8b9715992dd670d9cd9b66f37d565f7deb500000000000000000000000000000000133e9a600d959de72ec7174f77ec998ef4890733bcf231ac781e4c45ec3a323151ec2d466fba636c3a9aee3edaf5adef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b87a1057f4e551a0ca8553b19717d751d63747225ab595dbf242df2f49eba09dbe8d1f1bb2df7879a6753bd76085e70000000000000000000000000000000015dbf6e786a4182858650dbd4d61bb39c3a4756d42527423c9748c2d9c04ccf24ad4409cf389af9b4ea55713d92b149e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d938d1f3e39b9eb6bb024a726befaa15a894132a38f835285ae61d164ecb050689fa38b8afda095b2494131cc24737000000000000000000000000000000000199166ad2d50c43c496bdb355d55ec25dae47bd5b8514a8b55204b6a407684db30a88d0cda6943db4e9122449deb71d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ffed3a502923a0cdee0001301907ed3e91ac6598cdc602aac5d295e3b3da62c720498e535bde3726de2ad52e1a2a9000000000000000000000000000000000e9aa6578309e7d1a71ccac1da24d37310801020b55cbf0c58bdab7a7ccddde9ae1952b17707dce05216e59da6ef6ab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe95a99f180d017d57b30c962dcebe63861eb0d93cfe5f50be8e41cd8af8f65c0e9cf83c2ff21cc5910891fbbeebefc0000000000000000000000000000000014d169be60848ec8b48ea05fd2cc84a51c18abf613e08efaf7d6fff38d2265f03b5b3fd24b51bbf1efe80ee4d7ba473e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcc600ef376aa3f0c003cbfd8ae0c2aeb976bf3cac9d1d81194e0b2db1a3a4186b455590ffa94ccbc331bccb9d6ecf0000000000000000000000000000000017606e7b18f12ace88c4467399b78282e1f201da409233f20b66d9c9ab2ffb31202887b5bc285dafd642a9e89ac0a53b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092736594e2eba4784f87da49b487e94d9c0054a5032b57e7381f7cd08544121e4f5a74e7efe74ef997093edd745af35000000000000000000000000000000000349a2ef6c262f37691072edb1591f9586f8983abae2d7cda2d77c7cf3683c86dbd32cc0ec25cbfa2dc46840aba8b3421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c526d8ef8c924fc55c756be87da1de5840f63f6cafdb2ba9e1da9837efa602c677d1680cddd948266c958fd1bbfb6100000000000000000000000000000000157b83c5be8c49424c444362dbcdb5e301a37ca51a795696eda9b65e3ec9e062021102a43a49d4440ce5317682f94f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002596396344d6bdbd642648aea4f33fa8c8ed14f0ad44b801ff0d361c10b4c666d876495ab0ff6482e930d0cafeed983000000000000000000000000000000000bc2c579af995417abe907e1bc51f5a9ce3aa19e35fa188642c2d0ceaf1c4460e21c498d35b78019033e80666ab1ab671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001294bbe57bfc324e73f9d46028ba61b681f2e28b047f952dd15315a11967d03a5ee0bcffbcd50b5f04bb222f88549f0d000000000000000000000000000000001803915af476cef3ab0b861b6de485bfd8ad9b165827b31ebeabe77c69ff4bfd951f241da59922fa90a8c44d18565cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c4f34adade99d3b2ba56d3fe71bc04de25eb1d6e89f0fcd052555ee9730133768b1d27ab04c2626201a46a1e8e69950000000000000000000000000000000016aeef79f5c9c2441994624a25528f337a94b772fda1239459a2285fd804cfc34c9423cb0efb2ac28f6dbfeb922e54d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178764d19668f57efe5dda5ef850a52b8998787262888c971f0b87c14231d430978240a507755df9f3df325823f4c782000000000000000000000000000000000aafc8833bbd099c172f3199937daced1ebeb036b568db5dca0245adcb5a41466301d57bc658ed2770699326360fb6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89732284af75f0b00ba60652e0b30b160b61a7248b87a44c6007d13b51f6cbcfa23a6f5f392fae9650d3a6a72ded6b00000000000000000000000000000000055df8a7e8bb2e5267774428695a249450e44bf191e1dccac007980fedc261991785a850319e73b3b5433bd5403de5541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d5d3bba8c9f45634da77af07bfe104db7fefef40fbe082facae4ce6d00ea2390a506cf05dcd6acfdf25e663f56095f0000000000000000000000000000000016a59aa451d9f4e62c719a9e8d914fe8bca8e7744dc68e860e3e9ecb5ad2f9943050579fdbc711406213964f2231ccc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385428013d8f81e65d2c318568c304451a611ed33e83b63557e1911eeee3c513bb33c6a6472964bab6bf1fc01f5ce84000000000000000000000000000000000c24a17eaeb3efaebac60fa72554fc409bd58e7460cd03c7a339ab5bcff4db2781d674618a41d5f0653990a532e4bdf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000427b896bbfc3cfdffe6cd45d52fa199a4cb00b82e2b7dae09cd6a40b79bc3543a3a736def66a33b812579dd27e1cf57000000000000000000000000000000000b9bc65ee5d2876e6643f64e108c5ff33f97323dfe34033cb74dee1b2d7dce22ac00523ffe2067eb14d5b304dc7759fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cde14008e6604a7ef648dcc6cc65963c63f10cea8d3532a996ad6459e5a98c5dbb32e456740dfc44b4e5e6e4d297c6000000000000000000000000000000000cc3099031b2a7238d391d4e42b9c6e491a132ab4f5fb931c395100c9dd93950149b77011c010323fad88cbf60a08aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf05fca93fcb755b2d62986b6fdf81e470cb61d712fa389f4fdfde4b037a40be6d8890e312632de8434d0ea755f2c00000000000000000000000000000000017294c2b8d346536d4aa96f14b38f82a6a2f37103f09417fa58a0f890d3ffd53fe2fbfb6197b09b18810a87433d071c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000950f1ff2d698b9ad82428f878cc58e8bf76bf86851f79758891f1190e7b61440ab7cdd4b190cfa9a9f6bbd1762b682a0000000000000000000000000000000008637379a889dca6ab39f1a4b117dd9adf70b97508916f772b799fab9be3ae53fc392cecc259b4c58b0804eeb29409ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001406dc561b9762fa2a902f38cf4bace57a72e8bddc4b7ce096fd258debef773a3f98acf9dbc744490311fd88453a0e450000000000000000000000000000000001c3b481b056db9669640b362fdacd5b788bce16332b3f5f680a62665db7c676f8d2a6b3ae0c378ce687350f40269d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f24ee4a62d0051d991f9f21e62537ff59831feef78e2ef917bfaea1412db8a328f11fca5e257289d46ad2e4d95adc81000000000000000000000000000000000d7b3e56d18c174d23bf08f1ebfba02a49e80d50776a1ce5544895954e0648413768cfbeab9a3be97fc361e1a7a961bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f37fcc8aff701f7577aba494fa5e12070d7908cf36eaefe6a69ebea5d0c5ddaa7bb2918467ae33e5788f4d4f24bc4cf0000000000000000000000000000000011adbcd33692fb2750e2b2d938c8ed2edce5f699449ccdf8ac5b8f330be3508cbc32bacce9d07cfcbd97a4abc48219f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c873f4b93312dfc235afeae4a123b9e4f24bff25975a3f14ff925eb73d00e78204cc3a82021e32dcedacfd9c91db080000000000000000000000000000000006dbce9a89622e0f1a3661888f3d2f69a15824209f1cfdb01807542ab82d21f8c3df64302c8d1815ca94383d8a17ecc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7138cbc0c40a165fbee5dd12d5640bf0b28147a3147862fc7d3cbff4e92b27d1042221d387b5072e8263171e6c24c600000000000000000000000000000000042b5b8785ad5c14a4494234542b41034ba2fd008e2942f78e0ddcdb44af54aed8c79ce52b1cb1f0ff931db80fe4e70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d0e1411fbb446e6916c50127bebdfe6dc106314f55be1ea5d13840f07a60769aae888f4718607d83943c634c350970000000000000000000000000000000018db45d519a981be6021fcc3942916ea72dd80407b679fa50061b899c789b87a010654bf0ed9a5875f2bd112cda25f641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5b813aa47c06f21b660584d6422cb3f2132fe8b988855c418bd43ff771989a06e41afdca6a2d6a8273750e94c563a000000000000000000000000000000000b6a8644067427ab5ebd5b8fa30a9da8ffb0d60119de5634a6db20684ced1de5d5f058f525fef24d89a483f5259c39981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aac64751f021f7cb5b3f80a3ce5437b7b03f79125e05b6900791ce938fc4c4459d90d00ed1e9f669fb0489f4929ca20000000000000000000000000000000001da0a5c2eb2317373d59fd16d4db0edd3886d4ebfbc9eaf19c2642f1f2e6f3dcb44f6a0cd7ab238a842b21a8348925a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267bd2a8e40a9e9ee94af1fa9fa5d7559ffb98c9c8135cb382d97fc6e66e6488f690e2a16344c4e5f48aedef29d1ee90000000000000000000000000000000005d75fff326bbaae44d670d52bf74a8b02534de696bc9eaf66fbe17100ec8408be497044abbd0dfa2422ee797a949c341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c261b11f552bda47f8af49386ca4ee973ab8f477974ef1a60c3c20838e13e88940576a5f94b7d1f58c23ec5a8c86d000000000000000000000000000000001676b9e9ad2a239b033666b5a417b4210e0c9f8037310d3f0f642cd63c62387d656c7e13f221b501f35736915b50663b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f47f01e087a2b2eb701102aa920b67dda1d2595acd813b0a9414d0cb37769e2ed9fc0aa6bd9ac5d424bf038155505d00000000000000000000000000000000068503cfc4d79f3032927c8b0e8f54030bf2b9f83979b0da4f7db5382c928d08723038a8247a157289e796cd983156c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a01a80ef24416999f9cb8b1d50753a607fd87713637bc4e57ac2b49ef668c0b9ae5ee5427e4c616d2d2f20225419c200000000000000000000000000000000055381c235ad7a7814a04a82feaef27c7645c53ffaf5df4fff5b3b60eb0931530841bdc527854b23bab51b354192badb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7b63bcf9a6025f35ad029eb483bb48bb51291dc82e5689899f75351ee2fe6ab927045c196cfab5815ab58ddcdb58fc0000000000000000000000000000000009c25a6e3753b67bc87cc25f4679774b6ce00d37e5aabe6caf3c4b58cb10ad1ac0d96e0fbfb20d485f9a853c9de791531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018616fac9052ab534418434683983c7b144f2b7622813ec2c6739d7bdad6d706d5c72d94380cf3e38604d7a3098fbc340000000000000000000000000000000017c19b62f47bbd0197cbb33d813e8bacf464adf82ab4f6fea6269f5609cbe2275db082e9883856cc8b0e1b577e13b1d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d73266155d16e6dd44daf053b77bcabae22ceb19aa8deb47143d3593d63fcc30b2e0edd146021bf00467824f6f110000000000000000000000000000000000da0256ffed3f387e8171efaa335ebbae211244886bc586bbb8d155a0ce7374bb6bb9d8bfc286638337ccb6d3fd920791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a9ff8d4b11234eacb6d8e362f2c800c03156057303fcb64fa18dac3260d8c0e57d10d42ba9719117ad2a71cfe072000000000000000000000000000000001757b3d2f217d5070673b78b49e6e4f33bf373021c6c56dcfa8b22bdd66cae266e091dc8ef14ea28528afed5d8268eea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098530102ab318cfb1d126c670c03319b0cde6149bee761ddfffdfbbcf2dd608ea671cbd91b9f02420df44ca3ff7cb8000000000000000000000000000000000048dc71118929473206ff870dda9db6d15a727b6907b1dcfdc8e350df94dc1042adf295c44bf632ccc348c0d94ea62981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aed1e6e862dc2316fa04049a064f4771cf6c03c91b5e1ce72d6a20bc0df8c5c2a9891ccac5a15fd56fe1e2263cedfa70000000000000000000000000000000000b140c3a50c6082cb311ce8be3ad09440f54a732ee26e420220f18a1358fd1f8fda88729e4a0e8ac1e25abd93de43ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008570cce293e71e2efd6cbf757f275b471beb92698f0088511834a9b627c146e1cc62f6f1233586501db97aee6c0beb40000000000000000000000000000000011510affe010d23cdfdcaa4483672cdd783eb2c91ea87bc9b50ea26585bca1c892bb783d19994b2a9d244e37065b9dca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c74029a5259eed3d4e6d816639181184dd4196cbcab69ec66e61d53db7a4c4c953ed9c605ab475b4f67e9801839d9cb0000000000000000000000000000000015ceae837fef73b1339343be14e36d125657e78219d18582c32a65d2af856314e6560c5d10a2e260e3f821ed60ebf6c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009810aed331821fe9628ffdd22252723f68c8f6e5ccd12ed91e0620c9ef03cbf81a02bfb27de0885ee6bed5671e916c0000000000000000000000000000000000d981ce8a913c32114115ff0ec28cc528e7cbe77b351bc75cc842ca2d3ec6907214b37dee36550d86d63051dea0c40521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f41ebf4dc2a1a0b6ea0145d691adcdd16da47323454bcc598dc24cfc99cd13e0ec6d1abb7186c8bf5bd196b949bdc300000000000000000000000000000000193663df67da9390502458194a10449e85212207af0afc7245ff917e4388ad4b52ab5f15452ab55388d40a91ae43d1f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073bd2bc68a882d64e355236eb5a8e3d3043691e97b1882f02624de9ee9378148c2245a720127af9053c6fa373318cc20000000000000000000000000000000010f587c17bd131b4720288281b08b34777367b8d045ef908135488f2a3685caa07e22ec653db565c6c5024d0bb9ff7c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139c00a3519c033c7d19624a171b205ec172a663469b5b825ac4570efa77e0613a66e6446d0848dd73e48bdd5254f9100000000000000000000000000000000008e0da7802b823a49f3ca30fd9e8c36d2233a1d519ccf3877ddf841b060c4b068527fe8a69744db8c2d1173998a7dd8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133c435ed6173adc2ef341e3e1359432fc6963c9df17ea6df67151be27b5178adc95bba3592134adda1df90a59302963000000000000000000000000000000000629836b1c908aeca28e755a021c15e9b34bfb6aa296822d9f5d0ee74d6883036878e47d202c62c1faaa4e10bf6b311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e59eae1c975d87b6238671ce5d0e5ac55c5780822a183fb083ccc042b9b5021b5485660353373730572704934e42d000000000000000000000000000000000ff51161a3a473ca78820bd23174a058c7e57e855e01be5fd7e234e0879cf4cd268b04cb7abbcc58aaf4e7ebfd9d62551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011143b11e7048bbff0d0768d5d53023f72d1828b6fab2a571afa9e54c31616c63141488fadefd06fbf40b6777e8bd5170000000000000000000000000000000011f56cda8503ab79579457ded3da095de9ae40286b1761d566558f1307233928190a6e44188f7a1490ea74c645816c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005cdfcbab392bed9af7a163296dc0e03cc322bcbae0312c4e90470bccd3a8c7ddc2410b8e67798552514f173a54dc0d000000000000000000000000000000000b4e42558c328e8e6edafc714ffc8119bfffd2a707c67cb76ae4cabd5259baa6870a6901431d6af743ddebb1fab472cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c541b69431810ddf0d36d9aceb1e489f1150eb7ed2a700d3c629813fc2b5ad70a37243f32f6e0904e838f5adfaeef7000000000000000000000000000000000a16949686065925bdb2158102e273a567eb4fa17f4bb5be9b5eadfcf9d7a7853bde3c379b5273dbf080bea9f07d667c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010763d3a4dcd76ef383ed2a286aadb321c632d0e8131321302ca4bce637f1ec0dc421a135792b1dbe8917b46331667f1000000000000000000000000000000001920adcd45120840b68d7cb59de44f14fbf5bca828ef421d40925bc9cc42a6d7f6f00ea48a972faa81725b5183270bd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e9614cd67f9fde907898814ae4ac7d0fbf4100f2feea3d7d49d05baff2dd29c0e00fbf4a5c8d16d953b76dd497caa00000000000000000000000000000000130c74a102c92a2bb442ae05f782ecc7ca2d56725df95f6bfb7387f9579a31a9c40ee9016499e7bd1cca3a3bcbfe168a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072b8012a3d30deda44955b8edd2d5d18166f148474e1113034909989188da1795135af8d4769aa71d04ff53e166389e0000000000000000000000000000000003de9c26320a159e18bc6846e00af52b78a60917b829e431b911742c241c0c965dd9abe214949f620faa871c98b664d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001abbd030cab8dc9c113521600af533c759e50ea1870c79a891ae34f15687c907d2d6d77a46fe5d8277401f3752e137500000000000000000000000000000000046dcaaa8a7da0498b7481776da1aad35075317d106a4635de4d9116982149b0bd388f37ad3bee5e5999d2b750cbd1f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa47f2c5f1438f9e121e7b09770cf6a5b3d7a1522040da6af843581a03eb5ac6af93e9b970500f5dc07af577e8874c800000000000000000000000000000000042ed459f246188a860d20b20680f9e1a6e19b7d2d8938a4a3646900506b09eaa9d67dbf54b35019a6d01fe515d243271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011daa6be4c418480f31e415d80349cb567f030a64e6b183890ddfb1d690ebe01a40c83584ac256dee1ca58d3ab9375950000000000000000000000000000000015bd24858629156c50384d6cb1507396bff8e4dcf8b035a09fcfb4ff40f7d2183cb3dee9c8c17fb93048dedcf85957581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd700cebe3fac881a8c5924e7f29d9d135a58c8a23208161644414638db73dbc7bbec4ea9711de9619ced383c9f0017000000000000000000000000000000000ce131b4af6c881250c47eca0e1f3938884c1aedd7048e990b8ee9f09d36743ca2ecd0654493c2e2970bb55b94d070961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018361375652152eb1495002264e1927bd90aad00c3d82a32ce96f1184a1f2d744201f4f943ef6f717dd6b96d3af50e11000000000000000000000000000000000e2eb1cf8d8111f0d614d1b5186ef1238c57c3a3907bfc23a9f98d31de07864f49eaa3322ccdc4128fdaf9b2e5fd304f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e312092d487a105d3a962940c6e84c849ccc34273ab9228ca0b3c30d4b2ecdabeac9ce9578b174993536087fdfa8e200000000000000000000000000000000164815418fcc5e50bf4a7ecabeb8ccdf8fc721ca4ba24af54cea83026bf0b10d35e93e8a3ab4ee51a456db89a11727621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000369c0052f210617a01181ede90aee47bfc4321361637109b09d59035b60a34590107768bf4295947436dfd2cdf9b1ef000000000000000000000000000000000dab21a273c8e9b87af07f1b19fd7f5216763cd2e04566b85f4de1b10b1f65d458d0d3540ccb35027b549ef0e312c9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183b501f63779942caa12316fe00479745a2717fc8502509c2fef2b995b1b140bfea106f622fdb000d917558adc2784200000000000000000000000000000000101fefd8dc66885cbe039f37777446237042aa12f417b68cd5d5942a6729f3ab941bd409815e6d5c15d21b65ac0d42941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dee3988a8410062f0aa41c28cdf7807a2e43c9cddecc5afc970416f37838d06ced979f465730298d33361a60a5b66900000000000000000000000000000000078a53dbe04a7ebca62a0dd6e21766a2dba416735dad9cc35b2b7eb7798a0202f29d924583519552b9082ce311fd313c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001742e2c7c336bb78e8d568ba6a5d5d3a99dbbe21b8aa754319b98282eae2d318e0237c7928bb6d91889dc452a6643edc0000000000000000000000000000000019b13d8dc3aa9108af620a5045b58b163594f679510efc725f35d4e028005eecb217cec8fee5b4853ed3f5e453fd29911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002857f6d7065da9beddc64cb6b7e4fc0208a4a2bec25a77c7cf80749dc12baa8cad350dbb5f5b719702efde7b353e005000000000000000000000000000000001687a1d1c8fb22dac02a67bef158b12cc166c54f92c5b09910b7d5018325364a933fa77bf419f6c50c86d7fb7c741f921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c80454cf14fc2e38885ff416b6b15dfcb4c71b8501fed7dfec7d820898fde9ecb75cb3d99186db1f1618b98e0595d00000000000000000000000000000000103be57ae37ca5d3260e091f46632ac36ccc2e8d21d7f916425610c76431eea6984101773d5e97ba83d5ec389671bcd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a944bc3c69610cbcb0e30aa3ebc86c331bae14b3786056396b4eaa89b51b700eea0d989613bc37ae341788e3c91a4c8000000000000000000000000000000000fafc203a3e081cb92509e0701d84c602d4408038ae24a04abf377956aa40d7eba65041b99250f06880c82bf659d72811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001629c8bc95f143c205152c2aa4ee97a56f09122bf91d101ac72ee254dbf4acdbf9b91d0e350d81f15acba2c804b3c91b000000000000000000000000000000000c76ee1d073351a63a3f080e8ade4dd602014b1716cc68732a9bea0dcfe08687a01edd8722a26697b3e6ddc7ca6c58c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b0d7d1bb038e7dd0b17f3c425460a9c2254345f69559b2de5f341d07fc3a32f01b547777c82dbb2e6071a02d7e7f7b00000000000000000000000000000000161a7e2ae3405b762b06104fd904526a91f4588c413c172f9562f3fbca340fee3c13023d24ebff0381a641fc4388bbd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef12e1679b88aff313fa2426642fbeb62cb68ac6605ae33ebe0e00ca396ff3a8bec7254b33360edbf7b14214b07cc080000000000000000000000000000000000b436f6d2ceee3db3eac89133b4f5be31841a7b0e505c5b2166379abdbddb7a7e25de447ebd698b50e256ffff43afee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072084ca44403d9cb942bcc1618ea4790ffb293d48515f5e8e489134273162427edfd6ecbc7d5b2afb3d06ec69b0128e000000000000000000000000000000000a1d13a8e9789de0320dcbd43b0a2a80212b76038c154e213cfa018360ce5f2ddea6384e4d119f52e9d5493574aaebd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104ee685e35e23a581ad06f24f3cb98fbc8dc41887b02466f60f05b12534ee63b98b05e359efce8c0670303d6e5e0b4600000000000000000000000000000000146f6b774e1e3a42f8e009477d25ea3203ec3727b2bc857d148a29545549d707fe4724fa3bcca306f5645e718471e6b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b7e556cf2eb7b4bcb817c7964a11c39738820bdb41eb2d0f222c749246d07aeb1a479cc7c70c81529ea5c1f2d46d510000000000000000000000000000000003330e67685649128c5fea9dea20ebcbe698557740481d47a09484dee09e0de9e26a7dd9c4b771ef8d934b287b83aef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031501aad4279f50b369cefc0038a7811f6f24d78c8497354258696770062c591f0a8156fd2720a9d25299f8deff57f3000000000000000000000000000000000871d0f5d69923ad1c724091cacb7d49a8c6c231bd66c94b4ed2ba729201dd5fa41b35de1332fa47bec780b6eab5656d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd1a92967447ef8d58f8646edc5ee43353a24d7fc412049126d164b348e2e45e85464884a3c9fce9051a7df15c778ea0000000000000000000000000000000014240846743301dbd3b3e8198bcf6313266e3b0d8b959201efd434e0e6b6e3b00c07402b0557cfc09d0398ad47fa69441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c321cc923815035ee51c1adf2693f169486e23c7be995867414c6347f2f402aeeb7615bedbbb2955e22f10b28789fe000000000000000000000000000000000169edddd17968dfc019b989aa529337fbc6fe93d841d39db96a64ecfcc5e4f3283ee6771f5fb46b40d1aeebbd1432961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180a8b800a722fdff99dafeee24e696f5bd3ee8cc43b1c65f74fd3d6e0ee08928dad0032b86ff4dfdaf8927409aa796c000000000000000000000000000000000a346e071b757beeb12e187faa00190cb0c0cedc9b291b2201937a8e1e48a9ddf5172a4456f6ef63876e77fa195ec6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011389a42c8494ba585cb22345a7feb47e38049960842f108604829e1b45694b2d1c804fbf85cbda092f2df7bd2d7ca1500000000000000000000000000000000121bf878379dfd6272662975bae1c9c6a5715ebe624e8dcf97a296d22d9db0a9280bf7fff23a55aac91f700f3a95963d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e522229006e9faea36eb4da89afe28277dbc76dae0e30c07402484dc53c9ba754d499403ce70d3b78c2dcf595ff6510000000000000000000000000000000007ae03841d24a48acddce4b902126646befc66b8870edee94e307c4d78b8ce69560ad94813ebd1424df480215fcdcc671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a63ca7d71bbe1c3fd80879cee32969f90992297a1b27a3ace516a64317e50eca6589e277b4b76b733a9a169c3cc4dca0000000000000000000000000000000017d0de9c4fed354fedde304d8639a9cea59cef0a60db729e89381c8d55552f8a3e7429a4856406171dddde05982f319d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001205c786a95dd3a559f643d9a41a0bab7f92064c77ed33070074f6269d9ab3b9d76f77e5f1d1df0d3773d13c2e2a442800000000000000000000000000000000074f31b38260754059ad3a0ce3086286f1224c8bce830d670d1b15397f7904b3dab3907b2a4e76f99f0edf09f26b73401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184bce68052d06c341b2c981156dc72e4c88f0615da6448b4063fa35ea54382a1fd649b6065d5471b4d4be59149f8ba40000000000000000000000000000000017c77f25fbb60958730b556c3346250b3743824f14b18f3808fe093e86e29e2dc16fff60d32ab55d852c3b186e1277ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a470cd7453757ed6369a1223af5f50398f5b3678c70d9acbf5f06960a9f9904b1675cb5961d34dbf274f03f05ffcfaf00000000000000000000000000000000043e5a432c001ef4774067736c9f15d09c304c58408a852f10d2c4c439035200dcfddd927cfcf543974e306c9cec94ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046dcbdbfe7e4b90e6dc89d8f167f4a1100db4e75ae8dea976bfc7787fa9bdc467a4f3a385748821ffdb2255a10b72280000000000000000000000000000000002156f571f9dff275099b599192154ae5f4a9985b04e576b9716dbfff904ab7586b0b8eb24a8f571ff4bb4d47cc40eca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000765b82e13b52e76ceae9794061c755260684d7e7615b2f3a62504e2844a6cf85d1d7cf6fda39ff9d17eff15c805c93b0000000000000000000000000000000012c71693dfba217039a10281bbb95c59f0b8d4501707f534cb45a6144f1d44e6a76a443962ee4dc344ea1c36f8d2442d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007308bcb2fa13d30cdaa806c48b4bc11d6423d9d59f7ab78264df7bca8ee03b892f6e9b6813468d01be0432682d755ce000000000000000000000000000000000ea33f2c2800dd1c94841f137c9d2877e63ac4f046ebf3aa4f59b38811f55ccfa4d179d42a4c3911e102ed36a7c47e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8bd5681589bb083445fa8aae38105ad7e448b6bc2b36a1bdfc1748f8761d24000298d6efd37e67f75049cbae72e9c2000000000000000000000000000000000274cc3ebdac9d4c053bb5ae71a03f731593a0bdb035ac1cad406bbcf72cb90c8f4a92a8d8589f1628e587346b83744d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fbbd7941f6ea166742aea1a88f61c217210eafb7e6a2b3faded8cd036cd1c27814f4699094651493f96c782d310de30000000000000000000000000000000003b9fc99928023c37015b34017451ba68115c0ade22ce8249e51ff9b7d58b24ad1e38ea0f4cac043b0aa8eed1f9029cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9f478bb0b31f1b527562e83da937bc718ddaccac3b729e03c87c6a7dcfce8d4600fef84d587eead1a0eecbfd2d7de000000000000000000000000000000000714c6cb8c2f34ea9205b842b8278cc17843c546a82bfe012dc6160156f41c3aa7584fe2925ed6d11df3edc4d4d16c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370df9ec561e69c902e9c176ad0e02332e47404ca6981bbdac3ceec171f61a5e9ad9dd94589bc654f40651d81d0a8a4000000000000000000000000000000000c12ec9143bd0915d1ab80fb1d5bcbc5515473ecbd1a0d393cd6ce1e781b7cf302796e4865405093c89f1ed5b54ff35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8fd577d3e12d6bf87471876099f81edda275bd7697cba7876bfd58bb1478b8ac59d102bec3cd658f22aa2d613ac3f70000000000000000000000000000000019380bbbd7b532e0c386058dee1cdc36aa632679a5fdd9ade46ab3906e7c021bf6fe985c8387ec3485d64cc2c515ae1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036f96bd1d34c0d46d116256d2983c32081af467cdcf7c73c6c9042dcb1b57aa867ce0d3c4531198ae05217779ea734400000000000000000000000000000000145fd274b536bf175ffcd342a78c9123350b9520db744d6c3b0852dab49afed7b1704b07e4447e9f0ba5958e7a9350101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000336e2290bad016296807e7a46b8246d32edd8b2b7628ec2a38d86962af4cb939e00bcc08eecf8a1c6418dcf3bb86d1000000000000000000000000000000000e473bb5585fbe385d325d761845d1170d8a0116a676a11fcb271bfe6a5adce5b74b0ab2a54fba2fdadc75d3dccd11241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a59b1bd3cdd56b4c98608641c6c5cbe54df9b25004fd4fb79516806b95d40737b1e0e8fd06216a0d91d81f60b9418cb0000000000000000000000000000000007455e41e85e846e22ecebc65737b945f250f346941918f80b1175b4a5ec0a927050ee7839c3d5de9d68773638bc8f1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138458a8b15ae14c7631e2e59ce3bdc8926594f7903173a305685c11848889819861a26250c16a814cd5a005941ec915000000000000000000000000000000000ce62fc63c148b02ca63df1a4d2167d921bfd99278cf4b235613d12c177c7af3cf4149aa91db68af26118a272897d6381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b854dc021681d4b0b52c499e00d8e8e7d614950e03f4e850270a5243b6fa8ec35d5349c5cf2804b1b0235c264e3210000000000000000000000000000000010699c101af4855d9b9963240c097323ff2f4f01a50e663f00c3911668ef1d9773637210f1315c9aa37a52b1a72e662b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e32cb9667f18134f018ec040fed61571eff27dc2107c03532faad6aa3bd25ef2b63b2e3b68c96503a5bb63b29a20290000000000000000000000000000000000a039b46f7b48303191a6b1a5fd5409c02d492238274159a0a6dcb9c3e06ce3b1c76ee3582fad064ef9ad32ac07639f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033d7bb66cbf5094df15820e69ec80e63f3bfb98671015a440548382549d934673828a1b4831112c76c81c4c6a032065000000000000000000000000000000000de4d3d1acd6f7828621496e476890f98f7229c66cc2fc2da963646f90c45c553f37bd17a53afca717011b33641166061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001503020b96ddfda47a5c654d27fc3fc69db6b40fbd88ece0fd4bb36d6bf509bde1872bb25bab1840451dd5087c6950be0000000000000000000000000000000000ff371616b334737ec545edba2fa532755e7be967d115c2c129d428fb9a6b360715ce03556a1fe5fd24228cbca4924e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019562b278b8cc4adbbfcdfc460a098a896f7315751abf2ed58b3a098b99f955d6d5350bb52d9a194152eb543ae74d4f00000000000000000000000000000000168a1329b576e00ae1b69f94fd49ba623d6fc9dc98e9b26efc8eec7298e5ebd59db4e5034c7026647b44cb0f626478ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3796128efa82e44d2eb70a3b95187033d08b9a929c3f0103ca392eca46d4d91d9f0fc4dbe59a65da2c0274818d575800000000000000000000000000000000047598c3d37ab08ddec9dec5e7cd6c850dfe014c8134f89504af51920953640e87d7c72727656f36c1fb4fe7fa989fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ef60864f4a4b4d2c0645341fc18bd03df5fbf7ab00d06a0ad743faafbd86793c6bf98ba6179ca44d8cd5548bb442c300000000000000000000000000000000089da90f8b003f5df8963a246590b49a7de2c5fcd99c04605d61b0c255c929d1d2f52b355210939cdf996a1dc58135441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b13c66260333c1c802de032f3d6f242937a2f244ccd133724145c60e06e8abbb3d3d4acfc155dabdac3d8070a18e96200000000000000000000000000000000113916c9b5b685c85acda28aa0764a698912267b80e294924cb88557de710a58ae016cb5c1c72dc144ab3addc82197b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce959f5775cb29a32cc75e48c570dc76b93faca72ca6248dff520a9157c7c99475b278b4989fb344748eb3b44fa4976000000000000000000000000000000001516c2e0984bea90edaf24897cba7e3b843912c83bbc565216b592c626dc061f27a5c93018519cfbd38f902388fe07311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d7013ae671d60c2d6585faca68745cdf19630088b2cedf62eb5882eef6e70c6f53bec7ef760d3a1151daf33906af010000000000000000000000000000000005f32df06ab2eb0671d07dda2c3086d1fd78bbd26fbb2a8065717c4080d0f7224473987eaf8bce52fc52092e639402c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b79efddf383b6360307f10cb8fc59a0bbe2fe2a0df9f83193473ac050c850b749fd59223aaae8e904d34c1016e6621000000000000000000000000000000000695fb2acfdbbb2155811c0be831b18fdadf23e3327793255833a2afe005f10aa0c440ce361be5828fba939bb878af291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d14754af415218c285df7c33f42ecdb176bc246236dbf217fffa21a6c8e01df19c55b979c2c9840551cdae5af603be000000000000000000000000000000001262ac8f0ef308102969d8b6aca662d3e8d2ff45ea11539b348bf1f5bbcc69d1a99cb1823b10ba8c28888bacc980278a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016284179b880e1e08315f169460d49774254181a18c00b73844c26d51d80d8a9a22b818a6714649585d718ded941ba4f000000000000000000000000000000000f798ae360bfffea73094028c39fff1eb2548ae60381d7be6565e56270d90352325b660d5d8c736d5b75a4d531bcd3821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154fd46adebede4e361ef31aec505fa418e6f058c916b0feb74bdcdd61612386679f0236602e0bfcc1c71be5855b7c0b0000000000000000000000000000000006994b386832e7cbf95a47ddaa6b86c7d73ea25b137a435a9fce36d5b8ce9603ca21652e21cf21f77e20cca5549efc581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dd9bd4d9ac6f25ebc95aec597a6e51c4d76a18bbee3a70fe710f228f7193b797752c0f2329095e2e212c4db3f08d970000000000000000000000000000000014ea3262729837dd8cf09983549fb7836d0cbdbd737e8ff15bdd79353a6f2951dce30f5dc9cea87878e94c19407630871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109934baff95dacf4cf92bcaea56426a732391b0c0a36ba481367e832729c58558afb9a15391efade82d4121397fb2240000000000000000000000000000000013cdf5d0828341d1e25cf287866d773d087c26208205fcd4edd32aa66682613e4c0c7f83ee5fb11261852c05463e0f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176a689450ecb6a5c48bed8ec4bc6bc63020edb2162c6df2f32d4e2e33188259b03d77aeb543c6e463e0fcf5f43942020000000000000000000000000000000014032970f4e8a2d9af7353cc93a3f0522e90f8fd9d4fdd50b1581295d00899ffe953d009b153647e42674b094cbcd0251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176b9300935c4cabefcf6b46ac2617ce29a321b4e1a62794af7d9709d9d5d8e8a409874bdf71adcfee4a637090dad504000000000000000000000000000000000924478019fd8cfd8c6630a51e25ab6cda3668839a112e1f839766a097ee8207829ff0a410d49d8c3bef235cd3ed787b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2df58e5aa40ad9d5e96c4505df7904213106a88c386fbd34f994fad8227622a244896011acc1de0a536b14d5684fb00000000000000000000000000000000184c323f04c0beb118d036b1f4b3c79f9e9a5287fc79e2453838f5b71330bc68748fcc7f07deaa04c6682626546367ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4f1622be1fb32ef380e1b1b4199e5cdceb9ffdb3d9c1778df6f9c214ee079d528621eb7f444fc1b30ecaad1e4ec35000000000000000000000000000000001395a99545c848827d76ac1ae0cc3a0f97ef81720ae11c17e5a1469567df87012bac79b4af1b3ca38914060e4cb1ad4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124699eeedbdf20ace526f6254beed8dda7fc95ef4898b10c66db6a1ca351597442bf27bdccf9d9eb48dad59b48d118f00000000000000000000000000000000125a0c19547e42b62a0a710c3a0f91354e0dab66a19c988e6c2784b12b8eec76a11235320511820672133b4f3b43607d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d0ff0ff3d2c61da49a23246d9a43c2fe3d676177597a9a998cd3f1c8e700d9400fee9f79be8e5d40c7de1ccaef5c52000000000000000000000000000000000d13d47a19880b7cb26cf89437350e302b7285999901c53df3071583d7bf0b2ea328a3b67a2af5f869a068fbb375dfde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032945dd4df0b78a591b6497423ad871e203440527ded4c37d981d72df90e8c345561213c662e9f2ab19fd3c1de307aa00000000000000000000000000000000179a700329a81e49e16025407ab09616e71d8194ae99168bcaada304d1d58d1f4013f2bc5204e8f110c0cdcfccd63d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d82a637559aee20f8728c894000b4369a1c90487fa29a40099e92b3032135d10abdd768bb132941de6e776472002e300000000000000000000000000000000163bb573c0b1a3415dbb0bce0424df75d72332e93c9017b47faa3932f3679775f8e08b7001c3805cd9675228f5d7032f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167183a84509bc6bb1aae22c507b0de870bf199e58aedfe2a9ca9f3f6c07f84b18f9b8ed252327a0915e2cb3355db5b70000000000000000000000000000000009401cd9ddc828051d78dcdae3864650d4dee7352124150a3011d4b18334563f859f3d275e43f1d1385c258b3a9e05e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d4d23d581e117e0452099752c114e3a3c38abbbcd22251933d6c10aab8cbc9f00e257e75518e972c98b4a2e497b21300000000000000000000000000000000134660daeaaf0e47ddf44f9c239f94a341697411e7bfce9970d924d7f47ce870440aaff6915fff1206d65bab3feee4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bac3231d663c7e511ae24bf298c2024d90f377b43d64a183c12f8c42a055a5f6c806e8f219f705cefa62aca0d332ab40000000000000000000000000000000019fb4f8cca6b29178fecd4abb4be9c459fb5378d3b2a4131c0df364ec997fefabb974e0102e8f9e074bfba7e740b72141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2f001b75628aa50824737442b2c9e40e7f349861dea93070397f933c758efab9f23c1c0aaaa9b3b09c02fa727d05080000000000000000000000000000000006b0ae70c498cb11698014ddce164807f2881ec3a91456c6c1878d5579717bdec1d7900adf6f730af4c5b718824325141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f9193a4fc1cbb0a2f91adcc4f3aec2b0ad2c9c374d1dfb37c25232a8be56f4d27c846674148142b3c25dc0bb7456f200000000000000000000000000000000091d3665e27165a961a0cbbcd05a4d0a76f1f8e0484004b48d48352e616d60426625527e0682f119cf0765264d2c8f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6040c77a6099d2c656e113ef9eae784a6ff8aecdb0dd3422cc96f08c79714d86e090676072fb7880f8db3a19e105700000000000000000000000000000000018f42b2f6579ab8641c44ac2d80f35261e4f33452e2c26e789a9f7335e892e469530e856e4b56736287fb7dd3a86f6481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001025a2a0e6e7c6dbea85d133e7f7957a1161cfe0c3ca6093d4f4dd469a0afb4cc24270c878a48a3a7bbf53229a7509060000000000000000000000000000000005a0b6079465da587de94f9b77d908bb30d8ad6db876f787e171a26fc4c9d32b765dd546c57e106420ea9f0cbb82e3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a961fc66feffb93ca228fcf7cffb9f5d67395089cbf41b66abd82f0272ac593500c91550b918a46106149b9b23de5480000000000000000000000000000000014d65e58b6044c85846cf500b3c848f2d8a4dcaa289efe721ddcafb9b43d18780add9da5e3119d2794144d87d5d65c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007260786620db1781c952652e41cedb08248bb3435029b21f0ff18a059d4bb33f3e95b02360eb465d0b8ad65364f6a86000000000000000000000000000000000021056eae46876032568df9bad77563d0af8a93c246fdd81939e4caadda28c907d117ecadf5a5c28a16ea10689c92171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eaf228203e88a7cb20cfd33e6df7a7d27360b28e5252545766e1f6057a427afeb04cc3d6e54c68d4a8d16c2c5d39c5a00000000000000000000000000000000192b11fc12edaa22227046382a5b175da2807fc9800b4d3a48985fcdfeb3bdd925b6dd802dfc78e03c58326a9dcc1e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197f5e12269c2ca204958f523cab81fe2201a913b228db65a8119db403c3c8de6251c53bac2aa28f59849ce5e22ea2d20000000000000000000000000000000008fc2ea559ae7f8d477c09968dc0a8518dbe220fa4b5b4d23a6edf77b0c58c8caf36339854337ff1138fb0ff272a684e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083d98e47f0e06772a8a30043c675f81aeabfbcfc0e796e7a3692a3cfd4a509212da826ad7b8a611753e18d21ae4a838000000000000000000000000000000001680ab3c7a1050099e5c356809c5c789594dad01ccbdc0f5aba886118fb951ff3586beceed4a547dce97abe17b0f50bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b843f3795eb1607e9ae75523734f419d305317b1b9bbcd086721a983762e86d0c03f143714847d1b8b8a9903abe55c00000000000000000000000000000000067a17939ea352f88cde5c55006d513eeceb140ab93c26239f52a5e38ca5fea5ea79eb361a8a88b4583558a05bde0a661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5c3ae9ff09d628e73a8456841bd78a455bf0c9fd4bc3d6b156380b2f60f1bac3cbe295217851591ef77f3c2286dc30000000000000000000000000000000016dc5713cdeef34f1be00c55788ceccd28d6d4e96f208ab2be2725eb26db55ee86984d0b13be20da2dec3eb3d66d22c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079628e0c0a804e98f4b614000dfe2c8d928c3d2a81d1080fe0708d43427721f006d41c30d235fd5c7b9cd840d4f586e000000000000000000000000000000000262c752601fac3faf8a5b912136795d86a0bf2d925eda9d8b5191721fe5f025eb82673643114c6af8fa5ff2e1e39c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019fc05759a65e865c6830aefd749c41a4da41217cd1f1f12c8ed0631d87bd3361ac66bbee5f245572aca05f103cf08b00000000000000000000000000000000135a7e24a0459d43c011f2f28723f3bd6fb3a941653bb8e2fed63198fea31b3788b71a6a54bd704254452654913e56671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100bc109e397ce813adfd5e84096642aa8676264527f70d911d4268f28c07a340e16947f1d547f6d94a03bfc560104bb0000000000000000000000000000000014f872ab7890121018289adff4bcf9d2506227edc4f306f301eef95ae3281d851d4339cf8d04447fcec9c33b0fa49d481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b4f6a57eed3dc147fb54ddd5da3ce00ae476f2798e7f1804abc714b6e049bb32aed30bba5a6cae452dc07a1bd657740000000000000000000000000000000003dea4a75ed07f12b51b1d0122650f903b174be68bc04dd9d75a1faa62522fb2ae61ef2d74b5a4a5b9271665ad1c4d051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001102a48bdcd0d19659fcdf51c192f1aa8ae9dc3560b0e705a934c6cbefd8f298b36142eed377aa4d4c76111004c059100000000000000000000000000000000007bbf83d19c0bd4617b89d4bdf697c26c8fa6a159510cfaef9acd399fc18ef93e8397af9c07bd6502389082b2603b4a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001505408d585f287714d93f7b3106ec74fdeaca1748aa28ba0db788e377489b859068fe858d02a13cf1a97c902b6551100000000000000000000000000000000151fd7b1e8320fcaa9aeb963765121173179b67b711da8f26d76e5f663eb9a997cc3c5bbd6a73fc9ac6c02179061f6421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fcf8f4828c2a94f384d277e60ef8f678b4fa37a5617d9ba94962851a0701f22c887560a2ef53c362f48a8483c4c7e40000000000000000000000000000000019613f6a81ca13b1caef16050f368aabeecfe837a8991855f9f0f1a1e280ceccfc0c9106a225a4a2a30f0445ca1556531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c566d1a302dfb6e2be730c2b4bb665a7f6c9f034c62b7fbe0a5b01caaa8c14eedb6aa0695ca3ee2e4407ff648e3f00000000000000000000000000000000003bf037b5322dd80e1d0776aa371f006adf30cc84d04bedac51a6b6519a104605d97a0e0c2eb0d2115a6b352466ee2881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f0bc4548a92e7cacde86faed9d6b217e33c116d9c051ae67a65343573fa3b87a0b27fe31d0c98eab7eb68abdd9393d00000000000000000000000000000000004b2749df919104ac6c553641ee1f86092bdcd3f7c07df6c13655b78d1dbec685b3fb62014b7c12a8b8b05b5143c7491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d709a7ab1a9e35c381cafaa2f1452bc6896a26d2e9969b39ffbf81024c42eaba769a028ff2ad2de0aab544e61eedb100000000000000000000000000000000007c703ae78bf8fc80e860ea804e58e7b828d8cdc3eea2a2eef85b0708bd5ffb6b6026d1806227f58e7badad2969c76501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134667d45b0ee37cb354ef27c73ffa5b66b1113db69590f24ee1c1533e79be9b33aaa7f4179cc21ec8e2e2800bd78e45000000000000000000000000000000000986f4ca56b08606dd7118600a618904a6b89041404eac0a198adf9d31c4aa5591b9f9c5ec8f0569523b64787440a8ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019155b09b3e8169272b5291062d13f353dced086e78b524e8068dd048b36d05e408a90016ec0ed803288152920aa050000000000000000000000000000000000103765755b359fefbf130b61c8a129dbc39082627a6db013f4b6e7b4ae6a3ae8af6059b45dbd5d6e6a4d8bd1f8aa32981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dff77e842c8700d082f7df69e3257315c13260be1d42e3d81741a3b3e5595e73cb4c66a52362e69f70b91b475b27680000000000000000000000000000000003c936edee5bfca30a0738e344993be1072ed30135b18de6f7b622a8ca5cb05635c54ef16a05ebf3ce3cd1d4c40258641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aa88e710f0365a87180019f3fb321fee4de04f33a902cf05db964ed398d2f89e7b0aeea3284bbacfb6f9e7ce3f33cd000000000000000000000000000000001490f3605639a747d9a6969e325e96ae19fb7f4f15279e9a6df0d13fcd548b7b283611e915cd1627e4006c02f4bb1f551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2257e517b472d41c89b334319428bd68cbab0118ee1bb263324b8c3ad29bce2385565aeccca87ac97378ef6fb9c59c0000000000000000000000000000000006aec4d628bd073304cf87a7f1e6d26b02ea28caa8020af95bc67706eb0e541c05e02416f285061aee86f59c1f96f05f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eca502344dfbe58cbae2f146dd5840d934549f3ddbb9df5907a06a0bf590958bcf9dc28c1cb77cd6c8f9de9bb0007e100000000000000000000000000000000197e889f4705b35f527a9b89cab29cfeb99ccf960aa33e97b3f0a4f9107ff52500cec10cb13dae7f2b37bba2106594ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e9fd37414c0d9e7dc654d8138bd3fef399eb51a5fdec7ee5803faf8187fa23d65d3500bf988dad4e1676a06053a4630000000000000000000000000000000004a8a2e8a6b07bacb46b7d9204a3f9ce10f252bf70ac1721f2a839ec32b1432788e11882215875b36831bb64a067b8f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056468eeda5c3cdb901732ee682ddc325c986dfcd8ca86b1ed949d6eb6cbd40bf6c9958ff9ea0058e9a247e6b3ea8918000000000000000000000000000000000b51b37005bd0f0776aab2151f09de1a27e50d0c4419fc78f0ccc14990abb6438ce274cd7528bc7ec6c2c7619cf5ec4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b6e9c6db3aa48554210bc926b0c8c69b184caeefd1a802e50e0b1d0233876dfbf3ded220c0e80a5b43e9278d50487e00000000000000000000000000000000055f1099c5e825f9300c94a4f23a9532f8b18f138cf1cf7568dd7190bf271b9e195b1643ba9895a0c6215ab5f55df2891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011866e5371449139ec5ce6136d5611a9dbb975a8906d6d98b9893794af41f2edf6a2a24e2da7b67fa708f99689201c68000000000000000000000000000000001179c17f2d8a1c9b943e924f6f82b5028eb20bc02ca43e0760405211464ef5bab3ca183adea1fb391f896b91bd61b9c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ec2d9d849ecb33e6b84f03d9b7b00c4b17175d84506439ea1c03de626a8c41f83ae8b35a05f278f80c4416cfc2036b000000000000000000000000000000000ccd841790bb65d9b0277e935a38340317786d18511bea4997eb0c11de2f75d31240fa429f4ed73a20ead3986c04ed941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013675a7eed551d195c07af4301d5a41782d844acb1cd4596a1303af719cee79d0d6a7fbc5f93846b3c7a68a604101f600000000000000000000000000000000017743c4f79cf7836ee42808b978d97b0a88b758e9b32a7b0bc5a1e575a25cad6dcba2acf2b5927f11bc303a471084ba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa73bc4535bab1a05d478b6a65d9d90fbf446beb4d1401d10cfd8e468f737a18222e0a0e524537fccbf73536f938732000000000000000000000000000000000852e15ebddd659575ef192a8b3a6c80b6afe627b47cd8494c66a6fc8b79c4258e332f6c514c421810ddf628f67be5121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000304298e645f19640ad6b07b863b0278802b190fd2120935bb4edc9198405a235f9cf42287975142cd89dbb56eb8d6450000000000000000000000000000000006d3ff4ff8f9dbe1e2bcf42ca445992b229097859496feebceb7520b6d8c6e6478c99f0ead2e40c55b1c59ac38f813151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f90cc9b70538dc1e1ac84e8a575414b8f307f3a006f9d6891b54147fdaf7036c0764d5c55ffc2263e8afa791d14efc000000000000000000000000000000000cf3d03dd6ab07ede83e2362db3f4662d7fc51ca515b9e22d38d7d53f6fb76e207f18fd4e97387ef55213b2763ab31141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b01c7b82d487ad4413dfee72822f1033e222ad8af3bea969dca56be7c2d83a0956f76a633cfbb9e8acea00bd3674d00000000000000000000000000000000013b14899f5a86cef5f34931b710350bc3488aacfcc53b874fe5090246a2eeac9d1a4b3a24df26232ed6f4dddb037848e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ac2cc0855d7e71583ffda042bb5913394f48a0c12d98f475d22e94882ad7ca6c699b212091733ec6ed9edc22331c0000000000000000000000000000000019dd3c8096e6b7e7956f877f7a173567dfec34cd1372d62d73ef50f47dcff0453beea54d0d408289f4c63e109d95ba141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153c613da8ab42bc18f58b95c2872e38a83f612d86c2f34c4212f68628d57bcc44e65431a754179dcdd2577751974f980000000000000000000000000000000003e3d7b8a78f2959ff0a95ab333c0606366fdc15b76a0f9a558850ba170ded891873802445c4519388b9961382d356cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ab1c6c8e5ee87364d8f88ccc2dd8ed3e5b367d81b4a86f10d7c7204fbf675cb6bc8d1ac50c336e09f9ce00305a1653000000000000000000000000000000000e4ed2c26ff4bfce1995eff736c2d0372995135e01d11fe0ab16b8983bb3929ba9cd31d161da4093536be757deb080381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c2964ab368bccf3125586702619c2980579bb4e645aeb91bc438736b9e1863a67b43557daef3a1e28f391b76ddc370000000000000000000000000000000003f1a1892aa164a1d35be30baa7308672ae8d7591f00245991926e2b9fa108b2a35b1290a3bc815990c9ba8d7f2d6f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018201db5729d940f1001f65e509ff84218a8f18c23c1e956a18b5d94198e7f91d15a03de584a7be5355943b5366d558d00000000000000000000000000000000118aed76f6871c38f3ce7784d7c0c0d5bcfe9cb56ebf49b7f3250c173b3cefd354d8c8c3b7f587cd37f0dbfbc6db384f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017749c5a65ebf7d6f2ffe5922dd3d65d8ccdd01fc0fd0982ad82f1539c95d2a43c308d748277a84febb89dd6168de240000000000000000000000000000000000ac76fec61e2b5cf1b8686c89962f46338b343b86a4e8c73ddae425990f3f6d1f461ed220b4b62a8528311b50b4f3c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f62331d2267b2212462c11bf2c7185b46eaebfbf159d799097bd545215592d3e20b1d99ace56f9239c37cf60887da00000000000000000000000000000000011786f28d2ddf291490ee11432aa33daea7fe558e33b0ae7783c9ac606e0e79fcc9b147bda9468800b78d6a775c2f4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a481a2a3a5a0ce05a1fd64576d844d05f7d621a43ba9da46e4516ec63f95de4876beeeeeb3cbfdfda57a3b7eb9d713d00000000000000000000000000000000085cf5f5c59f675deede80f60f2dcfd1390996481f0a9321fb02f1732bcb60d72a821969ef53fe0b60d43cdf3eae41121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040e4fe640c8fc4db159272baec4f2815630fa77c8123e6dac95bffc6187c7106c25c3d36cc97d0ce3234c548ea0eb0d0000000000000000000000000000000018cf0d4086ed624618ae2abcd2dd66e5b664097d0eff57251dd3e1277bb4359679784f8c4c6b25d6e01cc2a330df4d7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43f713a9f67dc170c504bb13f2c5967fe12482ed296ef09ceed819d5a652429e096905a29d73ca9fe9bbc8d9ecbabd0000000000000000000000000000000011e63fcb13e7a18a941465b1a0e4ce7e3f92a41fa83a4334a729c1cc2ab8b04c1d8e3186f6bcac8ebdab9fc54a8a63ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e518f402026bd1923f210e14bfacc55f8af8ff6360f174c12ab18af7bbd343e6ed2f59849c371ec1a3df3efb80ee1900000000000000000000000000000000168a0ba2fdbdb6309d7300c43be81f6924cba902635532ff0709d4c103ae04566d45945c0c775d93e178cf2cbbc2e0c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000491e9d9ebc43b16b0f3624c2023ed584ac67b1135704b77de4b337f3fbb53f5ff83c16d664b8e28f2a5952ea375765200000000000000000000000000000000121d9f926504a8d806eaa9ac921acb53bff7830c56c882a9efd94d5324d2f372be98b9ce61e4ba3674da09bcc2e7aa411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000120a3d1e261e9dfb91c54b1d1d342b190b1501b914e089c770377564f520cca50ed34958993947c1b3f1daeb6435d8d0000000000000000000000000000000004f05424238adde2374a73ae618ea738ffffe36acc9ebe17821fbec914ec5f129d2a6aa1a0e4a643fd6ab67883638ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000608182e6d48b7f8ff5221cdf5df561703c2fad686da44efbd9d4489399c10d32d8678b879737500ca3c2a6962313d800000000000000000000000000000000099ab9ce92786af80132465fd1b09c5f9aa00e5137c5182dfedb7c284f08d9d755c833b377a4e353f4665df21a02fad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e6f9c26779f4b789dddcc5710640f269302baa0530a90a0226ab647961d4cc201188a9b1fa0c0f1f13081ba7f4ce90000000000000000000000000000000008e0715ff3c9cb350c1c8bf7846ac495f5f65194f2299ee2791b28e1783fb14e499a43c5a84176549307b221d628f8301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001795d91318d488f7f0b5f17070485e7001197f95a1685920cd5dc2c12fb6c8faba48aca95bc4cfebd59640232dd75d580000000000000000000000000000000016d9d911535082a282d41a087984c034ed2d061b8ed33dae3d379ecb4316e04be57273dacf5937e988cad84827bf22cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e85b0197dd3b33e247ce9f3381fda91b035f2fb73249de8fd1a15b316d1eb92d12a1fdb0dca9854b077c2f63fa5f9200000000000000000000000000000000041b687fd04bce8225dad41c9f5e431afa562c07730939d4a05ad02464fff26d538c702dda6ce235ef0cdda303d044c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f67f536339f48878ff73c0d74fbe020815312a88fba65e98409edb0fcf87c6c49df95c01aab4f64f451f2e7f73259f0000000000000000000000000000000009e3a7aaeb55572d0592dd86d52b71d60d1caf98207511f2c8d7ef70032976a9998e220daebebb59fbc58b5bbb9e48bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136d49b5c53ba13ba8d4979a548f0e3ad72d2401b8a287c8ef40f5a6c80842e2b1c5e11379efbecfabd6e76c552aa97d00000000000000000000000000000000039ccb40325c08ac5a56677b497e9e5a289971fd15a76da80bccaa8d10a8b39d8432437788b009119b6a0ed3081d6cee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b1577a85cb87cfa9b3fd757a728a151005527c227adedfa792fece5df93b7f0f26ab8317cbaf8710626e0e7835518c0000000000000000000000000000000016aaf8d979bd0d1d8239cda831aa9eba553f22490d3f167fe8d61ea24fe58e6a451fb4a0762747803f55f5a77aa66f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b52e671feba534926fb9d9daa7d72d4c8fb9ec5f9f0a4cabd7dce41b11a23459a65feac65825be57049b026f0be8290000000000000000000000000000000000885c5dd6ba7b328fe13c17384b54e41aa8af832d380fd5b5c1aa3dd8dfb354eb9c53b4c3d46969bbfb1a1f7bb78fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccb0ad92eee61bb59a9fb0bd6068bea9a3255eeb18f3ddf93b597a655e189b59b8d8ef6d21e42b7756dd96fc2e2a6d000000000000000000000000000000000a72c6cb9cd6d549224440b0479ee49a391a2e31a55f567e5a739d814b0dfeec5a79db6068695455a942bbb8c84331b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018684860dd8a83c505e69adc5724c25397aec2dd73714d211df1c891a2af074cea229fac76e91baf3fe7fac6d4ff55770000000000000000000000000000000015e7c017af76c941684411091908c63b566aee9dd47c71da1170ef2826c9441d24b675fefcb529abd712e717e1684a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037d4341041bd91c93180523d83f8b785c9e2616faf41e97fdf48b22524b4525eeb6e1def30343d5fbca577bbcbaa13c0000000000000000000000000000000007111b3bb6c5dbb99d93a1df9789bf2b8122598aca78b9f7b010f94f5676780299280b9eb59e7145b7af85c19ee2331c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168cfbb62e1f747d67b45e6671f5a2dd60ce1c12a1f5e17f9eddb16105ed3196faa252a36ce5452fea3afe9a5a524f9a000000000000000000000000000000001094cc1cbd3381a6828b4ae641c1d8922fc96ace1ed08f3d9b5f777ae2df106089d5d211aa61afe2792fccd8d2fec55c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011b59b33b90ebb180d1c9a4a1f575751c93b3a34497c0b4db65cccbdaa39cd0f49839779e837d65030de0e37351f6400000000000000000000000000000000013d14ced4cf59ff65f38a2d7d4b055b5329e1b8f79eb0b8795ec14cc65c351c930f85ff0b247496dca500cca147d78f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e4bdca95a46518fcd3a631951abb6dfd937e41718f93ccec35f8aabb765dea23ee082633a7fbf5690d954160b37db70000000000000000000000000000000000ec48cb7ff0ac797bbedde6635adeeefe0be0ec3067472c4d78f9482bd60055328b3214924052b924afe48b305221901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f8b7b922d0085ae8ee2ec577fd9e45c02f6208a6fd3bc4b4a3aac1ae3aea0012044f02dc7e592bf5eed9fcc7882c88000000000000000000000000000000001139eec2d41f669beac5bc249f5daf07a8e9543d5c663079d68a9efaa6707076d6a1661852dd0f55bd289bf642573ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126355ab6d40f2c192ead1cda9d5758089bf3697e1b167c344f5f3b18afe4c97bb87fbc15eac768eaab38bae53453cc7000000000000000000000000000000000d723b8a9703902d6762e538406be1e238e86602661b2a9e20d9105944a5e3253c720ace41dc150e36f6ba02aaf9751f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5a37d98f9ae0e4fa81d4c1c3da1e9df589358d8330799d6a33f1f896823dbe9e34174726d74cda8d0bbfb57476baf00000000000000000000000000000000115cca57c86d8bffb547179536ed9e4e0b3df08e4efd0c3b80375088f7fc27b68b4a1eae1a2d28f71c3ff94b6e5e9f7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e8c942e597c9d9510259e8118ab35623dd994dde4a778f32714cbabfed9479fad9ea9881b9925e3330627ce61781e20000000000000000000000000000000000e2772a4176772898be703111ea7be07cf035c852299cdbad8f088123e1cabb58627e56915495c8a2966de239837f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010de9e937b7aab8cff6bbdf969a4585304422d62c482487005af771b066da1d66564b9302a0f34224d51f9808a29ee92000000000000000000000000000000000da02a576f6896b6f244d8123a80e025a0705b8b837ee60177a60dacdc8108973e7885ea953a63cd426a1e20b1a27b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001384031b0c47367e6ce851b2105a68d242b9f709b0a1b5f62df8e33619aa811a574f4f63f5bfb8ec98befcafd22ebd33000000000000000000000000000000000dd894072a2d3fe7e1d01f7048f394b2b8cd102b32108f5918fce9c36de3779cabb18da48c2284ce1f121c38aa3c3c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdc376148574e2afb2c77db4ad630c7b01266767852a6f6b6c2a7871e43678d7dd4a1fbaf7aead7aed7941d1241f36a0000000000000000000000000000000002fc06e129b3ef2a823bf042e5a73a5c0c886839f0eeca5583b867de96926fc2defbf2d8b344ed8273269047050685091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4798604fb9b9f971c5d520ae4e5836b7789becc9e00e3094c4cda0598e9d2c6d64a78894cde5992c6775b1069f7c800000000000000000000000000000000038dda1cb2c6d566999a490ca855bd8e4e800149195bd8290aa947f7adb9c7642b8c2a1107e66176e393f62c5ef519951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eafde67e5067a9fa0ff24e7d0427aff98f45ae3fbf9ac0e66cd7a29fef14fc787d4c7e54cdf290fde7c82edfdd06260000000000000000000000000000000008b795b1feb5b4a268cd28682dac5582639e037e6239cd17665aa559583aa14a1ce5a2801f0b86dd5b1965234f5095be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa9c5c827256e12840e06fa284b8385ab470a93d4bf74219cc1ad396411f4215135342aba52e590f1c6b52d347589f00000000000000000000000000000000010152439125202e0f7711400a55d947ae636245d3b8afb60876a1e0a72c69c39f06747ebd8e27604b621b5f8bc81f66e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f469cfd73a1d93a431a83181876d67074d1af0b0456d63a31ce70895c478a7f44426237ff1250f652565fd7d32b0db000000000000000000000000000000000ae7a7e99f2d3b48b51b5249e46c2ccf4e01a77516488f55cc4d7856772c1214aa7673d3d850505089d4248af3b518f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9c04b77c46891098535bef14dc0d3034912e19cf77c0f6c28165c529a0a594232fe4c0e21a36b0bbe7fd17fc298c990000000000000000000000000000000003f4ae3f9f7556f5f5f56ed4e3e78f3775f3a5e36c1f4db47704550d40b3b84299584cdfdcbb56fc8b3eaa9ff5097b601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c2a7289432ec5e79a4558645bc213072ef4949a17811a2eb1e90dce1dea8079ce389d0b50cef59be2dd5318b1858e60000000000000000000000000000000000701f6cfddfd1d68496c8063bb73e16266a250f1e2722faf95c261ecdfff33438646738e8c28bc136996489e22013801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020652f68c6494558533c1abed1087a5bc70120f2a57f4f8d0c7a2dfe4da4852b9d4b5d65cc49f520da2efdb0334a8740000000000000000000000000000000010fc81e44985a22084881d4f4e3547c2e261616331a7e0165c3e3d11b879ff2ce2fbdaa44268020e0ee0cb2fbcc272f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001333f633a5f60f4407f24d3bc351f5292f5d33fea7ecf01ff82872980fbc7650d2851cff83cf1af31b221d1888b43943000000000000000000000000000000001626408d253bc06e447fb4fd2a133c28a2618077c2c165de45d7b6b6d03c81e430d490ef1724e3a0492a7a00fc2cbcc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5b77c19ab18df72424fbbd4d2fbcee43424c27a2d927cb282e9d1a5b2ed7b69c0cf60c1abb1819e40a387d1206aad900000000000000000000000000000000067471803a7e73009ffd885515c8ef3db2e8d23280eeec84d5520b443acf9b44a31e92032c96cf5aa0c2e369c4fbcc391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004049f4b969ea678351b05f0aa4dfc20e20a215232b69fe6a05f733b08fa0431aa6f3d5ece61d07047582e89caee19810000000000000000000000000000000011a3e97f01244fb2a54c07389c3f8ddd5024d42a519b671f2d0fdb95ad003313edcc12982fcb08715a886a6845c86f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e5b45f4770fcf4a4d5dc04fc00f587e720c0f0184c49c7cd0236009b4446f8378b83e6fdfdd571009751fe123d918b0000000000000000000000000000000004a6f103d678af9379e6b03d47b88f4d58e1bce0bdbdca67ac539b4acebce5a1d56cdef2ab6e74c2ddf652244f86077c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001688d72c07f3f67c64bc0f28e593bca09e792bbc453a34acb1bfe66d9cfe924176c6418b86684fefbf55af1a6801be3f0000000000000000000000000000000007d5ad12c260d7830c0652427f72b2a3756513fff4cdf491b1bf396045fbae36e2e3a9dc089757354880c67eba8db2cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1ea6565ac96c5dc137d3e9dea66b73b6b0962026900dc75312fc42121f0dd0b3ed8105a31daaaac2a099d02901a8750000000000000000000000000000000005ace1992ddda822827d29d99d8600ef0aad6e306eff2b52d8b8b66df3b6299e19b43abf331a81f55822b4e5c4621c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce9cac0e5988a04d1d1b2ce2ce06136e86e46d6136180cfa8a44e7009453ebd6610e03a4ab28189bfc708e24ac9815700000000000000000000000000000000111a5c1cca8378fd16aa75fe6a117b335299cca6b79b47cdc19d91dc00b7dcf62b40eb609ccde47833113aaf651e4aba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155557470538b31f51b293a5552d635d26ed02e80c4f06113b2f46d20d91843c50e445315a657048e32a9f1f0b07938d0000000000000000000000000000000016f91d844ee427003f5d3ee766c8d23b91865cf0f67a541933ced2ef88e1250638a2c18d125912d9fda4060c481b35711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c41f15333f54864792b5344caaf727c4183c3fcce547c322c9e5afccc19b8b4d1a3f55023066483769611f9a980d70000000000000000000000000000000000ee18470bf2676827e9fd037e4d76f5e51182f29bf74dbc3ccf05840db9ad8bd4a0679e8988dafc8a25e8ec0f366f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ba236786a55802562d5eb7e034988253a8a3e5dc8f2dda76e65172190189903387309dee12fa0ecb460eee5d7b879000000000000000000000000000000000ef242785e006a1f3361766b60d82ece2cb5fdce40ce0cb61e4fb4a3d74fdf12d5707292b2c9fd43eda88854f0b2c0861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003384ec8132ee04de514f6999b2385cbf93cafde4c2b39a56748ce67ca205641ff88974bdfc897e5179b9daab902653600000000000000000000000000000000022ea2e8d99d19273d0496fd46942d49bf4b2964c2aa0cb20d61ab78d9a6ef2fe4cbb31ac95c0d40e22f42305b8ea45d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd9c35a3209ae2240c85aa71b09e5c706bbe0b2fabd829abcffbec6bd49bf1f9228b7893e7c577d62f060627d470c2a000000000000000000000000000000000aed38d577b00bfdbc8f4c78b76fe76f161d3e56baa3cec08c9e19592b208ac93c113a08710d1df01095272b1c7874a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8d3f0f4ee6e6d5c7089eeed0387b51239ad74b3cdcbd2e18ad02434286647061f50ec168c063fa055edeeb8eb3f630000000000000000000000000000000005e204d847309137e256faf23388d2f225108fe9fc2741bd4ddbf452fa6b8fc61e0c1f8810fafdeb150b1e691e42d40b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b99158821f422add2795359efb2824a6d3fe459bb456857810210d9059bff4de6a1f1baab8598e1c05c2d50dee217600000000000000000000000000000000104ecb3e7b729e2dda53bc8de3b2cf33e5a7230da2e19fab4e3a4b8c442283c52038fc563e7f66bb9a3a231e3b2a062b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f40d22e3cee29341e91c936af304d08c5c16ad44d51d03cbc4e96492bf9567528ceb942a382600fcde3a950be68d790000000000000000000000000000000007ed795c876b31646eb45dc8c63ad974783fe0dcf4e0e8e9ee3cbf5a0287cac3787f0f1ecd94e8b4bb5e27361b3db4e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156c741f39488e43e0d79d8284f72934995ee03fdbcbd033748235ca83b036599f0fea86548bf3343acdd07f360fdc2000000000000000000000000000000001720e2e70e708ce3e296684d584f277024edaddc1a8edbfdc6fb569d18c2648040798ebbf759c810c84a0eee8edf97061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4ab3ebf2811590a2caead3967b5d9970cb3459a4e8cc9b34db0c6654e7986d05176f97a34fe60b5096bed53c2a09a500000000000000000000000000000000171e05f29c47c3a95acc27422f1c997dd1570a3a3dd6b742d1de21ec33aebc718543db98ef46624d4231496bf67926001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000818b4603fe095ffbf063b214e19d065bc1441b535342714167de6f5a772ed98832e1f6e74e7ead657fd453aea96e893000000000000000000000000000000000b6fd6af91dec023287b8e3c15405ef54996c7d8f234770ccbb1ecee27c62bce3eeb72aa718ecaaad3f306aa3d2962f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001658d558e2b947cc6ca28cfa4acc21495f55108ef04cdc9ceafa7e82514332620d41bd6500ae8d284ef59f2e1792e22d0000000000000000000000000000000008b5949db1097a1f9676a151a08f902b3e27024b3d52ec8b0f7d25f75ba7036f56c11173149281ac775af7dc4a2916e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cb91664d01c41f36316814fcb35c8e50ade0160520a281eaa1c6853c7d5ca8cd0f525b350a91beff2470a0e5355e96000000000000000000000000000000000e1091bdd43ed58a2555ef53f8404792a6936d28c679ea9a3f2e30a6d5bf539551cab3a01f0982c33e8dab23703ed7a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000618ae8a3e503231c27a7dce860dfd06daa17f956bce449b8fb0b4cadeea37a64f8c145ae1c6058713dec0bf08b75b110000000000000000000000000000000013412c6e6e4362a1f6d5b154c4317d6b736d4599383f3c24bbc0df3a0048625f6c2aa3e009ca2ef3686b966fdd3921c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000265b744f5d43d68d863385ef43a875cb0f911959b47248f951d8bc22462a02528f586d81bebf84488dbff262ceb7b0b000000000000000000000000000000000bd0dadce86079bd92cf5afbac30b1b95456c906cb0852aa487a47a2fb67770755045da6fb7e2332b5c7d979e1b5a3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e518a0114af9f6d2e82035af499dd6fe41a3d738cf6ff17d5b04cb585df5cda65aafe501218d362cdfc3043f871ad900000000000000000000000000000000120919f609d37d02f00eebb0afb3ce620dede7940358fc2fefb935c8fb4ee8c71b011b2c9ec582243830d508ac7406ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673b02fb6dd24f44ef89ccf533c778a38d8cecacb885750af6956b801aeb67cb55706b122e71483466a0607149dc92f000000000000000000000000000000000550f5b02c4efb8864eafe94b8790d83d85bbc6e4d22053c724e6ddafa3ad6da184c908fac5406570e88f8d67e9d4ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016abeef972685c1ecae4db5f0056771f2a66f8c14ee4a39cdbaed703d2d66c53589494b48fd858801de153777368cacd000000000000000000000000000000001535493b8edae5d2804ce0855d79c223b6499b831ee14b541a4099a387cf67ad21a26b5b004a2399836836e3d45843941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153ef01bacab389b8aca28bf5e46a8d4f33071feaaf397678c16cb09c1a1d97bebf7b384acd0360a5a570c3c378e5fa1000000000000000000000000000000001999106bb1a51013b256c0d27b5792c44c3d71e95c3ec5ee13f9630e6741ed502f3ba51879fc1a387a196de038d6eb821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0f193a09019d4e127d2d41d7202616ccc164cc831845c471e8b2becd9ddbd8193bbaa38845e276346988bf6c3238b9000000000000000000000000000000000b67a89aae818b1281b1586a57f02942dcbaa0c063e266def098bede46115cd513da7c65046155e32fa83d4ff8d2f4a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffd9488d7ec87c071c305091dd06da5166933535811d7e680fa1c1220c7e1acfc96c3a8887204ee69196e49fb65c5f2000000000000000000000000000000001771a88c07e0214f33986dfc627bacdd2b6c20cc9d54209a59fe98e568178b6e522990fa19c8cad30dc3960af40714831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c3941c3872ca141bc25fe8e414b6619dac5e5b1943deb8917cea3ba34e038fa05ac5e665f8f01dadf1f61c25baca1700000000000000000000000000000000156ce779a2c263ce7da9acf14632c21099571da31c77f9ecf62de839d17567f44d7be1a72e18ec8a9dd59b17390f6bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca1b249e61571695c9c9f1de9fa513c99d094377a045045124ca58e4264a7bb087b6982cc610cad92ab66808eaa534c000000000000000000000000000000000bda0e5bafbcca8104eb7c9812b66a4a79ca0d58b2a5f54362a3e9ef76bddc79d0517292ea2dabf460782254cd920d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fc737ebee4afe1373345a8d6952bad18d9da7b56c2f869e2d76b3008e411d3abbb1b7cbe0bc6bf7e140c0e63f686b9000000000000000000000000000000001016fc1189c7479e3fb028a71403722c179729b4a688f35d7c8f1f1496b334b244563e8c11725c6e4b670a4044ece2d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009786d244d5c8a447a82818e2b12d4d7f57891929fffca7aa1bc626685b196f2e37d4a86680e79d7ba76830ce22dc21f000000000000000000000000000000000b1334e1bd8eae00becb0a06e6a663be43863eea698e639753b67bebf9e5f8d8e3454c7eaede4e0e5051f8a90632537c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4a0a370f5ca3dd0d2819bb73c64cda995c890cf09453b237cc7d6a55b9c67f71c7c196cf5b799c3979b4a0eb3b2aa000000000000000000000000000000000f522244a641c16f3de32fb56154bd335e6f2299cbeaf14b8cd15a89478e0f64e264a54a6fc6006003dc118edd1919ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8b7469d3d36cc7ce0a8843d66de8e4c8f848b2e6c871231b8250870c3db66dcdc893ffbff709e2e9cca43bf893d9000000000000000000000000000000000063352165e6deb56acf2aebe8025e7c42d3eb47c53bfc6f38d89cea3d18cb84539ccb59799fa8cb3ea6189d8d085559f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5b6837b4047c3c3b9ad743c1f71f3787cbbd8cc274ea8dac3b1dda5abfeaf529eca830dc533a1db81e88621a2345eb000000000000000000000000000000000d0e03ca3767f3b54b7701163916f4f564d4eff4534f4722015f90fa2ef2c541863800446390154ddc83e64d8de0e9cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb2b9efca7044b1c2ed99393c5718ff1f9a7d4bd07d7d5e4694565359dd6db5fd6c8e5648f1cfec60587a20ea7012d4000000000000000000000000000000000456941d3a1b366e2d4e37a6bda52435eef8c165031d2152de2a0a7998218339b296da84717b0c6b83e8c8156d32a49a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012491b7bf68adfb7523bdf15e72d3b3a21f3638614d391e4d71a5478243312dbaf4d7975657426a1ad2534fe27b6eade00000000000000000000000000000000192f08f3cc9500e1c056bebd18909e76934aa9ea5ed8927f5725f5168c0ca3d11e46b33300e03c647f46ac59d5904fa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deeb83083c9e24e4e455f14ed2378f67a9752f5140d4b374fbd56bccbc2e0a48a2d4a0c38c900756380ab958bb8532000000000000000000000000000000000d6e027d5b6445f1eb1cf658985191eb61828d05ca40cf939719f5f40076eb76a1ebf0b332f549d37c7abca6b5e12d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f337852713fd09ec735da927a3fa478a32d5d8cca76b7ef363c2c708f217e536f74d51b0f0adac511d1cad84329194800000000000000000000000000000000011b6202c3bf97e4650e15771632a465d86f35780b255490be87300eef6eecc8c2937418eab1fc668d22fca8300f7dce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009d56932c3e4168c9e9d2b3af80f8e1b7b2463be720418d5f80a2702d1c65e409fe8d93fa0a10a0eb4ee7a707c5fd6100000000000000000000000000000000073581208ed579ce4d58ce90fd03e84228395e8dfaa8083fc83704d1e8da907d77582910aa9312517397e893b27b77321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124ecc7c91b111a7bb7fd42a9988da68448ded20837b6ee7813d220c8951752bb16b239cf9d13e580849bc949293bd530000000000000000000000000000000015c98b0504d6d8a88a953954bf4f4ee10d4e497ae07054f19af67defc06c0966bbc7b8f535407145533acd0a4a22ac7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014af136bc4e066ffd839853276adba657c9b67519ced82bf51695ecde8fcbb56610632edea3d0f3ecad30ba3ffa9ff2a0000000000000000000000000000000001ac938136f98de79d19587cc5f728fef35089cce55ba919ceda08166fcc6619d0d50c1440035ce608516601f893f9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126bb9671e517267792dd4ed2243cd357703cc1629cb7bf08ef0d9ef8cd0175fe1495ad9cb8a090f89e0f98f95eb7b8b00000000000000000000000000000000089ff09b2748aa3c722fa744397ec470f5eac218e1e8b20538641c27924921a8de8b29ee560ad88f854e03595c99102e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000764a2a77904401f737762c762b06d26b08a235fb3796680a17ac003b2930d698bd9174ab119970decb7952d5ff4acce0000000000000000000000000000000005912d311d38341dde42f7403e7f7a6e2d7dc6e773dcad32b27dcb2e1d74256f6972eedecde900846951e4f2c249c3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100381469eabe1327bd3298fd73abe89f7a77c1844f1ec3fe36b8b71b6fd58ab4c3eaf4eb7bbe356ccb6299086d31bd20000000000000000000000000000000018a1377c49e0f05f1ca89f6d483b474b6b77ece9d714ef8934d19535092da0da9b885f89fd6dad8d7b4a1af8a814455f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168fd4c7928724a6807a2c53a155c77c6008b9cc3691ba67ab6ee3e7478ccb8e61df4fbadcc5ff0dd4de09d84f60dac400000000000000000000000000000000078f1a5aa1522956ec82ff461e2b1c286b1587217ced3c88a70f269a19165d664f937390bf7be25037debe10390716e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e6a67526b8b74a4bc5aea67e179f7d16ac42c4c693a7bdcb1109e71cd960d10f18e4513015ab1f9e9cd55fb32e24e8000000000000000000000000000000000d3b19f7129006481b26c5b7d161cf9369a2bb93fa017a93d394c300b3d8ec20c1e5e53364b65984a12616ab1fc4917a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001922a38508a578d012db1c6863b03739e13c1da571213d92148f7605579a9e150c30a83cc514c1445c887610bf5252e80000000000000000000000000000000002cf9a4bb6bf9852bd58175b391e4a1c9dd6da027f404f8878da6a83f5fa0d7cbdcda03aa5444329333a268730955d271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4bbd4d0ac43bf6ddce5569ef9335ee428f366a8483c6ab339ec6c269bdee7acf3eb186c720be346e8584e2632b83570000000000000000000000000000000015eb237acd09dce01d17ea0c21cc66994eb42be77d38a5c07b84187b53d63c76a8b7d6dd4b821e90d35ba89e3bf6bda11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3710be16aca675c2bf2aacd9ca0470948a960e059d74ad8b84e280fdd95c228541551aaea76335bc19333b92a116400000000000000000000000000000000119671acbfc39b553cb821c881bdd7f72f501bc4fb45e6bdb8dfec9e7517f6d9b3ada8793c06bad0dc6961dcf35ac84d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065f74559e1e24fbaec2c2b9b0dd123183c2462a448265b2731e2e0928a80602cb828832a1ba0025261dd1e3beacd5de000000000000000000000000000000000746ec52a802fc70614fa33623a07750ac300ecdc8043251968c6e6b4f0b49915d2596befe84058fe1708a96c6ce76be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001091932c74bc39089576ffd44f2f6a1c8bab022629986f67b8c022ad93d2a05c08641560d105d725556da7ad8e58c76a000000000000000000000000000000000a2cad59e673f2abf1c0ed2536c9b787131379ca5d55aa6625c8f5c8e73508524e07b4c5ab09dd28145980417f2e99bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187efd24effdfe761cf8b97742bafd1f41bd9dad678d2c3117c54b46f48388f9256eea89319a7f632f586c6f4927b29c000000000000000000000000000000000bd476a7804b3e43b68ec928f0e1faab4c5ef81496fc1c97d7edc7844fc1bf350e9499e09bc700aff0864d95aed371571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1b27da1af76ece7e7e3e4e741b04803a098c0af9ae3310039a9276d6b35cea1594aee3db23863d9152debed6e45a3000000000000000000000000000000000ab7d2019417c48ce97e56817336a0608c459cc55d807197cf6a1e99ad8c63bce753b76d33623abf3d5b40475ca70f1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d465cab0cff80f17030671b0f543000d607e361a7edd48d92e5668173b2de628f3d8269425cfc3042893ab4f521d010000000000000000000000000000000003b3d4dc2f2158c4cb7850c5fc1a08c257e8e4257bbb2e601a6efa476248758a6b5358199c0218b50cf6e30bdc10cf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ccc8e8af726afaf2944470f04c62015c362cff9b041bec0b9050dc27c53708dc72cd34b0b7856afa0489d074d8061d000000000000000000000000000000000c2c84ff780d135662f32dac3f21d428279660e56c64e9fbaac7e06c951ecc892eb431c0fed0047a8cf3a964ddddb3581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fe644f472ddec2f8de2d1a42775c50ff6535f2075072c6ca058a3d4a29e8b59fc1a0d823a23edf90c2af0a854253320000000000000000000000000000000019a9bfd071c81ab09e22dedca90567999c4322d99968b4cda602e4b914b1d45397832f6ccacd48e16dea96fb4d3b6f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e4c6dac139289a62ac28d1d044e40af53efc4e657d1777a36ebde3261da250516eb7708f1f52236794ab8b03c9ed600000000000000000000000000000000018d22c0bef069edabee7dc518cf596c02ea3289a896ebc96233e539b05feb9ddb6023fcfcf5ac0f04d24b198fd9e9571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea420a67fa3384c28e78455abc0ba28a1e2489ceef4ac82e68416411f55ddcc48c6fede3314d95f2e4fc73ff2a6b360000000000000000000000000000000001ac8de611fea805f10e544eb9eb6e63fa0d7e559d8a225ef1934114c5397b5e52e05defd4443f503ac2b804ce0b87c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161b3beb6f28b5b229927e0a37713dd499b7ca2851c9c0d95c7d3b4d83376fb0d747b80d8067c64f0c5b55f2452b84be0000000000000000000000000000000012af658c46a15139f36d4d5f25adc63dfaf5e77046ee868b4acb37da046c19a85497834d67c996c3cd427bb0b7fd3b5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001315b21c683bc730a0306ccab9310d8829737366db41011bac4d6bdff6228a5f61dff33f730348c2b9da6a16285e0a0d000000000000000000000000000000001170f50200394cbb53c8edbde2918555b6b5c8dfa8046e411b4b61cec988cc1f18ea9b8d9332cd5701ce42f631cf76b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014653176e3cce4dec0fad0c977757e070f013739a39a0bcb08823bfcdcfef05744585ea050107c5fac3c5e35005c09f0000000000000000000000000000000011457735dd2ddffac03f1e7f1a86067a7d979349fb67567d87c6f462b81c7593ca7d8c9c8d75a0e486777d7af05db3f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001da04b157962b502f738773bdc1f0390fffcb5cb05c2c18ad14e742954ce02500ff57877e25cfdec7f2f1b6844c42d000000000000000000000000000000000f7c97a711c5fb7670d61e2068b75753a5284b4e61770bea3a722bcc2e4f3393ae805517a7cbf8a60745b16a3cf50fc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ac7173e2271a6cc7dca6f1c80e77acf5953ed6ba59692ccc7766eda835e553df95ef71897b11cf29cfed191cd31b1b00000000000000000000000000000000158f732a9f2ba7fe3f054a0cf0bd50b06ac1115260cfdb1796a76fd630468fcb5acdd2cee4a064ebb672d9623bf517261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a75eba744d4b8b57c6effdd11cc722ad7a1a94f5aab609832390cefff2f6105e790837ac485ed339e2724a2ef8418b000000000000000000000000000000000fba023eb6ef6f757765dce72d18e204065ab137e48c9f2383088e626c9cd023a56dbd5afdc2ff492a1a9505f8c869e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007afce48c13014171e0dd9ce4fc6040cc420785a2e390fc58b79ada006c06421b1465e582a1d0f9029b441b1c10f2e7d000000000000000000000000000000000d4f3c17e6c6923624d887a5134495edd3f4d7e8bb6a82ff23dbf842f03d460fb4d71f584b8cf5be7fe06e8ea7b5851f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012235511341c1a6f326e85516f499f11dcb199efd33ba9af83b29858720f15e079ddaea88c2d0234a7a01b497ede511800000000000000000000000000000000199c7491ea10013f9277a840eaad1b00122740466db127715909c944ab70f364a6439f846458196c37d36a0478b3fe111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e32e07b410c0d2d087363e55afe637734fc4ac624bc3531d56054d5161793e82bc7ed33c88327991e1a053f67b3ff00000000000000000000000000000000156c6c134393e1fbd9571fd2971bade2577fa2e9f38ba18f7706bf622d66f8e86cff0089ee49ed5c7fd9b01c22a5db591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf179a94ca8f132fb7b103a3bb4caee3e29d608b16a303e32a9def5060fe030fa899220dc59e9316b8d099d2fe42bb000000000000000000000000000000000a5bee93c84159dc0ee62572e2a0868ad8a91e98e1992d1a393a4bf7c616683ae352c951a7c166633e1acea41b81d7171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006304a02c93f2419835cdb324b78719f3e62fca5cd0e366e5510d09ef1de1ed9ee9a0d4bee920671c4d1c91749b901910000000000000000000000000000000014f2ca64d0df7ee607bb8c39cabc811b84ba52afa8fde5070d78cd358784bd89ca307c2c1015fb57513f4918730c34b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ca8aad4f45fa6c6e4305b3008d966277117bb0b706154b640c5af1e5222b0391cdc8633b46731fe9b32ccae8088cef000000000000000000000000000000000e856f9efa65d3df3fa53365ec34d93046ab71e0f1246f8d7336d60ad6814cd7f5f3a8310cd5d1b894a4d81cdaf0bbfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b89b6e17b64f41f303055446d8e36cde67b33cfde98ab9ceb467366069423007ed17d6fe74f92d179bdf027c7c3039000000000000000000000000000000000c448267092f77dd005d1efb118e01dc4eb0aced975378f8b27add0914e3768092eeac8bcb13e667d977f190012edf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f64a59f47f83e83408832d7cd277a78abfeda384c24f5b73604fd50a3ecbbc1b06c0217468d8d517171695dbc8537b000000000000000000000000000000000fc5ed81fc233f79c45da8f30af16faccb52ce2284d1a9e7de72d55663e147a0d0a7a641c7a6056a027150fed7b4e9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e326a229b627999880ed1fa6dd20aad6d3652bf6ad9a0dac6a1c61b4b9b95092698bd491bd72a289bdff826499aa840000000000000000000000000000000011c9c349313ae92ef97167260e499c541176652bb5751e2a2e5a7739cd72507c09f94f02491d107ac781bee1169347531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013de445364ee9cb93adc419eef88c2b5dea831f655c0d3adc416925ad8f68f53a9d8877548b6807bdfd9a6388dcddcfa00000000000000000000000000000000096fd770f94c6475cdb51487da8e51c5023f040590bc6e9d19a54b747dbe8906a76e2b59b64fc2bfb2bd547356c464b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf1d4a18762878f1437c625785bd3342e9bd7bbc1f5eff961f13dfd0567dd29d3c43027c76d650cbd97ae2c11fa93ca0000000000000000000000000000000014f8be3c695584125937d54d58a67185d11a2d3092ed67f45167b09c4a2abd188b83ab0201971004aef4bcd1edaae48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce05bfc73115713d5c33d9cfdaff819de53974305d860e79b7edb232a429621347e4bed057050c46978b80b3bbfc07e0000000000000000000000000000000002283c0a5e93e583a4d20fdb7d9820461eeb9804fd91f2107c78bf9af575125d930642fa76cab995b90670f524120f2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0ccbf45e16175a552e74010a5ab54af6bcb52478c4a1d7aa65e8bf7e240df856e7bf7cb1b88795417075a1cbc9ca4e0000000000000000000000000000000002a9e3f553de57a3ec13defbc8be91c153b74d22491cf2dcd92698f19cf4e9442cad1ac8d8be2793bfa71adf04a9c7811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001252fbc302c483efd300cd0fc4cba889eca8fc8ae329cf65b5f23d3623ba98b35ef7e167b31e0cb66b6ffd95c61a5b0d00000000000000000000000000000000118137f13f381e930a54b7f986c8b809b4e2b3add44a9b38314d66debb9c73cf55dcfcb6476c7d51d0b09e2dc911c2ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ba31716b261bcebab58dab2abf16aa35b0661a33298843b81ff38f600a632c82866b157bdc05e787c0caa1063fe5bb000000000000000000000000000000000d664bff23d5539d1fc378021f3bab203407ad30094a961b9aa21b9605f94ca8de9320a27946fa7c24f8e42e61fcd6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011155b2240cb3a982fddee6e049bce6dfa00233f130dc55a57c1845b1d631ed5c0d40b06471461cec7266ba4bb78c1980000000000000000000000000000000011f35714f49747b0d5a5027c2e9d1dc632e2731b34742f5f216a9c967c10217b5e343a1682daf1b1aff45e445c56722a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89a986e548a35e0c014755ed0a38325f9bcfdf4a74739cef09883345438c1d7d5b2ab5f6f792827d2e13fd7a7b0ddb000000000000000000000000000000000c44541a5b6fadb90bf5cc88ff053c10119867f99b44a2672997a570cf2c818a2e9967538bb509042b33830c1b5a64f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000551cf72244897c911f6cb7c1ba15dda34b10c974b8dfbf843fdf2a07c14404bac58f7ea552b4e0699ffbbfebe32dbf8000000000000000000000000000000000bc4bb1038e2171266d0ce5def581bbdae500819102725021397f4c03df816fc9b2d38988448d030c519fa45b0cbe70b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001824c5ea12c4b75d413b609469776423b26a75f559e44463535cecfe6fec469fa75fe8e9a437377bf1413a8aff70055f0000000000000000000000000000000010a0dead767f3ee1c22f8da401c7120c51a4947bdc350af8380b6fd679537ebaf718966b18664094c06d93b0f812ec261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001072719fc8cea906a0c4a79c9800f1b56493d57bec18bd9b963e5abec8200a4a8e0c8c02a194749f2326a495f128a9b00000000000000000000000000000000013418b76ed9da79c42349fa533e4560c67ab80706d9c84bf2c604e3cfce15e823eb03756e6577080575b94dc06864fd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c8bfa132fce79559be4132ebd735ab296c03702001ba85c234b4205e0c067da3ca3e7e20dfcdc3382ede048495d959000000000000000000000000000000000172f47d0f251daa4cf320b959b6276ca0add15ab1ce7fdb71b0d553eb167081cb5a00a64495e5c7579a1d764e56a47a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4732c1a10cc9f2d9911d029e4ef26db04c57c3d6151b73e633d2c95fdb3596fd665474128ef11b6237400816c2e12000000000000000000000000000000000055384e5e247ad359a7d46b2178460ab36edb9a959962927a3925ecb812cbf10e314f67464309a9dd361a99c46168c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f796d028887fa5b3d4634d9e0bdb573b93ca936066e6f04b773bba53518ad30203eec1a6042936d071514e6bfa5f2920000000000000000000000000000000002fc62c26a7353b52db6b4b9a42d7c05d73b57ffaf3f30e3477f09570f53c493f547f5b6885e099259d1539792ce5d7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b8f2c5223f86c694ff7943775192b750a7649935f901c10fdb0dd5f7414bada981904d0c9bb4d46531e36d71bf753e000000000000000000000000000000000b536cff8477ccf93e45283cb63418d95312e2c0ec261c759a6b9f6c5d7d13fc398b432c859eccce89ac5b8c072f3b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011da94a5be90d556e5162cb3a1137fee28e589ce8e5a63a9e4eb107a83dd2e491b6da3f28057dd405d3405299089eceb0000000000000000000000000000000017df38816141a18bfa41aa6aae3eeacd8ac6531bea08179220b0823867149193334bce6cdd2984eb08a41efceb51b6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b09ae260c192350741a8f8e6049746338ab6a808d580ead6c5f1cb92457289ba35c32a330abf9038fe015ee42c6d8800000000000000000000000000000000081a581b92f7e0b3ca6ad1cfa8d0a7daf32fdf7574dc59b4bac0d14174982860c960395a2aa070d466e7e6c7d1833e061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058a98eaaf21b149184b499044daf38760234ca5aa8b20036e39ad2936a80e71c352b1fd0b64a090b0e0764cc7d67da00000000000000000000000000000000010db0406de126e8e05dc07fc896c4b1d12a8ab336158e3b0636ff00b981656b9a39f0fd9b629b8109eb6911012b89eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010201bb8d227c6985435a7c205768170c42422ce90016bc4b77390a3088e7de30ec7873a5642eeb87f908d86129113ce000000000000000000000000000000000b16ba2f42208ec8aeb80a7967f667f002a55272fa83b9be910fbc4b4974a273b4edf45887f1935209c026e44b3470e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811c178195bdc73e7c33cd10f4a0fe8e41dfe230e334153950028fccf9ec804ccbd726990e7d6c5639552684c18bf320000000000000000000000000000000004ef8e3c72d14c79a226a8336f808c2b72c48d927907b732fd99f15072e3c81dd39a1dad5b0da1b2fce3adbd74bbcc9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003149736b1352b7e23226af2aedd449881fa5403a13e7649385032b030f9f715619862a9c2dd2f1eca777898b339d4900000000000000000000000000000000013a55a271fe5c02939758bcc631cb03e8c98a3e47c4a05df3e2822536538391dac611b77d5aa82b098774fa38e1666991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001314ce1ad8e1a3a35e50544a7ff3b9ef1eb6ea0193eeaa1d2968046b4f09f8086f3ff63c048753d20e30e9dd4272e827000000000000000000000000000000000cece16e82979dca32bf380982025270caf9ba81bcbe2c0b978063e7d6bcd1cc2d1b87d10711c25cdfe3399bf847f11f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b063dfb76ed32b09e807f17e347807c5e9b1408bbfe82c865e4013cd93b980e2e5afad45973cd865722e98e2b7483b00000000000000000000000000000000080833813b73cdb0984d33bd1d51266965cb951a5b2981c8b17155f867edb896d57dce1619646896e301a5f4846825ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043ed3a325a82269a3bb5ef98cb94f08e0e9b490bb408ab21fe305ae32dd75ebded16a0a5efb0a89eca8c6a0568e32110000000000000000000000000000000009f0592ff5d0929e65a1341fb5525e078a5319dc1d0e4e8b8e11751ce484a8b19acc9090c42ec46e6761db637857f8771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3a4b87cc251ad311af3dd8db1d238052ea94651352c0093492e4ef57aecf21de575a37626e762d17378a3ce27d7be000000000000000000000000000000000141d0d51a2d50231f762b78ebac3c59857576927aea9a4bd3a302e4328362cc4b8f829792c5a818ca7e33434aa0a0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c521d9fc7ca94945c5d9d8756f7ddff08f9d1ea012bfb77c3fd9f78fc30746738c196fe6f793d10ee06c552fa9c3912000000000000000000000000000000000d2abe395135a540564abc2ea1151923e13ea05d87840ecc9aa0cafaeb1209d8498d6eb024fbeca3276b478d41e45b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140e53c54c48b5e00134d8ae57af2cd5374a191df05f6248c2d51cb1a8630b86d070c2743a20cef26043ccba2943eb91000000000000000000000000000000000273be71d80d705c24217d2af91b69ced45a8abc17e67c76e2c370af5a05eaba9bd706421141bbfe7f44d47fd181ce591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111d6765dcaa2b9c539f5c9df1f727e41945f1a0c0394d2fd6daf799bc331a972e1a4d844b293da427adc1bb3fc9f36f000000000000000000000000000000000142b3d87e2b607919d6abdfa81efeeb3abd092eca502c18399a9b4205787c7003e9327f6fce1b85fe76fd5cab23cb7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000933c400fe9431ba93a3663e386b00dfd35a54b4faf339db14d4410fb0f3cd63aa9ac6580082e26a7f118512a8206f4800000000000000000000000000000000185cfedfbd48fdc163f854995737153eef4708601a1542773912680c9f1e264027c93cd137d0f767124e593acd4af2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000762f284c082cea4262660a404614faf737d4d70dd7c270360888248c081a4090a4aad047143f84657ee321c65d065d60000000000000000000000000000000004be67e36ff93aedbc832f5d7809c7f6bb45293c5b953d25fa11ddf10f7bea99c1992c241c68a4dc51c3d4c0c1b7c9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124611fbba211a186ecc58466173d5a219ce335cb4d239bb60873d10e982379b75cd9ed60b22dcb17e0aa4f2f0f53e2b000000000000000000000000000000000cd4951d1eff4ace94331303b93408e1689bd0c3c2a8439ffa8d1adbcead124b75576591cae7ea503d4b58f3a08bf8121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a506c0785857aa0acfc1c3b9a5cdf83a5d17e507f33b7a082adc5395baab436fe01a13f25e2f6c1be3553cfbc33031700000000000000000000000000000000150f07ea176aab73e149736edcc5d34d49400f6c57a37c599328ff822d74a9079b42ef33ae01219bf017f79c4308a1cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aa7bdf0a75e10c7211c155727326ac964af2484642138fbbddcafc6dbb5e617f8c659a2dc400526cc2481608565cc10000000000000000000000000000000011f74e59202b79c3c231b29695a841c9120f4dd68ce5864c5f4789c404aab8bf2e0c6e18c4abe2dfde5cdea50acff99c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174fb722dad03efcad8a91f4ad4ec8a7d577daeffbf724c281514ad1a331d3d650335357274a029492ad11efa294ac4d0000000000000000000000000000000009b13b6ffb6063a678c49cd4e1bddda88cff5dea88df40758aa0eccf95e46da50a22087c36dcd4a04e6547d7144e8b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348461ecf787f12563efe0cf0c1f5988f56b55fd13ac520f4acca53a2f9e19af4548e535500ad381dae30be60614c4d0000000000000000000000000000000011ea3931a1dc682177fe902c7858fa62ee9df7251a5c1b99796f33602520222cc87217b0f727bfbd93b6a3cd19e0ac391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f2807a0007b494f8d734d8b3eef29385f274d040f725352be537339441f3040c12116b7a84e49ebbfff5e778507020000000000000000000000000000000005fbcc42a8f28c11281d481e9f804a58abf1920e1a65f159dc8fcd4934a2e041d3032e3a95d0c84dc51e0e11aae3fad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012be6c9ee0ca13b8a5447f45fbb006771862ec48f027dcc55fc15f62a7fcc240a303eea805aa52278fe4fd0e280f0a7f000000000000000000000000000000001644ef46d1e3eea8ea2bdd728ed91a0c660d0256d85859f32e6490c2f5449c03748905e1518b8384e3224f20d039bf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a1b250d9c69ede6574fba8bf0472dde873048cf2bc38f695f29fd81dad746f095dd42e486037b8fa70d04b98e9488a00000000000000000000000000000000156a7087177469d649e33f8ae7541c27e90410b91f3680f858fa7c543e59c9e72c0d1146a1636ae839af1fe77b1cecb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671f9c314b848b8469f4813bf60c76e13412436bd6f51ad653ecdd00cd248cfca02ad08d5273b2c31fca2fbd89e950e0000000000000000000000000000000017a4f7e5277cd5feb2bf4928e7b9505c1ad076042ee709dec892760e7b419f4362e62cd4d6188e99f7c3eaee3cabb09a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8ec3c28172c233c0b8738fc4b011b055709c9ce1be04fd77b996babf1755eb75233cddd67dda45f771bcba6b58c7ef000000000000000000000000000000000fd70a87c019125e0628c7b1165cdfdd3bd19405628cc7e8646d55c83a9b109aea563f5d8da21d47b0df8b0417cfa05e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025492fe97c73962b601cc101960b2c8320fed415266eda664ec550243943b45db460ec116e889b0f94196c31530a1840000000000000000000000000000000014dc3c680abeba696827c272ed9f04104348593297a58788e7198c004c3e8e43ba8a3df13c0c79273ac1387a1c60d0ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a755d2e452ef95db10d824feb95286f9123877bf61ef973e7abe85b682163829f78cfd738ebd9a8ad6688539e13235b0000000000000000000000000000000006427dc1402836734d528a8806a9d4188eaa051407a3ff35759ee17428a718f5c6f49c23388b892ef31cada19f272a0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b77275b7a6f7e11364b533db09d06a32e9c9da9026177d51f64735c2c56f72983853fde4c467b73ef105f3a5ae443a000000000000000000000000000000001307bac72e80b471fa4aa987291c58bce55c9a87dc891e201bcc51552df118012903187804e436dbf262ff3c998429d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003975a28d20f150b5401070cc89326906071d5e5eeeac33a6a5502637752f8269cf42ea144ec2341c22c70de24fd4b160000000000000000000000000000000002d3f2aabffd93f15fbe6094a5a49d8f92bc0971412dae7bb9e759460252cd70a206fd68391362e5f6630e139dc0541a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e207c190551cd071c020ad92b96a4f0b9be4fec42edb1b61ac03cfa097f675dde001bf600563a7af92803aa1fe83978000000000000000000000000000000000df65349b486a1942efef08e0abc980ec7def10cf0ec4ccffb495ccfd5d86d11abf5aff7a30ccf0632c740281c8ea64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ca44f4ee0025619ffe68769ed7392449ec0be0481ec2c735060241b8cebf54db7c98af29a4eb61e370bf6707efb13c0000000000000000000000000000000007c9fd725796fec1df27b23feb78fb9499c97f452c65faae40900eef68348fb21c62f5c0d1f54c6fb444e7e37d5de21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001731e86b057431215aec6e17f1b5175d8f0cd645392568f57fce45ee357ab6f98d3ac46b0b529e44d0450a82a3a24b0900000000000000000000000000000000133adec624a8e434c8a38e05888b7765c715f91c9312e976bc18aa6e633786d79ad2c37975feef494c6ae654c328eb2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e12bc922f44c44fa39c6df1e8b0f2a4029ed54eab8ad1787e27afe7a66a7964ab5a25346600d6debcd25fb18f9b2641000000000000000000000000000000000b3777d782f9671a93fe5ca28d5b36e4c2e6f241570334614058a31382d941a136fbfe9843e190b731ed19ec8bc648301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fb13aa6124d72667e54267d08ae2fbce363445aaacc5e5998e48a505c3e834c7dd1c183edb1e00997fed082bb169d4000000000000000000000000000000000b73b94cccbe87e5d25f4e94a2023c4149738ffddfcddd38524edffb6af321933d759f2087992ac7280fa0b73422056d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b480c3f10d980383d208d72b20eb9f49870b0c5a37c718768485c82dbe9e8a81e2b14ed542fd46239a28e38c65b480c0000000000000000000000000000000005696db865fb41ce037f4b414fe3634c61f50c5b9aebe36fb634d836dc61a7814169f6b642589d6522c0921014b980e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016397e2c6f2d0ab33736e8cea2ed87f5d565ca342602cf9ed3366245f4d8cee2a910bc0c3275f86fccb72a6b0eabcb110000000000000000000000000000000014feedc5e5cff755ed7eea591978df0d170eae3d0b86d646b2a8e72d46f59bdc07e788568f5f0cc461b898a8920c8ec41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132589a6a7938dea56b5a6b6e7b46dce23c0a33a8d1b9ef046e07416e1b4264f17868d86837bd1425d6598de4d49bb100000000000000000000000000000000012c1b6485b69b9fb385a7016023a40e166baaf89f4d466d698899228fea35c77039d47937dc086222177f4d54e32ac281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175d8758b3c28fefe3b34f46f5c25fa7567dadb691f1db89537fe456579e42c072c39efb1febb63a196543a9450b933000000000000000000000000000000000081d663d7eda00def9d8b1c2898f56c11581ccda4d39f6bd696f8ea99caa966943f38ecdaad7a40435d40d02162237f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149ebf3e20f69f49a195cd0cf6f28b0e25a26923d94713b434c2c0265ff10e54a729ef6caf3713477f8da497e6e210720000000000000000000000000000000004f05396f703d55de60bc31fa7ab97ebb199315275833fb9415c4ea122f914eb906b46d65e294a5a8a247a7401eaec321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027126bd7d94e91ac30f9f9b9a5096d1761f1edbc6d4d5721138238ad3ed1877f6fd6feae4a67efdd16b000dd04248d700000000000000000000000000000000094d4508eae7dbe0ada5c6774a9f5ca2b9795734fd5137845232248e9cf51c6e3171bb0db255bf3c1c25898060aa6e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013341daa2a745adc0d0ee34f2392298476fc3b1eb295f1c7fb62bfe0b88cbbe89ea58530c0aad90513eee62a7420a1000000000000000000000000000000000007259a178dd247847f6b933a333b98564365a2d29447d156d6f1514a674452f2ac797627dc7e471e6e21f8a453ada5d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d0005a7bf3bd27bc6ea8ab49f5ce83c374c535f76a9e7f039292b830e1f193a50a84f41ffe5dd55b83ba210cf3e37900000000000000000000000000000000119f069d93c6c1e0b448adf3de843e4cc370ca2f16d428278bb632c6c4e34e3ffe24d27b162ba5da92d0c487a43f14851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001544a235a132924f7ae985965acd4ad409043f61dc7b880a69786621c417aeb34b026299e0508e78d581bfea2fa9afc2000000000000000000000000000000000e3b93b553b53374e856d70cdc29f2c26c38c89c0f5d80b7f46acfc2a54b42683403e805f4eac6c29a65799d702b35a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159322c900ec37623ef56fbf72ceab58f89c70f4ac42aa2b4b526569f92b405374bd19a3cf58d836adcb0732bc4fcac6000000000000000000000000000000000fede779dd11eedf222e80713bf6f01a92fe4e15431544e6d10a7f1147d3d02232ca394f735a43ba12c7c810292a87491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d922dde2cc3cb5170bb9e26c3887410d1abcd1392b76793ae3fe226c267734bea16d3749b5c335c5217d8ad85e1270000000000000000000000000000000015d20038526a12199959f74bed93515ace97dc09530868ff4f172f7deb030ac2ac2ee92b4782d4804fe3918cb5aaea271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2d2e8b389241ecea9213b810eb4a66ce9e467011d8361f379a9c40c2f073df1bce54a4ee38b4a022b87ad2e2ec398b000000000000000000000000000000000dbe06455356f3df6a917dbfa25f4305cf0f0b2b3db401b4a246de6201016d18a4e97f32f3ae5d6c3f7c36027e0698aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e694a8f18e3c27ace9566cb294b5d7534b3dd29f27d1876e2f0374cfdc7b3223487e2553edd4bd009583e02dfad09000000000000000000000000000000000cfab86e673594f4759b2770d1faa6db3fe6e02a5a18c0379ea26f2f81bead5dbd7a551727b0ee3d490d071ccb88c9831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000421cd4a80bf1dd13fe4629c7223f90036f680457129ac1832de4c46f93680e75280ab6fb37550da062db1e53b3d5625000000000000000000000000000000000737e00b47d2be7240dd558e01c25d4b61a9931d57a3d435a25a7909ca48d0ea672d74e7ad9c101372be2d7b67581dfe", + "Name": "g1msm-1024-jwasinger", + "Gas": 2138112, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000032007cd3b483e58ad66b9d31e32576d448922874a6a811bab27c6b99991b1760667240c17c8f725d14b9ae03d3975ed000000000000000000000000000000000e074e23a2f0fed94017184199ba2779a4728d33c3116c6634206eaf46dbc149d9531e0428d3ae98f33e3f8078e4c96b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b3ceb0412b1887a8e93debd54b8f853521040f44ff311ace6be13037a031f4e6347abba34eff95b7b330d34bcaa5e0000000000000000000000000000000015ecf07218e3155a8a93c6a0c87a91bdcc0783f6b9de0d49753ba7cf833e643501e0bf0c308762d6b5e11375ac86740b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef5a85caafdb82adce7441ecc0322cb457d1e689512310787e98e378cea1ba91c18e9a520cd1cff8f6639365ac99ec70000000000000000000000000000000007501aa83ee78e56907c2ad81932f35d35c37f4e200d6a6aab2c9a54699a4d83cfd8ed43c60a11a2101b0c020a2f89981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088f4fbfa210d9263a014e688ce17b51784830ca6522eeaa3434cc3199cf73f7c636b4a052237bd52e273ace2ffaf7bb0000000000000000000000000000000000c05fbab30db84cdd7c63ccac3abffb8310c65c257af40a0de928dd28e5550046bb1bcfea5fc3085c118dbe0c9f46c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143b927a4a23924aeaf3b97aa0a6dcb5c2e609204414a39b0693affe36d65d33e059d9e3d3786f3a1ff9c9c7346bfb6e000000000000000000000000000000000754f407226e2b080868d3da913dcdc263cc1253098dd49d763ba671b8bc41cbf12e87b878df1a936cba0cbc01e9b7631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001286fcdfb4348c9f35dfe3e006d8ee64d3d09a09163ce6e4c17c6b09ec6f487e9ee44fea6c83666eb86ad4e59b8e44b90000000000000000000000000000000010923d71f470fbe0d26d4c3e4bae44cea3cc5d1a358f1fe1c0bb3c07e745b221058a0ac75d24b09f528924a770efb8591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2959a6c02274ca15b459e88ba5466eea318686059ede0935e8d4f5e8b60d551e2ba3184b3b058dad7ec5dd4b2d913f0000000000000000000000000000000018bf3dacd0542aa7a388684328f67d0971b4045f2967223af6f280d5e42b33e238b69cb43dbe8ec07c36bd9eb08d9b321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c45fe4ccb91fa877878719f8e3146672a72d6fecdbed0dc4c76f74cb8a32959dad028c9af5ceb94201b1a1b1f936370000000000000000000000000000000012a67ae13f41d886cb552177981681f035002034c31dc0252fe704b4e445e94062a8cac411f7d260364ca09c745889771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e351934bd8d5acb96b9a6b5cc496f419faa26d53130e04f8378e4c0c8b1f6efb530a97fd7a5f46ed8b22a683ee6c980000000000000000000000000000000010f37d114779513790d73a4f7e2945dc443bfcb3034a263bb02c44c204750266d9b14c9ed8d7a4a9ee2ddfb1daf837fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb7ad23b86d661c2d81f74e5555fa117eda06e18f1924f31a1eb12fc3b8a7a33f12dae599e21cb1aa447405cb69c348000000000000000000000000000000000442833695039ef95667eaa264b5ae242545edc1d1cb98e650985dd34f4f4d6c6f1399970bd440e6c5d7618e0b75449d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d36103e4bfd235b508df977273bd25b3cb595ed2b28eb23e7f601350d688087aa5465a4c16d81e5716d2dcad03d31000000000000000000000000000000000bb49310af633ca47312a14055ae15296c64b287de7f62641d092104448945faf27af92e0eb5f2fe2d92a83d77baa0421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4883ebc79f7b950e1ddeb699291c79671c41642b7dda699c796bc668f194ed0c4220f00cd466cb370a56f327445027000000000000000000000000000000000bd4051f0e7e2bcd9bb0bff7ce07257429ec684b705397ee7ab0e76146eeb1ccbf3e253d9ef0d539d9c6bca197a22ab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d381f5d5a0a8cbaf34d0ec9211a1f35f0ecc8055e2c93bba4ae05cfe3e9874323f4c30afa5f43cb71ffdda7320e7dd1000000000000000000000000000000000b90dfe427466755871d6c0dda71382fb9768a0f39e694a319aa182c84f1e7049218cafe791a03cfc3afdc604d0ffb841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5a81270434ec9bee1ec77cb1cb9302e184f88cdd0248c8ad16ddf5cdaf88ec5e616fcd75f209801c26e316dc9b3030000000000000000000000000000000000ea6967b748a55b34e5326a517c586f124ac90743e122db0e28f1675492acc48d3ead68e475e054f7e77e17ac1c1dec21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cfe1a0c029ee59e67b00ddf61451f85adcc50de559b40be805c4575af2699e4a311ec0ee1234429aa0ebdc6d1921cf000000000000000000000000000000000132bbe7e63886bd9922ab742f1a1b61d0209786e3bf640fb1314f195a1113069b0c2c7eba636b240d8f8674969ed1861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038b843c973efad1b8edc51e346a3564ed54deae2b57845884b78dee089bb8982fa82deccd47013ef7524d7df13490b80000000000000000000000000000000012b8778b25cd1cc301f22cf9c4918199035bb68d2d7a1ec5dc6873ac0983227ef59e51838520df74ce20fc8b70a0b7991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e85bab1f99f515fd31060877ecab50dc8d494ec28685ee048b5a4a252eb0829a27c08208501b25cb19dbf188171cf94000000000000000000000000000000000c3125746a939e59f4902ff79abcc5d4f92dd087d89cd3d2515dcb8c6716a255f9e2ef52fd3ea18b453158b2ddc101e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001067c1c7b32ba31ad257a8c2b249362e3802de0d08316826ccdf5d0620292feedfd0947bb6a8279e8f3116d3c9d6a0390000000000000000000000000000000018cd58680a615c13bac94648e1c651b98fd4490b18267e86f7a733d6a1fdd8ee0c6ff3c3d2ee33466e03e467c86312811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021679ddaeeb1679f165b53efb32dbb76f3c3b7a338a04efdf4564d6c0f642409be752a9cdb148284a60f439dddeabd4000000000000000000000000000000000bf6ddc74dc5c7f5a7e95d3ef36e7afdb5fb620066709ef1f225e2865a2e808fa2cfa8d9bb461c6d8c980d22ccd5f2541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033f40464a093aa771150801d3fc2124fac5d70a35a0202284baa9e0d1e926036c1d1636aca98b5999599251852108210000000000000000000000000000000016ab78ff003361a19e3c2fd0cf0dd1bf81d947e7b9d85835a7c3e930eace725fdf8655426e89dc19b837c90dcab546041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e6f927754ba9539ee3fbc962394488ddbeca108ca74d26e396652f49b58e2a621bb5a24eaf4d5ed68bd04e4f888dbc00000000000000000000000000000000172d6f63a7f70d89a6cae192d069661775adf6c5297eddf29ac7c2f1fed25c4d07994527c31977060154266239c611d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689095426885beae3f8f147742ff9f2c904885d7273f751dc06d8337dd89ac888a47ce7a60bddd1a6825c032105a5130000000000000000000000000000000010e2d430236f97377b55b3ea938da46e7894caad02c290509fcdb11905ec51e8d4c58f67f6be23640f025fae1e598cc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003a6c6717dbf1b3a707aa7c2d77aa2b05a58c87b011d3fa4ca549af916e3cdab14c318d7f380fb258fec7ea23399ca0000000000000000000000000000000000df4b139cdaca8d8093d8c4e73ba8debec68d79a98f8b5a71d0d5b6b22b8968cad2ac068dd10bf905411069eab30f7d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b8c59fe028f1e9de599a30bd461ff6a8f52c029bee709e136e5d389ab0f17a5bb684982cd8eec25a77017a4412f979000000000000000000000000000000000b88f9cdd214887939d4b5b3b0b91ba7012f50fbf7211d40f4b1bad3cf06de29a1606b75cc02636527149e0bd6c208071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ecdfbc63653eb22469763509db3a462a06c8b55777b93c973bd55b4ad4d556a3f7d542334875711e636fff27839620000000000000000000000000000000014d65f36ec3188b646ed06b3909b2b68a33320b710bb73009484ff54c4e59b13003d9181fc3c5ce78f0d24e250ce59c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001085a46ab150ab3c9efa1d27cfc70c097f3d870150bc0e9b77d3281a3ac236f60000991693d91a46229c31a5bdd6097f00000000000000000000000000000000120fa6328d34d7fcbd7d9ab28640bf3dc5607d2ad019d2772e44a7f4126b36e0c6754d8810ab835c98f03c3edefc22941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001052894142a43feace25e0940ea0eb9109446235f9d80955296c0e6eb9fb437752730f375b7574b0ce51e6e73ffb986a00000000000000000000000000000000143a9abb96abbf5cf89ff70bfe5c6fe1b698070e47f12e3836d83ef273474911d4a62343eff96b0b9e6e07efeba197061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159c90d7142b25b142ad6273b80408d31c4a5f25f8bfdf8c6802bd735d063c2a4677aa85daed153323bb3b9c5d4c9200000000000000000000000000000000084d099e93955509c53d0e226be0fb1925439332121ecb5f014f5084b509a4618ff37505ef7ea963eaebb0503dd3dd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125341c3362719ea01c16bc7cad91d12d61d831d0e6776ec9d5b6977435a997ac959f8ee87d1afed5d635bc51a5f9b60000000000000000000000000000000000bab67b2091caf5d5e2ed5b9582f060a6e34872c672bd063bf42a9d962a55ae5cc921a6e5444c0070cb52ee6bd83d1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d5e6c469006a4927bcfcc6d8e44714639f8480e7d781a778e4ddb32c8290fc6840b208650cb2c3f41708b17b21eba000000000000000000000000000000001030727bdc730e39eb9cb0cbf7ff49279869ccdd6e7b72ccc00802de953804f0fd3aabdcbad2ea3148b0e7dde373f4961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182d1a8bc85002c762603b0857cab576c68ef1353f3c45f7772a24cf0a684a422f5747e2ebfe7999d54d4d8519f9faed00000000000000000000000000000000073350f9440de88130e07f826445cab28906741ad8956a54cf375030d8425482e3c8e3ef9c74c0f2ef0d9e12a3bcd81e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997d74cc5cb14562556df3c05282a3c71516d2635477bdd6f3dc103c9251efb26dd269c7847cdbd538f339a9dd5b2c300000000000000000000000000000000098262680f3971fb3fbbfe40be99f80932150620d3bfa299322be22291d03c78a62c14816f125dd283b8adb72a827a1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026a87621ea32b6d66ae8f1255d3dfe188224c42f10165fdf664c4b63ac3c387dece6dc786f86f083b6c672562c2ea0f0000000000000000000000000000000017388f32a0c1dacb6eb492fcedccb90a72c84258e374bd264c69f5b01ae376b2abd697f0236bb27c72d94e3d81ca9b951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2d89c80df97d1427dd94e59ba07ea9aaeaff6a2e36cf4d34c40e7c75374470d73bc2990f9e6dd79d25c038fe49e50000000000000000000000000000000000baa6f4e1239f2ff8ff0195eee0aafea0628d4aecf36ba572edce0607dabb8e82446849b08d52f8dada4a5ee496ad5d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019250da40e17a94e7aa02ccdf4ff466c9c6eed3af7f37eebb91c4c331f1c8451d82a6704c4214bfe6a0dda87b0b5f6d9000000000000000000000000000000000f045301c4fe1bfef3681d4d5f631e5fad1627a77c8a43c19684b1e4847e195031fa47dae857fc2077019e2c7e7b24471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b6bf707e25e1fb6402c32c7b994f64ac36e63c774afdf17091f6ee4bac0106352e541a4899991f0022c4d343d7db5000000000000000000000000000000000307c4244f1159c1324993a252012856242d578360c8bc6e3bfa706fd5766174bb832a69b2c2c472d56e2353a238a62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004469855880a8a089eb7006362650d617ec5e09e67889bbfed11c6342dbfc20b966cf73e473adbca1798746a0845ddd700000000000000000000000000000000030318e8e18958ac777c7716d98a07bc81c23b3c34c7df73768f40278ab36b94f187c39280eb9b239ae3e875818fcb451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f8d347c12f90497d88a3a6ce49c993af8e35921c9c2bd790d160520fa275877a7d0e56d0403ac169650a6e449c7838000000000000000000000000000000000187405f96434de0e073619bcab0ff0f6e595bea588007a0a7e90bbefde4e5241aaca77d4841e7690c67b2029cee43311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b964cb25a3b580053fa30f91865a24c0986257cbe9e46403ef98416f12d04ffff5fabec3e01de824a1eb072d729e0700000000000000000000000000000000151de234008bd69b51cdbc2ffcc7e2d7d7c90b86ca05fff2b35b19ac339582feb01885315c799b584a7e9eb94d3a27261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028a6dc8bf282283ccfac9410426f70431e2a12bd3b30c8cda309c45ed0ba7fd34944d45055144604fcd4519158ecad6000000000000000000000000000000001412af8ad71474649d27334d19133dbdf89556dd35924e081393498e4118d29b34ea211f270baf63ab64320b42ef78611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037c9801aefb7293e96589fef72c0b20911bbf585caa2b62b2743418366696687e8d6ad421efe860c241c76bf4045db50000000000000000000000000000000010c20eb3608dad85c1ed8d3f5531d5bead8d5b939b70558b572f90a383707014202b1c2c940c3f96aac3743a81718ed51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001779e1775b0a6c342c85ffa896f2df91891bb719ce3b1f5f09913c17cec6291333fb1ac28d4f5e708eabb2c02dac3cb10000000000000000000000000000000015c09641e704667026bdf4b3bc78dd62205e01bfdff6ec52de776ed8a3bebb81452170a9926ce90d6affc70667f138911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001866280c6def3853ead557c96924505b12421a3813f6bcf776b0f01b8d0ad4e33699407f60a01fdf3b623b2f6c36a97c0000000000000000000000000000000016ca2304bff90ba992d857e43e51484464db111849946ed606b5f5fc769afd1d454d8eeff25fa59d8fb86cee3e45d4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171ca1fe6c3a569d66f1427872d2bfbb945a3515c71ada66914eb5b39b9e12d66de4cdafc4d1fb8f64667070d631d40a00000000000000000000000000000000165a23d82e31b797356e4cba86c4cdaa92f2cfc9750b056a84ddee5b4d21543fabbf03e4760df90de2b0a80c0c7a25c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012207fc1854a740cc6cc443d7974c19a0568d373e404d4ce6293ac4ddf4b81b01c67b88b1c6d4aa075765ea55983b028000000000000000000000000000000000cb790d9609c18371be48b834ffa53ea0375b268e593d084172f522d6bf58609d473f1ed28825df1940e6ea08b0e63c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219f7ebb4609d93161b954b54696884225d985519a3013c64bd21d82b209cee5f9f2a23b7c95d859ed0a5b9e0cddf27000000000000000000000000000000000786453141e45096929b03dc2c7710b6a163e4fcfc51e73c08fd20878ae8ec431105d000eb9374e183cb15adf96e6df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002efbdc82c92a2a663530c4cf5eb6e179b5704dd79c472d24afe2f7514766e72275a1ffebf2d29336481f28bf10fc9d70000000000000000000000000000000012de417a5aa2cf3ba38faffffade38eacb8a829771b8302ded729f0d1e02707d62365e24f6fc5ebaac8ebd382917d95d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019951e64343465dda2130b8f5917e6448dde1b2cc4e76e8af410f2040e82c7865b030b4b3db862328c99850156ef5a3d0000000000000000000000000000000001009b1c9afdef8f6a8df4a87de5e6ef0d61d4b6aed2b721e9bef84a6e2dbaeec4307d47a4eeb155f61b7f353bb77b9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f1ce3c8db6d7f744fc15df28bcfd48b3cde56a52e9f78894e08d4a770579c01e6dbfda682b1d7ee593660a249ca489000000000000000000000000000000000434f7cc6d08ba7ed39b57a33edf80d45e9c5493854dd74e5c42c34af9dccc9c58c265c53d449db86653fbb00413083b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006598c499533b0b32bf8c7fef46b2b32d2de899182c79e1082dbc82d3fa749b7a96acb1c1cc2c0e3cfd8a0bb0d27e68100000000000000000000000000000000101b8e6fdcd5ba1203b83521b44e65003128b36f0f27a19c52744173331a15bdb398e98d1698bc5fcff8c82704fe0c311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006dd5a4b9e21754f0d81db9bdb0c6e2acb3a57ed1680800ce652d19abfdda4f4fe82108e80c135bd66992dcc0f92f8f0000000000000000000000000000000001512f2aa5a7ff68e38b830e23043d99730a5e6be3288bc18925a785c27e405b8f98ad48d776bfbbb56039a795237ab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3f4078268aafbd374ef27a85128f4d0a2d6e28a68c09ccd320c8b61942b87947d0cebd62d88e659ed5d50bb3e84270000000000000000000000000000000018f64672dc8d1989c962b751c9ed932c0990e3b28579d24f55c72c5a5f715007bc69b0442a260dc9645e86ab65f176c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192629af670e5197154a571d9bedad378b497d5e9d644d73d2a3452fd047698717653de2955a16c4bfc0cdb1940c760000000000000000000000000000000000187a27d93fdb7710a54bdfda60b09b62f69f6f7d4a18c8b15c80dd8d57eda20eb9bbe62af1b72ebb520246c81eb4c12d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000476e95d2e71ef3a156fab73b700244bd9512eb337fb4b2511e1648f1d0de6c34f4b2f38bb9143d01f3db39f8f1255180000000000000000000000000000000014443354ab9822c7dd6b72ad979a39539a7ac75876fb16a4d6af4cdaf88ad3826c3b168b2c8f2827bf2b0092d6c678561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef83fdd7c3dd23ed4edc8bbd32a553c125a3f9a8750170c70e248f8fe39e6a385d0a021769d361774db81e5be00022d000000000000000000000000000000000decfd66779f3ba05fa4e5fb0e189d4d20afacc58553d18128a8ea98a67729526dbe682f61db961112082fa1aa6e8f221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc0b339e5bfb39f21d9be6db705c131d8684bad473f9e885ea545dee22918bd0f1a86841140969918a951bcd457c42600000000000000000000000000000000036a51df51ba575651a7458ef08168c0694cb848625d13e2f5b744e00fd8ea8b878cb60f1a41e4fd25c62073ccba66081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b684ff9f60ce57b457224ac43fc5d88d3f94e0ecd538a95b5c8c4d6a29361a8d43dacfb5210380634f08f343a8b564000000000000000000000000000000000a6708684cf5272742d3ea7ce0dee63a0106cf28cae80e7ddbd2833013213e7f763af1e8e2912faea1544ea0058696741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1ed05d66d11e2b28f37c5098e8e707f0751bdff48756343c3a54b45a126ec5af938c03d1c05a714a2223ce96bba0330000000000000000000000000000000016eec9338cad83721c90443a91cba1606895ca7ad61e20b4bba64ba541cdf7cae5c6c753869fba35f266927299daa3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841dca2a38bf9e33876a7bd4cc092535455b026c3a80e4bd0403cbba5766d491345a3560c6d265d93e40e1c5ffec38d000000000000000000000000000000000a506f72deab22a3724b94dd7518a6680efceb7a8b0d33f066f338f97166469ec11d27a2dfc7e430e9121a0c555ed22f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fbb69704970c1cd56e0751721a4fcd8dad1b2d3d14361b4229267dc76bba021458b1f69a14957a10a5f58ee32f13e300000000000000000000000000000000014ad8937e701ac0c969a97e64790e693813de432e5f68f78441946f603698ae0e39d6483453fc54dc7dcec21ff828091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040a43241a0a03501dc6c6af6512243ce956d9077bd0892d72c97f5dd558f31d8dbc2cfd0361d909454d83a5215b83b20000000000000000000000000000000015f82b5e63c39594bd5309fcc327df698a9f05f4840dc651058e9aea7d1599e51c8cd3af2adc6b83ea8663003747d6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f9c56625f60561739e36891786e6e59fa0702b3aa0b497f66246f9570ce49833e195bf556d1ff9d835b7141d85cf04000000000000000000000000000000000d4a7f99d3f67cb2be1c471f01d2c5ce89ef2fbf985fccfa37fa8c550b9eb87d21844e5bc714b55beb5fc8a183c3d0891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180ac2655133504ddfb97b292cc9be3bf276c345cad53f8ede52e81d8c51f82ec48598f77f06595eb2a071b882d0d9d4000000000000000000000000000000001461783ef9c6b72556d79ef5f8a3edd3d91b9c114412f42c523b9f0fd4a156c4e9789ffec37707c38b793b4730d85efa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cae6aa287a1dd866917a01d9679d1ea29aedab0ffef3b5b6ed8509e1c674208261e56ff1ca375fe3d41fb6ecb9ec1f000000000000000000000000000000000e6c937433f95e25f4ee8aabd24b701cc211bc22db208f422ee45826ec6b56fb6b50fc6c5449d021e03f42b4397b93301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000b7e8f674bad965d023b019912a7d2cfb5b5db5998dfc182763c2db4ae13d3120b9b59673781290e38777028fac6eb0000000000000000000000000000000004b23e96ef43a19439b9ee78bf52490804ddcfecb43137cb8b99ed0be83670c16541da61bc24fc1ce763ffe2b33473531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d73a3103aea50eede0ad6c01810bf2af21ba18533cdbc47c03d69eb26b63fdb54a0661935b9783df2d57d49450417800000000000000000000000000000000041af0ff9b643cb6f068cf1b75fe857e7c98aafb7fe1e2138bb8ce739d674929910dd1830824dddb8dc1e6ed8e795e921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170e16fd0252a09d025b1995478d0b2097547a79b415b4044b8308118bd0c55da08c9fa28c235e7ed8af1cf7b71620b90000000000000000000000000000000015009f6f01560195f4ebfa2904f1cbab5a9dc65582a63b08e45a99c59d7aba13d62b1ca5eb0c9b0d85d0ec18e376d5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193ab882c2e79b5714f30d57dcaecf87519f70a3fc3fe7d6f02a59da51578892f0c7ed5ac5b6372cc5856a0aff7da0fd0000000000000000000000000000000008ff891fa28d25e1215159ac4359316d4da5c0ed9d44b2a941190050e4936a7ecacc3b92c62c75b5c1e5aa4a8d0da46d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115489cf5dd9f289b372e219f9f3c15f768c69c94264fdf6aa6a5f81a5ca2cdcf5b7ff86c9b6bf732f40a99310873615000000000000000000000000000000001700c38ad4be29e9d022ce18377fe05bc767c5997527a85084042a88a72d62a1cdc9049b1db3c6a7a9939deb9c0838b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102de80550ae9aa9e25ed441967e875c3d17519611bcdaa93874665a6b21a6218621dd5c75d2e09bfa4afd5563730be8000000000000000000000000000000000bd608717a0791ae9aee400a082d6bba1985717be3b63d5c8ccb7432ba9f0d397f04e91522604a60ffbc5032ab6ecb0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9a153393b95ed146f6da48f3f72295fc530073df4f22a613f9695cd92fda563184d37c150fd1446b1c2d94f1250940000000000000000000000000000000005c35a609a67e2b8461ffae2a5283fce152f968030d1fc1d330b06bed9a37140fd39e4663524e1ba55b690d6188715e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f82dd7f3672472148efd9935eed494fde50662092b1d08022464bbe8672eee6cdc369b8de570ff5637f9ae04b93af27000000000000000000000000000000000c4005fe2db14371ccbe55257657629a769fd8d3e6cc37e3cd11d79cf1d020306b48ddc68627c98623924cc1749df7901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b41bd861c49cc19cb6988a2e2d426b37eaa5cd32c457c1404d5efb65f07b0039b1bc1f5dd5e55916ba666b1e105d3600000000000000000000000000000000102c868732e30cd7c727653d58394a29475087f6aa02f19b855ab41be201bc606e073d8cd2efbe94efbd03bb06d461b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005150e5832642973353e161bb49f4780ab6bf1e91f23ce7320f585d9c784860f88905fddad1ee558045fe83444c68a870000000000000000000000000000000011027a2af0036bdf21fee8f2a250eb37b9e44cdf42ef927fcbea1d50c74f56a650630fc7984e88c84f58b823be3def601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001156b0ef584bb46734bafc0b9579358476c57f318b097708e8f9dd9add8aae53aa8a95d10461366d7a215b481004b021000000000000000000000000000000000468f36128fbe1c65453396f7f1218f2a28a7b2060c4286653db8ab786e7fdfc51f4a9f6271b7c58651b59409e3c288b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000147302fd7b65c86a0e87e959114784cb65f72ebbd43a9f03d84780eeb0c1efe10f815ce731d91e83f191422d89b882b0000000000000000000000000000000010d0019ded6feb2497a982f5d92e11a11114c535a2434d9ffd3fc7833625312aa3210718ba33ec123319733861f6c3d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a284d05e32251965be5d13f54db18b2548acde54e2ceb395e94aabeca3dcc338741963a245dd4cc0bbbcec2287bdd890000000000000000000000000000000002a7673189eb5f0fc5bb223a7142d32d4c2f76f378b47c3c01d37fef858a2bd913f8c263e0336e149cd0925774574f711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079e02cb0ba6a3e5f0e04d96463f56b70b93b1db504997f865df3216bd310964a2d3f253e180907748c7e707334df8140000000000000000000000000000000001d62217fa6e91423ba839ea8b50a6525c4306b896ff2eec52475a9b675058f9b83075fa91a62ac431b796726b60b1c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001462756dc8b793923770e87bfd8a327f70a83c161048bc868eb47e2561fdddda9f3cbc991544b3d10b60a5de8988e1aa0000000000000000000000000000000000c415624d92b17a8744a468244db414e8e4b980ba04ee7937838447a706d01c68f4bdf10433e92463306c35b76348591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001859da83245613ec3a91c04b5fe32cd4f242f6b58e4823e5d9133b6efbc196889ad70d3665008c80ef7716f31432a8f50000000000000000000000000000000003c1f6fce218c6a206f3e863a33d4151e53e91adc0bcebe7c5ca9c5ce38f49a7483f21a909cc01a2c5c69532aad743761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb2e148232bfc23ee9f904976cc2cd9439a57d5bc221e8ec68fc4854cf5598b06459eb0b3354492cbe2dd211060fb2d0000000000000000000000000000000018ed57ba2f2b86ac7d834d64f7cff8e556e325e9e088dd630f649c3f4617ba4f9c0373508a0c7367298ddfcadfe1037b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ebce2f2e32976fa23c7985a517f95a7471587895b11e9d741b024111ce5c5dda5246f97b3a33c259b271f4d70c29200000000000000000000000000000000063f87dcd69ad605ab0f643ecc81a1e9688d6d0a7b42107d7f2c4f48658db4a475391299feddbd08442f1b65ea92315a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c018cf79452e50882e10fb629829a038f48c93fa916e5793c0bdbc1be19c7bc75ed5738db96bceb99cc861b4953ff7000000000000000000000000000000000df949931aaa56834a119d1a4766bc397153027b9e98f67cf1c9413ab016eea3319b8fe6dffb2ab0aab7d98617e0b1be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7dacd162f1fd7b1def536c4083529561eb0e500ceea94992c78f6e3023b5580d3012b89f7694c7aa9da18c26c12bf3000000000000000000000000000000000043f80774cd47a8a2f3054076120917e5046a16917e0a16acc32773eb5caf25299c6a7c6652b18aa4820d75f6dd97401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001302487ee0766fcff5c21d3a6da03bcf6847ff1e9d3504f69aa9594ea00a65a6c6028050cb1eaaa7c45250fef886776a00000000000000000000000000000000147781f4ee28bc31c1abb5eace55a9e3b58f7b3644f790174ecb0c1eee913e52f6eebb5dcac42d67a482adedc33bb0821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039adec2ede880b0c96e13b60589e4f9e65e86a14703915b6311918f81fe3af2bf434be941facb5ae03b585e7dfc5009000000000000000000000000000000001268f097825a6ba6947549bd4a3c051d59fa6846379778c53872c66391ed59b14ef80d41969743a989149bf7f6b44fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152b4faa107163d6f5e7738461a7539b71d6585465ec3b77cf84ec5f11138dcd1043bfebdcfa26ba58cbc26fb1cf77f500000000000000000000000000000000088782327f8e8c98c3afa9fa2e4f881b374f7c4cfe567b481081f6bb256dca6eb10a3c51ba5aad953fb531c6014e0a271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059069a63e4c1a51df90605f0c604ef23b1bec2f6c2ae87344514292baca2d4adee3b5fda85c00c437446a853984a40f0000000000000000000000000000000014d5b41aeeff5e3c1c9ec8545d400d41da4157b2607159756b4868282b665ddc39b9573979c89ab1a0482c0ce94a67c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010316a016f8976ab60502b324f94ff1a5186fd179238cd8d894d78fb89d6def54ae1694ab223ffac7f188fdb9a1bb6750000000000000000000000000000000008a66b5bc4836338d05f9f6b04fe1a366f37d4cc19eefe5517616154e0711a8385c8a1359e2c6716e5417e2d0d251d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d61f67622c76fe10953b942555acf258a6a73b2101339cac812bf68735e361ec74efe01a570760f1257701718d3986200000000000000000000000000000000029a6562ca4261117a34277a45340ac6385dd77e494e2b639732eed24896fb55c040839d7ab982f2bf642b212303464e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071fc210cecbd2443115d13b1b890aab0c33182e8fb35ec912afd5ad0c1441019cdfa353dd886ff2deda0fe72f6e005e0000000000000000000000000000000013745d02eda254cf2acfbe8c7e5a4fbbfd31d6bb993da3cb180a834380be0934ed51bab195af18090db2b814520d953b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000867815f868c5efd7ffe8bae3f0fe3beb85379cd4264f770e165c000cb49728f7b40386b5020e07f39569dc83fe3dd2900000000000000000000000000000000085bd4ade2f1f134da5af39abda5e5dbe91de3e9d37b1bac92c505971a436d7110b64f44e3a14fec40dfa61dd43312941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca9ca0ff9e6f96ec2c7996b31e79c9103e7ed80b74508ee45adb744be0a18f8f22b704992e6fdabdc05819ddf66272000000000000000000000000000000001731073fc0048a7c92079754baa5a5e8e5afd6bb599eb7a31952bee9cf20e246ffc4e0381dcdf2e1dafecb067caca7881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d934b73bda02d06e90709b50d5d13e2375d7dd674a4ce67c47238ad2b8fe5548aca2af33973b042336cb5bc0b05a6c40000000000000000000000000000000017f45be1b13312e020fe9d74b83cde81db164cf3b17951ed336edd59cc31572295b16e24dd9441a98dfafdd4548b129a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004504d4a96824b343989f62f18a82ecc4a96a92795cc63c2c5c8f7777edb3c5bf16fa9560a699ad58cd152253abcba3b000000000000000000000000000000000b75ce9b422209d35cb380f0d6a1c18563cb23f708bcf9e88b21290ee00449561e7e88857192907d86546959702484111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccadb065435c2a54ec8dbb414f7e14d83ae2fbe09b7da697c9db14c72a7f571913d54d08ae1746650bae6e9dcaa43c10000000000000000000000000000000003b924369ccb05c65e9a4271daf88c3ebf07594f2f05ab7070307ce3093f82c9e2aa8f02c776f766291554fc780b61f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2766bfdf616f95dffda112d2681bb1a093e6c5c65ee8b254d95bb64dbf76efffeedc7a85153496348c04e8c413d8020000000000000000000000000000000011a90ee51123e41ae9b7357544a3bee1e604a1dd818b773ffd181783e5f592b202770647fdc196d4ae33b923b4590c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c5352571653eef2c93d9e84ed8b1a8ebf94a5e8fea352497edde7288acef453b4bd00cf0bddbb2271e4947cf5a6f650000000000000000000000000000000008063c1211f66e9ddefe67cd93aaa5dec7890ca25b43d18b38a999ac6010723861bbd6e1250f70e62da1a0f8f119090c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012769606353454065c2ab1cb25d284744adb5fb9a9524526203f30f0c266ebb9af11d58518b087d06b06511e4329318e00000000000000000000000000000000138969e051a71302ff060f5ad9679101f06b40556d3bc7082b41c1d4a92f38c75df919bc5033fd7a8a32a5f050e994f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c478c5df9ca90ba1cc4367941a2bf68e69159fc4e40a4a701aded777209fc1f8b185e8b13311f5623ff6172e4d543c600000000000000000000000000000000048cbac81daeeb22a81ed04790da93ca2612b708f4f9d871996a6b1e7ef1ddb4470a3dede075ddb84c198097a09b0c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e433bd30ceed5c4bbc555c5f09772ad5a2268ee2adfe8e499253534f066316aba70f05e1193a7e3958d3c7f4a1ddd200000000000000000000000000000000161e8e9c455e75c30977de9678b38bd3d1f0bf6d20a8e3b5e4e918cb6a51f9be833b84bc2d6942b4f366dfe0537217b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beee16abece6c2abdb2cd560554562c01cc42ae3ce8ccef79531de962e3f921b2905d30f16baea0290cfe687903a309000000000000000000000000000000000091d5e5ed66dab10904efffb132dbf633a2edd0c47a511398cfa6c555e16020052fd38e3f3f6519d961aba547cd61351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001002d1aaed3845d4d76b8ae07be19895d1e4a0bb0c90c3c5c8837af979cd1411ee1b2f056280e4a02822d8020aa544a700000000000000000000000000000000179a25f8c5558dbfa3a00fe127c91d819c3394d5c5851a9a9ba5084569f60d5869e4d411c53a5602d4b48747d60513511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194b5f869052c2c753ad31e82caa3e8ab987edf64b701e94a6b4c9432a286a9efee8bb1adf6d0ec592b84aafbc76af78000000000000000000000000000000000be06f43b813da7362f5437f5580ed3d9017115e758acb0267a75a844c1919287ece8b5cb17d9647521a832a2f6e5e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3a14cc154a635110cbe481072d8b783bb2fc1c5c079e946fdd0f53c23b1c27f79908f1f49a5f1799bfafb47332fa1000000000000000000000000000000001446f925b64dfe4b678a9a1c6a1c972f9bb35448aa5d10c2b5d5ee28a6c5e0ba75248a0d4ea7583d524323cf8abf56561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c0b3ce58e00c4d91554f5c4abdde253da3fe567da96c8f73b121b7aa09e5a1daa3743f3d0ab691a3e80f3ce5e88ca2000000000000000000000000000000001965a264a01bd107f9521d7044e7f4c7beea1000d9c318ba3b84f6db395011874dfa7f7dd3e4dcd235d38f893542c7b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013473897769214a91c5ab026f385ff3873b73826971e27955c27891c3b7f10cb526f4c5137f98a1dd132ee4e2cafd5100000000000000000000000000000000011c1b45da6aa3a24bac0575b0a3a109d1c185612df1eed53944c099ac0c7abe1ce61c5079d1b3fdc3746d9d740eebb771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132694e7d6a021f7d05f7479aa171e2e1746cf1903a8b325522bef4b773997f66ca708d786b5995df1c615d8f04e96f50000000000000000000000000000000009c48456478b05ff74ea83221bba6dae5abc14a64214fabe4b092385289400c148754a9f5e1bbc08b6fbdc50654506e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012662e0633cea5435cc896b6de3af926adab899098a6bc0816aaeff8e0d706d7bc9c6032172e65631da76d8224c5bd80000000000000000000000000000000013a93cd08319abab8115b995ee8945ad748bd20d215cfc19adbf3bc4fc060b7e77de956a962afe922d8377bdffe06f5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097dcda137766c1965306264a9ee37ffc0404021b2721a0d05750f62a78c920b51ed8686744ab650ef824d5604d5372f0000000000000000000000000000000000e2fb06b77e1ea0dbbcc0d120fa00fbf86d5bf31eceb54d9e58cfb8d87b4b857bcb792c66f5b912ae7b88a2a00d689d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005de4e8167035d2a6c2ee9682ffc0da2f9ae1cb898c216356a30c82fc44f142f04a8ee68faabf1dd0f9df89428c2317d0000000000000000000000000000000016174869e2cd1dd9d938479a8c43f75f7bb9ade206ccdecae5ee675abeb29870b622e838e5fcbbd94e3e09573bd7f4521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b662d61dd10617b053ac3796e0d8c1cc6a4210c95791b615628fdb8f1d41c79d5281dcc5d62b361efe3e18648ce2a6d0000000000000000000000000000000010063b63e5a0d8b2b0ca168eac8b49219b098204682986a3efb251a8bac1b88b3e6d74f42109c3ea527e9cdba9d41b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c29864c493d10320ecca3f201fccb1e821e83f8a68e6e1eaa3bc8a734f93d592991013b880333edab581908afff7e000000000000000000000000000000001083c06feed32a6ea6f54b59c63856c458c217089cee55626f401cfc07cad80fdfb56483178919095dd02815b552f10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001849467444028ff330fa842950ad471d7f4751ea9ba52050ae6580fb2897e91bbfd185d7d8a607bf03b0758db478ce550000000000000000000000000000000009f73653f3e2a7a5db07f3a41a31c1fbf1d2f09cbbd4a608df8e72a68dd07ea2272d69067d80a074542e33c25661d2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ef0446b723cb2945354ae45f2b32b70155ff8a4f7d883027fc01fff5bd8981ac1b763ec79a7eec0b3fa713796d25d500000000000000000000000000000000125ded99bcb64d92d9de082cfa69e2f2b21af891c049c5f98e24f5788ba3aa04d71e799fd87f02fb020462365fb9dc5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001698f3e1c65548aaa68001399237b87ee60e701116c3d7c77b33343986c98095e1e68f1e8086c05746cdf43049a1ec6c000000000000000000000000000000000f7a64ce4ed9ce2c3458fb9d4377d751369dca025b48029a285f901dd3d514f6f09d71c0cbed576f5ec201d3865727911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9dbaf6a26d6fc045b65098ba16795a80e757d567d8fbfc8187d95f2c84635ed411054e030589f5a1ddb91b8cbdb1c9000000000000000000000000000000000d29ecfe4cb00fa10714b0f685c28900fb6d6bb16859baf03e95db361614691f01c851eb02f3740abce045d22a7892841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cdbb96c7a0f090fdda28d90568d9065ee20574f3f841ef589f96428f7b658f06db8f2beb5c3dc9e8d23cebe24d0d4a000000000000000000000000000000001428857ccf3c898d73821e06accf7d5ca8e2b941b7e8492c8f2595fdad49a2b0a42d1d9320381a5ce6c40ba5939fd41c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d389ec102f24ee8ec8bb9764e895f71e46e5fd2dfda4b572c5327ac2a76fd3ab4f0e23e98a2c3eefa4c249480906dd000000000000000000000000000000000306156750e8b0e8d2499fd9425f425b553482e68d1cdaeb96c9c2f158bbda5d9ced4e581b749799a85dee15889df8f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018556fbe25e00f028acd3d4c6119764118e88044a11b4d256358c71e9b246ce5f0543e38e94743e9db8cc00680dd5bdf0000000000000000000000000000000002bc95e45cef2295a3e7cc6e9d81e22dd755f65ef9515748f183db267e9c627a5b771e11373ce05f1f5072362128d81f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065b19014d6aba377f2adf8c37e9497e36c2f5bdc47d99b0a204d90361d12f1f3ad4cfbff0823ba5a9b4a60758ac3352000000000000000000000000000000000731a6da0852e4583c94224ae71d87115347390da3e6b1666806dfcce169857bd7285109614b4e4bd92b5bc74ec941e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bcb9ccd4bfbf762501b873c50d185e296c8976c96f3d485008446c56b719711f580678c0f4b700e9064265fe9829230000000000000000000000000000000005dea90a4ea17a6ca553ca1097e34a9a92be34a4270a62e6d4a5a74c86c3881daef06b242e1e85ee579c95ff6a45e3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541720a25e3829a49e1398b256cde6278304b0ff29ff8ae766d2f1584d9180e74b852490f620efdc6ed4ae9b694817b00000000000000000000000000000000184220283757a77dbd04f4f2e47296d9b4829fb788faf03463af6cd116b3beedf3bd47f42274b56867f72b74a7ccd0ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001777a85496fc37cca483cdafbe2ae22a196aecda9a43c90312c2ce10c1aa34d2a7f3e4584ad3acacdbbea02ecf17ffaf000000000000000000000000000000000aece05dfdef5e0c921f0dfc04ae9a5f03bb39ca8a862a3628998718ff2c47413c081c586fe2d53e218b4eb6918a6ef41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb84be5262fac27bf796cf2cd8c3f5dd46e9f86c146be5a84090372007df74292ac66e8b9cb8b39db34ecef62fd64a0000000000000000000000000000000001635934b146d516875562990df328cfe2791935bfd61481d2745a849ce52d2d49c238d1ad3338b47d67de49bb1c6235c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159614781925f6d57b8dd89acae268e113dc21e870b2ac099f8b581eafcbb3a7f2a9e58f4fdad1795e9c425d81604bef0000000000000000000000000000000012265fcb86336b06f83539198b57e7893dd051309c3977941c36afe2493f806133f484df54a9c632635a3e8eb5ea83d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001319f83bab38ea61515b0230e525373d5d756442c88724cceb652090e47dbd6de1fd5f98b07eb50651e58b391737750a00000000000000000000000000000000077d25851d2f1c64b14ed30ea48e2824b3cd93a2922d78073a5c3bdd1e2cbd633aca8e3e11435d77aa3640b5edf0fe471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189cbdc7e969aa333fda9d00daafa3ca7ae1f0ded43d19c6ed9b5c29097ff4d7e47c433c71cece756a18f2791dce0ed800000000000000000000000000000000086b88a1a3a3532e54ea451b6fe7bca425c5753fc1fe9b2223bccbaf22b11d27ecefe4c8b0809c4a79740ffb7893bf921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bfbd5ac57dda92068a47cd9aef8dff0e5417c94c031524eca6ee6fad749b24b3a5028f8882d9ac919debe3986d0268000000000000000000000000000000000808ca692cd9690990909dc38fbeefe7bfb2fb1c5538e2b8489c89918657e3844e4a95f67535288cd77db0ff4021f0ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe3b15aac6a8b04cf4f8c4e1caa99f7a035112dcf160a79f34ef0ed725b4e23738d150138ef236132b5b6809e0cb2f00000000000000000000000000000000020d2bdf1a62babe7f685a41b23216038ddd03fc8f9dd8e84b62b055bacfd3c2a8ec2f5663e35199d539109be305f6ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da4dc6bd1b290f7593f27e64401ca3dcfe8dfa266490b3cdd1216dc471d0e4507fa88b7bc72dfeeefd9357d28a230820000000000000000000000000000000004b84b35ff110279a8cbec8f5f00d04934bf1b64671c2a8325720a243ac63a3b601ddebda7443ff406c0910bd7497a401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000babe817d6d5f0a39f0c5b720b31c4f7c8430da3976bd68502bbf42a6e79ba188636193ca68acf73d9f93b4661aa304b000000000000000000000000000000000b4b26ecaa5ab138d3def229c28d4b9207960bdce29e2fa63ffd3f182f86e835826a66b4fcba323d7cff4c8af82d17801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042cef5814745b9953197c0853ddd210a9179e25ae8a71857ca06ece63926692f1f60ca1261503f5fe45fc5f155c0c0b000000000000000000000000000000000b4620e4c151881f6c629fcbc4bcdea4be19a180683b14f5b31a153154e4b0760c6fb5241da531bf4daf79c14863060a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ea4bb25d0f3116155d1f77ca8bf51c8bf48c3a6183299ec1132bd2fca92165a3e39bba2c6cf074c3822ad942e9a3870000000000000000000000000000000015338f1d0fe0871ca513168f25ab1a801bfa915aa03f569e86bc71e2bca55754fd0d834cbcf9d5fa38453226011627ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084249d816cc6ed2cdcea62b58d7852c19bd586ceb3870f36be476160c336abb874e5449c7458a9715a520602340315b0000000000000000000000000000000001607d0545f1d2977d3673adb80063442458d519571bfbac599542dc331566740dc9c366a860dda8e78d15d7c15e30521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185ce194db60f6250688b869f0c7b26bb758d535c35e2fc1308826781c52fa9f168ba6392929a0a762ba8713d3800f61000000000000000000000000000000000db29e64fb43067d1eda7e69090c8cf5145c7239966553262b7543eb5d536c05fd7d0df3f631cdb8926074a0baacb8d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015265f76c9923b8462a2f052637a3172ef371164f75f5dd59efd49b84d4d33df53040de25782a0c1299f0fcde0074f32000000000000000000000000000000000b9ae1f6ceb27bdbf08642f66eede79b63917000c64c88a08ecc4fceb4e0dd83a5448a4cb66e7c0c4bad6ecaf7dae19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113dc2fd6cc3d2d3d41b8573233ab54b055448288088842f5c74c3354b3566227de84b3dbde9555505bef60d349da28c0000000000000000000000000000000009c77c78ff364592588221485a64867933267f6ac15c454add80d4fd22e4af85d872f2ec36651a3167d901a34bfec11b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac42c8955d4487bb2b2e3a9a76c94c2b9b53ef636a949e8318158c76bf481013512df51f6cf9620132c80497d14269c0000000000000000000000000000000001d96c4dea5e0166dea465e490034b31242a8c3225a3f7c048ede9b05a732106c4aff5f099136a8222bb9785445d53b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009665f6e8a77b02be1cf251eb13488fcbbafe0697b7a6ffab02cd222216b830eb70bdb6d7b422258332057244fd45189000000000000000000000000000000000277f279f30aa9dbf6e8e4ac71eab6b2f166b48e5ccf3acfec4df756a8eb85d5fd1e7d1877acd853741c3de70d36f2081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011373b0c5de75897f5ac9a032f067736bf1e9a18bf3681911f4bdace09aab2bc9c3e7425f401befab054a16eea09d97500000000000000000000000000000000179226fe77262079a1f167982df566f7c2af78b49cf2539d7b273f02c81827200eb8af97683ae12aabbbde5436bd9f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000368ec17b90e382b9abc8a833e647d010053af3152696d76bc89d4c84c4860562ed42c04ada7f8272a6969dfdccb5bab000000000000000000000000000000000c167a58793136d67436d9df1735bc0c53370f216b4aea46cfeba02b2072142b2c488048ad97f58b38441d7175c1f30a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c7ab8731a68c8886043f2e5caed45b30f79a0142f374f99b30f65d54dd5350f39e8cbc59e7fc066a0e5b47599b0de90000000000000000000000000000000010c8cdb86060ba474f03570d100488b1d70ce313ae98790687b5c201c27f638b91d6fb28e7ae858e0bb69e79192a6f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b54e262c824b32353517637986da2e6aa2e23053a5c20426c5016f716b1bee0f5a753dc7e0ca15b7f4f53312376c21000000000000000000000000000000000ad1a8200a402136f9d71abfbe8cb745169eb35732992bc8cd240c4219b9ade073daf8d7cc96ade28a16aab4335158de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3584599dadc7a7f55902fa94d69404c33d78def92dd1cbaeba6ab60ed61885004716bf4749662e3d285ab32dce464a0000000000000000000000000000000013adefdbaab3f1aac72b4fe8778ed01c4f2fd65874d73703347e6d6c714718378dd3f03592b77e5d889ecf3cab10bdc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000452cc48da32937293931d463dcad00fb4a7fbbfe449376b38d3942bc84196552a5b66cde42adca0925dd2007dd7d0c00000000000000000000000000000000078e47899067070d935303c40c61b4488e8993c0f4c0f2f55019c74b1bd0404a7f6894d7bc5fd55f7e384e9a00b271f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b029ab55cbbf12314af058055968d3a9de7c195cbf6bba84cff23331bdb49ebb205e668e2f403cf568e640decd20e00000000000000000000000000000000148c6deba1af3a27bfb1a69b9034701178d290a058211b359b7b5c28dacf14e2e48cd3e737318e1bab2f52bb597b45631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120a25de8a703f4ea826264a995cf83ee441582e20cfc64168fc9fa7970d668bfa0167fc81d121a19abb07dccf960326000000000000000000000000000000000440942721fd7054a9e42108fd92260afa5945ff7defc210bd46fbcce105e1ea6ad707132030489848b26e89ffbc34b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067584e32b0a6d395511201591cd505778b26622f4f44692ff33a48844a87e544778896ac93fcc963f459f11500851f60000000000000000000000000000000011038b1a7ff10e7aa31dc8730a7ac9c009da3fd0757f233672856923cbc785c9ce419eb9f26be7cdde3e5cea696aecbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002458897a574f44145fc9e3a01c82bea3e4d7cf3f5f746eb87c8f2680bd9ac384b3e88b4e71df0f2c438a61c216f6c2a00000000000000000000000000000000177ed2ee1bdcfed82236c9001af939391028f183aebd7d78e3a59ede34cc61282b967faf6a7af739a8c9875b9f7750151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009792bc09a1e30c4f67c0e5932c26950de8080ccf292c7cce5ff02bb47644adfff5c9da4a62a55a50b6187041f6ac32f0000000000000000000000000000000009bbdd621ce67fc75d01d7a7a1c33eea3fb87f051f9d161a7598e0e6a65751ae9458b7f9287c42e26d65a93436904cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001498776665e429690285c133b4292f3508628a90e43d705590e14778b8124d09e883fff8a4c9747d437f58eee524e7180000000000000000000000000000000001e73af4f2f1d506d0ba5bdfbb2493eaecfc26107ae75ac76fa6295bd6f7605cffc11c04dab4b7a069ff4d5bb596c2d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ed45cb2432a31100205bce096050f8be2579a68967f8ff6178c7c76e87c2597029668784afc7e32d9ddb39df3b2e89000000000000000000000000000000001905f497d5d2f30f54f1eade15f3f3ffdccf14dcefef513df3eccc95932731d46da3e777ea02255283e3bff107dc6e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151e56a55a8a3a75a6ec7da7f3ad97e09641875f9f7c076420a4c61fd93f76175889fb8538469deae0e334aeb4cde8fd0000000000000000000000000000000006b701457e0be02c0081f1dd4b29164667044291a329678d558fe6d6472609ad94355e2eba16c212cd388b4c0dcac9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176b699913ce4a2577dcd3db9bc21c1ea73e6ce44ed4eb1016177afe6a38ea6b75f8ed73a37e9396f702698e691f39cd000000000000000000000000000000000bc4e399065a23dda4cf31f1956651a110247867560105dbefc307a431e61030c8a7942cda050db8486581facbbec74e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad2e4bdd58a0596e6c1280bcf4b97baaf67443277bcc174befa306262085d05fcbbeac1371d988914bbaa012b860b00000000000000000000000000000000087fdbb7c0d258d24df98043e10e40f986f69dcd6ca9f1d5d2411a86be1889897af289a51b40909e635e0c3ca941eaa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fc3ed2d4f44251a1c869fbc2c0f4509d347b4e3e6d3faf0ea0b42b2fd474323476df128c007be0ceb54926d2fedcbd0000000000000000000000000000000006eb94e026a12fd27435aeb36ac623c65305fa941b5c0e047557dd71d019827b45d4e9b2a26baa9273df0d1a03a9fa8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078fd3c1bd4f816e48c01d175cbdc60f6a9f5d053ded7ae21d105e0aa3a1a749c0544b901f39c862e2f7e651e80c2d0a0000000000000000000000000000000011d634735d8c4d91dab2106e99071c46a9ee2fed7aa30d9de75f249dbefbdf0172867da9f8b734b69168e7b5561588461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086387505a17cd30daf6f5e462e224d4161dc4a308fad82658551c38848815c8199ae42d2e6af16bdc272b1b6513cbe90000000000000000000000000000000013a2987c8eec7ff55cb3cd36058beabe1021bcdad80561ca702f8147ce9b3a2d756df41595044ccc8df7c21651b566e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001485fed6024ee50f26b05f86f061d50872430f5a88457aa187b57a5d3b7cb0dd8efee006db375d5c1c70bdb213b8d05b0000000000000000000000000000000002f4e7652dde9da8c6bd37b9603bbdcdde0f2de628fcc133d51df5b396a5512720ea1884b4f98bde5a343296a80cb60c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103cfcfe3d9e929f40ebf81f329dc63c1a8117c93f18e060c80c68e88cca715b8621e6f864f79231eded1921ae04c602000000000000000000000000000000001398c29a1a8585f6d308f99d3a56acb2eabe6736cf348edbcd03676f6ac3976325afc2a3639ffe7079b42ebeb88a222e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001141d80481f45582d4d1be602d0a065e2bb1e93619fad6ed9fc643560c8fde3af9c01ffb6a461a1931ffd0ef816d74320000000000000000000000000000000000a838f1b5718d5b8de8b6accd1b49c920261992c9c82dce8d99c02a3289bf9cad37fd458c5574334190c432ec557dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007281a214ba7e92b4c9d76b5c048eac4c970cae5190a81938983256b9506c9d3dbaf81fcd90604120e9d743df86d60600000000000000000000000000000000120558c4998f5c07d64a6686f18122bfdf873e1f97b13133ee8bd7264594c17babb4f0f270d21a2eb6916d5f65c85d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001902af0399fc9bb169c1a64925f6d1bb2e5b54ec8a32efd47e31b1e639ad440ac6d3a43265f47b66bdb75f960b2e099b000000000000000000000000000000000c77c24dd3969b03d68e04e6978a7fd5d1b03f2cb0001ec1947d8edc373c2655b69e342d46300f888f09b561368dca1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079235d06a7efc54cf53d9042841adff4bea22823b55531ef51b14acb6e58ee25c80107979b2fcb0bc22c8fc9d10a58b0000000000000000000000000000000005fb88b4a80d56c78c2e46218511a37108fb31e9fa9dc8eb3e7cd5c559a18bc7a7c35b83a9cc9358297870b43af0103f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bf4293d4148ddc8c80aec8b512ab6d285588837b381195b21d8d09f3cace7cb3b2532d5bf1cd97c2a18a0475d6be99000000000000000000000000000000000ef0ce84181c1834f52bbdfd409f838ef70710f7c31db946b8f825648505bf08a57dce5dcf541cfb67b987c22861bab11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1a1fa2095db1891e3ade6deb3cb8c1458f09dada8d02dda37790d3408d1a3f3b646be4c571babffb52e4fca4ad3ef00000000000000000000000000000000027fe5d22981bf45dd6d072c46961633f66f3eec09df47e7875893cef22a3384efc76b7410c1dd127d0a4356cf4517031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2e9a83d178dcbd9af498f243f89e00e073f49cb041a9305a168f54da1efabc486c020ebbbc2ac00ae0274c19761810000000000000000000000000000000015ef2ad8ce539d04189915f8e8418dcda616e4d65056842f72caff3dce98b0d975737b4dd7f9474405f61173dbf781101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e42f269dac1e170500cecc68c902529704f8337148174509f18565645f8aa59b87ef772d7bd702a6b0cc38c28169311000000000000000000000000000000000d682c2c1f0ce5712163cf9c087ad4a72a2fe4530afa372ee9c58b8471aecef445b30da39109d7351c5d69dc1d2504811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1f5f8de755a26646002182a1135511cd2f231a675d83248efbd216e722a5b353e543b55e3aa25f6f424c11cd749c75000000000000000000000000000000000a72db2586ae36f2bf9fc5c0028fd8a2c8542b87ac6523b200ca9191b565d43c013f48faf2212e4a1b515c0f0d140a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2138c81bfb8d55a7a743fe280eadb25587c046dd693b0253dc9fa12d4e840f4655f6a1228ec5e6d21c975d6e322e200000000000000000000000000000000103ac8246743940ac842659972e5feddb992c09a1a39d12b89e8f05d8b0907427aca7dc03cc826a70352b572d3974c861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012188eac38d09f7d8f1111ed2032667266178cd9d1d97874f01574b724dc5e212cafeab63938a7e1b976d8c437229dc100000000000000000000000000000000184a53da6e59898f7a942e1077bf4999780391c774d457d0c65b8071330f4ab42438cba935979646b2c7e58c5250ccfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063a405105eb730478280bb4c12d3daf56b5ade5133e11eaaaaf995004fa83b49bd06fd1218f8b69a9c9e55fb9038af8000000000000000000000000000000001591ef398b9dbf06715b53a26c5532728ba4dfa41cd89ac257392b30932e8059f5281e40076a83ed640210524447306e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e7f44081243d8574d7ce0529330ac1e5602de5be468162c85d224daa7f2a0c12cf179cdd0521bd80299045adb4076e000000000000000000000000000000000844f3ff8ddcee8a3b83dff1660bff7c964379980bd90dc057c737ca4f0f5915948acbb308ef5448a9a43e3307fd0a901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123333eb0987e94ec732a461c9a55a244d0c4ced073d95ea9e5644fcc6e55130f4d13a900d7c7e82c03df624a12890d50000000000000000000000000000000004c3c4854c8b97d82fb223815d0f858369cd06cfd0c85ae38ce4caaaa1689835f0cff7b41de3b09535051c2e6a15eab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c1e8de4c1ba3950a57975e03655d0aafc284611daa777e4d7d39c97556f3d3a2c1e6549d48a9d00214417272da524000000000000000000000000000000000f8f75d64939dcc3b98f9e366bc55a4602e0a862283765b60a83079fdfbdb2e13f7eb5632d64db8b08d529cd554ad5591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acd6ab8d657773ca289c10046a4f9733582ea140e165562753dc7f0bc088eb5e01282f3afbcbda64f498f85baffbb0f0000000000000000000000000000000019faee6f734069450af8b8c1dda24e967d35c662503bbe982494710c5afa830828646db550f61a4002f579ece55e3cc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d00ac49563805b0c642452d957763348a6a8d4705eca327e1a2e76f87d5c841a0ce282502d4574e5fe584098dcd44a000000000000000000000000000000000bc2bb11026c365e21d4cbad7975021c93a4bc696233795267ce7ab84edef7dc8c2f79663b9b1b88a36fde37187758af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001568b8cd4a1ac261b765576fbe33058f734ce17d9850bef78592540c10311509b486715b0d55971bda1ba0993a410ebb0000000000000000000000000000000004eb6c3e030d791dee4c786f1a607f5b3cd9ff1c448f1b1fe1b880031a833f7138e7caf8cbe4f5ea083b8bd00f6188c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223df77eef43b0956cb14076e38526531449896a5da8320c290bfb448b0c40dc18d242bf184f658018487e26a70c0cf0000000000000000000000000000000012d38c364fa8b787ab2ca2de82962e3f81b67895ecd273b6d63ea88abe7d6f56d45b09da74b959a8467e87767a95f7041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000349f0884e725291bc3518bfa6d5802cafd1c905cac0d00cd587fe6be7cc2d58fac49e28bdc8a5dc5f3d4e59c04dd790000000000000000000000000000000012413d2475d98108523212b8ae74bffff236d7d980d7d07b1711dc9edf8bc7234a61243fe0c48626444888383ce4a10a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167677937ba9898b0848c9329b0f442b00896bdcf38f1a65023edbe2278d1d47f06bb9ece56aee655eed2731a8f1f8f3000000000000000000000000000000000618c1438f46432b58cfa042bdb535b69bfae91716d05558297f99a9b22e84cf8249909a10d98450867123b743faac7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060b287e2a5b1aca8df91d805cbcf73a790b41084728c1284e439787db2993c3a9981ac2dd1a7f93c3e1de5b3c2a6ba30000000000000000000000000000000005bab38e0ee20d088db20287def31185572bfaa5db4d7b5f015017e32b8df549df5661c418618d3cd6ebd44888841cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057328067132bd75a551f6108da018bc2bebc7789d77ff754e6bf9f5609bebbbb56b7482751b6cb5abeaa9d507e5930a0000000000000000000000000000000001778e80c8ff9647bdc187b257c00e34d7a183f2174fcbc38501b3b6a3651681ba98af88c81c1716941a0d7e80bb4e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d920dee21d3e44d6d27bd14c41f49ebf7fa3dfd136e7b7feee5ee9bf43ae9797a6b3ff290b7a3e074c6ed850819f21000000000000000000000000000000000b6cdb238b8a3d9fbfc814830d7ce10ea71f49094367acfc2693ffa3637c847d745c42d176fff8f03c679f73d6ae4d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001003e84593ff63e4c4b7a0de75439bb38afcabe5c6b9a087e737ef4cb1e8f05956cfa48137d1f26d3a3b555c75ffbb780000000000000000000000000000000000d7f19210a5ffa6926f46d492be60abd160741339e549572c3ea787ded63b53d62b8904e162d19fc0ff962badd6b8a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077470cd0e716a383ead5186625c3ad47309ac77e08654810feff787884d0e4c414b094c2c77f6e08b04c7c5280301f90000000000000000000000000000000013b114a6459a4f33ea4813d5dd5b753ccf418014cc718652bf1d574a80146fa3b26995c8c67673799c01bb45712703121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006508ad991570185f389409fbbfaf619103744729cf158da3b8995b5f8bf302bc0b8c137a94f95ec7c3ee29f3a5024710000000000000000000000000000000006737a7af173d3fdc226327b5df0d5c86bbc498527c524f454956ae25fa8d134de0dbaadc9a40880fc3a7bcee0a27d931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c907cd3abacf79edc6d152965b445897929eb5384f803d38d1dc260dc2298ab764d48f29d8f5cd85a639543d17b82000000000000000000000000000000000cd123e96c9aac3fc82fdd4dfcc05151ec04b755e8e52111c664c9f4b2998d6eef2142e41f3d04f4e3441d28660e75e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc6905c971c0df26c7a82517acc21b117dd2204bc5612ec157bc819d421e394fd62f13a00c19d4880ef0572bd25e06d00000000000000000000000000000000001b2e3f750043fe10d8e1781e1cd677f405db3cb47648cf855cfa21bf9f1d80bde6e31e8a333d2da89af25c5a00e1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6d3b2bfefa8b83519bb7caaa5841b7522dad456a6da16d046a33575cb30ceae709d55fd758861fa4eb6f2d517ec81b000000000000000000000000000000000fe252ec76ccbb598e5848685d048472e8f68d5a55e67b57ae52e9917fc5b3c68cde435106dd1f5064c2caacbe0ecdcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9604c6ca1948e4d15d2f4d1e6de191a6ccf88264c6a69fc1473b3502cc64cbbd3c0de6e805e4e1d2f3ec884bcab9e0000000000000000000000000000000015f249778f004b62f7f432a2dd931752195885a6726acfa9af5211c5f5710a4a73b6d373abf7d2136b7481d827a211f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002410d56330caadfd9186a95d184216d19e9bf94a61534431677052d1bdf5b8b9b2d55a2a5a18459c87ef1b8049dbb8c0000000000000000000000000000000004315b3363b9e6ccb12152bc00d3f9dfc138ca538a9149c72ee6ea367e46a95d78822b20d39b50305032049e78533d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016434f8c752791545b985212bfa0b213548902a6c1c996f935103216507a8e432eb46a803d29642666fe0a99674757970000000000000000000000000000000019c38ecb62e6917600f7c8381dfea444a46391353b3628aa3a33145bfa0f1fc6c50ae7efca19f160a36f3dcffbc6dc631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e66925725fbb5285d52a2c09687620419e3baa74cc2519cb1c881d6a1b1ff191bc22542f3cc3fc55af14fc5714b2c300000000000000000000000000000000184196315e745ba4756b8cd3d53e3ea936ed4e8ee47ca336dabdf0074356114eedd1730a5ca8a7f3eb0444ed812d9b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef485978e910ebe2ee8500da07aa5696656b1984a2e8702c63493201053a3871511a38b9d3b0a4f009cd2c6a46358f000000000000000000000000000000000117d0ffac855b6beea17a726a7fd66d90f1d35e59475b139007f4e83ae0735e91d130b61f81923d0059e8a9286ff7dcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006185d1ad02785a38ec700c7aa1787670794850a54ae1e144231599fbb430a8999e4f00e892bfde88d8e91cd0103f3040000000000000000000000000000000014c1f6f5018e6b886756141a08a8cc9aaca478a8292ce59be95115e20298fa3a8a5ad4436a6b9a8feb801008243139421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055395a15c61502e8cf676187a8ee4c07a9002d2d3d1a6c5bd0cf8e64a7e7a9a10f69a4f13275afe5a901d637a6bc9cd000000000000000000000000000000000d310857bf3b7e0cc904641386804535fe1cad339b8576d0ec3035d92c7d2cfb995c9696a83367b48e2345b5c273797a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071f4537b0eaae5887c00bfb0995a3169a0fcc9ad571d28a7a5c4fd5cb0e231a20c07c598ef92ceee6a84561dc86816900000000000000000000000000000000055597bdd0f41005a99b4ddd9f8d5fb8d7e353df90d4c6b7f906d675515b1dd5ab17f3afaa6422bb522cedd9f2fb33401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186a7c38f05c5acf62b2372769669117bec525d8d89359f52b5a2db0806242283cf854b1c314b8dc1d8dcc58bdc91fb4000000000000000000000000000000000c930cc6a1aa4e91f5ab2e0447613a9b69b0384d8fe577b7c34dd1055d0e89d5181adb587c6bfaf64f265d8740396ccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a3b0c0475a29b42ac358bfd7b3ea674e1a9f204ed1e92f908e5a18715c7d4a71bac04b7b3e0a2317cadbad77afff1c00000000000000000000000000000000085b6d81a1d1a4db97bfe2bbefa3d4e05dc3b7deb4cf975742129a8c33aacd41c5903191ea930af0922f4990d2fe90431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000708108158ac9e8e99b248b69d2f9c7bffa52672d3be6e2a1c5ed8ab55c79c04c74f2a9509b094192a17cb718d0ad7d700000000000000000000000000000000135a82ab3802f57c05d908e1293e5361ea425be2ecadd8ae851b3bfcfe09443c8d0209590a6b32d11bbcffdbdd89ce7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aee69955170db9d4285cfcedbc3d35b61459a9b3868cbcb6b8eb469e9265a3c1adcb9f68a65ded00f13c4a49675e57000000000000000000000000000000000f080eccd4c199c88316c228446614b941d73b50bc2faf1fe9f794dc72726c54e9406553cae05234ab085bf2bd1bfb9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000db63520c96251283688f97852bae7538e9c762f4992c28029b0d1f5941a92e70906d49e27c64ca69c61abb9d37659700000000000000000000000000000000094f43d16d02ab68e85d49986d4f0a3804bed0f22b45ca9405f9eefeaaba038c6964f693f0552c2f26b87c1908307b4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016034a8d5ae1cb7252c0587b8819e0dd722bedbf1561613f3fc1407a61ac3cf50aa81f4031d9e837ac3e5f535dbbf04700000000000000000000000000000000037b8bedcef2e40b81f4082d9e83489f6caaadae825f9ecbba3d7a61fcca22ba96907ef3e87a60820832e9a18c0da3ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109fe6c5d1c991f5f1ecd97466c9b6dfc361a0983dd0b303c356d43cb4db39f0b909077547bfab0641c93f8f3904f77300000000000000000000000000000000154c4f05332de6b79d2040ac20fe9faa5b7bbca05705f73caeebaf832e26c85d30a9b5da435e4159e7b303e1cf2322771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019c50e2ce57936daea1a0e8186849418ee2364ae2bef81007240431c1697aae7e349d226ab9f95ab2d3d3adb32a67a500000000000000000000000000000000006e7c4c17e9495bd021edef9f1206878b7fb37b2b7dc7cea3ddae80b116d816221fc25ab5ee9ebc65cea02c7ff5d7fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001732df8b8a8196dc1bc35c41fe2e7b6ad40b17abc41a2717515a27415484942e2263508fe70642b6d396ef915b0bcd10000000000000000000000000000000008627c7a84e3e7366a966cdb7859097e4d5ab032b37692215cce3d6646c294b47182d0c31a8bee1acf9b2b305d19da121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192e9a49506cda4d13736550a386f87ec34b9caec5927f6e09eece0b3db7c72abbb417645f8e02de71264c480627b32300000000000000000000000000000000143785a4f6811869bec77494c27658d094c0f1a9c1e74ef5513c86599e2a077794cf01536c2e1b0b96117870c99bd0861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136219ec387717e54517cd80a25cf440ca2223204e023759ce5a3c2c7245dd43103f764004a8b589fa2ce0cdc55526ec00000000000000000000000000000000193e80c9af397fd2ae8b48318fa1a15a251396fac90a993a4c78afeef1c7c91c19f3ab8874a92ef4caa0df87204a43eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c46d10e2990e076de07ddcd7776eddb53147265f8ed574ba63cf6f2950416df58973aa298d501188bd880bc50a7f2f0000000000000000000000000000000012f0fb44ba0ffd24109ce2013d4ca1431df5a8b58eaa264ba30fe06e9cb2141c663335a3074fd92fea3d0445e235699e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d7ba01ee498456bbac6e75709cdb8a1d0921041dac84e446f7acb821e2cecbe2f3d5cff9dca64484e097bfc1020f69000000000000000000000000000000001426579234531acba2f0a14fbfd730ba2f470d6d2009427600df5e271be5bb9a95483b2418e09ecb6fac9ec994db8b941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587d7de5776f6c3154035af574c25a1238078940de8380f5abcb4dd0716b3edcac9ff5db3cde96adfe629b24c3c4b340000000000000000000000000000000004cf46db82cc7080741e33eb4e14e905ff2b750535a8d43657fbf0f936ec038f0b239a5c620718bcfed7dcd18ee47a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061325b172ba4ad7eb20ce1a2eb2ca242da9522f9f8ca0617061166e27d19884f10304fe098534e941846d8d0e510f6d000000000000000000000000000000001160fdb0f63dd20763d50f46cab5c4ff1121870b6b105677cbc1f6b0d31fafab20289a9f789ec950bf92951240516daa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001620f4678c14242e3cb398147789c73739fcdcf90716e9925b21507ffb3fc8708e043d216c80d851d126e76eb3b4f6db00000000000000000000000000000000149880a1d8b2caa34ec2150bd71f6e145087be0bb436f7d57e65f674e75f91f5bc0ba1ed3a1d0eef4ded9345f6dc58391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f770e891788042e8da8e0d6a28adeb78fe42cc8d80b541a05feff27a5b162d053c40e9fc1c558064a81f449ad7218c700000000000000000000000000000000139efce42001c1105b2bb301c75a26e1d093dc557dc556102dbc0c12e7b584363f3a708fc93ee5eeea47efce748072631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d42870b296eede640e36befd6a56762c5528ecbacab1d26f828ff3d9a4199e1aadf4989ee9fd928d378448006c3ec100000000000000000000000000000000139f0adff5e9377baf84913788839acef8517119edacba63c62d47fd1a4cee06c3b31c76f35c3d4999771005147971271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e62e7f7d3bc805958decb4be93f7b8e1c323eb4bda22d988e6b623788440940b806c605b033d380c085a7a54130daa00000000000000000000000000000000151688efdff162f00825090f0e6962aff6956e0fce11b3c5f50619d4a10ff6375e8e59f8292047ad5385634b975d7e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d6a32934cc9fe2b75ece02a52f13f4d2bddec07ebf0bd87e6f9bc3768572fed736733d339890b4cfca046d7e3b9700000000000000000000000000000000017d2617cbcf3029b3a024e5f87192253a85b05cf658334d76b9b7afb555169523f0ab2015b75c6d50b0ba627f98b6d541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000614a92748905741006e49e144e9d07a55fbd50f0e6105d513a1acfcaad203f5fbfd2ae1ad0c7967d8f0a0f092263e040000000000000000000000000000000014684a9ad9ba0dcc46d95b6a853f0552cc195e78a294b5047f90d4532fc3ef09846fe4618d7cab5168dff1bc1f83e3831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2b1d68581186abc5e3a0a1a4a3500c3e2387b7d206cfeca37cb742f52678a9fb7028d613451464d544860ec45b4e0000000000000000000000000000000001053a980b671f45b5066e7dd65627e247daff1e4e9a111b549e050a4bf55c690540d6f5c686a0d10217b57f02e752e381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d6f0d6c0a2b1330dc14788b0da2f9fec098b85e26256ec42269d28c297ce563b9c6089c18d39cf60631d62cc213d6d0000000000000000000000000000000009a939af76fece30c8d47f45831ed5358800fdf1bd5c765e79921bea3fcadcdd035fae86011db453cc5927e1a0a292611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d48d0dfd38218caac55b596c5a5502647e0dc64a22fbf1b56cf420970c5b457501a3beb0e4f5398bea461626eb2140000000000000000000000000000000002719797d6689956c940420e6c66c2e77470f2f396f2fbffe32a6f7a3178c7f9edf29d7918d3512d6ece682c0c5472fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c22ac560d253e6f212a74f88484a03536dd363040956e72ee9341228fabc4263971b08b137faf1cebf665f72d9190a0000000000000000000000000000000003d93daba595e4885ed55d0e809e062afe4cffc654e1c0296d622a752b225bd2fd951624a90a0b055e840dbaeea1328c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071228a1bb21f492b8e80397cb9a03bfa897cf24314f5e39195a3f90fb2d4c09fb9f55e6262fd8939eabbc3333f1e8380000000000000000000000000000000017e3dec06c00211c754fb628de5d7df7ceae6243ca8b535ac619acd93dc40f1c1be2ba8c92ce991899a2ccf1695a9a911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872601b4212fa01d443b335e6244982675e842826e875a72f7d0405549da22e46f728cb35ba073f9eecee5b9caabcc2000000000000000000000000000000000c2afe425e3ddb4f2d41921f792c9edb86296990bb1d5b0d84e70bd26aae306f46443f7a7ee6d8fbdb807b6ceae288371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000028902d7eff252eeb7ebbf4de3a481a5cdff5d36541581439d6701750c3eebca45ed3e0bb4d255050e1f9c1d5f1b26f000000000000000000000000000000000feab30d6f386103e1e01dabe91cfc8ab8aa82f395a7f86d72b91eda38436855f5add9cdd564fb60eea78a1fa1c033be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188fae8df2b9fbd86ed21e2e2f90be5886ec5db6c238d52870f406066216b0b4b5658eafe7c9e265a9a936c0894a351500000000000000000000000000000000119dad0641daab1c23ba99228bc38c16f8c09a656340c720f502918b8e59ea1da7027f0546b3e6fb48fcf4815270e37c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147d6d7524ae2184ac718145b0149b9d72347596eb940ce7cca9476c674641062f1d55128c676ae52a70d3b07172fdd1000000000000000000000000000000000f3aad8a3659d0167de805aa7ead7680648465e0093fa2f96a772001a2d7551c4c4c2c4ee0c6b1e6c5a52a710ba03b631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f374e7e268f5beb5ecb001073c7bcd5212c692a910894e26901d268b4531fa49f802c15eaa987bcd5aec88b27defe5f000000000000000000000000000000001171102b3eef34a3938b40443051417dd8e2cca86b0101d24a5f1e6b51876831aa7b2752dd4e5eedb2d0c98e2734a7321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3d92577fb2d1f18f8d7c0f8941665b5128b05ae773cdebab3bc889452af61c6cc89204ff65f8ec2e5aaeaba336d9690000000000000000000000000000000016b4e5f95ae838789c411d2bcfba7d17732cf2bdd96e7ff567b8ef94b5d7b80f59b0cb35e874c869a48d8428a99ce37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001499285a8d67cae5e1b71f6f4a642893475c4123f1357c5228297f7f1e0533449f81e2aa596f01271dfb8de7f02aeb0e0000000000000000000000000000000015b504d899a1b02d790c2f646f15e97e20b6252ba6a56fb49735dde41a7b33c6933dd4ccdf4d02ec5dd68389bc79f8341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6a79aaf9a049991b7b776ece59f7917eb9c50e20bb533737baae8d5881964915b5ebf5582bae471ed33fa3db51254400000000000000000000000000000000085a8e1c6290cf6069ae662474fa006aa3f87a3838eb2162edc8fa7e2f8595716cb730a3eacc80f4ce323ee2968713381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd2f004ed843b76cd7a291aebb04e3b266d91d3d1ab8e287b9961a54f97b00b87e419f97a22c0e56c32259ca243272900000000000000000000000000000000161e8e82f06d704b6821522b64a5fc759325471ae98208b313b42eb9a6485979fd0da35ad221d6acfde9a15f9824d3701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100951df5fda90b78c6bf2a8a27d4e2fbe1ca0294644afd99952f10234f159b74f83c7f51aae7d7386ea4eae076a5ad5000000000000000000000000000000000efa6bab032a516ea6a08b2931dca5db86b927cd87e25ca71173adb3e0c322ec5ace76129812ec4d2c0c892696e288091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541fa79af313a4575535bd00b61ee5b1c6d7cae431856017f8eecb925f1bb6e8f56c25a29f3b483d43f30c37cf1f73200000000000000000000000000000000004ad6fcd8965a58c77b3ebc5f654fc8c7719eb562d543cf75b9f5abc1d1b3f9f37a931b5994eceea3d869584d57f69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018193081f522f57261ee8e93961c791b2f93cbc0d511536b76312413f7f070cf07f6280a030862d16945b80c52176ee4000000000000000000000000000000000cf169151eceac29983fdc0b1c42bef19dd657b9a3c6b4450fe71b29b9616ec6cbf9841b3dbd1b540f8aff3759e0d1e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006eb192b75d41ae7a0447975d343b3797e8876c6386fd6e13ec6d7131bb7ec400b5321723b369c41062c1cc2a04e3d55000000000000000000000000000000001037ba5338cb2185724e4d26d3230616f4cab4aa7da473084b1b37f3c171fc3cdb18e4e2fdff012b86b0c2369adf0e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1682c9bf0907c46cc0a2120f2e494dd9fcdc8e0814284927fe404d5334eb2f584331663e3bad863328c353a66a35d00000000000000000000000000000000189209dc3262e36f42060b6687b9dc3b092362a80ea3783996a12044c564744bc5fff921df27e95ab61750c8a238567e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbb667a785537d6e6d906802f24e85bf4afd634c31ea5e3de45d5d31dfdaad327463a434c3c8c56b2fc3e916cd00f0f00000000000000000000000000000000181f4ffa345991cd52bba3850eeb88af2940a8ba834cf49186bc278eaa4ef63fd98df70e7e9c347d79cc3a62dbd6c6621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f333ab73bc9a758dac7d1b2e69471616a7c76b37dbf3bec9e4845069dc5c2f7d54fb126e3b9d61e0e2f29918cbc5c000000000000000000000000000000001298abe5d5f47c4dff791a318c47701ef373c76aa2b1ec4e6eecca589fcfeda05b167fb4f1618e51daf104765faa10f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db516539454b7b9040d44bd0420464a0174c9dd6a992767a8106823329f4b63c580b13cdc3cc77bd680fcb83228a96600000000000000000000000000000000112fd05917627d464a4cb60dd3991d7b472adb6ee14528a36e3f0af680be72b526452ff6bda647d310fa5c620b0744cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000532e78ec3dafb9f957e42f9c49dba5c821a076af4e337d947f17a1756b12cf144850b2d9a27f4c4126bc2b7d64a844d00000000000000000000000000000000145ce8a6318ac9d2f074f4e1b5e8c54d869b9b35398561a09df89805520d94b7a04b38ca98b6fb88dddafc153837d3351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706a516cd06e73076e228b4c2fb036449611fa4307f6bebd0975c1b722968f703ae431187d1a5f755eff43f8b41cf740000000000000000000000000000000017938e6fd63059c5d6409184a54776aa789c524a0b1afbcc26b6065d3ea4662412d125348c3676a6ac43e7e4d03718c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7e3c36698faa1c31b68ad1ec22f51f08b658901cf49976ba7a6158e958a11b30033c82a30181e36812acd6a5d3e9340000000000000000000000000000000009953f382ec63c6e7e27c5255a859f91135411bb4c7bbe172adc619415f32bec0ce7b6c5f499d80220ed5060079a92ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c98fe321e413395e57fc6e3fdc5e8a9c1cb632e347b272b4866f7eb42da714370a97e7897c8622a0226b279f6a426d00000000000000000000000000000000004c975bd7d5723fa35d63d003c90cf3eaf1aad036a307b6d2959c99deb850516d2f920a176c3962355a72a88e9d4fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eff3e33676d0ebeed03add1476ce79ade9ef81fbfa5af0b1a5f3d2ce53a40440a2cfbb8f6810856e46deb01a119c4b20000000000000000000000000000000011e5b0618ec54c2692c9141c856db4949ba347041ff318dbd15707afc682144afa088594975d2049e994ec93ca8ce5811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dcbe4c867bbec261e69e4d1135e4a6ab521d6aec9f993ecd5e3d17315302a16f99eb036851957184c56bb49ac97d3000000000000000000000000000000000ead6bbddb0cb90c3312cd1b92ea1bffabac5030e7be5c6f4b7102d05847f841c0fcfaf6b53907e65c832946586eb75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164c4b4acc15075d253e298bf0fa64f664a0c6639db88f0eafab3ca585510e6b54949e4be4ead8d4e552e9156a4fa878000000000000000000000000000000000f9c290172c6c2ea7cabcc7778698c908646444e975d28f03638999df8193e378b9e7b0c346ac2bab44e47c63d5fb8011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b6fc27accf54ceb8326e0e99aa7ee5ff9209f8f6ef34885f49063aff5fc612d82007c51d89b1100c752f8239c09af10000000000000000000000000000000017261bec4802fd4b4ac34e6a06cdf591a063dc4dc247f84ac51fecd79cd7a2fd669b740373fa0c216e6661a023da7aa01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a8c4f6eda083387d892b14c32150f4a4714bdbb12f847a410e70dfbe74908cfc8d615b5a0717855c48a32af7ad140f000000000000000000000000000000000cd2580f0196192617029f8681ae951aa2c095d913d301da1c82b048b05d139dfcbc7d466d726ffa448eb23631f4a9f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd156f3e0828f92f52581a07a065d8d85889ded1b0b738cbad08f28882e518b93e3ac0f924276c6818c88826d3ba658000000000000000000000000000000000b1e4d0dafe9596cae9536cfcce7e523db522234cecccdcea9bd579e111bbb907d7d831f0de7e0005b48e7fe001a08c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e1792bbd7dbb479ee2aec11e9ed0b3121942bb82526a02200a31c13737b6dc1ae05a295d7db398f4ed6c3115aead3b00000000000000000000000000000000005663f797aa9268b36557b39de35c259ee0c7af49d7c2b60f1e4f58aca95e2f3e73d9eab0e9983cae7e9b6359e2fd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e5d6c0936574a108ca584098e01f72dd5160a68fdab44ca24f23427b74039956e1da01a9601decb9fac8b70d2a42e9000000000000000000000000000000000b43c96316a2902197d35c9da42a5844dcdf32e117ea4cdbb43b80df488acd111efc7b1cc7bbf68427685d92d40351ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c35ce21d2e878c5d1ae4213746329d05550770fac80ed5a8dbb46f54b77908230ab9e9067c88586fdbdfcb5fff55b000000000000000000000000000000000c6dd2a68e6a80ee049f2c3d3e60ce9f72db75e05f4c4b2c514874850f55ddbf4d62442cffb35042c1f8c554574d32291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004169e872b20813112ffad59cb043819c1c780d3e160de7cf12ca339a4be912c4c39b6a514ce876c58a69d4bd8b7c8b600000000000000000000000000000000096b300c0007bbacab9195df89d273582f8295374fe81fc73342733bdcd42a1047f2adcaa7a7c8c2c634b3cfb9e4cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b6282c3b03c52e646cd8c2269acf48e06658ad8b10ffb925f21ce47650795303d0827578bda26b89fb88d0fb7cba6000000000000000000000000000000000b5ba78d0c00070bb5bd2f278c51b496a14bc571da8e232f0a386b4d7abb52761c3d50798d9280c77e7e8ab8fb9bb9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112673a3caa7f0e6845a24f85c41977759d5a4d5f06d50f1f501b89d349fa92b353b94943d8d4ce4f7418f789269628d0000000000000000000000000000000015ab56834fac5bb3d374e0b57783c5cae1020ff08440a73c64ef15fe0fb6ab08137b3b224aa9bb3b3ec450faea41c1771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156c3e7b78c5aace14d7ee4071f5f91d1f6bc0ab2627158b4df4744a5cf1f9afdfbbbb4b446b572da73530d6a4f9517300000000000000000000000000000000042adfb740b021d90d6e80ee6be60c4301aa65ac8d66e91226e23e849d757c1967d3451d4f08a394f0e0dd82680adb961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fc3e013b44b75671f10fdece84ef84dd45721bc2d558a733158b70d44a49a9133521096d8ee99710f4cc403662f8220000000000000000000000000000000009159c4fe16ade0b58c8c8cfe91ee564d98c5a126ac64f1f92f7e1225c43233f20367b9d2d885c02ac11d1ed8b60e5d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004c4c42d227ccd9c0c745d9103f3592796f0a1df5da7d07b5daa1b4097a3f8e1db6284f38558afa06a8129850e8285400000000000000000000000000000000041518ed4f5607fd9a335cebac12922634c79ffa21fbfadbe4fd86066ed29fb5c4fba4c26c4aa5602e7943b4e2dd37ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f7939bd3a503e123bab0aecb3fe86acf9309431e48f63726ae11cdb121dfb7cd4df23dbdc388e48b13694404c5a7700000000000000000000000000000000188ecb65dae4940be167fb649d14787d0ba0ba0b86199815e850f7a6ebae9a1b25c14e8ce47754944d1f752c43d987bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f9a123ffe84d1caae6a752aa6f6faa458ae5285a2cdf3950996ed3044db942732402de77f4300319eab84a924a4fd20000000000000000000000000000000009b693431e49923472e1e2e40f82674b293591bc3c76f20cc0413baf454ca9007ceceac172336c0a2794bc3c6cd8db851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097ec2280bb1506234a181e08e1a9f0344bdd20e0d008b622b4e08a208f673661d090dcc314d1948968771271f4a96c1000000000000000000000000000000001385f6160b4f3106b370758c3d5472fd561813b18c3bc9abfc78ec69f67d73f2954d2499ca1329ffc46b5e98986a50911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000804e5c84bf37f9269e630da289e5ff50e77764ad19b43d5ec57c4e3b1d12c17e1fcbb64d923c172fbb4f1097a955eab0000000000000000000000000000000004cc3569eca32f83c7cbc71312774662a9a0ee3a99b12f0633869198c14b950a200571a2973c4409e3423cd67c2b91b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001afcb56c1690fc1cf71191e275717d688476d90b22143677237cab9d6b6ffeef3823a7e525c981662b768d59a9c468700000000000000000000000000000000083af25a46953881dea78dc73005c233979bcd1c25d3f07dbbb128b78043ce6274a79c927f241ae682f81ce63cdca5711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007defe49418f28f904abed1c8866efbd7595065b8f28469bed7c493d6d2f6e6e8f593be20cbe4b29a8bedf2cf08646b10000000000000000000000000000000014649fba9d2f95c74c9b22b97351578afde9aee8bd3716c9357b81a0e3a36aca6deb9f35edd66eb904d4d044c1c2cf691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4dae9a9fe8220f95551e919ea6d714d7cb6dd73e33cfac9f15c7e73f94016e5b1aed07b50d29eb475dd7221d431a7c000000000000000000000000000000000cccaf42bbc200f7c6c3bc4efdf138325919756b36103e120e9a8b2ac5c3ec42d981bea4649cb09766ec8f719c056a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1e1cdb155093aacf3a1afd711cad4c694d63674b0cd7842df6884095f7933f8492592cc042649ea70cd91445368ecf0000000000000000000000000000000001eef0fb70f777deecec044a998fb79a620b30fed52891f96605685650c7745f5d6c522d99afba98cc6cbbd50f5297eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fd0196ac7b4de4919e66687bc86963e1770e9db4e578eeb2b283a6030817c45cc90dadaf70e19daa459da36bb9e24d000000000000000000000000000000000afe1fb7a2dce7ca9fa2d6f349241e8fb2ac2a712a8aff1e15940cc01cbff3e3d7bac5cb1b93fe0255ef702758a085711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95c17593e2160473962f6775504a1992bfca655ce6e207c9c40295889f6bd3988bbb15451af79b27306f57a828cf07000000000000000000000000000000001064e5e187c356ee674158e46fcd03da8ab9891d471a443034f32c003a53ac81de9aa0adc71806ac308b3ba6fd2383501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183db9a3fd140a49ab53704d2661117bc60305410e7c088f753e35a659de8e0aedad09b3f3b1732956adec4859c4dd1d0000000000000000000000000000000013ca5511351cbb712df2c5d8895a60e02b2c28af39b1647a3e56c1b6378603b1811d07cac68e1cdde03afe85e0ea99541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1b7992ea089729bf7a5224e64ad737dabfb789eee95ff82bd1356b6c765548d5879585d3b0330ed5071f218c705acb00000000000000000000000000000000114b963127ed55cd158c99daa1f921d2f7ea0a2f3a7d98da3a66d1738fa34dee72ce6bdc39c4213ed63acd9c803394e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029010c65975636648464c0828b47b4c3c4aa75b69d09e133eb1df2c4fa999c8302dd277bb1628f713ceaa0c8c9b3c6d00000000000000000000000000000000086b1ca94a9c80127bb6f243ec354a84f54fc3330c5b667ea9f12ebcdf2bc4fafbff8c78bf362ec2600f4b2e81d959851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3622314fcf0cc6723e1682538c5a65ad4d535e2fefb884aaa09ddad3bcae874ba4e5d290de75fec79a4be052d98cde0000000000000000000000000000000000a6e0aa2c47473a5a607f1d555af6ddc0fe2ac1ce824fdea32ac3a6008e9e103a5d140e651923dbf7c80ca9a8a07aa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d05724ab947b691e28ed8fa57601e666ca9283c1d05809a7622db9240dafc110b8fd35bd358a31983cf7398cbc7ee0000000000000000000000000000000008e0be0255149f195897bcd77f61fce2161458da965a81eb7861334fb6769977db0abbca42de61337dc88aa537db23771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9035623a9b1823046a9e9bcf1981366926bab6d33b10bf3651023571846b7d09467c224c4f90b0cde13d092288022000000000000000000000000000000000f06f13456eebc2208172ac1f33c3d3e16a2499978ddf9cd9ad7633787a79a66c5a364df6b418b6526c95b620bff73301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001907e9bfcf7ad7867817f59b94202cba059d83c604ff0b0cd4f8cf32ab55143819850f95803be57ff55b699aee00c977000000000000000000000000000000001152f0fa26cd14b1c79fa79da9532e62ec2a3330d06e1661e4cff82c1b2e144673be00c0b3d867bc8979f2de839f7e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cc878433c0dfa238222347ec16a05c7c068b6f5cf75f2945ab910d81c2f7afe6724e5ac8ac164f715741f70135e7720000000000000000000000000000000010ea0e52f574b667dcfb80863de1a1aa06925a5ca2f8257ee5ac064f49dcbacc79f9d964625ed6a201fc920f6e648d411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000648d4e19f5a8eb871a1b5314527316d97cb3b8184c6f22acdf6b9e57da17bfbcc5efb3c53a0dada168624ad9b1266b5000000000000000000000000000000000ecca5627aac4da54fac0c839ec430ef6b75635ba4a5832707eb156e45f5149524eea43561dbe8fd5229d710cbd5fdc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000995e3042d9ae1a0b72c1f7c444b5db9fdad0db7fae649025f13a0e0d73d576e957fbbfed5cd8e03be363e9123cf7cee0000000000000000000000000000000019d3342291f41c7983ce2f253e84bff27ec965e393bd770963d5eb0333aa0878cf8b9c046177179ca963876ceedceec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000874854849586769455fc679507906c1b0247ed4283936e319a287705463fe0a33c84d6c09a7ddba523b70c24c293fc20000000000000000000000000000000013389810197f7582850a08f30264f5da25d087154f2c2c0f5bd4643493801b94ee154bdb389c71f84d670e4a18034bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7096dc6b04c380113f32a61cd77b6c0dc99be18e25e57e0aa6fc2e340948c4f2f46842143b90348226efdc7dd55ae70000000000000000000000000000000014d73304f950c062bfafb025174b841b0c16322fc7b1bf65b6a69b6a87ffb1c3d57312f8b17df51a9a006b851b0839741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011849a6f1fdf85ba3e01087f851f4bb445bbdb74f524b80bb2e4c76fcd211b88d8aebbd19f8551630daf3d4b1c265ea8000000000000000000000000000000000086d087527eed86c2725fa2887def15087a17eb87b619ac3fb334279b11acff2507324e775921101dd82d63d52976d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130374f11ea770df36dd18cb3831040edfd87b1aadd03366119adac1367d7ee5d758938866369db7918ee4a848da5cfc000000000000000000000000000000001577d8d05d586089f107aa9efa19e0adf19ec25f1ccac0747ce7a44727be111f7e1f56a547be8a2aad98892deed34a081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102389ec9650fe78e523e8d9b1fe4f3c3f065152c26ae40bcc63c960e2928138b48d977634ffd97527ba131a58b7f9ef00000000000000000000000000000000145317623c7bec3e7d80bf5c4a2f34d524e968baf6afce4106c07ade26f16501416fd83279a283d45666a59c4de7225a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddfb47f525cdfe2dbf677b340cd1041c88c304adcf7a9c02e0a348ba18f5bd30adbb023671f5ec409da090fa5fba46d000000000000000000000000000000000a1242108cb0c57aefbec61fc8a620f1806503fe7d4b1a6a1c7168569a62f393567ec999a2be2c49f4d1cfdc732ad67c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018067831186a08baecea61bcccc34d3a61941c8eed8ec353942c4c8587d26d1726776f26367b56a6554adcda1d541e9400000000000000000000000000000000185b44c48e4f7a186cd98e498b1dbe879a04bcd3662d8617e1f7aaaf2296f35314bd7534e25de6f564b20e85f1f4d9b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002223eb133c8be9c294ce8585d5337f0211d3871cc0eafc1448343813da89dd8fd942509a650e7008d309bcba384fb0400000000000000000000000000000000004cdc07299325b20cf278441e48bf005f39178ee1fdf69e7d0ca792996b660211114ef633608d42718686eca33afeea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9264235969b3c5684d817a5c043a9f76546ed2d5ef358c2a0dec0edba67224a723b71d172f64fdca6c085a4dae0107000000000000000000000000000000001548654b9910a573304e1ccf34ccdf73f240c96a7e9ef46be1277926bea83d8fe8f81e8af3fcaca1adb47a6d1bc4062e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ca1e46ebc798e92445a0aadb05c4335e8dcc711a90977a180e919ec3a7dc73cb18b00756edcd5d095de23275f3d3b500000000000000000000000000000000046be4ffddd250a949ef5d9a8e3fb8b547a70efcf683578f242d11b848ae15bbff71038d066adc4053fde607bdb3b0881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011444ec9d095cac7f8f0b4cf320635d10577753f34fe56e76d5b28e84060996fbbb9cc55035b4b5c1bced7cb11313c44000000000000000000000000000000000991b1a37e95436018cbd0be6b068d4e6f802d782cad8751b463999e22e408f91d48777d4c31e2a63d09f943fb9473141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135b47ce8d62d23dbcf43513499e997b50bce59906d94633374015ddeb74763f1c7f445ca4bbf48fdae56fb95fabdb6a00000000000000000000000000000000024a7c43135b5fbf2b987180a90a2ae9accbfa22d1cffcb582768d8b31bbc31cf7fe9a82fad5e4853effd2191eef94621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aebc6a46b961b7f06bce58c83cf5c2c8a82247b024d0458938abc6e22f0c58cefd109d1ed19f63b3fb9d038d0853061000000000000000000000000000000000ca8a05aa3466befaa77473f321621ccedbfb85e2fc1de8d91e1c68ff40155f9db2a53f566df2edd24085e65e47661551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3677f0d9917b8e7f0f940f0b2ee928ce15679f9db66277d64b8cbe64a4b65fcd61b8eef79b95212b165fc573d1eb370000000000000000000000000000000007485c772f91e69d5b8bbd4e081ee358189cddf53e37530063772abbce1994d61519e9bb5529b7b2d2b6c7e95d8f09881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a2e2bafb08e4e3de3e0decf459531a63b66385450c242c1d18f469fd6bc54c98c2603eecb86434aaadef5974119de00000000000000000000000000000000024df245829b7cea913cc77edd7ed76316394276763d97075b70125c3f8ba19c5adb23f974d7ba548aa880210cbd68a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000581e32661155b9eefd8591c2e1fff3ac409d7ab9a7866d48c7fddaddd550ff23531a47161e5f0e03b123c395668f171000000000000000000000000000000001437d9f01a837dd478fe17c67a8cbddc62c94d65b99de9d462474115eb258eba7cf80dd99de4f763cebb97399d6e1fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d4acd7bfa255fd826788c7deadba60c082d9120e7ab2d6e79a88a94b8f0c0d82b1d1fe51cb85fde889aa19adb3d28b0000000000000000000000000000000012b2d20a8e1ba660a537f9bf0dbc7ab53a72996d8ace255c8fba1a613b09abbe916ec444d2701b80ca39d09fff46adf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f57b023f8be03965ec900852b73bab809d9674480030871744b1089ceb555cd40b0ab3a74b7c566b9eeab018455a40000000000000000000000000000000000efd21f0cfd87f6cb99da29ab03e518142c8ce8f7a46264d0437fae8a2358492ff0875c8c598556de5a877ad167e33401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f9676d650c0eedb68104b990fa0d6b89971a61c380714f20d36153237ae5e2757daf5badb50b214960f295161973a900000000000000000000000000000000120c6fd84cb97265da18a474267a9a7af1f4327f92b18b5d22b3cd6692ae5e1e92b0b82a2b7e817bbc3e162b64e991a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008f7015de3a56dcc09bb5e87e0b3a47dcbab73e0b3ec4e280375f5c1b820f175b360175edbf16d23f61cfcd33e8db30000000000000000000000000000000001914eabf620052971a87d9eda25e98c2b92a94eaa9bdaccce4c48c2b8fcf9cc35e5e6354bb6365c61436a5ca63bb59d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd4331fff0d7b74b2cd455aac382298211abd2b774a53529ec3b93041390edd6150468da836699ca993de3a6be3bd2000000000000000000000000000000000994ef7368b1b2bae34d2748f0e12514399b69b43492794fbb7c45fb2ef7c36cdda988ee05b867bb8d2f6211beaf96421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028bd49d5b03f6c546fd66fa20aef9bf8304aa9678fe6a0c910ad74b494eb99ef709da527763cf4fd82dc6e275814b9000000000000000000000000000000000617af35c4860cca38e17b1aa9a603a22a4f08655ce618152221e6d52f72faa735d99efa88030101e87e5b1d460935c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fdc8dae7d59b823eb70c24dc9037874c2039231d2c88e768200b9a15d0f194d0fccf362064ade9fb88c53e3dd334c500000000000000000000000000000000125cd42aa2d0c6bc79abb8ef38578361af12c586d342d016bbe8116c5c99531fe1baa16c95020b0ea6c39e5f079b3f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb5b1a777889342b697f5bef0919bc0a3617c7eee93a650be5370e861d2031bcd7880c788b1cf40345aabd96a4eea50000000000000000000000000000000000b7c5be7d85c5774f7f4581297a674a8213329cd55a6bd64d27519c7611ab099afdf970b7648c19cb68fc457a62429271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034a99ae8489bf29c8d37e54ddcf3844a1f284cdaef9e8775bcc595ceba444116c352ce972ea7fa1aca2434f4f238c620000000000000000000000000000000019c2b8717177d7de8011efea25523e88187bb2fb5a1d85b57db7d0a29a68abf2b2723ca3ea0b3827e7ca190953b0681b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000608f2a6aadfcba03f91f65f1c6f911333e3bc3ca50e2060dfe5af5305c00f485e3ddfe32e88e67804d5d4cf9b999757000000000000000000000000000000000dc0475a0e78bfc77eda3c3ad1c92a352b65f0d99db47da6d4d7ff967fb7715b53ef408722bff08f3a2cd2b2523c2e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008475b8cea77a15bb5fc457bf264846dc05c47b927b0949401ee94bea619554c714fabb604fb406b972116e3a00c37c00000000000000000000000000000000014776a8e78e7d3aa155e890717048e27c07fdb5068e06247fe370911213c980ab540fc93c0aa41bb4b44d14e075cacd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014d89ad78c92dd2a29446b78cd6a6f3031b1625d20d50710da8afbc800172eaf68568c1303ed4bc341bf4866d6a1d6a0000000000000000000000000000000004abf2cfc1d8b701e3795e6f48db7e931958f11e11969eab2cf3259183c26b07e37a8e4f78360ecc453662aa2c25c89c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bce712b99a779b3be31a8c28fae56f29eeb83c181b30982300e42f6ea382b35363b0a7a38bb0b2cd1e9e18da292e0e0000000000000000000000000000000015926512d9a0069dea49310c36ae19b4fd2021031314f7e4ef1e59bb213fa2506edd8faeed624ec08b904de2faacc1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbcb9a6a81bc04fd4b5e2cbef6fd758d3514f2ec475d939b09fc6567c94f5966c561e2ef6c2b530e96918802794539000000000000000000000000000000000b0c63e4f8f83cbfb13a7c4a2554e767edeb6bd65d648d0c729a8637abb9af34b974e558e2884249ef0f415bf83df56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116c9bd0a4bfa67a78e6044e44f255c8a75d61cbb5fa1f4314addbca7cfbdf24579662b0cafcd9fe156833bdba8325be000000000000000000000000000000000e2025dd6a05625dee5fdd93b3bce77f00fe36c2cfafbf60edfe807b90465535a315f56c8d75935b843b7c33d21da1931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016165beb6c6273343e979eaea809a65d4be9e7bfed856dd7a07fe3e9e62706c5bf7b30e2ea575e241100a439efc4044e000000000000000000000000000000000aca4996279b719adc1dd95e5d1587aee80483504e53a75bb0be1f48193fc01a5b0e896055085783dc57c93d783e6e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001640b2796843db11c3fc4f366df9a6987c8f152c5d0ec1f94d4a2e7081129e02a14c58f126b6be174c44f4c072c938d90000000000000000000000000000000013f8264935ebf4ed75ed9279c5594c986a9f344e4473acda058830d81848eba854a96fe1ed6202652099e635ecd3a59a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f2342fffc9b84a32aecb30f4ae439b56e914d5368afecd887a9fa5e4fa68d4ddb20660b596fd93b223ec65aef086f90000000000000000000000000000000017045599ec201cef97d5404e512afc2a4116724e71547db8b9013d4a5d958f4dd4e4475254bb2bae879f2d31179849601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f78ba4dc45d5dd58371a60877f15b9e47acc58c5229342254d5a147bd93312da21b66f2e596e49b468b1f4715d7f1800000000000000000000000000000000152b7d1bb81e9adf35c7d380909da7596326d36cd8d45fd411922887d1d8c8e58d2388500cec9425a64212aa5daea1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca4147f154e1b915b23168f573956f599a2253c5176e9a2fee0f0710efa5e89d2f90b12a304689f1a086867eb70a9e80000000000000000000000000000000005174d0c90dfeb3c6b2db73d09b83289b52a154b522be6f068d07bfedfa4f1091aa1f713ac5b6e100fbc2f17e17c2d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bb1c917e8785ae4f4bdfe18108c9ab2a6d8772b6ba764a5a662b8524a1e957b2724d3cedd03e65017d37551afefd3900000000000000000000000000000000014ad857d22f19e55a64c9ceb2ce54f6c96d62c503bc3c224e69d4683d1a39125978a8bf65931bf903d8da94ff51ed341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151e8870c9d9681a70b64cc4bc25dc9b803eb013eeb8ed0eefab48c841a3eb6b5f9563f7a76664845018cb435bbc8ebd0000000000000000000000000000000015241fcc18bd49b069c49ae541a57a5abdf1e920efe40385acf1c7c64ff5e0b5f81b7a369d4b02ed9490ac7cc0def7531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003323d2a87678203cc54877c7df836e53ebac12d9d6c280f6b54ef6b0d17f2e0a65ab4345c3965d47f7df0e3f5ed740d0000000000000000000000000000000003fd3af23a6caccd2f80db3905e9f001bc5633fa5c4170b8c54770e3fd8b95f40bcc50e7e61c68df19e57389de670ede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1c7e8c5e6e629b9d8de1818ed6b63bb7838a7b8eb33ca8cd19aea33d2a6f4166c70b86ad58ffb15139edd401f7ab2500000000000000000000000000000000038292d6fc281883afd307b75dd3cf5188e812a6e01a5d21caa7af5f5fc60c409ee7fb56205696961d0f013c292da2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f429f22d2eaaed99ae57ad1ace58f8700ad4d9e26541fd801d74eabe14c11626cabff59c36e39f6a12903a1b78c210000000000000000000000000000000000ccb99df5b7b80f62f129111127ee0dc7259a8edabacefefafe42c882a8e5b9623c22a4a6b9fde272d983e534e1a991d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cdb148cd630b78602c5da04aaa971b1b91c6c7210ffec6de2fb132a2b20d907def6a1742d584ec6b6c72ffee0116890000000000000000000000000000000010f791a223fe8fa561e53fdca268c65975b95c18176767a4120040514b0a5eaca487d639e4040e3ee62c61831c59aa121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120916fc4c1bf20923f8bf02373c3f62eab0257ddac78793365953900d9cc9379233453c9d516d281111355c5118cb5100000000000000000000000000000000034e3288469df59cfb33ca253f90337d1501a3489401ab18de3ed31019ca77729f83a589dd20e7207276917b6a740ba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000177efe5ea7115ae661dec468d7af5f6350fc58a6df8f5fd118c066bdbda2e0d6839448c7e3e9659f5d96b4c6bb7fe730000000000000000000000000000000009dfe0a8eb0bd74fa27eee1e0588f3d9ba61cdd1ed4dacf3df2c0bdbc668c98579f4079b10b6ebbeb9c5954e18d806151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e911a1429736bffecfd8f88cec05922cdbd235956992ccb337388803e93fe6d472bffa69b6445fd3bfd7ecfea8ee04b000000000000000000000000000000000d31eeff680ea08598e7d6e2a8363dc64ecf68f8aa7ed4b320248c03925f47de804a3d1032304a440db826adbca6bdf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b2a9415184f0d79ce8f774bcc74a5ec611ec43928768ac2b531f310bf0c4947d4eb0625a97bf7a168f5089122e4a170000000000000000000000000000000000840cbf61df78fdbedbe5975581a5e7bd41b19ebc61e8a0541ef2abc34f5a1bbdf9afef2d6c9713c1615cda000fd8b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a83040679087e5e88a005c69aaf4ed4e9c01c511b930f2f234aaead4b4df52aa89deb22c6391fe314ae93e8438038a000000000000000000000000000000000790f5f03c81805b9f238bcec04e99f6d89565988f85c70a1214a28f29ee6b487941a0e0fb121979a02dedba4d94c6b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112c67214a585457d14003d451bb4e1d2cd82de1b4ae8132f8407d1c5f8bfa8b22c81b220186d1f2de4abdf49a9448c00000000000000000000000000000000001c30e3a774a60110fc6fd3da7a341be0f9b783320e6834c6c8bb929be84f1eb2ef6761daf3a700f8ae6087f277dc6df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036caa1f4e66f153257ad4b44865ec4f073e395856118b04a3445372d3c6e941b3962a27ccf0d99ec242f095fa908517000000000000000000000000000000000943e03496bddff6c96d69d633e49328edb49b5eb97f1632bd8d29167448e0b92e051b892747d9a3521830bf7d69f9cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbbe2a71a450988b380624c928fd79ee3fe7324514f6bba24abe9272766a0a6f0b894521f63a5342eba95b4cb5d8b70000000000000000000000000000000004f612e2eb3c2400e45ad0fad3e5edb65948f4bb4fcffe5e235af21338121a334cf1b920fa78a331f1d64d62f78902fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da04ea8aea344e5f5df1b4bb3b24331cc234bc3050537997a502643c264f94118da289cf0b9be0c5102ede3ba77b9a0000000000000000000000000000000000e555b5778b64b9767df062dc49f691120e20fb2b96207ab01cef7c21fd7c418a36559fe2a70d0ddd71342f831e2c5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aff6350b4444ee4c4907da991a42452a39cf85db2280f962780230e0056db723b113b5cd6e54a18a51ac811d46c7dc00000000000000000000000000000000058e1e75dde66beeb3309691f8e7958620b51f20e46b6bf9dad70964679bb8d1866ee17cd91a8de3d608d817df34244e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154a5031ae67d378d507e19fe6b1572b1cbb267a819f083a3c06642d37296e4406545f4c31991a6fbb4b9a88640398c400000000000000000000000000000000130c6ba58d3a660cc9324a26a33183459c726162ac2176004c0267f0936483ecdf76f2a0270cd820b56035e29d99b7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ec5c6fd52b295b6b4084e67aee813873be442eab6793f18520862843ed36a3725c47c76bd34520d45c93504ce2e1e800000000000000000000000000000000065bd3eeb2fdcd19ef458f24f9b7ac6c8736325e55fa728140743ed8899e75cfc133d7eab743e9a2a6ab853bbabe73f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018786b3153d61fb9a3057b54734e84e0419da3ed2bac0b1b2653d2253ea604810b4dc5df2cf66e92e44c607d5845baca0000000000000000000000000000000005add1276b17074d1622f3bcc93f1be0c544c1398fa301e1ea95373eeac208d1d06905ab995a50bc2f4aa726f44136981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f9465481405c1e9656a1a1b93fd4d271e0c1c3e86a38bef3e54f0acd865c0576531a3c0988b8d335ff1562f36188b0000000000000000000000000000000015b2d3b56b1b7c1e30f3d4d7d0fd03a2f0a7324253da551f04805233330208bf07bb6ae1ba5cff41bf793553c1637c681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0bc38ca3ca1636d4142a41e65e9a201a33dfcd0189fa01a9d67e31cb4f28a72e87e08b1cdce85869eb2562885069410000000000000000000000000000000014618c3d92be0492ec2be0ab1a058486228763e1b0e67dedee1fdab4d0eebb9a4afafad5be4bb4db8a4ce43216a78aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e4d431d80e96598d258901e0cfd796bc27d8f023a3fbbb583df311fbfbf292d9404ef6540d1a6ce34ca0f2bac3b31000000000000000000000000000000000bd28e5570188c7c316797b0579a5139906fa42d4751be15437a8f165487c81ce8fd75cf646a7fbe4ef2c5d3143d1ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000320c17a19aff64752e12764363af9d46493104d537794c46bb2c5b9155cf863f5d9212dac52f5b305872b6fdb600c800000000000000000000000000000000007758532f15fec81d22e669a711b3a3e37c88947c1fca58cbba0779ab5fc8af6b52a2f2bbd689e4b46a920d3958f45af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bb78aaf07d53a0cfdff0d7ed685d4b8944e2a2560f730c524444cf97bd40632654e778c15395207ec2fa9ef94e70460000000000000000000000000000000007f006a31be4be21c7e7417a1d535581e833cef211f3182a864eb2e93dbe86ee64d28fbf9f7be47e5dcf93d42b25d81c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e809d0ce711cd762010b2da69a934de4a09e9764a135bfb45fe4e8e8cfae7d1cda014201148d68a7a25d75788139ea000000000000000000000000000000001147856996f11ce95475fc9e8d2599c26bd1103a976ff448b7b3f96f78bd6d77798b9f166d426334e26f156cf2f27b751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392a1e8e24f607a0a6f00ff9747fd1f8d7de472c542a56c00102e22d9f2cc0d8b0ff35a3a54cac20ecef25aa5d3ed96000000000000000000000000000000001672d438d03110ae1d7333fde735ef164ec03bbf0e1a074045c619ce988d96a9385ed9f2731a373f0a9a76f8e31a2ca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d845c4b71e765b7d489271790f08ca9b009eaaaa4702956ff7854d2b703f95568cc6656f72c3a31b6328631e6045a2a0000000000000000000000000000000014e7c6b2b055d2db266da3f7635dad731ac9551489be998a995aaf28d2bbce0e7bff05f3e5f364bec42c4172108bbbc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a80fa372cb49f5e66a9e7b5c56db05c3f141f52ec1c987a7e98cb0841a1cc8ab59622f45beabd7622f805b162c1d08a0000000000000000000000000000000005374402d5f5b09f52d8f072c1880c78910a28e5c510f55c82335152cb1fa9a4af8d735c7d2e069e5a779df8433eda471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001069583f1f3b45057b91e4460d728cbbfc18609823f959b8c78abbd04cce8f21f5e594961d6c6458698286408a8b52f20000000000000000000000000000000002ad9013fadd9f8b2c559c63fb0014c0352fd9894f596dc1ff4127c356cc9b4c5930880034154eb8910e7582f37842db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052212c391d999df71e3c212946c286809205d1159b55bc9475f59ad0a8f587a0ebd5fbdaa5c219cdf591bb7338fbd2c000000000000000000000000000000000bdb32b4b6fe1bfc7d96e447620b7be4fd9a40e2edaca99efb86f7ed4dc180a80f8ac11755582daf440fadeedf9b3bb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054f57574d71171c82fb5d3abb1c92d5350709d6b2275aec41b1f8eabdb48290833896d4925e1461f70674e4e555cfbd0000000000000000000000000000000018eac4aaf3cb2cdb5d5243b1738a34e68d7aad42a1f45beed29209e2cbe9aecfcf0bf67939f1b93d30a98ef5750e74051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b35c52e2bf7ec91f41a060906a6f38727da8254376a1c238c198d2343d844820ff0117739240dcec2b812fa490fd97000000000000000000000000000000000ac7e38533ca88b8d7502f607ae9cf91d9d929b85ddd4eee327a766a98592d6549960a972a298e0900fa2f661d1e4c851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1764f43c537f0143c6f01160cc284964d5054e34dcb5519f1de3706d31063d408fb4cb20bd94479445c8725560b6300000000000000000000000000000000001c0ae98ed2cf78cb0ac25153a7d6230796473b8c2413ae60cbbe314d61e3470723eb9b35610f3f06ec70c3ef0b569471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396e5bf77beb600b6cece5aaf125a304083f1a4f90cfae44aa72e858dd8d8e8e0b141d6a76159022a7517c69eed920300000000000000000000000000000000039381d29dc299ca1086843a1bdedf76604ef78321fbf15fb07f3e92de84cc2e74e3287dd535260ea2e9f19012ed9f6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f3af78edf2ed4e6fc01ff29ac963f0cbf6573e8310224c30758322b80df2218409069d11c106956e94ae9f3c156e2f0000000000000000000000000000000000d1417774d4f11acf5a572bbde0758f28d9fb659dd082b740382bbaf8b64c2b8a5965adf8660f77ecdccdb0867e5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001325814275069acb96cad37a3dec0545c1ae407a5f50113c6a60c5bad44894f56bf3dc28037a7b6a93c3b5d66dee1684000000000000000000000000000000000139b11f71f934027a6eb3b12de798819aa3caa151a38ffaba883a6e27e70929eb3b563d7bb3ba307697bd7e2a96ad3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dbc7515d691003743727d56c36056d1b42c1ca66747b372c0b8a43a86e768db4530b5158b360f174f93193bf77474b000000000000000000000000000000000034c2c9c482b32f9d0c721eb27ff1da0cd9941d875eae797e846e489aeff2ec6408b3baa7b4ccb6a8fecb074f8757301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fee60d0b028b3be37861a29bed8411eb90fc333320e2eb12887d21f06246b7a38caacbd846b81ac505a96fda580a6f30000000000000000000000000000000016250dfd534a20076765d63439ca4584d8bcb49d028131479556a67eb27b7f7ba01610e53a062da06563231e37bca1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da114231f704d7c7fc1fdc6fc213857afdaa902eae3f96336b68dfa9eb0ff91c91a248892382706cfe856e64e3a37e30000000000000000000000000000000001c44f9834ecd5d7f4b4a88cb878ec190c3cf2b4a2f16509e1ca33d84e7c8efc4846a9a156d7ab70e31d894c70712d551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e4194664198dfe3792a184bc375834376592c7cbe977781424c19e664c0bd17d28a679073ba3e1297ff4752d2b52a90000000000000000000000000000000000aa36adece6647d454afb83cc1d23dc0aa7ce4346ea004cf324667da96cce6c6ed2819aaccfbc879814cf726d0b93ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b2f877df52aa6287731c89dacaba184662e29daadc6aca2ae2abfbc0685d9f2bfac933934ee079a89e4603134c012c00000000000000000000000000000000192d3014c14eecb3c63d8e1e98c8bdc32de3414c65a06f24441a689c86f9761e624ad9acf50034fddaf5c479eaff93761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018214a7f6453f0034b9b53bbaf69316940f1f313af5bf49f6787efdeee8fc3c27cc9dc07c5ec8458ceaa9fb15d94813f000000000000000000000000000000001766b803edb19b2ace02fee6c207ee7377760b30fca1b27e050cc8f89ab39e102ca952a33e6647ecb9c4632f169950ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f31c65b92199c144de3d44e52340a40a086bae99e6b807a0341dae5afa547d6982f8cd20de46a4625756cb69588145000000000000000000000000000000000a36b54929a717711ce0c3aab11f43dcf991d2978f753f45c11ef3bd914ff671844b21c8e9bbaa43dfa550b9ab29e9d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ce157ac22514c3828ab6c4e3e53e05740a2cfd847ce3a63869f9b535d74361e555db67cd5be55f19cc82e01895dcc60000000000000000000000000000000007ce7c88725fc7d53d188e8adfdf2b305298649427672090c670b626ab4df66f2e14d1645a76b12cfb5fb16349cb2b3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8d82eb98a3a5e194ccab916554ea42f097836ff43c2fe910639988bdc063ad64b463376c3c2c289a6be9dc04c10888000000000000000000000000000000000a3aab07c13aed10715f38f20501aca4c6b69a4f6196c0c049defafefa873a907fe807e55001cc066edbcd32194ab1de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b51edd39b5b6461e001297c80b60e89f624ce960000bdad4f680da1ae44c4f891a16f61c0db0ffe251f346d1e8445fb000000000000000000000000000000001492317fa3877744bab150f303d0edee2dde992876aaedbbb0d7b6666650b491dd9319905bd6a85b4b9a18c349dd963a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001459257e78ccf3bf82f00529fa6dbf7b40a535054475bbf92140623e6097331393bb620e8a2cef47f200e231a3a439a80000000000000000000000000000000019d2f2ff813d63e128b2894d67a46dd5fb45d729e6c6e438326c7c471fe371cfd29377a95ac2833e51b194169fe4e40a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e71bb76562528d03294d9411796f44c4fd4c7ca52605653d168be70c8b28ba3790664b3820fe4a96f669bbaf4f44b40000000000000000000000000000000014c6025a996c78ad95bd66d532090e34b5ac9e95479fb7fd6f490a2aa9dff005a9f74aa79dfbe16f401cd2c08f4905171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107bfd6ccd3b1e7a9be262edb1ce55a08f5e87650286c679bfba4d6088bc265c4ee490c9cd5b05b471d8e008b267c4ce000000000000000000000000000000000228f702abe1b18a086cefe61f0692cc151929ae8e07cdf4d33f4d85ed0f54301740015cf7c2fc2fd957b9a45d5245c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cb348fe4d5897b38281690dee14c61920d0064ec1f1707a190f3501e24bc61b839b9ee0f4236b4df2c5f420d0efb5c00000000000000000000000000000000013974a5a8ea2d46b9a709c981d2875c5799ba45bc6c5523380e63adc867fa6b0c33b1794bd422c6b01ad279e3dd85101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153138b4af4123eebb0bf5242b39bc49bb1d7e8d9944c11f6daac2879144cab0fc3a40655bdc30ed804a1d9287726c5e00000000000000000000000000000000025917942ac76cdf20c96a5ce693a8320a0206da64cc2a6cb978605ea4350765f99372f3dd713c2ff11f7b15c0efcfb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e98d5b5bfad6e5cf49b36c20ea4ff3724e0bbec5ac241476410311ecc21c68b69b307ec33ea776900b05116df6dc9a000000000000000000000000000000000be9ea6e8d6893cf5975207b52e226204fd41fee655ebdb9b901887e3735c4de7be340ce6ab68826d999acc41a66d1501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d431e72d4068fc6516d158900d276225eab74b69a35ef4c37e44b9ba4ff48ed2091af627435d0af2243c02adcc5540000000000000000000000000000000016757338f57046fe8b2edec642b2a4ea5d500cad331aab54a0241f74260b342713264bdc678ba98e8ff98fa0beb709fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ca9f8d241535cf61c100d2697fd1b0d9596a5288cd1277a2d1b1192914eb270a8c61e15ba9e31b8d885512ac8a70db00000000000000000000000000000000036d28ab97a65690ec2db8a35ad74c56c3af9124d01fdba76bdf0462b7e2b551b28b34dfe0ef641e684f8feb1ba9f1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc7e468f401ed1da5f4b6a970e8ff35d75f214220e0ed39baeac2bd43c6f052567abf29f99266c7cd81d011f6cb1b7a0000000000000000000000000000000014170f10fd24a2aeaf7ff88f21dd4bdb0fb79e6428a2ddcf75691f601eae84f26b3208f8901c93cfd63355f405fc318f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e395da6751313835c97ce998117da08e7bbe5993662350ea48df03a30fc65097020d55ee266419739964194dd06f88000000000000000000000000000000000fd9bee77374381d29d8f37633fb3167d65c94a2141a5e20cbc5939a049e50d4fe0a7b868b0f598b898ab43ab607d3781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d98b8c9a2e5802d7778cf10660d1d4dade4063bec355b243b46a9dbd36f7127465e2ee5803cbbad76ef1e198a5f8f100000000000000000000000000000000187f2f5c276b4bc52129fa1ef2f05de3ea2ebfdf6593587f7dd87744ee2810e43bca6bdb04005543339df351b83368631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff8535755b078ed2182ff3a8a49f5890215254785fbbfffa7a2790171084d56aacbd01fb5553a07852f7d1dac759beb00000000000000000000000000000000113a6adf9ad1da55b395782de6ef7f56b44c0cb572bbbcf30f662d7b6ae6710a26ac020d456228a8a879ee834b4200841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e95296679513066215466fd77d5db89a61e962e20ae3eba6f24f402d6823355480af9ace526b42764cd3529ab555d100000000000000000000000000000000008dcc1823dc83c493a275d1c837eaa446c872837e78b7d34328e518df42f04d50ac517ba27982d118ea3f8488e3b3a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523aec3444f4e16ae8cdb153e8f1d9ca20de23449011c50e1dca749d55c2098240ab85513c0abd97097c60c8f471ad00000000000000000000000000000000017238027c2abf0ff696fe7f98f14177018e378d715b3f98c3d3dc06d2813e9146010cd3bee3483bb7712e8031b59a4dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011360e4586cb6fb2a864d19f54bed7e1e122fb2ea43cf16de2a6c41d936150bb011037cca5b1e9021d721d54c3156b820000000000000000000000000000000000bd5a730913bd277858a9685cb2eab31c55bdb0783fe11994dde5fb1b49b73dd6b6169a5c602a09cce471c2a603c97e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b6e95644d9266ddd8abef08978cb9e84577b71e8fefff1d25f038a645a4a426b90da08c278b6cbb1bb4d2cc7ebcfdf00000000000000000000000000000000032c82dd432f8365296d2abaac4081423110145d1fb17e45edf3093a9627a00b257303959aab46134fb03c7f7643e3ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc217708886694d1e1546078bf41107adadd76b1244249c0d9529fad652edf7ba1bd91ad1644b450d73cb081c4cb503000000000000000000000000000000000fe236ec172417311bbb4906b35083608632650f917eaa1580a462b0370247b8c095ca209ac4765a922077a9e5344f011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018c85cd9aab84571430dc7c9c484b350d0f600ee80090606c493636681e8755eb5a86d334f4d2b961302165055e60bd0000000000000000000000000000000011013b1f59634f653d213112a6ffd0ee7666aeee3c62747704bf3d8a7d77a037cce20181421e906b6282fc9c872eadca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187ecdcc37fae66136f2abda2d83bfb3b16343da7ae39baf18bd89cd563fbff896cdf1274e470eed05c3cdb817ba7f9300000000000000000000000000000000036d96d253b980dd81714850f15861f13291655df7dfb1db24708ff4828901c7d0bfc053c926c33b5c1c85a3fe52ad691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547a7b1727361f8fd2302dc47dc7e61dd6fea23edf8cc8e77607ebc01bbd7776e134c3b7b5f6ad4d38e76b2a1feae0200000000000000000000000000000000194776623554e3451a2bfd9fde00dbf548b1367bc1fa1b831143334cab86a6300665e84850519de030ed642ce877bdd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108ce08c47afc76bb2b426932c431560925f2c5f5ad38e6db22e6d3662180e5617bd0fbd3f50a38425ecf2396868c4100000000000000000000000000000000002c3728742fe095696c91f81f96b91482d1359f071ef72a222badf186858c67cf3f2196ee75ac1d66ac8635271190cc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172a0509acf8853b256dd02d621111f1062279be8503dff8b60e200eb0e6b9025a026f021bab63386af83989fb48ac1f0000000000000000000000000000000011dd6ba6fa97cc9976b47d18b3db61dc1d16f276b46c4099dfbd8cd52bc82ba43d7935da6706ee37025fbf3a394146e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d697207d18ae9a20a274601a1242940cf46983478fdb0c842670838c29ee0b8038405c52ff9822eb7bd912bf3f1b20900000000000000000000000000000000178ce27d6bace369eef2d202dab0bc294b275ade6ac574762afe72e0af5282010d3f154db39941bcc962f477c73efb0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068a5b132aeb84002f3a80cdebc44ccf1c9e7551b3114640721e039af73921c2dc4f06e78af033876b7e9cce189a22a00000000000000000000000000000000126454a74d8ce9cb9bb0e00b5921b9e9ddc816ce38e2accfaaed506ba2ad527040e42cef8aefd5dc36608b86cb20e5dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001789bef9dade1971f998f274bb176c0bc17f87fb82482d95e4dc1103a04a705a29a541d2c40203c948ec0f9f14ccd2900000000000000000000000000000000102448edf58f27db4482825e830ca787bf8c4d53fd21dc264c5f35a921dfaf8c9fb36ff6a10ed4dfb67eb1f2d8e6d7e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d842c9a1937c6f6eb8ad2c92dee8eae3f2d6835852bfd60346dfcb67df62578b4dd1ec536201dc6bfc62259a24152ff000000000000000000000000000000000ef6d4b8f5c4b9619608c6651514ca55658e2d32cc7caefad49d5c7d627cc8a4070e53733a80f41656d848aafedb5aed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcd732ad217abb89a936fe170381b9fd759dc53ccd977905cd1048a2e6182f5f12e128504c9afeea633550fe48b94f1000000000000000000000000000000000b2d178d358ef76e7359a06da3844fd3953893fc39ee3daf835e73693d7ac70e42f7f8ba3b2a938e74dd04bc3f2bb5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b19c11581cae45c9b3d76125314df9883013c3172f523c54278c05d01f60126e0a3661904363aeb242a3cd9a9c5034000000000000000000000000000000001441be72393ef709317448d76957c624938f8d6a50641169e847a8cd3a2916d9cbebf91ca6e32943716c1881916f03851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001127f60282ac550a5ceb43cf485a41cf59f0955d0d8d5505d977cb74789643f1d59bf3029ef5d083325492a8bf72daf0000000000000000000000000000000019a81fd35a6238f1e25dac4e09812df9520cad98fab8baecc04a00d3d687de6d43c291cb046ebb1aa2a2ab56ecf411fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f80e6d946790890b64c076c80fd973222161156a90e66bc41c61cde08330cf0b2f548cc142c568ba51312f5026cd735000000000000000000000000000000000a8b41735ff3367bfbeadb87290494d223acafbdd6fc96a9ccac4a1a637d7e7534dd88064327f41413052a1b4b831e461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe57f65172775f893c4ae5d45c60eaab4396fa7544f0c45ba29369a05b5c3610e1437346d5ba4262f371e190ee28bb300000000000000000000000000000000069a7596e8c82c65c5ddd8ea8c9f608b74d39dfd8e5797b695ea258550a0da7c2bd982a8f1bcfb24cc3a2bd1bf10daa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f8c5847d31dd5888c11e53ff5543d9d49e01ca1eac3ba7caae847fbd2bd1256daf190885defc13041bc5b832266c9000000000000000000000000000000001628b9e76690238e00d806264c00776e151b89043d0a5c83c25a350ad9692c0c3a76c2c96327a4acb02cdcf24cafccaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b3fa9fe5708a6bd022e0eee7768e291c0c33689ddaf7393bb8961d86543154bca566feae2691e0b43602566913311000000000000000000000000000000000cf5fe4fe971753d340717a9a2610e6f01f9e54e3477211b2f45b1b0906489cbb16fc4a90c394dcaeef6268bfe2007131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019baf5109be1dcea35e2e7166612d578ad8eafe1cdc8b68b1edc5fd61d9951565c73c9aa4f06c0d08f51677c87910b160000000000000000000000000000000012cff62815ed156824b1d0f9b278f60b4d4d3f312ac9d9b70894c500e0811823e3744a541576b588fccd7d4f688249541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fece9be0c8574a9cf243c773a868aec118407adb29d54b75938558f0941c23d32f5a061899c9ccf16b02d495fc20043000000000000000000000000000000000ba39346401aa9067816750fe1234a9f24f9724dadd761126472f8c59bcccc8783ea96d4e1a91f1f11943a59cf0a1e331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5ede8dbaf49711363b3db099d2d1717b14b4194205da385755288988ef5fbe614c5183c557f1c37df323d7833a74690000000000000000000000000000000004863b2d47c4d3f198eed1067bdb872c98dd19d442f9700f5a742862b663ce91213380942773c586959330e0abb80bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9056f07c1190f59706e3edd8c58f8380cba6104cfc99c372cc720638fc5b7c3d62ba082fce6726b4bdf5101be5912c0000000000000000000000000000000002e6e903c825e96fae44f0305ec1ff2b7f9562163d1d19ed43a8faf9b45b621a71018f5cedafeafa245788c35b2f49791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d6f3a54b0838f5e0d04f7762f030f208228631d316c2292e9b5625ddf9e23992deb041aa6f7dbfdd6930a6002af870000000000000000000000000000000001743213de89b61877f528f73c9f39755ae62bca6b855985ef20ef9fea29e49addd807adf1805c6b2bc56ea78297e43da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001881632285460b4546fe60fcdf7537c674b75f92c0d35d0e85a97b46b29e164b49817940078b8c4c87ff3cc3906ef5f9000000000000000000000000000000001230f1ba7a7cf3c7ef0fdf2fa3b9a74087ee16aeb3ae32eff8029e8eaba18793f61c1a96e77c192e609308ae21faae6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d323b0c98ee70b77391d0744243494d40ad59343b6f53848edac72b8f9f47baecafc207385926dd2c1ba6a2115539000000000000000000000000000000000b223e2aaf51f8ff5774d6b126c5b47bad07d7d2c849e5a44f926d0e53192d754bcac761a51042e32f303697a383678c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f8059f2d094d7e6edf241ab917700fbd966cdbd178ca625ed836d4be6f456c1af37b44841a0a763cf9695498b450b0000000000000000000000000000000019d51fce03f4713ef40bfd506886a07aab0da3044a475938425e8497f576f0b28b73bc506291262382075ec028b6b7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74667b92ee623fdd066808ce7965cd4e938bf6eb636919103da1f47da6fe5d7af4fead3a5f007198f9095b08014df800000000000000000000000000000000025aa9902420e3356e1646f5f5dd2b845101c4c15ccf687d56e8677e33ee6d0fdb3cfb3b313b3a0ceae8401005cdbf461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cb85016867d6d26fd6555d2fec6f60f0cb55e425ec99af5e90f08b2f16af0995fddfad8632df5269d1c55899513ee60000000000000000000000000000000000230d2973e94ebf8274108dbf01835b0e62a0f8ed70c2a4468103521677d2437dc344d2749c2f5a273c6a5f5c91c2901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b31821d1e4027786cbcbad728209972df08a0c7d2aee94a6f9b02f810b2e09744d446feb8387297fde0e3bbca613152000000000000000000000000000000000e5a14cc17b37a43b8d23d9efab2250a281c8d362ec1e974f33f375b2e7f9801f013b9f69b9f1913c04e4259c11af6221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b839aa36b7b06537ff0e014cb72308c407a775e9f75a3e14a69c578710ff59ee5f79f34427d281251f59f2f035816af0000000000000000000000000000000015727fee06b027758b4a4d6bc0155baf846bce98bf66a16ed3d2834a20a3338c2317a063f6c12ac172cca73ef5cb0f7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000120485ea8768b97f87e3cc11f59cf798787629975ae6c7d3148e6e0f06f50b840090038d3f21c3c8ecf540b2cc3f58c00000000000000000000000000000000115f5bd276500c909a7fd26e37372608c3bb55be4de854914ab1e611b87fb3dcf26d47d72dd9daf31260b924f22d72691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb444c08ea1ddd8a7fdb9034cced4f2c345419c07e748425b8bee30ee799d035934150117ab7ed30b20c21f8877c0a8000000000000000000000000000000000b4d627a8bef0fb3ece9b554cdf830e3e4e2b51534c776294522c461eb81124119cc91dce3a2da9ae1fe67b7c350b94d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccdb74e8f32d377956c91a1a8f0e6f611cb768266c849c68b581bbae90e9c7f7ecca0e6c3d21821dfdd50a8aa1f029000000000000000000000000000000000d9e734b9a2adcba55469857086f2a2cce6646da6c518a699e76ead4f2b39fd231b0ccccfe639316c70cc8b60ef22f911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001835997583f5629da4eb34c240a206f9a1404ff638b215a47472f44ec53d8161e2d2b82e0be14af24e9f977bc7595e9c0000000000000000000000000000000004c895840fc89f0d380bbad45a998951eca010c7224c3ad09b8c67b57fffc7e4a9ac715dc2992846f2640c59a524ee2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a730802cd62d4011a92217b5a47e345b615006d3338a6bdf86f539493f3c65a02095a900cb2a87e2558e37c12e6e63000000000000000000000000000000000292898b8c6f6a5ae41bf31b814dab69e01d9df350e32e831d10d0bedb2c5bda9c41f5b8c991e21451a7663bf9e719d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001865011b70c3832d4f6252f539588dc16d98392af17842d5e37b03a4b7ddd0b1c4c87a41c96025a50630751feb073090000000000000000000000000000000003d3ea5c21e8ea79e76d3dc80e29d11f2488bca6a28f14a704da5e41bfa99d9bf25f88f3df1baf61631c927a175dc0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d7a8181075a81886835b59dee0eed9d0772056b19a8c694624675ad3335f74943dc7feab7f639af567c70b85764ded00000000000000000000000000000000061bcee0aa7fc41e661fd039b0e8e0276f531f5ef8a89be48f441d1dfb1c731d7bdc341d3599517da4be25cf316060d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ed06a01daa9671a7a7f81cdb3539d87dff264294be8eebc816d1790e01224e81252d133439da9bad5e26d2d53ac42e0000000000000000000000000000000002e569bde8c6985d91504cee76d9d375cb57ebdc739bb5d3ed5a2df7b83848abde94a995debdc19cac0b77aad9bca1601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a009b393c61a86af9b4014d08f9f33654e680b48445307c4ac1522fb05ce7798bc7a6f5c224ac7f187af43b5ab43ad7000000000000000000000000000000000ddc149fcdf51db41606df83d3e49771e7dd9a3610d23fab84a896f04da404b1084e361a7c9a939e7d12ab6894d2c5771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c09089b878bb691a58b26ef07bca1c578c44a4f69f207c12eb2c64ffafc87e780e769a975a56ccff1c49bdb2a90d990000000000000000000000000000000000c338644f3e0f19e0e675fbc47ccc70f3fc25ce2d0ef664b8eaa97aa30237b36bfb0d46a04c12bf9e2fbc6c6b5f67b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ec59a363f721465d9fe4fc0af80aa8e3393a2188d8f95822ca8fff07fe8906fd522e7e76e6a1d58d1f0118de3432cb000000000000000000000000000000000994b3e9cddd65b2559bcfbd8b538bfd5b6aa7937650a699226b97e14ccb4cc0d478904f5679723d3caf5c0f477a53b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2087e21df1da91336f5c3ddfcb1666ee66335363e01e5c23574cd8f39a3d0dfd044d39baeebe71dd31dd972ebe7eb1000000000000000000000000000000001681c56571fe767ac7e08bf8cb03d1680c5d33cdab2221a5ceed6eb25742c8bc140b8df934cd5157d86455eaf59c4d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079cec6ce1d188a094734833c5529006f1c0447830d42cf8a7b3990e57783d897a9383f5e2251a13bf42e1449b9c9c170000000000000000000000000000000013ec1f908af9c5a05543745a1f4a7883365f757a73dd8a24dfa28c79fe08a3409806e7f451ae8c7d4abe9174763e20c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175a40d1eabd39cd09d191ec5fd11148515f63eee66a9b45a4d0e9eda27e50bd1d198debf087bf3c6782d1fe364b2d0f000000000000000000000000000000000d58c9f43e4138a6e6fc53322e640befd78dbbf983304a032a23c037515f9388dbd781c08345599dab56728249c791ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114441a09145e8929b881f69c89bda8e7fc3c9568b65b5a909020c29649e2a3e93a0070cd8a425600f0e01b792391bc20000000000000000000000000000000001ada046c6e083351a506a59f3db226606bb5b761e40c8e5b95623a06ec75cc144b6ea4604ac9c192c6ac62a261268811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a498fb2c9a02dd4c9b9410804b4b1914bb42d566c6c101002e6a28e5667e80e0d326d49d4c9c519cceda6b28e806068000000000000000000000000000000000b5468d41123fb55dc4388994fab27cb837f5890c685f1666f6415b94555285df448a7fc8c0ef0a636857f6ae30c66c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a94a17292b26687b9174fd77d47c2d0bc741b0dce8d929409f904b774f917563c9d8b91773aaea7f76fa144cad72057000000000000000000000000000000000b85d8f2819975ec663837b133359f88454db44287b6230ffb23e015d14bceecbdb8e65b32f949ad22e3a329ac82a85d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100ff69abacccd6820324d4652f1b7d208fcbb39d6f6d440cfdd392450f7d06d09210946fd22221c53422dcd239aeaf80000000000000000000000000000000008ae8a4bc94aaea601c3ca4c8c537053d75ac3e97a1787577084459d0b445d2f1e939aea3911c28cd79c571ca402001e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d170590491b00a645282f79b012e1735f2342a57c5dca848f3032fd82a72efd7a5a57375c699b7d103c2110685be6b4000000000000000000000000000000000cfb74d7f007f8820048e9b213d32a5499cc0494a2dff396874fd38656fb6cb3a76892f02db0f2fb81b73f417c4e2a731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c1f3f87f509ac5993162494c85ebc82b4ad7c7683e120c7f766c7b29599454a06141b0b316deba7d5e15e1c2bc47d0000000000000000000000000000000012a9b539eef5a057b699b0b764ca87d820b13b46154584efa36ddec5398820e5a2de91f184a32605cd357cb0cd52bfbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2d142b1bddd87f4e3ee229876fb4318eb2f1cbaf64773c5d2c25cb8b6f18cb8fbdcd2d37d859fdbaf568b8dd38cf960000000000000000000000000000000010acc3d377132629dcc25a39d2404ce318a31b69f718e4600ff75e7244fb653311baea030db1668dbf59cd5477d0295c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6574ce7415a772aa066bb792895a3d7e9923fd392a8ecaddb4e63f8482a566cf91df3ec615915607d466c7ee80ff84000000000000000000000000000000000fc4ac2659d31b0c300ba58380057c9c96330afb661418a2dd825936df29c39790e79697998c15b6e3c4c21ec0d787311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a019a34ea88974159ecdca82659e21f2cfacd1c5a9405d81a380ec5541ed272869a3949482c346c72605a8369410ede000000000000000000000000000000000e53f6462b19e5ecda90644269173ac4238cdc50e56bd385ac8d3c0b1d70062ee4d342a1193e259421b0fd13867a76a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001471137f09985cbd2de91fc00e547a1c50326a10ed9b34555ef6c20562a26448cd82076fe14352a4472d19806f5b6b6b000000000000000000000000000000000b48a8061e60fd3eb54bdc1a405cb73e2ed465706847199c1ae4ea3b355b6a60430d8fab64fdf26727308be94d7ade781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000361d9b30ec0b22a1b56543dc5dd6ffdb6b480d041fcdb28524bdfa184e7793ed368ba3fe8a2d4a6e8ec3cd40817439200000000000000000000000000000000139fdcc15b248e0146e11d909909010dc78a3ad22c812a9ca5b0d8799f8680d53ea81773166d056d43f1ed027c60fecc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129caf3dc0af718e9e38b4cca490ea774ea33df1a0e40db4cdd8fcf4aa15a7ef08e68d6bf54ab82aa25f03396d324ca80000000000000000000000000000000010592a427cd1aaab021674637d836dd55fc70990e0a6d9896867f4f0dc49232620a96bc30504a82b27babe9752e8160f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5f332126f75d71699d84a12b8da2fc8ab474b41925c92497ea231ef0a96bced111d8e5cc621f6b2fc38e061ac74e20000000000000000000000000000000016921e63b5fe43b027f4273a125b0eaa291fc40a6479f366f9b039f730e423a52274db8e38595cdabac8974e309ee4f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002569f84c676ff3f1488a4449a4dd825e621e2513461ebcefdfb35a7dfe7d8309f0bdbe1358ba88a264d2b9fd53667c90000000000000000000000000000000019fc3307bcf83d12c6586aa58f742e028475ab5b1990a87081d71a8b84b20bebeb076fc09bcb5a024a9ccc66526f7aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000060f7eaf2f5f098bfda593148dcd3c9c37f1c34b574cc48a9e67bfc2fe50261de116e1e92f2954cca1af041cb5b0de000000000000000000000000000000000ecb93b042a48e6df82e3428dc80fe85214ce664b38404fb88fd670e831c8f4da7260ad6a12b3b1d2d917ba3b242825c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000324cc5cdb2cd1bc0189fbd7d464f55153df20767e275cf6a3cee85c66fe92a2efd58e54246ec9bf412cec58e020f929000000000000000000000000000000001573f833669e2fc97eca4d725b0127d97a88556bf7fca9bd7fca1e4faec98b5b7beb0892f3152ef8ae879cde3edbecac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018b71f98faee5c8c4164a676ec4e0aa241f7e723b31f6f6cb1b9197eacfa12f3af872fe6fc0de2e9790a67f26068e66000000000000000000000000000000000bc7d304b282001ec4080165c7119001ebbe60087742e5f227eda96954e45861e539a5811add5987194b6280049971bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daafc7b029ab715ab7a2dacb21240463827bd5cfc9e225693a74dc34cb4d859416a8e12c7f963b531d7b07a781b25b100000000000000000000000000000000040675ae6b27b73bc0f71be9d9dafb0ee9e2954b2768c2255d7ac177bc34ea57d4acf43506254041d5ae3868a2cb0c1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000007b5a3863bcb9b6c49cad893ecfef3d34c6b88a1dadc81746f027b3ef37e81cacefbc2d0a68d99e2b952358434db250000000000000000000000000000000007391cd37ccb995db44a5f61721d28ed67ed76bc2c8619574c29e8496941527907a17cdaf6d8b13b4385e6eb9c05b8ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001073e86555ef9db8652dceb021c0cf562d1c5c9833e2c50bc2192cf4f446788c6ac7b3df1e1cf076ec6d953e50d95c74000000000000000000000000000000000a31d76d8d7c6161d358415ea6ba423f0af78494af50a118ac36ce4831fdd2aaf01084b5c98ed1840db9027b5eb9fa9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022cd497ba6274b09e4463bc6396ae257cb21cdd4298f9ae534769f6b7a1cdda3f4abe4f05a07aa6ccbb2ad519ce1345000000000000000000000000000000000ffb58bfb64c7fc6f8167a19c4de93d498179fed803d41e220acaf2ebeb4c532c4c921b0feb5040b5ed555d3e0b12bbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999f6229b581d5420ded5d71580856a484642acc49970b25b21bcdb8814c1c3aaddd6d59f5403101acf4d3855de298e000000000000000000000000000000000470c532a10ca9e609b04f09152184bf884a4497ef4e4f2257fc9e39e98b324db933567859b446db861db724627a71231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086e7e4467015a44f4ffcfd5c185f926215fb7a16f57f93872496d6537c85ea330764a6bf9560910ff539c3e7d6cd8aa000000000000000000000000000000000fd94df18a12496827681df9467e167f178b0de3c588ec883025fe02d8c17c4a2608b26806089fa6d3f27a32698af1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bf6299b4628ec7eb19422402fbae1794effe10f1cbec86936007dd62f97cb11d98c74c4f91a04aa29c1b9dd8c1e6b700000000000000000000000000000000040d6d86eb507fb70a4066b8a20c07077aa276c24d9faf427d99764573ce708cbe0b0945854c5207de5a37a290cefca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ed45bb21220841e0b9ef7b19832770977e81447bf52ccdd1c7b73f5a8d122515ef3d0cb2e0652b457c1c3bbfdcd463000000000000000000000000000000001051359c9fc98d39d4de5e46cd33189e5423aee58e3f4a3a66b57a7eec2af9e97d3b3d420ce4a142b2f079d8e365b4c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0b371c20558206718a0456aa7637166f0dcf16cab7d960f330503d363513e58022ab43cd5b4e38608ac16bc78b94dc0000000000000000000000000000000007b11965051f0c6b573dc4e399ceacfc50c86f766f12a37fab3459954886a6649812915ac9e0021e528cc656ecfd294d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000692bf377b1c5f6e84836cad689cbf41800abfca0770a3f9c6a8c4d917e6d93de039ddee22e013ef05c6ae51c1557df200000000000000000000000000000000074f90fa9d645ec84a4681500abba428055eeba3c1d2f8ea8f88f577e7e7b0a261b2d2ac6fa799f5c45bfd31f7c248d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d0c633b8241329a5e5cdd13a2450db3485031b225a50fe8ce60dba9b496b5931ba7b3214f6be9d63c019186023c65300000000000000000000000000000000067b9d7e6931fdf518b10ba0c3557d4c16291e80ef148c4a2fd578a69ad7a094f2286a3b3a2b42eb8137df748d3b7e6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034ab73f7f8731cc42ece61199a67aabea2434724689a7ebe19533c27e0cc5b4d8dfce52be27f8892301fefede8f9a930000000000000000000000000000000017c1ee4fab35d9fa7a81ccc2eb9ea73f19ef394b31cda79afc9fc77a69326f2b16c805ec16e8d68cdcb3bdcaa16192f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0980f4c5dbceb47769af9f640cece2a80c6cbcc3058dd62fbc0d0c89e166354233635067c87609c011b5f293a21fda0000000000000000000000000000000006e77dd8384f3ffc75b97799d4df6a8bdafbd71803b7dae9332c21643194670e154d7d49e2f6adde178fea7b2e3f6b131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000355c0dc652a1a9afe66faa4e202f0ca12bb368c345598e98ad854c8e28813e91d4e6d7a29f47a7614a215e3748e5a5d000000000000000000000000000000001444aedbaa412b06ed6e374982b8e7ed3a9e3dd89807f5c94f19d7d1a6348fc64a017af639ede1a7bcbc9eb0ae87295b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b1d5ae4c22bc3ae8f024a56c0f35db6b7f38faf226cf768dfae0689ac5097278f6c63ca796f5f2b9c0d7dba4adf38d0000000000000000000000000000000019e4f92b9cc4ffd58a0e7e7868d5368d283ef337ae3a83922dd62e0f8961d025da10ac6313199f13a586cbe2610fe29c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd6930ed1818f5e86c4248ff2b36be4bbdc5cbdadcc83e5d3cd9527a7be7695a359e12ac1e4c628063c00604e68931000000000000000000000000000000000112c28b80e46d9e5492ed5adbeb66079f072a510cd27e580ea6a8f732a2993ea490dddfe573079088964181016d220e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130074006800303cd1080d212e330d0f17690c09c44af87c0323996b79644f30202dba6ff09a9316d9dbc9a588ea963e0000000000000000000000000000000008fab72f336753eebe20f72640a3b79c76dbd5447dd422b20697a9cfb2482621f038e1a1643e6f4c8b2cda73502c098e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001633fce7eb0738c5f70afbdaaa682f27bcf10236b74b3f2b08bdf0ced225e31230265a7eb94ddbf6b64ff750a59aa8f500000000000000000000000000000000082e32e526a6a950a0de05698e5637752082d52597e7125d2ed3b85ecfadac65879b9794a546078605a3537fc7e00e371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030d3b77e2185ea2cfd3c2f0f1baa93a4438f0551e240858e04bf47a48452f26b409f93bed7a8059e18d4ecb4fecba1a000000000000000000000000000000000e51fe174b701f7151d8a8b06dea7c80c99f6c5d091a7998c39d250057c05c45a8c40e5df09b39d5933b44feb727b4bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51839e6ddbcc89082f926651444b4be14d4dd9e46d668406fa4d05332ffa442c8e2f79080d6ed3099fd29ef95bce03000000000000000000000000000000000e9c55c194106933dcde74c90715eb74c7b66ddf617329bcf06bd48ca0120d38155aed66668965c1e2547fd57320f1771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dc87907902a30b4ba2dd84e7574f3358b213849d1e3830e208aed82ffca81cc4be62d3e68c64b1f4bb1770775249e00000000000000000000000000000000199b8daaf7017b6940fb96558e6de26cdeaf016bacc7cc181be448c31553df11bac7e674e25d2993cb7132b2b7e063b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fff871d376f0841f98c53933819e0a628d6b6f3c95ab1c317b79f28dab1852a03806eadd1b3aa74d797beaa3f0832b000000000000000000000000000000000d073605fab40a9c60eb8c3363a519139a6b813c289d288a2b23dec47f755244e437561b045866076473bfb8f65131a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092b6b42d133179d029682d5cd22542d2c22bbf14c814a08d9d6fe957b3308b8a7dc3c31df1ba47820fa8252cfaa2a350000000000000000000000000000000008ac643c485fcd0cc7696481da467b54b94d05ff923865fb09fac132aa6e8845b59128adc9d617579aa799ef0b0efbfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c34ad44b7326f8746c4f03abf6633a426095464b96cb410091f26d30bbac675895ccc0b70d42ec141cf8472f4bbc17000000000000000000000000000000000eed56242bbb8cc5c4ceb0f170de5c4b8180ab39582b20d21e18baf316f3ae1e449e1134d19dfb9558e73606afd955951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011563978a057d2790bb8fe9b2d12af5cd65d3e83d1778279593c02b4332d698bd6f8d43d4d8e9e0e2238a40134bde558000000000000000000000000000000001721be325f7ea7478658e65a2fcf9ee018c4b743a52836d4ce5745e6781c17346f120ed73ac8f01193c78f2958cd89eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d9a504755dc73585b6a1b2a7d6121e7df704c5d2479e550b012c5bb0c0143e570c561216609f24862a300b2499bc8b00000000000000000000000000000000017c07a85ceea839d4add65466fa57b1f70dccc5acc6e6e068d59ef4290a66c8dec61de72c793415ae1a0efdd36f69a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000712d668a1dbcbe170aedc8e6261b740ec74cc2b02d558fa628860a2d8e66f923be2e939e81bfc574f3d437320cbb06c00000000000000000000000000000000041c855cda274c651d62418ffc6b19843cf4349475a78d1d14cd1bb15ebc2096651df7ce4123e8d242a113b12219d5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fd4a5d8d261ad3edabd56ddfdb7ba34ff77f6619bf50bd611f3bcc62c6c01f917a519b21dda61e2a80a49adb39c3f800000000000000000000000000000000127b0d164cd62ec4f6c0732c8916eafa6fe6b422da0033bc80ee8e5d0a6c3a65b123b82430e0d487008963602794450b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000571c0031fdb10799569d024444e40f433d106708c4e9b51bb32fa2e68a8c3eeb81eea87ef37c953ec2376d36442acaf0000000000000000000000000000000008e6ad7b9da2afcb7153a8a384beeffbbc073e4edd623570bc4edf1705b455766d7ee87d99dc4ebbfd28e33e5f5cdd3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a985aeceea0cbea0db060af3e5d44d258f28f3cc2abb47212387634fc999401fc5feb9d6c6a10b277063d13e85cf114000000000000000000000000000000000e000590867dce6cb0ac7f22341f81feb4c6654086366f4456d502aea159bac410501b57fd9b43a89ed750978a6d6cf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef1cbf90ce710ab6b41fd33ba8f723a9a877dd2f992a336cf3c4d2f72d8ee10444917841df33c4ea51a560a1c2bb2260000000000000000000000000000000007d42afa00313b97af6f29c7c436b971a1b4fe63023333dbeb21073621a9d1aa03897e562f5852926430035652fbb04f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045ad6dbde9da5b685f6d7dc10b51a78a2edfe476fc12e992fd3dd386dba78c7bd6326fb469a4754c007c3d83d6ea99a000000000000000000000000000000000e4a62bbb3cac8449c39ad99a247be5284de9f26a3ee99c0f98f27aa0c840906ef3521d79eab7db7690e2c7893cdc2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001049bcf8e75fa9b56fee6cb36251da6248ff342954bccc3fd23ac3324c464ca5705571813f104ec9ac2cfa3cbeff51790000000000000000000000000000000008732848dc5991b0e1e7838140450eb6f97c0c78aa7535ab15b714e1d63556d4fd4eeb009cad4f7bb485dc5e1c7aabf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090fe58e288b8428caf41594e646d84228ba2dfb9b6a1437a21d07b1b5e182919da570420bac6d68db41e740780e95be00000000000000000000000000000000040929cc25f42673d2ad3fccc101419a106e28b3dc982f01a7f350448b5b745561e59d18a000c10969c493d4d9ae94c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc41bee11269a9a5ed0ead2642f887f0daf524af7148b802f9b14a3e69bb828a135437613ee6e2652a4396f57da791100000000000000000000000000000000053ff390177eb1cc3a23ce37eed4c4548ee8000190e6ff387d3c6b9d0a28ab36b0c376be8bb5727061caf8de0c004dd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001216eccdb6a4d4c61e6bf241e9ddbfe8e0e4ed08d20184f5c24cc9f4810d9fedfeef229c161b1441bf0c99f47b36fdc4000000000000000000000000000000000eed8866cc67afa6506695bcb14aef302db96424a51603e1f00f011ebf0c6923f0520cb114131769926372ec0d7a806e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed0c1042977811663bf1d525b8bdd47e9b03b314674a840309df70f518353fa044b8086fc61eb49d64a1e3727bbf74c0000000000000000000000000000000001e4c45d3c1107f58a41ce9c553e8897ce6192ea559d66178f54b9826ac48eb1b4dea328b81864dff854501bc40a3eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5d9c689bf0008a826963c11142cfe1d738cc510ee476ef723d06999bd72e052ba6c61aba9c0c4bc56a399041568a450000000000000000000000000000000001f955adcbb01aa50f81e1e5a3e089d26a360147876ab4a28640f33d8be39f33f2e3d430fdd1ebccf6fbe86b355475581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5f4fda5c986f362d8de4305b61c1fc0daf2c04601499464042285cc0d35fb4f46a777e7a4d6e935fbc49611ea620d40000000000000000000000000000000004096293abaf5943f6535476b92682bd1531488a3e8a4a9fa7738f877788c172fa185306a34b82f83474181d0b87c98c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009096ba37dee41a8695ff721e7c6a0f714596f254dae0612819ae14a037850c13f9e9c5aafe4edbfc4ecb9d89d8fa37e00000000000000000000000000000000068cc4712ac28a8db9d3eeb79e0d72c2646a31349d8bde9562eba5137d33c1da2a45d065d2584b3bec25331d14d7c6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e370aa978a717492e2d08f1006b9c04287d199c92b1fd7014e75aa075d72aeea10b89a2f326ae2e174d77ec6af2524000000000000000000000000000000000a820bcf80628d179135abd412993313ffdee30283e1907f67f37200913dd1cdb04b50460918134b280fe7cd5115267b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a6233e328b2517d75b5cb8c2c53b5782f095e79015478624eda0ed338aa07c7ef287c37c7a15662c26e7b49f1d615000000000000000000000000000000000388ea5bffbe057bc5aec3a15a035ef29935df001e8a6abf01b1719767ae39620d3193c87b9ebdb8b176870c9e75e9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a2d6dbee2f182ae123bf064f0231a314bbdfc3ad46adcca7c25218f784eabae814c6de9180bff76ed4188c084ed58a0000000000000000000000000000000019cd3e1c87f1ece124d5e6bb3681c48779f9ebb215409805e6a926842cba22750f4536be7f6144ea57ec51e798facb5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055267d6e93d635e5b7a382bda7c14853cf964c05c81effd0a7a9e0a0bf947f382bc023fca481d5ecbad49d2411660e30000000000000000000000000000000013bb88834b0037ebf65dd15296ea0889a393d6edf53300f2c53634509021d8127b33dc9d665d15635c5ccf15e5bc3d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005684292efadcf43de6665fd2410d3b4b073fa5754dbf4063277c9ff3d36d46758344f8d7e59aa1861527e958d440d2600000000000000000000000000000000117938f23a121ea17d27b8a57f0aa4a73f76be2b9fa5af46a38dabad187087545e9f1463263146149abb3622d3faf49d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7e2f73d20113702d1c95bfaee5830aab022d7f80047bddff912a884da2a538bc9d108d607ac8cffd870a7c9fa5ca4c0000000000000000000000000000000007622edcb2c84d7ae3b0895d8eeab5d4b4a7a879b1dcbb624bb6148be6580057887db95605d0b21a9c858a84b6d6e7a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e440b2b4480a19957095e7e884eb29efd6f8949114a91240dae77464c437c79b5a7fbd3f59a83377679d948dcf451b000000000000000000000000000000000cf68dfaf6ced5a6496984acda652289da71c86f385d1585cb21297df843faf0434978097407c9d03e30137e8f30beb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a195cda7a60e83da8636e1bf8795cfda7e49d2877346a04bcd9a99771a77cef77dfaac0ed3deac5522b1d1988259f30000000000000000000000000000000019703a0ce8a51a72b5bb31f494a2b934345ad7629775b8ba6f4256b1987ab7f64c9041b370255d9edb3a07f408005aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173795fc5219025fcad0be04873b66e271a6f2d10d62640cb10e93c8bb42a74b203115bc85615aa85f9b5a13484ce1c800000000000000000000000000000000126fe23a8acb30bd36264918acf16d9676b466d8e4db1ed1c61496ad05401316462c2ce4ac19bb35e3812ad21974965a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001796126de82544616a8e0daaa1ac755312c301d6410798016b32d8c57b65b1343afe1d8aaba1f0512ad028d1545fc0c50000000000000000000000000000000006ce0af8db44d95d4686e8dfd2f2772070fad8e8c12bda55336443ceaa9f6ac12dcc8acdb0bed889638fd6a9a63a0ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c003e819754fa93590f73b567c35d6531ef649a224d7dfb4b40141217e398548f9fc88d2e724398355725b99cfad8c000000000000000000000000000000000e0d7441a592da8bf1b56f89d5549042093f203a54da638aa071d588fcbfa9875e38141c1ba6d26910f0d958c5dc5d091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001968aeba818b7ce877725b3fb8cb3442944e7d12d71809d4f7b34753e5092b467500acdd59733bd250e8107cea36c3390000000000000000000000000000000017c775964c6475866322633bfb100f50208b667b951245f41a8a361e5cf41db563099bd6027c3b56a91071638f9e221f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e5e026c9adc51cefabc991079d116796c0e625b891bbfb51cc57f4bef975df47898b01a5b91e081f496078106a9e300000000000000000000000000000000143977f45e579b464ee22985eca3f0aa257e506eeafe185453662f215820d75f6e20587775329082fc94874ed16c90ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001070680f83e6554530be517747be1cb367a40427002d2fe4c74f982e2e74247235940e28c6f6c2e1b4ab29def63895ab000000000000000000000000000000000dfe3f610b119993193b10b62a86945b6b234220f4467af941d414b2934dc8294b56a7f02e6ab02c2d4ae7ed11e5b5a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5085b2d455ca2da033a8cd03f1ce8badab0ba2fd968e57d5d86f927ace96ba760c917515dd18d14d8fbe4e7a7be15b000000000000000000000000000000000346d6add2cb16a50cfce28b3aae66beeeccb463d1b92d258d5cf06b6f3981d7d87cb20a6d80335ddf6d18c65d2a93501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc469d47861d2e61f15522680a5051a4c0cea7569a570d8e822bdd4ab43e741206cdb4f1873fe485f55cfb016e0b866000000000000000000000000000000000c000300a234fc5f160e7e41d050d592867772f5c051dbf8c8efdbe6206808563b94b2fe76c327b16fd9e66936132d021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bc9d6e66dd33d8bec3ba38e94a4c876ac2204e4a0a0f07249c2f4669b2e76f969c69732f0660ad4a8396172677b35e000000000000000000000000000000000c580810b033b308a0ed3854be7fef74770056cbc508b868ead00fef512acd7a3df7b01426a146d0c7f42922322d132e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b40ce2140196395850b8fe8b295e0037f6d84655c5d6ec2749b556c4a673e4e0c8889346216eeaf36a599bc7c149d400000000000000000000000000000000183c3e32492cb1af03495a7be23be07d2e868187477dfa523213bfe54f63a3372fa42666fedd316925cab9e3511cc70b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000865fa2918adab8e8ef9ceaad21181e055fa56468906cc70f4561b391bb81e2fc6c2ba2cb8868183e80c7a6f5b2b9121000000000000000000000000000000001523aacf75a1d07747eb9c5b37aa302777dccca95346e5e836ab506ccbe72502c75055f74e5a082c9ba54f9e36801dce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b2bfd0ee491183ee659501e3661bc29b0f862fc21be9ec8f167fdb37f7b91d9765a38a5ef6419529c8016b46b94698000000000000000000000000000000000b93d410bd4353b04b97068cc45db00064180392d919b64fca0f54e5484567204408bf8bed364fc31e3aea738234b2bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001017eaf9312a6f272a8b0f7af3c9f41df13f4d029b9df87d8d325592562d37fd7719087596e28685d91bb9fb71b1926b000000000000000000000000000000000b5f8b51b6d8636d33b6049d6398de5f1f615abee6d7827683d4eac0a8af00a4cee5d7c45269a88ed3880df6e2df19661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009482bec00076421be6a00247b40510e2b7cb78967b16659d95ff77b837a9d474fe5a67441acfc180e8bb672c5cd4da2000000000000000000000000000000000cc00cbfdf5303055df6faa42f619fa44b35a1ab6f8bc510fa8a8309c5e4cbbc7b6f09aaacdc01c7b9b060166cbe05501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d7dff24e51c0d068392461c688d9dc2b3aedc118fee8f0e0d00467fcbd2fc8594d3bf658fdd83ffdd028bcef005c0d0000000000000000000000000000000018c4a95917fc4964ad68ff3cedfb42f28f3d4887d31fa4934ccae38af85d5c5b685df87af29a84e98e63b75f0f75ab4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052e41463a212b2b7ef8dec1c118160eef1e72dc0c5e1efffd35a9e164c8890d68d15b57c41db7883e84b25c8e2f0f2200000000000000000000000000000000025cd2480fda96c3763e63c7fc7654be0fd96e27b272ebd0f0138a88737b3d089af719771aa85c480d73861b9199f3261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d93fd2a09bba916090c92d8906fb5b8323b47794334f7dbe354d982bcdc03c786f2f8c748010c8459f44b8da559a8b0000000000000000000000000000000001658ef67e917692396da86f8d8b357ba24ae7bb8ba1524a7f1ca2a560c258f6900e8fb48c4c093ac1033d849a60ea811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017645c46479a4519c7af6a1bd9258ec5382095f218e32d1d0836ba24fdb343763272ea7a4c355bc3b53956e22e53509d000000000000000000000000000000000de9ee904483bddad4db59c9f5936c91ac9e4f12c89d18766ae217de3d10a8155999b75d5c32bd01aa39ffde7110e00d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b501e9be7fb0d482d08e03673d28393e72fba2c9f3a0c4ae8269bf6b77493115de55b154f9bdc0bf54903fd3400f57000000000000000000000000000000000b3637069e9cb8e157407d8280e8e187674185626d6b2b7fc5d06205ab6fcf030c95a84ebb70bd1b575c4e38a1837ce91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec1011168da8c3867f814ebc5ef2039d524927a64dbe929eb0cc98aaf8d0c23890a1219d202feb90fc22e000d4eb40500000000000000000000000000000000088018ffbf4f90d97367e3981e66a6e445254479d29791d50d06042b4412c55d79a06010948e62359c8fa000c5e67b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196be932cf504ab83ef240b768c77b6c0648e60845ea52547b217cd62bca574fd5e91baa81b348b926a0c1080fe983440000000000000000000000000000000011cd458aa807cd3e950475520af9ce84e922d5dc8c1a17e02340cdd29c19aa8619a9d6a7be4db5554d980c2793215eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d44eae9233452e0b9fcfb36bea78d228b6c33a94d15ff6442de0369ad3940ec4635a36f56a1b9f4aaceada0f76535920000000000000000000000000000000009737cfeb396c5b577338cd892342f45206077af456e552b9a44b9149c379daa0b22dda5b009d762153f26f9862391ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058567c7196fabb31d8a61dc2f925f594acf9b9a365e94034f39fa5766dae1660b30225a81b4bf1c921e311333de6b2c0000000000000000000000000000000002cea39ffebb2663e95a67e46e8b78a00519f3f2dee9dbd3cd01446e3fe653735ea48ea30ad6c6aae06baf7a78e46c661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195d2461a86511caffee542888bc1da2eb85254108bfeed7deb1bde1c66a3e5fb723b6ef7567c47d0fbf3202a788d9e70000000000000000000000000000000009d9749340139e9b3e658ef0636e402b783318e551e376296825e3115b961c3db1e623114f685b8c32422f092811b9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013536f9f4d7916e6fb9ea555c3f47bebc36df4e46a34ebb27c62f3eccc33a8a426853e22158d2a1d6057a2fdf207b6a30000000000000000000000000000000003171982f0dada0f6bce712d079a428c2956a4608892635057cf87f995c1641e9e04b9f48c06864e74020cc8456dca8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001968f7371301e0d5bd27da19b7b558bf8d599ccbbfa25d7c41a59ed3202717f135cab52fb37c52611ade4c7145662ad900000000000000000000000000000000053d4b2f1b36fb22f01fb812b0d37addaa1504089cd9985266d216adf9f269be1234598cb6adec72cb0a2babd2143a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f16a28e6abf79f88657f75392f98dec34620c5016713abe3199d9fa4eb3256eb74bb8a6bf79567985122d9b8eba698000000000000000000000000000000000e274ad2fe795b3e301a561432b5ddff85037fd8d8d32e96e8e5eed92a74898a95c115607f6043cbaa19a5b6949800411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a17771cb54e5775bbb61c02b6e5b4bb19bd0c55ca3ae0182ada7619b37b426bb3f1a30e8cb062b7fcba0424ab1ac6a0000000000000000000000000000000010056a77c0ccd3069f5320fcd1618297ebd45ccd132dbbe3813379c1ed2d51e8149af082bbee560e3df59497bfe1bb641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165508b6c7b1560929ce24e28764eb2de7d5c82bcb83706bb13b52fe637cd31ad9fc443b76362dc1bb071d5de6fb7f4a00000000000000000000000000000000109d6be605f2e257f42360f2f993a0d7625d292ef06b09c2b3a5cf1d8e94ae7aefe0566bf7f8116bc9b843bb8cafda6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195b2c0be0a515c3c8e7907ebb994c2e4cf4b835d083cff0b7f18316763ec05055602263b5811ff02d5f6f885fe425b000000000000000000000000000000000730c0c8ce4ddc9cca60626a4682f483f67b920369ceca5c27a8e9305c21e5abb5e75a2c001163702083a76d1e54aa671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b076051bf16186f01f51a7ade47aba844e5d8c32b0a2572d8004a23914fb60aa277ee0cb0afb253bfb2ecac89f77330000000000000000000000000000000006e5e82f6871b37f5d06d4f5ae1932603a79f118e77c2666682f79e4a0e79a1fd92047984a247f9634cc4d8d7af7e4b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018717324748f996c7da373bcb2b82dc85cd4fc0bfb2954645b1947cd0bda629a3a7d37882d543ceece0ee1a513d8c88d000000000000000000000000000000000eaaf23e343e0c4a02c5303ad2c89089fb465cf8eb782e44bf5b1bef338f91410db399510a30ca3efe628a048494cde21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058f96b9701cc411eba7ac4e5a3361f3fd7aa42c11d08c158b73be4e04aa83a3978e59c68dde2fe00f2a3381c4daf3b90000000000000000000000000000000007ae03634c7969c6ec0e6644efc62cee5915991d6b3a1160678baf00441c756cefd255c41f890b9546ad993eeaa530f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecb05561c0b37110186848008fbbc3accbed4c6016a749556118ea0df45e9c1cafb91f931b292cfef050ac3190b847000000000000000000000000000000000b62fc7d2e65268d1842b4fe28116b96040d2abbfae6c23a991321b30981326787f60e5f6cfc8a828fc498b7160791a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db432961a006ee2205233ce23a800e91e9fd118bee6ee79a7d1c96b3df8e6931690ed58342dc5f6ca971c6ccbefed46000000000000000000000000000000000e4a4e90d39200595e83ebfc75b62e941203684ca06d594262894baa24b83d1ae0b4a6f92854520d4cf0023005170f171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f14ef95cd019af7fe1ef7ce3a4efecffdd9fcc88ec5e50b1498a431f9287a078174bc60fc37ef1261adaee5c21c4bed0000000000000000000000000000000016fabf8a4bb076b7619588f328deda563402c0620727a8047f75aa57055433450f0c2e93956f837f6466a4fcb8e7b7441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014453d804fbfb2ac7c1c55e86dbd3423f814987bffdb6cdc84fd30703f12a1d19c53f0ff2019cd880caa7d6ecbcd0cb4000000000000000000000000000000001183f2ab16fe9eef4a4b70d8ed8974d1eb555ad61d524a3d5279a311e80bcf2c2c9aab8019365b2efd9a3cc3901b03d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ab0aa8e5ccae66fdf35dcfba4c4028d6e5b8af1799cb0150f53e128c368ef8da2212a56ea5286d6b06ef322ea26719000000000000000000000000000000001789e48cd3ad5c6f50257b649485f016f85c4c73ef8c4873656bd2a49306e1661ce349627b7ac615300b760bcbca04241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cae2bf1659d7dd9a384d75b3b650675f0ce2b213f375cf61f4455906fe2c4d7ddc6d6a84757ae5135f3c42dcbd1dd730000000000000000000000000000000006c5f4ba5a38077762b2a16cc997f47155979fcc07c29f4a6b56234b1f37a4b0d90ae6b83838af3ccd2679763c7c5f191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f8236407988ec1428b6395718aedd125cfe98ef37ebba89521eab8a598d682caac88a641209f4fdac9e883eaf6c27a0000000000000000000000000000000013d3c352c72c31d6de2cc469b4c5dfcb3e36e4969777944a4e1beb42a328b3560a8b3663ca7e99d9afcf83e1102910101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f63b952f9e60a765bdef50067bed6c1020c980c2afeb722a1385b424c5fc79f797ec0ca480da34ed2f04857e0d1b0000000000000000000000000000000000057938dee614b947d2d8af9846255644ed3bf70969b05f4e29b7f17c2d1050eb69dbdb9ee24ff1a79682cf567c5d2a431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f4b7331a961e3078c6974b28a49cb4956c44a9f366042fa9ea071acc3a8a14b28353837e4d89c986e5aadf2eb5ebfb00000000000000000000000000000000059752b5bddde7c3956b3f1f3d21319f08c38524963e738fc7f72fb0c84dfe3cb84b6d53d3ded9048d064adb6936f2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136a0cf9a571869fca267186eb347ab24cbd8a7fce5d14eb07a53b064d0c04dbb899f83049eeb03720d21a93b6cdf6d00000000000000000000000000000000001726d2ee5793b23db417963e64c80bd72c7cf8c1becf1c9fb155d2a4116b91466f572f61fc54bc6dda7a97d3d30c99f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cf9ee32d0e9cba8266753fbf374a317d5009731bd390e5a31f9f3e32fce8dc3f36cf9c08fecdf32ac55a87d72a50e40000000000000000000000000000000005c550515bff3bacacf6268558a9dd0045ff581087df755456c7b6b3d3e0593717573fb2c9859268f0aafe5cf825e1401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000490401f13da73dc5e73b500349ad5251832ab2c132ac46dfbda72e649d17eb90ec8e506b66c8759e3d4a59b0c8f6d3d00000000000000000000000000000000127c82eadb70618bd9725156e7ef9472f230f981922b40fb9841822368b4cf10c8f750268c8a13a8f3eb489bc895d8101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f6b83157c648209d8c57cda768271b21994300461a609607e2bf71585539bdea34bd89cfdcc391b1cbd1ed027a6628000000000000000000000000000000000edc14ec7bc059170164779d6371ce7fcfd833e3fa0e5b1ff7bbb55b7dda893bcf946c33bab3a3b0af1f48df3aea68511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000090b0cf059f9087e247cc990c75d85d6e90bb554c9123907c5461c85ede897b0d2819ebb11672f205175eda4d2d96bd0000000000000000000000000000000008403c18c972de72396a9c297fee41c195d74ad51f7e3e409de564ae245c80393d49a9ceaed14b08a57259be06e7c4331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6b6a9c392d19b59998facac5cc6c69f9b99111559af43078e113da6d6ff80e086de98bc61e0d1a71833802f065e1d000000000000000000000000000000001995e63570cdfd9091588b742ed7aaf6ac574907d58037f8db0c9db59eadbd9bfbb2069e1b957eaff7fe79d8845725931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046bbe94965d4b5e111368529757ba0dacef4570de9777e17cd3846322f556156e170db64568fe8602cd14f660079b1e0000000000000000000000000000000010d92d67917506b90f3d27e9c242855cc5b3341bd2e6b57014f939df8f63fe02731f540fdccc954c3350bb774a2f8a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fd18d851767afacb5430f921f39d72c7638992bb50ae95d2670e17cfb9e931ec527b49396b36502bbaf2a00034dfed0000000000000000000000000000000014e384562dbc2ef409c09094caf23d88803f9c13074f747c2256277b545a3891eda292f2866fd5e7f8056468dd7857a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b5e84a6a9ef0de15551123436bfda5000460117b9148bcca5ed719096cb10b81bf6b310be90cc3cd7c0a22bdea59a60000000000000000000000000000000013771b0b4ec65d56a912fd855ae2cad38dd344b8ecd6003ca0a21daca4485c93be32258cb482bf97519a8dca5cd997591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001256b7bbfc139f1e0df1153eba6e15d22bc9dd1a95959b409c36bf1112956499f628c13aadbad454c3333356b90adeb800000000000000000000000000000000055ab42ed7b05843114f22af1b6419bbe85d19213050fe1030c28944c19c8aa9d0b0dcee323fa0fc529c5b066f9be42a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170ebe6e34b6b8609fa8119c327b002445999865006a1f8108d11ba4faf49e1c28f214bc5b44311553f01ddb92120d9f0000000000000000000000000000000014e3cc6fe5f50c328706d3981ea483978d102a25bb4654816d972175a640fa20fb45f86e784a598ff746f64032d6985a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a189c1f374024ef70c64e3ea708a6080a82917e518be522c92cf7798de8569cd775c0b5de2810864cab8443f5ccfcf6000000000000000000000000000000000424bc1c9acdb55fb48ccbd9ee42f0ed6e9509ae8d07f028e444e52f3fc4fa6d9eda23dfd5dde256fe63d66da51310c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001444fedd7a4851bcb86594cf66449f5c10851422c409baef41542fa10196fa36519424bb3484d6ee4798bee8ef47d4c2000000000000000000000000000000000ab559465b0a9a263e3946222fac471c257b6394082b978b5ee9a0357602aa51a63d4c107cfbb2ccdef872115e6739941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b9a331f3e22c702d0f626472e1b6eb92382d26e2b115f2e5dcef89994a721ad05eea962e880442d9033907160d168e000000000000000000000000000000000af1e3206c787c35035689f0dc6051482831bef48429d4aa5ecb56c30da75f05d2b22edc59d4bacb20117a8852a552341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029efbd7a80138e7ffd86248a6b07214ba4c8bf289d0006d8ef9f8c4ed5838263d189dfe09d71efc9a77eff4ce84ce2b0000000000000000000000000000000004c75b773eab13527323b31c485396d7206ee7ef76524b81ad348279258329cb275842ff41d25da8d07f82eb72ae55eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002388d889ef1f0ce358062dae8295db3f5932234521e89ed99b01a4431b3b87959f711a6d7e879f8b121e23a9385b2440000000000000000000000000000000001fb2912ad78d9523895b6099631e3312b54f272f9defc116225fc8e3f4a23dc2e330230202775dd0710d6d54cfcd3d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b6bced2e14a33801f48c41f9c60cd7ec76816efea0aad0496fbfd40966ca8d2df45d4b30271b03b290448c9ebd62140000000000000000000000000000000017cbd8abbf1f17d869917252b88dfaff433c36740a97b53d85a74d043c7dd333f8e34445a76d83bf30fe5664f00bc8791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000412d88f8114e4d499c408513965cf851f1bb278e4d1517a93cd7b16aacc7eb3255de9561a9e443d9bdb23753290ed670000000000000000000000000000000000defc87f2648ed0463a5333c57d412001aa7ace114779347afa4095078c1743934626bde7393716b1968f4936f9e5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079b7e119a2716def435e100871130cb999252ae47e0ec5ea3b39399a22eab06959da516cf054cbe8e12ecb6217b6089000000000000000000000000000000001956c25151c851a61836764366e68a8a94b19b2756de31e088b1e1aee7baec41bba223d61ea08b9fde3ac5968f9435971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001667e291c7085f4f5305960f20ba1aab9f4293d6df23f069b0958c5166e4adbc29df7f775d1c7c3d785b739622fefdc5000000000000000000000000000000000617bd1af62f2cd28aeefe60d4f0b0635a6c604aa67b4adcbb962e61d808c788f47f4777b971b3289f72083935756a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082206aed81e0a71ec263146c81ee7919fa0749a6279723e891a2c15ef1d2db8e99f51126ae7236f177dd40f4ad81cbd0000000000000000000000000000000006893001c309bc017c468d6b40632bd039c58d99016fbf6cc8c93f2d04ff7c7c771f722a9b937d655999fbda05a23abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed7f0c4d58dbdafffb3d710491a20e71d2ff5a73a88278f038026818986c6754d6cbe862e0a0cca21f574661bc24af00000000000000000000000000000000096756952fcd30a77058f37dad6e80ab6427baad2e82bfcf647cd07cb5a1216e3544451ebd49c63c5da64bebdfe797b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb5528e305af44841ad78e9e3005f65daf7c8b4301650a2315bc81abe9d603b518ed77d8c0f3047295213aefda72130000000000000000000000000000000012d3738f4a4bb366ac7b81b4127e76eea4b60ea7e94d708aa8be2a02bcaec678197689f500e43f9301eed2c7099497481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f71c567f0e75eda67b76627b57de16da316423dd76825960019ea8dcef44ea4a6ffa8c349bc56ef4bd229f7f09415400000000000000000000000000000000072dfb67eab9147f33f69981e70f0f755696279972a2f220dab2d03b9d20f7badf428156abb2d624cb56fa6531aaca6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036a5f85050a4c19ec8e571ae4ce1f4c7a85687db6263d867d012760194c85903cbf4c921378f91e52f7895c97fa2d5000000000000000000000000000000000a9fc6002d73ba10eee503066a57f21fb1129bbb2786c55e2cbf22a282a0716c61155b794ab85e2cfb9ec43cb3798ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f4a425c5dd7d7c417602850d8696a1b6b93650a1045c6599bdb42fdfb5a36bd6fa8bee427bb698ce0392b56ab01260000000000000000000000000000000007b8e459a68895739cda3d1064b2be478f620f8cec83be70d72ae7a09387aad280d063b63bb0975f93e9534ae285981d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a4811d1529c290f23d306c204d9a1551b1c82996ea6bba9e4abe12b77649eabea6a671abcda6e45b8143f6ff9966d20000000000000000000000000000000012b98219286ef575ffd53b8a30c2e126ba7cf98d59df2801ad8d9522aaf8621b02a4a97e2a296cb9bf4aad2588a75eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2ad4aa6e75762b2a63ff4828ee99af1fe7556e7451a831ffaf08c58f07de7781015cd4d61776863de01f89e3c7521a00000000000000000000000000000000047ac48835ef62151e9398bea0fbe7c895f798cc03f6988c2242d1f4fc1ebb5c670afc76ae43c8b201a6f473f03bac981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002414cb45041d2dc3bc3ee62d6895baf05c4df98193be13a7a7f60450049cc39f9c5f5a816f78b7419726498ad43d1fb0000000000000000000000000000000010f2a5c1e0f523af84227634aef8afa6c3757c9de52046cbb511ef5c4b218b06d25e662f821513fec64396bafe2a06971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014427895a5b87a359d278298c58b00e57ae2665bd1d34adf52f8fd323779371081c105e67e66df497bb535ec77abaad9000000000000000000000000000000000386f074e0f6b0d7c3e3f5eb751316bcea4a17142f89c17ebc7e5fafeaa8be3724dd7c792330c041a0b700bf21e472d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001187afff5c060b5bdf044fbce8659be0db6f10adf35f6fab4576e4d17d1c49cee17f338e34bbbf88ffae73a1263a70a00000000000000000000000000000000032f2fc39fb5c3995d27b991934396145a2410889964aa700491ba6e5181c7f621fbe3a8a0b11304d281cf5527ccac6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038ccef5a2e4b7630bbae3625eb9cd99db637aaf48d5232f6c5e8b7ee9b49f994167454398d0c63daf8f7978631e0dec0000000000000000000000000000000010d3b8b17a6f64237ca23d1ba360e40aee80f0f7284ca1322b19dff466eaf47e73b0c2d099cd90b420a480d1d8a0fb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016819bb869d96d0c0d919155bea40ba6bff378c6ff49f108ee89426b4087a9ffd8c4210cd5624c52d5ba112a2c52a0df000000000000000000000000000000000cd01bb76c7a572437ac4f2c43bdc6a2abd512bfdc0949f3221a673a731e232bd6fd50e94dc2a8c1f65ba94ff091eff31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071d16f494cca29df2deb5fb1de585b701741b102d70478990f2c9dbbe44d899986200bad1a97528894bfb63738567e70000000000000000000000000000000002e9495f8729db545bda1a2b44e18c78aba1c5c29d10785f27dc853a234bcd2335d92577731bf73658a0490f7ea2c5fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153d6c0168f1d9581275a470b4be0ef3a69cd85a6acdb3b72479697f47e9351a90e0f7e91dabbb2a361bb01e2b3541810000000000000000000000000000000004926ed58cc1693485517e23c6fbd45548df27736f57c6a6a40026b7bdd557f8d2dfc4ec1c17a1f472d7b4f3f2da54171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6ccfff9087dad4892b1881f0cd76ecbd9510a32ecf12ed6d51f1520af7a6ec37f78004ab5c334550f6a262c5e401800000000000000000000000000000000167cc603de8b7892fbd80d49450b740c29722084ea455f0a7ef041913438afdac48eb275c5cdf0830bf9005d00ac32351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7b23ecf9de352ef23d66171f813104897a7c5ec5f736565311741d25f77dd318d20ead294791f812f2c48b2a9febb00000000000000000000000000000000171e04537c1833e5f31812adcb23e62b0ccf2eb61f2ce391fd7d5192e80f93dac78cde29d483ba5300516d4084dca83e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb84a074cb9f11b40013ade413680802d08cc4d5e58a3eb14937c8105fbf110bd229dfb3b335e981ceb57cc2572133500000000000000000000000000000000115239b2372b2a34997d7d216241dd4d639f1ae57a61ba8eb32d808efbd615b8c43008e54fe9ffb513baa831a27a4f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001962ef21af82f8cd4f6bc6de3bf61e79c3d05c38a126dc61fea5cb1ab5745743871819529ae59990ea051259973e7c45000000000000000000000000000000000c772de569e55429f955730ca6beb2009a0fc65ae6e4eb8a6ce4d15775cbcced19d81cb1f8076eb7fe946e649fdbf84b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba2e2c4b28d6fe3061eeb5cd89df8624353f8c62cad5f8cd015cd95ddd86a2d6a9ce13077657ffc9597cde565f150f600000000000000000000000000000000022697ee91b6e54a2e80147b8e85649ef17c17e4b9df1302a76ad0cd767f36353f40a176a59d237ceb7972736435ac5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d591963945e5d73ee5fe37cd2da52695858283ef1df7a05867ddbab6519c47d8da17c92b6db3ab8059d6f94a3ff789000000000000000000000000000000000ba23783ba1db7f7571c7c0b039cfc218bafb9a6ea2de2676cbd9f06dc4c2dbe828ad3eed8c6532b8846684e77a340091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a793c34459307d018d4e6d0fc3d6a84fc306a170b039dce4f31df709e51cbd23a01a45c37229ddfbd848bd32288da1c000000000000000000000000000000001432e19b43b130c2bcae3a7ecbe0a1ee8deac081ef43785f24491b36b7b0b43eccbe35e0fbb64c2e624d028260d2cc771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000226d95b0080b5393ce69055e344fdf1bce9326d3d0abbf132d6c2bc8176f752a9d3ed44669b2c5d3eeb539854864875000000000000000000000000000000001311213bb526e9efe3e8c04811e4b2712e4a6525a176737401b0f9b23ad75cd523ce57f2cf544413567fc207998b53e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a99fb521926922d98ca0521b606f50367a7175735e1c842d8064bca6fd351de5421bbe8f73b15bd56ab8459f9f4d56000000000000000000000000000000000cdc1cea7f728aa712b6817a82a230590bc53c6a38a685790512ac4b452d080d8d93a8ee9b1db3c94e9156ee2e172cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011873f043f42c2e96657766688001de8bab46421033ddefb6e1539ba72024ec28295b37611f04ae848a89f3a3a093d08000000000000000000000000000000000c47d461aad37a7213e4106f136f1280995b56343eab58f62fd45510ac35a2333a97829474ecdfc0852a03fd1b9884bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd5ea04c9307c9e10bb61d7f3540757930238c7605661ad0b0894a6686b465b4dc02006d9cbe990b5867a752574c0b0000000000000000000000000000000012fdbb1383d29e9b7668cde6ae6e5674066245497019f07869790633f7707771fac2f615e51b07ac68c95aadd4a8218e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027147b01d53738af34aa3dd3314841c35d35a11d90bd8fa84121172d3f7728017bfec909c31f68b4c4f24f2c29324aa000000000000000000000000000000000a2d2f8f868c0dd6f70a7b0dfaf3e1de13eb4a7a41eef9067b0eccbd4e27c3b65f36435da3d9a4d72be91cab03a645e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726222813603f2a2fe7e4ecbfe1fa015a27025334c759b483d482d5572e137f75f819e29e86edd186fdad37f04e66d00000000000000000000000000000000015d75a5c537761d4f11fd5d231c555f6acbc1da24213c14c4d400748a0c8c3a6a002bdc94fb9f2238f6b70b8451304eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013140f8d0a64463828e8dd9dbd967ef38e5212ec9884fb3c196222ec962e0d53a961e35de2a05c327e0df33d9d7ad280000000000000000000000000000000001884820a4496d9ab0ba7fd6156daa99b864cb06e8f5ae3fceb2327bd6214c0019021bb68db557405e854a0e953ad97571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf0098f1a0f8ce55e4957851636c526e3282559ad9b14c62da94a637b33f9a84267bbe2f0222d988d83457e4426fc120000000000000000000000000000000017f9cea8edfdfc46ec9d6e701aa9278b0ccf5c4224eadb58cf7828f8d717e4efd7f67f1ba7d93ff410d8bb948b20837e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7bcc69e4291a8535ef99645260425dc3d22c793063a5d227dfa4c627cb71ee4792a072f6757babb9fd9eb99c42cabb0000000000000000000000000000000011e7bdb631bc280f6424fca344a5b91081996b88ac9b3c6d6a06749da370244be698aa137debe419ed6bec125b1a6a481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033bd57061984faeb50bcfba33e49855addfa9dee04497e7ff6b2c733b081590aa4f5a05d684aee591265fec24c8d7100000000000000000000000000000000009af6ac5c732402831c8b319fb20bbf59ed83ca7f8770e5bf2dfbeee9431aba0ffc079a6b30e9e4c89894de8e13b62031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001230473aad671d7a062fd993c311ff3d16725ffea4238de73c40da753e62ceade23b6d12ef8898c3ebfce050d2d964b40000000000000000000000000000000013a537a1591bd440e178a753330c0e330b6a79d2202b7dad02c5a78ecbf0a8a891c0553aa6c80236e67ad4e0a47c5dfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001314b1fa89fc3b01b4f23b9d72493667489e508b218b3fe75b4a00c8f2564d8a6d6c05bbe3ead439f1e312d014765141000000000000000000000000000000000601132bf5058cfe88131628fd28321c5c8ce72b5e5ae2696c55a391c1bacf4f885a15261e83fe7b4a834ae9d2731d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc8650e6b1e2bb7b44b2d7607d101fe9b2ed0f3e8f26a972b6fbac77ffecb8e96ce9082618bf75fd5d977a47f79b010000000000000000000000000000000011fe7474810e706df57f40d6d976e9ae14532c8e9780474c2874725e741a9422674c0d54ceff8e96aa2dbbdcb0f029551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e940a6c8cc619f868234fd74874cd5b181221a8bd282e2ab0f690d3b00a66ab536f8067499fcd53b0e0327782f18ad00000000000000000000000000000000021d872da387c2e57a416c2afce59a5d81677a8951fa60be8d1236fd88f697ae2783e6fc02f4ea2f4f16035dfff249071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be35e271696e4037ef82226e26f561512caa6b8b7bcbb1a0536c8af81bd9526d8d74d1319ac3bf340886b1f6b0e163a00000000000000000000000000000000102bb876f49c76a3737ac243b877dca91f0840e72b9ff510f3245bbdfdfcff66c3d9adc47519ea9db725b56e609b39631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036b4eab67c87e49356842a48989dd37afcc1299e92ad181efb67f754cf4fe389fcb017ccc53e0a2fbe7c94666a21ad900000000000000000000000000000000163f4ff13243987c9ce4670c30a1e8f50ab0325539375d232f1f603b46d4520822e7b6893d85a50a9e54e6cd6ae807641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000438ceca6356c37c66d7ed674e474e65fa4f2efba2c4d392b5f1182dd9f4970cfe3f2bfd9c78dccf6d739151419dbdf8000000000000000000000000000000000f7d97a52e5cd9c4955db7e2561d562ea1dbb117f434f6ea3f6e2cc713d5354327966e32fe43d505733ce75905f6f2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120b69653d0057394c5f1542ded11ecad31eccdf97fe5a7dee4d31b007028161a5f00352d681c0670a09909cf8776f8f000000000000000000000000000000000bbc61a17568f94e7f4c2e6dee51514d44a1092777ea9a71c17cdd176ef542da9f13f3ab210df2d67e09c192036bd64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa09b166a384d3bff7c93c7f47278a78301378d6d0574984b7e2b0b02ce3820022954f404c8781632adeed814acd32000000000000000000000000000000000213b863d962c23997b1387e8d3761c04dd4d19c5b08da0c554d563079003f004f5eedba0e2572ef3604c7afaf3fed5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001180158b411b3ddb466c0ad94c9ebdeb490f91bc393b69d2db9652381817212083d045fb7ea280c8b940bf392429865d000000000000000000000000000000001610c5c6535fdfc58ad51f3bc63d4a2dc5f1f51cc836696230aa4f2d31acd1f5f6c592e18b5058db82a77325fc16092c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001378ed1a1318435462086e814f68717e724d6bf1d235cfe00fa0b6a1f694da983b9ee7b4bf235cd417975786969d8b0c000000000000000000000000000000000f76389aa8baf6be42f247da78eeb87fce48b98499b8d0d44735b1652a9f3552c2fb2e2d611a7758fe6fb87f4964de791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025e60c67e01f501c9a45c07372f228940a62fce3e30d0e39d2e6791b2b6c86c35fccc98067d4f51211eddf29be8a8270000000000000000000000000000000001bd0f4476cbbc14316f3fcdea81b88178044ef5f9a339a91d7c20def236d14422dd576a221980b49793389542fd23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd29d1b8dc0e1c66acd1fdbe6c3c37262fd596c237ba06b9235f92fe3df42fd8334affec03ab059c8bbdf84e387e6240000000000000000000000000000000013e84002e508289b820af2dd6611131bf8a59ff593cb87ed6c042f77b07acd13e3b09fcb2416a24c182f04d49e0776631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bffca8168829485b52e76d8155396d728a958a92d071ffd1ee3c801a0f69520df8ea596da544f617cf76ed2afa64bf6000000000000000000000000000000000f46926586ab6264664800babcb53f5920afbdc9249810d04c122755797654faf332c65b797ae62fb0589320422f07dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158540e90ac612b363125b6bfeb782a6f7721870db25617c6dc797cbe75aeb8239d54c06b0072e3a6366465235668fbe000000000000000000000000000000000aa9878eb1a6374cb5cf4eff2f6fd89460aef2b6a6eb906e807242cb39926c4d47a6071793d7f06916c59d3856aa337e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187038b45b079a2c342175eb833b3f56e35e3155291313acdbddfa5c9d8fc9c7451bb5e1094001954958617e99db726f000000000000000000000000000000001334c6debc42aa7b4ad075584076e57515f3624a761b2438e76c52063a3d7ceb6b28c38ffdd1d577a6943048a4a58f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000079ff426ff17d6e4dd32f831334f9dcf129abe77f38eeb81e9c3bdc06624bd31aba4f11335097a5857d5d2a7d8c93040000000000000000000000000000000015087ac80bebe5b873a6b49f3e271cf733f8f8d9ed9a5303020c65b5fdf8d28401beb5a34270a6ead70ab5e58b0b6b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b19f820114aff1e91b49e587c851057c41a2df584e1330ce404852ff738784563206c6d8dcdfcaad9485f82d06e3d000000000000000000000000000000000d53f0dcde9d193f0c84f3fc0c7d093a58796bde168f223a38cd1b5e8ba3c30b07e77a741f1182eb403e35b14819465b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164ac813cc3b45b64390cdb09b68e7d79f0ed6b6ac2056b604449d1874ef6780944cfedcec6d9c274006cbdab414af5e0000000000000000000000000000000014f96f88e580df705ece706d43a8b98bb89eab33443f5e98cfb1bc3bc3955c837ab9afe26f530673ba033c8ccfea9e4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b74171ff9d8a494ff1680b77587aa7f5edd8fd4346762c1bb14f163767b1cea9cda885f20dce0aa07f59b82259f855000000000000000000000000000000000bf0aa17635224a1e47e4aa5a21f49b46c268f5c0582b94a66b189ff399af7503a45831de71f120e0f3f0979f1b351a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3359f0c58ea8dccce0f0793a04456a2089552ee83380ba160b354ea96682596f787f5991d5cb8c63a1aad724fbe36000000000000000000000000000000000147b7d7e84cfaf9ac3d79f64a8926e8eb6228e760c979dd79517430a44aed8c622a8cb367f056fae572338b9f4947d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000406ccfaba58f5b19b3ab6696ebc36de407dc7fa84e0000a78ae53e8884394aea252776f5e78826f7ae446ad37fc2717000000000000000000000000000000000a8c058acbe8deeafb4a1e7f046cf02147c73fa1155745b7d41f41631fcf166c6d1bd819bb29fe1ccf38a154712b1a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000382639b79f0f04f653ba5e98803bcc79feab89724cd8473a3c99dbdab70929177ae836a8379cbc29b0805d744b3a5bf000000000000000000000000000000000a575522682cde8fafd74d6be77d79474269b10c2eca89f9808ca312b57850fa55fc2637030a44e87b1d2e56f048e80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b53f24c20bdd9b084f71d8077a603795d6bb4d85b3ede29b06012b5519605fb96fe995c7d8767c7ca4c9022abf4c00000000000000000000000000000000014f99b1dc9f9cb40304570bf16153dbaa944dfc95e13d597d7b7ed5e3565fdbdbfc9fab694e8dd3a8f49468c8f34b6d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dda86643d21d2cc1ffb3ae47bb68ac48d5799f6d23f9a99ca094cecef98dab0fe64cc118aea3b4588aa7093a79e1c2100000000000000000000000000000000020a08c9fcd09eff76c368682afefba154978faf68ba73414e50a83a9e6a76d2c425d044df241aba30ee8af49a812ae51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164992abc7b798aa8bc219225c8f2ea32cacd2f759d352674538852a79fce87262ae58fa4805ac19bd0cc24fc40e7fef000000000000000000000000000000000dc6680540fe41815cfb5c186e4252bdc18d9347a0c0bb4443014d1f0dd728f733679a1be68337c91abf7a11af0fb99a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191747f7588e2fc4179f35f8c273934bbcd29c370300c18e1f352e3249e7d79dd2694d5f874dcb9235274c2987240ab5000000000000000000000000000000000d92b72e8d02eccb193f9308fe31d7984c8eefdd91d53f89166c668fd1517a70d91db1d25dd20af1630e04fda4ab159c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000727b94700431b1f54c34dd666e1142f40ab4693e7f57d240603c45137bba0b5efabef4d1fc436b06b0ca0bfd533e7c7000000000000000000000000000000000581cf87bfc4890a301a7d06e92c93c60405dfc1c5b1cdd9070f08e4d0f0e4cd1130edb9a8201bea22e54f6d029675461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001477ddaad1ecbcd9a067eeac5687d609af1968c2faaeabb73fe0326c4b0a1fb9770850027f0a32578c78ce7cf3be434e000000000000000000000000000000000b552a04af6233ced891223cdba7d980cce5162c0b9e2f62a227a3e2ce6ed3fccc2825e1b3b8ca0ef6eb6a7063cbfec41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013370c81c296ab212588634066b146ead2e0f870a125761164de1fd6ebfe70a9807746a9837b98ca0e5a026335fe011d00000000000000000000000000000000132d48237ab432e50929e256346c3264c2c45c4f3e0fc4ba67edab3e427825ccad596d139224284dc0429e35540352061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004969220e2d09bf662840766239258a3fc4e6312fb4692b8a14ed915df4d9e781018309ae963cafe73aac26e269207410000000000000000000000000000000006532a4ef6fcd40ae6fb195ba32053ff9404a500c4a236eaa90c99ef0e0c4a8e44b6fd6c7a098964428f4df19296d6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070c14e36980c29d9012bd6c4051238245303d23351bbe58c531bcc179a29d9e5a8c26f5453b06f905000d5634052fa6000000000000000000000000000000000e70bd62e47181addf1313d7e8073e7cc93070088ed87389e2764810ad8c5ce9801ec01586cbed7739fa2f94b8bafe3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f83368f3887e86accbec036c8bc269928ec0ce71be6937d5c675b95680eaf8a6e58215fa710a4d1253002e29fa3a340000000000000000000000000000000003004306feb3618fda39e38fd75f67d7f1054cd9afbf38a3f0dcd5c39ba1763aad7ca62511610034983ca1979729fe291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167f47dcef982f27d1f48140568d149add2a06b1ef4592979a5877e52fc0b2ebf58042d910fb16312a1d213bf731e8ef0000000000000000000000000000000001b821152424d5e69383fdcdd4370e11a2135258cb6497053460c12de4086715a013123cd23e90ea7e719fbad1da50091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001598b6c1d9693c4e538075a645b3d84dfbedcb5093a2a2627ee7d652a204487140adad7c04f6a85254e95bc27a07070f000000000000000000000000000000000b7348ee14a6884e0e3c7a0091024eb92814b711688ee0845659e208cd183c3dafa43c3b05d82ef811c3addcc505a1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b594515da045e65a39089cd9bd75867a6aabd2cce4f6ee92f85b76fd9531c4b7fa4e0f9a3ccdf9fe0131d2164519f0000000000000000000000000000000014f88496072c189ca01fd83ba718a4c905e659abb3396505b79162ebb14d04ab2d8b8f5b9fbeb25f78e99a34b80e2e861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f845192fcec8256df2a289fbcc35f77d920b67085edd37311e7444a362af051ac7578e2b2d2146aed3c209ede46aec0000000000000000000000000000000000b1304c3fdbcba42f9ebcbb624a2ecae13a98882a45ea86a3f18bb42f4d5d8fdd78dd445013574ac12a8245bab31e811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001022cb8522b20732f3206bd5e3c8ccfb60c5f6d4ae2eef93d7968f361818ed7a519c0e691c8fc75e3b69a3375bb2eca00000000000000000000000000000000014b9c960eb3ee6748c1be21c3519477b42d2da1a092214de50a9cc5d86a1013158373408dbec01d04c9954710a86bb351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042e16808a7febd2db26336ebaf19e05562ac9413855b2e751d04ec954de02c1f0daa3d5dd2e1425b1754dddcd115f1d0000000000000000000000000000000011cab26d5082eaf641d69985d488e930dbc73e0e55e03eac71b458f2a9f0e74782cae4a6fabc62ac7dff120f4e67cc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067e27847598b00251feb02188087dc402a23fc6e69de155ede4ec15257377ab26685e498ad5d7990bfc1f6e83facdec000000000000000000000000000000000b9e8b48785ee96723a07fb91e70e545e3d9797d3b8f30821bb3217e8a155db6b5d47024ce1f3d1593cc54fef8811b171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025301f0180aee7159b3f2b8c4e87ece03337f00a8fa06c092112c46f3e8d5fd2902fb13ee1f3fd23cbe4bde4dcc6470000000000000000000000000000000000a94c030055c550b224ceec91c883483adaf67eda82ee3fe82914632d1873b969db60452288edff0ad9d586074ab137d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001133dbdd74995fe59c85976db507df2d78fe70e9c2c0465c9689e013ebf02fb71d29afca0e17cd6b28baa895c92e8e3200000000000000000000000000000000112d1cf1cf5a5a11787f12bea68f8d9e04986f67eb045992b5f302146801422d060f1d06e4436bd236b0df68b1d4312d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002539a66795a02e13a711bc58de141600e36477d7c86fef67dc7b120f0808ea6983b457f955114a951ef4f4727a42b5c0000000000000000000000000000000019e3db6e8903b94eb9d016d2604cd590f1ce2ff618ee28bf273a48212c35ed78edf1d9e8b98f25ab385070740317cd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017126c96e747f3b8736d96491a1434a73b11e563163fb76c42c77205bdc3485060da531b2cd9bc412e51255c4ff7d94f0000000000000000000000000000000010e33f3f68f9a95d257029798968136eee52502413827fc6beebae0551562ba1d0b0569732b07636d3c5f98863fc7b2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a6de613af4c9ef26ee55ddf9c217fdbbdcd25956d0fea91c485cc7942f93b7bb8b2551f52c04ff139404c125a6940b00000000000000000000000000000000112c9880614c3ccd84ff7ed60eaaf15c9d1743d869d0186c687ef3d3bfa91cb92c08347aaa79f50580b94e593fb062a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000860da09771df210b36c60f0a0f5bfe01ac7cf0834458fbb672e737ddc8979085d7616c1db347f1cdbd5b6b1128968750000000000000000000000000000000010b78112913366a3aa225ae1ace9f6e323d2eb63be1df8f3394fee9aa883772b28765c6e8420524d457b00835c63b8421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f86a8054120b0e8fbe9ae39eb6ae8db7ded10e1f440d726ccdc26cf2f275e6d145fb83133d726f3699c74bd616c02d000000000000000000000000000000000ff8ad9d3bee0484b128145953a79c6b8c6bf5d493f93acae34914ec373970ca3dcaaefb32183e746ed7ece4b21b345f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074fbc7a0cfbfdaabce6c54ff7d757d2399867aff98b74c0a8b8d0e903f7ee580d512c78274fe3f020e9a83cf83795580000000000000000000000000000000013de902931d058dbba2bfe75b67565f7feb8a8aa854bbfee4e128363f4f7438d06e17402a71ee7a318c47f1cabe9a8881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001756ae5b63a7171f19603008feabbbc5e13a4e7226ddbab0bdf532b08f8a1a444080333d0b2721921aa3b2a6c26f3623000000000000000000000000000000000c1926d2cebac3d2e1f07b35425025d83a8380712c0f4bc6f66cb2f5e0c05be2bf6c59fd81576548a832c7bab4b694711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcc53bd6c2cdc3c3749194850b115098e521439b2542d8ed5008dff0bb65e19484fc132488cd2c2a6a3aaa3403952c0000000000000000000000000000000015a238963b95e85ac0598f07bb5820e2f85caec8afedf6c871388e1e88eef802a79c893617ba595a3a383605b7978cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e49bb242cef9aa4c5a771c7630aa236a0ae567039ddb42822f707382b0cc25d5b5ce849c2b71b4d0d681d3a1a2a3360000000000000000000000000000000004168201da90fec8fb7cd0291f58c77f099a0074922f3a22ad5a0935d005bd14cbc6ec8bb4f7cc5d648ded2ac9b197f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003720b263599359968ffb1011bcdc7d19ffcfee11ed33a021c886c6b120f6b86d2a669a2cdb873cf901b2c4f8ae2ef8b000000000000000000000000000000000ef3a9d585909bbe18dce9ccc4c97993a39b7d6a9310459b87845667d533273d17b5fad9e790fbdad2f24f02d7237fb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e82e5a39fa806e156d224b2f10bf8943668c07407f6783965ee8e4410ee55846193a8b3206a8816cbb1f2abc3d5dee70000000000000000000000000000000016825c1a93be6d4b80e0a89da82a1cdf8c53a363a83d174c21d9094e37d3c51f286a3f7fe8b7a61c374ec8723a9a92a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e419fea158143e209fad39a025c1f092580901e0f8b3a697e40fd4bc413dc68133420fa5cf33855df3eb0f0b035e7f00000000000000000000000000000000187f77f8f10cb9a1a7f18af6d731193729656fab98d4255e3c9ca3756e211c20d5dacdf355ca0e2f6bbc7ec003a862f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001093fde9f71d50aa53f57121b3353cb862520f25e52481834efae55141ed97a19167b49daef0a8b94c5534283c7799f70000000000000000000000000000000015a316314b0227d2144f9eff60e7ee8c55a45d35d809ee7538793e6b1ffedc7036e657f0118a5f3ad27541c0d92f480e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5ed4f39bcb3bda471051fd252b422b7fe199ea7b3abdffe2c47d6a6c413d34a7c642e5ac43df66cd99b1176f809aac0000000000000000000000000000000017d288927597b27adee29e7529136171dc09dfcb3121ec828f41a344a949611cfc59b5b87ef1d15076506a89cb766e7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000023b9a77f7a8586bfd9073f16b49c7f03929bfe4484ee4fa535bbcb11b74894ffd7f39d69c9af6e52d880e97a079772000000000000000000000000000000000e2ccafb39fc1f663f3416972277acd1b9497bdd4c4ab280dc4585a0af628751a3c57a80a84a8738abeda8796b7916e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000844ebbe018df01f7b8651d3288db8feeccb24cf686c132685daa1576aba1f32dd6be19499fbdbc34fbc964b6478c0ac00000000000000000000000000000000139264eb6d110d97e1e18a928c9eb6bdc2de4578c52b77c232a92ba741bb454b8c62b2589ee6200b28b105bc0b9f0a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd4ab38a37f18dc22139059a1587380724e80650023eccaab109039ff2b33dc641aad816d1b2292a6bc63f01876dac1000000000000000000000000000000000b62ca4f8e4fac00afaabcd66a0b6655d4a5a9b9a400297e91487365013c807796cf0af5927ba761b3aca3b7b64594591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e991eda400b18f91ed05cfb26101cb5b4c2f890386a84c8376ff83e29f8c9896ff8cb07f2e29484044841887d4daac000000000000000000000000000000000525a917051b32db4ae3b037a928f9a83e4a9981f76d7213bd232829e10b1069455b42e6eb5b2f1537f19207c294455b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000662a4e8106064ba11d9681895029deaad968842b756391b2a7d0ba744b7f2aeaf8209b7340bcd34eeff0277f1bce3920000000000000000000000000000000014590db213d9f23e444882e21def8e991fd8233e1f354b05019e4e63cd44d1587f04a5e0ed623570d0793c43c820e4461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077c160cea39b6ae8620e342bdd9bf60c30cdc17116c5cf75d6debc579aa0948e8bb4593a44a654c8cc010dac41ecf8e000000000000000000000000000000000a75c55524a6a9eb45a65d95ba69480a79c81904b99513cc0581886187dc206d633588fd1aec55fdf37315dacdb87d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee28a7b0b539deafb583aaf0047c8dc57cff3e41ca4e6a1a0287d029959232a72cfd5454f68e8595d7eba8d21abe23c000000000000000000000000000000000889777cf303f057d532de75bda3c9a481aa93de704e7639453e22b6c39d1f6c38f7f0c991eab15e5ba223aa9074c7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8909e3fb5333853f2a5157c22cc8b9efd95917d61bdfb8096b4f38b2ad23b61d92834f98416832a8845f12d330a13100000000000000000000000000000000140b29744a9a7fbad8ccea93fc320d1bde715ef48632803402ec34d5a60494b5b9972144c6a59e1a2dad563e61080afe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec61b70c9f0dfadabbbacd90a3cb7f5dc8c06bf0482f6c2919bef5c26bc789a74b5e2e69f5e07a05eb9c55a17a881100000000000000000000000000000000089bf178569f4d95b872a10d33489afae2de71f7c0b0c70039d0ef311fb87d644468ee271cf4e50c27890847b411794c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8703ceb2deb5d8a63003fc52eebc534d2e670a360123f5e2c9195ddfc7c13ffcf35646215711f51b43acd53879e51000000000000000000000000000000001894126efc9b0a888a43681c6bbb070b605d9bb9fd0910d5f92df227d8cefe0b7c613dc88704c0b8ed52a4b05370945d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003ef9b19a2425aaaf00202d9c1b1e49364b6e73a99e8b32992ebbf4586ba5962b3fb68154a8ac52b4c87159bcacf2890000000000000000000000000000000002c9300a843ee187897395a9265adf1432786c6f3ed6f0fc272eaa3a919fd503735b8a93009a080c916decfb00ec09441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b52c94b01b464c85750c7790b5be5dead57154b20fed1b36dd21e5e231fff38d848651e44be7d49c32b06c6cd6bb01b00000000000000000000000000000000138a05f0aff2595665ace929f6304ddff03dc801cb2d1074fc5f78932b0cebed39666d9fd9ecdd31a71e3c6d248352b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf9fb77fcb472b173507bd8f2f60d9815472a11f82b7c9e1c5dd62361477108c431bdd5f1e7a81e83e49824513f8c5f0000000000000000000000000000000007dfb87c54b8a22ea70ec543d5bb51bfc542bbe71a54adebdce1a1b3df869ad341dddcdecd2e8bfa51e301562ba289271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d6819d438924be9784dfdb0394bfa5ae022f07c3f81944719f07ec460c80d424c0cbb00da2fe94d6afb2453394816500000000000000000000000000000000143b79db18018a8d8b8beb23080929a6769610f24cd6280011178533b6fca277647c96e86f7e78db3f4f15173be072bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7cf4c43bfcec98224d6b5f9d4325eeb759d96aaf103be1be300968f4405bc39832a2c063cd36fde576b5d8f1b168730000000000000000000000000000000013e99712ec0b46e8f464ce0f08b15746e35efc0f642f21b07625c28a951bfb38ad802826709d27ef5f0d0907c465123c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076107e3b96ce90dac2e193046c08f0c5441995f7daa1652abc01cc2dd85cee1553c5b52f73e85ee74a56e93000051960000000000000000000000000000000003cd19e2df7ca79cd65dc0cff6a707578355fcbc0bcad44480dd58a290117132e14a4bfb662ffae9035d01ef7359c79f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010995422a8d80f906e4b7efc22c1aa012f6cd4bd6a4703ac038769c4691d69a4ae0ad1cfd15c0066a352b1b8ba04e5b60000000000000000000000000000000001725947dbffbeb57d0bb2c56d1311e64a38c8dcef8ea3a762d2543e18ccea6c7ac3b5d8baf3226bea7956c3f721c6881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a36e1c0b9210e2295bc1dc2c0918b058474f93ad772ef1635fd32c8f276a680a6dd61037859490d620110d7808e4b7300000000000000000000000000000000158cf44db63565bf98c8537dcb682dd5a96b8bd63a929398a7738632f08a33fe65501e172c7fbd9c567702002d04f9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000723c083b9c58107e0be9ad76479236d9c2f139e3780467b93defe79225399752ca30bc94e93b869ed6118709db1d17a000000000000000000000000000000000da89809c5d1e21972b0bd8bad2a7634b4c4e48ec2b927605df73443dee54f5f9b3f245f13915cbacd526cf310b9c3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000290a52a6dd7aa892dde93b69103c4245455a0d8bd225aba9c64297d13b220b1bb305ebe321516344b8f9b20aeef348c0000000000000000000000000000000015ddb3290dadb16912b25cc60714d5605ced00852d8abd257e6c07c3a1f4d22e6d077471ed3abf8ff739e944e1865de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6c220ea1ca282f6043e3a8f2f5c7b638044283e6afbd6ab2159aae284a4d37714bdeb76a4419a306b88d0d575a6cfa000000000000000000000000000000000393d24918be09ba33dc8b72c84d935e2d3b7d6533e55024a0c1ffe4feb51a866e1a8a8088d71d16db6f2d542cd07bba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016faf65fa08e50da2396cb718c079ff8d39ddcfb6f012ba594c96c9d2f5ee095502aae9be97d74b89eb6f8a23877e330000000000000000000000000000000000466802a9b01b3d54fae3f68b8580ed4f62ae040b378834ebc152a55be6ae8a018a389f11c8bb5c842362b313b6abe411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b968d05aadb9944b96f08cbb3a8075f45dfb9ec191a5087460c0b09ff0ada28da63e7b4a731ee6f77ae7b4025a503100000000000000000000000000000000017cebf15f390c72758e65809b80f55f06faddc12e3f0d1b371e4e08d6073cf3854a73a45c58a47778ec7613086ecf381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe5046727863f81bc5e35520c437f08ebe3d6979571eac03e5dead6a4e27fcbf5b0fbeb266c1c7a000b2105066e95180000000000000000000000000000000003b6d837f23e1fa6d84ac4f67705a6a1f9e139cc1a6ff3fe1a5e36212cd59ff617ff491683c633ded78e01fde4c0d84e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050831b3a735045877b83e407ad7eeb7c62ba2a5eeb40608531f1ddac41fed114c7346f5be478b1385bd9e96a374642200000000000000000000000000000000107cea6938c2f3f56ebd6c006aa5839a8ab1fcbce4b1db8ea77b228826c81e371aaaf4f9935bc0ff41896f31c1812c961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000282f4c11ae5e6ff5bd33d7857e1500c6226dd5b95041722bdd2fd51273262aa881a2c76652ddb06dfe94c58ee6ac873000000000000000000000000000000000d673a030b738687aea2c09e8b22a96008d86a3276c825299dab0d1e0ac8d89fed56adf6c014ea66ca5fb139c0b25c971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079920e9006385096c34c99fe4fc7cffc054abec7970208c97dfd4ab11ed383b14e0476af8ac62efe08688b10effdb84000000000000000000000000000000000e3bc1137795ae1550d9315e9882998d883f8394caf54663e380a6f63c58294a96ff4a635248c74eaf041cfc7248117e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e12396122f6d59f22dadc2c5a8f8b885db440757c5c98696453251ed60dde9284b66968faa36ad0edabeec7065756a0000000000000000000000000000000002fe37cecdc1d508fe2bfde3d62597887e21b12deb864908377b5e0d9d3e11aa969ad0d9e9bdeed34a05f7add4c294051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f84c6bcc60d0fd0fc34b9506e6350f0a7099188ce8be4be8c7830a16df628bf83c63553f3dda6d349c21b82be47aa50000000000000000000000000000000010b8656c56db06db1c0afb2cbaf9eab00d21d917135934ecbcdb0cfb572ac841060c189576e684c58fbc4b49dc8653241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a046a028afb690a6e1b5d9b308b0fbcbe58b1ad3c1092111eaa5152c78c77e6054ce3ed8402b5c482871c22e427003f0000000000000000000000000000000001be6dfdf60abf1efae7bf95fe57b17ebcecb2b95c495b120e4ccc8088bc115def10f752679e5fc30cf4252d53a6cb181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010950ee8b9cf6657a82916223d001bcb9a1ba17a9176eb40bc6b465ce32d5219025387eef51f8d0a28587d4d0775efd000000000000000000000000000000000a129a7e652d173e3e0de083ed7e0d589c7f1ceb7dc70d5e90df18baf69b2b4320567d195a99c288090128ef7804d5d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a1f90b7ce5c08e6e3782263687898291fa759a3db24bff38787b49a06344a322abe57cd5e0e631aaa9c321b27b76000000000000000000000000000000000131fa5b486679a4d205b937bc37ba7015a306708ba676d935defe536249d65350e360e19774551167c7145e01f8daa041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e63fb8caf70fe6364eaf3786c846c050ac2a64baf0c343244ae81ddda292e56e7b1aeaad002a555044885e9a742dd34000000000000000000000000000000000fa59d09eb7f4a7344dd75f46a706655a7ffe30be38f80331dd5b9395ea8d6ef22bae858a670f58f8c803e68fd9814511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e952d3890695cdc8b0d5a97bcb99abbe1090467e1c7ff8f75bdf92eb8e4a80e7d74b4f5253a9174ca087c862312a240000000000000000000000000000000019ee5dff6261602cb7063eceaf8201bd39358d16d9eea0a9f4900082907ed82bd82895ff6627ff475f7e8a31977efa801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d0b6a6813af916cd3fee44f4f77eb0ac8ef2100cf4d3e65d6822039c882e928b4972d2b89ac5d9cb5fee8e3193359d000000000000000000000000000000000c43ca171944a1f31bd9ad52dfe1a6a200a5dd1f420342fc46ac9bf27338804cf283ad0c6064e9bc893b4424a0fd0eb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b051b381b341f053129e955cbfb5ec05bfb4b3ac46547b8dd8aa5b04e4806afbbf2ae8fe3f42a847ce797aea44611850000000000000000000000000000000009d2b5935ac0ef09355642f7bfc9984256cc8a1d3f6937b0f52e3ac506d723ed0808dc2a453ce912b65cc5a6a5ec8c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000dad12c00f84ac04f85986f2e325b8bc297f79c48f77f40f202818fb81cacf1c0292c2ac5a0d4eb372bef21920e70f4000000000000000000000000000000000146bf3a19ba21d45b4ccd5ead95a0683f8d2ee6eb881a3b149c71f0dd0f4eead6dc6c01343cf4697bdbe28becd2a0661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f49c2300a84c38c9e213bceae9a00005932a25ead2d416f60cffa026dce3a6719716f61056a770fce0912f76d436c750000000000000000000000000000000007f909194b965910b441931405ba0db0b44fc71f56882fc2ec08dd01e292703a66d4fc282621ec15d1b5776ceddb55dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac302ac3b5d103308d9674987d6a3534a6ec2fa20f93387729ffe8a49f36b11e6042fe82e2b33b45b82a7be93506975000000000000000000000000000000001527a2c0921df212520f5268a60476ab1a1a57db0af3a10976948f2910b227dda427249a48ef92f83eacb84e61cdeaf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016166106f823e6f9622ac1decf57ff1d535d366db729835566f2167fb4bcc16ef3d6e59c7a34ac38ed8536dd8100259400000000000000000000000000000000078147154032e9ed0d52e933d83a7532b9ff33674960929008a85227e6ff20ce477053909320e5072a0eb728c425b2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b41afe1df5be62069bba2a71ef325424b0c5608d18ae425bdbd4186f15096ac1ac106deeacec866ef776852a62aece0000000000000000000000000000000017aac1b42b21c5e57dc8392d7e948a4c9a10be03595fb9e49d060b4253318bd9fda2761f3cdb314b61960810129563f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187c1abb8cb78b126c760f5f4445d7b4344899c6ba153ba94081dbe8286dbaf32218ccec0a8166937a51765df7ed98310000000000000000000000000000000015fe3724e2eb7ca7895f765def9c38f65c62faafd9d323ba9b1a6bed8121379ad9afa207c33211488863d5ca29ca9a101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050db936b15509f4b127e31c3f627a869940f51371a1974de56e68392fdea618e062f322b8e19126acdde8e1f59511960000000000000000000000000000000008da0a02adb849720dd6d4d13c2b4d665acfb0878df5df55cdb7ec8787d90c078bb8c0d893b1fabe96d7aa3812b2213d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f152adb4346ba3320fb73d263a1f9aced1dbe4b5ae357611c7a6cf3c73e1e06f91d5eb51d37d89c55f904937bac732f00000000000000000000000000000000029e8dc42ae1da7184e5ade15413dda58529fe98a7a1904dc087085c091aa68d77b9b509d594b6887414f8193c60cf2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b7f0918093c177fd90255566eedc349e857071ed24bbf6ce7d65b5f7fa292930f28d327581ea2afa2a91eec23240cc0000000000000000000000000000000018b5632b6f7cadbdabb56f6db9af5ae346e2c5e9495b0bbec0a0d43e7e28e04e1ac2e921198ec167c180858d86615dff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000517a79892072fd20927c10b69bd3a2444059fa7aaf3f14f0513468c2da088a49a28d417e6e38bf98ae78cd9b94f72500000000000000000000000000000000008761e6b67bebb6b572ed921b3c44aea507ccae47f4e099ba84852b540d265ab556c143d71e083e90e891107018e03661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d9e339b7bff9753ee58d49a779a1050a490acf7432b3a5cc3901ce603b33cb12f9ac73d91bd9664429fdc580c047d000000000000000000000000000000000508090147f48efced9188e980bdd386d43ceed9afa4607e6436df6ad885703ae02243c3887d9c2cdbcf9da09c5480301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f143047d610b02f7f1fb9b7e9ac9e62f0260a19991fe62f3c80825dd704fd35add86a88a07341c7a9145ef558a43770000000000000000000000000000000001362c7976f83b7b1886de38cb5c9c90bdbeda6b65d317b245ed71f7baa03a1e649eab4c2a72501c572215f3e26866e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123eeb802db0c2f446f29cffa2184e92623ba6bbacfddd8983d0da52c3e4a3f60e98c5c4cf93658930406b03a64a1f2d00000000000000000000000000000000075d46ae3ee0a0f2d94bd2c45800a24eed849e5d40ade62b09f2beace7ff7ec1431653cafe42882e9d475d2af4c855af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006ac508f53dfdf24481c15d7c1d89cbd9c9636b6508668f63defd69ae7d8e6a0305afa0f2a0caa6aad0a654541aac17000000000000000000000000000000000e18eedf3f776d73c5d667e8b37d770b385b6e432b793dfba920c43504d2ed09c04fc0736c8e927b85287650e6e015e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002126b9c214dd9542b15a7bdfce7f6a462c0ab8ddfaf0abfb8e730e7e57f955e0b06060096658b9c3119eb0bc68c738d0000000000000000000000000000000002419ca1b9cdb7a08d7de9032bb23312da7284992d54ec58bb8e8b1fbe7c70e6d33aeaa07e26b0a328e0e454bd75deb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f7a0fb3fe333a92b8ee37117e30ddb4a145c2ff58a3173494b5ea1e577ee3bcc8a54dfde20ba7ff3bd9514939b5428000000000000000000000000000000000fa720bccc05c2ab5f377cb70a20196ae3ccb1f611301b2f44b95d47db0ce0cf28bf669148300592c9798a44d1e72aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b38f0f576d43f07d79ad99a62457b169cbc8c235b47aeb7d0f8388fe995431ff2ef736782bc22b8bac00a09c38229950000000000000000000000000000000011a8382187a97492f5da1cff5fb145c859d6085db0e18aa1325bff944e918cfca8c1febe8b492cffc3195b6cd98e66fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be172b62803645f02953906ac29b1993adffb9a030cb4f6310f92b16e72dda02fcf13659581ee0880b77fe1b0abff500000000000000000000000000000000115c81153c25f5a08b546ff91706e3b040db1b153af2781a96a8005c5706153ba3f030b85e26792e8be6a80aa04a970a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c898228ba06a919f4ee8743e25493b65492527e936999fe0d4a834bcba9b768807564927d4d037e82de07b96f9c226d00000000000000000000000000000000037ba972eba7f0315d262398bea0ea0fa7091063f77c7c14a2ca1da97c882d3afe00822f8f4d4c69cd4e56e3f4f28c0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016377e9b486f434e99480291e3ab2e87feccc329f4bbe6101c2f5c96c2ea2f39c355cb7ba28e1b3758fbe86da0d567b80000000000000000000000000000000015fcaa7a6c4a884315e3a550e44f2f36d3d8666f272ff26d1d94ff0cef1b8f739b9861d57ca1bb14a0b05b9e38ee992c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000107c47fd0e4918ff15b3cbe48d66f61c9e92ee119e959f5382d42ab20109f30080a08829228755dbbec083e734dfcb30000000000000000000000000000000001a7428fb01468b201b5f9c9893a19e3ab1cc1cac471bbaf6cad29cd919f4fa17f78a17706035bcc24b2a76ba07818df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001850e6d6385850925372e956c04014e357ac4f12c7daf15219b4b8547aec8c0d7cc5009a34bce170d2f9d2f468da96520000000000000000000000000000000006a58ada59e20dfa5f4535f2d1a72977e1efd144a232183833394951b5454ab64b943b3ac5f64cfbffc84ef8d2567c691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aa887b5821d57ac79f21baa23c9bd109a1ae485cc33c81fb170172b09b6f0e75120ea69341e172ac857feeae0be6710000000000000000000000000000000018a20704aa17cb24e92cbc1e0bf88107913095a3a908f3b5f0c953003e8392d6e7c71f8f9363101a58d171dbd92d974a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178e4206324d82695da9ed70d6486b9ea5718c1999b0f9b97e603b21d2d5c84b657c487eb8364967e67f798112045ecf0000000000000000000000000000000008922c279f2fc6c702d0a7cb79e6ddbe7c459d4114e3f5660ad146af988338da7dcdc12261cdd919ef2d2aa1bc0a458f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc06fc5d19f0308c0ff3166ee5f3860b5913035063f1a31b6414ff908c1fee5f5266eddd73ae89502ac866b9a8b1c750000000000000000000000000000000002fa1072955c6f686c09a7074c56369c7946e93cb4b3a5cb0e2d3c02cbad742cf80c01159ce4730249540bdf856109291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac5c22af41567a8f4daf7b9ca20d5702d47054336e3eaaaf130a4e1299de1ab81f966cecf11b8759aa36f64f372cdbf0000000000000000000000000000000018129bbab7814eaf3d8da66c574452af4f63828b1dc143607f6cb82ce356bc7fab2c89db4b332d68142bd03d3ad12d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cfa4ab31cff6c1495ba3200c6a2d58f8b4ec520b769b3ab619f225cf2fa57a36c0dd2ab068d8cbd2a1f2a39d14cb93000000000000000000000000000000000aca2768ef8273043a6242c885c405a5911664b63b69cd37328e9636775704bb8851f2b6c54c41bb0a598d0a0601fbf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000343ee3cfe739080d3f7dbf61af8f0b5328ca6d620850b8463bf9320794923c4a49b08c34468afc5a97c1b2196ecbb1a0000000000000000000000000000000005cb3f25ceab2c4cfa550813a5f0669f914dafa311917366c13f28305386d9e894e47d13a7644f59264b74a4d1f21cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a4e8be12baa785e7e0a55f3b63214e0cd467b5e1d2ba771853bb7f699b4d6cacf6d11fe2b72fea2d847a69f987d191000000000000000000000000000000000803549dedc10598508f43b76adfb581ea4f6cf7f63868cd4c397238f431f35a8cc31060c9933366ad89e4c4dfb9dfea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5237c0e69648bf70412cfc0169a8a682995cd4dba303eb0375ae434256fdf2ea8c1299a186cf38633fe9c939cc4f2a000000000000000000000000000000000ec481bcff747a436cc403a90464f24ac0eb1b23568384d914bcd2aff753ef0184ae8e2ae4fdb29d1854b2e84df900421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b3a6409347046541f0dd2f23d215fe4e66fa1ffb1182d78e9dfeed4bdd530557d3f06f1e293c58f8d65552393d2f880000000000000000000000000000000001de0d23e8f12031832cc4e33376ce400629de8039faf2f91d204e7c64a5319ddd903071cdab95f7577c609a74eab5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811f19283aba662f1531c306a5b99d7c3f59400f30acd2e2002b51434e87cac5acc933b8f7c53556c32fab3f5cbb72e000000000000000000000000000000000ab3d4a00dc651357f6a4c4a2e21f239fca0a437e4bfabb2ca575b3816a518022fbd9bdfd68aac839bec1769615453fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c81a72807e1d9f8134e9925365ab4da7f958e35d1b3614aa4c044b681b27e5fa706aff573a0b204f6d06690308fa43400000000000000000000000000000000057b0e465c3e0c2cd01c21596854efc63029982924d4af17a461a5046d6e84921e80e4f11a4fc86c028aaadd727710161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6a880f00389495ac590390381beb67f51d192143f1e412fe4fa5ebb0567850dd869fdaf33680e6c6952a4f3d2d1a40000000000000000000000000000000002689a0d5f2738518fe29a9a50fe61ec50c06f0aeef29bad334947617e8d9c4b9a40efd5bf56f3c0b7cf6b8238c708fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127cf776c2400db8d771db5ffe75a0387aeca50668f97247505bb50ed3efe50a161b26f3c8375f60580716cd8e403cfb0000000000000000000000000000000013d26f82ca62eda2a1d779900ae66da6ea529046de818520e472a90d967114016a64d45df622bff0e66d273f480e84e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff191b6b4f64e56ef2ee0b2ead49d4db2dd7299ff43e40c817b7c2d34cf7b961639dfeb7d11028b4a90e6e9d7ab643000000000000000000000000000000000d4315d38109c08e0b6c61a5dfdc99130b781c8fe781c768098bad8866315df2e767968d997526eb0a955f1cd7f4dca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f61d385cda73446f87341bd089f53c3c42def6a34b1a26dbdad575ed353b7a25ce0febdb89e88b3ef7d4e3309fdd5700000000000000000000000000000000137d8d8de4977c5d3bb3bb4beb1b15389168fe57273fa59acf2286c1c4d9558ba8577ccca971e5502c4383ae0807a99c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b192e213a2c740356e608629e623e1444c50559b66d91b83ab934d14c524855a1695b49bf35954c268f9e17ac99a0e700000000000000000000000000000000154a58c76ea2c5920d9b7a8623290bddbb21da15219edf75e32d4c32e9b725daa4bb6fa509b3b881d9493569fd0ca8431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c6490a675fc775162312749fc02e18a196208e2293d2376265665779e000a4da6e6e1343666e6f87417dd058f48b6f0000000000000000000000000000000006048710a80cb90cc6fc95202b014506f002ba14080cd6ec08424891e807f97eda59dc88767c88858b793e7b5a7bfafe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009954dd2d1d332e76c85d5b736705030bdcc06cc8b731c56feee7403c00255eb918a370b35faa21f98abb8c96a1a8c56000000000000000000000000000000000b65ea3b664969b461c693ff5adad600f224788ded552e2b2a97503c058595e5944bb74979977f6aceed01d108d1efc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004aeea4a5e8fc6032b562a4b5455f2af36c983b9d4567c961da0b4a9bcd26e6fa1d0258f344136f2122580131fc6dfdc0000000000000000000000000000000013c7c74ecd0131427ce1c1acc189ed68888273f8a78c932bd0e9be0e3d35301a471fa41e0a6416196a1846d58c6961631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684d7d87ea69ac759c7694f56441c45cfe0113b7a58d608f93a2f23402966a9c031ab39a58b775917c1e1644034540d00000000000000000000000000000000168b7a9cc121cc01c5e7cdbbe32f53612ad0cc67e9d719b52250d1953412713f959b992b542a7b25cf717ed0b7d191d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7544c69ba679ed4f9ef2d812a65bf6c94b6aed766da1acbf464c25c400cef4bd2364e147c71529a5dec376c332d1c100000000000000000000000000000000135b58b276d7d79506e0a80df5aded63db11a68927752d7182c0f0176d2383d2a906bc23a89f144567c96e5ea07b9c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9da50ae458d2e512731a11286ffed8d865d59f2dd708c28449ecc5d4ed4a3e5ddc62242ece9caba40089ce12513ad0000000000000000000000000000000006a36f2a31029733f3da4dbb3fcb72c52b4edd21e182895d476e6ee6e0e0f018aefb6f213fc180d0fddf6f1d0384b7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492862a8b2d3d21ed5cf525f1d413f9268cd1b591ec36c6d9a13c6f77e92978bf4221911308ef084c9adb12c10449420000000000000000000000000000000009b84c40c5e6dd81fdb1deb769f32b1254c2fdf1364ad9fae7da1d7827b95f1edbcc73d72a72d4746464e999f8ed48f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001744fd3088095025ff76c2e29560d0cc330f2bc72d2a42e3627d2df7a1a916e4ee63a36074637b8f2876ac4395321ef1000000000000000000000000000000000f65f54bed4549b3cf11e779a558f52d27d2970045d42e2e312e8ddf6e7aa846a5ce3b682d05fddd3459de00036a18b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b25d37de90656446e1cd89524c46762cb5687bf7751517feace1711ba244c0b3565fe52da1e8e66db0004e6e3f5f0000000000000000000000000000000000047bae4d2347d6488cc2d1d06e27227d7ee95f4cf00cf0d16bc936d6a3715fac9cc7aca54f02a26aa5be3bb2c668832e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dc926a98e68c78d9e9c7ca0448d511990f457342bd821e1e30fcfca60f3fc3714880d20449a8a1b0142009724d8298000000000000000000000000000000000bfd3aa3b486a0d818eccc680932bfa5b525d7c4d77d42d1d176a7f4f11cb81a2c65a6e3e5378978ae36dd29920c6fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aa5700b5e8c39310f3b48586a312e1e623d355c18e242de8cd68ffab9d1bd786cb656b9ae984b9bea081b62db05c2d0000000000000000000000000000000009c9f58e35dfc06f1a516b17294afa5167ef90314e70064f2b5efdbd12775205bc47d7adc216dc62046a300e84ce52291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003605bafdae0a7bc09bada9c42f4cce2adfb28862b60f50d8034de6ad50e2bc0e1f81185406d6bda716fbe74062329ab00000000000000000000000000000000110a7b7944d97595ff8fee1d2ed7efc9a64c2cab9b71c3d0e246fe1c8f9d17b2a3a2333ed5394f89215787fb68dfbc251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf4f370ec9c2a04bfcb97d06bdfe33ef71bfcda3ad5173aa6a48ef00827c96adfa73cf6498c7b11d07e7ac5af1c7a11000000000000000000000000000000000e8eaa2b214122d041e275a927de61b6a3a2582e4acf29e782fcc6d9e10873874655589ec8b458f1fae91860ca6b8e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cbd67a893cd24658b567c4e7132f3c3aecc397ff4615fcab6f3295986309d5b5d8bdd006c081232d23250a5358721000000000000000000000000000000000c6304c6383884da2bc74019502a2b085b7645872de8321fe8469ae1f29bb969490ed78f0665924f5013037d4f4ab6481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3b7e4c01f7256b0f535b75b4256094dfa0a87b6f1af50c529f3adc82a9838ba1a0252f33424748051f1d9b355d413e0000000000000000000000000000000013c9aadbad2e26e5f196b97b7ca1a16b36514ac3297d239f1c24e102884704dd02fd26b0a2a5b21226c8df594f6250a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116b595463dd9efffa713622b9213ef4b93b23b57ae8a029cf207f3d10093daa9a660782f0ee57a127b1a0b50d2d96b8000000000000000000000000000000001518838efa4f46763896720536a1bea0353355280c8e650cd747f38855afa6de06a186ca3e09a38c4bf33320f88048761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ccf8d304ace09c576bb83f4510669e7cb160864444b4037ca68817628a2a6fdf8e671e8f269947ccfb7d7a958b812e0000000000000000000000000000000018eda754602632ddda4af2d702102f59abab31dcf4ab943f1f360a0e7f0003922c66a97c10f98c2d153a7bc2cc8dc1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016c747ab2a6568a6b21fc221d6df4907d8be9bbef9bd9a5c8ffad7ad59ccbaa3784ed8af0cc01b082660aff6fcb583f000000000000000000000000000000000ef37eb24a2715440ff0aedd0daee3751cb66422b720cbbebdfb90e35d96aabd5cc6f08661948c5b3791b84373528b701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014acfd5c8f05013db4af8ba42879882cd86a7611765d2787acafdeafa01c7ac0b64a06b85e6602626e5912c02d61e5e4000000000000000000000000000000000338bd539cbc31c53b70543aed4e1a85b8a50d8853a523bab27954acd30a50e9eacdf6e47bf3d4c8f0698420d01d12d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018167b5ed7830bff61e900caaa19cca326c5c60898c26f87a7f716ce0901d740387a5ceb317a8f26582253cf96bb11ea00000000000000000000000000000000172367c4b5f78cbc3a3f0e85d0ffd802f11f806e590082a71128ae1de3d293149093daff6b59c17b1ff3a6d0c1483b011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cafadea79d2b36adff03530f0f36c67e7a78f0db1ec23a736dd938a487d2a759b171ee13bf875a86cb636da5abc9a9c000000000000000000000000000000000fd74fd075f946d96269395563f6947b3a428cd19edc00a89c5d44e7cd4b011dd28d679a4d5fe2dbdf3ce7d8828391141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a73e98b38fadfd4940f0cb1b020b5eec20a9f7514672807ac762ab23f5db3954e6848438198274c27f3f991980daa7600000000000000000000000000000000134ab48ee70f34b1558f2b99fb18558e6d8a50d95121ffc193358c9958ab8e98ff5ac607ad30448e9751d480986568261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e0e0cca7f2529bc7c264b4975b8c2b8cc1cabb3cb51b216281876331a45274422fa35e4be6f5959c557605a07e006a00000000000000000000000000000000182aee61a6e18a6d386020bdeae4ac52dceec81a41e6e5d42d36ca66020be2d6137d76b745e780c17e33056e4efcc2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fce199e6c20db79719ef4628867141d606a44cf920605bf07ce36a6f03b568d2763f2e69f13984a3fff80a9c48102b000000000000000000000000000000000718d2d4d1cf742a65700b4e1f381a1b84af3958c4e3a8670b17a0c0cd344617ca73fde662b56960bec067449858ba891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133a9816fca200f57b0ea30e3c9cd54f971cb9377231b1915279ad75a6c4f4bada568d60311b4835caf5a27134debe9d0000000000000000000000000000000011849824542e0c079029fcef54fd2e6d07afe05ec5b4c1cd6e3565f7b643d2edfe6acb4cbef200190507a59b2399ea8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002194fe7fcb9e1ce063f2c01f4c50993a4c029aa941a859ff91e15e3a3bbec28a7651bb34747944e7bfb0f8b96f4f7e90000000000000000000000000000000005aafb5a9a84ddead31623e3f567b3380be34ad23e783374665d25c71f52ec1692b949cd8c9d6ce34134e36024cb23201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c79c77a30863d778a45203e41c01b3a062b4507c1f7dc60e1bf7d040ab74db6b180a841f8ac038bd798821d76094fe000000000000000000000000000000000373c28df5de7fb7f2ffb4c3d114b73b1eae364a774a7cfd19d3dad6587e934385bd8a4bb7b3a88f55bb321646f0dccc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bf02193e4697eb78afe3405721638acf980135c52eda0d1e97cb96cd4f2253782125586c58a1841b60548da475623600000000000000000000000000000000108bc3a95b7c53f7b6258aabfdecd67361f5241cb913d0e11461a89e982ead96ce96933f3753d15fe6b1e315fab7e3281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a6c7767adcf7f67a0a5aa32f701808b9b3cbb85ed94a219412e6d80d7705716221fe644ae9f7bd35b99602c1bcf2e000000000000000000000000000000000ec9eccb6f4bcb15bc2498910e546044231e28c7705363793fa98aab4a112fecce87d01e7da7751f8593291d5735667c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001966718b31c504ea12f09a981137d3a5554582bfd3cf4c377333209cbb0c1bfc6b874c14034ba26640dcf465e205d9ba00000000000000000000000000000000063c0c6ee9f30f325f3c57a61491217a9635a47f3ab350b7db610247faf5171cfe91c2dfc649480582ae4a434a8a4cf21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673ac402eb2bd092c43ce780c2e57b6860119f0b646d7949febbe4b3dd535fb73e89ab845afcb3491fafd1d8267b8d30000000000000000000000000000000001975c4eff091d49ec01fa7b12c9473854ce7cd966e04d6f19829ef0a40f3f0d7e07cea12fb9d0a866c698458fa5232e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd503388ce235a49347b06a59d7045994482479b55490ecb038e14f9b0acf5d3266321ff4a39e536bc0b3614240331000000000000000000000000000000000d9accbd244d3b824a2ca4c81891285c99693a2a9ca70030f772c2dac1ee75eec539ec115ddf1142bbda67756502317b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f57341fbe964a56df5d4b3d93662aaaefcb66b66c1c20895eaa36edf01906949e842cf4b676d0c4ecbf53ffb1d8e980000000000000000000000000000000014ba76f40858bd67e0def739f6895846b24919fbe73cafdbd8e2565fc198e86ed6e700b5b5fc67822c3c1e7b021a60a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001023e7844bd2a34fd0335f21702b0b4bb4a905635cf23eb5f3342a117a418dc9cacdc83c376703ac6414d4fb954e498a0000000000000000000000000000000006476f6b4fea601ddde15f83b94f250d773d2239926b5f82555d06ca0e257483cca4e70285eb17a681a2ffe174e03d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb06ebbe9d9d4c31bcb6109828e435e41eca49bdf810da1f8c9f8e5ca1094e625f89bd878a8c55d1ec1d17b7c543dd0000000000000000000000000000000011a9602be668b7fd6f8554193ac74a02cf5b399d62649571caa5fca6126b5b33d5b085e70751bcdbf8a66845f3ae6b421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013efa58da1fc78ebe4c9cea402f50f1ed5ac302935157fc78ad9edf53899912acda05fed6c94b5e40ee9e3acb6a0134000000000000000000000000000000000d9f1d498117e59718d01c82e6c1f5a70f97d994a3644c890e4ec0d5b692a89214cfb80661c1d4ca87c4e524170fb07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056b92e22b221598a4ff581b51add6c3a90de63146bfbe00a278b63a42ac7edd53246d4d670c82bf0123442092160350000000000000000000000000000000004ebaf4323b019bcaa5b6287644c30db64ab48762c54455dc8e8756d14917498b62e15b9259c0db3da456282694c8b021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d39f63042e20753ea3438150a060f24820af32601fb4d82a0604fe046d089f82e844ad220ec072f19b26e38fb1b2d8000000000000000000000000000000000adb7b0e4d52d81c93316aa3ab747ad7915cbef11e51ccabb61029889047cc55571eadef554b19921bc0604cf069fe4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190072ed20096256a4303c80ee4283a485ce3912f05736f27d8c94c2e6031ccc4f9af73960b7775adc694357aba0e1ac00000000000000000000000000000000039b9452906ad72d218532fd03eee7abee89b419f2d358ac89fe3abc4211eed30f6148397be24c5386faecd11a364dfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7972fc63a035a1fe9606b52621f1ea4bf5a5f7ebbcd66535f5b48d43a3b4c4a133d08a32116337cca785cb10a0275e0000000000000000000000000000000017729ee6d78b5d4e55755f3ade681e10e8a97e1d58d7dff66b4e40b800b54f482ba1a9c6ceb8d9bdf7560c9097c9f94a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f679df52ea8fbc73ef29483da630e616e1fe7ad4ae3a2e315905f0bb882db6de2da13d247a027b1e684a4c4885d3110000000000000000000000000000000012dd2468dff38e9464643fc6dbb6c948d601caf462a267469b06a4d72b058a7d3158a3ec223f856093a984a1e73ec51f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997a246693e0a01344e5e7d14cc8bba54fea5a7b1755c2def0fdd3335855036c1aaa0a201384edad8f3828c7d8bbd5900000000000000000000000000000000073aa8a814e610eb7abec355cb578acafdb92a9e84ff2df800e5852eb9165da3693ae857d7880aa2e378e80d0f1c78501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165334b5ea793575ded7e347819866807f3912b23afcd16ae5556d1e22574efc0fcae014ea62f9038fb4ceae22ec10c20000000000000000000000000000000002c2fe8622b6da8963bbea32cf314e813d396b9de50a256c6160bd7b83179e023990ecdc3d74415bf29f2aeabcaa630c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ae2ccde78a44a3eabca4213a509c0f2752c7488c5e70d26f65ea3875db4cdfc093dd3323cbaab30beaccaa87c8d2500000000000000000000000000000000013ac0fed61c96bd7032f0711add9e7901e539c1c579018532b3270d33ecf6d3a6f16bd749711d36bc2cb4e1be9416ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661fa014f07947626a0744e29bc64c93f79328f1883a09934b2e35c8be93b5c9f9ccff2f138a9a28934f1689a42a35400000000000000000000000000000000137f170ff52e79c4fd0f11445296e01cc823a3c64b5de3a2f746a699eed6610446fd7260f730a3c92a8d46f4f5fbd1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150e62275213410da1fd99f4b284d0a983af739a59ba84b9df118c9c013871b563f6bdb6ee30e87488c7cd84fd3f77720000000000000000000000000000000014bbaaff6f5f9728cc414598583407ecb8e49212ecd574fbee6afc07cd7a69d332c12dc202dae75e101a195d7c6df9fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a0a4f4b7375db4ab709c41473fa88432742de68efd7cd3c652a84efbd3c1c1416f426a0093691bc1d5d689617857780000000000000000000000000000000004c7be76577721d32cea70f30dc1e27c2935db3f51a60046d6a97b78cbbeda424e94b745af3ddbb95da2b7dcc1ebd5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183961151e1308ccf1dd0c3edfdb0d8fa3fa55f678241d812327969c6838d87682f7b6231a777d0ea4a944738491c2850000000000000000000000000000000018b635aed5b3e6f3f14c9d147239e805fe1cdafc055a4235ab3b711fc3dfa5074617bc6d3e5bc62b10e93722fbb922691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e934826618ebea7b70dd3fb1b8858b3b33a518b8d2dc89b56d8dc31c3bf3576834b0af717db5fdeb362fbfc8f49bc200000000000000000000000000000000018a8e43431bb3aaa57db39526cd5be28cc11cc7f22113b4d8bb34abd7442cc4308481b62bc937886b7d2509d5f8435b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b133090accfc8198c0101be804fa771bbab85070c962b3d55b8ca9e683c2074bef91397e6e472f4fe49226291fc5b3a0000000000000000000000000000000000531d3e6b8b16a091ebe111b41289c705ed00bec7357ff6cd37a20fd4a4e0a74ab02bf72ee122656ecce4a65b40f4481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acf1de55b18dfa6aab398cb5b936f824a9ebc1a16ece09cbc8c3f5f0194bb97eadcb69830efe519764687f2a0ec51ec000000000000000000000000000000000dddb0a0a50355b4a8b1fda33ad4c8cd226474e49ab62bbbabc979121ab8040d0b3660c450c8e7cc78df0c7ec5b309eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6c50c8b5e57b1c396484ebbca423c5a08a4190dbdc020920705b15692a126be97b70e57689f19f1754492731ca1c0100000000000000000000000000000000037b7d1c6372666748b08fff1cb3995acda3206f1aaa13668f6370caa871f964c7901ac8a5dfe09da44b012816782b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811d757ed709dc893e0873e32482c9f7a27db1f4178704d472848dfe09c0c67dbc36410b562d82ce924630b502786b200000000000000000000000000000000014c6b966ac1c2b46e6183fc5ff348e2ef1445e4dfcca49917d6803deee4e63d55870806d056ed44bb093681975f29f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a2dd0a8d15287d86826490e8760c21963b2a3779acb5e3dafb5ec457c217c908cbbd63a7ce5deeac44bda51c2b2b75000000000000000000000000000000000f3459596d662692dd96e541f4086af27bca94358fa3b7e484f7b1b6e1f3e335a3164626a629bc1a009ac881f16e56341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8b505f447d6de33df40229109ae3602f9bce1fd7885fd6a20453fa268d891b9381389a29a0543b60f01f3971c1277f0000000000000000000000000000000013081799654bfef12fa57936fd928f050ac89406f0b8917a8d357eb7af52954a8be4db98e95c641045876e2570c272f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7d0ae16c79dfc225055d92146234f9600abb4bfbf975580b9b830094813d14bf0691f1d8090e078ef3806078613b8100000000000000000000000000000000146e65e824ff866cb76eda4d75fb0680605726c470744504197c93296ecd2e091d540d7ee761404d3b6b48e847994a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042231c089344fc9c09d80731ee734c8491b72e5ed1441dd9346661849b59f19e4d02812e9a4b812c86810b499e7803b00000000000000000000000000000000182d8875100f60ef28c6f7ca70edc0dd9b9f2c279650a452a44b16569b72d3ad113b324b10a24a0a050fa2f44704e84e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026df9b95bf9b21c3d6af8d79c43505ebe1dc2ea7d7e67e8ac609d14e45858d59de43901e90e6d760f98808dc40647d7000000000000000000000000000000000b8c1e03b7fc79e1c05e1ed7197b9f5d0f3c9fd324f31fac7c282bb0ad51735e683e9dde0f1f7773266f62119d9526011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137ce1c6c73a9f6d585b0aa9ffa3c076d0ff1c64f14ba4699c2b82f05266e3aaa6c7bd499e4bee39c1273e1a0b1d12f20000000000000000000000000000000013d94acac79a253181e2f9e251b3f7011e5202737f0fa46dc77e675a3b7608078f7ca12ce329da543520391acafc02b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb0c98e8cc9425bfff98d32affbdae33f723409b32b282053972892563263d09be0b7516b725719e5c14c9d5b80a19000000000000000000000000000000001077b72534743ecde12b6a994944bba7d2d4f1a913a089fbcfb36199b1730c524315896e65f1756348e603dcd28729b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b57d7f46a8b2efc7636b95bbe2e3db4add05c7351bb6080882694cdb563e615b9f6b474ad07b1ff8f76a68c618f7c10000000000000000000000000000000014e36e7e70bfde5f22063ece7e4ef7beb6d33ad79c68f6c0f31966a9089120e4442884591580955c93e871ebe7d707ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d46605d1320e724a1e707c09cb2a9a46dae1cb159910eba01b5964bced950ff444e9f62165dd9666f30f6cbfbb7a8120000000000000000000000000000000010c6ffc262073c4f3a041103e1d0a0b6523fd6bb5bf86f0a62ff0d92a91d3eb85da4158460fa12ccbe93d6d18c33352e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f31a7a6b91d6268a9acaee973f62d883435697169173416aee8b8fe708bee04a0aa1ea3d6ff9681b9747a4aed6b7830000000000000000000000000000000004ef41111cbd28f1ffeabdaa67998d90cc36a5a37f021a7eed23980d8c74c33580ba5e8ebbd039f29e13c61ee93154e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113dde670bb398e65d49fc13d61168bba93013c0b4d63a4066705679cd6ed6e19fafd25f8f3736695847d47bb29b122c0000000000000000000000000000000012383adbc5860c38569e6879b14a08128c4b42ba878dac7c44fbc2ea548ea4969a7ee86e7cc7228a735fe1cb2f0d34d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001008b69f6ff2e8121ca788be709f5c121a1425c57bcdba7e6338e8d4bf8fcbfaa6c5666e88539459ab558704ef07792700000000000000000000000000000000094583cbd3f9e5de234ecbbf1c07918502764050722af7da1014b122524ba8f19c271160b782f848c4d2410bfbda6cdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b25f20cd6bfc8e61dffadf7690895e78e9c0e2fc57699386ce5fcd4b3a9a8b56f2274daf9bd2aa571d7d14d0dc53070000000000000000000000000000000002b4a98f9c592586657a788aea618cc2fe74d11dd3055dde1439946ffca1834f71bb7ce097e6e89e76d056956023e6f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c8135856ad44f19aa60946926a87ec59bb8cfbcdf9158200a6f6217b16587f15f0ea324f0d5cbd865474ae19db8c220000000000000000000000000000000010730b4000035d23bd5f0095f699c0bc28b614210ad7704e63b289975298196739573a217e6b0d4a040821b7e0a70b521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea66027b903d033f6d3aa0a5dd9b9ccbaad009fb0472193c8b615475a542d937570df36650c253f4d5be079f9be13c00000000000000000000000000000000016e7546fd38011c7412ed787a6149d069538b4f071bc89bfb34f8c9e75205e7ef59d441471d230a6c22b1e4ef9426411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b790a6ef1e6d21140ee601de150a768f6f8e22b3b1085ce227f9ed70625d0ff6fab617b6684043d9f23a321c4ca013000000000000000000000000000000000cc9d0f2caa382a8581ada103d683fb6cb01a4bbb029b82b2207a5d864f5f5924b8735aa48c092baa41d42011321e4121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fe10b37048d75be5315cc4a3be9ed16f6c65c1a5ea36ac1c8f1d36eeb755789898e4e2091abfeb53c81825aea7c2cc00000000000000000000000000000000142d6c97a41d8facdbfb57ea6073d4e6ea67cc80564a93a9115ef99338f4fdc6d96ef6b4abc9e7c3a5d6fd6e5c6792c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060cb93dfd4dce7551732f75cfd707e5fab0d0174efdbeb95f134e3689a90f8a873101aa72350c50b31c414c0d3c1f2e0000000000000000000000000000000017517483e78db30c9d574755b8d95536e89a50a68c61fc4f62eaad9299a131a47a6009c11764616c188e51eb12f04eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175491847481df452311edce53b35e8bf5bd7d162c8f94a663ea036e70eaafe8cf4b3f6a9d8fb308c8dacd9939efd3ba0000000000000000000000000000000001b1eeabba269639904d0b2fde01b0f00309a391f91a601a8a6046044bc4ec16c8b221eeac6439581dcb86c2e7dab9761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bad947c211e9ed9632e098b21dba1a2d78234e018befa8d39ae1777d963a1d13ae05665a769f18995fff260f0dbec0000000000000000000000000000000000cc34f2e4b54811e64137f617ca712d04b2c4e75e5b45b835772adac37e3d1093f5989932b0268013944a758ae5dc4971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c59b5d850866d1c7d88850a3d1b87fb135bd24a3aaaec08779fdbed33fedfbb293a08c16ddf3b56cc6e0177aa84a490000000000000000000000000000000014001a5da2642ca1cd1b079571ae8dafc23d0c94a61999b292c3b3212da604144cb5136a4fa267988d8abe79c15edfcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c92854a0d114f27ae33442307902c96bf05a8a4b8696ace0396809b442ca5a016ee0da0c1751bf2965a5ab0fda2c660000000000000000000000000000000011353e746b711ffce1315844f75c447bcfa8b178f474863be4348f30cd0239be7ae468eb4a475bcd2a0ec610c07550721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e3e41b684dbe8d04414cb6529f7c7eeac7e463946d3e65c16286063917ea5b19bd955f2ae4f66d2c8cec740132886c0000000000000000000000000000000006fa5c6273020d1b21b621f75a31a39d95f97513010e0629e95c297a64959bad9bcfddebc23be4e83d6ec8b21744acda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5994739094ed036eba753b64f297e6c7b355c7a0330929f0dd3b4ebf451746da51f4183a007def6d1e9b6e184730ef000000000000000000000000000000000c9f85c12bb508c1be890dfec05f46c6e94f2b3968843fc9a8de24cd565fcd26c0dc1be7198fdc3b24a81276609812121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d17d24fad0f216837b9e2b59bebea91bb78eb9453d7cdc85030d666089710202a8c754cc7352ee4a15c05ba2d27d0a0000000000000000000000000000000011985b9e44ec67365b49f96b6a69d8364f12bd0d20998679d7d6df9c39d79228840dd9fdd8f42127e2e5a860956666a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002711ff76847476f4f7456e47e938d8bebc2ac55c12619b66aaa619d4866d77221c54b9d8c843365ae248d685968e166000000000000000000000000000000000a2b84651691b96445cd6ec6b1a6f1caae37a8d7dc216993bd934ddf44a06c0ac1f2c5ec283ba2c5cc79e39aafee87f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001853e765b9ddb214e9b6a1b03541cbd66bc06ad66ae5be871938e8e3bb0ce68fd64d75f4e200c602d84b4f820c7a01cb0000000000000000000000000000000014eec4aaa7ad2b54e68ea209c34d39e9425fddfb21680747451ee0e0412ee2b1c0256526dafc09dee7548a485ef185fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89634e5d6fe355e01c6c7233164d63e6367dc3a5520e6fea3dbd147aa9cbce7fd9fc38ba98aac2629f7fa6168145af00000000000000000000000000000000015306b8f46c5a1cea4517b98318eed290006247011a2a0be3ab51e303be24b0fe1749a2c1eb30b9375b53c65850a90b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033031e42e5e139061631509e852cf0b84542de1ebd43547e37c4a8af378d3493b9f35f87611f4bb147b926de3d1d107000000000000000000000000000000000ef7dd8241a6b051f205686f4e2ce67e6ceac4df93ce299edff5a491e460d791776f455a99c42bafed95cae8603ad8ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cf7553686c59c5cc9ea059c701c6be23c886b5794921ddb63464fb2ef218bcddde42af99a98737a6959d06636a01030000000000000000000000000000000015b79e7d6dde6ec10d5f6d8dbb73a43f4922eb683213b321c51db9e8bb533013a15d7ed0f4925ebadd60b8388315da451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a24c0009badc2c8b01866272e7537b7786e8c3fb66bd77cdd8ddda8599a9209ba774244d6d18b4ca0d9512046ce71500000000000000000000000000000000100cdddee8a25eb17f88043321a1cf1774771321edf41d27cac7d9a9dcebaec18cdc68cc640de7ac64a354cfac0ab3051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142fdf224370c235f838fdfefb09fa1ef026d741d24bfe18f6b49926575c530b18ba328a81d873e6f8980f6c9c7570820000000000000000000000000000000018192bd931c1e2003f2e8294567ab9b6d8a4c6611871b320678d21fadc45cf7c7f275a8ae30ec2a0da9c0e482943ceb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000595ade45a1bd71a2f6930a0b37d63431fb0527824865b97f6841d839f71b5b956fd6ed807c9271d2290e208a0a363240000000000000000000000000000000013d3ab83e0223ce9a4727c069a59d6233acb527fd58548c38a65bcb1af36b2f5f8069bff5bff5b63b5ebdaaf083c318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000037c14c346765731a5749b603481cc6f93963c041259fe7c5e22f8cdb2ffa66870b8a4782ef8559b9a534143ede6ce6000000000000000000000000000000000829c7314e2d2862bc6baeec3b7aa45bd2fbf5be9bfe201f6753c270afb1ce635c229edea98b89da821636127b54deae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001425d58abe34549bab67d814590099f431fbbdd1e7da98c889da4e7efa49ac58cb003ec6bb22a8185ae58cca2de8a5d9000000000000000000000000000000001741c76516e8c2bdeceb2ab1d9822d3d34ea267342a4da3a394e34799b41d3c88626b89c29b019a7b94ee231538594ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007422603dd8bd78acf6f36dc2384e0ff02f599e62aeb6cae26d59af16531c0890696b05d440749e6bd6db5b301ffd27e0000000000000000000000000000000012739703562e31a33678a72a1a8d822bfc4b0210b2cf936d3d4e0b8706c9e7652725aa8ffc88b1993928b8a544a013471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caae310c6709a77141a190976a8223a70437a9854caa397631f28ac4257894581c41022c568fcc2755cb6e2918b32f4000000000000000000000000000000001487940d50bea9f7dac4717f89cb5b13f9042d19836047d9d54b67cb616b94914770d7c82231486ad143be3c057089fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b42c2a87faea8def82a4b5d6da9a58ad92a5142aabd527601f584de887a4ccd3d7777aab11f55889a73a0ba498cac30000000000000000000000000000000003b318ddf9d7299819408daf7543b2f8869e280b320a69b654f1a164e384cb062c53d1c2c1506479bac8d9b7196d132b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019791737e690d5c174cd26cf5c9ad23271525fd7b60a08a09d77ccbab3d00ffae2acf2edf8e05842bf0e25c8473ffc3700000000000000000000000000000000161298f470f57284851315af49aa4c416d90dd4733ac63e9e0e802cfa287ca7f10e03d0b7d8cb49d30bf28ffe2bec96f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff82fc1216f6bf48793e1c99fcfe3ddf8dfbf1df20fe0981cf282e428104e220628109d5ae9c7ade1e0351017975a310000000000000000000000000000000006dd1b893f940efaf6f0fef340d9328e3a8d461fe5b3cf1cc6d4ca05ffa59e1da06d42cbc23e2c021bacdcad8ad347691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000759168487e5f38d8cec9d244d59364632788346bef56d04d0094e340bf7d6b0cf62aad7bd73ba9c1652e42de5266ad4000000000000000000000000000000000fc3f4a03094c3d528fb03a12d657227ce1e61b77bf733ed5ca60e35a0dd8ffa230d8c691ddde72c983a5c8ee6a4b2e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156293d5c5cc00091666c8dc47aa2d5c1310703af4dd86098618cd986c1256709114ae9298315bfb5c19d890cd0a928500000000000000000000000000000000137ab1c1277b8a7d87bb9b6940c5a5379fd70e730df4279e8956e84a32638cdbf61bca9b9a2ca126efbc5f1014e2d3951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065a55834e5e40d12f95d789adf364020bb11872ee7dcbca20cb9ba165cb885ad0151fa5079888476f0883e4893f96a7000000000000000000000000000000000b3b20eebae3e658afeb77b4e66b859035ae6a182edbb4c762690cf297a9b416071281df1c02af5dfef96c955e70eb021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdf478f1f0dbfc1e603344b61a34250ff8c08fdb84e8988815629eb2d6f0c011e797591e003ca7e620d2eb2e1484e2f0000000000000000000000000000000019ab5d62ff27572c7183af7e12898eb0554a678dd1a3b70b5bf9ffa42927af412a7b27591c31eb469092bd6f9cfe8a191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b5747d848c968d1d7f03387a70899274db7cdbe20e98a80d15286ced50e528ad7a622b5ca19f879467b2c3351fc3f000000000000000000000000000000000123de59541602ea9635375e572f01a39d7f9eba98b65e632ee36e912cd57db7cbf4d2dda750f07f0c776b531827fb1791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6f5356f9be7c05f5373b79d710d15b2a76df384adad6c0bd6701a1e9e086bf10f6f2a1fde3f06ba45c89ee87637fa200000000000000000000000000000000175f06c41428abc6cdd1a5f527d816b2d3689396a252a622fe9e4b822868a20199fb045e3aa8a811338e7c047a69c69c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f1f47a101b93a98eb91265f032cad950d11a16ef9cde66a740f5a550659d0eab7795ff6c56dadc01824f7070f202100000000000000000000000000000000087231f19f246e6398743b15212f9faa3c983f016e052366b3454dddf9c79c20524cc3533472b9c0197bf405ec4160cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fc97f58472a01cfbe5429eb559c31a9a00c3e797e6409f5fbc2854b05204e5c147d77a7bd6442ade8ebf15a9327fea000000000000000000000000000000000c413723ae66ead9c223a074d47bd817984dc91cf4dfc49876e4feec4d6fcccd9e7b7e6320978da950deadc2961af5a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a77235dbbc1b2c2cf2ddd353c56707b61e75a0e28b3f94f7d9809b1a220c70af31204a6e1332ae860e17706b32d419800000000000000000000000000000000037b84256c6f768eb5a057c1a865ffca79c95daf1afef21aeae1a63c0cbcc729851ad16ffb2eb9f2481534020c624f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e67eeeffcef0c04e53265e5534c4ece37385c767bf95779498c87cf72d053ca28aad30485d0d56806e606a8fc220e1000000000000000000000000000000000cfa38da02853debecd2c9957a22d4f8cd4a0c1b364d8d440beb3ce2d8fd51192d96113b1c3d89e9790dadc267e899e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000434db4ca161e47a5f99383e89572bd613591d2b90364ea863f21f471b50c64b3d1883bad7a8c910abe25e9be54518060000000000000000000000000000000001eecbbd35e2b0f0d3dd42252d52951b494de78bd425b7d7994962115a3d290fcc1c970dc7ffd0776d367968b0e3fea11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149c99b029149fe5e9d1f8d984e7ba22a7c591a3800a9c53efa65ffb1070a44716a4016cb513a8a81fca0fe8dcdf06920000000000000000000000000000000000cc3e08e02cbc862f4ef9da5d9ce67cd4ee543c887ec46326ab0ba60ae987d6eaf459d7667dc2b9f3f9a4094abc98e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013935d17a97687a562e0e048041dac85cedc728c4c0e96872276d4c21e6c4971b4df846467dbfd0abe22a51afd8a7c3700000000000000000000000000000000105d663335d884601da565e6e74ead6b7c4530dc4a22de901a5e1133b22b0823f30bba4d6e550b39d04f659ce98824141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a52cc8bc6207af0546a5acf66f319b24ef21fdbeaa0ce890b94d7c8c465a13826bcb447ce2d67de0acdbe2a92fd33100000000000000000000000000000000084ac9190de8c46d2a1dd590e9e40addbcd425a527345d721a0871486eaedf189bb140363a3ed30b7ad72d4d76166f8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b86efe1f7b8fb6a7163b1b142215fb82c8bfa83bde03ae5fc6c5851436ec42aaaa8c54de4a86eba1d4af8c038f68a22000000000000000000000000000000000228c9289d4806acb45d12062b3dd0ba94f64be372d09a48831f4797a2b9bca235ba8a8fe20dcc54275af7c28d880c2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005660aa7d7235a7b95ea3f3b210638cd5fc77c63064bc20741ed11e4693af1786f0d11ee2043a1f324e02190a126e6cb0000000000000000000000000000000008497aa15a31aef7020975ae0275a30d63a229e5421153feeb95b8c8e146741111a3c3ada3faf25480c3e9134728427c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010211288a84a0f734c6f00e56ec926ce191048627c29f0f627ce87990a484597b0383afb889c92499eb4712d1aaf177d000000000000000000000000000000001914157c0b2581c656e70b6593d7eda41eb915507099c5021073875a50f435490c531999515b81279c0ad2c7806651151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c25f3280b3f3f642ee083ca59d45cebe5c4b24a2a0e55e2592c239f3f10377001443b61403eab42ae64557b51ca06200000000000000000000000000000000001f14aa3e724ee21f9f7a0db09d926144ba53bb6f4226dd880c80b7b92a301af6368f3ebec9b1d8268dabbf1bb8dcccb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9605b895cfd007a7ff246d288485be5049cf0bf2808c2c3695a585f29527492f1e0981b38f8f597946f978e2902e2f000000000000000000000000000000000042768e6b159f9d297d59f1a3b4525e55ba168044aa4f374b631b3d76fde1d526defd64d56b4bd740464b56ef3363221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001a2d59f9b3aaa4d91f0d51803d559f4b422c16b9869cd3ab8954bb01eb7f64e6762211ca37b6c7cf035a43b3bf0dbb0000000000000000000000000000000019458cdcb53683713de1a020acb5666b91aa813c4440daca0a6d2b8c68d4c61ed1b4c8812af490c50b1289ce62d2c2221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013daeedd76807aaebe0dceb29a0454c41a5e1711680ac4c0956191f6e2271523e68b301ba3ba3637a067e0737aeea52b000000000000000000000000000000000c842f38681df32dc8e2b3dc48e9a98a87eeebb135ce8887a25320afd4a22767b17217168fdbe7673d0dc4f4b8828f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078c52f3352ef8666b4a7ab6e02b751cf42ab0f67772e947903220fbc493ba8c729f89c9864e97d0adccdea0730b34a6000000000000000000000000000000000e88e0e51dc0c4583de937753513bfeeb6a0b83b6b8b916c29585aefb11817c4eb15198face86415c83cb541253171e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523d527ba948b18a922f135873e94c86b72bfe637d8139b05a09672bd311f8dce4e77f9b70ffaf22fdeac6aaa8305080000000000000000000000000000000000ab481d920eeac58d2110432b0ef4a53a3b9dab024a01edffa8d5a0267d2bd593fc7dfbd26eb290f2a26bf9b81501451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031c17d1dc34a8926baa64c39827e2634df57649e866f6d5b5a466181e74932473a93f7821412af71776baade843365600000000000000000000000000000000179ae236d19e02702f03f79fc4a2df73f1e78d7e396f1b4d93b72d5c9e3edeab5361eaee8236fa10c6c9fa5208f5ca771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242a54aa60ce662759a3dbc073e620cb1274b66b56607eb7226dc56e0d630d5f222357af0c925dbb344720b701e1900000000000000000000000000000000000af7a28c75b54681d31cea97ea0c1d0760f43cf36b38e7892f2566ff595c464c4c2658c7995e82edc8c5cac6e14e511c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000797ce7c88f8b92bee00c66acb9f44dc6b0c97715acb2551b278742046011383fe01f51433e846eba05fdde06468164300000000000000000000000000000000092a85310ef2293c4b6687ad3076b81f1d2fe2ca8ac5079173ec9b92ca368accd1bff31ec5f398966c8476cae1a58a0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001870ff2e74b8c9b9fbc0d841b0670aff0641cfef16c6fe8e1074de3cc167a0d7be96f1e313839acb43a3d1808c3db9180000000000000000000000000000000013e9b07debcf3c0cf834dbe9b976eb709e87c9888693a7cb279301b89a7f8085dfaa8a73e73b8956c1396ca83b29f3f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e61ffe58718c79d4739bb63ae922fd6a7ce12d0db0f7ce451f58b10dc8add9a5ea8c69e769ddeccd52c643992649430000000000000000000000000000000004d21e6b4f86c345a8297f0065c1c029c636d8e94717210f692c26cbaeb5153a94f3a48508b0497a1ce0db86a8dfa3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e0bd9109a5fa9f2766cdd043fae09f8757056eed27dedfa6c3d400fa28501205ae172ce77a36846b36183b9c007f16000000000000000000000000000000000cb48f5677272c2e617776a44e8f3a3a47e24a59ec63f94eeaf9d3b0e1a70ae825af11e646f967a48a1a542dc0ab0c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2f27da60e1d9bf894295bbf715a029e6be14ff32f1ccd12115ebdcb0cc825ca8a6bc46524d77640c9884c05ec5e8f0000000000000000000000000000000015b9652fee7c9febcd32a5ff466bc4ebdb73662e411a3871a203330c5eabedf4eb849f3e86a819e60dd78af14cbb82681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001915de1c647292bed3cf0f626a0a7579dcd42514bf216c2a2c33fabce4dc630256911f7d82703882f622679262def9cd000000000000000000000000000000000982dbd51471ec2fe780f116c1e67efba7a2b7068d4efa76fb4f9b62b61d0cc717e3b4cafd4d33a7bc5eb86186326ef01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b083ac5073d49f91dcf2f4dd2d64ac36b68e7be9aabfa1b1e006beaeef23c668787b499f55445eae76a808cbd48cb0000000000000000000000000000000014cc2521de20bdaa49a60c55aaeefb919800aafe54df3e682463cb44c847044aff2586bd53a677ed986cfd95353c31d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f25f87a363ccc6c50fa1ad639afe59201fd1497b0d8d534b0f78c1fb8c5f2f3ef924f607d3c038ca2af843564f0ff00000000000000000000000000000000010fa0c55838bdcc278abd417c3bc8fda1c77910576439338f4e614222894e1e7965d35804407bc86b5df14906e1698b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000504af0122b4b6423ed68a9063e8ccac9ec3042bd671b391d73e43a7bcf32fe01e900b79e38cb4bcb8cd19407c3c833a0000000000000000000000000000000001184ac4c76678c71067863c156d0f9a184dc7e141916e811475ba1f8ed7c734123ea6c9331248767e791916ab9df5e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003381961f2eb0a485dcf7f7b7cd3e9472c353b022c263f1ea50ba8b706cc31e08bcfc5d58165ae36309669c40d550ba10000000000000000000000000000000006389847fd6dcbf8fb896d7f235c93bd4237a0dc8d8b107c5285f8088b7e77de7a17efa381448a4cb9a65038ac02cce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017837a963684a8f0d66ede7d54166d443ec72463365cf41a357ad4db67765a61b2780cb010b5e63dba2f0008e4cc0ebc0000000000000000000000000000000006fa81b011db765fea0328baf86cfb1c52a3202a9377c8ddec0ff7f096676edf5ef7bb723f77c9c4fb9fe2059a2ca8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd4608596e29ffdc156e4ee9a34490e4391ce5635cdd23a3d14177c2a226a7986b32d612d5e75945f5222413285963e00000000000000000000000000000000193c7273463a7b626221da82b246d03d335abba13ea3dedf08d031054ec6bb2eb3753a212b364ff003afc1a5b02bf5c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c65946cae08c4bb1d5d9d9e88d8e1b6352c668b843887de7103cfdd11bc7cc8695786bbb59af1f9f5a62e74df2262f00000000000000000000000000000000018ecf72efbd7b51c1b439c3bf90e8569681ef6674b6fe99d602f1ecbd663c0a3267e1b473774c06065df946193b23941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a59b440519cc27aff499971118e8fd208d896f782d42d13fef77620437707b5253d00126e63745dff73b8bc675e879b000000000000000000000000000000001600c96ae36e316cb7000c50f5252b87a3aee98a8eb401b74e86acb28f9202a7f874dc9bec14b78f1a8956389e0df1201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037943a748862e0ef68849a0f01d6c46012fe33fb45414e0927767927c4edd4f03b23088b6bdd5cec856fdd8216f5b5c00000000000000000000000000000000009f3960b95c71c2c955b8b2a607503600b38f60a25a9b3a4d8004567803cda3a97534eaa1c6bb3753b2befbd08d0d521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eb21b34f330481b3cfa17d3e34daaf89d733c55c3117f84f87b42f00b52cdc00d9a25d9e33b38ae29a069bdb1ddbc400000000000000000000000000000000199fcc646fc80a71aa6c0c399e23da824f8a9ae85bb0b676ef1cf3f182c8b6cdc9267b722b5b1aeadee8b9396af6d41d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a58a23f8b32dd16eb33935e4f350930ea43ce627fda908e8369fe819a222eb5939b7f7ca1e3966af6a01ec8a4800b800000000000000000000000000000000100514e87f96d999e2099f3f43406cf7ebad2b0200af38bf925db6aa4e393d466f4781a95a5c65c56d642ec2c75669431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d6dcb70b9abf4de386a036e6fdd322f961006c0e41920e387b7a5614ce67a516804d1d95d4920b244b8d301b8425540000000000000000000000000000000004fdc7e22bd53dd8c0682178c299964a26b225744d1397112b6630454191326bb74e18ae896f431a115f14920fcd34541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9777cc480c91a39b7bfec16ecb5aacd86e5ed349dfa7d87c20f966617a69809c915e8cf3db3296ec9354ab783161a0000000000000000000000000000000019959d41887cc7f245df9950614dbe5e058ad0688c46263aa930b8d7be6f685a15974e308388b07102aafa6c481d80191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d8c6cd8d42556f07d76f17e347175c2808cd9cad375c905d2cd49995a9c6bf98ddd511b67183d1659817a1384257df0000000000000000000000000000000018ce8cdf9cc7ea57766a851136b265f147758fe859d1015020c9c7b0c7152178da431f456cb996423e191bb5f9581af21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072cc6276cd004b85751f361ac83d78b81229dca5467fb4c478b6e27144618a8ed7e281cdc8c59c185fd4751b502f74c000000000000000000000000000000000b37960fa9e16662f389628c65bcee50107f850f3307be578896718003a0e292f4ba5c91162913ed28311be2b030d6be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e026e225dff7d20d43b1e68b5954f8bb501c667abc4160fef966a3a35de4b9407a8e540d16d6acd768688c53445392000000000000000000000000000000000e42d3cdd76f104bfdf7549e324836878a11832c56c3f41023cfb173c4c149803be2f179fea2d26eeeb68443991025981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099283e7e76707f7b9b33fcb838740538a4638e686562645cbfb4dd504d93074e2bbfd0185ac29546918f8622379c3f10000000000000000000000000000000002539b10a4c125269d0ee300256422899e48c4def2ae165df7d9f40607a3a7e65af2d2e3a12086010db80555f259aed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110fbecacf2989d31877ffe36fbeb537d8f49ae677b1e2bb5f1a02df45bf4be41957f9aa811c3ecdaf8f6d48a6b08cfc000000000000000000000000000000001507566a144a09cf5faf8725163cbec5fc6e9ce61b606a30700fca163c9453c7f4baa71e5e1d12d78b5a6cb92e011f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cecbe40d14feac2cc5a530b01543e2261a7c6432fc88b10e24d76bc1bf6e816c0fbe4c7f0fc19cf81eec889c324ae20000000000000000000000000000000007ea3671a42cde13027401f6761e022df18bdf59557ea30ac9ff3b33b4c37c236a10734ff0aa96a4ef3e24b2c5a599c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b654ef9a4cf80be2df1a1954b647fd43889c98c868371b195cefab2b44bb8ba65ceaa3ef40d7b25aaa3084592989a2c000000000000000000000000000000000a5c25a80823e96d7866a10abeca8cd60988f39e5c15494ea670767a8818a1f6134bf197c856b2558604ead7f14ec7571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022e77d0748c92298d0351f3ecd78a53051f85b370e803b3bef56f896a8c919e64b9f9bbe46163c5803e645104b613390000000000000000000000000000000011f422ef67a973c8548b933eb83b41a12993c0bca651ac4bde625932064b1c18ce2551a178902f7aca5f2d9e0771d4271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b25cca8ca1800f2effe7b73b26fac8bdb4dd52bab133f352556f0c4ef803b27e1db7efa46e0bbd0b223b61add16126200000000000000000000000000000000138c31a3c1dbbe739979cad8046e419d93ecc61f7af4a77cebac16f91c6d9725a2de02527a47522d8f8999f489f566b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b4541dda14d014b5c660c64605abbb8938bcad2a5a8ef88010be8f8c44ada7522eb9a926f6d4e15dff1bf46a63281e000000000000000000000000000000000379bd9b32cf5769365ec07a749880a08a52d90e6672e4f99e1d68994e76b124388a6fbd2fbec4acb6791b5f932fe5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f327ff6c4208423a09aa244d0bb652d58457d1da9207d16de30d5e50b119aa5834a981c740b6c81197295637701f2fa0000000000000000000000000000000019b89be5e0c619603e6dbc48d8aa80e22a96e0ffa8d4636033ebcd34ebcf051c99e0227ff397181ec26def107407ef0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c27c00a28372d17b821465bf78b475b5dbe2d5e352cee5898c4cb2df0e96c6870f9769084e27a5be3d94a1e8f3bcb70000000000000000000000000000000015dcd307586ba7aec7c000f7bc26ad67266f8b7560c7e61cb43104484f4ac2438f3ec20ffc9c4d165972baeb1e3d97601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959dafd305d580b6c5204b16ece2884125dadff0bb47cd4d385739da36d673a98ef3ca92770384e5154c837ed7d088a0000000000000000000000000000000009c62087e6d6a6f4ee5f9f85d246c61ed5050c8f4ce92e7482b5196c3d91b87acb22729afeb4640afd9a22931af79a851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001374226a3faaddd287c13d508116bc156e5dc9aabe3a8e43b7a4ba8a20073b9b857b29d34a626abdcc74a7f76dd150a300000000000000000000000000000000149faf8190e19640064246c2a669e061a87c235db16b29b0902fbbf6507ccaad40604d2ef4f42d7569c1f6dd5ec6c01f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012149361cb00324924ab1c537a295833cfcce0ddd985682545f5be462d9483eb1e7388bea3a687c4bfa5e3721c515903000000000000000000000000000000000b92a05caec1f1f8e8a19632d4e9e188d39364deada60764042d3bc49440d4e1c55f5e27a5c19c9bf4fbf1da5e106be51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe62a12a4e3c6ee1c2d9baa17d039cd706944ea8777a8506ae925bf981a04dfd0d2af8776fd9cba93b4fe98a8c2728000000000000000000000000000000000140fce64d1bb8ecd23164d7162a3e621b95f4cd77352b207b0ff8f024f244c43111118d9932ed8f494393518e76cc351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ba939aed0955f2a27b9d4f1953fa9b02c51140da6cb6bff23a1c6817eb98392d0fcc6749ea10b493d783d9c38015fc000000000000000000000000000000000a737980b50e4aad5492d2f8314bde67112576e07fa771f82af3c987a094172cabc6fc93ae44113b49b7c42a4be1bbc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe73bb5219780f30966f76810f2bcf92fd118ac83947946827e444d139e720d87bae7ea299ef4fee23968ae543018b5000000000000000000000000000000000419177640d967c11a436457f42fbd1111edf2b34831b0f3784b45eada7546f7eb49d51bafa47d63372614d4142bec2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3a2585f96f27e335db7b80479d716f758abbbe6d5ae2de8856e6dea0b09332a95040caa094af1e3a06dd59e047b460000000000000000000000000000000012c7467ab17344443e91ae8220576293be411e2298b528e14bd341a857674e0a7947edc5d909a8eff1bd232ec4c0ba6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e869a41a4c8c3a7cc03b60146a72c3b07eb9208a6d1ed57663f2be9230987323802969d4a30dc7c61a6dff04bd0a48000000000000000000000000000000000701fd43d4f9c3a8fa880ccf88a7168e13528ab1f9989d7593c10779fc1d9263d86e61cd99d62188c3a496e054293db81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f944f746e34e5c4340518f2c43a59d9d2966fb56970cd91901e27aeee3d43b35924995042d7edd139d3193ff6a82c8000000000000000000000000000000000946c7a80ff7690530bdef41c69e7b116498d75e2fe42baa7b942a5be82e150461cb82db3db8ad6ec043870130d9249d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013082e93c4df7903a6ebb9d3cae1553e7ef457579b8cafd705379b6299534aa1a289a5a1f946af3b03098b0977a6e9dc000000000000000000000000000000000e10cc8ac4b9ce09c91690a13b6b2ecd8269c622f27b7e03558139d7dc3d3a4df5d271d722a5338f47b0285068f03dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003721f1df3ae17b3bfb440ea29bd4518848935974e198d881ce3ce6a2ca38ec1066cb9bc7b76f02d6f3b5e27c192fa07000000000000000000000000000000000c5713077165428ffb53fb892df24543c3ae20dfc5f98ead0c0f4e7d9299ccd22f581bc67e84f26af16b86d4b1b679411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001764325a97862342a95fad17a3a56be14d320f120b310e3e043790cf581afc952aa5013d3109adc8a34b53bf2baf9b320000000000000000000000000000000012c0c53fd6b20e3c087306a781fa05e5926477fdc5667d68620d7506c8bb41cc50028c79a96d72577a73a5cf5db4dd861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d52efeb200d553e72772fe4003baffd1bfa8ab21e791447d68ba1a9ede29dd61ce7602455832ef04e100d1f33cc27b1000000000000000000000000000000000d8db28b044832d2ae490d7cfb1958f37c1e6d3810ed2be3280934757bc073248daf65da68e8ca282a121fe11543e7971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002baa028bfee4ea2d8383a594e0a8dbab82e195979c3da981278174650baa06296dfc845e3de7f8498828ce57312d3d30000000000000000000000000000000007a5063759d4bf602df5d1539eef2114e40b5248065efa678a35f4beefdd277e8dfb1b1f555bd20354f24f5c6c453ca11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841b858e4fca2ef8c6dde997b14e0f74c1ca1117ec3d4ea787f403c44cc2437b208a01214daa11be9a42a5efa7b5a700000000000000000000000000000000000e36da1ef990e8c6ca161a5d935e6d40d3cd33029da27558ee5ebad8646eb269da33e77262b16fd02ae759ff05a3cc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4101b03b3899603b7fe2e48e2d19ecf0d1bf3292ccc6e58d9fb7e5f9b7f4f8e58f33c5c0e28d0f0f5e6a88f1a2eda4000000000000000000000000000000000845e086f6a0bd9ed7b8ce67426c2c7d6a7535c127c88e2c223756e32c7385b52cd25d47dffe4f31d15dc659f251a0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017362e42f80fbe3d408a55ce25f7b39d7927e82d0b71a202b8c2fb05e7092a27bacc9a04ec0cec2448da08005e4f1fdf00000000000000000000000000000000079a8ea525e98d5ab3f4bd0b1e428ad8c2bde15e4c3b74d61258b692f4c497211808a46658c419ce3cd5173f1acde14c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000307f5701f7e90982fc03739cee3ea484529e0c88cbb34d692ac3ff7f4a502a05578b3323bf3aaf62433dd4f519803c00000000000000000000000000000000131a48875cb930e87f495a78e80e111030c3b13ac6089caa4853f08f54689655fe30160ca3951fa5de1b8f787b7917ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095a56aa6424772e757dbee4976cfd6042a66a37f42c1b845d0411b7fc7d359704ddde13deb094b42342834480da13cc0000000000000000000000000000000016ddd1dbb74bc38b9beb25313d78fe91a6d088e71b244d0586f93852eb5c9a79d3f810bb9e40e2496af71a8f8615c4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007206abacec86893ce4b7be5673cbeb8ccb80a1e46087472f542733c163f90a1ca524b448aadd243b6f9c7e214c0ba7f000000000000000000000000000000001570e0208b9adff5051da5aef7a8b3d404749ba7db925e5831a1bdcdb8cb98ab30436383edc3f35d9a257dba55c1965d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004deb1a6b8ac7248cda184a3dcacb67771450303d06be28185c26ff81ebde1dd49f01ef1963f9d8269997dfaf12382e8000000000000000000000000000000001200daddc288898e8ebbbadac3225ba68000779d55a049401228b4de1eea69394e7244a2f96ffd88fff3b26e171cccb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b9a5f9d1d00a5c9a13245f66aba3484ee8fabd4fed08ea3ee2846a8abb5d2e3e170f500b0a6912241ee26f82f8403100000000000000000000000000000000189bdcd1170a7eccd9474183b96a7905f4fa970b5af3ce281f63cb068f86bf255fcb9b7d282e3a12e31e8053c9c590571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e97979b8db52f4a8b32e74404b61521266049a54b5c0e5e16367641776b0359031302dfb37ea189438fc45e2f7a93c0000000000000000000000000000000016927c16874e70b9ea3ec9ff81862d62704ea86e3cf2fe08af235435e49a2fa868aaff66e975274dc7723147421844411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001336140109a3b222ef3a8ff1b5c43472d5afe6ad9d3730f53e4f442d54fcf72993554ac81161cbfd965b39fc28df12ae00000000000000000000000000000000180e2489700d2af03654fc0daf434e91f9c13e2404be49c308ef1c96140865b38b153383869ab05fae2445b6d16998e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016d756d504d51b1c16737783d8704b5c9b28a6c2acbf3361fe675a2a85b74ac38ff4fc6f1c50a74c5aa6f13df0842aa0000000000000000000000000000000012abbc0c41bea3154be90981f370cba3948c4615e94b1c5684327d107bcb98980282794c42570e2e72985e1db7dbbb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007feba989f5ca654abbb9c3f94e6bb2947044fbe8e24a5ade346bb8e21850b8d1f96f196d49b5b7a814e1ff18835877000000000000000000000000000000000088baf2fbebfffd64faa42240afb4052cfeb2ee7fe655f81ce5d90d5e5fe6eb795f7c8fc298ab18e7c7f1dd59c5dd1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b396bf889140595686d9cab55f8d0b5f445381e2598e7e09e33f011457e9479f96cd8b82b1171c4130f158fddbda8c00000000000000000000000000000000089481b1f774bc57db2c55b869e57021b263cc44d32d978fe6d164db60a69fd19c2196b51dc3c164ead9982fe59ada371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076408fba9c5def26d5c4e2d51d27b9175976dd76ca136194107ad2f9bd2884df7d5a388865fcf1a69d7d65b88390ade0000000000000000000000000000000019ca52a9f338f7fe53c84fecd2b7b0ba685ee00c0468ef3f95f20d59a8fc9fff48e95af7ccd0ad2b5d54fa2f8d26778c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ef5ed1107b0cacfbcd0ec4826a541dfaa58012bd36d8e7d1d263296d00263526d59d74c30f5cead2b21c295fbef09100000000000000000000000000000000134234abe4f6dacc63d81d72b4ac8496871ee241b273bc6de57ca7db986adf2b16efc9824ae5f1e3b86568ec1e52e0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130466efb332149a161a753dd9081cd125054e71a6f4c3d4bb518bd18a1dacdd15588961e3e7152a1b4a7d8f10425624000000000000000000000000000000000bb37247fd334f757255cf369dcd160c3c57c66ee59618f001df3dd82fa8e5f22f04bfb745c20e48a6b9540296f3c5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec50fe91297632a74949de95c6d9709753138832747c05c727cf3c762462630ae4f6b40db59f6989521a2047a0974e00000000000000000000000000000000076e8039cd188a076f7699f9146a755b204660b9ab7a2cca2f52eb4caf23c39c15190b90a9e4d6a8e9dafcc2e539d14e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d46ae8b44e23ab46e6ba794472664605b4708d0f8058eeb57251f7cf5cedc7892da092e7cee4b41d4086164c67b7ea0000000000000000000000000000000019d6acc78ce3e0e1b5a3112dc9d11e4b0d8f6d01b14df117ed2dda3f95f729ae97daa2b2716c31d6a886c1732e4e5b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601b821982b1d3cc47d27954fdf58a9d0079f3938ac8739e6881366ca95e925b185fe5807a1a084f73adce26cb2f606000000000000000000000000000000001566cf78b7f467cf593f6bc497b722374fe25c5add8ab1e37b0e7ca0a49eed7a05d8fd5ab5ce192f5feb3dd4e751f3c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f197ab1535890a0c9dad930903a18fe9182d62fb0a5febdbad360e3393628350f73b28fc02e875d6db20e28431706ab0000000000000000000000000000000005a94ec83909abe938e8e3b8a60c9a05cfe52983feaaedd6db606f794fa5981dd6dc45d3bdacfb8c475cd82702fd92bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a55c09bf72cdb9204fe57b1bc49757f4dfe647f8273b02adcc22a8cd5505275aa02abd5041da83c065dbfc0e46e47b0000000000000000000000000000000002dbadc1edaf5ab65dfed69d700d1303559a955850089c011e76bfd91a5e4be68c2633ead93bc55164d1b8778ddaa4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092d628b9b8443c0087bdfd3b3c1cf9060ea2ccbef3388acd130b6e85d382276910932e217b65d8280e0ea59ce2c32ba000000000000000000000000000000001906d266723fa2e1a7ad20c97c596be4c3ed6844696d3554e9332f2d7d41c2e3c7d47d88b9812722ce9ecb03c8803d191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f031599ba21cf15e24afc2b5caf796c7cb5c748260dd19a0230a934acd1e4f057e1fe5469d7088366f06863898348340000000000000000000000000000000018b3aa8d5a1fd73c39b23330ba6ce150d85e744bdc4eb1e89e79176e9c55b5ea5724c9bf64207c654fd61f363f44ad021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001994a4790df134ae14ae149786b027943fb4a222487d0700fe64dfdc47b9309d7d14c2221b75445bf0cc3d87325a14b8000000000000000000000000000000000d753cb5a28081096e8b10887df5f787e718be9e37a4f9f25f514015f99d56536953b0122a5e44d7b2ecf996845dbeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c788b4b3d572bdf266e1448d6f616f5a32190eb36cf86f7dcccadfddc6b8cef2d6e8176f5337986c1d031f52437b3f00000000000000000000000000000000103e58853bc4e821aecf81aa2eadff7621983d28ec2b821b123cf70fbb83735228cc917282e58ce1f69af939efef099f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000759e04cd6bfe63141c828c35b726af3cb300fc3440a7f53131ef96793f0337280d58ec44d4e9220d40b1ee4e28a472d00000000000000000000000000000000185ee56d6b2fb9b54fb0bc8de6c707cae9abcf4013c404f4e60021b58bc9478ed964924324edf02a3fdb4719f78eccb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a4034ac630bb1e6c175edb855574ba3a32e791578e0e2a37eb77e5ec0e33e19c5e381f589fc495262e266109755f7000000000000000000000000000000000fe4ff65445bbdbdde90a0e24fe3ae9b60bd114166ffdd96e540e85841d6d7b2381804880d61af92494742b538ceb41b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f52c043bc5b7061b70c32b75e6a23f5d60625dd5be63c4c0feb62b93476043c55981e5dd25dacbb4940fc49630fed0000000000000000000000000000000016c4dab374fdb507264de51e1c02649b4948c5350ca0dee8ecbd006c8bcdb8f6140ec707d5c77e86bd571b2f89db44941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017604117a199ffafdf9e3c0c601ddc97700d971d684680ca555e84ed5800a10a852c4438c9d4ef7dc278aa7e21e24c32000000000000000000000000000000000fe7425221fe3dc62b28c3fb17bf1dd1f75d70ce46a66cfa06fb49d72827ebe7521f036b6deee349c17ab53e382c87681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000895c511ad824039acd2a68662ad8861267233ae760121618b76ddd0331f85eff99feeecde95fb5240d76e6bc9d8652e000000000000000000000000000000000aaa407055a1894dd30a00d817ecd16e1380802b1e50aa76a08f1b1fc8b2e2b5e8b05f07dcb0563b75d7746eb563f2751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082913ce03bd087958281d6d4e925c3c4973047c7dc2aa06e08607d36db0c7aafc52ec8271f6052fcc7a8d1d48946e2600000000000000000000000000000000150ed6050298f26cb78c2d89fd247d2b03f6eb9f78bbece69b2558220288a3e98edd11e34dbefaa944eb3ecc50bcbc1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001220e91025956120ad3c0a1d195ddfb03a24f8295f7da3f848f3ada7aa6fc7c428a9e89b1f03e4c64b6ef3593f11b64f000000000000000000000000000000000f679e8346db24fd2a5e9c97c196e1366e96b9b2e3bbdee7bfffa2e81317e62edbf40aaea46f8edb33e0fd78ff30180e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aea4d6e8b5bc1fc871500e4403af57a39db7174e8eb43ef5400067d295c4ce4fb98ad8a583227ddc22bc717d2055a610000000000000000000000000000000002a91e7f14f3e1032f0ba54e65118f182c877de098ff265469b1c9c0e3d0ca2afa6cca4988b8f4cdc11e4b681e6d5b561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1b13f8a0afdea83dbe58f2d7358004df183103edf053d5a5b66684ef801d7e552b030458807f773418758b411a5f8000000000000000000000000000000000b53e8b1c0993fec54d82110a0d9f0791cdb45f507dd853267935125e09d8fc191c7da072f15231ea5570bcc6cf1375e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f15a7f2fc4d0e6d99431e54d3c1ec067e90964bf6da6333ae11b97067e20cf85750e38797f2dbe72b38a0dca0c7e6c000000000000000000000000000000000141a00e60a3cc05d4b01846fbb24740a28e8bfaa1229e80c28389b0817519c0ab1fbdb7ec96c94d4509450fceca3df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001480b1cf8cae6f1df6df5b77a5a018f32f5990fe2d9143ac9c6721a63db804ffffdd63e360bccacdc6b5f91f941f9aad000000000000000000000000000000000d6187fd6d329a2d2fb7205f6c69091b5e72eb4d693d7b44be1894174de0dee2400a8c93c0f8e30a535b408ace483c641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001232a3ae2a9726895a150c79e151e0524e32e4ab21d2e3400752577b92c0034a51f563f1b817562838fd5bfb6134e606000000000000000000000000000000000212e413ae3de9b098bd15420948c85bf048547ef678c1a28116d5672a4df10965d6a68eb388d6c1ba6786777d8dbd061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197846af412005e71496df79f0c8c35cbb0f0be4c84ddf0928125ee0aa21257464c5b24bed0b8a306f85d9383b1f6d4a0000000000000000000000000000000000084999a9761157a601820ed61819636e5d4174c2e02aa3d442887757daca735091a755747e9e104818ab43f3e70f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000470f3a35a1b8d9a0fdd988567da1ddbce8ec0eb777527f29fa94c65fa07250eac6facf16667f7ed3891458226ec4c0c000000000000000000000000000000000c750070aa47567357b042e664595687a7a9114176d88c141d035156d3f9a41bb43ff43e16574a16b03081c1286f8cd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040a06b4b14da7522eee96fca05fd48f0dffc4c7529f67c58b188eb8b1d9e2abdc1d9118fed5f8bcf5c533be105ed69f0000000000000000000000000000000007c17b89bdee1a4418099901a65da0325a3203f0e180609344bb1f647b6c9745be8bfe3d7dd90450074bb3f8b8f431171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140977dc235cfa7da42badb6dee5b180337d5be4a6aa06949a6f3183224f4eec24af01bbf1b128b95fd3b3991592973000000000000000000000000000000000fdf8cea050130ce6baea53d27156533264774f00753785f9b66aea05949879f137000a2289ad657ac97832b9779e2481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32f3ffa905b1cacacde77ba1dacec89528def3c42f8b501aaea66b316ced3c7b632a1c5a45f9431728c060e06c092900000000000000000000000000000000129c84e748433bf402ab0ea6ae5868064dae4c09767ce4fe8b3064f0a1bce94ac547e9119f3228846a903a3c84551c4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a535796c5cd1683eb3c373ec66bc837c2e37fd06015c4201f8fdeb2a4c3dac307c7e8554c6f3ed2d82d051800513d1000000000000000000000000000000000e25dd60588332be0b546dc7e16af828ad17ff9132c1980de7132d80a76c382d7bc69774818297044e0271f2b6028bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001417ef898ca333654e342827a80d621ff18810661a609ea6cbfa7ef25001bf694e390511d1c0489ecac8fcb368a9db380000000000000000000000000000000011a193bde26ec56f6583d76f7ec43e2cc1ad86384e3d5c9574ee0b7a5f0d2ee2d6da1ff5bc073b696ecc24107543caec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ab5b6a5e45ef44620801c0726f3f03e072888055b0bd7d767a9fbf4760eb70a959eb474c8da8bcf4294f22cfb44f7000000000000000000000000000000000dff76fc074985b900720051408fb3bd0340fdd487d5cf9a7a8d146fa6b3a673d1fd453cb4f7ba06a167738b9323acd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c3508ff0d3925b153cf4f37ccfe0a042f042d5e8e98f1ad80d1607b1ec74b6a98c09d48ea48f19b96f2be06479a18000000000000000000000000000000000fb5743cecaa42cb9ba6d2f4d5329c672219b9e478c691879561c00d4ed801cd23b1329f1e115030cc9d3a2f2a6134801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c37917aa38aef28855ac55a34c73610cdb8c6e0e4c8e69e2fed1af5628931e22e58c7b8e356ecda1742ccc4d61868c30000000000000000000000000000000017643bae0b0cccc2c94bf0ae59802fe91b6a04374bfe3f0c7874ce435098d7a091fd6607e651711d5b88ea227c43a6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000685570349adaa9fe48b0e12f192e28e76573c86bb8343244f644f8124d2b66be6f51105b2641d8d6634169802bbd630000000000000000000000000000000007373603070b47a89660674e1ec35b57472343c4a47a876fcb83e7042320648f8badc47a6ce6df84a56616218209d3941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000417b236fe09854fa8b6fbd304b450674f22c6cdcb21cf3fc6c1525e10a87ec296683dfb5be661eed1d7742217e24055000000000000000000000000000000000569fd7aa0ac0588d44c06045469cfc11eb4c8fd352c0d9f2bc613d4b2cefa642cff9e9ebdc7bcdb250ab8f00a7db2fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d59699041be95d8e3e5d3b57163f87eecf9dad15f3df46f2eb0e942452bc7bc19ae8a8e02db27f630617a662b01e7f3000000000000000000000000000000000108be5b5f52aec359bec1955b5f2c16181c0da201db6dcff2b86cb002965a2fb5b0b7cd687fc81073752adce855749b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029e0569ce7efd45f96cc3c0a5e53da1cd444c3a27396d31eed14a60232e2a74442f3b6ddba3abbc1947aed187ce9a210000000000000000000000000000000016ceccbf33d7051dd100b782e26642de6a995d30e2fcf659f488aafd665baff51ab2e3242963a6c622d270d205e6df141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004667a4fcf3ddc6b3fd2cf20984dad32840c5c5d412d78bfd9e56f860549d8782ef07fc45b40d28e4c034ea1b17a8e26000000000000000000000000000000000a125aa927092dffb9c4fca9d6f874654dab8d7838b7b7b10825f763eb6767fec8f74d4614ae5eeb43c8239560de9dc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004411261d3faee96dbaa59988eb64e7f66095bd1bcbd8264fdb291658fc8772daee67968dc98fe8492ad3fba6f72f4610000000000000000000000000000000014ec1fcb60acbcc80c9aef300e426d3a8698c30ba75e854451799434c38cb19bce1fb1adbbcf33d4e19b1cd930ccc2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016dae937fcdb65e634bd24860def5982b112b750b91ab0a057dc13aa2d5cd3ae6cc45014db447bdeecd9708f9f91579f000000000000000000000000000000000f3833cb40cfc03e00ae502930af502944e51ea4ec3127dfbd9804565a897536d0d13a9a26b3abf3539d37d5e49bab741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a895d2f609a062c21554e0874fa41d8a21ee2c115441bfa50985df795a4ef40bb502600d9113fc00e653cf664678bb20000000000000000000000000000000002e8c9886cf24793aabb82a57893a985f2c0e590df6f30d7f0c0a0e124aa57c52a0833b153ad614335236f2c89e794971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb0d59bbaa9737bb4c90b1b5e331a09ef9d96e521c1f1ecc2f79ead7c5059f1f391a83a671f496199a3ba2589addc8c0000000000000000000000000000000006e541162a11f0aa7fd4f48549a83a3bd63c5eefefdc25d3bf04ce81f86d35b162558222ca0a80bdb165de21e06320011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655ea6ab02467d1c65c4716780c9f22f40782b41ddbeb6da9239afdcce220e40512cdd914d31d7ad7332248ee783e2b000000000000000000000000000000000d9e931a296526a99d3ef08dfb1d4775a2e55c836bb0e86cd3359efcf67cf865aa531a8d49e143e9086fb0dae3087d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a281a4b80cc821fd1a13fe5a2e6ce0b5370777451fcffe8431835f459b31d4074cebc933bc24e19d1350f959a557ba30000000000000000000000000000000019b9fb71bd4b7a2807a52576401dae1aaa1dfaaed062db9499deea249b2fbab0d26675a8e8391156125b50f6dfd861c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000031d083dabb84d61f57cf41f75d0b378160dd20ea659828ca5681cc82f66d36321b16d4db29c7603a5a81723c253f970000000000000000000000000000000003dcb50264ba8286b8cd0494bb0db3abd2703a9da4149249431271102709b377b958988fbb3928a1d666a6f963dc46851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e6601da2dcda7aee8acb6fef2150899275da9a44a84d3a5db548a42b897fc8e65690f7c38536345df9dd618068ae60000000000000000000000000000000002d4681118aae618a15a005cece766f00054105cde059d419fdc7b62cfcaf5c158962885913e12eae66917e4c06d3d641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017011b0d2246f43beaf8dd707d6881e4950aef1e08c38e08cbafcb2af7e8ecf4940744e5353c37ebf0068a4b8930d5dc000000000000000000000000000000000b34ecd6bdd1f4d2a5d1d8bf088abdc4be0892f51e22fcdbf1f3b8a969577ec6b14b6f7e4269d6ea014f2ffd8729728a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f8a4443e250c7fa5745cb3e719c48e304d0ca344c22d0226d2ea65e934de8898f4ac7ac5a643cccbde9246c8ed8e8b0000000000000000000000000000000001aea5be3c7878155a5e43aec8b86e62757d2a1b5211941eb2efe5346ecf7e9d61f3aeda9526276cbcfbd0251d5cb9941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130df446b9bf740740f503e9c3d8c6f3e97333e0527904cf70f230c020c7a6ea6e2c52ef334391177312f0099c801bbd0000000000000000000000000000000009d8f1e9f87e13cab8b5208de4833d870158018e88b86aa380850b0b6aa9c69bee37afbd7f25631137f6a068c9d75e6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012a98fde1b4ba46073935f7ada2666859038e7668e3023d8d5471cc6835c9d7fe56d10360d348e279a0a9089e08d9160000000000000000000000000000000005063c18a9bf161b6d7e4c11fb7f774b48c1737d8e2e7258f655a7f691995bd5c7ef9ac3bca0bc27586fc636a6753e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fbb522ce0dcad916b7fe27db8210bc75132a811ccc966fb1cb10f839291a4e064df6db0af560bebabb7f0dbfd6de6c000000000000000000000000000000000138004922c7c2240ce8a221eadc88a2dbc5b41af887da8eb34ac9caad07a5a4dc5528becf6ea955fa23a0a6fd4b85c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168f7c11dd99679efd54b362907320046e65d1e9b0f2653f6b4e98a2db621c601379baffae0c418ef6bf41df18c48cee0000000000000000000000000000000003d1e78881301a415182e6d1d29999ba1de23dde7954e6ce1b7ac7e68ca4ff324adea9886c41bcc6d0e5af0f1edfbd181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e84003be9055e3775ae2eeb9ec97602156327711008bc6dff034a075294016d2a6ce2a40b26e1668678c25df6b7022000000000000000000000000000000000225d84753141fd56e9be6e4efa1f9621cb95e6ea635fb3697e5503954db3699b24c8129b7ce8323badefad6c025983f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005580465f8f9ba4bc4060d856fe456a88ba432a7c4d5e05e999fa877292f4adb09715af85bc1fb2a7d1d543453ff8500000000000000000000000000000000015bdbcacc9143c4fbafa1255144cf0e07fb826117d4cb0b24b38f3b60f482fa5fef3b0d9ac94c39d6d22db765d89c40a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000779171e02bce548bec3d1094e41795803ac275791b5833bcc85548e1054260e74bceb273aa583f2b425fd07c9e67540000000000000000000000000000000006e7cfe6ced8b9cb867ab34219e8d6c12ed27a68adc69777b34fcfd00ab9699cd45fc7987aa8587f462f680d6d6ad6571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001904cd4d37d69f8345a72397bd0e4db961c60ec9c5cf44a49fc76c0ba468078ce61352cd3bff784620d3beb24353476600000000000000000000000000000000140521926bddbf07547b0162cc6c57de98fc9a15686a9de12f86c0a81715183e5ee9cc7ec2149665aa1f77fd9baa31381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000366bbc35b451f297b8bae0fae2ddb6f8130c89a297ddd4adb5a84cf83c48736db6ff814611a51cd9ea02ffd95b85eb000000000000000000000000000000000cb73fdc813ea478e07a1f88aca3e17687fcf83cbc926fe4928a3fda683223df1619e2688a495707b819a43cb6de1bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000501b3428c2674ddf7e7342964af73326ff93528d137a29c976cbb95e150110a477bcc6a517399eaffe8b185517eab8f0000000000000000000000000000000001f2eea4573fc994596154a1c7083cb26b8c7b64bbdd2c121eb90f36b25caa30d766a2aaf987961aa378092f84d42e741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363f22a2855c14249a1f3ef321fd39780905982d5c6b338b22074f2497b970a82241e2b8538170a3927d5d428440ecb0000000000000000000000000000000007f672f968b23ffd23b79929b0e16dd41d42fc97878e9467506517b31248b2094faee9f8605e6debe0bcc3ef9908b6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170b24df30d9c6ed018b04f31e02fcb07bf7f89ce9ba5f1e2b0f6899dbe975bd60266f5e8240fc130d18519384b957ea00000000000000000000000000000000157913061578ad1cc083ac3d2decda6b2effbcff260a802be3276da9e9825f8ba23a190391d26e9b04c5bd1130cdbc201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e1e1f545c26058b93dd5c0ce82759aee69f928d06ebd5519e3830d08f3fadaff436127c69bd9d03ce949866eedce900000000000000000000000000000000098d4f3fbf6a6db281f6262ed2bd7e2f7af47ef2e77f2876de489bd9ce3b8b241330437a2684310c4ccb1cc2b28119971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000496fc523e07eda6a3d01caee4a9fd6ab93174222f9ac3cc62207d3fead137608435792d0c215d7ad0434c08b4577643000000000000000000000000000000000c3c349e1bdaaa6e36300610899762cea2905a37e5e72bef8bc5b80c411a549642c8fc5ebf0ba47042b69ba4e5fd60e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e9d56e526441f93993fcb36470c12c0b579b616bcd5c63e1385729277a6a27c4fd14c09f1e257e032562aba8bed4070000000000000000000000000000000003187bc57f92772ac2438c51bead0219b5ec2886fa0a780b0a699f345657f98b77fd6cf784c131cb87c04c26b2b236741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cac711712f8d16422c70dfc3c2b88984bd47be413e8002466bba5460c8fbdb7694e4980d500c05ba5f110768b632370000000000000000000000000000000001416292bfe461e0f910e821792cd92820c31628010335b94b91528cf3eb18fbe87534ff489cb4528fcb2285c0fde77d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010020bf3d218d9515448fb3eea708191624aa0ff10ade36e6eed770b71fcafc56f9d386ca3c6656bd7edce08087122a500000000000000000000000000000000140867bf7105643cd23a030d547ce83850e1e0304c2274aa467b172fe432bee2ac082222983793769c0d3804b63d79441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6aec9d7cd3f027dededc638c4c6b3b2a7958fea48bed0fd2bc675313e4d2ba12d9187d113bca0850b17e20e2e6b1200000000000000000000000000000000021656c781b21b7383c8f90b1065745cc750f056a4a20610e3efe452a28235d074e247fff074fdf4ad9718497c10e3701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000993cee3735705aaabb0eb7b0c05ced270af2559911929e4601729c283952b5399226d6caf8018414db54a61cd814dcc0000000000000000000000000000000004f8ba2c096c1fcf792f826a7900dd48fd1b72f4cf6f260941b1f4d4c1a2727b7ae30cd274309da12f092ace6b0f565d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095ef9449afdf574b92290a955bd0e7077104a5d94b8c17427a161a47e3b970af7fed5ab3e6fedd961c6d11ff8ff671d000000000000000000000000000000000e2358fee0e7a559848d30d1bb3f8eaab926d78d11ebf05854f653f6ccf8b9ed8a34114b881207ebbace86577b5711541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abf43984cbcbd25ebbf9b5c5686be803d2baeadbd4ac4e769eac118352d21c331a86fda6fd4128442009989206706620000000000000000000000000000000015f80a0d1dda56177a48834833e214824b99c0a6f408b4e8e99355b499fc4199387b50dbd61447ce08633a9814c5421f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee61140d93e426376c13cd8a8fca79f3ee99bd601881e3b8d8a825601f1b8f1818e011365f8175c26b66071628539bd00000000000000000000000000000000193dd261d1482c0579157b4baae94c9c7b87eda36fe5e8c906feb7f3cd54bd0851822995725081557a35557cfbc10a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042435457b5d2d7d5e3dcc6367842a6a88ac7c470a9461c47780c7a5ce4417e0038853ebcc9fe7fcd2722df539a3537e0000000000000000000000000000000017f685f25839da010ca2e599586636dcf1fe2d5666b494c228994dcae8e1f3b6c74bf0c8110f4644cab17e6590c0cee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a1316bf89d5c10794b2f1770621bad1a6e94933fda91f9fffb7fd58cd79414e5f2c3ff9c4ab5601aff27bb9f008d1d0000000000000000000000000000000014771ff9753521e4dab0d6f0498ada6621b64eb690c469bf5d86260fe105f68b063661f12edb0fd0f66fd4f91c4ae1f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6cdd467c5524e1c4ed88e8ca75bc3e00a0c32edb01170f3606e6cb38800a7b751e0824a5cd6c92c8a6286f1d0edee00000000000000000000000000000000024c22cd170c400e847ac665575230d66c47f2361a45ee9acc08c7ff80d99266ff2408bc1e341f20eea482b92e149dc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b126a68a45af7dcca9fadd40031ab4a8b92707518bd389781366d589dc4d9491d4293ae3b2cfcf5d24e59c1f2b9d51000000000000000000000000000000000eeef1f0c26c47d8ca8d52a3474579bc6e0bb3a845c81e9161281ef3dbd80384cc171250e134144894c30ee49b10c5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a576c1da3e5fe21d419a0530f3d4444db1e2c067fad0a692fcce400e383f3cb0fffdf1993c06f0ec337d93e63cbf13c0000000000000000000000000000000002824120ca2865d634e89f2b5c32a131ff9f9efc5e226dccab602dd37d7e568b3ace6b8c8b9f55e98918567483ac674b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043d7e54205465d0cce77a05441f216df5484fcffa68a691106136554332c8a9699ef4dbc90917a625f9549e5ea08807000000000000000000000000000000001769ca9a6efc8f69e947c853416639055e24a871f1c1c67377db631c4bd23772785ed4cd667278dd153973b81f0efe251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f4ef83f425e13fa82d5e4756b176fc2f2ca2ce05ba273924d4bf282a4b2e9fd7f3918135a14e9e4ad99f2b66f45f60000000000000000000000000000000000ee32349fa4ed2759ed7260d0f75798263527cd741bc3e16a7ec8b83bef0fffef25f80d31ad47603cd5ad44ca1ec1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe087ba8066bd7f0f4e364875502e149c8512b684cad0b60190816e1f5aab2a7af75e0bb11663070620f4dab0b892bb000000000000000000000000000000000c8cce3300bcc43ed7377f9cb97d51d2188b76a0c4eab20c884da991014d030b21391434c27824553c801753631376be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006441569fd4eb04c729df0c562c935b3d1e7ea29b11c39dcd92e32cd4a793dc7856ed9dcf293490b6c66f4d5ff7cccb4000000000000000000000000000000001887927525329ac248430e2f6ba5abeb1f5c285f1564d98378b6666b5501598eebceaae66a126f57562bafdc91bf59391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa13c71ee07cf927940acc09be245cf9360bc3fd1cf22d049c0596faff3d879c0089b9036226ef1351ed5be266170ba00000000000000000000000000000000064a699e9ca11af818e9fe6f4eee0985fceeadde53ceac455c7fedcdefec908971641d91cf0c845b9f14d0720cb0f4a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109f80df81131f7542ec6e7930ae323bde0bf23c28e8e1b9cd1e0550d01964616bec75f90fc620ff4e47fb5a01095105000000000000000000000000000000000ff16c51cefb8b8930d135831bac5081fa5852993ad525b81a62db21b5535f6b6989c7aa6e7ca7a17f8b9aaababe5ee01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9ddc36475c23781995342169d2c0b190d38cb1bf4e9db7d89d00f0ada52b194c98ee9a9c520acc5b5cd3f2f5c1155200000000000000000000000000000000027e3f123c61e162aba9e639b0e6af44a4a265885d9fa5527f9d0966f6b62bd941e75057164687aec3b8d51ef52fcb6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000704dc6cd2ae310b3a8489cc0e00b3a91f928e6198e3639289134dec0874c342e8a68a1d490068cb955442d690de431c00000000000000000000000000000000075a2cf0f900d2d6dd86ef7976d6599c1ce095432454a3de1773f02dc64bbb58b6a744b5a212e5b188fbc688557367351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121aca798f99bb029fabd886070db0b61e81ff94764ddcf8159ba87ef8a4f36f6ceacf3a6185c53aa1f9d93a4bb2b91700000000000000000000000000000000126cfeacd1e0834c0aa4ff136dd617de714cd7afd7b22bcee6549a97ba539de4148271d26882f422f308b698e97b7d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d592947aa79b870f2e2cc63ca07a90ee00ee3d515fa312f0c9a4131995c3e2f6d18525e0fac5b485381912d1fff87000000000000000000000000000000000166460bb93817ac666615bd068b49c30aeace0dbb0048bb909ad5dd16fe601d9508b12cc06c39f415357b676c31c7b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026b4afa3430a07727537e376da8eb5fd6fb3c607841a602da1453c7dcfca7cb0b32876cb649eb7f4e97f948fae2e20100000000000000000000000000000000186eedb37b465aa682537b65fa0d25433eee73c7acda818cf46f2b8d68c969f56bd3c6a95be9fda9f93bbd53261a41bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004c754f93fff201605620decc02ccc509ea6b6b06a8b473a1c0bb1fbc5b2c5bb9d40a057ffe7bb7c36e667a51c9237c0000000000000000000000000000000011f6d16e29d6214a3577b0d4ebff3c737945fba79eda7ad5dd6d3b3a92cd7c1bc3002eca642c09d60d99c5884dd7e7ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063dd8ecc3e2b6e07296a2a6a7d844693d6a8fecdce3070a43a43c0fdf132e11d0d1b3d74bf48e62f58c1bbbda52bbca0000000000000000000000000000000019862384b8ee86707d454c2fe3f985b99f88d5ccf19dda994a8a4c3fcaed407bba8e2979344f046d02f1fea36ce26d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d13b8545eafa1c274968cccbfc3a7ab274d1e798b8bcfa245863e17891694515396d2938309edb101ee4aa42168bab0000000000000000000000000000000008ea8ecd6b750e1427451afaf4259a10e7c0bd9581c359d8b515585c73e04dc302c0c9e977e395f47c26cb086844b66a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010821a1369efb387af7a5532ad1203bea209ba365cf554ed61120437920b1a3e5f77f1182d54ae82fb38c5aa95b5599f0000000000000000000000000000000009fe11718f6f05410e67d44c0549841cc078a0e5623f18f193470d64ddf0143eb27feec8548b1949f46874fe90720be91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dbd92164c7ce18fa5c16108b514949bb522bd8fc12bee4794736e3c576794fbb3b75be219a63c02657ed9f280574700000000000000000000000000000000011c7539b583d223932b48b45a5816bc450a736dc700cfd510e4db303d6175cb048a87058870958d0e6ce8f09e20368631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c3db43e31da03a6d0da7529d766bf2839964e7971347a40536f5abaaf91525996628f66777bb7465872645ea0957af000000000000000000000000000000000875114158b4eaebdb7581a90d201b34463df9a87464889244f005fac6eb816a55f6bb36a50664bba790eccba050352d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000373a124a53ba5e7ba5296414be02ae89d7425ff0ef934a2a6d4741c21ee4437c43a23f9cfed0be7bb314b056d95c7c000000000000000000000000000000000357eadea1eb51402c1824f61d239a089788cf8e1e1a5bfe0095d49f7f266c23ec98a9d7584cabf375d1423bf34bfc421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000579da742878757df9c6c983596e491b0823c339e61fad7b5c6cbd735ddd2188e46b16b3ce0c58e079ae8e08eb205c72000000000000000000000000000000000d5b053a1637aa80003dfc2ec1c99b17f2f1e10b1589fcfdc28cdb382cd300215314095d6649bb250272be6341f8fa3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010519ef34482a1fcdf0bacee9107dbbf778614c266c1414b713cf1e955c14d4c317434eecaf683d33caa399587993d0a0000000000000000000000000000000009d72280e8698267b1483f5f52dff05c6e91d02cf91310c43ec52b9ad202c1e985ac9380bf387d9a587225630ef226691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110c0043405e6d957a98fbdc65e8c10e6d82f30b5642042a5b2b70b84114864eaac3fa7371727a4dc278d49db5390f5a000000000000000000000000000000000406b258f81ac32933d3f55cc6e313871794ff14e7e1d8bd183fc1589926e922de4496ff2fdc1e57d4945cbe53c190bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002bb2697d79b24540a51f6d1a6a04715cc67a7a052752e600cffd782cd3bef38e0a958080e5850c48dc1a3499ff623b00000000000000000000000000000000099f89d6618fc7dbdce69f884965fdd5e0bc01f50d3ad6bde2a0ac61729850481e8281fbd6799e02b2730c75eb35f2761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c96eee9a5c445a57f6a39a308ed32aec39d444a50f2340750b741f01d68adf6ce933993cb4bccaa4b4ca54262f28a800000000000000000000000000000000117abd1de879221b5b60eded5df77e50c27204a5e5b78f4378621e39c77d76ff45d2128bc1357a1c7e44b16efee0415e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccd05154b487ac2b73753b6dff8f6d46f2457e168ed23a8520effc8aff9ed198348f8de359a596d9e1ecdf3b5f8aa95000000000000000000000000000000000e00ffd26fd4fc73b78ed95a60dbbebe9f04b6313a62955f612e3947769e3a12f70c38c0af64bbc9ebf77f10d85033351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011de5d407eb9f38341c61e0eac0ffa54d063f08fd76590ed69f06af816ec29e761a706676a66124a7758b44650a1142e0000000000000000000000000000000004b7f49b4cbd30f1cea3b62b25b0fbe1f1333a9251a7f8f024e50a2e55499351bb94e14a358099d209262dc264bec6121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019ddfe05940e7629f77f1cbd5fea4514ad4aa25ffab529954ee7c9d7cddf6bcfcaa7ad57dd61a271dc5771599d48e58000000000000000000000000000000000ce428ed85e6b660b65d9803d4d91514b1d1e9b56c18b171ec41a540ef512c306e39a1383b0ef8ff62f266dd33d9b1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000528dad1cbeadfb1b1012130ee3549e189b0df22b96b9d3abc7c3b95d84e13449528b05ce9a310132958fa907d5eeb56000000000000000000000000000000000801686e9022c9e5b8843f69451e3dc1e1117262226b6501af10f38a66fb0307a70e12be4eb1563898f99039595be8aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f42706f314602a432c40a7ca51feb150bc6b38d514594d6846bef8fc61f84fc23362f23cdd2a9ef61d0a671d917050000000000000000000000000000000015d914776e0b7c827fc9ce86365f92c6d4993d8d6843c3cea555bc4eb82c34ea33d65f3cd3e2b15ba156093d4b5a705f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ee9f7ad9673c22c5a5d908064cfe418e4b28b68a7a50cf3f0534d4e9f8d60d1a8f6c6cbf8a74e99ca97bfd602acb7a00000000000000000000000000000000027a9e2d1e5adbe923fbb8c35c039afcf6d91d31a249a36c7425d1e7d626adacdd683c66bdf80f97b8f231a3c2b901a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673a72543cfab54492560aae86ee55e7149985bc466a557be38386ecb04a52f319d1d96a8379f08bf9020d96ec8a988000000000000000000000000000000000aa32345281cac1fdfeaa709daafa764838404902285053fc4606b62569c8d1c59baad7578ebe8596da94c8c52e78cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7b2c7c4817d5e605e6bbb93b16db551c865e31795536daad279a7ece0415589636813c2927d927cae37b535660799e0000000000000000000000000000000011f892351555b1237b0ee16391723ba3e31dcf5c0badbbc2714af27397bc8ced3f24cfecd922bd287ede8f6fe5aa311e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f965f3ed7a123a4a2dcb8cda707d913384bef6cd1006c0c3e1649e9a7f2c0f7191ca9c61e105ec2864c9ca1db92ad50000000000000000000000000000000014af0007ee0136c93ac2fe10fb9f5887d21a08ecad1313d0105b574aaf41a99917d27113b09db792dee5c19281bae0471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013da69ab41103c2e1594d183481c619494de16c50d92d86a2f1f5b52a52bc85383d5d2892cabe1fc14ad1be5e44e08cd00000000000000000000000000000000101707b1dea772c90f1331b9281dedbfac38e229a7e3c8a49d636236d05cc085d2b25abeefc29c045fd739ac6580d21c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001208c293a83e64bfe136afa87f67728a364cbf18a2120f08ba4f14eb90b561ca3ef59cfd91a6711bebc43aef2fd982fe0000000000000000000000000000000008d079099e412f4c36abc0f04bb69b288d8202c2150ed4501edb12fe06291c12df14dd6a740887855db7e49770da58ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013db5abac41c67e843b97e7e37cb0739b61ae9b3eef335d3e9276a09c6c371ff7966cfd8a118d357c5b281c289879c8100000000000000000000000000000000092725da8b4c7c04097cf1f1cb9c79f50e946ba8b621dda62b33135c29d6dbd98677b27d0dc493311739e40a60be2ee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187944038146b034f10dd304c1766de8b0ace0751c92d5dcfdfe0433e209b2752b36df0d30c126abe1ccc03c83a12df0000000000000000000000000000000000de01a494677f435ae434ca91ae5c79a187b160cfd6896ebdc584b294b01dc08e2ea530c36d4aa22e41ee1dd1e9a67aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2ee1169f81a81b890f9c4b6d695ad02f8ecc7f2b6c40f6fd0e36b7999dd92bf7f5eb82dd4aa0468f5c563d81477b5500000000000000000000000000000000110878fb4258f9e20189dd4f28356bf37ab9aeb15c534b99d312770a91d0c60f608009eb74f46c50904c6da9a5c3e3041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000483df709fa7a1c34e92d006005cc77c6ecc41cc1b66c47ed012a4a277eb383f5d8187071bfa2e3780980810f0b7648300000000000000000000000000000000176571ea0a2c3f06b6606358974db9b1c08a901fece4505c42020ac86d0d2f7b1817cf5a554520e198ad13b2a28741db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137f0a0e188337f1ef76969a5ca87805ba7e9c3857f74a4ab08c90ab9c23455bd968908e19735e63382303bfb2d6997e0000000000000000000000000000000001c9acdc427b5691fb1c57ef6e15a0e4ee91a54e6192714d5648e80c405bb736d59b41aea377334ef26d5c4a5508600d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001852ca5cc7d3314a81ef7b46bd47375304c1386512d2d8490e826fe4079fd875d51da2405ca75a8a68aa7c4e90d1d9a90000000000000000000000000000000001e7e572f7fa35ff495b1dc612bccaaaf77f4d86698b5d3b6e977aa811e2138b7a343e858bf2d437e0f102c645f6c07d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dab5d38f5b4e87d755e66f64752409a783481ce42dbbba85eb7f0df88bedd8e746eabbeeb13096d5f742d4c9df081a000000000000000000000000000000000f88200542ef65e322adcdf33ddb2df1952de97aa0123ea076bd67e8bbba87d16808db6900c6f6af68be20ce601f88ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a443fc39ddf1e9ee0f5d148b2f46a4243611c0c44acba37f71a2f20b55be8629774154a046242c97acd8c759dcb12370000000000000000000000000000000010505cad2a0766080b001be5be4145f14dc2a86e425ecc2617e64ea7312d8538edd914c56af128bf52899cc099495b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8e3ecce7e68d8eafcfae82be606ff2dec4c27ab0c8b1e7afa6f89c3c8fbb429017d5ad8bba808cbe27eaaf04d1d37000000000000000000000000000000001992263c3dcf27a9adec71fec8ea8c5737076eed05427d527d06702ac822ae86d117ef8e3ebd7947a2770ea7bb57c6da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0056fb5e9e4b611e6a8c126ecf8c60fb424d3722645d6bd1b526e7073f41b2d7e05be35ea88a97044e1abb4d3d8e790000000000000000000000000000000004318758af7a9f49b634ee651ecc69ca79781103d38afd8eb75e882c7b4969c8bb1b9f3111a030d1e14e174681f990fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e70a6475a06d542494b703691d1b91fc6b593e9669b5d5ae4868ef1181df0ba92f81ba548c72b48370467975fcbb82000000000000000000000000000000000ccf0c053198f0af003a342770391a6cb298d57c418ba6b18bec38e9d00a91f1e985def08729085f2d2ae10fd6b682341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000723fada9e052ee9e8d9095bb98771a06b2e579c5fc20aea7df41236a53717f4c5b9d68a4278d70cf8ffced409ef737e000000000000000000000000000000000beefa1c536ee32714c391b6f7d4573e7cd239dc6e749c5474ba53faf1341cddece6e3ffbebd4f74198d92dda216124a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001852ddb23f3b7e8f562f80ccaa6bb9b3d5603b029d4e90dea9936421d5247b254360e72768f510c66b5fe836e4494bee0000000000000000000000000000000010c9002c21cdc363f8fd78907b1df78bfb42c8b0b98fa95f9561ba1ec512bf1fc94f4d096a2b6b48a3ae9fe981ee5b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f4d7ac401da77522695b882b49358c64636a844026158995d9c8df9cf1b10dfdb21473d11dd866e0639af0ecde4a67000000000000000000000000000000001875999c398f749ce8109dd532161069623bc22faf3873dd44a87639e92ab6c932332b17dbe3dc7f470c8f9173b2ad0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb9a5f7ef6a77d451855850debba0b4fbfeb2997b39caf72906a7a488e11fb8ccc726438954a58f04d3049719ca4fc0000000000000000000000000000000005d1dda4ba546015d10db80d7c1e10466ab8ccfef4f9c4fd978391fb1250c3f0342a61249561011a4d74c5a5e10f0fc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122cdfad891523382368dd1f9e28e1e6e857f70334c3cc05bff85cc21bb43dd3b471378eb00464567e143eb55d12ec5f000000000000000000000000000000000343db67e4f54c4173ecdf95d4ab129e9695e2b32e6856e9ac3d2c544a4f64e5dd99f73da4a235ba5e7e944db63151621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009df2771e9ea0b07867e494c0cd34eb168693fb086047310827bc0a80107369ad5d508ea90dbaa50f788b3bf87dff963000000000000000000000000000000000ef9e3771dad1efcc30c58c179a554a947a0f91d8713eb31fd94b81208feabcb0642ece0d467534e69892e568d12d6cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6a1502dd2b15a100e690505ded8391e1679eb62f4bfc34d8653ee5d8b6db8013a2d27b845e29b09bc3e2320a4ad7f5000000000000000000000000000000000ca0c32ff5310120daae39651222d04c9b726cdc934b6caf8da6880454190657c09a25b4262b5045d69a8abf8e7f758c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000945e13f2e734596865db4f6ecaf56accfe5281eeedd7bcc70328fd46b1fad6b3c10eec768509ff3cdd1d29cf7805d650000000000000000000000000000000001dbb0cd0b1d41a7064d06b9e1ccbc834d707e3ea5536907e5be756f9f44b0c2d5508f7b989400e872dcd1c5b48b5cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f53e6e87a46a3fe07a8ea41f12f6d7a693dc07909a3fc9d62e8d9441bbd73ee1fb6881be0de840e890859ee0742d300000000000000000000000000000000005c8717e28112e49e0846e47826179ad15c40294f2e72444a6c6c3e278880c2793eddca8a9f817449679fa5321408ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110a44d3adab3bc260782f563068c3651527004a968dd69d63a8fe030a37399eafc3660f43ddf4bddc300e73b672dd6f000000000000000000000000000000001684f7eced92bdd4b616959d5262b30b7edd93dd6d2b25924816fb0f4647e327a25a7a90d7287348dcba86bfe420fe631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a98e81a6b71e43eb430b7d85f98ff88eca55cb405fb125c5fa04d4f635674793a203b709de52b7d19612a252bfaae6200000000000000000000000000000000135ae46954abad4675e2329d46d5f54c13c4c878579be016fc8ec1de5e4b354de32f413b10d7c755b4887d950ba84aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1263feb2ca2f50dffab8de58b1dba92f053b61ba6294da3ce6b69aa97ab326bd63ad9d29c4a1849bc64178b95a7951000000000000000000000000000000000235b6b3ff7f5255513aa2088c4391620de20d80e6ab866c9d8cd5d5af4d9e2bf40b9b4371bced47c6cb741f3c48ffad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a558a8d99a7a9d73e134d1d8b15a27a1f27b42261dec55992fc6f82cf6ca1b3f4cf814a52a7c150f7ab56c40e186e20000000000000000000000000000000004aa1ca0a0f27e9f42c42b99a01a4d60973996d7a543ae15fb7f176f66899b2a82903855a2cab2b6fedd0af929d909341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009563e68d919a8b32b5c019ff8709fa59e8311590412224810d67d1cf56135c3cedfac6c50f5acc23c4d2753150921de000000000000000000000000000000001982a3505db9288f3af594593fea076fb2b853bf794e3b843a9274f1e812cee80bbf0653b3d7fd934f9414506ddef8181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec7f4ec4758593ba4690e4e830048aca8cb6d251d89dd08910f299a1fcc38c044476ddb7b388dcddba28080a544841b000000000000000000000000000000000ed13d7871e6b524e04d3316723cb069d980de2f43f0bbcc301bc65cb4d9d8c7e5119df98506ba848c75a1f08b19db301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b7a728468f7ca884cb4c69cec3a6af45aa0f986ff79155135dc0b21592d6206eff4afc6eae736b62d617d5fdea63d300000000000000000000000000000000002c3c20dc23476ba3e2626cedbf7c303981c43ff67c5664bc8452964af61c230f0e4278530a738fc421793c0e3203601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001338d579db7a784f10e0534beb16d380f8090719338f92e6d210bae913fa1aa140539ec0e76590233d8e1f5ba2effaab000000000000000000000000000000000b4f57efff088214162de1f12cf564f5f4b256a4aceecabc5f0b654c82ed13f2bafa4e01ed35773a038e58fc87ebf6691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b90b2c59c29ee1683d84e2f55683495cb8fa2da353db75948e1d7c3f2784562cc1792902d6f30b2a8065b15153b57c5000000000000000000000000000000000844901e21ddfd94b2c074592c82b5c76ce318e1145c776dad79c71d78170088cf29d45393d16eeb54f016b11c070d431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001390764d5de94efd678c6b531fc63e5255e68394f029966978c3d2692952d4edcd076c28596977c725e4312f5412ccf500000000000000000000000000000000135a5c0c969e9eac78e57399aa4f40a0d1afad3b05ce25746acec614a7c62fff6e4852a3cb18b4a671bb467837dd2c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c450880deed35621558f9d949e1dd98923e1f7dc9dc6247bfd523e617cced6d5131c19c1c99668992308ec3118e2040000000000000000000000000000000008a1fc4d4625876df290978b017fffb9abb5379aeb91cd284fe880d65116199f9c6356c85c4d821b483871e84fcc307d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c094fc12f6aa9f4611d4e2ef273b42b3082c123570645da9579d32df57d61ae475e5bd0b9f1e1040d1fea0c41d8d0d000000000000000000000000000000000fd153094e0ddb80ca2a58d11743c6ac77b9eb9e29d7741fcba303b039be6529b100c29b9f5213ca08fb316bacad6ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015621e00a94afbe8117a04d021a5b8c5d2d1e3381a4979ed62085980151ef63bd3a8934072c053f0168dd9b921ec85d100000000000000000000000000000000149f09ed2f79be47f87cc435460049e908cc28095da3971156265be6ac0b458e90603f5fb412b688bb84a719859348f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8a886b0ea9e5f7255f6a57eb05fdcc1b089318de86089a571527d5ea47154c18b22a4b144efecddaa747fed999456200000000000000000000000000000000109214676a57b867090bc3b978357d264e16cfd58317c4e7597db3e88edbe7c90102585714eb03c004a4978645c12ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4a3f0188778d2ef54365ec782389ed97016c1c7b2c7629151bea40f31f3ca0d4f1eeabda2c7c54fa1ef969cb267b2f000000000000000000000000000000000033caabb2a512770a5bd36a67e1f07126e16c09740fd5cb5281c70ac8520eaa30244b0a468d4f68f2d8ad80d5e571b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3dd698a801ebcf32ced199038b72c912e0d35263a4ee6237a2bbc82159ef02f17e802fb94126e475e09a5bce89c6bf000000000000000000000000000000001872764c8ac505c36651da15bc86a62445038478ad6c4eae2d552db6702c03a7ac185ff17f9bfe6fcc64dd6190d667581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006daef9a9b2037671914ba4362f3a573e544ae4603a05667d97d6302fa32d9b3d6709548f7cdf315575d4f7d58bcc05000000000000000000000000000000000073bc768871551650036e92d39298920f0c72b6de24ba02cb49bb5bb8b6cb2cd9e78f1da92efaeb6393a14bdc2ff3a211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001194f0c810b1071040b6dceb7cbd4e76de4f7f57537476f6eb49f2e83bb248d6768452af90929aa9e1e0bfc7f7a3f1d000000000000000000000000000000000decd2838d4f53f9997da4cb29f3745065f21aa75cad6a8bc56e64d6dc0cedb20ad3594fdb0eab9e3acbf0ef1293fc671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ca78f8018a505f3ae1baa4c89d6a64a9f874bd503eee23864061070e75cac4310b42e280a3cb693e1d113e39ecabd0000000000000000000000000000000011bac44598642c14f41f3f0bd7c9eb43ffe5e1dfa35fe39ac4e7e444eddd7a6e930b8952970b05753a3e7ff9d9a5c7121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d17c56bad4abb4e69e92c7624c540988ade19e97e3ad7368ef9b5fd659047064ef7a12cf1748d77fd1fe4d085f0a130000000000000000000000000000000014952313acd884c9a77b08fd1515a9b8c9996667e43bd1fa52e12c256a7daa84814fd27e4aefa0f2272ef9b4062c0eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105f70193d48e445101f41eea20bf89bc722c7df0309b2032bc0b6344dfc62039feeba9018a50985a325507b4ca8ed2d000000000000000000000000000000000018b34cd0d7c1669ea54df5d809749d46bc66a29a961ccc5aab50ee3d2569268c135522944f8b7a8423f3426f0d32821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32564e6da33c47f5f4ee4eee394ccb7595cd89da56bb18d489a105bb8ef1b8095a6f89b390b0b62eeb9348b879730a000000000000000000000000000000000c0913987a59a213407335004e0ee374c2741f505f1c117b3efcdf57ab6fa79e47039a9f06895fe5e7c9b0c4eeb2c6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131925162982b2ab0359badb008ce0bf1f653e800bffdd2a78c76581857302d0b91987870afa779b3165aaa6db1ff2b20000000000000000000000000000000010271b35bb046f6a38c78438eb3817c51b00b6a228772849cb50b5abe63d14e005ecd8bf59293aa9dab88d84e14cca391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000565aef1ee55db5e742e6d37eb9d469e1e49c416ca0880ef957119883b4a668e0b7d7e4baa26dcfa736ff6c65003017300000000000000000000000000000000042f981dd588c8d0cef2db46a790ef26582a39dc64aca18d2e7cf8b6f14111f216d4de0528208b0b70698fe424a75cce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103e4810bd4a9b08d38e81e05c4de55c6aadf5c7318b4c8a7274d757e7f4371e7d52864c582fdf0ffb069bbcb5fe387300000000000000000000000000000000189f59b6ce93677f2a622a6e5d5a8440016c0ec117efdb2f89d46fdeccd37a12d452afe4808ce585e6065af1f4413eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca39fc8d3eca63e7c7fb0f6431de476905961551e9ac2c44bb2f60b5db0669ab4ed9f44c71b350fb86e4a0b464fdfd50000000000000000000000000000000002bd726cf22db43e2d99e3ebfa2cadde6f2e1c00e2882a96c86fa65fcab94cfb5292f883a42591e1b46a7b07c1b373ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d75cf1b7b161a8fc20853335337c6ee2766a844b8bd9ec6b5bb969c2c632d52e6c41170cbac9710258c40576ec7d2000000000000000000000000000000000272855808e61348c24e55ab8bbb94c77d8751598c026c5406b9c5497031b6d3e4f79a79896e8257475734a063221faa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc5d1f677da41f78da055b7794c9b4ed43a83068d5629a32404fc2f4f6d1115e32528a4b71410ad22295569975875890000000000000000000000000000000000db0eed2992a6d0b7fd9e82b34869eec0161be61f4634b26c3bc82ce16a89e5cf4cb63c47d1c1385f837eb9ae2d7bae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002be0f7f78e79b5f5fbbab1e813d2f69265862ac6d32f569604f33a41b39ccdb95cff56eab3e0376b0f862e0b0578ec0000000000000000000000000000000000fab97373008c422e2acfb3be0c9ab6431efacbc26d84bef2c80489df2d48403f3d358d2d6915bf4c8f9dae634d5954e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009824973abd3c728d02b2045a0bd1695eac2dd1013f329e0a6a88b49fd74bd13cfe849edb8b55536bf329eebff89622400000000000000000000000000000000169b57eab9a49dce2f678645a1510ce80d5da8173684358381590f9e03c7be35389ec6143a575005eea9b723bfeb11b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bbd270f511a6f953c78426ad6139f97e9fae967af786b3de31d511b557faff0f005a73f1a29dd1d42dac95418b83de00000000000000000000000000000000173414012561ae8c04539915098a7c4adb06f6326f4b1e3d3c7c710148c1088dbad8ae756f960f117c6e547cac562c821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d6734c76ecc9dbade31e8452a38ce2b45b0aae3dfce208a7707442b906d85a5ef1832f63448687aadea5b6cacc9f440000000000000000000000000000000012edbe4f2bdb326d5e9bb0e41693ac8113cdeef1c605ad0206e2b3f9bb8439d54ac9d54d3e38ca88f4a69c4c11ccf2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e72bfb5f5816f10c6f10d340e61a369485709e044aae6e80fc8256e2bd5edc065ba1c749a1fc85f7d94602b510944f000000000000000000000000000000001287db37dc67a39dd177d317469505f7aa9fcfddcb7e6d9542f5e5746127a18fbaf16a56f3570e6b24bc82264fdcbc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3de0c9e848eaa2bccca1ee5c393cef1fa4aa15a2d6b8b936e851c13589e1804b124308d8d45caf773e1cdd584b3ae800000000000000000000000000000000180ad47eed54b964f366d34d01452a39cbcc3c985d8bf417bfd97d7324057620b89aee2481d8cc95a7cf540d44beb6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148cc071144c74f858c3863813603ec102f28d4df5c872c6523296e275784902e7dad3267d9700f5aa80d85ff62f7b1f0000000000000000000000000000000017d1ab953f6523b48728868a6432884b2b2722bd430145da548946d9a60edab788d53539298632b5f125f74f58595ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002849cfafff6fb2a7768d9a256fbb8cd809e24ee3fa7d204b7f09c326b5cb03863c91352002458ebc19ef49bbb969cc60000000000000000000000000000000018d1a88bac26a824bdd90068a58e0508c25769e0e0c6cd8cb4c30718d724c35c7d44f229cb3afa46fb07eb708fa48d071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6240d14f6ce6d65e19b72aaffb0244f21f5651d21a872c6131e41bd0dc021709be25525d2cea6a0ed7f01c9dff88b00000000000000000000000000000000010e749fdff1f63296bdb033f59d7106164c5e19c7b33a63419402e9d98011ee0fbd4ce404e370e3a55760adfa8b225c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001567404a725454d997f77357ea181fc8cc8eb45abeae1e4e1be34d3ea25ad92eeba66fa038284d03019514edad2b48970000000000000000000000000000000006463c1c076ff62aa5a2ac496e9db979730cc8e4392285361503c2c764dc4fa1273e9bd33e44d6bef8684a6e7baf6cdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af0135dafe61dbd8a1780bcec8e4221db83e43d1d81a90e25785cbddfb991ce267400a088b132be51600e53aa88a1f20000000000000000000000000000000008b7ade5b3f8380bb086e55ffb6ec32d82870ec3cf136a8264956a0427e3b515018f853dcc720f819c6d6478f84aa1ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172f49165a571b730a79f21b9b3afff0962033d297451bfe11ffe3085c1ba9c4e978bef45a38c82188407a025f5b79f7000000000000000000000000000000001634d3a795eae4cb05296553d5abbc35d09bcc44743c6129ee8d43f6ed7eda27bc7d0255832a9c4fc7da764a11379d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6ac7e35ab8d48de22a45bc3f31dc012d564c935e59887807ab8ce149ad152026b6d001054c01cf2ee969b6d2956747000000000000000000000000000000000edf13915914ee21bf0b270c4e1f645a43ec5baf7d70efcdf33de1ccda1d52c5f9adbb69ef5ed07127b606f6e89ab02f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001655bf5f49c26fab24201681400682a10b0ca784f1da596377e95d784f784d3d6346d9ece18520547e6ef0852ef0c9140000000000000000000000000000000016f95cd32bd672b7d4bfcaaca4b28091cf1a1393ea40797d7ef5d7d99721943eca021fd67a26b848a691c7c0c863148d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a743ff0117fa8d2b879818f8d2486943c9617b080eafd658d37c63bcf7ad42e00c6e5e827114a00f6a89407b2d70a1a0000000000000000000000000000000016952b04a90edf126e6b5188f5b0d2e21b884e0233da035cb9783e7591989e61f50c628d0cc81cdd288f446e9cefa2c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e4e33c1075524a560c736b0b3d900d472b1b86af802cfd27c43384ebad81d867dc72c2dcb9c24e4b32446f0ab388130000000000000000000000000000000015c406c06a0911c2960ca837a9acfd551c0776db5e2375cf13899a20096222e1fd46fc70834aa2155e248a0b2ae4efbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbf3163b9753b16cb381221e350b145f212274c68250ea61fe978ddd36230d7e5225ac6e334091483a3bf2e25c02e15000000000000000000000000000000000ab812b73f4d2ab50540ed81ca212ebef636fdc14cf593a2e2f917a53c6c8a92be97e6bababe20cbf7d6b2e4cb5da7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001a2afde2bbf3d60c8d182d63a214508820ac51698ba797de4152be872f0161d7b789247ea73788b47218fcfa3f2b5f00000000000000000000000000000000138e78986d9f9834dbd6948bb42c5862339b260a6ecf24bf660d2da0328c3312eb364a4bf3681834c5b25a74c83ac2fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f87a869a18005791d76bcdf1ce64077b68da217554811b97bc776ab40c89cbc6cf8941e9a8d3675d9f9afbfd3208980000000000000000000000000000000006801f794aa066fcc118d8415ed53308d4516f6376ec5e6a4ea35d39dc127b34b1b56f798cdd8ca2f532f566b27f2b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeaa8149a596a97e9f15018e946b5b31e250aab729443d54332e65bc268ee72d9b7f2d4b93c151d8eadceef5d4110e5000000000000000000000000000000000c47666641ec861aeab8c6fa0672ff1b5e43a1ebc7caa1777c1d4202991613094a3abd3cb71ae8cdea9d61a994ee5f131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c41e11183ff135aa1e12f8371e0c31c07eeec11442a3fc5b4a7eda2ac531cbadf137236d4b3fd491e0be7b4b153638000000000000000000000000000000000a1b347e894b324e76fd6dfad28889eb368a870c414a5ee3116419dec06d2e2d8789866cdb5d83d8916a7374a63939201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001840cc889e8ae4a91505e5d14e52bbc87957dba34ac8e379d43928fb97262760f731f6b1497d250a8200c113414e3757000000000000000000000000000000000becad162c908bb1a20439370715edcd32efd4bd6487f6dca1031130b1f8d6d0d9b39998f2e7bf07c2fac052de37d2831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cf6c67900ae433f570dd5687b2c4e4a3e056251c1fe5f7f42a629acb3f08fbdad55b793e52a8a71395a6d52deea13e0000000000000000000000000000000011c5126a203e93d59f777b9e6cb719567a5b440c074cab1c25e977ccc5b0dbf75ef19920340ca57e1371a61e19b9d7cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b582932e14e059c35c4f9793a544223d4af0e089349d523e892471ab2c7de82a43414063b7fba47da36ab04b65be4c000000000000000000000000000000000d5b0c1258cbf6af0ef5fcb6b6215824f0bec8269979804d5e8ba11b69a2e3750a653cfec0ce4dc30fb2cfe1b2462e4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b618a951954ecf61f8cfeca12da72895449457c294c515fdc67002bdfb5855211b02f2d382a4a918e9abd6c8afe9e700000000000000000000000000000000015abc43343a55fc0907955ee26c1cbb415c40d8d543a1ca5d8d8b8c0c7289819901c7c0c2fe7d767573642749b777821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112ca64a7c34fa3807a10dcb94463f21e38d243d0730a7e3dd3b8fe6ba519673f85f0c6d5bf613a495d22fe77bbbdcf30000000000000000000000000000000018b712a6c0c545d0aa6e712c01b9a27a1f5402950aab23edd1dcdb11fb63616869c076a045cf0a13d6886c3044dc5c271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fd745dca9b87537450a222e7a6a0ab1a58aa81f1459b8a7ca0c256a6eb2b800268a779c4a61f2f9d30572c663624a400000000000000000000000000000000001f9b012d6e243805debe7f4978a4d2e9a086116e031d8f525469e768d52887075d395ce2b0b8841bbabce78cb7dfaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5674d1473a05f3882c5719a045ebde7c50fcbda6de6f094650bee8267b26c79abb8b9a6241b95e299fb15b656102b000000000000000000000000000000001773f0d20002fc229114608c3bf6b81fc35118172e1a7486e75f5cd7d9f025b3bfd579aad3ea440a5fb557f96d688d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ae8a6c76dc1572f4e7ff164b36d66e7fa7d5e436fa295472be39e1fb46fe66d8a7d36b2bd949d52c1a5dbb826994d000000000000000000000000000000000885f897f0a0e62632130c5258e053bcab60aeb89700551aa8efe492784e6c8a589fe522c065e31d29d1161aef28a8621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110a04591e110495e721b21ec18cfa6cf1cabd8722669ebf43fcc771916ad3199e774467db46c347bd0959de53014d30000000000000000000000000000000000afb50bef961725afe70b7ac2ae5ff298d336477b4427b737f27cb3271fe41377ce9246477e33f2cea3390305d29e6cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001608abd8c9b8bdbd8f08bedeeb2bb44debdb842f781ca484f18bc12535a252427fb078ca735981dc48450f267cd5708b000000000000000000000000000000000023063fc39679e9c615473d08c20183b59d28698ddb22cd462a22112749bbe5757b20e9db706a8e12ba059da0cf61ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f25995dc9fefb2749a8d36788023dd286a138c188c57e246877ba36db96a43b715fda169ffd3bf3e1439cfe84149a64000000000000000000000000000000001778f51c7b23bfcd7f0fc04adbd4f46bc6cc2daf56ef3f6c4b3507729f5f9a1c164b80f942cf2df727916f252565d2791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f5efd23dc4a6c30a0490e8cc20a5094efc7ef2ead0fab9d73affd46c015f17b96faea7602edbb9683ebc6007801a1c00000000000000000000000000000000041eef5118ffe97a6a6637784f15c27eb0297a895193650d965ab24479f891bde3321eac035d979d0d723a16c689b6201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b85edfd564cc9afafc28b024be48af8d81462a3cc0a12fca56fef475438d3621da58bc7c66c24b1ccab49e2393082000000000000000000000000000000000b76d1b97c383d2210402e95be7a40a55d4669d7911c29f1206934d5f270a89b3cb165eaff4865ef7a124e7e4863c7d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b9c6df96cd2b2bc86b2ebde0e69521e72ece5677f1bc012e3e4aff50eba95795243a1c7759bdde6ddb1395016354c30000000000000000000000000000000009fe687f65924382645ed92edf5027f7b2b626d4748a0b97799a684ff4eff63a7e7bd4aaefe569a2b7562bbf78e039a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fe9b027020a2e071ff88c2779224e7e4571c2697eb32c0fdefe4316e498ecf76c62e8baa4c3d396ac70840b1746c4d000000000000000000000000000000000d8073ec215c3adad9177da1a4915a7eaa927a5f34de052c422ba212b821f9d344db72db6dac06d61640682572dbd5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd0695f5d152fcd3ecd8a0cc47d90a1596876b63d03087143f6e1e6de688d576064b838f292345490a035dcb709090e0000000000000000000000000000000019e0318dd94dfe8ae3ed3fc4a2e69f357536da9bfb8b6b505952b54fbbbc7f87ed16d94ee1f1ff370764cefe8743c2321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000622a1d6bd1acd2c1795e6a90433d9536738446c20253f5dd4264bf0e0a68884bf87f0fde7a4fac8d713e3f9cc033a300000000000000000000000000000000005faadaa99cbfe16a6005f4ddc6d6c88d6251b1e97b42c65e3003a22c52229932839a1ef0869a1842d00804a93b0aa1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2bb722f8b8bb7fd517ead291ddf9d768838a75b84092de562e0dbe2469cf12c61d376d6320316b667a78068fd468200000000000000000000000000000000008b547d2d036578115a8f10c3bd3dc212860ad22c20d244831e23048e031957951361f0d8bcf94822dde919dc0e30041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000535ffc1e8f265b0fd3180c3dd36eaf0dde560cc7266750d3936fe8d0d66de23af7af29da1c0e80786d3a778f332af4a00000000000000000000000000000000094fb43c07069943d3bb8cdb06409e301691651cbaa47ef30a985316fcbc7bd6675d0a26bef0dddead6e3e7128e897871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d5f571d4259af01966c232a2d0478af3f8a5e437ea2654e3aa22dd8126a4559ed822d80f23a99fd47e32e585f540e0000000000000000000000000000000012126ddff53a254e2549a4e3625f97c8049406f338e7cbc9be45d54693aefdc85a88fde7c2876aa84ab3deca13a3f9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035b3a83abdb6a3f26cc632f096786d4f86dd4b2e23a511313bf394f2dbd857766012a5dc2a652126bd2d4c40a55e8660000000000000000000000000000000000b0eff72869ee494a35890af83127d63aef983a1e4fb14f5c2f01a40aa520c470eab279849318cd09d0b892217794d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001380f371d43ef3a081c52e19aec34e6565f1deac51ae23d6b27dcfea4f0262ac0abd3ae82793d9b3f4e7e85dcd922d6300000000000000000000000000000000038aa7a5659b21cb046eaadb3c83a2de06551c4697ff8a38cc5b01d53d6282ecf7912af5981f39b404d8b3c1367c8e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054c96632a740641e3832560c862fcc126627865c3cfcf3898086cb8932a4c711379bd4dbf881113b02a543cadd91ec700000000000000000000000000000000042b55177a03567cbf2bac828d6c91f65ca8b64f2ee3383ce66b0bd29a9c01f34b87a967f289748b492621679d26c21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eb8bd52bb4712df06935892d0c8cff126db7500dd698a40aa9a7115396a5e22ac65d01623a510edad31af1b043dc530000000000000000000000000000000015e227c6eeca6ad5162209b1c64f52b7b7ad6f5f236f91a7d651743dca752d320383fe3d57f353b9e8f37f93b498fb0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032801b26033c561b6262d1d2f9cc3391e57aa0fb03a900e66a3e1af7cd00d3554ab8134b2a364d3874d1ceac70d83d5000000000000000000000000000000001164285afb3010d08bb0dfef245c742c7c947a4b8a31f097d368b66568a3712b0882ab0bf0aa24c0e28064cf139308821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014db504075b12150b2bf4bb3bd726b30a6a61278c976f16afbd7884f4a7086768a0aad8317abefe632083bbb13f62e5c000000000000000000000000000000000f4af249c94f689673715c208417a79e56af1d9f73337f1d53bed2561395d7b9d8c8f243dfd2ea2914494ce165f6c6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001466d0b266c6b66d1e81594ad7e8275d30c72768839a1777e6cd211315a394dc1586085a608db11696160a2598bef78900000000000000000000000000000000109a3ec7b59fa58699c8e6dceac4a5b94afa517d7a4cf7bf40df59e535056870b23130a021d4eac6cba20d9583003a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001609c271c8805878a0870af860992ce714efa0615806e6745f534cb7fe5017b231e851a62a01db66d90141551a7b6e7700000000000000000000000000000000009ec54393017419021e56519751a3dde3169e8a4debca3eb0bf606d7d8cf0d0694b4d096b934d4cc58dcc0f4992fd5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fafaf6645b84bba45a7cac36636ccc23e325828b232215ebbbb34b807c0226e515c84ab6d63cab8ca13034db978b608000000000000000000000000000000001020f63d1990a1844cab6f2dc86a756a1f565464de9f4b09f3187039ace9c6b9e83f12b1ca7aa06c5713f73aafec92f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014496cacb938b522c6568d95fe06eecaaa01ea584c9aed2c7d4015d6a53f5118cb780c3526776c2fb83835b920d5a405000000000000000000000000000000000ade76cadf54a66fe79212595e3fe355d960e02768f198edc5a8beee727551946398abc1f82b4404fdd88df3971d5b451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c9ba3ad47c1f23d9d76f6547b97107f8351b41c7514118de1ed2ac11a7a3e80fcb5dd8fd85079aa0636bbff4c8a07c0000000000000000000000000000000001d5aa8fe93b8a9e71062965da2880fcb29fcd776be9c51c1d9b5f45ce2b00b917436a0cee6ece95c192aa53216c0adb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f65dfc2ec2d408eeab0ad43eb425d381c6d04c33f6d50905b480e0c82eaeb706b9cede0be5446437911eb7db828fcd00000000000000000000000000000000037589bce74200534a1c25a87b0252efe6ac2670f0628b518b887fd95d0b61033c304399797748c2e363986cd8d03d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d272501c102d3869b8718636c3c74d19751e011e4919e87d03c6ccbea09127d4a516e4dab08815e0ce178bace28cd00000000000000000000000000000000072a263dd2b21f6a917ca5656f03b20e3a0aa8f9c86682f23d140855ddb25699c3ea0384fb5a8b90274baf02585bb11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001742c85fd129b459267280a35fd2197efca3a574f02e5aaf9a07e4dd07c477487227892c5f07a075e9f6eb71855e40560000000000000000000000000000000008d5d90997c41ec5654098a6594bd9425f2ae6990e1f6f96b00b8d8da2532405cfc3cbd72f282347ca980275ddf8a4aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db330aca445448b28f877fee42c52c20fe7678a964e7fcabff829e913886e42bcd841c10fd1552e4ee74d9abac5bb3e000000000000000000000000000000000468b10dd604607b1d597ec7db6a4f38c71d7c2d16b92844a2826aed9bc98e07dcba8ad4167055c693403f86546362d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161c9ff70bd15e2cf8b3705b6d4000cbb6c57ccf466fccea7dddd3fc7bdc5fe9771a1787ebc2ad62a2c79fa24d335742000000000000000000000000000000000f422dc138a5a44750966c4b4bf800c9f2cceaa3b1fcfed393310526002f019fa8152160eef0a6de91c09b957eb388e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011f55536a12029224804dbdb505085019a9a3f7f2385ed180f6073feec79f4a7842239f1c22cbff300d269d32a21b8a0000000000000000000000000000000013891ee8c6a06354b13aff05acd0f0ea39bd1931fb6b220ffe0bf5e47e7404aff92c0227ef527767d41e8860943f4cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151d7ce322c265889ec51efc9dfaec0f9484b7196312656b2a0ccec2050e3ce2dc67ea6e5845fa982b9600023badde020000000000000000000000000000000007d07a21f7a291e33a70d1c97eb48467fb28477279433a7afdc2fc7da6963ce11256016b73c6c6d00e0ab46ae1f4cf651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136bf0b0af899b5d612ab92b3b4f1262ca0c6c14acbc2362af81353514a00a2ad20d45ef194b6f33780d505f356d229900000000000000000000000000000000151c0801de052ab1ef24db90d43a7ad6fe2a622aae6fdede328be0ec3cd23bf92ceb8bf9fd7787930b048d9cf97a64001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c7b01bd44e06f2dfea99d416a5b54ed3c3408d037a4bf2e4176de4c2be8ccd3cb9e30582d62372d31909c832c3ce850000000000000000000000000000000007a1ec03a0f012a3c1b881ba6a6f65e824a77a8ffa79f6968d1feecbf5ab4433b359438de7556f5383148cd9ffae1f141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d719b658ba6a3f2b4f84afe77a7cc3e1ebeabd49364403788db9972b8b7566e1f916306dbdee17de5fe51c618d3f3c0000000000000000000000000000000002bb87cfcc1cd29e954e211216cf89f9e7e2a583f4aebaa956da0443e5d0ecec0906cba146cf06beeced4993369eb70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b828ac1825ea0fc41892cee243f440f96b858df3b11ea4002cf0d35d1328366f877cfd5d9622367f119975ffcf933b000000000000000000000000000000000f057e8fd1c0e30d32db258380642ea19fa8b44da2194595018b63360809cf344051214772a8cb305c64823075b8924c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242b3d3a9ebedd4e91f60827d28d84f05bb0db40d27ee69be6925e7b620e5c8a854e5795ef1c6b478b400d95b675a3e00000000000000000000000000000000043a9c897f3dbaf024cb8200e5e551c2365c44d7018af31a008cadadde2b38dee77777cc44f725681f7eb518e0e1ec541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011283ebe63911db8c67f64f377b13b85fd6c8b8dcaa2e1dc6524bf1be9698244b22dafdc6dcfb03b720de332b995b79600000000000000000000000000000000155e5d4e7c658c0a28abe4fa28f16d1493260e6859b8274de58e6f23314480bfeaccb12036355e77706b37fd90cbdf5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ace541937df3a0eafaf3948e829b357591a3a0cf31cad41ff6682abdf55239ee450a2da1ec9e29e67f1671c6809d9200000000000000000000000000000000088c84e9dabfa5dcd8a63e2d9ff3e540b9b8f99def1e0f23515f4ae337d501182dc08d0eb2b4b53045c12fe8e3b299ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a8d258062dbba5760c84a336470cb769304c65fd3149268bdc1b44daff125860e00ead98cd6ffe757e6ba149e69207000000000000000000000000000000000f2c843043dbc78dc56a45c56147a6717cd4f45b294619f490153590dd120e7f60478a12c06a3e5e678335036a74f2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052862b589abfcb2dab1cb1ef80658341c95ec55dc22c59b0e035a216e73b4ad10ec752890ed7fe8e0475074620c544f000000000000000000000000000000000c5b5c9c4c330fb3125f28cb5346fccee22deb0a504a736aef34a04b1e57f6866a1b4d9613cc99302d0f9df86950cd391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb6fbe236dd6761a2522d48b68b97055aef2be538f0105b242d138bfb83401617219c313eeac6c548419799f04fc5100000000000000000000000000000000012c301c993f17b3b15005fc4db6dfdca4a9d6cec498c0070d69284c2f145ea2ffa1e1c246fd677127a24ef5de01d8d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8c482f97fff549bdccc9e255b8bf7f341598ba19e04451e9379f794a9869eea138a6c83ac9e103d37e45690d5026e6000000000000000000000000000000000ed94db46df11f21e761c59d078b4ce4da283061f20580ad451e07285a1a46c1a05c5bfd2f3c7998f37832591e42dd6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101abd00e62c73ce99d8c2624e711160a2a90945a1e03f01ecfb1913b706e8a6b6ef9a055c54676808bdbc804955819b0000000000000000000000000000000014d971cb41c6b2a610ad92ab43c1449f87702240cb899907b66adf41a8ba5c7147a418409cdd03546d1ff990fa69f8e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185559440cd44edd0dcd144a99577592bccd1e313cd451beccfe5e48b88a1aaec02ff7a940e4d71a0fb937aed276f7d7000000000000000000000000000000000ce9d70ea4ce88c64f07598c5fa7e1c57dd15e4438ca5e160da5ee7e923d9e54a1fa891b473a13441f6623d2588680691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1c5b647a51ec74fc181e270a70b9f837f6c9a0275a8a7f55d86f1b14d12ac77c2da595e1d0486c809f1a6984afef90000000000000000000000000000000019311ebabf285877b0633daa5a08267fe76f071d8f1f3bedfef7090af8ca18624f527e248f9229bff22bac10d5709fe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6fb1fa39089f61fa7b699c8e408ba3620ca24b60b89a94467811c73c44509657515584839dc169d95e3f5c23f0e9b10000000000000000000000000000000013381cce2b57429f6e4aa94c2c76330a21bb75b306d17bc348a48da4072f1f85e792cf0537447feed6a2e93f03e7a52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28c4fc7f90f4fe21bb9b67c63a1573e0445b36884ccf276ed7e6342bc41af999fc4ca7c0c70738f185e37f419ecbfc000000000000000000000000000000000f37e8fe4a44eebc486cb213b256a6d3299f8f344a7f0360caaad46a6fe91bda2d181c72e154fd4122f1f837fb3e27481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cd812ce9160202975214f2994ae54c279428895c10e224350d96c5f7f1594e6e84e75a40005ac8c809870ed34d15ee0000000000000000000000000000000018c1dd6b459049e81269ea9909901652f9af3b05e2b5891b075e6b540e61031aadf0950075e0617097771f382e72a29d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006271fe057667da2d37b0e0e98a4c5dd20a875a8a76dc9c2fb1b66fcb22ac6269daaaf0a2d229241fa153a313324a5f90000000000000000000000000000000019e2162d8bbe052bde936d0aac598aebaa2e70f2871f72bb58d4da413266da79e637d57ff9a794a171aef910f9219b151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae08a28ab4add98d3245b7d1a4745558aafb3e002954b89a39bdb5254556a63be6cd96db0ee127776958469a7db027000000000000000000000000000000001457f07c310550e4997fa925a6026009c7c227da8abab7efdd5de5d7e41dc402cf092850ef0662f1acadf043226a41701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154959caeaf34e938ba5fc09fa0dc030c98cd48bc1c348f6258f60e75d9b80f21c51fceedc1b1274409c56a0814ff5ff0000000000000000000000000000000009082ac1f9ad90d9b839eeafddee87c49fbb9ea89e4f820c8523be5c5aea4a03af5db7712d3bd5d2e288dae64c1cbb4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155ae8032f93487ccc8296fcd1eea54517effb8a34bd4dbc09a4f9ed9e4f541b82a9cabb8d2cd57cad74274c993a3b2c0000000000000000000000000000000011048184a765e0285e4d799b1ae45c7151b0c1aa54f59d165f276501ac8c5d5ccbd44288bbdbfde58e18a55a03db4b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000477d4b85b0f75548854ed23a321933fda4e527853b64edb02565e6d6f60e2c5fe3a1d8da5b8b689af79eec471af315e000000000000000000000000000000000cf3fd958e8406358364674720ae91494e43d089349b3ae4912d3134a5d1af38f506055bc8468d90820fa3eccbe80c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6fcc585c9dd530249af11e20cdb83ecc0cddf42658b13b1f4adebaaab5d03a4b3221b155779fa313331da8ed3b0e1b000000000000000000000000000000000bf11cc3eec2168423cd8348b113f4139ecbeabdd8ba778a543c5271db58816f892ba0d7f969cb0c7f18d435101630d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061e021095e6de6caabe2f27924928702f2b84fb38be9f954a018b6c312bd05607654dc1431762e7edad1941db7f751300000000000000000000000000000000079905af69fa10ccc714ce1b105e751813e9316d15c38807013b2ec4111d9d3733b77150355ef8cd56031d35e29b2d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfea88db432daa1a657d04c2b0fbb42b9cbd23a2d4ab47bd57fe2ebde3f8dffa6b01ba745530435ea38101ff8095c640000000000000000000000000000000005df5bcf93ea02050e9a472c2c3e4bff9fe47461818d78be72af77793e76ac4fe90c39d7080f737a40fff17087b02ac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cc2ba0e52b4962edf02e0992080d4e9a51838e62dea00248598a8e0e72df3de91f0c7b3e4ec3d59c96b1f164d62cc600000000000000000000000000000000117135bcb61ea19e4617a440a4802029c038551cb407e0dce79a321975066ec5bc60fa41ef21ccc27fcb7e4e5c388d0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012550ade0fd3980bccb6a803bd1468a10d01a8260405f1ab66247801e3795f4af22adb2f2e3cb2bf6a3a355cedf1a05d00000000000000000000000000000000093348fbf2587d071ddd358da9e7a96b324c50c0421b66e2ff6f4c32efa281477d1b3e163eafcf977a4ddac3f63176f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e22814239e4f5ace9664400f3787efb9ef4eef8f4c83921c0b3c3309d80b5d5e427a2a097ec78b8f3c68d5d59326c4500000000000000000000000000000000182ef856ab48686af204889bbde2518318d20bd4a10960c657ba5b5c601e84182abdd836af7ec8df2e72529af2865e151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6caca1a63b589d43666371d533b3c0f1baba0fa544c62eb8c8efa2d99108361070f743e0daad354a68c823f636ec1d000000000000000000000000000000000f039815f99ccf7fbf856c9f7afdd6c5297e7787608c99d109edeca04b2f2213a5759aa5d3d35d758f35a70c2938ba831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189bafe56321cee3d9bad92c5ed0b27c1598a231d6222d65223c8da5758bbb9d30c2dbfc179382e7df1adb65e05a46e5000000000000000000000000000000001790ca2d4d4292732e64926e6662035e026e8c94f2db6248dc64ec56bd9363437e0cd3df34b52291cc802f89c64859f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a00a01dd3f08c433498c4df0ff181ecdd77ef32c3321374097c192a5ca0c01d85a3e1729e565c70ed2c2e32638fe47500000000000000000000000000000000147ff41cbb097145987389700348a8834fe082f9a2df1f975e988e4033b965a26f523ea87f34821edddc8b4afd46299f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e71d75397d16bb61212f476e71aa7c77dc6f0426b316e90ff2da6583526288540bef759953adcdae547588539be24000000000000000000000000000000000331fcb9ba770dbc8c6fbcce76fb8147d2c1a3e9ea7f77296400a79ea25ec599dbd77d6ee493b5aef58ed836737da1761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001da354ebdcca09e3d2acf60f7325bd80f9dff4b693868dbbb3c99e0e72a98b9be7a9c2f0d0f2e6e3245c711d52f37400000000000000000000000000000000067f0f97ae597c3ba0cb5a9f9c9fe85e6c485b8fa188c85c0284f7c157a097603469a8a8a6e216e887e7d3fea9a3acc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c8c82ba5af2f60dd8547711f81e6f5e8220847925398d0f05f6c699b0fd3311540c7a84f09f2c6f38ecdc4682ce9f20000000000000000000000000000000000360fa81f07bd049a481d5241f36984d90ec04f362b589f4036c6d9d5d9aaee7f7a7060fd45c1208062dd54073d6fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f472da772e1c9f2b44f2a5d3049d75f7058a40dcd6339790f8fd663e50093b942220c733dfe494113da89c8b1f1e4a000000000000000000000000000000000b4762ad8088bff4de67369aeb0dd9390fd9c26dd94817acf5172d6e528751197946f993288daa372197c159d54975841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a2738d64cbf20db3c6c31cf7a3ecc97ae17120d6f680044cf0f39dae0c993ab513184b6a182ba95e90dccb196ea7bd000000000000000000000000000000000226e6ab7752de192d0f84b9b981e0e8ba2c1da15cb7e2d75f214457655ac0f30c9e7a1c4960ac552a5510368d1b0bcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128ebc68003d9c3aa3330e8b4fef0b6df21071b264cfa35c9aa1a69ee87ce799560f5fb80232a82c44a913a18282f2ff0000000000000000000000000000000019e830519686d17a82714d958d6b943ddae7caebf95a7fdbea07edb376f92ab17084858c747607860a8694e5181650d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a57ec7735b458576d58531596c996b5483fb401c5e25fc75abc81a18ceed9905d93d5c622ba24cfcd658d764b60af00000000000000000000000000000000030e119731dc868873f1e60c191442ba608a3493cf20f0f02fc19f9997b528b7c7f99dbc85bbd05aa9c8dc2ca656c1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c638120329be5cd9da5c60833bf63c6b8a99b340ba5a1c22e0d905b457d6370bf6d36a5a63ebea595aff3024437e90000000000000000000000000000000011acea0b6a20f158527e1f62a9c07d42097071ff1667dc7063a371ccfb7b8369935981381f6932625837432fb61a1c5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b32e42599259123bcc24215b7cb1e98d3b95571ee127be2d5df4b7f2b0714120213c0c586ac6cdf3fac4402729876c0000000000000000000000000000000014bbda24e9ed3c6b1a029c5b9a81f164fb0dab00c3a81572cef52791d10b8c6a84c48da296daf49d2645ff454e9f72ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d1daa744f61fb6b80a725c59b49aada75804237063e31e62dfbc2c498f8f398cf55fcd09da4f4431b90d39e8bf650a000000000000000000000000000000001325723acb0a485d57acb8400e6191cabb4d3a3f725dafaeafe35a93203eb3490b4a49f02f49b259c6c70bdbc352bdb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188d3210be6d46134965b71ad5081f22bf32b3113a0b825198f495a47a4b3414d48dc6b9268b39178cbe28a999407aab0000000000000000000000000000000019ee7e7b3408d7f882e6a696231f68b61005a078a745d7cc4caec6d365de03212e562c2da208860b6500d657679d91dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e78fa2838e1e43de7baeffa280ae5ecddb6f7642a8b1a76423a88202b96cab8653273d5a96305b375608dee4d69d8c30000000000000000000000000000000013de4ff293bc87c6f887bbf304cf63ee506844ab8b3f897d537e212c60f641c47379af4d6b5a330fcf6cfa95c6054d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cee92913c4c31570a7fd5a4478ef128f0c77b6713c5f037382a44c49bc560bff7657b2b02a8120ce086ec1d955a64e000000000000000000000000000000001962d475c82c8d20fa610ef33ea4b1873a09a42d8c9e5c54162197be22dc3fbee574da7804808dda9e9da0fe31f266491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c41c697c1cf5932d4e2166d988f844974bbe419c845e0f4530ae2be46250594dca8d57313348dd0860f970d17245f4000000000000000000000000000000001161b52bbf5d74c8e5c4b150453d11feb6cf48b5cbc723f3a5be0cf08432fe1928eb446f42a37bd603d7878e7d3777391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c28dc5e564c1e9c8df0634fa3d24977c7eb3a95b0e836309c6dd62b98a3448e597092450d2354d5dbe33a32b4e26a93000000000000000000000000000000000c9315b58b4c8bcde61357f0e8998718baa5f8d52506c8c7094fdd3dd9d908cdcc035edcbadb57ab747bb5ab8ad93e791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165719d7739f073b5ba138b2ec9304308d88fdc69443b8b5c41babfa416778abc2e26f6b292a96720ce43c2c38cbda7b000000000000000000000000000000000488153cecefb2021b059eb37be80cceb2f0170a201ebe82583b23797b5bb798b7fd911a28223285c373f00c119114f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001962a364e7470e4a4430a96a411d39ed9ee29979e1d1b4c39eb0ab2527d93ca80a2e167af61099c125e485f1d3428537000000000000000000000000000000000c236555b115b662ad29ed24e060ef4cf9d09177999fcd6ea5a6396f3b6b4b3e9988f34694964248d27f0ab045e2ab941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0b44005249a529ede11475a755f1227f35ffa5e6a255690717486bc7059a29b1174f4fac70d620554501f51794eb6000000000000000000000000000000000ffe3ac61120557dcd4f7c6b05f6bf1b28fcc432e98947b428bf5d45f4fd6adfb34d7ffcc70aaeb079ff5c5b578644971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e20a17b90e22eb49658a0f97869d4639761ec9e4feb0800f0eb984afe454953b998071258409ca6e9ca68d5a6a24db0000000000000000000000000000000002aa4923edd62fd2defb77ec619727f88311b52c9774bf917d3af57af1db35db4175333580991f93bf2f55abdfe65e171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001961fbcb94238358a71022c9a29d72078fb55df178165095604a96bedb1045aac718cbfa95b6f44b281d82e02453c22c0000000000000000000000000000000008f96658df276b8b5cd2163494543e25e210da599d3b6aec5fd861e89261ea0e7985e986aef33fb154a906fd07790a841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001331750f9dfad97546116278bf352563426dfa14fa64f863d22afc6679c4aa7f9f0375682f0ee542f2b72f1b9dca435000000000000000000000000000000000b52ed382eb5e474af86a728eaeba55995b075034cc4eab4b58631bf7bb80f1995e04e4e53dac427005048859425b42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e7b86d6e1c5d63aeca19db808b754569421a8adf1f80a82ececcef01aecde0b167d5fd5985adfcb7fe03076d9494470000000000000000000000000000000000a6444694094133d0fa5fb27ebf40dd9f89b4b2daebb5f92ba17adb03246210e9a17a29ac4983dca59452dd15c9fdd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e775024e7dd8d7e7e6329681c3142c71961676b196b0268ef38f3131a27dbcb77a48ea10a9657801796f6ee02a4b71400000000000000000000000000000000039345a9cdc53788142c79d3a993c81d0ccde639a65a43289721f998eb33229cfb59ad6b6497e297f04dd30d91ca170a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070e23fe5efd8e48ebaed43b678de98522bc11cb1d68ce0ab8562c8f7c9b1d7b21417ff0a5482b9509e45661b173ca3a000000000000000000000000000000000607c8dd18a3df5308d217cf95edd3cc20ae81cbd706f031fd94da667dcde7181362c1c8cf469253c8405c4a485777861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195723a2e119821cbb391964db4c5522f3456e9ed1d8710653460cde00ba229b303303455741309961ed7bf8e649c4bd0000000000000000000000000000000018cd9c87b364c48c96d4c88bb911f2bd7513ebbd62e4200a32ee3b81327f394cbfe8a86f4ec38c046ed6677be7cabc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f011985c1852aa7b6aee6c391d52bf3bdd841d77477b06a723fe6de19d7ff5cb37856fce035d65cbcd05c6b246d9800000000000000000000000000000000085ea71b5e716685f46bef93afe39cf7f78414decd2e00b34cb0a17ff6419934c6786ed347cd0fa92f5752e55b5e6a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f1b3b47e529ec8d101cd5414d806291e09dd6747c6d4baee723244144114c0c494bb386e2a6dda63aa1fd4f44fec580000000000000000000000000000000015db8b8fc7f0e402932773902472c66f5ce78e7f922aa287a8619ffc344b55dea15e3f973810c05426d381754dd83fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063c8125830a4bde7a90337e15a706230309454213427129968025bcfd6f162948972f4355349ee9fd7241e729ce26ed0000000000000000000000000000000000cc6503ba1a09ec8f77089503661255f755aaa1cd266ca5804ef50db8848159aa9b840eb7f4f5b4ccd1cd553fcacb131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189b299dd0e06c5a3e24fdf8a2bd97fd01ea8e1ab622fba0948c0e81bbc9d82ec17ebe6b07788f189a49298d6b4fa121000000000000000000000000000000001705a6a64909557f18c43945dfad11ba44934751616481dd7ce366789d25ab1c3a260c423d097aefa7cd458374f0b8101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c74958a23d3f6867a2aa16035ec56d965cb35a6e471d843b9cddf420f4f8a671f31e2dc4fdb3cf0fdf330e17f15e56000000000000000000000000000000000e980adde2310179db5f307ff0ec23c442c2e72b96316c8e390668950ded2e1cec2b5dc6ea23e0990f50e1e87543896e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e87c4ee0557de92d9db4e3d3b720f9a752d8da4f9ad6123b3dceb1afe0c812278554d05c74e18af76193fdbe31f7990000000000000000000000000000000006a5c3e3f06498d90efd9cbdc830d06e556cf52f2f6c30f56d2ee797560f99cdf01f181bbc2f1c8ed6d83b670418aa541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d6538213cb78a601306f8bd1be8e90c372af4bddb35bcedc720f9eb778cff236385358bb54b370220f297c47a000d0000000000000000000000000000000014c181538dec7e9ddaa0b067febf02fb6ebadc09da53e5cbbdb357ae638ceb42c2d0c56814df4524af31ee515219f2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079181eed3d24462bc74897c084c86fafe24f1c4271611352dfbd3afd975c57ccd5f90e42aa615c429611c745a75d4270000000000000000000000000000000006904cae0ec31d7c3e6aa8449ee530ea31885142d120227ae26f367024f56a5f13d3126d212cd3594b36e07c36891f331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d5ccd720d47ba683e7889e1b9a3ba818c600c5302dd8b4de41ce39de24ba78b0e375e1de8fdf885be75fffe6a0a2db000000000000000000000000000000001796e45c3005a795140922962a9d7aa3166db944aaa01f73b39fc3455b77884f7d75baefd13f5c123e7c5f456eed5dc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fa86fe649c2b129afb7f37f539cf074aab4978784f092515fdd3fa159f6052c34d9bdf066898552b0899409fe81fdd00000000000000000000000000000000158032329f1522d747bf442523c54b1c93fce867d96554ef47e006b2a1f106a7c2bfe8da9cdbac84a2d416c2ec42f7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eeabbca3e85887f7549cc286fc5249b0ca2143c1bd67b1e80c35ef908efd06c2ea9a9bc5f79ec1b060ecf70fad6c2da000000000000000000000000000000001448c1bb70993e7918c626774e143079c659a0203606a774f293a994c40b69983871f309b91c2b99743414e4f378f1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001540d2dbbd7bb5c3a43410f0a9c6f9105a417c0ea52bfef688bb89cec542e6e756a609b5d4dca3f06e256c0e5d885d64000000000000000000000000000000000ccbaea47d304b5fd1e62528ca555396f4416615a5c6dd7e0c5d066098f0ac65fd4c8ff5fd85557f21acc4e7dde8b1ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffa570f0d83387a4ff26273574bb94dacdf92ab195d923a9aed40134a03b075eabf7c9db5c69c950ab37e97511de319000000000000000000000000000000000ae85daca5ba906ffc0860f58ee0360b0b723ecc75b37c0b38695a17009ee58e63c5bb5804baeff275266a3aa118768e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000002b7503c40bb2893c815822dca084300a1871394f539dd7ec07018afd359610278461853d375a5b57fe0f3767bc6f0000000000000000000000000000000007aff4b8659be35c9a4da9a8669e6f19398ad3d940e3df6e06534e727787863178809e2cc79672e66946719442ae3d0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000465f658a14fd8bbd054199af94e886e0b3fcb46eaccccddadb9a40f1d1a1e8312df5c41914b4467da114dc4158d7607000000000000000000000000000000000a94261a49c1aaf17d54e3ab1efe8458d9eb3a79b3f775e96ea7d2133b8975912e873b8a8981c46d9516b7aee424575d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000705e20185225eaba9743d9b776b66e799c4883f22ff8fb93cec7a9934671b8c460b844da090b011a5a04876420cfd1500000000000000000000000000000000029f60f51d109b30e7aa7969a313faf62fbc0402e212927c470ad5600cc382c69982cdf8b1166556cc762726578d453b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b12f72b49616cee6c297527a08d24d6dde88f4cd52249f0d76168be8d1c982c93b784af3243d82059c839f2016b57730000000000000000000000000000000018206f54d28e5bfec1ae3bd7fb3ce239103450e6d7b6d10dc9b8acd2c16234c9891c8fc66082def422f1b386673dcb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001693d4d5a35beab10bf91133c1731f03d5bd7f942afeb07427e644962f7127e7afc1b52285049d6436ad1e95a4759f99000000000000000000000000000000000c18c224830ea65670de0581d266c9213a2ded20a848d1067b4ebee00bdf60ceaefa757e3140239d16d374d213fbe4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004ccd8f64594ed787886244f40adc18d06fdab060be46d7b5aba96f9484e27dabec436db52b33b8638bb446d4a067c900000000000000000000000000000000130947444d41e9427b71d4b83bd94e7e98747c990c0e219c5d08189569f36dc7c933f5fd783658762d016cb91d7fffeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000637cfd0b2f6d2a77a23260b775b47df7d2966a8ebc0a5493e1ce4a5b849c1d9bbed1075700c5910b3c10e5a9c1efb050000000000000000000000000000000014b573d573834f1d9f045d708836607b75d80763f802b75f626acfa75fa39db46246d9121ec70652e92074128d3f1a9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9ea7944b98a647f0570314eb273283e218a404a98c0d07fcc023eb3c0461ee5cd488f47792567aaf21bd6f623129b000000000000000000000000000000000b7412cbafdc74a9b0bb7b3c4b053280a136d6154ce5ff49399952e122307beb58caac5f825114c4a7797cdac9f950dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063edfff9f7d6281d702a85cea7c41ad3bc076af07484a7749d04c679cbd03fa59b23636bb5c8457edcffacd1700212d00000000000000000000000000000000045c7275cbf5ad941c919aad462c3a242ef65024c5a671561a9a3ae9a8a1c9ca41bfd18412e8da7ed2a48a8c80e078fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e25af8ee5f8ac1e6547d81735d477e3d745177b0906db211536e2ce5c9faa77aaa99397fb68e8f6e13c2d2196ee029000000000000000000000000000000000f38805d1f0efe78454708aa19a08d03c760280747a22e2a07e41a2882ea3626f2f6dd4cb3213be037208e9ce0c0d0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c8bde4608791b96ca947397be46e43676e0872c3f85c76f9df85a6a50a0e5a186e4a18427bdcac7cc39a2f63df6f51000000000000000000000000000000000ffd73415a588865fecd709a2a9570ab218d7915904b5c34c7fe3a8590ab2f20a82735edd9cd2c3464a26808ba1dacd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c632f5b1391049be0dd9d63a1d307c2f6a9c69971e4059341d510936438eb78d60d93561c2ea9a2745bf3e0fa6b62dd00000000000000000000000000000000191d511e1024ba5c00ffea3f018cbf83de05f510e03f198c03a8741e4e8013f1268bab5a43f3879c8bca4182d116c6d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b3a3b722f3929634b4264532229c25e1cbbeb2d7bcbe27ed9a7ce77925ae7323dc621f6e9e9fd563b38df715bed9280000000000000000000000000000000006d5b02f9389df85965f25616fa56ed77c3f5cb815fa796aca9cece3e1cbfbe74663afef1623c6fa8d7b897b5238bcf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123f9914cb063cced7b6bfa21e4f4c4599e0c19c09b422c75497f7c89a6a1cf72ebd560e79fe2df058b161f47cae903f00000000000000000000000000000000074789ede4d477511409676cf71383533bfb488e8be572d6d3e53ae571acd95ef3f18bcd22065a284adb31051dcb04381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d704e21957529816830777c9bfa8f197a355946aa63c14b6a50f1880dbb75de05875a6fa27c09db983de15242896a000000000000000000000000000000000138e2b0c0b632f9d01b3e7e721a471db48537447f71db2d280e3ecb36093a33ad6b1419066df052a7f79f5a4e4c89cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f34cb14bd29d06bf511f952d92139477572532aeff6ff352c62039c678ffc7283fdbcbfc9588b60e22fcdea9e32456000000000000000000000000000000000e2b45add5640480b9dd65b480bd1135c3bd261c8c5bacc1183f7060488704ff197f5f4cd61742472b0aad7d7b46f7411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe02f20edea3c7c81e0fb98df7e7389e59058a049aca367d129d5c88ec8cbb9cb441804a17ba411de7d197d599d7ec0000000000000000000000000000000002ab15d1704e69756804fd940f00fa1b37c1993de135e8e1a3c75149278a011df35a5b3bf1221833411d5b7004ee35bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137ed39fcba2df9734453e3884d21d17ac422bd9e72e5ae7b63c19fada2bd7e8ed9f97d100bbbf80f2b9d709b769c00a0000000000000000000000000000000018f1ee43e9f214f84b455a83eabe208fc2c772cdfd8e7bda8daa58ba422e2a9d71e8e3fa7de513ed3951729d7bd96c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c86fe1fc28590fb919c6d814d83949c61270756014bd35542af957b023d8a7aebf4070e21ea74254d19ecc6edf481d000000000000000000000000000000000d4170246614c4a4ee4a4c523e3970b937bc33220746db20554ffad9aecb1b47e2a6dcf89929a0aaf173efce65a5296d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca1602c13be84e3e69c7f81c3df81e7624c623aa884ffad757c97791589d97936c934ad0c6f9707618d163e119b15c40000000000000000000000000000000005f8c9b9a6f1537b8583d3f36694925fa6ecb2c00d862c08c824c06d5c4e1da22df81ffb8bcdc02fe477a3dd86fe62861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c01c3f0e5e76c378774b215e665b082da9ed72ae3091b322881c041e070dc85d7f7f6e24cec4fb2ed7a689acccfe5d000000000000000000000000000000000ad1dd6c2658cd8b43a83bf2af17ee58d9c60c8f2de6b45132d7ebbe76c850bd3f535e9300eca124f953daca4d3c489d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169d65d36c32cce1a664ad8110bbe36b0eb5c854d538774a2b70640b3f6122203bbc7af9e4f3989d693e2306d969ef5c0000000000000000000000000000000019be8bfc44f53ff818279cbe4bd24b7d5a647c7af3930141dc73296ac9fca84fed2b00622fa7717e48b34c5dbe9dfb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b941dcc14117647b4d5ec0c663dcb70ef41e19e0aebe9ceeb97d72947d6c48c7b38fe623fdc6eed42d47d5e19117a74000000000000000000000000000000000d7bf395d86f6d3155c3b59a9d76fbd72b7cc321e60e758ed5f4399b23a51f8310186d62ccca1d59199734a628fc9b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9154e91da2093749c99413d6fd7fce40afb38124ff87a841b7f0eb33abe7630b63dde7dfb91506cf295b1bc68a71c00000000000000000000000000000000001ebf1aec3365464c67cd2ba77b4a690b5d1be72541efacc09a86c141bb197d52e93f9cd6097a89881d8cd22321fb7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bc565564f6f465b6f7595d4f947a4e534927be7646319dd863733566d9ab8b101129a71b719b2bdea7fcd09423fcc1000000000000000000000000000000000285a69b286ce370b5d28067ebf270cf66c4df33d0d35461e709c4fe823a49830d91fd8812d00d045b6d3eacc3f912bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113b9404e290ab59d0057ffaee2899c49581712abab1340ee74c4c5b6facaf46dd683a0bbee068a6619409dfece5730e0000000000000000000000000000000008361232b18707a7727c024f0e83a66de8700b58e9d651211db104b1c045780de34bf9309164c8d5034c550b66d76b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009940de312bcf7ff7ed282035e1dea1dd7123cd3e0e8f04c0dd9614b7226e3b8dabe4455a97caf5fff085419efe093400000000000000000000000000000000195d4837b010f1801766e0d673ac925f73610b71ddf0be6a7ecf7575bd7f8b111fe9833b3e110dd266cc1552f6a06fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b828543577be9242347551bc6621349fc271043d3191a187930cdd941553ac6bbb263cae15c8630a14cbccc811dc4a0000000000000000000000000000000010b8e5ab94318fbf9973a6f8adc3065ddc7f6d3f0918d3eb6d71fc14470a6eb041f0b1cf370920414374dd7d4d8702971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001143833d136e1b3cb40bfa34331e9ac52533c8a64c7c3e7a3077f547c45108bf03df6bcc2a0322f431184e7460189e5000000000000000000000000000000000d11d8e052d49b4a52925a0038f593202dbfa879be63051aa8bc03e1c2f37367a34cfbbc4f5b7351e38adb7ebba36b981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013750414582e6fecd5b0a53389a44dc073970f445dd394056c3614f919be46a85bfa70d9156fa9b7ae7a3fe370af6f33000000000000000000000000000000000223df72c4c8d98619719912d01bcbab0f3bcd5f8955b1490aeafd4d8adbd882b18a8494dcd6bf16d418789f6c2a76e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120fa1e72db0c3f4fc7ed7c53c9fd77bf2b2ac89f1dd0c8af54adfa408f4a44fd16cb28346293dc599de045b8d4aae850000000000000000000000000000000017734cc479ee2515197fab9b3cdd4558ba7a304c4ef2495dfe935c7e54ae4e48101ad93b09b83ff404969150011e54b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001de602f8b09e9d47df893461e4db65c86f15d09b309a2399101704c42fbe65dbf3d640e52b571643f75d552f405e17b0000000000000000000000000000000009cf90af95a3cf5ca6e5cefb414fc923dd139eb1a815babd25057f0911bb0257267f73f31fa3e71ef5ace6583d9529b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000041cb05deeea4e41879a2340498c97d9c0aa459f9622943c6387a5e32e5b96ccbc3c335c369bdb7d7bf00da7d4b3d9e0000000000000000000000000000000012c92598b88864501ef55b8d9894a3bbf36c5a4ce12b6a9a7024f1f84ac0537a3662a375a2a28d4b723be60861e65a7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000784b8b2dcb771cd42e543557d98bae393d652e71a1619625dde33e86079cf216d32bed64ad6090a24c5aa1abac874a400000000000000000000000000000000026869ece7ea865928bd81064913eb2570d0569f06cf14f491d2856282928c2449f39e772a95e6205a9e2242ba5167581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009ec383fe0f68d41668093caf86f46d40454937ad29ceef6ceee0f3522a9f52f35fa08b2a7a741a1d8acfe5dcc1c6da0000000000000000000000000000000004be1cb08c81226fb4c7f32f086cf933ce5a4af615e657de68fba967c70dc50a3dc013d32095a187702ef9c9ec8fdd651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001601e253d663c01427194d309c2a311a885d4ad03b6f336433a4f5aa2cc0c0fe2c55933c497e19cbaa172132b25e8dda0000000000000000000000000000000004295f9fb86aea6e7c1bc26b9e5468c7fdd370924e903177f863373c19da19d7156f71acf61ca2027ca137b425c595801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d293a8e0633af32e2dc5c5ea444e6461cdfd6ce6faf50b991e31fc60af96d1f2b1e21289a8eccf2a02a9063c735e1c0000000000000000000000000000000015e7ccfb25b90abb4b2bf11bff4e08f430b519dd1e895e34ecbd879bed4914a3ebef8f19ac9048c5139cdbdf3055397b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc614eb8c27fb9af064fdca8d5b4c90e6d719067cd86869cf0652a4cc037d69e2c7a8a684580843f73f0d81d1edff1000000000000000000000000000000000daaf6f172f31d801c87a623786487db9e2929d8701c7e212fdf997dae785b9bb4b9d5321d99a341773f9c07dc08db031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a6001714bfb5147b1b1152e0f701147101686970779037fbeaaeb0ecef8a0033b09619d76cb8e6ed42f72c0d179cf30000000000000000000000000000000007138e0874f0af15535481860a784ea17606056e030532f8d39190a18ab4e9f4da3248912f656a8ffdbd30b7b142329d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b57e18bac0ca210a48199567b99af637afda70b9ca8d523bff6fdfd401e0ba139f47d1df2464f850080b07e08f26d0000000000000000000000000000000003d4f64caf21182766a81efc1e0d90dbb49836f9e3fe6798d3c3e6d36b4b147f3ebc5c8180be356024526427abd2c0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c421117f5ceba5d854f4f614172e16aaeb5e3553f1cc0daf6c0eeaeb7946da146bc8641710d701ecde71c0374733b800000000000000000000000000000000166c20ce406a615fab1f7866ae2bf771563c4468441d9cc0db941a1131a37f4eb25e7b158d66f790069120f0e49d5e1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f369fcfb0b9c79d581b05364869b9a43f23aabbd969c37f148b14a924c560f3a7e79edef244d5350cd3378f9f2ed52700000000000000000000000000000000179c661350bc05d4ebe4406ec2ea5c9bf3f51e8140931b9b6a6b5d78d0ad08fb51a478b57ebce35550a7c2c9948965d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb091ca17c67e4320c285dc856703ef4b1db833f4e6e367110265decb53efeba8b3b1ff4ae96fe8c17f62bb977c67d500000000000000000000000000000000065e5f1f40da76caa9ed568e4c2445acf4f18eb72c653eb3850df8602b1c805c19887c9cc8d482bfb1dcca97a7a7e1d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7858ae8e362f80d06370212027cae6f2843022041ae296640677672f9bb4760d70dc53ee7dac9937d65173b7aeeab0000000000000000000000000000000019f5f0f75e4fbcab50a030038837dad3f72574ec117ab4fdd0b63599a6982b7d4b41aeeb14a3c23e8d0052498b16cd011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145e2c82b834d2cfa4307c57434646a418068ccc68ae2f2eae21f3c6c0501d798b6a90fd891b1b9403501df7c0deb2ef000000000000000000000000000000000fa49a30f76b510136f654154fa06bc35f9b4a7048cc5d407d175cb0902002d8a0a92cd2e77e1a938910625d4326c0c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013988a56a09788ef8d402926f14e11f21dcfefb0247303a9058ead03e68c9683dd24abe0c273907b841e6dbece0a6464000000000000000000000000000000000d26709a6e022caf725febc3c8139278bbfc9f995ce2b93612eda7426c815900fc3a0113505a89d522859bd817a40d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600e2e8afb23565d2fd50ce70012d21714aad68ea82f221519502ad4b1b0fe8e536c039a0fa121a9e27c695dbb4a3b90000000000000000000000000000000014819c937b51d0af7a8875536faa6a8e790c60b0ca9bdbc7dead2e882238142a7794c3382bb73d02d547bb74c52298d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199683539ad2d7c34963b7c74242045acbf28172b87d05011e86fb748521fe84b36bae7277b52b1561aa3e6be4be637c00000000000000000000000000000000098ef38b1fd6f047a86f544177473860ca147b48bcec653421828a16a9d98e27ec4c0f104d9413d2820211b96b6c74251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000424a335ddba0dcf0a736f8154177ad87dd133a65544d047a1e7c14c91fe75bb7255fb65d00e78d4799391284f3bcab90000000000000000000000000000000011a32aca62cda6bf5fd47520d52b6c7928418f0fce747825d3d9a0a7456e3df4e14c61474d9632a98547a0254ed25e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001238e79aeb6636d43aee04aa67fb7d04ee65da479f92395225720dce1e5197fc2eec954faea5eb8de7302e207df9209a000000000000000000000000000000001858a4ab878fe4f081d7d32847bcd0f8590fdc7be6f756158c71ae6aff662072fbb8af6d5a78b3ccceab8d83bfcc591c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad5cb907a8f6670b25fc0138ecc9093630e9ac3820042f9e3662c43db53a0acb2762482045ac030a7422424fe9b4170000000000000000000000000000000005c3dee62de9bb92936a00e066ab76456e9d3c35226eae4f14c25d7faf8b6dd3428a5776a3da21fd943887dfad2291561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6280f0a614598480b4074594d6ffdb57985277b2d79baa01712930f64c5028e5c5a288a60a3d03c75e0a8bfa4b32b0000000000000000000000000000000013daf3e4ec5fe1595152ad31cf5a5de9c5ca4a7c7b7c18c9f46fc56fce68fbba14cea302f97b9dc118710399efc133921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ad1e54aa9ea5fc576a74bd71622bd200354455f73a84041530590453cc2c3b1836d600420812d441879c5b44fee65800000000000000000000000000000000097ba0d583ffbab156783943e86d23972b49bc839dc9d2bdab4e29741f0cec51b584ddb8978e3fc8c5881cc5c04a84031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba786b0e864e382afcf2a2d902ec818b7cb4632069afabbaa2434cbf1d52feac99784350fd32628462705778b04e7f20000000000000000000000000000000017368ad3c1cc0e8ad79956403c1c756bfef99ae7d10e3ec17b774fc9c5db90b3ce1a2dbd48c5817c45c12e1773659a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173393717405fa8a11896c9325cb8e7afd270fd4ace6507ad2f03d449b5afa226cc8db5fa24679eae2124c67699360630000000000000000000000000000000005ec55dd33152794f2bb99c0c3100e41c90f18e6c1de9e750a6c0729f51a9f2a6435bbe14615a5cae8a72b2391e18eef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b5be17463267787223e0855d15946d262d5f14c36e636289f2f45aa581f89a3964f9f4e27ed673f6ac45c4e922f8d70000000000000000000000000000000006a1e21de777f6fe1e4d6947a48c15c23ff66b69315bc7055d442bcd7a9e002eea21fb09d53c6a5c32ac8f6f454c985c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044faafcf404c7e3890925eef240919b668891fba385765d66a72aa25b9788fc66af2160ebfc4d7b9a18fa99bbb22280000000000000000000000000000000000c44efac6f1e32dff6809d563a389ad041997daec740af25a70c1936ebbf3fccc185c6b117aa778b24bde67f318ff6911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001902810d7fbfca99008d86142511d3cbea0d68d8a5595ce9d7d4b57b9a224c70c12e4f8b06c75a84f7694619ca36238200000000000000000000000000000000075a69a11fcbdcb083e88044fc7b0f0f997454b92517feeb6dedeaed1c6a00bc88d2931a5a59daf1ea42d03a9923d1c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b35b6023befb075c9bfd4c0a7bedd6abc49dde537afe62a1daa6d90113149bf6ddc9bde129e6d7be8f95652d15f4ba1000000000000000000000000000000001196593a29fa3a10134307ea4334b9a04457466617bbf83a4aef71afea937d668177395068a36a9a06623376841412f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc3fe05ade32c478946ade2fb9f8130feddf6a0036c820795242e37ec588a7dd59e82c96114875414be86e672dcba110000000000000000000000000000000003e78f6bb2a353fb48c95c0e5dfb44e3862f2fc7af25b51e202327cd20c8fea1a6ee00c8713b6f2e761dd35e94e6b82b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2e1589176e4d9d18777e3df6d3c8e08210c6ca96fbb8dc6060ec3c5f2e360f922343ad2e0f8e3cd1919990f343258f00000000000000000000000000000000161ea4389e89f80b8193f411a6e223091c2b1ff90b2d9093b0a4e02bf3d829663db94aab7e02f972c55c5c639b1f7d021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0036a5674bd0d796990eb8f10e7d4bf4190864228d93f981b4f0aad29d9f3d1ef3343d7479f31fba4cc8f045959ec70000000000000000000000000000000007a4d3fe27bf5dc98f8c9a66b30562c6ad5cf0619c14f869e0c7a2cc26843eec5d87dd2d6e211d893f2919c6c1e74d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178751924e460a4c4d7c07c6b2dab58c0d997dca3eba51041a7bf196269509af14018d3e15a0ed3b96b977a435eb8d4a0000000000000000000000000000000011ac437acd31f2a5d38a665d15550d4087ea62ab987c8f332b40c4e8bcb5ad44b0de6aaed228880a6d692176a88adb0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087d58abbfdffc77a46569262c746ec91c4b03399b7d9e8ab043375cdff0f6373fcafdf84e1bd6098917c3fe9e12d2610000000000000000000000000000000017e332732034531da2f39ca9744c4616ebccdc3b7c6be2b6ab0ca7a108fa6d0f0b3f51c4dc0dc69c868b8959c9e12c641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c01d508f330fb3e4c9aad4bb0aa45fea1c8d833886010005ac65f028e09705f39c5d712e97d42e922afe68ec9227cbc0000000000000000000000000000000007609e0e7f664b083e96febc8b52af7ce330f3d0591778aa574b38d330c1fb113338d310435ae8a215488589e03d67a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015133a6c5b8becfd8b13ffc85b96b132a7b3182cccd710573b91abf8c92031665897345cb60baa10de673e42349218e90000000000000000000000000000000000e5ffb24009889a6c66c40e49e85fd210aa44c56b94542f9286279a383f12a75b31ee9542c0afb02d37e33046451fe11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000865f597728f754b931b4d262c98460181bc9201f488b72efe6a7fad2b7eda99341e771fbb45b606b2856db8f61d0a1f0000000000000000000000000000000005f25ad127044c72cf6bc9e2926c96f68dabd9dcf0a8ed96097de04bbe8401e0430f02ff2a81b2b1cf69891d29cde7e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557dd5508da0d6024fed5892e439987388ea82015c7606c3b330be485ba0b7d838b077d482b51e32135160781964a8e00000000000000000000000000000000195b89cc39d65d4294ac46fa2e8b7eba0a0c2d1a74b70e83e15e0381407d7fccfd512182247f5d87daa9ca38f008cd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011274b2bb04b713a0d4705bba63e2fafdb219166e985dd77896095268f5f7f5a27df1376af47f664011b3994ffa6ea6f000000000000000000000000000000001688a6f821056a3011313b44c0c1c30beb01bcbc58677ef926ba658581aabdd4584673cc2c59560b711031c84bc8bb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b98870af3e92b92101c21f56fba66bcc75f3665983938736f417c9827db1802b4858d1362d1f8dcd796cfc5baf18be0000000000000000000000000000000009609130c9e299ccbf0c0aa37e2d2a6d6457fcad697eb35f34d1383ab79cc51e9040e5050671ee6b7234ba48bb4086691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e29224ff1227a2319cb893060365c78326396256b979ed77035ff112290c119e29a19b21b52d0df34d5a2bd4811a0600000000000000000000000000000000008c8caad76963e7ba7d15b1e60bb1a6cc9f2ccebf9299daa947d3808a52d93f4523a238b5ecc50cdf7b954544e32dcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022c8ebe8ba1e43eac1a0cc24d1341241e514f976d05683942f213809e6494a124599f2837b0e9f67cea1a2de8223c460000000000000000000000000000000001b6cac2d4bdf9dada0ae6567eef08b19c7319bd7d76fd6321a59f5a42f20893a75791159eb9bd42f1ca490ae9300b1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e86fa869b27771e6dd5f6ab81b12f290696e760d52dac9cd4050ee26040d0179ac0b18e8eddac37cdb411f1023f77d90000000000000000000000000000000005b8ec54ce2816889fda281ffed0f81a99808f23c578b777a4b5e0a915aec1f8a1b643ef5a5634ea025b83e3a957c9f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112095af9c55ec5423fe2186f80a29bfd3c5cb72d405d7adba1ab8bc6327ee8f28b73298095b7c118c5327db6a48b0f6000000000000000000000000000000000fd45756f1de446bc751fadd2db191177f390ffc9139a3ac71f5dc5e4698dbc21f8406b0161bd8636c4be2cc85ccef121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ce186ebdd55f6ee63427eea55a7e77bf0d2c02d9037c5b20d0b9b87ad24612359366c9f01ceeca1721c84fe34ee2e300000000000000000000000000000000037e2525373e198b28d389ca5236f361a8c88d9ba41ac7f0347cadb6a3b202d8574e2d23562046c4faca8dee5ad964061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012af791919fe5ecdc2e9c29edb3c895114508324eecd3fe0eba717730e3b6b2582e5055dc0a49afde3826abaf1ff9ab20000000000000000000000000000000012fb10b6ad4cf5e50e04763a71cd8642b761ff18eecb74c031607535777cdfa77dacc6d2b565d4b42adea935ae1b226a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001944c2bdb35063a045b5141e652fe102e6dfd8b86afac8fcf3c7f9d8305909bbccb644ddff0e6647f6c543dac45a32660000000000000000000000000000000000e75b7c25d3a3785bfedb1a0a978e57b92087d213101c352315d6d8b6420a3eafd2d05d1dd7fd70c2a9405214585cc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c4fea0c2570d05f7bfc1fa955cb16699a7a08797870c43f3569a41050858e2968d0dd259cae010744771446d55c150000000000000000000000000000000000ac8c11729008232195350eea6e604a594abcfb9d4efc0ffccbb39862e8aae57fe1e2aec9a4faf035629d818f0897e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001432b595e90a783398b918a4edf2a7874e825ae621f5fe6923d38c6e1711a17138f3dac96d6787b5dfd2ef3d9af831a3000000000000000000000000000000000b8adeb7b9e46f292461db8ea4da0a6e548d7f57a2cd7601d97a959be138d21108e5f71da7baae98f3fae6167373d7411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b04495b9765cf4479ec1c48f9c2f59f8d568860838a5e06d9a234e41c565e8e254cc7795f049ab8b88703bbbae5198000000000000000000000000000000001026ecc5eea22e8a0468d258847835dffc12842e3b1802b65745ad043c4368e26e2a5e51178ad60db3604c57ec9393691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007eedaeae6295531b6b9c3de66a54a7e98f5fe4a6d0044adb4869d1b896e64d69390344420af491eb8447f4b7fcf1c8000000000000000000000000000000000ea40892c6e23a4f2b3bcdee4ee64531456d15c37b60e17ec32319b742eeb113511246112ae6f6b25f59d965223b66f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b314507f254ea7bba02a98143f5ca7701dbfdf091095b016a6a7377dbf3fe0ba2f1d5b941a47e86782cbfe20e79d5000000000000000000000000000000000b0568164f38bd8350c65f1fa6a39b20fc4ae73d1eabf25060a31640e30445c82ad98443082fc2ac909c9364a04324681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001644242da17651c7cbd5eaac89222bc82c75a3df2b40902460573b7f2aad2f1ca2700d86a7b7dfff411a7f0563c643530000000000000000000000000000000019f9bc9f901762d658d9bfe53f0c617e4d37b4e22906254bd262a567f5a3b8eee5d5150eba74fd0b70dcd32ad9c3bfdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e1535ac548b33ded6cc26be524ae7892b065dc4e5369f0c9f2cd982c6a08a486d14ec540ecf7599127734daff2566700000000000000000000000000000000030e455f011ae5f47c6e49b51ad629a67e521e07bbd97cb8a870db4a02e14d818375a30e8bdeedc06c556bee97381f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000587378f429f92641d46381881247c5205f165baf9ac9b7dd7a7b80b698532b4b5cc9edc4f2e7cf4fbc21b5a5e049e5500000000000000000000000000000000004381d30959d87cb2af3dc8a10b660adf58271c307aad22d3c9f69026e457f5f7f4dd52dfee3b99d82de7da483bcdf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000934ef5ce9bc7f8bac10a7e80ba1b2e5450d0a6e168515c426e56c9c29fa3697f425800e0f34adcad9af7222bf5668d00000000000000000000000000000000011df5cbc583e28ca10d7317a7ffffb1d466245735fe0d54fbe6c816e47536a0d27310d1fdabe89db0ad73ecf36b2f6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178977a4188dcf62995efeef158e45c2a5f2ee6898a25a3509d0a10e11a74da51897065da34464fa3426707d0b9b5736000000000000000000000000000000001887d9d7b139fe689687fd330884f88fa97c3d8f5b4f249bcccc9ebda6af417ab0587ef7e704ab829110cb4f59f718481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a29b9eb38e1302cd0a264021edf027d1426c1d9b1159014c1a11f0c45ad9592072132fcdc73efc3923a73f58d8519c00000000000000000000000000000000165c6b26965a3e5d0a01c47c459b133174ecd9a9e7e8e6bc154a3b2250975e3fb7bfc537704636b939d00d9d473dca631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5f1145d783d10e60cdf1287341a8a2838d5c8a798fdc90cd9b4910c6da4e237aa5142dc2840fd158a57899a14a6b40000000000000000000000000000000001b2e1daaf9853f7b880377a29567b778d3d4200c6227d171c54c4196359baafcaf5e8d20a79993fa8ebf5473726768a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f56aabbc86322c2683de66ce3778e6e15c3e95ec34a75cbc72aa0dd9f42a7771fafb4d81b9c7e82306feb5a7496c9d3000000000000000000000000000000000200f7c472a699844177439fd274eb80dd5d7642c4c59d5a04cf77f585f8d7689d84fcecdd1ead1291ed535080e268e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133493bfbadf2b95f1dd8bf263e25651c0f10a7f442ecffc5ec905739c2999d7e4714fc71f63170f8cd4fc3ed4160ce10000000000000000000000000000000019397e5fc4d40418fd991ec5d82d469b5133d3f5c63084e6c36d621478e5c05b0afa4e0890892ef8baffb743d8c7abb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164532b0adb51b97cd8c46e4602a153a72057ca5fde11e82428f1c7a32f00c27f14605e6b5f1d58248ce7e5f771528d70000000000000000000000000000000018270ce81d72cb32557b77fd7566f68cd152612b80325bcb82e94aa301e867da3666245b6affdf6d8aa3694933edba691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6654fad1a9cb850a999c5ba5c303efd3416db092cb8ca260d7e15b1cc76250c884f3fd4d496b7559bb98c0b5b0fac0000000000000000000000000000000003f7bbe509a39a8e73a10286a7d5c520c80588875f562523af1aee9de9f4b0902df29d28d1bd20adcdc2f2479da49c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000709656752447787f2513541f3c1e147fd9df83893c448719d44af9fc0cd7397ea84c851b899e81e32894485445268c1000000000000000000000000000000000d4a25806f432f56e85791c3e082de11be5c75754a781b9c2c126643cb5a7f5ee77c6749fce1c0e7dfd628251b5f179f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9c12164084e2633a083b0ff4d2f69718fa141852b2bea1ff56bb90baed017e73fd4806ee684a69a872dd102685a5cf0000000000000000000000000000000004c6c6f5b204e02946b0c1deefb4301015a3002cf9c0394d4b09da2f034d3caf781aa99c854bea61b10f7874fc4bcacc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156adbb584bee59620251323f9c2697b9f9b6d527a85339c0781078154ac893f060739f03702334ce6bd4be18f135ee60000000000000000000000000000000011960659ca49c3371264da7a4ccbd67969ca5278ee0a5c24af47e11e761b4444f84546b800f566f0924d25bc6621b9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b720f853dc92da487ca06d48eb48d0cf0826da51464d75d4f9faf38c18dd39e3d5b01d2717920e3df13e4044c1bc21e0000000000000000000000000000000000e6c8ce7b0df94afad12a600166998c61b40e42e049dd600189aa4945345879eaae059850b71a63e239972fb8b3ed9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf8a0f9979d96edfdc6f7e7caf64b8611427d4c7c7eb4b350a86d2d92ab2de914d924f81bd5ceb0855b77baa3c8d2a60000000000000000000000000000000011cd82d3b5e7e30f39aee829cb4f29e7d2edc199c123278e1df46236e0ba7dbad9391156e752bae633514f865f3426231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ef6fc23899be1f5843f8f60f203e5a0ebe2f1d323cc73dc16ce7243e98d105d8963aac0eaa3a0daac587f4ed8ec8e000000000000000000000000000000000422418de2168fea3837fc30a4d9c5ecee3a57892de6b360a1ecae6e23e41a25e6246968e8fbfe4317181ce6d13c22701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ec41bc0d0cd1bef5047b042192f75be67e3bc3fb779ee7539e9d9fdb48933e001b58632d0a16fc3f8591333d5085c3000000000000000000000000000000000106c4c3cdeac0dba701dd10676f51b9a0803f8146591d1facd118fd25a02ca35ee7dd2b7db9eab0163316fcd59335911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a71f669f37b3497cde82ecbf0811d5f53c4f3add8e4e4355c40237ecd40689ed21e50b6789b99f00f25843ab47f0706000000000000000000000000000000000c52d4d797a5b212323b262d429144ed1b04e26622ed74d75a4700d1a34ef2f8da51016b1a6ba28a978b65ea6e8214bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009161754ae54a4be331b1b35f38e30f3841c9c60ec10a67e43b8510143a70b225328453c511b48afc9dfdef1438cedd90000000000000000000000000000000017c1dc337da61b16978356f24c1215adbfb9fa249500202aaabfa7840c6d265b37fc5045feb3b125c3a0afea8248c0381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002653c587522fbbee9c7f969bba1f6a0a7f3329108e8e431f68751570d63ee6f3e111274ad1e4a5f79ff7f8e72d86c0f0000000000000000000000000000000003636bb66d97b490ba6c02c505803ee6f5bd2e216ae048cba7098192008e68209a67c077e2d0a962ca911f2c897ba67b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b61a8a9134805b78cab9c17bfcd07479fa108cdfe3edeaa8b46b9a287fa747b323943a736c53bc80d405f003caac980000000000000000000000000000000004db63c3ee6e1f942ed62d234f0f5e917ed6ac3c903b96ee9d071ee07a8d767754dae1d40b473935f6c6175b2c552cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001558387f4c9bb9f5224eb8ddd68ec26ac133d2df08e6d81a0c1878f2ad7a9cecc57a7d99ffb0f8dd65ffe3509df5d8d0000000000000000000000000000000000870603a38bbc2454577edcdd742cc884421164468c6bc6024e471ea698df47d2677b8bda3b95df24f64ac86769c15ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8071c35389d02ebab67b4ddb81e4befd28970c9227a06b7cbfdad4257008bc3fb4f11fc56b7c06ef67e59bbb293609000000000000000000000000000000000c08914cc823559d749654260381ce2a34476cebdaf707aa17209861da7702dc00f10d440efe4e53d31b2bcb56f679041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194b16efde683c06a8fccdd5abe2059b07e216572d6397e6e8b7292616a86dcbf3a28260b1d7b49459dcaa4a437d12d700000000000000000000000000000000036e686593eebeeed81c0138ea51733ef22f6c282ab058ae4e7b534b8af124ae428ddb6b0a71b32835cff320974409b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121e343a8421ca45549ccaf3a674648b45bcd24ee297f91f3945f62a6b30d8fbe85b3bc9b290fb06d3ba9d7db566789600000000000000000000000000000000050949833c055605b8783e26cef0072d112490624bc3ba7fbbc3dab486aaa413d1e2bf00cd2c788412ff41b9496218691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ce9fbced65a4a0ce7b86d75afce01ced0700d126cc3b740d7055419689acfb700142a492b3ad1e236797ae77b5558000000000000000000000000000000000cec0f90a956cf122d8dd64d1e09ac0927c35a6a3fb4f2f92c4bc835996d60a7f294d410ad90ddac90ea30ac491242411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001473fe10a4b7e2e1b7a8c083553eb3aabe4219e9819c6e08240e342f1c95d0a29c5090948024ec6a77435ea474b0f6b000000000000000000000000000000000e77bf2e6fc185970603c29a0464c8c938f165efd244fd4f450686589337b9e9f0a1c92ca73ac8ecb33679e89dc585881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49c6900df36a63910ab835c7de14a841267c468c9482141cf2a3e79b339f2b7c3298f759504e11be23bf10b326435c0000000000000000000000000000000009fb36cc0f5d4803737aa198cd7f657ff9635f56076fc25ed18b3dcbe35519d92cfbc6c8bbe54f2b452fecc9c756e2f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b44e4d5da0d8ae286a3aa6a6155ec436c3ac63147687a60dffe88a1a762ba9fd753c73b111fba14c16746484ab79ea000000000000000000000000000000000a92a5d031e0b8075319fa5c3200c5d2f766aa960f4f61d85baeba65a5d17d7b4b02991b8759b958d63fefcaa005f03f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a724478556e65eb32bab3a520422a843ff9309d26fbd601cd23b078521fe4b561cc13a8a4e9752a1e9789488dbee150000000000000000000000000000000014081b1b0dce399df8bde059f7fe67879c1126e9ae063e7e226766260b30ba59549622c4a8e6e20df85b053f8a84acae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f51dc11a317ceaece075a62da25f0f4f029d7449540207213a8d5841b7a57f41f92f0bd9d798a005ad3aa0fb4ed050000000000000000000000000000000000379332973464fc62b26cb05297a4a0733b79755cd775c51677fe69eaa5bc1fe957fa4579a20dec17cb2307f082286bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000575e748867692f6286163b257e64e28b46bd5af2cfd268143711b445e80b23fb5931694396cc5615958b3b44bf489a30000000000000000000000000000000019971075321b105447e71996faea681e441cc2e529a52c852945a62c99f0d92cba674a1f70587b8c755467fab72fd5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017668cde6fe168fe1b38d1af57284893cdbd9c06372715676b5826478188c83cec280d6937c3f470b680cf31b96d370900000000000000000000000000000000034392441a6b0acbf6b11e035ee0f7ed950d84aaa361424f52956bb9781e362f48ae6b596db46d0b3e539e24a722ba121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee31409f46f48a480bea1eacbd0f5a6d3cd748415bbd42406a0cc77090c32f30c5e2cf1fb6b2fe2b6d7b09dfa35ecf000000000000000000000000000000000024cac75bfe6c5b6edd76e2cbb885780410a43ec8be9295a1bbe30fb90f41dc0823316a8b91c8b239ad0de8ceeadc1961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147dc460a6b1ec8f82d9156accb418e0410948f6b22c6332a2ed9a562f6feb0967ef261c5d8cd4351141acbfbf26b6d50000000000000000000000000000000013003c7e5ce47db3dc4d6be2b688e51931f0c4b3ab314743ae56ba7ec2e4288b96a846353f3542701d82b90dd32c9fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163070f474f08599608aa6367c5d9c736f2842d995b408387f9fe25fd0c142e6182dbc50dbba556f25843ec5bb83ffa50000000000000000000000000000000000840c7bd5918b3fe7360d191ee178feeee71f7e8d13bce81025f00641cbd4639ff55558587f40f97ce11417157775801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e84e3a74dbb55b995aaeafabd9043c33c54c769b1f520763d2a8c889715a183f575de90d9ad00ac389dc5996c7466cf0000000000000000000000000000000014c6666c7241e3b95ca489cc435f8cfb658be370d5893a514d797d690f303b9ed96255419eac3402a889bfbc2e75589b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005dadd2862ddec6c23a89b6c0429d292a8ebd5eb9b0add5b1513e6cf0b599f9063cd0bbac2b30c4fcb349b65fa097880000000000000000000000000000000006d9e0416107ac597b36caad37999de8b878f0a310417921832cd61f0fb0bc530fec3b1e858be756021f307ade91a5931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a30491776ff6465e75d9f89a1122ffb0f9ad8b1c9505a239016d3f06e108afb8586899fbf25cbf18ec6e1318c8446e30000000000000000000000000000000010fcf81eb321ed6b930f7631bccddf16d3fbacef02a3803db5d3abb91685c0258f6ede867bb2ae29199ffed7777422311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1af6ade8c405c8f509b7828a754880791d9ddf4322b963c5809620ca1a8ade8863f4c432e379d8b9a80fcce4925a1e000000000000000000000000000000000c6638c39623036eedfd3a9ee1c6f4a2c1a6b62d70f71c59fba40edeeacd595969353baa8066c20de04c44a70c29a3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009357270bf46560cef42dbd251686a7211dd1927b87f57519fbd06f902d282b9cf3fb0ded9e3cd4cb602c236b065f77f000000000000000000000000000000000b83bff22f3b795f025fe78ac7ff1a2db600c7e64fcc01a0684ffbf314c8685e937f49f00a38bac4ae16069dac5e0bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091356e68e8f754a1f72b1749b38b4545ca9ef8d6e06e8df6be16800d87481caeeea3c68dc75271ae866e5b4ab4a5642000000000000000000000000000000000d292422226d39d78ebc8d326a0406ac1cdb415619feb8754afd7bb31397f945d418f18077459a32807dd5f492f7d13c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000680ba8f899e5c96cf0964383153a96e523e2d97a2510072184e2b99a4ad70fe95ec0bb84798c68fd7f6238eb32187ff0000000000000000000000000000000004c52a429750a71c784bbf0513dd98cd45729aa24a55cf21b168e5a3197cb47c0a5c313c66bc3ff6c4da1af75bd1b1c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008df700a7348debaaeb2d1adafeccf07687f0a46c6aa54365f20e959933c9b535fdb190c7384cdf0059a589f704e1eb70000000000000000000000000000000003974849274f1f56f4a8b2e9ecb7f0087725708f470f840d287813b45463a71366d04d2f157c0bdc5963d1beb0a983251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013055a2cd6e48a80e859801518ed959c7f22a16f1cfda4840c08b6291406e5659d9afd5fc4e66b6750e034a4d1132fa000000000000000000000000000000000fe1f227e8141099a8370a88cc3649857f10d06f5a5ea77b39b401ab96911bfa360967592e6660dde6bf9db838a649411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b097ab40a90baefb6d09fe9a9ca66f170499570c9c76bd8dad56bd923112304b45dbe755a9a334ccb3f2dae7de617c0000000000000000000000000000000007a8cce5344f8b211088e50148cd2f0d359102bf3689e398b2bc1115a96626859262bfdebdde6875db4066adb38ffd961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152312f40868cfaa1803d17ae446f31cc2e2f3e8fd6c6bc529ec2c2b24671f38d94e2df98ceb0fd9787e7010895412c100000000000000000000000000000000124b8fe0e4bb4a2379451ece4c29d72811f1e3f70d1d51af4baff5de42423be1bde91cb409c2de019bedb77978a3d57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5c6892fabf1ea76b416613789579e5a6caedd20ec486d7afc4fc84eafc080c981314d0f30f6855dce1b1bdb4d0ee0a000000000000000000000000000000000dae57a87386b0870089398d8f1faea4038b51cfb9cfba68254521a54893bc86b353eb3043893a4df90a5788f909175a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115e0044af94fc3a9e9e2404c36f86ea140515eee337a847af8eebd884c243b069fedbcf1440c0dd5c2a9cf0cee9d01a000000000000000000000000000000000df60cd5ac4df3f20a03b29168b28ecdc3d18a85e69800ef3e26e48a9d579a5602b8cb1b45ae668465e8ec022dd684931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3dfd50ccfb89d620be5c275e0e2e110f1d23f85e0300f5286a1c0a0224feae11419834941ad40e8ee6891083d2495d0000000000000000000000000000000003814aa2439b63646f2262752d0b5c928532af07f1ac76418fb0f93a80b95087342df42f359cbe168b3d04b0e258ef761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bf8c18eeca8a1a25747cd39eee9c2e83c37ab1e95ff357424e070688c9e3cc4529e9ae66bfdcfedfdb291eebdf3bdc0000000000000000000000000000000012f1992f566011b31eb932ae4a9264727de154dbacf579ba78bf148f4007b13bcf80ff188e867499e3e699981d90cc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492efc24fdccbee87adc55e26276efca68fe995408b50dd48513c0486896248635024da4cfc215fecbb7b019b80654c00000000000000000000000000000000065d232c192fbf5b3d548232322983f079aa3c78b41d74fa4b00b9fb0adbaa2b91bd4732a1b74d813173aa4a6ecc87d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019971562f441c69984518778bc064ffd51b12804b1fb434d138ed1fbc99e935e248de40995a4b0378d702b1739201a25000000000000000000000000000000000bb8d24a48d522da40b7ea26b6a790c66e42d98eeb1edee4485d273ef7fde731012799964f7e618bfffcf7f977a0a9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094d794e7d42b85954a6c0377b53fc53d84b0b62d32ccac4b74bb25b18859cc39395b0464fba4b35a7470c9c2f446cef0000000000000000000000000000000006db2504333d4de2f3a4f0457a3260c57e8f47e8c5dbf29e957cb5eb1daf025495d11acf1265a10c6f5b1a82114dccef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008912d140625889210d4d72edd0a4bb46c1645b60e590a80bc78ebf199b64c5147ed3363a855593ed6b1b5959639e5bf000000000000000000000000000000000545dc5a2c4eeee79c00869e5f53f4ba87af9badbf7234f2cf8449f9a125da72515df437efa261d629009d27822969211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a57e68732ad2c8466e7267bd9b793278865e98df1dd65ee19a774d60224e709033977fa2ad4756007cce7016230f1000000000000000000000000000000000c544802c42028979f2cbecd9325cfcebc3f4d54792c09f9539d2b4a9f5df8b4f9631ce7ba2a6faab75a451f67cdcb861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e3f4d577cb731d7d620916971bcc310417b8a2d1b9bf3fdb387d161d722f495b5fa558a99bf4888c30d0ed7cbadbd9000000000000000000000000000000000b03dac7fc647ff3aa8081d520ca5100511637c6440d3011ffc5a40bdfb85b44bd257f5f0a0af2184c668e76ffefc3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c2dcc955d3d5dcbae3c50621561afdb27a146b5f761e2d31a2415f320f168da260f1c971a84ca06c34768888f87b850000000000000000000000000000000006ce6f027052a8f3e65e5a72d671a404269d4ddd413a4e02f3f7efeaa6be324528fd6d159d4a4ca62b1aed89ad39e3c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a9c80cabf0e987010638b5a6733c7418cef664d5671b0b5f5dbbcc84c988ab8356dcabe7c83e52d941d79130b6c1a000000000000000000000000000000000b0dc84a67177e72879e3a8685cb089971624b0343479418cb06f11c66dd2b46eddb5fc52d286d3d8da869bf9b0553461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b9a44a6231e23397a7f926240a6ff6fbe25411eae71b5ff9394b7c41db03decdf75f900ba8078834cb48bb7f38f0c60000000000000000000000000000000014e4a60dc0f81d9134a1e5a80c4abe82d6a73076a341566caa844be47816243475b0dcc5d7e43e6e427321ca884f0fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098313a197b57ea3afc8e0c991440c050bc4742624ac528f2dc80c36afc646be75fc5b943211ad48387b8c4bae6ebf7500000000000000000000000000000000119987d5698b783dd6c81e564c36f312bc552f76977356e3c27d6d8fdde8a79cc12e88696ca7831727ddeef65b7f9bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d994253ddafa13ecacab8a4a60bdbd6a445920f96da4518b89019a1b7a242eca83a673ef97088c944e2f94ff85c16500000000000000000000000000000000192b0d826819977548f97aa59d3d3f97e75dd73712cc9a77b0f8d38469b2e9697301e7d381a5c40a7bf3273b51a988eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c3a1006bb9c747bd3ebd657d97eda34856af5ead590fed4f655424bd0b39d7bcb6ac4bec898b581711356ab91ee7900000000000000000000000000000000081a0caf40a8f723f9d1e69a541e58807c66af59a42ea5625790cc7fda9c6a9568608b0f0e404e05d6af88ee8812df8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019159a8197dbf4d68f4ecca1a51339c30c76798de00c1ea1e78e9fee9415bea2741dcc0b44a0e377ff9edc41cb47f9b1000000000000000000000000000000000124d14efb3048190fe2c7e0117830952fda684db1f9f027a801ca400346e5cd75d1f43bd6a586bb2afeca32b9fba2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e804f3584e185bcb1b6c49ac1800f26c6459dd14430d773cee116332f74a6717e6eb58e8ff5e9db70430eda3cf0ca59000000000000000000000000000000000c955146a036d7791b80c01fdcf524abc91ccf722ffc76217c3e63c19d7aab931ec4149c14bad7836343809bc908be4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d00097ca449952baf50f345c013e854a956e7896ff7c31083611a921d01514373afdcfa17f450e409dcef2db52327dc0000000000000000000000000000000009b9e867d632d915f3bd2f2d6b315160976224061dabb99e5f0c911c9a001c4d7f53c66150cf1c5607f61931f82e57c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a3ea15b2d73fbb72c7052cac17d81046f2a46b3e433e1afad0f1be1698a2b49811a62652bf24dac4f32f7b04d009ed000000000000000000000000000000000d6ca10860f5eadd005866c3e0ad07a3c277f72c961cbbe64bb613f47adb7567dec6d7f4f66e13d6efec45971b101fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deb30db62b796cd64c4aae532c86c12fcaa3e89713df3683d80535f2fcf18fceb4e982de48043aecdc364b4b487a320000000000000000000000000000000011dff25380dfc3d50ae24b93cbcfe1266fb62560e7e10bed612973b8170bf1d07c9140130aba82c7e6a9d641c605d9db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aebb4cfd5d3db15403a280ec6e0e55e430857e2b29af764a6ecc82be172432f27ebe6d0f5a2f8c8209ff484953589000000000000000000000000000000000180e29868aebd114f703c6ff8dda3a4fa9e58a0c0b7b54bd599f9e691384b20ae73e2e953529e27031b615c959e3e86f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbce672b1ca155f5b0c6bbc7edf76f60463cc96887428c22589db05d3bbf337d48026ab323670201f8e9f8bf2a8d1ce000000000000000000000000000000000aedade057e01bdb05ac53650a8ebbd3ca536a5271ebe416b06597ea441a6e2d4a28cedd3522d37a6a967671e1ee7b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4b601facd28516d2f438c55707ee19b88ab7fa0c1b1d67361524deab137fce42fbe77c74377477e534a1b8d8a93db000000000000000000000000000000001849a56fa345261cc373bc81d49f3daa0c1469c19781c0a4839e111a57656f4775993b58f5fd394b8c6adb30608f31e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7f9e4f72c2f8ea0131c7992977a0cb811c38598d9c8fef9efcd662f993b569f2fc5b80fd58e9f3e203bb79009de04000000000000000000000000000000000865e5b6b16fa6fce05b29e0e85075cab87dae3155fde12c4e66e15f204714ef32b6959188605c38858d72d0011f6bad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e7f861ab8d8bb6ebef0660c196775c02b209dad9a177c0a892fe71e9faa736214b6a212fb020895d7fdd3a10aebc1d0000000000000000000000000000000017f430a4344d00e35609c915789add8ee31c9b52093e8f7d2b64c53263634f861d13212445f6a874ab0d3cc216542b4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005789ee1ae1bd390912797a7bbcb83b3a26df947ab980b2b0d198827ad06b329b161597be490cc8a78dd6759836b66a900000000000000000000000000000000191982c2febd53d354bc9b2ba5bd0d26472de805cec91967b9cbae0cfb73dec346ab019b09bb8071b103b718e60e53c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000964617d67f169cad6aff8f1a877fd8db45113d483cb789d30c931c6e0dfb4f7e13662ba9b9432ba05dfcc2e5b04b2890000000000000000000000000000000007454bc0057cc2289991ef666ff1818d0b4da4db5c498b330611395ede9267b37fa4486492aa07a134c4abdd9dfa19431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013255baacee3115c7a37704ddcd935067a2e01539404fdfd5d3831d7caeef29f664d3a8174dc016cf0370ec9a057f1510000000000000000000000000000000003c6a1f4e4f04b7eba45342396e8b39db65922c009ae00fcd92f2db75b3d64aaaae92e0648fa871576fd2b1823f964231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014680e4121a5ec209bde069b52744fec71b766275580f0ee939c5c5ed9e004b2904ecfa55da81e27134945ea00416b4a0000000000000000000000000000000016737a799141295bf04c4222ae5fd0a296f9229536345a1b441d1bbd09ac25c28c0888744b1af789917a3cdbeec3a2d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064cef1213732fda38663cfc5d03cb13856ada6b32a32686a05e57a2991b3632a023ea772d8aa18c47e1301ea239050e000000000000000000000000000000000832816acf8001fa758203c61236a313c306eac4f5c7cc1d3576cc8f05ed2390490ba3e2fd80fe43cc744fdabb88dd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c03f25980ad2fb5200c3b01518340d57743589435ed355bb8049ffe67c75842d1952581b66ae73447efc39e188d330000000000000000000000000000000005463c58843f3500f818af51bd53bce8ea4969d72f3802cdf30168895f3b927115a8b6c22d72576a932827b7ceec41891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8ee14eef3910d08b7581e83cd4289fa03bedafcbe991fa909ad78454f35151daa13775e48f3abb94785952690a11af0000000000000000000000000000000010566ec88d825bffdc831fee82f78c37c30d6bdec966b0cc2019af4c0e76fd5f3984b74bb6ecd9c753bcb363492efcdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005034dc4b0c9c559c4e8754998f9fe3c8731b8d1b0d68cff44173ac0418f6ccc070d14609a73f5d04e7e54c82dbc963f000000000000000000000000000000000450ee98ee4c95981c605a63a119eaf2a63e4f46dd1a33414bacf7c1229521d22031e138a27ea28897f5f432cd92eba51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e321a57b61b8336922d7b429bb5ef4e3ec3fe17e7b28aeff96ab06eb95d4809a3ff6a4c11e4401bd118630cedb17000000000000000000000000000000000018bb0dfb2a8a3bae60c6d709995eca65ca8c519247b75dd27627f3a759fb43380fc230a3c4b856dbb6f6a7ec4250556d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965b896d34898676be2364d65d38e25e44a7eb63636ca944f5ff1b9e9ea521ff737046d63b5c6a84e6f61a26af4e350000000000000000000000000000000001957f3b667c111f16e040d323d277415604ed1e7108052ce4bd2a074006e19afaf57b4681430b423f12bbabefe8e05761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019998cd0f91c9263e232cb8c9f2c6d2df614fec7fb6689e341681c071ca67a7be1871f1dca5ae8b9ca57e6cc43f8f8ca00000000000000000000000000000000108de74b482a3c0e4c3fe22226cfb4ae92ad3beb883569d75f238820be12d1946162390269e543e16d13f5de477fdccc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015aea3a19354729679e5da9f0f73362ed96dab415c4d028dd9d31cf133822c1e6eaed70ef31adbf7159b7cd52d043e38000000000000000000000000000000000d0e62fa7355c5aa723b6984c614361024ac9d17fcfbf7f47f4ad5f41f5d7421fc1e9c71af2bf65c71f7f90a7ea88bf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c144b3651ee93e0039ab3bddbbb485be6d7381e16de46f9f193edfc6b5854a958ce7506dcbf13af678e76e0ce6462a0000000000000000000000000000000014d132dde8f087112294a128cc2ca668f6f40cfdc19b281ae1ff9083b195e604e0a4081c06439e6edd9046de668f93191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d7846bd118561de4d98284e414d0a03fcdfac842f699552bcc1433e55a6b5a24be461a3f152893fba95f98ae99b4700000000000000000000000000000000041ac833e2f56a86ab8000c8ada2772c57d06a8b58725c91dd614fa1360695f5c2ec961102deaa282b8973ffb4e932981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb61dc0fdec8aa2bf7d35c63e650b599f2438df9e69d0cbda3d0812d72533cd9408aaa1e9d73105660b4861d637e78c000000000000000000000000000000000265561781afbb577974dda50def44918aa559601b49519c3aa2f192607b419ae2d580b92f06a7cf5c3263b165c8e88a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7027d3a26f5b1472a7e7d9659ce670d5d2895a62903ec07263fef96762bdc8b005fe0ffefd55eb8f24d0b553acd410000000000000000000000000000000000a1111a16a30d9d7a12a7903af68eb30acdd3666732fa210f1b00402888314f00d9bade83df22cf7a5412e7680e546b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c04f646b08abc84cfd2c7c1d1fe7af5cda7294771623fd005c1bce9aeca57a53222c5bcde5d267fed40e30a6d26f1b0000000000000000000000000000000012e42e1a7ae5798c3e96e873a1d2cc2160a9c5165e5dbdea61daae4fb20fa53b3c17808c02431037f986b814e34a4a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061b9eb388461bff173a20e7407a33335f0a1329647fd2736d4eec8d802197b13cc35b6fac718c60650cbb95515ebe67000000000000000000000000000000001075e59f6376b8a8380dc3a4458bf2ab1c43839067da8a8b2e3bed0ffa115b7cd7895734e48a981c10517cae7eea20981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019ecef925f1e7a4f9c4ba638de0871879071ecb5c5d6ac412c777331bdaf51677e00a2b3b243be79af2fe334ccca365000000000000000000000000000000000ab8bfa536eb618e89343a5f4b750e17fe15527bf5efc6337f06439dbe8e7dec0f2c1f37ad337ab91815848aaaa5e77a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c12555c07c85351a7e933dcbfbd60e54a3de649caa9cabb8086bcc46fff069c57a82d13826c3fcaa613b91c650c81a0000000000000000000000000000000016cb329c57144c08d484141375bf30a71d857ef8f39a8682dcd6c43b9ac52640386ab007a03512916bd0c434291330aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067ef11d4b04cdad17205197efacb296d7348be65e1715b9b451a934f9d9398b8b199e47c2f8f0cfacdcb6820f61b352000000000000000000000000000000000b1bd820253d5e8ec9174ee1e322b24f82c07c092c32e8b3583ef71816bd0ba138ab35e5a0bff7b65586b699e6f098651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c43e0133170334b15e13ad289734b337c243e734f65ef20b6ff08886532de569507b7f599a8a64be8fe2981687d5200000000000000000000000000000000000eefa44c57aa35119639ca7d14668a386e6d77d9a13030bbaa45f1b3d465a36f6423b65e7e4216b22ace73e34cbf18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fd5b2c2f8a5b410b74936b2b33e81dfdfed67687df761750ce9c19d15bb4eff18581c72ffba955fd4d21e38d7d67de000000000000000000000000000000001252b760c3ccc423ec35b4c5431212e11aa258a56e6e35cd534f8a2e1cc819a5343e8ec2e0696254e1447d8a7ddb41341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f684e3ac6fe6ac7df7e6621198fe52aae36c4d2b3ba93044f52046aee50e66c35411477892ae8bdec3d6c54fb35790000000000000000000000000000000017d166d85a58549558dcc4de934f1b60116d684f84744c1863c8f675629caea689706ec7fa427a1923c5142a3642b4d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005870db230fbda010ae540e6dd923f79011925a2790234a839ebaec87d6aecbd65a84d5d55d80cda41c2f69e3aa4b7b3000000000000000000000000000000000f469fa80ac924c332dbde488f196d3ca161130662ab076270005e0cc6f7fe434d5a351358aceccd8708d6efb4ddde2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ba2dd1d8ac3d02106c7fbb64ec15919238cfe5b73ea719ad27d2c1cc51ff7e611f7dd977523ca907bd04f5c5dbf35e000000000000000000000000000000001909f5e81de424fdbb543a2fbd419a6dc4c95b18569b1196f4855a046e7e1963f88838572409d60c0e64bba59d6d78ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc50fdc09db9053ae709e7235ff09a30a875a052028e52eaca7952f27b90f6c5c560374813417d4034e78d93a4f83e000000000000000000000000000000000c058510b2bfb35e434f430d64eee5d313f241abcf2c7775f5ecf3b3360a14cfaf947cef77c911541a327694b91c75ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ec1db6bb488025b0d861f59fe37ff4483a9612b6a3854a61ae5b80d922b098ae51978663926d526c893290980856e0000000000000000000000000000000001d521aaeca2df95d17fade0db6077009c7445b5b5b925891746acf3fef9df97751f1be42caa154e77fb49e67dbfca791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019131379dd190ec9111959cf7fdb12261858cc4f05deea28da351128ea863b531de5077f6d3aaec697118a4509a73f790000000000000000000000000000000004d1965f37af6eee68a7b9826f7608a46c09fd168e5d55c2733c45af339619cc551fda5cb599503527cc3f478e547cb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015afeb8ce5bdca8a0d77a7a3edcef6dda10431f41b2e840590e7b26dc46c058eb94c30df06c99ddd669f43a23e362a890000000000000000000000000000000002c01c16dd26749e5f4e3137979a6fa73b2993f4451bf9f99fef12122fc49b2794fc46b7dd17d8bca8bc16491e312c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c408d2e8580095222b4203c06b8a6a6c2d5396873779a3678b80f7bd99f408879277f72da13ff2f6b87e752501aaef400000000000000000000000000000000047d97338975f51108acd393b014d0a6869eeea5933cfdade82f8e713e2f431571bb8d87271ea9d539ad02c5c47337341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf31f959d6ccc537b03835f9ce6ba98565f702a496c5f4b52818c79403e870dc83aaa7f1419e77a760ac7a117fa4f1c00000000000000000000000000000000031cd33e07f332da3a56cc75dbfb2376467b71f82554ff6bbf2c959f63bd2f784453f942a47b43ef0d9318bfbcdc246c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008e6a36b67f756ee2bf8a78d2d88b2948fe5b9ae8364d448166502448c41e3bb2fbb68e92d60a00420e933bf384852a000000000000000000000000000000000ed364ec6f9ccbda1d6507e5a3a00517d1d7bc2fcc6d390a591a037c72eba36217aa07e7554fd76ce3288aee8469d08a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015486bc47b915ceb10c0b246b529d5133cf3007b53cb95610d5b70568c45b258c42b7e9f3ac40774ec14188cd967c7f20000000000000000000000000000000010954c5d6212c50e74de0e6a7752649feb18c45f0fbfa67f85dea09f37ca8c6f9b61ab13f1c901e90935a0cc9c28b5b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd34acee072657b1190c5fd2a5b60ed23f5bd150f63c55db78d917d42b0362dceb46e44a43bff6f9f09284a0b7e0aad0000000000000000000000000000000004cf48ba2801045ea7791b9376e3e233da7cff43c87a3075cc25b991980b67ca1caab4aa75eb5fe7132a1d3e3623758d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000976bf5a79c90facbc3ea806e20286c96edf9a48d277405a2d825968c3546591c74895599970ea7dd2302de883431b8d000000000000000000000000000000001031acca7d331ba32fbd0410d0680c0a4d8b33c9c91437f1f9263ca0f437a75edb3eaf45b492889287a3c7b3001065641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5dead2607a2da62aa3e76200ce65a181b0a17f7b8e5814b45f08436c7e50a34d99a90b1615aba96626e9c31e4f8daf0000000000000000000000000000000015005b1ce370efa385b39c0c29e238b98f131d7ae78b489796633aafa24f9a594100de32993fd9799c69fb0d21146f8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041fe5a6f93756d22eb1c72eead88ed791b58d66758b63e3cda7cabfcf3dda5f2c7e09ab2bcef89fe093041431ae258c0000000000000000000000000000000012e9a6518faa3abb02b6402c357a39db8105ec82c204a1735e792c0587b6b781b427dfe14cc1956ae7e2a0a1ba666a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a06fedbaee0b21c5d1016bc9339107b47fd75292fc822763aa84ee401f0fa257a491e44ffe3683ed81ef8a945c9f9c0000000000000000000000000000000001f82a217d92c62ace556157742943d42b22b4ab46af8e9f0bc7ca9051bcf98cc78394fa8d97ce93307775eac7a233181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063e2a482dd07da954264985eadab87e392747327834fcfe9e23172fdf0ab0f17dea73a317bb33ac56dfe0f250b2121f0000000000000000000000000000000014036b9434509906a89b817ddb2335a1aa7e8c753a14dfaf2e7a97e4cb31e1895078bdbd625e7002ad4197c8df6d0c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005605558de69cdacd67da47ae1e27476e51b6b9d2aec3a3d381401fd06d3f6200cee7785b38dded80af4897c9459dd8b000000000000000000000000000000000734cf01256d4c36499f7895acb3aca1dfbfe316c9757a9cdffcb4a326913c990017a48d40ff544742848414ced32db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1a52bd36fe1d30f81137e31ae4c759e2c6dc86bcbd8e491abf7b506e0ad9c0a0bdfb0050bddee8a14d490532534c1a000000000000000000000000000000001774d3b97b57478a5c2c8ff46e59820ec09fc73954cf30f7e1bfb7decfeee5497c65366daf5fb55cc71890e788db7b771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000becb0ea048daa55c08292354b2f7f3f87a772c122c28b3c192e7f352bdca3097710ff8ffeac5c903def0893be1f1565000000000000000000000000000000000499f4f781a97d6f6499dd90828ff56108ca70c9074cf3ffd699b17bca3415acacf7b81775df4ca9aef69094eeb2ee0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed216e6af7f5ad67518a6edebe57608bde0c7afd49aae47127403144470a6c3b7e14b31b000f4eba1411f004cdf4ae400000000000000000000000000000000139ac0586483490c670a75c775db97c5a41dc010086b5a7d62ed372e96913d47d83d9ead99611b4baa6ba619600fbf0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153c83e385cf2446646645280489c3270ab146e791d78fce37b12cdf7b02eadd4d64326d49b6fd2fcedab08007ddde650000000000000000000000000000000018ddba58b1b5101c1ac1ef43bb72f7bf96e58a1da2c985b71db1a33b9273cc72bf4bfc251a25df6e03ae3f70d1d9c9431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c740261b9e340150250b096f8372ec484bf4d5e7faf8a7b826002526dffafac37ff23adaaf8239b8bf5f67d316a00b000000000000000000000000000000000f92c82ff6ea1333e6a50b40b9cd5eadfdc34ffddeb5a86eed52be8b85ea98789d94ef24763d4d00515585ddc84411711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0856a6bdc1a62cb07231879f8a46b288d73c0cdb3c270011c657ccd98e7754e146b68f659ce4ed517226a3af23c21a000000000000000000000000000000001085d5768619e4295683507015db2062ccdbef08c81d1a2e31c1353ec759ceccc52b5cf1eadf428c195ae8da70124ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad4e6f6252ee8d639265cc534fe8aabca517c54c149baeaba29a4015578d372c7a41092eb43d19207d2aa7f72c91efe0000000000000000000000000000000017c745a4895037631ce3210bcbbef7590f05c7b33eaddd1f52fbec80bdfcf1fb0299422b623546e3d0ad1584e76aa1ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ec62c35cb632f9068608ea6511d945225ab4d60b14c81464b105df31f852e4024584eae04b238fc2aeb146b13eca400000000000000000000000000000000147f8e3fdcbc1329b5b30c32c879366c5d999bb8b7f34646929ab9f6e7156bd18daa16840353816e28ccc46d93f8f0871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b56496e4888fd0fdf388160f7bc0d0e539712c934f505dfdda79924ef428db0a4b7f5702e00c4636d5ef7c43d031046000000000000000000000000000000000812b266cd98634b4b08a2ff6433ee000497fe1c764c9461a5b401eba4b6e6b1f745920da59b6bd88a51d48add3329c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a8cfb4495e0f1ea81ba44899170d983402fa2cdcbc42dfe0be9c76eabf73ef029857bfac2647b84e7808521bb9f8f0000000000000000000000000000000003273fb2ff26bff62c4aea0f721976854f7522ad1dbf4bcaf594e62d4c77cc6a43d3192aef39c7996851a0e0d300d0df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8f6a526c797f549479137c181357c8b73777702f4c2e293832b7c5d382345f55099589b5b761d691593b3d7911abf0000000000000000000000000000000012eae7966b31a0975b21ab3d79c809dc1317ed14963351444606d33f6673ffeb650bfc9f3177ae2bf44a360c0ef958dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542b6a5358f73c6392e0ccbc628f402168b121dad2c119a3583dc5ffb63c7abada8702a58402fb865163442084f2bb900000000000000000000000000000000044b381ea59f07427a2e296887d4f8cb78fb93e739876b424b25475cb2daf68d6a0518d5509ec9742c158685089c3c391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aa0a6fd26b1ef831d0c452c425aae6260e5f483b714c20ce807463ac28aef2d3e749d1110b9f4576cb7729ae73dfd70000000000000000000000000000000017e68fbb10d9bbeec1055dcf109824eaae8980a60704b18185dd9792a5d1932fc1146fbd7138c6460d9ddcfdb80988e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001729e530cd85c9b8bf107d9144ee13adf6422148c6f1dfa07f7f00764ec092a3dc608a8d26e4fac1550707697e6bd4560000000000000000000000000000000009a270f69d7332df2d2ea143a691d3273d37834d2935b48e6dd04d1d34bbcf758f097ba158bb3efedb707f53b6a628e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178044b47c8c7ca293ec349cd5bd9158b928cf34f2bf0ce44f094518d755c12ad90b9fa0ccd3e63583d1072c9d205257000000000000000000000000000000000cc52efd543665babdefdae276db517cde138c8efaa1f1b803e43bdcfe5f0d661bb6aa55a1e8336fdb7611cf8255a44c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df99d257ea1dbd0e20bfb100a24840ab79f38788547c027943b79046e612df0536aa96554f9437978cd5703458d49c000000000000000000000000000000001434e7da6fac87b5190b23a9b698238c1d4382be9d398caf187b3610f14cd458061501d97ec4391b3a60988f0e37bb7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001789fe1597ad51eabcfa4865ca7328962dac0b681049060b94dcaf54612dfbb872d77cfbd11ea6e38d66ee774a88efdc000000000000000000000000000000000d2717fd2b3a78285fa3451f02b75cafe0fa94341a45551dc09bfd3c93dcc427f6848ffb6e33f55b765927b558d144261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c875303b5342a96daf5feed7274fc26f7db8aecf2eb193eb4c38c6772f9dd2e49c0b5ec37f613f43e6f1f84d0eefa8a000000000000000000000000000000000777c5f3c4f6f37db51413c58cce1157148f0f9eb4304377eeb0d162d80c44a9ec2381a775c0454e9b8c65e25801b7341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1234744b9874a6409a150660cf1d3a4e3eeeecf4b25ac11c3e134f6b110e8764fbc9401a200918b5881ad6bb0a3e11000000000000000000000000000000000d9d8e7b5b5b010db6d7e5bfa7463c82b17939a9f000bb60aff9339fdcae8619f11fa35955c63fc58e82725e93867df21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166bf929de63f4734f3ad38af9d0fb6284c5a4ceca175f4d37ec5b8d164678e0c88f49a30b278551eef7e09f58c5c8ff000000000000000000000000000000001060372a3e7cc12b25896a449b1df2666eaacc2713ce1f9e6af650ef574b26658d5c08093678f2478db36b002f5a849b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f24f42e64fe73921de8eaf76a89cd659ac1a9be4d4a64e726c3c008b0609d2d6f77e9e141c0434e7fe4e1e318144a900000000000000000000000000000000049a61744929e7ea7eb9c3f22006536c290e5721e5476c18382a09f00cf6377601928606cfb90c0e4832a9e2baa7445d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088030f13c12b299bb2734a562192be3694436803af1a6cf64550a9df7dd11d582c403d458b53ab19c157963b71976a100000000000000000000000000000000077bb47db6172549ea6b00f1f278f58bb4c88f78663d82c7d8072fff04578703f5a8d7db19c006584f728dd4312bc9f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470434a67ec265eed708efe232907314cc94ee6fca9bfd15745c60f20a7e049cad88cc6013e954e364ded3cdfcb463900000000000000000000000000000000115d0709a6a7249e5644afeefc93db2e935b69258ad9de6822b175f87c2b5a34dc5a22bbf14d05295c18931334d73d0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d463b20914562e55fc19d3101f19d858207bfbd45ccb876690c1f202fa2600d719c2b9d229564e03a61951b316400d000000000000000000000000000000000387d6e9826d40849257fe305d682ea3ea8d8d74515fa854b0e281a2acb291b8173673253171a6ec4b5a48a2cb567bf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087d32aa3196cf37902e3e22676ca838fdd54cb1e92833bcb4f437095f51f2967771618fd59fd593215e86f9d5c31f39000000000000000000000000000000000ff45ccbe8bbf76cb3accad67554dde5cfa1fdd225c85c075f51a6988fb9957f36992bacc52f1281564d64f46d3a24261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc9291fc98abab63ce72791dab5cc28bea069adabdc7e25a720113bb19a5613b814491d44f0221b0d4ba98291f5076100000000000000000000000000000000073082e8f724bc8938da46a47fabcb9d1c8e708790a435043dfa0b1aab5281e579ea8e091e0ae3447221924eb360414f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6ca7d603249b62ef448f1abb71244ccebc2ca178ece155dbe3a47b052b8c903f4d1fbc5115f1b4b65a9ba42b506dd30000000000000000000000000000000005923a3ac9a83670c9694df8c3dd4b90b908d15ae03f43543b52aee150429cc5f1460077545ecb8b0c1813dabdc7f05b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001115665e5938e1d6fbbc9db56cf19c6863a5be5b35c4237df8d5460e1d11eb4f82ccc0c2354b949843be16d92cb6dd000000000000000000000000000000000b5f64887e13d3cba7abbd86ed48325705f5ec14db7c8c70add677faf2fdd3baaaf0f34de497425b9d36c41db35ae1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f6c2dcfb709e8e9d47c15fc545161ee50d0f1147f195f055cfdbcdd1ccdec191fa9519aef70e63f5fe2105d77abddd000000000000000000000000000000000e963e6433fefc34036cc77b01049c14bd28f17d54274a68defa9380e3d6bfeb6a0f0106b3b1128a3cdbc85080cc80051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cd27d3730da9b25d5071c5146d103adb6ce6c4b1145621a2728dbd91bc30784611666c36ba2aff32e519a63a7f76a30000000000000000000000000000000017f805efc967f09f4c4c46b37273d1fb232a105917c81f69682122bfb90eeda89f766cdbbdb123396e6ddda0db3bff551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffe73e4123863278b1771d8385b870e1483165bb038d504e476f66106d0778f9d21c68fc7e2342e0a1ac486ff571b4b00000000000000000000000000000000052b0a09fbc0da14110a9459cbe61056b5562c1ace79caf55e58baa86c16240638492584ce9dfbff5100c6c4faba3ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d84e8a53d78d669d5876253bf188412ea16e7b8ab7390789ce13e519b13f09af3957a40b4beb6ba8a027966d6a12660000000000000000000000000000000001133d79ba731923bdc78ce6286a50f2470bf28d195c1e2b42c0ee738f38be38b4f6bf20785a03dc8074ea01e5bf5caa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017323c5490150dfbf38faea5fa478d058fa4b5ef7fa3614c04cdd5432489553f61384f385a23cabd5309bed7ce7aa6e20000000000000000000000000000000008df614ed10b00144c6ab4387883b0be5f907ee69382705033d0adcfe235e69813f45a9c0ee00700e6509bb23400dd9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea4439f9da9e484a7af5d582dd57099c335ffe410c2c2d32af7886410f0badcd9b220230208a8b4db1a765efa8133f900000000000000000000000000000000198e8e1cd28ceb274321ca5ea0b4ba44c8e1121100a7cb7f360eb0f48e493c8bb407106473efb4259311939168c74d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8623f9b47f22866dab20281dac6a417353ee873aa6179c081ffbd64c2311ed3c646ec09bc205080323cf568b1272b70000000000000000000000000000000010b03698bbb760c05f6d729729dc751c652bb669712f45b82ceb7e84c0fc668f701e2d4e01b2b456b5571703e90c5cf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100a0ee49d4f5597eb541ece7d97e1ff350b5fca33e70f8b08dee9d73321b7b540ede7db67f0c44957a999a439d21ded0000000000000000000000000000000003caa9c201d59820288d6f1f827f33a83196d5bb3dc7a42613dda61712840d57d4d8181a211a8e615baa5806ef2d477c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035a0893a9ca5bf544650260714e977be1de2916d31e5a1387f303b05725581ddd2aa42dc9129a08ef875c00833289dd0000000000000000000000000000000003ad409e30a7f4031113dadf1b97672709e7f9bede4fe3aefededf759af17fda0567621dd81f3f2407d40e17eb73963a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbad5b0288777419e219d7d77daac73b6981c9629ebb0953b864fdb6e97d60c7d033c44d103ecb1a74b3403375db440000000000000000000000000000000008d7b7a3613fefd4058dc7f2572c129272c8be4b578cd7b59d64ddbf7b587f1587a3a03d75632ba291cce765ad7729b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012194949874408f90ff0d641c7579941b87db3f01f3dd20f84bfc52dcd5487caf28bcb22e9d0d332bb93dc2e42007d7a0000000000000000000000000000000002df041fb394585357b968993f13bd808d21a6b7b66aa26fd6a22067949ff2d999693216402366b5e9e4a9c5bad3f2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001877ab5f2294598de83e411037857b10a6aca53ccdca72971a6aca66b77fec97e879c0a9b0b0ed0dd288075cc70e6cf50000000000000000000000000000000005439a16c1c70a94973686813549c279a82b3954b39345f6de329c093891651cbba7f9cc08e707174703d3bb0bde2cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000684a214e3d5ed90d20c1a7b18a4fcf701c1042eac31c15824aa54e2a67d367bb2648edfe7c0356ed7643da1a96438e800000000000000000000000000000000142293cc80550d166e6188cb02e66fd63219564958c1d5a686e0645dc44f0f7da77a43eb8a0c26a5a09013f79210964e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082dc740877929016940089cbb67ea8da4e733cb65453904bf52e36aa0e0e06ad8050afc500f0694a1c02ac39aefebea00000000000000000000000000000000187fddb1760ce9db417cc426428bc03652986f6f6efec75ac8fa54eef1c2bc216ac3d5d17c9f23dcd037c4fb36cd94ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001825289ad9aafddfec7dfd8720023c1a8a04c22926ee1a2231ef2ea8fc9c5e88c5adcaf11c4c6b82b05d989c2da3dda5000000000000000000000000000000000617b38d561b3cf090c070d9e5b8f3d97eda7ac39322c312bb2389fa49c78fbcaaad2c973ad96fa20a2dd168f92289321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b140c4e65f7434f86473ed147c2d8c03ef1ed6bc6efaa1b405cc5b80d3b6604dbe9bab74bacd50955b22741cc1324000000000000000000000000000000000b216f7e02c4a9bbd3ecc6b7f2f107459326a27d5df974e91255dd14165e17688ed6538d179d7f44a3e4c9ff4343dad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016017948e754a3440a7c78b2c7ad696a9a701c905eaf0621ee48e80a54404887d7172701df403e8d9913fd868785e5b9000000000000000000000000000000000c02b21928c59819bb27ae9d05b1e0647e22857b994020b646a9c98ea33c00eb3458f219174a02242b7f45dc00505e041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000460339b13ca7eca4d7e6550fc7b1047972c36ed0dd285ed3d05394b153961234311454775bb601892c0896ab1b047b700000000000000000000000000000000193deeb32d52e14ac7beb131961b401441856c3fd307b919db511ecc6fbdf656c11f3d6af2aa2508a990ca01b3f2c9da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f2478a8de6f40a4282713295ef3e5fe537ee29b480a31860150e97783b9f7adb0f76abd107bca4c7bb6818c75849060000000000000000000000000000000008795d4b975393bd43ac07728171a6411f50f7825a579edd212e17293b9563e5b72a27132edcd2a9c37513225709dffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001451bf0d41ef46d0626f580c93dc112752379be4480c63d188c54d1e04c43c22fc3022ea736c22b9faf69a9caf037e1b0000000000000000000000000000000003d6083061523ea5e28b0c037b68cafec5eafef297f40207d4ddc914e526e5f5f2a0522bb09d08051121be0f3a0b1c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5d5a37e9009df0ed24f589aa36dde0f5eb51f65f0ee8e43a20fa0688cc24f8e1dfb273392ce2ce3d79a9269575a3300000000000000000000000000000000010ab230a5cc2d9dcf5b67f1be7757eaead84877bff6a561233919eb8e1b713b77ce320e2812cbbf003dd91f924f952491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000bb99b3e2c49ba31d648a0ee0315888576302d375899171e60ec6b34c344d6c21058e58656dc59e36fa68033c4c70f00000000000000000000000000000000027734c169529a04414aaab0fc27c383d4ad8ba9fac391a122127f2d151a7558388bf590be7df1e78501b02288e657111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010977b35ee9322e5c9df70062045449c6c46824dea989d7abb6aa536e37340c46a003b3725d8b127199d9e813c316b2d000000000000000000000000000000001197957f64b98fe84390fa9c4bdb3d882fc1929524a9e2de4f7dc5694d83701c5e502e5d8c98673518f8490e2a7102731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d219275a2399cc78e99fb00725088c83c48607fdb6653c4a9896147988596c21cdcd0e81fd0f09db1ba32374eeaa550000000000000000000000000000000000a225824ec32ec8d7cc53ad8766805d8f88922987541a0e2777b6beff68abf5f03838a4d013a58cb02571eb90f31a2af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b7aa3e8b687a233af5b4d4ae3ce830f4df51aabeca09465e4e1cf3e2446a5c83e51538bf74b182c342aaed3f014167000000000000000000000000000000001808d1b4884c4dc24363b0aab9e6f0f1e653f6dc0f00a40b6177f65b54b8668a0e2a234a1f2c91f6cc449e5fa7edef401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012698165841a63b5df6d62cfc671cb03648927203323462a47b3f3550417228e79f148fe717e61296e8b33157042eabc000000000000000000000000000000000a87c946c710d9efd8824e2ff59e0eeef09a0fadf1ad0493799da44395cddf5e1b47ff48d319baa50fe9ba53433a167d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4e13efff93add9bb8dcb2624218a01759618c165adc90357cfb9a13e75aa9544cb82cf40c3b06756e8559e28202771000000000000000000000000000000000d237e6f8082280ddaa1a164b258f19b9bdbd51041b0573a43967a593df5c2bd9358208451583be0b4093561b36483951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122dec2ee37c3d34c96d81f7826312e15dbbd9d5aac9c24efb5ad63639241e093cc4d20da3dc8e69badf1f2ddf8eeecc000000000000000000000000000000000a53a91bf1407b9497e26d96016574c9b7575a93865df003589002c27523d6ee33e7047360e6313a6de9f288dbc560e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c2abada9888c25c28a90ab756bfd260691a152cc1653bfecf022ad53f14d5beea5791a54bdbf7c1178c34dbc6d30b70000000000000000000000000000000017b4e030b32dee8dd8e94a6986016e5f22048d78ab0dae8973021aa33fdcb6da3521b566a8d9d6e084d375797d7b26f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f519fe291dfa0479fe78121d25598314c92e3d352d23f2447b00a153ce0e2317f2410bf3e94e87cdacd9fb21f868ee000000000000000000000000000000000ea3ec51efd63353195b34dec9c819eea616d8dbd2a73fba70e4b158e8cbf46088dddf6c6420017432e9b25a67745b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cdd51e99db42e2a42d23c61c2bc65fd2136ac519a1325f1850fa4f37c4e3071384077106a276cd4cd52ad6e67edb7f000000000000000000000000000000001133a35ebbc24e24bdda8c563a09c602951ef9cd0fdbd8509246ab50208b0c9d5590adfd9eadc352ad8aafe5c872d6671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ad3f7be36677a2519a3df2ab8c0e6a4dfaa8bdb0f060f999c8ca3dec31df10268148146bda3c655bf52eed2d2e8bb30000000000000000000000000000000010c2871d77af0040bbc8efb542facce80f3a5df0c3642d94c18011243d2adf3156a4ae0f1188da2967f7c8b648d65c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b2f964230494254be4ca9c7fd473ce3117dd4b346cf85d81bc6c27c8f2544bcee0e2d1d0a097f6800160ae170f40650000000000000000000000000000000018174de7be43fed86a2b4301b4cc2773cc4f57192a9462b713368e14a0b0a065d865572bfb2f6a151cb23f92d8a90d9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001195b8cf90456f5e34b04973a9219fbfb8d04105e280d75f1e58e9e450a6725ec8488aa499373ee926a15209b831fd2f000000000000000000000000000000000289029aaf50f08102e44a0d8cbd35766fd15008a9ad3c3be6890ee9da9d76c1dcc1d29445440af01740e9fc823a7c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000357cd6f20b474c2c375af8ecfb76346b18d8fba0791f1b1379d1417b33354cfdf4bd4802487740b40c2ed112df8e5f7000000000000000000000000000000000af259c37282510fb70c8f8afa28886c8762722afdd8092b3f173da80b44c79ac3017d09276b71514f173258d95a36371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c5886109cae47e540c566b804739383bc491c449692137619aa7150cbf1a7e144cb7afe0b22cc142eb4d6e6c4c2bfc000000000000000000000000000000000f7395f7fa3c5786b356265487628fe4479060f62be48acf466199b742ddcd9b2c3636e9a34933486cab4ca106a0ea881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee6392dbc2d04d9d1a0da43ea4a4e4fa86d48ef95a96494a5e8779055dad085eeb0db7874f0fe02e2d5094ed2bcc92400000000000000000000000000000000058872b881f2daaf7d2c1248932be6818cb4edca146b8cb9f34ecf74f7393babfd019168a258b8f87e60abebbcdea11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009012cd169b4bc6ce52087ecfcb3e1e4a5565b3557720fe0336e4830dc01ae99169d7bcb7593372fdd1ecc773d2b35af00000000000000000000000000000000132ac9808c126b1e3d34f5626be8b693e1503d28927d021ea0a9dd1aa64ce0f4a05bc82bc6ca40f6b3882f2e33c3e3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7e692292564d2c08a20396922055e2a3d8fbfed31f8a05d0090b554d5f318fae7ab45acd5cd54242522cc1b2ed8fb50000000000000000000000000000000003bb6ca15fc9e3f8ffeb1714ce27274b990ce117231922a273decfae4dae940cb5f155a1eb5e67851c2a380635346eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c33618242415f2bfb939f6f9ae2d3d1623a6372800b68c7bb06c75a9d02547bb2c49908864a96b97c3a554f99b9d400000000000000000000000000000000074965028b92542e140596a1030ac234a08bb5ccdd450e41eff53ee8f88d2d3f0c473a499d1cfe8de76f1029c9bef78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cab60d959cd0972b7265a92ec6a8f50679539f8b337f4607b0496531166fdb22399e4f62854cb37dd3c31e945005900000000000000000000000000000000006ad9d94db5c6bca460338151357492a2a219e029be62049f03ae675d92fb5fea3b4a8924d65c72c4740ee5c09e501561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a387893ea1fb87c3437d405a4715a2abe71d505fdca4cd6b10426b77dc411ac5844402a5649f0a37a296dcaf908a17900000000000000000000000000000000103424b912f3575b4a46245349be127850977d7e97768b36bc96940be63a14add24bafea0aba6aaceb1496cf257078191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cdcb32cddc97f800535e87e9fb4897470a0d9b1c5fb8be60f6030eabc8a02ad437b372174b7008cacacb8ad51013a9000000000000000000000000000000000e643ac29852f16f7a990bd455406e8d54ee4c4b53ded6a251e8c268a1261f1b2f3f0fde5c45395e81d4fb1584b6a5fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143a6be72808901e0f73f7e41b3b636840501c7bab43d2fc5a767d5214de4388529acd8b6618006183fef112b8c7da460000000000000000000000000000000005f9baea082ef1f6155740a8fcbfc604211ccb5d785902718372becc39c8c52e03504e76f6c8c7be00c477d68fb589291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a21c330c5360ffb3ff27e84baf1be5a9cbee1cbb7a7e9466757d010ef1cddf2c27a7236b1da6de24b3043e0e735bc400000000000000000000000000000000002d009211ca2e3594069e7c5edbbef17cc16cae340e1c8f26b95c215abfc39ee1e7745a77aab78000f1292fd0a0c21de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196a9b00b7aaec5f1cd3271e721ca31f1d8763c2387f6b3a41cfd1643bf38ff113f3872bb05748888e45f847966ebc62000000000000000000000000000000000ca7fb0df9a424d0b963a3e0177abb9a739f66948b00ba41b4c498325fd08d8f98dc7bd68ef067d018a3f655f0ea5c8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9ee00a50bcb3e75c9e16ca09173974939c3f9b024d7194aca4ca11de26fbc357cad20450de030ad45d911952741951000000000000000000000000000000000e1a0d6c1ddb87a1ead84582f940a714d90234fa9ce67d63d70b2f4ecd9f9dc80eb085d6b770eb9ff76dcfcc0062c3531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7718f728ee75df0700d32a36efecaf58a834627e7e9b6c275fbbca136af575d3c08ce4e958b9fc9723fba7c123cd94000000000000000000000000000000000cb3d8d625c701d70f6f17760824041c8e85e4eba6e1ff52f4f8b28ba210dd51eb7f02e8b887365a094282239f8ad2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062aa94a7249e47a1b89c447922c6258b80a3236756974c105e7138b415e06189ddf7e9b6be120229320205102ad790d000000000000000000000000000000000264390d34a7cb6c63fe4efccb6dc9bfa7a00a1007e8c9ed83b8fd9be02a785f9187eec4af454b5e7642bb1a1fa2059e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012911b166ff6630e39d465efeb1e5a39350c58dc8d90f9dab2d584a6fdd7b6a060a1a012870b1fb3041d9d6c8e8efb85000000000000000000000000000000000da888491f18a7c08c3ae3dd9dbae3cdafd0ead10d2149e077807f9e165611f9854630f5ba12f1e69b2dcd7fa922e86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b4ca9840219728ad548735afa2bcbac50e57c3fd616e64e1de856026499aa20dbf15735041882fced148d58b2e066d0000000000000000000000000000000018c5897c9ca74e7010a4a5840370c52e7ba8eab65265c617b0f9c77dcc3cab68a2af1a1e4b5400f0ec88fabac9b20cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030bb0c5ee343ffe5138c75a2a1fa4e39526e96093bbb628f9125c7688a98dbd5e7ea6c3d48f3b5125cd995026af7ef3000000000000000000000000000000000f480a1d6f81ddfe607c820b3497b3471f7a359c4bb086f4bf3077348f1ca0d40a38b8a36501f861aedefda584c77ba11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ab48bb3a60a8b8a751db878a0e3148fdebcae9a8989416d584993e3f8d436f4c96bcf6ec2ae539921e7a923f24bae50000000000000000000000000000000007e7da3c1bd5dc539505d60ac4923efd56fbeceab841e0360e60dce53cf2190eff8005036967f7b8c80ad402024d75c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183297092462d554b459c3367dbcc9c5160108b8279c62171873869155cd725fb8f6772794aeb262b43092372f570ef60000000000000000000000000000000010d549ebfebcb9058ca4895485f21b0f3b9e2dba707b16fee90ac859dd8537d75d32c6c51384135aaa6aef4de6eaccc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000216cf040ee2a7420c6cd35a9550c607a74760f1dde8a7ba5e06c7cba7599c820ab945600fdd691d77993d8b9eb8b23d00000000000000000000000000000000185b86e05890bde07814b99e7ecf87c980cf914d7f349bea886e5064d3ee12368e6647eae415c06894d8e3a18cfcc05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b14dbaa80399f6f0951a13eb3bdd383b3709d0c7e023fb96f5c4182dd926266c5a1ae25bb7fbcb00bf8257b98c863de00000000000000000000000000000000044ef036bd4b28916045f763f33c6f85359fa80af15302678046d5f4a9463ec4ec4a1873b847642e766fdc0d128e7ae11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057a45e6bf6efe47e05f380c0d3dc4f106cb6c07e839f10c125517417fee39eae903668d073eddc5d5096077daa38aff00000000000000000000000000000000102cb800ce0fc31c9164b0a53880566394bb61b72d28975e7bc3c0091ad79af0b927f1500b6505363cbbf1b78aa850f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099279b9024e24e4c335d10e2ef668de59a45af0dcd2e687c1defe350ab8d63eaee952eb2e208ef1e715f900c114013900000000000000000000000000000000038c4bfea318d152d3a69cf188b1f062bef23f12f0b1d226869c268bfa872a88be2423afb601ca7ed0a13b4901c8d4ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e2aa6106dc3bfc74b7b5d18a40d09e7b58635279aef9730929c1967e0712a7569d4add49770f4132cfb5b2b6cd5343000000000000000000000000000000000b2afbbd6cbf92efa9694c437dfeab42584109eb324b40109f93786288cdd1301d9da58dd68d2b565938fa820e86e3581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132b87a78584e03504954744cfe0715d01ffa53ce607e01a96a3262663d427b85638be739ef7f5433f12352a70b061350000000000000000000000000000000000840332389d474b72dfcd968fc5839892a8f43fdadc7020d67cb0136f4617846d278e2c2435986e335968370236cc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faed983cf87be5196cca1efbfdd07cd2463bd97ca6f624daddc0f020ae0e6f233d6a644cf361f666471b7836266caa40000000000000000000000000000000007ba2587eb49d2a6be0b531093deda8df81313cdd6642f68a53320cbb786d8928db40317776de8374ee88c2998b25d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000139078db19d01a59605c2a874b0cb56c5fd3b425d8cc79632a27ff658a8b173d1ebf29f93e92afba301461df8daf865000000000000000000000000000000000f9d212d26abbadf585c0b3b30eca7e0b91bc71a991da72c13658322eb9dbfb9df3a9034cbfb9482ff0a3ec9aecc72c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080a9d8a4ce382f0d10c283e68ddcc63aa326c60673b38eeff3cc9f05896e81d974d56c4b1950b55ad73f173d63e11b50000000000000000000000000000000005543c67fdcd5ffdacd6a41a50c8cc262db42ef6d4aa22aebdfe21446429d24f1c9a6188ffd6466b8d421e750a26d99f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e849e401dff6f79cd747ba63d9d095f1184b97c3074122c24c29b2390396cb6c609fbe9f7ad824f4a51ceca25326e20000000000000000000000000000000015bb5334f987eb5171c92f0c4041a291c3666f81bb1d9fc7881de4eaa56c80db0ebf8d1981875ca1a022c2e00d90eaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130872752943c5dcb86ef3a0fcb098a14bf69d3871ea20f27b7d4fcc4429db45668af0b4f35ca7dee663e766fd1cde400000000000000000000000000000000012ce566dac7c1147c6a47b4e19fde9ebe2dbcee1ff689d90c372e5a66c77ea10a664e1366c323211fa18ea69ea46db4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400ed428a6e6a388a9870ac92b548bfddec0dce75ba3a22af4667825a0d5649ad6ea9146d4151a148285c28624d6258000000000000000000000000000000000dd3c6a15f4f6bf616712fc611a99ba42eff8ba404b8e0faef0f583cdbd567145403566b1c8375f4595e248750ee71ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b8cdddce2226c068e52d273f7711a0913cc471673295ffb200bc980f7c465476cfb5bd9df4307e46c6238a2b98d2d000000000000000000000000000000001080d006ea4096567cc56d1cbb5dc568dafae8930699ea5c18738b3d81ce9e8ea27a05443063b5219aeee98ec65d569d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027c06c03bef72d7e547268b6a9d5c649225b7d861d84e3b04b1fca6bb994dd03df198062a9a2a46725ea75bab51527100000000000000000000000000000000137cf32048ca8ba8b52f3983a8afc6835cbc0305f6f71c6fe05f14c527b082170f0d089189a5f09603279af1915897d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2d4adc368a0e84072fd2f8e45016eddcec7251d11b5bb641389e34a4d7a752fc0258ffd4b7a7db7acc3ad8fac587770000000000000000000000000000000016a9399021fb80a2fa57ab9416609be8d0b5bdc2af1e1db77beaf0eb6525528e35b0ac6720ff781147fb66272aae0e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2420c7b6cdd61640266439eee1bcd5f081da72c94bb1e45f90cf2c22c4e4f53e4bb816a3334472fc89622a4a8490d000000000000000000000000000000000975421734c1a0b90f8992448a09cfff974d802bcad7bfadeceac3feaf7d1e645be1e19edc3c94b060e1401d7b2dab191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001914b335c07a336c6ba6d59c502177028bee782ee9780a1f02e239d119ff6c135161654aacb860473a2d6cb4161860e4000000000000000000000000000000000f7dfe4d2401ddbec12028b8f6f4296ea2b1fcc2ad16af91d56c0b8cd1c5b9753481919f2518925770317045e706eb511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001738437b6638aa216876860fa37a53bc7f1fcee4393d179e9fe92ced9baba5403aafc443f1c68a18dd4b861ab63b545a000000000000000000000000000000000703b4d1f9ef4b0dd434a2062cc48a289bcf08fb22f14f293f0342e8a6bf139116b8694554b3b4b8363614cb9e2b90701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001395844a02056a97810a67609dc818986c2e2d9aaa8505d30fc751be7305d9dc752edb93318f66d59d987af2c0fe6f3500000000000000000000000000000000082dc2148b20cd39280bfa2183d11012bf5c594ad26661b65beccbd3ea3b27dc6775831e55941ad5593276d5fdb2d19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdac8924ebb2a2875cfb4142cb62c73d9daaa7ae72c9969f6eb817e17e256e987ec0629fc244e69ca2678a37fe44ace0000000000000000000000000000000001245ba0f72335612749eba13b842c41c937af88e19b1ea6b91361195d88231b1253c35022666b191d28fe727173ac711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e0e73172afe306c148574e89d0149b65056491bd180b0b35713ab76b4cf01d53f3be5e3aa0f28e0eba907a3becf81f00000000000000000000000000000000153006f92ab9b70c3885d6b099f41db8f903b69e417adc94f93c53dca493d3557c8ccbf55d55f06825226c0adc983d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f85321ff8c282cf4d6d72ccc02cde927fdd020ed5b95cdddf4810f8b07ae71aa335988ba4b5fee2d55c4a7e438634370000000000000000000000000000000004a0b041e264dd653eb8de9d9ae95bbc6ed81ed769853011b7942e63d2c9b530d2c1da7733a02b23741866e2d04355f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b358dbcada3a456ddb67cdb0b8f9979eb396f07d2c33d6f08d2f6d4b09ab04cf155cc4950ece534459f7b53335f9aa000000000000000000000000000000000691b39edb1b00041761a12e2c7425dadda0aea6a50e9c45606d9755c0e015685ecc1cce91e0ac8936c3ff69104667aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7bfe72c99854c4585ad751131829509a796a5d722ba2103421d197f9874e41f6ac7161a6a883f1d413367e093766fa0000000000000000000000000000000019c08dba2e8a5ca3d59afe3a37b161f400bae355339292fba4105f58dd4bc764e845c32092ffdd3ac846979a86c017541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba553541a118d9abfa89775c2f8b362bb5d88411dce6e12ed611573c1b02be0f56ed44100fd39aba193bd079005a14900000000000000000000000000000000157e5bf2eb12a530ea29bd268d90ab03c64a6f46d19f90d4044229106d19a371a6dc3c73a23669e02ac83b345e6988f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014952918815aea3c98b79cee39c9c3483666f2091c9c5dddd9acc2a19fc39529497c07f484dbd9364ea845c3b78b5453000000000000000000000000000000000653a2257afac9f711c9197937e43a3d4b389317cb29b4b289b97843cb65daaf64ced8345240f4fbe4ab42f24c8415451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001818b11e2174ea89d71baa50641fdde66bca58bcd583a8f2147feb92009d2cba2ab326cdee87fde5c9d03aab97a43346000000000000000000000000000000001706a596255d9d0fd573a45c2ec171d240de37eb3900e5f4f6c046d488554049bf5cc6828156518548f8573f0c41de391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dbe6bd0b4105dd9d48cb0dae7a6565047f46c3cf388608621cd60939e632b0f8ecd0e741bc8442a4e270aff1a0a08b00000000000000000000000000000000105f7cc77e5cec9ffa975ccf8792d6ce97ce554bbbb7b075c7c660df5feb659ddfd86e17fdbb60cdb0390dfe8a3635ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a5ae750b45b4b7fe5221da0b4d9dea782688e0dfa6b6ac96d3c0f960b2d1a32c8b6242629c221dddeaebf2b32931400000000000000000000000000000000154556ff16caa2586831dce8fe83ebbac880d16c7b84b317b30a7b76b89c9a84209f9dd6c1060cc8621e1f34045ac5b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098a42c83827de71d1eadf012606d7c596f7b97eb600a6e91b1ac858b0aea038ea7840982b332000d113e325d6c6c74f0000000000000000000000000000000005bdc8f299251735a7a362840b48c7ffd08503496de13379f0cc4a9e32dd2eb43e8833fb163ec979987e9df9318e07f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965efee82bcd6d9ea87b285b7186d11480decd714fbdb083b93111ac81e8ff4c9da659b6d27aa706ed77adb6882e9d300000000000000000000000000000000130567c569704b7086e8ca1e42ab92806b2ddbfcd7c94701b380284074cb5b883aaab1bf645763885de24ba4c0ffdbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001942b149319968cda4f9d7a3b20d983e53bc51fc9e63a26a149a1c9c51081dadfa6861948279a3d63bb9d3ad195ba89300000000000000000000000000000000092e0a0d32f6fbcad7a911fb9f2b3c8abd66f49e3d2a98d701854351a5655736f799ca438d5b7630148b0f0a71a4d7641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005de8812a827ba6c2eda2d15fb5a512c6567b8ba35107dee99f07f70e77d1f809565e1709aaad755066c25e90eff99db000000000000000000000000000000000cf0b29848ca2150a6e8fc30d0a2fff095e3cdba2cf05eb6b4f9e7baa012fdf30013182982d898984f5a35a02c2d88d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee118ac4f40f6a8557c4e15cba996d5c80a03214d561b6fcd56696775ccd88b01a1285411995e1672071541bbe2a5f9000000000000000000000000000000000067beb2003398d36feae9f418a2d0d8f200b922534d3bf018fe6234105ebe8287617337b6a0b034ed22f389614afc081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfc352ecb32c491bc978fb115dc6e9779ded0e9aaf7d2e5586d2a21b12cdbcecc22c4be5648203643c56e8a2517cfa4000000000000000000000000000000000fd9804ea2cf917c485ab65faf9f52715a03dac2f4f0803b4a3949398060b7af106fda3eab55179a8ddc11d3179712b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2935b11f74fb47d6f7d1e50b2dbd65c4a31c267ace95e7389739724e5e26c0e21e2bd1bd7c02eaf05cf945b9593600000000000000000000000000000000012b667af8d120a0b26fecc610214565f94f1ded4c67ced5828c74b5e14ced751eaaf9cba8bfe3743f056d2f20c8a867b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a13d122dfc6d6aa8315e775574b960eeceaf2e53b2e5ad1dcbcdfc785152fe4f56f667fbff4dffdb99c528f5150141a0000000000000000000000000000000002b791f1585342f9c98975912a64dd56e41dbd43466394598f0f5e0024f9cbc6f7dc02b1bc6ca9e37e4c9fb86b4a33241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031e61fac9a5ad59f21f0a4df6fd17ad02c52c27e797b516114bfedb3be79dcf9596f0feb56234c2889451032c517dc6000000000000000000000000000000000df261ad5f4028967b63e6b82a2a32d5a05e326f2b7a153f17f97b944289c670dc37a9252e40f03a38c289cfe233a9661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4450b069f179258b904c4280dfdd660f216521f6d44aab245e3887d5eb244889b0816f8602bd4b6337728e0640306b00000000000000000000000000000000061c39ace8d371c4a10a596b4879ec61615c1c070c0fb46b23074851f94576c60b9331c3f285fb59c656504f50338e9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001675245ab016871af948c95d5a164e981256a0aa5e5b5c1845f8d5322bf8196929ca204def38358c5ec786de70ecfbd90000000000000000000000000000000003b5f2672ac084e1cec821b60f82bc8630ae904998fdf62542eedf9a6d08706d25945dedaa1d05ddecea7ad9cf4fb90e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180474fd96ed91dc70f2ffc9c3bcf6160fce6e42e481c5ab1ebbff1717911525fa7da22180b9461044392e025c206cec00000000000000000000000000000000061c5930f08cb4fe3d584edaedb5873a21a4f1496496f46938db1bd2ab1e8ab186cf7f2d81fcf09d97182e133b9d77641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ceff9ccf7a40575dc01974c1d9a2707896e96cf96d8317c94d288e9fe1c651a6afd06b73db5257ddce5e3492e6075050000000000000000000000000000000002a8d731e5198a077676ff03adcb0d998b857f0b0f734b2f72c89ac51f49c671db28eb229e34a1c7dae6d95025683dd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cf49f46ae22d66f8eeb3442c62c89a6fcd7811608e18c3addfa8b261ee17ec829aab147685812f8bb54276b785123d00000000000000000000000000000000033909e12dca5ba7de515ca46e2ea59668768e6fe7d5dae35fa49a42427d224a6c1b71102056528fb9e2b0d8e792b1ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062f46f68ed283ca0bd90171167fce9a1dd00e467671ac3895e41a64c082ca934fac3c41f9e4f09f2f64e6d372a680a90000000000000000000000000000000008c7a314bbbac36f9baea503312ad72c593cd2d1d4073fbcb21ce87c5c3ac416165d6b49b9e0db0c6c73db6e007a74021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b05ccee05d515d411a62c1d7f90106c0f8453c8ed2ad97b633b52c0b8b7be8275214c886c8c750c3ada41f45165a0c000000000000000000000000000000000c7fce37d21540739cd6e98a67549f9db725f34b3279c02a5e663b03503009c3f3019571fb0f68c1dfb86b2fcfdcbe661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625f70fb3ac0c9ec964ca9f5b68eb9802512864e4e149d9f567eaa6b28566597da6c26f978fafd2199d93c9858cf1ec0000000000000000000000000000000010e447377c13f49e36e85498f66ee5bcb40f492854135330979a3d9b37dfb3fb68f8d41efe5d425e9e67d7125e7c11cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b98c753fc64f29c26f48f7e8ba20a77119d5070b2348eece41eacf75f3e5343d095be24830a1d7a7330e23d71d9694f0000000000000000000000000000000015990f125ee6ed6c438176eae44eea0a1b1fa8c6a5b211ec2709d72e5ddb02e6890d1ce60e90804db39d7666ab2cd49b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011570c19ca60f248bf4258407507268363a31926627dde77e52c086be6e3dd56b6f5ee717360eef87e78c560a9c4976d000000000000000000000000000000000a978192f987cc0f03bf4872c764c354000f93fc9f364a340ff76d4250883cff4642acd3a8b47fd47d10636ba0656b431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae8040231c919f0f3e6ccd46f4bafe2b464e135b478b7b8c76c01b9cdd01cb5ef520e7561190bc5b982ec5e38920a87000000000000000000000000000000000c7f4d72e869dd3c859cd1416569b2ff3278fcfb230a737fb9931f29194d0f1b765554ad5b4462267409609738fd08361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b18279295538e4199e716091d75b7206bd8d82861fc0ccfc8425e123cde5b233640196c37ec54f339934f7e0afc52d9000000000000000000000000000000000675565cbb9c2f281faac5d416bcb7c346a278c2b00370999d1c6865ac5f2ec4703c52cc7b52b7817027b9331a383cc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a0b18c5d0f0a14945983b34d5fe119067d69939164b7239d3bff43b0a9b3dd911976b91d744636fdcabec1a618f04000000000000000000000000000000001571fb469a12f70681dce097be89822dea93aa68a91c309a513fc36ccb2c9964abec0b723d864bf0b0af94d40c511cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000771a6ad18fb99edffb66c11b6e54664c72f6ac11380888adfbb95da2645ccb76a62335ca152fe3d10bb17c1bf1970d800000000000000000000000000000000148627c05233c6507f5def752bb27639f8e356e42fd723514bfcbf304df0270d169f4ac0c2e8f7703ac97ea4735ac95c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c2c615405a1962a798f56b75d5d6d2164e5f21ec9f08647c725190b7ccae38f19407e9c36a2ef4015a449bb881d3a80000000000000000000000000000000013712a73ce0cd3e15ccc55e41506bfa9e1f87ddec178e0e4716807b22db7ebafd2a766ff55a1caad274afb9be98b156a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000254bb2e7bf42ea22908b313d3ca8dfa4ffeb194073a126df0023b6eee47c1b4de97b777747648e9146e60f989f08c8600000000000000000000000000000000192911cc9070a8a95cb6b0f5bea78cbc75645b7f1e4beb9c3d117a04b25188b8ebd0e1fcb5611bd85f2f7692f5e290181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160754037da240a910fda111a060dfc16700e5ce7ffb5e0fb8c8a7e3fa4780589e194bc416a7b3f1c5a691c483e504fc00000000000000000000000000000000049366b802fc4b025356872ad66d4cafd34c234fa7c4115e6d08a60acdf61f55b57e28af84e6a99e2a6739529b3eae1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012151d0ab0b97a56e01003b8eee2a0a54f59a018fe85b9a3a88466382e2f0eddc246276d8979e7a30d2bdcdd6dfbc9aa0000000000000000000000000000000007d7dcf664dbe78ea1eb5af4b9118359e54aaabb32f365e643269578e125c42a483acbcd3f107b5aa814c2672170ad341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c50194295e8853a3cbeceafcd549a63a0ee12a8dce5ab4c1f7c8751ea8a8980eb3706eb9711a1eadb8f6874e3ae71d00000000000000000000000000000000086382b73f8379fdbab190a31f36900b1894a028a732fbde3e37d70d3a8c53d5cbf1d60797b09a7756cf1cc8bd3738561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f1f1a61bcaa76b6b13d4cb9656edd5d1b0b6c9f3c2f935afd990f9e196ddf3fe94d6961e87bbf7457aaaabc15fa840000000000000000000000000000000000902a9782f8af65ca135c6aa62e1ffafc1c3663a57aa79f30d203c832c873dccb94d3fc70ccbc024475112139393dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1cdafa828687c55e58c1a2faa1746ff737cf0eada80cf664ea3528a4de8b43647438e377f74fe7fb8d207a8e2e44f00000000000000000000000000000000124431f43eaea1cac8d0ae373d8f514ae84142ebb5e10be9466da0d56aa45fab333332a8f51414b15e991300ca0361351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162f0b3b51a486ba9f9dd5371b7d44286d6d8bc066646005149571a387e5af2b24a41f7f82db561c9206dcbc82442a8d00000000000000000000000000000000173c69fd43f04ec3f2d4ded29367b790ca8958413585ac0423bbdc6a71bd888cc9f3ff905e0006848a8ac79aee080f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001311ca6267fd37f2dbd066c33a639830f1cdc77ddf173c8ec0f422d09c8e7595bafc46ba8faf4a89841bfbbbfd6aca26000000000000000000000000000000000e1998fabd618e84d5cbe4abc5c4743b6a34e9aff7c43c3084e549de5dc323ac4a5e62be9afa530f11c80a298aacd86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082889f7d334c8bce97a84b790b5b0b07241fba8efe91d61f0b7689a9c3c43c92c777bd66927cae9911c8f19afbf2ef000000000000000000000000000000000051114d50edfce8ad48550aa62e55c29348ee5d1a96d7ed497a8b98ba6707c6b06029a93c11743e94783ec689eeb5e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dca5dc0e4d005ce43f920b8055e903b156ab5ebc8231f34e2a68bd022b6b3308f97d3aacdb8b7edfe5d327b1acd0ee000000000000000000000000000000000bbca756fa632ef50ea75f1ba9518ff1bad2e95332f7c089baba58c0fc6d8bb517af01b458eabc069e6d305ab639cbbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e246c26a722ac2488eecb546fd27d3ce231e7525ed27d8b0a007c85e18b27f4142ff7b0a11227b0fdffc4dd9ad542900000000000000000000000000000000058d01b26984665222bd59512798faeb160a540cb77dab9b7cb4fb1d3a25ab1ecc477702f0561d333c3e0e9afa7f91011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c62b3e1c1042a51f113860a7570d8b6f7b5adf21e9902d2854022007d80cf58fe9f65417649a8b19b9f2d1de9405c7000000000000000000000000000000000bf588bb802df12f15769ffb802dfca4e08550383ba0f9dcaa940281f780bd4b3fd02eafa28feba1ef94be340db96e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184a256e50eae99cb5252eb429ce3954066ff6893416854a0b2f5f60a3908aff263e3fc0fd63023402aa256c6f2878ce000000000000000000000000000000000775130031dc563ef9866d63969e6940917a12318b4c7b58a7aed3986ecc37e268bbc6b491c9b1415ea310065f8297b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074ebbf5dc9e032bd6a8e2e6de5c7d961ea4714b1404e8ddc70621a5df7ea36a502b0d277eefefb71c2a19c04c1517db0000000000000000000000000000000004913dc1cfdf43c8a950879734a8bcf6a6af35166e1cd48c8a3a950e0a035afabcb8cc961a19e67e3e9711739e8eb7c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135c3ac527c06b3254938a85b08962b5a1eedb0f29d989b8a621b90893d52110fafd8c8da2ec9307110a0cc5fac58b8e0000000000000000000000000000000001a67bcf1b003afe537a756fae59c0b5410e2c29757a3093f64d36d7be557f57339935e1b7729640659817682c6ea7011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fe309f09a54119ae8f088f935ef6c77c3969e04f556bb0604752a9d5e6df4d8138bba9405776aaaa9173f16ef5f0a700000000000000000000000000000000139d424475f4b5137b93528d5f219b473b03aaae685e17d262d83dfd5ea28117a32cb1f818ca28cdc9447edda387e8961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192798d81fa09194a7f31ee602f4e475240d6c647e29de9775b3385ea1e51684507ee1473c0226ac0277339e88eec22f00000000000000000000000000000000047da48c8b3e02eb93818e2fd58167f01e780172979fa296959359544faaf18b27f37cb4861fc86da476cee90707fbab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cc4d11017b08e0fbf7a37ac4bd97471f34418c8fb60b8a974c5f60a0a11adfbf204a9edf20163de2e1ab8d812a895e000000000000000000000000000000001471b65b5a0d7b3a3656780dae231016f7f9c6afe5cc7bb21f30a0ac09b2983c6c1019165f3ce1ec80cbebbaa4ce755c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ada32571d1f4f9dd947d0d3fcce17c705cd4ad2f3ad139df092ac74e0102e36f6337f0f64e5acf6e331c08c91b14b88000000000000000000000000000000001316a61c0be759344bf7028209291e31a6cbba20ed77baee5e7de1a8d2362edc1b2424cc11fb036b9c04e86a3e445fd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d76a13f9c68429d6b585515a2cf96bd32a9be4029717c6020f1a36bcd27efb146ac8e69497bab61aa290dadd77a58e00000000000000000000000000000000033d2abfb69b069c313205bbbd4662bc3e3e7b46e43912366f03512f896043b640dff00fd2cea141e9abcc971329e27c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088a223842be7cc6c514f589984dad64463be4fb9ea4840cba0690a58e5ea207f86fa01ac2bae3b82686c1358de7db95000000000000000000000000000000000c2896e7717e66a8b4fdf99149287662ae3af2f8a047bc631330a55410af88bb2ec7957f54594a6f338a101f0bcedd1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003253734fc1f61a537f4c0b3899bfc37cf8cf6929566f3749051b3602138adc52ae169dd35365afa3df71a6cd28e15af00000000000000000000000000000000044e355cd514c361f9b7c190e4d6bbef6790e05bcbb77b386d249d0e1af46969c13cdff5b062e3bfbbbfef225e18ed9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022340d75eb7e0cce293316f8b5b2f8a3166db1aa356d4ec1d7a3d74a0b5afb6c9a197cee094a3d0179c8e0c8059d0f60000000000000000000000000000000007d27f07ad5820f6188560f86198c42f87548a42c6e7ba7805c181afe43f837bba51e15e4620f79e1d60cb18348612041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004279cc1f57a5dca8615b1981ba8bafbae157f4253f7da72f8ccd5be1b29795c931df3d9f95d711483017a9f20d1e04500000000000000000000000000000000016c21ed357700f02a37b3f025809dbb2bb5ed6c60e195ba35ebb2cbe3850e11bca71550f2d59290a5bc3a44e19c94431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f0dbb75b967ac6b5e31c460ea7513a66ce15aee0d3b4a4b0219923ada64d62b27e93d1ca5cdcee59a4216d706b5a9b0000000000000000000000000000000016164f86f0efe58170600abe7e500daeccbbf1e9e41b6e625e8cbbf299c2899dd57e1196ed2f4b000549f13d99d7a8f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a208615ad2f10179584e03ffa40d736d7a4fd06508b41d08e2fbb7dcd03ec871d602dc8495d94c85b645d017b5a1c2c0000000000000000000000000000000002dd1cec0de565a72e47c655af94ed366747859c8ee60ff62c491b36912298dc6e753b387691fb4c71bc9b280fad10461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000266a685c9612d7f382b04d38b50ad4202944657d35b87fc0a0234fab5446adfaa431cbc9a1cae794997a1a32aee5f530000000000000000000000000000000001c1428e505fd1182e73aa962a9ee272996a708cfe02ac311b5c37faa9e0608919ed411cc3233074ab6f78b7dbd8df4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef23a87125937fe9908725d79373c80903cdc4ed2bcacccbc25cf5837c1179c9dc534480063ee0d5ffacb384205f9bd00000000000000000000000000000000111f0fae06bad6e524d00af3ef1f3347f46121a32f8d52315ff21789063eda4601ac3b6cd3acf33c7e52c71ee2cf4c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c0beca26609f6ae5f6cbd0859eef71b4cd7d75511d3c6935a7eecedc0abe5da9789ed1a0be4dbc3746f9a82fa1dae10000000000000000000000000000000012adff1919439558e71d276e1e21f061000ab267bfb8423ff69a921c85ca5ad7ba0aa4f33e387216f0e88a410375ff311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb930cdc25aea3a082a4e291f04493d9bcbfd59610ce51ae1cb6aedf61387977d42ad3700fe0cc1cce37a570866111b000000000000000000000000000000000c9760228f5ba9c7befc6ef763d1017bc8a2a8988327df60f047a4a20728892eef0a21c4aa4fb73e093359078bcd10e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c80912bf79cbc32b4bb44a498cd463d77cacdd1ef3592687c96a03e28ca0700145e118462970fe0432849110b7cb780000000000000000000000000000000016008807e5de33b666cc573952649ada4643b67940b65be0f9dd54a4afa33b67f53c0c6c2bf5020ebcbafac048dbb7aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bef0a054f5c8d82a37b793c507fc0841c755a25f7dce1540441696c936aacdd292096aff26194c1311e61b5f7d42f700000000000000000000000000000000169043a4c3bd801272dc7e2425cd91e02b8fabae5345e331dd72fb3dd5c4f8e4a80e47d2c9f92e5ebe78a73c34e43d261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000452a5e4f04bf67257eabbacbe2b38bf6a950dfb08080fa7d7ad8928d5123a567e0636ee6da9b767098ac6682b79d5000000000000000000000000000000001352e89c105a085c68bdb04b05cc6abfaf29e28c61d960f884aa3f50b5417741d1cf1fbd3946625b6b7fb80218342f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014124127c5db150232e88a103808736c202dcc63801516ebda06a1fdc8d7c7ecaa66d083c5fd830eaa907bced902d5db0000000000000000000000000000000007f388d2e7387cef0f53f9527236e12756db8cd94e785bb43dfd9f3c0916d51caaadacca6279aa175fc306b23506a4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b65fb3942a3bc3a0da7fdafdff5fc37db4094e3f1cc7a70d80e094f728e587e355438a24e731edf4647d051550ba1e0000000000000000000000000000000010f97a12f00cfb30bf7c80c685a4fbd0adfb05264fc7c67f5c4e92c5f82c6f427335ea06a535aff38d98e8737ac990281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007539670c793d1b91f9234458e884210e42eaca0aa1668a85760d2bf311c8f05e1ce5a9c44c178d9f1c644320c6fef3c00000000000000000000000000000000100764d18aed2bdf55c3ec424a2af427be4391c5b523ba99c57acae456da579090f7a312f6fdf304c0bc777ef705d7401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f52e825bc139e23a7ff129f27fe6ee15cb3c7aa5d0dcfda2f405f689823d8328836380aec73c974ad9c9034364b55400000000000000000000000000000000053bce7bc8a15d8dbda96162c642cd6e1b69b7d2718d861616105a28abac2c0a784a329c4fe50b74413e0ca24ebdb2b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001110c9f83d5817a82e1182f6bc6031dc6112ec048dbfc0741d3df716b5ad2c206032a606e296dfed31ee1d93edc1e82f000000000000000000000000000000000089749512c1eb0572c867943218d24cd1c5aadfc610dfbc7a2c4e30e016d093767605a53a6824463971525fef1fdd7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181857afd7cc75aae25bcb6b5acaeae41fcd98771b9b1a1efc9bfc8cd3df0a7e7baf4311ca4411710651cfe7e451f7d90000000000000000000000000000000009bb95d0ce01fcc66db69b59555b44959d86dc01a63038018826d59240759f79981f3001512ae95e76eed6fbb508026f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019604b9d149ff4448a986e478f6c0e733d1195894439d768e3d65f7e5be36037114bf6801786641e82575a034fc45d7c0000000000000000000000000000000000effd3a2377bf0e90fe25c733e64c08471995ff6a114552998a84fb3791a103d8a07e71a5ab470e619a8be1e8a005131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcddbec700e6706075a7d2d28c51b683ff8ab557cda780b2437697e868c92882684e7a285c4648465643616e049ff330000000000000000000000000000000003ccc01c5c8a9e09bf8029c8eee9000c1e7963a2afd06a090345f899e8b1baf34f9b2cfe9e8ec8c471a61cf075530d491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df0f041608a5da0366362aeca3e43a3b59de0d4b21fa0a37f83c2b006029f41d3c57408aabc3207d26d4c5bd2269028000000000000000000000000000000001487675e8946ab4942754b61a2edd145e5482956947e5a28b4e780463bc695481be1e555f837892e3f8f979daf44dc4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02505ff355766385e7c545e0d5fc37339ceba0e6261d8cadfdf2c71d7d0f9e0385a12de1224ab282b115bfceca1a630000000000000000000000000000000013a1d1c03bc36edcce182f01582677e40ea178fb8505e4fcbbd73583514af6d100b6ebd608e4db06a375f80e59918a391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011800815b749063fe1f3da8744a9812dbec6b12f4352d06463ba254141473e6bbfe5ed94678d289b01463fa0602d4b410000000000000000000000000000000015d6b529a33da12a0c17a038f21504e44414d9ac2ac618d0a57796db1ad28e10e53b42b418fbac2f3476f12b3abd27a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec4e5d42ae2b64111da2f2ea314f311d03508c36fc4222e06c5822f737fdab113b32e9dda18dcacd84a576d905af9110000000000000000000000000000000002bd0f3f9a26f356a060d043f0e6fa361170e83cbbf30ba9ab57aae053bb827a38b17ceba8f766fc63d55fd5e9bdbc931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040b0ed65fb627d069d81b9b9c6bae97067c0823a868db83a0b31b722f346f21e2dbfa18aa570a3221ed16c4331370f90000000000000000000000000000000006f315db56b39689bc706bee757c67fd68ea0d782e74b64e48fab793e001acc524aa0371578a86d70be271cb59325f741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110afe91e7a6ed75249e80b1157ff9be5dd99491e0e4a0739391b9aae1144bde8119b972e887a7ce1e2093535eddbc3100000000000000000000000000000000063536343d922473984ff1518d678a0dff486d315483ad89b7106967489f2ef6ecc315cbf552168f36a4536d4eb7219c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175ac1ddb840c29a57e31daac52803bdc63dc860e25e2beb7a999de9ba92f3ea21035be7fa42fcb15afe5ae068a898e10000000000000000000000000000000004173e78c6b790631576ee36668e3fb9d9ab5b95b0c3c9e12356c4f5da0c776ed0efd6ec5dce57b5a9f0eabecc79f3251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1256efea124ebeee7536fa67d52211cb2d6e21dd153b7b56d3c75a88ea13fabd44472774b560c827c773767bb5d7500000000000000000000000000000000090d01c8f4fcf382a9f3a7b9a384a878f10607371609c9ee6cc2fde6cbe52d5caccdaeb13b5426c2e4ee9628a1f109d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013e68c0d21448eb799c7b9a66152d2132ffcca5e86abd6b4af57893ada49a16306b380095ee2ba5b01f0359ed9b31620000000000000000000000000000000018a353b8cb237774ab89332c08c93c94dd45e9f1ec270102b0d055753a2a95dfe34157d9dcb873b5375296528e2b7a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcdd62d94bdfc9c8827f2ff7cd80d4542a6d993d5b18a2234761ec8ee11b4f4b65e18456feb9bbd826606b306445330000000000000000000000000000000001592c717f9ca17d96caadfbad9761c9518e4aa53f486812f80438b03466c84d2d797c1cd963183ab41db36c47f1c48d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000740fa9821228f6b48df5cdf277a613278f9bbfc5596da8cec7608f15c030f0617a04bdda9ca17347a614c4c460ae50c00000000000000000000000000000000064b8da267527980e4207c730f7c38e1b13fe3d13798befac5e60ee730eee77debcfa42490b6bf14cfa3a853e83271c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047360af520ad7d81a1c30b77c585bfaf8760776d0f5f4c1044e8022994c9688dea200e91c08dc40234dae1a016136f2000000000000000000000000000000000faefc86164dfdbc128d0072bb4d15524723d3a191814d9cd6eb25d34393f240cf6ac63e03494e40f79d9076848bd6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f1a402a33fb33af259e6f3eb373ca148cc60f61bb46bb59dadda95282a73292778091541d1a63c8471d3a9e8682ebf0000000000000000000000000000000014a8c48feb5936aa1fec493172130d1363e8431174e9bca811546a6c53b881e84e2b4781a342d1b6954184a1b78e25761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187b5460ecce36ed8e5db02f204a4871b7b1133bd4c2182dd2d9e70f62e8e62a0165914dd3aa197f28860db9de6ae4900000000000000000000000000000000007b0277d455bcb423a917c9f57fa0b5bee51af6d96fd68bf220b0b27100d58856535a272b87163db2fcf499fbd85856a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9246004f91d44fc52129958618b36670d00e587537c5f3b53e760d56165a4b5f4d3371fe11ee3b8de0af2f610838680000000000000000000000000000000008dacc4bc6768ee62cb9138a33a9483ed13c3a3957aca9dd697e1be3eeba5c1d385376b12262ebdebc6af35d7b3345ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3ba1774e67f66fe4337746c0947c915cba9d16206672aa419df8790b428112fa2ff9be0dc2b945f223eed6068eb93e000000000000000000000000000000001246cbe76e597cfbd0fcbd28b7b576c73e123951ac44f74f58094d8ed4f05ba6a69a66a0c71be13d25c38da5afe80c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0613bb9860ca07fc7f1949876a03f29fcac55ce46b1c9d486e9c2ff8e7eb8303269b70b38b0d62395b0c70b66d3fb8000000000000000000000000000000000ad153db2504c85637797ed9dbc342617afb150bdb593783d9c8cd1b1eafce41f8e4ecb16da4797569e36dd56b3665691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d5ff3ba7159046de97b10793137f49097db4459c099da627cdb6b91432cccae95d91995747c5423aeea8f09fdcb23b00000000000000000000000000000000091b15b4d1e3cbb1679f9956e66fcfd276d8e00e270cea26df5d3cd744bed003180d302beef8a39a32a96535569a9ed01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cc8be6ed3bc6fb85d996168c3cd77d9343016b131312d987d2a063afa2aedd532493535090a71bd3a4557f64fcd5990000000000000000000000000000000013dfd6c33a326400fa8e5575a5f09887f0c90eef7126172789f52771a03dbd42e117c2d386633c6499e47c0cf44591e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d531d643e289bd33a114e91cc6805cf45fe09cfb46756d252c78e1c72721b3482ee58a55b92b3df8466a3e5b2c5e67000000000000000000000000000000000b382b5cbd7379675347f58bb9c9ba9df34b420eabef1b437bfede6923d23b68097743eccd981abaf82dd623aa13bc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001318f56a548d8bb658c3b8486d1ffb90621ef462d832a7bffc695342491a44125e6c3d571f1afe12592b427e673551960000000000000000000000000000000005bff673c9a4fc9533bff8abf979228a30141a33647686213e08652d94af293de577e944b7def9db6482435e11c994bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190dde2e55db6b51380ac359ebbf71e32aeb12cb87cee2a042970e203be778ceda3b90a68cc2231460d39c6f38f972a20000000000000000000000000000000009985913290ebc4ffdb154b54c34e20b5b951cdbab8f4bc6d678f5a0e34dbe9756a95d951d8fac0ef526ff006a77c1151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001054f66a716aad2b1a08cadf2e0c8f430820761d765c6646afa93602a8b287f9add1730f307842b63a2ec5382587d95d000000000000000000000000000000000425d03c26fefab667ee9c2b71e84cd055e56499aa889f050a0a6eb256212868b1fe1dccb8dfb2be9782064ea1bcd71c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000b4ad86ea0164ac538586a337e425a9ecc4bc5bb762197597cae01e0c8468d33f58c24fcf4010ce686bb0482982bee0000000000000000000000000000000003f932096cfde9bd5137c024c8659b35d63be77d4f8ea6bfdefcf6ca04ebf143d550d1d830ed15d317c1edbd5eafc42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f0cfc0cd5b06508bfdcb5718a4c63d80a261b8306d84461c4b0866794200bd28be233adf5927da1f35ad76e3d3faee000000000000000000000000000000001216142ef0ef4f3079860828467493f2e07ddceb663b97d103352e87b225eb24f0698e4050b062393cc0e93daacd8ad01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000129f3504419d86bef4b46bb46cf7c36c97cc6b5d08936c8d304577b691b43daf6d2ba3550e0d153e6718aad028b2c9100000000000000000000000000000000018abf4a9f4dd92e1a67f05c6905c1e79be30d6e201c918916eb13fb75346739449bab0ac86ab9ed51d30bc2f408771a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000970b3998896c60a3afc2e3caa70bbd75fccda97e2c20a815cc0044a73143635a693321ca2dd62b2f01311e9b45ec7e20000000000000000000000000000000012847e67ff8427e1fa065525ef18340cfb7d41c82c0c381be87a623120aeb075a6c193d760ac2ea2a1b2b935d245bc1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073481000bbedeae7a8ad2624b6753716a34f006af524eddd10a93f561217102adef7247d9c82acacee2cbb8c110ef500000000000000000000000000000000004758b444c59dede5ac76371d7fd30fcf0d34126cb768ac8ede356db3bd8e8bbe91bee032a3c6c07edfc95b3b22fde461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def6ef9101a742dfb22d46f92fb318aff64accc19b93e009970d0aee0743f0eaa1f90c4918f9a37dd3d18f9d3b57f5900000000000000000000000000000000157f8895be634a8d235a50c7ba4c98666c2132d91451d071c89595e2a41c13072921764fa84812242a0f6aa164c39f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d5aa79518cd9d5325d0127631e124a1a148b45bcdb27f3fa680d5e868e2de7747752b64af72786e70d008e101db0e9000000000000000000000000000000001894c2a988a99d578567c182eeb36170c3895ba71fb05104ac16f630e5d89bf30272fed3fbd008f3a0c0a48bb777b4451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c144f5c012d36ec58d75c09040429048e6a317c550714e4ba091b681eff493dcd98f9bb6a267491433e1ce995d96780000000000000000000000000000000009b3010abb7431240373199a50d865f1808b4bb6c55a7f65f7e06fc8042f3753b8b4a9f4075d3e60a6e9af15dbc357701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e7552f97296d60ff327a5b1e6857325b09f0dd5b6aec3df9c8e0ba061e9eabca61e072568ac0b885e20b6fb212efa900000000000000000000000000000000136807cc16f4e18c0e540915883bd7afed95ff6c9d10079fc2713fac90e7d4d43f22033bfcc4079b179fc77906d4b84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbc60f948c2c733716702b8d0fe9d2fdc94c49104b314a94c5dc5dc4a278d89b814b4493dcc5ad47528f70a49865f74000000000000000000000000000000001901bc9c97ea3bb05dcf2ae05e6c2a38b3693f173c7ebc5d71d535f88e491d5ceed00dc049b6a47155c20549ea1edf631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018265bb96eda1b3fcde6c527836fe432b8b952895cd3978db66ba0aee789367e657ddaa68d9f0701412f6f05d1b6fc3f0000000000000000000000000000000003a8e4910ac4391ad9297f2fd7903448fadb9fc981b4819725cdea045d8a2b2ec55d71e604c40623267e4104d4221fa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000404c9badef6e616d93c59835aa0f1d4eeaabf2127e5165fb78ec6eb38e83e4f6c4c6aa792116e795c854d643dd714eb0000000000000000000000000000000015b0d1e2c50f5b91c28e7da910350efc381dbbe250c4268e306914516fc6a30da073b67fc80b7dc87c55dfd83d9898da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160e2fa8bd979f815f7c045e61d82b7ed0a691d5254d69d8e7e5e48a899497f34fe0ddd3f193cfc5ee68a3b4eb544af40000000000000000000000000000000006c9f80802676cf98ec2abbd8ea0716014ded2b9ef9262ea19a90236a036c19750c3ba0860bf1ecb7c0e0ce0bff44a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538ec0f501b1d931a3d84306c3157e4e2292530df497de260559944b238ee14a06b45b630772b462a7571b78bc1e7d20000000000000000000000000000000006384117b5f0b02209bbf0dfa92b54f4e8e4d0a62d58e00dca479756094fc1c9317c42d7dae1572561edaf9408e52af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f2a0a1fb45ec2f0b14460be6c09481e86da415a1c138f2f015ddf19dadb224abd6df0d107a25b2ca181b41fd524003000000000000000000000000000000000e1fa78bdf9f2a8f7cf4c04946b5cbd7ac50eb43dacdb3177d1f250ab8ec53a0d13af67d2dbb190a026db605626d4ced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f80dbc50371743ea40d30377ed7eabf6830b786e229c5bbee9a7614b90481a0ee0e38e27d0bd803e12aeceef57289b200000000000000000000000000000000092dead05b3db300f709bebed4fc30585b65067d842da14157c2387212648ca945e1cc993db1afd310cccb478f2659911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049deb16851751c49459066fd1a0f7270beb6970e223a0fae31ffa3ea69633a6b8fb7ee9da6e60d4c5ef6f2db48f0569000000000000000000000000000000000278c1182df37adef5d388ce43cc07d3646b27ac5a5bc5f7a9b50f6f74c094f5cfd814a0aa8a6fd217b4f48c1ce853351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bb7b73babd35842cc1ca65d0af68e0c70051a38f9ced716600efa6b517624930daa7546e4da61069d121b943798d74000000000000000000000000000000000b14bb1160a76e907de9df7452dc8400671c125e3e82bb21945212bd21a2e3f57397427eee5db701f13a551b2052d2bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112fa4eb5db97f269a8487069fbb2e03f0c51a70f45d33611e17609d1b0609d5e2baebe866d99fff869e39019ca1a80a00000000000000000000000000000000170ef4a68d0f5b60c4d9f6eb6b629d7ab71bf7fff1eafc06e1ee317c2547b448505d67cc96e1166bbe7e905ce9bec3331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c4ebcbbd6216cdde825be522e61a8625560e4f24be225885f9323ebc3cf331e80f18f1eba286f761314ce2ef2fc99a0000000000000000000000000000000005a5b803adc0e76f524d1d93a5d99a988e3913489d2009394da5441d69db213466c6ffc53c9070ceb7321de77b4761f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128578ba01dd688c1e6cb12492a288afbd277072d42a15e81cb54f3853ee5131396e5415ca185833f19daec396b656a8000000000000000000000000000000000b42e06c9404da6e7b34b37e48c9b8c1168cf4537fd59ebb06e3d990cccd348c1c49d7e8ff2536843c6604854e3356321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590520725d5dacfd807f0e9d7b90046a5c506e6541058f0611d1f7d0ed54518f7339069f816142de77bc78e1ce1956c0000000000000000000000000000000011deef3425107a3c0765485c9bd3f399dec88eddd9040d8562565cfb55715178699a452972795950fefa385db5044a831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063150b62411d859a7d76fd378c67403478198744032ed2ed32cf3982fb3c483d1286f33af452e9191b166ea7d13ea3c000000000000000000000000000000000be24bd912f43cfa1566a427876bda2cc462fb1e7f1f5d5421aeae495438dae106365efb5d68b42a3ea67e083b70ac641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183abe01770dd743db6c40e46f9b263a00c8cba950224c8a51c897a92c78a7798b0b85ba59c404f448be395901978fed000000000000000000000000000000001927776cc278f4841734e4d3ce661fe843e11d2ab134d98c565fbdf05fa179694d2ce841e80418d70126105d3c10442f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001448f7a88e1790f7fa989f2f2582ea6dcb39dc674bf404032b512c9f9588000fe9a9795d39db6cd3add1e31b21d8c44e00000000000000000000000000000000193a24d86e1b707273e640fa98a2a068ef5b1b662634df813d1ea87284396a1a18ea634b8934a0b3104a0f1f2bced2111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9fb507acf4b1bb575ae952ed84d5ec4e6a29b5ea24a897753b90d49db1886397dfae349856e0d2e69ef09c4f28fd6e0000000000000000000000000000000007d5421637f5de504eaa49c22ceacfb8583963d6f10666e3a0d64cdc57ef242d93cacdc5bd86da8b9c2f33c0263e06d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c453a342e940da4e0c4fafe0ab6706505248ac3a8781ababa62d3e47d747ceda2ed34ea15b76315fa50d9fdd4c36918000000000000000000000000000000000e326d5e2a7e70e8070cd9c54f78f1872b40786f3edf6633779bae6e90efb175356b9fd706d65be84f5460a4b52c58841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001652ddeafcf821253c148db89a648d830ad613ec0ff6bd602935547ee1cc8900088dda0fcfdbd271debeb7ba8b31ef2c000000000000000000000000000000000753e9a5acf86af7d977a473daa5fa6d27ec934513063f16fda5a86b512bff702ce1c4c34c542e69603158c129c89d121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001948be4f4d88ef5c51013756c53451e3fce7326c8623d58ca4afbec5bf8d1a825a461d7b39ed6a8224d534d06c6e32000000000000000000000000000000001579ff5700907668a9a1ee047f1947413ef9546696adce370e32af316b1089e00bc61b27ebf6433592b4fcd97640a51b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdfda36069d8ed76eb4cea657f13c1489f5ac1f8e0f62bd214ce24aef1245dc1453d3c45b827ba38132abac0cce8263000000000000000000000000000000001625f5dc86acb1e58465f3f44cac49631d63755b4949ebb235560032f34a0c22b68a3411aac826d9fa9d8f78d4c746911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091aa69660689333fb60a38d105c443462e0aeb49e6cb59c47080e92093a2d824f1f9f0aa6a2c86fe50a4e8d9942549f000000000000000000000000000000000ff0f77b9a6a6138951ff811008008d62c1020c30b2ac29e635eb3ad753f2a443852ef3c8ae63b816d0be327515a35be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128562158ac53555989e3879e577e7a97a99e1758b68bbaeba5880d6d70592ba60829554bc1e29668c5009d27a728c230000000000000000000000000000000004abc9d2942359c1656519e885154cd0488e7a5461f7c924e771648fa0635d8978cf18cbef8a87e708218215d10f060c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ca203f58cf12faea4ae0e79ed91f07b3d4075d5e524919a92b7a411ebe4b9efdac5c7f19c2d3244b4d9d9134361ca20000000000000000000000000000000014f6c0d4751a6781324fa4f0d152adb9329f22453a7fc27b50632baf8d9c5713c9996594ea883964834b2bd379f46d8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e38f31e1ba0a15720d569041cb751f885808a195ba4016f5e1e9d8e39783c813cd0826917ec9334516328a56327dfc0000000000000000000000000000000003146f4d4325f78021c28ead7bdeb307a9b51fac79f342c29cbe79826f9427651bed51c8c25ba006e2ceb1dcb44b0eb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004067519e8ee71cc8bbcc2289a1a22472ad758eebd26902e80b7885852b9e202421f25fe7f3ac21c34ae0edd1ca2dd72000000000000000000000000000000001847709676a8d44cd1d60a3590e558505372d929bc95d93642d0955e68b0b376eabedda257280a552a7ec3373046122f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046035d172dd7cf267880286a3e8ced2dcf16625f912da4e8657244a1434844205f1d72ed6e82ef2d714129b2973bd9a000000000000000000000000000000001050ca3bebcb84ecd73d448f7d9a9d3ab8253618450e6654ab68d861b58954d8c5f5f5752171f357a02e4d6aa1493eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a71b78237c4e15d8e7a57bc4113e9d87a16d0905440c420f8db7fd5154d4f2b77387317060ab556db85929679f2ab60000000000000000000000000000000003ed16459ae558388bf410b41ece27d6bdbb02501078b9b46fa4065b664f8e08e051974b2ab2bacaced66a3ff2399a3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001705fbdacba90c504a414796326cf867e0b21bf959ac1bd63df2adb5df983998667324049bc302f13db07b6d27b5a0a50000000000000000000000000000000015a8b20341a2bb1bb4a7aef8614c8aaf7b770702a31f1db92596b650bfdea873cb62248b41951462e9afe9fdd4e1d6ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aae2d94fc6595293fb63fe20a6480f3a8403ca2f47f04543f461a414695a86f1eff0fe7a603631cc7a8a0cc503d04200000000000000000000000000000000069c867a7468268c6ebed32222622484fab001b01b51dec6d009f73a8daa879ea572faabbdb21b6d45c0be0753d5a1b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e885ef239df6064c88a3b219ad40a8d01a2e02a771b544f2648582e433c78fc8714dc3b22be4d2ac01d02498debda100000000000000000000000000000000115eb97d959b55cc272f3974b2fb0c7954f8512ef0a95064ebcdb38db772d9946bd4bd0a8941ec59241faad65b19ca591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041aedc786ab8dca9a201805814bec8ca6fab1ce90b2c6571f398e312963a4d9448127cc9c485faf4e904af46445bc3000000000000000000000000000000000106c249bf9245b9bb91bd7befc7c69d397c1d4bf0a727057ae9801e5b2df23c698b1369ff6464f4f9fc551a7e333d34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64069c6b19172a6c92a4c492faec713a11b4dfdf606fa4eab902980952eddb33170b77056506e5a676b81345a7b7d90000000000000000000000000000000012f828b349d974dee88585a23bfa3ead4aa457af004793f86323653fff8b7640675db17b34080ad68df8fc784f7817151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190daa8593e3ff56d0cd389162cc472a091386fdb3a2a1a503f86d89a1c31f3ca4ee7319cd12bcdd22ab7836957841dc000000000000000000000000000000000f69c92a106b6c8ffe1cf0643f507af0174721bb4c44db4f3eacbe4280fbe24e2435930d768c822b3a4766dedc57453b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074954f0da7f196fc65af579cb7a649d639f1a820b48534169ea7d2e9f6c9bdf685be2e8e2c230e77a9a818e840ff6cd00000000000000000000000000000000111184bb532feb6bcb2da352c0a273a383b232e8cd8ee8f4e92af0b640d311afa348d4a0fb711c228f1193ff940409501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea7bbe602058c1e4e43e5844ae21ecb809e6024c477fcc03eb0e7a5fca10fcaf896bfcb4223ecaa4de2c9b5ee8e14b0000000000000000000000000000000009992bcbef9505503d29c07e71db857707f3405a7a9d16765975e51a5effcd10aeb529fc3b990e220b6a2380c7ac4d341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ec149ae811524bacae845b2b36418ebbcd9f572995a9ff11317426968d4d19519aea52e866f10eddeb5a73b569460e0000000000000000000000000000000012a88d14b708b6f5e42bb6cf1d70c3f400df8937c6c27aa0bf40a582153bd2798187a027bb09a38a9c9eaafcb5b948121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c8ebeb011134172f5e1e6d74c769f5bd50620702c72a3d73ecd014523c505feedfd24ab7b14a650873f8c9f8566590000000000000000000000000000000016c5f4c83143f67aa6f4a4110cf767f8e61dc40abf654dea54a54ffc3a6fa40227a5b796eb7a16f9f2d965c0cb1981cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3f7837bbba918ce0326a773e2904f08a9403679562f46b18bec25786baa32f274f61a7cb2a632183db698e3f416c0000000000000000000000000000000000d84f5a218a5aba7dfe2b44d9364fc4d8c68bfb28d619e159a6dd1f0811fb3e1aa258281cfd3a83dc474ef0a45e06b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001700f9453e0b7fcee68bb4d5dbe5a14b990bfb4cbb16ecd2fbabfd61eb6c301adc08a1543b08cd0d650b55202f2f552d00000000000000000000000000000000119c952aadd2be608400e60d49519ad0644ee4b5ed82a27075bc79c9e8a72081e7886160ff58c427906ac87341d22a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003c0eb1396eb5d57e0fbbedaecadfc791b002f2ccfed2fcde2081d132e1ebdef082f41b243dd0aeb03daa8012c743300000000000000000000000000000000018ddd528ac7a9c32a9bda8bdc93ab3f7700946859d5e94533694c09b63b2821d2fbc560ef187b210b1ee5a55ba72a27d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d440494b0af2bed95ee0833dfea0a624b97ddb2bf3dea395dea1fc688b76d8f2ec54bc0421c6baff4ab47eeb3decc000000000000000000000000000000001346400505d27a7e01cafbcc4a9ba5351589da2c107197a945a16d39d8e9a4cd09b5d287702fcf6c6a7860c330c175401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4dd90ff36976646bed1cfbaab176bff5ea25dcebc1a59be65db11d7763000520891a0bae74ab7a38b2463ef04d87bf000000000000000000000000000000001618cb0eceb117e2e46b5f49563bdb5cc9edcff0fc2b32dfbec1e68cbcde4d09d9493f6e6558447ec8cc5d3eea7b8c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018afd1a009c293139778f073406b15977c77ef96ef377ecc5f7e757784a32cda917f14a305062bef0ca0356002970a6c0000000000000000000000000000000017d0905bc7e07943f0c7ab2ef00410ee6f08115ef06a7bd5d258890aec39ba1e98152b45d202c35b23a995aa626120351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce87242957009efd36e79ab13e6261bcd1a68c678fa723a4dc3ec30ef37a56f44c0756d9f190802507a8f3e0fd5122000000000000000000000000000000000bbb06e79570bd3389479f3dd193f96778572b8c77c68f8843ff4bfac4baf66d26a3c50c4fea3b6bc2314af35eaabe4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eabff10f2a2c2e84201658083a53cf673f33747e7079353473c53e8844462aed9d0ed3172ac75af36b03c15626b29280000000000000000000000000000000015ccc21fba91bd99ab5a2c4963b1f39ae85c1dc5a5e912239d252af6b1275f2db78b4d81c11032443f4704942e57d2751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38e5c29411815846d9289773a80275e47c735ddd28f7ac91d5b0eeb6e295f333e973ebb7c1c487083a41765e47fc6b000000000000000000000000000000000094f0c6cbde38e264256fa4976968436ad2eafb3ed70c9e0ad9e4852b2b02624efd33db61628c7ce78165971b4ef9c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e747178b058dfdcf5360c465fc05fa210e844809c28304a875fd14c067cf49197c93c3847425e0974b3b2c1c420c5000000000000000000000000000000000051eaa2b2773af3a4bb5bccffab1d00bf7108fd875d5c94d439967daad7aa235797c2ca6008000b70ce26633e21c72d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001062040cf5e1274682adfb86b8616d73546160a03346a9c9ccd27836177a4216dd6a5e4b057108335a65b7e80c559e61000000000000000000000000000000000f85729f0305855c575e9ff7b6efaecdfd58f1db35ae5e64cfa2b83873129cc17c9654bd6596d1aa174bd9efd4d490c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194c6118f8e69220d27c2317a2ba2db3d50eecd107f85acbc3bcf7ed334507920f6bd3761d70d316399db451cf7ec6d40000000000000000000000000000000012026ad1bfa0bbd73c8d766b70063b89f44846b4f12084c49f128f14e85098ad87605cb4185032f5a1704fdc566fd2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091e62ada7e651d558a58da4fde22e49ee23fa0e8e90afc9577e86447a54d6ee0beb372fcac90e68da3bca36aff67a2200000000000000000000000000000000029109f236fff7808e09803558d443ecf03d5a637a22baffeaaa6a15d6b6b28bd50f192515829996cf9accce73e91b491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b41373279827efc80412515f56c1b69606153e61f7442af0ce9f32fa0a20a923f6b90348d1b8008cdce8f3f8c80bcb000000000000000000000000000000000b08f23c875f8b1360648ebc2669f0235f5d4a35d376a5c7c67a45b9eeed8b2c8db750c8f0064c01993d4bebc64242ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d345705c5e950c89375710091da73bb04ba8401335d150b8c843ed88153edcb099c2a2f135aee844b057935a02d5b0000000000000000000000000000000005e9b1dcd6e1942627a76a68edcda212818d283756efd9e45541235ac4f3a5a4356db7006f8601f7c713400362d1c5531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008432db6c86aecbf88c13221b7d8d46a6d51b1ac3d629aaa57804f5333ed5a438ee1dd4c47238169c74c2ed008755a8b00000000000000000000000000000000168047ff280a9ea7e02e2832700121cd61db6983af941d46b47de6d90e0e1b2f69d3ee038b330ba4643afe00ffad40371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2684a6f30e95c1609fb48213baea58d2dc34756a6768bc5222350bbb7c8f2308da3c6589b32ff12677c7e665f537c30000000000000000000000000000000002f0b18c4eb976c147dc356ebeb1d81b88a5a56c0f352df993f024deb1a91f47a747491bb83fa98824ac26aee19eaca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063ff43dac0dc78fa4b4ca5047c4a70d9a716d7f68903b9ff3377f70494c8db35b83d22c0e718352d411839e8d4885a800000000000000000000000000000000085d88eba08500813a5240a64fa0e638fb37242c4503701384d49d62aa87e9ad79a709deb2ac5853d241cfa1073caa5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012522ea0e13df61f1d9a4c628b5e17cb15fc850bcc9471b7056a4cf020882ecf4dd290bfe643ef20aef17c068aba6ea6000000000000000000000000000000001393e8c0742206a45e0f221cabb38a2d383e1e864cdb660e4676da56fbbfd38ade70490b0b41162f902dd1667b439a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8bdfcbaf7675e0fe270fafc17bf6440366c2f62e162267825c850b64d7af7272ec86b7e9e8d9df9a1aac642cea4769000000000000000000000000000000000a40c6e462aea08702386860b7193ff8377c2c674309b915bbb8ceea7632a0781f8120970234671525177730cf7cb2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c02516a2fc738c460b4b5105950f30041d55e81c905404c89a4cbdc48f62207a46301cec257237bfbb9706834d2756000000000000000000000000000000000a13273590963e1048f2fc46dec82d2064ddee0a339a46ccf0db3a0c0fb246db8a0047212c2adf10cde5b3ca07da8e261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c3aaee4080003971ebe98953c20158ed1cbf123a41449ac67da43358903add6bf51b54312928ed0e47389413d5a1a600000000000000000000000000000000026a85acb562697c7041e3cf96a269cf54848719b07f919d2e1e602f443ad76255eeeb7e7314640d36c85280dec22d401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018503e0071d3c8dfd7e25f74a8b248b9d4611c9bba17730d94c0637e40486ad8acc75858edbd26ecfe034059bf43a020000000000000000000000000000000003aa2b335cdeaa14fa83733434afa028460f7ccf1c7e84c8827ae1b763073478395450e39d9847a8f6b2c5b13f85366f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078604a999bcbfe5f60fccd2afc5e2b60b4275fe90e385a230b54e28a4ca5453f4ef8af1240d627be0be74235cd833d90000000000000000000000000000000003a9ac7682d3befeeadf99fb4cb75a5b4e6e709ac22d94cc09452bfab631087728c13db99aafaf61feef38b9d06bcdf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b947081e4ab6278b5094f71530d0a04d094a9edd24fd35586e457b39b11acfa944eab65526cdb282eb9500400e2c1460000000000000000000000000000000014be062ea2dc13b173ab950b0c943df48df7ccd21390c6b0098d80092d4bc165e5b11352c0807d556b6d0970d315333d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104e4e155f24e25ee1fa6014a7d967597dea825d1d37b6a048eba64b498110f0f93a0e9e45a961b990643568e02cea30000000000000000000000000000000000a0d2a8e7ca79c0c1d8ec7d35dfd19f66fefac148dfc303d0d053fbff786ab33629e735bee042884d45cadcabcab2e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178d98bac763b8409d9743d14f5f8350a00079177f83b484aaf6dfbe8121c8322878ed323e02e4dfebd2c75d682f80ae00000000000000000000000000000000058236bef349391bc836504eee4069b1fc5e5c5ecab99c6f797a1c1cbd41cd44768d392324b8c0d1697862de7379e9741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7177aed94cd16dd91c490b20dd6b52d6ac5b846dd586f3d528a40e890c185f808c3c9ffc3d574a96be5ca2e28a15b4000000000000000000000000000000000cc48a9a1bba2d7109c8542b93f66aa7d4640c6d129c0a2fe7a5de4a08a637e231c6ecb7c624e6c4f430600c203d3df71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091bdd84fbcc36a5a2ebb1ec02469480367230791edd6655440266e16ac69e0094582e6f26541726b95fae04d77c1bce0000000000000000000000000000000014952e5582d9e639ad106133d8c3914980ef2cf109977fb5eaf9e0d0e539db877320298cce5002419161767fabc678ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000312dc4905d50fe3e0bdc92b61a32b38b8a7c88bddba57532c2a3d34efad3502c174724983d8486f1a2b4cc488eb13e3000000000000000000000000000000000e336a02518a109524cfadd8bebf3a1bf35e468e6f94ecb575c4c105d5079a903566ec2188e70611867d68c6192da4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131bbaa14d4d7fd46e6c69b4bc5e70ab98cc4eeb4aad80e522ec2a5bf568c8f78b20563155e180d833624c354da3235b000000000000000000000000000000000b65c30282a38ed95d3580f74f92c845496753aa8f093f79eb56a7fe2cdcd364f276bea369b9ff8a899e35ef3ad4e79f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030444fc22c9e353f9764bf331b168e55c03f564b2bf1f176500b78b47e65f16a2a095ed640c3a280bcd5cfad3e9bf4000000000000000000000000000000000031c3013f51cb5663b3b47c66f81c132fc95bff8d23f9442ac79f87bb638516455469bb9cc3dd7c9a97732279041a88a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165bf1fdc3fb5b1c9e1acd80a33eee7d9f15a0224337408b13571f6627374c6b523680c76b95403d10a9390b9aabd55e000000000000000000000000000000000d3ab62bf060348463cfdc94b6234a23b7b5934c1390d8aa5e075ab7f7a15b8671b47bd2b532f4b05b6e64caf9685b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2550408fa1f7e5d6250151038aef9519177fd329fdb7436c25c04a833d859c868febc13da5824ec090a8e2e789950300000000000000000000000000000000141837a401c63a4778654f815ed54d85dfc61a73a61175b3ea4acb7ac0ba3ed8b506d08f302b91b5ce9a303ab795bb141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165779fefe916c61361d690ce281a37b8dfe7a0568014c56088881c135dac25c9f1323753410fe72a81f276596faa12a000000000000000000000000000000000d29af555f18f8717fcec1a1ae023bb0a8da6722fa94e0e54c6ce3ba424b2de0cf2bf08bc5bf594cb042fa43cc706c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005be40542e14053360b3ac551e38fd1482f5bd5224ebe17cdf71a46836c5b684a82fdd606166b019633461ffda0f76260000000000000000000000000000000018b77b97a0aa768a53bc2853a897aaa2411bbf98a9169ac6734891dc87fd0458613cbe9d5156c7ec77c42f18689b9bcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067545b06140d2d3fbfe3aa706444af10e07a1efbc1d4f0569b37db00196ef73a26a0f126bee93b70bf15c40022f53530000000000000000000000000000000016cc9942d16a7ef6295c13200cd8a9afd97c945b09bdb54c2eab05c6311d92772d598d9d246e1356a18a5da4aec25fab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011264c8415e3ec6b5bc743745f4ce84c6af6474d5b6616347b720e9b9fb89dcc782995c626c76ea8e061139ba8ab9a1a0000000000000000000000000000000005d7c7be4c2090cea6cf05063e31230158d96b2ff7b96d9831babd557285ac090abcfb213c3d52903b97874751bfdd6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005475aeb243b9b04de4a22d71e5711308f552408e6b6f1c76730e6b81fef3f0ff3bf79778dec8116b304c864a32f6b26000000000000000000000000000000000e3c31a159e8449a9a100760ecead5ca79af78ae151d95e12be5979e9d10c38bb785430765e7bcf38b702a61e5bc8a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b924090f2389f6b3f089dbdc3d98c361fe2d425274257addb8d448015fc6b3e6088ec96c1c40b6d4a610b2495f3e810000000000000000000000000000000007ad7d0a06c2be69f7032291f0895b93b22623d996d1ea1f976415f35d9a70a0c458562c59ec5fd13ae9fef18ee9d5321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa32bceb655b5c832a33a0405762a13491aa71f57b1d7b2a920b8abb51870b34b2e6161f51f90ff9b4029216e19397d0000000000000000000000000000000018c3ede1d4ab1e7e65bf7b15b3e4c18ac4187920249fcf5057232df37ba2e40b5a8cf0169f1ab6b508b1a0834a468b081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015af2cb45b9a9cbee29c09b3aa2207557e2a7569f77e6ea7bd38431f5d8a591e3920a654292cb406aaa888d7ace525f0000000000000000000000000000000001985f3d8df5b0d98e34b711abe7195e54dc5e98578a1a178a9c79512577f343eedcf85daa98fc24d93f1c9d5a908dd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ada11d3798505a5a613a17884baa67b71ce1235fc0649e1b5a13b5b55fc4df7b95303b6aea51a7b346157a44076adb000000000000000000000000000000000d31a38cbc46efc66f80cb46c872ff7e1f1a6b7858fc24bbfc676a1020a22f7ca65a093278ff89040c82c71e35f598e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119b9e58a4444e4e9e81ac8a69d9ad96fc6837135ea845daedd3629945b01ca82939ba1fb0c300fac47ffdbbc65a770f0000000000000000000000000000000008394b6a8eb77d7d1936312d7d09a77d736b40269b8ca7611c31a7547d0f17d7b11a8b891e6cca952ea41f4ccd77bb0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016686829189e32380c1887b4d93e04f1f57d257db3b79e36d9293a1401a3005b9d5cbd07d0fd4aaa6e7a0c2090ffb4ca000000000000000000000000000000000dd781e58a33a7ae65cf9b9462b222f289c9a48845fdbb9624c122d7fbc7f096c7f1f9a1511adf1379e126cc29650ddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d42759f4b3eef0a64c6bf891a6f33bd9eea5263e69a86721b5fb2e6f0dc9ea05fe9b5f984005836a2cd6c3be18656f40000000000000000000000000000000014870d36acae6ca33f8a519fa37d81895c7eebf0d203c41bc221c967ada57cc1bf8180ed9cd177012667ca4a0eacea551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142f74f20258e07e91f890f4db876d5be7057772a9262c5e67a3f378d26cedb21493a442aed3d05f05427812842ed880000000000000000000000000000000000adb2c79b6951f1155cdbd12dbcd548154ac5fe369205334bf6dc366b753440f0555adec4815605b1b516ee79466b3191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177a0f3b57e86909aa4ddc39d9780acf35f8e085bb0ea8d2b5599ca44904a737d03d316f4e1456d277aa79ff2e95a102000000000000000000000000000000000fdb19590aceb7406b9960b69dcfdf8f6bf1dc942aeecef601e375e5e00bd95ca283fec78ad7f31327de97301613cb431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035c14036ff867bc40d1e06697e64c6d1e2f712ca7c9a012ffc4ec8116ad66fb40d94ba463d6f8664160cd88208710460000000000000000000000000000000016ef0067524d0277349302fec0c12fedcd878d13d0fff211bc65bfa72ff979a6652f7aad552b308fcd4122c278cacdee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117cced5032c03ccad304054cf1dab7fbaf3139a4c8c918aeb4bedb8876be1c0a293775367f993308343cf3a4777fb4f000000000000000000000000000000000331daa33caedc1cdcdb38f47cae790a85914cf854a0fbfbb92ad03cbfe428b311dbf86d0a24fd97af29202d6b73d8dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010297af9e5a061f89190a3bd7af999af98f846c8e1ea04903a31a2c9b51c4f3feb190e169b2afc4a4acf4286e8d43bb20000000000000000000000000000000006a03be46b0534b4bf4cb2c0aa6dec3a12e5405750c8489f684cca0e03878af2e0eba7257ac0bd6c4af53aad6b1761df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d7034a270eda2921eff3405281e42f76efc013f4d855fb232d5d6f3f9a1e291d38a39e07fe766f6c0e942a6ee6aed0000000000000000000000000000000000f652700229831a0ff6511f83726de98782be1c6c2223eccbc9f2bb25161e0c80010c163610a81cea686cf56c9976721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000785864b1a74a782d2854dc50d7f0b6d3cecc344dca0be1238c0526ad4e6c7f56b00cefcb3bf5f46da5ca0620bd069d40000000000000000000000000000000014ecb7fed008ede18d2aaafe3a5ef90453d1fa18e26c32a23ae53e357f461c63d8fcf20e281f7477fa0d475e51bb5cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d906645bb06b3e7875ec0110c630a355d0423cbf613b8c9ae435fa10642383e502f05206208a26145d7d9ce3ff1fb0000000000000000000000000000000012f88c7b2a1351a2cec61bf5fa824a2568845f969e22d8b0ea4651e7a10c306160636d7b89fb2d4865e761108b96f5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e61e2a7539aa200c26252d3cae80b49d6d694c7f2ad7da45cd3a17653b73df295d85ee924680e0f3f237e1247445f4000000000000000000000000000000001704f6ee513f7cc07dc2dedc50cd5cc8df5b7490a132c6a5be2f50a972cf985f06cfe6dae1ecae46baa3997b92d7369d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9809bc703e6637438eb5ff2910ae3aaccc637c73cb2986bb076b9451c1e59e8f585c207cbf3fe89917e9bf104c3dc800000000000000000000000000000000056c847cbcc3d2826e3190d5ff03b7e2fd74c862aa38c23063756ab37b12c855d49816f1d2eb8774e60a5ab806a41a481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e3a89454f4407455144da1d3269e8f0c2d40a0301956741b5ae1eb66811dd0cb9e8a80c47fc8e6c51b77f6509a2af0000000000000000000000000000000012127381d513a5e1fef86a6811c91785fae288337af3fdb247af5f4e7abfe19c8a1352390d490587c9f484b2be0995441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031084bbd4eddf5fad8cba15675c53c54e82be30438fec449df904efaf4fd8215e07be98c80bfbb483be8511b3858c9b00000000000000000000000000000000009a9a023a4158adf85f2c7853026d693cfbcf96996da530f90ab890b0225770ced035057cee431ce9f7bd2846b259601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0b08b21b24fdd8b9daa4b0f7dce27c78fb5e6dec6e2aabcf434b7e3943fd51d5574c6e9243c83bbeacc49b61fa54ae00000000000000000000000000000000153b7d3ce0e8b42521d00a5459db91eda13bab60f878eca9a28c5f668b15565f52e897c506a5f238591dec9fa99839d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128d189c8e3d41cabbc68fcf83bf58f6665ad836719d52d21e7499e7b121c3202c5236ea2a87091ee7e85b1f14a680b900000000000000000000000000000000125543ca2fc4a954f6be6dca42ef87aa96f1a07793bdc1404369945c6dba1a5b163e01d8638e14b913542060cb5369a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001790e335b2283dc7f9390347fa45f97da6c790d1f7024a39def5d709925c2ffe67bec7568ea5b850bc72cc091ad2956a00000000000000000000000000000000136e7bd1b776cb436994079c0cd4e70ab5b01b78282b423762116f19b16b0e3cce2551f1e78703b5412c48d156f1dfab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156b21a9811e880b73aab79b491ca78fdf34a6b8cf11729caf9925e164fa880e582f563aebdf7511924f545e8e2be4f700000000000000000000000000000000157a8af9960d525e718bf4cbf815f760db51bcf9256060718d5b6664cc436e1d5c2f640903696d8b5556a6bb8da4f7d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4e274d226fe6511adb8ff4019ec904adc75fe70c4d54863f30188a7fa1ee7990b22bd39a8d6e608859d7e68f173d8f0000000000000000000000000000000007126497247e941d46d9634abfa9e211b390867a8577b28a1e475f4977d5fc5aef73be339186f65654c06baac1e895df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c3a0f8b2dc7ee0a045b4fd6b5bf58f89166417211221a064555bf94b5cc95c41614e3671e3c0415d3eef6eb5a4fd3000000000000000000000000000000000081586cabde74252e5a0d6b057e28d4a2915c8106fe31a38c96643573de8429865123b627246916d0b3bce5b44eb6b241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d09404447121503c1270ba6a8e9563ab0f4b4edde0b6792269985e357523a5932b584ce2b38b388fa8dfe9de6dc6e8b000000000000000000000000000000000d469afa64d6b74214eb6af0a35fc73954e8127129dee1bd8a1c5072db1165a26f8a50f91e0216e0e0292edba49ac59f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d59a79ff88bae650cd40ad984f8048ae1b1488dfbb8ddbfe1966c9690ace1369f3ccef09b14de5f3825f12758cab98b0000000000000000000000000000000012d336b5f0fcbc3eb7bfae5ebd5d69fce58e335ae26ec81c99764dba4262fdfa7b53e1d5d55996deaa1618d240497d6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140021d531ce1194b801b2e92e9ec096f74769062643120eb65d031cb38b13b28b5f55c73ab794e75f4cac61e84dc54000000000000000000000000000000000ad74fa287d5af2c2467dd101ca5b0b69e09988682f424e6e089e1ff65c68ba651da7a7291f180192e6bfe453e12c9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e9d72847c0ce6c6a9d70eca36048004dbe0ab579d37431cba92f3a53b4e2c830aabc3ae431839721881f140f40a81500000000000000000000000000000000078413deae4ffaa019fc1be05a9a104d5a7c1384f6d64b59bac69abc22e5f7641644a40e834a4b9644000dcd50f696cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e80723b788640da8190c5540e3ab68e107e37791be78d4b0fd79cf41b523de8c0094337c09f02a0b9e46a628d45b300000000000000000000000000000000013104f5470f6de2b0a6fcd1155a89448337a06f00497c3e2f9a2747e976ef7f5deebddfd03191ace9e5c728aa498a9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013231f3e1a15cb8897eefd942ce289c23f8a1aecf5361e7317b0758d673c9adab6dc7b1751ba455a8be1347698681ef000000000000000000000000000000000c9d9e3a2f8b93e677e12e13750672ece721e2f359c20d161b3703655180113e73d9092882d06d31c1a1b5d1d6a81f951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006783c20da9158a57065c6e050b8fcd9b6995e73cf4800ce1ec811b8812ec5b7296b5e2f728dc239454e0aea8e9993e50000000000000000000000000000000010e8312d7fdd9119e955e68c59961c3b932a94db432b78922898473cc5a26b914260e000856072f777e49a5247839c1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005efccfa80f98d4504f8c72a18eaf33aca8df5117c5513cf62a23f29fd6071842f2a07cc1b17c86504410e34b8d9109d000000000000000000000000000000000080be0dc25c315824bf4bf22243735f2ac0579699a43bbd7aaf6e558ca889ea99278abf26d360f633ea1ea2c03f090b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a939826e4af9d5aae5158c66b3566d24adc76ff27333c1d9937d599211320df9035b83df6c5073d47669611ca4140000000000000000000000000000000019d57b703c532d26a6e8631017cfd183063dc77ec67cee1f26a13025ab23926ad0c913acf5932af05a42f667eeae53ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965c90b66d7ee3c9fac25501d7e208c2c9a98c95daeda52c65e4b3b0ee832a4a807a88118e0f773b7fffa663679d3960000000000000000000000000000000007c9a4ae934d1dd89dbf4e05bd9ec4172984ac3355c926024a240bd5e08d9e423b7a1eb7339a1db263cfaaa4d1cf09dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c5f40066629ec55cd7244c651ddd161efd549da7171b7cca06e6002e613bf723b0eec2727165d4abc33a3d9ef2f34000000000000000000000000000000000135b50049d03d04215ccdd904fb9b41f7849f451f7a049bf02920311f1887b5e0aa0f5517d295d9ff2386a263bd010091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005691cea3e9f22b69389d7da82a897b5521269f30cbf0721b38809739b513c0b3738aa5f137d588ec10f870e6dcdc55c0000000000000000000000000000000009f1ebad8c281ac9d403c81160a8830329d7859e159bd5389c925abd78e2a155d263f530d836855304674e47bc0907241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eefacd7ef50eab87d65d99b6a977fc0e1a269a9a41e5d849bc129f4f6f200fa6153aca4ee3bd0c075e619a9dc302b10000000000000000000000000000000011e618ff8ee5efc5cddcc51615960fe38b898ef0fad0e62f51cf41deefb4ed0212f4f194cd5f4fd1640871b1e327071a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e98f75b39919e90e740178101df956ce1967ff86f7f6e4a1d4c22ce289bc096327e5840a02328ecb1f886f09bb8bb0e000000000000000000000000000000000aa01cfa40683b45a5676e986803b98805aeb8e35a10da72fd6a6687a54b37ac1987cd24865db979ee8175fb59d7bee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037496e21899a743491622e4b70ec76d12248dd1956ce339e130d3ae1e60e773fb87b45ec139e8fc31a9da4c91de94d2000000000000000000000000000000000a11b261a77edd34096736f9ec19f77df3953a1e8224f47468affcbbbfa9e32463b12dfaf5d02171f2fd09306d694ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000871d54bfabc3a68a7dacdd1078443ea1250051f97f2b6ecccae51e6b9c21ff9e432f891c82ef18b7e4185ed77c4a6ab000000000000000000000000000000001389f53beff07ff56230755f8d69a95499ee496f14bc098c092e57b279f9654e418d3b9064c5ba0b23043a8bc01691441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c5e72d55ea16eeadf77a9c8ef3bf326c49824068a17971fc721de8e461a1b2d5515eadc3d82873607988cfd6292136000000000000000000000000000000000c59e84aacf343a067c606a318f7ce1d89cc6039e7d3ebc4dcff57d6e385e45cb1311261287af430c7bb39fe1475d3fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d38637200ba9061ed86eca6642de7807baeebd01fc47c7a0bca687e54550832dfdcbb4fb036a3d8a338654730335c3200000000000000000000000000000000116a156ef8c67349b1654e8a4ca8f07165c220069d2be24a99c936e2f2e1b8580eed61965f76220b6a4ba2de9c2d1f4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8a5ff2a4138da85f557a260c20d1783b9dc9df5d047e8c03e01f9541a7e8922f20e94fb9e057c930c80d8c5a4ae700000000000000000000000000000000017f5f3492f2d8f76df0e7894689f1d04e29d1326f937040691587cd3c4a879c17c89ff1de6d6598d4a064b1a5e7fab551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008241e53fb868b922bbe91c29327e55735c80aed846f5bb497f79e5eaa40ea3c0d96b2832c27a6a67e3e31b9953b7bb60000000000000000000000000000000005a5aff72ae801a006b4deafc7b7c3563aa761a82c4510e63e00c3a7f3826fbae62349b040594b34f1871487b9dc02ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018acacf8a679dd25e18112e2276d45a76563f8f639a175652d755970f330f131260b0664b4e93b858b1ae415d8e7db98000000000000000000000000000000000275b055bf52e4fd1d48496f631765c3ca8be9b3c304bf579c610e2ae2da0c36bb512053eece513337d7031faa54e5cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001710359d31a61efb50f0b8776e3b961cc814e9a5388efdc4d9059a5daa11114effb2691d07aefd4e63ae65f4695173bc000000000000000000000000000000001892a5512f20016b3c755c01649165ec51a9d81d531a77402168954dac97db63bb125d64df28090cb2efd7a27473a5e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a2366558b7801a81b266c98b6b87b80dea8a0a3d342a235dfcc834a19fef5bc68ec5756f16fbebaafbc20fe4c688ad000000000000000000000000000000001886106d5f07003e8dadb94c192d04aab73ec195d417a3ab43d4e40de1598713626c810af15291aed05c149793ca16621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ade2d487c0c9e4b07a11758949c757b0e5204591deb64d68380de87ca23aa47536cc9353bc40ed44a9bfe2f1f8c8d6c0000000000000000000000000000000002e437138d8d0a24dcbf03e83d11fc8182fbdc6a156811c4d5e8bbaae4360f0a6c66d97cb446c3147bd764cbf3b2fd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a20d28b9e2591590643e4af33ff5a8fb2398b06b6d2e399d8e9a1b33d01e774e58cb376645d488d3e0b5f2e4b14e284000000000000000000000000000000000b2a576c1b862d7c72f7843fd5baa0f91ceabf0f37f956916577da5af4b791dc63bf0f540121b24ca03e1284a727e8ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000063ba4963b8b4ff3e5433c1cdb7f808e2355d583083673ff57cfe69a01464f69a71f15f20ca91e0806fc20ad598b4290000000000000000000000000000000012b54ce9cd92bd323242cde713b1af174454ca050e53c3c0de7601d9b2bed9561997090ae8c7248df715afa8bf5d4c781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec68b7520fb8a8f40f1d0a7f6c07c61c26384f9be89f076375e8b3b04e7260a6cffdfccff13b3580b9073af55976d580000000000000000000000000000000012ee742d37da2e1245b48da1a9a88863c1567deb7cc5b70c4792babb6d0d008366710285b1f8e52b6ab051e4b08368b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097bc511f5e59b189cfb0d67db04c10a083d329ad5c2a5a30c967a633ed4234ad25060ab5dbd658d81500a5164f1ae5f00000000000000000000000000000000129316409f017c8f0dae8105131630022495b240466181d623aa97e2cbdc8494da109c8da8def3deb4c5540728dcf7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003799118586c551a0c6e00b2d92d9b860b69a02366d843b6c636afe3bdf589b2dadca20646de3711075e80e46b881ccf000000000000000000000000000000000bbc5c8268adea4af4ff5dbc73d5653a0748568e8faf4b48ddaf2bce55ed421fd433b6beb2f2841e0fd33ce97bfe4cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f030d731cf794b3924a287cb9718f3ea9fb7702aa0b2cea6e1fbf143efb68c8b1ce144a595e542c6cf9434fcf5a806b0000000000000000000000000000000003b744bbc210a41a25ea33fb704646d4f1260634667ecba3a0994f9ba9622973e304849a4ee08b6f3fc3988b68b335831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b48d835c83c64efe538847ee6a8ece0df7ea033cc12ac22eae517225db2fc16211a9a1b91e5eb89a11d149ae1a00580000000000000000000000000000000018e2131acbb6ddef2a05e51c2f3c65e56bcce1579c7d745b1d6a9ed5d68498982de9a911f76e42ec12f0e1749e1411ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec072b45f593e294a4798ec52e6b5e0d225cef122b4d80ca5a9b953f123c9e6037eee9ee69cce336e89d6933a4b24f00000000000000000000000000000000166cf2de8807d46a063e7fa21141039a5d2ce8a8593b98797251f997c5e984a78d6c87194c040d8dec23729c01865df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fec7579e550d261d3b4be761a3696edf45daf70debcb0d19cfea6f85f54e6da8afb5027af634d5ab809876ac4bd1e80000000000000000000000000000000009b7fdee5e162620699ed6892f0e2c472385418fbfeeed4ed24a5d590f62d334f44939a7a61368e88d810c990c6bcc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001890fc4f1ded9c6082f83d68bd79e12610ac05212942a4cf14827e6f366bfd52067ccd7e00425341eca0296e96305ff30000000000000000000000000000000006b519d626323b9e2828d438acc0c0a51e451694719539bed5b2d1297e4592535073480ee0bae7cf594e430208484c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562186d9227bee2748a4387e8fe395cf429e399c45a89412791ee4d3aa840fa166731c4191b86dab5b79cfa669e9cff000000000000000000000000000000000f643cd18384070f442e134b2aefc5f8d29c4c3f8b677ada25dccaabcf8eea58ee012aef5341f0d4023461dc33e3cc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ad86a50a3c13d0c87ce5ec8747f9b3e286c8097df229e4ab6f56e1ea34a11da78d3f54c3e308e439490fa083682ed00000000000000000000000000000000001edfcabd8785201013cbcb9ed9abf9fe2f3fcd0ac3c890a9f2174a8dfee16a7db6b17a94803a31a806d5b8e8291427f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114e0e0e85f47700059bccdeffea30dd3f9ac0dcf73e63850dff71ca101a8ceee8893b405fe381782c83322350b070e1000000000000000000000000000000000873fbaf0478915a5bed38cc1ef0977b78a3c269ea7959752cc436a291eec7332716f15ba24d415c3b230b7c489cb5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d25987d38eead40474303d121b659013a1eec84c5b653ba1725e6aa73394b39625ec687a730a0e0328388cf3b79eaa0000000000000000000000000000000002c46e8944c6262db393a81c27c3d970188d132c8d6ba38a6a5e1679b8cbad3d6282afe27eddca8d007914d651230b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005496f1aeb84f693abe7282d3da1566cd066c33b77d662aeda7065dc75c2d3dab6a9be18efb700b37e8d315e53383b5d0000000000000000000000000000000002d664a80eec5a20f81aad8bb791f44f1ca6cb608a1fb24201dd029c4cf45f3e6ed3df7bdcc123b7037dfec3d93d4a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0e6ff47b4b2bc6fc531a3ce06852fb0b1a2d43f6e816ae157b9de3a3e758fa9bfd219f063fd42f989fa17ab674beea000000000000000000000000000000000fc3e4b0e6748058b658b299737994aa0591c056c506b79f57e03b4749efa339565079ecc1ba2304b009a3d1a7330d171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89d70dce1e67bc0550db3715b4bd96dcb23b1971a5d7c28b1e67b0a176b60ed3b66b51bc3e495f36dfe8077d0b81950000000000000000000000000000000005144a6407b4566cdba7d5c0a8388a075fee80aeb2aeaead3f18f6229f4f15c0d40fadc139bf9c10e57583312126dbf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0637f614823c1489d6a6800c8ba382032e7ce7619aeceb255c38d83e51e1b07c51c307449924f32c5f4b7137c1dfb000000000000000000000000000000000cf4667098146807e27b953182868656afb0b928eb8042ec1225a9c090604a0aa73e4ea6c918999c18c25112bd746b641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001326f14057519c003a057f2af6b62b5611ff40467e5b7f78f815773b07293425ac2f55135bb836b5872349fdf3e7f8af000000000000000000000000000000000e03225b11009eea69dfc5f53f4e91d1a6a9bed701193c92f30febe00094bcab3dff1cc277d06088bc2409a9c27545b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b48d9e9538a06728503f412cc9517b1c76680bacf85c4f4a3499b2501ef585a13d027763770c8ec3ae8716e5cb998f00000000000000000000000000000000187393ebc3f88a503d262f78e910fcf8406572c942016b223b35459cd6f1d6427ebecc717d05fead70d311727fd583ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f8dbbea33095f2447eb9371dcaf8716d2be70ea7ddc9f9bc92719e561f8d3d938a8463134cc751607ce68fa4401a2c00000000000000000000000000000000093e67f737dfe24634a7c423edb5aa167095c99a55c061d2cff6b8e8d7896725aba38f8ef71e878bca06cd249913d9e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000822c8d44a86113ba2fb36b8064596e4d5816bc340aa26fe414ecc92265f5ee468b4a62aa565cd4c94d4007eef7a920000000000000000000000000000000000154483f0a4a2cdce89b62893d26ab5fc2ce1c26a24382a78693a56f9a2024d24d1d4d41ad79e9fb69793bd8f9892ed1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed31c0fcf97549a278dfe6e8cf7b00a004f1a75eda46a5cf474faf031c27ddb57fb6299f3c2cff486069c580d45008c000000000000000000000000000000000ee36011b11236e4f7df627c737271cec1d624df0727e94517066298507a28bb7a5a8f8e56138cac8ae2b57a21aed3631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d9a1ec9a5ae3c60efe24e4210444e44d0720e9d39bf47c2ead437a9b533f7432c65308bfa48a74f0faa205e33a05f0000000000000000000000000000000009beda6d3be4b5755b3db0f931a735b60590b888cbdd69755995cd70ac5967dcf976e79192de88fda15394948279dced1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000737bccbd79e54f428cc33e9302e8ee2911dfd23793329017e00e4b9cc303673b67c82f22150b009ddb660fac8372bd900000000000000000000000000000000133e556c646fed5c7c63e07fb0badedfdf988aed7e32cc59a9a5e5de85ac0a82f1dc6bb94f4b8ebfa476fe06084a54ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189a4ef3635ca9b40203257450d4e3050de4f9bfdf9f9b859c936e140f27ca512afc052eabed06b179536689aba8b1700000000000000000000000000000000006fe52018815fcc71c6d236e912f6205daf613002312a086fdfe602c97f450cde5b105cb7190f305c2f316c6bdb254481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113106d1b744936b2c1c5419ecf403a1937d77f3e92b6a72d70c04a62e1e7b0283cfd736799e6e93bfbd485009cc7e19000000000000000000000000000000000c30ad2eb9bb1ce949e56982eede0c5013d668d0e32d36a261a476cf03ed6c2aa5b5168f5574bbd7c52b5749aa31c4941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7411ed9769e37b6f7e6c2c767f9d1fb80d9bef6eb50f9ade585b3bffd926df755cb32e33f26b1eb9812654ac1e82ad000000000000000000000000000000000c58b3d5434b6dba29a329b6cf2b6355063d6d853b13a0156ce75e376841dcc160cfd44da4535b254ae8eeecaba329c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086945700398cee1a149c68f29783b9a45781b2f972723639ddcb3fd85537931e3996a168a0bc4aec074b0665736eac1000000000000000000000000000000000639db2981af84e101e11919568cf017cacf5004a8e49f864265a045cc05e4023725c83cb1227da791506051565d56221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f8ef889b32607b7a0a5fb2e950129cf44f757afba8924996f5a5421f850a2315f4948f6b5bf1fbc9b0675af2b076a30000000000000000000000000000000012a6a2271f57735b78839b58545a90b1388a2e84d37c29538044ed9e1f93e012aa8b6f940ee2231a0534441f9e7488601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d1305dfd5e573cec3e35850ce79b29dfb8c296584cfd794436fef1d9d02c67bf444590895903350ef737a4b28e035000000000000000000000000000000001408da122aa028cc5708d326633a31d2c5b1e0150fda07c90ddf441eaaf75c39b5fdf8d52493f7c3d495d18f9fdf73df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c00881f2f0c37d7d5b9d97bc29035d2c9ae7252f81c8f1e8f571c4f768234a1558a375682591a5e2cda484db2831e7c000000000000000000000000000000001165c8536171d0ed7658bb6f21fa17a5c75d6d1bd934f6a112a47091ca1df7712bab41e83f8dd6397fd31080692e99f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881f7c17358d61058fe7b4a7337f27562ed490d0f3f89aab44c55cc61435e7c2880432717c6fe7fe913da02cbfd6a7800000000000000000000000000000000093eb98e9299a3195908e0a0fd0e2794e0bc11bfc94d7ad95624b9c9a7fa31b1846bf955f60dd7d1ea2ee41d63b534ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ad014d7709684ffc29e93f3024963a046c227ae36b348698be8ae6333dea5dd212e564fc7be75225f28f7e3020949f0000000000000000000000000000000007831910f16875f741fb3ecce0cb73834fb1ba8468483a0cd862605161210ee7d1f2e4fbd3d55e07c27f63a6c357f6bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b42b6f353e108aa38c26cb6387f7010c6c1eca17b03d2595fc900c4fc083905b7aaa8481027bd97edc016a850d703b00000000000000000000000000000000128d963119740811beeb3984a8f37d2c8a1dcdaff4e3367366e4318974b9e04e4a47cf13ad709e4eb31f19b2affecdd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ba16c76a01932a245ac21bfbcf7947183ec9edf25101bf2f7a6034ee26ddc95a0e5e398ddd3c9be2977571027b74a200000000000000000000000000000000092917851d092c5dbf050015ed451b93cc4f45fc7d5dad2fb27062b54d87422db24ee55e8a91c7e2653a1db823fc64531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165ae81d0c813d9f980aa37ba48a546513fabe1c9e0a38ba7160792e0c8a2588e0ceec56cb2722bc7a8d38d934e41d410000000000000000000000000000000013cbc86094719af6353cb42d51cbb12e5db4b74015acd5dbdc2fdf9f136bef91de539fc45412f1f50b7d16228ca47de91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000514243edb723a05d62658224021db9747d0f41c5cff6234a5ccd6b8bdb7747edecc6375a38e71038afa210bebd43d110000000000000000000000000000000018d0679c806b10e1427662ae2c1a05208ead185b9c351a243130b71a97805134b7cadb2d38e68c4c6aca30558d02a3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023b8f03b05600cbc38d574e59f89be8cb2b442be4780d7695fbf9f5544fb67d941931a25ab5cf825775b2ca412538380000000000000000000000000000000000f508374d9e6f510f3cc842e351486ba04937d0a8223bd772aa9cb686b18890917b6051c9bffd46344645126a77e1db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007612670c7b184732b5e555b1955919f266840b2ce7940354cf4bf25677936905f4e3d341dde46cead1b0e9e48ffb7b90000000000000000000000000000000006f7bcb2a5147425619593db4ab9eb37ac2683980f5a61abd8fcc8d5135dc41d4efad0b8db09b049422b151747425dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dbd1ba66474cf97951603d7c29ff65aec7cc91513d6b0deb2c1d21e3aa5eac68a3a4f7d1c04bc7343fb39227646439000000000000000000000000000000000a9306b6ba9c819448f6a216b4a0d7f7aadbddc9536dfbdf126e31fc15803b2071f9441773e4bca9068e43a51fd4e92d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b0bbfb0f66cca3fe522b7bd8cb13b6eaafdeb2d303d71d44376837005150bc38f8bb7acd24a71af894ca6b862168bc0000000000000000000000000000000019c3294f6b392356e209320916746169bfcb1a992696977ddd54485a5c5d69d099aa878b0ac3fb2c036a24149677b8081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b74bbb45abe85742ac9b59b490d90472ba2aef53da18489758fbd3bf9b692f2e9216189f4790856b60d3c439e4176a0000000000000000000000000000000005e7e0c7d7422cac5c7a2a4a2a7d2497c438bd41cf07e051ed947464528c3900e6c038f57d2ecc4f4b193a8a52bcb31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b0aceca4515b4179a5c500528ff0608843d03a8aeac9c694cafcd2af89c18249a55ee1ea3b9d17fa0c7ddbc4500580000000000000000000000000000000001985e44abef01215d87404499f69034cd0d4241534c2b4ba0ab9d85bd45813b204528bcfc0b1df3307c1a6f77ca43701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c38720522cd0eff260157a0ecaaacd6adbf8963b651a6bed9bd10a4f2bd67dc665cfcdecbb7ed7a28ac3b4a191f29d40000000000000000000000000000000014063ebcc0b1107c84ffe395b6204f4e14203061d018564d14978bde203b3daf709e72b144325035ca53a4747375daaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000912de492afc46f39bbea9b8521e76eaa0acd44713927722b9f1922461a3e2635fe77c6e4a945c3cd4889319b7210427000000000000000000000000000000000e356e23eca6d1a9e40e4a813f5cb0c5d8ee35c6c8b01d90a909aa9b07c486db3b4929bbbf0c37a20fcc899cbb4d8e0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d173b148a20902950cb15306838be3abffb036397ae9d638d7e2f6f9d15dd03d814cd328ae14bbebd51e8322348ad20000000000000000000000000000000002749a17d89aeb4eeef05b850a2b9079cfbbd02a9ab631ddc4ed6b448eb620f79b77e7376ab450c63883afbd90c57f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce42e1a1636f2d723e79a5fcb3fba5eb9d27dea103f301f27375feaf3e858110a80cdca4291631a48b68222bf9812d0000000000000000000000000000000014495a155aed9851ccc87ead597a6f530c5f45f888ac9e87da5a613cfd0f300b2668e3f69ad796b1c419588c71161bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001620fa048f8fa229fc9cf71d2ae900d9073a4ab057e14e2225fe617712827a63da030990e4dd251cde5696156bd66c8c000000000000000000000000000000000e7ffb778f2f31d25f8b882bbfeb5b7b471b47295aaa2b5a6bd0bd1370479a5b4bba517da37f3e2c7e5d6e60e56cd74f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed32d715acbd6c502af3fd49f965bedc936bf238abb36644c9ae320434071049cea4b8993947c4dad5a5ab37c39f5fe000000000000000000000000000000000376041cc9c915f529e22c07a619abfeb540345057338130f358c5eff4d00183873e5ee820801410c18ab1bc7cb86fa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a6ac2f81a2fdb8382915ab0b72d01a51c14b5a3f6d4baf56ae1885ab574d4533d4f6028052d224a9625a9916ebd8f1000000000000000000000000000000000a0da16cef13799b7b7470a804a1f877b611545936f2a84a9f2115dd255e10dac549721ae425d257e703f083c02647b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f3e4d957f871f3b03a3164cbf36cd62e4e550a56190794714fadd0507106271b43bb74a80927c4604de7a372c44801000000000000000000000000000000000290e1dfb5ac3a6f9fa7c3b5e83ea9fba12108a1c559dab1caeedb9ab15bf56c966b4f0bf7d27d6a6aaddc69ccbd9fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd55867ad63cfc4fcd38d2d98f59e5155724292154430146c407da6ffefcc48b922edc30b5759b12b426d45d8b766d0000000000000000000000000000000002d7bf93ca5ac9e708671baccdce4110e8754d94de1e69e32c8f45655e06b4c34be76fb5008ea408d7c41a808e6403ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001178cfdbffc0f910f39b81b8d7a4e371aa8745ae1ae74053d13aa90f94e82f56efee051fb7054c0bed1a78fd93df08910000000000000000000000000000000016a6f5cd4c859c5176c755991f88aaf8d603559419c621c2e25c75c24a478d074be283778d735129d1d60ff4e7146c1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001551be4464ef1aefe6fecce96de12199d777b8c1829f7f50241d1f88eca44ecb9c719b7aa93a2b4790721bd29d71291f0000000000000000000000000000000000d2c8c7088d19c834214ee8dd27e013f690a32c1b476eef98806ed56a2cb5d79c532b18ee3957ed753330768451b3cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef5376c93d82a2957723d1c0fddc8694a56ab0df0d9ca639616c03a80626a49ddba023226327222cb6e310f37718d8d00000000000000000000000000000000148d96e2d367eed19b0a93e3ffaf92885076ab5908555b18b785ccc2ad725a2743ab546a4f4d4bef365500e2cf5f249b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c13ef8aa7fb353de6f965c5c637f055803453a062d8def3f77a48d09bcb4c72c2e28a7d3c439a9775a7cc7a57e8de000000000000000000000000000000000123bd915e5499074f5a05f283985333597558f8c0c5549a51015a9b31f4988802b91279c8794490c56699e3ebe4a67b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056389ba2dcc052fb3981f6932c80c7a2482ae51a590fb0bd8550a4fd50815bc6495c2ad7d52957090d08d3c79c78de0000000000000000000000000000000002a95367f919b91939e236c5d11904e344bd4213aa5533c79c92ab51955a5e6bf7a76556f489c09b57d39dec3f8b5c4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d339263b3b1afc5edbab744ef1a0f981905621d0bf3db71284fce5e5672a7565f1af6c5f62599156e3cfde3b506957000000000000000000000000000000000dfc8243a7ad96b04f7ba3a2220803eceb989703769360495157d61fe744f2339ff9e3328e669aa1b0eb7f76ff8e26fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190544712535736edb6cc0b4949b5d0a040ebbb851dc26bcdf02e442497c066996d90e34bfebf3fd55826c5bb02df2840000000000000000000000000000000017c0b4ab5f48f2d0b26f5d49532154a2338d235e34811098ee59c1d663d03fd4f97b4b7c353f0f6d386ebadbbe14fbb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007eadcd08a64752fe88f38b50286d1a4b00d7474a3f00a9e646b48b03d850dd49709d4aeb0d0b314bfbd955def7864230000000000000000000000000000000001b78342d9747aa1349443842a9e7a05742b8a5aa3caa35ab38d4710e21f2db47573ed8c7a66a97e84ade9c6210825431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000901c6f7304ddb31a289e9825a572df60711b59b6095ca13cf912f8d2bd3c76956949723066e8f797f24d9959c1e961400000000000000000000000000000000023daa1adb601db783560b8711ba364e4af6348a41e0829629b9e7ff38d36c727740c7bb70bf3a8d3acb65be4a658ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a4dc18958fd0252a6d7ef4562cc4a2fc724b86f971ce22f134c6d70fb175bd7a397be822bf72b2e47d1e63d880ca2c000000000000000000000000000000001820f614dea92dd500e8bf7a4dacfd6254231c53967dbb9be5ba306a0e06d5643219ebf20497ec4a073566d5b1237ed31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001184ebd10132286a157be5d6edaaacc780a355a2a5d23ffb3de2960d064f0150787131e1e54bc4a25c40ff10cb33af88000000000000000000000000000000000c8afaa3648f31568479e5366d5c9d08333ca7f58c7b6da08d5c66c4e24c6e3d569f0dd7115231b34225cac0212cbaf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167a43a6757e0ef11c981f52096a22834e70c2bc0fbf3cabcb60f2e73a0f623edff59992d9b6d4521c27787d77baeb820000000000000000000000000000000006de6b5c5b39b4d1e6d0b02ae5561d248cfcefc97b1e70422729c8b9f09a9b383a234dbb984e511efadebe8f6a0caa341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5450e01fe52fdbe84abde2037fdd37da6ae24ea0b117de72845fa06c23caa7dde9c6996e0e935d2115ea19cfdac88000000000000000000000000000000000ac77830b0150483e9093918ab2f054496aa1e59cbd0c122674d14ea8861c385d85271cd30aa3143b756b44b2d2d0bca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040384bd2e85f83acdae5673a5aede3bcae41230d81f3377c0b6a5a357d4a053e890146459fcc55c055e1edbf3e80b88000000000000000000000000000000000595ffba244438208ded3b0667478a41bed268accbfda6cf04b6deda97f96204219131a8b75e46a9fdfa3c4855a280001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89ae4b50700faca55387043804ced7c60e582f90de771cf8eeb252ed4e2eb56473c57555e59101d4d5b8e6190a468a00000000000000000000000000000000073c62e0851c6f836c08f5e5663bcc7acad0aac4f822fb65af12e15ca40b1ade50e5a782b392bdb7b0ba14aef04a1ace1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063397d2890e58ba3f027f418a3d9de26fcba11d61042a0135b394920bc45e60d28bc1d71984d6977e3f497e0a7415d100000000000000000000000000000000166cfa88133d62d4e93760c2b0355b223027592b71d58d286bfbc9b09452781ab8034d4e27faef27134911145550f26d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cece3f42d5d9b5192a6c2247c3c401e8d69eec654d7700bcc0dec3409fae81f3400d7be1c511c19ce739c14df5cec7c000000000000000000000000000000001070988ffa4e696fca398ecd816249af16ea7d9c4c8228ae3899166bf36b4cf7e6437fe5277adbb332d1711484c31fff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8963aeeb9b2dc735f707bafafbfd8448d143f8bba378b4c088f76e90781a1321cce4edc2d73b220383da93a6e258130000000000000000000000000000000007a00f81b0430873dfeb6a0350369d9bd74d0bfe32f8dbd5a23759a69d1f58d9ccbdc41275ec5b4ce7eef69b6f0c9b841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a22a6f85805d009a40059bf5b921dfc67cab1c455b0a68846e4836f4f61f48ee34bb7bdc4b6d8ae2bda494d9078efba00000000000000000000000000000000032e577c7f801d8e8316debfeb6b195af1e9e08871c10d2dadf9b3707af45e1fee9dafdaab4691f9bc99733c477792891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfeb714c46489fb9c79258e550878385335ea7324e48f9ed749bac3a515d50ba10b09727cc9683d964bea71f431ca10000000000000000000000000000000012d824f815a59ed78a0446fb8cfb7e615b448f04360c2b5261d4b24474d5e48918e8ddd37bdb2ee5badc996354cdc12a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001590051121a084934fd381067b262aada5d688ef11b3f97ec10cb62b46276689ce5937f80d1967f49012ce460ec73e0000000000000000000000000000000001787d06c7c9891c33ac0555d5f94dc90841bfa2df0e51872508967403754ee9d8ef97f2329f44ddd805cfed6597a31fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076f60f8215319c32126977772c73b459b6fafb5990ea1c49a4e2eefff2286841f20d2c93c63375b4b6aeca7baca55860000000000000000000000000000000011225564e25ef8b98e777a53969888ba139d466a8c3dd4765c6051a0a6e8b3f33b91e08e58bcc5a10ec694768e5103641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4b06e631dcfe3aedf1299c55927d9b0486611b690fdad15dd76afdb9a4f147a7673853703ffd66cf879750935917c00000000000000000000000000000000120cbb99ad9852c5db18c86b3701435c3cc8189510ad6c443d3562a85d1f794521f3685e1139dd58e82ad75dd95598491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138bc109ff2d31ccea8d556a56078062d0f7542e46cad7836867a73a46e973c3a45b57479cbbdf3d4fe61eace6076edc000000000000000000000000000000000e781d7918c80d927455bc30ada70389852423942acf73557b3128b8b6c384819192a5bba7cc3f6af95c5ec575c695f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015751eed718b395dcec1381a25ffe31c3db047b6fd85f92243ea4fd7e7795cde56998c0185d59e70f12081c9f3150e5b000000000000000000000000000000000784740fb59bc5074211c77d1cd104ff5267d2c955096fb8d46efdb62cdf5b0b10bee599656368cdac54162b9899e20b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047183098acbe57eed0f77996e222554393a6b4d05b40035985285f128147edc60b28f5fe43c42a4b602324a2bcf537e000000000000000000000000000000000dd79051e293357664fa484d061ba18b57fa1466754fd019ba624a2211746bf3e9e5f1d4250a313c524d3669dcd1635f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1d6e24c1a368b8fe64243d9dd2a3c8bcfbafd84d0fa0afcee3cb7db4632f10ee324c9b3cc298d3b584666bccf5b63000000000000000000000000000000001162b287823cc1cf18561935b20def124e91310b43931a9a5f7354c2cc0c584dcbbcdbe616245fd28f6680a0a32a859f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018619b644da88b7fe3adf1902229fe374b0a78a82649500bf89f4a1f8e77d7049d076e9db19e5fddf25455fd861c0a240000000000000000000000000000000014260648fca46f0b21c523526e590f1e05925b69a6d0583e27e230893f80c0aba8d08aa4936ee616a7f5f607f752fcf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a68e5a4b5944cf8b57e441c0c0b42966084f2d7c580c58dcb1790b55ab76c8260ddcc21a9929de904b4a1883979db7000000000000000000000000000000000e9d95f1bc27128670ac591b3454197e0e65800ae1700464fc53a750d013402da050c5d85c148dc9b9b0e9ce7c76f93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d15b66a81a58665b132b448a3dbfc40c450b0d30b318c920e40d757aa24933b8a1c2d2dbdc66e91feb08d292d717ee200000000000000000000000000000000025602cbc28f4d682fe33df506c6f1a7b07c02b26c543837a9c76d1b8ad4535d5292202d5fcc391dc88fc58cb0776ba31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d49fd5387d746d9f97b8ac32638c5179956494c6043c6b269e82ff89764b4db9c0102db192429836f41a16c45e91e000000000000000000000000000000000ab4c731c155293b9380774ff5d83b95b294f3c9e078d0010eac0c96185dd3d25c4c4897117523976cd673df20be216e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a3b8933c08ff3d92593c9fec9430d6844910f1e04ef2c583c528fcb4afd9c6939411f20a621605eb6dfdf20d9426160000000000000000000000000000000014ffce1452814a7fc518ce9fe9ac16cfa43d7d4cac20e96da514cdf9bf4427b21cdc736efa2e1ed296e4fd28c4a4a7fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c85c900edf01ed86648b997785e02375118d9ddb5ad69f1dde7c3f4290707d36b17d94446fd423c1d5e7518ec61b130000000000000000000000000000000013ef4eefe9d16dd222e87e96047c2ebdd8e74d3a1e84c04252deb00c8abf1b6d73d7db6c8060ac976064a6d325ce17311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb495cf841bff7682a9df9f0df58a20f1737fce178968c39e8406fa7e758cc594be4f65adf1e6a466c17cfd53d118a400000000000000000000000000000000076dcbf885f54cd8464f5c6dc5c0cd454293c5d988c2b249b5d50c028ed86f4210df769bc9a4654fd258a04c3a0db97b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015c32741acb5a8c46f943e1b87e4bc76abad655b96ec4f4f39a6ea9741b7fc4b73bff8bddf6c45ef1e0f2ae8c3b2ec2000000000000000000000000000000000c3da142c2475c315bdd08452ca3a72f3642f60f76a6fb51ae28e0e6b2fd10b14cf365641be5a019c5e5b5bd80d39e6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4d8898762da5595849e6e245ec7eb391680eb3ad1f42ed4901aea988b3051f5be7d091491362fdb84d3980bca857e700000000000000000000000000000000034ebc46e7ab5a726ee467348fc2692232af80541b689656be2584a74c5698dc2b06e5e7c436fcbaf1a72d2ad0a9f8711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a4b21b49bbdf6a4ef12acd8da1dec1a02328ae127ff9faa98fef345f3fb97f4532b2ed887e6e0c2e946f051730d215000000000000000000000000000000000bf8a19b9d187b5bd720b6b5b23d0c675f99ec78065eb5fb1f825a45e1f66508ce1046f14af425a61796581cff3c1f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654f08932b433d62defe726eb40561dde98e4b127e50993ece5a26d9de2c9e5a1dbe6bbf2cab4ee47eff59242f690590000000000000000000000000000000015ed8ae18c9985f79e774cb6a9dd711c0386eee84d4ce22df4e6d8939ae32cceb3eb91549b0eab306b500a6829cbb1fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001545c5f3845940a58e39e9b94eefad0a1214d7e756c88c84af30e2661caecc36a2f755ff30ed1858d93d072c272d3eb6000000000000000000000000000000000a0779ee83cc3d847ec206b18a66b90bb9f6413896bf429ed0d8c28968a9b0a514283f09685e415420cf43bdbd4deb351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9643244e71e4a47d5b2e16486cd664494db959f005c8ba913a12c37b1d3a7499bb9ad15c64ed9d54ad5c9dbae9eaf0000000000000000000000000000000015603459849726db1c69554882a42ddd80ebc3cfc673dcf2e165e319ff3eb4bc97443eac25d69a41eff492432b059a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db49fb3f6f19b70178996fcdabecab437d6592983179fe586ba0cf806c7ca6407f49d4600344ff365516c4907bd3f640000000000000000000000000000000004a7044d7f59f42c7290bee2d2530b4caac4cb1b245329368f77488e3ccdbe1937f1effa3282bbfcc26d01bbb8fff7271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007886adb3c8e5a57e23d513b1f74221f2588e593b6002f5fd149c23931f48daca2093673ff8b2565559e2d8949db2d9d0000000000000000000000000000000003d1241cc955650721bc45517d4397a8f0ed97df4176151dcaee631c18a6db2cb96e126b563fd476f21d433f338bc0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dba7bd1542eda4a6dbc9a949c57add893529bce1930ed07e278259aee91e9d3afbdd963d932b2090d9648ceba1ad3f00000000000000000000000000000000000ed3347ffb0db43885c946d46c496556e423e9c06bdd861e97ddd131e7a4a7af69498774805a52e5ca351fc26587ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4d36e627e86cdcf91a3872382a16860fb09ea1d13a7283ddc45cf71252cdad99e5e61644deb1200d45d29ef7868664000000000000000000000000000000000681e0eaf607a9e9b8e9360ac9b83a0f1aa496286e1f9023b0a9860027288775e5af2fd1bb2fc082cccf25b1ae174b0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cced40381e9df0923d970b023c5b5f4c88dfff7ab2f8cfad283f6a2a171431ef6087cdc177a1e18c23b7d81074abd1000000000000000000000000000000000caa36b1b833457ed29dfbe30db55d97b0b9dc00ad7d0ef94fad9e8d3804d9218ffb29e613215d96a53ea881962805351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185ee6baf1a64785f231ed200a8a811e3a77e7e6f44a4ad2e51ec15800765b36da741ad3d3d8ff342137eb2db066181f000000000000000000000000000000000fd083a364face0b024aa2a865e687b2b38434b4d84294ebd8ed7be97465414346aa2dacc8820e8cfdd67e662c7cc6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e188eee4c8507ed93925af2873660a6c3e0cb8e46227a73f51ff17f5cdbc57c30ba4cae734bba8aecc87f6d858019600000000000000000000000000000000198c77cf793ae6f5ffec95eeecf8541be8b2fc28df71db6e5e7152c5917dad8785159762e746a9fa6a928a4544c3ae401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058869b3aa4c251bf7a1c997f49dfd7a12541d619204eefb7cad59eec103eeadc28e5f7c5f67376e92b3172ea408a17b000000000000000000000000000000000595d941f23147d8d81f1bc163d70b8c9e1609c46efabe5f5b5fb6526befc6201ca66c4897ef523f268776abee349ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014adb7155bee4bfb38b34c3af7860ee2023cd3697c2fd739d4ecb145fe49552132be468e734abd45745f349a42eed12300000000000000000000000000000000078e1e05c38e6141da8a4ceace4bcf3cfad21813823b86b479ba547fa8120832bd2b909f459f78095a6ed6d31018a1041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193fcd1290109825b9d361e9d79ed99ad3d39015dc6997a4ea4df3ed6bd16f1b8c5d7dc022ac446366940c8a9d96dfad0000000000000000000000000000000004a10c4853a29b4029bca4199fcb3bafc300c209f2b32079905c888a31bbbe5a4795f0b69a492538b6a9ddbd54d41f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001826b9626237a037ee0d2ce2894983d206b47c15051c8e8b2fa74bdd8915ee487413266ea74821b136d9cd238fa2328400000000000000000000000000000000044b173f839c3df14fc7ef922a93b593a1babc5bfbbf809244bf34af910381c91cc5013a578a953d093f69ebf5d527331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1f9cd54610b885e198509845189d219b0fb838e2fda9eaf541006a4de35941544e089b2e9b021ccbc8dc36e5674550000000000000000000000000000000004960bda6e6f7095451a859b11b5fe080394f8917d48bb5cbf6372bb3a1236f05647fca260e50faff0436b70e44a47131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140662cb8b88b8a9b91850d93e4276a03ea19b9619748f4dce6a2a9a1468635f0edbfc9e8436362c53fc4fd0d370fd2000000000000000000000000000000001418f5e3b3117fd8b6c4f8e1e613063f31a88363600f421480a153f011df274b5b66f681e269bfee5709d2b65abd8f5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004da2910a8031b7926309284d4cce1a8b6aa0d077139e1a0309b05bd10bd4eab7e40f622fd33087fd3058ef437cab2f8000000000000000000000000000000000bd8c522f82ec7d451f7555e7262dafd434a56c1f38c3517405b30bc862d35c4f7fcd8af23d71c1b16748e6594e0d9e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e735230407c7dcbaa1685101045e346626833ba8edff0db6a25076d5db3ecfb766782fe2adc54c9c83c5b00adcd3890000000000000000000000000000000003ffce54b0d9b57af15f7cd148ecd3811b8b560c7f5076a386f8b0b221f38d5ca6d0c2272110bbaca079f44ec5ddec2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000baf0041f7b53a126fe390fdf3d264ceb9dfbcb2ffa51380c72824c3959fe2a0ee36728e146a65299fd7c561c6df622000000000000000000000000000000000131b8d7c31fd96a4c9c02cc8a5281bfee25279be5a4113c7a3c8311032cd7ff890aae4211f929f4559f578043132cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd64ea2420ce31c253711b653f27336e4cafac3b46b391a406cdbf5425f3c128e294de46f382ff3bfe48dac3dbab6680000000000000000000000000000000005b1b1a2833ae879914061c8c6421983f15591398a174a42234c16c82843b9e01d350aed973ebc3a61dba6f0abedcb501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e18d6c6371b65cdb95ce6a3b963869925f170e17d9ed5e5e6e7d7c3e35cdc299006eff202241ce487d4dd24a7a4b690000000000000000000000000000000008199ef4c6618a71b5e1fa2210a5211780d9daa9da4129bd82a9ec69f544557bc0d26cf22fc0a0f221d475ae150c04271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f1aa1f08b08c9f1fb0b6bb502a18b8336e4f44f509676499e74c46ee38b05f8e1c9b13a24bd6c4cc333e1602acfd4d0000000000000000000000000000000002fdb55872944a45f7d39426bfd664946c6d84a2c9ebd504a1b2d644da194eb59764217c9e2d3fd7784cb638ab5f54211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f059b7f8a4fb2b8341f55b468c01b2df418cddb0f15aed42ff1b9147585ea53c3a4846dcd542d55faf485400b929a86000000000000000000000000000000000f4074cf3d5737798a2bb4e5011224e96f6434c3cacc5e212cd0d54114bf835f335e870df5dd088105dde5b6c99003b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001260766694ae2197793fcc56d61957b344a111d49fb81c0474f4f191f83a79065d64ccb00e35e03c7bb2117e49138501000000000000000000000000000000000ad60e623a7dbf8c94b7f2f4649272a6e39f2cf21dc09f2f21e5901a32c67a404460e1a011a5ec4183269aab4952c0e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141220c320d9bc0ebcc7db83b2d86316ffa7c37c48efad1e80815ddc73fc3a735511f829ef1c9e0df9fc21651a0817d600000000000000000000000000000000014ebfa44246aab61717a36e785f93bf6681eea4172aa1ef9af9138c2a97faf65f590f381da6f6cc1658f8c8200699951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c17b681d90055663899c2c0a6399acecb31f618488fdc4ae11e18c6eb8b4820a37019db29927a278f769fb104fa81c000000000000000000000000000000000c2244bf4d389f043acab3c7db58c4fbbe6061d5a305d4a8c4bfdaacd5ebec96cdd366dbf7fb45ff10476c4cbc5bdd711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ccb4c3d73da4e0331af41351735e04dfa7a0ca2df9d97e299576f4fc1a87446472903b82130212724356a0dcf872b6000000000000000000000000000000000eff7342bab5a18266f42ce93d3e11efd67d05363910da902a99de80252c35def80ce57f0613b976e0d3cfe29303f22c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a651edaef46e3d2515eb8d465479a2e574296cc9f9f4ad586262d4b31a48139ab4fb86c592cba97fab08a954f1d9aa000000000000000000000000000000001015f3b8b0e1a9c4101f8b34fc68bfa6e43d26c0633f13045940f3284785af36556e7718d11247343d68d7dd1604b5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067213d9685da752eb8898189777910948e5c396171dce9e40e7de8b9aace1c0597798b32633fee24a5a5d55f78e070400000000000000000000000000000000115583417cba5efdceb7a828114e589c7adcdc2bdf471832fb3b7a96bbca9210fd20b4ae39241f829df26bfb09290d281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f2ab7d003ce8bad794dc4b458be56b57c6ca2e4a92b5e54bcb2f73ada174388966ad58eaa9cf15de86a557b986b1af000000000000000000000000000000001735c69d93a905b786fdb00b91da2c4ca306224ecaf31da122229e4d244a2b0cf024b70bd1b409b94aefc4fd003f367b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f68cd338f14f17aed11dce52eb4f83564068ecfdad5c779564ca6e245cdd8aeccb9d8790c93dcefba5509bf6fef55000000000000000000000000000000000127573a73abb85be8916b0fdc4542d056ad6e8fb9bfac043e995ed91c7b751e6965b90a759c024675053b3537a534c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a60ea2eeb86a22e1e271ac63f89236fb023b445b88e0bc5f2020af1f774ca1e819d8e6b928b3389ca06c7b580ca9b50000000000000000000000000000000019757a653c175c7196ce7cfca76257887b9044cac70f6bf4c93a265ed81b88a89708b13841349516e87b561f8e12c5fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f558bf134da0dce52e9c820a8ab4b1be24e8eb37c95fa245477644f8ca78e2bfa8153d9bcbf302019de3b7bb6b2e170000000000000000000000000000000010ac083438ee76271364a409f226559d16bcc79dcf83cbc4b1e0bfd389655be8b3eac4d7d6f94f7cd8b631325cbbde511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a63bbaa683f0d422c6901952d6fb399c230d84e20a3d99d0eddf0ade0ddc61958b02201042307f60b195c9ed4c425b000000000000000000000000000000000bdadec09d890141eaef0a5cc8e12c00552e3fa8270ef63eb111784ecacb5dbbb535377d25ec7941d0293cc960ef20e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028f0cb15cc179543c39cd424366259a29996b6739b709572da6d0b2ff57d537043deeaa67430530641c261186765308000000000000000000000000000000000c9498deca86636865290352c8a0193ba9053e61e98ffd228a1fe3aebdc347e109735f16b70d1475be47041aa06f4d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c936fc77099e57a1f697f69bb44114624dd202e24b45c6195b08e744a655cf1f3bd3c0849cf24c429d408d6077d97b00000000000000000000000000000000013df11aba6c7bbf89a28c0f9da7dc52e69edaf68d200f392348ad8f17245bedab60502d60b8ccb151dff1282ddd3dd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b336dc23590dc12669b3bae2e6dd61cba465f55c8547c494a10580611d687f7126e50375119bee85535a7242319d36b000000000000000000000000000000000eee78d1ba5a4f15a05bb6621a9615e22bc50761c709e171095227a92aaeb31473220832c80844fbe4ad357146a76df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086259a0cea7cdbf04c61d86a5f4928b43f6b9456a0a87f323214607255ad6f99655954348e8f561eaeb8954b2c466a5000000000000000000000000000000000935872090297741d605a1d1439648baee5ff45e2f2e2d2eaec6859b6315bca1d85bc5ea58d58d662eef0c93ae64d3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b6561ed1de7c694284b4cc9c67d6ea776f3f072c2d3179d97dfb21d6bdb0baf3a704449cf794cbae3ab063a4905290000000000000000000000000000000015a558fa6b497f0b0519a887e92c25471899e887d4ad1988998e0228e4507af0884c34474686bb9ba0e92bb6563de6b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e116459ff88ed81513ab793965816526a88fdca0cc6681ca1b5a536037d48c133b3ff2dbf13fb44fd4355f36ef166620000000000000000000000000000000002bf0436be880c338b0003bbeffd4a7bc7f264a7d4931a31a755cfc259e5d63a532ec72081bc935e15501ce4a22ed2891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e22c15f8e4445579207e406d492a4d27f0f6898108a3aa571ddb62d1a2b46e0cc6ce9e02a0b565657fdcbb144949260000000000000000000000000000000017ce50ec798f9b2362538a737dbca84fb97759b8046e8ff2daa53ca38487047bbc3112f68a63a4dc13403331e261a3e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d2434274430323de37bdf71da462232a719144fad2fb2127583f0418ae677945a339fefb5899b826f474b3082fc35a000000000000000000000000000000000996db0b08a2911da7c2ad2263e0d9c110fbaad57530aaa80ef0a90ad5f42c74390c55236043d9fa6c8e6da533f9b4831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001854e0fc75b75d2516145e22c10946040245801b7ca0ef68e47c9d06af0b2c6d6804c03d643b17dc858a07e33259edf800000000000000000000000000000000108a15e82329816849fc83ed4a0932eadbd41c6031cfe4c34b63fee885bbbedfa2bce50d03ebafe2f01cb680d66dd6e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f61135e9dc2b07c7323ff99689b2643e4dd8de61900f036f0c64b08ca49e334f72a58fe65596160233e4b55bd21eb0000000000000000000000000000000000a0535c32805ee6791033cbd2b9444ff048a7d3a8802d48822af84e05b5926d873c2d48010a29e0cda8a6a33cf7dd5241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000068e137db7bd348852113e6007cc99b77bc4046aaeab666a1b27aad73e0fe0a9cef555320ac89b79af2d553fc2627920000000000000000000000000000000007a54044f2d8abdfdbbbb8367a961949e01ac9a2204c272125e75295acf8c249482418352409324ad6957ef324e9c5031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023931a4d090ce4d798f219cdbd1b23e99dd1a745dbb5f5b01fe7449c8a1077899dc9c404fe2fabbe3fe208f55627efc00000000000000000000000000000000127a4ee85874fc84a4a38756b6cc1ab8c99a402659a6892ba4c2a6598dea9cf11aeda811dd6d62c3db3eae2228d7acab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a60c7c8e723c208fc90af1cacf37fc035534945b3da6e405d5fb05b1a1b77e7234cc938e7962d0bddd13437388651de000000000000000000000000000000000307eaad9fef5deaf958341ef892d136d07dbbbd13da01fb2abf993d73d68e9d3383893d31bd1a2889a3dc3d4381e6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000167b3a8e1659f042972ac35450259488a711ab2ea5fc24bbe0af6168ff297b957e5881bdf36fd64aa63d66246af5d58000000000000000000000000000000000172a73b0c84ff7a587fb4cdf18d5020dc3041651943371367c493a9c10a535224b5b80b958e0e1f4470c8db562b60191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180acfb74d948a4e0736f782296ac66ebb49be6d329ffb57d352803d69c65546a1615691ae369cbeca2138da1df5d7d800000000000000000000000000000000029f6ee011db7de94c5289537c0353f140b15ed66a4ef44493b923974f99b04d7636d3d9860e8904fd3bf7b227c1a9e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c439980fa21ea1d3a4adcacbbc911759012bc9f54c78e873526806afdf4cc4db454f53a38776024bc2a2ec33404218000000000000000000000000000000000eb61d3a60bcfd9b94568a4d286a1cac1d410a08932d14723a60b07424be3d6ae7801fa676901a87d8338cf98e9c32171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bfaae6d4575a6b01d71f557c5f25f21a9cff88b7939280e3189a8c52470cb4d33bee0a5aa05320d5b7b9bbbcc406d100000000000000000000000000000000047d844bfd9a53c81b33148e985e9d7faf74e9208f46afe78750fab0c7e02881c5d71739598644c797ef8fcd26d068791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029706a909ebf642eb10b57b592899a710c0d9a1ea2ca13844761885732edd327f5404189ba895e23b55326b51caf9300000000000000000000000000000000003a82793aab771c1bdc7ec8159dd64eb07e93be2e42e9c392a7e817828c3a716c48b48240584724719a6e7d0401408561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000884ad21c0393e133da9a79af06311add389f7de6f2d79b2f7014f811e24db0894ea4fcd874b1bb2d46c0ca1ec9080e1000000000000000000000000000000001697b7ad2826481480a264e31b6db86fa8e8e10ce539277d2887ccd63b92d8817b5ca89399fac52af7dff44ea98db1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030445ea7780ba0b73fa802ab0ddde2f5d6619ddfc4d32ea3d142d0b8280d351df8ef055435e4e7ae6ff18dffdb0dd00000000000000000000000000000000001915df3ed014397359652293d2d6c76e2e87edfcd3b2f239d1c538af07768acca146565d434317b24f14a63438c537b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017467df73a1a06807a59df888586ea2a386eb627c6d14ea37c60e21b2339cb386b910b29c9aa88e024849f5240ba222a0000000000000000000000000000000005e7703e7dc2a99b3f1b016467b14b7d5b7e988850e94dec8cc22f1e5a864306a900ec68476a7f2d134e795a5df72bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd4cddb96619484e61be11acf1c0a1570ea061ed36a6a80bee377d30c3418e627904bbb32d86ee98b35d9e80a0589e00000000000000000000000000000000051f7615c7f6aaae22754691b4d73ed9e8272a5ea51af1f60e9a815b911d71aa78ad41f3ecdd07b84d81cb2b26f9f46f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018144aa2b796921a35f0f5e65d546738677df679c09c3bac57463027a54bf182910c595bf6fb7b13a60c300ec728f390000000000000000000000000000000000c3b9fec4c01a3d333357746a61349e71864a9b5965c3c480eec1071ca7e5a18c71aad0b5fd169c0c3a4895aa370bc341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9799693bbbae9b5781609bd2d349d41fb17b07cea94d73a822b1bda33ba47f4ec4d55690a6d8ac4ff16cb32960dd50000000000000000000000000000000011512bb39ae06b7c36719624a7151c1f92a1ea227dc243a801d7e369986f670dc1708815b96078011bab22a161899b221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b40739e8aa4a2950889c9830dd358adc16a31dcaf779f5f936ff669a07e004a8d1f2a985db05d84ac24b115fccbdc090000000000000000000000000000000007edf499bd56229e65c007117ba055efc2789b08e8ee725be02cc653bfe6549dbcfde4e62c893d31928274a27665a50e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000358f3539d76fe3b4f0210dabc4b8d75677ee854376b5803940bab1701601f7b13a593baad51fcf7436ff05c53e2372000000000000000000000000000000000ec36014c9968f898b0d85b96ee935501473ec6185f4a2aca562ddf017a8bc5dbea8a77d38e72ba75a74127484a2127c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d80d0db1bc2b6016dad5190f9b9498a312a33a3094bee94c1c6749012f4667f76c534670b06fcbd5c4837e308700a82000000000000000000000000000000000950c5882f8a8385bbeb32304c6d4b2e1590d0b652f1647985fcdb6a2447db2a487e336c74c316c29d40b6ed62d4f1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b5e9810bf844d425ac9f44349872eb19b047fef683ab5adea53019ba7ab1c49c9555f37fe0418924f40b7481850ff7000000000000000000000000000000000fba7994f389b3863f5f70aa5e30dce156baa4c9fb33c9e64383609756322a8e2767321f623c68578e7694202ad528201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c9c5c754c9aef1c85d9234ad380bd98ba60e829b84788be951c8488cc7d5fb5f3cc4c07f6c018a9cc6de5bd0748670000000000000000000000000000000010abfa44b037eca1457ccc12b3d013e1617753c59d476d5336db9c87a08d6cc8963315cffc808535df2fc15078bb40551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001893f20ffa0b680ede98a4ac5c763d980d841833eca5e2c4586b819dbedab8dd804eaf99fd2fea21ef22ba56fcc1901f0000000000000000000000000000000007f921fddd21e75d1845c2925bf4b0d8dae1b5b52f3756f4147a4597ad4168bbef40069dd048f262e5154f3839568bbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013abdaa044a73f7481d20b7b309e85d84b953ea24823d57a3d8b87ee668c6c7e8ea9e1a711b78a92ec8b1874d5d789f9000000000000000000000000000000000e1a0aa671215617d3b9725723cd524015190e87e4397162f407e56380769157f66a4b6955b09e07c1b388af299cc69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b602a4e1d757b630abd7bc4cb3c5386d8f64813f6c10260ee49fdf09593786c55374a92f5b42fdd6367d9e485265050000000000000000000000000000000001c6f3af834b07f685959682d6d91832dbb9eb37c3e4698f71864b7d6d4614f220c3b16176a0324eecfe2c57f08ecacd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000478767439c82381a0a5eb9dc301620f261ad5a6afc0a2700aac292ef926c4b8c43f113f7a5888e6df1169ed88cdf3b600000000000000000000000000000000135a229a90d923f7bd9264eb3af03371ebde0073e644a2e3289485a5d3480a6f02a518eeb606f8d66ea7f4a4a6c0bb871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121910719b09ac8ef9c78561169a20229fc8ead0d4f42f5327e9130f07c7a9c68af3f18795a9de753d704b32dc9eed00000000000000000000000000000000000713e1152eb454a330bd2e5e726432fe5d1e59acf4e64cabf4a3cc6133e5dd1a87449ae4b704aa8c5b0a5dcda1e260fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001524a2490ad9fce68d6c26e2dc7c424592a29d5c4d04472916d44a61f30291f4c8fe6f5c89db2169e2a2eab73382b6cb0000000000000000000000000000000014d606953a86684bc184c16bfda76b9a797dd5c2a6900c5bc789e49079adbcd8a8a4da0f3930e86be904efbd13bbc61b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f9c42ec5221d061c7192325b5f051731a5a652ba6cb72f6d4d454a7a7c9e43b947fb29f4e37fc4fb9ed78ffe74b9fe0000000000000000000000000000000013ed2be22c1df754bbc66b659c13c92a2e7bb0984872b70251ff04a525db41cb7501ee49acc0ca62e0f1abe8488d7c7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcaa1293cd29b966a3a0813661b18c738e762235fcd8738cb0b7f3776b615ddc35a38b7904ff9cffc3b35a437efe2b40000000000000000000000000000000004904578221a1cc6c62518cb6e7dcbca7f17efc86d5329b54cc04ce51917e6ab1cffc06371828d817a4542584c2f11131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187d820063a1d46b115d8b65bbbf0ae6d56f475ccc324b2ce942bb94f55e1a9efb7ed5fe0769d86ba47bb22bce2fbb60000000000000000000000000000000000c2daedaa9f1d044f2bf95a733615f20259f09f6aea16c8760d94fb494c37f4d7d14dbd0506104544a9ae3a09fa50bcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051e157a71e1678706cb82922200d15fc3bcc07d334fd0b06bee40eb7a5198d9f6a0c4b6de603041edecc325683ff840000000000000000000000000000000000b9e0e6f1267c4e6b9a7663baa138180d33f297a5ad07dd369a2fe037344380d47c77ad732746d23451b714bd4e7ffd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001804a53760572300e00bccf2d3461ac77af784bc65ac01be9e374a07d055d604e32db40b4356e95a293d059a494b2f5000000000000000000000000000000000af1cd35bca5740a9a92fab62531760f3c9608a45b548bacd8118a7f4ec9470a7e5d60762e9c9823b93f9a9a0e63051b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006da7aafc25391c7b591b6079fea4f35fa28b69883d45168596c1b899f7d0e1ad7c19e10951f5d5d755ffa3cfc8d14d20000000000000000000000000000000003e2de39ce894986c95bdb831c39aa26d1042cded410ea1228337fafad81155d03c1b70f2f4091bd44123ebd953bb67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a0b56b3e06e9a4cb748946d0193981f24999828ccf50a9a172d71d78a57e6094ecd6d218495e409471a3e9628da13b000000000000000000000000000000000fde7265e8c4d6d8c15f9127883783bfde4e6438578d2d9858f332455255c1c4f0344ebb82b85b940acb35e33d71e61c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073da75bd47306002b7130cb78883d4d0c055f62466f59473d6dae47758ac46da64ab8e543c77d1201492224621362610000000000000000000000000000000016d1aa37d8387595fa75167941100e641851c4b57fd659777e3a79bcc249c0b6ad8a6306e6d4411e84425c0fd395e0ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bf38ee26c7076ed56683506a06fb54f4babe0b5c8ffd3dfb477f2986591e023338ca9cd58335545a18af4795b8d2a4000000000000000000000000000000000c6e3bdd97a87a07eb3979f0f486fe832dbdc4815d70a3c9e14f44b51283ce55044d686b709af58d3338b68f73cbe9521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6901aa3061540c90dd13f3deeccdc07dc300717dc5e8d8c78fd3176a2014a9b17a73410d816e39b08675923b5f7652000000000000000000000000000000000f123beb981e97389b695e7942292e4c416fb7be81077dce0b668419bd63fc2273526e5972fc9c143825dd4f0f9f28c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8531f5bf90ea098374db41c990fb4d7b5e8f9d55daf206a7d585bec537d176d582481dae164c13374f7d0898b6305000000000000000000000000000000000b125674edd6ff3229ae8d86337dc4afcf699a0e665a06c85a13163235705830c60d1df7ba721f293decba8f2294b1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fa96c23c82d82a80c6496eb0d28e14aac1cc0b85d48120da4c57f28f79f8263a78264caac9b911bf84337cc5b632f20000000000000000000000000000000013f432042d6582eb2191bd4cdf01f299f3a225362032450c2e4d56890df836bb7b2ba1ed20577b5331f033d8d28f05551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354e6767527570a4a0972e9fd7d7ec4038ca8a0ccece2b8226549062ea3271447e3a9295129eeb472be1557eca3740d000000000000000000000000000000000582ea1aa9be0451188f6d5bc457c2fbba689b1c360c114ea8c23bbc4d91b6b7a13279e91644099b9d0ff83a842fe3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001150a34a299d7a0e7cd42bb955707d0ef980a17570ec3d29be2b3a00949cb68ba0d261083cacd35ed5d16c574612fcbc0000000000000000000000000000000018fc879b2204178841c0098a6546eaf5295230bad47005a735e1437bd4e265e8e29f95bdd40294e82f5e5ceed271ab0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cab28759256ae12c36be4f41fbdd948a385669405977dd34870c92d9dae7dd34d6286b6e79102b7f9aeab86e2ce085000000000000000000000000000000000cc18b5bccea8717dde660ff953fa4de2421f7a4503fd10aa158963a939d945407a49bb47a9b29525979f5e421182e1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6d7939beb06aa0788df4045cb0833a86b115c871e7713b7137f18950304bf1900fe8f4fc447f71de0d54e1bfd2fbc000000000000000000000000000000000e9798f25879e29e81e315e6b438e4041d9337c9afe8f6e222aafe44730deb3ba4e055b3ba2372b4c2955f7735a004f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b91192ffc961baef2895bab8eb91bea26e3f82cf3ddecc766a7173917c3474be0dfe074aa181399e3121fea433e6c5400000000000000000000000000000000039e3494dc9de760c9cc602c2600cca28c3b2c59e93897e4f820a2ab804416985c1a7a0ce41ec718421d84042c1947c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113da26716776065e599ad8c03e5a83aeb6342c0226ff6aa16d99f8c1f14fc223cd0a5e4d9587258b65a73d667a66e300000000000000000000000000000000011d377f905252560995787bdf67607a78193ff64dc66dbebf6a0c22e4d8bd4d36b924d2c8ca591b08b4b37f3a5ebe1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae620b94c34f75e07fb2b4b0cd9ed53bf2fe5fde9dc7ace232f6b5afadc47ecf90e8d414d8dc87f68ae9c5ccfd92540000000000000000000000000000000006e0c1703d64d75adbdc96404a885e9b731ea833101e28394bd48510a1bbe8a2cd22180dab16f27e427311a18a9246391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a23b760e11e4cb2e7cfc5f612fa33fd9e4f960dd74eb9eec75c1256c4740bb0b0ba0e0958a5e67f9580ede91e39a2020000000000000000000000000000000005a977679380f4dc8246c0ed3ec7afe3a9b886f96660ebe86a14d704ac108974f753b1b6c4993ff52ef1809885897d621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbebe9d82cb18059064a6068a12e671f4f14fef3979eebc514275c3c85c2819893a0b38b7be1183d75baf8bfee0a1e000000000000000000000000000000000f2b1c423da2111f9e4e98936ccc7b59fa8bec782fb34004d8c5d6f7f1d71803e175d664c425dc6e2430dabd90d8dc241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c96a15227e962a080ee5ad16e09d7c607dcd418b3093148fa6e4546294efab1228cb6842fd3ef131261a087dce81560000000000000000000000000000000000ddd392fd9bfef6af3b5361141f5a20b681384b6d5fed252c4ec95c8c4ae94a1350bf355b7651c792d0344ee940773fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015eb92cf3dfd70d4b4d669310cc5424969cf96e4091748e7586e040b96b47f0faa179e989a9cc549a1611583f402e81c0000000000000000000000000000000011e5dc27433b268fea5ddfe7c342598e5521eb6d5b89a1b1fd9a5b99ed9395777cd68a399efa8702f2394ee9463755c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010625e728ed2acc936cb99738721d573d58255febd7ccba09bab4dbdd5f5a21c0f97660e003ef15da9ea1489e8c3374500000000000000000000000000000000089298cf52a135ea35032a392e6439ea10d8d313bc9d8ef953f2da7f12cc29f97a0babf64e813ad226a161091d6d2e5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b0d33c656a6e4f33d97d690158ad3f387528ba63db1587a71c5672703f9d50ee1d6668cd38a8fe10ee78df8b0b5b62000000000000000000000000000000000b4896f958313a544e462419d8ff1bc0e72b5a91e782c4ce204dfe4bfdda9983a5b0f5de029f28a8764f680b762c1e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050a36e428f0651258c0224b024ededbd34b31803bb11c1000f45371cb74a33b85c0da1118dcb08f4e935c0e7f01934a0000000000000000000000000000000018b5a92eb415377ade0db12de1f398e6c854653b4e319b23c02e903dd19f13ffb5d5dacb89d9b5274a35b3bb3e318ae41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b080a9991bf945f25e9e3f4cf7e3a99c2549d4200df0d0e0c531a68111825cba95f472a66f0443d1d55b17290e5ec8900000000000000000000000000000000174e795142368cff844277257cc95b0d180669f73239db80cf5eea4756aab431f64bf5ce7782db729335346bff2b9eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147626943a0bb74d061969b16f1928381cad7810ad162caebe1482725fb6b3178eb9e85a7cc233df98dc7cc937bebc230000000000000000000000000000000005c8cbb684de372c8772be3df59e807e6423e39bdcaf75da00711ccdeeecae003ab9aaf3c28e98a81a1dad4d318117a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f79e48c24d2cbb4e30d4b06fb0a49d41a23f586e2472d1cba1ec0c762bfb9c27491434b1e7a48fe39929db79448fbdf000000000000000000000000000000001060e66daa0b5ecea92824f2f8eacc1076b3ec0c9903db829d2c41f3e8a56edfbb6e1abe4312786507bf9477c05295da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074c9beb0625b8972b380cb0271908e4176c800346a73cb85a91d3ae18ede308593919fc99bde12378eb35cec465622d00000000000000000000000000000000190badfb4e529e864995b9c17ee6cd74b792af2b548db005c7b3fd3b412069bc8a1c4972dc1b3852dd4acb0c0525bb5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e7a3c54d473abafa9d9ddb724a325638f0de14bbb49f0c7a3c35aa43f72f5761705bd79da03182945c917e0df81deb00000000000000000000000000000000124cedcd30a7926b9d689c5bd368135c15308ae8fa2f5e8e6cf2d5f5b37f5098188723d33ac4f3db44030b47841dcc151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e12b3941ac008fbd6201b7781272e9353352ab4e90f15a7006cc2ec4102a53e207c4db288d7562914e5bdf295d5f8800000000000000000000000000000000063b84d43322ce7ba28bc0380368afe24897e5c23c718a90231e8f52418db499ff0f342fd71d7dd2700c462826c9f5601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835f7f18c6028ee64e689b1be4f6566776abec08fa235323eeb4b24e9668599c8670e460bb1d41aaedf3d2fc12bf32f000000000000000000000000000000000aa2655eedb6fda6b78fa7e522d0715e1907d657b331bac2a16f6b3994d1e3b05ffd93e1c76800d700247ce3681b1f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689b90708594f5d3a67f75f05c91a28773654e4714c5c283545c5aade7f933730b38b75d80b7888a101f17d77f1e788000000000000000000000000000000001029b7f5587f50ce70ef02f9bd58f9cec823c1fc7aac07a5b8ce30a040ee4801075fee129ea3a5a5e036ba50300c13d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e56c36c4a5547a9cd7446b9cd3cfc8a4c6e4773dea364df4811a1231c07a456945c7c83fdedc4cdce2132b0db3d4840000000000000000000000000000000018aa0e11b0464164393c950202046f38019a5f1147bcfd79564ac82ce6a16eacb6ee9269a25f05ba96411baadfe0e9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116f39b4ae156184d0c74dd275b752bf2ee8a094b2642acd1817f7b04eb0099f0d69329f69775ef6fec6d97c6e09915e000000000000000000000000000000000992537ebba244b3ebba4028b5422326f55884b53dfc03b75a76ed1aeee3d3bbaceb0dd2b11e391d83048b5504abdc0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea1c1e139a2b9e01d1c114efc0252f36bec019fd07bc732ecad8e4a36d041ccc8efbc606503f4cd8bdf0cab718f9e6a000000000000000000000000000000000042a6880fb6ecd68df831d6d4255b1859b0e486c95756cfbd484d8c005665e1473811b1f2ff7bc5fcc44131197f09491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000803fa3115cd921acbad7d441efbb92cb13410ffd974742dab7ce88f08e48f5792cb57c1d11c833ca28e3d428e8206db0000000000000000000000000000000008f74a222397e0ed0fdaadae67a98942e1f1221fc2a3d9e83d34f991afa104d5a704b0f61a77915c683602e628a84b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c70036a2c272b0d4dd5ed54017448eafe542ef58f99cc4f108cc6cae0b10b6b18d5d7bd7388c9bc536dd6e59c91ec0000000000000000000000000000000018a5f2f4933b1b829f1f591b2c7310eb9bc56d40c10441a46d286c72d18e7ef3df057c855f35eaabef6984b03f2a3de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d95994193a0ad423ef6f90a7ec2e003c733e0da890a9c8d756461f7603c9baaa0afb626341664634c6646239ac6dd000000000000000000000000000000001813a8f6960e621b67cb8ce31157d0de23483739b9d03aa818dbcfa067709046fa7b913829dbd81bd9a1a4fe748875881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f7d0eaeef234399b1b585018fb9f49f28ff3c5e4b96484764cc5588841a11b2fd722f828d32ab9b0ed06af9aa5941b0000000000000000000000000000000007d8e9a06835508fc8cd0ddb97df1a0726c5c4c97e82ca90fdd687fd8a367b7fe5b25be52857010b8e047c4bfb160b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001043c9141144c84ace125a0df6f81cc44221820e45bc842ac117b016b26396bde506407ac2350505785a681b783ae5cc0000000000000000000000000000000006dfbb8d69f19864fce2469beec2a11709ad4ced6393551b302c33fb82250055e98e4ee61f4cc4500b42536538e4363c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cf5d55991981a4e431d896e5ebedcb437599b9f678bd54e2b0331056d5a549f5a8e773086cd5bead08710e9df601b9000000000000000000000000000000000b930719148bf4fa8ed858fb1d9891dfab144df0ec49054548a51d1a14824103d6d88ad90e9d77da938e88140c53cb9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc4cc129f83d350c2d0a9f223bd5b83a53cc60da3f486b17d1f980311be02a61a82a9f28833fce943124c2761b82f650000000000000000000000000000000012acfaa552c17917a4e594b8b254b0106edccc1a3212e2c8ddb44227d10d0edee55e00b725d82d9eea34def70b084ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146bae5fe4227ec94d1fd28e383c5bcceed5159ad91a65a6baf2e88be3d28a2a69dbcb0c913c07d74b04f31adb781743000000000000000000000000000000001081cfe902840aaf5b8c78a8d274c043559bf48f731fa0c942d75521a8142fdfd0b7f1750762ac330c66d26bda8f9f5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae074a9d3426babad7565d9bfe50359812a0e7f6eb214cc9297212a3f2de547d4d51cef62186f20d7ff5fb717b6f122000000000000000000000000000000000fd712a181ac8f9570f1977c76e6f99e54ab6af3ac9b7f216034de44c7dfc3f91f1f1a6ef7654c5a31e3f0ea3025c3961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e77326dfe61b083117b3333f0d6d3e4c747dccd3faa2a31998f8196608c3e0a41038f760edfe1b3bfb094f476d0113800000000000000000000000000000000160d2271afdd7a2ccd4bea2443e263ed86aa0ca8af6a69d4d6e35b2a09ca9e2d3f90892639ddbc33a92eddb52fee61a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8e0ae650b19977fd6298fbd0ee2cfe1e5661f2b821753b549c2ab3a47622dfdd6e08ca89dc91d545ae555a59b3958000000000000000000000000000000000af15232593767435e86500f2f1b8922cb23e4fa72f45e10cd14b7f66200c859d4b8dd2c657a4a7aa083e5bf9d2360211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e987b3e194143c6a8960ed87333f9eac4ada59e5f17207317be05376dab64377151e77160fd1d11e5cfdc7ec868fb61000000000000000000000000000000001843f101a396b2b2e9d8ae95d1a1cb9b72c1e35344402b80726d47149bb55b6867e96aaf66a4d70bcc5c6d1e22ae5d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072d47a27852bf70556b0713fc3879846138a039b49c204b59007e6a7afcaa6926e521c9cb38a9d9ee68a83e7b3a81ed000000000000000000000000000000000623a771dc7a0aade68f3e97ca7c35907ef6b95f03b81f65741bcb5f0fc04f8a238052d80a93e8657b1a39fbd179d2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a473c948874d2b4d27c0a6a2d71dffd04eb966c75c13709b2dc9e47f2d9c325afd6b6e15d5009e958027764f817ed8000000000000000000000000000000000733933d7ea933bd7353e9e60fd42c406429bb68ac07094c161283ab7b4bf4efaf9f31f48dab1dd6ed7f1051e034e3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd165ef4b04daf0d904f9f0b0b7743b8e1af8192b0ccca1b60d64fb3b65f2d3a88f3afdc67a01cceed93c10f7b687ac000000000000000000000000000000000bb1b760e397ac78acc2c6834557c782a56f83a8beae5365a385109edc722fd095e0f01ec7183cca8daab6489758431c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006259cc10b419a8d5ac55823899140e53a84aa2fce1ab8f8499680d405b48251549b65477bb90e9ce2095ccce31a610f0000000000000000000000000000000017d81ae5a3748e6ec118e0c7dc2e128658f06da33cd0ec79000065a9928fd3a3332f3547ec7522f45518615e3b45da8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149fe2ccbeffbe069090a4ca4ea1b47cd82494c9b501eb13e798f244e8593fc71c1b14d374a6113c10115107a8cba36c00000000000000000000000000000000072244a287ada3450ba7fbdc871bebf038420caef541ed295ff31db8ea054eb7ed4a45e63c3b2c36538a712ead620faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bca769f090440197f815273c348a468afd1e5b43ad7bec1f24933c1b8b7445f2c9382583a61ff6a0e7c2e468f242cae0000000000000000000000000000000019f2e8b57ec17a2fbf461d5f5a10476c604264f5992da6a6ede80a23cab61103c4a73eaae4a43106c31c4ddb13a160491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175f5cebe49a9d9e0b8019aa55804a298cbc4e944c0a16b0f89b3d217c17e3486c0c61e70099d7ad578fe9600354c0ce000000000000000000000000000000001532ce826cef5464b652d5494e407a3e25851ae97919eff054baefc4a1dbbfd32d833d91a2291917c4eb1e9bdd57616a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001899e6529ac23ab5a412596828b1e192638a2f87c13c83acd61ee7ee377fa16d029408196d22a9b3fdc74985d9ccb45700000000000000000000000000000000021a95bd3f437bacf173a8f9d38dedb2b81cff014ec9372f7cf26acb7291bfde7f24140d280f6d7a2b44153cc2f3ea011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db3207016b163008e9001ebb72daa3313a555bfb571a0181b8cad9026d6cf1714c4fc5d559e6f927243d2b5cf50cf21000000000000000000000000000000000fb6c683858d00208e36393a396edd2fc959771720c4df27d03815758f55ef2f149ea92204cc984591811395350da4911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e21db878a3f0a7dd8a481a60374d28d76fb1305399fcdde5c20e8922d0293274dfc722c2c1400af6eee75f2fcd0995000000000000000000000000000000000719994ed98e76cdfb51c030b2ad1064d3f3bd45203a89aab20a3d0df6b0c764e306a90d0436fd24e49850e30775e7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be766000482f589339e5fa516073c7f0f57f3b61fd1e8096e43bdcdc8265ad5bfce2851fd79c493888cbf4a2ff2e7b3000000000000000000000000000000000dca0e74f86d565b61cbde53aebd0f71254daa4bb575e1f4630ab33b6e165d2744c842c2b62acc0812f0bb3c1ad6ad9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f6b9281c5a11b945cd44a82a8590ef4e3af7ea8513a74bae21d0fc41a6f7cff4d9236081fb38812ff34c32f08430fc0000000000000000000000000000000002e2091e6dace0032b2c5525ff7a8e1fd365bbffe1474e85d15e46dc5f883db0b9b0a187befadf18f60fc81f6fa3dc6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c7b244bd94b6ccdab961ce17d157dd379d01ecdaf53b36da3e35f70cea2cd332ebb5a17a45a88fc4fbf0f57a10e71f000000000000000000000000000000000da6ed38ac031f365309508a1f9c592fbe76c837b45085511010a203ed6ace88cbc5a7900efd4548c121e068ca55ca101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c35f5aa682db98901f476e41d5f4578c90b9236722569af34c32739f9201387bc6bfc22acee0607684140f445a905f20000000000000000000000000000000017b9a78469a201d1147e1d208b74ab3ad785a87684917168761371fd3677c6a4cc1a1d972d12f5beffb1608e61ba41791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d95026ac7cd4501cefde256c50f90d9ef30f76d1ce01695bf3ab8f9c81a3473723ca21c5242efb87c9a45f7b3029a6000000000000000000000000000000000dfbc635443aebb9eeb2f292f4f678766ca4ab0208697ca3f459944b8e1a765eeea453c61de023b68bd680c149d70d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f4d68788e35a38fa1100d42c2d32b357389f3755712a32de187fa24f058f33bf65b8f91731dc253ca1ca615bc2bda90000000000000000000000000000000017d4260b359ec53ce661f5d6885bfa190b585e2e5b6b390a7cd78f1a8039bd52f4dfe80e6d08998592b22f9c4ec4d4b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013d23197273cb72b9eb49d1b79523950928b1359cbbc219c8663bb3f004591e7a64108ab8072b04b52e9695db39a2870000000000000000000000000000000000676b33bc024a565ee1d6620883cd67bd3d0f89155e37686be817cd557cde6101f5c3d629d1af7fbdf361dab23379a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000864d88630ba013c1316f8e364cc4c0b39a13153900b1393885cefb0ee0ed72768a90d52d0aba61925982032efac6bba00000000000000000000000000000000081c2754adbfe9682f58c834b4f6664147b1108c1fa98303b7e2d9a8f05071eacb5d98cfab76768729ba246cf52524d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001372fc2791498bd11c89dcc8fd6617a4bd8ac4069d1a15f535b132f6636dc5e16c95b7bb7d358f3a6e9c55d778141c00000000000000000000000000000000000761e26e9ca8c064f00c7eea8e6672d96be2e18a3edd324befe7d4b70ea39ac325872424aedf8d3395196796ec06efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015711323df9bdf9dbe5423bf73ddd1573696a88b0f6d29edb300e2fd60441094f9ed6dcc0d61d7e1b6a54aaf2609f8590000000000000000000000000000000010e9acbdcd956a783359d84fba8e4a71cd231919b92a1e772f624347b90b310bbfdd9453502918acdadee21834542f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c70c5d4af6a876bffcebd08bab2097f0f16160865373652111ff17f2ea96f483e170de13a489f392c19b7ad3f754ef7000000000000000000000000000000000c0f3d4ca084337f8de962c289ec01c8b8cb8798f7e717c5082282ecf9a967d821729efafd4f603b65c8832e56e7b7131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f00dd8777a3281ab2595a362e1299da287d5b34fb18617d82479a82ea90510d7048997da7059b76cd7e3388dfa4dcbe000000000000000000000000000000001320d82168d5d6911068d1e7bfa1a89b321098caeaa4fae7f38c57e4191cddfca284808c5225c82edf747bc37615c60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004de15fd12b669b89c81ef4226b35e546b056bb8a0e48c9eeb90abe007670d9f5a2126be4e211aa027b424435d05c87c0000000000000000000000000000000008f2568e0ffdbe56451d45aa8a3306aa8e0b219db72970591ceb7bf07ba9f1a296d395eeae7267fa4cda51ac499d352f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014edf21be3b77894e79b0a55d9e0ab4fe8f399ad6eaa2bcbbdbdbfbe8b8c7d49ab31bea8335883c570d4ee32d35cf7ef00000000000000000000000000000000160c929baf538af899a618f916efba0fdc597dc46572ef66fc2fd25e8acb28634af18270180c1771534b1faea20894061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bf5f4bb8d24aca0b58868c485ec80aa1535689161d43361bf794f179771797ac76dbe65345b2035ec0f969fcf1d2a800000000000000000000000000000000113d3450ecc7ad7b0723dc53ab41abd81de81c22e1a853b56156e725a6a5c1c45875cbeeeabac8c35104570425bcdfec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d567aec9f19d8d9d2b17ed34f87384914badb67caf546413ddea616f666b4d453afe681073def102ffd93577724b9100000000000000000000000000000000197d67e0f2567fbd6960f2db0e4439939ec6ad1b68258d3a3c657611300f80b1424e61b0504778e43fcf3a7cef14dbe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040975e73640c05baa6ef2f5dddcd6c828b41b945403b5d83afe898412942ad435d49f650c49292c095af216fb25cf000000000000000000000000000000000020ad1ae763e2c2abbec0e88194e91dfc58c650687075823843af8e7792525f905acc8346c7cba8cfa4107ff37ecd2f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebd1714c727f1ab81dcf39a92860d1fdefe590ba680642c65a55d14a7d4726e4eba6b651d5651783394a4405e2c755400000000000000000000000000000000186eed887c2b22b5471f6ebc70daf747684b8317a900acd1ca884fae27393969276e66873a78feff0839fc88d15492191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ba9f7973c3f8c6e1002cde146bf9be0a2ec0360ac7b3acfb2fbfa52cb6da5be7f1bee392c2c3d9f0530aa59c4d95d1000000000000000000000000000000000a9f0fbfc226136a255445faafb1041010d240f3f8d5f8122069bc3e7df4491b83f9dc09ed9eedbaff68df1b3aceee511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1fc17e5fcb57ba387547763c73402c293aa6df757d2215ea7c47a1e00d48a69ae925dd8e6d5c1bffed2c0490fe21540000000000000000000000000000000007d9445bc180a97d1939b602276287ac932ad0fa6f5ee64238721212b46565f7182b79ced8c1c7a833fbab32298f8e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001750be6b878b3615a53d7d9228870031eb93926e03d12f2359e787c98e4780b6c75f58034dcab4143f8575fa8a1ce5e9000000000000000000000000000000000bdcc4617999eef67022dcf838546b79c54b6724d6f1f0592b72bc73a5d62cdf45f8e69fa2c6f2fc7236272e554856601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035eb2e1f4bc7cc53c9933608d859437518253a8d0aa09d23463e0e42aa7e5d311be4fa365bf0327ccabab3e8d3ce8400000000000000000000000000000000001ffb7940359984031aabb105fd22d87a21559eb45b32fe998f9736de710ed1e63aa65b3484dd66972a7cc88e21085201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74687c072d2a4c86ff5b4b59f917fc48ade84986bf3be94d73b33bbce2fab01ee8860d06bc4e7d16d6754c55bd47e50000000000000000000000000000000008f8854acac323c4a0208f72ce385adbcf02d0f2d8063c854fc20013917dd1446ed54e68c25179cee135fe57771594c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000513537c74da804e205803dd36d8c517f4d44c622d585b5604a386e16edf5609e0e40d6acef6b1a02ac9f9bd08da4e38000000000000000000000000000000000edeff635e75c5e0954e57a982d65e43e7deeda3aa57a743e98b6326929995c6684e9725af3559752791b9498caa92901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396ca682de8c10640472834339221b789b6f3bb316781d4d7aae85531a8489c3f5f4c42e49d96380d955540f046c3b40000000000000000000000000000000007e19154f4e2382453d1a6d49672eb35ee1fd1869dd952dda4b8aa2b863e77c98b662aed1d9aad3caa6ab7abb1ffcaa21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061cd0d402fdf6fd82edc75564cc84bf8407be05e6bddf733e79e293fb0ef5aba5fa450215aec4a8f1b3f9f84c3c8d510000000000000000000000000000000007fe8f816bd15d636b42f6e063a359524944d4974767734a41ee7d0cbc0ada068f08fb3e5ae19ae90b337e1d2819d64b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b10032555ced8cabe9cc9bc3c2a11e716696d7d21a120e5ac5f5e74242cc9be741940a604b6763f84e935350e661620000000000000000000000000000000017ae001defe7b6e9f07fd9ee7bb1b40f5e7c386f53ae2a38901634534a78f98e49f249addd5c571f6a8392d0b68c5e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001287137a0b495c9251e49d4fd1b39c9dfc4e18a2e4bb9ddb25f0fc3a4a909d84c0263ff92c5f971f67280b3b8781d7800000000000000000000000000000000002b1d687f4b9f8365393d0776486ab31e02fed21c0f681f90ab97fcf22cb2c627be59063587563891b13861124de3cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e10cf4c4644ed6d5cdd44ae7711405ca67176b21bc650749b5a6205f56397fbac705ce1cbc6e6550d5ea65f1ff6565000000000000000000000000000000000d4e9d54b1ddd1a651e772bbd78788cec86dcebe839f6ddf9a28502f69203f952520e658d331c269c0be7e576b8657661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fa26775cca3f3182644ebe07fba23525934acb881ed622cb37270279877ae8bd18090d8b7e269d74e7924a0b22afcd000000000000000000000000000000000410e136378da2cdd00a5357705747a8242c2b881a890b355565491491b4ce6771955f921e8369d9b82d802ab355b51d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092822fc67fc229b88115ee36091c2bfaa68f415fbf447d07bdb38cbde07f763bb2ecf879c32b486a07949518d92b2cb000000000000000000000000000000000cec33b21a2b63939bafac2fddefefc57d0f8f6074d2acbe33fcecde1565a47376cbf74980a3f3bb3e3f7c11cc6f4c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001460e93c82df1bd3a31aaa3a04d88647f133b0e6d16d4bea27ae5269b73fb8d70be69cd267fa6a8bf03b3b2d8231d4530000000000000000000000000000000008d008828d1219875dbe482e497eeefc49ffe22f65d80099b1226468af77320ebe42330b5ec51e56d207ca2133839efb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956a4d45bc8f90604780aae88a458b623d271e5f2de92603f0a4bc830c0e0c74228e9ee374153d955b212dcd3312ff1000000000000000000000000000000001050f36c8529334c07057ccb09ca80a58a0b43b16087ea11c7429bbdbca3a1fb7dc10ff82443077f417349d31a308e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b1addcda6725c46dc3a7d1020de298ced55f1693f6b56b1c5ec8be3bc9c87d9176b2d48bb9ddd36ad8db533621a2e000000000000000000000000000000000d859a9cfb5f79de00e7285604c756c1770f1dcfee03011af0b64493fa3f1755b9d7769aece05b7efc585ea336467b211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040836499a84961f8d6b3b32dba2c8d7bd3068838f9acef584dbdd2194db56051662ea41073c83b016c49924cb2b5c1f0000000000000000000000000000000005853537d50a00f43e5de61d8e8141a7ef6182db08668717c19ae9ba0d4012bf2db2e093b9a986adecfbd5fe71f9f1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199b1dfaf88ca431ae49192f069b74f8fd62acbe80c2818e404dfd0450725d8939a4a4a73fb0bb0d1fe64529a175d520000000000000000000000000000000000aa8778336022ef875b6b4ce44edeb2ea274ff3c11f06246b417c17bc8525c0089ea16cf08d4be990a82176b74d2fd8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008127cfa03cf0ce8e672438ea94b4f94114ab71d48332e9f05c83df045215cb1e0800ffd053bc7728a4fc17bfca186f0000000000000000000000000000000009a21359c62cb582a9ae82178a3ddbe156abd820dbd35668137483ceea84c1a2890b598b0eeb7224f3b146dbdc8194421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065729d9d1f5b452fbaa48a25e221d5621f5176911d346c33ae098c98081c5e97991b9dcd316f2e216246f62c787120700000000000000000000000000000000073c49b125b1346b8fc129ac99c8146800af7f307806e346f405e91987bc0a8afbd748c305f3e3ad70e9db0d62ad0c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763858cc7e97310e5030fce31f07943f1eac57487bfc45d820166ff8d1327d8c844d3f477eedf0943c6f1dd23e62e5200000000000000000000000000000000070f317d6a28e79cb3e6eda44ce3fded3b9dc822141683defa80e28b8c94003fb9e25978649b81832b2bbb206a7361181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000473c0f0c926b3ccc844456a117a479cf037223341191fdd1a1e6ad1ebad1229ddf290f4c87aa95660b46628330ddc3200000000000000000000000000000000082ef1dc0beda0b30d2180cb3df8ee6e39c83fcb0e12736e009ba60d69422323695303a618291d064bc0e2fdda415d521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d322f7c0460e724c7981294df9d3404b14b18613ec64fddc8ebf46fe916c85b23607905136e583e571b2176df224167000000000000000000000000000000000f4a78eed408a92e258ba4894f276817bbbdc2b42722aa92d5e34aebbb3227aad6353a62bdc158601d4692e0c0b14eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030814ace0fc2fc9d766d2d67ad6c018b3f8eaa51fc7be5402965c6b216eb24399addc8bd70dac11af998b2412d05d1f000000000000000000000000000000001466c0680735bd81fd315401a10dfbc7ecc3ebb8d7904e4906ccd4969a8f05dd7e4dc9a194d34be5ab08ac56d42821cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108f66f4e220ea80a594721cade80fe5fd0207813aa16cf13092cc034b05f9b2125e0088199ccafd56e7fcc36763ca540000000000000000000000000000000002a4c80c6e405069b838dd034b4914aaa7c0ace6c1e184945ea370244268d80ef8d849be967886189101d80f5378233a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000061b5a278c3e4f9a5a441b70a610dfa807708b039633f93918de0fc59437ae17bea40a4bcd8b5aa6bc9281032e9138a0000000000000000000000000000000000ac40e7bc9347ebb8b9a88f00d56527bfbfbf64344a5ae796d2185fd3794d41644cf1894fb04e73a88954ba335cb18f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008885616a26b1f1e9c75b349d4edf291e25b7b1f93da877485c582e8887766cdbcb4d082774ca092e31404da4963e82d00000000000000000000000000000000032b165e72957877bda52351268734b53f436ab25fe933e5a1ea2579833284ef958533c3b40fee209d8c85fd1ddcfbae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811939654715967f79a1a7ffd4d6fff0b45de35886bf7d399eebbb4dbd673823180a17c8ebaebb7d0a2203616983f330000000000000000000000000000000008f060d0cd98450ffb8df8c3dfedbc528d28a8b96d5cbc96bd9916f93613bd9314b33c82bcd6a90330463f98b72f31481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006370168172032573b726e9c9ea9725fb7896b848e03dc530016ce0bafe34c317f686d7c54e8c9ba350c576416d03309000000000000000000000000000000000cdb96cb4648af55be9b5d9f8b36ae1453e6867531534f64ff7ec3a074e8c1e68e24dc702b0245bd4f5942c76878e7e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013952bf6e5f7f8bc0caf9f0f9b193717b90bb23c3f5cdcb91d789ce286e1415a675cdf3d9fe5369ddb1654b1a02495cf0000000000000000000000000000000006010725c8d83e11f0c7e95539d1cec4d4ad2dcce2f64e63f74812921229bcd86eea04cf68406a54588b0b62da80a9581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f24976039b76a6a71047f32498b491ca1ac9a70f67d2ec96afba3f36f4de3faef4be933f8bd34496f90e23229e2ea820000000000000000000000000000000016b8337a96495b5ee2603e6dfc27853388f8e9e92144d38fe50bfe8df49b087e2d974c486bde3e8afd34796c44d8d9111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ca381c789bfb65c6908ccf68d573af90424272489dda7420d8daa6d99d2f9fc42da6b74f24c66d53d11ddbac89128b0000000000000000000000000000000006c6157289990500741b6384d529d87d66b8b4c49f17898a4919fbd7a2b515d2e19907b5b49ffa8ed7b1b08f377bee081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137cc28952170bdf54613d57b8d64d4d134f8227b6be7fd9c90ed73006c79e802776a17a9dba6b3d80df5b6e187a18fb00000000000000000000000000000000046023a6de6c99d01353b2f2d0776f5fcaf410390d9638df993d7c3663d6ce5be67a3e10cbbfe55f953523d4fa2852501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9e328352c4ddfdcff0954eb8fe686cbe66caff29e75d9ce760fa1ee96bf53aa8e3e1e5d6a6199ae758c8ad2f5094700000000000000000000000000000000008db49767c72d62ef1e5567c362629340b0d270cf465f636162e751f4854bb6d5bce10e1fb01e8552240008531296ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe601d0eee89e94f16e5b7bbddcb03dd36225f4800999088a56c29282084a8f81f033cf46d1b420dd426a837cf6a3200000000000000000000000000000000077df5b662b6f3a18261cc7407ff929d08cc7993e875053cd72b59a81342b5342ba186651e4102437b0b1f7b673ac39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cfee3036a352eddc8272290598e66e0a01f63c610901f25f3475a8df2564a28fa78a20635683c06274cf500aa0933500000000000000000000000000000000041c0c9cdf9cc2971ff9275d1944ebbd91acca5b3623783262fd768cb828f97f6d92c26789674eb75cb67a93268328fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f9d1fb9a75e6fe8e3a1a8841960c28f87c817f34c2ba0b947d56e51180e7aaafb73a9257aeb1f6bcd78256076458500000000000000000000000000000000108920ede87f0732393274e2990510eb01081587e50b53c59c44334626ee450565ac5f380375bcc162fd1c93208a863d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e44a683d95b957c790e2eab4766ce8c5529657f953cd14c17be536962b15ed5cd8643a5c452d9c0d814f674e55104610000000000000000000000000000000008aaec51383ab7bd709f9a8b3b67c2dbbf038965a2169a7eb8812260ca750ec81cdfdf8078ca73b65597f67bf6b077651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab413ff5e4c05e1c3e3392a59328a8765f9bcb8fe7e23e0be8228eefbdcb1641377404fdbe2029b34f14f6ceb9763e80000000000000000000000000000000018d24a78c4fce1c41fb160f2899033e1eaa9c5fba794a93993a2455624fb02b002e28b8f2483524dfefbc079068d65591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9c2e736e12b19b90c5303d521080ee69640703c1754ac6c4152d2de62b6cdec118ae4497b0f25b1cee6727ce6d1710000000000000000000000000000000000fd2a4abda83147ab7a4d602d33666bbf9ecbf8c3b46c795f4f1bb5824be61c0cc34376b2e5c42b6a6fb5d1dca480341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ffa325131b62f24a33e4ab6671aba21e88ed99246b60927fbd0e6e1a0c34b0a6a63218bff025bc63501316fbc7dead00000000000000000000000000000000044b65a54deee4ca65ef58c363680b01dcb88e81389b14c4712559083689c2d8a0bbeaf43097e89a45a80f531bd42d321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c5ace6433cc539600fa8e001a6a20b09aa5e03912a828094319fd79ab72d2e3d9108850151e773834f4671c35a16c60000000000000000000000000000000011db2ae0a95f4854d835b767dfeca4a0747da3f855e82d85ad026170f1c7be93eb4baa13ccaa55cd7ac1f57424c5c4e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb5ae120d5a9d211f5d9daca16a5bef4425135ba75eb7e9a97621e5f35b9191fc405d34e844b22b45d302a19d0f9a8f000000000000000000000000000000000fe116324424f38d69fbaba9a0e228860be5c81ff9844403facce0f49c089e615ca83f16467f829893b1e959e4413a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f4a39fbc15ebd6c23561b5cc5120d97515712a3b9b7fb5d75884760ba5f7afc68f761d4b2a1393affdbf19971c15b0000000000000000000000000000000000574e251b22446ada61464835a8f1620e292e624a3193079df2df1bcb3aee2da30bbadfd5e3b6f7fed3c599eb2fa9abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159bb5561f3ad4a74167be4ec4b79af84e5f83ed2df14922cd048a0fba227b685d51123e4d326bc8042d9b13abc695db000000000000000000000000000000000c43be7d98d5525637d790b07917b840f54e500276dd364219feba419bda275899c99ea5abe1d0a5d6a1972b0ef4ea291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763a7bde57e58cb69f8a34c28405c48bde7b0e5807fe9f81effaf45bd96e475808c11c4c72cf5fb285bec2688c2b6bc000000000000000000000000000000000d4aa1c10a030d7de39b74de6dbfa158331e70ce664335c3d750565fa0820860492271ac55f5ec451f2e46703878cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1ef2394ebdb558ff688c47fc79aa9d7a0707383a9f67fa9188cb643ab25811ccd253fedc0c7dae4ff77b54fa5aa5f000000000000000000000000000000000247d25d9d688a054d46d53b43aaa4e63f239c91c3086b568cb092dfa694c285bcf69c34ff329b976e3e3b29dadd9ff31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042182a619178d483eaf287bfc23909e36efef791a9318ce9d66a2fabdce4fa1a318e4ece9379188aae2ec63bb78b5a700000000000000000000000000000000174f6696194133d8b500b90457d9de7afef0345d14cfb6def1baccd16f7c34c10671dcd8a8f235f8e79e5a352df1138f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001697cf85252ee50c9e52f7b0822ee7bf2fa690f109086125bcf4bc24bb5d8e6ecc45e95f2fb4343360301c401893c8a0000000000000000000000000000000000cc903b21d3347a0ec1f88c90cfe5cb29725dd4d332eb2a3dd2f2668867173964785327ab4b907ef97f70ad73207679f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b29f57ee653a017aa6bd0b89d48ab2df7ff083276d3376895d6481f0cf99a425d54524c002afb6f985da4031443a74a000000000000000000000000000000000231a8b90b77a58e42638a3575a81f87a7af311adae80ab12e6b314733c819d74dbf315f16b40eddd0d6435f17a0760b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035124899f58a0ab28dd9d41bdde4190c6101606b6ec42b6670bfb2d7fada41b6fae728b72b1373e463b22737646736b0000000000000000000000000000000014c8348fbdddecfb418aa553573ddb9cd3892f2ed660bb1873458afe086c2adc2dbd999ae77e7ecacea23e416bd3b4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065fb382c0ac61bf04deaec0938fdccf3cb86ca6e6b6fb83a0679587a62bbc2fab92fdc80815a439558a057df006edb9000000000000000000000000000000000cb888ba75c42a3abbe79e3fc8fc6d720b1b54b3470157228a4c3d797cedc4ef48ce3f0b536a0d75db4ea209fa27c8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ff0551f558ba2cb02bd156b71a955dba9a7673746960f7040a067370d8ec3bb19ca12e24c82389900c00cc70c545d00000000000000000000000000000000007019f11712f452d18c994d52a0c31db4fb8c718c7efe6271847c687b6be23b4ce5fce434bb29f57cccfac1e197aa7871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009322ead30a644a96c7a431e167483e3474c00abe9b47e64f123dc296e3b8a495341595cbfe38fef12cb17110473fe6800000000000000000000000000000000170c3cdd855347b2f7ac01ceaa18d0f980b37a79a96b0bcaa4e9062c24bb39dfc331e8b257dfed1b0c18bf6d198c174c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4b6bb60b71a4c5bad58f0c2f8d282b9b2b8952ab9073a0583a7a6f0a56679a18e3e42f59534b984e9ec7b160305b1300000000000000000000000000000000027f62c83bf03b65cb3e9ab90e3104d65b291850233e1ccbd6379f29a042323915ad2d312d3fad88f745f89f5c6ca2461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009342e39e49c0ff7291714e830b4ec3ef76e6b071fd71c35d4369678b0593dc522f62ee6938a129e5c17be140535711b00000000000000000000000000000000093559c79516f7c71db4473460fec93b79f601b7c35568590f21a9793fd46f50e703bb19f04df53afd80ce95f914754c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117f6da9bb120e783d03a08ee56118d3843a791dfa398125f097652cdbf9e5eabf10d403d09064223ed4a971830a7e1500000000000000000000000000000000064469a7424bde9e45b3bba41e5e196a1c518076d121df271741abb2e47f1bc9c6e69a845964c6b4265d0746843612a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bbd87e6dd10fa07f4637c8346f196b77392e58ec729b214f1b2d6268c361584b89eabd52bb99942ffb13909f849545000000000000000000000000000000000fadfd8e2ed7bc7afbfbd697b88358093ef5d965ee71afd9e899bcf45e5dec88f3e4546ac0bac2089b90cbd6ed577eff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e77bff20ff9efcd866747da07027d917a52167974f0993c179c8e4fcfcb9021498709b5327e597a1486e281ba2276610000000000000000000000000000000012a7098f193c54dcf4bb9af7dd45d3616e1405dc8fd7cd28c955cb8f67ee04eafb708fdf3fd4d1a6ce23e68106e711aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000702d7334921562dc0e81e0d9565d58845b059a6978c1e7ec541d37754e1407e7ba945eba53934223bf8a80dbd80a4c900000000000000000000000000000000017ecdb9a4aa688b9901efe8ceabe33dc846c6ad31c367b791d0ce69293096ae6a6fdfd9b0542f906e58d1ca9ee8bb291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bf36571a46fb136451300ebe32b2b2afb55ef7e3c62663d35f28f52bb82bfa7e4481fa81723727df2d828af3be65e3000000000000000000000000000000000652c2fcc391da6271b28593af460893b7a23e5f0c6cfa840abb7111f353c38ba5b4cf775d13f84e460402f76f2956001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017571f4ac610bdde007e838b1e3cfdd852b67cd46fd7508de64aad01204143aeb13054c9a320ff3be146a36efc95b2450000000000000000000000000000000017ccd16290d32ab0d72966fbf0104cbf05d510a4a232b055fa5ee0087166ac35d9c737e21b8e845ca673dc76cc3ed0531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8b823e4e24962389ea96212d886338f4bc9a4e7ff2be7fa4edf0c8dac7b7317049e3e0ab5074e2455399743485017f000000000000000000000000000000000b1aeb78d1dbc71e2045ca6e128d1b8a924babb9ccaa48bae01aad0a24be8b1193646be2c0c0fb4624c4ac7f33e6d82a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a83a6a1f2e2a4a390a17a13e7bf3ab1cc227c7976818c7e22b111072cd7fe46541032c2277588c8f1bf58592c75ec900000000000000000000000000000000085c79123fc6575c8ae8afc068397bfbf49cedc1018315183d5849e3bef65505c4978b4cb8c8258eea326e024b8785161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000502e2682bc2d212cc7675ebafac2ccf6ee6e8fe5d56cd46cfdc1d9f65e1bcdba56650c3a1a8d4d545fc62600cb3b7ed0000000000000000000000000000000016e68923a51dad89f65780c9868aa7560970e51fc35ee09e0fec9f685673e52a25d4ec148a2b8b969082408637bb49d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b1dec1a5faf0fa04b417ab9aa96417669d5ec650596a21563f07e3f6db060939f0357a52e6c874828812f67087f9f000000000000000000000000000000000292cc178a39052e4d8cdc5c3b35b5d907e082558eaa197fa3092c12a888dd76c4e5ab1a57c8208008f64e911217d35f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000485421dfce3bb5b31466f52a9eebf8de23d77b9dcb0adc6d67c9151afab181038d289422cc58e34f99f7b1034ff66300000000000000000000000000000000034e031556b96e0fd847bdad124be5505028bb0fe8c1a61f8ab5e1077fc052efb0ae1955368d762fbca554c3853d513a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b048fa6198ed21ef406c9a62caea97f04eea5b6ead3ae5f3651e60da6f670310cfa4970bad2629991f61350ea0259b0000000000000000000000000000000001635f552dd8dae543006214523abe6bd4a12e25563fb52505fdb89fc60553b9ecffd7e0d8f69e4ca2185008f064c78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005c5eee11257acafe86bfbff9947f0956d1a744cc4eb9386d13ba49537f5c1f7ebbeb52ac1ae57f13dbc458eab7c4c10000000000000000000000000000000011ebb90f116c32f8031d23494089f78aff9c48864475e772e8fd5495ba0e76e6fcf02797fd4c349517a981da3de481191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e99858241af981d2bc129a7393b3bdc93478a278a5a72f290633bc66b4983a6d3b2b0374bf5d6595946902ef405e67a000000000000000000000000000000001360cd4d2be3a963a309e68d0d001a0508a3c85feecaf3be8f5f023e277a82824b570c1b644565d1c483cade402058141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386b89402091048fae55be428c7ee6d00b921614242b6baefcdeaa87b2fdb9358e0c4a5a632450739281990c9142497000000000000000000000000000000000be5d7ce8e9377a98d52398f0ce9fcfd40550b35564c40a10ced0be046c5cb7704594ea175e93c159c189f5864bdcc941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5061fa5e74c6c01d1c20fd2c88f9ce5c11952d4656959ec39dd18c9bc1a0f8a0823df9184ce9c9fdd73e8615d338a9000000000000000000000000000000000e5422089f752f5f62df213d5c47d59445728f8fc1e29ff79c0c21e3d05fb7d831e2fe6921698a1cee5cdb59a197849b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151a67dc79601c44e752545520edbc37e176e3cef4d9d7fe67bbd1abd73bfc7e704e784f5bbc317dbe847271276d688d0000000000000000000000000000000011687a342fc0b3f5ef14a86da718f6d6d2db9b4a63193c3e045a3e67aae20126c018f3954b528a2502b8e7635af8d1691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095f7579d4ea4de95fad8e23effe5745d69cfcfeb2c28195a9d0141b88f999a42ef50548c293a39010463ba3b1eee79e0000000000000000000000000000000013914fe434be4ef6333641661672ef317a373f615c701a95323ecfc52b5ac5306f1564b4908acac1d92bea9467286e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c90a6ab03ba1e40b759c3eff77f70c9362bf27a0b415fa1eac6f210cca9d8813c8fe6ad1a1f11eb5b4cce005f705c90000000000000000000000000000000003e78bda2bd69a1349a86405d436f5ee0595236119e1c6925ffb7a821b3faa4a120804fa70915b0f5289c88ad95626601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c1810f66c313cb5cd8329244ceb3e538a34fb5dce737e96cce8aee1042d4d900ab82831fd6e449e57db4bf603c82310000000000000000000000000000000003eb976bd84fbb7655773782129858ae8289c7d6dd08eb6cdcea047c185fe442fbe3136219216c349ef16a5260f5875d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b885537229dcd9e8f42e00e9d62cabd3957210855cc92a60c0ce35ed4d21d077cf353d7534eb1c46171942143d1ce00000000000000000000000000000000009a57128d7bc9f3809d05b8466f5310852e3b50ebee2029f35f76ab81e825e67299205c7ce9c558b53ae1a6850c20da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001576d11e4c4094a82d6307010332bfc299be1b6c5f2b2d2b1476436befb061c163ab17deddb47f361aaa2be0a12c37f2000000000000000000000000000000000d8767c224837c2d1f2093fe7a352d7dc530f012a1f0a1ef8f011880ff3ca705b9d15284d1b8468a65cae94c9accf5b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527eee0ff91b68dda2fd5d43511d20578d225496defc97e1e6f8d7897ce80a1b5d66e6dcce7aa6c374b209594d3587b00000000000000000000000000000000007aa971ea8f2942de31b5765663a479e2cb92d633fd2bbbff722da14db500e8b184e51b2e9f3df49fb88568e47ad42d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d56b368bbb6f06439f124f3246e5868d12b7d11539ecc3b8547126ec40641859416f871f4dbd2ebdf3b5b48c2fadc000000000000000000000000000000000a6c7164c17dafc85d844da68d8dd11bba8dd45307d118a6d83dd79e85f0e3577b2c0af2bdb6bce47f632e6228af97ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160dffe6d01b918b0c468b487b005cb6cf139b946d66c718dfc63b273599aa3e5c3041b163d94defec5d4e4b92560f9300000000000000000000000000000000188d52e52ecef9fd3edf87b0e7145f8d4038301b58e45ea891c2c71212e23f5aaa115c901b169aa059e658f89ba21e0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000411894e35d547722b761f3275b400292b0b8aad42c69c9818fd3a8fd9fc8deb28769efca48059d20ac8d3f4178a38700000000000000000000000000000000029ba85e1121ec3b914df7a35db64d7b8480b04d16f57fd43cfb4e5d47b4c38f5b2a904dd471991823eb72c89cb091b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001813363c6e145148c114cd83ba38d4ae8274272e35b1432e39204431f2bdba50180b74e5b3d3c4cb198263243f412ab200000000000000000000000000000000027f9fae80b29acb1a16ee510d86c75a47bd390e40f2a639862130e3a34f6369dabf44205f06d5dbbe43d18c5fd27f731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075b3e2f7ed60c87a0c3e5f0cd2e4b06fb5b6eb78bd94e033f03ac79a8c8220d3656425c76cde8c8d61708a85113e497000000000000000000000000000000000e0d1924a92ba1133ada7d4a76aa4a7a5df51f46abd7d8228880c78ec112b09da61d8544dfd57f0cb62a9716395bb1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098ee937ca7dc00a8f71b3d020426968ad0d4ec0e06c6f628537c9c486eb047a2bc56316871f4aa3a2885851c4878dc900000000000000000000000000000000165d17cd127d262ceb7c18b79deec502173ca3fc1b06e89b967127511fafe044198898914ea2bd6784071b8b8f02b9231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035033ddba0c6a00a5246ac8dc7c662e5a90486fb184952498d7f269e7ba9402cdf1db237808c0bb1e25c20447fac014000000000000000000000000000000000e38f5efe637f8fc54e165faabfb58294d51569db89912ffa55162dfd952412b32747a48a5759d9c8b04c252e9e8624a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fe5f0c35dcaa100d3470644f541484a8e928c226ef53c0786fef4639c70defadf416170de1039f4f542bc8ab1aa0700000000000000000000000000000000158cc9cc88a8a281495bb321a808bd202cf79d37d3f693b92440c60ed72a3bc6a999a9136d0b80a0455d736ae11a2d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002683087640ca2f9cc72bc8a9fab391d98a6f77d2cf6952caa8b73113f812794779dd8c479c2e373ac8a27097fd3b2750000000000000000000000000000000018b8af4532021ca43649dcf83564212f53c3b6c13fc63ee2f6ac45a5aa4ddb2cd1484024c1835a46d655c0547999ad451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012042a79dd5d9082a34f418ae88b8fddad2249f9c6923a3c70cc28e88815f3215147d7eef52e93e50a4508ad4013a921000000000000000000000000000000000a68b33446e2a40e31ff43858c0d4f7b2909eac72b88bb196a8475875ed095c9bb30668dbcb6f815c700bc97d32aa69d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7a60b0f9b798f9ec744f88fc04c05e8d3e4b20b01f0cb6d3a7bcfc00ccc171507a569a6e912cd8ea910ed4d1102ee000000000000000000000000000000000fe0f84cdbc80d3182a3211952efd9c80d906145b321cd609b5837978d6e4a8d5fa25fc5615a451ef1c7c263586f4d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a90296d49aa133074f79f104910428f9bba6928c9b7aafdb50e1f749eb54f46894acacbbd36ef9e1317226ac583c540000000000000000000000000000000014865ae3e38b87f26d9fedcbd88633dd34215409e271861a2d291a19efb1680a32ce6bb935a89c5d0544c6b5b848de8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062b20a559b3d08aeac6fc78507570224547478d45ad5502618865b0265c74f1e11379802ccba0bd1f63de5e58927968000000000000000000000000000000000d37355458d73c776252f2370a38457330aa0321e7e0c577fc8ffb0e1256bd02d9823a76b21bcb23986127c732e08f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001352a9ea1c603e4831347a65e8d3e5bae73ced0afd4d716d5f8d61e0c0dabb59e7ef67a967e27d073e66412e380f3080000000000000000000000000000000011f3d0d9d53f5d1a9a10a343faa8287bc6bf63d21e556e8ab06e9ce7c0d87e524345fca6f9d0b7afd56f12877ec09e9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4085e3b29fdfaea8ffb95f341d71012b186ab31057d0ba84deca90e4ccdb8666d130a0f879fb4b4f4ffe71319aa5bc000000000000000000000000000000000b455673b7afa2a412cc2a4ce7f672c2ff56e0bacef9e2efbd549061c3afbaf28c7d665857d47c987f04641f842a76711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067bc7dc93f1fc5ae13d6cf623d9320fee1a6e3c9189e96fe571a57d2fa9323bc515ea201eaa3ff56af35bea4de74cb700000000000000000000000000000000152875c58cd8f0554651b874f00ccdfb51d06ac22175baaf8726a69985edc2e37e4537673d95b4f860806338cec715c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000101679a1704c083f4bc6ef8977eca52d6010a4aa716101a94e1f4e9e51f0e7a2e7318f62266b38c92dadbf03b8947ba000000000000000000000000000000001767857cbf680c1a02c527f2155b88a5d3eb1260f66aab848253cc3b22086b239070f91f64d77c177d82ba666d2eac6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000563400196e3b2bc30aaa9c0ab8ab0ad8497995f3ea7fce04558c827434cbdbe3d211cdcf1601b9da4ef31d089e6c4c6000000000000000000000000000000001580c0e650488c186817c53b7f04ad1e1038b7c1c957f6628b92a07aae88e524346d8cfe40e269c4a53b693a9a2fb1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002422e90d3c9da67aeb6f487e0ac60b7948d766b37d318c72fe454694ab901c666e939b453e7eabe0afde69c5fa66f0e000000000000000000000000000000000908c99d5e8c0fa8382115ca083d3cd91d1a709878a5ea9023639f9dfae2f6f5f6fc86eec0543caa8dfb4b5b02d2161b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6f9e8aa323df1226f097a2fae52ceb646038b37bf7f30c7123185c82a29e083e8c4511c149b3cf15a6c1f48270e89a000000000000000000000000000000000c53eb2772b99e3ec63487b67a4d0c6e9db31199f1a60aa878c9181c28a9f3cbfa06d46afa47845c484c7ecd47fd1eb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c2c29eac81f5bbee9700b7ab0051843aa4f5bd2d785e7532e7d83818ad05b8e9c96cbb4f0000e4c4c57295b9dfabd0000000000000000000000000000000000475385cd89a62172a09633b2ad1ca5d489edd5dc65987369e9c86d2cd5a1cf7a5a17584b590be8dd04096eaab7716561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c40efe3aac2b7807948724ae3437de67581c4d0126028b74ec374572b75d74c181aa599936f5e3d2265eccb3b75c800000000000000000000000000000000104ffec118d710e01ffbd0ab625d18d823d730356ad3e7c1c1439feeb0193cb2eca3a3e3059a8452175edef161400bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb6764f835ab810c4c98b34fb01bc5b87632aa36d97dfff6ba05011500e61457e8e77e7e3f9f82562e5180456ed676800000000000000000000000000000000087d8e882d64776fb8f4bf9aea0c0c15004a0a9f303eee2677746806f7197e21c30d996d7a728001b5a101a529742a681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d2d37f86675ee5c7297f352439f2303833e8090f3a099212756cb6d6d963ce5cbec226b0877b7945767a7031428a2000000000000000000000000000000001591272b308bbbd30d682296a7feb34eda7d44da2953854d76c05954d53b18ace8ca0f5c32d5cebd6221271648c15b771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc34329b06516d11bb7a98bf698c0b140caccb213d1d5ba130622087965fe2eca5154f4ba52fd3db944cf2064fa5240000000000000000000000000000000000f7572eef30eb62711d4e6365c52995d36e26833b249a3731fabe7f25c0481a78f460ef7a45e5131e2f7a914767877d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d48cded4e28855ae5af35fd787f8bdc49cd8dc58024c15e413ef0ab34b3a5e8330ab6aef621bba28806cbc8e50ce418000000000000000000000000000000000057416b2b9b29483a8bd853a8d9ee9038862d11b0822d9d8aa3f1fff71e5a1b5d58d7bfe5afee922818d4195fed74741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff1685cbc9e9423f8dcc513e3c958ea106a3f2f800406569bc7b86365f10023e3d13740f1315dbcd0e1025cceb980c00000000000000000000000000000000128ed8907e2539034c7cde95f8d6916cdf4c3e352031419871887e9cde6ef87c57deb76a4712e9abc386641198d5825d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096bb778735b3867a5dc185de75b7732f6490508d0927f76748c300424a6638101bd253fde0d989c70d775ae99c95fba00000000000000000000000000000000161b527e7b0edb91c3eba69808042fa84d168b1adfb39549b3946ad04ab757c9ffb8e9a93da910c4a92b7bc7de5387e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136f63ec0c4ee18f1a90b36541914e5307c4c33f3f01e3ea6f4c12f4a21c6c3c3f82b7cddfed5cac821b7bf60ecbb9cc00000000000000000000000000000000196116911a5980d41397304b5e87cf54ccef10d76e21ecea42fc9d9247d7b63913b92c6a1d55fd8d69ba3174d14ba1d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000015b874b6d84bd5b7157e2a3b267e361653ede58b098174a22d6dec096572d05d5e4a2ad7e60a67ea6a3f5e5781a9fe7e000000000000000000000000000000000bf50e866245db6446e8a2b294f6987a9305f5cc8f855bf4e04b9707552307dc497f4706cde8f5c849f3554ab642ca35", + "Name": "g1msm-2048-jwasinger", + "Gas": 4276224, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000a1730de8e6abe2efc1e10dd1ceed419d14ec6ec5e8701e17217ca974fa33741a444d65b0f8f59961ebb354c37dec39700000000000000000000000000000000023c960b709fb4a0789e2fa2496bdda7330ba40410eb959dd32cf620787b5cb52ade72ebc3d7c57ac62f4ade497e93111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001398a54c25090c1cf9eb94504693ba8718a8c40150fc47c24959360e0569e45a0fa40691b3abee78e24d55785b4f7c4a0000000000000000000000000000000002fa98a402d6470e1a14e7ce61bc952e6a3bd17816b25231aa0ef9be1da07dabebd7d4399d12c7a80dbb8f33cb7844871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774f2bfd349b970016d57bb932bb43be2cfab127e2da90cd4d2d2221a1246e7efbf684097c7121c7c677cd1092ac751000000000000000000000000000000000093049f314f8a8b613975c9d3e16571abbebaab1e4d09efa6e12dc27f519b918b45990ecfb4ea41772d53ce78f2e53a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001122c9857481ad1b06a42e2d6e419563853538592d37cc6d27481f7505f5efdacd3808c3b44e47923aa5ec34e81ee23f0000000000000000000000000000000017cbebe357bfe70738d4a656f5203bec6f371aff0f777dc58516eda53792906ff31b824dc22d5594fb5caeb20ce0447e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d49e3f5a9959904c285b12bf0d3585d4dc32ce9b72f6918759c4cd0adf71ae1e10bf5e0976081906494265e881f9e5000000000000000000000000000000000dfd2340586ef9b3627e1b442c986d507fac383384da9da504678b121db9c0400d2e5445a86f3981885d0bd0a02ea8201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001065f05c75bea3129a55715fe93d4afc347a792697720e96d06b08697091264d01a2372904e47816e458ae38f56203340000000000000000000000000000000005130ed7a8d1c1719a9c4982b0a0e61e08c59910e719e5298760066edce86adab6892d18d01df7503dcfeead616c25261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153b75e97ffa9a7a41de85b2c413d1f2138cccf6e27ef3e3f3ece12340333204843b4c2c2e8b86d136b5c6c7fb30df110000000000000000000000000000000009914563dc40520452f0c4456133ac9eaa2b44014aedef3dc48569b63502f8f298c71aa502c72808a1cae66e81ba49621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130ab51776303e6cfd0cc3ae7566aa24cd2dec7dbfdd06adc50a7f6fea630958defd538104aaee0b00f7b35d0773f19b000000000000000000000000000000000b0bef4683439b5df92dce913ba9c55672fe2641d59f5f6e51ea85f33b3c69eb69274de5bb0d97c6973ffa51c2a157271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac37695878cece25ce28edb58dce9376f6ba1cd100fa1f958bbc0f3e9d16486948c83c8ad4a13c03dd533b2671ada84000000000000000000000000000000000b9ae369196cf33149389013ded774f22b779b834771a77d02ba5586d6510f0c160d2885637cf91900164fd9b215b0f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a2c23c761c3e0097dfb2edd635031d99bfa9d8e44755892cadbad078e2081056695c00934a38910de92f32af53e3d0000000000000000000000000000000000f32fd7a71143553af09d0a45634b449a5f100e492d710a385b3c4c4ec589784bf6b0e80d8c36ae26bc4bd19c12be4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c2aca4e569bfe9c54dee9413a42f96a69d3297011e0634ada6da227844263a74eef8cbcc9100ff7c0dce57f3d906140000000000000000000000000000000006556e5837abfdabaaef168ec47da7fd644ab9701074f6e4d429986fca50eb9188feb6b9aca5837ef78fa396fdea79651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f10d835345a0724804324f9df74d6c0a1744965866a464a9f21c334a7ca76150423a5993c77c890357ee038db7e9360000000000000000000000000000000008aea7e714c796dacc479d89a5e3f62d0797ae39132bffb4fb8a1188dda2be4b4d59dd992453f709367046c5f95544621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa8473f7f71ff2157bfe94e6792ecbdc940b63820704c0e0c627fa159693f9668af4d247f4d3af9521407c1bbf3dbd700000000000000000000000000000000098f74730f1624d709fe7eaa0fe019c0deb4858bf1674095c4437ff67549db429d6d82e6adcdcbc9f2f2c7f29ccd45e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e302678aa16a3c88bc89d5a812abd0b5f22e33f8a65ce56ed9a08c8c9f3b963a6d87f343bb435af7b8ee44b0c2439000000000000000000000000000000000078bab275c87423fc7f9d0327d543f66d15c1c9847ea4cc60a0f5cc4f1fc4555e86638f8563addcca236ddd2f998a9f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8d4a91ba9603d51104a6a47ac02a2eb4ef6535a1b3395d6f4a11e2c62afda1be2342850f74b316be6c957fb2c6d9400000000000000000000000000000000010c5b48fcf1f6a832046b11befbb89fe9729391caf395ce7f38be6188f55259e0c414e2e4783290c2d2c8a534f9a68161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182af9fa2929fb2298438a3d9512493c7089f11677a68260947bc9a624fa2b8ea1e4a9e08c288ff4b2f383f8a122dff90000000000000000000000000000000016d28fba47fddc65af954c02dfc5d9cdddfb3f9b0d6652639fe86e919c3207dd06426042c92c6ff480e195e405d743391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c975adf0433578398db50f567a97e27b17e89837dfe3f30cb6e220b810be1ff1aff1d192724d5ccc378c41026b26f70000000000000000000000000000000009e6540cd564d6a0d46627ef833d46c4df2cb4691069257fb068bd793f361a7992ee39314a37c148c26f4454fc4e6d8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000360c05b68d18819d5556c49149558e7b02814506e386d943789677c243c7a635f8a36d3d6ec465e0dc6769356813b5f0000000000000000000000000000000017139f82f4c15f64e8f1be020ceeecb0dacf0579094483ce84333bfecd267a7219cfc9e03bd148ddecd9419ff90feaab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d135883074547c37e5e92c929e510ffa66020c50ee332a77ecd27ad19cf379dd769a134ffa7e2f0886efd03a3630500000000000000000000000000000000198895a37464291134dd59ccadac7a8a550da6b4af64d991c465f007b2e287c9a7d84dc7b366a3b57414f5b74a9593e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086b9e3b72ed9ffdbda1c87c9d84349c6648a028ba4be9fbabf02e3ca28d6ecf64ed3a5d435cd0d640857d63f82f3ecc000000000000000000000000000000000fe64c18a9b7813a3b71690607deb267436114fdb23524c2c3e078efa5dd774af32d1dd4f86eaa1f8cea26f06b6b98f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081bceb5b09db69aa9a6c89394828e3ea221afbb39ddac67b01fed5ec408901039226320b24acc501eb9668dc6ad0886000000000000000000000000000000000f86b25a356066e8f461047104efa13325493945a287fb7c1cd916b968d4f60257a534398bfda135090ba0687b74be1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b60efd3515eb74330c47b364aba0de8df518563a6042779f4bab35b3e3cd6071c70ea95e14ff4343d52777b493f113000000000000000000000000000000000fe88fbbd16a0d650bcd2e449cb45302d4f4a65fc4e6beda5b7dfe9d5c82cc562cc00fd0c6613655da131217ceda27f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cac4f34fe4cbaa792793dc0ad73f5f320ac9572e80d25cea8fb37fed59ad191e53d151ab94697952154e44e82ec60f0000000000000000000000000000000001c2def9f22510b9de82ec0bbfefe31a3d539539116eb62f0ddfa14dc85d8391387159a53215f7df86292215c0ddc5cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e952333968cbde29ab5432bde7428d24827a51ed37649811a9a702f238b676d7565d4a73ae761768411023d8b43cfc00000000000000000000000000000000074c7fab6efffaa74d4a5ffb6b389ec3d41acf99cfb03f0f9f262884353c4c8184440c720551dcde08db4d024a6fd3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181ebee92127b88fc3e45f1d4c113bd07a0c742dcb2ee7a5942c6e965bab8ec9e6fe0348bb8d96ae551c5cd2b6f00379000000000000000000000000000000000f6cc9b1665a1e7be035eb692f1d220d73b62655f3a2689a757890bc794db261d53c58e656c4213b369e10e03f56df171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016254205a057a86f4be8fbe0f13dcc0bf1826c5b587f143bd2ea7e7e1895dc99702a9029b5941ca7722e301f28b17b6c000000000000000000000000000000000ff97a0e49189b70f26b6a70ce316d450cca8d0f25da4c44d239d6d8605369ceacba152248855a76c1b6e104d44d27f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153205e65188decb59c780508f6d9659a4d341214138f414f367af6491baa85e5f8b0b863d211740a15a021149fa808700000000000000000000000000000000177bdd9a2b8fba59839a5e7f6d4c88ade9cb88f8aafd3c65bfff84f664a6fa2f69cb1acbe05abd2e4ae85e08160a79211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dae18aeeb8bd44ecf858046a9a737cb560db4a49dc72009192b348fa2c8e583138257cb294b28b47d3ee0c4e62d4f35000000000000000000000000000000000d4d7e883779ce0e3b2a33fb837cd908369fcf09de40f547792ab5555a413af9ac14ea2c23e22f3ebba4003bf356eec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebf7d3fee2894d17762ee6564e2105c0721c9543e3dc6103ebbf14b57b238e3211c7225b94a90cc4d72bbe8e1e0f580000000000000000000000000000000008ee85f223a1d131a4915e9bf09b400e5935c28bd08575612385e19c56064e1d8eeda5c62b4bf363240820d2cc1f49711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d35c4dec0125f2eab6caff93079a923fd2fc72e08088c258e02c429ede7653ea97cf8b8935ee254dc45cffcbd580b7000000000000000000000000000000000ec6c19d3d4801112c8b510bfd80c63c533e316f715b603692e7630a0bf6fa4ed246b6d81a259aed3f8bc79044d491391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147dfa0157cb13b4754101921c44ba948237b5113a4bf30587825598a00c10ab81c5106aea824211b55f494f95047d050000000000000000000000000000000018945753ba687426af1e26702e9c0cda4e96da4e269f745284d0ca188c60432fb7fb6740e1912053c04176b1006383b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d36c5fde7b87c4e21bbd395b6a77604cf7b5dbdb73fa99d2cfaf9099f9464839c11ba868f061b66b26e6e467aee7d00000000000000000000000000000000029059e464905e61c93a59d6e0112500306b5533bc5a99509806bfda9b99bb5b2f800094778c74ea110d700e0d22da631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a7379d9cc9211a9e81c57b5e0122a4f2b18277711db3e9e0c59fa8afecffd81afc23d56b4719de86c77588b41226d5000000000000000000000000000000000e99c9c166a36a813fc488c00d57a3f576b39954d0074f240dc7a5cd1103ee6c6ec515e80a69d41b2c98f3f0e5276aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e44a2b8cfb96138345fc79ff62df105ad53e9d2ebe94dd091bfeb320902128d3453e80c8b26f48fea29c06630704967000000000000000000000000000000000ee4155f63cba0d57cbb9c64e2470ebcab1e38857490063c737c05ee30c5bbef299ffe120d3dbc9f9c95ce4d0d95e2851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e8ee6b6db540c3d7bd0a84f50b4588237e7fa27ec1989af674d6d7de150dbeb16d96a9ce2134d512bd47e0b8303c07000000000000000000000000000000000ae06b55cc2f14404c03cbbe344499ceb69d9e1bb7a9f0747c09223aeb2804a4ace3b3ecdfd48608aa90c11cdd31fb201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db546943c02edfbc05886f781a85220ea3faffe1f740892dab37ba51d711675a5b7d5a686c3b13decfc0f02898abdd1000000000000000000000000000000000b4823ff38f91a33a7f906ed6f433c1893544de606b95cf7b969c08ad7596fd9b8c4931ce1117258456a7eb715202a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff950089c390ecaa4be7a475a1d8498bd52db0d9288025ced228be4a5c7d9b672c6200e24d7bc000061c1fca2fe8bf300000000000000000000000000000000039ec6c37294b5a6ef6e124adb86f9a1e44224b0a986ade2d6c66a1257d43a144cbf591fb9584b2e398cbaa5e485571a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001681c1a8efe90817e0352b115381258d5f860c7fe7cc2636b37c0254cbc18b1e06b3eebe0ec079aa1a9875a3a14fbb9f000000000000000000000000000000000744a25ee61d8917d232d0f5b680f94053ee94249e5aab6b895c7a63f14c0fe0bee7991832b790c42d4ca24ccb3063701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014673a362a7e58691db22038440b359c80e7a9c3089457f65e663a10ca248dda03df99a73da427f85c217f2b9e82b9d000000000000000000000000000000000090decce0b5d39cd91d6092f1d2684ed3a25d652898a58f462998dad13dc3509aeb4e6a93ad990d33a032e4a4b687e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f37d09bdb7575434bb7d8b81d8f4c7224fc69d861000ad95b00c9c4d96a0c03d1622c958cadb6278acf7c62b1b578c000000000000000000000000000000000658ed63a89a80b4d12592de824b695cafe884ac81cb096d5651c770ff854be188e7c4b4b6279f132f67260765ab57c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bd8020830748f5cbf7aa11d082f73b829e6a6a1e253d777957fcb7c69765581b5ee6feba52529c40a6d5fba578a5e8000000000000000000000000000000000d450a421b99895adb23e113b0dff1c79f4a9f477bb800d288a84f8a3d234e406f17669147aa83ddadfb80cff1be754b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654baed6e488143ec4867960d4346d90c28062be20b4deab24abcad9d707819ded944921129e090604cb1b6a34a85870000000000000000000000000000000019a22e7273bf6b64f58678b429b8b1f104102e0e9ead9ce2660e6a7610626c6f16015242a2d29919d36f518a1b353adc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdb2004cea1819d33d7c28c14a91e64cffc6a9c2836210483813c42b0621e3b7d56af8d72728e971153bfcdcfed2ff0000000000000000000000000000000001369d94d084f00b1d68a136428e11c659034e71216ad058ffb65759a9862ec21e0a763fedca6991c8d73e3266ca563931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6263bfc52a439bc68bdf6f38a105c455a0b5d0eb604b3116daf466a7bf9a61151f0499316dd792f56046629c5ae70900000000000000000000000000000000058406f8e3ddc48776e67a3666467a2b324c856d9b2ff04a3a179d07b0d2e935c5f4a4b976dc5559e7aa1450538f548f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de81224cd5f7789f5622b06c9cce12e7c242443468168f11ce98632ecc68644be3654413c54a6b07b405f6dcfabbb400000000000000000000000000000000184438db25d7bd4ba14f7577837f532c70a50c5b45e60adf175b40df28bd77ddc06062e9469f84e092ba1c1e4b42bf9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f84ef89ce7c6edb4b44f78fced7e2aee2d1121305aac0a2df912686dd263c3d6a59eda567d304967cd9bff970a18f6a0000000000000000000000000000000018b44e5c2e7eca64d221d8b8853a20f60cb029203d547fa56541d9e212361f82a6dada13163155eb524670265ff6dcd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006998500ac726d1fc5c31832a10266e232873543a7cf23e9b6a85ee41ef436b3c25feeb93e2e57dccaffcbd2c52c98fa0000000000000000000000000000000014edc9e79d6e17f0a196feb215e6b317d9ff074fa1f8a3be2d33364f4a44a752e5e2c344e6d8d239581dad316474a9ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b19e7db6ec5c82ae285f779629fa71aeca960b9d77d3ddcc0a7253e3661b20827a778acb2c8d2807ef87a9106c145100000000000000000000000000000000137ea0da2e655a86ebb40f78ed84cb51436158fcfb901edea8d3b88226bda84aa3cd7510ebbcc7fb871e9422a66a912a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003421b8c520449e2375f8163e0abadad80a6f6824d9a343f47503379a79a907b1c0a0051deae0b6d7546beebf4e118b8000000000000000000000000000000001722743e81ff6fd370d3d16240bb3492b4f6d9bd05500be9c0111309e7cfcebf550953dd3e8b69f68f9b4ea007e810cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c01aed49707be07b752b7eecc651d765f6c3dde5bf7d2d15d038aa5c4c86fd0e576f603e13050170bcfc7e9f9cd0074000000000000000000000000000000000c7eba29b7f8b7a2275f6a753060e345f7dc2bd8ee808a6f949b36ea3af38018bc5ef5ec17082a4f905612d87a8fc7191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000eb5caf92ec1e8ce05eaa246eb1b19f2c2973e85a2b65a1d866d9afe2fd532bb6aaa5c7225e3307a6d199048fbfd346000000000000000000000000000000000c089b9d16b9e1fdcc8cb8be316a85c7f81bbb31db542532ef0a60c7de9338f5800463de665d643b4265ff9cf9c37d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018550a0ac6c00bc0908de8b8b46cd090a3dd75634660dec25642f7fe87abdf726310ad892c54468ef68a214eb1ddcf30000000000000000000000000000000000e70c9fd778849a57b1d77406bb6c02a20991e6d497f64869ca8822ce16a6db992ead7a7dc6249020657a2fb7b54cf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001323fcaefe5e291403cc07a0407cfcd9b59e2d62e321e7359c778257de88f895143212248418269eab5a45a4235f2029000000000000000000000000000000001880f0ef888bfed9f284aedecdde018fc64f0fdad9bd75c9780c0ce3475faddacb623827e7f3f0ad2903a4fdeec0f2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d56a5807b826f8b5da96c78fe403ca1582988fba6b6d68643a77ff796d1771c2398a7ecdd38db8e77eae1730dfd248000000000000000000000000000000000111d78e1f8d2a2f2ba0f1a4272097d98f9a65be03b0f4c74f48d7fb581ab5bbc233db95ebd5475c11fb47094da3b811c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f845c4863bc39c257f89e133e200a5a6f9bec0f1277aafedd9da8e42749a922abe7ede0b95f6fea78e867e1c3d65a560000000000000000000000000000000004f9c3dd53b5cbd97a1fa5cf4e0fb39d815bde164530b7ad394fb7a474f11e57df7f598c4aa2a2ffcc2ba9f582a1832f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195bcfa7f6e92a6db605bc807c16d37e108fb53c93841f01d90ed188ec74babd08e511a277aac4a9e4ca5c9329d225380000000000000000000000000000000004dfed8033fc3968dc99e476232f3cf015052a87e7fbcda6f77c66e627543da9e7af7ab32d8f10a442442da09255ecfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9aaa41dd733fb0d2947c084eb636a8b12cc072a7b962f1f013072f713b936bfd9356b1fb02bb4e94e2efcf44491c950000000000000000000000000000000003c8b2cf351047a4511c1defda2fe5c66b3252ac440a188d5ca99616e589d21de9c56ffb6e2e691e5f3fae026c3d15ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018196f98b6f873906713e25f936aed219a7b040fe2b5765652cd1453ea1444ee116e8114a17045bda94b82ae1d14e8c50000000000000000000000000000000014c11a6dd7d70a53b7b8ef57b68afaa06c821ec1abaada6f3a8d7b9348fb38c97fd23de77c725704901aebae124633891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3be8b461344101cec2ad95490c85409af78a9d56cdc0a76560278973040a2954d90bf47ba69a8e38ba4fd0e6691e7f0000000000000000000000000000000012cf0251e68d3308c471ccd3d8b6fc919dcc70ff525729754c40cb73fb8d84693e9b6a1847a690853183ce42301a12081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a757b0063fdf78ec95ffbf93b97c28111053657b3276ec886fc75342ae5a54cc30e947aacc3206fcc06bf31e61f93a000000000000000000000000000000000950309f83b564d54ae193df4ffc000a74cda3189a8329663925bb73cd1757096ab5e2557795ccc6ede40995d8b4a20b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa73119e29e042a756c2eaef97c65b2087eaae3af35e6f21316056b7b896576f62a96cb42ce7de22daf863e6397e74f00000000000000000000000000000000100fcf4558f9f21f0e27dc7fa266e276db08864aee4556b9fd71938010cb5dde58e8e17e30a58dc5b177ff57236dd05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058cda6a99fe3a61fb7b3966f93c246ddb214c662d092ad624c69838c7b1e8957c82c2a94bb1035109eaa8b77aabf8aa000000000000000000000000000000000b626cd6fe7bc670df7c9941217cfd54cde93549b765cef6887d36407d12c2e75d3a23778e98b89ab0cde710589368a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ffd0b660874facb3349894390d02931f06654ce0132d951e888a3ccfcf48d9b50e670e2bf8aaa55eb471e4ad1ce80a0000000000000000000000000000000006fb52bab4a8df567f865785aa76a40c95d7a3bbceeb733c994d2d5c906d15e6563bb6eef412d2434019dc77f10d0e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090d37f7f7cb9454e6c6c4e5b32b04f5bb7abe2c548c954e0a5d3d2474ec900c0c6634568c981e102a3910b4bcd7ae09000000000000000000000000000000000f4c244fe24406770e84efa931f19020cf41cb2dea4e289e705c15096b1c150b76b3adc7c35d5fb6261c739f66c412bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001efe87332f2e970a2e7dc406096899daf01ffcdd8ba5b5876254bdea4dde852f42f24d315e27c1a1f02c13349cbfd17000000000000000000000000000000000b233923c24921a4e182ef9d9bccc4781d863c9dfa45dc6ca6eca4474cb467b67e5ae593ab93a2829c3116d202a81a2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aa3f76745a5a17681fc69dfed95f87a47795a37ac68e89a380317a2157d66c07d98f48363a135f7f2343ca13a8a0190000000000000000000000000000000002f7d4bbb0b25762fa1e670f206ed6b2d2fd0971760ac4913ded8a6b2e744811f9ea986fa54706764103ae69e0df2d171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e287477f127a13031865cc2cb5810df6bcf48fd6cd2e3c9f51c9e274ade5be4fbd02290d2fd64d80d64d6508e920180000000000000000000000000000000002c030c1bb7600a63cb879a999c86ee793052cabf2c34d0305d006eed0d88b8e807c4665ccfd162c502871f2e285ff2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117a4b8f5f51199cecd6cb7f26bbd94da77344164676c7720e56b7e8487adeb93e96bba98d919e68ad959dfc77a00626000000000000000000000000000000000f0a5903482513d6c42b55b9c70d7faafcecc95217bc62b1cc0117fc42916bbf314eefe22b3e69e4e305988e7b55731c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ada78096c2c59bc8dc24bdb7fec70c87ed8c274139f5e6dd141ee7d293204de560546ce5a4d817d175cbbe559e964ac0000000000000000000000000000000019d588facaa929d0ebb94bc08440e25670ca985eb148eadd143151407cf0703cb1abda2aa4c832598b8383b28cde1d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106bb1c9a751fe58361a83bf04898505bafb486c6f601e57bd3ff91d49061f91c5c7d6e5cc0b1d2c7603b91bbba8b306000000000000000000000000000000000d62258885339094c6ba81cc823df6f14b94cdbfd5c5334c7b5a01944dfd19ba97ee13dc41be72dacd9a4c4507f52b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfff4c4927eb8bc279b63b98e63aa4ea94d11cdd485078beaf75246a5eac706c7823a794b1bb1a125ac197b96a1bfd8000000000000000000000000000000000d11904384f429f44ac54c3cc980fd0ea1a5eaf94d41a32b0838b8e748a9eec524b9d498748d51f4dc7f4d5f1b088bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e3d31e0090f4f375f6057ea9260ac04b2cf6b5da10e0327793b621baa16b67cd67f5afbf7b3f38ba202294cbe1854a00000000000000000000000000000000000630c5e90f69cbcfaf17c151b71d44f7a430cd22586f6b7f436e878c2b5010d4029ffe4acb6820b6cf0107eda5b4651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138a20d57200124b381a9b7ea17d8e4fd82cfa596e3efde313313d28d68d37cb0736f4e9f1fbe1ab977d6caa6de7394100000000000000000000000000000000027b8244d19dca38b351c6d796c8d6189439ec8aac3aac523865bfc1bc7c0c201ff5b0a05d53c63f144802995c7f74ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006694a0c70f6d3e245d157cdd52c7d0e7cb6274db04b7f8ade197f68a13387b8ccb8290cea14047f523722e28fdbb08000000000000000000000000000000001726d95af877344456b2f2c053fd92251a96356012bc51a365bcef878301f56810abe425c82feef61060ed0dbf1c35311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066f6abc564621898361c5df6a4d2ecec002544372896237e967671981747e23d6b84d7da24f1cd71434843af6f19d7d000000000000000000000000000000000bd41dc2850bc17dedb123c14d4a505565a5202af653b5b30d7a8c0bb20917ba799e387abe1cc8bf55b3872994b57fdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000feb28be418692ed131339c3392e29c2d1e30eb34c11202b57f598abace6bfe22554548616c93f0e3a576125b9bc4e4d0000000000000000000000000000000013ea5f992dac7b82a9df4173203e2201f1b8a05f851462befe321eb83a3aea62d53ca8089c0c3588c484c519429e58e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093475f526633791d50a3ad6bb6dfb31864a924ed126830eb394963500494dd63eec3c73e99cc61b4a8fa44d261df2b70000000000000000000000000000000008a3098aad0646aba714b7fcb8fd862a115fdfa8935220c0944ed999774b2c0628ad4f9a10e4f8e54f0f6ad677c571b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147e63b348cffc21ff8ccf80fa91b680dbef325ecf0c37f68a7d0292305c8ca7beecf20244847f7ed0b31cd01ddd7e4c0000000000000000000000000000000016ca25d30933b25e3a1b5bae19b3c99423d9d39f7620456bdca480a2cc03638fe276d43efb36cd739b2ed4404d3b70c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019686d10d81dd91d945d77118a738c7026cff7f7ec8f183867acadd235bfa822c11df722a91f6982a663412fef2a1078000000000000000000000000000000000205386d7c022df1ef1a8ecbaf778382cf9b89e2472d4833f2a82b4bd330421a5f183aec4eddf3a6cac10f7046b097d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000822bd0d953f849069f198c6f2c57d81f657cf2070eee6b03625730587d2f790df245161ee35c91e75b6dff3fa8db488000000000000000000000000000000000e174c58799ee4d62e60e0f59bd199927942548f06f5ca3505165561194ac48752c43154e3778bce7f5df50858908a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6fa0780933322fedd45076a6b8ac764ce833686162d473fcd210d21693a762c7e07ae0a59b2a26deb56e98f7b938d3000000000000000000000000000000001585ad7dc6293bacee6ab52b71a7bcd9d4879096c03c446f7090b24755e67befc571fa275bc86ca130030774fa8eec461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a69f8534ac2c82c184894f659d223bce01c813cd9c6446da92f6a1681add3ef2eb41964d8c72baa0c6e57aeca19184b0000000000000000000000000000000018be90b9fb67dd1f3ef8da67535c8bdc226e58d5a1234ec46d229c5e291d8b0481dd6f8281021f2a4cd525505fba98f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a38216151b9037db9ce417bfb110a501f96579e3cf65b3ee00ac8274e032efb3380aca284b51822f3d0ee5323665910000000000000000000000000000000002429a98a8c541c213f7a0b9bcfcc0ae76ec243fce7243a0e3ab5a319458865de187752f06e2b32577cc9992357dc2d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f50898587dc3f9f6b633b65511e20abdff5152995554f9557694a29fa637752b996c6bbffeed64b63d1919df00644be0000000000000000000000000000000005368cd744cf84e869347c2796c1d0a08314c0fc0955d7514448c2ff967ca24a104de7296b351ec90f90b62d7fe1b41e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109c2c15358574cf99cd2a0b6e3df786feae5d2bea15459060dc052653fdc0f7db1e7f644b17cfe2cdc88a5319dca2c300000000000000000000000000000000199b1fa4a1a6db6232f860bd32089c6608e114f89f8752bde137363dcc90072d6e844e1579de413238a621cf46dc8e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126359d7ad7373b5a2099c0b11e027267578a8c54aee6831999a2404afdf46f6d327e1cd2470f53a0cd12249e22e31ff00000000000000000000000000000000091f71b271f3e7f4f2e5398064273bd28b4c8c36d8d19749ffb0afc9a4a35abc9466713d7b8e9fb7869661745668b2921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d6baf01617a330b5c0e723cfe7d355f259d3558028cdeeeadcc07beab4a8f4b9adfdd9c31015c2daccb177428d84900000000000000000000000000000000007fe48f8d3330f228b742e146cd5e94fb2a4bbd881e33438b15d79f2cdf15705e92d210ae8122b18115038290fe179901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001005c8fc3c58369968d65a12f90203f91e304e0f09c51db2c82a06acd3fcce96b9813ca4d55ea3d14464c7b1f03b0c550000000000000000000000000000000010a6359aa1c2202582afe05b52df0a78f98586d6c7f5ab1bfecd0a0705f6dfb8011399a568ee0ca123ce9ecd5c2c0c281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2dba33bc1c4ab9fb8300a9a66c308e4f4e939171f998f5bbc9958b1d3a892e608003aa26ac84270778fe9bd1998c65000000000000000000000000000000000da5cc256f2ebf9973e932db0fd6d72ab119232cc63a7e80d8f44e6d3212f0c955a01b4d89d23ef4fdcbce4e4bc323661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ad45352fdf06bd7dc1ce87309142200ae276a34ef084cbaec2bc8a168b4c3e3c01994b2d17c64e16834af2bce86dc40000000000000000000000000000000014fe3fdcf40ded42f2dbbac1172a4f2ef8db5338df69f4ae4fc9e3f6776c27d77264f275e97d46a89c6ec92b863504d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b238b26eca9b1b156356473581de6ccbe600f6ed9809669963efd9e5b683ed3669e6bcbceca3c74ba1c7f840d015e2d000000000000000000000000000000001128ae0585912592cf9b5144fdb08a0284274725e06ecb2c6d6db4919466715c823bc1fa1e77ac368d62d984ade366561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121e83dd10c9115eee656f89a7564f6d529eae87a64a898cf1e68e1e7e4629fa202bbe881b9493f1b306ae842b7c7eab0000000000000000000000000000000016a2feeb4276274f0f6f8d5352644004935c9030e6a0092483f28d23e9ca051290c5d11df3fcd25788b8cccd1905eb791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab46c7de183ee87d63d5de408e28dfa58466ffd9cdbef534db106b993224afaf7f27b4c948297ae65c6292ecd19c9cb000000000000000000000000000000000d5042690d0524de33d68d39c2602a0d35ec63fc4e4808708672111ce7035d8cec375b47c42bb477fd3dd52039248e411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d88024893aaa6bbcbd3cf1a4e0c55deeeeaeab60e31e151eb62eb8da022b96fac2a4bbfbcfd0b648b6067faa46b35a5000000000000000000000000000000000b427e8f7bc5dea9baa0a8f7b1cbb8fa9f642a2644b266a064c789b7acd486b3a0814294699c38644db097169819b74f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f42889caf073db3cf184c227ddae1cd0cace401edae3c1efb75b60ca8b3f1c46f0c235470b951bfebc18fd48b47c8ea00000000000000000000000000000000155e01e3e3258df3a20a431f36402731ad7291808a6507a6f37c1b7e0ec8095a5b5582911eea4ce270abd0aea5e3dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07c07905a272fa66dc12497f3592bfc2fb7578cd27545ef2fcc73eb43807b8b019285f9be9b92cda37bb3805c37d07000000000000000000000000000000000407edfd4ae2bcc499bd43a04c4435222c9638979ac8eb9aefc87235a93219f753710011f95a01d4de0332042a5cc3b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb3795f68bc388665d4e9532e2e79860bbedabc7db77acf2dc8c73eed24fa630c0d21bd1a0a44bbd0146cfad6bf167e0000000000000000000000000000000010bdd266acf71c79f27320da220d5a97b238f0be7052afd32d9785785e8382bac411597732bb647658fcb344bf73c5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086568078a77b456c68175fa5ce8e45d71af32f145696fcfaa48a48c64b46c667ec8080ab39cfa7a8c01de8ebf53210300000000000000000000000000000000122cda8d2dde160690622638b3d1b939cbec1e7dfe9fde774f8b3086e95e5444cf8e2356009363a3d20be756eccd6f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f2e6fc0f5ea0f0a752e3791ad26dacecd293e6a2623402dd75b736e88dde4fb1b3d306e9224314750e8c402ddeccdb0000000000000000000000000000000007ffc8775122e562570d879a6f0184ec9b22e85a0eb7bd6ff17b853fdaf1d7d095e14aae86a1065ab3f228cf691b489a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007654aeb4e7ec52af3f171996a3d903857be38682e6a2284967ab0c4d4c4475392576f0be00bbf8fec1ad731f276fc71000000000000000000000000000000000ff8bbc7f8c348e3399dc83b8f721e78b2610798191ac602d83cb1bf67e3f251be9321941d8d03a9b99dc1197c81edac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003487d000616ee9475c8d368dcd1f39e449f87267772dc76dc1f2f2e966392ed0f663f9a6bbbf0763c6240fe9edc186a0000000000000000000000000000000006bad4fe4f85b85559d7e1906d081fca82f9e2aa1be0abdb9d926711f15c219d5f101e68d43a938d520f0ad9ff58f1101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e4075841bf11b459904b5c37b27e6f1d7b23931dad18a9c381c875a56ccc3422037ad44af8936fefaaf908771676c200000000000000000000000000000000031115fe1467eeb33a89d6b4db05f4893d98cc5fa72b48e0cfa0493b13fc0f3af393b5bf79adf88c827152c2257f0eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d82a376057ce587a4bbee669589ad6b0bb685abbfc79c7f0bcd3abf64a9321b37db7aa4fac9c397008ccb20b934b3b400000000000000000000000000000000027a1d90ba72c6aa1f77bb666e73a953c6c461e0ce1777bbbff3463931404cf4f32cfe2344f17421213a66a4223870fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013237a815a5e3ec7f7bca6d4700a76b69b314356b6923dc4ef0c6046460239890bc87fe01509108c64ff52a17e67d52500000000000000000000000000000000081a70f4d256ac589d85a5884e346e45178e0782b0ccabba7626d775ea8e9def6b818502345f0453aa38f05173b1a7031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8d10eedf21dda2f003c9cf671b10c607e6c2ea4e5103d92ef0401d4a6783e89fb9b3e4f01c2f6cdb42dcf9140df6ac0000000000000000000000000000000003861554e6c33f66e7fe7cf5cf47a2da67b27f52ed3d9eed70c5c044022d1a826299eec62bc04a538ad10079de0c2ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000deb722b15709fc2b153b28f396bfbfb03fc64a6e0bd68472f6efaa27b0db7140b812085d385c0e5b60d64ed8143ac920000000000000000000000000000000019763e324e37dd02030460204157339b4c539e9884f23ec1a0d351d4a56b8cb85e05ba2dfe80caa7bc2cd075204bfffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc233f2fd0bf4a89415dbf94f4c67b3e59997a4b59caa56ab6b769a6994eef21be40a54705a9c0c05ae4c805d2437b60000000000000000000000000000000001935ff5db947e299e140dc7be1ca334dbc69e2ad5f8387a5e151d6cda96d52b388c44a6e515d1b581ed5d2ee8d74cd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e2f66835cabdb01ceee27528914d0f52820a1cd0a562d9fa953196cfb0c19f1864d7ab9b5cb128b6378caf6d0da5f9000000000000000000000000000000000597ed5c9ba5738781848b3ad3cd771a4c80a51f7f1ba9610f3c3814699f56db7e42b4c2c44181aed1af7db04f203d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a15e6e1eda7dfe5b8cfe7409c5d5c1ec9d9d5af490ecc3fc5782ce61856a974c6b4771eb6a0af53a8cc3344050bd682000000000000000000000000000000000b7226444d71a04a35d3fa17db43207b8fe84230829802f45755f65a08a3f3102914c0bf92180b68c3835828f46cb4621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b22a41232cd2cc3ec669b39028c918aa6ae5c5eefa26db673f57b79dd1ad2ad49bc20f31c955f98e54b920bd00c9240000000000000000000000000000000001e700ff144fd4939b405fab8884ecdc70c936deeb112830af7f84ca02e1470d3608e1d173b1330b4360071a00107f5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a5bf3dd1ecdc1012f3c481dce96878c626c28df1fb55d400504e78d0c6e8b00281c9533527645d2cda17bdccc5ff7c0000000000000000000000000000000004c71650d0fcef16ae357880aaa4294ffb2cadba82e3ebf85d8805b78381e1c22e5721285c758e1af8073fe3fb6696691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ce57889917275107b3280e368a4bffb3fbe0edf43896d4f06467668ee0bed164bf1c1ddb2460fe8c1856646a0444a00000000000000000000000000000000141ea944c806798ca3e0053f0dc803ae1f0be4b33de805df15f3f77701a427d6a0d6d715b883f4dd9058de46631844751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1189e9fc194b8706fa5fef300127173797c25e66adabc890c6a3b9cf69e17d116059fbd3651b65b42a781c60376dbe000000000000000000000000000000000b32e512e679859bdb77347e5c4cbac0a012b3588d1a5f23f3e93e382980fb0dcb3e87dcd8903dd4520c4248cde6deef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2a6c8e7154d99083cd030d33ab62a49a2102728da81e9d3f7658580ca4a081f09e5458470a9b2e486baf3cbddc0670000000000000000000000000000000008ba2f0e681788a626582411810613007e5ffa8aabc59d2cf6490d5c0b20d83b30ef199b90413d7700aeb22506de30331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c34322f59e563a9930cf326432a05ec367e798b60ce0a2c30742c1ec7c6577ff34ef947be16cbce439dda9450bfb889000000000000000000000000000000000c24b3663dc3207de95a1eb68255db233ebae57fadd264f89849e402a7759091fcad7c412a8b7baae323ffa30a126ecf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe19ab1e5d4a56a50efd379e6584d0e8930cad4e3474e09c024a419f038eac2e7e0b5122c1fb656b2af4aa47506af890000000000000000000000000000000019de0fc118a1034c1594a93b4a94a16d83e85c5e86942acf5c510d691ba6f07943f8894caa5222c35a73d4fb2296049a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256c2970f1d3281c924021e28c23b92d16c3edffb5e91c776ddbfbe2b70780ef599db181d779e16d449b536cf0ecacc0000000000000000000000000000000001277bf7af6c983d78f706f80df9d2bb3c98a669cdf4a98080bb82bf1557d636b7a8bf73d3770f9c77c656c75e4f4f241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172da28a357d85aff8c4697a491a6ff89ad38ef354c8efedbcd540f2564422e63f552a4aeb9db7f181780912383851d000000000000000000000000000000000567fb0b6180b034f1a0e4f198f7d5b8bfdb97874fc1e2b90cf5af58fd8413ba629e0e0f18e5a4f1edce7dfa36bda4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099063041d603e5897c5f476e859ab16c2e6ffda6eeb94151b38a2318b3555bdf2e2a7394e7dccf9c4144bd07f3729e0000000000000000000000000000000010dfa4b89c516004d7d62790113ee600bfc928a35b01d8a1a574b4e9d6435ce4c9129dc8dc8cce90ad9715a0125ff23e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c1404fa874f10a413bca4ae3a7d733eaeeeb889269a288291b311477d340c6b4213acfaba5d564aed893f50d4f5553000000000000000000000000000000001182dc1752dd419cf886dafc064487827479c613f293e2d13b7713485a26040aacdbd4f6c10d52afb87c5b66fcb5603e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a78b7070d2d7fa909605acea77ef2b290333005affdc1e481c535f722fcfa46375184bf7666ae542829e2e8fcedeea0000000000000000000000000000000014e281ba8d5bc5c78a5b66beb6d434196e7d17a271725096634f509d9512ddc9d4cbf7f3fdc4036e22fe5cd252cd95d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001093e2461d8a5ad955114c2f697fadcdd8aff026992772fd3e99d58508ae8e47d19a634223119531f05649133953406d00000000000000000000000000000000053a42632c7cfb4c03fb8932e791ce20bccf1f7c3ced2315295df758c3cd2bc022a3ee747204aff9af4d8e4011aabfba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019974bf48595b51f32ffaf0dc2dd84787006dedbe1e2ad41d048fe2e8cb16a9d56236b330ecb9762f26d839e4a90d5ae000000000000000000000000000000000ce8570f60e75ca375ef870fe6f3578770b2d4e569370427ef92be0e91f0d0a5a392f1d3dc1d6ed6cffd72e82e7f90ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db0d517e5c950bedffe2d40a6308ebc100725cb42264831bef4b9dcd784bb5458a241efd19e7997bdaf4a0e414bad34000000000000000000000000000000000cc1b0f5a2985d3aae15715c4ccdc976f4616a75775b648ca66b736eb32c49b89c51510ec7e956223cb41ccf2c182da61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cefd2fdd7c5e83eb0d88a306c99d25b158904af490f208fdcaffab3a791992c3d0b2351f138628b26ed8d7d56af3100000000000000000000000000000000003c132aa33a08bc45414439ada47c3583c15638f52dc7652fd9b8376556ddd24aebfe9135b84b6c14a63737d8f12b51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff291d4949878be7f95de509546378dc070d30868e62a063aa949ceb075d662544c76c0feb895d6190e3c04f7a9ac7d0000000000000000000000000000000019e70d82ca0fc26a7e67371b04f00b9c2a86152a24b5ec2a7de2c20d08f264154ead7fd184fc3b9131a5412bb6f75ec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019960bbb5468f21ac685f85b358a57bd2a69edbe3ca1737525e821f66ad199f202d4329d929c1e83fd0216d6c33f12b600000000000000000000000000000000098f5dca3489f126f3e0bcc2ddbdefa40217fb68672f35b1ebfe60687f43d1de5e23f61d31fa3fdeaa6384753111cc4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7766d0889887313d07230171e6e5022145f44f36fe33d0b8a3434846859ea7b20ebd97a5d6cd5b7238192bcc13c973000000000000000000000000000000001265c1dfd5579a1535418b54388a9069cd02dc17c76243a1feac210ea2088498e93d897472510120bdbcaace5cc1cc6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ed4a3b00f0a3c1dc4435ba743fb6a22f9feec147dab90132b007acc5eeadae614059e25815cdd3d85a79fbadfc136a00000000000000000000000000000000065a62f36f3c831c1eb7d49ccc73f75ebb07325f5429a1bc6e2d9f0cfa4c84b3c445d5a5beaa9e5cf99a0b47e7a4e9541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000634ead49eb6ebb2e8f5e7b0ec0e31b35636311008d7ef681e904e7254ae9bd77160e52f7403c51cf0d0dc3e6a05ddaf00000000000000000000000000000000164382c9ee86014182f05ecc51f8550ba9a54767449bd46e454d6fe958b30cd791d85033af3fc1bea8f679fcb268a9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019e389bb7aaa7b247eab69d15c7fb45143680e7b8d50b99e653412e191c394ebe95e00ca44ba561e2b8fc8085fcf250000000000000000000000000000000000000c86704ed1787ecb09bde8fcf39bdf32b079159ad8d115b7bf2021bb221e9efef9ebd8e0f3e48343a1e483ca55d9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8efb5c4232c9cbf2e6097486af882265ec77f6ab99fdcc089eb47f1aae78df24194a134cb653a82f7cd539ea2c49f7000000000000000000000000000000000de73cf8fefa9693da1413bdcec80a67ab152a7d04551a874f7f09ab8fe811505a1d288d03383dc78830c6f8175e9b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000997c6eacea3040961f397e9d7b926622ec6fd8aa2273a1b06601f200cfee161c67c8f1ec5548f5b6444abd92510a42d00000000000000000000000000000000184f187ed44ede857103850892a9fbfd159df4f244b028b8677d508c5b3a8715788d52e823b223b6e080f488dc2aa47d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f0e5ea83a26d3eca34593b23b98b7446ac3db8dbacf6f3105da5ead1346b77ae018337529f27bcee8bf1be0a39d4e20000000000000000000000000000000007adebf2875a9bb5e31c2ef7a5a5e8fd81537e9d973a3021e0c21a1222a21dee370f854e2b54178d63c5dd9af50185d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001518f5bed56ba6b4f14d82a03b862a96c2225f667c9bc6e1854fb641ba7b9d848254fede9550cca69c1a6ab248e5fcec000000000000000000000000000000000ba06f813d3351c927063b98be4880750363c0be3c6a0966992c92429754661a390f029681514f374f0ea92f63046ffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ab613611e2aa6b0058d7defe6048c5b2256a1740375535a7f0c676fe22cbf423acfd41800761488c2ece257fe4b9ed000000000000000000000000000000000f13537e306672a1fc3bc747337dfd8f05c79fcdeae09055b01ffa24e01b41c5e5989f92eaf165ce6c23b44bf65cba541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041aba18b9097a7d418a7f94b395a9a639f4ac1520206acf40643be3c2ede5471080d7b0adbe66e72b76ab820e8133930000000000000000000000000000000015f88f9b0ffd52c5f16b73f41d2329197164188a953ce00325e9782ac61e6aaf3c518064cf72618fed264360a922c02c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015416730835d00f6a73c8b991837ffa64d7180ba9228761fc476792499815b02c314132e096425fb925557339187898000000000000000000000000000000000535a4b5ffbbf0ca186ebe63992a0b2133671b3da481d254c1ba7ad1652fb983fc9dec7a7d0089d224c10c765d58e3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009634a8eb38c02db736aab937c76ee5c11121c62bf72b6c2866dfddeccdd4691e553602fb370e22d476434b52d0aa2b800000000000000000000000000000000136abc1167988604aafae182612eed96276b0a01fd89b193b39c1be4ba96db4dcec77be8cd08bd9247a4522ff025bf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066330f2a929479e8348bcf6d84ff66170a9d422d2fd383a19a5ed1dd68dc6666575692907e2f2f124453af168de60f0000000000000000000000000000000017c18768c5396de8d31d59fc110827f9da2b34218bf22e20274ebce2ab6e68226c860f05b70c57cbc32ecea1af4397fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa94e57139d0de69e4cf53abae4a95e063bf6b255fb5932a008b91fec9b22372b838ec19fd9001465e4af0943896dc300000000000000000000000000000000155f42b375b107b0fb63b4174a3c8793361c547728b8ffb72b6d5b88b0dee2598fbfcf4419b628dbfd620420794578cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dabb8fd32b3883b92cdb90e9571b7884cbce9a58dcf5787908462f91a31fe3a6a15724312eda31aa681a7ee399e29a00000000000000000000000000000000151afd2fd79423db99c5593cc08848e6cb763bf242172d3db0efdb5166b0ffebfba675b54f9f68e8d22f27b9fadc79e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63372e22a5cd64f4f062d06572ae39096a1a07174ac19f232bf697573cb584615e24dc1dc86218da2cbd8786de5f65000000000000000000000000000000000feee06c2a979dfb4ca65744d0560bbe44ebf8e3e69c2b4eafe6fc139d8e3bee0b8b2e63d07a8ac6386433fe84080ae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030dff2f81392463171b028ca0d65be238270dc698f7506dfc03a5fb85083aa8ab4d36512c48a5206782bf61588958390000000000000000000000000000000014e9e8b11d2864d8cb52548664096f6c66860d703cce4fa33cd3dee9769438eafc076effd3dd4ebb15179dd15bc490b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bb59ec2c9d94d4c4ecc13a0e696dcd3f3adf5f5532a9301845bd312d69f8f39d571e919b287ae2bc36dff77da7ff1000000000000000000000000000000000060440f8df400cf3167622473828693a195a738f1a44c7109b0452b4d9a67948e4ae20d29c5302b40fdebb36815810081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3fd2164530eab3e5f472b7735a2c7e01c0a420ff2840a8d804dacd72fdba1669032fe81f99c0332fbaf75bdf9c1ee7000000000000000000000000000000000c82eb91810bd698f12ac69967dd7b87b4d5ff608a31de60be216dfc6f1aacec953e31e181410328f8782b4999ac8d571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177379f0dc18965beda800ca6e301c63da209d916b1c889b883a1b29cef25fb4d6c6438b5ff4b4ced401736c273d2ce80000000000000000000000000000000000cec7a90c631febef2ce24e31230ce992a681eb23496fd93a50b8861064a4b24608e457096d6269cca80efc03c887f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed4aceea3b2ee55ff68e4fe9746f149ba2c5981326dad5c13185f957f06678c8a261df1f8c63fd6b20681df948d950c000000000000000000000000000000000fac99d827225790ff8e07663eda1338d7a803cd66b59fe277c7141bbb08c05260661d65a5264ae663292a8b099ae2db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75a45c913711db9ba536c9cf8658fa595f1bda7f6a5554b7dcde3a0d4d25510c9e9de43ae7e8946cafcda848f06a5a000000000000000000000000000000000c8528f8521d85b5e436bd468737728ffb1e899bf6c23c55621c4e9dff3ee61d96647ea78037648e9a22acfcc1020c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f318e7dbbb9cd760e5fc35b2478672b8d2fad15cc9adf693df34badb2946ffb6d3e86caf6417d3f7ba25fc42c5722d00000000000000000000000000000000100d3fa8bae4dfb2d034e2a3b0969341a1faf489242d6f2c76e8168e0b29a6947d54c380d6daa9977a9292f11ced44851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d08a3968fcbe9ead2525d33f241d3dc18b96938635c865a7eb131c7a02d8f1b91afc1bac4cd56fc7e684556863729100000000000000000000000000000000186f2b3ef13d6155604f0b3688d45433a015b74f2fb433b67890c3db18d4f0e45779a8c90eaa7a80a47e91e30b24d0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0c3f818495ea31b0a3d1a96a40b719918135635af754a60bbed0b46c530daa3b93aaba4943c7819b8053068c35ba0a000000000000000000000000000000000106223b96c9dd22adca5e4afa82b7a6cb2ce9a6e330457d906ecd9bb0ee797bf7e48b08ad3e6e932a69b99b114499d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a561fe4d2dcfc355bfd5ad27139e0ce9dc674acd93d45f95b327fd6bb69ce6c639532be11f194937bbf7f7e6994e20000000000000000000000000000000001912584c9547827f30872cfed22f71fbad7cf7143f688760e5f1cd31d592911049c5e5837993eb8796519402f02b14631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049c1bf2f8e56b9183f6197192fe1eb7ef959d1c5e36b8fd15fe2781ffd55a2d349e61d4b88ffcdfd4798d3bf484b244000000000000000000000000000000000b541f34ad6903c3ca39841bbbc6c8281bc7ebb4fc9a8705e5611f99d9cd26aef92a5ce7c813fd808871ece11307dbe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007027179eb19707db1c1aaf7e0c9133e001ca4e56fa99037f2921b8e9c693ce8c296d475ca72f41469e9eb19ad6ca8fd000000000000000000000000000000000556fe5659cb436b31d36f932561f1714e5adbf4bc024eda16797083b396060cd1f09019f2a7b7af275835d47f7706b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006efa9179042688509e9d23287860e72f30c1ce3ca48588704514dac04b10636c3134e94ee61f4beb743837bfd3a29bb0000000000000000000000000000000004f316185decfaf0b9124fc4c259f99da4db36ae4078b0ac9864c9a7dd35b5e89652cdc801337cf85eb469b6c12babc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e25b734ec2e99adde2d526f066f24fca155f8f7cdcd4a9a5db08ad829c88d80ab4e65419c0f293a7d58606798ff21700000000000000000000000000000000060f0173bff2ff4e6f2ccb5a310b6bbeb3f0c18c6b94c257c535ce630a8e710b701705f4164959c82c43adc4e1ecf09c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a4117fc6b8168b2c12aca408e73d7fe0f7afcd14f7d523f22ef5856a32331231c149dd81ddd2ff3e1092c6da45e640000000000000000000000000000000017d6704a1b1fea5acc3737cbeeda45d90f4d6fb413b94c5377901ecaa357a56ce6bd97e1aed5afe26e48dca75fbded3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a940c99dc5e54ca122f58f34986625b9210f52979cab92bc82b635490353c0407a0ef5b7d7059859cf64ff8cfe55aaf000000000000000000000000000000001177c395dc36fd2560f9c436838df13e974fd4297abd5f9a4d5dd2af248a8a5ef25871e1025ee3b808c54e7e12e25fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018149936252740d0d055405d64ca9bd4d9c870d9e3dfe685f9a130a6e146781771135b593c5f3464c115a108502e66620000000000000000000000000000000007218be7287e285039960f216befd156f97d3a1ec24641b3f34fc02cc95d79c9313ae518d40dcd6735a66d4c12ad79c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020ab889381564aa46716797f5969cdc1d30a26cb3d9eeb97b79f0e908ef993a239f64e24f46a1390286b598b4eb0b9b000000000000000000000000000000000b8d7e3b488fd9be95f29f6fb613c26f5ef03fd2d851c6cb5c6398f525bad462a965d6b1ba4802534b8f5eb8b449d85b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001525d3e059a650a0e9bc15ec3145812d7c016925d533a52dce34c002d22b7a0027e51087110f2070a9aab4798c5fc3650000000000000000000000000000000004e7d8dd2e2bd3bb69ba0143583a431cd735fdeb125cefa5920c596d9dcd4bf93945e3583b8cc7d6ab4f08518ea787cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000971952c8e833dc062bf77f984aacc2983bc4ebba185016bc1e3e8f3edfe513f697def1e4aefd9f222cb07a53a88a8d0000000000000000000000000000000016ee349783d8d2d7b54ba219e7ac022cad0bcdf6319e2f8350918a5737bb4e65f54e2bbc59925e744405d5dbcbc1f15f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e29a226240ab824efdb457530aa96ec26b695e039d1eafc1f095cac437037e6a4059312559fe7c92e73199fe37744c5000000000000000000000000000000000313b97bfdb19419cca53eda4cba2d69c584c26052964bce3c1dbe8147af2d85f291bb612c01bd53b782c2d2f962337c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189dc3add19429bc8ac496e689e3907b22e37eba37c269364c7b8108b5f808fad08c5342bf1e6f03fe9d5e56372303a00000000000000000000000000000000016842f33d676a90cd97158b164d20bff847bf30e32fc81173fbcfb26b2225bae27d4cdeada9cb6b4bd4226a151078b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f5d4689535e796487eb644424174656e83447094596212c65e043885f04cf3922122b74abe191dfb1a4ce973250760000000000000000000000000000000000e88f8655a2e80b6edbc334de91a445295e86bcf54e0538969b63ec16b6a679b16b95b36618e7efc00bc96447801c17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e8243821d60f65c9f2450cc6b2092f0b55b772feb6a8e2b85e91c831e5d0f86fd211276208cdd0da61709e3cf323ba0000000000000000000000000000000003b58b493a8a23a55057218d0f061a3a2315e4343dc2bb6d6e8c4ae524a2e98e5fdfcb7d073f9d3cbb6fc85a28a5c6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc4c1bf00fc3a7cc9f4bb5b3666b83e52af8435898294b95e41d9a4ac2a1772dbe9e84fffc1b3d728366227aeb30a6400000000000000000000000000000000107c70581ba81fac1fedbb6cc9d5cea8589b0a0cfff3935a03a9b184cbe5710038f2a57b9f008ee2326613674b2730841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5af4f9275cf99153e66def661b20a6d672cc84b9d2a96b067dff0958d55c3aebd0f2644a60473bc546a0991bd06b080000000000000000000000000000000004c5cc7cacdc2ac28be8941adbf10cd3b74b56c6e888a662e71349560010568b867909742cfb85a3c13b1d9ce01fe0071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc6925e522b2ef65c416e4b1d4449673c7993dc973bae4952741105f308633fa5b18debdb815bef33cfe1113e5c6ca00000000000000000000000000000000038fd4ab5281a35e3d79c3107818c49dea6fbef4dca22ae438766e1443bb203046cfbdeacdc3474fee6e7d03394a72ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c0c715f844ae036d4cfe846c34d73a4898f0b3d2fe69717b4b758a6dad9f79339ba81a75f4710357ff415577ff0d4e00000000000000000000000000000000116047d57b155338326509f9be0997ccc48c99d998d001a48e262da616555c4afa08cbeeb10f746526910ddb57d13b971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001429935c5293fa437649ebffd00887bab438fe3973c95be362bf8a1f0cda12b780f896363c9d4fbcbdf7d4eb312ca779000000000000000000000000000000000f612adb430c2ae67de06a0f4e821d5249e526ff41ce6f7c858f8dd27b13eeab906da8d98d0285dbf919882c905d258e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f191d3f9d0d62bf213aa857b0965f9967d88c4b2f48c29de55046fb9cbdceb61c6dd6a2d57bc864bb309587b9cfa4680000000000000000000000000000000010879d82acb829655193394521fc47c1137d7e70af414318f056593e820e009fcdcb9c38d75f3ddaa8cb8ada5108ebd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecc78a4fc8b222edea873e10b13d7c26aff6d4d86b77f179b8b435db73e17c04afe0ab7dd74e11d77f02a8ffde0c49c000000000000000000000000000000000becab1ad811a19f8f88a1afb8a7ee7823b668d5ff7684d9a07208079b2adabaf29a229cbecbe9d0b2ffa3e34535fb811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003237663189a911367bcf8e4a362f06489a1f9ba513b27a88813263d07be4188bbe07bb12a04c6b6b86e5d8a80debf380000000000000000000000000000000017512fc5588b0b16703a13b5f238554245e08974ac65e0b46eae57c97b10a33b8bc01f104a35991ee46c5f3654efad361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3a8b25f4d88936f7acf6043abab1759e959f55311557c7a836c55720c98960389b61ba150d13cfdc30ba35a4f99c0f0000000000000000000000000000000017378fe4ba3bf430802dc9c2e623c959ffbfe172d72d16f27f68d35b7208862d1a3d8ba191c99e9a82bdb2f30535e64d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001570f57cc254e36e731bbc311b2cdef5e97da51de84b1c7ef4164ed3f17135150a1071913a76708c0a791436853fb12200000000000000000000000000000000170967ca2fd04661709942fc2c5da6bc45e15d2f989d45ed952b80c2a38e5cbf339f376c955f996ac77e9ae38150627a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d64140311922b1c7d05e3f9ac1a68370741ac824daab2aecac3114ba3d7768f6e904606575d6cb406895c5bf910675a0000000000000000000000000000000003d8231c081a57e41cc491db7eeafe9e11e7e1e2adb022f9d9b76de45cd8820e25c91c6d302144506c2c65632aae2f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8145957c7bd5a110bf0667091e3d16895204dc123f70d801472a47c3d9ac2d9b11f93fd44a0a74555b3f5704be7b060000000000000000000000000000000016ae910428b0aabc6a499d945569c91e1029a4309a85635bf22144c415161d976706bd3e673f44e74a5fdb0ecc428d701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f103336b40a5e4bfe7a86a03832b414f8957935aa4316b0161572166fce5602ebe8a0d5284dc6c818fe3dc0f3833b310000000000000000000000000000000012f8f7920ea770844cb6cf798c6f9d1a3abb921b3478d4f1802df36a3c101df1e28d2af09a1091d9d49f6c6a0ba85da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8c8be082d2f02513e7c2fc6ac032d058ac42bb2b614daff4583a4a16b4fe7661bba02a8464dbb9d9191b42cd6ebf4000000000000000000000000000000000070dcd6d034d13cb546cbfeb6f323b60ed11dd115ad9d3061c47e33da9c9d4ddc042026175bdb34720a5a92f59554f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6139d00a7990ca91d42d933e0d39312ad7fdeb0c0496e9ea3edeae7d4854e531b28e0c912003c1177d0792c5cd8de0000000000000000000000000000000006a6a795f27bd4a36e9aea91ce07a1173edcbce6dab347a574d4fc96661aedf57cbfcc161847be6b6d94074dd53fc5ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010180f42d688c0c489efda991939402af807458b88b354bd416dae7356ae3ad06cd537139ec423c6bcbadb475ddc69c1000000000000000000000000000000001519f82f9cf0d1e4ec8e94347b6e577007893a18603474a269cf1e84769fa624f1d989411d2c51849b0c27e583f967051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001780930da219a98e2ec2c5725d25d6fb7b48241cddd375f4edf99bc930fea4b31bee4f0c8902f7ee30c69238cca0eec30000000000000000000000000000000018ee1e93d7e926ce942a074958a2fbf037cfd77ace27c28bf32b7775854c99d6f4a8de698e9384653f2dede6b0ed1c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4dce78121515816f56beee2fb3595f855335183641a1a83188360edb3cdd6cab6f70c2f7b4f2887d489e733c9afa1a0000000000000000000000000000000015bfe06b7874ac5ed0c1a624ed5b90fd1be6dbdc56f7ce09e6613cd8636e8e11449283831e1e76a40027baaba2c5a45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005775ee6ffe0e01e022c29c495dd242c24f4f4913d0127515e00b867241e179be8f2d0819761a8400e511425c45aa6b0000000000000000000000000000000006473c74d045c7117f06561bd1140679b32d72fcdb1de45b89a4fb363e3d1c4e5e857572e45cc603b5a9576847896bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d830d7cae29ca19634ad3985bcf7db786056c5aa538faa430d7102fe02982833a72ca079c237f7884fffe99ff903e70000000000000000000000000000000014b93dca69343921b7d9029d728eaf61862f1e9920eb7e29c48a7344a10548ddb0f98e5bd70628e062e5d54045d647021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba27fc8c0187a6493ed63f3e8c2ede5162f081c3dc048b03f918f1649ac03c33c25c9df6fb2135bbd863bcf8747d698000000000000000000000000000000000aaa7017d58aa7195b882a55bfdc605acf9bda927c02274566e9ef13b462223f9aa3e9d46a8e3a431c96b9ee7546d78a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd824860d22e2b3b504a3fb82bbe47d8e097465c0c729b1334153f046cf2c6229656dbc18439e3112b34047343d9cc1000000000000000000000000000000000faa6e919fa2e1da3b07827ba50b0539f2033b3063446a45e6d9cdeaea79bb9e1b8fd76f8801ed2b7579822efca7f1151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ffb9a1e0d2a5498aef2e2a5e5fbdc96f9ae5fddad805cbefc680b9c54e716990d2e22ed279073ea8d4dcbc9d100e5a0000000000000000000000000000000000429a53efa704d50cef9369168119d5e45b5bfd332c695b1a6b266b3cbc8ef32b09201b5591349ab738a0a2fea0049c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203c563003c6c2b9991a0151543af6a2959246d3b4e7f5a022893da096635c9dc5c06c42354941784b4756f511caa080000000000000000000000000000000002627a8a781c5b9b94805fe697583ac5e2c8144159636444fbab072e838092fca0fb629007a835abba5a9ac3fc69e7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197c0077825f2f746fa96dcab0fc15edbc5cc54a9cc35c13d2c7537cf8ac036c8d271dbc02886e440fab5db2442d0b3300000000000000000000000000000000004bdfb575d8fa2df5732248968f6b931dec26d44a253bb49bbaa4dc597aefb4b80589c2f533ea7926d9d107ebf0d53d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046f44a0d34b12b1d34bad1e529b353bfa77b2efbe07408676b478046f1ea5e17543dbd85aacf6ffba5b0086c3425afe000000000000000000000000000000000e69a770acef6f33f7eb8eecadf6dc36e138f9748f9e605e4114c7d38ff99c382bd88bb46daaceeb5783affa6d7b9d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176279f374709d54c734e3f9a959c44f05d1e5f4edba9f71978f9c83e2f4e16df1f25f0e2e57479656dc680148e2edde000000000000000000000000000000000283c900f4e975952f17e991a1ca5c52808477e3d977a3bf13e36069f9aba8201f5162869089e4a2ce7c08c4f410d3491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e691d39f7243df71f8c1026c5ebdf10de560dc97cf6c18d98be14aacebde4b5300c0413d341a35c4b70f80f1b2a80a00000000000000000000000000000000013559ed6d49e132c6a187b2d1529ee933943150ca06e831986ef42ed9adc1a6dc2f144142ec2bc2808587198a0e31521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce95aef2a54ecda3198ff02574087c9bf92c10c8906de477213f3a78540ccb71e1ab7b4bf1299f9da12228a635d5890000000000000000000000000000000014f204cb272acb217192f6ad6dda7c9a67298ce3bda3fb6b1ab6b67ce85409e8ce85fc16db4412640f5f04b8fbd304ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2c68cde8682dfb11edd9fdd808e0e0ec244a38d8405f321787a394183fdc8167a38b98efa09714ff4180d0d68322f60000000000000000000000000000000011611269d6415e6e6f12fc2836039270298a85dd71c8cfac124f5063afb6244e5f8a8c787de6e31b02a9aec12855e2b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209d1c4ed9d48a3ba2802bac42385e0c2e0995a6e6b79e884a3dee5928e1bec92fe7609b85661935e90b6e040a6fdb900000000000000000000000000000000082d7e49eec113e8ee9ad0481124ed851f6716fc76a328772e1d574d1fd8259b4d55c7f16f117608507611b95310d0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bce6a14f3f9aa1617e070c59a2ea042566e7de7b7b54a6c7483760f2d1e65ed32185cb3a773731658a6ea213a8a2af000000000000000000000000000000000a9b55ec566f54c48bba45c542d26fe96a27cef40160e8ae30ed78e1b9ef981353b641a2236d90108b5f040fcf3c1dab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088271a97d9862bd8cefc2f46460db3eb9efe5390c85be6fa134a0b776186c314566118a50060cb0e97c5954c0ada84c000000000000000000000000000000000baa89a5b1adf8c9252c6402886475930cc512e90255484dbbc0b6b496b94ffa4d9a56e2410a52420a0fe5d4dbdeca171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fec849aa99f886b10160940bb32d9742ff883d779650eebed55eabc65502d2d131fa67924797a7a69eae77a0b70ffb000000000000000000000000000000001286bcb2a8d390d11b9adf4e0246312959ac0b2d4f6bcaea8813520d98520bf64754d9b951e396c396d26180b26eadf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081d1e61f7b729454c857fab50c88e4c3138744122c7a1c859e4ba53e08c0e169727743774ee5c304de27bdda7298611000000000000000000000000000000000640e0953ff8f5b4d18e48378b38eb7676c1ef76e4e59368e3236786ce8b41412b012045de3d62e432164bf46430a5581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328ded122b64e9e361013c0195371cc6828c02c0004a64ac59be363120d066d8043df7e01ba2cab2e5d39c48cd84194000000000000000000000000000000000bf7ac9d8653a29abc833925385799b2730a0d60ef3105e24362441eba84bb989e8c34c6ae07abca17707993faf235e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c72178cadea50c8187cfb2dfc5101b9de0681893e600894b2606f89df36b2f07058bebc3eae92720ea357d26fcc088800000000000000000000000000000000164392bfc933b930860b9387d30f9e0c7a766d5bc344f78022820d7fe787fee302ae86abad7788be77344d522b26afbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e2b16dddcbb96405e2902948a9c1a43043f9691e85b9bed9aad21d34a4dba0cf9c55d39b7296e724f16cd2c5cb3c000000000000000000000000000000000142bf02e017597bd511e06b487d06cf0520bd876f4fbfb7039d7fb48158e207ded3c2165b6bed6e026ee391f65eb0ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000548de52ecca447c99f5141191b1b197be036ba301521b8b290a4f59b3b69a210bee8cbb507ef2a6f6870206f8f1c22900000000000000000000000000000000163dc7a8aa6da9f591e3dc6b948959465daf5bebdd43e5d4077941f4e6131dd99c6d42b8b3f87d09baf0d1cc9b1a4ec01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000291b8ca871827f12a5d72b48b1fd1b968bc47778a5fe6cb03b9a7b6815dd0dba61ac23818d5ae7a5d49af5f6d759b8f000000000000000000000000000000000d2480252da7ca4bc7c012de367191a98fb11e5cab773bcfa8557f4860bf9f1b64bb8c9e929d99662f6784873a48adce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fdb2a9ee343a9cb7a182d8d3b7052f8ef5e6de5ecc7466088acb414b9f802dfa3f05b81c2483ab05d67a1dfa8c0a990000000000000000000000000000000019e20d34df29e82a9d975b22261c760f4e0672c8743e87d28d5520690e157d3cf59fd0e8a240c57757f8e1c9566502ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005751cf80da8e8cca7df46a8428f9097bfab5e5f0e0f595639ed8bcbf30f2b4abfbb80c0176906de72d8951c4e5d9cd90000000000000000000000000000000008420eb88b545e81c6e5a185dcb85b31d2033e88448e43f73b3bc684cf5b6d6373d5b43d4c12aa6851a4ff2126c9fe851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad421edbe9880d5e68cec5149f6fb5003d7d8459977f5693e0c67c48e581a1adc132f51fb8a154120389e3a9f7fed4e000000000000000000000000000000000c1053d04108227803efcda6628f9e0caa12f5c47399f4e234694221d42194f7a2371167983bfedabd5291a915f53cb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123d6d50ac169978b431a9340ef4f2ff444c523eeff810b591a112f00742caf342c4d0e768b9bee37bf4f478360699700000000000000000000000000000000003ac5c383a20d4230268dc6798377d650c1d104b0d2031807aac7b3796ceb188f824a2b09477b64f3df9d6ac2359711b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005599de85996a8a483097821ad74664104f9f7644b9e6a04a7ea38e2f77bb084d21ca42f5ac8a924e12490bdf5ac166a000000000000000000000000000000000982550b4beb9c7bd1eb29c5937164d48657f9aab8586d12fedeb93f8aaa3dbda3ebc5385059d945d7ad13653687c0c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009587eec77f1181f7254c285a1054173f96bf31fccda6b346c5b62d28b1cbf3dc94a2fb0b5744134902265765758ee9f000000000000000000000000000000000f4f0b05595948af5d149e626142b870f629acee64cccb49d48178b005dd0b34cf78a1ba17fbe8df7d90682cc9b141c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c4d598bd2adddbb39e56c67d3d2240ef186e85b1da7788da5108ccdbe88c986578be858f37a8c2673de3e07c6f555300000000000000000000000000000000131fa148a96d927f804cf17b1650d8903d86a2f7cb358932e4e6c54c495aea83af42326df88d9a9f12437708bc3faf7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa3ffceb84e17696533b4f840d391520e58437becbced77ed6b4e77c7d889853e002b1aa1990df303f99e19aa7c2f1a000000000000000000000000000000000499d6cd4d219d9bf3c4ea0221367a6e35461a98d1654c6fbcde89a87255b023aedc8d4c33b5c19628d10ed5e7e534801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018589ca729ab6e409a481ba2caeca0f03ad813c60d10f4c4c54b171878572d4ee27058e3573f1858c098e6dfe49a56680000000000000000000000000000000019a01342142c17bfd9e93c79aa2ed19ae2c93138aa7cf2dde2477a69b0414561787d6eab81af52dfa503a17a91b5e3c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000faf3972d161782b825240a4a3f3da53791cf6a91d271573898200440e3cb2afe17aa97f63dbb94d63501dd618638e8b0000000000000000000000000000000014f574f394d5a3796d7e8b5e9604d6ef7312570a4fd06f6a732509ab45f733f61b127a6a6388442a5f4971e7407325951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d939610a281fd0860ce69854ffd33ebb0996ce1965a17e092931afd10392ab29eebb8dba7a035542f8a8560b47186100000000000000000000000000000000005af71d93dfeafa875e8017983300aff491dcf0d6aaf5f73ea0ae32749661e0afa5aa2860daa1681d2beed8e8ecdec221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c2a8b293b6337edaefbc7be9cd4f259ff6cfe50fd5fda89d20a8c4557447b8d77a5fb21d2cd52d96b2ce3691d96a5f0000000000000000000000000000000013ade3fa55465eb5541e50b0bc4e1c892c3ac581e6ebe9ae56b021ced02b22183dc8716bb75a8d1855cc07bf2dff25bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cba6107005b6099711bc9bed98497f5c182a91002a687df39717b3e3c23e69cc355d9e60f518970cde7b3a1a4e71ba0000000000000000000000000000000011cce2ef545f432e4f6f5d17140dfe06dce150bbe201d72a99057c9e40ee927005394060f2820229ce7b33462e7c10331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139205c3454955864c3a3a363ee0a9091eec9db14f0380da3ab1f25f3fb631a2c7ce870300a021ff2612730382fdcf800000000000000000000000000000000014933b7753b6164103f6b9569b48a5730c885ca1336683e26e891aa351fd4f970f874573fcfdf1bd4ff329dce58f25801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e2d3f93faf40b1358297b2122f8361e935b16184fd8e7aaa9bfb4e8a6818bc5ba4c849f95a43cf5665d6f850a19a1f000000000000000000000000000000000033407979c761acbf3a62288984a201d7d72d8c18509e5bc0d2881fcd49a9866ec473f48ff62e66fcff3df1376fb7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af88d3a1d0eeec8ddd8c7462efbc3b5945c9d7c0b1123e93157075d08b3a4670893b0770fa3a2fcae6848dac75306dd0000000000000000000000000000000007948fa4475392917f5ea70e5452d04ac9893ede9e6b3001a6e05e0e621b674b4f7b146f10f6b63981f9549773bb45911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137e0efa3254eb3a3000199f398812303a06eea470a04e356801c5d65e32f5bbd377f1a21c63236b06bd12f4cce5a77f0000000000000000000000000000000013c9a58a37007499dee3cd29704ed70105be2485f7808163c24b2b0441da9057b70232275e239c4b93ccfc4b735673c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073afed6fba90e89b8fe7b76e88b7bf32aba394e8afc2ac2c26a60f8b6b3c983e139a09411db918c6dcc67ab41535aab00000000000000000000000000000000032ee4015c21aefdb4bd54bb9329d2b439d508b5ed81327ff50e078457d1b3acfd432c7afc1ac9bc1d06a803cae561c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ca86402d3d96bf010b8c20702e0dbc2cea2e390ebab92e1577b8f9f2bcfc7dc488bdf949e9d19f18a6b9608a8fc27000000000000000000000000000000000a6e260aa93469aee078b525d7c2cd7675f1df85d73bd3237a3f8621618b0960ec67c48e4c6b747fa83bf820a4b066a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b9b59de96a11aa3aafdfb514afd1581f084deef380f583adca8d72147de1fbd528cd7b7d8a92a5ea3e84e4fc19a07d00000000000000000000000000000000083bda6ff113393623c7920459c44c3969c093bc95cfac9d0771ce20d24b7593549b8434bc7d52b554d60c2c1780d6f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004b99bfb772f179b630b7d58a7d41cbb50affe56c8d01006b69c9d9d82e44e9017185cc013244cb4c6f666d220e5b0a000000000000000000000000000000000eb0b3272f4d1ef13118c58ad148dd0db76d763bdb297654dc490fb19ed863db791511afa15222924a7b25845ba8b6f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df44f54f3a59a00498116f05b8213aa8b25bbb52104c8f2b47c9ae43a7f41e56207763356138f04683bd576db76805100000000000000000000000000000000079eecf398ba66a9f4dd742e143fd582c5b645c6e1e1234adb83fc7367dc60ca0b17451366dc23751d1ba1450f77d1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfc699574aedbd91f87e819962e1f7c0a7317989ad46d70fef8012ebe7ef9df464437eb36dc4e09d195f3487b5da08a000000000000000000000000000000000844961b01e1c64e2cf6485792444cc3b0308ab3fe474310f51de4f2272831203106fbcefd104bc19168e6b2f3bb55bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001815cf6212abe48ab721af502e10e717b7f83a616268d47e200f16ff61f8f67d4f781cdf4399c33be0081e7680b8f1f20000000000000000000000000000000005980ba4a63904adade55258cd974dc0748a3ab8462e1f847ef976be395a90c0368dccedd3bb8af84c6eb36b5e0eb19d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001656dccd663a762c675a68ff982f5b3668a9d92e550cd2c363b4283f2e6f73736fd183e3f0193d89feea581fa1b52eff0000000000000000000000000000000003f7706bf2ae3dc41fbba3bec3fe4e55591f95275b09b368529bf67e029aee6cbf9273870ea19f9e01ebd768fe3b6cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000539851a23d0b050838f4de937debc50e6c4b0e6bd995e7c66fdc5991dd7751513b0e617400ddef77cde37f9779e35560000000000000000000000000000000002559c00ee457064fe79a3af80ef8ae4f9ecd367630b2ad20e0538641c2a4c2d8775105fa325f6d2f4df33944fe5d0551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168d60b7d339edab24f476abfe56d89798b4a676a6e213cbee6e184f35ae7cad9a38eacb9e2bf31b7e5d35a09e49a891000000000000000000000000000000000dfd17233d1825e25f915d2028501729f930f56d794dda6a625ded2b868db9fa28170329510b2f09cdd4d9546db3afdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fac4bbf7fab9c06ddd2e3a1db9557eb6fc57a7a4fceb3ecfd2c187567c3971e88e9f59b5db4271e30ea98c1a20003300000000000000000000000000000000019e602f1be4f6d2debc494738d7fa03d17397007b121a866329061e5b1a16a6bc92580a7cce31fa2234a16d6a25ae671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78fcff232c30fe19bd991d7976df11693e636f7078402923ac0d2832a8901f5f167c49a6fb27e5712da659026ec17c00000000000000000000000000000000047e7a0b05e778d4dd3da7bc6b93ace745bad9cb8e7ad0c81c180a54458942ed8a15a85c4bd69a96ef55377300c391081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc205ddb7d7bc7dc559e04badf1867b6318b59d2d5a658e00737117a68f5100e7053143083980d7a64be5437711c9a0000000000000000000000000000000015ce9e3e939adf5b21672647ab24bcf3a4fbbf0b891929fb2d69df95de858c97f0007c5c343d70ea4a44c8f45eef77fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf8a66f5a33843a2c3828b168c7bff11115c2f2bd9c4c99671f1d69f1b3de0d3f2e51342785235fd93d720c54867d38000000000000000000000000000000000f899f8fdd2012d3ac16ea2f88121f5413de84b9f3a6b6d01ce515745a8b6b9aaaddd3a7c43856c6ee7233786fd4cec31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001514f463f246a6e60e6c474bd81ecea4b0ff546376697b185ba344c0ee35e9d4c91281389783ddfd7ceaf5169adc31f70000000000000000000000000000000009e1da9e83daf8b6843c7f068207a3fb4d690c9d11a87640e76ae1e0a99f623da0ffc0c25a5e8561b253eb11babc86d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061289606cf4508cf60bf8a54b31a73b754a5dfb954c2cc784f8b21650b33b81dde4f7f0086e781e739cb40643743551000000000000000000000000000000000eb3b1be290b7cd5528ceab57b7e869ec5177236aa6ea7acf36bff08580126dd20c7b4a60aa658931c3c18c9c5e6e4d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162f37ae71771963148d957b24dfdd48cec9c7b4c2a37ea6603d8abdc3024b4b2603ec88ab1ab00e254986a507bc0658000000000000000000000000000000000755e615de6bae0ed175302aeade00c188357c48541b34d924ffd4f91dcffc14173e9065b16d8668e1f473a09dfab9d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051826f8c438c628b5490049d2f6f89af48e612a6600e326d021ea0c3a6ae326d74fe7d58337f439f325f8971d20ee7800000000000000000000000000000000124583402dbd30381e3965f53eef4afa7b2c4331e0c4f63cec2d6fa0169121482c6d0596796b65befe506142ea797fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eee34b82ddd8e94aefc50317cbb3a4e36c472f3912ccd0e3b36b407dce8dce7a0b859a11c64bc4c721529bb7aed2474000000000000000000000000000000000991497bd267f64eee46309f123e787c42bab9c9ad9f5a9caa870c038810f9f69fd385479a61ecabc8a6c1909c535b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014da3405b1945c2241810e1ea8ab77f87bd0915e1658a7d9511a0433c4175c6599ab40d3bc378c4965965a95544c89b7000000000000000000000000000000001915b0babe5fbd3ca5b26aabb7f32fbd3ee907b33eb3ec9f2c8e1e69b481693f9bfc6c54a4fc097ffdcc58a55b8400b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017598c3be22425b1088094223a52aecb58dbf20f4efc308d136fea338d491be3403392dd23faba2fe18d677998f348e0000000000000000000000000000000000f74484ca3b6d26157d506c18eb5632869829dcce3deed4f7a56eb20b50ce045df1d62d98ddf49e27424860917d7b00e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008061f9895d7252366b94f471d609ddcf7be76cc738891415f637685495d8567d4cfebb64e83f0db9408833023ed0ff50000000000000000000000000000000004305111db5ec3aa8f3f93468c05a49105258d470d97a74175064503f45537156fc561049b19fb9bb04daf067843274c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096811e723c0c8a84cbf55d6059b226acd6d72266101dab905bfce75ce8061d1abdb2e005a43ecf9132664de226ad80e00000000000000000000000000000000087f639c68ed49140c385d039df1030df31e88d764f60559cabbd79ce8f4b025f7dc48fa24b74720b01b09228ffd9a171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b891ee25885a493ac307b65048e56ca63d1b5598ed2b5939ae3cfc8c66cba3f817709ce25345e779f961cdf0a2ee5fd000000000000000000000000000000000b30c7106a9af3367b2d930fa591c530dcc55ae27972af7f3ad3ff8c6e4bc3fd97ad0b97374d74b14649eb39f6929ce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000403066292d808988f3dcf9c9aa8f8ad1e44be7cbddd7035409a052798e81a14003da88d3a0e245b653163de98f5024000000000000000000000000000000000148fddb2dc717c114441b5d4c4d726a4c20516167ed358a477b52c859c9dbcd30a0e75aeb9f98023333041a919320d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9b22a0e6da44e9cb98a7e5b130ad79aad8810c3da48cc5a847bbc433272ca4b2e144c222fbcee65c1d0a3866b169fc00000000000000000000000000000000122b7d314fa335cdc989efebe2cf053aa7433a038418dc2c19cd516f51b34535b86f1db4a4ad11c4d554702dfe550c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0150998231a77baa936b34e49ff55f8029d730d5767edfcbd246fe21b69c42538bb4ba5d9561235ee9912aa418f8ca0000000000000000000000000000000003f46a3a9e26096496b777d182acd4c8d44acb377d5446f7d1ecfe9474bf7c39921bfdab64cf5c97abed9448a65645361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cf6bd0d88a1f258601b4fe8cdf52ea6036552e7ddc2e6fd77e9cea0911309c9e25fc008d06d64cbb5fac386ecfc1d90000000000000000000000000000000014880d3cb9a7411cfd2024957d25d3ac470e456f2e5d8d364bffcf6083d79d279ae1ee86ece82a1823d07e9595437f9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9b7ba393fa8df0a2b411d579cf678898a94fde779979f04b3267996f44fca9d5ca38da51ef08c04a392714f486c0600000000000000000000000000000000113700383f13ceb2660ef8743eb7abbaad2716a1be071ec772f6ba487bed1456e75c471fb15c089cdd532d300ed18f5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d837df5d9f0e613d32306e28ce89115f759e7d240900aff4897279518e3c1e380c121b3befba68afa3f5ba2c010f2cd0000000000000000000000000000000019fb5931d75918b9cdb8d160062e6518ffa5a1ce7ea9d44236827a398461c3eecd24e8b5cf0af3203b4ff925e43767a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001754ea272b55f1f84bd26ed7c4c9f2d762b994702e2125c8922130436c32d487d49865ab1b3fd7f12b7183bba80443ee0000000000000000000000000000000004f5b02aef4f388ee06e2a75039702b8e27f3e4b553ee9a4352ea416c4542f9d514e15828a68f3196cde2aae58cf522c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e866afc2bd4fa398dcacf70526fbad1688c13a2774e5f14878a9f017e90b3d3842f23f401f7311702f668354095350000000000000000000000000000000009b4b00708d45d23a302959e822e223c1265fd44116461dc5067c189f18e28255bc8116dac4fa1c05471b4e9a1f7ce4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000487ded1892222f3436118b1afac98396e9b10a7f155a0d7cc34ac10bd5767265415ba9a6b2fe7c696aec2fa6f7609c00000000000000000000000000000000010b6ddd853a62be08605673ddbba0d252b5a71f3f7bfe2080de1bab1a5dfe0546b1cfa1e25957868186038b255de02c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000496792b5bbd7bafcd4550275ba8a2264c1e72f7ed75f5fd575ba1e8553e7ee0ed81eab32ca109d345bf644689a9bd72000000000000000000000000000000001230e2fce42d1db5cab8ee196281ad2f27b9c7e0bb5f229289fb3a92dc97f62ea7dc5fd626c2dc3fc3fe51b12081c1231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd6c26b91b488ea47d5673cba4296e3440fce5ac4af4bd2e40714ca6963dd75f6eea2812a18e54640d86684450fd3da00000000000000000000000000000000125c3fd4e97ff08fc77f5cc97604658de8d65e6190de0f198fd9e77d0a30e47e94546ca1f7beefa175448eba56b1bfd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650c506b76c6daad95237c6bc1bd2cb2885236b2adfa9893bdde46e2094e9e843c74effd553e1dac5570687a4f71cb00000000000000000000000000000000011b6df2fa0c78ab4c85581a1448b2fe6ac64b1e508440393de858332332e33658fd827fb49357c2909a3b7b89df5345b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008475e6b3318d6753898545ebb2c14984921bc2619e4da3893b5aa2756e8b5a2ace3c3741f6af7ab4fc88b59cb5955950000000000000000000000000000000015dca7693ec6237e668533f762241c5e5c7eb9f708fe5fbbd0975611d61317d943ad037bb204a344efd6b802b8e65b451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144535a8545179b4d4d5df14a5c2f0b76bea627a9769132fcbde55992c60db28920fd753a2c5314abab8d7312f8d71990000000000000000000000000000000019d62c386ff41b693682f33405116724673b0a54d46d3ee69a65d396cc78c7dd796d494c9d2e07095ddb15d1e3fd75581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038d11c89f3cf902da1789b5c0e4af17be06ae4a92ab2ad4242cdf8646f40059335036cd341f6fc9a189dce4b220d11100000000000000000000000000000000029571a79b876e320c343eb1119d83e7be9338ae1892ebe20c73487ef108c102effca463e35898f0cb0ac52d121655e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057fbfdd25c687fa77c73fbc1f008416f9a62731ace70f5729b5af47ce05b0c64747e449d01da358dab6c4f02a23f4b000000000000000000000000000000000f5cdab136e727256b5bd420ef3e7c30204a99c8c62845355addf490e9d9c2ea0fc7ca7b01d8458c0cc86bbb741a9a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ed5869874efb400f03c498fef99116c3b28e12557b3bb51d29d551367713d5f325fda3ea89c1973e513b3f86223e99000000000000000000000000000000000d160cb2c59efe900fb63c7462950f7a327ee5ff240a5efc50f73107f1c67ac89d43770f5de1ce04bc5ad057de20a07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001efce793a14da04cf1a3222909c3288e6f4ebd4ec9f0a2f7f3443b852c5aa07f5576112a5f9c25f6ba317eb0bd3ea6900000000000000000000000000000000176b2ad174ff7892581742cf796c215473a4fedcd158b0989f1a1f1c0c084f135dab34af261bd4f91af06aaa96f18b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f81c1c170f51ee6faf51b42a1de67e70e0b94f4d7253849075fc00a73d379b9e6e8b1283d869819bb324d09894ff86a00000000000000000000000000000000197fdb4ed1bc23c2a88466851f1c6ac2ecdb73961301f5e9c12aab65e99e89f93b6e751f063896b713d38c763269c5e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e15ac0d229f2b72259eb0cfb8d69525145a2402efbc62db47f868693b1792e7b79be101dd1c1573fb9d8e1af02463c0000000000000000000000000000000018be7a48bc39215fba39f4663923b20bc356b81d0cf95575eb9c6b7ecd9c4d0c1f6c1cd2f2e59931a2fef1aeb12db1611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9ba03ec1d161db3a85c97e698ab778097416b8a07ca72cd3765d7b7a5640516f95652183e82601f5a754aa566e6ecf000000000000000000000000000000000b7ecf4a64f298427828662e74e72d12b8147a58ad58f8f451ca0b23f08a10a00a78d184525ea7bf1d7b24f111ad63561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89ed91190a40514b6fab8c51fb6435639b3368b0ea1ba8456805b79cb3dc7b2cb92422d6b5028df66e3aa1cd5b5e400000000000000000000000000000000013213692bf65ba4d4300cf4b851e41ef0cda01c024f0cc7c427fa4d498fa7ac2b5721fcc1cb09e09799f5f42863fda091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000787797e2b4bd823198db3aaa4094980824745480cf994a0fd92e6d378cd17c430e7a112c8b98d58e718ce31b04ce755000000000000000000000000000000000e960940bdf423e33a0d938d0801b97c9944479ba95b1c0774a5ca3a961b69455595e3ac4e44a057babae6ab351669ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017db727b514457379b014e4b23f03f1abcd26b18e5f73111960ff006d2014a73d1c629d98e102abee5fa3ca3a2325b13000000000000000000000000000000000c3ddfd751eff5351a598e4079523f546f46a924fd8f460b861efd0f28ecdaf974562a22c7d7572f36377fde37dc323d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a08b93e6076ff874cc85bc44eafd9771c05daa4d2b09ec6403a87a8e0744fa6430f44de839906c2654b39ac6d9ee4e000000000000000000000000000000000d58ae6c088af5f55c6b1f42c0b1ff53f47f8742957802137ca8011bea7ef7c6fbf9cfd2f241eda72aa49c3f6756f70d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018cefa58ab523810741df2a4df5422dd408a358208ee707a1ab117e0cef38095398672a580cc37679ec5cb5faed8cea0000000000000000000000000000000007f83f91d0d2509f08867e6bd962312234ae85dc6e6d351b82ae6fb1c0e887b170c5841c4a22b8355b97c15292d6263f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139f241da3f51c87632a68ce74035b89676c1c40754ce75f8f529fc9911fc54415a66645a0667fcf482accd6808dd35c000000000000000000000000000000000041723167febd59f57498506d1dc8d4ffe4edc2acbf4bd494a736b3209d7922b7f950f95f7e0b7f35dd4f135ab2783f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001860f8165e50339f9172aa696876cf38e2acc8528e3941f881778622901449fef5d7ba73d475d87dad0c1a1f4ac912ae00000000000000000000000000000000129b43ba963a3c07533b9796b35a0209cda3b6ca7d27278225e8a89e430a5762e16c93093b91bc67eb3fa8cf7f1e6fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d424f1c83119a794e7e67618afac4d63ed157349bbdbd09ef00192a5e08154bae6fcf3e47c4ee27049db48cf48a6c70000000000000000000000000000000013212caff92bd1dafab11780ff771cbdc2e69037c44406f9cfc4ee87f08b7facdff8c273d74c24b3dbae274362aea8151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccaba1e8ef4a3b0abf960f54132f3e8c3a1fab95aa3030d89ff4601fe430dbad57d79e767cb1f51c8f979b49dab2320000000000000000000000000000000014cc0b2d1919fa5a2faaa42f8e1e9430421e589ec7f65a5400c1b4138b205d9cb330902b7f742d5f5f9cbfdfa528fe601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ffed6f20e3b7e2d6ba8d9e5043e505233567385a5d2dec90f84dfafd6014819c7b7ffdd7a649ce9a9c763577e4eee10000000000000000000000000000000004fd48f6e9797ca0411a1232a29c7fc4fa276caf6d24a4efc2959510f681817ec39d8950b856bc30ffa28d03b421f20d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c194a1c97da407a0e4ff5d07341ec988ee2fd5b4687b412fd1bd4b6836866a4b116729741094463dbea603b13efc770000000000000000000000000000000019ab98311307a8dafd88e74411f74b2536cf554c9a8944e0cdc83fa5e128e312431e46a961ca31ebf18bcdea26b4a84f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113770393d9d51790b613d5c67baf7864dc6892c05ca5cc15895f4c9124768bf0714163684bdf5f17bd1a53c42ad95d30000000000000000000000000000000001cf48a7f7d2cef5d3fad15101c3acb59a80fe07ccfab8dddb6ef51c3c68ec93c389b4ebd005fd329c1aaeaf0371a30a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136db71a46c7eee425d3f32947ec9847828d42a0d70b7628b8895b42f6bb7a74f3235eed4b857ad2f5990ab7d3ccce0c0000000000000000000000000000000008f0b00c9f15f50d774814ec0521014e978dadf0827cccf4a455976177432adbed2ade223fb766621164f6ea6f26c6361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008562699819e683da8b504311d2a0f50f8c98ec7edbf5cd94a651cb91583ee74c25a2b7618faccde5b03659b8c4e1b30000000000000000000000000000000016022250c18f9eed5585e05ef26fd6b27056f23047bad590c2170f0f324484bb2afc113021edcf1e99c3d45a92644bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a52510c70eab373ac09c63c9a90936ea8a80906d37b19b0ed97f96e287db58a9dec8808af203814a1bece686f1d99500000000000000000000000000000000094452f6417ade2591770a9dfe1ff7cf0540aec514f24012d40b531950f394ed702c1da63299b1297fdd2614d5f1f33f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001135061c93bd08adefaad33aad54b02988dbaa688f00954b016f1d820a1c840ce78b39f9b2f517cbb0a4c45018d8982d000000000000000000000000000000000d91951db959af63ebcce05cc03999af80fded43335883b852dc142d15b12301b76b99884c5401accad73e67fbe0e9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176e05a68981e91d4f4d38118c7edcb486d8dc84897071b8cbcf3c64467ede53591d36251c56e8ea471b39e91d0321160000000000000000000000000000000002aded3bcdb23a13020647fe841645766166e0153d5e957d592b04356bcc81b8e3a0d00ca6db4c5079a3f559037a9b341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154a8cbfb8374e095bc27a8aa76cd8586b64983ebebafc317cff1db29d52a43725d8997699ccc3ffc04771cbdf1f56f00000000000000000000000000000000011310b05d105d4107a1c4be3187aa29598d9fe004b6fe2ea0c0cf9390dae53325ce9b07e6e33f1d63f01c21d02a637f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e114703b23697a172c6d7d9c9da4b067f0417d35f1075b0b953590e7df333cdc64dc802a2bba5025df1a610e40812e000000000000000000000000000000000d9facdb1b23eda1e538c8211ee7fdd4498e95de2f0b0a339875c72717f5c303701fb88259fccd5642fab59433c6636a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc8170f29e6b1adee45f1838930ce70760964ef7e891a9e638e2e23a1f97134d475b30ed5ea0a8cc1d5a9b96906c39000000000000000000000000000000001953828883297cc95372690a942e999c877aeaa658051a89890024e4b455617d3230c1beb16f015244480625f889f9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fa950d20442e100e7eab3b94a148cdeed7ab15b589a0dd3ad4be764ac6dbbbbdc4520dc3f80d1359526d16fabf885f0000000000000000000000000000000004971da5b246d65eee87e3b232cd50e14cdbd77d5538d470ab35e9f8b12026fc7ac994f29f126e1042253843b48e71d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec033f86bc013cbdf0971a9152712c2959fba12ddb51814b582db597a60eb025c4f7ce40a8bb0e4685d7c80a6790e2f0000000000000000000000000000000009247a927ec0af042420213300c1ce471e1005150306086cf7eeefcab14404a10c90fd1997da5149900bad7de4ad8ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b94f292345559998bd1c44787d75f34595fb75c829653a3a2fb03e4a4903c88cd66b3b20f9ad816f815d4f7294a5dc5000000000000000000000000000000000047e0ef23009f130f0403541547624f78a8adea913801f4ff083bda13577d7e2e273f8945c7bd8658e8f49103d3bc771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc4ec84146fe5042b3201d629fcd5295490b918fe02fa5f84ed7b809b48d11688ff30ea132e4ebfad0bc76ad1fb17f0000000000000000000000000000000013ae842a93d228eb585abf989c6004505b2cf19426ea27c13b07ad2f12f408982d6e7376c8401469f18a1866238f4dcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cac6a277d321f35378a9f046b308c98213209df49a426ca34fb1e43f50f7531a1a0a170029b4637b9be3437729549000000000000000000000000000000000169bb341cebc52396bd83c2ea7e6f4a8d72a84053167d5b2f229f77d7896190cb7d61ddea77ecfdaf9b7ed44a9e4d1d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004533816a243823e7b3475c2e63394ffea01089254b31e2f64661b10bc3717736bf099a0c0b1e6dbaddc0eafe325105000000000000000000000000000000000169eacc012f078c717f62a5bc67d6a014b7949439add5855459f4b66c5cb9a5b2e95812967f919d83dde78faa742b3671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557dcb5ad08de34382d56e0b611751e53e766003637c4d4f9b0d5d5f5e13fd2e6516eafaa1c0790671e5df2763bd283000000000000000000000000000000001805077c7e39d88e127a732eb738738006e271f21cfa4091127ff46343cae30d7cc24e7d61efa93c19fa802b34a40d231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003565c99b76ffb7cedda2e9ed43ed2b37c7417a464d060574739da488bcf35aa39d4d13027fd17029de1945523473c480000000000000000000000000000000006b9866b561a78eedb647c53cfb06100bf5ad627453cd0531e2a46c2ffaa9e0c17f4d46264dd79090fa982ece43e14b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000582202db870de45ebade9d081be109bed7e4de081ab169d416db6bb0e10d15880bf2d98b4d16afef1ccd2a8de4e1bc40000000000000000000000000000000004c8bce91b3a1f7768a81c3da81ec586f785562a361a5d189a3ee27203effff99496b695911d740dae0e008ff02c27761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8686bfb3b7b3a8cef9986d3a18f36cfa4e21f7e10c5b86206066a72f8ebbf4c5c26c3a9dc93d54e2827810ccd29a8000000000000000000000000000000000df2bb3c1fd2ab48009750e13e882563a35405a495dbf721e17d9effbfa3cfb44e034d3c2969fdf83f0d7451b8be93511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d2f8cc0c810619e137fa6721e57f80b5e8ebd1ea8524b942bef4f76927dd702d5b6edbd4f766b6c3acb190fba21c1000000000000000000000000000000000896f4afa5e8d9cc9b8f83cbd0593c9f1f927d023885c14df171f9675803be5636e46f82b43c0ab6645dc0ee5fc1cc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000085bc358cd6703ca2cd0a4ae1e29a763e49131aa7fc4c34528d3018f1a5a28407b82b81f355c560ccb0bbe651270b13000000000000000000000000000000000340fc1e89d4bfff8fc7ef363b4762fa710ca34e78212013ca2e18b910ed8959f8a7571db682f618e454910213a0586e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e85a3329ad8c8e8ea6b56f13b0ad1c1f807434178cc2e91195092cf3a0e41cbfad1d3dc9c5619df0c11b4928bd2b31000000000000000000000000000000001853fd0c2e3cb5c22f43b0a0ec8f427b11481ff306adabc8f1852e1e853aeb46cef65633e687ade694ccd19e1577ef371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016612bdc5823aa43f3a2231a6f9c091ced5ea2c00a6a9c532bee192e89a13ed0105cec809ccbbfb3c8c1604bbe0cd91c000000000000000000000000000000000756ffecefa1cda372a5297af63a448cb3303710b3c1545c52619f37f3822104eddac852bc1ab3310644b0dc5b8b498b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122f47200608d56ed78c98820b2100e67e490b1075c1e3eb0a2c6df40f4f0e33c3eaffc6750ccc82909f91ce43fb06940000000000000000000000000000000007031b4a578dc3f4a9b8c10d72d21830fad427e206fea4b99207720f78f045f8199667c7e14cb2c13e3beb079e821a7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152885db532cdb66d04941591f3d23ec04d902a73222e81d16c66083b0474037bd3ac68939ab91dbca03900ae637454300000000000000000000000000000000176007cd60937b1c554dc3777f9469103082bd22b0b86a77cb893f39e5a204a8707f05a92bbbcb905f14466a9e67bc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e87e587e2b33af1de6216eecbc6c96dad6b17fa38b7c58553d54790d09d95e1a3c8a39314c90a44a2ac48e2673dd300000000000000000000000000000000070164feff1a3112949129ecb1db8cb43d57f6c3f5680d04195442d35524c4ad17fd4c9a4a506f8d0f8eaf6a23e542551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cc3fb8b4629547602119596ef9af770c7f445ff2bbc05582119773d295400bec6e1012be1b41c1410c127acde07f0b0000000000000000000000000000000019a9aa5f45a437865b5d0031dd9915f8bb4c0660e841c0803ec595c50498c855e3a1c70cbefdab9a2c859f0cf8618cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000693644e99b13c150817d409b37e250e582651897ce03f284276d4cf287c38e09ee7788738887ae98ae260caaca899bd0000000000000000000000000000000002ed5d43c840b50a081c0105d8238a458a51ffefe2ab0b3ebbf595e13142d06b6e9e4b673507931f502ea7cccaf4cc861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ea1b1b72a50bed7cbab7fe55fc11ee5f80e82fd106350c52dbde9f3b49e68b381cd0abbf7d83de2e03c303ecf3a66d0000000000000000000000000000000002e92ab97b9316acc5a4cc46178467cbb154a35a99cb5a26568e8039261568f6f7a0b2291dc64cf440dbdbdd16f8d2351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f6d8bd01c8314989358d8df68097c15c16231d66745c2f6504f4714d84c4de68107dde79c8b2893ab2976f741ae365000000000000000000000000000000000b38f3a228a5baa59b850dfd24309b3a4207c7adeb29137b876b21975193a7cfc10036c504118451fb65cd004b398b8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aca3c9193b3138cd9085123e13e9b5c4a8cf675a4b82b5b451c91628a3310be4d25d44239c7aa926f6e951a132b9bdd000000000000000000000000000000001188604da73ce0a5a1436650e3832a3a9e9199ddd624eeb5df2ce55a85cb6efc835ef1d2de093bb5592da051d8fde07c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001971f1940887ee36e930f03d3b677f3939a04f752a86e5ecaf2c1a3583c972b3e685bbd6fb742fae1033f6bf9c3e6ab7000000000000000000000000000000000dd5ebe8b2afad2ccddfb036692cc3a2d72c9200b5d3330875619001279eb399259a68f6712f198db7af6249299a13f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000799b33022b3ee24eba812de4cf544cde7a6894c344b57ec009ee483de517b7fb2f75a2d064b884c94324895248e8fa50000000000000000000000000000000006d2f24a11717ac889a2bc5994044b4790b7283f4e3ade25f7b77fdf0348e0748a523e461aacbf425179bae7638cf42e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3e3a6eb82986691143dea394a278e6f8b2917dfbc627480f19de4b3670c96ac836b7c41fef928a7fd6f3fff4be6e010000000000000000000000000000000001bc33169713146d01730343d81ea32389ca34985329f6adc5a7028afedd3d910c2c15e62d94ea3a3c83ab9c40c1891b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002068c622d6cb619dd16b4b91be03e4f0aed364b4a1c59b72e200fecaa0021905c2ed79a5c3d5493d4d0bc7e529ee94600000000000000000000000000000000021bfe3633895b1ea954125429f21ac9e7ade2dd4ad9a9ae9f244b3b1c96da79122a27ef7b15d1e232bca3d25339b33e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133689379bd57980dcad88081295a0d12dc85ca7419d15d3e24bcfc8976ad35d2de3cbfddef279cfee23a8a727915a760000000000000000000000000000000001a4bff3854b5eb2656ebae8480d3a858e0e16716b26ced496579582c0faf99959b8a389192015f737cf04643d22b99d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9dda7c7b77b9fe1b474e47454cb4215d802e5ed72131e4411987c3e8f95be67dd3a89e040e83c99f01459e2c010cf60000000000000000000000000000000011e104658935c879b09ded57f73ee2761ebdfd5de0a1e4d0b927bd56b4d2841af62cf355bbee33910cadefe3dfeef4081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100f08a8d88078eefc8932a42edb66557690f5d2d54249f0776e487db611b02bd138cc927fb7e6cafc0081d603be20b2000000000000000000000000000000000d815119f67e920273c578fbc29318d4a9b93342096c14dc1de2256fe3efdc2525ec1f73f4c1addd8620040b14de13641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016870eb02ac057797f8a76b4780c48b886d22d49c0eb8f2ea605875e69a5d19e7ec8f7d91b3bfe404421750eb4baa38200000000000000000000000000000000172db71aa5c89e0f84889b51faf4814d54ea17216742e8f50916800e5cc2ffd78d060ee36d9cdc37c76feb6b6cf73b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a03bca64ab3966a3468ed1bad6fb6517434e373cdd1f0d2551716ecc067445dd314ef638b24ebbae26609fcb3b4bb400000000000000000000000000000000189b8cb09089ec04a71f38c9e01beafb695b206aca85274aeeb598e92d61a91f23169e8284cd10902f6493ffcef890971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af35d80dbadfc569223208e2d5f515b6e7eab59843398245920a5af8c563cfc78e1d603c66fafe1535f0d480218e8bd00000000000000000000000000000000175e46f89b3d63452c879317893e7dd19d0a9ae426ce4e99d1a94cd6ee79a88b97d94d51aabba8738b62376acb037cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061f932120eb74dd2f702b3559ee4b25f7094e617bfb9b60e40534ae2f8a0eb28664576ac7cab1d91b88490c50f1fbb60000000000000000000000000000000016f39113ff2decd67f9441000194e50074d9c32359a6381fd083c75787dd1efbfa645397bb9efb512d2428d09ca091fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000644fdbd9637e8075902460961a9e59a146e0fb44d2f13dd4745b5d02317ad448541f98bde13be1d0d668cc76cb6097c000000000000000000000000000000000e5cd58149b2697ff46f5f898f43ffe4b25e87c83c739474ff4f68adf2967613a187935aa6afee35345af04baccb98381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c2d1b55c83103240e3f9f59d1f659d17cec41fc96614c695394addbbc94bb9400755811a979516e1d5e7ad5bde8df90000000000000000000000000000000005f0ae66143f7ccd61f05e6326a49d4048e27b9200240c9ccc3208e50aacb39a011a38a7c7a9bebfb03aec64153f152c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de01b52d0476e8ce8c557f3f71b5ac1a4640b67b4ba8ea69071bed3c3efaa7bd34e381736d7cb0f83568dfa238746a9000000000000000000000000000000001219cf8a50765dafdf9332bc948fcba8c47c945035eda2e0a184b43638ab72a9253c8d4347fc1765b488d9675e5b8daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9c438588eb7cc58a165fea2418e1f430ecaf9786db2cb2d4a5d853a91bec87e72f4b11d224c63e2422212c646d30f2000000000000000000000000000000000ee39bb67fbf9dc7af04a068d80837c8ec1355584d76c6351064b4c576e65a389b2e9b87f7d3679f396b7a7fffa607bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132fd1168cdfb8946f5019f599fbfd7452dd7c89dbd6b246ae0da8edd2b29f2a9fe9020947bd3e09c7878f9a607b31740000000000000000000000000000000012ecb87a8db9bd6dc1ac3422f1f812f370b45ddd4d28cd203fb6edaa112bdab900da25e2d59754bf2a4d2404f087eeea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026146ec5ef6929be1ec2df395a878c9e1ee0f6f27be202709e09cff3098ad15ca989e2f2edd673bc8214c02c0dfa9540000000000000000000000000000000013cb27be2cb14ea2349115a8c9f8c2d7f61a9fddf2ae5508581d0f8a42d05fa9fedd3ddef6b8f4badf138f2f6b209bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e9f1bebba2668539e154e65177fa187812df6114170ae46461021a3e7b358b3b20acfa69f1698630a3330ecbb20edf000000000000000000000000000000000f971fd7b3e060494362d40a5d4d674d2d0e3f273e48fb85a25dc556cbc8785ab813681671eead8a419dd9de717b87131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e18ebf0c82c8e309ccc1cbc9e1aec1373da8db6d965bedbaeed91ca7c4fe0553d90858c6dea054ceecc20227528fb0000000000000000000000000000000004681dd9f85c181e785f8c06e606820379e92bba0d4ff587520132a94e3d0c621af7a5841e3ba1c40a91c5e6b3c7048f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001270c243bcfbc387a538f53b74767b78b8381668468032b5818f47fe5cd9f8b8d838adec3419060c56f50919c281d3dd0000000000000000000000000000000017bf377d16e5294bfd43b61d024e577ca63c178cb8ff8b0760860105a0f5f0eb1c5e47cfbb56133b871dcb89a87331cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001246aa044f3a02b68cb16c405cba4460834fce0fc9fcd59fc198a8c7ebb4e0b42d581bd47f727fdca571f2f816da615f000000000000000000000000000000001992c56047d03bba546c4e1e1e2e39eea1709103ab7e63201497ea3f8fd05fd3088432e9777a8cc8ff628e1d05f8793f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131b375f421c6bdd6006f18aaaf715d865c3d3a95f715edd696b56b05ee2510faabe8a9c0b7a61390c4d0786a609aeba0000000000000000000000000000000008afafb325319986179a679e4639948cb48fb738a61f4b4363e067c1ece76e512aa7371766e0d935eb037d142217a2a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd7fbca565ab850631e645d0d6466010e2d55fc3a93cb414d1e5cb4c1e5f8060ecebaa74db64614f8c0ca9b3c7adf42000000000000000000000000000000000b78a1bf6bfc8f44aa3014b18324f37297ea7032f27c1b5e67a5073b73e8fbee9d373611c968f003b015ef19cc0851891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101f7c11b79187914d9c4c84fdf4472a9aca6178051b5c8a066d13a1f99c2592489c96852486e94caab0012847c31d460000000000000000000000000000000013e73ed84c657711df767b1ad96b281fdd63d90a01497d74567df47e96a9f14c983e8fd7c2cb6a80dadf3d4eaacdcb081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f7417b1fa997a9584eaa61f336bd750fd5347c0e7dfc496bd3cceffb6fd20d6e2844642f7f0b16a0aef17dddb2a20200000000000000000000000000000000134a6d1639ae80e37ad3f35da183d7a83b6a0afe9718f01cf7ea3fa208bf7f68a296cb22badc2443fbbab51d9e368af31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147822bd7a84ec594f661e7afde6a3fc5b8aa47248981f5c5601c2300e3d55f672e9ed91d994ebd54afb5f3269b71014000000000000000000000000000000000ec8ed4e5a5ef62da3647aafb16b0d42928c9e262c45aee1e372402a221822980eff1dafb10e5c97ed5e1e519575ad251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099aaa95699b7c65a72f0b472b256a76ac0b302f798a29bd8b78a394e83ca9e43e3ad2a2c8836ecab261bbcbc19708c0000000000000000000000000000000006df75d8fb0bf897fce956d6acf8a54d0a6476ead2cf929bdf602227d799266ccc76b6acf935a23780c5bacf0039b88d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e18a05406ee1709d7d095f05efdfb4da54558f70448989d02cf4864f92b7e150108d61fcf30d976f68c1f11ee50cb400000000000000000000000000000000069550bf7c18ba02f97f755b9735ca6208cf92fd86208e20a94c6096a12ea5b6427df767436564c024575531bf60b7f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcde442fa8a1d734b76bf959909d18278b34ee956832f5ac49f68981228484a66b59cc139333a39825c221a92530b800000000000000000000000000000000013e40d5978260b6871eefc9857cd2736f39b158fe849937152cf6f320b68408af6754de3d7d564f650766d20edd7d69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e18ba7f45d20f1e5ec5c7dc4cdafb57530a88a0165571050146a735a3b8960c8d20ae3f3324126284fe2531545c285600000000000000000000000000000000073cb8f9b1a6bafd74b3d256358c914b42d1eea1a80269aed97d56ba7f0183b1db01a05a4ed13d14a0f7c861de648a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130c6d6ac338b20ca3fd7bf0619b7fd562145f6c2a83981a3b23d07e77e20ee6fbea7e1b0f378dbdfbe6c206c350da49000000000000000000000000000000000cb2dc59d96e3ca227c06b0536a8913aa5561355921f18dbc397a62240d13879963c073c5b5248cd5bf939f36df7373b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc533e5d6a74860d93c3b3b7737bfa6cdda0785854bb98f646f678eb654be70525ae1524e935aa616f51787ce9c06800000000000000000000000000000000187ef8a77effc734c97b59484b0cc6b660d74c611fd51939671ddee33fd17cb225145ebf8d3ed938249f772b85b96d911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa1dda26d80306692e16d48e98f32facce2414350c72ca81bd052a386172e8e0300363d5db8892f1b94e3d4d99343310000000000000000000000000000000013615214d4cde9f63e5803b9e321c403399a0a3edf235b4f793c6006b54cd17facd5369585564207d405799a1b55cb881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040fa595724e8beb7fee1edca40655065e9561df12888357b8d645863cc14b9155adc4ca7fc91e3025a062ef517c41e5000000000000000000000000000000001662aacd8ae85acf179be2c922835b0938a1193191fcba906162216423dbaee265a3370a6099a9293e7ddfed1aedf3521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb732bc03bf60940e25d7a6a7bb96c0d4e4d72282f13d48d10c2ecbe87e7338739a9b1b9e125f160f59bd22463d4540000000000000000000000000000000000198fd13e1fc580733623a24203c856348c965f1d1e0df6a68327d0b9c1bf4243cdeb6e32cfd00b539afb43d52126f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119eaea67c8aa9a319390119e73e36601106006afb8a9ef6098abab40309fdc2038a3317991d92fb18ce247ca7d1f5e10000000000000000000000000000000010d378e0568c0a2c0a3476cb34a86a7515e4ce6d123cd2057498f681d86d4cd7323ff923bbe72a82260d5470850154161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bc777a01ec8700b90fdb72f435a03a1b8d0d5c3f478de38d6c9b8ea1a31a025f8bba396d3461be1db7423e9d5ef4f0000000000000000000000000000000003540ddd975bb819c91a5e1f68185ed186d5cace078d93b4d8421cb4a645744d71371c153f386f72c4d439c77a6ad4121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0045c8c0c88094ff2b7cb0feaea36dec6a374f20916cf108f63c8a0c82ea59a32a95d32132a423db3f187516fd983300000000000000000000000000000000062fc6b5391334e7f2e66bb276e5c0a7c77f2222e1a5f09ef954d743f59e95fbf247fc0a995481ef673fa33f221161591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ab2f2387e58341e71c3de1ab9363de988f6fa23a638490784b72836ecdf6135ce185f6a0205fd2b466d5e01c11f64e000000000000000000000000000000001105363b6a7b8d996d55370409472f64be1fc8e91e3794d53af775b7639954d695c5ccdf2fa335967e1da1bedbecbe6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012169f892b89533e667f0284c59d8290b05ffc0786eaad2f91f80133b928352030c04a82227476eb5e2667c6963cca540000000000000000000000000000000008052c2a322e7cd404151a5f036497d5f6535e6c76d5b19bb517ae7609723ed3d0496fe5882a388c61276d07b25c27501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e475a6e31dd1908fa305a70802f3715f0c48f56812b1321c24ee29f9bff2e21baf3cdc9dcde0754b0259642aff80509000000000000000000000000000000001083306da90472ce0ee7d8acd29aca516c65d940b3a9dfc42a471b7abf816cc28a97283d348ff5575b0461174ede53061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111fa36dfc6fbc929fc2ac7665c8de726d656efb718b4d984a756681fed6158a8d372403e18d8e4b6a610224c6d7ad7f0000000000000000000000000000000018ef01065bf66bd295f0cdb13c6de452aab434fed68d4a7e8d8f46a9735c201b31a7cd547af2f439aeede3ea7e9c8b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042b29dcfe6a621d023a464f1eb6b6cb2c1581ddae6af44c80f00c4eb16e1677358507b0cab6691692cd7a0f9274a2c20000000000000000000000000000000015083da0d6d89cdab1a1877c13e6561034448ea057b608181085335b96a178ae3c2b923ca16e49181538f28cf68fffc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e632929b71e05df1d4f497553efb842d3a286b0df663df9016182394b0ca1b7510c5ec7f9d19d243b178535a1bff82000000000000000000000000000000000bdedb1093a3240c5e2a4659f604e5147cf7b300497e0f1fdfed1653b6c4a24a8c9a51395fe97c27f71a5b4f6b52c9731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097cfd3608ae495961cbc69c39e4fdb2f9340593532859bfca4b0631b67d4bd237f9fe3610eac80f16cc376a9b7cd82f00000000000000000000000000000000000610a85b4010068bf5fbe661e0dcc391e8f10e641035cdf9f62e8b4e90aef3c02efad48060484bff237f9f5cf2de3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003400da5e5a306627532e78e5c31855b81a953e53ef482ea80267751b369824bf1ebce86c6f5e860f77f5df9122611fb000000000000000000000000000000000badfe57ea33b051d54b3265826c19745f7ea6da29b0717f83d2d8ac82f6073ae469fe6c6a08205f691d9713d5f285461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001687aeb40b60fd146ca41456fdb6fbe1d23be51c3d1f45a51fa9888db7aedc6cd043a8cdbd180b2301f7ab0e93740f940000000000000000000000000000000014562f0b9dfedc26dbcc60c101f5f85c1a728112417079c3a51ac909959a91bd6f3fef7569490ed01af2d91e94a6b5191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b57af56577385884e4a61f7356c27660959166550f5d2e8085bda29355a4ed806476a7bae78b30cc52d96b16570304c00000000000000000000000000000000155329db361682434ceda4cf6ce49ae296c167352bdae922304474d0e329f8c77dd433e7c1e1da9d916fb8e18e799f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005450adaf5acc678ebb31224fef2a0d2e3444aec8e2dd843151832c5a94654c493b31f93734a3781de1a35fd5d6923fc00000000000000000000000000000000094a8d0906e575411537a36bf4448b6d3696312ee762ad9a517b4edd9fb05f82a82eb58908dcb8baca1831d009dbf64b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ee63c84b48e561471e1f4120905d6f8d91fa4a41e9edfc14cec0180a19849731d39d8aef273151e4b8b287210cda58000000000000000000000000000000000383839ede8849cacca9ce263cd58642bb4ca375090f5be0dbedd342718a85fdcf18c9013bcad6eb2f95563f9c9ff9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104cbb266f94eca53d30b20c239c2dac542b15790bb4af3684c598541b1ad1c095a1e2efee3f472508d0f9b0f0737bca0000000000000000000000000000000011e8acb1284ecc6c88ec36f37cb7b134e49b476857f6c13682a2c5eb97a19f158832e75a801d19b6a60267061af67d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a9e2deb868fa23f4448b8a991ddd6e2d58ff0a6c8b24b2bfe0ccf0715bc57e1c29c1395fc6394dca1ee6396c295cf000000000000000000000000000000000c5939d45a5db911c3b719bb80eb71e412325f7c3634ca6db36beffab0f8d508c9235013730a8f481cb87260c3c12cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011217e7aed6bbd230a65182d6edec32535d83fbedf578b16eb9e1e2d6e9b08186dd617b816ac4ab865830ac2b265ef2d000000000000000000000000000000000694cca1bdc0ebb5c1d0d09192bcae63ac87e5b6855f7aeda1c0d97093f5efed1a72c73af2085bf082344275fc09feee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003783170c2c95dc5658274d61f8b54bb3413dead820f7b29384bcecb98bdf9d53ede8288c64a6aeccee69d294eefabe200000000000000000000000000000000130bf2c37eb720c4731a850f2a6b7d9a214e26efaecfe16469b0b39a9f54e705645e8754e7e2865f74d0a7a5edc5dbb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba5f0089cd9096fd34b809210bdeaa1099a1a9130627bc3eb017688927bfd630006b9dc792544ffdd9f137cd5f9ffcc000000000000000000000000000000000ffe66322db6aeea62ac317fe949703c6125da92af85cc3e0ac8d8a5af7ab14842f1eef72c25a95737c6153f3442041d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085c49c037280f0e9994895cad16e323f38e59e4578407882821e6324ed56587010e932e181635e1ffc18396a4238c4700000000000000000000000000000000089d213af54613a338f10ecdaa3cbe9eef4b2e917ff44bffad6fae46bacf6b9a6ea9e7fb83539877f285317616a33a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005536359f00ba85e2ac9f0db860a0fff3ebb1dd3eb418697b719c6caa392409761db22e08281d0560fd2e7b8a7ac79470000000000000000000000000000000002c9d76314878bf50143b3b69d582ba90d796d5352ab55aa8e125e032ca74d078539644e8da0fb22f01a8f4c313d9f8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fae677f9e71b5a07290e7b97cab17e2a4d83e2fe56b9b2f90a08d928eaaf7728ec9d48073e8cc928f4d886430d7f32000000000000000000000000000000000690ce4cf9f36580efd5e60418b114857eb3e8ebac4b9329fb12521e0d5cda899dbbf5e49c81d23eea456d8bc8708a161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b1f8abdf620947b77b9e064ec983a64aa3683aa7480d14f0747ad614582d03fa6b358c0a022b033ce19c0c3474cef000000000000000000000000000000001016dc01b4b57d9db775c61e13fdf0e5c50fdbf0cf8d5d5a7a3ca0683e9f61de5d08be5ec77cbc80c7fb5f5dfd486e161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190d1adfcdd41681f541b0111c169f3e7a85e7a6383ef6260e4b884ad1b907b78f9fc2720ecc0839512ccc25182da36c00000000000000000000000000000000026319005685e1ebd1cf00da6be131c445f32d50e0c2b3fa7af319f9c339b9ed22438531d3fea33c98c9f5977982c2ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbb471edd5f0189d82b0eb5590c84f8d9c7781edb179a5cdd29cdd11d7b4eb45f0c34f1c43c27d1ed75e538e0a3cf3b00000000000000000000000000000000055356a2f88ea8d08714a2b8b9a2de24f8b3b8613b483831a8812381c01d1dbabd81a74cc9ee55af7d39fd72e49cdd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035a7a881349b6756c3e27f2732a18ecac97eb87fb94c284bfbe727f53b4f87dcd1cac7219c70c91a1bb6b3cd4adf646000000000000000000000000000000000055a1a44381acc2113d4e3b4d359598f1960425952d8dd4fe31dd8a593b09ee2cb73893fb45dc0500e08942a1dbdc7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7d3970eb82949eccc717fd15b43d70609153a170ddc3043181c65adcd10da983389554eb5fc52bc16486de3d4107f80000000000000000000000000000000006de65b692aaee5ba7e27ae71323f8521be08d3e51ceed86cfed685c34d525497b90e865a009fff295272ff8f643701f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000110b74ad6735e703fbcace6c89e0a5a874f25498da9a2a9422be4e7b6589c2f3aa61ef7ef96557f40504306269e56020000000000000000000000000000000018dc0678a0cce8b8008618ff78e2d52d37845cebb2963039f87a890229cc441d63dc48779c20f830b63de17cd82f25761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011821defea047f8ae7e410b0e40053c551ae78b550755e53b4135af3e3f65ae74a2c8d11f2c5e94bfb485c1d7bd943c20000000000000000000000000000000018ed5c4b2ad754040b54eb495787a4703b5955d28ff354b4ce53c5dc79f003463bd92200a1d746a6eda3dc6b1cf5fbab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c35fe854d6c9d41b0e229cf0445d30993a3be03ca8784775ebbedadf47c15a519944a08ebb45d0fbd9eb067b363590000000000000000000000000000000010c0ee7793b27b4b84465e81bdf764b36a2e3ee3fc0a149c0805a5f7e08303cd38154feb9dbfc55001471c0c73fc02ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c71d678034680a2c22a8cfdcceaba1d284829515afc9a2d075c411a233f4d383c15efdf9b38c36fbcc522805ae1a79b00000000000000000000000000000000010d39f975e0558ba1a8775949a2924b9d53af6c8d14c2eceab247beb2c5fdcc4e146a0916629713440eacca4760e2561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015593cc0c0b4edf82c121aa62a65d59e77f509864ebf834d6c4c4bceb1475e7d6dac076ce02a6c9d048667e984087a2000000000000000000000000000000000926918fd5709660cbf1315f57b16b10269afc9b0f9ab771a3d263237831f04e91d63dee1276c0dc81e8f04293e9b23d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002067e1b319c4af12c01da2fdeeb5023a6cb6796ae13f7c10136f77e5f17d59772a6a3b0bedbd536f7385a599f9a2fe200000000000000000000000000000000117e47ead23ed2ea4f0bcc9d90762498f37694f12a5bb24ecc82ec77029a0e9e1b0c7123a9538246e970e700f6d1e2d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010587fb7dcad99516c9a68832ce579e8cd07c829dc997e5c24c318a5d16cf33af493da036bb227b941cc0905020b725c0000000000000000000000000000000009d91f1a3341b9295d85026260f8dbcf909832b504d514bae9dc15011b1cc0d64ea53a9e9f39460da0d0b1527faae40e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097fe4a745fe9803efc5c4f106c56434ec2642143eebdf729991fb21ec409db2ce080c2e40998923ba173d036cded8750000000000000000000000000000000001da0439e3d62895a3e270f7b5b73d0db152016457775b90a057132178e67fc385999d68558fd482dfb10f3012a7e5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ef73a51d63c29e98a659da8aba2b496cde60c40eeaca0442e53daa6b56a9020268af3d69e7ac338875e444ad8f925a0000000000000000000000000000000011d8f414c8c9a7db0688c6da3e719fe55fd2564e2de03e954962ebf0a59dfb59516b24e58286ee26c2089910192bfaeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030812fba39af8d0ec3c275850f81479e9c9fbe7d3d72961e0c1acd2d126435cbbbe8f9fe17438bab9f262c8c571b1a70000000000000000000000000000000013950af9af843cf55ff3cb22aa67a39892b13d2ce9ec92cfe4e2bb062bd7463804e8f48ce8942b8b3c115949f502f6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087f5de365480c350c6c9eff3db5df2fff245a95c42ad70604d3215487cd389bfcb037ab2daab12c8ecf25c18296abb3000000000000000000000000000000000ea3448277abc3abbaf772050d964692b2f77adc028d3fab7cd9c41429f2a0ce145766b41c049bf1d11d3b82c820d7741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f0ef6647470f398f4c46d370a61c3693bb82c7ad1169b80cad8d6860105fd60723169259c2ec7c80cdecb32e30bfbc00000000000000000000000000000000107996dbf17ec32db185c7671fa4d909fe48fe901b7c9bb70ae0be66b32395df7fb6d3e8b9f46c970e0483c3cb68bd831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188dadc56fdeb7c12e3bc17598369df0b32d1472a9144b20d48226d950452686f99fc81916197d9b98b9c3277aa5aa3800000000000000000000000000000000039b400b3e1a5d1a2536f07a779599e63ca221f17c523019fc33355fdc0f7777ff5c826b8e0b247018191cda461048d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002830b178b6b44651007646505dd41a0c9edc713235163521f486cca96849618c3e96688320a65bd365192f4d9b3b5d20000000000000000000000000000000001657b61d393d2c354139f36269f238d836b1eef467fc56ea1b99db819074f9de76ced36952e4e28a84dd2b836455b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a11953a4ed918347dda5ed4cb92fe0d696d0504611a1d8257dcc80ae2121084538816b8615dfc96ad293474fb7a4b50000000000000000000000000000000010747d6a69ad299d5e15b6876138e5d30b347e156417342d7ed5c193537e6e1c0c946f0ec7612d36a5aef907de7219591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e7c5a20598669f6f14e3332d70b896b4bec6e1c5412eeebcd7908f9418252648864ab7be647d28a10f6f769b1ba88800000000000000000000000000000000149065eff48c87736813e8fb6a7dccff196f96f8cf4e9ef00c8d3c5a7f0dbdeb01b143b88b83f30aac0423310f9a4fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bde6cdf6ff6a795e333497ef003ef13bbf47b0830a3ecdfc3eea32e9b1b5b8489e47be4e64bdec5b3bd26a056277a24000000000000000000000000000000000ce5abad01f8b59d2ba06b637da67a981f88b584604be71711d91363ee23a21a733e9b2e252e915be13b352b16a7f8461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b49b39bace0974e8197c990b965acac828239231141107b2305400d9e352749baafd577262a3eeccfc283b48549ce620000000000000000000000000000000019b8ce1c1ec36df8324f227ee01a97494b8430d720c155d49f4121f46375085ced8295590c3c96efc812f1cb5756bc1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ee0c5b50d16ae6def56c2eb47dabc74c72f84b50d1001e38e1f66d1602bd48762c65cf7f18ed17dda7fcbd9631d3b200000000000000000000000000000000143e3dea2fe77a259f194eb318b252061365830a5424fbf60abc3a4ddee072c3016b7d0db76fcf24439f31c1359cd3691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f226d40743bda60d90addcab85fe41be1879192fcda3cc28cf41c452026af8781ebc84d39866f96bffa4fabf238920000000000000000000000000000000018add4dc60856e3c65b6701f85e3de3f906e585151876d02fbe5edcb9e03ca5e5a9a8ec6570da68bceca21574ad1cc6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e37282fa13ff000c5db0eac966468988c823e82465cdefa700cccf3f6c058f5e8a4cb3f5a2a2bfc3ed0a480d562226e0000000000000000000000000000000001f71a4cae9a416c6dfa0eb43d42bf2017db82f94f0dcb7cf43f044a7815b66f5f21fa2eda37f7d0900b5155a1f25dfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a27ac4ed6b63cc4edec30f3df4874ac1eaa5fac2d28dcbd8dc8a85ef79d11101e369ac8b2d821fc14877cac1e50826c0000000000000000000000000000000001124b42b00ef786d5ed515165319f83644e7643cb0c4d765e82c216460f516da83bbfe4dce5ac047145fb931327f8011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff757740446e9dd061cf31403623fcc0fc5d36233cae36f5f9fb237c6b33350bb32199b4240e4a5a7d2992774f3e7500000000000000000000000000000000056be9bdb9bb8ef5c12411a3ea930c693a691fc171d2f363f8ea38f645aff98a892575a28d8b820b20ff6148ae79a8431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135ea73760db39bc0c28dec2c3ee42008b75617bf3517f48ecae338a2c28e666f7cb421d5b2b40c9933ba5998bf04ede000000000000000000000000000000001140bfb083fa54e9f8783b4f94afb95daa87b43d4e228d3d1dcc02af8e54bb89225c0cf779c6f2043e45cfe4746020c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001738c3d4a273523a0646b3017a030eb25e5d8ac5181fe006b67309981f2ad4c42c50b3a9a268fbdc99136d82f2827c5d0000000000000000000000000000000019c1ccfe1cacdba083eb2c6508a4323e461339e8e9c5ed69e7d419fe3aea6f5ef0615a9d579873b9b96653dc5a7ac79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157fa6a78fe1d801418857cc0c4cac470b3d817ab09b57ee5e9b15cd80c31e672f697e9ff051984db2696a6bb38515cf00000000000000000000000000000000130b697a63ee88848063fd5f85eacba15726ac0e5bbe0585677390c39cefd05a1a3560b7e2939bd3c5d99b2e5bf1cbe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd68e1a744f568c5db97036b512cba89397e771124fdcb550ade4d88ff261e4ebafa62fb7bb93ffd29a5a78740ae8d0000000000000000000000000000000006674b7550ad80e3d208bc588457c152aa676181be8824e0f502788950d04dc6f97d4520f5f08329192259fa7acb7f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229f08d29ec0eff8364f06203bbdb1ace0518f67b548edfc9b9a6903aed94bd8e4e5ec29c9dbb2542250559ce35ebcf0000000000000000000000000000000008bbe8703842463d2ae5064e4747de36050273e63a750b8b3aa7ab3b205bebff541204747d1de0db4678e68d13a4f94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bd214cd9be24b856fc8d0abed768bdac48eb19bdc609ec5d8a00165f425878c937afaecc42daf387c52a5a1d04d5f7000000000000000000000000000000000cd6530f58a361c7114cd34f02b39fe0e9e1b19c6704fddc99d42bb64b48b5a6525e759035297021b3438d7628f84a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a95a40195f2bde6cae58a570987c7f50f712f90498b503cb61c65b67d04ad2e75a0a7460107d032a47f1df302164ce40000000000000000000000000000000006fb856e55f6adfebf759d1f40fe92cb55ff9458057dcc05149aa36277c3477aa288a29d71dd33cce5b916c5d60433ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b6bbf521cda75970d8937f96803018971a62a63eff8e536958fd805d68148f284317ddba2747a6c741190e37cdb4610000000000000000000000000000000010807b802e69a45689960cefe34627ed89291a1822581dccafe90f14dad2697db3fe4d7361697ea8e76bace1e959af0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3c7c796dc6156da8a582494d70bd6d1e7f8927fdb52fd4c64a2aa0d63e91bd48d25b8ddfc63f48c6ad84d43ea9fa60000000000000000000000000000000015d886c557b490a7d609b38f9306af6c3f63bf97e90f310db4f25b4d90ccb4cc75792884bd9e6ebcc59144c5ecf9a5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153915b5af6df4fc70297f410829fb9de7fb44312313662d45df144e270282f1a3f04f44ab6989ed87233d14729478a100000000000000000000000000000000176a24a6ad50ada0db8c5e22678911ee304490e2c1ef49aae3246dd2f6798916d056d970dc57ed0af6ab74235002fccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004234d99c52e030df56d1e0996b1b9609377b10b82e42de5f7e98b176384f5d2a6211688fdd0505b4fae0a9085a198a5000000000000000000000000000000000f1deb0d205f3c553de4cb19ad7385a8ec5666cb50d41b3ff5f35c4c4b682a0ec14913d34fbe7b31312f62cd3c8ee5351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042f960a0e70adc0edc14e5ff4acfe32d98465f8bf4c79a95dd3fcb3d83f758c69b50b4f6e8434bb2525740a4af6eaac0000000000000000000000000000000003a195f39529bf68ff1a84b81b89ac4c624ea4f8a84a001704419e4efd699ba0e8bcd4428bcae5770c13eb25fe74757d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000965927620ffeb7745396798aeb67c85fc5858c135f3bcac80b9c99b739564f0b823eaa1e680d32a63da702e26b2b1e90000000000000000000000000000000010a9086cf5666c8054774baba649981c4239eba8966fac97b13f870b486050145339c7f42830baabe3b9cdbf57bed9b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000839d6fa2c972575b980f10c14f6effc5370bb4e4b9f2ef01447530fc89684e4f81b83c33469a0451011cfb8eb9d9c360000000000000000000000000000000013e83db9237dac1110bb449217a3ac45998eda8742884ec4c3d40a1dee610c15ec2b492086cf04edf540e6ae1928476a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f40f2f0fe706b9cba8beff3fbfbbeb74057377f881df252000ffc017b5ed898a81874a41e68917c841add1421b42620000000000000000000000000000000007668b0ec8861c3785ba955dbe46bbeab9c4b276676dc22dd83a126c78b49cc37e4abe79ebd5bde88bf97aaac3c605531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097608d73c5553ec354fe559a1fc0a91c5eda7fbc2847f288604004de7c195a2d49e45196ca2d41459fc8c086aee3ab5000000000000000000000000000000001956454bec3ab6e32cb6735897118eae4f2805444bf4fc65421ef3239ae42211930a371d88e130fa4076e33bd13f29061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792666461e081e0fd1e7d598aaf0eee51974ad3cf07298a4886f4338c72f799f3ffae497a4703e5de140c70a1b06db2000000000000000000000000000000000c61d67968f80c1c53d7c0ee639c8726b5a2b410a862892152c211350ea6c4655247ac97130f02dcdb2228bea2969eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105f4538a759a7936de7d933d1454995ad27c195877cd66aae6517ae5890b05ac08401178183bf8a051b83975cd817a00000000000000000000000000000000008c84dec52ea2f91f132277f915405eb6273e7a81ef231c360ea50e261c20feae382d15b1e79db67a8118dfb00fbdbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004870fd12576639ee504d6c4673ed85de343b868984b396e7dbba0d69df0367b009c369c61f538873dfec56c8303246d000000000000000000000000000000000b65148dfa906ce7647ab5192b2465ba65d74be067b3aac590eefa592e1d4048ddd4b1c7bb8f5331a66fb714d92237bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c566b92ef5d9ef0f33aa14caac5452ffe5abb6592694fee382cac4788eb1ba7acd8ef8ab8ea371aa404cdd8f6ab8a700000000000000000000000000000000095f8978de0ef3286744726e8df26c1dfdab944d49f0908e72d94ce1eff05e452517cf5bd8ca7258fa4782769ca12ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebc3f4b274b637c1e2474a02e8b195020f3e9a7677f90f97c3c0254df02852be5ed7c295073c714ec8d85fb11b6dbc700000000000000000000000000000000135fa897779c0a1e417f6d1af81128b61d13360de57cd91b3e69bd7f7ae34d7277bed74f48107fa30b5b01d86178df7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b3de655a2500695eaa7812050a62dd71ba205e5d08beff1c2288106952b4baa5dbae65dfd9bc6f645a23598fed7849000000000000000000000000000000000d125743535fe4e55f1893a2e689f9db0adde3b3d26c1554768e08ef204ad60712d0de731ca9d65e81ebc96ddd1dda7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000931c0d5e2dcb9c2508031e6b8a4d1dab91cddf52f31a0a019401b67e4076fa77d5c0e030d7bbf67ac4b1abd93c4fd8800000000000000000000000000000000023fbfbf22e7fe29fa87e616207ee147cd1247da42b7d749d9ba5f855065b2ca1a5c84c07a50ad4e962fd8ab2c7c1b001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001908d4ddef4b4dc7bc59dff3828fe404d3f568b7c90e4c88a90bcb0559084140a6b5f8b97a5fe9dfe5458f9e8aae489e000000000000000000000000000000000f14a1f8d6908686123fc359fe3a7c4a6a9eb15c9b3b720aaf88fb1156d4c6979c458dcbe60b398c85c18b9cded894601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e5531cfc3affa1543bb07b55d86bdaf3af5f9a23c3e535c108c049dc70469edb231685757fdd6209d66919bea0e30e00000000000000000000000000000000066167310bedfaaf277bf07b9602301af885c089ff5fcba210a7123cbaad0f13f73121f1b4b7f049b8fe1f57535609541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018336035871f1c8afb338ffe9efe254cf76e66fddea963aa6cfc248a3b81de6247f97aa21c67d541bf4d1c0ad5d4357900000000000000000000000000000000046720f87817331fe3472d94dd931aa6321876556f060feb8d1271448d851957b10d4d2f1167defbc943bdf2a75a24781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f6892eb08c8e1380b57c191dd02f363b7a967c82cc18de1130d95d727d0b7ab2c4cff0e87eecb7cee45481bb794c2e000000000000000000000000000000001100c1ea6f96b4399030d434201fd4d2d6ddb9bdb48072c3747ab12bbcd5db4c88c3b3b34a13d5124def604439a3a19b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf308fb63727f155b74353721915d8008db2e2173b06b849dc83d913565a4c70a166f04cb08e0d7537c164817654bf1000000000000000000000000000000001261acd51ba3bb478cf6fbb9cebb37c5c66b88b4b8f2f63fa84c19ab034d44e1620d7dfed65fc550f7cd5442ad5ab4ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199a087a02d6fbbac39c30857942b2f619e52a68a000902a0b98c7a63be05e250ca68b2f7832bab7ec473b3778d790b2000000000000000000000000000000000c58593b99a936f3380c7773147f1de50646e61ac1156e39a1a9119447dc1b07d9ad8c3f48502b5ecc36f3037f2bf1801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009db68fbdca3bf8ad2a98bf9b9e45cd91b7e33ca7026b92eec2afa3eaf796cae96e47b028867934ad6debbbdb6bfe43800000000000000000000000000000000078c204bec8e809e36bda95277f9c6ab9c88d85f2c7045a741f45e972daded1ace83597e83f180b3899157208ce532a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f6301286bc3e529f92db82914d20c5d23fe12c6d59bb430855c3f306e42c5c92b14e68c180970caed697facd639eeb00000000000000000000000000000000107414cdf846216fc126900da3425ef179439cfd27188533bc8b57eb12d05033e488b55a1acc684f689149f164ea07d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134b259fa35323ddb6c4d8bfee81a82862386951056db9da4f5d501235679615f3d696916c12999078195d3b3f7ce3eb0000000000000000000000000000000008b5583c138079ee82b1bad6336bd93be979bbb6f9f9d3fdf529ef3335eaadbbcbc95c6b4b43708d2890ea4841e453701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846819214c21d4ec375035d91ac6312d11ca71a740d904505bbeb2c93e56085312a0e7c8c1873d86f54decede55b5f20000000000000000000000000000000000e7971c24d4ac0579c67178b117af8865eae68a9098e54dc2230ade0be16d95203a2b8a648213b6460063bbc3bae3e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b62fb779ae877823caeb1cedd026aca46a202d00745d5b4466382c9aef9deace93a269c8b9eed2e33e253cd99f69c000000000000000000000000000000000baf8e93b562ea911db32eebc7881d8a38e92638d058135b0ae49cfa54115c1d141c9c61604e16e18bd88b18b2423cef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067619719b934e00fc5544d387412dce58c1d0fe8c17a8daf091db354e9982ea2c03c94b287abe3ffa80668ef38ed05f000000000000000000000000000000000aa033fe3a2096e3632102d98195821635caee580a0138d113db1cc2b50c64a35f3e9c57c851d51a1722184f41fb8d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077fcd409736ab10abce17d3666fcef33902c5004cc0292fad126b338c35e3f57bdeb7f32ad3822bf2fd167fcd7aa5ea000000000000000000000000000000001561962667a7f38c322c5b409702e481e528351bfe4d4a2e10e9e1a693cd0855d5d305c4527fa067b4f010cb4a47f1081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d4e739c363ff1ca9d73ec8736fe24dbbd1462d8b41d632502b2704e6cfb28405d3f440a05abc9fee7245eb4a3b51a9000000000000000000000000000000000d77c01323193071bb8bb0d65f180978fe3bf475c0b938b97848d20dd42627cb653626568bd732c673e66be14d085c4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096382f11181625eb1ae8bd79357fdef53290037824d86d288ebbc93f6a526291d72c8bb6104958d075992d7210d0cb4000000000000000000000000000000000f83530da3fa6554b00144012f6027b80adf20b15e48a8fe2805b82574b2c2194daec8c477c396f65f4300d2cb72b3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e1520804099b399bde36d9b79377059d3e7f02be46570d225d73ab69bd76ecaa7618fa6d72bf284fcbf924af4cf5f0000000000000000000000000000000018142fcc466d3bf2ee8a1efa16e7727b71f3336b1fe3b1a93d525fdf8a0a6ee34e18ac3dc0efb7af7ac88d4af4fc75da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b31ca726810fbf53187693003b3951bb9c448d06dcf8a7dbb120d8d436b44476a02c2ce887efa1f9065410c9eada0b30000000000000000000000000000000005e5ed64149e246646e38d83f2e2fa6b692971b19d806aeffae6168e12f900877be6784b31ac67434188c8d30967fcac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d7ee0d3e07177ff1a3f939b472df1a0aa253c1463207f52a29bef30435c7789f5fe22c68156e74b8883f4587dd30c500000000000000000000000000000000088512034da8012890760b2f677a60787859b4ac72682879886c8de0942edd5eb63f1a6e4718181fec1e8ea25533aec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb2d4f38563d5fb23b5b33f95fcea1f11f9b353424f5893d078432057fdcb73b561f6752efe5e92699e529f3cbb3665000000000000000000000000000000000aee0ec4363d8143bce9a8537e82c123e61027510bca53169600ae56d678fd6e513394d5b34a77c8959f301b94885ca31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001388fd6fe3b7907b01e49635fce4dfe3bfb05df8debbc8c5af9df86bb5dc16cd9c8c35b3184f0d193595f68a9a11de8b000000000000000000000000000000000ac7f2620a45dc80aa5af926587b0655ec882966585aeae87889aedc98a1a33f9dbb483a6add415e0784f452edbcaccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004da92224cfa217420deacf8d427aa1d3e6268348a6ac0d23d4534e4c7f4d490743a965a94d8c7cfc7ba205488a27fd600000000000000000000000000000000145904a450258729a7c419c0d2e01bebc4421d59ab0baa9f20d62bae0160c9c1afd11bdaad2f3af5b910335191a2ef591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000015f95203b0f1e4b071484d974611b0a03338801df32cf9ea00abe2500bd6dbd042fb03dda5ec5bfe3c92a0505f98eb0000000000000000000000000000000001830b29e99ec697cd279005e8646931223f0fc005d8d7e152d3281ac7f3327d3013f9b322208cedc2e0b93f404f27ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c24dcaa36d609607050f0709fa8fca40d5777cac1ee44718f485fa0c9fdc92c0a7ab163373c60c69df3712df421c680000000000000000000000000000000018be04d1326b970ab176a62d682e877aef7ac534f6d6118497989890b8ae6df80bb061e8c71ddc247d6f1f6495d8a2191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006354cd30b9bc2f762d7d2970f8bcb73b33a9731c55fae7fd115010dd69c0bed9701ab3e1430373006c0745536a898f40000000000000000000000000000000002f5b7672e352e2b519eeb81ed45a9f2fcfdeb79ade86bd3b12ef27de298c1d2b9678dd3d276f7042b7e506d4a0629211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4a0b803cfb5d042cd93f126caab2991ca65cf1743beef49f16337b951b6e7a41cd1bf72acd0578411c9327a42d698a00000000000000000000000000000000029b1a91015b17ec7fc460a55783a35a8d35af3290b71fcbf7ab753149ea68f00746bfc48791621a403aafe5756d743f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b5ef30aa8ab3caf3b1af8e01c650fa5a0e96c44924d5d06e03477aecdfd4bf343ee14687e46c9a8de744a802248b35000000000000000000000000000000000aa869d7f623a0b3e586dc3b2af48bf52bae06036d29371ff8dc6cefa610fd3df08003187840b927891b5540b8b518281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b4d1e69b69e67f09aa8b8b9b554f467ce7501527113cebc13b293dfeb9394eb198fdb9b75912421bc82bcd11a0a972000000000000000000000000000000000446d4746e255d8f81ac4df1d5a451287a791943e2187943525b2fcad4778bef92aff9e770897e9daa08be733d0b08211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001453ebcefb001ded4aee20224eeb7d84fc4a79a900faf19a0b904dce7d5de2f91d57a35265b7fa95f4c2ba7c34ba7f1300000000000000000000000000000000039f9c28346b182ba23579eab72c0150c14d61ecbc5ba5894dc2d72030175ad290268470eb235af033f1af2abb3619461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cdd154d48fab1a248d4b46d6bb7c2263f868f5be6a0633ff7623a30757f84fe49db0b8b45a2d51cb275c229e43fe2200000000000000000000000000000000116657893a630d49fb4cfcac1fa16958ce7e12a5ddf95f3ea28b6d7a09821c3e162752924234a42587ddf7f9e85e3f0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab684885de7cd3029c7aa039fb0f27d6a4b719cc73fbb6b22c420b40c71bbc2b36b6c2456edd34a27d0e1e7934c3c7f0000000000000000000000000000000017329d5b941edd858127ff5c7349d9860087b64ed0b6f202eabacfaa0c7276aa7aeacf22df087c94cb6199a2b2e7e8351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ba130ce7ffb00c56dd5337bff14ac7433ca78d89a9dd5efda1d8e2462e8f69a0471aaf0acdb063d78b74ae4b35c634000000000000000000000000000000001190a2aba2064ac2350362ef83607db954f7d4ef3724965a5fb089eb0c6469b348bbb77ab2fb1abef660c2459abc0d611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1ee4eec9c6e73b52dd0ce541f5b1a655ce522aa7f5ffa31a6ba65087f7975fc40769e2b3274cc1292b7a34014831e000000000000000000000000000000000a38e3a0d357d8771e0071ba95c53702bbb8a784c5bd570a30e4245977b79f1739304ae65d2938d65dcf323f15c068f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175bad86e0918127faca4391bc73077a1ab48aec2679cf3975e388e3066ee601190c9eed60868f8c419dc1256e8088a80000000000000000000000000000000000f312f01308352c5f6262dffc351ebc529bd9ef5a30d6bde7ebd58d988d4b4bcd4308a6760d3add2f93acd36be5101e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c201912ad9e4e86ccf98478cac2f211b9b9a71f27b6775e198982c8d7c4b176f284ce8d061b4799ebc6d5ec9d80ef4500000000000000000000000000000000057d3ce28b5f75bd164deb738ab3e0d5ba15b73b1fe5f3a1a33840f1bc7ecf33c0cf082f93409c9b61ee8a0f0eb757191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673ac336c306ad0b2a705f07417fe5a3f92cd08419931b9d11595a2d173b72e823a986a85c7165415a881955e8ef76c00000000000000000000000000000000197845419c70a99d9e6859642d4cf93e15d87938cf63a56d508656bec0e6fe9b277cf1b2a9a91bed2f270aa7ade13fd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d384d645e982e4aaf5b2b9911f27c90a1782a7c1373d4869031ed39c61e0a73c4f872786cd1a60d7aedec1cb84829e000000000000000000000000000000000ab1c707a024247b54563f879b8eac6e021ebb67cf10fe451ac9343fbf61b3dfcbeb20fe7b3e2b45356efc3e601296b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdd1e7434bcc85444733590a911810f68b447985e29078196b0f285b32fc62cd0f3f8e0df33e367b06a8162a293dad0000000000000000000000000000000018738f903badcaaa65d4a384853e079f5fed839f7155dd81fb5d34fcd6139528f690bdafe2a3e632a7d829c08e95c8e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001004b7c2f038bf83b21ab430bb759c0a265f556214dd73895649321bb559fbb68e0a30bac78a04f16952269c23f940e700000000000000000000000000000000024d128d1047a69bf41c0ca3cf0c10cb095968c8d72a97fb3685e1f3bb848788b4f174dbe5fef7b26c48884fd40365f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001ee46624f93d2345a2181825e4e2c9f4f19439017e798b669e64fc50f71c5d7e48a1acae9b51e827638cacbc0795160000000000000000000000000000000009a4ebd9b5bb88aac9d1231eb36b0a32352482d560257f074af610c4d6de1368297cb38a0cb4ef8925d0dde389b6da3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9b4cb1eb011b931f125b3efb7602869f04e6c041a974a07411e6aca2b75ece4ad0669b500dd8e4650ddee0f104a0a50000000000000000000000000000000015ee6c929cacbd4e4f48f44fa2bbfeeae85a843cd1dd9d920a05d04e4c31f6dd4ada47523e03f8b18a5dec80872daee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001520b1c1822fb566cbb68a1b1b42c409ff97b9237bd9383d96e9578002c72f47565396c7bd1786916d3936021137a54e0000000000000000000000000000000005f0270804748650ce51324ce0adb335a9527d7e6afb3022237656b41b83e3415c66ed128daeffa51cc9d5258825f1751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001790133643eb78f99b2325e69630a96b3b6e68bddde859e5357ef9cb7077b12139a2aab5b7805946ae08c15735456328000000000000000000000000000000000c506eba2934d1839a6d43a26bb49f3e423edc69fc1d53ff1c5169cbc2450acf96ae1a129dd434c791a61d4dbacaaacf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045715e6ebcd9a3ffcb26e702e310a9b86a38693b41f24086504a5e46ede2f06cecc53b62bb5fd637571e758bdc2b15f000000000000000000000000000000001517cbbb177218ddc22da290cda48a45e2fe9697b3cdcb7c99135bbcdee1c1df0908d02fa160a5d526af7299798c64411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683df08172b009f344a0c09a6756b7050c8d769c663a205487396fbbe962cf97d0b2f85c117d13b3d5b8293b3d3ae8700000000000000000000000000000000093006628bd09b9a8cd681866ce7401628f1c103043958b9c4ceb4ad4f123fb4b59b60689a22720837a13ea1e49a2d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091f8f00c356201d81aec1d6a6c58c4033b5a7fd30e6fa5eb4d1a462eea7dc39bf679b4d80830efbb4a8a68e5f3c2260000000000000000000000000000000001bc02434a63730ef71dfc835815fca8355cbf400138a253260e72ba3c5b891b7a257070720e8137d73e6afea9a4c9501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000044358e5ce43b47a67c3e32c559bc5bc0159ea7eae087c0569f0f4eabbe21a1cf15086e9942063609ae581adf2bf5b6000000000000000000000000000000001774f16889492e6b33fa65e293ac654bf3c9d86ac6c380a7d339ed8561355cc84562f292d63ee72c292c2f45d6a6d34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d5474c7f6fde44b420745f0db077d49d91fd8da065eab81d203073487dec28d508c3977d80f6452eb8829378d1c5f4000000000000000000000000000000000c97cb79ce73e7d784a14327f12e3078e1957d2013b3b9ece239769e5950e4cf1a7d25deb7d6dc77d2a40316fbda63221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104d5c73a631bff7a935f75fab6a72cd57d2f924ce6f71e4511516683c026ad3ad89d6ac0ede9635820d59dfbfb291e40000000000000000000000000000000006fd052e0abd6384806f26909edd0b310f82cacf4d1e0b53ce2b45501f2f42d425f1c2282b1b658f0419399b9f6d1cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000134d33c54d8590bba2e3981fb141c9ff6e52df9cecf52062ccd1e12d90c4f0f57ba62cf37e6a185af9c06aa60daf6310000000000000000000000000000000019c9a35b2d94a9a2243705a91526b05e68e3ed170c39261ac9619cae636621c0243497e41cc5bdc7ec4c3c4a136738b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015550b9dd6068a759434b6a097739048d33500f3a4857c537e86635dcb80819b640464f726b8b0dc2bcfcf8d7dbd6bc2000000000000000000000000000000000c2ee1ce1ded97c69da4840b52283e533aab896d86a62f8d12fe086c620fd76033cef213bbc681fa810e30c382d049f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c19bcecd287d6ceb9e74feba5cf9286f25d7920215ddf8e81d56abb35ac93a0d0f8a8cc40661bd92df2391d1749ea00000000000000000000000000000000012408ef5bcc98d3ad62132a7dfaf037f4456f0b37ad8b983ae9d390e1844fbfcef0611ecfe3c805b94e443b90e658d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011553fe18ce7e629a30d5961763fb174ef5c86b00640ba0d586014b3cbe2fa70a4ac69483e9b7fd1da21920f1086424a0000000000000000000000000000000001d0c17b1900cf9f14051cff77d8e7a0b701eb2c27b92bef8a4358a1157de170e5ca581e0b601bbf9b4b2b9090b6a5091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174dbb27a1cc96819265c3d885f59bca5604ffb9071463c1ac1b3515b749860aac285b8eb9db11d6d06303b689506f3600000000000000000000000000000000175c6133ad5484dccde28512dfbbea740b7a19f5b95fb47f013869fcfe6e376cae83481f71db906d336dcdb6dff9caa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f319c933b1a32be988a9cb672a0d8fabb357f1ff6d24d23935e2e63785def45ac84b5d68e4da507938d0aa9c9b5d120000000000000000000000000000000018f64b379735cdfb045ae4111fdc9575c086c8dcb289d9481521b0f1a7264bc9aa0065c8087cdeb89924b6d0f9e8dfc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182e62382160884974e94dfb13bf34bf19cd7a4864166b8d8f90df41d8b94158397d47a776317436d3fcfbd47b24e8b1000000000000000000000000000000001652fa3db52102e772c590727a46fa7af51009d7640f3d512f84960ffa2d41ec2b3488947e35dbfe08c6291fd3e7ede41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066c1a2e39bf78c4428bd007aa37a37bb10431d32f5635e23646ce81a2b230030ea70db94e1ff7f43b0f11b3a0888523000000000000000000000000000000000a7a04b7d5944dde588bdc478cf6d22759bbb61ea56397e729b0c436a039054af9fbe99d2ab34843a6eb933527362edc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011e06290461b06a4d1bde45c3f91f85460e2501ff7ec4222b4b0f328fd76e9e37285411ab2dcf32fd7532e5e9ef6602000000000000000000000000000000000f1ef0eab341cf4114c130242cf57e6ce95988eee3982a86f3c09c635ccd155bb6b94dd4b30df7e5ed7bf4c9fc1c062a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010350dd168fde3225cf7406d643d7a26bdfc3da68ac490e1932dfbfb8b2738e9f96712611f34319126512ebcbe5af8ce000000000000000000000000000000000d5c2df7cb88fccf3e60e9c87fe41582225e85704f817deca73088bc7d92c56c69d71d8e00619079579a585dd45d820e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016307cc7e923dd4401f42c99a8ebadedaa7b7a290566c677c3b5904f2896d2736fa65d5d1126fe9e7996fee91d7578a40000000000000000000000000000000002a57ede35b9d45974646a1f66683de1b471ef33d891422491877a0501fe14110ec187400626cccc062ba226d4e59c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cbaecab51f99d705410f9f0594eb3707768ffa072a03c81d6c165243b0711f75f409e86370a00d6ca56b196c321a6a000000000000000000000000000000000b60154fa3aec3b0449b0574442f66684f49caec95b637313d0e9dd528f549f9f23abbaec4be0ffa3589844c4d05b7091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001030eecaf6615777c9aff309299dfaaea3b286a95cb10374c5ef234131bdc8bfa4d7d0378558e226c0f7df1b7530f0f0000000000000000000000000000000001202ea63e2db63031647c7b66aec33f40aef6603d01a85297ec9a3e0c0bb984b9d8903079afcace48642d6412c0a156b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a0ae8edc0ed8d5642267013d843aaf5789a279f462c69889af47cf0b20b31195e14d538ee3f831b2d4ebc24e0ac9c200000000000000000000000000000000072d019bc43c69c331b5d3c35e984309f9550f66032114211fb40e6bdf51a7e8ef0ecdb52c898dc8ed7842120cb5512b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000754061724865567b0654afcd38bb4c35e2c7e8868288ae794f3a0c2928c847df0451c18ceadedf1bd46cc31163df70e0000000000000000000000000000000005504f200d230e1140c53fc53b60d96302371eedbc07356d613fd9386cb3747873aec2725fdeb855b481f5c2d9fe3a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f62f5c773b8261d192194efd3ed7d2731d629bf10986a4e57a842e0d0774e6236c0e238d6df9c02d7fe31f291d5d280000000000000000000000000000000007937a960e332e92ed5ca985f4de66d75bc32a7edbbc560c9a1efd60d5e3f52848aa938590d5a29dc3304da1066ed6ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519a249d9ae62103ee47f3275d0ead14142c8be0578d013c04471d898d52ac84a18e43c955592c2e74820f8facf42d90000000000000000000000000000000019afc23d1174f4ede9d34cb987ce79ca0c91fecf3db835c5b2e43f90bc8b84406746293c352d8a728fc7e849d7e4069b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044bea11376ea3322d194133237bae05dcc3f2ec7cbbef78949f1c34bf99a7f85266114d873ca2b929ea765a99c3eabe000000000000000000000000000000000abb75c79f7271c368d8fdf2f295786c81fcaab5c112def778636a1bf58e1d36e27007522c86dce0b0608aade192a7361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001259eb1e3d111422891cad5b506f6bcbb580505694ab8b2cde79144eb72d51b2736381ca2dc4624b4f3a5d7ef641602a000000000000000000000000000000001536e2a0bfa5a5fdbbdd6f454cc4156aad62a948f5b7874ebab9aa19be41b7c5581921698e90978f8b04221b2bb786591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a2a344bb24d32b96ceae594d566a732b142db7c3b3e35013d94dc142e355cce06c6ce33cbf554928b885a1cb623dcd00000000000000000000000000000000031233c6ebc36668fadbf7ee71083bb25b3cdc8fa93259bf486885450e80a0008e84527a9f6c3d93eed16a64d1e495a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b5979a9181ab84a4ccfc97b4ba9b77a423588e489a5b547ebc6e82b5af63bf4fe8c25ff977027f68688ae3b27001350000000000000000000000000000000018ba91529c4e3c5e60433548b9463abd07ab47c99060d68ef42b6c0ed3f96cf508293f588f563fe194c9ee96426e68f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e5cba303d3363dc1105a344b733955745c9ea2ecde95c2b769fd69ad6f03970df2ffb222bf6b130761330761464cf0000000000000000000000000000000008a408a8da834baa9d903a4c96430828f6cfd7700c26f7b65d22fdb17edfe6c132819abed47d75302f88bb871504f55e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab7f137dbd16ac75f652136366d7706d4bb89bad22ab4b9d64b8a78fee4f308a3862e6e95ba386057ed359e07113a70000000000000000000000000000000016aace40c10a2e3c42a6ca49fc19c81b8a6a44c5e9a51ac1b5590581ea3fe86e8b5398cc1a8b2bb03f2d791eef8358d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2b3cf4ecd2868551755018a478976208f4984fca01bd18d2a4d4a6f9a7ecfbfb0b89ac777835eed768681b8457e06e0000000000000000000000000000000001c2c5cf4e13221b4f172113c6622ba06147d01b0dfe566268ba77951e0a781ab1cd2b34bd00dd89e0d9fa8d390559ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018feb4ba0b489565cf530a1812461c11dd6a619bc3b0b82da4c1d0424aef83ffc2a9ba059f19d5f7605f6a45d5c26c0d0000000000000000000000000000000009e541f7587347d6f617a7ce72f541402de1510b9cd5840c615db05ea100f4153de8d1f836076dd2829e439b65453ff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba97c329643a9b1c6d38452439ca35f1cd73f268ab9b5a763d89ae3889090340a65e3d47a408092baed69232f188115000000000000000000000000000000000d5951abed7ce6bd57ca5548a8f293c459500cae7a69c7bdc141a244e5aa57dc35d4e36ee5087959bd9a8ea03eedee9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f720f052b0311e03dd5f3aaa8cf9400b16f73df081de05232053934dfb94de6562744f5b8ffc83891f0e74b5c4769b000000000000000000000000000000000494e8bf92f523dc1c1186c22a7d9efa85b808746fafd979814e0f050f014f29c323a0e1cb7781ead6fc23a780b14e701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009eab960c0257a3a9ebd97f692dcd2edb5a696604e2e409dde5678aca3432a273e25e790d69b5060e62c5c5a0c6d23c90000000000000000000000000000000016d2e8719b80d218d257e2dc50ba40a5e6a2bae3c864c88cc22ca731fe306a833c0941e8c515a9af9af8b60a96b5b0001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fff55cb452bf4b29a181e05fc4a549760bc6db7d1f95bbd92013ec506949f69a0512787ef535e0de4ea39af048011630000000000000000000000000000000015d87751a0f392f35f15d536ed960eafff49a5b377287d250e8dbfb54953f81ea80d3c4ef9dc18fece8070887ac93a521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013409257cb8c5706fd72c0a3f54f01f18f52d5d7ce32329c4ec69f91f77b266b9e991acfe6c09c1be13292c9c4619104000000000000000000000000000000001256fb5641dfa056c1543f4210ac1bc71045769e28139c8ea0c2e34b5c9af2f2ceb762b6d743b7ece9bae959796becb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9cec304c65798b07a0565e37031985a20e35fdad3de06e63b8349f90e560aee6807c70626729a8ce07de14030141400000000000000000000000000000000086f816cffc993d27d99cb9e38049224acb3f3265454e3acd4a59cc1be08fc748654b109c74c26277a6d1adaa45d4dba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001949f8c3006a9fd1b38562af028b3988d9196fbf138a08761a5996c9f78cd04d98881fe04e31a1211e9af008d3d966f0000000000000000000000000000000009a9b17ff34f25b08fdd7649149101616d806be021a0ef2caaf0f444baba6ed1911d1f228092e44195a16330d7cb1a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001862718460302f9bfb1f0ee4bfd7aed66d8b42dce4a1947328c9285987da79cb75a66a0fea0e52886fc3c2109fd8e3140000000000000000000000000000000018556cbe768fc7bef3764cdef9d1448b96d14c295b61fba924891792059a4bc2d2ebf9af5f16ce001344d788d2d1fa511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9f8c53fa684ff07ed321549d7313c343da213ab816045432c34037b9a60c842d04e432675f40c06845b335b491e760000000000000000000000000000000008bc95295d3e64f4652652f6cdcdd2ed7fab894dc3ffc44bdda7239a42f0793f445bedef930b556db2fe4fde00f703611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f6909454c928812eeebe5d769ebe70e4cc34a3e9101476a8015ada1551467cc3ddb0dce463fd288546839cc136124b000000000000000000000000000000001431ea74c09a8e0b688766e1a4ab78ef88d34ac37187dc98bb5479761f0de4076d3872d29c3474b602791b5404ed95ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8bac8d09538b05b92c7ac2e72890884d57fa9bab00294eb06104b1abea03cf924c478b2ec62471c99a6059f29c6a4b0000000000000000000000000000000016c6ae2c8be6a2621365d08971076ef450ccc5cf2eb76c67fc951d8d885373ce27fb9a27d70b7d67899558866a99fcf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc80f8038c6af3bb8d0f31e89c2efc2b7b15f5437cc72053418ac49ba0c2a73669d9f2e05e60ea5ed91e6cd0374e74b0000000000000000000000000000000000bc5e28a49af3fa995cf68bf0b557ef7a38274e4ae2ca52bd684950dd9b2a263502d2e3257f7a9a86e243e22914fac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097b950382ebbaf99b261e0703a4406ad156db535b991b099f546aaadf8fc20161edb8ccffb3cb02574cd2343334625c00000000000000000000000000000000187b1a57453d8a977af44987b99dfbec678d72777219be86c9564ee3b53c8d54310bfd807aa10612d23417862128d8c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2f5d961a328aae62cfc82b4003c5332d9ef0e3227c07b6f373ba066529785b3e2d4165f5cd97554ddef8294e873530000000000000000000000000000000014a1848d2a311ea29d462f55bbe85f1f56417164d9e05f01219a3df02fcbd654240a0f1b43e7053ea89c477c4128409b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199037c6899c293b728cdd6e9e10f4ccbc8bb17c1c1377ab0877bc85b6f8891b4e6a746a167c9831d46881ba786abdbd000000000000000000000000000000000f320f07e1854612de8a3ceac12529de519f49a05ddcecd8662b9e1686d52bdced8309ab2d78d47268c99df37a3cc4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e130955d9360bf0aafceea50cf3b4528db8017641e66c312b588d4ac58043570c01b778bc5ad65f907bc8b642881630000000000000000000000000000000011a6c4edb3e9c53922d7ca35fd3a6ddd8c80effc7bd0ed3f6f0ede8c33b246fb771ec61e8cad29b52bd9ccaab892a30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052d83bad3ccd6ca92ec559bb270ccc727333e9f3dffa0be2f9042ec8bd9045ff024b20f855e027c4be1e2cf71032a0b000000000000000000000000000000001074fde56849ce5fb412997d89d49776af8f489824107a616a796a124043e9b6794d268788dcc3af9bcb7ec5e54d138c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cc9b6a53f2f28aff549e3b0b8c2ca7fa2ddc62c0c59c01ebced96c13363479c279eea9a0347c40271dc3ac50781985000000000000000000000000000000000b6dc2dbaec24ba15d0996b006d651fe0d92e57a23f6b14f74a4b57eff95f9c10e382a84f4c69ed8a9e6ff6fff85e6011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c2673f85e74b094adb61bf4ddd2b930d9c4d85dfe4344329252e7d7524790a056f432349ec6e6c6ad05bde1f7ff980000000000000000000000000000000010cf06e825dec655a2ad4ca87dfc550ed9d046049e7e662287558cfd04ced49833cb95e9aa08b0842dfe79e97436c5511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699b97289001080373f0d6386d7da6bfda67ac3c63ae2572d0747ca1db42e946ac4bace449570a1e15987d6c5759ac0000000000000000000000000000000000d02702a5f7d67391a35a690413a074e1da491ff09b831d170e4801e1d5ebda34b6997342f7f13814b53817254cbd4d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139d55fc7b72e4e916369a1a897916289c3d375b25f98029eca0d6423bcdbcae31d45dc0fe0de8ec3b1cb594430d720700000000000000000000000000000000115629efc9227ba89a95948c962392d7044ca8f04836c433cc1761bd0517afbddf3b1b4e79369ef66c3ff9ff358640651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bbc4098ce17d750cc954bc3e388d91ba41dacf61908cfe851135c1758fec5552acef94cee7d046a4eb418d3c75c0cc000000000000000000000000000000001586056abaa810b260424df3f385386ab6f8672822bb4dfbd01a7999a231250767f8dfd8f4908aa1420565b196bee4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223fd420bf152788af499ca9163a2c10c0a88b2985c9604da0550438065d99a98a080b618d58e9759aabd9f75e5cd65000000000000000000000000000000000b3a9fc09ad2428ae0e6147921d508ba10c5573415c39b578b13de4d0535ddd4c06704f4a7c95342eebecc10739aa7701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e085d117460eecfaaafbe4ef27c29aefb8aff9840daa207379d7c7c3d4a2b9f4756153035ffc4555261f9cec56cfa60000000000000000000000000000000008dcead8bf5d8888ca814215ce50fcd81421ef661711fb318dcbd2252b009767079bdcb074a4684533d512886f5d94731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001424effafd8c24a9d2d3dd282457b6c79653dadd7285f3ef7952e7965020c68434f54deea81f7cb6eb69528a435128720000000000000000000000000000000013ea60f289f6c5a6e593d2634b8edb22a97193cddf026e459beb96a366df07f64594e0e3a2469c114635d34b9b920a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033c05956d9d47f6773eeb4bd0d8401c11c6dc2d4ab0a257347f8f8f47313c8f498f1145c284ba785282987e12075e610000000000000000000000000000000007d77b93a2a018a9c1644fb60d9d56e6dfc73d9048b93afde7900773b0e7c490704079c493270c6306969b5a7cb0676f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c92df4fbc3dfddcd3fe91a5b964765fdbd57b5359de078e2901cf8203eb01cf68a25e18180ff17ceaf00de7587fcd8000000000000000000000000000000000204361a3f72101dd1a82a78d74fd8120b3c9c85e25676b1e0179cbeeffd3341bd9c23a7dffb95ab574bb1952c0f72981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b0a4c42bc8463e5c99d464900e05c1aba594152197b732e3669b2b98819b682ddbdc79d6bdee56e678e0c2ac1e658a000000000000000000000000000000001450e99c30418fdd3ab051d355f295ab55da37ac3b1e0b817608503a0aab370425806690d3bcb97db179c6fe89b17bc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6a3f4f871182dbbbc5e40f3619f4933d17e4178aa74b72c241a880958c886f830ef35799041424949e86aa5f3a805400000000000000000000000000000000139de4f3f5b4deb8653a476c5904587d0f9bd72139a50b7027ac0824e20ce001585ac799e1d126f62a150a00a2fa731a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136da9bad883290e409cd6ecafb62f7206f68fa3cfa8586824cbd9e4cd6706298ed126e5860b7eb36155474596c352f5000000000000000000000000000000000ecde7140870a35df40a936351d74bb9a7c17933fd842638d44c378cddf7cd0ba8e447048d8f533eea439fc27ec1b0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75742112f08be82286f14eb0ac44135e80e2ee2d343d7b2fdbd414eb265ee4732dd218ee0c5271c6443edb48a95d600000000000000000000000000000000018663bf79f5be19540ca3f6134392462973aa92483b10b78f5bcb1377180c768a4016a7ee6ca5081daeff402e2a19df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4a3d5c23da8b18675326f625c8555b8a63216b7a58b015cf12f0f9520385b01ea7af90c360845491f0f31be33e96530000000000000000000000000000000004d13ba2fdddf20f2f457d917c0bf8b7f144e7c6e1234259757f175008bf7e2807c62bf8364127cb017524a038d9199d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff3f429ab382c5f77a0f18b6540855e046d7ffe99ac42c5f777a1ad1748a9c0b92941ddae8b651e4f0bbb6df441496000000000000000000000000000000001922e039d95ac0175b2fe4aead5593a1adbc096ec37a9aa9de1468f9eed032d74a7908444731a0f68b84fa96d71e24d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807fc6f852669f1e20c697c6ba7a6be972b2d2edaf37640b5f7e0eaaa15e5548cba6580f757155b43544370ed523cb400000000000000000000000000000000055a7201055761682f962eb49387346b60365381adbdcaabe0832af039d16120eec5f9691a795b5b80cbd99d0dff67fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103152a3774d38f9ff9c5ea039914df2ba77be06e01cc646a8c9e4859d240f70d70ed8bb0394df0deec45a665cd73eec0000000000000000000000000000000000e2a932c2974e9cc4db2183bdb2e9508866d749e3bd214583ca7873845399d6038b95bb39cdadf99d39d2cba76ca7d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000707143fa6336fc4f92f0b722319ca7c6292ed962391a9d79a6ccbacad3316df9d9677ab16a21cb7702701427a2899a40000000000000000000000000000000009be48caae2b58d288324b70c4c17da302f8e3b2896bfd864a97f83122f8863ac10252bdd81e8e5eba3ad831903e99c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e6ab2e31494d0804a7703d844de6ea4f83ca4d3c0f17804172bc79a226f1220ae118f0b6aaf2e2ceb985a39d210696000000000000000000000000000000001409897b3ae4f2dac17a321c45c7eee1e787348e01f5408c320ac674977107d04fd298d649c9c24b5909b94f3bc7ed211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e922ef3b61546587cf2b8d72d5ace79d09c39882e9fddfbb028fa2e50c746fc310be6c1fa709441c3267f7880e865aa0000000000000000000000000000000018f92b1cd76a5c146e651a60676b776a30b702f4fc0071d1f07d3be8ad07a3c9b44cf60aea5cbc1bf4d1660273ec3e251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c88cc0376be4de2d5813eec54bdaa3f4b674e29e76beee06c152cdde87b73f94d4f029654c80e6620f44665036bc8800000000000000000000000000000000189df77417243b30a8ee53fe6596840237ce7f1a452076ba30717af727a5efdc36fede12ee51482a484cc63d7688b4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005738835c100d4bf2bd5dee5ef730d4c2539e041b696a9d612e54dafdba9d8b03e1ba22bc52879d15adc03fdd2a9a86000000000000000000000000000000000118879b5be0ef3d7c5783b22dc21f7ebea149bc46ee3401c1e030afa6565d1b15293ac420073796abc3921cc432a5d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014916e0b677b6dd38794d50c516b0eefd630759b6ba60ed52cd46d0f6f6a5040a4b012f53da723b83fd3f6f315bc46a4000000000000000000000000000000000bd104283d7df4227bd76901d02d7c24d8594ea40bdda0522a5a027ff1a97e6ee5e2cf4a1c2f7ba92740f29ce915aaf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017577ceec48b7c761e9bc2ef23475459086743e419c60dcd245f6f96e4210b3e419cd83525c283b0a4740464f4bec43000000000000000000000000000000000d128c33f50a4dc74e847b2e143a9a920e72eabc96d5124a6802585bd4f67f5cecdaea1a393c2eef2ad8bdb4a52bcb8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001254055caa9e7df6e74e370816e3d5f171410bee1b2e063281ccfd5cdea8594cf351d4533419cc86c814c4b22fdbc9b6000000000000000000000000000000000f98027c58d94c4e574dbbc66e1559f57537315318586ad330024c8926dcbb6854c87c473171ac2bdd574ac1d7111a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af34145fef2554fb92ecb798a0eacd6c2cf4bb8ecc43802b55113a0782eab3365b4cd206e922f4dd4d1e2a712adc21d000000000000000000000000000000000b798df6bc751245299341f6d410c39bd59ff8bb6a8a6172295b1d31344cbdce45516094fe3299a58d0453968e746b8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a3017dd1252b6072b5a705f2873ecfdb44527248c09c37db6e699cdb8b1bea38236c694f4e9768550dfd8a4ee438e00000000000000000000000000000000138ed9231d869236b6d9f5a4e20b6854301aed9ae1c33b4858b9ad9d6d9322da30914311c84addecc59ca838f1723b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ec1a0298a1f2c4484cab04569a4a6528d6d5bb20cc6d3c6961589b9867bf09cdcd9d92e0f4a4130e4066e2fd9cd489000000000000000000000000000000000de6c4cc2890584cd615e3ea8c0847c0d6065e480d79b11517fb69447681425b959549dbc8796291f4b69d29e0eabb121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c132c07a3c24a51e743584c064e4da1b0333f557f467fe38a3794981e756337292455234725cdbb44e17ea5d1095af300000000000000000000000000000000067db5a0a68cce2156090669c49d125be123d6d02fe6df0d0ea979ed432e5f0612f33d4e2028b31b671d03e04ca92b131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c624288787e6deaeccc96be907bcfd3b6c6447a68626e48489b245c1e5b7b02ac9e816368bd26014112723734735a00000000000000000000000000000000127697d5528dae7d3d25edf85cf053b40c8d9058b91e855ecd647ed29cd4b3b3534376d5058368cd7561ae0588611f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c427fea83887658879196117f0ba3b1c80a8ef195d3c322628d51a488c8d9d8cc24a25362aa6c2ad3385e87fe96ae9000000000000000000000000000000000fda2ac5d2b030236025507b9062992f28e52cb9bf8682ef933c3fc8ddda069266d985adf3a841d7356b4f19f13ecf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c2b0f1c6927e060fd2e1e3429e686fbffe312ed7aa93adc8f0aa039635756c3feebd794ce61672a7bbbcf2cb789db400000000000000000000000000000000145a0c709cb36cc9a3d9876ad14ae90473122a89395e2efb1880acacca2106a4c0de6521cddacc5f39a74f9956e6d4151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b17bbc8bcec71ff5630840f2f44ee8afa6fd1285c95de1ee1862684ae629ebf1aadb28dec7816235a506527b004754f000000000000000000000000000000001677ef99ed8d05d98bd36b30dfac9490489308c6b69aef8b45471d7278136874910179bc4250c287b3194a1884ea1c431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099b9e7162f8147ca64515763c0a1d3977b2108c5f92d2bff3efe51193a1bac2d5719c603a097fd0b33c198bfe911e3b000000000000000000000000000000001036a71dc229149ea90f2097091edf4e6e35997724c9b5309c1c98faebed852df4587dc279c27be7ef0f6d856b77c6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088b1082c9d3e700a6eac260c8bfc1090bf8b313efb96af470953213fcbdee995fb14267b1008093cdc314d1a2f2a0c400000000000000000000000000000000136beccbb9c4bc8a9628b416bc455df705cee623e4cf785ec0780b2f25debaac9635702b6f90db6de820d62e05af118b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ab0c2573b4767e81fbd4679622385bed85e393626b163ee63194646202c3ff4e6f5394a38a2ffb46cbc8d6e546ef470000000000000000000000000000000001fb163006b922f0561a4594a9c8f53762cc5dcd10f6ce185760745faa516c9f87edfc3123b099bab6878a9f96972bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9cd0c9ea338b6e4fd92ecbd0092f6b9fcaf11c41f1a6db16098b4a9efb974946238c2a250d3c2bd48b43f48072ba500000000000000000000000000000000007a3fdd09ccfa06e5a2280d6f2c88c2e5f71cd43bbd57b6f07dfde72e8c3ae2aa89ba554dcdfc2f74ed66066af8fcfcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aaf3d50538276347a5ca2aadb21f1270af44af2d0a343b97906570fa5ee820bb5686b1b5213183277b12f12c6cb7cb000000000000000000000000000000000f71def9c8a9b6bc555ae3250a7a3b256d15a10180058426fc385c7d1f2ec484f7968dbf0591394060218c0abbae88231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f57b512be82457b8f4575e596936844e9aa6a9fdeb16e204ec1928a1ad519fe71bed7234dffbaa566bebc401cbe369a00000000000000000000000000000000190c2ae4bee3ed2ed40ec75381eb1042034f2e14ad755b025783b65ce3f955a0311e110dc40ce3bb7ee762e41e9832df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ddb4e74acb26fe4b3393dfe1f69ab6410660e764e546e78283e38e178ec521937f518f8b8517bfaab2b39040823dc00000000000000000000000000000000019c136f0785e341984193a5bbeb3bc6548fb31eeced9574070c26f0ffc91ee73b051916f64dde3b9f4896fd3129ba251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004561b232c35fb60bd0b816fe6f8d1bde2a33d13e810aa6e451b2f4a3f4101c7ee12a69491e06813ba321bc927e9ef8500000000000000000000000000000000098fa407e32ce4bde5caa4aa4b1f875e1ed4175b3458b69a406d738003fab915de94617486d30adb6562f3a5ad3b5e961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eab1fcc9884490cd5acfec38da8c601c4dfca4c08a3ddf9fa492cd10d042b4825102c6d7aa3b8c517d931697fc59da000000000000000000000000000000000960e84db7cb48d66e796c0b79540026f504d47ca2b1798cfd83c35f025b92a1b2094882fb85a8ab81918dbf1b2a2d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a81e649c7e25b6802185948df23c829612fc74803572620d7c6706e7ffd4077a1f39dd4ec91facc1ee24da76d37a1ed000000000000000000000000000000000c37bbf210f00ec014f01a144626a359617ee108db28c13f8e14a5a05c17be274a622905ec8df58a6c2071fd556f3a821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ed17ab284eb2b459d711a3fa4862e32c19f9e37d0d109d28dc04011b9e23df08c4872a6196175d05aa76ae6ae17ae30000000000000000000000000000000017dd9ccb7ff37c891e037a64a4ef6e164aff7a188b20113d3be84c88703b44ff7fa178879aac4a7f48af11716b1ca1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bbbd531022c696b0fc7ef477804567d1c7fc16c3a529a4b815ff68828ff02ddf0776ceecd6013470034468265c4c0d0000000000000000000000000000000003b36b2cb7a59852377acd258c78879684cf6970b870a8fb45f05efb85f06a14e55d1a604fd44a15a1c152a38ba22c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028a4dd5e0ed5cbf50feb81b975df8820ec9a605816f100ef69a0fef036e8736b535458a855a0f8f6f7e14c67d9a1ef000000000000000000000000000000000ae6f68d5c89250355c7f137634a53c286672f14e2bb30d1279f16490cc21cda283f5c4a29c86028da593637170e917b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110476c28c744fb76a33ddf92abaf7a147b0f1bc7ce46df5f76a2a41f84dccb6d75a7e6cadd5d4bd8945e71fb605fe9a000000000000000000000000000000001502dcd865a85daba8b4293578ee2c2b030ab38cd27aa041e7cb749e8495a8bad350914a15da9cb0b662602bc67688291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce47436ff67e35037126c1215450cf09b413223bb7da213c489039f437e2b2e6eec2437ca8eecded7075e138baf528400000000000000000000000000000000028db966959059d30027ba64e41dfed409a738e08e13bb5b35ff123cbcc4ab5ea6214e9985a685c90cef36f2285940391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044197fbb6caeef6702f2e49aa73b8c2ea198a331527ea66239d6c63c9560e827ee5bf10f6907d3bd8adf5c5bc800f530000000000000000000000000000000010d8a4ffbc646245af6209100cea902ab38c6ef8b82488390a13e60aadc3a01f205499cb86ddc2ebd8ca3cdb8af08d791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fadf219e7b52190f13840a590e438f0641baa274e66e144a9f9c37fa7c1a7bf6fa6be6a8bd678ea643be45e3356a1b0000000000000000000000000000000019d507a4596ba55b8ab49b624eddf1ef803e4346221b4eaa42a4e83e3f345003ca6596a2d50850cbb33433a48ae7d4ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001820af4318193cb4f303e645d8b3f05910f122ab9ddade14e18c535bd5c74b5e2ab1582a0a5265e4d44e40f0191a7cac0000000000000000000000000000000003fc00a27d948727575a2d7a5ba0c4c3ea596ff3b1eb2e57b9a51c628375138c22ca93ebeaab39e1a953890877cbb0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8ab6cff137f979b38a05fc284f58c32478d05393e3f209315e087d5d89779f290b8e6bd405e779daba59392f381e400000000000000000000000000000000010460e84c8dc37032fc060494f0f2a8533b4f6276e27875abfc4a57f207e6c949c5361385254518ea03e2ae6e5df0a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8bb7b7109c98e70cef8672ccd1ea68aafaa195146fd2071e7c3857e3d5da9d57432ba86c3cb600445f4396a4e19c400000000000000000000000000000000015560f9e322af3d3c8bec7a899368a0d45ffcb7c027ab2f26339d94e1516a35a6450664f8fcd0f5569b81cb07a3616cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe5bc639557dee959ccf9172b72bb6284d8a25806d6bd98aabbced7c321f96f557960b3ce9c1a0074102d9fd1c5e4f0000000000000000000000000000000017ef6ed144cb840ec4cb664d069d246f2912e0e815ab9584f1885f38d17531572d9b537b51feec26f1078931532842d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101f2b7f4ae8d205e885d84a4b09e7de834caaecbb31e61994991ef0361017ad25bf8dec1009de3ef3087d357c4caa40000000000000000000000000000000000c102cf6af462ee1fb901a67efb90bcc45740b67f772f5e40657be8858164831f99d0b94e352b24edebe65c35675933e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006044ce11df891dca33e14e826c54df404ef4ebc1c58f31303effeaf4b41acd0b8ff842018f12f6539b1d2e2adeb89850000000000000000000000000000000005ea06237a571c9a561d54efdba1b03ad64a16a58d541cab3d15a9d4e0ef2da96a8bd0a1f5a0ee897c0e7edb0085bb181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f7730758a63c5c84ddacf0fcbece6f89879d42f1379584be332e6fa8d8422cc1eacb2174c2219fcd1e834618da00a600000000000000000000000000000000084b313b9e3f7f476eee9d84939dc270751281c5f2c8876a687e4fcddad501da2c3ca3e14297bda3551da4eeceb3a3461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049e147ad70e2fefe95f50b56aa0a896baa01c9e7d9eb2c92c64471e41cbd8e94ac867d3d6aaf71996471b7d9b9d33fa0000000000000000000000000000000011b0428bec8f4344ef72e2d3a3bfd6656792c26322aeccc126a016480744ff74ef234413c3ce5630d5bfaab2ca4c42811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cfe7c84f8259cdbb10df2e1041774e914175734f141cebf661c5f8954f76aaf73bea09297826c1c3b470d2b84a31f5000000000000000000000000000000000fd81b5652e55c74884a416f866ec1a011d361df10135e26d2bae9bb4ea21c5afb7f8d88eed18d68b0f76146b0ceeaca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f424eadb52aa547c6aeb02cfd82b00937493c490ab10bea322146472deab2425a8201befacaaa66fe89986030ad2d0000000000000000000000000000000017188451976d4c3f15ceaa2b9ad9974510e7473d968172ff2496f71fd36f812adb05dbbdc401d0cfa0b4419d5284bd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ee5f61d62ffdc777e60d3eda462fd982942d8d7d3a75fa328f1fecb2c31278d1bfba67d728986cc0a717d536b7e7aa000000000000000000000000000000000cfcbcc42fa7e744f40afd3b8565753e8f420b5d7f0749f4ea4a36db0f3013fdd18fc772bcf2bdb93635171f9fa1b0a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f03d1c004918427452443c351912fb464c6ba5c290986055154c88538f9334a33f896cd8d9e7e7a7dc844521742afb700000000000000000000000000000000178c2cdf8b9bca61517accf152b86b2cd9004eec49401e792f2bcdbc54a9390ef011d51816d292c83b19c832b64d4d6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0ef2124eab4941aa70b6b6614c3944813378136d49596a170fbfd1d523c49b25d1294835f95ba91e416e6693ebc28e000000000000000000000000000000000ed793e5e1b84a6f79898a551562ef7eab240962f1a21b54a46d92e2d5643144e9a206cf69123ebe17203c0433583fe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db39aff46275b0f1ad346d89818b3c42501e985b134834e3a00ab2af0a93861105bf7f86c2616b81b57d61516f81623000000000000000000000000000000000c758624c0108bddc03c8415ab1191f3a47a417a8c3c4099952c4eae1f3c3b7b9fe78381d5c0337bca9e72665c5e10fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001118ecdc45d794a8e5da752f07c813ce5d2d5ec99a9d51d68512fe7d20074575b17fb781c925e04c6564a54c3a7a216200000000000000000000000000000000168a3d23bcd6e7c083ab2540b5a719a545a0f02409265a5cf34a232c268e3a635c975e288b8c023e1444fac068b6d3731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072bd0399cc64f8e8f80f109618ec63a63a441c0bce0641b20eeeeec04fbd31c3aedd8d8218179d7c9f323e7e317f88b000000000000000000000000000000000250566d87cf739953cb0bbe4e29022d4f9b1217b40432aac6e904dcd6177df6f120d19d13f59577a349c18db9e0c1e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ca1005596d46ba521a576a7876dea2d54822f606d11e9a865d1d2d2d40db2970d1f1eb91571ed7d7adb99c0946b4af000000000000000000000000000000000ff5c3ffe56b281045b302976fac3a586c7673918e89b40f148eb5de54cc7456e5aa354325146cbf33a6ad79ddfb02d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eae449cb76344bb8d0d875ddcb722bc7b6406f7747bcc872b3ebc4732dc3c0ba5ae941a90d6244224c14d37ce318e9000000000000000000000000000000000c3d3b1c242aa396588857f2ca9bfe5a27e719fa4ae08b48b2d67d39ec1c10f56663577d984b9697c78edeb9e7ef20671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f6885956471becb7db511a0068da34f58a51c6dc34116b780d3eafe165f6b2adcbc8558f2d80a2cfc5179c0254dee4000000000000000000000000000000001622531e50446bcacd7c9ccbbf458e900f174e0ec914e9b0763d5ffc969876f0ee4708771fd13afe872b89abbe02f8331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001495f71d011d23767192a7c5e4b029cb0d09f5b52cbe3175d1873c5234994114fee61223e965bdc4054e3eba2e8163230000000000000000000000000000000018e018bfc4c6e63653c2719696b7d6889984b4adc044781e79549d58582cf096b3b02203381ca73db65ddb6bfa3efa7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a590b31a9849ddd77ec83c54ecaf37ce3f85b3bd0acbe38234d6adbf74671abb5598ce6bb34d65e1d399d3f38417aa30000000000000000000000000000000000352d0e73c6b5e4f321643e9311f8d220549429b90865370061a4b54112db26831a4243fb653143e009be13d11af0b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75a7c76e7ae0172263b05a61a1205c0c0d1ae2df07c7c9873dd5eaf8b82aebcb3ce9fbe8afc50d31c5e4cb63f3026700000000000000000000000000000000081b594abd588ed7710e6dae6b3d84a3e690ea32d0242f2846b23db056b92d5784559fb390256ab110d9e835ffe8769f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000536ae82c661a58b4599f29c29e4ba5bc2c45b67511638057219bcafc10527bfe5d927ad0800ec01a170acf3cab4afd000000000000000000000000000000000c981e963ff54df01d85a172f375c855e4e0ac6a44d3580b2c008b8ce2379ddbb897587989f7fef5c39507314e6f1fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060d70d7b323f7e4d1f1f7ba8a530998575746342eb840a3a308ab2b101b55ce870f07ceaa7087f57222a383c947f6fb0000000000000000000000000000000004a3a3b312896aa719aebffe9ae7cf536d5c1cdc1ec04caa77a5f555d152b8b3b6203bc1e6655a94cd0b970ec2c0c38b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048061e01e777e517794a89e8e08bbfa028dfc6d3dac3993f0af4608bb4273efb65bde5ef98a41a4e95a7e77a78356b70000000000000000000000000000000002ff48c3945c43751fdfb829ff4b775db5a2a425e73cc57a7d88509ca4e7081879695020f5b442ddd3c55a2cd647970c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb3cdc685d2e912e00518de50123d0563829638cd46518a6183b88e2b1b0fb37bf63957718d8df8f2d0688f29e624f0000000000000000000000000000000019cb7f2677aef17e0d414577887997845e1aec634eb7bdb327b8f0791f82fbb5eb55d78f852ce77cd66789f96e6e9d801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123a9fad69c28ee2f8710f271fb6827ebd4a393768dd3b47367f44ac29942d2e089c5509ab41e3b3bdd18d530c79f59e00000000000000000000000000000000026d84bcc60ef42dcea0bb3cbd3e8b695a65ae04fdcf2f7f40e459034af82821be7b034d7408eec9b813255a98ea28e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f2a97a5669d252dcab8ebbbbe10244f2e0e29bf49bb0fc6ad772965ef3f3ce352752afdc5bed1b9f851d62772514ad000000000000000000000000000000000cf4fe7217f8d84ababe2cef667af63c306c0a44c113aeddfb79dbc5114b315169852b9806d5933570be71114d259fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076fe6e63676bdc71cf72f1f306d0496ede550cca31b72386b34099fb75c86a387717069a2d59d7a29357b4e814708d90000000000000000000000000000000017ebeeac5e824240d0dd60d11fe293c7092210fd633947889e574e24fd4f30f02b49b65b045999e545b497f9fc8a82081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088bde6f7caa65dcb745403c6645700280aa270190bf9bd265003a21407fff6e5541f051e64d6747fb9418d6813a037300000000000000000000000000000000063db74d5e321fb54bea443e997a865b3249639fefc2a23838ae4a5a9fb0e866d533b2b3c07ef22ea14d7a78737634561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000610752ec6075b6694afc2ddde05e2b65f8f28ffae628b11ec7faa2d423f172d5fb3062cbfd2ba7657a7d7b4f17052210000000000000000000000000000000014564a4848e2c442d6aac740f943ec9b11d6b076b7f7b711859144259e6ab2125b05834acecae57acf624784594209051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073a59d827f6052d7095cea51cc76d426247bd416b113398d738298cfc721e0050f3f9e4f4efd9067fdff2e19877b86a0000000000000000000000000000000016539295bd719ff861a4e38dd57bfdfdca65b8785daede242b4b4568a71563bbaa06b943b855b08239bd7bab5cce40641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5a8d8cb68897ef727fc6265f1afc9df200e89fb01312654055567edd4c9d7d2f4053dd5ba7ef3169c2ae38295429100000000000000000000000000000000011ac51b2162fe981fb44d6b840f103264025ee1dc57759ea630395561ab841cec65f3dfc69e3cdda044166e9bbae8471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001616d71583724dd03aab3b4285fe4e2bfdfda2dd83a1270a9073616823f091b081f8f44bcc0a28ecb9605df012bdb87700000000000000000000000000000000146b7d6d87e40a6410aeab5790d966b45832aed85b2fc7885a7f3bc922096709dfc1fd028bf26934afef8456a0d58b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6786b2140887425a8ae65ed3028125f4ed3e4053ccf5c487e47eca96511d0d97a30b1ac0096dd16357377c85d3c4dd00000000000000000000000000000000090bff2093048f94ce1545d7a737adb2cc76cf20ad3926c10717630b684a99017f22a6c39f3ed1b9a7e955140c4354cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c73616481fb2fc0b533ea07501e8ab2c8c797db0a3ca2517e339ec21d5ea32de4c28c80adfd1705bca87449b2cb5860000000000000000000000000000000013393b08d1b37c6140256337a3b03fafa5ee3fb6e50dc5e2a0d679ea08c73e868e76d4a1a49cffa553a37d2a9285318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011db23779842201faff024b712ebaca45566181787cbee9418ca0fe2b966ffa24cbdf26549bf5705d552a92ce1f5935b0000000000000000000000000000000014f7c460337e3c4413a49acf676bde6e2b69a500e42e4bd5be590a4f9c9d37a0f46622c0fa7940f25a654bbe0dac07bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbd9e173d1d5317e1388f922a888087b12bf63797a87e1624d47c6ed89f2a46abe4438648471c7ee69c5f6b6ad2a86a000000000000000000000000000000000a498b77785e85a0ab8a3061557b562074e91112f186c2f1552de927f146749f3358710040df403d0cfe58096d5266361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e276dcb04064cc2736608bf4d9f45c2368f59ddcfc961e0776fddb5a61813aa91ad39236524b0ab7ebf66407edfe000000000000000000000000000000000198bdaa519f206b71b4b2ba3ca5d239c8de4f121b4058638d5060d2bec8fd706f27dea081c555c2dc18aa28c5ac53fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001733b475453d6987c9e417399c4241a978a59242036d088fdbe822d51a9a73a5fafc01c0c9fb2924894fb177b8b1136900000000000000000000000000000000126f8d591a97322b0948f3230d025a20a9e6f0bce400fb15dd7145aeda051979b97830da579a39e3ef7456bdfa3f4e3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c8c82c648f4f552c3aaaace443860008e91062c285ca527153251ce051050014365864f683b60bc4eaa6ea3f3c26ab000000000000000000000000000000000d6a6a8ef621dff9d259ceed3f7ed4a44400741bdadbfe257341de6ce7cd3ccd5c7c86b2c2245eaec65decd8d96802a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c95177d7a5c2203ad8678a19994f4396eed5ec8194c1958c91f66122cf1c31c1e09554b236da69c8536ff41963f82c0000000000000000000000000000000012b3fd4c9bfbac1f22006b2c1ebf06d3c652dfa0ea0ecc435c8873582556ded084df1c6f4808b9f9091adaab887343d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b7609b2c6a27d602806f24fc45357f98d62304e8b43a959c1f11f0cd892eb0e6f6f87bbdab1bd77ac2649db68381960000000000000000000000000000000006a70b015c4c343ccef09abc894daf520fc8d20b6e0d1461da450e935b5e94b2c07f9cbaaf948da639f69188858334e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ad0c31cccf8979062916c64cfad9e1151ea6506b2d46efbc819a11d3549a9948b199895f9fe0c05dd445e1306699a0000000000000000000000000000000004a7be9220cb74c62e745207967ed0d5820c5ec6fe16f96f1a3f7112e7e76b9cefe8ac86fb25fa296552c86e0a544d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158b856f880a537997bc22f740ece5b67cc234bf8100177fd48ee3e95ff8280a9927a6e48957be19656d4506fc6652d5000000000000000000000000000000001480ae0d6b8111c8adefe373cfe6ecb2d9ea0ade44129dde2c0cd1b8ef6f79d32cc2933c775afc381d9d62fe600a60ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000032710ee67b2852909ae2537b6964a711cf929c7e5909e1cbd1ece2c0b302f4629dc0112b0ceaa1c45313c6b4e1fb56000000000000000000000000000000001805b1297892a09273cc97b6d8dd6258bb845f8f32ab087d840f08577949f7d1558a2da4d1e3d88a90c1f1b82a7035f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d007c829703c814de461253e18f12f9cc721acff8d82dc7dd4f580738180f3f11f6b01b6b04500e691abce0f2e84c10000000000000000000000000000000009a6e7e3998fbb0d803022ee8f8ffb6dcd7e227a730d49a9e11ed709b91f18c74269b05289cee0fca67894aab8aa19511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b841fbe72807a55f1cd6540d0ef63674f8a08ad30db6878c66d1147b47b67b3a69d19a3eb98890b92ba29ce93f29bf100000000000000000000000000000000095b85039fdcf946b23f52a71b6efc722d3bd1e601341031584d735737a70cd7588dfa62053e03baa7a55cccb61d83991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001999600ccd5fdb94a17f7626d147456b5ead657a588b87ddcbd1c5fd30f01815632f79ddf7e00e0d5b34bf779cddd2ad0000000000000000000000000000000009596fd894043e582baf04f6dab4aa24d8630ae8cf6440743a5d636b74aa18cfbd9ad84e0f778dc9b0e5eb0dd3e8168d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce76f3232af4e26d44aecf0f34616572342f3fb64228e709ff279249193e537fc2413e584322761594c768ac83b5e500000000000000000000000000000000103b41786f5477b8189934b43d79cbc29fb7afbc6bf1c1cd88357a37b5f996885bd071286386e1cf5db6f46d16fe508a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641839018bb72cdb6391f94e99c74e402843b60df3f03e3e362d8a534a81a115720453c9574df2b93dd27561eda74c40000000000000000000000000000000014c91b573c11d0b5a26beac01619cf51010a0909000a52094ae13bdffda2cb4d9cd7e48e1d1c171d291dfe9812fbe7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbae97970aab184aac94bbff425ad01bc641585d9985e6378b4841e74bf4f7cf82fb8559aa6c4724103276cb7aec4d30000000000000000000000000000000009beb522a5297e76969b799c572ce74d6ca92f19df848f027051372f9416cc882d11b0dfdc803c6ab871e26f2560f2e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097e293d62ba305e6f6656e510a0d6e082cf2f782a7b41d485171fad9e338f21bdd84248fe4652aa3e2bc95e53dcde6d00000000000000000000000000000000143e52c9396bea4c79a2e68886c762468c1328e75df73dc3460f95e82bb4ce85ece96f3aa074fde705cbb26734aea3a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ad1e9dda4a0c540a2b91b2fbcad6b4dc5122b0b63d5b2ba1fdaf025b4932686d06ab4835c68ddfb6dff69c4d0e170900000000000000000000000000000000140f193c508a348e877f31aa36cfe2385898ed32331247bf6a204cfeb7136652b5619724f234303bd828abb2c5b25eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001792580d2d7bed5f4d7187590c4f4c8897929d30ad53ff5744af4fbc4b5d5c57b74a1c99e24860acef4dd87bc71be0670000000000000000000000000000000014356351f568196c162be30eaa96d209aae93533e449fbc66467e10ee97c599dc4d64284452f802f6a712ba580d3f03d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c275272dd72342fdb1f1f4db4d8ba82a751ee379a87f26d7778c929a56120a96f286b2bc8473edaf2d3d0653d777f90000000000000000000000000000000011c414d18595a1895c9af42365241095b6510b4fa5704256f714e8a81d3e4b1acecea7cf4d8f2bc01485d6903ab54c481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cc84f2190fb3643989137f8884bb4eb77416ac395407af554e8501503ee2e145057d4f22bacb629be1b0dad7ca85d8000000000000000000000000000000000f5fb1d1b64022599bfbd214725302a894f032992475349f23c2868bb18fa1836da38981f333d3004b8921a50ce3e2ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001307776aa3c28f99f6be998d64906219ccd1b880ab54a588d8993ed97a1ecf14c12e7694981f8140faf359d21776f9280000000000000000000000000000000004859e8acac76f4b2af72c51dd3497c2dfe40adc65d4762d3596f2415844eaa4f709c4b81307aa49f272a074d30c20db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095cedfcc32ea620bed3fad20f9d17057bc7b291a49f4324214b1772bcfcbf27dea516c8cfbbbe944339bd37a4289a230000000000000000000000000000000018d29e8cbd01d664678245aa8c07de3f2887b5dff09bd253a29d36b86699bca406d4eb473ab0678b52daf93f812b5cdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001355bea25feb09895aae1ca997f4a88b31fbcdbcc20cda7ee8f19a01b897343104d6afad6c63b7de8b18c5227fe752bc000000000000000000000000000000001276aa69bdd1dd0dbe110ca622ecf1f9f86d2a7dfbc486302ea0f76c232f3ff60e69904aa998f33eb0c3dbf2236bc0871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019151c38d933bc2a74c581db3cae81bc655e0eeb3031112792b6631dded36cd8d69e5e846ca8beace0ff495b5f934ff100000000000000000000000000000000182e82a6008f4f93795bf540223eef3edab53596f223d42010a04dbd601373681bfc3c5454419995ed75d0ef203ce62c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75d48ef374747f99ce2c6a4120c053d2a8cabb1cebe37e1f925e9fc34cb57a0679c18784721717456427b60269f2b00000000000000000000000000000000019c99b15a1c50b4c7d6754db62ccc0fe505d637e116c32a2136b80062d33fdd64980e5f88b277aa533cbc9b3324753221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000093c0f6cac8cad88679f212f3f69621d92560d51eb8a38f07fdb5b0e47f1ce890123050901fe5d5eed45bb769f9e3d6000000000000000000000000000000000942b35046b666ee55b79f151b21b5ab7364fab5a73160ae81ccbf61900a8b0234ba4d50613128796f0d1c1aed89ec761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000171054e20771fd095632ab51e13836c9d4c38799be1a75a74532b15c4eed6bce7f53305130fe9617e8eb447da911550000000000000000000000000000000019ecbde7d21f4aeefc6619d434fec381cd1e6ff5d755c69204e3ffac4954ec184c2907e8690b6ddc822376ca2c2dc10c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001112b63a03d018af74ca0f27bc645f6f17fa945be8b1aaed62a77f743e31368ebe61fc1d58f438fe84dd9ab78108fd2b0000000000000000000000000000000012d7625b134d15b5949247d55e95d146c6e30c3f0c8edb79ee1addc9f1130ce87d66c9bd071d89c493e76afef30f223a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bd2bb6707220d1c16d12d89f95b6dacc209bc2bf9a27273c5037dffee7c157d4ce0ae7eca0ef5662021baf5e87ddc5000000000000000000000000000000000238257b34e5cc4b6d6f3812141f5149bc20f6a589594c0b9e905f6a11930c82cdb8199f9900fc6c7ecc1db602affbe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bedce42ca45ab6dde10dd6dcb79cb9457a71ac0693a770510ab21ed4232fd23af6027b9e431df35c2034af3c12c932000000000000000000000000000000000df657ccc2c2b2c20c6c38ac442ecc82d399efd1397a4d31ec8c3c0d4404f967ff585cee82729f86f851c6356ca0bd251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673b26b897752394d5ff4d55f2c2d2fbe3ec3d91c6fefe43088e1e4b1e539d0b0369479aea4af3fc23eaf35e02e0ee100000000000000000000000000000000079c3da3911f44fddf352c3ad99dff853753ae696ca3f169869ffc48a7bdccdd023d673c38850eb5593f4bb37a0d896b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006a51a66a0d9ad4cf6d6a571269cf61d1260d8c73200716b15257e824ce40f9b65423f66c5cf5ece60d9a4ef17e44c1000000000000000000000000000000001145016e95c35b61aea66b4f2f98261c2ecca66b236c8b94bc2ae6b1a53c31774b8b58404902f55619784d3d819cdf981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001166faf413bb0f32a625af9d223269e43ca5a71e0f92c79ae7981ba876321bf008bdb184dd961c2c3a347e5e080c2a50000000000000000000000000000000000c2703d0ba96eff7d258cb09ed4ada8803d373e2ea4a364925d14cfdbfaa77dfaea9eb3506b058e615c42bd7c200e5e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010acf0496dce4a3d9f0b72ca5cb1f59675a294ac8f92a7539dfa661b600161294b37a99301a1d27b13a0b12e3c89bf3400000000000000000000000000000000168af6cdba3b31b3f865740d59764102d350b714a601121bfa771fd207fdd6222c50c464467ca2194a8b6d3b5f09e1461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025db1a6c019d7873fee3e7f2f8d40866f808a8a75c437aa2046239580ccb1e3ecbc7f00149ba5b82567bc0108c0a0cf000000000000000000000000000000000de040edd5f73de4732c100134e9d35afcb217225bbf0212ab5d3bc88ff5ea7d855c86ac701e18b910232cf80956e5ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011c8d1025df627a8f60eb96e6051aa37e1f6216df1010bc42b3d96eb5e2a8ed53d03eb50fc6d39772c5899c6012560b0000000000000000000000000000000003aec2de34b07290a3331270f01c3e317d8f3d6c0855007d70c7dd9e0852df2143d3c9de905b0a1dba1eebee88b3ec5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b71274f2877a8ed00d3bf172d23b9020142de223f2336b786fbc355705ec8c09353b5af777006de91f184b10215631000000000000000000000000000000000f6484f6a20fb20978e9eb71b94b14ecea6b2e0bd55f724a076b0bd5c51663b92695e8e3c700732da45eb3aeae0e00941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001606eb6a75e26b280f8058abe0c452fefb02a22571f561eb143315879750db12098b0b19099709388d2630c5a339ea8c000000000000000000000000000000000fb1235241722f2e09167482a1067cbe66583fa639081ad4c8e3b06116a53fcdac730bbd33ec899937cba5ba5a7ac3291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066fed1a40f5caa0cc57d78562b11630b3eb40b43ac28bceaf114f78304142d38526f872e6d5c3c83750d5530874b5ea0000000000000000000000000000000016535316347e4b7a7fab67be00de108a8f9b7359a0c49a2d58b1279c3e7e0aa8e63ca8c01a7cbcd08413019f74fa2d801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130b1af5b6dc6e504001471b953dedbfa505a15d46a78c9364557d5a9fc723d294111c51af73189e53aa2a0a031ce87c0000000000000000000000000000000017c7f152c5dfada406db46aac0b7d8f7c7b56d5e08af8914807ae6c9e9b11dee56c9545e722f2f8e64e2990b8cfc70511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001952fd20672ae2486b2a1bee1972088d7ba1e990231cbbb8bdd8de855fcb23f9dbadca3bca7105e6eff71fceca33ef0d000000000000000000000000000000000a4e31d994906894a157a5796692f1e6f5e033be2e3a01299194662d975983fc54854e839f879c3a3bebd17625e1913e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150681d80a8f923e2a2fe1f8f1a19ce7765c913c5ac1d71a03cb853bdb79b51316ab7f02a9e04b97392cd409cba1b8ff000000000000000000000000000000000a01a5cd056f484a3f97082b8fdf43c1ff00f5937dc89aac330295dacc1ad832f6a6e5a1e3a507e67a5419e9aca39a791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035558b530ecb98ff1ecc5c3386118cea40ea2d25d2e4e8e25bbeef7fa9cd69ae39a4de78d5665c0900a236f1760c8d4000000000000000000000000000000000a7dcd3fbc8bab4c853b9c298b1db401484825880f6f66652350af4b1ae2e74297cfedcc6412bc255a4b374f32c06ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd759a0c8524dbc755bada8d373b4719d0bcaf9a722e976a70f40b62d33fb1215a4a7cd1402fe0ba20a9f28d7ad57c900000000000000000000000000000000185f4cea3e456c25efcb4c2a5770aa5e0de4b2556e4c827ee234531c5785c29148b36808ead601c108e0220d554b70a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bac42521dcc70be69d6ea1e844b99e870cf29fed3e176ff889dac057201c3d7f8a7d9bc7b61d6792b273e97885a84d90000000000000000000000000000000005482985e06dbf2510b90b8be3213640b202c5ec6c572ffef1672abd02c55f15a97612902e270aee0e7f47f40026e11c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083e97e8fc6bd9d5fa57a30ae72d54283d6fd3b1ae19f76ebd64d5264467222214d840e48874ba51c76315317c5e752e00000000000000000000000000000000119e5ea8a334eb2f367fdb5c0c40c13809c8d8224e206c6a29f5c5bfa18c7533e2ed9971972d36a6d6ae483ec0e95fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b2cfef0ace9daad7baa7629eec891e7ea578209ac9bc94a4917cb82359d99f11314a5f81f2cbc185ce25d90ce81a6a00000000000000000000000000000000174a6b9fb60fbd017f214d002ddba7596c02beeee3bf9e679007214fea6d60c645109c3616079c2a58e0784d04cca4781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a272689068abbc959afe2845ce16117545fc13ec1d8a6453a87763439f3970ae01eed6d20e02331f1485570a14d826a00000000000000000000000000000000005a1ba371762575fcdab489b072ac197e8dc65279b09ac3a94b19bce01fd80408c82f094fa8a7ce11aa2925d18cc0201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c534a60de438b1829ef559743dff610495a93d5d9949eb974f2c0c78cdc2a9b64414a0d1690ce7f005310496662d1c000000000000000000000000000000000345aaa1a7ba189eedb457fb99b9aa3b0f5379c224bbacffb3ea388fa133cc82f07b9b349d09846162777781da7f91261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb3041e6973b2440ffa499129350be0d607437acf5a92ab4cd317df6293300e2612d69e417bb58225ead19da68b1d3000000000000000000000000000000000a67372c5bcc8476ba59600fd347d7bd0bc971d86f52b6004bdd0bb8413b9aaba76dff76465b0198917e5f66b0881a3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185770d658f382bf37e5e28d502f1a8d1e1fb16b7846cdba8d0d061cbd4051d4e77225e4683432e41f3a923a51d9f99400000000000000000000000000000000073860d68f0edc329825632061b7ad2cc7c0de07367ff8165ccb3c3cddcdf4b4ff539bd2e2e58b81a617abb0f88773fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066c51bcd2c6a821a00a4c1c5d81e3c5fa817e7a5adb25f9e22e4563e81d75f31c7214bbcfa1c1dae6b0e662270c862b000000000000000000000000000000000ad0ba0f5515dd08422fb5303ff389f383ef399499c63e3873dc00ac744dd856c5e614510539dcb7df0ed2e7348691511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4251016c0372bde4a05be67765ff833d7116cb5718cc6147ae269d935eef194f7ece096a210aeb36ce3ad931d905e30000000000000000000000000000000009131dd3c9c908f02307c8a447003e18fe07d106239e5c45f129fb1af5ac1480aa74585b1e9d4c2a1c9289bf8bee6c401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd49e84bad0e9b07ed81d57218384a0b13fc23ee981e95c634434ee2d2fc2bd50305ddad9dadc7a845da89b0e82c7c000000000000000000000000000000000b7d5806a901c14f7d149a1febd957589e095e7a0f751424f5464c9a11fe87d0ca6d7bbf2daad42006b32a02d46809b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ff38766c7310003aa1e05d172b9bbe9ef867bf60b8f01647069dd7865d0ca1b4d085913790cf866f502760a4afb000000000000000000000000000000000017dbccae6e9ecfd5854a57f1fd1f27309e815f03fcd87236af60af1a0f910cb89c77043ca5508e38704ce6bc5b04e2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bd8417c3edf98676d31179914a5e9e248420d0c3e164c38a774b2a85187ecfd27fce8a7c8aafd8814f47150b1a8d540000000000000000000000000000000007afd52f80daa5f04729105a1602aa66fab9d6249dad4f4e1b55aee8c98bc9a2dcbaf36dd96647e67a90598fb1f90cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5dcf4cc9a605968c842771e80b430af1ac6c325e73917d6c9ca6065ee88975007074033b68f54dcc0f1659e7f95d500000000000000000000000000000000198bfcc0fafdeb4f45cdd4fb65b125803270c182d9bad293d6525bdad1ba6ba7e930dee9e65dc3b61574642e5e6706ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dda18ad34f43bc17e3f8708519dc0a31d1f1c300191a7a57d6d80dacecac18d53f89e39141a9909277c4f332284de500000000000000000000000000000000139c2f42c8d215fe43c8728d6f89683a32ec4402a288ac1a079bec56a17fba86d70eaa09027eace5e9341e158418f7221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008357084539860615f2a6491f0b8828993490397b766404d0a97d04a7016015830fe33c29b5f2159e874860919f0150b0000000000000000000000000000000002b69fda7aea712383132d2778dcf9113d49cf3731662df06832341dfa3851e921d2be47a493dd45a90c342ca8c39c7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f835bc3f8a6c845087f6460f42c58ac08a434f04e61d7bb167d64eabf8ae37bcdd9f4520984a4f15095b14e1c39a2c0000000000000000000000000000000003b00977e36b9aeac2fbe67d2d4361cb646ab7ba3cbc82495865ef5ff7045fccf74d0fcd1c1af845dc5b63afdba709991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0034c649a979f9a7fb38cdbd5139c1c9fcf7b5fed2e01a583f6d78e8a083f89e73dc0c360ede09826ca2761be4bdb2000000000000000000000000000000000b132f073f9fe0c70da323c711925d1cc1f7ef024e7c5729d9a5f31df6c4075399d890352dcf3370e58c3d6270c467c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721ee2c1cfedf346f8a5b4b90ebd2f41ee47573ecc7793a1a63f4c6c91266299ea588633c54c919ff4aedf418b3381c000000000000000000000000000000000f3d58f573ffded7c03206719e71e3c776d689cb41d3e693b6ae5d06db71991aae1bb1cabe822c2c145e221181c869001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000580cbf7539329132027d92701d69aa550fc2445b24f704f550556b2018ce49a584eaf95b1dd55d39471f17f06bb4961000000000000000000000000000000000cd0d571c7b96a54d9d11abfd69051b8d5ed89018844515f5078bfb657ee09e51557ee79fc49de3166be2c4c8467517f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c22b26f017796f8276727446efb3053822ec24e4fe55ae629410b26a791d4a3bab71eb845131800cdbefc5d0b5949800000000000000000000000000000000118d1ce29682fde0346b5b42d86d11ee4a2fae6131f8c74a6491da1d4ac5898a2ff9208fc9a2ee331de0923df7c834631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c82e0ba1e9a49fbaea47c1e1e1b0c8771f1ba263601b4b37289178df68cf4dec35c04cdf55549ebda44bbd8fb1e8d50000000000000000000000000000000012f56e912490a2ffe77c3759f54f4909bad27b9e1fea231d510ae9a4879e5e78603764bab9bfc8f6f4d629e79ff8bfaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b003e57e1c74fedaab38e0e2629e6efa9afbd2de8239a979d420e8034d24d15b45d989a5843cdce523079965263ad700000000000000000000000000000000036f893125aad6575996da90dabfd73c93f793c296b6e08123b1c0d9fe7bb57a7c52ee9ba0f72dbe41a93b2dd428da921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f282ba2df9beea080a1463341323945ebfd30c5b68492febb868722ec3e32412d8f692299670816d3994d30cb8d4e5000000000000000000000000000000000e2e03c9519430e5c9dec3741cf0f3dad719fdd34b9857ef9a860cc0b786085629cc32a895ad9181a21d4d43356cfb491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2bb6c1769ab85dcd0227b375dd6b14c4b58495d0054acbdd77569b4c59cb759fbe0e2a8db074b0cf43594ec161add0000000000000000000000000000000003a51d198e15a3f26abbc98f7791f5a94d4eaf3d455834567fd0967bbfcbacbbc81e835add3bb8c7cc16c6e0d58604071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b18eefe08f146eeb93ca3011510cf6bd45057f62a7b20158d6e6a1e40295a4988cc3cabdc6e0012ecd5d0c8df0083c0000000000000000000000000000000001fc37fe7d05cb55e9f019925194070c346cfaeeabc87fa3bfd133ddfd82340cdf33b0628d5eb4e6ab464a42f6966f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001195e53fd2ff7175fcea36da131136eaef8669bbc20d2b31596119ad1ce1790a16442e1dbbfe237bb0820100a8f3b830000000000000000000000000000000003118c1236f48d28099d8bf5dbb16639b4913d231d1813e2b4687f9c53e889308988b1848793111bd9f73b1f410d27161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdec6607776099cd4dd93007c5ddba4272119d37abb836a82dff7c734704f81a9e31da21b491bf00d56851d6f1d9ff50000000000000000000000000000000007734d972cc7a64d979b9cc66aabcfbb0b2ad77caaf0ff40cb9eb78183fb3178c2999cc3bcfcc6864c1f22803d80e33f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bae441613a18af6e0049c78c23f0e784d0f0137dd93511a51b398738e5eccdbee89400f57f9be7f88714a7d33f0175000000000000000000000000000000000d363643697e6c58c00168dd0b3df281dffa2d27bb4b172a08068bb2b05cb9c1d2da26f8d512c329eb64191a84f5050f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001679eeb2722bbc5f31822673c07dcc7a263c1c8cae7bd058998659a954a55624455fc800731f06c29653133be8ec755d0000000000000000000000000000000004e62ca6e2fb6f576135c06aa5b53bf0bda70347d60f8f4926f2d7a515d91fd92ec67486eb9e4267a47a62afb84de05c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000199df9102d15e0319584ff77851c04952b5a68f477ae84d570ffada39a0cec817151905770ffa78381be32a397f3cd80000000000000000000000000000000015e4e114824b65c9923313ceb2a7d360f36d07bf5e2011d6beb00f97c92abdfa6724112c44e7957476312a3d17e659b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122b47e56e34daf7653d5bdcb3e75d887553ce99f21bef5974f9b2fec5184455a1fa0999af7f28b851a420470c6cd6b70000000000000000000000000000000001542687df8e6d52972bfda3e5dfa7dc6bc537ae13818f31fb319adf5b042c7d8d9094f428a3d766208c501c6d43a0f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de152a37cc3ab1e9553e0f54f800e52b155d629994a73eae549067fea6d14a0c2b156b1ee3f9b781cfc3b3b0b88bc3200000000000000000000000000000000083e2a21921a77bccd34e8e626c64cc445a0206a73636fc8ebc5a7c4b018c36029f4480e2636e4b10bafb6a651c1282d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7ecc412be53d20cdfbef4ea0ae7007f25a8218c39be732c91b34e7ad9ad05a74cc69817203b8929bd9c16568573b0000000000000000000000000000000000fd10504cc3d8ae4ab0ab1ea7492d7b09362ed5ee2c5af9d3868a28e029d5860afda4097cabd18c57e53ffa6c47334661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001719bd521a9e71a9a0f7192b37aab412395fe04b55d000309ffd1e9458d239db9799b900715dfb4930b60af5d2c3763200000000000000000000000000000000191555e483ef578b9183d74ec432814e484be7da872c5861a8a9e070472115dec554bda7c83bbb7ca2f73f0ec67b05101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c41e248635fa186c4497851c814e124988ba8f4db329c2ae72ce5665d511b0cf72b3ac3122d1b825f5d14ba6e3e67000000000000000000000000000000000242e51075aaf087155ad59f34daf37af824839a3126f2ffbc29c2ddf4c832f36000ce312a03da4568bb01773cdbb34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189d003b0551a8cfab4ae83ac67e2d97fa7d3ecd470e841395da9969aa48b9300f8aa7ef4e5c00ce76b3974c7524f552000000000000000000000000000000000427211b247b475aee0274df2156121639e3dd759ac85a9a5f2fbc80251d656b9a8301b3da04cb1abaf94ce133b871db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000886617997d171e3ba6c99a27b2b79cd48d4ffccfae6cd213d716f766c75b77a4a8907a8d0bd1ad7daa650569555681a000000000000000000000000000000000c38d5187a918db63662bc5ee2ecacfdcb50934721019cc8e2d951bb150c910986b127da2b099a78af227f1a24e8bc2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039c3f38885a296dfc969dbe139fe0ba8850c9849344e43959da74ba3c88336b1f9b232923137e00f63bec94964e453a000000000000000000000000000000001001b0029ffad34d03f4b566317c6b9ce0ecfc9e94103bfa91e5a5224a41f11930846ced29939f2b33d29685890ba8ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f4f05ae2bc9b05ccfa85c0d751cb2c0522133d90cb1d422ad71c69b6e5deb9aaa729c4041ab1410043eeaabfb8d74c00000000000000000000000000000000188b44e4059c88e9e3a5c084ba310a1069924fb65d592ef4aa769709bd39e68103503ddb88a6164ddc8cf931a883583a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7eef955b9ca1efee65980764104bf950223715f740584aa8d4e1178db867544cda3d97d43c835b3ba4ad9feb813af00000000000000000000000000000000182bdb028dd8e51364c986a788ba4058b470719d774c0e05975c564be87eda5d7532f926c3015e73a0dbedc9609d16ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f2894a4691c802c027d769cc090c3044060798c64aeb5a2dd310b30b998cfb67c47be9cd8f80c76443231e06699bb1000000000000000000000000000000001775b6cf3eb18fb3186a1cb7fe202a2de13940b523260f6d08f0f68ce368c9e24982027b973b201e8752ba3e9a7f77ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d7dd438519773b2494c3f48f94b6ff388c69d0d479cfdec6200f20f14fbc89c169b67abf25802cfe570d162e53ced20000000000000000000000000000000011a236c092df352578458db1765e09fa33349d18987db181696db16a7fdf65215ce31fa1e2b40afb5ed2382da101e4201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150bf08f70f4de3cc46a9b2b4a02eeb2e574e536476aeb2ffdffc842625d4ff6eacbce0b015a45450836e52cb775a8080000000000000000000000000000000017a6fe20fe5e4e34e810fc6208d5572f1b3bad1130ea35002aa3b8b8b1cdb9c255471051de989d73f7455575a77269001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034ca0147d6ffea3579c17b5a781ed74243b56692391b094ef1e3b7e795bd7fff4a6f4f00031d249bd42bf36d0b72ce80000000000000000000000000000000015a98ed5d981938cfe7f3ff90d838e0dca637557bc54e4c1487a59ab66d16343d42d316edf8d2cfbb324492e98865d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2166ebc6162beca7edd8f0770cb0af3dccb41e613940f841c7e601bc93db8afdb29960827c2245ae9bbad099458cf00000000000000000000000000000000117c22e8d504895ea1cbdce447698bca28affad52d01ec7817c2ef4d451dba46cff01364ca87cac4c0e3031ded1eefe01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ce43b125d8ac3323e9f08d13fd556207450e996433da1dc56fb634bac2422dd12d3e72ea8187a4fed7e6aece4ad25d0000000000000000000000000000000002893624b134e5e4ed4a6ea787b39b2140d7c6f0e7da65718a973874607dac91f3cc8299ff88ff656b5ce270889d38be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dbac43d51c70bfc0fa2265895ccd110a74e78e7900c1eb32e878a7a319a65de850e7111a1b4127720cc96ec53d7b75000000000000000000000000000000001219ecd60c5c62fde6f58d4174224e073e08c6b859032437f528867823cd73aef065938684cfc423d0a7c6c707b379d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016098b07be0a5e22e2d010f3b69745578f272ca4fc1a631843194f0a6d80228961f1197aff6eef549e430b77e36b93a100000000000000000000000000000000134bd264a3ea6c8a6f46771eca7d68a7cb8587dc988c0d9acfa15c766a1aad683fdcc07c32dd8160109eefc3dac1095c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad200a52be3dd4c621070312d35255b95ffa56153476998e0c603c12cbbb7df2fa2e3328dad1dfa8882b36f85bb9b0e000000000000000000000000000000001428eff2221b92061eb59bed1ddc8a3c292155ab515d0a12ff9e3095e009df65a9057cb2915f01bdb10c5fcbdbe3832a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75476d362d3479410a431efc172aa09e6860fa1b7d74230aa8e104cd49de3ead3d4c6184619babe09cf5abf6d7d12f000000000000000000000000000000000bc07aa8979744705e2526b8962b0453d867dc03c9c0b788f1ee0643c0f12f551aad1ce3bcba1ecf8db7dac3df30d8a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001923f2229257a834002ce2f5cd1003be34c05775bc93be2fc953017fd361e1eb5534d4b373ddff2f105b3bef760856d900000000000000000000000000000000157c20830e7acc2484d2005fb9a055f603d6a2d930bfbf534094ecd336e39f7b763630a109f574d2dc13b338d4c0d62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ad6f12838e1c8d9cfada32515c3d2b9a202988a2288385f9a218e64bb6bf53d7ac4ef5a0864dc54797aad0ad7272310000000000000000000000000000000016017f2cc8b4a4bb6b9fb24cf643e67411fa008cab0138681da6b89546492841e15724a761bf074fd99fa9cb725b5cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcef5c0049a794b5a7918363636d393f87c3b34e225bb37aa1333348b4ddfe678254b1caaffbcdd25df1648363a261700000000000000000000000000000000175b56d2f43bda56dee6393ede61a075ec600c9d529f35dcbd228387bcc7cbd882c9012eccf2f6df46ee3cfc3eeeaf0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d49783696c7c6cd324a3f27ca5d38de3d014cf5e205ccd7a53a8257523f3a50dfdd973738b3a570a5adf6f5b3b41470000000000000000000000000000000000985eb4158fdcf22d7198d8016fd5d142f47a0681adc5e953df8478359a151328bb9618c12cec6f54696c1de892e7211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050fb60a3c82453f68fc186ce3e1ed02f6ac8212861806b8fe29652c1875662d32e5fb073004c9f402154917552b6ef000000000000000000000000000000000e9dfc089d1505e13d0c41a915d720ac1b1175e78e0cfd3b420fe2bdae5aa580eeb164c7fe8837245433638c9c650c5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706c3ce43fe463bf0250de2577108ecd8d068964e57dffa75714d54a6dd27b0f82ff46dd272d72f55207168972ff9010000000000000000000000000000000000fade45a4a41bcd1ca186017304e0db2e45c664b98175636e631167cd8632354ed715d07961d7c713ef80e50bd43d941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb6b3286c17986cc5c5f9efe88e58d3443d00c40a2b0ba9641ba54a6b0c7dcd64d955e494c5d92cb85976b896519830000000000000000000000000000000006afe9d4877065e46efe7b8c2780e0dd579eb59f51b330f8aa1fdc777660648f99d93c3eb500372c6267cace3ba3e5181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000057dcc480aaf282864be9274bf3ca7699d62995a592d8c644ff1f89b5a1b9097099e9de74c8f60d40753f7d41ce6a00000000000000000000000000000000002574a2583f1ee4049089f04986e9e1aad89a4f1e65db3dea058cf710bdf6d9c3abbb0bb40c85844b5faf4d865765ac21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df10fed4bb30c8f1612f7c9fdec4c93259d0fe2ac4a60a5eb839f1b8790238278840aac3cd2eb0673ec7590008ceb6200000000000000000000000000000000001cc197745bc860881dad6f36ef7c9f6328e942f3cc94efc323c9fc2bcee545b02b11092ff585345f0a8c966b57f7f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dff6ff2ffe2af6bd7a750d9b05cd79fe8c389f7e5e9fe9cf54f2ac374f40dc25011465e65081d27f577942d5e01275c000000000000000000000000000000000b5b417d7dfce5e19156b4b57f72fd95588e7a743850d92f0293de68a519af6adca00ee7b24192da81744f85b8eea83b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002107b07d573481e0e326ffa415a63b32ff50878775b83dc6263ef3830fe0f62e82f01965a5638c25b4dccb9b6c48cda000000000000000000000000000000001341554c70003b58a6cd0f8c1a5dd8ccd6c990487eccc7bb3bf5b4d4ee685e31ccb8d86010946f822c03ea1ecd2775f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a2d029f6427723df063531e523c0b3d53fcbb876962d4821a684c65b911905955fbc53ca193b829b785f689997c02a0000000000000000000000000000000011abcb59a45c6c79a53934adc0a1b2e2f03cbeb3952f24d3bd92f6b5abbe042964b17ddea720db3a610dad890f2d3c401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f17c0793c803b709111a90700bfaa3a2d618229ce8225be0c7a85808d92eed6f1ec1d9b44757c9cdd401cdf1c8ba50000000000000000000000000000000005a934358f8a7362c05a881a3bcc1da5fde19d6e43994f2e607b9308fa790153e41e454ecfda74caa8a689a2633c489b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fcb0c935df793c1f25b489bebb38a1216c83a082cd234a8bc7ea728281230d886b770c8dc8cb6e66696675ea1548280000000000000000000000000000000007cea65bd10ac159d24bd2fd0532f7802bda997f4c31befdd2e799efc09cd23bd7cbd81359be49e4e2b29f269e53e7c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008251020287af5ebf948310b2d0c718f92a6bddaec3a456760a35bb8bf23651140a2bfb8960d10de187093588759011800000000000000000000000000000000166120e0a17c851841b6c6d7512c815f5e0b0f3e740c0c3c0f7cf0e7581bf02f28bf697c330ba0240d4e061ed7593ae41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c4d82516ff1762e0a44795b4687c8b8fbca63200b53340af38d0d41c0169e46925cb7c8a255255d175f82e42393b830000000000000000000000000000000019e7d8b7560c51d0311d795dca5b97471dec0b36f1efe52e90bb54f3dbd7b44b7edcb206596bd80ba68023fc94b5196c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014195c5169d2bc6d9d31a143317c55856535c1ccb4f3f401f656eee5e2e07224c04a82212b0b295f31960593950f967e000000000000000000000000000000000cc32f83d76d9faa17cc06550b7b2b5989d063b72c6d6a8658df7b03ff4177537a7412c82f8be81ed56a16d6529c48bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117dbe8d8513333f699863ebb7a604717eb4d3191fe34b3fb6bb42d3f5fdad6c0208df2014fa5237c6afe4b30ecc15710000000000000000000000000000000017bcdda756df685282981153f822e14472fa187bf105317c46f5c49c87cbfc94a2cbcd006b93e71c26d94d6368b8a3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017138bffd5834ae1bc660c089dbcd8eeb913aa3aade8da8b7489b2eb87c5527ff392a4c429b6ffa0566bf825b2421e9a0000000000000000000000000000000016f7ddd23e3459eaee15b294f06ccbedb428c9c6934fd185b0d33325b91067c58eda147e3395ef3303898b9947c334f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ac27cc2d8552dc2a4cbc0cae91a3e5d178b6ac2ad498e74d1a284c9651130cf477fc58e000c6f88d5c191838d7b183000000000000000000000000000000000bb54d5035ecbb95a3ac7557c49c5f45bfb738ad39abb84f733fa9289efa9a7433d5e61a41a995a8ece7b3755ee179d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032f710645727bb1c49117baa7c7903962013737c40e3fea6300711ff3b77bff5af6810edd261547c44c12239e153a8c0000000000000000000000000000000008c8cdb9771e98e244cd75dfca38f23a0dfd504087f744137279ad252c1d52c34a0dcb7022c09d63711a05d00d4e41d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b7303e54b1ca9ec39fb3bbdf881c1427e66ebd6ed58bb6f591bbad6c0a0ae0a6d837c402e398273aa2d398a2329e3d00000000000000000000000000000000007dcaa47a5586a9b8fa0f373a96212c547b32b9ef376f36260fe8f85f6fd7a5ccc1b90a6fd5caada61f5bc361eb38dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fdafb7768d900d2d900c4328a270dc2fcb6fcdf951aa1918e8e73f5c881673bce8e9691277bb35ddc72c04c9454a4c00000000000000000000000000000000089aae702b51201215ceac74a1ba557eb15c761ba5997d554539e98fd79d212a0231aa466f04b5595646ebe18d35acd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1ee6e4470ac294093804b610ff0c233b4587d80682ad00d041c2db61a76c3ca6563340121c1ddbb1f5f4d659045166000000000000000000000000000000000cb22831ab3a26a990991c18738b79e19acc423485fbf3caa0c0e08c2544c0da44afdb3ac4017252326cfcca725ce9c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d32a976a3308f49a0f8330be655033f3462ec55b7155c04085bfa77faa38fce70a76d557d892e5976123b8d4166d95000000000000000000000000000000000e32a70de4ca8e4ab9eae6b5e1daebbf8c5281ae16f732c34c1d8e4306fa790de9ed847165576c2d7e1771f417da33131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000251a8c1bdbfd43dbd739cc49df3d3f2dcd9eee2e481a6e4d9f988709ea1d507eaf0fd40c69b01c8d9fbb65f5789a5f4000000000000000000000000000000000dc0ca937eb55529ad999adf5c208590d1bd6551a3509f7faab2efe3be3feda9b2348044193bbc0a33e41eb14869dfd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dec810a2ca7f2d46775d7c9dc7a9b9338619e6d1618bb6df5166f968770f2e4577b4632e01d9914e3470674367b70a00000000000000000000000000000000190cda6167278048b731b919d8973e12287fb104e8e1b7da26b83a9048bc7b78f0e26e5faf6e4d2ac97ba1f75ebe87161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c66a40ab2edccc6c79b358322a79792476409d798fefe32511a2265ace229c718afeb3fdc8a800995601a0a1499ba1d000000000000000000000000000000000577f65da4a815da54b5901c917485a7287a75e53e5d802f6addc4ef05643a979698bee00363f68265e03fe285f96d7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172fec9f191804e66d23cbabf1363df207f1a2c83fb34486fa0cf4a7020b28c7fe3f14e272b02822a83647f6812681b600000000000000000000000000000000092bb316167a3dfab5ac6806a76a3493427a87909eb19ccc06d15ddc407a5bf1cefa13276b7a096cefc240ea23c43d671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddfcf274889f9098cf717c130edd950d8be9f1a1658d1c69fa841dd7879a70cebeb4cfaea1c31bebd8fe250b1ba7e6e000000000000000000000000000000000f4e4ab4f559c5e142ad550a6d033b6a24cbe8c2f72aeab56b82f52531f1b8b901bd496f49c83f31eb44542ebfc8f2c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f284ef8c378290c7a07e4ba4c49079c5ec31096fcd8835aa8086d87bfc2bf460964b12cc87f9e1cf5a45a4ffda450c0000000000000000000000000000000011eeee3fa1edab6eed94181fce1473141a699c5c14800fe58713f44fcb42306ef94704df5c7ec1c42a294d7037a6f2161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018df084c8000add26252a8f2a5d128587888b50f31e01e017f748b420767e0121f6c1facdb03ebcf49e0631c85828da000000000000000000000000000000000fbee5702afd32030ddd485cca9918945bb9d7f6b8eddb8b49c87a698ad777a385b5a357e3d08fd9632f859167bae7cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff3a9ddba8ea46bf9c4bf84b1a89f84bc892e4d327de415373862660052ac8961c37296a9e511e04e63d1522b51e7a000000000000000000000000000000000f706aa2e0c47d94c86985036c1e554f565b9052133c32734a154c29df6c675a1231aa1a129c6aff8b884e62b40118301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035578fcd95c71d64158abe7c208adbb5a1c3a9b5a76dab8113609fae680d2817cb60a547eab8647d163094efe4e3f63000000000000000000000000000000000d34d9fbb399e057d8f435068204b3058f1981121a5ecc63dfba9b969300496e45c19d167c2a480816f2ac59c79416211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0811e41e5ce8cf7589f2abe9a65629a5935a9c778f5f3e8be6fa272a908f7324b1947a6e61d857e487d143be6fe8000000000000000000000000000000000074b16803126d7fd8bdc867c72d069a75139bd17be8a2e26292202220b1d3f2039e069cd4563656f35534648d6b1dff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abac46d9caf0e70f1c5ea33ba8acfe37a18a6df210219053a128f0a4ad89c246d4cabcc2ab452b3db97c0e24245f7bc0000000000000000000000000000000004da7a6230cbc0d75ad7d6d745846cedcaae5bbb7df5ef0138010e7890ac960876c5416c5dcc2d8b892a4d397ae3a4491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106332e62070830a02876ef10d23016239edadc9dfe2ec041a7a85fe691c97991a8af8e3738b71c985a43ae40e51a4ae00000000000000000000000000000000116abb64db2f03b687249c66f444c4cc3b068bda06456a773a461a1131b3ec970e53d640f00953decad9500a2aaff21d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cb777e1c9f77c6232f7a3ce1fa2f99cabb467241511f1ac40327ecf7bb8dfa0b201183f78932711dcf4a4f47a0968b0000000000000000000000000000000004199bb1b9681e4ca55746f9bec3dcd83cc07edb4736b025abd2d9aaf625a8e9f692768aa2f26e0b0c6dd5981b5816cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b00e370996680bc8f2113a09dcf94acd89dd74905dff81ccec15d3f8c68e0cd6489689fb070810fbe3e79da633721fe000000000000000000000000000000000d7381d520d5584f1d224497ae615484c2c887d1cb4d0554a02bdc72a0ef5c9a32ad0e27b25bb8c5f8f2afb6eb3a72b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107c1004ba60ca9603fc6a582f290247107c86812b9322247a055d4569a8648748e258e8d28cd41fd43c23e0024f2a90000000000000000000000000000000000b144d001a5da1bf1153513039a8cabe4697367edba05d74d17ddaeb29703b8e95f31352d711ed4bc2e75bb191211a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f12da7234025c5fee95f6f6a50a63b2588993085f6ff097e59f8125afc2445335a04035b3a3a2b0f7233f3a2817e060000000000000000000000000000000002e19867c2bb015b56a86fd085729e55c69f2434684707073bb163f6c2f0675afb676653ca9a1a73ea2f79a645158f9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2cf49a05083c4d4ff93addf75f34ae7b09e98ad3d1624566fc40792ae6a75390eea45ca2061a2bfcc82b4dd9e93e9a000000000000000000000000000000000782cd194eb089160a6ec3819554efec099a6b47e3dd865d5dd3743f4bea19962f17aec1ef1a5e025abf770161ff8a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b884ee2fa05a0625cbc2b241f9822977c0bac869a86e1c4ea553df124a755e920f633fc8bb9a14882cf81c16f9903c00000000000000000000000000000000033597121b1e5176dc3d91665fe2115385821575530852acf29b2f45e3a466fcd0cb28ab49863c8ffe8e4218d51c0d991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbc36c1b71baeaebf662514ada557a7c07127e46a9b6bce2770c6b762c190248731902e65b7330dd04012b84375d440000000000000000000000000000000007d047eb9290ac0a2987287bdd3a5ebb180aff6e6da25f022dd94b8c9317c2bc081bb199f64123e8e698732819ce2ee71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001046a2b39c7341f9f36ca3b5da7186e184aba0936de635613e7eec9086806bb27cf8ea99e00f324dcecf03d1ceee7fef00000000000000000000000000000000131ac04f57d925a4d1174c166a387db81d1674862552f2783e6f0e38aab2a43b2d5ec158c6374a36195ab5abf3800b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae01f62e61dbcd7e10c05327a54432be8aa14837608334f047516aedd8a3cf39c5a7ebab43e2f1354d09124558c55ba000000000000000000000000000000001059ceaa6ac2feaa425ba1df4c23845334419840cd31fd57d6e3fdac7a20390e9f575296ee1ddf563a647f685c75231b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a06a9f012e5be6900eaf1253eaf5331927dd4e032b563df7e135545768b422b1d16de295edf256b1e613b29389b4160000000000000000000000000000000017bc1cc1d2b2759e78b850e3dd83b257a98fb7c39e79c95b4fe5ffd496e80253c0a0f137be1fb71d33c7b73930e58b251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b102f8311187c0b84e622a0ed9c497fafdd6dfb39f8e40077cb68a268230c1b82be2c4b558ee04369d53ddcd9b5f0cd000000000000000000000000000000001725cc4af7985779bcd7af3936874530f4e2e99d753cd7c40dbc6df10f61c8b267b7d9161f235905e844e03cdbc5fb391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d27bad5d6734724bec530f5ebdb15c334599ebcfde49ca635bb373b991cdecb45fc2e3757162529b6266a77e906ee900000000000000000000000000000000003adde06f1f82a98f890b41f0bc9a3f56f45dc6a28ba67882021ef69f92a59968dc01e329df5bf3aa33fd4580afd7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001480fe9796b03f65c2dfc8d7667c88f888d4559b84b9dea6f830af8715baf80951a1201bd9f6ccd3d8578344fd93c95c00000000000000000000000000000000004596ac83e4d53f8f9322afad8976d0378f41a54a9efd08ff81c10dceff0f0a8306d28692abce430d0783868dc4236c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000592a66e57b12f6dc54583d40654ed5e13610f729c4da9c9e56f81e76459fc83e6edfc97b6ed396d2b56973d1180283e000000000000000000000000000000000545eefd6097db75c33c16ca92df93f6701033f6a43f79970fceb1021c1b2c42d5b1ea4fbc1d21840b7112d0ddb6e9051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d8b5783309e8bfa5e183128ef55906980e7797dac9f49772e3da92b7fdfdbbe377106adfff48bd8bf4f6c3ad39fa2000000000000000000000000000000000888bd6f1fb9cf82dd6b4c0b993aac19e3802b84f4990d3aab81d3adfb10327671ecd00aac394ea353c14a9c2685efbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f5d460d6e4cb387e2aef66046d0551e0d7b79e37fcfbc5847409e48aa49c578665e2f9951114a061f3f8043c9cd632000000000000000000000000000000000d7fe2a8d29c82d7c0eb5f2ec5f0cf22ed0a0e16b2e08b76d9635af481e3fe2eaf1196e64d577b981267ada0b2b78a9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122e53cb3b6f15b4609facd738166dfe707e925d1cc78a757da2ff1f7eb460646c109d9a6c19c07ecc76506ad8d5c0e3000000000000000000000000000000000f8822f15ea9890e0366e9497e5435a4b12d76db5bc1c2fbb057154d95ad238f2366ac179e7374730c6bee69e282b1091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199486c252e88ae64edd7996285ec0ae96b0f8c47adb17b911907dd47f889c54222b1e2cbc0bf813ad04e1cab2b72d71000000000000000000000000000000000c448c1102513d70f485011b83571bbdedf797cc8ddc7435f6078505851332761736dbf1aaeb85dd37cc1ac88375e5691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d099bbf190e608841e934025a6ad2813663029078d1a4cd55a138b4770d2eec66649bf1a8b2fc52de1d7e600b98fdaf00000000000000000000000000000000060d8359a72f8027c41fd95517f599e211718dd2b6cb7ee799c9d519b9af87aa39d0abdd7de87328870b633ac44075c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028de2d74c1e4115ca8e311ea8a3183da2b1da74e3d9d39024053d4747eece68a867b2fac606e6b9fb6a1a1b7bdfada80000000000000000000000000000000014a52d0a2bbc0da103bfbb41e33b42f2a2e25c3d2b6d8a461c879670d05328fc46bf76faea4d61fd2c39161675285a8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019feadb8aae9605128ef8a7e5e7464904692935b4aa0f071c83e5d764598bf22cab0d447bec2b75ebcd352f25dd29435000000000000000000000000000000000e29f99d5cd00b229437da308625e789ab51bbd7aa1ce07b3bf0fed81eadfc27644b4288cf3ecc4b7616706c9d19ce861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d47568f2e41d4f12e494ff1834b373d8e6e5751dea9a0f92326c90159a2a4a1a366bb7c246dc5e7c8268ff76f20f02a0000000000000000000000000000000002311c179d953bac57c7e78b1d47eb826bde900dba9e926a889111899a0a474db9e79b5308671ff55219249139a07c911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f558daa5331f7f71f8a5c202739d2667c94c7d4f8c4526cfabeca521ba817b59313b74252f025171e4215370571c9bc0000000000000000000000000000000005eb55a322d602619742e2c7a0789e59b932d2c06b463749bbd74b9585a2620fdf9dd9ab4a45fa13104531777fa07e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c82b961e57d515ea0892781a80e90c379edf06a0e4c9f48caeffb1c27ed4da3f6a4aab4d606d4a4b030a2bd3b7ed60000000000000000000000000000000000d0d8d96ace834b3b78f655391cf0dc64b400da5a6dd3881f971dbf7839712d9cb2eea058ff7adb334adcdc7e370764f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000111da88adc2dc96023c63648302a2c6892cee147a19cda06f409fb59569e2df1b436b9c897eff4b97356035cba0ec0300000000000000000000000000000000015d4e9126a3b202fd1f6707ee5e106c08f595c1b80451d2707b9505ced85621fd0c714f08b2cc13747d913c3e668a2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129de780407a19165bf441c33ffb126eafe5cf19f374c0431bfecd5ce038220b24e396d86230a927e3dade4914e509fb00000000000000000000000000000000179545433a62b0a912d61595cfbd9f300e8eb51d01139afbd5b1c28bb01d326ab7dd21ea766628b606466a6550b235c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000664a3a100f40b55def8adc08dbb4e8a3531b6069b6d0713a6618e39b42ad66df85a343cfc5123474979e66158ef667e000000000000000000000000000000000db8e7e5a3d862009901b66445ee9ef8f6041a6767b313ca577eb5fab44612a2275eb0c3e7df29d58c28b051ff7ef2691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49fd513593e6c0ee647d266b70b6f6b8948d3df30a4ead1682de173717e2bb66b0e6f1f3b04512ee3a312a94d9d801000000000000000000000000000000000dc35533dd3beba6af9c55b7bbdbf87f13fc848ae1db5f295c1fce35abbce45a0201c8f6b20f0b8f2372daf7e13985191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cae7d9c1dacd5873a94bd1a7ce4f7b317a4f0e4a00510e5b315a5284388df54ccaf66ab6343783c0537589388f12ef200000000000000000000000000000000129abad4ea7852061262bfaab3053fbb8eae6e2576cd0f20af335234acae3e3a2f6cfde127fd97286d338c88c0c48e531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000336adecfec05020cfef6717347a5f3877ddd4ded33549832a0ba2e561e155ee327c72919bbe42409cb4ce8df2860103000000000000000000000000000000000de555f8cd7244fc3276f91d9d8d093584c1f6ac75539f274666103311a6f244e51af045a85e708c12770a77946c31471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9807a293a298622afb0f97bccb054e6a14ca6e32153012a575edec52206f175ab35c3c267923b37a1ad286e947e85c0000000000000000000000000000000015a0284f984fddb790679a726fdfddcb703ae389b81956c2b7a9fd0bb8c4d1e7998aa80d23a616babe488616228c77bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082e8f8012e85a3f82afb9c796118fd554f818baf24426dd03d6f5169f068d8ad4a4e430401f333e7285e4ff29126e5e000000000000000000000000000000001927c2b87575c2896445c728e4c5201ec3e47fa8a5998d42b2676768407fa77dc101ba70e14633f9d819f670ae88370d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fed6c8682f5d8d469f2abb43fa89c061653921426777e0404a32f7730a14c6b1eb88d8edf45379fa90494405a1466ea00000000000000000000000000000000162642d55184cee24f6eee0bd25b0299e1c927bbabf5424d99194240ef7a626b28f4e54db88feef14a39821923fea7a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048fa1bc38671cc4b125c57d9db3d33c8c25925ffab2c5a9e9b86c526dcf4bf291554a0fe1996efd2ed087f8210747b10000000000000000000000000000000003847d6061e10036265421953407b10964213f5d5a641d43caf428a2958d29bdb3f338b4ea10a084dfbb4322a465305b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c16ff9d85b074ccc3b1a89fdd08cdf14871bcbb79e0fe2be07911e9d840798612a0e20553214a486b85ca4e5fd9b5c000000000000000000000000000000000ff6768f72be779f8efb59f0143377c370fe0aef64ecbc27b3349b653afa88766dd19371457a02d1157d5fdb2bd5abca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b2dbb0d7692378d09d69a4c550c66b2469c6f0bd31d718392a5dbb3ea59b27329cbb10519d19e9446e233ea3e0e9a000000000000000000000000000000000d9f7c72854439fc4f6f7cad7792988200bd38cef7af378053b0da3404278223cb65c2524f4b607772dcc53775c0e06d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dbb56d62c30dd9f922d7d187bdf37b5e1617caa4d57398248ebfca7bca05dd9535ec96ebbf85c270832d90a940143f0000000000000000000000000000000014360021fee7ca6deb29a469c740285323661a205df206a50adf93e7ae9e15eda6d0d009c3b304a10e5b18215e2b76371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdd1e5b1476661c2571e14b8a2e3554bdddc69a5658f288e10d06f7f03a4dfde60a81da963b3d0097993d519f21731000000000000000000000000000000001106b929bd96bae00eff5cfc8560010ad02abcb0132e1abadb46dbc4143a492ab73e387ba63dec5af50a0ed8dcb3c7011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132425bd7886d3e028ee3cf137c28416888cebd8f738a30cf665d3b2d2e0d41bd979017f061bb7fa74a0b6081267bb0e0000000000000000000000000000000000cbb80711a010c484c164e4ec7054c79cf968004012e4a02dc2b38edf66ff8fa94f73323f3e347508082018d00a6e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b293d1abed211a04772d5264d2b1c0e66fdb45fa4de64245736714a3671fb25e5dfd6215127ba5b2b452bb4144d74f0000000000000000000000000000000013e33258dfb5493b3590da48471b38ff7bb5f9a5973def9d7a7584c7b9610c1c23df1591ab4fe94984f21ba9089c46ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043fcb2ed212142227e7c8a7758f52ec40dc9f81203b10e40e55498703725f88bd314d7ca005606fb9a9a32de43edbc50000000000000000000000000000000004514fd3473a382e9b17b7fbc42c5b16804303e73f82c65f89879ebd8852aab9f453e9816fc797309fca8fe05988f2401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f39f47e7c9c2daed27c9288be45ff7497dce932f0aae9dd1366078692a75d3ef375d7ec571ae0fe1d87d035723e7a70000000000000000000000000000000000256e69eab6fb139d1b11dd0b08c6d75030f79194ece0a4e29c2708dec3bb377a482633c264d91ab21b07141774b30e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a844b1a5edd3f0e29e6f65e247803075f114f0e119a5aab240b006aabb30f6c18f8bd1b5ea2b308e63d392f37912f200000000000000000000000000000000155c5f7d8339238bafbd02a37d718bb75af164701e2b480ed74aaf93157eae8e63aa58cd47d63bf3edf7c0823d9c6af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f36636831274066ff32dc0e98ac9b4367351da7ae88fd7789212ea9cc675625f075f767cc5e70300bc757dde79d1581000000000000000000000000000000001915afa483bc0e7437305611efd47baa29f9ad6ce8a177af2c516044448ace10f5db1926f3f9272c32049a03acd5b3511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001262108681725ba3312474398ca7af16e9c381371755d5c64760d987ce7b844ef7c1a808074b9891dbd92ad5fe9234130000000000000000000000000000000012be468db76f5e3fb609a222a6298b8d825d8f2f642cfae4ffe20fc5be8d712a3735d5b9e0518a4964dae2c545d92f7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e4619e5b94b3c0790784d502ac4e3d094ff44b260f66dc71d7a40e58f54fb08c2ad817a3a0c07a6391b18515f740b0000000000000000000000000000000014ebcc4a6daccf4b8303d8563bc5c4eab1812d3449a27d513d36804c24e6de02abe4d291391d84fca271980c506570571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a2a0248f14093763ced150093fa47f3fd8b30d72ef156a6253017c03a089e99282a5ee332d0a75ac5dd58838eab6ab000000000000000000000000000000000b7527990d34345433ec6742263a8a173ff12f453e010b7e8b18880c4c1a50074d9981ac3ae525d0e1d6f0a6993cd57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021d79fe29b950a5ed3115cf1d0ac09bbd98ff54da53ad230d4d18bbeb6a3b1141cf8e809ae7758a14be791e93aaee530000000000000000000000000000000009720864c6c10aa1ff281f969c485168a32b34289787410e486c883fc1d9636a2cad087b30d8c06cb87af117d86a76a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006201b99a234aa8ae87cbeb24255996099a0f7130e8fb6821d6741a9eab1009f39e3c22f45cd4dee9f59f5e06b6afb230000000000000000000000000000000014be94cd8549172b1bafbed136569a9584d0783f0919f8b666dba37f5485999210a9879ea5aafb6e825d81616e2e005e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d8c346962286318d25f34136f8760db46c0cddb94b0b556a835ad5a847dff30692ba53cab49a9344959056cbbc89670000000000000000000000000000000012e656921d9a268b02b5a08ec1dc2b96a51ede435eebf63fd176f88339254512a06da55497448ceb321eb7565789f2961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a2e91a24275d7ad56c54b3a4570f1882c91431c374df88852581540a2f2de8d5d866935848e84b3b0fdc318228b40e000000000000000000000000000000000efda833e49d32c9568a4c07f69ac18e72070c82a2fd404f09f28427ebf9ce88ed0648f519e893a6760d7fb2d6fea46e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f6abc385b15828fdcfa2f914fba28845792d76027f1a857fff57ccf4f7f6f1344681731bcf89d44ed3d554b7bf86d0000000000000000000000000000000006ce6abaea1eb2322abf1151783726f2db845051455cee92222ce3c297f49e1611cc5b8b69b6702963f1364a0e0db2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134d0455a5d0b830a4cd8c1f5cd6a4565fa975b68aa3e8586d4c13709af49b0702d24547d226e12e0a2164bb3ca23e920000000000000000000000000000000002eea83a11b629b04c2b859f14e8d64e90c81d1a65c10a632de2431a7ce4badc74756afb7feb28366cf34a0cebe9d1311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3fdde0e2ec331e63c9de21b9daf29f6664c71197f3a19313ba0b24baaca69759bdaf41945986bc125b92f4b1de9f56000000000000000000000000000000000702926c2ad3cd2b5e6963d391b2ba7aaf73d8807d6acd5d13e7b699ad0b4d17e191ab2538dacd890247164d8551c2671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000784fc8227e05aa5af690a0907cbc61e821b973b5f38ec87722645a68c4a9bfee2a023231dbeb5ed654a6b9895a962a30000000000000000000000000000000012089505a283413757dc86d57aca300ae55404893c40e8dfd7650805c8d36000ea1d2aaa52ca3be104919a64667524c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc6d9dc8a9d12dfdeff75f84d6cdf46cc3eefbebe5693a343bf8f065dd7a1b0f07a055dd204ccbc50e7de57a255043e0000000000000000000000000000000002b30ee9154520136af5e00b41cea3d197fb16638c8b0e27db04ef26b2beb1f0524c030aa12207f04dade06140eb646a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071068aeb2da0abd740945ac95eb1315fc3ee36546daa98ff19df32cb2268de75811795c4c857b51d15b5af77fa21936000000000000000000000000000000001383def2963220133f9e53ffb011110b277d929991475447427811a96277bc7a0f8d73692d038de255c29ef0a26b54411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa8d41f8d2e406223512da2eb25a3a84ee60a5f6e7fa7c08db9825042c87e1660b7609acb2420ab2cf6b47400a6e97300000000000000000000000000000000084f590c23d03506246f586be8b92ef1a8e6bea8c5cdb68e6496cef9954c3aadb304629bd3c94842968e99ae62b029731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140ab4595f7f621bb57375a14261836f1ae53026b5adc1229cbe2fd0f18707139867d38ea3510d895917e6e46b41ba9000000000000000000000000000000000b3ee0ef74b0b2058ac914be5747c57c56b576dae3f7a6ee375e2f9b637d282a258c43b6b2a808ae63b8ccbc2f0c0af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003edd1471e326b302f326907410ed05d15eda89649a2cbed0c8a8e39dd43d310d6a6d942b7a2ee3a3cd785b52f7a911e00000000000000000000000000000000038797a0b7fee56c950d0068860c111e6a1e1986d78b4425948d94820765620d2a925f8d4af88f863ddc1886ff716c3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d11e26b94fd0226dc45bef20ca2b121b53f1e01373d3d11c330db54edbfcbc51131c86396c232f388a8fd16e7d175880000000000000000000000000000000007a4db4cee29cf75d92597592d2a02baf5328979a273545638b4d06f96c0d1705f61ea3bdb6c3a3ca547ec7db2ad86071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e2185ef1543229ef5ee3d21b204e716f6010370dcb0585e7b1a8dc4629bc06b145406d1513de19270659b373e6ab34000000000000000000000000000000000bca21e7992b37521e9123f2c52e8769b99a47111f72bec767e87f10661957f71ea30ebb985bccdb17d353889ec8c6891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010040a77f16295aa94e7b376dfee5f3a4d535b9c8672d145f884eb91a40240f23711f0f7cba72f71ee0f2770b9eeecdf00000000000000000000000000000000083bb9bb523c71c9f6721d4fe52fc4b6275934248ebfae16bf4b0c7be0de755d2bffd6a37598ca6ff6266f22f4774abf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea29ab29c9191c2c7ca467c955b4a115936d2da83c659e7e53f9fce891e7df1b9e61c75172809285c75d40e22f479010000000000000000000000000000000016afc4c395ec6b108837af8a532f39193030ce1e13dffa12f4cdf0fea039d1b659b75e929689bd65f9f7b5f7b5b4fc161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004aa6ece79e12ac8f3285112bf86ff83273294626b73f1613a8759a83cc72dda5d86384a363e6e2f93b7db6130cc8c450000000000000000000000000000000006640019ee46b667aeadd7983370bd3548363af90e2d147969e7cec178f591f7e3eb8a9f9c2acda150090368c26add711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1417080ba8a76d823e53e3f61e071fb674675bab023dfb671607a080a4f9aeb0304000bd40bca43548029dbfbb7128000000000000000000000000000000000ee7d58874226097c28f45a33f6404ebc4671ce782a10d833b8f94a352476677a998ac49d4d4d2a815a807848962f1b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128686dc4b42ea97f0d5302d6323002f7b7e0265610fb4a3a79864bf8ea8ef5c4aa357122fa1079043f8ad827b7a084f000000000000000000000000000000000f461b1ee6f52ebd5a451cf7b1595b79bddf592d25d34e46fd8f2ad7eca4bf30120c3692d325326cc3ad039af645f3961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f96d0eaf9e0317e14bb70e31c94f0d1f2d3bbfecfb30ea93f34a7e5071506848e07ec4c3af118f61267738acc6fce150000000000000000000000000000000019f5cca6d3b55e45e44d496cc403f771813658f368897588fda43f37a809b2aaf95c7d79f2e974586ff47ea7e2a9003d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a504b68bf21c0ac56bdce3783c79d1ea7dd2c6ce7164446dc1dd3564b2a1a9a99ad47bec04cc83f545564d2f0e3538d000000000000000000000000000000001437eacfb3ee21dc4514212d9b9b7fb6cf24b641718e9ebd58ffde0ca9e7fa7f899ac802f10ada25b6210a8452cb09691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c3d3ac8b00656caae1bf4280b3bbfa252afca51131d646e4aba719201da4661bdf888b7697a020309b7840f88a31d00000000000000000000000000000000026e116bd461efe94dc5452f79c3f22e55cf70a1cf0be9cff72d07737fe3c4b3267394bca3b3cb70d978bec302bf39721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807c713d4a50ee84cd091a02b84cd70b305e73184dc563f3db1d9b05de2f28b4ba0df1a97916dc986984fdceb173ba0000000000000000000000000000000000f65b71408435e838418f3af58b8d083d9992307ef94cbac612d16ee1d27796424c7f68e97ea7c98e3f93779ff4e87571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a9c5a37ecdf4846c449792ae970b62b7328096b4bbb960a16df355089c8b84cd16abd9d8acb3fe9d8c19ccf01a2253000000000000000000000000000000000ce16d316333193824dc70268e75db57adf9aec968f45397a51fcfae4cf6fd70c4cf785b78adaee730611718267b36361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e64bd95f001be6408638e93a21f4ad4dcb5d33a763c4bade8d56ac031de63fc373ad14ea3467c49889d285a40595900000000000000000000000000000000005f3aec71bc0cb4621c60ccae169431c7af732e8a5a59afe83d0f4cfd734da361ca2f66cb13ef1310f70c2b56221e9a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092a1b5d85957280d8fb1ab5a60aa3d84e73ba935d81451e979ebfef460d7c9f7f914abf05f3cfc500e21f3c270d9f9c000000000000000000000000000000000d60a01b7bb45463287e38b71840da4026fe211d86ebb4b8c46064e60bb2ea14559249b4ba32080dacb18c6316cfa22d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947a1cb2a25f313d93f4e0d6ada5e74b5103b5e166bebc0ba01ef685889ff4d4f76801f1663f27acd18e64bac3d56950000000000000000000000000000000011dc2f55c63d7ed56344cfccc286c4ebbe19061307935b05dafc2ef147f268a184fcf4fbb4e9785a7e381fef42d0282b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005d33f385a650ec8ea8bbcb4a3825aeec9fea1f1fff223f3b6eaa9f14fb03d0ad071b42b148095d05c77fdcd8b451260000000000000000000000000000000018bb939b20c3530a46be3c8f44376a5ad6b95c1f8ac2ab132c8263dd3d404e31afd48a1d88b646e3229f6e1f397de15e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015726d0020f9e63c3b41474a4d6c6d63f5d029b06ea161c75ae07a9895c26fd384f4a532f8b4a4849425a207326c2eb2000000000000000000000000000000000fa11e3367947c4159fd5fc5a223ae5de5472404050232e9f536a64718a95d0ae028cb9731f81c9059c1873a130dd3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a4f288141024e4007ceb89522a8cb9d4cba74f1b947fef8976d13a0ead1edb02c76a6e891293c5f05c0070f48c39f50000000000000000000000000000000014ae87e5597ca97cbc3a02e1e776ddd2c04263fd62ad374681687f2fb7f24f760eab408d56b990d2b7e45f7311a2602f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001828d39e38ca7da6fcd893eedc0806508083932c5f15eae3ba072b3aceb097dba204ce5b9d11c0b09bcaf497336885300000000000000000000000000000000003832d343959621e339959b164bdff6764f2c02875e9c716ede4c21a47623df6474ac951167fbdb6cf8687b8cc0026a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c1f59ce78b7319833a3c1f12697682a81e76f112e2678823241c953978abbfb38241979c1cab0ce50841e2679d3e90000000000000000000000000000000015fdad8707d644fa921198d4ede58e1a845ba04142069fc7f9d824d801ac09887a43573a70fd92184c154786788a3d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001510e382500eeba249fed5687c13a344f301fad613c715e2664bb9d8dda8f56dcc09b82502daed6c5b3efe6fbc0321ec0000000000000000000000000000000005c1774a417215d654ae9a73396b8a5f2eb0f85e317c0e08f63d9a1c584373b1cf7807f6a536c2c085277d0171bb52701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8a208f76058b3430d81ca13e742fe5714b46e10ee0672bc966f889e43dc199f4dcd958e9a46a7199cf1d7b423e60fa00000000000000000000000000000000071723a892470433832b0b41743a5df692e13b08de622db6564a690995a5618155db638fa079b7534f8cbd5032e61a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b444a33a3e0b81682cf09f78eb502faf52cfe4704d73e03413667e8a2c4b0e859348f01e99b8aa6a519f62ccdc23c15000000000000000000000000000000001262cfbebc08972b003a3fa79a1db786a777adc309c1a7dcb12a497d11cea5241e8a9fdf66049333fa0b1cc0407148491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d91f825aca6aa44baed28a6f4a6c081f4859ef9a51f6d9bf21afc78d3958650923b9245f78cd7ca7cfa5f5c7b145a9000000000000000000000000000000000f0cef2229837da6e933672ba382660e28d8f199b235f9d880386b646258ac6864ea3bafd3d8eb36e1ba376246927a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae3005befd604b001cc0889364493a011afd35943bff70c6b239547dd142bee8971227eec32b2deb2e8230f3e52f02000000000000000000000000000000000169929da3186f1092f9b170fa734edfb6275f6c42ab9e9d7c083e219d6a3543522ec8ce16d333e4a33e6304bd3f1b931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ade6a3630e120927a568c3c5e7af3a7f2167ffe9ac47ea5541c2449615837e4012af1f8ab32455a0cc2f7578b405350000000000000000000000000000000009a0ce5c7cb8051b095b6e66d6ccee9234d5a6b175b43d2479d18ade111abf054398db47f7014d64997f6e43eee5d4d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006774f98386d0f7bf14df73f958e6eebf4338c19f82d2d31e7930c9841570e992620f764de7fc905385fd14b9149b2cc0000000000000000000000000000000019ee9c785c1e93aec20c6bde989f3f38e998aa044b034d81b0de2d6a7facbd3cdbd0781a2415e463e856c634c4661ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050991fdf32388a015b4599986def2d2481be8bf4331700c9bf201e34bb74f2f862ff6760d048f21635517957d27101700000000000000000000000000000000185e035b9f9b736b0fd2cf539144d36ee7e6d42a96990f4f1f2a4f9e3f2fc84d0dcce47e8154e2048523c40fbff28c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001990ca1a9bb9d36539ebd8b63ce7151095c61b64a74e5c38cce158855907d1d15adc46bb478c6e169dc0ad595460b3ef000000000000000000000000000000001646ecf66583a86502c4905a5c2b57cf373272c26273d9d9118d469ea602b56a636ff96f7e3905a3918d5ec22ac9dbd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014789a9c564be2817dd5806b3fb47697d3936e773f2773b20cd4a65f096da1dc754c3242cad108d01f2ed4ae8df84afa0000000000000000000000000000000010f2ec772ca0ef7afffb31030d4529f711aa103576f369b129effe41f800f7148ae15d45783f9aa899db1e60285265751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111aec3f4f6bd8b8d28c9a331ef9d8f796f8a87d6603b333f8d6d7772a07513d5cd86dc3e2f9d5a48e9338068f5e5fbc0000000000000000000000000000000016f81f4c7ad03aa15e26ebeae68697ffacd5ddb967c48161f33381832128bbfb1151d9879d44cb37b63a5309bc93d8a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092120f271df91567f708efa79a955eab379adefa7ec29fb72e8f9fee34932bcb7fa3ffd9e0db0c733122f2f0c5c942a000000000000000000000000000000001619ed78f7fb4da227cf8d82d18d9a0726c350bd5d3d0fae6e74720e5c6764b51033bbc4c01049bdf4ee3fde659e37e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d29cb0f63cd86d5671fe582776db03b13ba37cfd659a36f320ee3f914ea592eaade5b939a77ef8e13fca309dd3b8ea0000000000000000000000000000000005f6df9875b49cae712a0e1b2b2f03fa5d4ec2d939cafe59110132fcb63ffb2cc784c5762e9f654b4172721a5a649ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d164b70bf9f7ef5dfcf18e7b072c7cd630472403c8a4226c884adecccdfc2e317c7273b95b763d09296374f9a1385a40000000000000000000000000000000009224caab937b4662b328469f75508e78801682964cbfd2e51f25ff457d5d34347106aba9cc9fde0ada323fb25a616a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d9912072511fa6f7822e81115daa21cf39ffac1caa5b4874171362a59d38df43453b758ab57a09e8878043315ebf36000000000000000000000000000000001487d30f8d55168b3eb47e245bf87b1f8bb3b9fac16a3717fa2932d6ca8f4f2d228ab76cfd36e8d39f659947b62f8d5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d985a9d46492436396cbbc9e5c7f14f99e4a95807b871c80e2585339abcb5103573e4876e6823854e125740583629400000000000000000000000000000000030c09af0a495f43c07f54a8dfe030232d872abae7166206c91fc807f3e5c0d2b3ea6159c75527040d0f5cf35838e2221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019070cb800c50384bc62ba5a4b170472c259f105cdecf95a295163cf8c0d62f9c052cd0f1969088d1c08f33413e82bf40000000000000000000000000000000005269a5f60561d08f018ac09afbb8cebd39a9b22bde4cf2135a10e774e95df33a1f4214cb54a067af8478917166171541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a23044d93c7b03a7766069cac6653fab8d1a117606c5ebb77456a3d08e774d1f21800fd4f23cd064964dd219dc94b00000000000000000000000000000000055583fa48d767606efd6c82f1c0ae1e6d56dbcb26c8caeb551a2c5f40ab8dcba9007e3bb2357a4cb9a523518b9c0c051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faa20074845a1bb02392b00034d2196303a5be345fcac09757d33ab6c66b352ea18067c793d616f0dbd0c82a9b58ae000000000000000000000000000000001153141d5ce7b746e047c3a84e1e9029176e94a0db2fabe1015dbacd4c1c8f2c97f57bf4d928000a6c7cf48b582c54f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8a8624c32dfbb770292ccfe5b18a672cdee8cb606b6ddc3e7cc9620926d512ea316cc5b613a82b4c60eab93bcaadb0000000000000000000000000000000006bbaf464d8bf9bcdee81d1aab424b0b3c08daffb4ead83de5119b628a8ce358824b5c72bd4de0d2ac5a897e418805d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6b6d3151f71be86febeb269eaa1feba37c3258000a667106de4b1ac84d91355ef37229251654f8ad83ba0f10321e55000000000000000000000000000000000b480e1ddd10a0758767afda0ae6bb0767c1d1a4833a5f4af323354906c62e66bc2330598e07bbd0dbf90af320c77ce21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd420a8a44016b806fb0db97b87e92b793ab48df243469e187230c19b262febfd8ea4801b39f2f1f1796cc6de21389f0000000000000000000000000000000005708499c87788c2b49ae9c08b5a4bbd782fea43ea68a6aa0926f5fb4c8a6120a7d00a4e861e0a4a0108736d04c46b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000397d9b1ea0c17ba8bfba39ba8b9a7c7d23518507a95d53ed70a1490164ca7e42378ca5e3bd2f846b164c06bfba8d51d00000000000000000000000000000000062651d43715ff392f89d65370585cb36d760ff35a17e07f637ee9a1ac654981a19b667bd3d8d7d8d504fdf00413f3271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5b2100522c7500740520357ade93be758008696ab6bfc82120aa1e56e352891e1c2a944a9fb91f182a2eb391b03d2000000000000000000000000000000000f3e921ca36af5d2b5f984a0c8edd38f4decba458641f3a907c323cfe243e12f6f853cc62aded980d1cc84f6bc4ee50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d192b60876957a35dae510fcbac59832e5476310195438f636aaee2d6314544fa99aa5a7e798d51d7f8764f915b4521000000000000000000000000000000000df53768b4aae77c7f23f74d595d10fa10be44939449cda1f1f74f4f0eb4371982d960207ed5aeceefe2f7e4dac4e5ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006db91cec22ebe5c50c7ee16a126c6897efb97ef04e3f45c0f1e13b69faa3245293baeb6b43ccfef5b52b45e8e8e40d1000000000000000000000000000000000fb6caaaeba72291edc9c89cc3e96a28cc24d78d4646d12d97afd7957c5775d13a846ed32a4f255e03fafc6846b024511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eec3f5c26327b54b03e7990b8d0f7745806a08ffd1a3192d43b458d7f4b00fbb81546f44fcd5fa02922f5ee158aada0000000000000000000000000000000011a13917c75cac2515193aadc239ec2cb4da1e6e11baed1410ad62e02ac63784616d96f48f17b54651076755454e77a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000279b8d4fb13bfcba38a5b6c92eaee084fc851dae3b0623ea1df13e01c18a3051072e977b61239817a8bebc17afbe266000000000000000000000000000000000e93ca08e7f8c8306a9e39d4ae0793e85fce82c40ce51266e7565988ec68129f0dc6bccb15cbe1932e8c81269d4457481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd944d3b3e96eecc15362150ba661cbff971e6cf1f828c95e6fba00416807605f0f3a367d35e174c6dbc80b1b8e43ad000000000000000000000000000000001069a552e0a77834d73da735b008b789fea422f3b2b19cea5c73127c6d14d172b928d9324074d8458d3f4028a5c8757f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0a9c4fa316d0a65b6d8ae371d8809a5eff2f4c47a58bbb1732e4fad64bd5e077bbea2badd59f1729a0b702f2d7c2970000000000000000000000000000000017e55870c8642711b162a7583d18983bf6f83b2b4479902650257e16b1ce951980aadf1b0c16165c092943481298d1281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014323197fd8f200b247ee900bbb4328f728286a11b9dd5edd9f8d2a3cdeb4a0b955cbdd836287d2d68ab69a25a565250000000000000000000000000000000002f88372fcee5f480a6ad826b5af5dd4a68a7b5660561e239893a8a361bae2195957094139788e3edb5738b73028a8da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003854dd74698295891ee1b5acb5b8978c82a7142f911d5d8abad84410a7207daa1d2c41bcdbdc66c56e5be5c90ea4c2b000000000000000000000000000000001440e15cbf14d10122307f8e29a94336060b4a441ffbbfd6cd482f7ca1dd4ef5fe57eafd2b49df8ea1fc19e9e7899d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d23e35c67a231551231b43d695d66bc01a78a044de8762e215aa7871daee6e50033430ec610e021983dd540d3a9dd00000000000000000000000000000000104eb4dbd6402e898d25111bc30b773c4382133a3c2afe5e56e2e873f1adff57450fbd719adbe10f12ec8446300703471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3cbbcb0ddb83a08379eae978fe444cb913020fd841b2b3ba432850aa6d3e29e46de6d07436ba552e8c7ab42d03e06e000000000000000000000000000000001745929db2ecdae61686a28f8d6589570c29bda7b5775c0a31a12a0e55805586d3cf06e76931d5622b00a551c2b265401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016003bc892e78edff115d0d88da2349791d9d761dec16e22fecbde28067f1300b83e1e9787e7f5afb4ea05d08f8ca4e7000000000000000000000000000000000a6dbdb86b7ce1c6528144dd7db8ca744b8ed7227c5de419cad9c2bbfdbf54f38db655b667c1a2b46a17b1cac5069e551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035125ed32b045f767649f54be7f68006dd965a56fdea04f4a3a3e0f11cc11617e4f94a315ad6250c7839e74d91421b80000000000000000000000000000000012a61f52b5f69f426451d09353aa0674f09a99e8bbe9ded79fc96ae755ddef0e06c5d013d9cf7cc30e0458a04f1b6fe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf91ff84184820e9dbe1363ada1d7974ce67196f6d0c4a652277422500a11e5b3c92f920ad68340abb297170a0b68d40000000000000000000000000000000005afc91a88a02e8024266cb70aa48a7b7a0e21fd9fa908c5220ec2f3a1dcda6b8c1316318b1370db1896e9f2e48bd76f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348af7ae01f1680502f95d7766f58b58090cba891aa6bad7d3c8add8e1cd210a44017f4c4c50eb2a64e07875b08d803000000000000000000000000000000000877719ea4899f88e200cab5e3dd2f450f58a4926742ccbb21236ea25bd49b5afc18f6f1057e411c11638b0646fbcfff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053671bb429e57201fb396a8a9bbf88c3416703e46260a29dae767c652dbc3db6d9f4bd9b70ec9229802d1ef9e433156000000000000000000000000000000000c9da36de9f6d287bf762277bebd3804569526d9e993fe34677d5945baee89c5fe1e9439d9382736e7ee963862abdb3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176670ede37e89fb10ea865f02864484c88b8ef598a0ab0cf0c115b6548c796188cb64f2aebade923ab990c0164c1b810000000000000000000000000000000002c7d0f101ffead3baf97b392ee7e4275d60c7632a472e0ef07a4700de8c056d8f6db5b20f463c065bab21b907a074a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c20981c0facebdafe00119f2fab2114c6af3864f1a088e24e896d6f2f9b756e06f282f12db8d1d5f5b41e7ee23792c0000000000000000000000000000000006f504bf3b85c64d744f33d248ca3b7a31fd0b534b430b156c36f379880ba2538ee1a691c9671d550ffa9fb40cc8e28c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038f7882b4bc43082913fda01e8e4a309dfe886185eff9fea61864276d25657ce5986b60dc1ade7a77cb5835ec07fd0400000000000000000000000000000000164eec14bdbf9a0cb9075cba4b97a0599c01a6ec2a8b9d3299c00c12f030a5e2fea2d3c44acd95740e4d2028a9d51fd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031f4ebb8c150a2bc7f6dab0dfe4b26af2d4777ee19ed2e580deba92acae59bb65cfb939992a607b61c4293ae3c319540000000000000000000000000000000009f6b9d81cc4231c9e33150b6fc5e924b11de4d04d4eaa81dbaf50193918dc681cb627ad2ca580eb87f9af1bfe9ecb541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa581fe30b5e16816b22b70e2c45ffd672b594ff2c6de7d1029c11775dd94a0469478e09669ecd78d8651627f332a3d000000000000000000000000000000000841ebe1612e4122f05d05999a42585191514583c3aa737c0e0bc7fc757b30973372cd5b8251efe77bfcb4fd8d8a04d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f1a51be048b40d4377ad41c2444646db8c351ac0e0a8599780b68b02a7528301a74431221f82f86f365a1dc984b25000000000000000000000000000000000042755042476f2aa1d3d85dc9b23f566b5dcf4d2101169f72bcca1114a5966b4b93bbb734042a8ef253b4ad0476c8bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d9e10771dc796a70aa29e8c9effdb3ad12a394f4b84938d518e2ee7f21804ca50a725e900fa9f33894a94762614250000000000000000000000000000000000e12fc5826661c0147d1d09945d125dad846d055d2047a554f2f67201b4e9407f3ccf8597d7b531e02527d6b9aa37a4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b3246c84b29c836e681cf9b0844e536bcb536a034df74eadbe0d3a65342e52aa77bf1aba2cbfe031cba1cdc3ae8ac6000000000000000000000000000000000b0264f63019ea555736fccffb02c73a7e7c1d174a37f2b1e584a5eca336702a6ef912b8ee5a2334fa1fc67af9d082f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001911ea7d4c3b832311daf9ea2187a9c2dc2786bdadcbd095ca389951c6c00b83bdd2a766c6861ccbdb2b76d69d4b1754000000000000000000000000000000000f3f165c12df6a03cab03a058fbfdb2695fb48ed00b1a9afc58145c2dc226cff0da1e23622689505595401adb03e05fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebe29ad202153071b8a0075c08e78a205fde58111347b38ad63227cb9c015b79858d01c0cf053160a93046e57caec60000000000000000000000000000000007ae8292a178e10192c871ab6f4345eed8b50ea01e717506943384b5ebdb4f66ea1f940d7b699b1e1470e25ee729c1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000136516bc261991696ec38aa4e0b484edac0ff8dcb1f4954c2e13b977cfd7b5413f5c149ee45c14a3df6427e9c4d5b90000000000000000000000000000000011e07424e789a146d99810f5aae0ee9fcfb94ed499154dde6582024c56931d34fca37f502359e0e3db624109067d39f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001482a7cbb8a08ac6c58bdaca01ebdc96c3583c292b9a6b0e634bfc340564edfe5e1b1c382a4608a1a703aa65377852170000000000000000000000000000000000557b5b5d9325631b320d553c1445855ac1ff861bf743cc6792a879a5d89133eabe8b9058cc8726330693465eff19d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ca7649db2e9ff4a27694027c61a18136c0ce7253cb49a744bc9bfcb2eeb0f9508553fffded834ad0f9a4ef7b86be830000000000000000000000000000000013a34de5bfb7bdc6dff720204466200e4a13d884756990f9da79a1e4e5df5ed88de148c916dd7a510376a160b733ffcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6ebf0b8c8ca12d17cf430780f22b5fce6a1abd593169cdae862bb500594d97e3ac432df1fdf389bb40665a69103230000000000000000000000000000000014ac7474ad52abd4b31fa37e222a390700dc01c94cb5b7465febd669dd7d759a3e867d2caef07d5db22cbe8ad42f5f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccb8588eea17564ac421af3ec356d161b951644e718e4da16c80556e912dddcf5264a429ed705f7852ce98efdd1babb000000000000000000000000000000001353e0bde13391585bb156989fb531c3711adc5e86893545054075c792fddb4dc566374707d61b57dfd8b1f24d01fea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dd3a31a46223be524b6d00a855764673460829d6fcf8ac686f128fa7fdde71d487cacf493eeb2de3387f74e085c23d000000000000000000000000000000000d2b299805bb732a097f041be32094479c001fab61fb8c8f210e4f22e87fc2b3cbbb40b45051d8259088e8306b39f4e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017852a34cea9d72a0f06b44f78ce7f0a64622f91e00af204074b0469e5b14b4a98a71741f1ae4d21f6d273c8022296a7000000000000000000000000000000001800e70ec3327f20c9043513551d2d792960bc09eeff27fc6b821d324f66b3473e97a1f074c1ccfa3fff9379bb2263041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001023e0ca5a8b960aaae50e4525a56c03bbe1da7e90f4e83b6c36d1307635b5558ebd705c22504b73792bf28049d8ab560000000000000000000000000000000008cdfc8b95133d9567f970f56c7c6f0995d9b464e25ae9db5fbcfc09c3749f83f65823bde2c16a9dbdb2b2c574f09c771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011952e955fedbbed36cb4d2911a6e9e4cd167f456832a463b1f1988ae32f40751bd195d5b1e9686ab428ac637bcf7fcf00000000000000000000000000000000034decb4999ccd3b3b69a302fddb3bdf12b5939776d1e32334c4ccb4c95d2aba45673407de47347ce57fa8a92dcba8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc12455dad0fd38c8dc3008d3ccab64e03366b6fbd07e199595e42d0d45c3581d92b8cc4cd828d60acc0d68e58d3e85000000000000000000000000000000000c626dd11e3c340dfdbe574d61ba307d84cb747755a503aa2874b57e033b87d065a31104a3f7b68de1db5bd92f90e1b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001764f49ee3571fcdaf72c30995a0bacdccf0a1152f4ba95116d244b5293932b5baddf9712aab7f662a7be28964c73bc900000000000000000000000000000000116e95aafc9a7d5c343ca5c8ed14cae22caa6f64f18f1c18283a8f20b37f45fec702e2482e1f45d31cb4e849d0d64f931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001569c0a587e297c652a14926d39b1281db6a60bbb5e01b2baeeaae31b6fedc863ae3dbdff782f5216a7ba800d259947d0000000000000000000000000000000001f8ee4b532ef576600d963905f8a642df01354777f762dc9d551a8863be870f6c2bb6e3363c22c0f496904f6f30e7d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083246bfcdeb3abd820d62268479a04f408c59f5adbaea40b261c00cdbddaa9a87c5794a46396a997cd64749425ad3d9000000000000000000000000000000001195ef3b2992cb323bb5289f9fe5e8fb0e66b29b78700a9553e82a02ea750d0f8ac7b1d31025553c6fb5adb42fbd00ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035d58cee313e58341655f05ff8534006c48733d17098989d9152a965adcd8fcfd1016c9024932606999c825756ff9c7000000000000000000000000000000000c7e7bc99d8450239f2428827052c2c5e3109481cac01c54c8cc5e93d1e74e3007908a44dee5e6bc5c1bde4e12486f711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e596634a54c462636f5412f567d7e1a29970dc44679d1e234e8c6ecab1cfac16b10d236d62a4dd86cdbc61359108c0000000000000000000000000000000014483895bfd165c1b5f7cab805cfd009b86d37391aa5c9a470abf8f2916b179126a78cf0afb9b14869795f0bc20f34641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f9c1c806a3fe403a0924975c6ca8ed3d13ffca31d0e08170b917ddbd8a4265735bbc1b36d8eb39aa526b208e68014d000000000000000000000000000000001649314df69f016975fb2da668f8efc4197e4a5c6db8a32d907d25a44978edaee79f5a1cc6321bfe7750f9b4b0c3ea781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019165977c6a3e555b3d796fe558b135980321b2efddb5ba1c5db5d2fd4b28882586f0739809e325bec1b1943f2ffe69000000000000000000000000000000000164f123ec09afc326316e92e2338352f12e8d8097820427636c572555b54905b00cf227e8c068321b0f0460c4f7b42b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001107f39c0da286e7404e2f7841a54e4ef9eb55861c9c7f643abe8269a8b43e373df8b7a2a3dd1cb62897beff0b998a200000000000000000000000000000000159e0b10d6077fc77d03a98186b459e13cb275a2a095acc097e59e08dd65e8fbbff2dca9bd240e9a46ccd020bf911a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003a69414b1d3ecc4425f3ce88bf92cedec017a5a56f4737249a88850e271b2922081427185669cdf460086efdcb8ef7000000000000000000000000000000000a3977155b262ce8e8203c78e13f0ee11e2073a02d9ce4565ec4f71ff22a351b31cf018020f2de96330da7e289e9b6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150c0566dca578e8047543b4d6248b41afe3d28de80435177a61dc4a7cb4d930ebb6c69f7a4169c7afc675915e9a7159000000000000000000000000000000000b043de6ed3553b055dafda0a1be645de10085595ba02a33120151b9ac76260e992615aa353c7a8525a31477dd39a7611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166b74f51667b43803059af1941b340050dfa14c915852e03aa4228047692d0b1ec8fa2d0e7a8c2de4394d8b82d47078000000000000000000000000000000001607ab94c338f691415a05eb0a1d14817887229ed5dba0ba007412f1840f8b6fd70999e7fb96ad1fee32ecdc196975b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012d8f23233d1d442ece97d5a90033b3d3d247dae694b2ea07d1d0c3e7fa259a7216f0d0c873c8531ac46254ebcaaade0000000000000000000000000000000006918f9f9e62e8e8f18dd7028bb5b02c9a0eb90044361ce7c18482af760a96f32a1b4aa1c696ed9af203d659a4f6c6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026b3e043fe8c1732c86116c1881692d5d7ad2545102ed4d7ac48fb9875679c59733c9d47cadb970e28cc11e77c2019d000000000000000000000000000000000f4e97dfaa754e49ec2149e85143818e732a16cddea5a28ae8f11a11e1f78c3e71d73ceae977e1e37b0d40d82dc2b0f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000829cecc6c9eff30cf2171e0ae6821c9be72fcf325df65f59735ff3bf7a955c2902224d09bd901e05fd13b893cf460a00000000000000000000000000000000009441a86a80cdcd6d5c2bc7ae9a3a8385f29e2f3de060ca0c0b8c645afd8681dd01a80c6089195fd44765d01b74af3161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013399883cfa147566729742f9a8c56575d1ce6c7d1d2259de89e7f1b36a93f33d9cc843b4e4cabbd501d5598fc6f2a930000000000000000000000000000000015819d5ef8d05cc547677e01a461e3b30fbb51054c121f83711123216642a9df5ef18e6d07658824d8fe3c0aefbfee921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010054b20f655f30f8645cdcc2c13845f8024383a1e6d2a2c4a15bd08a1ad2ec3d415da676ec648cb4d64c9342c488ce10000000000000000000000000000000014c77475a095a7087f2b6dc7a27da27ee7d9ce7f9bee82a9560ec002aab370eddae5d256c368a705042f78a7632879351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ffcaf645cecefa3a717f93dcf70c615f75824f815f47cf02628dbbff782495d594c988d2278b5be857d99db0fe70400000000000000000000000000000000045f7fdfbff9c8da2b23ac88212786079db7cfb5777d92ba59dd9c5e40addb60a354c90752d559ba8ac04985b5b3cbbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a3d42df44adc46cdf50e173acb4cff2d3197a03b585437bede5460391f4e12ee2458ce5576abd14c656d22c1588ce80000000000000000000000000000000011730a4083ba5d22ad161857496c991ad9c37abf30ab30207ee46b77b28b8c2e915e6b081e14e7217618bc40ef5488511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027abeb5f5ccf3f11d689dd746f8dadd9b3b9c6160d1975f8bb3e41e4ad6da6952235ae385b5b8a3a5899cc8f1b13fee0000000000000000000000000000000011a90363703958e362de002017e4e86ed2dbf5c04fde4e560aef013c9a49f49e51acc19f5f3e2e46c33c81cb90d98cf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d3ea45cb0c04a16a6cce99ecbffc9774cd0cbd79eaa8955398d60b561c09f3fe4f83ccee537f8d5ab5f93461e85c2d000000000000000000000000000000001736ac366727445880a43c8dc1bb15878cf07c6f1eb9eae0d3a435595c791f68f5fa10ac4da0411640a5e9c4fa1724371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee7c3dbb6847432bae8cf6e6b7339777867c07d8745c335fc4061bb2b49da4af3be3a22877a9428f9bcc6957d0d64ce00000000000000000000000000000000100bc614d637275674bf1dd025127c5670831586d4aca79c9149f793c71b92b7f71b144d50b900f0140f7e42b1a8ab4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9a55089e6fcd424863c35d52c90d2a5fe7c45ca946e7f973812a6cec14262ebbaddd01c872ddab62213b56aa181da6000000000000000000000000000000001283e293ff5e04e379b00e7a8251e1b5e5dbd7038b99c3e0221e1f7c242458eb31f5e2a7722b638c4b08c3ef1131ae681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed7ad207ce19a772919a1db35bf0547f74dfcdbfb0be33bf388b147a17fea10617c8c07607245d8997f6775f47d8dd900000000000000000000000000000000142308f35bd128e384a630d1c7ae1547d833839822570deada353edcb09f5325f318fb1feb6000646fb5ff26a2b22b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006524535389bde29cdb4021475adb9aac3b3a6039bf1366167c15ec72ca56d8d9cc66b8393e2fe7b1213de4859130d5f0000000000000000000000000000000007f12ea23c2643ca11d037806367948c7d0a032cfe61b281dcdb63b038c6977a3ee642e5c1844b2e97a8bb4a7827a0c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0f2288ad42102f284bf7695559b0d7ee44ff79419902b5b06a32a4d03fd7ea03c68273e959041d7ee25a8f113b5e390000000000000000000000000000000003823ddd6b94fcb20ea16e56239417b6039c5237577e34deeea479d60ae9ee020e701f3ef30b680e58facecb3bef953c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6ad5d3f33da0e48e182653421a497b83d2b6a16e64ae75f5309158722f72b2c35dedb6b3580e81a28391775f77fcf6000000000000000000000000000000000e7e6cf3ed216ad95e87c3e9d2f387436288448af3a8fcba9e64487da322540cd2698dcdfaf11352bc27fe4849e0a0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffbb74b75dd5ad1613d7f51f7e03f9ea2c94235a4abb918c50b2146d5a17892f0a4c81a274f678fa6bb3184063fcb49000000000000000000000000000000000a371de0789ed85d8801a9c9fe8c5a4320a42130755b09fdddc9edf27d721beb90db93238c3bb1968561c190c95f23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006546be4106512f52cdd1849aa84cd155be1f4ccd8f1ae8185b17d0bcfa2f0fc9e95a8a14e503f80562ac4fbd5a58ad50000000000000000000000000000000012d0d9e53f902120bdb4b74009425187844adfaa1a72bc453ba9b8bde708b7b6281d1ab12bd2c247a84c9f175996992e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd26a9c0ddf2fb1a04da0a1edce583cc1e7109abee3ba2ce57356dfa6d718083ecda9bdb4eb56c82930a302fd9fbc8b0000000000000000000000000000000017250a9d4acd12df90702265920d19dbff62820ac28a53886dbddd215c8569576fe57fb5d6773ead34e5c350b21edbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001593c85979da0cbbba2be2f21c8634a704b5a2d9a9058e75318ce478cccd2fc682b1344e0669a3fe63a377ada1d19959000000000000000000000000000000001055b5a5b351a39284a5cae6f667db6859f2cd7afd3558a70c0cb8832d354a7130397104d65e4bdaf4c6fe5042cf7a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003152e79c26bcd3d6be2d008da5aa3db178be19c745bbd5e180f91bb2555db75899c2b9c5aba40a5b7938cd1bd0e02ba00000000000000000000000000000000023434abbb1409fa6200c7aa1dfaa5aa138a8b5dcc34bb511b6d8944a05e2e856fc8e470cd59672367ba0ed3b9725bd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064a421769e7a07be019579c2535f4833635c07646dc7ede80f5f7595024f8cf5c3d2012e28eb561616d4161adb73ab90000000000000000000000000000000008dea6f18bc1c91c0462bbea52cb4fad9fd2f3e08a658908079a783f7dd3d7a431ce365260ac88d7696e20b011cc59cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8820a5df7ab0425997577a26f2e07cbbe0837aa4c02d100e30d44d8edf91ba54f4a026619b24e270142537ba33c8a00000000000000000000000000000000195e4e8a57e36baa77321b3c0a907a8ec2b091ab5a660e180c05ffeb16f509f6a67d08cc85d097a7fce9e80cd125a4981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002404b3866534ceef07b6f4b032427ad51f5490cdb923be78bc9132533357a173d38b9cb3b7694209377f1a90b460f3f000000000000000000000000000000001742e92898b4f3b31a7b7b7ab0cfbd95dc804d46db4a066ac7b9ee9c6cd12340cbe222eceb175df34855e85867fb6e4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f437c104ef22a3d140eda90f524089ed3d4ccbee836a052fccbf158ec2b39b9e6914cddccbba0aa8a90aa63a3266ed000000000000000000000000000000000c3ece774ba6fd2fadf621596d3eb9eeaabd79fd8185b74185a23218b7d04b985ad996952ad894fcf1cd30d84c1f626b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c7ccf0cda632f6b28f7a45d13b4b1615cca160c54db6a8ecf24fb628dd0ca964d9dda3117b6f38fbc5d7f07e012f600000000000000000000000000000000072215ea146eebd043aba3ebccdf6e85e19d0ac7cf6470650e27734e20531b6891d5f597e5e75d5e7ca646ce6819e63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c93354bcee400e5ade6bdedb95b9c9d616823268c51b4c579d87e56c576cec97de20085c309f5157123a890c6e6829f000000000000000000000000000000000b4b518be79eb3d762c68c94ffd981e47ea847fd625353bfddadc29a289c9d1f9d325e9cb97d3892480ecff66b3ae0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018feafcfe6047e7be0294cf81c4487576479477106bb17bd9a037042d30a7058ad69ec575b9a79459a15a2311f25b8f100000000000000000000000000000000172ac9966625cb75758e70906846564cca8a6bc6842a0c05e8463085e9ce52e85fb0e30d735b509476d561a6e6289c5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6f7ca16244ca9b03dcb770bab60f079810e7edbe0d9a3d12407a35d70a14eeb00e955f786cab3efafb64f146bbae700000000000000000000000000000000010ea5facf9b8ea088c92ff1580262b77791cb8328026588be483e3633fcff3bd597687628a0ce443c04cfe44db7d1ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122ced525a41d10bbff55052930676c45a2f52e1d5cf3abf12f8c775eec3b80507633460130b17b9c4c0c5869ae3336100000000000000000000000000000000028b92cdf071a327019dbd127db1c3c6c2683a43228486e751fbace9c5c95d1133b7bd03bd6381df4a1b99d2069effe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198c8081949a7fc40c645c3e662f6eb765050b0aebfc710fd81a605f7ab33a983027d638b6d6ab27b34eee23af4a06930000000000000000000000000000000019b7eea2abb90eb8c2a453ea7b99f564e9de89398c6ee145dc8ea7050ed92eeced4e9d6bc0592285b7d81eb1e55ec8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b7ec88ddf82828d69f0af9f0dd4e943e87d482d33137dd7ab55906253a5dea4a418865da2b357be66723367c26ccf7000000000000000000000000000000000ffdc792276fecfc17452ee4ca4616875b8a376cb27bbf40bfd4dabf891fd9b0af3f5c7578bf8112750f742980bf45271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dc718d20cdeaf12355e9b4abeaba99bb491026833def62a56028239a5dbd2ad2405b1f47c026c5037bca74a257073300000000000000000000000000000000117e0700a7f257d5377916e679e147564812710d468ad88957df25092fe41574dfc6d4a5568d61f46fa9f8499aa715021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d083b057e01a19a519012e8443312659dc9488874c3132d2f0225d5287a500b05333b10ac97d6a35bc076b7b71541210000000000000000000000000000000018c7c9d21e9d464e85933beade2fac8c5c64510015474fd83008ecb165b9e6790c834d405406223c64a32251e4fbc0811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f906ecff9796c5b197b303375a18e4c6324c0f6329be23c367bab583fdb3999f63e07ad9302321fc17946a272f4708a000000000000000000000000000000000fc4f3a3fdff6f6ff67c64393c51c2f9104797b81910428d0d516e442ee9dd96ed92ed4a867a8e7ebeeb42a8816f85bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561cade10c6fc55f3dbdc7f984e0847ad00eea34b544ad1f04b4cad8bc2c067f7a3945c7a1caac5c20a2f4d37fc39af00000000000000000000000000000000150e3dc81d27bd0778b46bd913c9230e9ec3f8b8c2beb0da37d5cea59343989c040e3d107657d372f39e9d38ce8d966d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bb8fe74aa0af494c6ad85ea2f53936c6297cc101a48e5c02810696dc24c932637436165e7bf85a7b7f3c99ec56b2a50000000000000000000000000000000018aba3b77bb2e1da2df67d27fb007e46980fbea37efc6c5ddbb90ba12599d0384ae37ab125bc24ecf5afe66ff3828d0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfc579e2d646103094129711d774073d7c0c2bab4d92fadb95fd8fcd87f5ed4a0945f79ccaecd316390493dd6ecc0f0000000000000000000000000000000002a8b2b6bd49fbfcd96cdf6089bd849da6e82620d38620d7b76077874e8d66ccd2807dfa438c7157386d3f694f1f68a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002febfc1e185028f383de39c285aca640989799f935460bc650e68d2077f0a77d0896ea21715264ed8f9c43194363ef3000000000000000000000000000000001376f2e6443461ea7224298d45707358a74d8e46998aa9e535e440f4d7209d906b5678baef796547d37102e1540646b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e97311f62da93aefbd6439fbafd57570712f5d4f714018fe68e715928a0e978ba062d1fd440ef85d82a3e07a24e95ed000000000000000000000000000000000a78b45a784470c78bcca7d9702630278604816e4c01c74f14859cee3bce05b77d255bbade2261e9334ff5a5913336091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9bc0de62eee4097280555b81f5e1b3070c63897edada5894bf948fe3748c17003199b5747c8a9f5c032d05817775900000000000000000000000000000000036083796cff0d6c15233ef6ef00282d9967aef21d8e75851f7dd1921cd4fb49057a6f1824312276927e243b315f147a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc194c5be3bbaa06014872764bedb9cecb3b4080b009d3eb3cb73e3a1f408f6d40733cc215c35200d26ae4906b6840e000000000000000000000000000000000b79e3bb2e163fec63b588dc0f8d33e62c6b3ff44d3921df782e89229db71934c946975c7d18d03913dd7f4749c8b3211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018abd6087a069c941f1989121984cbaac8d7b08713bd71ee95df05350b0e47c45bc9a50a4f3a11ee28f23afa9cfaee2b0000000000000000000000000000000004eeb9984d209549b2acdbfb23b344189958953d3c78fdbeaac0c61fd5d837beb10a455caa2aa0944223299575be815f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6572d80a157f02e3d16c93e82bc11c5a5994794dd9ecf628d75c93d72baaaf65e97d271ec114e8a12a96729947824500000000000000000000000000000000061b8afaa66d4b861e2d442883bcb65809ec930e5f88916f9b410434c7a1e064f060f94f56bded021cd8b0051fd8f48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a45c180d71585aa1066059aa92c0c87edc8b0af3c60a780f3a511dcc65099fe501040e149a4e3c7f9626fb93cc60e78000000000000000000000000000000000ba38feaa90cab68eb88970eacf57a6f73894532bb37ddacf8f6411c6ae2117538b50158e118bfe09c841253f7a139d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b37bc2ce2d4c989bdb41a98312b424824afb2e25cb4574963abbbe0d4af58eea1aa905ab882d4d73059ff95b529b2e000000000000000000000000000000000e9e9a611f32c6dbd627fcff3b80e6dafbc830d55a41ff5fc8e65b1260f4d6827c3de9cc88d9d0bb6856db493a53385d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005abcfca187c11e355ba262f3acc8073d4a6c92a22d888b85172684c14fa171dc5726a2c5fb6cb817a9f6116646b9ddc0000000000000000000000000000000007dd558165c7431466773828a44f3bf4722ff76e5b41d09d95726b4c8cf682287e1435c45f939f70b78fb1fab45ac6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014400c30aa7e17a4cbc2e8e6154683ba827e0cf640f311c5a21b4ccd925d2f6e6243a7e9f04b12e396d9cad573e5004b000000000000000000000000000000000cb9006c4b45113e72119707c6e6c5409d4dfd324538f5cf32f31ea96be48d06400b610abc29e550ed5663a6f021826b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007505688416b67f45d30f93c620926538015bdbb9bde663c13e8c52962f5f99fe708b47977ba5c67a54355431a58c8670000000000000000000000000000000000bf7572b65536a4f064d4af46ffbe1f3f179adb81778799433424133feb54d2149d24890ab1d7101acc804b0c8ec2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d36c7036fab7244f80f608ec310ed56e71f16c606a5e0c32fdb246589f6d1f9e86d82aeb92ef80fbca9deb45e45b3300000000000000000000000000000000157f947f6744567a8fbabfe35aecae22db2a90fcc9a7e0f59ae70d4861f8ab26d4c6803cfa84ad272628d7309db551241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ed9f10ec3dac0d655070c5adb506d34ae26003ccc0a3f0e3eb1d236068a149110199ce46b105b77d1c84be8f880a76000000000000000000000000000000000bec424cb16fa12d9383daeddf2f0e4497ffe101a6bb1dc1f25587d36ebc15079d80b9fed76f6413e0319ea2101da80c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edeac545330a230358385cb0bd815961466b42c22a2f2c1abf09ad6bdb1ec4acc610515bf68caad34958d2678cc8b9e0000000000000000000000000000000018d53d4d1cbcb3f4a164eb7284fa4ead1a89bbcdfb5c5f6500fed44c48b62f63eceaec1777ca5cd8181c7c15c33af6db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590e721877c4b430a79b2deba121777120d0ae3f4fd9dbb0d6374b458994cdbcfe91ffad5b461b4b289de35c75bae19000000000000000000000000000000000c5b0956bc43422f9cde4766f6a8008d8f05ec10d642dfa02c4e47a8327a8ec0965ad4649dd0542a8ce565e66bd001e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c961d481923ddecc36a5d37a813be88d6d5ef1d3573831b0c494533b25cda4071cce1df8accc71f06f2f358c9667f00000000000000000000000000000000184e14c8bfe8a949854959c46f6b4423865312f497307e446c7d717cb2993b3731b6c7a94ee54a4af9ed7b9aaffce7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc7ed0782c09eb07ebd5221b9c0d29adeafdb67a8754b69a856b1ee81fab2371af62316213d72e14786fc904f204a00000000000000000000000000000000019d158fcbbe512bd76c53fae0afc90fcc0ea282ba666de8e5f06e70ee6111ec986d2b53e3e2d8b17e9f9acec0b724df41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e088b828c4e6ac589dcf893c71f056483ab903433a2c011efe671a8e94d73292b52e9e6dad150d204a20417ce7201ca000000000000000000000000000000000003d573fcbe59139e2dc8cb9f5b8a89d4a7126ea89957b35fdd1e0c3541199584fcd98ad3d0ac7d42f9ea159fdb8d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197e16fd9f3fb148316291c906ed4832d173f6184e7bf1748123d9d3b222df929414f812915fdada1858ec43d1b18a3700000000000000000000000000000000173bc0ac999bcbd09e24a86f9e0d594665a15c338368e726bdea7ec25bdb411ce74c2c9798b5cea3fb583ab9e69795631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dfeac09aa5125ca8d626183657b855aec70448181ad8da21ca4c4949280340dad52e087134090cbe1d5712c3091df00000000000000000000000000000000008325043269f7f39d71afdaae493389bf88e5472b0a476350da2dcdf3cd9d848eacbfbbc27aad3f923a5f2bdc7e20aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018803688ea03f8d633bdee4e4367ef6ca23dfc925016672a96bc4b252aa917f5fd160777d2b03bc071894004f99ef677000000000000000000000000000000001704af270b60b6d87f627628d49f2466f5fa30d4c150eb59328378d8ba1f124bd4c4ee0d2cb3cca726447df2ada19fa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f4eb256c0e03e41a8b902b946cdaff709c9db498290ddabad5e192366a17e89e53eec06b2b1d9134790d83111415f000000000000000000000000000000001260b5036664c0eef34432a9d8393fe0f3a090a03d9958a1e1542b9d2dbfd862f9450dff5e8e70628fe9845607c3b5b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e0511179ebf03b33fc3c33d058e9a6ace6be29688fed00f3807c3926d3efa3902510edb0d6539ab0516644a55ab05e000000000000000000000000000000000c792ad5d217c5e48fa684f86ab9d75e2eca5785a44192f883fe9819ba01f652fb32a29b28d49905216124ba9ce6815c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001604724fb8af98ca2d2183795e610e8c169e93906563755b3be0e465db9e622905630a7dd9f15d61aaf49ea724c7545e00000000000000000000000000000000080f37e6dc929accc6fcbc9a3c13f278fa4b3bff1ee1a7249c956ab7ecf885e5580c08ddad0efcf7a30e71f9d357b5011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000418dcf53d6635b4c0931f49a68a400422df08dcc88ac270fe7f934179103d7541af3cf4003f9e7e32ced1050d22c9b200000000000000000000000000000000075338a16894da3ea6f512c7035e22884e250ade8ac2bb9d6a238036cb47e02747de4a76145d38d690a508089c0d80801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9cf279309791c8cc577c664fd332c14cc5c821905f194ff711b08b3df6b3e9f82a72bc46af00a1368ff77d775933b10000000000000000000000000000000015bb2eb014c3fa9ca7dcac01670e688969e34decbad364036ba40a961c77aa4d7a962386b5578c3b4ac351676736787b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001674f239a7f3532cc4100ec4c2ee2b0ad56cf272fa68ce5eff993611fab4e9e59c680c392200fb8206de486322ad5413000000000000000000000000000000000c22ace6ad16e6abf06ca0588b19841ff7cef5c72ad80d9041715036a0a160f5354f83959a69a1b2b922214bad71a9e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009ca4d7f1e512eade03b67b4fef5959b018e6af3866a9a7bcd154effa0868f7bc49d5c1be6410615df3c5a6570e7aed0000000000000000000000000000000008c6dc890425d3007c12dd4ba407bd5f15a19ce26580f348f3d9a4ed4c5ec289f4f2429546938e09c8644c02ca00aba31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6d2d7bc3144a4f6f6445e2d12c1863d92aa9c1f1a79b8bdac144d74a2aca175d702555baee5ddf8253b320a08f85b5000000000000000000000000000000000eff16de03c352263c5b5286eb94beb11d9b5c936ace083a6bb93818e1ccf6aed8c51af70a749db79491df82aa801c561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030c09bf41bb34e61d1593622c6ea1073fed838ca6461e974bc4883993d2acb237c07cc8d6fa1fcd4a9c03f6808749350000000000000000000000000000000012d2c4403cd5fe15734f571ec59647cc4f4ab4ed5e0c2263800f9f1a1e3d20b8ae55072b441efb21f09c4e72c878894f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4e344b6ade10c56530bf2e39c3d38babfa35d328f824450054e253b3a8b7b30cf21a23881f8e5f0677d1572691e389000000000000000000000000000000000b8b3f651cec94f48104f4ddf84b639aa44e9c7ca7c33672e1dcc4cd08d0439be62096dff9673a3b1cb7f287f5a14ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051849958125f4f04e79fc18e4bc08ecb481cfaf19a3700e23a9ebf4b653142f78cdce7bec9dadea96d0a959acbc55f50000000000000000000000000000000015580cfb537c7f3a719990669277679037c5553b2ce03c89d09e0f6e8324212171daf449dc4d7d6df0cb838bd06d1e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001601e06adf8969c35218acd2016c954c3847bfd9e0fd7d5a9c6fab5dbcf6f67de9e47c8a9e57c15eb849bf69c465b7610000000000000000000000000000000015757410919aa01ed5d43bfbf4cd4a8afdccbafaba3dc8b8fde5fad23c8091871b302e859e7d72e7202af8d39add35341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e6d01228713483dbc05cea49f32a841658d269288eadff56f31da2c831de1e48f899499868b650974b32a0e09eb690000000000000000000000000000000001afbd6aeea7c2fef8319bfef02f191182a3ed74727d6c62ace61ec165dc4f938f214340cb48f05846fc58840628a8041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074debafceeffef489e664f3bd81f15d0ae49e2a510795233a39f55819c27ad366ae38dc32c36687a095f7a59832513900000000000000000000000000000000120a2384968008c5daec5ce5ab2ead37c3e8b34d381ed78c8549f01e8e134583b29bc71faa947fee6c3171bcdf9b02f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8fffe737c1a46bef9e76e5b60f69f844c6a40eb8d7165051db1569b6eae9485384b3444452d1fc6abf8a0ea392038300000000000000000000000000000000093600f3841af24defb2d774963297d1615c305968b33e9d109482b93ff063d1c9267f8b611eaeb96bd912c13cbecf261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190be8b35c8cd03a1b804ca9587c6b6a5c79ea78063330bf49637afb2234d59fd82d5304fdf4d4396b10d5da4bf9d29f00000000000000000000000000000000177d45f747b2373672efc9d49f75962f28c992776a6624ac78b305a35cf970dfa00c4d334d56316ef504e6e63762317a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b050941f7ce4ac3d95405c79d9a394016870d9cf6cc33813a87fc59dcc556fd323346286ca052063fa7d571dfe97200000000000000000000000000000000148e0312f314cb689d3e4134b7df68b8ee351aa95b45dfd0fbb1e9bb852648f69b18b95e06a6c2883afaf99ede8c26311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a015feb9f7feeda1a5fc50aaf3ba9a04c8768b1ec0987b85e3e3e36e9eb73341950e19df00d046c6d0f2208163aee4000000000000000000000000000000000fe0d57519122a66c130cd8713cddb9e5bb795a49ade0131584801692c2e733255b3dab830a038b015bef78549ffe5961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bc2fb01760bfcd7c72175ae4e0aac45632b0d2107de734a9456694f20e8f9cbd06351aa37b236086721f9d26b9a19100000000000000000000000000000000151fc93cc357e7601bdba142d11f8d1f7fd282e7ee64b41c80c8155008c3fa66a20c7fe044b792b7b85c6484a85375a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6e2eda451d727bda5caf50301f7a5dfda551604d2ca995953ff9160f24fcae8c50793567496733ebb4194bedb6cefd00000000000000000000000000000000003bf18007c6265fa3279c6bcfe6ea01e530ad9dc46b6208e892b8a1ff559e51fa29f48f56cf0894d0d83c3e820583881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4c2b54347ffb088cfc48e83f364886732023ad9b15765f7b1f4bd2246f0ae5affc9e7b00e6dba257d153ed058d8e1000000000000000000000000000000000cfde79090aafed59f6650d30425baec943981c66b8cd84eb3e359517e039230abf5401af5c8fe7047f73eb79d63d3bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306a31cf7f485731181513b94ba67315d9bdbedb9e1a76cf6589a5ae3e9729a82409ae54ea427e9109b0ed7b6d4fb8e000000000000000000000000000000000a3babac244b49a34d440b05b3bf523f2119e659781b1a787d8f792557ab53c9ba4762d5266656d5da7d3425b17f76871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bd24f79d8b557b20c3e822936c34f57c066755ad884e6dce616171ea29529ec5d6cd450d0658f2f9d5eae83ec7903c00000000000000000000000000000000179fd25154f799ffdfe70ba531d916051f52390e23e5109db61d122aed9d45aa8ceb1774392e94a060264220f22d8d301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecd24d7ddc3f81472772ea2afed3c79baffd0fdd287ba8c6c0bdeb36d2eeff5b92947afff2dbcf2eb2ed36c3bef927500000000000000000000000000000000105f7882a7d1236810366b7ef3cc6bdf8ef8a433a7c27b6792f9a19d783d9e253b2536517afe0bb86e65ead5632034491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049aaf34e09ae3693115d92583d1bb56aef51464f0895a2c6694795f5646b6c0547df5901cd880a312873b5f3d70f5930000000000000000000000000000000007e78bb83e04ccfa8f9d7e158c66fb8140c29282090b6c0f9fbdc834f5187af5cc48ccc327fb1dc1d896c34380e78d3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013379573068a85df62f71de3157b2a3d042e54e74f779ef6ce08e3f373a113618e205bf2cb64da98881b2522935a24ad000000000000000000000000000000000dc8a012201ddfbe8a0cf5218cdbebfef1b239ee892a9664f5290575756abcfb8bc223abc809b3098ae6d1593a6bdcdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000148e39adf09ecf10fb21bb2181648436b2cff699ed62ee1e9a50516b80eb576a9fb9c56a054313faac5dd34eb5703bd000000000000000000000000000000000a093ba1b1d5d8e797a54ebfcf320e5557a006f8b4eb01a0817e59f6f1fd5d9c993ff882d0996956eb65529f47c5eefc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e464349247043207a5c7d780f5d635b09a5d6be27f360cbc9397418d0a69e1e09db9c1a3078a7170f344ce27578fc0000000000000000000000000000000017a7ec70006cb88edaf099727b469cb1832a3a5d245393a7abc66cb338d5b14f5d73f7899615ce2ce71afe86240668d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000617eca06880ca45377b280d7edfc23fdfbb9cf5a1d71ec3de5d452366f6f8c0cae846145ea00fa55e66e2828474b6b200000000000000000000000000000000035faa871dbae0b924d81764c2d3d08d4c8bc1d9709b13c69449ed614acc58c4453ada36479e6ca3fa93182506c9fd941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002009bca2c96684b1cb2e7fa39cc70b8d2ee5a332b453dee6724d3bb4843157f884d733a15d0c922cf7782f77adfc52b00000000000000000000000000000000059ecf5d0b25742f52deab98554b02dcfbe87fa55586ff47bd2b693d0ea26ae82da72636e68007c3905f172e0961ec781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170762624fcbd6e1313a7d3605df3917799f87e2a6c5e976b56e687b5d666183e4a1a7fbd6b7c08f54184f883a890162000000000000000000000000000000000c65cab64aa762a3fdcc182ca2f133201d44c6c28dcb881fcdb6242583f42abdae8d379927f92768704f9465c7b6bcae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158135fea5ee211d9b330a4112e4ae736921d6974838a2ee1240e77f558dc470e41551ac323884b113459aa7a964a91800000000000000000000000000000000155ef1ec7a8fbca7bd70414a73566cff1548d2d03f89b4a336e50d1971fd502e829c7ab4c5c9bee3905d25adc32d42581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ab4895200b6c8c224cdb0376c2e325d723dfaa361bab31045332feceb9af7f7308f05b049750953110c8defd61a9a00000000000000000000000000000000047f5f7c158f8102105331b8bf9041c30ace29787259403047bd0a09c034a57323b1810e9e163e93b12de9ee4ef7f9b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019027b33f3f61111d4fb412e4d120c895dc6cbd7eaa448dd9f28e1e754a4decdeacffc0de9803068b6970310a3954f0a00000000000000000000000000000000082f94c1f1777501e7a3559570ecb30eae51cec434d2b7e81bb4ed496b2de42837321516e368b6dd9d15241ccb9434161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d065290372931ee3bff8e59dbabfa4c0c7a4be2fc4bdb4c07911ba57d0d4c4162e72ff3f3cd884958255d61bf7ff90000000000000000000000000000000000645fe437bbaf312d73a39d6c02910b5a71104f8573d1bb62c817ba4714648786a47a39d56d22c5575afb9e3c9b4a6f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcf2597e1d007c58388f696f32e87bf0c1c9dd0a8d82498e6b712817c65a27312a6ae4d66801e89f51d8ac2db87495c000000000000000000000000000000000a2d0bf956414b2f86f2f868385f2c62daa0b4d1b67960eae829059a8e91a9328fdbad019d651dcbe37a48182c8baf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b161ef685574c54796339d79da83c0d7662b11836cbd80aec7667706b198a49ac22d35ca8ec589591120a41fd61114000000000000000000000000000000000d55b8f7dcca3bb5721548cabfd5635060b4405d7968cbc4a6f6c2b7618cf99e9533a45f42ab1ccf343da563f482a82f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000012d8b3d241d6ea891fab2dd53e79743b809c71ff769da64a5c65b0bd91dfd747f8b858fc7f7abdadf2f857e13ab0f0000000000000000000000000000000013b03fb02ea7acb79426b730cdaeb67fd851ed51fedf34b954b4ebe5c0a7427dcd26da4de5a61f206f523fc423bc48f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084444f0c9049e4c912921bca7bd350a130d3bb90c440b590699f973d9bf15aa678878b44d4c855f6031d96c3a542ad20000000000000000000000000000000008b3f6036c1bc72e74fca81e3b3737b23277d3f144d82869e1ff5b5ca0995929e3f6326c7a3edcda18baf4de725fa36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e61bfa84a8c090a64da3e495580aec8762579e2eac4c62511cebe09e6956b9c35dac4a0e0f2f5d857bb4f3314ade9f7000000000000000000000000000000001959863c91ada69808f779ff8367b3cb4bdf35bda52f89bf2b29c3b1bc25c3fb75f9ef7283b00c670a817ec4ffe164341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043952b8cca166fa8093696c66c8b6ce39bb5fce907480c9b930956aff574e193c7cb3efc849b68c9f3fb67f244bdb9f0000000000000000000000000000000000eea7bfe0d6185d4aeef016e55cdb35717c1be8ef64a36452c070eb46204a4b482b04fc7e0d65f88963f1a814de54fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103cc9f493f26295d855fe8fe8529c80176cb8c0cb1993b84fb59b86e0c7168ce3a80d10bfad0e94fcc4d969a1c9bab400000000000000000000000000000000102c014a17855e58b87aeeb6971bc8045ad5e75f2e22b59489830ef635659354390046429bbaa35f80b6b076402a7c261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001189cfc25c6c51ea038fd83061b5d5e48ce15911336fc9e50b8a8e81a8b2c2e7de605eb81f70e6a511b1fea6bb1b5b280000000000000000000000000000000011ea9cc3d7db9fae5c30368f670b17dc1bab0375fd1f8a971fe5a1ad0cb9972e2b4e04db9605903c29afb59096df7c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152a1d2eae01c41ccadb7c13e6405c0a93a44696f58ff16ff62e15fb78a6a7dc9fbbaabf5bfdb589ef54d970b3647ff3000000000000000000000000000000000d9a5c2cf5713c2e484ce4f759ab0e5fb3d22e8b0131ebc9eb76e2a557a5721577e1166c57c2514feeb0b69bbc9b8f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039c7097e720b8acb7f2b620f18165dcffd6ff89c16463600d183fbd3ce8dfa24ecb863dc54c9ca8072353977f391b680000000000000000000000000000000016eba4e180292f73f58f1b44e6b0ee19eb3f3ed8f25806ac690255099e7f69d11ba7e5f4c156b28a5628ca34133054421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d9d1a830bbee41fab3825d0728e77e8ad22f8df12c3d829292acb379869c9630b642423ec1350b8d5f3f7ee49751900000000000000000000000000000000192fe4ac65b78ec4fdd534f320efc16d1ddd1a03ae5974a0100bb15c038f7e27db085fb6ae29c6600bd9aba4b78419431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d5513029f1f2a07b1c1d1e35e520032c187898e9246e33beda61dfbd6d754a0b86e17b5589ec4a1239c0996bd4ee590000000000000000000000000000000018d5a84057078f951c95dc9497728f92d4cddd773733c9d2488f886a85993309cf0c39346ba91ed818e3627511ded73e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fa53f6e339c97f07552796ce719080c187fede2ea0a9d7c6add01243c88f3a257ade9199a1826477d4871086966ede00000000000000000000000000000000196d32a3d320a0527d874d1552c5da42342b3a5b0e5fa48b2cb86a838523e4cc9d278291ae4d612c234ee79c6e9a96051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080631d6f440e0caaf4c0977109bc8e727cda14badffc50898cbe2a97bb4ef264aeba669653410ebf0f1900f07a2648600000000000000000000000000000000184f0397f7cd94e7ca2135037a50c802a85e3540f0a7ee3f42d7e6a0346bf1f7b3b0dce301469136b0ae21b1081d73661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000957c8c6231d6f21fb331878c20587b4be19601040b03d6ac3a9e7750bbbf76ea044492bdd1ec86d2a0bc39b6cf119cb00000000000000000000000000000000012bf274249fc4eee13ed718b260d95e37a495375b96d99c99e9789103a420ed911342387c14b70ac751c9c0240a8a021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006094a74ac191d887254e4d4799d937995498077d04f414fcaebafb7e67b4cee4e86e57c2eca8d1e43f05410c23180ad000000000000000000000000000000000f252c575a8b5f2c67cd69c05276f88550c04d343f957f3221c7785417100d190cb9a98c6a181a9da02bb9afa9e129381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d124b9038f96868c2e51b8925d622d9bc0b8138bfe741d618ebee3ea532e842dfbc7e1825f459a0c83caee274119230000000000000000000000000000000014fc28b5b15b884f78867ce588c1a5a6f08c735b87ec72373a3fe490c242956605d572e6ff58e0935b3a1ab1526025201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3d23a294f9c7221fd73d8d6f8e2b39bb1c67203a0a77a98810ae8751f00a4c74c8c296f8308143d572dafb3323d6330000000000000000000000000000000001d8a837266020600df18f16eef2b27fbe21de5a7227106cdb424ba2bcb02893190cffce652066bee6949b2a3fb2666b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb01af082a0418f7862b5003f9974b047ab88362bdefaa30ab9c938942b100aac1371dd6eefb680666a9518237ad7700000000000000000000000000000000157cc059bc3c120a336e260395ba274d647b12c0e3198160c87fe95aa37e308c3476dda3066acdf854fa889fd8b1aa931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000338d3b7fb5a42ab99fa3d0c7899dc0b7018db189b52fc3db6c9f8805c63c48888050ea3d707241f17deafe0ebadd4cc000000000000000000000000000000000d9dd4888cf763efecf5289db692ea1143adabfbec4948c6de76c435ffc5eed215e516a080676b942303404108c3bc6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3fddad4c0b3df0acb6571568637c7e2ae928eb350c139964b15fb8c97763f187146f84c3f7777bde0b10a131e109d7000000000000000000000000000000000f9a03e55aa4c13bfede92948234a3eca2c34afb324ae206e861a4ed9183eb4656d3bac0738fa88e92b38805b2db45971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048399171ead1ac19314d19c79b08163cfa6fd4d2646f1f6b6309c0a797eee978cfca684e4f03ade78adcc35caec275400000000000000000000000000000000153c43bfa36675811e3e79a7d2e2e50cf5374442fefcabe0d2a51143dfcf25e80f134feb2bf91f43f8efba3f7a27b2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c34aed6c66ff21a6f2b545c3de17cbfc70e735165a0d825f7b602a3211098cfea1506be60fbcb19f3a0dcaa4c9cc70000000000000000000000000000000016d0369c42524833adc06b70290ac29a7f56a286b31a4840e63fa5092c36986adfdce20e917196a335ddef03bb73e6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d036afe4328082d9bec8fd8b054c0470ba3417c44fcec1feeb4801caaee02d81f046f7aeeed5d7be5585fe19eabcb340000000000000000000000000000000000d7dfaf9c0c6bc01d10e5f3e30e49b45e2b280114e3a9d39ce0d171ec3ce00adbe791612b7cf4d67986ad68f56512dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7cca7b0b6383ca093a5151c0e048571e0149a4008da9e6fa3b71ca749b5e44ebe97a69faf6bbb3a84a6cefa67f518c000000000000000000000000000000000a0c65e3a156733d3cc9a2586f54dce579a0ac73c5c16a67d4eea5445aa83834fae20b42fe5c891c6ecbe55f4ee873821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f1f8f5811d41b03f8a06cd5d6bce93242614d601f3c2ece3f22bb20cea0ee5a0898366397378f0d0b54b557591514f000000000000000000000000000000000d424094c655ea7970fab942016da2f9e047e2679cc6936e73c8a86b4ffc30230f3fb32aae79a1bc114ad42000c321d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001900a5f2de43b4cc8b8201b50d9fa206b783404d39a2f1c36d6af2fb7ae5414cd346670c19272a0224916694b4b888f00000000000000000000000000000000003ac2b79b2042e711fe81594337977fc6074cc6f5685a72c6ce496949ad0c082817e648612b6364c11fb303152ff58a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003651e0f56ea75e11994813b17a23048e773ade830712c88577ac74a121e5ec664e2f56ebeda1f755e5c5a71963983f90000000000000000000000000000000017d8e13e9142dd41152ffab4529da7b5dfed85f38986bf873c3e8179d502dfe2c9620f9e73cb431d55a765fdf8cb2b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bec94137f8719b3c416399afd0c9653deafe810320ab57028b10ed719da3d67c7df0328d74fb98aad7dbcd13f2ec570000000000000000000000000000000003dc3fca0ad4266d3822920ba8c346fe009bc4a70064915b262556522c87f26d6a37fc090199df998ffbe9e00567627e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056f399c990c96d08dd9d00e22d1ec868d16c936ebdadbb67b8e7ee358de148493907a94e1a5a31bcfc4103870482028000000000000000000000000000000000e63e9e609582da5ffd06d37586668968da7b0dd0bf7848caa0a67cdeccb691c3d65edc89afd0bf37e5c574d6836d4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1807bf3b94da647fde9a0b4759fae6665bc1746884e9f68233c0e0f31d0c39ac076192331073f972aea72fdba901a400000000000000000000000000000000056d4bfde8146bdbde9279634ca8fa92482df66b3ea777c0808829630d7b1de60a6feea742a3089e56f396dcae15a4e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185c6dda9ed0a2e9f838e31b049780dd63df502fbdf41411dc3f951d4d15351b431e25ba7b0bcc76e8d02d0e8f69689e000000000000000000000000000000000e5518ede62b48726205060429240c0826eddd1bf315da5304c9dfcee40b8165defcee41ef9dd90b35249c6a5b0495b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001819f8595014ac2fa5f432cc7ee167277d986745102826013f313cb105645c865dfed3bdad3fe2785c7a00d0b03302df0000000000000000000000000000000019d710c67b5c34b304799378e580b298d8ae1f02a9fbd10e3b94515ae79c1db838cb62881ab16f461b0da39dd18e74de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cda12a68ed37aea861402c59fc90b7bbb8a964427c1dc2835c640242c063eca7cf635502e055ec54dec19ba9920abd80000000000000000000000000000000002f294b0667da603e0b3b736bae541132abfaf1b1705350afeb029dc51ede721b2f7823e8d3db36b0a56e404c63b2c011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063b7af2ebbb584d8b4b60ba6a8048249d9871ba408f72e8518498ef73edd55f969455b05f92fbfffd6577cf439ad3280000000000000000000000000000000002c966b853839979b88f15feb7cedaac2390c3bae0a39847787a0f42cbdce964d91c1557c2800baababaf954192aa07a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c561c2be003cbc11b8520a06666b92d1b0b6dfcf345e7b39b070f6cff9044228d26cad64208687598e12863ca2b643000000000000000000000000000000000b874dfd4ac8b4891937af08b40366294c7d355195b5691161f3c3d62fe566baca7cdcdd57968b16f431c8492467ff321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee05d96f62d2aee89334a1b34328137996dfa45de4e943f76e9171df1235df49762db30564d905769cd0e22b54a86600000000000000000000000000000000010e562be0c84e350d26e66f345dd966c8c2d6f6f7fd734db1300fe4ff6e667f4617791c02d1d1bb2daed35070d33be451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a29f182fa2bd36611fb68bd0f2b70d7737ec2a9824d20d9b9490f014dc417a3395397bbfbb5bfb208bd12e958170e000000000000000000000000000000000cf54f216f008eadc244f014ef04d7746302b5fad839b86261d150bf5641ac14b199c74a6d24959d5f62abd1089abd5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b9cd0a0b151ea21dc9e1270ac0c681e56af2d30d15d90b972f9f6380639067a1ff2e1e4c5d0dc6a42f7eeb0b7e597e0000000000000000000000000000000008d342af211a3bef380c83331ea97ff5aa9ce1234b0be5b16aeacbd4aabcd10ce9fdd9f80a282fdb489c80da408c3bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f190f2bda94a6b5c15c4a3ece93205344c3dbf33e92bfb4964f756eaa54d6ea1354621a316c7937784b163df0a7a6f00000000000000000000000000000000101df29c0233f7d9211dba6282f2eb254ac00dc1af0471a7687ac624d4adb7fbef86f11692ca0bf67cf59a1be4788c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191db252588ead5df4cd5b2646e5daae4dcd9955de380cdedafd658b2fa260d7ec0c2cdd3c8d1f5ed33319a949f4d2a6000000000000000000000000000000001545e825b781dfbcafec2e606fca50bca1f65258fff0231957d3c1c70765897c52e43aa6df35da9027e1cb18c145e0ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b401659ae5fc4b8443333bd9bc6a15ca919719bfdf3ff772abaa1a75c88162ba36bc3a776fc20720b523e31dcd0fa2f00000000000000000000000000000000076b0c3d530b28840c031dd0f9b0c9d758e353d98fee65af13109dc8abd6b98c16748e27355414d8e2221b08c2cfc2c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000980e27cc723492a0cb9f871a6f16a00a8e93143eee8891a09c17b2b070d68e352ea4cf3716f8b4b72025df090ba2ed40000000000000000000000000000000019d11c5f76aba7fc44df427db11863175ae82527a5e3704de7c20d1d8b287b37153de26dedf1e5c3a8074f0adcdf5ea81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005918d0334bb27edb3cfafef03059447fc4fce694eddc5be492fd68c50a0c0766b4b1f51b2ba57980282017dcf70a0cb0000000000000000000000000000000000f158ad866fa02dbaa1bae3ec3b4cf857819782b872d946a4b682aba43571e5eeec92ce4dfc00e68bf14ef0bf8a35081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000363f25c0a2f7d5581e3524b0ec986356366edbe1707db75d7440d632f9d60fa729a403c8d5e37824089dd97a22b59670000000000000000000000000000000013545084d519c85660b424da44da32a93e9e53f510baaf8b4222be5fdd93f43945a8b0fc0e2b9d14420c4027a0c66a471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f8f2bf4fd29f67b9fdf848103370268df354a3d5f5291c203adb66a87ba8611dbf8dcc68a0ff4dc98f9f41e08e737f000000000000000000000000000000000a278629272492068abb084589298f2a8d2f48d71e524988e44c221990185c8e74e4ef01ee54237989e1add2f12fde5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6364a312abffef938b000a7bd403d74851d9c6b6646e69b3455e40e84d18b77d0fa14aa862b0977ffacf16d37c700100000000000000000000000000000000073d72568c833a1f8cfb0d5e22d98c3bc812b522761a055026148edffefe58558461e9b670f09f471d0d2846f496ba8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69a457e975f75b1bd3b29d1b5fe9c21eda14940da5be5b144df7798ac94a8173d830e80cdc52b8c5e9712160c047950000000000000000000000000000000018d377cfaea2aa32faf6a19794727f27c735f0026797c9a53797c4d42d3990a21a2427d5593eeeb1cb1720f28ce5c4311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000171576d9f87925451d578861acb515ef68e6b278f736687de653eb40c8150046a3572284b36aee38aa7f4c6bc81c1da0000000000000000000000000000000003f410b94592c4bf3839b2cfa9b0cffe8b6a0b37e2828945035c9a1e7b32f86a41d1eaa209d88182823727e05e49d4a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014fd5c48b41ab311b841b99fa2e29fabb6332db5112cc68be6bfb12d642d54a96c97243d57b2487d2ff79263006d1bd000000000000000000000000000000000c81eac9d2026118f35178703bc8886511953f7b86a7cc20d80a101b7124a471a36afc758cc6a04b75396e6a8b77f14f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b8469ba59e96ad7271c7f818318cc19d29dd255c7d38e94600c12cde76f6042ee1c2840ac9e6f14a8c32ccabd6777900000000000000000000000000000000116b1dc6de4923901f39be37ef5e92ecd635f3dfc97dbecfd22d0cb163b38b10c958520c2348bbcab676cc702416cfca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179b8e4171ceb15c935af42a3d9ef902bc3fae9aa1bda29a06b078ec14ebd9d3c779038a364a55c408188c90d1dcd38e000000000000000000000000000000000857e2935fdba45e5a64f0a5a592a49d3d5ccdcfe2116d2d13da31ea575f1c5ad1fc5b8aead349c0f3f737ff3842511d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e7dd6b05eabd1163be3bc19aa7e67dcde09032140e0ed42cf02010593d1463b68f312e7b1c78dc056b2bbf3601495b00000000000000000000000000000000056c7c750e03c352db94704757f57d265cb40cd95309509f4219e47820d092683875ef06d8288bc2b7274b355ef3ab101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a79c8a1e3e0112d8997ac0b8960ba062e3e6a66be2803e61f2fc88ac5d047ab9d68047dd1f99e8602b016cdcacd417000000000000000000000000000000000630c33856c1decb5f6c889c6477b11cf1feb65658cd1eb5b27c5cd41ccb3d340f8669e1f9cd17bb199127656aa6c9031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019694326d17f2a6eb476f1b149e8538669e6637879279d8f7aca01b6779803aa352beae9840394bc67cfc88e3cbc89200000000000000000000000000000000000e93267e08e2e88c4ada1338abc3f842f9534cbb4a663ce1902d96efe29ab00d6898ce4d7f519dfff23a8c10e54de581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008657511487a4cf3041737cbca8a9a57b9edecc93507d46a22cfb331676f9ef251987127541e40a9cce74c64700b262a000000000000000000000000000000000ec6c0853700af75c3b7a0ae0a9ebc2ce9f5272bb7f5a3d1fb2041a3ceeca5bfe38c0ac7852b8ad69722c437e01ee7981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f3afd8fa9d42dbe9d558d4373c1e04c2967484284b6ef07687902a46dadd4198b2f717888ce99077b2fb2bcb4b783d0000000000000000000000000000000019f949613852652d818bdd3808a4a16d4e8822ab5c34e7283ada7bfac3fddbe999621300fd9b265d4c5e7ffccf6c55db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bcac738fc5b334a4b1a02847cb62359e4b7bd5a59d937e7bd5994a6bababfcadb1d0ee1bcdd1275aa8d26ae2d52bad0000000000000000000000000000000004a842961be097c91a43449b5b231773b5d8b20a4a0512f1d7ec95136b5be65a6ae42e82cc20e8f13960d1cb6c260afa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f3a17da3574b5e88d5a0e01297bd652ed5062651bf099e064ed85b0bfa57737bb07c849a28353352f7a94fba8ee9a0000000000000000000000000000000000ea014804648e24649be2469cfa23d67eb7df8c40893ed6d37d72ec55a6ca095fb50554f7c8fbc7b951fd9c968ff43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a098c4b5ece79b419d731e75f1ff731d20e0a63fede245fadeca480fdba01835d274a2df2992377ea1d9494237855a0000000000000000000000000000000016b0bc022d582b54a7dfed8e48aa9c8aed703c923838225eabf369ea21103a2cb7497c1c8d149e04077955693347caf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195b409e64a2d6d7685eb3c2b82a577b4d0276198ade23e0f9e605d332b5ddcaff7010648ce7b3b0595c1c717ebbb7f3000000000000000000000000000000000bc7bddd61540c1638b1cc2ed60a0f7b51f35223d7a43f63444a223ff46b1214d89dd05f6debab6ed163ee1a66a4d8561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131604e4c1045f77bf80efc9f3ef72c0577152d3e4f4662c35ad77e4e3fe5387a69ded7b91d6fe3390c6cf9a3e97a85b000000000000000000000000000000000543980a1d8f4149ae53e48f13cf045e066541cf5ff42b2fdcfab6177578601bd15c86a5ce16b094fcddbfb1037234bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fb5d57256bf951f342f9b337f2952a296c8f4a83530b20ffb8cefece7f45363c1369dcf60f7e34be340423e3a61b5a00000000000000000000000000000000055ecd76563d776357459b8b7cc42c2983884167ab5a2a9281c6ea11461256b69e185769ebbdf1e2ad766e548573046c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f0329a4f25683820b186232205fdea4d9ac16d77ae368d072eeea82e4f6828439f8a92a370b09a4270510fccafd15e000000000000000000000000000000000202f99e5a16ae529ca5ff8fa65a1ddb0931821f1d50883d74310883b1b9a27af355d706224424572980e9f4883d789c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4c65abf1b8ab82beb2a1b8a298343abec58b55235bfd4b39e11a0f728ccc30bf846abae02c6ccb95d6420a4015ace0000000000000000000000000000000019311125a2d8c93a227e1cf56ec5288b91415c29aa4efd12b7763a2e5e9ff8a2ca0c541571dc9daed160275abf2b8dc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064463ef8ef4f64b92eb8ee5d7c9c560754ea4ef556c5b951e47536a584ec8ecd2cc46606d87074ea1f9e5afe061a78000000000000000000000000000000000194a0e950bf91cff8b41d852cf317d30a1ab70160f00344d7e700c0c6d6f2639f57a7572ef4e5b5ea7e65519eea3db4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eda2e5b923c29289c29b2e681d05494a4ecfd2cb7093af1e2debb7cbe3aa861b4c436699d7b5fab37fc5c34280abdc0000000000000000000000000000000009587f4a79e11f884613aabb07268769c69bc4dd6dd18021ca8b5e25ca329a401de201ef9b78ff1ae7087b15a662b6801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178d9024675adb6cc1379ef82dd41e29df4367e736c33f1ce2cb7d3586d2a07908ac5737915b583366029e512dc4b58d0000000000000000000000000000000004fefa28e42827e878a6bf9d455c30f9d53f7dbdf817130dd0b979c01600750e9a9708b4791441ad7127c164a55d39d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e9836a751cb070efdd4a7bd2b79ef9b0b2d5ab0a5ce382e12ba9942d640d10453da32916e7458572cdbfb36931a3d700000000000000000000000000000000023a05f1827a52fb8e3c97dea77034d347a02a1aa6db8e5cdb155f7ba479c5844abd957084d804b50440883a7f395bbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004162dbb0cd49fe5019df6f10a8bfbcb322c8ee62a8eaddc88700f3aba103a1668438c50969dcd37fbeecc20033d48d6000000000000000000000000000000000b06ca15f0b1e829551bb2b9b652ce329a36943d5c5b1e0106b6eb3eac3878a53bc079bfab10ffecfa5a4df2b15096501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb7abe42ce13ab545549c2da5ef63db56b5cf549bf6064966c0db4d4e29519ede65c0b069c0f2549e73302e7cd4ff30000000000000000000000000000000011034e41720620f5161c3b97a3e274b0abf6bf7ca5885afa888ccf4627682274d701497b331f9464673cbde9fc0be50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a330cea940e8ba220a3575594f30caf80fca7ad9131a1b3a26318303fcdfde8d1eff41f9d515855a2a7d1eae18dccd4000000000000000000000000000000000e460c3e6aec2e17d7c326bec9ab97b59268f026f661982383cea9264a379131ea2b7c2979c3672d4990a052b72922191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0f2b0634afa168b9c1987009b6259ca6db6d7b198d52642bb5719fe27607b9e8be25b9ec0669e408e974425c79548c000000000000000000000000000000000c7deba9620f7d7688d42e11a5baac5819ba6988b77b5aff8f1c205013361a6157205d31156ee7a3c888a04ddfbd32151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d80cbc692428005beb46c71f512f258eec2ef851d74949bac0c59085544e96c7f2237785b03555ed9711cad339b4590000000000000000000000000000000006f0aa0e4ab492d5adf5f7df57c33651411a9184d340c9f99f70238e86d2086f3cc64bb05e7f0bba5d17d0bed2feb5a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bebb7142be81af4b3ab2147ddba342cffd8fd9d5ed3417fcebd635ec706f89bb2b720fd94e9cbdc57975f1325b2a4b00000000000000000000000000000000030bc47a8cba434fb7df01f928a89b1b6bc37f329f43134dcbcaecf2c801b0c4dcff997e2bb5091f8642036e67f9175b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052a0df3a550bc012152186454f7d2e1baece4d3e52518c3549987178658b391d2c849beba1b38c59f7a5a1ca2f8b2a200000000000000000000000000000000130bbd95c39843d155fc1b9b5b9550c9d4ad367294267ede51fd1e7392d55484fec319922247a7d0cd043908a3574dc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b77256bab416dfe1ec204ad1aaf25740da6bf3a373c68216867d66b013aa25eb18dd5d6fca3304b1f66410b602ad2fe00000000000000000000000000000000021c5e26af09f33d971b0d6d845c348976b4bb47a1911ed8221e4a4fc1324d399222130a340fb79b472277159cf1ccab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eabd4d76d709b44b76d62f627b895f5d68b2ad9d13dba3737f317005cf805714662bb25041a9cdea7e912fa647c925000000000000000000000000000000000862b0ad9a9625836199133846b76b397220fc938e17cbdf0fdd3bccdc7889efd402d8e75c0e093102c349d65804ebb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec5e4b27246412b028b09f9644c6bdfafcdfad163465dd8e3dd9f7de1fc9b668583dd2e147ec61a1eeb707188ffbe20000000000000000000000000000000005f3b1e0ad454df724016f3c94c3cb360aebd774c203ca4720ea541e5383867e875a5810d9dba61650eb1ebe8659d9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f061a77f054b019cd2acfc1e0bdc86fc8ae2717ba1d134cd241fcc5c338726435ec576265e6559887bf7c6d1eda248100000000000000000000000000000000165b133416309552da35464108119e75c005a9f1ccc23b03f5d42e5bf5c0fa98f98bfb9ff85101854f4d96dad7c9f5b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145bbcc8efb04c44ac83a087353d1d231e831bbe22c097e0cf0b9dba35b374570825f6f21915a85b5428f19cd55ae1b000000000000000000000000000000001495df4ee901ce0fa2a23ea7bda5889cd069f88c1ac888beae4f502b664e95563d2cd4ff9682a25189ef60fe3ca626531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b7c2f786f69e62485a70dd9d2ecbcec0be6ec0cac5e6e8c50995c0995793077118aecdb547dce1c190dab0e9f8e63c0000000000000000000000000000000017fecf7e1b34a13c204e419de810acae98de49680f572645307790bfb7d63619ccf8ae2004d6fd517aa2dc17edf03ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042e6e6e05463dcbf912b50de03142d55a08194938995d372d201aa34aef1f62ce875f619bde166a60431e518a7a571d000000000000000000000000000000000cd0c8d95c9370dc2f96ed46d3c8ef6416765eff945011a1c41cc4fcdf7fd14282781cc6179ec53dac71be931002b7cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148d585a223eef942d3c04217c8d7c428a7f770140f6e07613a1f2037790d8214379529ecc66ac89174f6b0bc2603070000000000000000000000000000000000e4349031f08084877d0ffffcf899290a522d4f19cca8cd9268806a6bac02b22fdcdc1882757b7bde1cefb3272ef86fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131944931ce981493eb9182cedbcb6b236a48a4c5d57e43acf5ce23b2ec43efb6b2990a7f792c1a47fdf5361c0228e500000000000000000000000000000000018cdc34647824decdef26a24c5558e83e0690bb29cc30cb3a3fe055a2df57576700f1a8ffbb5048822067262a42e92841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173379f32053b6f82df42f14552c91ee2d07950d32771a493a39b1cb31fa613c6456fb3747f0cd3b883f5679faadd05e00000000000000000000000000000000012e04f47a65a2091623b88df8feeaf6f4e7331432f85e0dbb451a86cb4a9dcb2eec0891c96cd19bdd0216275f6226dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe3c14cfec078808200cb147daf49d2eb913bfc0f827c8532f48a61e80f78ec762a03ad951107e28cda132252c976e70000000000000000000000000000000018ac56a7af42554bf080dc608754cc3da106be3bf3e0468a01315892c5337a2103a0dac37d38ca71a4bdb50f6cd9f75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bed8ca2baa5965cc05abd385a2ff2fa5760c327554c3f0826f8d3643427e74484f08dafe4b643d03f602a173e5f9bcb000000000000000000000000000000000ebb6e541bf97c37a5f7783731fd4fde514a501738aa5b5ae8829fbae5bf63f862558e541d0e64f2f8935512f056e67e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036872cd30e6bf3730b4122351c9afe60ab0938e0406a1c35a89d62c20df3496cea52908a5e2896f127ecc3ed9b4804000000000000000000000000000000000180bbc580508fd8e1b682d39194e9cca4d76988942691376963a8a207424b6e0efb585967192ef84f127fbeead7b32071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149b2dcd4d75b6b568462bc672269b4d5f7d2bdf61416fec260eeaa76ef318201c6a0e4d474926c7317261a8c92b30e4000000000000000000000000000000000b0cd3ac3704347979706d288db0de75a7b0ad4bbc7ff0314a2774094331b9bd92bb3ed8b1c27497d53e8741296676781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062a7722ef1d30507e1d80d6e84367ff79caccfe47267fcbabf5191ab94ddc49577fc3807c27057ab547b13a8c5b78480000000000000000000000000000000016236da7a03d3986a8fb9526e9c45b386413d58fc2f9392b1b318c87ad104b345cbfce84ee1e06b7498c747658cd78901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0e4833cd2e31ed370d4b3aa2e7f6e71bc5349be6eda14e979d24affa79d0ff62aa7c3ffa442cf3417a400b9c6ee3ff0000000000000000000000000000000017c438d862e1bc0f3d9f309eb975bb09620802b33584b1a45b23558d6e68d0a695d7ba7191acf8d20c3bdf05d905b57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d12f5dedd3f67b887651ee178d59e4ab01b8f403d69ad25e6a5b581ab1f1b67212aa92aa143a10e5fce008d22a2c10a000000000000000000000000000000000e44700f0c164836e796fa4c15a5929ee4b2937a4583ecfa662bff008f446c473d45be3bd978e4b50f411e64786df6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c9e7e3cf906cc0ff2c52d5bff4d7f7be1dccc0c6924db53fe9c2a8bdc46bfbdf11b8a440aefaa3bf095eb6303e313c000000000000000000000000000000000e8c7e38fafb79dfe6d8780294a59b71e77989fc899517ace11bd45b50b12dbe470328189efd2ef5a92eb2779b636b551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bacca1d023bac30aaeda08c53f5379946ae67416838083cea9aa7e005ee4b4b829b86d9786aa392e6a32bbaef151a50000000000000000000000000000000011923f683222e4fddc50eb4219cfc7c25b93c8a23c4f480671b79f2f926c173909d7eaa579ce312d3fccdeb1008577851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1f4eef07aa208821b5e922cef7768d79d37c0e75250ac311b64b457b6c7ec03683b676f16af045fa35d45a31ce7c7f0000000000000000000000000000000006f7dad7515720433a7233e5499b2de028b1d84aacf5e9b026177a95e1c52658aae04a1957deca4eb1c9171d9ff7d0ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191d16fa600f91b3ca6317704e25d0d2cc1f2b207beb8e1e98ca281375fe2d23849e0c05a7a55ab1ce1461c74f1db08a0000000000000000000000000000000011bf998911c5c3f5ce74ca85fc7ff7d012961cef894b0fc24232994ef91decb4e0135707fd4c94aa39787f0d98e7f1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124e15e1fbdd7ad699793f6b63d533d22599546348e34bf81149613479783206c9ff793a050042870e33233cc00b3bc5000000000000000000000000000000000b8e75ace9bfa5cc531e094fca551af997ae28446b3eaf7c84ac45010c85b79a2c3b887813c2eac646ad194932cf43201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc8449120f0230d9b2460834318ccc967d9707660df7931d69ac7c8251b12ac8bceba6a88fa5098032a2838f892e100000000000000000000000000000000014d803bfd175a0b64c7109d31c50eaa71e5463fbd5925c98b1b3ca45fba9bfac8760ffcf6f0620591c3293cd76a6e2c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ccd8c5f558cebb35cb12a8cf3149cd242a1202db8bfb0e3123545f1910ad9ad6ed1496c191a65cb14bc79fe49b7e8200000000000000000000000000000000005d355167c3e64ee161d95cb9c9f86c1b2d13c26576cb8592593ddd6b3d883d4b54affad00a8aa4502a5fbbdd9d44641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ca6ec18b536c1a0fa7bb2d6f7e13df668fb7b8ac3a7f44ec5895e2edc243f525faded7ce6eca8b24283617def845090000000000000000000000000000000006123df662a4abaa8d519b3b00dabdc0136ad6e096205f751fd5314e15e45f5221266070eb7e23a08d4f7416f20cce601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173e440d00f0db24e17de1ed832f99bef7f3e87dc4d62bf54bf2d7a6fb358a98d21ce9a6889caffd8c8c1efe6716bc8900000000000000000000000000000000030b0d475a7371bf619bf330d7ffc46fc8d81213ce04cea7b8110672bbd602baf641c570e52d85f35e1cb3ca68d487ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c36b6258f0b6044628aef4cbe97866c560218667a87f0278e02088b253b9174fa22ea325815bfe577b8a444f4ec9e3d0000000000000000000000000000000006409da464b9fa3a38827b3747f8d3d148c896a87b2ce397748a6096445633f09cacb978b86e074fc0eb016493d5834e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014125f783d1db6c640b0acb1144ffcde173ab1bdf3f23fe57967825487880c7dbfabdd7ef85541ec697dfaf20a91153000000000000000000000000000000000bada14d3640b8d3d16ab8d1a5ed6f52bd25d8a8ad243d962e4503b724ab192f0e0c8a7bce9b8b00d6f7d3c3167d65431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017149af6dca0caee7b1247bceddf5ba0de7f00995f91f89e95f7157b7eb6e9e7ff5e87922deb4693b4631dce6386da38000000000000000000000000000000000639c4cae1d1b7d539b662726ddbe68857349557a0b19aa63557ede2981f8bb0c69aeec7dd865b341cde2aff2bd212b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bc5a31331c53367cb4a8c0e993870987025866f5ccc59fe2bf8e90345c58d34e20b878530495029e9a0956bfcb007600000000000000000000000000000000043e5e7e46b11490ccc19a684a80b0b63841fe6b021beaff27c9a1cd21e3a3c0f7d16941e424e6c55f57ba258ed019fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077118b0b0a0e2c69af151c07e0f213da00a2d74fd8c5266eb2db0e8f959e04ca5f0998eaeff7b54f7cb467b462de91a00000000000000000000000000000000066ef94ec705e24c05f666d4aebc17200f78f835f4af1acfe3a5e91cfb03b921fa637def74b000878846798be51363271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101457ace090cdb1b31c9d496fc2abd726f46d1160673468e0b2abbbd6b8468c4eef46997b8453ad93ce4be61ecdcb320000000000000000000000000000000019456add3b9277da8250ccb29f48fe897c8f72df826fdb5568633b7ac0035a50c6e70e7e1b212cadbf39e156b57467611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054183fd4866f8958762e142f539f60f5706072d60574cf669542cbbb9455858b9d62e2d426ff5c8643f835dfd765fe50000000000000000000000000000000004898ca36cf395d9097a082722e81d09987abfe1af50042f516c7d32c7af849e984043d80e9b3ed0be15d91af242ec5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010e1e77284313aace464b4113a76ff4d831da44e921d07a13f8d721fd05cbf489e75e0fe7b0c8fbc41ce499559dc48c000000000000000000000000000000000870c5f40db041e511ba8dc46b8ade76950622fbf6399c254792bdf9edbc60db37cf10e7700ca0578d216a68b9f03e541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000801ba58a8b7a5962fbdb3d38f27aaacdd3f7896f34ff01a64a31c38c8a502f3a145457f3f631a0b7bc938c56f544e38000000000000000000000000000000000ce2c50bb97d64228298bec9d89bd5c82dc449f47e6523250ddb733cfcbe1c9c98e3e5fa359fd58ae030dfbd2262d9231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155e278b2fd203fa2d4cb7a5e6670b2b8ea005b535d77f40c6385d2e191fc01bebb43ac440efb31e3d90422c5abf954a00000000000000000000000000000000124f53f7647e1332bf909467c9108aea7216cb16f41cbe15523450763c78c86d910ccbdd86bbf8d044c7625fa765a9d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e9dff6a35c2bc0ca687b1ffac9d5c93231ec206237217a5805acb9df09b1a6b8182f4ed9621df701af72792da6bae10000000000000000000000000000000001158134b150f0fba045e548c77ae725782ba763baa2001d98276d9ed1b68edb4361a743d549c7b35520bd7711c6952d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb1e3abb946d1e5ec9aa145361ac84fa9aa548f0740a5b812ce97d38f47e067e5dc8493bab6f37f6f562bb0ed01ac640000000000000000000000000000000001d93268d611f9658f101c1087b77bfc95b758632a6b01d9b8882e2d65c056ed5e53350f7afa3bdeab9a7eadf0ef22c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068ac72074450e256d551fc7f224bc2f1a82f35ce9834f41f44b561dd187f7eeb63a4849c2096d9aa08d99190b3bb73600000000000000000000000000000000188f0a026c88c0a427737d452bee229b4f6d1fc83efe9dee0592504eb4fac80d325da097e4aedf60648c7e9e294b78761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001799070dcd77e2133bca4e3905d4a9eb5373d189447b5622bcd912324c084ae08994d87c5b88680a9c148edab6858a8e00000000000000000000000000000000177ad7211b87d01918c73cf3ce22e67b1452f2871bacbc9df8c91bcf6166fd6d4ef7bef6d4b414ab22524a325321a0951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009518bc29b9c1555dd6a453ee98fc077a433de1fb02cbaefe656d5217aba8bcf413078f9ceacd526bb2d6c22ce6ef906000000000000000000000000000000000aec729a9765cf09d5316676fa593c9ce6c636e64dd9bddceb22f1f30526804ab901808a936d904dce969eb490b0d16e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000724ab07102a6d42cc167f26e34044529b3bab769e175606f082d9320938dbfd4e7af54ffb43d99421bf8e829dce0b94000000000000000000000000000000000599b1179ed5b40a164e5253096781f93d3c001e42b2e2f24a59e543bb6030bbc1e4c0cdc8978b1ebcca119aab6f98ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013755fb6dfbf3d53eac9014904ad0a86114a1a6a52c565ad341f57fd9b697e5ee9f259b771cea32a0aecc915f102f98e0000000000000000000000000000000004a38a3070da57b8afe93397a2895a104cc0257141ff2253067f20e550a6cc150923e0b3565bd73c0927632b5a00804e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119074e161f944b8de7584fb5e94e4608ec2d5afb161f87bdd588667047333494d37996a0e039b4ad61c89495b253c2400000000000000000000000000000000036d7895561a20e465e3e3b818f486450478c219d8e6aeaa2541837dd95cd168aedbb12dbf39b964d29ec0ff456344891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003486e9abffafbf258154960a841329a943bb2e4f67b2e24a787eb837b051c18ac14da2b57f41a321d63904f69ac11fe0000000000000000000000000000000009c8d96ae369c24d8abc1e8e52659008165a106a0b1716a11ac60f2b232db48d79c4aeb9954bf93455e1cf6bb79181541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001772cc685312a4fb2b563e7d688d95398526a4ee0e6a226c3feedd9f511e5c0887efe1298c47d1cafc4f3733bffe79a2000000000000000000000000000000001948f103021964150c1efc1993482c7ee68bd5880997e0d1822e535dbe6efd9fb611e2fd7e85847bf2b6a61d8eb2fc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000345c14c0f34092275cec8962bcfcfd54778ef6d982c6250f1bc29776cf25fcd4b7f34ee53567e597408a6ad06a08df90000000000000000000000000000000019302fd67d63b19f836e704feaf5582e7adcc2b07f87fd2b5e2f7fb26efec4023cf01e794b41302d98a7ae34157c38c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b75d93b7b637577c1d613e045ed26f923c552a1d63223009c6c11b2bd9aff6772d44c8eeb7acf52bdc0d6b9874b81e0000000000000000000000000000000019f32fc0a501038bc4a0a1aed222aec1e5d3dc965a50179495a6364c29637649c3f56148d65148928f1e0a44cc8ee54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cadf27e69da3988ffb8d18761f7de9bcd466334b92b1c2ce8e8331ac25d7ebc368795e9af09dd713c4e7167ab8c810000000000000000000000000000000004001ac4535c9a49c0c685d0206e80927c56aec9ac4d5e6a05188765b94c9b7410b0cba02cd78b56c102c4b4de7a965e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cc99c8391deaf90fdd471bcb765a0a96c014902931f184a2a6e51f160f5ef7ca45215b50eedd9ccf141f9043cbe7b500000000000000000000000000000000103aa3681fe016866872bdbb6d68dafc88629aa57c7882809f34af0490accea82aff0e42e4d545bb908b72c19314ee751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019755fb221e74da759ea37d11bc18c620e84c00bc3640b735c82a936648484bb12f669c24fe97a057f6b65018d7934cd000000000000000000000000000000000ae45ebebfb387bf02a618581baf7167e93b20749c52956e02a01e2c985d1d633f79aa4fdd164cd4bf9ee0f75f3583371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2082ae75b670e20751b2ae3d8c07a5d5ec457fc66b382cae4f0a0872d28684dab8da7e9aa7460446f74de5df28618a0000000000000000000000000000000017c5e4f3dd572c6d29af9b903a2902af5d783512f18703b5489266a858e2f43d7b92251683029d2e08f99f2eed7d172f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a26baae206d7a96c508378792fce2b5092e93cf091d056cdff7615efa8dfe78479603460815173876166182beddc610000000000000000000000000000000018420f5c583ee7df775c33a5633c5ee166649dd0ea3a47bec20155df7526a1a8896d135c7f25c09350c25e0a8d3539b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b6864da0f142384f1dbc0fdec037258911bc60ef38e3236bc9ded27c26d81ac6cd6318d1740815262f9abd84ae13740000000000000000000000000000000013bb2161e04338d7f62ca1135a7a449152f595ac20eeb5eeb2ab5c8bfa1e978ea762272b10252db3b9b9537088ae9b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000313d3e5752444afdc4f85d55b0045848d5e5dd06f20f2ed722b9f31b26a0b671e15c0954307c88a9150ff56839b5ae0000000000000000000000000000000006b9bf6d6c3b961ec2f089db75404272dc47f4d58aba2e3ea99a0500819a22fe062749ac8eacdd1f551cc27ea5c32df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d63e7b99854c7518c607ca8979f7f3bdd65a2d29ba7559425a0e89b9541b5b120aac109314c4730fe2c4dd0a7cc76b0000000000000000000000000000000002d990913bea08b6c18a91aac227cdaf3b226eab83f32fcd344a7d78dc28618b02062c982a3f5cc9d91516465a4029541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507f2acc08671cbf3ff04a73e5058b8fb4ac88115835adc57c2940a5d5f74e18c8081ca2973da6cbccd0fbaad0a39720000000000000000000000000000000013168837b1c77236150f8d210ab94ce331b199dd53de7e42cb55fb7615b4255dd626efb8b6b028dedbc987beda252c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147067371c214b98b6c0baea2234205be8dc11d148689e7807a07def24e2ad0d81a761354834ae526f4ec3e354ff46040000000000000000000000000000000010628ef5d71baf6b7c220ac605a567cad025c0a5fe13d1fe25530ac1b1b0a65d2ad57b5746c8f799473183c2294e027f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed037e4cceb9efcea31537ddbd9d2be7ffb9059217d52a40a87b8eb26dac6f05e45fe9deccaf8d05b4b36a2a3874cd8000000000000000000000000000000000cc732bcdc9dc08fd6aeace39e623e0a9a503ad82d5b0d7ab5a78a34383f7edc5a585138bd278fe5465724b2445a87dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d7c65c7cce5efc4453b6fefbe9d735782117b125f579a65b25dc429ebd9baed44be6d99cf8e2abe94557ac2e3993c00000000000000000000000000000000164354e3b077b0f9c14d6c7c7a84db94615e434b807011e2f215ad65aa85777b9b9892e7f2a3b8ce7e203ea665ce46251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1217e68baf9c77132fde06d3092fe9da378a40885deb0bafc5600cd11092f1978588119d668e14edbe8f0fbe83b599000000000000000000000000000000000948af0118880d8dae794692cb2b386dc3828564b31f1a2407af48fe4c197159dac5b7dea5568915599b716a06764d5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007772545d564c170890f853eb935f873b7de123edcbb07d2bb3b21dd2a59dc1e7a63574ad560ea5cf4bb529f939ba7fd00000000000000000000000000000000132ae7de1b7abfd605e9df2c8522e18ee342257c44a0f0437f8def12f41fab19eb45359f4deb669f2813a53c75997e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b108b091329878fa269e112edb919ca0e49e35f2a4ccf17cfa3b236d44edb34f38d2fce1cf0d5b164c926de74d48930000000000000000000000000000000001350c7d259f785468b05fc689bd515f98cd7c4c80df214276fc01152a617ce0a5e5e1947ed2b9c6f7cc0fe4b70db7c0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067797f0faec22dda3ded692a3122008d83d806f3e62e181322f35694a70915d7b9974b836f4961b257300f862a804a800000000000000000000000000000000134aa4f2dd4c0ee1f20d4c51e4d8a95cd241e9214b55d3dd22db840b603c8e03ea92771f0a6dd31973386e781bf9bf111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047a579690bf2cff3a32cd5df28a1222fd38e32217f96b29ea2cdc172581b6ca613db553aa685c68d253fc3c987164630000000000000000000000000000000007c3e58e4de4d4786f29709fed5b33f03d9a92d067bd62ea56aa0a18f184665b7c22140c225200864bd105f82c5e23ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186e195da6d8da3b4ba93bb115de35f83c59078ce2e0121d0316052b923b16b41b3517ddd1a039b03a5db1ad5e1f590e00000000000000000000000000000000047eb890f2919ac0f894718a1f55e11fb8dc1ca0f6065e71574b00a1c5520e91143354820b393543f97d4d0524bbc1ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d07d2db3374ab1203ad9565248f9cdac1552b86c8ea325dd1532c31b21d19dba4d2437847ebe020fd72125e89016f000000000000000000000000000000000ab09e925d1b1895fd10a14a9ef322deab88f4ce9029e129fc278ef77c87be6646bb02cbf8609be21ac96a4e07309ae71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000996850ef0c1843cf24dad6363856cb70b81b5e974d62c64ecd3c6f3b3bb16fc8fa93a9193243a99f1e99a3c66fc4397000000000000000000000000000000000c9938109950f4e4011bcd5d3a57da43ba5aa1ca967ac2b3bb97eaa71e611a7ebc22db32e5a51b3c5c89bd73f8b990f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecdb77dce577ab9b2a7e609b7e5c1dafff253ade5721cee1c6bdb04abb2fc184c67dad90fa088c7c8989cd7780fced0000000000000000000000000000000019ad26889948220d2d8d34c852c81dfbd3c71c8b9b77e8103d048f8fb8a104b5659c77befc0ec07ac2a26c200b09244c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000869a8f614c3ade83b0af764d7d2430f5d9bd01a3b84d0050d9b4e7d458b4517c5cef7e96b339ee749375bafecdbdce7000000000000000000000000000000001940807fe28050ff5c7e8b4eb0fd1a87afc1d40b7f881700c0f0e7e79547939ff643ea5d0045a68d4bc0b53063f7e1f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7cf2bbfd6c2073089616a75c59df78d38fdab556e46f6f083e6422f783c5de02b4ec1f4edb8bd6b4621b37b61c46a3000000000000000000000000000000000eca616275b579b77074a4437758ac72e273026518a5ed8f40504bee9acab4913e4db7dccae17931851501d1cb4529001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001135d2888790fa5f65ee520a76c03f019a35044c4d11f25a1af647230f47d0591d3fe21875aa18d993ef271d59f58ea400000000000000000000000000000000024e534d655868c137a700ae673d4d5e70e4de6813ffebaaf071547aaa97e215ac6d91b252dfa30895af12159ae7cc541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731e1d5e13101864ef558ce08197a2967f837da91e1dc92bb55b0ef3054f2ac8f618006350a58bcd6bcd53ed5effd09000000000000000000000000000000000133a95b9eb4429e3ccf7f46acdee581e170df6dbb9de9dc0c4eb2bfcd297a11bb06b2fa158332e9ac82bcdec75057941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16dbb611322215c8eb08bbf7dec61b584209ddb1739050bd18dfc1df35592df956ca3badfe09fac6110f56dd9535ff00000000000000000000000000000000116ee78b4223868a8959fb711d543d4a3a4a71de196cd1ed276ee58ee86f9f0582178c51075b8f56e243c707aee84a001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c100ec958757aaa9441ea5a3f715e5249c93d63e2bebfa5f7dd2622a0884ee6fe6d164fca7a2b80e8627477432e2a10000000000000000000000000000000001f07661572e57d3e17b528ab7afdb0c8318010bcb6e1fd19848de362e71ca448beb6d32ac8a1bdd2870df6d4f3353491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018205e3bbe3e92caa3972de12e92b86f11f1ebd46f51e318fb63bccf25767288b074b3e4c3f71fdccec386b7f2da0436000000000000000000000000000000000f8ebf3f886b2eb11707bf154a787a7423c368f7d2aa62f5950a8f80dd83ca96c8be8db82de8fc3ed1a65ba1e939efb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000285137a9709f40bab114f5efd2af714d10c5f7d7299c9966f18e5dbcea65b696a7c2b43810a4a8aa5d70a4784aa81e8000000000000000000000000000000000ac3ed78ed88fe0c1cb6905957d1ac95434cea03adc2f532dac16574b7d070c58535362edd50a0092842c59576c169601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001970ad0086a67e4fa67800be0837f64e4c45a2e292ae02208886b5955a30ddeba56fb5d4bf0f21dad884749fe3269c58000000000000000000000000000000000bf4c81f8692c50308705cff255c889198798d504bf4b5889b5fd98f63fefb5233c604dc8d8960435810598f0da667351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc2811da1fe524a25a154005dfa97a47c299ce9e1e2da4c93d4291d98928446e0ce5996a8244048964ccdcd9bdddc5900000000000000000000000000000000128cc484de090f0f921bea4889ac6e02565088e6ed12f4c36eafc6c57d2ab1166290bb3dcce726d95175d7fc2e5df48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0f2d123755bb73c00639c70385dbc989df17586c35eb2bde85341ea6afdcfa17727e16979e5478604e99bf7657a35400000000000000000000000000000000018fc90c0579347ef3238182c74dce4c4c87f370bf97df4a91085141e6b8b3d71965c1cca523dde99a282e7c5dbcf6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000054397ed4ea06f7d9cf5581f9488d3f96a477465e65b726f712f024757c1a7d3d297da93e56d6d21c8b600a623cfcd70000000000000000000000000000000018577aa55c945548496558e25b988465d7d9c92e97541234eca8787da4ad4d061978c27e9938585f373ac6ca39eeb5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000620f809bff2858a302347e93055e9d41b53547d82495de4b9206bc7acfaba1397104a8a44711c5adc548738fd6075d10000000000000000000000000000000012aa46732b82804d324ba18c37772cc40b60640e07ea063ee2679c2456836d344efbb57bab86f434bee0b7432d9fe2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190beb7d10b1460237cf097c823e14c0af827c385847cdf52ba44951e03ef82125b6e0841c1b07e10a3191b0e3841fd700000000000000000000000000000000111c682286a2146ae42b4b12a9ec2a7cfda346fc76d873310bdbca70a9645157eabd8fee7860b773e888b8d991fb94f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001201c17d111f7970ca13117b84e1b8128271847db6b361fa8e1c686d0aa29383a58828fb96ba8a553027edcdca3a899300000000000000000000000000000000157243b0ae6561fd2ee45cb8075e92ddc83430e2d9d643965c8db52341e3c3e8bb9db4fbef599a4f694a1690a1b8a6761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209e385b8a9c8c7472cb9ab0c65a8248bfa0b69d574a22dfb1debe6ed61d6ba911d4602e8a2d80b78860aca5214ec7a000000000000000000000000000000000fc610f79469f54517b5f03327ba6c04f6dc44fabc3b65f5459b62899474004547a2bf22856cb14b606187460cf542d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c0c5278b1f95283722bfa78b14d30b7b81b3e3c3b5ae6fb512fe5eb4072c0f28558b84e2dda700328a2630b23657460000000000000000000000000000000016c6cb3012ae7f8537d02690ccc92730854c5bce7c1e7189bb285430537908e1489473c1e6f5baa99bcdc8f9a16fe5c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017948edd4f8bf62cfd7a7d8d129a85f26d1dca54ff5780f6df9abf0968d82dedc23e570aeef749624a4fb28b2e5b8ffa0000000000000000000000000000000014117623e92c4a0311ef365a38f19896525a939fff48703a3baa13e241f3a595faa267dfaff29af0456f16540859bcd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625a3ac1862a0196ab6fc140e1a61eebeaa073c8580e78ae14079924579171c711a5375d9f8f1765116d5c25807ef62000000000000000000000000000000000a86a33a35c81e2f799c1b47438a1e03a72d099c5dea53389c6c4f33eecf02bf5f6a944f0b1d6e28fd315dee9eca08f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185188627407c10e12ccbd1d6ae90e64260a424e26969c07dc22e6272d96a437cf27ec989909e69309eaf5d7649ef0f5000000000000000000000000000000000dfdc31a362aca57db0e07596b19a3745312a2bd1290af819500669658334b7dee36d0697ffd515add2d81b091e8b0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001182cffc34b0605dc65f43966b0c0cdcd79e657b458c0efc4b1857b5e3699301e52241a43f53cf794d5a3b6d87b131ca0000000000000000000000000000000019088f3bbcfa5c28db3cec94b87b7c915339d8ef65517c5ce12e4e9a7950f60088b67705fe2e6911fc335bcc6c971bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106d215df1c66952866154079ea0b71d4ed47b0598b3991c322933d146ec051ee75ac4546ad95f52ba28cd23bac32c5000000000000000000000000000000000da4c23d36f248b6f10a58d20ac790a5bf26de745e57bf8a23210ddc70dc6521a450a2926b7da43f2f52fdc8e96d89ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142fce7069d5ef6851f4d6ff5d9c1e010e40965b5ff8951610c128118787e475aad0337255da25649a028f36ccba1d5700000000000000000000000000000000035b1116c0b9f0b68a1374ddbafd2f883ea9a01ea54a8a71873bd638e4669994b0adb3f498e1832995124fb88e932de01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3443d78d116a75b83cd6340f143b31fa316da5b5269c679d2cd11f6333a87aa3023ccb38ae3270d2ff0052f5032de0000000000000000000000000000000001786786d48f514cd6a2f49342f4eb1360903c8a20792c19b2861a49c9704814900acb668842a4a4d087034a8e151c7c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050b55c82609c0f1a90847fe66b2896606956ae641a4ed85fd15489f25f7a3dab66de41b9f58b9612e7d43e09c045fbf00000000000000000000000000000000019c79fa38536fcef4784d83b06dd9cf42dbad0ae1988558b9038c8d522101a51bb1f8b0cec97b025a6cefc29f8b65371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001612cf45ce354e907c06282d34b5b24845f255ca139c0ae77eedc317552665a1136a265e4043249b59a940b5c008728b0000000000000000000000000000000001dfc7b5586c7aa4f96db1bb5dfedf2b6eeee61f108ecfc5f0d490b00ae9d630c9b25c6d90711b17e30799da560320381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a828434635295ac6175aa01b1fae2b240a395712dd13c53260e6654d789dc1afae4ffeaa3ad26fd6f5213eec087789000000000000000000000000000000000e9dac8081d53e08f31e313a88ad7e4865854ec31f18f5b7bddb6aa6a5418f37815c1c3afceb95fd008d0567eadfbc681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017da4b4b2a1e010ae158c8df7d5c18d210b1949aff15c562b88a0cc46190ebeaa6f85a5c58432c15fdb8da44d40f41520000000000000000000000000000000019c7ecbf1d4795a55455a11f733712136e919d43540d44a982f6138dbb0d70b0a0b3e995d9701a54999ffd83200833451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000326587976be62f9b310eecaacebadd37c14fef7f95b2377839c5afb9a8f021cc73cd5c37bd8f2d629533ec927627d20000000000000000000000000000000000fc5df4321e26b1be94383a3c54cf0a41869742f25f04944ee92b0748605340156eb762c8da40dcdbd4e55e09975cc0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012442cb20a69c228bdd002b9159abd341728f38fbb8261e9fd17c2b23a46a986fa223d868447d00a8cfb4deb51b2ff00000000000000000000000000000000019c62ee4dba3cfdbbfd73e85cdf9f2f024715f971a46944b38c94a489f4e373eaae86b9b0167d0d0dd9368dd7f4de7ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073421749ab16e2e8e6225bb1827d67e10ed3d075c36d0e017de6c557c1c6357f9981b17ea73d75284f32932536914c000000000000000000000000000000000177a176dde7e983381157d2a263f55334c483bd8c82be074094113bdfa693750e873b2abcf51d70ad4f33ef3ac10f7321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afd15e3552ab70088110fa92904851d0c36db558a3d65d16512f7bbc9b8c3c9bf0e71e3ca4485d22a85d2c109b470370000000000000000000000000000000015d1c16181beabbdbeb0e472474a898e2933004a5dc40fdba76e663322806cd4a0f46d3a5abcd06c8b940b815d348c3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131e1b144ffe856ffa047c130128c91bf27a3c59c7061f52d2a08842ad017bde74d62671d65d8be7a3c8bf0a451c39a00000000000000000000000000000000002b7f14f2aa6e30b88bad39feae7154f9281cba2353aaf37e5e2c3de3d328aa45d2c232c5759a04224e1a07994553a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ea693aebae4f5e02229a089f0957f1cc0bb9db7fb5e8487e38ea229e60cf55855d09cb979f91aebb0b813144f69a01000000000000000000000000000000001258a1de6cf07585dd6cfa88d87589a8fd0c055947d93d968af516107b724966fb3bc5c47675d41ddcffb300331be4f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010604d4fd199b8308a8c9e5b0a62c25bf6cd7275d9182fa6d781c7ba68bff1140d97ae4c61aa29c8556fcc739f7504f000000000000000000000000000000000682de3a5a795af0a130d106345ae8e9d8a5ba2523fff38ad5c941117429786ed1f0e562b1628c70036ed56b91a8c72a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bb368a1ef9eb8946f19372659a571250784879aee50de4efe2e43c148e8c4ac84b23d2cd5626b54acf1cb0b6deff1d000000000000000000000000000000000efb4f97ac9011faf83afda4be67bcfd926c7575ea43654645a90ceb79c6c8d21d189bd46fd979869512de7517ef60221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001310cb34fd5e8055aab5bde3aa5d8b69f71d52f31c1f8b66a167506a14eaa2faadb74604bada4e6724e7c197c27f45ff0000000000000000000000000000000002dd62a444bb0a0c76f80c735a4723317fcfe881a900ef74519f397d9d0789beb6fba90666bc5f3805edbcbb8af9cbaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd526bbc54f5bd7e7fff15d902b69c10a8e046e111837d907369ad3e95e811a99552701d0731e2ebdc832ae810707c5000000000000000000000000000000000cb023201b78c82104bbcd0d498d2d297378c36779c8976263d3350f5a1c3250bf5adf8be2ea04ba3a5a6baa7efb67ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000515512de97ef30b9ab9621813ea3cb8ed3157731ef6d9929112bf46cedf8941a83235216e101e74ee227bbb0d90593000000000000000000000000000000000165bb45cce8bd2eae73e764c7b19f19de04ad9ce763a332db6be8a2b56194d673f9048602e6236795748666f46bbe3651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dc069d80b23610db1615396c173d0750307d0288581d997f8ccb2cf63f235d638e564018a901179a301696d9b54e4b00000000000000000000000000000000098f8098dd74039cf3ecd35cb7744a88618b0a0aede9a5e4ab78e5ab14639562cd85dff4618b4337e2937c0a4680a6bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7ae9d8a83656c38bc0eb6541f19b00a9f29f9ce5302555cfacfe96dc3b3e402453e99f23148c0d98c95b54f070d074000000000000000000000000000000000dc7be7595475c0db9ae12970b3908159a8872ca5fe1cacee0383198b9f9d40f18223c60867bb15aed46dfb916669bcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059520c4c23093bff92633d8fd3ac3835f3704b661d848a4978220ea3b3128598edccca35cd20f3da6a3522be82ab62b000000000000000000000000000000000904d8cc09be578feac5d9002ad0bd6612b1a83eb3cc71789b90cf42272bf9b1a6b4f365d7b06166affd0b101c5bb6571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000518b7882d2e8f9b3772abb215f2ff11f4beab7752e41a44d5e63b18acc77d095607d7f4607055c030935f2a862ac10000000000000000000000000000000019a1ab8ba196d1de6f7ffa5dad09d7a276b492694754e050337f5857618639a5463f810a74425473ae40bf6d3a97a4801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ec66bc157c486d766b44558ed391444a323e86ae996d7ef1c7f07582e30f2b0b14549b8f27e27ffb1e82b09b1308d1000000000000000000000000000000000c1d81179e0a15b19e03ea2d8756bd088b98846657b7cb6d6dc364bdcd28e0c79bf8368ade430ba5e83365b37b030c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd6a21feb39438a54b5f1ba21126a761da7756b061326201d92f9ec9673f2bd698ab9f51cafb3ff83293fe340ed57b0000000000000000000000000000000009b400345b879beb2bbc9ce5b78b92699d5f7fad9382988511aedab5343b2492ebf374025490d660be0f0055c57eab7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cc4bf9a40dc806a8a1f324a812432f555d255ded0055a2796e3963e3e8e6ddfaa6250e6a56e829a1dd0ed35dfa8c33000000000000000000000000000000000a5b60f1733ac2fb02ce534bac7234ffcf54849af139ee16f808b838470cbb966237a56ab6d1a3355903f65df3f1f9801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138e280d4e7eaa30dd2b366c3ac26839cb71bdc64374d3cc8bf1ca693e8ed0755762db881da4ca36a28cc21696190d3c000000000000000000000000000000000088658acc052224756de51f5d41e12b764d767797f3647f0f8b00e54ef9479c1fd898534fe933fe571d2427dbb1e85e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e28de35850759362fffe018625872ed58a1eaf4ae434926065344289c35509e3fbdab6830d9d545dcdd9682fa934a130000000000000000000000000000000005454144a0557445a8f924795abb123b765d6ee824c6a7e4f3922b385d02efbb3e8b524e86c8b7310772366bdbcb238b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6f6881e6e2533c4997702e5a73aa29bc12eaee130b53d90cb492e075baebd119861a794765e4f18ac68b670ccc37160000000000000000000000000000000005cea9b2d319b01ed4f73ab2da998447b46762a36d3d8c182695714ba5ae4d4136d259dc3c3e55217d3d5363421e189a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f432fae63fb74ca33b30ab4ff62184d586f931c8fa5a2aa223787af7cb2eb956fb305a947a18625c9056682fb1504600000000000000000000000000000000166038ce66fa6eb68296ec474055004fd8fb87023726095a0cbb20d38855f8bfc29f878526dcb3dc88e334f2eec85c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c0ddc42bfc8d17303254682b7465037c11f37e34ad5143a62598a8aa8008a2314f59ec7e30656db6d1e013069ca820000000000000000000000000000000012da64ab3bc4e3d7adf0e0b6000333259ec23c33416057695e3a82e34d5c4bee399f3101aad9034881b050258263d2781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c02398513f62ad752163dbc34edfa64b3b5cb4bbf5961693c7b7d3fdb0bfe914030c0673397a52f5a1ecf6f9b3f4f00000000000000000000000000000000177ae0e79802ec895c52c408bae671e01c2570a968eaed26f625b75fa9c98c4aa16fb33922fa621a5ce1f89ea9a9d8ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018522ee067b8c624b5dab45b3e76f577dcbc8e3b58491c87aa267c957355747e10ec1240c1b1895d9129767ac7df73c90000000000000000000000000000000007e481f44a18a8aa0573aeb64ce06a5da8112059c4448e312c19bb9867da5e1b9d581f4dcb0272f0701b4b8274d1ed971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3845b662736c0ebdd261900cab0446da8067fcbf7a3e126e074da03c07d6a277fb82b65c54844e4fecce98f448d03c0000000000000000000000000000000015c978d1d4e164073986716f98f2b363841ae6f02abb51221d6ac9d632bc1e6ada434ea272f66de1949485dabb8e9bab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001999a398ac3d05939b46130a21c4370905c357cac3720f9ca83177c45319a79dd7af17ecb45f2e0ec82ccb3c3c8efd8b00000000000000000000000000000000161696716453d7a6818bd38e1a2a56ceacdadd5004763423bb254067331acd2c84438091fa9d41213f3942f5499265181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101d2761b573dc0950dc9cdbefe88719c084614a98226660411ec9ff2dd9c2b812a829f7552f2f533e46ca0ae94e348300000000000000000000000000000000009bdb1bce7e09d70dc47ee43adebeb7bec97300355a012058377c2b96708a05b7f86f055919b45f2a7df6d29dd6a9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003d62cd2eaa9e2975a85489d9a89f61d35430290bd971b6e42f23ac590fa0a76e9704306191a8b3929dc05bd386c1380000000000000000000000000000000004bd4aff6e01df2a6f1cf6eeec2d5e64e7549816cd00715c19718109b2be5f0d313bd89916756c0ccf8b172c1110a18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4901d2e46c6ac3c9e2f39464453a6c7daaba5360707a7b2e6179cb7d6d225fae18582fd37f2c47fd75fa6e14edaa7a000000000000000000000000000000000704fd1d8c0f2311f9c947497a217eb165956aa49ef8fa4d3073f1d29864723789c97baa5b7c3ac92a2c2771e0279ea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e36258b9fffc7fa146f28fb68a01508da0ee1bbb378e5b9f41f0d7116fd7dcb5088f045eb7f47f74cec93b97e903be00000000000000000000000000000000174727af9d6ef2e5699c931652955dafee15e876948600178d63cdac64936161f525bb077e0be91d1f03e004a913467d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015779a8bb3d0fa11638c480a056e6981a001baa346be93e1d627fc083640e1a0d12c089a1d0107a1e412af20f3855b0f00000000000000000000000000000000155e67a7596b01dab2713c60f182387d407a50d03649165323b27a8b59b7301baf8323f9389fe0ae7a334dbda543a54e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017325ee580951c62a534b139f192f92e74f60d78f4789becc8875eb92de409a653fd0bb5d3ad5e2b9544e27f6e1eed6700000000000000000000000000000000069d03b4e569e6016f31c6a66597399760b48afcea915823769a6adceb83fc1b38b2b23fa63d5915d5930ec8c555398b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000badfce8bc55bc07f5179ffaf9a4d9a7d3665b894579cef8a00b6bc75c3afa7779c949f71f74dcff551f0d6b1932cbb3000000000000000000000000000000000b0975bd4e9da6a51c4a258a26102850ebb28cbee526583fdc31924da31effc7a882e39074acc612ba0e5ed16fa975df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018380995a9e08108fa4ccc420b5706d39fd482da48903006cf0ee45dc9cf281324631566c19c10d24ef65b07dff674a2000000000000000000000000000000000e3a4be63bc1e0576c8fc947370da4496e73ed39f87fd4b924e4746dc619d85753db0267a20497e6ee9cc08cc9cfa8c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008153b366c75e0e0ec84576263c008d034cd6e7ea70662fc5f5054a37761f65988953f8377acc5de8be88afdb18c237000000000000000000000000000000000adea330372e62f60541baf13cd66b3b1126774fc9788f9624e7b725839eaf0ebfcdc2923dd24a3d3b73a59e8123bf0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f054a6035cf267f8ab2394afebda11d1fa3c38a998306cbb6110466a77ec83a6df1690b93bad4e8f424a21404da5dc0000000000000000000000000000000009fc6eb95f5d23a2ffdd888357a46f3303f6b7b478ea56506dd4dbf08ffbdbcb87440420457ceadc79d6aba39cd6b2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000345b2d8dd8f4e9a6675863a0091348a7e3d6ea4e741640b2f4fda41db1ce3b239257d5e0f3e7b20162269f10dd32ff2000000000000000000000000000000000e1bcc0ed478c19ffaec404ac08a5cc2ed281dbd3d786911a31b865d841bdfb2016e2a91c1f8ce12542ba0fdb2bbcfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c2d8d69638792165f10eb43b3bca6f4b5803938e145ad2c883d5841dfafb399cb5660b9fb3304cd0c7835f232414f00000000000000000000000000000000014b83f9b9e6084fe73f92a1fd244fbb3d8bf1a90ff4848bda85eb765a4c64a2e10772129847fb41dca548899ad991d221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f641652228c5eb7eb2356bfaf53dbaa107ef15c27fdb92ab86f200a752bbcb30ee81424398dc59c0a7a3d5ae9d52a9e0000000000000000000000000000000019d5c91329ad9abe5fd7bf87cdbdc06aced85c6907dba0303a41ac6df49539b7ef2f30803e8f81e4a981049f121887c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004021b8c38841f20d012ea29bd5944d8765b8e9c83e52f4d0b970972dfa66482e5ab7b06f70fc983ab214ffd8d50cb2400000000000000000000000000000000041a0885fa7e234060995d727806b274b0b8f88294693c2da78fe7176ec558fca7ff6c15e42ff05b145f57342602e1371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf70a2f34d052efe881db309f225d9965cbf8618a7b143ccd68546739c50aad4d122bc2e05033089a4ac511fb27f08000000000000000000000000000000001820337d5f774f4041cb59c00b97e3c2a615c1eaa3358089ec0bbc69162679cb15daeca255f1de2f01e9964fac0cbb731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000611797ad7ef7d620806c4a48fb14a12fd910cd804d9ed063954548e21648185eeac5b32efe6b80a36a2385f6b7c09800000000000000000000000000000000002e81822460be0a390aba478e34d66526a9737cc201e85ea90c3ae3186fcfb3e42fbdb1be323b5819d337a97ffd20b261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002efbac97066058dd071f356c60bd176c2366493c27a708d4ffa9d021be7da9fb4063cf05e98f11f3faf36f39387f4dd00000000000000000000000000000000190417959030a3137de4af1fa28d401191d4b26343acd45b5359d82aff8e95acfb46b1c57bf3573bf1c5b21e49e659d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4c8ead75087f1ec889d543323e499673280b27d16c4528c707ca471376fa314a8b61d4ba71b260e8c27f86a8b76fac0000000000000000000000000000000007be34f41f4e434792c7b49775f5e2fc1da83602d99786a537ec6d1ba8799aa10fddbf707a9ebb65f579d129c15478f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8e6d9a0d1060e3ebb477765ca2e700927ee2c0ee21bb8b610e8d19adb1238b148c40557b639f4da35e4f886e3b8abe00000000000000000000000000000000195cf51b62e6a68685aa6660a3724302ebab9ed71408581d2022257b96b988bcc6458a515839ad300d91e3939c81b4001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003180ed4414802774c2564e8521b0d4280ca86515859cd628ce9ace55bc94aab11ad46298ff58b28896f2099ab4a360f00000000000000000000000000000000139374a224c957ab072918ae587f8b0a0935ea829ef0ef75901bb939618849e70b562890427e9cbaec119d1cc952cd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c2fa308485b8567c1c76d2bf4e0ce87d714c51438b089afb553316f11916c5d5802dce99e456c8e79aa70412b90faf0000000000000000000000000000000009bdce6d811bbe8cbc8d89ee2a3472988b727908f7a6651284f3cd805d0bdf2a959d40b86fe18c49120fefafeff22d6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f8e7942c65d59040f07f4073fdd5b4fc9c8e7340179ed19d2927696f01aafa4e45884ada8efeab6fa59889df87329a000000000000000000000000000000001951ddd6f7a1f6d950e956015a7619a2d7662964053a09f98d2ca3539583f9fb5b4f0578c03ebcfc136274a77a9deda71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ba963531914ffe8b5af97ec4b5656b99d6124ede4328462a2d809459f3f9d2da5ed874152685137917598082ddd0e3000000000000000000000000000000000e98ab1eeeb2a528b88ce39e6e4a425549e3e29cc080874c383e1f8778015c23084ab04777d165d213045d54a4b434561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001535f3ff1366bdbd59e237ddc37e23a0c92f2974306e57a83fe97e42c368ea7f6fcb62b221eee2f154ca33ceb301e630000000000000000000000000000000009a4af87d2a599d2316d0c15793c0b75c013a94bb761f5608337d422eb588102d54298730496dce7b9c3276360bfd42e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f10b7c6e19d3c39324d07acddfdec4eb18a38e13b16a8cd8e3bce4fc4b204261c7d470a9941cc50a11c99d9d00623a0000000000000000000000000000000018db27fa37cfc87e069c35a5bad3f7991f64fc6dde2f49acc75787c8d639745fe802db24cf5f2aa0b196ee09ac1c9e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b04fcde9d433bbec0873c436c914b968bb8dbc8403bab6753e6aa907ae7049973d5b88fb0ed306611ad968e69d310580000000000000000000000000000000007736d7f597f41c02025f2adfde4991d1fa7b65aafb7c8fa4e3a626b18b3270daa603e9a5079433bbb921bae8b1f15441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f7ca8cacce156fc6651d5f60f01427683ffbba9ae23a20171cc0e8429db2416725557a70ed3f91879c70fc1d5d64ce000000000000000000000000000000000f0fda13ce09ddf6fa1f808234cb07b0b1abe22bad611d372004c116ae66a70f1c67fde718cb9ef8fd9d13e00b140be21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f1700a75e9f2e0bb760a1ea941afe719b973bee31d62e8d74e8ebc2cffce6eb6dc2944bb8147694cb90b65fc5b6caa0000000000000000000000000000000017cdf01e6d54647f1b996b85223e0fa40c2771820e8c672adb514e0c8ca8889eb2e1315c2df13b730b6e7ab1ee209a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087dd5d4c827323e1ca76fb04fbaed5e67dfa2d3e775cdc23c4092fc3f1f0bf6a4a25e419912cb1169445d723b4e15390000000000000000000000000000000013be5368018527fdc50236909eed1bf4de7ea4a73df85aed243bfe1e0964b2545e0d06c48e541c33bb882f7e06a016961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f281392806950bba3d5b03a94f0f0c4b575fd0cefebbd4618f69f8de5a972fae47cbf54cb6362f736bd28261dd4bc7000000000000000000000000000000000ea479191b4072b72a510f33a3bd6ceced2b834d74cf5513a9ddd90c6c28e0edb9c3e2aeb5a452743d562e9cb342e0ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010670940ad9e2571a6d0d3c9560b7bfef47da754a08038994126aa960daee03467596ed8950e25c2e67525be99d37840000000000000000000000000000000011ab6adbca985f0aa6cfcc6b5b248c1653d210bea583a53c125630c17c5692730810227c4a1746f43436da6dc9714b9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a3bd791a3b27bdac3d89c26ec02078650f6f2c1144d5ae03ef0a39071e4756ae9b4dfaa500bad7b659fa0f22e3382a000000000000000000000000000000001524fcab621e8e35c995bebac8b567b3d55a8d9fb766f8fb9ffe8de5b9a3082496748843d941435bbd97ff4e1b4fe4211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fa132c5142dc3db0bfdbc39cd64c03199859332e7ac16a1614c528e38342e83a1c0ee043011340e369fb5ddfff2a6c000000000000000000000000000000000af1ba67396f7ebadf48f7e754fad1afdaf2168dfae475b44b81914857d227f09dc398a57bbaa89e44ffbc3ae43642b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad8c9182af98ed81465959623ab3d76958c019f5ed8edb1dabb340069e2b8e8cefad89bcebbbec41d898647a8a93b3e0000000000000000000000000000000011ebcce1e38cc7e38e6aa8d59813aeddf0bea4fdc462f83c36ccdbb4f298f1e5482ac7d2e5b8b01e6ab94d377f03b41b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217579190c9171d32e31d1a47e3acd77199dcef8d0c8cbefe28931776f4b5274b1fa9fe14c55623f6ecf19049131ec00000000000000000000000000000000026bc9aae5e03f066cbee582eca8177ad5c1b5dc08ed586484ee95c779d422e76d36fff68840e771673f850b296ad0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fec057e7f9cf9ad7f00146eaf2004120b3b75c0e751174c583794281b9ac1fc72e80ac76d54a70eeb026ae878a19bd000000000000000000000000000000001137b13c750996aade79c835b706b9b8586203b9398bb87289d12c0356b0c4c2135b1ba78dfb615b105659f111529d411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c595a8e95355e5dfa3a466c2b80ab9190ab3528d6ba3df88b79a8d8b17cae134fcb91e206b3421d35947b9cb2077a90000000000000000000000000000000005fee1ed612d91c9c090c2fff6ed195fb7407e64261f88875744579f813b5a38b1a330cd13c6c8ba5528e88c2650ef541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139881e3a0d9ca040c723d14ea3f4d0fd70dd2a4b20f59f0e9f9bfce83c9698a07d2b39324b1a7863f8c83141f45e5590000000000000000000000000000000006783fa2a93cc1ab51aa4f04fcf6fe193056e38a79d6cce83f90438802d675e36ea5cc747a70d106f97238d9f16692c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9d380b62fca0260552e15424dbdf69fff7ecb5dd6b60d0c43b98ea259e139ae42616aa27b9ca646d86c3e743a494a7000000000000000000000000000000000b9310718c17c0988b30748db9282f5ffb5872ce6706aef0a04589a502708c265d273e8426681dd681eb2d56629cab441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144f23ff0705b93f52c464a3662dc523c424020f5111711f9ef967af0685d07dbb2dd1f73a0de9b0df8b97aa23424673000000000000000000000000000000000cedd13c97c1f09778ed37053958d1d3e74d658e2c457ffb8b29f35612a45de0adcf1d45f71a077da7b960e2826d3a411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d189242537ff37cc87821e25070c3f8e04a49919f87fedf0b07e7fab88ef25621648e7dc966b696e0d26e17f657efc00000000000000000000000000000000135ae27eb2df99af461f25814313871e771a5dc24206d291c2072553ef26a2f5c30ff24c2da915d6274d9de79d3f8c9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157c582e409c0aaecdd47dde6ce2ad3e5db199920ad5aa7ae7f39ee79fe100eb9e5a9f4d8db890ee4735fc53504d3de0000000000000000000000000000000000c2e26994bc2df5bf239fac763390aec6b25b6e578baba391f5eee8def1214b74e67829e6bf2e91ac41011af6ce85cb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000624eb17e5931eebea9040d23cc6724ff937deae5a4338657e7dee254396fe97a87ce7868889fcd9608f74c5dc11592b0000000000000000000000000000000019cf4769239b97d9cf207dc04ec188ed8dc4646f07b951618b4923a3ccc5b5bc7144b5006521ad4f894aa91f26b2aef51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f8bf08733700be4fc9abc12f556a50c5a8d00ffe64c8a5c74e033d8d51a1950fbd3f0923b2220a18fc154d065641bf0000000000000000000000000000000010099a564a7d8c7a72cb795d3bc3f4f369712959837ba6bce07be4b628a2e7ffa18ed1f67ce0f8a77f8a1c65b6134dbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a4330352eae8c7455dc20c027a93175e4c6dba136e8c5240d8aeab64c3c1cce1f1c6ed0a3ec693e7bf560140a4c0eb0000000000000000000000000000000016af7ff6613395ac5a731280c5b573eda997723dfd3896d81e8544db7d1c5612d9205e16873e41c0549a43180d33d5f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014f0eaa92c19d69d3c4a1fb0df8c2bf7c167c123cc6095d0cf1cffd5f320b6e50acabfadac734a3268ad2ea13c837c3000000000000000000000000000000001291d0750352c9cdbeb480cf2ddea723d3652521ed6cad5f7f07f200c2a2c07547aadceda6df57bfa295398c35f61dbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726cdbc932ad48907a734162655f65d4008ea188a1f4fa13425c4d0d4170c7f6a14eb58230785fae19dfe8b990cbd35000000000000000000000000000000000b830160c2f525f5b06d41cdb4eb35279c05eeecbcc32759ac81d7e99fed9a24779f4565ed9b74f2b1b654bab78003df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e39f6bd87a6d7e2153ed393c46fab9ee3edfb2ef2af9634486b997e2a889371e2c321efc2bccc140d5094f2098637400000000000000000000000000000000186cd2327501b9bdc2ad858d7fb704b9ff1d1669f36b4bb9ec15fe93f82e62e3ff16ef9ac9eb6d3b85dbecd0af3899ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a32a2a46cac4adc4428d687fb8f34393e6d60a2fb91546eaf8b94b385111e5cfdb41bc18b7a599ded969e5c89fdd23000000000000000000000000000000000d633a889d21809639e633012daccb52f21a9af9f2f03f714608c58178b8ae719d00ace589421b4ee3621ac8203dbe911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001433317800d20159d380680be435b3aa264ba36cb2fff6088a007d82aa1414f642de62cd8f3b3d46bd9f26c1010faecb0000000000000000000000000000000005645dc25930c5f374f6bdc006cbd659936b98a157cc9078d8722dfe0348124a1712ad6c4577d162b74a83601b00f70f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e9c4532401ae40a0db678eb9b77d75aa12c8f495d4aeaab9d83c14041a40782e9d5383cdb4018c78650f0b372f117b000000000000000000000000000000001577e38c54ff2a74e1098b90d67c01f350061e30667c9fde423bbf1829cbdad836f64d0fe52906f2c16b6fc3137eac091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195109a2e44aec39b9ebb7ae4121616fe58615999891d1db96831c43a466a565ee661f6d23392bd863efefd3c17d1fa00000000000000000000000000000000022462a51620e7be6c7b98c8805e7b128dc04789798ca4db66ab46eb7f064d23e00c4708748356d1d961aa2e217025981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194050fbaed1c80ee8f0ebacea0c1e2a33a16d6e3dc749c3dcc2aa0e1d383378aaab61591955455947fa5ef0d860de470000000000000000000000000000000012a1fb715621ecc89cd7008055c38c0390f07ade578bac59e33c22972a989f2d6477008ab8d562bd00c142d654915fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010564449dec5e396078dd15a04640789a243d7344a9e58b55f5039cfa4f61a5b82e95633cdd013797aa3ff61b61be4fb0000000000000000000000000000000001f6d8721e2eca71dfbf71f914d4f1a9ec288d18c346b0506edb13323dfadaecc2a233c994dd119509f1e9fc639d62451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb81c2109cc05bf804b2a179193a821d5a161a8a2833057f1bb9d00e4f214bf12c4bd1910130b0051ed2aa983e2aca000000000000000000000000000000000c83707449afd6f66ee78a0e78c563b28b43cb35f88f582a8a07d43b93d4b5ed9872f5ae8b652bf99db3c5dd2d8a414e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145cab6789abe9fc85535d395f45f753fa25cc5adca12e8e4b4414873c01ff2ad5f676e752a4d8acb9bcd50ade0443600000000000000000000000000000000010689cf7250f4d83b639a6109bde9a59337bf0b0b5e5aa9f7a35db4cf3ab5d2d9b60648055bb2c68d773df495d7504d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112b819d8b0be43fe0a25f88fdb60cae2d4cb93d8da34a5f4f1d3ecb26683cb20acbb7e59256e2e16682f9377bd2ed00000000000000000000000000000000000d728fd71d9c0ab5a09fe6e34c87df560bb14cd969cf2e444af7ac36b56701eee6b6c29967ab7ac4bc04c7fd8cb921691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f444dd3258960d127b8a02c7ac97609558b4ef890cdaf376a12a969dcdb47fb5d5bc6a620b4a90f496ccbc5e5b633000000000000000000000000000000001668c53a3937f6a7ef9ee15c3a7969370562f476a455213e98daedb1ade41f08f4a6a10a2877c3ca35d60023eddf19551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc586609f2739a211458021a98a9c24fc5cf8d61d07fa7b69a27a107c3f0fafecf2129ea3ed4f221c51c8be4812c221000000000000000000000000000000000b71c35db4b0ee1d3625e39d43e18fc89d2bab581b7cfdc858a213f82e5244cbe3d3a5cab8892a60cb5f9e512f0b95821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051eab14e80be0558677a908142170fd80f120e2deeaceba737211c93ce0a966a62b65a86286ccb95eecf52766d82b6b00000000000000000000000000000000024f41b32bc97700fddcbb8a84ea8b33e9940a47d3c92f663a346531081146decd893ae3adaabf2203aa914967cb02161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c31b413f1f22d9d257eff96229180891ca895b6799c26bf5a2fac8e8f6273bafeebc6f5e2fc39ec65d3c19b94a2d7000000000000000000000000000000000df2ceff55acfb3a19cf74b7f054d86a12a66406db301aa5a01c2409a7ac5040f9b192ff4d123518f0d099bf10d123f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ebd4ae590a1909f648b5175cbde3cd630182aeb8d2115fa199e47ef73ef37f0d99f178c02d9af794456d2503b27cad00000000000000000000000000000000185fe66379021fbcdb6232893eb38193c60dc4973f3d2731074c560675ce296de56c982cc65f398c00303b2b61e344651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2135e833564c0db590061a5328ad1b8e8c249d59f7f43651ebda660e71215c7e62c045d4044abe373716e711256b900000000000000000000000000000000003065d86280800141ec7c314b331af8ed68d58dca2f3019900b8ee96ab95c1b0049946847d61c3c56ac2e3265cc945721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001827d2a3375cd7a6f2de543c74781ebb066f90c5c64ef46212fe73bf9cc00401905fd8562d01bf322508d4b2d168346d00000000000000000000000000000000147345bda34af73b6533cc30f09e81075ddd83a4835111e5e3335ead04f98ae646c8d55369e41d0951a9c535c9297e591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ca1b0437291776d3ceb19cc7c229565e1030a1d8d41a4dc8261fce6b335692196aead347de03a68c8cb092c4b2a3000000000000000000000000000000000d47180e173da6e6c7ad2c558db3fc098d8b4644a5152403e4a68bcbdb29f8cc7680459e072c7efa9677eda196bf9f971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c3fae1cf782340c97e18d8c9762944d4d95a59ae06bdd17a3fae723e31c15ab448cec214776c27a935b5a905d821e0000000000000000000000000000000017455e4f4ca3ff1761b88b10810aae602ef9c2e6d570f31b200b1dfd870f18716a975c2691b05e6c54b075f5f03172491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018af2aa6cdacb5e80782aed917e6f81d8457f66ef1099ffa31792bdb2190a788fcc4163aaab16b42c9cddf9e2ee06aec0000000000000000000000000000000019c4f4d629336b75b333003fb2978f8dbb8c8c3acadaea80dc477908aad8b932d86ba2d3d8fdd52280da4856c5c480031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ec140b4300e5b181110e18a5824c653cfaa73755c45d92bad4b7efc9ca1361f8abd4cb3d980608043402887ab8868500000000000000000000000000000000009b99f980c4626c0d069a0b83901ef76f0015d3a3a1f530c94679b5a81b1f564d1fe19cf9375ea8962e2ab4c7e90f151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e6aa7df0b094cea000dcfd5e5ee264174732f091ac6513037d9a3778671cf90c12456b6596038b8954ab13724cb835000000000000000000000000000000000408a44b5660162806106e225b0cd8c48141f7e6aa3e266a2e2b9af554c510a94d15762faed6064b524d5c941a1ca5f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094cb5504889a15c0b5101c1377af4ee8d5e82da618d5b9bf39b8d1abe899d3bd7152e8aeaa6b615f0a0d846b6cd24e200000000000000000000000000000000002d714a7530e1634733945cc252a1fc56bcb6d7f06c713fbf75f0735e40e5ebb37d68b0453fa2495e273dbc095457141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009688819eb6525d20f23d2f839e2eb103f327dfcf9273e444a6ca90534cef1b7099f05c091bf7f4e32a846403bd645a0000000000000000000000000000000000462b0190238322bb647a2f88be7581ca008a4a699f1eccfb34c8cd0d160783a7ef133e09804fe52f1c6e93e9ee668141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137477a11e1bef1bb7890d5bb7507d697e751b13759ad5b957e4c57c72519f20c03cda148c35c4594e73bd8e7e64151300000000000000000000000000000000099ab0913531df0d5086c61c593e088c72c865c6e8fcb6af92aeec180f600f7036a56dcecfdd7a2f21f966684b5cfcad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090d1117476d93998f80a5c39690bb9c2fe9ad10f2853b842ce6f859c1b1927a002ec7fbeb229d0939457781331ac8890000000000000000000000000000000002edd39365a79b19f44f9310d857644a512508e63524b81f00c89dc64e212f818587c14cd05572271d6aff0fd7b0df141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c0f5356abc8aec544b220fb07a358da727d38ad3a641afde91f2e2d99b9ce67b3cd71c9542b597833033f3ab86224b0000000000000000000000000000000013be4bace02ddde85208f186d238eb2bc503988a95b572cc1e52c2f8b2910e7d53b25a2467c2c20d6f7ba926ef19d6c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a291afda5c48bea9f0a2aa12be52ba21c05fd2e9560e4e0f8cf0e45bae7e50753a2418ebbedef094aaac19cf7bcdf0000000000000000000000000000000007cabef6ece211562b21b9f65460045e63d4bae5e6decfce9246cf5b87c3a6d41994539733892f900f6c9f743040e7181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7569cc0b122409a0cec112e531e2f0ebb32f0ce625dd88919a22e97213a999325cfb24f0d65c9561267a5a8c36b3100000000000000000000000000000000040579873821d826ddbde8ee16111358ac8104c55eb9c15dce9a1505d72b64689a5864aab40d4d56deec3646130947161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ae0514d4a9ffad25fd3d28c2121757befdf5b1b1529192b0efa496469f928747941a81a9f72adbb4573325c87d1cf000000000000000000000000000000000b663cca373e565dbb866fa6df50cf04f3b30070eff683fe9026c40d23b98ab1b50ce3766ff504c69db6d09e0902341a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aaf42c999d4294ddb6c336121cefc16063dac4a20d8b054a7d0bd80e70a381b2dc3dfe4d7a51a99bcf0fdedc0a9a4d0000000000000000000000000000000017b2522acb1f3ddbfc2d4b843ee9840e4f0965c09e948c98d9e0f1e100703918a51b276392a6ac24bb3a1992337a48fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a5d563ec5d4bba5c4fe29cfa9543b63378b6d6f638ac78be92d48d3e9199c465c61ec971d9ccb25a36a90ebc90c4a70000000000000000000000000000000018595c3e1ac655a9898bdb08d70cff69b97474e87e8fd045117cc9534bbdc33b2e119e5f13078063b2a9f9b30589e76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cf60c466de47dcfd9d6c4ad1b9a6c9c213d870afde146ce543492dc8e908740bce11486ffee295c308f85229d99d650000000000000000000000000000000010016176bc3897490bd66ca73472f3c4b1e49dcad510a5955a3146ae83be6b0e3df7617ac2e12468dfe92f4be0dda1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003059cb4966bafd78b8c5efd34df5b2a05da7cadcede24e4f3d80bec458e8947380c68ccc472079898ede894a8cd26650000000000000000000000000000000011f3d37aa82a4e6ec8e2b855a23ebb7e875d3aa1a71feb248406ee5bc149e23428096612a38783810e4c07512e3b64601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008400ca9f2e8d0d0138a830d95f5a0c62525ab4712fdeff210bed20385315997ea559801f36af6808c3ac20da2bbc2c700000000000000000000000000000000020858260c042ad5d4b23c7b6f85584bc2329247a24ab67dff8da3dc26acedbddcfd5576d4f72f4fbbb88ef391d979291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d43409768185fa6267d5c65dcf3bc2a89282ef7de1f511029b5b974420afe3e5fd17333e186547074945f9e0ead6b00000000000000000000000000000000166162acf4a62cbf371628f50bdb5e185296899c6d16b3ec569c2850b9b9926e7a1a2a609ef7655baba24c313cadbc8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee749bf0eb482436b13e8a8bc539b30076bbf88019b2269035a1dcb87be0a6ded5c3017980ad14474886dbfa7d2172c000000000000000000000000000000000a7e4a0a6e8860c426b466667464444deb12e749b27383c3a411666b739dfb48fd357566a2276a19ba3a60c98e3ab62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab78c6af656fccd07bb0d68d95401e54d074bac7840ff670e17164fac756e105ee23456f562ba12922b8cf8bf4b771d0000000000000000000000000000000015ab2cfe8d5466f9b940df38ed0b72b0c887bd8929877573e2454cbe49bd5c97b68f438e6cf5d73e742db7f96e8b66c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d34840c59c38479509369988029795bae5832eaedf74a857c7817412178e62d274fc771eef772660570c7dae1bb0225000000000000000000000000000000001185fabc0b10261b2a7c20f545de14b2a97d4f8cf5b9c6eaafb34aa90f581d15efe741a469c26db176de167db13da4b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000876e3830f5219519e12cb4013e8a0dfb3d7dfd1001669a1833f77d86f4bd56cf95eefbc7cc7a89d65a36632ecf93daf0000000000000000000000000000000006c7409a101650c11a462dc7218a6ef768608ce6ab880246ae7b713de4513df8b099d1160d137a3a629db8cf19c9d6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d01195c1e1f42b7befb1c5fcc101c79c663f93b37bce1d62158b556b9df82d921cb4f9f1255008b19ab9669584c1a0000000000000000000000000000000014bf4620ced3201483938401fe3ae8553cc0377aab7cf71a43ac67f7f33b2b710ab3ba406a69779a9f81c77ba21de7961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e802ea37750c6412977649624b674676b04f2cd726c1a4340623a233901b84d9d0f1a699baac456cfd833b33ad0b1c0000000000000000000000000000000010559de22895014a68bf59d71279463a0445b8bed92d48008ee344c7689dcdb16d40e7e792e1d49044a4b2ec8ab3b4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ff348de534a39f46929814c0ab81f1095df34bf5a49b04e4556c78f6fbf77ec206059a9663307ea829fac845e187f30000000000000000000000000000000010a243a68614f5947425ce153bce76bfc5e0b2662519747e7df742777de47f32a3fbfc1eead222990653bdfd170bb37a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019317e522bb35bfcb293db19dc83855c206c6a63c95c5654c6a7e98c1dc121c5a9e3a6b78494ebe9625f659cff2fab420000000000000000000000000000000002363f50389e3936101f7851cb471816ccae29e8ab1e4e10ef57327b636da83157e6138615051484e07d20bb0a9fc1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e1a2ae82ee08c0e3bc40276288840b6b9ef7a654c98631bfc8e34a7d182c1a847dfcf5de00ffb3a6892349d097bbd1000000000000000000000000000000000f15ee34f15660cb6b2cb651897e5fcdb7209d809b6e1a221458465c184494ea6d78c47810b64029c9499fc23f192a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018240558dba4aa381444cc92bbf2d2c06c6a2d3082f25033e8c0a756a9aa66eb3cb499355869c9bd767c764d7df06c3c000000000000000000000000000000000275dec20dbb317964011d230a75e900a260a8644b800f6cb7e0066f9514abd2d706e1de56546691cf00294ade614e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dfcae20f28e376e1c4eaa71952fb94d2b0ecd6f567b526379aeadd5f163223070a9030980a295e51b1b865c6402c31000000000000000000000000000000000239592a1cd2a7378a7091b5bb63bae1625016ec0fa29e2caf53a1778fdc47928c270236e723b91480860d4eeb6fe3131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084838ec621dfe731a0f061b1d2bddfbe6f81ca3ae66fb70d22a1fb31d2f402be3bf62ff208dd089ad502ace1843e3eb000000000000000000000000000000000b88805c7b66eca1c078f34f72cf2d032e42294737754c13279145e41e99fdeafc57819fa07bd73dcadcc15cc93d68bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136511ebeee6b98fe1339db907cfd9662c33114d86915fdf94db4d960edf5cc18e1205ca794061042dfa053b343039820000000000000000000000000000000014c90b10ee3fca4fb6c07cf988012aa59ec98c4378b5fec1f5bb50343de8b273e386fbf078e4225a1d61e781ce4dd2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173f426ed1c9385e13ba861b8b854a01a2dbe36c75c0d8253d2135a1b1125f589684e73dac9a02b9cf45ac9dd3738c08000000000000000000000000000000000ea6e876ea13c6ca1774a4053e6922b1c8548d424a5e18f2fc42c17fa86150aceeaa1f946a5f8179f060a69d397050991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001143e7823229436ddb657072cff30c71e6590dd1e3a8575bf904e97a7955eb88f875a51297ef5dec11357341284ee43900000000000000000000000000000000015ba2e543bb43dfe7ff84919f95b3ff6c3e611e290f656c6fb4c5ad365acd90f973db09228df8a814c946cd783a005e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e069c881af7adc50056fc8ad9ec7dba8e6a40fbda5d0cb14b81aee508214039e411ce001200980e6cbcc70618a6eac90000000000000000000000000000000011fcc15d75b22edd074e4601c1497561532454f2a277fac7eb032022466036e80d96529cf77bd0c93e589a78c5fa99611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64652b93720016577981eeedcf7aa344c30f1c666829c78b88d520931947dae2528acc1146f27f8508df3b608437c90000000000000000000000000000000010361dc1ed38f01e57dd2bf481ff39013dcf5681971727e21901d9a9deb708d91380b7842bd397511ebfdc6f08450eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f785649e9cba7d11a8797afcccb917dd9af73bbd4de14c1c56334d20ebb2484a8673a63fafaa8771bab95d3c733e020000000000000000000000000000000004b74a1fbfe0ac3000d89fe32ad795f7ddcb0f64bac77612e4890304a37b158df94289a9f2487a9eb6c432bc14debc471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078dc54a8c2bc5f43e7688299338306881460d87a74219d0d14c566f1fd4b0530c7538fcc71e6ed378f0a7dfa5701e940000000000000000000000000000000004b27133d71475045df3cb72c05dd0207ed18d556cebcdb76f0d6bc25caba399c6eaaec787db7f699387137a46949f921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d3a6c791339ae44a86583e7b1fe19522df8cbe3a5e1c8efa0487c800f98b234e21c35909ce3696a8003c9e1caa4b1a00000000000000000000000000000000153c3333e0c28efcbfe700bac5f0a61bfed4fc6da73861ab8d1d85b925b9a606f112642a34e8278b38926d370d6d69151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a947a93e12c6230122e4d0e29bfc6f95f734dc93cd29426b0a5ca816a06b939d24e0b2939c552234684d50e7ae9a63f00000000000000000000000000000000129c6b59c2c1f61604335bf624db2bff14ad47476a55b50fe0aab9b34608971a11659d15a0516b78472bdd6ce5933c0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001556c7064f4f1ef3929db9ed8de036592d8a0841a70e1d834addd47c8e738cad97e6f1c70084c59066c71baf07a4ce2b000000000000000000000000000000000d0dce7977dc5c70f28a1905a18c6b1449b3d469f0679086cfbd59af33f647f0913cdd6cc190920c2d4ba91b8e6d85a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001807dd844caceb14669b190d2b67f355f38b86b5732030f2073d474f5a31fdfcd01f2ee382bb57aa7368e2293fbaa8e1000000000000000000000000000000000cac5f4045cb9de4b16117fa7b58d289e7220188ccf7ff7c0e931a78a220beadc472d866a42bca69af7c19c9dc0c0f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2fdc2026239517e34a9b5bbc5d22314ab0f8e27e9c4ca06d3d80ea502074d78e1250b2df1334761e7d73aa528710a9000000000000000000000000000000000e3981abddce0782884ce3198ce96401e40dc5866e105fc0bcf4cecd287a6a538af681690d2ffbb5da4564130e747c301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fd67332f22eadd7f9a7fc4f0e208e744d7aa85947b79dda024a46e036d0ea28d91403218e3a433b80562362827d1d50000000000000000000000000000000003e30229abcdd4da055771f85263be533d679ace6fee311ebf566ecd8968643b6b89a5c0e1c9a809732e4480d63c0a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc799eb53ab9553c20c0cd7d73a446e67a002ccfe2c2f50aaf6a67949843b1ad308fcb75fa16fb508d446994259a3f00000000000000000000000000000000118397891d6cc849654ed21e0c3650fc86551147e52430f2f2802f140caf5f48e8785811c9841bb82fbfb22513a8591b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cd1283696323b7e8e3b6fe2e4ae95cc342cbe929bee0076be88a09184520b85e7df42f74ae010ed3622920df0952200000000000000000000000000000000008c23cdb0edfe93c235edd2e0a6352d40069d39f4754057435a00d8cbe67d5708d290e61bbdc61562a353e43b37e72de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba9eca902ba0c9d3350a51af447f68d996d1b1024299494090744ad2f07d8e08a1ed53a56437d65991b90c27c194199000000000000000000000000000000001841622d67b5a0dc6e21533c9e6eb179e6ed385b767e1b15fd809bc21bd26642fbd9ce1c21a311e0dcd5eef9c3dd163a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd19d02752abfbfc2c46ce1d029f60d2d3d50360695ec82a82de64182331764eac178ae5ad443ae12a45d4b51dad8a00000000000000000000000000000000033a3c5a0aa7bd1326688236f42cc9a47355c133a204b2633d09ca2b8b48a8ae5cb4c6e71426bdc074218f0b7bd0d9d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001281b2d0bd52eb9b0aa9b425f1db10ff49496a0f3db23a34f8072370f9e82c21c4c6e51c1370a45f6c7aab38e509ff53000000000000000000000000000000000d0804e911b421a75dc1b9c768c8a0265580ee2990ac6648ea2e1f0cf49d7b2c304ba738920f9f71fd90463da3a019871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184978aa1ce37f0ee415fc763cd2c068bf7d20dc1e43f32556a929a231f93972bebae7ac58b8c91adbac0d6d7e0516690000000000000000000000000000000003c3309ccf812d2426eec92fadb52a7306d21a8eeed3034d9ab3e0342bc00e868621057dc954316ad13e2f9aa804eac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d0772c1c9d18dfa53e5a5cbe84b4ba822a2110f6e827ea8ffbc1578fd200708a31cf515a9ddfbf4e9c4a361039430d000000000000000000000000000000000dcad6d3548e242e4cfbcd244dc888dacc6dc7b28ded4460c4a02838dfd75a7fe43606d700a2776b6671803f028738fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144c00bc8ecfa45eba043aee6059430269880c74709ee2f02cda5aaab8023d96d17394a9aeccdf58b036549418b76ba0000000000000000000000000000000000899ad82116a8a8ec8fd6b06eca4e9729a637e13daf94824857bc2207bf419e6f4d54b2836f2bad9e196127e2b01b7c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189e742127d6fafc8531a6dbd9d5dd052be4afd3cfe5517bd4b7abf13668e3ebea055f63afddbd0d512d3e7cf3b377020000000000000000000000000000000007c1c38fdd18bc6281aeed25a5b1fa5c37cc1abdbc1043d44bcfa5a01d1ce2abc3992b001ce547d4cbde74931b4574431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199bfd61ce873342bc5a692e0c5aa671f8277c8dea681dd26cfd52a614e91e31d1a3bcf407aff346323cf63fc739666f0000000000000000000000000000000014306818dada1206ff5b1ef24e3155c5ef386b2f8d3d2932947641b803b616d22b7a292955990716fc26813df188eea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ae67150a359b7f1497360ba26902fa1cf68058dd891fb1d0ad875ca5e2231fad50bec298389e69b8e1098afdfb1cc200000000000000000000000000000000120c519c65e96a0e377229c54f0e0d0c86ce059692f19f55738b392bbba65f3cc843ec64ca493cfec990f4f59de52f501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c87f722fd4c2d0b54e30036ada7f4b8c67e7164899ffb83724c347a1faef10b3bb8fc32b7284983a3c36cf277eff48e000000000000000000000000000000001158e938c58c74cff146ae9fdf23c29a9a1fbbc07dfdf22d370a0cd77dc5cee586de90e386e5eb16badbe739286eb7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186a2890d0a9201d91aac640f4f06d8f3eaa51852270f64f08c678bedf6f747243a6079de046361f4e7a4b3166866ea600000000000000000000000000000000041ba7533f67c3c58cbd1e5c59fb9d08a805985d8cd81fd6764dcfd3cb782570ab9133a6950d32e2b4c593304f04de811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e69bf2c806d40bfb07c4ed68a80adc844a1bdcb208150409537ce786109c89e16fd2cf4d06bc3a10960d050ffafdf6000000000000000000000000000000000e9722e0962ffe223ccca06764d0f40892e7de7079113f795039a2b6a0e12b873f08aca4aa43a8301b9189e10e2dd5f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004586444308c3271227817bd7e34188db5d5f42f13f87ad2c734aeb064f84f9be2edd32bd107b1692e33fb4c325a765b00000000000000000000000000000000151eba68cf5134bd9e745c44af0c03685cfb42825ef1ad7b2147613c9db391b06ccb3efbf314fb6a792d4f47c80f4c771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b6d0cd240d296f39729881320f940dc02d84bd002f934f903ef24f5250fe7994a489be6fc46a2c4204a39a0b91fcc50000000000000000000000000000000011aaa09b480f80fdc825dfdde935efac6ddabd85cff016ce61c23f2f9bb9e8b63ffcfd81a4fadcd68ce7e315af45d4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002eea660e91dea9a7f659edbb409b63eae7f421ead0aa5375c91fdb83c0a0fb5f80bc35bde5b985bced69f8b9f76832400000000000000000000000000000000120cc31816b340702ca26371b54296cbad56587a767dc8be15496acc20872301c94dc808840fa3bf4295745d5a830fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aea40b8da6b8a412ecbff0c9eac6cfed70da1f2f17dd3eef163f8c380aeb8519fe2f862e689ec3dbd42147fb61fd4ce00000000000000000000000000000000010cd22695c4d0f9ed49f35d80b875dac008b4c45bcd793f408e92106c060031328e9db25178a8d4dfb8adf7246380b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016694153e799c192cc8837430ce7292b85532264bcf66024d6d7532731de3e73d1fbce5277dd11095f64aa2b9d97791300000000000000000000000000000000050c8019c9ee4c8034457354d109626ed7f629bbbe6425d588b3916c8e851d03dc88040f05057e7c7512299e66c3fa9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194baf079adcd08d95456aa5a6585be7001cfe1fc9b1734568db9bbefd2a938883546f5f2e7920c93455755842f878bb000000000000000000000000000000000b2674771556984065cbbc238823a53a2768fe59dd733d5a82c32bf9303fdbc333f7624b425c12c36f3fc32ef2b8305d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af9d77b68e0c570a1fd928d79ec8f0cdb99d0fb34e4dacff1e26ebc59f9e701d189619c02984ffd8449c18facef4544000000000000000000000000000000000387f1c4431e6feb8ef397106b6ed189a141bd151b42e235de7a328c1a52713ece701ab3fc3ec85414241e09d61764081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6af89655756d3ecb46231f49e5f806f30ad97e96ede4c7dcb781c82a55f8978612d215d0afdd7ac50202e3f493b9f10000000000000000000000000000000007750d2d54f51f23c2c88b37c803dbea64a9185661e5eb7fd4e59a27eab92ea4fc1d29bb6728ca7ec5bad0a2d18c3ea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b23c66227f52dd54adfecc39c56650ca08c55117a17e22dc9329287c28488f2a9b9331c5ccfa9e33cc63f8ec93a1fbb0000000000000000000000000000000007f58cd6d476e97d3cc012a814b34155bbe0f8989ce1329891b420865115614984178e11c5e767f6febaee0123fed1ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8db4f6ddf7cbbf4864eb42f849e4ccd3500c85bf5315387a140ba8739429d96d4a23fb87e22421d04766462efeba4a000000000000000000000000000000000dc66f926177fbbe81a0ca85239df9e760dd3d9cfc736c3af724bdae76e7f74f6f22e042bc275bcb5771e2702ce25baf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001765beefd04e0e855d9b91532d0d5fc439b90fdb8d1a5fd649297ce52352ae5c93941c669f14a29558e6559ceaef04c00000000000000000000000000000000110fbd6e021799309bed6fb47ebf0ae84a4a73c564dcfa5ffac03b69d4d3c17799f6784d8a9a0044b401f233f6546cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041844a3cae4d12a8f5b7654f5b7f2a6e44c8f02ea150b864b2ca5deaf20f09e2745d2ae22a664b53b3234c3ed46753b0000000000000000000000000000000019d3b9ff4854b4b821ce97d32d0956ef4728394eff713248b3dc97189a8195357657eccea55b4b2d83365eadcdcf4b6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a256303b307e97bf2b38bfd80b9b8fd309b8e7079c416aa4c811b0923aea5a6a658768ed006e6a5c1f811da2c697eec000000000000000000000000000000000af45f33fbd3a4958773bec545ac3f1c9f2c4ad527c5e21850055a881493128b0598dc2eaf9be7e4984c1d946117fa031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000196cf8732372f1c02b351ea5b4bb7eb8f0e6409ec2b1847b2892d111da1d35cc8402831313ec4315f68c293b2c7e1280000000000000000000000000000000019bc46d5e30ba4151fa71a564f58aaaa23be46a334aaeb0340b8d11f3226d45ce133053377a64a3a71cd0d37ace67e4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001290f521b45a92a46171e917101f79cac23330a89fafcb04ea83a0382be810b01f28ddd578a901dc04e7ca009fade2bc0000000000000000000000000000000006303b87c41c771dba9620e0d535b05187d495018fbd84245bd199ee2cd990297d58339d94a01f0047a4a2db26f498151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000118030299eef298ea8a721a41dd0bb31be0f86742144c05d7fe632b6c35e9f0c2ccb7b7fd87cac1e5882d43d465c609000000000000000000000000000000000269052c4d2afb14bbbc3394d2f1b49e2a68ba0dd6dc08bc0328468ac77cb601af1719d412b706ee2c0c2aa425592ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e98a6d533a0472e5c15b3e00358ff53388dd1db0dda0b40b2fe210d88cebb2b620093b577f526f3da72314b695f267500000000000000000000000000000000074fedd522430e7db49d6645bba93e374fa45f2fdfea593263c30b009cbcafdff30e8f2c758f85c324f97c9ff0b198b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eccce5aa7eb494ed80550a8c7f2adda1117a33e48d2df367e0190efc3c75372b15d035ad4e21803bfffaa8af22be1200000000000000000000000000000000177d153c6a1920ef73dd3ca6c9794a384e9e52b2c1591afb7d19cf08ede33f82cee31d94c51ff3390c3c0db36284b0261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400dd903191c1508f2c4bef8243744b53ba9735ab327e585dff03f789faf15355a8b3f453ad65b78942755ca7a16b4c000000000000000000000000000000000b5995cf77455ffe5825290c0c26be1c7ffcdbfac32e528541323d3c7daaac8f0e40c6144e34d4bde7ff8fa22ee01ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da474302a6d882c818edd65816364e9f4e6cebbaf7b3d8ea287fa32e89ca363c0193260ace23f89f51cf8831365593f0000000000000000000000000000000014d2b16f2a16e6dc4f613b6bf68a0d1b1b4482157e80eb4b7b9bab7590374e8d392690cce70b582c4fdefe117dbc86361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b06a05803d4eef9d67215351a841a3f1bb0876f4e4e7aac23693cb77e01254e6b09e220cc955ef5824ac7a89165306400000000000000000000000000000000098cc84e0c4445d5f37ca5f6073fea188824e98e986c13cee6afb997536274e2dc392d1c00ef93705c4a6ba70df664471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8af6334edf7d9de9e2a3990ad75a77b3bb84973188b26f39526e97e4b8073690a0f3ecb5dfeafcefcee1643b0e5a60000000000000000000000000000000007992793af8836a975ddbc7f548802aa312b64f458d65a2f7f52e8794e7023183a57164f17179afd7df20d8231e245c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000449443b8d5576abcae6c6fc5450622f4d6a29f573e887b220e6bf240afa56fcd0a52fdb6e9d4f908629f254b99cc7ab000000000000000000000000000000000cb871bd95a10a4e6ca1a7b1ce2c7e750fbb6329237013a17ed82e16212d5152ccbaf3ca3412de407422a96215387af21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a8775dacd21fe96cd3c93385d74b304851e30fe7fe96e1f323b223996985136c96430fa1d0abd10a3ccb60597cb4cc000000000000000000000000000000000dabc1460ce2b684808a27d468d9561f4f997ca6678b3083fbfda14fc83d2984a5d08764ccbe6732b9dbf6860c28b3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ead00552017bc66e508e8fc3ed83ce277c18f1d3f2dc6e410f5b0473dd4ac4627b5a9ed5b5dc2586babc3aebd67137000000000000000000000000000000001681df95caf06090ef1d2a7ad0663176103a988cb7b42d35da7e7603dfcdb2ccba733063b8b88367c58b2e0fd1c569e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dfcbde75729e236db9c1c86d583236606c6cd64019ba89bbb1e6f9ff464f5e861e23224a0da930cb15a28de0b5a61c0000000000000000000000000000000019207825799c31e93faa9e7d2a149ff933dac099a746e60b6b425949d97ffed36dd41387fb7d1d281fe00ccee0c14caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039edacf9be55a33c96ad2646a8dc48c769fb536db44b25864a288f207ab0c6fa28125d3ff23ee8215949368dc57b12c0000000000000000000000000000000011041a5adbe46ff76381b9811c0e0721d2858ba916bd79a0498c2448dae440c6d0a4e0de7fc98d9601ea8d68fd4ddcd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e42da0ec8cdc17b759b568508b7135e56b6b4c08c3ce7cbe6db721f6412445c62d0e6afc207fa67051c37e1d06e76140000000000000000000000000000000018cc22c0dd2767cd0ea2c4c7eff51745b0fb7d1de3a13e249190c8d88f85325bdd2a3a0f39af6a3ee354b150287ec6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b842ba47c7f95cbab9308f121170bccedec09cb2432e2813b4c1ec2a74475e1b3563e60675f2e69088f9fd56855cd7900000000000000000000000000000000195b456ac66c17321eacd7effb38cfb2b3dc3bf02dc46fa0804e2c82e3a4c2d8c42ffe1fd7c929010947a12d0876deb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad61409fc3430c81164ffa466330a75448a3efe4dfeb1e0986a91e8e79333eeab43a14bbb04d8c0d198a55bb054cad40000000000000000000000000000000001cd36e9b60e078478a9fc424ba94c12bb18a611b34db2fffd66d0e670fca127e67939ea71f274aeb33bbcac8d44087e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef61b14a7ba4e88dad298de167a3677a0d971883c0c5f3b615e3de7b0c2be686907cffa25878915e08ce7bda7fb175f0000000000000000000000000000000004460e7809f5de78761dff0665c5b143ad4e45be66cd129ce61d95fcaae27b5517de75c3e54a5b9d5c2b0d11059ec9481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fffbdd8fa56c4eea545811bc7ff61f443b384966abcaa955318f94b4290421e4f48b6309c6e36f7bc0ed2ece304b90000000000000000000000000000000002d67b8ae3bdf68412073c5e76020204600c346d658407b6ade017273cd0083e3b13a80bf1b0224a2fab2d52478a98521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bed948721c0ea417d32d7dd7948f4b551ba8b3274c0253d5b0f359155028caaa1aa4261c778519eb6c3e0976c0d7d2a0000000000000000000000000000000010996eac90fb2c6658bd7924b56dbb1894d09f287d9993294d2d93d60eae85f7bd3c7bb20adb87db0b0b6b280d10d0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2ffaf84b09ca8659844f52ceb1f8dfe2fe45c002103c2b61716d0cb57adf2bca0c292602d5846f5ca2327e2444bbc20000000000000000000000000000000010c95596a9d89d84984a9d0a71bb0178bb5766d88430e85c8e963bdf455de4d518dec9101ccfa81d49f3fb55280db36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000613b1afdc72547e9cc86292e211d30c3307be713a7f9ee701d99bbefc0a1afa55e1c2cf5929438727cbd7aada8dc1f800000000000000000000000000000000141e58e47d82c1950d2638c766c98fb0c982ff562cd15ee4e0ed8c409b7d985d86c984a3735d31a6af6e4f21b948919b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013677a29bf9941995454e887132d2df51b813dd22aa5f4913c3c900aa9ec62ae88c8aabf9313f6494361e9c412aa7cd9000000000000000000000000000000001995ff2214023d62f435ff5defb48a8fd2da6203429e311c688a5fe72d8ff71ad06fac85fca63c18d93ba717756cad3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e82175df164d9ce2ba4b0f8f52a290cbb9dd9620f263bd07f0dc4ce278e0d64c9bae04e27d000919864088ece92ec1200000000000000000000000000000000104ac870a1feade71e8fc2e4cae12a8b2b6abe635b7440f19a3038c25d9fac853cf20fe7a8e3436a58e913c1e16166a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192759b6787dccd74c3eb737076a6ef29b414bc546c0ab160300a4c9e9688d4ddfe78cad120eea9a38505f90c2765307000000000000000000000000000000000303a69e562faf5707da410ed1e788bf3e44ecd70d8754bf22e27187abe99acc600ce695910f7c7d4cb3385330b3fc2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001857175ecd64184455fef2dc8dcdc95f54db3c26b549b10126fecc32190c0f2b1c29683a05f40415b82608a4539a43ca00000000000000000000000000000000196f330f35fa7e5dc109b55b35104a13c35971433ce3b224b6129fd59918ff252563cec08d17784e2e6377ac08d125c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000754eeaaf1d98eb71d56bd2ce724bb4b24cca802c77d57da63e38c358fd4d9b63cde929db2007a77a0b1d6569d78a87f00000000000000000000000000000000006063ff64eb8fd24f46ee0e24892b8d369f6a5f42bb0dbe3387bba8fcf71cb1dfe36db56a4a33ad4ff38c92e6f2bd6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009df67b1eb91ddc9956aa76369086c34a7306da10d5446b793952fc2aa24569751f202e5dc9ad2575bdaeb0cb26cee0f000000000000000000000000000000000a8c8dfb0470d5584c1dbe564f27a71fa9faec1e8e26ad6261d2c10e06201e072aeb70772d414994e7b2802107e4753f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbe495d32115a3328de135ecd0566e29801e9ddb1faec6a2412b71aa24e531a2bc9cfe768d53b3c0f5f438e16bc5823000000000000000000000000000000000782382130bdd522933119e3f8537cb7b424c113f7b3035a3de0f33dbc91c900dd622739020cdc1005fe6cf93388bbf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3672b72f0d9d3075d76eed164c1c021d34024229221c181a139d41f2ba778b4d516d0b7c15cf1c8d64cb85df703273000000000000000000000000000000000b833d35193a4739f7f181a50709e76e35b1f0edc71e01cef6252b095c6ec5772b573e222d446edbfd53a7b25e70cce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004eed604970767b09484a1e0e0d80b6c8c8c5f6a1546e88fd4ab3741f12d33c307d65e5f7412b18473ef8a128cc035f50000000000000000000000000000000016983ef707f7bc2aab8719ffd283b37f619b57dc47be27acf81bf6301075c5dd935114130eed016baa6b82df5e08132d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e1b5cac1e8cbd6b62d6336be394dfff8af8b1c087df956341b4289076a96e0c090dff1b7d91e743ce7056b3595a6e0000000000000000000000000000000013c804a038ada92c5abc0e4062d1ac57c8afa8995612c40a0adc37366f63e17b24772e615962be0f63076d4a304ccf4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014993c56c5507ec226d02faccdb700a6f601a833b2cf5e1b2fcfbecf1eae40703707d5d78db54e5d43a8d3a053559d0e000000000000000000000000000000001882521e14fc5043a7a4028e92b46e679af33e7ed95e02a68e2c78f6834b2f4ab8061d789a5f6fafc1ffd586df4fa5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc1dcf2d2e73b92c25f7adb5709906f46edc7357720592b57e177e8cd0e3ac370314ad1b7124f92ed9d2f21e1a3bbdf0000000000000000000000000000000003c7596270e4f61aeafe91f7f7f51bf197a254cbc8e78fbcead8bf98f3108d3ecf2344a887563708960e9a3374e304c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193ace971ac3cbe335fe577d1c57b3f59d89a249d1b90a3e74737d993e11e5fe5fe1d9b3e1be397b9cb5530d1be6b38d0000000000000000000000000000000018feca1c1fa9924751f39b4f9ff840c056b4f7ae54b60badf8edf3017aa218d4c4bb6c8c3263da84739f498af538916b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155878fee9a5fe514cc8704e0644452ab40b9df815e5294c729e44432dee42e1b8311629f7790b7909b26da4727fe4fe000000000000000000000000000000001637223f6c518518d9cdacd908896b4253b275b0813bf259240859a5e844a076a0fdb5f4c1aca107b4ca8b8819d5f3841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001722e1205a15c5961c642e1d0f33d32733140c8c72bb90f46a12fbf3c373d03cfa9b0cc4d97b37a105ee9ce374fddb100000000000000000000000000000000198869c0906c40cb9ed9f5ffd78f0ff8042142292fcb8da1477869a8e92ed72a89ae50dc7ca52ba33034d56bb4cf77031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057155f7027801412b5b72e64081acecb9e32e03c509854b83e73d2e6289ad570bf219c39b0ddb3250946975a677c1da0000000000000000000000000000000015ffe7341ada9fce0707dbfa39cf1f161985fec9c18cfdc980fb554893e004f8ba7449f9551e5f0e1e9a7822d0221b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008faca2078b5b5ac7c9bb99fd94e093d02689c0e0dd5d30d2b2d62c4e163486c5f052975cda32117f81f9b0f2b0802a100000000000000000000000000000000110716730769de8446141ee082b886726ce60f5ab80fbbe2d7e4bfd3631008ca4232387f0c17acde2bd3af10468cc6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d08f186d0a658731c6cbec73f5aa5143a7bd1a73cac5d96b9245132ceb27fadae2ec78e77895811da336a7d7eedd770000000000000000000000000000000008345b077b819b25e13fbb4100c1f361b223d876ec6b579c5f78b6de4218a0c889ce33e5c65e1d3cce7e81f98a7572ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4e5a96fc060a88284313bdca833681a90580aa4587d1115acf37773746f179bfad612bef1d81f83ec767f2e96410c9000000000000000000000000000000000e735e9b9aaf3659dbae640adb20489a17dc9e618c5e0f086193cb0beaf636d10fbc2e30d7269562506540e61fe25cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e994b407a8fc5347b05b91e40c2887925b3429f41eb4964f518e046bff873d43707c212b9f1849d4a9568e46a1c000000000000000000000000000000000003f26a1ef1d35335bf077717d08e740f2e1fd1b6905c7524128e8e23f8b662508b6e0caa9948ece47acb56d19df63af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022f58be560afb08baf071db85ad388dd95409520d164f5574092f45de76b7545aeb4dbc9e8587e143b3703de46f6437000000000000000000000000000000000a65915b318edc344338043225b9fdcd5f55ffacb7530aa1aefd8a27258e16db0df9fe6b90eab3d31c3ade9ce132a3241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001042273de380c70db6496029650584890d477991fd2e588cd931dddff10e78b243d753f55808ded6197cf651b1419854000000000000000000000000000000001557146e067b72cd33cc8b03b6d61bb371e332c70fe6d93b8edc0b56d8e09edfc3199f1346c80699e09fc810fdf2a3111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3b1f3ad0f9c488a57d3cafbf8bbef233257fda9b8c4c0fa29778e78251cbfae648e669425a76f58a82d2a5dbf0be560000000000000000000000000000000008a1395e4cbe4bf6b81cefd3fdfcf6542a00d9e28d8e1d3b73619d4dce1ea0967c92404abd5096d9c43a96ac29cb2acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddf48cb8c152608e333b89fe72f168825552d63dba4ccc4667e2e8bb32adce9dab27831560742bf3d90980e0d64366a0000000000000000000000000000000012fd2a170c8d0ee456a4c0aae6837539e79c799c676a3a19179becbe2d57f0eebe0e0c30e46cfa6bc5265f78c2c256441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046491d85721cddd56bc9ba9a7d1c54296c9ae2f3e3dc811de0a26b50560c7a423192cf190198df873184840296806550000000000000000000000000000000011d7695520a8777e97731dadf79d4608520233a9c0bb519b20de0abb375c33f376b78da587a5259bff83da1b669088ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2dd654ea142ed86fbb4ca0913ca5367fa8f205b197ae3286b36c0b20f96252359e67baff8c524fc7d2712502f3f65d0000000000000000000000000000000009c67b7b25c5ad1935db10e39720fc06ad2313e6fdf14f34df0daf15b44666d8820fe90ed9198e36e0c19d7180bdd3161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da395c33b26e2002419a93a965881056b59cfacf390f95a100fe77fa1db3493b885da6b45e3ae35077a61d1b0c3ee4c0000000000000000000000000000000008016dc5022eacc7cc458d29bd687654435c7d170157bc30c6d5fab732811ca70c1ca8f45eae1d804033e6e70982a63f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b3b6876fd0a0f1e05eda1ab8060d7e4fa4e9854165d31e44edbbc4aac8020ca117436e099821bf9de3dd462d856ee30000000000000000000000000000000015a08df9e87137d030373100bc2c238a57a109faab569ec1170af939c6f68e9a94a5170ce14938b368758e61517463b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099fe5ae800fdbbe9090e11bb57242b4fe7f2f898e84f7a96c2cd30ea9fd57f49e3a099c916c2e20153501d44158832d0000000000000000000000000000000005af19271406f1450a81d42bc1138a07fa2a30d8295ca10896cdea942abe130624b107f433b1bccddf831c88dfa44f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075a7f387f0eeaf13befaf8c37655d3127f7afa3512aaa1fb0554dde5a0ddfb62b1116dbb111f70e32247140b43c7ef10000000000000000000000000000000000c9d6f510f7b3e7efe9bf87b160d891bdaa359e77b6c9e4c129d946f03b37d4679d5793b97e28462976a44c754e5a0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2539db3c3644236744be7851161929b2c3590e392669379d272a889df6e0835fd42cd7a48608a1318dd51dc51d9a1c0000000000000000000000000000000018771d61f0ff4e7026abb8b12771d9778afa5937f20391cae167012dfba6a16b643e2c0757c8abeeac23c93223f135b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ff8747848f47321a602d93884fc6171d96fe4665245590636adb55ba0b87562ecad1865b66753837ff02b3d2e3dd600000000000000000000000000000000042aaab1c8c24046d6ac0804d4bbdbc09a1193c59c71c79cd20703ff7b5b5c08e37f88f41fb94d72dcd55f19a4a24f1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a25b5bdd29a1856b06d16b45ee6ff8e0c89782c24d7bac83563c5d27a59a86abfcd6e45aefc8252e93bb0d85bafaa1e0000000000000000000000000000000006817dd5d13b8a87bccc5df1a4289ca2e3b06433990fea0b8f21881deb90594801e24b1fc6c6ef2a8a89a210d8905b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c7bc9688b8263173fe9b1805d942cc444c43e5bcb34a52a9964703b1f8b0e89282fe5451f1bf367e90634b047197b000000000000000000000000000000000518dd1424a9489b56e90cef7076086be6d9bbc1ac98e3cb0aabf984b8f99b6bc5ead1dbc581fba00bbdb6aff0454be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c0e9dd1a3ee82b771a3dfca8192b15447677d5d772522d1ad2600c497b1df505cced652526b87667425d2f5c527e0a000000000000000000000000000000000f915a04fbe51552ee125fdf44b918130a510d34151f05c29fa4dbf9b3cb0b13f0bebff87bd3822431202ecddf59a84a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dc6d3a3ef25835b6ca577a320faced7222ffb960d0015145f282305d59a722525c10f247a3b30a6289bc45265de70b00000000000000000000000000000000022e088110173dbe2f535ef887c540c5d94f6c8d342fbebb368281c5c9861fead1a1c2747999fb7edc4d495092fabba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f05bbc6490d499655213e3b40fc3d2322c6b586da991164ca2800212d88345d9663f8a99e043c46b177655e9b1dba40000000000000000000000000000000002beef6b052579c4dbf0a69f55a5251cfced3a4a2259abcc256d09e8808bd7c404fc832558b017f82562f103eb3fbd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ef7a65b15a8a385801344d7c731c7bf33b8d94bf500291ba8708886cc1a0f5df827541328e52385c1fe0b75bda5c0000000000000000000000000000000000700de6e48b9b4ced185c0883d6fba32b4c5abed54df18732ccd5c27448ef0a52c6c202582c84cfcb6e1ce9c81fc8c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a521958831cb4f4b829ec8d46a19147cd99a38bf2c3fa3c48d7f7c7d7aba877a6025086e522121eb2d6ed19fc74123000000000000000000000000000000000bc97e37f397f1b7356493a41aadf04bdb40fae1b3c257c0ae96f1be9da655ca8d0b8127b2da7f67796359c6d6f0425a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000633deca8911646ae188660c78d29bb133583179457e762d5634ec7d4d09c9b4c2124450436c93cb8c62c2da5d913b9b0000000000000000000000000000000002b237bc619da52c43b982e2c98faf898d14141532292b70f96375acf56fae4f09ea08a5ef96fd5c24e8e211abd9a6681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381b8925bbe1b08a4e5b7b72525665c271a9dbc603dda82f0281f6fc703c97b730cbfcc4a884d7c291c41ecf46cd05b000000000000000000000000000000001954c80e47b2fb3c7c3293217ff22384f978f8bd2d29a2f680090fd3ef4737c5bb848bd5b244cd0bb7d4dc8804e1b8791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179b16b8e7f01f01b59957e6503de75594a3aa0a81526f3371b19f3fb1d1abea621499047e8a4c978961a22a9cc9c697000000000000000000000000000000000b4e1bb84a9919dcfa1b420e22a3de952f93bbd430501c8c7051cb49dc606e7758254b5232b154f389d13bb0584093841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019112066c6adeabb8f6d1ff46b58c46e7f869ce4d3ef1def9153329d6448f0d1e7154034a0deac6ce213fa54747a13060000000000000000000000000000000018e6f5e3a57859f9d670c5ebc7c69e0a41103b2d915979841ca5c172a69e3965f41dd2eaa36d6f3ea8ecca3d0e34354f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afac7ac38da62b43ce70efb3e158afba0d6322e0e7fec41f4513ba95f049cc1ac8498207f118dcfa82718e0449aee690000000000000000000000000000000001f4aaa8dc3df31fe8887c43048997a10bbdddd76f112b6dd01ab14a287b3841a7f9c58367e0eb9748122a9a1f0ee9191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c5e74635eb8b85afde9a293033de072d6a507ee907c3063d9388387c2b6fee14dc91d0aec291f85864d0d89fc257760000000000000000000000000000000009126a7ba2614130d5b3696b09e36a68dbf71165ec60575545b3bf24f2c6f63a346cb0a77624ef142c44f96b525370431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fe8232738a914f834626c0d33aaab43bbc174349733afa0bdb72eee7f8a661495ec613c4e92601f4a79af51c54ca400000000000000000000000000000000035474535602193b9b66722d6ab765cb02b67958518ffdc85b67421662989ca6f067b8db360aadb18305a273d203a4061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141c53423b58bb9ff7d27ae251be5f0afdc50801a7df402b88fb6f951b834000b55ede5e90b88b06675f3e6e8b0a2e6a00000000000000000000000000000000132cab43b5d96668129142bcab9911b089bc65bb6920de80ba6d69656f62a125882ac8eeb524dc0e75417f77602cc1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dfca23a6de3aa8473ddf75a31b5fd7cace7034b756f85ac86fafdb197b1c9193fd7b731f6c21a5b3e7957e6fc57cc000000000000000000000000000000000069cbfa0f07d34318580b2d26eec830a5ca9d91de32f115c2937c602f8646fabb1861f559c04f68517c944828af7fce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd217a250398567c35150bb5f54b12329fb65f2148bf0fdabea5c6fa976ad94a48aea2034ffbd150a86d645cd22026000000000000000000000000000000000dd36f8fb3724b73cbe5390929bae16610987d9465ab444b0396aad86b0abe2635b8ca3c4f49dd47c6609caa9af53b6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001443851045e9ebcbf325686f279c61e47887fccf4cac42bf16a25be8f23858974eebd2b5b4c68473780fadb5328aaf70000000000000000000000000000000000c54f60391ce8e8bf5e82e2a07e001b6e1133b85d95b2dd46b3e4d865dd91e0a7d82ce8e176b585759ebe52de978b9131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a21ae14c0577411929b94baf44b011035f43681b0687dabe966fa4a0c536e38ba53d7184d4386a5f2d3546a0d2fb9a0000000000000000000000000000000000a1515070e8dee546d6642628d11d97965c008a8a77383897652e0530fe98cf072983c28509bc033d3a655fae26ccf291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011018373e0216d38775b9c01a58eb68356631a4643efb2bb5686c607105e32fa4ac30fcc9247f3f6d23be44fc35b70cc000000000000000000000000000000001730a408d06a4cca57f2d16321667da3af8f22c0773a00df27d9fbae3840936c4f9e874a757cac4d8a9396a24b9b19e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001937df44e0a722a2f0bedecfdb54e44951624118e6fbb59910c685606c044a6326ca1bcfbd4e8150eb5be3284d74624d0000000000000000000000000000000010e11b8811238a4378340f57c944bcb22cc5f90207ec8638c0f8d76eb9caa538c4affcf0c0cfe11fd2dde722ea3f85661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001569bf45aa71c78ca97b62dd1bbf0134341b9e68a7e7cc32bfdc4d6ab3bb673ba55573630562882bc178a72276acc8f40000000000000000000000000000000005c9785f234150e087d570fd46649afbc89fd4868e323d9eff3e076aebce2e9fb09c1a427a7ed188b820586f3a7201fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168bf81438dd0011239dcb839d897845400483951c4a7ad18d431c081be517877817ee779ecf137c094b3d5189f375b00000000000000000000000000000000014df014dbef9ba7efa763bc7811437de082e6a53f3a5cae8d5d2198d1b3ff503c34f646638f2858abfc7e00a223ebfdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c192e98669be2dbed41f8e61c45b13658ed0169c5e5f80e60a1c92be21dff495c8f63c6218f3953226b21108ad159f000000000000000000000000000000000d13ae4d1eb8f0aa2dc32946d4140225a214edfe841bfbf1fe8119c5e6062133e490aad97ab158557c93603d253c29231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015066911f305f3581e488d39acd4c21c8fb732a306133f8c26c8b3386a7aa5c1db92c6a5f90663ec1c2d10637988a6b300000000000000000000000000000000070b9e1983f2e5cfcd27f6baa424b19c5088d09e54a600752bf9dc149f38bbeb7c2f3ffd4cdb7f8ebadb66e97e6bac7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053b262b75ac965f67e3a4426d03f2d3401b6aac0c848564098c1b0780fc7d5ad60dd68a3f4600a16a94de7a00c60b6400000000000000000000000000000000170e8be9139f9e0cc9f08a49fadc38e04b76314dd66b8b7f87a855fbfc73ca305ff0650cf9631548d914465bae21c6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ecac5f8a09bec5b728dabb6a42256b80e294552c9882b9fef9fa4bf0b2f1ecdc4b8ef5b7b5b58f93988c98d3286eea00000000000000000000000000000000128cd3180884d6c6669c807edf86da6249324e75207db8cfe3c0dae753a9ff91801e44680cb871f8f030babf675247b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3c055d34e132d2437401572217144d5f802b4066ba98bcc6215d85b968a2bdd4eb2fe7a869a35289af0fecc44c52490000000000000000000000000000000017e2cf12c7917a33588262b988c39fa208abf79a19e6a3c8e72ad42f0aaaa3310d6a7340249eb75e181513fb069e0a961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123915e8ccdafa20d60e1462465d17c1fd127825704f8e73976a4e611a3d3b8a85fbea6a6cf839af569e0ebaaa07d82f0000000000000000000000000000000006e3ff74c0fe03504224bbb25137284c624a1efdfc4bf1c790716db26dbfc89df4488e1be7157c535a91aacdb886abfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010368947b850fe7f68d38577f798d9751e5ee3833cc1f01f7fadb7be6fe1ca4da2ef79f0e9e2c731b4dcff4c2db88f750000000000000000000000000000000016e387e9190f9ad95d0de690a177c008cfbd061da000d3e9047b21c669be3f140cc93aec8c03d88ecf4d84f7f8d821631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003af12a2ccdc7fd35105e639d1524042f2e41dbbea20c993222ed19fc50e083770751eb23d43acf8bc882dbd2edc5e260000000000000000000000000000000019727b23d3fe623433764e4e31650f300dfbdeb2c0ab8ea3faca9331a755ebc520171ab226d4e68badfe15dc7dc646861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d0b066098541976d496948e619d2d915016af5e7da9e1d98ec860f6d1d6a011cd5754a2269fe9c5299a4f1cbc447e000000000000000000000000000000000b7708f4bc17411ff67c025f55e495cff8fc0a98ad0ab65f672f6c5eb24f649e5c05156498109303f370845cd3e269c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d8e8033b4baee25656ec226ff9e5a833f5d48ac075dd9089b8d0cd67242f39f095a1e7098418b0960f045f99e8535300000000000000000000000000000000128e656237d5d5489dba7acfcf261137666cf501be256fdc7add8fae50796b312eedf403e560aec343fe7b6958f40c2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116973b23fab78e6e2bb86c38abecfa20e1caf5df09f410329b7840fca245c444e5631420cce346b7b4f596bed17974c000000000000000000000000000000001412ec548a6c79a9615d6bc1dc7bcfcef0bc71ac811e6724fb88d8aa87cb187fa38c28f864b84d10ac21887bc4cd79521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004494662d055e684941c308795ff2116464e0cab72ee9fa20a3eae4ceb4178b17437f3216102a8fed95ee1e541862bf7000000000000000000000000000000001895a144b0621f1ae8a6d624fce43102ce5fbc3ab844d39cc0f822b0df2e5d58f2381659b9d8b5abcb6a4f5b0dfee66f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f959ab7ae43642b043cbc6877d24697a4fb324df8eefd065a0ac2da6ac53489f1ba5a056540f344879a63b2abf16ea000000000000000000000000000000000080c1956342b3777067b607dc5fbae53c96e697120ac7e158cdcf8266b4649215a095dc5c3c21144784f4b1024982a081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a09ad646c9f1ddab48c1e8ee2819e19cc9e89c2b22f85de88793c2c21e552fde407422227b5515021bddc0950f52920000000000000000000000000000000005eebb8bdea44fd2cd4f5095d5893330fa371b87ab269a19e4714ca0b25227da83ee5035a426e0fd07f8ecb050194ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001265251439d3b1989cc5c1d7b98276c4f75decec0c78daa260161c7deddd4df418c97c746b6ec9ff6188302dc5c84e00000000000000000000000000000000105fde2f4a81d245db44cdf900601b0780cfed92764194ad11505696978db156f0c239dcbb2ef23b961743270724ad641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092f2122130876b6e380765b50372c9f2cb18d8b4ea272e598ee8b55320c863372d418fb9b591dd2c57c71f1e80b030e000000000000000000000000000000000efacf890803ca2b1920b5261510d9583abb12aa0e1efc820c972988e2a8912bd321896fdb911937b5e1b9000e82a5571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a08b9cdec028d98bcfa263723ec32bb283b191f6b0ad5b8b6795ec7af4600209e7ca17007252ad79eeb92e70d699ef000000000000000000000000000000000cf8bd21dabb69046c657d6e66ee81597304316930306d8189c7ccd1ea2a2b9c0d1bfe8bd354df765c509bf41e4f34261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a19c784f15829810c700b41b38e06b441025802524593a186c1ecf58e761a99dfdf1a1aa4a4ca80d10a0ab17fc3e0ef0000000000000000000000000000000007b74102cff63c066485b68b6374418b0051b896756577cd415ced272858408550c1f4669d10282bef2a732ca58e8cf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfa15cc7baeee6e4240d5197540483e79b4a2b7d100d1f1f3777643dfda5313c7495bf21ce8696dd78586fed65d6815000000000000000000000000000000000a656801969cf36a3243c74892a0bfc923cf813ad824f3d2513937f6ace4a83c8efae3af9175444dbcbc05348ed35e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020b756331a997e91011bbfdbb490aa700bf26cbcfc70fbe029ba42bd97990017f24f2a12851539865ec312994a22e5a00000000000000000000000000000000100fe7803ca3d31bba156db9147c685d5858bbdf8b34accb3dae0402b139c29eb8068b51e5a36dd1177ab8321457027d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bc4375e473a0cb6217bc4ebae061fbaacea053c57d25b3f5cc847d245abb35c3ac165e679e71a996b936a7db11c4260000000000000000000000000000000005f2a36f716b481d51deb094a3dbb81452918eb243da53dcb4ed200aa78ea03ca4559e0f1819e717cc66ca76b9a817f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d9a85a0461845785e39f8f56bd99b1c3dfa89fe6335530523b38649a62448961f340086aa5da123d86a11f098e7ca3000000000000000000000000000000000576b7bfb6a2e2b11fb515333b890cfe75e907ab4518d3d60bf36683eb2981d5eaabfddcb809888485b652aae7d4a7f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229a3425c1cbbc4538212633fe88944df87e5c71b99bb2c8d55a88191861fd2acf21cb5b4cc058ae84c91b8cddc9d6b000000000000000000000000000000000fa86b9206edcaf427b9432ed8a62106f27cd466611dc2c149af246eda8f7252d1537074353cfedca6e29a426a7f546c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100cf68390412b3d6f7515d7d8f88b1f6a3eb6456ad911669e95ab01d304aa81aa89879ec15c5bc3f2cf24a5409caafc000000000000000000000000000000000497f45ae5a965cd8175959b2d73e647dcee55a104c5f89c4ecd81f9470e3bf003008fdff453c57a69bad46b5d6b0a2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006816948e64a32eed42b0056102c9f3f1a5bf8214f8718a19f8323fd59e67a1ccfe2127455b21cbf5bfd08124c6dbdb30000000000000000000000000000000009225e10b8a5974826fa720d578ecd6bf7193f8c91675a0043497e2bee9801c7698068faf316ddb6e5b77fa491b22d751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119854734ba80a316abd66ed2d220ce40abc655791c58f70a9c20a9195fc164f72e680e1c4da4155c00a4b078d2a0ce00000000000000000000000000000000002fefa172cd9d62512e1ddc9566b6f69855889281af11701d7d24564ba178e6bd5fd7863eab398c0c21ee4989ebb4e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001172acd67a574da584c69629e3d0749dea49a4bb93b07d0b7eb24f0a85e16614fee96d2ddec8fa44ed767083c53035390000000000000000000000000000000008ee21576bdf5b2e1606962dd8fcae0957e7c722d31832091a69cbc2eacf1590f8ca5d3f46b4fcc321d5a25f066a17551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c221a750819fa7d92b538f2cf863a43cad81c6621dddedf81f2fa748b2563b565fbe1cca539600ce0cd452250bfdb00000000000000000000000000000000191be772861050cd4b68504f7e839db4c830e89d141c8efe5b063c9bf0b1e2ca97b0c0dc77095841493c4b29463102141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fab92dc56271f5431772d7f4872930cccdfb1ad94e13fa075840f6584203b9d3abe769fb028b5c8e05ad9ba8b9c73d000000000000000000000000000000000e91a61e13012b3f1f3ed18b7c91eb4deac1d659c7da3580469178d9c861104a44cd73a930cf9901e770b43a42c0d6fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc82e3d7b9a135c3eb80e84bcd655885ce42f92f50fd1c958c503fe9ceb7e7daebe947f915b45968d1d0a44931ef91000000000000000000000000000000000158a02157c32faf4048ed4ae5312d5a48466aeb435efa50b515ac32e88f4578a02788298215683a3dba8a2c30648c4321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001520d4658d717a8b9fd64bb5f23dc86d7d75600be05e8e6a2c31fce815f42db4e30aff05fe16e3f3a0b2772da8d99b7a0000000000000000000000000000000011048429fa0623f549828457db04684a413436c17c551c897cb9b325ee5000b05d67e25a163b54be7c7ec558a6a746f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b0b07ff4f07c8ac5b9c162a1bdcea4efcfba8e4f961adcb02a7fbdce2bed72f316be3b3ea4ff72c0b06261af247e5c0000000000000000000000000000000010468f3d1425b239418f7bd8e70ff5747d85069ca86d14d716d8f54905936203c4f11b26c51cc50d11062e8726f683db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019be99ac80ed551520a109e83d854d417d18298fa8ec7024a0b1eace829334d0992a36a069a424723cb2fe3d8512d6b000000000000000000000000000000000180d7ab893fb3f7b1f4cc7454a53e9ea1e67ccc0fe659c29b460882168b7aaa3069fad7f818ade4295a9260190db9efe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018287773c452dfe9d64abbe69dcd21027764248a684a40f630ad106c573de6037fc8896d2452bea8572199574a6029400000000000000000000000000000000139d571255edcf9a8c26054d6dd29da2e4753b8e2048fdf058290fb440c4978ab2dd19daff3303abd4e147933a99df7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036c9798a049b34196b5eedd9df22399ff1f02b0cda65b58b87ddd9a8e36b1600f2242c6694030940737ba0eaaa7a630000000000000000000000000000000013aa2d506119b80d0f0637907173705e80d93c51a5e033044b322c87df88029df2246de09394a4fbccdfd02daec264da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807eb8f582ab3f6f4af8d1119ca65f39ed44873bc8f05fb3e24071815a33efe6edae9bfd17baad7be38636e32752d7e0000000000000000000000000000000007d169b2363d7000d81aa036fc16557dd7559698c26958b2a30a4c312cab5253662dcf4a06e4dcf4996aa39e9fa470381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000795e084ac510f891bbba776dc9c89c3028bc5be7ea4e8d7f15c7b2b70f73a6d7ac6e78e33955310866edbff5a137df1000000000000000000000000000000000f0e02a792452ec96c0b869c92d095065fb218dcabcd2e8286948dc51e573235d4255305ce8587d0f5038f5c72aee4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d49432dc402de6f21893d9283996a259d6df2a7da5d218a51a4c6f0cbae4938f9352429f7b5a8fd5052ec86c8eeedb00000000000000000000000000000000072c2502b05bf02e13cdb15fe9c457fe611f37dae396f333bc161939514934743affea10ffacb0673d0085a2f5f9496b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160c52e982cbba73b7f70aff84820e5d8d1fed4595141bcaf8f8ef0e5739bf73a0283bea40c9b8471768b08f043546e800000000000000000000000000000000056617d5dfa539f59ceb25f607dafcc9c586f67635e47f406b67c49024b56a105693d39b2609a497f7c46d75864a05471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cb3c2dd83c9efd78945607c18f02c872ada20e592dea21315e8d99af3f9b88b68ab17d4fc25b8a43404eafefc979670000000000000000000000000000000011de8e838d8b5807a5a20edea048ad6a7082965e8d6732a902a2e97c40c80896d1f9dc8b15d8ea3712aa04e8020ec3891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070bc90292f5ccbc7e68588089a117743a7dea99aaf4d249f8e0d93a00f7b59451966c00b31c9824dbea3e30f2e6596e0000000000000000000000000000000011e8d0194ff0404f9ccbca22456ede1e3e3b482ab9e4636c8af477cfd3102ff89c9af9f1ac25243575520d29c6ec00d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ebdd540355987212b2fb9cebd71a9eb72c57fd1eaf95ccb8e5b9beb65da2ead0fb6e808bbcc3ad59c2ead2f36353bf0000000000000000000000000000000000cab74266752d4f33f41abed43c67c2cad5a83a201c91acd282f1e2d837f72d52175b9c1df7a57567d01da4dda8024c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b073df5fe8949a394671de49c17c5277aa1304c9ddb673b6389d1e3c88741d7a118aec6f32c2238d27adb1bfd115650000000000000000000000000000000005dd4477f898237f76aa803efde2533088280d503ed7a02c69135a1f761c84520ce675c3d2cd973d12255793a58abed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120d32237fa7d4023f039eaeea63175d43534145bcdbedf88832f37ddc8b0b48bfa4738cf54a6557149307722d1ac6c60000000000000000000000000000000004cd2b45abdb1d444205d2dd606ec840112b8d1c7bd1baecbba996071e9ebad4ebc9ab0d8fe11325c57859ee535efe751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109a6d6021ceca689b98a50e48502681da366be95d584565c911582d0ebec2ec842eec9a8c0ad4c9526deb19b1c8861a0000000000000000000000000000000014741c0fdebdb08b450183b36b1ab2f26e8749d5ed34c4cb1155a9f4405741059c249de17c7fc0867d6f42e145e056411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e6c05e9e850a5ac95723e46054b5b0658adcc1be8c0900f480946350b5369b15540378ab55f8f3e9c4390b953360da0000000000000000000000000000000012505dc029a53a509b845a6eebc12eefb09d729aafcc9797c27acdf29a6760c6547ee42c2fa8bfb4176b8fab2c88ddac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eee87a030ca52f7af02a50e97f0b0ace756a825cedb2a02ac06fbad9016ba46e7208577a023b648271260121f1147710000000000000000000000000000000002cfcd74931d0fa72ef3a39fe76d4e3f3b63b441a7783575069960ccf00c050fba55ea8c8e945a9b4437fdef0f6003721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c589a1fb3e786d9eaaa56cba34d51aacc43dfc9d92859654a90c7bd4f6eac4a2605f49ee25a889b1043c9dea45430790000000000000000000000000000000008b099b6dc9de481649e442eaa33b4a4d4d32223c38265c26cfc02c71f7c43e41e374c1a919d2c2909793e7239ed80ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045b341c66de142896199f574ed462d10f7225932d83b06376669eddb042a4f82e6edc86c7fc359096718af2bf37714f000000000000000000000000000000000a36da6a457278f263498459ebae99ce6257c920dc7eaabb20ecf36b24514e2003e6dd42a45c4cb685ac38b7548b3ab21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001950ed0e0acb4c3765f8128cf778ee58067f9d4cd9be955cbade4547104ccd19e16ec01b91f30575fa39e50c7b2bd9000000000000000000000000000000000000d663fee557efaa61296e20b547f0f82c7449ca19d4f1e02c9367352cd763e85479755b57231bf5355402af7daaa8e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b3efe0b861c14bf3a1b50c61ba56f29bfcc8a67c04c24228ad64f5964a383fc658c4f11be606aa22856c7cddd516ae000000000000000000000000000000000cb3531054645600fed1ca0a0c6b3779a51d292a6771cf16de5dbc698d448a844746e4622e6d472440c540d1bafd97c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce7a0bb51cb2eeefad7ab2f1f6f20b330c0f3d3a1a6b94244d9db4629a49e7a2d370d9204d349d4fb1729d371f1819a00000000000000000000000000000000018fa3727cb19113dcce338637c2b2290e9ff1137161d14dcdf1a1bed054f7a4711b50ac176352daa83add7cae2870fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a6d37dcfbee39ae8b0943980996993f47e9c4dc7db34db03b6d24e1d457fe6aef4517dfa32ff63528ba35dc6f9950a0000000000000000000000000000000015a229f9f528a3dee397a3bb776bc04fca4eee97505f9f9e7f218383575b22f5475d6cb4ad0376e035be4b324675afc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001323a85be79169297cea9daf0368cef178ce2b133e093c91e9c9802e5082dd76b804fc7be55548986761ad71fc058210000000000000000000000000000000000697222d456a45bf05eb61516a82737afc133634a069c5ce957b3371b3933cf75b83b29a6f31f60d67a170a7179662fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001690e91b9fb7ddfe0ecd191b6fec8047409a153f2e08ed3d309b0f6853dbe5cdf2579e69c27f354ba205bf875143916a00000000000000000000000000000000149050f172460ad12c7ba3aca01934acdcb8e51150d917b4b696494376d20bdf8f3b2a60261978585c45cbd47313efa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195b76af3b69e7ebcc573228abc82c08f252274cf05ab89cc5a6d8c646dc22f340d1f3817f503e7381d8ea8d72b313550000000000000000000000000000000013314c65e92ea61dba1e415e5d0c46ba0695b0c03c4c9905ed3c629d71e2f16a479c85424d5940871d53ef17acc221331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b86eea0f6fa9681e264acf5c0290a950ad9287be412d4715d846b0bb1d1543605da633b7299ce52246c75499b75bc64000000000000000000000000000000000a81b45683a01431678baeb7070c0c903b92f1f96b0a2a5d896ab7ee6d6d6062fc07b387bf9f7dc4f093f49b0ac06e411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa61cb0c9d6494853bb501e1a7fb6689f970772b8038c0ab3ed17eecfa28955311e386ebbebf8d160feb572ab85410d00000000000000000000000000000000151b9ff63869c97a5c385790f39b440ee1c72de16a576f82f9c3fd80f9de39bf481456763729667cd34c08bcb0e024a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001586935a07b819a547018adbe63b0a3bad8c1636f7023ffd4b26d07fa540ed02ac821e5dbcf3e10e63f7d348471c5bbb000000000000000000000000000000000614232f3dc6820cdc96eb56843c0aca376586cb801d0325e5b05451359c85f810d8c63c9177f2d9ec744f1626386e5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011de7d147588446d75904da811ef4e85ab0c8680f688bf04499ed7e517643e07d4fe7754dcec9124a2151d4f771464e00000000000000000000000000000000141b756e740d973304f890dbccf8e197b0a1bd254a9d0e1b49468b37326d169afeea2d86baf6cbc9ce0f09967b00d48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c97054494d055e828247968f8902380a8687e0747f2c8be0ab56ddf58b75df16651f248a757925f9ec6dc218bc87d41000000000000000000000000000000001600e069faf4fe6ed355a948d7b9f90d223e93eb26e34c2248f17d25242b88cedf2beae3242053b381b0361752f20ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadbe674fd18cc4d241c6643bfd5120200ac8e0a6173e59dc52add259b91ae3337f6db0662ebccc9fd107d7c749079200000000000000000000000000000000139079c7b506f61c943e5e9a861211a5cacfe42363d8cef75ab2ff05e6ef1b316b7fc89f1cf7d7aaeebaf600ff591f491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a909049ee11dbadd7bddef177800c5023ff19596988266d9a27bb740cdf9ea74d12a4909b147834a583b5db20dee6300000000000000000000000000000000150dfcefce15869fed2331a924c77c723fb464441e664ee25bb8ffdc0cbb505490b0105eaabff24cc3657845e8f632201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091bb0a0f2e6ed30dc8bd6b185d4597151c5a0c0650170c0da53cd737bbc748f015c8ea2ada70e6006efe60643d3ac00000000000000000000000000000000005dbee65ea4f90fa60ab702d1f136d2ffe9e88cc46d06a1ae0f2a08b7423dbee61f4102346d4fdd29d732fe553d854151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff968b9460d9e9b0123bcaf5e7cfc57f4fed0eb5f50cedf4bdcbc6b58247eade79aba316e3809f1e2c9598876558c3400000000000000000000000000000000198f6d5fd4f12978c8ed50ed8273d67ea2c28a432f25a094f76e5fe9434c350beba3f1d93c5b1ed5ad88a5955410d0991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014048b78b7a1132cf3ccfa1269712bf5e9cd59488797c2ac6c4c26f3bae4e3b4f3050085e9bbe41954d10ae5a9a87075000000000000000000000000000000001357fea3d344292ae65d10d92a1123a3ef133d37374bf20f0f07e31964b559035ecf1f812aaf64309f43bb51f3a4e5801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001199e39255f6208f0bdd309af7ab559dec39e6836f608100c7c3477866bec058dd76546f79e0fb5e22fa598575e0d2f4000000000000000000000000000000000df872339c6cd3ca630ffb33834075a5367602962768ab890cdb2db6784f95e554d99c9adb713aa206c96180ce1512fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000195ab991a36c912514ca04444c0d44fc3cdfd0e40c0afb9dd310fd712ea133181cfac99cc49e898a07c18098f05721f0000000000000000000000000000000000f489b243e09e54a48a589c15ca823af4bbee5e8afef6a45b89fc0adaaa2a9a79bf422b2c610f77550071d3285078a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011391c9a359c9c1ba68687efa2bc381531cdeb571f586c8893e6449befa4de0886351dd6497fc9cf9a29c96be77594ab0000000000000000000000000000000012b76ecf7301cf85f8b6e4eed83ee03a37707dd8fafbd9c0f2e5bb01d49a5401abbd2ea6d4def405c04fdbf58dc71de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000044e7ef1cc2092abeca7516ce3815c1697d4cbcd3f19d41c85902c88a4e686b77eca7fb5a46e03aea0e4ec6ffd70504000000000000000000000000000000000e54ee755b698f7c026d94d065ba1094e68992afbfbd89e2dd43e17784cb5a713e723a15bd96b7bcb017f459ade54b541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e9718bea2e11fa01359c4a545382a931fc177084f756971e2641096d9254565ec4e02099c8b1be2c4516b5c9e789700000000000000000000000000000000127e6082d5f838ebd676e60fc6260e007d66fa3998b8c191ffbd2acdae0aae025fefe0692828cc869fbd308a23e5596a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000257559732d99da8f646a75460f143a91475d6e06d4a52b2840afd18325bce52727c5b3cd4c4faae5fb7c9e23daf6ce3000000000000000000000000000000000075909aa15aa574db3142605772c43621f75d72bea53edc701ed118a5f5a793d46c0cb07b4b7dbab5d8912c1863c5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060dd4eefed2ef57a59992e5d130ad7dc379239fdac34513049fd25e21b778d66d4b7867cb5047bf76c4d766b0f97e6600000000000000000000000000000000056a52d55f4f5944cf2538986388a406a8d4d1037e701488129cd6cb88ae57521346c79c2d1bd70fca9a20093e7752e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162105c0737d011caf032884a379dbff34dacfb40010a49d22c47b349fe45354cce0b32abf70a2fe9d0d39eb6ce8dca4000000000000000000000000000000000a77e56ec90af91ce92400fa544bb6ef83de8261cab0f263e26e87c9f9c866ba16b5c6870dac9f4f6bbdb74c42c870ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e99282b1da5c274df366840f317af96b438a488eaafb61c3c43cda62edc175b4a7daa034efdc94afe4b167e573802b1000000000000000000000000000000000ecf8da5c49aff47c28b4685a815806ccf0a9a194d5e7995aa52790a6b33c2ceb52b7b59c7b31b905fe5818fc51cd1941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cc32910bba04d090fe0ca9912dbcf26f8b1f95d3ec65121a5429413984a82b54840d0f252e4b6a57bbf26a9e6476660000000000000000000000000000000013f1ead087dc89abd71cb221ccd6b33c3c02f044d5a542117cf354211d4996ec9350370f1158c1b5d0fc7763d007ba3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110b4aa749e6d111899f08ed0c1993c77bfd9d638957bc0aad18926e457103001b5b819a1d62a6807ac78949b278f3260000000000000000000000000000000005c33a3ee78d2c0c3c447c2af5b35f8f44854549baeaef72a09dd16cd33fc7317fc32e3ae7a90d94afa202fdd53c16921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000885bf363dd2914730ee942da5da479a488259e72c75bf543a2b97a6975601d54a871cf1eddac034e13dda8001b258270000000000000000000000000000000006e0052b4bf4cef0689526b6332732a7f61d09871ff59185e0da997cfe5bff201fee5ceccb09f9d6eb1b343e152038651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b0b93c63e99f45e47ea1f34726950a059cf373cb109b8cdb279fb9db2af5a74f0702747cf92e6d910a85f7e8d223550000000000000000000000000000000006e95fd92e41e30a55f00db40e3b77cea6ad62277a63b5de995f63091d4092720084b8c91df3b7609ff27d6ffe1c02fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d624b2e9c019631f3fa0f5579f8cda39a840162ce6d64934f4df851e4cf844081d77924bb0312380f7469c4c21d1efc0000000000000000000000000000000000d978ac41f054eaae0ab1e2022e1e675d4e157b04b9caaf8148b0edfabe591a86cd6000d8ecf58b7719e3946c8d92d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058464c26f0bfe8982c02a954e3cf15d433489a29f73cd3d0a99ba7306ae467e2e31de7dafba19e2cfcd7cee1794aee00000000000000000000000000000000000a836ae57108ecd890ae8e53b98a13d03772ac8e7365c4ee3940f6bed7c57906f9a3096548b8a135d95edfaa7c945531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fcc4c28705f30bcba3dc8f21f50f146c94dcc1ea06db07f1db4bf8e23a2201947dabf410523989dcb4953f0f3d84480000000000000000000000000000000013844a44c75ad1f3bef5826bd8cc6a155c9a1b1ad55c2806b355b235e79bf07ee9f89e517bb020f483b668c2536850771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026988b706ce9fcd1aad5fedbe116b133c751501136e3beccdaa6f348cfc7a3dbe1f5e6ceee4c367130ce863b5592617000000000000000000000000000000000823b0b866fb9b5d56a5659a92c649192184bc8abfabdbb65962dce24728ee6a88441ad9bf6ff290f3557f2d34f258c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7ca17dfe1e8e6c256eb985edb81d9a4c47b8370aa6a694200d969c54e82d10cde63b6f12f315119e2b3f7afe5b92190000000000000000000000000000000017e7c45696a9182677cbd4214250b08b8a0941215315038844aaed01f02f23676a4360db38ae88e7be684d505999ab1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155ba51edfd06028e1e51c04724e23e9df577e748f264e8eef61ebe232104f5d9795aa56ab1d7e1dcaeaa1e5979e081e00000000000000000000000000000000126c5b6cf0e102c92bb298ee6ab18822870192e55f990f2cad7aca1e710f90b8e24f2d61dae6e91d5d360d8e28db724e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121eec3ca445ba81559fe7877e5f205cfc2b5c257b01b3e0382d767cef4c52a2132741332f3c270eab22c7f3ebcd2bc00000000000000000000000000000000145aa5d02f86061238c465b3aa0ea7d96f55e821d1c0e88a8718884069cb16647cc6a68fbb0b8c79921ae6bf85352ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a5de1f0efc90969309a4ab3b759e37bf3af9100693de0154969fd1a6f00b71cfa4f1a5939ce830a197816eaa63c54000000000000000000000000000000000a79d5911081e6de8f1e8a251e9809dfd5b474785e33efb536b8cc5d5c160f2262fffe6a5a0fd9db64d3044ec08a8fcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b653a35f69f0071a0c3c5e1d12429634278bf5e30079580c3e30dbbf207bcaa00946893c3ef0d9490c74791dbae222e000000000000000000000000000000000fdfcc4843ac83643bc9813ed57414804b33a431d7901e9eb8f8a11c74975277ea48923b69461a4408e0a01fedca21ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136875932d8b14d0525ab3a1b7e8fa61594804edd00ff2fe45b5fa706919ea9fef5eae900b429bf5674dc3e84b40d2c80000000000000000000000000000000010b99d5e7251b73910cb5dd443755e4853180cab2813f9bb4245538c193f8bad88ca2c3a34a4685af0bd704db4fca42f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c67931a983ce71e271a443a9514423f6aa578a2a9e9b0197219832e79e4ff6eab503d438492ef3b8983f4788d3c2a8c0000000000000000000000000000000014ee7fa2c9a626a7a5ab6221cca2a78a7a258668ad24003fbf262babc563f87ef8393569076cdd1d59ecb2c8f57e0deb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e568741db3e4d8361784d7aafbcfc9e6a99dd3c9ec5bf92fe4063f69f624f75c3f04407ff00201a54c8e45df346f900000000000000000000000000000000000b211ceda1aa72598cc3f9e1ae8ea3e5d77ccf82ddf8c86474bc0b58a1c7a3b89b05ba96f3bd2d66c48237be125a0f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cadc312c3f92ef48134d415c1a34e97de19abe06ed2b96ccc4b3d974ccd563e566bebe76e67877003bbdb8bd401c4c2000000000000000000000000000000000d7d610baf66d3a2e82774ddbaa00541d30862cbfc2f29b4a6dc24fca976d5dde8167f957d1ae7bc7e2c409859face3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154cf2dc88d1b9efeb401208434ba14163375f62aa02f0ac7de4828d0306c85554bc7146b17c68043b2c4b33067a26c600000000000000000000000000000000159030a1c6529acff9a9c496e662360b647cca03f3d00aa0eec639dd5572f0960ff2250a6eab18cfe9d16fdf377449011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000475cd1fbec7c172ac560cea6fd9448d745e61301014f9887569da845548c9b3ce8f01bc6db6fbd8ff6c84073c7f02a500000000000000000000000000000000131c69d5c3bc61d25c662133fffb9dbc98c01b706db4621e54437d3ed62902d56f6d5020aa2b48862e73ec7bc1a1778f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fee063b6c6734d96de1509759de9ce6679cdd953155a6d9ff70e3259441b35c8ae391f2ee1714efc9255ebc93bc0d2000000000000000000000000000000001790ef7ae78dd3fa52c332ca783226a707bba58ea78806d752e64e41267dd6321c7d42634e151d1fa1c4fd902776408a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017cf4a64601b9bcc3a12cfceabf43d5d4ff93d03bab06cae3f2cc19d4a88affa9e46465c1dce988b66d423702bc4bdf000000000000000000000000000000000eeb54579e8f121183a9787b22bf3b42f317da44b77965a19f1699326b73602def0d935f60d4a262a85911df81f8ff5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac22c1558585a06a2fe3942a28d79983d3be184de3da4e49413fa3ff94f4a0f66445b9d1c5aff5b7f6e64db59e3422e000000000000000000000000000000000558fdf3d68d6bafb253c424372bc5cd6d1f0daecc97bfe163e65962ca2a8886b2077b078343e67aaa7953af6ea85f441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daec869af0613fa94aeaf448a2695c56ce85affcec568592dfe513a81798e399cd00732bf90dd071585bb9bd1645de100000000000000000000000000000000023a92a28d32daccf0c35db4bb11236666723c3f75b1b6b043071833618d4308483357193eea8ac52c11c41a894f44a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007d88ef9aa5eb670d032324a7aa389b936eb7bf1fc80a82dc47f49293ca92de5a700a6d8d37f4e10092c4de9e98503500000000000000000000000000000000128aa5e7268422ea5842fdc8cf1b634f04c001f9825b841b70e79f14c3181556ccffa998de98ad318f91f90dda9f36731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dae8702d9f1bc1c7c72b1fa61c7d26513904ce9ce0934385e9b3d613d517da539a1ba85bf7782b9ea7b170ccca2bee0000000000000000000000000000000011aeb40943f4fd1e37d64230bf258cc482b5222b0c16d33ff730e2dd5b68555a950d9b4516cc8ed8783319115b6285d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008904071d0b512f08371d522ce44409ecd053028bde4760422ffe63581a604ce53a303750fcb8c0fbc90b46dd982d7cd00000000000000000000000000000000179f1a5d2bf6a51e1b52daf88dcf17ebf0fe923d8d6ee356457b8c186bfc845e378dca77963ac31c9c1f844a5715d2a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149b71f3b1f2b0543aee0d862520cbd677f306cfeaccd1c7faa48481370c3ff0d39e3e170fd88eb25a72c86c366d24ae000000000000000000000000000000000c597594f26a0dba4f8d96336a43c7327874f9dfdca7468740e16ba77b935168b008a89f55049ccc54834cf9d2e6b9f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000fc8b28cef0fdd0b2bfdb48c022bed85689f6b6d76ddafc92ad800b1158c455abca778b9fd49e8c00977b5d2ca706f00000000000000000000000000000000048849fa78aacd30157693e47fd2157e9ea6c8de7b79eeebf8dc76be195a31dd5f3cbbc0aa3a85bf6bf0ecf586c348761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcb7ecfce41f680a1c4340c9501c111c146ac5a9457c68eb4b77c62a162ba8c8b6050309083f31e3f6d8f2495dc9ee0000000000000000000000000000000011ed7cde426a5822af4f1b9764c7892849b33d83fe10b24e64711b89e2a4702085fbb56dcce3cc946ae033dad76250841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001537a9e86f194adc744154e6b7639ac03f754a3e1f9a4bae9ae17bef5a6b3a7c59ae73d363679bb9ecc88ab86c24272400000000000000000000000000000000168e11aae3a8b4b1c5149cbc08a4436cffbcd093f476d44c7d49c5551ec3a20279dcff50dbab0245048c8c06e45a16551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018154344c90fd0e427d938c9b1452febe277928eaccc4507397a28501f6ba102195c0c20c95124dcadd9b032024040f7000000000000000000000000000000000d587f2e943d436f82779f74e1978855dcada6b84d79238d39f7e55ca3c00f3b856e921be2e82c7a35104000d3a205e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d192f001de6e72b4b85e4b276505177d8298efc0b56d20e3889f5188d781dd15c08e7a616049f86338c424cc48c0220000000000000000000000000000000000d63383b0e872d454abacabfae483f6499c890c2a5b30afd92e38e08e05eaa6054bcdfca9932bafffabd4fcb299957551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da375a4351830986e6f7b93c8cf2c79372573c0d09cc313bd6ef0ab1820f27dec320089e8746fce4379f1895e9575a0000000000000000000000000000000012f934629242edaaf4d243234b487a6f74ad1f6569226b40e4517bd31767be1a3aa4155feb9a296ac79447cc2beccfdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001914fe4b019bb63d75d10ccd25b78c3c534017c0e1f72911b21acacf0860579806ccd70d95269bb6a3001ca949e2bc8000000000000000000000000000000000133388ecf830695dac82257e0c376b5e25be77b5f5088519962758cf14aa49a27adaee2e465b92aad592b4070868d3b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256c0fef8ee7284fea5dd2185edd290655dc6b4d08085c853eafddd3c4d329b389e1d4b7be5a2db2b5ef82102f38071000000000000000000000000000000000d4ef464c0b650ea412deac762f5e59d3e6b6097e2ed72c4f961f44fbae29f300e95d24db49550d65b8dc3177eb0c3391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fd185205b47a025fbb4a67f1c427e05dce5d163f6f00fdac0d4c2e47812fe0519b386bd2fafc46f68a445465069afa00000000000000000000000000000000105e05262097644a21def89751ce1957c8d1d150317a9b4bfb01fa2730bdf0e946e3115e316f07e233b1518f72e919d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143a176c2b333f6d2e19a43bf26ab8a9a3dc5a19bc2b71ddc2f08b8719fd32cba54d320e88f3b57548b7470b5446675500000000000000000000000000000000185498b3c2bb8f72766b46e1fedee2af3a91650e926947f65c61e40ba4a06d83f5f68016f21e1d40e1390f383c323c6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec1027cde8aac7bd034b60b6f17bdb1d0839ccb32262af595f15c0a3ced4c834063316fa0930f7f6c34fba15439ab18000000000000000000000000000000000d9b8cedb0243e8ce56f92be31a243a42bbb73a6fae3448c6b80417b18d0e8ee7048157d37f884fa66c0506ffd0083a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006daa65c099ac2362257b9bf1ea5a16f152df28e9526c31080f17ca785c1fc2c8543e42e8c5024fc9420e199f837c9490000000000000000000000000000000012589e7bff4cd73a9509e008413bec5f257626f2365075d11630cb8f167c3bde03f1d062ead08fa2eb36931f8e3902701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ed324872838934d5359344980d459e5edaff39eb89c33a3b911b1208f33763bebac31909e74d9b86f8fa276b4549d0000000000000000000000000000000000b387f9dc31902ccc58cbdd83c1d129e628c6fbdc8a180e58b14a2ecc3e35b63c6cfa85c08c4a56a0f65d6384d768fc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136b1e48073c265dd979482e55ae2de6114193e3b1fbe5cf3a1d5ed11d62d51f4bda13c32266703339f4cfbf357ce82f000000000000000000000000000000000b17e24e77240924321c2db1eb2941b570f31e3a31234d11c2caa86cd2436b67ee4c17dbdb0ce9cc99bf90470c5287d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dfebd57d40a7e0aa93f975d485d054eac9f999ea1409d338eb53d5269c61a7592e5cd50dd3561ef0a176e784d428af00000000000000000000000000000000106d959ff80754040502035e32f8773b0c00045068142469fbed48851d289902d70c97042a592087aef75a75d010c9521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e23ac180af7f325eeadc38f4c3b9d37fb7aa9148817ba508ab16629b9979cfae24c65d2a83b64a457131c920dc9530000000000000000000000000000000012bbfcac733666df96a5c3fb321411c6bd5504451037bd32d0b6aebe7164a81fd0d70dcb40adf6685d4c49eeb75bc5501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018563149cebd11e8459fe8db1d3cb1acc7037fe5d5c308ad0159be183144966c44e3e7a8c0bf375972065813ba7a366a000000000000000000000000000000000d33ae69ddb61995d10fd4ff1592c5ad11d30561db476364e8386806ba2f047dd07ed6746eac3a754aa0d295972f315c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007e400744dd3062c24f397ab8c678c400a0366b14b7e1bc89b0ceb7390cc6d31aea0d3afc9cb32ff471d241471a2e88000000000000000000000000000000000c39a4ba9cde4479ae5b5db32c13dbe4bead8669a35499c2f009bdfbb879604b4e2387363bac076392502a6e757c8d361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcd332572d766e3a5eed58985c755b7c0986b5cae01c24282b20d1bda5dbe39f5cea1eb5a29212874a337d62a96fd510000000000000000000000000000000011849c12737b88236624c411e210f0a55b6459f1eeeea5ad68e287c8308a9e5e87e7b96dd5f97671fba3677f0c0b50aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671300a283a9695b4aa3135d98edf4efa124f22503e646acecd877e6a207991813855032a8fca0b908ec7f05dde75a8000000000000000000000000000000001049a2e11fe6dfc9f194a76534fce4a1b99a4bc58b989a89506294cc64510f37a102c670ebf23e7c412c353c74bc088f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d1332404e5d497b78e44ab70eb8d5b981bb6230c3c1fc47f634fdf4d78fd0c0744709b92f9370c84551d0cc76bbcf7000000000000000000000000000000000fdf2902401ec6ad1bd16aa0df8f78c0b4042ed1112f69a1740da04e43315e6e14c06d0f73dd207b36f117bd3c6f871a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000294d018aa3e8129250af5b689737d108517e30da4f93f12487f7f57f3f5344222e004ac75f5a65c1a02e0d0137dea75000000000000000000000000000000001217ae634c6a04a46c17fb8666500175662c44fe7639f43a0a80965f00cdb844067c4797b4ef5fde14879ea270e3f6721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000519e13e91d8d2a0e6c657197fc96ffd26bd13d23c6e7a69ded5a95a07fe5c988879d84bbdb96ed3d4047cedadbec1d30000000000000000000000000000000019ba75602a0d92e30d450287930f5f1b25666ce235cf4bddd9e33ce439d8a1a2e1bbec54e20396231098e168b70b3d3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b9198d08399658b084bbdb04ba7e9118792f83a77bf443ed3d73ceaddf199568fa1407ba976970149fc9253804acea000000000000000000000000000000000617fe94151cbcd6f8e35420c9ef326dfedf10896059898a8c323591aaacc1696597d1b8d60275297de9e87ce74fd63a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dd3b5fa4439ae2744a8fc770c4a4aff203c6a49c0de485a9228d38fccab96603271e7514fda27afd4626ca92790c4800000000000000000000000000000000163e5107efdd6c749e18ef16fd5adbb5cf080f28c390f872dd6d2a491b4f4ac01f350ac9470d65c7decd66e3f181e94c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000404538485a8a30bea899b4a23ecd8ba1c38e2dddeaecb99e7a05444c31b9fcfb40489dbc792875203c6941b14e244c5000000000000000000000000000000001761c409e265138b8f48e399f7500d031e372f0138f3c6f5aa1823f444378ffe958e0da4efa481e03614c77a240a10881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006444fa17c868d3a94517b0e6a73153210de21811a22c46b2d9037a9a6c359a9a18208fdfb133093a6bb5045212b38fb000000000000000000000000000000000b537e55415bd31135ac89ad4a0a8191384944aee56ae517d49a632e8930b2f9cba38ac1db423f279add2f153d48834a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010918060bf6bf3046632b8f48a25b044fb3e51d346dff24b6dabeb4177843f65059d28657e956fb5465e9b06adfddc4c0000000000000000000000000000000015eea01168f52269a09c90518277ee4a97b0029b0e224d9744ee4faa7b38431b821cc597997dfd0362d24fff1871c2321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194859f3ea3cdc0ac42e403ef25f298d1060478e8f998feed8c2cfa83e7a904f72a7611642192c4aa6e43afe067bd22800000000000000000000000000000000098d51524e941205d4995cdad84157a6dfdc687c4aba3461adb40287481fb27c92810ffb53c62f364707ccc313ecede11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9bb5dc30840774ac873dbbb617bf37508846f47f4a1afb1becf49115025dcd0e276bd59f1263f2303e0003b8d3a39d00000000000000000000000000000000062de355f55abb1f7f63e6eb007ca4bd8d98abe569d64f132816c75265b9a552398dd204c3b38a9882580ae677e7c57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cfb65adee3205e2592903cbe55c41a9ddcc51caef96a38b252d8dea589f12b6514bdbe8db75432967a0a3a046b5d240000000000000000000000000000000008b40b23f2f2ecaafb93db1fc378351544a74d08e335ab80f150b0ba7e7a382c91f87a6b05a2a6b3e15cd310204651631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009687be8156dfd68ef223302157083bdbb579cbfafc8a62dd4187f113db0a8fb0e8ca6c1edb2339aeacc6fb2f05446c500000000000000000000000000000000146edfdaae75cf331e0f21261c1bc1eacba1fefe4c95dd9f010d178a52a6ce7936b69e0cbe9dd749c12fb3b546a1c9bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d60fc6d90aa77e460d5ef1aba5c5f75319e8e88c8f3ede8411f9d15f7fa3ad59ef33c75df513f18b31e76fb1350336000000000000000000000000000000000f130392e2c9ed3e54df3d939884086359892f41d395b5ca0b6d4e639be0d00b3c329381f286313f7c9ce1775fb5ca661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001524120f1fb00d612dec222a775e85f9ba3a18055fd15258a41cdee77e1ba5d2ca56e7c8de5a367f62cc805a58d183fe0000000000000000000000000000000014c55722d24b4e3c99a21060c9261648095b591fce65f82059fd18e099663e86b951cfd3e229f44f4cc23615945ecbd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051f3aa5492708b02d5800dd5435dc920393ed23541886da0f22c8c235dbb4b3f263c2bd356e469fde68f306f26e61490000000000000000000000000000000017130e2c574d966452da9987c7832fa5f3b6da5d48ae4dfc34f05c084a23efb57c9c6a9bad3945331685fe12efe58a1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1eac72476c0ab505873440822370908504f7f17cd3b88679eeed0b2599acf8f9ade3c1e509d95e8dbe80d758fe52900000000000000000000000000000000172af8a8f2e04c9c5864d7209d49f2b293d9166d57957823768d35c2114bf1f9ba057820fcb061862cafc2c26bfb1d581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d2a3957a29e0f726d603f944207f62d772a04cf897a41b795691c31c4667ab78ed733c22b7d918fc60b895572183d80000000000000000000000000000000002ae8c95b2e805137727b99418aba57335a3fce46e99079e7c1cd2f46c774e18dc18f7470aa30f8b2ed1b185c950fd901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a751f9a48c6c6c2fb4d6dc03c0d940f13d973a81460677b84b33439d3e484943e9eff6507a3fbc60a90648e7b84dadd00000000000000000000000000000000068dec6ed826fcede3907949346c1e864bab5211fae8349e0a083792036960b1963de89bca1dbf009400d59fce069a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142d29d0b40d847e91262695dd8d532342e7721ff9c9913843c3e43e5cf7faa13d0f65421ceb327f0024f32aa04fe50f00000000000000000000000000000000180d1d8a3cabca93eda47ae7216984447e215f9106624b17f68e20fba48fe88f36dc5f4d5d8aec1408544fa89474e0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0dc24dcf78c0a9903cb58790d7650127f972df175a796ce47cf754517f0dd3e52c247510fdbbd31ca512b1cefa77d0000000000000000000000000000000018c01dabd9fbf047f53d226d97aa54f4878f60733ac5237904e6142243e5e9391385f5a622f06530f9086c15ec3b89d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059e0a3b295890087b19f094430ac4edc6710dc7ded1e4431cd27c77272b6f2678acb72e1f882d7b183b3646eac5181000000000000000000000000000000000173ea65807fc8e52db9293b7499c7edec86240ece1dd152fea87e21360a01f54fe2e2d610eeafaadd8091b9434fa5f3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018ab2ada92f243926c2beca33deca75f69b82fb7f71a34c0f3e3404ecdf3fb3eee7b5fead5985f2c7a56a5f250f88da0000000000000000000000000000000014a2eb6e97fe92433af845604e23b1eafa18ba317599bb0b280ad38aedb1ccb5e0cd5453b3edfbcf2b849ee4528eb3311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aadebb34cc4d77cc49645107fe8517034fb62c5e1d0f6d34b6737f90e932f357986781b42d6a4563ac8b24dea7d11700000000000000000000000000000000099ad77cb36a7ef863dc64c987eeaf207aa07bf36f23a9ebefece128cf2de308c1e39d41784e170009722bb816b268c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019423a4fd03dcd91bd01bfab813ce8cc583347207d762600a3038b9d2e932e9c5ef0a08d9154be79f4cd93323b41d0fb0000000000000000000000000000000013ef87e3e3d3719ca7220df884828862f154eb20edb9a743306afb84ca2e84596c473e013f5d5a0cb6fd63a1bdba6da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f26bc4e9a5af09fe36525cee913f2a0ebdaa48312d264800029e1d96649a7728e4e68d7ebf131b59af13f20cd0fbcb60000000000000000000000000000000002098e5f2c82c005b9594a76c239fead57b8300774dda04f972f076176c64535206a5c46a83dc47907e48647e91dd3fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb528dcb0fa0afe9ba57f744f1cf1c3355a581d7193cb9ab571c7a29287015c665ffbd0f644e5e00f063e7e424f6fb40000000000000000000000000000000010b795bbf8782860a6775d7f34ca2a59758e9d68e7127a8ee15dacbb4a701ef92c7096859151c0af8b5b5941fe15ba821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a09736baae46dd67e055cb1e59ed49f5a2d3eeaff0741f6b9572cda18c08af9e816cdc9d283985c0964c41b70ce8f400000000000000000000000000000000195434d7a60e52cef1c6d42f8cd47a49363e2432ef7581ee6e003794374644b0625dbf36814f910b4a2595251756681a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005798ac4278c47d9376480e8fe1f3d22300a1b12b8b8777ee434909dd9040f7a9b7fcd00cb171e441a52614e0c1a45d50000000000000000000000000000000000bcab365ae0c01a7393efb27d013c5d78fe3276be7ca34126a1d109f0e8b006a3e1dc859881aa909fbdac7a16262a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073953dbe2ddc59c682fafea7bdcce0041051288eceb83f3ed6dde99f478dec897cda2a0dffa27341d11a54ccae6b83600000000000000000000000000000000122735fbd366bd91fec19d737ed25bb7f1c93b96fae37e371eada8c3474dfc05c0711f41054e9fe985788d392acaec421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5b9c55f62e97ebb4c0a9a2c13db0ee839f3595e8c8a8404357ab2a3a9b4aeef2ae808ee43f1d28fbaf19b9921c6fb000000000000000000000000000000000da39753e36961b767ff7c13a73b5a07f1d8ffb178fb96a0be3f0a5a5b421a338152163c7f84b9cbc03fda9f05fdb3751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5947c9934c8c8a782a17a383eaf0fdcab5acee9669db2d24526701fb8bec0dd2d235d711e1a5cea0b420c4f702b12e000000000000000000000000000000000da6c6eb9f20b0d3bdb3934ed281cb1ec47de1a0852599297a97d25d69ef9fc1434f63cd10677b07aeeeecee08772f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f570e4e568128ff643b05bffb1682bcffe80b97de3b695f25fb8ef80a0f571a8e642c745fcd9db02ca301b522c3f2f000000000000000000000000000000000092bdccf597e4203542a7c9f062ce9e06deaecfabd7fb8e185b0ed127e862124915d66a1202e638a6d8ae34c4ceca991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000837c07e39157fa53f0f72fa6c0a5a301970a0b68f8977ee6929d6fe2c60adfa4a4f9bd9ba7eb744de8f0c1e878658600000000000000000000000000000000013377b22e1affd67d3e31112eb27ff14b2cc8b30ac0af07633e216e5648dd6465196be99a754259820cbf41198b290461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca8ffba09abcb7b98080208115aa77ebbf4718fa593efd04d1ad9d1b6fd2dd8183d5be01005eac0745e835fc3c3adb0000000000000000000000000000000019f3ac589b1b5b4464bf7a8db892c65d3aa8c2d9dd554cf6499b85be03890189da67612537c31f16c37b17708cb0b4311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c845eb37d9b6a6470e19c7c2c8c8a080b06d53d33640fe2dc6aa5ad5480f817e92d822f62783946ad1f3735cb73d2d400000000000000000000000000000000052ac51c7ec7d920d6e8654e69e353c28af835d5c0cd74d48847397b1a7c626e27b074a223451d9d5d646207ef9fbcb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c394248512a006df665827276682746c5de1d173af3e6350ccecee7518d8b306dbf86cfc5b6a241d465656d38320550000000000000000000000000000000009b58a441e0b8fa142ea1b350e0997f4307c05fa9b4aed1b2076a65059e1aea7dde4b80846329c6f62975354e74791f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130b18169f6e1b9b35a730e44a1336cdb753ce2bfbf268bbdb11786fc343696c09c60a9abb4b474790979c79267fa304000000000000000000000000000000000158c48234f32f31777de7977ea71e49b8a93c032091f1577d8dbc1167adb453835b664412d442174b1d9de4b9d9582f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d9db814161221103a7daa7f1e7957e9234e78955adce0169cba91063fab855d0e2996873b3e7c533337aa370e5dd2000000000000000000000000000000000797a60157f43dc6d2e739b1b63c337bf019337e097a5a2cd496c4b38305fd0278fa639cbe40f1458f77770719597a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100788abc3ac86f54e64a0b8c91a4c16cdbd029332456575cbb48ad07a94b6cccb7e8e97c95bccbe111aad8949b364a20000000000000000000000000000000011b8af6e976ec1a08dad7d44cc3cf62de4b85a1e9c7fdef6994f433b661f52ff8dc5425e0a1ba2706634343812a93e141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001535ca6f5ca62067f97bbd091f2f1b273072a53080bd4d34a0c57357d0e0ffbd31dbe178ea3527bbc60b1db28a43bc7f00000000000000000000000000000000045c44c06f49908a38087ada607194813eb1f6e914f5c0ed2f7f046fdf87794ed94e046a79baa99fb9e50ee645245f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132601bc08081104d1e3ac1e18315494a37ca85fa671d6d5352389dbdee649ad4bea8e05ddb1ccc5ac9231282092635c0000000000000000000000000000000011022a0683449868c381aca7f5899b932b6ba01f6a45f65b53e04eeccf013142a86f120fd5adb25ee691843b2686a9011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c65042b5e92e816fdc8f50bfc2d33501c319f73e2b9183b796d5bdeb519080d3b103a320868678c0145018aaca8de6b00000000000000000000000000000000020e22abf8e3e18bee6fdfbdc130beedc5a45fe69bf1c70e2028df0580857fffeb0bbb3ea7328dcc7a428c08542f24041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b304d752ecb9a6a5b79eacb25cb684fc05192276e5f36900f0559475523f0eeda27a3251b498f0118a9842eb46b27d00000000000000000000000000000000114b65d422f2fd77ae9913f194dab90e024fbddcccf4f19c911c1d67135ac542710770d08ce2366f7983502940e071f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fe122b11d0f5ac0b4c609998bafae12d701849eb7d8899cb9cd6059c0955e1c5eec12cff77889d88c2c219932275db00000000000000000000000000000000072480f02a37821b59abd3d07297dd98598593b9704a02f0d65db4404dcf45fc0716b323d454e1ccc0bcc97362f29d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053a3a2e0467130acc0d78effd5ef299cac38d9263594cb539a9b567e4535a5e0bf54a9a3f67ed731b47d5eba3312d6a00000000000000000000000000000000142e232037d5f0c658a25627967f4d77c957b2388fe289e5324728657adcf267dd2b6c1b4c8dbba6815662cb17e4e9ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003987ae4c072ec0ccbd50884d7fefe0b0e67302c2bbabd0882deb5cc89a15d31be37d1428b2094d52121542cf21264cc0000000000000000000000000000000000e89a160a6ff6271eb530e4a408d3bd910f79d34c520546d43c20ca2a1761069d55ba876901becf355f42976c97658a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169af034cf6f516f76380d296069d6b05a07175e86e9c91fa6a4a48925cc41f2d5983fb088ba7274431c06251babf31d0000000000000000000000000000000014a4ff21fba7d28d32b1c3ddc6859695e4d09e8402e8feb8245a1ea5a59cb837b93d550113f80543dec9d3c1e5831d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050c44599bd0c9a0518fecc1ea22738fe2819f1303c483984ebe0a855936c1965ad64aeb5c687d91cd51b1fd4592ecc30000000000000000000000000000000000020d23d8742ba39c96eb91ac0b5043a19abbda297b9decd29881d12864554a2586419dd3935c4559de0ab7f73ecd441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014947b554cd6547338abf2207e63f763190606e07a14e6acc841ab7ca1cb2ed8a0533fcd20dd9961eec00daf1a54597700000000000000000000000000000000192df8e21513a584b5620e3192e27d798111a786c73e236582ab29cee644d033feffbcfce2b46687eb6bdee271e92bf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171a8fbfc4fd210b912d0948fe93cc5fc2cfa46f5eb014c0363f797b510419c070427691d1e943e0e4fd90edae759dda000000000000000000000000000000001775c5cfbeb60d20dfa0f59ce29ee5b2c97e9804d27d2ec917cd7662f7d9c3df6235d80bf51915700e07b7a7d45982f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4859318283d6ba2763bd2cd168f4a0dac50c6efbf3c127a56dd82a49a54802382758cf1c30026ec1e54d4b520d84ab000000000000000000000000000000000cd253e743b1dcbbc9520da24d0cba2fed238b789984fab90a9712ed3233ddc5010417d4988c54ef2f2a02bfae9ac4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000258f2d15a4dcb712639479ec6252a78966674dd21a0d08360e6fd1a3122d090b84f3622e8a50ea68da5aa39865c7aec0000000000000000000000000000000001c8bc79a630d2795fd02c145094540df1026e82a59388181026d890abb46e5a9469c5fc3c7a9f948078bca5f22c62711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017712b6b2ff52c1f37b2eac10a1f10c3eb1de522e172e909480b7502f0b57258d4600fe3d149a4a14243ba72f04a9a4d0000000000000000000000000000000007b9e60073c0cbf28c5bddc9d1baecfbb0074d88163cf09daba89f7960af91427e40d1b22de74c9934a7228bba9b38911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001545b79e420335c44d37852c6660208bda856c6060ae7f17057d16c7570057c73c3e74a433d8f6d73badb4e2519d9938000000000000000000000000000000000ce6dd53e06f253e36b962e0bae79960a0b8db05fca83a262d58eaa21306d5a373915bfa2f1c3b26185c1760020265a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123983e746e8f131c62416fe3baa75d811d84c42dae0c2fbb981112892620d88529c75cba693450e27f9fc1058bae5920000000000000000000000000000000019c02a83862ae62b790214c220b2f23114c44968c98296214a20241b89ba01acdb04f5627f51fe649727723a25ed9f351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000040a2bfb0f3bfd7e44a41d6c19c1063d47e3c0c088ddbbcb580ef75834d8e09f84082f8af25683d08ada377122ba3020000000000000000000000000000000015873b3e3090eb1f5ef68e25c53e20c09797963025fbecfc9058946b46ad9bf479b7a77e8d833022ccab797631726e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a572608e685bc3baa0068273293a7402f215d6fb1c38d8ea81bc99ff3a2041e32f38ea997cf9c16033e035a96543978000000000000000000000000000000000104d12c941f26a175d4ac36fdc39ed058a89025294e98d86ebdc39564f9da0dea8735789e723d4878a813d2f2c686651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce04f999be665bd91b5ca7615949f9c9541af8bfecd17f44dfe1d2341fde5574f23d0f391455ff2968a4d443ec995f0000000000000000000000000000000014ac55dc41d33d7d739ef78225f5b770ccd2a704771f22291942208dfa306ab6145b460021bfd50653c772601902a0561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3d12ffaa5e0080c74d8832acee016d7fe1a3f36f9e6c5402d69cede785f795d5b9594f10630876bfc680086ba1bb6000000000000000000000000000000000544460af30e2d06b4ff3189c4f25f88fbda57e63f5101b5658726e592516ea22a7db66a42ec0aa734e1dedd8f3d2aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c8461d4aa30d897c2f916e5691c52a07f35d65f465d00361da72dbcabe9a17190a4b782c4529619193a272c434ef4000000000000000000000000000000000ee2a2315e4b1b110f6ed63f83bf9dc94052e3411db87231dafaf438d8ca66f391a783d79ec7307f249ea8c006dc0ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169f41b3d39285beccbf89aa2fcaa7bd7644fb121396345622904d2202b68d9af6aa12a164d3abb40b77561a9d306b81000000000000000000000000000000001039b9ebc1099b923451a0a5602b0490121ddf9c9710fe40a526f65faf81badf306784fa8a9f8db4c47a6384e34cc5561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001309f591eb1ddda7779fcc9ed31bb27fa97bf606a51091b349586625bf18f4fb767b2cffb5177012110be6d38b3556c80000000000000000000000000000000015db62001cf4d8689d991d1b1e78bd4e4d948eb0b9f3b7d7b5b829467cb9faa9b3770180aaaf9183ea2365dbdcbf27471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5a4e188e69c9bceb3d4a9a4f4f83bf83ac7b9ec089ba53026db2e8ded246a006f10694a21e70c39f9aff1b4c08cb54000000000000000000000000000000000f1ef3ca42a2d0f1bca9abcc5366040650149745870e5e23b78c598c0d3e2ff3c69d808169e72bb3010bb41664702e891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099a5ec5b44b4a039b9749c6d2867c9d6a071a7f5e9267294d3bdc7a2992444a29312a54b8c1b2852057935b4707b78d000000000000000000000000000000001733cc053b1a977200bf8f8a122a814f62e7a737be5f90db07c7decaba7dc6ea4eeeaeafb682755a503a452285fbc1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b65c7a7258d0a9d42f914e2354ef6d2118a697ddeb32a0abe88247850b55b71690e6f7df8081b1ccd464ce341d54c200000000000000000000000000000000181f47cd05617e40ed26995deb4ee4d7afb464b9e509a7e3e7969d17a4c4f0f1f2be81471b0067f764b63134019174321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dedba233dd5314bb6a5842929c0fa0c50bcb2619ccdb24d81f943e9fee0a31f21fad3f143234dc075aaf9aa0c46490000000000000000000000000000000001186ced9649aedacb91dfc479a78ae37651117aee96acc7794395c285653b14b897584d41672ec494922b8f0272173031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bd746de84a779815d28df3454a3f8ae86304b57f527c73709311edcae8a1bc49930953d1e33393b048b21f9c58d178000000000000000000000000000000000b3c42c7cce7d0f64bd6b1468548634ecbe30e108c810857143346cfd2c7f3087ac49a709468a600edf6f9fbdd600d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001123c0a321ee41fb612d725243b62d9f895c5243b7b8f5af5fa9664d79a374f5018b1397507368a2e91f92fe1151c87d000000000000000000000000000000000644cef7939efcfa782abba8a6a7744e59095cbd657fea0b94a6a50b3f0b93d17a341b7609675e3e45e2affb08888ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cbe501c93bc5b65adcf4f27d5d9bd4148c27666f17e785295eb8c346dd4e48a7c677659751c6fef04d76f6d24c89970000000000000000000000000000000001f274a8e6e95e52759fcb89376c2aa9c720984b2cf0c501b0636025f814cc52ae6ca0c1fb2faa2364cab732c49c3eb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146f93701cc9419dcdacb86a5a66880f724e53af69c28e45218e0969d1add8faa46025e2009ceb6482c1dac37b249fe10000000000000000000000000000000006e39c2576aa013b7b108e086be1e860bc7675de6be454bc22c2106c439dd52992a7c06a041ccbcbe0abbcca35b8d0051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b44d67e52b901733866038e4a4df2e17d691f67bebaedca0259bdb2b3c44d5a5c75c5dd309b8af49b597b246c5cd62000000000000000000000000000000001117f136956f3aa97997c1f773d098af2234e838328db138d8150dbd3609294580cd9fd097913cd28dc3b3cee664f4691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aff41cac3405d006e43cd0a0ab4cb861ebcc5836083bbe657e411add94824c726c9769307025676635fba220722a0a0000000000000000000000000000000012ed758472ea003c5e07e2c064b5a009215fb0280d2467db05e33d7bb28c98ab9e565191ab0ad3dceb54be08c7199fea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a3ba2ce76af954f2f9d5218f9ac2b9d4933bee3e303225b84e408e89c7c5920efa2a7fe2be82b6adc29b14f425ee4d000000000000000000000000000000000cce0c60fa0c57cc9c6b8586b018402ed7e0beae1654470092d7aa8c023c657298f68b784c1a294d0cf1e6d84351c1441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb0de7dd2cd1cf1f27351cc04f707b1fcaa5159b01f507e19ea425cb18c09dc343de44aa0fac400049d3077b1338a320000000000000000000000000000000002bd14688804912462655b2ba970f481d043cc357594eb44f05f0390306d4c9f0c82347383208a71a977e696cb2730201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0a07cc3229d2ba16a73bceab432fbfda17ce3c526782b2057ce650c82e71c15c5932ce87a7b92688f39daded4c77d700000000000000000000000000000000050a1756ce9478e7d80139a09ac041591a5663a3874a9ff8d992d6b49edbb0ce475df923eab24d19b56e4a75878dd92b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d74df3789c32f32decc8c68b94cc9c83346b31b951466c1b7d42ff4be45c7a76d5da33ccf157769406c4cc32dee6ab0000000000000000000000000000000009f25cf34570239097cfa720f8101168e58637ce0334b9a465bab906dffb96e7544a05ede469c4d3368d07d3e811ccdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002be1d513755de9e26f70e52f5f5dbb82261f6ad430307932b586f3951597427b8a2972ee28ed4d00216d95b1b59d2b000000000000000000000000000000000291deffc942625f839f2b4306f682aea47c997e491370a2406eb2f13cbebe65efec19af3ff606ebc6c3d7f465cec9511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a38daddeff2e822a39d66be80063d86442be0360b203dc5dba189cdfe731b7476db335a1e2351932b2dda77256a08000000000000000000000000000000001380f6bc349145f90229aff6f5c7ca0afa72662d37058ddaf36ad5066b961fe43923ac6e8c8e29b0a0fede5a833a78fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186b7559098a8832f57d2471f64d07ea0fc5f43e5957809ab76dbacec9d81ba37ae59b54eaac9ddc7c20fa866dd4b0e6000000000000000000000000000000000caf4a4e9a77528af9781990efd1c554bb7587073f1446e09800bda26f49932d93b042200f93b5ed3c59dbe9153120f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001495f4ed84240f37f3c6924950846f40f8a94ab2858f27b7f14bb79b5b55d37f27e3db9069a5fd69d146086cd1738502000000000000000000000000000000000c2a450dae6acf62d965c2281adb7360787c12304c83df50079a449ec42d945ee37ded1d55e0c325c3059a8861ae6f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058f004d93ecfa600e871b0e02e3b6b9f144fc955ab8b8f539d647817de3b8b1520effd22b734c8d05514578eebfdab800000000000000000000000000000000133678f22607bf79ef764e059fa4d22538ba0a9b2e17c40014102bb2c636645e2963164575fa928234cd2ef07c522c9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b317c96dcca84230d676b8608bbde7f9ebbfd505f82b150138278b9326bcc9566b17b89f2b8d95decb39c2c7c65dffa000000000000000000000000000000001124165dfc607df45515d41af9d80f28c081b1c5530b3806afa03f12d43ab1c4b958d9e76c2e31e4b074f82782add1fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ba91cb74e862a75d94f1096ca68309f475189ab4eec941843e465a1e7c8afccfe91a4e710c7d0eac906ffd51cd13900000000000000000000000000000000090a6f22f56e1cb8d23f70506bb42538009a03e6c51cd087059524e440f480d6adc48200c95e1970a2ec6b28f434d82d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069dc7c55387c795a802da58174eca9212e28b9f635dbd9dd40e6872f4e14f009c8a3c6c8fa3095403f50f45eda33ef9000000000000000000000000000000001637470558b3f448d742363454e3ea9aa816ef9070e47ec34e29c065da87309db31e1ada1afd2826efcb72d241f99b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000334640b27ceacb7f39ad6f2a9563b36578e428ec66722da9b68ede088259563c83209a979cd6ca27b6064368b4c3b7300000000000000000000000000000000160911767d155b4be6adcd4ccac95d179a11a57a5c502d15b0ce47db78b36ba2b2496e36a1f5b9090a1aab8803365e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145dd43cb3fd86cc6a972c7622260db52fae18560090b19a4488de57e3e1e48516df4bf5b6d9ff2acafd21a7574869700000000000000000000000000000000011fa08dc6e569b4cff923996f9d5791535de7969a71c6e96c33c1d1cd16ee8d5a93e27be604fd05a903467f82cefe2241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f9ea2e119a7b76b0a0f7a5a12182118ced171213423fdec86c0481eeb96eab14a38170541804347b5e9d5c601e27b900000000000000000000000000000000038e2a21e5e969ee39eb604267c551208821e562861af45f518e38537ae36126d4ab1eebbbd9b8aebc7fdf3e13a5a3d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bc72f736b9fb8264505ba322b9580385955e2d3b29c7f4e1e66438ed4d78832dbdf6c08e9b99456ff6483f51fe349f0000000000000000000000000000000016be56b1b622d502c4601c70866ce96dbb011c56d59545270d31002950f296bc42e9657c2bdcca36d5e32f6606ac0c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b430c3990f64fc049b99505f9711976af7665329e46a89a5db107b805e1f9156c2fefc471925fa1f8a2d4ef2d53994f0000000000000000000000000000000009c3c589fd456d56f55511f3fbec6af1b070afd7cafa7a27415a723607852954103c0c4b8f25f6dd5ec09ed1b580729a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd706c6cec82fc45319f454f158fdc42d8df01ddc79d245daa7545a9c6aa687a6410ab53e26b69b0e9d98b23021ad60000000000000000000000000000000005bdb89cf1cc55f51088eb9a573863f6b6c0d8fbdeb4902e55fd001b157dc6dc793b95211912b04fe2dfda04a03699361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b766c298b5b1c1c31acff294e1b73240e101045f82da8a353a0d2d19aee9f2019ae2b3127177db9ceeab6dfb0235ab0000000000000000000000000000000013fe14aed2f43634ea56e47e6766e1f70176b7ef048463280b5d6472c1ea61ac24e12fd40edbc46d1baa0aa9e520d2431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fdc3bacfe962f6abab42cfa5c5b46025b04ab144143788bb545ea6f41b0025bb7238d7ab1380cc73a42bf46979a816000000000000000000000000000000000d2f4c5593e4ffc6bf38942500ebf182a757b243fe8a68575ad4c83866cd0b27eaf5bf13c22299d2cc50005c0d3a41031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c09431e6bb6e3ff17ab8562bdc375f1fcad232006c4648dd2676183cffa5bad5eaa3bf44f0df036d8e1990f0610c6c0000000000000000000000000000000009e1ffc59b64de9f1313b842d9778fc89917c2cd2e03f8c3532a558f9f4ffad7de532ef91c9ffed39fb16a31238880a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009460bdce66b93c899f21cac851ae3ba055f4b5c2611a2c837df9da8b382adadfaca8e13982e4eccea663e74f7a7c5f6000000000000000000000000000000001117aa9a960b7a7ebe773f1d52b895c9428d23d55bef4afef53a9cae10c851999436ce812bbed28a94ebd0ef78672a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012aadfb9875a81a8e98a3bb9fed98cf1d353c3a53f159bba8caf5bde402a4874f94bb9a3e53a4d39b83860e46a470dd30000000000000000000000000000000006d1d36ef517dc15596b5eeb39390a8389d931c35d0a611235897855a56e3c74d3afceac69f799bd702bdb85e62701c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242686bbcd118b4a980faddd057d6310c341243bc050dd9d028d7b18607f74e0390e209c58e1f1d087011a4283fed97000000000000000000000000000000000e1a057f838aed63ca2d0f859c784ed93737d67224ee1dfac52bf6181f2d89f77e030773a62341620b192716b4d1a1591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bca58037997e802aaeac3c83ba8a45dfee792a4c13339bee768ef9625dfd8b90aaf3f76fa70637714d6ec253f53f6d0000000000000000000000000000000008a3b27c350e478eace79276604e38ffc2d2e39238870ef47e09375c4d8506c78017ccae65c63ee3005d3464e58a79091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000816d97f86ca02fdc08ca87f1627f2c552801cf9bd5d6284e5b0a5a4662d1992026fe430ee7173f4455f80705dec2e11000000000000000000000000000000000fba960e0fe33402697011d6c5db6ed7391db32e59a16eaa3d7a7bfc15f1c5a6eafa5808de10e845b93c2d83f117a5ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ac03a9555897361f01a2b1183d13ba62d01581c9d90dcd8f5d1144947c231ee270cc8c9ff05d049bc60f00a569da6100000000000000000000000000000000032a280182b7f678850f1f249198dd2bc52f9f4e708155d1024005ebe4d16f0f92017d24f44ef87d5cd6c8857cd52e441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6e1db8322876a1061f8b627975ccfc06b869772b01cae1ed152d9140946d9fb6b7dc9366daa054bfd621b0d792f6d200000000000000000000000000000000193dcd1f35df631e6d5328b4835747e4f10b26d8f95aa896fbb762980a40ccb3407be9be85e04976c50aab0eef8b8eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015223b77f13593ed99a560a4ecf4ce2e96e451a379dee462211d982498fa22e2878fc6d624583a694ac00db4340c12ab0000000000000000000000000000000014c582e2158fe485a533bd3f95c3f060ad70b8dd956383c84971e7c0f4a5d5a57678bdc735d1ef8d8df8194a69533d191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfe96b343e367a6bd0180f7459eaecc5402da1268f8ccdc7f89ac6d3c492f4e386068a73e4d67be06956e8a3a988ddb000000000000000000000000000000000f70f51cf54d25d792e200357ab8ca6b38493820252f540249afb4974c4d952aaffdd3e3d3cbcd0c44b82b1320078a0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd91139278f06edb6a0ed8306fe77f5aad91af559491f585d9862588351120d75082e498a954b6343fb9bb857df3f70000000000000000000000000000000019f6d2ba3ba097c117698a349c33edcfb131ae7067aa1c0f299642e3f7eab42265f2e8a4f8dc09e4840c82834226cd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006451bf0cbe68a40a02447d126d4bfcfd12121fad1f70da60c74b89f051268d40169697ef6244fb6d1e6c68bac7ce5cd00000000000000000000000000000000056d0be19c73b8d85c57120bb616f518abc2ff388fe748201146157bd420028ea6d83c2400ffffa7f3091e55dc577cfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da1ee24cb3aee7977d34f5c9d7c8ff0cd9f6858ad6cbba73cef1da7bd6e44205e39811ac1869895f48b25e5fd691dc000000000000000000000000000000000193e25e186229fd82e1c9f90cd6e3fbf66b5ce365b9cc86e9b9a6df10c8365b0b80660b6c2dc285f2d9aeee86f4cde031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d9c6591a6b05cbe2cb01c4b137cc56017b7506c8449b909ba4a7d6a5da39502e059f36f48bfaf3882102078b72cabb000000000000000000000000000000000512be90a1ddfb6896ed02baea6a21b14c96b6bafd029d4d4b353548c4b62b16db9c4331bd4fd4b943b04a1457b63fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641ea2ac241b7c3899db22560c267a409f7ab591cc41f9aed910f9dc3118e90ddad82e6cec8970235227070e35f0afc0000000000000000000000000000000010e623b9d900e8f696f6d2a2f7883ab02ab227edeac7be8f741a8bfe07eb0b0d5731e974ed86fcea0c2bdbf82472415c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044eac7f50ab7c4124977d18ad487f1dee7779bc5c6858a66aa451bdd83dc1ee23758ade3eab2c236caffdc5e5cb8ea8000000000000000000000000000000000c2b4a4964cee0973deaaa9bd38c70096e3756b4afab5a64bb00109fd86f3d4382831456cf9c169b1a8c9da769dddf4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dccd3bdfccd782f99df445c3395bd3f420249d6074c83a098c49e978bed4f05ae9758f9aacf966701d7b0fbc065939000000000000000000000000000000001759db1e40e54b654b270b6cd5ef2d92749e12fda43667d78db17b4b9bd8968bc78771656c9101cf7ea87f34bff73b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001917c430a8d61fb3c0cc1a0915c9652d733171bddf4f13cd87a109b192d7b671a9d6562b4a9a779a2a36bb3b0a24e4bd0000000000000000000000000000000011ba74f7ab7861e2bb4a25c2c5b86c26670648dc9d665eb6c697c3f0f5acd13cb951aadb52bc37f49708a46407385c731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3fc9586354c14cb338465ea2334e7eddf404fbe810fe1a8ce10fc0b7ba0a746527b4d4f3d796af995e46d0236391330000000000000000000000000000000018d168a3b9ca279b9929a3e431776acb119144418319d7d2367f6b44e5b94cb7ff640a45da61d64e0c9eacf4f544e9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001571cd3eb9563be1ed5f4da12d182a1ec284a1f5afc08c615c5716c939e831dfddcaa47dab7c43262b671a8cc7d7728e000000000000000000000000000000001381dd080f0f39e6ffa37ce5568aa269efbd2f8c9ac02c8c3e98f5df21e728a67521a3a4d730ae96c5ff9dca0f8dd3b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000761236f004ca82fc189ca57406894a83f663c4ee1172318e9716bf3897d5299e2678b39a62d5f8718c4d8d92bdaef0d000000000000000000000000000000000190f03b4a1210a7f3a4486138c85f8b04f7d7e394173acf4115d7859675505611b055de029c0462fb0faaa590ae33231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5cc0d3493bd4746057bbb071ffd65613865fa918271fb95e33792e2d107b45abaa455624c85bbe97d20f810f737d46000000000000000000000000000000000a8ff632fad7388e42eb77768ce1c3730182204121505eb55941ff9ef99abd6e5749412488c536ea5fa5beaf29c7bbeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c31805bf51c1c1cedd32ed127e6d4db09d7e36ffe8275a16028e047e2a45583047d7c0bdd93f6db937d7b88ebd69f000000000000000000000000000000000a117b6a4d19103d761e3698589695cf4d887cc99df52f4a4e168c72483d1810642a4f7f97602c286c9e9b9ca5402d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c1b84cd981f7fc4039d1f79a6de0bdb1a12b7ef4228adbecce80437d64a558e1d67328d5ee230bd15ec59b1fc8c71c000000000000000000000000000000000a27d65a50887a76c51459dc6b8505ebbf31b107dea0df9769eaa379ac6fa36a9f145bc53000c6ab93bf9367421e3aad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dcd6f86494811936f04672bc836665d647cf5c950aed50ffa7ac96fda78777954cbca957c5a0f5352355d4c234dc7f0000000000000000000000000000000007a128a0f8283d250d12031aa2bdfd9291bb6956bb86a96e2483f866e065446d3cf3aca59fe2f3baee3202f5c538ad721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013093dc6037e82f03f8b9e40f18005ca9351896c97bc536d1ef04c24fa80a5a826e3faa7298a5aaab5bf451f93522a510000000000000000000000000000000015f44e7b2a5e484a3328fb0efc9b1c884505e8dacd22e025be898041196bec28f8d06d727981ac9bcdb062f92063bbef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f595d13ae920b25e61cdbada5d59b70ec116616e9767e7d9f900b1bf0f9d770c68fb32e314ff40d4c200ec8b13e2cf000000000000000000000000000000000d0617ba8f02ba2d34b5bc7485a9722a241eb3ffb0d94be22609355c6f91d646952e8dc3b63fc44f87cdf3b40cf47fe71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001690c65ee4cc146eb25840ebb0f31aa074cf6deb582618d20f235de27d60cdbcf4ac1942e6c7ce6d69ad4ed28c8da63b00000000000000000000000000000000060109dfc9f340a3b8081e42b2acdaec27c981b4f3b555df9e12e9fa5de2aa9c53f5f72a64c9244de0c2958d99b4698f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f940d38f06d8019db6f403aa9b6305f262209e65de106e7ae15a9ba7256ec70593dd7746be248d3ad4bc4d77ab4df7b000000000000000000000000000000000b028f3807032dc37788a19e4bf6de8d90df899467af06a6bdc363a5918c78e3846422dafc4d56e692d4e3c1dbec8aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4ec361ce4727321435db1db60b15f22815a867701d6ee270575ccb0c299abd5dae0dcb6cae3e18fccb1e0930acf417000000000000000000000000000000000d27b8174707ecc37f40b07eac828668878655971e20f1e4a3c427e1d379e22caab6449af4e26f01c6997e9f42f000c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014991150fb8306d94717102de8d30f76a1c074898a3d9da8df8ca8489902635b97ace62bacaf4bd1092be2d7781b1eac00000000000000000000000000000000070acd2dcec064f5b5c72dc1b0f6c1bf7a964106de0d292c2efd44a7d32152fb064e01e3c91f8d60920b9d9889a4800d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116a924dd6bbaee3b26f1c3b16335ff40f948fc9c1fad12a35ff437f2cf5e68ca7ccdc975c6f953cb4d0a9274410db58000000000000000000000000000000000fce9dc655e2463eb9b1868872e210d91b08bfdd5372cf5462a26f5a83e2677787ac9e2aef54885163c64407e3ea727e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000509c0b1ae7ba8f4cc336b40fb75bdbf6c4a454f3439f2d40e81589c614e7d3324314d25c1d7d1351eb2892c4a3d11a300000000000000000000000000000000149ec72c38900ce863e339a5ed71364b00c96217f4369e0de623f1f291e1d2b8144e160642dd37184daee8afeba58cd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5bceb1e90927091326dc60aa97f33b8abb59aebc0539a001ccd4d99b738bb483b7373514d07cba9cb05dcecdc04131000000000000000000000000000000000e47917b5ccfbcc31122c022b176d72e30793ad4b6da694b61f2d91339c76e37f0893e90a83b80afe6fcac61eebe11381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000789d54c3b41a7af487d63e53c69ecfde20243332af7af1cd87ad02c758c0848af8644dae5cea1cc269ef31ee576caec0000000000000000000000000000000016bae18a053de086f1ea73a5bbbb4e6e4a8e59d8aa7aba8f9f4fa1f5f5ab9c666387fd9ba61e6a25ead44d9d5b68ffbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190a8eedd9b92ff81438e2a72198944b98a167335044b84bd7dfd1fd38fb958fd7d045baba2d09daf9701ef11ae48a6c000000000000000000000000000000001954d59bb07d501850c59c0e0d946e72930958b13a4b7f7fb322e22bd53e0a3fb0644bf5bfcd66bb2d809db465c370c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a008824091f1229c1ecc087e73f68e4c6576675e86e2afe283097b38d93b8521a06c5c829c63c358a2a0c1d769e98f200000000000000000000000000000000173c000524cde4e43734757d405e2f22c79e909e14fa4c719c6e859c0b40d463cf074e0da3e1880f023ac034713f0e9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fdf243d85a195df663e7322d9d135f37f59ae5f3f7af112a11d05629d8d65ed6b772d77d8ce546eade6c4bd125147600000000000000000000000000000000116a4162238cbabdd34690689ea9b399429e9aecc9dd59488e53f86b9c0fea97d397d6ad2e631e90644fba9fac4099531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f5a2aa5d92b42ded42023c47060279fdf8ef79df84c57699386bceb38af360ab34969efc7b9bc4af14ad22431a8be3000000000000000000000000000000000a0b05301a23621505acc5ef06bcb7203dab95d0e0d6c7cbc3e1d399f536971b446feb25505d3e75ab8737b7a8bf98541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011354cc92d4f7fd7de00a85d6eb4653f33c81e081a6ef54e01f34c3880c11c7c1985782ad0532479d98f8dcfb037e5c90000000000000000000000000000000019619487ac29c5920f83db694b171257f6cc41390c3459bc977efe5e3fe74fa08de74a524824dad334ad58f2fd7c18cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004daf2b6f83593a45fd4838d26017292e36023a1ac8c7036e8fdea3e99357a07aa2da19543acb0496ade188a25adec72000000000000000000000000000000000968158572c40e51d91094f14629b3a4e02431c85538a9fedd0e08d948dbaeeb1941bc68d97699b98eb6ea6635f581431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd4457b87612ecb6a205a49f0be84d4fbf75fdb4968816d8c1c92b19fd49ff7bbcbfe73ac499f7b602b0a8925a96a80000000000000000000000000000000007042123ae8708a8499fd18d6fa92ca672b41bd372e550b820428820db74b21985322ad8f1d3d36536cdb0975cc3447b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bb0289b35eddfe50a2678af93fb33a0248ac2ca00406e9f295310e5d036c582127e3549d504e1cf151853895a60e700000000000000000000000000000000002ffdb08dea599a112784e333799d618a514d18bfb95657f4d97c23f5d17b4d8a30a97a25a59c1a37f7f77d3995e99751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133e4a31151bee736fdb3d0172f34a3084b4cc055ae96aa25dd910bde976d8d53ee36e34fce2034faaa7659d974e80c1000000000000000000000000000000001794089cef87d43c56262f4f5b4929b1ecd5f3a6116f1a46d7630ec2146bf2721d9c39361418b7fbaf51321de53b241b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002143ac4d66382c831dd0bde5c8d620e728cbb92cc2b02611f69f0ea895f44fecea96c599da45d2a9a264d756719030c00000000000000000000000000000000089a7476bfa2dcd26e29d3ceebe3b7411ae8205e6df1171b8cae1553d83ff09f1fbf82db5b08ca64e9c0e2b5acca2cb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dd8b8f3be4451b3d371d7d5d663e950741deaeb6488e0e1912b983dcf2938f61cafd05e0d135df0af23cd074264f5d0000000000000000000000000000000016d8f1df9cd54fc20486557a2bfc59b0eb0b89a4e24ff2aa4016dd1eb07e9430ce93b3b17cee24c4db3456c22875e0071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d81b20a63cc524bd3c93cb7dfa6d8f666871103f5999693c966da8f53784f2b05e51344dc2b5aec2f226660382e4376000000000000000000000000000000000267a7d07c557c24e218a006f271dace8259acf4adf7c965ba510fa2714c68206d0bb6d082525a32d8aa820dfabb8bc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3d5d505b8ddb8f6b6e9ddb39c5e7feda63ce1691ad47c22b9acc4895272f0b5a46d39d18bd8020303eb1882e671a3f0000000000000000000000000000000001950e22788144247a8a2e2fdd2dc4d22e529f5dd165afdd9a80e84ffaf602a88489a9cf141227b91b7df5b92b59b9961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010055455028fd3b5674a784e874583198ae38cd1a75d93175644d429ef7b940f5e20e9b0acb36df8d2714bb9627b363300000000000000000000000000000000097b3c25bea41b9325c6b4b9bf5340c804571108da83bd1e0ad04621accd40b87d2ef2c5591dcd7daa3da6bcdf5c45701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af8758d4b9518c9a8e8a1746e0f2a7d2b21fd9e3fb4495b4d112c251e76e882d94761c7e6fb055bbf1ef957b68348c00000000000000000000000000000000002f4d5b89da6542acd368057e6e1c9885215a73604fe7245f02e62cc151976ccc35038ef08ef97ef9ea5647ee38f8f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e15ec549b59ff5961fd1ee23b8ffe533e8f6e8382e2dd84b57228405e19ae3bc94db0abaaaef62aaa2475be46c06be0000000000000000000000000000000004b3a39397bc04bcd5f114fa17581fd714409118c5b74a1f5ea45b576afad2bd50a9524777945605a72ec41a549380341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87b0cc4f9059a5b548457b216907982de8ea939d79a83b2445ea45f0c6a2853e1443b78d0e7a2ed8e111ec33e4db1900000000000000000000000000000000033d7c045a5332712dfb33cbaa1a57862521f94af5a84349ddf15f2cabb8eb040226df2ee86587a6b5a17fe4a204ddcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001213bc3358e2cadbeed872e1783c5786fe80ded92f12753e376131bd3961874f83c18aa8ebf1daf89dc6854ac09698ff000000000000000000000000000000000775ece57afd032b36cf5d3e9ebee0121b3a667927a8230cd109b4d8c83e84a67ae09de9d17467656220ecaa44c66b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000394d17090718ba504f748071688ea9c99a4c6b4f37b79bcd7dc329592f1d8b492c0e35e3e660d5c30231d6f9c0f62b4000000000000000000000000000000000ca6b54ab44d758fc8a0bfdd57d13717788f9b0672b5e517fcfb2d220da572ff706524b7d247f15345936a223a5d61c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c75f767841c115f5f91f989afbf3851a7983c9228c0d0c22e3321825cb9ada3de1e3effcfb8f2479bf07530ab53b257000000000000000000000000000000000a96644036b2b81bdf8e8cf447df975440ee6421fd13da85e49546c08d9eeabad391621b9995d059f6ff0b7508b61e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d500cbd528194af718a06c86281bc02ad8456182db78be7073153112df532ea64321a6182a907c6e0720ade5769dd900000000000000000000000000000000057b169b3bca558b891662aa7c28741eee4490447f38dc4c4577ed785a952410258b420e895d3ca116e4efa16b8d080e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065ace26804907d15d38a507b272f15fffe9fa8dc5d7cc1cf3142f93f2d0c8d1bc3a5bd144e0860ceefbc96a33c00f210000000000000000000000000000000011adb2e8c6a4ea8043bc1c4778a3572b63f77de43dc9218a4a9de370cc82af04086aeda0347685cbfa328f9d07d8806c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507ace73342a2da65f092540bef86f5402633c874b35fc91dde21eb7338bc88aaad1ed82498e5ece65fe9f56323ed43000000000000000000000000000000000c6419b62dd59bdb5a2755704b22dff1249838c02cde5e546a14cfd3b7804efa9031d6c452e3d376032bcfb268c547861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000477b1e258c964d7b9994bfd3f220777641d54d18b1c0643f924aa895a7fa46ca54ff1f1b54d2d6f1ac85448a1f1e65b00000000000000000000000000000000125edbc8bffb1b884b0397138354bd87e621c4825caef64992c4637d8869156f71598ef4682b897d59445891663d2ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ca65c93e679d954e4ad8e71ae1963db5793dab99f4391a0c4c4f3e91f96a7ba7d258b682f38a322e1ec4eecbce5e8400000000000000000000000000000000161bb3e53d2f40ae1722446802c684b1d76de2823f146503633f99028b1cacb136ac08da25f5abaf02b65294db41a2061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c8cfb68f37f2130774e8eedfdfe0eab62915d37781ac69ad61af77130772df3337b0364081d8834285db6f7dffbef10000000000000000000000000000000013d53cb14cbd4f6961fe6e72889bd547dc004bcf8f35d7e0855daf58599ebee9c7f858045c83f705fc7d03a8494239f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001609400fbdff7e752e83b75e309f0d0a30c106d7ff4f39cdc88998be3b4c39687a05923d386927687b7ef7f3758a7b4e00000000000000000000000000000000054737b20d664a524f47917188427a53d53adc1a71d98baa71f2d94b735ebc0ad1d9a85f036a2c50c3c5b912cc253e4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4b8e8372cfddf6b0ea29befb93538da01430e3f0b669388b8c51e7298692b2b0823cdaae3568978d507290b0f5e5c8000000000000000000000000000000000c75f72e65cdf40d8aa1a9d3814a04fde3934e941d8e0ef21a055a5442f9954122dce00b0dc6c5848ecd3097b2ed6a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055fbdd3050b150a8cb5960af091c4dd2be8ee913ad98592795ea9136f055a9fd5da7b2ad7cd46b85d20adb5dce4aca80000000000000000000000000000000011551e409b3eeb1de4e90f864e0a74679c8a6fa13b6525d55a290fc72673b013eed23867be9ba2a9b4b4020c8c3c68561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002690104eae5966a229f57acf3553763004a5091a7ac2d0bfc2be4de3651442a3a110a1372b5fbe036370d45bc2f6cdf000000000000000000000000000000001637a90adf9fe4f43397aab004ec584b2b9dedf41412e4a0b1970e4e1d125653384f1cc4a4c6681076b57acfa1d58d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c545e621d2f23032a1b64dc393a59cbd05cb4ff1b67f47d6eec5f81e589baa4067042d7cdae9f7b905281a43ac9e580000000000000000000000000000000000dfe8e70066690d20381aa4530c5d6368d7eb23bfb2753514956537c2648a83eaa4894efe4abae2f858ddc0575a060f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a40440a688848705b3e3f9d3b88abe3da0b3250ae5316e32b809e81cf3b9c94a3a068a1da33d90be961bf612363e510000000000000000000000000000000016f953a1f8e1df494e30df6d20f57511289dcdddd2bb5495529ff574c37718853261dffa269e8f7bae5d3a06e736f2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124be474d61ad446810a831fc1d3fd47b4821cc915c373eb4a5a401037a89898ded96061a46c801206658ab99b2a9c53000000000000000000000000000000000df266ebf2f428926255fb74535c60ac14afb2d2a952cac47ecd90f9339350bbce30e2e9e52ddb1910916395afde99571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019774d7ff59a2d275eef8ad3d311d723e314184d6151133753c812ab9ca7794d33e8c36c03da51f127deaf2f26dfb1180000000000000000000000000000000006215eebe30d4b30756f9100f5085b50a2952687c287d75fca6758f657ebbd047ecdee68e8f85ef35f588283ef62220d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6b91efe1a4ff904f5e62ed5d46b3d4b5061a9be68929504734a0ca2d0247ee515c80523e0c8e159f98c4b931071c780000000000000000000000000000000002a219b88865140e41242a2a5fcdd443b0d0a631f856f6bc6135f90fcc8de7d3532234df936be7b2bf3fce5c704c877e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d737c22e18090adba58845d573de5c19033384586e3c12f2e357d111007380a5f1b935dc3273fbb5afbd0dc8ea114570000000000000000000000000000000012977b4ff957defa0240f23e456c7cd03da86f3b2d764f92b3cb7a5bde126eca400258b4c77ae1277c861f6fa6b421831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ac96b5418e7d87c4368da9a25a7fddb71f4d7cef07b7c73fb98936fd32020c03b0f904bfc5cd84012a85ac9eb9d8f3000000000000000000000000000000001856c8c60b6346cc8b2ad1b5482a5a30b42c43e37a487f4ac2ffb92eef8dc05332efd2a816ac591d55ed7663ee66360c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f98b89ade1afb85828bfde0efccccc0d4208ee107f0d32987ff92fd2ee7526939b496b36be5561c9350e6c40d5398500000000000000000000000000000000046753a3c7190ef7b0dad0b73d4f953d64664427d8e232b0a87c77c69b775eb4a35f463287661667a5f0be9d122b4b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d1dabdf454a196de199eb35ebedb3dc138a9ee2846e6fdf8ebc604d128f08b4a0d782c287c4d297ddf30ca340bfdbd000000000000000000000000000000000b6e627eaaf3d2be3ebe22d0a1d1d67c22c4f7584cec6c610133a2d3ac405f76e55b8025120196bf69f60bb89e0586201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c77ade0f0a5e25f927fa674c5d9a4e9e7823449c6b1cd7bd814a57babad2e7e927ac3e5de69c5aa1b21b0f554a64e00000000000000000000000000000000003333ee0e2ea188a9159a7452b1650ee42a08f381ffeb737525a73205627dd272fc16e8b8eda97bc63e87b70863bffed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6bcceb0edc5270e004287a996897616e59dded3334b4b7facf72729ae87e4d53b692aa87ff32c5165c5891b0ab6bf600000000000000000000000000000000089bb912b73b529aeda7aa80d6beb5fc9c7e9329de0ee9429aaca1d37a64002af5a64647fb413fd07dff1ca6eadb1d751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021dbb7fe1194241588dae053184c59957b7090c839e4537c32e6259d1d2025b3d5e12ec33accbf84b58dea35e567a52000000000000000000000000000000001341b6c4fc818fce20d21cfe58d3896b4b354980f392183120de37520c76dd564d452c1e375b03df397f1916a68cef261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026561e93e0e2e300996bd0b7d334d305df17a9440a70b0731475d4ce9fa3d87e99c23914a8bbd0bb1a23622b2dde5d7000000000000000000000000000000000388cb1632c98dc43c24b71f5f18ff4abec9f686c9dca7a4320fa4df2f16833a27a4ecf493d5bc15be4decdc1d45a79b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b24e8cfacab48b5cc1152bc431bbec7af6ba51d5b1ac4355d6bc11f2a9fc2b7bec82d0969a88cd69aee8d2d70429f0000000000000000000000000000000000cb54a0754fc36324922161a24697092251e2e80fa6bfc79f227ba695366add1dcd258fc249e8a6934c25dd7a34d2f481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6730888308282d820e5f49187f5f8619a2b1bb527753e12bd19b0696d6acc6e2eabcdc87a24e3160ab466dcd6763e2000000000000000000000000000000001272b03e3b0ad7ba0e6434c725c16d06950423f542dab0fc99da1c274a4b98b50557b56b4481890ad49de6bdba91da1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb4d5f490c6a43376140bc18a98fe3aa94095e7bb777468f84e0c01e3fc9dd2f2cddb2b1de7a40f1343076f5ad6ae5000000000000000000000000000000000474b848b0fe8c8549bed222ad805fb4b87969d8f524db2b4dcdffd1872239bfdd187f8b9e38cbc3dc132d216e630cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191458e3a3982195230be8fc9da15b0f6a4f758403415b8d835a5bdc086b334f932651487dd95977a62fe93ea715ec6b000000000000000000000000000000000b4e5321f8d5225642d1a79442a0a0440dc399ffc129493ee38fd53efe0a0ef248f9a3154537d3e14c652bce9171abf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655a595cabafa34059bc9e73344c6dd1ae36a49863d452919b153deef8fbec015c9a65457b8a280b145c3a67148c88d000000000000000000000000000000000a4445a39a72822b785adcb17f0e3b2319f8e3d7c56193bc14465b6b66ba79e8f56e448a7aa02c06eb996d0d71c1e3ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019327497181b3da5192b74a9fad4e33343da179c119fee4585cadb78720b18862e8583521db6dc3bdbc1380b748a753e0000000000000000000000000000000018d4620274ae5152b23bf21726d545c60239b8dbc8bcd62d6c88a9c554fba6717e48eef99eb78f7778d36580f746801c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f007b195180c989704ef5c99b67d9070c7e2ed1467b378ba259efd8e6abc8a3fc591f91096c8a3cb4cab2f18abe1b0000000000000000000000000000000001551bc55d0cc827492826df9c73624a56df9cc54088bd2b9307d0534a837f1fe2a171be154a99347c16e0f8305ce9681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b7e0642220f559b82ba41d2be17d46418742ab1f91a8825cc2ba0b6a9ce6556398967720c0bd6607bd0695bae66b5000000000000000000000000000000000275b70d632a486dabef2d92c1b55b25d74d68aa2ef3133d30f704c44e3b60685dfa888c1e4a8b42650dced216c82e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af520515fefc40926183fd2ae26c5c24f74e85a25765a74b6791f59a3c713e7fb57c6ce54aefc2c8154e710492f9450000000000000000000000000000000000b429e9153f77a3d08c5f0c47cdcf73513039dec6d7058137b3d23122b06289adf17b4dfe9aaac055a8079039a49471a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011447843b7cba13155c62b5cbb8a298eb7aa57db3ec78f7971fed1ff3f1722165638bbe9260c0c8b37edb55cbd9e8e35000000000000000000000000000000000caa709b541a29fd2c26d6f74b2c580bf898443377582d1d808aeb0f162d5baf55c2691be5d4804b1e402a2253847e611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136a9edc2c7456129c1b6abe908d7ce24985e0e9a6c8b2fbd060b29044f30907c1e94bdc92ce8150bb066e4bb48c24f90000000000000000000000000000000008eeaea50e040c3ace35269f330f40426553f1b92134f700341f5f211bfcc9a49273f9383bf01be4f7106fe99cd450aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195d4c8e78813c8a7a82449ec8e7207aa65008278d48eaaf87fbf342d2f058262c82e0f47f214ce343a7d8647db861790000000000000000000000000000000019b8af15fede12e1bd523e51af08069cfd0ae9219c95a7be41e3fdf60d5fcb18cee2bd9adadfc34372ebb7d5539986461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000402cb58b3447ecf2b0f70210c4349d5d096ad95990cf995dddab89569474c86286bc9ad47371b9e8f32048abbd02c8d000000000000000000000000000000000d9b22738c7c4bc949d329d80d898072a3537b3679bda26c42861b8cdf54887ff3fd39d5e374d8790c3f2a5530b0565f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cefe29d70e1f6f5545174744f891a8eae67901fe9cd9b5fed7193d722fd0bd09ba163f282da3b850d9b294e75d8d8000000000000000000000000000000000198d518d5545f3c9f9ae1165ef82dd26b50839910bd101589d1a554e9bc740495aa7babde13e376dc540b5050d4e1cf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148e4aee273b1f356f3ef9b89a236d3b1d4db651e50c3d4a9a4d5ea5b6fc5f0eda52152f891d1442dce8f4197b1978b800000000000000000000000000000000125e60d0b514de28de6a921bedcc3893564442e1c39db568562608bc8c1f143c2701b5431070f65d577b799cb7ffc5771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce47007e9085f2099163ea1ba293e61f097d1345784e06cf32ea0ebe14ba0510e3acaaa85d4d2ee103a6cc94606340000000000000000000000000000000000bfb05145276802bec90a48a0713585d38f455f37b0ef7a1b0e69eb5e9ce34a0c57d480312fcdf22d8f90becf44366931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103b362dbfeffe70db16e28037a7724dd6ddd5ce38250ed3bde22ff641627f21c1592c61c209b53e67307bdd2ebeebbd000000000000000000000000000000001392bbd8d4134a696acc372c29f36f37aa7dbbf8827945c9bdd1ed30e5fb1cf9f0bdb84012dd188aec90725572f64d0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037de20e90bc2003ccba1cee28ab1ac29c73ec4863340d37928dfa6dc5b13b72a366ba0f8d34fe8b6dc007dc855a852c00000000000000000000000000000000067f0946b593778041f6053985e8c6221513f804a7d3824c8003fbcbb6dbe5dedfe79ed7c3b68ad2bde5c68fcb4726031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018889018d102c17a1becace07ce19153808bed3379f7dd562937dbd2ddf24f268288e3952e53924bf321d87aaf10d2a3000000000000000000000000000000000fafe1fc9a9cc439d4e9531e1ffbea780c242ea4e52ee6ed4f92586372116e97ac828a49d177842e796a7c9ea243011f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7ca86f72fa0a34908346a0ca02b23abd8978cf1c37374d9f7277b1f3be7b8cccb62bca991e3240b81468918463f8c3000000000000000000000000000000000038ae872d7669a416dd85e522002f07d0769d90761a32444d888ef45dde6ee7350d26aa71b021a7d27420a658626e1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001654c192918a85053dde43f99c5b90836e880372d82d4532dbbb9ae9fd3701883ec35c63983bf90d5a76cda07dcf83aa000000000000000000000000000000000ea6f384bb572be445c7ee3c72bb92b59d1e262ebab4dc142ae075a04d7bbef2a34b81efb2c9bbd8399f8c5977047afb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf8f22116c9c7b992e6b6f0dcd9afd811be529c5abef4080f0143f46eab6141591744c7ee62e0b0c41053afaae9a70e0000000000000000000000000000000015e0e6747c9d87826a8523e32f125af9f3aba3d85af8a40fbd43990271e31f12e0a2c6c73289390e4eec183b889e79a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02d48ea861b1f3f07b0ff80e3c09a2e446602c523fd16e080bc480c7b8676357d6a9a07537cca50309dd21c5ccb4e10000000000000000000000000000000005ad8706a3fa386ce8858904bc8b0ea99dc4b5a366e6002a7ac4786e22c9cc9fb23a5e2e923b140779f756afa0f0cac61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0f2e66c8821fd5a443fca9535b992b0bc70a7caf62e9ecb511394d55020d5e66582d2876b776d27129d0b4d13fffff0000000000000000000000000000000004d7cfd164898b3d68b0b20f65d2f649837626d9f32084311a79f17c761064e25933c025fd533e5ce44bc4cbb0759ab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092dfd0b701731670e2cc923fdf8ed09bfc2caeff6296029870ee17f959fbb2154a5d59289104e28e56407c4900154f800000000000000000000000000000000159be25ae3fd44020d962d02d7a39a38736b88e2ce91261dc24224a0c6302b909932f60ed57f8f9d50bc77575fbcea901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f7b3bf08b78102637708ba44b959abb5092bb339de8a61fcaae4ef4e35970fac9259dcada9a896e3383cacefd3123500000000000000000000000000000000000f201fe244ace590e44de77e7de540d188c8e6e10377989a3e015f7069f13b819b1c6268ff6c32790904cd0b855c2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ca9779363e4a448b0d360502660f71a63c3e43f7a3a2c3883e6b62f0c4ef401530db411a6a7846d7c2306541a0058000000000000000000000000000000000fac7156c23e112cea8eb3f064c16d3dd0502f127650927dd38170071c02a0f3a28d841b868ef5af250eeccf70a9799c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd04c1a11eea9377809a62d3847f5934e96ea7eb682ba7305f53a65bfa899b361278e0a5cd1fddc032fc84b79bf910c000000000000000000000000000000000b1259b32930e5a66a1cb2dffe3a2a8e8eb277d38f9d4ce73ab1ebc591bf7b016b1f4b9beea946a6c6bf43d9104b91f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000728dd39e3251d651edd206f0d2126caf71c353df36d1aa4a5bc601312773af245ff296125c8fd1e63662ff5e6dde6c5000000000000000000000000000000000632dd081603c7036a5f1f9dcf2cd028a8f38d83237335dbbb52741bb6ea87497918024b2808d9c0aa1e4609ed6c93d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ce56f5615ef97fdc3ee13e44d597da433f1d91d0f86e8375e58a1a0a3cd8603d587cb57b847a22f458ea36a09562170000000000000000000000000000000003ab8eee8fef0e230b286d2f240292441991d7221695474bd74657de3cbc7e06765de6fece7ea589f8c9c113e0c89ef21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018857d052a349f52000f0a355987bf6bf1fc29aa304117c382e4f337de9a65dd1ed7613c7955c1efb47931c42a001f7c0000000000000000000000000000000007325e50231dd46009a063279a2a63a84b997842077cf5272950e246bae0c1f36f9568fe9b0da7de13547ecff957c2e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a632b7414d13c76d17c0f272ff0718ded2bf6ba2ec9e3452cc9ac6ccc1f54ef69362bab463d9daef5e63c9f5cc531000000000000000000000000000000000e55c09dd2050c956c6d3b3b17fca72d453c7fd8a34e27501af521e003b0c03847f35526b88b60fa97ce0906dd7d3d2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f323eec5c18e2d062790de52d120c643d99b40a7fcc8a98ca17d3c27763e6bda0cd37f5f3e56c379329a58fc47dbc000000000000000000000000000000000b8780b2028b28e1caed89d085637dabb9cafc704372a0873827038d44cd78c5de6856a2376c4d38161305a837979f5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fa4b01881101f973b8bc201b23144b82b1ae85aad670f9ea28988d63770580e97704dc98f2e2f17c7e75735b5fa32400000000000000000000000000000000045b3e531d921c65d38570137b0441f1748bc12fddd2fc1d8458be051c0ea225d58fa25967fe2cc970927ce986f87b111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f64ae24498f25d84ce0b198998e191d6a8a7d728a2008c6de0658d689309c958c0e25f0b47bb15043541fa25ee5f50000000000000000000000000000000012e94a844965a8a1aa38a6ee73ecf065efd4c6202c6179fe63f0c55981ccec905bd846c1586ebfd06367b37580f4716f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153954366e6b25ee954a0356cf74b9361803ecb087207e64e276b34e1fb21d61a458c3f8f2b6923f67361f9673ec7703000000000000000000000000000000001126eb26895317c081d22db5b26f50abdb6b91e22eed139562f9bb0fa81c7663f90868d33cbb5ed645232d45a03266fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017122498cdd636fb5e3cc453585551fc6e0be644793649f8b7893b464df938b8ed246fcfba7e9e2031c4d604fa0197e000000000000000000000000000000000972a58f61dd6f6369fafac0994a567fb64ef823d4ff5a4adce07d56ffaf94b57f1b6a5b289cabf1cb6236e9aef6dc721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000895b1b5e589b91d240f83f6d93c5dbf86349cd2127a16bfae054b2f6e59c19bea6e4f1bc7f4a0183e03f906fa7f98670000000000000000000000000000000016357ec0e8d217e7ecfd87c69638312e28ed98c1b25fb48141b6c3c79c4b1a47a014de7801c6d90475ab754e480bd0ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ec4c98ad649af7fa1eb1d6b09758df2f31e1869b5e2d8d94d02347f3a015d1dda6e0fd317877314e55bcb4bf41810800000000000000000000000000000000054b715c3e79f361813ebd633ee2d0a6f5118f54c2ad6fbb0bc9ac80a62a7242e23ed7a8039718f79dfff2aba3cc402b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8b7e910d01fca5ab5e53ebfbd77a199a0ca616523fcadb46ce2fe5d4d8279cd4ec9b52ece33eb26ee53507c8f09d73000000000000000000000000000000000e2616f17fca6fe5ac9463f86f60587e1bdd432e43ca209634a9ac13c3381927c4dbf9d9d32bb9f47de02c88c2e6deec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff1cace6e7c369d483ff9cdd7659b8e43bbc6bcc848ed824a9ddf70719e11143cd4572001101d84a6d2fa677dff5222000000000000000000000000000000000735cf4d2a1a6558a6d336ed5fb31fa19f03522ec6a053d2b4ab7481c78067bdea946b190b138c75adfa7a4da25077961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052d2270965ca2c49226db6c1b531f90ddaf40e1d80ff61286eafa2f372e700c2a0ab45235cb8d79eaad3e69f7f8bcad0000000000000000000000000000000013c7962b4b50b60d5916bdf15ba8bb1989604d599908b961dde8a548315e76eb70645ce4ea8db7c7137a06b5697c4cc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c5db34a79b61b7ec44d8edc8745cb774b18172b83391b2a6650c6527eae588d3de23222e17188e83a2dc78800fd30000000000000000000000000000000000fc16dd28a0c0bab7d22275948c553189b835661e6534d2b90a4bf717875dc5904feb6541aa4e2da11a58a489ec755fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f1997537fb52f94d196026f56fb09d5e93e433939c64e3ec686554c0e05f4e821873ba0657eee4ce170925198bcf5d0000000000000000000000000000000005af4e5ffae463ec39d73cd350ae1e2d7f73cfe7f2f20e7f57c103046680d60065f3c1d0edf895d4eb1353c824adfb7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c2bccf4d3fc88cd10f863228d76c9d3199bf2f1b73016b6dc33611dfcaa2971364a1bffca0d363c9469e756afc447c0000000000000000000000000000000017c073af9ab80b163dd4d87bc7475cc6d2005c0166d96bba4efcbf218c755abc3b7021021255ea19feb0e9e1e5dd81d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c819673e6ae10757f839040118b8b609721881dfd29f06be749a91f58f7a308a3b4a9c3fc30632b2d19de23fade57b000000000000000000000000000000001265cf971440aae83691f337b08eefed434f6dde1369333e8e677863bf404a4f515b338b441d7782c86e146d666851e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a8b6beba9e8bd3f58f7949c9476b7d6fe7de81aa04b8d74c6dec02ecad333e5a37502bfe511b73fa54cc54ecfcd88d000000000000000000000000000000000fc1bf78b29a82ab4e6466b84e83aac98e75ec6402c0179b0e9f2b3d27c8a5d3deaa093f93cad5f97df5e082fae382fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ace0142f74d8ebda313896beb772d001f67a61963c0778788076e50753bd93e8f83e3529975c91699e4e904d9b41090000000000000000000000000000000003827f1cf87459b1dbb80b1c585f3d29dce2690ead97737f02e6d86af1f1d31c2fc537be8e7b50d8fa65f31b7b8b3ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f18a5513c8e08bb3e4e648e5cfc15ff9d0b5e4bb031b80b9d2b9f3717fe617d7fd6e911537fe15be8b130644e32325900000000000000000000000000000000185c9209ddf5da2ad0a1affc46eba28ad317b425034b933d17811a6ea5c1497e5ae6adb39dbe8627d9c2fb6f27a4985a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000394593f5ed51e8ca8b5c44b1be690c9b4fc908cec57e013a9dfcf81a540914a854879ae39aa318eb3341f2ee47417c000000000000000000000000000000000103376f1d7015e3bbaf4d5f107b377bab22a9f026fcf4ec3e90258b87f5ad117f6e63ac8e0c6165e2ce7824df4558ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163a022be3d2838cd964e0052a67aa9ca9710dfe9303588d60335624ed77cf97bf5960da8ef7e4f0cab8c15bd86a25170000000000000000000000000000000002a166469e59d361ea18f766de68ade1005ba61cf785bb670c3759b73d6d23f06dc0dc6c8fadf9a146070390a0ce0dd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056a3b1d7c471a37a93f9835d91c167bb73171daf4f548cfe7f3363c835426a4087dddcb1bd4d8424557ff56ae84a6020000000000000000000000000000000001a38757d9235479b0c78f207b25163e77fd919d8775de5d4d950182932e78da4f541502d5bd2f9090ffb899cafe9fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b83a476b664c9d22236fb0b78dd9af817f99b043755e6ec4ce09c0de032d840d609b6e3aef61f04bbb58cf6bde077fd0000000000000000000000000000000000d67f089e57cb578d4ca1225ef76fea52280114b7c4bd2495e5f845b961992052b12f270ed57a01ae548b60c6a32cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001624d4ac492511f52d5ddf70b03a6dd5e26a738cd6ff634e8dbfd19aee1b6fe62054277c5cb4730b6a372fef7f14cba3000000000000000000000000000000000c41e675736703e995e1e6d9659f3f473ef344f893d8218a8fa50828fdd55ab74a62c6e60141d72f3c278ca9c3c5b8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001780b01679550e813260e6af24e5cecd00a74442284a4b1d01628b32de02122fd3f959d9046d1816729d7754bcf5bccd000000000000000000000000000000000cdc847b35e8c1db9d3304bf8ca0f9bb2b6fa335e4a233ef3039eb44b91cea40fdc24121ff99d595a0b867a43472fe681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb87b3d456df47fb80f2f6c55c45dbfdc7b00024f1b48947e4c92c5e85af28cc5962b4f9bdf9f042a8c48716da69b400000000000000000000000000000000043ce44fea4a0c9529546ecc17987f6395167be1856e9fd9da84781ce45e2363f9e6e55573298c7ace3b76398d701c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001944f6184943889fa740e193e6b664cc83d7cb73b868b6a1b9680d86f9e534330bebcc2912e08a30d67e5d8840e5a762000000000000000000000000000000000cf87dd015b4ca5fac58feb35233ebc9920fb44da60a1bc045be81379ed83c5c83c0471cfaaf6f20a77afc35618c1d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c9407b77e402877b2d1926d9242d228aa7813e4fd825a7997442f304a777e96072767f02cd9760c56be73a4342b6f9000000000000000000000000000000000dedd33dd3a61d9724670ffd95b3b2ec6e69235ed651dbd4c403a9500723a71d8284191b2d757506fcef2cf0c7d21b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e45874dcdc3a10a3e6bd859c39d2a419ab2d0529d42583cbb777d253817afeeaf9c7faedbb06583be004d0b8c30267000000000000000000000000000000000c2c7ae0fcb6c775f55d6ffcfa63476e61697e6aa6182810c91e4c48d44b5491a4bc858070bddcc588b7b41e2ae6b54a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154e9075f6117a788418a690d9ab818a9f553e3f288b231293701f70b4fd675bfca730c39dd61a50f3e7856a651a6d9b000000000000000000000000000000000c5530571fd75630139352a15cfa9c14e5f7c0630c8ad93af3957a0912a572977320aa5622eee148f83dc7a89ee1b43e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203354573ac13ea13d25bab55cbf7108cf457480fc8a2d6b89917b2bd83f71ef4378140a08e90771cde78b381107bb500000000000000000000000000000000182f3db4a1d75468c6296e57641e75cf3b4f538bfaf92c7c83eeaf07b40ffd4b1d0e0f687d1aeff65d47463033cfbb4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b25f93a4b0dd05dd9843adc1b4172c81839168566a2b927ab71241aae9192293fa8a3ab5812244c531e501cf8b395f000000000000000000000000000000000fe8d6a81b7799921c5a9a8512f05c58b1734ce9909ba0855629235b94492b70ab849681bdf05a1ebfab91346c2a978d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aa1c6068eac3cb2d0748cfcbee9b164bff473896a3bf05c7a20661a41d43afe5a1f7c90bd667d51cee7019d19f39f80000000000000000000000000000000008c9d4256efef29255ef4433075264937a7864ce5f000006cbaf2269dd389c548d6f88dee0605831d88c6d9f988093331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e4743ea94c3d6d73a2fc7d648995656f87134a19717c661041230b4986e6ea919856af73e5c55dda15a65508e0b5b0000000000000000000000000000000005909e1c21b8486d46acb4131419f209230c7d1b88ba86f8f4eaea14fa06e5f01a39072a3d331eb52af1ba9547f9e4681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000713b4e2ce31c8363175b3045505c8193ebd1dc68ec1d5d638b7c4eb81431f401d4eccc30fcf0ee9002ed566765cfe5900000000000000000000000000000000118018abb0ab2877211333427c40a7286662ca75e6254aee20ec3954a6e90311f8dcb989d86b67ea38ad0ae4fec855c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b33259c2bd24bbcb8c77b21e7e63e2495f3f1f4ec75a83d6c0e0bd46a878c84d9fe0df14537e2a2febbc52b744655f0000000000000000000000000000000016e000812f8ca8b989c583f03cf36dfeb21791fe579201c8d2e09cc7242d4039bb510a4c9cb583b64cce8b99e2267a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112aa9a3eb360728780cc0fc7e82fdd600fe3bde53d06a1612ab7cec9582df90f35672183c5bbc7dc3f4532ff7dbf9a0000000000000000000000000000000001129438b56d8e3e30af00ed805b4a8c0df361d25c8cd302edbeaf3a488d85945f8e741addbe8782d3e84ecb3b01560161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094b34bcbbb8c9412c676ececb8ed1c41a4928d395f345e1868a4c7c0514109698e31cf535f393bdd2072a300746b3bb000000000000000000000000000000000caa9f93140afb6b1410fcb6a8fb622d87c5519174c19f3ed31d5818ef9d28f5b9e88fffa486546895dc4308d84b7e631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6b47b2e1298bf23f124252b9c0fa6c278fef6acc40571d22580f3e9b2e344f1316e4ef4dd4c4aac9b865f6511192e90000000000000000000000000000000013cfdca57f264c1c82e8072beb618a601988a6a6746a381b1f8d170b9359aa15cdb7658f2610b7eeb6dfbc1c4d4aa6031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ac696014595f119e4cfafb03c32842e69d3d3552d40b78456fa3859032cbfe0a18ccbabba3ce1b512aaae0da9f433900000000000000000000000000000000033564cacf212f71672cdab25a2cc7f7fe29ddbd473522c0fdcae704227cd906d4d239e228dda66db9a09d68b7faca041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb4138910df1da9b724fc850834a29f9915aaed5ec0a1b4bd7839df1cda322875625823e6ff3e577bed88d7735f7a900000000000000000000000000000000029a1314acb5c437c72e580100afd831d6083bdec9b562b1dd749eb29a29d7dee8cefb0bea1b53bff248cb334a536eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cd78dba670e10dd682ad4b1ecaf563cc793160333854fec5773504523c09332ad437d5187c56b536cf116d53c4b02200000000000000000000000000000000112c4b7d926624d466adc512bbc810258aa098e6d4af5b73483947fe2fd427e599b3ae191454104536561fed5c16ef2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2adc5496282548bd2d65002c343b0c9493ad16d3fddf324fde870214164a4d96d1c0bf34618473cf67cbc2e844e06000000000000000000000000000000000ea4f2d957b21eb87e286e75acc8e1d89f47d3ded2ad1bddedfb7f9d5b43d1260aeb4073d95c9514ee436a16c4ef2b7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1e6934a1e3c3a731a80d149d53bedbde29a34077333c406adbd48c201c8007f74ed028b3af6c107526a8f51da3ec30000000000000000000000000000000014f1b95b6414120fedefacf2fd5c8180b418c69aba43dafdee311646b5c82eae024c336bb96d94b2044dcfc7a96202781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000adde0c3de13b5021490f37c9d917493495b94b47ad0c44fb56ab27a64788291daad3fb0896152e0c8b5e05931651ea10000000000000000000000000000000004634c6ca41775d92bcfd61e2665b3f5a58ea6cfba597e5d401cf92981f04c309f5549af37c1d3c3c3cab81aa4ce03a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ada46325e812135e304db19ad9b040503988336f4cb129da0dd55dff4071799fc86ace822ba1f1872a7a1d26da2aa3000000000000000000000000000000000d153d03b839c0eb9b9d1f2b486853e9d42bbb6487474e436190b893f364b20d0c5803770236b9e35310d819a1eb0d1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ef784f949da0bc0216c448f5b0821cedd3382f0fb7ea24a16bc425138ab4d792581b7c9a943e085702b59eb18eb102000000000000000000000000000000000620665e06ca2a9984a2017a33c089e3a8ca040aa3317e3432bbe0f00b7bb0f7571659f8f93356abcc0486f2b54157801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cccf3495d097d93244b950b75d5f2a71ca82b993384d07083f186b497ec9a8e0fb5006bea898142a189e085a85f4230000000000000000000000000000000013c57f27681a2f974f7409538f213753a09b8694c92f71dda53ab3ccc2ed4f235b49705f205c8da43ff74de8864f8a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000deb3725b064be6a19c2e9d343aa8f39540e701d6843a3c6d8e0c0f6ea3924938d35b204810fbb3158636606bebc572c0000000000000000000000000000000011be3fd18165c7eb43ab98697f040942c0bcf1572f93522484216731aa434160362789e344e60ce10e796726219425801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067054b1aa99d31ce601a1725c614afa54610b74d97fe245a35ffcec99500fc7f095d4f8d37b1e483464eaad0193ade40000000000000000000000000000000003c26a178b334b605a24d93d1ecbd0058c7f8eaefd28fe992d75dacaad7877fb828dd20f3d8d8987122d9de820bd7a1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfecfa9732c9a9cd3e237bd0b1d00751c4df0a091cb372b6dc51baaac96138d58e1546f7c38550e230081d56562ac110000000000000000000000000000000015f233887b2793b0214d814731b8f7cc2baeeccf340f9f9de6049e2146731e830e77a58722016e2f657c77ad670a0f351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e6e173054e1e2b89543830f767837091e17e7ab78053e9f15598c931e8e2bccc61364d2134905199b3614efc2ac43000000000000000000000000000000001614c7e7c54f163d58c892a6fad75711d706c138da9e478abf61b05db0c7951d889a3edcbd802c1c25e9b19885097ee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018438c03c9e56431cd731645ed45cc8af9687f10b2a04bd49dd1867a46c6497a6dab56467e178bf22ed2a874194e19c4000000000000000000000000000000000bd5bfe1a6141ec755e1525b8737b3a329ffdd949b7b33508e97d428eafd72dee74af212c81348a4622a635eec2d40661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197de8d809db7bc5b7dc4432932c1e19db2dc45bf94db6c5d50420da22f40d785926ca6c36a4fc55ed273570a0c1e0c70000000000000000000000000000000016d0222928044b65f29c861f16bbb974c4056291271e05a5ac2461ff8800c2f575568bcc94701086db657f7dac64cfb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e1a6e0c394616445f594928751be00f7f565af53558cd4831bb9d312113642bfb2f4ffc45bbd87d2f5f4e12bfea150000000000000000000000000000000000cbf3311e1b3e2cf796ec707570b3f7265154cd0a001fdd3378fbc89083dbe5e47df6fd591ede10be2b341a3a41a6e681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c43c5d23d8af4bcdf323b5c3f7d8976fbdba38a7c96d1537a60e506064df7e3b17905bd23fc5545505e5b2a0aa5f7e0000000000000000000000000000000014f2c90c76e52e2f83724aaad91c9c0346f880cbf704e8fcd954c5ea7752a664874865ca01866d329e7473b639b24cf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001548960781817c6aaaf833d79d42649e57f8d284297a37eaf2c20a275eaf1c8f7ea9b858a82049536baf04909687fd58000000000000000000000000000000000df030d318c1eb2720169d4f6a8592efed7083be119d6128e127c6d1f8327c942b63346ee32447fade5ae7a2c8d3efa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c4af0fd3a0581158c3c6b323db4a36a44bd0bb9f021ede5ff8b99241d8cf7f20d19855283796773ac143d1b3e1721f0000000000000000000000000000000016a73b1d31d8d234af8a9e820b4d1ec0c584c9591f7421cd95623f450822a8bb2e9876938918d83c7f8da1814b361d2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d43ee4b9ae7d04ba723e360a3823036121630180bb967d730f99c7ea78e65e5af64ab40ad6ef596759d581ac1cfd3b00000000000000000000000000000000137868ea6b2182e10d669bd461a6b8ce6c2c3dad8f7e7ad5f657310573633031a09addd06eaad2fd92fc6e143505b31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001387a927c70a0edef3f4325b808581a4fdb07f33be097e1a082cd9f40ddc46346ad79829e1d2c87d3b130590975075aa000000000000000000000000000000001534a5ab9370de057181378ec7e580bb67d6379775668ba0566bd8429d832ddb4821c59ffb807e64377d4e2cf3a575ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187a84ad4cd132bc8dac86a6baccb53cfbea8a1bc424e43f6eb3ca03d7a2858db8f143d76a5692d40551e8d4396efb00000000000000000000000000000000000fc0795744641d0c90418b764fa216ae28ce7edf8c5e77266e43ea8514d39f4481358f92f94af022ea8bdca728fdbbde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098f99707d90bda18e305a03b0fd02a7557fdc355d71e02be92b633442b0ba55c850b3c020d36b249c61eac9a9b68dbf000000000000000000000000000000000796872dc3cc45efdb52ebca0301025bbe06aafa0494054e1879fe7be86b76cb145a6eca8bddbfd55f45078d2d97099d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f66910191955f4025d7638c8b8c82755e7749618f679a0cc9fa478688e7cdc52757e219a95c6afc5541ca929aaaf360000000000000000000000000000000001979109aecb27702c0a9591f7c002a0bf480164f4c48c26867ca58f3c1fe12e627f731c93ef3c599de48661ad906af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064a50eab9206d132a9103d64eb5574005ba4fcdbe50e889f648129e3c5289fb318156d856c8d5e0c8e41dcb94fb53cd000000000000000000000000000000000f639d12fdf796294c1bc245f22b1fcd80bfd90e0847309c51706e7ae7a15e2b3c2941c94d74248a0ce723e00aa91c551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccaf612116d89f15c3f3c827162b1c259dd275fb47900e3a82477482d62435bb4f6644bcdf81da5c79bdab812ab1e0000000000000000000000000000000000afeb0f167b40ba2e3f99634a33b4f988a826bd7251e523adaa0e7c0954ee0eafc808a7472f73ef02da707ec38a7cb361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769e49b8a64a68ca5e895dc7695b4db31b3da69eef2a11a94f473b477e0584f768c96594e6e397b9311a271657e42010000000000000000000000000000000004caf21a77aa0ea516159202b022f64f4fc7aa9e7b01bfc711d719cd1a0dd7bced0c7342b2f0aba16fc411c4f6103e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001709fe2bb3fde768ac4b01a857472a98e4141b23ffa830ad42ca23058492754a67a2e749eefc09f48d94b740fe306adc0000000000000000000000000000000002402f51bdb7242903cc54d7ebd3d744409fe8aac8eb4659f6ee5ab4429f7403a973f85d6e127d9acd51d1641f2fc0d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098b3aee0c4f14e96ed96c220bdb30836a9e8f91dc7411d2220a088090475aedbd3e0513c0bfdf07f93a66f012a872eb0000000000000000000000000000000017f73fb0213a6dc18f2055c480f724ba9cab19cfcd764d725bbb3c752cdd539e75caf952b498bcb1e3feb5574ce6e52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d0d4731d899c384adb60348fd22569251ec1d7d19ac224618cc9bd37d104abe19400485f9e22dac5b0f7c7a71eba2000000000000000000000000000000001057dbf8f57634e103b28babc342e30995b2a7d53123b5ebeff687776ed82a8e2d5dd81a53a2ea6f1de75ee8323dbe711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183c93ba9dfa0e1c6d9ba95536ded6e78d606d1e76f971ba568d6fefe0f8fde86bf6f04b1a66e6ecc1bc9ce71e2ba5cf00000000000000000000000000000000014b9732b90daa700ff9e284e58375463608dcd7ce8b1307ad986a39c806caaa0f57251956ad7ac21a8632945997cd391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b9317943d346b692d32f67a8275ffe1a692ab3cca0acd56fe99cb2ffdf674ae05d53db5b34445df3cb3e681b91ae0c00000000000000000000000000000000153ebfbce5176ef8efe90d88c2b6ce43b8188d380d7e639e9c06450eca86e17ae5ca50726976a5164e78eceff2af69191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190913f75326b19e0d55a776964ae813b02ff83977ae18e59510ceed8fd7f2ef4427ef8bd45c6ce6483f3cfd7afeff41000000000000000000000000000000000a9b9b73ba6f057199ec981c656fe6ed1fc65c89abb665a0eae3ec714f2e8b25452097ba0f54f7d88cddbb214bacb7691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008198af373a3fcbfdb9737486ad42a86c37c679742403e61c0a381630737f060f28c05cd9333b0d661321e9af404c205000000000000000000000000000000000c3a2ac921d3c0e7aeb5a43039eada3b633c4659fd059454cbac5b9264778ec5bb9557e4313f9893213cc3b56c70e0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001717491308e7f441de17e64509d3e5391222246fb318e221bd6937da55c1c767026db8a4564ee51e6e301a4ca4425622000000000000000000000000000000000327cc54aa5fd382bc4df6eb4f0e0ed2e3718b588c62ba5a6da7f0a0308d6c1fd9eab0f065410847bf004e2c1e3c04b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ff0c994d65e0364ada3c3ce4eaea9441528e0545f03894b8c46305aee4e952917e1744a6427a9956cf4a5367af2130000000000000000000000000000000015e143971b656526ea728dbfc7f2c018ee42987a5d1f0480696ce06168aa6d6db7e8170d36304c17aacdb53579ad29fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe0bb48e574ca28860e29ca02400883004d003f521d07b2a737c8919859acd968616edc2f6a5ffd62ea5135bfe62ba0000000000000000000000000000000014025e83d1d873a2831c90671988f9fdfaa5cf91dc546b6ed9a0d6a78b56c85a30ac919dd165ceb0935f3bfeb04221721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000feafe20727ad9815b9d0e9e38ef750b8e5e58257c37a1aaf870c2b455df71529bf6d3ca11cdc081c0e08feafeffadff0000000000000000000000000000000002f4ccb52e0b77344077ad31c186deb5c4a21e4902a5005464a35d5cbf8bb2abcb0985fd260069ae5294ff018e6bed0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c47d12e834d2d4d46c915126e06d12b6878f58b44afb764e7d0261407966d81177ad0dcc4eb7619d9d3abd710f4b080000000000000000000000000000000017b616805b1625c60e0e09c1da70e7f83d1894c97ab44575297550847bf7fa08ea5d731527b662d480e7dc1e300226261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f0d4282a824f35a48d1efa413ea9b60ee826b849a91bdcd960e3f1137a17ebfa9008bb188b7908d5535fdb7be77abd000000000000000000000000000000000b65f410a042d519862b87c1d66a7bd72a8eeedbe1b5dfa397dff53d2c3b61f77821b5f1f8eaef9b2d18f6ec336da1821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001718cc7f8cc5371f44e7777f66f0218cf3d39abf93fd2261f3c3d7d160da8193e9d5b12008c5959a58eff8aa839245520000000000000000000000000000000003ff3c7366737775dd651571fc420d138883a2846428ec04104c6cf461f0da6500036c08f057d4aa9dc69c4bf21cc9dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d8e48a0f4b5482868b4fa9d12b1adba697b249c6a578237042bd731fb791830bb8c09d80e14cbb602bffee50fc9d270000000000000000000000000000000008010048241948772d30511b1fb7f77bfa97eca5e14efeb2502ca1d85879f9a27a1b663b452a657c451d006490b3940f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127df660352ad016e565ed7cdc0bf1f6c1e729e08108323b0e171d75f26ae8b0bff101bdb24365466317027cc8a2d98c00000000000000000000000000000000178f7f91b7b131f5b522be02188cace1d7e42d9a224eb4555a7ab8eb6a8fe3cd86f3be4e162a97364e24f40375177f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035b7673b391fb367a47e88e5f8d243ba7e78f454d2e3a4cfe98abf33b1f81ad17134b9a850bd252ce5f788f742432d000000000000000000000000000000000156021692b862f3a3d10908e60cb016a5b64af86e41aaddb525c5037208da77839250c3c08175c3662bde33c310b6dbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001356ee463b4d39178ba441ec481ccd9a9e24699545311dcf9ce7504c6e71533350d917a66bb8e611c74c8f24760c6248000000000000000000000000000000000964558bfd791b501b102aeaad5c42e08b161648d5aef8af7f274631eec68ee5bb913c89b7f2b2545aeacdfac15ca25e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae096a580e752a44e80692c2a95a60634e5fa5b2843e8769ec13ef11b1038295719c4ee4e3ef7c6a67673792b83033a000000000000000000000000000000001225f8d417578719295cca6e0ca0f207486b11ba38ccc023c2aa28bb831926d2018962ad0d987ed8a4956dabad77c4fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acd4517399389661eb415bec10e4e66291e792afbefcf335beb38d56e00a9a3b3ba8790a02ac530d550cce1bbd3124d00000000000000000000000000000000137a6f6f53905d1a540b84057ef56be664f67e6cc723362b2a15a151b57830f1e9b9fb5aeb127cf685ae2a7944bf04a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6fb2fe7593b3beb8767c2fa7e2db04ee7f76aebcde2dee14f86ffdb35b31469d2978d74efb870344dc17da7b1dc2ca00000000000000000000000000000000073e9ab353a058159f4135b8d5f01dd1cf7e2899b0c5c521804c49f7e85b5b2b75002c4f2307146ae7335a11beff413d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001529b7421e683b48ee713f4f92cb926a05b198d111a268b0e8b5c3825237f385172faf23fb6431ffcac050395bd8b1260000000000000000000000000000000017d19067e6e363c796cab866318531cb170082fb19b686e50360b65ec0f4f58ae08c72a050ab0991cd7b421abebca9a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ea13933e3dcf0130eda9f1a4504e0e61c3eb5874bffa792579125c6a840695f5de4b31bd02834494856243c51be460000000000000000000000000000000004777c406bc24928b81e715bf581dec4332366ce8cc1034bf436393147a1e64bfb7ea72cac416b42f96c0708541598821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d07da4ca2bfe04458cedc26e2c5aaa65b93ecbbca814e7d7a42b9ea3e446c24dc565d0c7b5e9e52c5a1c379e3d169c10000000000000000000000000000000003a6fd82c68891d0b56071bcbc88f3d728477343dfb21173f210cb9ca1ca1a0164bb40685f67ae27ab6d0005ab3d6a131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae6fc9d0dbf9addc45002fcd2c897b76cac062187b5f930c999b5a0f0da8152e896e3dc731684346b7b8cbf50dde6b0000000000000000000000000000000008d3b5f0f55cc1da7578f81c20530f1fa8717dfdc2aef1d348d90b160c02ba86f5caa4f6f9394031add5923ae6f742881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068d91c7a20d92492ff4ff15eff47307759a400f4c72c3fe26c2e1bc0427bdeb44bdeadc5fb56197ae79e91895d328600000000000000000000000000000000157f4d4f972617bd6a70ee63058d8c1b03d8b9a3930d825daf53a6351036758012fd5b312600ca9841f41ae041e560081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d48dfb7214495d23a3f5d4a5c2eaef2e4af49a14fdf2143d4aaffa611a2f7ca7e081b07184cf0d7b326757a0a72e8f000000000000000000000000000000000e816bb0c865957a2dcd1da14bc8043edfcf06fe03a0bfa3587dde25011862e32881ac9894e99e3d0deb0b20bc5beab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000981209c7a79193a170d1a6cad516fe828adad25ecb07703fd2b765c0ce81d2e5784ce027657741840d359b7c8409c4a0000000000000000000000000000000002a6ab9a5bf08c438d073792eb1680f46941c77c2de9393d6eea36214c7834d9f6627b8c1958ec58725316b5b2f89c5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010902a41f82d0ec79b619a27d59c1fb40502f04d05e7e5d296a0770b0b2c856107607696cc58d04377ace84c5ecb5fc10000000000000000000000000000000013ec7fce55163625f845d54c359b78bc6e070d22c7132841966ddfe4b3501dfedc11bc58a440c24e818ce8b95e3a55c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a80ef0b44c4bb40dd27b6dba81226f6ef4756a15519f7261b4109305666a39ddf7d2d39488db2146ff203d68589d480000000000000000000000000000000006e990462537f9937a29fb42534400c0ba20d1165576b1371409d654e15375c7f3602b8f3ac54d8e8ee43fb9034eaf001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a61f53a9b5ddab05f17b840da7bb915eafb4b45616ad82f4ac9c3a3da9444cd9c966c4afc1c98e12133fb9483904c1c000000000000000000000000000000000b8ed02ef606539f7af3c5a28c512f15399d7cc0208dd50ae217241ef0baeb248e93004ca1475297c750405bc0c607fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa71a6a7aa4a28aa547d9cdd439764f31c920b32e6055ddebeec07d7c3f1146a36a1e1d6f707411e2daea2060743363000000000000000000000000000000001468a10ec26fa61fb13aabe2dd749bc45117ee0b23c2abfe9593a40beb35d6d1faf87258eddc06b472b7bcc39d8f0d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d08308b02c9ed31c8276a8a9309a2641e613855164336f4411dd1cbf8ff072429aa3cdc8c047254fbe2f3cec68663000000000000000000000000000000000d30dbfe0afe28320ba5d90ae312dc38218cfba4f6e79675a79af03e3c2dd3ae6b2044471528a8e808b41ff6a987eb2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c64f85908ebcdba5b886c03d2cd6c05a9a2c62854e5eb40453888dd5e64a19b3453767cd1ddccbbe5a00f7f00df0b070000000000000000000000000000000012dbdc0b7d809bfc1b982ae863165ad39c420b0672e5ed83f9b291fbb6632d5dbc3663feba64a44c80702397adafe80f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a18d50808170ba5008f077d429d08422fe6ccb1e8cf540e9cae73f3ff1fb5ef8ab4d5613b96ec6e58a5587ad987f631000000000000000000000000000000000bbe6b9af1097fabdb10db28c66caa07a2ddf7820717a9260127e59d037cab4b1c81fb2139d6f9d82ab01aab225021881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019903debb88d1ae0c40f21b682c6fba8534341eb6b8114d156d78d9dc5fed28fbf9729fc58f4457eb8ceccba821bede600000000000000000000000000000000061931ee10d3b88d9b119559c077d0c0e79de81c03b5a2b245ad88a01ac646d501b52621029217dacc707797a0fce6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c18937d2c42ed233e07e05ade84d018455a674487f1c23a3e07768c6212499644de3550e9f459d62218b63eb4f8d41000000000000000000000000000000000166075ad74f83cdd39bbd7a0d5107fc5461cb66d860ab508704f048afa5be811d4e7ca22db03ec9bb9ac5c55a3be5501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fbceaf260ca9331e0b7412690ab6c1604f71079c961d7129f1e45e54a39bfe89823af0b895ddfb688e3d9da98abe6a0000000000000000000000000000000009cd218fd239e867da696dfda26e1533671c3ad50abcaf08f4c34ab46ca0294cad596be097feb3eb1c6702ca28fecc361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e665c06de12799f5fb97d1bc365538ccaae66ece63012b32a061e6ed95a17210206c6526b3e3f512b90e843e62bb7f000000000000000000000000000000000e884e144a10e6f268b7f3c9cd8ea4641ff131333450cbe46e49ced7dada19222d47ac0c2f7bcd80ae2edd6ce819a20e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e471aee58161dcb711d96f7fb5403829cf8be682fee40da45dd47ba19a8c74e619947ab54af06a09efd518066af671000000000000000000000000000000000b5be4a912f590b4374f863a7bd33e329b89b7d66e8c3ade79de518e4ef1e3be9117d0be2180bb7806c8b9447a451f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271cb48885c01b03ba5e85b68e29adaa593f74724a6a70321280f6e7f5623480772277013e0cf9ca444043e2ecf8557000000000000000000000000000000000e84a63e0587eb66cc75e7a77e46ac859c92f9be7c12e3091706939d794d44a067a509d15d0f79db02888b2f38f5cf6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086cf874901f34aaa28d28cbee9916fc0476705424653f6d9825b8d7a4bfa03918924a04575a49e1a46bb77166f22bc6000000000000000000000000000000001073b7bcfd40bca0deb526c0268907cad2ec1ebc016da7f2917e9075c884b69ef5992eb5b2c8ca2e4edb8fed10210dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc27fb1d25cc01965454246f6f8d88a0be740af5afed68120f97b9e9a97fde1c14a7f0cea14ef051028997664ffaf2400000000000000000000000000000000102fa1cbb91e761d65ebe883bcf6d32ccbbc8b664bf4114e1854eb78d63ef8a37e6c701d706a103499f162fff536b6881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8b5292559034b1994c913e5326d351d67b0e4432d79f27d9a0bf069a1fd9e0163d0521f213662086f9395a33bea9600000000000000000000000000000000010d9397ce0e3ab166ad9f653e60c664b748a6f52081cd3cc9194e68383d2523d835ce3f05d76f3096fc5366f73d5a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1958ea2188985b2eb0903324eb47d6dac15a8040c50afa3a7b4bec40251ac24660dbbed2f977c22608ab8d904562ff000000000000000000000000000000001843ff23c0ae5b7c22574ceba00a591f68576320dc75623fa215ae556ecd12ffe3d534833d32e2bbc8c856bab169b9111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000115129df0ff8d1bf8c162f0fffb7288f2e02cdad80b4b0ad5ead44bda5e20d826976fe05646ac8c20caa39fcd042ff4000000000000000000000000000000000816eea927f38d8b4cc162d8773ff5f2a820ec8f18fdf19a2fecf3266943b7a3615010886f164e4cd540b042c8aded681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011782db8a64776ddda8b6e7416c33e1dded2e897dd6c1525ea9a1428b0c9389d94620bbd6ddc24c6c52276e7d36eaba00000000000000000000000000000000012bb2686279148d8f3790d120a28bfa40ae651a6ed5072d3b37fcbdd12c0a68f4a67a86ebaa9e5ffdd82f686e161b7201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001100b2b234d7acfcb1cd46ca6fce1e87aab6ff1762712f57ea7ef2eaf84a19c34271ddd8a8254992ad2f7e0b0ff378e0000000000000000000000000000000000eae719caa53bc8403b0bd11a84493c577cb568730092ffa26141a361b959bdf32ee4a883be76134c8991c0809f93dea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000506fb3f61d9bf27a676aece8786c860739ec5ab672a229b3c562956d7d9ada429c97b6de8a9a9973df0f54555b75a660000000000000000000000000000000004f4eb767fe5e862b6059674562fcc0b070fef344947326bb42c0869e9bc17578714b1ab3b1aa20475fe05a229fe4b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016152be87ad121f372f5d555c3dd767eba4f654c2bab5af3d9340c1b91c84cf40fbf29a0187a1a59b2bab0f26ee814d000000000000000000000000000000000055d3b29e6dadca2c04464e7b588943d82de86a4c46fe00f6094bcb98ca915a6b1e79e43535acf8931caa1f143fa05621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7e9cd95ce4f2283f8f52b7d870aaf9339e1a492059cba08b5a5b1ac94c7574ecaacb66cf80eec75363d25ef97cc82d0000000000000000000000000000000003af4b2ae5c6e4c9f9396e5442145d1522b6b4630474846af0ef6f2e363c294f078e7047507945c846484b61a116dbda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0e32aebd4d83afc1dc70ca4d829e5af78836f2bffb0bfda52339968c12ae013f0386bae83ec73510efb889be27f8a0000000000000000000000000000000000bcbdaa1d5f642290d1909eb931dba726ef948a5cb242b9f02c12a524ca0533736ec4c70a4c6c9b4f629fc9ce166b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009686a75cb811dbc7eb083931bc537d2e33a80f3a36ea7285ce57440bd6f29c09d6056bfea03ff211eb3ebc435d70bcf000000000000000000000000000000000e3bec298626395c71d7a99188f322dfa97937f305d98130a0bd90ba11e4b2cef372b2ce2e1fa435b5ad0077143dbc641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142a6227eb30cb51b2c7af06aa1e86489ea34a90d4e2a0e80164ad43e0d6b5202f9cde5db145f6098a6f24efca5c95940000000000000000000000000000000004751a45e2944494178ab16aff057e21ec0d1f1b7a5b3371fb257a8286274815e20c799230f98d10363274ed121887d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001784fcaa44fa1b42b72a08a49a30cdf8d1a97b7c626d455533b8d36bc1fdad4b429f914950b670f5d14f6f88e3e930d10000000000000000000000000000000011a78bd8602daf61e98dae8c775cdf0f42ca163cd72c8e0735e2642319c9f675b1f52f021358cae7b67d55e259648ad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017c0f232c8112e8994b7b6ae201125bdb09f5aecfd3ff6c907f44cfca671e668b5f4396300e40cd409019ba083330950000000000000000000000000000000011e8141a04a46fd8cb67f4bcb700d7fc10c8f3bae45310c9644cb7e2e26ef64f25cdcb7cd365e4a2b4ffb37754b0c7ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f629a2ec4713aa4bbe7e29df85bcb3a3dfb49f8de0de1cf90c1a5d32adc5f90ebc104aaa4498ebe20643a49e022765d000000000000000000000000000000001657edfdf0348982f2665d7066a2570341cd66712dc0fc3956b696494f83a02e36c0e3e927470978147897e586d829ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021248a820ef82a119012ba21884c70446e9d353310c7d66d884a31200cc7a0403487ce8f3af741adb29f3a76692b92700000000000000000000000000000000026d55b7c8cf35519b2663b83374318738bb0ed700619c54f2ebd99dfd24086f7e312fd14d572c6e43ceb83209052ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015275b54352ae1c0c3ca4fe7b97d083856b3afb389dd3a2e033f1745058689fa29ee7b8e319e00d0c4b185273efc64fb00000000000000000000000000000000030fcb60f49cf77f8d96d6338cf719b36f1a984167d220d19ff925356593fb49165800d5f828e94b7f6e2087610bfa2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165db6631845a685208571e4020758686c7fffcf9aa43999e057e6bbe3c8f05810abc51a4d6014de32b900a8f3a60903000000000000000000000000000000000f92243dda8d5d782da0687e096c2646e335dbfe51427b6ac21b82312741da6a306566dcc4232ab86985395769412a061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098cfd4f949f620b85353db03bce6b58237fdb5212015796f6bedcdf5a40afaeb7780dd5893c8734676f1c897be12282000000000000000000000000000000001864469fd7ce5b6ed60ec7dbb974d7eb015a685c46a6384b9281798ab64ee789555f45a7c47e3508f71b80748692c3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006000e76cbcc19aff95ea3e600e762fc4ae066fef6b37975e3ceea7cc6e03f281477587fdbd391a2f637ce4cfcf26b87000000000000000000000000000000000e6840e69580e51f3818021a00f22babd53aab98354253a6d9bce3808a64bb6ae24a715629d3729d4df294ac932514831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3a2453ce024159df7d66a181345a4fefaa8bdcd3e576fb413bb9b8c8632ef423db9d59debd23b79f42353f56ec9d200000000000000000000000000000000007ffe213072ddc642616ec85b9a0736bf019af82a6dd720406a617b67fa238db97e840f1685a5b6a36140fcd65c4c8f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b19d231f5bd56b8e5be9458b493d480e1334d2b9245f3c1116d574171df47cb65fa50d431cd71094fc9862f5213f8e10000000000000000000000000000000019432e129ba3e1b074b3714b2fc309b216b6a93ce4b2dfa778aeaf7950cead749ca88bb837b4821a85322877344be47b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cb388857366c94d3d345f830347000f01ff2f8d74f43061fcc1c41e43955ba99649cb6cee875b817a07ffa228c04900000000000000000000000000000000161706cb9096f32fb33626ac4e96f7ab0694ee12455c357026cc7d0e9f046db2be0b09b0c6034ce0a4e52d84f50803881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ee6331da12a117303519723bc2c8ec1b4ac4e2772b6db88048261dc8cbd5ae5df00f37b22d6acfe5823ac97a1b9484000000000000000000000000000000000500059e96827a21fe537627a364ad71d1982544a177bd1147c7d330bdbcea4a3a9257e1213ada323682a947638395a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cb49963924fe2807269a883ac92ccb211ef44bce952e25bdb47db464d21f3f57180fa51d9f59a20313a0e79b880f76000000000000000000000000000000000062dd86c04a5db6549fae3358f0050dbbd190f5674f6c716b20aecc638cf9bee65a62a7326503ee9caf8687298f6d371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b43b5aaa9a24acfbb031a957ea5f87ca5ba2569b2ae7ce0fa61b65edbb76c73e54e83742bf49650e7bc82ccf1dc022000000000000000000000000000000000743ef4cfe4a1a55dd8e2a68d31ffacc947247668dfa8b81b159d2a10e46a5698fce7049e3e47c61040ac0acb3b3bb801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013391769860a1f9f861e0540ca8140858108d136ed0e62830cc45cd9b366b9835afdd3b819a85e14442f3064933ffa9d00000000000000000000000000000000097e14246a5e19bf0fe65f2983565d6d2b2fd920d8df49c54b8b5d9cd49b3b220b08e3707cbc16e6a4dae06f104b1bd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174830cde36fc59364fa578eb81f5f53dd86b0c7904f1caefeb35ec10ad0472737d4596e0e8df6b13d3259caa12c349800000000000000000000000000000000031012ac20f5523948ff3167c160da3d4419059b82526ed15a1a7422a83a9a1732e2543ba27291ef110b3409a9ed43dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013225b6520f2584af1fa996602cf6d836ed83bb62cbb24035e07135d9dcc7355b5373080bbe180d74204af4d9190aef20000000000000000000000000000000003ed7a0f97ce73f7889e91087028836e8858af974928f4e7fe769efb2753102f459235480ed7968711e2ea56faddfba41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b2f2fca1306fcbddf02000bca8d1071f3e6b8e2253579208193c4cf64f593754481519ef62b23aa931c853c8df83830000000000000000000000000000000013d202c8409b43b76920af871165908acdb072c0ca049d0e337318beb1fd44e893b99a2722d1a19f65c975e2b88354241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f10b179f4bb062d9fed04219b89334a283b6e0af4f6266c3d562756e12638990b7069300dd84919df70fc082837ca0000000000000000000000000000000016e6c8e190e62a343e7988a0eeef2fa650f1ad5eb339cbbb5b0ed7e1737ec76a6eb6eea08d2638f0f594764aadd543b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a130655ae07d71841720206bb6cade8accf09a3f1814a5cc437fc863179573ceaea4c59bd2295eb824ac2a28cf178d0000000000000000000000000000000000965ae68d69b1df7862d74d435787e4db5be8e9df24ddef682ab39ba476e57f8650d7a4d0f6f64954ac6813a66e15671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014bd0de07a69a8bb7f91e18d060adfe96c9502cc346952371aaf17f2d6e827414eb5ce325847a5ac610f08c9dcc879640000000000000000000000000000000004f4d323a4036e52eb248b6c252f8e29d924cba934804682f32fd62b23ece955730c73c58b6cb1595cdb06edbdc8d7f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047f966f35ad7193a1543807336215a8af7bb86ca50ff2bc84ed48554e59e29d0fca76285b5dbbc0ce0d5fa91de03964000000000000000000000000000000000be02bb7cf8b45282803c36a3a2543e03948bdaf4bf571111ee914a4c9b50e95b5ab65e20c580747a56e626cb205ac5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098ff6150e8bef0fa9b86c3499f7b7a336a9f429fcd570f6482f74c5a696169a2d243c46d13a36cc544d0aba8687d91800000000000000000000000000000000114ca91b45c040b41a2eda56bdd39054fd8b134b377e0bf9ff069a5e690259110c25e990b24324c7ec65b74eb50337831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000490fde965a94bde43e44ac869e35cf6ec567eea401faa1148ee58c1b03124f1ff0ab3e00e2fe311cec9e9875d0e44f0000000000000000000000000000000000cab21121115383fe3311259f287908ddbe8500c6830d448a7fb1b67aea6472db9c0c72c1eba5e392e387636e066642e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007526063da1733294b4b5cc98db4390f1eaa1c2f20976ef88a68dc9359663b6242aac0ebf4e724c085c0e4e064675c7b000000000000000000000000000000000a92034f21cd22bf7f563fafb53075e8f31ef5f7f7901e258efab4ceec2a62b4c647a7574c916912503039f59914326e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119a6840a7a15b7165264554867b457baee77a1117ccbbf08fac034559ee9ef4b82945bbcfa9958e3c5e08548d6d27c900000000000000000000000000000000095a7fc4cf4ceda1d05719826d14f305fe987a41ebf0c2853488a356341246e5e90c8369c1fbb1deee8b9b10c16f394a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed2ae400a6f891e1de390200dc25f058268f1acef276b5ff78a2f728d97ae6d0e913c8afb6ac6d7b808dff9fab802440000000000000000000000000000000007b0f5cc391dc199c6a2b28deb28d9cc8e4f4642d32838d2721d31d78f98002251611a2b80b4dd695f73327b1f6910981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103d41b6ce4148e421dc67e0542853709a30f978f7ffa0002aaf53f8a6e629ffc2d617ffaa0b5faa84d5dc38d4c59a89000000000000000000000000000000000b325e470c0a7a4c05bd4a183123a982463c077b819694f1677f2f7383aea3e9a32650bd66031d95ff98d2b3baf4a89d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dee204f4115551ae044b63aaa363eb10069f9529ea64879dd81dfdedb035415d1259d5c3ff8faad04ec7145375fff90000000000000000000000000000000018b75efdc32e3fbf5b9148016dae52dc7a44172f7b4e4720760ab0899e063c2d7b03c47848174d00019f5eb105dbdd6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065033c17d112c44858b364f0afdec53d6382510a1ac1387f4b215f47a3cf0c6865eeadd6e582b28ba60ac774a06682e000000000000000000000000000000000732d855828c5a0f7bdea65449de163ab65dddefd750f426e9d5c38065257780d189cf538c04d84c54fd692f4b9bdf231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e1c9230088ddc65f76f039b92d90f68e347aac05546e076110698052dbc1296c457f70b1776a4b28e9e1a2d5d1e42500000000000000000000000000000000127e6f4ca08d3819bd21f9eeffe80399817fe063c3cc999aa02a23f7768faa4a21c6857bbd03062801a97c866d6ab65f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001440546b91e4af2395cd74bad04a3417e0037213a1e62c29a0834f791a424cad624775f3699dad3fe33c0b4ff09aa600000000000000000000000000000000001792c409a941e234cefefb1a702fdd93010c1276fd3a1f798bf09350a57c035ac2db822ef9e06f7e6fc2398761a6644a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173da028dbec940da1aa48dc1f29aede078c968462b596a4f291b53d7524c352886c029d731306fe9b3227d32a2e917d000000000000000000000000000000001113b9d754a449560dedd8666367757cb210a66bbfbb5c58838524166d4c38d2953bcb73b2926be8c3715dea2b3d6eaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185adfbfe50cb40278096c6aec43c99ceb0c1e9c620d5f6b0afc63b7ae898282361b206b4fa815415f402f2f75bb41d10000000000000000000000000000000005e342cda6f9d73f713458aedba664fb0ae2af31072198d7d741b8b2bc0635e503af64b029becb1416c7d65df3a02be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3db41bfa0b6c681017ba834ec4b34bf22b66ea3aa44053f8f97f1badea1495d4bda737571eee45c9a413d426a2cfe80000000000000000000000000000000003258ff7a8a93b44c1e8d9af233378008e3cc4549a4d9ae38ac342dc23e5144b9afa534a5df4aaae332c02fd1e0b9dbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017185436e9d3ff9dcb88afa9d7a3ba2777e65ab86fd3a92cec4b14e2c332cd80ab579324e41581bd16bc5fc5eec53a4f000000000000000000000000000000000923d216a2049abcf0b07bf901128085cecce233b4b4e879c835a228bff9f3386b33d907b9721c8706562967526295ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143d6c8bf2f9848bff41cdea96dddc8bd005c3b04e814641db49d59c4ac7cece0a33ba5ba515aea2cac2cd8b4f2a08d30000000000000000000000000000000016b65a32810e6cf19061d81eb4a08dd2d10b6e894654379080d53fecaba630a44a4d358554c5db488aa4db9d8866cdd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114ae424bb03f923d4668a249c7246ef5c040330e1812b1507f432dd25fd5e222b8050f5ad24701cfeac17ec66ab85da0000000000000000000000000000000010b1e9887372d31a4e952ad82e97badf5d3010bac27ab9dbaa32fe7af18a4484c4df99831ac21e19e21a0d918a8904361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f096edf252a29855f8c22850558c443617c621f020842fb4597b6c54920ccf1f9072c7ed003680d53d81c28f98aa2bd0000000000000000000000000000000016b0ced51f0f2145722b79d9f41927acf85f02f42e2c7aa63afd0f9078fd017240f8651974b3b396db7651c8cc0f88a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000881386d58225df214e5a90be1ae02366d1eaf6c7d5fe0f1b71f0e58aafbbe03312d04d6e4131a439aa2a973cd9be18a000000000000000000000000000000000fbdd88a8fbe822af7f74ec122e3cfd2d77a041995471d5c5e26298c0b4d788d13306ec6708a0d57d4667bcdf7fe86f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a67b0d4a9ef1d940ea4ac8655167c8b8a6434115c08f23a9f88194439c041761fea39c1ce7150199a5e1ecfd3a40d21000000000000000000000000000000001278e1b63d3013d4c394c7298dd57be96e24f85f6adb22b608fe5fa96e4a1ca1edf5568faa68f41b9d5208cfbaafbb061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f83a23025027e8612fd22178e3a1b4838016b01bb572134fd95283242bc7eb80ce1407631470499ef96092887968e6c000000000000000000000000000000001542ab9ecd7693f86374777166612fead509f07dbed57f544552802bdb6970e823b3190d3332d0df274b172ac0e4b2101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016106e598a6a0b0d1a321dccc8470352067520e1cb1cbced536b1aa609b4e76485d3b70c718710d2d97ffff48be151ff000000000000000000000000000000001858edafdba6a57dc3fc7fe49f5ae600f072e397c03cda9816aed5402ced67232e3cd6a4e413947c0f500500cc02b20c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103a5677b93c2127f73cbeb5029af545437070ec1feba08617b96b669146431a2678c46f834b838658a09212b82c78270000000000000000000000000000000014e66e960ba77b61d693a814ef0d5c6a49125c0367b029fe8ef511f1ad180c876d0a6c2e3ad8e4b74f73cb61d4ea667b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fbe1fc29df63db20c40459e3810bc4bcb8729e58b57fc508bda7ac9d42a6b37ab3df1a1af773bc7852692640f492c3000000000000000000000000000000000b436bb9103d770fc6b59898ded02e68df5bec60c38b5bd84f3f9ff17e48ecf4664194fa160086badb0694b565f4921f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c38ef67cffe9c4d7e8e00e70d4251f0b03310bef6c07a9d987c761aa5a21d667c339526513b098c0c9c8c37e123445c0000000000000000000000000000000006b9a6e3c5d7657cd8a2d8f8afbeef518e4cd2b5d7cfff23ae6d8800bde79eafe0565cf4f5d83b90d737b795044dc9721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b55fbb936cc1119404f2a85478dd14bc7c29dd42c888eb129e0b1b09163bb1e3b4008c88f672fb7fce7649fc8a90000000000000000000000000000000000004676c40fb8a58bcd17d14d8bdb456dd12f1b30d3684687880bc47e78895bd0588df26ffa09893d2ba7804886d8c12061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ade47485c8efd60d0c59aba153933c19eaf200837e5985df675018f36b07e6b7c5e30dd49ffee2e9dcd24e3583c0f90000000000000000000000000000000003a8a4ba04d86dccf4b2d5796b6715230c4583351f47ac9c3f786cf9c7d39cd64b2748a6eec0c5f61be325a4f88380971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dfae2b3a536057c98397d9c3f4ce9cf4838038bffc2833db8411a3f27e4cc27254c0a495dc32767d46b73af11b2fbc000000000000000000000000000000000c11b660ba1e1299a93de9cee700ccfe99267ab4071d7a8f601d52d647aeac576460be489177ef6bd0d2ec326f4717881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d9ec1c3735f50a81826e31ab326cfb4d696040be2a38285cba5973961e3f2363b5d213f9aae510f26a13fe9276ae230000000000000000000000000000000006c7383e97027ccaa22b562466c6e2fedb73c41dcc37fc48c113875ae5f4c7042069e60deccae98df29eae60ba9a587f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c4defd5c4019b48a75037914b27c6423fa4f9c68e8b0238872fba21c416d990db50e65f9686c0e4006589a23a89f7f00000000000000000000000000000000042d7a48904098ee36d9f3d64f357e729ba0d2bd34a2e6398c439a1a3969ad8a7a145139e1561e300345bc697a1134811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b115178d952b7511d70c6ea4ff5d73a9519755f6e705dc52f41dcf10936adfc6ec0aa73e0b2ed28e770608ba6afb80000000000000000000000000000000003666e5c1b7d5943714f3356d81dd18b8e957b8480a3187afceec9c86bac053e498f04878b7710f461d1379500e95d0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d90836b484048de60c572a0022868c8c0a8a4977bcd875e510acaf254814841295c7948dcc4119c628d33f96b10124f000000000000000000000000000000001305c1501c95fddc6f1266327f0969a30a93b650e1274fcbc93fbbfc3dd765914a44709f1e852f9f4fd46ac0da9fda611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000e7adc1971494937db5c7ed847f57a9a6467dcc42ce0cd305d9217bd65d10a97f5e487bca4354ec59785ab5663a1c500000000000000000000000000000000042d9cacaaceb5d12bb0bcc3df40ec26fd67f2b51145d3acb9222971e5523963d2bb3b82d0a4ba336da2e23531dee8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b1b89a5c9d4f73e4774a46de42358aafa7e27d065cb87f2eda27be6faaf90ae83d62d253e07117231a81fe32d0756a000000000000000000000000000000001075bb70c748fd66fbbe992ad6e8e3a92978cde329b17b6023df610dcb55a605d47bd1421d382c2131550250d710cfbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000abe54cc98f4c0a2ea99844f9344bfe6df769d40c8e94f5b9c47ed193b9f21f49fce1f3c74aae3ef145fb42a825dff90000000000000000000000000000000014149254dceeda26c438805a60843962e6df1ade0260a2d6e7cec572c96675f4545eab4a765642bf8c899dadd472aaf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003113607082a2b70cf4269fa32e53974c10a4551cb77e42e2e6db89d77c13786cc78394542f3e228b48d557c4dd9c866000000000000000000000000000000000da19cdeb13be6f28cf6b225f07deb091d9e4f3a9b2a804a97b67d82fd67f16bdbe08c3621fa7f2d7ece7b41b483ee621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019256b3ea2de00770225e96dc15d4467bc61517724ba8e5ec48192cd2980e60e0a825d33f4db271dde64dd19d8acd08800000000000000000000000000000000167416f3ef7ee2c5361ce321d97d16d5baeddd4050dea90af1407189c981822596632faa4761fe3690cfc6068f2598da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e360c7a3250430441c47059e538bab410d6a2ec04a54c8c66ef37489d5eb5d1109e994bc3d6577b91a5ec90061a09a50000000000000000000000000000000004102c4d61bdd023b9effedd6f5281522764d1f49ea65755d8f1ed07ab4e0d115b32d9e5e81c1fa2f78ddc7a5f23505a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017dc7ca2d57ddc9f8bb7cbe16e73ffd47dfae9a1bc949213c4bfdbb9474b8f22092d09241dbc91a5630e82a6754108b000000000000000000000000000000000ac7c8b045168d7cd0cd1eea9f8164287b45d2a4cb4ca458034b7595249d22ec83680aa3de53f0d1a466ead95b2da5a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100b46105eea02e91cb6bb5dccd39c05746365ddbfbb736c27987c74f8fd82a076d89ae36d68b7978ee8e8686357e7f80000000000000000000000000000000015017546ad389c8f070d5dde58868610459ee62de83157d7e5a190ddfe129e6cf306c399bbdbb4a6133920c5926773ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d5e9424d25ffe389196d946370c73f74c8d9fec218a33c93562f9d5aa77068056dcba4e0a39337576668c2cdd1ef99000000000000000000000000000000000e32964e0608c964b8a8df2b7ee33aadaccf5a48b37e06161ba69f819f9cb366f4eeb672c718206cdb02c2f547f47b8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3851ca8be318c8a6a865e3b8a28eae24e2d7e5e274de254db81475e63e24e5a759ebeaaa623737dc39766381abb092000000000000000000000000000000000a1bd236e16e9995fa4d599bd76ca9b9958755a5e8f80e20fd1c52053fc4396705d737be433e617c45a3286e8c49c8281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005eac64826c95be4002733e2c74d3d8626afbddc66e01849ffbe9db4a5e6afd167e2dc6c23af926d6845504677ea4aa70000000000000000000000000000000012ceff652cfd03616d29adf426ad190f85be220dac1c68833c522b6e9f9dc323c32ebb7e4616991a5a432d8490c6c51f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8ef24b2f4064978b73f96e3d2ca09e94091452d832591e2cee38564a8015822047550202c4d09912999c1c2189b25000000000000000000000000000000000ce90f8fc100d6b73f76c1ffed24ecfdfb7a778599032d2ec50e46d8d942dcad8b64ebe3adea226e6ce663558fda53b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188a3aeb6ccee304bc729930f41340b3273faf1f1cee9d4038f2b7e9b9a8aaf06708ba1e7b50b2f87108568d38dcfcff00000000000000000000000000000000165c69d3cc946fbc5c75ed752eee1d19998d2bf37fdab76aa8466f64594622fe7e3175403378c7411eb2d82b2528dfd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173082e0049c271a71ed0be0aab6eb73f0beef04232b3bb4a1e3097ec33ef74f63df992cb63509253698c20b469ca7db0000000000000000000000000000000014953ae5dff61ded4edfff0281b7093b991c62c9601f0aa64e1c1831c9a798e772d8aadddd8652802406261bb5bfba3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000299da1882f322cb02a59ba81abd852c3e6c1392355db52f9beee8d339a845cc82f1e5f2d48f7909412e523aa5bfc4520000000000000000000000000000000016b5c4377c83434a9c953cdd042404d0786a41bc582e7ecd88d8566e667f8afd6f03eeb437a65f1bd5bb550c230610721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f8b8d5f0e54a2d3b59307471bc79375a627aeb2a53233c1722c56dd32f08b73c50fcca05e2402a5a5ff11013f17168000000000000000000000000000000001194559288dbc2efa842599820b79ec60beb659d15f50d2f8f1958cf369d5c2627e47f631a7474564472e1becabc9d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b1f86ba54a90315811ebca01995657e54fa5b9832e5a69555199f4ffa356150664b7fc6694d9abc783ac78878e90f0000000000000000000000000000000000ed415e154044f9f186b0c2890ade67e486c401992189dce22cc011defc26bb1274ee9d3e910d5805410e0a0b394b96d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e13daa56faa40714799bf601004972470218cf1f3e22b5700276523953eaf818f98c51ca132db0f6ba2939ffab801400000000000000000000000000000000008f9da63bfe4940890af99963478ad067d85d5846a56a5f731ebb478a069d11617238b6441b5d072fb46755ec66e660a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110aa6fac509f5c020a2cd8dff7afb0fc584f0fe4fb38b32f62c530094653eccaf69b1b66b8cf65e16d5814a745ec5cc000000000000000000000000000000000237a358074639d00681cf993fb1c4d5facb7244c8f2cc7dd4f9cf1bf23582f91a8cdddf893b824b9ab11e51b8fbe4371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a44202404120d12ad00dcb8e3978637b48439700598074446098ee8f5e316ba00fc1bb417b7f68a03e35205d1d34f3b000000000000000000000000000000000dd4abdd77ef7629ac18d4d7a9b7345c8047795228d307d0bc270158d5ff8edaf680fd1c515d24f7741bda33a7c82aa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006941c95cec9cf89a83b4b6147536df52db8ca2e5510ec2ea369c35caf04a4b61c5eec0abeb13356744d43ad3f9fda330000000000000000000000000000000018955eccf195b1f64ea88de73e6130c495c36c0aea23b57f720936383c0b004337d01cb51f897977766f637be51d07691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225de0cb0825f7f99b0224da95e7d04144c24c7011300ddbc9831280170dc54a7af1c3f9a0dc2236d3d5d7ff53718b000000000000000000000000000000000030f95ec4fb1ed2c22e75c079f518d005e187e4e056b2b8ad5ecbf4202a71d6ab0c74017323d7ddb3a17f0f6e940469f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3f63df120c777024085443aeaaa51c5f8a462fa987a333d37fcefbe28a891753c6d13417dda3d4578b669b923c4fac000000000000000000000000000000000f11faf44779259ed20eb0be99584a9dbd6233d05d783cd9af6b6af1ab7121b3b51baa3de38af5228ae7765dc3b112411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74f8331190dc0b7cfeaf13973a69c5ca70a6f7aaf4632fdc4c5ff77705b52334918aede4eaf727cdd57f5081c50e5a0000000000000000000000000000000012082eaef78c5a5c8b8e56e02461898c0ec231b3bad5e34f8472a040ba8e4bfe7ee20aea16a274bfe66b0e7dcaadfbf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b79ada27bd10c66d5dfaf1827a4d87b3c054915be0252b452a03fcc4b9c9182f0e6e8f2cc2510033debde61d5eef47600000000000000000000000000000000073524e0f807bd65ba037268bf87e2e8df7efc1bd416bd62529d74e1cb997a03a03c30f6593c41a8452be8c716c4b9eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008361fa84654132f8ca7782c8d36ec8b42a578b7f23f6dba4d3732f0fa3ebcc062568ed2d23c07ee29d639106833e56f000000000000000000000000000000000dd7689109e813857e37d0759b164a81e78c181193954361f1b028dab011e3f13de92226ef520ba835eb38d7de36bdb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062e6d31218fe6c749ca47efb6688ecbcbe51bc54e49f88908cac1aaf95aac9dc3e917ecd560f6d283551cb4ec0adbea0000000000000000000000000000000005280bd041c289354d8b3751fbe7647bf63c35a2c4508aaed60cbfd5d6d5cd9b2b27bfb39f91d41f7efa539d1d1c56001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000163195c0d7aa2aec805ef88c7c0ed950c4ad12f68324dc4a75451454abed24887a5000f663ab1f06987ff267e0146ef000000000000000000000000000000001784335a91a1ca7f70d938d7c8c11f6221bcb7bb83f4545778ec9aaaf107653603bb842a079c81a953b562c67e203ad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c84d7150b7966612aa7d21af6d8cacb4232cbcbc0cc12deb08ebff3f0a91627273e7c0f6b7eb3b24bb5156d5f2ff4d7000000000000000000000000000000001099ee918e94b1e965ef755b861e330a568015c96301c65ba4fe41d37c6f9a66a42cb47de4672bed3fa44a5d20a473cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080aff5d354abc56c3c8b3613293bd98a52fff3b326bdc3f1854f9a5270a9ae43be4478b99a965f640bb7af196d9f6ec0000000000000000000000000000000014cb47b9bc39de4a11e7be6c2200df708eccc55efc29e74bbe56f665caa5a562076c35714f55437526a702f0cfc62d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097ace2dcd6ff27dfcbaff177965dc7d0dbfe354f20bab46096b03db1ade5a8ed1398005e6f8306292e6e649a24c5ec80000000000000000000000000000000010aff1d427d258e471ac08de64fc936805d147b5e2547b84187a6547f19cbc1f43a9ec4d3bb0e21e69597bd4081947181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f0999e7c5a9a1bafeeabf5f9e7de5e91f0f8e7e8b3619b2238c605528168ca452b9a7d231072833cc89e537ac865fc00000000000000000000000000000000046755f04f94f5b7461e588f9342b74be381ba50681c32a9deb36a286ba6ae107aa0db21326790697d9f3aad3fd75fcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d2a05456a67a946b87027b0b4157fb1a779c6e680f8417f84cd7e4bcf724c55a995dfc10220a7efb230054c5b94057000000000000000000000000000000000c895bad9887d9d2a5722f94623936337610329143bd33232b6b44140df1a813a1a60c83ab0d9f71f8f1fa20a7f61dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102bc7dba8f07471d065c19645db587225d25b0d5d0a1ec32a169379e60fc6485b0fe04f9b80ebd9b1184eea4812acef000000000000000000000000000000000874e146a80456fd85aa35c1dfef99100c5f74a42143df11b33a9dc3bd45b5ae49230de02b93a136cfb22b3fb557ebd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058bb9a1600a071b03943f58986d04fefbf06d62c84e034293ce7f3d8e715c55fab5ba70fe9106f6b9bd17ae1f1dba4d0000000000000000000000000000000003e6cf22495e05480b58bb6fe3b656059b06485e944fcf6cc8a651e05484b5adbbc987981e5230b14998e728bf95db731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017354b6f0838e4d55b00ca2ad40ef5bf718cb0f8b3468e5999e1bfc995b9e4fa2dbb10f453921e8e71590e078fedcbd50000000000000000000000000000000012df80f6932ee3ecd9a76df6bf27ac0d7cd238e8b81928bbb2d7ce2147372ae5f5f802b6c58180de92f778056881e2d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9e43234724058802ea856a70766f643b903575511c8487423d92958ecce1da686b7024660411307f0fb90e0712716100000000000000000000000000000000145d45e6146d1600b0c0882feb4eba051fe3c01bf7e4f1963a38c30158b473335aa7059220bc7c7c577ab8d482ca57131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160f1625b8f4bd477f3460f2534cb7eb9028f178fbc95d403040ee5065e72a7c587f768db2119cec13a65335112ce438000000000000000000000000000000000a1bc0cb8681b18439bf90439fb85a9be9638827749bf1b508544fc645ecfd18e83e7e37f39c7df0dc8a4707d43739071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d24c035aac02ae370dbb54de50c65df8d7bb90e6061ee5c3ab83389d6f81e6b5955df6b4d93f4a09d77c936f6474130000000000000000000000000000000019dc107b0b9dca38e813b3a2712d7c0d85ba4d7c289ff25b3d58e0aaeb68c572679d9f41ccda70b503724f1d6e081c631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014322181b436142575babc3693014e785d1c319d058081acd161a1ef6161cc20a31848845518ac5c9160f22dd75ee581000000000000000000000000000000000510c626d87768ee402169783adea593d3711f5ce32e10b611344be273de691eeebfa49f29e0c98d4267ff4a77cc45ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b9e17182810d5c070b77c5a3526f15de26065d950cc4591e01959bb3ae5d363bb8e9c53d7f6a521d0f1c2f2d395d6a00000000000000000000000000000000094673fe6239478f93c35704ff2861a92f257442a9f083283e5e6490d8c4a9375a50b7a444d39e55bf088ae638917efe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019df6cb6d3116126e991aaae3179a83cf53ba338dde3574de97aea48bcc7318dab17987a2b1d7cf1f1dd3580c78765700000000000000000000000000000000156e0344d9fec0f8180a795511ec113ef7476e027270324a439b84371ecda744b9c9bfc51261a5f1ff7248fb81d1b26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386cbc75b64113c132fcd8d807c8a12487dd192a31a71f31b903580aeff41e58272904ab3b69ddfe8e86571fcd601070000000000000000000000000000000002d064d223d9fe62ee6d137386e93526051a794a3ff91a003659360a24442d79cb29c066ceb8f20b7b9f7e8a5f93f26f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008075793ecac6c17624cb68562c0679ded37a9a143ff6abb1855865ee6c8e95c31ba427e21457b072104075ae2e74fa000000000000000000000000000000000050a0254bf96db3dddee69d9654ac7819be2b7f650b0f31f9afebf39dacbc66ba619706fad5904aea6fc983d61103cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018c8fd0b2793c7a79da208ef4b11504734a39f62d62261f2c43d13f5ceacfdfef26753602ec4436cc7e95989b7dbc1f0000000000000000000000000000000019f3ba5f4d2ac2afa2f2a0888e27e80fccaacb8200be4a3a8298f75fd0e9e21916a252467263b41339ec8277a50705e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e0f07bba9c9e0b92a2e256e91ba3198671d540b45a730dbf9495a6ef0e0aeb320bb847f1de3e24b7750068225fbcb00000000000000000000000000000000111f0e63b21233cc205b47afc460cb38be78999da4c93ba25cada6e7ec6725ab0d0347b487d527f39c23accc9f3cdb921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ef6da9fc5c9d2d64b8a79d6204a379628b08ae2508ff528a217e803a91b6a7e76a702d48a40f89b96ea4b99433a470000000000000000000000000000000008943286a27cd49b4423ddb4f33ac37573669a1f3019ac2786da0796c14b7f4fd3584c4a95bd0d34a4eb74369899836c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bc096c879840d4cd15d7e5802dba2be47ce9baeaaa8c0c62ee33f9128d906792c831ac2b5963a4cd4903ecedee897400000000000000000000000000000000010c52d58e74d117c0335275fcaefc52ab0b525315ef29d7d50847a0187b6b677b44689dcd486c7dcfbf32865e9179f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6162dcfaf71b35d02c5c8aea44774c2751902deda9e90f4d9be83965d78a11a32979cd8fc27097b03ce21e3b49f7600000000000000000000000000000000154d9a3392aee248682bf1aa6bb7e3d5e0a4c9bbe59620dc7869dcfb13beba012f5b6ca886d6c02010e031f14b68c3901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019da6bb122e6606f6227f1f9413136aa80a4f5a2e79f2ae02d570b9671d2be92af74a4b4d89eefdced9ea9d6ab4b06bf0000000000000000000000000000000013b681b1692c1b6f5e5d45c0652bdf986240e66be08b249f713ce1f59a73ace4032cb5d0318daedc3f19ba7f5f93a6961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120386e7fdd15633c18a108238cec88b3dbe9d1fd949d749407f4a5a9409a6b7be46c27cd8a09087e6e1fb02f0e8570f000000000000000000000000000000000435920c79d737f800f53801a72e6b95f96d71d743b2b77a8e24ac4ff3d378b6390bf6754449ac160ba18a428e2bec1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f212d0fd42ee5fe684fd7bcbdfb1ac8cfe7b1495f957cfbb8b006b825621a151a082da17a348bb2c7e1a8075cc3bc7000000000000000000000000000000000e19856b79cbd783bb4cb99372466547ef56e7cf597a231d27390906ae935d3ca71a0483cd1916b8107dc4fff5ccce741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d253612091eb02f7d5bbc6292ada98de8ab89f77d3d10dec71ef5d8e5575a613a493dbca65df777b2f7dc142edb089000000000000000000000000000000000e77e496cd62f43b54fc0ec7116c9dc7a898a081f5f0ac7abd7bc220099150bf4fd84fc7af3589f24b256e0eda71df9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdb14f6de4d16795aaf603d0c90f535644dc2c9391d48adc4d583005a03771e1bc9910f15047706b66cd52a0b9675a20000000000000000000000000000000004a54d32f92ace095430341bef42bdf4d870a784e72eb8093331c8c0653d11bc7fbf28369b5550e14d23acacc2d51ffa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000add75651af869dbad425521b6bd0ce921c2c67be58b75d075e507d46db810c0e8c870e6b15182495197c9c912e9dd280000000000000000000000000000000009da83bd5409c27c58b630a563af5a7babc3db0ecb3ceb6a697fb331d3a77b2bfedd275b7c34fbfd49974533ec6b7f3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000204307d5b8d62e593392795909de84139b0342af7bf62171e445820c4631e904a24a054d5144170b0d1f663efe14aa600000000000000000000000000000000048d5045d0962dd811a1f0c73a78f3b2b7f902c8fc6594b10d2bcb011a8cca0133dc25600f8b565cfb8f60f3849c239b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160b5534f3276c7d3f96e994166882162a79de9d59b11d3452e527b241638965172536432606628312921681f10af68400000000000000000000000000000000113733d67b4f4cb7e2e1e8f94a0eab139760606edca093fdd2c4d637e92bd927cf605b673d1e3130ccabec6f39bb1c4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002c1ade277d3187c4523a4da41fe7c63d7748f621baa8bcc80f7e08db39146c66f20e552d3f0998479bd244e470828b000000000000000000000000000000000c2d190380bd9592f6972e899040ad28b7dfb561a1503d4e0be04244906dbfeb2086831624d0bd073530b6eca5b60fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cbea001895711f57724c544e90ad87c1edc69832ed427e112cfa5b3ebe4bbd697b5f01ae12e7a95103c1c7097845a80000000000000000000000000000000011d18278cffd7bcf9e284313d5211d1690ae0441eff747b5cd635ad728078b46b85ede6850ff9965456e8be71c2853c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010dc20b32f6efffddce6de5c41e0cdcd133f72234a4d457ce7f1513df33354f6fc58f2f1911ee260495fa0b616b7e19300000000000000000000000000000000052ab431058cb7d63a07e73a4e9212b0d2b063a8b52eda6de956ec2c30996f37e7dd20723990c29ad3e0a42194f98bb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012999ec0db1401b70dbbdbdfad5d685639982b90e40f27486d52c706fc70847b34af58c1e3f150939c2ff8614c3441da000000000000000000000000000000000adb361227db201ddf96b44f804933772b94899efe07db774ec3312552d04824138a63a221e7a613756996a81c06158e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000269507552dac81ce5075863fe8d41c4b5df57b3f275ace4b42941eebeb713c56311ba35665b1e54202345ee4fb841f9000000000000000000000000000000001353a6f314ce8117841aa5951c38f2452e8548e5453a14d273526029ce9fe166a00ddd4cf72d5aea1e47b2dde52e0c171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf5ffe9e65ce545b1765ba7f35f4ea958ec5fd2e3adef61007055d8f1827a9d6624e9420334764e7414467e28a941f80000000000000000000000000000000002af69ee1f4b84b421331d6dc6020958131715ed9d1bca7a17ab78b050a48d7bc5e63f042557f0cf8da4e8ddcfafaa6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e36d883b6a378e1c61a6afed62702baaaaeacb0c4fe0fd66698f42ed1f3417f7dc047f8ae8258d41a7327eba08046c0000000000000000000000000000000018bfcd932606b55d48167be88f2d12ed86db995fabd30801adc68defb5a5d991afb574c0ad45e7792b68042d3318e3771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000939fc33a76be5a9d454cd698c16225981ee5190d8820430904a8c43654a9a2267464045ef738daca1c46f4d57386aa700000000000000000000000000000000050df6b421416380927eba5a7cb0bb753c43438d987219bd097c6e5ec9c48e76605d01fcf43e2f22c69fe5fca9f9e3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dda9faa76f41069537f849f579de11c2b61908a97c556ee397b5c5395060a51dffe745ffebefce80bdd99ded62b6173000000000000000000000000000000000b9b5ee1ea775ed43f3cc31721273047f23cdf0a3ef71628b04468c61a8047498db0f49d29ee01f81141c0a731a0b5a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d1f23b937346916736bb4b2868bd2f4ec600d95488d296461d3c07c80c14c2c5a254e0832dc9cca63ccc43531659d700000000000000000000000000000000112956e0c677e02ed2b9ad1b8a4c28aadc5fdb898c2d76ca54f58c01b694dea4f2cc158097210dda2f85105af940b73e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6efd94aa1debc9afff662fe38ebff4a5cf0ed0aa4a225483381ff75304bddd39399eaafc0f21867ba3066f4e08ca57000000000000000000000000000000000d9e31904c9f4f65e8739583d1edafbece6fbdb7703d8cec9065934d2ef63949abf229df0ade203ac5f3b0e2d750dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a8c51e8438c89deb9492db14d7ddcf88a9d1f92928e5c5e3c7e2399eadac428e8d99f8dbdeb85681d4038e2d49d43c00000000000000000000000000000000160e5321e9c3016f3b1a8502f395c17b183a6903bc852d2de59e0bd1cc82a822062140b57d9156eb10fa831777877d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000686968df25f3a1d6d13cb50559bff6dd42f6c78317a7d189a7e4283c4d48dd0efde47960133985dde75b32cbdab03f8000000000000000000000000000000001877ed3e0bc8f16d7dea421c1e7a9b484fe78c65d214b4d73a93f4e70344381c2689fc73fa465ae02f9636e11457e0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019535efa06d28a93b7b59826d0f4a7fa9dc92bec5c364567075b00698baf8dd4e8881a23f67d3b05ea2482d071d28fb400000000000000000000000000000000031ef5304bdce0b5df3356d57cd3ae796a270b856fd93e7570709f2205b95854ceeeda10ec060fff9de1e44122edcbb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7830a7f90ceda6f238f8cd7bf882a7cce91c3a0e9750199ef55c85b2484f29da37fd332ac39a0fa435de030bb8000000000000000000000000000000000000829ae2db131e5cecd01125ea7d6cb547ba9809c74fc68df8587921bc01f637abd7cf4d650395cea8a139576460cc66b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000744f517cb9596dc4d9573c3c61c10f7dc3e052d3be58833e9860fd291bd831ef50af29a2dff72d35d7adbfe029099dc000000000000000000000000000000000085670b8e81d6de6070cabfd9785a4e07accd5e171d49932d5a8c6fec59163e361d1801c5a4a27c77daa46801f666de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007f2751987193573936cc8eb78937d51ee031ed30098392d63e392af93f73895cc000bc883c9a57019a3555f8d81d03000000000000000000000000000000000636777afef84b2c03cd4130f70b7ccde36ee824a4a9aeb02787ed27f5ed657e9642a5959bffc418fb66448c44d298da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ea7312a8f2f5d8d652f861c25a4a31d396bf92e08d94ece7045a6598fda44667ce783f0531bd1f7147a290692cbb7c0000000000000000000000000000000017a6d8b4867a4d15ac437d775ab89cf768e921e50e703c9accea84c15aee8626eb051e8e0c41ee2d860639b5ae2f9fec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129d8dfbf6a338e80af2306de6625e062e0475afbbd9b4e4d74c583f0de1b375af92d6cb05da449749a60461c689f5ab000000000000000000000000000000001093e809e4dec4c0d63b18d5b8cecfe1d8bd1f5e5b35f8a3720e3fed97de44dcc8d71cd84440ca048c80c8baf8f1d61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a28c31cdc6f18d24c5127f3496582c884d6c2765ecd82b1e9bce844bfb7780d89d9d87a92d2d33d8e94d952109f21100000000000000000000000000000000109eaaa89b2dea5af12155c44e0e25aa01cf2b0625f71a0851b57c98dd78214e3d60e452a750a6fdeb8458c899b4a0c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cbaa1aa05f6365e5bd07c7c94b641c9213ecb1d5e00ed2ff0f1a93950af31721402896f8f9f77609abdfe058df385b000000000000000000000000000000000aa6dddb7c46a83c0d4655977afc40cb0ac91feb926c762259016aaeea405628a5187ac6d9d84e1574a6e3f0c89cab3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cc0d9e7faa9f2e362592b6790bd1194f29143cd62bc0d62ab316292b71a2774803a0b7ab0666923d862b7ff69d01f80000000000000000000000000000000012ba54036a1e35bcd32ddbaac27b3e5dee76293a1ce599c5e9e5bf87e4c0f802426ee2643745dbfeb6354d2affe429f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d0207509e7d0f2dd13213f731fc977be1340098413fbd2ab7c54f2ebb401185a07c4febbcb2ed5ccc4a480551aa0a300000000000000000000000000000000153eca6ae8f272c052a4612ae30d06d93d44ff2bc46d1d224574280b3237d2290816989cd4feef9e9b94f1a816fd13ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e0f8197ae9b1b4a31e721fe6ad0c2895a41b11bb285e1cb0539a403026c2efe80e4143493db00afd4a72133a86c1f0000000000000000000000000000000003267eb1f9a472763ac1efeaee92b689e47e58e76894f2afdabc33953b2873958ce1a259bca68a0f1880007b11b185f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002259000f06b3fbf09097b088f53e18068e3037b028517c60c22306d95bece12bab7b664b7fb68e71b7b93b6df4c1e0c0000000000000000000000000000000008aa7d7c47d3da648caa39df70f5c41f36e18e8954e32e859b3f6be2c9b49f0d5353be476aa275bcb481aa40ef1c1a8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001525d9745ba4095f7cfe08fb815ac1e89bda89207cedf8ec5853b56d0c795088a56ae454ba0422451cb0725611e482d200000000000000000000000000000000012d4d9738806dd4d26b73cbb6c77832bdd3ce690e93d035d439b01eb7dc459dc18da7804d809af45d6bb69bd7d653b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023d58997b5c8d35ff94e40a26976ac4fdf4c4bcd6cc48dfe519fcd65b50564d41f9df4b5b1cc8cb4a07e163b097ae5e0000000000000000000000000000000004f59956e4999c865c580b01c379e4d3c68c13b85880b8b9baacbd21eb5d13fb3019dcb24dbd6549ff4e96166452d83f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff36f9be04d939cd7ac2dc0d538db15733886ed3b8c0f4776e95f46e155f390ce1699eb7e25afd371fc636029f25cf70000000000000000000000000000000019bd5c1b48002efaac48cf24f184e71390196a6858d59184359e85937eb944e15ca9768dbaa7f77479c593ebe8e3536e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b27d9b13cabc9f9b515cce517559da96042ca0d0d92406737f1d95e5da465bc0a3818a865e715d11dd9da0bbf0a4fb00000000000000000000000000000000120c1d610eea3049d67e43f133c265d92471609b780b890005246f90a6640fb3827a72f16a04b89d3e005d825974a1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133d2915ebdfe7443d89c8ac69832742435299129a345075d2ebe77557f770bdd2cfe46f4cf83931225548c6bd60457e000000000000000000000000000000000bc53aa2883b13aa7eb9bd0cae4e3d70ccc7bdd221d069eeb1435cac2127278638a4a472627aed5ee48cc4ace75346fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000938665903d30fc0d93e270802b81423d39ab264610d3740c28f7c808ef138f26828f07fb48a502a9995598265ebb57900000000000000000000000000000000035744722a3deda8ec074a62801208e0ca265b8012cd231d8cf1b5710f7c5e481378ce5208b2519b91a091a08a8b5d041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d765593ff173c52b49db1fb3b1bebacaec51852f07d5af1b767d733a85b3a84fdc550df0b6a749da2e6e633b835ce900000000000000000000000000000000052ad9c73567fad6fe1f17041931bd0a0fa72c755b19cfc6b615df3f4ab7dfa2b6232b4c0840ed991a9c1dd76f4e6b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008fd1155efaba339a4b153683fe1390528e93e144d4cc611aa4df473ff0100a5873eb76b1a99bd3e55d591573ae4176000000000000000000000000000000000e44de38a58170061ac988bf3b5d15d6db629c537e15a5cefcacf4d65f3ef3378a911f142b5f679e91edf7ba4177aed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec37af4c86def87346fa8d0ac6741074c6c184a19142d72d5589d3eb1d3ec535af4014a3551402332957b1e065460720000000000000000000000000000000010684088134cb1eaecb6dcf154f1475cac9c2ca8394bd037341240eef263f58e64abcb6a17f303384480502bd788c2f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcc013431c096dc6fec985bfdc51b5907512c07ef592fa97e4b55d1c0c34e3ff62f60517f209e760bf0f1654fac3dcc0000000000000000000000000000000007a6705dfb802b8bbb83d7e5aee2fe32fc8809e664b7a89d08db694fcc2eddf75f6a6f0fbfa5b77686b8e66351b7e2bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174e672d9cbf5135727e4a1c8115ef41c379ee8fa5d8815fb57110a6e946fa43878fa0dcf1846291b438db8019f2cd8500000000000000000000000000000000122908e42064d08853fcc60517880b889f7e7a791810d39c8e4179ed3605977304c5d2baed33b60f18cc432d61f0aa8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029312d08b91687ad0da9bffbfcbacafe745976b6cccdb9b2cfb251a873664dd6e83e3c2540f208e5b885ec66d0a764900000000000000000000000000000000189e547017655de27d90b722a1bc728ebcdc889f775b064c8ed9497c4b7ccd780e335f8d0e9e1d30cab4acfd666e0d1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb64a1d534d425c41b35975facc39a1d6a775bc566a9748cb5a77c94e14d36caad9ac029f0db9a89ab1caeb469207450000000000000000000000000000000012b362f1e7e6ad18dcca8c49681c26afa32216cc46a8192e80e17cdf27288d1642f4b28fc3a34e5d03c3475dc20cebae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047c5075bacfd47298b572ca3a9698d7e2b1948e2754adf83d4d28eb2a5f01435b3d851afe9f89b2aab4fa48b726cd2f000000000000000000000000000000001584a01c0bece725a66adec84bd563e57063881e7154ff82bae17e8ac0de7e471213ad938ddd87a63b2b44199e857a111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccdbb9c4177b9952e168ca548a7e535337075218e0ae5ef1374a9dfce640e84b16d0db7a6b8928ebf0f1fbbe3b521610000000000000000000000000000000001ac558a19dc64be05afde347ba96b710ce93d6a44b2ca6d3e121c5827f6228638fd812e0e4ec601e23549273f121d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebea2ba8ee96161a7a47c21037c6168f70328e22a8a4a521693e70030469aab9505e1c5d2259805377ec7238285e8490000000000000000000000000000000003a2a91c89109cfe1312b79226c2aefb7b1b8663247b5817587ff22386981090f32c9389ebd160dab0e5e322c3bccd691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a22c4eb3a8fd6a78477f860906208ec9dd9d6ba9cc2b2a68a8245d61a52e81b41eecff0929731806724af16c807fb00000000000000000000000000000000010dc39274387d87221d3b36a1505147537ee4a4d6b0a37d8e725c26fa33549e2923d9825bb47c79d0aff631f6bdc0fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f1613809eb2d678822986e9d9a47e6716c218c0efbcdcf6e3249440622f8bfb0234111d2ce3fddd41bec43199bd77b000000000000000000000000000000000d948380dbffadad9bd76d19a04f385051343be2365cce283411a97a90bc5c3eacc9a301a7698b93854b84ead7cadc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171713cbd3ebe33a3ca2930cc7c88db56987c176b7d019c4df75d29e57d50d3e90562a5691e214d0a52928dca66edd4200000000000000000000000000000000028d093ac89bbcc49b212ce990a288d9502b3738ac46e7c1badb3f832783c91da63ee482db107dbb8ac4dff5bafefb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000093b6e9ea3d375a43108254f6de3f8bdfbf379823bc48afa64f3c91efaaab317328561ecd5765555f41a2980c298ab3000000000000000000000000000000000c3b126edb0cd037c6776ed67a459a2f65cb10e8164ae2cb58a272e81449d05f64111e49f1e45631aa2d1f5f390c94631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ee2c356a74a56210590d5a5fdfb8ada392128a15837646e3c1b5c2f554d213babde53573632fb42e61fc2efcff10a20000000000000000000000000000000019fbe6f59dcf0ad6982c6ddb523d0e2979c68292a50d71025e60e92b32cff4bb9634a03cf69dafe9a355abba41dc3b811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156a978aaf4ad0b7212eb042557ee7e837add87ef683014a736d17cb7989ae1d468fab7e7603907e3c2e43b485745b8900000000000000000000000000000000144b33dd4f07533789c0aecf3b31fd7a13a623e593387973fc2d13a7bc4dfd16607926cecf1b7060283dc40932e92f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044cd95f78646ece01df935114583df43ccad16ff65b23de01191f2e6d31562f429c1cf224a3b527152f46392649159c000000000000000000000000000000000b45325017cba543e05ce63d068a3ed9e3f14f1cbc69670526a5b3dbf5bdccd9f1b6a19dc76fbef46238fbf3ca8135d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab7580df53c160768ae3e40444031939e165a63c3e8b4006333ff0754ec737b0774e567cd614513f6b3d56ae93de77000000000000000000000000000000000464f1ef3df22ab0e0598a4cf38fea26456bb36ac9fc97ba6afc7a078735f4028f6f048f0df9d93cc6739dead32abe621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a950a9ff0fb2a6ec2b5428bbe0a70da80b2fd30acc192439f66ca1562770dc5ead051ab9878fdee2d30c9322df7d320000000000000000000000000000000013c6d457a46cb3747c7cdd272a64d44e698458d6b01af33f1659840c22d9b9d805f728b53cfbf882ce338248406188db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e29f11ecb1717706da7f0f8ed924105d1dd943f24016edc5ce7e5867ec1ebb237e7294692bb6cb2709b88b9c60d863b0000000000000000000000000000000016fc034eb0252e263566ddc1a692bdd4d8a97bc5f7f9281681f675a068e0fb6d77e8a92f9199d85094885175a4275f9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000682f53b1e78a700d38917d27039a3969304f043b4e163dcc74d0298e5f8293d217ce863bb69e6c183d9a293a0f58ba7000000000000000000000000000000000a88060199b86d0c1d5a638ca971c188139e4920d21c33adece5825c4acb336466472308788545dec1c5201133c2be5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018da96d262e9ba7b447e03f5a68c54ed757e513d312e436ea33d01d58cff2f1e0ea2f2f9c59209ab330a00a41170a5ad0000000000000000000000000000000006cf4d75383dae7bb7b83d2dbc91fd7a72eec82eba95fa1b0e425c33f82711b4e51db44ba5bc734c4e01960cdc4653431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000119f8821e4fe51fb759ea968d35d214dd63b89a50866ee1cdf5330040b7963332e1085f82f4dfa18302bda702a746c000000000000000000000000000000000152003d4a9a32171df2fd57785058fcc5487ea9965d151c287908db4e8163a71fb333eef4d91a2dc99953b9b1914ac731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aab889c581c59a5185ea72659a4ed8f03a83e7be5595e0e894185e2dd19889cb09b5a0c48246078e2c9a8f8729d05e50000000000000000000000000000000015ea01e37ac7803a89a879166e97dca9c6b96fd0288c1663a6bade53459462ad89121217613d9c54bf16a821e5eb0db11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f29fb94134c120c4fb61d7a90aa43e5e5194d3a41a92ef28e88d17397ffc99302c4dafee3f47a0f81f758016c44dc9800000000000000000000000000000000120715465f8d0f1b55c5d73779396af0ac85cf5fc7a0157549278367209f67b99418ed98ac58b168ef2a6c9f84cac1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000051192eba0e3ba46a89f434d5efc7b506d5d7b18fa74202c8ceb9a83166230477e8245db53d67bf861b69d7c099fbdd0000000000000000000000000000000018fa8bfd85f3878d0fd826194bc7b63bd8103641ff7fe2d7c2af158c69260367010fa651b364260c325c85085b12e1bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b327ee838cebc2607ed856e2762983b4503b1cc114dfd1840f85d8fc573596cd92b0f8031f33ba0f18bb4a6882afb40000000000000000000000000000000019975b3746b4970a4fe6ba2b65ffa7167ef8b462ef9e09276fcad52d6758296a2f2896f9d1bed1425416c79e7f27b2591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d040836b8f0fd1beef01dcb78c28f3679a6f1c7d49d20d939d78b5d2afc9f8810b22246d991dc7ab0fb5bb944e02f600000000000000000000000000000000004032024052aeca48fc75f68d4057dcab01868c2a9663a61e8c6863fef645bcca35530742b7c2b5e8c1d8b73801aa161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110f3036fd7f990044a5a994d7090d92b965bfded7c173aac71f1c6d9d784cb39b88d1cb7ac7757b9926d0e86cb58872000000000000000000000000000000000c2e10abc4e4e1a4cd78934c57c593830ae5accefc19bae86d380323a128ce3e0d8676831add497c5bb77bb26a57b80a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cd4f33dd10fefc7cf8e9c97216d8a46fed0a851006dbb38f049be4ffb15e2096d271c5e33ee770ad8d6c9bbd720dd50000000000000000000000000000000015bbac0aa5aaa83e03ebb656f55acb75a941ada612d2c2bf1b1785026c50c09056ec58a84dabfd23196ae45461ad88581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001643d59d2878df98ac3257f3056508553b80699e248841458751048ed3b4f7b50d520108a501d09029988f89d652f25e0000000000000000000000000000000009de02104c72eeb1274c7b1d3024398ce1aaea629044ef4587b4b744f1d536ab2c5618b5a4a6737e6524b3dcc04a3d721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c3ebed669daca862c519ecd9d7d52a1ba0928bc221ea45dbf86ef4609963ca484aa3f41bb7d6bda0c90874349b30320000000000000000000000000000000010b2b46356386ef179939b74a59eddbde29f88f3feb4784f0be394f0d5ec2c197f28023e59e54730f7e4501ba1ef18391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f4fc540c9e9bb5bd2524a731ea8ee835653093724438ae30af940fee5d0fa4ae0ebd215e79a386c63d26924076ca8c00000000000000000000000000000000019df2c0842edc384f40561fc33fa85d413f0836030b7770ee4a4a84fb25c95ce15299767cf2f0b847229d316ce1c1c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a829cb37dd28c5e941171a6e43ed3919a3f7cefe2a1e31b9bf6a84ac2fc089f95c80854b3235b3ba0cbc28fa358a58a0000000000000000000000000000000015dfa67dd80760affe476bc0a2995e36ac29feb084ce6b3410185af654d289518ef6fc55cf6ef42691fa7d20f71d419d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef2bb65a36641ff3965194a8f578ca9ed3036009f89147d63db2c4234cbd41d5dff1fcd9e65055f71dac16be566e0f50000000000000000000000000000000004dd9ca19d72c8de4cb87121a37145e001fda355ff5bbf9dabaede4cbe9002a4ba50dcd0f65ac8e4a59d5e0e34a0c2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c16eb8af28434e6a1548e4d256075405a48c3b8448b80b562fe1bc1c8dad1056f6171768a98a72f4268f7e25e2fb100000000000000000000000000000000035154e2631a09cf0dedeebaca68f15f51ae998434ee73d30f16250988ead13dfd4a51fd126e0d4f8675a4015e4d76391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7bf09da9e26d4258bfcbeb38463b15341960451dfc923ff5fbccfdc90cdc76e6781832bc65ec4203d840ffe9f4f204000000000000000000000000000000000cb1c0fe98c51fe9db06c4d9020823008531c9e3b7d95aea44811f89f10045909b5789bd637b60d2e79e2de79e38fb051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008619f14453a135a44e372edb80cf7d9b8d3796f2e3661a3a8dc58bc8d6915c7099a36e6d52f25c215095fd2b8e90c8b00000000000000000000000000000000008c6c5e395249331a020fd14626b409b44005c6c9b6cde5543814444a58060b359decbd3365f7064a6da7dbb585fcdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7801d28b48167a85d962cbc879781b51594e1cb2b741cc2bb188ec47ac876b692433e5c52d961b8b94026ec5deef5000000000000000000000000000000000dfbfdfaefef632841a8e679bcf1a6f98c6800a52a8406d73dd947be51cd8d100926bf1b49fd843c53699686939fa7ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbee8a9ac6f7d80dd314618abddd5d6f3dcc6a6db7295d4cbd07c54320d9ce4fd71326049c14bde60cb4525fbf0e248000000000000000000000000000000000d72127908d2368563461595c87a3b65c71b9d078578b4f7ac3f6fe26146389c2a7d244e35e97cae339dc288cca556621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047be5633b0d5e3a7ae598997420a2d3df0c8a7b52f88563159f90edd044d99d587990e5238224ff0e3e0fa1d8e10d26000000000000000000000000000000000f0477e0c8ee6e0fd9f11952b495561ab6b6e2e4da357e2cad5b9bde7b1c01ecd18623fcebfcbd0b4f8ad910f2e2c2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b8ef64c209d24595d98d3668ba6374a565bb367ba077ab77cae3462a02e0bdbe57d572fb796817a6bfed4397ec9d92000000000000000000000000000000000773d08245f1f970bc0157cecbeedda7bd01b35e2b4a7a7eecba84e81ca630793a7e2905e5c2385ac04408732ac24e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeef118721adf15dfc8b4aa3d7f24d25e8e93d09448650019804dd4b3cf542403498f14c0b6d26351d6923f25849b3000000000000000000000000000000000156b3bc736e37b9f403b6e58c5915fd7519a471c7b7b5aa5ce7892a5094aaa827b4822b7b7a282e7771094dda8c139691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000566f225acc9678de46c1bdaa2fe77a18b7eb27e5b4203af35564d1b7974f8112ebad23aca88463950294b6651a40eb30000000000000000000000000000000011cdd1f402bce43ce1cb158bc152a68aad4b5aa4b7c7d3c9f2d0ebde56ff3534d20c9e3244bedc10dd074b1efdd975b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005105380b26cb9bdd08ce17995308d16621c12376ded3569d67c01b48f794aeda3d7d0351407507c184c9a0a68f158b90000000000000000000000000000000012caf0e94634aae6ae9c03baea1ac46753987934a03a157d7ebc454b4b9fe40c134d79bf2b71c3b5c2e2c0446827b7531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d7ea85ef270140d5f9cf89927d756345d2149815e4811318b14b542ff5e0b568ab9f1276f4ab26b4ee1fc7f1a9ccb0000000000000000000000000000000000c84992d8ac6e583201739647b254cb839db3751e3d733abc709ec21ac05eabf15f0583bc81eb3ee7a5f9dd31f3bbaa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016001a27e7dc197ee240a9093d541170e865f430e0b69b4284299d97ed9f178dc55761209a46b3c012c429b26e9de330000000000000000000000000000000000650c7d4afdd19a5d8a9272ce638c0f6141f3badad71dfd262d6e6f487f3ed5ffba6d083f63dc00fd13972467d85d8ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a103c5dc82a17cac194fce92956c9d005ccf87cbd7ede79d56b1113835ef755666ca0d6f5746ab4fe99b44251da0d900000000000000000000000000000000192604f95d96f38bd5d6827285bd0d164e71b72ed8333f7150b189779920048e04ac9cffe60908fe69de0b6fbb22529c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124dcf9df82674ea54ff745ba6e8024480c103beeaf2cc8f4c5e40bfc31e409d2d92794f3916381cd1e8706c985698a500000000000000000000000000000000052b9b88007f58ff9ae8a2618436c206a478616cf869386b72b0fcec7a09332ca84836907d3706c9740fb473455745151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117b2a3c22e9ec184e9c8998d0cceeb9174b0e2244711e64c794607843941d05068f0b2aad7f2e8d8c0d6e1447a193d50000000000000000000000000000000012554fcea4b00c2ac818a63303288c87e913bf6f8eec8797a1002a53be28838f999931a04bff641efc33426141b77b231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6e99c06a8562d0c80e9289dd12a1bde931c8d3ddb0e4635efa55a81b214d619504a79fac358fc18c8344ffbda16f36000000000000000000000000000000001255c33a9c33fbf95328ecf9193a33c5d4d63df4962288e939387bafbd51040cdf37b9881894a9523fe1112962955e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa29063860e7d4943050773c233049f309d2ae30ba180e29d348ed6522e5db5b08d6abbfd119f961f837aca7121f3cb000000000000000000000000000000001897cecd6bd872cda410471eeee7365a384340e5aefef39fb581e2d45fb37b0b85b66d31e628b2627a4d7453083254241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000996184b3737624d216f3650b84aa482f943b932722cf719bc8aca5166bef6622926afdaf17119b430e309d5e8b0133000000000000000000000000000000000e638d624c7c0f61af5446c9c7343ce399535c1289ce2c4f91dc5551420997b2d2cf2715a61e2cbf8c2e83dc19f6c51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a11a0faa8eed18b2146328df63c0ec633470130211218ca88983819c361eb70cb80fd4dbefe2c6c1c9d040fd595dc20000000000000000000000000000000018cdd5506ae40955b4b444303bfb09b68022c1a215b8e065fe808e576cbbf7b096f296d7d153d0a4d5cc4812cfe4f2f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e96ebd31885b466bdbb5d828a47a636578509fc52732d4475aa85d85f74cad516eb16f9d581ea8daa0b96ea5494af300000000000000000000000000000000173d251234dd9e55602a505eeb279359b8da8a78976feb8f6dd25130c149f9963535a14fd72f3bbf3d246aa702d9f04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e5cd30072b0fbfa00d5598c7450491b030dbb2ff13eec22c13f97c8b9a53aa692918d3f29fb914b6b474bd0b4562520000000000000000000000000000000005858b922bcd4db8c2b4e68588226742cc1af43a7b4a0d428c8479091ba525eff740b8c62f5fa0981f974b834db7f2a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fa247ddc79645de2835867cfc818809f6a84ddfe0630357371b42e32b9d6a192792b8eae9a580939099631ff09db530000000000000000000000000000000002cc765e0f1bee545c3c55476fd04b5683c81da9fee5d4a8d48bd124e2e67b8081437e22768fb785615521c984483bd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e0569715d5c9d07289d0bee3d0eeb463994d2cb3885ff2c810856f3d8910c88a7415b13ae59c52abf0cdf7f5614c01000000000000000000000000000000000e58335d30de74a1ec71138eeed8f2e65df3d8e2fd228562670e253e5db6297ce5143ff697702e3382551846654c88c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137db28c2d40d3ba5f4ccd8612509736b77b5f229612d3114b7917081d7ef5a0ca03ee160d25e4823ea87240ead566ad0000000000000000000000000000000006a42925bd25877e15fa7dd843ad4babb0705b0b5d37d19c481d87215ea8f866dd424d3a07b11f6d7b7831db4855174b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8f1d8d64d431be80826670d4f87d04bcde52d9077e36284a2e56dacb2bedaeedd98d32ca26cb9c16e364dbe3b5dc2000000000000000000000000000000001953e86f5df185fd780f46488cc06611c2738c8785acb86c8b4a53efb8fb6f8717dee8dae5f00601b3379eea7e98ef061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001074d846a6806752fde4347ea400039f77b5a242bcc9276366d8628405204c70aeb59bd03c0721338e4b87ee9edff1590000000000000000000000000000000011570d4ff979cd5baf1a8b0becf89aeebc77d39a3026beed2f8b3ee07c94fd24d391d8dda9f65c006359ab67bc5d8c2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cc49cc2cb37d7188058b84a4135fefb3e09b2f461a661dc2cd9f7f1a30ab7eba3620f7b77fcb8380da9dcb9727050e0000000000000000000000000000000000b8f7ea7e2f8c6cff5fa9a4c912cd2a913fe474d9ce2125b6cdb05b00a8305b67fafab4cc4eb3f27574bb38e6032bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2fa197e604ae7fd31fdd8069cd8369bd03b01e4114dd1bb8d491fd556d6a2f54559a495c54239b75f9f4403437ec9f0000000000000000000000000000000008dbb6f24ff848d19b857f0649357b9cd44986708de87a2a7eccc901a5a181ede8ed4de8e3c69ee876ebafe13bb2eb851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006944e73970d0f02a06d39beac6a14961ed5e0969f3c690b855fc98ff709c09def58675ed0f3ff5756477d7bb8e5123c000000000000000000000000000000000dd082e85a1962e7d5960d26199fac8abc74e85f0eb164f5054cd58cbabb35ccfb821b22cee21575614ca14523c6d77c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161ade03834ec2464e75137b0467385814f90cedd335e69e30b7cb39be84d3fa2663a323355bf7acd88646fbeb883c4c0000000000000000000000000000000011599339a8bf243d320a848ac00386f5d8d4bdb60cc3f7b6598116728e2f2d94ab73c15c45e9cd5f5d8a6b9e31fd3e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a3b317ccac0354071a3974ce28feccea6f6f71feb14fa764ae80bde043c86bbafa5d4d47ad9f73ff13e93c5948ad0600000000000000000000000000000000173b0b63fee7eedfcf1193a3ec870bae1417239487a4fbc83c7ba36773ca61d6cb92aa86958d25fe1c34fb361c05056a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e362f0bde50f89e79c5d74641d3afd24ac658292280b97d3e50e2d35534364998fd9ce9185b8cf92edcd9c74aeba884000000000000000000000000000000000d27df92d858ad19b40e1785feeb5d1dca13248773c7bddf40360ec874977265236e594194bb480841e0fb2b9b440c371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eac9b0f3d86a5f30ad7ff365e33f45313ebc1b5b5ff985e575dd6f3d0cf80924af5d1640d25469f8fb1d9ed7b10fc0000000000000000000000000000000000aa3385e750554244a10768a4bca814a93d51d62b2fc92ed0499da9ff864a7644d67987f73585e926da4083a6866b6dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d7e97aa9f5c08e6b3a0ec7c2aa4fca12edc36f192b6cb409bcefc2ef0577a1ba06f9723470015f70e49e922d02cf3700000000000000000000000000000000096563dbf1b11f34b69793a60b46cf20d256e9b0bd3d16160c983010f9eb8d6c8b600ecca4530bfbeabb0e4bf5666b661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000624ec7a4ce6d89e70d23557a1e91da51eaa465e11d872938013ae1f15284610a3c74b4d3ff2d4a258fd67b523070930000000000000000000000000000000006a1e8e1cd6fd18e6f580a56faac6115659e0d3385cd3343369a69b945bd76e7b438535c89ac4d6ffac14a1f9165e0901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947085c97fc9ef9de91a970f88f0689fb251f205d258a8621b64b2b44baa5f53772b526aacea7a9a74b186cb0f6bbfd00000000000000000000000000000000029ce2f8622a935b9cfae1b19a54a998bf12128a0af2f0c2d304ad497a2d657fe8eac77815882cbc7f3e223895b6ba921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3990cc9d0851ac93e3d8f9b51a2bb6efb84eb5f5a9800bb9a49cfb71b01d17683795d92b3abe2123473b89d44e5530000000000000000000000000000000013841db289accd77400a61a6d771b54be3ba5f7c23f8618c3bb6adfac4ee0b5d4af8a9b197b2a02abf5aed031c6e47a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fa80e938f64a5bd0d559ebacf2c0ca1479da9cdd05d3de135471fc03928dfa6cb50cabf89b0699d654d6520af9f619000000000000000000000000000000000c7403b38a37c84682383d86a74477b9951998cfb33cd2e8a9cc69977402ddcda3dddc39742c121f4dc9b5d75a6f817f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2e89d7cb46f202091726904980bb8bf266e70b753b479df561edbea6d3f4ed4cb1477a660f029b6059f82b4a0bb96c00000000000000000000000000000000118772fe9b5ca7796e2855d07c2558eed456dfe1e63821d853d1d2bb830bd7aab7bdffe8b760d434c54b257e38946fcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058deee35fb35298aa2400bca59c257aa8d87ad30559608b5da87eb2ced83ab157849390198a67dc73d61ca072538c9c0000000000000000000000000000000000235a134bccae84fca2465645293c2d0beb755aae310dbe62d417f360ef3d343ef6cbfae588b24787b98f4a202610bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4c23578797773ba21ab789f5f297e08c8471577f61d5364569f04864d09ec73ab8d2221fdba3888e7295dc3a7548700000000000000000000000000000000007fc18d17fd41d04bbb76081c64047a47c52781eabe1775b6336e3916967d38db194bdb52e70378bb80cf4d4efe327391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c933acc1890b4b0097df4ad57bffe8cf753ab98ce76f4497975e56d27032b2cf692600da65f1d3d128cf689aa6ba85000000000000000000000000000000000244c3de4789cf0ea6996911e9e0db614258372fe5fa06b732542fad81182bd6a03dfb956c44ad68b0eb2ffaa1ee203a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001399489803750d0170611d6c26f8e27039b5ea9a982738f7c7830ec47bdb9ac33ea516cca37f1837c7c577acea055d6e0000000000000000000000000000000007a30645d8912d66825a7b7f20480fb9124e6c215bf486d43802757e7e317066e5a8eab7cd8f4f9184115b152274e21b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e85451fc6b30ecf1375ce4fc2a1eea6033327057ef2880e2d44465cc3e2942fb8888ee93cc244fe33bd9d2ce392c98000000000000000000000000000000001005c4059a2a81768622c90f8842ce77802f3d71519cb3c89090f26f8b4c57c3fb4a6f3c114b0fce587760e337bca16a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164042ef1d66f14484fd833d1e794a54eb119e3931d21a4299b707021dae0822787d4767c46824f12da2a210c170e1dd0000000000000000000000000000000012ac6a08f0e36ffe00cc3d5075bde17eca2438f152ee52259ef45ff867179e839a3f7d7d8aced02e71ad59661c29e56f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d4b8499102bb2eeebc1117ef48484a0a17737b0f2b87d171f1ee03b5e7b0c10b92c54f96d99e5e4eef07984c475fe20000000000000000000000000000000019dd0aceb42bf192bcc849cd65ebc13d61d2b4c2746925adf31ebc18f158657f42bc36ee847193b864fb3b4b035552881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112603f370343059004a926005c0cf8a6f641d06dcb0a6a7618b66bbe163cd51eec2e58ce3d878233cfd252d6e3434a100000000000000000000000000000000060b12dac962a0fee142f2117aa050048c676229d524903455b838359610e2870f337dd387a42621d47129528c95c9941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e182c7452b78085584c253265c65557dc2e10739322e1297a3166437d46532db03e6dca9394530a728ec9ec6a6ff6d00000000000000000000000000000000113dc255b64b1907b16f730f81f236f3534d0bf3b678555c94e445600347d13e2e47caaa5d67c854b554c0bca72441381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd34dfc885f5b23b9b28c7f23e6b47f541a2820e627ea86066042878a28623ad745efa76851bdea23b93b34fff075c100000000000000000000000000000000013bcdd250fe6360be808777991d0cc7fa146cec8ee9083d9e0484ffa77c9bf51a00503a5e3816b7d006d1d37bff99591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d2daf32581b961b1f0e4b9b688ecdc7c5a267cf368ca21f1ad1c09a09243da369b792d2baeea0b4f83a973b491cd30000000000000000000000000000000000555ad8682fd20545d74365968fee0f908aeefa614c94c7a5ab534d9ff155fb429dc01dba16b480e38922986f92a6c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063a8479ef8e3784fa6944409a64cd944c795ef311fbded7a88e62e832ed9732a20cc2fb53d96d3c312ab4a19e99e964000000000000000000000000000000000089f2fdf008f122c5206773d45d1c8532cd73dff3683e639d2481a0702f8d182debd48002707c42496a7f8b370be71d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000053c5c5d2517736a4b1cb1e57ea1de8d5f7cefd900335e6d67b25688962eaf834dfc3f8704c861a851cfb7ccf06620f00000000000000000000000000000000090d69c777da22d03b6e37aae0e44a7c22343f14c30bfbe68af60ef4de1ea3fac8b364c22702eb374ca2d46cfe2931851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5fc05480708ffd20419ea85953e9e52c50450f93d35fd966fd3c04593dcf1ea87b0b3ad80cbc57104a3547c202077900000000000000000000000000000000168ae5840afbb7d2438186f6a8228a24893993d14fc5bf21aa0aad39861fe63341bcc130ff65b5c6ae6e4b5f3580da361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172ae3ec48df7b20e1f4a17259a36cf81337934ff722f12ce97f08f342f8dea2606ecab6999a29e2514f8d71ac498fd70000000000000000000000000000000014a95019bab52c0c13f66037f12d1331d3bfc479e18b3a4a239a2c28ebfea145851609ad97d299ddf46f8b992e6f61131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce66b2a982b3d8a93df162e5ad29e40bc39cbe3743ce98ff1fd3603c2bcc732bbe7aae6f0a7e9e5c26fd7aac991e7c90000000000000000000000000000000010b1d69af3f7b892478f144ce62b3536d1994bcf0e09a0c9663bac6bfa0e8542f48c511c6828c12ba989ebb184f192d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3db8918d212f4d3e5468aea53252b468684450a30766ab7ff735a770fb490c3f333273fb0f4e6c0aba8bcc131c8f10000000000000000000000000000000006977b3561c80fcd787f26a6ea575737bf9614ceda908d60092a1811b9803034c17235482330e1d5415c6550c851c8221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ae1f20b0656c0a18a7e6fb67a68e1cc44b8334c127194aa7f4092ceb846f7bc50141ea670673bf0a4a7ddbca8314640000000000000000000000000000000004a18676c13abea760d6830ece56102038927238604839831214c03ba222b59bf19cb9144cc97cf297a5b461208151331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000186c69b362aa531166d1101fb6a5fd36ecff0c3cd22559589ccd0e8bbb8800ef2f302c430e5a219a2c8ad10a7ed02e6000000000000000000000000000000000a29eab1ec0c7a5eba5166c4a7b5962e44d0fd5a284e5026db55ef01f79a60a01a047e87aebedc654299961580160e671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001430cb8efd9117b996ae87069563ccf9d61cc161ac3256b8b4701f8fa4628dc1b950cb69dd54ed10938aa652d4eefee0000000000000000000000000000000017ea67dfd12a132b44a7b18764e13e84682995ac1b4cf6f43e60d65082d54e5382de6fdf0dee69c25c0d099c649cbea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075eaa8bb63037b20beafc56a5ed2081bc88e618ee72f5923783a8142c148d00427e4bc8dd3f7b747ddff95820404d7000000000000000000000000000000000180117deda01538e264729036514d667994625e3ef1802ca8da33f77b13065e8b97f3ed0b30c7e6a73007c034254ed8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fdcbd8a2fa2ba32751b5c68b0724d800a6d24e8e3142633b8036ecb2eaffc24972553aa45c0d6ec1db00b9297bb033000000000000000000000000000000000751e83f17773bfd780c8021189731674507b6028b6624bb316a4eb792d833a72738aba1503aa9254fe11fb5efcaacba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da5a4c6a3fd9b60597d7a657cc0413507f5a42ab0244863c34b2a7caeed0396953e260ec232b7d872988408a76331a0000000000000000000000000000000001de5dc51c1bafbfa59c689a41a1f0ce70cd163e7143a80e14819148934865b2f11ef31af6d02acf487564bad524e66f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000321642be8e91c22b0432488eec4a77a953ad0b41e05cfd465ac6fe4e0a0d8e0d64495a1a42a4aa2af66dffcef063e6f00000000000000000000000000000000112c7e7c8c0021f534ad0138157b61f3f8ac75bcfca4998df0d5b4f9bd0e2a2710c1116ee5dc97a31ab7b3818bdc5e261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136cc14793e42bd8987a9d667e8527c69c910101f70b6aacb0a22790ee5fcac29cb8e3029bdafaf5c5a40183f195d7320000000000000000000000000000000014ab149d778ad6cea6f0ade2f8c2ac85f676fc3b746cce6994b0eb08eada6221fefc558485b1df77a23b36f4abb63b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a51db5eb3c7d3681413b98d4419b0c8862df5c0f253266d992b6f4050ca156b68456c4fe73b7045b7e810596ecc40bf0000000000000000000000000000000002702a490e5c3f6c6924cc12eaf87a24ba21c188cc5004131fea499ab97664b4c7bf8ac781627a400a0324394cd593841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f907ae37553832c8aec680d7a00388f9b1941d62c6fa1ba15fd302a50a2d9ef2147fa8246c071567d815112a19e5d000000000000000000000000000000001520fa86c4fd80a11ac852ee67c328f3e0c48e2ce6de28dca4081df615ab24b04aba4d4fceb47d9b1f606d916bc311331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175e26562abf9e622eda51e7eb8e9e821a0af605c68a6c7b576430f5b46d501b37e3af9cd0f633b99b16b1137d6af1bf000000000000000000000000000000000316a049757a032932eb9b55b3a5a3290d30e648f20289c6946623b6ebdf91265e36009da78cb402d87d205fb228c11b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc68ff1e69cda887a9a2d90fdbfb015374b8929bbbc20cd05912b3c764e9084ad94134cce695c206c1181c4766cff3900000000000000000000000000000000022baf28fd8f791b162cf4ee60804d080e7d0ff2633075b29ecca2ecb099ae96e2fe92b667dcef841c747706d287b3f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bd8bdc2cb56b7ade7177a1d23cffceffcbca4c3618436c7c9122db3c3d94175ccbcb358fcac3c640b130a53d4301fa000000000000000000000000000000000e340b7fd3d8abb3e903323056c31e4528fcb82f8bd391ee36efeb09f200922cc95da28703da061b2c61ef3f224d6a5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000484cde22c7cb5c61ae2a4988028f8a941a5fbd98ddd40be8e6645857d04b8199b61ba5afd5e92331bfa43269ae9ee4400000000000000000000000000000000159d88a3abe08620da1565144c9fee9d9fe3683e84d52f3bbd7131139cfb23ed5f9d15a9be939c6992026a067da972d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000256fd2c238779203ec9245d5d5394399ac45e7ee66d24e28a883eaec80db22cb3d40e60c4acbb7d4d9c0723c820c7c90000000000000000000000000000000016219f918e5a8029bf3b324ce34147c9fbdcc999aa67c6425d8232361dae0551c4e52f121731f0c4ac9a3e5de379c3571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e175fb7ce1c45e861ffbb4d6d035ecaefacefd4d1738e4d3abebd22d0cefad4ef2a9d8d1f80e85795ef2b9e5e2bb1d00000000000000000000000000000000137fcd96dc0653c3e286456af1972ee3f59ad1d8455b292fafbe90876189a5020bdfdd1505c8b8a1cc5bd6af908498f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114797bfc48f63ca372403704915b1ab04a01525e39668ad7f96d156947b7c1ddf2e0f912e1086b3644638e5d404ad2800000000000000000000000000000000181fe2b2419d0a2ef70f4c5171b2264c511a708802853a8a8c8cb63e06974db14f195caed54abda2be8e7cc95ba554d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001173c6dff5658f8d2b75e7cc25968b02f8980831035565372cdd07aefe800263db99265b2fea0199a7e0ee86da20287f0000000000000000000000000000000000d9b8b52f1f0f3109045a44d9afaecd71ec0c07bce58bd19818aa85d237af2a25de57d20ee3da29372fac19823165f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a0f18b15a351dea4a7620730be50d37eaafeb0fc420b28b7254b743667af4240506298a5527946f7a167c7af309d5a00000000000000000000000000000000013c4e796f70fc5cd79cb05fad66e863a686d69d1374eff100751d5e0d990fa065ba4eb1598fc91f234a32133c7f0ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752034cdb0feb96aa4a621bda691ddd5c0448140de3a47ec6c05fc4fa95c57dc4e7350b0dec5e708d378d9af8d0fb260000000000000000000000000000000002a5a433a9fc8f438d3dbea44ed81db8ad1602f93b7076b24f234905362f77d9966519188c64de8023ccdbb5ea4522661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d490275de3298c1129f604f8b53425fc15579ad16bb337058c9eddb70f39e68dd512a5cb694e3bb238ae52202c6bfc2000000000000000000000000000000000c96953e74362709ff4e5b7d60169e6132c93db83e1941c017570af346ad7515ec39d24c22ceb5d0e9b2e0e632d50d471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013153f8824353d0e0ac8c2af57b5baa95889ff4d6f4e2e259a350f5d1556017f7fcc853b4f5a756db47316b3067727e60000000000000000000000000000000007851490d90a003a0809bf11687ff1893ae9e7511e3963fb221f09a3cc52b0bb2a3d9dce627fac85aad7705e430f58e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001384bb7a767c1dadcc33c1b91aaa67b09e0febd992d44693abbd423552029814bef690adc6333f79533cd77a5ac688ca00000000000000000000000000000000175a59c13f91865db10bc6ee32dc74cd444e585b5bd0a85334cd4ba834eb0c26370874878bfc811a91df1d9972be43521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1f8f5ecaecfb036bf799f9067c7723df8b0cc770fc742888efea1f757c337c00396325ab3c65ed53a7078f34fdacb0000000000000000000000000000000016d21d783afb44ea3d7ebf353e222f3def22964bc09b448305696aa635db1fa60c56861470849068ad3c0bef6fff2f3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b04e3d8bc44510a0bef3bfb00d7c9325e0993ec72655c79d29e5a999fc7551c20e61f5711889e92ab0901b552cad640000000000000000000000000000000007d68ccd732c848b9da8d9b5e19da6d017c1d377d1f857421497c897181a86fdef790e22f6c5ab97b9279b808c97a34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cf67258dc24f1a11d246600138a39156f03d36d500d61d902d21435fc825ae7f20cacc9be4e61a41c8f057c74f313d000000000000000000000000000000000a419ef3bff762b45d3ffd9b785640a2587bd4e445c895464d1cff3f6d8a24c5d3fb638cffe050c5fb6dd0b900ab5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c1a875b3d7ceecb2c858102cdb18f71ea8c84224097cdd701a734ee786bd97a29bcfcc33cda023a50bf9527afd7d10000000000000000000000000000000007c40823f9ab5f90bdae41f46d9aa3e302d12980d759ab0a5da78ef4db6b25a1ff7576d7feae512d2c5b7a00bed137c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071becda544a633a00255a219822ee6305ef4d8a5e425b723e36d5a1ecbb16f6429e72fb6b9f808d1903d9e17a0abddc0000000000000000000000000000000004f573fdd43903c47fdfac2c9f99f9ac01b78aaff42daa2eeebda863331c863e7db8e3ac3f72d0a785240da5bf86909f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f86306ab206922dee831b3aab5b7a66181d8d7165404b0ae204677a82216a64b0a203d9e136aebb1c76295662f207f4000000000000000000000000000000000c4dc92a6df8ec9a3ad498e36fe8ab87aa89a51cc06d2e69d27ffb6904ac95126e7b5fb0383bf3c2bd24d1b889e5158e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a700a22442fa2e5ae2c30bcf2bbaf06f4f83ee67c96272f795fff9a69ba9e8bf15b3d54152be2fa23432df7e4999d570000000000000000000000000000000009c953359926deb190c2a79ea64670f1cd4c2d17748158b5913640b6612dd626040d79f75500d6e461d50786ae9f46c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003ce2e8b9d4d7f361394fb84ae495806bd33f44c83ccbf78e74db16d4c0121f29e9611e3660fea361cd1d319a2553b4000000000000000000000000000000000048a841444ab64f1cd7256485b0cb0ddd5017115b0e736d85cc1a275615e507c5ffae850f3bebc6de799e2a469cff991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d6bc13bc9dec3a9661cd0b3e0ec62ec52908ce556186157c6aa05d3ee365bde4598d08828db6036dd48b6d12469c9000000000000000000000000000000000aa8a78f5ce806b1613f8cd0e75af1720ec82e2b9d2d4cb193bc5d11e6b77f0e50fc7e44c6dcf0549290fa799bf184131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167af28735c55e8d6a628534351aa8fa8d51a8d8121add5fc34e529179d2fda73fdda61e826861526aac15aabd59440900000000000000000000000000000000046928ce13d14514550997784e7711033071861c02ca72d0c8d3a3abe0e28d4ddf0f2e917946645bf41889c3a93712831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120b633b072523dc8d9f020ddb3960c576aa139590d88f9e987a80a9a93e6bc72e46cc0bc10283bae675eb8ee4e0355b000000000000000000000000000000000365a56b8df56503ff1a0561c10cf1c5fa10967f8eb9a955acade9b6a70b3e33cf1c09f013c026fee1f6a85ac40747b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd52c72980b228a167ccdac72ceb8921b863b3af6dc0f5897d6b4f63a5daa07f878af1c2af83a3f8ba0ce0db5ac43620000000000000000000000000000000013068e2d6bab3f2c695338737a6afb783a9efb267a8b06182d326204457048066345c15c516709e44b6674e33a0d95691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fc881e72dde64ccf8825f13a90a45fb9152a5819f00a89ce9ee59aa1b3881ab7dda1060a0fdec719d3873ac269ad3f0000000000000000000000000000000003ae7f502eca903de83b40c44e2085ecd1acf1dbb04e4f26b02770c94042dc7e631afa27a7cdc5ab603162e3787ae36f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000408c7c011857ad5f456512720fe0e90a8c2e60767005bb24fcdaa5f1474dcfcb190cf2d093fccb69a380c8b9d9200020000000000000000000000000000000003c731f7444223abb6475e0b00326cce7ad0506cfaf82b6903c4bced86e634c038730c008b25b9e18f010a45a97626471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee5b47c04bc210c0b63ecac79156fff8a7aadebd9a16f5e19bf083015dad1ed250dbc234ab4e706729d8b6f3971323600000000000000000000000000000000094643015bb491f15b60785ae54f03cd72b176c7999909f921261077a62f2b287e1b2db5371e41631fae13d7689e2d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e78765c3e5cc3ddfa8c1f1640f4eddec8c1f347ee77fc4a21ac7648bd9faab4e7e159ec7ef084e22aef4a7be7263cc000000000000000000000000000000001211dbbb597bffc5d943f900da60a3e1535792bce11d78aa72be854c1445eaf95aaef08c0a2bcb3f9d1f2358487d1f401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e88f5c73c86d21ebdcbb9ade26d8a4f5b76ffd69db8e24f9dffc66f0bb66fb41f45578e529d77df33d971b2d19c64020000000000000000000000000000000013e6410c5bd08bcc5cad62cceb66d7d078951a37df24b1ab85f3d06e71a3dc67a6989de0f9513f7efd19454f0cbfc7c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74ceb48485e58fdfa9ef1645d5b565af136dfc646945f1dd1a8e2adc3a07cf5578c9de70e4cd0a40e444107c519d7300000000000000000000000000000000079fc31c9c22e5224e104eb4a9c57178207336b8381960546a2c3f2d3270438ce568c237ac9bddc00c345997182625251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000987949c3d813f0392a8531bb8a465ef3bcd57186fc29948de2eb87da2c197e3ebe540fe86ba9d8d08792a3e59720d0a0000000000000000000000000000000006d945fac065e7a53df12f24895cea038d4a5999fdf481c8c0260bd809a05c3212eac608135e574fec2794ad0c11d8631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d2422130a1d9eae7d048873ec62df88a998f0b858a3c183f074cb57e33a8492a589f0790b2864942a0462ad1ac22ea00000000000000000000000000000000093fd6bd4b78064c27562257529627d098e698afc74c0cc588df5aae0dd318ae6be3f5d1a137feb939e8724eeb12f31e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171b1cd2092d9f62c47ae87df2d2d4468a9505945723d86ad3858cd7fb5fa0799920e75db9acb32ee3de30798b04d5b70000000000000000000000000000000013ea45b878f2cc39e7624474a39e56381f153ed466fd22423378907f61f30f27c5afbbbb261ff05b7ab1735299cc82ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001930e0a06d75f80fdcb7711048460168530772c5ee6d68fa86884cb1fe0d3ff7a2f5fbed10949f5a609b4447da53787000000000000000000000000000000000074012521d510418cb641d6a5eb0fbaabd5a83d999d211d2074cc6129aa575a625c2cde7bc6222c645322f69ff01307e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507874ba47bfea1818950c9560049255eebaafd30be02d93a49b051ddb952561cf14f6aab3955bbbb2eb74151b8a32b000000000000000000000000000000001814b0f26247042fae1e5c99fe18b6f7d76b12487a823c4559105f974abb5d19ed9749685a63193eb583ecb26761d7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b971b0951f942037df962d45f0ef2a3f9cd822ac89f0f3bd76007cc2f75c8f024b57182c0042769a13d70b175df87f10000000000000000000000000000000015cddbaa23aaf0be5a9072cb5a963bbcdcf56fc63ec30050dce88ef4d3a58530a8cb30daa28cd6895cf15345529afc8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e6ea808f234c7bae093efade4b59f38c26c873efd3d13dc9a49abc5b55f71a9bc8588934324015651cb3a022a658660000000000000000000000000000000014d6301720d12f02accbd35cee42947e3226cb0b5ecf95654694b203bbe5689ddeb5070d520fbd1cf4e613b4e96d04361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000127e548e7fc50f351eac4c7285dd55e3c11c3054be027aa4e76fa219f732fd72b95aa82c63cb56da9df3f0dad5d076a00000000000000000000000000000000134148977fc3b07ced0a7b6ae69b3901e5db42f51f31ceeeb20ad82f5b7346c0e7190c9d751f356a413c3f4d41318a431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010de422cf373960b0e8caf46859678de69eba51d49b56ae7d7166481897d91a699872a7b68b71b5753ebbe4cade33133000000000000000000000000000000000318096e6af31351fcd11f7059fbb678f8e64e60eb1ee00930b6660774e6c3d5564e246197303b75a7f5ae1490266de41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167cd3f1efc2e212b8cab37728087228c5bdc007efd46a583e1c2bd390d745d7a70efe1d85c0c755946aeee739fa969d0000000000000000000000000000000009922ce7fb12c802e361785377461079a2f350e3691330e06e78f52dbc5423cdec7ce68cba38d472b55f93a67d655e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010595bbce676a43adb31213ef82327a0e56a3bdc47eca85ce1ab4d0cc7ebb74dfdc8dd494d0000037d74a2445ab696ae00000000000000000000000000000000145747a9d2d4eb7af6bde1e84ced0f87e2758df399122842d65f3bd85098866d4c05f3507a4fede4fd784019c1e0f34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005953e8f0e419bd853a20b57d3fe46859a6a118adb2afb8ef6a5c10fb1a54d828781eb7099cd8f5cd0aff1e8711e3c06000000000000000000000000000000000418abdbb08122ffb78f03c0b1be480a446df16200bd5aaf246d6517ad1629140547c4985ac70891ea2ffaf2f9b7e8d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001804347a14875450c9a7ba8df26eb6fd938922ebb3df8699f9cb412b696180ec2cc1f96809d57be97eb6e20cd5c1d1fa0000000000000000000000000000000016dab34a31c0c9e29fc4b9ea4584c2c9466f9c25b0b734547b219972dc9011f2bff5b3243f7aadf245420bccd28c2b581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d09b73f38a361d9bfb516837dcc769b0673909d57b5b15cc19c90cfac6d6b9d46c2d4fafbbf5261d00ec8a79632755700000000000000000000000000000000096100e7d0047ed4438937e5ff8b54001d106c53716560a957cf41e8fa8e8ae12babdbfc4922a2ae7be42897241835b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007830e85168902d28512bb54b40bc26317a10d4abfe39e66561f683aeb384b987f18f5c6efe68031e422b256a61788d3000000000000000000000000000000000a50bd090b7ed1fc86def17e97d9e85d109b3fc5791c1f7c24e06c3dab994d415ff5d079fcc5f0c357970e393d7fce421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010436385de1925f47d38d60b487766e48efb5320d07b16063a8240d7e923bb640011ed2c64478525ce9b4b470f4fce9700000000000000000000000000000000054d1dd08ba5b5e6e8c662ec491471bf08f44c16437545c715b7427926ec1d95d42c440f8114ca0f79ec8599b46f64711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b44f5b80c879fba56141768b1ee5ce132b50bc33f618d1063a43b7ca894106f1b81b64998fa1e6f79248aa687a34e170000000000000000000000000000000015b7e15f03aa7d0ab3ffafe56d5c05a0f118a3721c2f19f11494bd08a28f25d812c1e23f20f99f1e9c13df6b4c795e3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faf3f6c3a1176c0210ca5dbc1e49c0276bd8cd55289208e93765647c3423eefdaa6328cda5b76ff3feb1d047c1e696000000000000000000000000000000000abbdfb510c15eadc4711646f55f2218bfa5dd3ebd35cf661b065a92becb3957cfeb6788ce04a09a5972bcf709a150e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0a34d29425bce751a063b92a8b0bc912b7b49c914ea04191397fae33a862dac65edc9f39ceda32eb9ee9caee3e99550000000000000000000000000000000003b1705aae6fd19eac9b8d0b183ba872df13b8390d8cc12e58ee46f10f8b885e172d7a91978d30600fd14d94eb93b14d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d83a98d663dd95e6e525adde6b331834cb1d55525f6bbafc843d4e8405ebddb0fd6a55a5effaeea154b10c290b672c100000000000000000000000000000000198a42b2d04812b4c837330fc832d68095d8dfb78f59a57acbb8965c7f3ec0a30078cc27da9aab88d8c0026d815c40431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d8b2a0a952460679ea60f33dfc4d78f68efbb90ab1de69b0c46ef14891d5bc309a5c205fa90f2cf5cebfa91b1982610000000000000000000000000000000018c1afe5958ccf07fde47603850bc4b869bbf6a4aa47a12a9a3fbcf5494682dd8550076e0deea9aa8b1c4994830582831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdd1a55a5027e2c44b597630b7da0fa2b99ceb3c395e670f9d93ee273d555ee0fb67f6785f2818f22849946b9509bd60000000000000000000000000000000013ed7dd0122cc6cdeedd432ec18ba792ab1927fc34e5218c0dc86c2d6748476f15734c5aba5bcb1735281d59ba7e4b781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a12002fa37391813c71e1bdb509d72b4d0a8bcd75e43edaff5b556464a46ac299df07e980fba7e604218a6afac22d00000000000000000000000000000000043d86e55be2f4b928f4688a947e3ef3dcb3d29bf35c2492d910410dcd22488af9a3efd17250fc490df5bdca105534351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cde6b0b705c370e2fe6a1939b1578dd70c43e162e440c2afdf980af34ff327906b0d0422381f1e5186140bf6c5a5a9000000000000000000000000000000000540d6c1c63f5fb9673a3441ccc6990aa05993afc9464dc12c427a8dc4dbf48a3d3e730c798badbb893bfbaed687d8241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffc355eb1b8ad6adc2a4341b186cf207fa027ada410956ddf4bdb7c623c3de2e054be306d5cfe1348a4d0b4fc3e86220000000000000000000000000000000016901665333329601179dad02ef67768a8a8f60a0e99781f61d62b7be4587442bc93a3beeb7e528c7687a00d9e27eeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011adc291df6d973e58ff3f9b58c495101853a5d12df9e4b4f116155103ea4d87a5e6c0784c01715ee19f05232331e99a000000000000000000000000000000000156b590de71a001beb99d891932577f62947dfa7f20b4e652efc0b634765fa9370d06dcdbe96ad7c1b5340a8f436bd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c40d9a484619d2c689fca42c4ef4a12fd03bdf2f9682822929bfdaad7df70b921e4e651ab5432eafbd82794349872a0000000000000000000000000000000012611ce2124b8b3e231dcbb9b70d32d589fb8ddd4bd209361af18baa4a65b4f9229b7fac6de5da0ed4d1629f153330781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e19a621f429cec578d3d804b5d19cf4dca940f2c207f0ce260b467405eb727b2941ebf7cf6593e1fd571ae8dd1ebd000000000000000000000000000000001855e5f2e6fe010275492f6ea2cefcf76a9a20952a1605ed32290159d31af43622e9521fe42a24045d1db1ab4e90f4471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a0642f13d7884a2e94b1d2b94f0a201fb6e65baa224fc1567ea43e9df9d0325a28f26ceaa3451054ea44b019f4eb530000000000000000000000000000000016bf52329dc0d73466a1a5eee91f7fb8f793012b4efc35d8a9dc5991268e1cac7df7be00ed19f643a1b9053be2522fcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d22426a53cdbc1a07213295f15fda4fb5bd23562e86aac96d8f88d34442deab8d4ed1daac65873a894a18a337eb04500000000000000000000000000000000139d13673bc021de2b05ca27e9952accd06ce7ae39f9eadc8da8bc2891b87ac65b41b2791cacdb3a1869538a76f1c2e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007494cf434a5cfc491460b7279994779c55d4d89645d7aa40547469984430262c960697c3e34fcd5195a4453c69fe46700000000000000000000000000000000031252a4fc43e92244eb9713690d81f0039862a8c05257fe342c385eac12c1b6a88c52c5a32c03abda2ce5657f4eb8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f2d6906fb28d14f9382eedd06e70f5ac4147585ea5bc90d9716b4113c9c33a3453211b590eb433b73ac055774a80030000000000000000000000000000000008d99615498d1e43db5a674c7496f7797e42d0af9da79560b89651ef15d02c6c7c8412efca0843132595743683033aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be4e3d77a3064014b7c10c8c613b62f0a4dce0fdf0a568c761e87337efb0cb61a18b033eb402728631a4e7eab6a7f2000000000000000000000000000000000592ccbdad457fab8c9ce5962e0d1281c3f0b0c26683a5b7263047534e435ead5eac3d51d0525ad5cbd4997a1407c2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebdf13af0959060822c881b2e75bc905b3f2824685d2bf1fe8653a945d06f820419c1ac6b1a462ae030c2413ed82c530000000000000000000000000000000015363a3167b6f1199620fd18226631c51ea1ce6b11d49c84b7f314a66d43cd800f8e77690ff79c54dee5e9860a13d24a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191764a011327a7d999cdd60920872e34e57e76696fc268ccdd9166f2256389f38c377c0e9e5102e8dc328b205ff78ac0000000000000000000000000000000008fada840d35d60c17e5b528293f98331eb99387aaf39b5779dbd7adb581cb4e85c4c7d2732d4560fc91997a506fb3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d6a0d1f17f56de0c8a64203aebe87bce6a1a3cbb40c47de113de66c131fd0f9fd47b602b87cfcb9da399fcf076a9a00000000000000000000000000000000047b77585f3d8d56088d785633bebed6dfc36eac9fd8f70a78ac126aea72fda946523b3f48f877acbde2f329d59ab9461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178205feabac517d9cc5e34408ab5191d3dcd1770006b25af69b3a852787c531bee914dc06bc5e6fa9c8933007aa766e0000000000000000000000000000000009072b58117c1918bc477ee11bb75dace84c8411e58d8ff930b3a1129c9a62f69ce140ac62e24c85ca6bb804b769c4771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b18fb5088ffd426fcb3ef8971b1ebdefe485586b41b4f3118c41ef8299cec3aff41bb1235d88b2d23d4cb4547de542000000000000000000000000000000000c07676d12e59fa963fb7c151a999a0d0af29fa78272c83fcb2084134ab72fb1bd347c90c1c445d9141b18e3964a0c621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad168e4ee533289f583873ab1a6e06a72cedef1f17d5f410b383a721fc9e1c100cc0b4f4f7bdd31f522d0c4c79b2e000000000000000000000000000000000488eefe5c3cef1320748594cdb7285b7b45134fe3c3db1cc5df8fc0e2c2752168dfad9fa7fbada1a01711e0f18db0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015864e1ce52c4cf1c413995d75f412b98a5f3f794edacd17b920e1cafb8507a6c29b779dc117d678cf244e8313945c8b00000000000000000000000000000000018bc76a08ab5202dd7b51051e775b14dd0958da880d37818e5c9957f5f73e582a5b8f2316958bbfa96405b31d4fbb971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9e4138a457b2848f666715abc1a7a4461ad1dc6cbb6d012921e397cd51410911377be48c72fe27f51528c4116e3b33000000000000000000000000000000000c8d57f124c6db68190cd119bb309e6bb3e1a4003b9aec7fecc1806c58240accdd242d3dad863d9633be334c08bf19e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c526dd7aecdaf43eb556d00bb1ff8ca15fcaa34f72c69ba86b705fcd57529651290ed3a9492dcc883df16153fcf0680000000000000000000000000000000010426e4e9a76bee4ad2fdb1c35bd58bb52ea361b4de0b5314d2f73af21b947d40f41d8dc65fc368c9a3af8f3d4ad1b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157b5316ba8ad822a3b54d94c13327e96a3cb1b734546ae28b394de25d21e60a8ee9e9185c74e918860701a1ddda63e9000000000000000000000000000000000271d9e690dbc0f6848630241932e011e7421bb53a7787497cf13083b9495cb323d5c457349d2204de590ecbd982e3a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae31f8fb3c18983c4c77001a5417ebce02fb8e5dd5789f2bcdc5766f1f481081a0cae57da0e34e434a4403333612dbd0000000000000000000000000000000013dd0cab65315b101ef5f4c0fc9435bc6c6ea76ad83b5e639f2a96fc59d1e827205a531b24ed8011cf7d96e1816393f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000983c402cfeb97ce8b71a5cb3baf32a4c449eed362c635525d20b2458ae636b8b7a4ccec97cf6722f1e3b266ee2118810000000000000000000000000000000016c8cf76bed2c1d37ae293b24a97cc421620f2949f32eac66ba1b839d5e2318086f752514f0510fdd1d2ffdd6f8ad1381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001489790ed244c375b40bcac401ba32326621e90a8617862490d394d8943d41a0078aa58ca02218089aaf6edf4bcb610d0000000000000000000000000000000003962c3714b1023bf79fc891836a0c56499a5cff186461ce71d741c437efe59fb114cdea4fdc4fd0aeca19cb89f1f1831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001975862116b6f2dfde4308bb09bd640fb7bf44194431c7c6c1208c018743fb8df74057e426aa882ba561d525dcb2b31b00000000000000000000000000000000152568803be056cec78f90d806426d8f34fefa8dd1e0190035735abe74551f9f48fc7046902c01247e71f56c5fb362121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2f9e8223fc021daad5dd0acdd2b49c9b70a2a7adabfe40aa82e565c2e0d2d393fd847f8170b7da4cb0dcd1b9f81f4600000000000000000000000000000000178845a237f1e6e518f66f69a6b087a72f6f480df9f0be0f33fe1ca3febeae7afceb877fa285ff9b571b4f8f51ce123a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b7f9ff03d6b9bc68c495131707ea7bca29442a1eeb56436d15a3fff92036edb9cb3acc60af335817359890dbe8d1a5000000000000000000000000000000000c70edcb6583a8932705803453e56fb6c043d0889752986a4f538fa7d9dd20216ed7d77276a11d75ff499b41551dd7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e177a6cd0fae4d0b877e30df63fbaf218a70cfb5f85acf1a5b593454d8c6c25d4984650ea24c43ceea1ca23cfd1f59000000000000000000000000000000001246bfb6d8fbbdd5207658ef05d755720c5df02ab7b886362597d3e000acfa76e1eea44f71b5da1d552676be288ca4411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007161a672c464889f0f1b144791eee1633eb462618e0e7fce25b5acba115e5b27598ab54f29e008d74652b943b6226d70000000000000000000000000000000015709a44de5676ab445f17f704051b5e06c171cb20eb4ba2dc3b15efd88aa757f372440e6278109e006a0b67e8eac6621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000286facc76e251ead7a9e988138d24e3b16296be9de3c93acf2fad5ed190a6d8d666d5523df5d3771bfc2d1fd12dc6af000000000000000000000000000000000f1e7504dc1da9b1e73483271f24dd7a6a8f0c0b16239e5b0db26f53caf6aacff55da0bfbcb557842f0082e6cb2d71f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1849ba4318617e825d9d7af25bdf0d309afa80c7e299a78dc216f622853af7b7e201082f23531116f8ffc7a7ff5c29000000000000000000000000000000000ad2811a9b9abd5a8b174a6e92c3a8aaef72a14c3e146a15e79e62a07309f396e6f4694e79f63a67f2c9fb0bee0a8c791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c547a057c14a7218cae0280fb42d39488c85e7ff55a021534798f59cb45aae870b25df493c513c92f20123256e918a000000000000000000000000000000000ce08eb92c35578b1b0c16e1046e17e93200873d94d3a8f1c19b7080a3b9b2d707ba10b5063ec527b3eb11a105c2754c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102dee27508e1188b018cc34bd3a8eba9d49644eae56d7f38f59dc4a87bbda847026815610782d6508e80e4676de3d40000000000000000000000000000000000f20782ec888317fe7660495663cc65abec658dc7561fb794de45cec69e2973a6459683d69053e30f7ee398e6735afb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001630513a5a4d2f90da3e2a728150e505a285847672d570a783ea98a8d36ea34aca83d7fa85fdcb7cf92415a4d9f64db50000000000000000000000000000000001db66fc8de7ea227119539b621be487814415d6437406a567ed95840d6fb7003fff0a9e820402de7a326e29a6c5516b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040f2f660f633b84c99486ff664da260da39a72c7e337980bb8e3a02ab1cc51ae27776449f9885927b1043e8b73e1cd500000000000000000000000000000000057273e4f164c6ce308bcc67e9721fc099782a5dedfcd7ae7e08719ad683da4a3319e15c83115b1fe4cc188f9b4056121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095354cfb522435830cd9db532099ce333486d0fd585075fa210a2925745d38db13f8fbb2313f6b587bbcf5a6bad654c000000000000000000000000000000001580b4008e7cd4bfeb8f1990650d4e531c4517b4f55ae4831aae50fc58df62a6067e34407b9ad36b42ee0d86479f2b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d54b8f0b00ff7369536b1079abeb09ed386412a009f0c93e94d301572ec636bd9c536a9aadc1c5414cb0f92ae269930000000000000000000000000000000008dde6a54941488a969fd9f453690daadbd97aab9fc69efb04b0099baca28195e4f775b524afbbd848a234e3c221ea7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d5f1ef5e7882ca99d5070c96fb12df242654e60f6ab0411192562712ddd67613406964745c3f49392cdaf26cc03938000000000000000000000000000000000c023f521482359a34c1c80ccbbeb2a531d37a7a48aad87be2057546f935cd87b17159a21b195f5659cad8333216770e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b214047316b2052c5492f7afd7f704951420072a7f2e3c5a8f609f4ff2574d859a1fa360923b6b07cbc62565f682227000000000000000000000000000000000b5dc45f2b280e7c8ca9e1cc402ef911181abab0c60b28179fc6996494e1b6f362da6121aa61cfb2467bdedfcc49a7591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d025dc7feda626e4a2879ed537465edc91bc40dff2d3e2e5c9c58e1576b35c162f9bc7bda127ea20b550259109964c000000000000000000000000000000001654a7647d36e4d149b5197756a266c8809c7e8f79c743ca812643c4188c2722d648abb96bbb5dec6fe9d738a14db5381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a14033fb955e0040795d9277e728f624ef10dcb9bd31641bae6b364c696a8f192be6bb2095cc47e02b9de420f807ae900000000000000000000000000000000111ea8ba7ed71b56afd6b20e9d6eb4ff7a5f28a6b6b61aedbd13afc9d94fcdfa99068347f9e529ab7a7c09093efbf91b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c1f364625f6105f62f14b4f69a7bee5ff68b59bd7d15db3b94b3bb889a972d9fd669162b3edd921ec1c63409db34040000000000000000000000000000000007f9373b37fd0e08cc06d7310f3c96e0f4ba3b28f938dfbfd8b1427939e46b37d15a0efc513e9caf3a11e40ac88e82de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087cd62556a01e8f35df74d8169c4e14542fe1366fcee0935c42732d983fd91ca1a8001328d602a16477b02fa246d03f0000000000000000000000000000000002941b569ea52964993c6e2854a58a239ab776dd013980801e224af4ae0607d50169b048955336a1a9e451bf930e233e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5d5a874ee067be22db4efcd602ed5e2b168342261ef7ad344cd348985e5c24a373993cb94f83f6c8128ab2d1c67a1000000000000000000000000000000000ebb4ba395f7ff170e7c39bedd5446cc055bd043bae165c4088e47d77ced60d73c1cdc18d2f63342fd6be3bdad0f0b021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2e479ce8bbbfb36ec15e5571fd8f69d7700e4ba1bf85d3cd4db2ace30125ac920736329dafa39aa60adec3318c91d6000000000000000000000000000000000db33edd9b30ad68884e490ac9cde61c8986adc40ef8a1ec9a5b2868feaf1a6d40a5c91466e0802a677097f205bb18531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007131adc37a75f6dab98389051ef15450428cac64df34157ab3ebe4090174c5fdec0abef241eb85c63540511b8e6be9a0000000000000000000000000000000007308d95d4af168c2b35574316f151c562a3eb946923a5e1c8a3bbd62d9051df4ed76b646da7092fbb48fe96cdab841a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8731839d6e8e852beaba6a163afbff808ceee455474349d8aa0cfb2cee4e728d7825c611c6a1a19213cdb6e9fc6a200000000000000000000000000000000165788ed11583a7e6674c12e6882bda8a33e433ed6d35ffdde07a9a2887b8f9a47ffe6d0ba70407a1173457e4f17b79c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0dbdffc104cd4b37aaaedf99549357fd4d4f4a6d9b32cd0b736f508bcc32b1d9c2bc1ebc041a7a5431b9931c7bac270000000000000000000000000000000018942e7a1135067f754c7c8b39c247230a41dd7a0e83e96ba327b1a113730b1630a6877805c1669819804ed721a6e1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bfed9b5657fa59093111f086e6f6522018f1b952eb8995b121dc1e4dc771c864c69db254558d9f9f64d7031eb0fd93000000000000000000000000000000000394775e955df9ca593af08be59acf96d297926d583355cd38affadc6aa87fad24e9473ff4101818b365e17cf82aa94e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf0cd7b9f83ecb5d55adaec0ef9e7c5ffe712ece8e592121a1b3ceb7ed0cdb6d9024a0199ab6bb9b02b40d0e5ce2440000000000000000000000000000000001f7b6cf489a1cabd71d3ed385b35a544949605c39b9afd22c51c6cc163482f2359fa105ba13233e9e6cf75d45476d501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186ff5bd55cb5a79f5ab753f9c6fee615b3b4a868082bbcce150fdb88828e6be0ffdffdc92b815841cb4ad60d800d335000000000000000000000000000000000ae583adf5f87b9fc446a8ec76be8a02d46f21d05eaf751cc10e4f9c02cef15cc2791ed5da1ad33e1b527979d65523391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb4a00c637eca527ce245af559aa43e66064da39fadb7b32f43490cc2bd73e57f92cd15e8a097d5d2cdfabc97de54b0000000000000000000000000000000003a9c9c6b7c1ffd72e20181727855b7c6a54454210e2b59a0c12df69518e36a029c3fe8381538365296b626ae6dd1f881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170588da73ae88b3679010a2ed3920eea030232a1f03672ebd78222763ba22844ab20fffdb461ddef34cbca31584f54700000000000000000000000000000000060340f06324fc2aa4cbf557234fd0b0f85f557a1c3ad8b49eef7726c6a3711135828803be975fd39811021a4f4636b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071a8792b03325090a75f23d4f16a025e16b396e0ddbda1d0e14c2090348635642f68f8837d44782d4c3dbd6376147a90000000000000000000000000000000008e72fddaa45b08b8b577c08fe9f9fd02bb92ae2dad3d4a38512429da1fed97303a849733ddc083bbcb79ccd5d680ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043c525002c5f4f5e8f49aa62e3fdabc277a4564a4f40153e139d232818ab2fb67186c916c6f97d34877c2df3be7d98500000000000000000000000000000000050892bf8b541407cc988ba58bdd2a07be559d7e28860de5baed0dd5da3b3c34d8f268febf351adf909fd2e7d809e8171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001389e2dba73f4101f38fedfb0c8844a11899aa1363cbc157abcff6c7a8d9722af103f2d14e1f79f5ec1496f86df37a280000000000000000000000000000000012ffd45436c9360893849c3abe3fc610356522832395f0dc87a3e426e82c680a07e71b7af703cfcfa49570d26fc764d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018a724c8d870450e88a559579860ee1bcae1420649af70163a85b8489b06affdbbf9db2e9d3e3fab63d998c6c2d4fec0000000000000000000000000000000009e6d967282b0b1c526f7857292b062039f1aac4d32524ff940ec9a74722d732c2bcf6a03228d035ee9c64462266c0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a143cd8141850f8799780e23ca5e88034336b8dfae8b6703b67c3861a86b093838bdc579ec17dfc9c8d511802a8c8b000000000000000000000000000000000876eb539fc293679ff1377a27b4c89969c7ea2dff20a7ef09a4be5ffbe97be047a17eec9d6700f5fa5021dc186cc3011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156aafdd9f63ae738994bb08cf55736e69436e03ca0f0d8cb6b142ce8037dd2ffa595ff5b0a6067dc38ee414349fc4b7000000000000000000000000000000000e23c86d857a63b115755206d1dc40e7e8c8cfa821f04908a152f0c392a6507c2ef851fb3f1fae83e6231296b3c4c8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036c8f74e376a5f2fa83449080e486a90064343fa81b09fb840084884e18c2e3d2dffcef2f7ff538501a925075a36d340000000000000000000000000000000004e3834c0959e746d540453c98d495c4ae6ed96caf0e43b52f70cd79a35486247f1643c46d901269d662640353e1e3e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bdf8c57c76a6f4a15fd33720d56dd05c7a436dc22fd9081878f686b7d2d21acf2b1d05dfdbc497690b0e0499535204000000000000000000000000000000000f7818a2cad848cede65dcf06535f99a96cb22310fb26d4f4f49955fc82aff09d36e29ec45524eb0cd068025fd26d7021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c0411793247a2b9080047dc845974ed0684420ea0715e228a65d0ba2f3932b9907134771034cb763bf991fad60cd52000000000000000000000000000000000b2b328219f502b4bebe7073275d3ea6e1428ce9b2145b32c99acdc172d4308a326c4f2ff872509b0a0ec2ba2ac0490b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c52c04cf70056fc6a0d6b8a7c04d12daf5b6c6984940e457659c601bef41f5ea81b3bd373d1ee6d890b30a9a2db737000000000000000000000000000000001879a242b5e492ed5ab41da7a450dfd56442755e0171177e0ec540047033bcb970aa2bd9e515a44f1332d394cca0c78e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000409a783d47da735ab470cb7ba54fbdd4352ab0158c47303120a2f9e07d21c8230709730a9721d89127abcd5293cec4a0000000000000000000000000000000018f5c058d21b0b9f641b6b13f8323572cfc700340a289b13262ec524cb2ef3cd6db4a6b5bd302348148220595a20fb0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097c9a0ac4e005f0c98d906574131f33a92fc04c408e04f4cd5b919d27c7492fb2cc60113e3086dc9583935b82354f2d000000000000000000000000000000000c7f25c7e2e994117a435b2e9534025dfde72d06be9bb1e04d84e7d811166f5b7b7c156789b972a4ac308617ca1c318d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2e8d75cbb13fbcbe597e5a8ee6179dca478bfc70444c3a413c733b9cf41d4a82b1f5cd6e5d526427163bce2ba70ede00000000000000000000000000000000083cfd45903b882b49e1d5f80438f2b436d9ff0b93e666d39835490795b15eac41f938b0616f43fe27f77abe3fb07a631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016dc1c57a8e3d242678e670e902eaa3b6cec8788ce8fd6ebf8f9098966684f3dc0f3c7b7123f61aa81737aa7ccd8d23700000000000000000000000000000000100c4bba1e04d566a04d29aa4d449097b09bb8837f0357291f06511d09bca36b3e483ef5af7ff7fe2e15dba2cb2a453e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086bc22bcdece3b990f534597e5c4a7aa8d60c7d16fc05a4ca6f68c5ce86111b62078d09ac3ae18d898b6eef082562de0000000000000000000000000000000000706eec3b03f9dd3801101dc46995919c18b58bd13775bdea6cbd8b1099d8fe4b0fdffd365a3bfd0fd74a60313f2cba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014405eedf0ad786cb14d13287d027a70023bb0515f7555358942cdff99a3c927024044fd414adb6be6e995991c4c580e000000000000000000000000000000000e3a248ae88b95741090b3ca6757ab934d1ed0281283fa6fef861d3127019dedf14719557bb9850441cb767e4e8dea7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152799b33ae932b6069bd809974f1655f20e8f01bdef67290e53179ebfbe648efbdb9b721c93425e052d8bedaf2e0f8a000000000000000000000000000000000e6f8d037fc48cb48c0b9a6196491df7cbb34eead34765e8e2da361d430d1c47abb828c9880957a19cabbdecca0e68141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4e32f49d801fdb498c30e86d1da8eac849f945d5daf5942334b68afa9a137b56f338fc6f9d6f75d2b6576c0fc2c036000000000000000000000000000000000526b18267fa99042e1df66937d1f0803d344ac0456a0dbf85b529ec35b343ee90d62a2bf6a59aafabc2ce53a082b6561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c485eddbd020bc6810b3eed3681c0795fb6cf487fc7f07bfe8920c47952bf6593c67c30da9b51ea078b0f0ecac0d0d00000000000000000000000000000000167ed7930ea1fe98b81ab1d1e258051dc2aee31cc214a2bb850440ad151756fc2a056c9e202d2a6b9bf8d21518bbf68a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121b4283e782aea757d0f5d69da17d151c3e1880ee884660191f839bafc90daed40ff596e8bc10c144b6b2f4d524badc00000000000000000000000000000000101878adc98b627148cfae69034c17a6346367eea17b0fa6410f44081aed8d5ac63e180c6aa4bda98bfdacdfa8c006101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189086621808d82931e7a7bf38909159092cc4d727706a6e094007cb7211cdf80c079ed1ba07ed118340afcc1dbba65a0000000000000000000000000000000008bff218e8779dd6c3b810579fc1b04672ae0292dc9550b717f71a2328651907bf1dddaf9fe7ec9c8c143111070159171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001615939d43bd7cfd77fa80b1ace0755115ead20eaaaf694a208c219cc67dd26c139068114ab76df03eadac7c0eb9f99e000000000000000000000000000000000c7c50d57f8dd062fa0c109f941d79d9a92f35afc1ed6b9a6ddc23663ecb75e4592554d81fe2eb544e3abcd16b475ff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000575ce7dbc05f1940f5046ca4ed1e0850e35090ae8cda85d5a2f8421048e8cf850a2deb4752d7e2435ac34d3e62c394d0000000000000000000000000000000004e9c70ba2dff23a31a1a0fc804a24d0c07f201bbd49c985687bbb998bc35c0a8794f4ad1c89105a5dba1fd6b400c8ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c0c8fd87a146b48c6e82066e7afe1e08f608e9d8cc73101e7dc3f64cb933ef849250e6bcf2034ed464d065f230f20d000000000000000000000000000000000e8208495b7c452f3d364e0a201b279796291bafe98b5eb13491a2d4fbd01cf2828f694cf3e3d50c1ec430f6a0c184321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4dcaaa994d8a1b9e0808684d53cb815965dd8b10f5ba6976885ef37979c81df093ef76f447f7326954189585db55ea0000000000000000000000000000000008ade5db3e12d311ea738ea5cd4076f298d41f43117af071b33ee46e18024720cf5ca5fb4e484e4d99931c41cc696a801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010daf97565856be5468aac670357c35ccc56888c82779c2cf0fa4f53ad0782da1b9f2fe004667f770adb6834c330187400000000000000000000000000000000167ceff3e014a8d5920222209600a54d9b10e7741b444a317a7752d8a7ac0e02e8548d4a3fc1babc4903e432a9109b9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f094dcb69ab3035622724606c08df428a55d474d4b437201d7b9c4ff656b1202c82cc0e08f9c88fcf126714cf555b240000000000000000000000000000000001aca84564fe471eddbf081fd7081b39abbf2b06e1e829e5704fce66e1baf51b2075d11fd203ab2a17907cd0ae63cb021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134e94132dc1713678c7554217b49f6977e49bdb1355cef8b266a00d2659870fadacddb11a1381b7744668c6fe6adc140000000000000000000000000000000003fccd8cf77af20396f6b9ce88dc508c147ce7fa280513505b49de549c7c44b7c497d461ef09adfef33087b08386ab0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001034d478d2b26698b0965b1374a95018a1e6218547d2b1a14b71dc9949b1b6d78c35fb8a0a74ad1d4474f09b91e40b8c00000000000000000000000000000000182e84f5c0758e882968b501f9ff75efd28bb8f365bf34bbef5b9a44fa4a6ae0b7bfeca1d2a639e5db21a8c052a033bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003127702001d1eec30574b0395006807eb71ecafbc0ab2ae185d19bbe081245eb8074b370774c471792e06732b5c54f100000000000000000000000000000000176b2ed94a5ce83b326906e68492095981b4b8396e63599305fc262b94560960087fafc99911ceb1beac7fd9277ed3e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dafa652d7aa77a93ed62621b6eab96b8f1f3c00e66dda7f89ae37cf2a076a7941560a850291119efe20e3e90ef45eb0000000000000000000000000000000011a32427b4292ca03a63877d0f6f5e57c71238ecdb1ce91b6bcea0c5603166bb7188f717cdcc37da30f958b348adb9eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001348b9d516f0c89e89db981624072d9589e21fd60ab54c85f6bd54103c37eda77930e4e56c04ded1d9c727b1baf55d4f0000000000000000000000000000000012b7a3fc319473633eceb0b97997c8cebd03dfa229ee9d3b01b3ab095d20b957cb723549c7788ac11441eabf41e9bb671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1042e03363101a5a3136ed423f3c11af2d3b8c7144d357c03e5177ab9c245cb1a995c96cf0822de10be7deb057942f0000000000000000000000000000000018165fdd3603a86796ff650a21c3a40c8646a5a7fd8ef8562d96da4f852f917c9d18dce15addd67268f1a94b58cbadca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d248eaf53fd97624691d1e21cc382de032b64e3936272d9a80bbc8ba322932575bb5f883d0eaac5dd55a64c65476e1000000000000000000000000000000000999a20d60c2e47d9ac518ceda5bd58cf6968c31e992ac36dba000c462657704b147c0d07834a5cf0971fe42a7bdab891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2943eb19aad35fe2cbe8e5d45a79daacf4d61ff07f1bda0fee4247c227d08403600f396227bab2d33ca210902eaf680000000000000000000000000000000000769acad29cb08e653009ada40797ad1202261d2c0a38804cde8887031cffa7e59033b3a30db21cab8148f24d5cbd101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a0c8b70cd672a7e94e9c62d642458bdc5e93503c46ca70017006406b06c8f223bc6b7da7d4b7e03272401612f804bf000000000000000000000000000000000ea392849993f0aedd837600d9aea2c76265090af0fbb3c1eb700ffed994bdcc846a0da2dd76f2c733db5b3f83f7381d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8240630ddabb0009159c2961abb79f493c7c459ab2674d435cdd7cc0c5f6340aba52e94bfc48d7048e6685b2d10c4d00000000000000000000000000000000050e4dbd58647e215a0c9fa22f73922625ddc599b8d08847d8ce790bd48262313b178deb1a4199d7ac61841fca2318de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f988d4d1f6b2c2315aade775d5aa5592f9137e7b9f8376aa1e47b6ad7522d4309bde9c57ae91bdc7f860d71fe92c8b00000000000000000000000000000000065094d38e8d695a28f8b9b7033c66d75c4c08e69f076af0288e98ef4576e032f34a751fdf18486a5703b4ac10127c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cd4a5f1f33b4ffbf4227ed75e7629ee41395b4416be31351330690847e19a36e6a9bc790ff9f68728dd193cf507e1100000000000000000000000000000000195dea5c5cd2d28bf6fe03ae38b3e18c2d7d98cf49c54e9a556591bf7121d88d686d3f76ccbc5fb502e9ae5bb5001bc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15ca63fa6587120a086b42c18182c5a64679781f391f75b4621e4780010e2c47c2447f4e242ea3c569f23697e7f4af000000000000000000000000000000000d27a970d50be8f5d8bc228b50ac6e27013384feebc5d824af5fa2ab763545cb337b62e9e8936857ebd23a3ad0bf8b431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0cf6cfbf1fc1eaa11556906086553cb4ca1ff89b876f84314664fbd2a5ecdeff6c9151ec55b61d6743f47f8cf4ab70000000000000000000000000000000002de62e7b12a811a814f025adf74916a84bf767a7811cee8658d389e78a4d2386a5ba2011e5f7ea3883d9b014a87bc7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a58dc82488a26b87691cbbd333b73d40efc76efdd3028a71a901f10e2d602693a111479fe9e3b27c268413791ae728e0000000000000000000000000000000011e77d2fd6e3b64d870ad354629d59318cd690b14ffda43fc0ede0b6b9f51ec19c8dbf65c3b1a5d40e571a02066629751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7fcffa27e9b41d358d34cad14a55360928cf005fa839ef94b117d79d7cf18b16ee9dcb33e36e62b30140b203c5ea300000000000000000000000000000000028c764b32a0302820c5e95762469df9c628938f66bd3c11a788714f95e960a89e2c7b0ce0fff6a00581757c522ebd521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018fffa1ea474fe59598579e370a77679c250b8b874d324b3b8aa094106a9e386915e9aeec85ddf9ba41d94dbc52fffa0000000000000000000000000000000008df80ca9da2f7ee21e62eff3d30d64d680ddbbc3a6699d4b3ae676350bc3d3789b9cffe7f9982449af72122461d46cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f5d5296a1fae3dfc78bc9d823ed5f279da8bcfc311e64b0faf60b91fb93e2ab83bd51d1350d8e08e064dc88e0b3d2c00000000000000000000000000000000062fa1ddad0680c58ffd11ba086ded53d44df2ed4a96d836a87fa6bcca97f489867ab1ab9f43c3f27258aed9e42cb25d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd929fd5b55bec3ba8b775c6ad116089989c862adba26fb5506ab155a953889b28da6945ceb58dc6100e383535877ba00000000000000000000000000000000182ce29d6d39cdc444cb21aacfc97366d6ac43f64618ad2d5ad8575e4def2ff194ce2392779bf9bb235a844f71fd54871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088219b7234b2cfd4d540fa9429d275dd31827d7b297128be304b59be36e0f3352ed67f02276bd200072de97024ba54e00000000000000000000000000000000015cd0e9d3810cae32072af0ab51405f33597ab1a8641cdc83bf40605f61f4ce8042dc02eada07f65141bcc74335efd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a5db56c7bd430d40d937584fd72d1bbfa2bcb21ed86af134e759fc892d9cfa7027d13851a5386c6945081c138d7400000000000000000000000000000000000cede2329f788c7b5536e6ff9ddc4bd8084df25714048680d13221bf4d0a55bf1f6d14ed1e5bb8fceae9c59e501748cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c090a3d0eb2a153e46331b6469b1233be67887019484e32caa319d8d2ac24c88583e87d7e88e3e565eb4a1a8f9a36d0000000000000000000000000000000004da5dd28de98b1c38d3766aebfacb9185f81ca2c5c938a4062afe3c216b5e8ed782cf639de953bd3a31ee4ae6bbea4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f73b74db6e476a55d48f6e3deb0f9f8b3511610dfb5f40e37a98f8f7944a360833b9a05d61f38cf7dbd59d8d0135d12000000000000000000000000000000001765a0ef1041cd0724c751ab7ce7355b663b83b2074db4fbb2ee6388378240721e2c23d1c5f2493268b3d7ffa9f355fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8e5230d5b4aff6b55bfde18591abaa35c697f96eb7e1aa40857062b050fe74a9edf077e6716808ee41682eac489bd000000000000000000000000000000000bf9e412c2fa57238c035c18ab6cf875634868adb7f6f82cc56fbc16a42ded00a719e3bb8793fdf6a80b0e6b7598c1171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b657f04ca044c1e17dc4cf1f148f8b9a64baf528140d5f3b20b5526cc95548daedeea4ed971fe256f966ae03d5632500000000000000000000000000000000152be8d503a74e84243df796098f22a299a3c0e70b179e259b33ae8a4ace67669f1d71c29d63d65c544f2f0b369e9e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147cc67d792628ecd3f7a83097b001f52961b164980f41dc610d04c1fe54acffe1d633043a04464036d4c52e02bb73260000000000000000000000000000000017952a7d3fdcd476b0290d74fbbd67462075e0caf2f4c7174a226cf4666b858757a7796e46892fb3f0035ab68ab7c00b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ead79b3196fd00b6fc90770b5452a55e1b20822d0753e8391db1517a867110a7d965583aa623b1c04a722e13e295df0000000000000000000000000000000013248f74ccb81f45a9c4e0e6cfa11ac9e063a3092626261b3ed70a6d53ccd8b566eccc2c08c992aaf006e5c29f186ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f85ee6c0eb0eb8059c0a1fc4fcc2589dfb5400093f5edb110536dda4da7ccf01053c35867bd7cba722bef412422f82000000000000000000000000000000000d6a3435b96a1a29d4ec4bbc1a5d721a74e168aa0f8b415a9d9f86e8ba1307aa7a56c77a7e8c3a41d3ead7a528996d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117d9368bce34659880559ef27824c39a18b1644dc75b88d7c49e59a837c888cf69d2a82536c5297141c8f711c303dbf000000000000000000000000000000000232fa91de22693eb521b73c510c9a2a4c0d3e461ecb04165920247e5e883c326f3fe9362a20b47844695b87b68ac7e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dd2ee9a4f573da898e33a479d3c0d3c3f55bc8d047564ca527b57f0d31f75760e01ba70dafe75d03e21e960a10a430000000000000000000000000000000013219c141ad8582e61b5675485ee55f8996e9f57954d808def6284762c09214e9d5421495b957372a615e5d6146f89d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d0afb17dd82e267770db5803481a4006774d596f2a46120f49e162f5855060765ea16be86a298299e8d5e673607080000000000000000000000000000000000a37c2e3886b29ef6eb1be6b258b4e1f7bc060026887f6beecfbf4b01273476010dfa4d367cff00d16c4bde2ae53c071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000abd57068b71935c7b8512e7fb4d6a726ef62ee21f9dde2d772e882a408be7d2fb5a63dea08df2c6b8ab54ac3b90e3600000000000000000000000000000000098097f683a9d83545c410633f6921885c701e94eefb3a7526eabd520e3c31c4744b706873b4a362116d6e56d3b9ed4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b54f67187d9d156b2c2cb19669c7945ea70c9daa365e25e54be7af1051fc84a2b1cab84705354cdbf23cf733a3575a50000000000000000000000000000000011169c31981fad975f4b9fe25e6b3cc47daa7e1edca88af9f3ab3b43f703c169e99b4cff2297d37b3472893c864006f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133afbabb0fad52a9d16bf742480a46b65b623ddc36f0836e3f4d8d7065a5b99a21ff977ab445d0ce93220b9cb07f3850000000000000000000000000000000010f9740e63ef557888f698395215768f2cfe2ee1af56d176c30f722fa50af58b454cee2da5dfbb64378637aa1fbbec181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5e22fc41d88c99119021cac1f29d58f08dd0c3fa2281e52850e1219bbe024c9cf01c5a9ed6075cc37b9cf289df84aa00000000000000000000000000000000042b92aa3d9d7daf59e1c1a454b567aafb836d3e0e9f2dd5e719dc2cfd6294e36e84010257002524d26cf5118bef4d5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c3fe4a1caf76049fa8f6788e89371e41e90fc555e82caba44417a315951f9647f324240745119cc1d0953b740f5ec900000000000000000000000000000000032dd389c5d66b46e25b3bf79621ef45bdde10a14536cff7770d9e5b599e9c5009215b38ca94758c525ca15f3457a2da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001227bcfb995cf1ce71b673bc38f8a4bfed67872617fda83a8b86e9070dad46309985ca5862a011e53f79020d6c3c95bd0000000000000000000000000000000012527f824e925150161ea2fce6100592c2f4a89edab115fb875d8ef6fdeaff37ea7537d52f7947177c676487d93fdffd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dfcee5353fca783ac968c93482b28e4b2988b83d42beacfe6142d113de23bfbba6abb68540e430c5602987d910ba2b0000000000000000000000000000000002129907efe303fd81ff362a5d9c55acff5ee6bdc4166297dbfb445a393c4d6a7de06b154beeebb73c22b0d99076574d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177c64106aae0934bcbf314c83788cf9efcf3bd7d5a6f933e65c648dcc10cf2b0b1a1610640c480233ff1c34964688b60000000000000000000000000000000012a1a6176176e88228f604bbbd3f721c66f3edb5f659c7ec852d12a83281162ec3e09cb32dbbd28246f81c11174c5eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119a39c6fd474a378fc499c70bf661f4da7f9c07648c729bfa6acff51c4e578a7a491c2456a3c70b348ecbb9fd066021000000000000000000000000000000000224d34e3affb9cf5b15c22b45aff639234c6073013690cdc3ea08ab64184b0a9546b61e92d47b9d252aca151c2883cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179226288c91209a37735b7d2271f780b52a77c07544f04dff6c17f8017ae7267c70c4be86004f2ba3a59eb8b147faa70000000000000000000000000000000012c36e46149764754f3f8da4f42a4c74f7e4373f2dec5f2f989a564d7356d35efdb25e212c67d21ab06dab8b3fe6e5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121fcb535a7f9b6b88108351b69f38c708ab9ce7666491e4ef2ab4da348de53ee58e2f970c0e034d702799ee26a52aa4000000000000000000000000000000001986cb4858829a3705693641e2b37da3489a292159c264dcb2aae30e4c57e570aa8ef96005598d0f94fd4b7448ba0d9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e059a037c66b9cc2e7f5c466833ec22d6d645d504fa88ab3f57b9e5376d6d1f48541a9bfe3281f2d05c2991d2e0fc60000000000000000000000000000000018877846020e28b1318dbb7117195ac6ac7b910fd86b2ac5232cf1c6c52630270183c9c0748467ee77ab786d2f91041a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001134052f59346c7607cc01bb78c2a33ba4158337a208878f5fe5efb00700c68c81febf0409a76e269e726315496c74890000000000000000000000000000000001ca1e890af2c3a408cc3ffe639f565a554c1486c5b0124f0b5972d8dff0272a1a531442139c85dbbc16770d07aa7bfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008459c590a02378894555a9398da781d996c7d1f0a4e357b5fb9a01c89e4fb2b52b4b12a3975d73a5639f4ce546f92580000000000000000000000000000000019f1ac7286712bd1fb4b54a23503cd04c9a61819cf94e015cb0a0986bb50895789a4848c8e6a52bc0746f73d6455a6ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000864371bf822c344fcdfcc848b9caf91b9292fcf337826b735b4d251ec5a5bf5dbe915ca7322c90d33e3ebe7ab677ac9000000000000000000000000000000000d628d50ba4747e6f24f28630807f08b110640b7884b482a4537af61d1bdd965d0a8184b83e8590b68897ecaadf802361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9d10092d4b21afabb7eb9e711a69d196da505b196fbc34aedcbf3745b87d23b66c0149aa5464b214d26dcebffab3630000000000000000000000000000000010767acae44d8cdfedb01397597cad56b1a4b070e22a3a408bff88f256009a737f1bffb516e749d91e5bdbd8e59023ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d8ec05cf6e9ba46a64a8927e5055b92051749ed219a878f0da9781cd56cdaaeb88686a259275ee5ed5e58f666bf1c9000000000000000000000000000000000d33a56a2a32bc4d05fa7bf0a6978133efc0ca1c594ebc5af4e887ad82212c426504b203aae1c437b613a4d3067f586d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c917e2e15c0d57a0a6305ed029876cb471fafd0d31b6b116e0973eaa5db4a33e3c596d54023dce9f4f154649ce3ec820000000000000000000000000000000008bf7597f79dd7082eec1dfc0d1980529a59605003b3e33c4bb5f7e3d3050fd950a80f8f387f9b84e1000891d7e962621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cef1368c4cbd5d932749cc0b0e63f17fde656f11d7cee2bc1dadd4f4b5a6e100681651ab79253c0140f68980b9932a80000000000000000000000000000000001461511658a0df5b5da128fa8b90528d8de67ab3399bedd07befc127b79ac25996377153cd7c46557fe2ad53000b48d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc205c10948fbd4d8b38250bbc6f7a463c00b3599b151750aeb87e4dc9de780bba6fce4ac3179200b7dd18be9e040110000000000000000000000000000000012d1959a51498cafc05bc6af7c0b9416b1867d9bbee371a550196753892465647d56ebde36b31b08a51f9872ac989f1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122bc9318be6f05825a149ee22cd55e8b7f899250d76b702f0fdbb856b06bdd629beae4c2f5f4fa60188b6d0295d184c00000000000000000000000000000000070febf1db092f857c365af2cfe718279b6d20c6b01931666eeee3f6ff8709226609854435976fc84ac674d2cb0914e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af5b0209eb702902d9f0817235d718b083647ac608fc2f53238974ace7b183897a3f4d096e91e97f806f8a6f713d3580000000000000000000000000000000004b0c3f4d1f694e536d28bb42a8fbc371372699c6c31041f83ba4ad6f5d2c8a5c1345f8ae112d5168ab00a7dcc7c373f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f10d1773484f338125d6d285999e2f9c7ca92e76f1ec5a69d032ca0e97ecf33685ac1ccb31d914f60d2d87a5f1b26000000000000000000000000000000001253ad7e29286962512cea59c7ca879d2b0d1df01c78f7aabb35267a6f1942a9fc823e25421592d0822ea5a6d4e103471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134dee2ac93903288ff36ac75df4fd529e8dcc22dbd2f586db8a2483d0bdda1bc62b470c95bec5df8d08a8610aeaaa15000000000000000000000000000000000887d6d5998a05275c9a62b439654f632288ac527c4c17f091b2d10875955bd214945cf95b3b68538a607a197b292e851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f683010d03aa4fc27d23c4bc85cadc5bacb5abeae2346e4b1c2542b44d32f0ec0e89f428a4d0b8d23500d52b961e380000000000000000000000000000000002981d0be772bdcacf8cec6b3e90f12d4f30f7413e33f772330e8d140269854c177fdf9cfc61a4f41ff9d89dac06607d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e13abb36796776a5bf5d0035caf79ed8b6a4cf8140ebcc2c4b2a071aabe86ae991b0f7304e425f2ea441429b3e71ffd00000000000000000000000000000000122211660e4c0a2d3cdf3b544df85ffbe96fa247c45ac148741a48c43a39bdb184c9633a4670b275d2df745dd2d1a5271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6d694268504ef5e09be3aaa4d73d2523da9113cf20cec97656e45df880e0b3f47a17c7e07da9fdec1f0e7d57ff85f30000000000000000000000000000000002061541aa9e0d9ee7317085f60e06c9481f867c5bebbbce48f1b74e565e1286c9868076329efe69e754df6afc8da1141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dbf879d2eda244b9c343eb5894abe8c42767a0c306b8edc8ab199bbad78c217233f60fa7ea59fdf47650763d69c3e000000000000000000000000000000000154caae078bfaf2a5a4bfc96e2acd4488a2cee0efb9e30cfe2fc3273035b7322aa6aceabd44fe717157d33efedbfb7811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107f24b70c1c4bb1b79483166ebf052f2f2ecce17a4f594d8a10c914830db9e6f7f855d59b05cd27c46bb8c333f5cbc00000000000000000000000000000000012644665c27c6a90db276572c3c28306315bcdb7c9afc8d3f879ae643b0719bc61d9fae1ce70a6d4775a883626fae11f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab1863d3539e56bd6fca1eeff2e717d2745f135cbcf28f213c9d247bf2f57fc8ad74500d44c20dd40ba700b93de63280000000000000000000000000000000000779fc271569b24427fb1d362ca90895a8fa02c1be293fecc46e9f8238db757b02eff349ca83cca20ebe617dc8d095c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137f00e0a1e7ea7ce47ef1932a2ba6299e34dbfc485439d43a26c769999aa1438bd6ad44deaf0b0d4545df47d89126b5000000000000000000000000000000000268c083eb6634b447699644b76f6f42c07291fe72db258a579294787654a5f3ecc394cc92cb28694642526c838345701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3fe80c3eb8c1a9bc8f32ea4db42ca5ec5c05304257bbc45d23035498a020aebd1077bbf304e63dbffef54765409b0c00000000000000000000000000000000199890fff7a495c52d1912b2d2f7608b60038d9ebe89c11c55b3bbfe1bf8b1bb640d8d502685be987d084439ec0b8f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d01553abd2fa20c7705503bfeff8ea4adfd6808399adbeb31ecde55f9c0584ca0253db923222ef414b8bb23ba274386000000000000000000000000000000000fcb59c25a7a64b2f6da1f847717f6d94a89175300f03d76e181531a831382ca90b8987750d9405c8c51abc882c332ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a12c59639d0ce40b883261c4bd5f0e232d7751fa754932ca5d9eb7063422ce562cee8246b602a1fca6e608653cf2d000000000000000000000000000000000249dd8d2326be060496f5f0d7fef68ec891b10fc29149d0b8d21ddb4f1d41b1e61877de162402c7711fc9db3320041c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f28bcf415784395119d3b5c5ca500a807bbb724f62e6146bb75bb07715e663f4a9bc546ff9d325ed2fea8c44f7b554000000000000000000000000000000000bded07bcdb0b70cbff8e069834bd282c0a2bb6562f7e1d261f477a276feb00438ab84d53f3f35e9675f44d3701650731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017782c22a0ec6901414a29aed07b8eea3a50ebd9fbfe0d8a0a2feadc927eade0d3f48e3b39a43a9f89a3fa10f960659000000000000000000000000000000001579254ced0ecd3cdce9478da86d636bde054a1ab6d2ab75c90a639762dcd80d0e09d7b2df0d28898798cacca17a7d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163c69ad6c491a87555a060f9e1d666e024ccf114affd667c06e694120c6089e015337205e96b389890d3d16022b6f3a000000000000000000000000000000000bf19b8511a6920ab194db23c7fa67a70f40eb1eced346963c8f65789505593e0c3c4da4090fc63411d819c15a7741881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1eb111ada505608c6826a89f406125b1b12215cd037aca9873a827eebd2825acb2d2c1909d022b4b70404d66a0e4b8000000000000000000000000000000000284d829f58e3063d716ccb45794337aa0639c3a7d4e6b9b23d381e8dcacfca88597ab05055aabb32a633fff06ec0a681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c30154e8ead8a42f28c2cd880ded0de9d6a56bd16b14bf872b585e1aaac30dd23c14eaace8012cb1c777ce458dd6f070000000000000000000000000000000010070241584bc05c8842f678b0f1a290aec6a67212d131493a8bbf4cb3d6396ea0accd8bd83a3633407354ce742ce7831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127f465cd2138bffefebd96aad1a1890b773bc3e92ef9f3bfce9b87e039a9f6637f9a04c762030a3c95fb481d23931a50000000000000000000000000000000000d183a827c4f74266b993fbbff76e2582e8c24fc18ff31df7c99d09fa2dbd3f783f7d01ae8b63024a924026863945fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007583ba430066f307434868063bb6750b75ce5703df2d88ff356c678374b8b8a9506d2bca473aac6a9a2b58f9410d2c0000000000000000000000000000000017ec6605f7bbb29e3ea35dc3432a4f29276a8d9988477e849a14c5fa9412a9f32705d4ab9cf30709bf27865c5795384b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d6cde89a1228d9b78b46871f1a0cdebc525fdad5019678b413b00b79763de15f1a6cb9b729d4426b5d19fb1e43752000000000000000000000000000000000b5a4f056ce2832cb21ad990d6406010a9c6af80a91d636da44a5a8ba197e3a4bf47e21689668499c4241422f0fe0df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9edde2c5e0ef173cca5e72237fa34009322216515f2c73523de2f4200ff7c55bd8bf1475ff49cac7a859bc7bf5fd7000000000000000000000000000000000ed48dcfd622af979974665276e9daef0299685d64da8b05339aa981757afbdc9ffe681acc74e44cc78049bd78cd10c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114c626d5a5f97d01d8972a466db9d015a1c75c684349765a25266f48c7460a0ffc3c8c0a1702224449508adda2ac6d00000000000000000000000000000000009d33646807728325dd7f424eb52800ac6f155f12c5fc6ed1189f5937d1fd40aa591a4d14f895f81a3e71c5acf9b83ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000716e761bd8756802ff9c2a6b8a25d195acf82ac99a18dd583c311fa408254423af6673fdd0af20bb54df65e2f8ca3ed000000000000000000000000000000000b6657fdfd9d3e58a83cb777871cb795d68d24fece0986d14c70369bfe804f12e44d1dbcb66a999f821c79f54e1da8021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c3093154401ae35866793516c006d7bb89b1b40d0b69dac5bb39503ef6c2eadf18b977e64f9051919435f4fa35ee5b000000000000000000000000000000000fe4843ccb9a13953775b689c4f24cc0c846c674d8c09d747847e1994f4247620d7d4e385f2eb690ecac8f8ce1f433111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b0f635346328719bb8e3368c606fec67423ab701b4c846df8587e0afac91a99e5a17655905e4639069b044b821ff22000000000000000000000000000000001018f5e0c0d11018a90a1106d31f9cf41c9f011ebfac0a9dd4f98698ac39276a0253a23ccf5131e0f28aa717d175daf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162a830f6bd3d39a1569c2dd63331d5deb433c896c0410e8601a3b26aef037de369e8583e8b2fcbb2a6ed8be94480074000000000000000000000000000000001054b7f65503aae3366f70be50e667c17934449eb48babf075034e4ee63f71a938019a3cbe29fa547462d7c367a679bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190bfb7a0b49c8f583e4dc8b38ffcabf4c4488ddac0c03ba579bde6113b650bb469c67b35b7b3330ea12a4d8d8a19494000000000000000000000000000000001881f114393550e3dafdee177de737a6f25deb10691f5415f80353c48d185681208710322852169b05944a5b10731efa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006524c6a811b6aa84405c40d2471d17d368857cb81d1823c36c75dff91d741cd4447b6216dd7d2c39d2b56635345f16f0000000000000000000000000000000014aabd4eed2c8eee836efa318a80fded1f94004fccdeb4e178eccf0278caa50615395719858db7fb2c7c7325ac514ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066112fe0537c20b69ac978d0657f4bd0bca4b1069a328c327bbda09a10fd1b1f20bffc26657817597b65bf17508b5cc0000000000000000000000000000000004415f38b13880a54d1db36cbf0f88153b58f5e25f93e5449db627e2b5db39bd885430119ea83a21e84deb559218bd321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153ee311d0c39399e915b035c81cc49ed9975249b3fa79f13500a653a107015e14e6b0eb1eea2e306cc0619a0d1b59fa00000000000000000000000000000000187ca82a83c941b370685a00c5d368307a270cfe3ebdbfdf05a9c77011f2862a2b00f36f3fee987acb44d358bb9de0aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7cb7d27a63cdf11ac421fb3baee8be45059292661978bf70607db3e00b38038e88a31fdcfac8a39169e96eb2a59077000000000000000000000000000000000110aba6454b1515c7a8e715a1d329148f03eae054f4bb0b4e689f2f844e30cb42454c3d650b1ccf2fd55b13de391c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c32e9510be94fb44f2c8d228d3ceea26f3c19bd3a115d0a2dd4f269c7bb7fc85571a4877012e469b3c184142d62bca0000000000000000000000000000000019306027faabdf805408188f4051ec8ec17b48406ed454441207683e08eda6b7fcc305542528faf83d6db4d199aa48201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124d308aeea141c321320abd18750ccb0e027f60bf46f75804595c1689dd6676f2d2b4de52a60f23ce2b0a9785d845ce0000000000000000000000000000000016f72448e45f6e1479bfa3b0a58f04823ad10a8fbeb9315a678a96674a77ec1d7e80bcd7ed366c087bea6f8158518e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1828e277dbc837727490d2b3b23467356a6afb35a679e8c4ce8b02da0fda62c37f55513cd3eddd25349a9f625bcaa000000000000000000000000000000001600a39c4ae049c22c2487dbcaa9d7cd83bc3d36217079f57af182ecab86ce2e377d8d6cd8d03d7d0238c531c65f530b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d0c95928e7443382a6801b52a89d5d765adde938d93f3458667320430372725ad5641ba43bf736e26aeada5840466a000000000000000000000000000000000f38f2fac47b59b51a6eaa6f10edbf0c808ed5e1ec37dcf4929026d86677792249537ab4c4c31cacd4509508df362e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000617b915c1a71472611c0aca5f332947f0e9314cbde5ac9fa197dbbd4e5210c99dd4857347c517077c780b183911f5100000000000000000000000000000000111e878f21046605ed1ec1acff14a65ab76fe8bfd9b5366c60c8f5ea3411ebd9dd40d5cc566301a226feb5706a10e93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d4dc494bfca265673402aacd8e03d03060f58817f1cb8ec02c4061c5927971882350a8fde6e03884d58b0ae09c05830000000000000000000000000000000009eddd78d93e462baa241c54834b50eb13588231592efd371567b0b1f6c221e42bbeab506771faf7f0f72ba707b2a1c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057177817fec28e26be81c7157bcb808948381ca1d7f15f38547d31965d47e578a80c6cd0df56326a88b2936fefe4d01000000000000000000000000000000000a48c9dd6bfe505565f29ad3f37bbdc105869644886db17e858584620390fd7c96ab9c0b4a071acbceddf1837b4bb42a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce7289e56f28c33a618a3d74aedd6eb540a6ccb11d4d76637113fc491b40c58f2350b0bef99d1a1f1145468f003bd41000000000000000000000000000000000719d4033aff1d6c7abd3a0d052033b7f11250e327d042db555f02e0adf8a5364926d0fa9af936a5a9d9ff074b3aa0191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e50c05a0aba567aa9263da3742f18a9a46c461e4da36ee25489023e9c83f29b9031ef255be676e38fea1976185fad970000000000000000000000000000000012ea0296b98e2c853a8b61658d95f098c327649bf2f0bcfac9b6a58264f9708d419d2569125a846cc8cd6a2301dba4141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175bad04a658386447d7def44f640c929fe001da40fc296128773cd948c0c45c6b4c668f7810482421693f27dc7b320f0000000000000000000000000000000015c056b2acd16f6df67e566d122da81055cc570e5f4be1071b9b58c3960966b583524d28c07ea281401783d215510cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e0f682af163d945b26e20df5f51847e1bc72a51ef59591e512d912bc8afaf52505e8a74e48071408d909051984964000000000000000000000000000000000c9f8b5dfede897748ed1290df886c7cfcf34813709fe127518889c27e85a8eb8e40fafd307ecd4c2811ce0ab663d6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ccf9d859968ecb3b3376208406bfad762a7727cf0594ea06f3547af48ee355c9d7c52ee7b2ac7a11cacab5b7b474ae000000000000000000000000000000001748e626aa18fb16b0e20e353ead9add544e3b0fe24e651c34f0543d38d86a70dd7d183cd256511fb4573a32dcbd0c751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000013aab2526c8db7e75642e3b56a00c2759206757954f4fe3a684d9e719a5df1d5036cad7d515ea4668ba6ea95d1e74d00000000000000000000000000000000136a4065add8d668a870fe794211edff0d0e476f84da03a3796a1b1ddc9b46145d17a9c9284d5e162e842ee8d33791ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb9c4effa3bcbbaaf4f8bd9300e20e64c501b44eb7a415d1e7a5673a9e0c8cbd10aab248778602081420a229633c3d200000000000000000000000000000000165025776b37dbc9efd3f7d258c6fce82ec3f7f3fcc29fca665c37d2fb9d94af3ed66baa3c150d8f02d2ab0ee6d196b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d5e4702503f19606fd86456f6451c18d61a51d9e176df6c80bb4ff2832c8f81895ee58b5055d28fa070db5b465bd44000000000000000000000000000000001851023a1777e751d955b7ed41ccb59c79642c3481d3b83b1d42d225590ac5168c8ea1c73300a470dfc6896f9596e0821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b0d317a634bfe36fe4d6bba0db9cff017c79604c32cad52bf04198b904033160836a1684d7626c4d95dcc8b9c4238000000000000000000000000000000000acfe12b3bcacba11ab226546a3ecc841d126b78c669ac88c58a19f16ae53c5c04f1289924e52e3bf25028a6e72f1a151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1bba3cbde5d43f9c78e65adf6e97a13d8e665ddd29d0069bb8e85c7c5d9a6a6c401eebcbe43117d9d37e076dcad4250000000000000000000000000000000002cff6630dbade788754421d07d9b9a5cf30916dd19c8db8f1d1976fd62991f29f2790525f30cf8d9ff379e532a3088b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eda161fed19f5074fd407bad6adff4571ef70bd435d4c70e4479d395e81f0833831fbbfc13fccc894e9c2df6479772b000000000000000000000000000000000369260e8b965240604d7919eeffbc84111f369dbb30b7a31c1e6b8278ee0324d8fd75601eac68c47be503803ccdbf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134c07ad7506821a767e40acc9a4a3b690414a48380f01ec074a5192a0aa9dc53e685b99f9b9db1da3fe17cd7266e045000000000000000000000000000000000a77531440c8ccfa968fe835d6aa8d085a86060ad83e96dfb8b996ceae80dc707387e4293feff8dca1da7fe975852ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7a6941070a08e4af416367002e201abb19ad89099af7d54cf391893b399a5e8c1d0adac977329d79d4fd2bbaaac3dc0000000000000000000000000000000002748750118f728605090a5ee87055576908822b6d8647306381c709efe321bbeb7d8baa84d448f32319f415bdfbf8841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6e9cd4b4755f6061ed11a1998e237d1526da1c68916f27c3097b5a1fa0a2f8fc4cf72364a7401b1d083cdc9723da050000000000000000000000000000000014e576aa7ab9443ce6165b206f98ad8b65c63b36da61236a2215a06398998ef0b846aebfe7d5219cd469186b6a38a3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cc6dda41f877440b84b733956377b280ceaa51bd0878154ed5a7524e2069a4a83199e9ca8599fb963333c093ba63a00000000000000000000000000000000007558b84a223cfacc73a2765515c5a1536dac83d355e77f30ae40cd94a8d266cb3080c7c2305033439a9fdf32c0000101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114f035c7db1ebaacf5a19b1eafce096086e3d1c15bd6cd840837207ad91605c1f6b39c645f2c73f9e1ee86c3c38a3e600000000000000000000000000000000043e9bd0631bc9655ff3567b23aa28809cc6c2dca10c19dd5d61d2f8da75ca66b3d3fa636dcd5291f0197cbc7445e5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114e7f4761603e6e5f1cbc3045f724ef2a109e0303dd2de9f0cabc7a740f8683476e478d6c6c2f06a0e2fc1d3528bf19000000000000000000000000000000000d9423807bd5fdcdf9a29bf0dbb18dfa24e9f6d251238c21f7178bbf72e0ad7ca8c88f26768e19ca1155d0a50493d9241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000710badc66e453d341bc8024715491d8087f24d49abf1b7ab3dfd5d6400d1319086d5b28dbea5dc0e6efb6c41a04d1740000000000000000000000000000000015ff3098afaa2f032a19322ce84ac8e96c4aa8be45dbf9fd38d7535b4d032e466ce9f2777ffe2a67ff98b8ec646993011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d186768a7f5a163c0e81289e9deaf23beae4cef029e5b2732f5f5f30cdb3376a6fb91bcdcc60be0fb704274c8a7446c0000000000000000000000000000000011d9a5234787e99e6ab91d688e1b8d558d1307d8314300b9c98ddc28414c34eb5422e6d5ee83674d55feb7550986ada11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c5523270e36aa4b8109b1de6f2aaa64cb82af4735bcba86cf5290e70516dc9f999799aa8d46f8272b5f1b37d8aefce000000000000000000000000000000000ff88d738e8bde309250b084061bd5b02965abc89f414c570bfb7af2e46442a6c3fb646dae95df9f9a9146cd5c0555951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035e7ba1d16be64e34a8ef1643817be28070938a1338f0677484dba34afcbbe7bfb70aba8af6dc6f58377c9c0284986c0000000000000000000000000000000005d162b6aefc068956b642af50d8d946d9c54ec87f6a357d0deab1fd7e63667da9ba3951a173c43bd31c7b48a4a169711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097a2176bce8bdca929db516336d07a0116e62336b0f20ceb211b45d96934a4179bef91e97599120afce741a0dd2809e00000000000000000000000000000000167a0d8b7fa26a863330d0d07741a0759cd48070f4ae20f31a26c78d909a6e7db5740c47d63c2e6387c56373074ba7a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001523c906d6871d1712021eb6d02cbe3de3022ae065757ecbc649e774cb023910cfe432030736a5ea071fdb1c1a06ba7d000000000000000000000000000000000275529a5c5ac15d80dc99570e776aa6282187592f7d486dfe1d5d525cc4a157367a8ca95288a73845f9d603980157781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec8afb041a771bc6cc59743659de9d7edd99b8a4467324a08db0f4b825ddb8f7bdc49ee6f1c2dfb27bf70250e5d0a66000000000000000000000000000000000c2e7e9a81c2331908d844e6f3c460a9bdcfef83cf0748bc934c329ba4b7c9ab82bbdcd19c270e393ba1146ef2be88911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51c3d6d6304dc229073956289625f7138dfa366b313525bf99a42cc0774fa559973c6f5dd7acc8ba8301560471e2200000000000000000000000000000000013b95841b2fef0dc5af31e47e526e54598fc34750793e48f36f6e95280d4ca507af75a8907ec779c6fa96e76dd4581011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b5b1ad9b72ab88e1b7b22d4436541a94f053208d3b43306af8837320023767e256073466cf7f77f101aada424d27c0000000000000000000000000000000012aabe4aefb6a294ee68b3e65377ef41798330b9682b0d87a225cf1c371c39269acb9295126f2f20910ccf848e080dee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066568bb72034a6e91b7fca1be8f21547d944a28c0313119bf7659679abadb40677b1637c54ef9b0dcd69e621b0175be000000000000000000000000000000000365372f94ed3d8cb57986b1e57b5b3ada3574ebe3e7a03afaa0b5e0aaf3ab7e812040411358728d2d1211d3b809d23a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cf3ec9d3877bca04e9f96f1c8c4a9dcc82ecd353ef497d76fdbdb48f75c469adb3ae71d3c4ef2a701996a740d67868000000000000000000000000000000000980375d673e44b235fd68811b485388be6befc8701048e68f7d07f201bfdf95a22c9729eb714a47643b86851575872d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f36c310d3a40630ec183b4968c6527369755c3c715a986472ea3b1709f7f68c83d4c09f75bc811de1edba1ea29a97520000000000000000000000000000000001760ea38928f86424537d3ed2804d2329fc670157fc2891bbe4747a594bdd572e08ac4f220f14d09a6dcf03690632e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f946984fdfa5973a0ded1d655b9918672b7091a6673a6144948c28ec7e2a5d8c847362a10fe2f0be73a541f98f166000000000000000000000000000000000faa511ffee7c79c477123db97ca38bb07bd726e168eaf7f8613e0d85e7ed803126d0b22be174983e9058358285e80991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182e13651ef67332c456646b6ee145c6a55f3187a51ffa65a043ba707ba3bdae81de346b5bed73367f2c9d61fb7a06ad000000000000000000000000000000000dc33d15486efdef313c95f9f70f8297e518053c02a2df8f40aac209dc98d93925146224028580556718d72b9153386b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021570546f896c62dd22f44cd5ad4978330df53cfd79cd1aa945f1b593c563ac1d27ab36c6a89f57e8f984ca81d500e10000000000000000000000000000000016c83533cc6ecce644ff64cb1a3a8c57e66c704d1c2e28e86d7092eb27dd7fab6cc2f506b55cb1b334382fe4ee7f25a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017814542ddf5c1e24505ebc0f8a2e8ff2f7356f23bdc1178e6b582e5799ea6beb1205e332934ab2f58d1e03ffc2c87de0000000000000000000000000000000002a84fce73de430ad6f3bfec7d6a052b70c2f6a7f7701a755a38e7fd1677acbf43c7619c8ede78d6aaa215b1213884511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181b11e9cddb6e76477755a60a116bfb26058fabbfd24227ef77c0b0144376f73b85f6dd33fac5295b34c85c91da394f000000000000000000000000000000000be9ac9baef26b8e604235a9fd93b709201ab7a71bb40f7e0dd0088392615c9a1e6c5e512e0a1ff0af0df4f40f58d3871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a36e2d05306a26a1c5f1ad7f3cfbb4901599ed3059e991ba25721b159499a0898db606cb4516e42335b1c51c15c26000000000000000000000000000000000920a2bce1aadb4660f013c39b6f76f5e02f1f991b9b12e01bdbbdc25660835915bb2e6f688b76a066985d4c736979bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004649674b64c3f92b013b7a0ddb3790eae67eef0a5e509a344b98f0da147213c8a5f6675fc0d3402f67c88edd1168d23000000000000000000000000000000000dc534a517ed648ac4aed345afe478e1e30fa68dac284f314643f174d3022726a274b7182922af6120230135cb4c2fb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c67e965c52302bdaef759bcfbf886879fbeb7dddaf0866727aa656018efb2b5038aa9ed8bb00a7dc35236c5a258310000000000000000000000000000000000a231f94cb81b70ab7cb3c592501832e306420b8b01f2df45cf1b374b04e8e55a666863bf2b2608a4ade5804b9ff6811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001203f446a7322b15f0b5e6c077e7c5ca1f3912480073d39ad00e62b932e6dd23521b79bab8b871958b9fc681fc8f62fb0000000000000000000000000000000013a416d6f7c218f8ca044a13ab7149be277e30dbf1361183ac4192ec2293d090a896024b785d9598c31dcea5d9065b681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b29cde24f39c8de5610538bdb9ab71492cf65140876cf5a0de24e6664cd07ef95dba1de70feea6d54126d84f02d1e000000000000000000000000000000000003528892a780e1b4e7ed44dcca1affe376c30cd43a6fdce1632299a30cac86fcd31014361dbd2d2b41e619063f2384c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3a547bd965507d04e58ec7567db6291709edd8eb05ce5110adb31e4fd45fbb2eb82cf0015e0a16ab6e3c62574edc650000000000000000000000000000000010cae65f07bf99b3b8a82f659afe2e778f751b52487d5eb37a089ae2f5f944f4d3d44de66e9e5d9b73d072ec6cccf50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117be0f47a10746ecbdb5f9e27171a168db44a881a5e8ac5a5284e975b0b8b799407b3fd56ecfb4255c7abeda46d9362000000000000000000000000000000000a07e72de4c1ee1d9e3eca42747797930c4fd152ded2aed2e4877cdd0fae4cd3462d0b5c9f998c24a1e30068cf3640091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000443dc582a43dd855a899e50c71183aa287da2ff7535ee914b986854a9755220aa19493e1fbb8a76c94df329fb7cadea000000000000000000000000000000000b88014d62c2f7aa5b66b0a911b4e680d4b62988abb805232cc40f071454d02a2c904da19c53ae71b5edc20989cfc7401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182f46aa6f74fbe1d6b7fb4289b64396981c2732a107426ce7ad479806ae5f58a1ab8a7c8e7bd49af3497c6719ec5664000000000000000000000000000000000087af5ded95a3d7c085d64b658099ea085ad95ed1712f6cb83fbefadaae2cbe073eeafc2ed27fc5f8a3fdf74e0536931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010999ff27f530a977a4dae5036f71be0f19aa1f4cb62cb5bfdb3049cd184b0d1750a395e75c575d2f1ec64dc239aa3da00000000000000000000000000000000156844ea096dec9c62e5b7a829feddc0df74e6e2a06db905477802a0e2ab5de6a9b7cc7001c2e2611e2b661122ad24a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001835fa9fef758d13e0d6d7e372e6455b6d26b6a0a10a677175f28288bcccf9b2079b94adca0bd345a8152cd45bee318000000000000000000000000000000000ee991f6788c2894c808b28f1d2dbea0fa39a5b7f12d40ebe4699e35e6562b696869309f603f94d3eaaab3661e812da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008134308eed1c5f36fe7ce6a09a0d5c1b3c7ae5a54406ac462c9eabb4e4de5e1b9955e5679f317c1b3887414beaa95fb000000000000000000000000000000000cdab023018e27f3af8a3946461cf4fa87038684ba684400e6967dafb6a0375e806c9e4828d4ef0c99c5a518f5e62c4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117c50eb91c53ba1049a6842c4778f68520a2c777396e66077ba21332e6e748a5bc2d0b2c782a288f315132c155c99830000000000000000000000000000000004d476e19b48938e72501199993b114aabb3c194084d4d8391c52f4d965f861d73f0c6b0cf717581d639a968ac00fd261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000261eb78c2d7761f9f0cbb6713db252643f556a39bedead9b29ed85fc1622937dbd886c42df17539becbbeee05bf018d00000000000000000000000000000000050d568d427fc8168c0955df7bd3d75d101c7d6c3b61a436a3e8d3f251c6111f66e1268bb2d7af3329be1b30f1922c211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011dd3b5b12c8ca944b3678159bac55f06a191ef0afc22f96ac9623fe8219bf333a2913b80b09f739bd20879e267c1a40000000000000000000000000000000000a6676a6b75ce49853405f105301cadaac5a153a6c68e50e2b987b1b69c54ecce9d6f302bb334539c47e46b632aaf6711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000474eef0c18ce6215c547ac32ff341f3013901df42865adfcaffa0cac9c85fef1b34596a0374646b97a50ef7c021b4cc000000000000000000000000000000001635adaf4d7c320f9e3a886790163df345f5baa543baa7ebca3a712d3f66c55b837430f3fab9d0bcc8b6d7df148f0dd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b702c4c81966935d31f21935757d1e464c0a487cb881843fe8050a30b2ce931a6c279f782e6d0814fc75ae754d091600000000000000000000000000000000012190154b7fb607d47059a5c75a228ada1f9f1c6cd9637edb7404a4ea71bd0d5eba8f4757bacecff94f2521238a7ca591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b950c2d748f0fb01a2ee6ee3ae0be0a6f30698707744b8b2eb5756552215ed189cd1c1bb2b8a76cb132b97ea294d4c0000000000000000000000000000000014f4b308232231424209ce8ad7e3f7b9b2c02ba99f7794e37ba45766d364555e1e305d0a3b731f94db50e137feccaa331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431e977a01295e59c0cad353c13cad6113fa10c0f74cac235ae1aafc8a9a0de705c6adad0e04596cff4f5312328fd39000000000000000000000000000000001292ba6bcc6dd06d06bdd43ee0e714099b76fbd0585cf5c8fc800afdf172292af73458ff2034bf35f30c663dcf07a0201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d13c4aa6210723e7b40e4c6303a5ff9037854a2aff73249a7c817565d46c5b5bf0f27904f397b3425809b5ad940b927000000000000000000000000000000000b6516a23e4404babe42fd1c9a10a6c90f80a69cb90fa4e564258a6bfa780167b148c3c667957a897b3effb52cb7ff8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128fb9b94833499c653e5c9f7b03d28d7a6937458c25b1d09f7457fc9469ccc8ac0a2a7790fd530a453b17c58246869d000000000000000000000000000000000fb5c99cc1b64db7bdeebefc69a4e75c87ce5286c5e4021eb7ae1b8e67b98ebc09c7aebaf733e96428c1d2ffb277e21b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7fc580bc588c297383e577785f3b82354f66b7390124ad32d5270abe95fbc8e5408eb7a49da3ac77ebca6a57933173000000000000000000000000000000000a3c7ff9c277b51d876e72262093fcf87520c6ec9911aa8037a624ed9cf5bb3a99f8089bd0b774f314ddeb711a82301c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cccb5ff10ccaae44482dd32a1b91010ffd2a9815a08d39d027fdeb63840b8c0c00f99e60ce1ed0576166086d52337000000000000000000000000000000000bd6f75b651d27857a52fd5605273d6bb13387634ce17b789ddb51d61052a79189074360f1b415d5388fba9156d2b8fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7acdc1c14d7c47f11819f09a2b1d33adc58fabe69a21377a524e624f6184dea0026ecc824b70e59b956b3f17fe992000000000000000000000000000000000de3fce8efe567049e0f899fb36280dab792ab5efa389e1b7cc99635fbabe3e052c600f7125fb38e095dd7ea980d47a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182027d4dbaa9737f2389936474cf920d86d3b3cc9a2164e0bd6a1087f7547170d7efef3409baec3ce68fb90b1d439f1000000000000000000000000000000000d01014a7ed1e888e282ca2037f878d4d46cbf134078e89dace4a77a41b2943277737d02cb2af43b5f8569f670a8d9901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118f0992f31e4a0f67545167fcdbc1a93c2b3a46ac77508c485a14c6e044baa8b04422a6aaf91d74fa3c73f952b84c4400000000000000000000000000000000126b32b62ee47a3676702ab4eb6735bd97854ada8ebef04c74c715bba28958694820e14f5c1fe4bcc956d8684abcf8461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f02309e85c8d18d0f1f42b36e86d4d08b30e0c1e36537e39748f1c889134b4a4dc82d8f871bbc20acf4271677560dd70000000000000000000000000000000015bc83629c4064c294832aff45af17faa7f313e7d96250eff7478808dbaf0e4790cdcd232ced5fc88ac3fa47dffc39381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae18244c91d25427e1de84fa2a9218ae99d8792f01132c5b9b63c885e3500ef49bed29270b0f694faaef428ffd5c25c0000000000000000000000000000000016a0b3f00199a6038e22c8420702dd3d70727b8838026b18521adc95653b9265c5fbb99a6052812227a266d62e8a41711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081fcaebab68677ace7cf5c31828ec9bd45e5fcab70151809da87ff57772e19f9cdd2dc8da2e31ed61d8deb51113b3d0000000000000000000000000000000001562d8f4748969d8cc2d0a3cd1dac2065f9491b47607f6965187e01b134a5ecc4c5383dbaafca17aba71eda850dba4391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093cb53222f27a258e0ed9ffd464e2fdcb7ab36ffce91d646ec1d158eb758cff0c1675440e82acec1ba55549e63d91a20000000000000000000000000000000004b70d06cc09bee74554f8aba2521e1d096df0deabc44a83efb01a8c26c700c733c725579384dadad7ec76fd323663391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010047f05006b8ebe1a8b52acb18e74dfff4324114c6291a2ea35747327313c8ba60139ea3394c7811b6938af414cc94000000000000000000000000000000000019a024075758e9fee3eaba5ee5fb6dc53d0f7a9c00aa3c1fbdc769851ff78c379544dbfdc27c51661feacdf9c3db3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d79527bdb23739f5df6e853632c9232b4bcbef6acdd04b4530bcacaa780ab5c9e7e1f9fc46af8703eecda6078cd6630000000000000000000000000000000016a15faf5144270c79501910693a69dae9a5dc141499e87686e833dd75deec3bf11e0d9975fd97bc2823e07c9eb50edd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d88f030d1a4955d2a50907b7b6230dd479e228089765d6916765c2a9b157cd6fa08313dd7cc0a0bee51381d8db94fa000000000000000000000000000000000080000e9a5cf21acb270f85ec4dbffd5f878755d45242f98f64ca49460a27cb3f040e50ee1b1b1d91d44220f1292b9121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097d6dfdbe7a6d8b1e93ee7555a5e257031c62f67ed42718458384978265dfa1e541f3424d354266e9efc40fd377082e0000000000000000000000000000000009be64f8e4fd2725dc3ca220eac4bbe54ae5fac5708f548352c9795d80f9fd044750e2de47f6447b394489bdc9ca485c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197893290290fde71a9118b654ea3d08e40e5d6567b0f06607325e35e2b2126feeeac5cbba311e6c06bade1d776c814f000000000000000000000000000000000efb96c5fd2b4492912e6bafa90500bce0baf44cde9f4a2188c2ce9087fb6b87ecaa91222c5c0f37f932ce888f27febd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3fec6bd9dfdf12be8316365f412902f10f2c2930ef8ede5c610d3a6bab8d3f31f4d04de5a4d9012174ab480ad23aa7000000000000000000000000000000000885071f2e531d875eada9cbb06e0b9ff1dfc3456479020ce576ff73aeb9de7b3affc6c79b14b419cb79c28574dd953b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e3ad5218ea3d425efe262120b2fb2a58913ea63240a654b54604fe4faa4549b3dbeba0728379fb4bd12b6d526b5ebe0000000000000000000000000000000006277f4fcc2ae2c7d173647c435aa18e2b93122cb77a47ae4237402052359b80353a1322d7dd16cda5ad6d2e9c0fa2281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5ee7e1b095afb224ac02974892f3fc9fd5b0d1c2773f125c7602b1d997d13d2bd28130c81fff7d9af335570041b75e000000000000000000000000000000001384ce3936604451ffc039f79a7b2a548f0d58bb21c655f7a020dd6314aab21b046350273423263b1e4154de6018b41d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000888d26042dca804d9bce363a69c9dccab5375f3ba53ca6c92752f0eb0d6a0e2e9c8fa8de324dc3b32f3765ce97540da0000000000000000000000000000000013e546b71db223830a04d1b6ae39cfa85814cfea9decd5c7641136ce4a1df020e553f02495cc6c9d8f20570c246905131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5370bb0d75669c4e9ee8070245ee3c372e3cf940d7210fdf4ab443b9226099df908599c85d123c3d58829d0cdd827c00000000000000000000000000000000023deaecd26b72d2e6e40b7b33783c66823beed7fb47b393a2073ca9890ef4911742d6c44c7e1b138685f4bedfdd64961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1222435f5056d78ac596335828a8ef84f23dfd22504fa4875b42c7ff7160e1294ede214f667f74a633469dcb2d028c000000000000000000000000000000000fbed157ed6a9807bb35ddd1fd2c433fdf115c9e1da7f3702a245bd50fce3575ab25cfb10c1fec44f357c3fa241302e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001198a4a93f81091ecaf3c3c84a10c370505a37eb06895eaf9b026ac6caca4900ef2128dab1a086dc5379ccc508ab6849000000000000000000000000000000000a5e57bf4559328468d79a47849d4320a9ac00aefd04241b2013a3a8ec2cc3a4f01a0d1c94d49bec54c827df2e0ca05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e4f6b1465621806f64ca23db2254f568deb6d93b766cc6bc2fa746692fca64463c384622f93189a510a0aba6bf4dda000000000000000000000000000000001437e93338dff4e9ec9549e215cffc01f70a4095e03b294bbf7a002d79b95368c2d7e73812b56134dc7b5d31f9998b5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190ef1bfb7eb8e589a7a1e1065e463420d8365e6c454e96485a11cfb75a9884852ae271839cd43546b8e8cbfeff012830000000000000000000000000000000016343ff76b64f33b45c953f6107147559f77221877234cf7c5959dab061d73c3afcf9f58d7962fa3e50852aedb18c0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000515ea034f48ddcae65d1090faafa598fa85ecb349eaaf04808964522a1ba88986722124b1e7844662987a7e7a85c46b0000000000000000000000000000000017a53c13dca393c5aa672b5cd0f0d6417a5d68a193eddfb6154dd93f49de4420211d4a4a0956f9528f6dc4d394e0c10c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1a7f429a1608395ec8a385d068297126a4cb5664c67eac643b9aed9066104333c4ae9bde178b22adf95812a394de000000000000000000000000000000000041641ad0950398b419249023b291d2f095c3d9503530bb810bd57430e51bc12e2065a6ba00ac7f6ce1cdae8f8c4b7861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017b8420c725f2ed05ac1e6e56b97b649ffdc69886bf23e8ea61f08edc407960b034517bfef15c57234ff396cc2ce9b6000000000000000000000000000000001170f591f2b15181971d2a12c2e3264ff9654aa74d96e4068a6d20ab4d4f8cce7ab74a87b4691271204f9c7f26f9019b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8df01e17fc25fce290dae5212176fc3177a3eda26a6484e25120d594fab4f7fb8ea8a261a312808ff5341682e8e9a0000000000000000000000000000000001ecf5cb47f717ba154f3f6347cb65689477e676cd5ced69d1f50d71b788bb4142f888e2802cded07e8df0752cfcd8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003277fe7e8942fc540aeb128b0f87a6937db3c42cf1b10986978a59293ec5f586d12f8efc56b24989bc7532f7d330cd5000000000000000000000000000000000365e6a7109d1c459be428fa4d920c3d7591dc0360a062e9d4f62c66877b86174c3f9c818fc7f0b8b0c083db4ae84f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d42a100025f5f8bd56979a0b15a9f4e3d1d7c41c8903ece56cede7137157dcffac8c2fa75fa7db8a648c38b616d4150000000000000000000000000000000005a41a34f189f261cb2169ca1a2552d448000ff334d380510e868fe3b13122ceb254097207a6a2325aed2fe7954bc08b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d77fda012cd3804877272cb85e4fea4decd4220bd961af177b13e05e4580af2bd24de83e392a49a1dbc781d6fe62afd000000000000000000000000000000001533905928350e78609eae1252877972fdd8190c24913fb8741a5da6d5ee171b0effb40c0062b003ed440fe0b12d4cb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fd7872721407893387e1af9a487834689b804a4948219c9296e17fb936c7ca9f39d15549fbe79cf9c117627db3622e00000000000000000000000000000000035bfb2670871a6814285155e618ee55f538db075d6f5b37289ff60337f14a01aa228721a99c836d74a34a6be3d2d8261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092a254a1a8b90ac06f41a925e8929e31196f1ed044e40025e3dd92e388da467d0afb93f9865a4f16ffd5aac0427557a000000000000000000000000000000000d5fc5732adb4525c812c005038a319cf8eaa83fc3b65c048735d8ae7e82b7c3951cfcd5eb36e87cd0a70a2e41ba79231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043b7f73c36b44fa867d5f63d45f7e3ae3b9ee433797c148345557928634cab556df1843206db6fb8582b5d937d24a040000000000000000000000000000000018b11f00679b3ff73dafbbf9bab7e909e11a3e257f14f367145d31208bbd5a301af2b1664920021b5168d27fa3ba5eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b25b442d2788e3e2158b6c4e1e7c654d19910d55201f4226127588b459a110326f7e3f8243f7735f01a44ef5d7350000000000000000000000000000000000a54bc5143469e523183749756a760e02ded2ad292dcf2cdc5d5584084fd9992a80f5eee34bf051832f90c511c5476681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bf4fdaad2fdc2888a8ee7a6ef278887e98a2268e56141b7bea32523e5bf38cb73fedd52af2c1804683c51bc31fdb2c000000000000000000000000000000001508739aabf53d1625881fafca4487a50ae34b3d8f675a19508cd320303a059eb82ed89851cc3f4176102ac1743e70a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011299c97ee11978dd6e4f4e10997436c523230591f2230112d0705400443fc520d94eeaeb4db5fa9820f1b01e16ff6a7000000000000000000000000000000000b7ebde19fdb8e2f04f0f1da417a7bf327fb97a06ed1ceb66a1ef5ae8ed27e4ec5f350c0267f84009009a1c5a5808f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003029f907b768f745b8399bbcb65703f1f55114a913450f0d2fc79ab51c4c606254712f1bd73ff40e3d5f4fcafbd647e000000000000000000000000000000001637977689677e9a3253283c6925df235cd676210379f284eb44bd54d007185afff3e4f17a1ff021e242675551d5acc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001028a4c6a19e8f4e2ea89119947d59379490aa0b99760eb1d0d72ea3d0e727c5113b18d0631464dd60ffd6dfcbc9b912000000000000000000000000000000000b386fe01c4666262fcda30a2f2008e602e509ba7b6c3ecaf55d5071f4cf2d6617fad5a469f4bf298fd018d9b56e9bd11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016995386a79aa391fa6042d1bcffe3ddb343bf5d0e0b8fa5f969b96c2c7713aa4a5c1a488dc7d58db8fae1893776c8af000000000000000000000000000000001848397e095f75b09a7a2a0ef33f46333d716a2044d61a0910ccf700c337b8c9a1591ea51f47dd383f2e27268fb3dd7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000581998237e4367ea45c66ae720701c9564202d9e167de582d71d2e65948f32d451456015e0b678484838526f3238d1e000000000000000000000000000000000817a81d1f7b80db93faad87a5de905468fa98b907ee4bd00a6cec7bff92bef9ec9f014e2e8d831032031660e40792df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4ad9fbb902f1b9f7f5906d89200ffaedf48786f03539b317d10d1a7317d0fc43bc8124288879b28d771ba12707e4b900000000000000000000000000000000032f484aa3a751b0b830001adfeb8366d982c763945b62d6fbbd1f3f95a1f41465084a2afcf19087f02f1bdfc9e359e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000943a9bacb0faf2c80edfdd0cbe16ad9efdfdfbbea95a6bece0a5ea39ef0b2306ed177c4bb6e6cbfc3f1aa4aca45970f0000000000000000000000000000000005835bd610465fef99c27477a029d7f182c3a16c134e718973495ef49819c6bf5daec6014b39865d1c66651631ad6f241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538fb84582b2d6cff465c2afbd2194365ae25e5c1c129875db0e87b49d842d82ebade8cc00b8fe2859dc16e695a32220000000000000000000000000000000014b2dcb25c17e2b164214da4d5090ce49366476a56e7efaae8fad1ceafcd46e32bd2ed1cedeb584d9132af5a8df4d54f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015261072d9fa05b56626f0c9de76681947d46538449b2f49137a3499dc78c2d9f128c5cc76bb1de8f2d4c11891ca80e700000000000000000000000000000000198bf287cf695b39f8213d96063c469c08b3fb0ee62641fb1b4f05e445a2cb70e5195f1cd5ef455cd7bf47fade2b588b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000882c23698a842f71b00dbce067aeb68c0590051765ca3b7732bb87ed2a31e2e806d89b803fb4c662ca17367f00c183700000000000000000000000000000000059abbaac8f8b2f8dcf70ed664b96ce3736e9975a40a48a25ca94f03c8401733745153cddb25da31dcfa9c73681128ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005972cd71237c7fa8a15f35f9675318ff1ac33ff525c27cc185dd79802df3d37617340d2a46fd5aca5a8882483bfaee200000000000000000000000000000000052b06fbfe7bd8fe2a7bf76ec22b1ffb2d68252511187140134b200438dbdc422028ea171989d7e3a6607dece4033e281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001251474bfb312c307243705e3ce250ea93488cf923536e5697e3026d608aae3921ca9b62d587cc1405c053a96dd71d540000000000000000000000000000000008242bd30f5cc2d9794b2c258006abe73a3547a19704ed34e37a8f06a5753bfe969a38098e9bc6c329818f8929aea1091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190f338c4548bc0a791e61280b91ba0433e51fb0488110203af50f4f1fb55b369165fe953cf9c22a5ce84efecbdfdb6e000000000000000000000000000000000e3dc00b2540ef94618a5c8d9998054140d832b76de7f79e3cf25eb607d191dc2298dba7c2dc501e3d5ab1f4b9514a2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eddf7ffef969cf5418e154518e929f4c8f063e1ac82f730bc1bf55064a42884bcf0583f3928f741905cefc77edcdb0000000000000000000000000000000000cd491d60f3389b5ffd5c39224fc883990e57b550d48e8dd70cbe263e99ebab28a4df65adeb1329d744720195736fc211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9415cc54bd5ecdc2bea7b32a2c1a22cca7f1c86f9a3cca56bd0e59ffa5df9096faedde3f10de9c0845979353747fe4000000000000000000000000000000000fc38fd750c57fbce6191eb2b6cadf2af99854bb047a65be3ac428730f9e364257c747f455bbcd957477ac5a9e3266421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cbc6f58f419b033ef48e86e295a7667a90863336dbe4a57af1c24b259da0cff2302ce2aeb21dda327e6c9fb1902262000000000000000000000000000000000e86204b2b08ce40bd0aca4af5d2d64b41441fab22945bce18baef1767cc4246b9b8421ec20e4c9b68f8eefc234b7ae81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ce327e7d2cf21417023d00bf4adabc5bc930e4d62b015798ebd46811df9937f6c11586bba314e57167334d88aa535b0000000000000000000000000000000013db73eafffd788d8d5450a03df60d59a5fcdca899a356cce73f5e212c9f79a6e28fb6bf716862e9d4c4643b40b6fdb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006790346c9b7e1231169eef17b152d40d06ede85c54abb87f0e1c314abd97cdd5d80a8d165d7c424e84027ca345b1fcc00000000000000000000000000000000015bf6e108688ea8ea223b6cad7fa3bd49568553b8e791d726e208d3ae91e5a7fec41855897049709ade21e6922419541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f93098d767316846b46bcb0d8b7fe1b8acb2889588a4f4cc100f5dbd5c9c987d4a8c6478ab091d224ac7499033f013b00000000000000000000000000000000046768ea3c2d0ce3a57607f3068a819a451d828833111c90ec8a68ecbcb62e9348b33ff776cfcd10c8a8c1c0c1602f891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c74a0fb7054e002b8fe4414cbf4d3090cdbc2c1b17bfa52017cac299e2c41749356d6253f1864f290de38427624d5000000000000000000000000000000001570f3184fd3a110385d2b48424626de6af78d9e16c1e471103f7a85bbf4afe7bb92ae51becea5361c75e48e2b687c231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004787f32b74828883fde4c4eb8deca38bb0a9a1dd265188c09fdf75497d992f12d307efaf4da3615c6bf4b06d159e6c20000000000000000000000000000000011611ea2680db7ac587076e3a3b1ce5801619d96d124880619a0b099c844558ead47ba8eeb88bd91bedb40bb98ad5ac91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d889ecbecf320c8ea7437b7d306b66153d764be87dc07fe63c3c201ce80bd8af339d502f38826ef7d181edabf811c150000000000000000000000000000000015f02a803fa9cbd37ef79faaa00de75f395f99ecf5afdaba8ebd6a6e847854ea41b8fb299cec7aebf107baf3ecf2bd341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4b72a9d0ea08048b03aad6bdaa0010e42c29113d64020f913fd46f1ff428ef2d77786a114ea9a6a79cb09ac73428f6000000000000000000000000000000000233609f107eb923e40ad6828324677cb636063c6a443b66c84f47a86515c2d08f1e8d368bb06283a30a6fa40956ae821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197ab30ca98868e39a813c3033050a8e1b9aa45bc3c9f3f404e9e8c53922e3077e4e277a51ef12a516185d6ff7350efe0000000000000000000000000000000006ab36def0305303afa4a21855d26d3e8198a2646efe78f565e4696d4c99ecaaffebe72d6386878f482d02d4c10bf6e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452ce20b2c6d9a67c7e279edbdecdf84ea7b20f57530405e2407335a0f02cf35c1b53e08a94fbd476dc31323d385ec00000000000000000000000000000000007649c64872da423d5b5332df46974504cbf9564d0087142fc2dcb9ce906a049325c1de9d69dcb0089331b52185f7fe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022fcb0e5e71d1ea500decc6d7b4612db4243b2c7efd15c71a32360245e5f4aca2c5171afd8dca508443f64cf5d9f833000000000000000000000000000000000a3e2331b29958570b9d10c5e2b2fe6405300a3a312502e0f48f59e37fd5ffda9f6571c7970159a6bdf180db38202b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000755dfd6e4d959b09c7cdebb385d57512a8fca54e5389be5401454c6c07ba0cb56d4ca8291502382d782707b4720897f0000000000000000000000000000000000e46c51aff857a6ed25202d10f0ca55671b26fe77af792d98091e04b9ea5795927a4c5697876596a7f0388ebc67dba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3ae7e3f7829937ad027342500c22b67e56261d0408677ad0679c532cede9b2eec3230ab488a14e1ea50d8aa7bf5c3000000000000000000000000000000000e50ca090f7905f30b04bd234c66e4cbdbc97b117fdbb3c50ae017b3fbbbe03f1aedfa6f5595824cfa9cf657690b86f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f5eb9da27d3dd2ab039703f5ac8c1e83239169c51e9b8d0902d2549c128a04dd0649c4ef5108fd01505e9667ac4cf000000000000000000000000000000001564609f19306ff8e54523d2a183626793d5bef4e163b62f0c099ad5b92b5a7fd73735035760680049172ffc8726345a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168d9b50e8dacf5ab8f28e181f1c52d5415db0ff312b9f849c749b0b5b9bcf47fde8b81fe55646efbe39f58a73657f9b0000000000000000000000000000000019657fe35c6730948a74e0eee2e820bd3db1d3045e0cebff257ca6f07609980624047c8822e74261df59bbf73ed13aab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b68c6408d5d683baefe2a59815b974fbd7665ab60d14ef051917bd886671ea4235c98837ca1513021913e17033bf14f0000000000000000000000000000000003dd76b2bc86ae90fc18907c16909add5ec0bebfc7399ce26311b4118629d6d76a762b9d8654dc7108238e0426bca7191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a3aba3ee823ca0eee25cdf5e35ced63b366f298e40db132e8e222ef695d2d1e2c3bfb4e0a119be9533e79a4f4971000000000000000000000000000000000132f474047b8da402e73166fb3369d321c97c1541c276753b4ae0f02b9777d01f273d1b8a9aa3ed868be6d11880b955b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbf62e0c2ece933803404b3aa5764c26a2114eca5922c6f401bec8d5d447da3a3837a1b866f6f27eb04f51f9b2129540000000000000000000000000000000007aa036bdfd298a2bc8881643c7ef1e9243841f5ed023f4e006bffefe0066995783b1a89c6a5a41c781069e94d672d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ad7027d0714919108bf1de241b4fda12f1fd1108c10810cfd38a79fa8c45c83a5041078e9e20f9579848da66937b5c0000000000000000000000000000000010d261e69d30994b40b185338671b6ae1f797cc136d75ea807bbf82dffb7573726080cf6ad3248b5b5fe202c382ff2941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175411ea735bb9b1387c839793758e0b84ba2e3978616902cc54fcf1dda6b16e3477087f3995da2c8a0bf0a1f69fceb50000000000000000000000000000000003169bf48b6b3d89560cec091a928c3d1fda2281a6dbcd27cca5183939765c09065fca3465e318060b533f73ee844df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001947bdd2a8446fa04f5971c6937be70a02a07bdbab4269afb44e153e79283359e23e96e18080bf433b220a66be65b858000000000000000000000000000000000a2a895cbd02ee0c4581b1886d8fea4279c9a366675d9210d1ef22b1e315cf88fb874a3b20a7dd0a1898e205bcbcda381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f832e090abc2bcd1f54b4130d334531c3e8300fd87db86c9088a61118a25416a4478ffda2a9871b9ac43093e8e6a52500000000000000000000000000000000155552cba13477324160ae1bba296858fd2b4e033b25231dca30961bcd3b2e1f8cf989b8bcda5cc72e4fecb952cfc1bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fc55b5365a3a34267628803bd7fa5287c22673fc1bc7cc50cd43dd9cab4a9d5457fa7e87c1d92c022548e863a50559000000000000000000000000000000000c98348baf672865d20aebb9ff61b5a40c6aa9969ba199206c4b065c71acf550539a8f4374474ad031d75f0d1910f0371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001476d100c2aadc55b6bfd73d7b6e52900d79649c56de2e5e7274d35e93fe44f669496cebf82cceb321e7496e07093cf6000000000000000000000000000000000f80c36442ab26bc3c67d4d8006fdb69b4188bf58ea6142a93de279b0012dd603f46858084af0db531741cacc492568a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b111e8c6426e83ebdc80ff8dfe0f06de5801ec49011af1b0114a8f78e86a5fa7373735a8e6abd46ac9af12b2115aaaa00000000000000000000000000000000045edcc73d85db585bf6522db1007823a63786a23f0365212dbeb81eac584ef770cb7b51582322c35dd2fc51af8e484b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f8c97a2d26f3d96460581147ed13051fbb6fec4f39b57f6a7ff0caa2d170ca125135f999e50ec4e0f79c7cf2e42249000000000000000000000000000000000bfd93b606842a2efbdc0c186726e0810f35889ea42392859e900d8f8e546c207af645249ba07467e0eb94e1067b0aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005268642e8bdddf219e404a46d9d332cadac1087fa6598cc8d2ef4ad0a519b758a700f66a8dba35554eeda77784237e7000000000000000000000000000000000a56ca04a67af4269c95c0070895e83a63d12c1ae29e116847cc782051c65e46082d7a0a46a8bca4119408bdbb9beba81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ef51d859710a04194a2efad785d6516b58daeac566ca601b39265ea4d00fc91c502614c26a351eb9b9f2706e70bf70000000000000000000000000000000019551764736d594117593547221338bbc2482d5175fd9dba46e081933fcf83c4d3ffde6e9aec56b6841f95ef9f25d9091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166e4a94e593a5841c5b4ccdb38914e7ed7dfb43331d3b48e2517bf6d64d7197a3d88c9c03f8440c28b1618a795cbc3900000000000000000000000000000000195dd4b627a72ef6a7b7ba800020a4de7d6764885b3e8ea861bd439c2d5654fe1fe7392199d19f6787fe0563ec1b74401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001542c11cbe0088a8799f08e7a9e5ba73ff4cbcac171cc75d530512395f61740964de6a88ec0f822cf7bd3e69c33e7be6000000000000000000000000000000000c0fc1826e12bf454be6abe4d07f52fd8e60f0d09e82e00c3cdca8789ed1d4ba58a3f43844cb2a7a1e4a88f4074569f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015822c53d5345aaf69f8583c60b4a51f64f8f17fd44c23bcddeb64187164f026651ebcfc9200d5755289347c154199b40000000000000000000000000000000010368a2faa902d3b699e27c610dabe8990f1a56e50c42c5f3a2db7412b4ffd5bb06c41ff73aa6d48594294c7cc43d4131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cda3b971d37280c3c7f38b4693321cd1461ac6efff1980d3bbcc26e65c71602fb6c0037bfc06a3a73d68c66cd56d9dc0000000000000000000000000000000002cfd987f64c351689d17bafac4b6a9889a15a12f499cbb067bbc5872c92dcd67e9ad12fd80438dcb667158e0b3911bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169912eeef3d2567812c53f599e08230052a351c926425e156e25a81539ae5f269be12d33a9f9bc02614b87743b877950000000000000000000000000000000011f74a70d2a333e04c4f085f8e452d146a0dfe9143a3fa292a9c9e94253bdedf982878d094c61a24d337980d22e970541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ee200816a9ab88d57c072f5594c577d373834befde0e8fea72f90b5611cbc0c5e8e2aa6f95c21c0e5a15aa3ad03d5000000000000000000000000000000000e3d2fd9888c7715d5ff4d0c89a1c2aa47d3c7739da8a8d64046bf62653dcd0ee3f6ba3e0a69c15f3823ac061e7627a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a71c5cf839d96f3b4a0e17cd6c7ff95590422d35d14cd7c8df470a053017650e3aabdcafe078f75782873efa332267000000000000000000000000000000000b3d786b512e252ed2741b637539e1dcd9ecb64d94176377c6c8ebf03bb0d29e52b472924cc08898eadc90f3e32efd171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0e3388569c8f9fcb8bfe3b7211483813607a2000169dd22f66950ef3e7f75a22b305be401f8f2e006943e69ba350320000000000000000000000000000000007098d2e3521387e3f38c34f31eb5e05c251b117c0d2f77c9ca24fb47168b0ae108ebda1627d6e32fec484efa7acc1811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fc3a5f5fb16ad292901ae02011fc59d380f5228492c0045098343b80463ed1e524b13d08e65358de9590bcbc150a1c00000000000000000000000000000000019a5a503e3ecdfd1e800d2799287b39001884424ce207bd9340a2beec8337669a55ad6e624a097a06b00c1d5af818601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001cde754d4a7c87c55168831a05e9203565a3143f0d4c3d64833bf3c2385be46c60bbd48cb87890f3082fec9d0ee456700000000000000000000000000000000038b5bbb589f96a6b776c3779d3f064ac7628883e5d16995f125e36d58981c2b092c86a7ba79b2af64098c011195a97b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b01416502f217c3c4d3644ef7acd861f5366947a4010aece6d546fe108343b215d1a1474ab1602caf735016b71a7fc000000000000000000000000000000000f8401cbdaf818b64ff9725e975aa47500141f838dc2e4cdb091f481d47570bb31fbdc8058d3ceb4a9b3b6a6d58879ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e5b9b6f2401e9b9b4802891f5fd43f6851e255648f3dbde87a301b30cb792786b0c2e20323455876b52132397f6c570000000000000000000000000000000002710a0180b632b5d69416c24f9bcf83384c260ac269d27cc56b2a7108f6c99dd9ee0c0483a912e128c6fe3526e2f2fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e254a635a5d1e3fa55b22c3e6558cf796d5b4f9e1f1dec966bfc66d6ef769585cef36d4c31c7342d4181c7a579f265000000000000000000000000000000000d3bbd974d2bcdd4f27780d9a54d5ed8850bb1f4d591e89194347b7cbae24a2d1334285371dba9a33d143f48262f29db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cb6ee768b184c3606d7d4abc1dbad76354704ca6e83f7789d8ea4821b64524e1826b12da5320d7274774e0701cfb4e00000000000000000000000000000000099eb18fd5143d4bbbc1d0e94d097e422f06baf2e1e73564eea0ccb94d398bebcda09747c96bd50a34c29e5be9c1f70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052181c68099d94b0d33015a88961ef166d220b5ef7aacf0d98bcae271538d2de17c415e3dbbfc317ce139ab5aace6180000000000000000000000000000000012f6123a05dfc803c8f6cc982151031436542daeea7d3335f2e0cadc385ded52b056068f1fc98b88a01c2e4a2eb39fed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c4a5828212e6847bca4fd3881f7996515b94dcacb29eb847d6e6661a632a5bfe5090bf42b3671d3224c58669b5f33500000000000000000000000000000000058257c1f6bf61583fbc0fc01731727f7381dde691270048bc5de52fa1fb7f5080d9ab9e36999924ca2e5243478713521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001883f73e2e52cf7e431039f5f85291cd7b5e5e41615aa07b50cef561b4bc225ff266d5127a498d3c2347157d2294607d0000000000000000000000000000000012a2c543a715d02d092c9f7f17c2250b6d3fb486919b870f09e402de795936894f9feb8f5482519fb9e19b8b190036c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b291889174b416c3c36db917dd9bf9c4fc873da699dc0cef731f1b4867c078a462a80688af97e346cd4f0bcc4d704140000000000000000000000000000000019648448888003c975f68e071626c254619dbd469d9b9132223ad3ba9f554741473a6fb9b06fed2137c5d767eb73aaf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011531fb5df9f99b8d2dee28f7943a50ea2b23a565e4b4de411f3c79fc3e39c7451d396e04b58ae817b0eceff31a624a000000000000000000000000000000000013cd3edfca5e8022f2bc356c1ecb96c7350399dcfa49773afb7902c80981591cd2dc34017335270b271dcb90382a7551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a907299a10ad69c95c882eaa4b5c358fdfc8d5b8b7f3f0b269fa45b5f844c18291e12c45591fd352a6ad99a0e44c30000000000000000000000000000000000c75e0e7600387c6d09e4c3e946f9464507ede225a62d2d574d870846ae322d91c3625460e5b598d0780977da5f7bcd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b20aef047d33f49a4fff43a4e05e4769ebeac15d9bdeed6d8a72ff68e1ce46b700d4f40ec436c14bbbbe7c9a166c7d5000000000000000000000000000000000c8a9896731cacea41f503ff2df566ad46e5574c50a14d954b1395d410133d5b985e2e5d1b4c168e1227756bc56910ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9c74d03e48d907b9c2fd3ea1920b4fe8faf2ce8fceef0347353345de346afb54437b524e6857c58df9a41415c8180c0000000000000000000000000000000011c7829b4eea03d5987c109a64e98d96f9d484d774f9dd50329a8a78b5ca4e594aaa1a3b8e78fc830d26e77e1d20042f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ff7238fb961161b04f90a0c411826f7d1e3a1d97f6c1ba6695364a40acf6e38f8c00b7d693e460503bf2b757c3a7d6000000000000000000000000000000001847b1d3706a5f11443a266efc4072b4e96b6bfc337e4bc2b07b6d58d3a619783c8cdf209b39c2be7623f9cc63b5a52b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001272966710902cbbc9f3481a6f2e1cde1f367074dc0365b14c6effceb11c9787a97d08fe4f6626bbe1263b8bc8c70ab600000000000000000000000000000000054be28a84bdf36adbc290fff833794cd5f8d6d15f5de5d1b712e0e0284ad1a31852258bce38df0551493ba8532d08ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010405774a089dff82f88fdaea591782d8d4ee7b85ddedc3cabd5449453fd7ea06a6cb76d73504bf460faa5bb03f2fdd20000000000000000000000000000000011a70f84d3d31b80b4fc0598b38801dc55bdfab5ccbba708bbe35b88e38a23cca6889c283d7bb34ab98e3aade48566141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000060b3957bb1d5e9eda50329fc869452551dbc8cdd4469a78e807f71fb40653f757ce067f07baf88d6063f40573b469b000000000000000000000000000000001118db56f4d94b12e58beb2618c48511885ccf6ea13c0fbee0d9378fb67add5cf042e60cd1a9cc595576d6b48e9d53281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e5dc80af46215b1471cc48f3b5807c1752217263fa3ce122508b7030824abe440cd3bd556c9d1af8bc996904cbae8000000000000000000000000000000000a16b9686b572c45976251ebcbab0d7683ba4844a36f4ac8636a968992dad7b95ba70c360b297c24701c33118317363c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013824b1127bde34c82c0b32f271e5a57ba7c7309fc04101ffd075e6b5dd6804af9d247277d9e8674872d8fa831b6a9eb0000000000000000000000000000000002dc54fcbeb08ee200236dc577d5b22fa9811f82aff26ee4b3cbc5e97942066a11d8f693f984881673527410828231ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186156bc81d57479ef6e84d23675af126938e935d32dc1b70a226c17030b883ae6d4303399548314424d3e8583c4ee2e0000000000000000000000000000000011361862f0b9c14121146a9e72a9a2db9bc5f01f42928cab6ac8a3940afcd182eda241437560b76ab881a92e1070bbe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f03a9ca1fc13669063f758d3afa3648329d2d2921baaba447a6ec43ff2ba6708f9b2cc1ccdc2523bb5b328fe63397a00000000000000000000000000000000039689bf993aa66a58a4a58ba58e6be3ceff19e2d4028e0cc475c3f640f78684f3db278877f1023ea0a6ed1a5ae3904c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bce6883364bc0b5ba7e03437bce3b5928e039a0a3b0831be3588b087b4b2b62be5713e940974ec499d165d6a56fdef000000000000000000000000000000000e1916501843a040a43676ec864f52f2a35837d8d6072f8c14460e84f51f36321ad9909d9ff561a9f849d551b094acf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013aa536d13324c4a610749fc9d02f97fe8d792fa29811eab8d8811645c50759664d00ba9cb7ad8c902a0b5a3ae4470e5000000000000000000000000000000000cd9976558d904f7057c3973dccf652a7668bfc12f40564028fedb424c16a02b07c77389bc09ca7c99b2699ef6c618781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009484742695e6bcb724be665f54057bf3949b1a08903f3a3c6360872710c27ff7d6ee2736f9c154e2087b5d5307dc81400000000000000000000000000000000097a41ce90c310ed70558d79e379a41e805db80e49e36b458073fd9ab9fabd620e7a80e08bac98f1cd48a3c8a9cb1eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001493e9cd2d1937f0f724e1f0d4cd180d661d701df181d5252e35dd468d72a47c2808e045cca1d84e0f9b20d6d2a41385000000000000000000000000000000000ac4071f471f8142906a95a065fb908e0531b21d47bec4009e2f308b7e3638663b3decaec27f4d58dc17d5a5d13db1981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd99775bb18975346d696106d8ae2e6be2d3f664af885ba7675dd0cf62294787b98f58013584075f139ccd344d76d950000000000000000000000000000000017aa5bfe3053b23691929db4e3a0350609777da28759c72ea7d76a8d47d09bc7941b58227e4010781ff3e708bd2951df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086a76cb30502c0a86b47ca8f546cd4a9630800725aff1c63a58adeabf03830e98cb0854b939398c5977d734eed1235d0000000000000000000000000000000000102fbf5c964a54b56a05fa6177d8a701774b0eb0dbdef1cd1dd21e8232e862788a674b9fc3101a32cf4724e5c57fb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb3c4383dd0b1a2c66102250ae38cd50921eb23c185b05fdef7dd8d70b03344bac1f2974c3e591dd30d8981c6478ea000000000000000000000000000000000d7012cd35633f815bf367422525dc8ff0ebec6d4d2d3daf53a5c7c4e3bc0c8bdd8157091a04454d978501c47330adad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000223d4e0c500c6087448e4124cd655f9ff8f216aee42f04de64a5f5f94acccc5998a1164b3e50940e8511d95917e958d000000000000000000000000000000000e01d2a2e271db6b445f2f2d3e7998da54fe873f8497fc5c6b42373482978975d133203362b36cb102c0c9cebe5baec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a190ed9c3d8cd5df3a5cb38ccc33061d9ff5d6f711d8047346a3e15f9157d0be394dd01af4a927c7a63fd40430befe00000000000000000000000000000000162de5c3ec84c0b6b4ba15572926d1128f7c459951a84f6611fd27d60af4e5a6341173247e7a67452b67b3f2cbbcd2de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeb43ca9202276f4cf9ddf9937c5c35912c74fcc80144d7331c0f329d857e6fbf7d8cee2ba39a0e43bb19f296eefa330000000000000000000000000000000016b8fbadd675d0484493e5ab3d56acd658bd46b2494a89818ec288368d09559e403aefb06e87877691ae864c556255b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011312304535eef7d614060b81f0d0db188b8036c01bac69d740f9bd50f4610f76b7854f18dddb520ba966fb9afcc94ff000000000000000000000000000000000bc00fa8fbb4b03457869b7b220924a6a1a796093925e11715b0475a5fc95f6cd8271ce92661ea96e0ba2a9ba3cc92611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a276f6f1c32675c8a22fdda5378f7ed99878f9e7a6e4a21a3b077922c5e7428a322535b3864a93c3512a7f958961ef0000000000000000000000000000000015970cdcede3da7d64d784f77195eec0ab25adae3afc6f44eddb21e781938e596a65081103e2ea27de747807b9392d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c4e55f80b849143f11d10ea6a19182a1fbbd3f3dcef3f905c6b38897621729dc42ed9c43818c1499f4616f51490afa000000000000000000000000000000000766d3c11696678d21c48b4a136800e089e2b85339512c468f37288c2b992c3629a9236f032f745745a0354f117abdf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000998d6584973cbf2b4028cb92616f6fb38cf8ef3996d6e43f95ef557958aa207d092c87f9b7d28db4143e0af72d6c6000000000000000000000000000000000077c6d80a5299969f6d523dbea1e98d38a47ae1a11896bae5f03d5257b0bba68b46dc36557f778495f5b3c3933f790de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc2867e5850aa55d572a33356944b998f0316610f3f04aa764dc716f412c533c849bad50576f723bff7b3f758581e31000000000000000000000000000000001600f0c50deaa317171fac835a1562d011f494caa0daa8a77fd222fd0665e0e4c70e6256ac663f2cdb0590de1547438a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c6e53a6dde124ac85fd512c4f116287e1ee3f4ff34ef5f7aa906b2b471a2ada490d32f6180ae0734465e854ff6c72f000000000000000000000000000000000888a64140f58a64d17c5456d3356a708507733d9029dec489cbf0ba4f9b3f5b1767cc177b4d8ffa327bd7f5f14f95191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6e54e6ab6243e3f7dbaea2f498b25d8d244003d27967891ca276dca6e74459dc11d192db19059daa4259f1386eff900000000000000000000000000000000180274a77406918e1c5a45fa2ba911bdb54d7dc2ee1d7708618004a9f1160afe2e53c0317393d60bbe61fbe8ae0927f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000817ff207ee37999d86144551e6dd4f1fed5df35bf74d167ddc235c3b2b95564e9d7ecd28cf21efe03b34551d26602630000000000000000000000000000000005483c5ae723d85cad4ca753d7fe43e168f2eae4330feea04f63829dd94fd938bd04978757010114584d54c48c3d1d0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7591146cf8cf47f60d456665c39a05a6a3ec2f524711d5a13afcfdd42f5b2793404c3862af760bec0ebb3120d8d41b000000000000000000000000000000000aa5f0f4ed79d9f4334670e1ea471ed2f451791ace43ad2d7cd93e2481198c029b117df9a38dff43af78077da130e7ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000685de9120b79495547fb080d0be29ebdc22b17357162d3e0ca48efb0c6431710e3a2c38d828621b59afebae551e812d000000000000000000000000000000000a7f9cad5fbf615df06c521e0796f40dfbc3b44c1533e1d1120a0c5b15404ced4b9fbeea73085f47a1b8d6c7df760b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bf02c93f402a62d9d0eabc6c6312a5d1fbe623cd9a1d4b46626d43038f60a35ca60189a5da783ba331bc0ff54ba7ff000000000000000000000000000000000f86cdbd10dc3e6df368cb356b12a359bd08107477cee517a853fd6048685f9afedded341e12fd5b6cce414763550d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025a1f5418d61dee3762e5077ffdabfa9b7cbdd7c5827c919eb21f11168f4114ab53b1d4384940ab2eda9c1ab82b690700000000000000000000000000000000041d010b3e4d02ce759a010151be38ff3b859920ec44307acd3cf3009d21c216d4c37cca1c0646c99c25b8f394ed2f881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006edb9e75c581b1bc96d45dff4970a63c4c0bd41d1b4c64e3f6a4425eb07375b007fc9612720145b8897bc75e84809410000000000000000000000000000000001c4008e7bad938ae5f68d31d92e9e375ed57af6f1436500cd8ad5423bc92704962660e469d7a4f3982cc3703556c46f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca0dd2b5ea16f5f5a7866d9b401539bed950f94e7aa1174ef6cffa908aaab8759e911af03ba6204b5344352b0c193710000000000000000000000000000000012616f913948aa5ed02fcf8695f52d521960f1e0cb8591eb433d92107da694f0a04e0aae6e454c0d7020032b5ab2a5271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001174a60a3edfcb5e8b5e3186933bb6ddef4824867a04213852c5356218b4c1f7d726b3f3327cef1cba96d77e9f8476150000000000000000000000000000000012f67a54c1da7682d8d2c1f4d60d9ac2bc7a000410b7b690b037079acc6b4479b4fc8e2812f84b93242808d2bc08cea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a927935f97915e29442593382e8dcf998edee6dc609919de5284490e3d7df162144029b8cfe047c72a87b221fdf050600000000000000000000000000000000124e08edfcbafbbc93d8971d2c472770a116b4ebacac4e945d86b71e16bbbdb0132f79fb7f6c382561931785390cfbb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c69e897a15d4f9a9784cb8499838196e288f778fdaa457b3579ba0e2d8baacbd2a0b2667aca7afa6d1ed682533ff040000000000000000000000000000000006822aac2411ec055ced53dd23cbe1378fc92667afd2807e0a082fb4aff985b669e554cf6b655b078c0825c894660e241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078a372be72701f54e582949ebe73afa1a82a04f6effc85a57778cfcc782d3ff18ddaef402bb80aadc1c0d99a721bcbf00000000000000000000000000000000049b1a25fa6e8e601afccd0b8c35f9d79db58c735a04159197cec6a8a02107a7e0229c0dafc492548a1fd75236eca75b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9be4a858ec5d7e9f4b92572462764c0f10b8397cabba130ae8e56561e43b02359dc3ea8edd3c6a3afbba76053c06d400000000000000000000000000000000134189ef2d71caaf586582578b4d8dae20cd6200da08f0f5b9481f7f0e791ee8425757c09eed2408d5d3c8105c8310451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae0e9620f54cf764b92b2cd22e8c5d10b81713c2725dfb894e5950557d20de601c4ff6756bb5cc3d699e3d9b85792bf000000000000000000000000000000000c1b6a7816620cedeb8139904edffeba7b64d095e070c3e7edf4d186fdc1cc76c47ba52fad82f1e71e9f12db26fe49fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ed9b17499b541e03ed812fb1e4b7a2fc15bc5b4039a0d63c7305b246ef5b6cf1b1e209bdc9224584b6eb744a83809f0000000000000000000000000000000012a0d5232352a17eb8ce8058d363248d31285c0509b517f62f3bc108467552a01b16bc9d5494c0c5377567f7a665b6cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176ac42ed79fcc6815cec1924432922c22fe9f139f03e1723cf7cca901bd8e969db53abc9eb8a8c1ab066e67793d19e10000000000000000000000000000000016deeaab18548d983eb86b8cf5cc505da6e10ff5df8b50a9e271d008ac501365c6b2d676884a80980c4166920adb08971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044631185d7e9f98365c23fd3d3f47d2451bac728d15d8b3682c2824aa2175ef2429050e9e28ebbd15f9765a3cb5f87c0000000000000000000000000000000019cb56e21071d2b790872427cadfddb4bb277c6101c8b078632fc287b942343ddf38d2b37517d8815d9e74464490485d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63726c19bf7d491af70391e09d46332a4aae678705b2adfb59e385c5cb0da27c2ee72d9df2dc52fa2a99485f0e09c100000000000000000000000000000000030da4dd6963929f022345d4e71fe820d34c6c0afdfac4382d7d6f94439747371a6286dc444c048a09a847af91c1e7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c3da40a3ea8aca870a0b23b1f36205b7b617e5deab0549b781ecaa1433bd9ffb9260a80f210d6274eed78fd68804e00000000000000000000000000000000012581febaabd7e366db2cf94384031bf9648de37dee83693f8e9af60cff77cfc47ab5afcac8b1841dbcf95d148b90e2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e629602f9593a5097e7a6e87bd8849d48d7535490749f83d2b31723174ac2d177c8b192942ac9981d4b1d4fcaa30840000000000000000000000000000000003a7cbd60929d98293bdb3f80e0dd1be44249bd96ace544c8657c7d19a006b63180aeb8eff392dfa3f1cc648edb0f4111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc1d7474720cd58e21bd298e22ca44b913738bf8466ef968f8d1bbf69a6b2075d40d880efc343d16fe1580b4a0185a80000000000000000000000000000000002f329395affc28a66be2f03a8e5bfb9ba7b1a3b6b2153eb91aeb09ad039b3a3805d0ec8b85d75a521da20007cdd5d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c947a6c6efd37b7ad92bd27b2362cc78d9ed19308945e32670ed02282ee586af30d6219a73847911bc0c5535daf1db8000000000000000000000000000000000340e074b08e57bc8ce48ac1a55cf525c4f5bd47a0ab4f521751b6d0c1bab207df57e54d33a333b2b0ad2a736fa12a281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c126926259c3e13d7d2d146daaa0bfce87b5100710a0d694411ce87a0690f1b2c1eee5ac92895f01198189e71bbd1000000000000000000000000000000000ce520d7deaf014dc9cec02499a872e6a1bfb02b342e0b50989d51d09715fbaeb5d805305c5732bd317104d81dfeb77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093e1631ae401bb528f1985febb8dfd56360475aa6d842a6a8f8315b2da0f6b0446c9da7bcdf9f952a964e70f0d9c36e0000000000000000000000000000000014d4d5217bc3f841e1ef1fa36b64700bdf89b1ce011315e14ef70aa7cd5f9f72cd4b6e089bcbb1db5bfb99c3c54d90d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b16129bcc4be85f9c15320c70dbadf395b98de5712b9215e7b16e9d78936c112a462384ef53030a4935249cd4d4d7d000000000000000000000000000000001427211eb2c65bef186f7fad027ff7bee0bfb47b06b54c1b8a6cb6e38d5d7068c60cffc7cc1f5465d80eabf0fc6a796b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017867abd83eddc1e282c55ed3f32b58d1f85eeba59d12acce51ad5d3a07794b129a0ed52038353fe8a22804997e682ed0000000000000000000000000000000007031030f83f95e52a64a364095a1bde19c0fe1a7a55912941413e0628748f3dad2889f6b518b91b85eb5df1797d6b891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012287fbeb7e65b170cc1eb62d7f0b617965623ac2e2e7a25e10609a6bec0ca6118679d451e6d42ad3078ac576e39674d0000000000000000000000000000000008a11d1ba3d3e030d529e7053ebfaba155a4723123697c1a6eede20264008d7f79892a147b69cef34847228d81c3bd1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c91c7c6a81650d1c3eaadf1034fdd3d364cbc5780a99194623d05903d906bacceec091bd142d0a986f2e4dd25710ddc0000000000000000000000000000000001a5e45ef9b2ab62e39035ae9c262d79edf840cbdb149616f15c2f57647eab6cebf6946ed4159f95b12e5dfa6b04312c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c71c4663fdc5c06dcf0938869f6e33bd489613ec89bf26e8280496b23a703890bcfb510ccd2ff3f7e9cd00d7ea8e41000000000000000000000000000000000dbba6ee6d63b1c2b8ef08499ef24424612a49a5ec72148c7bf8ef0bf020cec6650cc21420b9a0a8e88a52e57b0bc5a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dcef986e2fe959522337b62a90424b84fa806dda9253632bf87e20a03d507ec82e731ff36d3280ea3fd0fb258031b9000000000000000000000000000000000cc6b5d543f20d9f558006e97748b4bdea619263dba3e502ab17d71a836b42d6de24e3ac4d3e45c8a6977e5ed7d2ba501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9b2046e275597cb45d9d780d77a1107bbe64995ebdb125ef6fbc05b2dfdf776f93ce2691cb41a35c943164b23b5690000000000000000000000000000000011d0f56496878b6280996e2436440782c71665d33bafb3d826040aefcca2c2d065b9fe46c44f93474275fac02071496d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018eabb273bf7f868bcc52623cfc480fe794a8a39fa8f3b4d86e8185ad0cf13af669d2a852686159beaa4c9a8fffb6ba000000000000000000000000000000000d3896701ce5354f859e07b5a8273b34bc5f3d8c17390ad2509db8241dd7898528ec5c2c915497daf046ae8644fa13471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000735fe9c2c56a75e904904763faf30def907228bfda9f68eca8084369e4e4151c3563085c52ad454921e8e686e91edf7000000000000000000000000000000000c595df91cae71b38345fd0e0554c0dbfc0470737edeeea613c11486155d7f422054d024f8d34adc33866666d9545ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ccb57a30b0463e0395c38c756d6790a00c9b02087a76c4a21c5f819262d2eef026cff7d6e7a43b2c8e0c7e73015ce800000000000000000000000000000000114602f60b9d0bff0134a9d5c6c8e18365364207f838e0caaf41b070f5a9c3f50bd2b930314cbe9dc75069986e6307f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea2e01cfe19b683728793d86113391ba236b3f5f8a26d1a87be7c262fcb4591d8fe0c79c0bd03c0f0c3f596c70880a80000000000000000000000000000000003992bd04e9b5967a289f6c7673ff209018aa1ed2188b5da54c5a1ff2ae5e856112dda2d456404cc866fdb92dd8c49c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9099f8ca2dabfcde480a87d922a9e5e374241177e90f82d55be0cfa1fa18b69050c9c38f8d8bed3e491946937c46f90000000000000000000000000000000018a2b379c6bdc34b8c9864e686a8e16a0222db7f8e1f68638a627dc00c09ce0d01ee8e4eda121b1a043d8f3a5372aeac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de89f14e969e81c34b349e82c25b34753438d3de9f49dc551fe542eb50dba907fcc9f8941be452206f23ebbbd640f08000000000000000000000000000000000af63a1ec01796ae3775dd6cd8937293bad0588faa690e707d26706bff4540867ad80fdf04a89f7dbb9c2184134e9e5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c64b803d391a4c6457b55894be653be668b4dd3094231d36c08d393c9e3b575e59000170f4b7147d6a337392606ac2000000000000000000000000000000000639fa72b9a1cff78fdd3145945e8a6eeeac9e369119d366d1014f8e5839536278f8521f82029136dc4dcefe827596c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3e303652331c8e196ca0ab7df3aef8637cb77209d145140b575d81f945cbedefabafe6e89c897caa5b4d5ea4b8256b0000000000000000000000000000000015c592e43e21f6866a3e1b1f76b9279dbf33b4bc48c1e38d051e18c15aedc4e892f926cc62f3d763567db9010ee6a2341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ffb1efb5f6283a1d0e1ec4c396076fe0f6e36706a2ebce5a14b2994c46bb5f398f15a793d11c4228b0f32fb1fbd021000000000000000000000000000000001733609f21f78debe7c3d26185fa6eb4db7424b6dc79b3805e3ae5f377c087a9420bf1f93382fc165d3cad7fe158c0961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069bdac1b77d25211546e9b2693c851d66ead7307cd12724a22721c9860d7005e42f4ee44cd52edb107836489a2965bc000000000000000000000000000000000ab790d61fd02299d0f06926b95a4a5c26326a28012fcb141d24a4c114e9276eab60084418e95184314d324d15b284401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000210b6dfccab23641922ac03f1cd1773391a9d12cddc8f14cd1f5a172b6206f7885784e2af99df9323714d6ff3f4483d0000000000000000000000000000000009b76b46a35ae4090e0ee2b5c631bbfd815efb5caf95707eabfaa35299819509c4803e371dbc1c3df633903efac630fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2cc0c0022c9f49ed62d6e20ea3f4f0d62b58cc089d08a7835d3fa3aa945860d6cbb1267558f8e43cc08caa5970f36300000000000000000000000000000000086ced2dc798345e61546d7af83d735d3f9b3475211e458acbdf673198c555967726e87ae425fabff13eef7bf3fc8fc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173a6e14c6901cda808d0d439251518b7bbdae9d88e67d695d793e396574b76f48606a61b14930aa3ffe89a2d96bf6bf000000000000000000000000000000001253eedc01cacea5735ee0acf74039f72a3f7003e30fb1b57ee1374f22f4bacdc53f24668fe39c6fd3dd3b2094bf0df81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018eea4f3a33f6ddb1a3db17728d069af3c8b57fc8fe8f8a6af75a2d0492a4bdcd629a02a7341376c94a49549abed25bb000000000000000000000000000000000c8e685b16b55efc3a5d7612cb61600d660bf6c61922678621822642a6472797607289f0b49ba2362f34e31e298f71281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73ad0d82fa06a1589ef7d1e2c8113a3c046acb403d34638ade0ed070d5a70488df9cc7cd3f01172a88b1975216d3430000000000000000000000000000000008a0a0743e7cb4a32897c9bab96f09b201d38cdfbdd2cb8ef738cbe34ba54dc1fe7be8b5d9a95187705780455bbaf1fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141a3b4a5fee89cbad259aab46a1c0569a1a0a553692e877e73418eed9294a968d15ffcdbee6bc54dcdbc71f9a9b794f00000000000000000000000000000000080f3e1db0af9ae7e7d426fc5dcdcfafa708cf83f454feed320c1f9ead4f2c380a98ef09198153d88397b6fb5e937d851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e321b654e27c5434e499573fa0b0319409b6d24b9273d0d01e82f946c7736bf4c919bfbcf84f4d74c8d3a04eb800ce7000000000000000000000000000000000d6ef2dfaeaa917770bdbbcfe57446bccb1023721797ecad6cb74a87f1c2697e3697510ddae7a8911bbccb33efbe65811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000766aa5fb6457a99413aee1d2ff3d3953d3cdfedbd6d567097e6dee2a53609c7a3d1e1f5f4cf4244e3e7fd9c906736bf0000000000000000000000000000000015a7ee941771fd3fe9d41bb1ebfa8a3fc0024e04260356f69da48859760c7a386624f43987727c14b58874a97e4737011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000574218c71dae1b8d06256eaf8179dc57aca34ba1a9d19bdcc6d3ed6eda6492908c68233b358cc821e46c8bae5e77d360000000000000000000000000000000019566eb176cbcc5182772f8af4e7ed060f4fe426f1708c8f1dd85fe220f29c853f99de0ce316ee0bceedf80d3a15d4ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d539129ae955a56f57335eeba423c810da23cef10e0a0529fcec04af7722085b83e3801b139e7222d593110c24daf36000000000000000000000000000000001051d25895a515621f047cd12d09f34fb4c617c01f169af27e90645ffd02a6f355964f02498ff336f0aadb3d7fc1b41c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cddb68e6dc68216dd18a139b9784b9eee498aa1c7e346d6600a2f31267a498142268354c02e5b29eed8db583dc4154000000000000000000000000000000001239d4b2cefe83747c11a0e8cdaf091d0a09e0065b97decaba824fd77c6f84d4c24d0cb919d2343d3486929d6b4e5df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2b9d9eae13ff4c0f27ee18819e7537b59d6bd78aceae13729bcd9270f9204163a45f389210be3643ca8ff0fa7ebcb0000000000000000000000000000000010f0d79e1d49b9c7fed7f7ff5b2cbfaf9b4b7e98cea3571083f6afdcb23393212d0b195a7e9eaf2a873d33dbff3d1a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ce6acdc8248bcb148039ca8cc08780795cc493b29ec43820b02cb73c6775ccda6b9ffd4c6cb90c962f33d9956a679300000000000000000000000000000000088f86cfaca7d37e36553bcb6cc7d9bf75867f24056c48cba84715f7134d3144c2bd6c5007a8d0e5399ebdf2d25399e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166ca0a341e5acb98b70a0e0663737cdf67621802cc8386d7d03164c60a7e4c984f84be1c0db4279dd80df84bd56f599000000000000000000000000000000000130927b883391f40d4f605ffad512d5a172b9ed7b638ccddaa73f33ee3a9e83780003336b88e3d43cd098acbb7cd3711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000800be9cb28730a625f8d1483603de5fa31cb3cc3a6bfc3a4a2f9b08bf204e2af8fb31218911b73584016844c2420d39000000000000000000000000000000000c41d1d3d8a814e0aec48684a5d8d51d394960992cdddf43971c4e1781ed690af8e40b253c6bd8f9d8dadbfb8dd38ee41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d3e726846a89d38d2a9d4fd934843da13075e70bb0e9d2c19a0574b224de3701abeba58fb6f28e95968c1f86d4e5c6000000000000000000000000000000000dd8adef15b50a576901f312179dfee26fbc2203b9f4f6f71996fddb13f9ef82c87775f16c41826b72dba701a84827b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000959ec02b5e5335a0d9d981aa87c9693cc0e545d3229cf43e070963a2744468eef7e28d34e732b8c7f5ad4af943e3206000000000000000000000000000000001772729f3ef9e07c4ddf99e17f122fd3f0aa398356cb3561ad962b2ab6d31bde2617a7b7e78ee11ad59f2c4388f23cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072e87cc0deee35949607c0a9bd0ee755a201eac9875e78c13f34c6e5f0a2e33890743e8e1451a03bed440436ec573690000000000000000000000000000000013c8590094d369fc3512273dc36556998fba9b203d1d2110be7564589cc1bd19a5940c93aa187e980cb8050a9867736e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da0ff079992e8a32739a60928cbeab7afad84047b173cd5bedc9a0285f0d1d2b404b135f11d68de35ca80c57fb360460000000000000000000000000000000015e61e00421b13f4f91973c308d9158f3c0d2442f00d3576acf9e42b26568d47f5aab442ca94dffcd136778cf3af13061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059d8ff3785a22535e251269fa41602e6b8f6a4dec9187fe15743f841a60481b25ad448084ee4a15eca2dbdfdf6acce600000000000000000000000000000000157b7e92bafe3203a317ee63fa8cf3607414c797e63c41a155a8698399a5e4f1024af4f53f7a74286804f88d478961241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019736c39d7edcdab5df31725155aed52bf90f51e4d7ff5f931a68246a74f1fb24d287243fe3a9148a291e23a68bbc464000000000000000000000000000000000207f3ae9e20a5a9790443fcd503bff1ed947df4624bffebb4eaa1268e1565a96c7d29d1f22c2f654dffb68463a63e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad47bab9eb5b8d9093c249ff7e825ca054778524c1356d9ed13f6fde88de012aa120719b14685dc870c6c3adbc2189f000000000000000000000000000000000f0116a3cd42c55a1c208dd5056e32b91183dc19cb09b6b91aff749604dcc5470ba741edbe677df8c39fc2cabc1cd5a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b25b85607df57827358670fa948ded04020d889ff094533a2e490098ecffd6a6aeda10145557c20e6950d338f7df2600000000000000000000000000000000049eee265b0c90a7db6688df2a1312c1fae3de19437d0314877d81693fb72c0394cc0e1419a77f3f9e5a96aeff1cd3421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b7daf6ddff1fcf4c8f81111a1ab5be32f7d5618e9c347b29794fb899b5fc2fa6e693fd545f08f4b04483598876a0d2000000000000000000000000000000000ba1cf2f8c76e90d5420d2bc5468a65a6f518b906208c54af9a2a27eba945f650368d1446befdbab2958ab918fb95a9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78cc0560c92bd97cf8d8a40b84caa626864317b970118a13f5516c8ea5dd2b75b15104de6d93e693e8e2b889dfa4ae000000000000000000000000000000000d44c529592561cc6e3056d4fd2d8d0e678559c2eea1bb66caaeed70833dc59faa4fed40ccbbae40dc518e477168e0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013496b9d2ed109e211c04a70d9f3b50d71767087bdc8362641b555685a5671db1427e31d5c7d68690fd89d9e07ac51a800000000000000000000000000000000166a9acd043cf2dc69d9d416994105d81d357ffe06059d514cbf25d30b2a0729e65ef0061846f131144f8ececae4e8d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181802859d2b59d94dd8b4b1005c474ad8ec25931fef394fcdf35c8355d5c619ef63ae77cbddb52188a0f8b7dda81a4d000000000000000000000000000000000c52da301d030c2ace3f9e6fbc4731992f6cd20a21f006f4e7795b5fb01e2041084d84a108606b4c202a06135ffeb22b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165efdeca3e7321bf5624f84096b952237594564ebc7d07b146cad0249a03563ac269854b584208806c16ab4e7a0d478000000000000000000000000000000000ad08578ee635820578fc23e628d9f556602410ac69f9f444e47ad8eab3c1930b25fbaefdae214ec1e73ccc15f467f511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea3f94377b7db8cdc9c07a6242e46d37df61b3f93a83c4d7153a214c1b1ccbd37e7b15676da27ab2821e45405ca37b8000000000000000000000000000000001639cfb8fd5a199bc39be5992890e249ff0efb686f91843690dd66c27ee3f9edcbee26957b1a69bcca501a91ff7706461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062960c583ead123b4923f780332deb7ba23754ed858fe67686ecba37dc4a449bc234ae37cf90790bc58af88893ef2780000000000000000000000000000000007ecf5d84483887d6389bbf1a326a9581721d8c77badd692055eb5e3840e331ddbcead90efdcee4991437e3ee541d8a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e12d3d046565f3b6d5036082ba586f6e1d648e0fff76e3c5e8b2e348234f9e3d60e15a86c27e04997812e6d50bfa040000000000000000000000000000000009c44527d13880c1f15f2c961c3508d0d5bd598f345c96a10de41e7c4f44dffcacb702750cdca15d5aeef2ae449611531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001606f0f3d050fa67a69812591c236cb6a3ee0fe0e5947e92176554b8b495921c638740fd397522a88a8a768e64a4af19000000000000000000000000000000001227c2abe891712f4a542638b9214e0b662c151c359e95fcec56e7d284adb7ef622bd33c4afaf74eaf575c2e90d139f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c4b9fabfb4fd9728d7030bad50b637fa0c1ba25592c3398bddbc28ab5c05c17cba0759c693ae3ea0ff35b5f1e9a217000000000000000000000000000000000bb1393d0bd54135053797faf8389dcfdd2a03002cb8e8db1fcaaf0eb58a831292cbf12cdcc53b903657cca771c67f291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b85adef5e911bd7e261ab581341c7f5c44aca9a9b13b7fe15530b5dbd068f2b23fe3f1c03deb7f0ecbee5c4908abb56000000000000000000000000000000000cb84c4ee07b745ca74bb4cef45517864074a8a0f674fa56b76b1f90d0b26a5ad2c966c55ad4df043b7d2094eb6e2aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001694ca1c011322e914a531d250390cc6b7a64a54741503ff4dcd65ef2b35b13969836d48b489ec296c888e09c2d1c523000000000000000000000000000000001977c69eee7e6a8ac94166acc5e0a6cb3d09b8e83eea1c62fde07ca5eb21365f7a1386a2c4b2dde5144b4ca820b47f121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170c67bd68b52f63e92dca20cf11bd5c36efde65c73d1910526c686f620aa7f9803ae8aafcd0a2fcba8b1b843c461d6e000000000000000000000000000000000dc54dd4c1f667b2aa723f5cc89e2b2a4f3bbe20d1523784b2aa69307223974e267250d901a1a737795bcf01b49916761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3702f67163b324914a469ec5ae6ef073022613fd8e19618489df4f4c3b2c338a834950ea8054a2397448f62ec7c9f20000000000000000000000000000000012f2eff7425ab8baebe628b97e5391ae19bb163440886c0c192864218953e1ee22e586029cef53bfd44dd43b00a184791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acec7e6492ef1d2dd309d011a8c011f0d4a137e9c859d066e490cd2d5d07e4d6074cb36187ecc7ba43b6c8e11a6d6ec000000000000000000000000000000000521d6c2a4c8ea71dda1e67d2bd73b82df04d3651bb790dd412db04b9c716044f7aa3fffc137bb36e489a201c285c22f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010421799b261063e1a1bd13a1ecc5d7f76b0b46a5a15d0a6a85cf89764434c5526f9d2e34921e68a5df9419fc3d00c6d00000000000000000000000000000000049bf5795bc0437c4bc44e9c20e95a4fc22877932a7753386703f5cf7df049eb6d2b75797914d75bcea598362251aecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d232879afb5e6c03f64d055440447973d0e548ec4dcb0ed51121a45907e806607dd4c9ccfcf9f175cfea96dd149e91d0000000000000000000000000000000013db5533852c4656db4962319025fc4cefce662a34d0ccbfde635b3c53962a702c013e0d3bc3678eb6a261fefb5c81711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0691a1dd40b83b171dadb6dc2246601bdac2a2d9e0ec40e14e47ae673c4bfe461acc3c19db079030906241a1066d600000000000000000000000000000000009d82218ba2e0fa8a79acf70ead7ef4583fcfb2e7313e2285180927fdf48510ed44787f9276fb490ca1c16b0ee15b0021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e98868651f4ac5e573241eab717fc7d2aa54d2dbe297a8a41d676453092851f9f4bfab1e60f0e119479f14cf226199000000000000000000000000000000000b8e13e01a24dc52f259fc14cc5ca20f9d74aa93630d7728a2f458dd401ab2f33b52a60e6efd131b0d749eb3076154211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000463f32d6aeb56a8f8fc301fe574330810d97986915f81fcb44d14c511a916c0a86faec3c310ce15cc2faa55447e344900000000000000000000000000000000135e7b493d90c12d0c5d17824457a2ef58eb4710f3e0f02b422344f6549514404a06795332335b681b5c56cca6ac42ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140ee924a8f6a385bb311f0ec93809fcb2b1aba509c6beabcb05d7c1053fca0da389dbce79d20d807f34292b147ea96400000000000000000000000000000000077034530ca75083c490cd22c86d35c562e19773dd2eb3107a4fe7cbdac83161eaabb46c222298800b3b6a3cb9e984c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c12b54bbef6b2f664891fc51d4aacb4247e286b42273dca5860d72216b5208942d80bf3b3b28afced371394a547965d0000000000000000000000000000000006abe2a5f3b47223c52be7b27137f3ad4cc9064c871571b604ceada0c1d436079980b1500c6e4720bd18a4ef225bfab31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000916f8939af1b71cdf7b8befebeebe6dcefad363608c2cabeab097c75d1b5e273fae89e8af02f93fd9444cae0ac050c4000000000000000000000000000000000eddf90a131665ddcb25191154672f6beb0f7e8c786d741a10193a2f145b9646d91ed6b0133b330242d99b62bd006feb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671dbd9ca01b25370cf67f6d5a767fafe2cfd419338d3b8fdace000541cce4d33644f7bc48508855fff27955962cf7d0000000000000000000000000000000009f3586f44655fb07b47556a435ba9d60f610a11a0f8415a1d7cf55583189a967af4d9d0cc133cfd821a806ac5efd5e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a7aa75fdf91e406c329fe61452ea9b5e2cb0eb505348275bbee2c1cc5398da2c0f5fc7b59f810050d0dafce6c30c3400000000000000000000000000000000043837c433a512e09f2e7d46ee03118c9f843994862c9bc8b10cf9a9bb1da6de38f726316e4c586910d77376ec449e301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139b6b621f6b5a506ab1b8354dc2200308eeeb4f84f2d94ec18a2e6ea30a3b2dda92e82184f1965b553f21a960360be40000000000000000000000000000000017698a432577048872d902d33a4cec34804b78b24e5db4012a0240c3e1e21d5ecd2231c38674e8969a2e433bf07df9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225f58d444f2bfdf5a288a69733bd0ee96c554a70e337261a659b795794c545d67031ffaf5f506dbda9675781dbf6a4000000000000000000000000000000000a6a9582e3efca1974ecab412d4865566b1bdd24e191089fa45f40e21960074336bcd1d7225906a1cfc414ae4ab131fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010c8da7727a0f32584747a94475738cb0038fc102975b2b4aad40714f4024ed90c3b57557576ce0df744b15cf1ecf160000000000000000000000000000000004c41fc346d8454f0572105d6798882a84d5c8df45eda32e6d5a1373a2857e57afd5c80fcb16e07643f04940abe317c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014707fc1f89793524b30ce62c6709928ee2b60288fc6aad5ae37499a5b970deaf3bd00315991d15d6a7b8a0a0225e29c00000000000000000000000000000000186cb3282e7bd62f0a5807a4c4ffe407d287fa8b759f16bfca4451961fa2cb522f5f12e3bc531645ee681c2f57c5a9f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015906b92e0e2927273ab3eee783f6a4a924fedcfde0b16f7ec41faf0ecb13d06235ccea81ea8a6a5b6a5514e21093a670000000000000000000000000000000010be2dc06b55c1a1c7fca4e22cdd9729f59943c95dd2502886687986da40de3445c7f96d34ef6c9355e6ac456df1b1f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5a858bea3409c9bb0683ddfc0600d2db8b667f80a63e26d3730e12e677eeebe5f6b42fd3a3bcee45f8fd150ff646000000000000000000000000000000000014f73254badd7abae6784dce2ffe0462c8072605cd98e0c7a3f9aa78e5c99f846eede8e7dc4db8165463344e96537b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edc3ded52d30cd7d9519ba5f990efbfafdde06e51f552d6e0653b2a9c95845868cc5cb4eeb0356fdc74a9c4657656270000000000000000000000000000000018f0aef7f0e6c1083f58822fddea79fa72b7cdc9b736b948e97180d40f0aba7028801bb69003ec7b3e5b8547c3444e8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c36332c65b1508ab2580dd203e7cba30293d6faa722693447e40a312b2d59c6f94b15aa83ab59d929b45c3bb58e8d3000000000000000000000000000000001549cc875a163c1c03f5285b1383582958f937cbe1881615c5e501970c06092436794eaabd1e4352d77302c6fba5c8821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ea466365f39ad591abf5a151a43cf848173a6fa2a00ae7d6a537dd5b97c9fef62f1df820c897d9c77f3e7f9a727276000000000000000000000000000000000eacf3ad07d54eec65c300cfb66bf700c43d0cec11922fcad82e4f7e249de29e08d1dde9709269cc5e1301c188b291e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000247937f2c8bd3c1d6f7ba1b168d1e0a39ffec2ccffe400de3f113076116e885006af62aedad8747ddcb79e8d8a5cf1b000000000000000000000000000000001914103df2d6b2526d4bc604267281cb7a2260b447d51082431d880398c1bbcf2ed5c9463a5112064f63eef5df85d7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005381796a10e86bc6cd20ad90de53be27dbe025262ec7b4531001aaab2c65f03368eb89e5012d8f1de063cc65f7990c100000000000000000000000000000000012a546e0e18af28229ffd401dcbd6aac4c59b6979acf270b498f1e5793bc23c1a6bc1e2d0ad40a3e78ef4f4abe1da2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ee39430e44d3a9b27d35a71ae4df9c3693d59e019a970517f7f29f1a7a2204ac485f859cf544b3371be80cd7fee4ce0000000000000000000000000000000015ccff4228a2c8039a6b0ad3f2e867140ea810695ae5569b39d35205b5cbe66afadb72eb3e955ca4123aeb778388a49d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082898bbcf99b9a7cb5e5c36c83c821140494ed81477ab0c841f0aca2462170f13f191eed866460b2e0b0d6d6f4190070000000000000000000000000000000000e9e9261220d3a750221dfb52f49a97ac10371847a6057edd4ceb35b395b7f4bd321ab3f4ba174f19ab9a6b6f404ae61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001533fb5370050c488e5fa37ee750d3d72f6bc25119f93111f23ba4237a0bbb470fdf6fad2cde62deaf3242f8a7eb559e00000000000000000000000000000000113d5d632beb247c117666027d7fc5383e7d6793848c6b7009d62051f140ed84f6ae8f8323edfb9f789ee61be3d1fea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c65f8f669558acc176e1cda87ecc9e30c0ff4bdc0f974231ae9bf2942c8f1ec068db6d0656a2e071fd9e3df91f869f000000000000000000000000000000000c8b94cc801be6ddf9f984291c23e01152b8354133fb7b6a876c564b37f9dcc2c9964d09ff58a3966dec741dc6c4d1d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195521f1c8cc6489b1459bcb7bad5c5e7e63bc7085d7a9366def84dba07111a33b409c7ff29fe591c17b8b58d2f060cd000000000000000000000000000000000e7acffc461b874fae3cc5ec42545c18831be14229e7ba891b6457a484a8ea843fe4f66121c17d1cc2d8fca5af04c5491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ece4bcab5ffb439d5441a91bda095a45c1fc7aea97b7a5ba41fe03481dea9c366f39ad9192967123e04a1dde6ee59000000000000000000000000000000000ede071bb318f4d36e562bd3c38b7849a3bb59e3e06af55f77257ebc34a14547efb8a4788971553b0d62cbd7953d2db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dbc1750daac84f5359d5aa452293902238da269cb207c353ba8eae7cfdadb1a73e127e3bc5c7e038e74d70a1027982000000000000000000000000000000000ff13ef919373a6ab51dee4d523e8ca2cebf62f55de7196540867390c796b92ac45cbda716d0e6e49f70403fbfc1671f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ded8ef5bfc2bf0e4877ea2f485e6451c22504f473a64c2c1ef223a91b4b64cd4d744856a3ec0dea209791a7f72e4a5000000000000000000000000000000000bd4aa9bd580d7b9243ac324f5ca1317e209512779c64b2357635a581e7aa7e46ac09452df4dfe50475ffdb5f8e185731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028349cc8226cfddc4c4893e1fd2e21e65e7fd90dafefd73de447c138c3f3047788aa7ce70a9d8c667134559e3454787000000000000000000000000000000000a1938a7e55e54d4e4d1569ee92482dfca18070116edcfb0cb1d347ff827d6316a50e2ce81ff6d078cdd282ba2d1221f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000005b8829e7072e0b9d7bc195f665bcdfa4e0206b21c8a6084ba98293398267a62829a7366c9fdffc96b4f647b36b40d00000000000000000000000000000000086229ce7ea618ab851aed9b39fc51bc286102255d32e9c1275ffba916945d2bf3b3dfccd7b08e180ca567e22143fb341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fdec5f605990fff4f24b9dc91920de637d2d1a6c1510923c1996dc6a07d255cb70e961c6c29453604aca7240f5b3230000000000000000000000000000000013757a0d6d54db50d7e525d3b9ad4efc09209c8ca3f7e713270ac05a6588d11a916638aab61fa89464c2097b800310bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061f2d89204e10b09c7de7bca0f1be0f0cc3036e9d719499e5936d1aca56b7282a0e7777139824b22c6305fa4bfde5e10000000000000000000000000000000018919fe861a16aa91eedfe659f89a6dbcdc18d72278906c357e2d2865c45ecd54fdd7978d6b5b65c901cc22e6aa286021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080b843e9b740e246f616d2022a6eaf615e1f2f728450a61f27e5977a5570e18f5bc1a758221356c681f352fc6105c61000000000000000000000000000000000493fb5fea3613d37dca1a060d4399f19be49807a32bc22843ac6ff3cd88db9c2e532ed51d2c98c4bd344248405c262e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8a0e714748df41fd3bfe287ba2151fe0054fee9a21adb9817b31c096b85132f5601c0d891dc46ea1037c65ac64dca90000000000000000000000000000000005045be4fb6798807d73bddc998e576ee364ac0a2ab5df7aea019fdf15d413fe7853ccbc576f875df66bd06fe1e7bb6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d3e4fb948a2cfd0c563ed78d1062688bb13f168b895f8b6e5c6aeeee7e0fb7dad0a5ddd36fb06614ac295fe0ae7fa2000000000000000000000000000000000617903758b9173c8072593a1606844d20af9791f8deb4233d16f8ae629f8d0662bd4ff416a89a4e284fcb265b855a7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000070f0ff6a9a64b2ae86e04945aca036d3b806752660e9eb15982902181231b6f9d224f405eb06a5720c195d361e88840000000000000000000000000000000001070edbe9fd7b565abf56c2907909391bcc462fcc37ff6ba6c77ec54c942564542d85fd636459a02806beed71675e491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007de78240d34f266caec2813479e960946c79a6110a4d12d2cac25f0ba2ca9184412b687b77e4f2dcd0a296223eac3dc000000000000000000000000000000000c33a72db7cd6dd2b7361164a2082d507ade7e902db73005bc7e2372a7b7449644703f55ea44ed25095ea81f3908fa4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebd0502f8e159c02ed8c58b1e7ed8d5665384ec530f5e1fd9c9771e2d1415294204b6c3c043e195040435692a7000210000000000000000000000000000000003a09086062eeb6f702b938f0b70c657fac579673544f9e63c3e04286dd7b71bac4ff5fd457e984c1617c5742d46a8871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006025ad59b7df3aa441710c18f93bbd772fd68597fb8682ccb5ca7dd04db58d0babe0960d61122da138ab3a2f579fd43000000000000000000000000000000000ca4a8e10c89fb58835c4338cf93730e0c430a3a2272113a5db93fe0c974bb752ddfc02ec73f70013999cceeda675e7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b6db9577aae205f97e25d829dd20a2cc39cb4d18156532b1f227c3d17e5b15a0eee570f558bc4a8ebfdec4ba6fbe890000000000000000000000000000000011fe3da32f887a845050e57cbdc05d23e4072173347fc5e9db6f2b937e7a96e525183afdde465df2d6d1e56f82bf2cd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062199ed495ffffb1c0f39a93c5ad6cbb1e8c6d49f168ff6b1e270d59db6dda48776214f36bc1b438e104caacc06cd70000000000000000000000000000000000a55e4e83234c75950015bc8dd867c79e0a12eabf4311cff26ced23ecf717ee3c1c3317c1f1004348c4fe19df0defc2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000227ffd06cbd6820614adcb7abfb9d553a4ebe02c5ba616878e36e478bd8e04e125604bc731e6154ce6be59efe31caac00000000000000000000000000000000071d7b9710bd55c0e615e4056f8478546e1f6a906c2a8fa20a8049e884bdcb31dee4369292815aa3f7b3339e39dbd53e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db5add9c50d3ca73627d8ee12f677c14c6cc610d612b2283edbf0bae8bd5513ce98da888831cdef2eac40b38cd54ff5000000000000000000000000000000000d7ee423fd35f9eaeb6f457759ffe4b59e54f76e8e0845df45d63ae607f7257cc6fb99117b3a752532bc04613e1e367f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f1253ec214376ae4904edcc365ad68143e3e0ccca4a03dfb34ea75f05763d8bd586539155e0fbeac9c41c0efc646b50000000000000000000000000000000002d27760d9a95155be78f890f2a6b4cd6b4273045cda3554a0927d01641fdf70962e0b54080a4989d8e6e5f28c58aaef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e57fe695c3cdefea4f98a16dda72691866839f4d9dc9fbb7d729eece71e6611edd23148d99092b2deba874224a362a00000000000000000000000000000000030f69f0f03dc7249d8e64206489756ff6c695fc21fe37b34590f3d9a9d2e85157d60c98bf2442ba22da7a6e075cdf911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f927f8e5e4cbc7a1081069fb3eb9b2841ba715b90218830a6a92c13085ed5977bf1b54fb0224ec94a62759dbfc694a0000000000000000000000000000000012677b732b3c95f68f1f29dd67c57e4f6f2d3a9a08f1c3d3194a4880d19d2863f7cc174301b298157581fc6ad9ae65c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c026dc37abf582d157bcd145d13ab4b27250f51af8aff1bb9860501eee54115f398bc6c157473e700556c8148ac0e0000000000000000000000000000000012219bd48ff9bee87d83cef54feb8dc0bc0208035218b1241f8e807dfa7a0694557575ec62baa40d8e32eac004e360df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee2d4e702869a7339ecf264e3b4e0d6f8060d1a0370f2bce559fce684bf66b705b10d3ca0e650d52dcd0dad704aa93a000000000000000000000000000000000d6c07088b7e7f1a0b85706870c343f2c5607f6b4a68086fbf9fadf7c5d2c494a0a18b97affdd7a7308c32f506ed84161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad3ab2b4362dc45d557cd857acf4a9331afac38f70336328f745a4934c26b909b7d5c726354c6b8a65e7d8368ed9f7c00000000000000000000000000000000044c6b8d2b35c3ec853d1a9ae34430059bb82a950bf4c6661e8e86223f3375ab683efd2c49115a2dbc7d985847f021921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140135b586bd76e16457083bdc076db558e9b8ef5062d4edddfc0f90de9628bad3738bbc513b2816eedbdd91ad5b42500000000000000000000000000000000054a4e9528e853cb38dd0a2a932b4a3e48ae4d05b5c7cd6a0467fc5f7fb57d1387f04ce2900fdeb62acc7703786edd6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d380ddced173c842d0e8a16464688d47ad39453ae463a38490186b2db09c1ca6242bc22f1bc1f8b11d4974bd07fb41000000000000000000000000000000000c7f9a83fbdc43f4d513ba8f033fbd836d7ac7d9ae22d91b293ca0fc5375398812b1fafc353c5ec98540b4b1c5ea89821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd113f951cc41637a8ae8fe9eb6b229aa65168d94e06883b08f8def4eae28c99323018f09fa28d3ed48300e8b793733000000000000000000000000000000000e432967713b25a6c3e8742c970d7cbc7407975860ad57b06e96453fe8e29d1ce93375a719792def537545f9542c7a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019463df93f9766d245c154be2fca15afdd264e515f8bbaf6a9aaef68e7dc187022ec5da5bdefadbfad57e35ce6c08e24000000000000000000000000000000000a91d47326c6e9c353bdeb0b4acd7db3c9a6b26f125ef4355dfbbf5300bbde537323cba5734f8de5ece51d967fe28fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5d8c0aa6f45eac59793a44b2ec74c39d854350117f64ada3670d1ec6250089450d09cf629e10c9865919b2dd3bde1a000000000000000000000000000000000c824993b76f7e964a8008a0f2996263a2aeeae7ff1cb6429f5ef082abfd3f19a450aa31af186d8f0a296a8719c8040c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001845c391fd08576749f9c8fc70542d5297fb0a514f51043311afc4ea016513e1a57b1ac4f297d7fa305b1768e9ee7fbc0000000000000000000000000000000014137b54d0893b47c1b5143f1da6771e3da0a09f1d1a8ab574fe48b4288885b454ebce4e5d7dfe6d1df0fe71e2b7d44e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f23089b8c117d1f7f135e4c5b6cfd77be1dbec0097f7ebb25bab498780eb70e2c7d5d5e5150cc948f0a19425368fab00000000000000000000000000000000114da06fd9ef52ee44cf3a4e5f5f63b72cdbd4fe9966fb978b231d681c1255c8a99df3b26fb273850c84c4e750ec7fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a49dc3573bb9f327c243099fb2cdcbf42f850479d0e3f4ccb2c913ed9435088a639bf100ef3fc6bbe73092a782d035000000000000000000000000000000000490a254a354d2dc461172bcea93cb51bdcbf633eddc0afbacdabc72ae4f68246ca062a43418a6557f0689bc7b9186d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185cd5665aedca80432224a30bfcb78422b0a50c444ba039b762a5999b2a112112229fc8adaf91cb52ee0091930f455b00000000000000000000000000000000077d7bf47b53617292fd2c909a3d35643bfefffd6593e5fa9b76aee416c6ec12bc1642a2584dc58a363c6d9fc03731111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019193a7130e849b48eb0d72e4f901181d640d79fa2bc1fac75de6bf535a13e094258fc61be9440689266c383d1fbded8000000000000000000000000000000000e178f92c190e3bd1e0821e5f63ea0e9bbcbcfb9c387c2753d69fb4d9516d19036d9302e93d06364fb138da3024b2cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5fd1e985dacbf4b0308b64abad7a4bad38677adbbb443ac32377665f47137f776b4982dbd183ad33fffdf7471b09a60000000000000000000000000000000012db89b6aea7069827799ed4de2021e23488bdc6d933c656eeaa9bd7b7514271303638ca6a0c5ee9ff549884fa51653f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b889e8d01993f0358c3e1a00af6228839b77d011400d36955b8756ea522324d03d4ebc881b95fa5b2f03b442bbfa8a000000000000000000000000000000001778990e3f7e6f36dc75ee88c1279d7cd281540bc4ba26f80de98ab0c1c8a2ec19b490b23d16a423e2d7edc2c58647b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4ef6361f2fd6f42895c13bb4c2c90ab997952215c8b322ac485a4ae8ea9d899eb79b145efc6f63ca1a55e3d459d810000000000000000000000000000000016c6843d3465bf05e37046ae0eb4866438a03ef1477210f151cfb0cc575c386cdce75bcd8a17289bd367704f3c5673911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e3b7e9941e731eeba60fe75665ae6a6df1b23bb22667568d3d420f55e51fe50535f15b8fa2b1d609fdcd9291a5f00000000000000000000000000000000000c75ee60ac0f75fbbc8e9b79ab9e65dc2703bfe83060264f1d63ff62b195de69e2726ffb23f0202f279c73f484aec0721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c004198acab8bab037aa60d43ea250218bef6215e88b42599ccd231914b2cc17a29808fc77d6b252bf5bc5d60471bb0000000000000000000000000000000011b96b416ba8c7d755cac3b86304e7c0561fa731caab700c0e343c173e6d0b2f6254c42a5d8a0e4792278112a8a87aa91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000083a1109468bd5e64a468f222bb4ead4601d0b945b78c1af687df288b86b210f200f686807a0e434737cdfe32f05b35000000000000000000000000000000001728d02edb94e55d591ae9f4164c9986743059874e551894ae2119b0e518ac8cecdc7cb9ca1a35e67eb1cab1f40f1a891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001149136a42a39611bbd9645df50de68daced9269dfc24ec8ce5ca3b5b7419ff8b8262cd4e3b0f92308585097c3aa7741000000000000000000000000000000000d45bcabec8890c376499ace9d55bceaf3fcbae6b65e87eaebe6cff106cfc803392b01069e5923e5e888e1d4e7bd1aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a802e2e3bfeb79bfaa298d4197f78b02536c5d9cb9a6f3caee9ed1583368cef9c27238d11aa18f22b62d5860419f0070000000000000000000000000000000017ee28c37adb417311e4044d42ce6d02bfdc9d647141c1361c5a9726ebabee5bbf546f8db56d805b5239b4491750d1781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd4d586a3382571dc7cf473b7ea6eedee5a8eb1762ebd0cc606ccc123b17265689b679e9b4feafe69ad7af462fced4000000000000000000000000000000000aac13ab1c36e1b27c09e6e763510873707f17b244e8696c9781d9141bb75801a078e2c84e54f5aa93ba99437df660911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600775281216279d33b07bed40344db56026041abb49f8e97899f33f02ff91c0645ff436adb6525a0a76b79eb1cfd0200000000000000000000000000000000141399b7250bb51fd54f6a1627f265f7dea3dd90d944722f86f51124fd9de019fe2ba770d2d64438986313bd17631b401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1d0088e2060d2bb36af9d528b8333d500b8d972e803f179551e9d80aa4ad34f964e7053c28df3031f9b07d56f7c8f60000000000000000000000000000000017213d0645431f4c3f5bb3a081541c5f5ac6a986aaa5df096b8c5911d541fe6994a617654536e5bbac7ea41f27bae8271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf24e7f89a9351000931121519767dd525f9c94ecaf11e35b626d858f5f9c16d6022b246a1363f94bc13fd6b45c5e60000000000000000000000000000000003e04214287bd4532668ff82e2cd2041d57f8d672d08f5aeaef447b50e2149722516c586dfaa6ff49488ae6b40b875051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9259aa5488052421e3d08f2c26ae1db4397459f30e769302c1f6c1699b7f20df53bd7e42563f02614db8b469cb28270000000000000000000000000000000015d7fee47feb93ca119e2131efceda451e3c1971b0c6bd62d7d6e2e25df39505ff746a7734f39c7a3f4fdee4e466b7481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018697783c243da0b0a1576a07bce66740371fccaf37027406e0d51fb7bff7156a0771fcfc267861ecd8b489dba8bdac2000000000000000000000000000000000ea43a8f73d65a30ba1d9591075ee86e2397d167a9b377d4c7d85cb1d7505913f1c5c92be53401c182d133252045a4f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000328fc303165f9ae76ca63fe8acf9f9d29d98853ae2f6611a82c83b0a8ffb8184f462cab1fcdcd2e4aace69a62a55fc00000000000000000000000000000000011b84fc9f5db0e4bd64ec4c50e54bde6377536ae497b294de044e06ca9f7e8c1b3c01a68d32fd38650a53cf6de9476481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000157f45f4acea6ddf56574e911b007b97a8764b9abac0e7f72c149b5522e162bfde1e2a51825cc70faf5fbc8fe18d2a3000000000000000000000000000000000ab77e7852136a9df30e59b0160f9ecca2b86e906f7717db2c772200a8cf4b31e7f4bc866a5db4455de961f289269bfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011045b55a82fd56fdacb0e0e8311a8a7eb41cf6db5cafdc2f84ca2ee78fa23bbae5c3e83cd542aff17de1a7ccc929e47000000000000000000000000000000000b3f6dc2e047005d0248eabc12bb5d8f055346acec2186973370db58a4eeaaa6681bb34d881c02cd166a2ef422c45b371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017199fde141217bb533d621b397b3e9ef1cd0366af049b58f72dc7cfaf7d1edfbaa199ccb173d50e747b27a1c72d035b0000000000000000000000000000000009d0853a74814f3991961d59585e90f4ae4a1be143dd8b8e1ef4f972c606d25e8f8786a800a31f83ee97d21ac0c587791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039311487024a056937fe1516d2f9d4c10feb431085202f049d3b5108e59abf626caca43be32be1fcc83c0e7229604dd000000000000000000000000000000000681075d589c0ecab84bc0727b1d604ffd170e991ef39100c17c5276ff0fa082350f430b0362688d7b90e9a9171ee3e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000802f41832842ad75f0965d15bb0cfa08ceb6cabf0f2749c6166e294a8742da426250cf06a35e47b9f59447dc1537d1c00000000000000000000000000000000076a075da305c8f1acf0b9cb611d253928cb7da90d255146d8243a88fb0a072e901b312cd0ad886da7600c482dfb3e2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfc28db3c4f92586d3738350c98948bea45d80f1d4f0e300f5ca7ee675dc534de1e06ef0fc1121ad3c20b3d5ccc36890000000000000000000000000000000001649bbff40f63e637d34956f68f61d9f38a427836d549efe0ea08657b1a417cb45e312fe844378abaa052ffd69a8d3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b944d1c6f3504d8f4315274d450308c533a2bfd513a3a0ba617277c3498784386f703e84b264a41dc2e0af4211b9530000000000000000000000000000000015829372d1acb8ff8909b6f757ce61ab660dc0a16f63788a7486fa204cf19ee51e4fa95c72dc1cc2ddc867ee45a76bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000273005b31ddbbeeb9d3d2adb2dcc56bf404b26d6509692351674370b664461be47ddd0c69886158e677b99f574b1600000000000000000000000000000000001816657c659db7fd665202b44d99d4797a6bd4f319f8a49f1d146ae2385b1742715711e89150b62803f3c0b2455e52e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148965001e27318d85d826c1598507b6aabfe7f2e805c71a9ae4ec90ff8e1f3265b9c4b2536c5e147d1ebf9d0706cb6100000000000000000000000000000000157d1cc99e8aba2d5573407654cc20df9864855b38e28d0294e07c4fe0cc310168dc7372200e02dc6982a70e174e599b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a66ac4e0e3fb93e28fe7444124b87f6c0b90eba4e3776c0c5b7930af603b387228d103197bc156880bbadbd2cf55570000000000000000000000000000000001e855e172a4cd25553d1cadc2f07fd77e5f2246a53fbe8ef0fb2d0da0ea0e3348c0669c2d3158d25d8185fa5cff20641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019703d6050df5137a8710133c5c71a53291b249f6a0451a192bcc754b95d381f99e5002dd01a6d4938d862f4fbef4925000000000000000000000000000000001507757065f4ea16eab1b523b4ccc16d3a153c9086124659ab4731df6d49bd31bbaa6acbbbd49e742038a35c070754231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107065e821f77b06d7c0c70f036daeb81be64f90e128ab4bffb1d49b21fb5bca523b12b2122a48bedd3844dfd41d31eb00000000000000000000000000000000191b6c33eedbd8bc950c5160fa4560a0b174926d486335caad5f89426c6a7278a94a30527191a5954ce7bc914df575331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019db69c003d015489baced0eefc0003d8e121cc9ba7f9476b6fd8e3e5acccf31569c4f396a41918b3d3236f2d08e8b86000000000000000000000000000000001499783826b5782e09def40554dbca40697c017931d1ecdd8bff5c842fb354c8a4740952a19fa6594b9c8cbe26ab75b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fe7379f752ec5f32801d8efb06a2c83b9f37adeb1d9bb6584236c9c13eb52e820ace40ddf2fd908f0c7a9a778de26600000000000000000000000000000000105afa7ae1c9c215091615fdd2cc577875bb543bbccb24b28b056f2c58be381c608033013e39ebe0375d50505e947ebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a61669016f3fa47fe1f8fe1cf01e76783401f2b53098fce585e303fe922360a3ada0c5e3631c08ba8b321ecda1f5440000000000000000000000000000000006b8d35e9355e4a9c9c204e317df1f4ea66672f13ecfeb7c98468a1a3508c60b71275631081be367ab590d4fa384b43e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001088ec4bb2c1d03d523fd95997b9ac0c89b2dc01db6fe89c27c055b01bc4c8c5dd1e217264bbc4f7cbd99e9dec700dcc0000000000000000000000000000000010b64e3d64d030cffbea26e2a90455635924066f83d0ad071019adabae7c7db1a34f9fda1a3960599af9adf20bbac16f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def07cd0454a6fcfb4d6eb9b84925656ab0859ae1a18c7829c003feba025e29f36912835f73b1e7d448613c53f1936e000000000000000000000000000000000e08f24295c28c656beebc76320cc9e17329ec8e5ed7f1dea11ef52b0189e783fa028fc5350f8f8e98dd03080cdde2371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107f442f86a16eb837fd6ec54060e56b2bb8fc3bf0730c55d53cf3dd21a8a1a2c29150b9df2a7945014b7e9e9d5de6ef00000000000000000000000000000000008072523f6ac3fff24f7b3a26a1a1f9f56ed6b1d2227e36f8f0e47997cfd3b1f2264a7a34e6b1fd166984619f2c5b791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5b4bc4958f117f9a82efa6d0de128cf00b28bd01e18b539cc4ebd4ae846678207b716395eca5f7a1b5e6ce5bf00a9800000000000000000000000000000000092c009226b57054d07ac20611e0e795428deef6a9eb5cd190af1c5806bc0e5fb2e7c0b0910adf78a96bc495f995164f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f895bad8698089b7a6e732e745de1ec6cf6fd34b24b67febfeb1e156986ac6e76e20a06cb1bc57ff0aaa55643c80650000000000000000000000000000000005bb615d1f7af74f2e9ecefc9f3c3602376cc1a1c13f1d6525bba6caebd8fe205c229ea432da6aa41697c753a8ab1c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6a801dfe8e3f3f35d9e52f107a0ff07d1d06abef9ced1b5f8c2d3180430ea7e07c0e84ec203de75e7b6c8f1fb2d950000000000000000000000000000000001efa936a8166b3cdc82caccd2ad89aa6363be9c3937a06cdc4fcfef92db97ae63af365045f7af7c7fa28fadd924baa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b2f952f3526839cc25c13a619b14e1dbfbb8bb56d31bfea291703998212dc233f61f52b2e77af723ecdb8cd922ad3100000000000000000000000000000000089cd07a5f8e28b4512f633beeff51cf3b900ffb5d66f57a65e674bb21c867202924d3e59687aa4498b2588fc0e7f3c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f8b04ee4b13b02859ed0111a9d28a6441a0d03a4b3367edf24ece5799e9496460313dae1057df3d2dc5860a0905ac00000000000000000000000000000000017ca4f4d3f59e2ed9c93ce5c970194c1d0168a5eb65a3ee95fd89ae098561ed33c3d2bc196c49d150490768f951f1a941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de3b06110793ddad32685ad95bda7c8dc380903b713e17e913c306bf9304714997e013a4282078798ee8e7a5184ea16000000000000000000000000000000000a8f0f8ece294b52270975068aabe8819a99fb2881660caa7c9bedf1871f381fab2721ed2192af1956739bd1340631e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd71c5c6177727c36eb1851f63a6b1a571484e7b34e1e94e1437754b1afee91c5cbfd0c9794d078191ab8ef7fa4685b000000000000000000000000000000001681b2b3602cdbe883cb09784a88a3c7b38301f5226e4132f537c800577712897745472d8d423675a478b56c7f2d361d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d78d5a5304918eb0a90fe0056b8a43be41f45d4241eec751824dc5f498e909524b3437c385eb6c05a8d03b49c664a400000000000000000000000000000000058b0484ea1556fd39d3f8af968b47d98962d889d88e975c590ebe4ceeff927ab2d538cbd24f53571980a5750cb698d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142b168baf55b1a98ed743f52c29d8ea9abd4c20474da3b8339c37acb7ff1fc3d747f9a236c55c3c2d603fc9a9194c8600000000000000000000000000000000181822c82bb0ba31b573ee2cdbea5824648da065c8500260844b914c7e5afed60496f87e30e08bc74195f4046172d08d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189061e7aa566adc7b9ce4c66ab3d038fc9036d7e0582dcc31b9e06f4d89c814bd3b98a854c4f2ac8a36b29c38ae658300000000000000000000000000000000143e826f208a9addd96ddcf81499b37a0c08bdf72859eb34271fdfab952b8ae6f1e1fd5185704b3c509d17347e6c56bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba10d850e242aea79c52e11aee963fac7df643148c90f831ba8183d96187188b40c8a0a337c8eb70c62e0428d42d42d000000000000000000000000000000000ca5687eeb89d15536c74f2252d7c6a33a1ce9f06b34dddf3907d8af242d39a380f8e2cbc075a1ee6da54039f39a4e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001153a2f97e3a48eb55dfdefe4678f3a556965a01e8b504905a2734c2ec95ee577c3d663af4d0de31aec77f568ae371390000000000000000000000000000000005a745a13d4cca838abdc83e921b55ea436e9346215ddc66d5bd98f960de3013101f5b7813ad04890ae2d1935b1d009d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140622b70d63ca6567285b714635f1b7b315d658717fa23041033de5b7f497524b46a0c8a71efe3e01be7f5c5094b6f2000000000000000000000000000000000ad63cba7e1b7ba072b0fe39e461c13aa292018f0403a605ab55ed4475d89d8abacd9a311997d02de19fa8bc95404e5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f362c15722df42bc54558e61f1bad262c6340393af4d826ac675d67f153c9b0c7b034e74b4b3d35d91754d4d46641320000000000000000000000000000000013c997f30539b144b241ab9edf61bd652ff86c5143c3e8c23795e0bb8fce2e6eb7af1cf1f46aa1d1de02016e6206410b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a56e88b7eb5b1bab38f72365177c051370d5e4a79dfd10e3c81b4b2cca5c12b17825bd804a13beed086dd060add2e95000000000000000000000000000000000a9d344e63d91ef6f5abb87e195cf6a1c8b071365986b148b905d975f843cdd0ed0f181a4137f21da69d7fb8367c52681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c0e77243dd7fde8646c435f35d039faade5c922fc1f22e3c6d52abe2ef34e3201cbfa7268c0d5d1cb757272967f4550000000000000000000000000000000011aa246bd618465903f369c8083516b63f2cb91e6bd0628c287cf14c032d7721a518b1abae6cc8799841c4e6b680b48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8c27d8cc181a6fa4227e3cfe913fa3390e90b385f145d72d7c0d8e5030fa4d3b2c32fb5bb079afbafac48ef0f51f9d0000000000000000000000000000000016abb9b7138a58f4ddcb25209c21aaa9c04aa5e4878d3df59173d9e5c4b06362e76278a1d474e64003d21d8c48e4b4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a02d28f145755f9a964920221b80a1f93fca15111a5d15eeab939328b36be417fda08d0b31890000fb5e2ee4bbac5690000000000000000000000000000000019a9f697c7d9b9df50d456a165ffdb5c9fd5cb403f368e2178f85c0b7ad18474846885709c90065bce3e2a731cd4fe241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7c299a19eeeaaf9bdaeffebecd52fc715374e3e06fd76c6ba7a86c32834d6fb2a294b65757678809af371bebe2469c000000000000000000000000000000000945f1116e0d382514035fbded3aad76ebde6bfbd1c689ec16a908f9c7383e066c77b503f1df7f77ff57ec5291952ed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000387cae57c2ff8970be249947f0f321ee9382b4c5421edcf0040d0b84122fbab90e4edb12131fa884781052e38a4bace0000000000000000000000000000000005cf5dfbec4fbf64ca7458203dfe3f7938620f52161bd333d3e371f767766891a784ee5a198b0f623bada0d6359e368a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a2896bbbcfe4a44eebb7d27e0444be2bc19d5d0deeb3f58bf93989672e30497792b4b2c734df7a642ab82b5020f2e30000000000000000000000000000000017e0013e66e14eec9beeb1ed1114d802ef352563d1aadb27aa5a4fda8cf57dedf0a896b91b6802d7df44931f80f334d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076a8c7e7042b56f1952637870f28d6cfe8ccae2a9a3fdc05d862b4015dd89ebf8e18e130abaf4c9d90b249c6fcba4d2000000000000000000000000000000000c3ee99cfc5df084c6c9c185709b35d282a016028a96d990ff9c6394045a9bb54cc5e8291977c0955fb839faa46ec2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016825cae084a9708acf2ca8ba31fe7c81cca8ecffa5fd335d58d1ebb791ed08978cdac4b21f11fde05819f40da6538d40000000000000000000000000000000000acff77119356e1e31add7e742a9662b8fe864f77543e75eb389bee2a53cb22699b9ac8f1ebd0775a9585d161194d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ff4b295d3b274bf0b43dcc4a1e1a6fb5e2a32638c5d8aeebf00a2d807c9fef92342b0060c6954d57c0cd0172ef89e500000000000000000000000000000000069c52e3fb24a0548755d09d7712cdd16569993d06f8c02bb6cc7a69606ce524c3845d8bf2c68d00afaeef0fe3b2ac131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbeeec6b11e1db3880f59b69af90796b96c803f9a3d339f859f7bfa389fad8d6774b818b6ad3dfdfb7d60cbb4d46ede0000000000000000000000000000000013badc3b037ada51c279ba6462aa14933ab865a975848acfbc664a491f55221d254aaf4115d18cb91649ee6789ba51b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fddecd797ecfd389742c3a70ab5b7b8c272a53d4fd076bfbbf4f01bcddcb7b7bae4524d47934695eca8bba7f611d6020000000000000000000000000000000007911ee36e8467090160c9289e293e137ac45b1fbcc7b13bec24aa266878d25d84bb9919293dfa33b737ec2ce2fd67811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4580008d4457a50dc2799794ed8d3f652a03babe1ee03cfc61651abb0abb2469dbe67204bfd62b4690033a22758f0a000000000000000000000000000000000d3ec120eb3e7ce30b9c3be9f2b7cd0408ca9c7f672896cc7767f16370614ac26d6127f397f700e0408e52d6447aac931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd2eae0ad1b14f9ee2451ecfa168f049297998db9cad05bd05f6279c06c48ee56b9107033e97e766467907194f6b6180000000000000000000000000000000014a7561c8c41e5fd934e9c051ec362573f1244b984a59577d5932db98b9f1b9d5f4a7531a5a281f53e48eb1dd8332f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135febf45e5b1f977f83383aabf0bad6b3243816e91b7785fe79ac43413c48d62aea4514c9b217a5bc52764097d8052200000000000000000000000000000000085a8f381efe12dc72ba08d6f298cbfc74766d09f377272ea6c0aa81fb54f4178faa5ef3aab4f73995053503b633f5001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ba3b23460658870f55e20df729abbfa7410e9a718df11a272ec77afdecb36449096fb301abf4b4c56239dd84c0b6030000000000000000000000000000000016f52d1482520146d408e231d7554db2703ef004125d051b7f9f8c335feeb17cb23a9d8c8276a696599419762b8714411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003414d561a2ade9c0e0eea9dc9dd7b584dec5a5f1c4ff956911343d1c47531dd392be7851aa9aa0dab3558fd47389dd0000000000000000000000000000000000c331f446002cd45a9a1bf96777bbce604b30addba2638f7a2d69e55f2095f2a8af8a8b3d543bf4cefded8b93027a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a46e3def610d6b372d7de510f2d1f6296ca365d68b1540debc2a7037e4f235b800fa1293c70207a52d4d23a0fd708d6000000000000000000000000000000000ac48c5f3b863337866027be775e5e00bcaddf9b5b9ef42e5c1a1a9dab896dddc162214924f183de3705767c1e34e06a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081b36aece4cd564342568ff31c468dbe9c48cb7714e643a74693b991c193544a5d8a4f05786cd7d5a585b5d5f24298300000000000000000000000000000000037f26dbfea1097b9b275c8516bed034cfb4c237aeeda641e53505bdd9b04656299e82979f0a77273e69b540b860eed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000806059c68dcabc5797de1530f0d72c1ad18f7869f5cd8f47e38877db62efbe968a87e0a8d7de77221fc79adae44e828000000000000000000000000000000000dad2a7f9e010bb6c9aad197ac3b79a2202dc07958d98a7507eff6928abb0b5d98481ddd44d71c7272214d79243a50f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8af193b20f9252af2ae9e46431984c142f4d4b59334ff5375e12f051353c360f083b448aab74df008764b8a5f2ca990000000000000000000000000000000013f2f7d29e3e7e5fff6ddf87725428a52931f2d5b0f706ccc16e412f9dd1d18b08865d27c82b3fb77d59e66a5fff9b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fbfc512811452bfa5134feb157e1daccdc856fbf7f6fc087a4439070a7ae2e461251892ac42e9be088e22024c0ce4d0000000000000000000000000000000010c3bc0deb8ef8b3772fe67ce99ac8f817acf9a7a5a8ceb8cf4d5ec0f897fdd314217151dcb5cba775637ea267d604441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad443118ff0358ea2e888ea09591120e8092a636740dccf3298603435a01ae8f29f21a3a22bf37dac9be25e7cfeaea0000000000000000000000000000000013b128b4489c2f200a9b027ffb156624d58a8ce933de34452a3443a00e4c59e170f5a52f617c9f5aeb6b27ffaeac00d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016589a97d60871e3af0cc6b78e9af3b9e11fb7eb1304602e2abaaa21255dc46b3848ce5567a73d313442364b422c55d90000000000000000000000000000000008c9bbb1289d6a9f02f9565acf566a33ae8ad2f4f70294fc2bdda55271baf90c5f21044cf129e84c9ea7fbeb21f0977a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000502b99435a32aaede99ad07a686fe1ad87bb4612b19a12857e7fb39523b1311b40ca06b4e5a4fcf6b870dd594301ab500000000000000000000000000000000035ebd546a4b8af6c3f49f85324d1953423a5a5b1bad5ca7cecb20166e9e9914868c2f47dbc10a44f92478bcd02faca01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005318679728f55f687be5b014f7bc1d1ac5fc50cc32db48d2779fe399ffa567e7551b01a9ae04545b9e7f0a55badd3dd0000000000000000000000000000000016b1a2848218aff2365ac45860fb6f6254fcd0b614f716e0bb8b3a9346e295f7fbfcd9b8f714c60c95c75e65323c3f7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000700abfc713714dc05c5a5d8e637e0ce7f8fce3da4e82c0bce0b6f6da4c9fe0e5985121c97e9db882e1fe9b51029a1440000000000000000000000000000000011a62c7d8ae4022fe6470c5a9b6481bc0b11e982bb98ca94c8aed70865200e614a97eaba3fedc55def5ce606b5c556531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b8d2b8d6147cbf8065f5f03412ea35bb57f42da3a83d415799bc2202b2bfd1ba2651288a4179f767251f6ca870bb7c0000000000000000000000000000000008b430f8a0f68b44b8cc4f471cb810769ed8d5212771d21b1deda18b6d0dde2c53d1f6767fed2cd4f9830dd121514fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043537de26759fe5db48e9409322dac5776a8c15d10c9e6c8a55ebcfd303f44e86c98169555529f41648ead20ce9ae8e0000000000000000000000000000000007907bc4ea9d494289343f874469534cbee027fd4160d04f4a6eae64d0a915a7cfc5135b925575a46b5d13f3e15b26f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3fe8ec6e7a8004624e13b04a8c16ca1e0916f9ac873e6e51850a70dbc5a023daeac1372acecaea83253580d68361a60000000000000000000000000000000010aaf3745e8911ea30b6882857c6c0b35c61b5bb038f672e1a87b3cbbcd855976b1ef6fd464955eb34346ddd1b2bba581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017600f733356bc9706efb991a25cb2bef20066b3788711ce4c6c24e73df777c570b04570afaf8e56d8ab7dc8ed8ff5fd000000000000000000000000000000001609168a8362e4cf811c359dee4516ca53d900c57859eb917f6ac6f649583c87dfaa73613417df47de08ab901ba29d471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e709c467ff813e4c0a9877f6fa3e316d03d802095fd101422bcbaa1d94fb3fead5aa94e41a2fb4ad45345d16e4126d00000000000000000000000000000000022815363aee1a1f7018332745c21f17217c3a0439089386b755d280361e940fb4d12c1707527316d966dd654ccfeec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112d296b561ece75d4c573988ae2fc84ab93f9ef15a5c2509844d69800bfba5d4008627bc284477db0b498e565c62cf000000000000000000000000000000000129dc7e339599c8881d77e1e08e6f4e0e414568eb1884a0a96da5074d9bf3096035ca5317ba6d307680e7508136ae19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001566799ca2f853e31b9e6a7cbab7ab588898ecdb8ed6ef1a783e34b3081b97df311c8e650e6f7fcc877890e7e3975b98000000000000000000000000000000000977a96e2f2813bf13e11e34013302211cd744a7fa95c902a444d50c6de222899121e923ac44d916b657fc33643f50551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ab76ce14aeacd3e3c8e4714931e7aa541b66459281224c7d1f0be3b5507e43195b67ca5efecf7999ae23ad57ee8c230000000000000000000000000000000017fb79964ed12152a7d5c19699c376667e326964faeccc9d0f9dfe5c7d2c93922cccf456c4dd9acd715cf78453563f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c252ae4be7c12b96caee7846036ea5e553414c7dd40a8a15ffb7d891039cf311de0252589958e6817def64ca399d9600000000000000000000000000000000141a68089a4a0cfbaed1c0dc66b8f59eb60f8e9a28576b7974945fc2ceac175a6efc7227a5461094a65417e8aac08d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eccd14464654c11199a1be24bcc5bf894f171d7ccfa6a9c4e07f0083d259ea6f3afe0809492e8a4487618ec2be516f60000000000000000000000000000000010a1e5fb02f2e59df4228bd6dd45f6f8e5435ec0363bcddae18147d09a62acc6fc93e84b7b004480ce929a8fbda1cd3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bf53d730774f6655e4af4fc81ea8b4202ef83c2e96042bb4498c978aeba16d8571ebfe705aed4a05593fc38979958f0000000000000000000000000000000013d9148e85a836fa158292055322a131f9919fdd02820b2b3af5472bd8167425d8e2ca5f64fd3ea5eb6d635996a453e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e544c26fe452362a6b409e83255314487166caaf12ecbdeee12d3e711bf744df543e1280b1c80ef4952ee38a9b7f59b0000000000000000000000000000000011e71b3de8768a6dafe30b614f97246217ce612d8fffaa32048b92155b13cf03ac26ae264d241fa16692a7aeb6ac79061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b6a386fb5d31fb654cc97895955212a470e7680124fa96a085fc69165c59bbf083f1020d339a353e573edbfbdcb1f0000000000000000000000000000000015e2932de1d0af3358001db59e4777a5913f4407b966030918e1d9f6ba5f38944ef90b3fc97d89af40afbaedb65155c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d9f530bba156f08b6885f8c96a3322b4b4e31e53711c17dbba29714e2401fcd2ff0ed994a0244f10ac1d75e704b08d00000000000000000000000000000000069ee19cd9d4825f7e441ceac3e791a8d3500c1678fa60fc025fd436adbbcd607ccb26b6e60c338d2ccb675da93a930d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c376c6d36629a22a4e022762da90499966aee49465d6fff77058af122b6602a362b2ee85827b05b5be00d7d03b75b980000000000000000000000000000000013d339bb2ea01c60e0a782050c7a4f998ef64fc452c1a45b1f1845b922b5e5380510b170af6907d47360d86ad469ab151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025e51c15ca087a6daeac26c08b4bbc4effb0813f8a23dce1959d783406642f176f2aa05b8774d401aff0d4cb87de1190000000000000000000000000000000017d07b1a006e3406d8c748c4f262a27ce440490525506caf8c1c9d09308057f0aecfcbc286ee60b725401b083cd0442b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f51265fbf77902058d52898dd332800c64e3243bae8a51ef933ece0357a21b565bbd2534fdb497d854bfd4e492c42000000000000000000000000000000000dd4516540e4a95e5eb05a10faddc47884eb7cbb881862c19dcd9936a4936901df881ad6fa029ab31d547b6e9f3dba431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f613e07c299424a59c969ec6f0ac4a914376a82fcb0f8873509347d5267cd2200c68d4838aa7866fa9ce440a412bdc000000000000000000000000000000001045215c25fa66c1d7a7947d81dbb998debbc7a5f2463377ef11c0eadb0e0249c8d1f52ce627b9d1b16675d05f47bb611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012932f29c9a672a080941ae2eeccf8f50f3155f01cd7977ba786f7125840ab9605b771793590735ab41fc1dd10babc65000000000000000000000000000000000e4a67aceb6e0331e6381e2ce6f69a91326302eba69b92c7432e53ba9d6230f99794be8eaa1220b272a3dedbeac0c1911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000867f3f29eb9aa8c1480137b86d1670a112d5d0c6f0d7baa3674a5e93a6fa47ce5eb604ef1eca90aefaf884f52b4c768000000000000000000000000000000000b23b1d055214e42749a51c3a94a75f5689a285d2a9fe981de27c565d4dfd59d8abb7e6c5868dad15c3cce822e1d21591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a556e55102935f073d0a907dfaafe15b59e6137deb822efe0ea5f7456413cdb4237da60808797cbea35acb696bf0a900000000000000000000000000000000129a5a2f446a56a22e162dbfdfa6e4da706ffee8ea937e1f6c8860bc6321bc4058c17d242c6578dd86c99c1456fc08201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e010f12ed38258be199faa4fd4083e88692a4bc14fcdf8b5ca5d330d6d4dd9490835cf8f6345c985eb2fd66f90f6f6a000000000000000000000000000000000d1e63a8bab7fb5feeb7cdc196aacbedab5a860dba9512dea39fe4cb62fc7440bb4e72ea9c2899132be49504f15845421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001452fe7d1b1e70a8ceb89698a18b1546998a28c2790c93bc9aebbbfafa4891f7f4b04ea3eb17f336fe25461022d28b8500000000000000000000000000000000190e2e9d90461337db4729445eebfc4b7888089cc9c09aadee260ddc0003ef34bc43eb2a364c7b0db3a163c750eef0bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de991b461c0908cbebf767e2361ca517477dfb9b0b83d81ab8758b0fe0293d6bdd3fcb2036fab71f4eb17654690101b000000000000000000000000000000000dd5aed5f49abb2892412696cd554ecd022d88aeb2f9c5fd27d39a8da0bf0e92637e7311314b9ed71bb9e7ff4a43cf1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b613ee71629dc2be82d0dee6e732124511cbb47c82f6e9b35fdbc5a00eb7bc5f39cea21dc734b637f13a9d670ffe7720000000000000000000000000000000018fd299c4d7b6d2c836c2b63bf4056642366c5dc5a08f030b890be42e719dad78e335aa750c3f9d78ebe20b35683339b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044cce1474ef9b00c4f74da04023ce9cc40912ffbd045e82d5929fcff527649a59e575e5499f4ce25a0320d1d7d8df6300000000000000000000000000000000131a42eda492ada34f1ba06d23ccc10de7f1977da173390aed188e2bbaac27276ec4e9cffea9c0dcb4f21a0edeb9209a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011646ade271835ed5bd917996e8b6e1a7bec01366dbfd5806e85d143aa7e14cff10ccf6900a5c6ebdd95efc2f85f5d1b000000000000000000000000000000000274d989be7a88746970815e7258c971fe3d084833d85a0b79ea25b111fa595e2e90b87cedb3627576b4f3991bd0235e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112155b07a321d069c05c44e92f62418af8cda4bd2e2c52d8b5edca85119ec3b5e6f691c95a2ab004e9faab5c5f328fb0000000000000000000000000000000011dec9e358e92ab524b0ec19a973fc169390eb8a74e334b17d3e919131978fd3aab3dd32a9acb30b203c15c5684537f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001479513fc9af463b57cc1681f9a7e4f5dc8d6567dcb5d7f4de7d20ace90bba25c2fe3b1a9dff7c4fe0e5887b0f3ed74d00000000000000000000000000000000138c1da0d70dd97948667a555441ff769e3413c3065c9e1e9da64cfbd8b4ea64680554e8aa0523eb253549e1aee400061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001888584708b0090fe51bd6c8eac47c3d9fc348ddc83173d2e41daf1b7b638eb3d953855ea660ef9d73940348e83f98650000000000000000000000000000000006f20a4bebc30066e24a63bab73e3e6e2a2cdb0020e4ee2f0c25aa011c2758d192ee99f36bf4cb8feb3f861fd3c93d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fbf64763545eda91fc78330a727c4b9b04899b66361073f828dd246b7bc2bf8a5c91099c99909a0190c46f2a369a9500000000000000000000000000000000070c152ffdfe035a10cec9b5a06081120d3e221fad1755f9e53329480166a8f2a5715643bd234497b77db804a2206ff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb49275096c8b5944621fb55a5d8acc8aebce7ebd900eb5a9a27b8ca377b3760173fee9bbeb5fa390a5a27edbe7c4970000000000000000000000000000000017b3a5dc4bf166c3a7697d8578a72ca8fbdea4ea1c0d45835232c034326e6ad8e2cb1259a178d3dc6707ecd125bc3c9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fbc71d1f4c44289d1b9e5afa52f86e1433ca38dc131dfaab90e91681f94f17a4587d5e5d313d2a35a2163d2c7de5a9000000000000000000000000000000000662de989f6966a09c3d52e5af827aae4b15172e605f7047597ff2526f85adb7b45d5db1ab2b4c64d356ecfd33f470001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f52a9444b72217455c7040a3d4dd1e88309a5c29619d1d22b42d451bde46b9acc2223e686cd3a19771b659ca0779f63000000000000000000000000000000001242d773791293ad16261e5c7afd958310d7940cea97626e0c4c6a6ee1e6b7af59e8f6bfc22c19c872c62b7bf43cf7931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157867cc023c51f3e1b611f473d9508e46431d7e1550ad3cd4626ab236d4fd93e55662dd3362d5f308679aa9d532ed07000000000000000000000000000000000782ecce6533867ed47cd1e8575b0d119094bde65c6115e1c7adf152b2d0201675f7550e9fccdc2c42f8f3cbf91602151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bb8cf0162d1fe46da74a615bfb2942e3b7d290dc0db9fe38e1d2c9ff7c6def3372b7ed0fe02a476d0e1c04634d4b7b00000000000000000000000000000000078b9383b227117c6989679cc481c2f48108bfce795015f3a7e850a062cbb129f709f9f6f5665775886d6963f3b0321f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000742b95f1b93fbc3459744c831574a36afda214360af3d568e177f464d1ea26e05237645c400170dcd3d75e04210bd360000000000000000000000000000000018760e1f758cb4f35d456c03dac0054674bafd3492383668141735b0af82ab0350640d2e1aa5c815fa6cc4b08fd73fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7be586b2570c8a78be52c121900716ef0e894fbf05935881555b2719b8cbe73def5a0077ccc468f85c44dd6bb28ce4000000000000000000000000000000000851796cd697a3bc972bbe2b91cb0626ab3690783f56149779fb36c86771dded06eeee5740a85046e84e55be9b6fea0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c472b8dc6196676a1cf27f748b58fa4ddaa79bfc0cf5e2a06c28b568e8d2f78b37f41eed14f8a464a49424e1d3684cb00000000000000000000000000000000094a43da82268a2aa369308247535069a490b6dcb7a5245dacbe7bfb19bc186a4e83999f0cfa8047d7f70ddb7bd396dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fc5c0719fcfd056b25517398cbfe53e0cf96d910e4f6d502c9da027a06463443760aa3e76d266c1cc5be5585a042c200000000000000000000000000000000026bd35f43d1748ad7ae43839b4add2f2c1807d76e17fceedbdda6977f27eb3503bc17f32f4a0a8481d53652ed120ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb3eec09543ef3291242c6f9ea672d2bd41073d2bd98904df573d5bdc7d5708c76ddfaaad80cda3fc05195cc84973a20000000000000000000000000000000011a50d7568b8d2286961d2a4646e69301d979dec65305e7a417b7e0af6bbb266fa8c17085adcb6133e0bbbb41e61fb9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a83671e08b524b58e9e17e7aa1d4832fccc174573c78c0bbb7560287ac3bfffb7d7e10c41a1da6445497255d1ab3df20000000000000000000000000000000007368d3db9b1f69ed42e1cb8523e901a9b00390d85de4c5c8a6a5e0d64bd20345a92438c3e682d0ddcd8efd2aaab208c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0c61f9366e067f48fcc0c37367d1f8feedaa9db0a4e1373b9685f9a670fed865e7b2e625361a4d3100abdc850ec28c00000000000000000000000000000000138d4e39cae97af144e36d191886858a8bf134d3bb2d10aca771007bd6c82794d0046cefe9c1b2cf8b31e8a59beabf501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb9aec0f949359cfbdd93f1d4189ea2d75a953d428e9d0a673e240467c3027ae55e183680e82c01578c9a8f092bd5600000000000000000000000000000000168e0559c6678a2559011abb2dd5961c53d46e11082aee1f546488e3dfd1e6f2b0d799dbf15d2cbb3d8209cbd69325bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fc1f231cb8aa687140a40f4e7fb4cdf329f871500820896fc7963710850e71c46fc1686c66f519f0d4ae25af128d7700000000000000000000000000000000175e6aae004b92d7053808527776dc39cfcf7e1364cc2e4fc044dd6b85caf20e152aad78bc3704e14c9dca66413683b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141aaa3ee60c14524da64446e3b0cd8e505b39ff7dae1cb5bbaa9a57a89cb05a5617d3a9f8662b71dd5fedd44eaa5b1200000000000000000000000000000000053e6f25f7b4dae561c83b8fa6725db8d9c0afdcc7a4479b538b7400745c1f3bf8e0491bc3d277c42a6d08634917fd491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ba162cec0d042c2db771c91b063e004c425dc5dfc8503edea20e4795d11ad77da1161fe47f5bf159871dfcf1924227000000000000000000000000000000000431b6617ed2961578fad9a957b2e26b95c1f360064bf528486fa56900382c1c50ab2a93f1c8dc1b69218bfc97450ce01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000245c73193acec3b204fedd32afbc3ca36711cc4dcd6647705ef0f57703d57a6d910c7463f96b9622916e8b14482e494000000000000000000000000000000000557826222f8f3a683e5a5961bd27453c25969a4e8a786b4b65eab227ef94978ae5ea049c89c6d7c4739cba2c76310511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083617ac293f5a590d097ae1ac0b0cd0355f0b4edef527a2fe9ec7a66d4901d7659bfa6d0eb5b0959945f12be732317200000000000000000000000000000000013a276555d3f8f69ac1364070c4f841e6a956acf9f7a2d4945ad66d5ee7f2b47d910d09814728b1b62f9a96bb01b3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a69858f4f67a3b5e9c3d3d251f2085afc32864341a24d47e9febd9cc82915b557f200bfd455a7bf43a3061a1d7fd7b00000000000000000000000000000000062c33a018c4cc935b4b6e949e3a1a68c6f440d34d4935f3e87b6f12cc7c5dda80222ce9b797439e13ef622f380ca8b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe7ce45555f5c5c739a940282d01e2353ed9d3d7d02af8781f3c35810969878f73c2c8aeecf9712738d3d16a4605330000000000000000000000000000000015e33242acb8458b785f8aa04966adae73d2a16ee1d53d0684c519b3deafdaebe22d8e0968f4b7785f73d6dbebf2f0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001350e65f13cec9d32835d90eece9fd03719659dc389aa95db54cddea182ae8b00dc3479ec73a8531293e36abda9f98280000000000000000000000000000000019a1bafdab6291172ef4f4362f24ec4738c729ebcedd1230924328a4d2018d9d8f3c2dc097457e4f770ab01ebf4482a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008ae16bdd1a3104aa11e7aa52b439c5d6ed93c5713076aab60e0eec254ab29f45a2232e6b62a7b7babd5d78efda96390000000000000000000000000000000009b0b57ab0c22b1fcaf3c49c731d695d9c7527d05866008c4e882186bf2db26d6320b5ee4934807d55aa95b88eb62cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1b2c58285f5e42d39c8dd9c23b71551cab9399b664db05c7aa0af350cf3163f4a4a316283b0bf2893f06292f5b6fc100000000000000000000000000000000038cabc5981db9af8051b77ab548dfe1bcf53a330dff9dc2cd4a013a93c40538bf2992ca345442b00e446edc8cf690861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb606a6d2b191ce027889322d8e1b45a20830d3de2b20cd5e87e0eb6724319fe73bc82dd7ee0f49b53d83becdde1e990000000000000000000000000000000014d8c79cb808be6f0f18e44eca9029a129a6428026a03f836f9ad1766ead2883169ab3e3f7df2c3a1752b6debb9d22571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085614354b0bbd692928c69cf061163f5719743b2b701111a430abad8cb1d0a863b02941587a1cc64cd91897809cb5330000000000000000000000000000000006acded6565bb939e9861672e0c6a301628ab6f923afd84453c0de644bb9881abfd0893207bbd605c46b22833d65d6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a5890fda1bbec36a6b1764ec44edcdd1aaf30b6e01f4a3dd32a22f79e4897568eb3d2a268ebcd8eb64cb01bc4c8778000000000000000000000000000000000e51d93624fa174fa47da1ade3adabd421f575bab5e0a6bd4579636ef4cf13a94090ecba86936392a6ad363c3b3323241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab7f3185c26803b4546a07176ba6c21d10160b0f6272baf9f5582c0bc1f77cb7d9f087f8d740dc56e13002b61da208500000000000000000000000000000000156afc2f4c4b0393a65efd03f27d212b00e92727b7b26b2277285a5655996d2e6654a4dfe647425e33d36065521d674a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063c9e0fa195753f6e639010ca7427fce0012a44b0c45f9c4a10637060f1a7c325a9027648df41dc7684b9c42af6363b000000000000000000000000000000000eed05a90ac8c4bfbc84cb90b406d9e9d9fc7ed718eaef2461184e6eef8470742f2d4dc10ab62631c18486541669fd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001083ddc482222879ad5389d0407b4306b22d6e09b82700c236d7192eb9fba99c949d1b35612f687ef66e45315579f6e8000000000000000000000000000000000785c3e19aa054895f46ae8c744c8e412d44654283e78103867542618b63844f619711233167fd8820511647be55f9651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008043db79ddf6de0fa4e191d107ac7582f9758d6338d60119e2e8dbb8adf660f8ab33977668b345823b32753707260d50000000000000000000000000000000018c21abfa629e48f968f59b88c7b13fc335211985c8c35b934d99d2f698c9f6970980afe3d459babc76dcce9bc3364c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b1bcc317f716218b021b46aab74797edb5679b209674147344424a77c79dad95cee5e8764a797d1501c6b13b66269100000000000000000000000000000000028a227f7e264760590f46dd37d047b1bc12208d1460820ff7d7ce5431791b971594f7a24e4fff78cd8ae174c33e62c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2fb40ee2791ee92d899ceff8e709558e08136a4405977125500cd88c8b45c4b61dc7755deaf554e431bc20357b6857000000000000000000000000000000000d886bece81d486278d0002c26d02d15ae6f1a73ad0187d0e21f911b346847331efb93e191d7651584f04547ce1e88ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f210b30119c8066e9004167925f3a449c544f2e7d8aa450415dd305e48bf618c69f5b497193268ba380c314a5c53fa40000000000000000000000000000000002a48b3f05b359e9fd44ef5c684cf322b6b95a12ee4932b75d9c883e025b9abbd08a97ba4fd19ea303e6f7e02c7bdfcf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b568eedffd1659a0ac38733b9cf02a012456ffaf082a69bfa45fcdcffc0dcdcfbfacb402a7c6b03400f143697af088f00000000000000000000000000000000114deab441b58379ad7c1d79ff7c97d30aefd7dc42cf26fe570cfb3fb5418c16c548c3c16cb80cf5ff67addf3edaea7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009246fdc74f70f3c8a7c75b4b225e0f8da8354a7a47550ea00b4dce290cf42e6540149113c987257088e1978c572e3370000000000000000000000000000000016b1d0a7e73d6207cb9912df0644901cc5f0fe309055293ff4e1c70813809da43ec2fba1707e6da6962d54fd322b5f791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a8055dd60d1b5aafbf771fdbed3f900e712b100384c77ebef21ca958ab417d9be1b6234967165659f3ed94bc624b1a0000000000000000000000000000000004c27e403332871075387d6af3bbe05fe19ad8d5f8bf34228b81d1a63d462f999e62525b0ba0c85a668d74cfb90f68a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016059012a0ea85605e9737a5cdbc223ecb54c2a857310532af9dc816673794363a5fbf0abee91917ea82d88bd87156db0000000000000000000000000000000010c11c12793f29e7550cd99e1079ad9b5199c00954c6a68553574251a6b575bc6b00d60dc9db766cf75a195e23a341b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d48a3b67394571effa194788addff8143eeb16d6f1d4db941a4ce2c868761a900e2147d716bed04f93cb9504310f3700000000000000000000000000000000000c1f954c4c367615b6a360b0f512159609d757552ddeedf1b7126f8e519aa7c57ca5ef77997c8c94f05d9f7022709f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084f2111a7abe0ca239c3243614c3cceba66ea4c21125c682202c720359cd45c0528f1763ea7f26d6b0b86966b5baaac0000000000000000000000000000000015e4514112ee251303ce22ac128ed1841445611d23c16374e4045ed81fc697e116c1a01212f66122d82ddb93edadefe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181011f7bd3f39968b0391c2ec9ea05040c9c0645761f5d6b36bc6a43ae28cc674e5f31fd07d78b2ded4e96dc9cd3084000000000000000000000000000000000bd32807e078c8ab3265a761b425c07bc1d80a52b53f5b1829d2106c047c98ddf08b4e0918cbef96451cf5748666060e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e31e54ec7da342987d51e7ba6ade67c1c6e48d61965d02484715eb8699b80beb4c962b4952dc76b2f48e71a71c8e45e00000000000000000000000000000000089963c41402cc60ac886b6310fd99e6f78b65cedeae54eedbb93ab0460880404d51a78accbb65aa19f5015af65e244f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016495aee4dcb189a41f7aba5a37b81ccbb5f4b639918caf8eebe5cb8c299ff18e0a75bf0d6085e077dfb99d27cc99bef00000000000000000000000000000000136af14e20e6962488603388ca797e4f0bc466bea3be06d852155bff85b7d6371214b54d75e9f5a0a8f915b107a04a361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005978209a9d5dc334830668f1347593c71aa7992148bfcfb83cd0fbfb7a6f5b0e95fe5dd3ed13f3b7e21e3a2dbce228e0000000000000000000000000000000012b5f08007623ff9373b73c0bd83be8eb430d040f7930ccad1519b4a533474b91474129af3961de5bfb6b671619786741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0595e1d2b0b4acfeae86e6d1ce4bed2dffa93a926af60d13b79c73fe23d800c85d5ace834b7e7b536cd0437b300714000000000000000000000000000000001465b7a1886b584b59be303268bb5ce42c33243a70542ec2d5c4baf7e9b0301a90b4175ba639b3a3618e33c219ffeb191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112388c93106797cad200bd85848dca83930a06b34d3c8cbe14566aad8af176d47dd997b337bf1916bb2cce3eb712b870000000000000000000000000000000006d1cf43c1a256a9a4d84947d1d2e93c0006c30e914ee31095e6667f51cba80c1bb9fe8937b2b240c8c65e24e4f1d3f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012deda7cf221d0fdde2d12ed17e569f8d8d3d1655559edb955eab3f22da0dbe349b3e415fce5b168330cbd00515729bc000000000000000000000000000000000669a46b8e6911bf6173ff4591e64d03432a568760418dac6beea5acbfb9abe10f2fbf3bc2da1ba2bc7e9b700785d39b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dad86a923ef0ef41f177744f72af35a0bde7fa4611c959b18c14dfaad477d7f555a162fac21e011a9a00d43a6dd95af000000000000000000000000000000001086721859b47fc3831b525df6484677d28d9e7d4c59c402db1a48a2c95cba2f6b3b0ab695e354fc01409e64875c28591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115b429fb38da1d3379c84e8589fbd8136a2d6811537b7911bb72443b803214d3d55dbc4c6af95c386e06a484d9eeb37000000000000000000000000000000000832e5aaa4fb58058ff6590ced9ae289be5a804ae6bf49611cc71a3c698d9a521d343e1d5e8965d8ec6203a0f12795d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb4d9b18925fb558b991e6115c995a6cfb0b948a658c910384344cfd566ba6fb82dcfb10e45ade8ec04211119cd9ecc000000000000000000000000000000000a7f84f1c839f46ca6b1cd9b70a2e9e91311f1e9f3a9587ef5e6c487c59b7777928dd8a6fcf4dc5a9a18adc653e61d541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106668c6915e31c2eacfe0e558649567b3ba07eae84801ce56ce37d5c19478b372350836d4e402506c67eff7b0e69f3d00000000000000000000000000000000109ddbd91c434c9066f0fb7332f00d5f0a967eea73015913947d2046551cb53b1fa42bcb02e37aa643eaf93f72567a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e6dc40e081fba05ba39eef81eeb1537ebb98ac5dd23373a81fd0723691bf0c9d9a6343d2899ffa8c1cbc92dae28f90000000000000000000000000000000001956d62844570b7368e2f07023d052728bf063bd9d0215e0f5e51cc927619822211b4c46fd6830dab5ec499c9614e0761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000425ec500c17703d5eeaa85c912a427565b434dc9e8b7252b3d8447ad23e17e8348089d5dfcd5b830e9bffde000c864a0000000000000000000000000000000012a383e361b178ed0cf9f81a26526869769f623728c72d882496f581a7ce61468d894565c3d095340ec88f527ddce7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c30a0bbf8bd711d026e4e961f0db2a9cc897d50757d569c2e612513c2ffbdba902f6dfcbb5e243b2aa7f70eb7576e00000000000000000000000000000000024b20d21cd49e76452bc5fcff7fcb987e1b6b9f37bcd11887b9c463888d0bfb3e0d3533165c255a2ef7cbf8ac96f6d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0a64d1909ada32c43a0cad9387c2dd01ce2d0ce6db5f5588eef1e3443b92d1b0df356d7858ed3183791feb4290dca2000000000000000000000000000000000d63ecd254ef781d6dc59d2b368923b652eed204c50f3dae94cd3106ff4f2e1a21b379e83f16ab02409d89da56d9e4991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f2bce4d90f7ddf9b23e38121243af0cbdf18394453cb0ac472e61c9678a9cc6fa5fd19c37837b029468ab8438f41bd0000000000000000000000000000000007541f9a17b370f212d248dbe3a1fb83b356cad5bfdb890e94cc4c7ae74fdab732c1277e52c09249d29028cb55176b521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a50bd4b0f42352d62fd1014cb215d5a4d64558c883af6e040553ed5da1b5da9de7ec6544756f32733c6af9730ad488d000000000000000000000000000000000cbab31e29efa431ab797f8a85781a3c7672a0072adf499598fa0471a92956bd4f15d1b45f2ae243b11331a9943a2cf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000174475e4f0b6e5070db8e6ed290f28ecfdcfc304e96e50f455979ad120867b6247244591f90ca6ee68fb22502a82d2b0000000000000000000000000000000008bdde38cdafeecf8020a7274acbff14c4a12ef1a57b7ef19d81dbe8329c4eb099d1b5b954188149498bb58672cfc5ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a5920aa6776e5fc442c0a85b4ddff1fe449484f19dd6829784946c3838b83b2d6bb0e67e7c438d24d0ff8908f99e90000000000000000000000000000000018125722af1eb632a258b126e4d9b324217c5a05a75633fb9b1c3556c4e37bd5ef6475b24cd855d89fd0fbcfca3f9a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119324a5384b102195523cd5c68cf07d9c4eddc96bd69d7c1b1e4e31ee8dd633a1a6aa484bc59022c04c381ba54121a000000000000000000000000000000000091a1158c1de661f8fc0b154274dc52b92694ec7abade552e15fe97fe9592c86e4df0f642ceeb6238669b71af91fef841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001592d2e3f6216054ef981df453c6cba26ec695e6246cb6b5d9389a12e4258942f4c0cda3a717d1cc716b1d6259178cee00000000000000000000000000000000009443e8d0b7c79f70f38f7cef14aec8faf512ad77d0cb38f32c9d57afb9732a4bba39b5b2d227291ebf4cde6c14f3301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049111a1d44b7939723e47335d854861ffbf06829763d9961a1811b403c68736463e825b27e0f4f7d65653fbfcddc47f00000000000000000000000000000000039080fa964bc3e7e0aa04b5545c17a1c632a77a5f2c4689eaa6bdb530648234c46dff95fd7cbe3001a066c10a2ae7b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021496f49c7199bc9efc61948701868328e171eaa86f6005f08bf9742b67ecc877cb0d11ee6fc9db1353bbe67cd9874b0000000000000000000000000000000009d68f389c2a8abb3562d0f650ea44953e5482c8b861bd88e88d4751594f4f3ab901008880b58ebbc4b378d26d59b49c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084691c9e595e7cabe1637a271eeadd29087276902cbfe8ac37c5cd4108b963cc21b3d77411869dd53fee7fc6d7d7b8000000000000000000000000000000000043712669686cf41b0fc8b236f0b244a715db835da6e6365893b88efd9318a14b592dae5a8c4af48431269a72b40f81b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183e0279f3cf502cb280a14368420ee1fc8cd975a33c75fb50192f9c2dc063810bb301afcb813acf9f01bd41af4a5e2900000000000000000000000000000000124deb6fd765f33646a0a25132be9ede1a7536f5ebe34f638bdaf9c91aba22889b84f536b0f15b0d2047e991a3d3b5411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a758ec8e948da7d62ae6e923b3f6c9e3bd8888a0300940bc150ebc7052912e51cdc3ed5f654f2658f128a0d0b0fd000000000000000000000000000000000160851c1b4655b6cde9d75a199c093c092802e7bf9a23b229aa5427f3c9f5301d67913582c69e937902d1f5438c7c52e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cc953e434ab38c32d23f0b620db17bd0f799cb9088f99e47136093e15275cab448d2763f4d2bccdee31b4a9f64df100000000000000000000000000000000041e855cd9f9ef39588ec4a5a445357a307eaf6aec689e0bead56fd1f931d70de3c10a2fc0daa883a73375185edf35851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011b66a076478283f61e0cdc69b289efc7b32e5e4aee431a66a47648fc67e2e00584dbd6cf244a8db065c0297cdfa4e62000000000000000000000000000000000667475e40667d5c72c2608732741dc0288d7dbd63a3239ccbc58ef863e8a98af450ed9dcd244962b3f5a76051fcfc131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b6e3302a1c2dd6a7290c1f77d1401f2538e58b40587a984ca82c889b2f7c3b8df6d07b00831f17458254728f97b3a80000000000000000000000000000000000bef5d8ba5a820e8ecd1be3329c92acd80384fc41e87c0586b71c9c56541528ccb6d5c123b07e1ff10eaf310c3ea7aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f21be1782978184848f41f0c9289684b3de983546fb84e73ed4cdc860c1c1c1319decdfba3b3da0bcc54474949b95c00000000000000000000000000000000162a2167262e080710ca0369040d1439285cc4cdf1f326f9c4f6193b532d25a110b0fe7a76b14f3f5a9bfc427829e0631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd1a7033b93e0ad07c0fabb079d387b6e85b6120e5b9e704918b6c34f449b53f9b1de9dab11b280e09f98e268bf14a00000000000000000000000000000000003c3b4791555665160e25319b22d4b5b05ba863b27c948b0a86a1eedd359c96263182cf3a50a2be3e7880779d7318a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b79b794fb2155f6c6c2a9e33f11bcc40c7d6c6534a1bb9d4bd40e332f01a31409a3fa6736de981aa77f719751874bb0000000000000000000000000000000017036201e6ead8bd4529f586c274908b44e4bb78eaba10d9457fc3eec811514558ae39767f274383fb25d9e21e53379e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180554e41066acb4835ddfb8a45a98917b1b7a4e6e8bab41dde955d69cc777cb991cbb989a541b219fed2694702adec900000000000000000000000000000000001f9690d83e1c2ff099baecf55030308eb89f2f88dd9b8a5b4054564ffcf7342397ce7e1bfed983709470c703888daf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004325298ee0128815df082d268421ca419608e9d65a68a7f5d91ab9e5999e5dc78c88387da124612a9d462f7d75c48bb0000000000000000000000000000000002e205ea73fa7a04b845ffe49e0fe2a992b8b37271097e7093bde957df9ca628e8241790fc2f1803fd62a33c317255961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086ee42724934c38b69a8f476a489a6779b386144cd3fa854c088c0a216195029b7c8fd31a597e1fd7c7793ecf8b37ec000000000000000000000000000000001296fe6681158df4a334f84825c006ff5e9552a45630c1a3e9730da3b56d7e7161ea5e4b57283cde8167689f31b5666e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002528ee7945a07a0c149819edd5bc01efa131f8d7dc17859904d69974616ddf16ffed7104711482582861a9a87e42d8500000000000000000000000000000000031edb7c42d73d15e9184275b933f05e303781f0a15f0d0c9f95f56161fd87c638262c28ef692b759b7a45c77ad8fddc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fae5969ee0a1b28a68900ef8427b5de0feb306265812b6a1b9259cda7326b5e0cb2c25061ac7b8094c878fd435664a100000000000000000000000000000000075f63ff43c737f35ebd0c069334325941e97ac9cfe4aeaa58f5d2213dd7d9cc91b4b45da037040365065ba10d642a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf5407251c0dc89134b48450ac51d0e63191b40191d0c6de6a1698ec0f830f002494b5728142d0f08aefd54c0a11b3f0000000000000000000000000000000019795abbe1a1c93cad03b058ae38bd5ecb62e893a3fca5f63da48d11e3b4bf0e6b39a58555a4fc247eb80cc077f19cd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049bdec2bb1d254dccc60abc5f2de6b2936de9569b45542736446d5021708bb1568166c2bbf08b1d1639d1d9cb2e51bc000000000000000000000000000000000ee5b5196c35e1ee01f81d8e0d4afc91c71527fb966e466a2c67356698671751941d0e8f1fcce4adcbd1c95e41ff6d551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010afc8d67b3a804ddf374f9f458fa14f114817a0ad8fe78ce2feedf7edd6a224b46cd59fbdcbe4e8c2a5309ca287b155000000000000000000000000000000000d535d1e367cb2aca480ea943b189e400d706055f898ff2f69450690ea26808a086b0f7c036f5835c7ac78538f5f80591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015391a8f5f46bad9d3ce0c19c44ea33076a3b3c96d9ec9dc6d4300e21b45cdbf6b81830b3983f31cf54af7b8923b0fba0000000000000000000000000000000002ddc02ff93e2c5a3d2b8db546746ebd9520d1d227878463e8fefe93432c7e90f187568035f0754e3332cbe2d1d324641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7635677ff39b74e3241528a5679d562b81f8a4e45dbabf5f9b5092c0c49e6065d0265a9ef8b112694d3643296cda57000000000000000000000000000000000186987ca787a8a3f71ecab13da2bf4c7159afdfbef16eb5608f55826cb21ad88b7f5b2f1a582322f1068c0cac99f4b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001217cf74aeac2c72189d2ee2173ee8529c0abb2e7c2449cf089fbfb02e39453b5e53f6be6a0bd63e330522e38a95c92700000000000000000000000000000000159296e25ca8690dc30a18c3e82be208d8e88e8c0bb8935d351e28aff92fcf6edbed9011330cf1a41bde71f6ad72ae2e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f78465c45eeb0e514c0389349dfd0f6111ae995deb3fb9984a4dae5898e6f3326cbf5716ce06b1b08072b07d8ea1210000000000000000000000000000000009b588de3c78cb46d9b1b0a2c97d5def861dbcfe9e709b136a54775c2764a6945dd90e5c96cf1547a7638415c0ecc7c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000359b265ada07ef3dad974168226b39e163c3482f69f9935276d17779b665a3ce7aafe7858f4731e2dd5a3369c5d20a5000000000000000000000000000000000cdf30ae1e86f4d5632ab1936ac45689d6bbf4515fa0737e76d265d6366ac14339e232486357254c2b015c46b5fb00001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f25fec0b0e8a6cb2d9d4747bdb2a58ace6645911644c3527d177a88c84ef973e8ee3803a528c264d13531fb7f97ebf1000000000000000000000000000000001095dedfe38bda187c2aada8dd68622e255dade82f6a21a671733df91167c7912512f71bf88037586192706b590ddbeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054044e06122f5febe575b9265e9c7b9ddbdede97e3a2d827365f9c27503bd55c23d4281ae86139ccb916d9f8a4e3bef00000000000000000000000000000000131aab04ef91d6899617bf1a6413f887900c3400b2c87611df691c89d4f664ef5ded56b7533924b0680f1ddc3a9308b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c541453ab6b04a055874957a5882ef85a81251f9ecbc72a24e6e574f3ae6fd078e29a3b56f9486fba7d5de024159000000000000000000000000000000000004de411aeed7a9d2748d57b2f8b131a9a28341d4fbf425eecdecb60788ca81ab7ecbd4dfb033bee0c74fa0d8a6c31441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135f8342f7e43505ab170a55e4acb6affd403071dbd495d6baff2c93af46f792cf03a03f7a78341bdb984581b340f8eb0000000000000000000000000000000005dccff2ebbe47c68cdd4012a54f57bb0387da4063f6391a9d51a4aeafca350174c0fe0b4b86d0298e4d174334fd7dc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e04541112e446801783efb6f16c7b72ce80a6a58a5df859236a49f8c76f8e8afa8ec1655d52ee7907380efe139917d000000000000000000000000000000000cbc1f3534a09ea42b2702b370cce29abbce7e0805f62408c33c32e5eb20dea2a81b43bef69d6f39b143fc7313cf9d281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049f846554ae4763cb83e63562f52a8ac5f19e596f09461948b9782f6aa823b07337615eaff0659e19119344476eb66b000000000000000000000000000000001734f653d089cb5f424ce0b2a66664badc32b902947f0c18732fc19ea9a8852d0cce4f5c8716159d8040580508cbbf111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c53ec787c86753590b422355652c94442ea9e6815d0b9fbc322b0a339f47af9420ce66555e7a580602a13783f0e229000000000000000000000000000000000729057b6581168afc5ef9d971e8cb80612de4aa54424c1f3c7a5234a688c836204a368c55fdb2502ca5fc5e43f097971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070d9c928e437ffd40ba8d0f432d58e51ecb0f9ea52f2331aea8cf3fb9cf2275ffcf1dc3b1340f50bed9b5c200480a6a000000000000000000000000000000000165f3540a1e4f55ccbc0d334acd2560bdeecf645cf52dc4412a381aa67a7edadfea9ebcc534a43ccff98e992c64fd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9da4712eefb1d86a62c9de1fe982b984bf8c0d72d4e4dac8e0e566fa1d62c44bcccdb6bd6c97948635ba0cb6aac92300000000000000000000000000000000158036151024aa3a11863e7f5b650e9854f7bd0fb05872380e13a7944451d842e10abbf8412b2caa4b20ed8bbebb4f931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006a6dc2f40bd7d050f0acf206620f9b935a82a2257b8586c226ebdef0a81196ef321413810da2d115a9bb5e032f214c0000000000000000000000000000000003e9a178816c3a6c5c4a45d3390e88a42bdc94f864b91648421cc8f5e6fc60748574bd87e35ed9bc517f2dbe3f438d9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002531e21e97ae19660aeae3c0d56cc11876d6d4fe58cacae886b749f6a02b401be21ff1070347cdde8ba76211a275021000000000000000000000000000000000d80af3103c4f3dda17126b2bd5559f0e9f92cfc9cb8264857d3015fbbb15bbc5ab161e8e7151ebd573f7b0013c360511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102e8651e2421735424b9ef320decd63f820f9efe0bb5a14493154da699d66cbee852d9d8a929045173651748d108fa70000000000000000000000000000000019b7d775027bca8fca55ec5b14197d24538f50c1d62117ab0f0ecb48fad5fbcd2cd3d98bb419d12be236fa9d2da6a88c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdb04916f15c866b2073e028a3eebc223ae984948304635111ac89c4380fa31326c62746a399cacbb1bb39f1b4eb5b00000000000000000000000000000000006eaa328e1cb84bf62de0b6da78852eafe9f8e0fc5374e42d81743bf2a4016b492630d3971e1009e45f4bdcf475992f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf2be054b9170ee2395fee23fec11ec89648faebaabfb7613d33bc541b8de1c3e4c556ba0cf66716d8aeef54c6022c5000000000000000000000000000000000acbc109c68bba2bb82b5af1e7c2939152edc250b8345e74bdad28ebaff9528ddf1f2ad88c7e62cc46301c7ddf6c39261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c02d81f351c41d595323d466047c1c9238e2ad8fb78f8e8b54bb18fb3413e7993baebaa5a3471837676eceb19b19d000000000000000000000000000000000245b93a58d1e270de67bf339a8cb715887743e5e06d27bd2d83e2944f8d04ad400705bdec0a22517005a77d90aea42f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ffe5fd75a4c015af73d5f649ddadb16c0ac903b4fcb2dcfc89868bad85fa7ed30760e4a693ef8f4c52baccef40946f000000000000000000000000000000000941270a752797ac9aa59d512d4e743283fc7edb46dc7d28a9f2af3e6dd40c048cadb40e0bbb2a912c807de6bd249d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b946ab2b7b1b3c1f825a11fbda43abd3cb8b84defbbf7dd9d68b7d8524cb090840a8cee5ae60d034482710d7294498000000000000000000000000000000001287d71cf3b16977ebc42dda57fd79595101720ad3f7775c0025896c34c29a1dfe4d9544e632a1581deaa268523d0c811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a041cd121b31ae08d8d185612418b8a624e8cb0d0935bd02d8de025892200958b67f1725bac629729b0c796bc5914c1000000000000000000000000000000000a52e73ee5f3be4ca2f9db6529033960d2859976e829ea5dd1a8750486b4584aeec720b27af8d44f84e543ae6d1836ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a460af0831927d192f8ff6933af6a8baecf566c0f322544a8643049163aabbd5e1e657902d0ccb4dadacfecce33d400000000000000000000000000000000140457699590387ef9b6af0813f78d7038a7b120f039b90ad99b2892a0a07268bf7ec174a2227aa55d556c9afe4ddf7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001058f88c192393978eae87a87aea76b9ea4a9a52288503ea58cc9e7badaccb83cf3a4cf3030eee78a520cc7317e6286400000000000000000000000000000000091c91ce18eb1dba13770555ab0f151cb2495873315e53d5839976ed3b654d555000a83d7ee21bf2d9186a73958c64cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d17c6c9f78911bc0ac04bab3de11998a55119b475ed721bfe0050c81725c1fab79c8243dd90ab3c0eb1c98d9613f8a00000000000000000000000000000000171992fbb3e78a22045911feb9f959c6efcf790e5d48318514bddf7625556137a9773d79202b4dfc55e705f93cdd5d241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bddf0f9e4c28242328e58b60ec912501b63a6b66f2dc5e1e1faa199d74de0d8dafe8ebe3b9bfd977efa16eb1ff0156000000000000000000000000000000000567092e9fc807ea56395e0afc4b6b3431dc6471d4bcd00c459bca676425c82294f235cdacaeef74a8f4991bd60b4e8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ea0abfead866753b81a73844ab7529d979c81a4fbd5f76736096692d6a6443e6ee9f26235e9f905246964de9aeed9e0000000000000000000000000000000019cf6ecf027dd75dd4b2aaeb89dcbc39d7bfe40a0504eace832ece56d1f3e79ca8e94d3e5f525b1154940174f1ab85b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086ef725dc03280911dd63f30d8adb0dfa397bff6d679a9fc6f2c3c4e59cd4a3c48133e7fb135c30b9d1d7af4d9033e1000000000000000000000000000000000e732bad8dcfe1a219ce87e3fddccb59568aad421afd4f6904aca4ec3b62711995788955cf789a2278115e73b2f03e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f49c016d706658e33b5282b4361a38be67c5e066760b50aa07e0bd537817571918a3532c26f1fad7937393199dc122000000000000000000000000000000000eb5afb13b5bf29eb03fc4f32d0004c75bb0c20cf5f545b740c5c99f76877203204fc2797457c84b3a804710f54af5571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071b2f270c3982a3b526d5f5091b84e92fd2858f4f8177b9cf1ef3ad58bab50e611033ef539a909e05bba45d66a8059c00000000000000000000000000000000074a7f983452f9910911265021a04a940dc26b1286e5317ed70065d5ebb5f2a0d0bd210253a0363644a07d6b67646b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014995c353ce70ca641febf073d06e1f300a1a669effde727c7a1ef99f5e8bc798044b1bef51ee1e611f60de8415a2f4f000000000000000000000000000000000e2b9219382180c2901e0d7f2f61e91989b8a70946e76d4e78ee5d96a6e1f0245744621383f204523118b3f7c3635e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370eb00e5eaadc4e69e2ffbbd48616061069de2a3fa762fa306446cf7f3f929485111753740d9fc66025c368d74a5120000000000000000000000000000000007b9700b11979a536c283664599fbb89df9f8bdf73c456e8011b8d3a53a31bc418e4d6e9ce48f098e3266136eced02d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eec48d4a4f33e04fc1c80c666bc3f9b4ea165ae961e8b284e9fdb512f50f906c51957112ba67bb4e7dd4f4a0c253b70000000000000000000000000000000002742bdaa8196ad6fba002eb0b1ba74e44a0be0fa2a90646c3fd7e3598bbed3282b15339d7577e4a64a374e43c91be451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e315481e74bd37b9c7782f72ec1151f631320c5d20f86648e8f172d4b03a5b230c92c85e00136520dd1f8d2ecf21d7000000000000000000000000000000000896430bf16dc35d94fc66ce99b2b43962d70571f5217834f135d9ed506579f2c4c716d74e9b1a797cde4190beb72a271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d143dafd5258cee86e483dbc6d6cacce2f54493798592c9db6f29aa6b23e631c64398b9800ad1028968fd21702a9ec000000000000000000000000000000001903841ee27fa9eecb3e4b87c27daecc51aa08a2ee8ac5c107324f02c5a7dff66dbc680cff544ee0d6014e80f82a5b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003118c2e408e1a0a675a7d81a4083922269ea3a526f60719e05e941408e2a63f46798c12156fb44ce727028fad8838810000000000000000000000000000000006382dd4ffdf4fda1a71d7c5dd0825cd7c66fa59fb59044c55dd01714737b2d4eb06635d69d62419c645093386de0eaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004685ba3662d6789a40fce48931c38b97316364ff0327ca2fd6e64d2a8e1b2d417f7885ddfc3af46f6b2710cb7258c3e000000000000000000000000000000000996942db2f57cdf8a1dad785215508c73691e2b244afdee3c15f4fa8c31aa5a588c131416cac4413ff2fa019d4040841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001177777679c9eeae64cfcff5abb9a4b01f6579e247a04a63ca7e42937cb8c8db102b410fc5cd90ca4467d563c14ae153000000000000000000000000000000000a01858f9d767c3274094131e14fe7c7fdb6a9017ba70087c5fb9ae3af9c4ca9333df617851ab1548076955ff88d34a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc0b03ad66e0c8335291d7fcded349404c6c3b02c986a0516634297847e0b16b9fecd16e640d4d36d6753d505fbc76e000000000000000000000000000000001799ebd179f06038bc8e0d0252180729eeaa3b45ecff68bcd6e4c69f270d23adcb00427d4fa1a8f117aa5d28a09b183b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001873e3c2ff5146704d0b76419f29e242309b0ce31cd4ce9d8182bf26f5ab12729a0678a291e5d6d89626733280f7b39e0000000000000000000000000000000009fec362982a9dcfe8221a71e8378b3d5d810002be7a66107ce0d92238897acfd576e0c1131be29003ef3db01ba326311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088cfa996572b286ddf4105d5aabb4cc0d4b93344efb5092d73a841d40f54f8bd973a1e7bfb9dd73c094942bfc8ef311000000000000000000000000000000000fb3b59d239a22aea27b483bbbf81f1a6cbbc6e5462d02ce8d3a76f7cb4ff94810a0327bcf5e74efa027dd28b12f09f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bd22977c15f92d4f4ae9a295cd76d32ec379fa4279f409e0eb9c4ee81e7204beacf51493e226bd01831cf496944f500000000000000000000000000000000161357b9a8c8032342d068418a63526b7ee6e465780bf1a4408f21c606d84a0ebbe87e95207ec6c0ed2b3659e38eef3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038c949cb93a367c7a61e24fc45a0dbf249bc05c210f9ef4a222e09c22d22fa6e305f536f80215556fd786e19642a11700000000000000000000000000000000170af6f62e8d037bed6dbf037cee71d2d3b3e7ba228eabd1910835ff4d391f414733b631dfac9a59dd0c01e6704f740f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bc41c1c663b4487aa4989e8f9eb8038bba4d113f8857e15829b075f7d8b4e63c51a332684ed709865e56329fd02042000000000000000000000000000000000de477cc7e66fd6a285e199c8f384a7c48af70c3c0c971c8585d3dcdea2ad0b91be2d3c824c52c3ea1ab1b9f31aec4851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cc8891c58282e5c4ed86652910efe4dea4e66520cbc764ed0c861c54773219ab5bd449d00fb89445edd6ef3bb0667f000000000000000000000000000000000208a18c217938d0f23325f90f4526b7f722172608776c6fb48983925b24f46e9a42cc41b9f06d828cfd5b6e35fdcb711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a1e79a8d63ab9a6b5116dedeba893e38e0f39cf6b5757302e6cba49b28cd18ff4371f5245226bbc0dfdfa430a32d4400000000000000000000000000000000179ada57f867261b55ca30898f5a72f24673e0939f201a61063417fc7cfbc7cc22a968fc94f9d1c7c566194d156167251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e5736b55b840eb92fc3a39ebf0b9918716559d530ade497dd41271b2af51ef5d35798cfdd75607e3375d4fcfd050f0000000000000000000000000000000002164a8f6108acdcc7eed4a7abb2edee188f07a84c24fcc4847e7c2c840c8a9e22476f3b5e5a0f6ab2c020d13637342b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000880a5e849097d7f158ba1efdce01b4593be8ce8d9e26987ae07cff455183e41782349364e56333f3bf863d79bafb133000000000000000000000000000000000581ff810ce40be640f78cdabdf7fd1c03705cac3ca9c67a308f8b8e14618e264b7264007d230b37e331d8717e88fb441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006723e727341a055328117635105d920bc562628254cf3cd15dbeb612af63d9436a1118b115baa75160a56eb97f9672d0000000000000000000000000000000006d063bab2c8a95f34fb715fba6dec4f474bed6d5627e99727bb75015fec671879c4ad71a33b85f7b3deab769b421b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f87517701aaa211263c35fa0719d0442bb5d610ec0764e79f7070dec93eb8ef418f6ec0ec9001a20e121fa6ad0e6242000000000000000000000000000000001334270ccedfac10af4af0ea27c237575c65f6b6dd9be35e8534a719dc9d7b584164428fb72e98173558b89517727b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120df0d7df5b62bdab0c60e598e1d440596b97691a7135699ce582209f7a75424d0cc190276b1b8ca224b0b45553bf1900000000000000000000000000000000120d2a4abe9965d7ed3e20dec60f66f951e3da8574ad3587a840c314532cc943f9f62824251022de29fdc334c80f99401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082aba2d7cfb40caeed35310aae8edad4d46493fc490de9f3c87e178c21adb8c714623e7146fc2e5ce6d47423f74f7e7000000000000000000000000000000000578a554e8d9d46e3a925e53a65d07927786aa294bb1b64b41bdd2920b4df7dd14f5b2f3f710f4784ed97deeb72943c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082d21ef9dd2a6e1fb81fd344fa462cb2981abf70c30b31e20eb696c8033dcfc71a555589bcc56c6981bb74735d125cd000000000000000000000000000000001718c95050b1d07063a02ba2cd5851f78c57129485b697b5fdb14e06a1bf640be7d211d98d3046b7754508572e5cd4f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d4564f74a6e48c117b198f1cf6a67265f31cc359b175f1d48a597f06f9ac159e7591e42fcfa0a266d6c0963f46aa80000000000000000000000000000000001728c0b2da069859705e604aa6bf6fe4a0f322c14a01f968a9f1e6d4672200dfa5b3b4024980e2fb0f6134e342e3cefc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561122d0fc951ce6c6b7737cd6376270e81acdb6370f07fc24555ed4e874b25e00ca6069b591e258981fff31d44e0af0000000000000000000000000000000016ad27b20aa2bff204f5aacf0e990b2c2486c90ffc656cf5c1d2b1ce16c1c341f4eba2c60acdc13275dd90cb7fe41eb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b2d0d0384bcb9a26a373b35b0cc9882df1e6dff6256ce28a74c9a6069303d9badde5230ba77ba8aa3442f51c6acb300000000000000000000000000000000126c90c154470bbca9959fd52caf04d1834a172ed11843d60f624d9f36ae1bb1100b352ea314dc9a6d643b1a1924831f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000589b21b1d79a615a8ed74f2a8e27fa416b9eea6898476cfc08241adbaf2b1c92b9625d6762d6b1b752e09f1220ac9700000000000000000000000000000000090542d2a9feeb380153966f7e3ba0af9646b83317e6236b4e5cebd594b913b4ff957a31803714b948d75b49f977a4c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002882d437268b6eba31d1ed1d5763f608c9c4b5f1cbaab50efb2369a30e7457435d34e086d02f1f6d4cc2e6ce8aef9ba0000000000000000000000000000000002ad711d14d30e883805f2ccac970ea5438b2d44f3e66a041077a48b7c92d487fdd84a4c400938b19958983e9b8dabd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147e2d7594ec31dd4b1afb58bcd88412c4f9d88639b043eb4556a23ab0948f9536169aa0006dbe73c5dac859288ad70f00000000000000000000000000000000023f5a4d7deaeb143c3486b5053b2147395711e17b9f0da379d508c18cca854e7cea70cacc191c52e04b89c3dd19ea3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a49216c008d61f896bc647eaca4e497f2fbc6203510f427f2a5052fb9fc84c0241ccd70ab9cc744fe84c022d2729ff000000000000000000000000000000000a0732103c03bb4aac33e6a0cfc64a5d15f88d71ed241b309a31c3ea31f46c09ad32dd6f647ac2f3fcbab218ff505a1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d78b39479f0a484c46596d2389269dfe92fca945555b6325709b0c9fb84055b5a7ff20eb700a302db4bea383cbcfd510000000000000000000000000000000007f1cb60cccfd1d99717345b9f77df541a5cbebed2a8cb2f2ceb77c830f759a81440e442f15df32b0423a7cec0d10e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac5dcfecf9fb8ebb2f7dc020dabebbff6a23a7169abeaa6c56b2d6864bee3c670e5969792dd9a21cc2ff0cfe25c5e76000000000000000000000000000000000e3fa81d3234eea9a4de9963347b914df9a92ed370e9324640c65f1a793fe2117160fd4c227feebf29bde9be8c6bb1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001811cda8eba404c5e924002eaa5f2c00bbf209ea2dffc771ca27bb1b7e197b40886ca03b973494a04e544c7b93d81282000000000000000000000000000000000202f96e7c1ed89fe436f7e625701f36b4cabc3fa4f558294c6ef88388675609f15bf01af16477ea178840db8e0693c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004d5f91496afdae36cb2f871542cad498f2a3b77cf6e6e1e120477939c3b2d4e0297a57479560b540f1ca3ab665bb49000000000000000000000000000000000263913192be2d0f0e1e5b2390fddbe6847c450a532ddf422771c5a55823f05381d12faf0d33ad52805b78cd462ad65d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131876acd7243937be8a38b724b2c6687fd8c5ae13e1d11f61428e179fab211bc18332598499237ed72a0ad885e6791500000000000000000000000000000000128a011c0caa0673370303b4f7019454bdbaf54bbe3c97c00b32da15570dd32c71551c6e5c9ec6a503b5d652470c9bd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3789124cb7f90bb08edb2fd29ae626358030b8a9c85872bc7bde39166166208cec7ba6ce1f70c5273b13e25fc0896300000000000000000000000000000000159deabe97d1f101d9cf236b2d33b93e13862e11b0097004151be838bc160d08c42fbf71a0508567fcca96ce530d14a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002fd078c644724688ccfa8f2af24bf30d0c87faa0d80e2fba66a7024b2f3a2d958b526f850c31c1651f44dd4c6373a5000000000000000000000000000000001760b1b0c08eb4c9a04d3881dc1c2d3d3e1ca23018f093a6e64a686d6eee8174960ff71b9d60b8935e2956c4066610691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cd7bbc9c22a7227a9df1e5fd5d8e61a6e90e73f122dd9d7f20628fc6cd675e901b5efaf0621f08096e6b607eca136000000000000000000000000000000000166a2b8fb79d78c5e60235595ebfbd0cebfa9d0438bd0afe81f768ffb0707981c75afed8665e53753daf20e5e6edab6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef4cee4f157c391e2dcf43462b474db45fc584160daa74d0bcf26676d6546e75eeff90583cc506bfe8c7aa4dc673b83000000000000000000000000000000000b00428dddebe423784f17c9d1d7d29ae5defa8bb122b72520826ab612002d30abb81d2b48e6278a64a26094f241b84c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009af6b78417a421f291db660dc53397aafa63f1cee05d4d4c5d29e1c5c534671a07c48f551667e3977ab8aceae57798b0000000000000000000000000000000011c7805c7d26c34339d95408eea866924f72bc8874a5fd7e3b63c235dc5bbbf16712b6c62551b3d682cad6b980f6c4941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca7d96635870b64315914df2caf5a6257bc120fb5aa662c9992e669ccd6b2ec1ec9532fe2b9286049b2c55dcb68369e000000000000000000000000000000000e7b6144bb6d8c2be680e7a055d13d2fed10488c79a970366079e233d4671606b5f3b7f913c4a7298816ad4e987df8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e0ffa0db03ab916b5fd93c2689b64adc611d8c271683646af54f21486d9ec0974f669660ba3cde94b297b534a006f000000000000000000000000000000000eea32952ec0d435e56320aa3f6e90ab19db7ecaf5f77c57a780ffcbdd4ed208b3ae1f948dcf3172dbc94f7781f1d4691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001800907f96f8171fe646661e77bee6673c002d06a67a0d3360266330e638c4b3a174b26427216bb420250505d2f9d645000000000000000000000000000000000f45d5cd984bd2c1eab642b148253978ccd99d7231717d98fd43171b31cf34af87cfdc1f2dbe7ce3395a460dcc376a121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003957c25906e16e27d8b76b009057987dacf368189ca07ccc81ab06fce6e0254ca5e2d022d50ee6a4a7595cb0fa925ef0000000000000000000000000000000006410a835cd298689924f4dbe73f1dab40b736cf5e6f9ceafd3a5c0b517ca9fe2f5cff603f87c41956708c2279ce8ea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000033279a421998acc68ec591f0cf320bfffe62bf76b352c47d1c20b3e267ee515a5f59a379c816cf721c8dcd79933598000000000000000000000000000000000b01308d18ee0c2f1baac4e52b5863ad48cf9c6142767f320c3e9fac2fb15b57db701f37266ed75634cfba435f6f58051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214e9e7d8fcf312660575e6aa43232cb24a6af853161faab29a3f5e72203b7f182799ea674bc5df7ae712ca5bdf8c2f00000000000000000000000000000000144e08551eb29c162405e4c07f86fad025ff813241d1422c73cdffae893e6099b63e178fc830b22a0c18b2f98e89daff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014cab54feb6fbc79d0c0ecd8225e25fe27f9c9dd6721b69b8d383593edef543d53a72e291e13f462886090028b424400000000000000000000000000000000018ed520e6091745758e9cc7045c3a1f991a9266880cdfb46ace386ed53762fc5a7f9797372f3aa89f09d56c9ceffc3b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce6286ba886cdd66264ad4e0e327a2f4376f298147e0688744c0272054cd6b886285aa01c3224ad28120a7aa11d5630000000000000000000000000000000015a2e71bb67f4c40b5cc884f3fdeff809932ca5a4629b9f0e9edca5cd48d94e549de301787fbb0aafc6bc8bcd77503981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcc166d171ed0d63149979b9545ef116049a303ca58e3971a5f0e9e87faff7cf55577ed03d62c57463293c46e40e600000000000000000000000000000000003926bf56f61188c4c0f509208982c2aee21fd2d77d320588467c3e78cbcc4aaaf7447e81b9e082f00920d26ade8c5021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013382c7bb1da9826fc1736c94a0a1e9c83c72f44f52a19dbbf82afed5552790cc51da26852647220091e3e523bc23659000000000000000000000000000000001754ea271fe9575e10a6f8793bb9ed7bf1d07bda2212806027953f12521fa3efbcd4ebacd10883a4dd4f5857d0741ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004854461441ccf044849c5a44ac53e239a13b2f790c7fec01044389013d869caf3a07f82909acb820c537c17917e977000000000000000000000000000000000196dec16024c33263854d8d96f413eba9bf073e1fbb674c6a11fe606d3dc444d734c1b85f3f93822a56ef8f38e8912a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079efa6ed020a10040d30cc8117d2ad4337db64ab16c9a219c0a31d718d11f2fc2ab9c09ce4d06b86a6bf96b0672268c000000000000000000000000000000001723eb2309e3d0e2c3129e181823558052802c2a64744824a2d2bff8304a20d81768b4d4d1515ee9e96bdfa7a93fed7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d1a451ffd71d205158e95fa4b25ecd48bb4923407c2482263bc38c5416143dbe7907d3deb9f5754e328eda0f2094cd00000000000000000000000000000000131f194744b656be23e16a9062bec09f7fd29a3884b8218729f410e9dfc72c55f087c200a373da6506b94f6cc9b056291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d13b67f68b0c0d5fb58c3efa9a71aeb822d76572ef05d1c36bdb79ea75b72c9fa7f1200bde843e77289c73cca74a9a800000000000000000000000000000000146b553ffdabdbffea4030dd58f3183a513707dcfcc6e1e164f72b7b125bc0e7837634f17847a988c7a6a4da25f0e6951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113a7948a2614e31d28e67b24a501bf873920b1a1edf286abec72e46c10193063d38823518c9c7df596e52dddbd77a1b0000000000000000000000000000000013ea4a5e1dee5164d02ec7df351ce5eb7ca2746b930731046a2a564ac3e7aea6f99030913c57b98a5150c63950bef2a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f5732ffaed418965c0c0d0e9fac1151e2d02dd1d13c4d185d98f635fe015adb526c838dc64fa957b61a1ab79c690860000000000000000000000000000000018325a5f90eb15a41ba01ade4d0faa4c65051faff9981fdd33f34d86dca3b6b7572b0d73149a2324d4c9145ad99e36d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8841319701f8d17e78e938b3f2d7f4278f0db83899e148c2ef8a6e3a24dc1eff506e01bf1c0d887f4d78d56b90dfd000000000000000000000000000000000ae2c6953e07fc2798fb87c95069475cb29c890d9c9165b1dab2ea33dbecfde998e102508fe0196c634ef6621a522e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012370fc0e4d806565992fefaccd09a3768ddfb3582b5a80a2e7920ba454d5e12f2db370616dac1251ed9a32457db49c300000000000000000000000000000000156c43d5ffde382f4e393f454511b2ebd69bf52fa84330cbc1bd071896b70a176a2a5e2ccaeaea5dc923b19412bf5bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018703189b335cf82068e80eaa87b5d4f8f85e41970c8bfa6507c37e76ee83d5b5cf83c4557c952db64d5d4de303dfc8b00000000000000000000000000000000144039970ca20ecd8a8c2c9dca526964298876aa7f8b8a5517a34676b1475219342845c0f37c8e46b71b0d473ea49b4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e7b7d3141133dc54886f718bc1d43026ec173e097c604f533c4f3bacda82512e0b8063fd8541ddb47712686afe5e7000000000000000000000000000000000707c76673ae26ff815bb5ed134e3d54ec622c2e68927bb4e918bb7ed58f4d1160c056165e0405c127eb3b99cb12e90f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7fda0868af825a41ac3635adb3f214402facd152ed275eada88ff725675e8156bab0f04fedac2cfbabe3cb4e635c0e000000000000000000000000000000001574d99e64867be5491e8e2401129892f109a00538b4f3a1a4c2f2b3548650f2ed3c62ef3ebd668c4a7e246f1f32d5ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c090361f99c42e7897deff86e54e64f0b0a279921c85ffe1f981655bffdcaed02f85a9499233e7aaae9f1d73e577cf0000000000000000000000000000000011d27d728df62489cc7c777211464fa3e350fa53ebd210d207f960e8ec484e78176f1593121e9d916ca69fff1ac3de0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e9b6f58842b955e2fc19430d73c63bf6abd1064aec9f32ae3adc6965849ba978f1841b66d06dc510a67f2bab60979c00000000000000000000000000000000150f7b5bf27d5eee259bdcc6466527a17a6621aef0afd11641a603a5452832aff96df0a93178f63209e945f0da0bff5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd1844f2c54d18f0c71e4fe778498bbbd3e3a2621725bba4f2b0573baa193ebae0e58220737800f75efb37fb9d5cb90000000000000000000000000000000005b749debea5ff14f25a7d0be3ceecbd396b5fda0daacb51ed76e608e3d84aa2318766d1d83333165ea07349674a4b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001349f5583de75f293ca8d6d4e8406c385aed8e52422085e81c56fa6b8c896fd336054c3a45810de1eccf48042d5df38a00000000000000000000000000000000035707fb49278a7f11636b95ab94bc97d8c7819e3eef9f55c83a917e7919713d19ebaf627ea063f2177185e9eb3c29191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc8f1d61a7c9565ce72ab07d947c5744859497a7627adc67e85068c8e15068a47fa98f2a357e3f65ee48aab5cc751af0000000000000000000000000000000000b317ba185ec85f9c6388377b8ad5ab85fa73e66a6356347819986ce79e123f601950396ea955075a21a1c6dedcd2231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8f4f9e9a8c4ae473fc1e521e39a189a77f416ecd445fcd78e5e5931e342d5e647a9af56e4ebb79585c9ebcfa88a9a00000000000000000000000000000000102b8256ffb7ed4a303692d718544ff6c1f528777d9e08f8039daccfe242fd89017ba15d39ecde64f08b7385eb1893a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f88f2f88501df778fc128d5ce8e11bb254ea472d8328425d4db7a316042d16bde7c393372bd3da0894558ad53a97e20000000000000000000000000000000017fa2f1508acf84cb1b6ed166be8c8dcd003d14a4f7dc65c788790d894f618221e1552a9f67652abf706d9619e75c8dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014150b65046182d52123fa00d2afc8cb303b687f90679287edc51b6dc3ec59aab8421c4784be781fcb19c0cd6a3cd06f00000000000000000000000000000000149a4f80e93042bac22db69da5cdc576dee22d4d21a32ffc1dddbbf2dfaa9548ee07e4776e8c12df01118ca0505e40dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f5020ef5b4e7bc1c21aae13537450ca867debaa04f6a3a66f2ce605ac00637d30a1c6ec8ca802a1c5f9e2f3bbeb9ec0000000000000000000000000000000013c02190d579a8f34f5489914ca2687a89a15f5bfb17dd231a836c4fee68fe0158e27c6af8c367a004d9d1de04eb64401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7384a45dd3a55e34e6c01ba4cb951b32bcd5684693fd4217760e56cc94806e7caad422e1f4e5928d2c2a7100557bd8000000000000000000000000000000000a57a6931c5e57ec60e3bb5272c00648cb893ef022f26e33f6a6c455cc6f0eff77d1adaea7e87625f89801b72e4f8e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051f940a9939aa16aa9b3f24b25324c60fb70e19d5fd2932c1f93b435ebd5bd10ebdc6bd429deba38fae6de67def4cd60000000000000000000000000000000012420d8942509abe6b7447668611dbb6f743689d670af1e27b01b97084e5b58620815994a2c4febdc5fd285951f8876c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032d8e6e03ec9fa4faa7a9d39d6963f765043f48e19b0195271d68bc2ebde5011752819063e22fd81706213e0a40e79b000000000000000000000000000000000d782584a12f0e1e1a1e2f1e640c019534eb5bfda891e1a8405f560c09bc52fa694959ae835f5d22c2c74f82120c96a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8741637546cd3617ec18dbb5b4ccf74ba2865c7c1003c0f937c733a328f1854240d104a8110de9dae6429b1334999000000000000000000000000000000000c32107eeaf9f01dde2e9a7203cfce709fb5b4847de0945a8b186cb1ac2df2560dc4ee2089235c42985238594cdce0f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108ff1cbf8d8a1ecf8250e424c4d916fe777cfd4b6f4458fe1b33cd43b4e5b8877d9e09f478fb3357583f41cf94ecc960000000000000000000000000000000016618239ccbcfaa25b5337264584988ed29694887924190f89f970d9c788486b80a1ea6fa2b51a47bcda04cb61bc307a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162179f41e2e2f5d85b2adf4e90a3e989ac7b37f74d531425e9759d713c33d08d3d677bcec603ca2fd51eb4d6e13e983000000000000000000000000000000000610eef42bdb08bf3c7adb8948d95b79a233905a9b71b70ee1fb22f7bcd482a57ac7634c03019bb5ae91b7fc2fe478fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaccf87def18741c63fe5fe3425bd82595a29250954250fd6f52f0d75fcdb71bdfccbb2c40f83565c3572797b34c94d0000000000000000000000000000000005c01cc46574ce46cf9185270c3075744e96dcb488e003c54d647a35892887290e0a49fd8edb22da1421292175d400911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68210933af738d9df821d1389881fa98126dda29cc197dbdad01fa0e22082121c28be59af8b1bdf52bc19b9b0379a20000000000000000000000000000000001e8d6cad636caaa1785845fbc39308c694ab18734b10bcc6b32552295c22a19af9cf05d9839bedced3245ffbb5584cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001121677b3768176245c16043840848cf42214e108a96b205cffb8ed059268081fa404258be5377d24f629475957f444a0000000000000000000000000000000008f430d611e2dc59a6e78a3268d66aff3eb6ab9dc29dfdba504d054fa673766f13eef94ccf28ff9e0d0d78273d73725d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f0165c08a2545b846c1d05cdefab7080b2a59ac77af97cb304e9f08794642e3ab2a537c23232c9fb6f8c560e6d14010000000000000000000000000000000011f548377765cbe98cd988376d903abe3b8d3e9953166a300cb693347aeec58e7477e124ac5b91438d9fcafca782ec691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3ec989da2f5f4b63c1113dab5c119b4fcc6c95e81d8ebe61be5b713c0ca462b8ff7abe337c8fb4efdfbbde5dea636000000000000000000000000000000000ec7cc566bd4f29eb81167017ea2d14ee4ede46e9c539dc2609da74af8bb09345ff08bf1a6211fab13da1d8f145db9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a5387530e2da598d720f1924d621aa0da94343e05ed346acbde08958cc48d49ad486aa958dd6a337c6678f74063ce000000000000000000000000000000001880aea194f91fe32320503b92761c60e26c0242d2e0521d4feb4b96d7804f0fcfc3be4afab9a47636f047eaf86bc99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ffcacda9b183a5077263f3a2efe37e11d7df0ea33e21518a5c1ed2c7f5c4a92d534be4555ec754671370dbee6a49f90000000000000000000000000000000000f6ff3c60ff9072742a960a6adfe5b390e2030ec3af9826f08d30895ae1f4fcda1181dc8d5c5c153ce43d5c965049d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214d9ce5f324800c46d9de61c772dc6e2fb189c7afa63d873ed5a2a1e44f608a755a8de016b79c247bcccb37eec159d0000000000000000000000000000000013dd1b0928817e86f30b70fe605f5aea470e56be803b9ebb04069ea33283d8c194931e0e2e8d47018c4331ea44a7daf01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392e022dd8caa6eba04204615cad587275789062caed525bfe11abfb5e456d005dc57ff98591fb2589f4a525e8cdb7400000000000000000000000000000000004d2f40b1ac186e513bac855871e6102aa9564eb8fa575114965adeb25e8584186b7ea54ddb0e73469b0a25091a6f3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011530988dee38c46a3d2b388580199005311b9241927292ec7a3d9132b5acf3a9f6424cb4660376ef9dc19579050093800000000000000000000000000000000131a40c103e66eed902bb20ef82e51a1ca8c2c946e55d73db4f9f87724105215be5d4b00b12be5d3989f5a73614d91e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fdbc914b5ebd7d11540f76e11855f009743c34c6725f33776070d26c6b7fd251dfc5f94cac3688afdae452958eeb2c000000000000000000000000000000000e6d8f32dd8d9bb6aa4165a76fc96ab598b2b65a6e12db9e435ce12427c03f030310d80f8f337199f679da1646d59cea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018018549f6fa8942e0a22db820fc4bd4b3822b8f1b4c5a039e7508392c9ef5c802fd70c31c91e95ea6b5fe4c7271fee7000000000000000000000000000000000c4c6d4b3fed72c5d54b511da7a15740647e28a6d0908b2e3c01d55fcbe65bfc8a67019ac2fcfd4a170cb78f173ef6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001832d06481573ab4d103113d49789125fe70d0f14adef4ed9b006ccc86ae717926bb9beeb44652b3e271fd99a75ce0e0000000000000000000000000000000012c7ca9bac925f4cbe91552261862340c1cd659e83045d83ce9489389bc920c0e3b03636789d10504722f736121691ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073de5b9cd4d2358c418a103d4fd4653b4ac32a43d434f723483621a159cb49255d7a0883d379a8a08fc8c9b0cc59cc80000000000000000000000000000000006ffaf33a960c1a466f8917da82cbe8f310961dec008d0d7fbaf3d76dc740339ee91bfd2e41d4177328fb11c19875d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d82a0e8dc2d82dc8856f18a79841394f70d8882c09bff7248a1696d8801056376c9a8c6980e26f644e539c24fcf5880000000000000000000000000000000012a69ef008501aa90075d3a1d3cbb0af712784653667361325aaaf32006231d8dfa5b6125d4c840dd21192ade0c23d1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ff3fd877c2f7f8a14d78e5af42e1754f16c3bd53ac0254523761f433eafba64d3f158d2b7ed136c7f87e921e3962f0000000000000000000000000000000000d08d67da1798dd43d151cef813edb655d93803f1d6f28c60c79cc44226e839cc58f602e744c8e5e8881a4d725486bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027be6f56273c38351ef2a857b864469b2743b5069832ce84efbda7b913624c9bc6e0962095256d262adbc4987f78ea200000000000000000000000000000000137bb171f08ad3e82a524e51290c6b9d5c71905a0d3b485802b69cdafedb57c753cc6275500e910bfb41fb557f4ad7ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001989f098c2bb8c8208e01dce2b5f7c237b191d11bb620eed3e8bbc77bd104a3444193c4b84b65fa0fd78bba437fc0bc8000000000000000000000000000000000a8792f2ab78460772f49c62bb036f92734f9fd61567074c671a2133a63bb18486075d4b10b08c8eb0c11f6f286278621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cb972663f97cf6682e7f258d5e2d540e313cb21371e9e656b318c45bcbc09ae402c8307d919c84f2bb61701185b57f000000000000000000000000000000000a56c242e6da1df7bf518abc777ed36a409fda31228ab519e6c63a2cd3b5fb2c1211461c11d4c6c14bf6fd70f255b3e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3c26d38180f3cf375d3ab62cb2c1f00a9b20708f1f689c91f577459242c1541e47f775654b5e6a69c75c256661c852000000000000000000000000000000000e4372d7d92c21fab13a91b05ffb0ec33033c27a4e8e0d64794894926580ea12b530a665e6b0a4b12fabfe4be621bbdd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053fc35a33fd7dcea7cb2f5aa94a7338bb69526c75a6712b8cd91ff1012bb67c76e37b7fc391407ef8ce4da0137e1a4200000000000000000000000000000000051c06f3e010f06a2a7768eac1513005e4267623a5a3bdc9a8b6f8e0b9f39f1704ccc0045c358d7fd34656528dacc3e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f6e1f16a704b6aed9fd586a1a8863944e2b0e62ab18fd7637fcc5912e8f900fe140ad93464581663c5fa1510279f1e000000000000000000000000000000001793cccd33cec78a53af5a13b1628653e7c20b4aff2e3cbcdbb365fdc1eadb8e9215bdce9df7d766932ad32063fef0ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014432fa74b331cce53a246f844e6b13d96b84c5672a4ba91b0b89ac111ee5102c0d01fc8ac9083d2403f0d5ea41c72b30000000000000000000000000000000014e884dfc2d84cb632025a207f81663c5421b44333a32b079dba2c8647866e0487d06c0322d36e8f5a45e3ebaca990b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061595fc1c47a286e16c344660a62cde66f1b9cab357f26b77de3496553f8eada7126f5d68884e8ae477375656a9b05100000000000000000000000000000000092a23335ffb2f1c5e8cb5eb7f6b63ea31a9505eaf63bfa58a4fc77e0bfdffc58788e851b619bc1c144673e898240da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ddb7188b3328592794c83f07c959aeb01aa660070d5b9b8248a0ffbf0cf7ee807d8ff9d98572a907422e1bbae4ff2c000000000000000000000000000000000524685a67b7b7ea6f8893e22f16852992af1624bb72a67b040fc4f25feaed92e837810230dc9b82dec732859cebffaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c6904ed6cd3ee7c4a26fc34b6cc4ad787c7ab3663de2f47bd002eb856d9857e2e940d3e79245b00b1728e358679c1c000000000000000000000000000000000b38589479505256b3718f96093b17e2351ce50930636cfe072513bf8cc6ff7f59fac2468d8cedc5351b5fb38ea4d36c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a5baba050ef38a53246de5465b832e2eda40e94cb1165621b3abf6f7986e9582533c54032010494f7bcdef0ff526fa0000000000000000000000000000000005e9458bddda75bef48f92dc146b2b7fff98b8cf89de62720a88527d01fe0ae1e7ca946defe6fee234bbfab522a777c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000872b7d182070e115309e8935ffd8eca8f4307170515780089d1a0254ce905c3eb062f9c1e5d81ed7c10aa31b639aef5000000000000000000000000000000000baf042059879a2f17e6b976240b0fe342dbca69b5868c59fc89b902957a83b368373e2eb2be201ec281c8f2788cb9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016e18e49e5fd482fcfb44b91bfe7a8244b51b99143f592980d56783d29a40eedceed2b459c2a741c6c68e227f11d6af0000000000000000000000000000000006c1741d152d500826b28b52e7007c091470f48ff626188af95968bbc32e8f28db6940612cad79cf7b8c5f625d3dd25d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c52198ff413685236699b3cbdcb2a844743ae0ec388d0f19784d75b76bd32ecf9d2072afd24eb85ab7373902f23994000000000000000000000000000000000b52487e28501f279667b7b8177b65a17760c421bdcdca499b9c637364dcb680bce1356501aaf602297abbe0eff6132f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c4e01b6264c5649a9f0c99fa52869354e43a4fa21179eaba87782e73304d6bf104bfe75459e15a6d510af2ac6a1197000000000000000000000000000000001972b5464de7f91e11cd3ed6a995a7a0372fc0ac2294131eb35e6443a619fd74c528c2348c347847908a0cac3943133d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d838ba9f20c8d4d0e962137f5de82584538b5fd73092bd3e02a31de6df79b41692128c5323b50644603685af4b5bc800000000000000000000000000000000146388be7e8ae6986b7d667f77b08cbfcc9f0f880a02008a30dfb48eaa46dc9d42efe3b738ea3d1799724a2952cec88d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bcb08bfe1da7657c42f1dfaffedff442dee9f2502a960300dabaad5efcb19d2f26704a36ac79c5ae8ad2542bbf1893000000000000000000000000000000000142268eab968c83e69e9e434ae15c54bd8f2cb784c39b3c84450446c6377ec364fb9c3f647b13b626c0f3a4ffe89e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035bb13d24ebc2b627bf8d3b96e80ae2303f96bfcf441d57e4ef3ebc3e461694331566c463680700cd4e47d55372babe000000000000000000000000000000000858eccfdd2b40998f4050a131d875f9ba851a801c6dcf5d85f31bb76f2d16160987076d42d8e72ae419baf35090c4cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0d640d467efbdb1865a54e3fd0ca9185e08b52419b3bd1815bf625831f86c90f9f394c6de225c0043c4ee60320a16c000000000000000000000000000000000c9662de7ec1ebe557d148973fa21ac795050d7c5d4d048356b4c9b0d51c85e0a632955575b0cfbafd8d72caa3cc41f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012514c99af2c22f95f4fb02e307c090fa3ace72e68de35f12e91069e2a77745d6ea84595db78318a929aedce62caa942000000000000000000000000000000000309db4e4692418fefd4880bc0082055f25475a173babe8f12aeafc13846a8b14bba8e63ad44846be62f9f4277ba5d141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b2d8a702d9ae43f6d508f92f37f5ba3bb86abecd5ed9fbe2c590adcd853b911b03d9a05448318151d94ac9bbc433b80000000000000000000000000000000015a142f9ff44bf5f1933878e2c009621543f00d45ea5da8d70fe8dfdb8354df537615f41d5c31a86e1fed5c9eaec37bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df888eb6b6f9ec62b7803a3f6d39a0230473df6d891726cfac7c10a380cab7e6da502f1edf0b600b374caffb194c78f000000000000000000000000000000000f926c3bf6870e12a76e35c3d661d81927c00afc5028617aca866f477bd870e97494b0b88829904552d5b01925d89d321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd2cb07b568d314425122f23177a13e59194a0d2feb2f818c3abf0793a0a27daf841ab0081af245f75eb6c20d4066200000000000000000000000000000000008c16784ca8cee3c304ba16b09acdcf7341162043b78df9ce8f069daee52407b6aa7a4a44d5e31f18bd4f17412e19e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cf443db1fc5dd8698d250cc9fb95505918d0316eae884bc323e2b06737f68a38f8da26d43e40e1d2b2e7df1a56b237000000000000000000000000000000001069b8ee7475043ade78b80e0675a4b808b98b8d7b0c3c2b7a63eaa6d5b80111fdc5450180994d179246847bb081d44d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b5636f7866dded581fe4a460b887cd18e0e3c9ce716e92907f95c491098f651a928a1208ebd139632aebc13bd4a2e20000000000000000000000000000000019f55b97ff92d86e56094f2d90cb177263220d74bf7066fd686882c918814e4d053d6e74757f324b6bc241dc74f4c3121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190fb436954884ce2fba4a38e52039b0449a3a556535425a93e3664fee7c1b2a943d3619ce2dee750f2949526185ba82000000000000000000000000000000001883c6626df40914ce2c15a7d75608e2fb359362e560277acdd29033be4533c293d01122ec0255122a18e90df478bcde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebae319e5f0460cabab5618c858d030b4346a560f95f1190d1215caf2da1b096920461a858240d4d6697d81adf0cb040000000000000000000000000000000013f1f0d1603a3dd6d4def1349072ca924fd7e4e79c3c72f1fc229bd9aa267b41abd7b9cb4a991d5e79f63993a1f5a47e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082053003c6f76cd6f01c0d0d50ee5053a6ecc285510b504ebbbcc4da2c262e6ea0b91de2c26a38e4cff4f4b2452859600000000000000000000000000000000183466a12df33b9ed7cf94985c29cf2d9434510496d8e73935d3ccfa345fc4be4c19c17f32144343b3a0cc3f15b62cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112e8f75f6505f03bbc71bfc6e2e15a1620a2344a604d49b7a8f4b83c7329b96c3961cab4a692844b29ad76590c2492700000000000000000000000000000000028323f8840f5da31af29705dedf59b7f3f0d2025fc62c7db6200de7c076264c2d9498f839836106c28e53ddcce220111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b71fada96f2275c12542bf9fc2b932cfc7878b98292c8f32fbafec75a985b703440b10e6e8ea7825f9d16b41ae2d8f00000000000000000000000000000000043f36d8b2a3b9f5bdae91f7de8da2fcc52c9bf237f1515148ba8e9b4d874fc3ce9b10cda44b32d30954952c6ef53aaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0e3f7c7b2694359934544101be4e4bdd4fa2849104da41fd80ada55ab3571fe2014af6cf640287176c0baf9cf09ada00000000000000000000000000000000057ec4d92931945d9c5c061ac62c23499424bbc142956aaf9c1a395b1b0817fd7a7e763df7c990e958e145bb260f39fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000161512d1016710aa14768013f2445b6dd727502f5dc1ba0e6ba2beb371137e7a78ea3151737d63c500fd1b757ccfdfa000000000000000000000000000000000674f712faa60aac4d7d623b54b15a34e832601d20a1a7fdf81fd27fa58a280520a5e552e59b10163be3287a457ca8f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e076ca12c4165da77862f49e479e9a700fb03aac93149491733a29c1e8d88ff4348512091f1e0eaf076390a6a25ef700000000000000000000000000000000137a9b12e0dac1fac59654747ce6e2c0bf69a92fb7ab12e53b0f83e333b43a747df3b8a9228b470a0aa1c67c7585414a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ca1e24e55d8ab7f1905957c9a2b487115e97d6baebefc2ea9066249ad553dadf77c816a08daa6571893a4255c3b71000000000000000000000000000000000106b740e1bfcc0e62eec98307c4f54d991a4ec6a861d6d1f0e62eb38a1652617856e4f2eeb99a69903a2cb8ecf8ed77f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac43272ff019f1ac63a156e1672d3734b3a988164e6bcd92c636560718b0cad035e00acefb6e9a7d5a498b237ec02c40000000000000000000000000000000019a483093ecf6a2869f9bbd5fe7c5d32a1b02dd7c7b6d1474cff196f7fa87f40de3fcacb39d8f1ab6e20db974bebec631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c6e4cf7e2420fb383e664990b6fae6e6903771ad8b37ed5d14a3b831eaded8613e3c2a5ad50fc5a19ac61b4e3afad8000000000000000000000000000000000c6ac8968b39223b0171f2d2314df24067ce48f5f6a045a2a758ececaaf9f51d00a83df3d2f796204f0c4fe190d869c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c04802e611a8cb1e8e56f9186cb827d55142e133e7b4097e83f41e736458efd722f69d224f761dc843961cdb6f46950000000000000000000000000000000015d1551f2a274666dd9e45a0e56bf0d2a27cf5c6dc7597a45614078f851bba62e3ab23aefc7828e6dc9d96a770a9d4e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aea943f15bb896e56c41eb9b21dbafb4dbf3d1f46ad62a5a0d9dd4b0bf5ca30e8cf51d74cd6b2193bfc0ddb3885c8d0000000000000000000000000000000016febac9461db6901a8a13374cac49f2885af1aa4c65aebbf80474f7ee30dcb91a34aac766ebedb23b879f57f34bb04d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002d463dc4da27ad2115f2a1d13ab9a8d36325a66909c1cf4e40a105e1c536be11d4a0a83508ac82efbbaaf3c780ecb90000000000000000000000000000000011ca8cad60e73e7922d46b6d1f4e0bd13c343f477516df12a29903c3c5ed0773c5b4d4892aca81550ec4b354786f0b8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013401c78570d6152026a581df202a27b13c8cd807e0da791565f4271a285cd61dedc3986af4f4b6db64a74b479efaff70000000000000000000000000000000013090059bd58303cdc68152a2e38823f3999da7b227e15a8832f2b28268149b5e9bbf002d0a9ee1fedcb4447a4c696081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a272bd9af5fb317c933c975f2f11a4c3c7bd783fbbcfbea122786f7d104b47773b754033e8056fe00a36b4100d81d9f000000000000000000000000000000000e5bdf44464edb775cb592cda24acf1988b15d0557a04b0a8b7ff93d2f83e1932a5bc9218f8fe94e4cccc5e896401e311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae2f845eddec32d172e7679edeab4d0fd815700c0dd617369ddf4c7c7267373b30ed1f2b6e9f5d43eca0a6cc991364800000000000000000000000000000000197aadca3fd15e77c436cddc99bd623d25c507618a850fc5b438d1525e8e8228934fd330d1dac7cb7dad97a4a11b4cef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c58e0fb254a63c750946f8bd3ffa8766514314c1f11ed73cd6136f1c9dcd085edb233fdee84d01742448675bd42cd1000000000000000000000000000000001240bd1a1b5f7183ccbe0c3dae9d02b1e2bf55230b4d2b625338c7ac3ad6f8d542eb2f20ba076228d97590d23278d9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f06222fcd79fd5949837331b61eb386a9d98f4bd4107cbeb232484880c045d6b55091468e1ff5fd24a8ba020253a2c0000000000000000000000000000000004f82852ad8d78166d6865234d8c50550a20ea28c251cc2a4d40c0d7b659b84b9819724c5c5decda883443fcb27a88901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f7811e2add7cf8b4dab10577ac3c8ae7f0683a1063b20fc23e0191401a7cf07237c6a618c2d654199357456042c1260000000000000000000000000000000007751df6796aad740712982976951bf22365d8ae6c70b70485f2f3ac4fc01ec4e37cd1f5ceaa09541edcba95b1f54c211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001320574bcb16fec24c391932fb92aceea2e6b862772f1dab4063963b877cf9923433cefc18b4e4338c18866294e57d140000000000000000000000000000000011dbded803938f2d02b5832d2bc158ee4f350a6ef1c945d0b456326916fff11083a5d0f0814c1766af3bb99182267d9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8300f44d5dffc241e7598fcbe767279228df42145535087947b2f7ead6d51c8d8c95f963acd8d773386637d959238000000000000000000000000000000000e878732e843de4d6d0e557f3416dd9eb1bf432af6c8ea2c3c439dcad4d35f864b3566491b4e50614e4ad4965531db841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d650a4d4ef2743778596a60526677cb7772ba1df41cb7c962a5e9ab28979ea08f7b51c5c8c8b75d737a169a8e53be5000000000000000000000000000000000e7a95dae68634ee6be82936564c3b90b55f59dc1cabc0e7c0e21a39b376f6b6a11874c5e739400a8e7b90fb1349090f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007771b7c0046f0031323970e5072558e981f844dd8e776f75107973f7f25fe2aca81409aae9244245b2195641eec737a0000000000000000000000000000000013035c533a96a82117bcf5f3df119508a714844bc93cd5ff40d151b4af58a60fbf20053cb4e719798f5c54d838bc8db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eb280d0657b1fc4305ef1f91fb1030c4a82a543c26dc0bbd076e0065efbe284a2fe74143ce5f8a786d92baa2b81fb000000000000000000000000000000000166e75c11705dd841b687d5ea99238b90bf193209e19315c7146d52e42d23953b20c1dfff65d0bb7f5e5744a5b3d3adf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003be0ee0cc0e3edcec734b0da1dd95cc897a1ed8e078b3cf260c67619f07a08db4837cd480c9fe6362e2ae98480d88de000000000000000000000000000000001352a88816cedf38a5d6a0fcdadbf5b9aa6a1fc83b6cc9744c3ffc6e07ca90d51df1d16623479eddff376f99273cb2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b8bd67bb43fb8a2266b98293658f4c707353ad3df04043d3a754adc7628e9d06bbea0cdbb7b406301a486794588b3e0000000000000000000000000000000004feabc20b20fac6b7cb620caebf5ad4fbbfe4a265f81784711d7d342f400c2033213c8147b5f7c0701a7d5e32d5dfec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093b5074e96c01ed6e9fd21693b8016547b17baff6c0c4be1ec9115d7ca16c31604fc90417d0f8e23f9162ad94672312000000000000000000000000000000001476950369a927d9f97f17cc3ce745fad4a43512f7af2c70c7405a5b1fa072a9d6acffb5aa9a9511ce43a7534fdd6ae71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000159877955d3e49f6e5347447f17ba0cac543c24de82e1e971ddf9e745335ca5ca4e32f3ca59484bd6bb690c17058704000000000000000000000000000000000857fa57cf1ada4013efcab045f646dc39a7499904ac45ad93e3d11791f36c46107e4c9ca2d274d902982d8994a0d4401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c6f3f629dd9322d2c71220fbe607ab5881ff589ce6861375efc81748955ed3def5da1e21c9020bc9ab534893973a3000000000000000000000000000000000da198a54e61e9d098edacfb3dee63b0f296d57069d6fcc2888149ec0fc1ffc93a507b69d53d9955d874ed5a14585ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d495cad1b3a883ce7ec2ccf3f31ff9eed422dcc11302cc938ccb8f5b72382b0d1c6876125eee4bf207b659495e5a4600000000000000000000000000000000097bbe69b5e468e70cd9e89b2d314af647672e89d95f4592cc77066589916902ab1b297289ac5087627a829aaa642b661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001279862eb539f6f00072fb14f4933431e6032fa4a9cdf24bc19e34a55a6f8e5ffaa3afd151dff9a9fd53a1737747f6de0000000000000000000000000000000012e1547b8cae6d23aa036eaccddac346b8069536eb7b3a027cbc7909881c60cf8a5b70fbc89902ccfd2d6e4a24edf02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab68e7d11758bdcbb2e2f7345720a370ddf1b3f3839dd9433fd97c37408035b23325318a8ba25df89e03de3cbbd802e0000000000000000000000000000000003f119844d019f29e05fa02b7cf065fa6dce02830c315853e3ff3afee580779e158ea602a08de2efb1462f9440d239501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000706a2d733f2e7ea6a7cc09baa3b9f3f86e0b938bba3db6d619438b2d8bca1184190af9434e69860acf00495671d72f90000000000000000000000000000000018261daf159d2534414d0daa0f4ad3b737ee2cd04ff1bafce5aca8cdbb9fb4774b3803cbe85f838458753b9c1856800a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056b6658d7817400086214aac098438ce97a7230e3496e335b45c5078dee1a843ae3aaa3f7fbbe0b2b07d0a8ec323c1a0000000000000000000000000000000001cc3ed8d20be9fc2ca26aa27733bd3797e53e4595f427f95ec937656b0d9def113fef67d5fc67cd9fd5ce0ecc79e0771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b811af804f574836cf077c4142881e30824aba7e8ce0ad581591c8464365d6424262a0aa47aa90d92e6aed60ac4230000000000000000000000000000000000329a101b1a82b10bdaeaa2151901e0b3b92e514007b13404d38e7bbfae03cdcdb3f7cf0b94613a69bd46dd39e52ef431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001571b940025035b8eba3c82f51559159a375eff08cdd0d18be551c58b32b712de4612149f2ac0a6ba621f252c8b8825f000000000000000000000000000000001438be78e9880ac556278d01b657a218298953d15194561df261ef0bbfa99ae3af4f6803185bc157ac892597df55246c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f897489b5667466c894e05e2ab074abd073185a1380a365c0f3b981cedcf5a6dd13a9f1cab8687bf4a74c510a9d4e41000000000000000000000000000000000d85a13387711329ee7232480095f5acd82a92bb56171dceeb5c2c1e2162b36ea9995ba6b557c874e6bbccd9158fbbb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ae22c38e5b623cd71855feae611d34848461779ac058141a1ecd3f1a83e7f51352e864a3c565657bc4a99ba9f0a740000000000000000000000000000000000ac436b7038e529c7c15d6cee6e25b145ce19b178ad1d54af8e228a4a6299360d1d4e8c26f664c646e6110c33acaa9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107bbd7af85992763bf6e9a46b74cf467e47d0d73b87dff55b481d782c776b7d5a3ef57e027e2337fb517c3ae388f952000000000000000000000000000000001291ef001a59aa4dc01e142f4c8c339c750e5576703b9dcc3094d640dec2efbd7e2e7593b00426c801241e0318d1446e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c788a17792f6612a287ab7f2582d72c90d5bc84bc89c0a5dc9038d679a0cb91d613df56a702662f7220710827f0f6b10000000000000000000000000000000019f80c7b4e69e68ae3f5b420e65b64196336ba301ded3227abf1eee2d4a0448533cdbebcdff2da75a154262c8451c8e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026eafe18c1e5cdb0f659296b22557bd0eb222e89c4eb74c5b21da78682fadc1eaac8dbb54a0aa714e68b288c4cbc2400000000000000000000000000000000018fec8de5cc8107ff37ec319c6a8df977de8bf61e172b71f47262967ea056a3e9d6dc8eb01fab2f5cb85195147b6970a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e2bcc87b4c21b0fcc0fe251eee14e69a42cecee1f180bcbd29969b1ca6dff77d8a0d4601cc25e866c8ea9454a4fefa00000000000000000000000000000000144a59ae421862dcd786ad2d8056ad7ef623efda3aec47eebda9218203220a6a4a31387823e5b9638d3cc941e049584e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ded2e47765593d38861e725b172bbf9121aa8d661c4572989d2aed03e024ae9d3f5945faa347e43b7276330aecbde000000000000000000000000000000000042ed94eb448c2f6b5f2139393ca7dd240ddcd709ba3bbcbf713c216e4895cd29dc30441564e12fb8d0f6c1b50631a451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3042a230f2c44ba569eeacb2d1440712e3f9d326123aab7d8f69463e389f7251efc69680d5017c7e5779eb4e11dbd0000000000000000000000000000000000c6c4bdcd3c33647711448c75c12ea905ed0f52703c4709ff62eda29d554eac990a101cf05f647efe6f98296c2fc73dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186ff13d914286ebdd5ad2032fad3b8941c6543ac1a37e30eada26c41a69258aad12c02a79f5ae82ba0c1be93821f54d000000000000000000000000000000000736e2d1a7078d0ad0537493ae07f09faa1268b97832d802010404b01a7c005f259b14c7fc886323af0f220f884aebb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001955870617b6b85ab13b3669874ddd91b75826c1a736ec2399505496ba5bb1fd9ce20c303c2da60937a8d4f20a4e6d81000000000000000000000000000000000be61d56e9ccc1011afcc0d75621f12b20ebfe68ed8065c244a78c33c4f7b2f4f40d6b172143ed0108ce9d51c874d4bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080f1b3d001c049ff81b253b635c6992eb2961a72d60cd65caf2e27e6bb48fa4bb50ed4d7f9852613afcdf03326852eb000000000000000000000000000000000552b84e59fc41ff4aaed1f3918bf69172e72daae50abfc9f9aec23894022ea3450d5d65dd017cc31e1645cc2d53054d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a6df535871d8034b0a0a036ec42a8113f80fe1b74e5a487c488db45114f5ac9524c3499acf15b49c14821bc2087cb0000000000000000000000000000000000457336046d1a1a2889d4a7940fe9cb4a693ed6c9fb83116461e03bd54f705af5433181f0d47ad196b174b7a094ce7fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017f510a6df7e25ef138c3fbcaa5049c8ac38c5edf3e3fcb0993c8743153255c485b3e37033e215aded48071fac73c410000000000000000000000000000000015994c0b76d039f6c5893131d9a9bcf827c1276ea58ed05417154d51d3a700b5815fe7ea466a992fc22561bbaf5cb0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089711d2ffe689db8a76b4caebd69458dddd94d6502ca8d3f502b43fbe97155bc755a6c38e3fef02ecf3cb3e49fceede00000000000000000000000000000000078fc19736caefe8fe2da2d3ae22f73371a55b3fa8baf4b5b06f91b8baef4e067e09bcc0edce4fed14a109a14be007ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88373362c8ed4fe804a41ee808fe9023e5aaf0b5e341118126f0c0dd0d8c7e75fc831243c5bffe2ec17ff8305eb1d4000000000000000000000000000000000d5948e6c75c4c0c39ae852b412e1474943fb615f5960c3c353224abc94131ae9d5ab8fae576cab9bf2dba61f7d993dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7ae10b09464ea00f1f7b1dbc69486f346d4c72a10a6569add7352ec2a699fa6c45e1fc83fd5505296e2d1982cd9dc8000000000000000000000000000000000ac6402c5c9bbe08ed99e57b2eaff2d69d7ff30d777a6bbabd454a377b2b78b666222e5739c8cebf339f459f5b6f857b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000949d6b7cb74a4ebfd9eb444479902640c2f26a2e402ec0afcd3c47db22d302a55aa39b7ea9fc7e30247f1e7ca821ad6000000000000000000000000000000000890c822bc5db707e62d98eebb758f5b14ca11708a3d924ac7fb3370c3679d0e7374b1ac19715c0ce3638c27e2a877fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001957da8b8c62081952044465c4a7a5cc248b204a3232a3db2a6543b0a680e4abc0d19651a1785f053f5318c425dbf77d00000000000000000000000000000000131c0401b07c5995c3821e714b2bb9c57349d81c93afc1bf95095ea7c3d3959574995f4c0bae8e3ab767b81fc07aa6d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfac923a3f0ba2afa4fb0a7b40b9008c2e62596119ddc63561c83991520b5eb6dd01ea0a6d64eb3152b9f0d8d5d8251000000000000000000000000000000000f80ec93ee30961d2ddc7ce0ffa7f125e5caf70a93c0d1dea764844423100b1dce97b3e74f0217bcdb9a20b0e98a4f381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105c920a8c628c5ee6df811918655734414a11d9d3c8c2b267211382bcaeeb101cf54b1218ee3b2d70bd103d93ef2a620000000000000000000000000000000018183909b6f4ae01b8adf79e8f943d35f606a8652c1003dda0e865da28ac0e5cfee03aa7ab6d119c1fe64cf3ae82eb691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7b6a789949ab6a18528052849366c64be6957112138a4d3cb2e4d2e23e4d36c9c9c73cffd4db1c6e5e4c130a81effa000000000000000000000000000000000f5b34a2a448a3b4dc1bae9e317726363d744318cd95a75be2718b6f2f7ed698ea4584de11f6312b9f06cb97a6a855d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183f731229099e4499ce7612c7ccf8592986f27cb77a37daf0b26bff95f7f5d3be11e5869c609ef24e2353415c644aac000000000000000000000000000000000114ec4f9b935b8b22a9446fedc91a1a827b486aac30147fd6e1ed17ae3f014d40d7ac93beb63c6c9e191e5cf85f53bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001244f72c444130d42abce0086ec4ff444e674915723bc3a76c38f1a5433312211506ee4184b6a39627138960695783920000000000000000000000000000000019d8c7191637362462b84eff3a35404dfbfc773644162557fee58e4eb19740044e12b6c595850eb69649964cffe0e3ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb83b92216803f44abb850c622dfbeda0c595a35925131ecf3833e39f9cd726c91555367792b0563206a8274aa65d6900000000000000000000000000000000019f59973beaa77e793d2fbda4db276b792c859878d375a21778dae5db344cb836f84985c02e2bf942bf148e0cf8c8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc7b92216d265c7df538698d3e67f42346e0d7d48b0637574a2dc398865a56f790360d6d35b8996ffe51fcd34cfc6d0000000000000000000000000000000004169afb5d531b61b2029c951db600aaa3425ad4acc61d100168e54751bc2b3f808d5ddc2052c87bc7a165e6470816a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aab59620251cded56b0a75f70599e7993aa1a2429bf7bbf1aa5ab072dc76ca038077a4f2ec35a733f20e14da803bea0000000000000000000000000000000001bfb1a02bc7971e9cd2a6132dd5c6eda6d35b1cd9441441258959f4709dec0253ba6c7944fbeafacdb53d1aec7194b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f21eef97cacdc21a070c2d6f982a82c2c4f98241402dd430b660b52ebf4e566adbc07b36644a3f338216f0cbccce60000000000000000000000000000000008ecf818f2fa8706424797f829074ca8a8dcd77ec2dcf3104579332b765bb3290613957e7c143c5852da45cc021c4ce71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d209a728ed2ff7a6d4e59743fc1f5f4fe3a1f74dab37d5f96a7997e11059aa1b6de4520a35716b14fc10f3c1fb6a13200000000000000000000000000000000140ee309280024c3a58c411a0c49fc166460ffef8891cfc505bd2b4ab75fa4be812f859e9042d27ad47344394f421a881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e56ab8267ab56080109e7e062bec24698acc1b23e1cabc79387eafad2f4bf798fcca2bbde5a085b68d1f06bcca53a40000000000000000000000000000000002f63a8904fee05c1c3c772e4a06512ee169788779b6b2d1fab5e15c9fb15efadd9269d6e8c61087ab93c3bb863f3c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ffa0015ee1a894f153fc76a42f582c3a6934b818c2f6cf97f348e3745c8787f815ae0e24b9fb2fed2fffdb4bce86b800000000000000000000000000000000075dc304ec95efb1d003d5e5a8f2112035066d085117e2817c944f8df23c53db5800daa1687b0187c69195114344607b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dca360ef287b9834d5f6f85daca79b765d626901e82aea8d0cb772632a6fc5d908972a9afb4a47c0f04704b747fa15f000000000000000000000000000000000709902505613d4da8441e63052bdb2b53fc518286ec92d4668ff2884752fa66d0ccb1dc234f105bd5056a11ebfc343a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148a9292a36ef70952c15224a0c04b605026e58c0c05adeadd3551957cae51f5c2be81d5ba165677efe890791f839b780000000000000000000000000000000014494bffc51402185c8509f29c74d5aec835d855159f8ff2cb6189d6ca9609be63065877804802ee9023557c22d384621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cafb23f4f461ceca20b75aa8bbc86704b4524efe61ff1e2adc704e38ac3648b205857464f7c1c995d3eb38abdc70940000000000000000000000000000000015ae0b7263624365a7678fb13d7f520307522dced26b4eb37be39e849378258ba1e54653272b3beafbba397aa7527da61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f75fbe3b2715efe591b764e09b9b29d3edf8096c80208893eacbcb091edf1a24e51b6de5e7aaf225a308902e9a7683000000000000000000000000000000000eeb52fce388696cb0bad149dc6b41496053e53c7163e7dedaa47b9724fa6fc22477728f0c4022ebdd22e592e202108a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f9984d2aedab56a7843e4b801c3087732993d7c75cc6aeaf7801ef285aff5fc7430c5efe984fdc3e75d58497fb7bcb000000000000000000000000000000001014d5953e8af52868da2a967635ecfb946b3b3dfbdb629e3271b5beb9dbb78ec4d3ee4c27c2cd04abae42bd53859f961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cd2e31ec4d48d76f42fbe42873979cfab23c779582c0aea33a1069339b92edbb577ea4bf5f217a7e4638d6d68fbff40000000000000000000000000000000017d409fbfae282ee8a4bd78e0e013bdc0b1c5cd41e2ba40637be8666bbf92a9423f16d0410ff5529a08e57832966479d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016f8df8dbf74581b41ebab248602420c2edce6a242abfbecfe7ac0f3193bd696b940d5c44875adf78ea855f26798768000000000000000000000000000000000c30e8c3786c9d43947337fbcf14eb3b40156d72a4f0cd455f213bb33b53157487deb8f3523edf86001c376c8a0c746a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000670a10cf742da54bd016333f57c98faef907093197f565ffeeb99befaeb855f8c14a0b97775c3d2661373aea8553610000000000000000000000000000000000d087c99d1304a797e89d59aba20fa4f9e14a9eab0f804b5ff58a1c799fcd931ef0aef3be12662a249780eca2a4e02031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090bac216e4b504ca392a25dab9508a1a21c7e10af9f896649550ae25a9684e165b3a8ecec46512b0127e23336ce71bc0000000000000000000000000000000011a92c450da8642367bcf7ff2fa050ae89307122ab84c54971e0fb560d96ea94e9bebf03661ab1dbf0ee5bd27104d0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e923f26ae98ca4f622e18ca43fcfdb4c67969b3bd1b79dc43855722842fc4085d544c8aa004e95c25189dff5f626920000000000000000000000000000000007ea320d51f2386cdb518355c81a85c7a4a4a8bf4da22f845c232577fe1b20bbd21fc69aa2abf4a913c21fe061707ddf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186d37d78621017933650d22dca11e8cd6535c4e00ff8c3aca6e93582530519223e7fd06bac0677bf37354553d8b0cfe0000000000000000000000000000000014746572098d48ef00a1c323063fbdfc227cb948486e7f11ef670c38649e3f8e2bf8de5a5a408206697e78427fa92a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f9070126160d86737dee5a76532288b4083e4190fe7346dc10bc00128895a78123f2174c4d48ff54be59c1a6948555000000000000000000000000000000000b0e56a982f2d1430ad5e6b7165ff32f865af82dfa2b7618bc8ec1b93ee925c8f7ae5e6298317b1e470dd06667101d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ad7d590eb6aeeca06ec66543051aeb4aa8563309ede60d323eacfb2b0596f4fe3d194f521d05253a392f287f83d17a000000000000000000000000000000000acf7096efcbeb870f588d7935fb0c7ebe3349f0e30231adc90d5e54d0feb47f7940219954c4e10c69d078c5980f3a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112208cfe134e79deba0ae766a41c560cbf5b0a2401e330e477a843d04bde3bf36b8d63b35b78a2673c4bac76d1c49be0000000000000000000000000000000005e852db35397784eb28295fc29aac1592b13c71f8b69e06f4da3f1bfb94c02f42e8b7e56cc65dcc76d7c8073dbdad851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385efc42ac56a1cbe446dc4ba7cc679faeb0039bb1ac0c27c1b05f42687cd457779ebbafd03593c25db132e217851ed00000000000000000000000000000000058807816249bf04ac2a73f3fa5dc9572caa9d5262e917b26bdff1cbd24e92c4d291ce47b02513919cee64f1b13ffcb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e78378c06aa2cd45a3a4f9130e37a57e38d47d076ab34f03dcd1549ff34ea32fb4082b49f3f322a662de186f98c9df0000000000000000000000000000000017fab497e041b494a846d2599c70414a571f563b1ca80cbddb020dee66ffdf89827340852e2ced4abd8979c6508c517a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002689f2da3b72de33c68154bfc506a834270858ac1f8ebecc712d2c547efc3efb832c4dfc19dc0f83082812e870402e4000000000000000000000000000000000b9b4d92d4a2257a6865b6ee4695b48472eae649e5d0203f935d921d89d88f927dc9ed1713b40596b7dff965db9b415d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d81ef768ed945f85b2028e5ead9ba29fc735b6285290933befa4a687d15aa454d9dc11fe45c6ca47163115f573306220000000000000000000000000000000010b4f9de18ff1be318e97dc7d165ca46d17f82e028da544fb7790e7770fcf06394bcbe95108120e2095a01e03dd465651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff0d24868a22904416aefd8a90b36395ecbc4cdda7aa2aa01224c57c0b67629c0ed20653b87aa145d859ac87681b473000000000000000000000000000000000dfa71092402ddec640c90394281bd19fcddf8a803f302b560b9f3782ac1f316a1336ba2bff3ccfb08aaed13a6238a191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3f61a4c5490bcd060dff8b9c28a69e28a6e8a9a326fe3c66d299a90c5acad54ab41c5b7c05776f0fdb1c39da92ae6e00000000000000000000000000000000074e925cee5ba0ae23092abf9077c7a1927f506e8900d8509f1c5b323d74a38c00d2501ab7c4e9304efe60576cec795b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000838180d3608bf17d8d949de03d91b1871e4a58bcf818861c2eab572cf5625a30a076ed0560c7cb41505e3180cb656c400000000000000000000000000000000056775595c8618bcfb11cbe62b944e67f3397045c5f4b07b65d595bf64726fb87ae300b8b81997219dbc4de1989129671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b5446c938a0fb70242c352eda8c92acb4863c8496f18515a5840dff3bf2b395bf6df05cc6aa7a76e21a69e8436541000000000000000000000000000000000f026a9d2746d99c85dbbf5ec9f7ac1347e218bc3d2cd5a4710bcbc49bba269594eae8ba9c12327aae788e8d654549981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066bc772b99db3993c1654ad0d65ea88bff1aad0c0a714e5e82490f38d2154e28775237767c63a01288ff5eb0ea96b1a000000000000000000000000000000000134429fd827d0ce3ac96cb657113f278c15f9b18e39de9eee11fae8830c74bf2bcf8b1b0417acb97abddb6f64d9d32f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd09fed3eeff11b1b322a47ce3299e225ba9105f39916ae3f93fdce19ed756ca95f7f2408c88d58b80d474ae586e300000000000000000000000000000000001521a6cd2d76e935dd07eb511e085a42e96ab17fdae1d1f24413a743e99b9d2c85098fb88b8b72b4f1be8099a5467ceb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004eb4dc68a9e222fa5e97041037a7a3312f62d68a56a9ab036cc2688e202e12b9b48bbb092eda4f4bd2888c0365e3200000000000000000000000000000000015b50a8accdb228740ac42ea6cbad9e9df9d9a69b78697e963efdf918c787a1c89860e3384c0d13fe1d319bd1edb6d681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe49e93887385140fed86f065af5f26ace2fcd0d2b70f77035814849f37c7a918d443d7f5fb5b4171f2bda29b88ae220000000000000000000000000000000003cda1c7b1435c91c389057aaaa30c003d79a5d5cf377729d9ffb0bc7d14857413818ee3b5246a966d44a4d26d1b597c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031c9faaadbc4c938a2b549415590f679d6af42bf09ab11f0af1574dd2f7eef0b48e9810c40e6d2341a07a1388d366770000000000000000000000000000000000251443a2fd5c59d8ddb5e41447f1f0946e69a9ab6be208687d792a120b30d43938a1f38b8d27ecd982cd73b5fe5bc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e2bcab95827afe4fc5313ace4349fe3e09e36d031a2548d6a5185f84857e2da4bbc215f5086ea461632af3d2b5332000000000000000000000000000000000a532862b949400a91302a94add18af9dba62c24e7b497d6ad134196d4385a618a474fd0601639354ec25ad3dde7b4671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075c27f00071971bdc1adeb1048c1f98b1955d603c4e4d69f74f66d2544a9a7c40637259136ed758cf7eda2cbeb804b6000000000000000000000000000000001279311dfb07bdcab96ff341d28eb77746bd268f2fa3492caa0f02272b17043e09cfaef088030c3fa8324d756ced66571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1189c4aeff2e004e7d1236888bf741e1439499fd268581bb1b39fd0ab553dd6bb6ade98363931fa6a7fd74f4d6fb5000000000000000000000000000000000cc6f85c19c8f1fb460e29ddf7c83824fcd545cf72b56dffeaf0f9a428ab2cd71b70172e60f65b52a92e8fa37d946cb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012146524ccb8cb2faa14a0a583268c21ea99d55fffbd3278c80a93ebea010494906dca2a3d5afdce13083667fff5a06200000000000000000000000000000000000fc213a3f4e5363af7a4d8d7f62a54d93264cf43b55680b6c706a1c4f7efb822b9a6c3c0efcf9d2d3c8b414846c9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107dcd28e7747c54f35dd5db9e5263caee70e9e7dbc2b7346ef32c821c0120a2c880a8fa81b0b6509c66bb51626e595e0000000000000000000000000000000017e2012179252de5172a940771acf02de4d94f29eec013dda0090fa48eeb52e545141b3ebe55d65abb1f885ce0b393881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a94e7cd33f053c0cb724521006dde9a0de77af19b233028efe7b6a5682a22d46a02cda55526d81ffe4dd0ff53e9d6700000000000000000000000000000000163ee20bf0a99b09c776b4bde73de92e728e258a51d5b97f4ba85a73931278dcb87425c69d4105cd53b6b63de670a3cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033c33cc3fecb91a6ae3607211a1863e35c217d66c2acc619423131d3d99f1c9d84c16c3f3820f1bca68b31d5ccd424c00000000000000000000000000000000190a9bf5522fcbb1e47d2eaf36efa78029f303fc075cc1ae07c4e2ddc6c35154f672c774c4a44544b2b0c7322d42b3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000289e570546f4808cbd4756f826eeb12f92c86a449e1f4506b033d8083ab6a5134774e05c67890cd4b4d16800d287af900000000000000000000000000000000137ca623b609fd1a1d77323fd4d7733ec91bedbdf2429834515432acc80e71c99772ace4d1c9db37e69732bd3f86448b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eda3c665e9bcbb702c9ef2d75a64a52efbef49873d223635ba3935e02708c609a9f3e667d84216ea242ce2be5898ee000000000000000000000000000000000ad8b603b64146101f8c91d2d228068fd7ad13ef53b7f670a52e70357500ee06c5bb3efc2ebaf2da27ce104b384e187b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001620cd8c8df11fd329ea5883bbb7a650a7b28d617e8887513ef0f9b046d992444e679639d90e6bf9b487b098e7bbe30000000000000000000000000000000004d3fef213cf87d6c0565726c77692f8cfaf2732285b32900bb8f37161c03fbc1d45a03b2106b84f79fa31ce9a2b8ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e8468fcb361b3c778c8bab018dc4472e999fecd0ecd9e71f488eff133e34025bfdb61bfed654ec68f8a2eeb08b2479000000000000000000000000000000001475667d8951d22ba9ce0a6eb2bef69f6c48f4b835ae66475dea344b1fc6260673c67b134155cbb200c7906c63d421e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011308b4a03b10624febb2e22b3f6cb66aad832cf35c25684294f93cc43c667c4e91d1db273d504f75f0bb620444e686800000000000000000000000000000000000c3886ab30f6e662dd52ff2122234a833a2a3592f6955719f548b12d45effdb31980b94c25b158972cc16c108b79fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ee50ccd4e9226c1c850f945f6afcde9caa3101a368d0b9df4138c4e86e01edefc19d359d03df76b5229731c26103fb0000000000000000000000000000000008dd3f5b1096559938aebd26eecdcd158333bd1ebecf2d1776298383fb7c15c66bd8c645e87b46c1b7f74a1a50ae5fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012eb73b7a0b284e20b2f0ad40cf151925a7e481fc7352f0f1de5662176afe777080c63502845ad031bd1fd99bb4ea0860000000000000000000000000000000002c004ee718a84bd638fecb7755a3267b0908f687b46fde7f8fd79ffa6ab5deca6eebfce3a8ef6ffe15dd293c54aeafa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a3a94dfad2d1a4b04c593a6f38baa0f254bdaf1e915c16c81ea930cc84fa8ef2defa91e34541f7461ff17cf9b1baf000000000000000000000000000000000474806abdba6028f13ba826d1834ba3e5a7211ce582b99a1b1cd81a0f3522e21e28aabcef79094da3af67e30e5a19551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009b1d23d51829ec71a6b43ee084bb3d4fa23b1ff58e50eec959e6701ac25082438547522aaebf4c7fb40a81b916b71f0000000000000000000000000000000008fc4226073f7200c08865747c249e8707a24e86c34e9face84087781020484572e4391fbfb8b2ac8f8ed4251808358c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158ead58549a811a68b149c23e2e9508ff9388a5143872772a91245a5a7e09540e41fd37e47c7b767982d2437938909a0000000000000000000000000000000019e35957349a5be78ea22f50ea6ad9f95becc0bd440394344126b718681da15c4840a3a4dbd84153f31bc271de41eeb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002803cc9b2390e25712dc32263c6274b6e9e5ed071cdceeb68e61236f686fb7a0dc9bd4f83dfad457f618a6fe019853d000000000000000000000000000000000bc276a62de0b0f3721570b5fac9bdbfaf7e755b75c54f48e58330b7866ff5360e1a7919509cbe9f152ecbbec12989e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017233f007e11b554d20b4c66d506c826b53e73c5aa312d3edff95906e50382be6c2c30012ad8baa2a61828404f2a726d000000000000000000000000000000000c0dad0a3d241480c9a357bb64dd0d7da96de47a660a6f15ab5caed1aa0c09de91ce3e5c4e43a0333585acb93b9f43701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012df7bd0c4a5d257048f3a260674ddb979dffc43be8c527f1788f56aec89a2b1c5e199d08c9e4fb93a3884db453f763d000000000000000000000000000000000ffe3e828d07ebd5bb9ab1225b9b04e82137498d5864c206489d160f65d7c26eb2dd53e315f2597190510aca4cb728171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ce8e21d56a0225f99060d2de3450dcc7f0ade73ac83a8f33da339810b6642a8e6e3be4e0ec45f176ed0ce0bc2af143000000000000000000000000000000000e7b0517db283a0b65772876f9dc78d7d37f2072faeddd0dcaeaeb7e010166642348ee9087eebc1d16a79e5a17b63fd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9f3bf0a55295c28b9b511b0611f6787dc8279327b0a0378e929e2d97601481b1b31ce175f1fdac7bb62ab10928c42f000000000000000000000000000000000164d709d890005f1c9b6292a5adad2dc5d740251a807c1195d12f9a18e0554f8af0cce4da0d5cd6d16a51134010b0e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fa4fbcb74cf63357ec20cf5e389528b0857057f827b22d7c98e5bee335932b7864c13ede0ec3104d97762c964c9ba8000000000000000000000000000000000c76d4601cdc4562bfdce0934679a3cd93e99df558948d488a6c05d5de28ac9aa34232948d39a4c92f2d57c7f0d36cd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100404a0c0e1af655a0c170af2a139486dd8a5a950535cec29980a34e282bfedc42016b260c002ccbe092e72145ee93c0000000000000000000000000000000013d48060d5b7e8247caf74a33f25c9243bf7e6c5ec56e1bdaddb11768f41043ab8e6aebd96885319676ff116feada7ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fac7395754a061a40ada34bad9b0a1d514835b12e37a3561108c41e1386047cea53c0fa6e8796381b1ead5eb23d7d200000000000000000000000000000000190a1fb5403a9cb118ffb6acab4077db18f42209acaf8b00e8acd9dc6267c3e10e4ff10787ca5831031d2fb5b11bf7b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012c6e6c14cb1ff68552f7aeef04aa9a70236f0430cc6fb0920c3d4788330db7abfa86a032a6583db0757fbbdda6d2520000000000000000000000000000000011bd63ca71b181a7ab4abd755162932724a3efc37e74569d55d59b2be3f72c79a185c31117e50bb8d8748501691f91021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a0271199d1bcc10dc730c7ace19b9bb014b3c61b1c331a4ad79c22886349d59caae000cf4db5cb5e30242412523cee00000000000000000000000000000000089837f08733024f44cad0df5c41b4bf4e6a326322e23111d4c433fbb7ca3ec47b4789f8b267556d078e31aeb1ea13411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381c75f43acd9a4677a7ca01a4cfad06f4b9fa6d8ce7b762d51deb0b2e8aa5ffadaaa3ad9aab3eaa327c03114a0859e000000000000000000000000000000000452658ad02a7a05125264b23c79c52f51162ee5bae7e0cb45f360759cb1ac4ff61c6350d734df51ad82a685f6b5dba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174bfaaf7eeae079a4dbfb55cf5173b7aabc5dca2d92fedb865a808bc0e23f74b696495f6732e7da79439a81ac149ef100000000000000000000000000000000056f5f1b11e65312543193826c5fd20d82b968cb122e1c6d41e294cbd2be551be488395f556c1c506d39eb16b04659a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012bbfe66de85a349daa8d17c53199cfdc23795f6272ca82b744517da9d1faaa90ab776d7de5aa1b1a83f1ff8954cf9000000000000000000000000000000000144279a62fffef383e2da43956eb39e4f40b3c36f6fab6ea36bec7b84b1fb6b61cff770858a29cd21c27a36e15bb1ab01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000853295f0764067431b1316bf6805d0bb095fc2dbee3ab01e21660863bc7b23117d1f49864b5a73d4498c277db5dd0bf0000000000000000000000000000000006d9351c0406ad31ec8e6fbbc06b00d1e8fc46dac3f1a3fd13f8c1757605e36830da693ebc2cafefd808edea627940c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc2cdd95c24622fd4afcdac5d4142e07563cc03955dcaa8707361535203f491584be38e15cde14c503565228eaa827a000000000000000000000000000000000c4ea0c587827edec68c5929c01f9b5f1de331a678a8c8f397f5736b84ec9b5a66741f24ccd1ade344da2782bbd192891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001903fc58d305ce920c122bda8957722a44b079ff202166d0ad4a766cbee356071f7f8f1f40ce31039d13cbb50da29d290000000000000000000000000000000000412d1c9fac9d71856412642b1c6d04fdc219641e59f35ed9487c7c913c337d80cc14d4b0c1249cbf0be5e4165da1a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000541dc34735d759c76a37bb006f3764d89c8022922e4799d503675d852cec5347c390e820a77c5c018200190649e4b4a000000000000000000000000000000000f380d28edf3190fb5c5af561779f472c3f5643df5b712ca50a85b01c7d7c5894d608fc407a635a2354dbd3ef7ee8ff01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dc81bab958902c0524ad80fec2a6217ced5b7d02448320dda3e2851b0a4395a1c87c797336f60dbb556d227b066e0b0000000000000000000000000000000002627a45cb80fdfd88879b68cbc0585f6707f80ff17f9ecf3857dc24a823f9e9bb9875d522f4046f48c060e2173f60101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dea9e366eec167c68bb9efb2418056cb640a4dbccb3a2bd6cc04a09028c4480a7d67a13a4449a92da20157061f4481000000000000000000000000000000000974660be9f31d459b6da4d4c9513b182412a4667085759fa132e09bf1c5f6916f38a6e89ad88c811311082c36fed24f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ff52c533b191b21255c9fb6f827f84a5e608cf4688afca81a3b27884f89cbfde0d9d827bc6116aa4a67f7ba239a85200000000000000000000000000000000190b47bfadd25468bfc62e068487b0a84cb3ace1a5909712b91fb30f60b081b1e93cd7f5fd5afad611717cf1c23069a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003854049f08e771b79e54bee7c1f6b3dde47120611bc66f002d037e8823cd32a81a7ec836a72518b5379baee7e8ffb45000000000000000000000000000000000125414c959e3a1d0a78bfba9224b147fd13a04e248a59c3237b65c52df290d7b9a2afff736b05403b355fee95d5a9d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47ec0db805e4e3774b5e9a402909bd36e724d0820bbbecd0ff07d6ea039cef6194177abebd2cac1c676683840f14430000000000000000000000000000000018662c6fa3992c1bbb8ed23f9ffc816675667d99ed173eb8dae02015ebec2691ed615d94a82f5358f63c06ec080792f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001273f785da39204f8596647aada492bdbb96d2b22fb032a344c4a2d114456f431f648463ba2daf931db481864e9cc47f000000000000000000000000000000000173104686e5ec28b7a69ce937d1b26092e964911d42f5b66449314b27e69c12cebff23c8f3405d190c1c234651f94161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000819cbafe4bfaca62e087d8aa2d4e338fba0c0b9f3aec65bc90a604f62c1d31334d101eef4669e71a6d8850e9043755a000000000000000000000000000000000d46ec0b7911c29e7a874fce5894a41c99fb2303174d58ac1f58b8978ed5844ebb1c38c01230021c0a3b81f3858c912e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001016c7ce2847822d00d697907dadc87d93ffaf78c1f3da31a33b8fa33b56436f1b2b15e1a4810a2da092961e8d977150000000000000000000000000000000000f52c763bf7d67a07e66685bfd6886af1bd344cbcada7ff7e0371a009368f023c567b1cf7e0c5b9d622c1ee8bcd487f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023cecb99effe9cd992f840d86d7226b304272e3204d9fd0cbbaf0ab3be07d50ece62c2bccb3d37065074692a7da706e000000000000000000000000000000000b8690d8ac8bcfdb5de09f2cae1d96b59246b0c7d437421af86b77ea3711bae6dfcbe4a44b1149cbffc732df7fc578bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e992a2a297eb7e63f18200affb11f5b8d941a3adfb9554f404f65c8f28dcd6f9bce66eabfddfdc6d202f6f1d33314d0000000000000000000000000000000004ebb686b17428342097be1748fcb770b75bfea70a79316f3840bde2ccb133c475d5d75aa0f36cbd80d38397f53376781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007875bc16666e6709dd75b187719ec3bf2dea732b3938c7adb37771d6ae836c7e4640389ea67219f971929710d1e7279000000000000000000000000000000000147476ba3301991e9f9a99cbc4345e70e92ded560418285b7a8a067d965964b9f7972c86f3e0cfe41d502d1526f34d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da21077f1534b46eb5a09a3e3efbdbe951b9098d803ebccc8040ca6d6107b4de658c7fb121d31dcee1b7f5d3fc3258000000000000000000000000000000000b8a0e07c99803f312da487e062e79ba223cf14dd5fe9c86cb3102bb6a97445c57e21f7f34415b21ff4b891d396cff1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1afd16790c25ca44f7c9616b7c4d58d7d98b3cc90404290211ed3bdaa7570be4b48b4684601d0178e031ca6fcbee1000000000000000000000000000000000130f7575f2178db4e3939cbe9bb6321cc59a143ee65ca06241c19bd8181b3fa281a27334307ed319336ebebcd771ce3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008febb3ce1404a784213246520299c1956196c98aae7a2c64389ceef9d9e8e8d73cf23c44f9aa00e4eca62d619940052000000000000000000000000000000000b4ffe3d6ad8382c64d011440c48d3f3ee5c81f0e3ad363cad047919498199758dbe01bfdbb1380ef1ec104a02a2e9db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001392960b7e8732af5ac56923e9ab4d1e01cda0429eb84044226d359e2ed726079e854e91e5137b481accc8cfb3d2179100000000000000000000000000000000061dd271bdfef68c28c8c387c7e0ab17ac6f595f601b4ac416e3044c29486091dabb00b926268f222b763879dda604b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87046f2d334c3bebb0e124721acae080cfbd94b49e5bcb5b348dfb3a2621f5a1942f879a2cfd0350fef700328ae08c000000000000000000000000000000000980b518b0e5d3299427d9ab709c3c6e86d7567c483b4ddbd2bdfc0f34990902a20128dcd4781d056a3b59ef993151251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178ec0d791b7a74d4ced12970c7a57a3b310557dd90a05e7d5044c4cbbae3461194738c990a10c2faf2d84e82ad939fe000000000000000000000000000000000dba49d8429a64cb503746f41c24bdde9776c930c1e52049e9c1179f23d2b3532c4b754d74f05619b94a642f007f84431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059dbd83f88c2321dad43bc3d58020965110cf77d62a3ad59da908cf4923717e0990b9975ed14fc08a954457208d6f26000000000000000000000000000000001512dae817be1fdee54ea080292d3db5088af28ca66fac122eb6ee858d20dc38685363a8d08a9a1161cc120d552199a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019df95d91d2c55546bfbb5706f0cfaeb25f39a50500fedf4cbf2f5635bc5055aef8120f05172af7a2065bbe978baf2400000000000000000000000000000000146917c9e5a47135b6c6ab1b764880fdf88fb64d5ea4021c9b692213668f902afc89932041a2c917f2829f10a5b690351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e8fdef9cacdbee0a23bc17c40943a68aba8f8d77a3a5f9f326b70c7efa93ee0c7b100d04529dafbd256e6922ac3f3d0000000000000000000000000000000016d765cc7fbec579bb89402e553ff961d4f19cab4fdb2a24d9c8862146658e65d5ca536457b0bda73ac8c3056fe7ece01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684699568b7748c179602148c8ac337fc90124540c6732a58ae320813e4587b1926bc729ad0f4c1902a0824ea664a8700000000000000000000000000000000012db1c6ac720a531b674c190354f706057fc18b6de1e7c7b1439cfab52c696efe4194dc5980489b2ecd7a45ea0cce181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015df458d1cbaf2d9f9f2cc92e6f266243ffe71505c2d0267164a5da78cbf2c2d0d9e8b70d10e3a254f7103f75e4ec84a000000000000000000000000000000000cc409c21ac675b66a3a53e90b125a499dde3457d07d7514e5757e3c166d40a77a133597eb2cf9bd3e506e8ccac84c6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e399b33cca2a2ca53b01b51cd1a657c729c711e9654cde8997dea0408b1158e5a269b1ee419767176854c30bf2aafa000000000000000000000000000000000305efa1b778575da8c5d116844a290b288ab119635d6efb2badf848f17f218ab1490aead65940b648d42473c2e29f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146ad132049e31f5674161eb7583e753a0981c89939c7a2f2467558a326a816007bf17bdc14a3f6d2fd21f77cf4b8516000000000000000000000000000000000d70a9fc5663eb6210b2ef7e60d6ce450f9776cf4d5e845d46c99d158cf9474ef240fc7cd6d3450b9bd60fee6a6cb75a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148da33cb66c0bc4d40d8da6ea26282b54886d266a0a2ebe5b4a9d6d43bf050e5e6f4a6a786d2c025b46ecd67850a33a000000000000000000000000000000000ee3cda47faffdd87ca9f985947345cf858f4dc3ff75707ed18b80486ae0bdb12e4ebea73c36cdc98e40c1c1c697bbc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba0b7f8cc0333f39d2ad13b760b12b6842641bf744fcc581fdd8ecb0f7f4991b9f2d272a2c19b688bc22f0504898f190000000000000000000000000000000019e5e5728ab067ae4912e188eddd983faf652bf98d02436455fda76640ad94be32edf17aa7c65165d9aa07a0dde0ce511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5a5fbce11e265d90110cd27a8a5dd44e84afa9b47b202d59b2e2494cb3421acd8a5c9ae626f9aa99119a0a6c057c3a0000000000000000000000000000000009ac6c7cf39ad858e884c60a48909f8eb8c93772293b672536b12c911e63c5088a025c5d0b651558c2ac4fdc85040e7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b8a3230503bf9eac8fa142e8d9590237d13f27243dff1e55329268ca81b9c8c621acc1d749072f7476b9b6993e0e3e000000000000000000000000000000001803f22a509c5b6f1e42e9336a9699acfecd62e51047ff0fa34edb29628814733710fa1ceb6709eca69f796ef747fa8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001441897d50b210b3ba99ed0b52c1f2cfbb842682eac8deafe16e254a9fbc0863c4e734ae3915b64ad1a66ce0d9a693670000000000000000000000000000000016ed42a66f357aa42f872ee51ee6c252ebe6dc1cc0c4b1d46eeb63dd3121bfdf46beaad106cffe7764ef5749a8ddfccd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2048229aa7ea8424b2cb14a8e5f06fe534c5a39e3f9c094876edf9cfb17c1dff605d34e6f4a6302a6913464a04a070000000000000000000000000000000012685db80e805efeb0daa21b847f1b9dd540596d9ef3f3f2c610c8f517384c96ad4fffc1e1c1b19a2dff755526f0db851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc120f58317c5f1ac1d145a0f40d3523679d78e7d7779b5e5f7fac66394b4f5ceb61685b2556ac1c62630ad99f9371000000000000000000000000000000000078fdd01f457ba3d3bda62be7beb2b780fd4dbf2620128cb18d5e38fe20eb352d222e7c710e4c43fa8682e60a08a0901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001210389741e66f6eb55b79f8ad96cce4231b76ce7ccb0d06b5c05dc88c9c26b64250c11b50d1acf60fe4a4b2a35e2fea000000000000000000000000000000000da04e446d92f9478bbed220a2ffbe44fb2e74f5b04d0b21a52ddb5e6c3abd8a42947f39c0b0dc07c9a960c7634597e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a19ebe1ac3216d222c92e6d674d38301c2f36ba04ead61766b6ded9b399b9ea4d47c643ec1818286348f42ae46edf0000000000000000000000000000000000c42b3f4ba530cc92b4503112b35618ca22fdd60460620cfd45143b73409396cc5dfe58bda6c13b91e17b5acb76e21091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137b5696c27abc84458c8a2cd7362d348c4886e6246751c188b5a46a5873c79fb13c0cca07993317d40baf87c35f380c0000000000000000000000000000000019413c058f6dc565a414b4bc73bde15bc12fb43348533d889ef4fc276c62329462558a7cbfc55bff6555b82152343a951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006fa2dd6e3ab26bc7a44c634b052644baa4ef5cbaf452601e686a3d3e014a2c416e5997baa70e59c48367c68b293a2a30000000000000000000000000000000000e7a3ae7fb86566575087567ba2405cca2ce713057bea5d324e126a4331f3f1c10cf13075d13ae4571e372d708614ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000733592cf60a16fdf4d83a93297e9248c70dd3aba8c950cc7f6c70c782a6fedb8c1166542d2b1019bdc8c6c0ffe21624000000000000000000000000000000001593170c3280012f0170dc7d84be2676d0041eb8298269005c80c64982b16694f39dd3b9d07fb96f10ddde76e019354d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053e2edd4fb2b57802d3caac5137abc025a463479c2cae77a5358e6e010d5e26c991f0dce0cdc87b318a04b258cd1f87000000000000000000000000000000001645a1957f5b267ba8bc83843eea174463c0d703dd12ef6383cae06ec782bf60d3bc8fb110c50a52c25bf029bfb383fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dce55d05fbd5a22c31f1e446d7658eddbddbdcbdfa8836e0e1d93ccaf380fdd0a043fd9ca9e6b814755d7f60d99f9000000000000000000000000000000001716ab66ee96de04f573410d130da8feab60ae683ad2429fcfb9792eeec1076734f4d66ce6db7d63cbeb96f3c7ce2e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c99a2fd35fe5e0e860762d74098bd3608101639a881ac9d025f4e8b0b61352bc91ff03ab51e27293851832c1c66ab9000000000000000000000000000000000cd1088edc93c45ea7f80d4cf9693adf87871b39d5bcc514e475b5c78052821111c4260bf7fcc4cab35ceeac080cf4421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b78d29a1860396d08f7898de3b46eba45879d53a205498959441bf1072ec6e23b3cf6493469eadb9fe2cd421c76b4e400000000000000000000000000000000116b1621ca40c598fa1e9886af25e7a882a3341ff75f4146a3f79805435c6c9d516ddb681c9e044a7cce2f52eea9d7c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0186021eefa7c930d48fb2008b8c8f2458f91c08bc16216d677f77b7ec913441c057efc2490f2c83bb5ca28bcea4920000000000000000000000000000000009a6ec839758efce3ad8b29af52a450f3ef84ee37a1eec54ba52eda0e6acb2cb6e8884896b9eae94fc6cd3989f784b641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082b8f9133eccc3baee10198188d3a3ad67c311ec8419afd63e6f9767af82f24f032d840fdc14137f9ef9e0883a7b4c1000000000000000000000000000000000131a10cfec6efb1566a600c5177ae6b78ea1239d1f6e76d19b9f36aae7214242fa1796892750d92793f6b6e191d34441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159431b25e9d2fd86e441921de5baf52f79442ef0eae41b68c9d06793d38e334dc04ba674a2eacdc373c54063c4e465900000000000000000000000000000000075b2266665a3f6aa3586073a167a8403fe0266cdc6a54ec7f284a043ae62b61f402121a790cef51f5857065074c47a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007722394c50476ebc7dfce5c7937851a4a77cbe38732c9b6ef6cfa5b2314dd4c3eb7475ed1c6cb617455cee653bf38b3000000000000000000000000000000000e78a1caa5303db1f7277d50154af087989c3a4239f2c0293663692a497bd655ea2a1ef39aafc3fabc85c65870b46ad11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001901e5eccc5fbf7e48ba8666e2d18d101312ac0ff1aec2e8ddf80d6c7e679d6f95a5d4ea289b80036811d6f10acbf1e8000000000000000000000000000000000120a62ff4e9799b886dac92f119376b19be0918ad67c234eaa86b877958f1e77982054111ffb93064da85a7e5f5510c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e86e1342b517d7774620114d5b19bea3752d052494d84bc944dab2807c1999ddb023816a468e22b856478aafb496eb000000000000000000000000000000000ac9568feab0361cce9bf4278baade58b8192d4333e360735f24e14e9e0399f387b7d6aa8f3349774a23fc342e2dcecd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000689716a41dbf3b23612afdef840922b558edb4ea3d786b81f4fb5ab94ba3e01404aeb5170a5be30179977f0e019d514000000000000000000000000000000000b8bf283b054b3245bedd9f534834523af2b5e2cbea68d2de813c5bff81764492b47b955d41817d8af2f02c76868e7331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047770eb09b93054e1e5d59ea23c5f5026378f84f3a35be9f288e4d5796b1c115ace6c6c36ef74b84e3a97aeefdffa8a0000000000000000000000000000000002b52e1575c7d1a4d33cb720fc1429ddefd4b5428f96ea2237c1df3110a2a29ed1ce6cb0732f5f834164e6d97e9171521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dc9c74edf387a46bccabc3172b46f46e9163c25bfe30ddc02c7a88874c333d5804f3e97cce2bde43627ddcc4cfd85c0000000000000000000000000000000012c7c98ae66f4d6977abfed3460a11853f631524481d9f57b75b7424061a76a0d4cb8e7a6c9bb03c17f104a6e7a271f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139a42b6e16eab536c4d27ef4f95abdee9414324f9dcc9690ba6fd53565d1b1da9f211cdc4a60bb96060c030243d93370000000000000000000000000000000019cc3a3e001fac565940b331430843203469c17af9d2c796f424d6c849dfe0bc03fc6b70cf67eea2aaea4626bd2bae4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011223fd60a880bb259554cd98c8e11e7310017c16d731bdd15b1cb7e1b1385f44fa5979a60b97ef1356613a81672a1290000000000000000000000000000000012976c0483c6839f92c5fb702c73181d415fd681a5f3a16814f45d080aa9e0b8a1031c92152a4f8a980e0317186cb0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078753794fdb85cdbea4cbc74891a7895624885e51d09c24358f6171d5fdc8717ae5ce331ceab096b88dc7cd4732717b000000000000000000000000000000000fc328c7422f0542defa870dc968796d8d063f448bd11fe6019d891bdfc7f265923a0fb1fdf475165e9235365f72c1191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198ca1c512c1312c33ed3d95cc65bf9c3ba58bcad5d950bfd9fc4a24fc271a715d665813cd34b15abbe1d45add1b9986000000000000000000000000000000000a3acc0d8297f302a1a336fca51de16e8eae373499b7960c7f1e81ecaaa8b5ce9a9b540a61829c1d6840620660b5c00a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2169a37feba05c4f3cb6e8bce5e1fcd587bdbe87abd58f66d6455621cb1c8027bc3293fd93185483f8aa57758e2c39000000000000000000000000000000001540efd6ff350d53841516a5763ad2257ec1bb880cbed1c6235df6c9cce5d49a429b7a12c5735d279e27a0615caa2eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091009c5a5d3940bc98a5fa1ddf195673c71fe86c5103870feb30618f4b29b83fd118104aa21ac7770b6dded4904a9c80000000000000000000000000000000017f8b697e9b057993be628040eb39df0d77aadbf4df36a6ada26e0dff9c716f00ec701caa37379a504102ac57000a3861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002b43018bcf395dbcfd6b465d0ccf78a691e389ad0f9082c00fbb5d7d2299af268f57074b5d7f72bd8edce35ebe592000000000000000000000000000000000093b938a6d95277d711055b5f2ac39db305afaaf39aab26cfb6d00f04ef33e4df62d555e47a0021a3ef80da778bf58cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9f958aba08e01dd28f62d54b8b1c37653befb36606bd8a18053d53b6da8d751ed984daf5a4b9d19a9de65f936fc54e0000000000000000000000000000000014258f6b0c40cbc332bd980b0e781a4ce62bdca790508a19620dc11c72dd0e81539e5a9a083b7e5e2398e735572269321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d734564462983eeca9a7ca5c3475e8746ba2d197bc06812f79259518b1ddf2feee452f80a5ec37f007e4ee03668cc36000000000000000000000000000000001970a2c52e7195d585d49ea982a7f22fb0a2214bcfcd6676452df9f4e0732ce4128ef19d2f1d9ead2adf913e8fdf36ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ff274406abc579fd61f80bcc9678c9175cf4721ffc42dfb049fa993496a36db96e6f311ef64244b717c6140ca1f45f0000000000000000000000000000000008fe505adbd27a4a1996a8d506d2eeb2dc1beb578d4d3dc881d1a7bf4233604919822602189cdae7888d4f139e47b60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fab864f836bd63ca545d854e49d60d2fc46ef81b3ca7f48d3c9ece4ffc602d57aa91c9faae7bf51a494fff329d6eb6000000000000000000000000000000000e6b64d1930e4d26176951f49e847c16de5031ebff3c8a0e76c9b315d186004b9d6b67359d69e2e863a9b93da0ef8f2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da15eedc5a9f943d548f98506588fc4ad8ac7c4bf54f6c137ea29e9facfc35d3012322b086594412175a1edb0a2a3f0000000000000000000000000000000000d559c4dfab7acedd8dc97230129a688af4e874e43281b4ef7738f2075d7f2a64a10db1dcadb3f3e541a4c3355d198fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508d39d74e7718e4ee50bc29a651c337f1e1ad838d68b5664c5da58e28a4754394b1b3dc6a298e7febb2e8bf4c82258000000000000000000000000000000000e605cba8745acd1629333d24d20e188f0edd646fcb525fdb74ea8d860fca66cba5f85d7d924a21993e8ef729b0a640a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a86eef6452a73f29089e5471fd1c70b9abef3968a6c52e747877b958dd33de9b4b51cd617204dcd4b4765ee35150c2f00000000000000000000000000000000092d7edf7866c59a58e9a46f8a644f2d6939ace882dbb6012f1ea6b7c45e2535b8f30bf2c92b3974c1c6f46e545ee7ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031220713282162fbc06d1f0c907fadb00f4d8e76cc1d535b7b6ddec53583e2fa5480db1c5dd3744cd10a2eaf7373029000000000000000000000000000000000328f9f0b607caf0cf344f010cc01a6619b53c6754b1d69a056dec33bbcb935b5fb30a9a607d5a77f32ea352cd7281dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095f0c23c723c191343232fb94f78429c0b1a4358a2909ddbc0fa1c551d49fd9188d10d656a554a9502fac1c4ce3075700000000000000000000000000000000034fe6f5e96a53036bd08b703906dc036cacabf7b88e808fa20e4eb48b192d1a68b327e12a3fc01ed0ad228b3f6ade9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001530537e6219752ad593cdc36fdc341487980c2fa4b2a222f10d0881620238d06dbdd40c4d1455c20266f659b53db0670000000000000000000000000000000015a3ee553c5670805471330dac8606adf848a1aad3b3285b07bd701894520c33702da3f6bc245c60f1ada98d95eb03471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944686623548e4027a3c6349e6491b1f367fd879bde5ced04877437cdb079a042ebba2624aa10f459b858e5b08230410000000000000000000000000000000011e5a2042e3a687393495f96800c5e2d611c31771bed906a1ea14e85f2572be15614c4bba3af34630b63bb901a75ebca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001290272147436fa476d6ea60c005a7d7dc33f1eb69163cc2a71602bd38d7f4ad38184f4e72bc23935ecb798d368c641100000000000000000000000000000000122583b8d15ed0ce8dde481b491ade54f75f37c987d0ac6afb2098e02c84e37429e36ff3172503c97bfb4b5cef710f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fabe8fa751bffba9a1d2971ad62adadbaa6ad86d0f5a26a146dc2f5778aae36f3826048e4a195f1c8adc2b1734992a00000000000000000000000000000000149f38eccc7482a50a62348c1582b361fad08f3f51dff7e62c691a27c55980c07cbe7bfd7c0f9f4fb100d0bac78ca5171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001656ec662ae7a60c95f37892deb1fb7931c174a92cedba1d3704f0d8e43b96a485514e45fa396d91be8644b4c23f464300000000000000000000000000000000113b12e1dfa7b996851847c92d3274232ce74a4f800968cf5595ad10393a78b7a4d731318da5a3341ccd58259748fb1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000956cacb668658a74830284df5b29ac22496bd202cba4132f5da470cf970f1121f1cbb3e3140c51cfb92661f797170530000000000000000000000000000000017a5a7a5fa41d93956d4c6bb3531a56c1d86ace01b8a0c28f4b65c56b02729aa3cbf60478935042b56da80a1bf655a3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f30d40b6f20887eab9cd907cee1a1e68d493e9673e44cc978ed0ab164139590f6b322a65e3cf00ac454f3ad1b62d1790000000000000000000000000000000003e2e7c24804091d180653b4159a858be58efef7f60bbc7dc82ab1647c5e9878239abb29b0302f4c9adeaae8898908131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000632e38402dc913861dfe9884a7cc7f7d2fedc72f96ba01b2509c25ae19d59102997d5d0b72c37bad2a9b58b4b3b6fd800000000000000000000000000000000104714d6f472e37d079a4b150f072e9d41789bfd0b3756aabd5df7952310e5921eab1f68565fb19014ba3caf44ffcde41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccd99971d40b308d1d68c1adf95c49a47fee69d0df2da72922021e7956bd2b652192ee0fde520d3526accfb61c042c00000000000000000000000000000000000c284c2a540eed2424f9fbd87861db5663aeed81d37d5c3a1cb54136549f3cfdba482ac5ba02fcf3a3124cae112751c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007835b602011904ae2b68128a96f4b6f709c960c010ff38df305c1f2aacd7a06e6428fcb1a5e91b348c84be3ca06a01400000000000000000000000000000000073aa1945abd28e200c880d57bfb926259623bfd24f20477973bac419399f09086d9c991ced3b66ac46126276d68fa7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008c2d71063a235692dedf9de76c042cf205da9d677b70e0caaed6a1d940f4231a7cd0e1cdbc3850e02c15ff0842d80600000000000000000000000000000000164bcbeed2534344dcf4de0582656e9967ca74baceb2d4a48f3671a284d6c09a4ff9fb4f00dfb236423476d269e943f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006c178e3d7b6895258014039ba7334a88ce19281878f735280523a4c94e665af641a4f17f15783d1c04026f4df78d12000000000000000000000000000000000484daca265f39a00eee8cf1e343382a55d851e3126ae125f344f8205999bb67f0ad099282eb1dffa8a6763e38a832eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c6a6f0231378bc28813339ad49ce2908b2ddbf700407352ccaa8c7ff8028f81d73c783a96f64708fbf9c8f6560871a0000000000000000000000000000000003cbb53b2a9294edf930e644563d4f0e4138c8463a3e0743f44b3b29f290be253f7bc1fcd10563f1b93972ee85d902971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b04396d49b3659c549fc5eb29cb134483a2baa8ef2b9833e0c58daa172b45e2f25214294411fdc09204a10193e24b6d000000000000000000000000000000000723892b5111e4332a2d6421a7d37f019bb1ab9da612a78044eb391cae0a9eb1762db45874285965846173abdb4933c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016087fdc8f38d75ec25f419250be821a4dbf4e0abb393e0629f2062864e3aae3ffdc54caedbfb60062840170312af0780000000000000000000000000000000015d91ee08c56cb73b7f9e19aeaa890c886f7c851340f342ed3e7822bda49442e767ecebf341bf17bfeabda7966513f721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc2ace7304eca1ed0cc7b04fc2188641618413940fa42ab0c2b8b9d934fb1088a34461a8299c75da37aed000cafa2d500000000000000000000000000000000154dd78d7b4f72af194151d628399f9e68e8cbe8a5b184644f6cda2299a31c5d49128dda0463af8fc17ef6dd8e6ee5ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068920a256141bdef5e1b2722c4a513572ee5b9dda923f568a2b6c079cca1345196b0e2d4777eebb415c3ec63a73f1740000000000000000000000000000000002e605cd7a7c939e330c0a6154017d445c699af448bc6132bdec999a01c7c64f383db6f47ac2e031495460d6a78f29f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d88e636ff291c890d471d7f4f0c05ae0b980240c330ed06488658b6de8004e4813e7edd5318d8c48d6ddf31c0ca2020000000000000000000000000000000010d6a7722680a3fda70db776c14623f86925ad25175bef333be2ae10ab2bb00a7d4dc571936ded57bd33d999a6fa36d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1d27377b3a4b06ecfc4fc01515ab813323709141bc9bc0e9ea62a5b722e0bf07b79ecf5f7e0a8da7e96e66c68f891b000000000000000000000000000000000666737d4356c66d7308b0dfa1fad87676da2e7ff51748092e46ce373cfd823500a44a9998bd295ae78b997ff8b69c9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015111657d70d3892ccc6c1d63f970c3c5d9b3c58c34b3f685c1d522c05c49ca2a2982efcd6936a031c327e891fee61420000000000000000000000000000000010a4b9a34b0c56715c4547285ebc9e0e7a3f1bc4cebbb91e21b63018fbf19e04df94086dfb4f3fe7dcc48253d4bb71161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058673d76fc9e53d646add5a3f870d8c6ff0f86b56bd44106a33cb8ae2e8e7d2acd367587a3f286fc88f250733adc227000000000000000000000000000000001160b9af3915e07d7ee7bde6e5dbe9fa4fec6f0a98a1a12a27b7c0169bee2cc768deabb37df5e94a087bc5ec09e6af371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c507b3b3911a1b8ae48d55e676bb202446171993ea93250b782c0384414c7f87d1fcc1fd8d9a075fe6e0ab5d19467b000000000000000000000000000000001388b0bbf1a4a7fd35b187851fdfaf3d4c24df87379da0fb846b59fc81259c4294f05756655c9378b758cb1d643d54341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b682c786552d55edffacd83fbeb3368ebda160cbd1db8d21c78dc55ff410ad24007a2c5183bf4eea8f4a5d2b4b98569000000000000000000000000000000001105f1de1b1a48956f54fdc89b952774e4decc9e79871bdac5acd4cb3c6e48d758c6ecfccadb66fa89ea796c475f96b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a31d1b778deffef6618aa9d215b7be6ffed3979dd1cd65ce89fdff3e35265a0eb491cdf6e19a9646c5251bad5d14c0700000000000000000000000000000000069fccfc584c8331aad1f327b5f292bd8a8c281828ca3fb8879bfd94a571cc587affd7f4678b82bcbcebcff01851ad021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f5dc0a3a3e5021968158c9b67f09ffbe2bcfd19baefdbe39910545c1d55fed5758af1dc1abf6a87a298a70ed1cab54000000000000000000000000000000001419cf68824b8a3a03e5316f55540d13186d00d817557edbdc5e2b1ef85033faa684ac5e31ae0e3f85f7f6b50d0a577e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012464d3ed71655e9e810e34f41e54c2e9409231237e320643f15aed9f33e837e67767b6bc7c733a34ddb311199cdc57c000000000000000000000000000000000590a5c6607aebc86ae875cbdac3f99bb452aab41f4d134e9ee1ff1f0d02abe194518d91d81de33a0bc9374a114f7f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6508dfa90f3459ac9a7f0700c34885c3baca593df3644b4f54198db204729bd6cec39a12684d2cc954d199fcec244000000000000000000000000000000001927d9092c5c8273ed994380e6bf08918af07acf1a14d3cdf8b7970e1103988e8aba0b99f72e14413071441f7f5d201f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1aedee3270b9c4c20f78fc957e4c487aa5bf6ba165780c96e895400c8ded33e7233b75a2ac16608ddb6a673ebd508f00000000000000000000000000000000116f6a6e5870cb17f44af54c1ca69dd97f0efbc513f521263f52e4ce4e3692d01ac6420a797c6296dcd9da33fcd793e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c87dd44b0549209b8dbb9242d5469c77dbdc8fbb0d3c6cc6dfa9d89018ddf459101e85fb9f568adbb4d863587aa0b6b00000000000000000000000000000000089e6b7ac9d6f696e129337762e068cc61e5481045b583149564de250576c025bedd01fc8a59ff3deb66a781c10dcba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000717a213568431157521a420adf4e66ace80d9bb7ed7e87ff8c8412d7d7ce9c399aba9c86e784637683f40629603fc3000000000000000000000000000000000d9fe441873ed2e642b6fea7f025eb4f016b5d43a263d0fb5bf46325b27a01bc362297c217825ff462e86c888b4ae93f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb84ee2857a6925857a195e4f7fbde27a94d8d58170b9fbd412e17080d04bf60cee58f27b283ff38cea8a87cb36045000000000000000000000000000000000264431ac58259a6637e31b60bfbb67deb8a704c0ecdafd9f669ca24ff246b67c8900e6e4155b40c200f5541ca28ea791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143c4bf59c0feb30af7351a5cd57035345dc95eb3480c28d84c1fdf3f6483b4ea59a8792d4b508fc0eadca32a575893d000000000000000000000000000000000924de51161a062c65d903bb38591e50a9e9009c56f3c01fa53052a249129aa37917c285c48f10a2985fc66a7ad7dd141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35032d2b1478f7d3320aa332db52f51c6ba8a73022751c4810ed080e5557cf8f7f415ba76e197cd6eed53b8e2993340000000000000000000000000000000018108de6e1cb75a85f3c0722ebf2f069aca9018bb3a56d1581b93b3dbbca8f799f9adf2c81ec475e6f4c30653e0336af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001372cf1d2b6c5eff6664fccc9de01729ac77995b63bb24d1c07bba8e909f7eaed215e1bf75c8d2122ccc4f66a0372c380000000000000000000000000000000001c5b70b9025863b2b31f3e14c38dc5f4f1591b21853321106053fdf6b57008cea654ebe0265420cd8a646b4061317a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048c72b1342d98b243a074068f028eda2565c543cb76200ed141cdfe1c162e075b3f404c2efc35e8d9993989a29c9c090000000000000000000000000000000010668156632fb5e263a3032c917c1836c93137ea4adf11420295d09d39000e293205f3a4a766bf6f128410514b6a47e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bf0af53dd37d037dbf6edd791f299c4cd5b7b6df4571b6e99cec7cff3e4a649738b3a81e1d82586cf9a7ded70f31c0000000000000000000000000000000015fe8ec6865e8bdd40a47c58fa54072272636e0978bcb8fad1a88b4a5a6c88329ecb29a74afd74f2e3c9b7ef89d2b4441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271f98776dd76cd3955d37fadc193ac0627e9c899505fc9882272b19d1d47dadbc44f6e1cb31cef63beaeb7e5ff5ac7000000000000000000000000000000000600dfd03e8c1bfe3cfd6e28696b901b30d5d4e9f2633d3d11be0aa83e08c4887833e81827d73c5dfc59e516c0d85eec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160314479b4863406cc1617c4e4c733983fbf47f3920df21c226b18c24b242c3b4b5676d55e127cbd5a35ecacf4cee45000000000000000000000000000000000cafe30a3ba39e04f28692fb36714fec7e6ab53439d637a6baada2114c5e374c440ffcc5a1d9f5fc9f0d3ccff8f20d001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b831e5f0dc0fb74757f8253858358e2d23acbea566dfa384ceb03f35001d618a0c72c8502633185bfd0b4d7d1fc6d0000000000000000000000000000000000f18ed9f7b1379a9fe02ab3c87bd5ce2881a5ee891b7a7f0ed80ff6e8e5438ebae7ebd146af70d958cf4ed734d4aa1111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105b14455cfc7ed1b92cb689694bb734945a0236dcfd54011f1f7c5b79c7d8a169135ba20d866274ea54a254df39c03c000000000000000000000000000000000ef3659e9fc55d71dde6d369f1bcf5cfe0d180d0be6c51076362cdb762d8d0be4b4f3acf49893666b78f2d7b604bc3861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0388b169e5509e42219f1bcc4e0f429c7cfe0688d23eb74305004b51ec5fa32d4d933a29e14d9bda492ccbcce604180000000000000000000000000000000008b59a341aec9542a224772c491c666a723c80a55241c68cad31c8d535bfb002d5cf6d85fbb5cda55dad92d5926d28601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a6f654fa95133f5b71758244ac30e66352c6a73915651f95792a85ef8d343e45f5537c5fc2f697ade2584eb6ae5a700000000000000000000000000000000013aa828d78b8b15d283ad0db332e58967c24b5ded030dff7ba7cd24ed4deeab08a8747b2947652b855ca10724030b9841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caa963604cc8938cfe63e69c4caafd2ba420b778232db1071e1c831812d57a8b239b00d09259c4e0cb14faacfad72fc0000000000000000000000000000000002d8bf1d415e7933c5c5f7dd46227f2c9a7c0d88f58aabde71e83052e7e09d47a74b4d53245a2756487549440bc859191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b712199f21c725364d82ecfca7a6d9ac8405681d904dda9eca93ec221a15f4e3bb471781e62c1cda29272f7e602af2f000000000000000000000000000000000f0a26cf0a94f2ce9bac54c521b6d8fb6cb620b3f3e177b8ce6eae08b85e07268295c1a4f810c6e18fc2b7b20c6712901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037ac050e2be964112dd0ba5fcfe7eabd7bdcbc2a8bb2dd84175b844b6a5578ee03ab41d8acb073d33dcd43189d4a5c20000000000000000000000000000000011e93dc6bd54b85e1c1e4a21edf71f3ea148ac31dae7f0252016e9d56451624d0fc5c8b5fc0060f43659c6c14bc0aafc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b4c481518b7d5891335cfe8d081f9faefc90c9be6619ba1dc3f8ff086c6bc76efdd5c9a950208ad3d7fa3bd3a6f6040000000000000000000000000000000017e10197671ec37b013c339e81b5569b64f24ee138b8084688ed25fdb7f92f50a5d39adde9aff81ac8ad2965657e8e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008bd328fe8afee0c4c9a2348c39e09cb6ea2564da01ee5bd971f04a5ef615868ac6fd571d3610716dbfba2761993f1710000000000000000000000000000000008bec344e45d27151e904b65ddcce9e51acc3a215afe8ea191d9254eabf4254b38b7612c62f8c96b7f152d8b30e2ce8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125de9899d0a983d9797a44df5677d641f7d72cc7633f909188d46beaa8134460c5aca8fa7dd2c370dc50c06f161fe79000000000000000000000000000000000ce9f83fec4118b16766310a518af679d8e5b265918472a68f9aa9b24b3e8b2d279b68c7f0031205ebd840e0d1fb27041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e94fb80bfa6bea5ca01d201bd02b9878a717f083ce75d908f3f10b255a07c3ab3d25b5d51ff342d7eda1760b56f4b00000000000000000000000000000000046b2ddb20d395e8babff7f6a69c18e7fbfa10cedad4688e9ef90b0da41674a348fe2f7e641bdc5e27b8b29dc84fd4251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ab6fc3793e1c72ef6846d828b13becb6cfabee2d6ee6bc0ad9e9c4daab2d419dfabdde65763623f540b75075c9d879000000000000000000000000000000000b90502647c4e9204ac24d207c68570050f9a4bc9253e4fcc840342c5372d138c5cc50d1895970aed9046097019c32ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153390aa01866b9354f24d25c1206cc36c25e1c04ca1c3bb0e57b7487adc700ea082a448232b8ac2612864eee6df4ca90000000000000000000000000000000000b695303838b83839019f4f2167293f22d202dcb6482e379c6cccc6fb073dbadc7cf7105050edd85cd8092613df7a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b159373bc1a70a2e189a1347a352d5076e3f1c9ea89c52bec1cf9881e6c31e6d6f7fef2a3deccff421cd4645e4b7830000000000000000000000000000000000df52d38438182fa2e1fd4666bfebedda43566791701218ea17baa68415cb5608f602938e20984e897d207c73b92f5e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc1d6fe9d847204202721c0eb12197d24fd0542923708304afb8163af9479c3972dd1b8dc5b35e3daff34c4405f7ab000000000000000000000000000000001739e6acd835faf97eb98a500ca07e2d0f0b5ab334e7db818025b30fa714398c9bbc2ffa2c74e0876171f3f4cd1fcd241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2aec119878a178821f768710f18d9494247567dc41fa1fb3e8694aeba8ea825da4f05ec7092fbcb2a55403ff48c7a30000000000000000000000000000000019b25b73eb310f57f8382e0fdbe1ba0c140e9c1f00da88be7f3316b08c2c0bb08b209e3b11228b88b8a82d77c864ef231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000604444ecf0e9ed667ef886235bf7c9962440168c34f6e0664cb2ad2a5995f252b39c4fce4c31af33e37eee212a93e26000000000000000000000000000000000c3b733c51c9fa047398c27441ea967f3e5930ff97055918b744d75e23565255d6aef73b2e1db6f1fb9fa6f21ab460391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be377d4e409363c98e5e36083baa1ab3bebc319eea62c64789f35cd775834a85dd11ce04d70b96e79f43dbb4a5d6bc60000000000000000000000000000000011e67d3f0a725cff5de9f5fdeae9ca53eb6f5c3277cc6d9e31fc11416c6154361549f6317ff2906f35ef045b785f13341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f826a48f4ada87b6ba8b6c524b7b4cf23edc925b89d75e6b6ab8c90ad21a78d08f93da8f2c20d66a37d5bb043cfcbd00000000000000000000000000000000040df76bf9104060824b034b908f3d5374fdb2adac578a4624cf568400e2f8418905b01092982489d5434e963adc9d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7a33f22df1736262f2ac2eef284c2d5825c3ffd51348b61fe6fb650e80dd3df835af1a27b11888313895f638599110000000000000000000000000000000007ddeb304e5a6a3f4c4c82901bf3a83542f05628a98856930b1be62bc37e6ceda67ed16e04ec954dfe4f578ef18fc8911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd2e2fe9ef5583ad56528382c038b49a3981541933df255fbd7a2861dc10b559e3b323f0f2cc4e38169fb20196ae1ae0000000000000000000000000000000003daec0bd12a57a806627f1cfe264def8e9a2c72366afe7420e97f634157234262061339bce8d2ab725209f17f4d03441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010660129ccea69597825197095855d741dbab60b1028727876c88a56ad2fd24bd0c33b0900ab83c2dba959fbbb6dac9d00000000000000000000000000000000063ab3783b881ce28db2ec9ab55a618955f1b3e26938df9b72550ec5265003592778a7e095e338bbb5678dad9a8594db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aeddf16374baeabbc83ff05cc4a0c01923f25dea8d65424065952d66a32bc0c0e679f4d5c86238afdb320c1708c410000000000000000000000000000000001751433832021d52e14d64a9943bb8d3d40c24d147cbd38a660da267383677fbd3dbe96d80f6645b25b46e47c222fae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001616336604c8c3960c6dac6be82ad787f1d33a5e40d07be8f1b1c19afd36395373e3db77317a2a39ce761951d1fe82d1000000000000000000000000000000000d1305a2e34448b39a2cee407070965aa39aafce53de8fa6ccc66c0821dc178bc6f00e094bbaa0d24172bf8cd847c0701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2b835fe80fb3dee161ddf7874c6e9691e5c13e4fa7a1e4fda44e20dcffa495b33bc6b615d6dd3715b345fc13d934f1000000000000000000000000000000000479971b28446d30e658660625a11d17095a35d685d4426877ec51eff33917359b2c7614597fd6ef2a9cda4caabccca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001888b705b40e1a7cacd6ca8baf8977220f603ad64f2b57abbbb25c3bb79a87e9fbfec39c3dc0135f567549615e8c1340000000000000000000000000000000000800cce43b4675b891f6715b0f72299724e27e7f226f77a219fcc696f6aa62032ef1fc1049d832be5a3b3d7b45658b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e2703793622ae928e8494aa5d837ed5a5b4ea94ec01e427a4c6a2af1903a662577149bc777804a175c00dd6317741e000000000000000000000000000000000381bf9394f69d07c2decccae195155e15fc778852e542fab205d936d4cf5f6e1ffad428968794bdc8308613f99e37351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e4364677a6b6732d137bb1aea847694dafde8d67689618e414c6979be677aa349203df0f60d2e33de1ab6d875c173e0000000000000000000000000000000013a8dc23c5bbe53ef6903eab5bc0b3a8f782aefb57fa6b8b8b7d134e6e745103ed34419f18fe7b8825beefd13de955c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e4fd807292c55d3876a4db9bd74c03598e7db9729b1c4da18aef3d303ffa99e90d73182d7c748faa44d069c1f5f1c70000000000000000000000000000000017845e4844becaf392a40c41b48a3fa8faebe05e78175065b417c669444f4ceb8ee551c57cb1d258da83b573d4ae60261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d9a9a752abc370c63a2f04807521e0dfa7823e73702e953527e0032243d72de62108649d4b59ef02826afd732d8d5700000000000000000000000000000000039ef9915972d2186363530d92a9da77efcfb2c032f2e73390c3fcd0b7301fe84c1dc69b7cdb54a3ea62a5be5200479c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd3147ab013428a8887c86ec72ae5a57c2bfd6bd75f46a993a085833e7e3e7dd7c1a5334821fe1dcd40027dcedae2200000000000000000000000000000000009c04ddfd3330f93ef03151527349150a6a5238ace8cc7dd51aedbfb291d6ab63db384defc7622577900a745ab60fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192cadeeeacd29e3d3a3fb9ac024d79e0db4895872f78ceb39711dbbec0d901cdf99ec3a507c98fe22694b0b11e0a58d000000000000000000000000000000000ca9d937a9067d2ecb61d7160286b39bb0d505e771e2a9c0914d93aaa59e2d9194060527af87faf9104d693a148e888c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5c9580f28dbc989e6a0deade168d480c2eaa7dbc6806e12895627c99539fe329669bb1e42049362b46a2b25246c9f30000000000000000000000000000000008c6abcd70c9c37aeb94ae7670ec954a0760d90209f717ab6f96a5dfe52b49f2eba1781488014ad1011ef9f565bf50261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000848636be6cfff0f5c651472528805610dcf70d8346d3e5c86c58abce7f416c1d4800991d2f7d49d182265360c78b81a000000000000000000000000000000001692d25da91432b309088b5e31d217cd51cd967783d682370a26fba2e3289b1a8873f64245e6cd898fecfd473c1e5eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a41507d677567a73e263f468a26a26d23eb1b5c3f8686217e1e09ab34ed7a678e3de57c1ed1a03514af0a8024601fb3000000000000000000000000000000001616c8a4993216452e6f90939816374c0c0677b457e44e6601287ac261f4f14f0bb8a7b5c8ae46af1cfd6ffbd0a266d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dd00e1be7a8b1e22b4e330e1838d9605a27a539961556333b2524884903af8b00b08e6335f4a307f036dd1bdddc6400000000000000000000000000000000010cfc6926f60c4f55750f9923f9998059a9d03c4c7572ef2ce79853016ff9d2be705c9e0458ed8335fd4a456891e49a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2b2a15e532956dc9fe7d1ada229f87c87406ea672edb0ce8f728bcd1cf6c7eb6eab2706ecd6f2a1d64400b9aa58454000000000000000000000000000000000db5ed69ff7f34b7ba997d33cb943788dfb0e67a07bd97d16a1184eb07cb60063af5b95605e3d1e874b9bed0f69d2bee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d38103bf5206ad11375bc7a6df76d910f2d4f77d1c14126cf86410007201543c01447cbc4d37975f6239b35b9a1a3000000000000000000000000000000000e4d7f5cd57cc47f24dfd6b4b723b5c50644368022775fe5fef05d4bf351b842ab079bb95875eee71caa61a2445a65aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b62253c55045ed15e4d7b2dfcc71157753a225844f63160c9807927f48b9f35cded2da826995a31c5667295715b3c090000000000000000000000000000000013a8d3e1fc09bfe2e810406de651a69de748957dcb1f4950e44a2e075d45688e2fdcee372a20c3bac14c639743cb80811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001934c3db03aa24253f461aa3cbd2e759c5f7fc945c312f4658e25aaabe9ba63a69e4d8a53108f858f164710ccb78021a00000000000000000000000000000000074da0a9837f8d5245123f5e1702e289b7adc02abeb63a86582c90b18538dc01eec55cbab5a48ae64eb04bf367e91ad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009199b28d6dbd3bf7221893ca18250cda72873352d91791e9176d2cd758bb2cb1d595d7cdf8fc0e5b99715b997c088b0000000000000000000000000000000000f25b3aa2d8d119948da4048436bffc457f586f7b93b72c9451e4895683679ddbe4746b96277a4391257cd822db2496e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097c57849901a0c8ceb9b9ab077cef030f6573c76bf3716b8cb798b644a07a025abb52484f2a42fce34c21ab6aba59bf00000000000000000000000000000000107d831faa5763986bf01da1befdfeb4b5f666c097801a651034ed12826268c70bb7a8951d6d8878cc7af537e73940081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068dc00d547466b69ee4f046471df4483fd845c22c717d88ce1595f5ff499b1d5dcc3e21e6a568dcdaa1a32500f7cd0100000000000000000000000000000000187f2ff0fd30748154bd2cc5bb1b16d7f12772db5a238f7c7cc98646e54b0fbf38b39ff408febe977cad6ccfa02e8d9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef8e1610333a9b729ffa3c1e269e0903fba19f327840f94c5752927f9f1347642ff69416caabf7171a204e42c429d90000000000000000000000000000000001068d553146250b78582596a8c99a355fc7f891646e5d95a195e034a2df9fb57ab612d5bbb6e8ae3b7f68b18f10e08581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601c5f1d30347ca81553d1189938116b0157c73b0972e54c9a0d9fe5ab48f543295a0f900c3f34c514e786701c8c3990000000000000000000000000000000003ea8dc74450579adc957b24271959c737bbea600cc269540bdf4c9b79f8295aeb2f8f5db86e03ebb33f3399e6952ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d001d499b54e833cf670a4554a4a877b643b9fea5e0bd7c846c373e79b7bb0892c1ae75f129837733e647d933ebb0300000000000000000000000000000000141e9fd4b6868da372a66b71a75304ac3a10b87098fb8b2540980dace4b6f579da5eb44bec509facddea09a4086973c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013da1c68ea9ae18057a9e9340a6cf150071e976db263e884b2c55e5a09b61115007956ffa3827eb85562ad7e9a20ce9200000000000000000000000000000000181f7e8764f46a0ebdc991c2f90144c0e9fcda912bc94304e9a84051c67ed432aca9f348a8f26074b0661c73f60b64d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb53ed6ff26b2a00493666633bc7a50efb6a8d25f53361ad31495b2a57cb353e9b39c4d471931553c306b8575c826a0000000000000000000000000000000009efeae0f89156f2c4f32a4753de34f2fe49544a5f4e3c1f609735d7e8434b5c75389c0c8cae12cf782d7c0a858463961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019dcbc65b55500c6de4c3100df56f6a75352c38a18c4a25961298adcb65ca7610c0b320029d9b8d61f6f590f942f953e0000000000000000000000000000000014aafbee5cf292a3421d3f26aea44967362ed455dddcf4ed55fdeac84a2d1d1fd179e1129f994927ead0c30f6a26d6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058cfa739c2d537470b49076a830472ad807226b52a9bf07e84a0c39de38c01f073e2696290891470eb2005a8737268f00000000000000000000000000000000191ed3ce208b6bcaab738572987928f30e1f20372f0518f2c7d8c43766ad31393b876cee074dcb9a1a77610ebf40b0411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169d563023e0a496ad95f818457baaf0316e825d12e69afb2b5c0a6d63e89f188aeee97f06159a479f14cc7406c3830400000000000000000000000000000000057522c0d59255b1367797021793a812d77ca53f137d46587528901a922505b3f59baf821f9a239c1fa51889c92f29971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bea5fd2658aa42ce339c8753155af12ba8c56f10719d0d3024c425f17a262d2189a1d12ae0cd91b6a138609a0aa6220000000000000000000000000000000003b653851754e56e0fafab7ea79da8f0d32793597cf109d49d78172df33da44e8c7a7bdc2b7c4f87ba30a262c38783a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e1dd9b39c8dc38d1c42f8724239ef8a1e0a429a368d0dfd2a954e054c2520a2c47b816b82fa0113827bc1b010a608b000000000000000000000000000000000dec3ae706926a4b5412aa1b1792f39700e39731ab05d2f3769499a0e6b2b37b1ab441155d6402018cfa564fab6595831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175c22ae8c763ad3e98ac4e8b1b595b6bffdae6f030c8e4e9a1269289a129313991e842a8638ee56844633387b4016d600000000000000000000000000000000126512e580bb64c9d0e2b2f81140856767b30600f2ef4e9f08b1a88d2208857c6c140bd20d32f82715c2edffcc4bb4c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db15ad1a06f77c6072ad66153332aae1914cd72c1d0207f1c711582d339944ef2bcf18a4bc1e247aaacad2fd4cf2abc000000000000000000000000000000000f426f7e706b7c12a8d5251a1cf15aeaf439014046fb6cb3a93c557e2d9a17e1b7d77dea0c8806e69337d5c4c97e8cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef5a2e56769ef864db536b0a6b7845a14e9554b7bded3118e61fa8736bea63b5568bccc00c75b027baa415d93285db000000000000000000000000000000000936f60473f9e3d849dc50a5f8382f627358e51672ff91f23b36f94d53e809c847e235a6833b24911ac32fe573b22c9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067c8ef39353039c6e85717f5cea69038138d28e5f871a8d824880e5e94bcad1d702a4288ef3dd0fe683ab49ee27881e00000000000000000000000000000000088dfa28ff418b50e704f0a92919a9d725b4832cfb6f881fd0af34bacdd7073552562e21635eec76931cdcb7e3fcadd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005526c9e42e8bd124690281c424641989c840c6b203a6f4be24d1302c8f40123ea80b82542a9254473cf62487a089ac60000000000000000000000000000000003acaa670dff46c78711cad38dd98128f849caacd734a2a043238fb840f5f58e08ade6159a378c8a95d9033b2c52990c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149959ea68c732401811c9179d7b6e8cf59cf2d81cf963ed9258518c5ffa49f9353530614daa689bd88c0fe539d010db0000000000000000000000000000000008be0e966f60eb0d020e59396ad64e2624ef6fa55069a8f7d4b576944b4ff450b00d94913691d24a87625a770127a9e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187194e63ce4888f10f0b99684faf7a65133c1a164024eebcb06f54b9064c47a63d348fb27351c3820f3e76b591952e0000000000000000000000000000000000ec000c23cbf6b7c7e691d5792b26e28e26d021ed8d8ad31c81888c62fc53d4f92a5765fb816564e744bbcb7abfde9791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b60d378cc45ac4e45a8dd0af9bbb6b4c0b67ef5a4075540eb5c19df12062a9f6f23b5386dc206420c75482f0a628d000000000000000000000000000000000cc92a3ea8aed8041e4b2fa4a488fa916e1b5736426839dc986980fd4ea0b88e5e23c0bd18d7c0ee7624985f87eae1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002bf43320647692469f8e05eab4f6ac97f21ecf30eca350cf90c4381a13dac51d2a851c76138e41cf8ee2fc0b00067b800000000000000000000000000000000121a9536da0957d7283ff97c2bef442d140ad8d6f430820d446c07da41aa1ec854a16a6ef19b2e0f77bb51f5ba3b2e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d722c721603cdcb90cf09e9078aa2599f8e2cb20c08c2780a365d154140cd8a3f7ff76108cf021dcb8bd6ebc1035ac000000000000000000000000000000000e92c1fa8f90fc999b49521bcf26206f008f46ea78135887f7b6478e59b5b6d4afb7d34a227538ccfa06d220b0e047f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a6a01fb85271eb067cf250a0aba46a7ef86dc77a5e790a5aed1befd205df5aad68937c1f07d9eb29afbf1e689eac10000000000000000000000000000000002e774fb318d04a1c6dff00ea421d76d0e7381cc972a8bc5a9f7c2a8d5bce26c979fbdbf0ba31cd9f7f90951e541c0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000356f039f3604203ded1ebde41beb87347982ba0941fed2515de1447a08ba0ab4123724137ba14124cb127cc92be34e7000000000000000000000000000000000bbae900394d878d51e24b1aaf2c739f1599ab1b19ae2bef75fecbebd7031360f96795fd5337206a5818cafaacc47ece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009961d8b69341b2bdf19d4268e489b7e11a03b023e39c1ca707ca568b988e28e962a8674df617f65d5bd912d0d280c400000000000000000000000000000000013d0d03dc3f5b4b462b32d6b187adaf2becb55e43ccb0572b331f9dff9f90522627a02aeb12ae0c40da260d2a7edb4cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019363e4d10d205e014e8d4dbd60ed1785455223fb9751f2900a76c72523be19dca6779ce5a549b61dd128eca790b33c00000000000000000000000000000000000f55f0a4cdecfccadaa18512f0fbf520bee75f42fde6f7fca140e314fbdef6ed36c4e005fb1492cf3331cf510ab83c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059ad18958fe60fb5e1bed46389f54e9904022c56524208c06774660406b6fb6c56f7b46439f4d3268eaeac39042a73c0000000000000000000000000000000009b6e55486829e9d1e8e5539921b188d65feb184e5db48738b666ff2b8272971b9e4c1e65985353801dd1adefb9a4b481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099794b90dd85ee7a8490dd428e5641b49f0aec14b02e32e57c884860a8982355ed206e489e5af85aece7f0e55e2b5240000000000000000000000000000000011ee8915cd6e0246739abce8954126be56f1373f4a1ed7ce07784a38f013967125a94fee3f70b33cddd937cd36bab5fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001202c23cfc2151e27f1871d4f31a71c5844714a84a403a2939e84b878598d7ea7822bf0e7ec3d4505495c6ddbba13a5c00000000000000000000000000000000156c7d57d719d3a26fc5a5237492c0561a63cb8bc31e31bf2c127153b885108dadd6c5193d2088db6fd185e6dc8612231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bfd8240773277ff84214daf2b275886e87820009a5766feb68c4e3a8ddc743589efe5ffe03c6d996b6e3b96e775e840000000000000000000000000000000018a0bdf3803c29a4bbe1a51dec9448172772c3373c8e9ad328fcfd10980ea2e218cff4422bb7e9bc6ce2788a9b6f143d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019de7fadf2ffe652e9c2ad8d05c87643b81f1e1a9fa999f930645e926f8ae58ec8f88d06243db0758c805d43b4dfea81000000000000000000000000000000001486ed9861114ed2d53aa68865ed479e7c1a4f66c29bd98f5c83697a7fa84dba6837f3240bce8eb5b23ad8b67e357d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139fdac7528942d2c2d8d0148b6395776d4589c9f6db05b7cafb13ed76997d82dce83e7e5beabb21f2219a8d36c99d4d000000000000000000000000000000000673331cf6bff67cc9838e0f2fee93c96ed152ac95397519e863320d0a3750f8cbc02392d90d7a24b3f9e40fea6ef1701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebb7830093eed2cf5e53617209c9358bc521084a5f34a521b82d4ccaa95ce4e602d1c7f182836dbd685bc4cda334d30000000000000000000000000000000000fad4c66b50ffcad01d448e79efdf6c9446427732e7d2593e77a06a4d804f666429db195b4db3b5f216bd4fbba16d4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3323d02486ed850b0e45c281354ac2e12ce533684e610c0258116b5fd00f47d02eac97bddd1f195ce88599e3ae3a80000000000000000000000000000000018e3869e7cfbac2a62b2b2feb7df2a72c9dae59239a8d1162020c7947ad9751efc47a237c5c7da70ee25a238132484351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ed3a533aedeca6381443c3582b69b54525aff8fcab94320daf35aaf29a945311e75e75c1ec8d18aaffb0280cc137b70000000000000000000000000000000010f9b9734e3316ef54b9adaaf649761c9621bedfd3f1f7f2c183906d576962c13f2b92cfd2d69cb3e4337022fc8a41ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d160d3a0232e4a81b1a1b39ff97c1ddd6a07831318ee1dc9d2e303f97cd94d1a745c970beaa01625356c46c1d94f91000000000000000000000000000000000f9b9086130fed82a16120620e0cfbee3553750907697af3ebf9d6c3131300ca9895d6f7a2f33f968a1c4f8c7d235e8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100800e484086215688bae53087c646929b12f25d189a9fb5006f7c1ed0b661107ee46395ad7842632423449f4ebe7420000000000000000000000000000000018ff21cbb1651f42a82a4a065d463489915e003b677b12bafad9a4f4f460034278f55d5b3a3516244d5f3e2507324beb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000736c2f0af8eaea0b8fd4fff820d3e6ce3b5ebd439c303d30f838a852bb0fddd9c43996fa6347cbf922af7c293406bb6000000000000000000000000000000000563551f216257c9e38dc07686b2afaffba8ac4f22f267b154c5331b5f199af8db0f12b6b4c449c77c49b474f943b79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb72916ae3e2ca262b6d5cb0065d01dcf5194e9df04ec7f38e0a58d19d40e4ee00305715e53b7ae568311fa8818f88d0000000000000000000000000000000009634d8703e0fd3552f5487b328dd81e01fb7c9d64ebda64a2b2debd06e18d6bc92f851cd0699642dc00b3b1f184906e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a221cb22551460cd5484318235e750b8c414560025937ebf55fc1cd1af2e911841e9a1c4294af021c903002352f2250000000000000000000000000000000002c1b0d00297e1f705944e4c1b9083d886f5b0c6cb4aed65826fa6237b554b348b18eecb1e523d79066141c5e34ca83e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010addfe3611224ec5ba409711c7e376bd3a382ee1ded2d297b1571be0b3631ab34fe24aa9fba5c9ed25599fb55d582be00000000000000000000000000000000166605242e271225a535294af4a136ff8d2978afc5833c6225c334cf34adba7874a0531bbbb918ef47a09c954c43b69e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041b6b093cf1d772eb41e8b989ab3eba4a970c3577f6b654ead56061a22bd59b6e50be7fc8a76275697a30ed06a9e14a00000000000000000000000000000000032bee49c5493763bcacf244807b135e6ce7e7f5ad24e0aa84c15cf93ecde7580b68df83e572a889c9e29d8a375870331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007af41a5c79382a1a43696b55e24ece6209bb2f16983735d56071d58b06c15d53c2c412c637f32e9ca00469e090911fb000000000000000000000000000000001237384457b67fb3026a96714993cf0597ec7497462683888ae695b2a630b76a25637d6930b48f1c9bc583bf5a71af071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000058f64f55522e1356e27f7f5a7faeb319666041ac42e4ed12cb79c228ff1fa43eb3cb8f8a412861245ca4529ed0d9c4000000000000000000000000000000000dccd41d4f84b7a8683f7737731335566d0dc8f14326de8b38334fa9446257900ac6368019b962766991e3bcfb767e1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e98fbb4756324e2985b56827bb48e4861298c4648a87b55b807183d678cddfcf0846fb974eb39bdb1a5b6795963f4000000000000000000000000000000000a72cbc795546698b0ec3a26c9d90dd0ba1be1348a1fbbdef2ad3ebeb3130201dd67bd812328a34648f3342dfb305b761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001185b5e0a8d8fe424dab278693c39830ab5d66b11693d282f8b57a05ba4c45af08930393585f8a406616baa73fe72a1f00000000000000000000000000000000083f45e55b7c7e79e4860d63a1bf865fc65954dd63fd82aaf9565d1e0fd727e8a8f261f5711b684427932cfe4c94058c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fac2dce2c80d2cd9d9f08277fa5623d718c65362fa002e92b7f4bf66316cfe3403d4e039b758280cc49bac4886f4710000000000000000000000000000000000cc4a501e9b3f847d75114ebb50347d5e38b87312218a91925c1248a3c460f1a1323eed76a7495074b3c1cf597626691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030a0c75eb0c277286c5437ce1b69d0427b6fbde89b02773d17da484f3a3e1464eab185aa479f2d5e4f595d0048200ae000000000000000000000000000000000cb4ab4afc59bddc19738343dc98d23f38180fe1bff8e0ceaaadf653906136fc1430cf78897fbc2949faf2bb9cb3b6a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049941a8a94e90bcbfc20a4fc6d4c115a5c0be1bff80ae599bd27a049bc45175fbaa6259ed94cc42e874d98771dd7920000000000000000000000000000000000ad60a7f9eba3120f99c1723c023d1fe584ab1a6a68fa440fe813e8677d5ddb7ecfcf942ddaed96538b5e5180c4d2c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e277619e7527b61e542caaef4556418ea7c72f96d3decebc6338c9c346f2a26c5ee6494fd3ca70939176b1b4d201fc1000000000000000000000000000000000245f8a32bbc5ce8f61d80c6ecfbc2814deb9079a5f9250ab873ab11ab3658c8632793676c6039fec41a8de8d1c3e4181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a405f46a9221470dd68d594bcbad7109661a07617a5e395bb47628d24854ba09d559d44a2cf703b6c4b80d5bca246be000000000000000000000000000000000336ed34acddf9329a9669a3571819cd83555485fb2e06f9b44b6b162171b6e1544ba502fb5dd5de1eae3d8b870f44921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dca74a1f94c017b371b6f4c3f651da30890d23ff2b8053a77fe23f690209f1a440346a0e35b98fbbeda50242fd7aa800000000000000000000000000000000141b8e7f0bb420afa2836b9874d7a582f6a801721a9ddfc35e79b1fdc80f37a609fb68f2ce9e73fea07da05d1312c8be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000202bfbf8f87625fcb0146f86e5a615a828453bc77e4dcf2a790a941fe5ec0acca7c14d0d9141833694b1bd146245578000000000000000000000000000000000b08496d894eb75c2d5a04c0ad985a6b51faf4da08d1828a1001a15c8259547fe925d7ec71132a35ada479a6871622e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab53b52d31517c09d460c5dd2533f2b4a8f01b0888e56f7d10821aa5021332b4b46954d4e94d497ab391d1dcd4184d0000000000000000000000000000000019150bb1262c44819aec0c80ab2a0fdac8a3ed7d4b1dc939631925377b9d1d46a78b48a63d504b5fcb3420c2fac72f8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6d341b362132f641a88dc01f886b6647cd30fd654886c02d64f0931ad4c2deca306f9e45e8089cc73813be4bc5ef7400000000000000000000000000000000010cff3e94bca625a6bdd323f5b7d89692ad1fd06e8f5f82f22e5ff762cfaf8b5fdbea66be9aa09566d7c04071567c991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2bffaf3cf09fa31ae5819c922aae799d6e715a32985a851f211d7af26d2cbd544f8f17d475d8ef3f871c5cc4de750d0000000000000000000000000000000010b159f3157361830f9241264c998dee3e4541b3cd6f7b8f38e9661b35adfa5c4122bb355df60e6cfb3def84960b7f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916815f3b7933be9e9a17dfd67bfd68c1f96800788fc60178d58efc4c457e6cd4d48f66eaf2c519f144e5a93e75fa0c000000000000000000000000000000000657e9217664397a47d41b000ba9215dceceeacd10071cafb0c14c2b4aa1b0b3abb6261aa09004062ae845871cc6f5081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d718e1cd30a051852e280927fad885d540be748bbc42d628210574dcc45098c2154e5520ccf2d7bdaa7e7d04b47dc80000000000000000000000000000000010881fbf33a29767c6ce25fa23a5c7c2e475156ceefb819a9e0adb28db7f1d9be3fe3b3e3df101e16efa73bbdff8a2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb3b930ce7ea2076f32093451f2f8a2d77890302a378fc30c3eb9952daa11da0dee215911ece81d86f79070c8db3fc00000000000000000000000000000000081a1e01184c617e11ff2df6a193c4ba925c61d49dae0762ea036ccd8b2fd0366f340205f3844273395d8537eefa847b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001457ed635dbea77a65bbae67b470e74b8ce77a1852053b674527f8ec3988b83b9f1775ee57ed7e694270b8ce99cb4c7f00000000000000000000000000000000014dd3de136b8e7881771a41f67de9dbe8b70057f54265450d4f50a9fc2fe794b53e97f9737433f4b2a1c3ccf7b244c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d047bcb8f97d04720af4ef9d4e5a5b6d50c23f86fef56772d994f760c7f0af6d1619e6b7fd319f5533e6aadc3aaf6100000000000000000000000000000000028f199aa9cbb1276fb1b6af31f549e0338a5d2456f83bc51b192f1f73951f4c5ab5ad37d3a9545d05b85b5124771a0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ed0548b8cbe2332be21d46de3dc3d24d37e4f36930e874b4722dc61c4064b26f33cb969601f1eb8c59b5cab6ed78180000000000000000000000000000000006fc4909410368afdd726702f364399a6483785f759353660bdd77200dbf64d5649feb3b4a68faffc5dea1b6cacae12e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c73c09c8b836098e64bc65102a6373314969ea4f953a1a6138018bb960845a987d8b5e629c3359ae44e509a03aa1710000000000000000000000000000000008efa599936f1976964f040a948bd500525ec147f3672adb2d55bce12c9d16c79d522d94464796c212c056f1a87f872d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e122df226e3b16b790face1dc1b3ad60422d235b4c99103eb50bd76717c54ecfcd68f99bd71d94482929161deb39430000000000000000000000000000000012e57caecbc9b97c63b11fe3cb9379d4d1d04cf382419a982751ce0ab03885cf293850c1f0b5d3bfc35e70d71e6354601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000166b3e11c9a3085fa5b0fb18717cca2f4b288a62dd1d5af870ba12aa74e08444aab8164bb6ad9d8561262a1461806180000000000000000000000000000000009e3e78e42bcab0f63b8d28cbcb068cb743585a7beb55576d481a2b57789a995fde09c254a77f4628b9401e39d5df22d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003048dc0a721cb06625c360c22ff03f00cb1671ac6f16521c734d940d55a62573ce44b1fcf4449c779836823c81b42f00000000000000000000000000000000019890ef43f93ae538ef8eefea0a3ee9fb39bdc53733da3e8d263182cf188974c7f510efdea815f7e96dcdb4c2c9629a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daa5a8a44117ea2801f9ba6bf260d1653d454780f14933ffeca34e6d7c4831de6f84bcc9592b3327dec3669e29ccbdb00000000000000000000000000000000156eaee970da17b742275cbfd277bd9231116504a69b12c0c324348681fbc6b19647860247de6fcb9114194b5bb704f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000752af6d89a9834b2a7af7e84520b934e64dcf7546a53b68ce680c513efffb7a7c1165d6e3f2a5aa51d43deeed2944770000000000000000000000000000000007efc9650ae553e3cc5fa62fc90a86675db6d3204971a2619ee77616ffffb1aa1e09dae4445350c287a0f72f6d19e5631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017cb2c078b3d13b942f6b95323bd6f72aa0516266b505022e8a039607fdaa24c789ef3a705d92743258f1c171594777500000000000000000000000000000000129010dbe4a2b6988b17fe8113c0d08215278e703ba7f64232a1a4c002ba7f92751281245be0c92017def294ab3afe481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae47927ba222b1d69a344b25aa6b4bd28312b0715868405f6c2cb3b6dbede3cfe606f7e8fadcd50e7ffa59796262ad000000000000000000000000000000000ee2f6ac4560323a534095c6555b67b07dfb3ef3656bc3faf9e053491bc593cbdcbc5781f97622f2246c84fa42c963dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f076835181c40b77c256cd8b146ffe51d6f13142bebc9207e367b4bb7bd613b30231b15a1c4238b8f226da3242184000000000000000000000000000000000b99f0c05732f9a52cc0a9a3e08d650a952852527bf9c6dec7f2a477f92075e788732aa4350ae62db02d76ca9f02b17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aca25e60b86ea6b8df91aef0e82c2268b65d8b1cdf4269a889babcf9571effaca00da7d358c4f6bf6ea9af85e843f5000000000000000000000000000000000c75bad6ddefba40721ad492cf52f176d633e87ad67d2a7debf96fc347140ad66ba084d2cba40b05937a100f249eda0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104dda1c1b45701322a361cbcd6042b9813e861da179a4191c3fafce2c493ebfbb9df8dc5dede373350b5ac26490b5620000000000000000000000000000000009ab0116b2ded6d93c7c8458d19911bdcd111c4d956af4c4b920ce8f07c8dc9120baee6486b87a33721c11759925b0511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000913c86373d9b73eb9a6e100e30d08dd36ceaedf7bfbb8d6540a26ae97dc7ffaa7aeb097cd3104bfeb340f6854a0bfa80000000000000000000000000000000017cc22bdd0a97c6b9e13751051b19b0b71499c704e8f967f232a6e37c797b0db5c49fd9ae9f3e39bb173c0302777a6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001419f1b27bbf6bdb17a319c52e3eeae653b07ed99f84a96455bce7a87b6a8d80ca501c86df95bc42078d7675e168969700000000000000000000000000000000058728a522f3dc4bd6f7a7e58c4bb47f6ee8d65a4df4ef190fdc169750e77f89e78427611294799c1bfa50d6bc9ea0751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006294bf970f3186ceb2a2aa60075ba258952787c4d8c5afabdacc6c9fba595ff35eeebb1b3d0f404f63f1c619e6687e4000000000000000000000000000000000bdebaf5b7e81afde94f2b6f503aa6124175620ed0cb749c799e33754fbb24d87da7d11565af8855025b315321a385d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd6fe84788c407f1a1f694326bca2c39b24c173863c55ec2a921d8940d1d294583e5866bddda594999b8e6801cae580000000000000000000000000000000009c819869247e3ccf09f4b1600ef7568d807fb73b300f8bc7f197ed870e94d752b426cda413145e7a60038890ac4c6301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001670c1a57c2eb3ed9fb62cb5d6874381fc8d523d046db238b62d6936eab2d7019523bcd177758756c319d69f71ec01460000000000000000000000000000000009cfb8fd75c76e73ed9edb66add7cb3ce068c7e38af65d705b70f433ac391677ba8693d2b7a9da66874744a97f4c5eb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d865d0bcdd521661e509a76d436afd0567591eac143dcfd87c0edf90c723908b3dbce8f522f7bae53116de56c7f30000000000000000000000000000000000d4a3453cee6210f473c9dff1a6edb803daf26f5351c8840fec93f4287913ec4fcdc1181c950a15d4f32c6574020e2ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154451a717b375799e61e9819fc814e8b3d720ab0c725eca55e46214a1c1ab3ecbbabdc62aedd7278d41dd603587c18d00000000000000000000000000000000152e95fcc64cd3304baf3425315650307d16bb89a339d563b5901a99a37c772176f59cdbed30bf0d75472920001113791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086e5ab34fae4b6e3cca1327a3b4f0937a31d2889472dd2694bcee4874c24306b4928906214a670ed815ca5ba4dbf50100000000000000000000000000000000088ab0f2a378ac465d719a365603acc61fa4c000fddf21d6b680fb54591ad6eaf2de2618bfd9141ae5e49a238f80e0331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025faf310a8ea586ab0357a5df6e8690c1514ce3f8c5918a2e0f0c838deca41d269a78246d9f09f616579e18ec21758500000000000000000000000000000000176e297c595186fb78b253cd468766dec77d64d6c6c6b8200b92770f93076f34292e63681c5081b69b225b0f074b2ea71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004af00e20fea7e198f8ed998bbb0b85792f232d7ce047e03af4ac8dbc81011cf9e9819116256f48aef1d782fb08b6c7e00000000000000000000000000000000177b309ca7bf4d3657accc697d3e96b260fea7d1e5c60d1215e7f53e989ef9bb9761b424750fa30803c11dda9df1cc981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017561f21f593a3ada8dc1831596490e8ed6099991c5c5d00bdc4e6b651a564ef3c60c51954de4cae44b983336203cd36000000000000000000000000000000000d186ec44246cdb540e385a909cfddb3927aabc8bafa94aab1c3458be19fd3862c52c899ae100ddab01f0cb9ef5715551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae579f18e3100bbc6b7617d943a770d8ea56f1c04ef36dafa288805e6f6a63077a4a3282799d68e870c16036d222260000000000000000000000000000000016b9ee73a3eaa003ae931d5945188bc718bcaf0c5492a5070d304ce9cfe9e6f6e5736397535b481d9f128cb03397ed851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000989c613c62038d452013200503672f82d7c55b3beb504db03f6767340ada2a3cbbde3a8a0728f92af4cfb68d1fec375000000000000000000000000000000000f7bd845488fba68975da61c91a8f64667f713c228d89de5edbe9526bc63195bc08b09df910f02e519043250a340ec921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e1362b2d78d142bab24f62c42a68ce20c5c2608c1536827346b7e86666b7ed07ea67488f6965e1278d6f23f26114ef00000000000000000000000000000000103662bbf4739d68bb1bca50b8418dd6defb6c697e2d70a1a3b42e795f0dfcb4742e8ab22877af5d7d007a2e3838f69d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ddb1a25cacff56d94299dfe3046743fe3432bd50f237257cf3dc33122963264ce1f11011696c43549f94fc9dfc1d100000000000000000000000000000000059ca6e500db63a0ae8c0dae73b101ac01274d477d8e33b0d25b4adb8b2ac8c9abcf7c5f6081e6c4dfd74b657e42c5dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ca25ce8835d989625f25295be93fd5c9b87b8956f88257b05c0296adbe62117696a20d34c1db3d9a6b01ff5578c9260000000000000000000000000000000005f1d27eb0ed45207932c21db85711c5f4aec17da426969f62c80431d1472958cddc81f783b85f9ece06a36ea61c88301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076c7c4c2542fd10ac59b1d92357ff4c561eb159964a2bc4867d44c714db9aabd9331eccbc572b9041428ab3c4ab118c000000000000000000000000000000001910d94aa6527b7249ae61389b7cca586292f6c763e338c7a2daaedf2d78742d7f51a6f657d47ce116a4c09fb96836d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a3877c93f8c89d225b6f6fd5633ceac3b7e7495cefd0af8a25e9af7f3e804fc400807c260880e689cbdd927775c7940000000000000000000000000000000017c119ca025cfec4e98413434e58f27c70d079a0b1b5fc23f45dd850215b15c81ad4fda47a2152e3fe3121bc763c0b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000671d6d815def0718ab866827af3ba0a59193f9a74b19218a024e0fc1cd8165ac8019c8d04a70dbe737507d56a373b1f000000000000000000000000000000001640f288c3c70e136e6af37f379f0735b25250929196ac881b9cc0d012920541a756cf390d014cad4a540568dce883691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dba5d538c9b449512b49e54bc2ce9cc4ef99a985f48897c7c9025bb749de25209f4f9ead694cdac886032af1613c6600000000000000000000000000000000000dd0a9b60bdced64a0dbf4a4da92b8574da7f7256edcff05ed612d123945885232ac9e789c65755cc3bbd1af369a6811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000197189db96fb4f76264521677f2ab038d3fb8ecd3d64b9ecb4103004e4208faabab36dcc4b96bfe4ab448c6787f2d1a0000000000000000000000000000000008c6ae95c556d58c4fa2b9f09f551f937df26750753fa3aea3c98012906b254def4dfa75bc280547629fcf5309cf50411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175f7acc8e916bc7d5c6377deb56bc74ad3dd3859f4a02976373107c6cdfa2fa75f7cad8f22964395f7d2d0e6a65a2590000000000000000000000000000000003bba58ec2c5423d8e83ee81b1117b35c57077692e37343c8d91b2666efca10f661cae1217186695109dcfa3c86295821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d766536b28b41eb3a4c5c8ee9e49a7a535aef63deb0c3a30666624649295565259ad5e56d90af4ffa71ba341bf42030000000000000000000000000000000001d217a7ed35576c4791877d3c1e20490f447b5c282b4dcdd9b20ceb5999a1160fb24636eaea831c8e2642afe38a7f7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2e8565b9d3ba81bcc551a5515e5d71435afe1d64537ce2039d72b3c43e627b7ecc1675711138bc87b2cd4f24834fa3000000000000000000000000000000001293ad0759fe43b146ce53b1627e55d69d15dfb8740db827819bbc6afa78bec7006a009f6469537afd9af1b4b6b970c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68b4caca45b59541c1b3f3a0280d0ad2fae571d9925f952c6dd47479364cb5566abcec2c4c54347cea55ac37a2e3d60000000000000000000000000000000002230479e97a8b0e6695d2893701705075a0f23acc4966deaaf16aaedb6a27cba1580fdde880188fbf4fcdda6e69e3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109ce3f251c9cf8d4a7d3bfc39b3f956e10f92fab73616b9d8c28e8781b487337b785bf9021ac7ba0f7cc96b05c3dfd300000000000000000000000000000000043a25257d2fc16a749551d0c6a9bfb3537a4a91ac24333201fcbff752d7fa42e11c568948eafb1da2ab16736a268ee21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a08dd6f72fa8bd1297c694d0b3349b60da33964eea2752f788d1b9e6eeb16d93241a1784ba600d9e4f40fd36c668100000000000000000000000000000000075b1eae7208070d7cb6e864b6861ec91ce3bc330a515d04f52b9bef11a1368f6b16c0aacf72846e0bb09c5eaa623fb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6a85d0710a2aab1a7afd060b669bc30e2e0f7036024778c7e59b7b870b6da129c77d10143e5627b89d99228d84eac0000000000000000000000000000000013b5b6ac8128c92dd980c984e298ab19190fe97462626660e4352c66bbb435fc5c6e3fe81424848c68670640d04d31d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5b49a35c7aa86bafd2673ea48a6bc7d94ec3041017fa4c358483533c4dc3f46a2162847f20c80bf2457bcbc01b6efb000000000000000000000000000000000e16c3ca5a3952a38d97b9b7f36dab8c5586f2e9d4c0928cb74c463bb2e26eee140451527fe5f9fb846c4b47b5600f521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032ba70a3ad35e8a86cd3872c142bd4c10ef6e817fe353a14de6da1baea7d7e6abc5edf8446fc887929d563eff19647b00000000000000000000000000000000185199f8fe88987dad9d5954258b3fa8432b9a9ac77a211cc79f583d407cfa9c7462c470d485227648e15247cd44e3641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136f97e62d82e3b12db1a7dcd671224cd6b0043df2efd260043b363d653e16b3c21b087f78531137ad149af8a3e212dd000000000000000000000000000000000a8b9bb2379b39966f32331141b68f059b436b718cc6906d3e366712e112a445e472ec3b5437eb91f28ed670270323f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000747ec9b5e0ea16d54112f042aca56a220af0818b3169ffa0f576c0f2ed026a2dac40f6b4e53eaaa7201312e0ff867b10000000000000000000000000000000018c2307cad5c686c9b0f510e2304d9af2fbedbd3a79f4d6fa2bb843143cde9b29cd4d6570e758b46a567f55908854f861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bfe1343fc3ef85f8cd8558bf0874b1f63ab666d0b93cf7980c01f389aa36093135909fd96d04d405f5239f2318fb3b0000000000000000000000000000000003915ca17408af1ff1d0d3bbd1cd808d2cf0651caae41dcb2cf807c33e1f38f53bf2bd32ac28cfc6888a40e68c40e62c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015291cf122c57e841f0dd8eadbbb011beba59b1d517433b4ecf30ee6bc71e3f91c1d3853b6ab4673ea0933f5df505d030000000000000000000000000000000005227fc5907754b1f4baed066679f52f50458b6669b09dcbb684d7533503385ba23d135b59cefe45100d88af1344bf641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c345c525fce9ed80720bc6957f5599dfa6d16478cb45906b0075e58ff68680d773be95846ee579947473441a4b269e0000000000000000000000000000000011be34369216e5b47a06ac9e4cbf6eaf7f3bd153bc160ba8601be175e3e50c9309d60b43b9a67543c7576a2740de799b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001633e75703e50f09beaaf93e668a9d8d99b53e75146eb8b38adfb9668068603b59afc83c8c3f7c491a8d9ab555a78ba2000000000000000000000000000000000510e399dec9bb96170b3c30bcc5c356bebef14434c7396825b445c98a8bfb92e512432bd8487e056d060c58153a1f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062daf4ed95025a94afdcb7d3df41be235239f402478bb208c65ed6649f2dfbc7f90a9c8452e766a942b4268ce9afaae000000000000000000000000000000000338ccb2175da5919f1286ba923e94ad7b20b46e8262b039a3efdaed6b98f7581257b94c5a464570ea445d5bf6397ea71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7c32b27f4597466469e90648d7211c35c7c54365cedfdca3ff5bbc063cea7e1ee2293c312b5fdadce4884d33cb2008000000000000000000000000000000000e80b774031e97fa5b86a120dca795cc4ae1577401494d27ce601faef3756438aa024a9b9eba9fdaac68749228ef9d771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009198de864af6e2b9d509efc9e50d366dcf20b78b58a837552a8a5861e77fee88981bf17c9c382529bbdd1d7655d54db00000000000000000000000000000000087bf7d5fba2d944104b641c146f85666dd4d4d8e3c36d41a8a63687fe25a936ec77c2182a90a0c956527b9901198aa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000daa49621dc933207babad854829477c85eba58f348d553edb2c557e128f8e3a7927c3994170b44f6ee803251b2184a80000000000000000000000000000000009d7a77efecbd0090993047825608cbd77cb9e1903aebc214f0d0cd1251e8c79b8f419d1df380f00c25cac447888fd721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001882144f00f49bcf882d2e83b3730a4f8085e4070e45317ad676eea90419f616f1253d5dde01bb52a5f6c71717f5393b000000000000000000000000000000001409ac44e73bc0a065428b5ae3099554d97f545b5da8595b36e874483f1f4c1e3a61f8a7db59fdb6ec93a0f8f10befcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178a786866c02cc8289ed1f9a4456debd85c4727ae773b95b604ae3c99f1618bdcbdcf740c5840b9aeca0e5462eb616a00000000000000000000000000000000062a98b2b811dc8f6bba38c7a5067313251d1769f0592ae2a56de5c2777cd309b195fc12ff38d9326b06eb64faa8edb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000850ff3c7750c2ec22b6ce17bedf4288bca498bcc42ae2ac3f4d4e4542cb71440eca8cbe033486556a4c900242e5612b00000000000000000000000000000000030f428694dc02423417374f514ad6462577de3b4a8452bff5c490a4a1a5910a7e490a86b1bceae660a076b8e401629f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121a34fc6a5115b57c0134811a10d2e8e74fb34dc6c23409d48460c57e20f6dfdcb2f31f8979973940de528dae17928a0000000000000000000000000000000005848464235e71376758db902185bc4da676b9c9bc9dd1d18d93c5430f454a8d2d75ad168a117b9023c56943192fae201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ad329e17c0e8041e1ccca72810ce9d615695c47d12ecd7c36450601b801c9bee2e309625dcc9b17447b3b423d72d910000000000000000000000000000000013c0ff5a0a98dd6cd68485f616a1f7d6b2967a0eee8356bc7c1a75fe4fb8762e38b459cdf58bb6ffcab1a6be8a148e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a2510660d7b4572fd5d665f60967f488db049b99a5436a8f3dcc56db168656aa2e0d9f410fedbe722e7a7b2195e45e000000000000000000000000000000001086630e48bd583bca8b3316264337b6a9ed8b6a95be56954ac953449810d230be3b21fc4ad8f501e3a16638675182cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7cf44851078718c57eb94d83fa431159ea793524e15716e76b857ee1317c619f58a05df19f5ba9a5bcb7d187bca457000000000000000000000000000000000ca4abc82f13b02c64f84e92497eed8463df5bb33a024f6836c805be3a5cbc094ad3716cff1f594d766b018bc80d670b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc42a196e5de18e38e50d6e78c16e26e2eb357e07015c3d2a821bba5f49c075b48d1caa7cda88bebf88250398e08e880000000000000000000000000000000007950cf6e46c5c03a741f3aeb1913d63f0673666017c35614f8673197c9dbc3468635034bfdb81d6905b543b501a2b2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056a73740a8f8293952af8f56ab236f12e1f3a61e480915243956d1925662cefa2d069cf7c3ee95041bdbc9620a584e9000000000000000000000000000000000f2b4844d222eb5264d7a906c4f7138db93e1a428afb6ad71e86fb98bfecf9613e4ed4a3cda5cbdabe6d0d532385a1fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000672693bd02a6d28f509e0a681f8c90743921e2d53a23fb3a53a7414245f4063cfa90798e9eafbfbce478dd0b8168c7e0000000000000000000000000000000004c1c8e666446bc8ef7c61eb75199f6c44d65f6fb7b5bd50f56414fb1692072e59264ebade0189d003a4d49f124b002d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040cd3f491f52f0ba00187cf1d43599b6e145be971d98589df0a571c487527737dc455c6b4221dfc4123b446f0f0e6130000000000000000000000000000000015a477eeb4669b650162b5b1fb111c5c6069d849e0b22e1526f4efff3d979d26e9ea10f5cdc8c2d079114ce84ba331531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d66395114180964febbe8bd6d44290e5ce746a3089fc9cdabae8ae0dd12a90fbbf7c88066d32ed7f0be40633b0c9c2000000000000000000000000000000000d9729c88361edac95c009817a83f1323d6747cb9649a6504a7eb38f0577b802617c704aaef1cf39e580f9fa4530e4821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b04f72a50cbd2bb52a99251de9000835357aea307d48c9eb8cd45a16b8def4a1fd2617597a112f82ed0117e6347c1d0000000000000000000000000000000015513dcf565eebd724c6f68066fd36abd0536c445e399d3492d1ccefd1b2ff265617f18004ba758e87d2c571c47c6d271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001662c47a593426e52945c2dd1e718b1a529240c428c6b8bfb214f189715d908986dcbba1773ff1bb293fcbce70482bfc000000000000000000000000000000000708cb1fa59c9ab3e7d849acace0e1e7da0465f3cb285fc5001a55125df277083f7b8c15d830c65426dca12ac6d498dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e1169543aab09515b6b0a87d3a4de948c3d90de680248e4091ad84223bcfc09f81ecc7264344ca1daf0af688ed47ac000000000000000000000000000000000065cc54fefe9454be27c6f01aed65e2aee2c4c90a5a838dafc56855cf734f5f1aaa16fbbc03d8fd414b33f405b975201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f92de10d62a287a5d35544be6890eb6a6474452276190124ddcb5c3b3e757737ec9f627202a541bf86dac05e9190560000000000000000000000000000000008ba87543d6c71038cccf3414f7be41d693caaa3ea447d97d10814f8eabd4eccaddecf4e4ebcaeb1469c73e5aa45dabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f6a1c4220bb82372fe30495661500a10a7b5a46dfaf4365282dd09b170ba5fb999ef50cc77b7e885cee3e9730fd9770000000000000000000000000000000016d8ec09644cc741a705550eafcbadfdee1a9bb8611f71299ec4eabba917127610c5e782a9e29214c01dca81dbbd21251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6919702f7ae6cab9a16c552b8b4224336100b00f1d3aa4410372e14bd24e8b3551b571430007ac30221605e00002b60000000000000000000000000000000002c2d57117259b6ca9f789d7faa1d9e2832eda5e47dfc1f84d8c86e1598f97c7e161d21b5717be307972f1d8103b16741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a824fc9c92a28b32d6b4f2e06a706c78998e3f21635b1ed651a055797638d8bc8d82ba552dac71220fc4f5afb24094900000000000000000000000000000000013ce26961e7ed33a58c83d0f1b665937f99af31f217ae99f1e12f66e109fe70e76a7b01740f2287b11fbe47b0fcb7dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8d724e06257ee8313316ae9759ab8637b25f9dc94aed0986a695cee4545b47efe6b685e4b3a654af7754dc1a2567c000000000000000000000000000000001959405099786ef965d172493898368cbecbfbff2b1669854b14922dc9b8fb607109a95af8b7723fd70daade8675eff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f33e622738d50d92da1ed0c149f048d5e43c07d468cbe7cbb05060f4a119702a6c6bc876b84e868f563d96660329db50000000000000000000000000000000004c54da801b474d6a2dc81b982ac350521742816f25e1d92a1d527171f0ae5fa9536255cac93eeac417956ae56a7ace41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000715923ce6e7ac79dff184b5a397945f3e334afaa4525c4e5dac3a74a111c4f2295343dcfcb55f6ab4cf8680cef3e9fc0000000000000000000000000000000010517da1f4e8e1b551fea509eb11bc28ef800a31bbc11e2911eb0f983b06c6d023c31d6845bed72e3b61ebddee7a9db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ed086a0a8908828c15df35654a18b9f36ba70fad534924426aaabc71ead4301d39dff0fc29e71f6af122fcf6c177b000000000000000000000000000000000d04bc14319c2f4f6d8da3c865da1d1c4024539de73c5d2e78989fe7e64ea92683316dd5fbf32b15c73b4e4a1ec315f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076307a676494c98bbe93dcb7bf21a7f3cb94047fd0a85bdba941a072411c0be58cb4154197db9507d4071c8e70931350000000000000000000000000000000002514400b08c3af8b30d40cae95ac4b8602192a0c067bff97107337435cd1d2c4a673b1000ef00a70f61875c17523eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7931f68cdc71a7527b22053e16477d8787012efbfbddbccfe1a9e4acf98b365e10001b968f469ee7e4ca294617c09d00000000000000000000000000000000100dce988aae7974724c229217a4daadcc8ad01f123f7cc4c0610e205a88502fb7df464b6b0e035e856dd070f37484811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3d73fd450306a19340b9218d1817222043cc64909b4b4e5c14ba17f3d697a767fbe2468802d159355f0659377a1323000000000000000000000000000000000ca66e1855a634a470f2972e01eb4ab84db9402e936e5759adeac01c85fdb033f114502f7fab6d99edb5b6993edcc75e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193a8c7b4eb2cb61364a10ccf547ff2960102286a88eea28e3ab52cc7c24641e46682dc716da226d66bcb31f4440f910000000000000000000000000000000000a31ee48a283f35754f6cb1973dd407d2fb550cc7d0661e42fe01bf6681f1da8eb100263b12956072aa1ab08fce3f2491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129b98bb61b15c856b17d64605742e402fbbf6c1880c0fbc0d731aeaf7210c90cd8563438382f00134bb79fbb1575e2c0000000000000000000000000000000007a04bcd1da99dfb52830ac9b08c0da7036928bd3127ba4cccd004359c353d986bc08fb98a71ad32e1b9dae7d694a30f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd143085086af59b500f3d1bf1a4af7e4f067578c0d675fb6fab135217296313227596d69b405078dadf74a19d7c47400000000000000000000000000000000170e4f9ea367e31c8f0a4784dc2d18ffdc99bb76f64e0f86d5c7e445c3d2ac2a82c95f5c6eb337ce0f0baa7a5c39698c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002aad4df3cfdb6e2e8c3045f44c6fbc5c6ef6b0cfe3089c020007530869fa6123d74516ac00e358ca94d776fb9824d61000000000000000000000000000000001432bc44a959b4230ee3606cc5a4e5d4fcde3f135a668c8c3e147b18c80a3afad5868b47bee2e7c0944651c79a3448c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c2f4087c429f13b3c69661cee99a4c7473ae5b809f9724028f46ec1ff05d69bf62825258948356c233ce7911476fb0000000000000000000000000000000000883c9959484f3e829963955a0ba07b38c32823f2bfa33fdc651cfeccf79f46428efd930761136d6686c422b60bdd6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b53c1b6105762f787332a44dce9d0aa6248110d701234f5f3e0568a3b123732e5e9abe8bb2fb72931e55ecbadf8fbdf0000000000000000000000000000000001c84d0fe0f165847f00d399bc293582a06096521144f4edcc5df8eee45449f138284a78b09b67ce8cd0e2d56d5993441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f53d0ec0ffccffd5993a1e8ddc99aa6ea16082a8b55aee86be02eb69ad8220b37fbac98ef8bdbe153aa9ae996b4a42000000000000000000000000000000000327a7f5b57018205ebf1b3d9f365e295281eb94863bef7bc1e142d0e39736858682e9282a0fc28177b8fccc8a8022461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001774fa60d000130201997d891105ab4853718ed65899c6956b277d93fe45fc5caa2d5eaed0dc87e74c453a991ce9add400000000000000000000000000000000062402079f62b7a7fa3d865db00a7879dab814a31d0d90ff89f8a552fb802eb2efd29ee151914c60b0acdb9abaee69621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083b0c4a1b70cf9e94d07618e340cc5d7c5337cb2ed576ba5b872017b29ea77639a7a8452173756c39b8e364b0368822000000000000000000000000000000000b15c5d33eb74e7d391f0399e9c7d3065882ae2d136f3710958478e2069e2c336a405c56ad83c21bce29700d6ddfe1621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c9bdc26cbe3fa65c5ba4433558d84fb9a3edc9f6e2d8aa0b581ba781d7a8838ce59153a42ab81954b92b81bfb7016b00000000000000000000000000000000156b9640cc41ff582f0d544e3aff9a6887330b00378e6044e3f93a5ada5e810c6b8daaf00a180ff57084bc6207595e361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b26f5fddda6aa833967a69e6918bf2271b874e31e94c0e5b4a8e2f0e46c423781f76d28f140f980b8879316c3f0da60000000000000000000000000000000018b10c8f47127c1bfee7239a1364e9b1dbbf14abc4bf18c743e69c36e7cb16822e0897e6dc82954e55de37a8db0f07b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086d5454a7a2bde65d6543285af367317ef0c8043bacacb82f1ba18400d39f7bc5af1bf9651e96003cd8e7041e1bb9350000000000000000000000000000000001e4e3b59f526463aa2cb31596dd84649397c82470f45f6271d50ed0b1ee9a451f95e3d958d1b19d6e36128b76e52dfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f9c42650ca7287c7c28857f9ca4d1ad77b77a3da47179e9bd28269e146856bc935b349e2692784d3765353fdfad7f3000000000000000000000000000000000408ac5979e5e1c22ffc4e6ba03155d5b358dc959f23df79a2a1a8f49bb5c38de8e5983e7d4637172b78a663ba15630e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f562b2ea047c1ce4cb0378bb7526b38d89b361c4a92420cc17e89a9edf25c67ee5bb1a0eb801cef6e5e8c1d8eb317c0000000000000000000000000000000003708d2720bb00c2f56c2d0b9ca7da7f721b7b12e2de2bd5982e88936379e054dc595b714a56717b54014749870276e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014103917b6e8fed3744426ddedf51e984c11521854f224d5636764e4fa12861dc3063a0d75e69e2c891de3a4963b5cb8000000000000000000000000000000001527172ffe2a09ac050079a43efedab358356055ec83db5815f4d5f1094629fc246e0fe58aa1cb440fc3a75f59902ee31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001370922657c96c5044f083f6a5e3b4c8cdce02590f389311563a526f7d71929ed75dc684c1203b35b630cc601ec264990000000000000000000000000000000015969a1981d6236b38ff248e0a1a41a17ea6355937ccd017fef21c2642be3ae74fa623028251f800e90f779cc85d369a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a993e22f919c4bda34d75315aec03ca1e5da527d20b358a65ad29ab8a5bc9ad117bb81402cc44b79914574474fd8e340000000000000000000000000000000013dc77a72edd884e685f865f08cd96f72c184778caa38c6ae6491f625a3a517fe2aaf7fed0ee8fe23c5d39a60dd54a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f6a7820ad1b602075ed673fa2e66f10956786cea667b7faec790c17df1e5a35a9c96f38a5de73d89f6948f8bbccc380000000000000000000000000000000013479772a2a2a58ec53700530f4658b151b66fc8065c32afca1d61b5c3add9ed0bf0873d4de78107c10c5406c7a67b901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072ae9d9ef901316e3ce208c37c1f5e9e237887ad61fd6d28ce0405efe50d8466219f7e57216ec8e1fe9a9cf477ffef2000000000000000000000000000000000d2a652b46f219faefe8f2e55f7c430de027f3226597602756c0307c1694009bb947cca616fc32c3d449c6750d5d2b891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026e1ada965a3607ac249608a1e0da90e4ae1cdc71157bbc7dc303b8a7405af8ae81a1ce87d3a9e2147382b6c497a9ea000000000000000000000000000000000d50601a103b5e89c869ad9f3a8456b5c57e1b5216177dd52c9a5b3aa2460af8d81e247e9b7160b11ee0fd103453247a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c221f4f8573b8afeaf8195295a7e9b00a451c9a03f5b6814b3a5419b844d1d13978155c3916e4b2fb89ea3977c3f7a00000000000000000000000000000000034352802bfcd66fa3675d880531d54aa74fa4f2e8dc31ddcedadff8bffecd8988e058a97f102c5d0408d7947aee8ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000690ff5934c5190c3fb58edba3097285de24f8022b35b7744b2c7d8d476282c486f116d5262644643f31d91041e49e1000000000000000000000000000000000185fa522c936371ef023aef0440b850a18ddc14baebfac726dd111cd62a8a6b9e7acc67a428f19742204be7d12dda2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d687c35fb1aa4494c9545adc75fd82b18b90c398b2a8d1b488c37c611f8ffa7b2493c2d657548959e9a7fb04654cbc0000000000000000000000000000000016d1fe97b32985940459e15fb8efab3196f9993ed85d9fe1970b81515f22305a9c9b66ba55a1f10fc4fd7927847ef52f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a78dc317c72c8fcc386aaa28bc6c6aba6678f804e3b1ed3c3f1f5ff56c20e89c32a5dd0139a9673cf7629dda37d7e230000000000000000000000000000000002d20661db754d9cb9c12bda65f89f9b863beefd82eb4f4214f2fe688a5e983a062fd9d896a89067625b5697451154211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b858a55751fe0546b2768605ee7be43d49acfe34b6ccbf9d2aa5dedba209885cd81cb0937ba72bc138f835cf76bb83000000000000000000000000000000000cf51732be8f584f527621d50537b0eecd8dc5ca2f3402d7808f8e379f1940c0c1c756771da393288f16e6c24242f1f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf30763d77fd474cf5eeb2f0578da92a08b26b072bb8758363e341001e52172ba0382ae9e3d3f351ed9912189a19fb700000000000000000000000000000000088df5a6249d00be6629772046a54ab790063dc97025af6e3b1a67e71cf76726f14403968547a2654c57ce819e3434cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019be6e3bd07f4c6fbde9e010e177c58d8e67b60f23ee9dba7933191be50936646c80381ae5d50e66714dc3ab58578cc1000000000000000000000000000000000f28bcd77cb730417c14ba9a4ff5dc9ffebf6617ac94f462e862035dda2b6130a6f235f923bf3e4f3b404b56854c4dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090c713a9027b9e49aa3f468accc7552564899b00eaf8601d683ae79f3ed1d262583d67375acb949a63bc66642ad57750000000000000000000000000000000015fddd957ded860774396d9171280d066fb15e52ee03641590bcca1b95c07a24abb654b9ff83cbf050b263e8c3d86b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ba11d10a62d1a736ba94e4431d62fcb96755ebaceaced3b8f3e3a8e7b61fd37c880fca7dc236a41ebfce3b2901c688000000000000000000000000000000000734f7e35380ff40b608eec521e81bd3a988ac1e4a8a71cce0722e6dd9e7002537cace78e23118d689c639f8689ff5841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bf27e5ccb271f878ac2e434ff5e26f0a166fbe9f0716eae87583fda93a60a296eb831b6492c54a601089e45604554e0000000000000000000000000000000016479994cd51b03d2e92be2cfdf05553e366222d7c0bac75ac729845b53ba5466e203ba69fd49e69834d01317c92f52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e8bec5b1dd098efc10929a76714f7279f3561946ddbc760220a038cd5f7f9a586a23c6f1cf9dc66f8e7bbc1545e384000000000000000000000000000000000ed599906fe5bf2467d866578746cb99b1258f816621868ebdd45b03dedafaa48e4fae78622ebce553e57350dfef7bb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010fc1c5cd3d562db1f343dac8e3aa3e5aed9ba692362e61c21517fc7a01a150dd28249fe405358159614a53b073da61900000000000000000000000000000000121f936933d1d1869dfba5df26ce06432acf2b3a882cdda152f0a6ae849a0c9372af34c6c48221943fd50118f0e5bcee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb4868ddbae078cc1cc7a606b0a420e01f3e806bd8e15ac0a86fa881d2be874aab44b57bd3eb52608c3d71052befdc80000000000000000000000000000000009d33184e19ae2d3db145747deeb5ede8d5e3e538c08d0f8d385405f5046e8809b19b788e58b5c48c3e395fd17a775cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf4705a623e2076c4e6b809ca1d9b5f2b2c2f25ccfcd4f0fea73fade7c5c416ed7d46ebac6ed9928ed1cff004b2d6b00000000000000000000000000000000125558adc8a55b0aeba9bd5ece3660f5119efe5fa0b73a236941c509dbe07609cb95e100ba08636cc0ef0f2318bc2fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001726d524081c1c7d38d6cfa8327aabff05a424e6670a7eaeb90b2b2f4a78f6f6eec453bd2d0b5007cfa948c8fdc12764000000000000000000000000000000001081fd7ef04d86286a39f0da66b548ed09ea0616d87509964d8c7bbef1bcf8245807ccbc8c6ffafb21f077fac9a40ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061dc1cd7463467db9e032099a286eed9f2d78dcad3e00fb6614d53f780c7787b98544723995815ad9f939f68378ceac000000000000000000000000000000000ee73385aaebb305770b70a449ef612ee04563b3defbad5b88d73eeff6f5133c02324c2d9a24869b514b1490f258a4161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ea8117f55e1f43805fdfe5fff4e76083bb0f9458b746d93616bb6c89c593f138bdffa1d11e83e0ff2cc518d5251730000000000000000000000000000000008b2ea2670245628d07c6f137e77e46c388c4cc21fc42d7aea10bba773cc945662f0fe674e05e04700601ad1914464f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f8a6cc8b32143b6f80dc723cb27607b41afe68f1aedda205bc081d070533ea9a538b56e9220ce037306780527c2460000000000000000000000000000000008feb8e8ba467904c686df242263e896aebc54f62514fd7232aff61eb04f9f4fcbc7818674135c2517bcf834268b0daa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e512e45d5ed4b359ec0b42a31a5c5f15a3fbe8e984e71c68bc39169555892491485c0ab2c5fe6e6a00b436372f6aa00000000000000000000000000000000014dad4da37b721b9f987ba6c16492ec9a4883d062cf02aa45de70d3c72ddf7ed975abd15f3b2c4191314275a11f7ff261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdc3ca079caff9b2d20319c102ca20f2a9933d1794f8ebcd805b5b8ef643d4b4a11071a5aae4c1887ed1443cf2db599000000000000000000000000000000000f65d02c51e897fd4c909d7b44ac173f29449eb3f1b37766acc92f1fa55f49c75ced4894e50f88dcb1a54a582f06eeaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000617398f5b306f1a5b4afcb8805d97da687a91fdfe4d14cbe00ac80b8d509f24e18c87dd47046cbc14693c77b74358de000000000000000000000000000000000dd19d684a5413f6f58d24f901e99c1350b122bd158d72ceab6cdcf959a6d692e5ac8711ecad4b8a753c6b7aac37a5c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b99fda2ab5c242a761de7b9cbe92d9c1ac8e6faf7f956f39fcdd1644eeba4fd15a06d4c3029c0677bc63861a16e0d000000000000000000000000000000000fefc199aee7d56105c99c011af13952d0a9f98c9de3a15fd095a1909c5fc27d52a938550ff63370c26844bc1902c6931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080bbd7656576917c95efd49c38add44b842a3bb0780eaa1e29c4102ff12ce5a811bce28d3faa3cc7286a23d1db7d0a6000000000000000000000000000000000ff4a0a4b654305dca52c309a73401e62b6b8a0e2496fb06d81b29d6ff1dadf8e9f2a6fdb429e7a07e0104cd7d8401ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012df87e8f1321e3418c4d8d3d5a400d13de389965c816aa48716164360b7bbe23a16fa3b96527a68fe178f831739b2030000000000000000000000000000000012e7f07cd470f4106512a0237c8cffe2e790eab8873482782df1d848a8b7da01eaf49043636d9743002295d864979f631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e023fd775c5e221536ffe0caff52d0fc46da1b865289ebca1f2e7916d8dedbbfb13f0919c9630a85a2f4abf56e1d835000000000000000000000000000000000feaca1ebef354d3efee51cb092f22ef6d18d60c81eca69220e875623498b59adb678f4a51f6d73ad9f44a3f4703431a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004851c061cf5a76a27ec2a6916eb65d933397377b16abdd2ffc0684a6858f1198950781d62ace5e23310cd60c7e4ec3300000000000000000000000000000000069f45b557b350b06d7de7f3fa18b1f867adf765654ea2e3254bffc958bd907ad81dbe1c3dca58dc451c592685ec03341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d50b5a6070393f86310dbc27d80974038be82996467b09c5e541383d1f695c8dab1f2f6b2d60267459d3425672531600000000000000000000000000000000068e9c0c815e43791245b639e6c13f3e627865ca09b1aed65248c2803f0e340e1f962f57cf356879ece089d02f72033c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aed7ff562a87ee20e9a8fd5ded84eadb2e62e8622dc146077bc4c9e59b97e9dce45a04481d73c1e2279c949e7fc30d90000000000000000000000000000000001f53dedd0aa856bd0e6db24b0976c7e09a6b0d3031fc71d44ffc7f4e3041780f37adf0ea2c2df98f19dbbdd840c22df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199898b9589ce2d703826aeb491f5412f8f0a785c3cd5aaf89a546f2df680e7162f2cdd0704b2ebd94371511da5da6350000000000000000000000000000000008ff4ba7203e15210eba70141f5a8b814875ef0646a5135261058b6c1b4f741f48fbc1c71d3ec094f3fe90d651e18c7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000133c30b22d35853cfbc6541c02bfe65b9c598c9a570a2ac517ee3cd987b47c15c8d82b3ce6b4ddf53d540e45caf592a00000000000000000000000000000000139e43a8dfab8c200542bf131040122ab724d7a969ab4bd5c28881489fbf7b185494c0693e0db9d5e7d4bcd95cd63d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000568f762dd79782e1dd13be346659ef2b64e1bf4b22734e38d21a5586a5ea983060858c96d56256af2ee246ef96a987c0000000000000000000000000000000006ae808d1c8fa32d423c9805067dd9e15826d8384e228c22e135588ef37b7b382bfb58a98565a4f5f4d902591b97e4791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000662e5c9303040678501acc58cb56c3a961538bab72897b79b7994f4f83c8b330e14e57303aed79523fb86590227f0780000000000000000000000000000000008e240f6cea5672a9dc234167b9713d51418333e9e06d4536b9321a87443a62130e0a8a8bb0a3d31dd0c78c23cdff1071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007568a18c2633b09c7472d7612418b6e08204c7613ec90e536fb74535199e5707d5f004144b0a4c9b910d66cb334a2a1000000000000000000000000000000000f017bef971a3cf3f58b2760125e26026458ea50dadf976c6b5384043e2d507101c0995c636afbf5989fc8ec0c83f0931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144e72a0f9d6a789a18f2b48974db6a4ec224f84d0e42e4f6d15c53d75ff2900fe0638a33834778453fc0a5cebae09250000000000000000000000000000000008f3f5732c8419318395692356e613ea5b7b7aa5c792714d06282020a87b75dfde2ea522165a73ee9781a763b86c700f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009daeefdfb67a9de5790ee06eafac7dd40d31cfece6ffcb8c49f8db9e28a0ca64431cbc2d967e731fdbdecfb07359c3b0000000000000000000000000000000002660b5b7d8571e5c02d72a63c275df4493b4111263f51e0d19e1467676b9beb76bd5261ee7b17a0bbd35ea0895e4fe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d9baac61892e9e7b47740d421e50b11adc76a1f7e1a9fbc958a342d969322cd6558f292d803c37c6eecebd1f41e748000000000000000000000000000000000cb0d2ffb62e6633d5a526b5f2f2f7b787b311ef61041c5fb2ebc95d6a742ab89606d0e8d82694d70177d6a2305494711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147b2beba39c95bf817b94a5b80f056edf03ea90cf7739e2944c916b74700f9bb759dc71b2980c3a44ccb9d3c3bd34630000000000000000000000000000000008bb29dfa3a71ffad8669fb24a0c854f02f70dcbb372ca0bd90383cf1b6824b22a857ebccc5d70ac9d48be571952df9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d10a58b7d344f597b8d0a817e81bf45e936642d0ed280c2956351660d2359444a319dd1cc1dd0e99331919fc5283ce000000000000000000000000000000000291b350eb996e5aacaea1c7b85cafa5103cdf27e0900515f734c2257d12e2fb694f9b49d5938e0fc4f51c2e7b57cd4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b74049ebaa441f0b633adedf45369759917cfe2719aa106d7ce098679d3b2ebab2fd420586bdaf222749348ce51c4a00000000000000000000000000000000004c5b5ce63041398a9b9b3749694a05670788bbd112bba82167e3af9e60b9f00fd3a74c0e691d4c3b6a3812279f931fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3a473897a0c9627c3316d59ffcb865e967378ecae9655fb68ed600afaebbb7396ff6fa98dab3b90ebade9321c08da1000000000000000000000000000000001179a9c27728246d2b18270fbcc3a75d90e89a86c75a9e6d55afb4582e359ae67c58ff5e3a4256cb4b8022f199dc41ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176dc15e0315a9b8fba926acf022dc8a474e2c78047a5d8b262471cbd4b5cca31a7cb40d65658b0540d44aaad894ae710000000000000000000000000000000004e2535d6baf26c47aa7a9868715d7033e2b573a1f5577cab98e82cced81225ad7c704c48700ab85f12db8ffcecf47fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e928ed9031a7092eec1cd98f8952e4f1b5e9456b3a230df46bff11e21fc2017b9f6798a58fd4ef4d1c3b42a8e5101f90000000000000000000000000000000000ffecccf12d0ef136a8c4b287b5c7940f0495e71f06fc1d228eea137941b00e897ae08206514e30f5c1bf8646db69611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d923698a0a84a87b2651d551070f452a77d23b37ebe811289283c10b0b3f2d1e6379ba9445cb3a371b0a09ccd8bae100000000000000000000000000000000094048f938184f5b4fe9397ce5833a30389753cb9f56f04df23b9fdea090525187928a96623dd613363c440a826ff7851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55b85981e5c04c8f6e234779aa1fc3fe649b4aa37b5970663a1e77795b7c04b7fd2c55956787c4dcd07585a113768b0000000000000000000000000000000014649ac93c708f0c3e68374c996ee8282829b18872b3663583e156dc1fc8122b82567efb3143ca05ce134e8768a7d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001554ef148c60bc44c976226e21b7f90bc336e745aff96b46aa678763170ce768f7fea2145892a72071a9775119162f1d0000000000000000000000000000000007fee5ca613f94898766070ac7a356a96b135de2f11605ea91661a99c8657d44047d3b315808f46f85645e33c8975f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016895340406b1a747cf5fcb2b12be622957cc42b4697d0169c075afc98768af700f42008f3d845a592022c1a552ffce60000000000000000000000000000000006a46d4d6720db4ff2022bda0a5a62ca61303fc5a7500fa278c863812e55c5ea332f8659c895dca8a1933c8323a0cac31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130bd0b475d201d4d5b39d707ae7b4462ec8cda721259334f9d6f32499b0fd5e54c89ed4317b211c839aac82872056f70000000000000000000000000000000006a8eee8ef30327ff03d1e8a2a02d53e7d13066bf74c4a6a464968abbdd9a6c5e31db7da4c66c5f701dbeeda50f427ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030effadee585e20d5386d03ef748f96c2236a932cf5369332b14c54a1f2c4714368a35b4039c52e8c73f77f0a9f869100000000000000000000000000000000014ac11944192e35cfcac103222c2ce7229cb5e0e4193db10b33bc0d60e65efe0072ff87c753f25b845713cd1a9b7c1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126db1e73c97dc152592d8d4d50da875b157fd0fa3c9c58e61ea82b5bca5dda39d4f836a5a5967922caec9bcf6a4c6db000000000000000000000000000000000107edf16eb63c43f29240f6ab53ef2cdbcbcdff59e248465f642d93f724fb7f0e3c2158f175ae49d892ae621b6c05fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385e6ff86d5c54942c61f8f6f0c10089cdc376f47c0eeb9aac526824e2425887d2daf3782b8af6ba5f257c713733fad00000000000000000000000000000000109650f8f39a6ccb7e3055722322ba86f5fc4579a689c7f36beb2114256ad3e9feb94b72ef1116f40461f12cbe7725841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081f8634a94eef094070e6d3a1479df97bdf813b068928588560507ed2cb27241749d02df943d03d1dfc1b78534e7b970000000000000000000000000000000011b336e5a5da35ec1035b3d38ea8d8ae4fd9d32105f9587f582e56a8cf456638695c803d41a2abf466724de25ac9ba391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001102fbde1a3c5ca838afac5e87638183ba9adb82949d28f257937de9b34e93827235be696c38c32a3256002e51c0d2830000000000000000000000000000000015d5eb14a5a12c7fc388f49993f9a56494f625033a4626d1ff66addf6ba85bf91019ade3c9771398e16b412ebc5654941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd4564e079b268e02e8b974ba0616f5f9bd8262a5465532a60b115897e1830efde0536478d56ca37de5d54010d90645000000000000000000000000000000000f21442ccbd0f604b6cc9688c8c714ba38249b787e7cb94f1f80cd3a9d0c6350d001eb90db1c32e15e4991227dd0f2ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b83429b471f82ff9f62cb2e5402bcb39e8720ebad12b0c7988a81791011bb1c212e0c7a20b5ebf2dfb03937fd7effb000000000000000000000000000000000f8cb80d6b2af497863828dfd869157ca4b7476b5421ffbd4c56054c6de29133e1040cdcbd83bcd042c7d47dfd122fc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcc03d5a782be1834611cc121c208cae4266ae284b79d86630a984899576b6cc61781c865783c528b45b0de7c63ff3e000000000000000000000000000000000137d5c4315f6ca01c1c88221814a6d5c4b5895ce34997f0a34bc6d3eec9347c7192b199d01ed440aec2369a7fceda7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001299694f05b673207c48ea5b66d245163e95f6f51c08c941f53bc217c6426aed372617b15dd499c68c1839facb16d0900000000000000000000000000000000018c298fda0e18eb2c5fab6ab2c33a9211e8ad6d41dbdc609002a4ad61cb3e6af7d4a61a1b2e65f7b782a798cc20384251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da7ca038fde08c0d01ff030484fe24e446573aa5d30f21d0539256c1ac80ac2cad1e240728e779aa4bce204834a6d300000000000000000000000000000000143ab5e494603aa04f7186b87257394b1a02069f0ac487121524bb734538123e5e88fb18fe45861d18eda761086e9e981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141fea8e72117d32a28c67c8032905e2a9c0914007f466a444abfca079075fc1929f091feef72238023b1b1e561df2d100000000000000000000000000000000036279deb5601c9a975f8779747992493c583a55643d3d9ab45d6fa55c2b22890e2833d3121f0db8660760654f8296be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e9a7821d4f61f9c6ce5241d294cd0596df6b435a1fd28b8905bad742da45ea2eb0e0a5483f5dfe4d8c891b5a311550000000000000000000000000000000003db81d0f056db8a975c26a96111e6ba918fb064fc95f5414a7f56f64e022e25defb19fd48e64461fae0d7e921c7534f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001056bf81c9a3d6c848973a0b4697a6a42ccebcee8a618bdbcde792b4c3f3f92b00e006b932017d4863c1df03b68893960000000000000000000000000000000005467d0594e44290b6273d8c9d3f47bad4c6bee27a45142b892a0d6f90a29c4db5ede4ce58bd59d7b7edeae932ccd4a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a5b1b28c3a1bce112b21afa50dbd46234b89ee1f91d735d59b72f183bcf107eadf169ee547ce1a0b9fce5e86e2872f00000000000000000000000000000000013eabfc8944b22af3e1098724aa788260c16aaea5c7b624a02d867e8201b3428105a0878da9b320118b0e019bbfe1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bd87ff830638652e9c5b1fce066aca06ff92aa99fe46393674ba217051fa972a42a2ef59df948ffaf497117d3395d100000000000000000000000000000000009db3eef2ca39294c2f953b94bcf48cbfa7395509184f8bed4cf68bf913780bd7fbb35f332ba89c8cc8ce20ce2c915e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184dbea0759c96dec441ca01ba93959084e874583608e8c9d8a8fbeb19af674a5692d22af75bd46655d70182ab88808b000000000000000000000000000000000c1786f7a46e188452457b69f8b7df4a575062083def1602c6453bf7f3059ef7843a503626652da9fbcb66b806a649d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9a8b92e3672622b4c71e488db3459885e3e41b5c554b3725196a73bcb9937344374ea259eb5998d4ef2bff4afebf7b0000000000000000000000000000000014fd6ba80aee046456da2d1a442019be90bb927dba8f74c7963dffc29950f576dbfe7670d408a1bb4f765faaa70b3be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaeb58a508f7eb92a4ab83a7005f6951c31f9d56dffc5e8f2f857ce7f2343a30f999f3407e4fbb8e3fca8a6370ae3b60000000000000000000000000000000009e598a46a06a887f22a63d98ce2c768bce86fa57b5824a7c270f4a3bb345301efb51667ea3c2654930232ca591cf01e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e381b8141a779006ec965781bddc64ebdf8d1d9ec3658d7b65d48fdefbabe129f5bc42c5cfc77960ae01abf59536843000000000000000000000000000000000b6ad8b406ebca6eee7e5c572f2166a583033250c6aeb70cfeea934f6fea4af7f8594e0864aa17b542c1d80e54b54d981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209a8a1c3bb1c85da1cac03629f3a1bffa28ec3b42f51430b46f7cb0de037a659588da61fd32f20ceec1827d45a4eef00000000000000000000000000000000116266a999af3afa74e14515e735d5abd3ec85a36992a9f82f01d0eae40a33e7c79712ab8e91f8248f7899861bd0fe451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e2fd3bb734927b58a595cc0ed40ad477e1f480aa690f4f9af7f9248420a9bf65a63f25bcc9eb0ab4a2f51a2531afd0000000000000000000000000000000001e9db2f59eec371ed108a643c8bb0e25ed9969c7b94efe60dbac0f03164dbf25375f07307425ed7a2998b48b40326601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040212c16c66902ebf81bc44353d3ba391c5b6aefc05f5c637dfde12e55c5e63fa8f705283d21180a2ebb365708266f300000000000000000000000000000000029cb5fef429ac10ed8b12412f11c1315da8f381ec728523f157ff967f076aefd0001a0feb39429e63c0405e6ac943d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbabbacbf35839ccc00d22e3be550e15a621b98ac545b9e9cf8551c65a5cd3c0290331d49e29278c9e3ca716e5a7f86000000000000000000000000000000000957646f5f592fee4d1aba264e1f7ac633417984e45b18e624f37f8b42653133657502fb25608276bf722f83ab54c05d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a7bd4db58475053be8079df2969efdc5bb47ac9f1d424efe6fcee3c23fef5311ff1f989ed8721e585eb5f95dd3855d000000000000000000000000000000000b996c80b2e3492c3dd2b9e0244373b5ba1b9b2c36292b8115ce1c372b9f6cdbb1cb9f5219ff9d6f65a470a5af1f271e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c2f0b9bc7c6db5f567396f4a24cef58151038aa022e35afe65820168e3af7f13a30f2a4ce1347f42e5b981c76578af0000000000000000000000000000000014068f6e954e92493698076978a9db21c5eabb1f94c9344a895a4201ed90a3468c13a1aa47e2ed8c6f2297c1d6ff3b531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f3b8e3dd11255f8748d0e535dd95024ea75892d9dba82c662308fc63dbb179c009e03e7eab6ebe9b25dea14ad85a620000000000000000000000000000000013c975868cef4873f827ce6fe397e3f4f6ed4c5d8ed44d76dbe3e6402063179161e3ddd1ac29f90c3515e5ddadfad3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f54f97965863c77a7d657feaf05bf666178331df0859eb4439520907e2a6b15bb4d8f5b3dd269c26fd59165fcfa1d50000000000000000000000000000000003d6a3df5d87af1d9366e88f868bf41a1367e39ffe744a0eef615c956bbbbd1f92c10b838151f4eed4765b8997a5970c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132372a6104f8f3555dfaafd263054af25ef0d8b005ebce11c9e181b00cc7f0876c62fb7cfeebd827c675af54fd0c64600000000000000000000000000000000123a7f5254772da34a2ca376e8141b35ae417c88788c3f72cd0f5d509ad3a7ad52cdcba2ff803acd3019635cabeeab481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178bf36636136b8b0fecc4b0d2da4e49b9309f1fce351d4adc4a4ef7546b384c17f3a820669227eac319f3e26b2803480000000000000000000000000000000010912e83d60b91e6f0645e1ba2578fdd03ac0a5540f9e5a54aa8754ae15f9d100f72ae18ea0ff20f4e7018bf218565ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0fb85c7fd63e97ad53eb91643f1d7a0b02c4b6b4635b55239c80cdf2e9a09481274442aa82c10c180fbe58d4a4cbc00000000000000000000000000000000013ef672c3d4d5a3f950c385980ad2152d39a695266a3ee93b3e98156b3bec003b29693c910cd96bf78179ade194d64c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001410659e4eb02effce055f8d9816e6b6cbfe69b005ba3570a741dca5b8931ed501a82a8f19d9abe27aecb9148136fd88000000000000000000000000000000000f34814334cb289a7be240d4d3293e19ed7e942d8fb88d0abb412e063e47de4e8ac6a93402ad97f93a4d2742363ac1b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000166f64a1c3e3428fb2a9935c9bcb1606f97fd53ec36f89f559616604742400f7ef88244f6f0133a8a34c92b97a843c70000000000000000000000000000000017ac94dab4a5293f8399186b9ce92d2e5341ce4fd95c86b3ccdfdc83659df2bde4945f369744aebc219c41da8aa8fc6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e64f64ce21e71baed7b1419fce470a86e952aa7d77ace9ef83f4c61b724737aca14b5f6a9b8afc96f56424aab175fb0000000000000000000000000000000015bb2898673cbd1efa61d66e4d8b6fd3913319e7eb3fd2b19f77828fb64725a4d403becebe0667a18c3a87468c3a46ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75a579c35cc744cc9cd5d71a46f9363c91c35b3f24a2a8e62e242bbd0f17b5a5a74615a5e1cc691bc976466fa4ae0f00000000000000000000000000000000064e4d67bd5b83269836e4839c86c8c3c7438b9d29408019bc20e0ab577e857b28ce2f1157941a360a858cb6c30427361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016beff845aa068cdeb86cf8f38e5fced0d127a298bbe5f7e3f9b6d89763b8a3997e9658814be1f34268ec3df2079503e0000000000000000000000000000000017226e07ed8cf7c48de4a121d3026df80b2b19bc71c7685b6baff5e8c038b2c504217a82afdafd043e731793619d72721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108b7915e793c4cea377c215d8f306d8dfdc79689789b22438559b803b7b319cb5d35bc18de9a0be317699808935514a0000000000000000000000000000000004af0cc42a5d9c121597d1ff737571584e3259344cf1fc3826eedf931412e739ddad5f3865a2da102612b6ff2f885a8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099cf3f1cd3043c741ba54219a92deaf40cd262b36736d8919855c625db8d2cd6a8005b5de87d8c9fefbd42776bc26cb000000000000000000000000000000001788c7190b8799d6bcbb720f54228fe997c9454fb9ecad3ecfe05da44900fa03f2ced6cc95e12df575f6db8bdad58a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063d2fb1497d9cf93a46d0eb9c27ba309acc904be26b48eac9a755a2b0ae278a474d6be3e15bf1e71cc1c383682d98b40000000000000000000000000000000014d924ff714d996690fd1ad0b34c893fe204cb4da5ee3d2199a0b9fcecc42c904e405f1f1a3dcf4328457896bae802fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f1dc7f1fae6f070eabe369e02d83b9e0ae934f3789146a587ea789882789b47fdc3121368bf88c0c35ee2d687e6e39000000000000000000000000000000000fba1d253793ec135716ec03288f6487248da2190c4eed2b1cadc2286bef2d695fee0126216e3d9de8195e97ac734d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001977f2088b9f343a163c3ee2d99890dd843459d5977d4b30b3eed034c5565eaf74355eaee08e599bfdea15b22478c7090000000000000000000000000000000008ea11d18299366846a5ff17172336d6ec85a8e442dc932a79530f735bab1a0487c65d924d27b56cf2d92a44c847a9a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000873c5370e5e674b9a01c7987d45fdd4ff6ddb85d68c30c429ff56296acc04706971c23cd03f6b6d7eaf2c8a40f3b5f80000000000000000000000000000000019a307ba13046d385b2b0eb72cb7e7a40e3776a9ad9486e68478cf7747f0b05d92c96d5b8e81751f2a29e5f205565a0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b5dc1decf9c6cde8651d3e8768ee709326759000895328f16e2f5c4134529655f7feedb440ac7c3649bce5c3fd9c8700000000000000000000000000000000074bb82ec97c571ea7e35655825c2c0662eb4b3e0cfec3782759752d0eb1552c9c2419c8a9c7a603be31eee5b6e7adf91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69e8c316370fd788a3178c38ef14539a7309fdf70861c257ab29918c24927efcb071d7b3f05a91631d2b78549a0cfe0000000000000000000000000000000016f752016e2c3c5d41e9b47f842a0db704837e0a70b39641b65656caea64871140c385a3034c021a1d31f329ee9910a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d08f56cf71e6f4f41926276ba1c5e9e88d3f956756e38abc09fcf3313d0737e8d76a2af836b0497dffe4d11b6f183f20000000000000000000000000000000013f6e19c1b00db73c7b4a509b720ebf1686f12b2e27781815af2a5db351a07cf15a310b40896bfb04150960dda46d4031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030eb6627e38171603b17f60fc2402d9a16a0aa9e42cfb642f54fba044f0a60a197ad872172b61bb7bfff11cdf76572a0000000000000000000000000000000011615c1f53b54665c6e45d56bf9440f5f7e57757a6b2bcc2f8d3e564fb6cbad9d04679e574a2f68fe71d94008b0bd83d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e9fb55eefdc4f89c44fb78db33a556d7fb07e378dedb26bce94ffc500de8165f6ff29893e26cebf31630accd6a0bcc0000000000000000000000000000000007a95f4806e9d715509730d2ea65f2bc5bde9bc8f6f43705d8b5a8fcdffdc3b3e5ea367a5c75ff2407561a49f43767581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027e0e801fe05151071075ee24ff3e789201aa357302e701290d0970e96fccaece2377846eae528771464e214e9d8ea60000000000000000000000000000000017e25c94d5129e018db375a018cc67dc774c0fa8b451cecf247d916ff6043609e24561b2b9c1d450b630a11f23f112cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfbbb937297757eae35024a93a0d55121a0dfbedb9658540f70e1a4414dabef4eb56f1c3e02a95d12be59dc65c1be8c0000000000000000000000000000000007a4f900a46ebfd3cd082cea61b605b4cb9f4f4b5a6772e7851c670f724fb2415de49170ad03c34a6a4f2408ef71160c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca7ccc599c082441dfd17c68ecd01813c23955d0f4d506fd1ec76cd490f25c001daba20f1a1cf981a7d28f8fa2728c30000000000000000000000000000000001e23a2a75fa119834f50b00575158c530b630ad94e24ab7626e1c25c9eea6811b72441fbd32cc6b2df5a6450f45768e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000be397b1f6efd8cb4fd72f5b7c6411c6f9c4fe5f0b7bc3e1956e86d2546c19752328300b6b611bad65bf08d498622590000000000000000000000000000000019bc19d9f338e2970fef712536ef52d9296acbe15c8508c8c4a99144ef6f76f5f18d98a22557b7009303daa8c5ffc43a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b7721a500f0a33da809571be189a00b7502d4d871bac803f5728105a3d58b44fbe186de087ee67ee4ff89afedb5dfd000000000000000000000000000000001790b57376e47a707823043a95aa0d3f46ece80490e1e83109cdc0f52357f100d5f5ad523f0d734780c4287133bd96dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60eeb008e009666e344f8c0486d54c2d70a662e4a1b16c577fc961c9624079f2d06a4137b194eb80b81e5c2befaa5d00000000000000000000000000000000177af139e7e5e038e9ddf909bb6511624ca046e2ea39fe37456025b59f661cfe66d9d69eaf067f743088eb8df4833af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053311a219ff26bafade5603edc0fb7de19ffc83f9abeaa542c587c375037e20ec6285d8b0cb55ad724847f02439d5bf00000000000000000000000000000000173afca71f6bab7a9c8fa771d4ecf4104d88fa94e7fc98c54da0ef047dd1d08ebfbbc6001da2c9390789d8fa993e1be11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d185a1e889f6474a15ac74a43a3f01df572ac34b509513d63c3320c4f5aa967e0b57b4a1c21a6e851758594d2844db200000000000000000000000000000000085a01a961a3c7b36ff8cf8d1e4f1d3e8a13b97dbecbe49d13eaea3f7814db6d5689274738920af4b5b53c3cb570122a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689f4617db2629c52427859183264a05d085c60ce7653edf55228a260319a7730a959963780acf0fbffa2bc79aff7de000000000000000000000000000000000480760c6f41808477ffbbcf4088dacd3e4d1ea3433be7489150f51d6e132de6caa0ff9f40169410de1eb9572d8bf52d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000386626ea6f078e55f0d02126bdc9095254ead02254e36fda4dada928010af313d80309b4c7fa277d1fe720c9f29a22b000000000000000000000000000000000f5cc754ce54f0dce68676796236da2b4605014ba5b34589cf03090ccd423a2b5254d43bbea6efe95e427dbd5b2ec7271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0f53a8a3ac24fbe02b36e04da5403aab375ba337071bff97f6fe1b0f213025f5510ca39cea980fb764fcaf174f7d72000000000000000000000000000000001499c498d87de3058c9d469d51ab1454b69d738a6754f8613309b7941b6778829efde33fc1ff2e8dd10cb08248fb7fe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147490164e580a71e22e5d7e4542c9c7e34884bce0d9516df9d4227ae76bbe544f510b2627226c30857b45f7894ec2af000000000000000000000000000000001162c3f1c0a243d46429edd9f8e3151eaa87c21dae7d7b82af24a8ef8ffd94f7f3ab43772efd0c556646a909c1d73ab81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128f1f181a2067577e6f5e3fe29970bb4c51e4c2a78988ab1d43451719359288e56538e198e70bcbd2357ee6938e1e560000000000000000000000000000000012f2cc03e70f101eac90f5b11503f75500242e6460b4821a3f5f2b375bb9d28176d096f378be46e7f45608d84d5d70281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e47074eb7d730850d9eba36f22a2b79019886ffb1af3dbc3766fd34156a248d0269a6e8e01bf3bae25cf7ee7769b780000000000000000000000000000000004506c23963e7a4f043f737a3d2f78bf88d29dff9bbf4663f2090127eacc32e2a849e5e1be2a07e943142660c6fedb801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661bd1bd92afe12190c94b965476111e0db7b3c7f28d8fbbbbbdebf40b878fd3c7591b11cba9a9c5bc983d989712e7d0000000000000000000000000000000000ef7c43a43f6eac3f1facafb73f7abbd57260aa7793f168bb789e136e8e6bea273e238f9c142c08e2e3b377baaa2d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b209646e4b69b1323f4599a1049194d5a607311e639d91c500686e7198e051e5806cbd3be6f9d62b2383682a021b885000000000000000000000000000000000895dfd92fa42deeb99eae815d61b0f9fcc7b97f16702494d0311e95afc58504d5f493b8c64143f2a35d044dd58b9c4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120906549bd4786bbd0f5f9d1c6d993051b7626b2a3d81be62158cc38b8309e3652e806cb12647733e030fadb37dccf300000000000000000000000000000000004a3e963182dc33dff5ca035b9f8fa38fb24b6fa5bbcdcf999189158e8d8ad987b20e0bb2c0cec380b1a2e6b68d21df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007802fbc22f43355d31ad504f1199b9b22f19cf0ab62917c39a8bfa574f497ee4eaf3d6d3e6513eb43b9981fe984512a00000000000000000000000000000000046c4aedeeed3319babd08e47d9b76f0d4d9ea07efccb2ee44cbc0ca037692cd6c87b50e426af123cd4b029a9f7d86911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab39c649a8b969cf8b1845d8c7131db5ddd320ffb20e01673765da7ed6e403bcc8ca92ac267fe41fee5aee33dc1a835000000000000000000000000000000000a942b4522e4f78692d040f945c4c8ee7f8e67cdc9b1f81fe9db3f5b55ae0bf20892b2dad8f74f4aca6b4c05e337f1471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af065e3d5dfb4a922a986bc18967cdbd339f1e58ec93b720d771d627adaa3e84e503be837b15af06e1bce2e1479d2a9000000000000000000000000000000000086d68058a20fe23ee7f67fa6aa5ca4af696ab727185d1f1cb4b4c7ff0bb1e61be65cc45ed58bdbf00f95fc96adc95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142cd027b1c4e870ddac162b6b8170d6a067ba6cafff9fd6d78c5c7f6f576f6201e449d0d0975061afcb44f8580df0570000000000000000000000000000000006817f31a985e1b534d3664602239412d22146a0111467cc8b13fdd3ccfab56e67b01f86dcc1b9097e7d4decd7728e771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001621e788cb0cc44e1b8c2318580a40db301ca29a81705381a11d7f096202562efe26be5c3c71639c648c0c0f5eabdb9b000000000000000000000000000000000a19dac3d16b27ea40a9a397c7331228e9e857290da2359e4a4f2638a2a179c3c672c62b9d96c7f6225a27a7311791521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000699b655918a7d1b2b61775cb3714472b493e7b0cdccd8ad4120ff0a42b7d1253331d98f6ffab67294309675c3b4ada2000000000000000000000000000000001032d11150d629a84aa2877a65aa278066f3c55c7d17126b4c048d4c88a57ba8c00d0d114ce49fe4df64370786ff6d5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944f87251dc8740d49b7ea92a6ea71c1360ce3782f8229130e6926b3a861ee800325d7c50add151947a510497419247000000000000000000000000000000000128e43bcc2327d9fda3eeea7b63e297fd9b35b7d731d66a2c8305a6835dd8f45f665c0ce667440ef1f5f0611989e8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148fad9b69bb0bdddf0047c5877c5af687360b82abb70c7c84411372eb043c7adc2c124f442ad0f2c1d30c6c746b131b0000000000000000000000000000000010249e8401d308ea8bb05dfaf0a32c30a3e1c44285137da5b08c3eca12212bf31c1fac80037c6132584353b2342cafc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a56103d62e728cff75041977cf94712eea192cbb325551c22ef17008d15296a3535b9925c5fb56416176a5cedbd10b00000000000000000000000000000000012a3d765f5338c4b32188cbf24f39ef5e404420deebb5c078427771ea7b06db25e7463a84cd16f37ecd3cc0d975d18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144ec3b136cd25c2199a7a98e78b5a29d2d4ef40893a5ca6c2ae99db7d50c62a98a2688bbd638cf9a1711f25afdb7370000000000000000000000000000000000cdeeeb2f61823a8848c542dae28f0000960ed4628ced4187fcd569795f972c10be1357aee8cdb8038bed8a8234d65781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001515362b4b885dcce8100b2fc5ab85348077db5b83dc181543213849af3609e6d68ec1751876e9f4c4a4939bfbd36100000000000000000000000000000000155a2e7049fbd76f416b03c70adda54e8465f8c49862c39c0c5622ffab8e9fb2fec0885811b8a8e52ec5fc08cec508431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011afc43b67340dd4d08bcd9a32594b380351fa6d2f17569d4552bdc0895b6bcb3bea1ff7be58a7e93ab14c247275315c000000000000000000000000000000000e4033fa2d04230d22c50a42a9aa52877286b553374319329ae30cc1958a51d870ab2613ff43b210bd945fd6a64406651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ff9b229f19f0d535e08316cb24059ab1a424ecb125ce444aba56e5b7fa0af424a07f23cdc1abd10dd0256305f17bab00000000000000000000000000000000034fd1f4f2ae0dc342608fed1a3850d937a37ba9e1cfd3ef5d3283dce933acf5a9413fd5e2522169761c6bdc60a44da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c492a93a588333a6d1ab40c9a11440e2f97fd21b0e497d8cb8f64415f415c2aae4f5c32d766f586d08532ba6fafdbe0000000000000000000000000000000012beb1ef4c4fbea1c5b0410586ba71a3dd8d390693285d8948c9d13b28dfac10516d08844f976142a6046e1f8dfc5cc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125a63edc2b5c383c726849dc734cb0d7961da58377cde3f994727eff1cc506dff698253e6e6171c76d68726ec747cf50000000000000000000000000000000015c6fa071f405cfbc45a69505cd91cc07bfcb748b2874d9ac77dca6a8426dc131c3c09f8c8f86052ad33c6091fd629d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bb437bffc5342926ab62d68805e9dc5099201e874ccd5940cd44f792140c57e92989e660e72648e72c680c78fff83700000000000000000000000000000000176459071bcc5d386607c5187e69360ccf7ca72acfd1614348500172bb27fef781d3b2a1ac2c0974519d13c3ef79d3c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179fb9c2cd3e282bd6464abc39c23e31176952b4a5ae2670f659b1b4967a2aa0f7655cfbfd6391928fc464179725c706000000000000000000000000000000000b11da59cbbe12d61f7df13004cea870bd9a10beebbd40c56ea9f8f045dbfbbb5135d6df5059d96fe45bd5fef07584f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070f3adb21331dba3c26865b57794bee01142255fd2427ebbeb3bfcb355d37cb262ce2eabc1ef14f97f25e11e34603360000000000000000000000000000000007c2c25e6630fa4db72b04848ce5df1da3d28148558f2ed62581a8b348c343c32bf9d429daaef37f34e4e28e7b579f971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cfa6857713747c5673a74f5b414fd98f7091310e31cbb2d1530459ac658c0d673e27299f53debbf41e4dfcce936f26000000000000000000000000000000000394549714bc3d8dd61c1cd1c6b450ccbe10a31c69886c0a767095d92bd847de226b42cc2f40a494e5b26601485686101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131ddd112c353192b8ffbc1578218573316d5eefd0b997af2fefcd5403a6b3d95ac161d4b7ecad142b8ed2113d566f770000000000000000000000000000000013f1d8132fb3fadb5a42f06051f80fa692a3c7f148d88c3d02ed8a92496952df3816c98b96511cddaa890de3b5f0e52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187e272ee6656dbbc960c9ee2ad15416c2c51ab4e17b600b33e36bb0d054e4f231f8068a9c2181a68475da170c1b6159000000000000000000000000000000001693f4ff3b4616277b6abef396c7ed3bc78aa85d4d11d3b3d13b659e36721609fb491a6182fb9dd386631d0900d045431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df3c4a648f06f28655da0e0d71412ff1f786da4ba6415235f227ae1b5c8b329464a5ebebfe8660d11ab06511aad3a2000000000000000000000000000000000f034e2d5180b789cbababfb9d1db3775074b1b4041b714b2b4c7bc55bb34f860bac254b73584004430afd90f38b0f091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ba10bb54c62ccd4d6c40ca83128d0e39f677e542f2fe73d536ac286fd102b5cd66743199ad458697bdea931b0c96e0000000000000000000000000000000014986ee0acc79959311a821c42ed49ba7e3f018688f0505317060deaf6eed68fe86c54fa24faeec2f06a161c740339051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006afa28c5d710eb3e4fd2bddb05ab6c27982898e46cecae0cd4a669aa27f05f0db6ada48b213cf68cda433be631b360000000000000000000000000000000000457a160abffe20be008081f3d71fa56b87caf765ff611f5fbbd83d8bbfce307eaefa29d43f94d557bf2195661bb82fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd31c70b600c66013616a937e2a031e9b99a6968b6ad56314ddc51772042ab978b596cf1a1f4f556124048ab098afcd0000000000000000000000000000000000561ac6a65bd9950c9f75faa6043e280ceff22916356da8d4416d8e5a87742dad1d141d82eb90f2fd8e58ee39d106921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2c02cceae1ed3df350b68e324143fbb9f8ce2fa018960439baf0f243eaa81e04a77655a95da16f880ca86d990f45e70000000000000000000000000000000006478667066a43afdb7fb88a9b64d4d4a389b0120312b9abe2c793a358950fe3dec23c6803d782b335f4a0d82b08cf021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d6d5caa0c8feded6333e4776e5237daa42c181a058d4b8cac1c30bb1284f61bb6e1d40b591ffdb18643b943e67166a000000000000000000000000000000001154b7d57db13d477edfaabcfa406b7fe009e146576561e50c59d1399465a95761eae4675e0f3f196a9da62f1e3769a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005be98e323b44f1553d3ed33b68958e1b51b1425a9f68af603093f705748b6a9d187f9e22837ff49dee37416ab07cf820000000000000000000000000000000009ca6ba84e1f86cf3d50ba3f7ab5abd4b6351ceee1c35847d65655b14fa7789ec7ffc4971bba4973543106ac2218adf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d4ac90a81b45990d87ebb037961f5f2aa11a870b2278dd8debf2604ddd398561903aa38f1d7e959c501da11d9a69ca000000000000000000000000000000000972c143863e33c238f41665281474d92a035b4c5bb23eb74d6814f4bff764871f854b70c277d9246935863eeb8e5d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a7b5b4a6e27560fda7b47b47d70cc7562534b9ad407495863c1b2e7b4d6bc0cc03e90480d31db74c8714ac3a2708a50000000000000000000000000000000008e3a1754d5cfeec4efc222af528a6947c630e540981566237a0622c8deb8b1ea0f663f5b06ae3e70c4fa002ec151bfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167a4191218ab1d97262d1b9eae10c8a789f3a8bbb5058945206255901d31cf0adc8c7d3f62e81c486034533cb2c1822000000000000000000000000000000000567f306d9ab0ac90e2db473afc4471017e0735dcff7a416f10882946b2467810768886cfae2367c312d3dc3373809491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fef9e59d5cdbf7c21e2eab254833433c0dd7bf6f310294be5054aa01b6f96e1c42a844894b484f21df7e682e180389000000000000000000000000000000000e1f5a78e32b3af1ee825c121e9637df84af5973b755ac1aef7c7901afb493154771f6a2fa1ff1fb2dced28752d7f72d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194ddb28b07efa7f5640f8cf62e9646f5acab9b92cb8c7e9f911d1ffc4f66263939d29e58fe0fd817b8a32657c45a41300000000000000000000000000000000197139af4bd080eae31f7f97872a447ae21bd1a5de18db7a4413e216979e67eb95277e1e5f3d2f5befe3bfb914e9231a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001242d476d43c34e0a5eafc1a864f8354c2d44293821bc38ca6801f5f89d5bb7f88c9ce0ac78015bef858600e7a164a71000000000000000000000000000000000537557d4b1287361f263fdb88600bcc223bf763afc56f24a7bd7ff47d25976a4178a5b1d648b41105b4e2653c2334401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed58dae7a96105a03f03acf408da0a43c37e7388d15614fe24e278558f2fa1232f656afd531c6d639dbf200218c7fa50000000000000000000000000000000003a4de29591a8a184e7e47ab6bb1be1c2436c9e1cd80e508066d828a09977fd62d9b173e2510dbd1464b1b056f0a80791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000398bae306aa14d3ada53f8e944ba25926a9b57fef711adf39221910326ddc64ed10dcbc0ca09bd2c63e8112494a4eb30000000000000000000000000000000004e2c0c99475b69de34ffd0cf157b2583bc8a41cfadc3c2f665b2590702eb225e2464a1e585331892d831e51a89aaa2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1094d50494a2fc829b20aff39bf7a663d42d63c4d7f1ca6a9d6070ca401b05283c469f256db88b76e044ee6fa6c9d00000000000000000000000000000000100c547eebf2071ea67a14405e2101add7ac9eb4f8f923f21adc0c503e3b539c09ac60f6bcd2a6c577fd138c406d8e221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e05393130d6315ae832371622a68dc08ead0a8fd5e748b114f682bb860a9a9870c1c03f699b4123f0eba5cd978dc7df000000000000000000000000000000000ac00f4fd02d97d61d7b877c79d89a9f133fd6dcb98d735578b9f9f6585b263b34d3764eece1c22fc809e8187695aacc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000082a5f6192516331d9e8b1833ec327b144a5a020d1ed0b0bb4f79831cec38cc6d223def3a17eb455b14abe48c2c39c270000000000000000000000000000000014046e573933bd62848f1accbd30994e87fd8e489084a4e22d0feb4a3d58252315f44e51568a4302ff7d1af0efdd89ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000527e8bd1cae5835c17796536b5cbddc14cd11788895261dd3c46408ea35d4ea397fa962aaf570b865b088ae6a448b950000000000000000000000000000000019439716e490690a1015cadba1eae76f523bdcb01b1b18ee1f241d44818cb4fd0563920179b354ca0d34343ec8a4d6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038344bdb314e9de4800ee3b8a70a2474b531b89b80a5219902894fb74ad4936e00023792f11c43f8fb9a73fec881e000000000000000000000000000000000008b36196a86801d0aa423ddfaf0646c1e05615b5af44e70e89f1345e4f629a1b09cdf87a287437ad78ad10a17fc70a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8f6deef7eaca9ded38de029b72ff2d5fcc65d3dda922a4d5235d77131b5b45a3affdffaf26fb7da772bf26bfd587870000000000000000000000000000000002411f238bcba73197c1282723463b2c50898eb546076011b24ff24b5b82b2ff74f097a8f617e7e44b666d67cec3f3b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008593b39dc5c4e81b9e1a376e39baf84992960db0d9c13a8db32da7ee31bebbe20b17403135ed6eb28420576d7467b78000000000000000000000000000000000b6bb04b5b53a0db1ddaf2911f6052ac7774e067d23388d1ffdaf69cde7ed5873cabcbb50ff4a91c16a39095c1a2f2021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fbef8516765ce9c9347e0d0b28946582fb75bb574f227eb5fac99ab8f8c03b7352ceb55bfc1e30e53ef8de37b9e36b0000000000000000000000000000000000c4e127992f0c2bdddb9288d216ff3d448082e97b19f11fafd93657907073e81d5169ba880ce6abdbc0dcb885cc01581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000148d4df38533516e588f813df1ee0693669c3ba8fddf50002efbe82ecfb651e907e3e72aa737a3ecf4c9ed896d067cb00000000000000000000000000000000122b93d1f34a58aeb960b77bf49576cd2d5bf371500baebb35c64ee4465856d6ac5a764739409ae2b1610dc70b70506b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000802f3cc53b9e19b7c86b67a0f26bf2edf26c9ff3ef03d89f66beadc7ce75879b73613883cee675613e78adac552222500000000000000000000000000000000136de5ba963ead16fe78dc68b326f95496bdd5744086a972a0564cc33094f7976f548a2abb84a6ef24865036f6c26ab31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000882ac25a031e8a8ee41008737a52b7f7bb5084cbaa44c2e8897feef93459ada9ef475f62bbb850c45c00164d6c9b61b0000000000000000000000000000000008d41661a294b291300279a823dc0bda32b7f11beac75d623ccbfe822a071c85b6c7ebb4e6fd4e4884df609665fcc01c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f320d2220190dd2a58fd0a15f3e06c1bd97430c8f61cb5cd7cf5762d3aa8795631710bd73107fc7386474a70a659ef1000000000000000000000000000000000c199b95188d59e362658562d085bce0498557a1613fb554f75116d61f87a4d2079e58da150ea28b8fd4a6e72760f64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c60fc15d0b801e129ce0f54e8bab46ee82796872e4b01f145d1227e69ed5398801b0a88962cd00df88cddb1f9768b000000000000000000000000000000000e2b8d5609be81bb3d1c7f8daf702d76463a3e6599a0721a3a2cc5ff3b6d3387743ac9e611ab5a629d0b59f7fe1cf9e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069c23677d7aeeb0a8e548a00f3006a40b493f0aebf20099dad8db312564816544a8db8f5bb10e1f0c57dc8ac63a6df60000000000000000000000000000000017223bf5c9324b990188f8c28604cd6feaa8886b2c6058d594c21b87c95383e01b962d04a288ed50ea13a2cb2ca8f0dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185e3a3a52709fa0dbd9780ea13dbe8ff0dbd94e514bfd9bb8d0784be0444ba84a987063f959a8830787560d6d6a95da000000000000000000000000000000000a0776471c48ad7ea6ec8f26e51f04ecb09a993ecaceb517e9dae29dd36713f12b7a38a0535d7242f698fd9a93e285e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff39fa938872b525f07b0e56f820a2c4b2dbc98b75c4c2635c053c624352577e7c6ba4a66af0d5e94d1058f5e67209200000000000000000000000000000000036a99847003812d138cc7f568cc481731ffa4b07ca87b0a63c65d8a4620b6f4585f615f5079053346eb90047e53d9461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007cf827a9e1f834143d334add1be4d168cb42eb7b99b13cbdcaf6f461fefc54f110199e8f909da8d0df4f4674bf0bcd00000000000000000000000000000000011526caeea64195a89f36aa1500816a0d0037b233dbf6a836827c84234607ab83e356f3257703f2fba96d07ae815b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000979e0dca31ac72cdac9f21ef1d7982592a7aad51b55c006451e6da545197ff937add4f1fc0eec8a5004b8d6751d3f490000000000000000000000000000000011c4056be6ef0fb8d538e0bb1c9b3eff46d3bd75914634e5b2735e564b091c81c434e05c340837194fa5fe9cbb83948b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125e963b23e57c013df669158a2a27e028e4f791d030bf3edbf7f8eb40c30162a076472a5dedf82286546d9b6303f28f00000000000000000000000000000000114ccd83c76bfec63a1117739a648af091ef65437b6a987c008d89459f05647640219172ea1c5c3a780ea380b54188e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f22d12eaa8d8d9f0f534faabead875d7e57ddbd8880310efd23fefd881d5000ae716f52b57603cd3ba9a0d97910c45800000000000000000000000000000000015c86c379239e916f726455d25ab619077326adf6a6a7d1bb2cc6df27ea48a12809c03ba188842a9f91bafd9accf0ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145e1fccab0effa89cd913499c1b4bf8492460452a9ab15688400228fc76e67a830e6a39e79656f4a1661a5721d61b7d000000000000000000000000000000000bceaf5a5fd9753b0aa412c2808300151309bafc5170a83a67ec91e65b50818e15736b3861fd78798adabb5665183a9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004330e60bfb618262a5d302556a584513f213f898050b5812f783828944fee41dc4b14d1f0428d3f7e67edcc995fd6fc00000000000000000000000000000000046519ca05da7bbb3777c216eb1038e87237aef7c3e3915c127b5797ef5110fd60f4761e70ccd276666d8d7cb52690e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bfc88cc3e717aa3a4cd66977eb4aa8bb2a052eae85c46e9d975ac61ee2f587734ae7760b94caf3136910011d49b462000000000000000000000000000000000e076798011510e334449fe6a33f74ce500deb47815ee4617ea4f4a576a707b5b1d434c6b48955d36a7d7aba3a9cdecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008aef76a49b0eadb4b598028fc69120f855613d65f814afb6ab7f3458417b3f11a34861599d93baeaec1454b5a9ea3ce00000000000000000000000000000000127c732ee9c36db7c719581fe4586117f65de00a373a6fdfcf510a81e60288bebbeb21e077c1901ef11b8a7c0b61310a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f748fda777487583cf1ceb2bf42324ca0b91e371fcf6d80638d764e41ffd5398c5c7bb76aa44d0c6c90bd13ab8b580000000000000000000000000000000000b1eae70910241324931926d8981afe6f9ddc92ddbba1d51f838f5f858322a5d93fa9092a098c9f0dd29ff45d95ebf041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f9f7492e85537876b735ac518a95a382b60ab7998a152fc1922723c4288b99c3b227101246a2341ee5160c879ad9b90000000000000000000000000000000000045a7be00785ce04a5cf56a7c6d0b835dc9a005b826df57ea2ec2f6be7b2834db5b35865612805ffa74108c4e567de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000601000b7f064daa2a1f3fca93843e55d4a5453322c0405e6e2cb9860ed659d706f3006e72ea6be8e389d8df8f1fb42b0000000000000000000000000000000003ddba5602f396f868bb1fa8092d79f7dc8e0a59e0505666c99de910cce43ef49a9e53fbedbf61958b41a858db248f7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047a63a750348eae4ba673e5ff353b20719cf6bdbc68c94fb5fe054fbe9b407d28f4a7c46bcb5ca616cf8c80825c49a90000000000000000000000000000000014763ed0e33d8979ae27a947b3eae170d583ecaa864f0ef44f13f4b28d1b7724917656a291e00b2b1fbd80e741e940131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587125684dcdb7994ae52b7580e94ca9149de7e06dc5107fd179eac5cf85274adb116d06c3d1b1e75efeb4c5eb937300000000000000000000000000000000006c7bc6b09f86a31fd2b69e9551a0458565f4bff88c775d8397831cbeec7f1de91ae8508f4ea75501fe072560fa8f33b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d70ba3f25d50f06ed351c55e396458e337337bbf923df7d5337464b2bc4d3e18c1daa81ba5197233f677933842801b000000000000000000000000000000001141ba7adf3445b4de07a0df3b545589dde0e41a28c9c7a193334251ab717a502f714e2cd46c4ff1c32da4560207bfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027f2bf1e4789a88bad0558800caa3574cc84a49d86ed1b40afd724d3506fa6d3cad309cae5d2b08ec4b14accec3395900000000000000000000000000000000109299c3506e096a803c2699c00e8639c1fc1504f2cd70561cd518ec858359ccce2fd06559160956e39120561c74c2c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fe6b3d259bf8d8c2b1ba7e2d74da566661cc7478c06513f7c64298293b23579553ee6a6c603840715f5baa40628c7d00000000000000000000000000000000153bf7c7fe9c9c902d2f7307609a7b5c78563040607cb3967aeb6af52eeede9cf4be28d809c10bc03479440e14153f621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001345a0bbce7902d149c9501063d524881722d0a760075c5912b5dbc6ea18f8fbfebdb9017e1002c3a7575330edaef66c000000000000000000000000000000000b6346691f4c480528f74c8a8eeb88cb578f47e122d1377b1c26e11210cda11765f3c2a018314aca9da2d39397b33f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ffabc584cf5734d315e8439e0d8839df833a654a47853a3f9580c03974e3a70d38a7a1f743c5782eba5450f7fccb46000000000000000000000000000000000dce15bd969daf9cb9477635743d10491fd96b3c21856136c66c047aca99f4212c2ee32cebdae113595a77432eb63ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164087770883dda13545a308bf4b7b68c6caf81be4a2d030c249a5b837997bc0954475d73baf2ae603400f38c0e9ec51000000000000000000000000000000000ff741f945145f099d758a2997cad7a99db8774587b03856189188f9f96afc06e1a181ace17cf8f960b72d9853464de31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd135b1f2b49d8555ac9aa9aa493d6d8d60738484ba90613bb15b328b93b08614fd05d96fd732b27e29ed576f297d2d000000000000000000000000000000000e03b517539d29a3ae9b552c129f7c611ec708b0f232db3f774a6e853936dcc09ace5d6728e175b9d20d9ce606f9e99e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a4b4a5ac8650067642d162cb52e63faec401607225b5f05335670ab59bc8c815915dc79b8e066c48f38f0e81634a52000000000000000000000000000000001702e03ba3bdf9971a9105a9112d802b955390cf5f57bd69624874a37c27ca507aab8a9fd6727a7227b3f545e0b90d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0ffab560d11eeb7038ecef42c043c6cdae32941bb329a6fdb9217f6445e431e63794ed8d9aa50f0d4cc1df2ed6123000000000000000000000000000000000379d9041c41d7443b1360c3620457ebe3186f9a1eb5cc7d7f26f8ff41fbd6b79f43987912d33a5bbecfa1c80ed9bcb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afbce8d724d371187fa42e392c1679b3848f85a24018435cf89e73b70ea4a281667ff843fff2979ffc2d0ef9aec97ee000000000000000000000000000000000c367f9c6a31e1bf90a31dcd95f9e22b995a664553a444787b0cda7c91b69110b0b2e1ae105ad13c7ace88f8ef8125eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8d0b306121ec305085c003aaf44cf1e62a9b12f4c3e65975d689d925d9ca9bdca04e0a5fab9e2d6e3217387a3b1a7000000000000000000000000000000000f59deb0ee31e2ab1e7e5c6884a9038fc1e78b735d2e7f5c165845c4625b1926fd3550adc2e0363bbfd61084d6c937a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3c46ac25f4442812bc443b4a064130730d1fa5269d23546e6d5d520a8a61e0d90025f135553e493d9eba9a5fb03944000000000000000000000000000000000a5f49f58d74de2cdb85c481eb244945d60c3f4465017aec127a0db0b4d0b123a6110b900238f3767a4c1c8019e6c7371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ce8c0ace3044c129b869013dc777bb09072820bc3a1c8c3a99b0a555f111146d6c95b21d7753a7857189f0ba0f383e00000000000000000000000000000000059275493bdc96b52a4fb0c1629af169ff790ffe40bacbe7aa6955ea2ddcd5b2d6a044f284928b593b8aacdfe3f1b31a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b2467f3f48fc7134251cf907b5e7a57b609056cb19978c0604c8486d0438d8e168b9ff19362e38a3b68310f539ab500000000000000000000000000000000014416c058869f2d4a5442cd8685f19f13633c49aef172323298ad38d76cf09eededa763c36788080820f7442a15413f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e55bb920ca483fd5c5f711b474e556a775418bc831fdb3e943bcb4b76c8b3f42027694ce9b1c0ee238f916c9737e00000000000000000000000000000000001318ca785512c43d3784a022fca4b7099f7b8299bae58853614e33a12d999c05b33455236b43a6224005b3c1e5d348971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009790cb28041cabe0be0701727c26794e734278f55a1ed2ea3ba7c307fac67e8dbf3b8a2d809a779a4d46275cf8258650000000000000000000000000000000018056cbe6a8d9e3d9d04c9cf36d06a742c1e7d562562f4388bdf526f82728d18e7f660a3cd80589d456acc3e5cbca78d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001aea7b7b25605401b97be443fefd83b301a9e4be23619f6c605ef5732c203f5d148d15a6363592d867af51e80be179900000000000000000000000000000000030a1d6ca1591722ed1219c91a9aee13c65fd4560a309ed7402ea5bbed3608b34d6d09633b574c67aa7fee726cc2807e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c69e722338339dc3b0258a2cf2bce14157a797eb87b7a530db7b45b6a3685e7cc0248f5bc01831fb9b13d83253d2bbf0000000000000000000000000000000017433952a0f68767bc166232b2a87a17c36746f887c3b48f1b23309d74d9022329541fe95a3928df87786be45c29797f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cb2542b6544b75382e3c90be2f2431b54bde8a0aa795a778676290d9da6fd7482be1653a6f950a757be495fe9293b20000000000000000000000000000000019e13d09cc61578590f69d8d07906433d8abe3ba2b7e2d8751c9e4772f07835909b37ec599062cedb2ce0e5a5d5b72ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004511d6d12957eeefb2b5fe5846942961d7594c9817eacd126cd38ea6f156139e89b776fbeeda43358b6208e868f2c54000000000000000000000000000000000897fac3f14e30056bdfd8c55bb33a828cca3a2829e1081d149aa070c5dc660242dcc8f6e2986040fff0a8cfb9d9af2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001820425766eb7299084718610003e004db530f0622ba87fa7c99134193f796d4908c47ee67802ee55f5d019f11f3d5b6000000000000000000000000000000000a5fb62dbb1e1a76ae29c52a31cecb238ce198da83c8a25baff5ed989fc015d7f60b4aafc46b417a08778a5e9626b06c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e2aa894c251b01f271051976c9b1add7d0852c1932f3e1004563a5f93c731bf2af74639926d9fb58351e6ec4b4a15000000000000000000000000000000000077a5ba7f61e50aed4b2350e598fdbc3be601d783d70bc5473f6f22610c76d48039ba03a03d1815a5e2c590645198941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3c241df6f8f7e09352ae002a36abdb9e870fc5b9e267dbd153bee62cb14c68cc68d78c64fe4b50e501aa8a096471b80000000000000000000000000000000002f92e1cce872bccd2374c4aa65a2d89cd9d695ee23a67951d3267aacfaf7920ed6eae1a4b4a6bcd2f28993491cf9ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f71d6ce835ce03d37853b83b14f5281c9766e2ca3b5eac565280fbd7e70ed1b12e290111fcd1e022c42427b58c75af00000000000000000000000000000000158e6aae0d7c22d2e052645361f19a60dfccd1434b1c5b40d7e56f7b17af05bafcd7909e11800c0c52813933a837b3d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce5573df58e74e4a84389d51a4e237af66ac7881f552a1a8a2338e3655f3adcba0be5e62158d8d6bb94d60d3a28a0d3000000000000000000000000000000000d4f196ecf6de0943b19551ad6c6dd4c9f34708b32cc2a85fc976b92cbc77fb306d0326241b57993869cb3c1b0efc3641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c41fb0b59196ff64eb4ee8a0234c41b4ac5b8930a9bb3a592cdc90726ed53eca6323d1411489bf8a1cf4cfa4f5bdcc00000000000000000000000000000000074f90a824480e2eeaa12e5166f2b78e5d21af3582fa002735fcd2c8279902a2aa94f288c91e614ed48148d66eafdbfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bf2d9fc2e1d3de9e445e15e1711f20f8b018b69aa2a403a6aacbc8c4a602d61630c7bbdb9eed38d01080282804d4d6000000000000000000000000000000000922730482a894099e6af64d6c80f0a2ca3de8737aa263a827339b1332ebacac919eeb532e774b41db20503a47cfaaf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052bc9763bb2ea95aed30ed23a83f4720a0b63589221eada77ec42e12081506a545e6b79838320816a98a6cb08ffb6de0000000000000000000000000000000012d71b3409768e8e49ade25b3d1345404e856bce789c53e908bd2b7b55e5ce4983a3f5745ab4f3eef8072d4ad17565cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001732efc20f2b3db60f1a5253bfd181b1bc266e028fddf8665c1edad8282f16f9d7e0491e58c4e9cbb9e6c09c1b11246800000000000000000000000000000000005e4e5c614a7b042e023419646b42b6f04796e886b4f06750c968ab05304835c8fe6dcd1a0046acc80b1c7c645007b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ac487643a5da96b8607ff1575d92915b7e858a5b8fef6421c7bcbbc38515e22aa997524b9d2e180c61c2b4decf836700000000000000000000000000000000155149cc3e5446bc94be31b9c244f43eb21bb47d241f9c7985a2817c232577c89405f941ab48bea49d5538cde6c18a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006744c53a65ed278e0d4ca62f51c669cfb4dfbdd8c9d3638c5117507e29c0b86e25c0fa34465dabf88fae9be8233f3d000000000000000000000000000000000889bfb4c1b7711169f48f13363b56c7c05d59833426c55a4b113eed935c24d09cf36c422aafc74aec0e42ce424f85551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ad5ffe584e1b6c80c7b2831af2010632326c01c8a3fe557d811d62ec8e60e8bb3c0a3987318203fb04b875af191690000000000000000000000000000000007c597142950f74993a7d6c98cfca3eaebd114809e4147793a411512a2baad1467bc6a9cc243d14f0b24835f310e08f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dba08466e1fa7044051b39ab27fb8b539715e3b0f6b358ed56ecbbb37bb53868c5ece6955c54cb843919ec21ff85d79000000000000000000000000000000000c334083404bd54fc3f279f8459da64a0e48b9ff07f0e2d17500062be83e93bdba295994a14fd474808de382b7ed49081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190eb09f200ccd147325a99a21aa51f09c15009b77284e801a77cc9611b4cc5940ec02d4268a00335c83a42cea21bfab00000000000000000000000000000000095c541544bfe68220b7b90165e5aa37d4793d3f9f641294228e8d5f1538e00fa10b455d70dfc344178b2392fb29b6e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000039dcfdd7a79b079364d47f2e010619983a1ecb3e9d6a043639a9b6b4aebcd1a086fa1869cda235c1474b407664af1a000000000000000000000000000000001015ca6303a8c3d6b057a170c1b4705ad2847959d5e9116ac3f67869dbd3eb7218b8fa483d3ab8296cd3ac10377333701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000508e67598c62dc72a4b0d14c2535286921a68021612cef91479b5f75b83612703e48d7c6aeb02575c3a06f179d771930000000000000000000000000000000016b354b9b6fbb5ab0d7939656303d374723d38afd571e82515f9d90e56d98fa13bb1b43eab48b4b9cdb6423f6c2af7331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a9455de4c4992cdbd93a7f83c065780f74432f6895c115a56eb0fb7641e7030284b1272da5ceea76b1b431d735572d00000000000000000000000000000000167112f9989876e7e330d787567fc60166bcf07f7dc61b766faa77e482e30d77dfad55464471ed8066876ff6096196a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148d72c843c0020a3d133a2cabd72cb0c5cff034932771a1f6670ef899aee71082bf936d1a096b1aa6f2bae13fd8ddcd0000000000000000000000000000000014b6bad54788ac7266223c2b9ac937206893583773fef15ec577a7d7bafed2602517e28f022ab9f1c2db43a3f51d073a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a50fe66ecf34da20fe032554072aef37baa39fa2f520015d5fbe7143bd763b424fa3fe922e5550f089430f74037774d000000000000000000000000000000001555aac1245461e814141b40c557f534d2de501ee4f06d400963316b19861736ee13b5363ade5fdf27e6bafb579e370c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c7b095d3a1e6b3fea0d860562163a7ae6391d2cf521a63c348f8287867b199d4126ab6f4dbb91cc2764ee97faa8365000000000000000000000000000000001397ebf9215bbcfd0e9ca49524c2df3fa89c3e946d506466ab2f8431ec4811ca1b518b78ae863f4b8667e8497a6a78591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066724daf7ef48974888c75ac6019116d1b812e70e77d3417a51c3d9eb24ac7a49c91cfb965c4338acad5653854babc10000000000000000000000000000000009fbb2ed47f57764dff9ce82fa5293ee1801eb342989d90a9a83914ccbe93428935a99c8458f1ff11d04bfc46875e2271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084473855aefd9b7cb72da9f07c0f4bc3188fb5b40fa3abf9f634933671fed7177f534e695d2b401a3bcb7023cf99652000000000000000000000000000000001155dbcd3a00368094ad6b1bc5ea0647584de379696c951344b7bd217e526c650fc3be6e91a4056fb6cad0937d45ea9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009732c3cc883c6b3dfa8b1508ac4b84e9dc8c3c43bb553df50bbc41eee68a5ddc7139d67c732e5f15c860cf351965984000000000000000000000000000000001586488d5d64aa01c2ab118ff2c67879f0cec5375795bb4d2761f1985c041cf5b8a8563a6e84e80d2145feb26e91e26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167d96e204acaaf22c3100d2f50fcbe513194494b05bf277e3664f27a21aa3e70b4bc0c33c84ae6b213feb9d16794128000000000000000000000000000000000dff734764ec3982682d93a30c85bcff701b11babb2c9d9c7b714a4fba143809afe9b8cd6f2df4931979c6cde932d7b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f14d43fc67e0dca75b6f006bbf771ad42cd2968f2954755cba4e5809e82c3a6d1ff4fc416275805e93ea279287a0b800000000000000000000000000000000183a66df5d298123037f364466f0bb7bdec5507a9156925fd5f0f9b0e2040963af6daab3099b8c424a9f3466e336f3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001621fd0e3600b2ab7824f4654c61a520cbe6a434df8c83f7e9f6537e1d7933d4de3ca943135ef96186bf4e2e720291000000000000000000000000000000000004299081fb08e700c8c268b6f0ab53268672612607847cb63129331cd9b43034dfd7e2f61ca80a200688e222b1774c721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c3a902cee2d059f0bfbd7c7d02d1cc58b2f08abf7436b1e26f369b3961d1889abee6f7415b52c9f892a95a317003500000000000000000000000000000000000496d5de982c7e0bea906268cc06092f950581f279737e8525d9addde0dc4cbb877e84dd632309a79893b9038a28b571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000640aa86a5b5d9a7cf5ed4ff40b31e051166b6a90483aab0f70ef51ff0e4dfdf7263e2c504677fb267535b15d095061700000000000000000000000000000000151404159be04aca0dfc823c4d241bb3563f63c949f19f89a24ee0d2d7927006ea68a05faafb32fe575d6ed3790212501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bca8cce3d7a8d2c3f7083910f81573b9fbb3327d953da3acb22c5ae06064d1824d5b23086116ef2767d32e391802ad00000000000000000000000000000000090a9220cbcc223a009ffefdc0a98598ce8afc6767e2a9a676e5ade17fb80128999f027adadd4aa158cff0a4b7e6a23e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bec82d9e44d54e252466ea0d8c15b535d5585d9cf820dff34df8fc76d347d70c0b908abdc9b2a22ced8c27277b5285e000000000000000000000000000000001287cdb054ad242d37a6377563ca31adad01512cd6d77f3776a07f2461ad6592f65285642c631f2050d0ddf8205c7bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012908d6b002971dfe3786868971471376dbdd906acd70f8f8c180da843db18af1f44aa29725c38b9e473f1f8e4efe5ef0000000000000000000000000000000003196c4d418bfe27b313899bdb2a2223f78b30d29b4eb280d64c8783cd7092ace845538e2431d0016805d04c0dcc77ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155209159a323faa6a0069dd056dd592ee0f78db4cca0f4b8732808f783956ab58b6816c8b6a2132ff67263501cedc56000000000000000000000000000000000f730e8099ed98e33815ef71333eb19b0bc636e8c094c12e2cdc8371b9856658bee4e33b0994396ca620e86e725e190e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012883f777d8939f935950a3ae398776df7980738a2989ad5640b68ead4261b5897a4c8bafcc1433cac34852e1a2cad7700000000000000000000000000000000001602fdfceb8d8ed6ca0407cb0f3704a82fbf40be03cc94a7a1edc501beea9a55e4ac2559af7a8a53bfcdad27e308cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b1db50e936cb7c58958f0d03887498d7b22d8859b9c124af2099fdbe532a1bc9f2e0ae15b1c818245827db92b89b180000000000000000000000000000000002c4fe8f2e4b61982dcbf9947256b60cf70263b1dd9c938fa05d8b8c008514f1a9d25ec81cfb1e789abeb361e18aab7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029812bd255aa73c4bc0a42569fcc1ef020863c5fd759712b6b511b18af77a1654ea726892e8acfe31ac9ab1e3a29780000000000000000000000000000000000b9d893e3d0419df8de432f78ff85d312d5c57a0ac4202d21befc45e04697d5bd0e3fa392c20d0916625708f70e7971c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c1bc99d288a7e3412eb70044304281e4753bbd2027be6e7f940a18ef6d71498a4ab7e071ddbc29a7c970369ab27af3000000000000000000000000000000000e11eca8070accd00eb0b304feb0e468d9027da20309f816ead0aac8180f53cda69fa87d9d86f6196b00514e721d437d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074495b3df8ad3b9063264bdf7752ae685cec7ee44943a14bab214da89bb98d1ad436144a38fbfbbec43cfa51439299d000000000000000000000000000000000533228056ade0424e4c291515fedd17f209f15df17dc29e312a6cfcfdc16d0f53efc91c17c01b8d8acc0d87ad020a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8fee45d7312a66824ac2c6e2861860edbe7bb6be46c4934274c2eb87ccf579badbd1adbf3f45832983f91618fadfb8000000000000000000000000000000000e12e5a68ff42f08b467aca7c46b09b5e851fc2a2f6550fcdf556e0d960624f3e6f47735d364462845fef0ffda620f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000379647160c7c4216b165551212eb8485687617af4769bc45151e1debe1651c05919d3b187fc5bac6eafe31b94475bc400000000000000000000000000000000082f0bfa32423848436deff7aa74d8ff936d26519769292a952d5e174e0774f873db2bf14ebdf1669c2363ba2ae12b7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b33320ca860c9c944d41530063132500ffa31d7a034e51d492445293315516e3e1fdcfe85590c347c71a74d6d205e61000000000000000000000000000000000e623b19e08a1c1ec1307d6599c964dd38d844e89f0931e8600fcfc5a2d25ea2edf88b9699214f527d15ab39c5b0ecc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dde052dcb1a0b8f385964c0c0686a8dd0a449b2ebc8ccb838008bc6a3e900c21dcc8af7009ff75028e461c06be4e760000000000000000000000000000000004d5a2d7866d81faf9070ed1430fce11447aba3ad12a5c6ee55a7959a324e1a173dff25c6408c758b9e6f9cf3cd1c22e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001482eaebf0c2906ed95f3ebd738e3013b3db0e5dc886a86ee720f17fb134d436ffd9cd92e39704d8f5bfb71e5f658162000000000000000000000000000000000666ec20a6ea1039ced4d5cc226ccca0b60df10c4b1c01ca641fb3d88e4a23554e4fb4a5ee0b74e97fdacc812f1dd2f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f52bca441c27802ab3b32cf68be9aade0011ec89a60d486d90c8bfb73e59d632a83cd93fe20ebaa2ab6a42d4359c90400000000000000000000000000000000016f96f62ceac74b2e3c8f3e274cdd57a5ead5bdf3915dd4f9e09e3518d14e4c14f227c1d1fdccf43916e03d207930a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ee3e0b56bc6f872c624d01bc4ed0fc28a2be32bfe7b2c9ac604805371df72eab49601cd5c6475063e177e9a4a92f6a0000000000000000000000000000000005ffa850d0b6baa605ca6579f2f9acc6134fab0bfa34f0f89d8ebef5287b505e298f139f06789fde5ec6b0837fb138491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7828faac68084ef41e989b968f235f2b5555ac2cf92758afecf2ae0c74fd546c5eddce5f0f4cd0c3daf700ac1b25f00000000000000000000000000000000056bf8aa92d99ec5bda529e018d860b64efef75516a48bd19e911934f2db96f4106b57e7296b37c05ab84ce418ef6af71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007784d7e0aff950dace1712233d6510b4dc434cc1ecda1084a2083048bc2b391fc13353ec4c7f0e8c4c286966704eb6b0000000000000000000000000000000007e1c59969cce5fd3bd8a63877c5b099b046a9e775171687d93947242c5850f4be964242f4f9ea5c155e7ddffcd134651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffec8532175ee307f53b12051ba4c2afb18a79b37237e64b46692a9fcf69565254389f3bff9cb278b51feaa7062a85400000000000000000000000000000000130b15555bbbe751af34c7d9e330c9fb226b6b8b68072e097cb973ed5c2b25b129eedcdb4950e8382dde4b54eb550e841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ab9008e4824899281e6846c523853c023a5c9b51d68b6a0a55a63d368fcbbaea9a35068d3315670770135bf5a372f000000000000000000000000000000000d2881943108c81a20491164340b74c6ffd01e49451671d48d7b16f465af83658c203ed1f05d9d0271fc4a831b0ec2b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a808e62c6c7deb6442b8663e52019d468a7979458dc433b88e9d5d0c50668a9fc6c212c70606202a2e46d9ca763ff4000000000000000000000000000000000c711d9a3f57df0a7966153b5fbfa6b3c1d58cb6d7e21337af41c3ca8b6612fc312b632f5f46c1254dc450d524d0c1cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000138ad3ebe1812c46acf97e12977d95bea6e6cd44b0b839c3d2a194b0d2bc0270abc1155f34b3dd9567ea493c8205fe5000000000000000000000000000000000ecc2dea430e6cb904e65a96d0ad5630a6bbf95d017c7c8ae2ff16d23501a6e9a7aece5191f6b20cd33276b481cb542a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181c4dedbc3766b06f7a6d555d86eea8864c4ad3c69317f719796b7b82ed806824633d42a1685249b8ecbd200b3b75fb000000000000000000000000000000000eeb784a270e7e827bb482f71fc641c00ea14bf7c3e8605222dc76911ebf6d6f4bf123cf89e6bdea2b268b159843c6e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd2cfe21201c40463e9805a1dab64f052faddff1014b10ab63946474ab98441cbb9398e1937583247d3415582e8d97b000000000000000000000000000000001378d334d571ce0eec0174b44e919e3a996cb706933c7314099b37b4375f22e03816ed8ca113e443d1fd969ee113015e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d760e4686f4b190a56cac0458c8f91a7ec74645a3d39f241c830a7842cfa5a3709cec89720f4fb50ac11fb810d0776000000000000000000000000000000000f80a3645bd1fa58a2965e5eab2cebe441c4305fc9b220cc10015d10bf3373ffc880cfefa374847fce253ff85fecfd0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d27c90c6a2dd4314e7587bf2d5181a6aa3025899d2fb32b1d5a34ab9faf9cdd632801db12a3ef1c4beb685a2ac81ad00000000000000000000000000000000028efb802c771144dab499069d221183d2404406956192ef160fc910df531f48c12c55535110efa5c3790e9aa92a0b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce248aa7c959bb492c36fd8c4cbfbdc8cdde00aa92d5f5db4e83a7436c9180940c5ed5ad52adb098976a8aaa667d2130000000000000000000000000000000010ca59e855f27bfbdd0fbb79deaa388fc8a9f01dd23908c6178b6144d3ea3903af220c2d84418f544964105ee29ca4d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a36758e69c8dedee5f2e79d42ba974c471421b7680d7595d9c8d13be9560a90075a40b766a76b745020bff8677b71cd00000000000000000000000000000000008193a2b48ad95b4b90943feb9f964a31a1273c5779d645d057376127c17d00bc446683e4f6ece9ea94ee6990d84a441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a772bcbf2b2177aa472b6ac24680c6dc02a91a19ece19d44c4786cc823977747714be750c813672cab3ecf9f2ab995a0000000000000000000000000000000016355213a3a0b2f42f423e2df016fdb8f7944f3ff86113388f304003cad28a5a4f3b5898f0d9c1786c09fbd0deeffd731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9b098a732f22c01f3ce078b5343e3768b99c82be3824c71d45ecaeac03ee01c0228312e34de13b81b942e60d78bdc9000000000000000000000000000000000867b037fabf1a97b7470781a56c6f4a9650bca3fb8588553f11ed5aeeed240bfcc5088588f5aa255389ff8fdacc83111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3bc7614c67b2211b6b016156e9093d88c7141fd8837d42972d6db2fdd6257c8f9511e8b03960b514909607a3a40f10000000000000000000000000000000003e40d7311d9bfcef8fa02fd53758a25119d782ae4168603e852c8f65f12150269a54b925971dac84bb9ce626d090aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000165b971dfc4053ae2a36920313ef41a96ddc16ff57882666b1e6d26962f100fb46e540ebc6b9bb62da981c790bd76c70000000000000000000000000000000003ee86e515a8d8369ab529c8fe48c4ae97132a7db12710fc0e64a10991eb9f25b82b51173784f74c0b4f4b3b9d0cbfa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e8e3f7d640a83910617b77ac7ceff3c7e71aa23d4bc4e8c71a3a46a4be08011bf3aa60188de4fdea03e6166a3015e30000000000000000000000000000000005763820a6d80fca5a91f8d41a71d4ba9dc6d46320c81a30203a485f084f11387b7d0fc6d0614b5123f28188cff12b061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097529cca8428b4027146f8df3a24c6f34b35101df16de022a2b509280c6a98139fc064d55bf4fb0ff56aab58e1e73af0000000000000000000000000000000006c4d337cea53f3dfa8044afcde803bd7f31f8531144e6683d354002374f935c2a8dce5a62492d911287cc87b70c35501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ee9cca3597ccfa5708ef6f4fc19f1fe962e54dabb6a4920abd2da8715a9c3da1a4a90b43a76e05798c1a8f0443a28000000000000000000000000000000000072dc1f70a35151f25ca6ecee9a7389582d57d7848babe64a3f0a87e35c16731c44fe6825376cff3b05dbc9645c071cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b2582e245171a73f5d8fbfeb773b4657073d1ed0c71bfeb50596cbb7b8b8b4902ec05546a99a7ad79a9cc1d1d3d2b7000000000000000000000000000000001804f2ce3fc8d22fe7a9b312cde7b5241c8387dbdd55aa0d099afd4eab6d2e854690354bfc6715bf3167c816de48fa871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004395b8560c2e00ebbfc6b926212f0278627ededab6f01c76469396920493f09a2eab43daeebe3e16f44f4510274dcc40000000000000000000000000000000011ec96a5dbb04a016f4907b1ea61db8691266ef0ba236d550d439f3a4f86d4968a0e82f81bc626d59ecdb3ca343cf48f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001209b761662df407da587c4edd21cba2490d08302e6a5d3e479cbd0858c5e8e8d887313f72f888598ff6292da6bfe089000000000000000000000000000000001480e2ceab346280b34cd55fb47a88735ec04da209a467dc2f0dedae6fe51d5504081671db0f70941b8cbada39a245951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000986483635879c384c59451b376efeb3c83dbb6ebfeeb62466d428dd6bbd859ea6c92f07ab29a4a888428b5ad2d702370000000000000000000000000000000010c0902330a6f82c505e2c38965f1b5d63b0935cf024fd66d4e80761fbb48361dec6c9047f28ece9cd7c819817a8dad51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfb976ad352224958f5f042c78d095ddf4d672023efbe37a6e716b1cefd2ab0c8f1ab01895ff446f5b44cb716615d2800000000000000000000000000000000153a5bfa1ee5d2ea594fe2544ba3de9256c54dddb2f370bf7eade51e3b32334be1bcd09017dbfe751c3fd5ab13c839f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161a74ec8f0ff654dda4a25e2027252bd1a24228d05a0293f47560d68144dbbbc28011f6d078e458dc9be23b04b07351000000000000000000000000000000000e792f731289b71bd0d6f2983864a0534e994d264d614b3a3c0ccefba8e6c44c46c8be2eb43f92442a4c2ea1c106717b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfe530b6c4ae5d3df6de260cddda9ffe26f0d5416c5baad987e80dbdb855de7abb1c42ae175f0a253ec99d5b6c311070000000000000000000000000000000016abc877a6e3d2baa98304ac7c3e7266dc2649ce1b7b406f79d482825da75a16df10f77cf3d3384b32573013d4a0a60e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdfb6fd591b298cadc76b7bf4877c6770edb6e119054e215293612119684d7eadc0960c9d8691e915e20def924aecef000000000000000000000000000000000f3c4b1418c4c666ffd69c3e27ea472934f1e1bae19da058a42bfaf3a9d23eb683b698e49a61406014fbf368dd5284661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002bc8f2bbd4bf1035b5d17849b2a499ef993c89725480b29235ab9baec44db18f099d52c98f75b431ef4b8c6a24e1360000000000000000000000000000000005c974be50f8f7619a382c599742ccec24a7fd758ce0c9ea3893e0ad0e22e0170ce1ac953aafc182c9c6b7d223e39b651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065de5ddc6dc276cbfbda7b25c5f324fe0b517c3df9d98755dad204a30c237c81c39aa72ea6e0f97b62547feefda07b40000000000000000000000000000000004e25761c473435262717e08a8edd35cb8222371537300ccb67193f063ed2386772112bb9ae20ebcdc892dbac650de4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d480fd74b34d4716aae1cc1ae806672231e58ee0e826f3fbc32e347bc446feac7406b61e739f22aa64e1f996ebafa1000000000000000000000000000000001469e9b5e1e890f3d9c7675d1c6fd3139a28d128d600e083e1e64112b35fe28dbc5a088bfc218c322488fad9d5d2f5b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e31efd85acc5e94dbc3afee2034d81c28ea900d683100fb0bbedcbd4443530c1d5f4a5f366db4cfdb4dd9487e220c0000000000000000000000000000000002cd4bd9f642ffeb43546fb021133bd3f28e1f05241b84e27afb188562a4e2fed7f8b1512f33ff7843880b0450895a221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001561b9db57311fe2dc1de21cca11bb2ebe093fbde1e3bcd73ee6477fe467ec15e3afa67bc9100576671eb2126c2b41a5000000000000000000000000000000000f77f858ca649fae56cae1eace26ddfea4cc8eedd488f5342b0fdf2ef2749a4e71b1c618fb8c45d6367c1e9f65fcd3561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000003d50e15fc0c401adc387297a9086557c347f1aee6a96d7585f59eb80c1ba9048e63c5a5f3dbe769ddcf751bbde7240000000000000000000000000000000000a5b9f0ef77c8b4c5f2a15fa0d1ac7217fc19330180fab5cb6aca99f09712133493611633de9b4c606bfe0a0ee843001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab424af569549f6d528820c0e6352fd2e43cc9427ac7e4db443eecf6907ee7fefc90d1eff203915da95b9d2af05c1d000000000000000000000000000000001106138a9306b5726c15d4742c5db785c7356aeb066e7ac9ed1d541ce862a560deac14f678f68d63f97194b810180c351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e57bab83500bd04ab1af8aad47d15c10454388e6b986bd68f368ca297541b0928ada2b64b1aedeaa92e8a9d8af9ce40000000000000000000000000000000011552292080a882f6dfb2353c6f83e559eac74e63c0f6ee75c1d16305992d6cd4e3dc47b4a83a95ed45f0f386be69c361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067ca607547edd63c6e045feb31686bb8c411272675ad576ac27c75c689fbbaa9ae50d117e15f70b71cd3adb8418edd3000000000000000000000000000000000ba660b6cdf7f49490ae0631478d02e310a987021486f0a8fe47139de8eb0f332468bdb321d8f6495b703313dc4260111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171e918d61e3f339fbf71b17570e25dbb925e3be0810ec566c4f680d044bb142b5a111dacdf73ff7f9b561df80fdf0ce000000000000000000000000000000000f66960f7a6fbaedd2450653db1ba3a3a0cb8af09958a7d3da6a5b8cf5f57d086ae7bd2c539aaf107360610a5977f4271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010cb86079a6b4b1cdb118b5ba2e24e8a61efe1014899fe09285c63fa167d9f7d6647848d9cdaf6d4d93bbae4889877c5000000000000000000000000000000000744bca0f63f4fde72a732aae6845f874012ef9a5538792a00561897ba06520a9b5fedc111279e78d989f729b3cf29eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001767504df0275ccec33f188bfc5f0388091b10c599f07e847e41891af2f2c256becf1253ab9a82f3f32770eb20c82dc900000000000000000000000000000000167ef787378466d427036a3eff27068a83d59bcf0c89fd946266ceddc12c11ac02cdd8e1f36b04f2f65a238a9d5a91df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccc57ff7868adf545760571148e2054934cf1185426110d2ae9aa2cf1e6268156191ea9c3cf890bd71a47f109128e7100000000000000000000000000000000018663175deaea4280d108f37e8cdbccab129448e88fc839051dcabc42451c88d29afefb6065083661ba6103e5ba71591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160174e603c366a1594410bf0c74fd8db53bf6e56f3a83b4d97cf5f361223cc6dfeb8143492534ed7bb0eea34422693f0000000000000000000000000000000009b557b469eeeaa719260a561e6cf7d5f4284cc1ebe83e368248d35af6f3288ee61ef476aeab342ffacbd5f572bf254e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63e719127804e893cca5b5994a73fada4fbf82499502964ef1f22dc3980531c763155642e4ba290a484e48190b007e000000000000000000000000000000000c9275ce5d8a3965afb2efff41ea0678966524a7d1a92dcdaf6f6b1f564f1f346b74b5bac5bc64b8dc8f679cc073789c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea7eba93cd7dbb7be019f5af45689d34bfa2033e784bd00e10a7d189f79feb68f3097dbdcdcfb7d6f5341b0e1b155ee00000000000000000000000000000000082480ef6e25e8dea79aa76c80b9cbc7f1f34cf386c8696c0c0977d0a03ae4c63ff50bbf6f93cfe2f439ac00a1fad73c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177fa7edf5c1c655217b63b50dedc5378d0596530f176432538023c3a0b3b1daa3127aee15b36bdc9288f26c45dcdc6600000000000000000000000000000000110332e5f99e3b23a4d7b2119dad3af369cc5c40268752539190fd6f8962072116e443d9d8bdd1b11e8ec24fb9d971ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ac4358df16489ce839025e95d330a32afe30666f99394449205c71a9cd684928d3ba19856e39505847402047b86b5000000000000000000000000000000000b8b750c134b442eb82bd71846d65c34cfa765dfee1eecf8779d3f1fbbb93d676300dd0445b5ef0d708066fdcaa1bbae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107febb6ee7c01ca7b8b5ef771c7c1dab6fa5b32e9089d0ace6079434a3c7b3287bc86fba47223700cf4843646f75d01000000000000000000000000000000001192e23794dc2690d725ac29a5f80fcc528a5dd1502d9c5a9cfcee89d65a970c2b71651743f2b8bd2680598a1ddd6aaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e819477da151c76d988c4a75da912b33bfcb480ea191911d711fe4d71b165f113b55cbe3dfdbdc650b3239dae61ea50000000000000000000000000000000008d5f335edbe9ba3a6ff1b8a6b7cdfdfcd54d55e6744b0ff8fad564326b38021aa4e6d4d4db1c05d11fd76c51e5b90b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008295bb3ab4d47a93ac284f70ac8033975f47c354f206bcd171bd9cd3fea84e1714b73d59ad4a34fbc5224a38dc4822c0000000000000000000000000000000016755f7440bdaa84d68109fb55ebd9f6ebb71c81c8dad90f585d393e1f9c114163a4de3c198f5660d0d2d8e2c8f66e9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001270375d304a5caca51357a7f81912d907d3333724ed4c3ddd038d8dfca308a7e534858a603ed08fce84f43cddd64e27000000000000000000000000000000000590a639f93e377b1b8123ae68c6da7229f479e38451d34e25ebca127d6253600bc59e41555ebe08f997ee45f2b5c87c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019625b00530ad0a7bee5a2a0b546ff59100ea45e9c4ade5d657f455beb867396c71044c646b4ef3de197a578ad43e4c200000000000000000000000000000000127509ae3dcc6554b767f179a92fc71854e2f4611696eb62000798c8d8e9088fb5eb2fb81c96ef8b5e96e065e3d02e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afd7c2e944ea76134b6ccf20f1dee9b2964bfbe5fe3d9400b97c02aafc866d966586ec2f69a03afdddb37781b5e87ce00000000000000000000000000000000075514a486e8b6285a5956e5aab149596303b26058b4f1ff21516be5d01b648ad0b0d776977c5fa84e5fb16cae6526b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4979a0349d585fd87063f8ff7f5200e62e2e3f031cba9a11ebdf86520e10a51d17cfe9bfc7bc0e5bd0cccccb46a8ec000000000000000000000000000000000c47c030505dbe71d18052a43c900c7c80f427676f8a58ab7b080bca5b2ba9a4ec08c03488e057be49b03332bfae899d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a77b6fd25f61e605234b5acbb23706475a8818f6c3eabbd2e29250feaaf754b7a4f29fd1e9b1f371d7433d4a159fee400000000000000000000000000000000043d833c0426f052c5648eacf88116c20aaaa37a131cb2d282ee7eff437d4a14dc35c7c7623843e94e3daee27ea90aab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d1f77c8a597f9d3581e1ed06bfea5bc03de1de11dcf0eff928024e279d0212f810bf19acaf82791031119e33058193000000000000000000000000000000000bae6e9d1d2cf08f99d9b889e2d2dff9cca9218593d050b59b9797835bca446e57daeaeb79f02bb3b51f738ecefe87781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015de7fa8bceb9ae2b563b999b3cbbaacac43b4e77d8274fb7a46bcefce3c724573fc58dfe80b29a6d1659e4995bceb040000000000000000000000000000000002181736e09e18bbf383418e796613815ace04774d72f1c04d6761064bf1bd6c7cb41d90440e24e17a9a15b05fa7a32c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141498f37a372b19066352d4194844098660d0463b9e7cd673f6185b9329ad3356f0de916925db6b41087607484f5597000000000000000000000000000000000da1bd1932483eda4ce05a12f75d09266d5f9a1ec23d375d908f3531cf66839624f4bd6ff0cab075b47c3c09d586ba5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014941a2215eb0f711175eab098b6e7d419cbc7094cfcdbe22d65df3efc08a4125f00ea7da81727e7c3d19b7e6424fa660000000000000000000000000000000018b9898cf15de648b099eb29795e4a6b8fee7815823ffb2b02a5c3569e714ff933ce189d564f299b69bb526d6da8264f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001368f6530617e9fe7ab985a4bd6328b6d41b9c2f8dbd1cda3ac9116fcb6ae347082569b873c7733e8b4be5a4dbd484ee000000000000000000000000000000000d815277889bae7035ff6b94a619e3519ac63877e77af61b5bea747e553e63a75b362f13db077e9f8fcc5b0c7cecb10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee53df3e00e451f3e79ce22c12016e82c45bbca0571fd42cc91f42ea73e92e661d2b6c40f17ec587c5b25ccbd0b8f50000000000000000000000000000000001b12ba0c9b5147145d9108d00a3336a5e99535a97a0f33fb5ddbe20ea2e37180d83257b9aedf5ebcd69489c618d7c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016483f851928becadd24df5e1c29cb7cb8f9b4608ee0106794466275f5a0c4250f949188543d22660343a44018c607ec00000000000000000000000000000000026028df9757edf3592272f31ee8ff496efbeedf5fe812df3d81b6b7a7cbfceb08ba2585a646d442c7bf47c4094abdd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004225bccd362b65cf423675ca72342e21f8fd0b39fd37009913cb31d650418e2dbf61c7c4d3634478813ef92382508a1000000000000000000000000000000000026fafc0cade13e6d0b974ce95f026d798b252af9b654acac2b186346907269e3e2b17d0a909a8d3ce7d93a8542b6111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014aa2fdb01e537178fffff81f9cb4d0b7fbff783c5300ef6c6cdc9229f800b214f75d85dca95f814822bbc60c8043caf0000000000000000000000000000000007862643d0f2b5a8c76118ddbd07c5f372f4e435be1953dcef7290959e4ffe8f9bdbf2b2c73e38269e6189877b86f2151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd24533521c65fd9472d5b761a1a8bb435d65976f19599d4b20352fb208a6aeed37e46333dda502a43b19d3796bd5e000000000000000000000000000000000157d2fe2c98a5a1abcffb55097dc7747f8b7c5c0c2396c426c99155fc48a5b95389a57dd6fe86138f6d47cda1fd07f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa7762fc4910ce3865c79b9af7ec03a77fe0a37c63f8bc90f02cd8f7c57ceb6938c363c68c1628a3864861c6053e0fb000000000000000000000000000000000e11b34d529bac3a68f313f4e1ebe0ef3e4eba0832cd69caf398a1a821219266e81fe58b6fcba38ab11863c6c440d6f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b224603d40eb0dfaedcfecc6c27fa1e1111455276a1f2f8f9111aa5e5168474769e62219d7d99752fecb2f2268fa7060000000000000000000000000000000002c25b5facebecd99a9f6378352702ad959a033ba70727cf0ab7571eb2f1bd0bac186bd2db03b729d5c942a8e9f3f3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005444c167598fc866718e4088671ed1b29a10c4172d4d7d2ec7e09ec896c0937dcc3fa0e2fa5413a813ab247572f9cb40000000000000000000000000000000007b4bfb0f3c3cb248709eb0d6da7a5856536920c22f294249399c1f551b84b8e2a323a9a16c08a79972e9444cf9d29411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7fe1b93783366021354f370dbcb20ca8287872989cc308c30023ff2088738d9cda2e9a9e368440d495d27ec7999860000000000000000000000000000000001606ac002dae9bbe6ac521d9ba07e6e54ff7441ddb5be6e71d8764f02f22f7b1e258758b0c44ba19c205add7b138a74c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154d45be3c664dadd1226ec88454fdaaa2ac10b9f9c046c9dbd5f6d77d2c684365a66f4602e3f7caf4ee6e536be8f5cf000000000000000000000000000000000f52d6324bd111063da6fdcfd4c9bde99a21fb0c1dbf50573416f625b1888d319eb9cf3671ef33b28d56523a67c0525c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109236a2f430dd436451539b9aabde6034f351c231ec06683dc280693e173729b74d8ea92d1a2ecd4c11fd8e68be94ab00000000000000000000000000000000119cf76a755d72a0773e87032414e8112de139df4612def0f55cc5d4d7439d76642b7907d4795e1b28b477f06df9378e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015044a4d4ab02f81022c9db3d0b1e1eddea7beee38e30b73ad802b42d191bde0ca656cee195c377ba07951b1b15de8bd00000000000000000000000000000000072fbc8fca0876ebc194c54243ec163757763fc66b1c70362b8b1c162dc9bda5894999373b65dc38989a425a0c284d1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c88cca6543024d61baf541dfbca6f48ef05b0bf8fbade4a81c6fc2969547a833bd05069228ee3cc1e6768319bff3580000000000000000000000000000000019d1cc3c83143b77ce1a20f48c5fe5bf687b104ec7b0b97f32acf83d46663903baf94e9b9124d09ca415148b76db43b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e0bf7f10be04b5dddf42f245d03144afe12e88948c3a974e3922016fee2657e8deaec7dde68c60cf8a5bb25df083450000000000000000000000000000000000edd46faf3945b0c1de820a8734da075b7d42e5aff88b568039001dd2009d6bb51400dbd90856bca8aaf16d0e8b0f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a74ab8c578871bb746da95fce4383ddcbd959156127efc1bc4c68affd22641eb6ef769b940b5e75d7343ff8e59bb040000000000000000000000000000000014b7a57c54a64f8ec69f0d63f26216082448d94b6e7c818be7002250bf44f65e722039754f242dce1d4be908682369e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538566e5b219404f1bc26b3861837b573c99398102d749aa88e1183b19463deb8070d433a12aeffd7e7bad0a25b75ca00000000000000000000000000000000118abc01e63983e0dccd5b7bd3574038ba300ce3be84bd1a9f62613eeb9f505d22b7f258798255c7db447ff21b54e5031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016280f6f4b4a457219687586b6add63aee7c7acb3857c563f37ee4070923ce6efdede605aa77e0b19e4178a0c55825640000000000000000000000000000000002e6bc54a025f75533e2106f95b549c5392d599385d0bea55b802b0af2ff2e80bcdfdb5921f289508debf770956ec7381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002529abd28cb1568fe810da3ff97eb78f2f7a62287daefa0b3ffe8a1bb8a7252d920ffdf9cb07022ff09fbcabfdee58200000000000000000000000000000000074002f6b87993cb8fe40289d125512a1ffd4ef5c7e20f9da64b0984fbb46e76210189ebc698e9dcaeefe0014b954e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176682241877385411d0121d2a18cc4b6bbd306ee1f23250c1bf1449e88473e3d4316f16bf816bf66aa5f32e0267a950000000000000000000000000000000000bb13bfc13195be19fd77e5443db47a3005a823a866237a6bee9407330a0acc8962efcaeb9a6fb1073506b35043c51381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f614bfb0d77ffb2981a1de0f640e8b2f206b45c3bc2e28b4a0c85dc94f318d982d6c0f0eba6ac15f9bb7ae005ac9f00000000000000000000000000000000004b6804cac754790b0ba4d2ed4157d5e33f34115694362e7d8b8ab4f05bc032fd230f2a70247b623389b6c5fadad56b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9cd682b8d91dd87ad0436244e65ed502533c941bc4b15c22e9fc8208d2b1680b2c1d565ab8ac691ef8cb655bea1ec0000000000000000000000000000000013ea73ade23cd244c46f696aac40cceca8bdeab597f1eefd2a245bcc6814fe4d3b53df11f3ac9a42b5b857b4cbde76ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ba355da5f29072f1ce6556eb28117c291a5d8359c5d660d6dac032795247e6ab28227f604fa695b9af360ee1686c24000000000000000000000000000000000514827b0c2684cc83dfe4bb118c039e37eb3afe3bcf925f68d64ec6c87416caa9e76dcefb8e7714ace1c77c5bd577261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916e0188c580c6da82b576c247bf026d5e1392d387b8cb6df4cea23dbb0b239cf44ea79dc5b69f3589929d93b8205010000000000000000000000000000000017fa7a6980d7bf80c02469fef3fdf99fdf112980919b171066e3aaed1d9811b351998701a198212521961fec1e7774551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000557a024b0b23b267aab806af84a6b27c8ff6732aaf1238271d502dae04fef430316cddec2ce0300f579554cbf507c6a000000000000000000000000000000000dea331dc85f67e917dab59e56d019a788277eb35fb26a30240c8fab661db14c3eb60fe4a1484d6223df1aa1fc8f6e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ae2edfdc30e040c860bd8bdcfcafe7df509cf2077bd05c9d4ede461d3c9e6cdf9feae6092db944d98c3c14d8d7d3c00000000000000000000000000000000018d932487fc8f30e5c61e9fed02468a78878f1c64f3d98893b0f8c52e71ed175aad2302a4e41b43718b9ccaff0b410b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003eab3a07f5cd5d920e849d09337b6bf207817e97b62d23b2cf29826a7648c6ebc21db032a4e036dfb515665f809089f0000000000000000000000000000000008d24682976cf230ea65e08d0f3914b37f0c4c4fcf0178eecc4ff7414a2dc0b4c2192f85e33cc08eae5a313d46e8a57b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ad461daf75d97fb4a8df3eee66ad4f4d52ce7db447831e627f4bcbbc1af816a4fec85c29b917a01878a821697c332700000000000000000000000000000000158024acdd1c792066f52f56b0568584cb14a0f90f34c2d45f2865a42649c30d83210651e0127b1df198175ce27047ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6cad41b0f57af2f22761f8e724a7254250d88fc8a7712780919b6f89145541c8baa2ab8248d509bd391acbd4f34b7d000000000000000000000000000000000cfdf55a4707bf285fb728fef03a93d5aa15ee98c7367518c8462593a8911896f4e0d507b39e5467163e8f9c24a479ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097b42c25098c874f981add61f7d5535ef4bff8fcd7d976029f168d25c64416d8b6a25412ffb87bf0b20e7d82b43c7fc0000000000000000000000000000000019a13745bb270a798aa678b0b74c4b298c0586368fabb350f8cc791dd850706a42f2b26f62006ff5f08a3e864e635aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151bd296259eceb417c3fc4854639e42db5d2761fa2cb8e38bc5bff810ddf5cdc9b718525b643ea96cd53c75a0bf4bfe0000000000000000000000000000000016a156c0e5a87e06137724c3f8d42d07a69a667d29d3cb271aedca14527c28b8a92d3d057808ab4187fb8baff1608d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003524700e29419913574479cc57b3b98f6ab23ad7763deddb53d8088c8c958011610debb575761a12d07ff0b6cc0fc3d0000000000000000000000000000000018d4f884b50e4118d718d6e90fd3e30150c89349fe78623f312a94b83560f6d5398bc17d898239bc3c1c3fd7d09becde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000caad01fbbf719a9bd921defd9e68f6d61e676006c8b255c8f8186c79d5bd31587a6c7c53e8318615f7818ef4e1e293100000000000000000000000000000000143af413792337ac93809609910e305352473d818e82ec35e58dea271d0aeac44b75cc40cf7274abf48b31aeac1765ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df6da3d6a58eba74e9bbda1424de97fdb3b712809d4c6c1ce7fbaf92b88a46031543efa7afd29e588c3f3e64dd19e650000000000000000000000000000000013829e5628dc2892a064cbee1fab272d6601679243d74a7882f49f7d99e2418b9330bd638da2f4d42c05af50adfa5df81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ee51f224bdeb7925540f79ec64c18f7a0adc888a7a8ca3b52e9a2e753d8b20fdfede311ac490b995bc67549209dd9000000000000000000000000000000000dd50b1136453ea9390f988eb38004636189433d9f21bab248a8afa291bd40993cd2a347c10f6a36697f0f03bc791a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c1aa318cb330e66ab65935c8dff53ee393c4b313a39ee498d8b31970656f6ff9a88327ef03f37586ba7437e2f86ce1000000000000000000000000000000000f8b56f81a587bf020d05368022a54459087b9ce2a9f08d6f33dec1ad5b6a83a0db87c4353e7d553609a4fbb14a626011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066e25d11bcb49ea88e24030e35ac832445922146bb4052a282f7b038ec0751c230a4c51f8a48ac7627f636d2ea79d6100000000000000000000000000000000161eabf9cb16be07fd6039357899d1a708f34ff2e67d00d5944d0805b14bc8b68c87ea1bba1485936e23457c960388c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dfcd2068333404ae886686ad38a0815bfbbc15a15b7d336d946f234e72080fb8439901561b2d483cbbaf07d6f2ca0600000000000000000000000000000000107908de7e77f92219c83255f36385f157fb633fc0d6a0e33d3fe05cd3f7ed9371f0beac7664075e25eabf3a0fab03de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0bbe3d79643b4f7362a33f603e124259c8242c36e46d605b5f9b9c6453a0a1340dfb6f594d975f8ac3245d4f75f8960000000000000000000000000000000010c1323859a92acdc936d0665074bbaff149b6fe597fc6e9bdfe546ab7f7a16abfc8216b7e4033c3b23dabab84574b2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fe6bcf24d612628b7244f08731b4b111d21c2ed5a55e09fe226eb6ef17c32cca07d98173e6846b446cf652c6d5745100000000000000000000000000000000082468d3b741325ff23aca7e67f8635cfb305424b9707bf93e236a4e9f38f914e97e10263fe7885304bc52a2ea5748ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b245ae5e8ca0a49b1671f6899122430aae5ea97781db40592874cb8f3cb9dae2f6de6644d4b9a3dd67faf6e80f9ad000000000000000000000000000000001291b8d2a0f27399dbd297593fb09c7510b2c86f2f130c565abefd1bda8c531edc7bbdfde907f1422a9ed71d05a8e2201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030ff7915fce335c6dce7a1addb67c3cef95205733d4dc00c449cbe674a339ab06ae017b3ee346428cd0d417dc4637cc000000000000000000000000000000000f818e978eaf89b99fa030f563fa82730d19815b1b229bd87739dc2a09f5bc975bbe2eac2a7be420485eafdb59740a5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ebfb93012319e55105060482abfbd936f72d7a21458cdf32da7422875a277e8372088cb2a0681c516dd1d182b6ef8c000000000000000000000000000000000794199bbd52aadffdfc593cf27462be8fdde9b36317f976a5a16b3b42129de7612b6e06df954945f2fc7a36e030bd431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7584da5ecb6e67240d5af65ebbbfb257c080b6bbda0e803a11d9d6ea7456611d6d19c9efc029d5faac9375e2c582b900000000000000000000000000000000118247e0f3d3b24a8b7e25a2cc35fbd76732a7ed63f85203083381dab82f8d2b08a80e576dfb89e0b0240131d5a3b5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd15a4cc7cbf56844ee8dd963521eca7b30cb3a68b924bf7f9990c6336c8a81e30a4d799451fe180898a9a5a112561d0000000000000000000000000000000017c328b30266075142b7ecbcad3b9a1c57723e7b0d319e49d4679bbb0ad9ad408925ca5ba0ec3b6167a8c106b62cc5781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fed565b085aa69f74d53882868862c6c487b6f5d8b5aabc7758768b9e427d2630c9c943db28c9404227f9eda1e9698400000000000000000000000000000000152b36f7f0a26fff1b2536adef9271db799e9460f35d91cf6afb407d249a88092058bd791e85f4f4d92e95d8b53fdd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d2da898b471acd292dc77fd2f986cefbde3879ccbba2907c25d87c4e30c80ad91878f7489f5bb95fb4d46e574a1b9600000000000000000000000000000000022c0ce5d5cdea7fcaaeda85382c695d57fb08953448118a6d0359d04af80fd85687f3e4fd928db0ce145e28923cb3ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dbe99647fd155fb471450021182cc0b2a43abb4b3665c316f2b9cd922c2f1434f74aa700533e0d7a213b6f38f505549000000000000000000000000000000000a5daf098da498e17dbab98945b574e9ff779151b42715c4abbe9e6dec12815d6ec593cf22be59cfa855d081a09d0aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b312de236ac83b0cdbdf7b8629676348b5fcd56f9486c6a8529986fd3f490c87bf1bac96bf5cea4b144a62b20c411a00000000000000000000000000000000006c9a6bf77de583d8bfcba2c339e1f731a4f7b73efed715bd5a03ae20cf9221593e075fd4ea4af5346108250b7bcf531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141f281aa6fae698432632b2479bd54cc4b0ba599426775efaadaebdd56d906ad2463c6ea9bfa532a0b8cfc632c1f22a000000000000000000000000000000000e51d23d398e232c4bb9d10556df130e782cec4d1bbb0bd3296405117e9ab0bb8d4aafa9b7c1e706832ee1a922ab50a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2ccc52c64e81bc27246d789747a6e208d07e879f93b4d93fb5c35f225fcac7ab80a725c2139d12ab799617350e793000000000000000000000000000000001114e4f01d74c81f08875015535e52493eefdfede8ed03392d06882ee73922bb930bda835bd40f7b1956328ea364405c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001095d433762c64e8eef7feca67c4f2fac4ff73d177123087bc1b695c9df9e4aba4697fade5785a9ba2c2459906a9d7870000000000000000000000000000000005225842d300934c97c5f82e5964b3cf1e1f05831e23bf96e0d4867843680c33915b41990ebc6d71fb976dd7b30b47c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f29b93d410dd7ba6c935e4686271c2abbdac185ecf7cc6c1826f9416d2cb77ea0497cdd1adf387eb72a7083304c69e000000000000000000000000000000000bc638439215f61ab6106b726125d22b6ba2d895af5879443bfe539aba0da005fa050df05985a042ce83f5a22d04a7241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4d662741daa14ff358c9eb48684e00d5160cb642fef1e5091a94e8553f504e56912cf86d483b6774461409713d69f8000000000000000000000000000000000b514d840864602efd0e0c7c17102e3dcc17c2f9c6939c187d5629a1796b00f1fd02622d58daffb493c94b5cf79068131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c68615cb39650f2ee35c9153c0a260a8f1daeb46cd102b5470a92b918ff4f484fd3f50ac4324588cee4975fe4c5686f0000000000000000000000000000000016a18030f49c2034a771d28ad4d525867cadf8a37662f4b28c1b3881556c342490d72e4d57f6d1271191c8e338bac9c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d8366c94afcff0792e31b7786d08177899b177b2cf49bc77bb846fae62b11032fef60f058a10466d668abdf436c130000000000000000000000000000000001ba0b06c6d3812f0c40c3bc2c5532eb14a957739eb7ed05987dcdb22f7b52a03955c2356240c58bb04cdcc2e0e975b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d0bb909c0f98721bbd0a9949d87e84e6cbebb93a832d320321fde1f1e2774e69a379c318d0f60547c357c228ddf8a00000000000000000000000000000000035131e801995f046cb90e9232c37de121541d2d3435a910e7937dd558326ec771bdbec2f65dea72ef6aa111eb2503231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000905c053e24816281a46d68e203d597a4fa3c234e0257ce069a16bdf6ef3078bbf2def1b47bf38e190860070b42f0745000000000000000000000000000000000d4a328fc86e1cecc72b3b773649eb5d08c03a27db631de89817ab4df8caa58b94cd6ec2a23d7c07a13a59783ca128331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085b4e19d8873ebabc7f89e4e8c3ac8e798cab339a1b7d9ab261e719713605d4ae3842e6d89e01e892ce82c44a3da69b0000000000000000000000000000000004a40dfb58ffa92d2639951c5d08bac4ff3f716e04f31acd29ba9af58daa60d2d0b8fe72c6361c7fc1d510aff39909021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a0c8710c77b22b733e3b29d08e41b14a16bd61bfd9b015d6552080b2dca8482908cdb40c509ff94a23e3acadbb15db200000000000000000000000000000000190c6bd189e34d78456afc8e88942f0e5025bf33ed7ac0b709c7a6e4bb0eac96e9aae5dae4abfd18e1178805771862061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090a5c0e3323e1c6052061b48b5c818b7e35e93aaa1cb636b111ea616b2478d87f2592dea70cc0e73ea023a9e7d30e7400000000000000000000000000000000184164ecb8b9cad2a96bfaf9491cecc7be26f8dd6d93edba11368a1225f8c918b0110ed47b5dde3000094b54c0eba9c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f5553db67bc8df3a16fff2e8ebf2799c182ff790b953cf2c564754720f2218d9bfc5f0c3824f90e53272d362359f30000000000000000000000000000000000ef7615fb1aa63dae3f7386a37b4959f0aeb94eb4352bb463e72bc593f0554abded1148b119b6789c683cca53e159f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149eea5cd1f67ae195fff9beaaaab6b60dad42a50ee46195527e2979d6ef0072cb02c6fcbba112c87110204c19da85ad0000000000000000000000000000000006eb91e83057a0ddff5f23e9b1c05dff534d0903e2aaf63aabbd779559112cce9ca71515d2955aedf53e0f84ee8270f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3df0ebe61fd0f3ff1c82a5d1f46a600c3e22a5b3be0cfcf09dfc38a0b8e6f199efdf0eb200badb8e78c44aab3e348e0000000000000000000000000000000000cfc4e93284ffa90482a2267a5b80be5b6d96d8114378d8034593b5fa054f0b1fb8aa1a1e9a0c55ec2d7b390d7505a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a7e86f0f19a6792d4a3755550b15ccb179b8551bf654ccf0be13a5f2a581c9d6bcc90494224e00caf7531966ac63c7000000000000000000000000000000000b92ba8ed18e31a9dc0c193f1eb33a570e4c09f204e453dd806b385c197139c8ab237781b2cd2e340f30d12f946a5abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012be2d05f7e439112b9caf67d305eaa9bf18c56442ec3e31d256d258f39ba10f7dfde4c1ef06daa2666dbc473d1c83b100000000000000000000000000000000180017de22f7bf27d25cd5048edc33de6a6112bca4557b43dac4a62f1347ce02285ca46158dc0ee2ca4e58e33968b17f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d01530e2b3758e5d7c1a7d6147c60f028cfc0e9769363fd41967ed47cfe58f45fd683b43f1342abf62ee4111d2a608a000000000000000000000000000000000072e55bdcda75f484352b0a5e6b6600b5e0db8d6c312e5d2cdca6aea10b36075b6362e65cddcee44fda5c9c3904e75f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5e0f7bc5aa1e4667b543b5aa5f67ad30fb4d312dbab4c47dab883c400717199a449a37f94e1aa84f548f165d7e017f000000000000000000000000000000000cc112b2ee9bd8adfa23db5e18c70b294fa48869f3524269c355894c3d4a5c6ae4ff38b6469194c9a2b34d224c5dc7a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106de6cd3c22859015ea2ebb966a6522eb79ffacee4022dd6b5282477b7227135fdf23112175090d818fd230cfce6c15000000000000000000000000000000000d344b613b8c4e854d67992afc41d213afe3a19e55a64f2dfe2039f1e4a5c416d17dec1c56e89261bafbfdd130f6887f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009782df7ff3f34944414ee90615641a7821c97542094607abc7f3dfab22b64a6d516707b8492373c45dde3bf2f5db93800000000000000000000000000000000169406ec0c21294604d99c1725902a13c872d1c3044fc2cc6092deebd18e0bffac7699ad8e289f344207f5877b385c271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011198cbeab130c5bdf760f6f094151b24e9ec64145ac0357ee48c5ccef380cc6a0fb58e207949a6f9be49ea1986774cc000000000000000000000000000000000b9136a902506fa01d15a44e8d471c51b004da3011785e41cea0670385fc352390e8325ca9e72da537a7bbbbaad00ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae41dd6640679a332da47c1af423eabd0fe632b341d7bdecb755c82a4dd4b62b02a5df0224ed672c7c619bc626a6d3b000000000000000000000000000000000788240e7d611f7c485dc5b7d71b8a5f2c8917aee7c4a85bcb3e582a4c9a201f7bac99a9bbd2e34a7d5ef4a2b504879a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001696def9c320137916fd0b9b1b9d19ab244e58b605b031519c4310083d2552fb22a90ed6397f2d91324824aef2df04460000000000000000000000000000000003ec63070553e114ff2900c678aa29e0f9549f20e5da6455036771fcd74e66023d10a8d25373372733e603b54ede9fdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e640b74f26ddb8b588d13fb12183c5553327c75bfb782ce3f4a7dd3d742724d02131346f8492f19d2042ba39c958ede0000000000000000000000000000000003b4e0174717953dcc8442bca939c52a873431ea6b09fb65bf0d0a3b73913d0c390ae5aebff42067fd4ab31a7ba26ff41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001876fc58ba72b8e11095dabf9f4dbf968bdcd63716a07ec9b42fb229259e7126162ad0a3cdb7516ba5177411ac688f560000000000000000000000000000000017e9d8b35eb73a0a0a4156bbe417a71477fa63e69b51cebf2584b8faf94723ade364feab382c536ac1a0d24b3bbec3f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129ed9691b2e6ceec944878ae158920d1deb9136211546754dda802ce434c58174091eb91634588074db4ae991034860000000000000000000000000000000000ea71ba722ce7a2cdbac5df838065a2671ed0e2957c5bd26da8bd9480821508a4d40b307c3f6531ef815cfdd3277470e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfa4b48cbde7c8ec52282d70133d6ca0a91d2808d877e6aecff0cf5b9dde710ac066c08cd73d54b010b498147091565000000000000000000000000000000000eb67f4daaf92108d67461762da24f0d38f19cd30c4c00468d58c5cc258438b11d26044ebb17ea09d5548491239d02dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b728395ef8aa8e76d64ab8c3fe3c4c84c7453acf4fb6350ebd6dc261ecd4623d47e22e853d12ae0d763815639c61a5000000000000000000000000000000000d4d417bb7e668d9d365a86b85c0f0d4cc32e71f9821ab1beda614ac4e2f1c0ea03fb3ee93ab90a6347f03e540ea9b7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140466f0b33681a8b910a82b896d640583fed191678be5d732907199fb1c50225ad104d0a8a169bca7f2e0f4c2671ca5000000000000000000000000000000000e7d645aff38ca00f056ea179d7a429fc2725d8292b6d9c98dc9ae4bc45e01c8abbbe9c440901a8ee15cbd67542bd9361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f94eeafe1e3e73298943cfd105a2d63e05673b1ff3d7d26a01a4fcb42e878732ff04d70d3b02d04d44aaf1af4027b680000000000000000000000000000000014c52335866b9486b3fcf15f4058c4f52438593a0abf0cb8732343091e50c354076d813cccfd64c78eacf22cce358ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb6e6510efa55b0524bd8acfbc22bd0850e4c59e57ff7fc8c07765c107125ca7866887150648914d0babb2135d5b97000000000000000000000000000000000ae4b76e47b0c9860e4d0e38c2491e37b2a3dc15beac38564b18dd39475f278690d0e9d2ce5ebfb306e7c7d4c61567a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001967cee7daddd5fc4d6ab943371ffc6cd17810a86c4acba42df60b23009dd03a9a6e8c7fd228dfed75926149bf777ba900000000000000000000000000000000185104ebed6c3f7021769f346a1ed3a371f2dfe0cb5aa30462a64a098fc96cb621f9b1ae89756592b3a71381295cd62b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c73305a7ffe40d128443ce2bf2c09b50334f6c6c9c157e4ee0651906e39925f7a5002504d9bae4a1b9403de1a87ad00000000000000000000000000000000005bb37ceb07b3f9d9e934e054dd23f9800c6b32ebfe9d7d367dd3e2c0ebfbe04be4e52c6ee170543972ab89c1747725f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051d13d5852b41df0072b099dffe4387cf70675fadfbf4dd0ba2037d6c2103e6c1982bb6f7f92b834c15522bb23259f10000000000000000000000000000000016dc4dcc3a2a7c470be10ad62b1cc867623e9e6cf463b0fa42bafca48c6052106b9e8934abbf7c0c83a2e6181f5dad9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f21d51822cf876b8f22b239c7ed3e1bdd08e8048b028a100cecd98ec91eb3f157b63b4e7c2a0d5b27f3fdc6917a9f8000000000000000000000000000000001978d4697130aac5700a57ac009cf5a0f6597df9fab7786a9d07e5b2294d7bac364677ace265e859e509142789f17b031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004977b41b70966e89cdddd3bdfd94c1c553b0f3fd0b079be877cfc02dee3e4ebee7c64fc90b735928967d02cd513bbce0000000000000000000000000000000012cdd6bcb7b917f9d9ee7506a167f5e5bc79585c8296d374c084e5b8cba293845d66e2a4425c30e60dd23c137667d95e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ebffb5d89a8e8176449a52f79676b8295711823f3cee7c2cb89df889618a0ff66c9cecbe7c36929519cad8892ac2210000000000000000000000000000000019d425a2b105257ab263f17529b0fbb89da61e4a52a183a46b550172e1d83b473ca74c49d067092a8dc1ffb0e11b77ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5f7eab7f3f9177c697e2b4cae8825480d5e45e57969c68332d73b1bfa04048521d43325a2dfa94d4cd26a55f4f86f40000000000000000000000000000000002336c19d198f8a6f9332463543a9cdb15c0c77b5184c16a8d2d22491a51e996398990ceaefdc6471292153c6bdeda611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c551c5feebfaf414b4648304d99e1b8d37d48e9f145c3d3201f32c7e9d2d89b00e3fe957e90a51b83a5e8d4fc31ceeb0000000000000000000000000000000019898130e4f9c445db004fba23124a1ee6ef52d3e80cd0600871484019a9382d2fe5ba1c702d98fdf453fb82b5687af01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f7599c089bdb7839433967ad2beae71d79e620c82cdb3443089f4e95e25ca5b69a0b32e762709db2eaace4daa9645a000000000000000000000000000000000d9ba27c416f49f9180ecc07c19f398f76b63a9734e3edcddf6815dc0a1dc87e0c5e24606dff575e650e6b6749fb04e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b319d7e9c2c41151470dcdeb437a4c55d0ade6263534e0ee3c389b663e6d2a01b707f8fcae2f7ef4435141ba2021a300000000000000000000000000000000065df37dd0fa2ea3ac47eea6878ef015fbe4d607c46abc5b4f90ba355b5d159c2d116218b0867eef96436c89d9500c331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d7ea2b47c08bc6f0308a40b9b04c3f1ad01b72d43b9e42d8113b9645109565315d9cfd9819d9043e598400614952d00000000000000000000000000000000007314cf838a5841da4a14200bd458b895b4a33bb474f0c84abc10330e538e220e6896e0180bb042de95c370ef52f8ee81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b3b06cc9d8e000397897ed3ea3e861cd1aed60a1df0da1c83cab35754f758022d25c7f33d036639a3b89c84109651a000000000000000000000000000000000d5cce8fd7835696e33376c3cf1d4aaa129fd5b352f90377a78748c0a917c6d05000253fa30a2f6ec95a109fe2d4bb291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c62345a6c810dd06ada4cdf46def7f872626ffe5bd9fc7f1975bc95b3ef6fce801374c4abe99ba63a1095be697a9c8000000000000000000000000000000000303e5d509395dbe0cbea3158cc291ae11ed24e4db81bd05c71d62f52857a80c10eb3d403b8a1bac175947b0010b3eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e93b306f6915e80f8d44c4e72342aa97c1654a370e8f5f71b001257f69e5542030187e55bd3e72dfe344bd0d861b8b20000000000000000000000000000000012b8c04fcd4d759963aa80bda996a5addab2fc0c01c6da3619d00194854b46d6a5edbc4c6c3acfcf34f09721f769b3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001087913294a69e7e8d383cae35f7dc81e15eab568c87fd5d0a0b645def5c7e9d936240a564966b2500f88fc1ddab3f25000000000000000000000000000000000258220e350aa832b764a28379b864763644c0d2baa5562cb1b22737f8df361c86c8d757fe9f298293de891edfe1aadb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001527cac4daf84915843f4aca14b8fe640fb4674b8efa7cd47b229347effdbfff4413fba4fb62837eb5e8e2ae9bef77d8000000000000000000000000000000000cbfd8ae00594dc9579a3415a3afa2c15adeb28fb9b76942875907843d32cf763908b1601070c3b053aeb2065ebc9ad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c623c9aacbe26468e62c3e618dee67e276db94e0339e32faa1079d1adfaba6653897de0afec2b4758b63189b211fcf2000000000000000000000000000000000f85dca1ab2017ca545e4033d974e932a21b5f0152dc2154e1ce2365da4a33d2f8516a40499a52ee07e390336060cedf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000290d3c670a67da0fdb3af26f70a5c9119a330f715dca52557fe4dfc20c2a28a92e649bdf8850ee03dadae330296d4560000000000000000000000000000000019cc08c8ffc527b6cdff5f9f9722dab5061dc96d8ad2866ea72b315a4602c90da919339e1065f87e2649b5dc284984791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb95dba7488bf18858d1381676f9576c568eb715ab225ff8d25a84b20c6f1cd6dc8e2955b6a5e6aceb176293c53dbde000000000000000000000000000000001908f016526a78f89443bbf738e4fa1ffeee5f3c54985ff9f21023d4fea68db6ee8bbd1cb33871bb0b0033580b59a9371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bd2e7dd67bd0b72b2ce52ba841a45d7427f4dbdd3702fab3d67655f1fa0befe5385c7d93a67cff9eb6c6301a8ea766000000000000000000000000000000000273a0cd7c02e397eff19b1c49174e9de5e523f51ee2943d3ee745ad986f5aba92f13fe45469b20e7d805904c335251e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d14fffa74365ce47f872d8671399d4385e2d46344cc9a14affb3e6fcced423d731f854bdf3098c05cdd42487c750bd30000000000000000000000000000000014550a918c4716be361acf40f30e8c2a865ab1ee5f0cf863828f1c2da824379d248f2b12b578e60509e36029096a89bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fca0d6b4fbc64bf3c7b7ad70dd459bc9f7ff64716307da0185e3bdb59a13c9becf67e6265de23d6abd309c5dbaef40e000000000000000000000000000000001507022bd6b482e8a0fd144e3923246b901d38b151da1bea81937f721a2baed35d39493a10494415847aa0fdd793f61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018523585204bc4c34767b0939b40e6f2f3f9f1e0e1996af69eee55ac3d7a162e395e70fd611beee50cd49e6a203860b500000000000000000000000000000000019f6b68f2e3c0bad33b7833994716170b576a9d2e6d4f83f9525b6d697b78da7b51ccd44540ff147aaa2fade0f2792d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b286587c6293bac49570a3e812f2bd61d9798250e64cb03c7dbae219314a95091f80ae143381a8f14c689a2781f89a000000000000000000000000000000000cd122ee1c29d904e55b9a6722e606ab08eca8e4c1c897a71aed8c63821fac8307ffc716612024580c03be1f11a606d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001672e3fe888c0d7b3ded53a4e418075b089c350699db800a0e48aada4e7528323ce36827f4b651dd19bd95ea14bcf92c000000000000000000000000000000001567281433198b984f240f7d6f7f402e4dddd482d28e25ed52b499e20439fe8e231b9e090fc0514c4bc00878a26777121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020cb7e8427e70ab2e948cd8e6369bb14e8d7b6b162315a0bff2fdc5a556960020ad498f31a3955e5290c1dd229346290000000000000000000000000000000011de6d70f29b24abf4dd666a6238bcce1edb34e30db2db8b36c1ae283840dc863786c79a1b5a66e611d1cd711c1f6b6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a11b0c833936400d13a8ab4d80730dcefe479b61f4c97ac09a8ad58b4ba08261a93a1c0af925836bfe119fa07ff5b4000000000000000000000000000000000deed4977fd03f3469d3617fc6cdc198234e518ab156c5dec9fb105627567b205d1d0bc7a272a3453b29528a6acd08e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143aaaa8ab651bb89d17d18ea6ee102f583aa34ad7cd7a7878cd2df5e1e6d83c418da05c3b064d0e80a9f9f739b2b37d00000000000000000000000000000000147868f9fb6174b85e50aba1b4c6128cd07e189d57d56651609bebf451e24c0c4856158e3f1e51600559e32b3cbad95d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007842fee58cbc24ac42ff3746c8d43a5ecfd93dd72158c5942b4517c175925d28af09ee117108bb53c5636846a6adf850000000000000000000000000000000005d9bae9894ce88cc11aeb9deaf05a90837ab689615ec3675b2c764d09ae05fa5a88b30bc243b871585477d8b006cfe01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000224f1cc5e10b2d8c220f0668475fd291c41442f5ee3a49299a37a4e8d7d5ee4fe0b89082d16b09e0e7d8891a6235f860000000000000000000000000000000012b9f8a3a88b5c81e547211a2d80013ccc3825ef5958d7dfb28b930e9b944a4da8b21135ca6b170c98dad70297328eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002062a534918e723df3a2a1301caaa1e1116786c297eeff9fb1a0aa7b99ef2c7b51c6d39e4aea555ca448783c95b7565000000000000000000000000000000000c85da99188215305c77bef56fce934a7d4af4f974c91f5e9a91e1ca256d367b228589dc7a950bddfdc2318800057f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8d7321d6cf2b2c76dc6ff4b4a98acf2dee69476ed7b78283dc7cd1a0d0fcd04c2a3b90de5d1ef95185f544f32e8b3c000000000000000000000000000000000f1913951d4171392b87edef264734b9d153d9c48c5823835c741e0b1429a4c4422c4b47a69e063ff1d8ff6922ff70811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092df8ad1a607f1a04a89b881ebd706a459527e196835cbdbbf480600b9f9e49103ee959b8e4bcd6001c1faf17619858000000000000000000000000000000000880b331eb233ad98caf105c1cf0897b75e006aa78cfe5b5fbb1637594439ada00f8d1bf690b0844dd5de837548e24131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000531f33c95777ceb8cc9fd5e855a6315ea2858eb8bf670e65690bb42705e97d2a837749b1b140298400cfbf5a4384ebd0000000000000000000000000000000006fc6be9ef19afe0e92166c54d9b91f1f46fd44c25b7b03d91504b1d24b5d67f4fd13cdcf210f1001102db9b444585ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000425bc0928f9876f443319b37b10f6a57691ac8ed52d39b8507c3079f14617aa73c70b449aa5efe6ad5d770b3bd557a500000000000000000000000000000000125cdf5bbbf9dcaef25863e793460222b25429a7071925949133d7075bc04fe5116bf4a65c32b31ab0c4d3984a5d668e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005294afa3910cdc869cb86e52834f68f2aae860af51fba8a42bec7ef32769c779c22333f8e3d49df1fe9d5c355c5f821000000000000000000000000000000000f84a31b00b7d78ebc073397a11bbf1e36cb3dec9518c19a722f3ec8f9a157a572811576bbf8fa7fe68fabaa8cf309d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc03151ac5e58b24b4059aaa89e11829b0ff26b274d6449da57bfb39f77b4853953989c099e0b6bc122333af383d4260000000000000000000000000000000008672b42fc3ffdec9766100543abdc6b9506f31fce07df72428ee395593c23cafdb9ef56d868c6018ceb2c7467eac56d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144ee6b7e8f68fdf1a33ad95616b0290d04e0611ca6a833ab55f6efc173e0432e60f4fcc5b52b5d255273067c6d0384500000000000000000000000000000000009409e46420494fa3f32906e474e2b0f676ba42df9920084e7ad6b503d8e0e2f9f67a2b1cfecfc097225ff8639ecb1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003deeca036c9b337add88a5b9846c9bc6b91f587517d25d55bb08408375a76e97df82adb13aa6f6cf8218003828f1041000000000000000000000000000000000318958073d06b7a346987cb543a3bd536f5f386ab4b2d9812c8b62a71b658b55a13411d35a09176e529cefd668fbafd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187b259ed5d758e510b2969ac280b7d2747a3804ef461b6f07024f92c3322637dd5c81e0606af927c7eb453262dd9832000000000000000000000000000000000627401245469fbe10f4625a1393a92835d9e2060ba66e8e1e5dc544461110e5a1f769a2d1af7d1eeed61ed090e483781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001694b28c850869b1c7f2cb1b248504f689461d8a7921ffd62eb1f644962735e3fd4f24d423be1f1d7d8981703ca6bfff0000000000000000000000000000000013ef3c6c5083e76c1db4524dd46b7273161e0d2e24e8198e63b1a0b55900484abcef24baa25eea43ae3e80bf755f52601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc89770172cc9971cd1cbfcc0648d55aa9af0b7758180288c38f933a0d7a08855a952cf32e38c769b579195c311ae2f000000000000000000000000000000000ab30469d47c249a718e1b63beb375eaba0035c8cf2e5443156c702090ab5ec1acab7ede3565bcf5d1ba987241517da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b33e042a76e20edf7957410ebee0524bc0cee1ef544e0a005510cfd8316e5fa8e5c2858f8bfb78d9d1f2a7ff83fc8c00000000000000000000000000000000118bcfc10fa5beee740783c68dc484a16233d9baded29538fc968672510560d10869cade0429896f10059ce6611826011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b845cf04ba465565c31d4ae828625790c4eae943c46cd950d88a34c05bcc38fcd5fbf4aab38ce439d1b2bae21ba0f6f00000000000000000000000000000000171090be1a8c2f4509fbe1d91a6fd52d5673ff809ba9cfc5d01c3b0a51804f631899ec48bad485ab4d5042be19994b251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189c4a7f1d492e39cfef93a099279619f02e356dcc8d23d3e407b278c0e476d02bdc5171eaf782f8f1d7dc4ab4b73c6a000000000000000000000000000000001930a1d01ec9c737b99910b6e1c025ee3a981990998661c31d064223620f6bf13a0400d5ee04b7bf900d1dca34775a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010040d2aaf104b9d3505b564366d01bf94051627a842d506e691a893b79d26a1b9ba2d3c696484508530f062166574c9000000000000000000000000000000000441a52812993acf6b648912910d2392564f54a022f3c0aaf3bb1b9581712486b9a001672fb3ee93497b1db4b355e17f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9c1e5b9c7c619b1782bb7e75d6b8b1e431016a485b17553e06ca1058d659f39ead9e9b9d69fbd7aaa43a468f3e1ba200000000000000000000000000000000045674e0327f4227be907735af33084f84214b8ab8c18bb22bf0625aea3be731830a6ba4fa86cf619ac4c1f1bcbce4ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000197b52c35a26ab7ff14aef8473582d79b80d9abe0ddc4362928c6025c52c5ab8ac44553c832004105cdeb01a828df29f0000000000000000000000000000000014f7d1b955c56a834558ebf58604501f7a69a14005dc1271dd0dc80475d95e3225ec0ee8811035eaa0a71c2b9189b79d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8e59276c63fdb451c223905578f8bad8d424f8aa19f99597ea444d24a77fd37f092886f937b0e25dc22693b358fe850000000000000000000000000000000010556f4d80a8cd9fbd385a86e53c03e3a6cd76b8d12beff4e9f8c6f030efbc739f70460f252540a8427e8503acebf61a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001324e5dedace06232165b0176dc23a0194085c722b8dd8f5350033250aa0b266d418e45eaaf980f2e24fd58b2970741e0000000000000000000000000000000003ba47e83a0f1a2779a37939777949440c8e4a02dc31950326a1130226a32f195f612d2590d8553d79b623e94e41672b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090cddcc6bbcc16e29874cd209debef6b6ae105f0f0f1bab8613588e3ada67e686cfe77668d1ec593382506752077ef90000000000000000000000000000000010e5636ed7e901456fa81e4e21068e63407c7f07e510543a694d8a17d1945da3ba9a620f9bb98b0d35a8fbcc5f9ba9f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce0436edc3fd7295cdd7ce652039ed650a742003201bb26ab1c4c97aead5f02194e42251f42eff28962f53cd0956fea0000000000000000000000000000000018bea5b9ae44dfdb73e987bcddd6c40e8a7d24fb779c72eddb214bf9c86225af5681f4357c1a4fca89c5bd7aa0afd19e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001258b95df4e8f29c0c27b5194cf47fe5255259ec0e3a3b97b895e06c9ad4c8bd32b4543547ecee722d6f2c496e3ae206000000000000000000000000000000001897bee3143bfb78d5a7514b582c1ee923ca9ee534b408ea1076a7fafd957e3d3f1dda66406a7a3af484df707f4035351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aab742d2416c4b241c5337e20ed2f7d096c707059c41d183d249d52c40c69e1c42d08fe2022902cf8f96d02463bd86d00000000000000000000000000000000190137f2028bc83e97becdd7057ce2e05d7df460c5a7b4671db5e4f4914fcd9c25aaab50d891c88eb7e4ca72a582c45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a228d19ef65011d60a01123de1d5f1d812a94ff5f555209b21998f2ff9f74ad9bc46ca2a238c4953304adb7e88bda20000000000000000000000000000000006697bd5eec42e31f621eda979a37524bb47c69dbd434ced3fb1924014523bc40f7423d193ae3436ea064ca28a6881931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017288d0d65190656e9bf3d1adb5092d0c41e217f480ca2cf22348a8d92a602daa2fea9e33bc62bb75e874e9ece0c42370000000000000000000000000000000019783e0291416c6dd719e7c5e2d76caf8a7db47412c99f007fa399f5aa50e6685979ea29617bbe400c7ece6ee362c1d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e393e0b715eca642fe6c191083c9d44ef567888b7b89d078638715a13e33e6c287c015904995b21884de4cc1250515000000000000000000000000000000000f667afcf51858ff0983d10d04521b3e3063916fed18169b5880087e21fb8bdffa627dd0277dad5afc86f8c8dd3149be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a164c4e56854b445c68c678444aac2f40d2ca1429b6434dafb9fcfda201debfa07edd0f98f31e0bfdf3ccc7b1b66aa00000000000000000000000000000000112f0756b1d3309209b35d419e95574ca27ba45c6627a335bb212d65a33513522ffea2ee1411ddb44a25318a4881446b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da9fc4e942b288d2f5210def20ff835382ad5ba401d976c95ef455944700ae4a292e97b69c93e91537638a16cdc5f1d000000000000000000000000000000000247a1d6d3fda87c736744292b9c3f7400aa54542ab24f067036fa64831464b79caa31f3c45e97dcb14b8fc90a63b4771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c5ebb0ffb77edd6f75b3930c2a191e5c55c9a5e2e64faf95b4d2341e38c37337e445a5deaf13b878b6b2748849159a00000000000000000000000000000000154fb71d97a4c029c47fe1050d5be513c306c017f15d2c7e401a3bcde7a6776a822f5b70a8752c344202c9f695df4c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008698920049fe32475f0f1839abb13530be46fed39244d54f18669c30a9f7e1aeb2b48df2d5d12aaed16fee19e9f64720000000000000000000000000000000017754c1e7df72152d4950f1a413fae9f4a5263b5b57c61149ec1d2a8c2bd1987f4a3f9d9235cd3ae17a868bfd91266041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182a296984baa54be20ed116741945827dfca7885cc41c16cd386684b6a97508aaa1b7a482d943eb686653973beb2b7a0000000000000000000000000000000000e5b33a5c3d0333e7ace47642b71a4770697c3d5b7d7f395091b02470ee9265b16a6c10bf17a0fdad6ad0ae879ed4891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c20fea839e22e38339cb9bacc6fb4a458045fdd5da9aad6e3e888933d913c9ee548d9e3dbaa6488ec0cbd252288e856000000000000000000000000000000000f47bba6522eba23618212b2f943511a9aed565578dc216cca2bddc1a2f7372b1e4984a7122a40ed2bd19cdd7c6318081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a74acc772cf806a2716f5bf52207d8991979aa2c0cab037c190c6dc03e5bc70c9e6d6e91c33fbe7739bee721f2370d6000000000000000000000000000000000f10e3002c8dd14fbe1e87590b4d6cdcde05a76659405380998bc218137a97555c79ee446a04bd3d73110fb1253e63c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011446c5331b9f762e508f5c4cc13eabc6078b206543e9c0d74525fc042f8c52856c58ee3006b439a4947d4ad1e72b3790000000000000000000000000000000000700ae4004b9c7dae224e4278a22724c68c7b225f6e865334066dfbe5e80a38e8838ff83fe29d5b1d2db6acaf4010fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007abd52f51ce39885e25cf397d48fd79dad99d66fa40fe4ef3ace7261199b02a183af4dd5e10e17b955c2349c4d742b20000000000000000000000000000000015a412a47d4f0d5d0ca3085ab63785b135dd545e8f122beb6b0e823b6cf8f1b83b216cb8e8957379c755b1010af61c1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001041146b3d05982a533547ea7cf05f0bdb8f6f70e73820f65aa87bc2b3009a154a232b94a61f8fbd5ceba72a05f5a03b000000000000000000000000000000000c9d8346be09eab6cc8b58ed6788ad8f00307dec4a48cd59d512747714511385b930e4cdb3b8fb5040c1910c04ed11c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d2ac62debae4881207cf5c73a2582df4d7930eaa0f09e7cf295f4c7a0e2461f84eca06e9dc7eec2f70e5cbce959bf5000000000000000000000000000000001628ccde7e966d29380fda2f7d235af0e3dab97fc66eb3b50afc2fe15291608082b64700e523de33ad3dfd16f35321631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ad779e2c7ed28614dc3c4ac1574dbda71b936b6e5cc8efa5a1cc191400250c91b0d3d1248ac2ef5a24ad2afb83dfcb000000000000000000000000000000000f9dbeece954dde2dddd4cb9d0fdbf06b5e83e80d67f98a1fe00c24bb76f5138d734ef2382d44bea9155f1beb7229e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c9c42f4f2869364fecbcf655f4042a93367058526bc9790a43f302c00f75b0a59d4a35f96706fa045e90d5b52fd2730000000000000000000000000000000015f8d2c8406a816040b7676cc7736fc7e72fe2677ee755aa0002c9dcccda0648082d6625b3e072d16f79188022b3118c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1abd8aee02fbb67b01263efbf8d5bf6069545bda04868698863e00f211368c17bb5668cf4fb61903eab0e8593a780a000000000000000000000000000000000e943966559d670ec4feafc6e069190864301643b8e1b6131ee1dbdd8745855e6a11470ef62b1ba7977a0a26e02c20931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab552994f9141375b32b4df1a4f016558fd679c3adf7c7e22b38e0e099a197cf908a39f97f7fe470446286831b54c3000000000000000000000000000000000c8ab44a0f76f550a8e52cd9acca3adf5b1073c13a3a3edadb87f08f702d96f63254334e097c9ff6f7f8ec71760d57941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000406fd6ea8da815b0077d6900729694574f47118fb3a81193fdb37db5184c5aaf20a5d5cfa268d72846d8f003a99bd1000000000000000000000000000000000ec97b2a9d4cc02cc67242e36bc5b154d397749d093d4e0f22ba15a55207af63ca2a6d0cb6579dcbfb8a5f4ad10e6bc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f99298ecaabc6a46b64aa0388d94c3e243cbf575ec1ed9c13a7d99a6f7856d95233cfcb56fcb17546c3558b1934726c00000000000000000000000000000000036b9080651bead33696eb09448a619dac90acf479b0c21a5fce917b9c26552742aeef1ffd198c74dcc89a5a45ac7a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113237968a4c576cecdf9d3c636b24b48db3215286774920330f223b20dbf0a873212419b749e387d0033f2ebd0030ff00000000000000000000000000000000193e4900863772841f9b5d3e6083a784edd2c1129de7bb4ece6598039d2ade494910a4b94804d7b5a1368bc5c86ee5aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001319888749b5c4109a4edd94223623da0093bef0ac47e3a96e2c2b14947388f115acec1860173792283cdfc3a3b65e4400000000000000000000000000000000073f218d630a3aa202c92768f8bd8afe89df47c15e71aaf87fbd223961301414e35beab334f5dc31cac6b76d7caaeabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071e748a86bff323f864742355627e82adfef377d0b566437694659d2838629e5ebdf233fef455bcda8b4738e9229ebf0000000000000000000000000000000016c150499ad747441a60d85365dd95d1e942ef94479f183f798ff9beca4a396a21565b11f62bbc049d4880d435f4370a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e89b8c9e9f150d6aaf476d186ced069d28324321b86a183590182a0b8ce56a328d6a285a7223cf97a016b3fef229a1b000000000000000000000000000000000067036c193f249eadba4e9d92de2c5957ff5cf0b2e65d191cf826212fb0b81fe54bd66e552ad9c866d86fdf7e96c2ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010eb76e7052a6c926add14ba61459b51657660f6e1b7e4dc1ba27b82408238cd44eb4644f6ee949c41225f288a942ac100000000000000000000000000000000162172b68ef75a1a97ab47474a801b21d670e06648914f26a90f3a9ef863bd9d1270a3f7c7fa6ffd4a97558779becf951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182f4c58c2f332bb0a207d08c75f84ce79d76b8680ecb0f09f6f234da4a6d748520b4527ca92f7926d76b7f108a254c70000000000000000000000000000000001bf543714e255ec0f2eca033915ee1eda3890764b20c75533ceea91b46884c4a3b2aad7032845d6ce9c8f37c64ded9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160294731c3da52bc00a61084e568e488bcf1a9dbba39733679e7c1c51da560cf01e5c0311a68e47841a5cfece41a135000000000000000000000000000000001212277503175f22731860090c92f56251cd3bbe06ed8235b253459c77bdde9ed42570e01e41a065f59c6497170b8e1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019505ab021c5b3cd703f076d52aa2bac927118f9e3013ff74d2452cf003a10e963c850724ff8d1ad083bfb10d6504479000000000000000000000000000000000cf1a5fbd75abdba47feb39e7675b26541364d65f73609a5d3f36cf8fe6dfd2d8970fbea034ff5743dbf7a0bb8c4cb9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8b14f8391c7b89b425914f5c46c42b52bbde0a23f00e59ff4cdb434061d7d970e2f70692676beecd6bf96c7c4fe3140000000000000000000000000000000010bfd77b6e8e5de7fc7d6aadc8119490896c7534194c2034128073e2ce7605c4af16bc300391cd2c29b3866ec1c4f1ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c15e60a978840f07ccee65d82a0801e48f7163b48036d992ee412dffebec86f8bbf33f6fcba1f8b379cfb8120412d10000000000000000000000000000000002f821132d589f2303c90a39128608f01766e302125c5f813e8865fdb755cf572afacc3025bc691f465b34abba53993e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ad1e29b358c2a627db496d0b2acb0726ac1f31aac410517d23039c6ca73718615736a773bd6480df74293df1c962e40000000000000000000000000000000006eaf5248e177d0568b294b228112fe7ba706478dd726a43277ff7364b62247810bdbe325ae8c20b894fd59c55f74c961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000729b6c8cd2b0de947bbec4ab130ba99e39abb2b145f03a98f896d4d60628b54c5875be3c612000b3073e3205daac20000000000000000000000000000000000e1464a79febe8e2a43afb2be57efb52e75f4736035b85bf6548eb910e89ee605d830f73f46e27635df0d233e944feb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b383fc01e9376677a8caefd9bf2e5ea7defc37eb07ba49a71a524fe861030e7ef2948e72613fc63f95254dd537b0a1000000000000000000000000000000000e8ffeb60fdb72800c7ca1ec810c426f402211b4fb024cbae322dc97d4719fcced67f107d9ebc2344decefdfca7c20661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123ef984064c03b19cbb95d762af67c9d74c4c3d59f0677a5518ef864a98636ff5ca6ed02374624e11f692676829beba00000000000000000000000000000000179ac3a2e118304936748658c3a5159b6e77152da5882978ac157313592526de48057db17cb44b87c11713f6bc770f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000006b48042717697178a568f1796de736ddab8414fe53335382fc6e6690ccf67bdd5b21d3ba6940c582f17582a29918b00000000000000000000000000000000048ce9f11816f7d857fd0f6ae2f53f5004627318c928a484756f64a2b474434feffa60e7bbf5e80bc264dfef98eccbe51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013bebe0fafef376ebbf5d9ad4bc776d80be98a6a699fe533f62f6d701dcc381fd6490068456c37c217dd087bd02e5615000000000000000000000000000000000093ef6f8126bb31d1a9383d1e41fb6696a339b6386bee423ad916e6f64f1c056ac4484e340f257479c1f2311edd324a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000070e4a3e060b9dce04b771a23ba32fc0a0ddd346b16d476a16a22e3ea9069c625fb95f7b18eaa6963778c0f86ef97dbb00000000000000000000000000000000064d794f438aa7fb55760c95d3080da44baf278f4fe84c649ba2910a9df1aa3c226316d895586f8008ec70e00795f73c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a72d7c154db16f02cb2c8fdd81b0263775a68f370faae2692e7fdb8f67d3e205f7b952591845a096bbf830761dfc3560000000000000000000000000000000011e7146dd8407bc3dfcfcc752bdee0d3e0f2a91911ba365ac258a4fa2b9c147142294d8fe4700c2ac7add3e0a98386991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019af09fb0d44ec9a4444b715ae09bafb07be6fd30c9296a40d88c5590c62ca0fc6181fcc4921f7998f30aeda9f79f06c000000000000000000000000000000000ce6d2a3c377a02f4d6c509267c851fd1ba8447e448f384acaafc5582d635809f9b69fdacf60a0ac7c10e67f5a6c52a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d95a599112eea3de63db72303c5eae91631c3b5adc43ee200eb92434f378a4faec684c19f1e50da34ba11df93e1c67200000000000000000000000000000000042caef535d0942b4e4a865a22ec037829dcb22c0ba4f6b1add51ad757015373f138fad20374cbdd4caa7e67390a8fef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef26e84550832884fa6a572c6b296df12f68bf491c51f6dc7bcc9e19f64ebd02bc300a5d51556d6276fdcb6e68f623400000000000000000000000000000000155722b4772ef115fa4797a43423db26fb4e481172e480a5c437efaf74fb1f8a21da3b171fefc0c8e12cb5e340d79d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001258daeba2b2b1a55d60fa172b0178103bec58362825d7e0b86e8bf414a93bd922a28099aa8701e359b7e03e3ad1ed640000000000000000000000000000000006431bb35150ac8bb1865b07f5abb021cd5df0eb7bbbb8ee826b26c5f5bda1a90079d6d527a9b3fbfbc161520d4e93ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f225ea60fbd86040d99d2b97431c368f1a05ca81d86e9fd9b5022cfbddcc9cd1647e895ecf527dc7b5d910ea09e49a00000000000000000000000000000000015e25141219f28ddfd695773a6f8a16a0b8c3d1f33fc45aceddfb88a854d26fa68b92944e8c24ab7dec89d12240454a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca39ee0f5a37efe276e25f3c5406cc07685e9a050f83448ed0dc8288521970f723ad587cdbb4d516a16bcbccec7e3e40000000000000000000000000000000001ffc8d99ef8eae221ebe1b750886892c13e63f3eb01c4e8bc416d5e994867a6663be09b3bc91684ed6d312e18f129611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ea14cb26bd057de40513f19fc5c3f711940fa2198041e31a1607bf489981a9e23e5357b143d1855e9586f167e3262500000000000000000000000000000000191c8091add5b1fc56f8804afdfccbf9b00cff1106bc3d8efb3a9abc1137681f9d38558d9cba646ddb5f7cca72bc67d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058c19a357cd3c4abceb502099bb9b3949040ade89536a1cc6b2eacff66f32773f3da943ab2274e800a0da82cb63bcb000000000000000000000000000000000008ffa9f887459e0ca67141b6e693e9d0ec0865e8c7d0a1cc8c5c67eafe72c49438fed2727dca568a4e94a33ddd852571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d304e9c35ef0143a96a2a5baacae7779632a537187201aef6f8e3e16dcfbd99d6470022b14b6052de6f9de47a53309300000000000000000000000000000000076abe43b041633c97b34e9e0c464d876743572580cafc20599dfb20d69513ae568cf07fce25ad964c883826d27ce5db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006006cc74b97b2e34a7154e076f3ab914276f639daf5dbdf812379ff220cbec7a826011f4cf91e7b9159065ca6ea72b30000000000000000000000000000000008f58e2bab0d8762a6ba35c9db59252b8069c564d60efc7c7802253fae95a3ee45698df8669b3447d5090ed9762315031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141455a3fb08e272cca4d32a5fd86875b1a24efb0bfaddacb9e3dc4d25ddcdf99eec96da98eac10903c3867b2e5c15960000000000000000000000000000000005b987cf14e2a497ddf1cd8f8e85649e550bfd5b4f470ff3e4a345b55d06211a6b89d1f30d6fb63396a537dbe10258e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e1fa520aecd67d2e454b4d84e03095c27d7153e045a651b174a0477da0971acb62db5f22bb820d15ebc644120969840000000000000000000000000000000000ddacc8352f64f37a74edf1c7000d2c72bc98a03806ad92520b65e75553223c0d9b55103c96f5bde15d2d53ba348e201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152be34330705962bd191b148e0c80432f9405f3bd0f7d167a80b863bfdf6d6237d6529290ac8dc871169514053dff11000000000000000000000000000000001697c291b31fb317d31f903442cc0012b444df787f24604d53d1128706f1178a2d05fe727c0f03e533fe652062f40ce31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e9efdf7feedd94b6a854bde985fc0d60396cd7c342addd40331d2d7a1da202cafae5d447a4cf0dac8c22dc84b8239000000000000000000000000000000000412619988b5cfec5df02e409146650de1ec4d88f74e8a7a4421dad1ab195ab6ed0c4979dd237a65081c1bc844d57f551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa7017f3a991678cc987549d75561c3499787d13243996332dcd9cb1a8c68f99d32b4911b5ab803b9f65f7a5cf9a360000000000000000000000000000000007ce2ab399faf1e44b538149ced698698a764ac29aea52ec480b48a8b00d382a911ffaa5b40d6ce7738fde526cc683a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183d7a6314271d2909629a8fbae11c8a9497332fd0f1c5e3520c249ab6907fe369ceeed22bfe9bf489e119af67733db30000000000000000000000000000000003b92151d6d9544e76c6f6a8886614cc9be9989b80b34de25f9e3bf4ba6a0cea8aaa9f90d108be50cc3d559a48c72eee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ce57780da4d47881c7b5a8a0bfc1a2eadaf4fd25605d14a7da5dc95cc2763c2cec81b02ad2fb45fd72d4d14271b290000000000000000000000000000000015fef4a1a1862a7ce4373d64b424f876f800476ece6f95f94602364f7d555adec687f8fc73fbe5be856e4d882eae1aaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001931f8a633c979f1ee003bd6e08acd890842b8bf4151afcf5250453772ed3de9fab58c10249ed7f00c00dcb17f421d00000000000000000000000000000000006f443c7f712f99b934a00648cad0d736ba642cecc147b245df90bb2232b535da55dea0b9ef75b64fd35b267fac1324e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019773aa35bf37396435a4f4ce0d81184314bed7d262ff85255999199bb797a1e2475301aaec7dcd8569b7fe12ff109e80000000000000000000000000000000003b95396fcf4c374e2eb8e00c7ac5cb91dd20c0ad8627bd5414bc2021cea4d7d47ea592c7f0c54cef0cb5bc1584b25191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe329c53d8ad8dd8afa8bccc63838b2c719909fa9926c3f57c4b5474b77e16b6b61cb4b30a39b875d76a6f2d00eabe0000000000000000000000000000000005a756cfec97615b844a491646c542d9bc9453de1290e8169865fd87dbba3e46e9ede7e56de643ec263c95cd2883b2941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea7182034f6dd06a2d767efb0b978fcbe51117eda9eb0ea2576eaa3dd98b56161352b7984e3b4eec1d94dafc9ccd0b0000000000000000000000000000000012f3d4b1b196758bde5103cb54d084e2ef6e335f2104307aa4c523bf6f9244e9744245847ad5280e138fd44d36f24b801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170127a26e684d9c343110786c22f6de7477cd42a8851ad6dbc00be4fb9259ed97877ff5717e2f1605d8553cb1da2aa30000000000000000000000000000000003b1c7add0964bdaaad8981871ddf74682d32d77ee0e6512d99acb522e4e9dfbc0ddd3c8bc0dcc63ca5feafcf35cfb211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f757178a65905c64f45ce6cdb8fac2fa4fce1af485d0b2982d6681d33bc9203149ea0e2138636af2e09da8aec69eb0000000000000000000000000000000016372c1964a4ae6e8e22800838c50328fe76c223d3a7013bf55b154a89c8565c0487670ad8d1cc6e06e0b20b0edb53901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161df9d10203f549071b175c0be1a98892478e48eba1c7d65cc471bb28d9ba08b1d93949cb66cb68000ffd16202e74a30000000000000000000000000000000016d58c2cd8544b773bc27e0aa96dd0ca06d2aca9e8f5518007df5cc6d8f91e6433253ab6a84e154d2ee333a6aabb931b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e8078d8b90bab73aca86ad76ad90a11a2707cce2a46148183db7042b8bc307848754acbbe9df379c63defa912b588f0000000000000000000000000000000009d693e5202e28c1e619d30078a7b9066450c88c207d34c2aaec282509a240a7a73b75165e5ee12b60cfb2a557def3621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae00881c2876950e34614a7e8bdd9bdfce88c16f877e98feadfe2929b49046d1bb9ed05a43a11906d749ee0cbf8a70a000000000000000000000000000000000d499b4dd5c0bf2f6718a7a1fca08958f25873c48b20238b2fee93f907d6e698cbfa24df0d59cb0a88435002f2bc30c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a9cd6572d0740326b2fd0891a47e2bdfd095e7ea0f26f26d626e9574c6e8c67ca0b62414e440e12becd8f0cf924370000000000000000000000000000000010388d4dbacc00265b4821279d2fae1be530ff75e3614b7d42a46efe2264ab034c4ded09888d1b8c750820ac581392281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ee34f4a2cac2171bab347bc78e837f5852660ea30b372b0a670e85d815e30af7ccdd1ac6110443e84ca8fd82a3ee380000000000000000000000000000000013a61ccaa13a8cd1f1e43e570326656707f4ea854d68e9e77062d7fa2c24cb257f3173837f6260429dc1d8970307df161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011320e22478aa33daf67f60f7ee94a1b9fecb8fa6cef70c40828d140692a30b0d07a03ad9bbfc2ba1e5f6c33022fc8520000000000000000000000000000000010ba3c4bbafa276d1434f1ebfe0b2541a93cf533dc2400be649a63a844df637bb8f6a52185c6becb3dac2276d7d659801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009afcec9996b8df61f0a6bd28573f1ed2f1e7881214484ca80b91b43b2a369b6d6a397ee1904554c32cf918a458eee7b00000000000000000000000000000000016ad065224ef9585138917e75cd13e32c2ed74279285c6fe95dd49c02cc7b6cb8347a648907e01d429c1a5b31a45b091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000043b49d7424947ce54335f9b0dc78bc5e492dab7104057e7a9f80097bdf5234a6e6c0921d7a6c500e7b84872c2da7b5000000000000000000000000000000000b45c1395e0e62f88875fe6b63384778dccb0f978d81988da473f388d7db89d79622a70d07426c1ec523206ef1cec60d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a63333de9b4f3516a06b9808fd43ded774dd8d261bc0814ba4970cc994082b97602cc7e9eb1ee651a4f6d509b7e77d0000000000000000000000000000000000c86f7645b8905791505220dc1e4a3d6116c39c1a29bf2d9e41d7acde74c795caa5605a70abc28016c0c0d7bfffd91d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5df07978f05f73f53109aab6434e994acf680debe43d530aeda7e3648054e7556ff018075eea36a2e7ca33a586e21700000000000000000000000000000000049d70eac478f1a649a2b30cbfbf59ac685c6732c8ff694e97a451582186867e2062482a504c693b1044330bb0a12fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7c523ae2e879032e992f47f7b955f3b0c5aa83458dc16967921d77cd6b1725e0f433cafdc10d8d84fdd2872e8d5e73000000000000000000000000000000000384746ca5b42157faa5aadf86c403b181720b6119b1abcec51ae58fb868b9c17e87cd9e6388980c030f0db9c49079451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136d56e5dc87be3f279521f248cc2bd04f2525b64ae4a1dfc77c49fec5260537d542bc821f70f636d05808bf5260651e000000000000000000000000000000000f1cfd5cb2f0e05559fa4c3ec2ae2bf55a36a88df5aa0ee5191ffe4c8deddcf6cf21f76183c64f474b1c7808460006731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000561b137ccd91fbbe137ec2d46798438b77bc8371833e4f4053812eca9bdd67dc0cd9c7bb8bf1f42a9325e83f24b233f000000000000000000000000000000000b70d988aaf182b51de00bd801e11c68f4713f48fa3002a94b5539b100b0777c2e8e2e354bab037b8577f308a7e02e7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df13768e7007ed48ee40ac965d6b223a0c15a148c2e881624b4b726cb9cb8e149ef50a2aa976d628f30121799be24cb0000000000000000000000000000000015148a4bb01170654003ceaa66cd02f8ad0350697950e3042b3ea972ab455d1491a11bc7779f703a7452f62d5bad5c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033ad90e36da5b9f49e3d106ffd6c5a3e701a842dc418e84c907a42ba2343ec17998feacb2182efb9ed3c0e5dcbe98e9000000000000000000000000000000000163dd1c83f135500d39a65084c33de072302ed5ecc3f3b8bfe1b74176c420e12d65e13d1628fcadf5153c43348a3fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001757b8dcfe3fe33fb5ad643a897fad178571261f59406aed1ebd20f8b0a45b7f2f3b7c8665b545b57baccc243b32897400000000000000000000000000000000105e9f23cb556d10a3ce13f1720b30c9dc33721e6d8f5e8839a766a9d6c8dedd45d56f46768135ef563d950efbcca2091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006c093d5b6872625e4fc22d9b4589953d4638c6b3870b837ee0c2ed4cad7be0045b2e18506cd30ae6b34fd584654429000000000000000000000000000000000f3497b9ba244a3fe372136ab6fad41d337e9dc4c0a4bf26c9f92d5142ef4e4ba3f824633cf1b16e50d38ce35fc606721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c919abca00a292a3c1746752b499ad5ebfb237f35b57a93f207bdaab67681adf2fd677b5207d726a010cd35e5900434000000000000000000000000000000000fc10e64eddb2e2337553e7f3d6775387d9ece87be5fabb9549e9a4e5a5020e4fa3403cb8796cd099164dbe3b09fdc8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7ca8e9547e391925640ba8a2578c3734d1c3765e5170e5cc88fd57f0f7807acfbb866d744de6dd2bce248f9efb9787000000000000000000000000000000001658ab1c819b8da1ce6fac6724048dcf95b39b75a8fe8a85fe9fe34d270b044a5d8f336faff4cc1df5511a837d654df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026f29e0e9842bf7acc07cc9874d391f4066ec6e04ae9904b4afa988cdc22dc386b23b174e5bf34c6f7d11258bc36a020000000000000000000000000000000009c2ab1ccea3a4daaad1ea137cd0292e35ba01316cdfd5e5ae9629199583be468d541f159491baa927ba78eb2be8f2871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d2dc038fb9f583463721b774461de2c6a0cd05971830acc3e1da538d4919b5e7a09a526c21f7f0b37aad31ece17ee900000000000000000000000000000000132728b7fbdd7a712c3ecfade91f6df1cf75240a63fe230241a73ebde95d3e7d9b68be1d46f9f2d1e7c92c53fe28d71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028f4454baa657c7eefa24ebb91e641ebd6864bd1508482508ef56b969af18db6e862a1bdb188afbb4234de723bbc79e00000000000000000000000000000000199adf6786f8a5c51bc76bfc07fc0ec3ce436204a8133e2be0e4fb12fe00a76c71f1549e07e52e5e945b3ecbff2e25a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed0491b310c5b167d6887df742c1e4b7287f7213a2ab334003d7613d2bed5bcacaee5d9bca9bb2db7bcd62caf016f390000000000000000000000000000000013ee7eae92a74231014facabef7969d13753daab7e489ef382a670c39525b57270b0eae1752fd9a5ecf17a2e8f1702b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044b3b5a2330bc5ce041d9bde4bc448bcec0fd107d91fe12ceba81b3e8ca5c6ebd0b9841e5c206c9739cf77d87827e1b000000000000000000000000000000000bf8eb8b6b41282ae73eb630c70026632e36da0aa2da359503ede5a8d3a39dbcb57f16ea33366bdb3b2b6713ddf126231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019714ff8ea48419e676ec5e37655298850723a9c42292ccd0c10092d49afe3754c0d5a631fbdc6b86385de7f8caa5c6f000000000000000000000000000000000b1ba5bda8116d21c650b85c0fe2fa8784bb9a95d39966635b5ba3f65027bd95b58f47498db8ecd7ed2728af54086b911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017198e31ba05ba0955179f0ed84e927dc1a0388678ed247d74477ed058e4dcb7afe5941b5e3714865d004a825026f79d0000000000000000000000000000000006f084446a3f465371490ebadc33354003072876eaa2976482690ecb368d93e2523e5bbc6caca9559188095e7c54f77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000118216bfe9d69caa6bdb276e1cf8d13649477ab2877cea5f18dcb76a0a0e82376d790850cf2f02910d60758ee8b9eb0000000000000000000000000000000002e24c4173d94fbb041f56c58a28f049f7da9568bc41807ab9e7522e91765dd5d30162743d1cc53ebc6635f5511c8c631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000889bc3495d60010b9a8fc354fc0970f7adcf532bb0c7ad1e8cbbe95db11776527f71ce7b1ee3076afe230d8a5f1db7a000000000000000000000000000000000141a834b8d213f432b2d2e749a5230dff9f3945116773c6c4364230a33546490cf2ef003dbc0e3cef5b76957a99aeff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c44ed292267982a027ceb35343f56d171829cd6876d47c36292c3c21528cfdfe02b4d5502780a3aefa3b6c71656252200000000000000000000000000000000186e3190007a65acd2f60b500f0d68d039499648428cbab8cf68d65fa7dfd160917e45fe977e40acb38f0cccdda47a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c46425e2dc1408339e8be6c5bb925582a1d8eae0e0b844e19ee726f34ff89babdc03f9caa03e53945c6cad5b7d8b5b70000000000000000000000000000000011fcbeaa262c97e42a02ae70f34192e7f53890cab4d859c02bda8e6b0fc85410e6b51e66c32564a453f409c3215ba1161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3f9cf96b897b69645a6ff34c42ec84e534143c43fce8aab5f2e74d70c611527d5fde7563306f8ec32d6c8ac789695a0000000000000000000000000000000004ac3f3a60547e3bcd505cb1856a8fc4c4725956f3bbd48d72e57df4b81fae61d7c11b7dd7f257adb2da8859b3e255611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f266a8391aa2f49a9680e3bb0224e769234d7a87d6d162004ceca7daf535d7e7393de2d86abbdd246846aca655c804000000000000000000000000000000000b99d33d33625dc13658aac232707ccd4d77c3fc2d142ad086c457eeafc61a75e28d24cac0ae702d4300e642dd5e3de71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdabf76eb0304999f97d2f9743504805f52d85381671cff259d768541ab9fce4a7460edb676bdcee84a1e5211dc6b0600000000000000000000000000000000145e4e2ea28a96cae223e000689841c04ff61e2899be2a3083fd4f1a247518e339e2a29cde0c865230754685a89c99801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000335598e6de809239a3e3fbe246d85d43f0c77f4d096d3399ef357c6116267d4e288f6885198f99ade0fdc4d25b0123f00000000000000000000000000000000057ca0ffcd52fda082aede02eb349cbd29bcd3ca4bf64521ff304d2f8507eb9da2165837b3ecb1124a55c31bfbf1df8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000152fe92cde534180194e10625c50a6fd41818d552ea722482d8775d003ddadfc37a7d549ec13f27bd28e2c1c061e9e20000000000000000000000000000000011d8007a4596991f21da83360fe441c4ae0ba4a13be87ae3cce6a00f83ea5fc83d8b60a6da1c64368da152aa767a81b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a5ef269bae013d5eb2646331bbda3c7d64f87ca7a8e4a3c71c802b1205b4f90ae582a3190cd72ae2661b9b38b6dd36000000000000000000000000000000001357f64debc1db223c416d91244c6adc8a0d0a0417027e751766f49a5368a943442d175d166a49805f1532fa1bc706151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001410d1753c8b8663b5cd8b7d1f9026d7e295f4c4b84a217588020566fe3bebe6f131d59ce873c50636cec97aa08fb6f1000000000000000000000000000000000c916f1ce545240b29e7671d938afaa0623a5d391cc4cac1d3a6a9e89320fee2c06dca26722556de8245e371474a386a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017daab196928228e11be0e97a14ea16833b59577084e83083c67d35febbb991291dd2d79259765d5b3a333473fe46860000000000000000000000000000000000a212710c38488eb738c60dc348d91f0bd915fff12244d642623c8b82705559a0bfb4857cc531b4f0d34f4f7ffe2205c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152ebd9e53c4a33e227e24258f43c56012a4d417f8f38a94284eaa77111022d9166d5b3bab01e84764c7a5db4f06bc190000000000000000000000000000000011d1ffcb92b1113d0e2491c90bdf1d6aaff7d766e3715761cdf74e5473ee9a75c9cbc68eca9b4dd683a83e3b1905b0f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d9cb67f1cc7e715ea0b28d2265fac08bf11fc8392ee31e4da3c00345ad606e8a152449a7d78fd8de8ed3ce2b6d9501000000000000000000000000000000000e37a9964f12d39f97adef0aef96a29556c23b46677ec1f5e768d4295416f7d1c9aecc5960aa050aee43e222abb026d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b1352ef2eb97d9603bd16a085729fd19a7342c166385f58f4cc8b45befa4dd6b346ca6f115176d5201b6ec67704cf0000000000000000000000000000000004e8457d96c8ada2ed170287cf0369ebb4e3b427bc8b4fb5d248c6b16590a62f421a1151c5c24e640acb02760995eaca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c0d9b7acb2d2941b03fca37a6db8137779538de42da7ff1b0bb29ab373d799e8a4d0f6f85622c0835e07b44e648570000000000000000000000000000000018943169a3337eb3e17690fbb58f7f03031da7d437c629310798c38ef1ac09b2c7c86723fd6315641b52c56c2772611b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002185205b4e0a5d0ff016ac32f1aaa141c224efc5ccbda4544f876dffd681dcdf5026a98ec0acbfc539a5542f558693d000000000000000000000000000000000df52b572a572bdb7888f163482454bbca4c711b328b09672375c48d1cfd34475241413c7d2aa0bcef01a35f7024909e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014921516356f557de72927adb19e226268ddddd9a3b234e1953c3e971e75a90db1a4f8f494f225c6fca7265f9c39181200000000000000000000000000000000188fa4c53a8180236b03d0c766358c27105c3fe1c35024a148ee38707724525c14500ac3b9c3cec8afd3ef3225e693031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbe31f82cdc0eac6de1da92a701047b2dbca2961894ec2cb1c4fc8503f318503a522da774c0a759b8f351fdbba517f70000000000000000000000000000000004bc09c4722e27bafc4b6c52b1d69da15d743b18cb8b5f534e253d14972098cf2142608a72b24bb54abf1426888f326c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128d181753dc5fd329e134f92d73720cae1b77305e4f606a8745f9725f16419d9ecbbfb41c816dc54642ca22f524e0440000000000000000000000000000000005fd12cf2df76f5d642bfe072a6cc338d487f3cab7a71f48599101f07d88acf75bbd3c7f3b996cee0f846961093180171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001566b2ea74b915470db0838faf0b3a8bffa28f2516d879a9776409ecb08542886a730e0a0c1c5938a47ad801500a5a48000000000000000000000000000000000fc64c55040bd9ddcd29d667dee740ff37687fd19d094c6c3c161b5d09553196be860243252d0e3692ed15d49d7286701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110e8745b034480a52d7b8ee8fa9441a26db2c9e26c3c1484a0c93a210d0831013b17974675495f5f23479d67bfbe7fc0000000000000000000000000000000013ea82cd790ace5a9bed8db0a38a6293e135897af476dcb45c6a36e84b1c5ed798e19d5aa3a86f1b145c3dbc82c5b5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009566f133cd348594c0a9abed3329aeb63b1f8fe7f3e345b560dda9ff87401b7db0e2c899b9cb6a261e353336deee38c00000000000000000000000000000000174445b067086b350606d09667eb3fc01a797c75b7af82ab1a1141f0109c787d617389b3beb0bb0cf942579c916eb9281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c8a975fb1fdeb2144954d0b711d9561e61de9777977289f34de9624da41ec7d49a69bcd1b5f24f0aec772a8dfc074e00000000000000000000000000000000075e868f8174da59d14b4e01b75428b341b1ad395ebd62f49b1c20fb4eb0ec4a126a21a11ca6a0c0f817b266cf039b291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000155583d24296ce8e16599cb6696cb8e8480e217fcdc750234a9e37ed54548c5bff99740a32c760c9887a5c0161ba0c66000000000000000000000000000000000a71c2219452948095b2edcf10308f3e4616b9eb89194af9424c88eb433944b18649d8310a7e365d7bacc2ed253534111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7a219a1f36ec671bf6d969550e1ebb7b5c32494cef503b4fb84e5fe117aea4b5819587b49cef9417e7a4ff55d5e06200000000000000000000000000000000155a169b7812b7d3ae26566ea73e7690d2530e7ad7b086c8d7573a6df73b7eb56457397d697062a44606ba3e0357f6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012789cdeba88c60e81d3d448c3d86fb9a64508e3ea147dedc3df258af03e78cc9b22f57acb3d4bc4662a2cb8ede5792500000000000000000000000000000000041459e0c31b598c9206609437b0604461f48819a0b5219f28a634526c68f2c7f47494fe6a42fc12508ec4a12b83288c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88b970a0be332acfd3413849b44682a72daa7a2d993b21b1c8f8dd5859373a9588eb3702a0e650d14f3628c9f96a92000000000000000000000000000000000716490c0b58297262c7240bf01f7dcd70d94d722a722cefcd0fcea35bd4e40f9779754d5e486360ccd2529dc62b321d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000056dd8a7d7433eb39c25bf04c068ff584b09435db11f13659015121df64e4e128f54a3c5f154c15e11bc35af63d7d99000000000000000000000000000000001608017375368b6a2804a04312193121cfc19475abbffd86d8b5de414990d75212432d87b4cd17114c5fb89db1c48a951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbbec2c7621e6a358db5098505779c151d38526fc1ea37bbbd5d69fd007c3e00b669c3b5e98b671964c2f7d090b50800000000000000000000000000000000102ac134e1d4b5ffae4b567faddc05b76f37f09540062c308dab9e800e866195da765939b692c7e1538a47eb6390bc531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8f059b1d13872af5e6776982303e9112f97d35504cd07fea30bd2f3a624edb141224bc30df4aeac1537e680b86a254000000000000000000000000000000000c86505accc2f238ab91e7feeee74ccfeb2fee97cbb72957435d3c144da91943e687ba43988def1d47aa8b7c295f184d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8d8d3ece2d81e11be7329e46ea435a3882013fb4fe3749f768ed1c07d7f221168ae1ed648c04fa7e26c324405f4a4000000000000000000000000000000000066daf851d334552367936ff9440d3032e8168b88dc7c115d6eab5640dea2ae8fb006369649b2ac644b18d9a338c8c971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae9b5ba6a29b120ddf30d54cde457643d8784845d1100419508b148f293af5ad3f5ef1f8e55741db0fa02c5a7b6d1b00000000000000000000000000000000169768ea58e3a9707e4a1d3d4e0ded5d546fd8f2bde67f784989ad28544f43673ccbf6f525780c42f14c902a0c0840341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2de02758c77c2d166ae87fd16e63f236a962c44bdd3a7e22a21b0b04edd9be28425d9f6277db7c968e50a3472922de00000000000000000000000000000000052d053b346b9da3789fdfbf34399924efe51b56e38ef1ad586d95be2821f6e379e3cf7852a8ffff7cf3f8de58f481541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7ff71a8e3425109398a24da639a7dcbdc1e71577e70d365450b70de83dcf85c7e9a0d85709d162f0e128c645927992000000000000000000000000000000000614acc3718e72bc66a05d82ac95ea075ec41d221f96c048c14a9014bfe42a45a69c6700008642cb7483d4f244d509ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001078b6b35e49e611bf9d67b968e3a6c28cd3e7e1b59a8b0ec46ddbe5cfb9d5a8809a6dc01bc73650c4aca69f76b910790000000000000000000000000000000017664b3a857e7a29e33425ab6ec98a266afc55ab651a16b28dab1a06efae658324a3e5b102ce88d626a9852aa9885a811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014a2f92f7894885341325ac05e41077bdbf2e28630321a12114a51e0c14b60a0fcabd1c75b9e046371b3ef78063f4890000000000000000000000000000000011b6869aaac4888746fb0dacecab0a1aec4d8bfa27703eedb42eb0e84713dd1b45f12c7e7234ef0c2f6366ccc25ab4ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f97a6aa9011f26167b9c62a1e626c7b334b7ebb28d1269dc669aa7a01c5868dd0eef9ac7a3e3cd36f7cb1e68a11dc4000000000000000000000000000000000098163530c5a14a9bbb7e1b321b1a472a6952d460641b0e4e8eb3c0cb67ef11254cf1683f317fd96e6ffefd3d05a122b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062a8771b779aeb35057cfea02bb02078c24ecf57e095674264bc57ddf5c69c731a13bd42f9aab01b9a3f4444f42c15900000000000000000000000000000000003191d8978a08c7cc46d0bb30078aad0438c62f595b5fa7faa1616854043ad860bf60f3e936c2b33088242db480c7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000080473c94c5f01c89e45e5f335dde2513667bdc475a96699e5e3800e4995260f19b0a6b6a2c8b704091245124c2c32a0000000000000000000000000000000016967f726ca770c1afd2f5fa142957ccef96e142684dfd661cb6be0b44db2a52ebdae7d56fb43f8a2c5d7d856a01af951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000082ff99ceff379ff8218af0c2a50175bf45f6dfff618c0de6d06ad81d3ddc0b87f0074592fc263e78ee570f5e76f66700000000000000000000000000000000040cc1ac3d5ee27983cc0ba8e6e7bc2a4af78bac4ec59e0103d677e2dc5a9d0ec35d996ee52f6cb7c8100fec1ea8aefd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000337b69c3ed88acffe0d4fc6287cdf25b31eee50a284c25801354556b1c478704faffe5301c86e3b59395036ca0365990000000000000000000000000000000004bad0dc614d3edf3b34f9fd5215ca88df311d4d5d2b76626f18c215700e93a3f8621ebda433388ec508199383f85a591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cee1a85aff0965a37452f3ed6cc3ee694206d90eb4ad4ca6f859e3a81a8d3eb90114945b18ebe953c25f775d399430c0000000000000000000000000000000008486a2d7cbb646191340bc1a0e470730c6b8368b189ae15e4488e0c7f5ac6bd647a3376c1084f577140f58e51d5d4291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171082ef74fa2a6effcb9bb5ebcaa443a67d669b54ac92490da7cf3b64b8ef97a11cfb3c4f3e0dc76674e2fb4d40f823000000000000000000000000000000000d80e304fc75a29dbb2e4034c77349a8bebefbc5e74b9f73e841ff0d295974c0b6b8648e25c92429f90813a8ab5c71971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005240b23a7da074d3b0f61267c765cfd30cbd8bf9cb8628236c01ddb3ca80032d9bee8a39ba8e960de46fd4202bb908d0000000000000000000000000000000007876ef35263fb808d6a5528ada90e67feb9ae28bc55a15f9bb3c705fa88b1bc5767a843f6edaf42d8ca790b12ae0cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113e305afc8685dfd679162cfaa94dd49a5bc79dd366724557a49562d9dc02a0cdf838c9f9ccf86330ac014f006f2d7f0000000000000000000000000000000018cb65427d9da03fbf16b87a9585f1c24c83e267e9bb8baabeb092b227ad65b8dbdafd45ccda7751839cbc124980cb431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c2353b8f363e0778a24e4bc60f132b3dc29775ea22bd774e59bc53615413092294ed7e91fa96b92dafddf08cbdc109000000000000000000000000000000000a7a0594bdaf9bc585f61ebc0288f56e539aa5bb3c9f249cc92c2e887541de8f5b5f381c1ce0c7105fc000fb52ae058f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f69279de331740395617d79d9a783bc607f57eb001cb9b28c95d6272c125310c8b638e719f9ff1aa4a06966cf72d030000000000000000000000000000000005d01439809bd20fe32f4c9c643895ef0362371ddeb99bf9ddcffe1beccca3ced30cd56d41c455f88626048870a61bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001560cf987021816fb2ec10176288624df8e7c3e8656ef06d7b839519029b56cbe0e79210b3491185fbf2e869730efbd10000000000000000000000000000000018631a919fb1254c57f34a74e7b5a8cb2288c7947e91b27c5c6536042048726c45f3a6679e4bfd4f412def2bddb5be341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000849db4da34e073c43cfaf978c5bf2a56199f0caebb2a304e0b6c7f0b5d3123db6f4685be03ffd0f8db6789a18239d3a00000000000000000000000000000000127458acddfb814c7fa57cbc0f7ada750e1093f25bca8b3d830cbb907a2cf00779b243b1d30570f963e8b24a46d7078b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009607dfd042c18ec26e5c6bf7c506997b1859165ebdeb8eba08538085741f036737ddbc2d50e1ff23fb15e3cf91934a60000000000000000000000000000000001ec90855f70d3a1d6a6f4e8a1028077b2994bb3ec2fefe3de2e3ca7e33f2a350a19938c7fdb530d5cda1095fd604fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c698ed33d7289338eafed25384cc9c768b4ef066b4fbe92b12bbad8f06a1a6606b8f1ae60f9462ecacac4c84f25480000000000000000000000000000000015fb02bc533b400ff46fea525dbfd3fd4e6d5ff608c72a7b4348b9f99f0cbce400915ff44c5d510837dc4a97a00e8b721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d69285b9e37ac5aa391d85c94d50e72abdc10b68844b9a4573454fdf40989b46d6383c50dea4a9a57984bed006b176000000000000000000000000000000000036470ca82ab901ca4f54c59ce302faadf6dcb49bff77a2ffc9ff9d7205834740572b4ab3672f48e5df5172603640b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067b7a1ef278c826a51a8824235a84078696b00f01273794c19615352302499aed92170d6a94c24dc6967bd9b707cffd0000000000000000000000000000000004e83ac897c5b86ea230614856289639deeebd7f010129d5e898c717a5321bd11d37c39131f43b3913a551453c50de971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf14f770a90fd8ed99556e70c75444b263855964634cd851366ef047596ed6af6765a4811914e6f69a04086384a6b86000000000000000000000000000000000444f3c9d3727c521925ecd94ba88c06371e19e59a868a9611581bc37be2c551cc11882d4737a6723951023aae4bf8c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2958ac971525e879ce4a2ebd5791cc58a0fef2335b70384623eb19554bc7ae4aee87e2e2d82b9dd073fb8a0f6de15e00000000000000000000000000000000174dfa1e2747e7834e394c40a664c9fd15e6f786e0b44374685130e0d26ddba584a798cccf9aac94689bae80ee85d71c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942f157cf7a5f17eb6b47ea6e534aa4d9d67d546712175f041d2700374192c75136a8ffa43dcf92fd54949a43f30f91000000000000000000000000000000000e03f7a655a397d3958f6655b3b2583296c1ccde6985f609a2a39390a01a19361df6806dc62638ed8547b754c8f544b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a80aed87190677e0e254f43bb045a2dc0bd61fc2ae0bab297fe5022380b275bfcf4d184fda535b87c10d38d27919b3c0000000000000000000000000000000005ddc57a3f38272126b7352866205949c945d45a6d2bcbf1238a30adad685f4c237cc6a944a77a3aa7f1114dee7c96f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000061cc90208a4daa72b55b1c75b4c1dc8f5cf8405f2cb3c6806c96be4564c781fc14c7d848053349787aa2e359a088920000000000000000000000000000000011e89e8d6b4a71b1655bc19fb5f672f04d3a8404b832c2fb8eb33d6788131832bb5be36a968f40c876deb9250db4b1451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001343cdbf82fb20ebe1be27a2cad67d9afba969cd9d4b192c40317de31906bf88861e16465555ae3822b9efffb449a13a0000000000000000000000000000000013d3d4c6ed6eacd34359cfd5ba7528bed76c2e39908063d4e14019c480701e1e81fc3a16441a2376ab639dd65be968f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005281e7d161fe5aac808165d5babc54a1fab2fcde7155e55ec48f341e4cf540a8b3a4045e11ef7554b867725c738dcc8000000000000000000000000000000000b1007db13af00588f5425dc5f6e8ed28579fa0d7e34b9bd9f3cf1fcec5254d0441a48e0de963f79c14f03e6e1a9b3f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b38f227434fcfa66532c445c577f0ef1bd713e16850713b89dc5e884e2c3b22b45ec4d867420ca84539af7b0c66df5000000000000000000000000000000000abf2a4f10097f11573a665e6e9a6b8a4619abd489f887f857f57abd4dc0e9913b3c10694dd34994955e45984c60670c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd85beb6c67837ef0dd6b9c1440b71b237574954323fc6a853d4332411f97abe6734276367f751a5afbbad694d7fe7000000000000000000000000000000000deaf17dff82f4b57331498a9fde46b8a5721ac130907aaf4ff5531576a559581c22e0b2317018972ab2422a7a4fb3b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001336226c03b6a8c33d245ef3396a9310ea244888ba9516f7780e29c44a4239cd592a49b9a9851441b11414692185932e000000000000000000000000000000000214093f5c3686d49510ede32f30c1b183ff9e8135fcf295ae1ab44d23fbbc941317db24231ed37965de57fcb72a19391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001177b6893af5e2f697ed6c970269bdd78d8670c76a16c32b25bbfbc56c8228c1ddac2b57fbbf59067703a09d20637077000000000000000000000000000000000e375268e3956dbb16960585ca737c586b8edaba3c194e05e876a7ac0e85250b03389bf7b9fa932e38dfa0d96d2044d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136983a79b451e57aba1533f95b5392e48942cc696b76a338444c0991944eb20b5e04d97e24babe6c714070612306fe90000000000000000000000000000000015f3fa8aedddd131109ca9cd75e82b85cae51d27ad1361921b31e306874cb42a82ca96081e6aa22c47c88667ec60f4f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008681967968f9ecb524eae7b08d0cbf0cbc8bb1b15a3b6603f19ffa6cc406ec0797965fc71d444861e5c5823971f6dc60000000000000000000000000000000013be555d447640982fe2ba6d70426ca6970f052f4ff7214b17f1cebb6233678c2cf0e1bd5f97aafa314006eb3d1869241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7eed07e01a1d8f694c4047e533fa416e6e1fd3595ef0d9d8a971a4d41feb0c0a5f4496906d0c9731f3fa6bf4e552f200000000000000000000000000000000099e0aec238a9eddd69171a1b900bbbefff18505b6c99cab64880a811ece9a2e40e218e73add7a896dfae42dda5c79271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157b503b62e94514e63a42e116d4d18c56641d5b4868950355e0ceb23986bc819d3cf8131a7e78b758b108044021ceea000000000000000000000000000000000d72bbdf710c951aa5ccb5964921402ea2af032785526d4d3811421569fd68bbd847b1e543eb46ef8079939373690eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a194a6a568954535675831a5abb985b26d43a95d0b402e08d606da7c1839a10f7df47c17068091959a40472530661d00000000000000000000000000000000003aee80180f519878e5497ba710aae527c95f5cb5fcd397a0583945fe7003c32020386b8d375433951ef7e0f02d7a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002faf84e2bf58f36955eb8021490b3afe993a1651f47b3865577030a6cfcfe77e6e22468747c0f9aa274a97bafe1026f00000000000000000000000000000000036c77fd13205abc7907de3c3bb096f19e4933edf2dfdf03c87e49b31aafe37f915becfbc53df5fd7ee43016a8e59f081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f973acd8925102d61d27aa26e2191ad34fa9365b36bc756a6cfab46accb37f8528263af2d235b2254a62c2c852024b90000000000000000000000000000000000fdef8b926f0b4376b305edfc3e1c6176b7b942b6f9b7859b4b8b071b8dc12a116504b5508c713041aaf95565fa9f011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1dd72e764616adbadd27a35331cb3d50ee56f09563eca95f7f1e5bfe571a2c27734382bf59eae798ce99cd20dda37500000000000000000000000000000000035c82ce3404e583e429e7d4cc67b60dcb2f5174874bb03de494c2d85034e31cef6ee7c4f4f93578ef26066d55b59d5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a56b814a5134019ac170b1f663fa3b6cf873e6171a716812d8d4ac26394b3b7cf2044d3416fe26d90046641a7724b00000000000000000000000000000000015cadc0765eaae272a27ea04d87f50463f18028bda6d83ae771756629341e3e10777c2e94b7bd73bdf9a34d25be49741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae75cf8041401512a35b2e991a98eb47eed7ab28c134b9871b5615a0e70824f0bb2c67ab75a082daaea5e9d1467a8f50000000000000000000000000000000004ae012fea8d12a543d725ff6bafd691eda13e1bfd9427ce3378e0c8c788520ec3cc09bb09477042b588064421c1f3501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073a5793217ec05210192719727737b7d8bee515c7ae7c9756e7988621536edb842570e3eb50c1b80d29e34e0db185cc0000000000000000000000000000000015b36a284108630704823cb7454cde11b93fb15bd5783722b24a0849d8e9f29079cad878c9b8aacd1e0de58e4f8f1eae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b02da9402e60d499e9c9f99398513c9021bc8d57b218586712983a97f1552fce0087bca68a713d6e8f6caf2086793000000000000000000000000000000000164f63ce74c0873c30628a9199063e9b0013a934769d54e32c108db1a0211a29ab393df313fa276cafd6ae460e7da3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dfbe8dfd661a89cf924281ffd1933ebb0e91298a95237a2826351c64c5c4fd379333c1dac0ff505212d7cd7c0f5bf00000000000000000000000000000000057dc28ee5eb6e873f63d99379ea6f93453053006ba5b27cc8fab163fff0beea8f4df0b1a9507a277438842e2cf782f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b6768a88e06e9908ba018fb0a2c3969c4c0b3c6c4d8fa53f5bdc8a8d65fed81c085c70b7b224f742d29a61f023cdb2000000000000000000000000000000000652154adca56de5084d0214e30452a0b8b778cf9043ea3852fbf2f16c5c4f2e72fc80adb7fe4eb431771d6e4fbd67ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca861086ff289d51ece5acf15385ad86c97ad01c90a5c7b560c0b1bc462101bcaf2ce5f70b23528d2643c3d4e81262b0000000000000000000000000000000016df41edefc6aa54948c26bf6318e4cc724066a0ce97d749cacedc69916fd42e6bfa081bee18852d4f1d82cee91569781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381988da7f81fcd5e1d892d89dca6486feb9ebd53ff94fbe964f480d1e89ad0dca1989b0dece9856aa4165e1647ea86000000000000000000000000000000001239b90bd383f4567aa95023475a6dd6f3e3e3835bfb2aa15ff527ac009808f66d6c9024d754401ef7d80d67005ca56b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f14cf5bc72767d734f46e6cceac005a738b33c392c30e1d4485ea2b59f00ae31453c0d79f6e1ed001c86f30e6de484000000000000000000000000000000000a8ee9a019b7c98e3ad496212432ce60b472a1317a33b3da820ed44be6f5e64b978d22e07ce2c044647e50fc547374651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d02db655eca226737c23662cc306a1080809e8e9aacc6f9ff9eb0dd3ef590e982c37cb7d2f297406e094974bb1a72a00000000000000000000000000000000143bb93bdc8c3a7f42cd7ad1786b584a2e767f4e9639d016a359dbe398115f10d890668f462d07d428759d7c314a59871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016ce91ea741313fcbb7fabae6341c6205aa06e4e2f082b5f999077d65a7880fbf082560627dd812ffbccc158afc506c0000000000000000000000000000000014c2e717e327d44b37d23c0742fcb5fa840089d27367672a14d56f91c81408a79d601e122f1cebc8d36224aa142e84f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015565b040c1990352735a43a66200f4eefeb75476cbcf5888237aaeabf09ae2a8029624b0a7757147922fea651132183000000000000000000000000000000000c4a6b3d0275f0df20c49c08e06ef53cc4ae0a4eeb972143d5d8dab7ad66672f2cb7aa87395faac77ec5d7fbf71adf421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b1ded8cef5bf44b7d68ff268b6a4db53d547558fa057c875db742db6b17f4b82c75062e3d832c8277bfa49e8cec97700000000000000000000000000000000163ae51410a68196f3a0de2cf8e18aa5de410f5585c48013aca541fcf1913ffadce664c189e26fd629bdc841ba8404ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111555402017e17769c1f23871d26608c5000d39d2c0bfb8600b996c152542a735076c9f0545ed2bb34023a66d62216e000000000000000000000000000000000e5a4d2e4c16b0fd22508e171e5ef80b5094580a6bd89567e1e1fbf462dc05f43bde98f09cb894734b9dd3da8656c1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118eba29a94b70d98f7219f93207c4096fd00417fd6e51e3ddca230741e89418f50a6f40ef7e9f1afa80749bf588d197000000000000000000000000000000000259083427a4cfe4c862666f60b01982c463804124f2bd77edc90c6e7821cdfe7106a2db3fe3d633b15557199657fbfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd09354fa5000af1172c7863e8f09524fecdccaf04bd8bb31844090a6fdf3e4ad822e394d8038b5c4dcce74e3f005b2000000000000000000000000000000000117ffd89bc99938120e5b4cd9d4e4a89c87682e6474ee92313f30e573ec4fa85341d4ae1841fa42b9f08d55930a168c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e2c35f5c4571df3df94b52fe383452a7dd5089a884f9b109ea571ac809c077fb30c72d2366c372664feba3fcacc4740000000000000000000000000000000002cc72bb35ad8150d64f6d8cc1bb767bfb2dc758f38ec9418b2369db958c3f26dc842d7b4dc34b159d01cb3498554edc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f268ef7311fb3bc5a5d384b555a07f46e149d56bcc98c2c10b258abab37b7226abc09f3cdfe93ead8443afaca6dcbf000000000000000000000000000000001535429b0269bf65ba4a71dea759ed10e4965c9852d78d361a93d8e35e10be37a4e6bda0ba0b9608f2f7c1da5c8fee1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134b8e8022e77206bf0c0ca2bc1b385e8983754e7c468a5ca82add347f3a3300de5fd5ced9bfa30c79ad636f5b4db216000000000000000000000000000000000a1a919e2c8636c7b7c22485c1d1f2ea513dad7a7ed6922d589687c2d2c2dc81c1c1bb6628aa419bffcd098ddcd27ebc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bce0322b8c3e8efd8eca5837462882a7338c1619d37f0b6fa8b8beec0a36c8375ca23c333af007611285336eda5982300000000000000000000000000000000111a3d0c5bfe00b00442ffa1534b76966045de0d81092516866754509b6a484c24bf9d08e56c7871cb4071e5b9fbbe7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ff7184c0614d51bea355447183e8af1f6635ad7ceb5fbf13fa85d0c536a66bc1df734024de57942baa6558e442810d000000000000000000000000000000001271eb8d01f2a76ed84c5d3dd8873924c45784ebee12be098576f119798a05b1d378659498e39e2d8208b6e64c90e17c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c4dd33351acfd22771ab8981518cb5c68e016fd02a065edffed90564f2eaf37a5f5f46fe53c4466791a4044d1725e10000000000000000000000000000000007a2b508dc433737d96e9a0b0b07208f967ba13ffcf73345ad7b29aa7fe802e3f5988f27d10c6f7d5968d4c076ae198d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b19032e48b8242946fc4dc0ec74ece961ae1dc1528b7bcd6266d9514f103d6f8dedd53618c944d09f6287cedba823200000000000000000000000000000000067fffb43e15d98665adbef2b7a2ed42da2aafddb7acd6e772bfb88a0d1854f5d9c250eb681b3884793533d276b4ce131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019de9475d338fbec3140e2b2772562d23ef1941d8512a64981804e5a975b27370ee1951448645c2ae38c0d43a2b80b4a000000000000000000000000000000000926a23f7a5a7569fe21f528a4c6ffd2d2337852157a07aaa15ff0a9cd74c30801dc424b3859a275db6d6d32fe9775341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198435da5a41a613c8703dc56768508bc0458e649c321774ac459a60943916c8ff8ccf3f50e35dc7d0af45b126a9aed3000000000000000000000000000000000d67d9c15118f6861a6c3863dcd5a9248b65750a8ca30b667f87b392b4c8afda5260f99425abaa997470c8c5cfecf6a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e7af19ffa6231aeedb2fcb9ea939ecce9f4f3b746a6eb455dacc5cf243ed8222e589461a57290d75e886f56c9321cc0000000000000000000000000000000017b96db0698e15efce619dddc805028397dc9f43e9ff9a586dc0cfbae68e53b1e1c8f0be91fb464a62a40a632aaad1371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163b358cfd8ef6dbd38e21f2d00d929ce39f0a4e4642b74b378401a4180a5ac4a8f459faa8061d81256f11aed4d44a9b0000000000000000000000000000000017e6e962ce679a44e31b01e208de3fb0bffbf1becacae265c9ba05d3a9f54700602c013b2280bd179508b84952e745621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003982778c5bd26e39a8c48d03ab310dec6e0f8ef7602c51367afb6cb2b4a452d8987f9541674fed8187f61c5c803818f0000000000000000000000000000000013c483f18985898dc4a691941c2b7d3269e201644e3e2d8eab46f0b5719b1c86b092a1aafe22a440b5ca897048b7314d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a672c8895fc97c85e108f89c458a5f348c0d043825be87e695de4c052b0cab198b28bb9268052814d27e70da297f800000000000000000000000000000000007fea31dbed2776b9a2fe6c95076cadd53d9d7b8cc0b965eb518699ecc4b6b9b6d0e5ba9699211346537e7e1f47af5fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004961904582a05e77fdc99308e72eeed2405751b91e5416691b223b8223d56d9d330e17479186964df3eabe02d5aa60500000000000000000000000000000000109396ac2d77c271179fd140a100826c954ede0a64fe8cdd181231de0fa4d61241fabdd5645b40851247a4d8726b8a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cfb7f00bdf223744ca3552e82c0090e99badd92cb80aa1729b9062644ae4f91dcadacbb069c0dee4649cc90db00ad8000000000000000000000000000000000f770471d8653a5519028a626c9950cdb7c1b44319db4a1b7960cdda097c7f1e4a0bdd17c848b0f37de4b1dfceb6bb231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001181f10f6ec9a923ce8b541b9c9995e44370ce08d9a306ae5a5610beb5479e0695451fbd32f62e68f5f1f12eb9cdfad3000000000000000000000000000000000ae57bf8835e96ed4694813308fd956b58466afbce9cbb5f74044a7e692efcab08d5532ad4a4ff9b80a8fdbfe609a06b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050ae43d3dff192732ba86a4bf81694ec7da667d28c7f77402aab3d5c1482184d9699b4bbfed8e9b25e7ad516a460c0300000000000000000000000000000000123e62c1f38d91323869f4d3fe34a04bb25877d99be4255b6ed30a403dd0041f80f081c17acb35461475059ac3ff27301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eb93dbb12c3c980c815e04330822bb70c7a24b561796f23f78ddb46d2c7cb47bf5cf15364a5dc85453df65dae8b4af0000000000000000000000000000000014f84c88935234f762853bcd7ef9a0cfff48f53313c5a3f8589a7074a68e0f188a1e77665759041ef6aaeb0848be32911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061971f6838b1f34c16ea34ffabf8305f9f916504bbcdc805ccb6118f09f9d31b41fd95b808057eae33c5efd03aff6bd00000000000000000000000000000000140326175e450b5421e436c618954d500e381d9fb8203040cf4eb12d93f8d2ec611142ecd6d2d129dd9135f6d97966c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001288c6c7bf2d17e6895605bb024a1745f0da23f96cd58d387210f6dcdd55b5c3ea23c0256c2400644427f8b9ae2d0c610000000000000000000000000000000016489d0309343d1d51783ba5f081c5c8d1fd777c6d8ed94f8949c888885a67282e7be0c23c564b0da4a9c10d6939decf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067143e697dcf6f53a4625cc7ef96e9d2e28d4f96df8d0f05f610680e2f59d7bd84f860ba1d587d685703ddfd1cedbf6000000000000000000000000000000001634ee51d57d09fb0a7db507106ed32b33c4889bd5e2cb7bf957b59376f36257ae9aacbba285ef9b69d293790bf2420d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001173d8d477d8128577bc340d8dad93f39d1335689332ce74d422ddf3e389f441172b5aa7cb065f7fc2a136d4f10fe5dc000000000000000000000000000000000dac65b4635f8b9a23d8ee085c4249959caa5ef589d08af377fd52519c380187416f9817721a998d815bd56bd4ce8ac81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da5a804e186ab01afa2d1afafbf0545c0c099640a35184cc1b74ee5484b97f84f7f607a11d5d9ba5bf021434ca7f0c500000000000000000000000000000000021f7f2bc9f45b334d5dcc8017f69506cc0665a108d0678f6a6e4bb10527a7fcae84d69a790fc370654e8ff269ce255c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f3c07e0ddbb10ef130ca1c08adf08ac8f12157f6803720763b7d078e04d15294d81aeb5469c270dd365fdaf245be35000000000000000000000000000000000977154c1c613f042ecbaac9e468aa306c94401631916fc6f14c192cf485d5d747bf74f8863f6504b40c4ef32fa6fa841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034950a6299de7869518671a48f1aca471a132b3f6a1bf1ab5b6df7cb8c942c12ad78c06a9048db77084c5f89b17d842000000000000000000000000000000000c8d0f3daadb7e3b6976e959db8395df1f93b4378531c0b05a88b59abb0cf473c157ca67e92b09324497d176116ebc281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9a9a44de05ec357ca6adaa942c34f56a90dc7c234d1fa9c34a9623293b8a477c8fb3bc05b35b2b5cebf3e7bcc91a9000000000000000000000000000000000c59071d9d32d6708fe16cc46ef1fecde8a30e62112e2d167e44caba5be0a39c3fa16407b3d9c48a9f7f22a7b1d8f8db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6d21ef7fb71068f8413031e2857705266a7ca10ef31000e6ceea839394daade5cd002f723d5217b29797c1112ce2810000000000000000000000000000000006a183b8b3edeac06626ad8e71b3dfd0c0661bac5c3b504b5a9d7c3e155705b4f81b63048332dd84ba1c48c61411b50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9dd221ae813b377940501d2ce2f11c5ddf71291cb09db93649731a1546d4ccacbe4d37d2b42ff138591c93b2c0fac600000000000000000000000000000000146a68a64cb40561b009460c5e4718750ddc4c69894904c3727edb63304625ac5cd82b1fd17da9a615323b83754f11cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c62538f152f1667a876febf1ada00c5637c42d8708d4392aeae1348aa0ab61cc7ece24d267eea11ec5031706dc08f000000000000000000000000000000000af84db236f098e86f48513c59402ba602a5793bdd72506e4eef7bfa4c728a77e2f4bf3ea54ace5665470eee42c3320a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134ba12e9d1c3de55cbfc5d796cf5221ef0247b381041340b119467903451da8c2d6e804dada0e4404c4b971f4abbf040000000000000000000000000000000006ff6f235cc3481d0d12c15a287f2f18823a118d0759255d31b8ca5bb63ffd639d4643ce4afa81d425c16f6031bca94f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd3c9bc3ffa9cf71747c3db458df73e2df00112e636f9d02cb52153b36d3a165a1ee365a46e097e75e37e5da16ffcc0000000000000000000000000000000014a44f2c101277228c82648172cb51dc312c0af0539ae10f1ab81205bb1802160baad27b019846b74a90342ff11b587e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cef9305320a13c43e7c30c1ebd912f955fd910ac908cd1e12dcbe74c453317bf75c07dc96fbb1d575fb0a44ad8a24d0000000000000000000000000000000004199af2e5e4256d4564321a8485edd408cb9d815fb464e3c39cce49687c57db15fdb93efe65232c7b438b4eaf9a01a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e79c90ef374b5638415725d017038770d2e0fae40071d5e8c0e98722e978a91b7a93f0c034a6996b71cb008127e7d200000000000000000000000000000000037cef266b8bc111df1aebd1d10720964cf22d3195ed159d196011b31c1db45ca1af7c95dd7322a2682d6efb318c0d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000348449cd3128ea7dd0d213f7ae440aa86527005bdec12c7e6812978b6f2f032960bcd8d2d5c4918adf96482b7393b4000000000000000000000000000000001682d3a0960e3576a797422ef9f0003c11e8431e091ef61d351940bb3c29eb3cb1dd1b8d13573f560d81db62d53d81d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076564c3a5b234db1fac5502684a243b92951f3ea7fe2a79469e42659f9deada85b0caf8a430d5549679f8063193ccb2000000000000000000000000000000000c075116f67bbfacc9fedc448846373e60aa845fcdedbabf4dd1e59ab21c7b1dfc2e3c79c2f83466ed173d90e987945e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aef5921dda01a4932549f1be9e672c7cf4fe12391f3d7d65588fc784239c04046ee45b5b487c2e7ebd925586212862700000000000000000000000000000000132a795da61bce017c6d42d1e7d0cff770533ea34bfddfa595d4815fff9fb24868b31bf7b285d3900ae431dc1ea66f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095def14fe363928f99143a3fce9b30a2d9ef918cfb6438d45d062f2a2208831f140d0a01a8df0eff16bdaebee2c381e000000000000000000000000000000000555753aade7c4d315b41698a332ebe5a2d641e137442e207662b040560c1690095507cdd06fb2d21a5f5167286249d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159baa6fbb096b00e37d96132e8f9d9bd13411064068f00dbe80f4013067aab9daf8e7c9679def5474a7a834edce945300000000000000000000000000000000164cd5aced892f0fb15107bba0ec74ec0e0ee5ce840d475f9b040954a8b251353b1ee65341ae7638d239fdde0e427fb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015122e427bf409464f8800c53e7e8c3364686fb16b74ae9fb9849b99e17e441e117542c8b6afede418b6e86d29b721bb000000000000000000000000000000000280fbc214383bdcc914e01e3b74f65f7bd727e9733fc9b93535a49bcd0e7c85211899410117a4295244a252d6ac9aa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc7eb8494fcadad967ca6cc08c892010844f332d0cd5d94e1c524bf669d749945a4dd178b79da9232cefe11c4581fe000000000000000000000000000000000eb01e49dd39506fb76e161dbb7cdd06370251ea9440693b2b846eb14ea8257095ef1dc2622c83ceccbba6e70475b2cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000149139a4838fac0be1067caf86a25a6e81c3ed6da9f97088ea29d15c207f9a9ae1a15ec45c88777843f8f1eafc36ebe000000000000000000000000000000000fb6a2bb465976d195127144c65a8f2ce3ba97f1463279a462064b5bf4b15d1a4bbd0524a44e91a85b5d44b540abed1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f73854b56376c2b04841ca7dfa3521b343e20431c062c59b86ca95ccee0408b738837657eff66edadf897e62767b9000000000000000000000000000000001102c16a2d173fd846aafd58061a0ecccc6623e7053668ddee19d16882a5447b2f8a4c1f1bb50f39eb32844e515ab6fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041710297f5852af042ceebc2ba20787e23ba01c9d3b2d68b39c8815b15546eb568c864f7915108af2fa8101ce23b07e000000000000000000000000000000000cd20c2799673d5ac0bf0dd65baa3a4d7e9b5602706c37c4d314a021a23063a23804c500b74a12ad78f24ab2608c266a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872406aa1b865bc76f78ca5791f5d8d7a78ff7d70538bfcf2bb39287605eff6212e1c7f17dddb4a85b7cb9bd8822ebf00000000000000000000000000000000147adf16cddbe6ddd6209a346b7e49ab2556888afc33c9d91d6d3ca85d294eabec0c84c6941e6ac0c1f70c96068d11751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001909524e6f6b1f42dbeed9f59ae0e0864b406e8119ee44c090478804d71ec330cce73cda0b40c5146fd7322c3905f7f100000000000000000000000000000000059034314201a64ea473b09c6442457fee247d41c7754044e75a9194a4790e81db29d98fa6c82d16302b9ced99571c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad15d0b44530feab60b71a19fe0bb727e659215c1ded76199cf9e5fb1d453ae601680a3bace44f6aacde4959e4da77e00000000000000000000000000000000111923c739a04757e764c76dca1ecb3dfae924970fe6319499a6d8c91ce3188fa13dfe678d9362135b173378f1df724f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b3f097a244186b753a9d34aaef666fa743e2041490646cdb29061a89d33f86495ca9b4d8f26338862336073946f5270000000000000000000000000000000001233915ee82e368a4cc8c4cf67934bbc395cee6f9a07a82a5c3aecddaa572718c9d0e8493633c16fa8f972145e7c6ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a31c45435ff67c4099fd83361a39b0305d0ca1ac7bd983d09771dccfb32b94663cbe3fc047ebb8a79e86134ffcb89620000000000000000000000000000000011c821696d0354b0baf60435b3ad4f6438ac190ae51b50f82690bcdc2b985b3474a714cb02cc74bf7718ed4980b722d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d091faeda381da24c2def22facf97017584c7dfd81ef91480f5c91e8d0467680bcb8f023bb24d53ff5a2a68f394d00000000000000000000000000000000016792e0773a52b96040694f1d3a9f9011ba4c8b3d48721514fee4cf880c7d2a4352039419230946d1ebc60a9736603651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea850dd323aae6b4dd6d61941e794a6b34989a0919ad97cd8a6ab1a3a999e5b26286350e5a5e25fb0fd1a1fb8a527950000000000000000000000000000000018634e07ca25c44acecd037208f50739a44c80a76a414ff0d47e4a71c4538e8d43709355c06d12870fc4cef00077959c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006154e62de42b06c9afc6c46ac15a77561d993585a6dea18a14eb86225a16d7a1fbdfae1eb2306af002203e6a8a3432f000000000000000000000000000000000007bc550c4dda3945ae6fbf8b58c6b29d4ad5f70a9730fd32a01b69e1d39e79db4784160ed6092fa4ecf48979bd22d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431fafb50b9523931e298cfd766b6de0e648bdb09f76d5dd44e98920209ee10ea1a3fc573a1c54c033c35e1c73c1f2800000000000000000000000000000000083761021f9ac8a0870f733fe5b4466a31fc585bb32f896f6b738760bfe8a0c697948b149ddf741a012a0fcf21823c3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b601a79cf2ae52e9e1424a4ee500d822272fbe8ae2c822f1229e3ecb80420a2b0176f38c40a671bb56583928e34dc70000000000000000000000000000000016fdbae8996fe9c304e818871f8936d71f899f95b2f7a062e4144f77493342a8345e302e0f9d44ed099294c3b68d78a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016269e9dd8b57d7a110929ac830f140b3ab2f30d2b346aec59cfa113f5465c1e03be7f247d67deeb391b41da27645af5000000000000000000000000000000000ec2b0d198d3b587ff08cdb1f8094728261c41bb9898445ad60274c1c470c1313322148699b2000941b77b915f27c7561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c30d2b3c76ec35bc2f6d3b2424973c8dd889c738aabb03e4e093cf3ba2644c2fc5e4b11c36c6465880d237eb43893e000000000000000000000000000000000b42a51fdcc4a21fb78aac34d4713ae019fe877a3a5b519b749d8d04c939e92993ba1e292b116afa7cfbcaa653c5a92e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017430b1e9f9b4c3b0ef8cdefb3c4e8ace13b1d67f34fd71fdf9c2a0b278746ae02c204bd44a1b0eb3d9442c0051dbf6a0000000000000000000000000000000002486b308042995c6e184a1b7109a2e5b3a5f92b0dea150851f3b356eaeb869304c3f2afa79db2af23d462c1e831f3b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5cb8f1716ab70ad41a1dcea28fa66550b85b1479cc9051c1382ea63fac7e60b442a03d852ed7e770c678e41247b33900000000000000000000000000000000045e9bec29fcba13ae3db440d1e78dc7a21185fa0cead088d178a1d7aaf4e2190bcc31c670168b2fc537c953a20e6f081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ed9dd21461ba501c0d18b5d4d43aa96603879c0a79600e0fd198a6fabe8c999f5789ca4589a14370e541b6e8f51760000000000000000000000000000000010ba806a2fa9490137a2b55e841b8345332ac26a690586263b535fb6c7176ccfc942c723d4e436f23dd4ba50dec4d37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039f1b01a5a22c1269df77611728ea829e6811ab50ecd3f6983a267d1262833d659d0226f8a806ae14c5a0bf093e1c7b0000000000000000000000000000000013363b08b1695a5275acda5d651beb16b32e4128728c4fbb58836b98fe4f324b5aecf6f6e7699131df3cb8fd400c1d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d4b1fadce27ab8f6f79034a0da0f1facbcc623e4fdfa6a321c664f07e2f7f8e5ea979a484a960f0f9e2db27c459f900000000000000000000000000000000024ce1ab7702c712d8056f6ef16dd90e798ffcaadf5c34f26a89e12a4a9e4675aedaa1968f64188ad89d814680b6dc321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138ebe60328cd8677717608548dc30b1454023ee3b11d3939f9d8b053d92dd1b0efc5967704fdcdc9ee7df8aa45b997a0000000000000000000000000000000014709e5abcd566343ace59443ab7bb17b87f5e2a8aa5c638869c51b26ada593b5fccaa62c63b9459783e2fde2f63182b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d0d928b383aa45cc4f3626789541a2bdea9f5ae0561e70bddd3f12fd32c1f2c1d364cb76158c0a725840dc91b884af00000000000000000000000000000000127c7434425891242e174239f35768a8ea53e2366670ffbd4b8cdaabbd506fa65e7cc8f0ef5eadceff9e4c4ff4f9bf791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3361bf07dcb795ebe86546a0721324c82c190530af4cc0c9fc97e604918a1bb41537c1deb1ef1ae6ef64ba22125ee9000000000000000000000000000000000b0da95098ce9501da6d36692cd7387c76089de03ee7daa191adb2f349cca3dcf2453d2d3a8bf42858c3f448f19ee8541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad29c630ad12fef0c344425295f5a16aabc9b498d14c3a1aaa5bfe243bccde6fe791fcec0989f64e457377e3544d72000000000000000000000000000000000127d93ded907dcd4e422146785bfc7dbc60c56353480e2e8be78d927f53514b8f1915481f86998a177ba94b6d96374911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60bb2f7fb2a5baaec9f60e68088b46ba854d9f58fe3b413247f76d9ca49d4131a5912dae92428570ade4bf53dbf6f00000000000000000000000000000000003e21c9e5a9132f5b470838f60de7c9d08be400a2d8d3fa0956832f5f91c64aed040347826116547407e002773ca51231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e20f1527781f06bfa0556ed5b3351a569161bff52d5c53bed067ad8e92ed5e0b74ed673744403edb10151ce09aef8f000000000000000000000000000000000913061357c40e0d396e7bbaff74999e64ad7bf31087a1bd0227acd86dbf6a5f981635a16f447271d58762b039d689331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188e91ad481ef0781e04bd123ccd00232eb5e6ac9e58c760373409639bd436e7396470fe343d0208fc590091b5ce6d29000000000000000000000000000000000547f95193a5f2b8bf4585b983884a3bd7b04731461c69f18de8ada62457fe4f22b20c051d2edd8ebe7266e0fdff435d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f117aa0cf2966f0ee0b9f7d54ece6ed73929f5b169717f196189b464a57a89f1a120825f66978d972eb71c3622a14c00000000000000000000000000000000016fe75724404866207758d508e13d570e32b94761b04e31afcdfb6364345b7bf715db3c85e3b1ea0671e9e567e8b1fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002922a91387620faee87bd78f1b07696833cc1ec8787f57bf0884f5303ec5450e8244c9b569e35849448518662ffc045000000000000000000000000000000000f729ae44b8d3e76e3dc1ec52d8535b207fd6985f744f838630bbf9ce981b8568e90320c2b62fb0fcd284c647a5f82b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065234b9b0ea88385aa4981614c43fc02474e366ea79b6d215a922fdacef636bcc0c6fad70290c13ea4d013b1d4bec84000000000000000000000000000000001690f45936ea704867c511a706beef775c0df83fb39d884270bd0a8cc3b42ee350c6f08a4cb686d2ad35fcab4363c2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f51e3c9f6c5eed3649a163c4cf96cc90e3eecd3777009460dd45ab93eb01f07f622701cedf638372c60cd4c6a3a92e0000000000000000000000000000000006f00e044efd13dc533c8e89d21fe78b927fda4752afb2b6d992965934892431deae064e6f174f27b09b66c5f8a0870b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124797f909dfce31270ca24a725771d56eb1e0e728c5ae10043cbeb9990f0d8b3641629fdc6e660a96d15fb5e41425fa0000000000000000000000000000000016fc687d0d274e36cbf8fc4785a8b9733c9e478254b97ff569532ff68bf25eed08b12a88043447082254ea01ecf2a03b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001980d05e67034a5d7a79fcb8d5afdbcd1e4a4bf8d98020bf9fc36513a30ca76a3bbd702f51369887ccb255a395a5bfc3000000000000000000000000000000000bf80f58f5ba700f4e8589c98ac00259a2ce4dc205bb739ee5e338103970358b01ce10de4c0d0c940f131ad8b1e7bd0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000651d2421317cc74da93d1052c75eb3e2e458173c06bec03c37dbfb7d47a737f11a77ed240cda5ce3634e53f6cd5a6a0000000000000000000000000000000017a66eff7687bfe8d797054948e813f1c2a7a53fdeb2854e8aa994f825c0a603f973e7a6d1a890ef4e8605e4b4c501661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159781810a404c8d3b9dcb3509ae01159bf2f0c5ec61e7f0ffb76c970624d8ae678d157f4e2c37e2f256b4875f65c9f6000000000000000000000000000000000c00726ec52b5a20b5e02f3b8dda399e3bd0b391c45e84c0fb3c1cd2dcd6840317295746904d2dc3a90ebd469e2487901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004080df94e2a441b9efd78676cabdef959b0124654f1ee9fe82673bfecb7f80ac7e4f035f29483bf03adf3d3e024d02d00000000000000000000000000000000020dbc0d81ca0766fdd4f1d75664cae542f51d1b6ba9dc8677e6904f1bd8c299ce705b954243a3f65a29a7ee2d37cbd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001089230dba7c884854c8b34ea86cad56120943a6f8093c179b1c88dc4c8c08f11941c326850accc2cf7cea518e7f9dad000000000000000000000000000000000e1f8007880c2fa48cf3d41689038762ccafef3da51145e93996796ca03f834c6cf42828a86f0c10130af6dac681c74d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a81d326fcdbb4874c155a504cae5359252ea2258db77689e35077a107be2fbb5e60ad1df002bc4da1084b82b90562f000000000000000000000000000000000e071fda83ff48ec0c69d236e09805b7a3de4b070728a8d7afb2aca801a84fa1c302bfedebf6c495ccc19eefee80acd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bc01888dd74bf1d579943d73f76cf9168574d2ea781a56e8cbc08b65bb0f7e232c348514c7608180058c79f47ff10f00000000000000000000000000000000085482021f53a52c5d74eebc1ea9f6c2fe1bae4d53e50a28953606eb0ce938b5e1836322241eafdb359361dec6798fc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b01008d2e02a255ef7959b45a2579bbad67d35577602165a72299cd8485119bd82380ebba9b15b96d7ca4e3b7a592db00000000000000000000000000000000051fc56ad0fdee44e7547328f7bf8e0a287a4fe12e327435f8b9b0b3ae11e9de638fb1cb31b3f2b19816720100ba5e0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000961322e4b85d3b4fde11276fe55f2e01f9976d6a58c256381835c7c9fea455e0ee1ea92fe96a81c4da1da26d086396000000000000000000000000000000000023a842e8ee3faa1fca123e9b8876976c6b69e755937e9f48d7e80b1db75e49a059e0d501a96b1804f7ddf15d29ffd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3aa4b508ba6f3b6a0845fb4b99bef35e4461f889196ce8801e20841c71e0809feeebb8cc8fd38a9cef8b6a02a3f64f0000000000000000000000000000000016b8c6b52fabe93f4ff7975f23cc7da6f636fe53bb8975ae8a5537be5d4942097fe736afddb95b277260f497d6974f371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001619a8b47a41a884ed2506b59a36fe159a8dc7eb7818552d66f1d1694bae768ab777f81a5f64707988327040c673613f00000000000000000000000000000000181f6bc2693b6685eb2464fc6922d08566807f6d4bc406499ddce894c69e50120b3c6b9d94c45aaed904965dbac5f5a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f6f479610757747c178a2172269f03950e2cbde1aa4d0af3828ca5e4ea3cecd7d0b528b9f94f8d9fe97cc47393b4fd000000000000000000000000000000000553a349e029b92f9c95f1653d340d70474fad4b5bb528a071c9d5bb1a1e95cf7cb41ab5098559d8076bba343971bc121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001167989ca880c6a3221193c533b8844cfae51f81c16c9cdcedab20f1ce0e0b11b2410818ac0e8be12e744ffc8e51525800000000000000000000000000000000091d88c66ad50b30236859b29a1c0ada236f78525513285b4f51b35cd3cff3230591a8b77315ae4553f704786c99f2ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c917aa064a321401bff66177439c346f8019b99865c29a0d1184aa5ed2de41af31b1d760c151b3af3dc1b6d35134e88000000000000000000000000000000000c3c4b5d56594870fd8628ee8e1dc6a591174c424583f724d2ceaabc41674d182fc5a0a9488b30a4d3ea024a76495f591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a536381edd5a87ab8d48d5b5e2d126a42de60d686eb956aef32d3b887e7806f8e9b6c632237255408f0e961db05c8c000000000000000000000000000000000582665bc7cca1e26fb5f6c1115600cf6c8312d53697a521bc4a63f51a8556abed1773c54ce4fe9342121245f3fca2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005aa7ddd5c99986f09e515c5586de6a414135f25356f79d8f20b327e30de60e988cd68e4780bc35db73a2b22012da10800000000000000000000000000000000111ba3a532de06535a07f4419bf56cee505a7489cb86fc84f10e54b224f0874cb1e66eaebb0283823a2c5cfdadc5a4ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dd714e2f323b8fd1029b365c00641c8b0beb60a2a669e75b3cb28e712d0c7131c2c21848261930adff3d02d6e7e70b0000000000000000000000000000000000cdd8b77a2a1b1c61690aa7cba2a578f839beaddf25e5ab3fa6298035c34abda3919a38e6740da471ec8ae6811222af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dbcc8e2289a220317e815b104172cb2e109a7d227cf6b03fa0eef838059c98d9c5c127c14a9af4c2c5cdd015a36dfe00000000000000000000000000000000194ec626ce2ba133e837d1786e2e619b5d1d68b0a5a3bf9faee959880cf60ea2cda3ebb00d30273f209b1f34a0a507d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e422d5adcff6af64faa995b59de2af18d10b4f795c93cafdfb2d9cc5d875f5d779362db9b178577e4669915864cf3e000000000000000000000000000000000b462b874cd4c1678ad4101608fe07fb0cddb73fb886fa1d3c7916c9eb7dfa72690eb6cc9c7b55b9ca8c111f6ce8f4041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6abe98caa71760196de9ad7d16bc5a7919f7e4e38f37743310f57cf5d8b6dad649dd1c04e21ac7278d31b839ab2b7f0000000000000000000000000000000002b8ebbe772212359a010a078666d2a9f5ec00dc9e6b479c4005b91c2efc54328075c5658011656ca7fc7398479656551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179c842b7a2557204d2943d14ee7aa0ccfae8ca3ca42f22eb8f07f78ecd462c94f9035879707a7b8d8f8c5c79aca8b970000000000000000000000000000000007dd30bd37d3e62bd741dec6f5ffd1f664ca5a3ee3b122f30dfec4bbc519883e201e301ba92aea0c3fbded7c7e8627121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059608d8dc34d6caa30d99c18a262263be3ea6caa99036e67b416bed3e48706d2468a437f74d8bcfde987838c41a1ff40000000000000000000000000000000015d119e2c6099694f7dde1372102cb52d4c04d715c0fddffb34d4432bb211843e8dd11a1ac15dedd03d15c6d5ce31e311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178048144ef4543fbc2dde1e76fa2c723237be6de82f0f4ae366e132e68428f2d4055bb83424594dc23a86292f79057f000000000000000000000000000000000991fa76a1fbb1bba55c66597ddda281d65846c4b8b861666b8e4c8a4b906e5f189a902e2cdf6a4449660e2866dbcd3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014945b7b2a4ac17191517869b021be60d1c6b580aa47ae59b96560213b664aeb980ff40b0ec3f1c74900bdf97e48ac60000000000000000000000000000000000a314b237a586ee94cb23ff60f6f5cabb5051e2e74de45f4463353f085e9e1d99b666822574e1552914a88d95054de61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ab716f50f4163f425ced103caefc1a1d25f97f960246bf9b0e7cb975dea7b28be893ee1d672c2b8c95c1af74ca9cb100000000000000000000000000000000041b7f8284b4f666d3d74f3b00b5482cd5ca8382782f54379f50c8bfec00996d71ea85f77467c83d858e4030bb1e3b041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d27524822be59e0d9308d04ea18cc5dea7570ddd1c787c759230188462a38d2ed7131e7fa41957362e207669692707000000000000000000000000000000000b4e8be6323b8953938f4cf72ce8f90902b057d7e652919d84b1eab345a5a4cb00f3bb8de71c1ed42bd6d13b77b7a5cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007077aad17f5a5bf5147fa71bd7df259acf9a6d514b6b59075cff6db10677e65d166e6b55f0c51fc8bc323034bd718ce0000000000000000000000000000000007dbb66d3e8744468f08d11e719cb1007088a04ddd34197f5eebea5d8594a6c86c087acd6b8e89253838ce17a87fa33e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be958765cf288926a31f7ee36ebb8a0824c7698e1b3828ae0173a000e6deb3447f988aaf4d7b69a594bd26017e85a2d000000000000000000000000000000000f1b8a2559eee674dee0f6b27fd729104b30c9586270944bb71069da1198491f116e55eb76275e809484d65d921a73871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9c7139db94420da23c31a5c8e5ac5175ce9a39d3a60b10ed03e90bcfeb641e43345af01124723431746302085e0f610000000000000000000000000000000006bd43c3d259dfdaab8b111a6ae716e25e32b76d3a9b8f2cef5332d5b558f023ae0f10bc2b982ea509a5c8f989f930a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce5e19dac7549d8c8be52032fef1e26e0c9898fb6f0fb67ad11577a350af609cad635a5d0c2c6498443221f79592620000000000000000000000000000000010e6a361c4c7c61e2911cf6babc634904dc180050c9416fc761332ef59a2a61b52cae921568840e6561a6e002d068f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b66ca9887402d79dd08bff64f56d96cafd2ed598efe9324b3a05f0bd4d85d8504ce022a61c85773afca59aa474a4d2e0000000000000000000000000000000000fd33d7006a63b62c6a0c388d85c90562cb995f86e0211e9545bdbeb6e611d81ad6af34d388776757c20e02c3ea74941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cb1b5896efcd4694c11551fba3f155d8adb936e1d76474f41497d3daa34a73f86d352a281ce8a2281fc7c8b37518200000000000000000000000000000000089c9503bf95ac414d26d55e8a1c5c23a95bcf655ee94ffd3dac058968ea07f30289766ed1ae02596dfd338460418d081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1f97b1fbe4aa7e4de7b859de8a34634e9c0154a6ed19149cecbd1f659791b928cc83a2ef029c2361e51d2e2460754f000000000000000000000000000000001658c1ef72f1f9301a3a2f0918c2eac6051603384f59173465a8819ad6232cfa2f15f52b4ad9d611b66169ce1072de091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da3cc02370edb8ff35edd976eb79148fc9f7a189635bc34af81dc81e1b8349a28c8900ef379ce2e604fb03a04577264000000000000000000000000000000001334b442395a15a5556396af1c5c8228206dcfa35014dc63c3e8e8c14a818f5159b494ce2cd9238bc855abcaf82401001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075052afc243482153bc1ce5a7e2873e785bf5200f5856ac7398e673a53770ccfb1b23f292c9babf3aebfc37a0684f6f000000000000000000000000000000000c92f8a9226c7605cf170b74d35533082780fccd5972cf09ee7a98cd88d621ba3c285c6342f66c44a39183f1e3cda35c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008556ff623981896d755b33fb8419ad80540f3bcca4389f82e9a175a4b5ce293ab5de5aa667140d97d0b6889480a16ae0000000000000000000000000000000015acaea8115744c245165458ba1e6dd9ca51eb47fe79b2320c64f45d31873d66ce5a0c6feb6e7ec67ae0dc5d926a6d841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000994488ce9d79f670a98d96f2a34d38f845b69a859e9c0e62564266fa6c6a98d39817a5fa51881b74faf7817968f89b70000000000000000000000000000000014037d46d79caa3de9236ecedcaf510241699597d0810d0a6453a8523c0adeafd4bdc3e8d196a7996feea92986686e0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010049b11484be92516ea8e296da69275d8374d293670a59a3c7569f9ddf376b60e43b31367439613d05abf025b1f295200000000000000000000000000000000097662cd496dc28fb41bbd79072df4539e8945769299a9103841292f35d83e5dc90129a61fd2305f0d294e77867244d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7c2beba5335b3bc4ac63357749e865490fa474fdb5061121f83684ca466f1a30287cc9ec3be53f387f0e618a48d954000000000000000000000000000000001258e3642cf85ec56795763a2eae6ecb8497eb5e381f718928cacab2039cdb2371870981a68461d969d03f3cbe0590981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001719044405e8a408ea41921c463b781303f6766b26c4078e092b7b6ae4281bdfd3323e1d1f27b43d8415f1d2bcb8317b0000000000000000000000000000000018b3b932b5e1b5fe1d4669536a069ca130623132e770feaf0670a4f31663ccc0fa1109e6adbf2ce911179a8518e366a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b0949391d2fb9fe822afb0f2802eb7438a1604b43f65e04144ff5d77270e43dc79b91d0c87e2450386510f5008d1d6000000000000000000000000000000000304700ef60f62ab6c64349c92b83102079f98ac56676e560b33bbc23c160f5e17b569be8962f68af873cd967a9a2abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fa75dcc1bf8f93abbe21843891bb6feee051c0fa17d85a1cf26f3d8814b91474b4c561170c125998c00f836a712b2f0000000000000000000000000000000018f42e3dc7b5ca94962d4ee16a791b867ff98135ea2c3c026fdc657788740bfc173b18b08efebc9349243b932d7c34ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001394698e826d7bef8c2ec23e6a919277152020faa1726383dbd9340b7acb377a1b9956e74bda055b9f04f3933c8036010000000000000000000000000000000016bfed5a31e376d1e0b5120ed5f518bc32ffe19b209ada87531a2849eb0d43c01e23a0a3f030af5c462756120a417efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6e86020cc26d0f917b7facba524a8721b944b00599b7b96262578fe5c50b1626b90188876b0030a7144dede2d4aba6000000000000000000000000000000000337cb713f5dca702bad8cd057539fd4bad36c54d856c6d880e0ef561548f54cb28536a285d7ae274b789e1e19d5df271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d91201ce0a03c3d98fbc6e967727176f416f78b314f2ad7d44c3a73d4a017ac05e20a0f694bb6b915b45016545857f0000000000000000000000000000000006ec3a170539000ac9a60c14f3e2c425200e58cce4a15a0a9e934e52a9143c9f68f582dbc493dd52b1647fa82f95f0af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000577a6a28c46ebc96f09ed8f92e0e5cf1aecd0dc1f8acfdab70adbcc9ddf97d1392d211cd46d337605fabe0d8bee1753000000000000000000000000000000000ef66e1dec70cb91fd1f2bdf6e7460c225005ab1d4ff605af8f6beace860d1acb2770eae3e3b74322e512d6416b21a731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047deb34e613e504d08da46bbe0d0863f18bd5787fac9c905bb80ea0aa4ae36341b34b01478688a5c666e907f92c01a50000000000000000000000000000000012fe222d07d73594c3dbd82ac4d5c9043d79772d67553120080e4d398e5de2c608059e089f3dfe2cf8a7e7a423df79cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019575ae5e86452a763ebf49b4241bcff0f0e76eb9cf4069e901f126504bab9cae3dd025310e62b33d70ea05eaa6c006e00000000000000000000000000000000156a6125ce8b1f681ac014f5c7a75e98e811fb25e35f44da553f13b7865d7f671d02e99f0e0c8eecdb811c4bf1c239ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000059353f4b3b39938979692f780bb2aa0bcc26d7ac68d609ef34f17d3dcd8efc84a6ad051aea502b42948ebc6daa3f680000000000000000000000000000000019c174736ee25c2c824ba4d81390650454ea6d1c87653a1478917eccda42bfd6229fc82a7cdf732dde7c1ec92f6206321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e82768dca49536986dffb242eb8dd1ab0475a2d75e7a795d3db8dfffb5aff2161e7c9164af56d277b142fe677379f100000000000000000000000000000000033863add33d93e95e21170348aca83195c37189ea3147e962d109ba7594e0a0696d1666916fb9d1623e843dc703e7801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f7d75f289b19e1969a69edaad7686c49635756f788b9231ebfe0440a1aa5ec0f8e4333d9e0e824702079df354b8c8e0000000000000000000000000000000011479b683723594d64fe0de95b436ae2d71d8e19e4a0680cfde1c034eab1aa007c177fcd0164fdf65e3efd01204f4f461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e721b73a0a7b9c1d2bcac1c155fc1c78fc5156a5251051b3ee7622c2832290a66c046af25cf47d5169081ffea9a5390000000000000000000000000000000005f7b83adfafc68ba7e29fdc673cc25015b57392a67d11eace617b0fe7229e4076064fac9a5012acdbc037b6e7bb2ba01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055291b0d854bd145cddc63048db23570ad19a74748d87165f662ec36620b2992b56df69f729129ded368d64ab3bb2df0000000000000000000000000000000019e2040220d9048e2eca70f44e17c9eeefa3a057ed28065b401e3f9278f10832358ad44b059ae1eb294256621efd60bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d87be06b756119bfe4b7fb882275922fbded986a8e1304d0510a10fee80edd2d6e02359db236e8b414a856992d09ad000000000000000000000000000000000fe56e8e7368291be2e60ff12a3c463485f97bfd39826b1d9876e0a984830089a32334ec5f32888c1af0b02c1362f8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000371d3013f51412b35c361a80d96111d004706a63174ec6c254da3bc73c9bfa40bdf793ddd5658e469c3540e4f24b776000000000000000000000000000000000cc91c03b7246408f709e78aa1de8891b2292ae8c90384b2938135333f877adf0b7e9a712f1c081c556679c9958e2fb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002691ca178725444ae61bd733a806327e5deb021c088c7d7e3a32ffca00251e14354572a63287044f936f1a485cb91490000000000000000000000000000000019bc2760fdefb400842b65ca4f5be87e33d4b035b24eca51ea2ee43df6cd12e93cad90ca73c7b1747372cf02e54051fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd5b5722a43bf8097d7b4f39d81c84465032e5dbd16cbe58a0626b398d199eff5af56af77346b478ba3d2ce149178dd000000000000000000000000000000000e20932d9a58cb489eddad1f666e968970987824846d8a88874f54d35962dc5fb7fefd7c8be1c9ee3f88ea1609814ac41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f2fc7acbb085a7e3740f7a8418dcc7f41b72d79e7f82b84ac1c752afffd088ffb3cc18bab6db1e5a5402b81f4bde3a00000000000000000000000000000000000e3153cd124f94092e208edeb077d9f43a45e8d38cb6952bc5bd1a7636da46b60bef450690c850a0bd4137003c99dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e21f8f69d58edbdc36e496b85ce348613e59c4d2e3e1bfa85fe2210522c4a1013ad500b1f823cdceecbb51968f802540000000000000000000000000000000013b719ecf1e66aad74139e19b87a9401dec4eff7c699116a7fb52b61c0c49e2307b052e9d9e227a929c340dba4dec9911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a66b6e0633171f799c7d96a87c6337d9cbda4b585de118f3283f035f48d5769cf765030ed1ac7bd5feda2435da76f800000000000000000000000000000000025d5ed119cd948f1f07e4d8760e6e4835c4b034e3531a1276984b1741ce14f8c2ad590ebe70aa73dbb5e8084aa612fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100236883827016d7437babd245723a840b89522c9ca73076887571cb55d52ee7b6061fcfab68b2d3d34d70113026b9700000000000000000000000000000000139c3267dbe37bb7d3da9f2018cc99427e3d4d3acc4781b1a7e09a4b799b4044f947a9ae01481c54c57c686371ee878d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020a95883d7c8860415e4309613445372c3ad6386cc228ca5e54de213bfcb570ea0b63a806a444d7aa550824210811fd000000000000000000000000000000000fd9630c7094a8a2d430c45f3221ca9cff1a9bcf9d9725eff9f57cbf8040e9d3ef0b21f8f2454acfdfb09d8566417d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf96c729a7433bde8c2d3e048228c02ead5d85002c486f732175599b7c027378cd9276dca7f5c8c8bbfce18222c51a0000000000000000000000000000000003a822ac6cdf8363ee3211060fabe2fe7d45593c1c537a7c20ff675d6f3f9de4d411704d0ba1e208faeefdb3854cd5331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089cd71f592c3580d9fc6ed21e5d5982e99b8729397a724a0b4efa89afe92455a963ac2642e5fcefaae52e0a1c28483f000000000000000000000000000000000f11dfb4943ea9c159d279b36e9f0c20b15802db40b6c7cb7ad537d59e468698d421dad9078b66240caf03d587a6a3a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b7afdacad4183d1d41a3c357f6e1b286d55e5ceec500b1d0a3fa261b8deb6390e861e5495f430d5c7f658e4aae9ae700000000000000000000000000000000123a9c7745cbcb2da8283f8230bd54f844a1e500c03566c5fdd77eda6322b7e96d18218063c4d644ba7994154cb6fd061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ad7ec6006f03def1015a390fb9cb6a41467dc7a1e53621d2b2bf57be21ab21c1b6a1c5aefa7c98d0e5ac813144877b000000000000000000000000000000000392a799c068e3a754b30d08f3fb74b521928ba9de0b1b1e11fdb535e8413b66225bcbb67e5cbfa19db122ea342153dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005446d3bfa284b2abf019cff0bea520134b305a58b6027bae727160fe6fc26493f3549c963ac1596e95cf28147c3d28f000000000000000000000000000000000ad0d46a03bced7335cd0b10e58f19326afc772ad516bbeff11b0014b6576fd938f86fdc9e8d6577500b2b04b13570601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e694e5da33617f95e1a3c5d30cdc212f908cd64e82563844b4648d3fb9bfb560bdeb372776fb4ad2b28dab4c0da8d0000000000000000000000000000000001641d9f620cc262f55dcb5b4f35ccefb98d21b906681fabfbf84aecb92b97091f8d3724086294137e87e5e4a98a22fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001893e09510804b67b0c618f7aee666a93c2f7851ed26b7b8952286de4d0e011cded679cdb277c0e86a732ec68658ac7d000000000000000000000000000000000b8ee6a99893820a69ca99839ab437f5eec445ca73c69f1dc3bea3e5c9c2ef708a74fff925cc609b3d86a2017f35f72a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004232efc15a3a48bf5248570bdcfa33ab9aa37a1d5b1e011e2d8b3348305fd0fc63c0d9ade59a92714e66f7d75d08c63000000000000000000000000000000001473b1592d73f47ac8d0e4f9284f950b95b2329de61c59d992dc85402f17b7eda99a7b413a8072a55230f38947b340791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fda1c699f7853b1c2d183ab064581b6768b1d58a8dfb1d93d8503f812ebf27739c7eef8460d82c88763f9bf699c4cf000000000000000000000000000000000cd092694c5383d3a3a946c0fcfd9fdce84cd629645cb188c89cbd6dbe6a6d92b476d5b3aa1b7e39c8eff684811f2d111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fc259bf4982df8e330d1a46b4c5e6dd7c8f6ec834015928174ef0ba76f8b9da74629425044293985dca6669b7195ca00000000000000000000000000000000000f24008c365c1e3427c7a32098a7409a75fbca89f13f14201744cfec3a8da8c163762bc20434fe0cc1cb4fb0d9100f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d95b930cf40061611e664ec0bb874a1b5db1e2021de48112f674dbbf7dbb7536d09fae9bf4d04c14a154c440093466d00000000000000000000000000000000054ea1649303ba5291762da24c6b24cba7bb76e219c62fd8556d7d982d88332c93b4078d664b6b2a42f471e877a248831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b9d5f3976b63af77479a42580f820d421266bf584b4b703f75fbb8f189c95749c978a3610ee2cf513c1808d326333e000000000000000000000000000000000805133385f2c55a1ee95d0092cb703956f6594eb3c11f46b401edf9cd5aa0c1b2857dc6fd3faa39185e054b28b675e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008415d387ada727b7d8bd78a24e599eefda04952ef9f122fcaf046e2c3a94b8c8d77f7fa126ac13f375061eacd29c45a0000000000000000000000000000000001cae1db9825f1e38132bdc40728c875d6ce8d7f2c70cf7dd9e17886c233333cb0f5bb319bd6b677044c3eaa10a8a8ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f8ec61364e420302c7b69658bfdbb183acb44ac9185324f715fc3b30908932a7825467b520525b205eedb55b7e481f00000000000000000000000000000000164eead0ebbd34c190e152013e52680b1d9597a01383613a7530600afad000898245421a4c0991f6829cf0a1404df8421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d5fffa1511130cc467ca61423c22b64221c47c187e2de64d1939d4443e5c25175c862c65120e3e490fcf427c2040200000000000000000000000000000000184eaacf3ef66b2e57657da7a950daf33fd071217009e74c3544ce20dcc96c7b0ed155c34ab3d0d0b137092493fd44511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000763761cd2ebc040b662475714afe908ad9dd5ff8c3b6b5f9fb8e18daaeb157f03c448f1c3de705857c5df8081e07cc9000000000000000000000000000000001760103ebdef4575c582f7ee7650332c5954d099c0c3098322ae08554b8996a51e5124d8f7a0d66b821bd202480dc5101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4240f8dfdc9ecc192e58aea7bb3b5573a206fd26d52bf885d698b0507e7b1572b219d53e6128b6dc7e42b67d7009bb0000000000000000000000000000000016e633b88455b1f07c72f3a88330ba6e8d29906b88b79a94d13af2c347cc587c557ef61bc081c8be5961a7eec4f2d5cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191ab694a3c060a03c63d48bb16b50f7a913bded06f0a98c0a9decb62ae7ef78c8b5908da6691b8414a90a8b431f6e870000000000000000000000000000000011b83ea6dfafc7d0f3e5e3bf256b3be362904dff9ea1bdb84b5e867b7a365bc4ddc9066efe50b01e8d9bf030b38e8e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171981e948dc5dba3fdf614a8799a19be786a4572cdd9af1e15ce642b3dcc9bd9cbe8657597ffa580bb987932c054c320000000000000000000000000000000014def38bfdffa433746034a44e5711d83329677c1b5ab9ea499fc3caa8fc7ffe1961efd038b4dbdd84071621bde772031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000269898b8cdf98033a58fb9d834f89fdcaee04a1b194c806310846ebf3858718a4647e26ded7826f167e99030239290b000000000000000000000000000000000fc3b57be5af8738ba84e91e06b5a19fc507829de39021a1d15a0d65801a3e222969b53dfa49d7bacd77ef4d8978bb771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55aef891af94dcc17bc8bb0aecd5310ee5c4da39aa5a0ddb826215aacfecba2d297de893bb06a4877f3b678fc252d000000000000000000000000000000000135d1b35cae63f807483c1a0e20af28171869121fe9449b112128ba2d6080706e245be90d549e9af074289465c0cbb161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000733f487ea1c6525300ee545a04fcd4584c9a8036d4f879c68e980a2672740107e147bad96471c0edca4648ef08f200b000000000000000000000000000000000bc2fd976f9a0303ccca59bbf788bc6078fef17f232aab528d39942aa533ba7405f268d875147657ddec24603275981a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee05afe992efe78a9a27d1b038ca23b91290b5d4a6eaa871edf410d7b8e929aafc71180e3de18a337c07d5d67b580e000000000000000000000000000000000493ac823d362e1947ece5ef0d9df9bc3a2e57df6654695b47848458e74714be7aa43220460165c406eea167ee6c35941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146cae7828c871adbe7c9aa5072f70fcb89daac458d8a42bd8c6760153b106efa2e28acf477ff927f83b646afbae8ac3000000000000000000000000000000000ebe6851cd81741443640d24c1b3ec264092850c1ba5e5aa51bf53f338dc7b7e03c9053dc2fc2c48a391981bbcc4c08f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eec155f3f320144984231a7f62b3d9bcd7449eb4e5aecf7834ff39849ebcc04f2e5c2728adaa636ae119c2d0c920650000000000000000000000000000000018c891edca4b070e6cfc9f738223450a8e2ad8d3e79d9fb0d55132da4065f18df688005d33562626b486fb96779d8b8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a87625563e21ff386b5abca07f3cd37da21e7894282bfdbe976cd368815ae75bb316798036e63a0f274ffe9a78f9f1c000000000000000000000000000000000ce9d1a6fde6c871fdd5853b0857775e9f3cc4b2da096ed3c30d03c06cf440d37ddb15277b9a8aad30b2e140d24c5e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053f29777c0febd658180eeaa3479ef1c4bab87eee206697ffe5f4aa7df2634b659530bd2bc1040ec0531609a1ed7aea0000000000000000000000000000000002b5588b0b10bf9c5949ffccd537b802a850b5bfd01799479a74c553703e96f53296b12a3705419d8785a507e6077da41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff1481cbd1c4fb9352d735cd559f76e0065d7f35553bec072443b06ff322d05c1c22d8396764f63c5b22c87f69288570000000000000000000000000000000003c4bf0361df71bd80a3af7fa8d643003a11cd4548a52ab8556723da25178981f394d541f291a44ed2b1548d9fa229df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e8c573f9243b489b8e8e6b6e3812c25583b649ee8b360a5f9e1255886af1d2e2d9f8a4fef6e3820cba98c067205ba000000000000000000000000000000000ddfb182115c90b1c42bf5dd55e0a967285393a78d5f536f1a8e8883130295d94036622d6a3fc3a207ae0288336529f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007258cf66474c365868e760e605fba0bb27602cba6714e5beb06ddaad753706762469f52d74b49f928842b61c1364a9e0000000000000000000000000000000009f6b234506e26b6a3b926236b1f19b1657d294d921a9060e4f9027c7110110d356b61fb7afc1564af64951307cdacb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af45c841e5e7b250a99f93c38a0040f504e4208828462b9e1fe2325ff4a92d7a1a029f0445f87bd5bf4553ee799063f000000000000000000000000000000000cca6c197f69648f137b812797dbe2347b27332f88957717cb1bf38a9038d24f6a1c20dbc6f52f8bf8fe46dec59005e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001385b6d645a8ab2e6cba02bb99304362afb60c34f4c8beb423a0720bac5df622776dcef9b9e6518db15d251575974487000000000000000000000000000000000ec28f0df5a3f0c79cf953226916fa2ab18a7f24619fb52a04cc012a3b9ef0849d6fa56c7c58d3b0bd13283b899bdaa81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ee7bf8363bfb242a3bf89ec3937e8d1e6467185bbe04b9b2dabab3c95d0434e03afb715d4174e4d40c7b12555459010000000000000000000000000000000009f0f0f086f6742f3ec7745cfc32842dd5e6a778242f2645c315cbafd7628405633acc6de095130370b604023484cad61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eb022fe1f4235672e241737200bf507bf4ebcc842e2685121e4d34fd57a2b3a0c36dbbc1f0bf9c7fed0761a687241200000000000000000000000000000000035f0dac383b53c2d3c70238563a5b12d5b7d9d2588a660146f3ea2cccd330804913791a0a0b19f3844aba9bfe7b57e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000121e1d471691b4a738d8634a0bc890a6bc0d0e7fcf0d85d1ec0247b2975dc168bfdbeb67e20f7134966e749ed255c95000000000000000000000000000000000b04b88658407ba9d620a1212dd38259f927a2cc5925a5e7dd4abc4d3b1b1480d7ec897cb4108b58c12bb95218c16c6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c084b17e9d679d1465d77581f5ef539a896f0592fd3e78b35561d968f44f3929b59463ed40a0419da69e4cd68eee4f80000000000000000000000000000000015bf4506cb7c5a2a45077eeadef73c181e274c524ec2b83f58a54bb1d6e2e98c1c6f118ddd678b0768918fb4c87934201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001538f3284a8bd61b0a2e535f0de9d794654d474ca727377f4a9e7409a53ab2b260071d5e279e7bacbe1eec8525551e460000000000000000000000000000000018ce4751e42dd6b2f447827ed2222499d0e674debb5313006a7dffe52789030c711a56baed2f2e4a4d987cb8955fcf0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154347987d25ab3ac8dd7e681ad5a3a54ebbd4a32f7c8c3e7a8f8037a89ae5acf40def6318a8bffa7bd03d677dec82160000000000000000000000000000000019e06ffd432e00392437c06efed9a39722011984076f9f2b7329ec004e4510b89c4f1847dc39b4e2b61e8782852c0d111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9c045576392a4794b9cb8f3ede03e29b3bc9c6b90fb8abaeb4d7c3266997c880e099d3898adfab85ccce0bd6819e6e00000000000000000000000000000000007f04a9caff80c31d4f71a54755b47e762ba7e42a5cc31e928097f18ff36707df3b4e37e276efb6fbefb2732d5a41bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cb6cc6da249eece1cc3280a670f4b28324ff99312d9f97075e70e403f200e5b6c477f90c3bf9a1e5e3461bfeb7e1e40000000000000000000000000000000009c1246d50e097d93575a483fcb62fd93ec95c48e3590f64d9b710158092fc2783aeca954c740c50f2c4c2f2cb57b48c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c6cfbf3949f43b79c73ebbf5899322697fea7a9be00e7a7351f649fb8bf249769e3bceb37e96f7b7ccdf0725efcec90000000000000000000000000000000005dc908d0a24f37efe63928b60d3fd51eafe641f8baf3d106f94ca7efe0ecd2955b4c2f7d9019710368489cf16cc88711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f51d6c04dedb3ff49704c0edf7fc6f0e4b0f566289841e76f8e71732d8566e0e287d5cb50bfcd7a501b598a4bd852ad0000000000000000000000000000000010ea9f03f57ec7df6a7c8d7af2fe08e24a83f4190adc0831e104d78f664d630d7a30b848fb2b2d69138b46d749704a181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb81fef2df434848cb83ce22b0bac08ffbe8ae5fb21d08cd21c9287cc35efcc26cea01449f920548b14151a0fccefbd0000000000000000000000000000000007d5cf99762f131512eba447944d4d2d86ffbcd9a112367bdd223f277778c9766c891fa820f84dafc1e7c4af7d89fc921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006917b6c8cb8a9a0f47e43946ca91d6c01a321750c40f4d887fe25e5f507f341b9839fd1c80d505212756fd67f1eec3f0000000000000000000000000000000005ba65859db803b2a42f3c38e489c2d90aacca52d1acca6bcf679c87998b31ae09d52126f7207040ca5db9eb3093fe6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003301dcd4267b2defedff1a830eab983220cea001e39c994995d8a8567a4b1cab91b3bdf8987ab627da2ea1bff09246d0000000000000000000000000000000001630301d11df6c9aceae152b49ecabc2ef3d24e092e5ebdc3aeea336c4fe8afff884fb7a2a7882980ef6194e4f166af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f2aae64c08e705bfbf9ce6e909e26c62ae72ceee896605805ca9885332c84888e6f021e29ca3b10cd3206e30199e03000000000000000000000000000000001354494650b81915f2222195196562f6300edb365a98c11a4070536486ab7fd76e63fb0572ef06cd89cc92ea36e0ea071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cef06da387d0bf821b0f7e423b31ff13532f43843589ac5158ab803984cdc0ada3c3d7c48e575891f458fb385e06800000000000000000000000000000000123cf581408868375c7baa85093d110cb74fcb5decf8a31a79a89112ed3f80288db25346b11f6a8f95eca2b12d0fa5841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b62444c72bb045e20a83ecd08cd1a613833b904561c190f94e36bcca1dcf61a7728418dec86aba6526fad0045f64a4000000000000000000000000000000000a74ce3a2a74c77a2a89b9fa93f462e9045a58643a8dcbc154c7b46a27ad2c0380782304b43e8256ea69b19b671f59db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bff7fb056f35cf0be36ae2c7942766d5d5216bc4aaf34be2e0909a491cc0ca5621a52bab2b30e9282ffc093a41dfbbe0000000000000000000000000000000004d3db82fc2ac58964e66798dfa35ec9c6e3da96555bc81fea825ba3f6ed79f227475e5ea126d34a6e93dfed8cecea591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e6f4e96ae1980526153e9bd611dbb808c8bb5a1181cc42d2c6e74d452b31853d00cb773f7815604d93327ac621086900000000000000000000000000000000096af5bafd872ae25b3bffa7317c2aba437caa9b740659a2c9948f77133f33dd2a999b3c7468e3f57d6d90ea968648621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193bc968b4e79f3c472c68a899301e91a6221f97f79c3ea3b40b7399983a9fd715c2c61ea3639d1f605370f4a1e51fbf00000000000000000000000000000000040419329d26a67f9e22301e81d411a3f848c628aa4c4becc2df3a17785060a8e987b1e799c48f6740bf10f6d195f9f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689f3466d2fe5a0d10398ad7a824b990e595052ce03442e7961733dc596913e6dc84893b64f3eeee5e5bf2b4eaa75d3000000000000000000000000000000000f268947fff9888a352b2f6f3be56f189cd7376f06abab3c1f27d175c02f84c8177a7d246698fc7eae7f539e0a0b0f641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010db4db9c30521597303bd0d09461f8748e315aac2d557e5594cb9eef9f3cef978fcfbb2beb90cffffb8ac3b7182f54b00000000000000000000000000000000175f5aae55bf5b9002eaf184f2d284ca1264ecaec21ee15b8eeda322a362ce1ce1fd787bf1bcb2f952b4afc0ad3ad90f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d45945227b5794ce037ee632fbf3f6409702cc4287f03adbab87951d1e7531170fa60b3ecf55a0a5622b8b86e92d250000000000000000000000000000000005b357676a10815481b546fd62eb6fab5e04c262245d427bbc44763189366f6df0dfed8fbbf7f655319db2429330a8321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019d4c1ed40b88bddad28a5aea556685ab3e9edea9217d97896aa4a66f2e65301268944c574952fe1a13b557a7dca160000000000000000000000000000000001296404d30c977e3849aa239d63ccc2c076822cb9740e9ea56d271ed6ae9c750043950cadade9efa86da1a272c7880991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074c9176206f6dd1f06bc99c4467a381281a2f08d886f18dd43c0b1f0a2a16a3ea2d725b62a952e599f0a12f5eb14d5c000000000000000000000000000000000890188889990214284ffbdc80afaf2460745aaad98167bf95c0a7c446b57cfee596cdd1d921396a301550467788eeb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bde1c5b939147169b4f66d13caa17703521b6a97593f1ea4016638c6a1f8be6fbb600404afb4040e6bda3b682047f8000000000000000000000000000000000442519dffed255edc41d3c3b98cd8e8f596b83fe2e351269a3e87b23098cd6d466df1d74d2a1258b6c9c1ff0d2d5b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000641ae4bf58740b5f568303660d3a8e225797a0b907e1daa920c72325aa54c8942f4f4473d00caa3f4c060d0c96040930000000000000000000000000000000003d487164d426f3d174fbc7c52cb0cbd6f788fd09959f345af713bd9502b30a4e18392c27fb246120df81efbeba98a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d19381a524d7cdfc05bf621952b5c0915b6d31780e8d534c46affe608e054fd7c8fca0c7952e9657c0131ffc1062b90000000000000000000000000000000015dc43c5015861ec08277c938bd70c48bbd774009b757bdd9759befff8b11fb0666beebd469cec1d61cdcce5cab699cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014edffa83ee0124e791f040b6293875d17db893d35a07a8dc947370dbe568e9ef694b79799e8cb267e7799042faa9faa00000000000000000000000000000000068f6b2d7fd9f128b974222ee2770c0ec8ac6c632d1b86f711cfd7a5c0a07f32a459a891bc537809902bfabd79f692271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fa8717d35099e4f09f9c17684cb8de738638e85a27f00b71e5c78949dc388b5d393394b43bf2c5646be7a7f934d63d0000000000000000000000000000000003481c8de1b4eec441b3ec08434f69ebfb6cbb4e43bb8205fb9b06204909c484e9c3867e0481de0dd60252a90e432a8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5b2d6417bc6fcfdf57ec3902d3cbe3ac7bf1b5df1bdc4cd6131f4f357441c447801bdc8954cfbd5352e16975d0ea38000000000000000000000000000000000502484d6e79dbc9ed88e8fd02183d20e6986ba9d5f227a85c059f7f24281a9fca6c88b9ab2ecd88569473f5e19248551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a68ebd1e0661dd9d9b10aa87354092049e39f1c931f788bba59367242b34405d486fd399bd3b417375b6be3336fc1a00000000000000000000000000000000139a9d5d4139e6dc8e8dbb30169fbab33c7221467a7685177e06ef9e5aee027b4de97b536e893402395896966cc3f0c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1c05be27831199b63cb6826df96f8ef6a4531462a392b72d78f3b5bd9c4b728d5b7dda7c27b6e0e17e48e1199ac732000000000000000000000000000000000d1ceef58aa563f418b3dfc7cd136be359c241e682431734aae479663bdcf1a18850783e4efa6c29774d39eeba7c9e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104b8cfe6145341aec3bf9a3b45b6e10e96188a55e48003dd6bea09381a662b8ae3c447c4d598a6a9d919d182183a21e000000000000000000000000000000000636514129c6b1b57b39b3bcfebf1642bc813c3355eac48d4c8304a8e8f79434ae996a60f04484184b197b449ee44bc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaa998496bf562a6d58129b9c542b68ab9bfe8c426d1d44ced520d8f31ac45d5b831a6bbd81fe4d6ab2e388bee7cc5f0000000000000000000000000000000007f4d95f1c05c1162b6b2abf7ac64de43c316e8ed60e97ef0bbfca9ca763ed98b5945753e120fab6c958c76d95d6f2411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152a3e0282d47c9ae9ac663d6c293b626a6fa535acd717ed43429c20891f32a1708b7199e3f53ef4b6d2f9ac19ae37730000000000000000000000000000000018d1379178a62cf7d8a145770ffc4a849e40164c3bc7891f6f070b3e706640a749415cec8e16b8427ef032087dcfa38d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001280dfcaa01e08c4d19d1ca5fa0411dbdee1aace0987a2d46d4aece5f326127e3d1f9ce1994832fa2d9f66b0775256d50000000000000000000000000000000005fc30bfa50609e5a7c9533fd782c896057ef387e451c02016e48639f854d4bc486e47653b125f7580b81c2095feed341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1eed0e550e052372d4789cb44aaa5019ab80061b6fe92dd1b31226df08e05c41eb47f087a9cea81d8e3b2abad01f5c000000000000000000000000000000000c7db890f28176e6b4fa3159f513c9cf80a7d29739b01ed05301dd41445b1d9fef270e7e486ecbd2cb499c13d63908e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055e01b48ac35cd63f36cff92ac9a0f9b5ca9116a7eb56e1c60b565f000fa923ec9dd340ed584f3a633515e7d49e05b80000000000000000000000000000000019c79922076b58807a26acf5a36b459fa381ce71a92cb74307cc7873159264c6f687378faf160ddf7db1aa92c3edab6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171022a2a19e1c9d1427fee6177b14fbb36d02749da0f4b889009c66995ac7304f1f68185368a312e3f7270bf7e89eee000000000000000000000000000000000a37bdb345e7d386f2f71331e78298061f82dd7a01257e294998efa12bff96e50fcfbf09fdce5bccb41a8d15de8219091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfee584bd06bd0745a76974b6fdc2d2fed39b45439390dbf15df98501230a6310863392c6818cfcab1ffd0bfa1cb850000000000000000000000000000000016ed25ece3ab54abae5c3213edc7965543eb47856e2432c2a1150da9bbaa907470a128170c758b7e3d75c0eeaba8edd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d947ab8e88df817e30e9d74559ea94ee0283cd0e818e97365d406f1b5348b83ab25cddc886800e098ab8536d3890740000000000000000000000000000000005a5002f7b4005ab1afbb178f879dceac3f5c32ff092ba8fbb732eaad0e4a60daae78b546a85e6e5dc20475330d0d3611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152e08fc98d15738b3c94fb8d6ee9a9d27ce4757cca0dad46b5af0ce6eea9bb72c8a5f087b5ea16a1fe91ac51b4efcf90000000000000000000000000000000008f67e30596530097a7bd32396468f01b13ca9d2e38379ff4002c03060e4c5e41687489e43cbbf31130d38a48a6496f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001685d4255b9263e56cefde5b9856a406409654425b29435f688564e8058218ab771bc2c3a8021fd5d8009b9d23128761000000000000000000000000000000000ada6ed76129810aa8b5782c8f2106df6dc378f702ea49b1e498c3e430f89defcaadd43093abc3afe4a6e2572e387be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bad2c7543e8ebc1b6c77c0dc32ad8158698c4ef2098446e8da819e4ce80249d2bfdb97f446039c26b81e763e01a8e400000000000000000000000000000000041ec882d3a7b99b7f183e67db1cebd25d5290548635e456ad08f2af64740cccfa75e562b7ea0279ca65e579bf8e4d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fc11abb12abb6198a28dc8302df1b66a4b3c35e8081dbf00ac1d0a53c5ff13bbad129392f8dac47e12378ee9557470000000000000000000000000000000019aa0606f91ee5d4cac1af57aec63de1c3b7f3537af791bc8779229552ddf9076fd83bea1833081f6d80eb07c5139b861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b363d3731804651ed8267125763151d61ee080da5b824ee27a519511c7cd5ab4bbb19a5399b6d8b4b53f0c1e887f20000000000000000000000000000000004b4542c696d5f1a6fc4aaed3356cf06f9ddc94a5635dcbb6aa14bedea810ec1c3499a9283a25910dd1d190a722df8551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069b147d0515c46a81c98af0e612da19bccb6789df292e4ddffa64e58f21c78b7dc11b78043b052ef9a3986b9d50786d000000000000000000000000000000001248985ccb175c80d5327a80b2767f20859c79f269d9665cebb1971ec62dd3f264a3668a006b030c68b6b415df8201041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d294cf5233db65440689802646a485988568784a386acc8ad44678d4cf65f9c7fc924f0b49e71a531a8fe412aa829800000000000000000000000000000000115247320ce7db88ec141304daa513abf38ea07879f1956cd12fa2e061a02b6c23c3b205b920f7df57a21288c0ac8c4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002859426ae10f57f52cabfc45fa569a79a5c1d41db8be14f408f0b75fe20f79ec4ab9f7504b61cdaeebbbf24baf42bed0000000000000000000000000000000018a46ec9691bfa73c008e62043a33f5a20977c8c9981bf2c0c351979a53298b51e46346243227423865c2b2d5d76f88c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d0f4f4d415be96efe1a4d18ce23d9255c55eee28397db99b89cd6f54eaee0c0cd46f8e81605360347f6bd7bbf747970000000000000000000000000000000011bb8726fde9b35919b981cc97242ed83ddd1ec307d417408ab7aa8be47fee9ad44352d39bb5a48964e4edda8b187f181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005223cbd3622cf0cfe4bdcec522399ea39e1d39ff644ebb9bdee515522f612bee5d3206a12eb95bff1f1a370c50b7b2d00000000000000000000000000000000167e5624fc12abc28af6e4416c339a54b73339e96dbfd2ed1d8377cb273b5dc8c034f4801431759e485af4b1d9e1fcd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001511cf5cd570ed46a255269e8e8983142a0eb4cad944163135adc6c1a883c2f1092ee4fbb8f1213efcd0fc179abd6396000000000000000000000000000000001864300a37950e21686f7dcdc9b313a9dda5ae1886b800e2f9119b5a08616cbccca5c3e374ab08bf46161458b2ff765f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd30cd411122418dd8f058886e759dd595be44b0c6dec724b90fadd0940c47c81c7f11ddd97a4aa6f08a44f9b27bfb4000000000000000000000000000000000e0274d68b9e8f8aded68991271a6a2ca5ca725fbbe4ad42b79c08fd78cb518af381450be413064871354be3f3a29be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021937d34975bb30958beb45eebd73a1c76a8c2bbc2f2277cd19505b6fe9b33056a815fec2216884aea29370b9b9952100000000000000000000000000000000071d697c09409344406c3f54ef5464e28a31ecde22f59b7a46e19e2599f0e57b04866bc7e482a681954799678955a1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a202dcb1a878e73fce11557cae947ef4cabd761f0aae5c3a02939a2c64d2e2ccb1aa175c5cfae68ebdd27ce51236370000000000000000000000000000000009f7b6c9cc25f8382e6b6e2e7af60a67edc94169f5382a71eee63d47f8c215509bf9d6ccbd65aea71993a450f8598f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d3e4c452f97fbb88456308255484d863c3a3dc73895201f2d045c9ce9ab45c28ca90ceff7426653d45cfd7187e3adc0000000000000000000000000000000009e55f85bac752899addb9614bc7264d1b86ae04b72ae2d29f4386849704e10dbad57505f04c9ab599713bf0aac83d901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001809d4703fae998db9f1f7d6c924d59f0220743c7cc7e9fb619641acbf7244391989332c930b2ec37da597c0f56dc2c0000000000000000000000000000000002b147c0afce911f6cdce7bfde143d2504542acfebd8171b6cfae5b7e2e03a8d0e5b954b7d51907d2127e0aa00f44d891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017208a5255be77869e6cabf4e3ba403dafa18ddd9674616158225d7b66600b29c3ffe62119998977532a3f20d2f269e90000000000000000000000000000000008757c8be33ccd5549ba3d173394772fb8922f5f9926613b00eee9e6f9479808a085e94817a3333e5004221dabf4934c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af011abffd18c87cb9812944675637d6e383938d8037c7cb74081c31f2b7f4483f26956ea499761765f38527b8aad880000000000000000000000000000000002cb3c8f78e993a7855d38955e227248c53b3505fd1c64e3dbfaa06900b0c6fa67e4e9d31ed929d457c4b1f5b3fe459e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbc5a7427f728466117b27932c675f2189f7707b9dce67c2211b3a01be0a732f08e72e3afe69337ce49e27cfa25fa70000000000000000000000000000000010459399f8a687bbe8eb0431e2b56cd7a8f09e514a74f83897d26724f39e653c510dd81fa68d63fed2d21dfa474dc1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013529d7b13a056aafd0b87c9c0b6ce3060ab6282b63983dc60399ba1d1e1ab1021dcfb7e17f50e4fe69cc2634321de4e000000000000000000000000000000000f485dc475b6e3e308596ddf1b0020878adc2caa7f294fe07b39d4ec369817675f2cab8e2800b52264526e1f23ad70411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009107d0b03f7b51997a723e356ed424c97e32f00e3c06416df0b3051de3efc1e84f3e985063576bfa46265463c520d1a00000000000000000000000000000000017ebd4201600792a47dc8d998daef95e6ba1685214f2b4bf366f21c7022ee588385a41b774d842eb6e1176faf2222361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da2d6d1a7017f43215f310756978b9e7e28375ae0b2000775b1960fe9d6b5ab731dd8ce3fa43c776ccc1734014bdbca0000000000000000000000000000000002e5eb7ea8219fa78c522fd09035caac6b5a42325fd9e84d085068c5ba7ec7a29b2ef197ec428ea3c32fc052e4f3a1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108370886fc81b9ddf2fe348d3bbc42181ec573a69ddbf93610d8ec20f9e82bd0f8b76e61421601e7db771e58a67a9f10000000000000000000000000000000007bdd99a952a7d93ee1aca9a22e77c0cb01bb70aa3dbae20b434fb3afa18f9560c40ce6a491725826bc4792f22a8b1711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076cb0ca763335e4c2dfb51bf837b96220d5f202138ff070ad6f9608a537c30466681645173596a480a131d4d130251e000000000000000000000000000000000ed26330292aa33499af23596f7a42ca50556f019e553d03439808fd62d4ca56c0cdde8db3cdbc2d56b27ab5b65986041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eb317415d85aa30cb7b951e366e89e4d45fbf746aa85237f791269f88ea9487aa55da7c4296f15a74411bebd48cfa0000000000000000000000000000000011c15a139b03a8a0150f6233cc8eeaaba450d67b7d8ece71d7533278d8451ce4731405b48f43646b568c6a0448f17bb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8651cd97f69695eebea35f179da3bdf9a2424681f0170542280dee325511d7362be9f82e9dc1ecb4d41d7fe2a5e85f000000000000000000000000000000000ba5af9394a30fa61a9131a9e14bd717ef4e7e29d42b15bd198fe358a5bcf044dad874a14a3b9ef36c3e3a3023bebad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4a318b55f7eec8b0a92b9f0aacf078490b495aca0a20fb5269de26e0875473be1792288c205dda05b5423a2ce252100000000000000000000000000000000085b6e3136d2d67fadac25250c543d82c77c0e14411aa20623d979e3b01fe479fdb69aee82eb2f1e5eed06e051a202651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041afbdc3ed5e40a4cb5c680c90649eb0700aaf56dbe18182d135c8f6303b4b3268f0dd83b79cb49e4d2474d0c463980000000000000000000000000000000000c632f6e2020555f1ac1533348cdb5a2edaecdac7442184d77bdfe059fba174ab49f7d971859f228a95c7365fa60aa721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e0437bb084996a31c5c7ec5bf66f6e9e420e531c13541492f4782ee17c0e1d19955fafdaf6f048a78339211094fe07000000000000000000000000000000000fe96ec6e9b20766bc2b3ddc9cb4fc0e7ca0fc6a35aea941fd8dae6be696c6fd649d6c4d25bfb62defffda9c0bfdc8361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f9a9c8094da590d1afe9240f1e6c1d6db9db91da13b2cd2390a9ae85fb0a4b35a67dde3ef228e4fe832dea467132c700000000000000000000000000000000090b062266b500b995195b8595b0782ee2e495cc98b70ece63bd93e232e542e2c878db1b4503aa959605783385c5776d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003c00000cb342d7a2f8820d8eaae6679ce973fbd4335e5c84b6bcc1183781cc4cbd9b6915211e3d8f91f2d535c15d855000000000000000000000000000000000425d832f7745c71f63bafe808bc1eabf47d437f062e9c45d24f56c443d53da8f0aa5ebaf6cbf8cc3a30a2d5256926c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7c463a994e5e38684a0cd2e18804e1139389bb1c97f40ebca64921d5b4563f01607ff8b8db72fc0bea52da9d97037e000000000000000000000000000000000ebe549961d8a97189af51a2f35ddb524c9a796338b1815f1df847a71766ef61ad50090416ad6754f53e5f129c65ad991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6ab3ec387545505b63cf259fdaa5d0349af9f71aafd28f8028c30e3f3cee48fae58a429e4b55e37cda1994235547e000000000000000000000000000000000b7147de1e1b369170739edae46db196d119d44b095b94ea6558b0928fd1e5cf7d002d95b8dafde4219916389c0e860c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001610bf411998c812dae4ce41755f6fa7ed56adba9a88705eda3b6160203e1c59a291cd94814b327018a3b15637f38a21000000000000000000000000000000000299da986caa5f40e8057602322c7fe18ecb9cf4cbf5fa647e9f71939998e7124e35b8474ca809ed5abf8d7bdbd03caf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017989533f0795c5feec7a4d83b335e9c9b83631c7f7945d9fb4f0e7236c6d1d2a369ef2d1bd07e28a69d7ed50dd98234000000000000000000000000000000000cbfab2fd6da7897eaf46653634ea240296832d58cf9a44cc57731aed90cea4837acac8c647dba55a22946ca290dd6c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc8260c9a345bca2b604aad43053f1056f2092a1f6a3e36b64df9a0b2b6ba955419368a8b17ce1ec4e97034b87ad99d0000000000000000000000000000000011c7a849757c6dea736d2274d217fafb010b81f06b424f0012dd788913a73abdc052a74069a7a42865f9db84913774501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1ccb3f1db307856dd21e25a040053187a503118be78530ac0e9fbc4eefda70fd34b824b40c50161f920246ddcd6c7c000000000000000000000000000000000ec433884857a788428b13d087fb41edb292135aee62b9b2d5cb37d15dc9b404aa0cedd4027ce11b7f1e395aa89c7b331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cec8c6587e0c711d3001e7addf6fe7bfe855d421971d3bb5b3896c625fc4ab605801338e0c18bf9a1d3fc7495bbad6000000000000000000000000000000000cbff0998681c7f56512c848065c308e578d33ee48484c8e4ff3eadd2a80847f22047162e243d63af9dd2068a699b2c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d42629c2050ef74bcdb8c02c750217e869a9187e9ad8d1936a3c3ceb6c6546694be13ec615fc38d275fc5ebf0ebbcd0000000000000000000000000000000007a96de8dc0d84835e49ff97288fcb43c312ade8bd068e3eeb9f400658cf683a3a08afe6bf50ad7aadb75da248b2e8e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ae72f133107f1c136eda2e15c99f25234b135a3e875c80d414afce2b184feb2a7d83d3cc612c87d174cb8c45e22831000000000000000000000000000000000b50c2131e1f1141bb2ee355ef49487e2d8343ea51df91b3a2efaf9f4449e7a8c4b420cc10330a14cadc570cffce1ae01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010bb5aa3a38b214b4e66a581c7dcd78f223f0a76c075c5bf143b01986e855a57d81e00cd3a7db7585c271f61bc6791b1000000000000000000000000000000000cc4b7f98ef84d87cf5af2272da65fd477dc90b65dcad365c7c159f2f03f345addaab6239e470f9b0c289929118643ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000680364936095da7ced38847860a06daf53d13e3e69bb4a3eda004a166db4d39a150fdeaf7aac055e0850ba20ece1ba30000000000000000000000000000000012cc988c3bdbb8795822268b5d08cef78917b98cbf268585c53f1d4521bced36c37457d7e6d7c848a226227104f269e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff8a4f6b20d623fa9e2917ff681de301b2d37dd48e32702481b1a3ed0224040ddf72f62e8dd679fea045f480dc0ffd00000000000000000000000000000000196c78bdf3d77587a85ba4e749e3d7eb245abefe6fc099d328c67614da0ff53c1c29d60bd54294fbc803ebe1c25561d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016692b717e655b0f66e5558121c910fbcaa25b1a0199f98ce83bbb96da6ed5d3b94638714fba313130abdc8a4545f0820000000000000000000000000000000019a56dae4705a8da9b672bd35bc8beee1852529c373de4e550fb238ad1999b1dedb5f3932401e6b67d0a94d8a00653331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192d1938da60d5046eab4a3b26ae1cb8ed807aaaf8bf43d6ac127e67aade117cb6fd0b5c82241581ad8cded5401363100000000000000000000000000000000040346a5b1f695f5b4de133882b9de892ff6a7da483267db7671402188dca3102eaeee7d828f5fb4289608b36d49b8df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c3e30718a3873afc4f058170d371b03b79d3a847159127f07a27a1fe09549404fcc8a8b2c60f7ebe7409e7f2a6d1830000000000000000000000000000000016c1bd7ebe4bc3545bcd6657a72d674a1c7ec041a2172011304ff7655e3545b5d031eac06254c5f8d952629302b690851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da547a84940cdd7c85a4ce58ec0274831fcf4ec307e99759956949e8384538a83d393e552d989953f22dcc9adb27740000000000000000000000000000000001136d2dd68f13e28d586a3d47ad0446b1df3e9eb1bc962122f34f050da6a0918062e59e61d12e4008d0f0d63d1a5ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dba2206f76a34ffa8e9e3a9de46a226e8c9eee935cac3d9fcf0f72c86dd7fe173049adc7d38724710e0a25907d23d8000000000000000000000000000000000d21be8851a843f54e1b2aa9f8387d191c29a54d6e86baf76c5703c61a2687e2f200e33c48d71a2912f3f4ca61fd08e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002589c8f3fc1ee8f7f63ecec8f46f43804a5f03d900e805040fccfd9f3807a616afa2da6912beb16d5c19f2a7c27cbb800000000000000000000000000000000039c283ba16a47bdff4fe47fcc97ee27f7d60a6e5bbdc9290a7a8c1f3a38c6639e93e9d1e24c038cd49022740a5d9a561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075cda913ae121a30fb8182f0864933663bc49c5ed960468437864b020ae0bec0a796f4361d94f24326191514e4150d2000000000000000000000000000000001339d7cb860aecb489030049e116bcfb2a0fe519e74259001010c4e6a87aa9468701d7f321295c024275766814bfe95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001102dee9f6dadacfcfd95be363c31cbc15770d5231d6d56fa3fe44d7b66d2f55bdb0e76c3c391dff12559fc8c15d6be0000000000000000000000000000000010118f80ed1e826f81ea4f127777a330c37b3f3cf00895a3d1fddd93f6c384c5f94f7caea6f2dcf0c350b960c796060d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001874bcd13f3c4d0309579d65c63900df2a7b1670da2a994435c5ae533538350bcda11f120aad6a22c2dccca1b1061c8f000000000000000000000000000000000c1a893b0fdc4ace6215a252d099ba97a25b94a9bd3f55a0701bcd3d452b4902a0debca580d3b3035260b656c1536cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc3b8e174ca1787380088ab061f4f31b78c135b402c2ee40a22a2eeb3b9259dc5df933db7fd810182e8c9ef564deecf0000000000000000000000000000000003e232c28195296c6e35d20671488a55a2f3d80da643e80dd9c6bc7581a8955b14752d2bfb14b1db2400f79c3980fe6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65fa6490c6e06087581a1098d592e871aa199d0949cd6475ea47e22440de37edfaf0a8b3001aba4e40e1ec5e73ebb100000000000000000000000000000000176239dee037f5eb902c8ceb3e249d38baecbfcfa847a96135da14ed70dd57eafa813ae6d1e44db47e89456a2c9e366a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ccd35e9fae2c17ef5700a48a5f69a25e255604dce2f0a522b9b70592835fef4bb8eeb07b987bd5f5a757052a31eb5f0000000000000000000000000000000010f8f19613606ae513c2bfc94e8a4a995f5a5d68361d98a96283ca022a8ebde510948abb133a0645005cb188b41e657c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000776caebd22ae57add9970dc04488159ef860cb0d056ac2492b482ef49d6624c48b9addf90275815fc146f60e5e5e833000000000000000000000000000000000157cc6f6238d83bcb04b030ee0a6e47f64f8501cf84bd0f8b1d8550629c4e5fdfe32b6edc2f6ea4cd78117881ccb63a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a4d7d6283dd4d616d764c5c422830bf1ce59a6ddbb9830014fafe94c1243525623ffdac46cdd57377a5c38c586fabd0000000000000000000000000000000007da883c63d4edaab0e0678ff8d692978b41bfe0a1376a011135270d3e9a0778d88c4265a3c3b7a6a5da45b4527cc7871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eebd68534f5ae97d9361bc9a0b47f7a1cf586f838cd500e6cfffef2a6cd184188651054c0b95404f4161ef779150bdb0000000000000000000000000000000001e2b20e96d3c723e5e099b676081b0308d1f8291e7964fb453c4fe238b33bfcef01e07a1cf4868a37d67ab5b713f1b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001121891c2fd0eac95afd89a470e4a1f019d7ccd0f6908b41e024a9ac80d6c4a34a2d3fb4675399cf8f5a8cc6cae090c40000000000000000000000000000000011c956d02b47bbe2691506cdf82b3d1cf459d1111739ee37ee8aeb5e2bf8406ac0e8f231a518e33a414d4e65ed23130a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ec78804581697c8751930147f37ecec0b08551b956653e8858447c48e10da3eb4fd53615aa5e0bcff5d6073d46a0d500000000000000000000000000000000038b4a3ae508a3d5a076bde92899201b529acae5a3ca6ae275277b0141c3edb6a29f9858d9dc7f8375759ed0d2a2854f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001144b8cfc620339c8494d98448eb21e8bebe865ab935100c9f5d3ea5e90a196a8e877c9b63ed9bbe125f2d252e58fd5d0000000000000000000000000000000017b3f3e93615c26c3bc73db6d3af5b4ef5e3fc14dc833c47bebb82dc6afcae6fcdec1104fb02c320ae699afe8787339c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001872be798aa2001c23d23e8c7a64feb8107b2043573dae31e123d0a7f938a388c318ccdcc2af945a19f49499f1d59fcb0000000000000000000000000000000000d3d42d2d0bfffae378ce72e9f0082157510f9146c033213c30453f69f628ab05e558f5b38346bb82ad5aa52134f5ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb256230e85213592f666da9811e5fa8f4303aee5d2e6257eea078953b19afc857fed4f58296161bdb4321a8412a9460000000000000000000000000000000017d14f7a193f85c47dd9c54b8f8465580abca29e3d3194b6375cd20d065dad91a44617021896ed23d3f4e46658eade2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068edf905ed7d56930bb7fec40f2a5a0c11b18aaf6f7a6b4c76afb76ab3ac0505ef2e54309e2d6ecb53af9917338b0d000000000000000000000000000000000093f6e1c94d305f2a6166722aa08161dc54ba9d08dad068287e679c67716466daf90160b287d6eb900d4e3a69b856cfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ae30f44c51c9f72d93eaa5cb57838e56d6140f39677aff2e42c3d1f7cd81de3f6f8f0633622d562937c0965b206ef3000000000000000000000000000000001772a3ea74093709de27c109469316fe722a93907f52982507c196c4abd62ac96eebcd9ae368aa6f4e27c82459e228a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a1167415372ae14ee91998fabe33cb0f5a45dcc50213b62efa471bb2c9f575fb44e452bcf2c7fe47f8c64955f5da1a000000000000000000000000000000000983537af461d56b68565dbb1aebb9aa4e8202f999f3c2759e806f3e8704756fcafe83626544bdd4ea0f8d87eadd4b211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029eb274de08f231ab4bcf19e35fda133d963dec581c2a35ae77645641b69a72ff79f5d9b5d731a91b6c67e091c0686a0000000000000000000000000000000015837b803439fe450929ed595c8ea0511f49910837da32f2a777fbde95c36c04a35a574faeace8ac44115c63c946de171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014aebc2b7cbb72f6bc5f1472206f635954547c2626c2e3d5eb9da78a281b4124a694b649607f6a1cf4f431c1f5d686a50000000000000000000000000000000009f2e99512d7f755fcfbdf46820fc99c036bd31022ae60766a96204dc98d21f09d81d27ad6ca37a436fca90d1f8ab2e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c93101d9b29e7baa6ea300a6c7985fc71544949374e48378ef2f2f62415e8661f914f953e44658cdde80c225349012e0000000000000000000000000000000009cdaa91587019d24b9353b9bbf5de859117f57ab2265b24d516597adbfd8c0ffcd8a4b4110fedbc602aa160a25f89fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e6d2531bc535d944cd1bd9bde036e75d668cdaa846ec2068ea532bf530a61fe76c97776b6e41d48e4afae7a73ccbaa0000000000000000000000000000000013396ab6e8dff1f84a0973e8ca73f9ebc98180377472fe374dfd1753d790431f4f441d777fb9a808dd9f897cbda4002a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661bc08d0b55c05197d30d974a6127ac610675787cdd8f705e2bcd32a0515743f4b301a45bfaaaf2d6e0ab99bffa7fa000000000000000000000000000000000c3f6d5d368fea0d6e750d02babcee99a8f9073e42754498647fc57b863bd1391a58f19bea7994fd62201aa3f9e483501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcfc928bb356780ead8118d9b19d1d1bc35e88efb267c58fbffac856c163d19a2dea66b9c9ca5c6fa2d65a590f83db4000000000000000000000000000000000bdf79d8c23c0a6618506345cdc1f6de3e442747552529aad8cab90b8f4859e15678456dc7a2dc4759819bf09c155e351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168249730a9f2bec5166f2ca4314b8395dedece77949c77e13d8bedf039a54fcd3ca37610aa1c01656b7799dd0077d26000000000000000000000000000000000a1c74dd643fdfff2116356875fe75fb115102cbc20453f6bbd0f3f65d6793fd1e0dcaa37d8985ff3dff12cc8d4b88f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193d905514b5f698feef6de53f66a7d67949cc9ab9451f0c5bf781fbcbbf426f520e50b550c5c01c8301a24b9780c8bb000000000000000000000000000000000e18de08e995622e9d12a5eed19436e761efbb53657ed960d345c391744d75d672e9bd014fab26f344c04cbbe021d83b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a063d2f15ed07d541208752fb7dfdf89c27fa34f54c61e3c6f7f0702885f7687c255125e30077920aab70ecb70c8f580000000000000000000000000000000012a464dbc759a696e966a658e841c98e29d8c5472d78d0ee174b29ae56459d16ffd4e797516550a3fe36c629b3c84d331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000718bba2dbf470d31098a060654c267614b2eab220d38290725208c3b9a348f083c20b4af4d8b5adab01a904a72e25e60000000000000000000000000000000002156cab69d4a180697c45d25434191f8c3146496c66333c4fc06296fe9da6a7cf91b2ee06e7253b9295b5de160fc4151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c73c3d1943f0331128afb239ee83e10ce1a5b4a57d1b0370447e309e5cd5f23d6f37a429890af13b030e654d59c8c3b0000000000000000000000000000000012402518f71a204c00697b1209a9dbf16510e71a3acf791f49c2062589ee382aeea0d57b9d03888dc9a23f3e923e36651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159d5e36003ad166546e8870425b163c007a2137d753819d14372557e1973a3aeff979d36028b978ec0ee6769f79997f00000000000000000000000000000000174b5a0a47ec139baf76b9c344f84d8fb14961fd6b966c1bc4d5874801b202792a1732b467e9e61e936a4965154484731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040c0f68d91e7209ff7759da3b126bc71a8186b471447df1bba36b4968fa11c7562a46d8ad8af69d22e7ea691161b7a5000000000000000000000000000000000518107ebe282e9103fb5c6efc6df800402d4fa23c5abd61343dfb8bbb108b5d670f735dfeb4a85c44db92f98a3e7fae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3b99bad71aba858228fc9b9882dd8ca3d6721b0c735e354eeb9f4ed7b4a67312bdbffb19bc502784d54275ffe027980000000000000000000000000000000014be2752a9b0c54d1d2a6eaa4f58af8e8c4efe09455b42ff8e3d289205574b3995f9b67def3b3edd95678c05f93238c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109839bd46879a76879206cd65c7c514efca31778546146a23e92e42d157d78e19a35f31a5dad15401fca5f7aacc3e5b0000000000000000000000000000000007ce572222899d6ff5fb6d69f96d7a403066df9de6117a990050f039a51ffea4bbd52685ee82a55eaf55ad27b6bc68781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001828cc3b4d9a14863e6d27504296d820fd7f87fd77080c642b48c0d31ac0619df9f906a3f3b4011aa8123e3c0bf236c900000000000000000000000000000000059a7c60b5ab2a99ccec81083d5ffaefd5ee39649e4397041310ce97e59349ed20a7269ffea752603cd5d406d9e166cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e8224012766bb1cc64340a0c06a4ddbf084a5b592344a5c4c24dea4733167f67774b750efba6349fa5926b488182870000000000000000000000000000000015efc8c22a7709203fa52b82271bb6f6724a80bc2c1d174fccd0051ff217e1931dda18e04b88345962b19310236366491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a909b9d9e94890a5d92b5a74ce184004b83ea744d10f7c1833b40868467b200adecfd61296fd0e6e5617cc242cd6eb30000000000000000000000000000000019049064f046fe6c11c60fdb006f68da2d0984488caddd6b8af985e8af603b238a64d4c32c90bf288854c5f4d74fc45d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000973215015991b49a56f980ea5f5ca7cf2eb9a3417b2a7dd86035677bcb75095bcd623209cd69e816b296cefb97adc5e0000000000000000000000000000000009f6d9263bbb4f3139a354d640518b7524db7dda17948460972d289e310639de4e3886cb678ee97744f603e38e6e13771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c97b6ca92fbd4b79f71e3c11754c5d4307e56f90ecb4a778827b3a25ecd781fd2b34b7308b42472fb7d171845cda19000000000000000000000000000000001662016571cbc04eef9cd2987e07fbada59a06e174620b725af4cfa81407bfde7903a020c9bdcff71aca530e68a665471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002fee51754395bfd525ca9d25a3ed54bca8c4000fc505d0663d4a25d3d15778f7fade55d6fd4394e03676016cda7aabd0000000000000000000000000000000010273cb0670ab6b91b7360c072d327d2b07810b779c4cb08fa92426d67770729f15cdf2f5ce138a0f48bfd05d92751c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114b260c1c3dad5541a69d3be25a253ebf6a5cb093fc9ba5f7d70960ac8b98a2f630394e9c6e00d6867fb0d76f357a2b000000000000000000000000000000000bab53779bd7cb6eee6b722db6455a551183ad607fdeadc500f50dbac2022eef90c3aff3719ab27086e16cba5a8eaef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def3f2b1e5a983c99aad7e94c1fb9616ce2ddb1f4e2d7353cbd29c44f1ca19f064f899c53e06e01bcf9031ddbe1d586000000000000000000000000000000000c50dfccd743154e4a3c572bad3d24bbf589c0c9afe03786d60cb025f3a55ace2963e239c4a486306f4306f86cc6c3a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f0eff1524799f10be7e6d0ed6c7e192221314dec37c032891c8b49b0138404ee0f61b90cf7e38bdf7e00997d6c660a000000000000000000000000000000000b215a899022b8485ccf4cd519c493ea2c4e97561dc05f4bb2a228f315cd195e5c2489f7c3e719106f034f290b036f1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001802305d8910d466ed46645a86dc214083b17965c802ec2e73db7ef6c970b97c56c244c6db5aa566761157ef97e0cfec0000000000000000000000000000000017c643a5086265e2ff13bb8ae22a5cb29427694e4a05cbccb51b3687c4a8a6943875aee3a952f94d3d8577590a8c4a971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074ca2bd7660bda1ae9cd02f872aedf0067b172ffcf16b951e92d3c3445b56f8e5c6dc8c671de2bc02bd5b57155d82c000000000000000000000000000000000066c67ab1b08b2093fc47eb05424b1c4abd5329d980f26dc58153abb42b535dcc8138b9c57640ec0b19716463c1c04d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf9974483740905d5ac46cfa7f86ea2871d0c2c4f2d6db4f7d52de8a595a8e8f2483294cdb2ed48fbbe2ee995434bd10000000000000000000000000000000015452c17a3df3952c3debd55b948561973a9cc40089c32a2a05bf279b69cc498fac7b9acce331367072b24fd3c9c2b941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011eb7d2290c1e206ce8892ec7a2bb4046c74cd1b43d6a819e35ddb1e071800e16f258a202159b6d6ae2ea979f970bfc100000000000000000000000000000000053a83b265f58432e949d8fba46b8925de46b8a4729383ab915dedde6a151bf93291075589c046984f25f757124947dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e7fe57dd13da716bf208b075a03e0d1bbb77208a603cb5c75755f7bfeb1ad2b1a27cd7ef633d5c98969bac9aae0dcf00000000000000000000000000000000132202229aea34974d59683c677bfacc883e4756ca95bdc948e8d89e3d4798af82d3e9b1cba4c70bad8942abe0fc92ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c60c17e9595293c9da4d3aab05d157067993211a767f404142497e8dc1fd650bb8fc91f9ea8025714549dee63e932bb0000000000000000000000000000000007a25ec2e5064ae7c7e6211a75ca70b2e65b91db502bdce81e97bf9deac2e851e2c8876055f10453e640c0367d9cc3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023b74339080c7c0d9b06cd6a30da6695f93bcbbe4512c447a4ab0205a0ec2694b2018597422a38a0f0be907a451a1320000000000000000000000000000000001d88d42ce585009fba6f8682b8b9395c94240450e00965a6b8bb0566059330df8546c64d25f3f3ddd1e82c57331cece1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001808d6bf8917b4e8c03adccc5550c16adc99a5895ee1f63069b20365d2819a15d26a7b1acd173c432a18a09ccb924a2d000000000000000000000000000000000654897a2dbbf07db16089349490456cb4f7712e43cdf92db0881465754470f0ff3e41ebc263d285dc743d369ebecfc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168e8474b562b341280f09e4ef3f611f83b33d983d8d210a8bfe31b5194b3d80e3fd2ddc8f3643650b6c9b31d696fe0b000000000000000000000000000000000560ff4d614742f59cedb4c876a88a333b7c4cab8235cbdbdd2a55c2841405369da761b9306e1a09c4a13aa85aa8f5141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000369eec48927a691fa6cf8424cb1a2a553835b3bfe4b0af0635a1686c3b9bb0ef6697e423f3a4bfdfa5d998cf3b91a220000000000000000000000000000000001dfb0cde1496d34083cb91d49de1d26bb7c4531eb5d373e50761333b0c18bc2e654fa4af7132e707c4ff278b097efc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005060931ad227800a54e2c64201b32790aa09c7257a9ec8a5fc356f5b3d0cc8dbe7bb6b9d37460c57dbe15e6c1ba4c7b00000000000000000000000000000000181fe5713589a7576f26c8c63a346c1d64ac37227151a52f056489574e45db04b1fc2bc208882892e7df83126a7ebb241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c84ca06546be459597444bc7d5fdf545738bff29d3d4da98412fb1c663526b341736e69d6a80b4f93930fededa446ad00000000000000000000000000000000187eb7106ece8375ffb080975e85088d00a23fd3a8e6c8003f240d6f63bd636af177b5a235a1ec7b7c57332d5bbcc86d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000255347c160ff93b2466fb5f8259e9b232f83f1761e16dcd2f9558587bf702e8f787a469e6c7b78c57e9b49abbb2ebd0000000000000000000000000000000010e29a4b5601ffc6eb3ea0599d8760a49d4b1bbd689f4971ad6b669126d6e36c836513808cb988669134ef041b5b89e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000317fb47b5fb06686e0b5537e5e2616c39fe1ca926f07bec3e9cc8ac8336bfd0a3b45cee20183e65f67c6f0cee5c69b600000000000000000000000000000000120f16e6f93bbf3e32901602f760ca86493758299adce458ad7969b9f8de63f512f16e7eb6b19e4ddbd140611978d87e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be3e496dd1f3c33c3e3aa3a3696c57b8e4b3835510d8e5b25ad1cd7dc578d2f85c3d85a4cb002b23b97d9f3e491f80000000000000000000000000000000000c43fce05be4bc1e67a2bc71269272d714d51428b3c515eb592f51f53a05ed89842d2c605e8bfccbf7677d084a823bd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012363927bf7bae16993a67ff65ac896a5a9b40ff12913611dd6520eb95cf7aa97636c68ba913d47866a461464cf56fa300000000000000000000000000000000021cac39b2f94cfaa083fec833dd1a158bae451ff3d5195050c663c93f8275557c09890ebf937a616495903bf66979ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0f9ba1cb6002eb3c74b0c54674936463df314f7d14252b54d41331487b155947b6d1454d1fcaee28408af008d7d1cb00000000000000000000000000000000186dc743979b259ef13e906348c808b36d5c6f7ce5a59ba4358b0c2b55ef41e15a9bd61a0f60a410534ed0ed9cd839e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c4772355d938c6db5d5bdfa7da2ea77e3f7a2d16b00d443c6715914b55429ee93ccb0cfe348b1a828ac26fa16e491800000000000000000000000000000000130a3c7b7b9bbbbd7accf619b79d70a7527ea86384d722873960c09624a8a0a835976be87e5435316fac01a53d48726a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000164903d578c71b740294ac699e7fd532d3f68f394df7f3247f3efb0fbdb4730f768abfbe98f76b4e6cfd38c010cbb34000000000000000000000000000000000f39fb51098e879d5d80143743fddaf795f087c1e894f51a81eaac9485ce83776a64c8e006950ce1d1d6122efcac55191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a7510183a533ab5261f4315140b5ce33211d0767629e541f6c54235b308f841196dce0c3aa763ec800070e1d01240d000000000000000000000000000000001381e7d726e6a537509bf5d0bf42ea4a0b02214be7c601d35263df182a56354abea3fe2cf66537ee287cad276e6e2ccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ae0089b787a89f5af279cd09226822ca647e8b2f3eaa5cae8afa661359f329b64803c80f085847513f4a2ee9d757500000000000000000000000000000000004bd062d20f3c8923386752e4eaf25e04cd663e159a936bd13f557348b7aec2bcfdea8e461228894f781760aa5b32eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f60f4c9ec91bf8840504de305cfb50e51d8f04e08427e09ea20c90e76c44c72b7ad5fc493313fe5d0768ff8206f1c39000000000000000000000000000000000446375b29af37f6f85789e7aaddc65abfa20e6a3718344a1cc14bc3b403050b6615146ce404deecf1462b095f5e53661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d031768868ca6b46fc6e3ea13c8227e5ff8e8e17d5e75b2f1ea01733ba5c87a58f09f3f634041f03043b5ef9c9e849e000000000000000000000000000000001459dd257684155f65fc7eccb8494a4490dc4f2fcc6a9927a893601514762d41ef7e253045ce5644a849ed7671b588621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d231605846bc1d8905b2f6b9fcd4344de4d8f95f548d0bdc7b4e77e15470b0a39e5c54f58ef41b436c81e37046df9490000000000000000000000000000000015474dbdc6e3f625c0afef5809eeedcdcfd62eb526d323cc7e479667dfc24d96452734216cdc2e215bec614e3baba7511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f2bd452a132690991d6abe4b8f89e46929543e2f0a68916958a4a3203af8c4e4860052e657f7b81c10d19a94d00264000000000000000000000000000000001326d72dab35b604c513451cfe4087748e8861ef7c47aad96000657506a76f14fb5013b3aae1b713fbf4d92fe28b1d821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b17bedcfb1d6eb09f516245c42ae9b77d1b3ae8949f0f2a1195373dc719e1974bfc63b8592a8416e2ad5e6cfcbd9ae000000000000000000000000000000000d57b6cf2becd766075080e5b589f15110d1cd022748e0c20cb6cd9619dbc6d34d61bacaa3e2c52c1aab204673cfa0481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130908707aababa96f8a93dca6da8372e3609bd9ce960d66a40ae5ec76c7f32fd11d50638207ebaf7f135dfbc3e372dd0000000000000000000000000000000012719dd5a441bfb75f04c3f93fe8ffe60a5818304c15b714376386c9fe8a832fc939ef7f1abca620b0b0659f9acceeae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001651ecc0dbd2f856cb207d03c031c1ed99ba253346d66c9a39719443de409b1d4558ce945b79820b0e0e519603b6f3950000000000000000000000000000000003e930d3f2da36f3975da2a56a9ca9966a66a540a5cd80c4120d04abfd688c4bfe1b582f3530401fd22bda7a2c6fb55f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f14664519a91756a3ed32f14f434775ff5cceb59c622ab6173da3935a06965fef3e38671e6c67f2a7a520a8f2126ba000000000000000000000000000000000611e0970e39ca6464e5ab4cb25b2ec3839af444e5c8adc225bed2f81104455501588280e4ce92bfaa90930829e265db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022b0d04ab735baaa42e5671ef8722fe290669af6183621632a7fc17f7d94fac578352b6b6c4ba5d3567b53dfc1529f5000000000000000000000000000000001083a90c363cd99fc4821b34d97438cd90cd5b77241cbf86e2f32c6454597387b7d92b27fe8a6608e6d098cd458e145e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ec10bc5c67adf872973d5bb076a7ed574f7aa082a5699607f27021c892010c2bec0cb47955f03cfcc7d8b68657d2aa000000000000000000000000000000001113b04f45a12741088b500b59b25a0d302fadab1fd83f3b8bbf09f20099d2e8ce013c760c1427300a73def35fa5dd4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fa23bea1e8b5bb918188e249fadc6c51ccd7a839b799a8d0dce769dc91b8261eef17a50dc28734d04acfe7e4fff201000000000000000000000000000000000297055b49e217f6dc28c16b7e399808c71fae0807f7ce8f33e2edd72745815b5905f14acdd80d341b8f880f1d27e0a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189164cfc926d9118dd8c887927ba751ad1a60a1d8369f9830a1c43bd0258976a7456f89e77f3b9994942077508f165e0000000000000000000000000000000015f1873213c86c2b93e75afed9816996a4120dde402df086c4beecf699692c3c3a65fb977b5762dac545a832237aabad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034da32e29a99479a085e0100d71b0a3f0bf6347d5cca232a467582fc3cccd3bee64be61f6a35aa9501c585ad2b5cbf6000000000000000000000000000000001701bca8988c1bb17fb44c67ae7064e16840add6e92d0ab6cf249b8b9f5d2d1adea5ab1dd83c0befb2974f39c0b42e911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8f9b587ed9f7d1eefe6ffef0b697aba2afac186e3541d76f0cfd0da7984c5babcfaf3a73c477de59fb2c1f5a76aae4000000000000000000000000000000000fc16b37a08684e103508912aafce2a4dd11ec575e032f97dd26c96813affa2966c788006e976458189fabce39816ca21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032f07f0696b3016995cafb0763b43754d51d647cd4bddf53d4becc54a90c29dcb0a9bc7124cc9b404b58f2e7501eccb0000000000000000000000000000000001f8c06e6bb72af57ae018ddd657e862865a6a0fc03082f969069a31f65f6bae406a503dd5164cd1e925a06a8e000cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b9acfa7b11ec10c5716889ebec08d10a7dceb10c857fdc13b37f4f8f78b407947438d09baba3e0939497186205910c0000000000000000000000000000000009ef4dc8c0fca6d06f3ac0f93d991708998ae653a85589b193d3e15c8b65a5e3f1f9576179f561445e4ba5e9fdac89ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162e572c3e7be9c6bea636a2de29758545e2af06ffd99ad959537f2f32c7017c341b9c6aa70df6cff54acfd2f8d5dee30000000000000000000000000000000016650814e7aaff21659e1725546da208bfa14ee095de78e345cb25ed781000c5da1d4151d1091d4d00efa1e17d6b00f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcdd7e0779d0f46f7e4da9a6cd0c409813884d5d7e36e4a1b3df69f3708b4e21310d3d4ca445df1ac9e5c58cac101f70000000000000000000000000000000011adf274598fb43c1b1c73e3e262707d5dffe30fe8495b82ee606f22945e809722ea158b1568e3ea3734ca0d8333a2471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192f37e80b58cb2bb33f05f18754dd299c7db8ac5af87d471a0ef9f6d10221bf1d0bfd21ba60db8cc8072c4ae0f84c70000000000000000000000000000000001898fbc5940ec600184601d65d665655040093ce45b437166d2e49b96905885becc7b70d9ee237c5791c9d1f8d270ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005673cfbadd283f76ae73d4bc3b72b037b37023a9f257e33190844cea8b3082ffd9c1bb74d61aa9a7b36338158753c84000000000000000000000000000000001826845da04a262ae2d8f08bdb97b80d2d0f8c1cd1e791c20771324cb44cb587c304dc48a366c5fc24ef53cecf961c951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e846a549269ec3287daf7efb6ea3548463d91c28e7468998935f27787052d0ddb69359c1c52f685a1553befd0ec6f99000000000000000000000000000000001736877df21b01a9e8d32756f180520a8c4804eb608a5b0ac999d23526b5a9f89bb112fac090ff1b76137971ada21f0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052ab0bcd8cb9c3b83585c0b0c428ab2b6b5ae2e64fbfa120edeff4430fbee752225f44364ff5706505fc66f3514de1d000000000000000000000000000000000ff9d7205da09db792e794a8958f6ce7ca43bfae14fbce1141a0a2b38a0ee4616bcb89ce795c5afb4bef81f2b843f3071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135c1455a407297e8d3600e1dd0021b64c3dcb6c1a3895aa88fc1bac47e5e6ca26bb023727dec710395e38f3b5f832a8000000000000000000000000000000000e1562e13d17eae9178cd3c4954df8dda5919b05d03d74cf9586391c6a8d553a21981ce69110d70aff695915d465832c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127d87ea0d6e4c8484ef810fec45c0179deab9d4793546b78ceeffca20ca533395978cc175a9c9a7c69804f8dec3a3c3000000000000000000000000000000000b01393df5aa07269af9a43029a672e2e6029efdda750112e93a832c6f31c7aa0aee3fc198d7af98887c2f80cd388afe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aede57e01caf31caaa407d7d0262abff236fe6f2d1731fc5db6fdab86c40561c2e77c225d79f98bb1acef7df8876f68000000000000000000000000000000000948ccb2ab131bfdc95eb1cc57bfe25929d48ab45a9bb8f895a83ea96078d0fbf7ec35b2a2909bb404bb2568eb3eac1a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000325a3bf42bee14a691a31dae0d5fa0f656e3175d255b4c1124e8e3d8e78eb0464e142337a8cf5134f2a45266b559a460000000000000000000000000000000016cbf32077d37cd39818ba035ed67f4957ab5205f892b1a5f8000fc38f25df6165254b9437f40a7e254b2debb50bd77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123f7c98cf9bc8aa622c66a6f5b52c8a0d62b7d2618a6cc0b7b0560d7d18e2ae3b776b45389a12319561dc10952456df0000000000000000000000000000000019c318afd7dd391ef8e99ca2c27bffba6edb540ad636868f17ed6bedb90bcac71c717f86b79e3d2e4023dffc5f824f661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000878486a7e72aa69cc375a2f4dd7214472f95ba0b4492d22672fb98b87ceb532412acc51fd0ad78707a91f4669bad42400000000000000000000000000000000019fd50cb5efe933673f368bb6bdc57dee3162724cbb304fd75a6d93853fef0d19383def7ce2f3e24a1e2c33efd702d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000909e0bc2dd6236931960bc3701e82404c72d005b1ea0eb329e9a92006bf3c8ed60b750cea2cfb0a50d1d6dbc038fecc0000000000000000000000000000000014908067978b4b5122a021119d699f43ada6250ce270bc9ee4dec0ae900fc1a69de95205fb1792492d981dadd58b39b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4044d5f4f427abf0c3f08faa4d080151fefaaa3bda670dcca75683723f9e379a3937b92f465b986d50a2639da1e6ce00000000000000000000000000000000051a6001c813f658b1e39250c16e253e1824ece5b62830e0a3f19e17bf0d6558531e568e269e6927460435335e6c07db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001118428e0be902b21f4b5504a1e927a6aad58114d0f96e894ed1048c40e6558793cc2f7af0bc4ea59d75e54ca089490f000000000000000000000000000000000000d7439ba0a4676ab10fad19381ef132169d02c992d94101ef3d990c8a8bb5546ae3e992f86a1d9e301315a970462b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e32612d21102f90217e832fb7a00f1d9e1d4080192893a14414158c7ba00df047fc3c2df8c0b7bc4a5d757fa0c530200000000000000000000000000000000145fad1d7fc6f1b6088e534a61814c0b1d49bdd797cf2f7cfe62da954b91aff5ac2f645ac54e02705225ec398fc7faec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002710add587900ee7b1e7e12a1b83b6dd9638a57b5f9cd69938a74731a731ad9d8989fc10de16843c72a87af23e0057c000000000000000000000000000000000b0ac0405c468a0b1675e1f23f336b9725838f4d09099585d5457550a5e60fb64b1dfe5c2414c7ec527d098e26390bbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009872ed07f121a0d5f3d74f7bfcab9b8abbba113337d11e638386d2e8db61a21d12a7241d88c080209b00d0be7d06ae200000000000000000000000000000000103d2c2529febab2293309f86bd58a8fe8224c1fcb82cf1fc50bcfed5c6ccb32beeedebe6e4eec0df327f435f3ca36491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c567e5e8ed207f1ba1b86aee5e687665c6fd5742dfd970febfad73584e05f87922bf3e55e4cf0ef7a0abf874d163c6000000000000000000000000000000000fcd41a407159e9b84971ffa787a5199c286d6ba51072cad3509900be7348a8963941b4a34e4b0c60178a2c023b3f7ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dc4e6f93c80277619259f7b5afa46e693e4a00f260abc801c45ec1e389c527c0f3c0a3ee0bf74b072cd196a571d644000000000000000000000000000000000dd845e8c348bcc0da810f5fa5ec30b899b535beab3f0dff0949d226e199d28ad60bba81729c311c1b720f9701323a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e10c3ea6609cd38a58d398995878aba9b07c63f785b8c33a988d834988c92cc80094bbbd9f888b239aabe508e965080000000000000000000000000000000012b58bbe3f0ec9707dacda9c8d2d5c304648c9fb39cca9ace411e7bd6a5f530478ddcb7da560a8f19cac4ce6e80833691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018240048a347c33100835d095e9d2d967afd41ede3bb0850adf7b23c17506ab0a0dc2999757665f6de1d99c2eb51bf79000000000000000000000000000000000e98841ba1853b61153edba568fc7ddbdca7bc0d836c3436aa9ca1a5de51622ecdfad0aa72265da0cae241fccd6c5a321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c7be458037b16073e6ebc7b4b93f94a587e1702d09f01d1d52f62cf8cebd6c4132c536a8c986800c7e2c1e7c6a31d60000000000000000000000000000000016a58204a6043c70bb9f5810052aadfbc5a558ec4ebbcfd232a065e201588bb0205dd4f437921097a48a1cc24449d9be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa7c4703fa768e8ee89efaeebaac6a9f448b20c8d3531eeae8a134433c8c5f74ed95f6e135e4ad829b127aae01b5748000000000000000000000000000000000e8e83a8599d11cd433fd3fd96223ae81bb456de03c4219c1a3c9c327afb6ca7967bcc7a7a3a22a86ca04d3948e064281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed9fddffeb795c498da8ca36504024b7c0c2dedf2afa76cb362f80dd169eee11917e5cff391af56f3f8c6bc96d1e46d00000000000000000000000000000000001628c8d0c49595e45b272604753d6fd4828a5e726aa621b72c49af132e5facb48e59d4f9ecd671a30b22ab37dbeac61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ce613ca7baafb7ab66c1b948096ef3d0ad730410cec7fbf4fff3b45fc012554c58c0cd3953144973b35a06a43b24d7000000000000000000000000000000000482642d858d23a72bc577fba84ecab1a3e5a5af894aca65864a363dbdaf2118a1093e74f4c69f06bf5cd6234f5bba661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196753e93d84df44b86ebaf70bce6c999de08dddfbd1af42e63f763013509c30286046accf00e0181923cb866403c20400000000000000000000000000000000190bc1e4bedb42488981b47c79f1bccfe7de13c7a7ea02bc8e674a4cf0179a5bc78ee22a1cc9197b04f477c7b433e19c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000920d8a2bc9647800d415c9f813a7c6bfce10bb499acf61879c21c1ccb465e42eb3097063b81937a7ddc2b2f617707f800000000000000000000000000000000022230ed108867cd285ac8642dbcab6d7bf8225785f1a6d8da8c487da70ebc84aad9f3b53d27fbad44e8815e327004421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e35fad09353a91cb9fe89a6de29b85d727ac235ebe8b81242f762df7c2bc8d9a2b7a436297de06f978dccff857a6a300000000000000000000000000000000144371aa408110e49e8d254ca3982620a3f9849eecf3ec47ab455dc17c3053d668e2e6ddbe008f97519d3a8b3bf5db831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e883c3a400bca3cd7e685557088020716279fb6780a6c357efd86b22e02ab2b8dab4d884f4fe61a2526f020dc1233b0000000000000000000000000000000004d3c46e2baafa0b18a94a3f14cd298a7938bae7cfc8c349dbe9220992142d6eb2769da6a1ce110da76e8f0b5567f0601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ca49ba2ab6ba3e3252e531c3f26b49d6aa98062a876a3d413c511c56546fae8aace2d0ddd92031474f73844ca0fe0c000000000000000000000000000000000c78d0aa1c26e2928571994d63c6da4a0fbb80e48fb96a745f98fe0b885d11797fbe5e64dc2e75431dc437aca9ec85101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184d287f2f9c58be57bfb20ec1dd0993eb6179f2e53c62203534012aeeab5149f40bac87092626ee403a33cd01b2e344000000000000000000000000000000000c852d782c6dcc989108bb76694d24561ca4d02e8babad775c047cf2225fccccdddb9a61923cdcd959f7233badb76f9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b89776b96c69b669390e1bd33247385da080720435909170c4cae2fcbb7de6436f9677516050e5b2c13de9f5b2b49cc0000000000000000000000000000000013cc8c3c50ee26981cf618f89e1da2a6af493f5771ff15cf66abdb516b08604ec7519d239f6e7085b01d943b11e594021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2c58d86b10c8eb2925fc2f07bbc9e4e3563d21486f2746f28b380068ec31d1d19f27c7122eda43a9dd7e6f085164400000000000000000000000000000000101101f420c1b41fcdea7bc76713f0e8bc52c9bf19bf73e343e4cced7deb13250bb1770ea8a6d26e78a6f09acae310c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d1dbc4571d6ae605aa13e16d3f78da77fc464af28a032f3ea331bb8d2d82c3ce2a3104df384e7f888703f612e606a00000000000000000000000000000000099fc4f148250063f394acda8d43d13c700aed3b68a60461ac340f9395b1509db02f2029a532854adb1c7128fb7873981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a29fe8f833972b439e48ca0393e8816b2051d3a755b49db17bc887770ca4c3754051475c87194f4b339ce7c6d18c1c70000000000000000000000000000000008c8094216b05f7a56872b735ef825eab2bcf653501ac31f13470dce9726bda321bd82ec9a85a2f4a79ffc91762ef0061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000faa1fc4c89c5e5598a1c1ae08f310e17d9a2b8d075ab837109e7523eb7f8e5ed9f26d64736f74a4213573dadcb7de7000000000000000000000000000000000ef7895a0ca0bdb56194422e3c4c1599c75ad99cb0f2d24b624a8f90bb8a6f95b56c71dc1f974edffc2a7a4d22238a121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8bcc6296a3576179640b34cea2c1d214612f777bf7acbdbbcbddecfee47fdf1e552ba5a1c86a27caa33f8c9d101a71000000000000000000000000000000000821c33a9074a907ff54dc3268b0c701cb49e35fc4a8c7103e982fe3c3818b802d90c35597ea585d34a176ffff943fe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b42042063eb2de768aa8276dd86418a5f1aa923bd45f7a4cdc3dd49aed83f9a992fa3c00520a45a77ed27aa6d1bb83b00000000000000000000000000000000035315441da71333a4f09baeb928563eccac7f3d7b4df9a9444014fd8ae1aa21ec02f7741a41d86d4e6dad4ae78d5d951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018834d84f75434b8de47ad7f331673f63e6084d33d263d7dfddfcb698543bb19eef11c4fc63d3c8d05648e8654663af000000000000000000000000000000000146d7e4bd2ae56657b159da390048b40c4e97236aeeecb6f3631f702f5e4df67c36605370ffe2a1367559eeb44e7e0b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a4ae40f57bbddcb9e8dbe48ea9c326432d2c3a1a0d2a056437321fb63ab30613862750ccc795057786ec2d813176070000000000000000000000000000000000ef36f20877ab932d26539a8d2adee6c565fcaabf9c5da5cfd29a5898a72e806639cdd73dfa8505710a4bff8af1d9321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060f32d307b47be543d862e955befbbeb4315c55779af943e8b5fc05276418153f7501f7a1864630634d6b3058b09770000000000000000000000000000000000bd339d2ada07b2273a020e7b8c36ce412d8ce147073f0048df04d244389d509b31438406b9f14232853003cdcf88eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bf216cc4dd2c63ed802fc8b1c24683ae08ec3525bbbdf302d1a18be095c1d3fb5ec9d69cf2e1eb46a9d0faf419db74000000000000000000000000000000000129da7c6439ba75877704612f6fb7ebbf9d70216cdfab85af33e1a1917a859008062ec54b6d032e33332f8ef425ba0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b8ee9d3d16834bc45fb141afe54fc1903478cffd1310a90a928c81bfd9bd02be2279778605bb345e778f6d1af45a0a000000000000000000000000000000000875a6f0f79b4ed2b9ee85c4463c5def1ec9d68f6d4aad1d803ddc31b9d82485d459b952a2004759d858b80d8a5614011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000037ba25066090e0a63098955eadf82202a69465ffe414ffb855a7bba0c3bb19eb5e56c76e5c92eabce41a492a3def980000000000000000000000000000000017c20ad674ed9f81cf4f545095c1b5170bdccf3a50bdf5a1d334f5850e4bb52b65d49c7d0c2d27603d76364cda8746de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011fbf855c7425a92e45aea14d693d01f618ed4f617b2ccef6fd6fb064891fccc4458c52dc434014cd4c58877581dd2600000000000000000000000000000000190a957edde27f9e29aabcf1a48378f46b9b7419bf42f65bc28e2d5712e7c6a718a58137513b3e8f978dc92bf19106ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157947113a993c8aadf0bf2f186630cb597360e7f2f757c440b7d70db1fddbe4b61727567bf4fd1ce6e472ef21e73e8c000000000000000000000000000000001848c97f79db84fbdc9f3bf7fdea9415192a4ae90f2b79a778cd34f0b9d80fbbb993f7d2285cf84e063b5cbb97a445a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1b00c1f0ff8e4a0599328688444a792895fee19133cb01906299ee23e9cb893d4905ae7fa6e1caa8eba18529f196400000000000000000000000000000000117a2070e2550e7a0a13a38579b03087b78d90024c5641d8e8dd434058f2a40ddcf1e23d0af6a6c91ebce263b81f04241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac064716dd170a3bb92e9263d8ace63140b6b989f5d7416b46771d185ba292279fdf03e8e4a12a443487ef5e9335ba20000000000000000000000000000000006bec94d0e8c3c4c0cce39104c0ac7da8da822fda8eadbf95c87f209607239c5bcfede6612af5ab839301873cba1e7971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600215a1cf4bb254b57e03595e53899109c76b96e56b5acaa0f2a5518ac19707a36767ce7165a9c92012fab1ba1ab6100000000000000000000000000000000054dfe661a29ea7889a15f7502ed952fe7bcc6adb9507cab19f1dee1a076fc95493de9f90250b4707bc7f09241d999e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094666e7366f39ae104e01286236f4e6a2f9597d4abd16e9cfdd8209302123230b51a5f783d8f38aacbd9b84cbda6a6000000000000000000000000000000000143a852f395fd3abfdadb87a8c5ef670733928758a1770f5baf096601ea12c7d6772ec46dc7965894681d82e21c14faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186f577e517f4c44607d25beb80db4cf436e7198462903bde451d5e4319efa33c87b695be9f7e69edc108ebd6aaf2c0c000000000000000000000000000000001306ae1aaa9e9fd01e4d62ffedeffe7a85d004e2c955176662d4e9c30475932e55cecf3a5892025120df844225c06bf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e35cb63c5068b6d76d5337a8ea384e6546305a08c7a435baa4680067786ead4eb4391f93614683b996b13f00868e5b9000000000000000000000000000000000caebc465d3ddf6bab660774c690fc1ef892fa3122aea14b212cb0dc8d77eb44368e2cc60737811e4e7eb331bb7c20f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cf066da14fd6b291349360732018b14c8c7cc96d4a4e607f7bbba326e25ba3c10267a2fe7f85d6ec66650690bace0e000000000000000000000000000000000fb6b961d146856f1f0044ed7d69adcd945dd30db168670682ae4985bcafa79d91c7280dc321990b26fa97cb7fefc0991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd76672456dfc8dc12a770e089d9ddb818ef65f04e05b13f0cba5e11b07841e07cf2bbb7a7219288767aee95080bcc1000000000000000000000000000000000625b913a7e46d6720129a019f79c9a6d172000260bc36c59f24e6e4fb2f4acf42f13cdcb4cf8e1d3a91081e92a6bb331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b15afe48660dc7a990c1f4f988a5157d0d4d27491c289dfd9f4bccbd1da60fe9e14878ac06d21c3b390ca51723694e000000000000000000000000000000000020de3f7d26965a54065fdfc2d309aa37596ba6bc3c861aa7d61c3f48fae06b790c4dc83c65fad3937d502f217148e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d260738d6763176eaaa62c6b6db979079aa1c2625b7c0e820c14a2dcd87f8a46e1f5c7e9b30b905d04cf1eb1bfb574700000000000000000000000000000000091f4f8f28068dd6034b261bf9bcfd6cd37ebdcecf4b20c6ca93c2c826638af6c1202200b4ff357ccdad89d70500ca861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc5b4825ab27319bf5ff104789d5d5600162412413c265c03e41a7d8e96fc5b5152ed698a9acb55d2bb22b969b9af9500000000000000000000000000000000013a1f428f0ea9a772a8be9acede71142266f0b8a7dd361c8ca7e1135ebcb557e1e176308bb9677f9a6de81cc45384911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ff9448d4fe9609393af7a9b7f0291766f96e66fcf21e22550fd6eea0e78bfc0acbbf5bb976863bbc8f23d2f58e74f900000000000000000000000000000000170c45b1da76dcd55f2a87e159424df1f9eb0be537c752b7e3cef58fdc77f5a73951a97687613eaf52c0af80d9cb64fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084cea7382e79d557637c6f0d7a7a2291bdf2bb2ccc78683cb98d6f5b276d80e95ab03db8ee16c4011dde023068f0192000000000000000000000000000000000ba624e521dd57413dda37a56661cb41ee4dc8e9c8a599bc8f5befcd52e3e856d9e05837165ed65e96c943e0825f32161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b83593d1a8b5757aeac5a8e2ec2000684357b472e89b23b117fd8574cbe7968449dc735ad0c9786bdf1276a1fe40640000000000000000000000000000000015c220f4da549206fde3b7d22827589610aed2f2b4e2330e174ecda888b8f34cc611fe712cbd589efbd167b412e48f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ba5b20569c67c71e34a0b497d7f359bc4f437d6a0926e07f6d6c668ede731a80c0f321edad47f9d44d10586c26dff000000000000000000000000000000000a6b8d28884cf3ddf7f7b14e178c7e47a6861db91f3cabf05743e0adbdbf964e0052c73d2e91594c7405a265158d07051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d51e6ca12fa2bc24f2686908201765168ba36df1f05b01b392e58205ed619c2bbc32c970f2701f56acd3fd6ec26cdc000000000000000000000000000000000a1280fad6a768d2c0688a466f291317ab4e9e40ba672da5792f0d70fa1ecf71460bae1fae6f2e3750db73f6d25b7f211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007be0f8845280d75d68f995e1276d0e8edc1f91155eca48ca8fd0f526001b73d58023610ec4ed71583db3a24e45a600b000000000000000000000000000000001434c2d86cc17165d762a256a4cb6f2d8a1069103ad34c519bead5375698fbe51c335a7bea327c99b3c84158b78651e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000786ac64f8e785401b884b5e10dd256c05385e76ed4f729b7f79c054ee071fc77a21548f50533a6b2e88be44637f0a00000000000000000000000000000000018c982d99d622daa5077dab56373796551e697f8b7d02c71d754c588a2a559280d2c8340437b30b542ffacf1662941291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ed324c0d4ba4347e6e08d11df682873696f01ce1615bca089a2763cace20a326aac0586600ae454139de7e549cc800000000000000000000000000000000000d9139c89f55b10f88cbe91d9e2022f70821f1a145c7d6817e5148587bc53c6cb4c62e33f3fcaa76b3a5424aa16944cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ff97b0c1dca3eef3f9416627117485d15926457aa9ef6411d520c1bec291bd92192d792361a40ec2f3c1328d2833a800000000000000000000000000000000055566657e00529e417bdcb08d8ad2595db8b30e4de1401004645fad41272fe99645b6606f557ad7e0b32db45f2f516b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015768e53a0cdb465806b4b30c72b42848a21fa6849660c948b5cc88ab24f01576365dbef519f9e0370b92a36a5c1c2610000000000000000000000000000000010e3c6e2b8bf2632494ea2426df204a5266df85f3b58ca88e68062d2e7d9f513bed1950ea6e78536e68c959bb433a4de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2bdb884a5ff87218f1d4f1daf98094410d94c0f036f4bffa127434dc4a58bdf12849b45fa1f94e9d637f24ebb6e5640000000000000000000000000000000004127ae1ddd782d81459c289dd3f77dcf3193c2f682b1e8e9078157aaf051f02326a218c31d59f1419306e714664ab841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e03b4bb1ae15aca4d2169b012ef5f3311baa8b270980232e9cbe62a99c577c3d2dd66d566b236f65c36294e37205000000000000000000000000000000000854f3d551b677a1f48b0791121612523d8ee8e801f5b5b0310d78693b5514f08bbe2fb24900beca249230aff064864d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001021fb68942a846028108cb6fd58a841f08973520e024135ffd6cbbae1890d9b0946f3dc590db5f9f801f05827ce7cea0000000000000000000000000000000010011246ed5b8b14c5877cb0f5288da70a28f9ac3e8695db798b6125f00d24b2c094452d8f38776bd20ca1840dba5ade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073ed27525e5a6700502abafbe9cff73ba7b4b9023f3f151e981c45626526b578594fd11a26fdff77364a9717b40a3930000000000000000000000000000000017d5d660705d4a887cd611d42e79f3e69d38f94ee6752f39d7fed623fec1700fad8e969c2985f4c56c4f5e001a692f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f153ba71c6d6440539afbd559f0ca9de6e106a5f75b2e8b7919bc85836a808a8f765c720fe9db4f694df94593dabd40000000000000000000000000000000001f41a2bc99a77a840291338fa9eb83d3007ce6e45410754ceaac469f4837cf957900db0a517b4e009b4657a950c9e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014d58e09e57bd4b6f4e2f45e4af1895d2c42a296f73a731488ff67076269a2867c995fa3ca42103792254ee263df15d000000000000000000000000000000000bacad14f3727296bc95cab4e5982587ac9d1e0ff42ca164d8ede267a1567a82016d2e14c7b94a6371fe5ea100e14efd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024fbb9ddb471b24290d6a9cdc6ca0213b0efbadb621c27e1075cd832a290bff4c60d478f6d128ed202228826d05ca55000000000000000000000000000000000c64bc8a2effc3ece60a555ab093dacc790274ad287eb6bbaea983245ec86f155d42ce514d78245a14596b61d426d31f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142105d3e847cabc69ba5e7bc5d1196fa5034c017fd44a5865ec648bd9197364b34ce7f8fa32022f058834d556bc3f40000000000000000000000000000000001667955e6b6f57fcf2b7dbcbd11bddfb76afffb4a23457581ccc2b46bde4f51ec9ff010a712ed86134e465185ebcf9341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0ccf98e22389072725385a69a3872c46cae8fd1851fcc1f5438c20210df7159c10afefc12b5e5edfb6abb3ae2bdc50000000000000000000000000000000014a5bafed2b86ff707e2569ff243d8a0cb5494b22515462196ae579167feed106636ee9820fe0e8331ba3f66f6c0f8221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000399aa610ebd2f18b8a15d22f5a17a2fd5554a5a0601c80dc7370ca2c5a342c311eea85be3640d3c2a9573b758c67d22000000000000000000000000000000001606a920ba1bfb72782e8f3e15c13d6dc942fe23f6c50e68a25c24614e106d5c94ae4100f2ec66612e1b8973ffb202791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aaf271b89b9756d25b71d33cf31c75320d54b36fd49a07db4d60e4876153fd96d5bae7291f8d8bfccadbbe51eda11a500000000000000000000000000000000190552f52a8619dec191a62fbb91b9f69676939ec8f3b2a4ab8d819b1bb1c5cc3570c4b368c27d5cdefd4b27570f0db21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004491739f5c52361ef76cb2bd90fb935dada845e2434315cc0845c4af3677baf606b8fbfaf0fba3b8626f9eb8629a61c000000000000000000000000000000000f662b72d3c69a0020105f5e184a0048518bc9ceaa4c03b266bf7f1b44c212c3b3534f7e3657c900974885d315da01f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8a95dcb1778e07b26860689c776e3efc4c4e06e3bfcd95ba1274001680105be10047e4d23625ed9fac4fa70bc716e200000000000000000000000000000000089ea06c81ac54a76b0ba392c9ab2df5fc87a81989a13f2bf3b04dcab20aca35850a6430cf88959b62198035fdff900d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0885a0ece785b995056e20c5bff678557681c33dd2152089e0ba03bf5178b7ca5d60d49203cc73a0b7064df02e334400000000000000000000000000000000160d9e1bcb4119067ac0b68b533cc7ea7b903a19138dfcdb1869750bc0b7ff9177e7d38da687a908e1daad56cc9829a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c78af0e1cef2856a17cd14c2ae9f248fe56e84ea201a4475783ef85e0228db9aaff7ed0ecc55b129e9ac00217f2c20100000000000000000000000000000000181b0e369748694d7a08b49bec3d93b515c14f2081f10fbb99d7917e7a19da12b358fa5f6e502dd1f67342a412b2c4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf7a044ff63e2233377a716e1b64cbffa503a3fc6169069bc38174e19afcd1a0d592505742bf9d3c13eed592738b7360000000000000000000000000000000000ac02fd573f9ea988d30e56c24b6545515d6f3af03c982ff0a82cd4ac7ac205c72551e6151e7ef5eac53d1d0b9fa1e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c9baee6762956f7b39e817571386f751fdf1c6e4ac40b9eecbe6e54d2977fb44c87c00ec2e1c1537ab66aaae4dd0fc00000000000000000000000000000000094dbeff7f3297076968a93d7182a1deb76cb7a596008ba97a1845b4f14a052fba96401a9c44fcf25078df9d38492e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000667243375d3b84df7d3dabe71aa104f23504fbc169e473e91c0ad6119a5d4ff2820cdd7346d9cc79f45d38a292431aa00000000000000000000000000000000078affac52470cc57d47ae2c44e6560f87580ed2ca5f7fdc72e40085d33b11f5ea20c55506220239fdc8e9b1cf712a301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094c0d05e26b5d8b693c12a9323db394cf8549da95b5aa67c34cf15057ed1ca0ac09309b7c99d5df94fca93c5e8d800c0000000000000000000000000000000005b7948118f6e21c9f94709f97d971a61e64a04c49bf719b9e3799a714e7935a4cf140534286a08e0e726bcf6116402f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160fd88d69100714bd613d80384f58e431430d9292a0a73db821696d609b06e9f309c85a60b6dc02eb638210b2a26d9500000000000000000000000000000000021f826ef63b9d848ca2c2edb73e48c476f437c0939f1d0d1a00e03cb03ef1b7975db11be620deabc97253452dae23c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001882c6537e4001a19fd85d582e89528120bb66446457dd1f2ad739376539c4ff49059311a6bed322a2a4404f880d15f5000000000000000000000000000000001137cf840c4147c0047d40d475c78ab65ae3711e2d7a6a853f461bf7070f4895fecd2f95118cba8816590ba3ad9a47e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad20d1555fad0dc02e4ab6a5a01bec6c98dc7659d6e6e0e8a63e65eb712bc388fe14d8bdfb2d5fb33de4ddc1de553a900000000000000000000000000000000039b8969c79d5449c4c0a05a678b5475702cfa990b9f8b9db82c96d08432704d205070ebc4ea7b95e850ffb98d1c233b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000774e5e221649e135f19bf0b2072eabf8714413138b8c3591a6e6d098eb57d5d9f63c830577a56bb8821c13047b1113f0000000000000000000000000000000012d5b8cac25be18efe9f07be7f185eae73b7996c589da67b4f14679970ba536dc66c81ac2f70500abc695875e7f35fbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164b7ce95be6910597daa839664cc62ee7d0135ec0d7554fe0a15a0f5ffcaccd1206d3668297b5f871125ae547fcb1e500000000000000000000000000000000078df16f5ef148456d0e44334eba0f3ec0e7973ef1e8bca8dc196ad1c5218624427b84ae53b905ebb30236972d8bec6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d3a919c9347825a43e96485d27d031058e1d6fd407d38604c318b53c87e1c744a11c7c7d8ba12e0b42a18472ea092a0000000000000000000000000000000006d2e0c973935f0b3c1d64dab6063417afd01ff40a44f89ae626388c13f6062b8703fe2e4169f4794832fb26ff5869561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d948ec19e6e1851c7d6428f73f663f5ce8f73af55655c4eb30dc994f0a344e520496da240d14164b2eecdcd4a88d9a0000000000000000000000000000000015c6c46e7ef42a17f51b53dff689fe3c57c325103db00c4366a3f83dd6865ab84f21e646c33fc271c299211c02350a911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019abe68c3d541bd0debc1b578ea8b4d3ea3355fef68ebb42e84c9ce395a09a06cf34051b5984a71351c030fb09d05156000000000000000000000000000000000b901f00977952479cafe39be57eea06ad1b51519f8d26351a9737415041ec9604faa815a45c2326f3c557d307c15c291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001803b18c8b7e48a9b7123adf02c340c7ea473d4f6528c1b3f73245b9716d40afddadf28c552a442a2a8808e5dc448c730000000000000000000000000000000010780066e036aa27e4132b5e7499155ba4dcacf999dcd9929cce020e29aa4b310d96b592b17221fafd7e742f92555c711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010df04597fcc7d5ab26f51c1e78ece212418dc156da586cb29e5f300c7da75ace644654a74829e697161ace9b4aa30cb0000000000000000000000000000000013a68b30668270a99b5257a41950c8ee7ea69292bf18a9108a2cab2fd5daf6bd174111a9d383229b8c59c840031e09041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee986c68f5ed22afbe5ddf8920c7e5cfb75d0859de625ca1f862c6d8295bfb289ee647a82d58e969431ac33bce4f4c3000000000000000000000000000000000523a4ccd14ae836b482002dbbee0d423dcf7ed96a83f2dc64d0284e692ac45dafd16efb76cf417bc4ae556b1977ab6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160bd45f38087d834f22f03e9376f522c2a13eb6602f49b021c9cf08f7d22163a0cd11b7fd2d887a5fededd2986165800000000000000000000000000000000016559cfe667006ce075cb64f5c1cab437992868a24fd6038ea4245f196dc1cc7a270631b4711f401e37447566308c6831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000046a5143688a53446c5945b17dc454e00705e3ed855547f889e09734db51030548405bba1ce1649f65a156b183db6cf00000000000000000000000000000000137ff006009f34c6259c4b3f11b4288c95e8ad10f36ef98d4b86d038bd4407b33d42ff96cbfa9b7c4f1d1b7897d38df01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000baa74ef2afbc4629885fed9bc9fa50175367ae998c40b7cb9e96b2776e13a562a3fea2ce3e6f05126d3858bfad633ba00000000000000000000000000000000087b64d2639e16f7670a86e0e925e7cb8695545f402edeb5961cfde6e754afe30aa30732178e0025fbc72520eacb96701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166af934d78f24c2fc831e160fe1c88931de166013ba68a0a9c3f04ed39b95931b7def3c991bfaedb7fd4629c2ac9c6a0000000000000000000000000000000004e819b46457d7c31dbc87fed71c8f21243373b755a5b6192bd1f8ebf9767ee959fbd8b18c85e4d01f2f0223ef66a6451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1d109f96afdbe33174afab73e36554dda70ae21b69d5934ee59f54d85a287ac82afb9d312fb3233485e1cbbf6e31a900000000000000000000000000000000010eaf1f255887b5fd97a48d9728325553a170821bb534c000c195021091e42b5b388a31a1bfe0dbe0f8498c6ec69ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e9a9056a210f34c75264c62778df217d4bc1f409f7f989dd7ae9d2b7a874775824f1fe5ac71ba862abf4ed9c2d7586000000000000000000000000000000000ed9b9f04daf140a012c307a5eebdc96cdd9f4bc353c830fc68391ce5d5ba68474f440a44427e5af12f127bc77b6b0471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195de1ed5057c6c01919cff1c2190c8882c0733c3cdbe43430b4d6eb5ca4a5bf5cfb7a48c569025cbab58d784bf9b532000000000000000000000000000000001983f9d2e3ff6d96951cdd215c95ddc090c8e109ab0405aac22953db8742e11f29e32523cc437f47e1abf2cdd8d31d461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013364f490ff9f457d8b97040312abd45985cb83c2b081b204afcb0138c2f4797c93c50a5b4d8961d2d2b3bc40ae72b550000000000000000000000000000000016a9da0c74b7a65c047069ce10a5d0f752a94d7aef09fc606114136e8f3a14e3c1c8dc38b6be321c059384bc9715b5441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ef08e69ae13e28037d2eb600d34d2c264ba3a6da7d275b14d1a2a1ab4fce1c5110849777c3250faa2a5f0a342e97c00000000000000000000000000000000054551cfd637ea60ad1b5fc36afcec4edeb34101711cc49a034a48bae6847ac8e8150b4e13d324c269c6309e57a048571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b462261c1aa5f552cf9990e8c8e4141bf2dd818cb6aa8f641a09a9c41b398dc6503fc0b27891f4137bce25822d46270000000000000000000000000000000015ac04d212fb8b661fce091f4114a0a6e4a36364780f0d6bfad04d268c51a8fed74f4b274e5f1e10e47aef57e605a18a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091cf9e04feef995d6898274a2df5a7281e586b846efbec3ad9ac88cf712f10b4a6809b71707837145884ef2cb1afd2e0000000000000000000000000000000005e45bd05e7546d18b08d6f9a6dc5fa775f464aae3223fd4a63441410dda07f7fc5a1f2203411ba430f5104d2fe7e3ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173943fc596ebd53fa3222c3879ea88757d3da19e7856ae6f84ede4acb580ce75e73f5da011c0b928ab89416e96928e3000000000000000000000000000000000d8c10f28530285378a077729151c46de22578815a06dc63e152796eb1a9ff94a6f3134a131f4aa516312cd6b603d6a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000944dae479de4729414186d9d3cfe1b9e3338d2b7d695f651d3dc7d1e1a1a96568aac6c52636491ff180f746b61c11b30000000000000000000000000000000007188fb6f89814dd35e7da3f377f30164ec67b5922dff3b6c4c175491cdb78c7a0aec962769f6ac384b6101f1679b0e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e5ee07700540faf2ede8edd9aef167d8d6bd12b59a031b589b0a3298f0694276c918e7e729b583e04f02caf5c1bede0000000000000000000000000000000000adb6cec4497fcd610afa33294353c5b5ae3e56308a121620de6fb35eee75313ef6a8e66482af72e7dabbfa0fc7aa991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037fdaf03f6b01d61243ff2d23751e1336307fafeb73d4874d42cb28d3772d7e93c22e1226f33044a6bf6ceab2aa7c8e0000000000000000000000000000000006d993fb518dd43860e452386fdd80451f9fdf9e5b16c1502e86e2b8ebfc1fc87c781e1260055517a1b96beb74d1b3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009106f7b56dcc27b52e46d421fc06228b3c9e29264ab39c80433880de0761352e003968073fff44c9b9017d7f1e20930000000000000000000000000000000000874400363d26639c1eaf4a875f81bba7a6cd00891e19a1e38de97b6600e50d5c8be4c002d0e0b274aa1753d9d12c6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e709ff863e368314701a79313510676c29aae9cb9ef84729a10663263c89649d942c73a4f631608f0f9f5830049ca34000000000000000000000000000000000db3700adbc48307ce6fccbfac6b37ef4a62c1c77033b5869812d1dc11ab2ea2ad0392582332323e2659b6c2eed20e401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f2e6d62cac4b859e7819ed4b663e1436ad39d37e6fb935ea3ea8043c05b16923d2e62274aa41de14e470b123ba5a9f00000000000000000000000000000000151044c9ffd6be16be4867cf15d17914f128eeff29e0d4f5d09b6f1f02970bf009bf0dcda34d0c950de2368ffe3329fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b4494e8cbb1e0caff13c61bbef384884b34204b1bdbe7e8fcc5d43b0726cbe0d97f22a615dafccc988e55409530d00000000000000000000000000000000000d7d63665627d60e4e96c55541e644aabdd0726833a3566ce6ae14981d85bb4e9d89953a303f25f2bb0a9fedc8446ba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db465766f316464c1a371b2983783a45ce901eacc33e81f79a4dad71f5649a4e8f82cf26c9c55ba8211662ef170ce700000000000000000000000000000000016222ee296112bdfc17b0121f9b4dcf8690afcfff744c28e3f1b7db44dc6a64b0a69a03d4f6612cc5ea07502abb628ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045c5542264a9ca22b71a03913f5a084551aecfb0e3422f8eee6f9e05916ba5edbd56df66901c271d3f448a892434d21000000000000000000000000000000000832ef8d8ac6db89d5da7d0941b6f2b59cab63ba4c889ae1cfcdae2323ce1e777c2f6ffc3b61eff909f63f3d57173f9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2d148ae5f752b11e1c6a42522b056cfbd8fcc60f1ce731b757972829e4d5e2586a28b66478fd69158c6c62afa1d2fc0000000000000000000000000000000006af04048a891bc2650adad04a4994e9f9bdb686806d769edd6cf70611d28ea4a488d927dd80228432a184223b7a46ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb59379c0a31703bcbefa3af8a8a71b66742e7a64e50ae08f95526943321b84e130c77d6ca78a5357847a0845462fc50000000000000000000000000000000017bbd3e2ac5de9a22c9ae1ae13b9f025be97af6db0367c55801a9ed66cbc622579eb51521e4ac9f1b3304ea6feb346b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001805698d12e161ec482fbdec7778926f36886146ed99cd8847c5daec6f6aebe42e67be09695b2befe2c39b22a4b897b3000000000000000000000000000000000547f1161f62e6cc352e7ffdef1e034af90441d9f47b576e99a6a189824fea9400f7ed451bbd8636f626c745619be9751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072b803f64170fcc4e204e96d7a8ed30a6bcbd810bbfae4830d828e42ae9e65cb238d2768ee96c9eed4068fe23739de1000000000000000000000000000000000f26269c72f5fd088b993cc6f1600a27e296cb47ebe4ae557ba305c1fe89c110c78c022432e9766aa452bc5725e98ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182c1d8959219c2c7c45c6c2cefdaed170c701cab78f432da61e71709de6b196e1d3b54ce2d57b366b3c738ce5dea908000000000000000000000000000000000e1ab01cce625b3984466675344676ef904ca6d8a10adc0fd1f50a7cc1c91703789ef5b435c3ce207e8daee3cc7684cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005eaa90dc20c9e41b93cc9ffb817499d51ea355f8c0bf8c690d2c295c038adf719ca3c1b0ed580817a4e7745a2bae7f20000000000000000000000000000000008e6189c3440a0028d87f74207e0edbfc358e80fc84308492e6dda8490d50ce8018f9a06e2ebea4577a62046a9de4fce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fd1b1256db96ff920ba5aa5d2053b6bb616f40ee92bb87a5db74781e11868c2933ef7c13bb89f22e4fab0e8e8e9e620000000000000000000000000000000011bf2ca58eb4b9b40b9157570b9907472776f0f46ff284f6d22aa8b1e3c4a9d89fa8c293f4c541565ec68172296239861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f183bc3c76145ed176659b4e591bbcad73fa7e509c82f3093dbe0a443ecc15d62817931bdcd4cf9ef15738dd30c77f000000000000000000000000000000000e5f1d3846b9a6015e41598a5e02522619d3ac33bad98727c723ace55f19fb652d90b1c506f0fa926018d63015da801f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092e5a45b738293f8553b2bfde0dd252b1ffe9969dbd15a33ecd399d2c8dea89954b985c387b3ee40ba95687c9ae2f3c00000000000000000000000000000000037bde013aa0ca45ae22fa89579b3e3ba97a037396fd1e9144ece55911d27d10679658c2dbd7629430a953fb789748ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011fff4058f1e6c171a3654ea2058c2a880c236e01e083dce134ce8397dc640c4138eda38bf4e7e7ce9ca21f2fa3a50a0000000000000000000000000000000007a1ffaa9b7d18b1a3dc7e2a0915d43a4b86ee4a8f601afc9823a836b6f7cec48a05f012646fc8ea95fbb54e46b32d251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066765e4233509fa2d587a906f7e1bb4e8568a4664461d19709a86569a8f75ee5a67a4f2b6b5306ce7e911a98cb5025000000000000000000000000000000000bb5037ffd90df5a0d2d92217becad4a8519aef07e889b22107c3bdfa0816343a8ddc7ecaeea5be39d1f25a24fe11f481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f0737564f1bd45e29c052423ab8df58a258610d7259682b74427bfffa4f7da3e62f20075678fe60e6ffb7e9d18c2eb00000000000000000000000000000000063f537db560c480f43f6d2be395ddd4b404e2521ca707411e2a1eab5096a3ebc907c6b5d1e6e029c4e5724c69a7a6921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c6aa3c3cfbc3ff26b853f4e72cd6a0532a34b655ab4f19765b35fd6cab099674ac0560ef2f6b64fefb2a2c3ece555e00000000000000000000000000000000191c47355f12082b7d8bd8058c89b9d123859943d76a07a9266ec21380bd123234593e6f5b78be8fc76b38d59e72736c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011eeaa371882013e715b38fcbc590a9d5f2e291b0955ed485147170eeb22f4bd6d6437b0262ae43c84593a30fcfa03810000000000000000000000000000000010c1cd372df982c089032b9d6bdb1058e914ed7bfb68f5c048f872ce0b18b547316f62444f598b1aedb6eda9d310e2681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c35312b114523f646124bdaeb9387226ea2bb8874284bcd148c5fe66780d50be9e60127b19799d4ca65ac0ce5507ca0000000000000000000000000000000003fba228b9c3acd082b29aa42c11399007ec004dd66cfc28ec51889c487f43df432ce628328ca6947555eca25683759d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2f8455d719d941fea3aa3c4cf2f76bd61442bc928c8da2c9966f4b9f9f31d778723a3f6c1a9da667076289027ab459000000000000000000000000000000000b8e5f572457f934133f898370b5448164f29756416918539c2a9d060fde1044865199c226388cc629921f9086c210aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005a96e24a4994cc7ecf5550ecc6ba410da6f800623d6ca348c2a32f04390219954dc5ce1bcc661633fb98e6194a971d0000000000000000000000000000000008de198cf36a506bdc74b59376dff4f3e993dd58bfc8bd39f8a187993d09e2f451b8217b734e818c3ccb8948a014053d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c274d00f95cea7dba561156338053acbdb4f31bfbaf47b1b00e35578849cff908e661dff2e23193e7313463f8375199000000000000000000000000000000000f0d840155cf1fc84a2b4481758d3597c29cf69ddeb1f779a3b15c1651e2f32b36720f4ddec93efb9bba1b47ce0309061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001943c7cbbfb919839e46c47e9f19df641447bcad347a7ce756af314048488378cb6528c3bf932ad0a55402ad01644c23000000000000000000000000000000000aaac972ce7195298ccc8bfc7a3d2c87d5a7ccbed52f441aad7c0e7a00b06559149a6a5318133cd4ab7c6f510b3a36e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000072b0c76dae39b84c6eca2b009511285022e93d659ce55f7ad57049fa2e53ded33b1fe50f8d497430394269ffa639520000000000000000000000000000000008697092a9b93f29bef74753515df6dd650b05d2fea98b64879d0af85a69939c4dff3d1f9f88caac2594a280d0d017c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6248145717f1924cad4f37389a3aedf55f5088661a8160e15dc134b993c96d0d24884a7e9bfbfa497c5e572819f9560000000000000000000000000000000001365b48bd92cbe282b728e23df4ea369a773d51add1d8c8d8c90036f65b51bbab874810cbca850e9580ec42ed8ddbdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148765f3480592083250f19c793dbfd573c0b1a8172303118964538cc4ff5ae7a4631fa67278c2f9c1a10e3bda3ec3a1000000000000000000000000000000000587307541f6a28fbe08bdc685a63c8a4e1e6fff9c4a0744acaed202cb6869d795c2f2d4a777a91eb375f601dc550d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53547075d2df69025c158b9a1449711cb1cb00b99fc054f5ab1c3770b02447a0bdada9d8f23fe63077126be568b1ec000000000000000000000000000000000064249595c981d2054cc8efb60506a99a9f97264492eb8fed7766b52e0cfda1454756b1d6f28c9c043a35b9a36bfe911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a9b92cd11777eff0e2007de5c644f2dfd1c928cc587254469e51126436d376e549c816f3a554e40b646f092e257e1a000000000000000000000000000000000a6573e739805764878319a042444d72295540c741414d7502e7bfff83aca2ec9252c56385cca5eec1f848df7ac069281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6e0bce29f4211fdd5576b0c68569a601fe642a6fde71c16ba72f10fb7e5bd7e9f608710e5a7da540e73bda8eddc74a0000000000000000000000000000000009086878e3f915c3bc4d702e12a64cb9b419e8dca084a47ec0be0d646b2285fcc85f48c2df26ccc21d477b1a4c1ca0eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596b04c9c6471f945b91fe5435d3f3ae6d8153ca5d9b84a027a7c5a5aaa60fc7c4cc3237f0dc53cebefefcd8aed979f000000000000000000000000000000001521728e9b2b73f4bff6a77f05ae8e38e21d3c504a833d204f90d9c1b4bc69d272d16035718fdddf2526e47f0748996c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ee2c384a03fb9531fe7daaf872ae8860328c4a7c7b2601000a7c57ec2b0879e387ef2653215e5d39cf6fbd032f1b7000000000000000000000000000000001206972f4d820f16c691b70cfacda0272bfac32374ddd273d6c925a3ff5f80f0f1e247845e895160e15e2124bb7ad00f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168508a77dbabeec5ad9a0055b512b31056bb0b502797cab99a4894a6c0c8209aa3e42bc54c1ff63f6e8c21fd41a3763000000000000000000000000000000001668fc859075792e6e0c8e5f6d96f55163fd758cd338d49d4446e8af3b08160911d91279f3a2f285813e3d5a58806b671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e61d7b1b208a3e6be5a6bd2a92113719e9706c825b7cde82280c7ef478be45783ea7adb1acfe42266d8bbde294713c000000000000000000000000000000000a5ddcd761be47920253be7ea95c214fcd1627ad76a08eb5c83e214fe6f5262e1becc3739674df2cf7eabdd4627e306a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010395d32e619a91d17aa692a01a28c5da55acaf2436415c51d899fc83d11039ef689be0cc266029edd73a01b9ed3e20e000000000000000000000000000000000fe6ed5d39ef9a6e876d9f3e268b07bd92481c6c0dc01c2e47ebd2b66995174dc9b05d80d99e29af289163a7baed69021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5d2a542d4c8c52c1769b1d8a3dcd6c8919b4bf0d3a80061fcdafaca2cd30ef9c07eb363fea2987e0a1bb24b4651372000000000000000000000000000000000bf382f5fa38e00bd53289e74318b93c1941c550ee992b61b6749205820a541857b3cdcda2f4f3c1b990735f1d7237311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e88d79be7f26f9a68fe451d1fc66cda047e865c8420e239bf6c5018ddfa0a8b535fb6bf266d2e4be586ee1b24069770000000000000000000000000000000006cdeebc76068b695853a4f9734cebff4ed8e30a1a8cf4f1e8276b1d145e193fcfd5cde94199dd17893840d48fbbbc661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ce1aba822b75e408d960cebc757b1c132aebe888af361b9e73e1d0ed3036fa3f1f140e76115be4d911d2ca923c966000000000000000000000000000000000b93cd4382e26d0fa5e003ae5c356541db03c0786db9d6917b25a061a839f4a4a0e1a85a5c43f966ec87931f939fd1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080191784fc117543f72245ca290f29c1d983ab82a53958295beaea402e348750f424e2c5a90ac231184b07ae29f3a0c000000000000000000000000000000000467f272253efa6ef414180e32806548671c5e0e6ccb0fc920a116ffe1614947eaff98e68db09d8b47384e7666e173231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000898377b0edace3feb8c091692ea0e8c31e32da56c825b3c458172c98a7667c3a28329771c6ccfd80ae6776fe5e380090000000000000000000000000000000006f2a3a801b95aac32ea50e2605192fd10737e79480401289f295ad41133e63880201513ef8ce7a9234eef2b005547ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e37ea14efef3e5d930626e250ad788c96c61d92f990b6c32cad10d390cd08b7abc14d61f9bed0564556b9369328cbb00000000000000000000000000000000179844bab168569b4bc94963a9198ca7cc4dc6ae730bb4fb19891be107bfa35ae6d57e755af041bf59a85d59ddf5f0ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c41ef4708363dcd85a2517ece918da8d7e29337754ef28a0b67210b2af3afc38498c157d5cf70280beb6905a56515a30000000000000000000000000000000012935d0217fe0057f77742acd0140926de195f70c285cd9e08539be872bf3cbe0aa1b702bff7eb105b5ef6a4349fc4d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e95ec3daf371e4e1582ec1d5e0eac2dee411da2152052f231b4a870548cd088d7ef095fc0ff0e4321b5cb4d468c35ef0000000000000000000000000000000012ac24014c6c7933d819b36acb4d22b27447e538faca06aa06e7303210281e45f57c37dccc4dd0cb5177ba48094ee6101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000095ecbdb6849dd1059e30bf0c72d03e273400c025a674ce0388269eb0798428565fc4249760f0c2f96e5dcd73229ac6c0000000000000000000000000000000003358950ebb8113746421e4f85f6a11b1b9949f635408791e6bdb834e864cf695968b1eb6ad6e4d0da67129ff81e52821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000526794fda8e74ac3e48fa942eb38cd943f5cb61184b127fba8202ee6e5ad51621a3a331fd39cf7ac4e49635f9518d0000000000000000000000000000000000075281aeb2da660ee1de8baaff2d9c8dc826379c777481658eab54f24244df5d2dcff68aeeae6f58b59015ea22029e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190b5dc941762ce5e81f369c244f307fb22afb653e1ae62ae34a1bd07d17aa8fe2a1bad1ef595d06485683ebd355f4d700000000000000000000000000000000013c9192ed58f620f0b32c649054d1b9248252c2b30af6ea73a5563434b68d3cd57c7b16cfd9ff6b01cc6bbe08106b831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4d3f60cd85a69d1493e89040a62565f8bece91a2cc17f749355aa082a69dd78e8577dfb00edbca6980198c7e94946c0000000000000000000000000000000005bf2bb9b2974612a52a064859a020af4257a00f88aac05ed1e46b59568260dc7006485aadc5c90f22d48365d76623461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000930f7dd39ddfb1a99d675f7dde6b3677bffc199690edfad5a74fa459be88468cd1bd92c1440c2fc6917fe8668f5202d000000000000000000000000000000000a9cd73e8c2bb60c4a1c31dcc327d634ca87c8ba54910f31e10994ef8b45cb23a66d504c424154b9738398ab3f149bc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009069ad4564d09f68a84cfc09924a02c07ae01c9dbafee7d26bf0964a03f7deb99b05e6eaaf86631765e603d66890a1c000000000000000000000000000000001075d3cc6597f0d2ae57309c865fff945a9fae217eee4c20c70454136df089b4642a1d24f2f5b6664db3f2d081818e5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470c838cb5159717a5dd9c9aada90f58d4fc55e5d76f53780793f0be07d12cd5a12abed88831ed265849ebccc22ab17000000000000000000000000000000000df539f83ec246470169b2fe9353147084727d8c28f6c452901f8b6921447231ffd5c57095464bb84ad465a08ac170651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fbc2d256aff20222fbe7f4a9a21e24677fada6d05c3652dc7f9d19d5a04e1fc450212fe041bf15af49123b168f59e700000000000000000000000000000000013ae042886cd885e9380702885e8e05f3fcdf6a5897f64e4bbdb109b1d8983e4be03e7096740f1a12a405ee29aa8cb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89a783c39aefa705473437d40b7c0cd141edda269290220479bda76566aae579631bfd792e47dce00cec4c3c81078000000000000000000000000000000000192c0202316e179f13de30114a9dad0a0788e50f06aa7a673551b0366839fbe155962ac02e967488784f0664a7b37d4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfd9ce7c4e842e7a506145c9feac1557062b238de6b76b3765e4e231a16ce1b72e78c05fff18c9f23f0c07aa0d0bbe0000000000000000000000000000000000b3c942b15fa9336de467c3f50c18c8a50b23720c4e72eb4b2ffde36f9b74284f9c9f10de4fd31222bd97615a73b41811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdca902dad1b647de40f044a683d981a01092ab2a809b3cd138001ea05bd48cb570e9da8c06d163044abf37a0f87dd50000000000000000000000000000000009f816f5730d73ad167cf51816e4e3a5d81986c4a717eda101b3a2ed17b0beaa6047b9071caeecb5e41aa67cd733fdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe8387d5e818c5fa1d853132050b6e97ba493a59828468dbb9c2f7d7e794d3c0d14b49d939a23cd448ec6d7c06abc5d00000000000000000000000000000000171552ec8b1c6ad50902d8537a41eb64d192c065383372209a45b99cb7b6be987b1e9643fd25eb38ed40b54f0e8390311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661b5e254a083385955d4b1a8b1049c45ef7588d77f3811a2aa044890a3dd881385a40c6e4c5e12d7a5859f5fc4eae20000000000000000000000000000000004d15cb7273d118ddee9adf5d2d488f86dbfc2db40e7e63671f5d1fbd891561474e5de54ceb107904ac66f76168fffe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000186243414adf27f27c1c61870f2d10a4087d4e8c836861252653f614d494875c89d4e65d91f9c06eebfc8730ea2a79f50000000000000000000000000000000019ad5ea68e90f7ebceeba1ecb1aab1d3b50ca16343885a863d174c05fe9408c75ecb0027176f2e6ee7a9cd3f7956dd151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003060ef4c1092f82f4627bd0256557b4aaee4f2ab3f6527500f5526d839fd07f4d00398248a4eaf1eeffabe16c4b77800000000000000000000000000000000007fe60dcfec1cfed48d952a37da1fb9911e75616dbb409c55d272fd5e4d6c5422ad7a9217347c1a206846a28941d21e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159324150f19f71a8eb856c4a47c02a6bb86f7f84ca73d8735220f83a87b3cbc4293884bc6e8c69c0445ca6d71ef62020000000000000000000000000000000002afcc01243813dade2c8428d411e9a1452f0f821f59d6b9c3c476f02bde37c98c5ef296ca8c477a1502e3a266555c911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d821497491361921dec83c0525f309ae4c9f0a8b3da4d1743d09824c1c05095e2bcb2a20f070020dee2d16468e9dfeb00000000000000000000000000000000075e785866729323f90f63f2965d25a73e66ed2484c089363e4a9a9904f8e6343829bf4462311be378a9426fd4598a5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b03bde49547b7208abf8bca3fa5ca0448c1b7cc50559c50f05e6eeabc9db567418571c42df0c488b9bd32fd1f2d84e00000000000000000000000000000000004ff2a46e8d7aff33d6111ce1e6fdba6f9c7ce1a29dc3d345251a56127f85c0aaaa53d7df039db3a1e6cf98b7becdb241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001858bbdfb037519e8310d95317133baa291d17e39883536db0fbd4053f586d6ff24e866e2261dba0fb222026a24f614c000000000000000000000000000000000e330f9e3fe74ef2f210277c5337c76fc2db293f85acaaf8759407436733aaf114e0f1c43ae45ce74be8c8a07462fb501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001138b90339b000f6fdb2a8507c3f76047b1bc4986d6b15fb542e053953cfae5ae4256d34250874868b6c5421711d3a5b0000000000000000000000000000000003d1eb30382166de541160dca09986cbf0351ca8497c43dbd11f523680ca8fad96e1b97964cea518f0329a440d1111101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dae7ec19e7e13816d6ce18aad9c28b97cb452510117c11608fa60ca4ad30cdec4aaa39e9342d648e945ae6674da9080000000000000000000000000000000013e5c329012e31e5aabb4c5c9e6e8f6a173b59e0fab66616672caba5d75ff940241e2f2192e614d03db4b2285afd34181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001405bd97d0a326aec71bfb79cd8666e93fc2ae3c03de65e17da8118e6371ea8d99caa9ace4565f55e9d94902f069bb220000000000000000000000000000000003f405fa1903dea0ae421712b0302e689beb4468a6f880e9398515083babc76b0371f02a6f872f632c2db6a5b55f39961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193778d333502cb80b298659809854b2d5364628b0ee19e3ebecd015fc72050297dcb5caf8d73d28e88fe88357ebfd83000000000000000000000000000000000f010524dec19afdadad866d21fad76f5ee0b5106f4d3aa6abd114f329750bbe39393ab3c0df89b0304b9f2d7bf13eb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e249c15c5d45bf202828aa14ba91c9cba20596c3b6e3d32ecfdd042998e03cacecd8054902ca2ba5003ec7e0c7b0d790000000000000000000000000000000006e0d4a6fcc1911ab063dff8829037165b86b94be9e60b06793e2b7707d7ebd1df4949acdb7344a97e1c2b538944f8401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014df2092137b79d9d7bbcab97a8d0d1a85385645937f0aaa0dffb8deebdaac54151afa68847e9f50426a26481ae4e9910000000000000000000000000000000015506542c4d7be853ce94855c9b799ea9578f8d57098d326bbda687b21624f1087e5165aba36928fb83383adcbb66aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001301d6655e460aac557fb7934154d1ede5f4471c093586d29953efd2b3d2c7f95f68d45e0adc23bed3eb9cf60d48b2700000000000000000000000000000000014d40a1c55263ba560fffaf03b2c959aaa2f40787a3720608c0cf065e4c5f5660cb20c0d5ccd913c0eaecb29521f41941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080dbb4d68500f00452a4368cb5f87e8116bc9a0162c77f9a3e8ed8c247ff5c0434bfcde5a5a664ece2677e1e31b0594000000000000000000000000000000001454bc807afb4b75e3505a0f888720402383c3cd65e06fa125cfc3e0d73bdb3437db84ffb94ad3686a59f1b7a07eacab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f66963f609dd25d96c8f0253cdb894c23476d117c84ca6a9d1a5e0b2b504644282b11f5563ccd00d15af1d659fbd8eb0000000000000000000000000000000018b75e0be485c28bf03f96e8c2a49dae9cf0981d3b7f74321ac8ea92686df164375205fb9c0106684ab8b74329d9d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7ac90ef43108c1bb73f20df68ba71b48fe03ef64cc64de58f9d859449807c3bae15fe42aa73e53b7c43ab484a3dc0f0000000000000000000000000000000016cc1bf2773b58c734fd2eca0c2f64c0ddee8a470bbfa72660d0b53ba6e8c19dfd358a551ab885348736a9df5315e7801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a81b6c01a43c8aa1e113796f7fb17a166177e78a3cb17e28550040988d15a3a7cb9c44ae683ad9fc16ecbb8b1494ac4000000000000000000000000000000000349662ccd1655875c2a856af77eba5514dabf982feb5e320c4d19f86600691116404529d03917d13f83e110b94949d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f6257ebc95205fc519dfb270d32728bcfbd9437fadf399980c65fed9515109f751714a2c59914bffd1b9c625cb5b4800000000000000000000000000000000101b77933d4a59b6a9f96f1925fe304b90598a36384ab3173497984f94a98246910a1a64e8b7f4defbb1be793d021fa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c5c5120d7f88fe277a7ac52fd6b088009921d2fcb8de3c4b87c70ffef2d386833524502846adf992cc7bee5af858940000000000000000000000000000000018d99c6940332a3ff9a1cee7c7bbd661a21418e19aa76a26d253e81291dbf3f58b8ff90fdf5393b8b8ceb9ac29e137e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001374bd903a00cac9a983f21fb7d7af0fed9fb908155f8d11267ca12919a73a9f3a065a2914a3e9aa6da52b341910aaae000000000000000000000000000000001326bc136b3b99481747df7663ef9be2e5edad64062329379aa5a7de81d8bee3fdce4d5ea0f31bae6a9f6ef0a9cd054f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d5b3d1e854f14b7c09399d4103e756cd6b763b565338b844798491658009471580fbbfaa93234a62a67baf2829ec06000000000000000000000000000000000fa932e1dd1b9259c4963d2dbd1b8baad7ee1dca1974fc5d8b4195d6685fbce02e4dddc88a2efbfd4c37a964027fd9881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbe15975e117331bd3f67bef1c3984792d3ff9bd54cdd4d743e854e08f49a4b53d9995a737d2260e02a9f5c006ebb7200000000000000000000000000000000117b488f467ec590d2fdb428363b14d72af6eb2f4aa57d7082cb0cd0ae94230b55613628ecfcc3960818209a34b9c6bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011aa5cb7bd6c84703a0ac1b4888ca8980b825b6064810544b0a427da4e62a503e960d1cc05c6d7112c01b9f562ca86630000000000000000000000000000000015e6df709464517031c6ede36fd7a3c8e016df0adab2b965410d920c87d753cb78541debbe0109468fcc1868a09a129d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001981820ce5a9cd926cab53c5fe1fbc06a1bb6ec7988d63fc00fea4a19fd4d26bd7c2e79a5ea024d0538265169f7aa5b400000000000000000000000000000000153c675f6c2e8c90f18ab15802d9682947ccdcda7f8b585cbf01054e548982cd221d327955b099a39d320e5b221914581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037f5200639d1b9d206764a3f0e7992ec472c3925b85d842ca1568e57d1af2cc53858cb3f87b495332f9af764ca51ab1000000000000000000000000000000000c7042ddec8091e407c0184f0e886225ac468b1fd8676e578dbaab46837d9263ab5fff8df3438e07d245f8f41059392d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2d989f81b48de70e248066514b70f1802650707158115d7d80f2d9d83889cd9eafe7d1e3ecd8bc6735cc57cce9f563000000000000000000000000000000000e89a7ef8215bddc217d659a7865d2061b99a702a9359084a8e9691f9f3a236f53625eeddec98babdde1ef5ef7795dfc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a2cb5351f416e77d89a10880a81de7306b695c8aaac896feeb592c17c483074dc8cd67eafaf7ba28e40c924e34f0d400000000000000000000000000000000058342c8a066b34b0c8b84e3588b612b72164e4ea9fa8bbe12f222c9ac5aaa7ba747cb718517522680c1068daea10b061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a57154444792db7029a46898bf1998652642adaaa69704d5e7256624c2fabb5fb9d3730c817f9cbd4f0535835f447d0000000000000000000000000000000001c9797b58fdd44aad834869872bbc94acbb7d767873de0f6d0f57301d30f82f34d03dfbac6d55bb68167039d80557b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d6082d961f5e8c92e6d20ccd485251eefa1bb89a8131b73dc786786e76aa8cd785b85765cc0d20ee4673ce437f054900000000000000000000000000000000153029a976b9ac56105dcecdda398daaa2fdf59abe05419b8fae0c34fb19fbfebf8f093f250b587468080044cded618a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026736877a292b8d97308b02b1770bbf5bdd3c959635afb00ef54e72ff0095330da53747093821b76068040b3a2d9d030000000000000000000000000000000017e44e0d4bab9ea67f98cc482b6042e4738ca966c440927f7ac8044c6e4a7ffebbfbe41f098058f7b961836909fe88231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be1d23ab6d11f9ff43d92c274a584b5fb90a25ae5399f37c14a9d7b07c02d3facc194ecf7621a11ff0e602e1e84970d000000000000000000000000000000000cc9230abd2cfdda07ba5e1b2a9e7f108cb231d0ffbf06be4376a1cece9b7f989376482e5682d126e167cd26d71ad7a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175a629de9152fc2f77b341c062872f0db9cb8d9f86e03573c343c85fb44225422a8275c7f1311e10d4db216e16e46140000000000000000000000000000000004803ec7b5d515417bce02670d9a8a23f026b9a75845f3caaab6bdb00f7459223fb6f8ea76888667f0dc05a69e9475e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000511817419050d90bcd51fcd8913ea1066bc4319ee2e114ec87cd100eec2278d28db82767e5fdde3e3fa2f5beb4e7b830000000000000000000000000000000007bf3f989b5b1e8a537fe560a52dc025789fec731a498fa61b99894cb1d13338309f49a1b78947caaf5bb2a2aa2be1a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001079bed1a00eb25d893af30d4337581bac578a11c8ab81de4e3fcf446536925264be3103d0208edcd7ffcda41b8b2c10000000000000000000000000000000000647606a0a95bbba268f8b5b2c2208d25a3b0cd3075480455d8775c30311c8865694a50f00c915d667e7aceb9ad468c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a067ccbae5f18e71acfd43a7bd5797e8af6f87adf0adf6d1c5878998db8a9dfd10ecf06cfe36f1068b5e4a257f06e00000000000000000000000000000000001816bca0a2eeda3f7a8d2e458b5efd2199890751bdd7780a9c000b11ceb253ada24d266b0a58f1d195f5577f771747a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007be6d6a62dedf527ffb005ec4485092c683c0d2d23fcefe8bf802c7eea1bd976ca0094ae348fd96019b5f05e340ee41000000000000000000000000000000000c91e78075e8b55388caf2834dd67e627956e833f502c5df9faeb93d420d6049e53baf7de3232964ffe6156bea40a0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015df5618e0709bb7e205426bcf2fdb2963dc58b23980b7b9090dfdc4a66c582be60eff275a4825b8138e61baeba317500000000000000000000000000000000010d3136d3a1b43042fc946cd97e5a46daf305a4e11e64ee8d384921472d10b9f783fba9e6972439b462a91043849ee8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ad0149c87537c68e6ad8ff78ba2a209691968a5ed6ea2def40fe7d2d69488ae19c24688840cf2d880c6b15ec9b404100000000000000000000000000000000160c3b7ed995b9d3b1d29edab8ea2660b1a5b59627a08f57c54cf328f6379d5ba5e1a9532a38b09a850f2abf117a38f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000277b290fcb8ef1381cd44297a1d3bd3a41e5fc0a6e2f69b33da7b924d487acc5c9048ee2157a61b36b25039d63487fc00000000000000000000000000000000035e64315e574cf16896373fc3f1667563735a8552574026bcca92390e74cbfbe5aa84f872fd8a2403731a0c6d831b591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019072d7addcaf9e8d1cf24fc1920bfab0a85ce1ad7157502b3c0a3c04f808a1f17f7d241469bfd2d5a13c2860ae025630000000000000000000000000000000001ff345f762be619f24a165db81d208a3bc005a01d96347d76c64551f830c4b03bf6726e80cec5999973dc2fe54bab561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000670f7b47e3be01c0d248f3981d4a87dfe845924f4d908c2519cd100c89db6dee93d229c42af80bf2a05cce8ffa6370f00000000000000000000000000000000187ed7213a20a4d720903b1944a2592e8ae25914b9d67f99762427c17cccbcd512641001b1750cd19c0404ee36e88f471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e6d78d76356cf2190879248a6cf520204f147b429bff70141bcd8a5faaeec86993a7a9eeefebed30fd9744fba466b0000000000000000000000000000000004ea428181993b93b472062347b1c977e797cda1baababdaab39cb6c6eb2d1d3718a654f73e7d919ea505423727c03d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093ae2a1ec4618c4b39800e6abce822f8cdfb991d0eb6090dc0a6c6e96954d651cf974addb619ba56d3251de6e3e2a81000000000000000000000000000000000a70348af1dcf1c1db01721a0a90b26c3c63314a5e67e93bf7bc9872e8d5ca43300648346248d043030ac65abd404dd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187ef916d050e60674d8409d5d89c495d4db271725dd5740551a78ad975af049450df424f7737167f4d31bb75e4da5a500000000000000000000000000000000054fcbea4998f2df6c510b4c3e41a50d05d9bf8605b01ddce218f63d4c4854c6e81985b6b97dbe368b4a983d5f9f29b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ba3f2e8e51c2f618b5eb9f5aeb78f9ab3e2c546107feb8c09eff9efb56c8321f2bdd726a830cb90f3a2b0252beeded0000000000000000000000000000000010af855ddb859157b11279a6abb66abc6de67eea324de819bd7a6cc93484ce89a4de969c87dd1ebeef78bee0f24565d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018eb485365ff7f1fa6b842101eddd76670444e5b9908c3dc6b2968eaf60fac66759f05395d4090b99f9f69a2ec1bc0af0000000000000000000000000000000003abe1d5312f38a06745cdda9e193245681203fffc3f130bceddc9dc26743dce701936586fb755521c5519f8471433af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6c7b6ba73ff633caf970c83fe1e3aef50ffff5fccae40d52de02c317eef50a57bc4bc92fe7f4d6ff3b60686dab92a700000000000000000000000000000000193b6b799057ead3bf52841a55a94fccdce3e15ebab7f2b00550003d78df067987d9933d43d6543679408ba68ef66b321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000013a71634ed6320fa0cdd18a78d39d3c1b2230efb90ad4e6e6efa103995d691c7bbfc131caacd198a606564af6b8c43f0000000000000000000000000000000000bba692670a6a6d9aa297c305d7576a438667898a0c121884d652c7edf991d4e0e914d651fb0844fb5a2088fa00fb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54d53a051b0c590420887116085e1842fd9a48c6d77d546ad12c383e59bd05ee86b9bbad29565bd053f8e6e4b026bb00000000000000000000000000000000027a2264a9eef42e1534b8aa48d72b40c4ba5962472228e35efd52e3f2b8c22a04e3e425e24b7dfa4e02041780ecff5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000058ef6d2d2a3af97081d0163a1e0baba0d4280e42b0e7483a81342d72faf731be8c0c7f2bab0b418b87862a24a4e249000000000000000000000000000000000362a99fa453dc0c348233f0f04288a940fe4ea50b1503d46c2c80293e820f8e2d1a9067677708d5491b67c1fb6723bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc96dd8caea981227ddcb73f9c6a18e0394f5e9c42a89f25a993a84daaff24d1652e9dfbb6f27bdef3183bba8ddfa14000000000000000000000000000000001111376fe8f10a1e11310583bef0266667ff3a5dec59ac84d38f8c5f1a49621ef1b6c8267870b66acce1c32001407b2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa07f9cbe4aca3e884423f35ec8421bada2545c1b7651451e884c1d5da8bf6e93b70c0336d7b81c7ddbc182df224ad700000000000000000000000000000000050e0772cb72232d86921d21300c1a072dc00f570a6a2b4f734c3b8adaa1513d5becee1f3e4be4fed7b023e6e19286d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3ce410c7b4b37e1fd076937d3f72a895c14bc278e211a49be2a7751834db4041563830151065cd89336e75c987033b00000000000000000000000000000000159baa0142037e38e8517cde6e9b7f78f2edcb6b1fe0ee877ecd22f22cf0030fd2fa213c6213416751c606dd7bf9b9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccbb81e72c037de8896da7f4f7de007825e2b6491edae347707bb0029b2431355f4be783d0e6dd096ee49fe44a797e500000000000000000000000000000000011d88fbf3d25d8938b4654d7c7227913d633bbee3cc6d1a5a199aa9e414c4abceea43aa4146574cc0e3cdbdabf2d34b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000513648c2d6e2204edf40dc93222f1f5fdd6cc2dfd10a0158a20ff7b30a1bcc47c851e427a19eb07d18c6e7b118e3bd0000000000000000000000000000000000a7665d23bac858e716dd4d562d4d4a42c77810214f1ace468d013249f547bf0b9cdb4950219f47d5795a6788035308e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000268df8f7fa56c6f519202169f5601cee1808169b7ab63f430928e2db4b5a3d886b32684858f3e3d50286bd731f51318000000000000000000000000000000000c5c9a7a75b5880ff423921675b48ac071158f5f60180cfc61fd965ef730c65fbe5a2f152c188498b0229d5798f96c7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000777c87060b349ad985c877989c718a4f37798a13c52c9fa8a3db7177211de5e6dcec72b977f9e25fe0e58ba11fc7abc0000000000000000000000000000000003fbac6fc80f34bc319a0ebd4bf999a4272970c980aa05d5c5c7006cc27d62b9accbd9df50adaeeead30aa978eddef0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3ad6fb16c0b31d4575289c7e883b9d724d1c76e73cd9705813b0518870735b959b5ea3959de57d69dcb1d9c0ac854d0000000000000000000000000000000018572f4bd4563ed92091fc11389ea676cc084c97786c2b765c0b7097f158e92112b533c056f8a394544b35301e458fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171f6dc271611b27885a064d2f3227b6a5d2be3f03f879bb3ce51e76da6a86677aef505a154fe290f836f33bf15752800000000000000000000000000000000015ca133a1541846c899300ff3587d22bbd3c2a678b3edab62a1e6cb765a6167892f6c2b8929c1f5f9721fe0685a58d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f59f626e49e5abd07cef524bedc3550090f1c166e0c1a8b9d81724896df1c7fbb074ec896d9079d153dc08f768773a1000000000000000000000000000000000f75a2429c6838a58f311fbb03502968c19eb092d770bb834f0c38ab652ba18fe0152d43b3ec70eea02c619c45b91f8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3cc95fea0a1be5a2773b01f7c35b04e24590d206bb23e0b8538de1827917531f2134a8c2ae9213306dae150b4fa62400000000000000000000000000000000035d9748285140898c34c99d4e5054268add04d1d02c6add3d1ad87eb0e70eb551fb6f682170639f77f8e384d751bed51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001875c68715f254eb73a0d8d9c4d174ec49ca34c3e539594b2e1b111cd967f908c1892ad5c9dd652f3081172ab94c00db00000000000000000000000000000000000bcd4d859f032503e117d37432906d385411ce82761f1a3e5e991912e43dc0fe3d3c37c39ed9d9a8b12b43beafbfe31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fac656894ad9e245c135530694d0359ef129607d8c5b9c0b0b45a4f9370345f0d6574bf8a1e59d945f1672702a4b880000000000000000000000000000000019b6d4d205a6d4f16c1a5a4a92203713d4a9d3cf6620d1070bedc8c46c27d81ce45e1f9d0b815e3b74d7e0d2eb97677a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a9ddb4e0d3f819a2099abb38e74949027c96b878386076034a9e70b99694ebb9f49a09e6dfab1483328252b1c4f4bb000000000000000000000000000000000a97f3855553d628abe26b228152a96612bf243996b0f3138ddb81ebca8b784d6c9011d7490859f40880422f6c02f04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040bb10d7ee88b70e5a5a6d0a3525b0b2792adf9525e78126f4c6e9d3c83be501cb99087180f08f7f3dc32a71ee00d38000000000000000000000000000000000f8d38e563f4ea7670073820170f621c60281b38368a44d13b8a21fdac7de1ce7e5fc6d410498a6ffedfb83ee82f850a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc92969ed4603cbbd19ea5a9826ae45edc05a56e8a8c1bcc306c4acc83e2595a74fa0ecf3384f9719038370b2fdb00500000000000000000000000000000000059b3ad11d19cd6c1e236f4c9d5c712715b4219d6ab6349b9d2490a82a23a1e1a16a6d94e457e12ffd40a55647413e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108a2993a55c9bf059786adf8b23b0b59f0c2a9b6d2ff200359f9378dd2c381728d753f181f9649f93821a3b1b22b7b7000000000000000000000000000000000b0e2c40634756b24bc4a5419c6b78d640fc8752fa6279a2517813a0d9587bc50bb052538a640815349202d587069e3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b69202a9513913e34759b04f9abc5ab86e325b9313898647cb722cb67907bea4490f94c8c0451de4079e524a955d9300000000000000000000000000000000142b36e6aafd2629f5f71d234d2549c46ca62582cd25232db4faab388dd68996740da5f7d4aee990187d17d9d2b86af11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e903cd3607beca550823cacf5bb25e6b3aeb098ab383e04f1d1e16e4f576ecee7daac869b659691a7ad2b06a32520dc0000000000000000000000000000000009ba5dc1e11a67c56df51a27cbded5c23c3af496447f20f4c493859f16cdf2c18042fd0a86ab94c614fc13e7b4b1117c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e12b9ad49403f8fd114f077208e1d966721ffa3bdfde0dce1362e3a47e6f268b55f369553f762f95fd749bb129b2e2000000000000000000000000000000000991e85882c1456b2882f8431df90c422a8a969005e6aec16d5c9f666aa35d2944327e8d01b7f14553ebf65a8ef619051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014933ac10182e37cf3041d7a14d2ce736167555540f86fa2c84162d75004b1342c42ac0398a6747b0e694b21a74371230000000000000000000000000000000009c09e44a0cf2ac232a7323fd68896176595c9ad0e2042e476c0f34451a52500ed41c564aec8548009daff29a73451511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119f64273c6e0ff11bf3c8e7e66fe1d48cb2fb2d3f55a6a0915e8e8159772bbb239a504771dc5555c3fc7a9cd341fd8e0000000000000000000000000000000019ded20f8dad5bac309c9608b601dfaf4a4512f07496fea84bbf5ce85b86d05e644999b4b5c18322b12cdc2305a6909d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073ed8b7e60ad6bd49a0397f3e45e645591955a1ebc239ffdcd8f51213855720ce4fd84c778edb6903297a118c6429ca000000000000000000000000000000000e6836dd05b8a52ee9f2929f7c406a1bc87f6606e72d2bd119c514f816cdc6e5976c38c2311eedd4967b97e8997bd1571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001845685f599467136dad67cf8c0d5d456f8eb46d208b8bb3694664583b3596c52166b370e12547f60728cf96cf404dcd000000000000000000000000000000000e6abbbb93626da88e5b73b71aa87a69d5d42d50086b03ea7b2ed2e1515814a7e2e14290687b5b90a83ebd72616c8bec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199d1d4fb3ac3d96f0a296a668ba00077f8c907d9e600b1e8207ac19493d0cab9153a6a906745cb067f60180ca6f977700000000000000000000000000000000034af3cd8be9d7208e09a5397397f866f2f7f1d3a359793eede42b0e1fd6f1290b4492f01bb245b30d2c0ca7c561d7ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d27bde0b186d027b1a38ac5cdb5f81595ad2aad5165afb4c1847eed5aa705285c3d07546225e021c67232fe37c986300000000000000000000000000000000011c89fbb17895c32e51aef8b9ee2562296bfa7ac6881a2ec880481a9169e257864660de2b7f23478fa76faae2086f281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040b102e069101962753068282b4124ba47e667f890623479904a54304d33db3c297a7fe075f7382ff71ea1f53a546ea000000000000000000000000000000000f6198c132e1a85ec743b23c8d0bebeacf5ccdb709b7f4f5587abea22a5de212f1cae7d52c243c48b14af821793b5e161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014ee325c09040132ed7404091a89beb19ad73781e401cfcaf88f3e6f52147e8c5eb9ae9df9b904aed1fa6576010bedb70000000000000000000000000000000018d4d09fa00ea0bbb33ea9d9498afb405426d5306f4edad5ded0d85230e47656611f4df3e3c7617fd5116e7b556219761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016837b7d12ebdcfbe52ae077d7d83cbb1d2e6d50979e60b4811b4ba3a48fb87614fe874367191872a76e8cafca334574000000000000000000000000000000000c7aa0b4e859b4a425fc50b0024f5127f357da51a163063e375b6145367d73a228a1cfcdcaf15078b97a5f52e58a67f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006788fbb0a4139dcaf5b36da3c982d06b86adeb0ffeea53d5ebdd059f9ed65e53be33aa61b90fb6f807bc350a5c8d21f00000000000000000000000000000000126b61daf11191f0d2dbaab4be602ccb4b3571fd8ac5c55d6a3e5dcc29b3077a5e1b5df393e101c921a4e3a32a5188ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002414a2cff9c306e0fb92319b60d01f70c46e7aa503e1b508f31ee249978c6d8864450e13ed18ea8b2f909d5b504ccdf0000000000000000000000000000000011bfec8cdb4e3389c87e1a6cb4b11d086241c2a9b8c812b43e4c42cd98b53a77115465dab3913b0841cc87d156aee5161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c2432ce6174853a469528591df16dcedf50f8128e8832535176f76f2ed1a4bc574ee87fb09ce3b13be24ec3b03d9dd000000000000000000000000000000000beae4aa819fdc59f631f486f8997dc881f54aa97426da0860069e624823c7c072074eb811a9c2ffb0b63cdd0132862e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b414cdbaa033c2ad06a5d56adff9c0579e537b7e14c3389895642b6b6bad9beb277e274b24716f66c780edaa504e6b00000000000000000000000000000000177776b3e2211fa1db885d8013b04859421687e2eb8ff171c4afb645580e40bf3b3082504d8c8c4601e23c58d6bb3a601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6aa32424487fe942b544a5f2d4800dd477452a26ca9f8f8971bb64b3188b7ab891afa3c5c62aee50ce561f2523e7b80000000000000000000000000000000003a8b9578524fb9f8ef4e2b19c43e8a46e1572e8689404f10daf74d7c69984d572c19c3c7c1bd34ee9c31f7cd694b2581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c803bb1d3332d208d9b03c558ee18ca1df6193653c5b4303819bb7d7e3b5a84d53936e07741145287f2d87206b60a300000000000000000000000000000000113cd724eb81d728b7898814737ffd5b45f9d657dd9520b78245bb29e8ef6bc7ba82ffab9ece6a6327e41fe2e75443c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089911369b0ec86ba5cc45cd2e27ddcaffb0fac52d1eab834771b3d3a4785b37b68643c19781ed987d29a1f5ad453b880000000000000000000000000000000015e6e5e7702f1f80f6cbe838084fdd88769f715315be921edd2df6b81662434342c277fc8ef65c9764266c8a914e80c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d852cd5d8ceb22cdeff2163a0f273e04f92db160a98e01c4325d5ea78dc8b7687cf02d112ff91efb3fdb56e775e9100000000000000000000000000000000024d03df6337e86715911f1a0c9217395c53c97b15f2e1ac3c12c553193eae8d7eae489d0a3c564a06d431c83f3da3de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8a35913a0e359378f371af5d0f3152cd5640cf50e0972d0c90aacf60341b04ddcf86548f3f63870f169a9e6c1b5b540000000000000000000000000000000011a61784f00d089918c68af8e2ec3893bebbea59db4a1173d54b16de7839f237aa33de69b454af927c1274d74af956231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117b9752405efaffef6c7088a2dfca8ed00f0875f47e9f4a0f9c67cf8bd348f75f302d9910b813857521814e97bf5eb5000000000000000000000000000000000292a121cfeec3f134fe9abcacae7feffdedbb67520d9bf3147d8d92e39903d1a63524f9cf2a1f461678bf1ba5903eb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dabb132b3a316a5c4ea0febf7cc5105f668779cb0b9fbe0de85ea37902dcc9e5c56416d3519a7f5abdaa1eaa0aa1b50000000000000000000000000000000018636b2e95a5aa1c3b19757d034afa502110e93ac937a41cce00e61d7e6c75816697f983fd6810f9099bc904086228ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011d641b383d7af018e07de39d1486e7ae5fb9e2f65017c8c17718d48985cb4133a66893a67ce6acb0fcdb7b226ecc030000000000000000000000000000000007f11c42ddcd5b7ce907fd8aa8d26e1fdee1ef752451c1616a4e2e3f0cf4ff080ef3a1cf7af65fa1b5379baf340908661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f5e5b379b313b7301ca5b478e98bc603a4d3a580ae5b7bd135923d2948ce212f03dc9832b12a9df7626b0a756ffbf000000000000000000000000000000000c2b32bea66c604a275fa115a9dfa5de9dc4c5620cb2fbf4321a3d9aae180e63e9ca7d9faf5e392fb9d408527dc3269f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9cd3039fae087fb1bbb7d6d12e0cf73c2b5864ce9843f7df37665ed6299feded350da086abb468da154e70abf3830000000000000000000000000000000000b5c720ba293ecfcdb0e94470d8c3553bfe22271a194235eca8f1d60133bd3dd54f9ed0d754e032a7bdfaf7fe99800bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be8da433ffc037f97f94d6c6cb1cd696c49c37ee4698e29875417ac427b1ba75afc32dcaabef073d8ef94796c781e200000000000000000000000000000000001221d03a3a0bca806bea4ace393b824f8761fb5a669c7e919fe5856083d140a4c2202f18c3c0d38d25e1302838400d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dd01dc0ecc42430c176d6634a4f4d68d99b5dba42810566e85c7e485286d7ee88ea012e40c47d039fab6103dc9effc0000000000000000000000000000000000270aa2a32f03ac705050396829e343acb4d1ab3fdeb867f62b9a309484174530b77c6e4dbeacd8aa27109ade266ba41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a4b27b9982397c7bcf7a665befe3b160e708b81fb24ed138eb21df321a424dcd2aa3ed6dbf7af369045b302712668c000000000000000000000000000000001349f5e4936d730960e6dfb10fa00e4c9c53052aad9b13e2def43a3ddc6b31aaf09b3ef56a08a74d9789cec0ec3c506c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052bc5d3c971e200e845e89de02af916e1a232ea30cd69ca1db22d2b958175d2db1b38f583ea77f85e5da8c4e2642e710000000000000000000000000000000012ba5e6560e7ddd8d5d78845f08e570ffbf22f68df79333a4f133939157e7962a49179fec9cd4e03748d5844ffa8a95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a4e15ae507023d1cd89f11b4ae46fb6b9808ced455254c6a9cec276b0a6a248661a44b84ca8dc91292a35d9807439d00000000000000000000000000000000177a39b719fe15ed797baa1ce7e33c5a3bcd71b1d647d708f3e62e85e95acd142cf7ceeab22725801ae87e13189c823e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043643e84f5f29e50bac5866a487b513a0c4e75fa9356a287cc4766d12f04b13f794d3eaff2ed3d6df5ca12fe48fc4c4000000000000000000000000000000000e64e76ab8c59c7fdf9be4760a40187e0df2e5f1e369be791e182070f53faf5a144685e36d307346b3d7b6a04ae213ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001170abb6403d1e138d2ff7aab7d5decfb076b619da1660fb9e237ca96b2a850e8b8bcbd6a5cc931f568c57dfc401158f000000000000000000000000000000000acacc8b40e6bd476ad8dd6f4cc658f952e065d3921e335c7de80d66521a821590259ac196f42b6bf4dd15cc187a59161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000883ae630302997b8e92a47dcd37eae5f2870f76a85c34d034eb2bc3e32476f335871146a8a176969a051d2ad1ca9748000000000000000000000000000000000842c1161c8b3b0721c88105fb0d6cfd6aa83588ecf6913aab2ec14be69cebf44701bf603d8e141576a0fec48f6ec7ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033b220a6f2a407d8b3db401179d09f39fc8b19cb82078ccb2fd08fe0cfa19f0a7867b09b89668f7b2087a23496c2647000000000000000000000000000000000d9e383b599c1b9b135f7b860b157d0422a1b0ea9687557a49faf5d873f08d59d9fdc55461bedb1afdee2a33ef12af2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dbfd1c7253bf2760fcac21df0cb92a8aa896a4102fa691ebf15656c836cc534c9493abad0e402aa0adef6adb61122000000000000000000000000000000000fac9a6a1906d0818eeba8876b2ec0a83f49a91f6233d0696fa66e72d292d5c21800260f3cae6fa279b36d062335ad1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138c31b66ac1da0e369a5335011246a217548126ce818d1dd0d8100bd5b4340a53138768dea6364797e3ac7da1aa0f35000000000000000000000000000000001846d92180a161af03df383985284b3fdd3ad35c0b577658e56bae74fab06be2603251fa7fbff5901168609797d783e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139c94c8d8098411347b27652f9d42f4e214235639a0676978aec6d098d4828240d74dd74655feb58ac65f69859a7bce00000000000000000000000000000000064bd993ffbf86d08049ea63376125dc5460f07a70ef2fb9c8551f12f8554c0cc232cd1401f144745612b01939f747dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011380a7cafe40ca8e1ed3a2839c5b217a3aca3ad7b33625594e985ca58182ce115da63c752e37f66c029d9b49faf2ea40000000000000000000000000000000010d03b5bfe5cddea5b1bffdbca496eaa20cb9c551cba27145be5e1eff5cc73af530c70c1fa4fabfc2d565119073095e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195edb05eee8943fa8a62c94e65aad4da45fc03a315747e012141022da5d2d333c1b87ef029ed8888011b47ae4cf53b40000000000000000000000000000000010593b5d166a017724a7e8ccddc3ca0b56cfd55b7ec143f091f6b214976c7914400224046d823e6da87a59dc9857c6771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b64ad58fd04d22278bf4d2bcab984f46668f066b131bd1bf0cb1fad285987eba64a7ced070060e6f7aedb70aaccd0d000000000000000000000000000000000e88777d4295cb4f9102af1442443023b2174a9318ebd1af0b18369d413e1a20e86de219f0efc00efafc5f15faddc1a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e9b4a7ad446e953f5d95790c1b9503caa240b94b59002a364f2936c09eec34af1ead5e99b5d9a9cb5ad704450ee9fe0000000000000000000000000000000012d8bb9173c977f2ab3e8eb25d159a95ebb5e6147af0008bf46392dc35d039af382429cedddba16ceb97cf98d08e39471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc81b524a6aae4a757191664b3c0b0b8c70bef533dca813f862daad51bdf10987e79508e976967a7b8c2ddd8def6260000000000000000000000000000000012e5a2d1083b46d322c4ea18e878415731078663fc034baef37e917c828a32cbc88614906f3d59e9087bbecd51f5ce361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143ce154c47f7e88e11434e5cf0f8f0c35fbd891c5a6f53fd5d6918fe674a80f6d3ddedf4d20ad24d61d21a2c32d5124000000000000000000000000000000000679346665be5a70b32fe3d9013ce91b3498bdbe06ceaf753e47d2a000b28f305c353fffe0346d82e62941cc48356c0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000143e92530c85a6e8ab458774a61807ec666d68005f1bdf3647a6e1bbb864bbe937abb693a6cbb48022fe64a2ca1ac23d000000000000000000000000000000000de9ada2838d974a599a8285546f0b9ab9d8f18f30b7f13e9495461e31b9340df6786dfaad1a92b2f43d2801ef41b47f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd00035ab7c55665646c55292dcc66610cb469cbf8ac75dcad016da69246eac903af5a24fa2c83d4747bd2252b457f60000000000000000000000000000000016387ade29a0dd23f86221ea645e3d4b444ce786cd8b9b540200d6eabd6c59a488a62526405405c263e5f8e6383e0e6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcaebd6cecc3472645ef0c54d3d80c63948c2093043c2062748b31e680f8ebb62047b34da9b435e627d030ff740750d0000000000000000000000000000000002a9d3a722e3aa534f544c2c1cffa5fda027dbe34344d2be432d8ecccd557fecd866c0adf747e2c20c42cbe49e1a7b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cb26b71da29b7422b9f5d6d7cc7771988ce7e01c04e0453104c177ee1f0ecfce5eec5415cb252f28636a70185657cf000000000000000000000000000000000a7bddc22a31487057f1b5f461f0a3b4003139ff51c05e386e36481d0527b5094c1a469a5b6021faff594dce88db285b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2f0dc367b5a4fa5ea6a00e0d5531936b6f2897b026ea418dc3c6cac4607f9b17576ea3f87a062c67d17e6574b51f060000000000000000000000000000000014add8a8d829dde6abdd0ed62eb2e815ccd6d7790df7399445fdcf2defd9665786119be0d110cbce16dc2c89236aa75e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dc6c77dd06a117efbe0ec4d51ab491094adb420a2f3cfa6caead0b3d8b8ab9caaa25e782521abcd07725367098f8df0000000000000000000000000000000015bf93525e4be9fa4fbf55cff1edb1a53e018f90f6534735e6444321f6405af5fca1459bfaab9c751f9150cee56933021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008fa957b164db4c8f426fa42989a1deac8edcba231b49c736595d6b7242dd3638e1bfb7ab1b4a8681a6f8302307dc29500000000000000000000000000000000081187a22952ad0ab4d397ad4d809e536863f888e4e7d843d2fe67d4ce4b5d7f673851f1d8b70501f63226211ddb540e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a98638ddd8ad888a5d1d237eeafde2ec4313df5336d63ef033f57360d334c2984d1594afb190972ba883d2ae8838d5000000000000000000000000000000000e39195a92bdcc68cdd0d3fc8557adfb3e9ff200f26cea133099c84db24418f768966608ab0fcb07b3652937fda818a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cacabf315a40a6f03262725268d659feb28ac9cbe8f6e55429f8e36e6617e03156ff8305eb32cdbd2ba0d002d23bf0a000000000000000000000000000000000f81defe89ae810c223ae455bceed16853f5bea0a1ad30e12d357674bcfb54d11edfa0d2dd851e0f10f875ac6a9bdb6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d389ca5575e17047b573f98f12a742c13195f5fe7febd6109c9603a9951c8e8e46598615667ff2268dbda39744a2fc0000000000000000000000000000000007a2e538b44dc6b077b02224f90c82305660fdbc4cd725accf414ffa23903a4d04fd23a6c421455ccee419658875d0ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c6de630499f97ae3c613078343e5fdd83d0f8f185f7d78e2a52698d317ed5b9a478b5c5661500513475f68544ce170000000000000000000000000000000003119b1f9dc9a6be7a1a0ddfeb2f323884c2a84c2636d6b584e01650ea08420cd47becb706286177878ebc9d291a2e951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a12489b1982d5f435607ce6348dbc7b53cdb3c287a579264cad11a9188cc04b7e15b1c3bd1a59fb350a5d5fb3fd3fc000000000000000000000000000000000671a0e265f44fbf8e1fafb4a7b190076d8ec6b541406fa96003f60bdb24630e7135032be49cdcf3babffde0fa6e63f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003b9c7f582d97226549831f4733ee8e00339797af74344c615ba5dcd1058ab32846105a75c13e2d799c63aee1ec46fbb0000000000000000000000000000000006860dc1d36bccbbebaa61971ac2bfe8c31656df5977c7b70454208264ca67e3bc95fa8cb9fd1fdd9fc2d0d4563a4b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153050d1942c3f00784dba283aba7e8df4850266523d83a073f057e9115e2216822af1864473d564e3b447e258ef1e9b00000000000000000000000000000000004d46188c4a7176fe28ea1847e0234afddc06b70541a11c7a24b340e0697e0aa3149b6f128b166879042906c8daae9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a24d8ed7c9d1fe6312af518e116c314e9b9e47c4fc83ee014cd96f6349db28e261246ea9d1f449fd68c5973d7efec900000000000000000000000000000000153cf2081b083d132db97377da31d6f7f1c9037919b8a6fb081581ec8fe1c0ffbb1ff3c3742a9df481e8c03dbd1446201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123b5be8612689fd54b7a51f7e8a59112b80037eb21857bf36511a111dc84bffdfa44a24790713878ba695f61a33881c00000000000000000000000000000000150cde68f4574cd1fe59d4b564238726dc47b85a632d4255a2099fe9acac32ad79fc637657662a7781de5b386d5e8b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000201963a2559040627e3319277afc837cdf41bb5afd0c5e7bf2ca54e2fd3ee8a3ed876273f73159940230f71b242939a0000000000000000000000000000000008269189cc7805901027cad209a389b2bc874c5f3c1e9dbc202ddeda38cfa3d5c4a6f0e76d64c9d197ee8733e5a2f8371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d401071d0b8a04e9c675a63eed61a6b3602663904819f1dc6a007fba82ff6114f462d670b749303f60c44d0b4521db2000000000000000000000000000000001024d6295d8ce1827340b93d6d14ac47cd9894a7e4ac1c98e1e27b2f337a52d4116fac1524ec8f53c78d649eeb2bc3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190afc05e895036170b9870a9e1f05b179e9ffe02e3fa4b017c89614b06c261a4c07f97d5378bfa6402ff98c7a0adcc1000000000000000000000000000000001296b02a572f5da700f05496f6083c5374c936b2ddd2eb9602e08ac237312856d37652dd5680d5f77d865c7db31d2e5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fbdec5990560e72eeddd9ab2d8938056fc1e2eb3ab0b6ba31031147a888425f504936daae6d7045e94060edd72c6c90000000000000000000000000000000008d19fab6ae96b8b2df46e3207721e06531b61b450ff8eb0f06de1e5df6473bcc10ec9a466915ebd390919ee09fdc4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfeadc59f2148df1fff4606ec606e5d8c9545faf20976f789c50214fed89dbe830c6a8d209e5ac1704304b0ed08666f0000000000000000000000000000000002de702dc49123c7742b65c981da898e94da26e4b4bf86a9111c64452f68a2daf45c82dd8b1e75ef4f67e4153a15bce41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017754bdce925f6e10f51673621ead49e83de7d4210137aa0c3b2acffdd108bf3115a6f45bb0872647986c2eb6d6a6f6f0000000000000000000000000000000004d817aeb2a67533533b6db4d3efaafb40375684cd92ba0c69f28ea045c5a8274da3447c514e30d32044c21a60b71a351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042543a9fe1871e9d78807dee72a0252a160e44495799b2e0fa92fefae95e663814c3d5020fa35093155291fa0c4942d00000000000000000000000000000000028bbdbd96316a5c3418e8c9beb229b557bc550409c1efa84e0f8d8dcbca790dbb8ae396ef3b217a59ed3a7467b614661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ff06fce6692c337abd42859b64920153887d1c73d4a0741f858d9a69f0d78fb44422288ec685899740c1ebb99d79f40000000000000000000000000000000006ebefc9df44d309f642eb4641525169492c72b6e47a922b11204057678be15e95e435c65ec065eca4502cee7cbb22781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006755936219d369b896474f39d14f2100b913275f24d28e4b6c815bbc9ee7d08f675f9bd6e23c3708b0ef47ef26f9eb70000000000000000000000000000000001f8b711e110fe63c3e843eb1ead42bac16fdd7651e2b12bf7b2172651835e941ce098576c19c1e4d5a2ad922e3e25fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046e9af65139407e3ca011044c41e76fe4506c3d435eab9c808166d52db94695af0e9d52653e1f7cffe15c89449a674b0000000000000000000000000000000014f225c106d8231724ef4d84cf1696c81783921e6698d412f1d63a349639737c5feb050bb90053a33602d460f1261f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f4eb1e6db912772fa878f42912998b9a4956bb1313b4755befac36334ec70b7de2f683ae8e03c122242a1b51ac3c8300000000000000000000000000000000094d115f355571334c0475ecfe2a1af05aa7f32f96a691bfcb6ee56022e081402e92a387767eae0307003f5b9a392e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164fb59f18a5628acca55f27918b5361edf348a8b733656b4fcc81fa220e672adb9d01be1265cc6d4a8f1682182043d300000000000000000000000000000000179c954c9a3d9230e29e0ab589be535b65d837556aeca8896e777e7026d9c1a5c68eab50c7dd8676fb75387d2b64aa741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9b0df0201a0dd3007e8b8bd1c6dc0a1ae4d97a1db5f552d7e9ced5cc40028fc38e677a870f55714b81886b6bdaabe2000000000000000000000000000000000190bf5fea0cc427ba8202e69481e242d1e538efe117cac1a4df0737a829c098680f7bf087db3d1f17adbd5d5cb116201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bc1ff16c8796c70e1c5246e135d854ff2156236d01a6579206fbea337c34869f1d067dc18588100a67570cc9e3a4d5000000000000000000000000000000000c9694089a63bee85a314c0514f8dee88dd570524d885790fe2e61b9ea0e864578431b18ebbe376e429087a267c8dd631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dfd2ce375e96b14036dc540ed9f7c18ea2c121b0b4124e904730e3caf3e2b37cb08d6fb6f32d9d24934c99ef22c6be40000000000000000000000000000000007f83abc46e29bf9c4cde4a014b9bc08e937d8a87359914c4e2ef230db6c8d167fa665d7daaf2357bc30a82072b1b18e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173df18946b98b73c8bf8a10964d8af3b029900f4c5d4b18defa5e94926006655aad2cb086f738752c9fc66870f7d86e0000000000000000000000000000000004bc48ed518656cd62ae5a7ff205347a45f349328c546e066353726a2eb33aedc6ae204f68f3b693593802f307a118bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118c567c53b202810e7496c2a9c9aeb94f41c76ca3e440784a5ba33ab54a0ae27966f8db16efd8e439872166e642afb1000000000000000000000000000000001816b32254567a4b74feb7b01e885994ad7b4d4b5b9af292ab14a478527ef8fb4dbf4b352df0f86765d778cf01cb06401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2512a7e313a9f225831445193d450986181bb182b4b3e8d02ca46c36d9fe9421b8d9ed74e6ee0dfd27d1ed54c2c36c000000000000000000000000000000000fcd56e3f88a91be248459eabbd6110935cf01a60eaa213c9b2aa89203059154b4cbfca4af201809649d13675edd3cf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001787b7e2d9406442d8f8a407bc1e4f038808795a2855bf0933ba4ccca3df79f2f43c3c18ae79aac9d521e159d30ad06d0000000000000000000000000000000001211607289607bc3c405d73756896b47884dcdade02a348363ecafdca5f53f4768dbea3b429b59b8bcafee3c73fb2d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c424d4b0f011ec400149500dca7b5a942247f7e7e7ee566bcc52a40311e169cb85e804959be2d36cb05d9e0ac8b2557000000000000000000000000000000000d297a1b3fa0b811bcbbad49552f26d68016a4d3916488722d877968972e160906eb28e8d638e8132476425747359eeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b06972916fa0bff8f5473cb0102e729aac7914c8d74f8c94b538747c31f2383fd4d876932e74aee52f86ebee79d36800000000000000000000000000000000070af831d3b1e2f8e303b7b82631f56000814941ab6db36e82e291a1ad43710bc64e12ce3d402434bb9707eda73087291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cfa731c777e7d6530c836ed98582c23f8fcb931feb3f3c506b8a01a5e583e0e538e4385eaed7c11fbccd58a3f9c74a000000000000000000000000000000000733ece5d96e443141b792b8f3de66149ea84dfcddca412b6d1f0c205d969753024cb7b464d202f1140aed3eb2979e131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fb315504f879ebead938710b9a51626e7bcfdf9408f584bb6a1f85421bad0f227c4e0924d8f3ed771ecd1223da21130000000000000000000000000000000017f8e4eef94aade0e3cce2a07e22eb318663f4bc4e716ef8fd46f323cc6bd5297ea088f664431bcb129d8fe4b67cb5191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217c3608cd3e40eafa9f7665cb910d4fb58f317cd6a64bd433652368279ebed63a092ec9002fc36a021f8315e0768a0000000000000000000000000000000004056d9e4adb46c9667b123e6a66e53be0dea549d543f97566def03357c24307578db03871e75329b44dec182f1129ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af4a323b0c7708ae28c1754fc925bbe8c10a14af5c9a1427db60ff55679023d264e9f9c2803f92572ced913be7f7d7200000000000000000000000000000000195211e7386cd27b0e57d7718392a09560c7a81f255729d97b156dbdc4061eb656d5b265b4c49916e2999a6cf7ff08351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140dab8016f211f47617a04e7a34eb7675ded713287725c2a1beeffc4cf66d2bab4a2ee9df67f1761f338ef7767f3df300000000000000000000000000000000183d1ba515211ede4c275b4fbcd1ba0c0664b5cbce2e516dc2480179af709d38f1178d0f867de2e690f2ba179c962bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c73c71a629f193a31bb575fc7e091e61d34846b8d2277ebdd8c2607ad73d2e8a266c95061b9d95d4230ea6ec87bb9fc000000000000000000000000000000000a47bf60c1590c4fed2ebd20b6dd7ddddaf4c16144caf5d99db0eb8f6e819740d21e3937b97a521ed918e801c7aca7281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013726f60b21f838c40890d86d3939fa535b44036aa2c264c2011c00ac811977efd1edfd5e46f733d8c5b7b528874f03d00000000000000000000000000000000126ff6fb3ad7cbe0839b055009f77e4209e414545afd6856918c547cc38b760612c6699d62a363154e60eb9ce085f6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000e90fa89c97f843dfea3edf7487e99ddb9e750c0bd37ce07ddab645276af09ca0a4049c42f83969966aee81a80b0ba00000000000000000000000000000000007d2f99dfccbfd8a7d744a30b3e4eb77ede9fdb8a0c9bc57ec84965be8a44fbaeef08b1989a863193d79b786f869a9d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163b4043793c01b95d9512e71b91c905d378fdaef9b5ea6d65600ac9a04be1a1c997b2595040bad16860e379d029b82000000000000000000000000000000000179491b4f75e733e5ed4072a936f1c00a1adb21506dcfaafc8a2d59a3d1ec3b76e77465c8fa7ae2b9694b10b90850f631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9923c972befaca40ad64f1c93a053fffe1e71b3b8d510cc63c6535ab409bd829aae7eb40fd06d63852960f42b5738e0000000000000000000000000000000002d181470ab2ef7ccc5ae808a812347b1f3bccfe91a612aa7eec5bd1f01057d579a18da7d8822488c66eec6e01b0cec31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b963a11b52f91ed718f745ce62477f764464ca726ae42e4cc3d135d7aa4dd5cf64eea034d12c4ed3b9569b10d7fb07f000000000000000000000000000000000c876bf0a44e29f825d0de9006f697b3b3a01ac1ccd489a815d165dc98b10da82c1cd71e4c5a83fcc0665874f062f9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4422a0165f90343c339376696417f446cb1622680bf2868474ea83e8e9e51f6f7a7b68c090e0f75f6086c444a1f52e0000000000000000000000000000000007cee964bf34568daa423816ccc27dd061b3c9138ad746c43c4567289a6381aaef2926faecaa02eed5482b07be7483671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011090f01d67847d44d01ec69a68e7423e737951e2d4e6297729d5f9d1a10dad253db00a461382765c8953d1b9a8489b900000000000000000000000000000000155c84999fe4c8b93179713e704f3c7ee0bc3377a785477e70af474ecf6fc966f15f91970e00ad69c9152dd39fa97d001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bc244fffa93300b5179e76649829556665a61975ad5b4dc74cd7a33dfd62b335cf1f16ab6710778b3be3561c26b94f0000000000000000000000000000000010c74b20f18dc98e32fc4bcae52d763e51f3bd0a44b5af0869101bf8a147480d52e70ee3c5f6c3ef5e0abf9c4b13041a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001915c7448d52e8cbf5bdf7e97662bd2fe5242de642b8ae14179de52641d877fad6bb300ce7bb423de6b8dd40157c48ce00000000000000000000000000000000102d4f82db9ebe90f903868ec6bd84f73aef12ef691afbec2dae3d7f442842ac2e1d8abb8f64b05a2b0c2abe31ced50c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036605d1822e9fb91e8c2f4e8238a3922164ddec8cb2a10da31e712c00402f622801d73763a2c9b4215991c8c433c4d600000000000000000000000000000000189bafe34a25d9d0e94b677f8c6d92e417a38baa2c92c3e5f5bd4efb166ea26dfc7a2af97ba2fa7190c23f83e7e34ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ff80a65972897edd715b62f5250f855912ea7df90226a7b0f47a936a7b25c164bead1130b133f95aceb5cc0dc9285000000000000000000000000000000000883d8d025d52ce0e316c4840ebbcef1020b45906444491aa6156ca03143f0bf588ab5871c38824b15e6295cd3729b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011005d4ba614033a414dab053fe3369a858a4df0847a3f161c19d4ae19e96f3470936ce9150ae68b701890b8b3f44170000000000000000000000000000000001619180bb363d4a772a08533892fe7f1b9b2df3a791e687669a186186fcd16c80c89e0f2aa138f6a4c00dc5e25acc98d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052b2c7f72827649881467aca8f83d27a31271872e268db8f5709fd70d5421ff43a31527facd3038c2abcb0202ce5d100000000000000000000000000000000007ed5e0ec694fb3570b4d220ebe13d10a2e41f052bf56f6ce6ec1b8325a854b99a2e5991a117987d82479572d2f7202b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011881698ffc63c3c93239d1d3e323a2d4d0df82a32879f25f2b1d84c4f9e13832acb61a2590b61b51cbb09b94f3a466d00000000000000000000000000000000084baf8b96d01ae4cd6b55bf8f7932cabc573c6e997852b86acb2701257d23a0aa69391bb83758bd701882d516b64cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a943d030f67762680aaed35a758c6be0291fe4f35b00c8508feb255f54353fc42c5fe9c742c5ed3adcb4962fcdc38b0000000000000000000000000000000016a6dbdd2cfdf0b2ee7ff33c8930bb983d251584a4cef2d4d3e141c528019b3c9f4ca298288bd2b424d567527c1159341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9010e787e5fbabd62e3114c7315381d8a1a1d76c67d5eb74c859796c412ac81db64fa9b9139815b4113667f96d8e260000000000000000000000000000000013c794be94e9ccdb62601bc4d8f12afe5b0276abcaaea97cb89eb33c4e315b4658a40611b7553b43a0fe2669827e06c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5d448c62699967eb0012ca537351eb13622de1006e950720691f0714f44d52fc795740653ca194e84dd6acae41b312000000000000000000000000000000000f29652a15934cbd5e28953f328e2d82a74b9e87a5beaefd4ae34e9fe4665c54d0507d1d4b74d45859be85902238cf0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b63f37d17c68f0475e3db0214b10f3ff20e87a22a4223dcd3fccc18980be018012bc2e16531a0aaf26d847f164a6c100000000000000000000000000000000198493adfbd103cbc5b15c9805602ef963df07cf8be20a0923eb53b64ae462d4f58705dbc3da591b5d787056bee9c46b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054497aa82c55c71b141fb372176eabe47d131e75bf049e1d994b6e8717e124079627ac293ef56d20f0b21e9658222600000000000000000000000000000000014ac1def6bbd5bced059b2a950511322ac5632ed99b2ea286ede171692da44a1017a5809124837c77df571aaef274fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001475a99e3755f855a0ec149b1b35cc6e43f1c717e33f975497cc4192ad0e18a86642618018a867f8323e613fcc9bd98a0000000000000000000000000000000005b81b4a910d4134ffeaf601289c3a7dd73afaf57ae3303dc0842aaca710e620e995c86e67df3273a14c374b08c903a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1347c4e1c5fa59d4bb3b30eea00652d87009d37a1f35764129115f53c8da5c9fc47275323474204114caf67286a28b0000000000000000000000000000000019f1925397fb0919672a483b2bf46e5777d30701c5b99138e4eee953818bb1584657d0563e9a5331ab76e665b610a8a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005474596ec8b34cb06927a34cb4b520202e63264dfdebeb0a83e4047c3516d4cc2949ee8514d7a06882d9ab58a37db0b0000000000000000000000000000000001baf5db373571eca2799cfa07c525eebfe9e993bee30cdb04ecd78d18eedf53a1e84a188b159c51ccfd051e194956da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018717811b337b659036e0842689a02a1b71aadbe503a20304b2276bbeee5e537499f334741fd21bef4c2789be394cb0a000000000000000000000000000000000e9ddf17df99036bf57843567e3eef3a2ca4b2ea0f98cd1e7f91a1fb6ceb3062b4c6c7332d073ec426ff65f0d633a0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5081286157d40e84761957662756abc63c296438c1f5029db6b69ae5697623f1001f3be92a85c46976359e2533dcba0000000000000000000000000000000011645fb51ac18b81fbdece6f246f73b6dc0e83cb286edbae05c9c9f24637996ba6178aa41fc99b93bea7c05ffca5ffda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c37ec44a4cf6d92f4d70794c120e985805f65e1dd88425db221c02475ce3628a89469ae2ada6cb5e1d0a12acd8663f500000000000000000000000000000000087b3247af0bb89b0ea60ed9e2052c1f65a4a4dbd3b32dd137702aab5767d336054d97eb04c168e705b9fc02c9cc2be41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001116f13891f7d68efa0779d65b32ca048fb4f24dcc665805d33a60fe43d9fe327cfd328ac7738d50a2d738141a1fc4a60000000000000000000000000000000006ffbbe26e6ef58b83edce0e944213fdbd7a924c4cf15c4329537386d253a7b7e3255d00132f93992e82fad7bd085a281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ae94afe20e80965f15bbf5775002ca4d49fbffe62915235e52ee77ade15662246b7785b27b8f1e2dceb0b11e0fe3bb000000000000000000000000000000000ee364d9a38643efcbdce3adc1ab1a99d9e8b1e32d57457ea7d5f4283e50826395569803734292efc0700c01bad6b5a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae0e828a85730da0c3bc6faa80c7edcc0b8462a476ed0a98a16bfc46f0de14b439e15c2e635c8bcaba00372082c41e000000000000000000000000000000001958c3d7ba82c7a58f538c609f042ef0b9827381677aa1b793daa3135caf67663e4c00a2aeb6b057511986cf9d7e40251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcbac2e60c2d2503047df3117d0000565bfb03a89df73902fc9de907b5ed011d3f111d10f3d7bd73282049c7ce83de00000000000000000000000000000000158442662776df1a98b36f3e24c46d8a2c3ddf64df0f108782c262ad69ea69c749c3dafdad9596636089ab54c247c0731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0c5108993f21d6f399714bba57b9bef8779c7d179db7a7335f28dd097efdaad4b1295cd6d7fca94fe0bc617ff15c630000000000000000000000000000000011b077f0d08361292b13af72fc5bd5c6fcecf903bf7027f5293eba4162db7b8677f07e1c7e6a1551d1c52e3e2d70cf681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127c59f3b02767161303481f4bbccf5e43c6879b895518a6efa114a17d54a839ad60d240f284095b2bb42bff5ef2d037000000000000000000000000000000001239061bf3c44f0246451ad3e70681b3e4c3de80da91501830cab7eb2499fc312e4f02698768d9417b6a9e6ca6ed085e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ab987676d27a6201c76029f7e9f6a8ecdd459fb9cc8c2bbbc5ff3123e61811e59a2eb297e6600b276afef8ccbf1bd0000000000000000000000000000000007d6d1eedfdf6e6bbe79c59167615687a0cd0eb3ac7e90aca363bf4b3c0aa480dd83d6b7bd77be21dbbcfaf52128f3321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c7f7582e641496fff87d53b9fd259c68c2110b134f0eb4763a759c0e53a0efcb8c153e3eb8341f1d69234d4526a61f0000000000000000000000000000000018a7212d8fd573444a6d6d461ea3564afe24caa43257ef4f5c40608d58ee8f42cd9fcf5a38cc91ed3d53f102554b49471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001076c511602b96a7e70e612183b14d88bd40fbcb07b6e88b948b5d15064f2f542512c1622146cd96973aaa0068939bf4000000000000000000000000000000001018e0e742184bc795de9d346bf2eed0ccbc19219f70ba57a1f57e9437d78ea0ed2f5bdc5c43c1c3c263fa50d4c7c2eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001908d12f0ce564d4f6e032f46d561a183ab9bbff034ddc3454d22eb41b4ffb8f6d16b11744b27716e6006b146a53864400000000000000000000000000000000164332a0a8edcb843f7499464e2192ad764710cbb1af8c8dec1991b0b4e1a7279ae82a7fbf112d8019e618b2591f27621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000979327714672dae98c4267010617a9c98f3035c0dd4fe0b51c67bddd7a0a3f33c387dc138cc15ff979ad33834d45200000000000000000000000000000000001192dc158a369ba124c4b07f54645dcf7c825f3c6e515468982af652211fdb4a309563f870a69d2688d098e103f8fdf11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc78fd54480cd8dc0d3e9526ece7d5a0a010f1a5d76439f64b669ca86e96450f81390f638f01963828dc65fd24f59580000000000000000000000000000000017eb4483f12e68d6273bee33d27447b98f23cf012562cabdf3710d46fc31ec359a2f6b9ddde6a236143616f9da78c1a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001194ad3565fa16dde329ecf41793c0bde4f14d806d18e9b2fab16d79ba018c2b2d9c234b9b9a765a428ea7e188b5c6340000000000000000000000000000000005c77cc4ed73e6fd14eaa930d05a6bbde53cf5bbe2feeba055cc22e5114ed86fe2160865be91c8d7ce5f4685f1d82d841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a08aed2fa9b3e616cfe2be8eaea968ad42eeca456f394453481d0aabdcbb09eb25c82073f7b28da9ecb6ec148de5a3000000000000000000000000000000000d4243136bf464f4ff36a8705cb88eaf4da3d362a85b63d7da8d575630758ab147f817c7f55d14bf99c798f1059ee92e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e11c518fe9eef2c692734520a4fd39ab10258622cd5ae317f6669fb5db60518cbf42a05c3215c0345e10ab458e6eb2f00000000000000000000000000000000199b41f04b918e0393a5e7adc6412cef4875d5bc03dc808a3a02386bddf964c30b28d7839c45a0d92ae750f341e67ec51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007763ed5ceaf0334e494284142117834b2f670e9b09ebfc430bb5513274ba4c61e08545d6faa741a17f05e17123c42a60000000000000000000000000000000014c082b07bda10a27172210e5953e4313d18bee178893364f19ab3d93466fc60cd95ed4b0cc5d348dcce17b46869ece01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178f95e4b974c56812fa9bd57d03d5e6617051b62c28c971fa1f421d4412a5ef261adcfb234dedbc907903615a8c7372000000000000000000000000000000001945808b48dcf24abeb0237b0172f2d8d91db6535dd9acec72331bde2ce6eac34ef5dd4d46578bed3eb6e27bd5df492e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ae400178cfaec36cf6ecd126c77437d9493ab23f0e4054a1ab4618a6ac3574e2b992a1aa3adb085baa4ecad2f18a330000000000000000000000000000000006b15e8ef4ae4affa0472e07062f148a7d2f689bbddcf5a2521a7bbf24a7d56d2ab2a619b0418483ad2a5e139ed9d14b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4f7ee6d5211d7d315816bc5f4b0399a0feb57faa106b8754a70655235f75e241fb6099bf480ca959b41ade8975574100000000000000000000000000000000123fcea6b6493d6cd328aef22bbd435a2e181b3da20d506deb2f15ad923f89602f45e1402eaa344140bacd5840b1a26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003713b43849400fb86bca5d7b3c5da7a2fc7695042666c19ace1c1375ffb41fdcc21a970f1277486c05f489d7e58a9c9000000000000000000000000000000001735ba468cf126e4b242530f0f6ad46a98d3a04cd5a6c19e4ab8fdbdfda0857f501274cc315e088467bde5765440c87c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001714ea52a3c84a6e67f262620da111b21e5b8e3e1b408f483ae63e4f2969be2698a98f181e2f7db311f3fb6a6bfe60d5000000000000000000000000000000000bc389c0f40bf0af0f81662e8fce476302c2e34d1dcf7c7354e95d69c0e6b80560058f5d56b982dc56b7d25d706017001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5b09130fcd7ebb14f1d4abebeb2cab306def81db20d18c9be01a3cb96e2cc1dfa52f6dd9d085497485aab356d0a4d80000000000000000000000000000000018d49f7eec034531130ab18d4b9886664cb0ae4d22614b386c19fe8c4a9ab57a9817d33563848379d7944fa4ee0006481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c36ee8ebf65603074e29ce922b85f2d5f42108c203117f0d9b55d99fb9daa5a60571e12312426b58e3b992b9c12700000000000000000000000000000000019fa3c7f4a8fd30b5849fbc41c96b363c427d7c5ed74658a52c11b99ec4154400a9faf3a1fa19469766a003ebd4f488b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e05014b4c4349313b9e035b911b21456fb7326182893b016da710a06a77da823cc5860f8b5913d2cfe196a3f0b4b2df000000000000000000000000000000000327852d486f0bc820758d7220d6645a4786cbdca9e51c7b8f5f3552ad7feef7a7a3e67df7bcd0abef70c5fd677f27451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d38bccd0f60aa32e5be727a7a6dc5552eb9bacd5c4ed69d5e669e40e563169a50efbb76f731f0b9a99457d5fe25ec14000000000000000000000000000000001828e3dc5849fa5602cb7f91ac56b9f65b63142a85aa38aacfe520e606140b90f9d389fe5b908b3a81365f3bce87b3291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab69f688a10b84fca21f4fd684f35ddeec3c5c9c56a3769f43464551b00246493c67728e2ba5bf05a8f1976b4fa898c0000000000000000000000000000000006bb30e8ef6e7818b34df86834a65d1a1b853101ecf98f263009547c8172e7702f292b560a0c2b8a931c734eb829cdeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4090e91a415cf6f4bd45a2019b409b1d2e6fe0c7c9805a3cc569678dc18a4f4c01009d8313b526c7d341f9aca33ec40000000000000000000000000000000010c7bf76566aefe4060b3b46715d90c8e0cae138f4ccf525ee291accc7f223efc9475873ad550ae3a5015017801059ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000611f2177daa3cbc71a63c48f26cc666fdd7c03033e6a00be0b6a3fc88e692f0482747e73918dc97e65dbd1351b0bce100000000000000000000000000000000104449505fee5f8b286000ab1bc0a3728bc95113c27bb5ef67503a6dfde1ecb0bc4da9d3ea763f09616c53cc7c4181f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000defb487412d2c74047e783689acecfb8574ddb902fafed26b72336fd33e55f37a275c3fbcd8b6f577a199c7d7d8cf9500000000000000000000000000000000070be97996e1358d2ec4160def5f2bf6637d9edad972b7c4ef6173d7639acaff511c252dc05d52dc61760ca2511a426f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c588c907f721a8370f1458aca82e4b75b3a2f0baa2c4ad579c84f7936937e81e36c4cbc9364513cc8328a97790a34300000000000000000000000000000000089a72f2da003b65272356d54b0c7db68f0f11f2a70a72a70fb7c56093a49cb4b1974c7174801f606137ab09fcbf87da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012280dbd1e2e391297643900ae37d96cabb7dbeeda97b4940d67916c6af0f3432f0ae9531344e26d8e995f38619c78d30000000000000000000000000000000007bb2584e9ccd1e9eb7ac5f72f1f3ee6d387ebf1ce5b70a3bbb3d47d722548f2ec7760622977b3c3df68ab298711cdec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001166f0b407c94a5a540159c67ffddeb376c281108acc0d8909b46f325bdc11d2244c05a12445e742a883a67111a23940000000000000000000000000000000010924a74f6835e83fdcf019173fad65b79dfacbeaa23b88758dc63250e3d3788ffa81130e3485cd85e9dc3e5dc9509f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bba0d33b345a9e058c533660d05a6175e05ab05fedfc004ee499fe85a73b19dea6104a3f360058e756ef79e44b4a89a0000000000000000000000000000000001e829ba021603f979715f07e2b1d5e8186c8198530b1d0440342346006effb93c008ed134ad4c7232c75d73d25855551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000170dcf2f2c3a32f3af069f594dcb1f7b4ecc37611f8f97c7de377aced2c99e03abca5bafa806db9b559e66481413a3c00000000000000000000000000000000000bbf781c376787d8972891957258cac4b90c633dd24c422720f366a2ab04f4d81355ee5c569692a08858415e896f2141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010dcbc6102675f8d7244eca1c777ca3857892852739a1bd01c75dee2f1028b01e58e98d380a11935058998535d2c9a3000000000000000000000000000000000a13880a5419dc6355846511c1512fa1c6b6935450fb90edfdf7208981442119011a068776d764bd1e7aa481f5864e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d7fbff992dac19d9b7ef0a42cf607ce2c7546b4e54cfb061448a3b43ed93b35027e060202418403389eb9ccd917d780000000000000000000000000000000001ac0934fe886a1d3d0099fb22ed656b439a89ffd239cbe572b38bf5edbbd695bb8971aa2bdbdd432ac64002daa849c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fd0384d3430ef534d37e55fe9f4e68a7457a53ce0a85124ed2ec259d1b4f4367ebcf0defaca5e4930a20a10b35537000000000000000000000000000000000d8c387d295b5255e8f73a522f76feeaba9a5464955978669ea30d3346c2ff448b2308e722957b5e2238d7b24a1acab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a4db1cf20278acb2aa644c24fbe27cd50134139af6112c0729ad42c803cacbac4c6fe182e2476d4baf626ed8017f6300000000000000000000000000000000062d241391d72da8c4a9b3029708b321242583c3ba13aad2aa5e1f2241f85ac44375510df448207d02074a1691f11cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001681a37159e2496d99e15a6d1ab89fa3d820425e5d7b7c68e107f1ff2963e638115aad27e74a7b81eb07bd5b41a2e8b3000000000000000000000000000000000e9ffd3cece19cb759e3d32b9e7ea9537c0002e99920da4f4c4e2c4c9dd9a90db4f6ffa816653801c8c5f558ebaccd081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c80ece557162009cc57b458ca49a0819c15bfee08adc9a567b34b3e6380f754dd25e1f0e2bb0b35310fd8b28728e393000000000000000000000000000000001221229a590c65ba74271382393d822b05ed1d249cb266df4135d1d29691f20d23bc73fd8bac06071d78ffafb71e0dd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118085bf96c359a52bcc33d8c97069881b41b6735a5bc8261f871708ed4a6382df8b509e097aaae73e4694ce309222c40000000000000000000000000000000010f22b11ebba9f0185b02378adf464516ead32a032e4d429c77bcda250140997e337fd07c584aa5570d55c683650a5151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ee8e85fe077efdc5ee35186264d7aa80d41a4e8753f466c5d60b69fe021a9353834ae6e7c4f9cdedf506e4084b36f800000000000000000000000000000000136d8f32c889c32b0b07379dbce0dd2d3aa3c2bbb542f15e383042fbd6df583c119fba7acaef8156d456f03492eca6fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c485629bcb36d8bd43c2a94fc6181ab904d866a9efbee406e5fba99deb6f1344b202a4d60eb31dd364478ea14db9d9000000000000000000000000000000000d7b3aa6e4227774e7a0aee80bd6fb425c307c33e8249855eac88f6befc67afd7f4c4081ea0f1ce1b97a7144230a1b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2215f1de6e8013ced096362460538ab6d337ffe6a62ca157076639b9db7587402d45d199da52f2ec7dad8f570f9486000000000000000000000000000000001316b87f4cdef09b1c789a193958f25c9d22ddc4e960f32a8d928775d7c8e67e13194829714fba6427ebd573bbaca8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005f88d52bd8c91f4e7fb1eb01929e7d1907d7a76750ffeb44affc4494294a483206a325a3b688480062dc600d97c97900000000000000000000000000000000066b54d2565b6ee4dc419417973a043e83958298f9cddb8b4dc4c3cdbe4f1e872e698d9bbbeb6c960e46dc576f758b561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156b3af859234f2c0972d940f918ac883502a936fca14603bfa262f2d1bbaf71f6faf1851c7eb5d572d7f6ce060cbea10000000000000000000000000000000010b4312c7b8554701c1b39e769f59c9afa29014d001f2ade36bde785e8950847fcbdc8c8f6308c29e8c355e79b4025d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a2ecf98e918b13eed5e1a40e772d715dde0d13a4b4441e9f0d82ec65d30e11cf6ad73d1ecdff46dea90680950723100000000000000000000000000000000165ee9c3f6f62f7e780b3097c1bfb9a70019318967740d52fa7ac2cbae9754b19a016fdac534ac04c5408a47af500e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ded56615e622332ccdb3753f2adc3275e8011d9c2f590ea4fe0857c5d10aa4068797ef3d76dcdbe6d9b611f2eb744800000000000000000000000000000000031332bdc675851ee2826c46caec91baa5ae21c285de9c0c64ee08293d5ac5a0cda7f7480466a001fd49e1ca5a64c0791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d0b68675fdf406beb82d7eb14c62dba14664d8972357f0032e585a877d07d7e62ccd46d8164b72375f54288988591a000000000000000000000000000000000707237c7a311eb8f608eccb34f4002bf604def08c1e05f38c9ace1c02ca7c1fbc0c74012c29b9fc110c13d6ac74f1a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000c720191407be03659e04269d248b965487dd80e0c3ac9eb562a14f80c2fd37ce72ef6fb2b7cc109e127126a9c306f000000000000000000000000000000000ffda2e4fa57e6d9dd3a32dcb61f61cc6e402817af7ac94c40906b63d856618657018849994b804aba99ac70fa48513a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129e3166cb6f3fc4d20976ca9733bbf70ec2fde5040d58e975388d6ab43883194dc46d740981ff723610726035a0e5f40000000000000000000000000000000011c1246816dd39f72ad79e9b9ebebecb64aedbe7c83055681d659b631e19eb77c7d78dada74d682d3150b6d1c5ba17fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003077e260dd21ce1648efcd9121088abe78151324374b311c99c6bbb0b2f9d94ca60c34fb56df62712c455dfee02ed1600000000000000000000000000000000054a206499ad991b143be06b21c22a5be618173dede5b554b4c4224e0e80e91f0ca7d3d1fbaea3ab62ff32b7250dd32b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3145e932f0cd1dd5fe622e0ab8b926e39ec3b2fe670e99037a3799656a1bd979cb2b3be7a3039d26fee9744c935f60000000000000000000000000000000000b853f10cc0235737633d8ab022a4045cf64e1ef14dd231b341ef820d2082d66c3f1dcfa15b0d691f6d959a17a38a8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b4ca42cb0d6d4c48d24c5966c745cf84db4702c583f8daf3997d29c9eddc6e075b067ce7de100c73f9a5d252c27ba0000000000000000000000000000000016e7ce4d5b37d9e9e2f7ae147a982e8d986966a0bbdb332315f72aa568466f56679ca18dadde86eaf7242a6e66c3ec6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf67beb5b99fb74071b3b98b241133cda05c4106e9cc2ae52b1396495db43a61c3a1df52e4c668c1f5a558f1b2cbd66000000000000000000000000000000000492722d3ead5b23cc2e48062d9adf5b0dffc17d3f411d8a69292da6b8bc5adc2245ff9a9d63b85c45357a69b34060881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005084f3d992f528367ee4ce3b1777470e2bd701e1bbc85968d409216059e35488f789d1b9250a4f99bea991dc2c98a78000000000000000000000000000000000b8e89980b1621b5ef11175405d6e929051cc70a59390a9dffdd0d03e1dedfc0f7593ba26bd61c06992767abab98fdac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189c2360775c7a9b1a145b50d06e5d7c29f5d7cafa569d5d2f0b8d1c1f039968d9b7d7f786718a45f7ec0f576fc7b6f000000000000000000000000000000000167199bb310e2e11d2406fe0add46d3407571c7bd0fc49c5666f2062f28a5b91fd2ac479f7c4733347ed463dce6331851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd205118297c7a56b9ba83e471f950b8e88b11e8aa3ed773d46ccb191d62db1ec3b66d57463c019d1640dca3b2f7aee000000000000000000000000000000000fe84dec9dc2899ae1cb762999a85d5a6a00893d5340cb6f4248f7228dbaa7fad15dec036c26a9f342aa91ba281331901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028c3275e9cdad9bb98e01fc1a888735146b3a91bef8002eb6eb4bd3e4940cfa6fb9eb35e4b6ba7a7502655386c9f0330000000000000000000000000000000003ea3fb82fe36d835f9f5ab5558859c0d81ceedc7050cc34e143063d1211455998af1026a32321023bde5671579c0a031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001563cfe5f00d2df0c36e7d210b5eff9c59bc4d1dc3ecfcb4f4e5c710106f21fb73eaaa65af5d06d7cb78bbed8b1e05100000000000000000000000000000000004e2a74d8599b5ece040b4f3b1feb767b70855f10336ab49d63a1b9c32f66baee1e606361aa53e83feb1c6dbe1bc1ef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072bec02f4ee67a86513f8059b837591271faa901929b6f64808b9091f7a217e4f04448e58e55792f4090f961e6da4e30000000000000000000000000000000018e1e8e0920f3fab9df791a471a58bcfb27c54084e2b2bd3715f1d01b2b1698041b026969ca5a13d809d062edb9142d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24c613cb51fcb4cc3134e061cfdebc8893610737c7c500768630b93358d6d3c19e81ee83ffb0b2a3504c9f231fb4cf0000000000000000000000000000000002825f5c0622bf9206d96b5d533faf252464f0cb974fcef0abb868b3c1d714d0e052461249cb74b9d0eb88c72fe525fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001551205296d06b5ba542ba25823bd87cc9c9898b48c39dd8fceb74709b888185c53449d92b0ecaae9c30377c14ef69860000000000000000000000000000000008f90647d74d7ed9705293442e54caf4f331c3c40f7e97fa07d36547747461d75afe87f071cc73d84bf0ad29ca86a1721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115daa4e77e9fba59ad4de88b95ce0733e7da1ae82861759be353e70dece9a6178a693f5c59124a6f8fe338694011cf2000000000000000000000000000000000c3a6f9b531daa61de46a494cc3cfc1ea6abaa37ba043bcf8b74318614372732ea04ffcc37e5e3e245efdad8e0b02ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d15a6eb2d463bc7004717522102ddb7c048bb7ca7fe643374a9fafc550868dd0ecdf12cf58d88b3bc5299e2c9694f32000000000000000000000000000000000d4cb9a5ecd7f5f62f89acd54a8d39751e5077cfcfa21d5c5b73c9b489b24bc249c577399135e0d64549e83f1f69f0fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017c3bf474cb06825f9d31df9b0d983cf475897d308f809e8a0a056c10a302765e22313538ef6ba29fabec27452d4f0300000000000000000000000000000000025d79bbc1b0c098003245f763db91fd53516134a4b19b558f7ec9f1a40508995c8a459767a334ec0cebe503f805de751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afe08e4357382a1a2085439e4ce652023248ab62c74febefa46dbae62a777ddc0776fef72f11b0c5f4c77086d72e72500000000000000000000000000000000153727e76d034693f2b92149dee03cfe7bd3022f080bca053b731c00bdac04c4cf75e627a0b1b7ea85ef7c682cc009231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cadf42f3db8aed3371093348cdd1e4d4892f35356e79092efe3fa1c01348fa479982ba6eaec9d6b24675620486692c000000000000000000000000000000000a3066a049e570b735abbf419b56d6f22c99c8a6b82ab5615dd03dbe42d3d3b7e44fdc3e9b2d3f95b7c32a6235d90f781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f2fc624d7367199404a40d16e059db78a5d19be099e612903d51b48d097d1710114b0e68b338dfc10ea7e3da91db970000000000000000000000000000000011c426147296f53d1a3f92e4d2a245ad517da7e8f976f6c15e2cebff1b200d6c21a7742e48c00ed57ac3192711208f751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168897633c1bd91f9690275afdf6d8fc7a226d9bd675ada7c43f7e996d0ffcf73374a0ab574081a81f378013be38df3f00000000000000000000000000000000187390be1ae2b449c870526065bea90d41978c69e86d1da233094c8aaae1a3702eabd29f640659ba375accef55d7ec461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2998e8f427f82c6cc9cbbbe3a7d2818c86d4708ad13e70bfeb76603adf50e3d76df72450cd4b96da6cb58648d5da30000000000000000000000000000000000f649b7b514bdf7efece32ecf7398afb2c19d3aaf580063bda8c2790e5e67d09729098bcef652f0906849207833323421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000077b4f1cc1ec0c11cda1d5a814d33e3ed25cdebbcbfc56e06afdd5236b5a85ec005e8d7dcbc51fe39602649ce3dc1c000000000000000000000000000000000ed22ba17867716c891f7b4f2a727f9ae479966b69dba7936743a0b2fb229f95ef34964945e47d4d80f806ce593b55db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012dd3161a8dcfdc3717e59831831214cb742e3d89c95a501d9aca857f9d84ed00edcc401a2abab46c9051bc718d8de1f000000000000000000000000000000000e0b764ce409d038768749c8894f1bb26a6ca912df517f2f79117d9b9d2cbf78fbcb65ae148a7beabd549ba5616747871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005009b6c6c0123ff561076f28aafe371296e3721ef7f2a5313ef7b3a587c21716bdf04d4fb3fe704641d679ca8a8b6e7000000000000000000000000000000000108108ddc46a214b28ef445be46e8a887fa0469e3c25b132bdecd0bbc1822d5301425ac4d2a78d91e41416903c2fed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128335f6275a132726f99af7ba3b65a1aa13ce9dcf8a12aac9df392ccf046fe5cad198b75edde85bdfd3ff07432e2e40000000000000000000000000000000001279b924fc5001d64713a433e4d8423748f746cc90e1651d0bee4b6f1e13a76277e126bef6bf90a6e464c3349809fef71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f8868a889101735c5afaf9145b73c0944e86c1fc87811d3b2b32e4f1f5e67e35c1cf6f4dc7e0dbe89e88be0bcacbb80000000000000000000000000000000002322dd1a43e96a876b39483c37084c3f51eb1d943253311d3949693f85bcd8f433ffd14680ce17158ae389c6f2855711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c1fff218d42355fa8c5cd1e479f36124abc8ac06f5b8a0c1db5fe59f341985679dd89c9a29d477251310c711546f6f000000000000000000000000000000000d313913d4248223afd7b4178eb2c4834fdf08876e73b8097dce6696dd3c62140af92892e695a43851e9e30b721b65641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013677a92dae64d04196ca440707b73fce0d260145718604130a60f7912b1fdedaa5ab5e624152c9d71b9a77ae040701a0000000000000000000000000000000008bb0489db64ed84fc6d41c62642f92f2ed969d8d7790ddcb618c2a51030543aefcef0ffac2e9ca42b51ef83a9bc5a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1e2b150b1e5aa7bea43e6fce343aaf6ce512e303fd89c021d0af0c0b9f642293f0d7790826c7d5be31fd2721df522d0000000000000000000000000000000008e4d3375cd225f783db60c8209501b9a0ca1268f57844fe5ea3d794ddba8611ed58fbabf167df6c0d4e74c6077869661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a65464b112c306993c5e43762a2d47a3d937b3c27f826d900c0a30da504c98bd8469e5decb1fa5e5e9c88e2baec36b90000000000000000000000000000000008d53ec9f666b3efcfb8e8c3be5d1b92e747b00628391267553a5f117c0e568f43e510ebb69259f1af649b2c6ce9334e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b4e8fe2baaf37343d10db89743e014323fbf472b0ec6df08ef642715cdefbb005022bbcbcf67a9160a74222fce7d200000000000000000000000000000000011c5ddc40f1d2dd68f7d1ad8185ec622c2008baf72aac69b0dba7b56be57e3a8e7aaba380859dc65fdb5b47862abee921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c708779c8c1f7618b08b4ead0befd4475803f2b262d7f1c2d0b444e7a3cf9bae1322c6356f99e78442d291f986e7d8000000000000000000000000000000000dd914f4fa648701487ba9124821ded93ca3876fc941112a887f80854876ca9645786fa8104002c9c0483f8f5ae0b9a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001604a7a9810c01eedc950302b8d7c6c864ee44f4eb3f6576a893a57306472927927585fc6cf4687804bfeaa20ad91ec4000000000000000000000000000000000b623ab75c9caebdff3f5e2be45e5af8eac5fa59a97cff73e9b4a67244919ddb14655c04f575f71c6834e0982592498b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012943c55ff3e8b939bcd90dcba33abe9485ef534b26e0bd0ed519604e978b327a984b0e2bbde8312afed0695b1ce3c220000000000000000000000000000000002b63d5533af80c6a2eff83e8b81be2469cdfb83cc383a29d55b50896c025bc54c89fb52b1bf345028b62703292fe6851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8f8c520acbcf06be5cd1304321e58e744287e9b90d6d60563cfa4a489bdd1aeff238d1110f1c1da7297964c2cee1e000000000000000000000000000000000c9ae8e0f16a8d1fc06efa2044bde2c835c29e641981630815c9b7aa0b8ec343df8d0289e14c95a30eb62065f07f17b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d996fceb20a0610a66c14e81f14ec288feb646b6e0ae3d5892ffbe68d424f742e69e5b2a79763e923c665afcf9c29f0000000000000000000000000000000016b41edc29f76296d5376c042a10a7984fab423f6f3b1dc587de2af63dcec122446fb67c6d43c8f3adcd1a5afadf1b0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b68faed173f8eb88bde53720e89a690c6b50fd144dd80d1fddbdc9cb5fe2fd1fdc95bb90bf0d67cfd85162646dd9631000000000000000000000000000000000e128a899211c216de1b9bf5c6dbb439cc8602eb9392d34f524948ed8813777e4ce61b4b2a2787768e5d4766144b12bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dd014e3470ab9bb912df2298ee6d0f817d0f0da5e766e51f0856b5c386d5464580328bcfbadc7069b6bfa4ecc32673000000000000000000000000000000000836b454b5fa1f6643b6ae2f6cfdc7f415067686163ba6f650db65cf403e4d153db6653e393e8fa83a794d74831e5ff51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f750d8d974e3cec5b956652a804fe7336d706a4cae007a71db27c984c2ed60b78219f1e7bad810f9199ab96381dc50000000000000000000000000000000000becb5f31f980facdf3ef266998a376aa52bccd8f045764751d7937317bb1a6524492fe96db9aff37b4920f01bdd58c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000367927d68afd21a1ade7cf74d51b1cc8dee02e16c7c3e23f593441f357f892def1ce21956dfe6444c9d0e8cce31fa0600000000000000000000000000000000009a901358f1416a15f1bab3b7790ad32903fcd672fa7c28306fedbef33e54321e9c06f86add57bdcda0ae23a4de554c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001678dd21cc1eb6550fe025700267c71f4a176ee8b2cb0a1bf1f7f79c684674e3630526268af164c7f4be48ee5162bff2000000000000000000000000000000001796f624ec02caa91d2c6a78a6dab9fdd47b0a46f759a8c573a365b3e728caa486cd4574bbd3b991e4ca402f86ec88961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c48fa017b29e7530faeb7d75e0c0bfbf8c308d0a04c40ad69232ec66eb0008807ad25f161a54868e6b116d3f5b7390f0000000000000000000000000000000009482d5f050426e4e8e2271895eec133e070b83f1056d84eedfec52e47022451ab65914b6e9b2bebc9139193e8ddf5d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e86ebe52d07719f30d4c420d1fae6fec1c62707bbc92b36972b8a4484e309098008f76ec41a3b41ec447da1699f0105000000000000000000000000000000000b720c75db0761011ad6524f7a7571cd0973a59f687b59d68fcd76ffe82f54f9a4c958eb47b8806eae5117f54a3346261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3c6f4a158c1437ba61b94a3ab68e272a1583371df4f47f9f829b06ef62d32e03ba901ab885aab0db2c91d410f07590000000000000000000000000000000000e81a0401949cdbbafef0fdcb1673d7c6577e2d995f7fdace5158bdb56250e1685e34ebcd9ffab7f732bd5fca96835091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000172b70db273adbd87b2a338ce4cc299a403a23d134dba5496a838b40836a7f880ce82249e662da7dc11abf6e707cb427000000000000000000000000000000000141bc872c9e033f12016e407bb06ea1d305a8047b84be886c8b3c73e8f87b512ef058bc89a1269e96f9658e1737977c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001501ac1bedcad52cbd1334903a39fd13e40b6e86589f15e5f74e015747c4ebb146975c658cc417e73075c3932a69e0860000000000000000000000000000000014e4e476a483306b71a88eec2b698ddda51985df05f5ec54d3b95799a9458ea0c8466d1bfbdaf7b1dabfdab3ca3ddd381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001103c34b7655affdcfb57b6fe661221b066fd1775e3988c0a838f3e325fe02518fed12cfe02daafecf0f1b0e646fb7b2000000000000000000000000000000000933eab5b19ac98145b41d92da1cbd19da751b15c6631bf312c83d918e6bf5cb39e1d37817e22f3a1fd922f7323b1a021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd813171eadb2c692532718c971839b1478975d63f651ab2ff84315040f691b44a636cd77d335b8943de180db03ba6b0000000000000000000000000000000004dcc3f6a1623d7760d42740114363914522424bb3a30bb380323dad3bca124bd25a47ee7f84d1047fc2f0e35b19156d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001957e261c08709e36f873472dc84050d0c5c4f2346da39d0615498b46a0b281ad74d8a889891eea44f9b2406ac15a1a2000000000000000000000000000000000c2b8f79491957e1ed63882fad1739502ca0eb4e031d763ec3869d9ea20d40a71aa141cacbc7ab4410fc8551b81a63001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dcd7a1dc8383014c2e53f77a09222ad05177c5f85048422ed33993939cc5fe46c8556999d8e0e4550bade927046a4200000000000000000000000000000000013f5aea8875a6efd8497313d43cf94df191752dc25ba2bbfba24afd8cee7bfef5e96844e3a4db2a7904395ec4b8ce5131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4279b503b0c0c301d76a592e6d2f9c3726465e590c37d3545ca6542e122f5e4328566ab32289900cd945c37f0552a200000000000000000000000000000000031bf47d718b90112ee9fd78226b20f0657c0ba6a37bc0bb4caf2829bc8872edc35a266cd353ddb62af716042d4f216c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f148360d0083c297d6921baafecd9d61ffcd62ec138911390d2b8101b4bbbe3b7008c9043ae0d1d2eba9e53ed006c7000000000000000000000000000000001309c867c4c69a4eca2f6afb41aabb94b024493acaaf959e2a2fa81e1b0ab806cc18c6918e390f48edcc66419915f9a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c245499662ab3e7b2ae00285d607b9647c6c7ae2e204b5a97c0b3996836daf31435117766e07bce4f3593c23321826000000000000000000000000000000000a0760a36ce06f953cbbf1b7f563123668c61d9be4e97cc48fbddcaae2552183f2254b96e2a41a4d8de42c0d193871c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005ea761fd5b0461d1ba9d4b48006df4fe9fb19ff29f146b434a02740c5e74bb53df3576990f18a05114f78bd5d7ed7a00000000000000000000000000000000103b5f50663e57b2722648328ac493a2fccab52b7514aadb5d5e7d7f55ab47a89c3590fa0ff965023b877b1b1742a9fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d9d31925a54c5a157dbed363cfd942094030bb242129f033f1ad99c8f3334fee8c9e87ab462a60cfa3ecbe689d08a8000000000000000000000000000000000fcc340ca5b19ef6016c60ee40378e8eab062e6b1970c6cc1456a9c910e65b038b77e6ce985b41b4c718e8669c43634d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53db4a679d9ccf8b27953ae848b62ed5ce9eb7fe3d7c3f43becd9b65575e950cc6cc2d50067ec93603478ac0276bf3000000000000000000000000000000000fc27dddb4015a59217352e79de5b64e75b6920860cd470e2a101ffdd25961d19874bbb2c7ba02e9d351720d8074d04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b026009c5570c19a180b7aba4c7df787bce9317f2f0304f47e36598125fdb777af86d5183954e487f53fd05b63504500000000000000000000000000000000025b7e38fdf50edcd6319388272d90238b1ce36b9da1976c3dbb7decac346547f066d83521d3d0ad39ad288745c8add71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071cfbaaa4b0b8ee4aa60c7d4a78a72217f8753ee92111f909b8f879c9604c64119c04dc261554d4e4f697caa36253ec000000000000000000000000000000001993f1efdfe5a11792f01d16449252f84dbe49ba5fe2a0438fa6434068bd0a607ed8592c29faede46618f5d614d1adfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000206dcace6c98749bed6964144ce12cc48ad114a6d24b8b579a6f80c1b79ea349a95a28e240e7616438abaf2914bd365000000000000000000000000000000000d680937d5fdb62b9bdfb1119677a1ee76cfb88ae5bbf6b6978e3b6952f80990cb24ed1244649792f31b3b81e50c7bb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117355f94435e3f3f8d94b44e60a5f4193ad35a1f8133b08c7248fa3f90403852db5e0df43fe6d1b7763f47c97e29a2a00000000000000000000000000000000125b25b10946497fe0c955cdea32a400c6c92ef29feef6a437a62582a3c30a599ad8946256bc24fca27379ae8f1362841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000125f0b2a45e4268728692b9dd31dcb4cfdd4b47ae6af83ef4353e7ffccf49ef0955872ca6ba722b86521f6f3f01e4c000000000000000000000000000000000010b934c017a3ffecc0200a03708216a2264ead70b327366a3606799a32be2af7a9bc4db4e5124f536cf4e64c291efd921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091e899dc27cde1a46164ef8649bbb852c112ae8aa5f04d7ef1c7aa1d000e05db4219131ee3bd1dacbba371d0e03c96b0000000000000000000000000000000015e8a7bdd71c6728473524891d0f26977b9b97de8c81230204dcede5528255459a96af94f149d1b657c7412d14d2c5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016cd4344819945b32731d44e1e539c004acd610b215021a1b7fc7ba9eafab1041fd4a81f9714379f6f8bda3651c022d000000000000000000000000000000000e4f4821bac25d98c1206c82d75637baeb3ecdefb305fb30f13246254ed71065b7901c97988c140cf485abe8e1b47ead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8b9358fc990d651bf5317846a828ad350799ad5043299d0ac447a9f6f056f8e5e4aa28a19f0e4311e66d1d8c2f3ed70000000000000000000000000000000012c8ceee3228491769bcaa5d50cb679cbc93962d5e666cbaa0c9c75b9d87a6131d04ec15c75b6f8b0a3570120875c3b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbd830ce4b3eca944a6a0e92e72a29d81c8093b6e345b1328e4e6412ff9aa3cb634d2fe0532dfbfaaee2e59a5a88e47000000000000000000000000000000000f4b126ad4a48e747d3f1424c20fc96a24bae606f69e6d7f8c870feae982f1f6e22e341fcb4246403e2aff38eab83aa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001510b6b360e4453743afe2dba6f842a5ecbac0d24d051d996a819866142c2e7ccaadc51ad2dc3f80d1aa9957e36508b50000000000000000000000000000000000d027199631371e637463feae6b23c79e8640a40d501853b0fe810faefdfb065cc91466d7d63e8af2a2d0f2f80c70db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000953fc9fa991a6d24f4b5817b2ce650f7d6625b811e564b1fb842b3211295ee65cc80fa4223f0cb148a1fb0a34047887000000000000000000000000000000000856fce2aeb9fdd825bb702878c7afc4717c074bd67f6282d873fa00c6b914cea334429c0fde48cf2aa9fe39c20c3d2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f191646daf141bc7a1cc9143d7f9b045a7a4c7d80a7f6392ee1bb551bfabdac441d5f1c5aec18719802a759239cc1000000000000000000000000000000000c2bf7020c348dd55704a2ad8554666af88ef2566c41fc27132b33fdb9a46d8a16f3fe9093982cfa2d4ebe7ba40a0d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000160929cc188795a485521a14c1f77ae9403af77cb128331e20c52a7ac03702e4a950d414afc376f64ba3b40008508e53000000000000000000000000000000000d412be7af9a8b07922d75259238e21b3e43b32231031bc40a721dbf0cc4665029f4edd48d97e9e3041e721c634d6ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ab68153c029f70d7651fc01dd733b05a3fb39089956d1e26d16792e6fc73b4829b8d124c6a2e2d11a921e9c46f48a9000000000000000000000000000000001395a5572fb70138eb7b2e249619da24c2d4ecb1b7bcf0df9df3c93fe2d19525f73b5bd003029cc33197bd4b789f606b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bfa06f07d6fe983323088ef936c43f0eb6d3b97f10a4f47bd3bf59de7f28a29728dbd4c744b722985fd1914a00d05e000000000000000000000000000000001028d3e3b839d4fd34490a8762f252a37bacd64460cf37a201d841608d9a79b6ae1fc8fa570a6452ebb3bf7c07917fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ed0876a13154fa0cacb313dc42c37eaa8d64bc99a1305cd3905c82a56e68f4b4d9077fb935d68e5feb0869cd2af46500000000000000000000000000000000001e9fb29a9868d992ec90e667f12e0590a7833c705af3512ca4995e13623e24fbf34369bbddbcefab6bf59c8b82edbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a0c8cc7393446efa0e4cb9fd17ead656be2207965d9f5f19e799d89666e19816df8b7a25eb6ab02c1118a1867589400000000000000000000000000000000008de71fcc238cc1e74dfec902e0f68224988a536687c9520bea55f39a2baaf219c3071aa167c68fa6ff16997c464e4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018d465e7ade20538a98bc8b3190574fcb5bfe4b9d724b6fe4c5a9f2bc12bd6bab9ebdec9f01ed0bf1f0aeffda075ece00000000000000000000000000000000153fd60245dacd425212c695d45f31dc052f92623f8dc9b42def6a20f82b7b1af282528bbbd9282266c0ba30f6e73a991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9ea6fe522a437648df336d3cd95ee9505e1bc6e504e3282bceffaffd020b51ef2fac17de6d96ca1a7978f4f7cad3ec00000000000000000000000000000000153e9331b2c64dac21677f6e1debd22803576b875e5c516b24badc8d7c8ee1d189abe7409c59616c0fab7644f04679d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004141911511b3b3d12ed4d1a68f4b8fa986f3d213a30ac3cd1a6f3bba7d058dc0b7efe2483658298c69bf9403ff5eda10000000000000000000000000000000011a6f6e45ab920e5c3759058edff6ac5c32622a34c3b931979a8330de1aa148b63eedb8d905218e6d9580d43df989e2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056ee21f9f1be6c5c718af606199d91a8029590bbd519b2ebd562f16e2dc7234c27b2f831eb8f698a3c553f1a4704ac60000000000000000000000000000000017842894a3615d2e0b95771ac9a87aa935c971b22ef0c106246642fd56008eb3d1886b08f2cf6cfbb641f54097ad55e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000202305552441f69c23913149be1b613fa08f62b356abc6c83e1d751be217fc4fffe843bf497b930974d93646fc2441d000000000000000000000000000000001951b70fd53be2f4d073c94344dde05231fcd62ce1ea0932e5d3d9ea6d752c16ceb4f3c4462061f3b317a6edb50a1ec21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c437dc972a5c3af341a51569a6dc4755891c35b2a99987cf241270c1a4c151458e5854cd3d1a9aaf8cfc1f99dea2c400000000000000000000000000000000102c34fc0819de288f35ae8a3b30621e621dda4551661d78dd607c4819963a344f1bd0f450dd3977db33dffcec4ff57c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7d7cf7d76d5d0070a4e8deaf82c9e824fdd0470a0a9fede3c7b1a2cd74b767b5bc7fd57de092728f0e669bd0f06336000000000000000000000000000000000e9807a3a67d1208f9dc69b0d72bfc6a54ceb92c6d29eeb4d77d6eb1db681307f94b5f0dd0156516b354e547e00352251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000523fa5edfd6696fccfcb38bc0f667fa854e2be8657adbd84b35e1293461c44d0e1414c6ff100c1d92763a17604a9bd70000000000000000000000000000000014c5d79520ed5b92d7aa273d1d58dc9d6dcc782fd1a7affd61610a3c8729e9de55282c782cd2b9320ab0ef989b5de7301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f1687b6b712512cc059cccfeda62610d896362d84bcece1174792471852c1b1532fdc44d13324257adc7ad803cb10f0000000000000000000000000000000017e1ea6dad6438ac814f67d4ac5d6d282acee53503b389e9c77723279f015bc02b0792987fd2819a5d85fb8608eae3791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa86fffff4db66dd31b506b7617f7ba8ccbb1cceafb49445daa4b571b44b41e711eb0c3d665ab20ff0c25a01d42b8010000000000000000000000000000000011a6d3137447dbf60cb47318a03aa57e6092cdd0e4ca9d1bcbb8cd2a49b4eaff2db61ffde9bbdd0f89b1e39f163e9cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c3b84b02b287a13d6be04188c32f276e0a697ce1ab71372b68ba58cc56592891cf772ec51c1f3f200a2b0339c845800000000000000000000000000000000006e8b5c01cce52fe6b04a6862a26ac06d320f4ac9953183952b5cbad330c62d6ef47e1b9719ef41e2c14363fb2d5d7ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccb9d14c2c46a6f3b1169abd7ea38e402cdb5bd6742c2867ec042cfb14597db7d42f762c58b89307038c2195d96691000000000000000000000000000000000ec47860b929ae2b2a64cef53c562d61c8705ae0e7fbb3e164190e92bf561c1f61dce99d4e715aa913e72f8475e9a5261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000522aafefb62af315abb6641a795d08b92eb446ec7fe09ac1a690b1efda72664c30f8936df44a4aa7afdd6346d05d1b80000000000000000000000000000000008fead14260e9f07e697aa1ca4c2f9a5215571c6cb281f75c6fed8fa3b61f30bf2141b2429a8790b51ee7e25bc0ad75d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4d81980e3cf50a9e9f770589ff9729e4b5ac62761797df747914026b9e0f9ef6db2d95f56d28ff98e3c38e28c2776000000000000000000000000000000000d3c0caa1c51a0a060939e1403aa9ef4426a2a10342c6a6f2255e0b20f65443e9e25b6403cacf3d1513651512500d2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009242e8176792dfebeda21badc305e275046236ba9f885b58fa07223b71bd68292430a64135ba32de0729c6b8a8e395d00000000000000000000000000000000002850d8294f406e15883152840e50077e3830667faecdbc440f43aba0f6dae7fe867362a74719b605af37aadff57eab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193d4ab7a013767ac6d6742a0dfab3f5081726f8ef1580d9efda3b323bee44f63f2fe715de287ae096c60fced81cfdc80000000000000000000000000000000014c84d6b5dde20cd9e800e7df887151bbb66d029109fceb9b176d243db26e10d7465599c0e6944c9c7b18a61e331ecce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cba2968f739aded66dfc79162581be27f19b9b6f52971cd1645b897f21136cdc21a7c2b0c8f67e4a44675761fdf97d9000000000000000000000000000000000dfa7e5e8aaadef3533ac9197f36dd347eab1c1d0af5197eb5698c2586d02a332fe1c74c37353f8d523eec67fa7cb64a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073df1ca45a848054c36204805987dcaecfae5616bf7ed27d69c30beb3361ffb73f17dc03af49591475943edacb225f500000000000000000000000000000000093bf03e24e1ea69e2248c8d7926ba8d1f87fada0ba1203e691267b95b5b293995a6d4b94e3ece2458f4e686b597402d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003933bbd0f2fcebb39476c11d5dcee0affd61d63f4ae21432d5f3a1fb95f29ce95d46788569cc7762a43b4241103163e00000000000000000000000000000000009429e37e8de9b10af669c968232820f5fbaffa4396b6da91877c3387b718de42b26e454dc2bae4b591ce3fd1192e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec72c5993613691e5862deb3befdbed1f284d5e0053711bbfbcc957cf8e5002a34dedf702b28d16ddd058240959048f00000000000000000000000000000000189335bda22740b5f719bd76e8d81fb47db76ccc79de1109cafbab78981d8766a93bc233f863c3b6699bd71b4b773fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140525d69e3e5a331dee6760af02707e86d48f01616b75e806f3c4401dc320b16570448aa29e6926803caa5f681e738d000000000000000000000000000000000edbbb746d6ed51d0b483ae42cc27d07784bbddc544b9c80a6cf3ff5c3ccc0545a04c0b345ac5df2231fc6dff60553871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001be6365228494d7057fa7302a4132aed61e8839fd4eedc8a1c77a07fd2c4d9883541d03b793f2a7ef581851580a04c200000000000000000000000000000000032f2247390a70b4164fcfcbc680c292929ed618e3b3c48441a67207f866302763c5604f768260c8ad0cbb7ce2cb697d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cabcd365f53ed1c8b2daf55ef71ef684c4710aa3b783ee709b904b37b333c032524eae931b25ead6dce771f89a4fbd60000000000000000000000000000000010bb62798b89ece568ddb039c9378e9dac1a4bb7db1f264d07bc0c04788bbe8e6e7bd430ffc0980380225b12113883081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187e3d59b300c4843a83dfde7f895ce9891ac298a186cfa5df708b2a6172369ae466cc9f43b7a064339b06b0caf38057000000000000000000000000000000000f9ffed1785032752ca247f728a4b33c1be1c96f51229ec0c29fd6b37a479011d397f7bf4971e6e8c3da152254d6b9281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af96cd0defbc78806c9e763fe8efbf77686cd25d38af9005d4a63000b444da34731c77b86df5d365da1967ed0e549c3000000000000000000000000000000000fff26a098af9160e0f99c5f61348c6d45ee37d5c6025d03431f3c2b66619d7c088f37f61920d095cb96bde5b7bd63041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663649bcd5437be1adcb8766b2b72db33cd1b0941154e638eec4338514c5be053180d43451ce28ba134f174ded72e1b0000000000000000000000000000000013ca2fbb46b5735a6394ef3c57312b01e6c317d9eae4be8bcf698a422bdc4dbdb0706bcb460332caa43ab73511775cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017fb6baaf4448a7acbf9a36637917f8512b442280089a3b691513929e6efb8f87a64343c0eab60f9b117fecf6fbcca440000000000000000000000000000000015e8a65c9f8ae703cf42c980ef3b8092f781e37f241954fde2fb5015f4da739aeccb58a76e43ffb0ceef721302ed3b301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040757338a4a74a8ca239674bef884be2fcba5fc027b201e4f7c01f7eccc7b22a0dc5b04f591461c27157458fb293159000000000000000000000000000000000ef3422dee73629375db8f079c5b625deb88faac9c0933ad186272d1f3027845821e409a9e8c21f94ee256c3d9f361761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063173b639fdd9c088ca88fa763f994d64a2f3686f0ee1189b5ec4afad1d43ee657012bdc78e1059e5268bb1818d617000000000000000000000000000000000075d874b508e7e3636b2a431ad143303b25c1bc61844d35c48e9f92c12fae0b927ae996182a4cdf549966ab76fb5eb4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000909fdd9007a9801de1d95570c4447731dbf785fac6e062f4c256b1d99662a9fa14b1f1da6a24b9cff16bde7d06dcec4000000000000000000000000000000000da1a9dc6e21733f57a1a33a18d10b85f91102692d9929aa50f0e0c3520afd32daf6e37a9dfea5b6ade3cb2ef10aaa6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8c24b764e0d8b1f50d703abe6bf609f0062f536cca3f9077aca161fe7ce65dfcf49f971515f032eff3a7c0d0c7e1bd000000000000000000000000000000000e77e685370dd6b39c0eec6fcf8db4db494b3ef1c57a362cd24fd6657b103a03a2a6d45d9effffc09bfd21b22bd37e211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163bbb77e5cb8c8601b5fb1bb09ffc0011c86837f3756c9db4c392d886e34523e7823cdcbd4bcdb50e516108cf26c035000000000000000000000000000000000943a59903c980b237c3f8b52d736e041d2a0531d0241360c7877be68ab1a42f9f220f830293e557a14fc1a997a52b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112001c3194be263338e746a29c4b405eecbca49539e3d8158ed871cce7b3f3efa6e85aba456cd5621171321487a3fe60000000000000000000000000000000009a8bd5cce84162f6cca7f1d9924e9a7f7d8b74bb728f1d499ba3b5efbd61c66ff278756cc3212488b5982ab2ba834a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b47e7931747139f10d4e72de1101209ec8d62d62c3da010d3ea2487ed04b0e4ab7c43a34104dec15746ffb6dfda3bc7000000000000000000000000000000000a03961ac974e169786c09b9cb07eec65ae100d3e378724b7206a1e532344be77ea3b9533f89c44e5647c7039ec7ca991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015be951aa77153fdd9635b7a3b15badacbe4348d5278ab172035a75c6e4d82899f18f61219b6e96a2e7889919dc2921f000000000000000000000000000000000ea70338b206b57eae14b042ceeff73bc2f84f1c199dec82cdc9a9edaebf8b38b1f76d3421acc384d1f0f16c627a52ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a02c674268a3a383b776ea2a0ce972223b41e74b40d24791f9f12dfeeae5310f716b8254d3cfd04ed1aef6a0103b06000000000000000000000000000000000ed602f1c6a6a47399cfae6d5df6c3609fdd7574c0424d074da5ea85827167ea3abf0c672d833983964d4333079febbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f32b9c4d6bbbd7f376d84f1beeb6717bff5fdb6c8b8d6bcb6ad18b977eaf52a22fb2881462dccc71fce685b743a9940000000000000000000000000000000007f610fe504df2c36204508669bbbe589990b54e117c94a7a7c17134aa12d08638d99441598ea82eace7b783a37f28421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010427924d67255ab762c989895699c348ddf8e8450a84299c82865c39b92dfde00606e6a5786bbb779eb9a5938f4e88c0000000000000000000000000000000017cc2620bc9909b4334fbeed4f3af7be5904e40f175035131a7c5b244871638809294d90dd7cd586c00afad77a67d2841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f2eeaa9577bc28533376fc3e1a17173a47e3d5cd2cdcaf76b881649cfbdefef3de08ca3db6cf84770f0f29b7fbf9fb00000000000000000000000000000000133a76b0ebf0f23ab8aec895a9c425de294a29807268fd005f5ae786efff0627f9f032b1246daedb5857f59331c8da8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000022ff106000ebf7a439cacb8a19f0a6713a7d8c48ff47b2841ffbcd89c7020b2dc12dd8ecb552be379427c914a837f46000000000000000000000000000000001633a8b62fb2af48f125471e97abcff7b408838e4f7bb14b09e94d09352631389afbfafda128a9adc21c4d7e597014af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dec39917d12e465c6e5d6546f8ef132c71c0ac83db9481d0ae9df66fd5adf6b83b40bf4b554acd7df487a06b7c7420000000000000000000000000000000015e87fa1b5f355b9b9ae9ac8631eb1597c03ad8db3f37619c081a112cfa07e891869514d00aa26d6d1fa059a76799c531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001389b72d9df5b6a7c98045843f19d75e26317e8d6600b730cb2a284d99be2dee516a7b685e913b977687f3b6db370c57000000000000000000000000000000001749bbed9957467ba50eee0bdc19535856a075e59e32e17d0f7beb0ab6e0ce3cbffdde6cb7407e9f1fe5f013ab940f341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014898fb09090e31bf8f4f7116a5ee09997e148138c4ab82714664d52b0e99d081a0bddf020968cdecad37f5abed48557000000000000000000000000000000000798aa0d4c6cf9830d45b2f2936a6470c7bdf4dfcceb91a119f639cef4bb2bf3aa2668ed8c1dc0732785be2ca95b566d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b2522b5789998e286b10c27498cf1d4fdd7f9f7d3a1f94093956c8c20abbac24d889d711d949b546c96572717ec0a0000000000000000000000000000000001958878c3be8d14182b6a29b0ed0f6f342db8894031a89b1dbdbf727a4e53eff83134a24c5ca9d5db5b6877fe258fa141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006678a0a8dc1fb64baead7d09427d370970d44bf3a4e1311f0b9fa36c0e4aa6af1ad1108d8b15f484dd1732f01781bd3000000000000000000000000000000000ec4b2561edfc6bebcf515b7f0c00c9bbbb601b788dea10bbd3d6b5fd93b8b940dd43ad3422303e4da39ec2a892672da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000846cda4870c3074d8a784bd877582121c0fc3d9ab8af07064d2cd27ffd3ce3d2af205620c2fe989660137406139d03600000000000000000000000000000000083b4ab1690d9cda996996672f2245cd1137f97b15f05b0b978cfe8cb226ea30628523a8b3e8bca0d2869bec385b9ebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e801a2c295ef5a08548c771689144b051f29202fbf6091596110e6b45186917ebea855915960317714e476232b89ea000000000000000000000000000000001003dbafd6b2b2e3c7de2e58129682db674e5721d1121eec3a037fdc629edd169562d75f1a46d294c340767c03fccfb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f3c05533ff8107a1c8c7d5fcabeac5de0620d81a5279759ed9eee3c236e2bbe0e568b6b059e2370b8e63020cac910000000000000000000000000000000000d20cec953b963d16356b1eeb3cfbce72404fd96a03f90a294aa95b332d1afb0b545c860b9490f7d1f6694b509ebe1061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8fefe9d1a7db70a6c3ac6403954dd3c392622b890e11827fb86a64d18b52b9ed729f9273ae91dd953e4dc9cd55795e000000000000000000000000000000000da7e157466b0432d3f1e384cc11908ae5985d071e221966aacd0148af8e6363566a61436c8f7ee28fc3c2a5631830c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cca1c0c766218ef42f8f7f1c918786d6be3a7ebf3e9df0f7bf8f810cc57852af6b8bf5f377d81eb8a174c06a3aa20000000000000000000000000000000000107b4bb4e33fbb20fc8c88f76544f78a6d4d5923bd8ec90f573e5730f83b4e6646c8bc1ff5f7470deef4acc5162ca6c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa70f8de2e6bb050f35a63e0e62e0c84c5120d1ad6160d42d25873ecb50180624938dd7f117df66df9b40e9a7142ac40000000000000000000000000000000005b114dac9b66fb65eb56818724740807855af818141bb2423c086a5fd7f9b2f4e28cbef891a74c6c3c35773184f4a931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3a213ede740aa9c3e6ed1e36c32d5168d8de00db430bdffbef15aebef56d7fc5420b52c5ab19126a9545aaf264acbb000000000000000000000000000000000c75b72a641f195b18f5524739ee5bcafc6e36fbcc134068b01638df28e86247359367d350b5f13ca957e3e461fd21441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d8e5f547ddf60a9cf321b5546703a396046718828e646c20a41f606f1a56dcd9a543777e781572e416dbf4a64b69a600000000000000000000000000000000097e7a888ad3b117f5d98e60f2c646fab19cde95ce926c0cfc9bba18a4b2fe755b09266ada7b3b2eddd9304dbc637e641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010260149cabedb03e1bbbdc88cb1f0941d53ef5582b4b821de7489ad686e539eb5523a90b689bec4ea3d36fb3cbf05c900000000000000000000000000000000047c48a67399319b93ac0b4863b5da9f4c18616b183e8ec068d9e410c840451e9896de3b7d64c6a23fc13fda470e62d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cbd7e94afae4f0c5987ccc728915a3c6cb68965975b2e573febf745daa2d988a8ac1d9b41c86a6f0720019f4c90bac00000000000000000000000000000000023938b0ab049aa6adcbc6046808b0b399b002dbae87b3e3c407cdf8d20c6cec77839c5a6f8e35fa9e533a2c2a3d15671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092f46beca3f0bc7e265f61104530f00c6db87dda039a8235907f060361378889fa2b42d7e8eb644751483b10330dc1d00000000000000000000000000000000012c196fadc1d6297d30b4548bf241288cc049e16f79f9ee2109deca82279a22b51b751c15d9082b18b4c5e541c4cf441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad2c50e2e39175760977aa6fdbe3aa99c205d43a402f98e0beb93398edfd143a3694325e81243c416457bedc89be6f80000000000000000000000000000000015b74241056527fc75863a2b59b2ddfb076ac460cb2c48dd7d5ba4d92f36dcfa7cdc4a7782b17513d6879085fc93a8e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf1804c22fa51c6bb601b756ccecd020a105d991cd58386c44bba991ba1a89a4aa900c36215255b4833de151c8a84760000000000000000000000000000000005eeb082c4e15a51dd7e047834e122ffb8c43d7824ef68844102f7484eae9b8142fe00b4c8555a6dc7bd283137bdd2491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000863eeae18fd883887e68fdc27466f991c98725233cc662655d31a721de43855dd188d2a5adc46af7f11bb9a1f0210200000000000000000000000000000000015229dba420427d8b92d0671a9608b36833830f217555016b5b64e674cac9e47c2e4902de959b76f1c8f6f95b940a4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c25f998e4a620c4e0d7ada6a84fa692465b0840fd0b3291a0c97aadab3d685272a1195ee2d1f5df9bf7ff5ae33fae6c000000000000000000000000000000001815b5406771ddc761ae6faebd3b18d873c51186ace72e57115f7e0105c4cbd3dbd11745b978f034112644ff0109deba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b22c9cae4ae714cc1f543b35c95d4e225925953fdbcaddd4fa93f321d00e82bad9b92d6c0a88e21d77ea969c0023430000000000000000000000000000000016adf022f5bd3d34cbb70f824184392a7d3ec19a4e27132f894798b9f6eea933b19ae0b5925ad7f7c2174c92d5f30f221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c5faff3e186878556ecb9a88b1a9a554504917c6e5cf5056fdfb9dacff65391908ba5c77fa727f04f2d68fa2b0acf000000000000000000000000000000000c23da7fc5eee2840cdc83fb05d54429cff83f16e7d86193932f1f6624be8f1fd3e4f83e558742bed041013718d509001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e9c1e7aaf8e9bc3cde21530ee67f9adbb83e59604aa1f92b454c05dcd44d6a88405c3faf25c424c5d215faea27c8d64000000000000000000000000000000000af9864b7f34e0334dcf718e449538170f28bc4cb4ba05169a64c0e48de7750328851e4829b7b2df27de46d9c82147d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a657439d4f39103f2805dd02150f960037a82d32bd69f275f782e98b406ba5443ac0aabd837ef8913683f05be92e0db000000000000000000000000000000000ba380b5ab7936611e81837265334057e5f7735180a17d25d804ea027bebf8ab2f0bebcb7ea048ace4da33d0c24360ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006eb88263278f07234ba16495f69a343c102db2592592156d6b0b2f52ef9c2dd80c7610d619fc77888a716c506071cd8000000000000000000000000000000001508778b26ccfdbc8dacea81be769a0c746f16a1903e9a01863987b0da4bb210aab273271693727ae633824a06c9f9c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006149743b95562dd828284c1b71a39e88fb3b671b11f26fdb4b9512a01447b02311b5954cf832f2b929b93f2630f3cdd0000000000000000000000000000000009cdcaa6c6fc46a93a785a373b33c802161bc6196e4dd530b6630ffa1439968cc9e5762955c39aac51a878ccd73c3cfe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e433e884137ceb3566c3f6fb021ced4a870e5e4791606ac3ace7c239ce1c71c777928afd40b063ca7185ee2290851d0000000000000000000000000000000006b16c5b9f0508c67a5e04ba9ec561e8143e0087dad3dedf530edba58f2ee55c88fb01a0558657b8cb740ed4c5fefe7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d78aa8080884f5011b5387225951e564e9acb244fd30375fb7ab7dca2d987997ae57460dc4d152dfe4d2569253a09fe0000000000000000000000000000000019293184e1ec51d9f647a49a83e7ebb0d44ce284b79ca80ee121b40c2cdaaad676ce246752a583ee3994cfad3228f7d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b94d1fa22dcbdf751559076bbe7b4984e54ea950448ea7f9b7171bc991e174bb6342e2da21fc4e25a2913f77a65b7dd00000000000000000000000000000000099ec2666f4d652d0ec87c169bf21713aef5ec89a4aba2b63ea55cb794273fc06d17b64d517c3793950e1f34bd341bc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a45c2df5d29c66ace36fe9f9c0c51a25db2ce3ccf85e7120f56b5bd70052627f42cbc7d759c8988388ccc624701642000000000000000000000000000000001750fc73f51c406f08a0462604f751abe449f4ffefbcd7cfecacdf6e86613a2594a17c9c004f9d185b1f23f2e8bc18181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000390eb16f841231aa50a666b4ba440648b037c8250b1ad96cfd349f00e7019f475134dd108cde5f915aa25c3ad62d2ce00000000000000000000000000000000096debb24dcbb6c5bdc9bef9709a88ddaca6ba359a15c6baa04b50710498bbc214b2a8ac0ae67354af48bf4c7c1f8cf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ca70a4768c019388804ed3f9798178790396ba3128fd5cb266fc8ff715d5bfbbb8452b983383e08b1de80f939f7500000000000000000000000000000000001b88bdd3e40c57bdbcfb573a622f0a02c7fe7d13e3b6e6aa60ac105c20f6fd9d6c084dfe9735f8f0744f3d5700ebbb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c4c1cb2c4a404b456a7dce47282a881fd5a971766af43b9eddbadda793cac9264a2a227ea6f0ccc71ce9f0b70100ca0000000000000000000000000000000004ae0ec49b5c718cb443cdf08c68e49371630371dd7057c7f535ce5207cdaba73cb2621deea8e6c83ad858e7a6a5cdb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcba72b846275c9a54f9556bd0da65c883a18cd257df6d4780c14aacb4f3e470138e0c7793ce8f8505c88bbe8045d0000000000000000000000000000000000e3174ee1f9608f33962a4db30ef247e7ee46a81061bd1bd71fc3fa543e51919df45b30e032375651b6cdec1de1a41861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092643dd854ab10911f3d4e2da4503caa4b13962e6a02f3a8b1aeb96f807383b44f3acc7519887c7676f94f15a6b0077000000000000000000000000000000000ef023afa1164e59bc4d52e1fe2f33622a44f300644eb06cc83ee0af18423356fada0d5107c2f964c68fcf8bf11c7cd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001099228e31111d2c10a4f8fd8104c1f67eceb5bec7ff3aea03b668ca0d5ae3d2c8dc8bd878b799d4e4b01d3512e8e70a00000000000000000000000000000000043c9965c26748001c2c6b7e3e7a2ffd6c43db54d0ac293867e9b5c3fd539c4f10eda61b82c5f01315d21dee4e7d1bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c50e0b7fbafb1761729ee402f1a0f9b1bfe87e050d1f9b51542c61b2ce0f9ba9c11ffe2828643eec1ecf682f87d39d90000000000000000000000000000000004eb6361827929c9183158653ec363c398f9ec85c3d5001275198e9445b1829164ce8b3dc83e96a8136ffeef7c843c891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000900e4c9c6ef755aa4e83a6229f4d4f14adb016c2ae0e0a6a7950de16817d055f7e7a520da3e40c881aa06169ec4a78c00000000000000000000000000000000110cb34eb673df99c751ce4fc8a6c04a829b531fc116fe1148ce99a8dea916da2e027fbb6c37aea16a4cd054649496cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1b3f4ebc406c848e108614dbc73e3f179b30ffd8a112902386b7464ff5cbf0e1353310d7f219260dd133b93238c1d50000000000000000000000000000000002c93c51ace18c4d3356307ce30dabde82b606ba3495442f93b90511c7de83f391a14febd9fe0d6560ac023398f4f3d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fd3ccbc38b3d4b37398c0de98cea545ce330bb8796f3ff34b0434a28ed0c2724c1b893d5d2a098fcb317b356faa62700000000000000000000000000000000043be6c305b8ad9231fa9796ff3d8980b0ab970fd1cabeeaea740fcc77fb25a46660223dcc4a6b82758a1b5949178a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f336849e1462c091ae6b7f30cb73d9cf32bcd79a405a28414b12debbbeb8b6f4f6b13d3ebb4b6abd28e1776d3a86311000000000000000000000000000000000472836464480aa64952d8f4a3f5e47fb5e72d3735a98bf9d40bb65980bd68fe7cf39cd67ef52d995b972f0c6c2455f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000917749a077036c0fcf68ce4db9ff9fa9eed138bc29185d6489e7388eab0158ad5b5b89bf9c2644f886767ef4f7e4bce0000000000000000000000000000000005240bc863997f5d079f2faecc00aaee7bf67ce298b5a9edddfb856dee127e548b3bfc8148320641cf3fb5e8b3ac131a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad3a1e0b636f92f925c18f3346c955867b17dd27a9d1bd7a8a8dfeff7dcdbcaee8b0a7207adcd0c999840f7a542d229000000000000000000000000000000000cae099f13d160d85abbcbca16270ef6b14e8e1d56164b58bdb7f51e8d36f4c6d72116423cbc9d44a9d753b55ab890f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb5ac9e5504c6aa9925fa6c1034921eed0d5818b4d30c806450ab5101c962bb86413bee10f9d18976adbdf6125adf87000000000000000000000000000000000d26ebea7d5db77dc70f43849cf7ea4493af4e5297d32f2ad5a8ff5d2fa0939d5afcfd1eda12e0e7e0d9686e8bebae951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f73ba8fd68881d40d7c10e4cd954e0dd5628765539bfdc86b1373c8a4685305e3c0d01253f9c4d0175fc23b6206efb0000000000000000000000000000000016eb923af7a0f173b5b0b5688347a8017cc22627706eaabbd169676edf186b3fc68cf5a7a743726490d515a06364b4661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001046f157cd0d5e3312a76b413754631c3d373a8eb2a8984e064bef03032c4c1ea6dc7a64cbc47ca167a8db2daa731e9300000000000000000000000000000000046ac9f6e3cb96aa5db209fdf837663e39f5288646bfa894033cb7c93c06f7071114e72cdfa26fbbd329f3b0098dcf8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008497141370663ad0f2a0fda0709704d0043716cdf2064ef9e52bc6b8816dae276d5ab0934cfcc0d942e865b2edfd8c7000000000000000000000000000000000f40a40126fccd45652c5ab2b887bbdf617082948cf536cdd75819778514b77b64c9ae48777fdf1350ce541ba41937db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074de88b95c3eed5eaf8f820572aa6e38c35df4a1252ec5547357ce63bf8d5a35ea04f620997db0b58fcd83bc25767ac0000000000000000000000000000000012f16ebfb1e199b4c9fc9780a6cd5aa0df4e274fd00604301a07c98ccef6dcd5524499eabca73774196243170335b4701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124ed5f5c532cd74a1bec08e144c5facc450286d9e49a33182f4f87db23c1092779e7a9e45a501786ae34f1dd609ccbb0000000000000000000000000000000016f703a97727df8c50acc45e8394bf5857f49d7a3127a35382af2b74c834fd7231560c60ea1328e69a6a8a87ee0a8c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001230242be51a3b27f23b6ec72610a64d4a25e51e422949e7fe14244500e328229891b77565d72c7fccc554be308bccc90000000000000000000000000000000014c59a7845d6d73a361d9e5a9b57baeb95d4a4bec542e942121df7aa6cfbe780c603212d31712e4e359fc8b4599190f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3a4c2959886b62b36343f1f777f5bc28a2770178265948233c76c51a826156c2c96b3fc16813606c45826ced6e500c000000000000000000000000000000000daa8981c470263e71a2a9ad4e502e21267517fc19270c1b920d61a0ea60e0a5f1f9ff1e6b20a5e29404e5e3d772bd501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000011f3b5b6cbc6d0f2020033e74a69a547b34601b9d24f3356316b1a1a2598300079b56338eea9392720dac6c16620cead000000000000000000000000000000000cbbd1bc95dbaae3982031caf8037aae5feae9a35bc97fd8bde331d5a7044e4bf56fdb13481f78eaaa7e60b878e76fca", + "Name": "g1msm-4877-jwasinger", + "Gas": 10183176, + "NoBenchmark": false } -] \ No newline at end of file +] diff --git a/core/vm/testdata/precompiles/blsG2Add.json b/core/vm/testdata/precompiles/blsG2Add.json index 64ca2006dc..a4a6fd929e 100644 --- a/core/vm/testdata/precompiles/blsG2Add.json +++ b/core/vm/testdata/precompiles/blsG2Add.json @@ -3,728 +3,728 @@ "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", "Name": "bls_g2add_(g2+g2=2*g2)", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf300000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e849", "Expected": "000000000000000000000000000000000411a5de6730ffece671a9f21d65028cc0f1102378de124562cb1ff49db6f004fcd14d683024b0548eff3d1468df26880000000000000000000000000000000000fb837804dba8213329db46608b6c121d973363c1234a86dd183baff112709cf97096c5e9a1a770ee9d7dc641a894d60000000000000000000000000000000019b5e8f5d4a72f2b75811ac084a7f814317360bac52f6aab15eed416b4ef9938e0bdc4865cc2c4d0fd947e7c6925fd1400000000000000000000000000000000093567b4228be17ee62d11a254edd041ee4b953bffb8b8c7f925bd6662b4298bac2822b446f5b5de3b893e1be5aa4986", "Name": "bls_g2add_(2*g2+3*g2=5*g2)", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "Name": "bls_g2add_(inf+g2=g2)", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2add_(inf+inf=inf)", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40", "Expected": "000000000000000000000000000000000a9b880c2c13da05bdeda62ea8f61e5fc2bf0b7aa5cc31eaf512bef7c5073d9e9927084b512e818dbf05eab697ba0661000000000000000000000000000000000b963b527aa3ec36813b108f2294115f732c878ac28551b5490615b436406773b5bb6a3f002be0e54db0bcebe40cb2e2000000000000000000000000000000000bd6e9060b42e36b57d88bc95b8b993da2d9d5acd95b73bad0509c2324212bcf7a94a46901932c0750535d00008a34f7000000000000000000000000000000000a374afd32bc3bb20c22a8864ce0dafe298bda17260b9d1d598a80830400c3fd4e8a8f677630eae5d4aa0a76a434e0ba", "Name": "matter_g2_add_0", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d938800000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633", "Expected": "000000000000000000000000000000001963e94d1501b6038de347037236c18a0a0c8cec677e48fc514e9fc9753a7d8dcf0acc4b3b64572cb571aebbe0b696640000000000000000000000000000000000d9739acc3a60f6dffb26f9b5f1fd114a21f2983deea192663c53e012b9f8e1cabd4942ad039badbd4745ddc0a26a91000000000000000000000000000000000b4206dcdb80d62195febb6773acab25fa2c09a2e4be9416ca019faeb72f1fad1dfdc51e8cea39b371a045b18947d40a00000000000000000000000000000000100758b888fa27e9258ddd5d83409e8aeac576874bc399b33b8bc50d77fce5358cb091d42f9a1b1ed09be3f200959989", "Name": "matter_g2_add_1", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc000000000000000000000000000000000a69d6d9f79e19b38e6bf5a245dc820bddbdfe038d50932f76d0e4629d759f8ca6d573fcfc39256305daedf452f9fdf40000000000000000000000000000000015f5949369e58487afcecf8018775d1b0a73e913bf77e13d2e5a843bbbeba7d1978ca27ae8bfc87d30f567dd396b980e00000000000000000000000000000000182198bb38a0353b8db25389e56ab0d8679a1bda008a65dad77e4c95bc6804f6311eb16c761e1a5e2a5f87cfada49fa4000000000000000000000000000000000eb5483959e98c30e71db52615f63521378b156f142d46f3bb285b94aef39d80feacec335b797c5a68dc17ba89d43e0f", "Expected": "00000000000000000000000000000000079e4fc2190d3441fa76c2d925d23b81e353e09e9138fdde51234195e564a32c98aa0d240f051298bf966d17adc2d6fb000000000000000000000000000000000aa327776fa7e15000dd548fcdc3a1cc6f9d0ab33046dd4240a3002962131b738ffed579945a348c795cfcb33682cf3b00000000000000000000000000000000179232ec56602d1ff79861cbfa2edece34b296541483aa65fe0cb493f520b7722cfffbe04294dd054770a38bf75d927b000000000000000000000000000000001826b88a6b411330757bb304a380487a02f7cf421115b84b3f468d11a83dbf304ce7a5661f4f01299d3c7865305a0006", "Name": "matter_g2_add_2", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf49000000000000000000000000000000000286f09f931c07507ba4aafb7d43befe0b1d25b27ecc9199b19a9dc20bc7ec0329479ef224e00dece67ec0d61f1ca5ae0000000000000000000000000000000014e6ed154b5552be5c463b730b2134f83e0071dcdadfaa68e6c7c7f6e17dabb7daf06e409177bc4b38cfdb8248157618000000000000000000000000000000000f145e998dc6eb0c2b2be87db62949c7bfa63e8b01c8634248010fd623cfaec5d6c6c193331440957d333bf0c988b7b10000000000000000000000000000000002a1ab3eea343cfdea5779f64b3bddbf0769aded60e54a7507338f044310ba239430663394f110e560594d6042a99f1c", "Expected": "000000000000000000000000000000000f69e3616e7122bf78230461bb1f4b194988adc6149372691d8794d0086fba0870a2255a2c79cc3426e7ba4d032fc2ab00000000000000000000000000000000174752301e05dcd62f7a3ae3357344e64d1c94835b2b742ac24449ee2728d693a0df10c3beaeb45d1b4af4ac2bdbb8b200000000000000000000000000000000051a761a3ceb275ec28a2a269b5ded1d9fd11a617c958e73c07de3a92ac480aa82c7d2a1852d291804e734526277f5740000000000000000000000000000000009bec9045ea89d5d16588e3373cc977f6d975d0e2213b171403a9b2ca460b3b2e1106b474185516d4200655b17a179a1", "Name": "matter_g2_add_3", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e000000000000000000000000000000000d1007ca90451229d3780d66d3aed7c9d8fc82e9d45549e8586600e38eb6763f3c466e2f6ba6ba1dafd8f00cc452dda20000000000000000000000000000000001d017d920a262b6d6597bab532f83270f41526409510e80278d1c3595ceabb9ceba8ae32b1817297ff78ea7a0d252e8000000000000000000000000000000000935b7a59d2e51bbb2f9b54ccb06ebee9d189fa82f0e97d10c8020badb3de7fe15731b5895faed8cad92ae76e2e1b649000000000000000000000000000000000792dadd48a20040ad43facedc109747411895180813349d41d0e5b389176bfb15895d41665be8d1afa80835ef818eca", "Expected": "000000000000000000000000000000000c079610e6f8770d65352f911863b6cb4fcb25cacc4a42f75e34e29e977c93244a6241cf3d5bd1040ce7d8987996f87e0000000000000000000000000000000010d08d8f6fa8ee7042c0891ea0c3b9b59a79da52cf3a91627c79d456212e3f6f39e1f69aa0053bbdb4076a3f7d05e5dc00000000000000000000000000000000069047218b0ac1e07650ac8f4a1b9235f68408f543517c4ae3c0ec47c79b468713c704ff3680edc8abd1bbed7a5fa75d00000000000000000000000000000000137737706162e02cfa75ce2154d57c9a3520818cc04626654824769ad92ff7977942f3881a28284ea47c14f353772d0b", "Name": "matter_g2_add_4", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e200000000000000000000000000000000095353ad699b89ac82ca7ef631775b2b3a6e3ed8dd320440cdb929baa428e63cb902a83857cc0e2621470544c69e84aa000000000000000000000000000000000892559ade1060b0eef2cbc1c74de62a7ff076a3621e5f0f159672a549f1201f2ffb3ac12c8b12cb86ae3e386c33e219000000000000000000000000000000000750df4632a7126ddb08658a4001f949b9764d9cc43a9393cc55d8fdbb15d4a1186dd87a6433d111888a7804540ad9fc0000000000000000000000000000000017554bd444665df044b91b0b2614017bbfcd7acc7f8c5a16cea2861235578ce2b27dcced9fba234999fa478cd3f6e42d", "Expected": "0000000000000000000000000000000004dd5dfe38fa70625216ecfec60ea8d38602552726f0fdfb8f392362ce845fe0fda76894d0e456796e08462bb941579f00000000000000000000000000000000195a85cd0685f4053ee539de7e04fccd2380819b291f89cbcd63d5a0015b3214500284a7c6568a71f52bbdbc38be410a00000000000000000000000000000000107c211bad49c7dd8555e30f2500c67e7175eb98a8494f3d5309c65a93cce89572b7b5489428eaf3f0a5c1be323c5352000000000000000000000000000000000c11f978150ac35722679cf79443b3706d288c968116ddedc1f1d0fca8cd746e3c92dc006330be14886c53c41feebbf9", "Name": "matter_g2_add_5", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46e00000000000000000000000000000000175dadb6ee656ec6aebf8d0e5edaee3f119c74e0ea64e374be9e8ab9fd3d085fceeedf4ed8de676ebe9065d83b0542ad0000000000000000000000000000000005cd6a875329c23e4918976cf997e93e403957acfc999f8159a630d21ab6f1762925c063784237262bedc82402ad81bb0000000000000000000000000000000003274bcb8db35e50164d136c2a98b5a6d2fb5f9767d0ee11c1358bf7ca5ed96d9122f8c1051ba3c658cc89777d03dfa5000000000000000000000000000000000380a240443dff85b6542f75db28b87c39e278cdb8d9627efbbc63b229e6ce783f6fb0114c8e91c2fd6ea71c95bb99a4", "Expected": "000000000000000000000000000000000fb33caed4de22cf341bb3e04d41c0198b064c1d371a24f5cf59595ab4a1edfd379916a40cc405d35f0603b2f8fb987400000000000000000000000000000000131ad6172c20b3a1cc2542db037de1324086fd9cd140ae97987980f260023d91b24504181af6fcbcfa242f48e99559320000000000000000000000000000000004a0404c00789459395f5344544041785d10f2fe74d4bf484966f5e9b6b4c4c8cb113a811a4fa82a1cdf8e3242bb418900000000000000000000000000000000086ba6a914f3f07bdc6750fcf6baf76124a17964bf9eb9a12982e8a28ca04360da3544b69436d5663e4e94bf7189529b", "Name": "matter_g2_add_6", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12000000000000000000000000000000000834cf1b4149d100c41b1bca0495e455002eb6596bddcb94ae48d0c65957e8b313372f8e0d6e57504664b266f38293150000000000000000000000000000000000de2875fbd14760bac4c2cc7d3f239177efe9f7f61f767be420d44f24c9fb863efd60dcd732986db8c5b72470617ea60000000000000000000000000000000000bc9535ebf11c2dcc8c7d3bcd09d7d14035635fccb5fddb7df29ce8855e79f99809781d6ffbbcb33d1227314609abee00000000000000000000000000000000039bbfb4d969d702255e3be7f255a97529a19687ce38cb70637c37894d4102591feef428b0afe8c9ef50310ae3b83091", "Expected": "0000000000000000000000000000000019c8a1a206c0006a3033377abba4c31c55710a094d8c9dcef7560818e90411861ce7d189e2763f8fe69bf75e719e4efe000000000000000000000000000000000cccc6bba8691c210aa0a67d26584a359fab94041d853160abd9669893c0d398c805cc37fa3c33bc5ee5ff915b985c45000000000000000000000000000000000e353c1993c36763acec2a75495560e743d099b565f3de195e011afcacff3d60502801f47695da7dd589af81e772eb7800000000000000000000000000000000100c6123cf08eab6c59d78b414fa504ed10c204851289b0598b40ac31971fa12cfda4ef7cd2d64f9797d4d2b193e0bd2", "Name": "matter_g2_add_7", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5b000000000000000000000000000000000fc09c241899fa6e8cc3b31830e9c9f2777d2bc6758260c9f6af5fce56c9dc1a8daedb5bcb7d7669005ccf6bfacf71050000000000000000000000000000000018e95921a76bc37308e2f10afb36a812b622afe19c8db84465ab8b3293c7d371948ee0578dbb025eed7ed60686109aa0000000000000000000000000000000001558cdfbac6ea2c4c1f4b9a2e809b19e9f4ba47b78d2b18185ed8c97c2f9c2990beadc78b85c123b4c3c08d5c5b3bbef000000000000000000000000000000000ea4dfdd12b9a4b9a3172671a6eafed7508af296813ec5700b697d9239ae484bcf7ab630e5b6830d6d95675be5174bb2", "Expected": "0000000000000000000000000000000009fc3870f88288c680b43d63d3bb5305b99fe461e59c07be981b8819fbee0d1fdfae0c037e830fbbabc40cedac7919720000000000000000000000000000000018bdd4903da4d14fa28af4c2cddcb708238cf68673ce77a04a3926c4aaf17d39a831c5401e84dd042d6adf595a1763710000000000000000000000000000000002c398f0e8ad9752f4aded980bc5de2d91118db06818d815c11e818ead47e7065823737db8e304bae32969cab065d1ff00000000000000000000000000000000180642a633c3aa402e5c0b18fcb6fe8c115575b863abda59b5d91997ab01014faefc975d0aee994f98cf37ce79eb95aa", "Name": "matter_g2_add_8", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb815960000000000000000000000000000000000b36d8fb9bd156f618ab8049d41dfe0698218764c0abb10e12fae43c8810b8e2a5201364e2778f6f433b199bb8f9a6800000000000000000000000000000000000707eb15411b63722b4308c0ed4288320078d2463ae659ad4fb3f9ef8124f379df92d64e077403e50727388adb59ac00000000000000000000000000000000158e1249d5b91614924acb23899c6bae408697dec0982c10d0459746499f4e6739afb9d5129568106ed1a1caefeaa9640000000000000000000000000000000019e841562e4aa75321143f8ce1e5ec6158fa5cb8b98c839a486188260c18ee8a7600930f23aa39eac2eb520d6a0fba90", "Expected": "00000000000000000000000000000000199600699a6108599c638df8f965d73b5de4ca74598df281ec95c539de2c7eff9767569692d8e0ad120fcbb3d9335b95000000000000000000000000000000000c42b11e2585ba93521b3c968e9dee07e4f5168c11087d8d750795555a105df70c969bfa79b1ab4e5fc8d81657235d08000000000000000000000000000000001370daa4699daa99e9940fe04f69150e6f752798cbc0e66c91c3bd46149d935c1815f32d7f14b510e16d475044eda9cc0000000000000000000000000000000016c7a00be10de5732795cc3ee2951e58cb9d42f9b05d02fbff1b83fab5d3ad830cb8178092b76172108d7a53afe8c539", "Name": "matter_g2_add_9", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e97795505419600000000000000000000000000000000186a9661d6fb539e8687ac214301b2d7623caedd76f4055089befba6ef2c96263d810921ad7783d229f82783c9def424000000000000000000000000000000000447f3e20caa1f99fbaccab7bde2bd37fe77cea691ebf2b9499f95bbbb77afe72b7039eb0c05970b61360fcf8ade73730000000000000000000000000000000005e11f828eda86c10a1d7929def547ac06885da278afae59c5d95453caf0a2d8ed186fa7c6d0a7ab6e9142cfa4b338190000000000000000000000000000000003d954e61b6ab71042b19e804efccd4956b56662f27f70a9255cec0c464b86c0e83721ad3785dec62dd4a9dd3d6d5d53", "Expected": "000000000000000000000000000000000669cc8a3acae17f99f805afb9012a38851a9e8d4fd9895a9946c29fc859849c24d7ab7b6278c449cfbc5f1d7ea1fdbd0000000000000000000000000000000007a9095be808d0ebc99bce94e851d2a7cd3e1977b923064ab5bbed2347cf18f3343e60120fa051d12fe27da3146cb423000000000000000000000000000000000f1e7f75887651f67457f6dc064d7c11934035d15fe4dc40bab970160ed1b1aa230a3fb84dc1da08770d847c0216347a000000000000000000000000000000000efbc62ade1678cd70eb38c644038bf19e52b0859f65747068d9f3124762d951e4a6ff05f34b6d14919774f8409adff5", "Name": "matter_g2_add_10", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a90000000000000000000000000000000002b94534aa0ba923bda34cbe92b3cd7a3e263741b120240ff5bdb8b718f094d3867e3fcabeab4a7be39c8f8c4fdd10d900000000000000000000000000000000048711cf6a82534d64d072355cb8fe647808e7e8b2d9ac9ed52eb7fe121647a721dd1234c71ecd163d91701eb7331cac00000000000000000000000000000000141ef2e23a1ecc7ef2ed3ea915492e79cfffe60b5e0de8441e878bd0653843d79c724e3c5ebe2321361df99f8932ddc200000000000000000000000000000000085513b4009f29b3e00a91c2c4be418368560802ba4194cbd2f4fa3d72a55fcae547014434514a8b2a8fe3e0b28d2773", "Expected": "000000000000000000000000000000000e25a38d0ce2aabd2538c95ed463f226e3f29ce7f10e1be27af2d3db741926d557178c4b125af8789b40480d8beec0890000000000000000000000000000000002a94b7c57fe2783d055a537004a3b67e41f5374da0813094f5944fbabf4d27eb576dc8b21ccc15f8339df14ff8785220000000000000000000000000000000008b9efd8abfa4fd71a8eafdba9df38360ef0b0a117c0052528d1c24df5032635eebc7b201439f5de858514666c68cd270000000000000000000000000000000012a2fde51f6f4a98435c325dc3b1ae846bc33a5ffb3b13fbe3fde2f74dec0aa815fa8e42392b3dbf798cf547fdb4db0d", "Name": "matter_g2_add_11", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b381731734598360000000000000000000000000000000009143507a24313ee33401955fc46562c9b20c9917df3b40ccbd7ed43b1349d4551cfd98a4976d6fec5fc289460c8d89900000000000000000000000000000000060566b79df5cc975e669da8ca3a7fa91bf3f5c9fb871c3d62f4a3e79dbc341b89d38b588e5414bc385d5e3cbf3ab9310000000000000000000000000000000016bf40b8cc4c01a87aafae0c4439b623a51ba9a383756a550b69d627d6f45209f0d87e4f9be9edff35c986f7b9c49e3f000000000000000000000000000000001842d9172bce51a164fbdbdb108d0faae07e4642f21c80e40ac31e737657472ae3dfe552b65349629c210a068c4afc0e", "Expected": "00000000000000000000000000000000067265782d58b04a2ef3dd419cee506e076e49d1119e28db1df7f0e22cba9bbdabc560084cda50bc8db3915fa9c489a30000000000000000000000000000000012448a61fb2f6fd8e355111b671f0e888304284b72d5688091f2ed00edf7ccb7e5bd8a733a910d6964dde07d393798470000000000000000000000000000000005f687356ff6c634eb46613be8e98540107e706714434faff54510234d4aff42ef7752e154aed63fa8ff905ec0af628f00000000000000000000000000000000180dca84a37c964b30f5cd11a090e54acea102f1b884319f8d1252a37bda005512ffc39dec8e33af0dde0d37993f846f", "Name": "matter_g2_add_12", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b000000000000000000000000000000000ab19bbddd661e9db8fe4cb307ecebdc5e03efbb95c5b44716c7075bd60efcfc67de0bfd7c46ad989a613946c90a4c1000000000000000000000000000000000120800e7f344cda816299fa37f603ade06beb3b10907f5af896d6b4e42f7f865b756f14164db84411c56cb2ea81f60be000000000000000000000000000000000f688ddd257e66362af1437b6922d3397a7c3dd6dea6bca8ebd6375e75bf2de40bc287cbf3434388191e56b92949c83b0000000000000000000000000000000005252465784aff8c1c707da58b5808c69583bf852d68f96912bc53f8dae4536b09ccbbd25a49d9e744118992b92b6792", "Expected": "0000000000000000000000000000000012a29d35c9af52f172787c90c5a3e77ed29d66feabf5d7bdd6bfc14dd9a05d402976b84d44647628c908d1816f4e7100000000000000000000000000000000000caf3c372e36de557ecd7eba02e6a79b1b4cff30343119df7a23662c8512095e051ae2dc27e577635c74a260be2b084c0000000000000000000000000000000002ceca293a58bc9beb4ee9a0679eab037f5cf7b326d65c0efeefdbf384ad8e4bc08a3a75a02e6b9cba8963e65d6e76ef0000000000000000000000000000000004631773a6590bc89b49a75bbbe2e732f9466ba259ef7a04ae69b6aa5d5a2621c1918eb213101f6f7eeee4656a7b1472", "Name": "matter_g2_add_13", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd3000000000000000000000000000000000e3165efe00f69aee84ac56d2161f07c017abfaadeaad34f8c96799d68bae0e6f9b557bbf9137e7826f49f29c58d1ef9000000000000000000000000000000000de0dce7ea371ad60f21f2cb61cb582b5072408a7efc91edf05b36a1a3b58fd9e6cf808d75157eedccc8f1c93a8ae07d0000000000000000000000000000000016d911943d80427385ebac1d1b293914a9e4dd9db06c1d6a758192d63c8fc9368e02eae7fb0e3a7859408f215cfa76ca0000000000000000000000000000000007bfdc6afb8acec625e50ecbc08a5cdb7862b795866323679885ba5cba3fd51f181078e03fe35e96e6383c077eed1bf5", "Expected": "0000000000000000000000000000000017f155ed9911ec56d71d63d57556de071ebe89be36e6bc9943ec068a70dd5a6f045dfb9fde5c1e29d52c9fc17579452e000000000000000000000000000000000a60d62ea549edf4b11f62f2321f39d41bf11f3c4f858dc7db85b1dab1b7644e27eeb1d022d6082f59c65155068d2c390000000000000000000000000000000009d309145fad15860e556ec4b4aecb415865954247c2034d5bc96026e4d6f7612af6e2db99f4e462acee2b303134b91b000000000000000000000000000000000114ed157e3d020c5397cba7e10cb864aabb47461f166a6724614e689274ae74c505fb6ebfe3e88da0d6c272a15a0527", "Name": "matter_g2_add_14", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bd000000000000000000000000000000000a68dccbe3452731f075580fe6102b8ee5265007ee19c56d95bcb096a3a6ac444f4145b980f41afcb0a865853b279bc600000000000000000000000000000000164767ea55a9038ac2dd254d8c8a4970dba93dacdf5416aecaa407914719cab165e7a32784b2c41652a86358737d831f000000000000000000000000000000000da9441fbc6578c85fdeca49082c9ebbf183de894d67c65158380ee56132d3cdb44b100d72b6d3b82688defb75d2aa390000000000000000000000000000000017d570e4f6e46550679d5d12c347414da207060f594620e2f8db66df8e0b06c912290b207a268e782d4b45db19a199db", "Expected": "00000000000000000000000000000000118e0c81f9157395578f0fb83b179721de2af3326d13189cb8f43911d8c3268a11fd9702f09f14c115bbdc43d5fbc08b0000000000000000000000000000000016a548df8c87f432c31e4e32c3e5b4d48d6f29fbe391d1181174be9dddee450e7e96bffe8c9f23692ccc080116592944000000000000000000000000000000000eef72a5c698c58f1d2ae9415da256b54d7b1ac37a1d1b88727c0afcfd854a41973c6cb10ecbc3a90050fe3d8d3ce8780000000000000000000000000000000019b16ca8f955dfd21830a3f7fafcc97d7de977bafe1983892988aaedd430d22674d97897d24c1643e99bfa6256df4bf7", "Name": "matter_g2_add_15", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca800000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e", "Expected": "000000000000000000000000000000000f2bf3f69276d390c9fc2c15e9f5f5d0b3cf9a6eb028c44811b481f376ab60e17d33a04b78348e46eaa94332c5f16ff8000000000000000000000000000000000bedd0437fb3f4baef87e56f33c77fcdff6a5512571cf11fd9605697abd8763315f1fe4bccf04acc6e971d6aeefd9c1500000000000000000000000000000000067c3ff69733baae2fb4ab77cddb7563047c428b40a257a375f8cf8c9d230a6619f7932b86e0836fff0c1c60d2c4dfd900000000000000000000000000000000057526faed8d62aa10e89add5a338320c748ca1f96ba5ceb579efec69d17475571fc4ce6fce3a93398ea88340f0e969d", "Name": "matter_g2_add_16", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91be0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f9", "Expected": "0000000000000000000000000000000004fc19f8fe47e6acd37567016704b07f906e8741fcb196f697e1fc24b0204292693ff424bf1c5e407f5bcba5a3b1ab85000000000000000000000000000000001816f992c3c461fa6d2014ced382a35b0d70e61927d72b4d661434efff3dafe2f4b6cc91bb1a5dbf809f10f3ed7f36de000000000000000000000000000000000dadf7f7223ccedbeffef31c97df7e01f99299da71b589c8828b65715012aa343d7e041dacc57b34a6b5f84523a7938100000000000000000000000000000000167f7e73e22df81bd2a7a6f14e940a401bf414e5d18b3aa610b2a82ca8f46aecb5721d0092b27f8968b2302c37957268", "Name": "matter_g2_add_17", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae7", "Expected": "00000000000000000000000000000000041a5783c748247f05457d30d16f93431e9046a236d5025cc07a27b9f2abaaa556e2df65cf0f0015107253fe94d8b4dd000000000000000000000000000000000193638bf69c7508c4b12808a62e89883c34f97ded6e1b5dcc3f28191e5c7fd901a72a85ae386acccc9865f8144b1bd500000000000000000000000000000000180e8184ab583da58b77b8a4d108a366dff3e3b336ebc5c9153fa815188edc95e7067ef25f7d79526c295d634bc98f5100000000000000000000000000000000125b147100f6df0cede8e22151b3423b1dd364899fdee103c71a44388ff002a367627a2342e15833644bcde61f2ef6b6", "Name": "matter_g2_add_18", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a7915780", "Expected": "00000000000000000000000000000000095fda8adf3981f4468fb82aa0ccf80e55138c922c6422cd8e67f53ee63e7a390bc345469e9211a1f8d810cf4ba27d0a0000000000000000000000000000000015c19b6af21f75e8e53fcefbae1c8d7f97853a8aae5fa62e606cfc92ae71890702ef9dc5609d3ca8fefd415fbd820c04000000000000000000000000000000000007b7e908766d34c5d99cb7cc76d5d5ea83c29ae1d9b83b163741bc9962e293926b1e251b546ce0c1268def728da78100000000000000000000000000000000084fbd6253211f7d66d52b7f14360729d54b2f94c52f2b76e521dc3961c40b4f19944923f64c6425a44eb158a9727a4f", "Name": "matter_g2_add_19", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e170000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e", "Expected": "00000000000000000000000000000000121e7f2eb906d0b31b8ce5cc46638428b6ee57a1ee70e4ec3c2bc044230b9b86875abe0862145b442c0e34308efc690f00000000000000000000000000000000139120d0a10b82737561d0b3fda01b6df69d9beb7dbabf3ddda036f9b4c317f3ac1eaf400013fe5ad664bea44a73b336000000000000000000000000000000000a923184b381027d8cb3f82708802b204566b2b8bb6a72767aa396324d8a26b4e0f0cb92fd1914d77a4e9af2f1ec31e3000000000000000000000000000000000409732f2225cb5e5c002bef17512519eb1a18bf6c3d7f834d0c7ac8a38433c88b550b3f443d259313eb1133620ebf0c", "Name": "matter_g2_add_20", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b710000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd67", "Expected": "0000000000000000000000000000000006a200642d5cece5eaacacb36000b4b897e8d8c661c8282f90495002aa515c7638183cf1e80a0b35e953adb92b6bb845000000000000000000000000000000000e88d4cda34e98df4d727fda79b67961b5b8efb1b125ef2a8eafc481a2cb2fa1530e59a091f31c25cc49d38f545491ff00000000000000000000000000000000082f38c1a1c35981f537547dc3b59331ab8c5e8dd261df58fe6f0c44ef1e65d0cdc1980e1a62f6248f38d0afe91e5627000000000000000000000000000000000eda1002e202e9ee4df5354cb87760d4df32eba1eafdad27cb0636879370a8f93be0bf2a30f15f2fbcd7e52c1bdf6b05", "Name": "matter_g2_add_21", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4", "Expected": "000000000000000000000000000000001341cf3316152ae8d57ea2194224f04756690133d2e02d077dc271aa577278e346e0ff66e8a49ff8c983fd34546e1f6f0000000000000000000000000000000016c9093da650643f4b4061e1c6e55da6ebaf9f234bef8325aeecad3863a0a2f53e1cdb2d54aa8b075ce6e6632fb4cd660000000000000000000000000000000011eaf3dee010bf2a16c5fbb1f7aa559cd4d831f087d9dfad4e157a6d2b6495e370d9791cbaaae19339a65726ebfc3b910000000000000000000000000000000008476d793305204be414819fce2ca70754a532682876277bc0586514f2096ba9998ae848c722ead6722d5af9395ff77f", "Name": "matter_g2_add_22", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa097000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa", "Expected": "0000000000000000000000000000000009792d98ab9b90c2467ad0d070ea44f382ec7ad5290a59d889313c5a55d7b8e837333ad7ecfd97221d405cd6c549dc8e0000000000000000000000000000000002b92dd07b61faec23f48b8a7893dae29509fefd688a978bc2e870d4cd6f963d708a0611b4aa65f5644fbc6ba4c5e66b0000000000000000000000000000000011e46a283946a8e033afbf7c14ce3162a05867809d7de94a090c8cc2cdca8bb79add21f6e2fa8d7f39ea6d26cd37ea850000000000000000000000000000000000fddb7cdf1f1126e7a6780e4892601121b289a386ebce0caf96cd392ddc57c47e3f9284889fd8a18fb330d6c40bdf67", "Name": "matter_g2_add_23", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e", "Expected": "00000000000000000000000000000000054dedc002c5f2da8c6e0a0146bfe5c83200b276b074e6d6f2c397e1208f152d3ea3e8f0da7da62cfd2a028d4c94fe5b0000000000000000000000000000000012ff307f86e266e7a212484a169d3e81df98217c6f715176913b0d383cbe4e790212da7feca0cea66df09d92544fae010000000000000000000000000000000009c211438dcf8ccb664b535e73eff304b92aa2f568aeaeb8e10ec142f92b211bb8147b250dad77d508cfe353667b6f150000000000000000000000000000000009d1734f4ecc88fd56f412f9243c387b9da659faa3fe7295580a6b7519b1980bd074339fa9b0bef44dcdd0cf0c4a629b", "Name": "matter_g2_add_24", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac900000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f", "Expected": "000000000000000000000000000000000896a38ce734c550c178786092292e737d44fa5f503d6d3b66c75e6bb70b59d1db9e8baa1ea3e256e2dfd8a942311e75000000000000000000000000000000001231db96a35229a4c7507b0ec193491446a0b43115c27d18b3715fcd4aea14d4e5c99db5934e73bb0b86f1bb91ee96fa0000000000000000000000000000000000d6f95d5637b29ea889c028dacdcb484d8ccdb243da4d5ff49e5ad82f234d414dc1484e9ed6cba1b5940eaabd3066860000000000000000000000000000000007de052fbb76902e06e1783fa8afcbb54a5069b4c5e9cee78d43da2cf76f24843a740a9eec6fe9b8f9bc4ac9baea77a5", "Name": "matter_g2_add_25", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b8592390800000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f", "Expected": "00000000000000000000000000000000156914a9137e52abd4579599dea4c0f857eed0457ee1d80635d3a6ccf0c766ba8ab1b6f989711fbdf125c4ff06b597ea000000000000000000000000000000000c60184e8ab32019ce20d2d137130f657c8964406fe4abb26da232c9c5dbfab243837d700c88d6b9ea4b8f0a2f514281000000000000000000000000000000000dc3e6e3acb898552791431859943d0a83fb4ccd62e4ab2a971370a93a99a9dfcdbe4c42535aa063354e0f2cd48308c300000000000000000000000000000000025be02da875d4990d1f0be626ce634c4856ea91f88f636bc27e313e73897c9c13a1e3ae70c1227dfd4fba97f521d6af", "Name": "matter_g2_add_26", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a300000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352", "Expected": "0000000000000000000000000000000010124c1c1c10868b570d2969ebc3bf5cd6bfab13ddc93f0fd2b8a1742eb8e04d31063bb81c52b92e253128d4cb4413a60000000000000000000000000000000013f89997cd2ddae00cbf24cb66a92146c553c6fae41cdfaef14d49078729f239ad2661937dd0d4d6ffd7076b03e0aa84000000000000000000000000000000000ba2ecf990cd846c95b35ab60d4f97f5814c8189190df9d521b3dae462f2d44db006a0daecf6b82c1459006bf82ef7c90000000000000000000000000000000016dc129b83cca5b3c699628d081306c5fa61faf9dda5e92894931714037628fb829c595bf64d4a7fa295f136ae244601", "Name": "matter_g2_add_27", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e055086016000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a6", "Expected": "000000000000000000000000000000000a66f36f2437db57473bd8b7670994f1cfeb8b43c0ceae358e63a5e4e52b737fce6b3d24cc4de593bcd44c63f2c5935900000000000000000000000000000000070b7ad970f03a38c8a31452cf11422159cd3331d746031781a5861e26f54efbaba63dcb1db8bab997eada9c3dac39cc000000000000000000000000000000000ba4a9d7350adca1ae64e722df11baeea77c5fb75c5b52c8c46b9d863a70bfed1ec47888e907213f4ed4dcaedd37f20f0000000000000000000000000000000008a64244f1870a1dbcc4bd4d5c9eb5cd5225713dc73aa22bc46b1cea36c88a66f85251a8a9ba7279c88bd5dd37a06f7b", "Name": "matter_g2_add_28", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3ff000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b59294703", "Expected": "00000000000000000000000000000000079f89f2defd1f97efe0ba1db28523abc88cdf66efd39918a600a07c5ed5b72ab9d3354a172735e7749b5f6814a48f4f0000000000000000000000000000000009e361b8609be8057e5b3c99eaa1727fdac17edc59239af17f55d72c8b8daa89726f4ae240c742ec4b02fbd89d45c46400000000000000000000000000000000121b475a2ab50357ce80fe01fc461195029de20f61474b0773d80434253adfc268a775e1a0e3b7df5e85d1ff8c5008960000000000000000000000000000000019a76aef4e04136b1ad0d03586a3d8608ac4573715f18d5fd6907d03e5fec7c5659e15c19fd87f242da972b651dff5fa", "Name": "matter_g2_add_29", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b200000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb", "Expected": "000000000000000000000000000000000383ab7a17cc57e239e874af3f1aaabba0e64625b848676712f05f56132dbbd1cadfabeb3fe1f461daba3f1720057ddd00000000000000000000000000000000096967e9b3747f1b8e344535eaa0c51e70bc77412bfaa2a7ce76f11f570c9febb8f4227316866a416a50436d098e6f9a000000000000000000000000000000001079452b7519a7b090d668d54c266335b1cdd1080ed867dd17a2476b11c2617da829bf740e51cb7dfd60d73ed02c0c6700000000000000000000000000000000015fc3a972e05cbd9014882cfe6f2f16d0291c403bf28b05056ac625e4f71dfb1295c85d73145ef554614e6eb2d5bf02", "Name": "matter_g2_add_30", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233", "Expected": "0000000000000000000000000000000013f8cdab447ef9be450b87f941c96d4e93d5efd811d80c6a910965728f7dc496dec132f3fbeee5d1e84ed7c24ca9c2a8000000000000000000000000000000001537d5caa13ddfac93f0f86729c743d9a68175a78c730528b581fb54b1f4d020473b3b766e3882a485ce5d02ab381c33000000000000000000000000000000000b370903684ede24f3df80e3834ed414a765cdbad98f20c49bef8663a82a468d3911d6bbcdc021e22c252e83a857e55800000000000000000000000000000000100cc8d05f071904753776c6092a38db84c5de751bf93216131a0f9a50bf78a722344a14b3be2a9207568d1f669d208d", "Name": "matter_g2_add_31", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f860000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce", "Expected": "0000000000000000000000000000000003c5498b8c2d4765a270254dc927c6edf02acf0759540ddad951ea8c097bddb949ea0bf19942accd615bef21e8572dff0000000000000000000000000000000004c17bb648909bdddab4dd86560cb6b341e96f58c515ce471281f226181bded16b358b56d72e363f9ec491b8a9dcd92c000000000000000000000000000000001828973958204f8ab8cd13f5af5f3529f368a149bfe931a8002b61a61895457fbcb0cc6874631bb55799c884b998d8b9000000000000000000000000000000000f61460bf61bbf3ce38917850bfd3cece1e3955ce29d200c6f8aa89076c70919c02668678edc0bcf94efc9e9ff6a650e", "Name": "matter_g2_add_32", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac5", "Expected": "0000000000000000000000000000000002c6104b3494fdef86d53f87bea68d313188c0908b935fb3b9f636ccd401c6e9cbd33bfcdd437e1a0150d0e4b9c3a881000000000000000000000000000000000bdc88396f807d1ba8d4d6e284d008b5e40445ce32c23a0178824fdbb6db3c5aede7687eaa2f12249125cded57052ad2000000000000000000000000000000000c7004365c1d3027997b55bd258dfc61ae07a762666fba2a14aa2ca116673fc03a6f694c069f53cd915fef6d37513101000000000000000000000000000000000ec17688d8f53e2c92502091c859cef4fe9a57ae984cb1e72686bf1f0656b10246293cae4b96214a38dc76cf2709bd59", "Name": "matter_g2_add_33", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c99739", "Expected": "000000000000000000000000000000000a44e6a48ea0a95667f607ee66290cb0094c964baed779bd6656941db28e30a7e9effe49a617be9ab376af4f535cc28f000000000000000000000000000000001933b87310bf5fa60b1abcd13bb7ac3f2ec0a278f6a0a70c953a2905ac1d3bc5a70cf1da885af45d1c7680bb4f7ff74c000000000000000000000000000000000597ce9f1bf7efacdcb0250427d0341e142226aaea060983175ea149912c5c4f3019fe87be6d87d186a8f562fc3059eb00000000000000000000000000000000198b5a891722a237a5e23e3004798c8d3f069af3267152508e283b4549fc5e8388330343f80e606eba30af51c99c7020", "Name": "matter_g2_add_34", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe20000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0", "Expected": "00000000000000000000000000000000047c2ccda315b9c013e87bc9168b3b8dd6d463403f1cefd824fa9f93a99f4c4f98fac5f97e4237f76b1ec91042f99bd600000000000000000000000000000000036861fd0a69cbc851741475905441b51af12c5b2aaee6ce9a27a01a43db810be9c7d6fa401406e98e327703404b83a5000000000000000000000000000000000310cbdf53f6cf8d87e2d178869bee4359a8dd666986d869761a79963680a33ea3ecefd40a1e558acae5ded2ca04447300000000000000000000000000000000108bbb28c73ed7e76a51a78e4d15a2c88c25e05c7127ae89d4347cda00be231b5e70e0b0562caddd4a7083efa4516722", "Name": "matter_g2_add_35", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a84486000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c", "Expected": "00000000000000000000000000000000137d23ed3fa0d7e5928af8d1f4bdfdef08e0b4c0f3bf6f51ed28960ce9805eb8fb254233bb18cbfecbadba95e112fdb80000000000000000000000000000000018615147d7a8cce1dfed6de25cf2fb52f54a243bed4913e20e66673f47ecddad9c5e4ff9653f522180de4b90ddb3ad17000000000000000000000000000000001521f12116b13f785b5211aaf438aa6668bbfa318cf0ed6d91aae963f6f00d32cc5f25d3a02bd902ccc25f847ee2db830000000000000000000000000000000014263b23396f4facdacf13c79864157823db724350bc640abf8fb6d62663cec1069eef9db56817660510e2417b51c616", "Name": "matter_g2_add_36", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e370000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d05712", "Expected": "000000000000000000000000000000000038f9df6c14f84b8ef8045010c8973e5c2f8d2e37268f6a674298de7b15cae82361ebbfaa00ea1cb2653c5d00886b45000000000000000000000000000000001376f7e2d5621aa9d6f7ce45ed11de7e0e1095ebeea976f78eb83189c6852ee199840c14059c233bc3d40efbeeb5eb36000000000000000000000000000000000c7b0e53adf4f0fc5172f903e3fc479539348241edc3e277f30ae6b4fc419aadcfb73a8f8a09a1ae1dd885a6250de0040000000000000000000000000000000007a00b57ecc8b056436ecacd7e0fd346b906b15042e9a700f54f8c3b1d251c566e0c55bd34f7a9e30f1566b7f2ab16dd", "Name": "matter_g2_add_37", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4", "Expected": "0000000000000000000000000000000012662e19e41bfacc0c792f5183596bc7f1986f9bea72c626e187d72111b6ef3f36f5afeeb640cfda99b7044c0d0b846900000000000000000000000000000000050ba08e1b9fe95dc67e6ee1ce60664b291c80fdb59729cdea75dfd18f22fb88f837b439fd119c46c996787d3008194b0000000000000000000000000000000004ea0f488fece967675abdd3c42f8fec25b547cfc45d42fba14bbc55ad7e1a75296a679113d0671cef0aec0c2165f4a0000000000000000000000000000000000f617f51800b09150a7560505079c785ab45cea4705992fc0325edaf4ceb30e1f0bec35a31898db5f810685e55634076", "Name": "matter_g2_add_38", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb300000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc", "Expected": "0000000000000000000000000000000019c774e968049bde2188e844c3413203bfe2c4355edc8cbc2cf6f977c34c0a42a206194e6eecba3c97b24558048f3aa700000000000000000000000000000000081ccf6f111575a946341759b9faa13f3608998fbf4ea3b547804737e30fc7e33495caaf2aa328b19bd48315c5c7f9e2000000000000000000000000000000000a4098536041cfb808176c7cd8e980eda613a2b390e8d63d607caaac26db02fccad6d87412b90cb4b3e186bf9ccd31be000000000000000000000000000000000d3c784c6587b9f786c06099a62aa639f40535b512ac2440912f04dfcd1cb5851b7378f381fcdf02d4e58312eb7e442f", "Name": "matter_g2_add_39", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05500000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6", "Expected": "0000000000000000000000000000000016fc7c743c5ba747640a6494fb3c30caad5a1e9719a1994d0ca73bd1645fec118a2887acc8876d105102241c10274cd300000000000000000000000000000000058a42a0095a7388fba7ce71dbef4ecfd2018c3fcdde14afd2be26588de4689d8de757e1e3ff22645fb8c17aa60265850000000000000000000000000000000010bb622f649e346834b95e82f93ae83c71c0a65df7842c4ba88df7f6eccb0217ca9377167a6d14777e0474c24821f8d70000000000000000000000000000000010c180c685ea3d0146eb82c007fec3efd129880f18f838f1cd2f80181f5a4884d6b5cc8247430fb0c1701a57f9d1d485", "Name": "matter_g2_add_40", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d03", "Expected": "0000000000000000000000000000000019419b635c3742cecffee02ee7e2b1f18ee9ff15e647ca0abc4398ddc421ae7e0444e3c1ec377def9e832d8e64fd40e2000000000000000000000000000000000d9b4abfdaf3b4c7bf00fa07579befa10a3418d8fa0f3a9c31e59ae48b0de50fc8e6d583aaa4d0fe6048bdd1a9c60eb60000000000000000000000000000000003c96d57034ec97c4abef1c2c81f4d4b0f4b6eb1e9dc5464bcab28572555b9b874df80325941501c3766fd7e06bfe7360000000000000000000000000000000002dbb3d72385b562ddcb9a80400ab3770f00d22b880cce2fce1641042b9da669b22b2fbc97617648c25ab644e661e2fe", "Name": "matter_g2_add_41", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbc00000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d", "Expected": "000000000000000000000000000000000d32b00154a5fe75c576c098419744ac36b911ee800f94bd598ff9b6adcaa39c836bc158c5d6af72c9e715a242d0fe710000000000000000000000000000000006e057c13885d6c05f5d92061fdc4d532f10d31d472c371e71367fef7c5fdd3741e665321d1119b895660fba3770431b000000000000000000000000000000000bfe695c3364e15479741e974f838649e789a76d073e552aaa60981fbc6d185eb7b297fd59e51535965214a02f5cd67e0000000000000000000000000000000014f0a27412248e3163e5f82fed02a25d953b336b0201692f08a3e8e9a9d223b736c70c1a39826a0888fb02a314e223fd", "Name": "matter_g2_add_42", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6ea0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47", "Expected": "000000000000000000000000000000001566022247ce012b7de92c8495876b4de91c36448f4f7e00f6e154185d38a735e701dda989ae9e37d332a5e60af5d06b00000000000000000000000000000000065aa42560df7990df2098827a55ceaabf3ec592c53d2f20e5dddc1481ee64381accbc8e58601428d33589b3af78a4b70000000000000000000000000000000002d9b0cf8bfd1adf76bca80ca351a4340f02434090518807e07ed76440497042f13a0cd7a9c30086872d6f145808fb290000000000000000000000000000000015daaa131431e3e78a6221091640811fcf88c835ac975a041a7ab50bc1d06b80e6a3c9ae77d2390fd14cc9bb009b47cc", "Name": "matter_g2_add_43", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710be000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf", "Expected": "000000000000000000000000000000001290bff629c93d992ad2cc709317c48980b0e56a32fe239258c7aec75e4523e0bc0b81319e100d10568a44847869a8d000000000000000000000000000000000055d9098e08eabdf2b883df35efebec9f6afb16d651ebaca1067e2129146268664ec51c8a4f28f13a250f3e9883053780000000000000000000000000000000002424dab6f0d18ea8bdded2a72bcf87c13307d27d53e8ec35e91eeab97fcf3398135fd436c530c609fd47a3508472bad000000000000000000000000000000000b25d0db1e28b98d4f9d3c77c0b71489c51186105d93be7fc2cf8c72b8abd8959340114635e705e698b0f257855ea4bc", "Name": "matter_g2_add_44", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be100000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2", "Expected": "000000000000000000000000000000000cb2998b4e634bc83b5585b0683b7b561f260eefb826719bdc3c95e8ae51f8f7b442d75d69e0f9228dacde2ce80ef4e60000000000000000000000000000000014d30d1c02122143868ea01b454a4f33432d875f8ba66e6bb1e02fc161bb5f9298e673339a9183a15759f8b94b519cad000000000000000000000000000000001068bf3c768e8c9e9058805050394ea820b5f60bea6d271f8e1fb665d3b7931ab0cc03dff4cbd24577b2c254a956e8200000000000000000000000000000000008b7f4148bd1f4926d2a84497b60a48701057ea08855bb9a2f838d2464e66360a59d058d9072f1416023cc72045af558", "Name": "matter_g2_add_45", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da900000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb", "Expected": "000000000000000000000000000000000a7843a1d67360b8a6976aeda2e4e98f1ea229a4d84b947dcf5ed8215173d5cf783920a7714f5b048778df30f01a0bed00000000000000000000000000000000035663ceafda9e5bfe934cff725b36b258f12afe749f907a560a06da4abf8380853f8de31adf14d62cdb310d8740e29b000000000000000000000000000000000f210d576aa5d4cdf5aefd8e55be099c422debc217ddf0151b8801f7d16456c97d1e134b40e6d71d296ee2518e50af9d000000000000000000000000000000000219efb35c68540c6bb0ef224e68dae6f7d48425c2908440072f5f63eec3c8e750b559c73e33464d0b5cdabb50fc4d3d", "Name": "matter_g2_add_46", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee", "Expected": "000000000000000000000000000000000ce704e650605f747cbc0bc76e82de8569ba7b3d897eac2bf5f79aba17ef4c989731e959c0bc0b7988000a9b0aef39430000000000000000000000000000000003cd3f3d978d6c85d98812ea0e3d21149bf4151ad1bef966ced124ad62dc7cde55f16e8d08bb1ad54d3a23bb73795d8f0000000000000000000000000000000019d37a20fcf6244c2898b271535e3b8f279eaac5d8fb1ba142096da383488eba28a21d038d7a9d3f9e8a008d6d3ee1d20000000000000000000000000000000001ba9c1720a4ef07ec752efa1ddb629505b3586af415c916fb0ed2953cd8943d9343268f438db860f0bced3e690a66b0", "Name": "matter_g2_add_47", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c70000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb9", "Expected": "00000000000000000000000000000000160d8b4bef36fc3d09af09dcc8357067c22e421f3811deea66faec42a2f00fa4aceca8725cf99062613126a9fd7bf7210000000000000000000000000000000004e8691a42c8f3ce0e7c0470446689e9d2b3cf57d55fad7387d624857f977cb9c6864c87bb4b6a2c17538478ac5fb5960000000000000000000000000000000015e20f6baef033efbd38081d5a10eeb3c67d89ebe5cd652110b778313c9e86cffb45231616d5b67e9ec8b7be15980aa9000000000000000000000000000000000af75dc221050256015fecc2bd8113b42afc9c624e5d28d7ff8312af499e34a603d66a4304f263729b440b6266538316", "Name": "matter_g2_add_48", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c6", "Expected": "0000000000000000000000000000000013edd8f016f6af49e9bc461ca14c438a32eaa3d1270a5acec99a666aba3f0a7e7eccea81720971cf4432bfa94cd18392000000000000000000000000000000000dbea5617e44c82da828844a5a4a1426d43422fd0158204a99f53cf9821f82f0bb0130a2123297a6941f695e172d9c5e0000000000000000000000000000000005f65a445e9f2d57dff2b210209f9faeb1c8b446454de4724d990aab20bd68362dd7ceb5b95de361c129855abba83f7e000000000000000000000000000000001219ecae79d62d3039e642369353993b1ece049331f06be256f06b01a1c3b0c617221c8d8f0bf4b6a0abe1191a3ee8e2", "Name": "matter_g2_add_49", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307", "Expected": "00000000000000000000000000000000158da32df45fe3e9102010bfd7faf3fde936bb8e52f68262ef479ee825a0d7169ff753aa042883a5403103a9bdafd2be000000000000000000000000000000001800a5776a47f52d2af08144364a6cd7442a0e2fc214a2d8d285a29bb7bd3a0293e89f0a1856223a527100d0abf12899000000000000000000000000000000000a6079d18ff3367c47fa61a57a967b782f3529bee93f452ecebd4f5c404b3e1769c100da9b8aee4258b5191ae1dad9a90000000000000000000000000000000011d3188a927e8f13aecf7f8637be6ddbbce309393a94fef77923c286244f8531d3e137e031d8c1af829891425afd53a3", "Name": "matter_g2_add_50", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52d000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc26", "Expected": "0000000000000000000000000000000019294d87be784f0f8fa29de80d45a697bcb694b32f3f6d7641d4b08d8a7ebdad0ef78ba5ccafd6b7f240e1cbde019c51000000000000000000000000000000000645f7851644e1e7e255d0b3dca769b987ec3ff2c9eda42cab65dc39be2f9858c31f307d59f6a2caf9dd932d873d2b08000000000000000000000000000000000e8e93f39ce05a11d40f3b52262980c79ecc52939dd02b94df3e5034a57061d040b0c8894189f4626f37bee485712dd00000000000000000000000000000000001e0b7c9c3d7456b2c0ad842083e9ce2a00da91cb1aaba371ff4b9370f0f2c08f4b53b8e5a3030c99b2957cbe5f9e967", "Name": "matter_g2_add_51", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d761800000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb34150", "Expected": "00000000000000000000000000000000040f355021ba50c9a3b2b4267668ac8d76dd88991be984ab5bab9c96faed6dcc6e8eac78ed29cd6f7d687dd55cc5d5b70000000000000000000000000000000017853cf0a39332e3c7d75b08b2940d693ac7cfdac46719787c22b55a2ab1036d6f95b68075f1c585942843aa486f17bf0000000000000000000000000000000008696feb333417a7262e8976d1546b6d0a9d5970095485b18efcdee8993b16f42e6dbfdd08d30c45fe4af6a5e203de07000000000000000000000000000000000ec26926720243124ca505c0e04923f3cf5eeca2abfdaf4388960b87c6c1713fc54cdd1c825e2ea359cc67b3bebfa2f9", "Name": "matter_g2_add_52", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e69000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b1", "Expected": "000000000000000000000000000000000f3dd56c416db1c06fd27e18fb852c9e1662fed42005e253230a7a8f7c3e0b8ce637666e1d20952c219cd2068d6865f1000000000000000000000000000000000aff045afcbefcdcb5255805a86e8af3de881e5482188c487d15ad1b799cf551c1d48c7665028b05ceb2e82e15ea4ae5000000000000000000000000000000000e0e6ed04926aed1f8c6a4e13227bf2a99d9d6d349a9c86214373be693db702a0011b4423defdb7d842bcb6f722c70b100000000000000000000000000000000148b1af285c65b12eef498f1c9e57a673e7a3803088c56e32aaae13dad3977dda8d3e27809094f8d8ed607239610a1a6", "Name": "matter_g2_add_53", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df10000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e", "Expected": "000000000000000000000000000000001220b3da7e7d03823458bcdcee82db56957e5aec335e9b543ebb0f3cf4fe3cf6ecacb6198c886b9abbdaa42f528b4963000000000000000000000000000000000138233b166547e9e9ee9d11048e2d2579b2b111af5cab372d36159c4c45e28d836d733a1265e8833da64f461c0a32cd00000000000000000000000000000000005f860a0c72034f1a928501d9f549e5c2a9dc72670272fbf35a0b301025c0fc751d55ef6fc2c5bf7ff42df7693f3dca0000000000000000000000000000000012c73105adf97bc0dfec1f56153c57c6fdb9d68341f4397b72f5b6c667873ff7ed5cc841451b391e33290cec256395c7", "Name": "matter_g2_add_54", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0f0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e6", "Expected": "00000000000000000000000000000000014933a0923416428b5fe5be7120bf399ab62ca091b07d03da3fd2ff080b9c411c3cda3bfef40c8450ae31c412dc5feb000000000000000000000000000000000214229a73780d4f260364649e9eb2ed751ad3f687a832a3738ca2cc81a3acf12757651e88c4bcd79239bc0b0c40e5a6000000000000000000000000000000000548f20fa375e578084e085ee71df5f8ddaec1db03a1415938d9521b5d9c914b5295835fc07263cdbf49d7802551156a00000000000000000000000000000000063ecd9efe55229a76fc848728e940183c23bf47363cb34c5a49837e6df8a5f0dc29d7108cd10ea08e82ccf017d246d1", "Name": "matter_g2_add_55", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a330000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c32", "Expected": "0000000000000000000000000000000008a71a08d2c4e2ba3d8774dcb42d3e96c7f72d36fb3b880a4049b078d8257a7a9a51b0b34c093568baf4aa6de70e709d000000000000000000000000000000000daf83b5ad4b91b557982fc4b9b7dbed2998aa39fc4658ba671f5f27b3888dfec7602949cf626c9e6ef21171acb185600000000000000000000000000000000013a7ffca291d9ba8790ca0462c54c147aa22e03a2413b756f27583155932aee65060924e46db321b3fd6f22ff7f54041000000000000000000000000000000000289d7de10285285279aee024e52476fa6fca85550f7af183a161e395d72e1339b629c64127f96bc85858d80e73dcbe1", "Name": "matter_g2_add_56", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a6000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95", "Expected": "000000000000000000000000000000000a4ed8d613cfe4f5dbda1d0c6812d0edee45ffc2667323c3828f8ce4ab55c119e92a82f2c3d06afe3adaa4aaccc18f8d000000000000000000000000000000000fe10c5e185f3f8ba81c93754132d76e05eb3543d8aaa8a2d0c98833ce5fa9e2b84420d6e3412e005cf89d11f5400a510000000000000000000000000000000004ac5f8cc614e3833b3b6dd9eee9ac29501002ba9054554314a4c516bfc8cec870995e811f7892811346574f3c58b2ec000000000000000000000000000000000a6bed54d8ed4ccb09211ae7773c604edc6ce51a05c9acc94e8167026906d387af681fb33a40e72e85cb076e072db7d9", "Name": "matter_g2_add_57", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f254000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150", "Expected": "0000000000000000000000000000000004d145ad2575313a922667b897052063139eef8c61dd375eb055c4a5c52cfbed35391a85df915e1eea50d000b9b6bb5700000000000000000000000000000000071cc73c16a234e99faba9b04fafaca1a943f2bdbb68dcae0a1742acfca1f90c5f69464aba42be6c18be31f79ce30791000000000000000000000000000000000bf725a2f4d7d33c66fefeefce13fb5649a68a93fb7086c943a7bd5663b5788a5ceaad7fd2a219ade832dfb3c0022a5a000000000000000000000000000000000fef4a2610610afef43da2161b86b25a8f6e30ed90053d57f5ee0a10effcdd2af769d32ef6843804b2b6590f95eccb4c", "Name": "matter_g2_add_58", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c5600000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b", "Expected": "00000000000000000000000000000000151ec7c35a67b878420e198ee7bf359d0668ab61ba1a0bc2e5e57b1b7b18838a015464f9910b659fb7d1e10af2801d86000000000000000000000000000000000511536f34067fe931c6e829e22443eb838f0c938eeef6f839eb322d72e2011dd1c33c504dd044e3cd721065d7075b520000000000000000000000000000000010c486f846242024f9bf40d805c8e33ecf1b44cfaa04455d5584db7ebc32c0d29e8742c61886d4ebae93f22c518ea87300000000000000000000000000000000072e184c836a853fd1153eabb1b645bd35ef72eefde4a52db169acdf2d8d68499398599cb4002994c6f4936de1da75ef", "Name": "matter_g2_add_59", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87310000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421", "Expected": "000000000000000000000000000000000642f215b772d17a3aa45ee3aee607321c02b4f7a7df3884259a25ce78c73e9536d46333fa388e506fdc79c708bfd9de00000000000000000000000000000000145864ce36521fdb641761be541a27bbd3f4797b923a870148bef1d5b4b0d463c0a7c8ef07954dad464510d836105e05000000000000000000000000000000000ca038e667fe68111b583dfaa95f88d3b9e46c0798abccd1476071435067e6c0e2fa81d25db6e1175e60efa1705538b9000000000000000000000000000000000cf1cb1b155e4ea47077c42a1a99c3f11f8b27516a808b5e73498ee12363652bb46eab7e55de93513cc2d6272f26a537", "Name": "matter_g2_add_60", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab71960000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d400629", "Expected": "00000000000000000000000000000000128c909854a20ccf9e8e396b617b36f233909a5f6c3524c93cc659d22afe0e7058a438a5ee4345bed914288c64802e29000000000000000000000000000000000239fc43718cd27855ee5450cc9be5be5d9bca8188c22601242a1bb4269ca0fe62ad5e12b2c65558cd3dfc89ea31205f000000000000000000000000000000000a0aec9527febbd35bf041a901b0b35e5e0d48a2d6d733bb557d0767798369a7ccf2f1c278710eb764f721821f9aeea300000000000000000000000000000000194931bad52daa16a648ccf1ba9a4768e5e2900fee4f9bf46ae07d1aa605aabbfe96684f5d2233c0b254cb4ad5517775", "Name": "matter_g2_add_61", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f20000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d", "Expected": "00000000000000000000000000000000189ee5ac642bfd0b612058f96e63acb1feb6b4dce125bf0ea1e56e846775af1a8b0864d4ece6bd96c3b5dbb04e2f6c33000000000000000000000000000000000073d57ab79314e38267ee8015de3156f2c1d5dfcb6655a150b9ab4a3bc9eeddf7b37b3681c49611e02abb012770b3f5000000000000000000000000000000000cfa1363275c7bc5bbb9bb7c03e7bb7f6d6d365e39fccbe62cfe0bb93280527c9ea99079fdf9871abed035b62079856b0000000000000000000000000000000010048e4e96f26710d254110650de36460be2a8302badfc2da8b26147da498e4620e79b4329033fc3f3a9c99b1e12aad4", "Name": "matter_g2_add_62", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e", "Expected": "0000000000000000000000000000000005889133be5f447013d779f2b9b0033667c5af87e1c8a16d239ca3ed238920004d87e00119ded46658026c26988ee63a000000000000000000000000000000000d4ed8fd88f7e1394f2b5a65588bf1c461a292acafdb77703c2790ef249f2de695524293c826252c94967a3ea4a3a28500000000000000000000000000000000001b5ff0aa278c7e87a89d4748aef13b516c49b7dc9f7cd5e0448dc6fd860a7a8af7183a198eebe6c7dd549fef806db00000000000000000000000000000000003c9e40ed44427cc3cf886ca2db341ae31f015c542b857f6702d25cb5036e3e6abeb8d4bf9a0e203281ab85ad89ce0da", "Name": "matter_g2_add_63", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f", "Expected": "00000000000000000000000000000000093b692a68536b16913ef38c3bba7b19ba94a6af1c36a2e54b8ac1754a29c29882107cde142deb95365af00f2d1f537e000000000000000000000000000000001035e70852f38f860a1a04f33081e84f3ed17d83ad894a6800e7b8b9259067b755fe7e08d4c1b297c6d53064ab8209590000000000000000000000000000000013d38db0d8575131865bd7acb6cbe994812bdd8bc7f51b810bc382a6eb379d442c47be20a2c8e751fb08ccce8fea68690000000000000000000000000000000000bd114951193e3bd58cd0025e0b0c807ea073b1c1f7bb04a2a00771b6442e70ea20e1124572ef5b74d2bd87c93c82f5", "Name": "matter_g2_add_64", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d", "Expected": "0000000000000000000000000000000006db1eef1f614613ada8383e63d631484015224902ca38f58ee384a70af0a0575b0e7063675d2dd997ed8a140e2598470000000000000000000000000000000010d7b833f050f18ff4e3a8d0df227a9494dad9cbde88f68802b23e87387622a5333dfb7bcdcbfe2d4d137cb532ef4a150000000000000000000000000000000000c9c40ba972ee0be2823625a23345fe352d701cc8bf9a153d5a55c205ef1b7e5544d0a7f65aaa24bde8d77cb4c31ab3000000000000000000000000000000000402f170c4c3ebb9b1e7d64765b66ba9b8d45b2ea9fe9517626f38e00a11d180e1f8872bf80f6322bdf3a8dd90732ae9", "Name": "matter_g2_add_65", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad300000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0", "Expected": "0000000000000000000000000000000002dccab673b26be02d2c645c82a2c73290f0eb053e07d4f81d4d315d9483e57c58b65cfabeb0172934b9fbb52ad519210000000000000000000000000000000011c34a27c850fe319fe89399e7680064caf6dcbad171c3a23c45b9883ee06ccc3482b2b81e5777759ff81b16bcc1b0f500000000000000000000000000000000119adca3e2b052c045124f021fceb03c979e6eec0a270c7f4ab13674e461839a4d3a10fd48da4e9ae750a238a2649ace000000000000000000000000000000000fb5210677e1096cb5448bcda16646d6dd29ff8a0765c5aa51d83fc952a5ab8063aa96e97f33abf701cb8688c989c363", "Name": "matter_g2_add_66", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0800000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec27508", "Expected": "00000000000000000000000000000000056489b2248ba672501069ab6742016cc8ab2af50a119239bbd3c0a4b9b56e014402b78bf62b2b37bf4645c3bd3d95b800000000000000000000000000000000046956432001feaba6d230da27a72e8db5c8eb3d52f00616f87b55c951217095f337a302562cda789e5714c4391ac27000000000000000000000000000000000172c2a583c9563fe02d43b2b767c4ee4e3990fbabe4ac536d64cfcf059f0e38672876289bc86915b6344eb398fbc4ddb0000000000000000000000000000000008915b0edade80caee9b386e4a560ff4b9dce33946ee992649466315786e139e3ce241ebbdfa7ee28fad7e6214e65666", "Name": "matter_g2_add_67", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e1090000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f", "Expected": "0000000000000000000000000000000005b81843ef3f98c6a6686f1fbd26f77248497ec3d41aff4be5968d13ba86f86309b0ec4792d74220ad8ef147bdee9aa90000000000000000000000000000000019825376b243f3e374b6e9e7e51e0c969bc72b39cde1dfa09187a3c7c5c2c752ee16fa5a4c8fcf94464287419b3a3845000000000000000000000000000000001308cc0c77219034a9fc3018f1d668a41e6959476aaaa5461ec73d7155c6a68fb08e1fdf8140e18270cd338c266a83f4000000000000000000000000000000000fee2a6e245e3bb570c3b605f7ad805bcd68e9a1f2bb2282f92e2a2e83b69e275b21b923f33a65defa8c4224934aa588", "Name": "matter_g2_add_68", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b", "Expected": "00000000000000000000000000000000166414455bcd0e8e40397f4cafa9628d1a092beaef62d35211cf49779ba98df5c1d692f650c1fcf0893a9d4ae1926b1c0000000000000000000000000000000003dd898d0725ee899b913042da8566a1379aeb4dd5f0222ac784205b4e74f32858ae490f981801b166a01fb96266dbeb0000000000000000000000000000000019f0fe4f12b113b337361b977aff7cc7dce50bf37c2609b9f311ce340d30225de178999b73345ef49625518e52aa4d7800000000000000000000000000000000090bc07c6270901d706a8d28d512b07fd0e03013d94d4e43eafbee59677998bfb7c2a58aa93571fb49c35518b6331bca", "Name": "matter_g2_add_69", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b22000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d", "Expected": "0000000000000000000000000000000019ce0f31d9ebaed0ea1d12d4e232bd3ad48373fa465af44f1c8015102b624d2f8330d1323fb2fec524e83de0f6699ad7000000000000000000000000000000000915d65fef96562ea3b76f3152aa1b8e445ef50fa66dc487ad0c04cfd7a33b5ee48aed919eb81fe83b1f4dca59b4990d000000000000000000000000000000000e4731ec887261f29475523f7dfc5d21cbbc1b883439701a33cd58bd24f5d447267707c2b60ea38b04510be7dd10d72b00000000000000000000000000000000146a679d7a81aac5952645b2635f24b96393529ab9571ecc1078c4c20a77e59acc4591b9f45df00428250c5e31b1a8e9", "Name": "matter_g2_add_70", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f", "Expected": "0000000000000000000000000000000016790155e57f7103d9e325a1f3a64c0b8a1875365eaa0c01c515538b64bd8265e8392e755a2f7314c37ec09026f13d290000000000000000000000000000000007bfe690fc4ab166b29de35e341e8faec4bc3c2d4ea2d42c9f4166c0d748b92b743ba646c86ff9e570612c75bcd522a9000000000000000000000000000000000c11b9ccf990162b772099fdb4266716b11dcf46c5abd12d03caf222c571e2a9e28cfb47e11db05162967ad4b430930e0000000000000000000000000000000000bafe02785607bae144d9ef5391fef02b9f2fd5dcd436e2506bd40866d8726eb83c223e09c00f3b8895181c6710912f", "Name": "matter_g2_add_71", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a00000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd", "Expected": "000000000000000000000000000000000965966a8a463de1f3bc49d9873668e87f54d95612231458dc8b885681cee8e2835482b4bfc476153c41b206f427cbb400000000000000000000000000000000183639fa14dd74c33e8696496a3ee269160f88e5daca4fdc468724d9b6af8e7d0706867cdb1bcc608029b89b94c531a800000000000000000000000000000000026257fc32efaf241c7712b0a7e9f881763d8fa0711a452d9b71ea25e973bffd88433cba768f1e5b3ea15bdae9cb9428000000000000000000000000000000001527afbb6594dc0f472673606fb8f4797fc855bde4d308ac1acdaa26f19a70f80f2d2bbf3498b53b887b79fd6273231d", "Name": "matter_g2_add_72", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db100000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3", "Expected": "000000000000000000000000000000000018123e82a5572e6b6c62d5db07448838df9db7f7d15dac1adba1fd924892c8bb3c417354e838f706564a9ac282c2ac0000000000000000000000000000000016613fc38997d39b2761aed3485de4d7c273e8392e434185605e968ed942b9d4712cd0d538ed5ed1317870d0cafcae27000000000000000000000000000000000354365566b6e43f8b7f4b94a6343146f35ba3abf61a204e9c976b1ad1a90d4d493494c957def69ff270371c1c8d953100000000000000000000000000000000066adbadf1b69dd16cf19349c82e362be4a3768551599b81a4853ca524a24326e6c9dcc38b5a60ed6fdeb3cc4e7973bc", "Name": "matter_g2_add_73", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d", "Expected": "0000000000000000000000000000000018ba8af47c5cfa552374cb1b25ada1ac785381f2da0501f86c9e7b11cd4417e64095a5c4bdc2480ee10d215ae2296063000000000000000000000000000000000a2e09eff98280f6a9863d8b8faf8871b44650496eac1aaf90fc2b256f88e937101407d722c95fa76846776d4e6bf0dd0000000000000000000000000000000003824f5bf25fa4aec5a9e044703e5564122bec11da155c01ba8ab8344265516c1063983235863d826f68bac455327c65000000000000000000000000000000000ea72f8c6768736800b141b477610e37477d926acaffaa1951a5bfebb042c94c065e984a8812430153d529dbf07ce2bc", "Name": "matter_g2_add_74", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296fe00000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6", "Expected": "0000000000000000000000000000000009f1339cff0b58b00a871add058929ffebdc58cd1bd8a9c2c965c63e1843945b28138008cca8bf7b7cc9afb69a11767100000000000000000000000000000000011f65b337710a4043e1fa58bb41d80d505e2aee434b6978129c80fa1b124db89e61617e89bc0e596507566f4a484e9f0000000000000000000000000000000017560f768496ed583b3522c4a013f8b96073197e5b53e9041db6dc935a266111e21d8c54fa33b7bda944a573f6e1f07d000000000000000000000000000000000168a0742af91f42058e6501e122b6fc50dc966c2f5981372704694544aaa68fba2b6483752fa2464526d5072f84d8dd", "Name": "matter_g2_add_75", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb519000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be", "Expected": "0000000000000000000000000000000005daf8338637bddeba63c788d78faa622e014efb84d3ac1d655d15af06317fe31d1782b2990354bd507632844cc87f2700000000000000000000000000000000185550250e2d9eec798e8b8c483dc37e2a917b304a6036e8ee518a0738d6bf946d99f6b7ee352b1a259aa894d53a8e1300000000000000000000000000000000105a4865d66ed4bc4f51dc52ffcf284615593d573b6beac490c3ee8e08ab83a529c8dd062d762d1d70b9b3290b6e8bd50000000000000000000000000000000014f598e5d0e40090f29aec1ecaccbebbf2a2d6889bbb9439798924db41b70c0cacdcf1e8ff6906f61943e9a8a1ae4fb5", "Name": "matter_g2_add_76", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c", "Expected": "0000000000000000000000000000000006b63929ce97554659ae731d60d11abe858383e39a67007877f68233cba8179777c0dfe511fc730448da3f1c4347f85c0000000000000000000000000000000016d4df414c287b0871c69f9745a9ae68ea3a1ff41ecd17d87623338bb8750bf12be52caa81537bacee06cebb86f894890000000000000000000000000000000007ad72c98e2428b90bead3616f1b31b26e978cd3f9b6b759ad53056098c18932c48ba78d3da112d7a738d7a9ba21d84e0000000000000000000000000000000010dfcfc53d0458296686fd7e0555593e0378d2cb176d456abebfd8322012bc9b408bb180d4237679985457e689131705", "Name": "matter_g2_add_77", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94600000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3", "Expected": "0000000000000000000000000000000009b166f124b5b85875834b5b0c088ab79a2dcf262240b284f57722e78b6eb56a192cd32544c1bb93ef492fe6d7a6216b00000000000000000000000000000000189b9792982b51b13cc3fc1691e0569b6c8d998168d3a3376e63ca60de4b30a84ce8d04fb265bdcf73f158d8e316bdda0000000000000000000000000000000005b99948b635750040b5b59568f0e8bacbfd512db2ae52c5032cd23eac18ad58d83b8f78cd26ae979ce2abeae8e1f3c3000000000000000000000000000000000d0b6561a49c358101b30f714563bfefc72e0febea857b1ce78cfeb9508b0108c2089c9b35cd694bc8c0ea8afc8d047e", "Name": "matter_g2_add_78", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a88", "Expected": "000000000000000000000000000000000bbb59d3e6b0b4d86ffc89bbfcf543a5b8ff922f1999a1e06c501a734b19dabd54632132c865c53e5287f69f06942a58000000000000000000000000000000000a3bb94431530879a7fb46b317d4f3d65b5a790739b396c78521a20e1cfad9c44248c9576be11c70970a49a1914ceffd00000000000000000000000000000000198df068ac5d3cfb9bd6896ab64495f4b9933a72872679ac3a46764478f043e9fddf17a7ef85fb72a8dc1a722804198400000000000000000000000000000000155c1a9db0c90634a6d214e996b13252bd4db3a4ab84ca7456ac3e7899e6fa096904a90f1150026307a1cac8de00c6df", "Name": "matter_g2_add_79", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d70000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff148", "Expected": "0000000000000000000000000000000010684ea0303f0e76b60eb96c470e1f0466f1f2b073bbedc1a0c0df1d2f6c66d77cb90ef9bfa4fef6a6a9eff8f5c66f9b0000000000000000000000000000000010e7ced79bbf01ae9f65d26894c73a905514296f19561ab4d00c0cde31737d01e7b4e8b8e6050054a7a17e8acb74d49d00000000000000000000000000000000174f771a98e262825ff2db7571f5f5475007d2f73a2c265f24e2929671bd173596b8b163abd46b868a644dd464dcc7cc0000000000000000000000000000000001cbffc9bb3195672ea2d998b169f853d3d4b4e147379329b1bbe69ce76d08ad78f87fdd876af227a050c31884fda084", "Name": "matter_g2_add_80", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d527500000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f", "Expected": "000000000000000000000000000000000fa306f630d06c801e0203525c75fd6065bd12bcb3c4d45c7e02b597f85a53fae1e65a969feedca75068433547e4632d0000000000000000000000000000000004b1bdbc29f19f6484ea4648c70eaa47cf5bb07bbc255bb72dcf68a7b661de433dafb682d51321369cd3372288b2b9c400000000000000000000000000000000136671654b24e1ff2e8223ba747ded51f5c826b6e2c0f02e2865fc35d15045f41952835800406f60f966d1f241914726000000000000000000000000000000001007b5e8ed7f0d25091dd959d89732e9df02561a829ce013f5ad1adb8d6d828a8ce87b52d39fda1b5dc2b581ca420e22", "Name": "matter_g2_add_81", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae452300000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf", "Expected": "000000000000000000000000000000000fb74d9ad4de11df81c48d10b9a14fde8353ac47dc902b4420be4c086332be480552e26fc42b7c0f30e34f740bf9a4e6000000000000000000000000000000000612a7e23bbb525f91084b122dd4cfce4074c9e6eedaa7cddb58a14e0b1eccc2f08296baea3eb3e003e576fab7c557ea0000000000000000000000000000000016dea145df47a2c5262893c273c6158ee14d44c3740981c161624a6e9ebb982a52c1eab6160c3849f2bf3821d953f4c3000000000000000000000000000000000e920661772b8b737f1a663badead0e89aec4cbb86e6dece5d4db8a673e75b844bfe81662dff671658cb8386c16a7f3c", "Name": "matter_g2_add_82", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627c0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77", "Expected": "0000000000000000000000000000000015930559743b21acaf390b557fb960d3021f3cde80630d8867a063d445f860c8a01037057de1929be16d879416b12a6c000000000000000000000000000000000c6074c54c83f717700f61c5b6bfc641502121b59b196a1f8c5f2945e5db1bca0d7a94fdae96bfeeb6204c8c3f4d048a000000000000000000000000000000000b3a78454479c0990e4c65e4f831606c7eeeaef0faa86596350c9e43e84ae959a0f32c8d03d1f631d9b2ecd046efcda6000000000000000000000000000000000aff797d7572f20b06bac75bcf8cef879df11599ba7f8b86eaa28692d1239cff22841b66e28662309e81a6a599e79ddb", "Name": "matter_g2_add_83", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ad0000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee41", "Expected": "000000000000000000000000000000000351bad2f1fd9adc84280515c2d9e538b69dd63ac93514987ecace75d6bc4585199b742eae0d357d587924333721a1d90000000000000000000000000000000003e495b544aaf19a6415d5558170b8686968dc922367c5c8c212fa1f2785535fe0e71498b98b9a39c8b1f2384956170a000000000000000000000000000000000c7040f34872eea5f98ddc78737dd01fdafe75081cf66ad5c7c900674fa90257105b4f4fc59103dd5b92727a072ae462000000000000000000000000000000001312bdd27ef038d4a89b12c86281975bb34b435d42642fe0732709baf55e9a0ecc0ede8a4775a33e880aa2e1fa7b7ed3", "Name": "matter_g2_add_84", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa800000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f", "Expected": "000000000000000000000000000000000d521781f60198341d116fa5cd9e2b5c2fe51f91f6c8318f351df007c96086f6c3baa5cd2b9b4f442305695dd9b01ac70000000000000000000000000000000013454fc15b1d182bc98d75947547b3bbebef6d5e2d38ed7c67d76eee8da89ea2be19280af4760282fa7576412d5f2107000000000000000000000000000000000d866015c84de74c24dde252542d0d3823f435203c71cda140af235d88f3f4b736e9d75ec32c09ab73bf74083e76866e00000000000000000000000000000000147dfb5f53a9cc61b6788c911dd8649c09cfffbbba368c1872a31cfe3bd6d6427d7b00163d39f8e0b81fc4c40dc60b87", "Name": "matter_g2_add_85", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bf000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c", "Expected": "00000000000000000000000000000000059fffdf2d79b4a297f6912e3035cf0b07db9372f3485150e00d60bbe2e7d86f45b5c2ef062dd92c7e8b1e2be5e9bd140000000000000000000000000000000016acdc57e7231b020268373ddc8b8a7318ead02a8c7181165ab045208409373eaf57ace9a6db1fdedcaa477c7a0ff6f40000000000000000000000000000000012fe630f7de8ef5a129b99faff2de080849bf3b59aae1af042c29b1cc49c8825a4f28c4ccffedc6d568f306416b5bb90000000000000000000000000000000000d86ab3e49ffdc7c2485ecbd00256af83e7f3f064d212ea91245d86ca75e3c7f28b42fa9496a5ccc0514cffc60c9fb83", "Name": "matter_g2_add_86", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e84000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb1", "Expected": "0000000000000000000000000000000012ba9a8fcb69d15eff147f663a5d7927b6f3f79330eb9ee625e0100b146597554debfcf97a3afb51387a73554522ed0e000000000000000000000000000000000a63a990d6454d4db6d58642eb3489f79e517fbbcabc06f2eaa00c4b6f9a07aae97991f169d90af3461b7a62db276e00000000000000000000000000000000000a95203a1628a6ae2551df832f7ab94ffcdbf985e4c9744e244214c8e8b8079af05a9321d1e49b7240c2bdeeb7b783280000000000000000000000000000000001ec747203be73526d3f943e0af814dbede34020144bf247eef9a6ac2cfc83ef63f18a73d3baae18bfd8d5e83d0519de", "Name": "matter_g2_add_87", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbe0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc", "Expected": "000000000000000000000000000000000eefda9046a950c232c6244a79c33e7135d0896bc57839a4f971030220e3ca8196cd0ad75269f3cb5586a384dcd17f9f00000000000000000000000000000000195ce623693996f5ce9e45b4e285adb969e6771e6b0701fb5c95715523c8cb93aa641583821a3b360ad6f4ea1aedcc9f000000000000000000000000000000001553a4d0f965d26fbaba56294591935bed63c84abfedbb9d5c61f3d43484ea71600935fe3c8b6b137d7a9074d907e86c000000000000000000000000000000001673c42c88e4acf8ca38680694b80458f988403a4bd667468506452303000d13649c4f610b738a94ff88b65053731c08", "Name": "matter_g2_add_88", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba800000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed", "Expected": "0000000000000000000000000000000007145ce58cbe48405392edda6022ba8942df055ab582ac402e7c9a0a951cc6a38cd147903f042273e736f30849996cd10000000000000000000000000000000011b457ba464ce818a34a11afc3c0007908091fb528836691e6eccaa9a23ea90cdc746769c4b7ec73efb1f2878413c3b70000000000000000000000000000000019ca519fa6a91cb7e83704daa9b92da9bb70b003f9e9bfe9f323430bfec9b19b01005aa9fcd19d5b1ac59dbdab0c0d84000000000000000000000000000000000ae356f5e5de0d7662bab8d947662bf87d792a3438ed477cf6ed4b27c935b1dd76a5aac446d4dc36db544d4aea40b505", "Name": "matter_g2_add_89", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591c0000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c5", "Expected": "00000000000000000000000000000000135c42c10ef97279e3d152b18cbb8dac11ca8c805dd1d80818851424f592e7522589ec7df6748b5c72d0808399e629cc00000000000000000000000000000000083ddf3843434937e05ba9e101096371fd8fb34f226bcd517716200003ab9855f7aea94980c57a6b933494cc57afc562000000000000000000000000000000000be9215d936a49538442189c9a0bd3be07d4b0b1d14aa45afcdebc1fde17d33b66f7dc36da1ea5411549577f5a1967ff00000000000000000000000000000000176a4a4962c4af75a712e5093ec2cd5cb5c0433aa0657809dffbc0bc02b1ce303ac084f39a5721d482d41412d391317c", "Name": "matter_g2_add_90", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff200000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de", "Expected": "000000000000000000000000000000000bcd916c5888735aa593466e6ab908a05af528f34a7901fb60feb1f51737c73612436c192dfdecf927019724ab2a9b7900000000000000000000000000000000187d4ccf6c22381d0c40c9d7820ff8efe6298c6dad0caa25402412661737cb482dba2719c3a50ec08cd022230952dfc600000000000000000000000000000000164510d4f2cf1e14e039561f1baf82bea678d0065e378d5bb7443fa782e6ab2a3bf7e4ea125d6415a8277c60f5346468000000000000000000000000000000000281f2e28b73eca4db9966456b75de9ae3830c74ac928fc4c36b4aeaaffd47ee587d948f68056df2826ca2775415a53a", "Name": "matter_g2_add_91", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5400000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157", "Expected": "000000000000000000000000000000000cceccfefe04f94e0b67b29b5df8007930665006cb5a59504c3656b8c0bfb52324cdf50fa2722ce15b0ded0efa7fc85f000000000000000000000000000000000cdf34c330c0125f524f0711197639f8aca3e7c435f8c5ea30b78e9622c4bb72a7e584980cb4c3c6ecdd0689daf36b6a0000000000000000000000000000000004b1505d7fb65f6c06ef23aef85b16f3d991218187c5782fb635ba805da463cec9cfdd670c53d680c603adb827a4460a000000000000000000000000000000001104af6bef6482ae64b3b6b39664ec06c39bc18fa91b7b4e5bfcd444c827bab30ef548b28ef5487582d88fbc6d7983cd", "Name": "matter_g2_add_92", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a70000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc0", "Expected": "000000000000000000000000000000000e1ef3003fe3181f690224cbc7008856e1251430ce3cff56a1965c89a892604398f5101d1bec7ff1590b0cc3d23b854600000000000000000000000000000000185b4d4b5fd8313c31542bd1bac034046ddc705b41a034a00570181503a6ea4c2d808bba0478900064270fadf3d655920000000000000000000000000000000005bed63ab9898b89f92027c04ba256569e6285c851753e12760129c98899bcbab34b62172906a1ea4cb056d4d0a5717c000000000000000000000000000000000961129a3e212c7412018d7407d7ad16412feba8c138f4f6ba69daa1a25c6b23f3466bfde6f5f0d09ab67248a2abdc68", "Name": "matter_g2_add_93", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa2000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc01204", "Expected": "0000000000000000000000000000000001504c47ab0c410b32d5f1fe3d3996dbf1b21c5ef5aa3a2862a9d561b419f818f0b32b8e931c65fffc393ce7beec70ee000000000000000000000000000000000217e9fddd2551a171a13183ae3aba6bc5ce99e8f3587b92a7cffc738b478d8293b8c71989cabf9a55c5f5077249345d0000000000000000000000000000000003874de865d93650a95af4e153fe557c45bfdc4837bd6e209b8f05ad12b8fdee6432675cd92fd739b7e98e56e7ef16b60000000000000000000000000000000011303c0c7ec1f434cdf07c110da5f0bcd85935c3a0ce9fdf5546ca61edbc2d478562dbd9aa45a5f8d96e033feac2fdd6", "Name": "matter_g2_add_94", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99d000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6", "Expected": "00000000000000000000000000000000101ed22b16502de0d83303134a97db17ce956faedf47256a9ac86004bcd3ed112a71328a58f98a85977a7f22eb1352c3000000000000000000000000000000000e841a88d10493f301af54c5fe07a31ef90de106a6c87d5631b6967fd017f561a56176a5f3544dbb34b9f94040ebd2770000000000000000000000000000000001bde3c0076f26973651cedd3da97c7eda24451bda856026d1e22d3b65c66a3fcbfbf506b4b664b5fc06fca2d712d8a8000000000000000000000000000000000ce553ee3b7d5389798cdc5af8569aaf477b5b74ca1138454dc61badcf3ecf5e0ee8457e374b5735d0b8408b04fdbcdd", "Name": "matter_g2_add_95", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d00000000000000000000000000000000030dfbb89bbe5c14a7a55e68edc4fc38eaee9fb539a6b2f941264c7dc295da5712b0af0f2bbcdb74f785dc9ba038b0aa00000000000000000000000000000000132b4e02fda605a69251a4a6289c47536f9735dd90908ed1fb619b3ab808b3a1f1ca3fcc8f4b35c9864ae311c15747f80000000000000000000000000000000005858ece0bb09e55e012450551025ad2a6d93a15d29619433742851a62d987e7f8bfa6c6faed76493a27060ef5f51805000000000000000000000000000000000dd6b393e6d1b8d546e3f5ce69bc1737399e6ababc628f25734030e10d82b5e9370edfb5da15566d80e23d2fbf8aad5f", "Expected": "00000000000000000000000000000000182f90f5d3ce3f5ff2d91430376144583247def83b3e83524094d57c0f1be98b1c4946964deccc25fc303d6450edfbac000000000000000000000000000000001844806f711735c5ca18ca48e559a9e327b87b91d22a5ef161da7874668130e21a9499728fbc2c88366bdb59f8ced0cf000000000000000000000000000000000815e7cff14b4ceaf26d1cda5c267f432fad294b6baa239b65d886ffb039321f9e24330ae738a35298c6d1ec1ce1c95f000000000000000000000000000000001188a4a2f0920ddeccde1a47a0636aa7c404fd77fb9c828e4fdb5406df80ee6c258c2d4a89dae5e2a2b05210df9100d7", "Name": "matter_g2_add_96", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e740000000000000000000000000000000017032b16be8656cf23bfe0abc8c9e6aade223fa9bea6fe25f95a025da79cea6adf38536eae3859b25ad1af1756b639cd0000000000000000000000000000000010975ed27cefbb43bafad0fd14c87ada8e84525e1d199fdf1e77caa0b718214b33e547a42a040ee3bfd51621a20d22fd00000000000000000000000000000000133d29aa41f92de37523d281eebfe91103f017e5fb390f6bad9a2a4419fa4702bfa04847edbca1da96eb1ad563a92c8a00000000000000000000000000000000014af850de7e800ebee4be1a33c7e3b30aa94106db7defa148568ca3c8d82edc97ab5769ac40162d3728687cdac201a5", "Expected": "000000000000000000000000000000000cf42f2ccff2e0cdda7e5f1d7652680650b4afa523c8f9a554ec18b905c837a189fff73982cbccf903ea492ea902b87f000000000000000000000000000000000d38219770f669557cdb623f2476b5f3f7478422b016123bf86a17bf75848548d1a1ce96a292637b8d52481321d80fbe00000000000000000000000000000000170d8722b824e3291b570ba8e4f9279c1dccdefb95cb5b7a94d27ad8a93513737f12d18ef3153c4e12b530bc457af34100000000000000000000000000000000021aee9e5f578328caee3177a4e08303c3b5533e288dcb75f94992db3520a6da16f4201e60367240b29c48d175942cef", "Name": "matter_g2_add_97", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d55300000000000000000000000000000000185aefe71f24281e5b03dd41e6d6d45fbc8975beb175118de7568bff0a9ccf917e9df97dc26bca16e8da06b0e9a8e7bb000000000000000000000000000000000015b326d401b827fdf556e4a24a3dd6c8036b1c849751b5ae3c3728cad88f931b06e3a345523a723481193f7afeb67800000000000000000000000000000000054ca16b4c87293002c31e64ad303e8f040e11de8b45c5fb9aca9dbec59b29dfda8532a8ef5ae6a92ac8ea90ee4303e0000000000000000000000000000000000b65a233a7731366cf24c801724265215a8626b1290d86c60bf1e74b021b0b44d7d6552f936fac7b5e60cf1feaa1d82f", "Expected": "0000000000000000000000000000000010d1b2f595166929347e06c1debefead06334f554dc31f320cb844abdb1810b5f7c4b933ff8072dc03d303f4a6d0d09b0000000000000000000000000000000013ab41dfca0a7cb0c58c2c19e02f675a94d9e73312cfe2999dbac34e6a80bff9472506b48690f24ad3171ad495f445420000000000000000000000000000000015bfd0db53fd4da538caa3aee7a90a669cb84460365696ee79b190d09a6d4c3f08965de7fff4efeae435db52b97d213b000000000000000000000000000000000182ffc4304b911b47b092ab678edd63ed5f5e8a9069daf9247f3bf9c0dd149cc9992728a13b0a236fc9b37714b35882", "Name": "matter_g2_add_98", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db400000000000000000000000000000000085dd8bfc00ba517dc8d7ddb49d711d35bd36f9fe3843689019e779624a032d2f023533b8184b73042d1a1953d2885e50000000000000000000000000000000009ba8d5d36e6efe02097a3206bbed68529f0cb9875ab81deafd886d9243bfec8b403d2abe713a2ec929b93305dd2da220000000000000000000000000000000007f8f90ebb2771136a92023901ca85e87fb7c8b1a40f88ae564a124bdd0ff0bc27ea98612a817e2c871fb4bcea3bb06600000000000000000000000000000000152de417d02f1d14e5899201db8fd5db8ecb40ea8d415dcdedce8ac70c28d851db68e9aef94506a50ec28145547a2d68", "Expected": "0000000000000000000000000000000017555399f979745302f08210de5311a6401b6b181100b3bc6b6d450f0f62079d2f02d7badcb164f50dfc46a975cbd6720000000000000000000000000000000014aea86c06e4c1fbf0711a8cfced2544c7624abc7ae7906cd992bdf575a702540c45c2117e221446ba09960cbc9048ac0000000000000000000000000000000002fac56960c4989a84e02ce36e8970c2e847ee45579d31ca77f042bf96505af574af822da084ae64b22ff876610ba9a5000000000000000000000000000000000a481cfea2aef8975c80a297ce5a185dacd25649d41f8466d3c63d786e3c264a8e4ccab5ef6b80ab1260e86ab6d5b3f3", "Name": "matter_g2_add_99", - "Gas": 4500, + "Gas": 800, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/blsG2Mul.json b/core/vm/testdata/precompiles/blsG2Mul.json index 886b0c6adf..ee9d50fbfb 100644 --- a/core/vm/testdata/precompiles/blsG2Mul.json +++ b/core/vm/testdata/precompiles/blsG2Mul.json @@ -3,728 +3,728 @@ "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2mul_(0*g2=inf)", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2mul_(x*inf=inf)", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_g2mul_(1*g2=g2)", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000011", "Expected": "000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d536944", "Name": "bls_g2mul_(17*g2)", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e", "Expected": "0000000000000000000000000000000006334ba1e361fd94bbd98f44b75ae9ec00ecb4d3467b5528870b1a1fa9a7d04449f12af90bd4c7a1e3f29e717d6d19d3000000000000000000000000000000000bf4cc1626393956915845ea7ca43d30a59c7196fbe309f2d5ee6de7e40c191d29821dd6aae46abecf634b904de8f7490000000000000000000000000000000014aeb09e252cc74610ab956057d4ac5af95cbea8a6baba9e5062643dc037d6841044cb38b22d7dfb978fe0b58f94cc3a0000000000000000000000000000000000fdcd73452fc1ced1c06e6271410a48dea05afbe889a692905e1baab8d72418c62531aab8b74842b51016f0a9cbb93d", "Name": "matter_g2_mul_0", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d", "Expected": "0000000000000000000000000000000010e70bef8eb893377e7ff92168d7acef11c9efab990fbded728b173b94e1d99e471a8357f16625d353287086543551850000000000000000000000000000000014043c1f00221c439e5febd12724a9224bccf0389914461644daf329208e869b1bf149880dccebccd440b1748d15e944000000000000000000000000000000000f7dee1e7d122e410b29a9eb011ee700c2f230cf8f611e196ec66e153c1fc331175532a8f9b060b573bddaa705430c2e000000000000000000000000000000000e1f659470eab7c0741bc8777ac9fc8dcd11a6f1b30ffb4265e96b879e795a4dbf851d1149429dcab95464e89f334627", "Name": "matter_g2_mul_1", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1", "Expected": "00000000000000000000000000000000119a5147fe9ddca7123f721b5662c1a44b0964c37a214cdf3a4fd34166e3b25210344e65220c38ec84d0e3b5ccc7e46d000000000000000000000000000000001642dad5dacf4295b871fe9b2787f0861f158807b2b6c01c2dce12ab053c9472bd3cb98de5dc33f40053ff45ce5c9af40000000000000000000000000000000005bb5761602b6639f2ecaf79f2d1f853fbdf75f4b3852b90808b858993a83f8a0da8a2ce7072aa91e3b6b3ffd0b3d1e20000000000000000000000000000000000a75143b9551d4ae41fb8bd71fdba7826b994c65904d9189a5ac5130a59cbb9d8dee0e016735565148fc49823d3969e", "Name": "matter_g2_mul_2", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a", "Expected": "0000000000000000000000000000000017ebc9446f8c8e17dfeddab9188d0c808565da29c0bdbbc4138a44ca3196c4564853be28286b66660cda36832d6940010000000000000000000000000000000007f29a9583b4ae83d3913dcd72590a3f20f39eb5a6d36663c1ef433058e76550085b9c01bf797d98d0eef45cc22ff8c50000000000000000000000000000000016eeaeb123b12d1913ff1e50f974228c79f2b995609d2e3835c8e1d68773b0cd484df57b86111cdb75de1e19eaf062e500000000000000000000000000000000002f5688c1286aed42309896bd65d1826dc64dda615238fa9043669806968b8e0e1e3e77ef192b7df540aaf0ed282a9a", "Name": "matter_g2_mul_3", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89", "Expected": "00000000000000000000000000000000042d0c1941ae0ed5e8787437ad5e2753bba02185317848e8ec2e425ac954e0efb1bca534725adfe87e8507851ee337af0000000000000000000000000000000002db55ae8126cbe86327aab880381a81205e33a351d172c883b9cc184799866a8db5a6b4321496e05d3ef62d00416d9a0000000000000000000000000000000012c45444403dd62d7be3e7658dd85909204751dd7d085f6edd38c0aa9185d3c32407d8c95bba371b380f788d0dc48e0900000000000000000000000000000000111421c6dd0db595ab731adfb4bc76c84a61197cb023b6f17e7176c443f20a4b6f8cd0a00cfa61e831ed20b3c6a84d98", "Name": "matter_g2_mul_4", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944", "Expected": "000000000000000000000000000000000ccdb2a0b670f199a9b61198e6a2ce2117075733e6a1568c53ca493dc3674c6ae85be2491d2ed983f52e2c7040824afc0000000000000000000000000000000004f52450d7e041c561c00200d5b142b32f2df2e2156e4f6c15d6c00e185e135037a1ed6be15e2ed920daa00e2f9bc8da000000000000000000000000000000000f39c38c18f03ce6baf1d016cf32d7387269940280f2e8d21db4da33dbd2d24ebb93ae3dff9f79b015eee25813d677c700000000000000000000000000000000189df61f7f1025fa6fdd0a4708ff1d53db7d414019c4828de2520af3d36776062350061c2261e46e746a6475fdeccb2b", "Name": "matter_g2_mul_5", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1", "Expected": "000000000000000000000000000000001388a59c57ec8ca5e68b99631abdafca1b71352ac35003a55bbc415b48b8171857adda31123ec86a6ed9e1060d56aa67000000000000000000000000000000001471913b1ab5bcf9336665d3d44232b4e58da70285b7b8eb1dfd7c54442afb28c339f56e6389f89b84db0879e1ee058300000000000000000000000000000000022101b4de40b7180ea17bb36bad0a668a8def3e7361a96fbfabcfc4cdbe6f607ee4ee80d0eb2418b848ad056520092900000000000000000000000000000000103cda694792af5a51e04b6422600a0ea6f50808ca54423cd4f59dfba633daa5afea49c85b900f52e182610efb62fe7d", "Name": "matter_g2_mul_6", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c", "Expected": "000000000000000000000000000000000cf5cb957a752ce9187940f63b13080790348814debf84b91e74fd6e822c2735941d61d50d492439475bb3ea7aa849ec00000000000000000000000000000000012e546ff33dee9875510a68301f46d89e6175f5cd9a6e179fb8599a580e9478fb8d92038982551dd29041d8185c7474000000000000000000000000000000000d52fb57bf2996dbbacdbcb4088df38e77e25598b91bcd5e41eaa27b1398eac150586b142f068d5b498e0ce458d3e8950000000000000000000000000000000012295e1d1039abe7a5fea51a04a34e9e8d44a0f24b8c032680703c119d54274d3bc2e548854021ab027b693e43964314", "Name": "matter_g2_mul_7", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108", "Expected": "0000000000000000000000000000000008e4c57309339400ac9b6b5df16972c272d47cf69ba7baf89afa4f4e72703999c5885253cc35686f6c8d277399da2a390000000000000000000000000000000018ad4e1f105f16b0dbb4eb089c51e709c25e407e54b64346224b1abbe15d62fabb231e36a69eb05a9ba7860f772634200000000000000000000000000000000019994d20a7ecc0f234ccb6b1793fa7d1ece64b3e157c579fb05a8c6cfcdd6f5456ac1f4c1beadb69206988ab543bb8bb000000000000000000000000000000000d435e74bed382442ab83ec90dffb91336137932524bfcf9753fa5ddfe038d0b98a045c8ec9deb53172e5662d3fd67e6", "Name": "matter_g2_mul_8", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672", "Expected": "000000000000000000000000000000001425890b6c46c5a07a79127de4ddbb751227dca4481ab7c2f601bf22b8f6a149767c73bfbf57ee399c0f2d0b12852a0a0000000000000000000000000000000012cce15f53fdfffb5f71de3567b0c0adea65b9321c85677c574787f7048c1bb5e2dc985b65fbc48115aa129e6000fe4100000000000000000000000000000000041398497f975289fb9fc6ffe671a19fdcd3753c82ffd3b2084574107bf7fadc8de462507f4484c32df39967c3751a480000000000000000000000000000000007514a7f246006e714d4a8cbb4e89d81b951b5c41a05bcf35f61283e888074fb3686fb6ecc1a66e491ea1e1ce0738102", "Name": "matter_g2_mul_9", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea", "Expected": "000000000000000000000000000000000b24adeb2ca184c9646cb39f45e0cf8711e10bf308ddae06519562b0af3b43be44c2fcb90622726f7446ed690551d30e00000000000000000000000000000000069467c3edc19416067f572c51740ba8e0e7380121ade98e38ce26d907a2bf3a4e82af2bd195b6c3b7c9b29218880531000000000000000000000000000000000eb8c90d0727511be53ffcb6f3b144c07983ed4b76d31ab003e45b37c7bc1066910f5e29f5adad5757af979dd0d8351d0000000000000000000000000000000004760f8d814189dcd893949797a3c4f56f2b60964bba3a4fc741e7ead05eb886787b2502fc64b20363eeba44e65d0ca0", "Name": "matter_g2_mul_10", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76", "Expected": "00000000000000000000000000000000048ea2c854a0df7b10a2147db6eabcb16eba340644f737fc99663d1ef26d8ed688c2baaa7d7699c5f540d7605eb48485000000000000000000000000000000000c959efb835d48d3e7a8ce643764f27c365f6248a88e39092e3a6498f04ed851c55b796dacd62ae73d7edf23aa45fefc00000000000000000000000000000000114337b8caa68cea6f22a25c0ce3b247cadae24c63fb02c6a98a728b54f97b12b1473c8e23f55338326b9575a637bb2e00000000000000000000000000000000033167b0668ec650581815cefab61d13661f4cbc6e01711af0aefb699e1979b551d0031c603ee5f6dd4f716ea7aa4a6e", "Name": "matter_g2_mul_11", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c", "Expected": "00000000000000000000000000000000142f6b71471f3665ee6269cf598fc3587a62523f9753eec48a2461a2e313e376828cf6d1a9ffc9e64353c8a668718736000000000000000000000000000000000153647cc4a5aeb8ea52f845c415651e167ace9f331c1d73eccbbe20a4014f9e1158c281495206de4b841839438a595500000000000000000000000000000000151d07c3f83217e63b332a6c47e91ef2418e9c658353f8b644f23266f5fbc727562f0935b4d892db947cfbd0757ed61500000000000000000000000000000000035bce4bd2d8261e21476c325cb68e581f20513eb5e0e6a0ddbfd4ac4674bc323590b6f52d0cd50010c13642e7e03daa", "Name": "matter_g2_mul_12", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a", "Expected": "0000000000000000000000000000000014e83f87e7f66d8ed880ca46a76a5d3bbbacf2dafe1ee055f04af568738f4c6ddf2a93e1810b616da6f64f25c35a7b5a0000000000000000000000000000000003d14447254b61168d36f92710f95f7100cc8f278b0bc9528da763a18a5386b3f5b83b96f4dc426e4b0fbe755bc986790000000000000000000000000000000017f1a79ed64abfe5e960fda02cf3330e6ef5612c1b8639386959f86c970adb797bf077a468273d37996a65685f75ac30000000000000000000000000000000000d973499a7bf7132541c0976bf2e9bb26a2b6cfa5bda720352fa7a180a6b8fe95befcc13de5a2efe58be934cf7d8e664", "Name": "matter_g2_mul_13", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054", "Expected": "0000000000000000000000000000000018bb69dd6db0beb468242265c382de5ac342d465b5f72d4e5a24c67a48272d9a1f3af28e0bd3712e16a854c5d91c616b00000000000000000000000000000000072fbcc86b7dee9c2dc177dbabdbbbddb630c98ac3bf3737fd22f99e2b2b690175d9c5aa4b577f78c545dc6a5d2d03c900000000000000000000000000000000161c4218143ab1f0387f19bccdcd08f9caeb2d1331ca890741799ff1b40533076b6a96a910714176c770b25d2c17715300000000000000000000000000000000063098cd9d1eeb899724b40a2d10ac951ba0277db09aad639957f58541dd391fffadc5d97833bb9666b054e12debfa92", "Name": "matter_g2_mul_14", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", "Expected": "000000000000000000000000000000000e43672f1bc25e7e0e64a3fd26cb246bdbd6fb5c9084afdc87c888634916e6a6cc9a351cc67a6ac77ab8e132ed6cbee3000000000000000000000000000000000dee9612527c8ee9c574a4c51f5d3504ccf1d5781b59c78ea15294332c6acfdcc7bc68853e70f1f72524c930e4c3d2eb0000000000000000000000000000000017eba629eb14a0636926275f1c2109318ce8818d8171c69fd371751b6de47bda5b00a0b0e3765d05bab7b8dea9add90900000000000000000000000000000000052f0a4cd9b91695e1e58ead1da1480fef08cecef63896aa51ab16da373b99b3b91767a374645ac5932d9c7fd21d4636", "Name": "matter_g2_mul_15", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca807f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf", "Expected": "0000000000000000000000000000000019b7ea673dad96c8352870136ea262c9ed105550cb403eb1e64ad598b2145fe1b95e5d61f1b5a6ebec47568c67b68086000000000000000000000000000000000f06ff9bcf2ba284e705b12ef2311f1a9b867ed742ee0737567b5c878547b18394b82c2bb97e16586515728245692cef0000000000000000000000000000000019dfd2d8fc4f2c989c7e1016e147f336174c84d380bab992bf1adbffe96d93d4d2d1d1dacdba3adfaf283b184478229800000000000000000000000000000000068d230422006004cd88ab0dd46a84af3905c7a1d329446cc23c1c5adb401a86a9fa76aaf577f77c2678cd8de8685ed4", "Name": "matter_g2_mul_16", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91bebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da", "Expected": "0000000000000000000000000000000015ffdd83355978ebfc386e13987effac0137ec628fff1667ede29cfcbd05e31cf8323959dd0247c20cf28978dc242c790000000000000000000000000000000016b1f810da2ae3c2ffbb6b83c47ef03eb0f298ff4c304ab0dd7b97207949d62858458d789c86c0cd474c34fa720ad3b70000000000000000000000000000000002a2e1463d5e795e6a25998a848b079363efc7d0337c3803385f4f17f11726b04108adfd87a811d709cbb6750c969526000000000000000000000000000000000289a3f472799c06a84bb1f377a36bad910220e1017884545159fe1b2505e8e7473882fcf324ba0d9125495bcbbc7226", "Name": "matter_g2_mul_17", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed833", "Expected": "000000000000000000000000000000000b02ddcfbf391a2d6953261c786945093b09377352473a86cfac6456a811233809434b566b9301eea3105eb86922efcc0000000000000000000000000000000015430deba91113b841303120f0738012d77207e9408474998df5e68d0d61f1a64afb947ff93116ae766ca5325046e263000000000000000000000000000000000ab7094055919f6f707b458cda552f25104d95e4ec8d020ea4c17ac1d7efef5c4c3a769120718f1d5171eb8630a3018200000000000000000000000000000000161e7209f8c98e511a698fbf01735798cb632ae1afe00870654ffa0ba93a549edf4b97d60f03974ab0964cd39298401f", "Name": "matter_g2_mul_18", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31d411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f", "Expected": "0000000000000000000000000000000006cb218607a1f66ce361c89fd20edc3f00421611adc9aa52ec35d45e023174962c863f740ac36c984c2b466cfc4827a900000000000000000000000000000000152b22d46e9660da8b1be4c5b14da613731e750ff7eebaf879f7074bf3c33e1528a2c8479e0178707e3855b49f85f045000000000000000000000000000000000c928cf78cee2c8b9da8215d33d189c5636df1e8e9bdaf143aba7ed40f29490ca2328b4a20cfc56f62e4ce49d9e77f14000000000000000000000000000000001574b7a9c3931933160ad4eb17400b6297210db47bca034bc1b5d17a0cb8c41834636b9123e625e5eb0b01738cd6b9af", "Name": "matter_g2_mul_19", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e176bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc", "Expected": "0000000000000000000000000000000003e17452a80996203fdc4037db072c452f9eb2dae689c77c88b299d7ba266d111ab2b9c4b24149968d72cd143a34fc4e0000000000000000000000000000000014a057d7a50c9b0f34712ff8008770080bfa671650fef43c82726257da180dfb9672b266d4c54d65fdc677d917e6c5b80000000000000000000000000000000013b452c980bfc4a484637b578be100753aee9dda9487d5ee5c017c689dda838fc673804369328192d780d60a9a3de0f700000000000000000000000000000000103aa86d1807de242a6d4fa4a49be6c91cd757df5808501acfca44940733c6a524b851ac962b99a9be41bfc8d6254478", "Name": "matter_g2_mul_20", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b712a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c52", "Expected": "0000000000000000000000000000000007c616472f9ac60f749979c6f870b587425d514395ed07558ed287fccabc77f0c90872f3885d0780bcdfffedd124eb3d0000000000000000000000000000000019531e9c25e84a2a968a85d9f1ab61a372ebc59ba5bb7a2bbb3c0d6e4c9d04061b28fdc719735e97ccd5f7243a58cdc70000000000000000000000000000000007772d3cff12bbee916a6569edce0c6dbc2bd8a794919a4dd7bc37024c8273245210511b8f6da551fe626b7b840833f300000000000000000000000000000000186a3e858a83a7ea1bfdaac65c2df1076059aaa193961559792373886c68acd2f9fca61b166a0ee55084a6ea122ec3e8", "Name": "matter_g2_mul_21", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b1", "Expected": "0000000000000000000000000000000008adebaa95d10b9fc0f1a1f0d52dd6741517d2ba23e3f9e7a9221039684ae226ea602dbb50df0efd44b2b5bf7495c0b50000000000000000000000000000000008e276e78ead2473602d37cb9f2f589f9c60514a1fc5c215acf487bf57c935467d29945d3d671b41a8e47c9495dbf5c9000000000000000000000000000000000fab06240cb8cbe9afcc4ebebde50c2881e4bc4d4f2ed09a1065e3620e6344fb3c5f3019250ca4edaeae4902abb7400d0000000000000000000000000000000003fa6c48ead374be1dd45c8417ca8234c15ddefc5039151e6cd7fb27f866e134cef2f59ac9b2ec1b26896eaec9213549", "Name": "matter_g2_mul_22", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa0977064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e9", "Expected": "000000000000000000000000000000001412bdb48546014adf3c4eac4dbe79ba700f90c8030b063828fb01be5977bd73107533a4e8030c8d9cbdde9bcf10649a00000000000000000000000000000000126d3e1006abfeddd810cb1e12c898cf5f543e414438e600ce4c94cd8dbd1e17c0f3b9831add397feda74362eeace6fb0000000000000000000000000000000005b3159638afa34f219513cbcbc51567b16fd5598b85e6ae0d232021133cec25a6269250df2ab7b5ace726e9e2fbf0b0000000000000000000000000000000000c35bfdd1c10e903da6d41e9afbe65b0cd66addd7893fde41dfda8e543a93938cdeab52cc9bbdbe61f93d651bd1c923d", "Name": "matter_g2_mul_23", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b", "Expected": "000000000000000000000000000000000bcc781f144bc148687875789fd8c54dd820170984b6f8ae75855f7e45619c1d2ff85c330b7743e447b5fc831dce9277000000000000000000000000000000001409aaf3c94c9a6b5123c82a7f311af7c2f60e9b197d49fb5b010f84faff972151b383a83c106de43454f8097005f6c800000000000000000000000000000000064a91226da8b9cb587030f1f4afb0d422a51e4d55212f26c621abc06fc0c57a473a9be75518a5f4f9a7f8d4aaba69830000000000000000000000000000000002cf239343bb77865ceabfcc1fe34cc9be4a1ebc3a70f16f8b7cb84eed5843524f95673b01466d6cbb0d8d9dc00793e6", "Name": "matter_g2_mul_24", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac93176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a6", "Expected": "0000000000000000000000000000000006bbdabfe104b62d22e78bc8f3446a86cd5f10c4c5a54501140768b55a7e6940b9952c9a90a14d8fdc7c04600195cd6500000000000000000000000000000000172e718c926cd393bf303984518432693c304a2758174dabba303ff4c0289b5bf5376b61e8821abab322d53e88f71d480000000000000000000000000000000000a2f84fbdb5b05107a0a340e81b56ddf6d03c23848448f841dc44f07cbf8a575289cf6d53986f581fddb0f2d07e38d70000000000000000000000000000000005cbc10f143a9a1fe23f670a4c47d385f5c7069d8c46580322d6939122b2d39d185d6a8c2e51e88a1d40fd2e82d08b8f", "Name": "matter_g2_mul_25", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b859239080d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36", "Expected": "0000000000000000000000000000000011769e191fe258ffd1922295a9fe877ad5a52fde6e343730f8f5ec6cdcd584f8ed1dbe0f55b5dd81f5f78b7437f02abd000000000000000000000000000000001253689089e9192d10a45342214425de36740c120e49f596d24658941ce2b2ecfb50e879be0125e3d159088f88e234f10000000000000000000000000000000017b642d1b5a953f47fff8f0649263f16f41a0ec0397d5a81571174aeb85431c352e2bf6bafa6894d2e6cdb5eafff16d40000000000000000000000000000000017b3438d0ddbd2ace1e63802013b5bac00d31889dcb2d9653a6f6412d157aad2fc45267322a62129087380bec65ec169", "Name": "matter_g2_mul_26", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a39915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc", "Expected": "00000000000000000000000000000000089a07bf63b8029e0506393828d8593b94b73c750815552f9a3c74ef7470b5810bc27212ba02ca6fdcd97e1e28a52a1e00000000000000000000000000000000051a93291d4b912f0a594d45c0264a9073663a9ec75e6ee81e13e79383d96e9330bab845fd1e5163e5b28c41c4a854c40000000000000000000000000000000016610bf2b2006207046e489294a132937edbdf95caf508f0df3bf8502e641aab9c44903cde75cff3c1f86873e06cc58c0000000000000000000000000000000005d33669fd8a6256dc55f513bb93cce8bae62a593eb8903cb7d7902a7727efb8fb4bb2e5058441c30b99f146ff5394c3", "Name": "matter_g2_mul_27", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e0550860165061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b208792", "Expected": "0000000000000000000000000000000005aa23543088a9a833d773a71275e73fc3081e13c907b8a04a330df7d6c06618fe69e644e0ee55869e364d3561e40f300000000000000000000000000000000010eef9238d2c520f32243f07161f3e35b15fc949b9401baa1a9c5df7d50b2cb3bdd237747735b235862bb57322fd9d090000000000000000000000000000000012dcc16496c95e39ecfd8f0514b5ab2569d89826d957478cdecd4e827095034e974039b37e767a0f25bf057ed715aeb00000000000000000000000000000000000d0593865fd2172ebf1b94c7511ab7d433a276bf833515146adb6d79b6e09d7c18f4c7f4d3241c14d01a4ad0f31580f", "Name": "matter_g2_mul_28", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3fff396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c", "Expected": "0000000000000000000000000000000015785bae0c27680cca2097ab52306207a61ba9903723f574091ef5e57c2e871e076d7f46e6e39f65a01e183e7bd822f000000000000000000000000000000000071110a384248664db46f21d87b455a3ad3c43782c68304ce17f52cc8579fb2e3378995d6eb3b8c97665e5fb7de665fd0000000000000000000000000000000019153a01c2b3c5d481474a71e5c67f27fae3232a0c8f1655ddd4da6b4c79870bfb0b6beb4af8c54aaf7e9251ad41d639000000000000000000000000000000000c58375439a93e0763467c6a11dada3e579ec53a968c9b9c1a446cf3224ea0c89c9ec218a8b78de91fc12f087e722f94", "Name": "matter_g2_mul_29", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2f0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa", "Expected": "0000000000000000000000000000000004c7495c03fc3fb4d0fd4e0e660d6424de9e060eac72eee3608ba95bac294a3a62d246f42dcf3b575ee1cf8e20a9106100000000000000000000000000000000091140aee42a9dc875f87f3ba29beff95138790140f8bb522c6c15281b3545995f9c13b0b73ae691317e674295db6526000000000000000000000000000000000a945a215b2861427e0fbbfc6fea04e79edeaa1eb87df5db8e5e017cf98fde7b8d5a04a1b2129a4aadd2e3924ecc0bb2000000000000000000000000000000000a43f8d3d92a03b7bd4c8a34ce31729ea0b8e6b051c30241dca2db31a02b6e537071a914d8f0876f944dfdb613540c6d", "Name": "matter_g2_mul_30", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", "Expected": "000000000000000000000000000000001821e14e70e12c7caf2a1ab651eb81dd61c4e1eec9a02fe4124abb865a7029e066f03b62e6ecfcf0fbae5151272b524f00000000000000000000000000000000044ac4a7399d6a67e7ee8cde3f5fe20b0a745462c870926f0ce8554061eba5bd62a8a08c798d8bfe30fba5567d47c7ec00000000000000000000000000000000178b8f061ad9282b3b2057f20c115c91df994ac40aacd05b7669e934bc7d650a0cd88f9fe17d7b766e34bed587ead58200000000000000000000000000000000188311eea279ddcf75f8dd82643ca3efd560ddbe6c8f2696cf7da03e65cc90d97b9f9ce99e29269644d8b881e624cca6", "Name": "matter_g2_mul_31", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f86d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd", "Expected": "0000000000000000000000000000000012496dd3c1278b55bde81f6944c4bdb71869f5e5e21db7b1425ea32fa1dbc8c301e7f5e68cd7629c91650265d1361e690000000000000000000000000000000004a1251591efdbdbeda21eb89165ca61a2e090a73426451b6933d939161364c4064a67a90f859a7713fb6a9c5321d5a200000000000000000000000000000000163bcd07d030fd6ab8a8e0bf39b136dcb34f03925c3fdadf55e94a90bfde0ecde5c51d2f4d06954aa6a96c913f2ab4610000000000000000000000000000000016dc065a852ef9e038d93cc583b4a71db9b96a7e7a819dc530598f1ae256368438f52e4b709f15f56279b9c7f9db8785", "Name": "matter_g2_mul_32", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045c00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc45", "Expected": "000000000000000000000000000000000a2397fb3a3891d1703eb2112357c5fb8acb070ba9f3a39050be6f05b49b8d2488e94adfbf849c8b4a42e287077e9fff000000000000000000000000000000000cf2c02a97addbc1584091e411f9a07135f1fcf989dfc8ae29155ac90b214ce20dc11a1fc75dfb697694891d934abf0f0000000000000000000000000000000018fd4af647bf0456aff9ef80969613829f8eb837205df552aadca46bc3bf9838e0ff2515d3fe869f80d78e2357091d8b0000000000000000000000000000000003c5671ea4723498359f29d49ebe974099da3dd59d21065a721f7a4f14dc7fb1de3a67a707bfa4bad7058312632c6113", "Name": "matter_g2_mul_33", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820f661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b", "Expected": "0000000000000000000000000000000000676bd7ce63d8b58cc1e5399ced9b495baba4cef9503c44760f92d6d9e092d6d5308fa88144491eda6c571a8c308786000000000000000000000000000000000605cebb4c20bc9dff0258f75a825f55f23a32cd0804dce56bf3cf2f19a3504f0345e0f1b839d4d5920aab19b363ae19000000000000000000000000000000001512f95f60a6dc79dd9261c321328ab8e22ff314e7582d8de83aa3bf280805cba8ba6d359a620fa6f0564396a45ca9760000000000000000000000000000000005837474ba78e0700c77141d70af1d8fb95a97cbadc95996faa93c2e81b7c8877d08d5287f83219a24bc0080e630e39a", "Name": "matter_g2_mul_34", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe2346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca", "Expected": "0000000000000000000000000000000010b2a9b32e431c11ceb474942bbbd6915a3cff64a74d67570fadeb7447c5abcf1bb35c822d4441565322ebf75e61f64c000000000000000000000000000000000b75a0212232af0a59440482a1f953cc29bcd35272ef407925eccd70c1dc4705dc1e97d2da604996d3c52155d05d77500000000000000000000000000000000018751bc59f5907cbd7f1d503bc5aa266f4109fd3133a1c4c2e58e4a17250a40053b4489da4825b4c368b0f4947baa6240000000000000000000000000000000019b41fa1af9488596b09c587fc33e044d51674eb6087c647d5a762d85e38a587eb5482687d9346a1a701bd3a8bd36a61", "Name": "matter_g2_mul_35", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a8448639a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc", "Expected": "00000000000000000000000000000000054836eb7ef9edbe914bc16d1498e0bc3c978bbed2518802c2f8e1c0b59fee482cce0ae8e805c33861d4cd595f6b8bf40000000000000000000000000000000007dda36d55aa7a890aeaecf2528a390c98d9ecfc8a5c78c2a6def30de55b90ae408ab770cf9a9a4663ba601c4f5765a00000000000000000000000000000000007ff7b24c8ed9fca572069e72b1e93978cea87a0fac7ba60f54aa573d881f21b73012b010e9c0fc9324aa7697bae0c4a0000000000000000000000000000000002d9773bf294efe64021e755e4dd2936a5060bbea5688b6369ffa3b94eadcc58cc3986c74ff365301be1e6c785939b69", "Name": "matter_g2_mul_36", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e372c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447", "Expected": "000000000000000000000000000000000902c1082ff09bf93b91c9ef5e447bd6832fec9297cdb065f11fc5ee626e6e8834cb5d74775c586609a0394e6114e8820000000000000000000000000000000018e414a40c27430b98246fef556e74dd3dd7adc601e3c05b79f8c29169780a173be9a725df3318d71b6e82abf97930bd000000000000000000000000000000000f924fa88f43c86ec98b34379b9a649c7564ef0dc596c95df19522fd50fb3a37cae031e891a7a7aa6a5e6a9062c3726a0000000000000000000000000000000006bd3340412f64d02d0cb3ac44d1f31cdb1906e56dbfb66d86b60a74cd26c1e241963fcd8bba4109c428db0bb083e81f", "Name": "matter_g2_mul_37", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d4828", "Expected": "0000000000000000000000000000000001415fbd8afeeb5796460a9095f14a8f3f6fe0374d4cc4160f030710a6d4d3a92febcf4dad770de3a3ba1a2efbd858210000000000000000000000000000000015792220c7e53262b56224d230a8a4b32019c77548704ec16da5ce167854305e6cdb9924c248f222d6fe95a8383af7890000000000000000000000000000000001694329d8e0f41256b703a8bb6548f1d9e0749a55c124c9b60361b4cb1daee24fcf272327ba598022a92815764fc8570000000000000000000000000000000003350658842c5b6fc5561a14df27d950a00c5bcc13d6d9d014bfd6dc95ec1a030594625f41d439b90b05275a0ffefdb1", "Name": "matter_g2_mul_38", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb3d4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a", "Expected": "00000000000000000000000000000000054c6cb26c8b0a9a4700e0b95348e6fb1190c577eba03a44e84fe7744c543321d02c4d8f55c03f984b44ffbd899ac53a000000000000000000000000000000000e7ab8da5d573cb88a78f6a6ad2b307bf867777f79a643b6ec89d9cb208711c85d7d2cf8f8ac69a8b322000fc7866024000000000000000000000000000000000fbc5926b9dcd9e4d1ca1a2b43dab5c98aa20b37aff0868c54441de44eb014e5283010642717fafaa95000f4313e14840000000000000000000000000000000003671ee05bc20bead72f2306203dad55cf20b13d3bb2cca079bf4391411b85ed4df55e1426645d73b6935889d4450c58", "Name": "matter_g2_mul_39", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05541776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb", "Expected": "0000000000000000000000000000000013fdd394635f42a926a2324b8cb870b5995772ef4e25ebc1da41dc5bf724f747da8d95a28dd703b5ed65ada5555c8b5b00000000000000000000000000000000118fd550962d1de8f1e60c312643ec7cd306f0bbcc932739270595537c8d290ca7e20b962fcde570bd2ed7ea43009fe70000000000000000000000000000000018b25fef4b75fc7649a489d078311dfb6da9909f472de7bd9bee9c3ee353f345c83119269ab797fabdbede41e0fe6169000000000000000000000000000000000b7c2a73741f6944ef4ce8fa20b2900612645c224818b7faccf6597827fa07f7262295f42be5f34a751a6400495f7eaf", "Name": "matter_g2_mul_40", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c425", "Expected": "00000000000000000000000000000000177d29de8a81db2e515d4241e5f7e3d35de22bbcf9aaa616b057cbf2dab57ab8d98213cdec82a2034964f3e1def8a4e3000000000000000000000000000000000a0cce8113eecb064a60ee2c470dfae8b3921f8da2c7ad8dc918b355ff44542b007add28a44848fa8d8f8671617431ff0000000000000000000000000000000010470fcc723286327e951e758fd0474de394778d0c1ec5fe6f263dea1957c60f05dc8f9d82b3c6a7d73b3e783f35ade500000000000000000000000000000000098a6ed331f03da7ccc9148f07b19b132152e15d9fdaee5cc092524b33795edf2b458b4e8383c5e29affd3f025094033", "Name": "matter_g2_mul_41", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbce7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96", "Expected": "0000000000000000000000000000000018a1f1a60172a65abc8f2d855ee7510c1e0af9bada084325027bd493ae86ea2c62c15ace7f63562a82cb80ee7095661b000000000000000000000000000000001736b977fb52eb1b466cec3d42df7e89047784f0e8362eb6425e37adb1e84d0438f5a6e82c7b31d59b0959a5f4aaf9310000000000000000000000000000000013ea0f849830f8e48161e840295637d8596b32eb576560289620b797b14bd395d835e8140b69039c904ef1d07a82127b000000000000000000000000000000000d7f58873701c138cb7e18ffc36cd0e47b07d70448ddd9fdc4b947003fb29cba0775916c752d531e527ab744c277e5da", "Name": "matter_g2_mul_42", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6eac26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc", "Expected": "000000000000000000000000000000000290fb3f38937ce4439ceaa21cf3b31db8a22f9f5ad9db0fd7d38ca978192bc05d41152f8f86ca7b2ee0bb58e125f57f000000000000000000000000000000001775913fc24699bf08f25fb946fc6527178ebb821c654b7bc69f6f86b5168fc42057a5d3bfdc53b3d57fa1ac05f7a0930000000000000000000000000000000017b9043cde8dbf500ad90463250a49f56b35713f2fd9a35d8391fc36c78c083e39674592a98cb857194ef9e73a62a397000000000000000000000000000000000e5e62e39433d443e7d2d32754d2ca2556cf6deea45e5076ac040e3d6de14e9965c53f8c65bd98ae7d17ad3a26f3accb", "Name": "matter_g2_mul_43", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710bebba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca", "Expected": "000000000000000000000000000000000d9927347a9ac9b0290e68143fbc6a5f4476604c3fa5ae87e729a03ca055e4c6543f9245a4592e195180d88781e46ac900000000000000000000000000000000175e0ee8de4002b18f32f70f1bfa9e0be87288cddf1c436428c2969884112bef5db19e041cbaeb23596e25cabea3777300000000000000000000000000000000074ed9e981818102b9ba818d478ba27033eb38e3fa19cdeb9f5820e59a64dc451342a160359c54bc8ec7d866b62080ef000000000000000000000000000000000a853930020bf01e20816d3aed242e00792b0d0e78fb15403fc3cc255f0dbd99ea6ae1d59d5978e562be4862b3317324", "Name": "matter_g2_mul_44", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be1705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a", "Expected": "000000000000000000000000000000000e9c290ba8a22f7bb3f7dfdcc9f5a221a5ce838d4fa85a00473a4dd830bacf583dd91a6a6f78d2ebb54a4c1bb217f793000000000000000000000000000000000dc51b0ae8bda6d28c51016764fc028258171d7c7646393228692aef7f1dda4a83e53553f63d6ba996d4c0a802bc967f0000000000000000000000000000000014ab155029dd35206811be9ca4efbf762a1673367e6b57528f79eb50008ce7c3b49a2d25da0ae68ac4030ab4bcc0daba0000000000000000000000000000000008cd743bb52e7908aa973c8518eaded75fc2858f4edb25fb7f2e09900f0abd3ac87e93cf1068bbe0c7d99619aa7a6b76", "Name": "matter_g2_mul_45", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da90f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa4", "Expected": "000000000000000000000000000000001746a449993b0684740630f3f0e46eddfa135371e33e8de4dfe553c78845399e63bb3da48798b35df48d27e1f991954400000000000000000000000000000000057e0fb1113968858981c9803166d8b3eacc91bfad320ea0e610fbc5b276da1b46d74fcc54183ba61d1b2fe6743097c90000000000000000000000000000000000b3a178ae3b739cae3e80f3f44db42d8c465a5cfe4943b449d4c3b7f4ad153916c6cf4fdfece14a00b271222c72764300000000000000000000000000000000041c8b293ded0c647f2e4d6f9b35304179b723c3e6e421a5cb103e561d1655b92e74877ce22c99f22a3700c3aba9ebb9", "Name": "matter_g2_mul_46", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", "Expected": "000000000000000000000000000000001103cc395acf81772955bda38f951a81c5a6a476c0b5e1543616a5a7a7be22dd487ab2a8586524891300adec5225b4020000000000000000000000000000000003479a08e2811ae9aab0301d66ada470935984d7466201f3fb28c610c0b5f67e7305f5ad3514cec5f30b51d0aae775d40000000000000000000000000000000005ea37a6d20c1ad0978da68ded3a5bfcc5ad8fe81e39b525fe7d1f2b2b1ab0be7ada80173b1d0b7fe1e06ab6354e64b10000000000000000000000000000000008f2093151a285dac511df1755e99a652a1cad0af3a019650fbdead1421ba8e84afc9eb0a4fea651f365d72f031a0ca6", "Name": "matter_g2_mul_47", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac7", "Expected": "0000000000000000000000000000000019f79677ea0e011e5c9a892a407646798b05be05337c73135cb771abf101f450bbffd08e125f077f5ea989decc009b9f000000000000000000000000000000000ed15f35966024cf1de2926108151e976dcb0d51b2736b0877d79de81f6fccb9dd299d14855f4e257cae33ab7455b95100000000000000000000000000000000125e2fabb5cc95c0a7890e9ff2b70102a97a03f2d11d915cf4332dd049a467333e12ebb27955c0310ebdfe2afb3173ee0000000000000000000000000000000011718167000f9b749f1615610a30023db4b986364da5bbdc4506c726624a073548a94307b282590cd8a43b4900a1afb2", "Name": "matter_g2_mul_48", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28b473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602", "Expected": "0000000000000000000000000000000005af8fd9e79568b46fc42b2c1bac62d115365834e509dab032f66425b7a571a4bd3bf702299d3c5f36c372750b3281f30000000000000000000000000000000018499089f306b3c9f7a645ca2f9aabc4e57c046992fff87e832e21e21875c6adaca050ea8bd7043afec3a36ecf8eafae0000000000000000000000000000000000827fa0f46134e2dff80088129841f0469ec7360fd8b9864e9ed99c5fd3458e6360661ab4c671846681d491b8b823d200000000000000000000000000000000120f829e8d0ffc360a14eabaf52bc653b1e90a36c0a8af806ca745fa306a9739e31435039a377e0748caf5e80c2b0b09", "Name": "matter_g2_mul_49", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c013", "Expected": "000000000000000000000000000000001745500b00e5ebc6f71c779ba0b0f8d6601a065c550ca19de9562455423d2ccb507e659b0dce982faa841267fb1a27d90000000000000000000000000000000009c36b54f12d130868ff9b9b61b714fb1067dc91637c09614c51b5aafa2cbe3ca7dce0f3e366d4200cbf603ad4fd630000000000000000000000000000000000172e543708bb853712d81c000c9f9f2378e628b4d13b074317e95deeae98e11e7f917f91e02a0b18cfe9b25f1b83f16700000000000000000000000000000000189fc572ff6a8c6606ba0cea7da7040898d9ee85a58f12fade8c5a22031ff26c2f9cc612bc6e1b82a0999fa93c6fdfca", "Name": "matter_g2_mul_50", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52da9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc8", "Expected": "00000000000000000000000000000000013c6f777df97ad3ddab9b7486d54d1bacb3b40ad3035b47a25a66c02e8866955e27a8ee52872c8222ff7466c1310bad0000000000000000000000000000000014a5eb510d7c743e824f4daab21c43db4d6de8ab2e825d13ae0e186aaba828d7b4a2343a11011a8ec4ea82f456e394a70000000000000000000000000000000017a55d3827b78a9c5ea792b705eba7777df74951930791b17ff5b861e98a4488f83007c073c3e904ed4ee328b6f6171c0000000000000000000000000000000019bae02f8d6f1e31dfa09f4feedd5217ade66f6e8248aa98b273574f72aef83d5048534ed38acab9e0eb4c64f4389af4", "Name": "matter_g2_mul_51", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d7618f228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b", "Expected": "0000000000000000000000000000000006490c327790b4c451f93197d7db24211a3b4b5f573a6df409206b4bbfc36bd10d2d0c989889efffd8f4daa4a68b211c00000000000000000000000000000000168f224738db3f07af77494f52ea5e957812a1acd62615f0eaa95c1d363cfceff29be9cf3be5329bb41175a0231ced4f000000000000000000000000000000000321f06b55f7dbfd4900b329c914f9ab9be2794e51e54498e18f83ece5bfd205131fbc254bfbf624d57ec2954b05f6f00000000000000000000000000000000018ec54f3e09bb2a6b112b575f9481bf1c85666133051e9c0ab53369d14eb90e27d2ed02dcda1250d5d539df0d0cda37c", "Name": "matter_g2_mul_52", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e699431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb511244", "Expected": "0000000000000000000000000000000001641b4ad10da5089164809d82ae47f74e27eaebffc2a2ca3c1b924fc69c1ea80ba3da78c78e86957f6a24e7f75dcada0000000000000000000000000000000014e781e4fe79ea1654460f4b0daddaffb29b287efd8168cb20d7ac6c729f684c5f2a7cfa87885accee3a797febc904c200000000000000000000000000000000001c9a44547f0c5b1f4df190285644c5a31df61e3de7da085835ebda917d5e4163f2deea9a83d641a4759fa3108567ad0000000000000000000000000000000014c3d2a79d80687fd6e6aa423257644fa5d0cf641aaf6a7c5675a810767904166fabd9a2ced0727e3badb932e46fd181", "Name": "matter_g2_mul_53", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df12051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d83", "Expected": "00000000000000000000000000000000129554de7de9a2b73340d94d96f0356a2d1c0524cfb007d76a75f462872e831f45553de05f5b6a1f9eeae37af7f6b4c9000000000000000000000000000000000b1ea2a649ca13a3dc7882f2423036670f68aa05792a8fcd72524420e37381a9ca80dfea701fa5e6da57afa534059617000000000000000000000000000000000b7ff27aba408f9759b5109600cff66c03cdb4bfb3dff64a4838d0516fa46bfcf429fcf9d5cbf74a27f70fdccdb1238c0000000000000000000000000000000005a99aec88967fe775c691d443e2dbd45080eec97e686ee6d7b32e801efe6563315bfafd5c7622d0543519cae4417029", "Name": "matter_g2_mul_54", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0fb96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f852", "Expected": "0000000000000000000000000000000007997a499b2194cab634750a189cca6783ff17d866d66f5998603f8639d2242e8039222c65b0d14001167a9b09afb58a0000000000000000000000000000000015050fe6b335884a225efcfea4acd025cfc05e8f5fe9a0e22a0c91b55664c118d79887de91f1ae6cbc081f6f55f0067000000000000000000000000000000000195b23c4c2c087082c30600ff00485d169dbd360643d163f1db363f270cd7d4f177c36b4c291d50da4101e67b229d0de000000000000000000000000000000000df596ba2350ff7d3e75b4cbe5f8d6b2cc0e14b3bd6dc021936e3371ba64031f6266fb1d2951801309f22bfb1c4b27e4", "Name": "matter_g2_mul_55", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a3378176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c", "Expected": "0000000000000000000000000000000001fa243b548f8f5c2e5d7736ca6fa95b74dbfd31f95fd532b94f81a255c73e7c0e000e20f9ca6750cb0dfdcd2c1aea8a00000000000000000000000000000000132a893a2326bf61962e1855331a53667e6279ed7358bc84c4a7c218b6cff1d3f449954f56daea72bc2779c60f1113400000000000000000000000000000000000091dd23c75dd8266f556bf27ba54c95c3ccab06168e4e6d0747239722afb20f3db27454c6db3a88daab0ef10659a66000000000000000000000000000000000d3b2e3fd358aa3dae983e87b5d1fce6d5688e66ced6e3a2c96b8d48041557295d5932af6532c13965d4b383fb252518", "Name": "matter_g2_mul_56", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a69c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da0", "Expected": "0000000000000000000000000000000005095d1becff61df906815842112c6508d6cade4ef5f4b7418f5f01e8c5a383addc1c572237613dfbbb88bcff80e4a44000000000000000000000000000000000bd2561e7bfbda8a48ee038855e37b03fee805689452e9afaf0da4185e0c194e407ce7149b713c689d25f953da36dd1f0000000000000000000000000000000015ba3ae4d4238175425ac5dcbd9e6e9e055b8c1b7752931b524fb546f7bee8723ef2e69351450c6d1ba3c366a22355e20000000000000000000000000000000008c17d77dcfda00a1d75ea0087c58e74263ce5ce4066e979c66397de8e236708831c3a9ca6b35ade8038a28930655eb6", "Name": "matter_g2_mul_57", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f2542ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd45", "Expected": "0000000000000000000000000000000005cabaf39b93d7fe15ef6a7a3031df58219bce702a5a77162551a3d916c22e8ec9af2aa20659e7c4ce5f6382a5f82726000000000000000000000000000000000dcefe1a48d8c239164b54771118f7520ac11a7a6b72d8e17be1cd788cad2f26d3a0d9113e6536426800a744be9f0d4000000000000000000000000000000000199d95a44a4334c87aed273a0184be9602ba443d5b8d34f3495b04e927f4687fb88487f586395c7babb4f218fdbecf8c0000000000000000000000000000000010972032f9cb3e8f45447bdd06df82656fbd3ce38a9f7564c6e5d62ea3596c9b7e0a94046f1c65bf0452ca25b15a885c", "Name": "matter_g2_mul_58", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c56fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f", "Expected": "000000000000000000000000000000000f250b5e47ef616be106a3334e2f516061eec8f7ac69f08f6dfaedecd76fb1c9685ecdac2c3ddd534e3947d007ab177000000000000000000000000000000000073819a6de38303725aa3a9e5a7a9122b4d1e60ee8deb3554b5e06ef5e60d71517c2279c5066af003b32cdf83b7fcdf200000000000000000000000000000000070721107ac6dac198f7ed1a7f84697cbbc3199a220d1aaf82e6f015963bad863f99190f18a482f730254cef753ba22d00000000000000000000000000000000169910eb30b8fe1ad8f84c4a132c6c74a6ff06ed6e792af3baa6619e3c8aa6cc3e6f687299467ec9554f9e91bee77aa8", "Name": "matter_g2_mul_59", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87318a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d", "Expected": "00000000000000000000000000000000106e892e336b2155909946ab73b980ea761cfe8c48b13ae8a5302eacea08b9cef3e60d5b33c6ec4033218ae5761433dd0000000000000000000000000000000015daeaee59f3b4cc26d3da745661e74db8fe1ea115d50ba49ef5e6151a9ac2f3135f0232235cac7a53e1e8a70eaf0476000000000000000000000000000000000ff494d17c735b934c2c7fb8f413103188fdb116fa8f4d4e43262968ab0fa1bdec23b0d4d8b1c2defe624092de36610d0000000000000000000000000000000008f70b7e9f2d7083774fbce3bff58a1c73fbcbcd9cb049cba71c0c3f0c363517c8956240bcacdfb7934d4c67b1bfdd2b", "Name": "matter_g2_mul_60", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab7196d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a", "Expected": "00000000000000000000000000000000098f32b35e3b7dc1862ca1ca3c76d009f016c6b91c227f2cebe8f1fe87567d936bf1c54103bec31b3552c077c0242fb40000000000000000000000000000000005380a66d48d348487624a15b63d2ecf6976b5b599901101ea8b1f57736649b4397f6679ecab0ae29573695a921ac475000000000000000000000000000000001710c368f70a2b9cc92ec65c4c2ca35fd63440eb350f488e7c6646f9c42bf680eb62a887d533a91e47988221b46c868200000000000000000000000000000000033c3327da938dbe4630dbe16838229d7d427f3adf18dee6fa26b1c8067838922c1bce78cce08d590ee1acf2baebc7df", "Name": "matter_g2_mul_61", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f2dbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad997", "Expected": "000000000000000000000000000000000404587c60a4bbd8b5b929ca2ec2a9ff2ba4733f4f2877478a669b238d65ca130cba398899f2910d6de04615f8ffc99f000000000000000000000000000000000940659b3e6de7c3d8de9169a28e68dad433bda78de0991fe4a1d404e5f4babcba9d57c7f3d638aef264642f87c61fc8000000000000000000000000000000001676ce240e1ff70ab03f94f3ba3acd31725ec306ce1fd707e29ec22cf91746216dd998d03ba13a79dedf878fae38d68e00000000000000000000000000000000098a81422511f77191ee15d402614c86f9447ab78a89cc348414108f36857a1929f2b92ced78752ab3604f276861803e", "Name": "matter_g2_mul_62", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", "Expected": "0000000000000000000000000000000010a4ba6952d22a51dbb6762a3f9bd09712c2be5a98bf0ef298d7a7e3a9735ab0d3bf39e40b334895c73a36c218ad24b50000000000000000000000000000000002860f38ef61b497bdaf4faeee7b406007981c17246cfa36cee906452ae85e1c1c6385898ebadc3b4ef8887fff25b8240000000000000000000000000000000002dbbca9034fb17c3f37727d44c027cdf47c36f3f628ea9385fc9fc371d23f22d983656caafbf1cd1f8bdeff4ad7669d000000000000000000000000000000000b7e71b65765c4113a7884771952268a9fe10576f745038912e6877c78372cd261220793b888c43accba1646e902fe14", "Name": "matter_g2_mul_63", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d", "Expected": "000000000000000000000000000000000e9c1a6d591be4da37fd6dc283b8d899b625ccc96371dd3d7731aca66cd2a978810497171f2aeded64fa2b10e480de2100000000000000000000000000000000006d2ad7287847255002480627782d513eaf1f68a3d583d4762fc156b8eb40deae6969fa8a7d8f8aae923800091386a00000000000000000000000000000000003c7eae0eda08df9b9eee2605a44fbb486e3bf2e409aaa1c8f38c06f969ff1f74338004b01288dce99be26a837e45d3a00000000000000000000000000000000178174d2f569a9392eddd2715ceba8762c5bcc6325217db5e5f970d6fde069d0e48a824e5b6ca017891de175c92f6b29", "Name": "matter_g2_mul_64", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e3616", "Expected": "000000000000000000000000000000000ce12c9010b4c4afbddb459c1b46063a8488277948188b4ec0b739e1cebb5653681d0e43a0d2c6b3f842bfc609bbdee3000000000000000000000000000000001123f60cedddaf4385e63758d64d4facdc443854176ec199ca0df0a9c258517f2512594f2441a4b9a68aa9a2b4a1f4bb0000000000000000000000000000000007cc6f77d181d13bd9736ee23a33b25b0bd969760642ee19004e095ebb8e2b3c0e09321eb15a2f7961803c0fb10b6ffd00000000000000000000000000000000004d8dbf2f0c14b07ebed2b9cb4bc87df78ac8a34ef0b05cbc2c6fb8e8156415399fa52dfb968ef0e6ec697030fb003c", "Name": "matter_g2_mul_65", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad3a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af", "Expected": "00000000000000000000000000000000172805bc715a8cfb2e25c384214f4005aa6d3b809a0ad95322209851ef92151526a9d01a914c4d7f0c120b9bf3837010000000000000000000000000000000000473ceaa092a5ac12f38b4065477672deacc08e553d8e9e6391bac0d9ca50015934cdbc340deb05aca916cf50c7915b30000000000000000000000000000000012e85461fbd26c2d0235acf5c8665750656819bb939e8fae77a8d526ca23443aee395a985cdd4b1eb700311fb87e91a7000000000000000000000000000000000246d45fdd88448c93bedf4799becfc7c80e67abd483f2a0aa41e8bbb3f38cbc900314436364f1db6e1d88595544517a", "Name": "matter_g2_mul_66", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0845111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d145", "Expected": "00000000000000000000000000000000122e1f2081cbde0055fc34d2fe61307bc333b35a1e0772a0cd6fb25338c89824bcf2f066bc7b571b2fb314ca7f45106c00000000000000000000000000000000027ed81b54372d858a6ba2faa65fdc132efbca6ddcd56c3625bd9267cf0ae04f6d342209b995060f584be8d40020669500000000000000000000000000000000002a03427a093a3000a1bed9eba91a82dc2f2fcea1a16a1fb8af29c4988b589abe6a505ec87a82864b3c683beaa6420f00000000000000000000000000000000134bf64871d69a72e42766c2903fb4589b84d7772a62f7d2f8f8d02a914f4d3a278c680c626ef4d69de8aa88b57589a7", "Name": "matter_g2_mul_67", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e109c07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a", "Expected": "0000000000000000000000000000000018fa44efeabbd1cc47dd9b1a1195ca921c99c77ed43a44502aad27b6c663f5ce2623382c3ddf208f42e3eea741281f4300000000000000000000000000000000138d11e497e3c5656bc8fc0ae4322a0bfb6fc20e249a47a103b164aa3d9fdbf7df4b1e3b0842b4b12568a31992a151f000000000000000000000000000000000182490d6ae35c1208c0d608984df4988d057f3ce5a25073c77cd5b224a5892768badb1ad5cef8f41d1d2022573098c320000000000000000000000000000000002a6e0523781ccdebb75063dc7ad1a9526f9ff8ea1364bae487914f254c0eebcbb2cfc3715fecb9599bfc2f5feaa62d2", "Name": "matter_g2_mul_68", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c29b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd0", "Expected": "000000000000000000000000000000000dc7488491433d5b3924105c01ffed4f30b755d7253d867fda595e7d80197823e56e4d182d5ecc72d8ef1ba9bca15a310000000000000000000000000000000007bfeeadd6fc468ef6340a2b394c155bf50808cb11e89adb0de5499fbdde91760e9531c1deb23050286a15e5910f1d5a000000000000000000000000000000000f096db706b08485fd577f37b7bd232b5a10c3f80c25bcf82f7a3b666c6efaac8e856bfe5f7dafb7457e33eadcb4133d0000000000000000000000000000000004460d1f25159ce6df59efbd7c693355af4634dadeaee2ced68124b2a887698c10e9c4b40c4f4f9c8444acb881ceff65", "Name": "matter_g2_mul_69", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b2263d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf54258", "Expected": "000000000000000000000000000000000f1aa4a7a22c568c41270d24824138bf9ffc763a5356b7c0bc1d051a0a0db12616700d9214972b63eeb2a398d27dc83f00000000000000000000000000000000020d0c2ff8f93db6b415c2a01712034e46bdeb6e665a5177a3877db9f5401d3dccb99907ef843062e394c1428983725a00000000000000000000000000000000088abeb6fc3ead45d5b261b7d684f168ca8f5f163cf338863e6b102dc40e2cd0ede97c47460ad6f560c27e95c8b71ca8000000000000000000000000000000000ca2e5cec212d581c737928512118e2f51a0d74070f40a998b7b06d22b9fc754bb2fa5499308058be9ab81521d057414", "Name": "matter_g2_mul_70", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c67a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e", "Expected": "000000000000000000000000000000000cfa23c46881893f6c50d238a83669deb520a7fffab4f912f77df7cca43f6827a1a0ae0b3f36c8f116ecefa33b8bf37a0000000000000000000000000000000014b7e5c18d2f9bfe15b0c1af3bc6e230039a341e135837d123e91cde9cbcda298c66b93f692232c912e5d7d3d6331c430000000000000000000000000000000009c8984999ecd3a4144ccb925d3e5cae5c1662dfbf8871013b1cb2946482fcb075c489c61b8d6261f2574b44da3fc1ce00000000000000000000000000000000196e7feab383211e4825cf98219c63bf9f45a72d66030219cb585d5d25237a01a97f00e122db6a51325022e69e7d8cdb", "Name": "matter_g2_mul_71", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a81b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83", "Expected": "00000000000000000000000000000000005c0282830934ea09c9f51b52cb6dee75b874b155c63076dbac2cbbf220863d55557ff1b7d681fa185435df1522f49d000000000000000000000000000000000a1680ebbb185c8e7d8a197a523a7a5e618f97c46670622034d312b3eeef140150e03b00ae3dff8d9f1d872f3d3dca380000000000000000000000000000000019bd2eb4bc25f5aa6bce206f0683dbbbbb002098a118fcfb060c1353a310c2baa1063a782bafcf6ff6bb8edaf6f1597a00000000000000000000000000000000082edf49a0435e0b9f3dc7f207711d66004ae688b18f5b62fd1596899ee8edfaac7da38973d81f12200018fbe8151572", "Name": "matter_g2_mul_72", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db1ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de07", "Expected": "000000000000000000000000000000000b8a715c1c2792a30f7ad752a808b621c34af1fb7f1e3392a36ca9481a019108a21e3ef338a1d05f2f23ac3e2cc42ed500000000000000000000000000000000101375c9de592031c55a7a62189fd3fa3c565abf7c64724796dca3b1c7a6e6834a16ef1c4e2afd6ce2e69487260f0028000000000000000000000000000000000cd385ec8245431d3b1aff88453db7f66a5d7888a5c1e0dd0abe9ac7db752933a343b8be53b7bfffb704768ef0a3dc5c0000000000000000000000000000000015d55c8cddb8715e25fa260d1e1fa672ff76eca7c80d19d00678fb9d08759b810cf266ef0a7e9dd749a576ce07240fa7", "Name": "matter_g2_mul_73", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b6", "Expected": "000000000000000000000000000000001311de31229f1825d0bd2c9d726fd71e05828a20406a4705ea65f441537486338022bac4e552bf3c25e15717bee00ba400000000000000000000000000000000052e082cbe36c854a028a041981fed87d39fb218a88208aa1096e260a3932a1155db7f306c32d133070b0a5bb6d161760000000000000000000000000000000003269d4afd20002873f4305018a4432c1925eea28486d657cb458198ff2df9d304bdfc7455233243b1712d8663591d460000000000000000000000000000000013376fb98929cbe7f7d090d1c9d5c4f6332bbf25470aa03c35a70481931e4bc91c937029a5e11d2a3418eab698361227", "Name": "matter_g2_mul_74", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296feac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c79659", "Expected": "00000000000000000000000000000000021166263d1a443d5b2eee9aeca3678ae4c2b44d556a7cb9631d47e4fa3bb05ecb94d6582f4ca0cd787027fb5f2efab60000000000000000000000000000000015335d034d1a0ce78e1246a16e35e0075f73d4a392da1e05c11388084cf80bf31d499e57c48f4be6e72d3abc7b387ec6000000000000000000000000000000000deac4ae1900a4e1814624fb4b8c7a3149fa9cff2ca97f02e7d6765e034a1532a7b8475ef7aef5ebb851063cf4b9e79500000000000000000000000000000000161e3af03f226278a07ff3b08e5788f6c5029b2c8293e7a7e3ae11c4d78676b60dc0208cec6b82e1714d976007fbb389", "Name": "matter_g2_mul_75", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb5198586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d", "Expected": "00000000000000000000000000000000120b4434babedbd8ff295a6e2ed5fc7af0548d7e60663110050be797584c0cb638988201ae7707cbedf0c8b3dc5ced85000000000000000000000000000000000d2de0a260bdd241a145e3f68a6de48da4c65107a500e02bfeae6ae7dc428026c7c3e9bdda9a3069d2744705df2eda9b0000000000000000000000000000000018a237906c0e277541c4f00c4c2feba7cb2c9b87709c18b62b7c36d78fc118cfd65c127765e01dc0ae5875b9552bb45300000000000000000000000000000000197485daf54e98e097b6bca24b0738682969256decbf3ebc05f6982e4608829f37e2877937b3f26b88efc3deeb4bfacb", "Name": "matter_g2_mul_76", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d6e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712", "Expected": "0000000000000000000000000000000005de82540aa67c69b962d292133b09e6593961da8944ce02557141abd19ac471f766b4083db85c67a44b65dad2202488000000000000000000000000000000000cd999bf3cb004074fe9f355cd8dfaa7b9d3439d902fddd2fd0688419b5b7f8c4300ab26b658936a90c0b8e1488249d1000000000000000000000000000000000f97ae779429a5afaf7a3343586eea84a4e76f00a1852ce42a4940babd565bc8d61bf72fca9b123922f1ccfb1db8c06b000000000000000000000000000000000935960fa941c27e74234a07857ee680f53c31047235c6152d1669724bdef37ba642cf4e0dd355443ea470e6430def8d", "Name": "matter_g2_mul_77", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94685cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a72", "Expected": "0000000000000000000000000000000001b0aba02b0e907c03d2f4003083c824ce60f2f55f70dc6ec7c7f81f3d0ef4bf533b4c94833e36e8aa7aeec18b7255de0000000000000000000000000000000004fc227a6ae303f3006f75193cef7c653e6bddd28fdb843b41c7d39966a701ba8fcf611efa71abf059d7d98833480e69000000000000000000000000000000001077fddd0bf3d5c80eec653916f9095e900cf165315d74a872219285f62b5412536e43c4cdbc120ec5c7753318852dfe000000000000000000000000000000000ccd90e01c1d4a00f0d9e29a88e8134f2cf68162da66bd343645a998730190114a6921c9b048dda58b60b42a133287f2", "Name": "matter_g2_mul_78", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", "Expected": "00000000000000000000000000000000185520023714580a3f235e24316478b8260565ffabd39670811519066844e131e337bd62ed2069bc6d2305e6638e539700000000000000000000000000000000055fc74cc7cd3fc393d5b5ab2419414effb783ff4da2516e5465a4acc195339c7b5238be4e0744b3d7fdbce46ca7f5dd0000000000000000000000000000000005f584a0311c02d611c15163529130a2fb3dc853083e7225b791ce5ff32d5ef7039c80edfff317ce9ddeef84443b5a51000000000000000000000000000000000f9d5acb355f767cc6286cc09f6df232532f9a0e9e4ed1fe28788abecb200e22066c23f3ac6c49c47071cbb023e70183", "Name": "matter_g2_mul_79", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d7535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b", "Expected": "000000000000000000000000000000000ceb56d75f3aa1548c50d7780ea1e33c3d069b2f37e7f96be6a8ec03266fa8d0868822afb3b2e54750722266f6032a8000000000000000000000000000000000080f15b7f9f2c22f1afacf558267b5b84f3a6d199fd3349eefa2e46c4f332849c0955d19d4513151dc0f3b566c0058440000000000000000000000000000000013305f8ff6080f7da05c28155c0c2bc1c78d855cdcff0bb2c6b82cd5107d7a070d0830e6705f6832ed5baf75a659c8870000000000000000000000000000000018f4e136859b4ceb230450f9abde0325a4d59db98279d7fbab710305ff53250dae1c8789cccc27586c9b9df5c0c4722e", "Name": "matter_g2_mul_80", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d52756e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a4035", "Expected": "0000000000000000000000000000000002a0214be95f020c70221fb4fb6856af7ce3845a4b607340f85127b52f8a204efcd94a152835860a4ddeef84946671b1000000000000000000000000000000001767777740a9922a91c39a36e2cdfcd544df902b31812ffc88418dab7321f73406ab142055b5bb264c187f2d4f2d6f9d00000000000000000000000000000000026e6941364c74997506df0f9fbe6b2769839e8b7c7293f4e63d13bd7bee90ff779cf82adc2f23c569d1e13826cdb0e4000000000000000000000000000000001618ab2ffd4b823b9c9776baf849641240109b7a4c4e9269f3df69a06f85a777cb4463b456023b7001adac93243c26f5", "Name": "matter_g2_mul_81", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae4523a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff", "Expected": "00000000000000000000000000000000054ce66b9b0b3cff6637d6cfdd788719d4e33516b98402d8fba54725309307711fb576299ba99104d4e7df0deac9ea2500000000000000000000000000000000055e06ff52cda9116a98ad3709f788d39db53844b7db58a57af52848ce1c59ec2a1f083efe79c5994b9291a2d1020fb900000000000000000000000000000000040c9ad63698ec78d06b41bdd6f5eed089b67f106348f9300f822a2d61ea1e5d2ddda0efd1025825c99cb0e243573f7700000000000000000000000000000000195dd00c48186f8d1337ca857aea02c4d199d638133e9cbd2dfc5f633502f656343746ec2a416465c3c0d4e9d53fd097", "Name": "matter_g2_mul_82", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627cbd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b", "Expected": "000000000000000000000000000000001141b59af8fe6cafdf2e247fcb0ee4642a9b4022b6d71163ec9b6ac2f7d10ee3c5c0173ac686b03cd6a7086b039ec786000000000000000000000000000000000f05ba6973c5d865ac5c037583b65eb4eac826b5a04a7ebed1e10bec6ec7dca93b1c2eba70ee0189fd552d5023f2a87c0000000000000000000000000000000002e54475940985ad2115223c5ea3a4c95890f3e9992e3e1a6df2170ab77143bcc5d29b9dcd1ed3bf16e545e9be21a8640000000000000000000000000000000019acc4705955761518cea482b83e3726dea8d1f66a5f19b06cd7ff95828e15d1b139077e0d274b0e6fb86c027844d97f", "Name": "matter_g2_mul_83", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ada300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d", "Expected": "0000000000000000000000000000000016fb5839fde95111742255b33f040c41dbd0f142d1daa8abc7c63008ba9f63f07381d9d6128240ae9b6cac5befad84e5000000000000000000000000000000000389a11727c356b8f3bdb6a73bc2f6d2d73d33d287365283359521dcac64f17810bd58c0ec5bef4db253bf630bdd9599000000000000000000000000000000000629a8af1bd0c1b1b6d7e447bb779663d7bae8e895e09418bc350e644d7022fa877496f30e2018f5dd1c9683b2715adf000000000000000000000000000000001950185d2574fe0c8277e3f93f59dc5628ec3487911ba9c3194a2f716116ff0bb9a39dde802dcfaa61633ad7657a578f", "Name": "matter_g2_mul_84", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa833e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b33", "Expected": "000000000000000000000000000000000024c03edb9b54034eacca4b321d51397348c57f406b074b16a9d6215e03f842380f5358f5c095fcf5bf3cabcbabdc260000000000000000000000000000000014e62dc442135d729f65090475fb408ebae132cdf2c2932582af887ed54696f3cd15b163f11285b99e8d8f809aa2e65d000000000000000000000000000000000438a2c99df216c67d92b99d9ee8cbd0e9751e538074d146767bde9675ae3a05bdae051efcdc6bbddeb1b7a8288370ed0000000000000000000000000000000007c462a8f5720e442e1917bf75fc3c3dafab6c39c80d0b93d81d1db4080f6e199be092b4b025e7b02efce4f30d00299a", "Name": "matter_g2_mul_85", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bfc48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f", "Expected": "000000000000000000000000000000000e8137c15436264b5960c27d0c22be7fc5d56a12f43b3832ad0d7f5abddbaaccefd140e2f7c476b99e6fd9b3a52743600000000000000000000000000000000019ee3caa56f0329a2e2acb8907b3edb21f4eee73e312352796b51282e097f9b10af61805d5c222332888737c7f8e227d0000000000000000000000000000000012cb9c610391940fed7882a5cba08eba4226c36eca8a2ed22fb5e752e0a1a5ec556673e47013258b499268f1de77bdf100000000000000000000000000000000031b769f606fa25b81a982db86a1cd442ed738019e7e64728ecf485cddcc17d9dc271146196178740b9f05f56627b061", "Name": "matter_g2_mul_86", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e844228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c", "Expected": "00000000000000000000000000000000080807a0570b628549629d2eeee39de773badaccefb76e01efaecb0ef0356f535d32c3947f0613bc7d847ef8c8778f02000000000000000000000000000000000e8c091ea30465d204ace72015cbef29645206390fd92ba7c4aa0fecae4ecee53c0b06e1fece99511efd8c7e9cff1a8c000000000000000000000000000000000c881c678c94d80164bb3295acf4341fe6c726ca64a1a015c890450e719b85720f41f80369f99ad3e7e3169ede0113e00000000000000000000000000000000008a2fe01a7100afda40091eb0b2b14cd00b7a4d8bb5cf9d9a3847970a94f2035fec7f292c04c38d7e49890e612830aeb", "Name": "matter_g2_mul_87", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbea417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f1", "Expected": "000000000000000000000000000000000d17f6d9460566d0543df2666d6ade685565e668521a87fabc58148343085415fee92c32907311c9d04713c34bf7690d00000000000000000000000000000000185da28f07b86885031ff5cda913a85b0e4d07673f456ecf2a9f0fd1b21d99e22442f9b705039252d57380b6a42912050000000000000000000000000000000014a4bde5973ef43691b61b3c0f6c2fdb4bcd6ea88e53e2787a7d93ad6e05ee2e69f2799712520f72b3c577ee278008ec000000000000000000000000000000000d92a565b3d8d0fded054a75198b31c521e3223650cdf762fbf7b851f7ac0fc66b8c86c20b905117585704c23b27e7db", "Name": "matter_g2_mul_88", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba846561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb", "Expected": "0000000000000000000000000000000008b1ebd753364a5a0a6296ab48b348f91668525c0d5f7edc4f2d29844592f34a209f9e77f94ebb38ba76bdb3f96063ec000000000000000000000000000000001062e0ff0a67372207052e2520d8b2823764a5075c94011afd6c60288e187ec77e08db01c95dfa195f2409b58c9dc4e5000000000000000000000000000000000cc2b87b613d97a716586f371c457fa869c2b8d1fa1cf4b9e8c34bae23e0544752b997df4711d0712ec11d3a9d96ac2600000000000000000000000000000000140eae891c87c2026f0b1293df2bd8ae2dcb0ab3f8de74676f37c905334ac1f53fe4b75511691dcf108fca51abcd524c", "Name": "matter_g2_mul_89", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591ccf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf", "Expected": "000000000000000000000000000000000276a138edecfc9378be4e241d64cbb48bfa6fd4fb1788f8bda870d5ec8b2132fc9ec888ef84c43a50b7de0527def36800000000000000000000000000000000153e90d52c747859f88223555bc8bc4e8b6fc846fe7028de728a4dfa085c6e350f9f1d12b9dca4ca8e07377648544400000000000000000000000000000000000cef00e7217da6df0a6d85f40be69f154300c423e86e54e513b2491e65002e308445238082da69aa9e5e83b5f4fc17dd0000000000000000000000000000000008da1da2a0d1da9d2158b9408dd9b0eaf414d237b8219fa7661e40c1a88eac2f9735d0dd6ad67b85aab85952369e8287", "Name": "matter_g2_mul_90", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff2f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5", "Expected": "000000000000000000000000000000001484993096c210c7bebbc4c0bda24b44a70e982b2528215c0e8578ea55f1181472758caf935aa0a3d6820cdad753e2f90000000000000000000000000000000011802324a6e03c3174bbe7261ecf3812c1a97e1be27269214f232274a3bf82775d47c5fdd70fe1c57155068b296d394200000000000000000000000000000000050f43c874c1cfb5fda81059cb7b4808492632fa20369dcfb611e503ded81a49dacff253e31d7e27ee84bab79e3c5d53000000000000000000000000000000000ef945b6f210fb09bf0ad5bbd4b5a6630f43304ddcb396807c967eb5146741f7432bfdcbd7e5f3d29917781efb62e6ff", "Name": "matter_g2_mul_91", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5440ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e", "Expected": "00000000000000000000000000000000028233bf12e8dbd8510f119be30ea1fc13b755c6ee3ca2a3637a3bf8f73776c9d1fe231b713396ffc579ef9320a05b150000000000000000000000000000000018e7c00b8047d64ca0c5df54486439c5fb3d1414c2f71cf8a3ed591b7c45bf18b37473daeeadcb625eda638885ddb9870000000000000000000000000000000018b89c9b6bf9ece36f1eac08fc35ffc9f7f964a0a9b19d495ae1361fb4bc98aef8770efb47d9961aff694b878d659818000000000000000000000000000000000eb2fda2c29c6761e35ca4c9772bb232ea0d297582af4f50ef76c0b74fefd414b535e356c069f54ef5224225e95be6e7", "Name": "matter_g2_mul_92", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a7ae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be5", "Expected": "000000000000000000000000000000001239935827fb2a269ab064a3ae2bff2555f89bb3a71a47ae815ef755fc1363a89d20326855cfdd0e13f6c85f727bbe120000000000000000000000000000000012fbba047478b5f5b07a582200271a0c331d6f76864f9b6c6ef8ae6b0965eda481eddaf72c7a887b21719164c633d39600000000000000000000000000000000017eb4353b413437244983554a639a9253d105395ff9652504df7700d879cd9a32d5f0824b1eaa532bcf2fea34f8f08800000000000000000000000000000000054ea45475c01ea0557fd143b21c7bdcab6d287bf6bf4f88b6fb06e02ac6fc5ba96f323bb1fda3a1c4d8f42d01d267b2", "Name": "matter_g2_mul_93", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa21268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c0", "Expected": "0000000000000000000000000000000015a145e379b7ecf4566a039b753f91e8ad75d9e9c9a20725ce34a900eb9a1bdf66cabee2100208d7792a963d1fb8c02f0000000000000000000000000000000007f0ca14fc4e34bbdf5008d632dd112c7368e037ce019b7c4ec412000ac02302c85ae64f9ab495361fa5b620e46420aa0000000000000000000000000000000017c00a08bba18426dda40e773d79733030b5b3b199a62436ed06b773fd1f10688e8af00e8a223cdf242bd1ebbedbf634000000000000000000000000000000000a17365cd9f7655793682b72e342227048da0cff88f6ace33ddab548ba126017e4b7f7439373a893e3b5803e662814b8", "Name": "matter_g2_mul_94", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99df9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", "Expected": "000000000000000000000000000000000081b4dc78b74250a82da9d803876add659411cfb467860b2ac6f0f68929d6377deb71d6acc9ea8fc8c1286b8f92056e0000000000000000000000000000000002c5fde71346a255ee9dc896f654eb2e0c66f4cb4c51541d2bbccf2463ecf0085a22b9d2bdc5bef39d80c4477824f116000000000000000000000000000000000ebda0cd8bf6ac7e86a1bdbe44ed1e15f8ffa1fff92afd67fb564306882f35037b61cf0d93f278f15149c04a2e83041f000000000000000000000000000000000fc38aa811f5ec015f10a99bf175f1479d4983c9d2180a5e3da88b4e9b62ef50560ff0a6c2fb7bda4c46c54551f8390e", "Name": "matter_g2_mul_95", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b4", "Expected": "0000000000000000000000000000000007b46fcfb2cd8efe32754306ff2f503d7434168c1c3cbd7c80470cc5a5c8bda10a80bfc0129da349724d2d6431c5ac90000000000000000000000000000000000e1078f4f4ca993d90accbfc036219507bd22d00930ffcfe1227780c00914fcff845698b2541510daf59cc83d8b947e7000000000000000000000000000000000b7c6d9951570e685d3a71b19a38f5485f974f85fe8cd4b4c196d33a18750b278b6d374483d81dc3e15c9b8b9b5dfdd6000000000000000000000000000000001003a239ea4a2f213f0f646bdb62cbe4f98cfaf7298d8b2e0eaa07bf3f939e779caab5ffa0033467c5b297166df657d7", "Name": "matter_g2_mul_96", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e74d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e125", "Expected": "0000000000000000000000000000000000ea29b1e059560fec21c3692d4e632a45c88a807c953fa23dbedb271b049d7fc717333b498ed12573a896f872e795dc000000000000000000000000000000000de0d10c47df92010a6635e3403dd6e91a1bf35bfcae82c1008998e86aa2d18a6cfd3f2f1207fde3bb39b723ec4d3ca60000000000000000000000000000000005e2aef9cd37430b15e5e76b2c7870630d255f630c12e865caefe308a39833e00319406746dbb2af3ed32135e91eed49000000000000000000000000000000000c229fad41b0d27ad7b5db33188fa70b97f22e323e429ef65fcf98f5339e908c31df8859b863356e0fc90538c5c49cf2", "Name": "matter_g2_mul_97", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d553041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b", "Expected": "000000000000000000000000000000000444a00cfd258bd46f659b09eef17be9929008d3d1c65e46cdc762eeaa2f0b52abfd636e6094e21983fad8171194c71a00000000000000000000000000000000090833e68614be5bf298e04e44527480cb35128bbdecae15eb95d6931a718f66869ddb68352130b4dd8a921ab3f26d080000000000000000000000000000000000994015b1b55340c3839d48320d178b2ffaa0bbff038f7aa63d4dff41a217582fae9613bc537fdeac8d0670c0cf479a000000000000000000000000000000000fc486e2a1680c10ca28d4c3bb22dbccc9572036512645bf868e7693ae4591569c973f9ea26342a573e23a06c2fb4b70", "Name": "matter_g2_mul_98", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db47cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf", "Expected": "000000000000000000000000000000001375bd5ee66c330796bd8381a26cefa3f40f8cc8de42d4d59a7adbcd3852e6d632422e6ad9a06a6e497b23b17b1df87500000000000000000000000000000000165d8e7be17ecae9bf51a773da705aea42536d0fa3a2206267da50451f5104ee241811dd0e6710a80c38df77b126c009000000000000000000000000000000001559572407aff34969f83c394d2b095a7ae9f53a8e6c923910f256bb87b6ec076fa6acb85465102fd24d34031f88f7510000000000000000000000000000000015ff9ba89b55ef75f63732dec1e64106d7a912a6657fcc970dd011a03b5364117cca46d6cbafbc0c5049db10fa83fe6d", "Name": "matter_g2_mul_99", - "Gas": 55000, + "Gas": 45000, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/blsG2MultiExp.json b/core/vm/testdata/precompiles/blsG2MultiExp.json index b5b63625ac..24f1c3383d 100644 --- a/core/vm/testdata/precompiles/blsG2MultiExp.json +++ b/core/vm/testdata/precompiles/blsG2MultiExp.json @@ -3,721 +3,1043 @@ "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000011", "Expected": "000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d536944", "Name": "bls_g2multiexp_single", - "Gas": 66000, + "Gas": 54000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000019d5f05b4f134bb37d89a03e87c8b729e6bdc062f3ae0ddc5265b270e40a6a5691f51ff60b764ea760651caf395101840000000000000000000000000000000015532df6a12b7c160a0831ef8321b18feb6ce7997c0718b205873608085be3afeec5b5d5251a0f85f7f5b7271271e0660000000000000000000000000000000004623ac0df1e019d337dc9488c17ef9e214dc33c63f96a90fea288e836dbd85079cb3cec42ae693e9c16af3c3204d86e0000000000000000000000000000000011ba77f71923c1b6a711a48fa4085c4885290079448a4b597030cc84aa14647136513cec6d11c4453ca74e906bbca1e1000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000176a7158b310c9ff1bfc21b81903de99c90440792ebe6d9637652ee34acf53b43c2f31738bbc96d71dcadbbf0e3190af000000000000000000000000000000000a592641967934a97e012f7d6412c4f6ff0f177a1b466b9b49c9deb7498decc80d0c809448aa9fa6fbbb6f537515703000000000000000000000000000000000031d84356ef619e688a10247f122e1aa0d3def3e35f94043f64c634198421487ca96af5f0160384bba92bd5494506c4d000000000000000000000000000000000db8fefe735779489c957785fa8e45d24e086ef0c2aba2e3adba888f0aeee51385a82898524c443f017ee40be635048c0000000000000000000000000000000000000000000000000000000000000034", "Expected": "00000000000000000000000000000000158d8ef3d5cdc8a1b5ce170f6eeadec450ca05952ea7457a638b8ff8b687c047799eb3dd89c2e3c6ca6c29290b64f5ab000000000000000000000000000000000807d135b6b007a101e97f5875e233b41f12bd2ffd77fe1195418a73a4c061248118ea1049aeea44750cd5ec83bcc1ae000000000000000000000000000000000f04136354f45a85a53fb68527bc8fbc7e8c1a0056878012b548a97bfdabcbd3fb8eb3ff187fbe65e1ce233afd2825050000000000000000000000000000000007b15428114e2ea094ba1e64df4c244f80aa2f75bbbf21a407bc84e80bf2a5ad787d02ae8a90cc1c137f0d898edb1684", "Name": "bls_g2multiexp_multiple", - "Gas": 126060, + "Gas": 103140, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3000000000000000000000000000000000000000000000000000000000000205900000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e84900000000000000000000000000000000000000000000000000000000000b7fa3000000000000000000000000000000000e7a30979a8853a077454eb63b8dcee75f106221b262886bb8e01b0abb043368da82f60899cc1412e33e4120195fc55700000000000000000000000000000000070227d3f13684fdb7ce31b8065ba3acb35f7bde6fe2ddfefa359f8b35d08a9ab9537b43e24f4ffb720b5a0bda2a82f2000000000000000000000000000000000701377cb7da22789d032737eabcea2b2eee6bb4634c4365864511a43c2caad50422993ccd3e99636eb8a5f189454b18000000000000000000000000000000000782c14e2c4ee61cbe7be6e462a66b2e3509f42d53ff333efc9bfe9a00307cd2f68b007606446d98a75fb808a405d8b90000000000000000000000000000000000000000000000000000000004165ef1000000000000000000000000000000000411a5de6730ffece671a9f21d65028cc0f1102378de124562cb1ff49db6f004fcd14d683024b0548eff3d1468df26880000000000000000000000000000000000fb837804dba8213329db46608b6c121d973363c1234a86dd183baff112709cf97096c5e9a1a770ee9d7dc641a894d60000000000000000000000000000000019b5e8f5d4a72f2b75811ac084a7f814317360bac52f6aab15eed416b4ef9938e0bdc4865cc2c4d0fd947e7c6925fd1400000000000000000000000000000000093567b4228be17ee62d11a254edd041ee4b953bffb8b8c7f925bd6662b4298bac2822b446f5b5de3b893e1be5aa49860000000000000000000000000000000000000000000000000000000173f3bfab0000000000000000000000000000000019e384121b7d70927c49e6d044fd8517c36bc6ed2813a8956dd64f049869e8a77f7e46930240e6984abe26fa6a89658f0000000000000000000000000000000003f4b4e761936d90fd5f55f99087138a07a69755ad4a46e4dd1c2cfe6d11371e1cc033111a0595e3bba98d0f538db4510000000000000000000000000000000017a31a4fccfb5f768a2157517c77a4f8aaf0dee8f260d96e02e1175a8754d09600923beae02a019afc327b65a2fdbbfc00000000000000000000000000000000088bb5832f4a4a452edda646ebaa2853a54205d56329960b44b2450070734724a74daaa401879bad142132316e9b34010000000000000000000000000000000000000000000000000000008437a521c900000000000000000000000000000000049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c000000000000000000000000000000000d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c80000000000000000000000000000000008b7ae4dbf802c17a6648842922c9467e460a71c88d393ee7af356da123a2f3619e80c3bdcc8e2b1da52f8cd9913ccdd0000000000000000000000000000000005ecf93654b7a1885695aaeeb7caf41b0239dc45e1022be55d37111af2aecef87799638bec572de86a7437898efa702000000000000000000000000000000000000000000000000000002effc7b302730000000000000000000000000000000002142a58bae275564a6d63cb6bd6266ca66bef07a6ab8ca37b9d0ba2d4effbccfd89c169649f7d0e8a3eb006846579ad0000000000000000000000000000000012be651a5fa620340d418834526d37a8c932652345400b4cd9d43c8f41c080f41a6d9558118ebeab9d4268bb73e850e10000000000000000000000000000000015f4b235c209d89ce833f8f296e4cfb748e8abce6990ce1a5a914b9416c08e0d3a26db89625915c821a5f152b7fa592e0000000000000000000000000000000006fcacb3ee6650a1044852d61c9c20bedc8ee90aad97de8e24670a9ef57483e678db11dd95428915088d76e30cb01a370000000000000000000000000000000000000000000000000010b4ebfca1dee100000000000000000000000000000000018405e4b67f957b6465ead9f5afc47832d45643dc3aa03af7314c6cf980fa23dd3bb8db3358693ad06011f6a6b1a5ff000000000000000000000000000000000c48e0d4f9404ae0a7f10774c55a9e838bb09d3bae85b5eaa6b16b0f4dc2354368117f3799c37f3f7126d8b54d3f83930000000000000000000000000000000007e61f4ec5bc9e2cc8ca471ce4ed40e729b1790cd2c0d9c1cb50e615ec7f346636e77e1cf632c881c07c5385898607620000000000000000000000000000000011dfaf9281901dd356fc5dfece21898a93d9ad9e4e246dd6e18d3ee46d58ab7e77401a3e8d04057e5638ed74fb95688100000000000000000000000000000000000000000000000005f04fe2cd8a39fb000000000000000000000000000000001796abe0d9e4a703962be528e6a5cb65c60725886f925db0e2a89107ec248bb39fa332bc63bd91d28ae66e0dfce8f754000000000000000000000000000000000fb665f5a7559cb0fa1300048a0e6f1ab5547226e86f8e752dd13c28eda4168492e3d3bf2f8a6b230dd57f79b1afa9910000000000000000000000000000000003422dbbe4a06a4c6c9fdf35e54f74b4ab1528abb7249e99898e6fd7affebc7aef95bf82d328dc01d63c25f6a735c35d0000000000000000000000000000000010aa5504b469427eb3584a286191149f5c3c5a745f338278dd95337cd2336d3c4e7532d98eb189fa543824953e7c1c170000000000000000000000000000000000000000000000021c6c659f10229c390000000000000000000000000000000009303f04d568e289a35102b6df883d5ed620355c0eb5d02236718cdaf99fba6e19ef5cee2996268eb9a53ae1ee09bce3000000000000000000000000000000000190be857d602284393305bfe0a29e29a6982ed3f04ccaabafb7e59cdc7eda85c22bc3e8690355c7a0fb7590ae40f1b00000000000000000000000000000000016efd497a0c5c6b59a1fdf2b590eb67a7da8cbe72f49084e7050783ff12a783cad1859e1a0b0ec8ff784c703617670330000000000000000000000000000000017a957ea4d53f4fc8412cb015ae91b38445cdb3e7078d875c465c941e0d9a852c78d90b31b6b6010efe8bd5117e831630000000000000000000000000000000000000000000000c01a881f8abc4d8843000000000000000000000000000000000173ed58056bec9874464d3f23c3e7d3d429d6c8a167fc7f39368830eca839d0eb8260d64ca823f6c785c71f85893d8400000000000000000000000000000000123372d7d4c91a249df8f3e4f8e669087b252ab5d8cf2529a87e4ed3622e4158cf17dc44b473d5debd273261383e8a0f0000000000000000000000000000000000c500eb55ab86381a1725f339f686c7e38ce9113493736f57e999badc661b5b8494d220ded0711e841228a389abdb820000000000000000000000000000000010a4025d823c4262367c53f50e67cffa046e4a1e7c69ff30373772e49ecb310de3b313d83cc41f40a00205722f233e270000000000000000000000000000000000000000000044496e633650ef8f6fd100000000000000000000000000000000152110e866f1a6e8c5348f6e005dbd93de671b7d0fbfa04d6614bcdd27a3cb2a70f0deacb3608ba95226268481a0be7c000000000000000000000000000000000bf78a97086750eb166986ed8e428ca1d23ae3bbf8b2ee67451d7dd84445311e8bc8ab558b0bc008199f577195fc39b7000000000000000000000000000000000845be51ad0d708657bfb0da8eec64cd7779c50d90b59a3ac6a2045cad0561d654af9a84dd105cea5409d2adf286b561000000000000000000000000000000000a298f69fd652551e12219252baacab101768fc6651309450e49c7d3bb52b7547f218d12de64961aa7f059025b8e0cb500000000000000000000000000000000000000000018461a3d444ec527fcbf4b000000000000000000000000000000000027513925b419f6c581788578379995290ab9478e08ecd1999d5e1a05c58144d2f9f06fb8c7fd1586f3ef6a973a3ed7000000000000000000000000000000001292b2ce751f6f859ec7882e14083eac9841b035f9d5ed938a81579dbce07dec2c0202b7f6b25226831cd9c578e893d00000000000000000000000000000000017f36da49414d7706209d52840250eea6f33970fd7eac448ee122f24c62f6a6e09757aa29761160be0f65ba3ce7a153a00000000000000000000000000000000086d471f958f3ff679805751b183fb6310e871ba72bbdefd59c58e95ea62de0820d5affe601757e318abaa5a0c2715bd000000000000000000000000000000000000000008a0eb53c748001536d7ffa900000000000000000000000000000000090721a089bbbb130c21a529be0ede9271a91a2dde9cb2a8e091a19fd2c0a40c390ac2bda8304085c2d6e38e520eae44000000000000000000000000000000000cc64109c67b342b6dbcf86cb60fca7ad378ed6398d89076ed108685c57a07d26e40ed3d5c4b3560b21e519db5875d49000000000000000000000000000000000b0ddd488f5a6f61f087cdbf011b50209a4460c8aa8c5f48c0b30d9cf6cf24259f4e7badc42e1b7a33352949ae566fc100000000000000000000000000000000038430e8db04d205d81aa1632d23919c06f89260c7ac5850bd8b780f8388e53db3a3ddfe98cc55d1c686e582f85b0c8900000000000000000000000000000000000000031133a6c7d698078a7ec7e113000000000000000000000000000000001800ecc167bb714100f31e7610cd3fd010ca299b394c01b1a89afd11b051e92989f6336db5e6d3212f6b04673526d83900000000000000000000000000000000070401d9bba01c0445e0a682406b099f21d16d9c348cc97156769084055ca328a145c134b8c8b58f019d62882b2965de000000000000000000000000000000000287f071bda99b0318e386b27a492a6823a9664084b12acddeda34cb53f827a362ba97c0e652c37bd9d6023041d8c8d8000000000000000000000000000000000fa708ca7dd917541cd02281e525d3367b5ebf5e9353103e1f83f3b894d03d8be7e4d819c123492788855d1fdb63f2e000000000000000000000000000000000000001171d5c4909480aae3b110d01c1000000000000000000000000000000000ef786ebdcda12e142a32f091307f2fedf52f6c36beb278b0007a03ad81bf9fee3710a04928e43e541d02c9be44722e8000000000000000000000000000000000d05ceb0be53d2624a796a7a033aec59d9463c18d672c451ec4f2e679daef882cab7d8dd88789065156a1340ca9d426500000000000000000000000000000000118ed350274bc45e63eaaa4b8ddf119b3bf38418b5b9748597edfc456d9bc3e864ec7283426e840fd29fa84e7d89c934000000000000000000000000000000001594b866a28946b6d444bf0481558812769ea3222f5dfc961ca33e78e0ea62ee8ba63fd1ece9cc3e315abfa96d53694400000000000000000000000000000000000063376fcdf64c9bcbeeff0f9f9f9b0000000000000000000000000000000004b6570b4a6affe97649b0dd7a0ad0df160b37c332a8a7348dd3994cc6b1eb65623b4a9f0a3f320e7278844e261546530000000000000000000000000000000005f8fb4cf5e5313f403f15c59c79b9cebaec78291f2053c49d6427f40f2db2aa659d3a8fed7c7b07b7a5680c7b95ab5800000000000000000000000000000000045cba5ec3fa9acd1b11e1f28a01ebc028f89f96f814513453c553f58785baca8abd4150f334b405fabb925b71f4f4dd0000000000000000000000000000000013daf00b8f53af776c2e8c08d55d164aa15027611188e294230477dc1c926102088f0451222fd2eff9802db8b884ab9c00000000000000000000000000000000002344b4be368d3b617df4aa8dbdbc190000000000000000000000000000000002b29192945df0a74eed138e431962f1d39978202d247335ffbf29d8a02e982c69e96b58d7d92528baf5c422ed633f1f000000000000000000000000000000000d52c7a82fece99279de7a49439c0ff8463a637cc6003320275d69549442c95184fd75ee5e7122e5575af7432e5159290000000000000000000000000000000006ddbaad6cc16c9e62b0da9ab0196dffe92253fcfb2df9aa2076d3f16b3284997d6558cc4432d2aa1705452c4e951e6e00000000000000000000000000000000175f906a99c9d65c4647807879e5eb781532db184d28a326ef9691f8738af067b6a80147bd69327d219fad7c850a7545000000000000000000000000000000000c896c3f9d64341ba7c5f8a06271dce3000000000000000000000000000000000c86c92c9598dde7e6fc5e05d70a34c7a14cff5f400f33cf6cc26e6bf6d9a0bbc421c00f3360721f51974d76be43bd38000000000000000000000000000000001137d93502ef32471f47890a181d7823b3a86dbfcadcc930ae53952f528d617e742a52e4f243c615cc28163dc31bd80600000000000000000000000000000000088f7f8bcbc6dfcc8005b8308cd4780d574d8530e95e7831e52eb2c9a88b846852e111a8389e3d3a67accf78b08326d200000000000000000000000000000000149e43fc675dd3bde8b89cfeb29456f130bbf674cea0266bd1b2e7de23f9a7294096327b452728411ca58acc949777fa0000000000000000000000000000000474d97a9cf29e85d4a35f6102fe7984b100000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f00000000000000000000000000000195894e95ca3e59929612e77c1075322aeb00000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000009027ceef3ee429d71b58b84919d9a8d5418900000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab1600000000000000000000000000333e268f0b5b1adf76b88981fc305f03ce4bb30000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000123717b4d909628d6f3398e134a531c65a54e8a10000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000679956d49265608468757580db6b8b1821c2eb13b", "Expected": "000000000000000000000000000000000728c5e6e69b9103d82358cb6ba3a45a677df1c3eb3cdccf694fd71cee94f1e591b8021b0eef638cd9a1d878937b5b2d000000000000000000000000000000000ba9bcf9ccef956f2af8dc4c3fbf1cc8f3f284b04ae8710af6ef4fb36301254c777d4461858fb38fdeeb72c0d8589af5000000000000000000000000000000000224b80a57d30bce4c752664f3b5b5e3443aefa6d4e95dc334821f754b8b8d8fda4e73d03cbd4070d43b18324a686b500000000000000000000000000000000016909a02214c6c0f6682895aa99cf6cf0a22eab6f0b574437ef9c36e9df32ac3b8c5adb9f6b8827df0ccf51b16f824df", "Name": "bls_g2multiexp_larger", - "Gas": 409750, + "Gas": 335250, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746", "Expected": "00000000000000000000000000000000083ad744b34f6393bc983222b004657494232c5d9fbc978d76e2377a28a34c4528da5d91cbc0977dc953397a6d21eca20000000000000000000000000000000015aec6526e151cf5b8403353517dfb9a162087a698b71f32b266d3c5c936a83975d5567c25b3a5994042ec1379c8e526000000000000000000000000000000000e3647185d1a20efad19f975729908840dc33909a583600f7915025f906aef9c022fd34e618170b11178aaa824ae36b300000000000000000000000000000000159576d1d53f6cd12c39d651697e11798321f17cd287118d7ebeabf68281bc03109ee103ee8ef2ef93c71dd1dcbaf1e0", "Name": "matter_g2_multiexp_0", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca807f80a5e502f63375d672379584e11e41d58d2ed58f3e5c3f67d9ea1138493cf00000000000000000000000000000000135aee0e30fbcad798738c10d4aebcdf50c89ce516325f655fe763dce54ffedf94dd74168611e5ae879b5bf5598d62dc000000000000000000000000000000000c728e672cd8b3bf9341bca929c34118b566cd3a80452d7015bee9d5cdc001b1f5c678d4b2cc4f7cac353e7bf326ca1e0000000000000000000000000000000014809aa22e2051e463fba6d49fbb060d0c7f599a0fc5409d34e71f34817e7beb1251810ae6eee1848c60796fb8647dea00000000000000000000000000000000145a4de777d86025d50e12f9a6615ecb9bdd41489992d1b643dd9aa549acbc63b04b0bdfd14b6e45c70f165e9a8c91bebb169138f94093d5c1c6b253cc001ce8baf78858dae053173fa812d2d1c800da00000000000000000000000000000000009a58b7116dbd6f550f8ca98071813130ecaa9ea86d5275eebc36860690fa048c9ebeb46600b2b63e847bff3e38ed0d00000000000000000000000000000000113ffc0932c041e0e34b2540c485eb74f5029b339cb60bc88a8a749310f33f330dea137e5f340044fd689264af66696d0000000000000000000000000000000002642da3c2c7b6688aba0b19ab29ac72e35caafa044863c364ea8833fca850289de52c0963bc33d7bba40cb5f568718a000000000000000000000000000000000552d35ca054da2f148c119454f6760607b351f2441921a2be17da2cc10902d71571c5554f132e60df79679428fa07e3e40608bdaf3e7764358a64a920cbb33ab4d571c7b3092e1ae11d9697f82ed8330000000000000000000000000000000018fbbcba3d4b1e548ceaec4a48db62a2420ff29a67af332ee7ea3f902f84e6c375fd33abc33d945c5bca25603979f9a400000000000000000000000000000000072ff416994364bdc6535f36c82212afa822cd94fade69f11eb38dbdcd37c7e22af55fe05e6a826dad822073656eaac10000000000000000000000000000000017bba179b847278a4878b6faeaab3b1f4bd7540d22817cd9aff95557497f8b9d286657b6162c0f89f7820becc637dd550000000000000000000000000000000018e2bfed71aa9b11fefca2f0db8bd9b8c69540267de50bec4fc90a6e9741891465c9761d19282e1100b3707eeb598b31d411519f2a33b07f65e7d721950e0f0d5161c71a402810e46817627a17c56c0f0000000000000000000000000000000019efd37727dfaedf697fcda7a59847dbda8ca7cdc92f34e68691d682e20ae6545ac104d6660fdb8f64a051e69298eae8000000000000000000000000000000001225ace0fdce456dd888c9672503b68ef77b2d11caf1265a767a6ea14911e3ca03fc153f18dfe9d95e0cc68b7b8a3a8d0000000000000000000000000000000008a6b059c1c4da046cc0b1b5d7f33270aceffa607daf6d0d078c06f940604e1a0b4adf01a4091306e3c7eddcf3d95101000000000000000000000000000000000f79bae5260a2f114ffbb9273f3049d3ebb002500a57ee0a7d157d86957f43f87a2e026fb9892dacaadca5ee04fc8e176bb3f9e512311699f110a5e6ae57e0a7d2caaa8f94e41ca71e4af069a93d08cc0000000000000000000000000000000016d2b73eeceee17d3bff3aacac9df9ac1c4248d9ea7d6a503a757f7bb22fa6970bb6f5cb5ec154785f7252e1508b382e00000000000000000000000000000000081edc68bbd8db7b10be06ee23d090bd54f9ca07ef24dfed7df7bb05f8cc26e6889dbd40ea203fd5cca5cb588199f9e40000000000000000000000000000000010d3478508619ea9493b4330e2fb9150024cd32dc1378f824788a884a4a30fbf39c630f465557bf0c6d69b4cbecf89f9000000000000000000000000000000000f20c9b134db5d8b7756800c031bf5962fc560ba95d4bd9157b16179f1a37ae08696a2be455ad8d018aead6adcc69b712a0c988d97e86dccaeb8bd4e27f9e30fad5d5742202cdde17d800642db633c520000000000000000000000000000000003dce67181d23af9729e9fb0653d7f79c890fba27de42fada93123e112c4a468fa889921192db8047d86e4db77c60266000000000000000000000000000000000869a1e39d42d9bb0cc0568fdad16abbdac3194af893ebd8dd8f8c2c3c855abefa5fc215412168acadc88e658e83f5570000000000000000000000000000000001ef139a75194f3c4b1378c2b66dd304d179460bac0a289405cd8faa3ff66a7b6e54eb7b8742a68150b1e098630135c40000000000000000000000000000000003892b5a645af916be2c6c7fc0bb08fb5f39341d3c68598940554e1be11e1be75af920db0c8710ed13c78edbf683f17d0b299c14892e0519b0accfa17e1a758c8aae54794fb61549f1396395c967e1b1000000000000000000000000000000000264dd4b477f5db65edad28c7153ed919a863c5c5661e0125c5429b323e055fd69c33142dfc6ed9c87082e2be4675e1f00000000000000000000000000000000046ea088a2ec94d3a1f1f97949f1ebc49690c453d316cc46534fa253b34b30323b6071d147d64bb94e02fb4db07bb0c400000000000000000000000000000000013692a33bb1348486eec40a9e93a4ea3810c7b4d3188cd07e235a2c898aa87ee0d17682fd24f4d978f9fb028fd26e2900000000000000000000000000000000115f8b64c00cd5cd344a7b5edc0ef0bb85a3e8f0f9dfb28f8ffe12db3e0d222c2d45dcdba0fbdc161c5d558bc71aa0977064d43d6802ad4c3794705065f870263fef19b81604839c9dea8648388094e900000000000000000000000000000000014c83d58d90db4821a0411fab45f83fbc05f7d0d7a67ce75da3ae568978d15f4c1886c6fa6086675c0045efb30d818400000000000000000000000000000000001e68691123451f4c3df6dae62c6a63855ec3597aae33a8a10ee274e902e9aab1460cc9c79726312df0ee0ce90c8d3c00000000000000000000000000000000018a39eb3e3c6c7fb8ee304e55d15e209afe2fe278dda93552a7b9f51fbd778da1502eb6775cbc3f832f8320fa0686240000000000000000000000000000000017c15910fad1ca5749aa82a5a2fa98b0ebb37e92912547fb1741f18c34e0d5fc3a307b928636c25f0320d71cb9d31062686285a0e22f177fe3adbfc435e9c1786752dcf3c11b723539789b0cdeb0647b000000000000000000000000000000000fa96d9fe01c18732e8d6454df9bb1f482c4b9add837ce9c354c72d49c2d44ec694674aaf0e6d6a095cab7ebb57ccd9a0000000000000000000000000000000001f8ffe3fb7e9e311e0f6949c07c26a0febb181e37b2268bb5e125fc3a100323740d1ebaa5e635dba3770fdc2ce4ee860000000000000000000000000000000012ac42095fdb677720ab3f14bf0afc55c95b43d28d922a5f8cb0bd841306b978751d24546e3a6474976961d0768f29e9000000000000000000000000000000000baf9804d99039c9fe966a696c64bdacc9673b0906b4deab108d34fbbaa3b0905d50892278570564017b96828c7e1ac93176b6724cf984632daf95c869d56838ab2baef94be3a4bd15df2dd8e49a90a60000000000000000000000000000000014ce6d88a7c5c782562aa101550f1af487296adebd9dae8252698ba04fbd58b92e2216de6ffd474d5992f97d9f22800d000000000000000000000000000000000ce92a04f5c8a99ca0e93992448222519fc454bda5d1d8638a7bfde968386e4ba0dcd1da59cd81d4c4dca3e584be0275000000000000000000000000000000000cb570796f5c8f7b8aa02e76cb8e870d3365fe4dce5df07ec286a0a821f922b4003d5b69c0f1588206d9544013e268c400000000000000000000000000000000098056a033d9cdae86aac02de3a444471854b909680719154b44d4f55f30087294e39e57643c692d6da725b859239080d76db3dcb659eaf6c086be6b414a494dea4bd30aef8450ae639f473148c05b36000000000000000000000000000000001214aacb0a5e6b7a40369a83c07fa8cf1786ce7cbde2b5a501d9c1292532df7822d4fde10a31fc0cecce3a7cfe3311850000000000000000000000000000000004f9669d8fe4f884ae93b2505710e6e45b19b7aa5df8cdd811f09e547efc27d21024cba05e2dc9d057055f30ec72d9df000000000000000000000000000000000a852b821b31cd27eca19712a636aa05ef2cd82c36ac1c2ca240edc7d0172b42a72c42d3cba583a5b5129ac1c9486e270000000000000000000000000000000007bd8419e791a5cea04993509e91a980d3ae4987a5b322400b6e4a4f2b636891a1c7ba4de96b53426dd556532403d5a39915646de2449b3cb78d142b6018f3da7a16769722ec2c7185aedafe2699a8bc0000000000000000000000000000000005ef88bf38b2f998dec7302cde829076e6cf69df23aa0bf6bbb39fc0d3d8b5eafba74efb928b1de0eeb3d86ec82612300000000000000000000000000000000011f47e9583997b19c36616e4bf78d6ddd6d67937f493986250ff02aef6e6e7ff074559af2f20a5bf1d67158e4a199cdb000000000000000000000000000000000007777c8eb259a836e6459b7bdb642f878d869fdcb31b105d01f280938ef5377f2775874c099dcd394abe70f17d595b000000000000000000000000000000001607379d1cd34e2d0ed765a339b21433e9aa489609b92414c6b5a05d796085269c288d739717def9db3502e0550860165061073223f066e35242772385c67aaefb3f7ea7df244d73369db1ea0b208792000000000000000000000000000000000d6e3068c082b68312141aa68f1540ea1415e93e7f1762b6f06ff408a9995542da1c727a13355c19f8f418a44de1a95d000000000000000000000000000000000dcfcf2ab12b1a0e521ab402aaa4d32ff649a5a97892eb6ad98487c3c73c35601c313b8130ad12e9098d16eed3bcc2e00000000000000000000000000000000013777b1eefa4af03dc44e4e054eb7a3a980a9c55644900b80346be84b970e1754d1f4ab771adc9249e4accf88a23fb400000000000000000000000000000000002f53b231f1209c6f8b52f99a78bc2147c951ac89b341495f4a60a6572985ce2bc823625099ec214bc9ceedb2deea3fff396ee22209271ea0bda10fb5e2584e7536e8bb1d00a0dd7b852b0aa653cd86c00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2f0d3d4cf46265fc0f69e093181f8b02114e492485696c671b648450c4fcd97aa000000000000000000000000000000000047f92d6306bed1cb840f58fd57b5b71a5df7f86dbfa55a36636cb495e08715cd57f2f3e7cd99a1efc28b1d684de1cb0000000000000000000000000000000000f4eb02d687a1a6105b4dbd740e2c7924689d558e6cbfee768dd303cc8dd0fd887f5eec24b54feccf00f473ca3f54ad000000000000000000000000000000000edad68c4d536912816cf6ef039c3dd0535dc52189583270b3b038e2c67b213d943bf384ce69c4a9dc526d7ef309f25a0000000000000000000000000000000006ff4a6b5129ef026d1d5704bf7fc0b474de92b5cf39722f165e73f4e7612d6d3bb40743e4b7b42d0dad5d5d6a2d4881915b717562844d59623bc582f1a95fc678cf0d39af32560c6c06e3a74023c89c", "Expected": "000000000000000000000000000000000153da66acafe91b6f13cd739ed3342197310e4824e7aef2e3414654c2678b8d09b296c3f928f3cc489893420031ab800000000000000000000000000000000010f501a96b86343a7c8d8c1250577cc9be6ffec81b5175ed07bd14988c5bbf7f2f3e7111df7d941d0cd267ea191d6ac70000000000000000000000000000000015e0d88894f7f83aacb6710f6c03ae60db8844dd3beec160fdb1df746b1f38a5e23def0893a0b39bee47c97af6535fcb000000000000000000000000000000000bcc275115e87f2f88c4afe8bf4faed46e6ad0c0357884356a26120591ba283f06b464c4853217865b1d2301965f2bd4", "Name": "matter_g2_multiexp_1", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b32e613cb38b41dcdf3c8bb9187d731546977fbffd79fa7f66e3d6aaf9e1af6eca2fcdc260c8f90818d7148ba2f4960000000000000000000000000000000007e4d26606a47c874c20e8480a9f5815e5b577bccd783b775d10309eeb3d2102c7a0abc3324679e44362f09e7a4ada67000000000000000000000000000000000cb6f12ac8b49cfa36b957591293c87b21af0a949c55a28a90ab0fce88fb5cb7645e20ab2edd284f0ad1377dd95ac10e0000000000000000000000000000000014c96b5dcbd3150eeaea5c2bc27750cf88b30a91933a3233a4d1d9b357a80cc20d135e43a344e718dff5c79045c31f86d5c1c9fa11c36b86430cbb1f3ec10ebbe3787d0f5641d6d7fb96c810eda202dd0000000000000000000000000000000001ca1141ba9542c56de8991b313c6ae42fcecb6751b0b81b8cb21ed70d5008f7ffe831766b89880a7fa6dfdb09a2cda3000000000000000000000000000000000e6766b17db165bba564ac63ab88d3f8f5eded07a40b48644e60d3223d30458e7dabe404cab8d6f9fe135712ef0b1a43000000000000000000000000000000000dda3e6c87382fa762510e5cac721fd2b654f002f5b9a3767a8c6d651ccc582e80e3f68d6913cda30f9f51ebcfc7c98600000000000000000000000000000000059a7dac5bb6b504f2bd603d486700fe22c14f25254537b2c9079c2b45d36c7ce56854c5699cc7649b533194f51a9045c00eb20fe7c292f3ad820a074d8b3d8d24506612752d8677c2d6ca24f556cc4500000000000000000000000000000000090f4b85961ce97cf7f99c342d3627105d790f611e19721a43d8a0febd67ae393d77a02b999108efb56f0397dac22703000000000000000000000000000000001112f23595d1613c47486eadc37f9b1ac3b3c3973b3fe964d3b67c3996fe2eacd9df5c287b0cea8e9475d146fabcf9e70000000000000000000000000000000018f46f7ba3c9af34c1025c2d460f0be966e68944928dbd55cc7fe00e5def598d80b0e3801e48a74963c974ab4727a52100000000000000000000000000000000096845338d5cd2ac44e097607d6a1a05c241eda1941991ae9edbba965d9029032c46da7218b5b2338e6c58898bc4a820f661d7b30fb11bef70e15b257d7073885468a380862202b2d705a84827644b5b000000000000000000000000000000000aafe45ea7cb8b450a51263eebc28c1ded662972bee512e24fddaf64f43b74b66032523b3b104a4e9f6b62394436c6710000000000000000000000000000000015cb27e1fedfba2d1679f78a388f90b22bbf3e7d090f0ba972fa8e72f6e31c446f628fff929953712ef6e425d16eba5c000000000000000000000000000000000df9931893cae713042bf722db6ce394b6f346587278a154c271d8511e690417eb6dc47efbcebb7c2fb9e77f1de9fde800000000000000000000000000000000106ffa395ef170c99bb5742428ae88fa4fd7a94476985c099e3b700b7403d083281fb71a19640c6bc2321e27bcb33fe2346ce87c847376c8967cc18297e6007dcfacb6424e1d273930f38bb0e88fc5ca0000000000000000000000000000000010b1f8b1c492a56936da905b8738affba6bd29ae5fffd40ba6b31325181d3b489a81b23dcb69f6e71bd29bfb388e5a8f00000000000000000000000000000000116a115303b4774da59844e457844232d088062d920db67b2a8450a194be7e5340ebd4d106454fd9a03c8f50dbb1e119000000000000000000000000000000000eb521edd61b38006cffc43ab72d395d669dec196846fa4d6d43521da6c2fc3bf0994ce7556a3cffec7751b3bc5703ff00000000000000000000000000000000073cea36eccaa1c78deefb6029903c2b6598301bdefa9759719c3b590fcc5a6a4d3d4d19f552b33f4a3126a6e6a8448639a142c443a666499a880aa1cb9f523411bbc8e5554de099ab485b6c2c2e57cc000000000000000000000000000000000e3925fa085db73c1e67b29ae90f8773f83be5ec684402e8e2360ffee8a8368911e584843e42b0d470de78591df6ea6300000000000000000000000000000000075c7efdeeb16609b4a47ea442af4d75238fb7534fd96cb236a7886809d6adc2b62c8ff72bdb041bc51c1a71b68219e300000000000000000000000000000000088b4eb0dd185e51b737d797334590e982b7b0a5f109fc7d0524b2465c2c0457964eba5a6d2d4d99fb628f21f15a776c000000000000000000000000000000000fc79f6b38f3356972669290eeadcd992a22bc1191606b663a1e148aa58db3938f0fc65e536bc5811c50d9c7f03d3e372c01b7795c2d16b5bbbb1e107be36cc91b25130888956b0cdd344de9b4659447000000000000000000000000000000000b87c47605fc060a8e3677e84ce9d14b9309360a13c80d040c625fbf0108f829300cc1fca409a0f9c96311cd4a9a21e60000000000000000000000000000000014c4088f1e7935cf6a1d2475b84497ce6a250ee2c0c991fe51a2f2836388a354824b02d9cf215328dfce3f546713e21100000000000000000000000000000000120e59be3ecf35674eac6cdc559599b273f13f28a529770fa156f8e519734c451eefb35023639f32049cd19ea0d945a3000000000000000000000000000000000f97755b62a8cb8f861ea02c77819f0b58181aecf612d92180ba9b475f0b4888b922c57f6a1c619dd5514620a1cfd9e2c712943d8795a6104f024b9701c70b09cdee9494755bbab0576e2c7f7c9d48280000000000000000000000000000000005860cfb6be6720118623d2d8ba05e686df22744b948421dd3cc1b1691e00d9b5d00d00195b4acf7a7b043f764f3f1c70000000000000000000000000000000012632a3313dd611e8d969bddd556c2d79ff387603462ac78ded3a842981697bdac34ee6f1f4744ed2ff16100874ac24000000000000000000000000000000000112b94c317586e343acadeca611c485c3ea172bc10dd39158c1e678007130062a921b53826d7be6286963ff822f1066c00000000000000000000000000000000040de8c0dadd2a6c2a7ea0fa43e1a5f2f5a6be3fcb0de6875d8cef1ee2daad87125d12f6869c4dd3d931b296f1df2fb3d4d77f6246c57d398c57848db8d3f986c475a41a23d424cd3cc2b362c1b99f2a0000000000000000000000000000000006fcd2c4fe848e9462ba1112baad39031c210952adbdd06293a622ffe2d1c6e4fcc8773ec8913717018b97bcb9a554fd00000000000000000000000000000000130a97442f3273b7b35464545e7351faf71ead9b8996c63889a45945ed82bba29bff5014776c6185219a5234d8475c92000000000000000000000000000000000491d571bac5487b866022a0714be11b38bfb296233845cc434a50be1d35f516b8c6b046fe3d0a8f4f95ac20eddea01b0000000000000000000000000000000017e34b04e6fdf152c848f2432b7bd84b3dba3915f06eb77efb8035750aca9d89e92e1d1bc4871105c440d639e8d8b05541776ed9d1029918af4c5113a6110139b8bd7f938caa204373a28ddaa51430eb000000000000000000000000000000000f1b8df4e8fdfe32eaf227f5af9f2befc85073468f10b81d32d0e126fe2b0cc8e8adb8afcac73213b6ed95e8e843b97c00000000000000000000000000000000004e3fb435ae0fb2d8bd091f250aefe5922b353a64e16abd75627737f3bc56639f8b40652cae69c73ff1969925b0afdf000000000000000000000000000000001003aed7cfb00efce49d6b1a8eba27df87479a4d37bd7fda6121549483b669a1a761204b0dd28262bf27e5c8e180540f00000000000000000000000000000000114fbca7caf782b3296d0b26b4c362bf50acaecb8bc5726b2c99f904ec3d092d5d40991d0d30c8e79fddaa45f04a75d3fa64411438542922a7bac10806efaa633d31d37c0b223314a8b6221155b9c4250000000000000000000000000000000017faf481fd4cb0c373d21d7caad40e93d9a86e62d26136892fbcc6f6e48205543aff00c45e82fdd1d3e0e733de91e7000000000000000000000000000000000012e14fcb9ad4d9d15347cf004745ed4bd92097eeeb41c4cbcb728a234616363589d8f5ad4cbb61d31a8aa27627723c7e000000000000000000000000000000001513dad1ff27e053902e779e35d04cab648939317830144ea775c435a4b55e13fa2fef03a1256abf5c187487c25a774f00000000000000000000000000000000139da29de8587c7d0ca9237c37a116387385e9cea453b9e2003a37ede7aa0a3f4c1df55255897f5975b662be33622dbce7002f41c6acab677a0ad023bad2a61b11c1b7221d944018b5ce60bb61e87e96000000000000000000000000000000000c118b147ee3489f30c6ecc0256a314ab674110588e8b69ca6d265fc270c3e5b767817f861140cca5d7c6be4012d1ffe0000000000000000000000000000000014800790654726959fd876b035bade0da744fb36ee5b304f228663a531345120267c55ac19fd66022752010e5bea7cb30000000000000000000000000000000000193ab7ac2f151750356b6e178557460c9c2672b1736d19a20e3fa28082479ca60021aa68edf2524f1aa826ee70b65a0000000000000000000000000000000015cee9ac55ab45abbc57d0ea6ec9ee49f6c59f6b94f99589dbc08ee877d3a261ad77f5473fedd72ed7206647eeafb6eac26e55f09b787c0542878e4d720027d9ea465f829a4e0164cf618c5d9cde49bc000000000000000000000000000000000ef203fab794a0ef29eb2ebf00076134e5932e27c99d6d445695b9df2afe7563602e318caf5d44724a21790ca0ab0d180000000000000000000000000000000013b9b1b1d3e98b61b0f1a0ef3a1a4ceed57b6c01849a4ad66a86332b3d27022cfccadd3567e6709d2de5b23b23dba43f000000000000000000000000000000000c1fbace49684f4be32ef6178ac3a95ea3f50b11494340fb73dc5391d50bcacafb3bf0f2631fea9c4ec47327d644489500000000000000000000000000000000040f82812855aa3e3aaba826d5810c1049cf44e86e44e23cc6da437971b529d2f2676c73e1fb9da52640c981fbd710bebba67cc47e38a129ab1140fbcf0386ddba2feefc919aacdce6059a27a1e2efca00000000000000000000000000000000060d7a718dd02b147c265f71eb136d1f31781b12a41866b4f86d7374b93dd10058c192cc0fba928373b1526e1a5d7d7f000000000000000000000000000000000cf29275373c0573ef22bf87919faf5444847203c7dc6d2e18986152cc294be04a5b1a4b0536797158113a15276c4fc6000000000000000000000000000000001016d5b9d4d200d7b4b7cc3836b85d6697fe14db350badba9978c7b56983dd1a7e572640ee0372b0a4e2079ff4c1abf2000000000000000000000000000000000f2768d104d895473ddf8c6b3cd0e7c22458d0037eca6365c766879a07c95037ee0de00d32c974d767080935abbe0be1705fb566367d9fc142c4194b0525c16672b843aac1160f9056ebb115e80d377a0000000000000000000000000000000017b9ca4349fecaa43ce911c0b256680edb8a0906ef5460fc4d2004579336df1e19560fe960a7a7cd74bb6e8272e08960000000000000000000000000000000000d5b96dae738db59cc67a51c61bec6deaeefaaa51e3259243fa4b142ef59676231229ae386ce699fbe18c4c00bf9d49400000000000000000000000000000000111b79f4b68dad16550a13334d09dc38336a75a5da23a17b5064e2d591aa3dab4c2e982a9f730a7633070504663a24610000000000000000000000000000000018f6d3616a7eaf17c805a88c9710039644d01b61aefebf76717ddcda6f4bb34aa15702de1e92bdb27b27f3409638da90f7bfd990cc4dac62a0d730f56b4eb1c1ad77ca9cd58b089c23c2f6efa00b7fa4000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424807c5a41ae2baa1e10ebee15363d1d4569f731d77a418998108f5dfae0e90556", "Expected": "0000000000000000000000000000000013b49054c3957d1e77ba2dc3ef75775bab9f0e9f76b33ff22e244e897b8ab80ee0749c81eceea259e99b5d2a72251e5f0000000000000000000000000000000012e017e4354ef86f73ec51921cbfdd01e3113cff044a049bdd34e36401712420790cf718bd28afa280ad12104c1851ed00000000000000000000000000000000097f28bee5d903e3c6de14e834d5beea5c847c3106742978e586ba7e913f8b631a69c473aa10e19df9795ebfa3ea6a98000000000000000000000000000000001953493daf65b974b549bb98e735da44b543d6fcfd97176fdc7f6f03617d90e6bb952a607fa8e5791df5dc1c9bba2286", "Name": "matter_g2_multiexp_2", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b9900000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7a7e300bcb3c740fd1f693d4c8915c4c46dcb627f6de6e4847f123623cd23bac7000000000000000000000000000000000f20a07526a082e88630a0256d134a8a5e8ada07b1cead39ee838dcbb30904e9016107fcbdf1f8ba182308dbe0b043d20000000000000000000000000000000014fb7732f67abf60c03ac902577532d0acadb5f3db0d6397a42ba693526ad74f2c61a0195bdc9704aaaf12e65aa6d88b000000000000000000000000000000000018cec4fb81c85d304588d11f8b9c51f5a053df11463e5812a1b2e6c7144522ba36bb91adf219892d0007cee470032e000000000000000000000000000000000b8e52d958a12a9037e8be9bc0d5045cade2d6ea05c6e68462b3a30b5d4ea34e5fbad173761e4e216b2e6958c8983b28b473df5e282565a0783d23e65e283a103ebbddb5c884183cceb62fc32d0e9602000000000000000000000000000000001468cb35a60898ed129f30c261b8431df6a154c250ec16d85a22f8717593b2c21853d123da86d977a7938c5ed74ef23500000000000000000000000000000000011f4e28e31b5f9e6877192a5e632d8c1ed7ca0c42e6e9902ca68f1c2de0f648c6064436012c5c7b14bb8d1078e02f2c000000000000000000000000000000000b25114b2697ca7eb1e6effdd1054893a188fd382d387ec098f846c1137a9b9baad01653b963a0b0bf3cb50c3ce3563d000000000000000000000000000000000c1d241cb03e642c1752b1e1886472477c19a2801ec032dc220c3243952f882094119bb92b621b654b766bc900d2d4f7a048ef7cf5d1f6f625ee3aba091147c389ebebc5b8f3d285e16ef4e8afe5c013000000000000000000000000000000000c80d4474390fa791ea5f2f16b41506d8ae13ee0993c8d31a07712687298ee7978a724999500c42400d2f788a5a36067000000000000000000000000000000000592705cc5a8875750a4e6ceb42aa3bef5593eda9e8212702a2e08ea70277a2a66526bc5237be33c8449301544da35e60000000000000000000000000000000000facabfbd15284c6433f17b0e6035d4fdd84d3ad2dd30a27d52809652ff6e7a684d7724697919100567ad0c3e1a26320000000000000000000000000000000006a0fc4e2af69ce15a356656f5d182a2cf213d76a6047a05a1a3375909d245f5316b91333d2141c0817438f0d87bb52da9b63c6bf36997118d58600c1e429c105a379b9e8b0de934ab9f433a4fa63dc80000000000000000000000000000000003f629618e1fc3018bb836301ccdc59022f0a25cc9c5de6e4c31fa08feea525c83256235e4ec8364e77e5df478f5f62c000000000000000000000000000000001120d6af221ba6f4351bbee4c2c664a769adb17872646df2c408f70c99ea991ffced4eab50fa98be1bb9426915f125930000000000000000000000000000000015cd16b028ce3d58b10aeb84b783475d894ab3f0cfdf7104ebb4f3417a038107128f07518dce548271061cb8c97e88af0000000000000000000000000000000018379875b68bc26107f9a068e5034f29dc2ae7e8830f8e9ecddc53fe7991206646cda33d37b31a47a977b46be58d7618f228da17f49667c113d2bc2a2c8a338f80be68496f5145b4be21a5786ca6d46b00000000000000000000000000000000036570783711b381830e35878fbeb187b84884a9a0e88c38e84124515b470e6ac18157e1499026b27f4f731a961eaf330000000000000000000000000000000008382838c18d56c046a8db495babf8d14c915622d7917ebe10cf7da7ecb65f174cddb9e70d0262ada961b396c5511b410000000000000000000000000000000015f63ce982aa581dad5c71fc79251b7f6336c4e78a4a0f4cb6f87167cabd31cbec987d7af4f11dc6d693a0b0774864130000000000000000000000000000000015c001372fe0530a3f50fb8b30e75ff4b264d673e0448211d082c7a9018f583b4d01790019874596c59c68768cfa3e699431e18a462fba704216b516e819fb3392e315b0c92a7411a329cdafeb51124400000000000000000000000000000000074d78cdd35ea17a3013e2301fe9f80f2d20d270a25fdead37eed7697a52d152612543781763e6035fa5452ab12cce25000000000000000000000000000000000e572236e1c203a1c0f99e6ec978458c1a143a6a650eee27cfbe406bb2858fe5f30222f468d119703c2f442bc644ff3000000000000000000000000000000000125384343fe132e16a9fc15efe1b3a9e47289e0afc4b44d492e33a6216edbc96d66c1ca66944a8296e7695f27f414c5b00000000000000000000000000000000084c2cbf0d7c932c3098ded7c70d4411eed882feb0f79e0f7f1c31f5fccb6d53fb57de179c3ba5754bc5e532c3784df12051041bd2f12f6e6e29924139770fe209b7bbdbcd6c0bcabbf5021a7dff2d830000000000000000000000000000000004d46066439c3ac559cce863c58316883651023990180470d2efd06e443a7caf3a514b54f15ce6e850d32779215bcf4a0000000000000000000000000000000019ce904b6c9c3de59f7d5017f60f1978d60c564f94a0f1964c24c876d1139a7ffbeb6d0d4884bbfaf5f2f189af6904a50000000000000000000000000000000015f1989719e69be95f25dda9358fb98aae2819e0deb7e2d291e2c01e85ba26a9da421896c6b6e2ed20f609b533154694000000000000000000000000000000000b287cfcf1dd7c6d735c1358dff15393ddd6c82e7a33c5d8005c4234cdf823c76a4725fd74cad74b3ec51df67f09af0fb96df57a600dc3b5aabff5b1034886d24f6fcf035bcacaaec738deb2cfb8f85200000000000000000000000000000000006b37e2226957d639fcb0bcd6c20b3c7b8372e7347a14b970e01c67c1859fa97c754ce588d0f835ecc053549d963ab4000000000000000000000000000000000c6a5fae8be3a32e3f70a4202a1ab6d97183964b9f7b9a084c49922cd9e0e952b0bb66c5580f0e0c417e079493bcdb4e0000000000000000000000000000000017b6132f11adc0d5d693ae7f3a0f89f5779708083eba23e03b0c9265e4e60624e1fb6940e8ee49d31618fa6389b1b50b0000000000000000000000000000000000a45c5f6df71359648aecb6434bad1619c39f10e279a02b3cc9725d0256bcd126843fc9ed29cbe02a32cbbe79774a3378176412b07eb7f423f23ffeaa0ee642590e0b7016bc063f3fffa93e1e35484c000000000000000000000000000000000ffed009c78ba9af8cd33af7b7697ae4dff863bb92365055baedd2299b7f5b5e8abb84ed434f7223c3e309ca53c08aca0000000000000000000000000000000003b2370c837dd6291818efe7c9af62dd51295c418739ecc509d42c92e2c97d12a9fa582946e176e8153fc9a273140b2f0000000000000000000000000000000001e63438e8b4a0462cfdff64a281ab4a7f48d51b51325817139f8ee683484f8695f1defc0c3efcca81d5fbff06cf9c54000000000000000000000000000000000192fc391cdc1ed6ddbd317f2f366f2ce25ba27b8c0f09c733e7bc0c0697544399a3a4f1186d139a8f6399ffa88e89a69c4b5627d84e153f3a4ecc14ddd6baaf1d62253a0f88d3af51be18d991976da000000000000000000000000000000000002e105e0eaa418d58019a849b89accf665a94ffb0bdf308a11b99b521de7af8ddb150c0e3b2e9c54cf5456b6105bc81000000000000000000000000000000000691a3b3986fbe1c0ea22329364454f37f645d6abe9310e883b9191ce512347e074e18e28b88c2adcc76190a549b80b40000000000000000000000000000000003f3a37a763c8d0d99a3fe36923843a22cb0fa18ced48493b2510fc99afe5b7699bbaa6c2ecdad8aaf72969354f121a1000000000000000000000000000000000f4bbae00205f54eb10c83d928d908fbae342b76050e33c51b6e282e02b3c1f132a4728dee4ea95455c25fdfc112f2542ed270764791aff081f1dc8051d22b8e18803a7e310393f21bb4a495a445cd450000000000000000000000000000000009a3e98fe4a98582ce9f274965f376cb45e8583775dbadf626cb1327c1f8a25b293b97e7f8f31ff72ba7e8e769ff25ef0000000000000000000000000000000018e4785ccb76c4897087c8a4242ddc744c6a0a53a4a844254153c23d6f16d4ddb945252d13f93101613f4eb0b1e2b8320000000000000000000000000000000011b81d344eac04d3471b1edde5e51f31f97bea3396580839fa094db58cf6bee371bbdc045fb60c3ee5c6cd5d3f6d3c4700000000000000000000000000000000073476bc5b1d52ff4ca89c3afc099417f473543fab6e59cf9de8a19705dc4bf2a210b1e6de4dfbde035c312be0c70c56fbfb7606b64eef0460b8f33a0be54451fb655ce0b81db89eb7862f392450354f000000000000000000000000000000000c414b95b298b9c673001173ba7e5ee3e03926f28068481cfa0b469ab556f8fceba9fd0a815180ae0b82c265fd4c6b7e00000000000000000000000000000000054a242c1cc1a9c710bc23305d09c2d613ee8eb3840b37943bfe83f9c1db456ab4436ad319fcdd8684db129d76c95320000000000000000000000000000000001683711c0c7f02e67374f190eed1ce6559479d6d199f43fb5b0ce7df7774a5cb21c86b3b3498855d9b69c5763acd8c4300000000000000000000000000000000062f87085dfec847af518bd71c078f994b090c3b27c6eaad79772ab58afa43993db52fb08649a32629d61c3db12c87318a29fcc442d0c2446697e94dc47181dca7a314f9073c06aba6dc55aa79978d7d00000000000000000000000000000000083eea9b5b2d5ac5f7ef51ca889a4317322d098a408a741827fb3419eb12a51c07c788c2798cb37635e224e99bbc894c000000000000000000000000000000001312ec00f4b3a4305700b44b3f215779a9a8bfcf5b5d3a7f237a33c5484099ec9bc5c8537fae768e2c0ec62168f383d6000000000000000000000000000000000cf1d5d05d11e1d07074dd34211d0f00eae1df4dc550c55bd2fdafaffa1ad36abd5da30c5d3a5aa2845b1d95a5cb571e0000000000000000000000000000000015223baa9f2ea4b04fdb05b05bf3a94dcabc5e64189aeee39c380de9a34fe6b4253f5795f70bbe51b80e1aec1eab7196d5b468797b4af1978983faebe59a28f34956dacf5b7f65d25548bcedb518f45a0000000000000000000000000000000011a960cf1978aa2ce1731b857fd91d2f59d4b8d7c6871ef6f4f85aeff549a2f397949d11a4793926fe7be37f3a83d11c0000000000000000000000000000000001954f056834d6e3b16043ef1acd0a47a353300257446e9a1db7e58bd0d7c4bc9ceb3db51ae01cfed9de99621e96934c0000000000000000000000000000000002e2fe460e71b65595ed93a0010e5ccd1a2c16fc4e0d345e7226c947f29720d2f3f54282f79cec086d3fb1999b9629b300000000000000000000000000000000060dd8a7ccb613f1521168a8a322aef9f84d9708a893f704f4fc9a19e2493f25620a47e0fff1bc1e212e65e92873b4f2dbc6afcdd409e5d50d7b655580f1144de77f3efe5d6268032eccab7deaaad997000000000000000000000000000000001472caba61c2f1fe4b1d0912b114c25de103ef4351668f22f3a158d7a347539a7b6656044bd490f036ca3e29dbdded370000000000000000000000000000000015f8cdf7786410b409f218164063c99e77d8f72f03882a6c9430ec725ae574547d3ea3cf30c3ad2c9c3febe6c30b1272000000000000000000000000000000000ccbbed85c2809433fbcf22d6490457dab800b21cb4de414c7dd1804a0bdeb7142f8ffbb2de921c2c9eabee6a6351026000000000000000000000000000000000a404f42c48e3ca408d3f92079b99805004da928f128206d8904ecd7fcb14121c7d9a9e7fb69accaff921315ef3d5372807347519f114e78f99617f6b147ca833bff7be962c9b1e1f32b5babe6067d7a", "Expected": "0000000000000000000000000000000000fada9f43b29abe15693d047adc277814cb94694cab3be56b92312ab7666649b8e9d92aad81f8e487be0f74b9ce8c250000000000000000000000000000000007f6891775811a325cd7f548011ad4c705ca0327ea0484d938ce061c913a7ee6978293c3258c4b865d5c2325816c39990000000000000000000000000000000016761f859beb90ea03aa35e954d112da02daa8e76de80297afde9c29cbfe8ef4d42dad535917685a99b2a91b1f952ae50000000000000000000000000000000012a4f24ab88341dfb8a60c19993b8abea96dbd7033d3686c40903728b4fd4da7d07961f2584b51e9e6c05976d555757e", "Name": "matter_g2_multiexp_3", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b52f05365c4df20a7290aee71a7e030615d1a2a971167884d835c24e756a0faf6ed0552341c561446c7fd3d5e887d830000000000000000000000000000000018718ef172c045cbf0bb132059754b62414097eef640a781db6ad521af5a24d78c622d9402033fa939f70aad0510a1ac0000000000000000000000000000000017e969e44b4910304b350b5d442bb6a0b71e1f226cb4603cc8b4dd48614622f3f4e1ddecb1894046649d40f261d94e030000000000000000000000000000000004dacaeb9e05b9d60ce56c17312a092cb988bff426b8a718cdff860186935507a06eddbc4a1a29e4ef88db83fc4b6e77830630695c8dabe9aded1b5365bf93770aab7e9ef4140a2bbde2f0a7b109724d0000000000000000000000000000000019829d5799eed5a081042e4646d46fb6bead6d3b9893a4240867b25ed6af6a3e154514f244466d80e3b9311e060bbd7100000000000000000000000000000000156157a654db2813cb9c1b4da0a3ee192fad076bb2767020fc5fc00e967c1a35a367ffa375703e1181b3705ace9dd28000000000000000000000000000000000093385a6a9dd0ab996df54b23f47f4a49b3f379e11bc8331016ecee6161fcddd22f6d49fbb21f098873f1e17424dedca000000000000000000000000000000000d5b5b0f2ce81e755b4030b33fe3a8bdee38c2c60ed3b4a88bffb9207cb762c0a5c699ff424c000ab080d763abc5438d184ef5eceadfd77b3a4092696ec34d0551c88e434567638623740b7d5f9e36160000000000000000000000000000000003af8c25bdbd0dc1cc344d55366f15555709a74e1f0d8d7050cb6b487759db6200401b7868fca3c2ad26e6362a30e6250000000000000000000000000000000013f8b6ffe30f9a133fafe64461d305cc6b2cf5aededf68ba396d4e00df651531c750a3d94dd77bc5c6713b939b18fa19000000000000000000000000000000000dde97855d7728f409d873b83b6879b45ace5b73f317687fbf478e594a959ce21d4d751db646ceb20432e8311e67404f000000000000000000000000000000000fea997323cf29710cf0e3d44ce682e039d6cbda155e43c94dc8cefc5e94000de4b9525123b9615b5f1019a46ef37ad3a80d9efab033e920061cee8f8d7ea6023cc05f08340642613628b39e7b7fd0af000000000000000000000000000000000cdf60e3bb018407eab162822468255bcffd54cad9127054bd1c30705a4ebf1afc7f539cca6ba4cd070b44410ec751150000000000000000000000000000000009a2e3e5993b6a7007dedbbd21737a8c0aef3ecd4607953c4a24bb3fed97ccae01ae1cec024443f300b570a66e9ac3bf0000000000000000000000000000000008a21fed19e9ec2a741ade7767b0c9f39b79c3fbe34aadc9eb3043583768d893bf927d26231759290c7dd9c4f158d5a10000000000000000000000000000000018eef4ff88d63149d2632c9db586a4af0606644b16c82fbb0a3b869f1ff924c59acc8efbfde7bc604497ff68939cdd0845111c860f6f5725f99b225c53b9fe1a70150e7ce922bfe214900aaa2790d145000000000000000000000000000000000f5d47911596c46c0c08cac5f5e7f6d0609874da4ac1bd4e0e59c393273a5fe31a756c7cfff2a01d19e79d209d7c6d3e000000000000000000000000000000001010f864eb6624132d4436d18db7f5b34727060dc426c109886be88031e3c155490cb3fb09e1fbccb7912875477c6d840000000000000000000000000000000005cfbf1c2ae1b80a8c7cfb2cefedd907b0552794f4fda101ca1a723b18de8cbce30eb54287e1847cee3f416cd8b45f2c00000000000000000000000000000000084fa63781f7eba9c7e911ae5866d485bc7e90603541c55d1ffad8b3cf7547fd57fb24b14002560e58410b828513e109c07041840216d60ff445cf53b273a46016c8ecefefb53550f8bafc79966f863a00000000000000000000000000000000124870cfa469136c638e0cbf15802f2699aacb66d7e4c2965c6759dbca4b7e47941ad9ec37a84db1afeeeaa65a7418e4000000000000000000000000000000000d4503049a6a53536bdf41dd832a6ecf3f10554887da7e389cf940394e1d88db94369b7947436546eb6c6e82c48dfb9900000000000000000000000000000000053f9a6e1f05b67cf553073358009a172e2ab8b43572a974da1f3de85a29103b13d7e67b2a359297172d27dba5c61439000000000000000000000000000000000abc29f50ddc1c113c73700b9b9796890cbf48818ba981fdab2db27ef1c58f4c2e4595b99eae397d40990ce2f6c9317c29b031b82dc8c9f4ea9524793b54207d4e13a548d73297f2aa6241aff57abfd00000000000000000000000000000000007d2aae9794b7a7de97f7146c0ee8415e09e56fd42535bce6773cadd6f7ac09c4eafe2e926cb7014377e54c703eaa9dd00000000000000000000000000000000172a4a33ccf99eb0473b2c44d30bd53159afae0c7706ad128bccf6258974d5e5761f9be43e618cdbd96027aede7fd5860000000000000000000000000000000012601bce2171c6e4c2968a3efdf1491285f9e4ab37cf973ab5c8e224ad5b40e1b6459ac89090c73deb8fc79fec7fb8e200000000000000000000000000000000112a6443116e6f98ab348e57daa3971b5fa506e40515e1611fbed3e7dd64c5c1e991e0d2539a70eb93e3da0f573d6b2263d26ae92119c7b06d83d7e2922e06559b1740eae315c6623d3e543c9bf54258000000000000000000000000000000000030372914b83644fa4db1958831e9335c72ab7a811fb337696221a3290e4c54bc10c2225f8fdc3a9f62632ba2f1594500000000000000000000000000000000114205926609470b6022d24046a1997c048e6d2cf6043397892c967692161c0ceedf409bf5e1199a64eabb1ff8de23640000000000000000000000000000000017cdecbe73779855b7b94920d4bc8ad057ce51c5481a5579650df8a5bbc421030d2ac44568217c4dbb13d7c639760236000000000000000000000000000000000f194fa814bfa7396697bd812d9449d06fc61b580d7a86429fdd1ad376e21ceca139356d7d13964c3c684563675711c67a02c61a7a75342ee7f0745886c0ea2a73c21500aef8078d21d20b7216c2990e0000000000000000000000000000000015d4ae1521acf897344c3a76261754ff99742585af4a0ee86dc473a88fd408091404df1da9d8bb291db68bc9c07d6b2b0000000000000000000000000000000008ce160213875c661163990f3f7ac219ea295db5e828354864517ea8689ec15d35c6df78ff14cb276e0c97ffd7fbc09a00000000000000000000000000000000038a3ee211e777d6d6b7ca6c7a0d2130f1a071c030eebec412c3a0f14c3584e7c5cf15de254a8f141a8210a90249ee5a0000000000000000000000000000000019f7ec6b2fcd8b3190ab37a6e843340d3f3fc092f5772a042edbd5bdc967b96e8a1dc9e435b8463496aa1301f87d0e5a81b0c87102055dc2901826875d5e85a794befd93fccca2b9c0a1f70ef5610d83000000000000000000000000000000000fa7f8fbfa1d4ef5f001a451c55ed261dee344025e599884b29d086e15665867932120d33bee579d5eb1b7e6c7299f310000000000000000000000000000000001f06356f793350b17b47a623059a068800ca1eab6089c7c146182990063e8e23bbf40d95a42bf6e976224b680b75bfd0000000000000000000000000000000008807f6606d2302450bfd8b38fd4147b851ff59762c1ff48f9442c4d7b77a32c5e023821eb47fca839a27fde60e5f61d000000000000000000000000000000000c5b92f1ca9c20d4b6b11d794a5853824cff20d9267a20a7aaa4bed8bfdc728c4d4d50feb8f0b569757b97f473138db1ebf66fce49c6beb12737fe05e3adc0a51ecfa9144ccf6253088dd1a7a483de070000000000000000000000000000000001191410ec6c5ff628bd25d35965f5e9fa7f3c3d8c0a9a1ee7ae37437a97c25e221110d892e2c7a0e9c8e386774eadb80000000000000000000000000000000003be30c25a18cdab139277232d8888f6d13112c9556895af8030f1893114d5845d895df9afe3c6f9ff7ffb1919adea9200000000000000000000000000000000197f6b4e38be0358a3f1722664c61e62587ecf5467f8aadc3a236b47682a75cb76bafb18a5c556b321d5da49cd4bfd4e0000000000000000000000000000000002e4ebf7f22d929b7421a600e67fa2e64a59edd87a2e2eb9dce1f06d3c793f1a812bcdd510e654d44fb4c1de8c64ba9f0305523dc79dc4b905e65587fbd095ed57aa42403d2df5dd489db8f50c99e9b60000000000000000000000000000000011c6f1dbccde640f63ad7d40089779d01075e26269421b4ce12fa5341f58ee9110f17d08dc1052426f2d00da2dd70b4f000000000000000000000000000000000740b147bcdf06705971c113a5cc12fb37345dd59f2cbb5ff500ce2b347fc5a8199cb3007a871670d5093f28979cfade00000000000000000000000000000000046563ea98b5e85b3c42222d5e0d8481e6aefaf077a1b99f2b4eefb397ec846aa3659aacda569054c9c8b9b69750272b000000000000000000000000000000000812d887943506d68e3525ced9b979354539b7b14003a3169e0084c26326b92be67346920c9a99ef0f9638e8991296feac23d04ee3acc757aae6795532ce4c9f34534e506a4d843a26b052a040c796590000000000000000000000000000000004c8078fe8567013e8d05a546934026cdeee7d485e30d739407db16fefaef53ed7bff0f9adaaf064aff014ac919d91c600000000000000000000000000000000107cc17f485af7f22e07cf14c5cad6368323f720511fc9dda677b360567f769e47a77f61274927ef9b7be48a77357ec40000000000000000000000000000000001487f0880a6cbdac33ca35b9b65e4ead9d8c2e9180c993bdb2052060325aff8c62668c643f0cd9b4bb1f06a3dc74285000000000000000000000000000000000d4b2d062e31fabe8d2a329dbd6417673a519f455739d140246f2b3e43e20f390088c08e545bf0419d796ac71aebb5198586d7ad8fc3e4fb42981a4415224c0d976ebe1c342e9bc1cd66d35168bae33d000000000000000000000000000000000811e9b0acfc10830c074c5a4d9f4d9382461eb523a61dda0b77f1c43b285fc5c1ef3a1fafd923addc9a6e904505a255000000000000000000000000000000001113102d015dbb509f0b8d0d0ebb4d3711c4f0e1e3d55fb0af247dd24be4fec9d6fe3ad73fbdcfe206891bcebefee4dd000000000000000000000000000000000085aae9e58fb97b96ca3c089acab7bdbd0c3adae141bf61075f5c13145b0d07113f1075dfb959bc7c2d3d3b3a06ab2a000000000000000000000000000000000bb5eac8125807c10270d94e5bcf278241d6fa82f68e41b5529b28aebc88870af55881db526f7bd221a8c4c0b29a1b7d6e7db0fbd2a7327c85054b4c0de9727dc0b051058f8bb4ecb1dcc7f825781712000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d94685cc8d88273d4aa822f44a447cc22f5a58c420bcfe757a459772825619669a720000000000000000000000000000000010192b925fca096682acf138833b12d96bf97c9a2e69e4266eaaae1785b9008f36082e23e2d42341427edce24449935f000000000000000000000000000000000d5b24a94adadbf542aa663114096bc670e1b6c99f3b661f55de121922452534faed7f68d6b431fcf6f3e379d7acf6b6000000000000000000000000000000000acdbcae49206b749d8c0d21017a33e689ebe26804d1fe7c863a2ea4210c3559805dcf73685702bc56e644b4e02614a9000000000000000000000000000000000092309d684fcdf44bfa321d473060dc2d8a8c66c51419894a3fbadbf1b56179c31dff25403b970d543f1dd0e19e56cf5b6e462d809f8bf1a62f276dcb27e42d9aa0ce33fc4e149e87181aca70a4ccc6", "Expected": "000000000000000000000000000000000b219032a2461a5fd1e43361c46beeae92e30247acadcdd241692abe81691c295ba38a1f0a2a45ae76b1b95d7d0fdc460000000000000000000000000000000016905f64e581aafe928520adc27c24703e7adeb36dfbb416a159cdb9b9a26c9cef0821ccf52f5ea5253b7c9d78769e9d0000000000000000000000000000000015cfff195b2123aa140f963628c41deaf19dfff44d26a38de4547c3d15edef10fe9f65b1802dc374d7ba8fb62117c8880000000000000000000000000000000018dc725cc8d8919a7414b7866fdc54c4467b0f87cf99fc9b36cd65c0ec526e32649f9c57495657a93487f1f2f5769168", "Name": "matter_g2_multiexp_4", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014441b14765eee30e8131a7ef62c3b59370f2f6f0dda20fb2a3654fa09492bf695de1d1a8f250bfde3c7d2ed805ffaeb0000000000000000000000000000000019d813f8be2519e89d42a9fd3fef09d44a996d6a4713a9c224bee10f0ebb196370d6231fad810edf9cb4c875f08357890000000000000000000000000000000001a5abea13e909bbefdb51ddc699614366f271b2f6490ac8efcca7759833f3feae11057ab1b9ea32311e7b6ea6de110c0000000000000000000000000000000003ac2bf3c5486ca176e34ec5212165cbe04fc9e8c375e3e999a31fe014eb824ea3f2d06b9cf8b86ce3a76960cf2eb4d7535b53ab5f1c596eb966f57867e021d0f3b099e17bf384479c959794b17d6a4b000000000000000000000000000000000598e111dcfeaaae66d1522be2a21131350577253a3f33bdd74a04b0bfba2940e73b62fefa8f0c34c4aa91b633f6bdfd0000000000000000000000000000000017fefff7d94afbeceb33714e9b5480c3a2f3eabf9d7f6e8507ae54cb65f69b21cd7d04d23f24e3a272c589f572b91864000000000000000000000000000000001652e3f5a99ba8dfbcd1f90de955ef527947642054be603c1b84b24bebb579b78e2a0be426ec21d32783a0e55f0178dc000000000000000000000000000000000a6c9ec91e8bc86ab198416cbc76239f0ac0b903f40310ee1f2066b01b08191538ca913c2736f53f23ef37fea13d52756e0512ecbc5a1b02ab19bc9bee4d3d9c721278e07b7a6e389c4d6443232a403500000000000000000000000000000000072e022c168461905f798e87425f2eebb517e473cef98c255d0fe434863ef5811920af65bc946b29d489b5dee1066c56000000000000000000000000000000000e7a9872caa82d191f6014c845e1b3ee4ea1ee89852b546a2c85ddbfa3c1d4ce99002e3d7732ccb8cfbd57d550285ab400000000000000000000000000000000144be65db373f6401d76e0ee64e51076b861e8fca596dd6a7f3b5735c23b0cd13248404fa0969ecaa701663a1032f48a0000000000000000000000000000000014c9e9c5cffc4518889f7742440053678ff1d9fb1a1a103d0c1f762b10655bd5849ce98f4bc5eae80bdd9e767aae4523a79fd15e80b694122dddb01f836460b3eff99e61ea6309d6b395c94fb5a43dff000000000000000000000000000000000948d0f0c20715f8658e1f2b4f9d32d851e584287225a2f47735a1f4c241b07f8d7c5dd8c13bcdf84e97d49817d4d88a0000000000000000000000000000000013c064548cb756b48600dd535af8eb5b9138f984bac0391df2e90a204fcb6c36017df910031864d802a2ff719856b336000000000000000000000000000000000000b7eeb7c9a01be88e573f196c2a531635baecbc8cff9af385455af3757301436686596ec7fe3618af26953c49f7450000000000000000000000000000000001332f4dbd5461ab9e2c8b3c19c6ff407a071018c92d2c17c1d1d481c24565276c0f55eee8692016c1fd76d70f44627cbd012914a96253926fdaabec06944ffcdb4637a05e3e78a9bcf1b21b68b9dd9b000000000000000000000000000000000d3ee70610b5029a28e586f0f3e65bb19a263db3438710fcb8073e1b25f83db50eb5bbb9d75cb20952a225023f747baa000000000000000000000000000000000682f7d5cf9d182b20ee88683f3915e8c9b03074a373e573aa57232de4e997bf155acf680e365aa0988989dfad102b2e00000000000000000000000000000000143962963e230a9154dc328f9583f5be6923a3b10ee7b1d0cd5f5cbff13913d8ff78ca315be7387900a50b94449884c0000000000000000000000000000000000f4f934b42452d41cc20d7b1ec547bcbcbcc10f215364ccf2b864db23a09d06e94c7a87165dcb691f4975323486757ada300c7e1041d94df0e0201e1135fa6eafc98bd33b2dfbe4c59b546a52538c07d0000000000000000000000000000000005f0fd4080e26971ab16d33aeae04220ae23781da3179e38190082f1d167514bd73bc8ef976a2f333570e9f56a6c05e6000000000000000000000000000000000e159905d29b52ba61575c3a263093017783e1028b3701ccf060c165ba33a765b5265a9b1681c1759bfe2c9c401275e9000000000000000000000000000000000c5ac0bc29a49a7c37d772954da850e6b5e301e230552be9a94017d770ebe2cf4dcfaf104633623e024aef6db57892900000000000000000000000000000000002228e7f42a9409acab49cca82cacf306f6c6c29fd9f7e2ed12fef2d16383cdb7bb2b39ad598b301072c615232db1fa833e9cdb10fc117afb17803b61a2bca7de1d190a325639eb23743f51f28294b3300000000000000000000000000000000180569ce03e4a0155285e733adb18fbca71225507a7adf01cb8e8648891525305e92087f58378f4fd8455d5632ad660e0000000000000000000000000000000011ab84e42f10154e306a568d7cf7bc381000f0add0500cb508f695a3b283ea69d140aa0ad48fce2d2d6fcafe60761078000000000000000000000000000000001136c3016474d6f475609606e8d0269fcdab9fd3188a512681cbc41eedeadfa3b3d9355e5b4503e8b5c3665e49fdf3ab0000000000000000000000000000000003f56cba1b9cb4302099b16b09c2602dfab80d1151685ef78e5054cd454b319adf8b5998053a5b9fddcffa020595e3bfc48b98edd9c229037751d02e58f3d4234d9a3b0ad9ae4947ae14beebb274746f0000000000000000000000000000000004d79dab9eef873f3415d66172bab7166ce0c71f322529bdeffa915c1b0d3fcd645c91dd3450ba61593ffecb95edb91e000000000000000000000000000000000d611a207d3222bba199fa083d0459675cb5fa00839fb4c9034ad868fc1e79d653c18651771431d6fb6b6b5ce8cf6f7a000000000000000000000000000000000ce802ecb106a4f0ca4efdcc058dd0e29deb6a5d30a2c15c8eda896bcdd3ac19053c10105328d239b26c5ddbdb3a95fc0000000000000000000000000000000001073e142621ecbeff6f81453660362545751f992ffeec3a83477fed3e6215a709ffe0d17b65d3369f8f3913bf000e844228758d2cf8105f2ef11d83018157a3119a44874dc34d5f0bddb533f50df52c000000000000000000000000000000000bd84f04b3858b1138b1b429c7216d5d1b1e99c1e0fec26440d59b1ad79788c2d5583122c2ad769fcaa6d10d816a1f1e000000000000000000000000000000000387977ed1ce5da51dca230531bba53d17d3de5d593ec576cabfe6463d5164d7153025dbd4cb3525c4145c4f6b85fc76000000000000000000000000000000000a19c943a90fec6921367a2edc5bc38a5c59839cdb650766a2d2d068242463dd4460bd1d0e7a7fb0e3d2104704b8b3730000000000000000000000000000000011d99d44b200feebe00bd42809e3f67a23cce88a07165416cbfaf4db14420f99e54d62db4280d2c99ca0bc3dc41eddbea417c96f0cf4355a78513c77cdc676a7b09125802c8045756da867e0025a36f10000000000000000000000000000000006a186aa584a466a860849c78e4922889c95a4ac6f39c99029fbb422c43d699a8baa51aa4ef51ff99557babeb3e9506800000000000000000000000000000000065fb15b5a0923bdb52dbefc7e9f1a898e32f17d610bac829235446fc5e1913fffc8176e0fbd33091505761f1d06d8920000000000000000000000000000000008bd358698fd073f660ed608462cfcef1da9a59b10905f1d98c4fe66958e56802814906430c10fc25a4d351d91f91cb0000000000000000000000000000000000a53638b1b6c6eeff468e099446300ca7c7bd899c6494682d14fdabfa9cead0bb37a0325d99e7d0ba6341cfa1d257ba846561328b7689b0a89014823537cf9eeaca6ea5c56a3e58d2abfc2ee455dfccb000000000000000000000000000000001070b98c6348a67e996626ec2752f45e4c007e9c9668459a777c03fab633c10236a1c5be99f3fd950542d5648ef9e88400000000000000000000000000000000073a564401cb1a3a53334c0a55da261814d27b86ebf40b02a76b20973ba2db92e42c138ca7790261c2d70401c984bf470000000000000000000000000000000004212d8a9e4b01f5c6814a88561c2c6143eea61327b031a2e0e4bd056c12dd7098fdfe4d1511bb441ad42b55b584a7bc0000000000000000000000000000000005c5d23824b0fe05eb962194550681c57c1566b315efa8ebc90b3593d7d86ad18328baab8118c9f47eccc0757588591ccf6c3fcd4b9e6b72853934b306a078b1f2fb17879db4a0a93d484abbc2b746cf000000000000000000000000000000000b1b3053774ad5515a20bd4c556d2b3ba95fe74fd0c955069c7f933dfd718ede90ac295f5a675f1c29dcd9701978353700000000000000000000000000000000145746ce88686021a0635bf6f0aa2f77c48bdb364cf4ffa804a57f95bd69d24eead05fbee24021c1ef57e1c7c7b894b00000000000000000000000000000000010ec4795a0762b86f3b83de1198698af67fd1b1be3ddef48f35cf82bc96d886fbb4c75064f51a9cfc5f61630c95d0ad1000000000000000000000000000000001465e31f58892466b8ae4b76a239d9f8d1ecb1834886344013cd1df0be13591798868d224d38213a6d75b02a1fde0ff2f6787b565e8d71be6fdb0c97c4659389c800a2047f668b366214adc716f402d5000000000000000000000000000000000f39e731e6ddb7496448c912ae314e833d28208252c7f8e27bcf7eeaf1da6e2310538b4ef0d55401c6552e91fd70691600000000000000000000000000000000069d3612f924961f827497028737000513548ad8e104acee28f014e730d4752a583cb9a893e6169b71966a1c4a4ad2dc00000000000000000000000000000000090899907edcbd336bd4fdad0dd67c578ced4481a25b864b32aef920842689a2c23265277a6e1d4a1dc1b5047a9f79a000000000000000000000000000000000055ba64e2502baf68e46c759fca30247a080464eda2b32e7cfe539e545d6aac6dafb731c2c45749e50513979cecbeb5440ed91f6ceb2ccf87e4106a16227a3cd7b2821b4f3a6e629001f78ba1aa7346e00000000000000000000000000000000042f1c8b9fe81cdcabea047d0998a1354ce09d62a14f1d0e9d188e2f35f2e1845c2b090c5e157595b33108c67e6c184c0000000000000000000000000000000018e69d3564d4ccc0306e1e6b227b0f961aa9afcad59d4ee1737f980dc876609c59a4c6a3506f987467beba0764b857000000000000000000000000000000000012ce5883156588cfe0f4838f819f985b09f1eab40a5ea8e30fc5d70d029a01a4537641248f4c21dd203909e0170737c80000000000000000000000000000000002888eb9778a4045feb5899dda258657b9f41345731ba630fbbf186b3be4b58ffc7f48abb65b693b573a73f85440a7a7ae8ddfcdb4748981acb9b2037c017174a140f2457fb0148fe807fd194a9f7be500000000000000000000000000000000051982b46a819c74105cb36da871fb2415328a1531d155856f6551bd043eca62ddb61f24af429edda830fda31e22cd340000000000000000000000000000000006449e5bcdb5619aac542f6633ee3e06a4fd56a3e1ce4034efc608131ff6ead70ca63e70f494f519d5c577ae7119c8c200000000000000000000000000000000153f4f5dddd5801fbf7f88a735b9170d24d5b63861d50cde9644579dcff277cdb0d5fbfc3b3b819a1172de05afb9135b0000000000000000000000000000000010fdea84983fe6c08cdc4b4ccd462bae2ba791ab5209363b10b3ef342c9a5e92184e9d8be1419e3d88402bc05bad5fa21268803aeb58a2d57fc797358fb456d5cf96afecb1ee0d2b90782aa0d652b8c00000000000000000000000000000000009b011f793d9a939d916d058ffe91b58138820a646cc450389b3074ae3715d06ddec1075afecda71c65c7ca085210c740000000000000000000000000000000003d4d20f4b93c1e90a0a06bd534d8b4fd64e4c4aba77ae42cf4c5b2bd95f8b02ec4069ea246ff46404e6c9eac632fbac00000000000000000000000000000000051e88c3adfd4d6a02d3f03812362a6cfba3a6c69b9aeef75b51106cc7f1750293d61e31f0ea29b5d7aa56debb6d2aff00000000000000000000000000000000086d9c4ea6769cdf49ffbbf7351023b4aea640e8c90f9291222fd0b5984bca4d481bf7e10df921406a34804e6a09f99df9a8a4e5c65973b785c1e2637937de239bb0fde34b786dceea66f6bb12eb4169", "Expected": "0000000000000000000000000000000007638fa4e8823dacb40ece440f8f1e57cc5c3851f94357a5325207db92380dd57a7c8709e4d00b670e8af1b77368285a0000000000000000000000000000000005b66a6e6b13ea0eb367a61ffe7c620d9edf5563cb4cc0cdfa68b99d9691cf9a40efd967c1e880238eec313eaf4c92ad0000000000000000000000000000000004f7156c69ea88a71a0af2922d1caca24055d40df058eef02bbf95d864156f62fb0e17d9fccd193840c36ad8449bb4f7000000000000000000000000000000000b8f46fd695c5d96d939d42c65c3b709d32f134710a67909dc4bb43d752521a8d4f0465d0590f30f06ce42bf5f8cac28", "Name": "matter_g2_multiexp_5", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010d48bf523f3909cf90aa58a9517ef5421f1212accd5e8a0f830aeb15a587e215ca9c340bb846b1d0474e43840b2af79000000000000000000000000000000000cc1a3976caf97b9d59f448f6d9f413eef8904f360c0cf912fe942b38d7fcc637a17038973a133608ae769d3e389b18a00000000000000000000000000000000069a6122c6f0ec68834b7617c755a7eb33a80a25acf95859da5ff03316447182f122d20d993b04e79b6fe859b7adf5a8000000000000000000000000000000000058c6f8c297524319bae6722e0a957d1ba0f75ee3a8aaf06148641c67925d15780e419a38ed7e07410e82769da74f2d070e7e2ae2751a1f71962726a31f77553c2da38f4fecda435b6e5459d5e833b400000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e74d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e12500000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d553041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db47cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf00000000000000000000000000000000196f78b64fcc342ba4f4edf34a3080ec950532a5de21a875dd061f09351def5ba3b85745a561e38117a14c20d33a14610000000000000000000000000000000003929c2bc55f323d57dc3529bcf6644e61c941b72b424d69969c1cde7a804d157045bbf6d5b79a3e6686509e11ecdac0000000000000000000000000000000000f6b659818510cde463c52cf00bd99da045c80af4d5cd0e55f9bdd81f34169fe869c519f37a98ff20c56db554469087600000000000000000000000000000000129709e97757724e765f6600c2b1928286efab55ec8d16876a2a3210bf9d31cc5425265d0576a2d5469cbd9a6c8c27c012adc8edb64db5bf0ed6724f3b54140ed6c81ca65ef9d1b38c8bca6a62bfd3c60000000000000000000000000000000009f5f167c9b61a0ef76415fcceff04f3fa57071c2d79f443ef8a7e6049cb1352f650ebd8f358904bb432d42772c29afd000000000000000000000000000000001524a875d73e03c53b92465bafca582479110611bac6a98fc7d76966e9781308a10cb202289c0776cf5c36515733ccf900000000000000000000000000000000002b1acace94a6fe196b217a9aff413fe0bcb55122ce9e344942843e5afba0d5f2cd0bba14c9c8cb9dd1c3e9024918fc0000000000000000000000000000000018e4f85c7663e596182603862adb559635fdf16ba35fbce7278680ea289f871bcf6755d85654b2a37ae77a37e77ba06ed1535bfcd68e8136808edf89967fbbf76b7f58d1a8ac95ebd4944b9e440f20b20000000000000000000000000000000018ee4b4855f866781f38a618c2fe4214c63034620ea5b72361079b0a5c2b2d6fb9ea73fa202db3a2678cf07219cde81100000000000000000000000000000000180870513afef93870ca64e2363fa1aa43a599db97f3b807ada1c25ae331c80b8ead5cd69b6f5a65a083606591de90ff0000000000000000000000000000000010afd546703baa35a9eabaeb45d301bd5be115557bbb4ff2a0e493668ee790e947eeafcaa923f62ca00b8e635994e39b000000000000000000000000000000001089996b218aacde4ccfca4d2f66d79fe161d962baaf2d6696e1a76ea40af4ae7195e8cf9f6417ffd054f20b65ddfb104c576996d90abde581afb58903cde4b9443eeb65e21b0d68c578e04c8f28f3d30000000000000000000000000000000011757ad74a3fb341c8eb6862978ab3fb5e8cfc8fdbda7d82756532a890d61919cce931872ff339843805e00d8c62ec4200000000000000000000000000000000060783a06e93e82cb08e5dc1aa31202ba11676511300e186ae8e45248b7fdec3b7d5b6849f8b79b8f78ad84f36218544000000000000000000000000000000000ecfd8ab18066fe3408fd20f2a4478156e9a19a09b58da76486c9f6a013d861960b6b99bf49cbecfa8c9d01d5615c1bc000000000000000000000000000000000b45709845d35d7b560745375df79fb95df15e85b96cc1b98cc832c74621339c609018d153bff93f2f5493a52b7326073c558cc615b1c61c9a42b8b0ab4668ffcfc9e95bbe958e72e7a5500058e6b0bd0000000000000000000000000000000003f9de90222619216852356052e9819d7c6e8ff91e0c6f1d8cec832770ed9001db4569fbf579ab16964d76ae7d1b89e900000000000000000000000000000000010b7cf8f0d283cc22942ed73c599115763dcfc1ddc98d87979fc3dce2f33ca3531cc2909d94f86736dda2a4e94a4f0c000000000000000000000000000000000b0aa4d947644cbc7df8d1927cdec66a68862e5a806e25554f27cc1a3701f429fc7097497ad0419e21cc403b472c8ea900000000000000000000000000000000146270ecb66e1763437b824f2ae122f72f20eb93fb30474691a0a192ceb932b1dee111fa44954075335ab360d31ee68d61301b4957a468e2817db5914ff102bc96460a2c5c15e78bd42884b1223fa71a000000000000000000000000000000000c977cb8de4b6e2e33d916f74eb4e42f089d22b54b59fac9aab0e4cafc8aa2b0f8c55d7251662b3499ea140e322dbbff00000000000000000000000000000000106944a9c2d2ecd08e109de29095f3460128bb751051a1f079acb58b6a60b0bb5f52e63d47b688f4a382a77c3b039eb5000000000000000000000000000000000d2f8be1c78995d54fbccab61f816b6ec52dd19aee6aeedc0e4bde2898b2d07c2925da0440a38c4c965a823fff10389f00000000000000000000000000000000183b5d15b243cc5d9584842ab1a0a1e01ad87268728d72aa8c0d7ec6e7069063a11fdd1525d2b30b35e4568da7c44c5495cd2686d24a5bdda0bcb118a2c0eb5ccfe411ec452e1beb3adbda7e93ea367c000000000000000000000000000000000f65ad4c21fddadcc49a8f7bc281d2b7901707f51a67122179fe97da46ea5e1bc6e70d68eb4eb6776307510a67e972620000000000000000000000000000000009003dc68cb0cdec4a502436718f066348f1957ae65ecca8d32c5fd776215cb9a098c0ffe56c92d79dd68d251f49f13e00000000000000000000000000000000038ecf0bb98ff2e84b388c58059ba0de0cff3d5881ecf01d668495ce81b76b00323c665ba88309af5552b7950cc8c08f000000000000000000000000000000001924aa0f460659f552458fb469467a2925fcb2420d4fa6249310456853be3d08bd5c37a3f0a9d6e94e434391d20cccedfb81d555d1e2df92cdb487a888fbedad976dce54b5c46a39893edeac21a12d6e00000000000000000000000000000000189c3ee691387fbbcffdb147c880218c3e5c0bf78c44461ac1bd3ecd5d4b85225e46cdb068049607fedfcca14882e289000000000000000000000000000000000260efc08531083db2839d1413c90968e87d79bc1a2c730f0020e40beb92e84b73ef43e80f7c61e1a30c0cee11b3cb370000000000000000000000000000000005c852ca0aae2c575c65ef18b624f50a32c007d299f24a3ec6cacbcef1d6e3bdba9650fd7d639bdc60a3e107ee9c013c000000000000000000000000000000000321c01a9de69d6b89db4ed88dd48261ee28facc5e26511fb2833fa45edfb58051c8c3ce9501e8b4c3cab9c456705889bfeed84bd95fb955d1b1045c059ffd051324dc8966e504164e54f76f02eb1b8600000000000000000000000000000000183d50635b22e4d620130e0d4008e3bfffae5dadd7e34f4496899ca54eb4d9e3e95c54ae1d9664609c58d02ee5eff65500000000000000000000000000000000029e3b4496a379464302b1476a4549db371f5d6721704b1d6bd35e2344d7679f8a61a0c3b12f287fd86fd247f9652cea0000000000000000000000000000000012c6a3793fd23e955708f5aeb4d6efb670d25a38a67813ecc72f899cd5f926ab7ef198bf6d591328383aaf54f756c66b000000000000000000000000000000001914d3e4b6ea96bb91333468fe8f3bb74636e9a4f2ed198e9ff01b49ba02791d5bd63224f6a38538aceb777168bef688e3b308b95f6d496e6d5b910b6aabef8d9f868471653e8254ab4d49d593180d250000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0bd4ea92e0e776be341c8444d4040ec121a2847256c5c9bc918adb28618548b0480000000000000000000000000000000003760958eac45397eca1a1d951a80265a728dc3c584f7dae111e7ce04248885321b69b334b00cdb0334a362676c2d32f000000000000000000000000000000001031e4a63129ec40da5fe9dacfe148a67662eaa00e1fd5c30336462371c167348a10e50f4dc18469a1a6b76485f77e12000000000000000000000000000000001412dbf993c557323426b486f18a91d16b4baa2c497b30fb332a710ac901c96d46a577d04ea87afb08258aa6d204a1c9000000000000000000000000000000000da015ca09ac0c3245c090f39852218f46fea62198fba35ebc4a7f14887943c3bd1bbbfbfa300611e45f419b33988e404c07f5188e4c6270a7e9e2f551683c4f9dc943ffc7ec279d15816a7f4910b8d30000000000000000000000000000000015c9121f72e2425cc8aa4c878907628dfe75a903b7f756b9e13728372cba598859d20a92a8297d95e1fbe25fd1cd968300000000000000000000000000000000025a3faebfa53918efa733949f914be08b791794bd4963f0c3fd78df48b14ad214374b08299327575c0731b54eafed76000000000000000000000000000000000771782ecd9980da521618af2f9eb55d91d67b20ba615c7b3cb1a48d483ca405fe99a1cdd17e4dc7aeffce586987d41900000000000000000000000000000000136000da90a76d538f336608ce877be943025b4c8bf15880ea9c1c001c20c954292d362dac9783b7bf66b8d51ddaf0f2a819a0438efd7ec0c1e3eea07ba201af6a832fecec818adbb781ad0c23e81dae", "Expected": "0000000000000000000000000000000014cb24001bd933b1d5866cc3de9f4b8479fe23e4fc26dd210f9d06e7a05449b9f5ac4e2f48fb847599f625824336bf1e00000000000000000000000000000000033fdb2e899427f1cb9757022c5b614f08c64b53583486148b7431311a6f15aea3b968913fd5f3e9b624705351074be600000000000000000000000000000000035420be9c7ae3203d0dec61ecea70e22e62f50368be870e74f9a7349453647a7f61d2a42cec6522164cca0c7081d4de000000000000000000000000000000000fea43388e9f6e31d419c7f9fbb9839b4cec04163a7b401d8f7de73a4560fbfef4e272f1db9c9d5b37693378f139452a", "Name": "matter_g2_multiexp_6", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000039dc2b60389f6c893c44072f4db23e7df4c2f299d6b70b70784d9370d9ff8e5413872c227074d429db999d30dc9499a000000000000000000000000000000001702273db356abe7a3f91a9fe4bf56584f13de4069a91daa6c0b552089bef60da98d32c615aa5610842dd8a507f9477c00000000000000000000000000000000095285e8c508ff12da79e16e0391dadbe9a823c586a049e729596864c3cae117305c05f009f9e8ac032abaec8a63f8de00000000000000000000000000000000078fc70e926decf7aa4c2e4b395e88f367757dc47a4cedcd5e632c456a4c160393837196af474948ce6ad53f830ce8aeb15af019ea2de662bf187930caea19d0aa07a74b49fa7d1819a539e06e4c69ff000000000000000000000000000000000cc3cb5e7b033cff3e5cb01ba29ce8e9f4a93e836ddea7d417f7b07ba8aa71a0efae2e1d7a8ec70bdff12d84d229245200000000000000000000000000000000019ce3c830505324b9bc7cda1fbb328150d71310f06a8424dba861d67a7bc0428beaaf697646d22cae9e00477cc8066f000000000000000000000000000000000f6ff67efefa5636b104a0351c90fd3e89a32b8a9beb0d123d3d6ae42eb5e8bbc19c7a972e27762daf852259c65fce6f0000000000000000000000000000000018d98c43fe5b13b701749f4a5dc25f0e713d241d573639fcc73429226bb131d448283338a909670066045c65789bf9e7064a6af51c1d499c4c28556ad1255af7467bc750bf2db2842d626647bdb3346100000000000000000000000000000000003cf82958d68429503265dcc7d88a3763cca32baefe3c8d32564cf30e8e6b8255d4a9f6a76bce1da473b50287deda74000000000000000000000000000000000bfa9cde6c06b2a2ff8f877ca90b3827d0aa0408c4ccbed23ad461433dad71017d4dd387f49c5febdeafa17d06ba784e000000000000000000000000000000001770fe70513533d91c83449ea52964cd8b449aa81f71e71995db5b19ceddef18e2919439c80e10086e670be669696e4f00000000000000000000000000000000194c20491c9d5ed827cd9d370b9bbec55e4a7b1c34ddd1d80201e7019d9487a747b4fa57b480dbdd09af73aa4f5fa0e9a3daea5a083af43711fcb09282b66882ae5b5b8e1714e9186f33ac0dfe48b7ca000000000000000000000000000000000a79d9e0ff43249ff54526c5e1cd55a9bce93adf272508871326c933d526602dc9dae5b6f129a0f1c38139ed1c39be5c000000000000000000000000000000001458b554e0387c1ddb9dee9f4e9fba9c81c15807f496442f4b7210267912b9439a19f95dc80a1e09a0e5cfe750f43c8800000000000000000000000000000000012c06b19ed4e8d5d1b9fed56bc5bdaa3bf0112db997e33aa14899d53e1bddd6aa91dce7e9d25473b66b8578d398981f0000000000000000000000000000000015369b2228e728894f2fd7c2d8c41ac3550da4f297de445cc0f0ef7134c478f526987643cb5408a0bbb79f5f983c085ebd682acd154f6e16a583ca4968d28471653375ef79df078b17b2cd9634258dc10000000000000000000000000000000016649a8231407074af5ffa93f9db5a2ddce8785be8ee77149602d6afa24ab30b26d2f74bdb5f7464333924a817e242e50000000000000000000000000000000001b990f5ed0b23e113042ff004236646c6eacacd99d1d73fe0c3d9351ce8d622327e827b2c0556802c5657f8f06062a4000000000000000000000000000000000f002a2a5ca90285f9b2fd429721c2daffcae5fe48c571ebacaf475606f96cc8350ce88a850ed75e5aae59d445249bf00000000000000000000000000000000015157fe1a767dabc185a8dc8fea3cb208fd995ecd9acab762638faa987f8367ff7c1a60b657be6e9461acc9df16381e5562223d3fae1d303a01ee4642fb4cc70f21937ba7fe377260fe82262a8455a7700000000000000000000000000000000073884ffbe6deff99cb4b0ae1c0e91e2f4a8c2c7296339b1d7e117d5d47ab055743d643155680740befb379a1dcab666000000000000000000000000000000001995bdc23991dd4cbd973e915a16691fb860490bb54011384c553dd14afc37fe673d13950c1e7eaa29c324fd9304624c0000000000000000000000000000000012197a19a498cd94ecbb3a409337b04e76e1a52715c40203add20eb80f7eac66f3386242d51bea34ea016d778248836f00000000000000000000000000000000101069ff0af2ac4dc7a5bf7bf7b56d82a310d67cebc41a9abf1e1af489e1acef3e726fe9571b4382777573712663e26caf1d0fdab6185e1c3f9f621ddc169ba92584db0b40b6ace7ed563eee0090629f000000000000000000000000000000000849b88e7ff52d8136a120f924b20b45ea9ae654a0fa037b62f3c275f0661091038a4c1d6ce7d50512e628b6b397c9f6000000000000000000000000000000000e50e82e9b368f2e316d41febab6b0f626d6588b7217b4e28eedbdf50a4abc9039be9e66c97790d12cdedc90873993e2000000000000000000000000000000000bc5d2bdf06fda1e1d1f5c5eaa7988dfdd790bf4d952f5d3a532bb59edf619dafcbc29274fd3661a35a3f15933b1849300000000000000000000000000000000162e5ce45499e620d0977fa26a291a8e75943c4b5a2a80be395ac9b89767ea5a06606d6b75ee4c8a286d2ea5a197baa5e910487c91f3839d5961f02a67f3b357206e406ba207dde969498e40d4a26e880000000000000000000000000000000005c11afc970544b96fc1a4cbb27259e19b5fd588d1be1c8f19eb4f111882292a463c951521388cb8cb743e5a4a1b57cb00000000000000000000000000000000013dc433dadc122376b75fedc923386a7ba5a363678fcf9edf165a50e160dadcc151b6f402648193d9ef960f5e401030000000000000000000000000000000001893af155aca343bc29989ec2b5a583d020a7558c7663accf6f3e40d0a8eb98ac548e933eb8e2d5fe3550927acc2ed4900000000000000000000000000000000043a79bcbaf07bffe6c6890d95c7e74d127446bdea51a0ba3adb164ea39684bb3ac552020ca28b86e34692c9b36f4384396d32c2c9ef685120995d2244756bd45591618597306193422f3b5df4b075d2000000000000000000000000000000000e6946ddc8a9d73e5b140af80cc91b31b9a226a945a9574f0629566f7ee7650730c5ed758cc30442770ed1602b84175c000000000000000000000000000000000da0abb9f5bfcad73b3f24903e9ef887c660447332e5457e4a5764f6628c04d6fe903679b8dc8bb3aaacde410812286a000000000000000000000000000000000656016c01d3405dce9f7d40e47976bc8a84abc370e7e42849dd0bd93ef1da0bc88e428efea43dfea37dd834cf246d69000000000000000000000000000000001939b2c92c8299d7ec1dbeb9f291c5e1c9481e10df10e6ba18ae695a780aec5a185ed4c7e82dc2bb5af87a74552c2ea32087e21d775fbc2c20dda715e46c9c4970394e40e991c78ecc13a2a5d0b0f30f0000000000000000000000000000000000942901572722e5005a9ef5f948c8cd6f557be8d114d2810d3cca29933a94de3c7658e7e28675c2a49f138d9c98c524000000000000000000000000000000001908e8b815e95ec07a90861ce53f545f0cd44aacc47df40c24d6cbc61e7b28fb91cfb1cb3c67b6c5b38c34fcb2ca35710000000000000000000000000000000017bad3616d8e510e325d9166790239c8c817c68ba7fb937fd5fb70a4219265edf6625b52ff26f0a34c0bf481c482b2c600000000000000000000000000000000023ff8a50a9c0e9ee829ec81972386ea012df5e8476d8c342df6b98fa1faa1382ae921c2f1018a918868672450355c44f44043002a94560d725da2ac44f30cc5f14f52dff5671c6689efebd803b1df7a0000000000000000000000000000000014675ab3efd44bffae321791e6fb35a24b9c07405d9985c685795df2db183ee9dadf18c76cf4095e1e0695dc2c08c4c4000000000000000000000000000000000835f2cf09647061ced2bdf4211bdaea408148100f864f47ff76c0c63a43e44e8ddd9e01709b6ad129bd574d71a1a63c000000000000000000000000000000001017eaeaa6eba76923ff27e5848e5f3b09e7b2b9d55b2cb7068f39defa8628d1c8cedcbb0e1cb5810febc4ccea712b7100000000000000000000000000000000054c873449c738383e9fc2f0f74a6334904171fdb704f5ac35a483ba19a8f661187d36fb35014af9ecf88225466c86e48624c83d846ad2e53f3f8ff5ffd3fca8723e6cd431e89ca29a4d662e82004b60000000000000000000000000000000000439ae88636244d5e09607960fb033e4217343899d044b21e61335425b94a5067c941e83e5a77f4b0690e1de037325090000000000000000000000000000000003a67653818cece3ff0390d097f1bfbea9ba954a85710f5c24d1de1893f25f2863991fb9f330e60cad725708e70384b4000000000000000000000000000000000243394c3459a3af236189ec6155418c1916b854a20b980ca1044b48e23b725dab7c60a48e89f642423c805c117e64870000000000000000000000000000000004c8c9fd9f278dfe9f5e24e0f5b42699bb9751b56520827afc2fae8393c690a63f10e92f77c4a10b0c161408da9bf505b2b2a8a42887ca6dff5b5364d88962068496bee79cbe74de0e8a06209feb38320000000000000000000000000000000011ba67024503301ec72bfad101a48708e3521c8a23c6bf2994078690041cf7eb75675cf5f20c8e82d11145e31751a2300000000000000000000000000000000008ace953ed2eaef19595cc7c9fb1806d26cbf1e888075e3985b28f8d93b9c0b4c820c8e8b50fd4e0b23923d428da3efa00000000000000000000000000000000054ee6f7247296e0748d0b52148a97b930e69991a242767d80bd6434d42b0865a64d3ce60953fd2631aef873d8b2acf3000000000000000000000000000000000077748b724301a8bc48efd1cd66086e727e9872e4efdaf55ba90ad1bed7e229a9cfb79013333b50efb46090ac0bdab488ecb5976f63a38d7f3d8c8ec441b705563c5e3d899870ab5d2ff84467fffefb0000000000000000000000000000000005008a1d62dad51132ad38a226e8abd7421392414acda61111c728713a2ece284b04d75c2bc58d355bb1d3061415010200000000000000000000000000000000189725b7fc48b8a648237021e9a2334247f1cf18ca50008b813978db01667ba08f00b23b3aa0e015f549ff2d5e5c535f0000000000000000000000000000000010483cf2310f64cf0baf556cb2f2828a1c15922547bec03cdb182a316aa86b5473f03373cf7e59a9a78f73193c1caf520000000000000000000000000000000007f635394301441bdc57dd1f4f97656f4218ebb139c13a17e12839091e2e81327f3353c56880c608de824a07a17b2bdd951f4960d6614b098249eb9420077ea5ad11e38d1694f4df33719d1127338f44000000000000000000000000000000000daf4090a229a1ce946064cda1c4b19c88100c8785c69f2eeec3aed12065787ab0abd797ceed07617d55a9c70ac3020c0000000000000000000000000000000011d77fc28355f61037cae3a8342bdf8d11e963495ba3b5d67055f790b1fd632b23565cad77a3d9968d364e4e2a553c9d000000000000000000000000000000001038d7e8fedea873c864b79d1cf8045485299a2bd4d26c5ab5c8d4a073e2c3fcb38cb230dc6ab7e8e228cabc6ed97da50000000000000000000000000000000009de9209ed14d62625ffbf770e8c528594aeddcaf1aaeedb4f3ca973e7b9f9f1a40370cc74b154f3bc641665d8e4d96b7056c7d93d8453be369831dc0575df6438db488780d518a53d19b8f5d22d506a000000000000000000000000000000000a6b0dc04591cbbb1b82a059e08b488fd66edca0f2d264c352f81cb6ec45e50f0af16917fa4727ee9888f84b6c888c60000000000000000000000000000000001369ae16bb0743f65cdfc8082dbe0d588cf8aa5406a095c3deefc27eb3ed462dda9dd4921cde6a1d878a805cd144515800000000000000000000000000000000124e08d4de6e831229005663df4e4bd5bb7af56dfb13244c50410e6d0aea420ba19208bf1a774207e0e0170ad3a9b4f60000000000000000000000000000000011b2973743034a2c362281b11a1ac1c89f59ace09f0a53afb0c2ceb061726c7aaefe274f6dc04e5d0dea2b687a00609a8aa982de1583c25307e9e2c8cf2469a0b1076c6be2fbf12caa8584f34988221a", "Expected": "00000000000000000000000000000000136ff52e440da609b6b73aa838f2eb9791221291b7b14d902458aa7aa9e37114c573edbe8cef7a98dd07275a8c3fd650000000000000000000000000000000000ba625eb47be09ac8cd1e2ec9015640f416af0e3e0e79d39ccac600ea08bdae7a2bc9144f13168a8cec03ce66b9daadb00000000000000000000000000000000095c51e81b5881b009b28006286c704ce3b002e4ca50ac8ea8e574d1e9665a5b1efdd60568d4a4a656ca6a2d1750a39900000000000000000000000000000000143c0c4b3b720fcd0b044a6f420961e2b7eb5f9f1b0d200de56ca8b02709d819f47f0a6ea7d6b49c4f30520586a45616", "Name": "matter_g2_multiexp_7", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000da4cf56fdbaa9004bf8ffa12d5cfb3f296ba5262dab079c91bdbadd6e41ee5f89912bffd5df1643146bce1f0e021b3d00000000000000000000000000000000150227356e48f29443a0ab4536e7a2f86f9e63840e23bbf1b091a59f52c27978bd6a15b29b105132298de45e51134da50000000000000000000000000000000017f5271c97d84f55f8b7ee0d73267bb69cdc7565c470a4b531f9dcd29596eaedf46e61bd79e71e5ade7d000c1c1d81bc000000000000000000000000000000001322812590e6c22bd90511ed72553c1cdb0ba83487b00e3adcb01a9abb438f365ca23fae9ee4a953544253696ddb0bf1a18ca15f0d931619363f5ee56bd7657b2298f228cae8d185c9d062910193e9c40000000000000000000000000000000007c59f94693320b01b56b36f8d1c39fc9e01bad289577738e648771d8940778276cdbfd59f07926e516fcebb70592de0000000000000000000000000000000000aa71d6dcb0b225526eb92b79891ef920634a007b87986fc0f776f85195ad7ec2d84b9bc684add947df8ff42c33b034d000000000000000000000000000000001362cbd6cca3d5c1ec68928be38aca5de1f224e7cd4f5c3ab1c2cd589bbd7c31022d4adc51720bedf2580d2acfa0f06400000000000000000000000000000000162bf0f38e19ddca9aaa370f988be9b35461d2a0f46143e8663f1fa549d0afa1596f029cf2f800b027b90d1eda6ae8a2b54274927eb29fea0cdc464271c918826d5249b2180a52a5020480d1020c9795000000000000000000000000000000000eb12a92fe65f79c646ba508fa615d09d86e582c3337ae16f66cd3bd74a9caa9dc17defb4b4e67ad62f0665c9ad1b6cf00000000000000000000000000000000058b6ce2582c46c0fc108a37e1d2713ff21ec8b1d8c18da0e69f0dfec7f2f327043e174e16d9d64f9ed4d3818a302bea00000000000000000000000000000000068192bd2ebc0a23092bb98c23f5792e179913c4ff1f23eb27296a77e83729803764b8db3b7ba4fe154ca467475eefb2000000000000000000000000000000000482b16e876aa90da6da35e0d7495a04d5b0a1d084c61821f23e1ad63cb1e66ef5975a3cef9ecdf2e696e9d9b50bf9b65849bffc842c21277be88dfae0040c54b072ff526731947cbec0cfe963f2d0dd000000000000000000000000000000000b712fffce3e63362bcc246da566a14139a3d12807ba83ab3520b0aa3aa20cecd5718e2b7e00f24e6fa705315bc2175800000000000000000000000000000000057a66fb12f27e4a5268e56805fe2b61b5ef019b31fcdd861e2b0beecdffe1a3a69e8d193815f97740324aaa40ce34a8000000000000000000000000000000001080a9e1133f37288dbc3835e45b6611fe84ec4790e23e5ff84a2f72bfa2837f55cae9177e5a3a918adde777b7298a9200000000000000000000000000000000142dcaefd73d7f6342e87fff8c6cd161389b6049fa077f35076eadd2b4aa66f3a1819bf8272cac1c28cc02bb6440dc42aeff769da1b62fde321d46c66f8ee7f2129446d805ab7f7bd586268de8f57c4300000000000000000000000000000000034c0f8249d6aefe4cdbf84d151ea9f84add42ade087048bbbf9de4a412cc805dd9b608fdcfa34fa224066b5f06d18630000000000000000000000000000000009e235ce5eb936bae00d3fecead8859e6d909da3d57bbe0a8aefaa5efdc94969a1cb2e12642c0099bca4e7bbf9833469000000000000000000000000000000000b6fbab498c2706f0efdb4effaf79218cf4b652a5205eabeb84f05a060da8cd18c8154a3d37594485ba50a8228f27f6800000000000000000000000000000000130ab70e17dc73f773df99cbe3f978bcd3fcb92a8226a1450239d209cc6969e2cecdc0bf3cbbe9a9c1de072bffbccaa952c9e56cfe957b924c9c0294e1c1f12474331c662c8e86288c97e6a8b8b5b20200000000000000000000000000000000031a2c10e95b841ecfcbddee4b458385e5650dec9a2d1e50216d9fc261a9829eb5fe894e47f171c8fd2f4d5d89771341000000000000000000000000000000001378471c7f770672ee82b70fc87af5ccacdf8995df9ce48aa9fc2f638105a2fdfa48b615970665ae4869f1e2dc7988e8000000000000000000000000000000001969517c503df5560628555a8780138e4c340d9d49d8fac4a8a11c894d283d49fd06aa81e9f0db8f015d9372762dad75000000000000000000000000000000000f5c2d9b7fc33167a6e9b5a5fb8c5d16ca009282edc05cbc8a048b835b16ba33515c226174d6ce5f9836581611ab403bdecec569d223c724d162250ed1d074ed9f4080aaae3f44b77df05292be48ebd90000000000000000000000000000000000a6a32f2006c4b7804e99011d934ac91b1b3fa6f5d02c574cecd6570bde1e998f135449dfc148aaa8fb8757d0a7299b00000000000000000000000000000000198beb461b59f57b85d858b730fcf853d967a1592e5e5787fd81c6a3d9d9b40c1cd7912cae21a47aaf78df5540604cb4000000000000000000000000000000000955701e84721866683b4eaba82c2df8a89bc906fb0a3cde565d314cd7278b0c56936205cc8ada10b03e69b93c48067b0000000000000000000000000000000004740253653a0d6cb15c76e145dc0b1f811bdc964f7d595b6027bb012b42409deaa8da83e6ddc3f0f7b4b237eb62b537915ac9453b831c41becd3c1f412cdf5379e9cd5c80bc6df92ecfc5005356d2aa000000000000000000000000000000000f88e1e30674934bf1062ac619f1834f35f804a958e82121255f8087ae08f10525e740ee53d7514e0ee7c49e324513c700000000000000000000000000000000019d554645696b7beae881ef62297283c5b68ad3fa9a84a47c29cb53449d33d6ee7a5a3cb83b6acb75cd41ac3f52fec40000000000000000000000000000000004b32776966e52e8a72c88a689d6c56833296d384e2059d8f615ccd3616972074987f839b4689d5610a88addcd836d930000000000000000000000000000000000fd4d21b00d81ec993d2350f1fe360576fa983754a7159c2e81024a00931d84e419e8b5231ba8cf8f05a0ee6ccea7e558fa60bc7cff4edde18301af2348faa69ed4f31d437decb7d4fe51142d179e6000000000000000000000000000000000177830cf34186191fa295b7f279bc819d8a53452e2114dbfe709971584ec7a2da7453aae3e64f4b14c261e22314027c3000000000000000000000000000000000ebf2aac35fe070403a4b7a5c2f102c67300bfd68af7863b45185b37ade1bc53d46772062189f348647e74c77caca4a600000000000000000000000000000000128dc7846b2dc5c453ba5fe4675d0c22f4d7089624ede05b0910c34ae623d4671979fd73455b35b61a57c51fe2895adf0000000000000000000000000000000008e33a3c3735be035b550613c712b220595a83c1953b24b3efd38c5913fc23df823e00ae5a1c2ea8a8eebbb93c5c721dc29be0b271d4e22d39e9e06db9e50845515880f30c5bfac80bca39a2d8d61ea0000000000000000000000000000000000a060a957a8da4384e3436110657110653685bb621c32810b6516c690a00c13e37f70185958beb0ed886aae5cdd611a7000000000000000000000000000000000b5afbc85e274049985eac230b2aede7b2df1485c9539a4a4eb6aea406d0f6515ad8bbece7155fb0dfb2123919fb8af9000000000000000000000000000000000afa722987390440a33d5103445dcef42cc4a3c461daa076d56fd38e0b220016ed2bb8e99b9a8da4af96b7da64ba90950000000000000000000000000000000013ea6b8d327191e53bc71fe43fda305a4a0584cad04048afc0480f179955cb27f2ac8791d847036470ffeb47aae36877dc8c2e971a3a4b9909dcc5cc6a0de50286294ee15f441521e0f1d2c3ad3a76e900000000000000000000000000000000032b490f795ac3242b8c7185c9e19f0440ecee3a65263dd4e4c9a431571deb7339bc6e2d73ec43750f6f027bcfd674c400000000000000000000000000000000076ab4ab3e8ed6ea3b882fde5cacb3bd094567288699e11f368c3f60f4283c5bcee7b4c5debeac541ead983f5936d9f80000000000000000000000000000000012aa2060e421f4f4249e83ca0ae1752dfa2b7ca958821841a18f05071a35fb9c1448619bd96f8a7adb2202d3ffda8eb30000000000000000000000000000000008b24f29ee7571f31ff86574e654a5d849acbe92653ae1a1d2baf4c9ca6e67da4937bfda51a70931a6e60d90162efb4f21c9ae0132a4886820115e71e280d33378a04344f635c769fffe91e89fa7ea47000000000000000000000000000000000c8b41e5c47babd6ea113c0ad9f45a75d1ef6bd313b768ac01e6f581ef6630ada623c1a27d4aadf543af4055de7f6b73000000000000000000000000000000000a0f73af06f8f0115bf17f7c5db0a6bdea77a8e3d8fd0b52b0d4e2c558f1331f655dc272c86d98bf166b532ec8e45285000000000000000000000000000000000499b55964186bcc6986e7744c52babf47e274e47a202abf6f816bc748baf846df2b5ced2a5f61fbb0aa2047bbaf82db000000000000000000000000000000000d6c2a9a3fa5d0524f772cca2c7e72a5f2da1a6a1b9550997e7a6cac5b6b6c37693a01d30bebe4b9c742b63bd31487a1e1067c01d5565d0f387516d9721f7f4e5253d5af8353db4a55500e20a95f3c9600000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682a23bf766a1e1c068e6e8e4b60391583ac197ade53caf0f8a43c53d1bae9f13e500000000000000000000000000000000134125416c7908cb4454ce6aadb30df46042ef2a6b4b69b19fafcb9ebafe8b5579046725590266cfd10fa26e1b5ff3dc00000000000000000000000000000000073f4147cce24e13b9eefad7c69b457acf126bf278a58a26a7c7c6b482edea6dca9725d7e5e4138b4ec81bc2505ce2e60000000000000000000000000000000006125caac1061cd6c556f4cfc122df8e949622a46ca707b48ef088ee5623df058bada1bc0cce1399f0be1ee86225f13000000000000000000000000000000000146e398c161e29c90c8a4fc44bfd5b3dba6f9e80ead561fa3d91ca5f416e06318dddcfe5147ab5def858fb025a1562352c505d4fd8287a897e01517ddbd7d7ea9d26ae4f58fbca172e5265e2b62858b6000000000000000000000000000000000944942effc77ad02c5ddb052acf86f3a9dc4127dd032181450295464b49ac1dc0047790acb378221fbeebd4c92886820000000000000000000000000000000018e1d201b38d88665696ee6cef11fb19f7daa7f11c5a5ccc73e6b66ac7b89df8437c9f07132ec8b69e13f63424ad694c000000000000000000000000000000001463117fdcf17f28956a42677b3ff431cc17ccbde067b91ecd6fae51e1e24ba8d594ea368d041656022611ad3ed44a6e0000000000000000000000000000000009715cc5add17395b7ddbcb961269fc5d4739d799fe9554b3c9e9f59c895ca5df8ec75bda05cbef3e6a165f7987e78662908006c06ceb9188651c59d434988cb5b51a5a75772ba71875444c65ddf0f4f00000000000000000000000000000000007c07cf1ac9b8b28e3d2f1f4ce22b8ee46e99914ba20c7362c679559a1618a906c6ea65c475ebbeca4947019cb6fbec0000000000000000000000000000000008b29f72cda71e0bc2246ead57b2f758b741b9232d87be75331275a5cd63afc9aa98b0e42c1b82cc258e93c97e596a81000000000000000000000000000000001512548a4bbd537a4d5baf673fb76ea7e35b2977216e7b29a6375e1f92049d7b7d5fd5d8b4ae6191f5592b738e149a5f000000000000000000000000000000000cc9d646428135296919808c6ac10c142e769bf71bc1490196dfdd4e1fc7b84e58155bfdbe77a9e684622ffd83e97ad3e8e8724c80f3527de5f0b2b98ecdf0b8d0471e63c0763a89da8a21a70dbf8399", "Expected": "000000000000000000000000000000000ae9da7d12d0a03cca3b41ad869f762784cacb988eac7ce904ec9ff47824e058e2e211e2285f9fe2aed0b4385949b4540000000000000000000000000000000005b0c873d20f7be1410d39885ce4f79884eb6ae2b2f27510d6f6874dacf2a66c64e56b7aacac61ec88261624936e695700000000000000000000000000000000076c6076175ad748dd68fee64431e5e4ad013797de4528287e7226c3df90233799ed5c8b36848c1a2e1c02591a013d270000000000000000000000000000000001f7f6972121d38ee2d10c621a38448ed12271f7e0e9e4567fe1b5fcb469c7906196fe92c66c37f8c5abc91160fea8ae", "Name": "matter_g2_multiexp_8", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000139cbf360b10e59c20dd4155af2023d5dfe0681c62351dd541cbed41b6a328aa44b862d1985b132a4d4ca61c95b61ebf0000000000000000000000000000000004af6b5a0f7a02d5c93304be0d31959bb4b1a7a5838dc3f9cf50180c4eaf3d32e68c006263d75f9735c8f0b5f811d3cb000000000000000000000000000000001644937e5ff3b8d2005a2f3b0984917837d44412362a121be481526173a4c61e20d61076aa10b4072b79743c5f7f4c4f0000000000000000000000000000000009bd399b55a59550dd876f35e54a5803058228bd6ab6c9a66e438cae473c63816c96bdf378ad426a236b58b90e737831e14282bc687a00264b4e4678ff238d5205f6b6fcc10040d9b4393e93f76297a8000000000000000000000000000000000f343e5118d7dc3a38e9975a5f40084ee5f2305e45a8aed28ef105f76345d9f5646b4f3924b92978846b4e605b78fdf400000000000000000000000000000000017e61a2ecf9b3403b43f5a10a97cf5088b4f98e5a4513b0912ea7ecef44e6809f10dee60367cf2fe3e903dd68c2a97c00000000000000000000000000000000039f37f414338cab0e12f99b2aa1e3c02cbdee3406d1bd17c359ba899b7cdcff605f894530895aecb469f41628c3da120000000000000000000000000000000001b78bf69f1b7168d735fb4b7b135fe70db79f50e792eedea23f83cee9b48e092536c2ed146c7499cf047c5b4f0a08735307650d6cfc681508fc7b8dcb5291837582eba6588132f46ab8fba674a1f5af000000000000000000000000000000001342346f1b553e29e661c9f6c0a24d8f788db98262d6af86af55d313a37eeabed1183e367ee3d83faa3f284b260e786c000000000000000000000000000000000960c8af3f7e6587cf83baae447491e73cf41e637e1efd730e3acd9793717e57b85530584942e7a030bad3b91a76996300000000000000000000000000000000166daca4ee2cb9516b5178cefef0553115dec8157f6194d24d191cfe6340406071883c89246c0cd5f89bbd5d0f1ee15b00000000000000000000000000000000187f668086b9b6307899d301bdbfec915cf24ac0be10d6897b0677e4f1de6a241f3dfb19225644858be0941530e67d0f7d6a25511ba63f0b7ebd2189cfc4c551083ac92b144e30dd81d27e59dd86e22600000000000000000000000000000000032c3783e701bcb651aef40c91682eda03f9d90f252740612c85a5727f8bcc41a886b328d5ce787031c08ace235ff465000000000000000000000000000000000b0eca06f9fb69ebb46d0af56d3d934b333514d7f31208b4ee2fb92009e6041749028a78246a0adc324034a94503e80d0000000000000000000000000000000019eb24ed35f6c7ae53047814cab14d51ae6cf336d140a17e794d5cf18450b7fac3e6f990e12d340291459197bd353861000000000000000000000000000000001983a596485e657deaedf01614dcd5f4ec515c0050e8068ea02c9833d0b165c0f467107a50da0d8cd43bfcb59db6e710eac8e5cf13de6db37982390c8b6b0474795f479584960748b7ffed881285e2df0000000000000000000000000000000002f1c29ffdf7bf20fb8a13363393d5f1cca5dd9af82888f0102030fdda641abd5532ffaa2669c0c4159a989cef1c5bdb000000000000000000000000000000000bd548079899d49cd368bf5c246aa168fc8c777bb84a7930258502c8424a4b68e1ab20dc9ef39c307e52bcafadb0c8e100000000000000000000000000000000070c18918f037d5fa1aa005e2c80ce6a80b4b24d33ce72a2bd824f9a061af1db236f04d6041314310b31b805b8a674800000000000000000000000000000000014422b173840da655aac6ea4b7a04313d5d0675bcd565258c73039f879176e51ec0c8a9deba9c78c33179a5ba54492012c134652c27da0a0272b0783551ae44db6bf592ff299b48c50c550367d470b5b000000000000000000000000000000000a1be8e39a47dbe0bd19b8108a5bdac582e1d11ef7fe28df1f12da52924e734e1d591e8e33ec20c6d5af5bc8c1161fca000000000000000000000000000000000eaa7a7cec93b8d5eb933103b52a35b3d58214feb8e2de0bba3a0e57e7993a9df0dcf8089142f57f8e0d1d303588ce9d000000000000000000000000000000000089fbfb389ba448eb77722994178ee3cfd15a27be4ed6f4d4ab6ea1a4c10d6ee8424beb17d08190fb18ab8498d4a4fb000000000000000000000000000000000ab02df2eb474735e28c45b915299230ce159816419fe9c99a7da397b7210590705262ee14c2a244f4922c35bcb119338dca9ff432bb483ad726bd20cf96b07ab6f07170a1449f0f1b50ddc6e1a0253800000000000000000000000000000000006508fbef44d36cdc6fb37b6324810ab2a1d94e39abdf09d530df34714168105e23a7d6f7fd9caf31f263b658f16b76000000000000000000000000000000000b5bb1802813f9f8a16991d41275ae6d18532e3dcd2eae091da7256aaddd501855e775b779959fcef2822685725cd43b00000000000000000000000000000000052146ee63ae277911fe491420651a96994a30c7d1b19bab32eded008a125369baed2ec5a963bfd863a83c29bc1afb23000000000000000000000000000000000a180d79335347a8be350a92491760c6bf1fd56604d4d99a1c49bcbe50b2d04b7cdde55b4aea8ddda4bfeb8e79ab6ce4146433a0738ab1b044e059f49a8af8d85546d0e34eaa0edf2b2a6ee466c0def80000000000000000000000000000000015dcdc17a9afbf88b54af22ed2168329bc43ba50d374c0507c790f37f9669d0af167328d50d322a827d45f39724d2b2600000000000000000000000000000000169b83f2567e921a4319fc03b2a7eeefd2aed79914bf608d9e0a54aa71b9cb3e09f1cbfbadaa520c0f77f547fd407ea50000000000000000000000000000000009b7a8ff8388c85a0fe3860f26b09b81b5dc51e00a8961fdba96eb462e1334e9e28a2cdc4be49dd8b96c548c64921718000000000000000000000000000000000243782436fe7cb20a3242a3a21402a43a2c4fcbe77cc7182ee3cc04f4795c269d8a64ddd25e89ba4fc796747b608092de0399ce1ed861c0ebce1d4e811ea0a3d87e21a54ae34e6b5e1284cbb94973680000000000000000000000000000000013ce6856b6df48e4c9e3fc0be0aca5b139e1b874de6ddc148c1c23a846d61e7a531cc889bab99706668a3b69d32b9160000000000000000000000000000000000a459676071c7f3065a6dd7632edd5842db34aeda8fa0e7d7a8ea29f842ebcf2c5fdfa74ee7685caa51481c4f46952240000000000000000000000000000000010c1d9ebf7bed9195cf0bfefad6ba45f1bd19a9a7d340b7c630b9953923efe4907bd75a3da066fe3d49d656f3ed91d2800000000000000000000000000000000039189de73332d5b5a160c296a195cb9d8a736cca23a92948d513da7e4fc46e1ed9c207e86751b3cf1310d8a7284877ec2b034594fa53a0951e2116db1b063345fa42dc8c870e1146f1b00f626dbcfdf00000000000000000000000000000000129821e97c65ad3801c011792f4c099e19919d7d03bf9fcba30b3735586bb7ead7d4f9bd10bc5f0e5cf1dae82d5651ef00000000000000000000000000000000038cfbe45bbdc494988a2dc72dea6a7e36652f5e5a2ecad41b4aeceec05dc4a389e54cd3aab349adbe32e65206eb481b000000000000000000000000000000000bbab53f2be2c471d6e9cbad719a73c00b582d0983e25e1969c0be1faa56b1dfa5b7b55797b3340cf8c7eabc560fac71000000000000000000000000000000000b0db19410e552a2f7889c2204a93c5cfc71c360329e3be3171e88fc7aa1e993a5d089c28b1a8f8fc80d93ba194c63ccc1e6d9c5f8911014f0f540211af5184d96fdfd47c03bf2d7bbbb3bf1a330017b0000000000000000000000000000000019320bb8d29b7b5a7130b87a39e87e271b96656b5a2749f13208520634009c26f9829401d3e21cee5a757782c6bbf9ca0000000000000000000000000000000009b37068d72463e72f3a89b9093c1b09f01770e647b5ff7daa50e0679bb76404cf7729d5575a39f5b9b3b371893967df0000000000000000000000000000000019ff29e41db50c736e12f62d76a28f4ca4f6b0f4f61aee00cc0e9dd4e5a75c0ca965b82698f704c604bb309aa5b457f100000000000000000000000000000000062c352a554dc4bb96b459378c21ec6446e15b868221b2fb745d31dece854bc281bc22827d84ea3b0fecfe5d156712ce6df5a133d3332e1f79f41201f8cb2c8c8d4d1ab0f640c4de6bd6e34884a77aa200000000000000000000000000000000021c52e82b0012537b57fd92fc276e8de842a59355cc15d69a52effcfaa7cc43dbda0c34e1b9af44c2db8e9356b9c71e000000000000000000000000000000000371a6da5dd39092b6108f631a0f4c4401464a109ea1e5d14e262c8a9577e1421d41734d2c3ed73645cc13ef3988e9e90000000000000000000000000000000004054159263ee60f6b1882ad7c376c738c7ed87e6b34dfb4be2fd7aa29ede414c2c6c3ff098c53f22a1c1cd836a6b0600000000000000000000000000000000012d7af6b57c688e1ce90e9f2796b0e525e775fcb6be65f5d2fbe3d1ce1e5d948dcb098c98d495a6e3dd813527b4635258e7219a9d431c597fe9700d43da8b545072f5a27a9f1af99053ac0494087dca1000000000000000000000000000000000e53128fa5392dbae9e40ab1ff0149d5b577d9d30dcb85eb5e4fcdc17c7daf2ff1d6fafd4a1aba88d2e7aeb45a01afc60000000000000000000000000000000012972781f214511e9b78d276767b1b64bfe5b43215c7680c0063b6974f703b209b2929470dbae16f9767a7cba5311fec000000000000000000000000000000000cf6b37c5a60851d03752f68eaeaf37ac67c661f644cf507c5458cb5404d0ce903c92ef66a657b25ce07e5cf5d956929000000000000000000000000000000001835f202705c8b984a4c7a6cd219c718ab27a96671574cf7cb618235d19e9046a15212e0da6233f15f18bbe192df29c38efb8a7a5e48d5f4a011a4aa0dbab22ede62c903414d005d507ea3d77bd47a6c000000000000000000000000000000000d01c6e8e34e646911391b012680f0dd8f4b8d77c10192ac09ce57b6524f0eb8c7f83ff8f26d856e0945d7a909eb790000000000000000000000000000000000070fca42e34dacce0051f9e26c7c0dc328fe652110976df6df77af04202831dd095715af1714b60a99f2177e86a3443d000000000000000000000000000000000063ba43df0155373df59b009a8083b9f62004327b16ad455037487c5b8325e7eaf57a4d05c533e284004be6de79ad1e000000000000000000000000000000000870c2e5a7d26ba54bf0d45ddf0a4c3011152dd12a5e01a80e42bc4dcc784c7ffdb66f9d6d69ac445c1d9aa29586245147f53e2c06664e1daffd7d9b114e12d4190d5d0fa2244d61a13da915c39b8d53000000000000000000000000000000000d84ca02ffb6d3cf6eb27a143ece73d5bf006ff61569f0eab00c5a512c5b46e1fc21e8031d1a578010c9582d75e1faa8000000000000000000000000000000000a41249cf01ecd23d06f6a3bb8573186fe47e5165ec0d447df62bfc236f4c203b4feb8e2a4785648af86646cfb0c4e32000000000000000000000000000000000244fa6caa86fd27e044145557697ea89baf718746711c8dde334a2c5ae3c73d7a0e04fed6289ddfaf26e47a9d26b09e0000000000000000000000000000000017db897060c0a8e3e5d8eca9970407b46dc2c2ca0c004d50a171450852f585268bfa8a379acd01b6d4685e04c0b8c106fb109d9a0a7b62c7c452bdf0a2853c4bf65e5439fdc83aedec8c0bf73a16b55800000000000000000000000000000000071e13963e20eb1dfb671aa4a090973e4a4b7ad3578f8630db8a865847be46c796e6f9e095a9ce558b93d702f8f8572a000000000000000000000000000000000dfc4c89ceaad07e3b4c35d96e8534122ae48421cd4443de478ddf9a8867ffdab279ad745e55c87b731afa7700bbdb110000000000000000000000000000000015dd6b0c26f6821177d0cfebb7f1481a971e7601fb24ea365a0c3127a5b1042eab69446de05b61cb6ac0576752f87aa900000000000000000000000000000000156326c52bc78c82f5cb4aec5de35e3c128c5561dc80da2cb24d68a7e912b1f2dac2078508fdd4ec38769102c082f0f74b0a931b894fbe61115fcf52be51d44afdcb96c94117c75adffcd8729b0a699a", "Expected": "000000000000000000000000000000000b537dc10a6f518122665f7d78326a4728a2889325e5be7da7e25e4752c680fd786cdaadfcc426343a9844efbbce8f2300000000000000000000000000000000085ba3a04aa8cea82b95dd994f5b3bdf0dcf63f13909aca2c2d61e4275a7ea22445c953b927ebc6b0987e98b553469d40000000000000000000000000000000019cec2e9fab640cc88073bd39e46cd571324904b1950fa8f626e2725936d80daacce2487f46ad23fa8af9c6ca0367fdb0000000000000000000000000000000007039a0e11cbb8bd940eaf4a192bb94ff8c6d6c79f775fa67821b5ba411641c09dfe9fac4cf45eb5fae52d2fc4beb6bf", "Name": "matter_g2_multiexp_9", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f73a297cd6444809aa11b0756167e71986ab31b52b57d3c0aac5637129b8702ff21ec649541e79644c27f0017c8ae3f0000000000000000000000000000000016f96d6ba02aab604dd918cc799cee61cda4c0164ed9f07d4932fc4ac3eeb92b1e6b40dd7b18cd8d26056b486e57ed290000000000000000000000000000000012156f3ca3aa1e79014dfd92fbb6c785cf0ee449a8920b89ad04355e0fb7c8ea804bbad082b4edc9abd3b24ab0df2b61000000000000000000000000000000000d51b5f62a6e70816d7671bcfc52f11bdac6221a23287286af78605b99ae8bd0c722e485bd0381b958a85f61e05de68368ce22e379ddb8352d12eb597c179c7089c6388542909876c69ee377b14054e7000000000000000000000000000000000acc52d0fca02c3228cd2e5202c4eda297b8227bf4e64308226bc487e5b64738efa4c07a3738397f90251ea9a1a9da29000000000000000000000000000000000b85b853826a28777a5767d5b1966ce12fa8999ceff5d6deab5c947fd19d19de9c103bb920bad615186d132ec22187320000000000000000000000000000000006b5a83827dc7b3580579ab7976a70ee160b712580919b6f5d4e180165e50f5a1698fa7cc63846eb1f5e6df955c3eefe0000000000000000000000000000000006c2957d8adc55931900145388583e5c2d5f6bd784e022702801c38534d2c92c6df9f95d022aa6d800e1e458eb7f313061529338195b665f1b80c4b95b7c3a26a7229884be1f4be9d49e1274a9ec3f810000000000000000000000000000000014e4c5991f9f2ee262019c1344a0843756157dc85aecb15718217a2fbe23fe0843992dcd3953ebe79acd85517acece0e00000000000000000000000000000000076a18fe710aca2875bc102f21782c9649f107684a4edcb0c4538f1a2890a2ae5b46a182d5470e620375327965b6d37700000000000000000000000000000000142a0fb19b28a034d326121458628356561e50cd3a471ee78bade0733597b8b90f647f5199d4b5b1ee6be4e1870bcd310000000000000000000000000000000018f8b5933848813cc2c1a0f079b095d565e7875ba6693eaa10967d496fb47257c9c674f301349dd8f2d22f8857f9d5ca44d740a72e6c8b5632314408022093618321c8c0a8cf2fcd9ebacbe43505a01c000000000000000000000000000000000db331d2b965dbc053b01a61e671d2ee6b04b072b6494e482f48f12221f23e3b1ccebf48046d92b4be2e4283c77f51380000000000000000000000000000000016704f3e1ce14f49df400592ce29627833ed1dbb91ae5f00779eef94fe9ab313c3e7c8da940085034e1a49158043599d000000000000000000000000000000001956d492f5764c6de0b8e9a716766c762620ebd3265a95b47a8ad2c0614c337692108800e22abbe321d77a6cc17f4b880000000000000000000000000000000017149865739d6aed0f2a4c3c71c2d02f8080d9339025b03f89a37a165fe6e5a4cbd489b5fc90bb2cc432e5baab213c8424872a78e340ccb077259aae65d6c448fe6bfb64daf4e2b6ecce2cc9525e35a700000000000000000000000000000000036804da102cce975f980ed5a69e0464241b5de87238f9892c77fc2b6e5ceb00d7a37a45b5520fce5f094f8b9510f49b00000000000000000000000000000000049da8b6c974f2d680a80d2007333f15702f1517d3dc11395662ca1db945c795bf64167840c4df0fda68a69e127b2d590000000000000000000000000000000000e94cc66f1ffb2112e37cbd5b4feb7d65032c2e57260504a42816aeac85648558f6997ef12028655103a8cb9de1297d000000000000000000000000000000000abf7703ddf6995d5c29124ba9a3f890854fe0622d547a4f24d6a60b036ec9e58f7ec2deca5a71e1fce2210cf810e2f901a1d84826bf78f493417a06a800d58dba688800026638316fcf9ae534436fc00000000000000000000000000000000008d22e456c643ce680f5ea14553a9c249a43d4f92d94135dfec85bc58967ec01135507bd8ac3954b5876c5bebcc1179800000000000000000000000000000000022029d4abec7fc9ab3bfddf2f462660bef7449c4093144d9b7d6f9e84f4f1c947855ca6e09bbb3bee4db096978ae0dd0000000000000000000000000000000014beddf6a3fbcd621e2a592e1c87952ed277163ebf390896f7c668944d6e0a026d3df74b0fc877ed560527a80b981d1e000000000000000000000000000000001414af918645ce0d4d1f670333fedf286b01213408019e327d3cb9321f06fae311b598c2f78bb578e85692e6cb787a52c5a3268a8ab5a12214b266aaa4eb562aa05dd19575a7f3ba2d549a25f1900cb800000000000000000000000000000000129f1e25d96b8c879710a81b727b31d27ce9887c245bf908a3768f3606870ca6bfa70dbf5135819d36582d55f230e94c000000000000000000000000000000000e91eaa33e7cacce4e1d6d0fe905c72221b534a72cd51e1de79a25ef0c06ab454a849a241c023b0f82aa07de28e35869000000000000000000000000000000001379e390f2f0f3636312465469b532d876529d58dda8b024b6b81d242af47b5720af4360d5a3172ad80fd9fd8a14ba2d000000000000000000000000000000000775992d5a8ae0640af845fae03dd0b2197699f413f90f6130d21db0dab042324094b36acda26ed86c65821d2d8a29d9e62a7b00d2be967df04ef56121c95c8736efa95e1faa0196e1f4485da82b3c3c000000000000000000000000000000000f5420156358ddbabf31fcc94678866f899e38747e79dba8ae280704c4b199a03eb423ceed18b5cba7e7ce84583c84a0000000000000000000000000000000001127669ef3ba3785a859aa4e942e8fc3181f2703b0ece6ddbee8830d7ffbfe498794f1ca2e67c3ad39ebd33e838dbc5300000000000000000000000000000000138113386846310db8e21fb8bfe40035cd89e51736b491d5f2d3cf5672e6836c25f62eab80f25ab49d16dbb83796aa5d000000000000000000000000000000001711d74ef4995b473239a574fb8ea6edc6eb7a88793a093df4652da240d069c5bf9249b58e9b1e11f7d6619cdc28a5787a883bf845d1ed04e0664d814cf0b49cf8c3e8b8594ae5d2834c753851ed7803000000000000000000000000000000000d32ccc6598af8156f1c5b35e69e7c7f57f9fe18748510605a2a81b4ee09882bf3fb26abf50206cd57c77924ebeda8010000000000000000000000000000000009043d364e0637c60223f9a5db8c50e983746fdf4c9f7986d27f5f4f3a6df487592ea42078f14efcb3eb1b7e81d058eb000000000000000000000000000000000233495c4961e71cffc2abcde4007c0d587687aea905f3ac5758d0f8d9020197adb6f9d7b86a542b8efffb05dce997130000000000000000000000000000000015b084e773e66ab1459825b6e6dba055a96e4dc1d94ac0b640e906e0a9f12d2124a58537c458e6e1b571311b93acc26c0f474e8f4051c4e91124c14895fe9e2516b315d805b79013caf830524fce8880000000000000000000000000000000000e4b859c679a90c03ea4d4b0b3d38211f685db053aede0f7f359f712e1ae808185758546877502d57200da2c2137f37100000000000000000000000000000000173b24ca19436b51aae22838674c41c752536eada3197de6efc98303eceb3e6e8e47ee6679e61e3cb5c8c734c96c98720000000000000000000000000000000005232b8c97a4860a23999d6ed6d173d300ed50b77c7b3ceb4e8407d9d6877a6004e2f76c553bf458b7cfd8d1e6fd364e0000000000000000000000000000000018a115201e3f4eb308c16656b3ca0635e6284169cee3f28101903ce1cab0659c3d83a449918df6e58e8af2e001036b8d9b3a5790750825ab75ab7422f833c671b95c6c58619189db66a6215ce907381c000000000000000000000000000000000131232788aa3038a6b8a055a896af4f8129e3dd3397dfd90ce86b3e09a775e5b5e19f4387f4c02200a36bc2a1e09d98000000000000000000000000000000000eb8cc0455cbaae97dfd05c1246d3d5ee58c286d263184ae342f5c0ef432355a574bb9fb8ec67634f999b6d1419f2b6900000000000000000000000000000000188b8a85a6b255408f074b3cab66b95e0e1a1b5b8965034246dcc196f2bb84aca3a78907409826370bd65cd4c4d0bcf30000000000000000000000000000000009603984f6d9876e9c235621fa817efe45727fd8c4f76abb7b0796ae721701161b39ff7cab4c57850014e7f1750954ab6607a48ba3fa5c033a1ef90260ada14ee50c95e5167bf801ddbd3acb77c3b3880000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc67030db724eadd2f487d31dd4354b5c0321a7983aead21759807bd893217c4d40500000000000000000000000000000000025809fb06c8a31f31ca5b4a5c795bc93355c78d9a2a4c1d707e32ff2a71d94cc1bf7b709cd5d6a183cb05fb6b5f360c00000000000000000000000000000000127bd8c9ee6388905ffe59bb0fec0e42b4aa44be74e5961dc2353e474baabfea86c41c6173db413ee28681a6bfd3ccbc00000000000000000000000000000000181f40dd8581b9adb2981dbcae27c7e906138569ff41a833ed3e6ee4fb0baccf2ccbe5b28ae2ff8e08c4f534116b58c40000000000000000000000000000000005cdd822cb47f35f31e0cbc26f6c957d51c6880369af94fd84daa1f1ca95e41e240b910f031585842fd2dfb170d618aa88e71d0be8fd050f6dbb8b2fb3ae2a9e593bef7a5163255aabeb07282e8793e30000000000000000000000000000000004a06984a3916820368076ab8cad6ffffded2cf1e67ac33f539ea8fc7a79580c1969e55b2a2fe3b31de912d6606c20780000000000000000000000000000000008a1152a581b6fad2a23aa8b0b51cbe523e701193207c896d08b99a672dc047498e565a568b79f8f9188767ba95212be0000000000000000000000000000000003539e82e5b88ef660b6593fdfd9591ec23e7109642f4aea0570f1f8f8e00822d2af277632ba74910459535b35ad47120000000000000000000000000000000015d3441f621c7e6922c489e474f80ebeefbef66cc59e4350b6f803e409034b7f498be2dedc97d902590fc1e296fe983c26989184bb87a586b8752733f9ce9ea06422c6a898f0f402cbcf760a7a21c95c000000000000000000000000000000000f775e13276c2e32dfde955009422557f332fb42dd9ccc3246d2b080e3ec44d910aa734478899698a9b04f6fb1a8f922000000000000000000000000000000000460ee4df6dd0184bcdae6d53cb66967c2213fa878a829c3196664f8d594ca6d60bb2a56f93bda3b0d2e6aac0a1a222d000000000000000000000000000000000fc9bf81d4cc80ba4e4df7307f976c2ec1ea2415df3c263cc970583824cd83703aa994daaa6e5c20450da2ba90a242830000000000000000000000000000000011f08ecbda9a192b232e8330ccbccb16a26bcf4791707f2cf52c2e11a8b3993221666563a772d82f4665804275b03b613d1dd9cc44b30a4623a4d14861688cb678bbb8b2f8ae3ba140f60e64c05514b100000000000000000000000000000000027fe7ca0fdf1cab9a52e304e55350195492abecce4289b0f1c02235412bb012803e7eb59e23c665ea86dd4f74c35c440000000000000000000000000000000011301ecfc78ada92885bcba8af75da6cbcb448e0c49511f3ea306f4ab944f5bc114e72f473cdadee2d0e84021905c5300000000000000000000000000000000010eea529fd3162ad7b49638a70f6f2c26a6844251b2c2f9f8ba54cd334914e84e5a1ba9c7b4e7a8b9cff1a909db78bc8000000000000000000000000000000000b8a6235a7310d52fc8050bcc484e6ecf299099e193f91bea9db31fae71fbd14978984a9e6de10939d0fbba96314b0a55639d80f55e24e05e3d943340e324f6738a593a915a6bddb40f01bf12f73daef", "Expected": "000000000000000000000000000000000de312093622aabdc7523cd72f568060f4236c7287d61c3372bf81d9bfebfda2795c3182d508f0268d8f445f6ea0a5f3000000000000000000000000000000000b027f117583406916a8f139d47227bbea28502ed0df91cf0841345435376c944a587c3b4bd60f8ae0be7c7bad1c8199000000000000000000000000000000000e9a7b96136b26b0044b11288d35969c17146241aa529e581a8fcf000c33fcfff2dfe1e55c0fb63f6032d0b6b0cf81180000000000000000000000000000000002a442e740ee390d87ec657fc218b76adad7f6a766cbe8f34f4824ecd1587deb3706af77a95c1d5f8e79eab1dc482c45", "Name": "matter_g2_multiexp_10", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f54bcf1637d03854cc2b785e52bde25de7e45308048ed8ec0169069c2124871782bd9d26471014d039c9aa022e1a99d00000000000000000000000000000000106698139b096a5a79d43321ea64adb783011f04e5779625c9f77e5c390b46ef0d249387e978e64529bba2db8d7aef2f000000000000000000000000000000001668d5261a4ba37d79c76f44eae9ce2aa3e216c5fbf6cd2e90c6a73cebd8b59600303afce70de3e83a08c20de4609b100000000000000000000000000000000004b1b122cb55e688f8297913b84d466c6f3d99c09f4b039660238c8bcd0b7f6977851a6ea4b1deb01346db06d75180c142fe1e5b3c0245e5cfaa1ee8dd8ccc4ea8878ce2272d152fd8b24032297ac01800000000000000000000000000000000192a28dbc40d5ceee4d33b5c2778cacf8c3ed7d3227e7ea0d6fbaa7cd4a81134b63415f4f1960656b1fed15023ce3a4400000000000000000000000000000000138f296c45594a930b949756d0ae14dc9a720bb2bd9e93c7895268121a086a9d55c10135962a172c02da1eabfcb8caa20000000000000000000000000000000001605ef8182fa13a09a6b7661472296af2b0fdcfd7b051e7cf1d9e6d7c7f4ad9521d7732733399bfd5d09a088f25d215000000000000000000000000000000001928f2e5d47d7273e035114cbdeabaca724409a56056b4e95a4ca3b2222716b3a5368da3ed406d73f43e9571d1e04902253bdc5565b6ebc219a75ab74dc5ffd304c94e67160389f87111899ac07a71b70000000000000000000000000000000009b35f132a903579d82cae6a321c1ec7fb0281c3e82e9af05c3b2830ecb4a941da5b1637c1bf0fe9a39fcc9ceb0d09d8000000000000000000000000000000000eef9c0846064c866ae07b3709091b8bd48bb6b20f995b44fb49e030b5cb6d78b7f8201704b53697190a5e36e9a4541c000000000000000000000000000000000a98a5d0d5640d6399a3580036f0e5cd693a7cfaa26438a00767d5ffc0777b83c516316d9cd4597cf8601544038f4d9a000000000000000000000000000000000e59541068a62f105a0d26a5f79fa5fa8b41b2211f1fe674d84dd853663962d64a7f70e785b51ac3cc07267c73400fe6acbf64f93f6f85805517ddf0358ecfea1fd58a3666b8dd9d3773a28590fb8a13000000000000000000000000000000000157f58b1c7152a7f931bccd9a79073967ec28855a6d74fb8727f59c5e3728fbf07a5032dccb28eb8d8b24229f2dc1880000000000000000000000000000000019f41bbbb853edc1fe3ee82f901e613107dd4ba1d880284ee95a2c4cfb2220ec1408f8bff14defe59775136bc75b4a1f0000000000000000000000000000000015538789157505a0798aa36fdd171e0bb14bdac75339b35805807c18bf9175d877360748f97a8570754af0e28e89df660000000000000000000000000000000010500aaa99216aa979acd66c5b0cea2a6a973f1cd10c412e823c61cb897bce54d783a6c0acee22cf9052166a4bb5adb8d9d3f97893eb4f14f21f68110f612a444815fbf2f76b8399ba6045c8a44270df000000000000000000000000000000000439729e13e6a9b5baafdaac65783ce79a5972791610a333224e61104d15c746d7cf8350e619f0f72cb73635f6795c5f00000000000000000000000000000000092e3c976a4a5424b09e50e6513a9e1f427356ce161e742be31f0e589e9ff862460d41281f0bb2d27b1837a70a5938fc000000000000000000000000000000000e0e51e92ac3cabfd999cd72b67cfc488e150b11b18f9a31b1c2338fd4f2c58937521b5a107752c342e67666b99fc42500000000000000000000000000000000023d8884aa3f556e98e006960293230ac966ad18f3f715e6ab31a6bf0872c04e6f115fb1608cd87ffb369ff31012a11705fb554531f53b8cef8d93566df80878baa96f92bb54aec19445980b1a1f6c34000000000000000000000000000000000be33bc145611afdbadc636e9d7cb7e3a9c92c32f6944a2b7b5f44c248a0754c174e3286ad307fcdb2ea02a3578aa588000000000000000000000000000000000457de1fa8642d302065319b1d32009c64e7d941fb43d1b3cf455248664b1db516379df87aee05a651c132eab8aaccb5000000000000000000000000000000000a711f3bf1bda60ca49271e8a3143330cf924328d3ac6f7a802c15be1d7413e300f398274f338e6bfd0225cd8ba25fff000000000000000000000000000000000a786c5c7b4f1701e292aaad9b2e47bb883409aae0c44ae813ba48f401f4e2146ea0b1d85f2ce862b6ac9ad3015d4b14d79ba2c485f0aa0e35212fd7fecf970258903bd2427c4c8b97c2c425ee1190990000000000000000000000000000000007d03697e195a6b714fc9785b49e54e219694250cf5fe77553434eeced15422de3985f8c736996c1763d4b9248a7a7e00000000000000000000000000000000015841a70a168d2f356a8ad929e2d1433b782351f4833c51b50f3a1af48a85468c2ec02699550d21bd919203df73abeeb00000000000000000000000000000000170902520080c46faae2bf35de396d56921bd0279fc889f0187adbabb9ae52b849269d8097d5b3f331dd5a817f9b2ff40000000000000000000000000000000016846a000f037eaf5953b7c4b477e441ca4fa738895aa24dfb0ef01a4c8fc21a318d40a9424e151380084578ca413b3344c7017258bb979cc9bb8acbd3a3e62eac7aa152db46cd7398ef07edd031e4f60000000000000000000000000000000001a50509bfb12040c0271b231c566d13510e6ba84448e59685f5bfbf5b008fdc64cd5e9456beabd23ac011b071e3a5fc0000000000000000000000000000000014a964c9faf1752170ca40cff1b9b4fa17f8d2b56a4c4bd7ffabb65798771cd624ba61ee43160e70731fb9b07af8ecc2000000000000000000000000000000001822ceaae7bd0a734f57b67e4834cfb00a6b415459d81c7d380a2e5b5c795eb1b6d63ddffb1131cdfdf0d76852c75a70000000000000000000000000000000000c5a1575b30e5470151ba055f577a0ea49cff869614c50194829e53a3e1a95847fa387a0f45d537cabef3a5925e61c432583e821328ae90a7db16b20525228e8d915bc8d46a642cb0a06dfb64168cf1c0000000000000000000000000000000018cab86a0d70fa30b4df3e05a91eef57f6505cbe4bb7284de56d420ef3bf315be9249eedfae92561c643bac2c92301ee00000000000000000000000000000000098ca598ccdffa9bc9d464d51b46ed8a8f22a87ef408cfa45fa7f78ae2dcb9f861d9d6a571f6fa702a71e783ee3395cb000000000000000000000000000000000c073c0a323c3051c302c0558463a5c030539d74b440fdcb16b42ad5ec097e10c16bd9a651d149dd719fb1fb865420a9000000000000000000000000000000000164e622bfb8ecd5eaf691abad9db38ccc64ff0fa1784d26db8c8fbebc929bc6d4dd471321e01233d55fb4a9661780b5506f22d323a740553d6107e651c192c1dc6e0a0161a82351f125f08c77e53fdb000000000000000000000000000000000fa48147388181e8d0033004118848c50c6425f2e5f91945a17abcff4d11928d298c092d60184e75e67c7ddb9eaa8255000000000000000000000000000000000c535bc54df050c1ba8d858a346d3a644e03fe24873b7dc3e23518d44b06fcb3f52b4be6f11d3b66f0180a0a95dddf680000000000000000000000000000000015e279a2893c205dadc8e1cdebd9c85454cd4b5d7537f984c8f9d451f8316620279357e218fef87339f1728fa317fad5000000000000000000000000000000000316e343ba68c8a762f4c8f2a5c20f16abc4a7a8365556c1625df832219670619b6dc70727e9bd9a64ed491dc22cb9d57f1bc0e1ebff8f935330c35573f9fc3b900606da9cca9a36b425977af47c7ca60000000000000000000000000000000011dc72100cdf676e41f21015fa7c57897da8260609467ffd38c17868a4dcd2bd5d4d72e89cd0db2de83618222ea3b5cd0000000000000000000000000000000007e074f73287faf304f618478566b91c8e191b229ab40743081342e676be09c2523681cf7ca6f7a396f8589a4ae18a6d000000000000000000000000000000000ff753a16c16bf0dd1de9fa9316694214aea6f99b81f66b6bffd58837c00d7f5632ed5f8f4cdf32ec59c29241ed5e28b000000000000000000000000000000000851e26675814612bcfa639fe567633e1960578a0c8d2e6568418f633eebc109e6c8af97e77bb28ddd47c6bba8a7ba724429b85fae16200da6eb8f62e95e027c24aa6ee2a145f6ef225139f29aaca29c0000000000000000000000000000000009eb2f172db0fe9ac0332381d929fa200a97047f6e732570d23fe27f5ea3013fdc52fd0b5ee74a4387af44647b75f956000000000000000000000000000000001355f8e1cf45443855f2d62dba0fe45b2bfc4e0d06aa7aec7e4f7f9c4e25b33d9c46a01c224517bac9a1390a9806ed4f00000000000000000000000000000000179d47a62a5c847f47341b1ba58f2c3b073c5282f925f57efed1fc43db04185955075255e4e4f6c209757ddae59101dd000000000000000000000000000000000ef5f74d4b13754ceb3b468879f1a8befb8bbbdbb143eceabf2dc8e68fe6cc8e1ea4f3eca1b23a1175c9f5f5c4c20d3454a852baf21df9f4ec8d711a48e6ffb36be8c09c8c60eaa090876236b2eae37a0000000000000000000000000000000005b70a4d5b91b85971aef26b1521e12904b7ad224f25e31ec6ef59856cc702043a3eb975bf21dc8e4fc55171a3865bbd0000000000000000000000000000000007cf7c3e75a837545b53ca3e175a275dc6fe42fb88678aad45910d150ea9c6c94eba615429540348bb2ba8efacbb20e60000000000000000000000000000000002eacb469f5f8ee6c9f557a6ddcc854e955c5b9203b4ca5dd2e097d3e021479e13629863eb5ff17db46a17d3b0227f58000000000000000000000000000000000905e66f3a051b304b110a8682169fa749ba0de7763d3af7edc3e40f2d22ce7b6aa00cd06d2c82d74f3a9709d955f44e13814a3c6386b19f7b93c2c4e0eb1568e8bd3f0012a1ae1357b127c33808aa0400000000000000000000000000000000060ac9ce51426d360eff0d911d9f97a86494340bc5c5ba31ef146b55ad3633ec57a700f04b0cb9d4e91e13c2cc5e68a8000000000000000000000000000000000df205ed85e27c25ce27270384d7c3e58c4e0a9f214d74cddfbc7904eb3115e7bf204375df7558c3e65f7a81a942c5160000000000000000000000000000000007a220d42ca8906013479442d7204457b3ff37c9ee70d64f9f6858ba788b7fc13b71d33ad527c6fc673ad8940b0f01cc000000000000000000000000000000000ad481ef549de13b174d82fe88fa57b7e31ecd8999bcdb0c7a8735ab619a13b1e684b9473f0c59c734567cc08c76ecd6aba0fb0440b2461ef64af6ec5f15db381714fce1da6e03ca962cfc94bba26d74000000000000000000000000000000000366f604228e2dff2348a462c56e0043037d1b415ffaf155e72c559d185c6b0a0d125585d060f159a8cdad959af631f5000000000000000000000000000000000f69e829a0995914ac122299d4424b4e2e120fa4913939d2f18f9d1496e7255d00ff0829c20521ef47bb0dee06c28dab000000000000000000000000000000000a3efb4a376281a60f5246d8fc10bc23cbb9cb71037f8f57271a9b01f5e0340a562f9acf0e9a95b8c65ab7a5cd95520a0000000000000000000000000000000004a4ec86e2b04bcb35c7840d85cd1dfaa88e17ffb557ac591640ed8e563cac891793b92e349a7903c6c1f88d26a01c88c01749cac36dbbdba5662687fd1ea5391ef9d0bbd24e05bb5904a20fa6a1e11e000000000000000000000000000000000f5bcc27c243ef65dfbfc0de6d431706ab20d6cf6408ca989a2bc1c52b78ab63de6f58b70bfcaf6878a2746f249b6b160000000000000000000000000000000016a4c9e8ad0634e8afa8606a1a7bd1d8cc0815dfc6906b6e6446e0ceddba4a4a2df979d27cd07b8982a12550bc700fce00000000000000000000000000000000051f8d972362caf0a8a39045bb468112f2e73afa392079f8a4dc4c3a3cbb8dc224c21b6633a5ffbad08796ba2f8df44b000000000000000000000000000000001825aeffda04705ded9c702ba30d24b9fe8eb7cb106ee5d4e4ba029dcb57bc42c74e74e92ef8360cf130590b838645429680fbd6e6c7b1b14b000d3d18bf93242c74662ef108d711d85d8d442e415ffd", "Expected": "000000000000000000000000000000000d0ab61b29ddea1aee0ca4e81b5369f37cf45be383f64ba0b1a5a74b790d7264016ee671959444c94b8e6291c5158ea90000000000000000000000000000000000152bf3709c56b3add8e3396d17abcfebbcfeb230529ea8144d6a120a0a6aa83cb284e40ffb9fd9a96f8a2f7244212400000000000000000000000000000000041f516a7cb2a7137746d028b0739c79ffd8f7535f20ba3728ede32504fe058baaf684cc7677967aa46777818b1fb6630000000000000000000000000000000009f1035729c55cf6ee090983a54d8c0574bf96342901f471a2e5380f11f235a075b0e157c38c456b6eeeaa10b87d3afe", "Name": "matter_g2_multiexp_11", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011ada4731ae7df493e405383603a8d79ef77f3fd14fe7b8bd9d2afe068998cb712e84927d5e6ea6e94d7f10270fd193b0000000000000000000000000000000008a14eddf88826dc3be792a0c1f7395efdf91454cec7e26c89f6beda37b194b706dbdde8745129e821b6f4b4ea6118490000000000000000000000000000000011c29513e8a826e6b3eefaa20ad841605d04b813cca282fe02dca0f588b9a579b2195b0b080cb6d12c1a7881008117f8000000000000000000000000000000000689c67d05ca379367fec99439e3806f827218ffaae995bf38dd8e2919fb2e751f426525cc2c6ead3b9aff2e377fc99e1ddff10527bb64de6ee2e3ab4959ebef9e7a6964b7482f9fae396b2b9b0cff9e000000000000000000000000000000000dd683a8e4ad54b1a95826a3000750c6e3cb250ab5d6add63c21b182d736b220d917d4e70044ec7101c3bf8ac620e1dd000000000000000000000000000000000f3e411cc6800b304fda1373ffa60c7718e20bf3e2e5f9784a81b47e398888b366e1f04f48f5aa070a661b5e2148d4fa000000000000000000000000000000000b0f8d0b695e000158ba80881a9256ed9dda5a7f53b550bf3b5c67ab160060fcbf5ce07fe38253ce037abedf4c6f08d1000000000000000000000000000000000bb92d407c457e9ea7b9851770d2743758e162dc9cdff2dd54b8271c046f642729cd2f10576013adac84a46d38623b932943fa2957d267019309f4fe5b6725379d893dcc270ff7f35b3811ad1d8d12b100000000000000000000000000000000023e880685aa69b3480bf2b7f2aed1181e094322da9e79c9263d50a49ba4fca713740bdb55886fc81c81a51045b35139000000000000000000000000000000001707049fb8b7ad278be2949b9eae2e28bde9de1d9eb964eae582541c2d7a8afc4c1489624a0919047a167028b8c77e3c00000000000000000000000000000000062dbb2bfce2f67c32b87ec2fa01ebf7deddfcbeda2fcf0ef094b1be77b7411f657e745350b6d2da16fc83a96f6f20e500000000000000000000000000000000062daeba038c7bc379f56ac371745b91fdfd5b4cbbe50d9619bf1d077f3cde966f81f9b851ebd206f2609a780b6dbd681551a3c2d0391fd8dedade892e8e2171e652d2a9b52f2288451c55f77fac788a000000000000000000000000000000000b553826dd9e2252c9da74c2bf1bf850df3f9c37439859f93df3fbceb7cca4fd949dcaa7fff31c9e06f41e51ae0b30bc00000000000000000000000000000000187810711ea5911a437a62e2ca483983bf2535ff9301a1cfe1b4d41902ef689f8d86f817a2a7c77128e4ce1ef6b037d60000000000000000000000000000000010170cf5f2ce08211cfc41bf54cfaa16584f833f7b97b2f6bc436eecc56ef44463690ea1f5c8c2a8f69d93a25206282b0000000000000000000000000000000001e627a68dbab6b0d05c85e49b966a769461ec38c38fd94992839bd0d46e06410fa7a48d418d65a8285f7852e8af4b318eb2fa94a5c97c28d95008dd1fe60137b34c2e763292d1b86993c02790b8c91f0000000000000000000000000000000011ebe2edc3de58a57aa9ab4d6626d7b93235ed24efc3d75c1ecae376c00beffc5e89ec509d243f693d327f7a4551921f00000000000000000000000000000000088ca2fe0651e4d8f3958454640a58ea1cdd804bfd2700bb1bb8e26ac50f2d7fc8c292f94b0bccef5735c4548025735400000000000000000000000000000000154936de8932279cd39ae803a5d814864953f647a5334bad958222de765250e4bc847e02979689dc9cfe1993486b5750000000000000000000000000000000000c7ce07c9746c6d72dae11e243acbe12dc23423f870f3130b244eef34524d547fe0b2c4b704ecb6b2e6c32f5675ce67ff72ae1def6c988f9242bff0e683b8d2a5c1aecfd6ebb9442131ec5b5b825d0f600000000000000000000000000000000031ea855125d75321a2a86a93e72fb3869dede7531dbcc1cb07ea2a352f3c6cd913275d0d43ccc370f4539f668f205f50000000000000000000000000000000006c4cadb11361f164f5899c6b57c0c6d8af365d902f4575c9d2d14dfd880501ce9ce218544b44bf07f0f04ed68e8f315000000000000000000000000000000000131332638026fd25b1a849c984f9dedd71e64fb52a61968666ba80238673077ac00b9e09817426ceac8c308f475303c000000000000000000000000000000000c7634af796e7aea4d4d83c9972fc822dad951d2473210ad82706ae0aa023ea85c1c467bdda68881094ad2a4f54cb33f331451748146f0564ab0d91b09db87e8a6ba8b14f8329bc041911616195f9fc0000000000000000000000000000000000fcdbf0083065e13deee2020bb6e47cb9e482df3768ce569f1f7c0e1c6083c97d9f08444e67857c2dce40e4a7b8d50cf00000000000000000000000000000000010f246e8ffccc2e752049f638617e122773a6f10220cdcc0603d24f1a94ca7c100f8ee2d9bc7c0a931fa0385eee456f000000000000000000000000000000000f8b68941df75cac3d4b6b3bee43fb357c8f4e56309d8509fdc62620a085d7ee58f52c7dff28525a449cabfd3b7ab3dc00000000000000000000000000000000019f934ef0c7c40786b073d38cb3e4623544cad59cb63440d4a6e76944d491f6b982e3a5e84124996634687d4618418316d298bf591bd927aee24a37c5ba508c3bc121f5150fcd1a70c1f27a79da7d73000000000000000000000000000000000c0208c1f3653fb3a5e2acbbb42f2598b22db1a714d616ee6bb501c3338e80db34d517c7086d43ddc77e0134dc5a4f290000000000000000000000000000000000a528245342e44e36f8e02e7259749e63ecfb38cb0609075e871701f2b3bb0765277b78d28cc3ecb7aa8c9e3b27eaf10000000000000000000000000000000010446583a905864064400f9ef168a122d179d46a058525c9be8a65a5d2ac5e967d51185d4964f81a5571123717210d050000000000000000000000000000000017da91a1d0358271b11a0aa524341ba1ee8c31bed15efc4c9183d60c6e1842ec4383070a09914fda991a63d55efa8f2156be810c3fa86e35bc935fc2b27971c9c41d03c8ab7b6c8869db90b6e0986ef400000000000000000000000000000000176c64efbfc9958b9c8e71b55e9fdf525d4e5a0265ff01ba95bcd5c6093bd063726f8e277d00b138fa4d8c8f80afc4e200000000000000000000000000000000183eaa6c3c605828852ab5e8a9432bcb87411dd18d574cc2491f1a280e7a267ff9ccc80b06c22e95107a72f22ba2fafc0000000000000000000000000000000013319d3a8564ffcd6fc7accdded740127ef205e8299b390d21e96b2609cbb463569c878f36191d43927868b06dcb912b0000000000000000000000000000000000fbde0ad8e89f5458007ef6ba0f01d0aba04217e06745a5571eedaf544443150f59117b56937f533b4974e5d57c41cbaea4445926775a6baffb4dbeb249dfe3b3e0c29f2a579927f540d8f6451553ef000000000000000000000000000000000c044a5116e175ca1d1ae59d400de24e4f47132251b4b3dccdf458623c36b4d3d83abc644a2247ac4d0e3f195d12e7b000000000000000000000000000000000048dff6bf65f158b19b992167ff8adb5c858a154bd68bf0c84e41351bf47a8f870cc735d1be5d9afc62bbcda2fcdb1c20000000000000000000000000000000008c5539746d2610eea22e79b3fe5b33a47fd3bf9991d34c6f9d824a46458480b735c0051d7b4e4909fdb1f2a1a4e4b3a000000000000000000000000000000001936558ac97acd903a29d07c4aea399227ea13fd6dea820813c5519412c157e1a477fcfbab60a787c6b3834eac4522889ee0e58d08779add74b68dd75e82df172b719cb5a772b0bbb34d3401b9f212ea0000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222773d07cb9d20744a2c3ac88082a8d6606acdc892666753793a2b8bb81116cc6d000000000000000000000000000000000908ebe27a1bdf0b9e56325c00ea3814527005793ea97eafec541c01cf2d7c909d2521a5fd475589a31e297cecfd5e7000000000000000000000000000000000017e3c40c60cd369ce5a90f6c4aff14896cf73fe06432e71940bd8086e36c2353d6bf9dd414bcf92889887e2d49fbbf5000000000000000000000000000000000ded856e5b2b139487b3816351584f06582a933af2bd4573a89aab0a41af01ec1cb928a7d8035228302032d399bc7caa000000000000000000000000000000000833b77c5d5c98ad95a144c0f167fd3bd62b03f4ad721561ed1d84c7137dcb19521f781bdd3ddc22afdd52c75146e101f6bb1445e9146b117bd0c95b009fba670a5391874dd314cefc884bdb0a4eba680000000000000000000000000000000005c6f28c5ebd981fff3aacd70eb18f134bffdc8507d1a3aa153e5787b68fba7f4a94c43045d2676aaa992754783ae87800000000000000000000000000000000148ff39e8062bd488accfead42a684f781c4ee579af6204b5b8dabad9022b029139b1f3670fc270710ced9a53253850c000000000000000000000000000000000ff50eca1a92f123e2534b3289f37ffd5d4e05f7678017ac20e35c2deca054dbe376c5529cddb5e58973f5c60914f251000000000000000000000000000000000b58298ba9496fe32891f4c1cff25395ac5a447205cedaadda4dcb929260ee55781916ef5e4e39793fa2831142111226d4158de4e23d793ba77c24a70f0ad07314927fff34361b0d74b25e8922512d7a00000000000000000000000000000000184d156f881f7d10d2f196b7599db85ee826c9c95383978ed68918756f642a2ed1c951503251b0778dcc39598d79fc8a000000000000000000000000000000000952168761380e8fc90a4966e94b8d2b88a784f6e607c99d9af1aa902506f59d6879153339fdb7b8acda178b9bce4ef90000000000000000000000000000000009997621d4e17c76b7798ef2f99d3c0a7519cce278cf718789cd8227b2b1459af7fbbc93078aa0aa361167b1d1c9363600000000000000000000000000000000005369eb3a77d2e26f9907a2d930f39dbb87634346cf10525733aac8ea10eb918d4043d2a05ff8e80b9c69a670e17f15c629ef41d5a2ce49fd81930406f19e760a47074e159ce372dd67e7ea46ad706b0000000000000000000000000000000019bdb390c66f7d28cfaa91bcb34c5c55bf93a9f2345ea396f18ed33ff2221a39cf68c5514fe091f7882e82470efb1fee0000000000000000000000000000000002d0b48d2c0377b0dffca247b7625f9901f86e2161626b4154bc25d6c643a48e9addd260298bedaa80e42caa5b9fc5b10000000000000000000000000000000018a2b0a760652e546eeb42e857ca48f59741eed91822c17692e9c41358b213c82537c9c6898713a13a241cca627a7dc400000000000000000000000000000000079c02f41fca45a56d9d8e305141b4fe8f98d102197e7864065d342e6b07f65b62632e0c12660f37de4d698c0df3d0f3c718651715ab786b4855092ed21be41b499b7824d0bcf68ad31b31ee4cb730d5000000000000000000000000000000000c0448fd4ebe9b5615653336fe0a618fa281b0fd7d72a8f956a5fde84f7d356b6be853bf823436bc0b61a603636db9ef000000000000000000000000000000000dc4f2b4d810c4290e263098576cac393fce137cc901b3be23507cecbda7d86d18022cf8e1a7df4b1298520ae5c9314c000000000000000000000000000000000a39413967b558dd8a6b2bed972687d984fb9abd0662a266680f8c90f1897e2aca1ba37b41d7d3fd47406bc5fa3c5b7f0000000000000000000000000000000000550fcbe5bb75afdd8d5f387798a8e83a8dbb6da4918c24eb2e5d2d8acd3512f6649a4ac9c8d3e6794e6f4f8a87687bc685a2872c4980518fe60c61e2276ef53c007166f7eceb355b4cd533f42c00b7", "Expected": "000000000000000000000000000000001654e242002aafa89c6fdb9e8fe2c197ad2f8aad11868568dd39d68ca35919f94308a80303655bc83fd130de6f9723a900000000000000000000000000000000062b5a064840a5a28b4991ae949f9508586447ad5e8c463593503c0e5857c5233b7ce7ac03e555c2675f2e320e8cee6a0000000000000000000000000000000017d65fbd7caa69629f66be8b201f53baee5ef2957a3c04fe384ae82959105342b52483eba6bcc1442763c677f515f6cf0000000000000000000000000000000002ef8f8ed1114cc9d299e59003c61d62edf8971d65b1b621779bd7b270c4123eb629f56dfa2e2723501588a0caf1847c", "Name": "matter_g2_multiexp_12", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001392409b92282bccbdaa0268e1173e60911754eb3cdc28a52e93f4d82ec99026f314dfdc59b39a4f988100f9c30cbd1e0000000000000000000000000000000016b3c555d5c196551ba715c6c334a668bcae80f5a17f038038d35dce34843f79968a90e2102f0faa22a93d3240b58d490000000000000000000000000000000002daf83727fdf45dcc1a15adf47de3f8a1724cf4d34116f52106a9e6b22dc24a288e89b940cc57e5a6bb87ee70f680a5000000000000000000000000000000000446009fa3555e4a056a820efa7da52117c15eb105af57985d8e9b33b0b22fde6aef9bad30480c2b8c1246519795f61fc067ecd54e9ef59996493f846ecca63bbd7ec28da586f0b8d41bfdc6d97a35cb00000000000000000000000000000000000372ead514d53007690843484c966361661816e0d3949b868176d7a9bea42064f49113a74f2572a6dca7afa0642fa5000000000000000000000000000000001199d3ea66fad87074e62a0b77d3fb962db17dd948f30c38f5beb0e44e1cd11d9172b878128e9a64a08394f13cd786f60000000000000000000000000000000018b7db157bb326ee2f72d4df2b1e0ddf0a90401ccfca1d4ffd6379c62acf5d6e4176a23ded2f81653038d56d848b4fbb000000000000000000000000000000000a932cc9740812c8bde33b68d94220690e0f55618b7e51d3e3fc29d0cb9a8d42b8f8e1efbba5984c3c1007c9a80fae408b5112baca5e0f2bfb885c5041189612918d203a117d886bcb3b27df7e64d17d0000000000000000000000000000000015798d10386f6d24caed3859875be5fb1a43ac753f725f28da6b3583bd9c0e404d36265c2305d7d194e2ad84bfd2bafe000000000000000000000000000000000ef2ea5f3b6e03e3c9693d6db60019f2efa4ea586bdb7623f03bd035c603e8996ef2ea7cf745aa31f60679ca04f93875000000000000000000000000000000001792a66785a3087a80c4b8652c1e4db8f602cf75c1a6955f480a977f92ea262965dad84061f6045177c831dc4a3bf8400000000000000000000000000000000006ea3862318974d6347639ec0d70afe748f4edf32b9e437fd98f38eaf72168a153cac180c2d67bac8a358e3a4d57a2b32db7ad39ec8129e9e9206bd46cec6a8ad3362ade1beaa97befe148f6c67a9c2b00000000000000000000000000000000000974da7500df70d888d5876e7c61bfffcdf830b49bdd40edf65a2ff476e9add35eaf9451a2166e9781805192ffd7ac000000000000000000000000000000000cb2e7152b5b40758b18caea356dd8e095f400282881207c4b79d10d741756e526be261b98b726d5cefb668dcf73a0a00000000000000000000000000000000014aeebb995d464f4d77bbb72f15d9078936b5ab68eb8022bdd97d050576dbe46e6010eb72250c8ccf2a59138efb38f9d000000000000000000000000000000000cf7162768e8eb50e21d3c0a076c7bac4920c70f334336037fb40e57e0efa91eb025356ac3f0988a6b127408a02eb53fe2400a11d9a67041824b97a96f0ea9da8848e7990373655d76e8bd4eb84df5dc000000000000000000000000000000000b1d6214796b4775c2b50e634a549ed104e6ebc0e032967b17eece6cf88c93aac23059f263faf3c3f38463270320135c0000000000000000000000000000000013ffa3894a36226664ff53ba9256d39c6312303f5cbda6847b4f68c56134b7d731e74bd711014fe374f909a081a7d02a000000000000000000000000000000000ae4590cdcb1367392635d0f8dc6b9557abd16290fd1abca6da354646d8585a7c9432978dc616e5fc38cd71d55f139c200000000000000000000000000000000124a7b5574ef52359b4beabcc56d3286db8c8fe4ca4718f75da28d89a8a95efb878c18b48360dbcb6fb50a9f18f0d559aa2d17c409ade92566ddb3913806723d41067540a36a9c283bdacb273c5b258a00000000000000000000000000000000148ab0e847ecac963f0156da025dbc52e765cd8827fd55ba2969da6775649529226ab13ab8537ad0b89e8f1ebc8648ea000000000000000000000000000000001395b1adb6a56b91c3621a4ac5886a7b13ec00f1c74d5317eb74a766eae655e09e269ec48cdf740abc38f4d6fe52dd0f000000000000000000000000000000000f70f77f07ef2909033665bc05cfeea7df6ed55f2f0b1b87d9f247b6c07c7e22f516840efe68005c3953a2702573a9b400000000000000000000000000000000166a334a711416cab180cc498308487b281711f2d1b832c410ebb4c591af54b154fc8c8d7ac9a49a241f7a3840acbc75e5e3d21862b64e09a0893ece646de60cd66aa483662125ffabc46cc52f1cdefa0000000000000000000000000000000008c19bcbdc2ef26a30dd88f3e35dc7fbb3c81c0224cbcd6b12c90883f3973bd7089636f997e5f213fbdcb79514c551c600000000000000000000000000000000058620cba8ed5b738167e809cf71392aadfe8f384a4cf397d10f674cfa914e9e02bb1518e42f16806214fec52d880f6100000000000000000000000000000000048ac1120d26e4173bb33a58c0ce86329cdbe9df6a6f268c8d5ee4f1d6110f9d81cd50c46256198a2462d50be3e781270000000000000000000000000000000010af13ba791d554720f5075d46d03b55c0c1dccd679cef5a7d439ae868d3ff2780cc3ab151feb72b8b92905a205e630449510ab1b7850badf58cacad67fe47135f6524f0d160f3013e8ff1c881e469e40000000000000000000000000000000005c30a126c94b87c54270d0f23a486c3b36a8b491bbd805ae0d5f2bea818a87ff5aaed2d5e6317b786ab5a23f1cb48da000000000000000000000000000000000eb2d4663eca7f8433f10e84984781a57fffcb8f9535518721521ddfc7a4958778915ea3c57bef399a453b8ebc10befb00000000000000000000000000000000161947f57d97a858e5b3e918dbb22dbf28629e51e81335a9bf105d0fd660ef80087c8d69d8db9841cc69fbb5e7f81487000000000000000000000000000000000c52b6a559928fe4ad984a0569c081f3f71eed3d5b0d3c14d1a23afa45594e0fbd94143348390bee178720fc603145ab713aa69664a8c721cefa7d6dd3fe9f92432b4d350621d5297805fcabb21ff8c600000000000000000000000000000000071aa47d392e1a7787b37c52acedbb4632d5549fc11b79919bab7d22f1bbf1c3a239df622b8824b07f6e35e627283b8500000000000000000000000000000000198e72e05388021919dfc1b2a58ca72bf7655cc6c9b62abe3b45cc782ccfd4a2334780e451b8a6b7c311887036813fe4000000000000000000000000000000000e20cbedbafd96c42612e146debae48c7fab4846b20ad0848c4c42c6aa0603e72f94dfc938ed9e3a9886d221ccbdef70000000000000000000000000000000000c861d1878e63e313e672bebdadd3fdbb691cff5fecbc24da895febce2eef0a3c774a8a9d751498e4fc8e2b71daeb40dc040d8bf0a787346560fa3b100b2dd9adb3f7ee716b8103abdd9609363345ae40000000000000000000000000000000005f7cd2205fa2e17fb9896efe3fbe110e1fa59db1ae5f8d6b5f4510abb4da867933d4fe3caaadc4457dcbb35f1b9c62b00000000000000000000000000000000126f2ef6022a7211fa865c1dbdd5b84d96cddff424b06647acc462408f2d31f34ce898d76e1e124db7c39e08dab0bff6000000000000000000000000000000000987f916ad6f718695f3c40703c59ca93eba38931b45d7c33c64c9f75556f075b744dfff8a5f21489b3db6c3846ba09e0000000000000000000000000000000013011b8c72f3853738e22957f742b05ec428ab0da28901800f787b7c3678449acd0359fee93c40c69623aa4acfc0a81017b811aeac4fb7d91abc655f8a4392176f9060346073c957ef903e25d10935a00000000000000000000000000000000014b88c0586fa18333ab11a79acab8e12c6257f82a4ed16d929768a60a3a5d780a22101c32ea9b0099aa2816f18a0351a000000000000000000000000000000000de0fde69efd2cea7ae08d6d2443883002e0b4e11da253222429f6ecc67ba8d282eee84d7f46e0ad00b039a2c2ad226f000000000000000000000000000000000aedfa0a5a8b7577dcc1094469233f8b07e6fc32af26841894d498d70c6a9a046ad636086def948d21e39833c5b6c5a70000000000000000000000000000000010ec6aa0efba4995582585bb67f997f60741648156324696312d17656baf6aeb3e2db0d1a272912fab2fe81d139e971cbd1f096026159218836a46b9801a4f0c43189324d20220aca777b826eaf2575200000000000000000000000000000000004a847c06abc8ae7ce6e6ff0ab856889dd3e9697a75e3cd4d2af9e06d4c2fc48c0562289348ff52f4d9855ad03d83aa00000000000000000000000000000000075673bc79bafa9a64de6bb0e9dd9fa29cdc9c82e90a7348593eec673cbbf22b1eca436ecf767d45852ed888a3f23949000000000000000000000000000000000f3f8543d1e667404b4564dddba4d7c11d13881fcd8ad774c8eab8fc599f55147c353cd6e163cd7b9d5da55ebc13c2e800000000000000000000000000000000069edec7e7d26962d88a89dfad213daa36046bb2851e5d67adbaa227220f29f83ea67cd3747e6724f148dac28308604cf221dedfc21098ff9a9507e493d0fdb1efa6029fcdab23a016515078c76f7627000000000000000000000000000000000c945e83822896974116663d3e2769f3df5a70d55b8392c1f6966e330951f3cc5688742d4588648a6988b928b9fe00100000000000000000000000000000000003e94b7ff7c71d633ce69bb44d0ba1bfc7c27a5ee618e703aef81a45ad61771a2fa8e3dadddf7c8038f1f65ad7513801000000000000000000000000000000001727d768c1b51066d2af87a9da3e24ea2a75b0f75b8ece70727f9f54ab77d841e7ae01c9c0760f4186d02a28d6f8ddfb0000000000000000000000000000000000a273f9395cd49b646e90fd2526d5c93fd46c7366b715546529c9edf5cb3d274c9947c21a03add3e7b20612636a6745ba5b30d1397bf28100f108b84e05107ddd6cae2e82f1973ce187e8c3a7d02f3e000000000000000000000000000000000c996c16a16879bd3194ac366bbd11b5863123ce6fdabeafe56407600e5d49c92ba68ac1256e1515dc9256de14ac26de0000000000000000000000000000000018c584d8a4f14900b2fee70b50b700199ec2372b731dd1380f42ec7fd3d01f0c9a007554059b85946c1c4f4e2fc504ad00000000000000000000000000000000073d6c7d671762e5398e4c9d57f6b68c3d97dfe0d01783f124256fac236f03b774db58b79cb4d5558e1ebf18bb9e19680000000000000000000000000000000008eb2b95e17fdda916b08ff2819cecd2eb031f41c8299b308339b7d9836382ced75e8eb1514a70356882d3a43227a9bc19aadc83d1db9140af303c0492d2b9bb9e2b53ddb62cd2132bdf8ef62aaed683000000000000000000000000000000001029fc28cd502caf3ea3619f6fd04bf457e6a452b5cad680ec2d4f8222a5ac2daa92b880bda76016973494e605ab28c60000000000000000000000000000000002c672c7571b5d8e99de6e47e0a2eb71c6d9bd12baf2b083e6f88598b32c4644d1486aef582c5936e622058bb141db1700000000000000000000000000000000033cda383a77d5b3adbb0809e834993c56717f81f8c66ad2d97f2b298d5a46f7b29a74d35da09271b7053a05af096393000000000000000000000000000000000132da041c6e3e1d68bbd2223f8531eabde8e180b36b2cd0ed4fca248f255cf3eeccdc5f61e1c581ce54edcfb2b73e0787eb6fc40b00246910626ab66bfbac96ea09242d1d70496466e4d681942050700000000000000000000000000000000009721f22bc49f68d703a4dfccc3bae791caaf0d73892bafa6e9da465ddaf0fb1a069ffdd55306acff2407da64c1c5a0200000000000000000000000000000000056c0a4804a19aeaf1b4fe52064e43de8e5d41a8d77de054e2cfdff078eaf468d123d7317818d1bad1bf3469c0070b680000000000000000000000000000000007f1f318aed043d9ad7bdd53eb6a8c3167240fca75925b04795210700463c93a66ed64851195df1bafbbe4227d7db5ff0000000000000000000000000000000007b8945e258311e7672e842b91b540fec9ef4a79296956a5cba3749c0ad95ed83d7b0b48384ffb3188459e997b86695d3bb5926f36808c0024ea7388998b4cc8c6c48d32917f6456b39d514143c6eded", "Expected": "00000000000000000000000000000000086a1ab4c19c27f70aa422e8292752c50b365d6fe3eba21e8f2ed51f283df0446020834ad27c18b5c7285d1156049bef0000000000000000000000000000000007288f40fde69bd350ce1f4d0f68e645f42de319cc032250b76fe4fa305341e244e5b2366751d5311105e3ccd30e701c0000000000000000000000000000000011d0c487c4eceaeac009b694931f8eafaf8eecd6028f14a4de33d2940bbb747025eecd509564721b50b7186910f81949000000000000000000000000000000000366f0c901fb859b4bae006fbcc9ec7e456eedc7366c899f68090fbd457c37b03ab99ae982872c7888b65c1a056c134c", "Name": "matter_g2_multiexp_13", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000072f3f03bb09ca30239dd8302b05e0d9dc4e43ea33e865864a82578c35eafcf6868bf0cd9431b92b76f00990b780ffa400000000000000000000000000000000170b76cfb7944ea5ea055aeedaface3e8f0fa4d0ff657fb9d5311f3af6e736da84a5e2bef5188e20f76fb42591267fd9000000000000000000000000000000000d85300009165a8da9cb8e590f7f8d372e4264df150b1551185c80e49dbedaaf872ef69c5763fc3713d0c087c89f21050000000000000000000000000000000003ba59b682174ee61630df95c8e2b1c48ffc8f7f8508c21f3bbe8f7bb3266521fcc06c8f90fe5126d872707872db6d59f44b0204792359895b448bfe6ffaedc14d54a6d72be7a49718c0a933807a399d0000000000000000000000000000000004e8f16480c2f080a13b9f2b66e6480132d76c4ef76e8bac995a8e33280073ed5610865260e154b32f75f527d89620b3000000000000000000000000000000000f9ca48d732a8055d22fbebf3d2bc1e1c9c815c184f594ad2337731709317ea6a205478ba05ee9271d35a19dcad4db5b00000000000000000000000000000000078013b9290284e7ad528a1bb9a2a64b3ef43964c7226ddff8ca16ab17b4a2e8a2a7d921ba924a718587954f586a954800000000000000000000000000000000004aa76bb1122116cc0c04d65265d8652f08b411632a732a9e66d7932801b77c4ad398d582e446968f7f4966e9167894de25977e7426cd5652559626ff8b195ab7ec679de987a6a22a6a0e366759dea000000000000000000000000000000000145de5d101498bfc7c57830eea2931663ca1165ec85b77654c866b04ba6a28bfe710c1aac9876a68cc6ca119708eaf0500000000000000000000000000000000096f9df9d5723e8379f2d09c76a3fd059be47d2c2ed8905d333b2464f72153c5f50b6345980626358839ac691c26c967000000000000000000000000000000001788ffa765c19758da6eb6c38e793190c64d4a7b116576f6827fc090b0f65304988f6a95cf4397f82b7691fc43960ee8000000000000000000000000000000000746e040d7aafdb06a31ba3d7b590dd28f0678badc261a93dc7bd9a605047ec67ba86b2b6dd72637a449872674d6b5982e7ae497b44f531fe203a599622954804c06d5348dc17eb1537e750006584b21000000000000000000000000000000000d8f3cfe1cbd2629f3899313cff16ca3d8f964ec1cc0508341936a7b3b49240db1116b2c3de28f9bc45cdfacdb5fd98c000000000000000000000000000000000fa642ed31293e44211b34bb28bd5b389ae6d0510cdab46c89756f31795506fccbdacafdff21b0127e80557e5ba9afdd000000000000000000000000000000000715a8951cb358b0d8cc63377799a9a61ecc85dac795d726fe60e429d492c9ca843be2a2633c17f830f199335e5d7741000000000000000000000000000000000b88a23fdac7d35fc135b45d7565854bf010a75f072b32c57ca4d0979c111aadd84c71df6792dbdc8e975ecd46a15df2e073adfb5ab96730c53015a4ab6210a35a37b2331ff5123e00798c33e040a913000000000000000000000000000000001171be5820b5a19c045abea399f2b8ab9905d2aa367c6c8c0f84eac132d26150b759a9c029414f1c8f7e4880214446c200000000000000000000000000000000147f0877321f2709183f0b617a7c5ce898db508a3ced4148cc9f7af011fe8040e90885ce817aa956d9f5d19dd968f6220000000000000000000000000000000000acb005c11481b214a17e3cca02c2af266e4c8cd928e3c4e221d866e9f296a2e913bf34c4e051c7503a5e4e7cd7449900000000000000000000000000000000125f45d0af1c010cdf8438bff0f406007853e566fa646df40a581f65496197755eeebaf4f0f77e1e936f399dc4c6c020e6e752d40d411f1ee6e67f48109c9a059226b446601047a2189ab815a3fe13c40000000000000000000000000000000019cce3f872af5cc515ac4cd7825a5318ead5b464d50349909a70b415a8950206974ee0d4203f208d8e6d14690158f5720000000000000000000000000000000002e08e8accede11afe3e2d085f35c08d7d414c26a9caa992d5a090a43c9b0c0cc1471f3693f9d342a973da65189c888b0000000000000000000000000000000008a984ad2ca60c492cff2e95d541d71e33b269b10d3df107c0513dad5af511c51806068da6cc7226df1cf5e5a2fbe707000000000000000000000000000000000fcd3ad75bb0a5c046cf83be3d973bb3685bc717d7b8262fb8205935db6e632472496907f7c965fc6b52042ce69999f9e657fda33cf4ed1aa89dbc19d58fbe3043acb5795dfb8c0cb97620f16f8f24350000000000000000000000000000000014ccaf7594d8ff6157f9439ba63480d3d07f44e62a86caaea510d0ec456cd8c6c4b42cf9e38713213eb4942ed45df2ca0000000000000000000000000000000015c2061c532cda006addd2fd6ebbae458197d55fb336f75ca7decc05dc6d421a65495b71ed11874aaf24a0ec13a7c65000000000000000000000000000000000101f953aed7f23b5b6208032f05b818e0147079b7764aa3134dd9e4a316bbef0309ac378ca3cff3bdeab9ca56cb78e60000000000000000000000000000000000c76a2bc721a4d3ead95af79ec24be9b7624bc80d7debc07e388e52ec621082b9a69f48d157b168af4aa73629697f784c73458e18d6f832f362dec7c49140e6523ead045131a1b719b0c836c1ef13a79000000000000000000000000000000000761832bb5b530b80c668234ab5996bdc225c0c696ea07dcc61c330320404827ada9d58d658e230fcb39a96b339b830e0000000000000000000000000000000001198b85418421d96ebfbf436193b411a3a89c206d006291bd23254ed5fe12ccdad15725a34d962005c0ae60e202bb86000000000000000000000000000000000c1d7ab83b1d2ad57a407e248492773a357c06b83c16c6ce1490e84bc4a3cbae395f160181d2bcca3edc34b764754ab0000000000000000000000000000000000f1e9f0cf96d7671763739b6c37fd442f0e816c49d9c8e001d322397e9d6741dbf8769ef9eb83d08ab024294e279a02838cb0a2b191f538b30187dc730a8c665bbfce8186883500baaa6c3242a0d147400000000000000000000000000000000063049bc3282934e29f3bb3dee432bdad6193a5d2247270e88887cac565f4b986e1b3b2af5387cfca64f0d50bc0ee1640000000000000000000000000000000019f0f05fc7f8bf2f0b8ed375690b53b6dafd0a07c49fa55d36e040798334700a3aafc4995bb90de9c4dc0e077ee18b58000000000000000000000000000000000fbe702d148609dc8feb3ac11c5eac8e32a2f7221aa135cc33a585e9f4c97afa1658d8962fd96e26e0c4c1d5108229ef00000000000000000000000000000000061fe418d3b440e84728091a4996119b515118900f54a6f2da2ad5592f48ebc17bba50b59ecf435de3cb892a123ae9d18a27de64d41d13ab67c1f7b1a7390ab4dbba7d219dfeb31255f9401d5b3c62f80000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a4553780030798960729d63db70b8bc3c0030e80d9b8ae766e3330128557e6c34442f6000000000000000000000000000000000549f6464b657eac28f838c6a8bcfcb7a189d6b3b9712e19c1a23503ac209da5f2ad4df83acd505b0231f00eb88515c70000000000000000000000000000000001bf4a46dfdd70542e9d8cd6d6215174cba28f9adbff31c02482ca38205cb4afa2f7fd65ecf57b39e4ee5cee320e33800000000000000000000000000000000012d04a693d565f96566b7c313c47d272fef0ecc828493b0841d58f6bf690a77cb72824a656442e288460ecca7cf05504000000000000000000000000000000000b33eefd5df8b098e6505cbe655a483ab5c6e417a4ed55420beab95e8614c8538dca9296a7848d6aa0495a173df6d0b80d32b6969af54dd345f42320ea96def3c6f4dfd4e22a82686b7a3c57a0df5250000000000000000000000000000000000fdd9702ed88aa857254c3ba50b484bfc324e583659c57055e4b09eb1662af2f70b547a1eec139193a0d3c75b565d3b200000000000000000000000000000000193df0fbc5f24065008b5e98c4c4bf9f1e743a6ee60c3700ae4a9108639e540384eaf1f9d7a60b8b6a5d79e1f34949f50000000000000000000000000000000001022f8a254d17e448cadfad35b7a54dd2fb319c8f9ba219874bd8280a5077301ff4332d731a75646cd93bbf31331154000000000000000000000000000000000ca1eb350844ddd0a65a4ad56e1a96821de2c6633a4a45be976577c223e367853e2b1ecf2cc40b8595ba5591ae8e40f3969848f1b8b36bd28967b762168edb451322e2f0c4b99b7f9112c9a66093fb3f0000000000000000000000000000000001f9cda056a0f8803be581634562e975223b5311f4752b189cb6bd6df1ca5e3824bbd2889b9b93da59e4f08d482734240000000000000000000000000000000009f43c25de25c5d76ee1a03691aa434de6a063bb3a1133b045797a279346fc938dd2636abf0c4bbcb528c9c28d3105c40000000000000000000000000000000012afc29245da8bcd3c0d96c4ee61617cd9ecf42a47c2ee822003af26aeb4e4de8e432ffb6b2d8241090b814401a8676100000000000000000000000000000000053edfd98742dc70d510f1836fcffa6a3ba9ffd4904c7f5559b48e49dd21071401362d0b39bc0d786b7ee2e84a76af0d957ee08a513c5e22bbec04722575a9b4f3a1343db0ae5beef4e66fbbe1ac90440000000000000000000000000000000001dc3f016ea1a74ae50c21c1955ca1eb4a911026a1e72b316c7bbdc708caef63f0c1efecbecce8901d65bbfcaae429da0000000000000000000000000000000016ce9301888808323c9baf6402d7073fb85ebcd389334cc69d7947e345748ee44b2d6aab3ef818beb21b54a19ae4f5b5000000000000000000000000000000000c49817753eb6459cdb4bc737d3710b5f044bc544c8d92c8ef138ec9d83889664267e1a5691f4bc3fa235ecca2a973a500000000000000000000000000000000074a8450e35f1da18e6de05960e21b7059ece8972c36f000bba9e24488730a44ce3ce200c437e06703addb3b442a790a8e0cf0f590f77d13819001916d2c58a654d0b9d3c47c842f2d649cb2570dc0d5000000000000000000000000000000000bc1f2e9af093ae8235c93af098e692e697ea0ab4c8f53019a6e950f7072b56d5eef6b3237710f1dd1cd1970668d06d0000000000000000000000000000000000d9a63f7a13ff9755c6a3832e3c4c852919514523092367fab7886cac317e564d57fb4042ef40e696edce868e697c45700000000000000000000000000000000129a30657466460db13575dca367105c27d631eead330319b084adfac591f5b3b94988925d778e6d4645d1d2816baad00000000000000000000000000000000005ad64d6e761a9a301589547929f4952ccbfead278cbf6658255a075966340f185d5f356679fb02ff2197468ed7de19a71a8c2a479dec43d644ec4113142e666bcefd6d729d4faccbc147effa836ddab00000000000000000000000000000000077d1e5b35c224e2cdc849c02e800c0b80d1c19f3d74d9eec34c40f56bbdb9e2b5d2ef274991dca843755f91a50826fd0000000000000000000000000000000014f3b653e0df0c608b75dee3496a7af04a828e6fc5604f16ed49c39686ec757e96adb0a667853006a8331c3d63ae4ec2000000000000000000000000000000000aae011375b337940f2a53d9091d3581e8197e79251b19c7fba01de987721a9d6fa694b7978f0abf877f46ec26147c98000000000000000000000000000000000aaffbd468a2eb86a3cff59e2e9b7ab88286d2bdd19c2e789b1a68810f0cdc76171a2661ab54e81b17643ff0275eafd72d2d59a7f138327a20263d6338d2a92fa5a2f741daefe9aa81d06f20a6fe3641", "Expected": "0000000000000000000000000000000010a2434fd3150f6b9b491d3a51226bdd457504077ef2ed5a11ceaa8284900d1b84039a34d5239a863809369bf20a704c0000000000000000000000000000000007934f34fd50a98225fe6578d3f34ae5e5ef5e104bb9cb398b2ca4f09048ec39cf52e7fdbac48d45212e9e4c1dcc6e120000000000000000000000000000000013ee70f1b52cb8b07ad957a7565b3e3c56306392cf7b5aa29047b23e5b41fb3239ac3611bcb16ba7c7ffc4213e3d9cc800000000000000000000000000000000035840f8ecf56359dc3239945720ad08702b4ea8d0fa9bea3bfb234431df4618e960a1eea87da72ba4d9443f14bb87a3", "Name": "matter_g2_multiexp_14", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d04bb9b75bc8078ccfa85e27d32e137ff5f05f9241b19ea835bba2fffc9255a4a3028c0caf9c32d3d27666e1394fe820000000000000000000000000000000013f59c3d8aaee34230cd7715a32e4a45487b9b16ce68d178f95461229a4d0fbe7d31edc7208a7338eed08e65847f8f29000000000000000000000000000000000d63ca2bafaa54e93ea54846b26f88b4c6749953f9cd00c670914cca279b794c1fb5e2664fce44b8c04f01c68698a8b9000000000000000000000000000000000b5188b4b7ef78d3662baa01b1813b4a0b0f855e11397584a460d56f594f11ff2e5d708a23a8e64d0ab337c7076872527740a826d524fdb7969776bede5ada468a0115229152907cb2b050760c18c8e20000000000000000000000000000000019bae57568c879cd743f7def43b6b994f29782c6a0c74734f35b97042a916da00daaea34f321481e6cc4749e23297c1c000000000000000000000000000000001853fd11d4688b027146a07edea647502e80750de4e5e2d105faad3f71ccc90badcc750f76f1b02db3bc0a1a635b2bbb000000000000000000000000000000000b1e45b90e6a7032179236f13f01ab664c32ee5728414ac0d6b9d79510e8c5bd0f5b62e6c59c1a3c88998bf45636cbab000000000000000000000000000000000ed16c2f88b5b8d29d7e01633e2876322caeb740251b034e5e898919f836ae73f0296c62253a0329ee8f71fdb5cac3a1d226f56bf3935ea95d976fde5790ba0584e5bbc78b37279aed8e50389899b9e9000000000000000000000000000000001455764f99e5eb0e0371e89f88bfee1c43224b9b5202746bd151f72336285556acc5ff36bd8ff87378249e82214cc5e500000000000000000000000000000000007fcee74e5335d96714e4d1a7c6f5c211b1a460efa283e0d0578c6c1f56dbd252198eebf0625362973c40d95fd890d3000000000000000000000000000000000ede26cf87e604507230ad996788e85799cc07245cf7191a6c3cecf0bfd5747b3a277cfbe41252808df6da19f005de9a000000000000000000000000000000001855991a4dd78dfc6088e6a43a64b56c8d86a0278b899bc8a1979a40a287979dee567217b006ca71374156a96b79c176c133e1989ac82e4d1c9852a6c7156a34b05784a58231d59e3cc875ac5834d5c8000000000000000000000000000000000cd032a7dfed029af020bfa249e6adccaaf5bcd2ccf33736281c4fce9c6e2b2e87fa828cc20301269d8e0579ffb866a1000000000000000000000000000000000765c4d6c4062cfbf7e24f9772dcd812f7e707f2b0ccf9043faf10018326834934df121924abb74d736b0da47554794a000000000000000000000000000000001540fa51e4580ff73e58def90a6f19557dec3c8306e2317ba0c25ece3eb4f8c39beb57741b3c4b9b8554fd2597743ce6000000000000000000000000000000000d875c822d0ce50dd638254cd4aad5dea1443813689a940d72cfa5db9309b171299ca3d69b137dfd37f0b7538a0852750fdae1b53f6442c4378774a981c90d282d5f8793feb2334470c873491e41740f0000000000000000000000000000000011c230689175cc672c25f3c56ef4eaf2bc5766ce424f6c596b40ab24fdbfa56a955205419c149058dffa4d86a48ad35d00000000000000000000000000000000078d493ce3a8038134541ae5f2a82b5e0590218a499dfd78c7a9c06b92307003fb62d6414d6c04b22f2877c3de0b65ca0000000000000000000000000000000001d53c22a622c5d91df934783f8c0cb7e370043ecaf99a0554987e6c5120a0e5f4ede023a9ad988d30d945a2132ba5770000000000000000000000000000000015b1f36a00fee95e13443c9f6e67935a840cedc7c3fb7833ece8e180991909922f59d4f4ecbbf23f16bf5ee7f0b5851b70f1de7cc5e6a2cf7dd4b6e60ada67ca47e7b9417bb5f599048fb0c9b2abf33d0000000000000000000000000000000014adff1607236910597a951ae169a7f56d6a3b4e0f44ac63a247716bbbf61feff7865d075f79e4108cda6c0731fdcfef000000000000000000000000000000000d740b13885c268da876898b77914bf4a002beef5bd2a3edefbf366e45ebcdf593ec6d9ab21e983fcae9a0832986182d0000000000000000000000000000000002a0827e812e983898351d9f03f660317d41669b0fa378e5c7667b73df299ddc4a32a529ca887a53245d7e1f946623b3000000000000000000000000000000000bf09a2de1a8ccf24a8a65dda72adcb96535ea7235de87f05d27341738b0b4ab16afbc5b37c97e255118dea9bf180ec2ca82cffdf59b742a736ae9a6d36f7840c46c20c126ec054f47ad52a22948d7210000000000000000000000000000000015fbbf7e8c26e2f41be32daee2c81390b9bc4413aabb053e3a88bc6117377bc16011e81ed167370b72f84f0e77c2b8680000000000000000000000000000000013d48a27d06ff00048b19879493a5f8ca52b7154be2fcb468b9de9edd1395750434b0e95ae6dd941e84fd6d8918455bc0000000000000000000000000000000012fd2bc91286dd46d68d87a3f8793db997ee684dec6b2de1c4202e5e7eb0e4a8a21222e3dcf80e1ae4a3a92474107d330000000000000000000000000000000004d8b71978c9025dabb3d1b1b3c7f4f13f166514b8b356fd064842269a36c6f1c07f150c03510af7d0913103afda4a68fad69492cab4ec7eb89ed37f1e7fe898ff49ffac4ef2aeb75d9c6b544109a08f0000000000000000000000000000000007d679ac21bd4634b415ef8e0e3670a8a1d673f6a4f7f3786b92d55458af980b035e4dab165a3b773ff3469fdd9d5135000000000000000000000000000000000fdb82db6e1096e73322050f828ba41b3012496a4fc4cb481f11fee338243aae20b205ee06887e28f6ba6dad00445f9d0000000000000000000000000000000017e6894b48f60b3d9b4184d58ab9554851e285a1d445b4d97cb1a7ed5a984ade8b0f62ab11ca75fdb280cc0e526108ca000000000000000000000000000000000c03b61690cdd9a4c6c83d03749db72c8946c21a944fb292866cf3a2dd1bf3dcd95743227709740ce8124319d0a540555af71c9baaf54967683f8553f72abf789da465041ee5a92c9ce1ad562c91c4d7000000000000000000000000000000000289f850c4834153f36bfc4855f89e9437a172c35a856117f8b841e5ad4ef973d3aa33fa73d8dbba4b9b2101708006bd000000000000000000000000000000000700025f22c0460613c05f8941f8a79a4319325c37c2b8f099cd910df5c0c27121a9de0e40adc7ba0fda61ea637b47d600000000000000000000000000000000069e17e00d4d726e8eaca8235c88967a7c093c70e5a46b1863ad097acbe233554048838a0a486a72cbed7001c83a27db00000000000000000000000000000000016ce4afb84c1a9e0216f23bcd2dda0bbada6a4acca78e1e0d765a5290f6f4929f6d0eeaf1306fed3c9766ca7c7268acc7effc9a7fe773a420ca430c58bb94e7baf26b9a97b618a15e7a18b31e5914f10000000000000000000000000000000018ca46a89dadcd3b54f60fdf9a7b97c95b9e0668ed9329bbe4121e588a1ba773c9d086dc35b699d65487f428c00ad8c30000000000000000000000000000000003ada6835a93310d0ada01bd7fd6778bd07e718d1ce05aee2b4990bf32322fa94ca898a531ec6e3b8cd7ae3bdc77e0b70000000000000000000000000000000004a8abd2b9f7449213e63ecdb435e5e13fe2aaa31a2c38673a6adb5e96f4dd383dacab391787f6c17579c78a1cefa5450000000000000000000000000000000002a8768d98ccda80149a767e9b5a3b0bbbc0ab4b5f696522c8f1c664f1d27f2f0a6690531672ba2070355c0e77095dc02d5a3d0370f4a58c21016d208609f1d3e7cdf43abdb85199bfc67dd12f589b8a00000000000000000000000000000000048fb58924bd5952d3bd7b1cd57a1dae6c1034df3a420c1151737f88760e4b0e78fa3f891a0dc32fcb50f89e67b0f08300000000000000000000000000000000073e9723c80eae7685db774d3e2bced53a52f24504fc3aff98e2becf8d59c6e83373ed024ec1ca50101d2d613abd286e0000000000000000000000000000000003b64c8e9a1341bc6a444a871843b3add7dbf04bd1810e1d6da7d31c7c2b7a264c362ac9a366dc8d93bcd9392c6056f000000000000000000000000000000000064462d424e54f50e9849a2bba1b0caae966a8618fda0f8965b1a841dd2173872a44a18ace1e2aecc8e3546a9558d7013549b86ed3fb880269be22b9cb8be6f24385bb5e24bba81bce9fd5b72ce2ab71000000000000000000000000000000000c40c8da9281a8b43478c28b2fe59a3cbad0a818e2077d40cfe44624dc2e46f72d4489cccf63eb8460d02f895e78edf5000000000000000000000000000000000735d768f6ac999a47c88bc2f3375f01052259dc69011480e468d8963ea8eda74726c4ef32c8feba52878eaf5c0147730000000000000000000000000000000010adb3ad214b17b963586a10701934727edf05fcbdc94d98255632647d73536decd0c91363840e1b55f29f7d32f650410000000000000000000000000000000019349045e6fd25960c03336888679cb53409027f35a1f211b40d24ebf724866c085a978ffa3a91d989da1a7902bca018c8f6dd56906fa13144dc87c31b53186b0683cad220ab2de89d2fb515bb269cbc000000000000000000000000000000000a5d2dcc05e218b0633e0a965b6d69a3c6c1c7837e1fff7ff75cc9ee93a112f8e34cbc95bd9dd8fe6ed22f2e9221aa110000000000000000000000000000000017d2e5d2c0578b1ec26b57c3305b209c979bba6925756892f031a7462ec44e8a4a2527e6aa2fc13bae91dcacb8c7a30f000000000000000000000000000000000d437edb45ace50700db548db68b9e8376b3039fa00cb98dd00cd197c14d0f92c8a3945127c43b10b34bef7894fa43410000000000000000000000000000000010d5a2e442a2eb35aa85fdaecf094c1e1f307dc9bcc540693d7206cc4e0d050ab900f17fbdd0754b59bd2aae705c60149ec934eddc44729d05f193ac927fbcb022288ffb2bc7d4f46d1bfcc7efacef940000000000000000000000000000000016c36464b426c3066aead1aaaf65ca637e93279e8ccc9d838b9b3ff1aa7b896f36de506efc2b0864763cb6ecca4926f30000000000000000000000000000000006d88d5764fc854ed7d7cf1c0e210496ce347bd887da2a149a09679469e98c453d85115afdd2fc4987b64a88c4a6f0a200000000000000000000000000000000053edcc0ca4c205423ee6a7031939379e552bd2d2657f8f25370c9f0ea0a947e77f18b5f218f98d12d720667844f3795000000000000000000000000000000001292909190854cee4499faa602af99dc49d1354a71278b439e983bd89e6c504fa5fcaaafb6ea26dbeba9850bcdfc1f69bd211ec887635ca841c4608fd00bdc0f5fd0f6365dcdfd7d6f4c36f4b25b5b1b000000000000000000000000000000000997e79a7549ada9ee0233b3bf9289df3ff797595f4b5eb2e7dda6977ca981c1c4a2b91b924812b95418f1b1d9d0cb830000000000000000000000000000000000256b830e80f238e8494387429d727a91cf5d323ea87f7dc143058c05e11858796adcdc677429d1db4dc2415cf23808000000000000000000000000000000000cab529c6b86beacc57c874f07108d1df7d98fbd59fce44c48afe9eb2dff823f4869b620bbafc121b4ead2cf244974de0000000000000000000000000000000002774906c1a0acd87de224a9450617db37f8f36a0a192f5daa2774eff0b73aa79b4804342999df761f8572974c697c6010bce61d4e35770e7737636c0f9a664eefa948662d3d22d1f1708fa48d3043de0000000000000000000000000000000012abd02540073017011e186586023adfca36fae454350b2015a796b7991eece65b63964fcdf581b4b51dbd7ddd506ec3000000000000000000000000000000000ccd3f2d9280908d4b30e924e4a862810a92e1a880cb56e842a94a2a5120956e8713f548ca279d66d06ab23e4976e54e0000000000000000000000000000000000c052ed00fde2cab515694d8c004de910e62d07c462345ffcfbd3904a0171b970bc58d99c5833059315283004f3390e00000000000000000000000000000000008fc4860366074ec0c7aed2c6ffae7c93ae0a81067edd8911b4c53393ebc0f23243823aa7aa2b2e987cb510f6e0a55a65c86930c1d142985bf85ce70bbad170947e850e5c6ac7803fc45980dd37a57d", "Expected": "0000000000000000000000000000000006ced307065868b6d082bd205bfbaea3b0a8cfdccf831bf154563b5a942154622b0d7689819b337479480d19aedd85e4000000000000000000000000000000000c0f04fbb26cf85c2c22763f3e78fe255d8d1f45ea47232ab58f5b785ad9f2458b0b28f3cdc25c4dfcb47d59957ae10700000000000000000000000000000000120e38740eebbc3eeea9beea483e70d6a9c30a5abd61b86e5f94bf65ffb40fb92c8d246edbeca425ace175f79c9c8afd000000000000000000000000000000000d5a503a26e50f9be34c2e64e4a80402ca6e17f09db1b334a9c1f6318f3e7e63b3847a7ca38ae6aa7c96ff94bf5de842", "Name": "matter_g2_multiexp_15", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036480931a5a585ea54b6dbb01759eb1d86804e3f03326188c71f859613722e662c453096431171a49eecf8653f14d470000000000000000000000000000000015fcd6a30b9d59a90d8595ca1758eed7d6810d2916638dc2cb637aa09b16b5ba4920df7d21fc0b923453a6c7d32f056b0000000000000000000000000000000019aa4d8e98808c2fc1273d383e836876b087ad5a7d01743bded01314bc62ced94052d75d312a18839c1b33faa9e2e5160000000000000000000000000000000015747ce0f1171c0d0ff1fee9dbb2e5673b9db0b0c3618cc8bda474f378db58ea42184f907593f3d6fc2fa215cabb7b2308e559e394a9c1ff07a45bb3e022f9c212eea4ee5b77db1c5b93ce72c0512b79000000000000000000000000000000000222640c1d64948daac3ff93e86ecc96bcf9c93559266529a37ef1372a81952431673d69f1220e07b8aa0a4f3164c83b000000000000000000000000000000000db593156078821cd0ce0270e8a444d0d204dce0583774496620bd4752839f3451e505aeb3db568048739c7e71d279b40000000000000000000000000000000019932ad2c7e857c2dd51f7846534050b9243e388260cd47a91444fa050a9154eca88ab4d29a37def16d4a11d35683f2f0000000000000000000000000000000004d15ec653a72256ac6b616e9870b0acc7d46286893c0eec523dc27bbcf5fe596204cbf83ce71c2690af67b3616794225e55826db8d12169a31ca27beec80554954f522b56f7994c62bdb527c2438d5d00000000000000000000000000000000180622bfa9a1c452f343ed21a3e9c6fdf76589cebfb9a3f0a53782a3e7c9d066294e10699c386b5d0525003289f0ec580000000000000000000000000000000006615ff63c856302dba6d4e25d1070fe873e0c4950ee5ba8bbbd4b94ceeb181f1ee450acfd22f21010b88f0b88375777000000000000000000000000000000000cfd3940b5eeefa92d775792affa34371d13f3098ede3007e06510344ac8483debadd5a2baebafb5ddcb45a9449768b200000000000000000000000000000000145be0107a1e3acecc89a116668f9887579ed7a72abed3f4236930edd3f18974465c99ada86c4980c88768824216170f1362e8e39ec661cb3c5af64e0001cc94701194344a7404f1ecf7df0d5633eff9000000000000000000000000000000000820e74e6d0333b6b36590ebae78960d019065f1681ce68a2a01a2522496c840c668575a57f9fd0f50b87f928a41b0de000000000000000000000000000000000dee60d90e96019cf2bb552d016419e92dd358ff97039a61838b0a89ccbbd537f2b435cd11f7b6e75a4ec6675964e7fd0000000000000000000000000000000002ca767de9fbf8af7c73d41a07e1c0e38e3fc971472e11928b65393a27354b2d732012dc57f498f94c0b933565a7493200000000000000000000000000000000134fe97b24e153f0e9a27d3fe7b89999c6a19e353325e0746ead013198b8e00ca6472fcbd2a112aecb9ddf671aaedd9174d3d66cde7c4c8a4499708a0c6f7c4da458eb970b6ca87e23601c702365b6de00000000000000000000000000000000031a9c29323196ef31030ba73827d228e56fd5209eeef0803a189e0c0e5b186ca1f342483eeac99e1e1b12cf490856460000000000000000000000000000000010deea45a01370602bf57a1f81413e8d3b337d7a1a33f9525e4ff7003454d1da2cfb1a9b42c4a654320f91fe7d04b6200000000000000000000000000000000002bafb7b7452a173a3971c2ba1768061a043307d2c32767056f18c1bf8b066176937876a87055e54675876bc1b2d2fc3000000000000000000000000000000000b5c77dba3b4136a7efaa8c2e28f39e88afbf26a7313b52ad6e390da4d948209d96e39aa08eb52200dfb890d7e88b46a389e0d43f2006449fe2de506dcdba4cd0e6077e2228f7d8b6ec9d8a4129c494f0000000000000000000000000000000018bd1ea5ee8e39c43d442e9c6fd22706e582cd80051f18334c4db2ea91ab019f54bc0074c8f0e52e50367197a797e7520000000000000000000000000000000005c0bcd1b047fdbdff25b138248bf4da4c013beff7dd3030c348d6b2b8724a147cbc44d570db5c4b273c94d0b99bc2290000000000000000000000000000000018e033935c20be5940863f7e9e39fcbdc29ba031e58c10beea90cc48e9da9988fdbf108bcbd87948058f386928f81fa800000000000000000000000000000000107d179204db7b288315e8aed7b92ebfe53b7ad2366d5d7944b3df68d9d9faad023e477213f85214047645bc05fd4cde5f8dc332cb31e43bc2e551356cb8d1533c6e567d34622667e7e4e3ddef352f03000000000000000000000000000000000a7b364fbd3bac7e2f2e7ee501db2d248bd73a76c2a12a3e51718b56ca9a8ded14b83b8cf0b5bd46f0c26896a65fdb15000000000000000000000000000000000eafea7128fe20ddf740a6396bf18ff5f2652a0317ea9b6e934927c3ee95b59c7dcd51f7c895b3989d40ae5f78ca508f000000000000000000000000000000000bdce57be904236a8df532c2c0072165b5cbd4103e9061fcfc0a45a67e4b25d11b9f816f63fc0eac4d6d3e10d2764c4a0000000000000000000000000000000012419f94ddbd8275054f8f89fdc27a74afca2eef314393236fca65705354e5cc0a470818999c96b5087997813823e9be0dc7052044251fd360538fa6d5dec9fcee53faf2f07de5d8df212d04f968a0b60000000000000000000000000000000011e4010d0cd7855a92cd5d4954ad735363c0c2ab00053db5e078f34e772969d8c492892329cb95ea8893b4b7ff7aaa5e0000000000000000000000000000000013badc54d90a19b84d76b30fef8e3ad2cb268204fdaa50ae951b63e48aec9cc6d585751dd48e4a8d4659b835f38f8da8000000000000000000000000000000000460728f686b9b15cc19ef135af71312e174860284c3f0e7a84cf85a5c934e2bb6cadee8e482d88afe788a796605f79d0000000000000000000000000000000019a50c06ba307d83452a30fbd862270652cf5c7a09b150fcea858a8102ce3b1e9ec13b6abfb323d63d2c4edf209c7cafc579dd4f361fed9084d9c66a3ec4c6af5293710ba5299df3abc4cbaf5802b5360000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d69f0f3c3f516ae34fbecf45f4636c22acffbee765952b332c0f3d8cadb9c93f10000000000000000000000000000000011982264c8c078518cd0adb05034761224e9063654904e06fb5e5a6eeb1f45e4ff3da661f1232693b79336215dcc0cc40000000000000000000000000000000010c96c872160d2de03a16e85f2828d0cf2dd16a3389effacce46b5b5eecfea1042a77de653da5a1c0380a84c435723fd000000000000000000000000000000000a4ad2d9956bd407c555b26c192c6bf59bf89e40d9c6f9c90780bba313a39db71a73e7633397d47a3f58f61c81edee77000000000000000000000000000000000a7f912530d27a7bf74e01d8e48890cc66f72d14950554991ed1edfc504062ff6bd3cb6941bb398df9fde3cefd33fc0676618f1954730111e572937cf0c9f7b3298a11d18cd890cb419f732c766bc6210000000000000000000000000000000015bc12aa9ecf417fa5bace8d9e5dc4a418555eeddde1da8b624bf7d6e1873ec4a257d5f6dfc058a8d9b02528e699abb70000000000000000000000000000000015b41567f8c780f83342449f27094bc20a839602ae482de14b92e40017e7acac8857db48a2d27f1f1a625883b6e5255e000000000000000000000000000000000cbe79ac0718555fd8fdc38b68eec8be83b32499d2654be44888e45a2d610b0e81ae12fd56550524ad85b5a632db32ce00000000000000000000000000000000069f46b5baf4357d8010869685b3828c0dbf6e2338598c9b42dfecf0b22d803f95fca716115f74c77778d414cbcbd881fbb9f2400ed1dec7ea63d2b26bb3e9c2acf70117e3026626f6f88a07876177880000000000000000000000000000000017ada4038189c544902167be958e43ee133730e5cd329e572dae2d853b694f5ff8032bd9ab41cddd11c51e8284970f810000000000000000000000000000000013eef75e6d28deec945ddff33128c199fa52565288d63677c824b8d56a6c29eb98d34c5834e84865be35d40c1c59a40c000000000000000000000000000000000e2fb4f9c7ba6bdac1d4ff5055be609abef7fecd7923a753a704da537c0ff41951552420bd78d14cf972dc84fa3f5dd9000000000000000000000000000000000805376b814b8a59435310d49a43081dd7ea36dc7dcb40d38068ae9085b3ea9a3b2249234234cacc76724d8ef84a2eaca0170d7b7604b8951a95d49b6697e2d0cd2a41c3671d8f96e936cca911dd516d0000000000000000000000000000000002288860f2d671c84c5239313b7f6b82e31c3976e6d310e15d3bfe1c566e2ab5d86ae6ed0df02530f9f7893ba419f1870000000000000000000000000000000017365bc096e260f8dd7b189fabe10eb66923783b41fff70a149251576b3b465c13230dd0af13cde562751dacd8298335000000000000000000000000000000000fa8eb9c818df27181b45a74b333ab481dc7212e417c4e12634816f9e177064f9e1101deff26156d26bc6574db9617080000000000000000000000000000000009379598bf02222e1ec37a721b9ea31a3adc33524c6a41bc58da06caa3da3bd730659f0a80f793a0fcb9c07b43ca929c2c2afc06f19e627e9ec0edf1083823d30ac569346040965e1c92e0c15011c90b00000000000000000000000000000000136870e08ff5fabf36410629ce5c23470eafbe73a7dceb633df5c1492e39445b86ce15c22bf4c421cfd0adc6518e78c30000000000000000000000000000000010aefa3cdf1225da09b796430d096807a83eb2fd5a58db3a4bfc5e500dcfcd472fea3077f0c059620f4ff708f37c95a90000000000000000000000000000000019ee2c62ff860338af623c535979ed31c42c0d0b2f82cd56c153e80e6d92bec9ce39bc8e8f285d1efd1c1e969521dbb50000000000000000000000000000000008ed69eb0a16c8a35d507bc3a50bfc97e18143fef611263715aacf5400cb1aa285b6d2ebf2ec219d2fec477360875a03141d0ff346e46a20c2498a74f910e9bb2d5d8530afc7ba47c3525861c9e8c5920000000000000000000000000000000014abc4eec64f2611197d0c1322c3248eadb725049379e64682f2b3d7f83f7bcea11358d88f52711b3020924b6ddd84790000000000000000000000000000000009fd78c5d1d2043d83be30a88f046f5b633c6dbb11bab25fa3037bd250b6b9d9394327aae25d1939f777fea9f3df46960000000000000000000000000000000010f413640aaa16a95afba98660f9e1b03a8f3e0a7a3d7f2b971f71b5e3d09016ac2b410f97d20471f48621d5a363e9e6000000000000000000000000000000000154b5df93298a5a14a6157819e38db33ae7f2d11dfd13f7f2a92b2fd9b053fbd25f10a8c45db3026f6f583bd56eee0f1d688a1aca2a837e0a353039294a9988a7111ac134a6a8a68e4f881e7486025c000000000000000000000000000000000f1893df99adeff5e4042c4c5e8557e53f7c34efcb2a7953d5347f81d2f4a75ca0273a3845f54e795ac1c1f8ae7240dc0000000000000000000000000000000004856b05d58898be6aba07fcffe487dd895144c7ac8fa8bb1a37c61e73bcd062ff541d510e24c5bf005c8351d3ddf61c00000000000000000000000000000000178b22c2c698dbc4929b119474a741ef44d6275fff5ba058d9debe9475e71398e464aa14a6712c5deeb5010d1c7758ba0000000000000000000000000000000005ad09389c35c45f349e6dcaf1cdb3b63648b3df427ea0c2a371f45634635f9253957ba6987df4aca6cba4cd472308a31b59c33ff02791031e7a9424c781ff17a209d132af06f5b825df363fbd902cd4", "Expected": "000000000000000000000000000000001090d83d501373cf07c75effb1c85852019b39eb0d77226823aa3c1054d4e408e82fbf0f4420a30144c611fbb856748c00000000000000000000000000000000120a1e3795f6d5c4ed5b886256c611bdd209677f8324b7091cdd7cab11788b1c0f780e8b4c38b84d7c2ea528123d4783000000000000000000000000000000000d250df34d906ed421eec2a78c2ff4ed4eedb717358d7ca879d58ff5b4d2d72521082dba6ac5d10859125e32c2c8b490000000000000000000000000000000000476adaed9d80cb1545be505496222dba1f0ea85d38d5bece0663461e0e9d47abbefe95303c926db008d08b8aa162e27", "Name": "matter_g2_multiexp_16", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e1a9066289392b0b0b8f0986366c2975463c9cbe7a74f2eafcb3b8b6d4ee3226ea5886aaae374341bc76b53b165e22a000000000000000000000000000000001557cd01b61b5f2361f6b558a87c67f2778e11c21734b7ed25f72a88cc62cbed396d583de4c2190ae6bbfd096c33bf73000000000000000000000000000000000eab68305118d7e7076043719ac1e13ecda4497df2cf392d6aae4b7753f114d30aae3e8535742947636901feac4b620a0000000000000000000000000000000002cfe5014446556b82d60adf874cef25e58eabd035deb4717c93bf0361f37a4a67aab70b95627326bd97f111efeed57f58fef5bc887b7caf72f2a533fe1455ae523841bd49b4adf16cfe87edc6f573eb000000000000000000000000000000000c8fa30f6055357f6b697f2115203428b8005ad03286d2b3c805bf3d4dbb461c30e6ee8b0973ef41f884b91e857c53500000000000000000000000000000000005e1c785feb4c4fb7e960233d431d51a4fe471f10321251d018a950374d2a686d52ee8cdd855a29e770bdc1bc565f471000000000000000000000000000000001158d31faab483832d39f5431a5d8aeb952d6a63b82ec019f235b5b2e5580df8cd91b46cd53d4a90b9db354b38c5a1710000000000000000000000000000000004a389b09be6fb7ffd14d7f3359b17991e93d92a1c0b9a89faceaf71f5ce77a1875aaeb7a0ec3b2dfb363c47dfc9875273b243b83d44158a66eb6d31e7c4ae1f4b3ddbba81b2cf9a654ca7c4ea2147ad0000000000000000000000000000000010587118c5f90b545ee707466ea2c5f378e6795c260235cdf9876aed8bd753aac592ee05e23882ee77f4a13bff97f5940000000000000000000000000000000000a0344aed244b90c4fb9ac337edb01429e09f951062b06025a5212300f5471a95f28e09bbc715417a6d98423b518c3a00000000000000000000000000000000128457cf374e5b8864b8241f476da093f48553d609a5f30c0f0f235ecf7127231237b6c8802f2904a8304c7c237842620000000000000000000000000000000004d55ff04eb09b33ebfe90f2a0966a1b59cc224215c0359a4ff0c09e60f9fe7ad8342868184d8cfcaa1d8c28328864241ea87af09f6e62111c48993c408efd3db9ebe218ac68f61a461ad9ec1306873d0000000000000000000000000000000019e6992c3da47715bf379a668a15668508e7ad27bac647490be8e82759b9b79c996735aa1bfdc3cef217750e4ed36fce000000000000000000000000000000000828f782c5bd4f2de3570a4930db2c020f75f93adc98aa0e48449d29c7a3b0d5c349963d956bab7f985ba6ffe59c90ec00000000000000000000000000000000062c7a730d286e895c57b75907713ebf1d20650b5e621f270f1d22a2ca480d022346def4102a62eebe867210e4b6122e000000000000000000000000000000000d6c29462ad449ee6cd122e3dc00d56dd5caf17a2510e5305aecfe85626cf73adb401ec2192eb693158650893fa67412a691b9635e38a46e2469811405ef6325ae7ef88a67c1d1c5b05806da329f27e000000000000000000000000000000000098de9ab41c289a05ba5a774eafe27d91aa8272fe9f81fadefba9a0cc0e31de20f808ff454a8647c44f5aa632742af9e000000000000000000000000000000000c96019bd5cdd62df1642656f0832ac8ff6aab86f671e18c1c7023dc16b8ff54a8e3e446b19682a23b73ccb90da2fdf0000000000000000000000000000000000178e3b4366b2517d4c19fb40551be6979d46319d7040682241b046f10ab88d269dfc097ae02952d46e69cb1cf159da50000000000000000000000000000000008341bfe1e2fb999f0c3f4e79523c720edd332401f9dfdb8dddba8d1342c2c1fb20ae2fd9dda92c7bde5a0c95ad971f80d9a35f474325d0f065442805cab3beae4a186b252ebae54a567dec6695588f1000000000000000000000000000000001004d60af8c21f7c62fcba1c5c41b94fc77f64b89abcd23a218f0da8f47d2ae6879ddcde52f3e6feeae2dc7b2720577d000000000000000000000000000000000b8e8a7da87aa62ca852e2984b0f12b85052fdd03883f01f4496df0835d1cafa48818b5ff1e3cb0e9ecd66054540a0d40000000000000000000000000000000009c16854580ad8191e3e80a0afa8da759a8b2bfa7e0d556418b5c96d97e88a12fb75a91cd68c2f4336c3ed7ac99199fe00000000000000000000000000000000195ce9c562c460c7e715908991ea8b017b81561b45133427f63cdfbe8f65202bdc8e8958ab0977b3a244cfa32fb35f37c20e998acda67d406a238f16bc2b3066a6d69d2436577b8900a180e6a71b0a01000000000000000000000000000000000107292f77666064b7d80d73ea8f3b623170ef79ccc7c228b8366675a422a0cb8491586a2e4ab1a067c31396cd670a8900000000000000000000000000000000126f8136dd61d61b2a9c0f4af3ed44a3cec3ccdedc74821f341d200601a7bf0a17079c824de6cfe28467e843d0c74d2a000000000000000000000000000000000bcec8afcc7ee56b36d6d08b51f61454c8fb15ec5baee1117ed55af8fc85f68674250334f79b0fce632e75623dd173210000000000000000000000000000000016624d64660b63b70ed197f6a675911b02b0bc6f880348faa6ce4727af74127c509ce8535d8dc8db5ae2d71aa497e0756fb773cde356e2edac3afd2bf703b59161162dc1e915873ecf606dfc0e6efec5000000000000000000000000000000000f57747c20e1b3923c7e1d8bd7d877736cccc0e0829837a086d62d48cb54f323d90b57ca3339fe4b256df529bff11363000000000000000000000000000000001940327a1b319dc4212e7a553d3f49904660722c89636f6a38604d96771fa0fc71f57674b7aa710db4275822c2b89903000000000000000000000000000000001956b81bcf961d16e50c053ca07ae67cb8597138f34a9dad4d82e0e8d23a7e08b751682d588f229311bc63f9598ef448000000000000000000000000000000000208981064443e8c72987945e399b45b74e529a0bb75e99b7d6744728e5c182a6b0a10e449147bcb0b0cbe70edcdd845bffc1a58dd06752a2a77abab835d089599b4781ae51ab998ff3c5b68329068bf0000000000000000000000000000000018c35ca3a63053fec853e8fda5920b560f1be28431f2f4b08789c7a202336c8905a5ffffbf69ae4427f267b1e13288d60000000000000000000000000000000019de96be76bd93886cc486c2671b5b0d731b568638b1b830a52dd4c481b9a1fbe2b3cef14b46e25f1188ddb3c158da6e000000000000000000000000000000001813ab16a11c79eb3d3d47ae7d9a7c05401ee91eb1183266d23077ec4c0c8f3ac7188eece06876025dc3fe271d65d4ba0000000000000000000000000000000004d2a416dc874e956fd6d29a3fb96195019f4136561b4c127541ac171b5a6b229746af6d6e535a8017e64ce06709e52e57f35cfd74f62fa39f919400f4d692855a4b4e9f91920e4306ebb2e772a484f4000000000000000000000000000000000623b7a8a1c24dcc603f01589e6679c74c4ed3452894e536a4cea69e99047092acc877dd0bb395b0cb693cb1702a64a00000000000000000000000000000000013de9dc75e42f12e905d729a52f25bb1a4125f5edb435734649281bdfd41083716d0797b0a80d842c2503d09cc61162a0000000000000000000000000000000006453c06f56dbaabd4530160bcd5312b8a148dbe19fdf9f1e44b7b047a73ee9ef9d981116d00269942ef73537885eb7a00000000000000000000000000000000075376135ff3acaecc0eeea32f8dc15add57e8f0297d053ffaa0fb0a8fc4418c5b142f96b6b9ce9eee2f949c960aed682d1f3709700634653374fba5a94d69163ef616a72a63d462afd9f01c9ddba84000000000000000000000000000000000120d088fc12210c1f5f6cc3d1091563f9a37d4d0e0d2c305b479f4d7e893c4d5c8170eb164e34e4843a21c9eb193d11d00000000000000000000000000000000159de80db3b1f0ffc5fa8c93e1bd54cf8ae19cbc9018a5dfed86179cdbc976c1c312212080ab221806bbe142d496e7a7000000000000000000000000000000001103abb75a78220218cde4bc4c59ddb5fb647ff808754dda200bdf586ee9c47a09e03762bb726b085928ddcc998af3ee000000000000000000000000000000000bff4bea17eae0f2ff3e7f99bfa91e6ae8aea28f6f3fb6080eb644861defdefc26befbb7874f612edac0cecf70dfb275614ed9a08dfd406df00719d5eeacfb0a96413b608974fd0aa1d4c6176b968dc00000000000000000000000000000000012dde607a2d4452c6c060054c8adb6307743edea3ccb6ac34c275717f177f0e454d9e33d4391208198cae39d7eb6f6c00000000000000000000000000000000014cb4d8bc98060ee68a8ddbc44b83db5cb6d09f09b0d608357629251c35e44383e97058d0d68fe2df3bc47424a5dda03000000000000000000000000000000000c14fbb6c844fbf896fbd3cb3464a83aa4c6e9a7f0450ad96a07527df6f1eeeaf587f60a990bd6abe7aeaf5eb46f362d0000000000000000000000000000000001d9468774318ea711b79f16303ce86288cee312af296f1c9f607ef5f97c7d1cb48a7218775c8aef00c227ccb586286e7c1dd2e5e5f630fb1d07e8934dd3ab029917e7775e401c0bcf7e1fd83aef728400000000000000000000000000000000181e7f8d0ec7a4a7858bc96b61484c24dbb9dfeb3746fd3a231a8e442369e3e83516ee6043b1c06e7e2043dc86f6c75e00000000000000000000000000000000184c1d667c0ece59f18fd2eeafc66f1ed530b7d5f4560a6c886429caa13255c63dea01c3e357e3408af58a39420a8b28000000000000000000000000000000000a8475ea694cf607246a1c50064cf90cbe50ad5cf8006934a1fdf1621ba38d20e70860a2b5aecc05acc60943224cadb60000000000000000000000000000000008afa03c2df8e83fb64523c57d0daa7cfbb7af6a4bf2960ebc64515a61a659b2c37ee661050cd538fa00cb34746a371b64e9d16cb61f2bcdef30cf544d97e078fccb999b96a1da0eeaa0bf232f01995f0000000000000000000000000000000008b33a297c8f86f1e9d7166f9e905283c8e1581e582b879caf48585d0bca3608fe46d8d9f6e7c90855aee9d92283d7a40000000000000000000000000000000016962410d6b4b6f91437617e84bfaaba49de0369b8748d2e2dacb63b421e0d7de4514e7fd3e0dcbcfba8baa4915610d0000000000000000000000000000000000efdab72953b870d0e113efa7c183d99aefc100ce59791aabc72423aff70a5b74c577c06ca94bfd6a7722199b4bc22660000000000000000000000000000000013b18e31700987dfa4344384f9b41e72afe92c39bc961333cad3e7d0a5efd3842a5e849cff5655c4673f720fd0127dca35bca9082d66c06761f702dd439faa4957caa70ce0343268787f41a2f4bc0cbf0000000000000000000000000000000008b86f70c8d8b03b0e9a8975776d7fb0d08f95eded0a0124551d363c2df57124e0e89bd45ddd1cc75c258a4ae2f87916000000000000000000000000000000001120eef9eaff7c308b629deafb060d2c12b20b57562007fa810a2191d99fabe9c7d3c364caec1724665ef556de66b57e0000000000000000000000000000000007698bbef6dcea67a2c643342ab2a0f830c329fb6244d4a98512daa8a3c9d808cd2acc0cebbe3da920053ad73eb7cdc7000000000000000000000000000000001155b6beb28fd88d252c6b407bb9f55d22103257287ce77353bea580c90173b5c3d49080b319ea28817d67c52bead96f7980eac6c8db86ef83748d10b210835e53baf8cc9f607915df272b6e28ac6b2800000000000000000000000000000000142b28509d72f9e3be9ee916827fc1a8dfc4ef7ae2b72eebad5db605fdb2dfa4492b50cc3e472df1b52baa6e2b0eff5500000000000000000000000000000000134d6821088ce4a8b42383d5a43a32bb0cdc96c85f304a2601292670633d5e231b9dc479d199829a9ba9f39c162318d5000000000000000000000000000000000636da344fcb0fe50ff3e22f8591418f64cfc722b2860b4a5047f973f42e4cefb93c2f8eb8a14b4d150758ecbf3cf712000000000000000000000000000000000e6fd06d5dca702cc9f199f7583add86c82f7b530d4dfb9faec36dbb669cf7c1cd1260c7e4f3026824eeb5b979e9fdaea256ebae4b204b3888d7bd244bbff26431ab5890098870f13800bb3be3e842ca", "Expected": "000000000000000000000000000000001684f447f8929ec0187811f66e985f0014eba46eaa87de2d4ac2347d10c0550e4044ec7792d9f315c50081dc2097ebdb000000000000000000000000000000000ee0c46efe930bc98f39dee8cc6a792744e84de4fadec035d25ee8ba82e1c53264d0885a1fb05b2b8dc9c6a1846c28320000000000000000000000000000000003a5ef98843099235a2ad9522c9cfce1908bef77b45794e7df9eb38a4854460031829e947a118e8160365fbec3725b85000000000000000000000000000000000dd205e195abef6a4cfa7da66f022a418235e1a1b2fefa6bd3ddf8a3851d8ca8c27652bf87ac644cd189ae55e3cc7808", "Name": "matter_g2_multiexp_17", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000064698182f90c20ed6f6da7248cea32a291f901876a900d344ce4dc1b07822b480519cb8d891b5ee4f33b4efd90742cb000000000000000000000000000000000e7e9d2e79ec4b07015baf69a283f6a4abc8d7c1699f3356fdad6ea9b1c70e41e73bc14e500634d73749f9900eeb65f5000000000000000000000000000000000002ddbf40619ea5123c100e2d6553213e37883fb34f0f0f2124795dd971892d5c9051cd4aa78b9d20f196301ca9bb4d0000000000000000000000000000000017a07b32fbffdbf7a80f0437eac1ec5fff5a68f3b053482f034064992158b604bc34489dfd41a24ffba806ccb871fff15805f2e8013007c4f6d8abf441728eda8d742ea2f1df545f85d092f50ca8275c0000000000000000000000000000000018b4de9c04fde8b708408efb3aa7f24b5f7bcec14e7d06fd5a5b36bab528e5adc0bbb1e378a5ff6fcbc95aea530ffc6a0000000000000000000000000000000010da98267770a47e5ed14ffb3dbcf537dd14ae5eb79522c772a7a2833be214690db0b4e86621de1842d88018fc0f348400000000000000000000000000000000135548e2eec9ae7c3d23618d8286db13a5a628fee04fb6ec9da980f3a46838899cf965c1cc6f562e71d5b5c7428cabc8000000000000000000000000000000001669fcee7804df9b7bef32e2ffeaf285e8501842efe87c9e827fce872dffbf92255d3c3a2fb5c382ab7aec0bba1ae0e5502d777b25f3112ba2264022e2f28dfb6e5d5239ba097e9d815928be44b6a62a0000000000000000000000000000000010ed20c069bb300a27571adabd239e70b767af90b91c4d0e93d88278a6da47b7c12fcfaf62ac0a7b9966968cc9f3770b0000000000000000000000000000000017273eddc25cf41f2d7734a3866711e83d4f2823ee6a036942799f837d5ceff10dd6022ea25e3c1e28c7b14ed8f4e7c5000000000000000000000000000000000f201f314f66f6b2c6e1365c0fac7b187d31bc45b5edaef5243b5488e26581dee24de4a5fe493bee44165cc31d8d72ef0000000000000000000000000000000009dfbdd86633edfacad6b78d292141a1e653a1bfd8c48a96b2f6bf8271ed6033c0511628caf2ef258eb64cc8b63d8e5be7d64b471cca34ab0c91f61ff26719c7186dfcdef13895d37ead407873736a740000000000000000000000000000000005c4a4a5ffcb4a39c8809821ff275360ff937070cb97a791cc9ec45f429256a6d2d6127248b6ab0b6c71c30c4fe84ff20000000000000000000000000000000019fa60f481c5be953c9c7dc86903a89af0ca2b4205be3a00d793d6de7103852e147ebc7d983c6d6e8cd99e681241ad440000000000000000000000000000000015b3b2eeb0f81ff8a2624e2ff2396bc69feffeef62b1b6a1e73ca4b9e60506c2950fdd23a37cf56387b8794449d3237f0000000000000000000000000000000017021a69ceba3446dad9fcfd8cbe5b89b61372f57d43a8d2e2c8f4534bef6b91408409dfda9438f24526f7e6bf1f4240e5723630020fdb48e44adda735943c91ad7d1e12f3c32d823833eacfcc8b02ba0000000000000000000000000000000007c8f07f22a3412fb4638cb704751959cda4e42e4612edaf5b1f22c8f9ea314508353445114bab6c07ccbb4b0d0bfa6b00000000000000000000000000000000062d087155c8722d0102c8e5084f95f5f58ed626d48197297d21d2108ee05f70f16d595ef73e8e1207a3c0b013fe16710000000000000000000000000000000003b6652934f3acd4c91c6c521c2476bcd2594a939ff2e7ebcbb0f451fcf0a656a518dbd4f36f165f9b2f58054e9f778f000000000000000000000000000000000bbf21158227e0ad5461de9ad8bd580f9e65327dd4e23f1ad55618f6b0aec45aa6076fa88557953ad15d385a074bc7d96e9e37bd811b76133c12268d325ebbd6656e7ed718cd777458867dc98b1b3bc50000000000000000000000000000000019e336d4d342f110eeeba9773b8e351f26bb56361c77fbf12fd9fc218fd075ae38b95f4a8a5ef830fc2cd92558b1711e000000000000000000000000000000000a112725046ca3b6cc43207e6b36f38d96ff98dfe3444d67ee3f4b0208f3b8543768dc9989f936637d7819e7dc5740fd000000000000000000000000000000000527682076572d8cca15e47a2faf62b129baad29afed22d32ea47983a8d0b138653c1353bfc6fbf9fdbec2efe36700f90000000000000000000000000000000007e3c5aff373b5154ae66f978fcd66d09cbebc7e0c96b4a4cf23c4fa5f2fa655410c7f1ce597a3f5f155017720f7c50f7d46516db284a3938e672ad3c6bd40313d77c5d643ffcc59e3f55ad983cdc0ed000000000000000000000000000000001865c265ed4606ed16056c0b28f953119751d7272bb33b9865eed312ba23b32d01733ad5446cea5873c2bbe37fdfce7e0000000000000000000000000000000007018aca1e7ac211921cab1cc6bb18874d2f39f00d916b8f3d46a088a378f3c9b49ab8a296d0aa21608f11b144a0c687000000000000000000000000000000000210561c0bbe5a9f4b2237e5bdf88bcd73326d395277deb2a883526978df90792993e6ee520c9d5ec0a6f7ef5c6b3542000000000000000000000000000000000cdd344124b7b5da556f64ac5d651a6f9b74427fd712007310d720f3236724e2284aab812d739a87f3a1bfe8737dcee7586cf63c5e52b44aaa79cdda6dd6fa92c6fce11d867b2ff5a04c9e44e0b3930000000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c53efaac96bc5f686d6b952e7082236622b737fda0dd3900bec71654bdebc8ba2e40000000000000000000000000000000002dd11f4dacf3d9c46579182df1c1c45a364a8dc1eb7aa7d54d0141306f1c23bed85235783a22b8e6dc4adc35f9193ab0000000000000000000000000000000010d1c642fce533039e98712bdfcda86eaa62d2d69b861ec4fd835488732fcea414cfb6f3f8414152f9d5398c73a74fd2000000000000000000000000000000000c6759b75b1e3fe86c00fa124d09c5b7438ad61fd1bb71695743ed7793f39b7a0fc99b055201ac1e3aa07ccec61b24a80000000000000000000000000000000017580c9341789484fb31386eccc9c344539a09f1c4421dd124b1a0ce61f2d0528942f7fe8df67c6b2bbf782996def47b39d6045573dafd09ab2a0d8ab6e97b0ade43bd79d820749ecf19cf7d99792ca8000000000000000000000000000000000d9c48a111c8c74bce8cd78d127999531e46a411b2f0be3507226766bc8abd088638a237674ac62e0fb7dd4a86d09b79000000000000000000000000000000000073675bb81e2bfe6adb5cd929e0b7280f5d60b3dee7f797d65ffbefc2c2944a9c7207648bb096f13292ff4440c3f03f00000000000000000000000000000000024d2e0d5ba1a804520c72331fa23a2a326d461177fa527473240dda130f4ef893870e893e1dbf7c5dbb0178dcd29b3b0000000000000000000000000000000002a4c9487485ec33f8fb347d246ab0d41b883bec30d2a5e88cccafa676569f25ffd8341cdf6c09f68afae442a574f3334c4a2ff4ce4b633ec8fe0bfea42ccc329b7d3fbce96c26989b3c7a391c9e806a000000000000000000000000000000000c1965a745e42853b4d54739b2dc507d68d80b330360a4020e4412ba5422daaae313fb9597c98575c66ccf351e62a527000000000000000000000000000000000844439e6f08a411e61d37b5b2b07921049432e1833e839b00d6cc11227dfc8770ad9ca06037043668fe7ce3bf3ce84200000000000000000000000000000000152ad6fabde2e0310c978404a5244209a9363cab1f3ac9f71339cdad6d40c84f8e5a8a196283b581d0209ce90e1e3c6c0000000000000000000000000000000010eb6af62c7dba122b0e24e8326dc906370bcb4ba791c47630f05f657a228c20e010c065b93537ec84fa14a756b199789af09ef1f27cb83189e4e13f3801c08d3a2adc8b5f88717954ee84499defc0c40000000000000000000000000000000001febb2cf2d664e4a277cbf08fc1fbacd05db415a12329f7be551ed56d67f0b5dcc917d1b02951657bff3a26bd8c178d000000000000000000000000000000000018af160555292b2f7ce27112c1d60038b564f5427d62604387de97dcf48e4473107f91936b5e8008065a1537f7ca340000000000000000000000000000000016bbad2a7f5451098294a7cab2fe10d206741a99b128dde5eade581d02ca849bab3662fc3400fbe055dd93a418aecf0b000000000000000000000000000000000b1e9586cc1b357da6e58621ce09288e62a79517144f6c6b867359251baad6d40217578d49c1501f23206b125282bdf4c72c1dc1efefb775a1bda754ff17389a6b6b6bb25e22697847d24a117eb8974b000000000000000000000000000000000b88892250c848e7bc7bb7e42cfe1048a1f61dc546929211846f49501ad8c7c8817f5b5b99ed092d5a2236d59d9c8eaf0000000000000000000000000000000011680c6549f6b7d9d187a6409d40cc26554df654083f1e8a47dde826149d68da756adfb1b65bbd219f79a10d8454e881000000000000000000000000000000000f9596121dad98bf7acb3fd65fe7e0bdc8924e2390341c11d9cc9cbb0517f988ff79a5e1d60bd89449b5f042f0d0b0c30000000000000000000000000000000008982832ef53bafc23ea817be378532b95b5872217093e7c7c2f4512d03a9c9a6dbb7950563a520781c7ae213fc82897b4a0c7c2e611a24c722975ae882dcb4b45e6f6b41cfc87e8c766beefd5b10bfd000000000000000000000000000000000ea5bc2f8bc2b4088d1fed7090ba389577b11a3ee0775cb3f0657ab5b07a6709d3a18fa5fc33554dea235c60baae4bb100000000000000000000000000000000196b6259b06a4c91a0bb0adecea134c8609cf983c2c87158a69c9de3b6768510fc56543a84d1266dda78d90c3b0516ac000000000000000000000000000000000d0222d8ef278cd0d85dc8765fa7c4256394a5ef61f91301af6c7422b4cb17889224c75ccecd2df3ddc9bac98b493863000000000000000000000000000000000548809ce26cd498816ef1222d062b1ebb7313a07e99e3aad1431f984e9b8ecfd43357ea57da7e0c6c011c5d5400f7ba986d48aa5b00fc16c36dcad061d10937b55ec4deee63cc2841b7ebab84f910d2000000000000000000000000000000000b95455351fbce6f73de0345a195f91bf96abee361908cea6c4dcde72048a13a9a23991a75b9c988ba0afd9491d15696000000000000000000000000000000000305f29b05fed06ffab484cb065d4852eb323fda8c9b7c0a78843bd7143effa95cbe5e50c1a0c3a9675bb5381709b6550000000000000000000000000000000016ebcb25f1b8e8d7a8f7131455ed2be084bdcce40034e7ef24a47fc29e447f912c20c7c9910e025aab975cd2c8cf1a96000000000000000000000000000000000d84a5de7a5fd8592f6cc2bc7c3d93c06e26185787856c922d95eeee345ddfb7cbbb60b6d992c5ea4dfb33101f2ef1dc979d4df836daac0960fbbb8919d2f90c3457cc987153def711d6e8a12fb14363000000000000000000000000000000001377d654f80e933c4598aba1f637d1e37d66a96680c3a89a762f412e187817ec08f0ae897b08206a73f1a423b742261900000000000000000000000000000000014b71954b9bc22ac22cb2d7d7f373c3238c923205b223cce6c219175df2bb6d7258ae46d6cdb019311bd386275499fb000000000000000000000000000000000a08ef83b67bc972a67b9174d0e5b1536af882d505d03464c9a97f68061aa319d612de9db84e1e7b12fc3015fc2973b20000000000000000000000000000000005f716d0ffc30005e4a744092704a9e29f58fb06bf7d8d6fdbb95a4c0eeb5c39452cf662721ea3e0bcc67f25931a109425ae495ba75cdd0bfe200ee24d813e1aa93c100ce861c9ed7fa5537e11778990", "Expected": "000000000000000000000000000000000c53f0ca8901f4751be4a478088b30dce70b9ecc382455049df9ce108eb0a8d2696bb325fe9ebfd7d967ab5b9b2c2bd800000000000000000000000000000000033460babd2984a5d8b7002409349972f518364e92648927e223d7a3b648e952482c06cc713bdc29ab83f2646e9398510000000000000000000000000000000007cb9dfe603dc070151cc477ec5bb5a2a949062e8442399597c5eff8f1decff538cd0aef1384256dec73746e63a6c66c0000000000000000000000000000000016b56ee9b21c533b9c464178d14ba5c92a90e6a54c3ed319f487c2082b1ce1d0ff81131a5fb3dd7d13e0fc1d9ad9e4a1", "Name": "matter_g2_multiexp_18", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000104e0b91821c59290be48b97936458af89078b176b5585ca9a79070c7050309b01df4b0bcd84f137f58304d90599212f0000000000000000000000000000000013b00ece925fd17a8effc43e21d982553ab2764b13defaae5e5419cb9a23ca7436cfc44088c2aded63785e4f07b6e186000000000000000000000000000000000267cdd42febf0706675b60af8c0953582ced84dd5ae870815654cffa46eb14b747fb8fbb3b014e59c929da49c6908050000000000000000000000000000000011c5384d7c3e0f4fd66ba4b4c2ab60f6f78f9930e1fed233263dad25294814d9e2aaba6388ee9f924e2a323693b6e43bbb2a329761a3d6a2e4d9d63d7bbf7fc6fd321ec0344cc4d7d1b6565c475ee9670000000000000000000000000000000018158ad70994584e6f2443b8b96c1e4772a00fa0bf74865c76000eae470eb02cff627579126cc465046d4e088782557b000000000000000000000000000000000d72979d455733756a0849baa8afd79e18960f3f6dc9676c33d1663961617831f3266015cb998fff28b78300c87c2a73000000000000000000000000000000000056192c20cbcbde6099256a8f40c78a32d3fd212fe9c511951c7523a3559f60662e070f5b5e5f87b1686be0bf6cc890000000000000000000000000000000000c7b7e8ab7486012d95af5b2474ce15db612bfe1508852b8d99f4402d0e4f075ba056c19df3caa3a93bb4db89443096143cbc3dd7ec63ac63618a9e5da1f9c3fb952c6fc6972dfec6caf1a415a0aa79e00000000000000000000000000000000005a2741902dab47e8d38992180a9670faf56d1849dbeaa75b2b4ded93ee5494184c8658232e9131a8b08ac9b5460bd400000000000000000000000000000000189077d5130b3a4d7d4c3074633fb12739f95b8b6ccb082dfa61d845a389e6ca7aff835fa0f194dc349e1584b3141507000000000000000000000000000000000f226324f242cbc5f616c4a897f82bc5503ab1963ca38f30070c7c9916ef6bef5caa7e2e26b3f9fe68a1d59f19a9831d000000000000000000000000000000000a999bdfa10e4838ca69694272b0187f7d0198d6db0fd85eae688424fb09baa165c623dc6da567fe034d7cf9f9a0087e733a3a84eddaf3af8c5009646a899f6ae8cf233f535e360e29e2952088ebd7b6000000000000000000000000000000000fe85d976befdae8fd0ad33a4404415304afad1c5698b91bdc15abb4f268807c906410a6ca827320f5271c8fd4c8d6fe000000000000000000000000000000000cbff7963daa20c1d20717bcd47b872b3ecd5f38de1a467ef50936f13d6aebd978116a736cb6c5d676c6a9525bb0b7fc000000000000000000000000000000000c3d20ba17a21bbfe873d88e9221571f1bae7f02f35b8e677c9c42907673d765150c737f0011fdbaf4faa883b0dbf0280000000000000000000000000000000013482c68a5e1084faf12e8aec92cd9f0692b173556ac8ac3c7519beb4bd75f847f41ab9432421c631b14c885c001dce25112b5912aa3cba657d8de3dc8138fec92b391d5f988b82e19f16fe52fafea71000000000000000000000000000000000f9091a0df2c989e12a844c447287b704803d1532a3ecbcc890e6f6a885a54b969c53323c105b3d14d12f2cf766b8ac8000000000000000000000000000000000e54f3a9def8b3a9f972726e606195849584b7197ab70a28cf5644cde15e70bb6e3044042b649825adaf5e37c2d5e614000000000000000000000000000000000cae412d8a3ee3c5af38d7a65bdf2440d9cc2d6348dce0791f4a7e71ac483d7487b6c789be0a401777de3f57ec65de820000000000000000000000000000000014df09fd2ff406707004f6afa366d06bcf8bf18f5fc4b444b07c98b3f358247c6056a6337f5b53c35db45904797fb4455683e0b33b5463bc71283f0625269b2b33ead69c1eb7b23a996c31c514d06937000000000000000000000000000000000a8aa422e1d58fccc84615f9ca4a4743cf5efe3a1066c9819f05042100bb8784fcceffc8b3a739f549b42f34d62629e7000000000000000000000000000000000c737cf78b10e82fc0cc9823891f1a5f1e9229d61e8f369c589512d01e5180246db46e4f09e811464c6e1ad930226d390000000000000000000000000000000016017354434899e2285da6ff4b27fbaab633d962197d2ff4fa5f688c4a85e1817434cbef13a6b018df4e359d7b9ab7cf0000000000000000000000000000000001433c364428ac69ce4f5678aadfed4e6d076241519310686de01572da5cf78af4a98b3502519beb0dcf04b748d08cac5bcc597c5ed7f79173942a0250e618c93cd0917b37b5f354d63a2c02a576080c0000000000000000000000000000000001f8b803f3f76aee9825a9a960cd2f9e8aa931568b32be6169036683b4e6d8c4abba6bb73b137c7c6d6b6ea92f2023ab000000000000000000000000000000000fe9edeab60bb55990ad2c85c8fc9341e81de54324652c08c615a745813f08153bab3849dbeffcf4073f087f7c0cf0f6000000000000000000000000000000001955289b1210fa31542bd89f95188d60751b32e8d54f1d4d280975850e57db7b151b872bd431c528c22fb89c9b8784af00000000000000000000000000000000079c8a56c72adb9fc9baa503db394635abb10264dd43c60f2c82d041d43240321ac1028688d92c4696395d8840d52f15f2613a8e50fbc6683ecdd7c7fd38b4caa8e5dc9778909fc8680a58b16ebf40da0000000000000000000000000000000000b0fd79e62c6129fa115d821b8f2a58a4564f5ccbb14088f59d5e6a17a64e803f32bf8e5a415aac4d6491612d95ee8f00000000000000000000000000000000008d837b6c70468e1e10f6b979b7c0694d65942aac48b5baa829c191579186314ea35fe440e6d843fded02b95f9816890000000000000000000000000000000015a05bbc4607b113b37dc0b4b8add23736e0f1bb1e48aabc15500fa6941b17153918d256b6442687a432dd9ca9a198c70000000000000000000000000000000003546953d97306266bdd359d4daa939e05c0466691de59d2dbe3584e2ebfd9a9e1516cdc9cb643c5d31731835dfb07c657a747bc919991ef9b7b10388bf3f301fd910f807ccd31e322be46580a71b7c60000000000000000000000000000000009a4366299290c3c6651b22865fb22cc972a05ca5981f5682574851e41096d531e375e981c4e1b1cbfebbc70a41bb6ad00000000000000000000000000000000001e6fe2097fca2afb8385a3100dbd5ee1b7ae972e06ef9f5e34eb9fbdc65455e1c822299e06a9dd5a3f71a0c1efd44a0000000000000000000000000000000005ad2ffa8861848c46722a7924ece68580fe44e03157c982b7133361e974b59dab7b75358fe498fcde9f68b5b99f23e0000000000000000000000000000000000adac33e0b7e6740c980a4f297917fc4fc13f53a71909f2eecd0067656c6f82c3b371cc638509151bf937f8257aa415d86ba09829f4bbb383e2e131d554c42edf1065022975655c07df2b3445a3e6cbb000000000000000000000000000000001462d509503d2c33829c3fb5380199b79b970c2ae7f944e54a6d0f0deab3571976916cfc311ea6ce6128c467665fbbd10000000000000000000000000000000017f6fe356cb0dd5bddd489c26669f0f365260bb48a5f862e9bfb778a7ff5392938b905759718d050f7d93f107236cc75000000000000000000000000000000000d9b3ca93c5133cabf3d3daa565bc6b51e63b7e37f68f3bcc43b9b3ee7db15f8bb33052eb7e332ae3e9ffafb17cb77d60000000000000000000000000000000017d6b898d9799385990c9dcc3f72ed93333486b98349ef106a230a71d768b75cf56cd946f5952075bc41f26dca9c83c003fd5e91f590fbe171aa3f006617b20ad645626c970c2351e048b2ac3773213600000000000000000000000000000000158e5e008796c10f6050826c29523864d06e68977cdc95d281a8606924aeed0b475ab152bec5bfca8e0ec53691b307f50000000000000000000000000000000006fe8e75328c067546eaba93f4be2b15513bae4a3458112c3ffa457d15c23636816fb469f071889380f31870d713e949000000000000000000000000000000000b9b21cd58f8742ed094e9b770182f6f3f855204d869e53c02d0c242a133e957c53c9fabc827d6379b39541170be313000000000000000000000000000000000014eaae1f0789f0b1e8ad3b452b4ed3ff87bed49ffedd13c8c35c35668c33537b63050c06a5bf3d88d516cddac13b4c935ee16785c004dd2a01920c52d3244e2160fec2d17a519974d4331527cc627910000000000000000000000000000000019f976b3584ffc188424614fd287eb79f060c55e9b3dd2f3eb99760a7cb5b70e2b62a0895b05e7cce2e390853fed61b3000000000000000000000000000000001117181241fead3865eba4804ec2c14f571aef5351d5bce29399113d007cd4e9c262af1c77daf9183346153e562864b2000000000000000000000000000000000f823f71035a4870be2ef20bc94e97d74d18c0a1be9895fb27c54df1f663df6f9e6e45ea5fe4502143a84c05e517b02b00000000000000000000000000000000141250f392fabd4566e0cd3a472a4b2971a432a3a5e1d9c924866c7a9516322bfa691e9dccdd5ef14c561bca6dd70ba204a6d6e29336015d99e107cd312e300bd54f815c785f6008c47c99fa008452700000000000000000000000000000000014d6827b9bc782863491bc7c544263f58dc04c18e08a87ca2fbb5799c4aa70bc039416a85dbba67dd83bcc27b70748670000000000000000000000000000000016c2816e93ea9d4bd6e42a9720cb89d637d88e00074da3300c6409be98a03403e9ac15f83167cdeb13800ad174ac47f10000000000000000000000000000000002aebc0116a62f93a6e86c7fce86745618e08f4aa9cebca7b520e9176bcdf1521cb2bf7eca7f7af9487fdc82dce76bb50000000000000000000000000000000010684e3254207c4ccdd49e4775198df981afcf7d9f89b894e204c5dd84ef42b89fe3e2f6b9278470e6cde4d3f4abb3b003f9cd3873dc6243748e16e4806f8eaa339edcfdbf4408a8e41a3df80c9816210000000000000000000000000000000010ab1d5494509060c9784b4744a0572a9466d6c374524a6d338ea12ac5ad89519217c462c3487e398325439311bea86400000000000000000000000000000000197568cb53ce03f00aeb04278f355da862be757366dad14ca6d30b3a537df9855a1196010773768a91cb4bb664a34f0f0000000000000000000000000000000001fee249315794d30eaf929f44b99e07927194c6015ff34a4530698d7d68239240c9cc48530d52ea06218a826a655cce000000000000000000000000000000000645b5d701bf3422228576467120935f014c754dd68bb3555b50aff5ca04001a26298982c97a64469aeac3432784efca34135a2e7853c74725bdaee1ceadead7b4c7d729650df6544bd525c05c94234200000000000000000000000000000000113e17730f8dd7258157085c30cd9d1950a26c848b55e3a8a55865eb567edecfb09f32ba27fb3e2096ea00c30f31ced8000000000000000000000000000000000076db9ccf8df9530b64cd43ef7b496d1f432885062406028901bbfc5882fd12533f84eb12aa2ce8b7adf9dd980db0870000000000000000000000000000000015e487de49f1e494ce9907cf0ed31fb0a159c5290538ad969b2c8a504986dc9cccf7c74a61f622154e928aa2dd689c0800000000000000000000000000000000195e887083a98fe3f50a9ff4b342e004398cdfee55c4b02a4db0f65a77d3c0b142a45201674726c96d5f79f8604d61860033fdcb731830951dc3c4b33f06310eca51762cb7279039b3d7d9ace93c5f2a000000000000000000000000000000000d80c7e50973205585b20a068c64957cf4572eea40e32ffa8b759c38c6ad6f4468421f2fd6a6f5da1b0d008f625b3e6600000000000000000000000000000000009242dc1de055aea82b3b917f88b6232c550c3aff41241a7e54caab4c234d29b5d8138968846f7c754d73ab3b4e7913000000000000000000000000000000001188c31a9d8359d737576f4ce7a7900314aca0eb3b51baeccfdc9245bffec49143a11b3331f9126b01de0c307aa4e44400000000000000000000000000000000104ef4835124fa6b30dd551653aca25db5a544af6782cd0b1e7d26178253e0e33cda77428fc1dbcfe6114a758cab5c814c8112ebfe12bf44e84796e8b0cd03a93d2164d6edf1f06a5c520330a177da87", "Expected": "000000000000000000000000000000000e79d18633c18ac818786bba87d09c9bb1571e179d8769f8fb82e2e2b7a6a8695c1f4f06deebcb84524e8facdcb49d0500000000000000000000000000000000149d0231fb030a1bec170decd307c10e72cf1cca55c8a1b67aa94ce61e4c7d2ddfd0b8e71598e1abb054355dbcac1528000000000000000000000000000000000090f5be784dbafb0a8aab1516c773720341de6176017e0fb43a275d60de54c1189144956d4876d989232b362b90851c0000000000000000000000000000000019dba28eaa6706361f285b3abebef68f764204c74ee93ea011db01c19591ddc6f98799fb3026c3c223effe4489a7c676", "Name": "matter_g2_multiexp_19", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018a6a982acce5693e632901f3136eded40071e8c7caa7887f302c32621c5bcf9478991ca519978b52f8f69415c0d070b0000000000000000000000000000000013420ab920c8ecad5b2f9aaf9b0074c2386b0b08c81923558770d4c4a6b206a865af8322e9755706cd5e595bf0ffe564000000000000000000000000000000000c0e5bf5465d564e3ce86d6b742ca687448e6952439b1ff44b86ee6461464e07f8039e8ae7a301c6caee7eb99e38fab10000000000000000000000000000000015eb8751b750af62f57971e88b436658758bd5712f98861fa07328d2b11e8725fb55a2a00252e0be06b0c73aac0f7b8cdbb32a4fd8b9dc58a382a7e436e23f49a134915372553eee8c605436221acc80000000000000000000000000000000001328927910ab502e573188271108706152f562b1d5f6ec074f8f9ec5eaecc6cd5e8284a060b65d26463d22c8290ea4ca0000000000000000000000000000000005a1fcc348122350981dd5090c865a2aeb851ba8b6e0443c32f48b157ba673ae5652a70390888b3458afe6fe975321700000000000000000000000000000000019edc749a9799c8d3df75d4024791943a8fa02ba0cac90b6819f0bc42687b044457bc7cc6073506e8fc19af37f224624000000000000000000000000000000000fff20fb2b554b63758963c1583b996ad450cfbd5ca9952e38f38a8994809096086ed86311f7d73a0a5898ac261ce09e57df9664d3e17d9d46a886efde4e37e38859893113558843bc019699eeed8ec00000000000000000000000000000000002a7005dd32bddf1031f27c2ab999604c048a37c39734db48a30baa86c61ef626cf82084651ae9ba8a265333060a408d000000000000000000000000000000000421bf913a25108b8f520b2becc6f8064029dc046d0d5effbef31f0af59eee71cfce83fec8dda7983d50c6d5cbc8329a0000000000000000000000000000000016c75708f1dbfbeae3b06e5e9a7fb676c27100b99deece14d979b32a9c3cde6e9e96c8560a00aafbe6e7decc84e7e2780000000000000000000000000000000000ce23c27b5128bcffa424fd1d181d21b06b77bd6549ca5eba9a28cf18bb9a979270f6a5807c640dde57a0cd4f3af8cbe2b433b7a95c26e598002cc00b7904816d59baaba79bae7c6a7c26dcc48a487e000000000000000000000000000000000690c7ab321c0c93b5ae4ed77843ff4030e4ffb504c685d28573e98836e8e56dc19d662ae9f496a346bf2a8be5396741000000000000000000000000000000000fbbe3861a8d202b10801cdd606b50db0ad6ec7b923b90ae81ff5443676c3399e249e9efeb47b72d2b0a54cb0594686500000000000000000000000000000000148a27016968f0258e5eafe0a8182c22091873a5a58b27aa2160674584e06d5b2f46fc57a00617af18d0688df75294cb000000000000000000000000000000000148449d00b3d1b5b43b08a0c6e909a2d9c66920b60224a2c6a2521f0bad35b99e3bff8be0effb2f7f34438662d7a4882897583b53567bcfdbc63ae3e864a9cda24bb732694a6b27415c5212c7f45a9400000000000000000000000000000000026b55509b81befaf6baa682a3e92a0ab423fdaa84d2897613fd31acd9e1590f81581ba0ba87d68af76b01c36093e183000000000000000000000000000000000c675e190570bc5173b8f508d5bd2768c83e7f56a08cddbc636792dd75386939942827617c4aff8628a74b74195adea20000000000000000000000000000000014f59f38ae9e77f3a76478ecd47f32200567bad11f191d303cf15d7801ae7b5a3286095fc8726acc9818914b27a776bb000000000000000000000000000000000da89fe9493b2d9d46596d80162f5831d4fd8cbb83b46e84e95d5d684eb927022ee62ebc3519442007fdc543701f97bd2f7ff17e54d759eb9c51e16cf6f12d645bf2d091427416b4edbe1dd21947b4d900000000000000000000000000000000170e52a240a7ccf2d57ae92ea8dabe62ca4b458a5da42319ae89cad22ebf13541b0daccafa1b1d3cfcffe81b500c4cf400000000000000000000000000000000174879425f3bfd40fb74a88e3dc578e45b0e0eaad94da009e4076dc42d234d78248ec3a035666dd6de235f87e1a47bcb0000000000000000000000000000000005aee47acc3260d11fe0ca16050a29f92763b3cf8ac78da52b3b2b3e26d8ce7b6ccc187fcd81695aa456e9b94a84269b0000000000000000000000000000000005eb297abf35b51d57474b4989dd8f793005bf8e82e49859c41b786ae39217b2321299829198bda4aaa261a2723d43d6ce0a097efee666c22d1dd0ae8c8e11283aae781e1deadceb3ebbcbc5e5280a61000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e277b2baa349884b54b542e3993210ef002f70c6467c7d512801f0003da789c00580000000000000000000000000000000002d947e728a3b376de520bf78e56452930de42544241180906719a24d72df65f8250402ccaf14d69935b1ecbb0b4d34c000000000000000000000000000000000d5614ec77a9f31915dddb3e4bb533db001702891a45f0bbac49e73d9c19a235a00442b52d452d77018f883706a616f1000000000000000000000000000000000dfc6a73a8e36b7b2d0614b1c6f7bf1ae284ed740c768f08416c0c09a601fadf3e4d7b17a93601b1803d19a04ccd570b0000000000000000000000000000000010d6a8e4eca2e818d6dff13faf0fae44a7fb90be436a9ef3aab05515a35cebfbd53e9af866cde1745f0e2c3b045486dd2b94d087c3ea101649ed57ff308dd3ae0d25a1ad8884763cea1b0b7c56a3834e000000000000000000000000000000000d6c5a6fe9b4d4580f8e1d89f0510bf5dd04e113d6ae5db04af2553bc0eb3a32fb881300f638fb33f7c4bfaa10b063660000000000000000000000000000000013e001b08191707ad98e21b3e0830286c6f3bf587b971dd4ce39e55f06db427676626a5c31c4a67a996a5725ec8f402c0000000000000000000000000000000012f86ed85113ed1abe9dd3826423911e63df0dfb51ad3d1e0e0318ae95991a6a11150176cec77f9c83268a322cb7e934000000000000000000000000000000000dda719cd2cf1aa769f94c21af20ab076b8f024e0a4903e38ddaca21b6bcd6f00baf7e1ed23259f135eb8bcf9c3f97c44f8c35b920a35b71dcf8d15a8a826e5a7c2a2c4f1ac2c2e3a6d100363e7f541800000000000000000000000000000000195ccfb9038bf9e637b88c83c552ffbd562357792513b15f703bffbd373ebaed715a6772fa7e6e5678c2e6422811dae1000000000000000000000000000000000c5a110f31d71b12cc42974003ba39d99dfd91769c2e93393449083a9b84d31473e3a7dff7ca40164e6e7215b03f44ef0000000000000000000000000000000006233b2dcfed96559b565928a494f2a50c2c375b3d7c60ee6b286c538f4fd5ca6f8b2a61654fd04d679bb3e05b9bcb03000000000000000000000000000000000d42233b7b5ad809c735c89c455ba1e8fbd623e1602bc729c01d362368666e4f90e7b076e32468041f3f5665c6fddb0d0ae6101fac82c10267770e74a0ee16b5be6eae2d455d742303a3c624d52aa726000000000000000000000000000000000f6d53de4f8b20de19b2fcbe8a6b8b8ec4bb801bce7363f89b133532ca7ce4925312e23c618a0182d158037c0d0bf07e0000000000000000000000000000000006ce094e24eb14b9bb1b4a1838d8b6da5f53b5c5799ab8dc8934b488cbabf698b99abeb016259a4e1b0f626d27f2c950000000000000000000000000000000000874aec7c8ac360e3980a6e2cbf3f7468f1df7a8d9158f8bdbb0f387d19f3b05326a081129576251ec41a926f670e58f000000000000000000000000000000001711c9b2ed7e2f789b29073f180e46d0c373d6e75c587ece67b8aaca1e9d9b43a96d04dfdcd42f943eca48e240b72ba8002fb31d0372e7730499b26d617b53ea04821c6eae922326d755a0df31b559ae000000000000000000000000000000000e8ddf88269aebf190bf9bd7a8276de92ff6039e479e42a490fe4ef00f646b049eb8ec4b8e073caa000bfcd86ee8724a000000000000000000000000000000000a9623655c0121ea0575de714e53c9e304fa3309f00828ba0e786112781a38bd458cd67864ab17929448171b5937c1d900000000000000000000000000000000198fccc4a333322599697e904e9096240b9c54f89ee6db97475beead62ebf730da1a179409133698ef13abe1310689270000000000000000000000000000000017b059ac08a3fcebde5888bec4d7cc2c70b147b3b1483fd001330637ff1c036faebf292801204bf2ba49350795708dedaa846e68337f4e9c99dde506a3af792732342e3b836376d4816557fc1fc9b916000000000000000000000000000000000a36274f33b4dc09e03a5ad648af0913e5ee95af83df8b4f2a158456aedf0a0528f9b4832b11162dd67e4d22b26e9f940000000000000000000000000000000008ce96d8bc0aaf2dea732dea188870d398b1f3c266b9bf019e1046cca05002416c910e02e998a1604a17c333c65c99a0000000000000000000000000000000000c1a0e4a80bb0331a94ed14570053f941a0438794e6f19d976cc62b3806a565697720ea03c2531004f13453991bd99bf00000000000000000000000000000000184bdae93abbe4d931a6a51ec85bc330d6181da2d34f2cc530e56b6803515ba87f5719fd6fce6a1a8bf1ee5a968bbfbedf9035283f1afc294ee68b2668870aa45e483d208483d9e967b11990cb55d8600000000000000000000000000000000016c3782daa55312a7cfa02c3be73ed75f4b726df5592351fffae19121b5cba73f427d35d5a2df7c63e2a5c68bf57f3800000000000000000000000000000000018b608343616eff759d512c97257f2103cb0909afb4c24a1cc9d8204274b7c9ed51bc762a6280e223a6116a9b23d1f1e000000000000000000000000000000000c687c11a879ec285180cbae3d2e4219df4614e238d4cbdff148ce5a8d21647c489ade3bf6f738052f149fdbc76c8bf6000000000000000000000000000000000936b34fea3a2633b9aa32244329891e332745876d05f95e4efdef859b23ceab4869db562555e5c8edce87a6fd075ae54005df80aa522e889e7720a9f2e44e6e7e19c3160ea282ec87a4b446d7b1c45f0000000000000000000000000000000000d4636a5e13bb59878319af6bb7c98e5d247c2c9cc970b9cec98027de2d4a8ad12d50906fe302c3d055c499a3742ee30000000000000000000000000000000002b0214bb1ee887a7ff10d458fe35208573456f685ee2fb93bb470762c9e27595cb00f2eae7574c8467e417c63c2a960000000000000000000000000000000001710d130f91861230562cd7ab87984ef45916af8e1168fb17b9765183d9d3f9b2c81c649687842de495a757471e28067000000000000000000000000000000000dd15fe505b1364f134ee77e5e3c1a497a20849b6ec7e201813677a1569a9f5a9edbe3df4c36bdcf9ada139b20e048ec893c9daec43032946a9e892dce960e07d29b304000378145148b9a24afd151570000000000000000000000000000000009a48d7c55d24ba49f890791d0f6a8a5ae08a19177575dc0d734fa37b52c3adc45b31b5e485a5d4a5533470c3549f5f900000000000000000000000000000000090f680c6fc1f0588add04ee03bf821868b1ce588e3ebe384dae657ba7885ef74da0bdc98d9d9594a9b979d5b50b93df000000000000000000000000000000000314f6aae1e99dbe3ea9ef85db7e1693a30869f48e05cdb073bf8e14865a671e75abb875d1b41f13d4eb74fc802299c70000000000000000000000000000000013c698b76dd68d1b9ab41672c2b07cb9a63168497d1144b51509b602c5acd71ca6cd049616d949214d95ab7a906a8f8bf685e6bb7713f8fe202c05dfd18003eff261456026a5185ee9e68aa821fe7c5b", "Expected": "000000000000000000000000000000001747f6d3154e0717435fa023754f115ce2a2b3241b62525cb2833473d84a8ccf4c95e3ea030f2b8b0ccc61124095ac86000000000000000000000000000000001827ed7d84a61c21268857036e91c732b304f609f285cdc4736c951fd8954b10267a8505f25d8be666792358632058b400000000000000000000000000000000121ac61f59051e6e89a7c1e2fb4df4b3a5b7773f46495a99e55348454e1d9d42254e5e11b841a1654ff9c80b157389c70000000000000000000000000000000001bc60cd06879980bc6ef2ca109d31f12cac28ebe4d2a934076d720b12f430e1bc4d4260f40045cc7a862726521a69dc", "Name": "matter_g2_multiexp_20", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000012a6984f0f8967c5ae6b13569a62095b5fe61ec607daff1845961bdd827c00fd56ef864802673dd21d90560fef6cbea00000000000000000000000000000000085ececa080d0f4c996d46c80a1fbad2ac9cff8b3e324aabb67182d79f941927050f025b633fd5119f30bb29b8e4b6f2000000000000000000000000000000000987518a5edfd5ae2616fc60000e117a4f1dd1db68195c3fb68d8cc639e4200945b2864d41ad86fb3e11c504fc1f9766000000000000000000000000000000000310939c7e11b93e5773cfd36fa70020c85396e525840742f994110e20019769abcd339db6881291639c193b987b68ae94b3c88e51af5822177b85978526036a426c9ca1077d594618ebb8fac4cdfc89000000000000000000000000000000000ec6922dfc74009c3750ce2540558c7c1e05cb45a5d651b96427c615d8fc563219215a0ee431c0a4827e40b26c4f8d3900000000000000000000000000000000040a4189d002a0e1ec600e71303575e82414e6400f06b9abf57151a28835d454f56421a6dc4049902bfb94dc0e9967ee000000000000000000000000000000000dfefc7c163c34cc004e9d97d812b2717d4736d0d1c722b6bf1a29676a32c8b46878d05a2d137cb7fff5fed8c0f02474000000000000000000000000000000000e3f0c9cbc778693c8ba88af8306d45477493ed6be1bdd9c81c65341239eb510fc948142cc30b73f570819b38f13e20f6e456b39f4efe6581657f5c701c696fde8acb59e856943f15cdd639c1fa68ed70000000000000000000000000000000013705ca4ecca16559713df65b376c7c5825b4f63d001ebbfce9cd1b592af5f2ddb38ac7c5ce3c5f7af4f39f909887e8b00000000000000000000000000000000179efff38ea1044e91ccad467cd2b49438079ccb4d0fc692e79e0bc374abe064fb9979c4a1f4b92c15cd1b042b501d5f000000000000000000000000000000000b6fda2dbf6339af225515681184843f1a9bcd72f7b1389f186f8d0e048ac16e20967c28e087cf09d7bcac597a85398d000000000000000000000000000000001946fca8c816e1e11187aabc40dd2436533d537ce4639eb2d08630ed2ce402c1806b6c2b3e04a960408fd4d2049849bae5d306f46a31c14de7b2940104d0a4424ebaff805a81f1c4a910566057c81604000000000000000000000000000000001802064095d029d3897725eeb93ed6e3b090390769026120aab6977d0de264a262aa312c5777ba322c9eac29e5396fc6000000000000000000000000000000001410f17820941e6a67b1b4993496cdcf0d4fa2d4fda3d43ee985f2606b1408aa9c9ce412c80c90a0c876cb5ecb76878c000000000000000000000000000000001514e9b2c65ca86713447f2d5bb8395fe8552e059829afc68bc43ba9267ef41ec6d69d06e7407a731bcca77ed5d9716f00000000000000000000000000000000025b5bb18cad46179fab15b2ccef17858f9259a90ea4548852b8c6fca69f0ecdf0b175669bacff1625a7143e762514194ff6d13bb0967945ff3b6fbbc104296805e4fedc3c25bb55b75cc997834de6b700000000000000000000000000000000146eaf5da57b6ac788f8caeb4b2ebf7c8999e03dd839977046ca834fffa7e57cd949e3fd44999a007b5dcf3c8621ba2f000000000000000000000000000000000d859632d3424ffe4227ae14856e05c4e750545cf276c97aa9ec03ebde334144eea670dc68e92b61fc775e477a2154040000000000000000000000000000000010b44279c0c80886e52fde5e71726422da2f9457ff86b21426d80356fad95d5ff3a7491002364d9de5ca99c2500f344d000000000000000000000000000000000851b769a691f0ebb53ee3693833881fed8dc6d9e5f1dfeaf4ab1aa7ad54e2fcac246b70d81110451ed78044a98d1547de4fb2dea292b76d8130e6aa8aff5edf0097de935b252d42a777d4d9b8615ef100000000000000000000000000000000131c9a76109929fc977a0a6eda0a7c71cfc744f5f3654e2221ce84c70787598e24c5d8049f92a7c4d78fdb869cbdd1ed00000000000000000000000000000000049872d2c7d472e090d2975daa64fd96f33e7f934e739633b1d7fcd5e771673ed8820752a0d5c8b0c6933318293a4f27000000000000000000000000000000000dd68fbb592a3957ef893180dd758f75978042add36c91b7bf87c4493b0baa875e1854fbc09e6856688cc241b76ab5a20000000000000000000000000000000006143699816cad8ab7583a72b6064fadb6caeb51c8625ddbf7b2911426cf438534da1bdd13e22cd545495c486c9733f7bac5c50a3a8a37111114c22839c88ce4072940c06f0d8b6d53fed155d0399ed70000000000000000000000000000000006c14301984607d569ad1bd774135e7c9e328be1fe54c3b543276bd06bc0bfff11f299a5eb43b5218c3605011d0ea6d80000000000000000000000000000000012f0a848022f95f4884380a5b8e3637a41e3c399a8d2765aada85dcf4b7c2b559122f792850430681a58ca153be2768a0000000000000000000000000000000016b4cb233e1bd59b7b362c64620eaaa5029c173a05e2278774ad6ed746c70a2f6e76c237182f5d9d790966ae69da5d44000000000000000000000000000000000c277d54a7a72c8528188f6cf29d934cc66471607e5e30d493cd11be6b203bdf734aaf37b686cd7101e8599b69446991c3f37387bad1af3a896a7e66a80dfce2df1709fa252b6fbe4334d02bdced432900000000000000000000000000000000169a3928266375dd5793b7504727f939ef0ed52d69e569b1b75a0e094698b37bc70472578beaeebfd0c3df4bce6177810000000000000000000000000000000008936d470dbb86db1567bb2fe7c09971c6d12b07208d9b1b403c20fbdc05ef8984dd576457fc6989470e40ebfe4ceed30000000000000000000000000000000009cdec9d80f2bf3ebfa9a3316e4250741d0d089245df2fd3c9bba4bac1c2dadfe212682166a0962f78c4bf25b618da900000000000000000000000000000000016521411286cabf3fa2c8f72ca62ca311738fbe63717fd12916a4c9e6af9b05d1f5d65cf60e84d9fc5f7b7645fe9bad570fbf5da3959a49fab7e97b3df3f2a38d16d714dd798a1f04ec2cbf84fce76910000000000000000000000000000000006a827f6149a320a74d9d8c1ae8861c1cb963b3eff899710eda642dae6ed4dbc247a22131758d9f843c62710ce083208000000000000000000000000000000000c83a9fd96bcfd4adcfc6d5a47e84108bd763366e91bf06a7431c6c3a107cbe5647da99ee6c1e57c376d366b21a923df000000000000000000000000000000001604d5c0364afb5503b0e1d52226988d7f7f043ce95e7c0a09d7f96e24a58f089156f0e6d19022138170c1b4b7dd33560000000000000000000000000000000019a11c86f78ce462f46e0462052cc3d342596b329fb62a282a59bbd64c345bd266922b1540e40aac147681754643c2e3e538bcefab5d8d0be5fc143e632e86fc065af3f2f621f293b914980abfd6a0c70000000000000000000000000000000015635de295c16841bf44c73639f047f735175e8906301746837838d124bf0d2a1ebaee142393ce9a0d58107c7cb036e90000000000000000000000000000000004fbbd4252fb901d0737d1bf4da62010c06d690a9584c7631ef5d36f1d8c37486a83f2a1e2db21f05c993fd117c662e8000000000000000000000000000000000f4cfcec1545a08e0e0298753ebcef5f61bfdb7c1b9af71cb4c2f783e4fa3948945d357e8302d99aca96df0cb0fc01a3000000000000000000000000000000000f543dad6d4b797f6fe0b00215a5f70f6340ac6bf7cb0bdfc5bc7698dbf0647e4098413dd19ca7af01685edaaa190c6e30b921d8cd2ca46aa6f3e0dc6ff08d77972fb0a248bd39e90a1e9f32be9e892a000000000000000000000000000000000ed552e94021d0912a0e7563462570cb572b189569eb847bd12ebf976d22343b9ad04d400ae98fa184b10ff36720f12700000000000000000000000000000000178727c3e6ff33be9894ef26347b104023ea0bcf79c1a33afc26ac0ee9879344964fada757118829214cfcdbbc0c5a30000000000000000000000000000000000b0a6a575afe5b0c1e287815612fdd3838ab39e8ee7795855837588614715f6687910c42217ad52c1b8721a9e1c908dd0000000000000000000000000000000018cdbf244c78cae1993400ae164b42c09dab4d8e3707a69e25ffa8d0b96b8270c022c0375f933f16f45c9274132a0a633a5ccd9436b15d4d04a8ee9894c116190062c4e7cfabb047b585f3aa1eeb460500000000000000000000000000000000070636611f903f55cc9499481bc3415a6de62d5e6bf8bfa82a8ce665f85bcf01690118441961ff46ff701e361db208500000000000000000000000000000000013d22dff8f6f86f659ad17ef91d90a70c180538f03e10de20c445d22e637015d51a311a3daaed90712d04c9a3d992d12000000000000000000000000000000000db3535057db95fc262f8adfd7f08f3237fde5f0e2aab589d4ddcd9c23aadc437e13644dd3b3534dcb17936a7c610cf200000000000000000000000000000000044c177d4484c07fb04d1dd477b188a2c157973cf26075001d14d2b07ebb9dbf8e495dc23b32a2419621e1c129b08c5ac7a5bf2cfedd7048be7ac7d2ff19d4f8bf0a94295ebdc5e792393e0e4bc27d56000000000000000000000000000000000e10fd069f2f5fddaa0112e70ae89d1ecf034defb24e2923731a7c0068780177c186fde92a3c254a1cbdd255111a4b7c0000000000000000000000000000000018363e01e86e2e922ba435651ad892bf9288be14b54dda821c397ae6167f9478c8132e92b1c2cb0c4037a4e020f08291000000000000000000000000000000000301b5ad2d5c35ebdcc7e7cd1ebf0405cf204d6f5e30ae6f46d20534eb6d7013682c5ae1bba76d2811124ebded0d2a590000000000000000000000000000000015fb3a8afad778031d04e094cbde5f02dcc89ad7b7d452c6c8f41be336a4c8b26e75cfc685b8776cbe5a487f09c304083563651d5f5729a0ffca6b383d884823aa3b0215fa057bffd8142199a16e4ffe000000000000000000000000000000000a7880b00f6a3e959ff1bd207fa503eff6e7279e701e37b40735e2bc8bf49e355e92edcaf23aa3654bb26fbfb07b5fb100000000000000000000000000000000113d9b792f4e3dcd958664a8778dc4b177c430d8db9da7805595e40293ef2c0a40f7a843bfa70ec134ed89a453f9da50000000000000000000000000000000000d7f92148dca4a9c96c47a0eb284f1834cf3d141be7c0d9a7a060af6e28e45620d8255e465e9a0d8f78b2ffe17d6b04e0000000000000000000000000000000004e7917a8f3070c656d324c9a816236842fbd6147d326652667e7bca0666d214233ed136dd9464c4ac619d46c28e2393833323c3a668541ceba18375531c3781dd98525b49dafce4c4b3188c90f3f4b500000000000000000000000000000000160cb05390b54151f6b154b396bb400a91fa83d77fabdf31fba349d1bf3b5dfb6476ad4d714af2a2963e41b077bffcb90000000000000000000000000000000012885f7ec8e780cbaa90a465b5706cf07d45bda7755ae3477c79adbd7956b926e0ef5303fc13f0b97349ff8b754dab500000000000000000000000000000000009ad7509e9e7f5018ae3d1280e881ec12129cbf825cb6606459211ed7b358a97cbe430e94dd9f5e4f6b74fb7287f862e0000000000000000000000000000000014d5d2ac2dbc3d5a061f4e52dbfa68e1eb1d3c818ba26686a3171e310c63cfeb188030b83407070019dc5c42dd079413d422e21fbffa7d55270eca9c96bbefa29dd915aca266071673e970daa0ca9c050000000000000000000000000000000008ee93fc610712411634079be0bd96c3969b48955fe5478b7a31c3ba7639c18291034167eb62e6b15c16b0dd5145edf500000000000000000000000000000000158cb1731b71905d7b958c5407f090a2c8a9319017719da143a3f4f3fb3982abb83b8dfe14facb014321b4f5edb5e41d000000000000000000000000000000000a9f98f775f06055ac1f137cbc1f95f4afa0d1c4935f536ba2e0569d874d9d76b7b86f71afcea07e2e785c7a6ee1c84400000000000000000000000000000000072f8988dd1ab0fa8037d3620068b34848c65e20dfc90612d123b6f9dbcf9d9d699d5ea73739d31ad54c22116365ab983ba7ea9ffda87131452b24a9efcdc91d1262d0d7550e5a6b787eace3577159b0", "Expected": "00000000000000000000000000000000161203d8db1381722644f87b04f47e4be2ea2bb105ea0e67678bc8d29f8a8a3247f8c05e057af8f98032faa93d896aaa000000000000000000000000000000000d3af4842627a095a2dca99b52d802b2ef8c8f3d09873ffe39d224333fceae84bf74780956904df6c1dcf5ba31be218d0000000000000000000000000000000001c79fae014e55e5d0239645d618593bfd5aef665b3e636dac5d191a8b88949d207cf0ae9822ce8e1997de302b386b8800000000000000000000000000000000136314cc68b372b06e7771d82b7ce7bfd0e9fd306787e07629f831c7aee853bed80172121949a940bc59c4a0b76f0819", "Name": "matter_g2_multiexp_21", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000099434adf799099f2e6e2fda4c905e1543893462133ba216aace25836db37b3dd5bd80af1a8c31c7fee56b5ecf9a0acb0000000000000000000000000000000008a6890e5bcacc13e116e3fe2d772ff49839803e4f81d6b088ecb7835b1ed44f2bfa04de1d46dd352346cdee71774e37000000000000000000000000000000000e94fe40225e863b7bdfab4cdc0c1c8d1399554ebbfa3f2c95ddeda74b3dff03d5cc78e295accdc9f02f3f89b4953de3000000000000000000000000000000000b23f2912fdc7a5fd1de69c1f479228f8ffc9f97c40845808cf17a6fd8131ea60285640d32bcd64c9be71d419aae82fb16aa2cadacb129598aa459bb2e6b7fb26d1bcb7a49617b6ef8e57018c3db1f510000000000000000000000000000000004c6f5aaac90132b2d0c6a4e70354ed2e724df7c3e6298eb9ae4ea92e3c7981944c89140c52e893ef2edb2773ab36bcc00000000000000000000000000000000021e813378be9ec30395b917ded5a0424fc7eab0abfdcd2328f725bbd6a1dace0a5aadebe40e10470df0c09b3f4b68440000000000000000000000000000000014e3fee16a833f8c543860ca438d763f764f488463601741a2331fa90efce9f6d54ee0fb7978460a1ab838039d398918000000000000000000000000000000000dec8bb882fe6028a4155e6e2bf48ffd314b5519dc4560f8f7410209214c4a8e37b2b36facc53f4db11ee63ff11f9f228c02014d5392d30863a12102d1c9315839b5611dccfdb489207f9186625138500000000000000000000000000000000002d107029bea087a2d53b6b371aae06c695fa85631450f4ad92c8948b09ed568b28948f80f1455cd22e2ad44697290b00000000000000000000000000000000002fab10cdd8bf17a633c8b3ee8ed2ce783f64bf978c384fb7dbd7e4f0da50b65eb9530365d982bcc17ab91a29eabc065000000000000000000000000000000001369237fb3241ac291a868e6f4610a5103d93aa915e954f18bcf348ece1560a12451723b96ad5fe162a6107dabe1c986000000000000000000000000000000000cb70b7064a2f94efc86060431ba4dea38bc64822efa73c76f3a4500ad23c452c8f2e72713b066a45bfa49559d14a719d960ff678e1b46ada4f866adf354ba8c1514df10ebe7d88d2c8de117ef5ea2490000000000000000000000000000000005ebb9c8202cba234851cf5e060a4114c6fee0632f37e0c52aeb852637f362ce64403347d336c32617cc59f23cc7c93e000000000000000000000000000000001126827b6a0a8adb698854c0089276861e3cccfee420512f0966df78ea0d9c55e85a0536f14ad40e649b8fe4384c836c000000000000000000000000000000000998549680649b294d506c529ade746aeb087f75d62a246b7abfb69397ed67f0f2ccb4811219b35aa894b2f87e3fcddb000000000000000000000000000000001027b604f877ade32df8de6162251acf2751a9bd770c21f22dc819a4f5515bb276a246ad667fe7881965f0b083d1f76304753af76295f72295645243ffc87ffc2110c9d8dfd20b464760ad965d7a97940000000000000000000000000000000005d1484bad44069b16d1ef4e9ca1db70ec6cd82eca645c2fbd4029ab4ca33d79780ebc144d8774d82518c1fefaab38530000000000000000000000000000000019abc7063361ed64a5750b70bd59283e6a61d55d49d8c2ea2f1be8ea425f040d3865c399a66c253bf38355360f06cdd40000000000000000000000000000000010a97b13b3b579ab5f7fd9801d9e4fc40f3b2b2acb9f21bfcdc6b6a3168720fd0abc2f77ccad01be6a6e268fddf3759c0000000000000000000000000000000004126b5454050d761047e5da23c0b2f9370996589c04f255a1ce8ef37a3a7c8078788a0125e4aa86aafce8df33f322d3d1b8760cc40d093912fb073c5012f910ae90f0a979cfe6d81c603adbb98289030000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9aab79d640b042664b23667d6c60ef9a5d59de72aee57a78d75752b350ce56d8da0000000000000000000000000000000016ca071d741363e7c3297355e49cfbdcf03d419813ed7b329cb2b2a26fc6a46cc52149ca3e9ca3ccd7284cfed97b985d0000000000000000000000000000000018da360fdee88e806ea1a61c01e86687f8e5359730c36c876ad2acb0297bbc1ae13d790d1edaafdaed65db9dac02a74d0000000000000000000000000000000005a46e4572f667b46aee36b8d377c249de25e797b31b822474aa647ee68cc7d40b083fd0a1d938e2b8d85508004c73f40000000000000000000000000000000011701bf88d4287c98996ea561c1ab2f29a5da9138338c7c7539a5fc8355efab6f58e240df4b0e0cb7f01df74bc8010501d1a2965e995bd4380d4ec52fe8e65e7fd99b1ca9f4f0c656adf7051c4b9a99a000000000000000000000000000000000576e79e507d250eb4040197064b8898b0142b3a2551875935f91f22705bfec6da156c7858fbf77028d4a00957553bea0000000000000000000000000000000015d39a325181d6d1a809b1236f4a1ba66a9bfa6c448470425aa5c8ef9fd00b5481c51e8752088dad62e928b3180408df000000000000000000000000000000000aafabc2f68a4933c7d734660e422ba154e37dd90114272e948f79db4ca51d5ca75d504cf74f2dd0479871d69a08386f000000000000000000000000000000000b017c731f63bbaa8fd0b0d9c17140060429f515d2e85a938d10f6529deeae4818c29b9a628802d0ffbbff720339b7bf2cfbf2abd851d2c1f55c56d4f8b11b196c020c2584cb03764580d410d66784d400000000000000000000000000000000028c4dacba5f33ba66368c19491f4baa6aea4f309afafcc8f464f2886b1d05b6397142d02f0295fd50825819621673a1000000000000000000000000000000000849e1b630e8db8ef039f280f8d401957f807ca90479745b68c3db1b5ce3a02fe2c099ddf9c387d7ed76ba75d6a9be9700000000000000000000000000000000013b43fabc3d4df82058db215a69776ed5dfd4c773d7a013dba3b4ef5cf65e25f79d7f76a06ca99132d6fd1fdadb59d400000000000000000000000000000000072cde8eb3d3e1a7f7e4a9eedb8e56f5e103db6de6ccf833f818f02a0706b2043d4ba0d5473bbb6472e8aeb28364e1d8214edaf16742762baa58a3d22d5bb2305cb03a1326adc68adcd268428f82a1e00000000000000000000000000000000007a33b95f42cb1d1ddeff3a199ccfd9a5d47c9fcb89dc09b5b3f59dde2b47d24ff29931920b76ecf6deacd70e83576970000000000000000000000000000000014c0a63e0152f06cfc32e6034b7829f9d9d09aca0a6ef821dc61ae8d99b77d76c1b2fafb2a14938a82ec72c4041ebd9f000000000000000000000000000000001433135cd913b05b3f58b2e9c1a3bbb951d2cf6c92fddb21bd5e1d9c44e464d5fe98f0791044d56e50b81a83ef6cb271000000000000000000000000000000000be12ce3bc47bf69a13762343b5e39c2a2f285896e5d1b73c55203cae2f32cccbb4f7b8230b2026a0c8b2f63db5e5bedc1f38916d6bdd5d379967dcd058ebce5887ef2bccd5fb7c2bcd758e374a195e2000000000000000000000000000000001494984d478784b2ab3ba27464109f99172033fcd5780a48fbd5a2144354157f6fca2d70b15b0081dfd306ab4239cecc00000000000000000000000000000000078aebc22025af53c6542abe56cf72ce5eb11d3f19212a0f7442d0a0df907c8aabe0ec01d1245ca237a691e685011bb8000000000000000000000000000000000415a1804a46f4595014ef29b12d99b89600aab1d98352437ab8342abf479bb2215bc687532e75f140918b3d030ad4520000000000000000000000000000000015e7b0dae7e3e80eee3c7a9ed4c739288ac2192f7d80b2c8cf9934cea5719081803b207623c771051d7694e705744dbf1cb8c8303157f23987f8a2d206f3add697b9d0a303393008429e93cd35711f74000000000000000000000000000000001470f82372e197a21aaf46cb2bd3c0b77c3428bf2ba073311e75eb65471a8164753ff1d989560f1ce477952bb6555200000000000000000000000000000000001645b5e5b4bcb5f6d34ac841e3a80f09a86a5edcb7f2a7e7bf549b022c0073e01be82e4c9e5c8e8de76ba367595639af000000000000000000000000000000000b43f6572553154e2530fb448d5bf20c3a182cc190149d3b1d75b60e45baa048f44884500fd02c434f9f7eac01dbe4170000000000000000000000000000000014adef5a52d76a267f87d9a8b5e9f570e7775ca4f6a55a5afbf80baea311b1866fa0689271799a654eddcfe36a6bb64c61ca9ab9c3df673b7ff8be098cdadd8354c17becdf82e7e99ce264174653007a000000000000000000000000000000000345a2ffa21eb06fa1d76fd81b1239147688093c6a44a40cae37f2af26add812884bed3e8b4643675b1a45320c64f7a8000000000000000000000000000000000c58eeb5ffdf886d6319ead9e6e190300ceb91d58abfb79c0a322de3987eee73ab82092eea8e1249e83ab67e33b303e1000000000000000000000000000000000763a3fba513b6731fb501aab39a4697f3e4de89125c6884f9782bfb73e6e062f17d34555a04a8e2959ee4e1a2ee284100000000000000000000000000000000024180dde2d23cd88cd29c8142d32435d0db57b8ce8e309701fdb963533c1cdc2595e3bfc01d8c0d08d594e096afb34a681a0861df30946911d789a5da1f5b89c38fa1a8c0407b608122a18be05955da00000000000000000000000000000000022d2e7502c4d9587df7ecdbafcbb813b1812d76655cb7f9f57418d5ac83d4f60b84a0ab5b53a5eee3c3954aa9fc70cb00000000000000000000000000000000083212aa1316561a079cb8d027bc8f89161fc828d050c8837a24fca6f7f94b6dbf10d6032fed895a427f07827deaf3cb00000000000000000000000000000000021552b99dc02a051ea3af1b1bbd0a7ef64088c3aef4a58b18a29ca05e1f442f8ea2c8fdb3642ee94c5df501ff6898f40000000000000000000000000000000001015a7987d329cd1eb5f991c270643a05b8e1bc35467130e9f53c5d96fc3c8336a00c060dfa2d3165358b51b6a521e56f0798b448ea0d10c84e2a8896f153b1ac3b84c5fed6a4ba6c932260bf01d34e000000000000000000000000000000000c19c3b9d7c7f520968d8531966cccbe6f0c3fa0938480ca3591b7489febdabd56a70ae55cc309e04d7acb3de6f41a3d0000000000000000000000000000000002ddc64023f0de2730d3affb695927eaba50ecb91cdf1f369a511a8cc8dae8913ada2d8f27a65e75deb9b8b648e4e2e00000000000000000000000000000000000311ef260debf2310fc31fb8ecc802200e11400909eba24b14d9500ff47c1c36ec540eb970c9262dac947b0c2053d6200000000000000000000000000000000199c19645375dea7602b74301adcfd9af259e1c7c20f377fd10d56b719f7a6e0e57d780c976124e0675c2a54aae3e0f5a8b7de8f34053facf1338b54cfbe38dad73121a0429663f484277af9a230abe600000000000000000000000000000000123fce6b793de0ce2d31f2c7c4218fb20f9db68946a7d57914174ea773d6e6fe1fbb1de141c742e0a8154fa1d81a91f70000000000000000000000000000000019f75536e004a61c6d7f466bfa06ad0c9375a1028eb7746406e7c71e551dba249b5c6284f635fe26989aeea69075b3fa0000000000000000000000000000000013088eab16ec77c7ce7e84236337e395690169a4ed7e44e23d233d36d5d25e6afde794cca2bee88fe749851a71aabe24000000000000000000000000000000000e627130da43a6ede3bd6f2fcdf008c8f5c7b7b1fa56cd3b367d3096317948bda115d732346e73b731d1921a1da6aaa18823cdb73dd076ad95679a9d7b11145c12a81b825477f799300d1fd761417c2b", "Expected": "000000000000000000000000000000000e3b85a3d6628e097a3d962f3c9aa37e3c5be43faf2a12cd9830ab33c4a904eda23027735bba563d38ae5ae8b302864b000000000000000000000000000000000c92be62cb091056d981ab8872292017cc22ae4eeb0cee03a60cb5d57d37b264fbed2d752ae9dfd76c0bdde1f1dd10500000000000000000000000000000000019e172b23249a17924b890cda6a65287039d0c32b2c0833409816cb21ceb73ac95928234ccf566287400a2ed7d9de771000000000000000000000000000000001276e206235392fdf65e4ea6210d22eb7afd7783caa0777ff0af719cc1822579d5b82fb4c30f07dffe7d68c649b9e2fd", "Name": "matter_g2_multiexp_22", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000a3d974770eda8c742e5d380482d36fabe18901b0217485141c3841003aeac4459ee28b280550e4643d0f50862bf2e2000000000000000000000000000000000369c2bf3beae4e8761f6c06d9bf5261bbedb177e609c81c9bd81ed0a17573b6e10e7f0512e06109cacc3d483918ed9400000000000000000000000000000000030253d0a050986f49c77ee20ea8e3e07de3ba72c39ffda877bcfe569eeb29598588f5a7cedd9e2e34491a059ac4e707000000000000000000000000000000000ce201f07353bf82ec894ec66c7012d17f3c7968b28b45e88f091510e1646380f902c1c5b036084f9497e9a91476dc2c9f2e54f21b7f2116c30d6e444ca82fe800435cbbd72a98a6d22bac92039c54070000000000000000000000000000000018f493dadbcd93df2c614af310e5aec4fac9e502843b8ca8c3de739315d9e9a380f826e2470c96bffa8789133f458d0a000000000000000000000000000000001768f8c3da107b9ac30a12b99f2f3a0f21483c0be334377733cee6024d85af91b03c7ea1c548b42e7a7869141816917a00000000000000000000000000000000076cfc99c16c270d2f6e34aff84832f9ee6493ab757b6361cc921823fe9c30f1c9b1664b650548dba767616bec0fd5d80000000000000000000000000000000006c5f580c9556ed31847b1a3527ac0b5b5f15b9c9197d3cff061c1cf72dc5c96cb5fe98535a4dca8c4e20c8c02158466c8cecea241dd6a924c9b9cc3d390fbf40ab897208ce9d3e4a148b2c30c25e7eb0000000000000000000000000000000010e2d7eb4e874a9c72a98e4c36701a9fa11051b683ac8ab9ac20d14929d72ff7b92a9048a11bde92dc2696467fcb48e6000000000000000000000000000000000eb29e621e9d0af8f661eb1ba90b307eb542dd84a486568f85e19055bf7b8f0a76d34acf276897a01349eff2c36e4b43000000000000000000000000000000000b5f890f22658b207dea2d721d90a8f5991ea2c5ca06b8d1b293f60959ed424dbd7052e010e594a5ee0feda1e93bcef4000000000000000000000000000000000082cdd4d8452078e8b853f196dd76505ece5e98df3e6a8bbb21f422755af23c5ab261accea48d8e4193d6c884773cf6e428fab2c596f23bc3c9e9855b74295f52caf73cb7371c93c65370583f7fef4c00000000000000000000000000000000077501a457d5f0946d25a4c5eede1b7fd80d90d502bca47d8cc40ab2f9a6d827d7323e7d4035f3d32b02401141f0a89d000000000000000000000000000000000985410246c1db01b42728ea46758906883586cba5618b66c21a3cf58cb98e7c6e0dfbabc5505d1d11ca9d047fb6d25f000000000000000000000000000000001775f4008f688882d02355b6eaa1ab108f239890f71238b36c76228cf2f575cd15f15293a62a72f6ad0ff17d7e8ae79f0000000000000000000000000000000004b6967a5ee180d8b92e95c5ef26baa56d8509e1acc710237083d19269c1c5a1f2d1680e85f0bf040747be1d301300b0f7d3d755410f77a0e4b2fad0f184fa9312b559785fb04c6020432465799ebe22000000000000000000000000000000000fee170589e8a3d3fdd93b536347af5002e59e8ef2ac8327a7e9f382560ee9bc36b3f636a3f99fba8be7b5ea3dfbcfc600000000000000000000000000000000032380cb6c043e3f9ef7169da12df1c6529d776b049c7061df660df841840933e514eb7ea3152ddac38daa2c52d66191000000000000000000000000000000000620ebccfd931eb70ec688110975ea24b7ee0f9937841aa1b7bf4f45af88b732b76a26299f0fe48259fdf08abefb4314000000000000000000000000000000000dee6bb8c198363fa4107996331aac07216b82208242c73736be31e14e4e04d97a56a1c22479dd94997acb0d32abd3b0557b05efdd02ac9d8e1453c82a321d798f3106bd18764140faede610ae01fa80000000000000000000000000000000000eb60e98d6cb4e4b3e58271d47261d05be892eebb9a37f6831ff19d0bf2fc235e655f0eb9b01494868bc082c58ed82d40000000000000000000000000000000007254a64a0d94340bcc2b0142faab2d73e8189dbaf52ad0c3a9206e802193168b8eb03cb18b0e4f1cc95b98b943910db0000000000000000000000000000000001e0051fafaf454072051d2aa9512ba2367778aa1617cecf6a7f989d69c7627c9070c349d363f56711f172d43f5730cf000000000000000000000000000000000f4141c8a45448fecce09908ddb42f7b5f6b5bb53b9e1ede0417bee327644af5c98470e8b5364642fc7435f84be1ab443313884abc4d430c06ae843d263f2efc1bba35f6cc270de05551e1f86096bb7500000000000000000000000000000000049c28e0bc677ccf54f4cb46e953a057ffad624752332fb9ee5295438fd5bd61abd2199a0bb729bb7678cf3077e32ec10000000000000000000000000000000007138a996356ca3f5d63bb5a36dfe901254459ed515e18ec8d91fa747a691b40a19878d9a6f1dc74e4f18374a399d38f000000000000000000000000000000000a621b36a3cf04e6a5cb699fe4ff7fb8b3361207186848e81972fdaecf667ceb35f413bd68772f7c1f77c1d3f43a3d610000000000000000000000000000000010becda5a06f3f077218d4387158e4a1ca5e0ef24d4ed304723ed5dd96da7cc9325f7e4ae16d9d6c348577697aa6017b8faea236e782a8fbe27ab15f051ed007a61e25247f1f259b9300974f521f30c800000000000000000000000000000000163ee307e0d0c3b61ade05a022ce2bf315d820ee8ece60f93d63a150e02be843a2eb2240a4882c29be2c7403932c348e0000000000000000000000000000000001fc8e9ca23e8dc8457df8f255db3b434f52cddaf05819dba7df1c5bfed438f756c8b57442197af18bf83fe9ee2b765200000000000000000000000000000000109cbe5279ccb592bd0b33b1a482df53459c48cd0913549739b784ba7ad32872377c2e3924c4d45064b0cc4764220513000000000000000000000000000000000d789795d556a37a375d83120a022f57e26da6e6f9aa3e40e1f32ed04b50fafc4d40d0b9b20a26e4d230dd789e20823013994f5645c6ce83741e48ae472674921bb2d9b8abb7d04ddbbb85a3f2f7f090000000000000000000000000000000000960654bd6e6a6b2f7d87c3c4d6e3fe6c684a50b62f7acf82a67075139a614c056a41cd49769960e229cf07468fc2dcb000000000000000000000000000000001727f2dbcc8d889127060de0079207eed1e094259b59a20fa42ab2783bfd176da00e61a65709dcd60402398fadf30710000000000000000000000000000000000c17805a01e64c320601e0ef521b6573e9c2eb354157cf0412e5c2b13f826759310907c4b77164f5899958cd30f78c030000000000000000000000000000000010fb286ce797c0429ad3385c709259b55cc962ae02c814e537e5261e897b7ee1b7c660273ec908110f997b166c14f5c181eda24db328588e8c670ab70431ddeebb0749b431bc1bfbd992c91f35d59b180000000000000000000000000000000015d96a0f988f4951206aeda63af85910db49ab817c83e218ec74cbbf5f34f81279d8a3f2fd1f3000f73b8c5550af3fd600000000000000000000000000000000186d2eca1cac226227d8981324859126864b84e8dac563b4d92357591c2416c93989cfd9e1ab6ad257dfeb168d829a09000000000000000000000000000000000a8a7247a3b09583cd2d4949721160573f1f88221e6eae833128914555a594f21a3fb2bfe3b1f01f3dee90f7772dc97d00000000000000000000000000000000132361ac1950756549c957c174cab9ef586eb2057a4eb22f49252cae032975f56eb0cb7ea70810afaf5716afde5b88015bf25b5070829e3d5a66ad24ba9930f3ad64767c51e432b51bdbe2fab470688d000000000000000000000000000000001328e22bb83331adb09dbed0a8c58040a3564fcae0ec85794f26c077de69cc0a7555f011e028879cb3aafac4dbecab33000000000000000000000000000000000a93db348adb3886802bab1e993f5d7275360a5b0466845055d5274e44716f3e1d03a6e1796ed4de4c157dc8a2d92c39000000000000000000000000000000000dc0879a8e9556b7d9b6d5dffce5e648f835f10acad3afca7a73b0fdd5d5babaa74a1ca80aa4f6880d9b015501e218a20000000000000000000000000000000003f7ae8207de4a179ae48cffc8c6e926455e46ef9e109c08be3ae7401bd36e0876642ae9ac4fd75a74c67ffb7790e265a9535c082e11b366cda0000d8ed0f92ee30fd2c4364c163a718518321c5e85d2000000000000000000000000000000001078f43093602a2dacf9b5dd7ec41d47bff02e0dd27a996b58c73febca06e3d977c2fbd73f63508243696ab5d8b97b980000000000000000000000000000000001841869086e850ad97b3122fa51c437113d2bca14deaef5715c354d3845f6829f6aebe668844352d5af3509c0d8da7800000000000000000000000000000000047c42e83194143b9e977fa1babf80d455fc86cf6cb491ef8306a1c32bbf8c868e11bb3308dd5f65fc2942b3e49ff5c50000000000000000000000000000000000872ce87ecd22b39b14c9036e971a562d51c5122bb10939cdfd1945dd1445ac9f5de06b70931aa5c86cd0fda51b89952c4cb49adce0292e259e92b229bf7965864a945de86eda3ce0bc9f1a6dc8b7b200000000000000000000000000000000157820de2a134081eb47b1800ec72630348583d77d512b4c6a8c8e581810471a2f57a8eb6b0af87a91960424009ff124000000000000000000000000000000000378cf11b0a2848b06412aa754ddbee5660730001db073724caf902d4b4894959f035a8838e28554b0efc2388f2b4f27000000000000000000000000000000001301d15f290dd11c3f8e53407195e02dbf8f13e4fe25fe38e84740753b5a0032f8dd07df3ce46ba424f6772b3aa66f4f000000000000000000000000000000000d166040d457187232f8f38f2beb1e0e0864105595764022c282867346166e46eb789786a7ec7c00b0446207e9ac1ec05e927f57aa85b2df54b4bddaa041d43766c8929c8b9146d723806ee0cf042275000000000000000000000000000000000793797c5bce4b1cc3bcd751c5ae1d293477af96a0e7c6bd392ab4410f806a53088cafeed51754ee7e60e61dc200ccb00000000000000000000000000000000019d595730af1f3039e37494b86a638a528d8bd24c429e3f8bc97076c7463e7f2618e23bd3f300bc7e7a4674f14f8295d0000000000000000000000000000000008e245c7590888fd8dd58f93332b81f48b6e3acd3cfcf5f3b28df654eae1172f52ef5a121707aa9cb111b0b402d1bfa6000000000000000000000000000000000a7c6403659e1a0c2dc7cc2e9b57a452bf553e96388676f4bf4a6e26b3ca2d3cb82006850d8340dacd65aaa0d20e6fba606ee8a5fdd9890b8017f6c432a45517d65328f13f3a2bb42d7115c02929db7a00000000000000000000000000000000054c37e8acadcec8a795619647d4cf1081a0592de02bef916f847936a1736e74cc3b7ee018717495def8b4ef1d098fc9000000000000000000000000000000000291d89d152b414fb5e7139d6d0bdc7b5b9de1fc44b49f895ae08718b631f7652bb4a895fa11149b9a9db30c344108ed00000000000000000000000000000000107b30992ced35e4ba874e436bed5d88aadf0a0c944ca3eb8319539017bdd652feb7483ab6c705aa17e845723b2cb46a000000000000000000000000000000000895dd8e04114fde4a4cf19925004a72f617f2ff146dd650a2cdbeb12977dd2b34ea7d655dee16ad9560b144b81212f5c1a77ccb4b32a762d60b37827ad6c3448c33af6af861c131adb5920ba3c2b85100000000000000000000000000000000005cea2e036a8ce057e4dbe2d9d786eb759c2a75934580480f78d2e228c3150a0a1d8c95ac5013aae3ab6e35f524d37b0000000000000000000000000000000000e18c18884209f9e4fb17431248a5f8d29c616a58af16e949f4317c2e117b80d531a39800dc70f6b161b98ba040a8af0000000000000000000000000000000007c42ce885d1bae906128589b72f2e6c18e4eeacb78c853e923e6eb785c073b6490b2f6b3dff2276916d96770ad5019800000000000000000000000000000000132d809c37c341eb0304ec933a6b11bf9ac0d2a13ead818ab6ee03ccc94160b405066381dcdb13b6ee3f5dca48ee10ef47cde609c38eabf457cdbd1e0c5366bf523dd5801d66a0282bc187d80417f455", "Expected": "0000000000000000000000000000000009406918e2dd6f06f4782ed110e29516a911f47133ad8adc58f5780de916a8973ad60e05ba931d66de7545a92f388c20000000000000000000000000000000000041cbd52cad2a5f4c8353c7153b5711ec23fa8bfa2f34f5e1a16d8a14cfd47c237766880debb992a05ba9ed0353beea0000000000000000000000000000000017d4211c827379b310956371129011a92d62d11f0ee5b0cbad9eea2d3f2a95d364717713fd0c544747338725adf27248000000000000000000000000000000000a61903fb81064614c9c6894c7f3954aace7611cedf6bab8e751f0c203bcab827d296016947c071d7b6ccc742e28ee9f", "Name": "matter_g2_multiexp_23", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007f90813f8c3eabcef04dc1bc9bbafe1dafe220e2db24e4b714aab2b164d7ec9df3e6a3f903e8b7b96df2ad8297381d2000000000000000000000000000000000e34371e51c4c952a0f38c4aaa5fc2324971ade310af2f36ed511fc5fd7a602a551ef77775fcd0f1fccc718710239561000000000000000000000000000000000787edf7a6ed6b50afcd7c0d3876d8919273428bc49833e3503f650e48e788b15cd82eab2672f612025d796bb62d72bb0000000000000000000000000000000006b49e631ace4f72c959919df5d64c537537ccaa3d1890ea9a1d70f9eacbaaa2ec361edf2d4880c9810976c6073028bc3c79fe6374bf8f91bf7851ff935a124b54fdb5db498d2d37939fcd43bb93d29a000000000000000000000000000000000cb63d7eef2d6614d1f629756b3a619a221033207d1621e4ce4791db4248500649b91ff07cd2f1f06eae3a9be5b6af080000000000000000000000000000000019aafbe56da1569959019033e8cc785c9b98bba6b069603969e7ff1150f023706b461913ea7949306a44c3b7d199e86e0000000000000000000000000000000005cdc3a7004f7a7f79ffbf4c4ba7c5dc30ecc62f270a5c231406fa63d82fc64f45e94779cac851ff8443040fd3b2ea6200000000000000000000000000000000040f30dc98e8668194c9278b189e0c0f7b76a4c686ce26a4a96b93190938f07c5b813670e206eb6b5da29624a1b6314ba59fcd2baa47621ebd90c5cd12b89f2a533ae86d537fbb61a14b1a80982c9257000000000000000000000000000000000a5a1bc231f803ae272e497f812ebb663c2ce8b43a366717fc6349264823ca93e29e30762c1a366d8680f81838907f59000000000000000000000000000000000a88fd59ee380449d632d7e1b926210d984d5298fa807570a63a63828cfa55c6e2f01b7745848281795dae36e562181b00000000000000000000000000000000025ad34537909e07beaaff09f22e91e76d93c668d1b45cf6845ab8ba0129e417b758e85a7100a31a9037e307f454bd370000000000000000000000000000000013590106126231b1c616a5dd7aa7ed6946aacdacec963b507907950d6ea11cf1f5b59f819a43eeebaf51a1faa7daa8e719ef9fdfc5f0c4ac41255eb172d485317c124211498a8b9a74c0bfda15b986c5000000000000000000000000000000000938d43b9747c926c3e2dfaca2d6f1e6d61d5a621ae08c66a5baf33d9241771509689f9ea7d75af607d76b66faa8fbc2000000000000000000000000000000001889a48a74966b9748f4a6128dc3d75a69499db1ba1bc9aa3a9428f0efa898b5f78a9e2dae942d3794ab3d1157a1d305000000000000000000000000000000001129c9bf343f476541980b85229c5c25289ca62173e29b75de431b572c8f01f64ec1aa4625dff9e7df535194c7f4e6e7000000000000000000000000000000000fe95c71f703dcc71cf409b332f66fd69c330758d41832236a510ec4bd9a28c4732434d4c3f97445e6301e3070153dbbb8ba028831f429d027319a92fc0f30def8b97a43da456ddc79443d9f8df72cc10000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8dedf8a6d86471f58c69c1a5e7518c69c34165e72ce84fbe0b7f69d9c2717e5d4d000000000000000000000000000000000b419b675ccee2509daf66e5da4031b08792e1181140b30489ae21f7925305d8cdd8a104580ae5938586d6b8e74f750f0000000000000000000000000000000012e070ab7118991a20b27f1a87fba1f5815665d76269f0d3d460a6b701e57ffdb4fed2c53fa63a3121c74f67e770f31100000000000000000000000000000000124218ca85f235eac3471e0acdabf73f79afdd4bbc159c1e34c641b97f03735e4c3430264f2d94f640486488dd1067380000000000000000000000000000000011c24f4fa1862779f22a628edf9d3cebe0f7593964b642f889201ae85e8fa01e00e48355053f5a7c6d920dcf6a7ee1d60dbaac3f5e25ca3d1d50ebb31258ec4450feca1e02c84672ef15c49b4de2cebd000000000000000000000000000000000266bf0d9d5a4fc713dc0fcc6ea6edae0b326e22cd97bc49c48a7ba398fc87d7a0c7141ba24d80df454de66c2b5a55fb000000000000000000000000000000000aa8f95c7cd61733b0a260149d6608a73d6c1f989afa8cb2aa4098e1fb5a66b4ad5a5c1c4d901aa79812385fd507f02e000000000000000000000000000000000a6b4929df13e1fe7f0a0cf699a7fbfaa97d7527cc3ea1f728ba59def2e75fcf3490199bd42e93b7d47985a307add07c000000000000000000000000000000001719321981d2085ba31c9fb131d6b79c7df5d10d6ad0b5015454329697860121e781093fdde1f19e897dd6f2c272f87a109ccbb8fcd4d4651b84f4708799d84ad0a717aedaf5a76d2970a7b93bd23d37000000000000000000000000000000000431002c9926aa7d2b06412f544a868a7d48fb5f077dfd098febeeafc28b876c434daec809e5cbf50ff2395ae7e456560000000000000000000000000000000005a15f713b6eafb09495cfb1c89e9421515a07a99ca0f208883f11c430ffe6f2592dbc41bcee5db36385a26f67cd26bb0000000000000000000000000000000008dd30fdd7767486844967c5da0803b52282178287b8ef28e14f07b487132fea3a82d86d414b4d0a25b3dc538be11b500000000000000000000000000000000002dcee67e2d17b3106dcb9f4117456a037ae1996e8f7a09b179baab1ee8345c6d01eae554d3f40da86bd79a04702fbf76326fded2b8a3fbf7637bc25bd201d20e3d4d724806cfa678ee039a39c24e86a000000000000000000000000000000001629fcc374e99fa8303a715fb5077f266b13367bbc0098b5463d3298c0892f83127d6b7f751446575b88858bc742586c000000000000000000000000000000001100783c10618752d25c235e1e76dc64db94adce05651fb8df0a5ee7c299d35b1319f7009b857892ddf9e90c91f7d23b0000000000000000000000000000000000ab6996e4935131becd5df288dacfad1e69b41e200ca7dc841ecc180a81b9d2ca14fc8a76a4e7bd6f924bb9f473de62000000000000000000000000000000000ae9b22f8dff29e5e0a2ec5b5641f53fb5e1ca03130b49d0c26696ca4b439a9d998d9a364ac9cc5ec52df699318cffeae005efa8ee75dec8a013029292976e107a507ec09e3c34fb4baf2979fb759f1d0000000000000000000000000000000019c557ae1c12ff8a7c00b7c9e4bc3d65c92753549c193311a38a84bccfc090052a2219461a9691affe2d67ea4357cdeb000000000000000000000000000000000cd35c5dd126bd4b90dd671f29953c5a49a14b6b3fe946991416edf235c3eb3d574613d27b05cd879518fa7dda3ed39a000000000000000000000000000000000224392063b0825fd332bbede23588c1912e7670a013a99da5507f650dc4284431698a5b4e8c180269af8bb30e4fc8450000000000000000000000000000000002ab8d3250d4bb8ceecc8ca2003f91420d0ef8a7dbc2361e5e7fbfcb59471a4c525856bf796a2c2608d219d215cf83fe3917f8baf17f71222166cb9b6c4beb2e57d0d054cba3f7fd3a28cd3dc4b409490000000000000000000000000000000000911417908c2bfe4f63a388f699b31b47df1ea0ec289ee3f96ffd0c71f3deade00d1841aa56b4bebc2adcd3068adf920000000000000000000000000000000005467c7e58e82089fa285c28ea22c759c7806d86fbdcdcc8e09e847d6330922a61bc331ae3b5acce777b7809ca98213f0000000000000000000000000000000010f376fb47933b1f701dd81cebaebb2d8d8f5510a26fb3e9e156ac5ecf2b943c5fa2812d52da542e6c335abad8ecce3c000000000000000000000000000000000dcbf467432acfa4eb9ba11a7cdf02f9110f44ac371128ff8f1f98fc70e4554f057a4608180bfa54d99fd2da010594f6f0f73e1b62561f5b0fbc409e6534ad9e37d1c0724b35cdd3f94bf6489e500fbf00000000000000000000000000000000179aaa7119f6fb986714c03b6db16f25eca7172d24cbdd318bebb633bf08920f9e2a8136c94e3ec7c19e57ab51531b3f0000000000000000000000000000000005937c484213ab5b2ca8ed1c5c90e8d2a2f1bac044b88c04b301ff2fdbe67dc4ea42779d919ad510cabfa2ccd178cd9f00000000000000000000000000000000183cc23fd64514ead63f55d375a07af7cf2a56aca64a887dcc542f8a396468a6abc776170a5d4b4bbcd4dbac285e7ffe000000000000000000000000000000000ce12228dec2f84219904d9ac7923f122a99803a9b34749ca68ba385c178811685c19a492aca2e1123ee82a8a9cb90fc3ea24fb6447f2493c78a267daa158eabb70c1b60af8175d0d4594c99122cb4420000000000000000000000000000000009612bf9130e17110f8b15aa6f3317071daf3433bf6d008c383bd5c2fdc7ca03f25ff4cdb483de3c84c0ef9e579f38c6000000000000000000000000000000000c40172540a7e20eeedfe02c37aabac07165cbf04830f20fa76fe8b05c826e7762c9f7567a0fb972212bf736e627948a000000000000000000000000000000000f49e5b1929ad3ed5c07670c471710baa24e8478a50f72a5b7bbc23a66cff91d30a3d68961fbc2e6e8003d08196f325c0000000000000000000000000000000004ba098f915ba9e934384682648ed8d4e1cbaae60d596655fcd9c05f4b049ba0d278730dba5ce3fd4892531a3153bb955ed307c01d9e29a0571de07c62d5fcfc80749f02b8dbaaee9f69dc9263e99188000000000000000000000000000000000449b15ecec6d6fe5cd32437b54218f62527157aa6344c635fcec8f8305c8b6e44c93105984e0832536237606f07792e0000000000000000000000000000000011e40e8aaf75f5ff8e4040f725ac27693d7b24805a2539ff54b3a6e90c048875ea9609fb8fb3d8de63ca1118876c172400000000000000000000000000000000006ef2a24445f728b53cbf01e5b076acfa7761a84d8261cf1a1b99cc32f330f32fa5ded83d5cd51cc284207adb2451ee000000000000000000000000000000000977966380e772670447b15ad9917035273eb71a21c37607a761aaec808909fcfed50679769aee1573d73cd241de6624877f31ddcb55d961bf9bc09903bd927451390922d647d589302855141cf5cef500000000000000000000000000000000074e475c0ff1a51a24be3c964c45c41f767f890dec82712d92a965be504fee43fcc6c0684b2b17c5b294a3eb7ceff1cb000000000000000000000000000000000597b7dd287f3fb27e35a9e4e1718b6b1a4addf9e95e93aeaa25aa34023669368b794a08fdb178d9bcda2738534d1962000000000000000000000000000000000a492d648393bfa317165ccb552e045fefce5b3444d5ff770f43a08a68efefe7fce1216114ed1495cd00f832538198180000000000000000000000000000000003d85cea8063828ff025ba599bdf1efe0412ed5ce06ad5faa841c6400e4eeb6aea1470d48f4e66fc768d7e7bfebedb37145c1442ab82241f56c27dec2cd4dbfa9fc3cf1ab72bc521ab32a82346f8f6070000000000000000000000000000000008ecc3dd40da2a7a348b4817d9c84242f2f07c5d0ef810dc08311e9d4090d6d96d68b6c725ee6c24de076c71754bc4b50000000000000000000000000000000018fb3a1dc4e0dd9227fba310236a6db7953f0b716fa995b928a2a8de38edb97eca09fe2ab385037dfdcda2ee577e677900000000000000000000000000000000062fce7fe7810273a80760d9f4b3be9e7c821f38ed3e075210d3aac6aa7a763e3cda56465f88b34540b408ac850742080000000000000000000000000000000006fa94466cc47990a80ae6a310ea765590a0e646b5988925f03cc7e30f04fc0a8044b403212290b2fc46c77e84a9028dde4d1470f6cbce027465b4dc2a3deaca14e34218910aa76cb45d47139b31df88", "Expected": "000000000000000000000000000000000f41bad0a932e28096e51482c646dbdf294aa7b91e0ec258670e7674864765c76989a936fb440bfbf4268a49f450d3230000000000000000000000000000000018282b76521db98f589b1c14e603b6f5d27af357553bca761189a38a944a11c66480f7ddd89d17e4aeddc8d78a2b3a0d00000000000000000000000000000000007efc4a90dd97f1312047ac78a3163dc014c42a44c7054daeefd5b72cd0488832cb6396e02ccff09e4171d790954fcd000000000000000000000000000000000e790fe8323fffc96705a42ca071532d5359641ff7cf8714789c9c578717a054c811cdb581df8b6a43729c6c3e3255ab", "Name": "matter_g2_multiexp_24", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001304e0ce6a4baa6e0545fdb314523fc91f73eee157249b94f284ba7390b12b23b1c849c45a563ac82b62a2c48aec24e1000000000000000000000000000000000a2d0e9e222db70d49d1e85f587d35bdf5e8328aad14343d296f95b152a79c83a4858cafc350a5df1ad0194c49bb929400000000000000000000000000000000199efb09b34d0699eb4bc1c57fef9cc5d98453bf522c504fe7897e22bd0596a3a6c310eb351e15e3f6609b074b240f7d0000000000000000000000000000000016b69f12ce30ad1a65150094e29d4cd82fbce5dc343517ba9e5d89245ec083c44af9a3dad2169f713d3b01fdf70d20642576b42e0728db912a78eec2b7b4c96575e341e86a7592a07a660c11e0044839000000000000000000000000000000000b3ce4ac12861052c602e71906a7c9f3e2186bd2b6eaaf222d8e80b48baee537065ce78372ed936e6728b9642ba1fdb9000000000000000000000000000000000e8186561d23515bc58c77769c93db76dc9c62bb715b283cbfb71462451120a6ded736cd8a292a6799fbad7617d9aa84000000000000000000000000000000000368a6dbc7daaab0a786257c813b1a25c97468732c27cc759fb921cbc3c9a37a46d7dd0298771c447d36ef0a10579ff5000000000000000000000000000000001348d5e34cbe54e3a6b357c4e651acb82d2dc40ef9ed8bb89f0cdf0882ec6a737998f4e4dd61e296d101cbaabccdc3e779f9205ef0e3a85199c60ad9267349fdc7b6fba4cb765ab21750eb3dcfc48d8b0000000000000000000000000000000004ebb53c462239a78bf13f29856ddc4d78645c457a656f3cccec9d3c032ec19c26488f39e0f5bf0d38424f9e3a9bcc870000000000000000000000000000000002fe1949365831f7c38b1cd6cf2e22345c4ce40cd73def77889c214d1077d70e39578e8be4fe5998f59d47cca7917280000000000000000000000000000000001152f2df1512013a42ac056b75802bc35c1883efb345cefda8276c594b061a0b0f4a49d8bafa6fe251658ee76b2493cc00000000000000000000000000000000094f90cb386f7933b2ffcdba5e46e09cbd7d537c12bc223e76d3a88ce9063a7b3574d3306365d65dd4c6505f1dceea53300679b7be7c71224247e8034f5d30a63f8707d92d843a703f0fa93160f6571500000000000000000000000000000000169d9469c53e55768c9312680ee82ee581727e28cdb1d6fcdca25d0c03f3da2ad6572039f12c90b09cdb843bc506e07200000000000000000000000000000000174528257f6d3542f754ecbe97eeeea7d196ee4dd01852f6cbad87fbeb4dd7d3799588f17aad129a15549bb787468772000000000000000000000000000000000c9ab635bdaca1c488538c0830453ec6ab3b2b62447c03ff6ffd2712bf62e02a63c76c79d41644ea412e733128685c45000000000000000000000000000000000172ef0fda359bab149c8c04f583f4ace4d1b148426e993996d278f79ed2c6d3933d6cc5fb62ec4869aadc773d3084ca0454b01910548432a0f706818a98151e38ff9e854f1faa95ad41a7239b5cc4910000000000000000000000000000000017060fa73b58957d12b3996d67b7baa8b7f0943ad52e80e5c4f8830d33dc74c0a39e08594b647945b402299ca861f7b10000000000000000000000000000000001efdc7f783f9977392e2797a3e0bed222d5b661d056aa0c7e04a493bb9b18048bf72aded134941ece78d63df0a0868d0000000000000000000000000000000011355198320af05f2121939e6489f31e9e13b3cbb2cb30c9e675854cb8ec038f80aa2f4b6f995774b36f5f1b6a84298f00000000000000000000000000000000172e18c490d0cd5ba2449362c0ab296212dbe69ac25515d0f91941d300051320f067f946dcaf999554f55f1f616adc0f3685617371b27ba8898ce7f30776d817ff09ef68a9d6721d4a923ed244ae82060000000000000000000000000000000005854f4dba62d1dbbf3ae16f70792f1bb39f111309b454a6400d2916e619d4f70764ecfda7eae5c28cf1d178ad53fe6d000000000000000000000000000000000ed0bad1f5d69a0e621d137746a9ecc764931ab89f24ca827e0340ddc03571ed697f63e79cc58b946e8462099ce4b1d70000000000000000000000000000000011de76edd1cc2f9ba06b98593a24a7a011f2701b451ea3ccd04361ddb678e06d91a676e3f11b62c68cfc05242cb8a859000000000000000000000000000000000599726b5f5b93d414f9310383ed9414e4675d644f83ebaa63dceb2bddc7dcfcbc17c7aaaccd0ee32b0875952554b4e660cb5aa2a0cd1e8c3fdc06a3a1f6f9b6d52a8cc2e98c85b8e258f72d03efc25400000000000000000000000000000000031110347cbea2756b5fdd549d6c0b8f4036f5718d41dcd6c854a91c9df29bd464774be479d0efcb8a3f82cc7441a6c8000000000000000000000000000000000e24a52dccfdda3689c87395e45dbd46156676d9eb2cc09dab22ef7ff0acf5ea243ff117c82b147994d65aee8605b2fb000000000000000000000000000000000e0cd6ea0bffc591c13c48bca0782fecf8e128b0b842aecb06f803a223d32cc350db869b7a77f8e31b05f36bddd587ea00000000000000000000000000000000042ff4ab4596d610638ad23eea904a82701cdf61f9e2dc5832a70e11e717711a2d0e72f32f74706d385a9567426b4713addb1fe778c84242953db87d2307b40eeb776f17767c3a4311b5d2ffd738f151000000000000000000000000000000001517efd853800946aa37868b525e58fb488bb69755ccec806afca2d21bd3a30ba46c39cdf694ad0ca92841760437c3c1000000000000000000000000000000000e5591c339e88544660380d6362f4119c5596f910d4ceb96ccd4c4d9672efc50805b6fedffa0a48d126aae69b241d3640000000000000000000000000000000010ea5babb0de734641f63eed2eba6124377b5c55e429987917c0bd109d7904766a10b0d2dd123413816d0fbabe25050b0000000000000000000000000000000000efc89ee2ffa56193129062ca55a3350bf50e8fc7d586fae3636a70e3577987fb0f8674d383def4b41225e490d3d81528416b4b4e965a5f024723fbad6ef2f65a1381e70201e26ccb40188dc3d0fae8000000000000000000000000000000000dae4277d62e3f3dfffb80818a5ba5c371a48d73b92d69a168ebab897ae8be206fdf776e9f955136d7f7f7b2903040270000000000000000000000000000000010ca635ee2e49cd6c951d75ffddd11557432726d26564239c611b139329a28812afe21f094c0585675f4f233233743050000000000000000000000000000000012378b2ec31119e508fd9ae0ccc4c2603b6820283284a278fe16864e5a18cf7992d850c1d6ebd1253103c219bd95ca4c0000000000000000000000000000000018cac4f0660240045214034cfd8a7e40bf0aa12f97a23c4e27db0e05bb25f4d755276a91a4e882a0be63437a522943ab78077a51f88236dba6d16d7fd681c631510106b0eb7448df456eb9ce758e74cb0000000000000000000000000000000002fd5571c818322d207d58fe0a898a045a26c95c2490765dc9ac663a0de78ef5fbd05b20ea96dc5388d5b2ccf13a5e320000000000000000000000000000000006ff29ccb768da45061ba4e01c90459ededa5e79513917401e7e37151095ccd4656aeb9cb7c083cf27b69377295934cc000000000000000000000000000000000414d34eac47430495be735eb5c4b1a68372abeb43658f27613a9c8b78f17d9074174a8deeeebb1f9cda5d6198bdf89d0000000000000000000000000000000010b11bf63b8c39c1370e8fdbfdcd149fea88eaf1c0a94a51bdd061e4c41abc626a448030bf9ba880032e9f1642caabae871716e790e1a0120fd26d169b8ffe3fcc0d03683dcdba7d2f953f05444076ce00000000000000000000000000000000023eaa08a44eebae674434b013ae9992c75690a3d0de53e4b05d1c0dff249feb24a12432bcb5defe25ee4e44a56b27eb000000000000000000000000000000000f146ac27e685cca04afe8fc58fe853825f5b0009e8831eb0d0121decec23b25bf8521da2fab1508a3ad8254865fbee70000000000000000000000000000000004af1a525d3c33e0b1629cbdb90c56a88d70a28037c87db81c59bcbc811c8f0b98aa9dd574436c9f600c0e8e2d194c0400000000000000000000000000000000170efb5e0e69e46a21ec3b972265bc04b9d5ee926254f61c0e18fed013922e00f1897cf69889576bb5d54810486e7f2776ed0a27553db6ac6d3959ff4c9bc5807fb7d4f0a56095ed2bbe31dbfa41827700000000000000000000000000000000111c832a96329d6db203fc8b6bb5b7db01521529c91c74d9cd71dc78d067b36cb7eabf1af80129a7a3f44b719235927400000000000000000000000000000000097339c17816795238629d4ca6c243a14e9e227e9bfc30370dbb9e1475f6d03020dc35559675121792436bacdf9eac4a000000000000000000000000000000000805870a1efd1fc34c9b576b77418ee8c0d36aa9caf9994a051e1d55b49275f34cdb55edc74ffc267c5776c8d0e113ed0000000000000000000000000000000001513afdfc2f000e3b725fcd0428fe72ab2413ff2aa91b44458a5249c9a160ee27bca01d2fc2e230f4a80454769961af95ce72b30d989889c8779c4056e441bbcd93629efc2877d36d27f670711e21c4000000000000000000000000000000000485b3b1f812b4a28ac87d16f86d8d634e85d49d6dc460646e1224de662e906002c44a1a269c3bc011fd22afeb2d58df0000000000000000000000000000000013ba0752444a794cd00c99eceae51e61c382d0abb26e5e0e595d59321447400e8a8f7d97390bd217fb50bc22cef34b2300000000000000000000000000000000184515a36024d0bf71d9fa4cc5165363ff94ee9f8579bca653ebc0620a9d3146fba70a2f4a9f6bd3777101de0d32e327000000000000000000000000000000000e041422088c0343f7704e726d65ccc4216c4a1bde3668108983643663cf0249e992f9acde2dd8ff478dd26cd8d9434d06d220f64de05bdd6e1140c1e409fdc13f43bd31cd94e633be38ecf22ebd77db0000000000000000000000000000000005bbb0c55fdbc59992c83fc0ff03f677e58b6de6f8649141d88963ebfead9383d692015a7b765b727eacb6de250351ad00000000000000000000000000000000183057eca610b8e07fffb60d21bf2eb87981e6e881bba04ceff420ca38228fce2f94d40a993e2aef09e209f3990dd14a000000000000000000000000000000001231bc55242bea6b589cedd1d82621fb71c606ca9306b268379dbf83ddb1420dea228ffc05cd8b67c38206f3f006ef18000000000000000000000000000000000f2c943e7a8b0ee00fc4e4ba912b94f68f504d2783babb90a3781b666b31bd161af2f97a77813eab9ebba76040b04155257da8ac7d23c5ed965d8bfc76a642a36ea6ec4c45baf6882021372e8643f09800000000000000000000000000000000054bd97b9cc979006f734ec433e215a4e8afe468e69173384bc895e10ead3749d991ff8ff203abff30bf5cc0d2fc8c6c00000000000000000000000000000000066b73a98d5f5ae140a5784c5594892c849aa7f2db3b5798643f755743d401ca745d810fad5f4a33e5b3cf0fd7d96f7b00000000000000000000000000000000007caea93ff5cc6ffc033717220a215ac4ed7283945ae77e62320a0bde13f2153dc8dd401297cd124b4c67a4f3839dfc00000000000000000000000000000000094568035ffff439e3d3201466f3a1d43414e3f6455627c5479c8b7c55130ccaa5007ace7ef6a2b3e2e5a4c9543dad9163d017ba8c7ed138b1bc70141abc5cdc3afbccd8b1db5a6b5f775efa62b8dbc30000000000000000000000000000000015eeef8bcbfac04112931e186f6fd48b7a8ea891ab364ce8266c5fd15f072f08fb3655e324795df182a5ed1c917a5db000000000000000000000000000000000028916fcb3b30a7f95321a0998e544f9f4f578be7a9f866cf72d6b8baccd93f8935f105ed26aceebb3f9c96073a8be180000000000000000000000000000000012b11f356a7e32f3d9281a8999363aca0ae5c1a058724cefb51583e5f217257d47ca76d21e54ab62260796b95f9d3ad0000000000000000000000000000000000d83c75c36cc8dea4aab47823edd26b4492da39b93a15fa454aed4175f28a025ad2c576ef2d76a66e666bedae95cef1a7a16e23e37ecffd514d47199cff249415a6d366fdfaa82450f0744520258955c", "Expected": "00000000000000000000000000000000059443f363ef0c65973d36469ac651eec6e52485a07a6d28112f4d0711802d182b7e6fc56d4f1aae51fe1c549247d885000000000000000000000000000000000d22118a6f1cd06ee14c63f0e005076bfb061bb85ed184b5444c08ed9dc35f77217b6daafeac89a973f2c73f00e0d3c800000000000000000000000000000000180430caa9917cbb40e3ada2de8d685b4daa99639669a643b8f5cf9a4a55d6162e9fd7f5d4989a1a6588feb0273669b90000000000000000000000000000000015d01fba1192f0f1acf8fb32fe790f0448c6563cf8ef5505d9378fa2fdd38bd99ba938077f71bb8eaa91a99e787e840b", "Name": "matter_g2_multiexp_25", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012d948b5268524659e29cd407dbbe8f529e608193ab9452f936b2f6fc0b81d3a63a0e929329e2d89b5475dc2d73ebd8a000000000000000000000000000000001219e20a081837f4d4e33bdffda08a946bb9cd876e42e2f561ebfd18ec439e0104b43de61f47b8b7a0c346c33e632be60000000000000000000000000000000000a135c72c45f254cc1c260af803e14cd0f89c2ac3029629a86b05acd3440465aafa4cf84e69551ae772bb55802a90ef00000000000000000000000000000000052750c3a99974f9044531dee9129110b99572cf283b61e6606f1137a87de7344bf01d2ac2f8a1db8d815b6d9e7511fa26a9bd0a71fd58edf81459152782733536e960d27e35f9f84d00da256bdc118c00000000000000000000000000000000136b2f21aba94bbc8e5235951b1b186fd4ad221e6ecbea5c7279cc8ee8b01edecedddf48cca47624ee9b155a4c167f140000000000000000000000000000000019852d2bc9c8abc92503f3e7eec9fb20df108c23643ba8a2fe16c2cf085bb4ac079d3f065a1241067daaf401b662288b00000000000000000000000000000000018bf1a4e74ac9507b97a990f3a41cbae3f32e263e9937a8a62679bee93296ee5cd25110833eb5d136425bae0e9dcb8100000000000000000000000000000000096ae4bfaaf4f18d3e987d9f287fdd3dc9b497cc84867e757da52bd5f58688403e1c9cb432a2eb87e239879d52990ab5f1e168ab93674bd7f2bf73318a48ef17ef4464fbefd39f77c17ebfdb24d679b60000000000000000000000000000000016ebc2ee18515354b7af5d924c895ffd5556ad088560f89c59a4ceec229279d4075f732b884a6ef2bb2eddc11d27572500000000000000000000000000000000110282084ab6f3e76eeb9e5e8c56749992913c2404b003df9c2d01d72751f879538d23f612c8faabbccff45185f4c6a40000000000000000000000000000000017476677ebf052d13f60ac0ec5e572c398f1a478d60ce92a3de88a74a28688d786d30b1ea8008409e45697db0adc628c000000000000000000000000000000000a5e4239d938bfc7c05f3b3a850ebd5f7784eee7aca48c861eb4bdb1ce6321fc9c6bba997e143aba13a42f69ea14937397fb0d947d71a1b032070a12588b85065c19affd0db53e466f194f04f58dba2e000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc640f850bad2f22049f2f8aaf3ee57564fb38a847e428e252f003eaac465f7d670000000000000000000000000000000010c703e31f2d488812a387596c797d8d414e406bd82f238cea50a459d842502e11220ad82fce5dd36635792ff5770bc50000000000000000000000000000000010c11caa640708850e1dddd48bae22961a45029971d823b53030979b7d8ef2eaf2ed055436105697c5b0b31b1a9d0a7a0000000000000000000000000000000006b98568b2b7f0aada97310f7e14084a14bffe580ec65bc8fe5d19c6213c45dc1b8e1da5c6c1b8555729f6c781575278000000000000000000000000000000000f2c506f3e41c28a748656d1dfd87e812b3ba21815637e497a30eca4fc5de18257846f12b67919dd2d739477cf5ed0ae8bf91051da5bce0a51bcba6f4e1b3c9063743646f4e75e3e5a8cbc84e8112af400000000000000000000000000000000102b6d561172adc9316b3ec11f05e66e7affb1bdc70a364faffa57aa5938c2ac08863be8fe79ce3f627558fcb2ab1230000000000000000000000000000000000c5e72c271a1ee186d443a96d53f0ba0ce226c76aff2a7c3215c2110f96cb3301bd586f509edc45cd20e662756897b78000000000000000000000000000000000d546fbf485bb283a04fa05aa962ae8d77ec4d26f749d83b208f77247778e32a9a2f1483bd84488806e27b13eabf41d30000000000000000000000000000000005a42c6ce8d43d122bbf984e9777f5d1c15057f27e70fef44b97c2c6e7e2e303fcbad643027b7ff3167916f21a723ea98da771e0e827a52a2f7e79e0e5d93ebae04c1ed78cab87d4353f24ffc52099b3000000000000000000000000000000001788323aafb95f8761f87f771fa05a8e49be71e397849daef5877a7f486af13fa651be7a93bdd9465df7be4ff65825fd0000000000000000000000000000000014b7a56f3f7c12e39be76b3872c1ee648f62f9cb6a1842d869e00a5dc2ac8cb4ecd96ec2483d5eade5b0f9113133bb050000000000000000000000000000000009a30623632b757ae8d03ced0c1fdd1877718f8d84f34ebb42426284f73bb7e8abc31a5e5ded57a02d08adaa90abfb2600000000000000000000000000000000020b47acafefce7f617081e22b2bfc566acec6d2cad5063a79cf33e02cc8931bb698b72184a11fab73e0bb0aaec76c61d6cff707bff10fd53ffeff8e9400966d8ffba6d4ad6a8e7e456df10f8f5ebed2000000000000000000000000000000000d1190466f0e8f03d2cac4a5e63a13d7c6d0cac9f2065295e2de818773199d731f8cb7b2be5f6ef0a246401b345a2d560000000000000000000000000000000007d9c5d187494df79c25b6292527b0d6d8c50b6467bf76a1a1316556e48159a3b5dbdbd9fb0bb901d857f61f423d15db0000000000000000000000000000000013e4401fe76e3f1ef73bd244189cdc81fcc152f71449c11aab24c4fa1d123c5aa8c68a2d10fe88c1c6631778dc0bcd420000000000000000000000000000000004ccffb4296883b8690b2f3fe17e4e9ab24390084ac917ed28fa1e04b9758373abd348290d24c915dfcaf0649ddf5a87e00831cce307cb44e8dbd5edf24f1535b837277160d2cf6daa4e862e57fe73b10000000000000000000000000000000000f4baa5e531ae462b95362292d5366daa89f2fb2707c58568c094c58578e84a8d253fe1de26b917b84635c0aac3a63300000000000000000000000000000000109057e5c5451eb9f85b95aa5ed2615d2faccd0539b1e4481923e04cbdbd2ea9290969022cfa508d3fd050549c74940d0000000000000000000000000000000001c3e147ad9c31927207f2344fedd541316f4010e3de194f924c4a1450a221285b76ff1894f8b1670731007f44965100000000000000000000000000000000000909cdf5c56dc177daa1f3fd7cc31d79a4f6dfcd462c07812cdf629426b75bdaa297b9d7e67aefdbb58175a21e29edada8168d56385722f339a5b27fc25a88034d348e3d533ff4dc99d28536c1c09a770000000000000000000000000000000009b4c6bd1c460d2e93febfe523c1d54d6bf6af50838e7a10b732c1be8748a0752a517e7103d0ffa4507b086626fbfa8a0000000000000000000000000000000015bf2c13891dfa8dba35b5da1235563d4ee1dac33e89006f5c9fcf06f2fef7b31ca845bcaa8ac608046e8b01c8a61fd2000000000000000000000000000000001898dfd6a0618df821474b90542f261c1febbf2e566978b0fafca44f6dadc57202f88366b19d2c955e4291ac21beab520000000000000000000000000000000019287e1ac6b3eaf412e58511b40d87558e7cbf90dc8af2f5d33825b40fd2f2425d0be3a05d0a49076f4114350dcc601eb929ae82ded73a4876c041d2e52fa811882fb8e22690a27cb4ad3ca05169bbf0000000000000000000000000000000000c0993401c024d32cecc0d86d4cc52c200e59acb34fee2ae052837f467905e736a1118260ee12a963ca2df6e1a6c9d0a000000000000000000000000000000000103f78f0e7c9a5628a66efa91f150a87e67623ded2560aef278a8caab017fdcf181981952b450c67e3b4d3f362822a80000000000000000000000000000000000df01ff335f23652f1c34480d23c62d705572321c0e7fe92556e033dd3cf5b78a3d554585403a7f3c71744c20d17579000000000000000000000000000000000a0e2c9e2e34e5cb36e96b29231f702abb127a011c7ea3e21d59e5c55f745a02039a68d59ce8e29afac0752d1939106936999c516d4acdfbcd488d39e3073db9db6cdd0c0fd1d29d58294ace6d2d199f000000000000000000000000000000000eabff0e6ed9dc358881796441c48e722ea171f26011ab898c5a06758f61a629ae21d5a2595a22dc9855fd2e516b30fe0000000000000000000000000000000002732155a7a2791078dedfedfd3381281554c389bf9b5baa47593153a2acfd22a08557d7a1d49be298e416051b9137dd00000000000000000000000000000000116faa2e2a261e6a3e4de6ad80d75ee05aebae47872e2eed9cd91aafb94a706de673a05f1b86c0b0131cf148a90b2b7900000000000000000000000000000000009a04c09c2a4fce22d237bbe930392dfbbe5c82d480abefbb3be876015e2f5889a0922df6d00d4e94be0e9fb8d2f4a1fd0bc405e3970dc2bbd7dfe0c54b7c64543fc241000adeef4f7aa2f1dd2506770000000000000000000000000000000002a6402848507062e5c5d63b1207a1a41d3b941d21792391f2feff95035f1b4625541770fa5e0f87585cfca670976533000000000000000000000000000000000904095ce640605c957715e378ed733ddf1f94d3beb63543a50c8922ab9f8092755fcc65e2a1ed9232c8cddcb5816371000000000000000000000000000000000ec62b911b08d3e8618880c3784685b2c6cbb07a4aa4e348ab72e4f918152622ddd7748bfcd79f35675cb956d11fcd650000000000000000000000000000000013f651e9104d48a081cef2ae0648816b2b4b5f644a791514e94a8e3dd3001099c27d1f9860337ced1b177b4ad7cd5866c36afa3c8581df069292d53b8ce3e35ca136a0b3f95a894958105fde9c77e39d0000000000000000000000000000000016334abef2a21b9c1926b2086075471bc2d2d2f66b963a41623af91fd2fd50f254c008fa3bad6b53658c2486edcc94aa000000000000000000000000000000001063002a5d17aab2bbb5da49e8bde63a1f3c4dcbc8800f9487f47c6d707109c86d3cf7f9171643418b195e50d7483af4000000000000000000000000000000001213004f31fdd0b0df5d8e3677c4f48624691e2534c02881c6cc6875b9abaee56ed5739c2acd66cb1b10553ba066ef1a000000000000000000000000000000000fb7659081cfcf8beaed9c1daf9e92702977c37a54376597d897082a25f9882f1ae14e7724c0aeb9e002dee708c6b4eb0f0a2bd678c5858be2a49ca54de8716fdeec84e1935b8f44545c740417efa7e400000000000000000000000000000000078f06bdfcbc7c0cc491fdc8069314c8a395983f9a2e5c2d1bec360f36e365da377885f897d8d711e33270e3ef9dc4d80000000000000000000000000000000007d43394d5175e020b3a5d768b60ec763d60cb1bb37c0343930fa82e92fb1becde0a178c4565df320824bdadd54ecabb0000000000000000000000000000000012f9fc96355721c35a6f5439065d89cfca5345622b3f38041b41c036b9bc6bcc980498ddc7bcf807e1b97831c099505300000000000000000000000000000000105307b482467b881a59eda1434e31dffdea531603fd3c460aa8d4f58d32668228bfa585bbba2dae7346141af59190e2c8e420db340ef2c1b5c6a71645e303eee95cd93228770b639287b14b6a5c59ba000000000000000000000000000000001576521fb3be8c3178549969e54bb17b0a3546ac4aacb470e935359e36bea4f43dacc06c151a527f441ab9616e07f7b90000000000000000000000000000000018dff940a21768ee9b9450fee7259663bb29af645bda2acb4d43f4e9d631e0127073f2db04293266e6fd6fd3d005e3f0000000000000000000000000000000000ca6a977016c1ebf52827a5ad52e5efcf7517ccc3ff40df8141f6335fb6c77c3fb8f6b0dcdba2596ded7c3838577e28000000000000000000000000000000000150cc33b55586fac30d316cad6580cee0a070900fe7d540167560b79f4cf9690a5e02cfce9946cf67a95dedc9a7d9aa35398541eb5a03271e2ab5ec2aeb2da80e634f63a050c25de98ad13e9d63d09bc", "Expected": "000000000000000000000000000000000adf84ea7681c442731be8db9508a050d4689c42af8f7472491655356a86fd9a0afd91435bdbaee98db3b1d8f26203fe00000000000000000000000000000000090a7dadc0a14df481e44e2005c9ddc6e026ce2afaba7badd18492bd3a338dffc349b4a339f56221eb795314252d53640000000000000000000000000000000007390fbc06077cd167f53a16f347eaf50ce8c9d111afeabf3a672687441b80e66a66ba3fdb28e2ca8282f3ae3dc81be80000000000000000000000000000000001998f98e85285a428a2860c22a00d0b317854da4190dcb4dcd182ac249e13c51f5d5df5db6a0fd61d01232cbcacd5a1", "Name": "matter_g2_multiexp_26", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c868a2cce65692f83eedbfeef6f9823ae9382fa5ed23395ff2444807e72403d4f6ac861ecd3a51db841889fe22a033700000000000000000000000000000000111c9aa53da85a63ce1870b963415f0d5f812e061aa6bff57425038d1b65fff57a78bdb963bf2450001525a93011a28e0000000000000000000000000000000011770810c16367d075c695981dfa69b072b82b034f8ac371f26bb157f9f9d667aa555a5c6baca69d08f421cd569faec2000000000000000000000000000000000df6146b29bc8226dccfc95a325d791b30cba8ff2495434d75622b170a634ec7995c5b4c689c73582ca861dd21d8e1e49f99387baca30b9cf63ad10c445daa142fcae1ab3c0a366a068bb5efc9abb3a9000000000000000000000000000000000fb30aac6502ecdd3544f1879bf1b3f4c19fb897de6c3a7cbf08f36244aa8e9dea8aaf781f7509d3ece16ca144a601e40000000000000000000000000000000012304be931a1d7440d67740f50b1a281468b412e8b6c54c62b993ec609012c7056fc7e62405c7530e8f5136cacb5926f00000000000000000000000000000000182320f5d9211c08f3ba5d40ccca45cb0060a6d362b4422084617b9d8212e94a9b878294ac176b8f0e959bc124a753310000000000000000000000000000000010be6678910072ed9f932ab01a2d72f7374a2cc82bbd86a6006a495272aa89fd655e6719ab8b3a0643d002021f7b7ebb4283a1773995bbc97a6df107082fed4ba40e2d30c5472a25a7643ca9e78b8b8b000000000000000000000000000000000f1ffed9514ee81e9b3fef4162c8f4980fe0429e57bbc224a9c9976cef7d26ab61ea7b0cd42eda30da97e3f8f5ab5f0600000000000000000000000000000000035b9b349b531d85361a4618a172b510dbc924df671b3fa707b474d0d8b17d30dc8ed208d66be91dcb7632d2f05ce31d00000000000000000000000000000000010030dcf6695d44ad3236032e47f7aa25b9f55869f5207e7ac8641db8c01f5b59627dd3442a1834b8b1fc595e47cdcb000000000000000000000000000000000f91ad5c923572a75d32962567e7b1b0eb84a91d485c968b5aebf8b3a772c2f94e47bc1d5b333fe43574308a78e768ac7f4202d670fc3b48eaa92e925f48821d2ae057d90c5f184edcce9ea900ab51a6000000000000000000000000000000000ae11c60537bbcfa46a08cbc219122ed66fd0d42f90e68243c32010eb99942554c349c021f0e3635bb50f7ca3d106a3f0000000000000000000000000000000019a61254aaa5b51b4d354f444706ebb0bc3edb87ec2d83e830ffe0282bcaa3278e947d053d6678549a098129bace43da000000000000000000000000000000001100f48a07456f01e16bcc833ae0a2835c964e9b0aa850574dfd8b4a7f06d03059e9b4df8931740ce0621ec7eb31218400000000000000000000000000000000003072392a824c386859735e2d203c9d52c19796ccf8538bda3b1436b2f6815bc86d05287f29fd0bb0569a81a57f0c22a76cd8d292a7053c449cb98f13cf768c6e37da9d702af28c16dceacfaf9cdef5000000000000000000000000000000000392760f98883f9cf6c0f0a324b9a645cbae12b780896f6a3eee918c44a815daed156248d6afb25901521b323f6baa240000000000000000000000000000000006375c6629f30b7a36785269d691772afe1b95d6e1bfaaba9459c31086c2697e4ce77d148fe2ea166cc330373583f4730000000000000000000000000000000000aa8e338df7eac5a7b070a69d3ed1553a0c52fcd894c2bc8d1b8cf6ed38983c6c392a9a045ffe8ff40b39d18e7c87c9000000000000000000000000000000000cbc73b589cba1bd47161282642fe6f51f2b3edcdcad6020bdaef369d3f2c11ea9cafb9a7fdccfb89bbbe13560d42d1d97b7bf8acdfbb148814afee1df79aea17261dad6f78772111a6dcb021d8c79d0000000000000000000000000000000000e71692cc2342d1e93e0ce72be69013023d012dd2294249dfd69e1d610e2236ee2cdef22446f1996bd3309825989930700000000000000000000000000000000013a1bbd3237dcbe44e05234f7e41982f4fd951d3741a3e90345418af1c922d35edf776a27bfbeaf7a15658db67164bc000000000000000000000000000000001197a2ee5c2541e19b5368c97abf51fde3dd0b922c3d701d7d84552c9f47b38ca09a8aef8240abfdcb03292ade1ff04c0000000000000000000000000000000010ca3c22ff8a47b1c683a58086ed9d831a5c25b6ce5a1971989974b4760cc9e83a1bc8d819825989751405b242eba379efdbd5953bc33bfba09fe7b3ee22c46c3a86f557e4b5f272853e67fd95a0f9b0000000000000000000000000000000001306f8047ba1a3417e7993bba0dfee9077eabfc275af91d0b882a53199874e0777d8dfd29767186d922d49087fff38b20000000000000000000000000000000005371b760380a6d287e129b329e735413447969eb9048def44f5c5987a64323d2a5c81484c40b20206832b86a4af9c4d000000000000000000000000000000001552eeae620c42d0bc4593d7c8e2c8fb4d6dbfcdde68d57158a7dfe837a1870a73b45a97b02abdea174a475a7061331400000000000000000000000000000000033a6dec61540a5cd5773b76847dc5016b309c5a027639598f51ae5b1067b3f7a02f5ea11b0e1be77a3ac236cba15c929a331bb218b99fd38451483a10e8add23c9641b975af3897670884efef90d4520000000000000000000000000000000012ad5ff49459fd3a7940a69e2a78919876e9b3a4f0c142499e7b5dbcadb5c2b5d79c5dea972f0f0acdfd10ac53bcdd92000000000000000000000000000000000ec1be9cb379bf1e24bd5429a4a91857bc3ad45095d15bc5537c2ba39407e9f2edc5fbf711ef4287a73ea466d4f53c3800000000000000000000000000000000173605df66aaf51810793db1cf2021de6a7645ae84a5d439ee035b917d037d9f9ff072b5dfe8b9ac69feab60fe2d70bb000000000000000000000000000000000d0bd336825381ae1e18ca37bf6160ae32b653ec9f9dad159006e92c24b661f22b5629ba323e9e06ccc5887a962ec23fe9301dc826bfe2988cf93c29ca9f01421b75ba63c5ed2cee1599122012ada36e000000000000000000000000000000000f5e593c6588add92cac2c9467247fc6d900f20b4d3216c258f88f3334eecaccbf3eacda227e2da46cf520e5102a9cdd000000000000000000000000000000000458177ad6c190222e53e054546413c13216286d414e3509b7dc794dc0704afd26bae93ff630c6157d05d46d805a04470000000000000000000000000000000015df8a7720d389e6112707e37694afac2f97282676a89964deabefddbb3a0f1cbc885d4c875b945b8303c1ed2c0f46b8000000000000000000000000000000000e3c7f1af7cf5923dccfc1d25bd86088706a3a44f5fa7f97171228e8f2a2b18e9631b2a63bd5a75ee0bb83fcc91a45c30a1cb530e8b828542fa4114de6aa936bd2be5ef3a9b7a0e20e475022381d62d40000000000000000000000000000000017823fc8a56e6e5cb9924037ad6ad1b43237894a877572dfe3d3cdc1120fe83e01de112b55f7f334dcb5c6247c210613000000000000000000000000000000000daa01f90cd14d82d4fc40b60b463089fc6c0e567fa46bae69184d0e3cc5acdb1d759e3291e2781fe0b65c734ddde28700000000000000000000000000000000164e742b123c19e52e2d7a6727689181f323990a3f3238072f7cfd7fc0f55b7be4274c0df194d85060a81f3744d3978b0000000000000000000000000000000007c03a1678b6e91c1bfc66ce8fd419cea13c7cda3213856ad21823b06db94538153a15d43a9d4270edf77b9a5ed490e6cf2f0c33bd044e8c4468b4b7e137ae294c178e7b6c9f19878331fb93220db2cb000000000000000000000000000000001865bc91e645e2e24c3efa3afab8b0e278dcf16b29831f75b3eef0b342479e997b9c5f8ccf67c789c830609b3cc425400000000000000000000000000000000018dda7857f919a6a49f6bb465c27342c8fab6afe6350c43b98e91a3105276f3ac27268454e9a9c6dafeb2218ddc7d3cc000000000000000000000000000000000b098258ff8b185a5c59b46150954d52db5a5f68bc7975234491406131e4f1286ce79156dd1290aafe688f936ad34e31000000000000000000000000000000000b294e9ce904fb9e243d0790147b6070b10ff611a06e3f639aacb744154d02016ac08f6769732d4f6944ce9257680d49e5f460dacc592bb947ff6f1c15b8464824aa5c957a645a763138ac1581ac5768000000000000000000000000000000000e541a22a7a36adc06e445f42497596e1017a1d99de85bb945a195cb3cf0c14d39eb7a2aa994cf234eed77f6307cf6410000000000000000000000000000000002de753e41a16565e5ab1b61debdad54950e9930e04badc6e356f10711d7688befc6827040356c0f0a8ce4f8d7121b3a000000000000000000000000000000000f2202e34ca164f1a6c0afbe179b714b303d87ef14534fe3f4230180f709dc63af17f04487264b3dee6b24ec4d0a423f00000000000000000000000000000000004044d9e3b3a77d6a309780c870a65e05e1ac531c5420f6ed0056f5e728e2b83a968ca90d579db50c2dd395f7e40beaf26a9736f728e16d7b8ce0cc59e2ccc848c181459fff4321982c08e9cac5794600000000000000000000000000000000166d7692fd30dcd06b9f01ba2101870ed347840509b3242f7cecf91fbed91abc24b08b08cc39c508e6499a2f8bc3637700000000000000000000000000000000076ce6dcbc77812b4d5b44a50edba5a082cc36dc24a5cc348283a4ce1518198b56134c9807ef850edc9e36e9a282b9ff000000000000000000000000000000001261d9412245abd7ba3fc1597f34179e54766c49306725d42588545e14f4e450ee1c7af913ad7225275c57680c23aa6300000000000000000000000000000000096602b4eee053998555ce522c060d5e04c7961eeaab0145d38c9b13362624f54fcc8d0b77f2bbaf8c312a3279f06e4eccf0a9be4775d65bbfc894f8ca66fa6f69d4249ea7f6b076fe193f2805e64f940000000000000000000000000000000012be34c18145aac51a1494f4052edbeff14c2812ff494cb78198cd7d9db9e951aea80490c55c4ed926f6a96a2c337c880000000000000000000000000000000000536e46a63ec5ac0f2f4eaaad6df98322c6a981cf2fc8ef253269cef20a76ba1ad089c24cba4ad4680dc4192d66595d0000000000000000000000000000000005363b9acb66ee95713b63dad076529805c0dd8921c738e205e7b1d0410a3ecca0870aeb2e64cf45270d49b473371ddd0000000000000000000000000000000016749b2b09d889b883b6fdaf518345d4cf097a728b833e92c4d21b5c41c8d5cfc0758e895b60ad101a74bbb6be6ca0c5fc6bfb37cbfb10a1ffdfcb91d9a52883cb9a606f4ffa8849a6e07386dc9bb34000000000000000000000000000000000067a684b55fdeea39a29252b355700a4810f083909cf2c07a80b362ac1b4d58f5900c68d266f7ad81ea278c0931bc1ec0000000000000000000000000000000001b1f78d194d77cfb4a2116ce9e29438dbf38c52733b0295198159d7cadb2584d86a75c24aedeb36234a0becf9d38a870000000000000000000000000000000011fced2244cd959872a25c0c7bb4af6151d99e1aac079c606db4987b9ba111261d4a16e7d82362b865324824445a946f0000000000000000000000000000000002659e7016ad615ed80ea1ae020903431b470bc0341f8e0918de9b8d2e933dd9f2d9123e9e9d20bfb05d49f71c3c454cd94959e16f6d780628694075ba5aa1a476d89d8fffcf4b4ab7e6343c011fee920000000000000000000000000000000008f3c5de8c94a98dc5ad7846c53980384f997d1657f7349ad9b51376d41f4b21861d212fb6428bcf2347d8774f44156d00000000000000000000000000000000110b245b1e788da41dcbf60a3ac4987c1925696dfca85d450107f654fa1230adb9436d60c9e742dfb4e453ec4944c56c0000000000000000000000000000000011043b975e01df36a36307ba9234a18b97aadb9da509513b13e4f3c80432b0cc5e69a3bbb3cbab8df41bbcc92cdbf60200000000000000000000000000000000120aebda10c52a67d23842e2bd9a897cf38c58fcd11e4e8c5614db5e409a7c03111feebfe2f1212ae753497dc59d6ae9122f3a5e940ee7e5038421619daffb8a6f433605f37e78d863f814b51b2ec4e2", "Expected": "00000000000000000000000000000000021067690e6e001e3d0d01449a7257348c4ef68e66dd47b9014d7687d44749be1f33e6be95df6a204169ab7103dc2d3c00000000000000000000000000000000062efa0c36462ab0734128dab5da8635705bd1e1b540817c5805ed9417f176723eea92425db539e8763b1c79b9923e9700000000000000000000000000000000176c9af1970f026bcfa87e6f85a20ed498c28c6982e21bc050cdc29c0f0af832ed4424082e4862d985b78519cfa75b820000000000000000000000000000000018718b0d0fbdf4783cd0b01524ab153b891fbf08cad60241a3f3163d2c3496c36afdc6de62ab3c9a037f88ee408ce5f6", "Name": "matter_g2_multiexp_27", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018adf92d8da050c76118a3a3b2ee43955ae8b14ddc8ed64f5672f40de475f7e0ba6ff60c4b6ca3e863d7914e6de2cc330000000000000000000000000000000013d1e19011a1ea90389480d14fa608985d895e05edd9c28fb34646f70fd7bdb7857fa785b1e3c8a2997da6c3b5337ccf0000000000000000000000000000000015764827d9838c2b011660230ef9805af388fd997cc229c939bc5f4213d517dd837328c45b0b8ee1d6508cb70629b7bb000000000000000000000000000000000d58fa30a2d095ee8d946e50a027ac4cfdd557b3fd9c82dbf1536ddc0f42491a176ecbdb026306e6ebf1bb182a4e8199b3908c739d505a1d6fa85a6dfb7a155202710b45861f1a8a7ac7bb3274a180cb000000000000000000000000000000000cacfc8d0bc6f9db737c8a316043a6b52fd5946937467afc09ddd14e509a89f2445065ac8a8c56454d529d67793edb0400000000000000000000000000000000148b1b941f159d93170fed949d5f53bdd2603d78a49443ac0e2353130ff914376e018c3db3d12b807d105f2d50eded8c000000000000000000000000000000001382a3e98cfd072807214479900a8602bd666cac7f19be0443ba1354bfc05666f40384e9ccac314b5d0a2bec1c90ef0c000000000000000000000000000000000c12c2222f67a5adba78f2c0be5be95ed743e835857f4204cf47b67fa2eac45cd5985fd82c7a3904944e7b84737374b17e0e27a8a416eb38c989a66b84f037a5a24ef3358e20cd553f037a0a2461d31000000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e0a3cbab01c34856b892aacdabe63d0a0c241ebc137a88c83ad22cf38997b211b00000000000000000000000000000000137b12f731ec925dc51e20a9c90323d14e1497e16b3a4b5651135054ef0e58e9b18167da15220b9a4f7d81e9a7648fc20000000000000000000000000000000000b2d3ac534e1e5b2c9ff4092c2d8dc5efd99121de7df953e5426eb33934ef07e41b196eca50f5a04a936881a05f2b2a0000000000000000000000000000000004feae2377d950717695606844a4873ed7b5f6703d7a63dc8b960b99b68efbba710c2db0f1371acbee314875b97ca054000000000000000000000000000000000f49ce3061e7254dc1bc8af3636a05e098cb96d81fb31e25da97c6266adf3c41a74d46ff32f4fbdb4cb7e4a3f69e827bb386bebe0e49b7f07b0ac61b15306c2515a1ad6fd76a1825dd29a60e845c0e4a00000000000000000000000000000000064ae3fd67250f2c6332e1e149ec09946147e12e0d871403e559b49aab68190a1454b3ae924727b6dcf6e1ab327c9d7c000000000000000000000000000000001131f91c7a0e1854bba3958b36083c27904cfbdb8b8cb3fe68cf578bd1cb6f7c6eff91d98e4b99086926c5d4272cc1f200000000000000000000000000000000071c6a92a8d460ff72d172c204c8a69d6b6752b8c1f731ec63f7f394c0c3a2a1bc15e865172f693f523c11cd4ab1f88e000000000000000000000000000000001193876df7f4a1cc9b337a41c9faebac2f209b9070bd75294c2a88d3091a1e55b51fad482fd2aee8f90458eeb7e981fb8902a82d33993a10c56b2fa3333cabf1c5d47a9c78354d58f70ce4807cf2062800000000000000000000000000000000025c20ed5572dd1c9a098f241d2965d8739878ddc57c017632afcf6e54964894adbd6d30f62f316c9c3ec7a08268afc70000000000000000000000000000000013bc3e930f4fd5766db8f04e1ebfaab2b67f620119c39d687c68619b3564f3e8b74666c9f8bed6c1f080a9e23e9c0f22000000000000000000000000000000000973a3cf19312f90843f1f013b05484064032557807ca67b2ded4a27fdac12d6cd0e1416c8998cc8635ce10046adfbb900000000000000000000000000000000108903617c78fc608eaf007aa13861c970557f2693b24e8a278920897be9694570ae6e6c7749c3eab84d5fa3af5164b1426a4e2317fee033a226a91a52a5830f9ac2cf5f329feb6bdb382438b8a39f2a0000000000000000000000000000000005695975c140fa14998e5916268bde2135cda80a45414fa85193fd6e13c6b5a6486898f590d76175d8ec2629c923e33600000000000000000000000000000000033f58b1cf67e51e9ad817b31919530cfdb5db5ca4a537d9b006b63399da49b2a5077bf5c3b3b4fb10b2478f466542540000000000000000000000000000000015c532e40ec04d9143e308895b2e7e3d3daee093a5840e1e76ab528fcfa5be57d9796ffd58ad5ab7df6f88aaf34706f2000000000000000000000000000000000b55747d1e8b66e2b2fea67229f2b7b17d58ef547ca841bea8db5b53fafaa18390f11b8170c41a5dd29331917fa2e348de0390c05fb0dc9b4a3f76b51cf952a11b909ce13f9abc9fed6a349b8efa98ad00000000000000000000000000000000001ee5ebf73bb40a5c0822350853bb5aeead3262380dc274faba6b04e58e7fb9d5a4ace109ffa5011e73e3d89ee6fd77000000000000000000000000000000001427659e5ab1f8b47edddd27c613b578890d4c66c835c0cf8e8daf19d0ae842f0bba5bc83ed7248adcd75cea5d222a270000000000000000000000000000000001d4560185690ac05e56c2d629d599bceee3ed2919c29e3d1ac54e80ae99b5eb2f93bab865e8c1eef7206f96b2bf4eb20000000000000000000000000000000016ecd3589e3703e5b0ef53790130d5074d2bc0fd5839d9c6ff905746a77e393f73edf53b98b99d9c87a1fee1086aa8657431db9e576643f93505b5b25836218759e736c0d650a5221a652338b0073eb600000000000000000000000000000000163850016261f34de2b831a0a8dd3f224adaa3cc279cdb40e0ae976bbf736dec26c55a6c79cb1c623870b62ea216274b000000000000000000000000000000000a79af5c054cd08608d4be1705058ef7b4ec38a8727560d960f0325d0ef915c049a89e76956d0296bcb6c96333c3470c000000000000000000000000000000000ca89379e558c7308edd25bf06dc05db857204e9351299ab66bf050c8f051341a6c15a02864c679f07373038de3fe87c000000000000000000000000000000001929f42ee5d9dbfd1f6656f61e6243ebf0eb491762b7f3608db3f3e9abf565ab1524f770cd2ade334885d7479342c92c6745a32591e359efa41e9ea93a016d2eedf1da112cddbf31818e8d687b36af2e00000000000000000000000000000000193b6cf7300e47ecd21a05a71b13a8de45418d3f67931789ce6111b8633b9f44063ca13ba8c8a598ee0725caaa3f277a0000000000000000000000000000000016884d982e2ec0fa7e59fb34ae8708d0bf4abfc260837ef4432e8e04474e504b85450db8af8e6809413c90268801fb3b000000000000000000000000000000000fb48a8331f278845979beb8cd21060355566af215ba44029455a03d0c016daf0f6b7c5773d1a99e893e76b4411a53c70000000000000000000000000000000007056e30143058eaea89a3065e1de768d49860b170d4c364a28d38475f90711fba62c1787adda90dd2d347da72680f4eed37a5f4bfca6b77ff9e4f7e03bfed52ecf02a8f84ed3da6da2787a4ee81ad9b000000000000000000000000000000000501fa9af88e28d4f0c0590a2624239bf1724ac7174b0f1d5fd7527cff1de9971d6aaf28ba4005e88e181daffee6b20f0000000000000000000000000000000007af5e30b5aa9ad206645ace12cb2b36cc1c6068e604184ca8bfaac5a4ca327f7c43a74d43417918da7df84e3bffd282000000000000000000000000000000000bfc0538d52f277d54749ed0b69697b4c60ef0c5483d21dda76533e15efedc9e2b2ef07618457d64bae8ef922c0b41f600000000000000000000000000000000048935cd352e999bffa613e3be0a9f9a063d5b5eb46cb5056e41ba214e87f871f216ff41ee297aaaf2994a7b6433f58d81633dd6e729bc17ddc596cb1f17dc6f0e50c052a0b8c5a4c83900d918a9eb560000000000000000000000000000000016ab1e8b6f41891e0b65f14397c0887b27ff27e7463333e0938a7a1a181dec603056afbefdb23b41bbfb2c05807289b8000000000000000000000000000000000980d0ea9ad5c87bbe1aefb708061f85faae1e1e3b01c55bd577631e5bea2b5ffaf5e2478f5a8df89447fb8a73559729000000000000000000000000000000000784d0c5fa243bf0125cb2c83a4040715197e99d507d71a3bd9ca396074cfda652c1ad0dd95c3cfae369e68d3431ee7c000000000000000000000000000000000e533bb33e6d269dfdeedf7d17c3e0c19f694d151e8eef801c326cbcbc463a42558f58cbc330bdff0d8d91e2974eb4cfc6b019d29219b57404baa955f66cf1b2ee6571ad5b80d471ff6db569e32a1a5000000000000000000000000000000000050f005b00f371a7308b5d7d7f67f7c00bf15acc518942607f32686feab5eb503391f964eb7ca711aa6c7b4e494d7eba000000000000000000000000000000000e2ee5092170ea3da0b1397023b2386c65ec8b090484353f2e5d64694aaeb8d5410ae22c92662fcfa21566d70173ef36000000000000000000000000000000001549723160fc7b8f5ef9a84bd1803f18b76698aa7a663d9c107c9ff6c6d02894edc80fd00d436f3a942c05593c5464ad000000000000000000000000000000001032f49e3527cc1f1355c65edb21220c6afc88919ff67ba99c65645cd3b8ca6662dd0146f6a90d92558b3f54815a361d6a76411ce02b4dfc84ddf62ed26508a2dfa5edb5a98a6a20dd69e8b8e7ad2f5900000000000000000000000000000000170b317e49f1304570a3a3e6bef78fcf8537a451ebcfef5afe3eac4aa1aa87dbf95d0f870fd3372d37efc9e663621cf7000000000000000000000000000000000269ae0677d71b2537078e96d2593482e4d41b6d1d2cbec755f307735faaf79c01fa27f1103cdfae1a9bdcb665f592c9000000000000000000000000000000000b115d5a9fb9fd9361d0573a8d68c5193f02edc1cf3fecf004c6603f118f28ff394220f6a9e1051a5d9d4b417290b7f800000000000000000000000000000000107b45614b18c2513f8c42a0032cf0f3f300157b39d2969ef7b126f17a9b5e8e9ecc5a61a2ed4db92134b0797f6a0ea35906098e4ad7e4eb2e996075c7cd660fbc399bc942f9080404b9d0758c4ae14c0000000000000000000000000000000003de39b056f8f0248b138437db1536b7bfee29af00c37fcd14c25c88f0f051eaa07c763d94c8ce497696311736c0b7140000000000000000000000000000000002b52981e828f8dc1cd371e6821d001e1f96d57a865a3c0a255298c43d52741b18fc60903d1a5ef6227061dcb243096c0000000000000000000000000000000016b5335f0f9516f52f2ed45fe723ded427206ba96af0879958f1f22795485b2867e953de3d9b3a9eed2c37f26838e1540000000000000000000000000000000004c860058c7ea2e6e4eb2a65c1dfc20b3070f89ff58ab99bb51a4eb9e7f0642f7b32d1d9f27c668a36a9e053a8d585f394ef8c281a9be3766fe784ae017d93f608dc2cb97cbb7dd3e3814b5ade845d370000000000000000000000000000000019cbbc125ca1b89330c21ef5b42fe0dc1e795271ce4a9ecabff04eec9029f756f180520f0e7b84be2e9fa4af395536ab000000000000000000000000000000001630cf0c4f3282689a3e01b5c8f9be3803f60238bbe9fecbb0d9e8e49f4ec9f6123c44840acb8cf55f8f6bd15579e6830000000000000000000000000000000012afb848bc0ade8f0c25c6c342bb651a7481be065a48944bbedbc14c095af8a4a048fd1e776126e2128f904afbcb17ff000000000000000000000000000000000dbc984f9ff907ce5553bb11a458deaaee0efea49d6816ed7abf1dee7b70cb18cc669d4808e75678bb898359c7ebedbe6feced33019b3b66d335f2118cd22b2952cdf9757fb3a0cff55b7c4f245fb438", "Expected": "000000000000000000000000000000000be6dee62b8c85e36a216d16c5477a7c58f03b992277af83d9b53b3b2169414b72bcb4a97e3667482e888738ff17c94900000000000000000000000000000000067337c69c37ef6f0ae59fddb84c46a2afe7fe047ddb57b3b80437609f1a21fa5a73420fa5b44704ca1cac6c7a99d9320000000000000000000000000000000017fe6f37d2410159e533374ff3812714dcd07610d75a53a5d502cf2f51e750c48858db1e109f6aaf724292c1402382f1000000000000000000000000000000000b8ecfe1f5f5d95777b0fe5d94fe81b82656e6e5a62b7591788baccd251d93e4bbc6857cc87cfe6b4ed470c33631ae22", "Name": "matter_g2_multiexp_28", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000126d4a9ae3550e31185aac9011e3f086517cf79a279326c264f51bee6615dbcc730d78055489b5602e91b08f96d23882000000000000000000000000000000000aeff5fc04fd06c26af8b048fb2d0d493525ba5c2bde30664e7371812d529ec7dbd584c056b05fe02179b7eefbbc45fe0000000000000000000000000000000017c6538d2801947cbb646d4ec8b70b1e24453f7a984db7ba73e3a5dcf595bdbad9703f2d846ab02491e5e3a5bcee0762000000000000000000000000000000000badf551dbedcefbe7c303a5c8a52151b5460caa22004028893af4d8a3fac30cb1da1e986f9124acd5db7a634657dbd0cb5e7df372d346fd13faa90b0d6961372ce2f32ec379e5e50e7ed8a13942cd9d000000000000000000000000000000000bed71c7d878e7ecccd8233e3e604e564cba0b1ce75f726f846f3a6e2f3b4f5b12a28b8638be647f5c33226edc2bc7fe000000000000000000000000000000001914c20aabaf1f6f82063223053809622ad82a3a54668bd600db1aafba22aeee5c8a07584e263c91cb0fc5fb809da63d00000000000000000000000000000000056d9cd8f79a90d16b36bde77e546f8b3064ba7dd0fde78d6bc538bd6ce12a4f32860205d5d396bab3d70deaaaccf9450000000000000000000000000000000012f7e420708b66132157a80753678de292998cb6c4f00244d3c47a6077b3401132b73c7f52369aa2a6a90892f7be4ed913a5fa1674c20c97d08608d200f3f7611010e6a25a790853ed4ba0c5aacf111b000000000000000000000000000000000339aa1471eddee8cc0a4e4db5a29c3e4e92cfbabe023995a79624614aca522cd459dfacc0cab346b1cedac347e1df100000000000000000000000000000000016cc4ee8cb72fe09e65616fbe9bea1a0077114ca841ae335f1f9eb5a0b129a4bdc77cc6dae8727d74fe21f0d870a43f2000000000000000000000000000000000098a21da6e983228ebbed0ec3704c9d2521e935506c0567e3bbf9b9c379ce6d33c3d0dd8f5e013b431f740964db634b000000000000000000000000000000000a7a38abe8e282544ec6c8740dce8559fd264393d0a5c9af9813b2430bdb92b3150eacb6732b9cc278d0d0e622b263ecace10870acf190b373c19ce615e20e5cb96d3c6be3ec155f2b29825f8476b7740000000000000000000000000000000019ed305bfe8d8bfcc20794832b3c117715b6a658c0bfeb629e5989f265cbb456e857e53d168932589e4ed2806db7c4b4000000000000000000000000000000000e2ffda25fc316a38f556b35a7a3acb1a2bfbc1f9469a1b6427ed1f216e113a379932b0547f5370be1017a1fa0266cfa000000000000000000000000000000000ebc493c9a79b8ba58f48b90b9d287c74f505dcb484eabda79ada987d63a4df04d671d4c4ae4b32f8ad5db6a1b80f37f0000000000000000000000000000000019fc715d26c0c7a0c291ad8319e2e8f2920c63b4d4ed3f0e2f376aeddd4f7bd9269175ac8d0f421b001e2e48634f3f238d9e38d9383f09cf0f8a8077f1d1dba091ff0abdf7e77c3b65c2df48d6c6f536000000000000000000000000000000001285ff533da833a3daae7d815b1b86feb6f20b7592af8b0eb76240f390ea48b69a75547b040e7282b71779f450d3510c000000000000000000000000000000000813d38fa21c1f3c87b9c97ac03e6aeb8fa23e0340a0dff4e3892c774595648743d0b8980a7bd21648ce9b16a245ac3400000000000000000000000000000000020a69dbfb736c64e4cbc800aa415729b24ec05e901f2c7ba38e49a21c3851dc03bd4f7ec829d4326fe6c13867069a07000000000000000000000000000000000d518f3944053c8f74c0aea1d054d89106312880de4479b3dfb45b00945ff8bb58b12f9a489fa9fcd87194a71475d0a1abeffecf9b404c6bb2e2d0c78fbb8609a38e3d3187587c3848e8f9781b7e9f440000000000000000000000000000000018c82052cd483eee7aaa421c2b998ab0b4b32326dadba03c1d923726697d3940b40d5109ba34de09439e833ebc19daca000000000000000000000000000000000e4feddc3eeb3fd1eff8316d5b0cba554714713e8a605a55909889970ea2c8c58bb6c568024709def73b29a5a76563c100000000000000000000000000000000098da4cd0281a16e2e3e542ebb92269c8208a3d373394b0af92dc8a2676f9f0b6e85fda9161e32558e0569cfc7b1f3df000000000000000000000000000000000b7b54b51821fc037f02167d2e640f8dbfd1472407278b4bdf47b958da39f28c64569c3199846c293bf60e86aa45f205adfe53846c0038203d8b8df0cb636aec7d4ed7f78b0b0c1734be448bace08f340000000000000000000000000000000003058abd4e3d49c86ffac9c95b1f07b66a22c42654dc4a2e3b07b87c22024a8bb0ee084a558ac22cc9fa286861fd77ff000000000000000000000000000000000fc9a89ee26c323df22add487a6bb278ca3f4c9a91eba4e067d5abc9dd3afededb4f98263e10083cc7ea224f28d3bbe100000000000000000000000000000000058eb015f1e14da860215d59165e12feb8d1317f652eeb76b3f08b38ed943c94e632dbf8145233dc93755e44e027553e0000000000000000000000000000000010897d5c2b481f9937d830b333e7649931e801a6bbffb7d9a3ee28ab1e27889691a9f0b9616a8437c3cda942bf07282206e9d4e41b628be51690b86aa8938db066c052f3adff774d35eee1e332312d3f0000000000000000000000000000000013b88963296d8c8197cafe160846ee11365b7a991b35cf5613dc57714aa48307f4dd9c6ff9704b29905c18a41a48010e0000000000000000000000000000000016a97fff65fca5ff282a818deb8100104308b8d9dfacddcae32fc2b6082331b44fa70580018930fe1ab9d9c1b13a59a20000000000000000000000000000000019cd2038acd84c2db1f0fa1b7eccc5f7ae3da803cb72c4a1e8390d49e0adff1d88a85696d9daaebce9c6b8a2f861fb36000000000000000000000000000000001271338587f06847770c72dfb3d9a657d05f8c7a012bec77a7d40a98cb1637ae99281c82668486119608b01feb25e6dab3d349b1546a8c235d60c41408c969a0fd42425f8b5ddc1fa5102d2821bde2c600000000000000000000000000000000173ed7c70f4683102cc6a276d192a8f3b189197d5ea5dc813c7d0162a1649e906f76a1c9a1cb1ace6e4d937934b72338000000000000000000000000000000000936d260b789b1a2a9d04388caab364049395be61d320aef66ce50f052eb462faaa2017731518675bb0e4a2f050e4f7900000000000000000000000000000000070bd1254cf4b209ecb40afe248f2e53c390636625460439952ca2977be021d93fbec264c31ced2a810e8a5e54d750230000000000000000000000000000000016ddc3312f8ed359792bd213d086a0ff1540e3e5a2dedf6c450fb96a9b6d1edff9bde31fbc04de382cf44694a631178229b83950e79750e9827ed92856e4d1e1b5f0b47c6bbf3611a1fef8f2fc47659c000000000000000000000000000000000aa4bc6e1a3e6c3c45a29db74b27af27b61856e2cf385ce0e5094ad53db4d31c4af45b5b234c66a21bf15018c13ece8000000000000000000000000000000000188affc993bf6c99103029c1e406bb1a693e4f1dc650907809ba3de1471d41095dc1866578962c72538ca85d09fcd22d000000000000000000000000000000000e487a7151916694b980e62b64ba49ffc54aaccfa0b0fbc5c14fa4a50d1bfda55698df5cd8570c07030f145c49a4ba9000000000000000000000000000000000084a05dced107d29a0fd4cf817ab67017ca33018d5c7302167d08c64c45c5c455fb5c907f21c39b8a86d037a126df4e76b5ac07fb4a184dfed685b93d2265cebd02a3296a3b0416cc6a115242079752e000000000000000000000000000000000ea7060a07dacd84287007a05b494bf19a03e5a759b0ba67624c54cac3562c0ca3fa6e444206614d00d6d6684b86bcb5000000000000000000000000000000000eb2f332f4481276f931d2192c1a9f6d7585e85f248a8ac95aed398cb61bda05230bf8b9c041c6f78be3b34668a9c1a0000000000000000000000000000000000faa038219f844e379d8cce55cb8f0fe2b55548a0a0e1e37e25ba4f432e6b1a6451b8f081c171490bf055f81cbfe5f8600000000000000000000000000000000037c70d4e8befff257c4bc98a4726a961f3e2e68e7e02f9f2c94aa8f5fc67a1da44d41394dfe376a6c04240e4cd5825f3a7a25ad9f02bf51fd73550ccde12374d9b151f2f6fe535bfaa43efc391f789700000000000000000000000000000000100a24d21c0ddb20d76b6d9fe642da5ac1de28afd642ab5c08574206b8b64d1fd822d295476bbdf2ca7e9267138034dd0000000000000000000000000000000000aa7e4f2f77acfe8b4c8f3fabd56b17415ee9bb182bca1db15c399479ec60382f980067b9d4c4ef7556d621259ae9110000000000000000000000000000000012f7a7f91a988fa661c661013736f0ec92b40f571ac15a47067bb847b09ba128d1dcaf8049b941a51cacece5db4e1eb40000000000000000000000000000000007528b0ea66b6ab8d5d318f5e4d1c0e9a4f504057dbb0397b614a1adb160032127f2ac35a1a98da70f023cd343a35ffd47944c8c814f143f746175ba0b2d75e2ae73730a265d869763f0e986c088bfcd0000000000000000000000000000000015d72b8d4e71cc092c2875de80f3d12e003804d980a4b1dd13cff34e9336397c4533b6ae3a03beb2f09312a605947a270000000000000000000000000000000005976027a98f7b0caf4cc7d0d71440d3e4fffb1ff65fbf32dc890b275b646f2a32600a6215d6b2f999eaec8e58cb6d5c00000000000000000000000000000000111583b7734be53a7d4d090486070cd3d9622156c52871ec79c83ca024880684eada56a36b58cfc3490e65de41e10579000000000000000000000000000000000fb670b553c2ed4c81962b149efd4b0c77edf6ee70eba88300cf264dda98190e550540fb9fb95748599bca3abadd752030f33b187df3516866f259ff959d57fa9c53323d5c851fdabb96e5ea470518ac0000000000000000000000000000000003900e7cc0a8e891dc4dfc45f08d97e73ccbe2021a560a92c493aacd9c0614ad100294b5d7ebd634ffe4e5ea301a26170000000000000000000000000000000011ccc136127189728a7036e85d233fd150d5483963c48074f9d8ff83a0791c950da380e717f2bd0bff8fc115e9e886290000000000000000000000000000000007d3e76bd1f22679d228b4ee50a60cf1bd1fdaa171372cfa34bf4136a091abf7e5ef3c6b3446fd41d5de68b563fc7ff3000000000000000000000000000000001107f636d9187155357bea75c943dafcfba2394a9300054026b46d6f9db31eacc06d1f64c2b139af297dc4783026d98f4da8401050f30459e026a207ca631f0684a10813c64ee86dbdf06b7b29cd9786000000000000000000000000000000000e3a4101f6af3cf0d5d5aa5a0ebc26852dc69f91c06e96c5f1c7f8e4528c3dd92cb6f629620136ec356f0657fd9ebc6a0000000000000000000000000000000008d34dc3e1fa8bc22258e23b504d442a11938370325c101f1cfa52f313724e0894be722646195fd078c1a49720cde8c900000000000000000000000000000000163730996c79787e7ab89030de2c26e26188187762fa128ba4378a398ebd906dc56d99cf228591f394396248665c196600000000000000000000000000000000008f0a8b3d003b6727834228798950fb7a3cb6b931bced4540693445a007b474f7459ede17f87158e932e4c9c094ab904d940555d48649f30026f70450b2caf2b8f7148b28bfd4349458ae89c323512e000000000000000000000000000000000cc2d30f7d3869abfc34719f40b0ddaf00f52bcee7ec09a16de51785d55531fa7fe3ca1544d7103b9caf7105d60d9e930000000000000000000000000000000002ebd8af0bd3f82dc9dca585feaa83071534b2bc2b3d2aadbe0d01d759ade77ecec3b3f7b72f82087365a14dc205add80000000000000000000000000000000011aa3734a4b9168d3c46944cd726bcb203b94b25a97437a6aaace9c84da708bb073ee10585f28bc41e0601567863c193000000000000000000000000000000000ceb4ae5a8b506d31e77e2a43f3af8ba9459b887a927ca5287edbc2ba7c7cbba85a6e4d35c099b7ec7bf7eb2814cc38ae140e30424d2cccc91be1fd3a62d9ee49c9d64fa062d9350b3fa567ec21bb06b", "Expected": "00000000000000000000000000000000192eb406b52075513584ae3c6093fb534270d716c79961d0a3c4bbc44096a2e8d28228363e2c8da54857945f1b983569000000000000000000000000000000000ee0d95748b13b531821ddd71a15fc529a2ce2c99a66f14e28f97478c3c2d524cb7c4cd7e71a1027030765554b8f50f7000000000000000000000000000000000610ab3e064532ce261aa2ba4f78721ac4f78661cc13fa09ccc279267e6f703f1bda17265a5eccb0061ce24d31e000ec000000000000000000000000000000001966a334b16e64e4dbd66119af97bd2b8d6afec0eb1b8207f437c00ab134ff369b3b3c1bf51b871a7fe8ad1ce93dca4e", "Name": "matter_g2_multiexp_29", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004c22bd94b82ed3b106532a58a0253daf51f579b9d746c624bbc6b58603942eb139c1b576241ca8fab5bf1c457112bd80000000000000000000000000000000010c6f7551d758d1128add57b110227296e060074e4cb934132368f079a794770ff406fc7717867df0f461f5c9fe56960000000000000000000000000000000000048f88afaf6eee5039b76c0c5b4b49671f6fd04f38bdee1b1c8f347a9dd4e6aef387b742c8f9a8aa387ab4d01fe4267000000000000000000000000000000000e7be987d0411dd7138e47ac00f9f07c4737d93aac501edd16362ea5a633c9071a6bf542d4db540d75edecdedc3a8f0ca57b2c351a7946a20cbae1fd789ecc5f77376b09e911749831e9b5680185b15300000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae8fbff9f8ac4ad10718d46a857ba28f182263bf2d13c8b6a00902af737dea56160000000000000000000000000000000003e33b840426a6bbe15b23fceba829bda9a5ab89d37e60133874f61bf1b10e05d460bb5d228cb178cfae2a5f41035d32000000000000000000000000000000000a9c5460c6443364d9f9440d101d92a0037343789ca0aab6dffcc2bf81e1aed312299a21556d16e55b1398334d9061f00000000000000000000000000000000015db251708253f7de13a5eeae5aa76fec415ecee1ffd88d882580da5da8d9f96c6ff90d920b329096a103dd71e7cfa580000000000000000000000000000000014c3a004cb6ab8465e05d965dc720b37084d98de424b160062f225dd0b67a8e62ae11a3c7bacaa129a568f3a243357ebb061de16f4f609c6947733b58c6444fa9549721fd9a2459652e8e4b8c69b5d61000000000000000000000000000000000c8fecac8bee21d916cc47b96a66b7a522ef4fea76fcc86ec490ff44b46fc01ac0446e3885e36ae7ab62a409ccffcca60000000000000000000000000000000011676ccef54bb27ab7db0b5ec025a9d1f29217030f3686e71564fa011d9fb598f44a8bed3da8fa7fcd10d01e3f66d86500000000000000000000000000000000093aecb91956215980854c6f19120777983a160e16026560c8076bdc4372f53065f9fee0f5830ea192aa5637590a745100000000000000000000000000000000035d773ef15d8d99b600a6a575eefd661aacb49d6540639223a454594570d0f00ba37340b63a2c8a0d4e53ee7dc2dd91355ed5b57b28451ad98fbacd5ae87551b7304e4ef5cf7b7dc443a66432406f9a0000000000000000000000000000000007b2891e9cea2a464742c7f962deb1566c9d4f9e4e7cbee1912a72c5b064211c39801bf42bd888bc239e6b4ba71d700300000000000000000000000000000000169cf5e706dff2945145d5ac14bd5fc8f7e7c3e5f7ce733c865e1882d236926c71853efbea26e13efe4eb0d0e7ed5db6000000000000000000000000000000000de9ee19c4bc2fac36debd4c91317e54f57e761866b134ba9a0e84a8d268b11674110ee8f91aa8a6b80eabee2e5e75ae0000000000000000000000000000000016d91408a670e4ee43ab8e21cc341596709113950d22bdf5073cd90f520667699e94f64f76290f1bebfecfd80a9e051430b6eeb01874ff4b0fb07dc9f23d8e45455c1480eba7fb3033942214e85a7720000000000000000000000000000000001982744a15e8163a6f2ee681bf27a68996682216037d67d91993fbbe040e16ea21a9cb600fc6a40e7289185393544c3f000000000000000000000000000000001131d7dd5a5b96ac1f4c4aa210afe7af8d371cc16d32289aad38c93afcc1d3be53716f82e9d14ce6b1c833f7f5871ad00000000000000000000000000000000009adedaf19fb8823ec55b803c9509ad98217730bfc6424c8b69a071e99d026492e7c8c4a06509491a3bbe5893988c357000000000000000000000000000000000cc60733a783c7df76541daddef2245e6d2b694b94649b13c21aaffdce124c1cec3fd8ed5a5d4d4eff3115ac933e5df989a697a0e8d2cf512edd2a3c3df354eb30a3eaf697779dd9270234b367c2b5ff000000000000000000000000000000000b366a80247a8e3797f1c711aebd60c99ec7caffda34514a3716154e900f2387c46f87f81af036a383e3f9234bd1b50e0000000000000000000000000000000004608b7cea13d08724a2cac691e61255ea7472537f7ff59894d511af7fd99ad72f0a7406271576300a7d1d56aea17bdb00000000000000000000000000000000141abedc914d3d1ed587162acbfddde60f7dbc1ee5e07fdb5f3515b87d1a29024c9e19f24e4c0e3979bd938aa4e798270000000000000000000000000000000010e72c6c0510495dd2c4ecaf13c1c6404654e1be369d1ca485c76d8c2304d60d69b90c2e171f18bf55668232e747825820b72463d54ac1d8f1b3f56f0f98861768b05d5174cf1883dd8eb0410420d56200000000000000000000000000000000081d5a229481fd297363e8e217bf1f94a00f54eb6e8a3f95f4de30081bb2b9edd82d53cf287e37b459afabcb73fea1d1000000000000000000000000000000000ab55f52ff7dc578ae8267fe3fa09bdb8174dc30bb835cab9851dbee7a1aeba82e83e07d5e79aafb34643d9fc9a0d1c100000000000000000000000000000000195245c7a762776bc1e81d7111e3b814088f1e0e7d686c3ee3e500cd0a7ad4015851563a1b8b592e491e00078187c66e000000000000000000000000000000001850c1e8edb0d6dab973a9975833cffee8b5243654bc4ebe64972e423799283707f9ad343bfa86548cd2acbe04ede5da3de7997113708f9d092836c2b0b59abf710d8401baea6de73ee0689436f035fe00000000000000000000000000000000000007e9191fa9057cd7df8fb83d497ad774735c242bce9bd34cfd21d3f8f2a8e37d1f38b592a61ac8a8d22a4287fc5b0000000000000000000000000000000010e36db1460fa65ea229402f558397c6fc57e9c8a4b0b9e85d9ba938196bfeffc951587353cb7c7d84479f60c087e3660000000000000000000000000000000004d86938bebb850fea82acd336c3900b241757dd937f831dd909ce548325955f103dd57611c0b75bf71412a6ac3d6ed30000000000000000000000000000000013990c82583007b693c1d6271c1e5820d7274c4a729da21a76eccbf7abab1f2bdd6c5d26e78d51476ecf154e4fecd1b87fc3d0560432dbb721f8a0610f0db31dfdfea8cd5ebe8da3fe3b8ac5358dd4400000000000000000000000000000000009104610d5887fb7cf6a866584cae30cfeb00e1241083b017ccb82ddc9d72fdc0d2b1d227c22ff6d8497495f44828efc0000000000000000000000000000000002235f959b071f21fd63282fdbb46b1dec27cc193f3e9988def691c73dddd789b6a1adb977a68e2661fb41d62280f229000000000000000000000000000000000ccd46984208f183f0b70c9152c01fdb8ac078ad1d85f41e3a24819da321d9dd9321a8d70103282abe6d8b981447f202000000000000000000000000000000001711057042a54ca76b0c3e7f36f2fd49e339b76cbd2e053d93ec2838848d359865fdbbeb9e75e408b4b316d60ce2741ef0b271f02031a126f8632e30d8b17cc5b57de7b8b873e0971ff392d4246a40f400000000000000000000000000000000001481684941fea0f66c78faa40aeb4b5254bf78c44df7e37b191c095ff12fc94248acf01d2aac5637e9536e73a82c9f0000000000000000000000000000000016b72eff2830f49b24b1e1317c95143cda8bc11b9dc4a91ff22a24e0bc1a244c7215ab1040fcfbc292ab236ac73cbd3d0000000000000000000000000000000013535421771fdad616171f7348cdf32bea7486bf4d836b8b95c69b71ea9915c099e256287aa119af53cf6320ad86664f0000000000000000000000000000000019ba0f36dc556fcf09f0a4a6cee53de485d03d846af7afb792d16220551fb5a42a4261f936b008babc096e6f8f68b63af8b5c136aa5e2d670edcfb5bee9ff6095d85a332ad55763fe1e5e8babd145c070000000000000000000000000000000014b2da0add872d6e61253d6022559f668bf192b4aafe0acfbbf341ada55b404d42b2b31182c1ad50c73673494ea5b7d40000000000000000000000000000000018b76b74e9e6cda8466a354ff66baeb935b5645cf9eca81f4b7342f7914c9bf35c57be402458c09781e66a89cba6e67e0000000000000000000000000000000019bc8c1f32ce934b7ccae6d8ca39a263939585d8f94414c3880fc7bb5a0a27d728708e7ebc42c5a935f769adcfc083f6000000000000000000000000000000001636b62bbbe34bec06253887b78ad5b3ccda1bc5d8baafe450f2d1a8e07334ca79a40c5c4a50b58aaed96408749e6f68285193e7c10646a4601787edfad3d76e19d5b013a0a954873d92bd5293d325820000000000000000000000000000000013c0fd7a8441b6eb2dabfe8c152aa480015f81139c46440741f3da1c50d18c17526c47e8b8c2fbcfaefabbad5f8a0b000000000000000000000000000000000009da839802e7c6759a87eeae5a05146e1d226dd828d4ef6d908b4a0431008f352539f3abcd3e4c532a3d8204e350a8510000000000000000000000000000000014709634973e4554d2379e439d099e9be8bc7ef031b6ea36a7a85d2ff5090b0e0de7cc1c6b6a004465edcf868ef5fd5b00000000000000000000000000000000146779393d82bde1eaa6205e69907a0536c782fa7fc6e11e5e62ad5468f4422b3688f2ff4da2af396741ca5e0f97de3835bb2175fff61894ccbb69d90375df627e925f1ac430a349e75580dd39546e44000000000000000000000000000000000ddb7d0380370830803a7eda2e9b694af71381990f182b5d1223992abb5afe9531bbef8b9dba239f411fc422210fdc930000000000000000000000000000000018b685009d012d72193043d09f8968f9a41ce2fed598a20536fe54cb26db1733214add38f73148e754e632f6d78f524d000000000000000000000000000000000b967a7b4ed1bcd9f3da16584b08e0c28d967cebe7a07069abfb3bbce94d26b6d95d8a807879b24fb1f5ea00091d6dc300000000000000000000000000000000039349785fdb7d38707d8136e9a8f650c4491c50d7425388b75fe30da56147992c3d662f22131ba7173b2550e613477fa25856e5fb9547c48d41783bf2cd13493a1fd71e56b9c7e62af84a1f6cdae1c8000000000000000000000000000000000455d7799cc1c2af1e219b23e8683113fec126bad1dd7a441c5d113b064b552ccb1e7314dfed1b11f42a18acace706e50000000000000000000000000000000014d2400aa3e2270714b656bd755c4bba55866d6e313f619e10f94de6d82b5343ae9a9483dc10c1a72a5a21e619a20a8b000000000000000000000000000000000a6caa6cf8609d23b7873c908e5321d064a9c107b5492d296d04f92c308ee705229dfecb1f908bca0024ca56bc125126000000000000000000000000000000000b31c384423c84316f65e03ba9e01a8f626236f76e4df4b8ce2fa053c1c1e6a9b8f0afbc253db8c9c5e2ce9f9dcf05c71155c0b9c4185025310e8020eb52abb6f2f1780da15e4ba81f3c9a88ed1b4a6400000000000000000000000000000000097938bb53db8d0aeca3f2bc180039a5dc5269748e9cf065cd88e59b30733d527e54cdfa224e9690581e8c7f0881241b0000000000000000000000000000000002d52d97d4dd415fb18348f4de78c65e2933fc45d5e5e1d8f0f0ca1cd52885704ab12609b91d6d2d1ce13eecc7fa0c2d0000000000000000000000000000000018b926a37a8e0ad836846d06c03a9b84db795fdfe5f15d1fd3e0f8fef1b2825b29ee3a503ffb2f75765cca49c2b3d4cd00000000000000000000000000000000073bac093e958a3a09543e060c81b35b6598521a8685629f77200cdc73b372588e66c247097e7c03492c0943bfac4d6bc5610b2707ce84ce67e82d5c0e5f5cd2c90925aefc1e39468ca86475012df045", "Expected": "000000000000000000000000000000000f79110c74f0e983f3d3618869af1d9b96dadba61f1d596294ef8a9412f946fa26cf63483528a57299dae48f85ada81e000000000000000000000000000000000e1a9cea3af1debcf7d6ef6f7b8566b5bb52d5548d4caf85925109228d7c9b50d65a1b24f089631e75a694f8e8dcaf040000000000000000000000000000000010efc1081f079e841eaa5a65cd7c945d4f37acc92c4ace9ae6c69a9a95d8cf569d604376b1c7e63558d022da90d269fd0000000000000000000000000000000010b7f55ffac8d57c89b664c36c20b2988a493de32f5a956c91b16ff67cb806298a59adcde12ead42d598b6ca3e1b94da", "Name": "matter_g2_multiexp_30", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b139e5dddd53433362c49403838b3e2ecdd850a8df12d4dfacc0bb98f79d40966d62dfd0da1e721e7c0f298457d590000000000000000000000000000000000fa35e9c2e37bee1020ed99516174408ba2cf443fed115fe3a964ed86b5e5369e40291dbfbab477e339003ac85eb7405000000000000000000000000000000000e8fb87794860237066ed1b7ae7c2a783c48c52c2267f3e7295d1f17598b96232954e1eb6d6e80e716628f1db8afe48600000000000000000000000000000000083521e3a6d6e3f99570b747498520db5c89092b0077519c8421f9f41772c7a6e177c9cdca52f89a26c6036cadfafa8b32fac970e52778cc90396a5ba92ab98e26499eb1ff17d4bc4c1f78b64887d3f1000000000000000000000000000000000b1415e1dc2d4c1f5619b40e616d258867493d8624857e41d007f82ba8dc53f7ebb36d06f8348b94eedb794899e97df80000000000000000000000000000000001c01656fa47d62b4372361b80ea61501cfda47da5534e3e2aaa27b1e3c4de0bee0aa322e60c476fd4345340e5c00e130000000000000000000000000000000010caa407d9d265721d55f01dcfca52bde851ebd918e8fc4c752a41875940709c64599f36fae5e3ac7f211e1f67890d1c000000000000000000000000000000000b54a86474dd5f410290e4b4ac738fbba5e88c6debec17e38a52090b17ef371dc8feb0573e76c4b61d7688547a89f6a36583bac9672a77f2fe62bea4364aacf62d5e10eb3a757fa0595a81f76543e8630000000000000000000000000000000001649c78147fefa91100738e50034424244d22d8e1bb6a2bf471e4c9b29694a5c9476f4b129912bb09fece53aa87deeb00000000000000000000000000000000117a3e040c1f54b96c2435891a45fb9dd95774b5a55cfb306c22517e4ea72172332d893047f7eaa665fcc58dd21781f400000000000000000000000000000000105e8d80d46e6bab2bb9ce0525cbfc82e8b3320ee4a8b9c0086e21cf2b5895cb35abffedd1b5a9eef21f62a0a1dc48e8000000000000000000000000000000001437ee33abadc8ef6bfeca16c3edcf05480c3dd97db06e396e10d5180472f50074f43f9a031a04dcd11d803462fefadc5a8e1d77c9e42a187054c938a8a5b4bafa834021b727036ed3941b1c1deb9d030000000000000000000000000000000003b51b10efb54dbc2973e001f0bb634e36f689264484eb128de2882d6600a43ad548bc7d1def4541f0ed88a1fb37f3270000000000000000000000000000000009dd80dbfe6663ab04656856f192002593df9ef7f792dfa81f6a51c658c4c9ce5586a5edaffefd507f51ccb7e8c8101500000000000000000000000000000000144160d5ca6b2ad626e6a3424ff5139adadd3319940afa9bff7dc409ac1fc3775d5413ef4612b27fd22c02c1fe57bb86000000000000000000000000000000000e375ff490a626dd1d933a5c751c88cbd61803986fa8dc089ccbdeaa0a922758afbcdc30d29268fe0a34b7b79d0f76c139c02150e4e89b25563985c7802c0c43d00c721d521b54e767c1f509f584bf2b000000000000000000000000000000000997ade20fe9c0d3eb79e61a66a5c272d02af668b0f3c8201a1ea071737f3d2ee3b0764f859480e95be75ab8845b407f0000000000000000000000000000000003215194b6a363d31ece09b18700479e6093fa3472a23ef0133e3dce60a3d56b6fa984b900162c4ad56a6899aacf35c3000000000000000000000000000000001647647bbc399f40124c43510469cf613732d0919e22b478b2603d7553927584cd4b3a407e3ec6387c4a93e9e5373178000000000000000000000000000000000bacc8afdd70e927e21521b3f62264ad4f22adbc872439ff851d3d169a1c79a0d02bca2aabaa0b9941ab1c71d092fac12196ec0e9d2f572856217521fcc5e2869f16d5ec5fe76f7d350698f55ff0c565000000000000000000000000000000000b0c5981bf6ef5b85bbc504fb0196ba442fe87302346688165aa7df8cf2642548760e11daf5b3fe2e37b43379afbfd4a000000000000000000000000000000001086828b9560aaee5e28bcb50db8153c40e632b18c61ed4105bb7f472b6a69ddd8a2836f6605102931ee66b2f07e441f000000000000000000000000000000000f4d7aa3d1a281af6f8afb3d886774f4e4a64490232f63dbe16e3b8c4f626e9d07f7c668d09cadab3c92d6fe852427af000000000000000000000000000000000d92ea3318779b532cd81c9be44b1abb179a8411319a6f8fbd7e3f158bc970917d3e0b25f3f3f6c8e0764011f9bab0398df5017c9c35604f061a7095d976d08bb3570ef8fb518cb606cd39a3060157ab0000000000000000000000000000000000dbd83910f304d0fb2b6d8619c3a308c719f6454a357d9ced03b2882a50692c06cda7f4331f54eb293ed5aa079121fb00000000000000000000000000000000019c33ec829367dfd2610ccef9842ffaa5e4f35809657c22134fb09b024e07949d8370ba8ba1e9149060e9bd3babc19c000000000000000000000000000000000ac468b42925d2daacb8574d40064d393caa643f08767d20e72ac0fad1447a64d8743523312f3a91a118d3e51e1f52d7000000000000000000000000000000000202d1971fef2938cfd10bef5900b91cc4811939f66f1f5578a8ae0eacb2538d2a51c1e025449e1637b5173ab7fa3b6f7b82e7e565f8a521d1a9d0ecafc029f76b70042e1ec36c20e3789b49c7e50ef00000000000000000000000000000000008b6709123b9bd501360fa463dd08076c59177dc0e8035c49fa2f541eef3831e4c584c5a9410c68999dddda6c86fd9d5000000000000000000000000000000000fb94eb34355c636dca909cfa71f52471217b9bc241cd3e98907d4a5c7eb67d5bc9cdb0c73c1369d7950a014fe6069fc0000000000000000000000000000000002e2ee515a5dc96a664bb1f862f21a8d3b7f903fb87f6dac41c3541f3d83633f351ba8dc4661607d24b912dd1ab097da0000000000000000000000000000000008bee545e00e3fc283185a85511e09fd0253e191f52d5c0b440b10228041800c013db3c9322a835e4927c0ae0b21bc1e8260c1b7a249ba215f0dc127a41876f858b20f4422140bb7695c8f98e4c474d00000000000000000000000000000000006ba635e74538748c29aa7c5690a0530f2b1970554598a432d4ea6d2713a4d26786b6e80f67b2f39e218b19323654ea200000000000000000000000000000000133ca9e5e0d4a8200d3522d8e87dec3c72edc1cf16b7305af4abd466aa7a0e30159388d34c36ea030450ef45b7940ec20000000000000000000000000000000004724239afc773688ea92296bae8845f20793c05807a18d6f35f03bef295da06f8ac9dff438b720dbea7ea93f3ea9c4500000000000000000000000000000000149c12922fd69e1960274a8b91384e929fb354936c020911495e6e3c49faf16899ec0c6e87713ee2f0149bf808ac8abfcd68d2b074d038ee0d9887168dc16805ed55df26329a4c0e062c2124a6e5066700000000000000000000000000000000148a4fe6ca67b6c785d5d8a784d5e68fcd2bd08294ca37f296b6426433b805507b554eb9f0fadfa9d293e8cdb8547d4c0000000000000000000000000000000003700600c2b7bfea54801ac95ff7a2c069bace31ceadab2947a0641462089fb43f0b9697acc005a23007a923ffe97360000000000000000000000000000000001705a769ce3c9a7a91283e4068c602d85808980d6fb457345a5f9b2499ff8fb3ec8383049b9b7cae96bd2ac6106a07fd00000000000000000000000000000000052b1f4e8a48a5eb2b2580614c656393819b4f0ffea874be899e4964c7e32d54757f2d48ca7b50e47e8bf6d6ab8ee7572a40c2e796148ed1c539b0584b90cb386844fdcde5d3766cbfb1d1b58626fcd10000000000000000000000000000000012ff8ba50d587765e68f95d276e364c8c40c00b55abc929f9ec240985269eb096dd3cef5826cf6269ecf54bc67773510000000000000000000000000000000000959492d74cb34c8c9ca4a21ddee97df99c8a6e627db3ef72200f39e0402d56f0a9709596189c80aa3aa50793e0f1a68000000000000000000000000000000000f7e5dbe884597054d6dc5e80bf4d0d333025bddebc1fdb1d61482cf15bcb4c8a95ea29cdd0925b5b816cc0bb307387200000000000000000000000000000000194e940c041d71f43ffaa51fbb31eb63c23559069b42dbf8777f35eddf14edbc3f7762c7b354174a584507ad714948234a1e176fb26983e549aefff9aeb220f50e071222073422dc2c44abd85528ee2800000000000000000000000000000000101a8e54d1fc2357df60b0ef8872b729295218f29ff63f7a7b6a70b3ecdbfc6809eaa8dc1f62a664b9987e8e86154c6c0000000000000000000000000000000015b5ddd012b42e1a600d738e05b551d91e7fcf3cb36018ceda9b689b92022224990c11a6fa0b421d5610b7e59b7463c30000000000000000000000000000000016130be17fceab55387d43179cd943c85ce1ff1881c07c937b2cc0645ec9ebaf0e10718ec7fe0d720f49bed2b8caf15b0000000000000000000000000000000017d73650680856bc11619e6acc139e137f0a06476f5f8979b5ba7fb8123d85916915da60d1f2e8c84197eef518b350c2a62e07bb97ca3805ba2d30f39f44e70a7b2917889c26b84bac8f9739bdf764090000000000000000000000000000000007d26bf37a97d532ec93a3eac00d9d39b064ecd172ebd5e18228b1601eb7a2c272aff9d88d63781b4a587c2c8582eec4000000000000000000000000000000000108000e850bfbfb02d7acef97592e15ca721334eb51197511b0eb2bd3bb647fc8f07713487b0a0bedbafb106992de4b000000000000000000000000000000001868c0b2ba732731f7536851f8005e8bae7b16545b39190251eb2bf93dedbf0803a42ec24cebd151998b690c38c0346c0000000000000000000000000000000016faafe909a1f926333b12f5463231a71058aec31d73893687d3169c4c3588436f6178447eed307b642490199c507d63a14278fe7a08174660c08323de272b2110047a1d1d8bd0e3c7d76dde030e00a6000000000000000000000000000000000331338cbaeb8e304fbb9257bb80aff5d3e043d07dbc476dec2795347e4c25248caad06ad14f56183d2b6276c49ff98700000000000000000000000000000000167e9578304a1162de73914b02791468e14faa2e0f161aa57818b8a169b5933dfcab787ec0f4b23737011163dcaa02750000000000000000000000000000000010aadfd5cc781e73c31f2fb64e7981b2e28614aa18dc7b2d96d2bb4ed8c2ee9089d6ebe0cf85479b272cb049e934739900000000000000000000000000000000128d7ea54f338064cd2f041f42a1a1e77d8b9be4ee55f568786a36f87f965d8142207e518798061eb3e32fe3b0f1541d1f516ab5b36a59e6300a54d17363ffebba35fa0c64cadb21e541af5078545b400000000000000000000000000000000004539f22654b3182d4fda5ab8d4bce6f1268d4e402b6c29a4cdff3b5abe0618d33db55ccd1ff12b27b2cb0196ac53e0600000000000000000000000000000000177e80ab6aa8512cc9e4d65b06b2bd76e33bef9038cdc1ab97fbb9d896ae2ad884ea16407490653dbe972b14e9c30c0b000000000000000000000000000000000c280a4431e41df6515979a694ce292f220278178f7f36e23c8a4cb2b8a7ebc520901ebe34c72a26b2c8a60aa1a155100000000000000000000000000000000006a0b80538a6c8093f3655905af1c59c235567d22192758c28dad1b715045189a412e4c1edc26e1d8ac95a584277709b3bcdb23f9568e409271b5f907fd64b0cd81939a52a6db38fd8d95de76213f7b5000000000000000000000000000000000eb091007672a212dc4937b314576963d7561657cf1103820ce9bc34e4d46c24f4891a4a4ada648f8cdd2c30f670b86200000000000000000000000000000000166389a37e6e3c02317d68d54f29cc98d1d1df5853940555161d71df791cd92c483eaad87dc0e765b12408d6ac344f31000000000000000000000000000000000affd0d5734cbc27b192c0c0e464db48d3d76799d2c6a493b172127ef2df6ea18a33898828effeeaceb7a203e35ca41800000000000000000000000000000000155708b9756752c9b44048c91d71970fd2cf2a4cae6b0baec00629c81387c8261150e78f856093d81e816be6403f1ee91b716b02b3e94600867e019be166f4532d264e0aa65d723dc0e117aded59245d", "Expected": "0000000000000000000000000000000007ceeb14945414d96088a7900c1120ff182b2a93b09943c2fd1dc2b0b223f684b0d4c0b1b5803502582f2daf16d81d2d0000000000000000000000000000000008df450fb25534fdc456a8f41cc143a84729ccb082aaa2243c8f37e34a6670f5195750f8547444c49f7a898aa8567d980000000000000000000000000000000008c12d360078d5645b0e095c90d4fd37eb20f0ebbc6fa93fa5beda7e7c78eecc06e0d839268e2c303422ab1769402e0b0000000000000000000000000000000002bd594a21153d7c458b9f804050d05caf2d90bbf9d18def79eb8148b7f89e3a3ac21f84b87fd13c39df5b91cf73460d", "Name": "matter_g2_multiexp_31", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65bcfdf0495e49dbb8a8f9a0dc517351f39a6d823dcd42715f329dc78400bd74fc00000000000000000000000000000000090b834a587521729426d5b134c6058bf7999f4d4bcc0812e8d8b3ebb050961321b5e93356e87171a6f12160749394ee000000000000000000000000000000000cd5148c7eeac4aaea4288b38a02b5a901a6e2805e2b1695ed98ed86cfa0d259d87b65bf3cc9d00b8548100a60a371d200000000000000000000000000000000026db1079b85411dea0b9fca383956af50b938a465f35347605c01f3b72b297630ee2fb5252da20ee0d8ba5071974ed70000000000000000000000000000000012ae26c193e02d7ae4a7a01181551085dec9fbcac811c45d5cef19abf736ca2514e1259811970af5913891abe22a75ecf095238bcee61ec1317c0f98ad4f8f9b39c5940cf37a8a3a676787d9dda99438000000000000000000000000000000000ed5d8a609aa4f3c65a89b8dbc9334bd3cec6c7763bff298acd6c260e4d3bec0088e15c5d82618571d13b74a2031eff1000000000000000000000000000000000c28f92f018e6f822912b6eccfab37432ab0ab9acab751f848401791bd2f16e32ac6d97948bd8a0bed2ddc1917f0db3b0000000000000000000000000000000014083be2539d914883172cdc70950512dfe7be8893b1ecf085d837c2e9ba7f03656c5a0e15373e04d300869620eb66d00000000000000000000000000000000002561b77cc2658c54d29f8d1988dd7448f59c80c02ee9256404d8ef5536ee50104cbc11b6ee1ab9ccbf0ca55e53c52aae45a6d64cac817cd479a501c77b6720c6777c6026dbee471b490fee9f242a6700000000000000000000000000000000000fff05aea33a9d1e8f7b227c80ae87c9e7589ba2804904b7d8386b24b0e5324e718f29531251969a972870a30c310630000000000000000000000000000000016ecb8f27a369df13e122c981e7ae37882b36d5492fccbc86d606aa1198f3e4ee7bb7ad0555e11949e6c1783d8f4cda100000000000000000000000000000000187f425b675cb12719a01ee3b78ea73d88f70805f72d6cabef6372ccb9d99008bdd7da54f155454c4c59f041deec86f800000000000000000000000000000000151c272d5cb67b3f801e103ee901deb4b3d3bef76ee4e1b2ce1b5e663ed292845ba012c732d38f9209f82e77f1f73cf354868215022673de608cb43a3cb74ef2073ffff34c54fbb43f19b22a02bcc2ad000000000000000000000000000000001791bd59815309f2aeb7b07df8afd89a288eb6f19c7e613f394353ac5398267e1388c97b17d83104446e57f94581a79c00000000000000000000000000000000154cc72ada5a9c99dea06ebec143a14271cf332b57c631725ab30e2d308d6b688ca08a79efb6fce632cb1216ac3d077e0000000000000000000000000000000012b4c6fe8c17274ef57539563a736c2f83c4cb473e9d075a976e18e193255057340f45de373c7d6e3fe5e08ad0dd97d20000000000000000000000000000000005aef16e11bd4e7787bd5ab4427276ecdf9c6c134b9fdb2ec39e87ae4a5b3b674b5ceee29bcdf804ebd7e83960d8d7ef7068c3ba82e52fce0223a9f28c1d42681c7863c94797d1786c1adbc3e6d10dbb0000000000000000000000000000000008e57f905fa202c7640500746b590791cf9d0f160a77e5eaa5a30280e513e8e801c4b6b04cc3f80d9403388571d180ba000000000000000000000000000000000da3c128ae234bc27824062832ac10aa9cd4978f37855a8b4cde3822f5b485fddb9a475a9805e795519d7f138a8199cf0000000000000000000000000000000000ec11b7e07710161fc557a56e04337f71aaa1a0f070cd84525965e53a1fe445c91ac07c618ec349997890ae893c165d000000000000000000000000000000000406b0eafbb8782d11f5dae2f6214282252af9ae9ebc5c17a81d4ddded40f05d0b534d14019bcb6cf4e49c4c182b90f00042b8005283c7b91ef4b3ff7e20a91349c8c3d1301c9b54b901e8348a7d186e000000000000000000000000000000000b1d456e66671dfa72ef3a56523eb939146226111fdbbeb697983928aebd5f50b0518db841a3d48912a7a780785c1f180000000000000000000000000000000007a15b2253496b78d270dd55b80bff90583a95283a89d40f6df71fadce56d103f0d365fe79256fa4f93b2d2bf4c06a2e0000000000000000000000000000000010829223166d38fd2c3041dd5643c9784da366a2ea8cbb3abdffb5fe43e975318c86de0ac9ec77c0126ee75bd209f7300000000000000000000000000000000004b124018e83e1e5e77bad42eb831798d450f8ff4a79c9b14f67f080047c491fbba45db79b2cf6015188f9fa6329e8be0a3eb64ce8fe140d94956b0685f91a5462dba1a90093e803dc617559a66d20da0000000000000000000000000000000011119be42b90c7857079a51695dd5be08e59374b0d1c7e12d0ffe870202e1f0c62bff84c9691679a82e610e788b7b5e1000000000000000000000000000000000c7a64524c5dd1bf10d16da7f15b39d05c9ee1620d4dcae79c60316a1f522b238e7934d1be897a441d0c8e621b67d44c0000000000000000000000000000000013045613a090d05d07310865d977c8e0bb1caa713b2249d6676e7cfd6f4e3ba8e667deabf9fdf7fd527685f7d251b178000000000000000000000000000000000dfee7f8259701b5726b6439a7ce77b92245499906502c7dfb384e29cafea61f3b1f21fcd7888231569ebf29d3035a61ec88ed0eac8d0f2f618530e91cdb9ea36b8d56c1001a6792a09e11ff65fc02aa0000000000000000000000000000000006d77669207bb2d064824cb56fc786c631936d30db630be3c08e18d7e95b1c26e2d4e7b2eddc2f946fba6e99acb2198a00000000000000000000000000000000168bd8f291f8bcdf8b5e9fa915f7f24856a62803bbbeb9bc38384149008d4e3129338035061631f1fbaceeccfaeef4a700000000000000000000000000000000146bf2dedc262557dec2b4545c94a37434e20e4900b1693e8fa9bda9a94dbd07e0a3bee5f3bedfa42148791f4951db7500000000000000000000000000000000138467700fd5088c76af2f77fea4b746f98701fc0578571997b0ac2fc343354ddc8b2dc57d5298dd4daf767573d8bd3d5f03e53ff983fe4886a3dfc03a353fb77927d7a0d1998a1c55ca7421a4bdac6f000000000000000000000000000000001536da0df7c91687339fc93608eb404c5f46adf4b9122b99b1e5cee0012e27ddf30934d8f669bd39091f8673aa3b3c490000000000000000000000000000000002deaa8f9349e7c551e39751b1454a00f8f7896d63110e8e42607e8023ae3070c4abc9885ed54ee37a82f6e5c68451e900000000000000000000000000000000079a62eb17f7b07d4117956d3dab5d16a7f90e98948d5c3caa124fcf755c73f060a90d002cf880f5246a87342717b4dd0000000000000000000000000000000001246f0f3ec2af7c0250ae14cc67b5a1d42309f06c6f47b89178ff7534c47e8413a26a43f27454c0f946c66634563d41cc1b04dc356bd348211ccc4c50d12cb382660a4f9526539c2a0c52b021ed216500000000000000000000000000000000046e4a08785de985c66c7417f9262d363b9acee07e250999a4a7124f101ec4d82e3e4b2b0d9736471329fd61d0cff13b0000000000000000000000000000000017bf1e20ac181780ced62a18c78b378fc0dad157cf30d6026680560b681f5755183bd30b4e454764c08edb93297590b5000000000000000000000000000000000a57cbe93254bb0796eafc0a57330e38bfca37f8b94c4d21ba656e5616239e1e18ba6d632c0129d30291736fe37a4ac90000000000000000000000000000000007f31df7dbe9abe15f4024d8f6bed93c92ff5bfbd7835e08e870eb1bc4a6f62b3809b922c6d5a7350e2e5a978c80a67397b584ee05c27d45390aba36772ed49d571837567e95f1fd3ba3fc1ba5916727000000000000000000000000000000001577abdf6e915c9c3b3fa50a4601709cd629397f2f91784528e4cdbb140065fc2a6ee3830983dcfd49a928e78cf530aa000000000000000000000000000000000d6f98df9e41009837cbb05bc3e3340d38e56a448fe396bd48acf03f061e7489d1402b36a84b3c56eb859437e9c406f1000000000000000000000000000000001912afae5361c3d8c6141755deeef26d1fadf6b0036b9d05b2e0c4d50f42328741f0423ac772fc66dbc922bd4a837ac40000000000000000000000000000000000616661f049b5c784ba05334b2931509e1e033bd203fe17f04cfe12e80e73eb7075beac9d379fc1c457bea1b6adf365752542cd551cafc5d50852526ba0a23d274317e1e4a6e75c0d19319e5853b8b6000000000000000000000000000000000f98fed7e4d67a513c746d2fb188597a605165d5d299072aad6d621e077845f93804d575a5796bfa726f529dbd90e014000000000000000000000000000000000adb2d0b6c02e4e8fcab11c7c8819e87f73aab673ff9dbc5c50fee751bc7a6a8d386c8f9fa830b5545f94a73ce6e1f1f000000000000000000000000000000000f08e05ac40655cf59ee3ea9f10fc900315c6f06ffd3b80853560559f580ecdd65aba5ba660c729e0bb9576eee3703710000000000000000000000000000000009da46469f4b8fcd8d2b016e96f6e6582fb01c75407c36c7f87b4a1cd8f08ad06e962a0ec2138ed6fabaa1cb0115f97e2f76a0fa585828f79553fbf3baac6a2776b782de66dedd6b734f9342e734ee3000000000000000000000000000000000047b45ad2ad4f7b5b72194f98b98b2150b5d73a9df2aeb2377beed9a1275a882fa2d849037ddb56af632489f892a48a7000000000000000000000000000000000e1b0d9b52c0c5324067857ba4701f5f20eec165be418871fc0f0adbc3a0bbdce5a33277a33b79013109b81e006c621400000000000000000000000000000000179c471e01e340d8e6fc0f737ec09f0180bd2dd2a86d0817f753d1e9a9f8cb18178e9de68c596dc6a824e6c3c151d8b80000000000000000000000000000000019405c1e571a9b200ff2949aa74647dae59d92a8669d4876ba23f1b4a12a1f9412412503c68acbd619cae3ff056bd346f638e6a70917c89811851109296a7225f9c7c5b3d7fe6d6ba6c7d1ee77db4458000000000000000000000000000000000ca8566b9bd088c471fd33fb7b1bf760ee12cc8b0cfa9ad92b45012cafef5c0772d9bd3bd9b266d6c3e3890c8f00057300000000000000000000000000000000055789839e786ecee7fb7d10f3876359fcc1bd6f2c5cf25c8337aff7fdeec9b43ffbe932cc4936bb708571a59e4339990000000000000000000000000000000013cf827bd57d8179d105f34c147665a072714ccbc114aa4e878d04ce66ca78bdabdc4867b3968c75dead147257197c6a0000000000000000000000000000000014a8dc5ac1858442ca627eaa194e1ba64091b5f9ace551338d770c92fb49ee12449dc200c8c35d70f9e0652b4d9b90da1c4ac944341dc68fee586d221db2a8167e833f18f012afa7c3844def6dfb26bc000000000000000000000000000000001124ea2b97a6d73c81387a51e814b9bdc951a773db2a32d50691be60f1d397cd4aadd9b06e4f49c32b12254e9f824fe80000000000000000000000000000000014cb365e9780feeeff3548f34a56548302ae0dc73402c40317fc819969ee9c4ea2a181381b94f82dd97a236671b456a000000000000000000000000000000000064b769c4b785d45472038aeeebd3ba9b28b3132d72023640ab2d7512cc6e31296c5330be5653ad6902e4e15e57e2c3e0000000000000000000000000000000014c7bfb1f142d69c17f73e23011aee0063a97a99d982d25ff72791a65c7a68941a80fc216cea8a49f3df2d0748b1f95db0eedaee9347b10ab7b346fbc16c10cc9db486f561f88b756c269ebbba23a7f4", "Expected": "000000000000000000000000000000000fb1227806c750e0eec0b865daaaf51afb74a88589d1c035c60dc1913f05c8ab18de24903ea876fda27b97a5eaa2fd7c0000000000000000000000000000000019903e1341f0285658164f9273b5c958060bf836264502b9dc298f75d4104d7a43b8d5dc0bb934a506ce1273ba839d830000000000000000000000000000000006e791347b54057195189e8b9f10fd42d170f37d455c0af5e92cc6a12e2c23990253be6855f4be6c84a708852c19a6f90000000000000000000000000000000005b72c361dca430fb2414b9d5a326cef8b77cfe5310153d6994dc1f8b9e74e8fbb43079e21956f428ed8aa48d6897e32", "Name": "matter_g2_multiexp_32", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000052acff88605f33a0cf1201e8101c95ca0befd443c087265821a7d954917a026d41ab24d29bdfd972bb52ff4ad6de14c000000000000000000000000000000000e134b2aac3f6270e43afd994302426796b1e362031638fe0263c0ec212b828a30d8321af34ef7bf260652150cf2293b000000000000000000000000000000000d6628f675008099e9a75e1294803e86417ab22670d36316798680289ae61a26821693f2f9efc8468721a1097c3bceb20000000000000000000000000000000006d66ffad1a2e0f39488fd3f6e0214c9407528c8bfb8d1ebe6d75596a3e3cc844d00fdf46ce7ff6cd6d67732874a24a484adc8cfd2e42abc2f0e0d7e9c4b378f73731905760bfeeef01c94f8d5c3cacd000000000000000000000000000000001160bf0f7f2915cfc64e12a5a91b7e2aac78d4c2ce362e7677dd0e9c0172b37fd1b52222a13c65819b87593ee32a9ba6000000000000000000000000000000000c8be2cbbd302b31b1ab6dcbeb57b4ad428447bca9159fdfd007f5375218d121673a010f2c7fdf83fb45883458fb068e000000000000000000000000000000000363d3d492e6e6901756bac13b5c32d55aabbedde878115aa41b57d27b49a0f017a61fc90b13a20e009989374b82f5dd0000000000000000000000000000000009302fc26e6d750ff9441d7471903cc296b320128de71f86c4eacc80ce0725e8eea6acd2af056abde2f61e0a349f9bb5bbd5d4a15998d733326ce23cced86ec5d5b410c29ee98a4de19f2662c3933dd1000000000000000000000000000000000b12aca17efc103cad500b3d773e43cb24df6be651963c0f30bca489f1dd7911ffc7204fcaa4511e161c6f75da4a5ff600000000000000000000000000000000179a36e9292d3f78a5fecbec1175f001bd4ac0ff3610f596aacdba29a12ea4844885a7c465e66d3883c7fc99d4a7e06a0000000000000000000000000000000016bfd0758b31f54f90eb8562bb693c45a92a297a3d302279c9e3cb8263efc0f31579a3af8e8f5a091d9a6a36776f445d00000000000000000000000000000000020f6c66fa554a5cb610ab05d194e7583e6798a113b8fff336c986f7358bb9fa6a7aab0b04be9b5c44a6fcfdd21999e83717aadf16301a9c8741d65c86ad7f849101e30b7b1a344643b100a8582a6ad10000000000000000000000000000000004bf40c1d2d3574ad7fe128ee376364591b6f647f939b0b556ac3fdb5a92873f17c007e926b8a39a97c814728f355bfa000000000000000000000000000000000b8669e10e0a538a421b717287455620b82574b96ed09f64db444ec73a67a3227503e1b4fd6869314214071399eeae0b0000000000000000000000000000000006ddea4adb703d7205b6d2af436b41b4bde3a8c5dbed9dd161c9b3b466ebf06beced64fca25c3bbb97f232315daa5565000000000000000000000000000000000d97248a25ddf0ebd0200c6abbcac9ecd9775cfc5ec8da91634e77488bb592e5ff277a9607fe721990f403dd73f746e622788b3597da7b9b106203dd0ea97527aa8f5149754bbb0c10bb6eca8a46d94000000000000000000000000000000000135bc4f28663a6d7d995f6b876ffb8e6ef1d2d0f232388aa5f390c57e8c48cb84d370ebc4bc267eae4466a019c9ed56e0000000000000000000000000000000008b6a9d13dd9d7014df6acb59f80b335a751fa2ba4dce63467aed18f68358f5cb743718112b3cb2d0b5add34bb6989000000000000000000000000000000000013a5389dba4da195f34fbe798b254403f0bc5632ed98bd6017ef24fff33640ae493c1bb7a77a0d3c97649230e455eb51000000000000000000000000000000000a69803a4cc237ddfebc51df2d90fa1ad03359f9635ac1646bc942546575d1558f5f2c3010f6e2207849ee697be41d093c21276fc1371060c226424eb9886de6897b15b075fc5a51aab4710e9dddd384000000000000000000000000000000001939c2431f8ac4ab19d2735f122c0424af2ef18c0028e155611237e86648bf1d74fcba3008f5c6aa30feb5d4a14a3f3f00000000000000000000000000000000174473eedb54aafc522973244ec2feb3f7e95e50a1e996d1100c8da4fa59428c280f76e9e7364906662c4d2802235aa5000000000000000000000000000000001021d15f8ae2f62dfd3862944bf3be88d86d8113f4be22544ae5e925d450044279c5bfa1bfca44cd5934b42a27096b510000000000000000000000000000000015e0f20efae92e1fe8dea2222ce808a7de9e9e861c333db139f8ac11d7c4fa9ae6e49f51095f6e16bc738dc6d094b4cfccbce4e92cf377f67244995badc72db0b80fe37c9b7d443595156fa41abea17a0000000000000000000000000000000012d70691721f5787ea2e2a652f9c65edaf763637f95c285a62d32dded18579b7257493e01eda19631d00ecdd4e27a9ff0000000000000000000000000000000014da9ef6076e646e7d5b52d1803d3a6d897664851c6de2a9b330e48695737e05f0369224c3eb357bf557625bb94e6ea2000000000000000000000000000000001554f68124a91be5b9f325394db23ed5db8f6c46eb46cb50e57947bae00819b151afbf4ab4949290ad41625499f42dc00000000000000000000000000000000009fc0d459e28cd1239d227e1d2f7d530b9d14ce5638cd308569300a791c997a51dd5a98aad703239a23cfe7cef7f47f6ff79345f31c107841ae388f6cf116d10bc696aec4933de56bb9affe7e20c649f000000000000000000000000000000000452580d6a37a07038ce3564a12c1c7391fdb002cf27a6df7e194b38f3c12a3026f2a8acfe5e634cf89140da256d0a420000000000000000000000000000000004b73c9a4f9d41b8b84e53de538e4b15198f50247e75c274c14f136d7d91dce4a62c5346bf11a105f035e29ccac3dbb70000000000000000000000000000000008a8a3b2705a82b551f8913853f682253e7f1f68c8e42f349337f4f1eaa5103f59430af0c4a124b6a739bf88298c5f6f0000000000000000000000000000000012f4220609899e8610809bb3a4da46e0688c285ba2e8750b4bf44a849cf15fbf5c016e8e8f9372239bb562e7f38916e921cf773387d5351aeab99971eaa3b207fa6a318ad60f1c3e16b7f68251f9c910000000000000000000000000000000001884558e709635c046bd6ea8872bda936ba4d5ebcf7a0208cd0a4ee08b69f36dd2e136ce655ddfd89a5b1cf8e48f5ef7000000000000000000000000000000001357e2dd9fb603e5190d7b7ee105668bca2ed23ec6a248aa71aa430c2b2755747b8dfa3b147eb51ea644bf0354a61ba000000000000000000000000000000000009b0b0a76c6980e62e4893157b85f59345e1ac81e1aad1e48acec44c4803e2a9080f0d193fb799e0277ae6f1058839e0000000000000000000000000000000014c984ae4ef5d9d319fc89895f34a7db02747f57b206b0b30e8c9757d4b47419e6c0c8378fdec5aba364936a3b1922ca2d69cfed6bb2d33fedcbd215dd4e9632a3cf86a4b2716406305f6a85e6090a050000000000000000000000000000000003e1bbb872db172a1fa615155f81aa75ee9760f8602e4135ef9f1640b7f9d54bda911a220d211dc4bb767bc2b5e6e23e0000000000000000000000000000000008464f23cf693b1d4545b6ce4aecdc8fd182cfb288c5ddb1f78ca578e9b16342c8178d886cbb6b8086c0fd1318c4ae09000000000000000000000000000000000af574c4d0fd86087e23daf6d9ce98765e1e445ef9152dbd68152fa4833ada0be440de4abfe7c07dbd4ee67f1a4aec9a000000000000000000000000000000000a8227b982f9286b03c4d49766687622206213d88cde007360df9b4ca5916c44ce44dbe6443577998b4b0d527d22593379cabae288f8a9a8cd54523c20825b8fb07886bbf0ba0c5c807956f268af4fa10000000000000000000000000000000012e31070a501a7df7be43dc23e23dafa32ebfbc10ffb4c53f5d36bab2af69db5a05ad64b9ed116560e40b71f9217189b0000000000000000000000000000000011cbcd38ec3c6a6d49df6a8d6e1029a0412b42bd3fe8b42ed625adeb5a2f631e97bfad302de82ae34f715962b5ba0289000000000000000000000000000000001019b1b619fde9fb885d3c5f03a4373358107af7509754ce1ab2deb67df536d05e07ca7d60d927c15b549502750054f90000000000000000000000000000000018f1768b7140484105cf3ad2daa7c565e18eaba834db3f6bdfc9ee37445f2d6f7dc2b4c986b7efd5373224d2c92aa5a81973977d8e8c592f9063c5a14a658990f9c3405643089eb58324cd3f05b5b5e4000000000000000000000000000000001847b14146cfa2e1700f368f414b6a66ccaa02ca2a90b40a8e2be2ee4eb66af77ba563d7507de63362fb18426b6149610000000000000000000000000000000005c028d2b344ccb6400b53134bd179028b8774000ace89369bc655bb9dcd1643aaeec830407ee941df5432ba27987e8f000000000000000000000000000000000c4a680e2157dbdb53ae761209d505b4cf6b18fef5aff1c5009ab41295e0ce2ca23bd7a4f983fb9d085e1d0dbc75ffe40000000000000000000000000000000013c0cc77a5d771f1df99d1530e65ba782604c1ecf67d08572609de9f18405b9b817c2643226cdc7c9ad35beebf87dab0a610bfd375a7b8d0b034c17c8fa27d4366b06c681131fa7daaeeeb08e25c2ca60000000000000000000000000000000009f32f2f83c21875963818872d243cc8c70b75234f53490eccffbf060cb3b9c53545c1c32025b271514f500b20b00ec10000000000000000000000000000000002491b571087a9e89dbdd039ccd2c37d5d8d25587495b2d7b0066e9dcca02d44b2c134b0128a9a1527396729f069df83000000000000000000000000000000000264e9c47f72b639597de8f26a42ca7d77324f8c0db705986fc3b40dfb46f47764b69c70037a68d76a5de49a278779a100000000000000000000000000000000090614b3bb302ed9fb78b8756524fb78d54a4390b27136087181342571f994b1a93faee28256d765a8ff4f448cc357c199ffe1dc2d7526338462860501d75380a5ed9d53e675125342afb6652a97437b0000000000000000000000000000000012c716ddf17fca0d974e8d6003d99aa90f06b201fd141c74d8fdf1167030d14dc732917d3c6f736c68fbde9df50c098a0000000000000000000000000000000000261ef2b47de8e1576aecc6e19ececf80ddc1f4e28b2ff27953a65199f65a6211db7326632cfe04d543895c727ef8b600000000000000000000000000000000044fd6b9b4a1bacb8b7d4c53c106b025ae78f17c3baebbccca4e18cfbdbcbf8b3ef88ed5bd9bb36d9aea9e24f4117e760000000000000000000000000000000007721612515fd075811ee804314acec9d389900c7ef883e866f71fba00c49d5c4dcc7a2b8e2366f5a93f4577926ed171fdd97465982b58e69993711a6a64134bc4e76b88ba1948af91ba3339e9b9d3e900000000000000000000000000000000122581659ab1712afc23c23c2986394de8e155bcf722e944ec05e7e42e05acc366d9a7abf2136b5dc68a8dcfd4a640bf000000000000000000000000000000000188842cf4ef54cf77c145acb685d3187cd9c842ba6705bfed846ace83dc4400c45120fc1d6a633ea879840d3d0c902f0000000000000000000000000000000005c8966862ed4458a753155ffe2c64655779860149641ee5511a46ec576798fdb5cd9521528df77bfebcdaae2f94b865000000000000000000000000000000000cc10d888d2b7a97666de99ac14a501b7e2171f074d30d947efd67d85226c312a7977cf923ddbc88c533f08a99f2045f786a2a3974c84752b32f29707805c71992d5d473f4b7bc1f0757d126607a1c07000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f285d33a7fbe6ac6eb42eb932dfbbca2f771ffad5e80fde686e5df9d34e9f83ad6", "Expected": "000000000000000000000000000000000c9be91da9bd8774f18efa3ae9248e4b03d11c49b377c372613b7e745882b2b23c49d518672e58eabd4d9b510a25d8fa0000000000000000000000000000000019687b9eaf5d68b0e795cd57055a74e44efb3e997cb038b7f1cbf08ca70e80a1655cdb04402c542a92ae4e435c22d0b90000000000000000000000000000000010aa1514402ce348d1d61b8d38b53017cd3977a84dc14445db64799cfe822b56a0adbfc5332093ce7ea1f0f438bf15590000000000000000000000000000000019ade30ba0faffcaede95aa272be042aef090f89d9ca25cb825846c4bf9e4c1dc575f8968c88ada51fac71f26fb01517", "Name": "matter_g2_multiexp_33", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a1346771f8ba25fc44323d5290068e46b3f756de6d97aa934d511979a1486bc32173575639a7e54aea8eeb60f32a8c3000000000000000000000000000000001958ae7fce87db47a65a03402313b99f659ae02e8b62db3525d48dc9075aacc5e5abb50156e704701f3ceb18747e0431000000000000000000000000000000000f98778311e28b4081aa76a3f9546b94c29d86fe8e66b905265d74ee21928dc3ac463049f70d355d8caee5b59d65e07300000000000000000000000000000000185cc233ce72770ae26406476c1779858523e7c940d69adf2750695cb12440440686b6b918f4adb3b14aee9aceb6422119582dfd9cb80d44c17c5f62360e62f6736d186194f0f8483e34d8d18d832d37000000000000000000000000000000000ae2f565a44c8e07f2a136368798a44926cffd3c3a6d4c2fbf91763c20d2bd959271343b80eccec4d59a84394c7a3ce70000000000000000000000000000000009481a5fb276c938801133adf10dde3e7da2087d0bcecd3c9435b7de544271eb3b07a69efe7e168869e727868f24b0d90000000000000000000000000000000011774e0197866b1c8b3428d353d2c9f6326a77ab30d5595e2402a0486f03ca6ebb1e8dd335a60a772dfdd9a3dbdd3eeb0000000000000000000000000000000011ed2480d79f73a67a2adaa6da3ae4f1e1c28feaf0e4cb9aafac658901960129e40f6415ec80a31d72004899326f714bac0bd9b8746fd02aa70d8b8a2b5d3be46baecf9449d8cd3d620cf9efb3c615d1000000000000000000000000000000000a73b0d8c31af2deed481faec54095875639233bb09f31b1c7c745cb54778d1c8bd0a230e963ddd2ec8d178d31fc14740000000000000000000000000000000015a889b16be93d0b6dced01f5e2278ffde1cef0576d0b04b49996cc5252854f879e04b1ffeb90e222f4b9d5fa350767c000000000000000000000000000000000b53dc4d72e90330ffad17012bc7dd2e497cf8aa6ec73bf25c10427e23fd28137631249eabe9d0308c956dc7a9e92047000000000000000000000000000000000930cdc5d04ed2d1eb62937d9f72fdd733c07a5a0e392fd5216100216b1a2e3cde7053bf766f046cc470d92bebaf6290069d889881d5bb87dd65a9a02a7fe239bdb55ee54a6310bc987e7c5772404d7d00000000000000000000000000000000131c4e590400b69b3657f7c67272b1e3491983997993ee87c94043001d78e605965abf3c1a8c8c39cc08d5a5ef05520000000000000000000000000000000000124f71c136dbb032504da910958e8a7949f1dc5c061f21d50e439e01e67919891633b3bb84fa8a54c69b632f78560ca70000000000000000000000000000000014a4b1a05f1060853f4294e669a20b91f939793a6eada6dbc84fda8ab11509b256d8b785b252a3795f1d2b99a51df05d000000000000000000000000000000000be2489f1f91d7adff356236859679c46b6bf8c1b375e8bc8bd1e97830b5ac223ffbbda60ecda168bacc2c0b90ed25d3be658348e299bbf2438a0c013f86eeeb69a013b8004a4996189472f3372b326c00000000000000000000000000000000111ebb796e8770d5a69e724a8d3ca62ef1f13778baf4ba12bf462211d35e325ff8e455c85237a73a3046e531f2e2255e0000000000000000000000000000000004308b76b06067e0a07bda143341220809b481b40b78edb2e24e83aa0f003d209198825b5fa9bfd92597e27a4054d3ee000000000000000000000000000000000de74485713f5c95653e98b96aeefb79b59911a610c2a848a807653c19d50394fdb52178947c779134d24b6d396ca36800000000000000000000000000000000069f47a71ad765591f6335b962e7c2d87b556801e1e6c25b449edc83432612fefd405c952397a704e9aa5a924769ad4e9b9d0ec92ae7df3f52a95747659f8fa3ca2cd01e8d7ef6de384111246886bafb000000000000000000000000000000000a3f89408ee43c0ba6a7c9c479327ebab426d430e3ff212c65da6364b16195619d27eee83d701a2ec50bd4b7acfaa06300000000000000000000000000000000092715831af983f740ca2c673e7c9c47727d64165c59fce19dc3fbbdd0b6a7be66288ea1f033ebb5ae2b38b3762edaee00000000000000000000000000000000071ca6fa9e546d4bce965b2bd0f0fb97e6833f05cedcf66d43ec88aba411dc4d6db9f1591de22f493f49a1dab1a2701e0000000000000000000000000000000018f89932ec032fc28775d34d588169a1435bf4ad7e2ee11c9d6934dae31324ddb96b3ef88f95d1bb2e52c3c8d9c01516d2ffdf1237b4e03c219806f2dea745c94bf08924e1b9f11deeedf0db19da6f3f0000000000000000000000000000000011b5cc382164fc21c9a72cd85acf61c2a78d00a16a2dff938f0b36bfb3bb7075845a1616001ab53271a9a257a38312cc00000000000000000000000000000000139ba2f27e545d45027a0b11253532e28fa691170e08608472ce3b3f9a3e9398c5ee76953b1a1d01a5e79f194c32d1f5000000000000000000000000000000000d875f44829555cec695f3f4a28078b0a6f168bb0985793d003443b75a141936f3c7c633518890e0f7238416d46573cf000000000000000000000000000000000675420ed817ecd24bc5172d3e7df60ac4281b24ba91e8b5ca8bd6a8321f5c7312a6ba043fbcdc467c8a5c957590a692cca0751c9534cee7f14d11b7c8ccbb2c537a799df59f850bb125c6362d72e9c400000000000000000000000000000000107bde844286cd3958cc7a1314127322251699b51d8af8e6b57495497f21a84e05612b1569b54fc5639a75e9f9deef750000000000000000000000000000000002355b1a60e24e4879448437d2c1b12e58f02d7eba88583e96e9634f7e2c8c6886132ef0488918f665ae3f7b6977c7c4000000000000000000000000000000000fed531e437b70bc4a19ad63c61ccaab49afc50fad1f156b1c8ecba0e1b703f8aea61882c6327d4d8fdd072df9c4e73500000000000000000000000000000000182177409579ad53786539514753c696c8757b8c4d9b8360392f24b591e43ec20e84c0abe468061a9e5e879c5c81314217f890a1120daca4a1bc1bc0fa7529f0a87b5fd6ec385f12b270bc0f1a5281b40000000000000000000000000000000001fb25395089228772d6000025cb0356eb510c964bf7d0c12d47a6608fc18cc448e44880eb5ba8475cbe6418fc9d8fee000000000000000000000000000000000f3b9de9980e5afaebc59c56e02fd75fdad13013842ac035f8d5569a46cc67f0cee461a939aa5a3d8fec2966294207930000000000000000000000000000000009a223ac0edb164845eb8397e0cae4363fb2c8c996c3c5d722cb50be56cc3789c732763cfd4b61470886dc991be39f57000000000000000000000000000000001909f17b229eb351dfe8317a8273d846edf14ad5ee0ebe8cc2b595ebfed19b73983035e19ebaee3d05b1dea35968586961ca18257d9d989ec13d4f158b18ec17d59344f4558b6dae6c0aa0c2f37affb500000000000000000000000000000000081fa9eb8ca7d9db52380e4c408e6d5d668471bafbafd62ba9023fa08f6d300a45295b583677824c29ddc3254439cadc000000000000000000000000000000000e2e613043b1566674f791dca9d860a49a75dfa24dce3fe18f544a9b24ec5266a64e77386b672c93fc4d079eb8e76a01000000000000000000000000000000000f471b86ac5783d720e7d73e8871474c8665e8a109aba27c1172ca24217eefb0f66c53232df1672dc0af6ddf9640e10d0000000000000000000000000000000010667cb22a6a818fa7c729e40a7e70e1f31b0ecd568b54a4d352d5c9df8cf1072ebf2ef1e612efd96bddcbeedd8566430fc004ed8a135ad97cdd1bc4d0c3ccd15e65031ad7e3cc13ef2c260958bc43be000000000000000000000000000000000a0ed87b01f27f26380c6285e82bf2f12ef3016c7e7f3a13041d465825664573db47be6cf099cea615e21f6a5d759b6a0000000000000000000000000000000007afb2a1bd50fa0fd3174d70f1c8d5c229627a496bc9bb89d4f52d47b1862e14d704dddd80045e58d00336e898a996eb000000000000000000000000000000001698f30f824ee5cb71b3f2451953c371987433d2eda570f2a13262ff9e5e529e316b06ef6aadffc152803b076f22db9f0000000000000000000000000000000009eb1d5f3da7cfe9b40a70e1b3c3dae36436e8d068a79dcaa283905614676645c99a5a165630ad46b70bd6be8b1f21a8d8cfaa1037e2c81c6973b221dc7badf25ebe3fb4b42bbdef1124265df2c7ccc40000000000000000000000000000000005c4390b8f37cc3fb9f248470b505a5d9502d44e4a4459d1f56452cd9aec89d114f1402fa45935930fa00888a4860a9900000000000000000000000000000000163b0ca84b5cca4f124bfb5a13a4a3efa677a84dc89b6a61e69d0aad34fade528614e549a7b2326d1f6016bd0d35465a000000000000000000000000000000000bf450dc8af483a9f993a29cb47d5362c9f5ef38afc2fba8040e14514eb834fec6520a413fce5868aa9a2c7c3ff6617a000000000000000000000000000000001063619f384102949fa1f8353f0aaa5031234d736c54103df6ef6fcd0df02a19c3aef471f0413a1e19febed6395459a0c25ecc5d37659ebb0c9e21ea2f8fddc518e3d8faa99627b21faf105445f69d7d000000000000000000000000000000000e35db3017963d3a9d62b7e7fbfa13ce4f5fb46a90c1285ddc0fa481d9379b95a77e8cdd4aab5c33059bfcdcd82473fb0000000000000000000000000000000004fa27c663c8d21f041d15cb199d31cfcb96a56cd673b730dd111bf03cd954cc33799456674ed4d58e8e0dfa826a6b26000000000000000000000000000000000e0df4e7f943db5b5c27bafc7e1ce099b2caa64642bcd6336ef926352682fbe81a1945b266cba7eab52b16f4aa63eb8500000000000000000000000000000000020167756b8c68f535c4691b1249ca1ccf0a539f7274623ada824d0ba789ef44ebb20ec1ba51d46c0a42da78653d287e26cbb32382902d9b1963779070d749cbc4df1e7605f840819f2c04aaf89c732f00000000000000000000000000000000178037c6b5fd1c6c396d8aaadb712863557feb744d2cb9165ae5c36376d2c066f7b1648e083f81c2c96da6562e0b3c20000000000000000000000000000000000b805b4e1cd5d45d8b6ed9d4f604ac0b40f336b8123f7281df43a6e803f8688bd8087fc4d5fbae695d06efb0fa35e18400000000000000000000000000000000000a947562dde45f613ee1d15614940a2edfc770d733a60374f8e9188675d4cf973a5c1081c11fe5a1d93bbe85e6f47800000000000000000000000000000000059473d80c82c6ca06b4aa71d072f4751b3b053b53ffcfb4a84906ddfc36ec5918668a62f07054af1b241bdd4485edba699aa549077a80ff8732b5fc9df148a90f405bccc14bf7305266836566b7a98b0000000000000000000000000000000008b9d0916a9f5689b8fdac84bec3a49d0224dbadca6329ecc156da633e1332bcc6735ca3ecb228c22032dcb7b2f372d3000000000000000000000000000000000cac0c264add10bdc1217384a7379f65b93cf822418f7e4e2b48eeac45f068a61f805cedfb1665dda06e04cb726d245c000000000000000000000000000000001578e98a40a64da59154b1c3d757d8f1f8cdc500482c7b7d65b9997576f745442fbac654c19331977bd210df440372970000000000000000000000000000000015ef69f82e85c81d28893d94927068f14c6516eb7d09898d5d055cbb7a9b55c6d7f686f067ab164160e6d6a8f91ea19d40e2de1a2901f1380a383a741d79fbb0a041da5d7bfb92edab74cd483edf95230000000000000000000000000000000000a6a27b498285085139b8dd0c37b700997134337e696c84b5e0cf70ea3991cfb40ca3a3098a3b3a2fa31e91aac78eb2000000000000000000000000000000000bbd7ebf4301c5eabd4f448b89f1b227415cede3247a1c8dc56a02247efaa99dc78cf370f644ffc06cd2158fa25197dc0000000000000000000000000000000004535a402540474d53c084d4fb6d9e12dba6716ee13286ed758aedc1ef911b55c572640180a54cbc084ff57ceae8a4b4000000000000000000000000000000000759de2a9e0f3c04b4f629a682dbcadb2140e5b935845cb55bd267e230e08c6e8cc5426057473aa03ea2196203bbf6dc062b323592118868d547e83b731d15ba2c7bdb1ee4fdf73600c2584f1db0b45d", "Expected": "00000000000000000000000000000000134c29cc5c33c10f04b6c09b5db71b10304028d06ad6acd4f4b39b16823288085a84a0380a1549f04b3dc692cb8216d3000000000000000000000000000000000a0a9379d63527ab9b5f9c00be4acd54e5fd683a0a2f37c85ba570171c705eaadfb0f4e4be1a8836c9de86dff46138300000000000000000000000000000000006ce78f135dda5af34a0e069d7ef13fd589cec5a6128512bdae7f45f28b09c6e4b3cf638628c9f4783097cc00082aeea00000000000000000000000000000000141e710ce7a979dd1772150d0cb2d5b269d5cda50d1bf7bd0cd827b24f9cd8c1e2775f495cfec0428519627b7fede464", "Name": "matter_g2_multiexp_34", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018aba8353cc470b287a163fdb9b8b4cc46071543ee8261f928a7b856287946637d9b36b728a54e1df5f185a47f1556060000000000000000000000000000000001129541b2e3b2e1a553995b603dc3eee44a5ea440e687739ee9e1339dd79bd96c67231ac753d483e0ca96b27054997b000000000000000000000000000000000e1cdf3591aadeb56dbd80890ff7d5639a64847cec771a19c769df7da732a6d3179d3a89ce0052bd7c982af0304408120000000000000000000000000000000000f5f5f0ebfd2b632e15381ccbabfa88eb774f2c61801381ca73e6970965ecd54f5f3a9af7c152186af8fb75ffb5bc25764ab6f4c43630d5e79e8c474d76d8973a7b7bd1c7f1a985333cf1a6be5ccff2000000000000000000000000000000000e527e40c311edc5dcdbb4d0b70497eaee14533aa8ec57dc7cbd7d839fe6c6ae62b1fd0be2346a038de687d5cf5394d60000000000000000000000000000000005f9fc63027dbee5e0d55cd6c57daf5df7af0d138393a2dcdc71ef9aeeb204ea347f7d574e71f2ffdd37d8f05dc7979f000000000000000000000000000000000f8788034c9f1c9c2018a52326c046cdba8997199732152963819b663c6e58e9d6a0065289e2e25a97ce5627505900f20000000000000000000000000000000002a747bb3bcccdc6ea0af1bf1d0ce55de3f41b93060361b30c76063346b606322a76ed7eb260219c83aea0806ac7d8583280f1b1e78d2339f64b5b2f2bd77aa24623b79fe2c9debab4212f4ff564983b0000000000000000000000000000000002148c043e065132e978e89f018a5b728d278c95c9cd1a6f276bd13f0cb708422a62fa22f7b377adf33055fcb09a6a8100000000000000000000000000000000024c4c721a0574e53118bdcc3fd41f73176bc8264d2ff39673210525166bb3513016b5c9af67a47a7032b74a62effcef000000000000000000000000000000000797dfa8cad94896916b7d55fbbb3eb0eeb74f70231205388d0dda69dd8abb436c22addd22c1e3689093739af957b65200000000000000000000000000000000010dd2ea2d45528de8bf1b5c5dc3267fe8951e48ff5987e67ec52d58635521cf1905f1688894e3e23a659764880b2301d4d27ff9d03ab9120ac2adfeb36b070015f0e90782255ddc9111704c5fb11177000000000000000000000000000000000eecc0a4edd3cc3f70d3e0e43ba56b04cfb3f1ac23c657048a94318e622217572b0f929c73f545d6f5f5613920c0580200000000000000000000000000000000137a098ea8d3aed32c197a2d244a2e18753045b55cfe16874f79c728c664b7f23b10476f20dfffb2f80417c26dff4f860000000000000000000000000000000004a7789b02d7d95a2ce0c7bac39d5b057509200393450a47fd9d087a353f866921aa11185550537b98f3073650d9a1370000000000000000000000000000000006ed63730bae06403baf705da0e30c6c00739799eea4a312d06b8d7dc35cb43a4f1e941a69e55ddd7ab8ce42d8629fdcc66d5291311c7cdd1f33e5365ec0689608b3569427a8f6a9cd0b94b671472e66000000000000000000000000000000000ee7ddbf43f17f722dae84d34d26add8c1d732918b8c75c6b295f2f584075cea0c655911410b32c06868c1acf36aeaaf0000000000000000000000000000000018775682555d9f5a576cf9462170910bcdd083671ae2e4c8c6fa99a702548f1ce9afe90e681b00d194322b1a2a3be7ef000000000000000000000000000000000f3935bbbf58b91fe8176f3e25ad3fdeffdd6b369ae70b704d4e54d4fe32fe5987e73aa5aa975e958497340274577cf3000000000000000000000000000000000c088bc439d638d86aba6bb1e6e9f7540ac2da3b96080aed455edd1fbabfc141e26f125cc3a9cf72070a24f298dcc3ef4b718a5129659250640e333f4567043ca749063e63d87efd86a9995adfd3b8450000000000000000000000000000000018d8a47d1a13b9b8fb5a1625f9616ba120d5c677bcc996f694b7e15d251fc4bc938b0a7cb5b70f22b8e9f5b416c513210000000000000000000000000000000003d0646458bbee7ccab27f858b8ab0af0cf583da12a40ca5a954d7eaf97c897d379129a63d8131036f29c30c6e644149000000000000000000000000000000000d5466b50975c5a2dad96e4e24339eafc8c85c2497a6f19e12d96603596498654cabea6995a92c91b8319ce06f18d56d00000000000000000000000000000000191a96d62139f8219b9e4369a783400d045d72ab2dd83fd229e08a4ca73de59a11a5add86c739cb3bab4adc5e9f79685708891f45d7bee38fe382820260061e212c6cb9a8572b4d1854f3ab09409b05a00000000000000000000000000000000032eb1f7846b563e98fca0cd44ede4909b6e16a893f5ef01eaccbd7d8aa11710606bbbd0ee6480f7cdbdc9ffe66c3a9c000000000000000000000000000000000c31bb6fb537cfcbffe815d86ebfae1f5053ceb756818ede8a58cd84cb34d0eacc70ab9095f9db1691e4fb4bb816d570000000000000000000000000000000000a8fa1dc2f28277a4bf8fd9665d4b5c3baf1352d89890d4af94a3657cdac7fd72558da1e65cbc5bfac142f0e817be74f0000000000000000000000000000000005ff65c22ff0abfb33518791823c5f2202ea5f7258c0a507ab84460335ffc2cc8d7c7f670752a7647d6a6487ca0c9adb85ac0f94f300b004c7f20aafcfd9129d6c2590749504a3f08c4cc708fa30100300000000000000000000000000000000190379b7629f74bfb88096dc9ffcdecebae0d653410f032a35a811a09022679c9be19f3790af95c3205a396819e068e1000000000000000000000000000000000b6f114fc277ae8f0b5374dd349985bf955dff7fcb0095e0e1e137fb539814be78c924074bbab54f29dfb42f3e7df24a0000000000000000000000000000000002d86b0507c147142d03d3461bfea4c3af7e57a6edbb372387de24a27cfe27c44ee4b9571325a1b3f5e83eef450f2fc6000000000000000000000000000000000ac3b226d5e13c36c3a8ef0c8896d9af55bcc0cb67ac1cee57a5c6519617ec77af9af60ed44e0a8284a2d59816ebf848fdbb634bc0f99c5795f3c4d6a0efcda7f71427f1eaa1c5411caa6cb05ee3147800000000000000000000000000000000079cd4511e953e4d1b3f4f3bbbc66a62772018e809779fa39aaeeffac737cda9a6116293848f967577f03017f33231d2000000000000000000000000000000000ce3cf48be423a2fc0188b94f2a22579872e9ba140798e560ad107f63ab2b8c601831f89d06a4bb8e7a758cf836ddfb3000000000000000000000000000000000a6a90f735f215a79216fc4e7daffbf74775f38824952af72ac38c38a77a277483e34bc95031679494d76f109c0aecc4000000000000000000000000000000000d55fbce780d885cf817cd2126e7acf115ae9c72843af23c376f3a5d4307d1eefaa0f4691e7c09b5da1707aeaa5b675af5e4695c01849259fb969183de385ef30c2403e081067c2d9b6b5522c73fcf200000000000000000000000000000000008924efbdb46b9324bfb79b922ba8b7d83f5e5e4b3b736105e5339805838171801bcf17208f3dfe5c7475d4e45b6ad970000000000000000000000000000000007bc0096fd23f0c93f0dde8a3974ea3105574e031202f6316d5940c85164c6d6bb5b86078a0c68dc822c0fd1b3dc8cc10000000000000000000000000000000017276b3208b347388a5657b10e3c8e4a187b376e42352f76ee3ee88873217b6b8185022c93097cc116abdecf3cc64467000000000000000000000000000000001915ff932acbdeb52f07b664bcc47c3a5b096c6cec32da4d7044326dfe84358e49539fe50782538a901b99428446b0f50ea6fd588db5efc5fb2248634cca683d39d610886b59eb3077fa9612c368d7690000000000000000000000000000000009e295d229b543a17db1cc85c846111b7097bd169d19b410de78f8da9684e664922eae77c64b0db430aeb422016cfe7d000000000000000000000000000000000e29aab30a1da56b8590e9df67171cc1b9c847696b51147cc57ed6c3b55819cfa0992c67e15e4ca6de2573c9e16231c10000000000000000000000000000000007cc9990c6722645e320dd16a4be8adaab41f958f769ba0d22e235549a7457778cb9b14aa6ea5caa9e0bd43f8d04cacc000000000000000000000000000000000b2dab5cf37ae8e76b71dd8748c86e8823142792445fa0b140de31957d35bb7267e3d94e0dc92f4342d9f8560c5d9d86dc2060a3421c5a8336c80983c9a160345901a496c3a74fc5248fca081d09953900000000000000000000000000000000128e2aa795f8479da3ea2a4efd12aa90a6fb019d4da89fd372e6848ff7ee17da689d766c9e49c88c962eb4f682c56fff0000000000000000000000000000000000fd68bb80d6b2200297aacae1174275f864669e962d85c9105032d7a352fea548e9fa0629a6749c789fa0827a40190700000000000000000000000000000000175bc3918dcc972fb728f1d8cc30ce9887efc6e0b254d8d22af87f95cd4182129d494c43d11b028c4b9849f5520a4fc00000000000000000000000000000000007c5363f507a01c0b6935fee0413345bceaf1336cdd20f69060bdba2e411521a61a549e6159b2e006ffa16e3bd77e998e27e4afc3e6d59d0f5871b35eb83b46cf15da6c326e88dd8edf84031f58e23f90000000000000000000000000000000000efcd782b89fee74ebc037160c6653ccc104260b5f8989545b40d51ead6ad6ce6252e1232281c813e3c883af86e68ca000000000000000000000000000000000b68ed21f76ce131c089dc454dc48ef948cc7c6d5fd87d647db954c9eeab2f7f76ccc51a1cff8612e89bceed16ca03ba000000000000000000000000000000000cd776670d5171610046fa294fecefb42f9bb4d71baed4af65a09018b09ad9341789abc23c9feb85adf96b4203b0c0a0000000000000000000000000000000000ec4ca0091a28b73c9adbe7120f2bf1a84a62ebba1e86b1948389b1a1966c1de4c632a5e245ba634b53cb932f5847f6ecc7efff04f143e2d038de153861da5e04016a7eb17fbe6365de13069d088b1a100000000000000000000000000000000022f319bb5167c2b945a69a438f712df8975a0e262438ea687e2b0d824e2d1d14bff1065f50fd6ae92494f6f3aa9472b00000000000000000000000000000000198ce9e4ddb6b423788dbea82d75513f43cb43ecf1b27c8788f041248f01808644f60fd823e5862cd7afb4f7e8b6b6a100000000000000000000000000000000119dc1be1bbb7e678319db73055ccb88ef7efcf6119f8a9c43c69247ff264879a627f653a10a950e0dbe69155ebca4f1000000000000000000000000000000000692a0ef5a75d42524e3fd52ae073b0f2ddf6378f18a5dcef05af4868a899b93c7f1d2691883e5c85f97052ef1f4177d09a2c3dbb4ee4f485dc60dfbd94a358a7c62204c021f2d7b140187ee9ffdc4ce00000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0d9b15c065497392e4b477a556ad620d44e671137cfd570d53590b7528f8ff680000000000000000000000000000000001423d1707e49d2215f639df75ee0e13bc724efc7d099259179260ba0f17157c4efc4276844bfdc46c61ac2185f64beca0000000000000000000000000000000019ad06d215d3c819311938f89609ea7cc63fadaa11bcc86cf5f26370a966eaed1aca312c18176674b5aaca3ed8ca876e0000000000000000000000000000000013bf3f13e87f3ce29f0524094e2ab8e39679566add32e779256006dc92ce09f60d5bb9cf0452b90ece71a5f6981d77f300000000000000000000000000000000112e4901efca14686c30a883ecdafdc389303f4cf46345e229885c76d900b0aa084a957076009ce22ee36d4e285d410c9e2a72eff2ec29a65b417767e7090b73c2fb530de6c8f4e4ba30543946423b12", "Expected": "0000000000000000000000000000000016d1fce53fc4cf40acb0347c0983dda46383e4828c16985459ac89a2ce8d3c2a26cd9acfaa2ec899cc63b4c6bc351f560000000000000000000000000000000019c9626363b511a79f297dc79c5a3b7a2e5127fe49a2fac5bc43a4376f170404f044f9f84b82cd09a306012fc81e3bdb00000000000000000000000000000000062e324f3d7c5bd39808b762a5b009cb30bec14a9591477959339bf2de9ef27eb42a0eddb95aa5fdca9bb9d89b278cc20000000000000000000000000000000000f05225a4d3bf910b0ac0103594a90684ffc0c09e2c21744032e30470d5727be3c27621dc2377e9845ad78be67b856a", "Name": "matter_g2_multiexp_35", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c64577b78ff306186dc44131cf8bd946a68e65502c4af9613154a7e3ffea4fe4e59cac4a500894b470a74e66db1834e000000000000000000000000000000000b4311c295bd30174f17b9ab3544f1496b9655302a4b6026a113b1aca31b555ce7b2d812bf8fafb6b075f67cdc59b77f0000000000000000000000000000000012d7dc3db10ae6b4e3e99c655aadb71124a0bdcfa6e30ec13c7c977d39f83aba4979a1f45881813a3a68e149a40120a90000000000000000000000000000000001b958c47cfecd619c05a2c54315585d15fe377beff889602ecba6ea3b29d51f6480f09a0a8490e4c754045f0bfdc3eb7b9aa7e0bfaf135ff24720773ccd1e0a46fab6d678d91a14de137061e145fb9d00000000000000000000000000000000010db66653f2ca73e55d85254f62e8b558584d546913e4b8f530968088d90cd5c4bc164fdb77325fe0bb2fb1a5683896000000000000000000000000000000000a1af9bf84f0b351c8e8c082a79c7ccae768bd2ed40eede38666aab1901a6eab0cff258f440c8c8eb4854a824b9aab4b000000000000000000000000000000000444fa654afb57f1b01d10be08a330f23667af58e3a40c630a2e01c1809125b3ff8f76e8a39418688a023293ff1a45e90000000000000000000000000000000002ebb117ea107a3598b888dcbd5918dd0ca307b21d65843c6c28b3efab89d0e276e5d92283bbb345b674d4a300595425c6733c9bb7bd195622b96c4181e8c8837d1912fbadf77d6029f7fc44d793b48000000000000000000000000000000000105818a11efaeab4801d4fa7558b09bd56294be7f58e3e54fab1f4f7c243ceaf08c99a14c3128ccfd866b6f93caf989800000000000000000000000000000000091ca092e5f83a04e872e621e71d54dd6886d088718f60ed5b62d3e4c165d3ff2cea1e50fcb94fff251df0f5ee453cfc000000000000000000000000000000000b42051a1ef52f87536b9bca459fa7070ca17bf825950b13b3bbe9db183ef722f62af6c05c174c65d59b722e1d2f5b0e0000000000000000000000000000000002fdb4a5480418e43aea28e5041af6ad55a6c226e1eea1a0449a99b5a937375285feecabea95c2652da5113dc17d8ef4410bb66334c677397d04f59eade9630463065cd7da3c9d50580c7d66bbaf487d000000000000000000000000000000000d8f93b589678d4e93bdf8da7834bc8edab648ead731b7f5f0cc299488f07262877ee9bb1174ccc106204dcd3f1f416800000000000000000000000000000000160f740ffca48d3a10c43e591cf46c129507f10e65d76a031fded2930d6c2dca4c79d7813f63e4ff71aee09d672173680000000000000000000000000000000013c768a4889315faa3976c8e43b4d466ea594bd94773f270a198f2571ba9662d10435d1e541a492055c333eece9bb29a0000000000000000000000000000000003dcbcc9e6a0cd5741d77da88fbbc269202e8f944a5df5dc4f9145758654934d5e1eedd596325080382458961ed3d21ed97a16fc5b2c70829b15f73615286eba334de1f520b5f0f6a83d2578399cc0b3000000000000000000000000000000001344fb37c1d7dcab01a4bf6fa50c6bb7606f7db22b85a3888ffcc2e9f229f196881cd7c82160730727e49b9e6fea04320000000000000000000000000000000010c7b15a6355d3152eaada7a606031f28809f278a1d0e04d264b563185ac7d9e351295191a6a90ffc9c6dd33995265db0000000000000000000000000000000014438086226a061a1bd557dac24d9333e14cdfa3a7bb00ded4a450e8889a3028b174bf38ae1347e6aad19ebc1cf5ff7800000000000000000000000000000000105165703c4592cc4f1f489d78426a56434dc77327c13221b582dc25306f4c5bfe596f3e47abcb741ab553fa14cad374bdbac08202bbe5df1229e99c76c1727f7789e0f8c2002f0a2c195bdfc00acb36000000000000000000000000000000000ad8b55a198a5e788bb54c32112761ccba9863cba16d95ec9e30181376e7eccaa2741660f2c5f708300be058e566ae27000000000000000000000000000000000b9bbca7db413964d2ec113cdee2d7a7bcdb712d285655f6b2897dcac61456ba4d08e25e8c28627231824829bd7d13800000000000000000000000000000000001ae49c10675256651e3e038a2150d85993fa6f2a97b9bc02c693ed97ad52af34015176258b3b2546b81010a4381d85c000000000000000000000000000000000c8f9668a0a497420acff5207a07cf780e0b2ba78083eb0ed8eef76beea996210541bae2e64d825000f307d54cbe3b2b43da827b812ec6ac23b00208cbad0f2e8b3a32434aa61dde029683c34c1ab1900000000000000000000000000000000012990a66c132a31d60d182f729b52d9b57d9d1eb1988b6f0b4d9fa2847f26983078ef9bbfd0e888e14bf7d1f92d09e54000000000000000000000000000000000585215ffc2673a197bf9cc6c6424547886abc6ef5c6edfeab2ef0c42034a4a458fc7155c35c84a8e9e9d89fbd4aa25c00000000000000000000000000000000118fb4fe0d3498dd2b55e62272e95a1203f9fd22314921d3e044f1b162376aaa7e8154a4e2184b66451aba98729330c0000000000000000000000000000000000364b9032ab9cd9f599979c8a93acbdb831707f1f84fdc92844b58bc7e4d72472ca5b09c51b1b04271ed9f0e391552463c7a8f7bf434ce5e63ac9365448da8663745f66689b4b04968f9b8b1b6805893000000000000000000000000000000000ddf9e4e302169e195f4f88fed06e0c93fd1b542abbfeea5da5d47c662ad9a16b8f4aed7874354fb9008d073920e1e7e000000000000000000000000000000000043fd1a4b781f25e8747ecb3eec45ce90760e0d5dd701e8193a7e726684ccb8ff21f0219ba15e9e777d339a3d87a1ee000000000000000000000000000000001117d2ca429048056084e4847c7169b4c8ddaefe1d48079949f9f14e4d74f0e0b38a95d0f17389f61da7b2a6d8cabd1c0000000000000000000000000000000007adfc7d87b1c533b4439f6b30d38c694b65b3b321f3eec13cd7d923f1d5f117005be6c3ea901a9479d79fc553e34e6c51f2e2bcfa6ebf84d3ad83c57257b9032e5d62a8663ed5d77afce00f33382bc600000000000000000000000000000000115a81aebee0329b174c01458f8714b13ea3fb2dbfb051b27b29b940652f27e01a84e522626d12be80da7e1039e2baf6000000000000000000000000000000000d9e37d2e5e7160db30acf5593d1c282541a0d4ac0482f0759fef8704b9ec3ab1e3ed248e37c6be285e890ef1a520d0b000000000000000000000000000000000c198a22c2f590df2902c8dc2bb1ee427b33e9687767666140f9d3b51d73fef18a259d43d86fb3559b1ab0abacf547a70000000000000000000000000000000017e705af54ab76145a79e747167a4fec6ec3a16f3ceef86b1ddd1be144e616ea7d686bbccbd1c5c258e4546405be023d6d8b15ec8908bfe008414757c0c7f79b3079f9db86d91ac3ec8f38ae2c94d48b0000000000000000000000000000000007c4c31287ae0b3bb90475f84abdda36610f887aae311d8e97bf97bbdbdfb11d38c7de331cc9dd022926678e5180c0770000000000000000000000000000000017f4afe28adc4b24d16b9cd97aacd171c2104b13b079c643d664a7c924151a401c352832c4967c0e5cecec5f1d1dae290000000000000000000000000000000005a8aa8a3a91461e0ba256e44af56875f8d07e24628e738ffc057249d8380417884f40c84e76dc6ce5816ffc05c0d686000000000000000000000000000000000f84bb7385a6936b519e881a708541570a31a9d7897ab8b348a350adb0d30522567fb917c9b6db661b6f53f98b5e68aaf4723e85076d48389c3fb5a5df16b6bc6f7a69ca701632b1159677bd8a6f7bb1000000000000000000000000000000000a8726ea352582ed52ab4e440102963891f059cf5a3f4901615733ad560a99930efd8692f3c30256d58e5cfc4f0803bf0000000000000000000000000000000016a623dfeae872639d99e3b8209748642f20af796325630596b6ab6146783bd4f2247c7ae38d53ba9a3fc0cdd6f29087000000000000000000000000000000000e40709656e569e4fe90eb85d8761c6ce44a4272793ccb7635ce75d67d97464e8dcd8c32bd4ac9a36fcce706006915b20000000000000000000000000000000019e64802756896206a9600f2d888f3d307ebf958492b1b5153c06a11231e2d7d2f1786368447f380093a29117cc25da9a632938a6df169fb64daa55d2f874ef7629d5be41dfa0d50827c082333f0fca00000000000000000000000000000000019c7409cda6084edc6e559da9b361c96cf207f1e2cd63cabc9b86c5bcb07a59b43e9c6ae3e90a61c872f168ab89cb2c9000000000000000000000000000000001101bb63a452b766a085fb788937f6b751417dd8d905ee50ab5bf96cdbb9d7b68c1735460a71eaf9e9bf662734f495c20000000000000000000000000000000014a103871fe523cd01053a992eb9884ce83c6023bd6a8c2cd9ca60b8780118c88502c6980904f2d2bf9ccc9fb597d535000000000000000000000000000000001929f25d52ee6b9a44333237c732a63ce2abc80c5510bd67faad1d7adac96eac5449823f3a52ed18bb90b93d9640d0d1283a4da7f71bde54d4b7e28b2b23e2eb05d8b025e77e15810625d71faca6d6e50000000000000000000000000000000015b0a46692f57ccd2b7f53040dd75f30af0196aa3c5499049eb172b4d927f96a59c42a129117d6162a1bb31d2e8734a4000000000000000000000000000000001366dde2d9070a2c057744fffe78effdc328b122e356a6aadb10c3fd2e8badc0ff70bc6d18293b3c52428e2ba78766600000000000000000000000000000000016fd48b067b949ed75bae3e4db29b5785bf672bd01032a925d653f8a605998e1eff6c77ec39dcfccd417f1e0a9defa820000000000000000000000000000000004cf22bd706dbb1cf8b97187ed97636380871402b3ba9de58f174bf50a7a0b528749762c3f55f5f835a276e43b46e669d402b71c1fc5c3f3a4ed9edc73457a27ea427f83a784796e01b7a1451b3305b0000000000000000000000000000000000ff424ae9372af46de34210bb0bd670eb173bd49076df5caca4bc4293e742121267a20506f931a4ae77cc36fcbc8df4d0000000000000000000000000000000015a6815b47966fb84aad5de62e6d4280f9135e129f33fd01e667f4d6e1bf7204317fa7741f3cff3682e251437927131c000000000000000000000000000000000639dca43483b79ba8043130e508e91fe3f43bc362fd1dbb135a2eb8f3b94d5cc4af70f1101c790545a0eaf2408706e1000000000000000000000000000000000045f0a04a642bb6e4db34fbffc8adb19a24648554f36ca371fb1a851384a4516a57f1850f7d6be59ff67029ec4002de310bc47acb3aba7eaa490ec104ed9b2985f65c7347f69fdc67b76f6f43846a99000000000000000000000000000000000e796fd500cb1a25b834baf7335641f34ccf04ccf60f82367f0e5c8c7fce8e3030e7b916752bac8e3adc01cbf4b319ac00000000000000000000000000000000142e8bbac9cae69ba3dca48aec045e0c4d7028f73c254433f921b7240761c661cf8e774a21da249f7758234cf7607fbe00000000000000000000000000000000045a3d80767d116e89bab0e9de812ffe7ffdbc41b61f5f17ad16be5bdc9968e34f46b937c5f94f8197e21b358f44b5240000000000000000000000000000000006978b93018bfdbaef0d40f1278e831a1fc50b44fff39b7c93820a284d90b699981b1f422f751a33094ae7b5cedbbb2691b88ce9888e5dcfef70d6f960a456dbabc792571f2a98746b7d833e7fab98500000000000000000000000000000000003c3561f5d255cf1f83cb5f4df8e3b8d5655d965826d56867ae66da631f8e7d489f733f5824c36652ab00586d9c593be0000000000000000000000000000000010b3adb0017e2cea1b71680ca33aee368429880759660dce2d3cdf57b6cd7339bd8853e5efafb9a5aec3f7e22da676c2000000000000000000000000000000000cdf976e4c65edb79ff15178f6ec5bf0a77a30d97b799e433f216a2fe3eedb10bc6ecbee2974167128773cff43f1922c000000000000000000000000000000001599b60ee70d927849764880830b2e7355daf95eefef39ef61569a2b83b2bcced4dfb28047a1e5350cc87ef3cd5cf1d93e82cc1261ac3864266379b4d518e25c05bc492a8946b38b8a64acf47aeec4b8", "Expected": "00000000000000000000000000000000123af49ac2981e14a490a4a6792f21343497b562266a47487cf6c650769c810852e357445bc68f3460e7822e8cd1e3f000000000000000000000000000000000143e79853e4bf6d031e1116dac2c6eca4991b8a1f822fac1d352d2cf1b88df239d82df886f0b24b3e7f305286cc1257e000000000000000000000000000000000b621056a9de2d83c946b1e2c7a07f9beb8e053202407323e412c0d8f60123cfd5818067f57034fe1b1b5a3d1bb285a50000000000000000000000000000000001642fdff2c52d58d38201cf44c31e00df47ea1439e9896b5ac5e9372482f4ffcc698be46c2d375d57a72fc677a9fc8f", "Name": "matter_g2_multiexp_36", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011f78204afa05c3717d3908dc7e4356ef96c426ef380b6abba3a5616d9ee01addeec3369967ed42e030c4b8ff9939c4e00000000000000000000000000000000175a19c86e7eff0f4e809a5105503ed223fe327ee4617f7f51257426fe408373899f39014821292a75e4cc4eb9f7f31e00000000000000000000000000000000052130dd3cd17840385db424802d869d7eac781365be25ba401b7b0e4025353c8dbf59e5997b5aac74c252192061299d000000000000000000000000000000000457f4fc7ac5d7d4fa07e8ed125df4c4e950e6ea926be9c04b6df3c3699a10e99af7ea8546b8ac70c3003468a75c821ca2a1148f1ba719b2da92c418fd137efe21a44dd4cce013ab36e57d97dfed92990000000000000000000000000000000005182a3af2b52102e09214d048a1a29d1e10b7ace6afbc4e6b1ebf16790be372dfb6d65cb8fe08c3dbbed8c5435a59a3000000000000000000000000000000000f2a1261463c09a88edac443ec3cea8aaa19659e8b7ec2e8a403dcffb1e50ebb3d07217a9ab057d8d097c075609c13900000000000000000000000000000000007d6525fea8fbb685fcf89bd772d48c406aff7377429fb199f27c3c3337f11f8e24c4d81c9026b469600d11e8cce51be0000000000000000000000000000000004b6d6102debaec16c34fecfeb444e7ba573b13b83ec375f14d2c541a0d1fa528ed6599a0eff4f8ca527c5baa579f762fec5d6167d7777169348cf81ad3eab5153f8f2f18fb5935c5ee5e3a759f9b5af000000000000000000000000000000000ba1f2b2c3f1c57afa0ab647d32af5d036ef18069a4abc9795dd9927ea274a718b67373230e337cb9374ef73b5e2303900000000000000000000000000000000016458ff2f5d600af9d2983f535c965a2a8aee48c0d95095bee642bb7bbab8bc87e3e7c3b52a787c53f0d1e00cb4ff32000000000000000000000000000000000d11324e812cd4fa65d20cf58f88a9bc9407657834d7a92f80bfd32c7085ffa2f9f78d7e18c1405a03de939bd0dbb06b00000000000000000000000000000000144a0f4d50bcb16942d22a12d28bf34d2b4c51512a3f11c130f1566aacbdb63ec3984df5569f41ef621f50d138883d0dda609e1c8fa42a993ff355a70d44dfeebc71a801daa36acd437daec5d7b645d10000000000000000000000000000000000d7b138fe445d7b7e130134db653022ebb389075ffb62ff9faa544cd0fdb9e78e313d0b1cb19bd812421d38d1e9996d00000000000000000000000000000000084411aa2719b729a1e299fe8a710f767009060f1b2becf2aaa92efdeea8c91239aa5d2504c6e7ad2e3f39d89ef00c1e00000000000000000000000000000000017e86dc0146c9bbfa5ea1e48f49918167dda13b31ba73311fd5cfdc12845b95b9e90972a9a4d36203be8c5920f8de5600000000000000000000000000000000150e4b6fa9cd9a609241d1de8a637c6ab25207bccf8e5eff4a97ed633b67826135172880b118037649407a3e1b1a0661bc5f7f5d096247ababa51852724ce9ddcc6acc7ab6180beaa1cda97dba94b4ea000000000000000000000000000000000ad7430b7778248d63a06e26119e5600ae97071fe8827b24440587e8bf6887b646f342741af69d20e243c9b45d7dcf24000000000000000000000000000000001230cba1a5a66197875240fe00c59b796ba1db5ea5653cc76bf43d6adce0db3a109168593beb39bb45688c1d124b9eb300000000000000000000000000000000144652474c58413cadf9b31715152052b7618e7093e931367a7ed0340e66d84c0471b6ec178e1730cf10e749e01815780000000000000000000000000000000009abdd0210f25d12146f2911a60035867f59cc341b35c73bbdf8f7a5a90d0bb6566c6ba0e868a3d62d3557436190f3f63222b41a59f9551e91572ae00582e1e41989ff5f8e2cd1ee1a78f55c2b28ecb40000000000000000000000000000000018ced3cd0c169693368fcf9c3dfc49fe248f0b9b5511e9407b8634d8ed7b54ae2dc4ac6ffde8b3dea70ca86ddc89449c0000000000000000000000000000000002f6b227e699dccf7ab1e0b1cba4cf9f05c4dcaf9fee6cd94bbb79f42bc9598fa23eb2c653a7654db73feb511b24829f0000000000000000000000000000000019785959766eb8b00ac2600d87240f2876e049725680f4504f59db6642ff8f82d4e1b856929643906c3be7807a2443180000000000000000000000000000000018285acdf25a475b37ee4da872debba4297fc8731eede6b22be3b0dff12117634de44b84a18042852ef419c3ae18a46b7431e5c1fe5f8d38c759bc48e8207695a3cdf07d4c1fd02f1009088539085da10000000000000000000000000000000019c7950b01e15669cc1f96fd94957535f32132ff6a5ae788f6f660024c332593942bd3e9603f862756edd4f3ab17b20b000000000000000000000000000000000bf3a6bbe10ad91d687a135f4863ba0332e9b04271d437a6a4770056e6b1ca34319dc895f9186482bbbc815aead03392000000000000000000000000000000000a3ef4d4f7a15da04a91ff079cc40040993a90e9ea21f53e31f7dede52dd513a97ece780374c5f3aa8c8b2e525ee31d10000000000000000000000000000000017749fc7761b06432632ac686d93484f08407504e58b04b3890cc2101f15d21f46ec0dc1e9028c8ef8df10f9ae929887d474e755f6ce9045baaed65c80f5a686547089e8cdf4ad2b7c2ce7c255cb5c730000000000000000000000000000000005a36af876edfdf26175c185c3ef005530e02474232ea659f5cf251c5de5721f1b44a25714967d283525632789331d2900000000000000000000000000000000130a6f5edf94736477143b1efc316f131b36d9658c484821be08e7f5b9c93f60cf34042858664db0ff0240addad8782f0000000000000000000000000000000004fedf49e6d49c074dcca96c01607da2105d8053861b4c677a69cff0f82e66a2a63f32f3d9fac8e6c844a1f77055bf31000000000000000000000000000000001528541de3a9d4a216c0e60c31d2b7c7cb91b839fc31307cc70f18e9b87b92bf5b9a9dc4eaacdec6e6bf7791e547d8a2976c8775b0eaa1e4aa384d222efc476305c7ea2d625cf5c67ea4368d7a9fccd10000000000000000000000000000000013faf7b2b8514f77021d8927a3b63bb7c57785e581f40ca82882341c13a9daf062a26b668844e58291366ea6ae2f179f0000000000000000000000000000000009060f9e1047f15f175fe95cb0914f4941bcaf071f24e856eae6f36263c812689a9217da277613c10c8e254a0933c80800000000000000000000000000000000154619e4ae3901789ed3ecdfc76069d8026a3e2cf142a144e8b58482233380690e378de6b81af0ed9b6536da1cc2a30b00000000000000000000000000000000040c1bce922503699e1fd5ac67725f11d7f9bb6903ff9204412f65355be69d73cd7330a3f7bfcacaa9b078ba6b9a9f839db274233c46caaa9c99690fd00fcbfa4eaaad7c41f8ae84313448c787165f6500000000000000000000000000000000103d91916d537379d6d8717b17ac5b7e9fedd98c24890b51c027cc086458259767d989b3ff9d6adad72bf977e4d378f400000000000000000000000000000000159c01ee371622378339518217dfc0570178aecc938b4a008dee1a6661ffa605c0f1472c107558ea791e0959d7dc1c70000000000000000000000000000000000ea3e10cbc3a55ef2dc7bde7a2e80666557e9e8fd9ce77e2e92c2c70777afe43c23072e263e1def56cae4b6d3772db96000000000000000000000000000000000cf1db638331c47f9080c04117ddab4ba79950563810d50e04af819f14ae0981f6e1e94a635fc90226c8d7beef0844354ac9f9ed46ae5aca33af9ba1c0fa5a2138d4ca02b962fd1d02b4636114ce19970000000000000000000000000000000000095c82c58182ae9a1ba14421c2966d687f7225ccd192b24097f997b471d13b46a048202712cb2d8b1be0ff40755dcc0000000000000000000000000000000017410aca05935a06942f673d1937a593423cbbd226f6707c5922306d28a60396baa08a941122dd4c583331c9481a734f0000000000000000000000000000000002c1d3a1262ce8aae42a6ed10d8020c31a468127e1a59d57d2d409ca9d14143d9fd21353b260edd8b387840580698846000000000000000000000000000000001512e29256b6b9f5a7ba4f79dde2c915b162e4881856258ac2050f02868842381518da4ed824243692b131710d7201f8ab300ee55e90ac046dbd772da788dacddf72c559d9378b39507987a9774301b0000000000000000000000000000000000ff83bf1d50fe35bb3d1bcb07b02d78a1b44d2e0c6bf82c600feec3897fae8b93c0ef05006c1322af0a732392dad86e8000000000000000000000000000000000d70c4957cb3615027cb950e4224d41849b9ff1b435ce936384fe17c4d7bc2883fdbba5123ca0c0c010651500557e1be0000000000000000000000000000000008b16fe9af45fa913aa7e5d01b5b58f946004eaaeeeb493759a5bc2b192d2dd71af24ecc5c6838b5e267ec2dfcf5c17d00000000000000000000000000000000038ca027c985af3cf60cda13e770fbe4919d3a5b413763c8ad155cb4903312822366eb986f2ec9e0804594ad4894e468275b22db781d5e8fd07f36788bc1219c4b4a13554c28d92a381adae111b265730000000000000000000000000000000003a313d6d41f1ebd6b98b2061a2d85943e52d89e4b8680611d41ea182385e154da24248faa1563e6ad79172f91a8763f00000000000000000000000000000000038d9388fe9169710e1a205ecfd03f674b47ba2275794469dbd5f193a55e00765c8eed026363b41afda417bdd8910ea60000000000000000000000000000000007a75f53d9b8e5eef19ef6f5fe8ce5d5308a1a7d02e0bf46f91a1e0cb22555752d82d8471c123269050fd8f35a272f600000000000000000000000000000000011f313127a036403652fb2f83c5122fd12c362ecba2251bd6c357a964dd758eb2a2c3053dc668b9a4bc071898d45cd46ec69b95dccdbf193d9ee4c51615c0b7be5ac6bed3f2559f0cb2755c634839ce7000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e450657331e2bf1816a84c190eaa850ecfe1a9376123e0d0732d90ac3537668f8f18b9f70000000000000000000000000000000007860c3403607d4e13f738357e18bbcc4df10fad4aa25776f84d3c2758624a83aee0996146ba17a812384e1d67a7c54f0000000000000000000000000000000002169148d86b1f7a0ef75d9bd19b6d7cd66da4293fcf33fed9241544dc2564d980161a6bd959f3b43569312bff7a23cb0000000000000000000000000000000001897c121cbf5e82424cc50078ca7143a0c670f1217a9180cd2a4700e06aa895cf84c0af94b7c04bfce047a7d1f8443100000000000000000000000000000000040c1a0c4257f90bd83fece3c9372842a148132d2dffa956729e741ce996d229aacb04387d51a72630329230020b2235f4087feda4bd8205d96cd0bf6eee44c27a6669d7ae8e16c731849cfbb2324e1e00000000000000000000000000000000058c001ee1343c6cde55bbdc4c538f5d14b0e8c199fb822f080ad96ee764bd1908f92260ce60cd521919f223301ba1220000000000000000000000000000000000f8943c35e7fb8b58963719f1b9820153e0831cf81dd208176af7527781ceabcf6ed2e2276cbf374e0525952bace0c80000000000000000000000000000000003b43ea8c32a13c014b05326f7b4ad5b5fc1bb2367866a69373ba91402f4b45409c6d034898e8b0ec3b93c2878d59b72000000000000000000000000000000000101c371ab4d57ed2cf17dcb731117b1986bffc586529fc1edc630de1c6f4fdff1e10b0895907bb81d2ccd3eaa96c04a67b81583fcdc9afe5f35974dc9b6310ee8e1c92031a49c08b05555fc0d33517f", "Expected": "0000000000000000000000000000000007152d538d0f750901466c1ea34a16e7b0e1296a2a3740568812587affa5c0c76ca2055804e24f3415a403f06a717c0e00000000000000000000000000000000119c0c282d22a01524d87eb850789c4816e7dafdb2782b57c32409b1016615beeee2067443835466283543773cc8b427000000000000000000000000000000000d68137c3df081a519747c044950c3231ef82295eea5b7040843668195d4549c8ece4a91447e0ec89530bc51277535fb0000000000000000000000000000000000d81a4fa2d32ada3e08a7bd4471d45a6afd2cfad5bbfa3d378b1df2e0749f9b05b465be61cc9d1a0f4abd56dce03dbc", "Name": "matter_g2_multiexp_37", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b153d6554c9879359052717457179d8318f8127eb73edc1d6ac2efb1ea9643c4357cc813d1df49730b77f995d6d449000000000000000000000000000000001533a450737b4bf8edada15446cf21ebf82aa7bec7943025dccc4784e1070fbce430699cf3a37a36a3ece692ce87639c0000000000000000000000000000000017b8afc300bd70a3221120f6fbc37a8e6158c48b476f00992c6f41808036765071bd0a76f7c641443b97ba523153947e0000000000000000000000000000000012f686b4759a3d5db2325508f148bfd6217e027fe261d3ed7b8fd0526036044dfb563e1c4399ec266e140ca372120e289f3c65c2c25c6c37aa45b1104745cb8ec511a165ffdb7e304f5478aa3add4d7e00000000000000000000000000000000061c8288b7bf2856c075a176d1086fc49f0359ca3e7c1aaf5f151e6462916a4e1b69b6decb18823759b620f7593079c0000000000000000000000000000000000877af18cfa0d029e7c9a5833b346c7fdec06e54d9641d3953d3cae0e8912bac7c990f8864c2adb6e576442c634865b6000000000000000000000000000000000331490f42993de3ce7cdd53afb4b310f25881710a23f601ed95961bad4e9cbf57d3077803908a91b65fc32d1a84130c0000000000000000000000000000000005aec079da804fc572bb8eb867acb93a24ffb6611eba920d2ce799c4c80cd8e73b3cefe989885167ab685365529b4f2a8fd50c46bade91a13d6dc5a06ee62e5e89e0ae7ee885e5516ca6c2dacc36f6f3000000000000000000000000000000000ecc7abf4f6f9692cf3a118cd01abaab4754c90d1a59468d402bd699992800c2994f47b2094878604bf7825f125133e4000000000000000000000000000000000662396427cc596458e880bb8a43dbe046deb85601e3c64556990de36e8637e8ea3b142a8195762910a83609ca311c3a00000000000000000000000000000000198b9c52be68d073910f5b26bdeada9e9b308e4541561a8ffb21fd8e69ec9d93b01ec966fba65be27ee53d4857a43e120000000000000000000000000000000005201975985cac810248e333ca714cbcac0ede46bb915d8c857837c80c805898d0f9ca0940819878a26d269faa02cb86128db1a106328916ca5d63c0b5722642febed26f00a89430d52ec3eae25a019b0000000000000000000000000000000004e61ad4818ea3c98ed3c0d247798a1a6ca6bcb35a1cb60bda9394272ec092c385661ab93a42af439f1b55ee8b9c0cd4000000000000000000000000000000000ee0b71ebf39e4009bdb310fe3b555cdc860abd47a67bf481ab36b5ed0c00bdca8082abfb75691d45e10c2f2d777be19000000000000000000000000000000000e9582e3b5bd580f3ca7ca1f58e39379918f2d04b82b418a91e133117a9703f7df4aad30d48a47e29aeaccf5b8e33559000000000000000000000000000000000113b4c068fd040cd3300a2d1ef658955b014e571e7c77594edd31968037c1fff241da88e7a88669a569462564e28cd7d45665afb6a864893e389511a0f7b2df74c9e45a86fb69f6bd79854e3a88c206000000000000000000000000000000000d8b0bf633072f19db61ea263a1dbeddb326738396caf1196e31e2cbe99a68e8c70f8db13cfdfa4fc4494e54c1ef28210000000000000000000000000000000009ceaf2a0c63604afb8a903195933fd1ada0e5314255be3d74a95679c7a7845785e22d2c0c206f3afd62110ac9810c2e0000000000000000000000000000000003a135b405f46ae3f5cbdd63f4964cdc5014c9f3405c2062ba17423dcd22b8f2011638d520ce0ec7bb0cb5b03e8ec01700000000000000000000000000000000066eafafe1cea67aa6de267c767f49d4a3fd44c28d45a920fe9b3cebdeded883d8960f5e9fa4cc179246918942b1428d28f5fd09c2c1819adf8e6d0e0f4e4681babff46757edeff3839e9691888c13220000000000000000000000000000000017e37a2f1c892fdc58ac3f72cc5a5e2b7c0c87333afb06de89f7a84b1267695bcd452925fb2f15f8b7b20aaa85a6b5650000000000000000000000000000000015b2919343962337a41b54076d6735a093190e1965faa33eee800f5eaa43c35f349aaf93f19977b6fcd19360b27edd6d00000000000000000000000000000000161afb1494482f953007038557c847e2cbf84c57c5f5b806e3b0178e71e3238305f733943bea7ad6f2bc290778638e6a000000000000000000000000000000000c27a2170fa584863697292e626e2539aa15f3c8eee65cbf1f1b7ced6297248d059fdaeb9c955437a51cb016d1ee97c3e6e61390ef88f20591570ec1fe71c3ed769ee8e234c7cc7303a4cdc065717736000000000000000000000000000000000313a30edffaf864d0f1c6bdafd7d1e563cef434d45e71489e9f9e4cc6700e44991a99220f53f0cf5e7de5f6e4098bf20000000000000000000000000000000010429081ebd2ed6fa07de6ab0b7bd559a26a43df99fca0a2252411b4554dc69821ccf3df1b05114da84a616ccee0a9c800000000000000000000000000000000131a31442f80da4621f7691664e9f8b467988fa039bd086a2d64f9810878b557614c27745b2e821016f648ec36ee797d000000000000000000000000000000001160cef9f5e4d022baeacdf10b3bf9d7ed5e50627a99e29df1be3667cb872b2af333f803bf426314369b490c2eca642aa83c5af2f9d10c06552ea7d1749cbfa7574b238433c1c0e4788efd0cafeffa57000000000000000000000000000000000b20ec53bc643bdfda1e3947b3773d748cce1992e2ae27c6b7460d90d48e08eb9240879a5a7d3dc3189f486706438dbe000000000000000000000000000000001024bae4a7f71d3d2fb8246e82d95664c4ee8bca4a380c293ea084f749911f984aa4c6f266ecfff69c4f57e20c0660ca000000000000000000000000000000000b58472d81a9f16d2fe7af87170ca0c8c51dada62a4b2a713cae053a0066fd268283a785ccf269e05d8873cd686d2f4a0000000000000000000000000000000016b68177bce92fedfbd90cdb752bc332f46fde6673911c016fb9cff4912d79d3267bf629c33097cf8979f2b913c0936d4bcc88d85a5a8a29dfad37ba97ab3a5defde4ec356146db8d10f33bfb36ddd37000000000000000000000000000000001030d5791bd2a27469d242c62403883ca167303d907839e608acd827b4118b752840a4eca0acbe5df0b447d6651e517800000000000000000000000000000000106d65f922581237f779ba3e66608729dfddb2c487bc927f34e5e39707f2c8a82e8c96af68e3257c7a9876a05a1b01d800000000000000000000000000000000115bec40b8fa914305b1d5a85b65f0811517d36839494ba69c929fc2422f7e8b85d78df4e1687ab0087287eff29c65430000000000000000000000000000000018d78a75ec057cfcf179fa2ffa7dba79cabf6525dabd69ab95b23dc8f293aa077e46e562caf447dd0913ac9dd60ec76b29d5d818e62c9791c320e01a3164e142d9804e9caa7f96b4c3b76baff38ee2e600000000000000000000000000000000023f7736d6de94b08d9e9efb6f32f8c17cafb1e1b9b1f3db6e58df72a451c3225d11f4304eb0d702b07a7966f95a11fb0000000000000000000000000000000007b3204f258c873a6fcb48d0b36c98ed5f99b424cf4f92a028174e0e93db2af549648ea95fa8c7bbb42b2a10eeceaf8500000000000000000000000000000000165d6e769b7df91374dfb44e18d43e03ae12ee10d8a618a20f67332cf96492ff514eb7de06ea53096e823770c686c32700000000000000000000000000000000012e69ca1e106411165c06ca15988362de583c4a05425e2f4aba4c14cef6d8d04c52c87b4fb26b1557801f55b02ee8ba971c8aad41e401ab6c49dccba28ef26acf4961978e94e633b72c581ac03621e4000000000000000000000000000000000e8e6bf1c8837c31446959242285e9b85978a5349e1f0b3447e380a7bcd6bce758bc6192cb880f9c09d6ad4a0ee36eea00000000000000000000000000000000199b361ad0b435d7a66b46a43d06e5898376a6c260b68c965f7b186fc75d2f321bf883646e7551eaba03181907d3aad1000000000000000000000000000000000a76e3f399f31cddc4dd4bc22187a68fba31fe2371291ab515d22730d320ae4240911c755750f687c7d26aed09da4210000000000000000000000000000000000cbc8dbc004b9253ba91b2238c92bbf7883360c7ce39f6e15592a8668654950a3fc5a94cfa97f5ddc60add40c32a3630659ff910eea5280dc5c24c542516053637a5dbea576a94a22acefc902e56568e0000000000000000000000000000000005448b623604262a9cf1a9a292c36738960e132bcf0ec8e61a510008c2ae0b51b31da25f2bcf0d7c0d4ce15b1d7179fc000000000000000000000000000000000b61df56ef891bac07a873571f68fe43f79438a31038cf8ff97393ba44cc47408e5a6d64e9ebddf0195bf914f141e668000000000000000000000000000000000d196ced22ddf11132bbebf6c85bb3006a194cebca975d74992ecfcbac546f0f25a39ed5d6100768c1f1a791f3604d12000000000000000000000000000000000f727cb947849d2d7b046218f084283e5513e8582229085f9f98fca522879543429cb8ab435aa3dbf01b68ed258d82c112ff32d44eb442a711250875d86a401d0dccc95e5ee39bec71738fd812d487c6000000000000000000000000000000001044bcb16b3384a1f350cbd62bae568c96932a364c16b34d91ab9b1035ddee93a02920ab4dbde2c6f254031909dc3a450000000000000000000000000000000004a29aae48210289e5f588aede0756ddf60724b8ac54de5d9159ea834d5da98b7a9d09a6f37bcaeaabc559dbdde58b6800000000000000000000000000000000112ca953b5ba652c715fd20e3b85c5bdfeaa7d577aa49aa4656d142c9c2afa3d8aee151338f59a199f3c0c3f6a430d6a0000000000000000000000000000000001ebc7a17da7809f9e744cf7f13fc437de34d3472f022493f58bb979e2282368f989ca0982098a7c377498f1d8d32583666b820fae2459b98f9bff20275a3c96ddcaf98a78f3f5fa4a2c0a26cea79352000000000000000000000000000000000e7c3d6bef4b1723479ab6724cf7858c221993357b194e5055db96b8168f8d78f72aaa4a2046be17ae9a7eb00695ec510000000000000000000000000000000015e85e85cec08133b86738e1f7a738de455930ffd5073997a1f1692c28044ac00b634b90eb24938cab56e286ca0dfaa400000000000000000000000000000000164646a4767ed69f9280f96be9a7f988d17c187162554239797436a0bf4c4ffa7e4f8387c3d2406a7528c021f56081df00000000000000000000000000000000197b1080bf3ac3ef7bd6123a55f20f1002f366d4efea9e14ed92fd2ef147e2b5d9251a302a85172235438bb2d35943a740a9181633a146d7f307ca7606cd45b8e721c46b955a6989d421baafd8e40139000000000000000000000000000000000db7cfdfd58a6ce9dbbcd5d65cbf22b5e1a81acc70f1c85651ba962d61fbd7ad83e5524fb9aa019c6bd75dade96f7d4e0000000000000000000000000000000011e269a390fd15ab1d52d38de78ec97eb6202604fab02c4598ecebc7635ac91ee564e751275a485fb43b933678f11fd8000000000000000000000000000000000b8597a00d2401664405dd1fc7d69786353c86cd4699af981fe869f266f9087b00df22a46ac34883173bead870798f650000000000000000000000000000000009117a49b3f2a8a850a0179b558319bdd19a5f1f4a45af0ccad0890e63b222d028536e9bb612093cb3f1068d262af90d662ac80797c633d8b9c8907acc2960ebdcb5bdad82d9fceb4411d5173b7411fd0000000000000000000000000000000002e1311abb9df5e4d76959276b6f725f13728844f8c7dfe5e25469cb95c6937a822282b3baa38817e24a6219601132bb0000000000000000000000000000000012820e6ddc50e19a8f98c15013ecc38901a4ef8ec2b79b85c7f7913da24404afa1c79045f1318cdf271028126f9420a5000000000000000000000000000000001794e653c5673e51a3ace631c1a1265dba07fb74235506b2149d42b90eb16afc26ec0ddc54d03f7ba2dd6a2503971fee00000000000000000000000000000000112479bdabb9dd057b325563c666910c01ef66adf47aa32f5a41bc9cb8234750985c266fcc329ea3704e2b8d9b15bfeb59401af15d9b83e2ad68cc8e2ad1508391516ba0b26fcc5ec6eda8b318a374b6", "Expected": "00000000000000000000000000000000168c90045dcccef35cfe8eb642924ec2629db886366fd9ebc082019690d103627865f0dc39ffdd2167111f68d8d03c89000000000000000000000000000000000b6f0928a32672983664ad15252b3f145afaa04f11d5f43a6169a2fbdc0b0a04902a183b25e38987c45579ac6d11011f00000000000000000000000000000000195c4d796989630f85df4594eb8353d44bcee76d82b73ff7a57069466337b49b875b3c1418d22d79716ffded7e704a6c00000000000000000000000000000000032db644ff8ca6a3b1ac7bc51ff783ce0cdb7bee8b2c21dcfd3adb56a3e210390756211f22feb3dd4f706e13e5cc163a", "Name": "matter_g2_multiexp_38", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c675cb5e90e45300619be91c752a5831ec47b4143c28330422cb57139882e776c1c5f000d6032cd87c16ab3b1c08ee0000000000000000000000000000000000aeb4e78724d46a55e5f101564bc05e0a1be1d80a781ce8a19607322e82c7ee59db9f53ec34c70bef0766a5b965f54b1000000000000000000000000000000000933e8d7c2420cc553afb1c88b5f64c7a39f78272b34b5611972dd5ced3f639ae2ed2aaba470abe829be6ca6d666ddaf000000000000000000000000000000000ac0a9b46323ccabf4b2024e3a5b4717cd8de9ed7de8a78e33a38037f802651a4b43380a746890d93289d547d94b61bb9c351c585d1920b8cfb89a5bcd72fe041b17f7bd091ba505b287778b0be4e87c000000000000000000000000000000000196597114fbaefb8108c185a85d0fff0f6bffecf056902b22d61cc70b49a747bb35638f5b663830a8d2ee15df9fd5a1000000000000000000000000000000000616ed44a5fe69da994e2ada03a1e09065964223333229f5f30ba7a452830848f599ee21810a95e3659cca495897bb710000000000000000000000000000000012d0631e524ee9d3c776c79137499f8c9fb752ca93e92497d89973033d60971da23f672f140c1a753b4d00d08a00babc00000000000000000000000000000000111159e95d131c8cbe8df75853fe9b3f24013daa083e57c5b716e77f6fd3872dcfe0156382c9d2778fe886621be19973ec42da11e95cebbeed0ebaecd31be24801fdec8b81f4046fea52f553c4e7910b000000000000000000000000000000000a7d253487591fbed97381b3a430404b87aac04073e5931ee0bfd9ea6e0d38a41090c6dc7f6a591336fc58a97a3bea8d000000000000000000000000000000000647c67f1816ae6fec39033c3169eb1ea89e5e20e755cfdea33572d6397e7e87635c7439eda4912361a32de313893206000000000000000000000000000000000e0cbd54634d070aa3c7a503df1171a5cc435d050def17395707bdf7a61cfd539348ee5a4c29c7845cbf0e5df0531f530000000000000000000000000000000007d006601dc1e092a616eb470be35b5d32742dc6a2a4d71cda8865f071dbba9d8a3a8cb10b486253b1633e4590e716dddfdd8996780460757702e34ad98f5f64a8c1e0bc8851d6c97f02749b8f77cd03000000000000000000000000000000000c502a19770a892b2fa1ba59900a36c0ed054a8bfa0c4e32bf471b90d0da9edca6c06b133c8f12e233b104262a81dbe00000000000000000000000000000000011801f159086d07833a691182595a42645513d316c084b2841445c4a63c6bbb402664a9a9a100e8d6436337ecbf398bb000000000000000000000000000000000f2b9bfd8ef6286bc41e9f47ffdd3efe437aad553c9da02b3c22ca04b5578d634c0543a07bea966bedf345562218c2190000000000000000000000000000000010be5ffe0cc9f580c74e027aad09c213189fa4b7aa92160ce813b8d398b2e2803294e1a730cf5c891cf1546c6bc91414f256ff23b38b3b986a62074c5a3e05e86ead9431fcdeb67512f6d502fcefe3c300000000000000000000000000000000132cd5220c125759a18c31313592eda774247f97b5134111b01ef28dad5c3ba4d3f13d1af9076d663f7e217258a6fdaf000000000000000000000000000000000f06a5b03daaf8f92f9a302f06413044ca0dcf2be81d9cf016120312fbd41b273650fbb542d419595fd2815a809c4b960000000000000000000000000000000001b11acf12cf46e40554a1d6a833566cec1b2750f3f72ef77496477831d5933f477d59463ba19c03dfbbbd02fcbb680b000000000000000000000000000000000b2aaf91827ba923c8a1c2fa1d6fb92384c9f48f8f77273056b94245114d1f3cf66fdcab330673ceb2e9dad6c1aed0d4c01b3c8bb0acb17198bde9adce3b0f7ed4cd8615f837aee928524b0984c99d0e00000000000000000000000000000000051858339be99d1271152bb390e9a2ec0c0760b7686804ba072c46db3cfc4472404a9f87d868a28f2aef16c9e989d6e90000000000000000000000000000000019a33f21d0bb8303f540bf26816f145360bd1e9a8229dbbe7981f1cb5b099e814f2691fadbeeed8e4c4b772bbd27e60600000000000000000000000000000000073eeb49aa7e601732dc0888ae6b0f5e8dde3d97b818155221f5ab8c599eda75b25c86f15ceecafdfb9ee4abe3419e10000000000000000000000000000000001507073b97d494de26e70f18bd1723d931cd2a88903ab6da2aac3b80fea78ce75caaa9b99375780d759fc4a1683950bd458f882b63c99ada33d8215111a6df21c8f7424eb2fe9f429256201d099413c10000000000000000000000000000000013b5422deb0e80bec71309d03fdba007eed33c3ce0fc6d4f9a0d063136b3b85a6fce90ee59956a9b91e1caa519f813e8000000000000000000000000000000000829a11eb50f3bb1a47b72cfeec9d1f63e02b9f7b2592174c481ea7b72a121645ecb36b3d1964b082bc6c7efb4483a180000000000000000000000000000000003d3aab53814f55fa97285af2dc6d32cfcf5a08032d2c15ac83ea036603e08a53e0d2b8d93a25dd969937c113e78064a000000000000000000000000000000000c938a68688138149cda64f168ac1466c401196eaaa44a464d9e345c422948767ad1e25d1ce4cc5996ac5d5dab61516b804d7a35e5731b111a6904e0998d90ce86cf612914152fe3d2fca0201a41166a0000000000000000000000000000000001ab96f0b60213855fe221fdbe2fb22da6bd6cad8bab8ecb747c9528d3511976236ffefb34afc462abfde13a99503cb900000000000000000000000000000000182fb121778cb002be3f90e2d6837a406edbb609bfae8fe59837aea6f5f6131a10791f92188958b57059b7b9a9d3a24500000000000000000000000000000000159cac269098d223ee6d145a4489f05875b6a546767c023dbea62b3cfba9f8518c9f4d2594d00ceac325f3d8ef551369000000000000000000000000000000000c0d2e4e7aaedec7e53bfebe8f7fe5115720e58768469b6673cee3473b08fb8cd1ebd0514689ef65d78d008889e3ed296f1629a801db6bb4066588ed79f75223120728c3a57f7129d88f7f877149223300000000000000000000000000000000079c40bd7fd2ce0f48806dd2e88850ba988e5adb0cc5120977da8110b07da264318fa034c0c213590a2616f0ebe40f21000000000000000000000000000000000905f41389be39361fbfe7641394d30870a079f230dacef89149fdcf81a4d1e0e10b9fa1c0c3ecadced9aaa19fa9dcc800000000000000000000000000000000192f50e08e497f902403df40a504a1b4b82f1957572a9ab7ef97f5ab93c6fb876d8b08f318244cba95ad5200fc2a6e34000000000000000000000000000000000be7ef45a14871dbb344a69c4036af4f994a22ef14540377d1144a92978a23c2d678cca47cbc18e8c036714112d11f7cfe80ddbcaeb784e24975b9a42801c89bdfb842cbde5fbc0c3d70c0632cfcdab80000000000000000000000000000000018d7410f0105ff03cc4ddd87a6e0b65ede4abd4609db5ae53720851c90255757e63c6482de4651eb1d3669b1e1a2f8d9000000000000000000000000000000000d4223be106693a672da890b64d2653135119983639f7052eb32051c34113022080ce2355a93a2f64a75d8e0578b2f95000000000000000000000000000000000764780391249d0c987270bd181a44f6260ef82eb00c06585db7ef09e8b069e46c4e0e659a081ab0fda491534b71b0ba000000000000000000000000000000000a8546031e6466ae43643462b7617703a63841d6d4cb0c09ce63b2fbe2c2ba7cc35367191d0313717b1daa665bcb54551aeff13de7bcc4bc2ac1b37e28ce466805757dda29c9c743eaea9da33f47f4fd000000000000000000000000000000001922491dee4e0f29a1dc090c9b48fe8e6d70c3441e532021985932005b22cedaeea7d9ce1796808d756b740ec63f8ca80000000000000000000000000000000005b34dae0e630be6a59ccae17b44eab4e7f10be2ee700bea15f9771a724f0979798617e129540901a8aa023630a446f800000000000000000000000000000000095bdf612289258b31cc79188566ceeef6fd66858b4dc060864d378cbbb69f951e9c6bfb3d1384014507ff29f9446f410000000000000000000000000000000019f06f11a833c06c1c9227255e3a1d74172e73b06675c547844065dbb909ad66bbc150ba396fa1ba22b7183c0fe80e96c4984739882bd2f882e12660815b96d2af7812d7ae87f5be034b88e9e04fa2890000000000000000000000000000000003de8082f828ec51e23c864a16147546ff60b5fa71897ff4c120556af5c6616bde96b6e53fa673cd1f8af503070bfacd00000000000000000000000000000000093013f75b6a19b5433b3b5ff044384ddfa258420c80fe81e0424e3102cbf9e550a946e56ba9746423ef745e33da51e7000000000000000000000000000000001227cfc3e9a8d6a71738c514c05766ed4f1f4605198f5a3ad8309c0a49499e4ecd34ba1ba7677d6d90203e54d7611807000000000000000000000000000000000a635221d514e58170ef299eb7f5b679050ee24c589cc7e348b2905a3cd1b7bcf2010cfe168f5aa60f4bfe15e59b4436e7f33141d383a1a927b7645656ff7a5795901a997e27003c5672ae4fbab4aecf0000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad048fba4674313a9727aa4b733832a0e06666d3e38184836edf786317de9dd055cbf0000000000000000000000000000000009e8450887137cf45b04184b3c6fedac6676cad416a7646e9980dc99a6d6b62164dbdfae7cc20edaacb84432627e6e550000000000000000000000000000000002acbd87ddca9dc775da01ae026f1c60f1cb5974ce40caef80cb0d2eb7839777c1f61eae0472c7568ec9d0ebb2ec7dd20000000000000000000000000000000017c295c458a9dd995d848e3ba585f8dcdec4185a953e4b8e3ca760eb3e815e39a8ff60416e1e6f974cf7e7b086ee4baf0000000000000000000000000000000003cd8725e1cadfbd80585bf5a19e086abd631d6787403edb4bbc785d1a81f6108f451ff642f4df17dfcf94dd6107352bdc0c4d0e34d8a16b3bfb51ffc9b3c353817e8e357c608b5075c173204963606e000000000000000000000000000000000b3cc99db523b3647937b694fc23281a74010079351b2c7d1ae4cc9167917f06c06e627c4ec44af6b09f2886ddf309b800000000000000000000000000000000001e2681dd123994627adc92e6ddd3ffb006521d8bb03040fe1989e4f709e4797d143cd0bb749de33c8109933c709e970000000000000000000000000000000017df13f532bc9894be932e72c609c0386d32390dee95dda45821bedbc1067043d46007b39b6ade871bd36d39a17dd04d00000000000000000000000000000000162db4d1e956fa5b5f9ef244dbc0c6d27718eca7dcc512d1d7b97bbfd2bd00cce7941d1b9a170da6341891773a729e9ae4e31f5b6629463311b9d3c8333c33c5b2e79761ffff9863acd9d636e1a9586a000000000000000000000000000000000f0e4b606ba0a175bf57d4478aa286640ce4b5507f9f9e354fd96c45443333f6889a93012d663d78956bbfa7c645bb9d000000000000000000000000000000000d85dc4d733f0498fcb10e1e814eb61245203d6c1a46181e5a388fda2680640a1271a68d645f8fb179c0dc3107fb788500000000000000000000000000000000185b02140f6314cb62bd7977042ffaaec41ba8788d356047488004d609ae680c2f0cdc94e59a3cf90b6651298b6a81d000000000000000000000000000000000038ce717d08d367a9f882f2241ae4cc0e8a31418498bf68d05805db2e162d053a10dcff85403dc473598089a78dec27e03f256e58f60307ac1888a1b0b14b56c7435213e271eecc79b4a6f88d102be4c", "Expected": "0000000000000000000000000000000004cb919a72e67c31b3409c28dca1d57833a5066c240d2889f5bbdd5540ab2a49484c2462b25da197ec8d93dc8f26ea83000000000000000000000000000000000e1ac1dfcfe22ed7ac52c701a7221b542ce72bf59d62cc49f95f8ba64c05060671098d40c83947dd1952494833a19b55000000000000000000000000000000001331f6ed8ea5ec9b9e1a14997c2c9bc9af2ca305b313e2bc5c5bd35308b7b451a362f8ad61d636dbf77d1b2388702d8f00000000000000000000000000000000186b85e656e45cb5ac9a2a2009353e45749b53dcdcdad4f378431a0e4a317652301f834617e14dfac9836c3c11512aca", "Name": "matter_g2_multiexp_39", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e6292b4d3031fcdeabe62921f0c562606b1ec6139b9c43938971d7851da4945cf69f39652425396ed1b2e70e65b9f55000000000000000000000000000000000e94bc63f3b8944ea6bd7bab811c013fd61303aa7713619faab85a271308bb220e2a94b26f5c7e4136a3d2761dffea610000000000000000000000000000000012313ef65ba41f8e0a57e9b810c13d23241e8430c6ab967a1a9bf5bd6308e89c135e00e789a5610694d146840fbd877300000000000000000000000000000000165ce83af7edc9e701eb57b332597305fedf4b939f3a13a95a0bb3d119c2a9204a4991388f7fb344ec8f15d32cab0eb5eb850f01feb55bb99e4accee0aea8fe6ed0bd29b2ca942ffe09456733aff10ea0000000000000000000000000000000005a88477765bbc8290b7eb137e6de78e62bbd929ca511cf0aa701f926440f21d33bcc6ac8f2ca5de57ee8116c685ba38000000000000000000000000000000000738074a9365c707190f882780b27dbe96179224103392b86c628b601e33b092a03e24a89bb6d1d1024862a9df6fce8d00000000000000000000000000000000188c713945046771bf852155ba412b4222173b6dec8320ffd1c59e9b36943c2c18b0dd3bd551b7b1367dde3e8031201a0000000000000000000000000000000017222294bacd664ec37e9b214407e5325eebe9753b430589de2eea13360783be52a479e2b0e9c5dc4907dd5f06a7fa822b373fd7e5806d227ca1f49ab0a7f8be2b5950906c8974de9f2cb4e13ed20a9a000000000000000000000000000000000c97299d7e18f41e538b91b75e962c3ce4e068202271b40469c58cfc477d7820e90a0e91d647e8ef5fc0cb822daefd29000000000000000000000000000000000bd1e11a3646c499a240bad708f97a49acaeb653aa5bafdcaba41c1c9d32d32c516c94a3db8816e0a43d1b1eceac7243000000000000000000000000000000001223ecf82c4622653ce84460c39afe8a967cbd87a2d75cbee1609161837c15b522480c4731c9e6de9c5c392ef1db18e10000000000000000000000000000000016c5e98d3d17c723548427868e3e6d7ef4bca339e41acef19e0710459bd4732de4a556b22cbb49b823c4ee656fa354f1babde7f3fdf9fba868b5eac61337be0d73517ac3f06c39b4eaceeb27ab6311db000000000000000000000000000000001125735092842142cb5387f1ef8fb69a3535e1f0ccce59661183d3104ec1ef79dd87a7fb36159bc67bd73ad403b46c1500000000000000000000000000000000162caf579539574199d56f4e756f1532c66278a55b4f67f4f4090368260f46023543a8a18d49e8c5783cb65f93d750480000000000000000000000000000000003accbc87996a220a625e36d5cdf05d8c16fb353068ad819f94ba8223cdf6436f8d822719153bdba620a07c5dd955fe5000000000000000000000000000000000b53c8a4b62466c998327e0c5ad65818ea383650bf0977d98a8a94fa9653fba276f7781af9f5a4e99052ee3ae65c283d5ba1635cf82b25b2d7e466717f5716c33f5f3e826bdedf19dbc1d95ff0c8052e000000000000000000000000000000001264608a59c0ee9a26568cdcea8801cc8cf6616773bcb0971234b2d987563270c7b2291fa035c8f2069ac99e16c68fc0000000000000000000000000000000000e839d8d982d6663ca4552527f4fcab6ad5e0a444e7b5921055c774871601d342a151133ae15bc76c023b7ea643182ba0000000000000000000000000000000012ffd0696b7e29b305412fb840c596b66b77ac2eed936fdbe0562541e4de6b3166a9991dbdfa0f79b78b4b86f11291de000000000000000000000000000000001777ece357f82d7303aa816237a0dbd3a1398574f4061dd2fbf6b32af38a65abf5ec9bc53bb8ede932db9cfa0842d53a1a0a832e5bbdf897553c1aed35fab43aa3f4510c1782115e14e5d56229de2dff0000000000000000000000000000000002b41743325db9550c3a84af80bc20c54b8b0b685d7f84d05d14dcabed2f450b91675aa8c5c650eb81151bcfbf1603b4000000000000000000000000000000000f3d3e69d475fe1d4259f18f193cd84a90b91589a6502588106f0a577d1c1dc4b2feeec20a4fc30b3e403d6ca9e03894000000000000000000000000000000000c10e2bd1335363fe958eb50981b99bfbadfd1c414830857b5257bc8fa6e26b50989d9adb5b3a2fa610b3151f8754309000000000000000000000000000000000008c825371319f4ebd684f76b567c4e9a389dce96068c101568dc8cafcc10896e3c20202b591a344d9a1c1be02310be9b75e0582e9ad7aa4a02ed5ffa22e55570c9f20e6a24e2186e8a2a2f838fa45300000000000000000000000000000000101d3f92fe64af93468229608007f50e3406719572acf265fb8b2a7051525a9cb67cf2e46fc8e098cf081e73f3b20c770000000000000000000000000000000017b1422f8208c2521e3896820b22a65bb2a9b47d7fdcd2ce57196123c1ce43c1db6d00f236d7582795d00ef33ad6d585000000000000000000000000000000000e261500a9c64f5ae107d6ccb57fa9151f5321ef4e80f0e271515f1eaaa5e3714c59bf97b39acca41b15d90c0505ba9a000000000000000000000000000000000c08c955b6df18444ce3726711d29c2088721fa0aa6e317c52a05f73ec7171ef8bd61047174c74afa1dea804c68a28e33b7252f8f3cc6341d490c5c4464bb36e012f1b05057f405aa907ebb2c983f646000000000000000000000000000000000985cdfb3934e0484805a1965984028d6c459654a3eea6ef66e867dfc737e1bbcd92e31020d5a4ddb7f8091cae2371f8000000000000000000000000000000001998c5682209153a261bf981e16bf1f7a6f8e5e566c1b0f975253ea62439e5b36c5e5060751f21941edf0d348bafd18a000000000000000000000000000000000c8822c1d6412bc45fea05faef33c65d5a6dd13aacf1279b9cfda2a2ee34df3146d45e3434ce8e5f242e9cf7d3ac27180000000000000000000000000000000019191b51d6664a3047aeb5590df2939b2cbb115ded70fafc2de4c2e8c2a955a957375314081a8838bf89d5a140b7b915f10427f6e461e7b63b781e116a4d5136ddc79ff86b71fa754f00c797c035412b00000000000000000000000000000000156fcfffbf01ff3c8a97e7bd99e59327d38c6f7f1083d068ae158d1901808b3c9ac96f95c2bcbdf5f74b36dd8ce58d7d0000000000000000000000000000000014c64256d1cce124c01fa727482caf8ccf007e4ae00e5277d984f31a11ce584e7633565c61d47bc8accdf7c28bb266b200000000000000000000000000000000052dc9f7fce4859c852d3d9e1e77bb7887ffd35d4d550726632acab3d4303ecf8b3ec7f4114dbd590ac20d748570899f0000000000000000000000000000000017abd1e5dad7ee06116a8131c05c9b48defaa92efc636ee34a2970d701c02b6be0345a58cd8749e582ebd105c02f10a06440c89f8b10ce15806938b7ad65ece194d2fa3cc8d7d5591bc1d52d010896af0000000000000000000000000000000018ce0fb077dfefd57f7943d432e12dc9bf92dfaa30f8341397ff8906b1abdf0c02b599edf85ba1e5bb6287aadc72d7a50000000000000000000000000000000019e5e9e3b0632ec10a26b7c1ec40248a9a8b230806c38aa24e47489a8aee5abb5450f6e5679e3f13c6ec7a79560689050000000000000000000000000000000006e257a74f45142817ea8044f403e98c99db8355d626c59e1d11c6859eb0dd1dc8af389f07562259c1f85411be6cbfe2000000000000000000000000000000000f463e345b004b1364894c6e8ab5d35bfbdf6b7544a576ed6b5c5398ca2074f67e2d80af1ff5b721fc126d3afadff1ef43f1bb26469b778edd10127e634fed4d749e25b41d8eba86eff2c068c33e714f00000000000000000000000000000000174231581338fc8c461c981d4949d18f5b753d27184ffb41568f11e178a271bfc69f8c73f2daed0fdbe5bdc7fdf8ef56000000000000000000000000000000001532474399d6a73501801e5f3fbfc6f13bdaff7a3ea7634568fe82745752ee15af23b16809be18788d295e044e29c05a000000000000000000000000000000000912eaef94ab1f3b3257b26c5e8bbe3f99eaceb8c7ae8da577ef98e24f3308abe6e6005ff674a2af01b4242f8ff87108000000000000000000000000000000001925cd635d0ce770f4925a3117721e96c316dd96708b096901ee04ce02e7b357428e4364cd488eeedf76352a26cc1d10a40251ec7a7e9f7cc29948b122010d9745752df3f4a9c67427a8b58122ad4e7e0000000000000000000000000000000005c4a7f26ef0416f34750badcbbb3bce075606435ee7f69b3589e21e37491f0b4a7a98c825ec222848f5e29618828258000000000000000000000000000000000381c5f6511c9f06ea1a76ca84adab4a26a3cde13e0825b3d81899d6ad3191628894d0f57787f854aeb9e4c57fd15d32000000000000000000000000000000000bd706a5b5ef0d4ee1b679a0af90c217ddf9242b7c39523c39657962952dc14e5e07d02154e05693bad08bfb24a2b19a0000000000000000000000000000000009f28a84aa5bd39eeb09f13fc8770fa7e2e053b6f5d7e6021da77f48b9c3807ad917ac671de88b28dd343c2847c5e8eee03e5eb477506c397bc1a5204b30872085a36b65b7a8df3e0e187f3022736329000000000000000000000000000000000a8ff1b15ddcc3684b4d4ecfb53473497feb8a04660350ab84e5719fdb0618d61acbb555174b0900b32341154eb7bec9000000000000000000000000000000001464d21df798c0242ac6aaaf3c579eb66eb8cd53eb1e5ab2727298ca61ea8ca4c7cf815bf5c9f94c2b76bf659a4e2da50000000000000000000000000000000003a25752a4360c84e9353b7f1ce74d5106cbd637ec5ecb03dd0752660fe5c7622fe2d0475a4db98f785307c6961f14b000000000000000000000000000000000163601a86f02900d214ff8fbd041934189503438c557138b6ebaca8ce3c109af50ac28074223fc81d6476a3a99559ac565cb04110bbfcdf00616c2826e253f61cf955756e94dffcbb6001f59ae4a93c100000000000000000000000000000000189597e6d618a20ecf9a87cc70b3e0eee69ffa4dba75056ebae93cfc3c2ebb368532b17d9f6c06f09e44d9f101397b2d00000000000000000000000000000000086ba610e490588e9385c8b6944c2bad1eb03058e927fb2f9740dbefb779bdf669a51af88b45985e8345b8cb168c13ec000000000000000000000000000000000db8b9cdd4a9bcfc9f7de144da0b33981e4dd53744cd260c4bf045d643a4ef5f25aa19edab7be0c7f8f5ab74a4b7f1820000000000000000000000000000000010198384a646807b16e2ed9186aed99ca3197b05964dd0348086f446d3ebb847907624f4e02f71a1e866d17a125e07e93ce1bb7cf7d7a55f0624bf5c4c35327b178923d88be748a9b079720c27b500e6000000000000000000000000000000000a293f07dc3f0da0da4bee671951175a4480a719d44cad3d627878ad2f17596f0dfbd6f43acc7a1f9857c5d1f453e5d5000000000000000000000000000000000be6382cc7a00d590f2aada3b4b75f01f8538caad2ade90227ec71e5661ae353e68789807a13f28b23b17dc0dafc19b70000000000000000000000000000000015a9ad5a6f1a511ffe1891ce260ce442996fe4d8515ca593e3e869cab9b18af57956b1daa43aec98a0281143b0c319fb000000000000000000000000000000001807a4ddb73a9aee58b54bab2b878bea8429cdc91384c8fa533a8c9d15c966350e892bdfce16d37a4048a763cbf25d71e2b4c64b363efef0c5525b0337bf407879755f060af451075f4345dea7e681a30000000000000000000000000000000015aa6b865796f88ffe770bf25612ad27942213131c566a446dc149fcc70a018230f1cc8b20461ba2c55300fd27930bb0000000000000000000000000000000000c39c4f229b23c0f65ed720d655121eab50f695864959a2aa49771b848730494d14597eb85ba35743f64eda897f95917000000000000000000000000000000000ad44cafa754f06e45dfab801998c40e5a9f56e4add5c8add1d7ed9e05d12459f2efe3f3367cbcd161f524c714f7782b000000000000000000000000000000001437b1f1a1399ce2a860f7c6517b14a2db264b2602c1c57b8eb04e165205842b483497e98e6b6f8a62e25ab8b0e722f04c85e47ebe2c26e0aa25661d3353b5d88c632182aaecb35303d8d47f01308a0d", "Expected": "00000000000000000000000000000000077b81fa5997de07738e1b34d8e17ef4a9bde516577a4290253cc759ceaae745e10a457204b9ed0069942e0b487d106e0000000000000000000000000000000015e79be67a752a46dd0605e9d07d738c5732b2b605457ce056deaa1f7093b0bdc91b4c81c4c5462a51bc713a7fbb86c3000000000000000000000000000000000cfd2e6043263bda2b97798e1a7dcb24c63aa7197f2749f92524329e97f93dcb56429d82c1d63c067d7ceb38e6c65b5a00000000000000000000000000000000026f352d2f93e6407c59d58742dbd91ced464a3746dc1ad9059e6bb9c146dc1e74235bd54b1d90bb3399865cd3102f3a", "Name": "matter_g2_multiexp_40", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001387fb972f997ed0cb97a5ccdaa759dcc3c2c7f4f15e5cc4fe74685e42cba75e778772d795847b45f274d32cd4960de600000000000000000000000000000000150b1ad31a3d434c1cbef877fde2e105d4a047dc34e3889d21544c2143e7b41b8e0024443a774bd1e09438293860a43f00000000000000000000000000000000065033cee91f5c4d429a074be3d2a8b001892455a11dc708ea73c0082bedb1cb8e8b567a6ea68a1296ad2b80e4b5b08f0000000000000000000000000000000001991ff6fb57e8cbf9d228f1a99697f785261ebce9d3c1f592389fc860b8d7a069896dd48debb8cbe0c43175cd2ecfff5bc589e7d89994400c511789cbcaea19b077e0b02d625e549bc6f2673ce40128000000000000000000000000000000000a0fa2d39d868737b9a0526296335256ab4894cc58ffd80bc6334e80d1314bdf017c8226b41ea135f6adefd07650ca1c0000000000000000000000000000000004334f7985211061dedc794ee8931ded12acd39d7e6a6ef44a749118d19ce8204d07935fe62fb2a8ea4f68f99d7c5f5d0000000000000000000000000000000018850a3fc8c851a06781511faaded1ce0752e7ef66da82c2464eccdf78c32fae306da3cfedaf76dad371cfbe012f2bee000000000000000000000000000000001296ca0b0e368429b122537b096fac77d6367988956a7f6cf70c7193b7033ce42fa0cccb8b84b9c78b16a68fd5f4c14c2c3d2a0cba111642a6354c117d494be805cad5b5c486bc47906a2d37a9cd9f850000000000000000000000000000000019deb7de7fa5254fdf5ef34fa616651ec70548187fb0bfae9f512e0bfe1f662783f06a9a99e434ced84229deddab9d240000000000000000000000000000000009c199ef916e6f6fe0677ab07beeff221a5687fa8da3ed3ad99a950b7f27159f857d1b561006bfffab551d240b764fb300000000000000000000000000000000148a211fb58b38072cf7c417c70d3ef92e9cbe22b31b2b626198add01dbe1ccfec32d333abf42140b9316312ac48aaa2000000000000000000000000000000000b551b57045365d842133e46814d5d0084248904960f8d2fb28e9623660bcee658582928703f86261cd70e95cd20cf3a530ff74626657262fb49460b2c6981155871f2eb5562581a74f968233c3cbe3d00000000000000000000000000000000185959a297a8f434cb9529a1f7bf9009fc1af3d09efb0a9dce1b9e7d30699da64e4b1d32cdb05b068621db092c1eb59c00000000000000000000000000000000106ef21e9031d108364e93ae4b5d21b0d6d78c2e86e0f8a7af27ed3d38dba0192954e8c716665333e5dcf21387d3f2b1000000000000000000000000000000000185d21efd7d613c409b6ddaa66eed70c235440974b2a9154f3711e3969061461f8824b4547c65e9db09ce875512ca2b0000000000000000000000000000000001aa46b22451afb12962bec5c6309feeb4acefdf3c98c1ea14275409b7111aacf7c92a8e024d01d4dcbfb1c91fc445a1d182ac912b005e90ab81d4f2a906da8309a69576a8afaa160fad2540ec049913000000000000000000000000000000000557370d81bc3da4c50980106b8e65ca2edc757a475194cef201c9edc0f50363cbebcf2750acab0b67e1020daf5660e7000000000000000000000000000000000462f1c1379be9bfed97a1a83a00428de63eadb6360393ba162af3762a99d7eae8549d0cee218e469e4997ada7b35cc00000000000000000000000000000000008aa5ead309fc703f6de980dd43c294530cc2b38b94d5281e9cd9b0d09f82f747a7107b700f1437f3abe36c01bcfed1b0000000000000000000000000000000014110a19d574f26e11e2163a981c3388c04854c5693e9033a474f1020d5f980666d84c60370950734c46663e194bf0ec42a002a460b51429e25f85ec4abaa580ac1a14315b1627bd52349b7b81a641d60000000000000000000000000000000015beff8cb3c79098bc73dc1ea4b240a4e0d094b3dbbd51592df6adc9c9847beb436ec83df6c55666e296fa843298446a000000000000000000000000000000000943aca2a6e57e9897ec764ee2911d9ff0a59d9e903c70a8494340cef2143895e79d3e6c03af2d6461ca199dfbd0ca0d000000000000000000000000000000000b812ba87c4989af07af44f3dfa87de119fea28ad598cb8e52247cf41bb8bd384c0d8913fc82e4cc2878065e797cc581000000000000000000000000000000000410ed148d1e354653f9d9d17c50026957fb03fec64964f2bee5eeea966b430e77f7b3538d9f4700a673fa07d0daac6b7a650dd3765032ac139d1b54ec7a5457c9e3caefa6af45d198433e5949d149ad000000000000000000000000000000000de0a9bbd63c59767938b555c7f9284d0885ca23019818c213a7d4f1594b028965da871cc5818240d155c05c69e4e25400000000000000000000000000000000079dee5649cc67700e9338799a9810d352a5c68098d0676e42e00bac31f37513944dcf47408288cb7f1cba121506a10500000000000000000000000000000000101a650e84352aaf3817b400da0aff40907aae3d2fcf16739f8ee8d5bfc62c2a0dd518201701932728a41134ea3f6278000000000000000000000000000000000f1f9dcc0b55d0ed327f667cebc052c4b6116fde5e3076dd6e447c3214d4c8847885be9547f95f341c42e7c7fa7e2c71bbedc44d54349cff199befba9531dd4120a51e2b830a3e356e68cff31bbe365b00000000000000000000000000000000148f706b4c93e739324e5db40d42025535cd33a32bb3f211add618c0e2022068384a5612da67150746896a2813a664e80000000000000000000000000000000007204ebcef495ca8232078fbf1539a4b46e89506a09dc008da457dee2792acafb6baac4f6cef2de15cbeb48bfd12bfd6000000000000000000000000000000000bf8900e48a4a56b653b1e02c3b9a7d81c2045dbf6297f1ac2acd69d1bf9e06480ea917e3a616243c3a30235abbc426f0000000000000000000000000000000005ebe0ddf4cd1aee76d0b3d03eab754664c8b36fb20ab1060900909e0e0a4abdb45bf74a0b1d40fece9bf73360f580bcbef3956ac71bfe97029b8e3f85923c2fdf9cf1ea6582b68d5a4eabc6b044c80d0000000000000000000000000000000007824d1c48bb2cc0f406e356f6e52b66392f6203f49dca7ce03ae6302ce3e8055d071cd812f97481acc654b318d6cae2000000000000000000000000000000000ae89f9eb1abe452efb7ca48f8f939d835f9a79e05211ed9f4abee06b93e34b17d920ddbca3d8bf18b96c3705c1a064500000000000000000000000000000000119ac787a7f3e9b7ee34070aac1a769430eaa8cc838f1752b573ac7f3c02a9f490de9600c856a55448598b149f5392e300000000000000000000000000000000193a3655a80e6e0b1278730600fd4f645d54947d193484131176b890ac197702333ea847317568230ad8af1280864096392f5b4291fbb18a93248e830b08fadbaad6434040c02b45cade73b77f22c2bc0000000000000000000000000000000012f66629836f0f57bdfd9bdeb2c9b7d6d5dc55c586e15d76aaa04aef06722bc8ca156fd1295b3063d738a85b3e8746d900000000000000000000000000000000097825c5db7289b1b9e640d19ecaaa81ee59e5b9884713f6d312604d8ac367634a264c316d73a9cf63358c8fb15f8c5700000000000000000000000000000000181133d027b97d8e2bef308a93b7ea2a35824dc7d01a3ed2f404fbe12ba3b3e51d94ec86cadf3da7dc9ecbaa23b411cc000000000000000000000000000000000a28a609d0bb015e375e74c087ce426dd3c20fbd8b374d3817c626faa81469cfd11a2a4e418a44f4d7ca621d0564bc4920a96f963375d7a294b584f2da699a6a00eb5781f46830987346cf4fe922a2f6000000000000000000000000000000000feca6f7e3cb286090fa3df9c5ebd10c06192fe14af58d46b827acf48fbd462f3f76d9d20670803946028437410ea52800000000000000000000000000000000183dc7085483bd05c27691c25588e33296fb610bddaac253af5b2262db38091650c1c3185d71a69d1a63770f95f381d7000000000000000000000000000000000189f9b9ea528bc2377ca3354fccf440fee059f5732dfdac320fb58541e74e444dbdcdc008c7b47681c05502f0b302f5000000000000000000000000000000000906162085e0e299a07e41b9d62668d4810b97d4be317bf376da537de7adb06de011f5f40af834593761b774771a80e4115cb4646c8996239f4fdda8c27a335361f0a19550d6eb0225c008408c47258800000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb0c8a8d98c93c392aefb64ce0c7ea455ba14c48bfbad0e3dc38d43abbc3276caab0000000000000000000000000000000001d04065373ce5d1ce47e00476f07708bb028040edb9ae7e8e00e2c6c460e1ab8b730ff510a25a3c8114c1753b7bf1ca00000000000000000000000000000000001c87217f150694a84a4e5aba8d188ebf7224e76b078dcaba4a91de6b4ab317966ce1a9267a5a27ce556c3386b086620000000000000000000000000000000003c8422590826e0999e7ae3ecba84edaed20fd7f1eba02b9daf1c46c2aec74d5fe63319047d37f5115f243ae0ddd4ffb00000000000000000000000000000000136ae093c3bd55ddaffc2494f3ba8176947cdf2f1ae408e7e786b23b6a65ba8c4131c83cd890386ba531b8637b3b042c8221622734dc6ccf6c7b84b387a3dfecafe187dab70ba373b4416ce3c505bef2000000000000000000000000000000000d09b92a559b8efe5224184fb4f43779d0b8c8f23587f4f74e2fc6fb1f94e8d2e0d591eb0702cf51a9eb402e79b46a0a0000000000000000000000000000000014ec2e4702f1ee1074cd1ad29791cf4903357e62570d16ac80c5e8ff73b255ee03a5ba070091cb2f984b2139de06a97d000000000000000000000000000000000d22fceaa48193756ce7331952a2d9a8057b67bede729e07cf8422bfc79f9ed2aeb99a9227af256deee9f8a6f227faba0000000000000000000000000000000015d9322c3a5a7ca404259c4cc7cb93dc3d46dd8dd9475756d2ce6fea527642f9230c7e94a804ecb0b4adec7963fa9cdcd3d1f427a25f5df025fa71244cb92dda9391d65b04756c41de0f67ea072c375d000000000000000000000000000000000e16fee11affc6714c7fc8fc5e7cce44d8afe645861dd2f0b8e58aa93d4f0de9b7e73020a1537bfbb0e2c8327c4aae03000000000000000000000000000000000b7745a4aaa8ab4593daa61e375d55f9043fbc7385ff229889fca514562168a4e769c5eeef4d564b41cff28b4efdb7bf0000000000000000000000000000000017f6c5b1fb00746b50ee4c7c743ae57fae2742617e5565241d012a0ef6067d9ce59be749a99886ce9836b648525d2e92000000000000000000000000000000000a3be81720e80f6aa0570c89613c78efe95d87ccb374e7f77065800590bc71d23ae097516ae1e97b498cd233221cf717b55c943fd9b11f2fb8a89f6c08a6eabe9434062354d845f1ac740e6043443f8b0000000000000000000000000000000008080a7d91caaf2470f9632575b43990a9523219d75994f1944979ed5b650be1e3c93eceeafb0875f66a40651f4c6dfc0000000000000000000000000000000007a19c4a6340e39230a33b12fe63e47bb0d1378420ec9e439f216699e512e4d70571a1670eaa6b60a5c899ac63360a250000000000000000000000000000000016898d22b2c123003480e3a01965a72de94cdfa39b20898c49e451dcf6a4727a1ebd629172aa1a1aa6897916cea192b4000000000000000000000000000000001217a373c78de9d3005690023b9e56bbed3073f13ca2408a27a3480578d8013fb9d3ee5cda95c3cdd091a5cc68d928da7b0c1d54e51b8572256aeb72bb032a5011a3e8ec5ad7e8b6e0397b9f6fc64c9f", "Expected": "0000000000000000000000000000000005829c932c80baa420602bf841ad9bb24fa25c61f33f5d88693207b81271c94eef54bb524aa830fdad8caf8c082bd4990000000000000000000000000000000000b8d184316c2471ec6875641ea83de4f9b7227041922415b38b07a0704d01f2585ec2701bb4ae0bf6a0c0522efc0c630000000000000000000000000000000001dd81e075620914254b38ca5a7287eb56f2f31f6f8fe02fa51488d45c7f4609bcf49972d0ae5ded76eed5a4c096939d0000000000000000000000000000000008067feba36999b58342ac54e48b0fe28245f8ac2498b60093082822d19854df5c3168dcd55ccb6b2cb397b77e712333", "Name": "matter_g2_multiexp_41", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016ed84856b9f41be9bc6c025a9b79e2968e2ee6bbc27608093256c541096e2c9eda1159e6dcdaefe783aa59d52f28ee90000000000000000000000000000000014aabafdfe8c7369f93d5472a9c6c4d426e4b02c943488be993d04ed24aef5477f6d455f82b4af78381b8bd16f42b56f000000000000000000000000000000000af34789c6c923103633e5b1b9fb447b671ab05265c16488ca7224e49db21973487a5d3de4de40b9d8a97ac9b1966619000000000000000000000000000000001123a6601c5351a586f27f8264d4227f5e1df868a03e0c3df5c148cb523cdd178f96fbe52464fdab210564dfc22b29536f082a5ffb8baa38ffd684a4a70114343a1e723bfcbfeb57d0a85ad5e592d7410000000000000000000000000000000011b82d78cd9b53b8e7e5c14a7371f34f08546896bd59d1e7d8be15d21742180aacdd01b0d08da2cb24873ce75e166bd500000000000000000000000000000000161ae0d724085a6e801edf73443cca87995c2d6b37e962db5719f4c480cb830e379fa778fd2f29e75173e1c31daccaee000000000000000000000000000000000a2c2b89d00b7d19f2b0530889905c30cecbd4ed0b56ca82208d666e7576c32a6e90cf867ad87f19e4fd367a10c449a2000000000000000000000000000000000b65c0226743b573dad7ff25bf1885e3dec686cfd5da2862ab300fde4fc8fa9b587d0f2d11ebe1f6a6770bcaf2588f8f5160286a6d23c30595809dab6ee6523d7d235114d1b295087e024b4f6ffc80e50000000000000000000000000000000012d4f299998aa897db9e3194244fdd1dfb95225e3271383b5cc296bbc51c4e1af52e849d8244f82421cd198158918d8900000000000000000000000000000000110638a2f7cdb7104de8fffe29be32610063bc656e13168921501e1614f282bdc9fccff4eb3c479a42b240a2c8014864000000000000000000000000000000000b0adbcbaedbedd376efd20a417bcce562b87b7449cac1e90d44eb05930e6f558b35ef755457305da012a231b5675bc2000000000000000000000000000000000db6fa926c7e02f633730569732fd9239bbacf2042599e79a4bee76619872901c6f4ec4d4fbf3f84143a0d17b167130ebbca29b94b6583d46753473143d13a7aadb0b18d6d35d7423b8a004991fa1ce500000000000000000000000000000000166578f3087772545c0f47fe0b3efe32874d26463e4f262be65a3bb6b0fad7d0f779808f69362f3fe63c72f24ed03d70000000000000000000000000000000000a8e61e8193228fa1825cf14e94f68a5eecece9afb48b44871c5ad62510ee1fc4e9c60d5f2529b8685e6aa13ec91979b0000000000000000000000000000000008d25d81bc4bc92508c8cade33c305c11d71a06bd46f184b05dc406f0939f0e0967b02f15b4f7f6984c9fba0644ca8e800000000000000000000000000000000113660a7d2152346500a1578641aad4dac2919ce63d01d8ffa6dad72f524c888fc2e9d2876859859e47d8e884f170f86607c80069dab2a16e39370de32df20534aca46565cf573159a93c64f1f0c4a1a00000000000000000000000000000000160529ff217934c85cbaa8b347151539e252dbb502c015e8e45c128df2b8a737866737d5cf0eca6f76e4a16790cd02a200000000000000000000000000000000127f7b0e4f9351836db9c204386a199293955471dbcd7b4ee9186f0434b46dcacd1edc02fb46b4c377c4e62cec10cd6700000000000000000000000000000000094abac17b11600d7447f7ad0f21d98c14e439c4a4a6572b00c90e14d9fc54e85045d0576f74b054d384179afc0a70c80000000000000000000000000000000017165c32410a498add8e1dd55ae43f94be234ba3859fc6b4816d7436746add313f42b1fb49e0cb6c4b7341f0acd09db841c1f256e866d218b3ec20c132446945177d518573ae3f0e739ebcc8821bfbc700000000000000000000000000000000060e503ee1c5d3eae4bc0eb30fd86303a5c48c10cc7b4736d17b8774c78a8c97ee05b40d366b2cc9bc7781b1e4a192f200000000000000000000000000000000034e7012414edfc6a8f7b2c6049236b6fb77eb94b05d55b218851fc1e553514e6ad388fac08a24c33bea63ddabdfd8720000000000000000000000000000000004c832477a90683d417a00a698b69c643d6dbf82f5afbb83eb3946f8098d80de6f2d457c0a06d0051315f06e93b5e13b00000000000000000000000000000000048c3339996948974f2bac14d8a6b8430897644ec8e9cff9eb369557003aa2827a4f3fc3444c4df73663ebc9325ff317c72a47e2267010c532d676ee3c3ebfb2be2b7569f6f7a22f76733d7773ed383c00000000000000000000000000000000082466944ee7c62788b6fa77816094ea623d03c7aa2af249cfbfbf78eed26a76cff8c23c2295aac7ee1ef8dc84630003000000000000000000000000000000000a8f88adecc3f50d8eb329492f2c031e722f36627cb3b21415781156ef44954c5b8529ceed5978a37ae1248909d38b5d000000000000000000000000000000000e08f628aa014152b50a85bb6eb947d53c596d82c0d03594ed3b64c486b8630c880adf43fb1575b02e4eb8174a04034c000000000000000000000000000000000776844f28958d3e12a5c163dbd039e50df44b1c6215429381790175a609a339621475a5b9a06c3276c9177d2dd2b576c52f48e84a68d99124e678dabaf376c956dbe9603974283a9efc7c27e830e9590000000000000000000000000000000004477f153c0510d8e50bfdc2db69182c05d5ae9b94bb1880de239733e380e03d50001378432312b24b5bf0952c38396c0000000000000000000000000000000016663990dbe529a5658f2b3044bbd390ad430adaeffbd5306f758d86bd5422391bfa1d21e88c63300faad55e6a2d1d3200000000000000000000000000000000188f701658558033ce2c41101a611f74ad6d3cd075c195476bd2cd59a1a9dcfe937020737250fe418b4de435f8b3a0380000000000000000000000000000000013f8d3625309767841603329f56686a99e196d697802cfcf31f8b48f9c76f77a321276a0158a22b94e91d6907f6ff451e4fe662495bffd8ace4c1ddb39e612b361bf90a0f1bdf6c7fde2bcf63df1bbd2000000000000000000000000000000000f184d22f3c0431b031ee0ee7ae9598ffb511a2a56f5c9f15c9a4b0c53af2a10d22a311805786e303e234239326dd74b000000000000000000000000000000001062725b8c576e79e314f6a56ef9c41f05a65d7d0d57d8414e2ae9cb1a520b16ede7e418d3a9413c9c1660dd7508d5860000000000000000000000000000000012ef02fbe96f9a191804b6c4a0b65b6024e3e2b1f8cff986f5a950cde9a32ad50d4f7a72804b2d18b93250a63a7ae97800000000000000000000000000000000000b3b0333d61fc46653a7172f5a813d13ff5a48056f9689c78c4b18b8aa3afaeb7cec305d98dd600786351338a2185a651e67e96f64b80f4978fdc1cac90be538774e34c2f619f8b8e60cd2aa20f2690000000000000000000000000000000010c91e1dda48dc528f618f01abbe01db1a7b6dcb0d47b83c7b7db3331f7156f7b2d0f081458241467b0078935a7b4a4c0000000000000000000000000000000006f87f782979d2adc02e65b56a4906e50430cb4e0913636e9aa0364535c9d7ecd3b9433358e00caa8e90e84b7705bdfe0000000000000000000000000000000004635089c7706cfdb5a22ef643d1a9a5021847646ef01ea559d1b655299b65cd76a73b04149adbac612e7aa756cf30060000000000000000000000000000000002d83d82bc9fd66c558e00547a8c25633899584c9b855195c00eb3c8742d22c601982f244a03f8e0c5c21caee24405481a6ecd3db89a7f07344b5728efffd35a11f7380c740669f746fdf565905a1ca0000000000000000000000000000000000848f10eeba8ef9c7fd0e679767f6b6a2392922092916da8f13573661f84ec97c65717e55c65526cedd59dc1e096f0840000000000000000000000000000000013781974518487de12661bedfca5fe72205c51cab461b5757ff14f319d081e7845cf8e099892ea85470039713e8e48cd0000000000000000000000000000000004cc1a27d1aa88484fed40ceef72e6bd201e5ee276b5ec27624286dee112ece767b37c6f1f7846d71cc0f4042f04dc170000000000000000000000000000000004f7335d6a1463976d9fd86e2baa45d08ec65059b14449ebe4aae99971c5666cdc6e40cf0510ae99dbce97ae8b4598067db5ef4c1c174c2e5ffe5555f54f4e845c463bb5105381fb39eddc01103b1bf70000000000000000000000000000000003c1b1e0848bbe37e62f1ebacef1a574400d5048f1e09d935af2052da29140dc4074175e4d6ceb7c2c071331b2f3d1d3000000000000000000000000000000000e1c84d6b20553ddc5ab09049ec488ea2839c5818e31455a7b231cd0455e2945aefcbdc6c1979821a80bb4f77d46e91e00000000000000000000000000000000199ebb31e8800395a9c2e103c9340444c97004186929b52de33cb8d9396e7ab8d5af3fe6035d4463701ea41e341f577300000000000000000000000000000000081b3882bfdf83e67d2dc42b211069a4e93c0f173263f9f20579128391e7f2de70335df949b9c0e9b834b6e574f2f8cc14018f14c50d40d3324952ec22ed247c13c4cf10eacd32c3671757bd12b041e60000000000000000000000000000000018aa45c6b3898a5fa618f87f9a08a7234c1b94fbe38e2297a1f9c7a2e9de0ed83023deebd56560b1928c012c14dd7a860000000000000000000000000000000009ab80da6c519aee8aa1fa68c35bd0fac78b55f88d861e8fcd445f629054325d63cc4241f61e5596dad0d54c94511e4c00000000000000000000000000000000105f8253f37f5538a2c25587fd33ea61fdc744a7cdf4ff23a55e2c66a39040d4de5eeacb7e11c0d2a483d59e7c3186aa000000000000000000000000000000000f6b10cd6522a1e34c87c702f58a07858cb753d67da9625155bd433020775351a9ec4ff879f91a43f63be1c969afe675ed4a28dc3acaf2220ba56d026b292a7d017bcbe358dedc57556cf638517bbb14000000000000000000000000000000001618dd5de43a6bcde91a6a03fcd88fe59d1c8c51d3d85cd44a1920dabd2608a0b17a987b76eb8f5b20c7f1dc0abb383e00000000000000000000000000000000198034b7ab8fb8ff267a52a9423da95bc587eef8684f18639df5db44e50bae7fdea5c5e5ef37ff14937f86cc948a34e500000000000000000000000000000000106d1f017da463176bdf55e3ada78ce70da4486be42dd0095e3a8a0f6e59ed503324565b717b45ee38d90dd3ad13c10600000000000000000000000000000000112d425765fa2fc28486b95e49db63346188fc5a6bd0b7dffa4430dc82703eb44d98d726edfa4a275aa5db5028d01ef530fb17a38b7d0888eb02394eed26406bce9e92779251bdbcb432153a550c0850000000000000000000000000000000001326581ac1a1a960db1ff2e8b89b1debaae46d1e2d0aa6ffc6c7398f207abb699ac59186ae7222b5cae3abe64cb61c93000000000000000000000000000000000218753594c63ebe5fe503aab4dbe1e944b24138948542c7c43d92ccfeba5854b7bf1bbcf8078d85fb0b8701b8b092fa000000000000000000000000000000000c3ce8c17f75e78a8c9980e9fe125290d377a32ac46411876ef011e169e86e1458ac5e71cb4a446f6c640cceb8d5617300000000000000000000000000000000176966eac1e20586ad2a03b4a1598b4db1d7c66be70b1b22833e4afe0e0b3783572f791ddcd4eb70a88f4acc28b6fc7a980b5873a5d0f78c3b8582581349498fa997fe3c6b1abe0edaed594253359d8700000000000000000000000000000000099ac8430fa411e74082cf3282f9a456d3826a7df4f91ecf621e645a1abc057e1bcfaf9ee73f149bc447cf4230f2f6c90000000000000000000000000000000004e93d7fedc9e2d7423c9e111b4674a2bd83de28dcbbcc54ce4b324c96318a11603fc9ea385f1c02364ab1f6b5458481000000000000000000000000000000000bbb29d70fba5b12fadb02a24bfe3f6a5362c71fe5f964dcd0e01442781d0462a873501029192858027d612a8572e9d30000000000000000000000000000000010daa9960005562ca2d18eaf4b4bf081f194fa824cc77515c81b2c836627f21b732448f367e2cc1830ad0fa4ceb928e1619f5719c320320a3c45dcd6207575e0d8527c458c56d3decf1d12ead8a985a1", "Expected": "0000000000000000000000000000000002a61fead6801f41f2f27603cf34cfb4b917f2f85cba1f9c684995227653c9dde559e1e8497234fba9b2e4c119cbd9ec000000000000000000000000000000000085f73b8e835a10bcb9312931eb08d916d2b93a1da843fa2f4530cdb26e93b5dc95a555dbe8e50ca465b162661ce1d3000000000000000000000000000000001442fff9019b5476c217ff725ad95c92c17b42471ed7bcc121e8a0506755ec279d4e56d770a322d56f56bc6a6b0a41160000000000000000000000000000000017e7710c4639d51c4a79c5a2791101b52742df202b1827192872f168bd21020bd068160a587fc501782c1301c231a0d3", "Name": "matter_g2_multiexp_42", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001213b5d5704c454845824994769c8b300676e75bafdeb95202001161aede276ab7967ea7362d38e97ca1484cf9c342fd0000000000000000000000000000000008c7c1fa04bebe5a1fb8678370563db63e7a10b30747c2ddeb4aabd4fc0ec93220d578b8110c6bfe8a3a6ea2820f0db8000000000000000000000000000000000c4061a295120a00de52300ee625ac46566464e6702489467316e8c182ca2168052c50b5962ff47285866c17d213fc8400000000000000000000000000000000086c153169a9ed1aba10a6cbebff4911b37907d6398c441ad47da17988d512d822ee36f5217355b93c9d6dd8dcbc8e0b119d33d32affaadbf6c2b6243bb7b344a971270b488cf887334fcb15de2818cc0000000000000000000000000000000017929edde8f9940826ed739bc9f59099ce76e85950698ab0140784647023f96afa064aa4a49b9728f496515a0a807e5900000000000000000000000000000000198d98f430384c1e7fa9e2403d9c3d2f81873fb7b204378cec95b97e674e10a1a43af97db0488209904469989ce80a0a000000000000000000000000000000000afc9b5138999bcef35613e38bff4f81cf532e00346f5205405470b2424622826c746ddf0369c7bdf77467dcea5cff290000000000000000000000000000000019ccc05724b3e9966bf918f01312c80e8422b697be89365b6ca00eb31b0bd08fae942e90a75bf9da1b3d264e416060f1f1d832b355d7e0ac3653431528ad0a8f6819daaa19292a00c910ff0ff39f46d5000000000000000000000000000000001568e52c2760d895874527d1ac8597730578176bdcfc67aaf69ccda253f6616230811dac59bc27cc1e57b94b5743cb3f000000000000000000000000000000000a4ddeb8b56f105ed5f47a538052f3d38a23c0ceaa2dea241554e6508f82f47d32415ffeeafe5ae5664c936b78e07648000000000000000000000000000000000b3b335a390aa0090bfd6467d6cd02eea1ced347cdce3c9ed85dd46e38e9f2ae9642392c2875a27618ba8f2c555d5b190000000000000000000000000000000012baa4b29d116eec749353b7658af70d4d216189133db707e56068c8483af43ba86583862e6b39df13b88058536861b9e6dcfa50f6129544835b5a4568954264ea68d9e2e5d4370ee31026997a3fbfe90000000000000000000000000000000001888b83ca28c244a6178377b4ee6844dc916e28c3f56312ecc0e29d08e6254dcda39a36ccdc317d1908303db3c028dd000000000000000000000000000000000f4b73d9316fee42d60f8de402a7d07765508b84d8f2c1be1f3f9e802ed7b0c6c5fece3db95d5287225026e73de98ea4000000000000000000000000000000000f1b48122191e1bc421881de831293a80566b9a7f2c9836f7718afb69592d59d2a714cfddf88945b94fac7a50b743eee000000000000000000000000000000000f1c6b052dbd03795433d7ad122473f109484d50245021c8727d252145e7db7dadc015265d1547f9c748409d74f5aa33f7822767391d3b2331e8e1b81c659c6e0262f7355063decedabac9797a84f0f400000000000000000000000000000000011e8613c3a771a177b4b85f0c6f97a53fd7900cc23566aecbf115058d2863189c21be36dd5dd736f6d0ffbe88182b400000000000000000000000000000000017b2c4e8d8aad0a12fd7130789188bb63a08f2b243c8f7700599dd33d7e176f70f2b1818e56540ab3fa507878d96a46e000000000000000000000000000000000e2b5ad5ed3578dfdffa414a4a2142846b1232cd2de468725283e3f92b536d8ede74bacc236993f6f68a16fc6a7828d3000000000000000000000000000000000fdbf06ae4cfedc462f5913bba9bba2b5c86ecd0e298bf27a21317fe74af6ab15014c62cbfb617356548cf808599caf4b1ba1cd6a4a6c433624dec63547119c0d492e3f38afb04e5153d82e400631aef000000000000000000000000000000000b48aebc6525620b99cd83979658a35afa233d17849bd0dcabffcf3b550f875a386b6c0b4ddacf18a23843629072c0150000000000000000000000000000000010432e5abf862d3be10ac5677b9f296ccdcedf1480e45de631b6bfec42f20edf62034f7205f659f11fe5a6aa9d882c7a00000000000000000000000000000000011702a3590e7aedd6948bb94bcc874e0b8d77a18126ed4ba3753dc98953ff941495486c14c6d801c71fca3564ded9910000000000000000000000000000000009faa427c0a7da26c92b451c61f5b5e8804fe032a4cfa014397e430882cbfcff81bb22f9c15a8747ef455773c1ef65b0a41e184bcaa0721caa4114d6393ae2251fed84aef57c7927a170145308bb136700000000000000000000000000000000061a1ee841251bad461f89c52196bebb1cb4463298e88abd62cccd21bbd325ddb33d1306ffedb2734be76c18d80c8dfe000000000000000000000000000000000d05a5ce6372ce34b0bf4b19d8e05aab74abc1cedcc35a2d1d4db38813d1e5c1375d63ca0e8bbf29c510a4319d2aec27000000000000000000000000000000000dfc57aa8de28745b8d28db3769ab5ea26b5115d3e59e51ff19af8ba37efacdccf763ce682cfdc77685705781c3924870000000000000000000000000000000018c17d87411c4f8e0ca51b3eb4c3765d3846e0d1b75574f8e511b2f3e8c5ff53bf7618959ce18dfd9e4c6285e88f094f63cb451d8eb3565274793925a1869ca5a25fb19639449c71a761809f785568de000000000000000000000000000000000a0642094b89dc9c6c7c11c1e57ed542982bd246112884969d424a3e091ec4fd73dd40a5ac116f6c68216fd1e733cdc7000000000000000000000000000000000788c7a63eecd1cbc26ee6b14b09d0a3b7a17a848fc0551d50cb7497bc98287da2d9b898260eb678a8a0f446eef5c6670000000000000000000000000000000017a1298f90022ddff3fbbcca180e3f4da8760218dba595a067287a2473a6e10b93dcd54154cb64b6c078b083b42cd09000000000000000000000000000000000116e999b808dcaea0566c0fbef1807e160612dce91756b2cbcf4883b04a90320a0759bba21b41e6f4d8449b52e52f9a96a2f94d55f784ebfc6b6260327372217d6a5b9637ea5f9afc1a65f99c221c29f00000000000000000000000000000000064c95bc9c0e2be48849a349f16713791c37310f71b5d0613cf0706febeea3a56a0f0f1ac6b504524eba801e8b759f2900000000000000000000000000000000007088d2f41fc7e1147b92a2ee7062b9bec194d3a47eb9985ac1ceeef57e1a006571e7247a13dc95afcf9905be57e2a7000000000000000000000000000000000e6a0770f4315acd9e410fe58395ab8b20a08240a6948b762dfbbad3414bfca0ced4ec9da982bc9b8798b60dde78a96c000000000000000000000000000000000a70b53a6d71c83971167afe329ffacdd417bd7b228766851c3b43701a439f253a8659312db7e83a398142fe19332b527d889a3362f551b88e63463b7f0cc334fab3fdd302b630e419e362ec1eaaeec000000000000000000000000000000000002486eaf9b743d3aa6a1f3e1174c5f213bbf3e3cc0558d63ce40e3c03e1c2f6e8508248bb649aae1bc92f3eb8118a2000000000000000000000000000000000042b03959b40eb0641d39117f7af50dc7ff048697a57b80723aaca164e2dbc647ffe78fea0a6a4c07671f7db6d5b2dfa000000000000000000000000000000000e141eab29f52b9bd0ee44861f154ec1bd30abd715935a7958a19007e789a41cdb0f4b9cf7b3fac0b0d4d77637b510d00000000000000000000000000000000002cc2eaf89cb7a04d425d878a30b5e2e9858ae0b2a2ab28fb28a6db0c7283ad861bb6a92067e969e5721b43466e857db8bdd400ad873cd6ec546bff698171942d536b94e69dfef4bbf316a471d4b45cd000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f63b496a64cfd15410192aee9912f869deea5a08eebd6b160667e12fdf23c44510000000000000000000000000000000007ecfb753be501d9f9b7ae7ceaabaa4fcb7b690ee04fa1a711a15dcf67e4422adef64a0f8118f93e67f24a2d1a2bcb36000000000000000000000000000000000a459e403d85972f7132641c05bb842416a7135009ff46b617bf0918e65cbbf33f76b98c10d901936e589bdf5de31ea4000000000000000000000000000000000bc6ec31a3ff92b4fae07cb73ad7bfa8423044048337b0ab9add09bf10fdf190a5f7996d157483d29fb29a681ed585520000000000000000000000000000000004c622e2bc606fefc8bd83c4a32f7353123205a6d3716b581c2c71360e5200ab069f60c256dfcb04b466c53cd61fc94470de38cb4627f53509eadb0918e562c6fa68a4cbdfa9f7578a8aaa8182f5315000000000000000000000000000000000125688e44f593c5f585765f30e9fee5e4f15247cf33ac78ed1744453385f49ac61128e23b1569ea33d74b207a5e72e930000000000000000000000000000000009d77360ea37298fe971569230159967012c4991255fb5337ca6d58cecc3cd44a024a9a044ac98a894cc97dea161844e00000000000000000000000000000000056b2dd9569f0698c732367cfb217af90a3d6dc15e2555ce0aa845616e4067a7fefb304f6525b539555a0a685f0ec5f20000000000000000000000000000000009acb138abacac351e03f7589d4bf29cbd331e93bf538578ca9466b759ea070931c786d35f74fad42261e2df431fd00316732c583e8049a5de38642cebab774d90d5f87601e3599ffc9af692ba532e620000000000000000000000000000000013515b0022ea946a8e679b9c0eac6cd67dbc4efc820f0b3d8984f12b7d154c0632a8d7207747284d49c498c79b6bb5c60000000000000000000000000000000004d6765ec6aa8744225c1e652ccddccc91fff7fa8182931c8648b3d8bd33b2177a9af03b2906da02bf117bea59aed3040000000000000000000000000000000006f1d858c4b223552f0aee466cff35d14b3ac6da35b8f482417e8f597514b065be315aec6662ea5c7784d3a9e2184090000000000000000000000000000000000345eaf0d72b9c11fe72261a2fddea318a8dab92a67ccb9438c11e61fd298a333cc42084d4ca127e09792e346cfe0f004a037e7562adfbad6b1ac48b8e4b6f277a788ea2f4416ed2900ed2791f09bc2400000000000000000000000000000000029ad10ed6d6d5bb591771cbd597a3a0b841c2347c89027126bfd1efee2ac403933beb99d08721232ab9b7354fcf9aa800000000000000000000000000000000198400d4e026c2463a07ba5a3974c869ed8ceb1f029bfc7f41b23dd7076cf4a83b17c27ad6506c852cd2cf7c4987f93100000000000000000000000000000000152bbf74cefb77fae8e825443e4ce09b4e223242187f563a236695294d0a5f540f0b29d6f93a54cf0a77900e936e61e000000000000000000000000000000000079f4759eaf044a80417345a1b4029f8d4cfc7e00fc625e815cb7daba2243a97d21e42b42ec968dc8647158fbe467088fa878f6a2e18b88d6badc5b42775e92c17974f3a18817b7769d44ceecac46b89000000000000000000000000000000000cf3148d0c30774104a097562cc83456d5d18643d5f7ad58aedd9327bf8e9450feee50ee893442b1cde87acb02b62045000000000000000000000000000000000011d4037dcc15d0c50337d71816a2b77428b8ddd530bc3b3c8550606229f88286ae94ba03578cbb5bbaf118916dddc90000000000000000000000000000000016160c8ec4e2fb780748aac279bc248b2e2f1092262f86d368d2f06a78ebcd27e929930c8f2be124e9d92dff5c6c6f42000000000000000000000000000000001980375281735390f48ddac9d00d4c6ee7312ed0797333a26a1684e09c9575e57bcecfc4a31b8d9597a8ecc703835e22c4f1a7d2b66e6202c957a649384cb277dbba769afd60708b457613f0f3372515", "Expected": "0000000000000000000000000000000019ff32d2901b7732df1a924eb3c099a9d36bf36cb32ab322f46a72d99d81c7942d0f2193a4aeb55cf079a2cc1707c7aa000000000000000000000000000000000193561d0433e1031fc51829504ca70e92e19bead2e0bad655aaffb6b41f5f75d18f04a162db7714f3f23da891ea91af000000000000000000000000000000000d010c36acbfb38d9dc2df6e6e21bd75deba5708fb1012eab23d06d78b1244d4daae38aa4f803d12441d91adfbaece7a000000000000000000000000000000001459ebfe65c3b2c9b2684042bd71201869db1a0248c740a54fbdafcf18fcdbcc7b677af43abe803362b462369237690c", "Name": "matter_g2_multiexp_43", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005b9860b565fc64146020647d1902e2a2d2fb2002b54bf5e21b6601124edf14d6e8836f938843fbd8c02ed8530953dac00000000000000000000000000000000104938181f16f16318d223febec3be3877bc57067fc23729d1f5552099125558cb21ee0eddc32ae0b0cc3555219eedba000000000000000000000000000000000211f809b624c4992a43e78a978ea32accf9e61fccef6bcd05155e52adbf4853340dfacebec9fa87e5417c045da25f9a0000000000000000000000000000000019bfe94a18da9ab4ea744389c17870ac96218d02178bf2ad502f166a3a1da8c14e3fc52038021503cd24042cde8f306d0241da9d8505208b4d3ba2521a42f28df7d06fc212e9e84931cbd30ae3ba2e150000000000000000000000000000000004fbb396eac2a1de9953febed9fb6e158a3b5a366f783d2105b562e8143031d7a1ef039e3fdcdb675b3d3aa4f4dcbe4f00000000000000000000000000000000155e23b5b70f1ce34fc229ad5c8bdfde7fb5dc0eca19596c658c1f8c38716a0a7b5ff59ff19a7a67e12760fa90eeafcd0000000000000000000000000000000002cc82cf87e7ac05be236104c1e668b5573674d9bd741f2d91d05c8a11af1f72aaa1dc20c73953fea38e6e069d2a43de000000000000000000000000000000000a7d1dcab00db0e7c0a239511d630526fb120defcd9453fbb57ee328f974a98721274144e48d22558edf25595b8ff4cc6fecab1334668102e47f1e7139059c1d715a1851a026a1580f93c2daa3f08a270000000000000000000000000000000010c9293b3c58d646a95c620a0e0a7a0a55cf43b4abaa0de1d5570fabca8d97c91afd67bd45aa234273715457da5a2894000000000000000000000000000000001454f8682f3736847cdb3f784a098f7c9e488629efc3820d49b36a2e928bbf736dcb3e1b30187c2c0090fff290dbf97f000000000000000000000000000000000a0fe3c635a81f20258db4f1031589afc8c7fd07f2fe1e5cfc8f3c40d08a958a3dbec537c51be2de99b849e006870b6c000000000000000000000000000000000728876e3fdc42273e8d71953de61dd5c03e7c31ab6ec56fc03cdf55c8f0aa4b4e5c8ed88c23c28568be0d864df026af4e2023c64a3b51cc3d82e262f83260ed4a5e9e3238b85077852fd501b52aceed000000000000000000000000000000000c9ba542189ec1828c397ace9639cf2ebbd1613356d8fb26d3c40dd00af1f43f5bbb25032561aeebba7b874bf39cb0d500000000000000000000000000000000175aa6e94a9e42cf809f48f51c48d60e74d61388dd217b55f3f63612c4565357581e5c39751a65afc3b7488caf5151720000000000000000000000000000000014c880d35d1d31793145803182584a8da003b0ee3c29c978b64bbfe4e1da82910a4539587ba350d393e1bf3169c5e4c70000000000000000000000000000000002a063b3fcd77180de632deca1ba89ec4ceeefefe9883ed9e7e06301a268bdf377c3a6e30859e5a39419e449dd27ebf5dc0a88f0aeb2b082dea6b50d591018330c2276830ed554840c10772403561ed700000000000000000000000000000000069edfb8a83760e09726f6d1c117d4bb3e499084b65e1e830ab30daf1625c37f851ac122f9f5c795912b5b6f7907ffe1000000000000000000000000000000000eb6e9b55869f65ecdf3ac46d0ee596d07c573f88724bcd802b4429392b9a56730a217a03286deb5103f70aba7a9bc46000000000000000000000000000000000e2803e1a646bd70c51806b676591b328cb20359aadc8e79d59e7c31e1ce2f1473b0b19f7a34f23aae09678b11b37432000000000000000000000000000000000b3c9fb5a39a6c40343259e12ff4fe5058f25619d145922e1d80c3f5d105a7495dd9a4da329a2e78afc31a87b2c5d5e2f68c9e76d9d8914f14007c968a31089041e67312c6a3e5d30e65efa55894ba740000000000000000000000000000000019da372143e30307a71c7b96ae0703301ed723814a35e270ef6a6b0c57144f494df1d3fa0ac369f59f3daf534070c9120000000000000000000000000000000006521d89d810c7542108de26bbc888482a3bcec8cb9b542db42d5d4af30d6c339a5b4e959da4f98dd6ef8075554f4017000000000000000000000000000000001387d9c684a0fbf615e7023c0f3ff47f4d2c5a9f748f0261656a09b23066c745420df0eb180c9716d6d0743aae7689a10000000000000000000000000000000014271b9d0b21cc69072333a6c03493321b9d9028149d24964a3773bcbe5045875c457aee11ab0682c2bdd44f098f363d80eb90c6cc25b3a48d93b94b698eff513da37210ba79d22d76a270aa97fd51070000000000000000000000000000000001dd881f3d2063adcc5638b4b3813a30e75fd308de3c9f42e5382fdbf097d5796ee9e03cb44752515b2459f131f58bb90000000000000000000000000000000010f491f4594dab938115343edb47b0087d1cd1bc12ef908e150ecbdb3a54d8dd51ab24a0e10c585f235ed99fbd3172270000000000000000000000000000000019d1665d452ce7fb6bb6da9782a55dcf12a1d9abdfd50435b8f2a1bc5b323c004fad35ff7e9aedfd414a9b68fb1eb1860000000000000000000000000000000013828087beeeb85e43e8540fbdf97af189878f5ddc1eb35c95aa06a26923330f3b8a2b43f835186865d6f5f6afdb2b9b067bfd893b12c79e13659ee9b5f22de71d806a85410c9a23dc43363915a606b100000000000000000000000000000000014964f3576b97c00a8c5f4372e2501944a1e4374a3c30e11376ea62e09d52d40d428887833bc2f06279b859c00c98a60000000000000000000000000000000019ed533a3bf469ce5b3e4e9035af177efe9e4f8b0a0e5dc9721dde49a7fc66fa31c8b1c8d5bcda1bf75a532bd2be356d00000000000000000000000000000000064ec4ed48d63ab62373adb7898bc904d246bf2b3790c3cd850524e50ec38e7fb4a364344a6a1dbd26f2ad2d0fccaa1600000000000000000000000000000000134aa3c6b72d39bedd8f9c619d206a295cbc05c611147d38aa7304e995089ce34ab1fa13c2d6c6807a88797dea20214b34abb11f7ed6d73fb81ce2777acd6bbe8839112c527ef4ad88b094cabdb4742a000000000000000000000000000000000a2a4c8b457d0d2554a2d439fd3b74b18843386aaa00d1b89a1c2d8ff7192cdd1d3a888994376bb7ddda4d16bfcaae3200000000000000000000000000000000155a7dc763caf6f0fe1ba9537c0f75d3e455c2d1c749dbb4aa7242b40a9740fe9e8e88af6017e8f743a9e4c5dc6ebc23000000000000000000000000000000000a693da3aee178e2f0489af77f671c734423032f30c0b7b48debd3b71e65dab7db12ab1e0e72d3ef686d6c1922aebbf700000000000000000000000000000000109c3476016884386d6206c94073c628375a02c8fcd3041e06b8b413508188a1d26ec5ddf84a77d059e9a039dc5470d08d6693acb1eb73f6ed1bb4f74f1062f720a7f2c0ecf2b5a944ff89feb2688e19000000000000000000000000000000000a07f457f5dee69e9ee746dd67f982914a2182b5cb2609d273d4122d57a32c195270c956361d78eb65449cf5e13907ba0000000000000000000000000000000011f149ce84c2a11ff818be3ff0f86c1b38a9555e169a8cf791c79828207b7aa89c84e8012a0c5d8cce4e89d758b90e22000000000000000000000000000000000d636e5b027e41809d7ec8bbbfd4bf641a56599a63a7678569404ec8d45c3b88c1d2969e6101528d4edf1ee9d8e793320000000000000000000000000000000011878eefa5ee49be83ea1f7a9cdcd4997ccc59a9669778b3f006429e1a22d3b2a051924f371a228856523e3a09bab59b29ca1b157e6a2b5b88d7467e851282491ed30382ba217b82ea5cc9ca0c6986930000000000000000000000000000000019e9a1950f663b258474b24c334bd256d3aedcd26dc971a745857bf1fe007da0aa00777db5c3e5d21294e99862bf8ea1000000000000000000000000000000000329a12fa0add36f259e401442bbe6e5f9139e4a46d5d091a2110d2561b5629211a1c1996f20d19327d1782340e7ce4200000000000000000000000000000000032782c94c6e45a88425438324f3a24ebf37f0be213424b1be52c878985633950a022f57f8d64af1470486aa3744f3f7000000000000000000000000000000000631556d52fdcee3529023cf20d46ea09ab3c642a7f4eca2878e4af88801d21b80b829c9aec9e73317252639c148676c40bb53575662fa0b726469da01c39df389efde3936d2eee18d7035704130ad6d0000000000000000000000000000000009eb122c61ec44afb56b64929040058a804311e0e97d3fa513a162748091304233480bbc883f6fb66080b563b308a24a0000000000000000000000000000000007d1d810fb8788b9f0cd04235771d7adbbdf8c6e67e8538b2c6f0f278755cc5e57ad720515ca558412ae1fe2cd40b74d000000000000000000000000000000000955496bdcbca8716245a130fe6eef44d13280b2d56f15bfc772f8ca66a52ca0a742e6bc273c28cfc858a3269f59beab0000000000000000000000000000000000b27aaa0d94633912c96f00ecc021773e5cf5e164e20c7a7222a58b0465e7baec4e67fb56ffe564c7a2904f36c265e61574a30a575138c44881c1c126be214c6b68335d7338875b8a398196f27510d70000000000000000000000000000000012e0572f5c84f6082dd05705a3fae738920ffff840c21e444f0ed002df16394afdc21c249b6f1837389c48719539f4c5000000000000000000000000000000000c26bb3ab52e3bddc219dc223daf472247547544e3a9ccc31123b82000b17ef325148935621edd36ced4e702ade1ee3e000000000000000000000000000000000c13a8f02dc3f209e9abf3d316fa843be9c4dd98ce1ca2edecf757bf2bb498750f6d96c28abd45d9c6cf5b8b6334b63600000000000000000000000000000000157a50d9034024dfc7b0f0db4ea0f45323d76c81bc844844ff9bdd0c13f2059066ec3060210aaba61bc074afd7ccaa286dd51553c4119255b31cb0aaad7391694f7dd29420420b513699747bee819a99000000000000000000000000000000001054edb092a7053eebc542f690e03139f2e25a0098c665741e8711c8a6b9582af47e467f74fff9aeea098b7732be72d400000000000000000000000000000000084f919e219de15e7f9ee122383c772415741e5b86be6ee7d2193a4f6be5c9cc9b2fe5e8beba26cd768bf2ea1b6ebffb0000000000000000000000000000000001822b4e8fae5bddbb36f5c226216471862af238be770d33c4fc1ec2777350db2f42e33a7ba468c317a128e8446ceff300000000000000000000000000000000130f704596ddb28ec6e335d9527707a75c97298407ff3fe17d3cba0cde4c21bfcfd1ae46272018c1db768c036f215182d88f049ab3ee2b01af449abce08ca14ea3b065f06a8665ae3510b4c04f42308200000000000000000000000000000000194dde06f8c54de9ab0ad72ba0de2241fef32fba30fd6f5e83fb7750bc120d51c461d75e495cee0d1e85f0f39aa9d3620000000000000000000000000000000010646496be02c658c82dc68eab86a4f784cf64494bd8441f884e8ff384cbb6ff3a4bf5126bbacaa556aafd652397a8a800000000000000000000000000000000109807bd4b6613acb3eb7d386e84166219e52e841c41185a269cc7cfc5f34e9ef5cd1fea29877749e0cef93a3b44eb1600000000000000000000000000000000020a388c668c9339e7aab15d03108317dea97720dd27a94cd3bb59b372b268d1a7d7d7409780bc4912c3f95acd42a57619d6e227185c538b122858ad5ae594720fa7f743f5805552152a213ebea64aeb00000000000000000000000000000000161506c4a2d57c852fe8c3dce63ec6673f05f99c1e032c8e591239616ef4469c4240482ce5985fdfd4a80f54dfa7024f000000000000000000000000000000000486c5b106393e544852c143c5ac4a882c79870363858b2c910ef4041d8803876cc55ef59cd6a41869bf5247f0db2c0a0000000000000000000000000000000000fe765ebf3c4edd3035c7bedd4aec918426898339d7aa004fd74bbf0e3236deeb7d2bbba56c31fd447816e301100a66000000000000000000000000000000001917c9cf16032e22cdd3f87f098a532a33c9fec560a88f9d4232f96cbe0fe945fbae6bcfdd2095cafe6e0b21071d6ec53f53123f01c4d0d4c18dd72ea87ebb5fcb559df255773fa0165f1432c229deb6", "Expected": "0000000000000000000000000000000015a88bcfa39f444cd66d0d7e15c4040561154c59b832c5ca895f8f8077659487581681cc8f13be136a35b4a573551ad00000000000000000000000000000000009fb6b87eba1edb3d1d23e566977eac68e8f1a28386fdca9d484c7e341c1b210390787418e2f2dff7a228e1cf10962d6000000000000000000000000000000000978de870dcd8d094072897707313b9f1a18d525e60a7cba2b2a395ffcc9d0f97f84e0784df36247d6c98824aaf3ec82000000000000000000000000000000000fbc6832c324d40f104bf82c8cda941212105131c26f630af1d3f7040ef43c6eb4486766b75a81433e46966f79953647", "Name": "matter_g2_multiexp_44", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007517a941bec38d0e84d21508d8bdd6778a853d9fb4c5e953bcfe3c8fba3732ca0b7f6cb5c363f33d7718b1b1a68f8e800000000000000000000000000000000150c0d975481422ddec2a58a55b3d917b6b7c0510e75442c81ee856e267d7efa09641c6b79fb9e699c6b473cccde7f4d0000000000000000000000000000000009d37bf938ac30fae1cb3ffaa971ff3746ee4090d4bf8b11dff7710b3f2e4cc686813890e03643fd56fc99e847ae5e940000000000000000000000000000000010fabc4048e0fadad73d0481e290c81884f4578cfb66e0a83324739652ccf273b62204f126696a2fc6469ede39e00a9fcdf2bbbad52a3f5c0b3959d46a8c42f6f5250a93c3dcc636712a4a2baed289c900000000000000000000000000000000089b167ce7fa997ca0ad3f8bbbb358824cb41f525bf60352d5df99402af62cc6d768113d2c1ebc7fe8190c5f732fbfff0000000000000000000000000000000013dcd35865e27bf98f1f6508b32c7e9a989d528df0626228087bda0d8b456af3ea2f4be6732edf1bd8cfd0ab9576197a000000000000000000000000000000000333b0612d7068986d21e1cb67a1c7af423e98cb14aace2ce02f84d32a38f97bcdac465f2b22e5fafa6aaf0d40380e4a0000000000000000000000000000000010de7ba4f50b6654fdecc4fc6c41289bec50cff1be18be9d5c9d1f906ae843189bb43f144aad4d2a2cdebbc2697c974918adf5d8fbdf81f8e4bf2f622e2d481fb2dea06a1aaa289ce4f6e783eb9a98dd000000000000000000000000000000000fdddfceb29fd79c31b138ae8e41507f324abd5e3750da14f4f86176126a06380d53dd5f7efd00e7f94bc1370ac9816a000000000000000000000000000000000d8371c602e393a4be250583c299d069270a344953f7f07a5fe27f8617cbd3ebc91f423dc176b272339bb3bd8a9a348200000000000000000000000000000000193a260a417c9c46da0aaf139e3bbfbaa9f248943048396d95716b3be0b8a148a3f0ebcf7d6f9a318b16d2d850ec2f5c000000000000000000000000000000000be4d0f2bf6d746b930034eea8a19d73377617645c29153b6ae6d3ca6fb35a704b6a0bb658282cf93555c998f6fd054a650e995b73b63d068fd54f596cd9669fc3061f0c1da77ae7d0f5bec012f9ba69000000000000000000000000000000000731c0a5d076d6addb15c1e5d3143d41371f4835d77756418bee452d2f03b1e603230c59f87905fb67d5eccce65a45d20000000000000000000000000000000013bd198c023009190c65686468523eccb57c5fe7b159a1c5ba30c662a275fb24d69338ec9c023ee6a10a8ec9dc7968210000000000000000000000000000000018fb369923ee655839c7d996e264133c49f102978f18261faf2f8eef376eb0bdcb5af375ada2bc783e50df16737f78dc0000000000000000000000000000000009ab8e16e1d0b406adbb37e950bc3820ec13c882ec4483528ebac836726ba202bcf796e84abb3c16dbf6d1131b3854cc3350d4f13e25052b1162dad3ace76e5cda71680fdc89460d8fa88c0d157df426000000000000000000000000000000001401029d7cf8e7d2690a27c01b32008e273b5a33842dcf52d84f77dfa4b2a1fb290f56eb4ccddbb420b27e06a7a3a3b4000000000000000000000000000000000c464c6fdba702f2fbf4232b34d615e66dbb5bdf80233f695e9103272111a06a79f8972d1034176859d0e29400f5a9c10000000000000000000000000000000006cc97a29f4e694f0cdbb099278fa94140b40147f4f911de96a762f2bd28233598a892899a6329cc3cb854b56076787a000000000000000000000000000000000625811cad7c740758388f330c4a56ef30429ea4cdb9a00e2cd1b7f310184a2e6ba36ebdca57c87cebd5232f52c34d92283f0256766690c88df6cf7c968b9a96121d26d19672ce9adc84b699476a32db000000000000000000000000000000000d0a16b5d48eb062c71b91d74a0d25eca0d4bd7082de25199f33a9d3d598d137fbee2ac36e8f877c157be7438ebabd74000000000000000000000000000000000bf93533bf677050d9a77a5dbdbf7cf084b5d934d55318256712ec361693738d48ef27536476fdc93dd8e81f13d67a8e000000000000000000000000000000000696fbd8841e60300602aa5528391aa8b196d8c186d6124c842a0124a8d8dcbba637502f330c980b2f5a900be8e04d020000000000000000000000000000000017b0c51e699d2252f35619520af71775f9dd8c57c2ef146adeb72640bec2ca02a59680153e5c9f66bd513bd8559b9d66145cdeae7fd3f7455dfd2ea9a064c135f0a0a36990ea34929e292e4cdfa0f472000000000000000000000000000000000eee94b5148ccbb3642e582cf0a517b72e6ea019676a13b1484982de7f4be0346b7ed22979ba7303f6367294a3eb2716000000000000000000000000000000001502bb3964f6b3e862279e15fb105073e876c4e48c55c42f3737dc9efed82b10fe8e39438ccd39c933f5ac3c6768497e0000000000000000000000000000000016cd8c4b3be55474aef7081cb969b75ef5e7cca9bd0f9627928fe9931c6f869a9a49d0ae2cfb8346116eb3ced25d4a8e0000000000000000000000000000000012456eceaf32cbb6514e6211136475a750889caea18ff4f9d5ed7b378e6d1d265721a646715aee6b9f2098e954a88289d9cdaa979ab08b454dcb961e3cc4bb18f706bed93a72a9c1e105cd69c0b691af0000000000000000000000000000000007b5633f4a7dfe62f11065d44581f5060210f8e572d960eb85ffd0a903d8b989ce10449fc90b7e5646784a9f6df28699000000000000000000000000000000001710f252cb35d88f6bd151ed596f2d6455f050c5e25add394dbaf60fc036016ae07a5a8ed494b95875c02df3c523186a000000000000000000000000000000000bee19779dc6430ebee993f82a054fbd42e5b7265090017e5b2d2f1469bc96a5a188adf471d576a416f6a841081043df00000000000000000000000000000000038f9fb4159e4e6f596a17ddf45a00a9e4aede63b062af5eda045efacd3977e8dfd61c307834c08bb4c284638696e92ef262f9f7a26353193939bfbbdc50ee35614a3c099776f08b21e0c4c97521eb8e00000000000000000000000000000000197687895f22c4a639bcf2f494dd9e5a034610b0297528235f1d806cf032f5a86c5248a83ed6b12f0de27f5c6e6f49420000000000000000000000000000000011ccd5dd6d6ce553ade9b31503a9e6a6119ae329178706f051581e3cf0ee9d6fb527b340bab8c79fad1cd451c7edb4330000000000000000000000000000000011e9f051aacd69c8bfd2f0ecb566e6d38eabc43f276ba7a1b8e8ab093917dd1c672c61d6dac4651026823b9938d3601f000000000000000000000000000000001362c3b2e6fd9b3618df26ed28f96530c1915f0a4ecb647658d1ae4ccf4c000f3bd1797696c9ac5c5000dbe58dba8de44f0d2915e82c9a69f9e9af64a2c5cacf61ead492bf69912a35ad6a316f9914a8000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e25ed3f13198b69604c08b414562f67a67aa8dd4a7bd3c066874182d21ed9004d000000000000000000000000000000000db02fcda340fb27a3fd7da468c5cbed9c8dce8471843a8ddadae43dbec9957a0479aa52855d7a6dca99e7922432365c00000000000000000000000000000000163503d24f9af34058cb5afd8e9d5aaf29e141c8521eaac282f138466e834f0daa9ce14e0590b501680d5b47f866aa8c000000000000000000000000000000000fc9175e6d20afd9d194907f2eb311bf8134aeb96da72f6423610612f2ed20a074c113fe8bb632d9ad74b2f6e7e2417d000000000000000000000000000000000b4621f5e4465629648b62b7f2b77afe6470f9706f9bee5b3ccfa66c596842cbae26badc689f7f623360cb7fc1d416b84ae188cc115e9d492be64abefa4bd4c93b61dd42a7d213e1100b8108611a61630000000000000000000000000000000003c77c7efdab9a9e71283b034ef581a31faee417febfa99be3c18e8ab724c140be684ce719bc5a9ac5d3855ddbf3651a0000000000000000000000000000000011889b02b4a1150fc2b7191a95c5ee767f3c9b82a3a53591018242fa8685ee3b3542526dfdc00695a6cf046033b8eb760000000000000000000000000000000016d7463159c4e3cb635f24bfb944bc518369e894218bc49d7b7f0ea99240259f7ee2b4c26c6083dbc4559ffcfbd392bd0000000000000000000000000000000010a85df6294fd6406ca651f15494153e9802f0068bfa149e87fe4b1cc3071ba74940a21dfd55a8a77e7e2a193468a3d2eede725a693277356ce71ffd7814a77fcc30eeb3a2b8863fb91ca03da1cbe37a0000000000000000000000000000000016beec57d3049c382fc039ac96b890412c5e8075afcab599fb877f8639747a587e82241d9a8059a0bb45ad49959777d0000000000000000000000000000000000a70fba1b061dcf587f133035a3aaafcdace3b1e771d71887ae914919e5f52a99d9933307ec15b5f0a1623b9592824500000000000000000000000000000000005064161136c04f9f50e42a5cee5dce3fa0ce1dc0655b3785a852cb9741927f6c9b357ac1010d7212533d1593c83dba70000000000000000000000000000000000d50b992bc0eee37a15cfd32eda2c591fc4c4203ef84232d1a1e7a9888005bc00755d76b9d0345bb01ffa7525f2aa1e9d0618f898594b23ee3754fe390d6bdfa7d47fe749d6819e306935c1eab6b0460000000000000000000000000000000007617e60d8f67344ce6d2fb65cfd5b423a1fd091626da837dc8a51d6ffdeda9712864e8f30e45ae8df917e0e4625e59a00000000000000000000000000000000077c4aad14f870ba24703397ff0b33af2e50b026f3e0f13f3ec1aebc9ea3af98cc65ab56cce4045538ae6e5f410196f10000000000000000000000000000000004a31d0eff18afa87f9a53098cfd5d21e913c7519cb171f83d0b73abbf3e893a3ccd5aebb9f2bbdd3b0eb0326d37fd1b000000000000000000000000000000000393052e6dff65e01e79254af757f12eb1931e0b386f8cf0fa0782269f962ebc5d9bde46f5a4ad3806e88330aca59ff01e1c9420cfa91026286d7f986b538c13e8c97893995485308c69f053927f962200000000000000000000000000000000033aa108d252e9107f29cc7da79585d4525ff2a35d31479a099c7c011a9c4414d7bc5f8498f8a204134b2d14c5fcde5100000000000000000000000000000000121214465992bdefb970d420face6db75d531e67314a021d2877643ddf738fbe57625d286bde7f40efc1d329a2e85b6e0000000000000000000000000000000017e14f6cdd916b1fc949be8ba3ef9ae6cc16d64da4dd498b5458ea0c14eb7aab8f970f030aab26397110331da11a232d000000000000000000000000000000000c56ccda2a5cca61025253407e72967c767f0e7f2aa0b97d4e4a09420dcb882ff35039ae504a9c62b3f9e7bb0c2e7bbbe5095ed9a9181aee392888e3194ebf9c4a6d87b503f4668bb6cc0d290880a44f0000000000000000000000000000000010fb3396b0674b9285cc5d5a4e7a41ac002f2b43332c20a56f428d1e19e1d1bb6f886d3bf03f7b0fc509e52d75965e15000000000000000000000000000000001196b7c253c50da10815bdfd7930a69608187fc3ac5fbcfeb35b95754d3017a094afcdaea867c2f08346717dfce7bce8000000000000000000000000000000001021f178c53b7d7d2041a6419203d12ee162f27999dd8f79baa15c37a7401e7a6df6aa4192a310cc1a23bdb0b427d63c000000000000000000000000000000000953c75910165f11112583476574f3987495d33e5b1a5c650a2b30692592a442d9de36da49255b0c01a7bacaecc9b81adcece8ee33d3bf3188574e94a889794077035ee92473b7266d92a3c018771b4c", "Expected": "0000000000000000000000000000000014da1d424c936453600a4acbd3666c6188493d4da8b34d6bc508aab07e59e3680a9e3488e69d42a724c9486d70ed4fd000000000000000000000000000000000048c637348fb9a4c631a82ded1fa08d693cfa2cdd6cdffb8bffee63d1bb2ee8676512a1a8d375e7ab942b6d6bdda45c80000000000000000000000000000000000443264e7dfca91f17251c33cf72c56b045902b4db2eb10d1fd856f79b4130afa6f29f3283af7d3b8b2a9d8dd63718a000000000000000000000000000000000fb386f875190ac7a49d4742edb387f72c1ae0366ca5c71d5b7e385c11442941ce0fb9fe2014fc624fe93ab86ebc7aff", "Name": "matter_g2_multiexp_45", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016a539a21320574fc25ffbc0ff10c821d6ad20674413eaeda6f4a31f9a028e21cbb3b224c225a2e3bc3dc221cec084cf00000000000000000000000000000000104e44989e2fba9ddce8e309f5d3fa3129f679d6456ed11137149b50adf8b22c1a148d47154450853e6797aba2b006850000000000000000000000000000000008b33b8cfc992efdf7d733803a6d08a4102e27fc4960ebe6ebdb7949c4ff5af76e55002d93a4f7204eff5f2dc4e37ef10000000000000000000000000000000017c35411c571c302c746a9b79cae892e988d50b4660564660de960ee09b3937b6f5b61fe37d09f1c02528f554210744aaddc845ad867f1e2664ef0e78bced8ff6904c5836e7c63ea3a9c858fd7b710b60000000000000000000000000000000009cd32594094d4744f59690cf8d7fd260b5ffb2a22945d938c035151861507ecaac9ea553e7b44fc4b3beb03b33783540000000000000000000000000000000006f4de33731b9b13b9cb395798769e54a0679d272c2d5175455e10c790debabae4ee02b6df08975efe806da9c4a208b20000000000000000000000000000000011859798a8383b7f994a1535bc0a96a114b90644d19921f0eec774ed58dbaa899dd3736cd1f4a4ff9bfacbc7370091d7000000000000000000000000000000000376c25b0f70427d4974c4fd1539d40996b6847fbb67822fa01cfd541cd3a3f8a9f3fe9f7ddcc3ce920a6ecb27dafca0c78cfc6a30cea34d3d3505f4f897631f67ba77913734f6c2895d871fd6d5581c0000000000000000000000000000000003a178f91a135d59dbd65eacebab293a3817d30e734c247f56a08812aa540a5c80e3f9908d86ad787bab27fbddd21517000000000000000000000000000000000672b3544dd2b91a626f37dbb389aff073777164e3e20dc572b18a2e5223bd323094e41bdbe2dec9bada227efb37dd22000000000000000000000000000000000f40f2d279c66f22bf0fedd129e02c96d8906f9f1ec19f5a5c1cbd5beb10942a066dd391b69920a0a697138f627a1b180000000000000000000000000000000016ef3caad858d323b752e5c437ee2043c8f691ca0f1862e80857f7cc478a689df97bde5b1d1350892c1adb03c5d2373ba1e40df9e1f7c84633cb3dc2223296887de7281ea66c5e1f2d5816334f7b280a000000000000000000000000000000001276e133fc5e708a3265646ef0a0122048ef95d7fb46f78b8dca57dabae0164ca986bdc74e581604ff31165f9f28dca50000000000000000000000000000000008a77611be0502d2ea7fbcf73774fbaec68eba36038e2f34f79caf07f2e4b7444efc49a4e85f88af585fd28a041f26c800000000000000000000000000000000181ab176e391190b1cae2e9b4105ca14cc82d15890b0ec127d8cdb46f30b704a089ac69e76f5b50575ed66176950e1120000000000000000000000000000000004031ce77fe9ee319b8db8f220ef4480c81568b3f6e4043c8710b559d25ad69dd38dda48b2e11d5aead18db0d1cc09b98810b9ce0020904dc1903338089c30e616ed0be03741572ce46946883874f4ea000000000000000000000000000000000f26e6d71e206c88dc81b8b8a5c05ee84a9f185e7b7f155253aa39104b5de5be7bb6cb6662df4f8e63b37fd1682721f20000000000000000000000000000000010058d13637c8da2e91c8cda7dc2cf1734a2f14b12b798e5c563ef9ef3624255a6e1c7550c37b547c35c55dc736a17ce0000000000000000000000000000000019ed470bd514f8bda8fdcd9c64f7626efdde0102907bd31551b1d1972aa14e1d361e1d58b17948909a669fa4d99cf3200000000000000000000000000000000013277afe1891807e269c22c9aa1598c12081809d888e0eb2513ca3f81308700893f74f176858ceed9c7955dcc0d8fc6893e7702da2ff9f3f14586a9ae80c8713743d61b915a7c379c1faa1b151406a9a00000000000000000000000000000000083664daa965c4173d6028e047794703a16e52ae459d3db0534d13c72d749d603edd668b9ce500677715e45216367c63000000000000000000000000000000000f4e87a65f4720cbfde7868eaadb34ec1916925ffd84e5407defbda0c39e1c7afcbc90855b275d528e7b63fd3707bd4a0000000000000000000000000000000004c9f689abe0d2dd3d927bad4b39ab44f6704014ef9a1dcd1966777129e1c72515b43c1b92ee60e9611245454683588b000000000000000000000000000000000ecc57b08b45037e62498135643cf077f01d216b5106551daab391446ce7bb37d40f41378c830081bb6a326f0105c2c4eca54e365faa35d2c9be259b53a1157b180a373813382f47c9154af18a2d83270000000000000000000000000000000012b84341bbad1eaf7fc8ebe56f67598821017365b6f3b4cc1f2355f868e8d55f9c0bed2943ada202a7d85cc884d8e6a20000000000000000000000000000000017693721988f73d77f7a41db108e428b0ba781ea88eab463693ec352cc13d394101b9a2792e0f30c77bebaa395a4776700000000000000000000000000000000093245e2919523cd57a0abd2e8a9c5cbe774bee957f26d3cb502b9c8c06483b850b031461dc2cb033d399651724f4fe4000000000000000000000000000000001530f7dbf6a0fbdc8b4f7a4d298b7824c15035428cb8df834907e25c64b8985186bb13f397b7b99ea7014ae65c428b12abe2079ecb3618de3accdf291d9479bec32bca1f9fe87b00b64a12d735f5b9a5000000000000000000000000000000000f323f01f2a63bc6eb1b565594ded14043c4ea5d1f0fbf20f39299052617c334e6126afd4273738aeb153c3561348b8a000000000000000000000000000000001525d1e1fa65f1b674feef74f6c81c82c3eeb709e597aedabbfc2b3262271b31d93818613ecdeb49c5d3a6a64f17a5d90000000000000000000000000000000010458c15bf46947a237dd1c61882b1561121f64890681bae5db6fbd24ef6c34b7fcb826eeee1fa328d9ef4d859faf238000000000000000000000000000000000e1f29275fe1805d02e069082d5e9a7acf69be17013e6c4c351277408d49383fe06f00137e777ba4aa49c29c25c6c0ddc541a44756ebda14aea95f1a1d05e7366dc0285305116b907fc89e777ce45f79000000000000000000000000000000000efb7373e11694b966d0182a9b01d1e52ec1e89cb18275921294e2d36333460b1e49fd420f1ab781b000d1491ccb0b11000000000000000000000000000000000cafcdc2c58fb3fad713ce1a38deadba8636c384243f9971e3930b961efaf303cac4eef1e8e4662636ff91eff1bf52a80000000000000000000000000000000007ea7441e1b2b0f1e42bd511c060b646c2d00bb3e6507beb5d17ab93ff68515b02f82c2dd43ce035ff660ddb0c104a77000000000000000000000000000000000bd04b88caf9dbd0ef5f89d12e72aa47d64212332b0ed871b7eb96b16295cf4810f6f20cc85fd4d1ce72119f80697c1b37d521d31de52681f1d9bbf64a12f9bc8fe0ac61aaef14d7e8d048ff09e6578b000000000000000000000000000000000c3d2d978e23a690e8422fd54f36fbee1f642611b6c3b2c2413844066159bdcd3703d1a392b030446af04b654f8f73b7000000000000000000000000000000000ae652fcdbd8e467ee9b447e61fcb811f8b6aa48840476c92daec3285785a06a81c1705fc2896c0843ab48eb92555b9300000000000000000000000000000000007088e6441cb85aeffcb4a9a0c81ebfc54a61f35c542be3870c2bb94d7081353322d4745747b0dfc3e5db07f9e48c560000000000000000000000000000000006c11f3e0941ea3bde0dd3a562dbbdad433f0b1e99ba34879e86f7951ddfb29b9e04ca62d54d7552a74e8cf1c3da3e704904a876d4ac1341e88fc4808508c89c19dd74aa8fb1dd7673cbc2d28e7d920e000000000000000000000000000000000c665f4417d0163820ac96c83cc2f09b1b3c000023d827e2690aad7357ff59e278832b992703f5f0016051ce0a4510cb0000000000000000000000000000000012f4b6688300b253fe868b3790f6d2f4fc16d81a49ff7a2edf821de16dc992d79482d66e443e0abb5da43df69f8d648d0000000000000000000000000000000009e033750a118d998b136cd671d0e760e3a617f1d6a994db8f6dfc391619f408720cc57fe550785306184b0c824705620000000000000000000000000000000018cbacd471e528535e22f714a841f110fb0484826e30f97842d65072b2790dadf0bd7b28df96bec531fbed1f3f93486b68911b04d8155f90c7c5c0cb519ee6ff14c0ae27ece0374f30fa148235e8cb49000000000000000000000000000000000c42b6fd52cc52034b04078a6565af2b43948695851393596e05f37f297dfaaea931a33f5b4c25980c093f8a742c0020000000000000000000000000000000000fdc7aa20e63743dd6ab32c82d2d6992b29779ec06eebd452c17d844159e90a7f3221f3e0e6b5805dc0f42dc3836d90f0000000000000000000000000000000003a2342a1bd528d701c2a6c72708a16df632f4e4b6cdb3ccc224b58b57af30b44556cc968ba3c0396a5e3f11568a73710000000000000000000000000000000019ccf76462668905c5687b7612a0bdfd4aac70f291d8b772e84fd5d4bcb591556317426471242fb5f44fd695c7d49279481e894ecd52a252cc76547513e2cf0a5cc6b20c3dc9c64c7f34f29a488258ef000000000000000000000000000000000c8fd4a171c5fbf584f567a1c10b20628e7e0d5d796eac4a9dd2376f8d488da25b9219c7c70709999b5553f8bba915ae0000000000000000000000000000000005d791c907984f2aaebf903a0ace52147745295f0c5e85964999a8fc74b64c8871dce358f26ed1b4af6c6f7f18e8f4c500000000000000000000000000000000110a453bbba72ac171876e0f6b4acd5b178816301e02586a143c2bcbfffcdbf593655408b9aaa4141b2a210599f452ed000000000000000000000000000000001025d5065f9801fcc1c1ebebdf67923b967ce985b5ca27ab5db8af7057fda23561a46b84fac5e793dd9af692c4d56cde72780ab3c48c8a102469799ba2f70d2fd9d324cf558a8c8b49e2ecdb71ae1c9b00000000000000000000000000000000023e5ea1909032676cdb79111a33da7ed788d2affbf4029b932eed843268f355dc92905db283d6617fbb530da3d704dd000000000000000000000000000000000b46f07de520aa17d597586cb0a6894a356757941ff9bdc2976f620e1bf1eec1dd9801d6baa2d7efbb3cc7073412ce8e0000000000000000000000000000000010022940611f418de9f9210b1be919d7506aca468fe5853675fe159d3e58685bcff6cbc2c1cb9e7d45a7bf305fca0eaf000000000000000000000000000000001888b5b0dd1648d9a27345f570a1278238957de1bd30c195d554750ea4b119e98b3989b912c4fad531de416c1533467f84ae1de8aaf498bd2d91bd828bc64e56482b225322b86529da703f47289c65670000000000000000000000000000000011dcc334a5037719256e514b2c3b0f36396d8cedcd77f33545842c686fa0f35558c397562a7e245f8cc412c776a2b3930000000000000000000000000000000006efd32c6afc56a07c813fe19e71f0248666c87e1df7e79b7afbd70178929e5660e85cea35d1c6f42b4c627a94ae0d150000000000000000000000000000000005a5fc2010798c793c1b407a577da0bf0e04b0478f19b7d0cfeff8e4e4fe2d581461831db165cfd17146c49a732c41460000000000000000000000000000000011dfe3b62eb87b039113152af74ae74137cba1762d4ae62d3cb0746272d1c42d3cb4a8fccd845a519fd0650a23a897a13256548db55ee9de70ebf6fa347d81bc50494b937ab1c3079977234a34cbfcfd00000000000000000000000000000000110e73e44734b7ab63f021727b75e735702f1acfa6669e0dc27111794ebee371734764bb165132af3a7e02f3605456480000000000000000000000000000000005fbcac7c7334cd0e6468feedebe077b80390833eaa4c28af80d29e75d692a10cf13058526fa5e5ab0fb635335ac8f220000000000000000000000000000000013f537ecc28685aba2cd60d0e3e787bc8104a3373177cb93107b63d39919c583ad3ad7a42e322249d7605ef035fe1af40000000000000000000000000000000014791f94aff42bfca13ab328a3e47b06f7da52e13436ad477cf55e53b54108d3aa531f0a5d73ae5ed7108d5cca1ecf7a575ae146524544307ee51e58a654d7324983a87e1b37d46cea1a4ec34114b44b", "Expected": "000000000000000000000000000000000bab02defb32b7938372d656feaebfb5431de1484361542c02519d20c6a500f0b0b112c331fe6f4eac3ec7f6ae4167e50000000000000000000000000000000000796b38c67df1361115bbf3a4afad2651664ef55b1ed02d3172f024f90a003fc3631753d7142aafffc64c6f6f57bf7800000000000000000000000000000000080d91637a93a9025e8691a400254af37cfde67eff7d3037d428596a808a01d9bda8025b7246fb00785cd1068b2752d400000000000000000000000000000000182a97624249f0c6d24672f04e2c93eff63fbe76cc11ace0f7193facd0655cc1e1ccb2d89d9547bc352a395efeb95afb", "Name": "matter_g2_multiexp_46", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000115b14c4eb9cc78eafedd2072be4555a3db9e61b5fe0139bf3e40a92cc37b4936c68576fee5692a80e4a9aef05a9b7a80000000000000000000000000000000019c828ea555a3c8d28cf0981e98609361b5bafa8b62e860d121c0f6d0f0dcef544784e8a5fa6a9f1d1a68b30e8e8a6f8000000000000000000000000000000000a2ef5146d2658609fd4eb98fcb5d42f6c6aac4fe53597128bbba3ba3539042ee5824f381c41dc76e2c6e4dbe0665657000000000000000000000000000000001807a12ae5f289ecde8ca0a913647d44209b13fae9dd6aa8fb4365a3beeb81652ec17cf92f6784c9ca5a077824ff6dc31129275f3ab3125db33d43b36c7de0ad60a6e9cb4457aa03275caea9635f0b0700000000000000000000000000000000186bfd109ea2369818ae2f466953eddfa763960caeee9d6f1ecbf6a3f854163342c26b56d3844bfedd8f227070f75546000000000000000000000000000000001877077daa2ea074b2868e86faf14efc6ed35a64161a77aec54624d9cb916c45de81b40acc3797c6e3338fcd7a42bb0d00000000000000000000000000000000054be1650d9bb6cae6a1ed08879668e4aa4cd139c8b07ce21d40fb1cf37f11de730ff13814a02d2d6d6df5eec4afe8470000000000000000000000000000000001612b5b7c613cb66d4134aa867d985682f6a544147e7865732887d4fbb191a9f5bdc27bfbefd397f38cb101a2d68b192dbcfd8680258eee451db60f3f42f02f388f87440d00badb0a725964042515c90000000000000000000000000000000015e2b23aa42f1e6a07b0a31dd4acc27e35ce1fb3333c3f330f2d88f112375cf24e6dd5afc4d245531e4e84f1f82230ea00000000000000000000000000000000193649f3b7efb346e0c1f7bc05b0910311270cd44b5803fa16e06655d6239f609363344bb7c16c2105e20709fb5ff0400000000000000000000000000000000002a6ee30841f471dd2ef13888ba03c9cb93c85cfd0f1d0a3927205e3f57fe291bba7eccbd2352f25cc4047097fbb63860000000000000000000000000000000005482d4a47d6e381f755c4756a761f0310d0d981523afcf288e47a1a643d6be62ac6410521e0f25828f469af6150f41e5a6f194abeb6b7c1c561aa820bba658f0277870e2a32f972f9d18ca361929b01000000000000000000000000000000000178ca460993d503e496633fe5230d895bfcdd0696d817a23ae94e529bb145a0861e4448d3bd48c55907be762192a8c4000000000000000000000000000000000015d2db77105a8ed6eadc05d3d1f26a54b3d1b812a58ab49a889f5b7fcf5ec08c2eea6ad09484fda29cc007037a1f6c000000000000000000000000000000000fd5628d61cd0835fe49fcbd2f17058f23d0ffaca4474923a2c0706d9333d9881125efa2fda56234a82158da3eddb5b70000000000000000000000000000000010ce4a0bcada5f92cc8898dbf5c108c0897322eb6a467662be569d9ed0f6e2c808e214b83969ebb86c84d38f67d20754579450b7aa155a3ab61e47e337ddbcd17b197de2dbb76008cfaa09d3fc806be4000000000000000000000000000000000fc4ed0ca43d5cb172deef02704579187a480cc977737070b8ed2dce48d3f3141619f37e985c220a2840ac01dc5667f900000000000000000000000000000000047a15e96760affa4e537a45aefaaab1e0e18052f63514a9f6544136c87b7cb4a5c8dfc0d9544518adc7932ce9cff5f1000000000000000000000000000000000c9be55c06f81e87de58a5c1df8d16174cf4115f81091937d98dad6c4780a9b8dae1081f8961fadc4f994ef62927664700000000000000000000000000000000165f9b1a8f23831a91be8077b18563c7648e54caf30895983cc26580241ca7c86b9b30408a9b27776286ed9f07bd8ecd4be94f96ec4a3d4e028644c63b2577a9ef849b403acc55e42432c3063a918d160000000000000000000000000000000006edc0d62ec31b14e87b2ccff3a21a7c8d38c3ba0ec48bbb8df27fb1acf58e1a87c4458dc2b770172460adfb9a9bd50b000000000000000000000000000000000ae80063df8d41d45fc43f3aa0881364ab5fcb9ac526ee22d3870f2edb0aa379e9d81780b0ab08a4cf308d819338deee000000000000000000000000000000000e0898453feebb51d9a1cd2bda36a307ff2eebf44dc8f4c694831218c42b51f723ffe521b356ad4e5f0dbbca9af9ab47000000000000000000000000000000000fd186dbc046dd02217cec3c7894972f71e5f00e00a40fb1521659a33e079b7a1f60b026d9055a50ae18aae5757ab8490983e6618e9e4208cfbaf647592e42b2d30de9e74e4943fb2bb49109a66302aa0000000000000000000000000000000012134b433877e0a7858e6c3b95b2a1dcfb0548b290b68c209642dadf550db1c636598ac43d101b13c2d8d5ed9602a73800000000000000000000000000000000102b5de123c449a078f6f06935c9537efc791ed8e5475ffc2d9e1d098c814abe56d4b7fc6501c315edf7e64a431c5183000000000000000000000000000000000bce703ba78f45a1c59c69429d3dda18243ba2413c5eab46d469f504da975c434eda451c85357738d6c7054755d5cec1000000000000000000000000000000000387724937bfd817a65c0e0411678cdc78df26ebd4a814d92b023710558701163349b56b80e6bb68a4401f2662a0525506615e300a924ab962e0b7fd0b044cae9516d96de603ee80695718c27d7fba0c0000000000000000000000000000000005abed9305bb79a0ef1cc70e7fc2eae35a8580cd3d1ffad73d3bdae541ad546b8f74b4ca76f8f374e31dbdaf1bd14be9000000000000000000000000000000000199b29da8d161ab3061a18debc8b7400415caf029ced47131e27d81a0f7f79b6ae5e570f34a4c74fb85fea1411bd6ea000000000000000000000000000000000b8a7c42f5289d20b1a55a42d53d49510d3871b6efbe560bb4d87029b85b930f787c3a42e225006ad62c68d5f96c2f8a000000000000000000000000000000000e74aad2b29a210cc316181863e71a1dce8866a088a072ad5972af57b813a2e968a5b16b294273acd6e81e9a5be2961dd77d3e9e64e00b9356cceb62209ad48fc89e69e2214aad2edeba1812272736390000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c41f75c89ec973f65b11786e186f4d42ee2e85c40f29745d9f428af08a39d5681000000000000000000000000000000001611787ba658b64467b4a28e55ea24a3b230836af6c2a7072231045ee4ee38e02302a62688d6f988f76cb5e50eba40080000000000000000000000000000000008badcd59d6d30f26ca674753ae9257a853dbcf49a5641999634a9a35a97096b6096b7b058360bec2f9476a51eb0d781000000000000000000000000000000000d30154440d8bb5fa6538953a96ba404658817be8047fa7a3a86493f02399543220758e649948b804f2daf84fb86f7580000000000000000000000000000000014fbdd62f761fa675e4cbcb61083a910bcfbd1f8e37f1fb1915f60929b047c970b87be0730ddc20f9716ed8c9bea7f19c70cfb76a04d1a9e0d937292e5553ef371e20d5d3dd33611edc0da178e2e4a1600000000000000000000000000000000143d1f811644e3a51c735b708cb2f8a2a90311f9971c90b9ec8e45bdd6488638b6851dbc882205263887b4dd5dfb4e120000000000000000000000000000000015692a6b06e3bd3100e149c6be3cbf1566fb24531eb29036fc48f85d5da83316a38af4e714a17552024c1ca4a5e39d9d00000000000000000000000000000000172b9c88ed9a1fc2d5a7f147d034fa243d420b129343ff92b79bc4d836e380e5a7e388069e9af9026485e9d3f41a7aa300000000000000000000000000000000012e8453dc64f72653c4e9b3f6f43fdd01b896c642d21604f992dc5591f2cadf71de4099e1075a4ca4b7539f84dd5a908db878b7f5fe817599add432ecf262f19d80ac834bb0a0f983728f6e2c189c880000000000000000000000000000000003e9b6d23809781f50c0033e53d245dfebbba9e0c4d9f676ae61b80fb6e774509f62fad854fd9ea841d9905d48d943a30000000000000000000000000000000016a1ba62bc684bb1848b0ccba59597b19973b56fd9b1d9d06352de44aa79c6bf65409dafb54f859d4a7c32e188bbe19d000000000000000000000000000000000e782741a4b16c5838a8f6e542135221ab3c6ad180c85c08742992ddf0239388e273735eae76c656e61614da386ce2640000000000000000000000000000000001cf6752e88990c221af94e18744790c30aa6a158b10a1f6a56c2ee3c3f0fdb2fa7213f16764ac9e9f4f65e99e715ca170751fe88ad289c91dfcd3c3c61ce1e33f4146f03fc0dc77cde9b32b51c75fc0000000000000000000000000000000000810b0175d781256053c3c9188cee4f55620a6624bfbd2f4d2e70ee68a105bc7b60bafdb76794a048e9f25da976390d4000000000000000000000000000000000716095f8fd72d9350ca62ca3ec34d2228cb563d4e89b19b152787d42fbb750435aa6233d0a97196a9324319837be14f00000000000000000000000000000000178e939d87c37d4a2f49e1e5596945879f2f0f64419e3dfe2afa06bd58098e1ba57a9b60c32cd6527481ab3b325ca827000000000000000000000000000000000aed480a1da482e40ae610a9522f0a18399b0130202f9ca79e3573987f5f7ae30724feddb52fdd05817a96f7937aaf7984bf139cc0b6ac94697b7dc278063a74e478d47528da3f84f55fb0adfd851d09000000000000000000000000000000000133adb236d9eec3544fc91852278abe37a1da0f32a84477c0d93927d64af613b7452a5f64ddec7447779f42873cb157000000000000000000000000000000000f6bd940b51b7ec5a0d92ac77a55c296215e970e9a499793864dd69c3a8d583403e95c08b719b5d8eb0c37a8476d3b960000000000000000000000000000000007d4444062ae06e65b45c6105af53c487f6b275ecdb36f87ec7b71d5861a1bdd6d735e9a1fc5dfb476ab8c13a98b570a000000000000000000000000000000000e043cdc87c67157b5ea3e5ab1b243aef479b23861f8cd823bced140ee03dd1f8bc6cebb4bde4683ac3340823f4d55b8d19d9496e7ebca44354d5c6e1f6b8211eb06ca23a6444c307f92f5bc6dcc2dbe0000000000000000000000000000000018c35112c27caa6bfe9cf8ae55f51755ed349ee7e7141c99069dea07c21a6d8634778a91f4dc3d17da04966a9eaccab5000000000000000000000000000000001800c8a9b146dba27050ce63e78895bee2016255c59acc34fd5e6cb926c16a8fcd2e8a579fa02559b3c571cb08011bea0000000000000000000000000000000014afab23fd4ea54b1ef576a12a2a62d42b493612ef466483ee8c4e62908486c038598e72dbd9256166960db73259def8000000000000000000000000000000000899a99ae8b10da4bbffb6590d79aa33bb2adb2444a11627f05622c732b70f90cbd2779362349aede5b591e84b53a8a06940e3509e1fb090fa787fdf633a74380cd5de722678826224641e46a6e920df000000000000000000000000000000000567d6458d1a3e012c63adc8b9dcf32254c98c0b7021ec6a8d579dad47d501715d2e42a0837def225515d663e663c4f000000000000000000000000000000000178daae121366ce025c1dc2d3e72068fd40ba9d54b2b3724f7a2071a59d4f17d4766a82364540bc31a46398c66d0e7da00000000000000000000000000000000147b2851311913ea53662082acfba785d21915cf00cd154b1b495246e109ac37c3fb6c63aabc4fe71a0d37c81a40148d0000000000000000000000000000000000122b7b1a81888aee37fdd6c23d31c38e79f28945cd1798cee3f4d674e923fc68311eda8ce45a561abf9c5f0bfeb4297b27d21c1d6e06d9fba7b61fb87d364a7a6252c70b8ace2d3679ed87ce0fcf7e", "Expected": "000000000000000000000000000000000f5b941cda417cce69a30c1ba4a82cca71cb4b953d06d8e545c1b792ae22738dc006627da02b4344bb8be93a5a0dcf07000000000000000000000000000000000eebf4ac30fe0ffb905f81577466889666f801d4d6efe0fb8a663fbf1cbe76b2167243edfc6cde3f49d97d3040a9507400000000000000000000000000000000007ae6a99b86dc7ea95801776589472547ffc7a623009a592403a9710ca365510d85bbf20fa4519ca0e0ca208bf86a670000000000000000000000000000000004b5abf778c72bcc5b887855c582c042a4cfff489b0548785e4c1b735b19159be8a3f4cecf34c769a34cdefa722ba783", "Name": "matter_g2_multiexp_47", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017b47384e6302b140118d0a9247aeae2091607ebb413ffa232223bb42d16753b2ae48e5ad0265e33616b25f0c4234be600000000000000000000000000000000167be566292b835a42ac7c099d80e8a0b5d4ff91d842d4ff6026876aa1570ef9641e9c0cbd44d8578f6a758717bad6f10000000000000000000000000000000014f692d195979abd9c55ac132d0def925d4e158fe946fa7b0a010c475d60171a0951d4b68ae3c463bf1136600a1ddaed000000000000000000000000000000000ddba1f4236c5200aa52f8cb7e15fac1f20cc66dc65ed180745a3eb8308f2c851ed6c1e27e1507d3f902ce672d6f8d24facfcdf87c6ca0506b070abff83ce7812181c31729cc534497aa8dabe243351300000000000000000000000000000000023d08e255b244cffe911e43b9b48408f9fb3562edc2c27f405bb657731c885a58392ebbde9fc80cccee2404cc8547ec00000000000000000000000000000000088ef289adaf206afd2b72c93049fca2cf9292bf6471133c64ac4f42015b97bb9a23f6c34653e0218fd0abdefa56bcc60000000000000000000000000000000015cb78c1440f74b17125c547fe7a37611f01b83b91a351664c696e0f647bd2db3ffead880b96a327780026d74c9abca30000000000000000000000000000000004d1a63607b9a5c9ec31168d85fbbee77cea0ae93e98c8c1dde14d0baa72f91042b2b7ca489958344916ce79bcf286456546fa692d9cd61895526282193c90148099e2afa54f7903a5431f932bd5fa06000000000000000000000000000000000ea6cb7ff6a7f4ec38ba11e9945eb406dbb8517585fef6cdd64edc970efba244b071fa162f7c8e184acbf71c5d1e12160000000000000000000000000000000001ab80c0dced33cac8a6a085efce71dcd7021f6255684bb631cf5c1716021bece57b900b819e6eb6f5b755b74c677b6c0000000000000000000000000000000005465fdd51352cbcd8b804cd509526c3b6232976b8278cec3b7db7da14b77f78898c6240c30943d1418462cb7a5abf8f0000000000000000000000000000000006b6caa6a0d5f2d671b10217c0ce5b3962b0c3edb4f2918497c316ebbdbe1a15c803d7fc3413907346f0e7d03920005aa9c1460c1cbb2a552e3452d5c5535868ee9c2952ec3fdb52dd826c16ae3d00bc00000000000000000000000000000000170db23154805a04013052a388e14b5da00e65b35b8ce2dd967213a74735dcbfd28782cef1ffe9d384be3ecadd101e9300000000000000000000000000000000082dea309092976408a379f1dbed9d8cf91f768e2921e49ece458859c80a1d9efd4d5e588470bd669c777d16f9d2e7de000000000000000000000000000000000adba8ef34e197689228e6c4e13be75b3d4732872c99b865ce7733b7a42034d6d4d7520ef7ab712f60f1ff87bc4d9d8d0000000000000000000000000000000005df0788ec39430fcd0625f8e030d917d8e7c251ee6e3b0e79fc6fa5f6fac2ad736c818bd833e58ec61cfdff52c9c6ee2c36204b6a005a64819b06804eb94c311d78977b557e7acfa82e147b4d6ec62f0000000000000000000000000000000000922d8b5db6e415aa3acbd0d6065db1b492c92313260019ef1bda0fa091c4bf091de95846af1edb34516b1abf7d278e0000000000000000000000000000000019af4ecc4f278315ed90d67cf4d22ed6fc9af5c0d0ca654f6a74a3c4bc98588bf5347b4536f36ca8b4750c18464f9b7b00000000000000000000000000000000021eaceb11638bda8b4293991983f11cc60c1daa2287f4b4a6066374bac82d117ac3ea4ec73afc4372d254bfc433b8c3000000000000000000000000000000001037fe26a10305cc5dc11a65edc705be5a0082656cad53e63038ee57a79e16075df54331233229a129483c34d6dd92ec9160c5a553479a10996704c3eda8e57be88eaaf5d1efc8371e7e10d7d106e4810000000000000000000000000000000011e63dc251a5a1e2ec83741682d90588b6b185365b33dba45458b1f56324a4900b04d61af155a0edb0bdc2971b7aaa210000000000000000000000000000000002dc1bd5448a2ebb9a02509af8777616ba9657bd3be65519233f0187df77c49fc931bbd3ec0ad5856b2ec0dfde476a870000000000000000000000000000000019f0cf8baf100451313711bbb0a0fa318c14224933897e74fb727b585cc8620b7d741c9ca2f0d3cbe14a8749aa48ef3e0000000000000000000000000000000018448fa9e05f87d4991ae1c248413edc9a8c3ee789c9c005e691bfc9003191ff469e26db9e42e5758fac79309a62942c5e5a50e5dbabb7a56897935683f80a5b16dbef3c23461e241fbdfceea38e3ee200000000000000000000000000000000109b71c19cd36ef3078bbae25ce6d0e8f7b58e129407fe68ab09aa747bfb3e90c04ab804fa6b7a223c172146fdb14683000000000000000000000000000000000d297750ba112da88beb84b8bbf74ed134b59fc9496da3045aa6dbcd97c68425fd68b75508de113733602a5565f4c8a600000000000000000000000000000000149b8ba6e05b66d07b353f46ace4e583bb61ed18fdbcea0e941b8d9805d3168040186d1c961add494f98e4e7fe68824d0000000000000000000000000000000013a6877bd46557d23b9aaf371ee5a101227d7938c64503b04b39cc6cb4e8ddedcf5cb6865439c9f8b1bfebb807ce52e24a95b293daa2761cc456b9667517f499c4d9eb9eb1d82237e7a7819b5d44f7a200000000000000000000000000000000073f440c2704fae6c86aca3cee34591ec03c362c2c5153a5e82c7bcdece2af0c58a3484b448c8bf4da851800ead959df00000000000000000000000000000000075a2c26372b482a2420bd3c9952fdbf9e5fea906dc8a4deb9691f8745372805bacd68a4838a3fefc381a2ce946ed1780000000000000000000000000000000017575b016435782cd09901afd2ea6773b11f5a983bdd19d14668d75362f95d055b76e5bf6966b1bd7bfdfbe9a939e4b60000000000000000000000000000000001569d74258298fac89d0d91a9945780f4c08d7af7b942d06255ae590db6e8509c908c16bd2c2bb634279debb72f489b5e22ef32d111261dfcb5a2e8d23c8d920f013bd9602bbef45e6d4e0909abdef20000000000000000000000000000000017180e36b925e2ce23c46813d96b919ca181481efb5d1666c4a4e9c8031abdd9521eb8228c4e3f16de0b33da4c73588e00000000000000000000000000000000138965bff7c573546d80ef7efb3d45e87ed20f59adb0cd7ae148d09a97da7feaf1b0ef2455ca19381762768a7d82f486000000000000000000000000000000000360bd29c3f07c5b560e2ac226112a628839da9db18b052991eb2d9c54541c1b5ade9b3c2d7f446ad50050531228120f0000000000000000000000000000000007105978bcf13bbe2bf5c8f7d165998c3ad99b6a2794c90f5b61fb7bf2472d307df8fc9f4afe7ae1e40e7f0eee8ef9466e687c0ac8fab70de2416642afa1553bb38183d2914050602874491057f78786000000000000000000000000000000000f4434c5180ad10cd45dca62b8da790cdb912c255c0f33950f7039e3885b38fa9e9297c7b0a875380545839d8c4d4ada000000000000000000000000000000000d0dd1429e512884ac209f788b5832d31649a78a8966d3348a93f841be23c8e4e42d6ff0d6c27e8f43daf495c9582935000000000000000000000000000000001307377f55dfed30ac1a406671af1895218a01d063b025d25bdbc53f5f9d535e4cd8053c09b2cebb25d3a08365ab8ccb0000000000000000000000000000000004f5c06f505ed15aa7661249b7edd71855bbf47237e049aa951e1ea3ff88f98591518bac975ac628e417892f8e9e5523428f1a27ea15135f044643dc36a3f9c2b4446a3136bb11f696b0a430a7454b3f00000000000000000000000000000000083336fa0b79691b4875ed27b2bbd2d2586992940356f6ae5ddd2021c5ddd87f07f0a5c1e8d8a2654b99182cc2233e84000000000000000000000000000000001880f3824f7cef95ae5743de2e17191848d8d30f0469f455461c6559ebc75a7afbc86dfa3ee17f5470f74018ec335edd0000000000000000000000000000000007c2b26353e86223e5dbd4ed6d59f1170b9cc9dc600fdfbc6c73b96f2c667a82128b1ae5af0542b11a7d1efae87c75610000000000000000000000000000000002427b7eeb497a20cf15c10513cadc9ea612f3ae94e2ae833d281734e7b5d1d50e240659ac01da7864a95b4cdcf88744ae21ad8a6c9d75b51133e81ec34d66ca70a52529c5c3a2307b0e8d6f1c5e7d97000000000000000000000000000000000e72845430ebfb84f8e3cd3dd418f6dc528bf521aca4f9dbd798ed903ef0ea3cf21dd1409aa3759351be32b21d8e8cbd000000000000000000000000000000001457ad87f0957006192dff7d99815c35adb3635815e5d157542b9f52f1e9f8c0143a21a3be4dc1aea3a895689f4a316f0000000000000000000000000000000007e8544b1037ece2e5a9ea387e0f43b72e895e9c2ca4d205f12bf6df0b35ae62a4d62756221d6fff65b928b7358f48b00000000000000000000000000000000012c5c3167f6ef118c4044c0aafc85a337d305437d694a7bd6fb406dabb7364d9e90d74a8b327aba971421a5b3dd5d06988a23b118179ee2c34ad030993a2d2d70375311b95254c44254a32508abcb612000000000000000000000000000000001995d7cb79da7b6c5a0c8ccc5ba075d8d6d8ed3cfca85e8ecdd2b589986fa58c4cd4f045983e9184d79173678d618f310000000000000000000000000000000000f9f7f6bcff0f6fd621f3f8fcfebac132b3f0d52a34af33bb9830bd714d2982f3cc6674ad6ca668131a5062e5589df90000000000000000000000000000000017699b298a46829020e0299ab89ab6411af0a602dffb0e149053ff40ccaec71a908da02c8e611723cd06c16a8e5c0f2d000000000000000000000000000000000523b287383c1e47a6f31d397359941fe0bb8167aa11604ff8569969eb5ccddf4c4f432d2b6fe6f39204020e850d4f2b30eac099ededf0087275d1af828bbf79ef7fb0e77179a068f2ebfe4c749a98c90000000000000000000000000000000004760120239593cae5bdec813735ccc99a88129c707686cf43efbd48fb08d8da3086879a6042bf118879fcccce0736bc00000000000000000000000000000000105b8191431f701b365c66680cb4eb267681ee4da17ba55d47cf26d21ba1c0c3eeeabcafcc79dd87b6457bcc91e9fec600000000000000000000000000000000126ab502f66e732aabe02fdb2f7a665a9a43f6b4ff21c22fa976e7e434b08b606e9cf0f02459fd85f5a80a332fb3a62e000000000000000000000000000000000b2ef01adea6c00250f2f14c98ec6d6083c45019f3d166419e3a137667324f80c34b6b72e991daf72e2eaf9985d0f9287e8dcbf708682225fe3f71b7a687da23de5ed188e40585be0553358012132577000000000000000000000000000000000ff22a0db4f1b1679bde5853a7c2932501f191f4a9f25eed968a796219cef028e26070851a9036a05a04abd73bd6bd4e00000000000000000000000000000000097e9310749f52a4b645190069f4d52315f0eb2ff9cbbcd31f1781a68b2664bbbf27166e6e74fc2be2e5b1eb3f3d77a00000000000000000000000000000000015ca218d7d128095bd4f4b4f7bcf7666e92b905e551dd22745bc743ad0783b6ac44b841f87d3deac44617a7c9a341c55000000000000000000000000000000000a1cb723a4c378e5db2775f4dde9a6887ee3313401a64130a78b90d65dda3a5d9c8bcbc1a0d78c310c869a7fc4889954532cd42a9b698a2c2d22b1a620a7ec60daa9d1eb8ac36894603be7bb9b5e37be0000000000000000000000000000000018b30cc461a4e1fbefe209a709a21ae201bc6094b2d15f0d6dee5a55dd84ef56b62ab1b6bd513b27c84c638291f4205a0000000000000000000000000000000008a6f2082d6d510b280a270c09044ad31fb18b851ad2b38859138c9c2e4870fba6b607f682a798bf21a13bff116014d200000000000000000000000000000000150ef352d494a97d0a7ffe44903aba1611c8d81fa2788c0f42a6db48a71101e12f07318da5ceb1f0af3aa10cd4c26341000000000000000000000000000000000ffdf3b133cc926684e4624531569bfa09b1658e29ad9c3efbd5e9d18353ffbbfbf23a2ad80ccee88f8fa597416d47173ccd5e19892765e549a63238e664c732af781fddea558a117cb927bc4a1aceb5", "Expected": "00000000000000000000000000000000134f45e5409998e657923ca76ce92b7d2acc932308e0694bb22f121f8324d16bfce86f96c67111c8080289eada4b4fb40000000000000000000000000000000008d9063b7845ffc8400c0b7585e819043884f92e28f7e3ffa47a39e808cdbb034ef4230b6e19bebf083e939b6b686b0b000000000000000000000000000000000e95f8fcd6b5bcc9e00a580a99627d92fa7486ff5ea587df5dded24d1b0bb76d339f6765a5a2058a8e227f633ce36e91000000000000000000000000000000000393041eb33f2c63df3f40d8ea1e1a9eaa9eb0a46151294845e542054d503ef69b40b0b676b0e4f3e08f4d26c36a5d4b", "Name": "matter_g2_multiexp_48", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000042a220276f12fb4e81c40ecef3a0d86634b4d1c0acfdc463df4e7501289f0be385e03808d44be053e6ac98f403a8a930000000000000000000000000000000004e3dc92e155aeebdfccaaa1d24f49efc8b02e4d9ba8500a5b953a96e0fdd58519bbf1c279750eb8b98616e6bb9a3f6d00000000000000000000000000000000086bc212a83b09c7361540349767896058d5567d4342c607ae9c07fe5f123d9aaac95ded6cdff0825edb5acbce3e2b6d00000000000000000000000000000000062598cd6d5680a155b6349cd51d636c1350746d17fe0fff5195f164ba2fa51cf52f8662f43d555f7be6bb8bcacca39448da17551b2369b723bf932173a9167663f8389d2461b763d6a061df78d7ff1c00000000000000000000000000000000193e2c749e5bbe87dd5c306d822740969cd69ad6e156c323d217c08b18bb3f97c85aad63aed1e3a455ffa1b6d2a670340000000000000000000000000000000012a3dce63a88ae32a746e3812833569959021e1dd9518621793308f8f11d04829b2c3d0e0ec39fc48dfb8285b6852746000000000000000000000000000000001235488d01c380e91872fc57cbf618c3531a6bbf6cba9dddb9f07168cd459c9e866e44e9e5336369cffd8cc3a36cddc00000000000000000000000000000000010d85f85d6242b63f8421e92f1c37f64d33fed67e0cd3dc4b2b2cb4a7fc7637f9e049fc959720eae6d1f452159d48b78def52379c8b9e7c24d971c3456b85b51a63ab03761ec66c8dfac1018833e05940000000000000000000000000000000010889825c752d0ae8445a1d0f3510135b9672c30a781788698f637c2f535e35788d76492edce8ea091223d016b5cc141000000000000000000000000000000000577175035c86c022e634ccc9a5beb96a36aa068cdc36e5a4fc2028d5dd099c5296d30a916d3b720f2e051e7d72e4d490000000000000000000000000000000017b46e49ba08a0abb9394479d693d8097a140094d0ef1d1ba7761fb601a686b0b2b4d49abc2e393a99c5cb760299992b000000000000000000000000000000000820f8e52c1b09986a70bff04909b044f671c3933de43a6bdfcbe3712310274ed880d7adc4947490c7de095ea651e578b2225be6985b9c8fa59a2890da56427612a4334937761e24a33d37f0f951a794000000000000000000000000000000001776b92f683069fdc006904fef8e91f716d9f6bc46306b042228088545f0e11a41b40b60722d4f0483250391febc0ed90000000000000000000000000000000010d5052ef2504115e9d9d4ca81c7080c0868cbed605dc7673f7f94f5959c793c96aa5334175e58499102ff76f974ced80000000000000000000000000000000011d1e719bb69d842df4fc23e8dc4393067d00f6fa8ee42d89b462a546414b91f68dda5378fa093b3ffa764b5fc63b1aa00000000000000000000000000000000099d0784a200e5d2d38773912cf1a49e813c871ede8c50da03abff58ec1943d2adefe66bd2feed1c57f5a80253e091d0a64ce8ad619276bc7a00cb49faf6cc84b917ae6b37654363f5719a727a220291000000000000000000000000000000000d7287adbe0bc3cbb35ab8bfe69064faa83e3e64d73a0c64d960949e10070081a99c35d1dacea5a3b9bf312745acd6e600000000000000000000000000000000034f1995eb8631e080378b22a51ace902ebc9da4589c89ab557b6aaf685fcc74ec1fcf95f6b9a31b7a45cfc5a1610c640000000000000000000000000000000009f56712a46c0fbc199c12d5eb7abd60e660e2c6d437007c34954c6234a0496ad0adf68cf759f8ea30980c9a78175e1a00000000000000000000000000000000073fae1cb78c776188190a4d7223f7cdce9a36488193dc06898919ef4d5136099c3185d352028760c753e9eebb52ac240b891d638d7e76e0dcb230b1f9a7c3b35b35193c43a6c86f345f5a5bc9c708f500000000000000000000000000000000019944fc459fb601bddf10a3a7eb55f34713d396c3208a10089b8f21f4bf0a5e87e95ccf73e0bd90474d3e043f37a72300000000000000000000000000000000158445bd2b6d396a390a0bd5e26256587f980eae84d7a592b2b4d788c452d312b854427185a770084e1b4c7898962e50000000000000000000000000000000000ba44a1b912645354da7d8d9c694b1d5a9ff2d642fad31975171deef3adb0f8d92b2d3a8bef6ecbe0b8e90470b3938d00000000000000000000000000000000012a040a72ab035684bfdf57bf473ff59cd1ee01ec949dcc6066e5c8afad775ed55123859cdd74c7016a092bade7f991b571175eb91888222085fc2dfe0f4401ed6a1fc5df86c0c6b8e44fba6454305bf000000000000000000000000000000000317ca8fdec8c7c56fa3812157f9ca8e9bbf91013dfc7052c0795a04a1b4649b2147d9cb1a61f2c114a705e5133729920000000000000000000000000000000012b893d50fe5ea2eb528d1a04bc8596b10d4714a0dc38bdd5f0a275c07c846970106c3f7b5686685f5c809e93c57e2ff0000000000000000000000000000000014f018a0d13c4c494f4a6b7e836f0f2f46c4b7975d91adb93616a0555910f53574add03b905000f8492465c9b5488c1300000000000000000000000000000000146eb4ef1103b525dfb5c31bcb98e550245732fa252a814824258093a2397d1489df8ca0228d4f5df0a00d473d1566c454c9e7f7ca14c66b8431e25e6eddb4f20507d03bf124eb607957ca2f43a0c17b0000000000000000000000000000000010e9962dc19aae8e92abf32fb9c8eac44d77f587159af4e3b3a080748322715a958d953d3c057999839a47dcc840076a000000000000000000000000000000000ccafa9761e654ba54a46afff51384f1c6331264082e23f94fffd6c31a1b1b568a391eac79417657f40ce2fc9a154a670000000000000000000000000000000007276b111c94130b2608827156021815faf2be29ae42c454f3e2f95de98d2f5b98cea3eb18335a8fa00e5464f8089cf300000000000000000000000000000000053550896e867e237086098f4493caa2520e8c97a05e14d0ab7012d37b7fbbd42a90accbf0fe2ac99e78ccf0be5c9c58000579e1ad83015c8f02a9db5c38d0220368a80b309ee45bb952cac824817b6b0000000000000000000000000000000016b5bca8537059362147911da9e69ad3ecd3b4a7c43ee7d6d809f46c74c16bc7d69bfb5d7c727b4d5d8a356a0458b59e0000000000000000000000000000000010f3a7eefeb3033a733af7d20c3c5caff4c409305de8d71e08cb9cefbdfacda41bb975c92c5e5f2952c3c1e2bc6ca8cc00000000000000000000000000000000148f5b2bd65b71184ba6974678f709c5f9e3f1a020e3d4bedfa5f5f66478adac47f06ca2626c4a759b5eae09756cfe49000000000000000000000000000000001301306d1259059b5567154ef6e4779fedf98c29ea967ce34b78147c5730f202e1c12d5b5094219bf85fa62834329b45909a45c8b78350e3ca21697e9f56d5fc8fc2a01817b78a7f5daeda487768ed1e000000000000000000000000000000001741f739459f5d462fc9ab55c68101a5a3f2741c05b4c3eec6959b2aa5e12493a19d1b33a9aa89337add642458089eb6000000000000000000000000000000000300d8b7988522706c0690da52d0a67ae41344e43cfa05d22feb91eb8635bdb970810e993e0ebf8fd63ab8fe3e048d660000000000000000000000000000000007c003cfba125692b88feba85e7288bf61bb25e04b1462f7a39b4198737010224ce4b73a320c81b1f70119af34d381d1000000000000000000000000000000000a4870c9de67517f4353de23af21fcfadcfce55365ced33a61a19e5de52f98721b17c6eb382970e7c4acd81b80a7bd2f6d4e2277da617f0ad530b6209df6264e1288122b1b4d92da04fe334be17bd8320000000000000000000000000000000002eef52fc72d5aa0456c13808ba548cb765e11cd0bfd0599544793f57c8a27ee90880e6577af1b76b3fe32c4e71f4104000000000000000000000000000000000ea99a4f6772f8114cfb3ae9dc20f11a34880a86088511e5b7fe521d50470148b43f866eb5bf4f67c523266bb55117050000000000000000000000000000000004bd802b889e6d18df7dbd65f39a908cf5889e14be51b5ebd423ccb63e4e5b35e429eb0d4f384b811b47975143ea2ef60000000000000000000000000000000018dded357c546d709beffff2da0c08e8059c720023234c7b53d0ae85750b3e166cde7faf340697b546b8dd7c13b1ce7bdcba6bed6b8c42240c01df5fa0ea81dd96168c6d98ee9d5d4653edfa5172eb28000000000000000000000000000000001405ef521bcc60c55f8551fb2e2aa7b10117b2f96c03e8535e5bff48ae197b7e5fe69a40eecd25a67f430ca02edcc9d2000000000000000000000000000000000477d85a7dfffcc5a2a1048205362ec42b268e5fbd27ee7c8d4ca77b5c9db84dba482bc4b164f92db2c15cc518b3d32800000000000000000000000000000000060988548ede00aad3682fe827d1e993ed1cf118bec7cbe6f69bc160f030bf87c299d40047a4fb5ee27dc2814649a4580000000000000000000000000000000006b9e0579f82fcb8bc149e40b1199f5897ea48ae5eb58abd2002c923efd0f5275d24a579bd904e49b7447c4a03e3fbe423d168e01657e5c2da89a27e513bcbc6620b8c6082bd39880619bfe2b3a7317d0000000000000000000000000000000003cde2bfc5a865cac624d9018c37c1b5746b5394597d79c171b25f84d5fdbc76bb90ba5cf9db14b3b8e62ff91cfd79520000000000000000000000000000000017596885262075e45db62ca68ee5b99d12223bd476e36ed4ddbf5cd56a0c6e9db5d79e7f95b96b1bc323d7c9fc5447d800000000000000000000000000000000018333858871dd41cddb7ad2f179f1f341b2ef20bfc7a1d3cb235e3a1a181e0da7251911886f0788e0f868e16520c5a200000000000000000000000000000000098ce44092980cb14e89faa7efc2906051c9a51cf7b2757dbffa49fafa3a9ba145f809f1212c27aa620bf062e839f83c2a76fafc5e8e33852bbeb7ab8229305be84f5474427e0c6d2ed35c7bfe99faa1000000000000000000000000000000001180d554fd523a51e0decb92e0134c6064a17dd3aa7b11d590b9b6022f76763b1e20562da21e836e65374efafd78b77e000000000000000000000000000000000488686f793dde899a3f4936f07f9eda7918450966ca85b4715d6fee978d9d091bae1b5d2d04943365c076a849b3359c0000000000000000000000000000000014661fb2d305ec9e63d63e9951d0f081aeba99972b094c922d2797a1100759cfe150812821411205f563e22f01ef29c50000000000000000000000000000000013dd681200608466853cd3bfd20f146a6383151931079654962684d6c6fc3bd6900bb049483c1ca6d2819da456f67e3be3c7e4e95167faed1391e269785918a207490c6d186bf2537c02e52e414d564e0000000000000000000000000000000016c8c7a2a1a76ec05770f2d6c8df35003104c034c76323fedd49663daa759caf2f4fefbe8d44b3abf1dadfec2a06cb45000000000000000000000000000000000837305004aba2e322ae29e8f0109f1c756a44b21c72733019e63ff9886a639464090770d12d35553f0002ad028332370000000000000000000000000000000005c8f82ca2d4f6785e2d76ca3a3d1ac67aedf78e9ac833c52cfda6289e6f5d7a83befbeaf753abce12376889caec312f0000000000000000000000000000000013595cdc9181ca70845c613663367ff774f073774688dc58edfd0c58de5ae12df5acd04a673b645371940d7f7e1601045d335e3d96a9b25be7f3916e92fffd75abeef5b91a1ec577ced52a96f6a9b10c0000000000000000000000000000000010f1b8b39ea8ffcb6a96bacd1c00b413c93d3f8da64dcf9257a7cf0264831be23ca63ab8d3d1cea21ed8d83ecaa3a0c70000000000000000000000000000000017a9030fbee573cb71330007900723f85e9e82530283f713f72e68c1d9a5ff9552d0da469a4f38b66e30df1514f922a40000000000000000000000000000000018b9020986a49213d4f3b4b052cf2fb65f82b9bc2051f20b399f2784b984ccfa2752ca576d352c7d65ab218bb8d5df870000000000000000000000000000000015a375a3711f5e9f85ad7266b2d307cac09ace9ea36e149dde5e0d5acdbac3f62e1cecba8be51d88f2143c3070eddaf0fa563a70780837ffcf9a84456f0b4f6eda0d60cce6a8538ba10960eaf17362fc", "Expected": "000000000000000000000000000000000b668f602b9f56182b74be413d36b03d2266d7165386a7f1f0d25d336d06d2bc5659e80e54dc71f153883292df1cd8940000000000000000000000000000000013151d305bba39734538fe9a2717392bcd134ef1f8c1879740c8cce981a2d70c94b23f1a71a0596e7ead55a55eb186c80000000000000000000000000000000000e5e7c268f93d8a9d3ce45db2a95be906483aefa3831ed2ab2aa357eca0ca231927c0e5031daa200784cba33b96e51d0000000000000000000000000000000011d57d9a9123123f9fb56e990626346e5c76bbd1a4b3349c3f7bc44f05a899f9c4dddd67ce5a788f85b4fb172385faef", "Name": "matter_g2_multiexp_49", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006a7946b50749147573991c91f13cdef4e9558be37736e3d990c5750d31ba9711721b88eec529ea4b1dec1c935fafa9a00000000000000000000000000000000078d8a565b7f58b915c220882a73b6aaf100f2d54cce2524cc3a80d9b526c3058903668d17427a617ea045c3322ec502000000000000000000000000000000000733c6562cdcb28d740c64f50ee9d204af4ecc8de2c1719fb73c20f2580fcf01e1e494faf4386764e03920a4162049fb000000000000000000000000000000000421365fa828affe963d145d318065933d4d865f2a3d24469ab0db66dd09a574945f8a8b622d079a7ce1c6fb6c795a8f6e2ee781da12b984e7a08730a60f50c41cdd7c7c8b3f1f30f721923ddc34fb79000000000000000000000000000000000a4fdc68bda287bd819ebb0a296212ddd19cc76b042e134f1637c894ad64bcd8431392c9791f2eaaf94f6c8d189846760000000000000000000000000000000009d974fcb46fe81d81d62b24b805ab5108c9450e162454c3260ecd0d5356b7c263be5f78f6214cc7254e461166910d23000000000000000000000000000000001081fe3579cb4d8a7e7d43ca8cdda28e1f9ea8df83c6069f4162a2a0e68e0d5876b283193649018e754c5c8fef101f53000000000000000000000000000000000ca4faaddc4d14a6648e3515a8b9028190c17f771c7de086fe4624a3008d7e6e374c967f303d9511b9da1a95409e3cb3d51e0b65be993ddd2892ab8f47eab78352b177be4b3fb68f47c65f5c59fa866000000000000000000000000000000000117318e376f2c130e5bca89b3d700fe76e9603adb22a5ef353bb3b5a8f641c85deb4640fbaccf94e025a59fbf2a41370000000000000000000000000000000000433428497ed89a43ba07d816df224809a827194ca899924c3844650a3800952cda8db82f2f8e513994ed9893fac747400000000000000000000000000000000064889f1cb7d6ab216fcceef7c4abf89be14ef93be2d39bbba2b74d06999dec5ae1941b507709d093b28e030700cf866000000000000000000000000000000000957fcb8658497802e78b8250373f77acc4ec47fa2c87e78adbb2daef70240da640a7945895940f76bbb80bd36b4ba24fed4dd284df98923bfc3c41496d6e64a10815a8c474275e0cdbc9ed26e92b0ae0000000000000000000000000000000013f9771c105462fb6b975b0b2fd20d0accdd2d95d879c8019b08db394cd785ed9f151d0eb1adeaa63bbc2686d1172b0f0000000000000000000000000000000002062a5f2db0a01114a1c6e8c739f80f598f4e905952101a244853078298eb443be6839b59d4f0c7745b739cc89ad8220000000000000000000000000000000015b5485439f1b94fbb3a8f5ac6197f0dc0577863f39c44b34d4c5437b6a82a704dec17529654b3037a9ee1ebf14c8d8300000000000000000000000000000000154d750e2a660205812d428cfe79aef4e1059f4e231024a665889d112af37e6e17e04cd7c926b6240bf2f616a1f572dd7c36ec97c1eafc8a20a772fb7887d75568047ea32458b9ce74ad9ca058129949000000000000000000000000000000000231223930956bd2d36a89a0a0a47aa46b4763919455ad3a3581439d25a82c176569698fd5ca2b9429793ebb16c98e50000000000000000000000000000000000b5dd675af51c18d2dc76e3103da4409f6e8c1cc719a622d4a33aaae3f23e529c78b63c55b67fa999bdcc7095a4ece300000000000000000000000000000000010c971be55cd02e4c97031d3b25acfbf722e47e5179beb26eafaa72d4bd5f47cf280a99e0c3c4cdac05bf1572d01fcfc0000000000000000000000000000000002c1370919e6445994df1e25ff4a79c8cd8805f12e5d8c781e58f04dff68a97424b35d162d875ca2b3f805b4cd6d1fa641b2c0354d2f7d92b05043f193b718d78b457ae76e19069c8e1c2b77d7999d6500000000000000000000000000000000169938b4d3c859f97a0627bd1a83fde725eafb7ab77b22cae06d2a776569236d834702081e78d61386999c938c0259b900000000000000000000000000000000091e922f00828488e324f9fea652ce1edff83d9f479e843ed4bffee27805a5025e7a150719b354b5e61f381ebd24d4ea000000000000000000000000000000000334ba8044d7d47795b59eb089502808a7ab8f18e3d5e1cc49acdb5020b3973fd21d6d82557afd748dad88e45a7623730000000000000000000000000000000002299bf949ef249b5057c103ecd149444635b4f636a2fd0d073484404c1ff4ef71820260ea6529bee6f5b07f2ba94de35615370a76bb0a5f64d61b97bdb045b9669f6a0b7644b101d21a50483d8b04dc00000000000000000000000000000000076ab7838db87727fd653a3b561a2a5594518f296284bc24a7d215b1fbc0a6492d425078fd98f92a414dfcb3c92cc1d000000000000000000000000000000000022b71fb467dbd6d9b130763350bd06f52d20ff2cbd46cdea5e8b1525fd73bfd08f5ff171f9fa28050e9a3b296d3e9e00000000000000000000000000000000007e917cef0195fc589317d4a71c14022867dbc0db26c653052e2e382d0dbebe67a0f582bc0a27dd1dfb4703c545d0da30000000000000000000000000000000005b1d8651b86a403ad993c5cea4b6b82a0f8a9f8a59d4b94f10e68e9538a559efdde2007736aa9d04f585851a89af88fbcc38cfd3c6bdd32ed1d583f2bd14e175d61448c627f195559b751aab1ecf7cb000000000000000000000000000000000653c5f5b2d97239821d173036929dc716e78d835a80af55868dcc3e218bcebdc2a052d31f6a573572d13f3bbb14f241000000000000000000000000000000000cdbdc3cf52239a6d4bdadc273b00924de8730c03ea82bd20ec1f04375daa4497fff3a1726269a736706355e72be83870000000000000000000000000000000008e0285b177fcd768d3519062177fa1314c4370f872eaf10f3e0dc94e716dc6a67894d887f40104552336cbb5ed614f20000000000000000000000000000000000638db8269ea4c2fecd5b45955609ef6a1c2c6faf6ee5a8d777e0b38f16d1acab2da7fe7b6f6ebb315ccb345835a21d94c41471a2e4edf0f688c2f032036d41ef5f8a966871dd099dcdbced8b37e1c40000000000000000000000000000000005b4f74cd099eafa6ae59e7105873d4a46e8e5985faf2d26ca564125dca93b1c48187ed7afa02cde8b52df878e1aa618000000000000000000000000000000000cda7f9eeadda16ef757ee8a98be147d374d3a1d40790d20a1ae42c9ed38e4fe22be76ec4f807cf93fff5c6efdb50d1c00000000000000000000000000000000121219b0b0d236a89a857c02249cc04c22299d041d95296dd235b3639416337f5be4a2ebe92a50d192fb748d5d4dca0300000000000000000000000000000000112545a4677ca7d60645cb8bd98689c4aa85a68bb62dc68c0affca5a17ecf0a08fb9b91589d08712b5af4aadf31caad2dd297b192f1c907914ef949fd27a5ea5659aab659b83239c4433f7a4e24529f2000000000000000000000000000000001342460712b73ca0ef07d953c32d280a3441e108abdc2d133265160608986481df3563c5dca20f209ce078b13b49707e0000000000000000000000000000000003580a5b4a7f6d6e066ad9073f7105f6cc1ff35ef5e79a0aba7f48ff2b732c7aec72cc9c5f9233fc9c267d8aa37ac17c000000000000000000000000000000000bb7f32db8a4e341cd9f8dd3b5677dc650cef675f0923bf2e5c8b84c33d447daacbf68631c2388eac5698495e1ad5a3a0000000000000000000000000000000015bf9cd1aa585eda2910128f2b452569abc1c94bc8bd308ee92b6c7315a56fc92d6cba03334bc36c137c14eb1f198b07d30fdb174a3f5c06b78cbaee5b6e7a4c90551083d78c5164de6bb45ee5de23c100000000000000000000000000000000091bca266255d692cdfd10929802d79b474706d160033495decd11cb0758136ec3ae7fd4bb99081e44dd7f25224e009c0000000000000000000000000000000001fbba1ba796416ac22c92f3741e3b268d89fbf0307edf0f25c7c12b5cd230c41582ba69465686ffead9f8363dc0c297000000000000000000000000000000001139590315fc4d81e3e747a53e63ad856635050367ffc143c1422e324d5fe9e4fb90631ff8bba764a87b8077b571aa0a000000000000000000000000000000000dcbba28afd445a57db762d08338a26980b4efbd11668e4050d18234ce35a909d6b563a5d3e8e72892514431fabf0147aafc42f7fe6854866cb954367fa65c8072bd1b60173a2d45077421d6e25f2bb3000000000000000000000000000000001322b1f1388a9dd2853829bda1a5120250ed08f07c84fa398e59fa2577454f38f0a76a1e8db897bf15b4b50ff52a847c0000000000000000000000000000000017020d7de1dd424de53992c168d924c42f26231d184ea3cd9cfe64ad9c82ad067540b2d9ab18b0fd28477ac792a80c4a0000000000000000000000000000000000fabc0769b95e6feedc2165bd6d324b7d16247b79eebc1f09d849792255136538e628bd6ad9b86af7bcdfdd991fc31000000000000000000000000000000000144f39f792bf5585f4b49dcd3fcdbb61cc7ef471e08af4c15cfebb855f0ac8d5fd057c9486e53e8e1ee4f66bd5e943ad106da5f98d5e7cd9f4a1c8d6e50ea2236c2abdf1e08a0eca54555a59bcadbc6a000000000000000000000000000000000c27ac29db98fe3038fe5f537d5ca6faa240602abe11c6f530d9b18d763d6dda3fb25f9538d316e6527c114405ae54f00000000000000000000000000000000017ecc872183413d8065a99a2d1a73b70150e2c1fca2c13a731a39b52aebc6db79772e91f115a63f7b23e5fa231df697a0000000000000000000000000000000016b9715ce820b619274202b52d7e7bee9a17aaeb06c2ecab8bc77c670bd4c714789e4478178d94d2aad57e7bb0b7a4040000000000000000000000000000000002d0723a3386248d8597d2b63289300de6a16011a38985170a1652ff81ea70a78459b3ef252cc5ed26ff1ef1ecaf6a42c971deeba2f757970bcd4f5548a2767bd6c43e63f4c5fc4b157ef060a1f45aae000000000000000000000000000000000eb1ddb7306d8d2858fb57dac71f67473b813f37f02d73b17f375be86028176cc1dd84347f183cb7d427b861be34c3d70000000000000000000000000000000009a8811ec77eb21f2b33a591f2fe6d7b74b40c5045ceeee275912aeec664838f332bb49bedcd958ede0af0d0232e76ed00000000000000000000000000000000156e28ee3c40c6f18c6059e06ac8f7b39fa23e5962f640ef3afce13c169346a4c8e5c2bcdac8fa15921a4740cc5a0f2300000000000000000000000000000000084371522a6ebb1925c8fad3f20277c34e657aa71abf8ed7d323a10c14cbbb1a9e0e54bace32eb845e6709c1c58afc34a5262a021977dd79ab96606eb24a7c5ed650300dd68bc79f4b8378f58c6eed49000000000000000000000000000000000be2ef9ef38a5dcb42ad31b1415c8eceae625850db4306a26a0598d4a567936d75b701c81793fa7b42d158df2dcb0d5d000000000000000000000000000000000851b82b59fc15b89e33fb618c56d11a07116ea35850583a07066ed97b8a864f3766c0cf921d007a6cb43931ad4fcf8e000000000000000000000000000000000ea8bdfa3c5f000d7cb1b5cd69537e4104daa15ffcec06f40a91b972d8011e5fccfa911c55a07383cce6760c145c39e4000000000000000000000000000000000652a4165602978004ef702103ef18e8fe7decab1522a76486c742d29103e3bdf6dda2d3cd64ff1b5d5a76f4823bd363083b3720c20044fa41712039b6e9e776197391ef393c0935a0e9990fbc1b7a4600000000000000000000000000000000015ce5b43e1fd950b77e2baccae8c99b82f38bce09989fdc5d402420e7931a38b7fdac5a254b0cb9bd8fbb488d02493b00000000000000000000000000000000018c5b3ff46a04ed114bbf56399738e5d594ef8dd1d5e2e8dc23a0097893be3da4fa4662686a6dac04418fd2d344e36c000000000000000000000000000000000efa3e970a5cd0c7bdef6a2df3be9be18cce63c10c331a18d628bbeef30488ef73d866f3c8804acb3bd375542e99eae6000000000000000000000000000000000e966d9e2f2d47df5d661a89fafb6d4518fa1544ab7a56716df511cbcca99098f944a981c9da569cf95debb455842006d6f846581848f5dbb9e8d220b881d0327c4f3f5d4b79fb2c4dcbdb9bcf44b02d", "Expected": "000000000000000000000000000000000ef06b515addb951b24e5d61f6e6eededf5f93f9f17455e1b563f187f73394457b3b7c1b90ed454218f8782d2bc848be00000000000000000000000000000000167398608a87490fd17506166bf54636aa4dd6d3e8c4d42995bcb0262268eaf2a6d828b295434f45e3e53703aa67cdcf000000000000000000000000000000001602ec6519e4987a052f97eb222f505e241d99602c08ea9c41bc95796675ebf6a819aa0bf87319f29dfe47f45f3c8c7a0000000000000000000000000000000002ad4291ece7ea0fcc9f4440e88eef693b8dd53060ec847bd27d74cf71218eb6210a71895ff1f1f4537a901090f14de5", "Name": "matter_g2_multiexp_50", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000129cc9cf82aa30671e969148f058a0b8d275bcbb1c8da66e52998d9555dfaa075e2fcf39fc18f305940fbc972cc5c0c0000000000000000000000000000000001252482c1419ad72229a00d90f1c09d464e896f47db91e9680efe36822e99e1ca7a2b5ba8b17b5929fdbeff8993bb18e000000000000000000000000000000001287d5054bf5db038ec2f7b7a3b79848fcc8ca42f9e19d5e21d36d2256f97e0edc2608d19c17d3714024e1e9e86ae264000000000000000000000000000000000f6262669e30a5db67550cdce8a4611b9501d02cd4e950aeedd1c87c4f0f63c74f35c802dafcf91c988a154dd690103c67c44f7c8513472b51f96d526422bac628aad4c40c521cd7cf9e86eaf92838fd0000000000000000000000000000000019cccd010df3e668b1c3ec053e76c46e45d01a4fe02eb074e296df2a48e0e4eb647b06c40cf64a0048a8fcc2b0cfa6100000000000000000000000000000000018e07bc50657f3bbf736c38518933e91af29e3bafd776243296cca3a1d975116e8b428b050045a61069adb23baa22d3800000000000000000000000000000000154f51badda1b828346986264b01fb1be4c7e9b570ab63a5eb15cabe9412a2f9bbc6d5111c638ff5118a4f6d08ed055200000000000000000000000000000000064d4e607a8994c0bb65770a14a14ed1b68c766ac2aed45a44c0f7c7cd4c3ecdfa077206812cf9b24e35021060a3668d2d6f95d4b6216e4226f78e4fa5011c9becf98fe45a17dfd740fdd0ef36d8ba94000000000000000000000000000000000b9bae5f720d9bd3271a71d751e4c35c39ad30fa8a67846107ff769c455e42465b2a39dfa32861634d5e323878f56f4f000000000000000000000000000000000a1077046cf5c7a66452cec2193ee21c1ace50dfd79f707c9297737f13806dc05e9e1cc5d1fb4c87b250ebea5a4ca6c40000000000000000000000000000000013e1fbe1a9b5f2ccff51120590ac0cb00cab502726b43a6fc12459e27bad4aa41537d6f3cc94a81a170998768f6a0fc6000000000000000000000000000000000a02c551ecec1c7a415256caaec1b5485a42f9ca8d897cf26546ace1f2bc8c2d10a353b8b84495b8dab5e3c60881185a58c25d36216b811ee42d0ba629ab7a0f9ce7edd7234620c28e37bb3df3f042e700000000000000000000000000000000021b9ab3ad614816d7006efe688e1ae8cd99b0c4437d4363e557642a7cfda2000db6503b32db36b6d1ffe40d967c5efd000000000000000000000000000000000b7fb0ddd9eb2be9cdffaf8f8c593a9296c4c7deeb1c714c11863d71dab1e6fd309b75c41e25de3cb6089726b43427f0000000000000000000000000000000001277065ea9d208777d0fb7a6726e11c8330f0b3ed3c6716acd559aab19b2fdafceca8126c9facc43b9d80534c07035a20000000000000000000000000000000015e8c12065d601dd5ede75bcfceb7300bf6f9fbcdf68d2f093b7654d80d3e565135d64137dc401d691a45fe052f58a6850a5c6bb6b87fbe5ebfb0d182d425ee173973c6f2085c556b0fe60219b9f3c32000000000000000000000000000000000484c4f9652427d0649c33e93d666dcb15bc56669c00980c53357ecee874bcdbaa016236df65a4339dfbd44e4eb0823c0000000000000000000000000000000013836a7275c29c989891c94e756cee9d6c54a8f634fa570655ee44b7c1e34137edc33323dc0d1f3a0218039fd6f7013d0000000000000000000000000000000002e88c7d5fd87e97a0de1be95021821942a8004115fb4fdd9ad26b7e0fd171f9c7e6f962eb179bdb95ef960cf9396372000000000000000000000000000000001636e351a0ed1a260ffe0d1355e6da288792fc97a7310b040cb9fcd5c550d85d90572154d58a9847dd5a8a06456bb2e43b4bdeaf6643ed159f4a3e23c33ac486b33e1edbc5a097a47a6c2c753e5299d20000000000000000000000000000000007579785c14fa012cb5d6c116d34dcc15dfc908a29e90de3bbfb8c9b44e0b4258644440d7c78d751a007c10f98053bd10000000000000000000000000000000009f023538822ceba0883a0e3454121dafe8e5e61d4754b54e6417c989efa998334641d458591b3076b615937de065cfd00000000000000000000000000000000130fe7f2d5e0ffefa67ad3378690c53a6e68de5504f3691de0df3a24c309619bd3a345bc2bec4dcfb4b77255cbfe09980000000000000000000000000000000015bf85ed997eef4d97a81f1d75825bb4409cf86b8c8e5f4368cf1e4c803f9e1e23a2a96f7b0a08e5cff55a78761ebce21d18596bc392dd0b71e1216bbb20a0e5e2559a46789c36a146cb78c5aa8e3921000000000000000000000000000000000a95597e4402bbd17c20dda088f0134d42f14443bd519b3511b28fd8d395a0e50758386498388ea6ad0e7634587336c1000000000000000000000000000000000079f348d3de505875c5192f795cd77e2f7385ed447b06f2dbee18e85c832386b201cb3eeb21aac3f258d2c4b0434d48000000000000000000000000000000001895b1891a08ea42eb1f68698abc20394ffd66bf0c32979668950bfec5cfc8425314eec2ac17ba25f29133a8becc9f5e00000000000000000000000000000000146160336d881b24c6258a3a86c08d346900680324632b6d5d4582ee0865a7e5f2d01677e5e49c5a4179f8382e49d1566fb3669c0789ba6a5b00f14c14fe2edd15d37a742c9e36cae9ac010e632d75a40000000000000000000000000000000013cadc6c394efb2f93e00f3976dde34efe75adff34bfb6f5e1a150b79bb5baf6bf29fa149581fda48faa68653cb61e300000000000000000000000000000000005fd25362d87f9581a202b186d2786d2859faa9966a1ceae747dd7a48749abd424eb9813e44caada0e456ee8bd12e99c0000000000000000000000000000000018e6b279e2b545acf1da29dc0504caa5982522546f83d4d3389e1fd6cb5328d4a167926a00ccaca402b3a3cdc67d757400000000000000000000000000000000089a9992a36b476fee21abd50977dfee01d7c91b24b3e26d7c15b2301352069dad920f0ea93a3e477a48029eef35605f06c2988dd6b8e9aa116eea4e1f63dacf100019844d37d163c047567e8e1188620000000000000000000000000000000005200b78dba7e423bc23e87c5937b464e97405f6461d05bd9d1d0fbf8f3c8e64a39081f9e43b4ec416198dc44db897e7000000000000000000000000000000000bdba1ed07c4a570359863a1098a73830818b3fa5b222316a3e0692a4ec65e59ca6b4bf5f72f8c1384e73e807d272d6e00000000000000000000000000000000073fa3eef473707b6aff37fb6f829f0fdb7ae808e85ebba4d4924a185c3656eb2856896307b671080347cebc32e958bf00000000000000000000000000000000076b56330f07cfc0ab34e98e2fa0ce4702b296a00f6ffee07c3ab523fadc048a047ccea7a9003c090951e4ef698d14e5fbf8322f706b1972f73fe4e22a3dad29c4ede09163561b2810cfc3eb2ffbc7ab0000000000000000000000000000000007252747c8275f87b21bbac4071c1826d166d14e6205095e5299315d6b6a85aed995f9ba59a2163ce2c51a8e60eaaeeb000000000000000000000000000000000460a000fe29cca24dec469ba5fb729edf3e443bb032d488cc99102a614a5251915267db003dbf395132d815ba78f262000000000000000000000000000000000161c01cb4d0942faf2303c108604babbd4cabf5d3d30c13d7db9428a445c7f72d96a7405e22e4e451058a94e20068720000000000000000000000000000000010ccf8a8ec4e6515b20e07057fb8cbecc5defb87480f3e32a1bcd0cfe239e00daf6a390c4815ef6b85be1f07a4c4bfbc4a46618381ba6b991b2edfdeafa67aef1cfea066fbffdba24db25385963326bf000000000000000000000000000000000e6cf781162502d2a758d0f96946bab887591b7c9ec9f67a1b0b962e74ee514e84c14bf67ae3c0a9ea2a3e472b7ef59c0000000000000000000000000000000001542b4e97f1e8a64ffd51ca43137b0660f897f6b3d5c6fee598fc4dd03932c3658ea55e1e9e73376e51df278ddd3a3f0000000000000000000000000000000016dae882ba240343e752eac68122424320d1acb1fbc4bd26c3983dd91325f25e1b1f06213e0e06c142997a13fbeca597000000000000000000000000000000001138b71c95d4de320f02e68dae9bb0de3e5b317cb596532c5cc18ca588cc8566c21551d7d55d685591126b9d9e466455cd05fce871e4ff11e7a4e834061c65a0aab7bfa8a0128d460a493337c6e63ebf000000000000000000000000000000000904f6a09f3a5f5baac902c702b059835737c06f62c2ffe9101bac32f854e4d72f74031f5410a5941612b1aaacbb50920000000000000000000000000000000012f39e7022150b2be12cdd621ae23525581405021b21cb9e55972724a22b1aeb2e15b135ceade132d3310e050e607f65000000000000000000000000000000000a92b1daaf23524904d74c3f149fcd2c98e3a4c257113533e7cc59c4656b785aacbf0ba6b9df0dc17cf7c25f1ca698c5000000000000000000000000000000000a20a5d7c0aeb16ff498f46bf05e512784d120b9c3c8b2877411852d7da3abde9e83a6d00213bf69ed88bcbb051a486daba9e37ae0dbb733af820743d8e307fc02a3ce9b40032b16d0e9466903de9caa00000000000000000000000000000000153918807d7da07ec7014154f00a558ebe0d5fb48fba4c16488d61a826a1eec28e3828d6744300c04207e8ff1cb61211000000000000000000000000000000000a755480457896c5a3fde35658e73fae821151c43fb92e9ffedcb05fabad37cb68aa24e029fc33a2518398d723c4859100000000000000000000000000000000148798bdc5b14b90aefc38946db93be1754f15d78762f38971b1e64a53fda92b96b0a70ca2548baec882887ae7f636910000000000000000000000000000000012299fc413dbaa77cf8867e331bc0602c4fb32fe44a150217de9e6391374a9ed83781034e5775c4933e13cdfffd25a9e6ef151662cba4952416eaadebfe5e0fa0ca1d31380e1540c2d5e0181af9e317c000000000000000000000000000000000fdfcbcce1603198fa344487d2d4838b3ff23fc0a73a76222707d9f8623f0b87dfc816be8717b0b12667bee460ef40f70000000000000000000000000000000015036dff68139419db619912e2d19b7d2a2d637fbb8bffcd941aefe2eb4d24c1f7dc32f4f53d4cfce67785e7c328d6c4000000000000000000000000000000000fd575be9bf54128a9a1cbd366339c993ced315a840d60f8b77e035352bf705c01a9def713e8cae3001dc1062cc0723b0000000000000000000000000000000004015ed456125cf0f46fe0093b81ff9315d955d470ad756a9303f548819f339e137305c58e6f4d8db3c8bbfab90718d4f0a3851bd52ca52919dfd21efa6efc56f6dd5060ad969360b1a731e8f38f0f5d0000000000000000000000000000000016d31e68cfdc5823970c8c2ebc53c3d4517792c44e90c10f920a819e72e4a6966c59a691b905c8b0b612065c56d86ca40000000000000000000000000000000005096d516e416fdc0df552c2688c74f1c067a3e5e7fd782479bfa468096e6ee3e601bc23d2e38ae7500325765483250600000000000000000000000000000000092c994e9dae287bb6450607a4263bcf6267f0f66ba3e63436292af7f6bc8e4ba794a12792b6af49ef59b5fe50ff6d3400000000000000000000000000000000175a645988f33612e969e1d91b2c30e47ec655ad655d89cd8dac151c3bd194cd5a8c28b498b1cc2f2966b7fc37cfc8c532b41960417047a2258b6e9e228f3cc1130b296cafbb75f58731a81fcfe8c83a0000000000000000000000000000000008d09ee15c80facf7e32b15418fefbf7e80400acf37f2a1bc6ced88b1591bcb8f86b45b544646c5fafa71b5b103b927400000000000000000000000000000000060865ba68ed8fb3d0a05779c278352b22d4244edb7add23d985a2836d2772dbffc3c82c3134916e9b0900c9db6ead8f000000000000000000000000000000000dce53bf8aca1ed44bee47096dd988689c1e32e1e65a5f8dbabab7c4edba866132ee2c036aba5648d0dafa9a26405fe30000000000000000000000000000000003319995785be720860bbf48692d1507185d898187993865648ded74d3aaca45df939c6dd986db42a51bd13579a55b8f71a6f7f091a6a21dbfffcec2eecaa22d05252b60bf91b56811a833dde3fcfde6", "Expected": "0000000000000000000000000000000010643af30c3cdefc30144c5d7cab17c9c54adccb3294ae79fe5c69376011c159be1e43940640bf5d9012ccdbc997e2090000000000000000000000000000000002a22b08904ea9ca99103a01caad745dc2afb7b6d23e666770e81a97031de921f9d4d1c04fa941c433b8cd9cafced3a10000000000000000000000000000000010808e5518eb6cd61eec8820b9f279dba2423b1a3677e21fe3a0ca2ad49fbab2995de1c5adc9ac867de79e3b40ffddf30000000000000000000000000000000003ce1270644d71e0055345c7463d72dc119495bfa04a818dd398d944ca46deb0aee8c7936557754fa18225522fb79564", "Name": "matter_g2_multiexp_51", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000059234bb6d1b66985b79e6a2c6cd158d37fc50ccd6e50ad2fe3b6a02ae2ad35b8b2be92139265957ea698441e780532100000000000000000000000000000000066adc7083a7f3dd75a8e431a36632dfcecc2527f261e961335bbe8fc8329d992880736bb41fffe41484f68c38fda61a0000000000000000000000000000000006aa0794c27d3f60debbee292c28b430c159cb2874b9467312cb857a8777058580f8a2d3b9bf4b8b732edb185cca6ac10000000000000000000000000000000000d81f222ed6acdf29437adf26d2b785535cd6d61b329df98be04114c3ae68bc6854e275792fd48de3eedf6ba7f3849a2e56b63fc6ba87cf021c2f92baec248756ddae0a4f070df840db281283a4c9b20000000000000000000000000000000013dab8066757b8bcce2c9965e600c31b792463623cd5561f7f6d55c5a52c22efcbe48b8684fc2dca87e2945765bf565600000000000000000000000000000000198a0594b5e606b18201fe2706bddffe7bee6c583147513333230715d18295714055b984cd3ff8d1127f9420863e3a67000000000000000000000000000000000ef77ae1e991daea1fe8338cf236ba959b22df4b24f00c6c01483b6956c609b805ab89712f80892bc0160fa3775907890000000000000000000000000000000004d30f5a866a100dfe469d4d0c47872245c4cdcfb18d3ffa0de422691044b52d2b9335682dcbf67aafa9275712ae3f5512a50af55f47fdaf176d4885e4910c54428c8ef433ea0cb1d009ea77783559470000000000000000000000000000000008010bd5fb5e222618bf4f919c203dadf9a7b7597bf90e16772020614481a0963a8e8b1bd244661bd33e0d147be7663c0000000000000000000000000000000007e21f548efb869a28d6fe39b999ab7fedae9cd6cfa531fe608476ef30c8703951839476811838608dac1aaf9cd87eed0000000000000000000000000000000006cc674c464f80cacb2156fc1eb680938cb38cc166a99f72daa50f9d2c40f10ff07e447d7bd5e59b6b22f0dc407dd8df0000000000000000000000000000000010b160c58ea82bc3904302b1b4fe83d1883efe3c8f52c4e05a3d8681e604eabb1b7f533e61c51e9a172987383506e7b189a012158b3c18e19471fca6d5aba5fd004a337d49ddef5db177da187c8cf1c8000000000000000000000000000000000d4f8372d1138489913654a7567735be1eacf8c7fd497c2216bf77a94f483bd4a7daa2c8232581d6815af9898a7569b80000000000000000000000000000000013676a1f72cc2ed80fa24f70fe1c52aad9ac13ad6cad1f519649fda6ea3787d86ea164d9ac86de96436e9db4fb4aa44f0000000000000000000000000000000003f7644f7ddc9276ac36aea5c36451f3d5d6e4c508932b16d5677977108f04deace5e8cf0b3b3dee88c328b6030f3567000000000000000000000000000000001953cf03effb7de9e62937572850e9fdeecb74fb4aa655de1abdc6e065920e6d2e51ff28880f33341443b5e6652eff4827dd109f6df1d9851dae28bcb9e552c6b1e1b2dfb331aa955d3d0b6c4862253d000000000000000000000000000000000c76a5bcbd2a61172fdd53b351d143bd30d460e398c9d4b7094a604ab2c0d46d6112bd8a5483c9935f0bf6d84df04b9500000000000000000000000000000000116b15825b780c49fb24617dca620e939e2528e10c49f34971736c82cd35fd3965088595deb86eaca3d3239c6c78a84f000000000000000000000000000000000a0cdaa541dd96fefd46b303b88f1dd4d24257b910a596817f1d946873cfd60ae58a88aa687ba573832331e8fc158db50000000000000000000000000000000016259f7285de159a2c6d6d8687ed348ab97e8cf329ea5de49b6d708b6da5b806bd012ca3641c50f479d85921e20fbaefca96785c1ab66cc5c8e434f59cc1ddf76bd78b6fe660f7cf74cfb79d7f2c7f84000000000000000000000000000000000797e815a98d362e1d7e2ac1fdcb477ccdec8ecdf340d7bded36856ce30e92b661669b38ecbcfb0896b2fd75df9b734a0000000000000000000000000000000017916c559db6b4b28b798c2027e2c70ba1b940212df8a1649b9f6087120660d698bea81258e2007edd4aa7d0d535bccb00000000000000000000000000000000167170a76db0783a8c3228f8246502b15d342b019fb44a46b514f4ba2de3ac66e435941adc3d91874371561870ba87150000000000000000000000000000000010097a585eb9264ea96904d8534820be185d8d9e4b1616439a926c0ff8ceb6f2bc082e5712454690c9c05b8018a996235aabd1fba36142bd768339e091b15b7f5b4ea609b57947a7187c498bd9833c2900000000000000000000000000000000025eff57e1f37903056835d1b4133ce064c86947f35859817b2cccf1a5c3923ccca766b3e0affd20a4a6df62a45c31000000000000000000000000000000000011158fce4ade070629162b2b6cf1924696f1f7776f3d623cfa3d54c66fc17fa0299c6650b709a1472262fc0abe8d9557000000000000000000000000000000001828a65fb90dcebe25413566deacf0677a3993b39d68854b264fe7807097fbd3106ac618545d3a6a42e197c65f0d2a7100000000000000000000000000000000045eb8164b6ec874467286dc3626fad3c01be61f6a8a88e5f88797978463db648a9b8a1e1a2589364ef2879cb5f75423fbe608fefa5472c7d1611abfa402d2eddb1e54542f45d4012db8ac6d1e5016100000000000000000000000000000000011847bdf2f67b40aac3426716391da488a8f0462b68bd35a8c1c762591e2f426f48f979a646a094bce16bc99cef7fcfc00000000000000000000000000000000092d61e408120b1549fc8d2174572eb7ed3f679327cb89754f326fa72fbff79e98cf5ad9c94c14dd86135e9aacc98b98000000000000000000000000000000001440e2f4ee2ba254a780a31b02babca093a38e5a1ac09ff388080b6c60918ae5b26e1c0888ea0976527ba103b257d02d0000000000000000000000000000000019797e49808b756128866fae0d6aa7e755a1d6f07f7e6a877bee150fe9adf0cfe612350c5a0e31d68cbeed226fa56f2a28d57066cce439d8d0385f647ed5e9b29e8fd0528c1ed8455f37dcd81f4b62240000000000000000000000000000000016d723a64ee06a7a631509c6e64b1c8bbe199952da532dd92194147bce9942cb4a76f2358e6c7d263916fa36e2c0c09d0000000000000000000000000000000003d04ce655cad1d63748f6eaa9912d6474a34820986835f60c812aee9980d3ebc18d6fd856a6de9546be024b2e95126a000000000000000000000000000000000ea840bd7f76f8e944f95146cdc9692d97e6a2d7d16d4a7f054f81888472da4d60ae5faccb72d3a05781b399536ccb1e00000000000000000000000000000000155a1c43c39e9dfc6d96e01c981662900fadf1a46aa1c2fdb70bb34e94dcbe86c4f255e259c771ea8ede50b388ceb2f61208d8d328014a6b2c8b2b9edc70589cdd63d38f4e70abb41cff1b7693bf9a290000000000000000000000000000000008f189d97f7d82aad87fb71d090a5c99d94079c0b74beb3dc860d440c0f46727fc49104d671bdcbe5b9551552e18afc60000000000000000000000000000000010c4edfb64b8932a617c316820cd27d3f6ffa89b471949362762af8e10d25265b84ca2aafd3b14f33c39a4b533da60d60000000000000000000000000000000017ef3bb919b087fb6745bbf115e2929394fbc9c89f65e7d591f15da93ab785aa6828ebb6ced99d3506810647d28ed814000000000000000000000000000000001591d8213ab349017cc93f1fbe6aca6765dd33ac1f468621e2c79e30aa73bd7606a0e5ba1d97ff03e0029dbc8ab1c5f4d3a2044ed4f938c17684413625bdd281f685abea2e375bece77c03d697c82cc20000000000000000000000000000000019b3a2df3a9571b066eb451e34d8a38c0d90b6e365862bcd92ae76195956c21c59441f0cd03cc69abdf4ba069759b87f00000000000000000000000000000000082537ef7f4bba5f32db4443abc8eabceef643b0878ef83860d75ba508369a3b459cad96f1cfd872df99548f656b0f9b000000000000000000000000000000000b2fda5ba0c405c9481edd598181ed8a59a8a18462508af8c5d66988a7a58a5c9635d93b5e0ee310bd35e0091fcd4986000000000000000000000000000000000af7e15e0052576f82e36e7e2b614dd835a290e05f2ed9dad7f508b4c04e8d437e7e937a7f4c88b5e66b06e0beffc4df7fd81e27a577b5e79929614c069d6d52146a6183822d25cf1ef84d8afcc1f6b40000000000000000000000000000000017a1d5add5601010d138263b4793149a02e8f4f7cfaafb69fde7b843a51cf5f0634e26b6e5e3315420d44b0fd205230d0000000000000000000000000000000013ea863ebe1b1cfcf4164d78dbe8fc809d2b82ef3e5a2589ca1357e48dddf2696e910a90301ed910fae77a1e462a5b1000000000000000000000000000000000012b40d9f25dc5a61454ddf1fa9c38e87eee60e55938b411bff9cf2161ebd7d3fc930131a198e7e97dc90cc245164e7000000000000000000000000000000000054f19ed8e2682caeda10c252f11706e7f3b65c81e7ae0a617469babc5f3268fe5c0ce2e85d44fb6731e8ac132b97c3ac5d47ce35d4ede84a83c9860322f582ec00c872b4b035d5d340981fc29884f13000000000000000000000000000000000ef0378945ae4683666099be36de3e60b5bae9c3137b702e5e4e35afd5c1e81d033c3d6b1debf5bf36bdfc4e3af37759000000000000000000000000000000000c37074af84ff596ff2c7ff963d96968464d6c8d88b69af64ae883457d02ee9ec80720661f39019230a6531a0f2952bb000000000000000000000000000000000454e8aaa2830f07d86eac7aca1d7589fb06aed646146a1b90f4959b5caed73131ab231313b50c15213f89566ed87a3600000000000000000000000000000000143516cd7a1b8da41226cb828887a0b3314cf4f87c207d1d84e9c49f0f7e548ab99e635bd126d49fd2e4dcea98f3adf784ae256d47de2d49b1e755cb0e972f3b614f3e7ba779c65ce175ca3811021a7f0000000000000000000000000000000019384e15a8754c6d85bd298ed550a26b51b714745bf2980b4920d6e73f59e657d85d3e86baa9bcf7e971233daff99d02000000000000000000000000000000000229d233d605a1a9f060605ae366a263594d8fa2b7797358ffe4c62431b9718d155d24d80bf5af1c806f447b92fcfbab000000000000000000000000000000000bbfb66cc0c7bcf251141c540f712fe9a359d1ed36d228379a1f3791991cccb7dfe1a10d40667ca062cccd55c9e6b08d00000000000000000000000000000000150a4d7a003cb81423604c13d0c5175183ab5f459b96842939f5c4cfbb9196db4667bb4382d2d5c92b70800adf384569a09d0136d4dbb3abfabcac55db48b1ce302067f413283fc1a21744f1c16ef7b50000000000000000000000000000000016352fb8e2751f126fd0f889f2a62a85b95c50d6bda7704112e4487dc94417218b0daa1dd6b998662af2582c44b011c90000000000000000000000000000000016bf4c60eeaca103c90643fe0969c2c261e9697ddbc02279f0d5afb5c905a984ab2396db93555cc2dd5682a1525446d00000000000000000000000000000000014be742feb1215cbdcde21e974c74e23c7bbc2cbfaaace28cf1d4f2b5a77dde2f3910aea74bc200277e6fe0475208057000000000000000000000000000000000bf98dd3e3a8b13e487d8b1a35615b0c6b0f514f9b8da7d6402586f113974c8dc9561db797a96f4f8040c1765518d175650a6fba1a5eace6b455ee780ff266c324f49801832640856a80098f0eed0b7b000000000000000000000000000000000362935e552dd01b5fc5a15a76faae937d7ad086b0a67e9cd3558287274106623deb85b6410bb4e64c424d44335f3b1e00000000000000000000000000000000096f23a54cf57aa3306df0a0a4f45aecb9b09bfe83878d551a59c53e18efc5a9f177cb7fdaec1648f66cdfaebb15c61d00000000000000000000000000000000135271fbe0cc0987e82f3430eefa8e3cdcc1be4a441393bb3fac0b8e8f78dc47ba2b833d9dca4277bd60befdf33275cf000000000000000000000000000000000dc1b7512fa5f9d4ea3f4229d947f43d7dc46b7770aadbd7351b6d48d525d0144183f2c84293c63c68d5262851401ae0282cb1f8f6d6dd81e7c49176503a76837a96d7f2b084d29d11dd9c6548cf0a57", "Expected": "0000000000000000000000000000000001c11610b63eeaf9e00552a230bfee290ea49bf9c93cfea1b6f684c9b5a07f341b718a0070534e0da9e6ab1239d800830000000000000000000000000000000017e8107113714ebb1743c34d83be3acde096bfb6cf140e943ecd0831ecfcd097f58d25a45005db61551a01d9da46de10000000000000000000000000000000000c2eff6c7c25885c514aadecb8f0465a0fb4385eadffa082e8d4f497b10df2395be5e7760a87bc26772dd78701146b730000000000000000000000000000000011ad4e20f5c1518c72f75d67a897f30100dbb83365ef7729c3501c6f266d6002edcab8c8bc1f449c30ec3624cda13809", "Name": "matter_g2_multiexp_52", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010a26eda028649789d9e01232884e4e5a6b8e0b17169b9d64393e2568b09ac4d3e61a5996108655c24e76abe9e3fb7380000000000000000000000000000000015e4e36bcad524f8aac7f909fbb884e879caa735f80fe9890d7874be919ee727beb2a074984c047dac1d02b8712afa3a0000000000000000000000000000000012458946f1e853a7a45861a92d4ce707e5aebbf69edfe69190c0bb130141a10869e2a73e06785b568248d5b1f647e63e0000000000000000000000000000000004d8061f25edb5a510a2db9e1df850518156138c78ace50f4c9ce47734a0b14352f5283083a232602a070c3ce94c7bd93d7f8fbaa4225f3008649eebf42315785ccda2b9ce922170e606876881825cb90000000000000000000000000000000000baa40ea518227b007b9714ae6eb5a4e92883dc75e6328caa780bb2ffee7573dcd7e9ac47821ac449187569986bd2980000000000000000000000000000000009d43d61f070ae308c5c285915600dd9c17b7de63cfeee6fe33c9ba857b3c72e057bcb4d4ac2b492797e7d785997c18800000000000000000000000000000000185215a7fefb96b3ff9229cc3239c3ce5202a97e275ea9b1541d7bc0a2931d7e3b01942febb45c6e96e66e3605744afa00000000000000000000000000000000103ae58b8066dd62c46c14c593c768fda91b90e4840b5560c974ce69b86bd6d2c13f689b72cf9619e57c9dc8e3d3fb15e71e6cb3d4e19f4a70a4465df6eec6326f558ee1cb99aa540ad2a73c363a133900000000000000000000000000000000075585f862c0e0e031efe12f31e159f2a8b89825ce80fdf65906474f0155f397fdc666292f6a7384cab790f071335c49000000000000000000000000000000000eba3d37a5cae738ab99ed9475c2c7fbb88ff54edb8490017162dbb16c8225102158a266fd4ba7570ee6d5ff6cf3f5d400000000000000000000000000000000135a0b0a38c036919f8389eb7bdc505a375fd75d513eecf0cac134645d60fb6030a437ac6a0fbbd167b7a77a927b3b0e000000000000000000000000000000001688fabd4ad751598ca036ec5ef6d7b314980dce7d8652163e89fad01b233af64defbcf352743ec478af42587f58177dbdb2b3c3b8e91540dc2724537526fd8c0d4b85d2cc20323d71fa5a4f61b3f12a00000000000000000000000000000000062a74a9ba0e2e8d95fca478be8d18fc716243b1faf7365a55387fd7188021f53bbe780e973e7d16c9db236faff176cc000000000000000000000000000000000f949be3fcf9b38995624570fcc9e7df9964d038eca189336ec39d9e0bd05148ff7df0b48436a2cf6e249e52248ee8a40000000000000000000000000000000007472e7c366419a0cab844522c46356acdf6a12cffae941fae3d3b78e7a83f0446c945bdf7b247abccaeeaafec49026c0000000000000000000000000000000006a564e6860b97feff368fc9a349282112e591a7a6987fd10a2d4de8ae4384ce229b9db9a93445f727eeec55a6fe5a9def0c8574167a3bd3b794f057ed01865ea69c38023dbddb0afdc55dd9523ebab7000000000000000000000000000000000c073d2885eb125d3e7db48127178bea2c5bb0f09eec7081f15bc6fe6cba156914fe1b1fea6cf14a21a328d831523ec300000000000000000000000000000000010d93564b2facde13d29dac198c5f5fa314a0398f30c6fb7fc9575bc83d4e97edcc1c1d34f78728729442777718f54600000000000000000000000000000000136a4ffaacf0b4a607c677ed343c1ad41a1eca49c7c48fe73ab2f74084a07cff18f07f54a7f8ea1bfb7fa3667863bdc8000000000000000000000000000000000fb0c007a907ecdff7bfe2242097caf0c5001124d112689a74544fe4fd85be9771632e7267a1cc7e9f66d7e4bb4c954c3ccc75501428d3be8bb469ed0f2df7dec10e1d205e11a907cc30c4a76eee3cc000000000000000000000000000000000032bb9f20fdb19f578fac3008396f5dd0a70860f77f8ae7771fc6253569d47b72751cd56bd373dbc5eadf55b99578861000000000000000000000000000000000c4a4bfb5ca6f9c1bd69d7377c6da405afc3128338dfddd9aea19aec5e1e0f547e3febd28445af5e27469c87c4ac15280000000000000000000000000000000003b551547af253d07625028db4b9a8da2a857bc925620c5d561bbcd3e063eb460d9407cd4d4813800551e5d0d23a2ea40000000000000000000000000000000006d5c69a251e9a042c66bd4ee92d4f3cd4e79704b1b215c15b319e09cae0d798eb201be24f407340dbcefcf2cb87da5ae5e403f555fbc800f1342275f18a73dbb679bd31873ee87617090912a52d6a55000000000000000000000000000000000a5802e388f7605bbacd0bb65ba96689e223379214fd7a92de9a313f55d66cc71ffc9ab3f9979b75edf55647ad3b6c94000000000000000000000000000000000f86f968b5c20a81f18074803e1ec55ebd73bc87451c48d5bb61604ebae46538dcc9d21cce062abc07b4b9e89c85bf60000000000000000000000000000000000f9fceddfa8fb5bd76fb7c8986372c32ab9fae3c26e9fedae892bb55178fa2f3432e6eab5043496dcebef46b20bf5824000000000000000000000000000000000dcf7a118881aea4e6a0e4e305910d4e4a5f3d0a8800f52659ac26f122bd63c8aa2c5583f1121275adc9af1800a007fc97ea57a38598204c15bf65e7270a175460510848540ca4004286f3ca09eb59260000000000000000000000000000000003ee0ba2b1de438abe66769124b97a951ce18aedc8d9ed005628aeebd90efd316e7a3c60cb5a103d6f72e7a40ed8f44000000000000000000000000000000000119597c99a7a16d8d35937ea15539089741363153ef898d6bb177d9a9b6c5bb4b79728155eacc5d82571f398ac6c32a200000000000000000000000000000000116184ac845a28c4f96641ec19a07e1f8326bd45e2106148f40277ae6fcf200d64e326915cf5c927222def8deccd4ff8000000000000000000000000000000000f890258e70b973c0d69492b2e7d10ccb3997798503c0943af4255c13b3856ca4007b18cb9d638d5d9cca71c368cdfccc54dd8cbe68d5151e4428d35ec2d5b5cc7f5e455207c0788a695c2d7fff6735200000000000000000000000000000000171035755bd519af04efdd477d407267c5a8108bd32dd6d3f1b9555f15f37ce7598c096fb5301873809f0c000457a4a2000000000000000000000000000000000bd35595246a8337a426c50c02299f297036f710b0979c7f981c6909e835c0d9556cf64e2676baf952a787e10d604f210000000000000000000000000000000006600ff240aaa026941290f49ae8968e72293ae7c2af0df1b4ebb9373199b95fc91feedd2782ce819440286aeb2388c50000000000000000000000000000000015b2bbffac097c27944143cfb22e38ff8e50e79f2336e64c8496b0b25892834efb18a765e26f1408df1d64f4b9b78fb947ee5651c127d7c8ef65ec68fcd97d1dc228bffb5bf1278aed3eef8115a5ae72000000000000000000000000000000001064bd04edf96a3c76d2ace669ff72ee5edd87d32592213cb5a6a4a482154c1723bc19c7c530d164c31626dbf758d43f00000000000000000000000000000000176ac06390e3629bdfa282bf825c0bca9bc4e0b8fd90fcf2d4ee456d5bcb3ac2882d8406d2fd59faf10c8327b1962124000000000000000000000000000000000b58fbe4e14ee0af03d9aac4131abfaaba43c7cd92d530802516cb67343b382a6d2af9399d93b43d6e05f7ec827d5ae20000000000000000000000000000000000bfd241e3180cd5ce9de831b24ca50db23685bea7e008be0c6ead11abee338618728968c25a8e5a916cef8aa516667214ab6a1d0d3f87e7c9df0c14b6fd2f9d0cd755d5fce5f40bdc8174790901549b00000000000000000000000000000000183ccf0ddeb8573923694decc02b8f02162037156a8f6523ed178c13113d094521c3d9257febcfbd8f15acfe3d5d5c27000000000000000000000000000000000cf716097aabb07979ee435cf57ae36a3034283eeec0771bea24c9a1a15ea106201af8606d3fc28ad8ffbea2cf274458000000000000000000000000000000000b962565763c4cc155b2d9ea104e754e5fb4745303240688fee7e2256fbda82dfb515a51096be5ba0b111637b1a25438000000000000000000000000000000000df04aea745b9df2df0e34153269958d3640c1596fdff3fba696801c96371420a3619c5ace9210af7e0de4f408b09a7729b12cff5a72f27e15032844fae50e3cabbe31a69568bc4b5cfa884f62e7e204000000000000000000000000000000000e6be3275371e533a676f8d075bb2ab8b0216642ecde13425bce4ffa8ac51cb1b4c5c789d82387f5355c27f18da556400000000000000000000000000000000009fa3a3df5195203f967322cee54a15d1e0096922b6b881bb3bce54587fdb82931c0b87de7a9dd1a21b4389a34d161ba0000000000000000000000000000000014dd5455deaa5ea4f9b5a6241c2e8b2230fabff9e1ac08b359f029f4c7838201cb88a92a5b696ed47819e4866512fff300000000000000000000000000000000181085d630d1e24ebf79bfafa134c08c0e75626dd400ce500392adf4462028bc714ca07b28b8b8f15c9cf2934a299c3092c1b10d980826351c3d193a0f54a7dd78a3995efb02fe5b4525fca8791b1c4f0000000000000000000000000000000013b60e3be9d7d43eb42f7cc2c0a7efc81c175b696e82b034c87d1238db2798d9ad6534b86992653d86755b4f00cf989d0000000000000000000000000000000009dbb325624e698c76b9d697e4f7f03e502ae1cd43b49a0957fc067858e20e8c7ede3577f336eeccee58cad53eb727560000000000000000000000000000000007f2f50be2c6fbc500ea347cd14ca195af08b835814ca515d14dd2f6078eb6def2b9475c2ce370780acf394065032d0400000000000000000000000000000000109803d612b9e27be5725f162d061b9428f363493c17eb39c097032039387d96d0939a06466470ab62ff507ff762fba78f715f35fc967837facb515ebff3df502223c29e7089fe6d2e9120bd3ecfcd120000000000000000000000000000000008a9fcb462412c1065dc7c3623ba5a980e6f86cc813b5d8eca6b1b8a302ee4176cebc233411f2c9ff171332c66a0d46e00000000000000000000000000000000058d2e7ee02bbd4896b5bcaac0f2b09c16d1664209710945c1f7f1a53e24496d7eace99488debb32afe10d7fea442cb800000000000000000000000000000000084d7600bcb68d5e375457078672fa07ba2c87c8ec5f9eb7b61a0232988b197aff052e7125b33c6657729ce8a1c668e2000000000000000000000000000000000a07c42468c7c65fcc984bbfc2f05bf452daf17d57e669ee5992ce67517e1c93b5f7f4c9434d40f3b9bbdb3446ddb982a9e49fcb12c0b1e9bcdbda52e9852ee0e98fa0d43f7476b3d65ef5370c9460a3000000000000000000000000000000000ec380d15e0efd71958978b1f9298ced4cc3322e472d03830ebbaf2a4601c8371e6bc1cad047b0e1e429ecf6fc628208000000000000000000000000000000000b278fcc53b7527545ae1340c24158ff662683919717c220e7d2838a853fcc84ce3915f105a932872ca7f64b7cf096ba000000000000000000000000000000001520798dcd146c0b39ee727e8276fd998de0157a68587c2fde56cd82a9779b6ffbf745ec151210d1e9143856f24f01d600000000000000000000000000000000175d53b992d750b34f9daa39aec918a0ebb2f539db8057eff1409492c90f79a00f14a4c53445c028bef5d6372c9f80c680b0d6316c5d62d41fb0399256c5c46ebe2a12eaad835d2c7177bb7325e21d3b000000000000000000000000000000000fb3863bc7b468f1a0ab0e4701ea392bd820ec5cc2d7d86b58949002f24c972f51f0f82400fadebef13b750884b35f9e0000000000000000000000000000000008fca1b30d4e01991811679f261d11723086753e816239c8c7ebb60ce9ac0ea207011a69cdc29e3336e8f589b71bdfde0000000000000000000000000000000010696ff9d78b48743abdc6c1f4b44b4c960aa516623a24da515206d95e65286e453a8f275d98aaa09fefea29e71b5643000000000000000000000000000000000fb4b5eb18b6f6f8ee7dc734e8bdb625a403dcac6d0cae363e5a7f3a834c8eed5f01fbc4dc752e228c41f3f9d992bbe01b96434f34fa3e00ee0cfe548a2d2ca29a848cf1c52f940685caa9a227e32a61", "Expected": "00000000000000000000000000000000165baa8b143e3734169986e68a848739ca05330786012de260148cfd0810ffd5659210855f19ca92566ea0d6c48086ec000000000000000000000000000000001225672112e0476418288f381165292a9aabd009b0d9e44d9f8f00469b2c56698f5f985ab6292c9dbcf73bcf610080a20000000000000000000000000000000005418cba24a43fc7edaf2fe77422a0b2e8b38a45415e13654c6176c8f7cf6bb2b80401534154cd3b23e977af589eda9e00000000000000000000000000000000067126ad59105621cb0931ab8f386570b54977563ffd69c2231c56e7961f6df2c5d7b114e0b1ea176cbfc1d657127286", "Name": "matter_g2_multiexp_53", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000139cfd67c3365c5b4422063d7901108c9f33e233bf6413ba2e5b2ad62d188cb50dbd3dac0f298aef7c1d621249d4b0c50000000000000000000000000000000012fcc0d5d09cb3d86895f76ac3d3e9fa9b2495110b0276e7a039d7d2fc2e48fee646fe331c1d8e6f019898ddb43dd09b00000000000000000000000000000000159356eb3ed0d4f146dc929aa6c77057be5ffbb064432d3fc35d346f19f6c1f8552c7079e27f3188bcf29941375e62c9000000000000000000000000000000000fbd4e9a57aaaec40ef9bce8b76b529bd2261d373f05fd69af58d1f23c089497473e44e937b2617a92942af1a99d031f10e0acc22c43080ab9cea11a60866feedd57664bbe6c3f0366beff177f66318500000000000000000000000000000000022ce2d2bee57f7567e9b52ae8e913c79e3b2dad381802ccad317b525be0b503bdfa92722eb0c21fdaa31fce2421ae300000000000000000000000000000000001177074350288dff9dd85dbee758fee1400cebc173793198a96c0be3bb810d352720e94b9bdcc6f5a8951b3a86b2a0e000000000000000000000000000000000179e21de58ff76427f5ed7c8ca3058d0e5e81e436280aecc75a3d989d1cf11d41734de22bda74cf0dff175ac789532b0000000000000000000000000000000016abe94a49f071fcd5e24b5f3a837fe3fe7c7dc53416f59d0469d71f144f71ade4569bac3aaa202a8479c794bd251645cab0c230c354cbf1a3c13c23a36ae5f2d5d084d7aaeb427c580cb6b9bfd9df600000000000000000000000000000000018dee638031a3c9b1198cd4a4f267cdd66849e2b80e3d670897d9e058bbe772936d827eaa4e78283d42ecd25eb4b22e200000000000000000000000000000000009c04ef31cfda7c086a31341434a1698c1132fb5916d359a523b98d05d57bb38a1e2e2bb779d4762f9d4ec24fbf2564000000000000000000000000000000000a788450652e0bfae66889c66b0dab8d1972a626facb690f8e4ebfefc7e1a7b2b58f6eed02c1f10a74b140a49b6c5de50000000000000000000000000000000009e48b52f2b0548dab1c0d260144ad2e66a22e0f1781f94071b5a3a08311d11dcad6963b4339fa63bd82b4ff0dabe685290608899cce4b3d25f57519cc881eb748e9ee7e27f7b21d69f5d8ab3650c3e8000000000000000000000000000000001319607058637d4b796020cca79d62af5862b1c186f32d99c0ff53a830888f297ac4389582f9fd010534d824522e6fe3000000000000000000000000000000000608ca0b4806f17b59a805a3f9f75e7a33ac0791e05050d4eb19f2d4c845fa4e4c738c3309e24a4524b6bfe716949ab5000000000000000000000000000000000a6a6201ec077e113995acb81d4d07d0c4a085d367ed740d26c4a0c04ddf28697c1cf5e648b25148888617ba77ced5e50000000000000000000000000000000003eaff54800dfc8eb3ce647ec4ae8c1aab6a87d4853a1ea061a5e6367d8ebc94243837d4752a1933f7eee0ec1ffe68c8b71debbd9f3be5d6e65e837bd78605d5653fe63025c320cf49c035ae66d8ff5700000000000000000000000000000000122822c91bfc4f761b65f4066a94c0eb1f53133a1355c019f04003e84edc5095523b2ce87ff24bb42425ce979743ce31000000000000000000000000000000001928bc315800ae9936e5b763bf29b19a9aeb71268cb47706494598e0ea057f9dbdda6733d9ea165acade87bd89b3ec12000000000000000000000000000000000a87c1ee17bcd7d348ed1a5022bbc7438bfad06172584dd8e3b51db4b3b09645290382ba991df37db0ce562c950c0e6600000000000000000000000000000000127c80da591c3ff8d300bbdbe27e0aa21b5edc1c1fd8a5da27f58a4dec3971b3c4f9631bde244a7072d9c19f1c0a46be250f62ee2c2972e751b36d95a578efd2fa5e0a2c1e29475a3cee48a28080cb0b0000000000000000000000000000000004bcd0a0321c3c7e6161cd53254353905c27d965f57c9783c3fa7cd5c55a5820116415ce45491d5d1ccef6017ea4608c0000000000000000000000000000000013a30e19c43a1f466c0c3ebb5cf1b57c44434892b18a7fde18a2a29b09a5b4d13d26cef871d689d9855a73a43d22119a00000000000000000000000000000000066d6b3c9a949049413300ec0398d605277911d7be327b1d816cf25543d1b2d7c31d912f426021e612b56ca288b462450000000000000000000000000000000008549f4dfdf018073cc4e32ac930397659ae7a59ef42ca4f864b26e4635c2b7669186a107e9e91c35f04674d2be46051ad08c3d2c36085212542427c1760c72f22838be5286402ef87403f816f4fec950000000000000000000000000000000015900fb486bd2c066cea98e51d30424681fc3347a1cfaeeab65989d1adba104a362837bee51b8b953ebb520feb49aa6c00000000000000000000000000000000198ccab1f94fa910f755936e357a92d358e00cf406894b46adcfc301918c4fd7cf7200a1ea515343d577d920680c83640000000000000000000000000000000018d9380a8568adb92f8f9f67c315f2a837d542b32aa82d9bbf5db6dfea27260738bd0a03683a9988c6c3370563e7bb8f000000000000000000000000000000000528ad42f23c4e21a687f2303f495e962b0a90713d6ef3abbdce38ed166ffea9c132e50c5b002b2ddbbd4933e9a1aedf6ffa16b6fc4cc9509a2b8d8434fa0f4f38b4cb4eb1bf7f545f9f43b9190cad890000000000000000000000000000000017eb2587aef34b03943a170d91d99aa16ceb2a36df3068663382ff4c135083c998743f9145a2fd5dd4ce3bb8b64cf3fe000000000000000000000000000000001256fb29c7482e5469d64183e3e848e5bf32f9c495cc495c3f8cd8e46f71c3f9880f875cfe429677615a6803f849952500000000000000000000000000000000146e2f329f86ddf5b0b17c37aa2905122f457c2c812782bdc15e132468af48c49b715e3080da504d59414ceb367596f100000000000000000000000000000000022a8e385972592430e76bd952a700df8d35b32deaf06c60173d0048d6ea22dad95cc62300bc1a60c6452c41b32b504a1271d29abc5f972809461a1afa5eb186dff5e28f20311a1d8416f8d54fc4b2d90000000000000000000000000000000009c80b3191783d235814fc86653bf2f9a32cb7938111408087b6ab5bafc480583e7a2a32c6bee0ee4aa867ad5dbbf77a000000000000000000000000000000000a09af60eed6c47a6c2615cbfe62025530b35727b42fd812032671ca1eece6694aaae259b05906faf7fbb54362ea890900000000000000000000000000000000055c5f0818f41e5d73e8cd5f70fa77cf477cad8dca2a88b8970a3a25c8f38382268e439642518f1974c5b470cbf29699000000000000000000000000000000000834e44669043aed8ad47cccaaa7476ad830e38fc1def66aa7e8207e889ac0fa1a931eb1e90aa6e1cd694bb95056c3e63ce55b3b32ad29dca1a0c99771fc8f7179851995d5eac804458edede9b8dbcd000000000000000000000000000000000190f8da34caaf472ea9b0f41851f808bba402b9be4baa5d02d1bcb2f66acc3172abe78a49a653cd24dea402dfb972f670000000000000000000000000000000019931343d0e59f0f0a060bcbbeea92fc4670db510c017fd94e0650ace68c2925c627f373d8e755813c199b79c70369f20000000000000000000000000000000013ee811cbc036d2786d8ec0339627d6134b10517c8858f6c6db19a9319636459ebaa217649825ffba32a224175267de90000000000000000000000000000000011039d587f3323ea9d3c50027c427fbcbbf7e097533d8a5f7a61520f3eb548c399e401df0f51884395ad6a338c0a3500c6fa7aeb016b3e3f599846af83f426b9ab85b6857f901c49554d03d27a390f5c0000000000000000000000000000000011d5791e9bc632eb63bff86aa433e6df463a84570b779c913f67e77fcfefb6af48f3df2174096a511ac35eff64e0e5f3000000000000000000000000000000000282716505907931bc93748ba1729777b959d65aec5a78c9f829ae6f2a94a022116715a8c2a653a832a62625473a0cd1000000000000000000000000000000000f694a16ce7a69f0261a0ae19478003dcb61bf93a2ff39f940fc4718a38b9f4b6ab13527c5b438d22499ba29c0b5461700000000000000000000000000000000031eab53440757e4065804896e9e811d459665598546796d67472054fa60e5da8685d8e847eae342e44730056757c6287275a8d16c02389795d54ebdcb70a39fa885320d00cd4e5aa15967916e46c61500000000000000000000000000000000138862ee422bc0f38ce3e27ed3c1b71f71a03d61cc474d989b0cc824efc512ef173ef17bbfb2090997eb9435f4d23e0d000000000000000000000000000000000fabf1fac2ffa25d9c8cbd49b3db5dfdbee52adb947ebc1a3423c9fa2f9d3d29329b60ce0c1c739c7fc6d5a5d3b9e96400000000000000000000000000000000090d92e8763d4df49b8121a50affcecfcd632923b5fede480a3ee79128781f3f49b592d8f65d30adfc75d8a1922c41b0000000000000000000000000000000000074456b341565b13ee3862bd87b72f9d01754c7715751738c5b33ee85e3d8a6f731d7292bb485b5fb59bbf3ddf9b0d0dbec9767ed2dbde21fd8f315ed6292b5b0b1bb6daf2b62665c34daed00a679cb0000000000000000000000000000000007b85110889fed72b3654a8632625835cc041ff0a827f3e1b86c090d816d98cb3b4be66b6e573b3dc05b1998f2772f0e00000000000000000000000000000000160524507679ee021f4307e5a9fdaf01459cbb9a3fb9dc8be5599431e2a8bef38bf8a05d601580085da503dfcf57aab7000000000000000000000000000000000f98e2e7ae9cef2b1d954b7f26fa1755258112c496605c3c77408786d4b210e51c76f10870f558296993e0ddcec3d76e00000000000000000000000000000000068841825f5f5d8f622c1d43bfe090d11c6996688589c3d644ff5da47b94c0638128878d51dcf6d43637781f0ab21a68ff634fd89223733f407c242e52f034691036c7ca69f30e6cd444c561de9ebdaf0000000000000000000000000000000013ec97016dc3d6a3cf41edcc18f88f58b1b88cb2616bc2a8f96af3e7774ec1aaefe86a86135a20ab7592c874a33a8e1b000000000000000000000000000000000021dc7e4be6462d64ba6c09c2d326ca0164305dbf5ca1981f265a1e50f1a646748ce66ae07297230325937faf60709e00000000000000000000000000000000121bda2855503ef11b043301cf331a0fda6e5914e5ca657890ffba2542d908f8fb02c2c93cb4ac4fe5bb92eea757ca7b000000000000000000000000000000000386fdda56c778a7552dce451a6ade55cd24bf9eaeb837ebef898e2e868d05eb5edfe97bfa8eff8ab7cbfaca3c918910461d349e9711fa701b92b62dd3e3569d1203b6a35ac8600367a4df9a9484bdb0000000000000000000000000000000000763746ba87e8bb547180b0bf18699ff74f11154a06cd77a76cc9c264db7c48286fc52e3ef2d30ca914cdcc5c4ed46ad0000000000000000000000000000000018037afcabd273413eb4a712f5d1888249dc987a6fdb8befb92c02660604bd11deb33f283b37f88880cf1be2b2e71f1c0000000000000000000000000000000008ecca3d1652be4764720ef13a6ed6164a3ae89d160cc8c2c8c37bcbaa52db0fc0de84fbe2a19b93b8100556fce0fc80000000000000000000000000000000000c5727babfbc5c36c1d57b9f69c5b41823882e0196e9e0a89d5f4380c4257818d90b1fa6d782e774f2424209bf2e6b5fcc110fd7a6ae46ef78c0e26183e707eb5e0a2944e3afc09e435d56e91584b93d00000000000000000000000000000000142d41630fb9db2f9630e4d5f9c13069242fbcaf1dd02f93224174567c3f944fa02b9791a409d9236d89df6ad785e8ed0000000000000000000000000000000002fb5fa0b3a7cef16e5638f217bb946085fba870836c618a7db9b4394da9144850572daccbff8208f14c8082aaf1ef6f000000000000000000000000000000000a6be9b4a6a9b96d2096eb3a95780f11be1e13bcb6e625517191822403935c52cd40481bce2e782c42b11321cff2cb7f0000000000000000000000000000000019e2d94e35d608a50b5c8b371044f6410dd6c1988ec7a677016d4b52cc3f21b82fbaa7db897f7107d81a177c31f8e52467de5b9bee26b26b28f81d96e880a3f07dd04eb56c15314f1a789436e01adcda", "Expected": "000000000000000000000000000000000a6f3fcd812e3878cccc6967d49b104599fdaa80cb5dee7298c3fdc80477d277f2c68f1c941f6e03441eb176c222a448000000000000000000000000000000000a4007cc5586d677e7945dc8a5872b4839d5b256999166e7fe8efe4d56895f93be4659f43aaf68c6070babb6d3328168000000000000000000000000000000000cef5304a1077c8f31d72e6f1f91ef5a021d8ba64719b4527225b34e615af388d9b1391f65511eac209ff5e86244039f000000000000000000000000000000000c856e7847ea0b4a8334d124417b45a8689d5d9f113b99ebbe3af3f9aae1cefb236d751c40488a861a8f0e0326b42c4c", "Name": "matter_g2_multiexp_54", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001805009a7fc3d1705936696191c163a07ea992cbb4bec66884a2d58ac3fc0e16b6e0d2292caccb3541f39b7fd6098100000000000000000000000000000000000f3bcfcb0c400d3d06184563204bdee465de167c7d17bea2e2150fe12eb9bc3285f5693b222fcd224181f8d193b7d95f00000000000000000000000000000000028d60b7fc3790aac7f6b3ec32c4be626a2c64c6348fb8a1f39e58ee56b81469e04886ed9be1388958550c02ca9a75b9000000000000000000000000000000000b60ed8052e43e99d3c10a4b97ac3197ee3cc04ad857c5cf4d8ea1df2671084d02fb683f28f5d499910351354d5e6288624ab43047c02e30ba2ec671511d06f869bf736a9866192c5f2eea6c065acea40000000000000000000000000000000002ddb1a9a88e3a0697540cb008bceb075e87e2331f6e9b68f8ffec48752d93cfda5fee121155ad2a142c0ec42808fbc200000000000000000000000000000000144b694018840835fa9c50fdf62c2e32261a8350d2ef074dcf7d016af982316a0c6f9e5d15d29d3a54d8d25aac5534940000000000000000000000000000000010a3765089ada75e9eb61328756ab9ca7b8362cf86cc82af3cf43f390a0745954f28da72a6ea4eb904a040596795639100000000000000000000000000000000056b51dbefab453012b35fb6e06af06ee92e4e84e92a9967b379af760fdca4a3f10f938684a646fd70a2188721c92e98edfdf850c0d3e3903404fe3e0f523cd230cabc45946c4fcb6d0e5e05e388c23500000000000000000000000000000000169effb324d60b71dc7ba975e3d5f18700b34cb9017f482f64be37c4df01fb66ee9eb5870e43649225c9a88a0d499b890000000000000000000000000000000016c7ad9c5f7b65a9423f642d87621a5192d7548e1099d774a99a34dd4ec9623aa1168b9adab092b3cf450f369bcb627600000000000000000000000000000000123b35bbcd791ce0d00148cdb3d35ba39054a7126ca5ad3351fef1437461379ef639896b271276a9561b46e270f7501400000000000000000000000000000000161fca2deb729fc55f1102fb75ff466319f18510fc66d6cf95a8256118fca618682f00318b0a5297be873a2f7af1915afeb34852ce0f3b5730962023418ad6cb860716dcb526dc53e8ab6a74a6a3910b00000000000000000000000000000000073ad8c2f713288313185c3b2455ade93d58e70d5df6b8dfaac8eccd990fca6843778fe42cc8aa6f34ee44aefb49397100000000000000000000000000000000012eb9cf288a366adc58d40c9ea5f2cb5dcc5b04108e3822266ff20eed71f56bd74f1a2727f20d55917adf20b6c4d6a1000000000000000000000000000000001463db177fe5c0dcb899797f89da963731dd4e9e8b2eb77b465b98415dc95f6d5569df51bd2b08a13838f4cca4b62fcc0000000000000000000000000000000009c0bbadad98361209f36eb23a9eeff98f6eafc7d5327fddb6bf43898a2be704520a005b84c5b45c6a68bb7c98d65d6dcf25e64093bd92a8fb394511215a3fa674db86d7329ac5ea70ec77d24d4ac58e0000000000000000000000000000000013c63973ce6549ca3dfe8ea8e3bcd6b0bd88f7c73730834d9ffe2076cd4345090d0364d161ae8998af1048d102f22e5d00000000000000000000000000000000060cd24eea4177c9a5c37038d4cb62aeb709218fa8e64b9084e002f53a0c4c411825812c20df282345bc4a6aabfff6a100000000000000000000000000000000106ea864dd52933be02c1a79cbaf6dc81ae9a2d619bb368c4abc36226104f3b74fadfab906e36d4852a6412315223bdd00000000000000000000000000000000192e45153e4942c88bcce76098fa51782a81b53abddb4c07bd79a2391be68858e2d278969b9fe75bc652d02fe4db1a130b40db4f9e5c27a3208899f4f536880b97f4c69e7d889c0726d87c3fa27e097500000000000000000000000000000000101ca1625e9d4a51e08f5eb81387b361f6445eb307d9bc92acd29d62735d4e5078b1a9b36b94e4ea0a314703a85ac4cd000000000000000000000000000000000f134c460c6d931396a0aa397558975ee973e642f1c4a32a3d397051fe250daf4215ff5ac4b2863d570c87f0e32c8cb800000000000000000000000000000000008eeb127a38104351298ad77481c32bf51bc5d3910b03da0cc34062dd2a8766adba6891cb9fc579672276666e1242730000000000000000000000000000000010c896ecd4bdc1ce010da81a51dac96409079853635e57e5c3a5733956a5f5a9c3ea6838849e286ce0405dd54d7e32d6730bc7f68d8d371d0bc51d95f8a5899249b8db5cba0d21fd88ba6f86d8691659000000000000000000000000000000000be489a1c71246adaa1c1dd6d2ddfae9523fd1d58d00d4f189f56d08632dccc694e63b371db6922a7f3faa05afbf487500000000000000000000000000000000174212b6840a797f0fe9e209b41f55aa5dbf169a2e2ecf05de48c44e608f6cd6d98ff5269e5412defb431caadc8a09c3000000000000000000000000000000000f4501715c0c511703f6236caa82479b3368de430f2c2d95b39193537be0b990fec1ed8e4d94634ee6233cfa359b043d000000000000000000000000000000000f3b4712f95005004d99fd739affc532d2c4c45970316c1a43f76fa9b57f6676c709e8791c276237b92750f5bdc94492ef06360717cfcab15be966cba2836b97deeedd20a52f88c73e2a583b64c8e5f00000000000000000000000000000000003abd36736fec3e8b89863670666365b169d8510090a89007c7ff3a82fc62ed371544013a1444fedc4358e92ceec62470000000000000000000000000000000008229855468fc63f4024938cd6f41c6e6a5653319cb83f38ab7efb9e9d281166261e7c854bfc08f55a0a9ca47e54dd42000000000000000000000000000000000463ccacb341fc5874f6ba2d44efb5cd24e9409b2ce7f43e9d39466288dc833a45988261f45d34332f416a68c5d10ce80000000000000000000000000000000002baa086177394203a04ce1b46415983399e60986531967b690b1a13cf8ae039b56f0a00bf9aff357d51ac57f8fac8b282b7d8b8b9345bf13d0e113b662141f5ebfc5888a5ef8ea06f7d5d137324ebef000000000000000000000000000000000b25a203268100df0510e4155c594a144dbdefbb0ac95e02bb4b3799aee4e738ef4c52f03c6937cdfa7275c28f130778000000000000000000000000000000000c432347a2534e86e90ca346a7b8b40f45075727847fa3ae2f2e297baa14aca88ac6e08342f0d248a92e2c272841fddf00000000000000000000000000000000057ec8099e1e30329762ccf0641b45e1a226f7b66b80644fd551d6fb1f2136afb8e8ab5c6905ffc7c24e67d7f21863e4000000000000000000000000000000000a9e472aa993bea05961affd6782efe8f50d746928efb8fbd328fb50a254db861c90db8df7faa7da8266ceb47fa1a13a2396fe15751bca2c4a651445cef236a865269849908df53551802dd378b892cc00000000000000000000000000000000025484652f18e2b32e2bbe79916c8bad42902db5528fc45993e04daeca008f3c2ff38fe4b48c292f70a7dc57654233400000000000000000000000000000000008e403f472b60a6046fd190544a1d6b249dc97cbd8641c62613f4de0e0fa9f5456d843ece4ac2b9f4ffa2c0278e61829000000000000000000000000000000000824e0b9b03198597fa54252b3df9690df678e9c6d82301848939dc55ab25a7751bcc2b99786cd31960ee7030bf68ac80000000000000000000000000000000018d1d8c7f2b20f0ba66db616322e48ac8f1d6f4205f228ee8ee6cd13d1f64be9af338c11f511859baabea3e15d165fc09a5897c9596223ca4d6628ca1f793a000aa21a739a37faa28637692b754148f80000000000000000000000000000000002845c4255819ec6e97abddf4c9db7d91658dd1d55328ab0565144b377e20ca0743d93fddf68acc985ceb7f7431e30b0000000000000000000000000000000001577a5691f2425e65ffd59071c2bb167ad05a8fe23c11c7f7464764442ebb2f7a75a8d02594d4426c1ff022f7a6e19360000000000000000000000000000000012c6ffefcd3964362f1373348404d04d1849e98ffbef7b5ed5704d74b9550869e30a4df26e74b5304b85c7503f7487f1000000000000000000000000000000000faf3dc42113f27ac27aae36725221d04fb1ab46b59e16277be0758b8fad706fa237c0c7627771d8e8d3ad610f63619bf20a2973faf886556e5329363bd9b9c96424fcf2e953df90bfd011ec07bc66eb00000000000000000000000000000000044de166200ec06bcb88720e57b84cd8f9534d1fe303a26aca08cc35104ffd7e81a6473c08b28037118dd8a61d090e910000000000000000000000000000000000f4325ebaafc67945de2418c81f5da92da4e67866ab5965eff0f392cc527fc34ba4e7e16b91c26aa370b27eb6a07f6b000000000000000000000000000000000e1d77ccc1c196cf1cdf0dabbee4829d56e937372e9f5613e261ca07e19b3fcf10f7a45c490b98b5a64b955eab5c4f2a0000000000000000000000000000000004ba2e81f901b0da1ead004c76d43278d372456c0c0a8c6752597823d44994177734ed3f355aaa22f325ea36b7c9eba1f4ddb773155a27badba330ae5d26096f350e9ca2811feb227c4eee09d2baf32f000000000000000000000000000000000c115e270ffd6f2cb9bbb2a62e04c3bf7be9d7db783d292bed272c297773b39e9e51c75e5c79a6606ff7d0bb9ddd040a000000000000000000000000000000000a57b637126b16b23bdaa6a7cf2346f33778cebdc0c9943eb2985ba5c4114674cd596ecdb6959791139c36c22148ab8300000000000000000000000000000000177c7ed16c29d99d3d98c6facca9cb5ffe72e6aa63959dbb51d9382f0fa49b02a1652a398eb223e093516ebf134448c4000000000000000000000000000000000d6bd518678828f582fbb3b1bef725e66f442c4d3e6325fa571e13db492300d03c0188399a2ef9d5687a76e647873c0f52e4030b5a4bfa767ae20cdea7f464dd2dba51c9c698556d24b8f3d4d1afc82e00000000000000000000000000000000085d4f90336987f99d250067c2331e7de8f09a80d71fef0570ecfd99e409c1f405058bd3461c9f8ac5ccda406db89bca0000000000000000000000000000000015f310660ca6a0c06b458d0b840a5c1c476d5175d9ff6dce6334466d363d319939572a2b00662247be1ed0f4e6676f8b0000000000000000000000000000000011e9352c0f81bd3857806db678bceb2150848f2224ddfc43fb0c733f0689ab4fffde50d5ce04d54055d27d7702e5d2d40000000000000000000000000000000005d835d04dcf4199130d6a16e86cb97f4ccff58c496594b83524dcd88f5570212f06b744379288f2a737c7a82e897cedd32e0429e7934faa526475c5c7fb977c3030ed74e145eba21af2d2cc8461580f000000000000000000000000000000000f7c4e621c37bd3068a972b9d4211abf9026e438ac7f8cb341516f7e6aa4d8bfb3536389e9155029ce9e8d5d376eec1c0000000000000000000000000000000012a46cab2624797513f2acaefa26fb22c4bf29188881690c350593fd1949cbc243c9d1d7d27d9d76aaccd347359a45660000000000000000000000000000000002dc383d4f9b75907f74bace1769bb5bb1b27a597c9548310f2b5f90098596fcce6b5fe0c72bc8be9037fbf31050d74e000000000000000000000000000000001900deff7ddc62ac302c941e1d2a28a4bd2351edd7700042ea4c4a48145ef91688666d8d7de503913ea259f0b58809f21f700d651c67ca5b8d95fad1a8e412befdf691b074956bb8092938bda2ad26940000000000000000000000000000000018ac8048d58f7b1a9407d3101824e3640eb20633f8ffdcc97d43d1b25329a2a1e91added42801c03635ec904e627eb690000000000000000000000000000000000b499fbdbe2ed41dfd6c454796e1ba57021f355a4de8f60964c78dc685e2ffe9c90f5a1f6c9677514ae4a9c95c8d6450000000000000000000000000000000009d10e5e2bb69ea6fd820778f75a2a60627802a49128c3f999d8c1cc2ba56ed18acef354a2e06fbbdfa7e7a4ade7529a00000000000000000000000000000000082839d66a18763656c2ef7196a1d83bd162e1f109b54c5a6095cc7c436e8a4888c4001696958270f54f61b81b00b32d83052a3bd7a13bb1ccc22b9519c7ab12d2dec67924fd9f15f96069de22e7b692", "Expected": "000000000000000000000000000000001463ac5e269d286961036db48ae33fb868a28b0dd828c3a66592ff9dc115303bdf3ab78a8e1f5df68ed1f3b4c6c3f2440000000000000000000000000000000012c64ca0ac10ab616fc733f75fe6181814e9c204f9e4eb79487ba49e3a9746b9b7916a1d768f2ec573a4c4e226365f48000000000000000000000000000000000a06b5b745dd92adbe1f4cf30c79ce0c48428b3e3b05af1585c4ca12eb2e763ffff46b55a060913e1f77fc9b0b085c9f0000000000000000000000000000000006271931ce9c8b9cabdc932297f3c87128a5af25a9f77e71ea4e588f1e88686638e89a8e212c92f6472692be2e05fa5e", "Name": "matter_g2_multiexp_55", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000001bf5b74c1ac89d4bab4663943e19128619731e315d2d7b39675f7c43493b338020190a72cc7a6edf0b8838886a7fe6000000000000000000000000000000000713f413bab7919cd57c2de3349394121d6bace3c10df0e41a0ab895433d225b05cdb1587deb93ae6e56ec26a29c39f4000000000000000000000000000000000dfb11c9c0bab7e4d1ee39941d5f6b932ab473567be2329c94bb0b146c46fc1c2cda25dbef8ff9b0066bd4ca3b6da67a0000000000000000000000000000000014e399169243bd619be7f2120b2cae5d19b2f04185aebc7d948007c4d3345a9f45249273b6290c2e86448648868ac552c40774f67a651ad70f17393b386e9ea9e81682ffd78db7fbc17cc5084f3c7052000000000000000000000000000000000a67bca1f8a0b386b2a67158e80262f025b225535a294394584118f9a701e31e91b2c7eb8fc7e28538966b967c139dc400000000000000000000000000000000185e8aaeec9b9abb9f0d6f34e2480e9abc30208eb1c6e023d4986d544b356a387c323c9edb5c52f5a2f0bd59cca7df98000000000000000000000000000000001877ce1ca6e8b30df86de688d950755f2708fd6f933c07ae45fad1b3e43337f1a8454ca5d2a80940e8fee98fffe953a700000000000000000000000000000000117a0ac9d27292f967ff5bff2ebed5d2ddd9f453d6aeadd9106eb52b53447974561b621fdc1d973c055f1cdf824c367bccf1e36e063a5fdd4b735dc18bf07703b80c6b72f987c05641612d7ce73562c00000000000000000000000000000000009fc4e9e816ff495dbfd4f745106fc90c023d95bc64b809801d02dc7cead905177ede5016f537243660e4b7f54a02ea200000000000000000000000000000000180aceb6e9851a11a1e34502897299e7db3e09f4970337612634fd9848d1de2bb3de8ede690ca051a75add5810ff777600000000000000000000000000000000199f3c43d429fe8f73e20f81ea00c4e78294eaaa29fd67563664381db3cee2186b387b880089cf96fb99c2e22c95449d00000000000000000000000000000000040b20ec4e685f104be188d0f15a79f27cf34dd01f813275f6019a9ffac56e234b6c967c80745294d9fa46e0083cdd907ea75dd2f54fa6413ba77f10a11e12abea3a4b947116e1e7c9334a0a37c3963100000000000000000000000000000000189fba635109ca215bf3a09c3e44ad65f7eaf653e0929aed39042e3b9c8b1132c5fe7cfafddfdd0646514aa1f9e7e1c0000000000000000000000000000000000c28f598c80ac262ec7a0e0d1c867e01ef26f182c5df9ea7f88fdf8bcf3a5d2f06128526b1ce72cead8ab4286a0b8d030000000000000000000000000000000008051be3328df43b79dc9040ef0a0263d474acc0edc023f300cdf7c13088d1bb21b5f37ed81b38dcf8718bf6441605f8000000000000000000000000000000000d2d474723c6c246dc59e683be147b1a6bd6e7d3cf12aff7b636802a99954e7a13c9ea429b19833a985ca5649b1a998f6855c61bb7d72b022c16290c6d3ca9c1255cede8e0b827b43e40fbf01840397800000000000000000000000000000000058bf424fd68aac77c42a046f78a55729e6b5b3fcaf436d0d98354b426a95904b55cdffdd9a8892c9f56f170ca8811a600000000000000000000000000000000142c1ded08928fd155b89bcfaf9c8194f4569b4cdeb3bc7286f4dd79e822f5db497768220533b71be8c71d121e557020000000000000000000000000000000000a9c753686534bfcc295eba0a617f86d7f9e78d3fe6d52f26cede97a5b1f107210a757a2d89361645856b7b20e89185a000000000000000000000000000000000f745541841cc4b5352f659c2b7cfa8d51b07f91b0cb8c787b4492bb4b94ea27117695416e2806e57c38d7e565b9eac67fa8503101f392a6c6c27300b6992af3fcc48d47f73db67615a44de883770d4f0000000000000000000000000000000004445d4464b51d6b12f164a49ee3b610f11738d60cfa6e02f8c33b168d9d5db90e6cc558cd12c56069571567d91183a30000000000000000000000000000000009e4b96c2b533a16803a36f8d1f179313b7adbe6c4b90716855474ffb2fbe087df3fc0b4ef14cda7d958efc5c92574ac00000000000000000000000000000000104dff7c859eec61a0ff8e0d831bf9667226d5bdbe298400b4f9e3159a64b1bbc7cb9f4ff9604e3ced40bb0de0455ce300000000000000000000000000000000134bc2461459ed6f0d96aca02b62e3110c2009e1ba7d3258656e9cf97c2a1685faf1f61733ce6ac3af7ef4d73d0b43b1dd947617bcb7ca1c8fda0d49e6d950a84d60230bc2411d42ac32e3651f48524b00000000000000000000000000000000104e5709f8edd71f50eac1770ff1c2b21f5ee8cf5a310fd1201109d1b73cab69913bcfa2d27a8ba16d974e9841586ebd0000000000000000000000000000000003a4bedc6277c61825f6ea1f438c058a1afd494c384689a8479195646888eecc7953b8b8aec849fb5f19a20071261336000000000000000000000000000000000856ee8eafb9b3d25fde7e38da4acec624d1444337b87b0b1a660bf497ff37929b1ef9aed8e1fb0ffc6cacd8f0d1a1a00000000000000000000000000000000011b52192c88264df56de3d7b14372443e25183bb816ea1c0346f15a1f324527ef8531e27aac3112e2a497a0eff0d5485b4cbbc6d537ed2b69c2c32c84f3cea3d2db180b64861859368e98aca32bceea6000000000000000000000000000000000a696c83010719161b6624aa7756e6e84980518416554ac045a93b63c2561a68ca2ff2fd5b6d2d667822ae4e3b3a2ba2000000000000000000000000000000000fb8fdab4f177b0dee52bb5ba615b1d548130deb87b14d05d427984ec148a7a94efc4674804b3660d0f7aae2b49f7b1e0000000000000000000000000000000004914c0359c8e23a7e431e517cb83e5735cb2876e8b53ad45abf1e9eda06e736378ce03ff75002374d47f1bd45b08e8900000000000000000000000000000000139abe340c2d773cc45cfc75c47ff31b2dcdce27ada3e6d6c0823f37e4e693ca30342fe41eb96dde464d14668eb72c5e457bcb8c44a2d9d1facb39ba7ec8ede5d5962b3256d9fc2e68a1ee5a733ccbd100000000000000000000000000000000180345fc01e3fa349c45b1a7fdccde5f9ee70d7d65510e8b4bce654f2541fae7641ad86f9bbc1f02e93e94422433f8b40000000000000000000000000000000006cfe7026cd423be189c5ade8de197aecbc9aefd4cdbbd2aeacda816247ad59ae06a5c49b0e29bf1140f400d46845191000000000000000000000000000000000cc4f240a317ae9ce75b44fae87c92fe9b6de10e1191cdebdcc37ac200957683849d8a957216676db1af51fa0a2a1136000000000000000000000000000000000ba84d595661e5d9bdf9d268a3cc575fbb6b0d469b58b3e43f80694c78f4e9e501c4a4f9c42ee4518ed7189a1c36ca0c19f254dbf75f1c42046343b0060e71302bf6c94ca2fb8aec74fe7a47a3c9c3ff000000000000000000000000000000000fdf7e2372b01b5d926a18ddd06b4573248c02d7debf944312dc06f76ba08a7be460c451d296b71e9e81cf0956b974b80000000000000000000000000000000018326d0e1bfb4a62ab6f772b47ed7188035a62141e6b2eccf53a299028902a172771e8e46c0b1ac4833ab12045922b3600000000000000000000000000000000072107574145c6afdfc7d618f2dba2b8bb01d92007dafd476e4ca62e6053e5e9f2e34243ec2dd16ffdbe3488b925a0f000000000000000000000000000000000070e8491a835ae96087013b0f8da267a7ca5b0a600d71b8c76fee35f41d8b5c1ad82c5170b0e8d1cacfc7b7b13938e96f08cf27a47d89ae6e2ffb27870d613b9ae586857e4ea00670944a2883ba325af0000000000000000000000000000000018f4da37ff63f66d68c875def8c758d9a5adcdc408f0c12b3a60ee4a285e6702b1d5b9326c61f443dc71ae83c7bd21e80000000000000000000000000000000013a665e430141cff62c25577798473a645d20321490bae7689de6ea223a434c7d3b16ad004b24a82e2c62879b2408cf90000000000000000000000000000000011b0108562f53bd47d9f8ada54166854bf758ef3769ca1c3b7b006fec8707107fef0b6c7e59feb727646b74c27ec699600000000000000000000000000000000028799b52107d8965066e2f629b30c0edb490a0f4d0b6cdfff89a9f7763afbe6217bd42c2059042397b6c0443465fdc050aa333bb6b44086fe6211e89cb70b8467eccc228c09aaa1d589cfc24771a11b000000000000000000000000000000000c42cb42e389f32926ef09584516249ae332641b573ed29bc0884feda08d35c1bdc6c3d4a69fa15105de95010c6cc24600000000000000000000000000000000006c57fbf93c7959c562e0f3ef59966c1640c706fd18a6b539dfd711b0ad79643642038954bc866d42d1c04be375b95a00000000000000000000000000000000039ca3ad23b71693e02af36a4abe6ccd0dd4f4aa709f74d900b9fd015a2eaed55bdc2bc0749c995783a7615971e8a1f50000000000000000000000000000000009a08596b29da34466c8a7f46b805f1b6f2e48bbba614d728562981d3d4884de9a3c1980d398eadcf69e90c851d48526d9f7f74a5ccbd01afd985d3259739023cd012cd67fba3a4ab5597e94d8fad43400000000000000000000000000000000123dde5bb9b7ca11da9e08a9489cf07d147492be8041a5ad0b70715147e21d6017a58af23c47d77885a7830cfbbe5e0d0000000000000000000000000000000001527cec3c393d03e74ee8a7b1d6a8b6398945cd284b59a93fade9839863f0af591c287e89b3b45e6048f2f9b518208e0000000000000000000000000000000017ac3a2d9458bbd5f38d584b0fe4b35f3a452e22161564a7582465d2068b3ba4dc5e1e24a996596b1fb553d641996a4e000000000000000000000000000000000ee5ed5610a78dee181750e35a8ab91c001446f04124930c2ed85de74c6167009af45a6cbc3c59c4915334d7853ee12f85c00be7e66e318bed8e66cc41e7fd0593004bbca20f0dbc28efe4441acfc9ae0000000000000000000000000000000014d60c1d436e4486f35ec85bf2655ba6b752a36c86fd9088c0ce46363e75abd636052f876986fa0f4a59152998c0e4a800000000000000000000000000000000083328e38373f1de1049deaba78f568db818b1dc38d981ae92b968134d369ccc399bc3bd55c841755beb484cbbd60f4b000000000000000000000000000000001788850a5508d81df9af1f087356bf8e63b3c8a4e209403c4de7b3adda07684a08f9de6f1f8fd8dd4b2bb9b75be329cf000000000000000000000000000000001506a37d222173f0098f56b7c443e04ffe08b376e1563344e7bf22b1c9df0a1292f70ba51cbe554843fb93a7f535a4aabacef63d90ad11bbdf0c5fa2db2838c238ad3049a3f47b7f67361825efbc6526000000000000000000000000000000000d5f153952defdea9309269bc996a7714deab12e7644f8f8344140fe53034de538aae6c3af7b06687684edcd2c5dd19e0000000000000000000000000000000002da67345153c87ca65012b8703acbe777900953abaedca4770fd893275948d150ca3d6694d58bbbc9e62904448a8d2c0000000000000000000000000000000006e8c95d22f01fd9d56178d754f0892f46166282a27e6b02826478cd39119636e811c03fd835c714a59bd2f7da5ce5e1000000000000000000000000000000000b5ab6233d8dff50648d89cd65793640c06ea784d00aff329e882ae04fb466506cce3fb6c381b4eacef8b5305953f7b6473fa3d16e6431da14b8639d4fe316692db087a167a2c4f07307e770bb9e35ae000000000000000000000000000000000595edc440a5c94506a79f3b3fee818256d7c4185be40c1953b46765b2f925ed16a476b07a267570c727592dfc4a0d8d00000000000000000000000000000000079ad05473fca57f26fd068ed659e4aa4919847dd96e683e7d4b3a731cc9ae0562a693abeea4fd550e644b43b553118500000000000000000000000000000000176a9751dbfe727a442797551254cf904862c4d590892e019a54b72f6a5a124d268777b82e19d557690ccfb81cbe949d00000000000000000000000000000000164ab74c150cd151b70fdd7d63d0404214fc9cdafba3bc642aa798b1c301c287ff6d05ee7b3a3ce997072b8189d54aa62774741f87af1d6942dc4ed79b70b2d706f3db6b6d083eef0475334ef1e2410a", "Expected": "0000000000000000000000000000000017d73e29f1d555a10272043ac0900e80883c185ff7d087ee7f5a3b762213e658a42d1b4fdd435d1acb9d5587fa7e8243000000000000000000000000000000000ddc440795d0e4308577fe8439d43418641538711972c9744dfc8a4c206c193aa17958404bc387c7c2fa30bc678937f7000000000000000000000000000000000d7e43c0f99adcb02db99974e7615b4ca0de72117792ea515bb04c4bc8680a3fdb0afcf6a3bdfe16bf54c1d7336aa185000000000000000000000000000000000bcec1d7fc9f2210be80e90631810987801fdf60890ce197db041b6a62682fd7e181c6110956c5f5e9c196049e39100f", "Name": "matter_g2_multiexp_56", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015425cbb7075a97dfa9409d7b014127396056dee6d4bb63ea285309fd91280fb691f9cb9572b544b332324f6cb3b1276000000000000000000000000000000000c5b9634e6748d5819396051322d9b7e0377554613a7fd8dc0c71cfb7886dc0ac29add7265af84087a9df5ae3799ae30000000000000000000000000000000000534226ad7324ed5600b5438b659c7b1e96f27ee1d77163f2d3073418f7ded5c613ca4b1a686764ecc43ce3388e0c32600000000000000000000000000000000198267e2bd474dc0415f47f5c87a11fe0945a91cc0bfc37d504ac53f9b9b0d087cd5dbc9b03972be03d4b3f9d2123945d10ffdd3797ad13e65a1115cab6529d0f87b91eb41d6265e694eed8f02667214000000000000000000000000000000000389a084d95445af6e0afaef21d3676794e45986b9520035111ccdbac4ddc1b23974a686a900616f878f3a06eec90db500000000000000000000000000000000064c75d1129753b5f399c1a5166a0f6a8f427d65ec2fd84d0c7339218e0a396681797bab68b33653ffb9820a6005fa7500000000000000000000000000000000147e199e8c08b9af38cb457b623d0fff32242b11e695f2adc0f136c5596db313b03c2466fb58e37c94704152e5c8f9dd000000000000000000000000000000000e8fe5436baf3470a19891b85d15486d1269e1b13098d837b0a510e71b0e6260700ea85f0bc6476217cc73615370cf003e5da5568a9427e0cbd7973a34c147ac2f3577d06f68280caecf8588ebf1591a000000000000000000000000000000000a39a2032858a57ccbfb940741f4ae21b318a56d5567cc0088ed52dddf1e0d5de60bd2da9b675212a9a28ec17fca7c0600000000000000000000000000000000039e2a4bb1b417f8a94b02cad60a3e1c4c4bc5a86a23def7cfaecbfd97d89a5104e0cd13870c9fbd010dfec3ad9b1df9000000000000000000000000000000000bc29c5623f9f18ec2af5bc651a65d89554705a349923ee15a9bfb82c114246b404a1dc1c24d65c8749e7c9cf62d963a0000000000000000000000000000000001496d76f7b8583a64c1627151589af876a2f5e7677611ea15f14606538f6052c56e9fc3ed145c313acea69a51547fb6145b5f1f156f3c823cc129568e7602694107608c1f9545edaa897df58d27b18f0000000000000000000000000000000015f83b2f998691e504aa740b4db38f5b0236ece3bc1ca933b79999d55b737bfec51e590c2127d57625a9b7c2960c06280000000000000000000000000000000001b7b117f5d722e320b7e90307ac1423aec5e30c29602d314bac9e5272ad3990d31999bf3f516ac78b2be0e16c0375d8000000000000000000000000000000000fa7992cd7fb679eb5f9f9a9febe9c3cf41a717c8f6fffbab5748572098407174f09457e13468165f1c7275d52f6c84b000000000000000000000000000000000737e95f62aacd12f8aebc288c5cfe052f34c4d16e7b44df4497d9a713b77485fb0efc09aef11c7b86eec4d0cfd9b03ecf6760be82cefac2843265be5fc0fd6d308c1ed06fc684c4693de25372f09ed000000000000000000000000000000000004d48d72ad4e77954ec6a5a62299f0472bc52b556cf3857019f8efdd694758f13029f9d6832ed672cc210f32033da8d0000000000000000000000000000000009b2394755d0319741d131b012ba0ece7e2044def20ae73fe73bcc276af9d807ad75be79202963f9a5c512a6ca53197800000000000000000000000000000000128f856fc4790d9fa68cd2a3c152d675453dd81dd64f0ab084c6dabce456f78c2bab0e7f315439b34f86e8fa61a33ffd00000000000000000000000000000000173dbb908ed617ffffb6aeb212cfe6c03f7ee51c84134fde67de2ad9561a897e28a0efa66257ae0c21ebcee3fe4fa68cd9fca4d166149ac9e6159ce95a06f790a96243662373637f0c6a59764b77b45e000000000000000000000000000000000bb7b84476d4b17f4ada0b6f50d34dfaecd611356862895c8d2fee6707c4aedbf565560d4207e43c179c5cd33cbb739000000000000000000000000000000000112d8b10c775218d318090dfcef55a903953f7466c50417125ec0b2c20a24fb50bd172331c0377d4f47aec99bd87a3fc000000000000000000000000000000000cf4e4b3c600053f45f350c8860e47621f50f3849872a91ab115f71a2b04657991217e2f0844b296d3a6bc33ee66e6a80000000000000000000000000000000008f625da164bc9d96be3e78df63bd1633a2951dbea0b98e359c6317abe6ac5799c4bb00bbc2c5d02048539e753019a6241733039312347a0c9d760c1bb9a1209a34a02b359a9c52a57eddced1575867000000000000000000000000000000000028db057ab9421eefd1fd481c91153b5c1ceb0f2dacb0097298cac986f036572c6ab0c8709325b3bc25bd494bb46c55400000000000000000000000000000000024be09301c9be4f726fbf7796e8336c50897e8534614c25f65c37bcfc6e724d530c2782bf483668fd08e91ad09484af00000000000000000000000000000000037bfdaa11660111ce0a9c3e18b5da74c004cb44882b1aea4173e18d3a17f04fefa3b319afaf4af9dbf3d4b9ddb2c3a00000000000000000000000000000000008f2138bf621237a286229fe762968a224358b030f6c20db58043c13727b516097b42d47781bd0f0df2b155197ca3946b21b18d883ef62084ce4bd353d7434d7e220e9cf6bd0e8d0bed1ad0a4ad94c7e000000000000000000000000000000000b4e2b058d6e77cf95be093375233e5c9c8ee0cb2a3aa93172c08faea111df81b9721a506180b7b45bdde4b58b0b7368000000000000000000000000000000000f7025cc33424a7c11eef47baef888535d938d50c0f40eb83ae86791834770e5dd95b30aebdd2c13eda3447d5730ce3b00000000000000000000000000000000088270ef05480ef8aac5c284358d8e06c3482c26279734b8513000019924cefeb396ae79f5d9bd863bdd9b22e3ac3c54000000000000000000000000000000000df75afafb138fb06bfd905c87035bc5d18c45a29267c3965131083d7e0112e10556d7693d424172a53e8d3120f0cf2aeafb6aa11296facbc13936bd2ba09a2cf9bbd9dab6ec8cc5f73d78c90b471a3000000000000000000000000000000000122fdd3c83c01c7cbe71f54d783181860e7dcf8406e3966e910f4d0ccddae3a245d6b1f94b1182d1917fd63960cd75d400000000000000000000000000000000043592e5797cc1409d6d42dacad628448799b24320acbda83f6ea9d232968efd021058f540e3bd73a7f95761efbb5fc400000000000000000000000000000000025b5a8577ec1064b5c557415a50e84c2302df97eb65860f979e5b1e261f47c0f305461681beb07e521cf03f0e21fd030000000000000000000000000000000017e86f3ffe72bcb71d46661a1537918d52e886e362d78ed756140a6b5083a4eebb5280b9eeb8a25251dec43a5cf509b13d39a61323c07f9f4656a6c5e6ba139da8175ebfb8a641de50cfa2290884662900000000000000000000000000000000122f26b4561d1f79a70bd0e401f25d50891c0fa0320579ef21aeed7c191fe1c75403a09260c3872cf74b798eb1587ebe00000000000000000000000000000000039a261d9f48b9eab6e89046f333ac328cea287993166057e9b99fa8a7d7eb3e7c34ecbb353b7427b235084f47f45d1100000000000000000000000000000000015d5e297317684bd0169c795d9dcd209452d024ef9a450c41beb0f6c7e6dc5fa0f3ae24c7cf2d7eef97bdc51788188d000000000000000000000000000000001487564f0e9d3e0d2d30ec9930a00f10093e29f2f195344f567960be323ca21231efd8528108dbee4d5ae4de3930ddedf6374d0849a4471eca96c5e715b10505c4c49664f341d04705fc688c8479cda4000000000000000000000000000000001965ac3a520c1ac39b86832ecbe226ae0474b76659076ccbb550a0daf41c40d424ceda084dd991f22cc53779085828430000000000000000000000000000000002e970a4248823049bb4339d21583fdce9540ec103d6e9530b89e39ea875b1c333f7f5f859be39baad34b374055baa770000000000000000000000000000000003460eafb3e54ec03fd5cc1d460e1359b97f5543e6231d61614c1225ab7545fae079ac8e65668b83d022031a7a54746b000000000000000000000000000000000321394863e7c70df3934d874613b7c9d6c331e59a599be593c82edb7a26eff9bee8e4befbf122240d2deb2d527bd38c0b7cb52b99abe10d1367f8d3def38221c18657a1114ceaa1c0673ab13a6e10870000000000000000000000000000000001a5eebe200ec041476457f8585cb4ccdda936cca4977d7701c44e0d4fc5d9c206682a23348013a055117028c16914400000000000000000000000000000000003519bd1dea70245e521988336eb41870599a877380c0a9eb19301f9b2caf963eb559070e23eaeefa4de0173bb1fbd8a00000000000000000000000000000000125707f5a8e26b28968dab97ef4654c315b0a118c20935e38a5a526d9ac0a0e18355d8c9f3f58c082de98691957e2d5e0000000000000000000000000000000010b58dd683f73a16d8bd5557b35b7003a761bdf7d90ef576de8acd420bc74f5219fe7f9d35667feeb3ddf1d568b56bf1f49b1fa80a321d4d100069b2c4b94cbda255d8e9f1a7f14ddf4762b76e4a386f00000000000000000000000000000000018267d8b83ca59d4efce7ee3d73f7b984f09556ea4fa5cff5997a1eeeaeb8bdc9185176d77ad0f4d86f2e429f4015350000000000000000000000000000000014114344d6b7c976cdaf2418d7f72c120c2fddcc65c3ead067482e7073e2a3a239af19f862ad247e3181b13f5236d1040000000000000000000000000000000015db961a093b248e83deea0ceeebfc3dd57c7cf8b48cd627c5c566a4f9bea30ff0ef9cab9287a0f520a72b02d9092a0c0000000000000000000000000000000015159439fbfb91d1e24af611563aee3eb498fde666a1014a9f645037995d72dca0ed5569da7ecd084208b7c228e8a2b2ad3625b0839cc1ab8c9798b2e9706ba6d7aa623f3c0ce0985bccb2ee5c05a313000000000000000000000000000000000e1780b32a7b17464cf514efc4bdb02283af396ffcf6d1ae023e07fae02becdcc3c467f89f8edc9173a71aad27b200da000000000000000000000000000000000c3e7fd95dd823338bdf3d82fd46c265a3f794d4065d83873b1aca66da5f80c5962c9dcf537fc315d024d8cab7bed89d000000000000000000000000000000000e4eb722080e24f54fac7eed4b94e7b1eedb081c3edd7aaf5433d00829929d8bdef940aedbdd7dfb0376b3ad5544d9cf00000000000000000000000000000000158c1ff057f7ffe6492097e339cc4ce56bbefd39658ad55e08d5407619d1cbea7c83b977a1583ee48897a5e9c0d9ce3e150e53fb45ba8ce5ca917010f26451220be51141fe21cfc1cc06a5557e8e7afc00000000000000000000000000000000138e8bc8cfaecba9fd1322a3c1682c9fc1286d78e5b6718da00acc69f811fe9f94c9f0dc9d80e9002c0022c6dfcf156a00000000000000000000000000000000021da679a068b2f5f473ceed588f07adc7f485003f7d2286a18c07b09b835881f4ab94c7d4ec742c33a7cf01801116fe0000000000000000000000000000000018a62c2f4a02b73f5a91f503b53332304afc9cd8769f236259789277599a203b8b304b38993835a87d7cc970ad514d2400000000000000000000000000000000179396865f859386df7c1b8fa84c4ee71c14daf695fc0841c293618e6f8c87fb56b924f3f91a273b969e8635d7f90985d69ec73df67feb970f1c7a3880ee84d948eab4d8672a6c1481d61efc6cd710020000000000000000000000000000000004a8cb437297722c0c1a9471ff083ce60ec40c908af4ebb570c87133df705e725e3209152bcff26a0d6e4602030610d3000000000000000000000000000000001832e55a9e703d727156e4677ef4f82b86c6764123c3ed1dd94ae3b46d7eed459114993968eaf8e21cf24c59d042f41d000000000000000000000000000000000f606d5ee57b188636334ad60057cec4008ace88f14ea06324edaecb26da627670b44b6ac57b9fa2717d03096010785300000000000000000000000000000000145bf70f90a9d98f56ed38b3506556a48a1340ca6161806d055d7a1382eed54e294564de7fdbf525b0012de3d25ab5c838f8acba4782dfbc02a14d4b1d7b2b0a582f9bd75642169707a475b1a7d2d7e0", "Expected": "0000000000000000000000000000000018ca453b9d832f029ac8c7c70df846be97b530e6e42de3ba6943a7d0dc00296942f88eba6a9cc3352900ff124efaf7d90000000000000000000000000000000002e4514102aa3f772f2659ae9f1e2a91c7fb749ea590a3cea2c1a2e0f7236f71e182374cf7ebd2fa086dd921c29013910000000000000000000000000000000007c025696cdbf403494c5fc7f9a10ad0c549f84d1e06c5c4bb22f7a039486909c540776224bcdaaeb3880ae9d745dbe5000000000000000000000000000000000b5b5b70fae8b3953ee6661a0f4a1be25596839482d78710e584d3bcd93dff2b0bf4c8b20974744667e25fd8353cec0a", "Name": "matter_g2_multiexp_57", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001265e90c564693db716f17d1a8815a8449e43b5a2d5446ca65160d864718cdfd413d5aa024e7581421c7222c29eb452b00000000000000000000000000000000133a6558baa53a2b8d239198e1dcd81af1ee46d55137177be467a99edf282edcd47b7861a3c822f9bd0df2e86aeb5dc2000000000000000000000000000000000d8287564bcedb1e57c3d74b0d484a9b475ce3f5b0322bda0e980de8891e2e8663abda99744b58032b8d7d3adddbac9500000000000000000000000000000000013cc35410d7fe07eac96abd2b35ff656e17b6b1eba2bd1d75ce5c87c5e76755ef9c2cce70f05cdec15d1bc44bf902d4cacfb05e5d10c41b06a487e9f8afa38759eeb55f0a5bc8640164bbb081c1fd2a00000000000000000000000000000000193f0cd6b4051cfd89f358cf6643528f0f042ae30ba3627d297b4fa2c2936426a9c1b65145b8192f65dfaad1f2fbc358000000000000000000000000000000000a92ca8943e64a391aa39126f093f2b530f556c1e3ea1b55bef1c264909dc93d260eec6420fb7a4e4a45f932d57951500000000000000000000000000000000005c7dc5832f744089d5fe034bc93e0bcca042ddd1b221cdd5958be86214831906ddbf82508dd91dccee467fd1625dd740000000000000000000000000000000011b11b3d24f44bcafbcb9baf62cef3f18b56ded696b73577375dae8108dcfb663d437e4cd9e44b7e6bf49741e058f8cb9a0b88d946231cc484550a87a548719f0a543c0698411f230a966cf602dc4de300000000000000000000000000000000073872ce0d74ea368df132897617aa8f941b67cf3fb395ca6c2f5bb2c551f17d68b0c6ef11e742206d6559796f06426c00000000000000000000000000000000156cc28eece7bed943c8410a44af112edd8576807e25701093eac0c9726f93da68a19c1d7b294f3ae6c84e32e7c2d5ba00000000000000000000000000000000050fe5987d5fa678be3d34c50fa6c5296f883e65ac3201c333b97ec0de00dee6187d2790c357a3f8822a174a534539a900000000000000000000000000000000177fee6e2d3909c0536acdbbdfc716f6ca19b6bfee7920a78ac9725c85114c69cd13152467e72270e35006b3c6caee8c74e3b5ff944bbbbf808f1f469a3380ee7dc37ebecdd8fcdbbd2f2561e0dcd68e000000000000000000000000000000000dd147bec9e0d1727c9d7597dea4a5b6b15c0a603dd1b586835580468148a502289fcc38194b2fccdcd8fdf0d8ec1904000000000000000000000000000000000186501fa4f3a20e80bf297e8ef1885b7d157617701839a3b524d61f35b2eb843ff0af13e253bbdef653a83e07a5871e000000000000000000000000000000000023eda2ed9d34aa253c8bf2f3b66b3c0c2551cc0e74f43dde2e429d9dea113a62572d245b44708bed79d662d9cba487000000000000000000000000000000001041cdaeb244803556e9b20db95f2a66830cbe47a68aea262865da50ab15ba658116657625318fe46fef393eeb6f3e2ec23064970a4ae4ae648a79edb193d98208418d3489e9b5b8517ebe99cc32b4d7000000000000000000000000000000000c27b1feeeb38068ee52b0fa440af2e3bcfd16601c8af983d259f2d15316b513ac3e89069bc141f02b934f2e474253ba00000000000000000000000000000000183f966cdb28f344ccae4cfda63ba6a6f29d00ab942ae7db7572cc09305e4f80c11305527b8ba38c40aae5f23165cf9400000000000000000000000000000000049cf59bbd6c26ab3e25b3cb94878271c73c0b4436573d612311feceed0f1668f4d79aad92360c1c97d60b540239ae630000000000000000000000000000000015f35eb8e4c40cb1297f7128d99b109ca75944c1943abe9158813432145a4a2a5663b55dbabfa48bfd9dd01907e1e8d3972fb60ccab83b6ce042c09ead82fea3d2cb891e21ddc5af7b5d8e334d5a3264000000000000000000000000000000000e5d9a671862733804f517dc9cae2190ef0005f26394e3161fbe771b9a486368871f4b1f10f405e45048362f437238260000000000000000000000000000000008100c6f96ae7af5fc86d9d91fbbefcc1bf5873dacaba9c3adf1b2833dd529d87f303a55e5d4098153377effd0f8114500000000000000000000000000000000010e4863a9b037d4ae6dff827a34be04c7f1627670b40e5cafb1fbca2fbf56af9ea6b24548db58e3119db64553d18cf200000000000000000000000000000000036a298ad5e8b32041a18e3f6c5847eaef20a5b63ddece41bd7dc4c4a54deb9c6d7002e6621aa01d78d64ec9991f68fbdb68c389b94c82f006fdc637696d8085b24897177d2992f504d4bcf5ff04d173000000000000000000000000000000000f62c0bad83c41887bf1ebd2644cef0577d793c2f3d67cbe43974f460a4afaf2e412fbf9ec97404e5e882ca0b23bd1a400000000000000000000000000000000191562ec9ace63ad2aae1f7fa977b9e0606e1da9775a978b2caafada4f6b3d9104562f2055fe037cd06df6093123a08e00000000000000000000000000000000156702c3feef1baf5ba202a25b9dfd5c1fc620e837501b0c5bcb85ec8b6e3e92bad1fc842bd1a0dac363e4bdf0fac87c0000000000000000000000000000000013a4b7e869ed9bdbf9671a5d8ca9145a2e97b6885d2a93b33f378e649e0e576be65bfe849119381057337315363bab2f4510c100005f2306f4b474d3843b4a79d04f0171afc5c66df70f631b0481dd330000000000000000000000000000000000a4b273438168494f0db235f535bf31893bb70f4119dc4741aa3c5e63e93b9a8bc001faaca10e37f36e130ef53853900000000000000000000000000000000010936551b148e16249dd934fcc83dee55279495c2a70d46dfc45945a69549657c3dd7cce00d8136e28d64b0c800344cd00000000000000000000000000000000115c053ac0b68573c3abd5f047b8fcd897e3d514945c5fe6efebf1921563d0079eadf32f7428ecb703d9163bc7811ebf00000000000000000000000000000000162e86af01daf552589b62be849e6176d74fa5da9b214a5cf2285802dbc44f346eaee5cc3d93a085740f74cf7e1b17e1dc682a2be4d67852d119795988c52230d8273648cc176ddc012a4b4da5a8636b000000000000000000000000000000000d77cb5045f7d4578621c76bf5b3db076661c72174508279280de3e92f0aa57057ab50180f0f908561a87d412636d964000000000000000000000000000000001853f9cdccf5e6e4b87231b153ea5257f52ff10dcb24cbaaaa95426d0231dbb355f9c47475d125ec1079b9bf26b23b560000000000000000000000000000000000fab825e06c2329a19de853a05c4bc65f16fa047eadba8e79607bb31b84ed6541b00f7f14b15687d67cb4cae0ef9c600000000000000000000000000000000005deaebb5f31a62fc0bc1af13da63d0af3c716df8c9bf00f1e831af5882b88974c49e8d35db2545747c85ac35156bb668af6b200fc8e6a57a954226d9a0254c8bcbbc55fd6c3db5cf8532323d4c50b4b0000000000000000000000000000000016faa5e91048badedcb33e83684d2670051c82b7a1d0ead0e28f4dddccb141a8ed1fa7606e4b6a3a893c55344263eb4400000000000000000000000000000000019b2c8758abe5d339afade4ad0c1d44d651f185f8a0030b81b136d5972510b353d43cef616ce04827d56255419831a400000000000000000000000000000000124b1e87f343a890fd690e384cd156da57f4f0fc5b1ca99c73bb0571332ec4c12d3ebe955e3ae792efadc1d5c0c67a410000000000000000000000000000000014cef10e4a9a41bf117aacd2fca5f1364a46b0c4aa0723a369fc6ede09dc76dcd8cb67fdf87ac49bd4bd9981a2e589647e2036f73e8cd5e42ad86914e192dd969465aed0c3b752986b84a0c2444c90b80000000000000000000000000000000002862fd5f38154dd452f65de0d3c1d54403cdd2a397ef416fb92e570913c543d3368a95fa114fcf48c3bb4b68895ba33000000000000000000000000000000000e7185443e5dbb656fcb9ed100949f8f7052ee2cdcba4f5c687a65a1b45bf66ede5c60b0c04845b9a870e004f8af8450000000000000000000000000000000001817be6d13cf2a67225b2eaf073e9f1614f3bd32cf5572766ace4a91f6b6be56f498b989f1c3dd3dbc9a819c029431dc0000000000000000000000000000000001cf41fe428b088a17b8ea93a653677705d5c024db530b8300752c6b100f2abe4c46dfc24afdaa2b3d53cd8ce0df1b6a70cd5c1545e76027c389645da1089fa88f675b5b6ef9217b584d7202b797f8520000000000000000000000000000000002eed272430ca3176988272e6157a18df7151bbfed5b90979752a02619ef467af8083208dcc9c7d926490b1283baa21f000000000000000000000000000000000a644f6137bde232c3a909b742d30bba096ef88b711ef100144276d0944487f9ebe8331483978a47c07d3a42c441310900000000000000000000000000000000042c67cdc10efa8301ae95d6d4f21cf152f04b235bad2dc5a61724cba64083f690b3158676ee6ef10f52dcc7061f7c7d0000000000000000000000000000000007018d0aed5abb744cb998f84140331fb2cef8d9e09c76176def48a85370c6247c2ac6fc726eea891b2041ad5edca7f0244041bcfc21ede8023ad80b6d4af4b2777c0204ca5f61854e6da34ff5e1145f00000000000000000000000000000000141c0edc966b7c845d4e68272c6a71f8ffb7fd8d56b7cabcd556a98422f830d7a81d123d701ce1479e84047328ac1f3100000000000000000000000000000000105c1164d721b6dfb05b6b69955b2f25db0e9fdb58600a3229dd516076087aaec05b837ade68bd2a19917eee7b9a22bb000000000000000000000000000000000da3dd97e693948fd6955ae52d493b3a2d2896dd4ad00a0b549d4d392e81593472e4f9435a8b7977f3d58e324c5b9af800000000000000000000000000000000068c531ddb26a2299cc584b5bbfb0235fd774a2447134c06e7de8b94993804958bbf1ee80728cc6db647e8a244462372ad7572da641373708bef008057aa5af1cc76ccb882bacc50a77b37d7047b1bf3000000000000000000000000000000001881432f4742dbe41bf774930413c98d49a781a48d6c64ee1a18f3076bc6c0e1214f92d5bc84ac65ee1c586c437d697300000000000000000000000000000000067e0a95f3eb826f3efeedc1882ecfa30b8b96c92f626aa324f4044ee74531fbfd50a221b1b0e0182d759d149d51427d00000000000000000000000000000000173f5be7098b756ea84f030e374973feb4f8811118ea6673db1db75ec6909303e571ec5a1d55a6bddf32fc80480cf103000000000000000000000000000000000f28540976a6ddb277df5951fe58e7310861af837cf31fe31c24f7b979f72ef1549372e7ea1ced15b655d24293dade7854b51c78093cafcb57c4c1f172d08257c379a9caeb5b5478cacb4887119a08c600000000000000000000000000000000188f296e218719bb9cabefd4f33d5728a1d280bc59c3d826a0f3b5338f92e6544a4cf36f1a493458e0adb246c01a415a0000000000000000000000000000000007dc8e4222c7ba78190a8e72ec7e6980e2581f51a8d6c41669b6fc9e16d50a2bf4d422af73398e76b2f39705eaf8a6da000000000000000000000000000000000b25a44523323301cc01b50d58726768c2cf61e691203dd34a0ce8d58fe4f72c1c33abfb2a56e0425fa9b7e2fe48e870000000000000000000000000000000000c6f11ea269d9061d2f462ac37401def1b2b28c47b84344d04d1f026add3237d99a586e3fcbae347a4ecb5646c8c569fae3bbf55186a89740af4da6c073d8c0e331542a2c972a49dd3bf65261dda6e49000000000000000000000000000000000c41a02e937f8cacc0be5d9f2d9fff0d6d4302fd252f32145974206463854b3a7d09b3b147cdf2d7536e970dc13613ab0000000000000000000000000000000005f9367f4e31f7e4d6e21664ac13d55f501f5368c1ca77fc439db60e1846861e6c4c3c44909469f88e02cd973499992300000000000000000000000000000000131fe6df7fff97f132bfcba1d2599a862c1feb514a05b4b7b0bccf49e00aaad043edae9346bf726e2eee498dbadf2067000000000000000000000000000000000e59044f0950a741da3881282697f4a1a522b026e493f6009227da4c0a963de622d5e421c30e0023f4118c9a036274f859b43915b15c509ab8930979312dea2ec9cfa9f679b004ee526aa5dbb25759a4", "Expected": "00000000000000000000000000000000144433ad3afca0a9581e7e87220a4944e26ef2eef6b887ce77d2a2559ced058e7349b36efa66c492cc75b014b3448ef9000000000000000000000000000000000267b90e45d7001edae01fb198d16dd37c43cadcd2ca87bd7cd1f0f65a95148144f5ddfe75d344eb4573c1376aa2728600000000000000000000000000000000050ade28b09b0394b08d128c089808021e4c65dac49d9fb45efb93792a4faf210230b650fc3ce810fb8d11947e9af5060000000000000000000000000000000003b1d7dd7c6d944d16724fd1bbfe0f53b6b50a70e133dc5998c82b51f817f489bfe1e0c361be36fa41f5af7c1577f2ea", "Name": "matter_g2_multiexp_58", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a081f037738b0d812da43a907e7c624e331108ffb72104d82725b9c14dec8449f5ba0e8c1a3f1379cad2c3e7aa99f70000000000000000000000000000000000937fb5d8b3c258b7b28555fb59620f114816f0fad46818a5f100bf7dc3332a03d285eda18e31e4047cb2606bc53b20c000000000000000000000000000000001574e355b7570043bf36ecd52f9c4d9ff556146d81a1e9d088444805db9b3b678fb55774865ad34d21022afea2c154590000000000000000000000000000000009f70a5cc658cdab280ed65e13aaa319049b9534a222217a08168047ee2491f25a9d2620c7343a6426bc54a0700bdb4fa53d5989b63ee5f157cc44c684ccc7cb4c74338b12fbfb534ea33db341fa6b460000000000000000000000000000000015a76e89c8938b8a27e4857aaae8c942371b6979605adf774827e9438ef739428fc53b65d32e4e152cbc6a4de42b8bf30000000000000000000000000000000019494030ae0507eeff20b69b4913596c1b9ea6927157945c8295e273707013ef1f2cd08c058f6b469a6c99ad73acc28700000000000000000000000000000000122ea7ac21a27ca7c4b00207538bf561f688429999332c45de7545046acbd6d9e96d31f5f6a00595eeb212918a28d2920000000000000000000000000000000018b023e7da67cb8d9159746bf700f9e151fa60ba8f5a28b3739de005822929cd28c49b9dbb4ca8a10729dd24771730ff4d840680013af06920dd06bacc0ce95cf0cf79e8ccc0b10027f2d28c1d0049980000000000000000000000000000000007811c759634904765029e955c3deca648fba6a9da6433b50a6d2086a59e65811d52d41ed8ff2e9bd63a4c0828bc702c00000000000000000000000000000000182c86cddf5e20697462c829f41c7b49e7976880311b01ed4d12d7174340799f19db0f295263a2617182bfd1b49e0d1b0000000000000000000000000000000011824bc20bd1b27876b4f48aa8fe3063f826b6b2c3dd777fb8999a25d9139f218f6f288955274884ce96ef2dc6d34d120000000000000000000000000000000000dd310d5e141e4eb13380db828caf74f62878959b6b2df998bebf9306965f723fcd4dae7c25bf2f79ece3e8e9b92de61b67d661ebc9008669bb4e5cffef81a32baabd71667a72f1d202ced823f09c740000000000000000000000000000000005667d8c4f8dc3f4aa0021d1026a1d0dd0bc3576c49339262e84d20198fffe33a389d28ab1d782e9d19af761a2f097b40000000000000000000000000000000002803d5ad6393d7072e149f1f2ebf70cd8961ba3bbefd648916a8ac5a5eb893b71bb6015e201dc241537ad5890024239000000000000000000000000000000000122e1d0e0859b04143f23c4d2d2ffec09ca2ce5eaa9429dd0c047032d180bcdb10c106071d9f9701c006e5eb8ef88130000000000000000000000000000000008347a7bdb3b4f381b58ed3a128134c09563b345380ec948943e738347de5b5737540b57c28d00b9d060c60942446617ee495199ebdebda02179432d42d5d9c76eead4d4993cd09a93d46cac997716a5000000000000000000000000000000000b26aaa46a279c482fb395ddb84d5b4c9c70102c336cd565ca9eecf62cb96f59f634adf46af748826590fe65beea752b0000000000000000000000000000000012cc63256a9f73f450e86ee38c54ea78baa5bf87d3bc01320f7fbd85bf11e19f75d787b9b12b8f2c7634368a9023de880000000000000000000000000000000006392fe611835f6fd50229725d71d435f704f78cabd1b5569e1c5a89d4b11f911f0e34ec034369f972a80eb407938b97000000000000000000000000000000000f4ff2d6a991fde9093000d7bd9cecb289383d259346d83bc9bf5389d4c39c82a0e1d7deb84b90ef370e0a19fce28d2b3e038e473d6f965751ebc5f69eea6f37be88cf001de0c4e4b700823d8326f17500000000000000000000000000000000193752c40fa0f466f7c8bd26658f133d0283d2ac3b02eadd27b3e9681329307f91a1512fbc53e537f9e1025a3d68a7ca000000000000000000000000000000001106d751c9e1637f00e51e0be856405e6b69421d81bb30b9b8718cbc9cfdc36c80d2848bab0d5246da84f10b478fe48e000000000000000000000000000000000827a83f28678c4e39c4963e95c2404a70691885788e5457e149c0c45d4e8c74eef55223ed15cd75fad9f7209a6ecaee00000000000000000000000000000000072667f02b781c8e0a75d0ed8f3d55e668ddcc8c61937c80653e240c3a744c961055c782ca41b15211c0f1e1ba800bf5ab2af2590309c9b9177e4f6f0fa06339fa720cf1c9fc7c001785d7145a3c9030000000000000000000000000000000001419629aaf0baf779feca264d0d9846b987506125b0049ebc8b307c4e3ffe00da1284a94a012bfd60456a4a937b2e0e000000000000000000000000000000000119a801bd0a5a1c1b25cebbbcccc7d2bed9baa4995483f4ae94121a8c6cd0c3f90a26234f51590d66cc38b8bef9020d3000000000000000000000000000000001125bd15fd9814ddd15be0997a6961b6f1c05ce7944514371f10c8e5bde271c4b936d6537d91ebed740fbefe6b281a0d000000000000000000000000000000000982a2904a524b1fafc50d540506b8fb07c3b4978310bf3cf53ce570b1b05e746981bcfc06d59a78d170573b09347f3fc9551f12084ad7d4ce346f841fef785d644821b5c2d3c8db3145fc26e65666bc000000000000000000000000000000000b1da333e508ec6b0329747fef35cb926d922091d4a45eab7cb5358f20496c66e17e46874ed9600cf4252432c29aeb07000000000000000000000000000000000c757daad8f3ed7dfd64782548eedfe904f7ef3bcc11eefc4781fb37159d07825a4c9f3fdf9cb3d8f3944277bf25f88c0000000000000000000000000000000011160e21503d6fd61a2ca0212a7d48317186f259a987a17cc3eb04a6d9251736e4a66b739a8f3095684b7d91ce6f79730000000000000000000000000000000007440ec0f9197352a3148f9bb3d3dba9b1d5add903e48b50ef3f6879859b22ea0e31b46ea4ce566930d8853520abdd14ef5823541696ecb88d0c71e00a15282c40d4826220a202be09c47fd6891b93ba00000000000000000000000000000000070ffa4d522df8b9f62aaf36132bb1b857e177280a7b6d3af6bfc79b73ad3848241df18ca7f8993ae3d67005ead9264d000000000000000000000000000000000e32b65bf035bcb11f86c60a334622d2367797d0226761b58a7db8c7324fc4bb498a558eec509c2326fbd0e7bb8d3d19000000000000000000000000000000000dd291a760393c6e962818986727e5ca5d46544dc47eb49dd828c6f74caf0599e88c4293881714c425b0697944faa861000000000000000000000000000000000f7ead0be081467f3371ab92c249cea73dedfefcb6aa16a162c06e30605e104844c3dd194b4a89ad5230f596bef64f19e32d695dd02323d40ac1eb9452cc53376ef941237563b1ee380c9824a565008d000000000000000000000000000000000ca545b53836899e507880329799e4c1a1acc17275f5d71d87b9e41ccd7a090da854f9936254448c988ec772a813bb6e0000000000000000000000000000000016c9b03fd01394560497d6a03add63c034f96744d96a13a4ec92d28719018d1eba1465e4332e53f37f2aec4d93d4ab7f0000000000000000000000000000000007019f5201dce326d5a6a1ebecf3fe50e22335593bc9d3e62256351c591f0a1a577d916055d79c0b4abe191b6b8011fe0000000000000000000000000000000017acbe72fe30c386e463f3e9b35a474b902f6712b30af88ef340e6fc6ec0fe2e606c7e26432c2a4de33a12e35ce41868f5e23ff8acf88d18e53bb31476f10fef288e20e818431f9f0d2ffe1265e8ea8200000000000000000000000000000000057f856ae648279f2b6dd17584e1388e4dfdc9e870db48ee6ef5f58389ccd4ba17e074b79ae12b728c59e2f91bac5709000000000000000000000000000000000e0f39f4beddbf05fd700458448067b52c11e963b22603f10d697d6b6286b1449b1663e032bf7bea48f2051d8ded923f000000000000000000000000000000000022cfadc1dc399ef5f12afe1349d9274cd595a9ab6ef7ffdd68f8bd2d170a4a783ce0a7303878d809a16bb8073d79860000000000000000000000000000000007e301565124eb66d59a70897f2ac356e7b0c1bfd4e3b57e508ba0cb5c9c881f9de86b91fd5133aa2977c8e81138d66971927817449ba5f053d0ed1e567b53b1179c6b62a554c8be6764d7ce203f74e4000000000000000000000000000000000edf3fdbfb03bc07871079aa4aade538a97e1619b54d0692a7f5f73d7fbc8abbf680ea3a99325e03c0501ef174deedd1000000000000000000000000000000000b8c1b5d3c926d7da6e0583f67d981af5286a04429e857b0aa4b1120604f9c8c93f04e763da169137416dc9ec4839a910000000000000000000000000000000006ca2aa4c7109f043da9cd90bc801404685db802eb8bc925d9d098e7af3d9f95ca490790b2b1c77995c050aaebb935db0000000000000000000000000000000001f40a2090b63f94f93e8b61b5ba1ac62a37548342ad81a9bd99ce8339435a7d7477c3b9cee9b531a1ecdc85a72041555ce5d6f0e44a20d0a0e2f1cc523455b001dbeef772d84b2599daec66b285027f00000000000000000000000000000000021464dded318cfa86db1e4329f302bbeca7095d910c4260799cd2a60ebb20e60152868e67a48b86f44000f267d11c33000000000000000000000000000000000ae45fa46fc8e043c3df99bc0d87ffc5867208fde0eaeda782230341a8624b101346f35fa24e1dd67ab200f5d6fbc8a7000000000000000000000000000000000795b9afedbb128a46c1eb25c52a71375903adf7d3520535372d9af5023dadb1dfefdcc0cb546e9d218890123252946d000000000000000000000000000000001852511855bb368cec51c54d95b430259f05dba6bae53b5c42d69f31371c30cb611037fbd81393a896cbdb6240114549d37f7bca1a59f65982294755ddf8af7f1c953b6e482fee854e0d89e9b269e0e900000000000000000000000000000000113b883c6bc41b0673145bfeccda414af45efe5710f436977712e7227f38911cbae851dbe03928f38e310033458eed72000000000000000000000000000000000853e32773ef1f95a3936aacbca50cdd5eed3d08dc467d7ee834487e445fbdaeddb0df394bd0c91fdb06d2883c4dadd60000000000000000000000000000000013a7f9cdebb2ec37fad172d31a717f4b538a8ee74432c5a5e6410460eaaa3b5f24d223b76bde4277097e93087b7136330000000000000000000000000000000003d6f141b56e1e2e400fe821524017cd972678a7d64f660c313e6a8910b72b5ac04328d45945077aa2946931c8dbd11706d0535e3728b9e358d9ea82df4f1137db7a02f79c0cd0dd672e24092bf7f6b40000000000000000000000000000000016adbeb3530f6b451d870b2d8292a01143986cd9890c79a64764383575771b8608ea61beb2de87bc034d3b8a085958be000000000000000000000000000000001125d7cf83239e4341c286fe0c8739e7013b234814b26a079ffbffa329ee4705da81fd12f34f49d821690a11b8f83c5e0000000000000000000000000000000005873dc5c0baf0f3297d884ac7b652c749abd0405b96ba60fe396efa179a79fa55be76924b0690c9a528c605ad4f9e120000000000000000000000000000000000fceec23f479c72e0fea0d10d3394d7121bf1673250cf1ebe72eca60af82f232fbee342e2c8705434394d4e519fbb40f56d6810620e8da932c202628c2fa9f0a9f3fda3aa07c262924aa51685d2c9af0000000000000000000000000000000005ec966cfa28e105f3496f977a2f046fb206a190fce1a6062df0fa1946f274cde9f6fa8a71089af8cc2fbc2b60746cf40000000000000000000000000000000013c77ab66fa92a2411391d366a331a40accd120db1c6a656bdd92858826fcbded296293c13ee189ea3f34635de56732c00000000000000000000000000000000162795b6feaf6a63e6ea2d34f2bff2a4985ad26463b8fac69f8525eb0a005bd377fe7ff4aae820d361592d2d88f98f5c00000000000000000000000000000000044c9d5d3bc0d99693f5a0605ed467cca8b5dc7c7093294d14015b59bfd8ac6bd479b73ed52fd30d8bd891ed971912c571e7f672ad398f5c02c989b475d12ce86e6e242d36784308e56178f2a6a1517c", "Expected": "000000000000000000000000000000000c3bed2f51a60f9afa6655853ec2f0e9d46bdc1277bfedffc468d9f36cfc7ad9e70365fecc84a5a40d863dcaadabf22a0000000000000000000000000000000008c5894a4f93b02fa1deda8b556798fb7d71f53046ccc305588bfc00b68bdfc34b3f0bf154ce7cb50c9536ad45e65f300000000000000000000000000000000003699501ebb9698e98dc998fcdac54dff895457d2e4e0a0e2d65d275b5798dc016e921bf1f65fec0f284a563aee66ca70000000000000000000000000000000010389c73de7f6d860c972c1f09dd24137c898e92935c45c10565ef3da3406cf521647ef80688f6e799eef4879ca9a6e8", "Name": "matter_g2_multiexp_59", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000114b9c33bd09899c684e81a5a4e620eefa4e620c01c391a4df5caa75be462ec7ab027a9ae2c31d6643c48e3d75b6ced6000000000000000000000000000000001925084d2a1f537329e23c77b8a820c385ec5e12e4a145888882ec611e99b05b789d79bcab48326db4424309c24d1688000000000000000000000000000000000a1dc78c25cd16211a38bd0c70d24c84da1b83adb219e1b9c06fe6a6669d6e0281a155b4cec32d32751fff653aeef1990000000000000000000000000000000001daa74f19cce1086a87232464ba903938465da5e3e1f9ddc05a4b4dc13f1026e1b07af7254d515d2ad6960ea62dca1f77f9a79850b2fd5a281b22f52de085f12bd34e56808496e1c1388804f534d2da0000000000000000000000000000000018810adf0cc793c21726e9a27b7c558aa16b81af73f22629c478d293208a107fbfed4511d9cbcc25fbc2826bf004e7dc000000000000000000000000000000000356b25cbc7cf65107438125c930dff24b7786cbd7eb744d7f27967619d5cc02799451ac8814782eaf9aa331e6f8dbe7000000000000000000000000000000001164ab32ddbeb11c2c8baf7f311ffb01bcc367395bc7ecbe5642d344a8e879c74a554b3f9e4b6ed7db4ea0f872cf96740000000000000000000000000000000017704b1dfb111807d1f5d90c370a5b2968008a5ee9fd72262b6543c93fa168285c04931198f5195f1abca648722ebdc5630c1fdad9338fa5236f817bada168a737dd3685b327fb59d8a37329920af4cb0000000000000000000000000000000000a336a04a8fd8e18dd9a582da897016983d9beb0fdbcea6c88b7c0640620be52bff32afbe700599e3c08669c457b760000000000000000000000000000000001765fe4faeeb13fc2c007682c031ea7ff2899090e16a9a11959c5c3ae7881a1dd2c6d2b7f5f708a92349a2b0de4b92d5000000000000000000000000000000000e7c57db660133ebeadc2cb2054ab4ed16355466932685d4d11038e1e1f47b0349b68bc4e918dd48ef8e1c5d7cc53f7800000000000000000000000000000000169b629ddd7add588b91d9866a750570dec58662e43409031a5e25f1b2913c5c5a7a7cf666953c99835431f091ab1b140969599bed4899c3c47e1d4081027203c73233536cc6e45aaa78a4f1150a51620000000000000000000000000000000017d03e9855f3bbee719a15208ae24324ebf1879972ac134b027c9e03444a5736863bc55604158e81b38c7fd78ba4bee7000000000000000000000000000000000468f7c5478cc0faab7098dbcc455bf18525b56272c2d02cc1febc1825579a613edc6b455764ffc71c903a0704224a4c00000000000000000000000000000000067104ba5366e7e11bd4d516565d9cdd93d4390f2af3c1ef2ea3b1e84ee8e5c0e0fd8ac11ec9d2553e4cc13b277d473e0000000000000000000000000000000012e10495ba15b29c669cb9683b2fc7a45fe7ddba743b4a39677fbf85aa738480eb9da967eee69b02ef14137e102e240eddd438de35651328de7183dd38820ea2983488ba31d401094e59cacfcd1d031900000000000000000000000000000000078f8c17427847ddaa1665d206866231a5f36d3a7b4e8fa13910161566163006b5aa5d9696f423d0c44195de65326f21000000000000000000000000000000001613c465b65940f43c61b5e3c93313ae49d92728518d9cdfc57b49d6924479b70e281e724e04fa5f165b5999f1c1ed3100000000000000000000000000000000031741b6830c16d730619457d42767a51037fb4118e00bfd6cfcd8baea35ae76a5159bf1f4639fc2951f0b57446110e70000000000000000000000000000000011a618ffbafe4bad0a435d04084233495e5f7fbeaeb66d0d49a8177f562329b52a5ed4fdc680b791f273a7b0d3d4b349191f2b2cc76d848e456d07c84c0826a8861981dc84bdc671bc9b5882d387a41a00000000000000000000000000000000043c09eea638e524661c60ae3704fd1c18c46443ae134a0ab7b9a98cd398377febd9026c28b3e1e50de98766aaf0083600000000000000000000000000000000105918aa1476cf52f91b9ddb7c23ac18af3bd5269dbafc369713687010720affed6b12af9414cecd521cf0c7f5416c350000000000000000000000000000000019ab4a3eca904a15782f560bbbc8819dc09275f1f6d7c3b8e98aa0a96ec33dcb528284636b0f42ad0d503489d17161ff000000000000000000000000000000000a2abada18e79c548d5829991a65491ebcfe0e1a2c89a1e05f06a0ecd197797c5ffea0ae90b61f54c6b3fc844e0eb3ddaa76094782d0c06f2080d699b81aa04a60891046e0053d2fa757c7029df8f848000000000000000000000000000000000d457cb2c77acc8ba4b19ade0c724a2b6b0966ecfbbec8cbea745439b9bb7f3dde2febf9fcd6c5e6139fd7175e57b1720000000000000000000000000000000003154466283addb0d0b5d86a9633f8300960cbe8bf6a1405a3a040472542e9da63fd4f79a43d641a47c2b69a31298d3c0000000000000000000000000000000006599794823797f8ccea9daf0459b9d26e0d207f5fb95383c6b61eba38516b272e8ae6ddff2a9fa791e69c0eb25f3e470000000000000000000000000000000018be316bbe0416ad7deced1486d4e31490f5dc7e379c17542b7d3e9dc77bbae9c992e657c884db320cd51c2141a4abd2049a751a406657dacceb3721461417571a0104e11c1e00805becf71ee77eadf10000000000000000000000000000000007ba1ec5293d169b88ca4d2d92eacd51f0b8cffdb403632ea8ffdebc37f3997baf736771231335d12717cb45b51be31a0000000000000000000000000000000013505cc24222fb2ba9e25f5f3497653462f5b10bdd0dc88f9b16d5643a99ddd4a7749dfa6b566f41cd2da7c2b1ae93d2000000000000000000000000000000001465fdced698ca76d5faaa7e4faf1260cd5c4fd2939b16d3593e3588c92de3d003540ec989be9632fdba4ecae889ef180000000000000000000000000000000013a20cecd5e8f161ac70e40b8e9ca4c23e2b267690a3abea941c293b03acbbe4fc68a1e7b6d35b79ac46f65edde73a3e0502d56084d1be7179fb735e233978a5a3c2756d780cc0ea6a8aa92b1d1f7c4f000000000000000000000000000000001936436783f02f3a5307bfc0bd8c0a00ed8013508a440d040ed4f45b37a4e89986102964a328e93fabde6d9dc7ca424900000000000000000000000000000000000f16408b869303181b4b4877b554353b26a7b4750b711f3c41cc4b6682b2113cc772cf9bfcd0cf60e59ef29a5d0814000000000000000000000000000000000d5880e2ef94663ead736687ee725f7ce98fdc594230c1ac9e8345d39754bd616e261076aa5362776a6026129bff105c0000000000000000000000000000000006865ce3cdb5081e86535beb990d95ec3d75f67c7e881306607e4876c42714d627f8d548849aece4382d1c8f2b693bdc9787a6720b8db1b4f0e1d535833ed20b519a0e4d2e9fef75022aafef523713750000000000000000000000000000000016d941b6a0dc023fa2699c836b74e16c31b4cd51538f73fbb271d163519d4de1cb0f6ec2f8efde22c74ffb532c576b16000000000000000000000000000000000d10a7bfe9541a7b22d455f1b68cfe2422a83a070d93476aa0844670f02aecb36e9f41b9d66e8e9d0d67c0ba85c99f44000000000000000000000000000000000d7873f96d45fa8c9ba9cb4913a7b01c8e38876b6bb2a05506d23df0491bcffb42983ef663db85bc3cf755f476291a79000000000000000000000000000000000c22fdb83f9991c85b3577d1ed5a171f28460d79dbc6167b0c30b200235c512f999066eb1fa449115aab55128f8f2dde10b47b662e8cc8dd005bdc81dc6d98d0eb98f86b46c0c8f24481af9120e84a820000000000000000000000000000000010faf9cb9d0fcb487c9e86a2d2123105baa8691d82ebae8f5bb7d5ae7b7d8154837120eea86dfcd35ea5482a7ebf7f8a0000000000000000000000000000000014e40640eb6e8e38651a2eac05165f6cf5e0178b3711f34828766ff9db951e1348f0cdc652a78840dc24ada8b1c835c600000000000000000000000000000000129db7482ec62873591018a8399a8c5e4bf00e8bd9dd78dfa3d0b4cd1d93ce5ec7531e56d58b7a1cb3e58f062f6895ee000000000000000000000000000000000d8db3b54b6e71497faed107b31f5e44f328780cf01c62cb5ca00f99f10385ebb22a367cc89505640d1106a9ceec98c4072460e3c5349c8fec9944dc99762625262e84c70f10d0a92077a351335127470000000000000000000000000000000011ae9bc3ce04df2add17e57f260a72f88f19a1e44b0b074cccb7fd547035038d19e5f2228db46843343a69823decda370000000000000000000000000000000015ea64b6147ef76212bb5223d6d5ab9ca866799365683720866d8ce1117f60bd552a8e9981c095894258ca3c1bb5150500000000000000000000000000000000173bd5cb455b80b78951b15180fa7f8fb4725c1a12e5c53df1b9b31b45a29083e66c7116741d9aa93448c81b5e6014610000000000000000000000000000000007eba059855ab058c2066c643ef5268c864d09ec9962537d65a1686322c374eb5ab8eba4c4260ad0919dc18b4289a694f3177c4d865caebf1ef6565bc85e0b0bd51365a6f321e26b97cce887bc3f44d6000000000000000000000000000000001598471460ae082c2e2568602c99923193c913b9e803cbb7a4503ceff369e8c4bb3a19ad245c08192e12a2e9b3e75c4e0000000000000000000000000000000013b289bec9d97c529382388f7037749c10a64f915746d23d8f37e15db9dcb173b3a6d00bf45e67b8c70959472148321d00000000000000000000000000000000094a99f9b031a51b7d54f7b8865621b204c85d23fd66fe8ce007f0b852f8b5b895010745b2fc469abb670e38fbc41e50000000000000000000000000000000000e36daddab2134f65696ede36c50f90f9a1c56165e09243cd56fd3d9902d3c78cd85e7028f6dd466f6a8655da62ecefd393654ef7ad8687c8878c55a8240ae9df04805d3e2f194e960d5e498ae3ca17700000000000000000000000000000000050a818ce247367e8b57673d205d6bff8c650bcab7bf794dd32494669eff865fd4e05d7b4d35eb579eb475a3a0320ff80000000000000000000000000000000017ae5d612bdd46e1351dd1367c08c16ceb002a29832eba75e48d4c82e364f17c58525ee653a0940955b874da6a5bcfcf000000000000000000000000000000000eb2075367b42a0b3dfa30799ce1ab327eb583316d15b8cae21b716e6c7fd8cab96c67bc39e353f5e842e74995356c070000000000000000000000000000000018ca4b533da1baab37f05afc3ae0afe976e4f4530401d2f97176f5c73de3eaa75b8a34e8c6c0543ca0a08aeed28e478bdb9f942124a381b150f00a59e4579d0a2b7b728f62715633288fd03d01dd12dd000000000000000000000000000000000b3f4bfec920018663bb39c5520491da5c538f82138f03390c768e088bbb2880287196af937f1f70e215edd49d1872ea000000000000000000000000000000000037e7607a60cf235d8e4ecbe69d378dc02f0a8e40b7f23745e15a73fdcfc971cc8707d55a8c5b91d9a5f42c2f49c455000000000000000000000000000000000467df75c2703ccff1a01fa5bdebde210b61b5f3fa33e76e55be5dc953f4758c3a2c499cbd42b256ff5a2005949d9bbf00000000000000000000000000000000010d574c69050ce9e909dc23a76e9a2106870e8d8ce2a0e30d42cbfeea56ce3167535a9af1d453d4d8e6a450eff870638e6eb65778a328cf899f66581ac7a4a89e0e824c15573bc68c02cdaad89cdf24000000000000000000000000000000000907fb825f247c85d93fca36dcede9c22a409fa82fcf540593e8247c17875a1385fe009f0ff43853c404f6c96e2809ce0000000000000000000000000000000012bff10bd4162207870f6363342f2541804adc6a4e3f7b8be51d361be34def7a85fb39357c85a4e8df670fe39233bed00000000000000000000000000000000014f7e61ccd52bbf6d050c9d506751e03c8771b320872179a9f0161ac5736edc13bc133bda6239abba1ae09bd6c16f0c3000000000000000000000000000000000ca78624563584f8929d72668da70218a2da12b42c4b894108e6b103201372554fdd6b3bbbf2d94a9d0cf4053eb07d460940e3620c59504062e4e98b5d4c8cbccdb017c47a094d06253743c29465731c", "Expected": "000000000000000000000000000000000de8e87899b294575392d523ff6e153a7c2038302ac74574bfae7fb222558f2b4c9556be1bc2757b83ebc180ae710187000000000000000000000000000000001881c7688debe3ff795788c90397c3fe3d6d9f56da9221778d7b12f5a54d8c0a00e1a8d4bb9c0b1d578dff862516b5dc0000000000000000000000000000000014cdfdffbb956a20d8521ccdb214adab14975d22ffbac107b2c15f42e97bb823c6a3945a5b299d3226e2044e64f8d1ed000000000000000000000000000000000eb769b301cb7c0c976623badda4db8ccb18dc7322472b5fdb969393d5d82b3ce94bfa59dae06ece424bfcb88e24207a", "Name": "matter_g2_multiexp_60", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000164227fbb787b2d47ceea93faf1cf7890f48107ffae3628192235aa57658d9a2861db13fec0e58c347571c2ab0cd11ea0000000000000000000000000000000015478417b6758826b1d6fe0c562d43451e289dd50de31ef365ec70faf961ebb65b510c4788b6c7da2dda9cf56d3c8a74000000000000000000000000000000000f9e50d802ca8cbf80caec6489fbb24a2761db1245d9f7e820e6747bdd0855902ff211c427c00157ed9b1bffdf39eea900000000000000000000000000000000128f69ef5dbea5f80dbb9558a25f133b9ad77492250e0654f8fa5b55266f2fd26826a5c373afcd74990ebf768d6d8fd20f2f697ef6783390724e04b81d0e18dde6533eea9f72c1e10bc72c7b954659660000000000000000000000000000000005f7cfb31492dacae51caf4036d99d917fa13b0d2353bbce4e6547ea744b3a49b162deac2f107149ebc2f79e74828f720000000000000000000000000000000015ed4627efa9b318cbb52f518b734327f5d1cfbb097adc6184c5034620504181a298ac7e52759586dae2e107f121a9b600000000000000000000000000000000023e832638849599d9d7854d3ae18648e67e8938ebf606a7c86c3a7ea21cab8d4dd5d9cda5c482e05d351ea3ccd854710000000000000000000000000000000001849665396bc36d0301f4c9adbce81fd2f2d0c7f89925487d91a25c6bd0730ce31678694a319666cf42162608ef15a834680b934e67bd7518f0d6a3a809dc7faf845eb71d0247291d61053d5cbe0ba20000000000000000000000000000000012c9b607e29e35f260f3c4617b4217d5dbc6953eaeffaaa903710195e080d593972e7794897eb176aae3539401a483b10000000000000000000000000000000019cdae8d1d9035d1fc4b4db09e7da3c20d3b8777523155d407cc6565a71a6c951eca609d328ddbb165c2b5a3e6b081da0000000000000000000000000000000009c4629b67c1c50e5fcf316136bc645e9e62ffadac8495c084f97e32b0a3990b3b1019261f78de576ff7ffc89e36e2af00000000000000000000000000000000070a49e8892c5b523f5914e2341dde63127b694eef556de6dcff603da109a53b342363d9a854dda3d2833e25afd5b57eefc024dbceb522c02b88810ada9a814bfd085fb63d570663a64bc0658e5ad0220000000000000000000000000000000018d3c9259f70312c803dd6bac6488541f92482f7eb61ead71fa42bd5e2cca9338218d62835051bd308799beeed3b422b0000000000000000000000000000000005e0da6859601b6ada82b1826a455a846f8b4e54d9f22c3c639835a8a89e17ea2d76e2f49fb151f519de3e9adb78f0590000000000000000000000000000000010113d2fdc1e8ce0027b651cee6f9f6832b531d843db3ef7bf209aa00018715c1c42c68a82c53247a267929ea3c9363f000000000000000000000000000000000e7d1152af6448aca78aa7983013395f0dfc298848d86def6f017780e9cb144bbb21540a14a4d47b61d7a9b8c62376fc2c136f00c97a515076f6a0b63faf7e378f2cf04f8a90ac942fd70e25e683cbe70000000000000000000000000000000014125c81d4d7a8ea18004d798311f0d80c41c8e3a08366f686145e867192bbb13244f9f77217559cae72a150faba12a6000000000000000000000000000000000fdcaaf79c0607ebe9c8ca309d29d32284f3567a18dbbd23da9d96bad7269395ec2445d153711df4c883e8e7f7b02ab2000000000000000000000000000000000d34dd6636ef18b14f011fbeb62d33ec4358166f96f38a54c36b8797b51c1bedafa43d9f51fa4afcc2acc0cdd991997f00000000000000000000000000000000017337fab49d545caba55b763c23ce9bb3d3cc475f5ca37a15322e94c37825fc800cc7ee67bdcac66f9b5c22b03bf6558b033f2270ad2416d03dedd4bafb78ddc598810768fafd349a42438923ddfc930000000000000000000000000000000013434d32deb96edafc9a0e855281970b7c748c92b3472b34cc758dc3c17c4e6fdcf3190c910fa54a0259ef8bec75a3b300000000000000000000000000000000137df92ec14dd2fc02c0ec15a4e63547492154b4d4809e25f3ebbf24fe84255babfd6949770ba61637cc67e8ff299a2b0000000000000000000000000000000012fb20ef106e8cf3c79173e15dcdddb216c25a4de6797e411fd11d5632aef1304b36f8135c915c8c38caa2d778788f060000000000000000000000000000000014ef5cbe5711a815b9ff845e9201745f4117149b54ea3c6d1606060a192d513aa8ffe73425e37a42537773796b6fac8f202d0d506bbcd56c92bfc6fbab36bc96716de1af02aa166e7db2e2a0a4c19cd7000000000000000000000000000000000b1581a5def94e95e565bfd402cb84f2f21c181639c047d8f91044da84bb7854f5cb4eb3a6cdeb66569d99410ca3ec6c000000000000000000000000000000000d8029828f4ca245cafa7f396c25592ef08f6768e1a5b806450be6ca5b548cfb212d8c4787c3f15fe922f466dbe518c0000000000000000000000000000000000f51e01a044b6da437e3850349476437e4ff8b94fa190387099b17e6462040918cb2eba3b10d6044ff2123242005bd6f000000000000000000000000000000000991201229a856f88348381e1f2e282f0487e7daf1e5a4ac3854e66fa3d1303e3c20eb9eca605859e7d46dcfdd7615cc8329762dde1c4c91043a740a8b9639e83e809f749fc8c4853966cb2ea520620a00000000000000000000000000000000011f1bff5df413ade311b0bc3b46c4ecb11e386b886b71226987f14bc1a3a4b986412c2bfe8a4618ad5d70afacf4a3b4000000000000000000000000000000001972f49fa8b36d11d9c9d4ed6197261506b892ce6dfa932b87e686cb197560dfb8718aa413c38ee1bb771a5618c17224000000000000000000000000000000000e563bd240f5e18b518a792750c00aa5dfbea1f79b80a71369238ef15df9885d341d6901fb9168a2e74249f036e9a688000000000000000000000000000000000670e59ebf6e30b458ea505075840ed5348563efd536c31003d8d0bafdacfec7ba1ed401c616a3bab431a0fa71bb6188ea46572fdb37fe282203172c147715bf0a16e02a62bc79f33cbfe36703c95a7300000000000000000000000000000000071319574a93739586eda876ffd3be5d982e6fa04f5667873dfabfab83ddf603513394e0dbb9f418e725b02d2dc7b876000000000000000000000000000000000c6a8e0261da2ab499bf9a639a6e261e8c479f3f2b2d12992b41a3267e034c25373d4da4645626e6343e867466bf3626000000000000000000000000000000000045a0312dd5fccdd19edb65e24d5ba50e44689a9748ed9ec208320bd9eddf8d606b9340cd34ebf983e69a65c242fed900000000000000000000000000000000090b3dbebc7dd49e9f764e99c43b5915b67bdebd00d22c80e36e08873e5c5186bcd082dbce94f4f230b237d60cab7107b9e49472b9b74cefe5a951febe595b0020c43fd54150445fcdc4292c5ffe65f60000000000000000000000000000000007b04063dc315025b8545cef11be6b601fb4ae02597d75979b4946f3872764ffdbfd309f5ab3b36fe47b810f8320c1b40000000000000000000000000000000009361927d02192433a8d3c3d7871d76c6d88361774913067d16b68625aaa60f5a4ca19b6fd4140a5a11f92dec57d783e0000000000000000000000000000000012501f19b73fc6ddb4d194895e5cc2b89ca84defb7ae94f3170f25417965102fc195f38dfb7a2d88aa4b24e4a2fcaa4300000000000000000000000000000000141d0a0be60c32247f6cb0e0114251ac68c90fd43651d58c3108c728601ad6efc27c27a331a2f086d55aed54b3585fd1b6bfa1ec877010aeab030b96e80d2e27b45a93c6a99e2aeb3ccef22527c6e47200000000000000000000000000000000043f74a82ebfbbcf4abf3fd02eaa4483108a3446c9cf041bc67f5078d1774308ddcb3f918d7999d1e2c0876177cab6790000000000000000000000000000000000da7d4fa72dabb314ad8f68b61fcfa38627d1d7719bc07767f596671c58cca16e005d36e42413d03da3c643eb46b1eb0000000000000000000000000000000019f3f8f1a4008f9db1b604373d3566ae7c14a9147f80597a31839b83f0f8dcdfd829f7fa933fef3499b671867c3121fc0000000000000000000000000000000018bba4bfcf7629fcfa47935e36462cef4fa3751c7affa2ee2cb2fe3e3532d46ca1d247393ea190fb3f48077270d6a8b22810705458845232e851b33fdbcaab01966b8ed53b455873a966c1d6b89363890000000000000000000000000000000005a1e0e3a023f67aa7ab0109814f130a05c8c739036b98c70c8a8ddc1828d2cc4e2fcd16de4ef038a7373d15c78e81f10000000000000000000000000000000019e2bb467409b3dfae0b06244b4140de7f75cb105ab897d1ffb999c6b53bf3b60a3d11354815621c5d9f07962a237ffe0000000000000000000000000000000012e745499d5ed626b4762b57923bbfae7f1209408e7ecb8813a545c4ece0ec7c48a4015e0e264b47fa08fa82c39d3a110000000000000000000000000000000008acfd3c2a2e17be41a70ebbd1ca2cff2eda8a359e0969a389ab0a6fa51db5601b386dd035b26232be08d704a02033a7175fa4954e56dabfd1808f93d2686e0b4fd285bcb78b80d15e10e63ea8c7b646000000000000000000000000000000000fb464af51161f9c2758acc09d16754d4d8ac52a37baf2fb6ccd3bca3058bd3cd204de6c8a0bfcce8822f16ecfcd0601000000000000000000000000000000001819075eaa6d9e3f0568ecc2e507370f938a65169cea1ecc40c9cb4d02c83d7964254602e3d041ba0f93c24369fdf3940000000000000000000000000000000016c179832739a8129d2ef184f4d1231d24bc8d4093670a63d73771983152ec322b6a8c954565d61c2af76c4f6ef5e8a2000000000000000000000000000000000f6623578a4fa45614f4b74768adf65a753a35dacc84af005fa4d7328d733a09f12f709a7bb7f89060f60d4fac85780ae7dda7e5373d0e0afc3da1507416f47ea8b467a5b6c2fbde484aec8777ab7559000000000000000000000000000000000189724a2a0723e7727d224ced126e4288f4743f6855b035722f2aa36cf2f0a6fc23f6835c25222b670c15248884451b0000000000000000000000000000000009a57d85140f31ca58e38b4a99c4ef103f0a4af0d5546d416134fa8adce6ecca6588c3c56ba06b2f59015acc1a081099000000000000000000000000000000000dfc67b7644851c3e928ea33aaa0f745a18983edb7488b148736e81ec0c62345c11e3f0dfce729d893dce27ea249860e000000000000000000000000000000001712009a81e06a85a225a46fac056b139c8da05e6b72074ee4079316e490a06f51c62241e380909b86239d867d631be16aa731f9393d2bb32adf04f19884dd1a5e7aa36e46408b847222a153da95aea5000000000000000000000000000000000976746ae4d9325d5e8300b57ce99650f28055b5e020700ee5f124fa76ef3bdb9923101c3a1f46b6985b8203b4e8c60600000000000000000000000000000000057310c3b6cff6c849938f533b401b0cbe10b6ff3736c79a968009b2c0b90708b6b9a98b8e594cce09c579a64ead846d000000000000000000000000000000000d39511e47f33e310332178b8a0210e76e4d4c7408ff5c2374f5e7bde8335525e03897cb3e2bdfe59bb76b21cc6411df0000000000000000000000000000000010c46a621b7fb2e7ceab8943b3371475d3d6f132fb658b8c6bf299888711f1b344ebd4a5793ffe6a7a7eec8c66c80303985f367919b0f3c667b1c1cacedeb0be1f9cb175c899992ef55f14e9b7aa6ad10000000000000000000000000000000011ffff38891ee56cb1fc062d02f6c9993100f991a556445b5ee1b1b0d56d8e64bc6eea4d7f69a6b6dc55ce7d8b4ba300000000000000000000000000000000000d6cdd95d1ab2a11ab424d7aa596cc7e5de025c57217da0da143887d7dccd6fda0addae7c2fd9e0996bdd0d23128e807000000000000000000000000000000000499b3e69214fdb4db7dbecd619ef9c6b5c8343c808e4953f593cc89adba02b5cbc56a5e7a3046c6023c5cf305e54e85000000000000000000000000000000000d267e21606c16479065e47da8e3c058cb59f55a1316a87117a73dbb067ec26f406eba6a40b30ecb00f506bfd3c32f4da3041cc52c6f1bf62dee4c61b1c5e35b72ebff7e8e89b05353388b551eb10010", "Expected": "000000000000000000000000000000000650fe9f3cb3620e0bf1654a7f1dee503b79fe2218739bad608dba9f1e5330f325b4fb7c340f118eb10dd0776fbfe63c000000000000000000000000000000000bcbf1c6a684dea5ad6c1a540b3525cbc64c7c431f37213bc8b08c8d8915a331c07bc899d3a2ea72a9a4bb2c539cf56b0000000000000000000000000000000008fca1c364333f558c7284afa1be486e84bb035b049a2108b0df99395149de83549de153a784e4df2b0134317c85292b0000000000000000000000000000000002784cc1d11667bbd0759bca35a16a1baf49a21765c6c2c3bcdd4fc9697ef20f1274be5caa0f820d37e843bc38c68957", "Name": "matter_g2_multiexp_61", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000051646993c3aba532988d7baa07eaabeb8366853436b8b19c0fe3e14ed45fdc65448d749adf745291ab5ee62d4e824880000000000000000000000000000000002cec01290d8e51ccf751183dcad20bac20b8231804a2b6f87f886aacb61d31b14f2335629e97af0ae0546a17a4cca49000000000000000000000000000000000762afa7b94ed580fd07d5141a8e1299c6ec439bbfc6c1a4d695d9aba4ab5d6dec93dc4de47096d72e5ad87d879eea190000000000000000000000000000000014769208ce8a9682c8e0340f68a0290a7782c2b04e3c13027f0b23966eada2ffb2156f6e20539738535fa0ef097f78d6709a2e80dd96eb12edc481e3d58893bd0d789a499d5289072d58c2ea80b036cb000000000000000000000000000000000acc4e3ccc3574285c19d2545839d1da9db6770b078aa399262b7c91a7c41fb4c83fe7dd0aad19f4e3eb2b56273f664f0000000000000000000000000000000017851c99881677b89956fcdf1b8c5ca5dd0997d810f3fb89f7378dbf7964926cfde315f8722531d6d715b4932179eeb40000000000000000000000000000000005e374a4c7118a76e59cdaadebb1c4e635b4dd18665010249f3bc78d559455d27d547856573e264c98ba39f6f3abea69000000000000000000000000000000000a532979cfd5263c774f629027f7624799dd0f9d6a77f675d790a85fccccad6e93c00ff2e5536b8e9a92443af14611e69ff35bc510c86a9e72c3e9c6b49d2abca546f7a62330156ec09c6fe6847a400e00000000000000000000000000000000056f109801b7a4a36fcadbee7219c06ac74e4a3f7b81616076c33ba2a71d7ca0776b596fb25d29992fa26d416272a4b4000000000000000000000000000000000c02d7e6ec50b778a7ff36fbe5751ba32beb1c2024b17bd99b46239e6dd5a708d2fc689e8e8924902e0d80287cdbd6e90000000000000000000000000000000016f18df97f48aba4d1b64e71eb894904d02ee7f6ba425e58f38a08542319e2498cb0dada8dbbb81bb398c9c924ae44270000000000000000000000000000000017dce98b335f536909ce01647aaabb918942ba2468d9a07c5516cfd347e1baa02029d39de1b2602932630e4819f2f00f391dd27628d0808d4a0773509737597230d7849418540e1fe4498fd70d39d16c00000000000000000000000000000000005b23d6f76b8bd4f334e91771383856794d1dc65b365fbc0c94f21fff049761d7379f0d512c42ce13f878e0661712d100000000000000000000000000000000009dcf70c16f524ff540f132b35074cec6ed7dcc1f319432a0dd09b3ded0778ec9ad0f05d67ecf3ebb7947951fc4b25d000000000000000000000000000000001075fb15240d532a9543dc59cb0098cbd03da77c3bf85a0ef8be1560958f8ab57d3777fab5836ba98d67c721a4a8cd460000000000000000000000000000000003511525fcf6fe224eb87b13999d2548b6b8bb8069fd354f298a025b04a33f48be72d8e82a99b9aa34ce5ccdc1f1a59c94f11b10e4c45f15d811e3db4b947ee6414e262965d7b5c23a731b019e63d5130000000000000000000000000000000019039c69d52a66330d2d8572a1308bd88159f0383c041ee7605d0aa86f1d0fe3e884d0a2ad9c72405149b5fd204ec3db000000000000000000000000000000000942163eca08672af3827dbd876b9c1adeefcd5ae74a2768fb55f1e8b342aefbf76bc6546853a2b33e26fa866e60a4e9000000000000000000000000000000000c60c6bd103ba5bb5323b5107373cd8d706038bf5ec2b367a43bab72411523bea35985b974c756184c346626ab2622d30000000000000000000000000000000016c4a2fc8a9b3c54f65cd150c80a3bf70ae8dbacdcd37128514b4a881239023e427f0b0c8984ce219207c458bb380da970f7a0ee05cfc3f63d46a3151c20da53604628bac70d7b521b3be65d7b2abedf0000000000000000000000000000000003e3df9a8ce220be05f15904a3321a6805ab68bbd539479be56b2a870c3d61234e9cda8190bdc89f48e7f0dd9374e1d800000000000000000000000000000000040446db3ec43e3e67dce62efd741a4157e8ea2597a143f7d6273b66c7045daf31f72397b4b9d374328520893157c1f1000000000000000000000000000000000c3a7dde5b02df5f7c1e750a9ee5314a580cc6ed53d326a9157b507ebd6c2da314c37a7f1837f7fcff7e8754ab603b7b0000000000000000000000000000000005e617ca4eced853f8f2e9fdefef810c97eb27d5c8bd06c5b4ea50c03761c01e8adddfe27d2d72eed8cb25ea7514a4aabd991eb5e8ac8ad7cbf8fe64a5889b715a2409305f2366b278adcd2144d7be8c00000000000000000000000000000000104ccaee210aa8196010a6478702a54cb7ba49c80a98ecbf5c0920408ff8b4a7568212bfbf3561b6a7790520bb73bd42000000000000000000000000000000000870ddd51dcc76c8a97ac4b4f23819df48dc8a8798df0450d7a45d273f830c908541dcaab7b066bcd668b289c846ea000000000000000000000000000000000012fdae32b020a346ad5edc3bab360fb5ba55004ef3dfe5f437e841b5dd7284ddb3880051956c8068e49a3fd165143ac50000000000000000000000000000000019081bf768dae314fbecec408d687df5b6ecb32ec24b41f9febd583c05693f80345e6b9d81322ddc72616c1cc39a86811a9caeccc2a2058c2f5a271c09036d73320f9bcb31b7296a796ef94ca4599757000000000000000000000000000000001316b5ce5bcc168d76d2c862230ce604d02cd3d242c51c250bc6b6fe5c380c9e83fe7041049f2272481ab38f44648f4700000000000000000000000000000000079acfc2b9629da9c9f3394874e64aa00527de21e726f02db180f86cc0b9a97138c2c567832e287635721ca40469e00c000000000000000000000000000000000e11807dcd4ac69fdcea71e3e6a93dafc27afedf12c2998dbbb2e4f33e37ea736df73af791eae69bff84f3bb212bab47000000000000000000000000000000000e834a34fb63d9df68d683a26d79ecf8ff67066586e5f760d4468ad196c66d4ebf8605ebfbb7bde201f47b35cfde3a5d8ed4eec02c2af286ae19ad5f05642587cb9ad93196756d269c783a11f23393bd000000000000000000000000000000000990f115519d2125d47b925b613edc3303110e9040fa705211e0d772edb2e0f7f88ce521d1738a5f65c9d158e9d360c2000000000000000000000000000000000bb951a16decf9be8381d0c88726b53d90bb32cd8aeff962d48e43863e4eab1839bd80d7434c7eb808bbc0e32e92a4290000000000000000000000000000000013dbd5bdb7caaecc42ffd81f14be0ff3d8fa228ff121ed4f2f3ad5961fbce617d7cbc8133fd49e03caa62f7d1567541b00000000000000000000000000000000195fd9b85e19d0e3e1c93bab0380cad6f6f3bdbdcbf5c6ec32b7de7972421d0065cf0b265f6250c02eada67e95284bce26f20eee9bd019f9e0f5c794e22e770128737198b5f5dbaf5b7d18040443a0bc0000000000000000000000000000000009ca977266277bdeb985750df47353a6b81c5f0c473eb3369d25a01df67610bebf66a6de5727a465131404025e90441a00000000000000000000000000000000054410a13287ecf4aa18f543916fcd65b15cd5d54617433217b0a2b91a79fea764b511b3b270de3e8985e8f6a2fd8c380000000000000000000000000000000009a9802a03a7c9fb63c1eb13972cd42ea2df614a0972b914c4015c2e8630af319d12fc8108b4c88db9508a9a77d9e57d00000000000000000000000000000000094d83483bca296b20b7bee124f538ae9c659a84541f5c9d9fd22e98251d2b48051ac55ebe07bcc9d2e9109f526d60a6c470a66cd3428a44a7d095ef410126257175597a333cd36ce6c9822d1ee9bb380000000000000000000000000000000003f2d93ddb6d5983fd5521c1d1726addf662af0945aee54788855037f47a013d2fe595231792a05e1259c5e5a8c553a900000000000000000000000000000000004f4f4e7df5dee975fb440b5a217c27d9d1eb83a5ae280a2b147896f6bb864abe04459c17ef56d784d3c4a0b7ad3f3900000000000000000000000000000000069da36057aaa89cda458af4ee27fd9ec969c8f7612cbb153da0e010d67bfdddadb2941cfbdba8c43019a9f1aaf9c296000000000000000000000000000000001545b8325a80176ea148a3d9301debd7046f33a1b419b4ed01916a3d0a072037fd617d96e0bad32b208983ac3be7dda4e53fa8fb708204e619c221b8ecee14fdbcb1f94731ac2c858787ab33906c9269000000000000000000000000000000001536a81b203df2640bbe7e695b5fde186021d21685f24c25966cf11dde554d49bcefca64f16697509a9ca86e58b75eff0000000000000000000000000000000014348a2bd4907cf081f2f7bc944a98d3fac671abde029995377df190f7f60319b8de1698b99be39c821328e32a449c760000000000000000000000000000000000e18d4da3823addb2a6cef8336c83f99f390e23d7129365d57035d4363aac7e9c4da9f8000f086f7d2206666f990dac000000000000000000000000000000000d6ba54e2af9afa57ff4536a35e9b61c8d8fb3d431b653a0c66a2a4b8f11d9b5c45389f894d64485233d4183895921f3abf8de43c54ed59b936e1d55032eab5c9d9e04e83e4696d969c24167b4239f62000000000000000000000000000000000d88d5719e07e2332c54ba41f330c7763d2b2b7c4140d19b8b0972fae6ef902415de5f2abcc2342fce24d3ed8ffe156300000000000000000000000000000000163aa2c768eca58194fb76822deffc37cefe04ceb70aba38a51f507be7cd64c0755abdc2e49e7db234cd5d68575c2d7a000000000000000000000000000000000e443d9953468b8cea4eca4f5968e214888e2b95bc20ece39483ac551d4e180c0b0a41c4668c8ddaf761a0ac03fbcad3000000000000000000000000000000000691930530ce86a1354d73cb21ee32d968e6d89b12e5a09a7991c7d27dec302348af7f49c3e0de91e1a1838aa11651e795f59041329b6c3e6aef01d3410836852f79cc436fcf23199e0985c56f65c4f0000000000000000000000000000000000d7c6f9d4aa794f34596bb9af4d62363462d9804898ebd7c7db7544be1f46b4bde488ec59004adaa0cbe40aef525ce3f000000000000000000000000000000001094629b1428c4c284b7a64d0623e10ca0c4d395bccbfaad89d1a737a3887c10b714541f2681c33e674c3b99a36b7a450000000000000000000000000000000000d6812fad9c5ea365a64ebd3150238349d88b76d041ccaa7e637fdfa6c715d9d6dc3d3315cb95fd6919fe419d028783000000000000000000000000000000000eee5cb772ce02fe2a4883008f17570aebb902ad7c40b4024a5b24ff75b3aaa2b54ace6fb4601b1c62837a20204194dd740e4a207ab5dd4a0621fd65697f5d30b8ee1440a5f5c5e74a0dbc6b6391c1b0000000000000000000000000000000001026d21e075fb8921dd849c98252a565d39ca9f5a62a825e7e3e77ab5be6620e76e45047e51350c48d9a4cf98a1222a9000000000000000000000000000000000f6459a8287bb2da77404a515dd7a35f46a4aa49ef72cd2cdefbc5e5242872df5f7b7aeae6848d59afa1dd142ae7caca0000000000000000000000000000000011e3545151d4e0b034b950cd2f1a3fc2d29e9d53250ade2482b7ea6075dacf7e8e777afa1e8e612b45028205235265970000000000000000000000000000000017a869d75144ece603c04d39cb56a487895cc882fec613f40f6a66601bdbbbb7748ec755553257d654d1558b1104a981f49a3f82d25c6e0d69207e6dff010d56f0d99b28fd986c5711878dcb6665b1f50000000000000000000000000000000011602a23c9b5cc091a700114e5d3557bd4857c4fc44cb8628ef327ddeeb728927347438f123e2011f9cfda9b6dfc42e4000000000000000000000000000000000c4fad264ca95827e9cbb9783e36cb0b683fcc33038d47bc7ab6b65998770325588e5b910e811cf7d61fce13c3378d6700000000000000000000000000000000009b4711aa67e84434cabc289a78fae48ea86641a162d48b79bbcbfd56237705dd2d1e9ba3a18d737eec29eb8e940e58000000000000000000000000000000001160fc9e2a488ad9385140bb62ab48ee613c2284208cf2f92912e1b973ff81a5d3de338d9aa6881cbe437907890258fc8390fa1b452f887ef3afc7129ad8ceb9a8397f7625c2b249d7442566814ae0a9", "Expected": "000000000000000000000000000000000cd0d8c746ecc8d92fcf2232793282d7e0e17e0ec27ee851487eb7788f590db3487296061075f36c24f67cd4c4bbf36f0000000000000000000000000000000010c5e1d05070c27f19c228813051c6a830254542eb71469664c842695b219670dba8ddff858e2d147019847866f01084000000000000000000000000000000001799ca7d8f2637da761622b793a3ed3317d50b902a1cabefdfc776b0d0ef88b707b8a5c36786d5ede3d8a381de4e069d00000000000000000000000000000000129881a3b56e0014bf1dac4775f509f309c33406f2cf22df9a0ccd15c87ea48a868d4437303923127bf580b8d6ed0a8f", "Name": "matter_g2_multiexp_62", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000d087c1b98f8c67c1bbc4389f21d9dab02faf46ee4223c609e7b9eb399132ae168bc12847c580f58edbb9255dca3b000000000000000000000000000000000065ded24bda39d2b830639fa511bce8dc770eb95e349d6874ce63b3355d23c1da3ee9771ad44e57c6c661b7453076fe7000000000000000000000000000000000fa3b2ef40a7c3d41f0c3a5f86afec252c6ce89bd1bf1f2192026e22fa256365360589c788753033658b1ba151797feb00000000000000000000000000000000105040ff4dc2bc435c2a82e1174e2ee0b94043d69074f01e8ed013da8c431f33c94a438a93b06774411780cdb72abbc8414ca9894bc15e6bca798544138689b2471f8171a5dc48eccfa36c83af142b7d00000000000000000000000000000000129c8c1db08ccd0dadd59b04df67a91fb6547d97ce23e59aa57cd3d38458e6baaa67285800809856e7e264d812e584390000000000000000000000000000000004a0be934248b4e142fc51745233b6d0ab2c46f53a8f9d4c84981e5eacff146ee6227de289c713e4ce24a4341572c9d70000000000000000000000000000000005916d14a8592af57a40418b10376e8e20f70929d2ba568c1fb70e343a1dfcf3e63c791cb639bec49c50aebd2f816fdf0000000000000000000000000000000018682c66a461a69b11d7c32f7aca07749e05a23fc46547bac121752aef64e9bb98a274d15a14faa93af8f284790acb9b99eac8ce85a1bc70c725a2f04aea3749d75d22c0df7c0755a5e76ab4d82ef9420000000000000000000000000000000001552053742eb89ae3d0b95be919c84e53919c898ada92d3eaf05605a19ac910091fc08a65e9764f3108877c837d478c00000000000000000000000000000000118e5d22f6df0e6bc7447177ce06659f94315478385372046b649fa6d39fefeeb492e6623e0160bc47233f4d3143e326000000000000000000000000000000000dd02c30cfdea5abd3550a9f28b546d82d5b3043f012de622d892062945847748ba820555fb811fb3382791ec43ce1f700000000000000000000000000000000050373898b396d9a641e2f2ed832c7619515fd9070852b891b4ce0b5bb5ea8b5e24248297d53e9db7cb946e76c4433fa49b25140d7967b0438e49f59a6b04b75bc8745b84d7350605be548c6b4b3aeee0000000000000000000000000000000006b465f4b9d60a3a14e119c54a7c35172bd648c86a7cf331e80ba849fc87b9dcd48410e3c9a07b634e83fc7dd71e5b9f000000000000000000000000000000000283ad9c77f549042f79c47b8a69e72164f0ee77aee50c20519d2b89029c63ea86dde2744cd21eb5d37e896c3abbdf56000000000000000000000000000000001668b08a87787928afe92d941240e503da07b646a34cf82ed09d4c2f4d479aa24358c8475eebd9bcfaa6bae17c430cfd00000000000000000000000000000000150e5b28bd901f7a2a9af44bfd6b78cc84900dc05e334de306f9a45f1e67708adddf4dcede8150a39670054f97a643436e30a51d55a1ac94089d0f3217c3a2182da6b02ce70ce7dd8e2d4e938bfefa9d00000000000000000000000000000000060d75764a92e30e80e7c1a6df1482585f4de901bbc36dd9d8978a76c12c739f85a9ba16741d0b19ed480fe2dc331e5b000000000000000000000000000000000024fd15c9e5b8872d2e9dae9ae96102bfb0e31d15e92a24316818862dd8ca7a6fef271d499fed5e0db6dfebc4c72e0200000000000000000000000000000000058cda551e1fcd701c6a3880b276a2f7536a26aa366a6425a1c42cf31eec678551f489a27f23ed5dbc76f19b0fbfae43000000000000000000000000000000001152e2cfdb584295563af8120c523a9f4c01cf72da64fcbe0a90a284d693a3089f299bc760166be062cf9f8efb6a951ad3da3db6492ff36102747d9d663bc6e9cf8f75b1cf77044989c7af3f11d66ae700000000000000000000000000000000116fc24e980b2e7ad6bf17bcd7c4f06e654bbf766ea0238a66d738bf3c2d41c8c63bd52f81553cca5fea91f5f9b74a2c0000000000000000000000000000000001078f19ecf785a5e0d3e764b7d6ea47b2d077b5eb222f4e6a9451f134ff0d77a0b9a3b53caf599705d131e3b17b6ca9000000000000000000000000000000000e44c07f00a1f198583a8ffca43da45d8e54e1f2a85bee7afff6c1c733b5d0b5712961c4b6d344869a8e4de3b34218e000000000000000000000000000000000083c78b3568cdf808b75d9ee2b03b98cd516bb16ca8cc35757f53f12119747bf6b5b0605bdffb2f079cbc69e99ee0bad6de8753f3df8be42b6d6ab578096426f852de4ff545d2e4ac12c3943b044b43800000000000000000000000000000000087ded6945bd6fae7a0aebb1ea68d3cd34588035531a6cb00fcf1b83e06f7ec21cd3486580165c1364027b43e238e34d00000000000000000000000000000000005a2fe8a9871273bb60cc7ebef44a361300a1033f3f0230a731f5723fca124ec9d305cfde45802482a45942154398cd00000000000000000000000000000000121eb94a41f9e133adf082ef651272c178d780a1c31ba8797f60a208ad36b4c703c9b6c08be845f8844dd14d6406734d000000000000000000000000000000000e5e3da7c91ab4cca1c9286020aab9795e64e667d55a5a700241f9589aa3519639f168d040a0027ac057f334a9f740aba28f7ef4b12c5097a15fa6394a4dcc3ceed6cf3c6240ec2ac949bc21a9f6447f00000000000000000000000000000000041f9117b426938acb40c905bbcba443c043bb55cf9b876edfa2ca051b6354124f0fa54d6a88ea172c3f5c10c6d921b3000000000000000000000000000000001828dc0b9533274db6afc802b2fadaacf57f28126094b6b9038ed5f6bbae0112c873fe5eed15bc49b970461abc2f5c3200000000000000000000000000000000107df6da02f106ae47718959aeba7b4fb4a8f0e2651560e2f2266a62566e13a5af86430b8800543f5eb6b1e96be79c69000000000000000000000000000000001628fd4a598813133de75cd7c96ff3711b6bc826806b96d07e5a89cd549592f0f51c84aa9ee0642cffae5630ca1ebae1a3d0eff3368b10d00566f35391bf43c9d204a4444b7eb91017f1b2d8a762d90c000000000000000000000000000000000e8fff44163cd9c2a4e148eef3cbbee19ab8f648da1a8d438be27d2b0bcab393fb7d49e096d9a7abed3d8f82c11c4e03000000000000000000000000000000001274335d8bde3d14924f8d7ba18fea82bbc85427892f18fb741c8ecc5f2d6d7bee74c68058164c55db3cb8da8597bfe40000000000000000000000000000000010c7fc728c094e47569f0e75446c399d20a1239b511e34d8d6193dd32df607dfaa4377a1825b3892a9f74ff4efa0d9df00000000000000000000000000000000067d904122a6581b5d5a60acfe8156dcb6c10ed083840e506487b5dd9117927663e0ad883fb91b4914778ae082de0a7eb90d76e660389e570bef756e9785e39b9748aecd7a34556bac8399aa5564d12d000000000000000000000000000000000a909706e3ce45c86f2c30de5e820c8c9eefef207e530fd504511827f5e6422714d3f4224afa6bbba22ffca533d647390000000000000000000000000000000013ff61472ddc0d70207692648087c283763ede668ae380b0b9d6ae6593498b0adc9d4e4fcc73b5cce250e7563f7577de000000000000000000000000000000000a81db69eca785373c4dcbafd8635b23a9f41265e91152f309fb2945622937e65b5c17656abf8aff042a1fd1e5e50341000000000000000000000000000000000c66269c3ccd9e91766d1a640789bde6de752d08ffe3b2955df8dad3d2a0b6cea9013af235cbfbccee8271a7242e310614f18dae096e4de75de3da284a5755efe51e912e180020a20adf1f5de43cb51800000000000000000000000000000000181f3f4a16696980bd0eb9bd10ff1084ffe90bcb65f12f505b25f0a26dc1d4e16987d486b2c0b117fd6f2e356b83a5250000000000000000000000000000000010d7be6788da3ec56c87acee68ea8a03e7d467f816060207bb163dfcf8a4e7721651bf2bb23d5bc390d50fb1ee6625a900000000000000000000000000000000196c1ac817493f51d9ca891b55fa65ad5192df83cdb63eb1a634ad54e2d627f7feaa68780418f5354e6cc09cdf2f6c5800000000000000000000000000000000190f36690b8d36f2e295b9625f23afef9d9babe87c1ba0303f60c6d44ec952ba6bf8356469cff9d952f8e26bdb86ca06e32d4645ce0172000fd74f30937261de89753caa716dd03a8b3269747f2349a1000000000000000000000000000000000f77df606f0611856c449c58393f4ee7a6225a5bee667382a48f59dfc747736a895d598f90ab26002dd0ed3a5a8f5a200000000000000000000000000000000012aa50d0ec440884fc6c2f7a0e8db8a5e79160f0c482209ae1a1aca2b9dfedfec6d6ea09252a373ea57905130220a4820000000000000000000000000000000004773f46165cdb19cae49cc42663316df39586c62be5b827535f138e1fca8dcf62ba42ab60ac6dcec85e8496f32b9eda0000000000000000000000000000000010c91923c2c7b3eb2cd9aaf0455c0eb035e38e5352d218b07ea23f50040ea58fd548b373c1bee9113d3d44fcb25f6ba08c8722e3e929ba21f1ed6c51fe5ad4940fb13d63e0293893135d0da5e6e0389300000000000000000000000000000000044b95fd5f0e049abfdc2adc699646afa5b0f64464779efacce85a5279477697090615933069992bf30036c6ac70dfe50000000000000000000000000000000002778e7dacc5566354c24ea1144613a5ce8a38eb56d53d230ca145ce83d5ed88596afe243df22cba10f423e64a7c103a0000000000000000000000000000000017e87cd2752d8674c373c557ab2b922e02620a070aacf6f5b3d3d07ca35d89ed2666da7246b800717c0e4763dc35f5f6000000000000000000000000000000000a3ed312e5f309eafaed486629d953970cb73f839bf30f506c2f393df4c283f299d6c643ae6c229430d919e8aeae8bd839bef6ccc893f6eed62e68f5f2a07812f2d3066b89653431e7e39e8596bc3652000000000000000000000000000000001082a0edac6267151c8ef11fac7614b74cf58b39b72fb71e4d66467ed4fb3264b177c691e569230f2a13a64b4a48c6fc000000000000000000000000000000000073a8d5f96ee580741bee1f82cacb6139d962fec34c44c648c8fcd0322796429bbaef083a11b4c8fa376d4c00cd79c00000000000000000000000000000000008d41e51dc2822e0f14b992511de799fe4db3783a05ddc1026a53faa89af000075ba5aa830ceb7551e51f0fff144c1360000000000000000000000000000000006bc4bf0bdf350af417160d06e8aebf2dde02c9b50be39b0c4dcb3a045f9e04f1f041f6de10328e287df6121247dd4e9c395ba8f2553e3eced8a42b221a710a5cd2a5ffe5834d3084dc260ae0f51698e000000000000000000000000000000000802e7b71127a15a279a629e89f194b51d19c4f329efd8ecf9fe69d340dd06068c8467da6ab39be25c194077d3ce2428000000000000000000000000000000000250172c787afe866b428748be8359d8e0bad161832abc108c850362c5839237483fb38678d77c94696260508907726a000000000000000000000000000000000d46223c1666f314f9a1e32a94f83d8150755d71252e19af91a3b460ab0ade2db2364d8c6217cb422095f0d9a1ed648a0000000000000000000000000000000002fc2849014717d1c07935efe601325e1842ed333897222f6de322dac8b50bf4d9859eed8880a34676af0d0e3277639053ef5568a766b6c39854ba059f3130b75d7fd870bfac2b00b626e2d71c4968e10000000000000000000000000000000004151d78d65b0c9eb26822e20d90ace8fac209a1f08f62ce722ae3effd7fcc476f4c0179e71b09fc181db96fb2ea4eec0000000000000000000000000000000013d17ef429483be98411947ca0771ce671fc38e27bd0aa4abcfd5ddf1af9e138404d86f4c2ed74702f80a573638d92f500000000000000000000000000000000178f2a7eb43b9f88acfa892b5868d7f7c5787a399c1c566de39ecedbfe88357fd5256ec57e1ba12e9784382c14331756000000000000000000000000000000000253a391373974beef746c4397654a30a68992fe9163f9518ff0ed9b7be37b858ac60c95259ab894bb6acfd123333b7fbadefc3880ca8dcff10b8b763f7d15f88965c2261b72ba879e3540a90c59effa", "Expected": "000000000000000000000000000000000710bfc39e92b0b9d15ee9bdb4959daa3a78f66aeae29eaeb50a0aa0460f3ff703c86eec8903011b4b61a0dea725ab08000000000000000000000000000000000856fe7a074d37786237cc14ff1bc53c735ee8133b231dd3fc63dfa0dbd1979304bcc7b55cd1bb66fd7529e15d15db5800000000000000000000000000000000014757f1fbfd4fa7935ebfe65e150519d6eb4f4831890df4b236dda98804b79862fb6699b587c3e568fd6de1e582409900000000000000000000000000000000000f7b54e4961dab9e94b1c4b897177dfa74be9937694a38207ddc9d6290dae1d5e122cfe4c8c31d853db3783999a7f0", "Name": "matter_g2_multiexp_63", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003bfd2535c6d8ffb44670bd02b5aa6f050f5cfae7266fc3225865bc3f34320820eaeaa952f80da51671f6d97b3df9d4f00000000000000000000000000000000026c1adc0ffc3fef9ccf018ff9a647ef5c69c5133fb4a6566cdcbd3180d9ee784f34d667edb1dd54ae292253b45576b4000000000000000000000000000000000ee90fb541becf96b4728f1859aee5ae74e30ba9193b90569b66b0e1d087eb81f30c21774298cb06e7dbee8f8aafb1930000000000000000000000000000000000a4361867bca952446f64c273735764e141eef43d156d6cbb6e68dbf3bc940e935f7bf3a77b57fca4bbc74bda2f26532c1a5abbddc02f453519563d6b6e05959d8de5feb493f7c58ea5e548cfec2df60000000000000000000000000000000004bdef85b0da28e0531734016e5953256c75c3620937736cf65de5f05b8beff294677668047a3b74f0f135b846a95bd6000000000000000000000000000000000b754df2aef855b4a0eb6f6aa03115ee8f38a31fc852381deef2b59bf23e2c885ae166030ccadd5673bacc35482f81e9000000000000000000000000000000000f1d760ac6dfb65b39c999211d4e4c3623c3fb8ea59cdcf926249a07285a8e4da1890327fed20ff07f12359f6d9035980000000000000000000000000000000009f2698239c8b452748126ffd83abec768edffb83dfa3dc7943fd499c8980e2d9aad76dc38b336a4a63eccf5c4150ce0b406eb0c097237556228f3a48b7e770c1707fd583b91b4b6b70f398b7dbb0d3c000000000000000000000000000000000cd724c51fd56528dfa688df46f71bbfc9144ff98958b559fca8fd05eda01c38c28630ee19579012b9913a393264cd90000000000000000000000000000000000aa1e55f2b6d9385ec6a9cbafcdbad157f7ebc06b2e30e2380ac54e71db5259cb919e17042d6ba6e045f1358aef276ea0000000000000000000000000000000010181ce9ffe235b6b271d570b3c2d6e1be60c53b4a98ef5e8d7d00b463e5bbc9d8d96dda881e58746090983d6f8edd35000000000000000000000000000000000333deb8b14f499319ad675f482fecd80f9a69ba369425decd441cd2ff5c3c77f11075f61bb1d90d0be850ff657d6b7cccc30cf1db4c6be6dbc5830ee37b5782c6dad215334163a9d9e4deb962186f80000000000000000000000000000000001581a5440fe892ee6eece5fc2227fe072dfbc440e0620a1e5fb505ff0b16d9e6033d83c83576b4b6ff87a807dc81b88400000000000000000000000000000000099b070a0d7497f33c1c478ac424d5564fa645d836a3d572d98782f08713d8e425b571433fee928475688db2b3a9a04c0000000000000000000000000000000011e1cbaa09a6361aff9e199e21bc52e98dfacc49ed83e732d4b4f2503b3bfdf85d029dead4412b6f3d7ea447e20d669b0000000000000000000000000000000005503e151d620e9a5a142e4f7940ed88375e7efc1109214141c191e9f38a32a40d3a92d6094584e763e0cf13cbb54bcc99461c0f12019b344a7f322900b64fe81e0d8a052c0ff5e977f58753b1b6edc60000000000000000000000000000000007c780f119bbccfd658f3f1b69ce9c56b1f5269bded713b6827d97d32b2a6deadcc02c410138d984d977527f3609cc2c00000000000000000000000000000000095aebacfa33928a916ca7b0ceac699c71620781b35cb2f3b254bdbd1544b728a2ec1fb35416ed7a8a3a630bc07ff8720000000000000000000000000000000012194abf7e411f4961b6f8a1e2ad052c27624ded863d7a9132d9c7ecd3b4074ef0060cd86adb73056323f4227ba5fa9e0000000000000000000000000000000002fde2be9ac1e8265f258a09eec85a70112ef1eadc3a91429c9206555933e2b89aaf7493fb833e33e5d61be28a12a1c2338ef9fa825e47b46483ed8fd2df64bc7b56da8aecbae704b7eff2e7d426f27d000000000000000000000000000000001586c65405e810e1d5b59304bb4555ca43c04a593671ec64d5ed2d2e626b1f8a89f48a4b21d38fb49909b8c614209a460000000000000000000000000000000014528cdf994e774b8fd54090cb45b68098c1ad9a351bc1f36a9393f3b4364f5beaf58fff6e5f8b21a85b67bc427c0e920000000000000000000000000000000000b48d8713aee51d80c79109fb8b4e0c6e32e25a7ca24dd3e7700f8f3195730375208b241b2c722af3c2295a1704cbb3000000000000000000000000000000001913cf6328429cf2966a48117dc74db0d45be7800f93cfbebf597fb48a8bdcae4fae2df7835f9536481f67261755da2a1dd6656a34f3b12e5568b9c348fbf4ecf50d65a89e63ec0936591f01e6cc7a4a0000000000000000000000000000000017e45a481449f167fd579accc896ac65aff6f1f7392df47d006b404de3cb7ebf6cb59d0913438f3a51e55a0ae3d446c9000000000000000000000000000000000cf4b7db343bea29af6e244a71880538b41b826bfd1d06a21512d00ce58f5d7500ab1ed77b446b1e3782df736bf3dbb6000000000000000000000000000000000525d08e134779ca7614784818876514e14b65e799b7832f61a63601fc491c8b9cb25430547f961cc1c22100170a2065000000000000000000000000000000000450cc2156c4716d0343f32aca82fd2d0712389b1aa984b31d51edc2aa0545c88ff52e470b15eb6b2c22e30f79864dc85202f32528e795e0fbe6deb4ef6e45efc70019520b01fa1d71d5505e42faa69a0000000000000000000000000000000004147c105ee8b4db68482b9d7f6a716ea1474b6c62efc41b9444ed1ef9e92e2b7010a1c1ecc59038ac37b385074a6bce0000000000000000000000000000000018a600a85c5c38be835d2e91a35cce4b59e5f5ac3b735fc007bf5498062beca9befc9c8ead58f9f21f6e08266b149d800000000000000000000000000000000012a476fcb81ab66e3101de2364cb609b17e06eabdff5246bf736eb9d5c87fddd404e8867578262f07a05731b04069164000000000000000000000000000000000c54a888678c28766ad17a18507e4bf5dc57dd394eb6e9b69abaf15e645cf4779bf6ccf4314d2756584647cf27af089ba2b39f2b893be03ab4da77ed518ef35b2e24278d707a20b67ab4d1e5972f9722000000000000000000000000000000000e809152c44cebdd8b40f0d22d57c3b31f29700e0cbc3e69f660bf7270e59093d84bf7ac358be7e45e799a75cf9c13df000000000000000000000000000000000c6c61f98bd4e3b7095fc7f1196baa98139087df00fae2a795e76544ca47e453f75929cab07c11cd3595de6ecbbbaff000000000000000000000000000000000171c70446c19fec3c152741925c8db28ab0d140720cb6a6c45e9bc66c012a421d12271889ea43fe1524944ff572fe6850000000000000000000000000000000006e4baa09b4660c69cace151e60320b771e56e7460b01442bfcf26823c17779034ac241b9365dbbfade770d2056eeecd892eb7c361f05e114a645caffce9437b7b43fa01dd66c1e75b30f3abd0209bcf000000000000000000000000000000001917a23350e94963e3a7488ac1dafefe9ab11856d405eff39d655e31ba808f02954b63e822613d3c6e5f358be04be4a4000000000000000000000000000000001620211b06288c16aa02f4404192e9f57a048e900f0ec5db9b478475f13b142f924c6de720031b3fc12cf869b422af470000000000000000000000000000000011e8ded9ad57e46713e7ac0044ee4edec12689cdfb98838a74adf1a35244e3d9a4a34c81323b089c10422abf26b044e70000000000000000000000000000000006f85c7478cec590fe3355a8d6e9557c5be084c161e090c72f1281be4ee56f36aa1e3c9c844eb45d9e295c15c4cd903efdafc3f57d6116163f1da9e70ea645243c5911cc4ad4a969a57c46c6b5c73acf000000000000000000000000000000000d555d9f23de97318dafb257cf444952bdd3e844e9ed5ce193c10b76f5179f0c6851f93af1553b128f34d3a7e75339f3000000000000000000000000000000000132704571a12a58f629dab48f1a3956392b40f801c2b3757c15f7be46ef1d9115d89920c460c0e2bb062b3cc1aaed7400000000000000000000000000000000152829eaef900fd2f19d6fdbb8f7eb3b02df35d218b494d075219b69016256e572eb7f555f6fbdbe17c59a666d190055000000000000000000000000000000000fe5c67c949b7c89a867301528f0ab24b04d31d6f18f575c475ab5a6098f7187eef20a9ed6e810684da9afd8de96ded6660a77b2be50eb72fd108644d913b9253209972fdec2d107213ba47357c96e9e00000000000000000000000000000000128bf3cbb5208d84dff719ced229921a889c9a4d02f5a508187662f03852531fb8be1f4c2aa9ef01de7720c352dbd19d00000000000000000000000000000000158d89a44b8fcf9ca8c96a8e516e130ae8af19ed71c2b8487ae300c3cdb546e248728bc58fd9cfef21107e0dabf44fc20000000000000000000000000000000012b70b42c8af4551267a94a795fe18e8d054291225438adaa33fe2edafa87742fc3709abcc7bada5d26e3a14649cb47f0000000000000000000000000000000015a853160b7666ea7d64aacd931314497ac7068a4b8bfe3a7deed85df2bb8dba277716a9d1ee50c56b2970016ada509d1ca575cca348dee9adfe68f8a78d39bb998205da2a5285c12141a77ee7af840900000000000000000000000000000000087c7bf08e085e19f0cb301d2e36478357e835620b1cde6e132c237ff6fc63e6fc16a8753550d50fb93a0a1741302cf9000000000000000000000000000000000615299ccefe4da879e5f4b01d6b6ef8358bb59ed8a2b365ec72003c16486d3266243db81f48855d81b6a25440bb861a0000000000000000000000000000000001498fd20640f39dbc03a474f4514e5e283256ac19468077af1c9ddaa40759dcf93afe256de1e49be6469fa106394193000000000000000000000000000000000cba50fc4919a29be2f4e74c261487dbf855db1856e8d5d008cc3f4ee5eb3babfdfaff878adae49b96db99d424bc4dab2e1e4537f855eb478274992cba4e3f50fd9e944f6246cd52dd1517b55bd7f71f000000000000000000000000000000001369dd82ed013474581ca1ab2d2133341d7c1d52065060d72b8317e899e79e9077bcefe6c76c3c7f67e54f76dd3c246c000000000000000000000000000000000405aa84d3ceb02bf8eae989a9cd65afa15451443af6f3cf5e70f5cd7bb8d413c57ac3893a7e8b888ae93a92dcfa2b20000000000000000000000000000000000378d003988f3c6c16d3b12ef47a4a49e2d3d2c7c67e384bcd510939581770aed92e06291ed3b7c742769f0d1ef740c100000000000000000000000000000000048bfa6550711a17d52f48377821baae6f3de6ad99ccfeb8302466047dfddee8005240cdc65b3ab11ed85b11f128624957f9a729aa01c8bf0271052202a077913a9e0c87201a367845f9b271c130e95d0000000000000000000000000000000013370ab697da0ff0a0efa8ebc7589b465374c983c13daee7b5451e8b299933eb5a4d255ffe4aa46782ae0916fd3990230000000000000000000000000000000002ee77be6e0b6fd260ad660a96100bf3259329faf2ff9796102928e70cd52c2bda8d0d1da1d484d7b023d3d59725d12b0000000000000000000000000000000014482fee88e02e61b847c08e61d7ae6fca2d993bbb69bf1653138150d5d7fed09cd5cd4097cb4b6368ea8023383477cf0000000000000000000000000000000009d0380d0d6fa39c9e242b9a67336d86445551658bc29fbd594239a76d7741ba388450caa244fb186afc36d35c8740e93017593cf311989ed8fedff72bb1f14f72cfe5bb7446ace5274d8ded54c1372f000000000000000000000000000000001537d4a47247af8f60f77d309666056c412ce089f3f011457e894f74fa4ad5168baafd36ed3294f5f61cc9cd8f87554500000000000000000000000000000000119e43382a846c8945e58dc7723a0f24b24d9cd487d436a156156a6da97795cf3f4ce382d21435695949b5137a2bf1d3000000000000000000000000000000000be5fd015998bd6043f124048c82e4d848e1b8c87442d0021390cba41c294de17648a47dacc06268606ba73cc95ae6e70000000000000000000000000000000000e05a3dbbf3da8320c40d51ac44c6380d56ecb460b0e7094819aa6af4d7c70d1541d4bc1fc5afd453b165f3d48d09a708bbe9e7a307e380c238ec1f8e2010a95fff8b03923ecd9b012f99e56c77a5cd", "Expected": "000000000000000000000000000000000b00b5c14685ddd17ee99c74598e6bfae5bb1c103f8ebfaec3a620ba57312f3093f9ad5eac820d81096dfece90e72ef8000000000000000000000000000000000dd81552160d449cd787ac27c76685ea0dc993a9fcf8ab182f1ff5d8a484a47c14c1c1a785285b44336c7f6fc0732a0c0000000000000000000000000000000003008b6d97a12868554d294faa26e2ebe2920add650f841adfbf0ee89af72fc4da5dc23b45b7ff191a58c17971b50ae50000000000000000000000000000000013f438d927f35b04bee8fc55693d5c97229c8548ff9de39fae6e26c26f89623d3b0c810b9be8dcf0445910e8eac5c58b", "Name": "matter_g2_multiexp_64", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e1f825b71cd9edcb231c178e160e37bea70108b369afb248edc7c6a59114c22e843fb5541e0f26c77a2b589ea88fb3d000000000000000000000000000000000d65d777e91920b17400955a4afecf82f67cd13f3e7c5d9c2076c4a4d8f7f26383d22d9977dfd0987f219a625c8a621200000000000000000000000000000000045716092850318c343f0dc5337df1a72f8c74dd729831d12103b46127c9180fb50cece34986a94fee6119e72d16a55e00000000000000000000000000000000083fac698ce800786719d1f6063c87d9f728da03cea2545b4ad8831f6c24bfff73e80f2c2fff1532f6d1fea60e7d438ccc5e9d01f6ea67dc3f943d57d9d8b5791d823592f7fae6719804c1ca097e651d00000000000000000000000000000000171d60b76698d4d3f14b4eacbdce9fa66b8c3cc7ecfb989439330fbf0d051d95f3007c389113346e614f5ec8cd170a2100000000000000000000000000000000151a96beb250bdeca3cdad1b07322040bf1cf2105dfa854bb24fa76c8abc25ef4fb924ff995da641244f9daccff2ff970000000000000000000000000000000007e5818778a8331cdcd1432b46abf1efcdf7e4aa8907fd42d5e7d14b57dbfc48125246b57587755ee1571be8b52d2c57000000000000000000000000000000000693eb562e22fa8ca4a655b76e43b50fe487ca1d65cc3867eaf793e50496f0b4658bd92199104c2ab92e4ac53c44db6f57b8fcb85e4dbc1969805d814e75b2b80f5cd1e5562bfc1e28becf731aadfc58000000000000000000000000000000001059d23ec6e472937d80829256db506d2d2deb37d4b750a980568cd5b0db085358a4d610d59009b64db1a9225f9f6f5300000000000000000000000000000000053d9ffc47672f1058856aa08e51aebd469111dcd129ed542454d6401e7893323f8a9c63641f499cd8617c7389518f8e0000000000000000000000000000000002b9b30a5e37b18af4bb02ae8cdd56f6a87820716ea1522a174a0d99c3716295ad0ff2daf663697cb56bc6053c9dba610000000000000000000000000000000019d3230c0bdc228fa0cfd5e0d8bb88be959e70e59d931d9f9e3683d5e65d8ba0d121fcea329b23c5905b80dac34de33b03edc53ced9ec5d7f302216fd30a81c3554a3fd04994f62b5e3da74c8b71bb870000000000000000000000000000000015a619addc75f425596f9a51c6cf2259087cf32afe9b1f07e346a2f4e1f8caa001dc10098d1287b89837f426d073982d000000000000000000000000000000001660598fcd3ab6a55423138ee72a4ca7b57277f6ce140f9f992dd9934bcda78513516df0d309a0e8ea151b2742dceddd0000000000000000000000000000000004cce7d84e0763fbbb54376833ddd7408afe3f741bc2b7e42fef3789a005134cc5540981a15a9f256e0e541ac58ff3b10000000000000000000000000000000019c20a0064f89d37548e06d63d8ff4fbf3584d5bcc2fc2757339b7c89db6d5da76d43b31da7364259187ed602e79bf4f976568ab779e335b8dc67a64f15b947e69cd3896ff393f51fbd3c3e3a157543f000000000000000000000000000000000d7ec5a27ac44daeebab7658011624c441e45924cce97d5bda354f1daf9362f5bce2ddf57151fa07f78740a7db170e8300000000000000000000000000000000121ee325f4252ae5cdd3e3495f36492d68d9dbe13249039d1185760e6e48a789744b2a9946a3d6478a64b378f76b0de300000000000000000000000000000000014c6c5b98c1e214f78b82f1b3be4c32c5013934b1231fec942b5591d3f0440bf63b1505cfbb7a8fa78a85ba58fd4aa90000000000000000000000000000000016aaea3bd0ae91b9d18ff89a40ae27b68d74f3a227383138ed737d59c19ac578da03df83f04c8d962cb9d6f84a15302f3aa5eeded490a17b1cfa66d409811741643b7beacf312b9d6c8e7e7e63579c8300000000000000000000000000000000188e5aed425a768f89f5ce09b2cc909b28c6a0165787c8e3750fca8e8162128ecf62ef0ff853d206d23bc076335008e70000000000000000000000000000000001cfd330da0d1b5b92b6533cf5a8b6b70bd93daec4373f28d669f5e970a947fd813ab1d1272b61afbd2748922b87c8c300000000000000000000000000000000002aec750fd085c99c3b9c3af62b6deddd85e49eba0293e6e8160b26a3945af546a760b8f8f85120d6a51d22313cd33800000000000000000000000000000000162a109abce2edef753ca6351aaa9cecdeac20919681c672dbb183b5b26649e885ff081b9d3687f802dbe20fda43462af9f1f9313bf966ea3b8f09bbe9dcb66a7f9e3e94e2024c49a72ccbbe03fe4662000000000000000000000000000000000f7ad6a1dd9f8cf52bef02ae1e82b0d20dcacfaa5c169a485bf8becec8b51373fae851ca29e64385f0b7024eb0bcf9270000000000000000000000000000000010412a7a710f842fe836414e2729d0ff2e145709d8f7b5e3964af3e0ae267ac53dac3db1e6d2b7f7671ec34b18c844a10000000000000000000000000000000002d3b96fab0e3b8fe44e316fcc5e35f06dab83f2c531a777e162f7521cdd5767ad0b6f877f876f73d2ff663d9b71f462000000000000000000000000000000000c09a98bf623e82a4d2d4b63fb867fab5d3bb1f85a0669c4c11cebaeb357c0717a0f246a9ce4064b7351dcf1e77cdbd393be64fc3763d06111961bb208a2b858aa1ff181781dda630ca41f0d45ef2a9000000000000000000000000000000000114270d35ebff55c0341776086d893513595aca3b200ab98c8b586029b19a360a04f2e77e90d382174296443ab8531d10000000000000000000000000000000008b88849c3cda9a23d37ec9f4700904edb24be95fbbe6d9e20ced0d52208b597d44bb9269830a1ac5cda35d0c0a03c9e000000000000000000000000000000001144466b13427c10ad7679567067dc47c671107064fbb9bad287924c9bdee653c395dc2654caa5b3013ade932fddd5e50000000000000000000000000000000008e14e3cff3bb57f0d87680a0c09d745c7272bd3c216ff9fde7c03df2caffc27e0bfd9f99912855c156a787200752c125d2a2b6008a3b4a4cb3a8c28864214c7fbe154fedab1f9ff8c96eab6a5f28fd30000000000000000000000000000000015cda76d42de9fa86f900a5180ff016155f31b9276c617ef664202848d2efd2876d412402516c0c3d26d49f71d894acf000000000000000000000000000000001307fa2b963fc19583b7e4ef2e9dddbe93e2505e8f4f00ec52db26ab411002136c1f646b1cda71e19480c767906a6d03000000000000000000000000000000000ba87b08173c841a2bfbe424584d4685c39bdd0f83f278f9fbafa8111102aa3acfad5aabbe032c7123631fb8b454255b0000000000000000000000000000000016c525c1dc247fdf34344168b7cc245579585fdbdd6fd783cbe60b727cd11ee97b87a86647f78dda207c98e65c2ee7e6854e742ef7c76ad438cbf30c30103741f57ebbcdca4d6c4f14e554dd1ed81b24000000000000000000000000000000000403887fd4429f44f8da7f17ca072f867e88ac046922ebe3e1e6c4f9d8e174399e7648aca924a557dbf7b29c540db33f000000000000000000000000000000000522324700fb6b2c43eb5b39e0da94cb60e234369543f530ea47f4aa510ec0fd79cdf4dd3ae046e21d78b9c0e35107900000000000000000000000000000000015e946b90984257ffe3814dcc3ef065fed1504f0790f3564c8bfad4e97cffdb61c0d73bb0b1dbe78c4266c773abd56b500000000000000000000000000000000078f604630074ebedbd836c463f3879cd5d4a2c947da0e47740ec369112f4fedd787ae59bea69aab61b91f05d92061036f4f00b2494a32844e01d0827ca78b06f5eb40b6769f36a04f20eea229c305f9000000000000000000000000000000000f722bfebd55f75f3bbd0a55492499c3a3f637ead0e54270042fcc88853df5bc5f11a3677efa26d31c28368e00c8713700000000000000000000000000000000182618bc8a4b3f6556d79848f90efd6883df90806a8358cb6852bde465a27a70644ac5d5040d4f64ec355763f1a384990000000000000000000000000000000015f717739a1cbb2eab30e7b1bd9b25f57ad56f36016b59128ea1f2089f2d1dd0128b455b1b0e9e3b320f68a38a1bdfac000000000000000000000000000000000b855788d6b6a7748aa923dea3163fe525a7b43f4619c1eff3f9219ec3d98ceaf34b97bfd19aa6f91f7fcff728728978191e47a0b0c72bd17319063abde7df51498cf0c980c46946bf80ae4c9864e2e200000000000000000000000000000000120048ace47bc1ab3fdc07713b91a9223fe0fffdcbeaabc8a61351d756f936e18177f672c5a4db7b9dc29bad16bb7c4c00000000000000000000000000000000101275492a6e843306f2927b6ab540d7a5ee925bdab40103b4ddd885e444e6a6ec2d6e99c061284a1967797d8a2e9e700000000000000000000000000000000002c12f17a5dd2c56aed0d308367f37510f83c94a4482e5f632161dd0517dc2d4f46a90bbc13034c63dbd04fe4c616e320000000000000000000000000000000000e4b9089155ce2178f26b058f4bfef57b73aafb83b0b78138a01890a167709f79100a1e4d797c5849473eb3486cffa4b7baf8816db56c0a602cfb4caa9089136ebde05722ad4838671e45ada5c716f20000000000000000000000000000000018180eee7e72b6a4bc2e60555236da335fe05fcbe2b3cca4937e73a550aeae6274122ba84ace78eff84d323b4196f58400000000000000000000000000000000147659347e0fac7a16c92950ea5fd115416072f339d7de3cc0f00ef369f5122ff050d8515effacc825c807f7e19650e10000000000000000000000000000000017bdbcae7f63052af9a7d8bd71dc98b6eca7ecf5eee7632959fe56ed51278099690c534ec33be4ace4612b0f516794aa000000000000000000000000000000000d6fa233be4d6d783bf973cca3740cbaf0f719827d7f9310f38d1dd9d1c1f125cdfca6d12fbf6a8e8104f79bf30b00647d9ac1699117bb9b8b90e2fb709eff4ea0f7882bdf6acc6885c9458703cbfb3500000000000000000000000000000000082f3beaafa575e86be53b4fe7b93835b00759f921933402282e5bb0e643a812e0e4b676ad51ff2c6f5332d777641cc3000000000000000000000000000000001760b87bc4d2c13122fd7acc6d629c9f9db9bc9a2c49634aaf33e258ceb3106bc2755b227c6660a1df1d92c60067cf5a0000000000000000000000000000000016a819d7109c9a12199eb98537a730908a693767cdb35a69b4c7329761939afea766f0b91ae405e273227330761a53dc0000000000000000000000000000000009d14d7138440349e83f5ded46d18b886ef3cd63e0e5bfa0a8b50985142b21a4733813ec347e40cabe28e6ec1e068c24a22b6c1a24eff71f0fc64b6aee8d3d2dd0827756f5c959f68f1216c2dea58503000000000000000000000000000000001676d7f489219b56c198f8494e156fc0672ae28dab20021b7a6018436c7c0f107efd2493ddc2a1cfb3ad490ef146348300000000000000000000000000000000001106e89fc098ce7bd8bead5d7f6432bc54501370ae6544f34cfd996b3b610f9cfc7ad366751ae1211b848aad7d93d30000000000000000000000000000000011f8f0bd037365b5427e76d57b018c1c644034b28d06c8f68c59bff45eb4a2c4d761d066d96c13f7e73dfd80c81704a0000000000000000000000000000000000fc826b5957613f35bfa36d3ce088dfbbd06c8f2e88056a22a9f35db561e06fa0378ccff29ba8b81cc12c7a504f8c704c0431e6877166686239f014008959332d9d009a801be6a1e68c2de52ee264bfc0000000000000000000000000000000014f0f64acb0d9638a68278099abf5b5da3aa087792bef15192cfe3689b69b7ec1aefbfa14e659358b5410d98d2eedac50000000000000000000000000000000015ca79c92e98cf8314a2f6319520e1eb7d4656ca6e51278710cefd9c768a25691fc58e983aaf858d3c8d0ed73e2beec300000000000000000000000000000000007a5192f1dc906693568291f163e9632c53e1f418a87cd25656064adffbf31863680468f3ea451fbd22ac990dc870b3000000000000000000000000000000000131d2e3f6956da8941e8340259b8a15aee9fc6f23573f9a348ee9a51bbca1308dc54e7b4675357e3a9c5971be3a5c16af833a784d22b99537236fb07ab7b59918783e35b89fc9692d7f76a03e024c94", "Expected": "00000000000000000000000000000000163da4bf7e159e05eec90318a8ddad4a59fb02d7ae2fe18795d38c3ccaf797188fa16577e6a421ccfb12ba1ed573c4e6000000000000000000000000000000001256654eef3352b09e0027277aec042519d99eb2567fce2cfa50a0c251c12d3593604739128171bfc13b3bfd1ce8f9e8000000000000000000000000000000000b8a46123bc863bed525f97166bcb77504eeeb66d2db207eb8342a3d18f7f5a99910fae3e6423c6e84e437a2c4b24363000000000000000000000000000000000b73cf08023c8572f48c132add67dda7a15def638a01b198361b9d21a4634ba76ceed9819b37c12e24f148d255483856", "Name": "matter_g2_multiexp_65", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003113ba8b216d933fe0c81f23f75942c0065d21d8f009d73b1f698281408874e33dd2750fd4298367b81827cf6fdad34000000000000000000000000000000000b8a921e840fc665a786d826f83ca5a9c8f00e7c802bce5473a7d1ebf63e8bb6cf5c4b426153508d874064d1f1dade09000000000000000000000000000000001492ab584088d23d3b0d1283904f9a8f29f9efe47950c6e9ffb9db2123f3f9820b906d672fc7f97f0bd38b8fc0ef44520000000000000000000000000000000010d321c2538f92aad4631af44ae39e63dc06becd2460f0cee0e526328d167fd6cfbcf4edfaafe32d13b5fe66c009533bb16c1bc60e1a9be9a82c93b7e0311e7516a57d687d8907599918df77b3b6caf3000000000000000000000000000000000ae75d01481a51294003041afc4802326ab878a3a75eafcda43cf873cc65e300d28aa986fb82a2d1d649e5be00f956820000000000000000000000000000000017640eeef8982250f88a4d187dcabfcc9adc3ee9194dbc3c04c741690fce5bc7cb07cd0b7c3497191d9ed8558fd0d24c0000000000000000000000000000000007527fd8dacb81b8d1abc746688db6a47211fa71556155d38361921c4bdb2a9e9921a3a540bcf55c6dd751b84c04a1040000000000000000000000000000000008de9109ba354d7426a5313d66cd747a54df347f0f86a3c0f99e9e4b68fc79641fcf98ab39fa23ef6f1a781c48f53f76cf301dfca76a83c70552c9cbc9c80cb20f0d82a70a9d887b04b150fa0764ce2e0000000000000000000000000000000017331b8367f07756e789f7edce4d22f6886656fed78ddacef6987a2751dd3d5d49011a050e7b2a3e11fc8d90266c9d710000000000000000000000000000000016959c303e11f23392f95c1402d1d1ad7f38343c711e96f18d03f832f76e3e81de789a6eaff797ae51079b13571334d40000000000000000000000000000000004266fd13db1ca80196a91263c79d1583b717fb61fd9ce5113e4cd94c59e605152b244e10e364b468c5a561c6fa9715800000000000000000000000000000000026f67cb263be83f3163856f091e9346651c29d4634e242da53b22eb6e66018d235b0f30f8833310dff9f3020e5bd3811cfb94c4e029a2126a9cf5561c677687f52059e4b7f8b7e7e73e5b1dd7f42129000000000000000000000000000000000114d8babd11c81ca2b8a7e193afbe0a8fce426b83996bae6f77201870e51c9355c319dd86b985272f73e0804c0f53700000000000000000000000000000000016f5ea7610891d0e72975816c08e6e25a75c7c42500655f26efdfb384241bbc825358a21caff347d00c8b2391501d15400000000000000000000000000000000199c8c74a79ee90c3606906bbb8cc163c214259e4d0127cee3283bcd9c1ebe4090ca7d7b180201910d3f6f51566d3bdc00000000000000000000000000000000032c785165ad4c1a2846e15318bd7cf5b42ce8b675cb18fcc4232e28701f225f1ea384b276e7a38b2c9e2e8b112f1911d8386fe6f4303959e58165b422e98c4813b1bad7808594473e4e66df09698cf0000000000000000000000000000000000842c65006caed9b53add048a2eea89e1b4584e1deb4365e3dcf8b9ecb02f337bccbe5d6929ef8c20461847f171fd4d600000000000000000000000000000000100dc23e6c1c6f6756419a9bad3133bba052f408a424c5239b8528ad4429a2bce64b72f1463625f7599ce43865581e9600000000000000000000000000000000125b4d71333274a16e52829ad5eaaecdda5c206063473dedec5a8ff4424def70e6f650926948dd2158b403f985a3421b0000000000000000000000000000000006a031e3c002702837e4ad28250b85cd94d42cf7b0d765b980fab95edded7636d13bdef1be63e66682c4e297d0cb2b0302e1c432f3b55ae87ab815647f196be3e138b2f6e9fe7acb9459650246187eb90000000000000000000000000000000003f7091a25da7d5afe6fa6b254604a1abe7a0c6ea11cc1a4167f5f648aa973d888383bc7e987b620d23e688868d318360000000000000000000000000000000016637f888efc3e057227cbefecb3037aebf8e330c3a794e51d691e3bc064237b98351beb746868aef977a83d1fe163ac00000000000000000000000000000000126d2884487984f851d1bd7d61bdb803321f263918e88e0677831563bacc9f5207358d1e9c76a5a25a66f0294f459e3900000000000000000000000000000000125c61b387a4462fa3bb2f06a4cfbd7df082d20cb23ee974aece2ec9a3b0c084d13a7ea83725a05d9f31b8033d2888ef9b0cc0ac499dffd627f5d19b87817dcd67e87561d5244a4b5698265f8c5b767e0000000000000000000000000000000006cf2bc7c691c4f8a64d0aa1ca3760d715b3188a2dd299ab09c723315acba8b0b4bbee819ba06cc564f0c875a63a415b000000000000000000000000000000000bded3d695e471f30f9d723f55826eda112eb0e3fbfb9a377cfa07d6233ed84108b92a79bb491a2971e9afdf83db8e9a0000000000000000000000000000000009b0e9928cb267508d4f9444c6ac3dc6f64f49a70c82c0bcaf4022e97854e5d9ec2612a2cd4d67642dc0451583bcb24d00000000000000000000000000000000009347dcfebe93a2f7674ad02ac48794e7cbffb04dd85b0c8c192fc85cfb9cef40fd11def6f63ae9a923960424eac6a02f3875f81fd39c9b3ec74eb269903dba4173d8eb0e41a196d3131252207ffa040000000000000000000000000000000013e8215c7bbdca445555c9fa0ae44e1905703334bade3294fc047ec262b9e4903880d52851967339eeadd666200b25ae0000000000000000000000000000000003b0bf4498103ac03601a8594b154b59a2a93d663f98ff8dbd2c85a1902e572a9456c629a12651aa87a1262102e1c770000000000000000000000000000000000e8bfd7d3fa0f773e6bcfd0d43a5c436862d1cb6a4ed715093c6782cd94699090c4bde597f65768e963fd0f8644e09b300000000000000000000000000000000064dab4d0d0c6b94c58b067337f2fac7d0d922cc822562b6bc941a794d96aac5ddb83d1d5844440d21d0a72a69303b8b2d8d4341822dba68c6fd58cfebd07b134c1d0c4e32ff63f7d59addff4df1ec3200000000000000000000000000000000098dd9a20f84fc26e78993a9de4d519aa2f8d343fbee501af945e5943e88425d29beb7ae54481b04175a07bf69b260a30000000000000000000000000000000007ef43e7a56e4e7d532420e152ce566d9055eadb4ef13d5698c49da905a4977fa8a7d3f51c8f5275582e1647984be61e0000000000000000000000000000000003755ee4432ea90f2197c7cc2e191dbbf7950c52a2c1b723f26d2aaf7a38c1b97efa29a312fed599f1199cf186400adc00000000000000000000000000000000150edc463f0a55fc70c2ffdd1f73a3abbdae459eb16adf79e96d18849ca638e6f41c6805b73755968be5cb110d81faa4efa3dab1d7cdf949bd938ca6ac371f953b3bbef1aec7ae76bda37db4c940b3d8000000000000000000000000000000000f7149602cbb3e5f2c5f8edfe59fc0fb8e1f03f89ea192bfe3990d87ccd28d4a80d7cd3003a8cfd669e1b6ff7e3cc5890000000000000000000000000000000006ffbc965bd06de07d8c0a9db8db5ab82d5f11afa1ad8eb92ed4453489f5899cc8c46ff02743956bed81229f64cf6efc00000000000000000000000000000000164cd3271ace4809eadeb1c0f769094272f3b66968690339bdb5da92e920cdc80c9d577ae4fa5b6426a5a6f46fba80bd00000000000000000000000000000000098f0a14a511ff424847d2b4d1b80a049b1f05ecd40af96b7a81def54486e4969011c122ca7dca3444029daeae2ecfc79848d3c53632dc461619c8c522013b83550ef3dc7fda197ba37c9cfe4340f5a50000000000000000000000000000000018409c0d0f37f4932cca87e24eb4d55e75dc98f938420ce036d43689fbdbbd839dc608b21d12a8af1d0a780aeac6617400000000000000000000000000000000109f2294669422a4946f926b1f106c2887893a042e3bf900559429c7fa484da4909216c8dcf826871534981021256741000000000000000000000000000000000a1ded19846e603b958d0bdcc9b554beca784b017d2a35ba117890fd0dbf729428bcd9823c7a378706220377c82a215c0000000000000000000000000000000000eafc89e30e4fc0544497e27674ec5b37ec0849fb382e608e09d0c1c94cb78bcb96ef4ea48e374aad1038881706fbcfcbfd192e917f2e0c4d6253c4e4755f30812149d1ce1ee4ae5540faf1dbfbc13a000000000000000000000000000000000e02cb3e099792ae7508321ce7afa323fd499de90c4006621ef5ce1054d0c934ae058a97ff8aeae0c88709c4d8ed0adf000000000000000000000000000000000e19318f5890320f17d5243adb4683a97e3e9763102c4fc93e3c3e3d24f4f61e0500be916c249dab00094b4ab048fe99000000000000000000000000000000000989faafcf6156472368b282313e076613cfe7ff135eb131b49e58932cbfafecf6585009d1f17ff8941d7f871be23e9e000000000000000000000000000000001167419d097ae8b96993b2e67da79b658adde1e12e43c71f27835845c7077f385612158d3e59fe2cb32b9418463e672679eaf11b3a30c7771ce63cec214416d798de20432670280d997b2f0631007d63000000000000000000000000000000001579b7d03d3d2c8a280e8ca113bcc98afa6a2705a5d228d92807a85cd5a1ee97510f632293a478c3fe0bd383f4b69cdd00000000000000000000000000000000107cc2e6bd02251bfd565b4b848adaa84babe9d4f083e827ceae6bacd9c9c221f0dbbef53278175bf27ebfe5949fcf8c00000000000000000000000000000000018d187c566690e4edd8d8abe5e0a448e352f622c96680378051228b6d081a4914aa51383326aedf45e351612ad6c5d000000000000000000000000000000000197427117a52f82aa6e931ecb0c5ffeec7f73ee8f44c5816935d26c06cc8285200ff9240d98cc244708e00669460f98b43077447b67f65e16a8aeb3564b2d13822e478dfb4a82a15a1c8fb7cc8170cc90000000000000000000000000000000019bd947df5a437a7f1ca2340bec628f2783cc1760dbc4a97ae10093aedd9f64e25ba79d9f4ce678f4fec91a3b1eef2d7000000000000000000000000000000000770e0c39988c9d8eca076464a3e10e274b06b1d2f6230e6dbd8dd59dd9c062f8958c6870c44ff196341bb9f65b8db38000000000000000000000000000000000a1833ef19e2b8e31577e5cd26e0a7fa46a5d25355d8b3dc0605f53714a60423556f3bcf17649745695f68f26570de0b000000000000000000000000000000000f449aed4120f3bef05506f2463f4546c7ea67b9e9110d3942dc256400d063dcc571305b1d4cd2bc3f18cf25319286e8eb64479b496c17d0587f6f26c62752881b6a9228643e8c43f21c441eeb643107000000000000000000000000000000000c1f9688ea64165f894e85b21761a9b2bfce891070103119ae71ff7acd164a57b0e054319631180c22f19eab8607f5b40000000000000000000000000000000005ba18dafcd3552af464acd469b133896e90c9ccd7e3bfc6e05db883f3c6aa1cc4610ec47f6354f6a7cff4385c56d2b3000000000000000000000000000000000fefbd9d78f48683b378d2d6311bf7ffaccaf7aa73a0bb4ce019a0c1d2e1673e52c724bf3a782729ec23d258043efff5000000000000000000000000000000000ea47ebbe3e858c5fcbf5b0cc9017d6ea23bda36e235d2aecbec827fdd2e4b042d1108d5f645b6dcdd786304e6bbf81b52b42f75aebdad1bf433917c025800c4f4e985cc077db3ba36f7484f95764e89000000000000000000000000000000000a313e1bf72d9a176bbad609631192c779e94c293463507edcd1c38bee8f33cfe6104d7169457ad5ffd9f045fce1cadf000000000000000000000000000000000af8db18938c51742b351fffddd74bf1137092ecb50a7e749391bacc9c1a19c7b9cf235b52ed577e7855d4ec1fadd940000000000000000000000000000000000febaa128de79274ef11d3e6378809d5b319796c653604723693c335eda175014b645604271429e3d449e756c85bcf6f0000000000000000000000000000000006adb29cc4ba053fea56d07225d2f7735651c0046f5cbe4a350dcc20431ed9457651d46a5d23d946959cadfc5500b7eae83106e9ea63791eb192e7a035bee27bd049b3a37f080076146eeeea6a769384", "Expected": "0000000000000000000000000000000019a5b588aff8853adcfa959afc5135807d00196a75acb3536ad4fc9a9df3803d919a2de7cbe9ff762913225577ebdbf6000000000000000000000000000000000ac8bde939ba2f164795804d96dfa8d3a1c4d9e4eafb000cfccd956c24f4d594b30bbf961917f625c86270cbe164cc5b0000000000000000000000000000000002de09fdf52aec0b91bbe99fe2eb9043b19975c6fd503815264ce030dd5e5444f0f4275ac9a07a49de775335d52ea3c40000000000000000000000000000000012457bb55876c482e5b907c765b476dfe6ebfe8e588cb7f630e58f78942bfca57e6c0d5d7b0ce80e48960e297863d212", "Name": "matter_g2_multiexp_66", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008f3f1f04fb80a23d348e3e25dac1d732265fd4a71ab8dad3718d268e49c79578e8e1ad1720e70357439e57df0791d64000000000000000000000000000000000fa4c15c76e395fa706a55d1909ede2163274a68b3e7afb8d2e0bb176f60c06f5a921c9ace35bd311bd79ae86340ba5000000000000000000000000000000000173633369e00c8c5528bd5ccf95c6af8b012e5a31941c134ad4541099c7c33c5ffd29a5a31e18be720f7ae85132cd6cf000000000000000000000000000000000800f5eaf7c8b1dd2787305ecc637a0bba8eac807a7b449410e48aed3dae2b4645b8459fcdd477fd92fa5ac6291b800ea4d710d2f632e3ed0ef69fa0219e16ba30d3efee99386f1a5c921f4548ebf64b000000000000000000000000000000000ea8057b2d609ac2130b21e0b4a41f0aca20ee7751f55d816ea42cfa4612b67c3c556b01b0bb1c5912a74c50a420407f0000000000000000000000000000000007fbccf8ce8d1a92756fe80b15c7d9342af4e166d3c1c7e35ea2fac34851cfd983633270c877224749365720fbcea54a0000000000000000000000000000000000885e173b73118721d28fd26f3a9c562bfbb878ce71091d7ae4b37c1f2625777d67955a2b7458af71077db7557171f2000000000000000000000000000000001754edbfc3f2af94c92e6754d6bb096bbc4b39bb1128dc6bba8b4d4d9fac6649598be90b06b9d5db44c4e77c0cd1537cbd9ae4597aaf582857b40096360ced0f044ea172551c6f9fe3a15e0ce290b56b0000000000000000000000000000000008a1a751b5f9a08e2bf5b2a58f62f0af6b8773f88e50f658ed220c0134e83c7031a288eb50a8a35016d2362b431d809d000000000000000000000000000000000d7f04d4a6c36cb3d105dc3915cd5d57f56692132681b3abca4b00e078c700931848e34ea1b7ec663f3886ff766fef41000000000000000000000000000000000a06c3ac81d6d0466e1ef21115150d04c8bd6dc3e4078e46eab213203c3226bb0c6500ae4fda591d6b8a791de598edb90000000000000000000000000000000014d849ddba2fa79b6a7107efeb46e9b6231d65384c69ed183acfb922d55b790d4fc7546afadc190b76f7da00103ef565efbcb4bad99b419820eec388f6f62ac8d87866d7beae6d431dfa48d4243b4a4b0000000000000000000000000000000014dfcb5fdb38cf09c1ecb284dd4f2de0c3d70f90d7c167a442d84e9a29bf43be62cd319b2dafdb6ead2c6596443a00090000000000000000000000000000000006220fc05c53f48e7e4104422b0660ab67fd88a695a201366de570f0ac0ad30421d5e37a1575e6b5ba35f45b441b297200000000000000000000000000000000077cb8ec1cb83c4974f6452ce0de630afc82e283eeb55d3b7e9969bb44bcf0404deae617393f82ac228b836c3cb6f95a000000000000000000000000000000000e2bdf539eb45a125112836008effd104e881aca397457004fbda4a40d152817801bd259434481f0509ab1838cdd1fd060d89acf5b49fd1f70fc54756c4bc1972cd8818e36efc37b422ba6a9318fa134000000000000000000000000000000000a09843630131cc6feeeee8aa8214408235655e4733badd6fe20c5cf1e45f6a61a5216e0cde937799437962706d3bfe2000000000000000000000000000000000ff518501614ed4a199ca9e9aad4e8efb8e9cffa9b4fa683093a49cef4669198a7893db998d5777f2cc8f4bb130c84360000000000000000000000000000000010ea66fb5224f4508ec100cdb611be133c4895a8de1b4c475b097494ff0f1ecdc1bf8fe467c630233cac2ddc07935fcf0000000000000000000000000000000009d22c0a45c82b0a19beb94eda0b93cbbe1f2e5f2d61279e1e1c93ba073cb766f5637195e6964a4814e588e44bb03f03386af376b9b393dde994da419d1f7aab60023546647f7b069ede939386bd6ee80000000000000000000000000000000015ca795fc7f0d169ba8abdafb1dee80b67e7dc616e824959f84c61284d6b2e0e8b9f99b414f5bd96d0e59b66ee706fd800000000000000000000000000000000042f473d1fa228961aad526efd003461935954abaae347dd6c9bc7fcd68b5f5138e57ab2a160cb19d1983089b58b51ab00000000000000000000000000000000188eb160cb968b4b048ce14bb72be27c228df1a6c014fa7dbec09a30aed8c71e8da59d3d5f8073b6a7d70d94c0e59dda000000000000000000000000000000000d467e6b05f033f3923667a82d5b489a5c90c99c5f68078aec700fc67a83d9bb4c09f3f00b9fc2cfd62bb098f885fe295ffca78eea65c00e1128f8dcfc96b39af1c4472b461ba5262307003bc972023d0000000000000000000000000000000003bec45d94f3073b2ca54d6332d36fdb8f5c801d9f70ccf6e3666b66ee06c0fdfd741f74cde1997aa205fb0318c9c4760000000000000000000000000000000014009b777b660264eedb35ec2e13ea586aa9438c47b3fbfd095ea3d8688a89c85bb4052bbd3edd450c19acea6372d0070000000000000000000000000000000017f26d3cfcb40fd6b4f3f1acb6d47a9b54c232aee484c7a8992a3d1accea794dc384fccefb0418d43e1fa7b399bdacaa00000000000000000000000000000000153c6cafbff3c53114c96d8caeee2880dc063d7db5edf5f14157117387f368c76b739553542bf6a9bc4ace3694de885a92837b4314e63ef5a153ea2ec4bd373cc3cecfa3e892c3a12aaac8ddcaf5905c0000000000000000000000000000000005d2481438c03493efc9f1e8e9ae6ab05b7430f7fb82e108aada0e886b14d769969d54b17b31e5bbb63d40836748f541000000000000000000000000000000000971deac599b2161a4baf1178feb81fd4798ad5cb063b1a0cbee7cc33b8fcec6c3f43d1d46d9ed45555187db636af99e000000000000000000000000000000000222acaf8df647744859e04104a5fcd546949feff6244e192a9031fc838f368aa465a3799779c637ef0087183f30731d000000000000000000000000000000000b8e8f1889816f89401b070db687aae47f7264c9be192a8d6e485ee71a5a688070d57ad8928d09d9a4925f1050e2c69e127ef2309c699a3602b0d86a070baef0eef90f539aac3cb6ff42cb19f284bd99000000000000000000000000000000000b8a5b0dd422469a8d6d7603e9f3179f443ef3fab0016afd94e93e2ea9e84b332da4b59f23a5257b99460efdf7d2aca7000000000000000000000000000000000c28e7068769c3a79bb8d92c3b89eca5d6eb42e3e18c2a7154f43a671f8670f878c4b110990c2e2b163ba4d1155319fe0000000000000000000000000000000001804302246fd07d86f4bb23f610af38deba8e324cdedbe5e61cf0941281cda8fb5dc211fbc0ce6fddf30aefa9563a0500000000000000000000000000000000015813fe0d6bbcfdc8e7e40b6141db21e1b490d846ffe82eeb3edcd9a024315193259612155b0179a4971e205738af74ba0f9a93c2fe35877ddccee5da39ce5ae60a6a19e72481319e3b3fa2eac614890000000000000000000000000000000011ac1ea4dad0f650fe0844ac3ab9434ebac6eb70a5f77c8f9c892cb4cb06639a15c63a9b820ef8f7a720040ae5b9e49500000000000000000000000000000000117da7999552e7886a25a939ada0944cdb15b5c468e9d1c3bf5b6af920e470bd648d24f3cb7f91e670f57a52cd65f7b3000000000000000000000000000000000a24147ef5f2b8ad888899c1db8df0a601eca9d76f1b934b1627e7eef3efe542f51205b96b5c00916688579ece81336900000000000000000000000000000000151863d964b12287ae4278c905341124985410f1ad6a72bd5c62230b7d8b0cddbea0c62cb2a7147afb5bfb03348be53363da2f227d636f10e814e360c2156e686e26ce3401dfd15f47c4ed277d05353f0000000000000000000000000000000001d32ea5faa6303c530790146df7cd5cdee93c0933b4cbc1c2b8030bf0a8d2600dba1907df1756152625cfccf8cc7fa90000000000000000000000000000000017b05f549751d090f42ce8a3ac5d959cf988ecdc485f51734d52c40a3e22a097917345978209fa74a0a05be0a66e5c6d000000000000000000000000000000001481fab7750380626b174602d9fcbc97555c516f4410193d2849443cf25ec22840e4fd00b225f98d81b38619e8844ce90000000000000000000000000000000001d56434066551c5bfbaf8c9007874abe57a6f78de9355a297bc117f2bc5e6e3f44b248037f400f7caf83fece0c00ba0ef79e3b6ce752d140c3dfb2007a08221d989038c921efff3bc4e150a6155a33e000000000000000000000000000000001667f1400973598ad3f56c2e49dcb5b556cc38ee3e5801ac4943f3c4554205d8fa69831e582a084aae1ef584feb0a1880000000000000000000000000000000003f0bb26ea548e498f05a5bbda8b8e536613f10e7165607ab77565b193f794664c8ab0a5ae2368d7483b77bc1173d14500000000000000000000000000000000176d8d294b4d975629c6a89bd6d45f9c3924a621259ab43d33a3d5aa1f423b68e3cef96dc103494bbb9036436c170f5600000000000000000000000000000000002f8ed87c584e69de59cdde02b6de9816c31a6efbebafb6ad9cecaf266f5bb9c8880f062dbc9235c91c668bae5051f4bc08091af8b8c6ea5c26f1a7d795132521350d774042d3a8c0523e86fdd23a3f00000000000000000000000000000000085fee95b859c52e44fcb2900a9aa590b1a5c2f981a388d6ad7b81ffbfe033f648c4a84e2119cb0484e178ebd3e220d100000000000000000000000000000000171e6ca074aa97981d2c2ab000a8bd12cbd5f5d574cb83158a6ed734e8f9b7aa4b74aaa43b7aae31b3f4fd3d82fd30ea00000000000000000000000000000000004fe6099a52fb491a0624a8d787d95617f6c64d16d20d1b3769f60d4721f7af66d7e3e905b3e08b2946ef7bff4806ed0000000000000000000000000000000004d3d1a56af91377ae6b00e192ad64fce6dd43a37592fa8706c9344b3d96b1f930e03be85a5ead3007f9016255d2df7570363101b87d685aa7314f6569fca0775bc6aaffabe136e6c336e8fa43dedb8a00000000000000000000000000000000155830eff04ec2f4dfca4f73403e408a68830bc031555433fd38ab3ce1035b5f882bcd6032aba69ecc43625546b4a3a8000000000000000000000000000000000ed5b698b1ae23769cf5b6dc2e39f8500fd8a881eb43452d67c6b84ef9f0b3c7d81db1909b646e92412acc7365923a940000000000000000000000000000000009f28ec2f949cddee9bbe2fac12c2c029f4e472afa1ea56d0edfeacdeb9f43a4a43b79ccdfbe8957b4cc16bbcac1857d000000000000000000000000000000001474b435131301db9e232ddf54569ba99bc476200ceefc15e4aaaf1a574c1de8bd2d63c8280e23127a7a036acae223b1997ff3852cd97c3a65bce9083ff66197fd5c70894641195514d556102f091e8800000000000000000000000000000000168475854829d47356d9a8dc13a94e8d169771ea0070d9ef45e666d5378dd676d603c2eb57a3cda072c11e0926b02d650000000000000000000000000000000008b493a9f4c19831341782fe6285db2f7e8250d72952351ddcfcae6f22a2ec0935e29d396ba32f72dfa4067d0e7ce7cb000000000000000000000000000000000d9e72e22f2a1522babc5f2e8dc7857ee690f60f7843ffe15a080d56bf63db86f124cac039cbfa16fc8ace4d6268a1180000000000000000000000000000000008f3db1f6c0e5e7b3bb27abd34bd877cc3c373c681a3abc88eaa91636924ee477ba5032801dda091dbc51936a90c84685ff95dfa306f91196849d752569b35812e1db7946708cd06df9db9ee75447bc30000000000000000000000000000000004e34bff7e9e3ede02df950aa0e8c5f4c5f85cd3be89d211e957a7de95b8e321cc11400c3dd5b2ba0d1a3008462cebe7000000000000000000000000000000000fc1047097f01fd2079e6357ed379ba39107ec41ed6c6dc17fa6248d52be2b1cc2593c9735a6cb48e6d6e0434028f755000000000000000000000000000000001896fc5e990aeb416cf21ccc73f02c41d019d0a2679bd533d0811b7c16ad3ad3a6988170fb2db030b5fa7c3e4df5acf4000000000000000000000000000000000b70e14ce1b54d7913b9f3782b2b8ff249967a6b871dfac7f54f959954febb2783cf20e20d1710e5526ef8aeafecb3d603c4308f0467520343825a91c0421f9c9c9d06957fa2fc051970f14085339e26", "Expected": "0000000000000000000000000000000008056d4dfcb593c10a877cc8a4accbf58f360256b76876ed2b33a07be3110f8e295ef459dd6fb10d12bd02a8276351f50000000000000000000000000000000005686da1a0da89074c6b13fe9913f5cd49e0ecfea46e06493510625f1393ba4cc2e13f023fbc7ec2e130bf9a4f7483ef0000000000000000000000000000000010cd660001f65876db5b2cb1a56d85171d4cbf037f3bfb0e01bf4430c479237cde5b6cce5839a4fb22b406846e757868000000000000000000000000000000000809d7711211d37df76cd1cf71001cbf02c76df67c83e4eccea3e05b11d196b5d52ad7c3d0a00d9f0ef5b018717fc3eb", "Name": "matter_g2_multiexp_67", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005d6cf50e3add0e5ac3016b394ec363d6145ed66ef56b07bcd33c90600e83b4277558695222062e02d1e2b0693858e73000000000000000000000000000000000de8caaa810d4ac39258e3d1656bf7f2fb7853a5963ecb989346abe90d5d35d3662f6e283cec7bc386a6a8638ac395ed000000000000000000000000000000001849ef86eec16b0612f214c5ed52c0d50a90bd65b623402879f2654fc578ab680d49af9afdeff546702304597a20f1fc00000000000000000000000000000000168707730c4e74eaa4e85e48e7239b9ba3e8cb74c24b7126a685da0fcc963b9f9180e252adf7d8c521deb1a2ce0099582849fab097a4f71bdfcfaf435994a0c6ac3671a4a9ed0402010be83ff95228fd0000000000000000000000000000000007d4fed2fbd9e9dd19e0af5c52637b2cd337e0bfbcef0384f182a56189a7e7304b9d2144266ffa79044be90cb7ede1b6000000000000000000000000000000000baabe8c23a10cfe85494c693d1b09fc8e43ef5f233052d5b6294dae14b4ff9e5ec240a1c00a16a9ddc27cf7b53bcc7c0000000000000000000000000000000001c595f193229da9acff04ef67ca444b0cec75db5b2c1921502e37eebdd2bb43ef47290fc6f1980abc75ef4c50034df00000000000000000000000000000000010fe7f3110ed3a240366ad7ba31d56ab993468dae2dc1b667a46c7759baa37b865d02834e14280a2ccc062af5bb2b7d6e6558521e301eabf09e80a509b46cf8ec118ee8586f4e46a7313a96dc37ba69900000000000000000000000000000000150350d8a771c79268606d6a5e1c147dc9d92e63fdc60b20be688bd52eac697aa5d90fe1b7b91321b2af87c47ac0d5060000000000000000000000000000000000fba8f4da448b8f2bbd99014bee2f9c581f2a974bb0b54f41a84a7fb359e9dbf88ba59a705504140284d486241e94e80000000000000000000000000000000003bb92d6a603bd93f8e987071a7385de68d10cfbde389eaf01ba6480caf1ad8aea03c84d1889b7d5b5c5f72e62a2d75a00000000000000000000000000000000193342a9f15109367030724946342e564507b26971caf75190e0b209e429a948d8b21ca16041a01010b68222db66a16b8f2f7c525fc0f353700fa823a5d32a93189699206c5ba5ed271a158ebb47674b000000000000000000000000000000000bc4a46eea57231cc64758560e3032a8ad8f1907b3cebd7a8faeb98c4216cb8a0c8fee09929ecefc4bee7955f4e799ba0000000000000000000000000000000009f9486257ae3f94a2ca48eb203e2ef44ecf866ddec7824e1a4bb3b89b320c38b3c46de8202480628c53c415433383a3000000000000000000000000000000000d8e2b5d0825b11344d16dbb2cc614c6b84eb1cb43f70d70e272123867b731775b429aacde611318b2700aa567a84c7a0000000000000000000000000000000007f720929287a70873e9f2f2031b66693eaa6e604668219aa5aff3f50e720b34c5fa3f5c66eced5c3e86e8b34a81b984c7e8adc0f0a042a32c733b5c3356cf4a7d648be51c1d78534ca65dd43a0c13e4000000000000000000000000000000001537ed68e203e56f31498efa314322694ebd74cd1dcc3145d534299fbdadd4256f20b9f74b895931a60753bde6ff9030000000000000000000000000000000000935c6ae847aa7f47bf427988665e5e18a32aa869e196cf9d5bac1349c650219a8d20e01bd8d49bc7e4bb8d464aee84300000000000000000000000000000000013e0661d7254428861cc3ed47c3fc9daae8b86db35d1c64f8ced3bc18a89202825f13163ff94ac0ebf046a0a99727e200000000000000000000000000000000039a6b0b2cb91e460d50eaf9600c29fd4f82a81c283ba4fbd9a7d103efdaeb1e82947f5cc1a7a1112ae6344c51119201650081a6720845a20164ef7c06ce1e73286a32dd64efbe57fe46765008dc9dd500000000000000000000000000000000071a6b0267806f2b9e0ba493960fe0e43f135c739a54c8daf5ef9ee348a281f19876f80c0dcea59dfe9457b49809c12a0000000000000000000000000000000009ac83690c30a4afd78f94b2493674668da4efc84007d2a08fc78bba271ed1f43e2a9e5909149bf0811c44dbe07c52f9000000000000000000000000000000000f5d523612fdb2e7dcf5da56720057dff6b0b80707cf5924d146c0c072edc0635c73fb04256e06c7c9355cfe77a7af0700000000000000000000000000000000168431fc569869ebba9b4a72371e3df232545b5fb95778baf3d9105930d9a89b4cb7eba430e9162a5589c7465e54ca3ac067d18b95591f7f14261f95513e1990f5a4f6908f94a015a93fe379726d5120000000000000000000000000000000000ce836522b983fe3ef6a502a0de4c599fad8a36a60d914218d5d2cc4d56d69eed8d27b2d50899639d1a0ea9dc7597f900000000000000000000000000000000014110ac048ac4c20e53f2214df8c06d77f0b3150077d027691cacd3715d4630a387d5819ef58eb1bce2e8669be330a3100000000000000000000000000000000178e5cb42f56df2f1b255a028a00df96c02eab0a79aa0ff3e9772fbe3eb62174728259b3a15e356e6d9666eb65fd6b7e00000000000000000000000000000000045197f136649b61d6e0e7b9a56674e769e2d26716ee7a63fd2b83b767a9ae96694e9cf81375d0377a1b27ea6dffaebbb448bb01a1963bf74e0fbf99329005af8e932074358d855ff43c213e02bf26bd0000000000000000000000000000000016a6a58301c243b0c59d6934bd926d6440b87b49f004f411ab0fdd924480175052f63f594c18007359055dc776e7f2d300000000000000000000000000000000176db4845cad46a13d9dd0f4077cd22b3458f64084c7325e9885f8ca341ce3ccd4f634f41efd6a70f16e1f0c9ae103a900000000000000000000000000000000068ba68f652c4f072a64d56618f93a1e148274b1b835433be878c06e11f65ff45b7cba0f67fbe80327abace68396da7e00000000000000000000000000000000047a699487964c98453207c98cc91c980c1ed37dc26e17748e6ee88e5f4c0ce424d87c82ca6db2264dc8aa9e437a5f25441fc4cb1ea8f86af8839aa40c35c0706f3a159b4bc902347009f744b73cee35000000000000000000000000000000000bf7e4a9751d4e3baa7ce9906f4378764e5384136944f6d3f3074dce66ed017759783c64fc381f0dd7512d6f6e55b4aa00000000000000000000000000000000006ae2a4fda156818cb5ea6120edf7ea39370eeecc3f306890f47a6dcfaffccbb69fd21f33fe491b7065838b277ad2b2000000000000000000000000000000000d3ce00c2f5febfeb232dbbb74fb0405bab86474d1d9c545c93b65c7892bdd58aa56225641074ec9b428efd9063085d00000000000000000000000000000000002552a8c1848fbefd6b039d6c4bd47c34dc34ab307163c4f6d337946f1d1b41aff2f7e37f5fd94012f0ebd21f97d18a83020a1ab853ef2018976e43cce2724105a2526b28d23b0226c49ff3d4a03d40c00000000000000000000000000000000105320cccd67b6ea78e96e66425a10a6911d2d348fac3231af583146273609fcd7fd27a19d4614fbdf05bcca0f92b927000000000000000000000000000000001204229ee1f66fb5a5dcc4ee978327e35d703ea310901be9c100af824e39d24a028ef8fce42370e5d734df02a26c145e000000000000000000000000000000000dd21f31f116681c1810bc36141cc18096cc113faee7db2c189abb7a746e398e272fa0cc61286aea0a5ec4008c8d03b60000000000000000000000000000000007911297718e98588844b9022c825bc4b37f2af30e1fc2d9cfb58b4500dffc8e9949afddd051e971fe78d4e1e7ad1b4a82702398b8c95c3a8cd163a8a3cb2a7a04030ef99404c325115e9a9312e8c1bf000000000000000000000000000000000760787190048e6ec8bc3bfc368f010e2f8aadd53164693a62b0d7207575bb2597bcec4bb382c57fe9053e90fe2f7159000000000000000000000000000000000ec525abbf13da64a8093c5d3fb800440f4c1fe798bcc71eb97bf2e0aa9e8be4b08afd2313f9143260058132d2607141000000000000000000000000000000000aa12c902084eb843daf7b351989bbab7a86acb62eb54eff0c7599bacaf44653c9fbf53f47f6ca72d22ea1671842eca800000000000000000000000000000000082f330d9a693f2bb9386fe5274aa79ac73a17688821f3c705120fb2aa76903627786a8614053f21a93e0aeb555de64e338468a325384a9367c90bd0450816a22849b845aadaf187c27b3f09800e791b0000000000000000000000000000000002ce7f08b8d5052d8bd07090744ca067700eaa1db61dad3e5086661850337bcab485c15fdd36c309a9e5169fd2a2b55e00000000000000000000000000000000073fa834cb4dc4ae120e738059749bfbd86b9e64fd71b1d372dcec8474f3341137ce8cb97a38955e9081f9bd5e07ab830000000000000000000000000000000001568df6806d8c3cfc9231802ebe5edc5d505198747a0adc24d0ac59f28d32b7b379d1f2c6b8352389057c7465692ded0000000000000000000000000000000004fb4b08a4fbfe197e924be3f7213a769a2bcd24109ae69a32a197b6212c5f50dbe8f46f5ab6044a4c779cd3e09d13bdd29136cbc4764346e7ae1af92fe64560f453821f96f32a42a2006b6edee75021000000000000000000000000000000000c07ff656904a47b0c7bf77540abc47cc6eee3e76b6ff0983151de9468ce3a860c427f3d5d489d096264159ab0567cd20000000000000000000000000000000008cce094ae1d9fff246a0e76cd67dbf9808c94554372fc4aed4879487ef240e45047dc201dd8bbccb613feb9c4623a0b0000000000000000000000000000000008a25297940a1bca1267fdce450b0cf43105eb4a21ab14562116039bc8379b1a3f58a7c117e9ba735bdec40f772465300000000000000000000000000000000000ae17a9b1fc3b0b7803ef48cb26643e8e78ef133f94bff5f87739182e662e2641e72383efab1f3ec58fa20fc816d56c675a59418f1462247d3bddda5937553e96d854b5df64a68145a193b2b1a7eb250000000000000000000000000000000002357e5a04b0dbd7f9a1709bce9b7afa12b10c7274b440b4dc3bf51a801d483804b1b4b9a096c3205a0e2aa7c0100c6e0000000000000000000000000000000002ff20af67f126c80293e44bb3c9ac74a94586a2de4146588c7ee8503530398eabc30f7e89322727739618087fa55de50000000000000000000000000000000013c6d06ce509fd557946479f2768f62474e6db04b2c92c5cfa86c023f79d05a387bd4c9aa618888476d4ecc93ba0995e00000000000000000000000000000000000fa477870c952f7506b879b17fb0a1c31771ee832ce0ab21a513fdd91b7a2a78a03d297c55558b834e255462b15520544a345719b40f973398a6fdaa2044037cacd7f6c361921c62053cd51f2e5ff700000000000000000000000000000000181336b8fdc03c02e23cd06ac975855caa2bbc1fe78a2fc7a9d0963c90a1f1f9330d50b88bf2526db6132d336ea5b8e6000000000000000000000000000000000f2d94d3fde2c0f67dae5a6ac12f713ccce2621303762e01961843eb9924d1d3c732b4c977d8cd0e5668adcd7dbf7dcc0000000000000000000000000000000005ac9ecab11c3368c75b0d396889dc34bd43ccf550d817c1dcdc7143c15d5c0e241add37328a7bd8556fde87d75d67fb000000000000000000000000000000000184704eeebead43f85b32d7f3efb9b9469f3ae10b73a2f034bd33e6e66da0bc36597d8e29ef5585443a655e24ffb68fbb38b4cd72eb18c3ac87860aa58b4b439712562f742f112b5d769415e9c19d0a00000000000000000000000000000000046751743f8f747e378738c265c1df3a368cd9570a2bd7636991045974c34039161fb0eddc6b813003e0908915b402170000000000000000000000000000000003341bea6cb81fc5e7baefd386a518d17a6f752c0e1ace5a9580a1b1649f5501c7b4639ba0cdbc33808d78b025a31f190000000000000000000000000000000016e3b9e8e189df73574a00a721440379589a7a6df09eca9a790e04c729400323b2110f63d547d83664c35227bd15b5760000000000000000000000000000000005ebd94e4640344e99e7e0f1619c6288665c985b90d99921ee61bbfce921265c4881a7e1034bcd840a665bae44467f5a94a849f6fb5a53bd5957e53ade1baee05702185b4d0fbb7c1cc0f46cb75614fc", "Expected": "000000000000000000000000000000000d993522760839abc960e99d62dca1021b52ddc8147929c4a064ec72570ffb3793205598cefab8490446453fb6da231600000000000000000000000000000000105db1e83fdff735d06d34574f962e70d84e2c1ceef4d8a8f14c2673633d7dbc7b97ba6dce9013f06fcfb134ffa2ef98000000000000000000000000000000000363be663cb0d36b8eb076df283b075ab9e568e460be804f197c51cf7ef611d8783ced304407d4c2540f1a4a04c18467000000000000000000000000000000000ab2c00473a2267682ecb356422aeafc893fab96a3bd27ae58d9b0786624c8fde446cf68bf8a003d9449702e345b1ace", "Name": "matter_g2_multiexp_68", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000a575d896b06c5ebd7459a70b9321cd0de082dce7dc0ce7e39581751d01b7db810bca80f39f521df0bf70ef642bd66a000000000000000000000000000000000ab497a9590deef40f6fdc0d4db2ae7b6ad9ab59f112a5a0671b48581f1f2b6a71602c73784ca6c0effce66a0a9c6500000000000000000000000000000000000af3812439e44981c91633f73d1a92298ca1ed426c98cfbdb50643cee36affd5fd02886349aa608f4b8a27452a51a96500000000000000000000000000000000013126db8b642d33dd988b745b07084ef86a228767f7e8bd45aac830dbce4136ca5febca5fda9644d3292203e27439d9f5b9d270fe31c772e9a0bb409d9f08a07887f045f906f30e2653d293b6c2c277000000000000000000000000000000000cc12f75fe5e6d6f082f9977dcce64c7858f3b6378112e7e083caf0c4b33b5811d62a1130c595937983905fbde8db1fe000000000000000000000000000000000308b803bcaf4f63affaea0206aa9f4770c21b4d191890602bb4151b80fdb42af0cd9f8dd2b1a3adfe28d0e49712d2290000000000000000000000000000000019f83af5cbee858fcbc9bca0f499222849b9e80dde7ac79b7c46785a484fecf274e0d4326469eca647cb223068a183d8000000000000000000000000000000000d0a8334171571bc63054c032299824523bd2476b1150a67eb17b84bba01d8a65295624202c3874e0302159951734702dcbf4fe86140c50618598be9185830bc1da11429162afe0528f00eb6698ec088000000000000000000000000000000000141cc01094391887f46391bd49fdedbaaf524cfc94d741cc7c8cf081dd7c425d81ea3e407be48127550012e39d2b0580000000000000000000000000000000014db31972eb242d6c2912b418ddf416fd7911f13aede9194559b05d1c9e12056deaa1e56c155cdbc231b39f4f9aa91ea0000000000000000000000000000000007b361beb6c156b5c8b92b489e6d6c05e32a4376d20ac3e1a54c94e678c88480779bb789c3e1ff7a021aa6d872c98551000000000000000000000000000000000215d270f2d3c5c5b9fa99a873fdc337f4edad6889f7a55556d8ccb5ee86b592453b74a720ef6a907bc342710cfd9cf91d7fb7121ef0baa85046567014620e1adfb9e8b3bc95adccbf2e0b0ea8f37c670000000000000000000000000000000017f5d31987655f8eaf046d6ea4025444924befa51c319b2bcb02dcdfde4d80a1c48049514e0b580e4bb59dd2fe40bb22000000000000000000000000000000000141ab771c08ad7c592725630aca0b2564de1ed8759eb3afb10a4bf451eb21d25e8d917f49bd5f7a06894baafdebbe790000000000000000000000000000000012dd82703c939cc5e7dd5bc3b924d744f0ef1a95fd0b9e57617e822e3fdda05b2e5a9959ec48cba0da40079da2253cc7000000000000000000000000000000000c53ff34d875fec4c7095af324d15921cd775873a3ba67740b2c123d6d482263b1cf93585dc810d19c68965cdbd9e102310d3b0535e78d803b477e5dc26c71bb18acfe66bd5ba5892d924d265afd6a16000000000000000000000000000000000a6514331035d42f58abf98b805f159921d8c4c935f88bb5493c580a6ce14a65e243424b41b3a9188e26a7f0c912a378000000000000000000000000000000001351e48b2d3f619887f4e83823dcd9dc15afb2800169ab78a2cd5ebdf25dcb6310f1051894bd2b549e509c55f5286f600000000000000000000000000000000007900972b84b6a76b2e686fa5757e98b8395bfc99da86eca122ce209afb39e8f3b07603cad92623774ed54d637e350d30000000000000000000000000000000002c68c42b3924b89a67764990478e48fc17aad4b5543bd38bcfee34fa1cae7535671f3b885852aecac53a30f28b0d4aa2fc9417e65cb76aa0093a7deb3d38c111c68f461a4aac57d8f09189f94407ee8000000000000000000000000000000000152d2c0e798d85e4dbf35dab808dd29d724e9b6c7ca7f53ffddfe1aef5976f2d3079eb1d3099e91b37d9fad7f1af5750000000000000000000000000000000015059423ee4e7201aa65e39116a2a49ba715b15e4b9547d18a0efd355de6f5a0159bc9047508bd3649407758d62887f0000000000000000000000000000000000e5a823fdc69f3928b22c542388f982f8131a978b08dde80d44e51d9eaed2ac4a1d5fa7392be6c7edfa33e833da4832c00000000000000000000000000000000044285f4e4ce526f96f9f512c5be754e0b0953744dcc04807ec6f041ba5c6fb9d5d395e93317064d50e61aae26810df0aa0b2d714aff175a0be2ba9e675a2be8936c42f15e304a146622a95dd6b3e3ef0000000000000000000000000000000019c457e369dbfaa130ee79bd33ca70d00a3797b6cf62126baec0c5d7c3fdcf5ba7f41195276dc412b6862b71560aeb77000000000000000000000000000000001206f67dee6521ede85573bbd5784d675fea42da16010544857d4e2d81b720b6f85f646fa23540880b44a6cde9a39f5d00000000000000000000000000000000142018ecd7c7acd4f4ae288e1c6a66594f1c7f31bdb9bade2b4dc4c6455cdc685b716382c54d67373831a19100185e850000000000000000000000000000000013b0b57463a3e4cbe063c0d4f4e998cbeb132a41c2877106ee60e83d4ef7d339a5432d30a3c149a42dfb1da9d61f34030227c3510ed6e4c7f84b11ddd2d6caa55e0e79ed59e1cc0cb325d55b5d145aa80000000000000000000000000000000008a463003900194e45fc2610fb461fde538b17c4fd516919000d423f5a1b582342ab9ec20d8eb6fda8fffc6a898e46420000000000000000000000000000000010eef0f7bf73e35dd75fb924bd9759c09aded9cce46b05e5d3c5eb3e93e5d5032ecc459e2220aa529d2f773c4b8b8c180000000000000000000000000000000002a0247f82a25468ee74da555218cdbb6405871f7097c24e89db3f3eab59b91ce48ac06e8eab2c049346436c846226a3000000000000000000000000000000001895b58a50c025e46a2cd0c59d5437f6eee75fac949adb7ee12d455c96206a33ec9ac17d5088fb773618fec131981ab6ad930000a9f82e082d408999b396aca2b0e435a66faba1d95e10fa0abc0625cc000000000000000000000000000000000cb0f13b0680c2f7de522a59f4e46fe1d4af3a64cd3ab97a2523ad3c3dc42f5e6760e06cf48e4db22ee64c5ed8273dd90000000000000000000000000000000016517038ecd2799d787c5b6ee93079c93f78de4a96449bc82699ddd6eebcedaa1d02981ab47c529652cc21663f1a665100000000000000000000000000000000067ae1dc093d4aa2ddd8b7127dc60745ce9c462a066106b099a7a07525597c72e4920bf64c2ea8a3fef3de51c703de8b0000000000000000000000000000000016374f51023e2448eee7c64115d85794996fadf4f76fd4266c45093c266f35be09e861d07ff194f3d15e310385705f0e1a6799cab8964c7b79b80e76be237ef49c2bdef5c99a38ea873af6e9d49790ec0000000000000000000000000000000017479396aeac06bd624a47e75b066d6daf5a37dbe515650cdf3e16be21e7d3a1f52a695c1c06382589eb7fc869c7d9250000000000000000000000000000000015c31ff36ed4eaec4d3927e62c111d062236e19fe6514236e6e3f7ff05ee96e3e4c084fcafcd21049a81faa1f84b7e7c000000000000000000000000000000000341b440e6c6273515fa7940d2f77018169bf6362b70a7b0cd6d66cd332ccc30e3ac48f7581edf47ebd137253a9c1369000000000000000000000000000000000cf424de046252efea9320b32b79bdab58e0e04f2916b4e8ef475da7b8ab85d8d5fc793a45ec6e6c035b6331a895d3efb206dbfd70e4b24bcc09ad35ce7b3aa62d17f18347f2bc5f15730202909c93770000000000000000000000000000000007c9111a85a6acb851e9cbdadf182096b720913ba3fb357dc2cbf2b8e796e9a8044b6df3ccadb740c73a16c3780c640b00000000000000000000000000000000059543a955c84a197d23cac22e15d82363c881026e41c57ee924da2a8c044f3021b29918d1db7926ddc2fc7a662ee7ab000000000000000000000000000000001355d8bcbea65a50c9b6ab59881e48e8e5f5592cee6aa69d5d01b033a84057cb6e74d911769bd2ab5f9722328aa204640000000000000000000000000000000011232571c95d0cbadf8e70454c851974efa4b326370249238db159a1224cc6d34eaad690e1840ad887a875b667ac1f193a607a7301bb7dc5b9c82d956ebb0bc54568d0654d725d4d5f13ceb6231e862e00000000000000000000000000000000088b7cbecf91721e01e5e4a08ea3b261febb58cdae3056d9316c3840b3e5720a289739568bec7b899f4b1f4f5372013b00000000000000000000000000000000001f8835d4b0e3b957e46b718b6bcd81acdb50ab85f10bb70c6343a23970efbe72bef89dbcb24d66e6a6be3eb55665a200000000000000000000000000000000046500afd292a31bb5a4a9bd7b5bd0fe608bb1265351edea69162e61f1623cf58e34e8e1a8ec58ca166e8203c86f84c00000000000000000000000000000000005d6cc367ff9c88fc8b6c35383f147b4f9e3eb21268a5a7405794441d449b3e1b44c8f66e30783e5f6c3567adf0d80171231e0fbbc2d98bfd1039a889acac471110d568b0a24ddf5eb3501adcbaac6fa0000000000000000000000000000000015bab57412cc5c7ee0147b0d2511b7836a14a82df06b4eb2b1baab102840ed04cad81da6e920ee000751e0727091c1460000000000000000000000000000000002f725e61e82980e6164cae7a2e30a36dd7245402f4933697607640d53fab2d5db57698be33a0c9b5dda14aa846db7c90000000000000000000000000000000007fdc589448887f6986efd817c63954d350511401333cb0df89214317dec0a82b06259ae9263f260fc7f21f98ad2630f000000000000000000000000000000001324e3bb46a1c69fc550fa8f2ae2d0ea74bc2d7159bed03c13a9d232233449e271ad1c3922dac5d84aae52606f77dcc0393c5c10d4bc4cd1567bca6960051f818e5c53704ce44dc4582767fef1092a870000000000000000000000000000000010adc26d73007e3b1cc58684fbdd7d197550658b4c66c702e9cd0f4e481f23a26c94c6798cdd9763110eefdca3d802050000000000000000000000000000000009138258ad1bdf6f9cdfb943fa32b42c4f1d834be536ed365d00126227c78b0df2776610fe5cf66a937cca3e0b088861000000000000000000000000000000001991db3a35bd2cd72377cd459502a84315422bed92890af906fefcc0acc4515fe7cacee1e4f360ba24efb23292482b8f000000000000000000000000000000000d10dfb682ae7a78b23b37b081efba32ff2011fcdae7b0f8a794a6ec33d71f5d6055f93e3b68a37086ab190d7d9bd7aed412195e347b680430c4528987859a1552ba8383cdc075c437ef19db6eff6e1a00000000000000000000000000000000182795b905320ee69281de833f37e040a3295e23be05ea7ae4563bd49d8b1fb02e95782c5c19645244633951cc29c5c900000000000000000000000000000000053368ee1412723b5c6465ee5ebddcfc00812e0e12e940f8485f44bce475c8897b324eaf7e66c0351ce9a6c92758c337000000000000000000000000000000000279f26c1e76e5f5d0fe1240c0956cd6025f6520ec303feb383b69525ebb6b2f199808a578a91368c3881a4044f37be50000000000000000000000000000000000ba4012c24dfe1038ec4b4565e1b321bbfc174cb197f0b0914bf1c126bdac9f423845f6742129670b7f3dfeaaa62df45b6701bc11c1ef3c9389710e4dd090e3db481c5400ecb91655c20694207a71f10000000000000000000000000000000016c27a3a950fc4857fc775441947f7ac02af9b3df6422874507b11f7b005c61d7d6a4a115d3759fcbd64633a8ad95611000000000000000000000000000000000e92954034df4f15450c32be31d4e146c4b0014a2b81e2afe755df79aa962afb05ca4d03577f15980fc6d8a34f2cc50200000000000000000000000000000000032db3e3c3617c16ceb1c8fae83e806744ca40cffb56bf9b79997cf48c55e5fea89db43b368cd922cd7ce30dd3984d82000000000000000000000000000000000d153fadc3854be49b2376ffcf4e5a46b9dfb4f54e580986767db13127e2d4d10e465f1ca932d79ca90f1971ddc0993dab45b07c059738ead9709bf36ab20b09fd3368f7aa12c6d9f3acf3f145c83fa5", "Expected": "000000000000000000000000000000000e1968e131e25d3f911284c369eb63aaf264ee82f4d9bd978b7d02470feab68ae82aed8509ffba875798a292f012c9180000000000000000000000000000000011488365570d9bff018ce6aa15e3d7e078368f09873ed5e0b827d1c25ef369d6571899c8df38a3df3135d0db814c87a700000000000000000000000000000000161973f4949bd72b9f010f017398778e0d7f0c8f77e12a87db1851af516b4540e3f4df314381f295c4d167fd9ac091a6000000000000000000000000000000000ae16f0a4a597159195aa47862585839485615095e538b745c1081ca73f202115a438d279dfa45bd3aef8d4043ec67c6", "Name": "matter_g2_multiexp_69", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000046eea8e5af344dc8600ba7e506e923f6c356f7ecb3b78bb3805c4561e808c1f570e122c4fc5a1fbe433b48ce0c15d510000000000000000000000000000000006f1ab405a46c825e104bc963d2b2f573f0d345bd2b08a952d8793c0297dce267a754b802ded4db478399cfa88e7e255000000000000000000000000000000000a5fc4a09019ac9649c07b623d2cbcd9f0cbb89d28c01b170b62544d8da8ba3f236ca3172ac754175a3db85d9b846cfd000000000000000000000000000000000f7580110db2549742f69bbc2850e4ab35a6e415bcd1b06220b9b009c1f4c99152289eedbcba2aa653f38f6b8460386b3ca13f8540eaf45ffdab5182883d32a1d35e7cd956092221cc40232efde6cd1e00000000000000000000000000000000026907ccf4d501265cfe67bc1c0b06840e9dd94a614c873d676b5416457d98a1dd744322887f1f1f86176b11a27d2830000000000000000000000000000000000cb08e541a5b32fdf51acb28ec64d3ea542c7bd75179fa3f74e9588156815bda9d027dcf5597d714aa001b2dd8a9553c00000000000000000000000000000000103ac1c03c16706d5936f216a6445577c96acd3a00a3d8a9c2c66e6ce568dd84a4c4db187a5fbde24e6ce60e037f53a90000000000000000000000000000000001da5cedccc02d0f8d1dd7e4d81c3ec47d432e81e941ea1452b112eaf40748a6634957c90f32fb0385dc5d642bf65acdb3c8b045ef559b76005875bce09a66b36f295070a73ec8dc66c86bca51fa5d4d000000000000000000000000000000000a0b8dd68918b58ca6b113e938f8a00b2595351777aaf32dfbf703ef3884f02c798f1b5bb78cfac32f196c1fe88aecaa00000000000000000000000000000000121a4104e374566f8d582f75a3c9b70f09628f116b7ab22679ee13a1691b0b0bdb0d737833fb606c746fafee5859f1ee0000000000000000000000000000000000b8bc89d718572ebdd6e3100769f2571cabdd79ef5ca9a4b9bbaa432b1a4dd752f9af9d2a9b1f1f32d76d4ec2d1636500000000000000000000000000000000129f1d760a12eb1a75fec1d2ca438189c933e87095b9fbf9a0371d64eb205d8f0932fde9ee2ab9f36f8b6e5d4b5dd31021953ea264f74bf64378a339461bff41c5193e17913c67be7e2a249c9737b825000000000000000000000000000000001499e5481ceeefcd2ff672df24e8987fb60872ed106c496178d71c68e9078409a80016e1f9727ed0d5922c93e821dcc80000000000000000000000000000000007bfb606c005c7da6b4ce2d974f9fdb2e3710c8f51f18257ced7663cc341ff81fe2e46308a2b62b13408965949a6f08800000000000000000000000000000000003fbd951e860e3a4724b667427fd9916ca4ba511a0dcac7b1125b14d8a4f4da82ddc0b0edab8ea50e911b0fcb5c200a000000000000000000000000000000000b43195a5f0263307e85408ae4eb046e06ddb1295a490ac4e0e654324de53d0dd023b8cc159d86b861dfcfdf7ebeee4a505655d72f1128ac0204539f0d823f076cb3a57a7e74e896b5019c9161d6486a000000000000000000000000000000000743bed2c17bea1ebddf750da504fe120f457cd3b1754c9413757cc48f7aef07eb4fa0572cb853cb72d68427e875456000000000000000000000000000000000102ddfe3dee27186a9484f74b3cb3aa366a79f0d2e36063af6e484f6a459e9168d7a4a6969bb720ec694a52db7ab34b40000000000000000000000000000000009bdf5b86aba4845adf9187ccf9c74b1fcabaa05764e41fcce4b38356b4a0ace8e7b16abfc7f7b96b785ad47fbf8e90f000000000000000000000000000000001934fa903b71d234c4341b2f49f8177334142e7c401553dad38e66a2c157fcdf7637165058955b7798a59051846dfb8cc4c861cde3f445e3a78d1498d98b2b947056cf578652e19be88da4a786af196f000000000000000000000000000000000ddde953f59b8591a83b0cdfce780ec23d052037c26d60cef36522d0f984f907315d7b41c8be9a9632f2b88e0ce950ce000000000000000000000000000000000b8d7bdd94a994901a434e6ea5d03ea45dcdb859e560833d8ea0bd9d20c7db9c16b2427eac27d8f1eb640b7d28a530fe0000000000000000000000000000000017b5b3a3097a74d9c1f1b23783723235b6148023b6b060234dd9e2f6fd05e38668167136c999d91249963e224f9bbcbd00000000000000000000000000000000133da0c217c31ca052800315aa8a3b934fc1f179e6247801904bcea1e28dec0b65632ab2690bcca3606bb1461aeb147b99762c5189cf154e24238e4b157caa1d8759002f69b289cfbf3f24f5dabf20bb0000000000000000000000000000000012778a6fe79b1f2b768432df036543cade95504bb7735ff547969faaa8db84e3588046a074838c9a551a4fb48f4a66140000000000000000000000000000000013288a3413d7e7edebd118463d5eea9f9ae2e10f51965480f9b5c244b05775d04079a1dc75ba0885aaa9e2e4bae1ac750000000000000000000000000000000005b766ad112b8d69f1a28079688942ea146f8f31616611909f539a57c58ec5e857da9fce415d683c1c6dcb5e74da9d17000000000000000000000000000000000907e5c3c83d3f12a68d6bf812e310f5a04f1417094301fab7d4f41007b9d01fc1bfbf739dceddef756417367ed5b1d0298b5f6b43074b8f0807086b03f5028709209310474c35c7ee232eec8579147c00000000000000000000000000000000090be6ce5ed09e45a6fd9ea3a9223fe43a835141c1c29d6b386e085846869f9c5798b80c3bddec8bc15171906dd417dc0000000000000000000000000000000019bdf67eb16f2708ca55fd20af8deca66e2ae270b2f2f9736fcf49dbdf7cee034cc956f6fb799f0e87c12f283a11448e00000000000000000000000000000000124a69c723cbd366d52919a72dfceb7e4cd9ca5b5cef1784bfad3f125b11d810328ea1c849602536af500261aa684f5b000000000000000000000000000000000bbf05318ffd81495efa4f4c271c8b1c669041a6446501788f49b8739a934f09de9d976fe7300b0ae861be567d35c992177bfb0218ecd8cdbc6dd9484e74e41be6971ec2911bacc8b53b9b4b8c70e5730000000000000000000000000000000010833a3e7329ad40c1a8cef296b015f6ac6542c612038ce00f13a99f673783cb7eeb14796485c168d21cc169065d051c000000000000000000000000000000000d3b1416b23453b893c92a6c7850cdc0e4a395459140391b1dce11055da10fb68f318c5561e1c12d991a28f3f544a5230000000000000000000000000000000014721dc58eada80f2d0574fb4e2c1c94c45fbd90c2d2fd666fd618a96f4736a5ecf34cab34fcbdcb19b6cf7b44098922000000000000000000000000000000001905d34029bf84617a956d1edae090853dc1b622f560c5289251447ab6bcea5700bdd80d6ffb2dc12fdf3b0267e74543cac52219796226385aebf9e85f5f179362d4149c33582a97b7d2aeb05a8e6a99000000000000000000000000000000000b4d380f4f4eb976e6121b933be8418c536f85994491b0b93695d50473615e41547ead326bab795d4d59524a61d607cb00000000000000000000000000000000104b7f4058c9b355d38908d715c311a53169b42d2434de0876f1c4ffce1c39603c4876b33fe3076528be15fe42849d3e0000000000000000000000000000000017e2fd647e7739366ebb606e8a326daa5c03cd2b726cc4cec7747cb3468419f1907126d7cba98bbbc659478ce3afee7700000000000000000000000000000000183be0a976dbb3b5385b544c194e111729c7a8d5aa98eba3fe1c0a5b69b5fe6e5d0164e96398cbc61eba5b86d91b3c94e03afb2efea85fcd035cb4ba09977b2e1c84a0d98edf88e9f8d2c4f116d0f50300000000000000000000000000000000023bc7eab817fcb9982cdac242cb6cc0ee1779bcefaecf144dbe57d5ae2b2ebfe9088f39f416a56de4b4dc04d4bbce7a000000000000000000000000000000001318e728c271746905788dd8f5ab22a3a10edce3fa063438e54ebadba22c29e461b2ed78a95a8f26a65b47022291b8df0000000000000000000000000000000010aab000b9c5de56623f18861b343ffa80da5ed4ae0d7767b7ed791bf3dd507fe7286447b6a07ea0fa12c19f2e4d8e8d000000000000000000000000000000000770e2909b5795a08d98dc66389655b1718e70b93c5bc6d805c3945cb5fc0092a5b390e6497b550988c28c58b6e016a3804dec43760dab29c161b8f4bddc52379a17f3168f684267cfbbc3505e32d5f1000000000000000000000000000000001259a4e36f5bce7d5f97184948d57fccd458cf7f2ae0c9e174f537bece01d744fef544447959cb73a678fe2c378ce3c900000000000000000000000000000000131aa575b2b94232e06879fa1f6f145a0bf5dd12456b698f731a72bc587e6def5054b3b2afb6dbbfc34fa5249dc673860000000000000000000000000000000011d64b923596c316b097a0752043efad8b61fbe068c58bec7a6766d9bc90ed965b3419dde3b96679426f72184adb8931000000000000000000000000000000001653af784cbad5a804e3f72716bb51e0c733014d587952c47395f953828566cbd7da811a3da1d48681998d569db00a7bed2d3daf616df3f0061f58c925e9dfbbf6e9cbfd4b0b3896a596919fb3d243db00000000000000000000000000000000077a9ab830f7683b7fb46676df09f72d773b65286c5f5ea86623306e5de51e63851c18d192c4c3b20af582bb7f017ff70000000000000000000000000000000016dc185f4158e249939541d35ae8230fd749988b9174c40c40b8c932aec625a7e94beaef9a07f492445d4675a01b7453000000000000000000000000000000000c107a895bfb45d33136db6251c76dc0461a235fa5d1ba7a5d216bfebe15691261b46c9816315c146becc328acb6b8c7000000000000000000000000000000001151cba240678efe61e3a36e169e314b3610e9d4df6650507f53ccf635d8f1277a80d86baa85a2d4c7e2af73934a7299e16797ed90581fd8c3cef1f30abaed10997f13461374ea649b29101959fd506400000000000000000000000000000000090a1ee6c611980e0421b72a122cb39257dc38d1e74ee41b809ad76e440fe307cf45e79afddd8d40b94382d48cdd4c450000000000000000000000000000000010f2e6e610eec7b7c2b95c1510af1af342ac19fd3b01dddf81b8961ead2cc57a8eca36c2f5747238eded5914e484c52e000000000000000000000000000000000acce0789cfff975b09d687ef79535c536f3b799157d3ff731915ea5b323ddd9f6f4750dc8e00a879d4e516bce8cb3e40000000000000000000000000000000008d8203dd13aee7363f6b10a9e1ae9b713bbc8b8fb2c56f05fa71e8d69ea571384d150e8fd01e855b1b0054fe7967a052f9f29432638c033ca84422b12ca80ac4ae85fa30ff56c913c5737aeb2c84d04000000000000000000000000000000000b332430c518d7dcd120b346440e5b6b48900b5c3656d84840823a96e5bf002816d583a989898cad9e09ba978ebc58a40000000000000000000000000000000004197b43877b833de7f69cc1a43ad8d6d3544cd10d42336d4b19a187f31337a37b10cbf48e72b77e4d8e1a1da68e5e4c0000000000000000000000000000000008887d5dd08f45034584f40a2a68254baf2104f9d6a4c2637ef79c5ff2503c246f7adc36559758a0c07533b66c3637d40000000000000000000000000000000009343819dec1d4569683de4596621c19785d5ed14ba13e57d94b1b1a108aa62cc8c55c58dfa18c06883ce50cc1364b95e6f1e5df7ff90c4a4fb9a071c0caf3a3997569538ab9837ed41d9d0a8d7305370000000000000000000000000000000003fc7f9a0804e7f1664f8cd3ca67b70ba128529a611c24214fd09674072a6b8d652ccd37bf5d4611424688213a41cb3100000000000000000000000000000000137a869cd7bde696035bd9353662e0d37d2aa0731ae55357df3bc43536b9210f360324cbb3670362cf9ef607b1919bca00000000000000000000000000000000045d9d39c04e257fcd912c54e57c86d2d4304e6a7cb95a83d2bff07964d0a5dd8b4e42bdb91a8b245e512395e6749f1f00000000000000000000000000000000120e5e4b04b8a744757812fc331e7c98b35624faa1cbabfc1470e4c0804248bfb0c53a484107a677a7d3f0d2b533e7530cf3283195707c30880e50ff5ef605b561c3c3c354fbe8108f93b36f212f9ef5", "Expected": "0000000000000000000000000000000002bed414afe9c7a630441e7b163280be10e502cf877e94b6521d14baca0087c5dcdfa39ff4a51c8376d99855e1e6f36a000000000000000000000000000000000dcd54727a7729408e682c6e213005687ed51fa7935c522312793fc58cdb273eec9c61cd8b056a26619fc8dc006b066800000000000000000000000000000000137286f4086763e6ccd5ee82d3bda712b26814a17c6a71006a3e6dbdd919e469bd0e744bcdb2074679e78a1e7d56ee7d0000000000000000000000000000000012d75de1310199c0e556d61d6c0395b406afba0f13bfb37486c05d66b446809e8b1a024e8fd2c55f1b82cf2aed99a5e1", "Name": "matter_g2_multiexp_70", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008b83142b22f6d6496cad0dea23c71355e7c5d98659580b5ee6e97eaccb9fbe523f7e3b925abbca3a38f67426f3fb35f00000000000000000000000000000000035f655a1b2d22ea21cf0081e78d7140bad08c4e66dd45230a113ff3b7a77e39f0f1a72991f85e2b00ff58b27d5cb54900000000000000000000000000000000105d04e38243ef1ad2f734a3c97e91506c5a7c5d95e9b8771b7fded8908f1be933a81a5769044b633d501c0df7b5d7fd000000000000000000000000000000000e670ae4af94d0df34a7f2d7cfbfcefa6eebcf2a6b2dc5b82068b023fe02ce8a279e1bb96d905ad4f2ffbd8214e47d702063b046a71c2674e35466657a85d8e02253b42517b033619e31a536659172120000000000000000000000000000000009051f1e636309016c5433cc7eb019c7dbb75b3a4a5b27f6927de08fdd9577e8eb9e12919157ed35bfd6607be7fc4de5000000000000000000000000000000001953b7a33695ede6d0792eba85567aa5052b8a58c1bdc94ee82b5001893c6b996d3e8f7af8b8effd6cf50656d8b85554000000000000000000000000000000000a2f769f00679b610bbe212c2f8045e7579a96dc6bff80899eb7715aabb1afe79421ad5000f2c7b85d4e0904e335ddfa000000000000000000000000000000000ec962a3d00fac14d05774adc49bbabaf46ae78325083c0020587fb85eb234387aaf6506f503fa988df8e9ecafb4a59992fa325cd07502c6576dfb93ee952fedb304022656597bf3bb03a2bbc471b32a0000000000000000000000000000000006823056a4da801cae430fb9e3a8663fc8f46bb6c180b743b7f9c7c7e3287f3feb1aad4be0e98409c74ff58004f8732e0000000000000000000000000000000015f7a3f692d55252fa5af5ec952f581b796d54089f13971fce2ef9062173664816dd9f37174294ed78681d8c8c5a9cd800000000000000000000000000000000154743c76f7de590a31cb96d46a0ec0fa88008b7d6684bd8f6fdaec70722afff7b6e88c1f0fb048714fb1072d30780e60000000000000000000000000000000006f3191946d0e7c1307a1a0d1ea9a26db195ec98ad88f9b8f08a03a3d48bbff1fa53ffc920f7db5ebd4c65911392bb834484e688799c3f0a3bbe00cec7322fba6245570685cd7df0d744473b72f03df8000000000000000000000000000000000355018079cd02dfcca15fbd2934a8e47c5ee89e679663488499ddd4abdaba7679fb1c9d2102317cf2798c47aff1ceec000000000000000000000000000000000c417d489a224fbba9999300eb65a23749194bf5302fdfaa33ff7daeb8d896e387e56600233038d5c5eb59f644a99b6a000000000000000000000000000000000f5a62e9d711293d4373bec1bc2637802938eb789c828939e6c42f10062ec171ac6110261165bd179206d649713f6fe3000000000000000000000000000000000b11f9fd0ef8dcac2e21ef09846ffe9f5a624ec246e31393b39082a47354fc9523dbd247f0059b6cc740d7a387b137f0fae2ef61a024e4d8c4ae277f6b1d834193df655ffb315da67afa4ee4ddcb7fbd000000000000000000000000000000000fbb5521cdb9c3a69d58e5c9cd7e4a50bf5469bda2603f5119f3209669eb3e374d700f851b0c7ac5ee3cc9de79e6a7ec00000000000000000000000000000000131ccc37581e64f6f9fdf675b9b63ceb67d9d5844bf512166f39b5bb09d8e031437c06b0ca01caae7ad6d8c9bbb9fd67000000000000000000000000000000000531cb0557fa18ef054dbff2e7e994f1af08aaea7557602a26fd6ff539ab3c0a73f1fe841177012dabed4a1223ffb5a7000000000000000000000000000000000a180e7a345d2b635be92888934608e8b6c17384c48c560f4cb9809ff995f8e70d83cd4cf0e96c458fc414e1275d2a993168a1007abd42bc398e317484149f2fa61174243fd1748deec6cc75e7c720a200000000000000000000000000000000125c83184f63dee35ffd2c0c7dad9010cd6a9735675099f24b465554ab3db727ee76b5b7ea603ead78795d33e37689a400000000000000000000000000000000141bdf7e270dcd356993327cdb5dabe38a5c5a9b53470d9a4aafc041c46fe8bc841089e337469bddab5d4f7fd3d6ccbd000000000000000000000000000000000f9613f6d05f38e3073f14d0c2557101a4864a7d6d0b5a2b931d0613f020adb99a1ab2037a39fea6e99fcfb47929827a00000000000000000000000000000000192d812e05a17d22c60b78c53fabcc55a0eef3656f8e84132faf16686ee18ab4d35767db9a384d42f392c40c7b0fe1c0f1525bba87baee35023d0976b4a2d87524ba74158f000e5501c6d06aed04adda000000000000000000000000000000000b6e1960e82586de19ffcf29a8c5f16cf2fcf5286bf42febef832767919abddc655a0d1bfa240cac8fdfaed5a1e8f389000000000000000000000000000000000fc1598454caf04414f1930f711d762f0d72f5cdc7a4053c92b916c742b00dd0f107aee111976c1b1218c4577deeb006000000000000000000000000000000000455d6e9e9bb848e0868c9d725edca1f50b279d0acef8c597927eda72763e3702f46b216919ac36b080b4865249fd961000000000000000000000000000000000174463cc7804796b4a6d8ff28d2e8cfd8361b2e38f368de30166cf3c20c474ea0a1e8d94749fc3e6468924a7d1369e62d3d7c014416f33724acaa46412348d350f93d334588d39c77dc0b8ffcb4cb1d00000000000000000000000000000000144e4b615ddb871bae85484c308423adceb5de387d0c7ffffdd2211b4ea28788eba9bfae96ffc46781e6d6343e2f501b000000000000000000000000000000000046e39cf43fd707ddc4b7ce9a8a22a2aa1e55aa63cae1eb23082f7b4b5dce49f32d2ff887b5108b40f98062c02d5613000000000000000000000000000000000b75b5460db2baca86528569b47209b5ac24930e2545cc6aa08c401a87ef2c4e233de537e5a857e533d0ba0981b24d7c000000000000000000000000000000000018f53b83072fe7daab226c831a89da63a0930ea86e301c97e639d0ee1609e298e2789d1a347bdb4afcd355fffd16d053bfbb1670b7045b6df689871d5d012dc93e8be65faa4a98a51db8501a4b7677000000000000000000000000000000000185b296e9c7209a9abcc3194b46be9a545666527ec9b0634a3e3be579447cb52330174c19e40e1667124552392a7a0c00000000000000000000000000000000158a053c788e5b914fcdcf1aebb4e21cc8bbfbcc20c4d692256b2ae48149f6644e1578f98d58b3e73d9768d0e7df643b000000000000000000000000000000001318ff4150bebd8fa612f4e84f89151d5c56c272969bc1f31a3c1fcbd8ded0e298914e98e1ca48248e9023cd12db0fd300000000000000000000000000000000076555254f382707fdb7419772a4978808a7409f59d1dbb8c9e648372e19c44573f5ce1888a2b570a83afc20e698ee44f944ee8d294d189226a6cff17456e2201d17d4dfcb78f58f8501870377a6e431000000000000000000000000000000000f4395e3f2e301ee3e18df3c23cdd142716c7fcfc23caed924f0561795948b0bfbed948a6f7c415ca615ee0ba4d5145c00000000000000000000000000000000176ad308c7fe8c3a1aa350fa82b8f8ec638f77bc703afe1042a6da22e5385cd8473ad789247f205214c9980532b12c7100000000000000000000000000000000092b0ec86c511992c66f320ad46c9d6d7c82df118a9ab2ce1f2c5611ff4e5cdc9193a39c3fc95f18ddf96e139688b00f000000000000000000000000000000000b4f671e334b7f22bd8d89d8c4eb8a52b04bbd4dd1259cc9caa1872093736680618930f3a469b3af4a00cb6e44b573f27de53613b7a31583ccb214726482b770029c0ed42f9528fa74da7d2d1dd915e100000000000000000000000000000000123b64561ebfe085238220eb1428b3a203acb01846d1e4428f3759db6cff4ed3c1b9d436706f28b77e3b92e2e39ecb41000000000000000000000000000000000ccdf1973693e4b43b6133563986f6c96e2b924895c813f8acdd0f39585e4ee95ef26c0d9d51d6ef88bb62305e51594d000000000000000000000000000000000f51693bd44b12188131ca84801bfee0ca853640c0a8d5b20123c97b369c98299ac04beeb27d75946cc6f45f8a07b5fd000000000000000000000000000000000804c6597810d2c75de94484873a67eae258fcc9577bafa778e13d4814ce099a5684b1cc94e0df5a59acc7b19328fb8bb0a9750cdfe0910c544668bc9b11ecdedf1b757ff69b61fcc838c502c2911bbc0000000000000000000000000000000009b02eea05c78a24adfb0187defb6810116e21894d8782605c1d590f8bdc10723bf71a1e5e5004b181504ac2deb142cb0000000000000000000000000000000015882389195128e20e50ec4f8d278e8b8791e362341be93c475064d640e1f8bb1c92a6c777d666f8644d471409bb9aa90000000000000000000000000000000000d89295f845f989e0fbc6e86e97400b08e39b2968fe6c9a141d1e92ec9c838a3d8e1ada5e44bb08189a5d514ebfc2f5000000000000000000000000000000000dea05d8e6ab50b8f8dd9632337948a60568724d5a03c7914e4a03e2af572dd8153effef1a7d5c2cb27765ef2c17bc5b4aadecb1111ff43894123648eea9e57685dcb7a25553233a374479c24f2f8899000000000000000000000000000000000bacd14447ede6af0e92e19b54c4f5b6ebfb94207efec3e9f385a4c84a7d670514ecbc28ab686b383e239ae7f9bd673d000000000000000000000000000000001698bc92d146049174b843dac8c5dadcee12d1d503b2d0e46ee68139dd43d3aa797fd5bd06e2b214cc9ae3647c98394a0000000000000000000000000000000018d20cf6c84446cadfa1a26192a04e16d2b2a053705a89abc51bfbfa35c2b03cd58021ad95a35364ae1e2da5d233208300000000000000000000000000000000113268e360006294fa0203ce58cbfd05d05fb625e1f9474c96c89c0ec1ea80fe834030592c2f1c182ef8a3d5c32caf71adde66cf749daf69a30f41ca00d251f7f1e93b0e7f916a1ba6b994d946b12ca0000000000000000000000000000000001727b6bfa9c601fe84a65c54f556887c4538cb5383a288156fec87420ae7f15da395886e1ac0e10b8fbbae8bf040f4ba0000000000000000000000000000000012127cdf02ada71f28ed036a417971b87fe443b8c65b7739795dc7067082cbc9f06f7bf10c709969281cd072490c06fb00000000000000000000000000000000134f1fa1d277d01e2811c118cf10e2de6324e2ba14efcf717a03c1a10dca0862ebde0f6328839da63d7d85f573e8501f000000000000000000000000000000000d20a036b715d18ac9e2dbe009dd0063a4b13b3ec6fd060a64c4ad2b98e05e069060179530410d154caa575d504c63b7b2f9b44c73a1a6dfba6462e1202166b63727f45dc3b8b3b73b5d06459a1beec20000000000000000000000000000000000bd5375e7f98d3972b93420a39fd6c31da86d0d9349ac3774bbef15c2240437cc0761b2f1245e805d2538cbca6f778600000000000000000000000000000000100232139641c8cd5bdaa75b77e1e1c8e33b3f9554e2ae00ec6315b82cc00a6a70d576d744e68938a299ee2b451558250000000000000000000000000000000004224691faacb007bde3e37db6c7486aa5d3b4259a24c8b7653238e7522604ef4ffc1eb3cecf719a1b7f52ff00c34399000000000000000000000000000000001156ceaccfe0396374c6dec5adb39f14b6f08a32b88ef7499756f5cc324a9f1553bf5dc106a97469f2c49be5d563e1100cdc89e668f7cbd53a2ef6597a48b93d7d9a78950d4f821f3935edf72649e0000000000000000000000000000000000010a549108e77f0ddeacdc795517ccdcb357f909264457cab22fac2b982d10064756d66d0e48af02a59f58eeb1e8ba14b000000000000000000000000000000000c68703ef1c1e93c78faebc5f7ccc69e39046fe8af92e12469e9fd6baee62a2e8cc06fbbb3def81ae5cc57f488fd9c9100000000000000000000000000000000064ffb6aeeed432629242c3843f8cbea5bf7fe78585763926c5c45dc3cb4d1c79b3715506d7cda18c531ef890b22a1f7000000000000000000000000000000000e0eeb69f28a552cc6563f5fdc9919423c4358a2b70ccd56b048c22111454f67107513cda2a5aa0efd2af25dc74a1c47e23b377ed80bc90a4645df09e825509eebf57f59d7a2aa1b9121ace80926ccf7", "Expected": "000000000000000000000000000000000b1913c672760f98fc6d4e96ad1ef200f99add6f233b17291036e187ac6692ab0a29a4083dcf86a532dd06efb3d9b8c6000000000000000000000000000000000323b703abed59a9824f34d97851546a5e78441accea4e3a933b9270f92a9dd1aa056858ebd1739659018a0ca13b96e0000000000000000000000000000000001603cb3ed75c09ae5da6b94eea6017dac0c40b17d9aa8b65b78f2ba17de051bf3f21109d9afb214d260a09391f5526c10000000000000000000000000000000019f3bcdb8f16d9a2bd11e3f9491266780aa9110f447e19f12f7a2d62dc4f2c7b5fa18e13792007f5f361e20656c8ffdb", "Name": "matter_g2_multiexp_71", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b7d06c16c77a57b5ed74d829ad6acd665e73d20f1d9285ebba67b60c0d1571e1b02cabe5dea44499ce6d40a83288aac0000000000000000000000000000000007e6ae768ee3d149c7130022f9883ed51e4fcf68c91327ac1fe85aec8083aa61a37e9afc25d3352e144aaf888f264ab20000000000000000000000000000000016f2423478e0388e8495a898c23d63a0929a2ee7cf848034e4c1adad3460c7070caf47631eb930678d3c85aaba044dae000000000000000000000000000000001587e63cdf50d6e0b6b3d7652ad0a0a2497e70259d73432831781641d3a76db4ac7cff1bef165fd8ba29200d7320e43475888762fd1de395fa80b6d8a751f280eca568de2947e953feac343fd6bd592d000000000000000000000000000000001181bebe3256dd6ed754b8a1d77ac07e9a341789b3f4a4988599c7c60a36f1e95d3e3cec52c54c0f0abe312ac358c28700000000000000000000000000000000189d224b2904bd45cd1e8fa72570a1e35c94680d03d30292892462664f9d7aca3cc45ecc0773e66a10248df28ba9a9a1000000000000000000000000000000000f654f4c8b02a891e14fccbd5a96228afaaf79ed8306c7c1267715bc934e5f2568ea06de2bcdc2a55ef708689d90108c000000000000000000000000000000000c0a413f16e1aab8b91a87e7027f067ffe7de65097da37d67f604a184c7e7a7af6fe59ced8c03fa32ab036862868b35018ce7941da132adec1eee8d81facdb5012a15ddfe0cd6751ebbf66ce6c495043000000000000000000000000000000000dc972d55b7e68f97191d988ae7be5f5301bce5c654b323d4c17bf6e070f7227c0789ee38af3ccc07b04f0793090c6130000000000000000000000000000000016288c405bb42b4e71d12fd0a798cfccc7d33aba0500f939f5fedbd0e071166169d3072befcc5549cc6963b6dacbef4100000000000000000000000000000000171ea4f6607d6efc875cd9cff203bc62eb83bdc05c07f702143c23ab2770f50f42738f748e6bb3bb5d6f51f40fea1d910000000000000000000000000000000000fb729cc9716bf2e9e30a598ee7c4281163b287422ab66b414da85b0b960102991c24cd023791e4241bda5b0f6ddd3424a0497c642dce3937d883ee25b0ea577c729366c7d67e2e5ff1ccde3b19a5dc0000000000000000000000000000000005720bcbc598c4eda697406dbb390c2aaf4bc22c794b4b664e9b85b7c2079b90f7678e69496a4a5cd3b46580b90a7a30000000000000000000000000000000001159788c3edf619cc5e6f77c4aeb4860764d46afac4cdce54cade63155040c631eed65c2fa11b9cdff14847950cddc2e000000000000000000000000000000000d61bf02587e2c61544ae8a98b4c742c26a3d6ca49c6ae1b19a9d69c7f8eca43cefd555c973145566f8332902217cec3000000000000000000000000000000000cc0da96623432a2c170f07a3aad2844c1c2aab9d1bb5d2183928c818e681c66cb3767be372be4ae65fa40bf5483258ce4e0ad0d478ccf5381470a3fc9b882639dde4a0147c7c82e50bb93431b07a1350000000000000000000000000000000016efffb5d4ecbd01567c1e6099c0f06644d4312c599579b4cb780fccc8a425f3d1263a5f0c957dda4508202a354162f600000000000000000000000000000000115686a37624ffa8272ec7dedb7a632ac568245918ed91be6c9116e0fde290c26b5291e5f57ba6a779750685b0f126ba000000000000000000000000000000001852662b92fb49b2f0359255db8a7a2d20bd37705b7994cef1eb8e318aed70fc37bb7af9fc0c32ab3efa8c0afad640570000000000000000000000000000000017a691c08724ccf0e668f2f4eeda692e9ac21385fea243dc62c37ca73421eaf51c3a60771da3fb3e3cb578de37d2d45d38573db9346a3c8de41af54048cc51a0edcb86f36372859d0d794f7560c8525b0000000000000000000000000000000006fe4276e8f2e23127853eb929ee4e0c6ec4a190d46ac222dceb995c2e1d8fc9f822806a877e6cf87cf579cb2862c25c00000000000000000000000000000000044dc671bcd516cf03ad98ccc55266688856a4e4e5a59d6a6bb93e9ca77c596b5ecd2db6f3cc6377a0086c53ceed5487000000000000000000000000000000000c3ca83688d20519423b2b5547afcccbfaaa088a90523272c7cdc9a9b0397340350f2a5ced2a8153d69c81cd79732bce00000000000000000000000000000000069916c468f22bad174522d7fb94b4b7d2a664743b4689daa5423f470014152387a29425642b50f9e50fb679ddafdafa02257ed12262d00e78bde574a9ebd2664484a446c03fe8cbb855bf92e56bc1630000000000000000000000000000000001fd452b8685b0806545e09783947551bc5f6446c9d15d079a8968a448a6fd6f8b7e91974b71a4b2c50954be299c4885000000000000000000000000000000000f28bdab0b0fd3e05d08ee2c51f1bc0d30380e3a7aa18d6e04b47018d6a8d2b35a8f06df3866ccb95ffbd9c5333ca94c00000000000000000000000000000000035f3aa1cff72df0bb10f1a6f8414aa2ad0289cd15f56d84061a7cc70562f1f12304c402c388e48dd3f34082aaf79eef00000000000000000000000000000000034730e3ad7a3373b97279a00dc7a053aadd088557e0da61b9aa132c5b402fd9aef73cc45dc1cb7f2076cb2ff27ae2fc76b9d21a3da0359a377c11a6d0a18bce7ea81d4128dc1e7618e6c35b9149d5c80000000000000000000000000000000009c91d800cb1d52501520b3625dd4c20173684bad8742c7ac4b35c0ce028556b6529de5cb7541e3c146b13f58ccae57800000000000000000000000000000000124259d345bf2f8c16215be4b6b7922f4e2d6b32f91c4b1c4f1d4974918fa9e6fcf10e46f0c0b55e2a7210d1a5336eed00000000000000000000000000000000072e6231244ed14aa0f5de06e2f953371995a567684b00e459113380c1434a8faaab8b28a0280336ae35bf1f90f1d4d10000000000000000000000000000000010289a63e0e5f1f35b7af22137e117a85df27874ba15df39b7c26801c169667a3afe9a14663d7ac0c2956f4eb70cf11fc9cd895d5d1ae0ae704e240c10d8ed4a01b319598d7885f7c3fffcd9b491f5fd000000000000000000000000000000000d0f22a9bcda47ffcd034618c15daebad8160f9ab6b3148f1cacb32e713df2ef19f706f14131f8ab1181b7ef7598e3e4000000000000000000000000000000001680314cd79fec583c8bc0842e1750b1318f94aa7700c6662aabd4c592ca61ad51a6876b686ac3fe3f508cb40192c31c000000000000000000000000000000000a172bd8e49637fd9eb611b590c68bda707931e403db35cde1c10bb74c389ed725aab54dcd7048285352c56c8bc5fd920000000000000000000000000000000012589683ff3f85ecb006c5c435ca7bfd9d5a6fd06eb625bcbcb18577cdef610d912e783f3986c965710269b1ff79ba972467604875028997efdf5139180a8d530a1e9f18c62ddac7753cc370bf25254b0000000000000000000000000000000009720c2b3a0658a4aba8e76e196a558bd155ff550b3e41bb5b43e7c5946bad803b1de64e342956a11627e7f24f69fef7000000000000000000000000000000000decf2262e8369d6a2b1ce07fdd257abe1c7610084ae2f347640c0cdb98c7cfa732dc609c18b7b6a51b47ebe4b07a586000000000000000000000000000000000e8a0158702ff6d6c3a7ed9fbc774bc329681130840d86ca3f26cf6642cb49e5f14ad95fff1c94151457b1d5a142bb5900000000000000000000000000000000035ae66137629e95539e09ee99b001d5b9a6ede79727d7deedcbeb5acf081cd05ad469ab06c265a5224fd5236db160b62f47637b64d28fb4facc31d5bed34b22e7b270431f54a689cd0fabd205e001ae000000000000000000000000000000000413d82d0b02ca706f0266051445c04f3ac594ad82e2f1fb4e8e0cf23a6c1087c29383238ad3677f170e99259e2fe93e00000000000000000000000000000000070af21f84895c0193f0b8174cb20b11f45c845a8d782b1f58182b149362e1368ba076ba702185fc54b5da94c3172f5500000000000000000000000000000000182e124ca29d66f9f6c370f6065f60928b6a8f445a74800d59209219add6cab0d1b79702c31d60e61cf56874a4eb6717000000000000000000000000000000000b94b733f76067a102cce9659292f31f3df2cf2770e3a83c1524536e29d0a84ea5c4883cb4e849830384dc7e157d8715474c3ac61d4fbece967fbd0599c9a92c3fe0e53899861f044308b0ea8df137880000000000000000000000000000000004b2feedd5badbbdff6fd0f33a4bee17b38cc8967fc72206246c349e1017ed0407fe08e0cd9208fa9e4e21eca4cfbc2a000000000000000000000000000000000df0d74d5cc17ea94457c0ee26ef24071700a0fd6bfc762e3ec69b8f1c096887f679e312f07cce8340686eb2716c9a96000000000000000000000000000000001878edbfff2efc5af64aa9a23589a52d63749b7ab2970f256874fe0cc15091c4511050b0a243d421dc6536f19b5977cb0000000000000000000000000000000015951da3b20494a266e4d014d0ec70fef4586c8656baf536a0ea9a48dfa041624e8154989a2fb106189217ca979ddbe8eaf9da65e0e1752a982601e9a070a7cc77d5007eb641fffbb78d2a1b02dcffec000000000000000000000000000000000657fdf40c829719db134acd6c2a9ff904681b1869f28512cbe2a64d93e5b62114a73bdc5260ad9a1f24a3ff191b7a3e0000000000000000000000000000000004e77bf63eb9c4741028dffd0591b4f525d533b455d35e51cd86c7884d63419a162b145752bde188d2a622251c087f870000000000000000000000000000000016cf02af01fa6750b4d862f0cdd5a87a79da7c3fbedb0fa356ef2e7419e25b3a2bc8cbfa97463d463d0ab349efaa3f2b000000000000000000000000000000000ea4468fe6a85d36ae990d0ba959ae050756805c4c769c829de475a2990ef1c46de20d5b466543978faae0f6045023e85158bfe535fbc342e31f32ab4723c0d9fe95a2c64cc4e59bd41d13a08ac811780000000000000000000000000000000018d42a2df8ca475be6bdc468a82c313599239b974ec3d27e8b8c534aa4d6b85d4ee9aceb15c38b3bade2bb1706a2c2cc000000000000000000000000000000000124d5dc60527faf48f5e9574308f8a328b410de1cb49f2cc6f76b8a1f2707f2d1a94bcbca0a97bc38f24545a8013b250000000000000000000000000000000018b690b3d1e3b22946a91ace004e1d8f92eb5beb284eb05b52ac5ba003d7bc387540d33d088a02711522e3aef7f74f4300000000000000000000000000000000103080d8bb379d961da06bc4c148cb5b056ae115b3a0e33f0a8c99a7fb7b7ceda35d3902e0733156d354dd0240e4bcabd66f5a8f37a7c6a32088897abfaf5a98bd4722c411bf4b52f0f5b5648e89df29000000000000000000000000000000000f4d068354cb5b51e5a86163978386533f8f9b6e388c5e75f7d9ff5e1ab6d1637717d251f2b723b7d683e26a274d610c00000000000000000000000000000000001ec5a0d408c55f247d62ffef172ef26e45c41029f1d04e36f0dbb4fe8af414b0f7fe7ec0cfda66a2855b58592486fc0000000000000000000000000000000000cb1b68045076f457746621cd415d743701bf3ecae8d52dd5582c3e0bfb38e6cf2651a5ebdf521afb1ec5b8066444210000000000000000000000000000000010f5672f813470378fa806abdff90edeb0239b00d85ff23a3fc6798779f46d6b43071d66f7742897a4e53ebf6c7dae719acdd24190589ae7823a42e8b59598eca12bf13b97aa9a0eec17f5f79a01e8df000000000000000000000000000000001422fbaf1bc2908be5900968af61ffa7b3af46e7250e4663ff321f42e2db057bcfb2106c433a9eef8fe20f7138b71d280000000000000000000000000000000002176e68cdb0ada2d7baea437bec8754ea293d14afb85a811f7a5d740d645a53e511b5605445b110174ceb5e6720e736000000000000000000000000000000000a69e992b6f4f7eaad2682cf9ac2e58faee9b3341e852543c2aafbff390ae067a641b2b5693319618fde413fdc64d6c10000000000000000000000000000000009440317af8f5c753b5de4648b06212256a39b7fb03678f1913b0a3d402a50e74e2da5d29c211cdf0b292c132759c36d0291be87a213b0a24c92df5ce42381ca378dc4b9aeb4cb9b6918263bea827bf8", "Expected": "000000000000000000000000000000000fa31d16d9625200c13a415fd61b7552646c62fb8db307e92c1ac3d2acc92336765a1db42407ab0f774ccf01291b9ee800000000000000000000000000000000156a77678873dcbe4832b9fc7f516eabc1a10f4a6576cfb15765cdf999a771a6a6d41021897dd783e9beb2db722a6fa2000000000000000000000000000000000ee4599a6ca9642cb4cf38f5f2af23271cc8c5bc6e2cf6bad572b618bff9f8677837104b93ca8942843fd5db5c30dcdf00000000000000000000000000000000138986714a4053618e66a85835d105f4aa2ef38ad18e34b2ee7ae30a4282f7e543c80c94bd12c244506e7fcba25f4c1b", "Name": "matter_g2_multiexp_72", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000083c515ef8509b12ab85ad7d0a816d986bcdefc14778efcb3bf7c2ab61991849f279ae6a9f5342880837c0d0f4a4eba700000000000000000000000000000000020cf5196b5d567fc429cb9ced7b55e4925e18c914caae216a736886a8d886c4bdf6d704bbd0ceebdc1975ef530c665a000000000000000000000000000000000f3d0a217c224434604d63cef559eed3864d2da62ac00d49fab8c2c6e22c688496adc30c8d591e21bc0be404b62083c20000000000000000000000000000000003d0bf7f25bab0bf2c768b44e10a6022650f7d5b7d568d502b9d0b28209ee69b1d952ed848572d3e966e8771c20becc4b14c6a38cc998df3583228080ea10f215a6e6a4b02ddb6d43e8f459d494a1ec1000000000000000000000000000000000cc4c4b7eb7e358d4133b65e635fc13b8a92229706a6dc5867171a60a99a8e343045a794c368f1133ae6cd2788c3a7db0000000000000000000000000000000019508aa39fda9c3efced287d2571db97045f8b7b0c7a9c9d51796aa8017fc0e5abb8fc994700dd5c9f755edb518e096600000000000000000000000000000000049f68b0ac142715cfb385161ee70e453f0e24e2e93f3f96c3d69447f3a28b180fe76989427b2e392c7ff939011e04ab0000000000000000000000000000000004903c0f8e0757dfd3f5edb4f54a0e292df15ff70757df7b0b04c99f590a3dd13c6ce7bbabf3e14daf9f3ec60e2379aafee8614394c8109338432ec72f2d9babba06f1e7b826b0f2558c3247c923b23500000000000000000000000000000000041128064ac768664f076116247e0f8a00adaaa824cd6fff33bf524d0c76e61203408ac13b294aa41f5c462cd42d3cec0000000000000000000000000000000005e150c27979ff1cbe307511816be900648957624caed1f08d88347061cd783179c615258fcf3619bc4bfa53d2513c610000000000000000000000000000000009d2b3d97d29386b93d7af014ea8f1cfe2c1db5a9aa0c17e8430b0fcde974a4e7b8b42ef041e9a7b1a8aecb97cefb52e000000000000000000000000000000000d86096ebd88b2cdaf5cda1e9ca6b7f12ed5def629354b0570eb084bc7139cf20bb8ebe4438f87937b8b554e2201344c28728d06cd90050e44a827b44f14ea35e83c9b58ce4c3a7a45aed6f31c94fb960000000000000000000000000000000018d677cd67e96b10b671d2ed9234d7708042ddfe6fb804d2e9371a80ad167004f9d6b92d26b3d3af34ab7caa0e03964e000000000000000000000000000000000e34a6c85187d328eb33c2d5b2ca96b5210d47a779ab810dcc380dcb7e6b3c334ac8fccd7354aa9108136e4f6dd4ea0a0000000000000000000000000000000000ab8f7274ee3fce1511c58661625c766ffb0ac68bdb835a948b09b7510bb573d49000000e3d3cea772bd71d79681e1800000000000000000000000000000000135ca42f2103905748a1c416d82170f7d24b49ff3f859d6cb7493cf89bbae0217529a9edc835be1f9890ce105877af630fda665c40d1da93b1f132070e0b7c8c2c0ea0e66993b5a3d7419a33d118d25f0000000000000000000000000000000007884edaacca499491580c8c7194c0d60ac6eba95f7a81f63742451c8ed21a223ca545d5cc1e648b9d2dd05016b4fea20000000000000000000000000000000014c78d5d1a93760096bf6da73bb41631e94d6a1b251ed0be7bda93e4c50568420bd4d49e4a46e5be4bb204cdb6b0ad5000000000000000000000000000000000128a860c23a183c5bdd18b4a1853cb53475f1a893420bdf3271cc4a65a827eba6b92e1f9e8ac0d10c73edec5160c640b000000000000000000000000000000000ac14b2170042ee6561c34f77fca40e1bd2d40d01798417dd954905135ed9b7772e5689e6d4e543d44a4563da8c3ca40c14f014117a74f21e0b698a257ae8e3d6091ba76bff7912abb6bd94d41886d0500000000000000000000000000000000144df2e76821c19167f60630f50c939b66867a82c2a5f807e943676c876aeaa2aef2126bef7fc431f0c7b39e648542fe0000000000000000000000000000000005e463627bb2d22c25520c27c05cdc75e1f2ee3b91e8088399ee42ad13ca217284596e5404b4370995f71fdbf1c1c7860000000000000000000000000000000012323010d6aba1bc6b1d6e7f7e8c7bbc0838564b279d5ae6279f7f7d3cb5d96273e27e7096e9a8540463ad16deb3780e0000000000000000000000000000000019102ac6bb33bd1c5a158a584ce32308b6ee5679dd6d2acdcfa4b9c54674fecad7489d1e39c05b1ded88e4ea93620724d81a1239ad2c945f1c560fd1674ac7e87d49aa41a1f4a5bfffeab1147c0ef7c6000000000000000000000000000000000faf210330693663c8a1d1fef78e211ed2542f7ffeddca3e19be3ba77ef211da1b8bb5abcfc96b692d74f8c7df40b0ce00000000000000000000000000000000134153a252fd8ec5d9aec08ba09a94c4416f95ff6f4ccce59bd400474c836af5bfd941f03384ca4bd5c56fbe81d96ea2000000000000000000000000000000000b4532ff1ceab2a3a177cb83a75c16a833a2ff28df447def351134ec4fcd608b2b75b1f8035ba7d40a737087f3e8c1c100000000000000000000000000000000127e3ed13384b69819b34ef8705fe9a66dd01b275f1f74c2c724420546b39c70cb7a8295a6c1ec4075ead4e3312b8b603a02689cfd2c353fc1b4d3913f5a43745fffe6a87a7c223ec3b25b321584a75c000000000000000000000000000000001351d0d5d531a63a5f56aaf1d7906b7ad2bfb4e9d823e2659bed4e05e7edc9179a7bbf13405ab5cf410b25c7d476c342000000000000000000000000000000000f0ec96128e058e8bfb6e0df1331887245dee87c4f9721fc7f1d20c20a2feea7a7078a4946803ac093477707598d59b70000000000000000000000000000000009399034e4aed13cbf197d8c4753285effa72fc53493ca316db11b39d5527b009aec6350d579f9dee22cd6d4cabd88ad000000000000000000000000000000000002f41ed0dcfa2437cad7b12a94501266d670ed6956196c438241aeb90474d17214eec5d5217090d28892d95f4e40055af95ab3fd062088ffbef6ed887fd39aa1d527fe7633b876187ae12e736fcf2f000000000000000000000000000000000ae208978a751f8921c6067ebab4190ac8d3608dbdf50222eec59460095b8ab2abadd97616c240edd0a9c53dd006e38c000000000000000000000000000000000905224b317a1e64d8af075b6db9de46ca4481458ad6bceaf726ba0f63e81e2a0322e79e70a5a82034abf00d47fccc300000000000000000000000000000000007173c3359f0c2e315d11d646a76e6f500c0922401e4bf9f4ccf2f0801a567fa653f287fdbfb878ba0d9ee12e25396ef000000000000000000000000000000000161d4cc71621e5df13d121c77105af195c2adff5fc6b656b0fc1dd6eb2518f474444d8bc526ae16387f23a4ab3f342f6541c6cf8217c2a95792900e8fc39581b177a57ca00162c57131ea4fb80a4c60000000000000000000000000000000000266af9991c393d3b55f9e0f22b0967d47dbc5b0c97947125e220c4bf9f4bc58d32ebc7bfb02b2e329c933ce41d0d8c00000000000000000000000000000000004cf5748aae8dbc1e4778dc85da575de2b6d9d346f5dc5ccbfd82513166384111f5e5f2f1c2f7ae367a22146d1fac027000000000000000000000000000000000095dbe68521b2cf51283a8cfea1f20eb7ae37e6e945c5f879ba4834d20918b74981f9e0eff4543a79ff4eb36d84a9c60000000000000000000000000000000007953cad14379ffd4309cef1ed6a2dbb73a93db0bd3a256753402e525bb62b10aaf22b662bb2c704865690af995e7d284b7c3f3c4ed10bced85f36fd6dac2646c65d3c810e6d2d116c38aa5e10b29c2d0000000000000000000000000000000010e99f318111baeb1b4611847fdaea7cbd5e3ae532af667ad2498fb2e97b1eee0297e2811c7ae854b882f616da7733fd000000000000000000000000000000000e56cea75b4c4e4c669a492a6723fd60e351a66dc5c34c46469dc36cb04d2c23cfd4aeaa23d0e9e83d5b78a1b77696ed0000000000000000000000000000000018f838d6a582a52a508cbd6bbbb9cf515e091deb7a640e141dea4018af6593c001dc43a8fe4819a7877d9ecf53d5752000000000000000000000000000000000119aaa2ebcdb6379f7ae972cb709990a3e8254f1025cef308281bf7057295e3099d1f3127f76bd2f9ce0a03ae0de8e8d7e33f394e96d17efa30d34f57eecc45d7b4ca150a31b8d0484578151d6e65c2b0000000000000000000000000000000008f837c478e874b857f1c939a26a02e13061d50728c10939ffcf5e862cb177993e204590699a28cabc7593056617d433000000000000000000000000000000000432d9e66dc78bb58ab98771e7e8b5fe51835f286b488e2df6c1991fd36c3c537f2ce30abf24f9d4fb13941189972e39000000000000000000000000000000000b202de3708984f44f7d05ccd9e574a2a93a285d5ca262017346580be273c58f13165437dc90d1d4103d3b9eaac536ce000000000000000000000000000000001873e1251d9ae9448de8e7ccb7ca59a21bcc0d07a2819d140c06ec33cbba559ba90647494a7ecdec8b609b58cf7995cbfde92a31e571ec03e509ac8a70ed5788869854eef0bf578efe6c5e6468315553000000000000000000000000000000000084e07b6576c73aaf43c0ef9c5666dc988ed93d1a106b71e4882fc0cfb5e710b91e5d5eff57327f5678f662f4a451d50000000000000000000000000000000008a29751f1653236a48adb5fbc59059c7137d36139574c6af97314bfbcc22f77a4c5162092762a26b5da7887b94f2da6000000000000000000000000000000000a4fd84c4d58cb9e18aeee180fb05f07c3e1d7ed8d09940182e9b4738744fa6faf600b6f720441e0ad6391a4d502ac040000000000000000000000000000000018b356be2aebca82c54988ab2a2ec58751ce7a815f3dd58a2218a638753d4734d38b74ca0e00bbc8681768f5d1a02b646f7de01ad0f7b4dcaee1123bb80a71d3bc1e63ca577a12b14ae2a11d8c0fde46000000000000000000000000000000000de0f22cf05620a5d4bdcf50ae179f23a9c089fd6eaeb14eca937d9e2480f1782a1c67df76e06191a9b87514daa8bbce000000000000000000000000000000001981cd1f260e7d96e55533b8e29867f37af507b4a58abd69e0ad6af2a55228ab1c82fc2de52deb7b7b7deae2fe621e10000000000000000000000000000000000d22a7a567ec8826391ee711768e612c403e3c16e20947ca5861185c24728b6c7e7756debb333e7acb53d86032d5748900000000000000000000000000000000016fad52e1e86b9e092955cefdf93a10f30db896fb519fd2ca12571d8dc8aa352cf4f8092e0e973d0b0c66df78433251e2c69d21d40813ee40a718f0ead36b51f3a50e9e4e4b2de8acd33add62bfc1d20000000000000000000000000000000000484bb2452158bca93dfeeedb40745bc5d9a9ad49afa20e6c29fc9ed1a8fde33ce508cc252ddd05fc486f8ef78738ac0000000000000000000000000000000003c2d6ff6f292b0f0e505fdfdd2940e72bf8c2837da4ec9c74fb593fe3318a9b9a8592524bb5d40f6c38ad871ab7b6150000000000000000000000000000000015f888ae2722713e1b5b02803a5b48d53116c1a4bb1191c9da77ded8c6ab49f1620b0f7c7867957d84503cfd3dca1be7000000000000000000000000000000000fd96baa382cceadc252eaf000d47d8c1e2085e9f274dd9dbb571bf85bba612836e1da2453fd914135842e2750796b54762d89025196aec4f87da2fcc5a9188b4dc7b1c014dd1d705223bf9fe1e7a7d1000000000000000000000000000000001820de289f62058920ac3d4bc60da023ac29c431ee429a10066f305d2b1a333ffaa906404af977cfd3212b53e66726b500000000000000000000000000000000094e448db84421e25cd03be3867125cedc7f77f286f404524757f3c1a9cfa28ab6771293da490a4d75852f515dfe1a6700000000000000000000000000000000097dec124970bc63d8f62f9133157d412f5ad3fd5eebb444568cf0fe2825d6ef6577ad302842f35570c9977638c6a827000000000000000000000000000000000490bdaabf4db27dce906cfacf3160c0fe25959df4af89301cbe6eeb29f72e4c55bb467841ba7d0750a59a32fc8b03d0ffb9f3e1d43aece3af1f59319a8228cd81e668b1e250d03350958dcac9e23843", "Expected": "00000000000000000000000000000000193358b283147ed5848559d4d1533734822b0248dd17b2effa80920a853b70e7fb683b08aad6ad4dbb91f964ad1b3bb6000000000000000000000000000000000649be60ba72734db4cc307a2fd8be57857f60660d0c496c0dad73794296552e17cb2eabb3537ce677edaac1c6997341000000000000000000000000000000000f91ce27345e86003c99d133eca50710c0722cb35af2ce442ebd74b46d659e0118be9bebf32111c258e4cb4ab795a2cf000000000000000000000000000000000d76ad65233522b1e079fcfef4dfa80f163682d7984d5062680a5dd4cbccd5044de4705013c6bce2140f7950032f90ec", "Name": "matter_g2_multiexp_73", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe4afb94d08ae311b7442de7291a11e733d8e555f2da6f72bf99da780a8f8d357cbf3d8959f6aeaca7bf3f5b5bd10500000000000000000000000000000000025af713b18cbdb5a960371c2dd0317f4bfd0182f4bfd6b88d588b56fadc1a0398412e7e0a786c326aca8779ae384243000000000000000000000000000000000581c277053c15df8eec05c34267f62e63faeefa2d124c2b4b84d2a739ce5484641ce955fbecb901d1e8ca816690189b0000000000000000000000000000000005355dd304b9b60498a3fb1f08e1ba0c98db327365ca9a0365a7f1e5cb56aec43b7fd2b4aa104eac7b1c30b6f53cd422be285a119dc8cb32b1a0c5380af736114a32e9d1ca870abdf278dfa84444f70e0000000000000000000000000000000016b5b3a6fdeffe5b9a0244a333ada4444a2e03771f94433832a4617be696e467b4e88ed80b174809dde4242bbb51248b0000000000000000000000000000000003dee846c5b84f89734016e547c63c02e4be07dbbecc86f811e2d8d3245f91205bfc055882565371db532240da1a845900000000000000000000000000000000194d53bbfa962def4da2a9bc7129fb6242a3922fe26cc4e603528ff31393a31d03dfc3463704250ea2ffa973ad175153000000000000000000000000000000000333768faee332d7468119b9e0469bbc7bc98a482562ff2fd9aeb6d9c67daac9c3da1db41c9e12224a2eff2feee51778bc0535bd504d7b9658e459c2e79b86bf4e718baa82b8d6e624fba0eb141c7260000000000000000000000000000000001910ded86d79f9b043bb79cc4049e0652c13d0fb8db2f070d695124d7a42cc3a2238282fc8a424fcd8d9ecdab4bb6fad000000000000000000000000000000000dc8d6caf97416928d2d58466219f054c6f28f49b2bc04d8a80cd46a308bc95aaca3a8df1914ab0c7da341862fdf47400000000000000000000000000000000004380ca7b1f7ef96295589f78a1683a51bce4b2afe50bd6076ccf5d07d35e6cb2ec7f74fa35097b2c0b9fff3f4797c1100000000000000000000000000000000054f492d7442b1c0d1293277d95efe822faa7d8881b9afde20db58d6267e049b90d0c8828a6c12540f4ba1e7c9ace6d84f3fa09243c01748954d84f4deeb460f3ef78f9c34296c6a092952bc463d7284000000000000000000000000000000000bba4761eda87a304a80180c2447a1d5a52f743015ea7c728e70d6a5defe3139c80696f842da3f06586be8d506ca4bc90000000000000000000000000000000019ea930d5733f4a1ace9fa0139d412d65b2886b659770e388894592de0694d38876fcd86d14580f9b92518d5496fd44c0000000000000000000000000000000002bf5d9a36d641d1259c1b30397aeb071b88844c4cf17e3de0984129d7b4d67865157ee2f682e7cf9d968fc07ce43618000000000000000000000000000000000f9a4f29868654abafc7ba935aa22d3d010023ef5112683a037a6c69b9e89374b256b8e1329eb5ad306d9f2063c22c335d84733ccc41f71a11d61852fa336df566109c5538c2c5f5cf2af961e93797fd00000000000000000000000000000000004f194f21373f09f8cb4984169890ad3855e814a4768c84e9fc97dfc181c60114aae534a27d3eb225b2125131c754ee000000000000000000000000000000000e6f88880e9645e35806d193f5d16799d63e2f9edd8ae28df54d19875c61857b0a34819a70ba3e9c31f00b5826b0cdc200000000000000000000000000000000193293c6cfae9ae4b24519fb23469e2f8dc4eda8524ee0b00c7141587b07c8a26a29841d41cafbd24bfbea2034a9c18e0000000000000000000000000000000017433efadfe9873dea9a68177af3d5dec4a13dcf4a710422d52020d4d145e2523ec0b48acc533a1ac7068c08ae6aa28bfeeb95c32362014caedf2a9e066a775e2db0d1322edc86759faa99bd70c05b580000000000000000000000000000000011dc003f7542f6822cb872117fa658638dee2a15429aaa9dd576a7e895bc0a2160bc120558a32aab9e646354233a1afd000000000000000000000000000000000fe9ed8ba572ef7d1176176a31fa92a5ff3dc38b0183ea1e22618e3b3214ee78c53074d4c60b5056901c6f046f8210070000000000000000000000000000000006ef1c20c3bd88bd6787598dcfca52da4e5e0e7c7643af983c709b916e71fd15475da30d763ddba0899b182cbc070ca20000000000000000000000000000000001a38a2e54a44ade572ecde076038f5244f266cd99532024a377829a64c20fb2cfe1633367c74b5990febb08e776bc34edee2ea28b93b2daf4ff927991769a9c69ba16490b5676074e64f5e91fa994a60000000000000000000000000000000011ce7b2cba037e5f3ff19b36371d34e287eec807178dad4118c6d43aba68623e182aedbf911a2ae5cf3d0e690ec3ba790000000000000000000000000000000017a617453f391e6e2437d56ee831ba895084f60d1a5f342e19a242b9661c703219d90a157e1b55f005f5059c15c179dd000000000000000000000000000000000746ab134c7f4bc19583a4ea4991c7cec3f651a60582b40c17b2d18cf6e252d93d2f3c2a1a3399be70512ec9eab251de000000000000000000000000000000000698daf214f2de44ebfaa36379862bd9ffb40987dfc8e632f14738c93c8e5c3fc7be9fa9100fb5f7440311cab34fe1897a07e50c1fbf1b388e9264c762798c31fe76761508d070f06adc63130df07641000000000000000000000000000000000e4ac65ce62180ac602ad68098ee31cb747886e95a183e4f819d54af99850d70496e6952076084dc7bc2d3f7a273383100000000000000000000000000000000182c718fc9e5cc961426258e82594a5cafc36270af0eb50646d161fcc192c30d40d06647e14a282421638b31f378de940000000000000000000000000000000002bf448ebd27cb6270e1b87087796ca6534ff51ba0962f3290ee1d06dc18ed39fb736ec95632b483f44d3a9d0e45d1d50000000000000000000000000000000018b956acc1300e60b22bb936b2b52e2ae82e256f15f1415263157965179855137715c321d3765c5227dacb63ba2d6225f0056903b4508cffb6334bb5f645cb553a8cc61ea6765283f933686f172f8360000000000000000000000000000000000f5372651ffb40bf853f6f8396a7c7483c401b89b67e098ea888fde8d19e7552a006a127af1f3311203434126ffad85800000000000000000000000000000000050d7e89b21c7484cc5831885422fe7aa8e898df85cf7a3a275370623eb9660611610cdb829d3935f0d0955e0ac97506000000000000000000000000000000000f83a3f79f1dd110bdb8521e18a64490d567210801d77fa3c0c6e5cbc7285840da325cab7ab08494c8d516511eb189dd000000000000000000000000000000000f72904131be66380c5a18af4857ada7c15e88572197e100de1cfcc9fdb4306e446f2f330fefcccb41b676f24e3e0bf88031f363c8b0062b34d48f4c2e5bdba884005e52f77ac04c2f29dc7ef10fac0c0000000000000000000000000000000009ba6bbf102d390638ceb9259205a1856def2b3a4b5209eb3e4e54074347f71b6c06b70764fe85c8dfc9074067b8d00d000000000000000000000000000000000339c30631229eabc1230240942bdbcfa6e18f23bfbf88b7b8a8fa92f18e35d2f7336f0b819e875ac643b43e6d931e68000000000000000000000000000000000600cfeda6033ff51c3bf9182d22abbfbeb6db46c0fbe15ba82e72fee483744ba5a57ab2eab6f35927b4ba6d2b150063000000000000000000000000000000001530bba4db8a60bb6b7a05f72dbcd23044011d75221d114b839aaa9535400874472f94c849597174322291b5cfec4974cb146e27a9d36dc698e1982afc945af9500fc5aeba719d06d0c4e4eb245034c6000000000000000000000000000000000c636ac98557e22897fd101dc6c54d87060f460b4cf2c5a88ea14641e2a8a9395492fc5a946eebbba36dbe38f6f5c0c60000000000000000000000000000000007fe3a557aa93f2e9aef4ffc55d39a9172475e6595fd57409df3a7fe3d11558c4d3dea3396ee62f61190add83b85813d0000000000000000000000000000000015b04e0daf4a10541623e7523ac5fbe57dfff9ac17afaf4293c493c1982f3395980ec63046cb1d424c6dec91899202c10000000000000000000000000000000019617b191e9e493751b0a02511a18757330bde56722a72a29a399ace983db7114f84795e2b70bc9d670cc0095220454ed983f98fe5112a55c23591bf4e259d072f893944741d9941a00f907749e3c9990000000000000000000000000000000017472b8c1cb3ec528400649fe7c39e3908b16ed69b42d967e4d225b694544e8bc7ce5bec87019db5539f1de39dc6807a0000000000000000000000000000000012b1c4884c37037a94f84c15061df5ca6c05c5a35ad9b37e3ab8e8297c9000e715fd2bdc3f2b485e86c415bf656392a10000000000000000000000000000000002c21af2933029f04b344be76e18ce499def4a0671a97dd9b6a108d0fb23852fcdc56f882be0319978952ef04a207a6a0000000000000000000000000000000015eb31e80fb162d5fa392fada8d43648ef54d4f9ebcb0e9652dd501f55a8875a16a148d42e283ea8bb2c5a38bfcc8843a62f99ac46f986f2f29f0ad3da0310f061e691955c711850a2816ad7464614a70000000000000000000000000000000015e68e011ed063a9fd9cc8a806d8e3561e4f449526ccb6e5ce983ebc4fc49d61d26dad7db64f56ad5ab0b54fbdb76e61000000000000000000000000000000001617d7387fedcdd772a34b267a44315212d21b798c0fe1e7a9ed3caafb678910d9c9c3bd1fff4a3c8e339d0c90a865b8000000000000000000000000000000000e2b3c9b9cc10f41c4c0129d34c62d526aea47c77ded91a5ca3afa0da1801bba81def3ca66a978ebb2d1f3227ea82a9700000000000000000000000000000000096b6caf7b6f29e91bea370f91c2576c188b08b95f9df6c7df995fc9879c11cdbe2af86809468d472fcac8a89716d1d87ee01b0c9c6a6ca1fdac35d89c803bee3595f03d9d200affc5292d8a7c6720b80000000000000000000000000000000016daa86ec04f57c72395d96b6ea5d6ba7cf2d9d4a50eb90f7121545f17c1ee16216f4086481d91e59fc5ed8542baeb7e0000000000000000000000000000000017a783d60be67206241e0bcad20e371d86d47d88ba1293b73f32999b0a1646967e5d031a5b28517f035168d7c7d7927800000000000000000000000000000000058f24fbe4e9befd8abe364c961f0ca4d9083260234a939bf6103a3e8f10a8381a9e3d74af7c13f159e5c7dcf456df00000000000000000000000000000000000485c9448fe3a069eb024ec43aaf563a98da09c02c294da2a94a98a95430e25b062e8ff886fb5fca240fba1abf7cee60297fc700698c56877be6764f48a836d210bb33e99b5735da9837882269af9b45000000000000000000000000000000001230577527a0fde2e8e66b8c4d17594bdab8be1339866819c8890c600b35889d1e3a749fe15fd8182001e30e6420ca6d000000000000000000000000000000000ce03cccfa87229fa8d560884d8c7963276d79ae9873a23d550b4555cc4bda35a242dd2e70cc730b70cdf898609b3d8400000000000000000000000000000000174aab1f142fbb7a45bcdffd64c2d38b99c8919baf9651aa430bcd39613d7565196c18f0f4ee6fe05f5c40ddbcd4a67a0000000000000000000000000000000011dd23f59ca2a033ee5dfa50afb0c7ddeaec6d4f50e1866cca3f061fa03594216f005bc65b2c97ed1109c305e16222671b7ac02db15cebb8af459290c35eb5a86cf98b86d8336764c6bdda6698b49b640000000000000000000000000000000014e1cdf4f10b11f47c15d0b6b7dfccb6081d05d116c8149989cce4f1c53dfcd2d0b7443677b03d037710eba813f6f597000000000000000000000000000000000c8415c7d5508010e0db1878ca663d359525b290b2f02c61436e945145a7a4e1b3ff4e27ea1b2c8d3adbe737d8291b14000000000000000000000000000000000e424ece68003cbfaf65a54dba51e7b0942cc53b2fa9794b4deb6aef1dc1ba1719cba285f9a1a59e71a881eebffe2eb9000000000000000000000000000000001404f9a3146b7201b09c5fd678fdbf2111c48130e82cc95012e5aec1df7e64a3b3c727afee4f603e620925686e126c0f5d1a3f78a2c2ab7b85cee68ee670f50a176e988a341303afb7722917f442fab6", "Expected": "000000000000000000000000000000000e9f6bedba1f6e2a3ff33e0e4b18fbf8e77558bf42e89023df6338b03a648c591486c63c2ecc8ecbbce23b3ff9a7ae6e0000000000000000000000000000000013d2526d83b4495b5af645d5a1af7bd40bd0ebff125e0fa14f10d1c08511dc29643dcfbd25ca0bee5705a56b26c558730000000000000000000000000000000003fa442ab532094d47f1a9111c87deacb15d80ca6e76bfb5f9b9a209bfe196643351d778b0c6d6b274b4799f733abacf000000000000000000000000000000001278d51523d5d9aefc0d3783e745da54f74a88620f2161090a398defdebf82d13d5b5a21a5cd466352ab8685b034fa89", "Name": "matter_g2_multiexp_74", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a497e74635fde8caaa5c9dfe666b1b40732e58b93a72d39c8a60c1f4b262e1f18f62229a30fb8257bf895352ac4d249000000000000000000000000000000000c1b2fcbd7f78d85c73ae55f67110b575750bec353e55761de0ff09a9f8a2d916c336655d8f6a78dfbae13fded5a9c36000000000000000000000000000000000173893333d998dd32cc3e82fd7ad8ce77003192ad2bfa1b1d2b43f9466898313276b922f9fbd8e83e86b67acfd9ad780000000000000000000000000000000004ed01b702bbafc73dc1e6846bc944be297ff08d1dfef397603294c7fe11668cd0670d386a8fa0f0f02c52d47f54a11b34aaf86eb77ce03f1d8eacab84d5ff98a565fd33a9a2c40f2a19d7c041a7e2a6000000000000000000000000000000000b5ec74a2150dcf5ebe09f39234c4dfec623318889d92b0bc1f197a69650bc48d28a1112306be763176b691c6915dc7c00000000000000000000000000000000028db19af73ffdd0111dabf9c7d6879cc7389320a249f108b41be8b1d4c259d5889dbcbb48b30a288e26cd9926682d1900000000000000000000000000000000172fe526c62f9cae49e6d3284170e6339d5af256441590cae9507c61f987eb495d340500cb761896163cb8ec631434690000000000000000000000000000000013bbfcf9cd3167b47b48af5f5ed7e6d45a5fa38192756c9e140eb89a85c75602814f767c57108cfa2f726e71f31548f808ab2065f1d2278caece0939cbbab4bcbe3eacdc80cfae6e4500a5195883de0000000000000000000000000000000000052d7a0f93142b36489cfa21d76c0eb96904a3ddd946a53b8a6730036d88d30336fd8aae3ab29ebf62a48c6e849ca66200000000000000000000000000000000198350abe8cc91bd675f26516d771422c128d5dc0af844c6c1af07bf04a1d3ad9654cbddf2de5b7828d1446c45e7828b00000000000000000000000000000000198f35692d5face8dda4b464ff48d650145242852fe189748783b1a2e48806294368ae0a99481bfe739fb4962f3b86a4000000000000000000000000000000000e3cf2e018a7e0acfee25bc3a82cb282cb377bbd72ce3044dd20e109d948f68720c27aea3d4663ee45b2de6f178a00ac58c69b55bac97a633f3ed7816e77e2a26cccc029f7e7429c86145ca4645eb41500000000000000000000000000000000150e6b03a3052d043da6514bf4ee09baf1a35b2a909473db33ea0bd4c6af7d7aee9a8366c1d08d2adc5998635eb0dfb0000000000000000000000000000000001370c2976b0d36fcb955e797087e6ccffc851d2450cd63833d6cbf52e1fccbbbbf9dc695ee45c7df01c2828051bcd79700000000000000000000000000000000048b5fad2fe0af7ccdf675328d8ff5e63b564d8436d04c55b23b6ab7d2aedbd25d614d1780963fcd03d569bed2085bae00000000000000000000000000000000141f94b4e7ba542707d0c3cb69f8dd79e499602952be2374cead840dc669c5ac57089c5fd60c44291703b872098fa2daae7faf23e841bd53683521cb3cf215577fa51f0f751714b6aafe5c740f66208c000000000000000000000000000000000eec51e0ddb8cf9914304e7766a7418e2854ca71367c1d2b3875c12b7dc5c7cc2fbc136037bb7ff72458027104ed3f270000000000000000000000000000000009fe5e8d1918f9b5865a8b97c2c2cfc8bd750a0ccbe2942070827a09d8e41ca795a86b2262b10462795f833c73e788ec000000000000000000000000000000000b95c9146f3f560ad880ca905b5f297e48905680b4613e91f393f72ddb042f6a6201628fb5f75fc23f2298cde66a6df5000000000000000000000000000000000a29a8fba7644ac96d77ee73a93dae23b03d81a57f6cd8cb4594b23571cc1f658f163081ae50d72e09c6513d1cd2c8bf72022cdd6d942158bad47a53a9b0c3be910a41036874975724a5cdd22c012871000000000000000000000000000000001807dd8d2bb40a642fef693739b1df12fc787db0f031306f31970d0f59f0c97c0894afc34b9a9913726a20dcb7d5191200000000000000000000000000000000096fe8bb5e911c1ed9985ac08d864c7020367f4259a0d074973a26cc421a44e8034a7007f6d1639285cf8acb8b2d64a60000000000000000000000000000000014026d43eceb26b9ab5bdd4139d4f94349b273e43f27737f9ad26d23454cdb1d35ea793d21f057359d28328a82d5290b0000000000000000000000000000000003dda2a84bd1f92524a8ede9f5e81f0f64b41b24510f4e0b8146496a776d5b509968f188c12c2d66cf755e5000cddb3b800ae0b956e38bc34cce55bb7e88f1370a30fc8ed0e3f1126c68c30792a2cabc00000000000000000000000000000000011246ad07713d1916c662679ab757c053e33def437d7a976533f0ce80ff6ffc259489c26524ea96898c3747c4127539000000000000000000000000000000000acf66265811a57e47a4c98b40b12a37c6f439550b18215fcf856c167b7218397d7d559f852fb45077945a5074f460be0000000000000000000000000000000009badf2799f1c43a2e3859123aca91e894f86d6298a06a9127249100ba270f2bdc79cf511691bf2d7faa45ffa17490eb00000000000000000000000000000000069438b1d53efcc4277ea7b41cbd28a19f80b5380136f62121e766bd2845e13d5cb40b2f15d508414876ddde491a3830a57c3322133d6ffac661c888995e7cb067ca1309f3e9178a266f1a410a79c01300000000000000000000000000000000112c4cc34da9e83207b5ea8a9251ac5f004546596f2294b3fd51b77ad8d8e98239d53ec4f527c7280801233175500b1b0000000000000000000000000000000011dd8627748c9a2b08524f88e560cd3944bfd1fa17e1d6e2e9cd025b04f2e3ed35125197136afa2848d24fb5fd19508900000000000000000000000000000000093219f9ffbfdaa60c5965b45a5d5bd923eb5d3971542ac147de3f591a5fbe31b30704a0061a524e2ddd05a45dfcb6a10000000000000000000000000000000006407dffb5580790e250a72dfe68a488431f61f45ec9df279217b8800f0ac1ab585d84e486487d5688735fe5aae75bacebe67f3d067b0d011abb31588d1b2fa9fdf8a56bc46b1a0196e926d4ec73040500000000000000000000000000000000107ede23f8e4f273ac2647fc251008905966dde32339c023f1da3c4d35d483a55b54f4157a303e68e1dd7fa3f3b14c8d000000000000000000000000000000001739327f282812fbcbeccb12e40df049284562d8986b8d4559787e1d5247eb6c83d6b838d099f36d8d0e32da2a7999a10000000000000000000000000000000005e5b6b2baede3ceae776da5adf075c1d774e83d6129ccfe7e835862686bb4064b187cc0be0cbfed37e5cc039f3a3fb6000000000000000000000000000000000249554dcfa53f73ef8f08daabf20c55301f75c8ce095cd794061c55e195221602a54ba54260980bcdb35685e41d0f4ffa1d6d0d1876a67337d66c596fbcd7eb22ee308e4a5f66cedff584f1441be6a700000000000000000000000000000000048b7fc5a71787231f1c7ed2134be528fc8d8f77102bda806ccbadf4f9bed79ee94b43c0fd3e5b1d776fe73d786872d1000000000000000000000000000000000152a1f005a64e16949d7249c3b391d5c1e0ded4893d0ce926cc666f0f88b64e8dd6ec4f92ddda18127ec24cad7e40b40000000000000000000000000000000013a2e1e7958a53307adf3beb32a88b7c493df0e37e074c9105da3c09bbaa01fed092fce2b1800790c6e8af3d30ec5a81000000000000000000000000000000000e2d405806764c75122c1b5e410673b28759f26af7489cfa6f35c6c0dd16c508af045009853f3329cda4a67948232bcef0c4ac919efdf3d0e649126da7f8ca3daa30b6ca6f3be6854c0f447a63cf2110000000000000000000000000000000000a71d61dbb3ae37230a2dceb54061d5f8c1ce645e20ec39785c229cf79aefe238959b2745e3b50e4b3c20c7a8e2ae27f0000000000000000000000000000000010e82b8dd5faed6bbd5755c4e5a88edbb3511d3f4442d1e44b82cf72a6414bf6558d29e8907b07f71c00f537637605bb000000000000000000000000000000000d8c93f1984b742b5a02777b706970215c7d8eeeb7377cc26c3af9005648c2eaea7f7a3177b6e049b132ef6bb4b188da0000000000000000000000000000000000ff082a252082499d70eaeba6d5514fc8d641404b48b2ecb256eeb40d9c6b68ad5af58556c9dcfc5667621c549b8ee760d8bf380bc2223efc779a747c0a36f8c2b18c3e821e96163bae14b18f3739f9000000000000000000000000000000000f4cf354b8de6dd2231448bb235af3c84daac2db49abed345da6ded50eae93982a4f2c27b07ce725a062b07fdd9058fe00000000000000000000000000000000076cf19408f0f0379c7e65a6675b9856782990986f5c6d7002e9c9c74b95ab875924bd7ad5e4812844f6d1f530e58deb0000000000000000000000000000000007acffe32f96f5e56557965e3db8dce87eb7140d93608cc003bf4a43fb261bb7360c576da0b7c4dccdbdd9cc53b5c5f8000000000000000000000000000000000eba1c668fd9323d42d6a82d9f075cec2d278cc57122e25ccd72cf8b5a569552cc6b0e9f88d23b9b7af18f3bfa0cc820006c3a7b5ae971e4b0ec34a1007a02cf8c55f067115ba00c5967f70a7dcef9d60000000000000000000000000000000006157cb6e2dfa2733d4c489ec0334f0303ff1ad410f329cb59f99a5fa3ed2cf84eb7d2f231078ba5db0954badb58425f0000000000000000000000000000000003dfee394f4c140e2cad61e8675b26f91244880d9a0b6798d6111090dc9d080563db5c89b7293dcaadc74ea5849a08aa0000000000000000000000000000000001aa1e0683014d5b6f99f469a0b7beefaf05a7ac0298bd1a3e2da409f6cf856f70bc067610fd705a851cd70054df9562000000000000000000000000000000001571b129f69f3a6717272ff75351fa053f46294f68ba3f859208d6c91ba5eb9a0f2133a5e139d04e38c7f7aa303451768f29e330b48230de23e0393bf1614cd26685cafb899db5a164497955d3e98be4000000000000000000000000000000000c4e84b7c8e46daea67c8090b27dc28b7867b89b92f56232bfd8ecd9968b865a057957292e79c6dc08162f9e91e6a4b2000000000000000000000000000000000b8d1eadcf3f1de6ee608a4a0ebb7defeeaf4e251bf07717a6a8e50c07223ca32a2ef290f26d0de14b1942e02acba39a000000000000000000000000000000000e901b546a4d3c68e4432f376c97f42ecf0724777956c4ffb1e6ca4fda562e57be788ecfa45ba3afadb439c2ea546ff30000000000000000000000000000000007ffe01da4fbda9fe5d47c3bedb4b92fdd71ad73fa272b071a7a7d1cdce7743a535da7dfe05a43d03368eb97fff54b2d861ffae8f62572938925593f7271a56e0f559b56bf97c454c38547a2185e2ce70000000000000000000000000000000008da0fe413e31ca68f84032f23bdd5399e01eb3b5ae47033c6834a39645d7b5cc2ec937067b91ac6d83035a86fa841f9000000000000000000000000000000000b950b982323f747782d9065dddca5332940058a604829e31560a6bf9b03ec72b09cfb87a1cd244ec694c7cf192c37ac000000000000000000000000000000000f4afddd25eac15d2248c71d76c9aa27323f75141820efeef1ab4f5003141053f138d9a7d1a901961d0f2c210ade27ed000000000000000000000000000000000217b1800c53d53459b00b8e463df1882b2cbafe85043f08093a5414e58ea7fd4dd933c601acfd7c154d0e4ce187468a2dd907071c2d39fe710215d174452459cc31d36007a1b5570a27ca2e42c8be55000000000000000000000000000000000046aed1acd19201553bb6a88fd6a6c0525ed44822d2a4ed3bca48a0a2b75e76cfcdced8f342b81ce03ffa72e667b3bf0000000000000000000000000000000009a5adbac43cca3402db016a2138342fae89285ab1fa16d7acaa9c3ee2b4e3df2641f7392355996bef7b1578ce1ef119000000000000000000000000000000000c8ebbcbdf2ac3fbb553a2e589f4b7c259a1621b83b14fd1927f92d9f6cb27e82507d7943ff5930f0c14b9fc38c9857900000000000000000000000000000000105b729f678db31d04ceae0aa37f9cb0b0319c4da9a1a4702a11bfe3a5f2f1f2af09b9cbd5ded5a930e2e65f4279a31699893c06db2dab559f2c374df4298707dc1815e55034dce920ae7b1df2ec8d23", "Expected": "000000000000000000000000000000000708e9b926f2536731b02b6b75305c549da58e312d9c53701a993624697af2f3469af34dd4634467f8c98a0f721cd9c00000000000000000000000000000000019185b84fc0511a048e3c39bc10334c91dc1052d323a31c8bf325479a2fa3e4228f8260c0e725c2b89d5a0319e6fbed70000000000000000000000000000000013c7c441d5cca81b48d43e908d6a3bf8b5057cf19e4884227cefa9b235103b46edbe01bada06bb9b620ebbd016d537630000000000000000000000000000000000431182c8a1eed66073956fe5798a894be396403c072e766cdc262b719d1779f960f4aebf61c1bcd4d005d3c7413e52", "Name": "matter_g2_multiexp_75", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000199f555aa5c651183f52470e36cde438422f41c9b2d1947510665254b74ba0bb9cdc6e6a1283b0c8f58d8f009eec46900000000000000000000000000000000018f1d8f22f43b4649300aa23ac92a2e8f17e7e3853b912bbc8e90588125c371084cb224c2d54dcecb4946ff6db53cd02000000000000000000000000000000000efed0bcc83a52f0faf9e260815da8d4e5286396081268485aab052a96af8eea0112be6cce1486b10b60551ad6c810780000000000000000000000000000000013a3b1ca3b9b7d50083c10d36997f5f521d4426af8d2905aa5d074ff37e218a0c96c74387485c2dae24c0842b7a74cf0d8555388bcc6791802ddb6c0f4cde44f45ac0b5d7ecd918bc34fb9fdedb65b94000000000000000000000000000000000efc5a5c506e94ad2754e235e2da866d9c46342f14d518f12510c93f13a619f6bfefec50c146d6d6170f190497eff229000000000000000000000000000000000fb91f34356005f38c9804250549554cfe67ce195d5e218e4e1b1a4fb904257bdb68d6dfb013e8e85fb5a4cbdbf0f21a000000000000000000000000000000000f09903db4c41fe3f11c6f0cdb7c31a131033e30f52cb66ba10c2e7da1ed8a225ef280d313630121701f9a490e8a0f5c0000000000000000000000000000000003484f7e8f7d67ce40b4cccef110bc255d91f61a4e1968a9ad37e25058eeaf39e9f1ff89c9b2e515388a7c1b49a84a2c33e5999498978d14c9de06f7beb2fd870f6f16dc42125fa496606e65c7466c0f000000000000000000000000000000000444215c3d4a7d62201ea1b69890e2ab90b5f5c6ff56fdc9908634c7489e785521b8dcd7ed409cf09c585cae8414a3250000000000000000000000000000000002d70674251a0c9ba76b8bf3b70547da77cde5592da9204954abd6d8aec82799cc0fa4fcd42139357043fc867b3d0e0d0000000000000000000000000000000018c57fafbad2351a3da695f8b523443e8c763dd7ab875caaa6a494a498cc40b1c0d44488e2dc80d1f0bce00a2c90c67000000000000000000000000000000000125d5a87ee3f558b5e1e7664b0cb95c195bcebd5e43b930fb47d15eee4fd50b3fdd0a401c9bb011c326acc77645440137894a51dcfe5a8fa4da1745a696c870b353fb03a31238b8744840a78084bde480000000000000000000000000000000018790123ce8b3b72d626493a16936c47770a9b06ca45b17c6fa5c7759f088cf98de8ce7b3b5d6082e9e42b39acf76f79000000000000000000000000000000000fea86cad8b40f315d8378550f6d3d831149339a8e8dafa77295859ddd2417e8f5c0ae2baad25fcfe00de14f45a537170000000000000000000000000000000014ad78bb2bce966d52b1fe1a273bc07f2f24b354465edef6dbb1e0123c7c3d7550983b3793ff1c7db846e88eddbf33c4000000000000000000000000000000000c0daa6fba40ec59f6b34d413130df5d9137297d1b7b71b83114a6570fef8e7f83d6f5689527164782f92da4b1ea12e8fb6a294589c816e18859cec34262df6490a2af6acc7daa3de861198c5bcf4b13000000000000000000000000000000001186b7c78952e5c32a9393eab07ad4532471595bc2c5d8137c61dd7fe6b6ca3aaba82dc205a559bdc15421a001b7270d0000000000000000000000000000000012d56b6fcec3d6511d2d723601cb8c9faabdcdd12efdd0e2bfd7c9292f2c3bd7f39c6e9aa53e6955727f88ad69c5b4f10000000000000000000000000000000006a5e56e4a42b04c03619c78232104f1f1f39e755058a19354eb230f2f09bf486b2586817aa6b88f27b884957ea0226600000000000000000000000000000000118c8521dd4866df907ecb252d9ce7a489f17d0f240d054a5dbff6c35895ef20b205236aa6e5be6f0825f9df87878ab783c4a3460caa35fc0e7342dd2da5c7b6aae818eeaf5a2cbf4794387180b95dfa00000000000000000000000000000000092809d18926c20456857826491f55cec17803e9e7d43f22faf4da18ede3bda15e3319539017ab20ed1de2bff490a33f0000000000000000000000000000000018d736b967eca64234f4e0018e5d6c902608e265037d9b8ba42dcc923b84ac62599e153e1c7d00e552ecc5aac57d1a5d000000000000000000000000000000001804aee99219354d4a5c46328f0658a417c85c6bc89af6db29a4911c4b0cad5638fac5ca61cc997fef3450cfb4a6c666000000000000000000000000000000000bf99dc4a400adda5bc89762e9011dae8ada23b284e52e2d49f75f1c75247f6282c95a36f7a72f896ea308131215404bd2b65c1580bb46e3a4cd9d9c4eb7dc998168c66982448abf3a4e08cd12f612b1000000000000000000000000000000000604f8bde85c0b26894e0de155cf896c911bca47533362a0b59ccdad0dd64108d33af8262d3ca2ca399306723f2482a8000000000000000000000000000000000ec10d3777aa54cd0cfd84b4062092ca3ac840a24e8e8aaad5f4c275e4d45091f838ae522efb1b2a0fa42229157297d300000000000000000000000000000000132cc70638d02186116773b31ec0e571a55c1cd78ec055fc647ab09cf4d3c543e0552d559b3daa4e99cef031e583e61500000000000000000000000000000000194a6a32a269692906b64feef9e4e8cd204e560b98db8c66380758d2123babae871273b4c571a1570a317c13a51d0fe9120892aded230949b83bfb2dbac054b83a9dbb852bd0ad85dd1d7f715852306f0000000000000000000000000000000016d05912dfff44912bf34f242ac85eb55bbb8a21625d45496c76d057f518352528c6632d6e8adbbccdd5983d13c26953000000000000000000000000000000000b10aa1402c15fd601ce605ade8f25531ea8f95cf592bf4ed86c4a3aa847dc8aa2369655ce5348da30a897fa8d71ffd800000000000000000000000000000000183f5a2f40da0a0f4598c6b9ea7b99f8cda1d85cec0e6da5365d7eaad1e9a3167bd647e5e654985f395ea72257f61e5d0000000000000000000000000000000014e615e2d5072c1b536ffa607f3a826ce297800b0da329fff397b6327800ecdc879e91f1e3ebc26c18e188e1ca66bfd66af9777a58539e5aa8b1fce0994e0e1cdb5877d93ed4db715c5aaf74d6a8bb1a000000000000000000000000000000000f3cd275d72a637bcce855e2e20727c6e5a1f15bc8d799231d3a7f61311d4cd2f58cf38448675aee9910c1a3d0b576210000000000000000000000000000000019efca445312f568727948c803d06b8d4e2c5289015740f2626fedbc0047d344aead06ef521ff7e139312fa41d1c107200000000000000000000000000000000141384e1c9f79e38bbb0bc1025c079741b93f56e150df58cf9a61ec27c2877c4188866fa197242965e3feb47a78c68380000000000000000000000000000000010638286faa6c45cf028e8e3d200edcb348560e2e35902927391401b3155240b62a40784db88e02b874e128e3a2132b5f37e2ed8e96921a0f9bff8b43d432b382d7b59938e269c381351ea49b8c1ba2b000000000000000000000000000000000c7fc4216767ed298206bc142862c138d78726e2d39afa18fe5732616c73a965d95cd2032d4b2f5a4d562be48ba6885a000000000000000000000000000000000928bbbd76b87f58ecc850e1aa4a2be11b15a81786aa7ca8cf0f6cc342db87b66c435f009f88ad97b747400fbcc651e10000000000000000000000000000000019f5ae9f06f2bc27a39bafacc7f3745fcdf8c78c9ae8a3c066ffd704aa4117eba773691ae43387b93e86d2e2de3688700000000000000000000000000000000014360a7ed73c05ef5fe651321f7e839c920bbc1896636143b88357cbf76e15da839bc7e1f1e629768d447c9d313cec8e23f4a77a2c34a370a9b59ab1cfad77212e433464d0195f0d2fd20c69141389f50000000000000000000000000000000000b9d955f9d28f9485d0bc4a961f0acbf09ee5fef38ccd81a2c73cf87a461ff1bf28d4dd1e0db3ea522299af67bff93b000000000000000000000000000000000889061e71866001b0760f68e20c7c0c033d782e6e6752f11502a0e8b6b70277a985dd13dd83424d1e5cdb9eb96a01c0000000000000000000000000000000000e05a26686667f44de2bef53c36c82f1fdda13dd3f7f8fe1fb026273dc4dfad18241d732ccb757e2b46ed8317dc69fad00000000000000000000000000000000038b55685b02231905dd9a62a709c0f015cf5650b3fa469462b3e9d06e3af8092d998c8e08ee61db1fd5583b0809a38996c59b0bc6dbf66f42cfee34413cc4cbdae7a61e232757c75474818591764d6f0000000000000000000000000000000006649a8eabb25fb7793344a0b29325a88294343f6c69612ee9d9002154a49791f6cd7b37b2bec69fa8ce11722e9f8a03000000000000000000000000000000000e10f2f3de16fce9b9817085f0130e1839d9aae949170ec16834732a9b12f589a2b00f17d2fd3416ddd020b7421ca20500000000000000000000000000000000016b51112b3c7c42a8c2a0fa7f286ec05cd07b6cea5675bf1132de99cf42b450b3c2a8f02ec821529a14a2a0fac3a751000000000000000000000000000000000f471ec8b65bde22e003500d1d422dd0d163abb424dd261fac588333755cc5124acde328085d8df852c61e024155564781c180924f1d982bf4b6a2bb1cac590cdfe84198fdecd87364e163dd988f9b1c000000000000000000000000000000000ec162d22b6516c309efb6a4577c5631a5807bebddc5fd1be5446e4a64785d49eed80eba2e89cfefe484ecb8d50440a600000000000000000000000000000000070c252caf6c56018af6b281b829a4fb8dbab850ba0446d233dcd4d87bebac00e3e5070bd41898dd561526498b153199000000000000000000000000000000000a0d76d1205c1f520d82c85bac4473ea7cf5f68022d95b1f04d06062197973001234d86921e70a94e478eea85264f14a0000000000000000000000000000000014c6a07f0d568f2103ccf8f61278e916458820bcb61fd91479b0dee874fe36c063a34bcb14ee434b68681d297637b5bfe44748b9eb1f44b5fb143cc8deaad23047bc5ecb8059705e7905c37625d5e2d3000000000000000000000000000000000aabac129385d145243c3a1f357ccc963ff14867ad039827488128ac639dc62fba82ace66f889b47d8eac39802bc1af900000000000000000000000000000000062bbbe8c72cd6f8626484bac159b7e28c6c8c3261edc6a05a30c308cc9e56db17eb58f62ab755f04a5c87e58c04c7550000000000000000000000000000000011a4a439d18501142350229778f67bbe0c9b948229dcecf70a8b09d1df6c54801a111c603301da2377d4198d09dd51e70000000000000000000000000000000017de3d9bc6fc5f415d04ecec013a635fa200699c496f4d0bdb5cea7d446274dddd0a7f6b06058fde43fc4f1457361558ae04d7723b7c9cb0574ba744bfed8f8a347ab740bdab99136aa71a6d635d0d98000000000000000000000000000000000c86590a02fb5c9568af4e69611f09980cb5a7e040c94ecdbe64e40005783fd3305a5657a5c6bebca7d20ee123a872b4000000000000000000000000000000000bc873a9bc694171d2606f4efa409897e03198a61b1bb16ae90f0d12345d2650d93c46e0c22b717e2f0504b8983515990000000000000000000000000000000001df9160ac3bc54c0121a9c69e9065f4266202f755c961bcb8641d13720b82ebd73eb3804ba44769fb2d75144442f1c400000000000000000000000000000000045e9c8ed2fe1e5c9a2a5bda75dd60f6bb5dcd0a805f68c1f662a5960b025ff29c8e21857d2a61bcd65c747d2a2da8ef6a794685a342ff25dd706e4df725e3466889d8f08a27ed2f32523b117f01a84e000000000000000000000000000000000f94df8d267339bb4f51b21014ca6d685f7657d0f0bca189e53cf19e0e5e05bfad773c0553daafd80c86f302b1907ba5000000000000000000000000000000000d92905addc028a1dfdad50e909c77662e10e4689e7c8a4a0174a3e1c746b361665b65e17fce02b6c067a5b8d7a6a6f500000000000000000000000000000000183444f0665790c48bd3c07545115a11f82463a092774234e7b33aac1094761f213235895e5e61ac1b0a15603bffe2140000000000000000000000000000000003cc2cbbf181fb023a5f6088d8a9793b17984b3dddc8c3ef1a9f82f8f436002610df60b2d35be212da9945bc8108c0bced3f23c51953e46d400802dde46c374178ef379d5c1b04d25449891f0d5623e5", "Expected": "0000000000000000000000000000000011f85691799cb76213068ef4f997af66c349bf707295b969d85fe637d4eabf54f3f29e739152aba5027c1b55317a27210000000000000000000000000000000019627f9570f07f44f326b5b3ee19bc477e92d813be2865e00da93135645e02e6fe5507ac4d50085b02149667794609fd0000000000000000000000000000000018fdc97bf0f88b2348b436d70ac4e28b5ee5ba21e21e94808b8b9e401c0c7d688974fe203ebda0b23abe38018876f4930000000000000000000000000000000019e28c9c936ea5a0b3b41871c3afaaabd53a93902e44a96dcb7651bce7e6143d81cb695fea8b94aa32c09ec030dd9ac4", "Name": "matter_g2_multiexp_76", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000703481cf48efe78fe8dad34184edd1765a1d01846de74a45b43d4721bf1af116c229f969868b0e6e851f22bdfb0451300000000000000000000000000000000063d316d495b1e82380c5b73bd61ce7f2159e7714c50e374e8a91dd56731dbe03a3378bf8afeccaba5fda73b4c2dd166000000000000000000000000000000001012cb2f6578065c93aeb673f447ce95fb42927ef9d12e07968ec04b6a604d785944620043dee5de4de33d59e67d64f20000000000000000000000000000000018cc7cfc360801ecc420d77ee171fb3eac3be0cf26b3f36a6cfb7c6adae7bb74c18071daed8fc56b8fa639ea138267928c8e071da1ae8f615631759cf33fdb876ab289a6bcfa6fba2693a58f8601dfd10000000000000000000000000000000011e0dfc437a65c6fe37bb9e554b5138f68a3c52816807bdf7d98f13cfaf86b37e9669f4e0db1b7865d910a309f16cc200000000000000000000000000000000006f2323e01591a7db1d3c7fa1a2ce4540cbe0396cc55baa3a3e13650a6f6b926a7cde0eebb45d359edd52137152fe360000000000000000000000000000000000066bfec8df4ab5f5f5eb369b34e8e22fe32abfc00ac58b68f2d3841248fe5843d6d29ad012249fb9ee851e40b940dc2000000000000000000000000000000000f4ea977d9249bc05dafb682a863ed17f7fba0a06c4a13cdf5a836748664183272eed96bc4109bc5beff61c5469e221f8371fff9230243d2e6cb6bdc4cd97260a8cf0362d18b9ba8df512d2a6f5563dc000000000000000000000000000000000fa3e3e77112774fd6d6b560ff88cc92ef8d009675d0ed65705398ce727cfe786684da50bcdfaffae97d19bdaddd81c00000000000000000000000000000000019e98284b8b9f53faf3b73902cc322dd80fc330dcaff2a7fceb55db6a4b0f7f667297f5e4650c797ee337985dc6b54310000000000000000000000000000000004e30acf2ba66d842575c8679caec607fd090f0aa2350464f3b6eef22e2b9a1d9d5fabb0f3909f1c19f6b8f27c53b040000000000000000000000000000000000ad76b86e32f84ad74bac68909da0c271571606e071b13bd92e387a8a16a1c4002c5a5e94ecaa1e8d2d6e051e19a45c763016c9a9cfbf336ebda090d3f2a1a1b265787e1917f0148f82a9c0b66b21dc100000000000000000000000000000000019bd07479b234bba974ca2f39b317d5f4be33afef66c1d69e53c44cb5e44c679775ba141f82486424110d186561777f00000000000000000000000000000000130002de0d453abe9052a5f70a9d55de74939d1c8e6ad5871a669a867861b1359322eb98539f4a21597d806aeca62d18000000000000000000000000000000000b2f0c649fdb37216c10762f510c3bb4c789dbd29c4f9a8ff39f74ed1a96609c60473a50f5ce3f6535e4af0f2f0a150c000000000000000000000000000000000893b9af710787361a32fbd19c380161c9a214a1bcf3761563424b8546f6068ba650d9caff3e42be63ebf4b6afa2de516c9f679167d5fbb29250834c9f65d3025606e2af20aedec309718f95ba01e90c00000000000000000000000000000000019805c0de5e232632228e2772dc79712e3d863bd6fe56932b29ee99870d2ce5eaf90c73632d1dcddc093e9b6b5b0f1d000000000000000000000000000000000405d77f4b3c44f99a956ef375879e62df033aa408127e0fee013b74675a8c7d999c6abd30f459693086bfdb326d67af00000000000000000000000000000000110f2c231998aca3d76e40055a05feb37eba76cdd10106719f2300f57906424d7eb6d9f85115b78b7371ee60e26d02b5000000000000000000000000000000000593a4721a67caa7cbbe1566611a1d48532c68adcdbb67f362c9ec21e08aaddf6b5e09a9a96df9a89bc25f11665f3a36aaa3300f5a2fafab132f5f4662c1d288210e7502ca2472d060aeea6f2eab2d7100000000000000000000000000000000151758f1921743d116f1c4adfc09cb68b3ff911329e2f6d6bcd04beb9c109568c796f328e1f04381a995fe89aebbc49c000000000000000000000000000000001388c73b1db46bdbe70540c99db46b730e157a23afea97648d73f9d5f7e8b073ed665eed9e9e2500152c87715f1c4d4c000000000000000000000000000000000284ad228867ed14ade5a327ed951ca50c87f0a669e59b7a75d17feb54bc5d685245448a912590179db1e84f1eed1e5b0000000000000000000000000000000017d3da7c167733dd88f1c39315e47cc80c3310cc431989d4cc50ddb22e9fa481c5dc02d94dbf806c4c8da16ba5b24905f6608f7c036c8fdc335601ac55e869215eb4e626f52bae813d45b827df2afd490000000000000000000000000000000016064871cb68f748939a839800afbb018fd5836914a2b76c51818e764628a76817c7ea329e6b2f9de653c8162a2a2e0c00000000000000000000000000000000082fa03cda4c617a780caaecd7c859c5251b56b61f70fb3ea8c05b4c11c030adb8a96d715c1325ef3dce9b20e8065b6700000000000000000000000000000000174a245baedb7e1bf1368212620b850151be41ebb00c977d85da499223c207ab6f1a1d94a51aa9e90d07764ec3615b3a000000000000000000000000000000000df5b81cf4b008480775ff3d7644f546a60382e92a98b03deaa4a20f831e69e14a893ffa731c4ae9ee237d747149a9080cd68c59b1371c7063dee5732182961be90b95247511a5b564d7eee8d2c7c64700000000000000000000000000000000019d36b8dae5e1083e687743f7494b7f9dd0923024df81e2f83c78743e227ffce588a16630201b9909daa6c9207b5f430000000000000000000000000000000015659059cfee7850e1cf0e49abeef2fe5837cd128742e62de20dc734f1bba343aee1c9f1a59d920a0519995561891fdc00000000000000000000000000000000102b7221257c40d9adabd0db3ec9f6348487187ea1110773fcb2ac5ce210dfed167a4d15e605e9d9e666fd092147a1c7000000000000000000000000000000001402ff9770d27d2d82efa6abe4a181e3c1d944e97a06f670d9e46b24f9900fb4a838b32e17482f25be9b6f3240870c02ea52329555d9b79eb1fd6d186df80b25245ba9225553f402cfa6037592f0b10f0000000000000000000000000000000001745ea52686f87a39fa42ddb5b0f69368db3757394fa7a1a93eb20c398c26415c8a7edeec7334df5b15345d6174126b0000000000000000000000000000000012b580e6fd228f087c7584cd95826e56d1c074cf16c35286c45d2067a362529d241c1e24fd22cc9727d423551de1a1f700000000000000000000000000000000104b46c42a706c61610f8c0434894c7cb9ef878cd0234f8aec0825cbb8297bed3de349e7f6037dd19a159103ca7753390000000000000000000000000000000010b781b3cbe6f415af15e37be7c60dc6703e6e79618cb3d8d9a5ea3b17c00822aef1eddacad66a646c009dac887bb070caf39f2a517d432d1653c37fd9a6c4a8a811107dae428f4b2af3b12e4b6acea30000000000000000000000000000000004b172c360fca555e65860c7a294960f506b562e012ddebad5803bc3f4b93159c16cedb73f339def9cd1beaa0912c93c000000000000000000000000000000000242e37775a042ccf59e99da667c67fc49e80e54a1b438a74fe306d668059ab4dc7d9e457adb45e1f91b3e6bef0a130f00000000000000000000000000000000186eb83ce3abe66b8760dcc0d375eb783d175b0b2f36cc08793d8a86cf76b7618b826f50c6b02ed586394abe4efec2f1000000000000000000000000000000000bf780324df1cc5de325a796f1fde367eb52dac76c0632915dfcaf01f5acd6ae890dbfc2e505bafeba7fed8fd63018c2ff0bad6dae80d5f47dd8c208fef0f3046cf1040112d18c596eeb934762977cdc000000000000000000000000000000001231b52c8a081add6e5c250caeb9467335933c2ed66826e4ab44561eda9259acf926f22ad0df8e8756aa51279d12bc9600000000000000000000000000000000051c46bb04d3e035d324de681c772e4561cecc6a5bc4ef0a0cea56618e09b3f39f5085e208229e50164bcdcd4abdefd2000000000000000000000000000000000ad7ee610398935a02c3a7139185409d7fd4681ebb74a239e15d1c092ea913016d3f585d8224cb1d109ac111660a94aa000000000000000000000000000000000903bb16efb052b99e9c46f3478b4acf800a173b35b0079d7728fc25c9415c8b05ad520f31e6a3c867245f64355cbc080d0c40e5d422685c5c83716380eed82392ae1dc6074a7edb5759fa34a61db2d0000000000000000000000000000000001788efb21597aaac29b7bcb9ad6cecb89267c757cfcd8893c32fb13c0f3e1af7fcccb9573dcffe8d9220292b7861cac90000000000000000000000000000000015f85d3686148ad62d7fecb71920981117cb8759ab249d0ceb45f9e4687914536a1eb16ccd0e185d1352a8d2b4a8ee7a0000000000000000000000000000000015d8ed94c0415ee0f7c9854841bac5821253bb2ed4d86a61f494cbfbd61614983e4279fb17802ca68aba4a0302ec1d8a000000000000000000000000000000000f950a4c8aa18f4605e1252c367dba1e170ad00376a8560c2fccfa7d5487b0d1d5885cec16a0a17d81b5a584d473853f7e93a16a443d5f981a02f0b6866536dadd276abc0998bedd76b168ebc8e31b82000000000000000000000000000000000da25ed9154121205ab6843f603a38a6892887d2725f16ff87a5218586c6139188f46da5a42b5e05982468e8115713ce0000000000000000000000000000000013c13ffbed4a60bcb8659013b022012ef3a4400f506d65aff7ffb1bd5a9a5e030a298e417cc1ec8ee7ebc06455dbe61b00000000000000000000000000000000132d83bd141c434326d4772de7f8772c30a6456de7adee7de66a04bece4c0d20bae5526c8eca5af5ef2eebd72c90d54d00000000000000000000000000000000131355c5e359081dc86e0b15c8aedb4f2016b41e8428051f5132258eaf4392fdb63a91452dc56aca20b7ad3263ebc8c92a1d13a64c03585715908744481c79f340b5bdcdd88d685ab8b91722ee7ab7190000000000000000000000000000000012dbe1327162e4176b4988cec23df0c1b0075d0dc51ea8afbbf98f00891511d9023cf7538c5705d59b6d6ddcc90b101d00000000000000000000000000000000036c12c7f7627b6d6fcba9a303248c38d784a3d1d0ff02e550565efbab68c5116e9a88faaaf09bc72bcc3358e9dad0ee000000000000000000000000000000001578ffb68cf12dc9a5ae6fb5d822324cec9e3f576ce08d45e24fec9203d36a6461c5b8ea6ac50233e8893b07ea6e71e00000000000000000000000000000000015cdb43c82b20b8ab270b942b9e625ada9283962a7ce95eae156aa4355e1123ff87ddb1cc85b2a94bf36102ccbec33fb2bc6979fa2e386abec058683c6d74de31af3cac21283cd5e4244d7edd94da9600000000000000000000000000000000017041e16975850e6445c7b4896955eb5eab383ad3c3031aef04e8fdfb65a6d52c9e647330bfbb0f0eab630c9f9ef7a12000000000000000000000000000000000b62757ccfb913ac4264692053f766e142697f598a3fe26e998119b63a3abc7fee03db32a8af36aa21181fe9ea89d12c0000000000000000000000000000000006bbb842a889d7ff3c1eb5e0b16e3a921a11d28a251c488a8a17a29edd93672fd15974a7e972a34c47283c583cf2d29b000000000000000000000000000000000e94e685fb1751f8720b8af79aec7b245ae8daa195f11f485f2c0c5dd68cf39eef848a402ce2342a6b3398cc7879c6010f1937936cc3766184e47f39acfe5af4497e8edf77ab34083135a9ced61d25ed00000000000000000000000000000000100d3fee47ae6c8c7981c8cc615870924fbcb34c2ed817d6862e2e6d0b4612222a4c8332c7d51b58ec59df6832139e1d0000000000000000000000000000000017270fa71c34ec84043ef64c5dfd61614b5b3bd99204f9f70994d71498219818a5f16843c67c668b06aa5ad3a6ba8a0a00000000000000000000000000000000057948c0ebd14664bf33fb282e200fa0e641764a353e8347586465dab0c79ca2caffbdc2c6d60b2d7c8cb6b088bd16fc0000000000000000000000000000000012747eb070f2de18f517648395109bc08b4af3f04d98e23eb6b516199b4eefc5df7d57baec736987139c7b03b573941f639a8b60a1849c71688a11e612b315439161717f525b5deabbce75808470166e", "Expected": "00000000000000000000000000000000128c6c0283ea35c10330502d6aa849a909df6b8dd927a24f08072135b8e21e40c495c42e742160363772569189d73ef40000000000000000000000000000000016d78dba1e0feeab46f8cd38681a9c2f6490ecc3a6e79b31caead256611d133090a4eaed9691a87b66dd1c2ee50d5f470000000000000000000000000000000016de93e176c950975abcbc692384996315a98065db6d6a6214472e5a338e291b36abbcdea1b8be6162fe578acd669abf000000000000000000000000000000000d7155e239e9b15ab64a538b0a0bd53936df4ebdc3ec9b0b1d494e4df780bd014425759e9743c9b262cf48cda01e945a", "Name": "matter_g2_multiexp_77", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a653e0c24eee1cdf8e3652809de0cd159f2c541981a4f43936e7d41c0f97ffe2f1e1e0d1032f0970023f1d27241a16a0000000000000000000000000000000012d1d8d2f96db0e5f97be096c961e3b90ef3d88492fb756894979d2e8104791a5b9a43888043ce9e543691f15d2fdb650000000000000000000000000000000006ffb94dc3c2d07830498260ebe4641b2cb64df61cebfffaf2d4ab5b6ba92cd75de209e8d7915ee744c4db5352ff239d0000000000000000000000000000000011f25722cf9db77ef8adb9caa250175e12412e6350b494395a86c31e1f5dee6c89cc6603f1dfd08a70344cdc44aa0c2df3efcda934ec9d2ab05f25d618e5a483e830d0452a88e980589fcd7cfc39e5d80000000000000000000000000000000006177a74e3551770e7d906222590108bae7b97a5dd3bdd2344fc12e7005f2c1a188ab9dffe68f5ffb0cc36294106f15800000000000000000000000000000000041b140c46868767119a6ebb58562570732198854c92bcc070f2a8d9be91282a70c5ab99e75cc9e5064ed628aa5c59de000000000000000000000000000000000f318ee33fccf455e46add44922bb6e99afd4354bbc79d7550f8d12d3de4f75e5ddf4e62624b116f91aaa80a148adaf9000000000000000000000000000000000fe012bf88e152eb62c0c906dccba469abe591687573a59d3debe747b7d895e4b0755f16e67fa9193a2fd338c04d243a4507a696cc57c0bc49fb4d1686752c71c9c816d7d09bd66910b23810d475aa02000000000000000000000000000000000b26c6e0106d4efbacf2dd0d15df17209b1306f388f493c096429c031bc4a6a535b64cb02b400433f948fd6004df2fa200000000000000000000000000000000061853cf1a32fdf4c370cd413754ea584d3722a08d58575075a7371e57a7bdef95386ed72f91c4893377f6b551dd6b1d000000000000000000000000000000000ebf17e60718c8563a1029ba035dbbba75e7191b4339d5d33f64bb35f34866081f26f4815e01b02e8330e7b7e9c428cd0000000000000000000000000000000008ce40f92efb5c5be48c814018fbbe45f1be45f5b607a6600cecd50d8f791de7d91939ab61204c2a1337c3f21b2c9d26518c1259f23de4cecd5e3a40abef5662b497ebaf16240f40ecd651d2ba50af0700000000000000000000000000000000123ef52cc44f36326b33234ab3348893bc722bac3674e43385b201f372fe4ea3569d69d4d561e26f8ea903e017d7376a0000000000000000000000000000000005b1707ef61ff9acb9e8b4dd6922daaaa2d8a7558cb55b1b9b96eb6d57c23f50a7955763c9b5ef04f52b09be8d55f4b50000000000000000000000000000000015b6e35d14da61e7a7fcbcb0dddaf0071d8d2d89f7179f44851947a2b9b0535d6fa86b5cae9713a73bbed909a4c6deaa0000000000000000000000000000000013463e135b1fd460cf042dcd0226e229d60cc2beccd8a1832df241e65a644159722a14297c0033eb499e5890f0caff1e5561616c195ccc1345421d8a6efec48f0a4dc8e89ee89599839efaf95c386551000000000000000000000000000000000fbdf4a533d355e232723fbc97352fc5d7d3d199934883a61a9ea116830bdf9e40d423256225d9a3458134332ef6e817000000000000000000000000000000001195f0ad227941c5e383c48f546be34762d158e6cee585650b6ee987f7b98e802f678abac6646832b30b6e12e90948cb000000000000000000000000000000001820d5fbb5a62140c6e8cd105a70fc2f1ed84e254c839deadae5eadbb75e1c33a07ad12ee92900f55478e91958a3147a0000000000000000000000000000000013849bdcae33fad27f16e91c6d46b9678a00491e3d70a8db905db4b1d2c6f02a29392b5b77c1472052d6f4d49f14a16737c77734125181c72454bb2d37c3725cf1f9b6d6f42b721bca469fec154b3e2600000000000000000000000000000000188fe1e394b567d71099fa13b5c8a5891636d83b6b8a08f410b080658a0663deaae4dca1afe8b9023b5e8e573c752c92000000000000000000000000000000000f66c65dab8e1b2912fd5285a4c87821888532f5107075cdfedacc4d7f75c6a74b4828d0b4c3a2c0ed94576654a7047d0000000000000000000000000000000016af44a6df79c8c9b6f1d8aeca24e024c454d7b94c9ed386858dd35c4158cddcad1207f9fc3ac9e3b748c2314f875dac000000000000000000000000000000000315e5e4f78e9fcb93aac78025e95b8bf82ce4c840cf565e0a868b0aac22950d62f7becbf8039a16ca3ea66a7498327d981483aa66e04351f4340fd2b461165b9a9983e91c148da78d3c8e0c69e77de4000000000000000000000000000000000f9a61dd1b3034b8cd7408b0a44c8d02f4fe0e87778d5d34f5e884ccc9e2d51eca6b6060b46b66843e8247b3c794e19d0000000000000000000000000000000005c47fa7799a0fffcafbbe4694dfe8d0f47b60f712d6319e9a56ac459a636460e700e2af80f9c688208978aec7c413af000000000000000000000000000000000ab1c55fe2207865ecf12e372a341c776d24c08dba10702fce1cd2c01eda314852d81d0ccf1c3423c2a12e8960677f060000000000000000000000000000000014f8a1964aa3240d788ea40bb51abc50fae2736a34120ca9585fb2d5bba4e5cfa201c83be1e00ecd1c46fcb2ebb4eb809913da6f756005ca8ab900ab686484483af07df768209a16d807f8b88b9334d30000000000000000000000000000000006441fcaf5e68b10e7e511a95e56b9613453ec6468bb126c5eb12f204c9681c69b5c296320f92a6fbb0b848f8ab5fcd1000000000000000000000000000000000141de16aeca0a2f991e9fca4b6ce8fbab3d66ee3ee4dffb0124384a7d4ba51864a53e005fd34516c92ecab33165944a0000000000000000000000000000000008543656b5495bdb726109cd98fa18e405648fa88cbe2e5fea5380b7d0ecb207f0343dc7888b9945e55156977336226b000000000000000000000000000000000b53d4e392f304225b1ef363a3528daca1d3a6ad64ee99d58491863ea432a29cde5edd4f390de45a567cf32112ca5929188fb33fb359f21bc5bdfc85d39676c2ca0a1e619bf8a8e8de62da8818bd6cfe0000000000000000000000000000000002e0c55a43078df575efb2c99b27c5632dd1c08bf28b6c0558081a78de58e4258d1b57d94ec6fa157add04aee06e7b6e0000000000000000000000000000000006d3f4f0791431a56fb386f4bb8e6744cd19b10bd0f2e65e927371ab488d3735e3b83400ddb25ef9d740a8620821b0ab0000000000000000000000000000000011e9cdfec8a8f8eba0de6809485911711149ca0ebd0cecc033e2e5ddfc195fa7de671a686edd2f56e5f7da7328dfbec000000000000000000000000000000000171f188afd5d9568cc5648aefb65cd715c0293344b9aceac1031f10b4a1e4b9fa2ab11114bd58f28aaa58c10ee0eeac65525ab4c4468a2ec0beecdb7fb072f28260ebb3d9da1a4c274b2c11a087e814a000000000000000000000000000000001651d9bddf61e5e54f86609c2479513ae84b000ad7defd840d9619a8361922dde81c999d0e95d8a3044c46fe0360c2030000000000000000000000000000000014a68c248808e826a3bb50f3c1c1438483cbb9da8dd67a0c9633a47f733e6aa7deb4a13aaebcd50de6e8e8f00000424a0000000000000000000000000000000010c8a94b9e0ec9965f6c8bd0c4279102ab682a14fc3c22e9640d68f240ccecfead9a2c6e69f7c8ed369cce7e2da50d5000000000000000000000000000000000181493e8137fcfae203e1b45189fb828dc9eb56887c89aaf9aad0380fffada423f0ab48ed068ba4e67a2b01a16abbfe55ab5a55a5cfc49cf6c36b5718e108f8d006bf7fa1ec3dc7a7f9c02a2d1e3fc57000000000000000000000000000000000e3e33fa4d85a35e8707419ca6d4fb6a61ee6b07ce152adfbaf6b5f1d7ccc253b59f91e4545848b3570bfaa804ad9767000000000000000000000000000000000c923a4de074dce3ccc94698bf6445af5847c0e6f22f225c589f744ec83ed0810913af2a6d04bd55200ffc738b31b01200000000000000000000000000000000186961ed1c6039476eb6f13bf1b5f6627b3b017ece57a4a5f33db8ef12347fd507398a421932d3d2a1d009f65d06e42c0000000000000000000000000000000011e10ae0139f95a2f1144810894fb98f6e5e86ce67877b949a2a7134c446dfe53c23dfbfd12919b24975f26eafa249216ce7aa7dcd01c1b7059ad3cc0ebf5d19ceaae633160a968c33aac5dc6adb942800000000000000000000000000000000029265ecf3c81aab289c98d9cdb917749ceef56e2e4d59de2d6c83907f394ddd1cce9d093a20206c2c1c215493c41c49000000000000000000000000000000000986ad139381e4dbabd6beba179600e1c782f436f84a7bd58cdd96a22269f1d937f88f25059214fe2a781ac519aa621d0000000000000000000000000000000019e296d5b17f78b3ffbdaa2ef5228fa9dd65abdf6b2c5b0f99a708c4721797b3b156b8df98a5a879f17f095548555da7000000000000000000000000000000000349677d4719445d5525cd65e2338463d232eb75721ca51c48fe52d0fbd299ddbd6cbc12546f056bf212d5700c3c4100854bce63dcdc0cf408b43690abbbbdacda5f3ebd9d9e462f89f9f50a9f7bd44b0000000000000000000000000000000016f5d5eb3fc3ff178843a7d21d3dd628bda120321ae44206d88f07ac001651428e0da95d3f0676e1bbb969a300406ce000000000000000000000000000000000029121c539ef1d7b9888497a362fda2f8402adf10a1bee11b53cf3dfcc6f99d5026bc386f86a2eecd0c276494878104f000000000000000000000000000000001320a402922f2a0bb287464854be6782046dd9dae4c0cd94efcb8ad8e0f37b7889bc97a3c8b4d3b3670a6924c8ee23ec00000000000000000000000000000000101fa8bb2c90b755bfba9cd7a98790b7bea2ede4c806fbd9f2006d10cf87c44172d4ba46ea40fb75afbbaa2abc3b6e9d7603824b834a83c1c408243b51cd2c2d31e2ee763d69e2ad6d369bb6aa2396fd0000000000000000000000000000000003285cb099b04b6acd333c7ac76c839b6c09388792d5fa1f2af0821e49dfbf40a06803c4cca92512bb76d073129a48a00000000000000000000000000000000005b2fdbb25381b3b67814bf6cc0a4cc17271416d16ee369b723b1711d968c355b755183f0bce519709723250515ba32a0000000000000000000000000000000002c7062ba4f642b95e028a364b0698b801f48af3c336fa09d13d83ec6cff10d210b55b23cad1d999889c83df7d1ab7e10000000000000000000000000000000012cdfdc10bf46097083294259754453e084010f7ee928cf540d44c80aa4f601247223a318700bc24114e7603922d15ae923c86e91c48582f19409b962be361da5936db02b6862eefc288f9a32d5f54760000000000000000000000000000000000669d760352e34a407aef8e141fcaa9468257b12ec08ec218f49f0769f3acd5068c6dc9d251a1b2af02a2d091f8ad0000000000000000000000000000000000064a7b4026ee3115cb730e56c4b9bf3e1527dd0f0ac6015f43d30a2f3d8d8c2659cf50247e70ca3c93d7e0a404d9faaa000000000000000000000000000000000979ca2e81663ed61486c1f841c19d83549388d798da72feda82283406d4964bc9991f876a6032382c35b605441ee7da0000000000000000000000000000000008d92cf77b44c516c243f3e6a8a8d3f9d3d7405820ab972338f700de1dd9a66d33b4a70540a30f630aa81fe1cb5bf057e1b3071b561a80aaaadb5cc24b348a2b6012340d3aebcca7e2f56983a8a13bf900000000000000000000000000000000198831a40fec54a210a63f5e00b132bb1eca6408335b85a75e28be6a111beea3b99d9f2fe5091ab0eba0f082c201c14d000000000000000000000000000000000fe457f8d215f390000efbb7fe7193ba02a2ef78e9bff6539995f01604fdca9fa3c010276afb90215890f5a5df3ae21500000000000000000000000000000000076771823180422495d89c301443a9d1fa141716e5e27205b8cb6b461a3ded7e6f196c3976cd6ad56b2e6ebb6b3a70860000000000000000000000000000000007f666efc677f6f767828e1291bde0ba0ca445ddb2d69d5d2fa090ca49e697ce4e00f55d2b706454be6d68f012d76efbb6863b755d3dee61328a60f585531c436663bbeab9afaffac49b6f0b57614eaa", "Expected": "000000000000000000000000000000000e1268a5e2f654c4038647a910e6cb4bab1d6ca3562ad4a9ac18444c8b8a3fdfbd35acf37f9203041fd587a5175ce86d0000000000000000000000000000000005e701a8ddd15ecb0231b7625f7868c81467c140b2617e60440a9b348a192e5248b1b3c087545cfb6d173fafe48d32f600000000000000000000000000000000071327f52b1325bb664d32c513fb12afb96dd8da23dd91bc4c3e8ae5f97d6bf673a5d03bb8bdeb6da3144dedac200dbd000000000000000000000000000000001852b86d3ef45aaeb691f454a345ed61104cecf0f444e4d841f2bc0402ea1291ef056eddb3fc3929ef4623f31016c3b5", "Name": "matter_g2_multiexp_78", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fcd3f253d018ef09a7c6e8f36662ab4190867a197e0c42a0b425dfb5fe61d57596ada28dde0b093676ce15d03406d20000000000000000000000000000000000df00598337060d603607f3b8dd16f277ce1882a2e9ced48e1944662323efc29b33c807653f31583a5d2198426019ba70000000000000000000000000000000009876c81a76986435d34c6d44d51cf1016c19ceed2432ef1e68decd64da2e31e42372c1a41a514b0eac0ac103ab6f43800000000000000000000000000000000121cf298ff8f610c64ca4a887c52cbe940333506ef2afecffe266b5b585ff737395e2c64adc23b5bd232250e67c7a62613ca0cfc742607bee58988df361d7cd5d809ba4fddb209c898cd555369fff566000000000000000000000000000000001885d5cdc3e0e0c8cffa7519e6914e5d85962d07633970c4174ae4587853f13970a1f5d7ccba97458b9b5046847ad29800000000000000000000000000000000105b7c0ba96d5ce32d7447351ded3e3f491a0e741e921447b91f22a23b64c2d749055a0593e5b47f0ff7815e1a4c9943000000000000000000000000000000000cb88fc10c94642ae7e1d7275bbfd51a2d40e9b29f3d51a1ceda577beeb131eae4b17418f9f358d47b4b9c9ca4960a3b00000000000000000000000000000000131a3e080b1d4e936d97d255b07b09a6210b5fe6900da87b5cc595a72de2b6ddb01809e2dc63ad460a2926dd8d3b3b2ebcca8ab454fbc576a2b910f140b23c23b14301c19e1f47989d78eeecf279862a00000000000000000000000000000000066b31c0bc4b3b9fe420dc095d551903a2859556d86e210c96480f1d31d449d85ea292e2432babdb71c151c7b215cd6b0000000000000000000000000000000019d79a60793957745077f9233aee7a4f096515eefa7c49473f09bbc73fa0ee13a2a30a08bd7f3bc1d5c412d671fc37ff00000000000000000000000000000000006882160e4fa8ae2c2d48ae389d8f023e2775adb7a815edeba13728b8f6b343c45788c8e9116445e9989e01eb43e1500000000000000000000000000000000000ce53ab2d81ebaf4a85b3e12a6175ad7fb6cfbae207a69a0fe2195ab916fcb582b097f09d9fc565b837925f68855c4b59f82ceeb6160d3256228d7a41fb3caa6f305b23142ab979e728356a13309e27000000000000000000000000000000000a30d335c035afe459dc262fb1bd24dc0bafbc08fae0bed47e4e204280eb96595fada9c4332df1218748921bfb1274c7000000000000000000000000000000000e37eb189560211d6fe56faa3b6e710878a21907fdc1a9f8becabca290c24b8831e28ebb48d06bd822300fd09b4d103100000000000000000000000000000000104842b88b9df6a7b8243494eb11eb62c89d1ccbde9f55fe221c2366d6bc9149178f177628c6fe7c7661318640295e570000000000000000000000000000000011df8599d72b85ade11261076e02c036be5dfa3b6fab4ff72ed7413a879c0a0742be6c36a32d0829a4e3171b0341c6a3995f7d2038ad02deddca34399e5b5653fa471d998c52bd52241840cdb9202b2c0000000000000000000000000000000019f6634435be45b099cc739fe5c2dfa01f61fd2d466d5ea464053e2d5acf2e0e9448b1bb7770b5ad426f8a872c5764400000000000000000000000000000000002bbd52efecb10b3bb6f8bd04a5751042d8598cc34e2837184cea2b5953ec125dee871d1f2f57ebc84849e3a7ee5abe2000000000000000000000000000000001962b716342df9c13c21d89ab5b8c4c0ca191440fa709627e0f240a7ba518f4c95adfc5973b6ed0af591bb54bd00937f00000000000000000000000000000000089eec676276c52bfbb2593ef0362c12a5f3c1a0566d5aa862f5f5ba1580f4dadb36c15fdcf0c3910ee14487ff146c8997b67e68bfe2d7fc256e6aa610dd91dc1b02c64186d24702ad8fa9f715b582a5000000000000000000000000000000001556d081a489eba4fbb0c20e22b8cab432a9f6ff459ab9b0e7ceacbbd46c8e24a2ee70151b019a1b4bfe47d934afede30000000000000000000000000000000008fdd7391113e8d9865ef48b60acf921b17c50744e6ad62fa24abaae54836b3d59a7441371bdfdcdb251d252a43aed7b000000000000000000000000000000000cc66cdb1fe32beb91b05922f3920060e7a95467381d62f2f036e6268af4128c9516780ea53e873993744ce932b901f100000000000000000000000000000000151f94dec958859ecaeb810c4b1cc7a707d0e1671cd4a1e3c811910bc8b95c6c944167dd280c7fed22f92ce7650beef998115b9f84e3ed6947bd6f0e3c65361cf360a65bc059515da852a72ec5cd178100000000000000000000000000000000004f88568c7ede48d7476175f1d2e7ded4312c24934f0d47794705621f8aa8a5072b86cc41e187f4aeeb49bff17a4c9d000000000000000000000000000000000ca6c579e86a68b4041150fbbc36da744d359028993681c34e66c537eb8a0a0d55aeb9b8da7fecb844104dabeb507805000000000000000000000000000000000fec63c57d3d3ca98cd1735b2f59217e163ca53b07b4fabc4415b98377d87e75f0fcc9b51c99a57ff61ca8d0016a206d000000000000000000000000000000000940e9f93f3ccbe74c7be93236a2c440b213a014ed51cb57fa053495c3d6f6c8edc08ba8e10be26e5faa898162d67fe327370e1037b709015e0bf178a41ac55774a813368e11ef7a764eb48abe75dbf500000000000000000000000000000000055e4dd9da22201b5eb64e3b9eff2eab614c48450424491a85c18e05f50659b88e862490edd11ff980b06696b60c35b00000000000000000000000000000000018fab38f58d3d541666bc29b9e94cb3940f1794b2aa851d079b9aaa1cf742b07cd6dc7c985c7e4d7d3fe683bb15d618e000000000000000000000000000000000534de5e1c1181e951b437fd17993e995fd4aa2f6b28fc3612cd4db615de742e12d66c03b9ced538c1c7cde27752c190000000000000000000000000000000000aa8580f1da71f2ae9ec26f3b6466813a40ba5bd3f89ed0d42695d420032540194617fcc2f13e36219fc0cc3886a69c36bf5fb297948e0ddc60ba26e49ef2892ca008e64a22ff2bb21ff70c56112f710000000000000000000000000000000001804ed7677fa3842bdc3eba708bf4fb7f7d4eaf2f1a46193c861595f64196398622df4358b9526f33663138b24fef1310000000000000000000000000000000011fdd7e1d0c5adfbbbaa69ce63c7c54525091289e4dfdfb3de772a8d5a958581cc23933deadcb8856540e2d0dc564dbc0000000000000000000000000000000013fcf17235506fb194e3adaab881c7aba4b87e5aef739e0547b858410e3cdbff0dab1980b1b30a7d03d617179ae545c900000000000000000000000000000000004eed0ca479cc458231ff969ebdd4e33732953e9f5610d78d4753b99c5f8cf73c742387b8e71b9be074fcc67acd71cf6b488b6b63cb8bf34efeedd9f95dff4d3d8c067c0d807bd1e20bd267748275d0000000000000000000000000000000001082b7796d35e387df689bcdda6e0316d343dc907822d1a873adea050374962b164ed27cea0e1b834997f8274e4c5438000000000000000000000000000000000b1905979a90c7a61f4ee2cf3a9f4d6ed4c724c9e216981b8ec34fb9b528018d237771ad620020efc2c3cb104df667cd000000000000000000000000000000000752663e72390108288ef4de3c3ea409c74e7051505b12083c41a2e8937eaadbd8cd61f96f7991722226fdd02dd8d252000000000000000000000000000000000f8e4eb7a3c78b8040a115c42b5d2fc69405f8334e948b8553f444dfef29bf3920892da431cd8394cf61f24e356e95694f661845e91de1c09f581c7612a25bfa0889f77c2add31b493b37d20bcce11070000000000000000000000000000000010884516bb9916084709351ed8768c6105fa451e08d5acb233511254ddbf4e72baf9c43b56b4d7dd129a38f5b34ee5f0000000000000000000000000000000000228fc5fffef746419cc69abb17cdc63ded44892b8c5d02f0c72bc8506a61d15a74ec4ea0e1d78f555ddec07f418539500000000000000000000000000000000048a4192c204b7441e871076d91d4f610c347c2d71cf495ffcb2e2ab808a8c1a549eae96e657d756d9a3b94db2892a2f0000000000000000000000000000000017a94d2472df89104ed96e24d166f922bb852b5ad80f80188fce65b08d39cc3ecf94991c6bec5dc12f9337e7c087db2f8b3bf8d5e529912b1b6e445f592a6d151c6f5d01d3b021a31a2669df4ce02aa3000000000000000000000000000000000f6293fb0e19ec85f43a1a02df9f59ad4fb0e49b16a216ce097b8ec59e781fdf176360d8492e8b77674ae2c0ddb1da70000000000000000000000000000000000e354d09aad68fce6cde40c787ba1e4488999d5b9f3fec25c9994b56bcccaaa746c958bd16ba271485f461b0d4e983200000000000000000000000000000000014fca0851b0bfdf2c69fb346f23b46135d2b7914bb49e297a0c1304d8c2851ff6bd0a0bb364938dd44680fe86cfe12e300000000000000000000000000000000164e23a53103dfa332e5ae09c7c898b95773c20f019d8b794a6b49594040e2e090db6a8047c943885dca95188e89a63b30e1c8f222019b877e66df0b6201b5bfc5b6c10aae340c55e74410a536ffb9b200000000000000000000000000000000146d37241ce4f71017e4423dd0bf907a12c1364ae9fc6dfe535c25e5e99e03ce157cbba2675829b396a69f92668107280000000000000000000000000000000000d5a992f5357615f436d95fa516212812f6811dd1f1921ba4129e84e3d487b6c97520995d8a65f6771dbba9d150c7ab0000000000000000000000000000000007b01f86574a9cb7eb3b9a19b6040055a5c11b13e7071078d16b9ad71f714ed28ad25db9511964b156ee34db22385cdf00000000000000000000000000000000154c29c6e2b21a75b14159b183e625c98a04be1850b22d314225e94b313619f641ead73130c1d6feb85abd8c9e172f6323a258d66f2296fa1c71065cf23c994eb8c6c35d35120d16790fec791ad215fe00000000000000000000000000000000075be2703b8416fa07a7cb6ae8841dcab1e36b0ea24231dba617a2fed3bebf8d952d31f68c149dd17eed136fe37b01880000000000000000000000000000000001156563f1401b731cc23c4be59e69b0e6a0827df4889cd9ef9e11310f679c1603a0d9c9679c29b8dab75ae51f49bfe3000000000000000000000000000000000663faacfaa92fbc095a5dd6b1f2dd141e248f84eff1716ee71bdffd4d28ef1f4c88828e3457e8ebf0daba1416d2d6070000000000000000000000000000000018f2871f5897aad9ff6ac45a9c0e78be8f312f07af5f1dab2bc4705558070abf367f1782af896288a7754da82bf1a5141ef4055b85f37b548dac2b64608d99ca293548bebe1e24355393520c34eda60a0000000000000000000000000000000001618a284286899f501f46c4761c93b68bc8ab3157144e4013e242e1678cba20a2d978ab53b4b43145dd6062748df541000000000000000000000000000000000c25da737368775e41ddcd9c64cf99a824afacb1d404f1ef46ec7fe4ffd89673648c5207551914e6e0d12c57e7d7682c00000000000000000000000000000000097ff49c4872e2da1f6c24fd6dd4667f0bef4eb30fc197d13e8b66adc425e39841dea011d79e4d775106a19ea1978f4c00000000000000000000000000000000147426b7d9b0bdc2be051d8f6cc4249014e1bbc2369bc32eca94684483f50ced2c07be6a320effddcc1ed5cae455fc92212529248c51c95b5b26961f27e6d44ef1c2b9233bb2ed32c3eee79ca6c6eb750000000000000000000000000000000000cf68f7ab056c4689af95b361ee3e3b1c1c48f18b5aa655cce1a2be217010814b3f07dedf6f9a7b835cb13e2afd7136000000000000000000000000000000000dd6d0fb94048dab34410dba4e682f020ed54a655099fbb6f6e94a31511960f0447d7e94143eea88195291b225d11246000000000000000000000000000000001864c6ad3f2f794239a179647d68734e23b3520b79952bda20acf2f5afe1b76bc18e35b852d35a5cf3b02a3ce86f640700000000000000000000000000000000015ea24562d7bc59d813b77b2a4943f9e98842b5a41c0c7026077a02ddfd3d5fecf352d4399f507fb12ada4ac495ddece9888dd839d9b8c236394c44d358f452a4588ae65d24ffe2bd345fc745de9d37", "Expected": "00000000000000000000000000000000080f0e50f90e001a442965ba7900997fcc89246742590b99add6d90428d3b61516664654bc8fb423f701e85a342a668100000000000000000000000000000000003fa9e84ddd754047649b7cfcf5bd78852abb298b3bbe6575c4c7dbc2e7595499a9f42f379a2463aa74f29e5c73a9040000000000000000000000000000000009e72d3c418726f6400b8cd8b9b649005f3b25ade40cd6f77a0c3cbdbef461e917d4453c9e07ded45301d21df4ec44db0000000000000000000000000000000015a06cac223217602ccfba4f4586cb184994bf08b324bf977dbb3884c394aed0622da7dcf5712970554d73b18e2733c5", "Name": "matter_g2_multiexp_79", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007340f432a5cd5aff1a1d98c6ea1c94be24de2d15a4e112925586c30979e23a5db93643308d3299e370b1f26bdd09eac00000000000000000000000000000000155027caae88381a60af71b2fa770e58efccfbb7642f5ef6b1591bf77e415eb117ab564aff8d9ebcd576f813b793ad2c000000000000000000000000000000000f604238d1b28f010ce8e45f2fe61d3ea20b902a4debbabcd54ce0ecd44a9540fe2bfe847178656fef0a5fd7e6d012b3000000000000000000000000000000000d7f503ede395dfa5682aadedc98bfe28d3fbfb52f42ecabc9eebc0e0a6616d3671604709f28255f50b62bee641d2711f812322dc2a7d5faa9e4877638faf8492d84e0f4c4c65ca3aadcb7eafed2106400000000000000000000000000000000176e1f9eac4dab0d253c0ff41b7600437b53a5ac5278d544a9620648e0bc4dc56aff0bda973fd1338f77fa174d8b13b90000000000000000000000000000000012919a18343cc166e2dfb92ff07bbf838779ef0479985bb85b3b82f9d0632b3f7a19d387f725a21729a77c58dd4d1d1d0000000000000000000000000000000017eb269ed75fe0403021ce70505bb60a711c91c551931605bb2a0773fafa07aeb47cdda382c0aa64f40f5e6e0e6bc77d000000000000000000000000000000000bed8ca999a4691646124a140fcc17dec02b74bd28b599c807abcaaff13bff65aff3892897652cd33b4ba5e4cc0198a9c1f6d538c5b4ae15c84581f8fd4c61160ed395816557fde197e1a013ba41ba0f000000000000000000000000000000001344d6902f5fdbb59a4c975847db0191beac284eb17cd92360e59f42cd7796cf2aa282bbd4cb074c4ee10b489ee3f2f60000000000000000000000000000000002158eb3429d0532792532fcceecc404e95a879be68b3685ae94016ca3762438b3320553ab6d5fbda3a0b615a04d996f00000000000000000000000000000000118f6fd8f60edf7088a0b4b49338bfcfc9c38be230460d7516f317b27c07600f504c8cc87acb0c95515c3acdc1b125ce0000000000000000000000000000000014eb422d44ec6931ac9860a6a017a907e8ed76de91bb7557e818dbacb19fb51457a1f45cca91f1d1d75a3567a3375b5cf2f6a4713eb692f7667fba2a3dc35363c3ba163519d95757daddefae11a95853000000000000000000000000000000000f2c72c53fdb1b0cd13a1f20407c64c46e4a0e461778b0e2d48c4f20be7c655c639b38f758fa9199b8395f706df10e7a0000000000000000000000000000000016e6c75cdfbc20c5dbc2dbd1caa66be92911264d407ce3c689ef3ae1dca44dffacb4c0d8a78ac959e47ac5c454f607bc0000000000000000000000000000000011c5d80d52e864b0a46fb48488f497fb85f51ac040c77b1d01336860b972858c0a6e59914112f6cd6c1612c604d26f56000000000000000000000000000000001136aa7eb63d6f85d665d0539975a9a51a9a3f5bd8731910c32130b1ec8b07c39eb42e4f61e7d22bed933d9fce1810581022e50c3fe7b2a65aab79de6d9e47c457d197e145592dd0611b1dc39941513b000000000000000000000000000000001306612f5119d33f177b8804443d14d04c8e059e28f63aa10ac6a1b25975327f378d5d24f0236e05849f07e99af93ae20000000000000000000000000000000017340f8887292264d498f84fce4af83573aa6cf1d57d99d364f2b84e1734fa4f9a1e07ddc81a2135ad5f5e0ed2989585000000000000000000000000000000000f65073250019ea69339379aacbeae7520c1ae10c8912ff827b702bdab2e15404cfc939389587364d811054b7d9f2b350000000000000000000000000000000019742f83ba0c9d36aa1d595fcedc3cdfa6c6f08579e66b8956fb32ac03530114ed4266738c57175e7a10313c8dd42deab80011c7a4aa905d4db6d4f6ae46eac9eb8bb18613d4ac5e5567990d7e8fdd96000000000000000000000000000000000b2513f906db531d052e8e6f1cb8d7d3c41c7ec3158b370268d1de204ed8fe7618b64ae35029d1718153b5bdb8439dd90000000000000000000000000000000001664c367a2d4170f463c90351cb321608e2a49fca6f3258bf10d32c39747084cf9d2c38d5241888aaad97985cb09a450000000000000000000000000000000014de15b86461cda9f1be69f43a9ceadfe7b7d1548a206f3237d93c7c01ee554c4245fb73827ed0ab72b99a62215faeae000000000000000000000000000000000b25e458522be9fbdde4554b1a0d9af157aeb7d3ec1f89185b193c0429125dafa554d7a531ef9502d443a26112b940b8f397789685a736375ead2312874174795586e12b230669a90d072fa636128c7d0000000000000000000000000000000006862c0b0e3d7bc4507bea1df82080745aff21b7549b372085776be2f88aedd4cff00ab8258aa21e63340963bd0d937b0000000000000000000000000000000017199c5ec3a2dbc1f1e8d74648cf8da247e35cb07df22629b3845274d29e473819a31bc344f2a2bd6c790530cfcc0126000000000000000000000000000000000e7fd1ff41d86a02014229c5085c886988dfaddcb60f5c7c81063e8289aba846337d61bdde57e276fe6c65bdfb48751f0000000000000000000000000000000010efa6aaf7650edb0c74d30125e36cb67cffd1c7f57932d92ab4aaf36f8d9245d7c75dc2b3bc8f3f328589b16e26230e28e325fea39d61269c576626984f85ea43cd683b08c3ce111aac0005adda39c5000000000000000000000000000000000935de4b16f5f9c0accee77b5820cf36c24aad9953d40a2409b7e6040f09f85da7d2252843f9f8005316146caae539800000000000000000000000000000000008a8c542111951b32bb0b50f7631f8938d22e298193edffefa3e0f5c861ac8205ea9b865f9420ad74cd22b37c5cb56200000000000000000000000000000000012ddd660879a1f52ae6284e14f2ae6ea381ff3f321458cb76bfa566b04ae19f3793468d0aab652a82671be74332a3b7a0000000000000000000000000000000005eb148c35732f7ababc73861b71fe4ea5e25bcdd675e975fadd0a9e0fc54e175b2e39dcf0323f4a9802a68baecd25df3cfd9bc41303803a0b4edd121b818a126bece309dfee4133aa5314cb8a91d08d000000000000000000000000000000000bc351eebfd3f3c332268055af1655c8729cea44eaae803607198cf747280adc0d3dedba137828834af3e7179ccff4c3000000000000000000000000000000000d8a6cca17e1c6ceace7c0ab1333ba76ed6c3b114bf99ff80127c6a17eb0585bf6fcce871deb7385e9a8896a21c065ba0000000000000000000000000000000013222db97e31e28946adecda10c9ccc9aa9fce33e0aca51d6483d2f0c5bc3f33994ad516215f8333e22167164ef5459500000000000000000000000000000000144d3707b1898d35c65ae2c89b1570971a9494e8bd23df835f565059554eb7b5cb66a6eec890058316aef43d6c6ff55c8e08fed30e422868f37c422d1efdcc93912d55b0a731479af863dca4705e0c5000000000000000000000000000000000138da93a9a4948d41a6fc6d057a217faf5efad863b45ae8eab311360c033362213edb0ff90bad6c95f60b8e1131336e6000000000000000000000000000000000f41766d9b57b3210d315a2b8f90aabe591c1de6037ec79c0d72a283f0ac3094436bb97b82b7ad12ff4f471a41227bb50000000000000000000000000000000009aa4f5b674782b7adce6bf75ad676480f96a58d68dd7ef8d1fa488cfab794f06e7754e9315430189eed265913db8b300000000000000000000000000000000004e2a4a48f02079c0ed50c1daa91b1216af481a982c7aa64d8ba90449ed886cdeddd0cc08f1f8764f7f8c5988fe677f5674ecdf795b48d62f0db0f9cce057fe570d15c78f2eb7a77b66e4895a45804880000000000000000000000000000000019c927bbffd96aeb9342666e1974d30f9dc215e8eca41c24244c63c106331ddad20d64c79faf8c5baa45cd30b561e167000000000000000000000000000000000523f063de96c9b77bfe5c5045a007e155b45dbe68c5f1162884f1d942bb385bd34c2a37e5e67e6dae4a23d600d75d1f000000000000000000000000000000000c221006f5bfc8baf43826258d0588d7c0fc345d68de1add1693bb897959c2cfdbb9c165e82c0c787529cd7be85afbc50000000000000000000000000000000004218e3d52b42a4504611929f94024326f38e78bba2aba105db3ffb4a51f8906b060ce2302e22ded60714d652a234c1f288fc80d07393f629ef2732879332a253b49d26ca7b2bef7cc49ee40530b2b3400000000000000000000000000000000189e5063a36b0edd736bcd9f997f4b08c62d33b27560e2e2b7b40039e7c63b75757f23746e70a330110d975ca683941300000000000000000000000000000000013393485ae494b1f1467cac9a8840c695d619aa1a78c40674038c053f264c1e20481f2005abc7f0545346f5a982d05e0000000000000000000000000000000003f2be501504f4d37e12acdc54b3280671ca0762a063fd3bc04473ed5a051cae3767044c002b7ed1abe88b2143af08750000000000000000000000000000000009d5952af88514996336e1ff19409e3e4eb3079f6dea22f9738f4a331ce842b151e0b842b68cddc10a711afa6d3242b256e69f4ce8fbd8f86f546fd6d129f9760edce7c5e178dffaf987bf565e9bb7e9000000000000000000000000000000000a79444c673e630f46bbc5a9e06e8c023978a78e3c58d72910a04c3733ad873c0d0de61448076b2fd3764cc17d86d94f00000000000000000000000000000000110cfd215d67d4a091578203855fa0e85feb4dfd0076fbfad20bd092fb91b528a4117850955f5fb6568fc5844e17bbfc0000000000000000000000000000000012ece0577512182c50dbb4a485256e705410108d9ba9c8d57780d49e2e25a0f89ed1fe917797b902aafcb8f7d98fe931000000000000000000000000000000000217cf1dffac7ae162181d43ef12e3e88da4840f1573d7ffa271f64d8d54861099be37b644e96e650dc613975d8a00a4ab40e86212189e6f5925df810141c132eab20c123166cd8d3c6f40f5dcf1b1cd0000000000000000000000000000000010bec428b2865aa7c077c168dc28dc549481c6f8367a5b84cbbad661b0225cf0fda3e840d96c4e4efc36c20d48f23d5d000000000000000000000000000000000ded3a1e9e2eded0a11211a217f9355070361f0a5887a7e19c74edc8768000311cb9dd8513977ecfb45416cda0908cca000000000000000000000000000000000b99ffddc79e825f0b73f2d0229d66e51624d854d00bdee5aa7a884dcafa1888963e2a2149db0f6e40ce3c67941a391000000000000000000000000000000000147618970c71965684bdf0d6cbe1de189bd23bddb2b861c9636efdcb7a96dff27bb1ac70485b562e78485a1e8e56531cb96a5b6129c58113bca713e6905c026c0bfdb6d679c203cbe2b256b0a49ecece0000000000000000000000000000000001a402aba8fb28dd37f1be11fca037baa99a6b57188ccab66208a50bb6967dcacd1943cca73e34f6b2e2f72407103a73000000000000000000000000000000000c0bd64d043fa4e3ea566cb84f9139091891231ff500b67e5fd451805f79003f6303352a4f0c236063d60d9088fae88c0000000000000000000000000000000002861fa7d0222711ffcadac86e7b9e7b494f5561c22544bd0876fb6e1b2e680d0f7074c2800312cb233de2412ccbbc8600000000000000000000000000000000015945f0c83e738a17cb1283d08d63ecf12a7272bc62812006ed78254bfc45ca7c42306cb79bb16ed17bea600a4d62b5d9d8147c4453cdeed971242d316e350abead3dd08e93ee54738a4a5aed23affb0000000000000000000000000000000002268793f6872f7715d802c0d96f3b3d850249d8e70aaa97f19793d2c92e7cef384aaac603eb51525c7ceccdd0211fc40000000000000000000000000000000002507d680a2db16746810e966d1ba5547ac98d08c8402aed0859203e6dae0cbd87a9ddcc05119c1ca08fca2fd733882200000000000000000000000000000000192426b6438b2abc7386599afbe09081ed4908fbeb807a65bcb7c6676aa76e5e0c2c87612cd109cb124c73b9c8e0591a0000000000000000000000000000000017f125a2ef5246e7a19e1b2741b31b9224511ffefe63ccfffaef1b7949e88af573e267d6c7617ea97bbaee6d50eef67e1ba8e52986d3bb0421eb53b18ca8c21b9f7e631f16b99ec56748baeb541b32e5", "Expected": "0000000000000000000000000000000018c2f533f464f9768308a56209711cf9b6653e8d38591d782ae2374905f99f75c0d42c63af4b534056c28599a9da874400000000000000000000000000000000071d4d708f00875545f381e164f77183e14faab599e472b2857c15091254ddaf5c2e9df809875336f92ebcf5b7628da500000000000000000000000000000000099b207cf6ed022289c27393c32d0b83aed6c7b57323e746374c1a8e2ade071a5293168e72f7aab82f6c2e39b97b03830000000000000000000000000000000005dada01b4dfb6a52d998210a67ccedc11d6aca2405e0836280e2f7c8fd7c8dd271c815a2e9ea1dba6f1ab0d6e89d756", "Name": "matter_g2_multiexp_80", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000195d3f440857011bf9b764ff270b8ba1d9d13daf48933e49c12ea20d335b58bcbef1353d9698a7e795b4370ee385f12b000000000000000000000000000000000716c151efc6e611b5b15c749eaf02816a86e267428750741b167404a21116f2025d0d07c447b9c7bee8edcc2c7b76d30000000000000000000000000000000012ba0bf62b35327111d09b402db2b75b2e835cbe581638af2fdd6d06034774533e6501be3de84e7075e4184e11fd81a8000000000000000000000000000000000329b14859d004c146047b03870371f53936e078ddc69294ff1fd6f42cf2a354a921e5f2e5c125c454e20af97dcf769e7d39b55aadd47afa3cd35cb85a89e729ca236ada965b99f64ab302a84952babd00000000000000000000000000000000042286dd205ac86fdec3fee779059e2ad59adb62505f7b78606c128244b031c53dc40ebc2f5afdba348892d5ef4c10e7000000000000000000000000000000000f960010d4818846b3a0291c6fe1aa53bf0eafbc0e0968e3ee82324452a7c1a8041c06b4db9cd36a07c119c9fd2f9038000000000000000000000000000000001876da0dca72869708b8ff9ea0b74ad6be25ba82ccc76660246413a04344f2b72e5a7f6fddb58e9dc0bfaa6b33a5fadf000000000000000000000000000000001538ad1673f117493d998941d9356fb9907f70c279bde8ae8813b9c7b371344456f8e67cf02bf3401ee06d55604cadf9c41ece17a6d8b4a22994227b37a9d73e17a88859683afd5d226e113246e70cb1000000000000000000000000000000000d91319b4a5e047ffc8a68e10c34b2b90e7f3f08f9e3ec53ed12bba5f66c168c20c6583ba2016f0137caed834845f7470000000000000000000000000000000018d5542919674d2fc32430175405d806ae4abe3e1236df2188bf4c9ddf66c0974036e28414890212ff8dad244d11e3c700000000000000000000000000000000160b128f1ffeb97edf0e62dff85e3f90fa48567ab777a7937a2c0e4659df180fae4565107c2236a5f2808e42a03a4ab40000000000000000000000000000000003ee74d214ec491331fb9db8243e75570daba9feb587671496cea4b480d80ee162c6294c082203534bee450c384f645e69700dfa3b6e5fba735d1fec3b3adc90719ec301c406ac40673f4e5677da3227000000000000000000000000000000001951afa33800a366944c43bb42b8c5c8beb9ea2e1cead8b84e0f94af51e4a156d9454c0f08d1b13c692c41cc480fdefb00000000000000000000000000000000077f4543fadad6f2f8ae8d5d98f64965bf9626971e7efef5221cb4d95d51b8764324cf4a11d0ff5330d58df70cb79d92000000000000000000000000000000000417251cd0c1b32505377e51bb30ac8a8a3c059644b9ddb5a058b3c6e1110e1c71ee19f549b15090144dcf4668d0d50100000000000000000000000000000000052133be345adc562238c4ecbaf76ca4159fc11ff563ab393317b03065ab668e7df401831baf7027f0577f5791b1ca3019e8eed297661c06c92075629e163e80a08835254f7af8c0f179400be114ba7b00000000000000000000000000000000067bd52b7a3193d31a4f1ffb76432c8d4108442616f17056d310fbfee2ffaade9437e2bdb8425cf83233f0c632efc1170000000000000000000000000000000011b045d6eebe1bc8218b696b5e81e78db78eadf1b5d987060c1bdd73aa65666f77e1d6bb6f3d939d64cb3e6bda08994c0000000000000000000000000000000016eb5ea5067413b72632f5300efbe0d01a284b2a59b68d0333c269da9302bf0f0cdc923acb27e51bbbbc1d4086e6b06a000000000000000000000000000000000ff37b8812963d9efaa1e6deb5cfd34eec70620fdb65808739295a819e03ebcc8f501b8194d0b3c72717fc922b785194199ca6fb7f6df8a2e72971c5738ad75d84935e922587acf3a6b6debf3c37bb5e00000000000000000000000000000000149b5e0df255281c1b518427094cc0903fe89eac9a6dcdc379b8ca30f3696d89824c201601fc4b0795a3c859a82893170000000000000000000000000000000016ee9e7d957f439d078f3c5da98d114a1b5bc4da9c17e117e1f540dcbf83a349bba94def4b87b63247f190e3b5813cb00000000000000000000000000000000005d4f56bea105be4bf1fcaf4f25df30f85968d59e60b1c438c28ea0f480851f5ab9c05a7ca6677e6f12c7dd3ed67c2e0000000000000000000000000000000000dc0e87ca5a8b339b485ff3da2b9854a07e9663c43344dfb5ecf3ea055eadf67405c43013e15367fbaa55f1bd8e222f98159c6b98bce6ed31c30957280d8f7820e9376093d1ec9ac68ce0777d02b084b000000000000000000000000000000000b0575fe2adc9ad66209cb2191efc2946672e4e81b96d50493d2125d9c83165f0c4d3f714539eecef9de0706cc20da9b000000000000000000000000000000001511649f0cb6b86111d2830812231ad37df5500d7ce1086241591dc3cf40b30f1c53dda3133b2f7fff253c94d5eb98720000000000000000000000000000000005b15e4e32f4f4e46c1560792a9973f6ad63f5176694734f379375f16a08c162a4a820385d3ea6c191bd87fea4f5c8cb00000000000000000000000000000000089218403fef08dcc6e679b49a74557dafed3278d41ff36a9801db091b91de0d46d779a40574fa4a3f2baaa1a14be098ef1bc580e0b52b10b049f07d5115a60ba96d14a39e48ddee3c219f11c3b2a82a0000000000000000000000000000000001c35a3fdea92b28c9ab4bd9ea592b998853a73be844b9dcb500ed6704bbf3ca4ed4216dc24b50254b6ca75c4ca3e7fc000000000000000000000000000000001815292d2a365dd7f41ecf3f9a89e040bab717241cefb3155a097eb9885d64fa55f5de7023f2ecfd33f483ff304666520000000000000000000000000000000013df522c72805b890aef97864ec6769f569504fca2d6a6beae97f80dc92643f8014daf3dafc0040dd7b985c0d9b2c462000000000000000000000000000000001155ad4373a8304fa6301cf48b4ace135d6a0c08cb06d624f42f88073e43612ced3cc37235422171b43af2b4ebbd5662d06f6ed682c56611fd060ed2b3b1dc48974769ed6dc504ca3e0b9f68b77e63c5000000000000000000000000000000000bb9afedf7417ca31beb96486b024af13c06007585d785efd1e78444daa9bc3c03e1d64b560e8d6a18ccf77a8c3c8d05000000000000000000000000000000001652d3adcf1612e487a9ca198801afb9ec30267148502684c2b91c05ebf6c48e2ce33f9c0a986daab81d5359ec1b503c000000000000000000000000000000000baf3d34bf4a78e3b9dfa637c6392c7f4d7ad0ec315d10748784b5b60221bd9da0f4b75c57c139ac2db329e270d559de0000000000000000000000000000000000c30e553fa2324d552bdbc7d2dc86531340c4894495ee9a38b64f5bb6f92314021a2a00c4bcd8837e55a0ae2676a9b761d7b314ae9d9e78f628ec5a207d12e2dcb690688d256fe46e0affdfcc9775ae00000000000000000000000000000000159a1e4e87c35aaaeacdf21efbf8ed99fd6a2ddd7e990c12407b1417edaf185b8f1df9bafbddfaf3d581b5d97d7718300000000000000000000000000000000012239ef7b1e1009c81098aa4aaad8ee9e003530db5afd49867aec47f46d5e29d44b5e62d80d9e832937a299633e863c80000000000000000000000000000000016af6f74392461a9294d9f848508651ca5c0cb50494ee7c6a334bd770580b924a17beb7824b489e7e101ccd50aa0d5cf000000000000000000000000000000001912a0f54ba4fbecaa55c150ae93455e1db6b238c032fa7992bc8456f183c09b6005dd6398a77ab91cf547919ce7485b03a0c47621401fc20d2c78f7e30814de9a6f838d4328a5b5be628b833c31a6fd000000000000000000000000000000000cf1cf7a09a12f51d10059425042ef8e140718ff11d2f17897a0156034f73ed29496d93b8695cdf609280d319c9bb742000000000000000000000000000000000b2c4d26fa1eb72eed1a24f27229d2675e0c6f91e3a4eba7d34b0fc1bf5a9b4eb49c3492d9586669abaf25a656e1f95d0000000000000000000000000000000012c5c83a03087b2449b71e9037591fa265d710ff6d869bfa18ac37cbdcc93024f673128db3dbad9e3517501af12f2540000000000000000000000000000000000ffe5824245e43953e3d0adcd5fdc1a97ffc87f8c5473fdb0fed57000fd126a9925ba7415c698248c51c1f3e12b270d5e4ac6a5e740e073c5ef8af389e70c2cb8ee8c4c04c2ab4c48c579e83e181005b00000000000000000000000000000000036aa888e40882b2d6ac71d66c88543e32b4a0a7c959eec560e3d26114d8aeca63fd87dcbb3171622c989a6c7a204ac60000000000000000000000000000000006a5e552e6d2dc95ab8636a8be16bc79572b47860bb88934bf04c195ec01fd71eb91e45f24c58bc2812ed5fa10c8dd7d0000000000000000000000000000000015fa3ffcbd4e562a4bc29975cf8c1eedf442e37374fc87128e6f68bcdf6e996f6f054e0b8c608e651753de96655b2c100000000000000000000000000000000019bba7c0b170dfc1f8fdbf7a2e09ca0c4027a6aa6930d15dc2772a0f20e5e56f0d11644094dc866595f801ba5552e6c4c1e20d8003fec60f68c03942185fed934ebc197c2863174442d1a1c8d1424d31000000000000000000000000000000000341f46ec06a8def4f044328bcdaa308798469c767d10e5db34b0ffb6f550421c67c6fab7b63cbc7504e55847cee419e0000000000000000000000000000000006952e5f791c37dfebcfe69cdef196dff66563b29e94927e3ab34365773b93e72251a63af4ff294af88d45fe0899a2c3000000000000000000000000000000000874dfe75b31450e99dea063c090e32d24fbff9b681b64a9dca5f967f82003005b003d17eb869bd3b37d4a412bcb28fb0000000000000000000000000000000014203b69e8af4e25232777f503d5e82d6121256fafdff1b037f65d5aaad0f09ce882151d6bb4705328400f00089dcc7a7713ea72a2ee99442232472ab3dea9307a02fa1279129d994af5588af4fe7af4000000000000000000000000000000001403fa3f418107e0bf7f3f4bfcf621812d32b1b744ab5a4c37b5cf946a5e5dabd675c2b70bd355590a9883436c5e32dd00000000000000000000000000000000069e006f168bed4439fb46db9ba4f279f72ed608c12a05eed172608693f42cb1f04aaa54191f4b0b35f967bf03d0e63b0000000000000000000000000000000003f9ce029f6fe605802de64701ccdf52bf4aa299400a6e1c36f5a1f9173bc11a38e7628f123fdcae01d2b260f77c577c0000000000000000000000000000000009c9732809f60635115cb479c80457c6cd8dad092111d663c0cda0da1fa71c9bd6795ad013d2efaa4599c8ac5c88e5f26f128420cf6ab4616a05b287191105f25c7212f2c39c3230fa56bc27cd06ebfd00000000000000000000000000000000115e08d8e4dff7adcfe46a416625be0ac26ea2d7900f5fed497809a6d46e7faa5b47c52ab3bbeb9fb16d82b549707ed6000000000000000000000000000000000dd1b31446e44f64ea5046dca5174ae854f6bb5d95886fb95aa136d432f1a8c03ef1a5f9320f89c82f764049a7f678a40000000000000000000000000000000014879783c07e6986cd393fa1e0ca8a7e23b2c9efa595229fc0b6a11b9c232ba33e92962a1087fe2ba0532d7b541827900000000000000000000000000000000013dc6e2bdb2801333e7f914b99f30b40125fa1ebd49b141d88a8c090b15ec3250a13812a19c3c0751a4e5ed100a6f0ba12bacb3419c34369dbfd1c968334f76bc50885028758a975cc812a04e6feabd6000000000000000000000000000000000a2cceef36ec78dc702b6731dbaf8cea1dc2b41fee1b235673c6941729bc5631e69ff37900479391a4d10b300fbf3eb40000000000000000000000000000000002f4881fd626f4ac434bc1e59716e5e5ee14dcb9adca4d639ebc9d86e323d274ad8ec0a4b1e6ff92e1fe7928d48924b000000000000000000000000000000000174cac80e7bc63989f58759e123513b611e9849b44d43a362f2eb84421ad008f3ae9e9f0f233e49fc8e10c1824ba948200000000000000000000000000000000143641099c8a6c8153dc8ce74debe795dd6c4487e8234f164f9f8dcdea6a53619c04a8fac215421f985557b5b956c20a5b00f26af6f59620c7130a6d12cf2091b5f52a6b638484fc1f242dc1773be256", "Expected": "0000000000000000000000000000000009807ffe8fa881b235b1181d2d3f147dbe21042524fb0c0b4c90fb122d160c7b895034ab32e20324dfca564ca6e3183c0000000000000000000000000000000010f6da88525da3e86ee56cd5514a436e3ce4128e437a876be130a70c42444a05ac269326c84dca532ca2e546860027c00000000000000000000000000000000011396a7317918841ba171ea46bbddc9bb5a08db7c82b90008c6982b4b79a4dafc151081bbdb7b9fb79784e603e15eb9e00000000000000000000000000000000070b8580f303b83c643a484dd031b780ff4ca2ec805d8c538a0b0c791cc7f8163654f5e5a41776a8681500a6690e24a4", "Name": "matter_g2_multiexp_81", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f38906bd058e4d32403fc3d39fa57bf49c0da65ef42fb129332b91c184185de4f9f0bfe8908a44833ff4ac4d65b88180000000000000000000000000000000014ea6fffa6dc462463c15feace841697698bc521f608ed0d16be5097bf42aefcd1f73182f37b6279f989e9668a8076d1000000000000000000000000000000000f56d296323177ce53c6977fb60e445278e59ed1cf92e3f68c570eb7a9e5f8afbec5e2ef64674bbb54d7016c829f72750000000000000000000000000000000001b29012ff3460cbe4a07bdc65885718f217cf177866823a7cbeae18bda67f65913ea20bb69e0ffb31bd82f19862113dacc5a8ec806f2f273120457865582b08697904a2c6510bfe9ea21eaf682fa4fd000000000000000000000000000000000a4126bff91ada057ceb9a75d577120c7ac8c9ba62151602414364cf88a3e12dfac90b5590db3e40c16163177ad4e7520000000000000000000000000000000004a3768d326c4ebcd5ffed89341e8d04f89e674f3f2aded3205a7193e11c20115b3c4d595b959d6e39a03d76f6b5925b0000000000000000000000000000000006e0ae4a9c45bb69c3a1c65e26e4869f2eb18fefe584e4598ba99c0044e8d911145a5db3f57194ceb6201e7eab9a81b20000000000000000000000000000000005be2ba6b147f3f2052c4877c90ca364427c6721ab64dd35e89f14f3179564d8812b9013e3e3db22f69afd739229682b98c15a259b4dbb8c300a39f0af558a9827112f6b4c5eae3d43bbfe057eb113cf0000000000000000000000000000000004c36cf955fc81bdba4ea8d2ecf934adaa57fa4073199f77bd0428d3ef80a7d7102179d4a44ef0de887bcb3ae915408900000000000000000000000000000000138bd3ec7a1b6fb65d1df6bc1d2ada35aa52b06729c10b5d45b9bb7cbbdf41677942b99eb9c2d32e3e73da7d5f9cfed40000000000000000000000000000000000b0291ca10245e2f7a963fa07ec62b15f6bf9e7a5a7839840ebcbe538dfecaf2114c7864a16564a5b3c85c15d97fb7a000000000000000000000000000000000b436e912b8a71cf8050d10d59017eca6e494e5440f02d2816924ac9cc2034bedb1cce6eff5c42f3dc57a74cf1b51cc0a0e68bdc97fd642581f7e62ecf134df2c05570713c96fa733d3db96ace88f0f0000000000000000000000000000000000c105ac7475ed9517a0b07f25a030a5616952d817f3893181e352907c7cf4ec9f5f3006e37b1da97e9cae4a1213584e20000000000000000000000000000000002c112c18268934823d5946d2322d0faec497d8e18736da91d2af744d90f74136c49370a4b43952152c62820d25e52ee000000000000000000000000000000000fe2818a397d70543e752e7022f12bab10f1b1289cee61a0230d545296ec872e34d8df6edf7ce9980f3c153e6e51d96d000000000000000000000000000000000f479e6a52bfaab3a31aa9a461adbec8a390daa8eb6273f9e425eeed764a6dbad44d12778bb888aa5808df272edde401e5512cac411cd103fcd7497fdf47d1221999bcecdba30467f06ec356483484fe00000000000000000000000000000000016106cb42ffc41d5b23bc5b06001473bdfe556d375fac6a0cb0a12494e9c02ca2dd6133356846e1759a2c485faf5e890000000000000000000000000000000003cec25b0f5d1db0ead5319d6dd15517657d1fec442facda4335ae0bbeff606fa9caa6a4c00445001180aaeef895d7fd0000000000000000000000000000000016ce3573fbe27a8d23b3ebd22aec989d61fbd0e41a519c5e2f1d650f2ad73adcfc8c840fb12bce83b722a0cc69164e21000000000000000000000000000000001434d13d44fd8dcf776c2a045734dff7c09ded31c9e3a4b5e765cf26fbfea4cbb4ac15c06599012a7f2cd572bfafd78ba32f6861298bcfd4668653544b4551d7357d64f733365a5f08ebf297a09fd4ca0000000000000000000000000000000019923ffba0d08ebf1bd43393142d61022430356081c18e37804172082c7ace987ece2594f4852e84604a77235c7795e000000000000000000000000000000000123acf9e1a86846ae27d5fc0358afa34fe9d6b68232c9ebf2d47cc169779c4bd24f225ad30886fdf68166adfd9898abf000000000000000000000000000000000a6061d4cef29d1e3535d54a2e36373e2c16f91543f53e1aca94c4abdabc663049673f2327ea8bb574244d7f5c99e981000000000000000000000000000000000b1f3e1d43575a74584ec7a3280f8b7196f9b99b5e911ed33ba6bde1188c82d906f0f8e6fc2b285fefa0ce59116e449524301fc5c3ab842d7f6a278fcd32249f1daf86a31dd254ab9a21941fffca98a1000000000000000000000000000000000373d36dd0fac76a0fc46ba5da279ca3be5a1f8d799570004e429256787110d4fb746f65a8527d0ba681a81b9980bd5c00000000000000000000000000000000057933c2b3e482ae026159211c4742264f7e890efbaeb6e14f3bf66c80923289af095dc97b751a117e181ef917d049b000000000000000000000000000000000068816ad2369bb57b3430c657284858d3736c327284e7410b61ed444786bcb34a66db9c16aca583aa9722aa8d7975b440000000000000000000000000000000007fcd7dbc062d28f6ef906f6a455337e517e1d6e6c02c7c0b2b2685b79f56ca3436c1bfa0ab96e4a5eb0c2e2c321c0dc17a920aef58100de67c482ae1fabf7ec87cf3447bde1e19d9aaff825695706740000000000000000000000000000000007bb0ab060cc12002e043724c0fd0c8bad30e08b65ba9f2fe5d09d18cac4bb2d50e29ee14590ca7bfc505f3ee3d4f93d000000000000000000000000000000000e680653d29eb5d90f21802f543eac3102a1de6d2a5bc943a53dd9b80bdcaa6951ced2eae5e2a25448b40468f1923ebc000000000000000000000000000000000b7494b494019e3ef36d5c620ac56483fc6b1c8fe5c6f67537b19f56ef01db327812095fdf805d3dfe678a3ed8bb6226000000000000000000000000000000000291e5b98ecaf7aef0374647d28fb9f8785a64d9165de407d062403047da14d4ecd19fad8575070b278608e16b71d387d76d5eebc3d099448ce4a8ea6dec047b0f062c6361ddb9e95ec898442423a31800000000000000000000000000000000186536e3ae3edd9cc6bc24fda6589ed26e72e06121e97e1ead65b200fa0578c6e53d1154dc7b14e7eccc3a53237685060000000000000000000000000000000012fefaf6c76ae7197b99571e41a19b14846fc4499e8e964ff750e7c3ffef6ab3dc19eeb42c5f6ba44a573bca7a15166b000000000000000000000000000000000a135db813a44a21174cea3a0b34fb49f273877203ccb66bce44b2b58794818d8bc1df27544ecbf780823467e2e4ee6b0000000000000000000000000000000009b08f70cdf4e349e1a73935de9fb2ad9f4feb8cf5f835be78383fda2af94d81af253ebce08cef825764151d5713ae60cd4cc1453dec7ae335db989886fc0964ee73e12bab69ce1f1458d1416471176a0000000000000000000000000000000007976df2d47c14374e554401c4d3330bbf6f1e6b8fafcea1e1974af61e8ebf493dc0473d34b30b0b1cbee082550d85c200000000000000000000000000000000177cd64db8334dccb17fb207e467e5b09e891b05df7658d9b439e3cb72bf3e0a70e84f96fb5e448f33c003c279cb38d800000000000000000000000000000000094d739a02b8ea6ff8113019597f41df4728b270770edc5e68b1f5c32775f0c706e3f31c0a82059c1ee150b89097376a0000000000000000000000000000000006ed888aa4bdbee94ec67500e30d654071774fe22464dd5b900fdc17b445754293504b10d044aac8fa0c289f0b2d9dce6d207c08e51d64a9a47f5353faac77fbb184e1123d38e39bbada85534cbcd3150000000000000000000000000000000014a16b856b04ac4b687c79f2b4e1dd6d45db25b382e0ba6687afac648c9b6384cdcfa89812f1a726bb4d1c22ebaa6668000000000000000000000000000000000764088e337df6db30ce8aa23aefd91d9e35be911c9e89ac62a1e06c3d06e28efac256490400fac4490f595cd03c127e000000000000000000000000000000000894856fa1c8488fce182a9c7749f7953e6a73879b6e743fdb8c780275447122f512806fa83d5ad528f8f61598ed01d20000000000000000000000000000000002b33bfd09e0ff452c3336bde08df0102162488bc83c27052447a1e5d16c9c68bc529f96ee3787a26d2009f22a1246342e1910b704d39b6a64cc7a44e44ba3e8b7e64ddfa90dfa6b5ef571f9ff7d7f0b00000000000000000000000000000000133e2d092352d3ecef5b67a09c2be268fcd4fe1f7360a8ce3ef5f33bf689242961a140d9c8afcc1e2fab3ad4e3dba49d00000000000000000000000000000000101eb285f0c462a22406846d82ca6a278520b65132d2008b124f6647a642c221b0c3bbd4a0abe8af7417e7aefb81b5b20000000000000000000000000000000010958cbc317f1186aab69ac24be87647b8013b678b0eabc6270167bdc9c0cefbaf4d9a34dc41524b709f1b881e6bfa34000000000000000000000000000000000d92c47257fd0c4d6baa4c81efe65852840479b9bfda5cc06b253f167069ca7367924c0c67d6497a1e9abcce7d0ce9502eda0eb154d5f9b0e25a828c6f77541701004cd0293c61ae4d36aa3038d0f1840000000000000000000000000000000014ad0f935ba129b47ecaad63b9dda44e7ef7933f182a0f5226141c8f0ede026ca2f11db7f4924b5c582461688dad6359000000000000000000000000000000001453716381f13bf6ebf8fff2ed7bcb90f7beb44269008af5880a355dd03de5c84c14f5aaf69fda043b422aab0c694784000000000000000000000000000000000e983c9e9b799eccfdb56444d31948067d46adf275d7f39a70aaa8bfd0fe1b83632c23d87f4e993c8191901e9a607217000000000000000000000000000000000267c8b8c5e09b59277736caad12ec6986f206d1c1f48023356d8bc877a594c8bbd98981cec6382bf9bdb9a5fa38275ecaf6dcd51a851eb200c7f5fc3e106ac5ffc432f756b942b1b9a5dde31cb2a3760000000000000000000000000000000002e28c245e71a7f6206427ee512f3250612785ce29b369682fbf767d06ac08f91de8ac9f82951574cce46cee1aa757720000000000000000000000000000000019b0dc35eacd961e0ca7d54a0e37c4ace37eb0200d5489316f3371412717c57c8f17c1379721f4dd67b3fde24f50d4cd0000000000000000000000000000000013b9741f7a32e5e5b1ae5400e32dd6fcc1fd43b68df54ade57c934720b1289a51deae77b1726e1955b6430f37928e2bf000000000000000000000000000000000693980b347ed7ee6cd93f565c87efb36fb304d7e9ae24e2b9f902bfc962b6c7fbab93287147f5ac892db2a709c9ab42106d4a893a68b7fcb8be96faedef65181c239dc2cd752c85ae7800ca84fc2dfd000000000000000000000000000000000ad6b7cfc6cefa5783093b7d700360b354d0698d27ecefb7d5928ac5bd6c299e4001474d205cf3b85a32c600ddaf1a360000000000000000000000000000000017172c3d5acf59b70b340fc703e9b7801aeb4857ffbe7a9d5daa0f32ad80d1c0ef2f0b3b7d1fd83a757c076872425fc7000000000000000000000000000000001291f55fa7d14b14c578d57178cc707cabcdc4bfb444cecabda271cbfba2ab361947d045ed46d9edbd215fa4c8164e56000000000000000000000000000000000f64ed6c989eec5222239d888d08dfd638a0e35eff2266410dab0498941fcd1683654064107fb7e53b8c02fbe98a25622b9e1cfbf140f4a3b1d06be656ad6ee5169a9cfa7cbe6efbf8173843d406acd30000000000000000000000000000000001d25b5bfcedc6d7ff7e9fcf729f858759936235d23ad45b14dfd0229bf3e50fc68799d19ef019b36728285bf7ecd0b4000000000000000000000000000000000326e300ba07935e0233a03ac891f18dc7b5a9ad9a28264136228e9e23e8f2aa31b7f5e5f3cb3354984f57a868a5d00c000000000000000000000000000000000dc92060e3403df3a92b15ba3e437ef0c403fcfc9c3545e544a78874e5d9b5e63b9ba6060c29022fe2594c2e6fbb6a840000000000000000000000000000000006a01e85f59dc45b1501309a350137d71147c30fb70da6b7637a9b1dd884aeb7e554215474784ecd3bef18d15d2c0524dbc68f77d40330ad5b8cfcda42edf57899454571c6c6465c4107e662a269aeb5", "Expected": "000000000000000000000000000000000b7fc0b44723ff0d1cb7c43e470d4d432fc4bbc7f9d98ddb3d91434a5574956fdf15f898e579236426ea44677998665d00000000000000000000000000000000176586b6f157e408138391e3767d0c1c8457857f4cfae571267ed64ac86ff8a4b61a28b406e1caecffaae6a399f4ec9c000000000000000000000000000000000a420992f850db20d4f7d2ddff33e4dc79bc0c39caee533920c5d03d1c2619d8ced769ac09f664c0921829bd7edb446b0000000000000000000000000000000017e4000f4d03a6707174c3adb74966896bcc0eaabf4ff83cce92a666fbd13b59efa2c767442062b6c8b1a3abd604f0ac", "Name": "matter_g2_multiexp_82", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016ac5146ffc26d1f0c33645931bddfb84756e1c7b03f4838467d1b6701ee9478ae03c910b6b4f5c14135487bd2c14bf8000000000000000000000000000000000e1d082f16e4d5c5f0b6fbe5178aef6f781a6fb165f775cf0cd4dd55f2b498a79edf373007113dcdf6b977a87e1fded2000000000000000000000000000000000bb94be280df1aed761651c0292f88037d172b675bae1933ec12323b947023b437d080aac9e196fe5e06e5c4137284d200000000000000000000000000000000064190f9725bfd5d56c31aef7fd1590c975e2ce549fa6d5c71b254851149e0a0dab0b9de3acfc2d64231c79bc0ebaa37ebb3c942d3a1a15cee806fdb0fc3635483743a5b0ee9c40a48700bad5da53ae70000000000000000000000000000000012199d02d3f1bd8c4005878c3302e6a731ea69d69accdd690b4667e847b079563d32e18eb7a440b8005ca936da5e73cf00000000000000000000000000000000125b0dbdb0058639513b007a84d3a3e6302f5d846f22f99a55181f097e200981d9013c00d688a11eb976120f1a5da64200000000000000000000000000000000081e723506635433528fe4a40fe4ecb8a9c3d8cd701c043c0418d149951651e21632cd85f03db33b89efadd69e009ebe000000000000000000000000000000000956af2e67f8ae676abc783c4ec9f85c50ea130410cee8216fe036cd0521b8ea38966288afe7d35c28b30f7ca5c6edc0c193d751c4f24f4808621979f07f03b2eabba75f08bb49682b9df2da7a85a7730000000000000000000000000000000003e11a4e9dfe82cb495e9e698b16c257ea3f4ecb24749751e7334e0f31fbd6677545e4bf9ff78a82853560f7e7ba2ae2000000000000000000000000000000000caea2c527cb3aeae427e92fc364365b1f55e7128a544009be2ff7a5236d1cf8ffd5a5cefc87820bff5bdf1c6bfa165d00000000000000000000000000000000064a3186774da8bb5d013debf46ccb0d894592c414f32de6f77da47f4d42b0c8a13a2ba4f14b9883d564fd8ff6a4c90200000000000000000000000000000000072f6c48b6a05039e3a4dfc6b73501d6d4ca7e840b119da9c074bd4cd2adf4f2c6e9e6325ebf6f97c3f0b00e6b9bfac6dee4eef524f133183b4af95e4445f3ee5084b96c32e284ebebc5b87f3d76150b0000000000000000000000000000000019ddf708ab31f6f6f725f0e4f65d11248d3a79af30927a6f2673901fef9819b189502cb952bd4742d2b8e84acebb5196000000000000000000000000000000000d928535c47eafa5da4ce4f91467fc31aff8b86b850e4582a597b334491b14da71763f9aedb15ed32856382069c094ce0000000000000000000000000000000004d6b3545d067aa0768cda9dc3cca0f58eb546345b96f7d6b9355d47770e00286d962a6b3a64ca2ce22fdb4834a4bb6e000000000000000000000000000000000f4ef9366d342b309076299816c1ed9b424b68886a5c69e21e785f97cb0f99ae3a99ff6b5244dab817094449048a7552da514f21c8eab0edb2405e673297bb595edc21027890ad680f1663fd960ce478000000000000000000000000000000000236c5b4c57ee4facec5d4ff37a478c505217af66e029c3382613442c58875c75cb423789f6703ff3c1c0d80991c9e3a0000000000000000000000000000000016c052de3336002f362d9b0cb386b800860527e0fe81a1a6df0ccde31f3265e6246191b3febd1ea48e9391c44593ab0700000000000000000000000000000000078dcb04ca93c676a9a924e59f924d9d3af872849bc30ca633d4025aecd981ba12e626337635ea77886a45f4da84104f00000000000000000000000000000000027df6394b195222bb8357bd684088e3e2a398f0fb0cb812ca5dcdcd1fa1279cfd03db62e0f8b2800d4b8b48238931656aeac9a669c962817c01069cffbd948d9d8ce764e92859f31fdaf85f5aefab77000000000000000000000000000000000485ce58b387083172102145fdb3e26c6ffca8b35af0e1d84ce9cbd89055be083bddd3da56443924049a056fdb2ef092000000000000000000000000000000000d998b234a69d584c78ed054b1322ceb33f73cafb5b23c1703a9fd609edcabd44f1a642802b9c0b6fde6a6828b50c1200000000000000000000000000000000019235ff13567bd007d77e4dfab139cd57dbb309a3cf6a6198a548c4e6915778094ddf2b05a91f5478169757bf5a56cb300000000000000000000000000000000110f6ea19a7f62bc3e78f4c5c1c6d3efdf1a7f563576e758218b2c363fff8ad8fab0e72431619e4ebc93d2d739fc786c40273bda92c9b1b677edd905d76d75875e5b77841befb2bcaf1fca7674dffd5a0000000000000000000000000000000001d45da76e3016c00fe65bb50f7067e4f06364ad8348184831c4932ea0e0f3a170ab5147e4670ee1b16924105b6fdb6f000000000000000000000000000000000b3468206db0613369b2b0750c98da65b660fc07c30cab4e459c311dab683b6b313b99ec0fbe92ba07f8aab43a12a2c9000000000000000000000000000000000f58a57c449a41105837d5e2419a34201cc921ec77408d6c0c7a2eb227be98ec1f6f6eb9fc088daa0d4c78928a1eacda000000000000000000000000000000000ba53b872dcb9fcabf35e673b467523ea77accfc1b38a5f92d7b9d269c28aa00d00b08d70eae6ed4d2e82bdb06008f9ab77e16276f9464fa2063230d6c1a4152553536c610062f18565c030e80b5cb540000000000000000000000000000000002b82e2b582b247271543117b939fd17ba8bdd617a223873296f7bd75de4790f0d5d8fe523792bc7fb4764d3739669d80000000000000000000000000000000006eb554347efc5f2ee79949bafc012e6d9964ce19459b3867865709d903fe3d11bc617f30f6279a9e62ea104565953600000000000000000000000000000000006a543fe5cfbae629fd3256575e3eb4e0b65864aad6c7f359e169038bf090ed9bd92fef32fe1ac20b2a8c90fbb6081690000000000000000000000000000000013ee42b0693b2f3b9b977fbae5c856e9e4c5e70120b5c29e0a9f898f6d04b7fe351e17b02716a44febcf0a00a9cdd9220be15b654ce22ae4e32987babc4863ffe2bd8a459d0f01f68fe84a75326889900000000000000000000000000000000001ae7368f84e354e5758554aa9c72ab4b00a644cfb9a4ecba38dc72227d297749bbc98c8f5d6149143b31442359d8013000000000000000000000000000000000abf087f77c79cb8c69e4289fae87b2ed483442daec3851a5ba32c43e342be29433b2deac6dbfa7a787547a7361ed0a00000000000000000000000000000000000fa01cff7aea64b649951a8d85fef0bd475f31e47c706b96ee2753df9987508b5e5456cc49e88ec3aad720a2535f6940000000000000000000000000000000018874d020e2eec0e286dce324b91f15b2a4f293d32956b27524f478983f0e0c5b43df802b60f4f001753f12d449cd821c8f1fe94bce21966427380b6d357a3599e9db03a7694159335ffba26fe29e4650000000000000000000000000000000018f7d19362e2cba91023455e115cd90f02aeafcb026349393ca4105e270ab1cf589621b40965fdc9795f66ea0f6a053100000000000000000000000000000000170ce0eb304e0e1047617b709c834b67a8989212e5bf1cbd5a33242be94bb141d5366e636c01a229943bead9a7baf43900000000000000000000000000000000077a17356b3b31faf90f709042938b9e901817f7379b7bd486d18e47d22b0430ba70fb3006e9afa67d7dac71ffaf152400000000000000000000000000000000064aca92c41561e195fa8239800c97d5242ff0f8ce76b0d119063e2ffa09c26e01d23d5728765a59bb9587e885450ad1c6d34471ed00035a484f97f4e8123d40ca23b017b94df65540a5551b905e57b3000000000000000000000000000000000876a57dc24ad58416f910ee3ce220630a1297e6bc691c908e6cc16f975b146872d71661bbb869361623c61670627eb0000000000000000000000000000000000760fc65097d215ab9aeb3d5a5153977e1e399e2cc0b0cb9befb0266d98ac13512a0eadaba4e051bf56794621c551ec60000000000000000000000000000000003c8e205e53075a96c14ec26345c75881a0d67c7ce0d62d73c83dc353cd7b555cde52ffc5659ab0db2179a899f0fd694000000000000000000000000000000000d7e8a7fe6b751f7f478698f4f0d30cd0a435a2295a958cabedf4668769819b4cbd4e8b7721eeb5ced3f913156abcaaff3abd467168bf5e57f71017b5779bdd400dbf416f34f105fe747ea2f8cf4a21000000000000000000000000000000000180546f697349adb2918129f4d0a979bb114d1b58e5baa6cc221a09d7083469bfaa61f80f1e3a6ccde0da54b24d59db70000000000000000000000000000000004074338380e3d7c0facbbc71d83e78b53191af9ba13ba0cba6015bf4f28e4b0b52ffb34c7867a335848f57b5ce5ef5200000000000000000000000000000000148a800ec38cfc2386497d9aacb4327d5953a6612cd4067ac13fb977046688e80032125d4b0e7cb49913e489796a50ea00000000000000000000000000000000132438d18d942e6dd3f69d117abf83c2fa18418e5145cc43b3cb8d18c873935e41279a9e13596f2863be7aeae9b73d172809801eb18d38a61ef8a80f13086d6b1f85ba751cdb8d17fbb9ad5f8d0f835c0000000000000000000000000000000018b3102ce91af86cd10162d3a43e488a0d7b7807dfb9624c3cae76f342e86f8ef1200444a57e2ed7f819828357a6dfe80000000000000000000000000000000017137b470f3c8d1a03e7252e18f4466c9ff809408cbb2043d6b226ae2746d890b267ce3255114b2e073eb66e93c55eb200000000000000000000000000000000054dc1c981c9166d0bd3a54064c33f15ab856b240770ed44adaf9f32d4429babcd0baf2c5b8a1ff80728e9c63e806cd3000000000000000000000000000000001897595f836342ab54bc2e1b72f433bfe3b5bc989727de48575abe89386aaad9b1549af3ca55f39feec14355b29dc9e33521c9cf035b094d754db994fce3161842a9509ec8288699680c0ac7761eac68000000000000000000000000000000000467f1a3093c72aba4c2d9e8171057cf88146eb32f38db0761a5ab2027f2213c89e12c67a338b4b342a73384109988d2000000000000000000000000000000000ab26c871d140c9c4e0512afe9fb576409ffdcb95417f8c6cdc0d964011dfb1e745045766bbbc08ff7dbd6935934bba300000000000000000000000000000000183488902b886200e63465098be87a905810b2e8ebe0364316da798e423dbb267743a0d2e3d93303623fb17df0e74ce30000000000000000000000000000000012c7e79f9ba36cc47762139d191e6625c850a03d5b6e0648032d1669575704c91e48a9ae432bb3553ec66e86e082de689c8c2998d141b9cd3a82507b6dd97e8d32e9e759169c575eb484e9a1559427da0000000000000000000000000000000012ef4988956e026a79e5e904ad3d7ca56793321d62cad46de3cbde8570be5f0ac86d386216152b37053741fe342de7c60000000000000000000000000000000014ff7804312754d23b251a42aea65207695d4df65cac4f87fc96cb920843c022f24cd27731224db751cfb621886249540000000000000000000000000000000006ea693105a1b2afc79dbf75504c256c519f927ea0d79ddd1997a49638a67151dc81b84473208e8078cf71d456f2de0c00000000000000000000000000000000122d367c147c91517679432d3c7b56f2d529d70040109f803b89a04fd8540a6c565354ae420e1bd4ad4ff61427332629dc83c1ea9e4f4fc12a7190e6c71c4f35d1a676d39e30fe688a05820dd989664000000000000000000000000000000000156e7f8f1412cec315eb76f10c92143157313b8eda0677a6c0236de5fd27e5660ec3eb7369f1604082c59e1aa5f94dd900000000000000000000000000000000018ca9f505a88ed2bf595fa9b55d2356748770af16b35bd5db448990b7d41c3aac53aa490791f7ac09d2f5a087f938f70000000000000000000000000000000017c76ca9ddfcc26b028928364ee35829c6e57fda40773a6bc0c259a1b3cdea715c664d7bd0340192aaf7dec7ad20a2ed00000000000000000000000000000000082a255966c4f9d0ad6bd3d88b136cb2cfca09ed6ae378c914c28ff3338a2cd466cafd839f3fff4a30b33ee56e684f4e00be1b9098f1873ce155a66899877c7b48ddda363ae1d2353cb3816f1ab15ef0", "Expected": "00000000000000000000000000000000075c71e21ce327a97024c8ab5fcbef4fff76260a4f8c8489167166c4a85d25096c617cceef73097a4bb956be3eae8b780000000000000000000000000000000016270f3ac86c0ec43b9472499c4d845eab488a34ad9e2148c72cbb1db13623c5dbbc8327c47ce596521bd1f54f119a660000000000000000000000000000000007ad4914ceda9fbc161121c818bd05953836a581dcdc78bebcd82ef548671c899581681c908a337618a445f77c6b7cf400000000000000000000000000000000173f401cb78024e844adcc88fcf0e52d32de134f6300216ea0da7747752ae3ddf4d181b8d266b53d1b699921f9871425", "Name": "matter_g2_multiexp_83", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f40eea638a3d4fec417701c936d61c5b233c9d6b3e94ba9addd0fa0b20adf9f8e07c6b629977445c7750acfd18001c0000000000000000000000000000000005f1ca1ca9cf67c33e3ff174a65adfde2db62e74edf30b5b0156d6b9dc86dd619ad8863c055096685d611ac015ba884f0000000000000000000000000000000001683dc67710880b8af76b464291c17fb0ee4eff3f648ac0772f4a777025c8cda0342d8f5aae3123da7fac57b965685900000000000000000000000000000000143d919ce2cf00838b10fc65374e770bec3db8ecb17d2db08b6a10ac38657bb109f54c1b3040b661c3914ded6f7eb80fa9cbdaa0ddbf854861eac6621255b2102e5343666c735d0384049d5680d105d4000000000000000000000000000000000616299341f2921adf083d1190c212a7941bc0d9fee50b05b265f2e8c339fc3dd9f94607631f485e394f5a7d71ae73d00000000000000000000000000000000006b2f12e22369e8aff45b6c05a2bb72a706dc46a5d1393aaa9e5a7931ccff33a5df2967189114c3fc5dbf69d080e39dc000000000000000000000000000000000981e1b119d04343e075a80dfc189000b4cfb4e321575817aece6009e6b3a6233d1409e8e584f0ac9caaed1f43e40d7d0000000000000000000000000000000001ce4693e8c14032c35497e0f9a586a4541d8a1a68ad014b0850753a04215be2bb60cd7c2fa9be4f4f09a562d7b29f3892073d958260a55b70b580f3ee27c42553b5b858b66f6928fe74b4de91c34bda0000000000000000000000000000000012d634764207dd7a0201703f855365f7750291c810ff292b3e8dee682d7d8eebd6d6f3b3dc8b0c9e25bd2860e031311b0000000000000000000000000000000000eb0859d79fcdef546026fcd380f5c936e64a5665d73f56d92c03dfb50c534a00c857c86ec43275ce69cccc0b53137f000000000000000000000000000000000131bf000fd117ef722b33a1cebd28899fb012e1113f767d0ed46fdad82a32e4327b883fbe29abba1bb7ba3ecc1cbab2000000000000000000000000000000000e24ef1e44029366ae1daf06524d8beacb2b99f60f419cc2ec1a49013b79fb7a4781dbd37785f32ec67c0a28d61a3cea2117f11d78dfead915a94f11fa7e904a96204ddf1835d3501639b83cd5f716f500000000000000000000000000000000067b6eda41cb8da47a424a02a142e2b98b9c69e7023cf616040993f41507798882194229cb6572806e82e9e5eb837b37000000000000000000000000000000000e38693cddf130d3645fd60ade780db84fa700e5bfb74ebea49cc95ab001bde442f363b4e4c61f683b3e67f1ec8c2af80000000000000000000000000000000006d593005cbccc55c5e336e19aded70da65a7fe42b6a85070e491a4ae54e18ac213556a91d5d62786b6d4d1305525a76000000000000000000000000000000000ff86216f5388114dc06deffa7b52a273b22fe0bc8d50804b491fac83e13915c2dd1b8c2779a46b5c313c4e1c05eb2979087caa1e89e48f05bad1d720477199410941a6105f911d589e1f94a851e0715000000000000000000000000000000000262cf4727703fb227bd7fce6cd3f25c1897011ab892e79fa47446711d6867ca82b9b95f129f7ca24dcb60ac75173d4700000000000000000000000000000000136b5a304807e029d0a77b2ed505ee5c920248242f0f95aa07e9bc2e13d35f6f67451d028dc19d26095b55cdc2fae4fc000000000000000000000000000000000b511b2e19da7bfeb183f0aec91bc7db3e7c913f1c282e12d5d2f422a49e7fa78a5f35656dc9c980324717a5ad386dc30000000000000000000000000000000012eae443aae59fdf907bcfe3ee4366e252bb57e268fd569d742456f348429f009f67bf92f9dadd401104ccd2549cecc8255603b470c056b3dfb3acae0dd45bcb3d014765a5181760336deeabff3f00be0000000000000000000000000000000016a827938d8b98e3446445ce23f48a7ba0d634de826dd1ee3c71467eb57bd4c24e0d1b4190f47bd841183baceaa2593e0000000000000000000000000000000011d360e0c18b45ace82eaee902475127d8f18aa4a2ec2081a453f1c85ffe3c59c0f7016f966574a7c51bc14f1935568400000000000000000000000000000000186b5d452c6dcc1ddb4f47b07e01b6d64644f6d01cba8498c3059cc494a68bd25eef35cae05885b9f2689683e65161410000000000000000000000000000000000ff826e5a62affbfd6d2062bd329fcb561f287046870b8be461767759cb0d5f1ac904ecd1f136c5ccd784bc11088233e0eab0e2486316956291feb44de6389b20f8bafe9cc890d86d27a598bab0f3c4000000000000000000000000000000001010e75c52ed0acebe30fc588961c849b7b6298bb8d859f9a9401737c467921c5e3cda101cd4e38e4318233d12b6c7b9000000000000000000000000000000001884db518fbe4d621403ce00521878c0d419d8cf476a1dfda59b7d3c7af2bd91058bbbf54ac0c5cf9a217beb78e3f98e0000000000000000000000000000000001272cf0ad917738bba052e88baf88347d60f63f5b875d604cf0531c1ba7d43e868bc70a682b7274067106f611f08ae60000000000000000000000000000000006e3236f6a66bd37af4be230d4edda6eaaed661f206ca4852d3004b5f358f184d80be6af81c62e5bc8c88e7a1072fe21fb9436456262e5149d02b33a1078e198bbb681699b3f485625784df444bfff670000000000000000000000000000000004fd1e2fd0d28db08224fa7e880abb8c48dfd0e488df4d2ae5f6649f448193acbe943baf22af4b12fd763e3e4ddaa08d0000000000000000000000000000000008df68f276f356ade28500eeae3b755c9af9b5acac5f5f60827b5b2044b2405129b00e5271baf9a80847d3b720026b3a0000000000000000000000000000000005e683d1556f513e6d093704405f312687c3b9e2de3b2840fff32e88186c89b18d1ac558d960b1196594730a9bc107480000000000000000000000000000000018161f8d23c394d10ba576fb0ceee530ebb95a670f2589d84c0646f693086ecb7ed80e556f3ed9434d7fa488430ccf430e2724d3501e3d79b85266fd83a2a6156eeb48e749a61676a1c92ab9bdd6b8990000000000000000000000000000000017860708943449c2227c0f50cf1274652dd32e999d5f9b1a8d672feedde15e9f1af484a7b9462a62dd745bb6d3c7295a00000000000000000000000000000000064f8cb707494f82ffb6374641817a466af65f5c7d83cc2964e6cb8efd021e0c40934a3ffbb0d91bf8a7a616dbe8d220000000000000000000000000000000000eb37cc9d56fa0dbf050b557aaeec76f9f6d0a6c448ea298af78004e41ecd8a1df8fe8640e77cb76b593ee17658326ff00000000000000000000000000000000092ab597967544fda640b145edcb3ae6c3f027c2111dbc282ebdd48eb93287ae4729cb30e45c1c8999b3a45b099dbf0ca49344fe6ea9274a103f323f3d9381e91ae48233dd579944e12afdeaf854000f00000000000000000000000000000000124fa4d48ffc5732fb21d465b559e995891fef98370a1eb73c9264988f75caa93fc134fde7f93c794582ba5cbf6bc685000000000000000000000000000000000b71d012abc1558e49831f053757518643ae04f79234fa92023db9c5483bbd872d24eb87a78960f12930094c4f8fb70e000000000000000000000000000000000651cf0016efea086d98e5bda8e1959e20e4947e302eeb021d196897cffde3e2c28f783521b2a28b8de1ad1a131f5e67000000000000000000000000000000000555ff8a930cc11d320afc3e0635a6f93da1487a5764d56636be4e5803d740a73d84666f6141ed5ee6b778a463823fbeb44aeaf3ba8b03e7ef7201415de7365365b828f2c1a38d09153e51432d35b9a7000000000000000000000000000000000974e769869719f0ee30895df837cff50d47382461c557abc4b8806b04776f401b76a5e630a6ccbd3484980d03ff58d300000000000000000000000000000000098157f0190e6bacbf34c20310f6471166750ea1b235e46a5fae313f90dddc799f21548088322910bb0fd7e41beb23450000000000000000000000000000000007f00d7d18719db9d91e2c32f51083b42c4fcb43c38087f86879ad6bc99600d4c395586187d26d041ff49dbbe517fca2000000000000000000000000000000000510cea4a7463bc5882d0cc25fa967a0b02072627bd57f9a5863fe5255953732846d4907fa301789bf02af9c1b25211c53961d33104649cbfccecc7eaf33b7a2a486c77dca363ffc9fbc9ce4e8c1adff000000000000000000000000000000000bf264c0b7bf68c595b89453ebbd7fe2e64f4ae2c7268ad51f4578c35d48040277f3dac9021997af02e492039348efaa00000000000000000000000000000000083a4fea41cb1e02e5002259f5f7b335c81e15cca93cbc884dc1b08ee981c55f2dd3c0db1a35ac9907435edd7f0ba625000000000000000000000000000000001468e508a02ed7b61f752ac38313345338d2b2d018f719f391c0f3fa1dd1602d9476f3d8829720d17021a459a2732e96000000000000000000000000000000000629edb2530c38ead8717b289c08036c12630cd8c9ae875111749ed893b8cbce40bcaeaf13df4044147bb665ecc2319ea04e97c20b42dc265271740f27f1a833bc5b324bcb843a8f9f8a68231c663d57000000000000000000000000000000001635830ebf227be126e13c634a84f3649d498e0999ad2dc73b9c7360db120dc2216addfe18c00676ed185efa1e789d8c000000000000000000000000000000000471e3cfca449bde0ba2b1e2a5b63d53badcb34da3251313190a35daf694d70ba385976d1f875242386fc74ae0173d18000000000000000000000000000000000986cf3f1eef587bcc70f66f25c60f353e6b15bd105fde9254487e9b522159658d0fc6b6a8a3ea38c27865f1ea4d76490000000000000000000000000000000015a2eccb9c10bc273cb712ee04bef01a11e486bc6a4d220a0f653582af6ba1bac0b5108250626ddf126f16f4015c9d2cb688426bbe9ae054acb6c1fdd4195f8a113727f5617642a5b3c0c65566e22527000000000000000000000000000000001213cbd035615f09189171b3e22630d72df2df93fa8c14427bb00c34f5b55bc8d1b1a59404bed6549b582537a397eaab00000000000000000000000000000000161072d8ebec2841f0f34cb38a3e1b2094a597640a34178ee951e5c993646ecfc3a4c0dd753e7e76f3a6da5a091f9f7100000000000000000000000000000000077e9c95b6c6f726902392c3a16b5cc71cd9d4cec58c00eadca6091e45bc095e53006ce8ac8827565e867531013821950000000000000000000000000000000018cdf909bd9f38e57ee24c0f51a5f9f703eb3d190dfbf75be00969e9e8f8fee331cf32d93c3a956d12f374f8752c2c79cf365a86a8d08db5cd95f239a2f3d22279556975ecc3baae0b774b0323dbb1b6000000000000000000000000000000000cbc27995eaeef2bef14919d48a008a0b0467856f8a6659d6e68e47a2d9d41d217c5913aa1d67911325dbd4fc38e36eb0000000000000000000000000000000010639740654bad5c4ec93f2496f4dc54a7642bc92ed03372ad4edc5fedcdfcf37158d3f02279d4e15078e9d5a7f8b5df000000000000000000000000000000000155ff4d6dfa031b0cc2f57df41c1e1b1c81bf5a5cc1e3aa93920e93c2e2e7a71b56ac410a87855400025badf6dae8e60000000000000000000000000000000018e637da048e7e84b9d1654113978fb148a54d86e1d011d7f5a86cd4f1e5bc15abc5b67d00129f53c0c021cf933f399c528715199c9f47fd6337b6b0e807e230b1397885fded024431c70e453f55f3650000000000000000000000000000000015d8f6e47b8f07b3e07ae0952a7c8f79519ce2828e3e26b284b8f2fae7432b337de17089b5c32f0081ec6c6916f2f53f0000000000000000000000000000000010ecfcdb02cff772db667266cb3f99f1dc28004ffcadca7a9c64b3b5853c09b7793ca0aadb155257bd64fa7bccb390450000000000000000000000000000000011096a52f3272955947304ba037e8b3fce6b2f07f2352c08d5932f4d2306ca511a74dc044d0f0e1e260ff40b0fac5e0e00000000000000000000000000000000130facbe0c1c6d077e9dcab647a44b049a1aba3df500bf27d1c268f71a59635e702c9ee1bdd68fbfcff7ae5b3e6bd83bc32e8643f38f8177b788b8c2bdc25b668308d914fce35c6f9023a769334a51d1", "Expected": "000000000000000000000000000000000b47d58802579e662f34908a4060becd40434e4934ff58790df2a69a759223ca29f42e658ab475cb92bd9c46566811c7000000000000000000000000000000000091d3a4c58a669d3bf0377abfe28d1817168b2a86375928d95df3459c83334669a59aba95ab2b9957d5ded0bd8925910000000000000000000000000000000005aa9c3fe0067338675099ee32f93bc8a5e9ead94b120dfa391651da40cf1ef5ff79d193b0b14b5926f10660aca6c11500000000000000000000000000000000058200992b111461f4d737533301734a5c3731c9f2e7b55e18887ebff4d5b74dbbfd23773606f54cd6a930b85b89aabd", "Name": "matter_g2_multiexp_84", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bc3eba5594666cec699a47fa13ee74722a80b4e5a1b28553de37c3163f2fdb8b801e35a19f6d99cd207d1642c0d4ad400000000000000000000000000000000104b334afeab36961824611f0fb58bcac55c9d36604ba73e9c8809085c019bd967cae7147c766df6565ddfcc0cd5fc9700000000000000000000000000000000026c3a6a4ace8638bf8ba7434b59c3aebd4bb274cbdcb898ec6a547b215f32d10395f3bb85a9eaecff5ef6d5ef2b50e000000000000000000000000000000000065bc419f9496b5e81ce72a13fc1bdce4738c2e3faacd80676be31db65ba3e7941ea75e370b6d6c0e7b2cdcce80a2fa14f8bfa3d47ed33a05fe3da738797f18ca5d5b8658055de5a9f85bafe6078f7fe000000000000000000000000000000000e7f1f5ead0f212439b4c47599581982712d2e6ba056f36cb04033ff5eebd81b5b41b874a78aeaa98562899418ab04c900000000000000000000000000000000095e45da9a4b2578cedd13af71e289d0067ecca1f09c014a294e0b250d1e8243ff98a9761030ac855a9d897cfe9fafdd00000000000000000000000000000000030b44b150d1337a3ed6a77f7b6332d7c8103da1aef0d445ff7467b4863e4c830fb782a81d01a6bf97e8d52bf333e78d0000000000000000000000000000000013bb76800375a45b847a96ef6edff3fc3c30e3d45bb4afe04230107f6a1802794e1dc23431797bc5e79e0d5ac6357eee4b0d302be94d437b8055586aa77ec1fe616e30552b4d7d3471ea219c148be069000000000000000000000000000000000602e0bd3d34415ddd517a73acaed5750dcfd68b633d51003edf79a169ad7a3ca2541d7a131c317c957a9597a753b5080000000000000000000000000000000007a964539081fff51e0ec24bb71257f6a1c513fb0047aad84b80180b22133246a1f62958ead75e4b2a68f973d17f1230000000000000000000000000000000000f48fe0f5b5a95e48bde4d8be1b2f352d748c1201b064bc88309a709b285f81260d4535d3e1dc7f1d6ee23ead35abd9f00000000000000000000000000000000135b480fc8a72248f7a4898fffc6c18b7f2f5b1af5cc3846610c299c8da252fb71190d9f761e037c6b47595bab6a03e56765d7f1079b142e513e604d577e7caf82cacae59fb98c6f8990522372dc906f0000000000000000000000000000000004773cd2884e52c2551c1ea0abb78fa17caacfffe13f18b75588484b8bfe781e623075bdf827fc82c6ed7e1d4d62081d0000000000000000000000000000000007e6023fc0e409bfc7d0b7ca65fa0e8d88bf1b4c202a8d1f0e1c3479b0963a646d16795fc5a128a54e624357050fed4000000000000000000000000000000000039f6eaaf99bcc9f4d8fb994a040af0d29c37960e9015d4e48466a9e554da30975c5534e76a1f08a55ed8ce7375b70100000000000000000000000000000000003d2b097d4afdde83a01cf2b4f9d12f77c8e92a8cadc225d40f974ccf385ae65bed1972a365d55e24231d58abed4395a2eeee02d9309af8c74c78e21836f4e6a7a6df5406617e2b4e9d300e37d8a2bfa00000000000000000000000000000000047b8c550310ae246e43b513d39e507f1dace7bcb543a49ae0854a397f62c408ae3632c94d172669ef3e013781796ecf000000000000000000000000000000001592914e260afaca80c0a240426c2828239ad5e256a707530f49cd65e9da2e4bb14a7d6d5978f52c04130a0d434cf4ca0000000000000000000000000000000006c0b8448ad87350db130373778d414deb738d3be97fba25c816826f59e3e926f44956c2e2056b7d769278cf56cf6fe0000000000000000000000000000000000a42d716fd83071bfa014a9b7af6c164d494f0347aed953bd2c1c97ade087a8bbea9f53c507fc0b22d520f28cc5d480cf8449caedd55f0a08825cc1a9e985201c8a7a54d1c4dd96f0ac54214743941810000000000000000000000000000000018026c9f6c86219d0be88955ce0afc3cb637b1c3a531aa2722c56816d368688181ef2fedf1525daec6d9b1651b71f27c000000000000000000000000000000000b40b15bb0621209bf9e33ebc27a7502d90fd3af62a1bb8f54a874a14c105df34ae34a43fc3805c1e4817ba30c048ac7000000000000000000000000000000000465262367e30ccc24632d39bf3af9cb160e97049d855176f665a185c138d5c529d11e53e56c65506e3e30be7b48c6730000000000000000000000000000000009485991319a311052d883b45911be12cf7648b5ca104ffe77594472f7047c803b8e9fb753b98645e630b9913bbc947e28ec5f9dc48931da70ba0cfa7251953e24c4c95cd019e00ac6fda095c1302a01000000000000000000000000000000000fcc0aca0d873cb8733ff7e2ea02b3736b737821af2db06ee6508e161f6159f9d944372c513a03cc4c9e30a707dca0930000000000000000000000000000000015c3774f4e0b30c9532beaa2f7f9b777f8d46bfd3888d6835f4a5a046153a98062efb17f78807fa17b3a995ce720c0b900000000000000000000000000000000083d48e01d2fb58244861a74a1261063f7d20b412c8a44f9945fbe373cb4b9a7ffd4c4ba4054ece0abddb6c14c013ceb00000000000000000000000000000000133c4976454b7be427c4c2ed437bc2e882854d2ddce42d2f97cd3fab1fcf60c3272aaa123a0cbecce1a774946bb7a8a0dc6046b43e6982f11f39412cbdef14f8e330d37fbe6dfa9ddf3656b86f4f60e7000000000000000000000000000000000f6ae7de1dba3b3030b208f61d182013231c4666f134b007b52d36bceb6f3cd77577be7b11abc097cf9618d351d61e270000000000000000000000000000000005803904e3e640e51900805f930638ddd8b86cc1bd50cbd32a142e10d85044cc52ff769bf1b40dcfb7269c913d00b01e000000000000000000000000000000000e6997b1f8bb649c56de5c4bf9968d19712abd22fb7dabee19e0aebd1b13adcd3e8b202975b4edc917d93adf087fb539000000000000000000000000000000000a32384fe03280962c5f575b47192e5ef3111fbbb0a01bda2db1e9733471f11eac0a37df8ae1a891de311770c482c06b0adf4625ec80149b7810767c985c2aa0187987b3649cab8c59a892404ff2aeb2000000000000000000000000000000000531fad86551ac6dee15fbd62cb13f38d8d5c89d23a031b9977f110efcf16501534757bc5b93f0250ff02d6cfdf2009a000000000000000000000000000000000e6d78343049a68514271fc785de053ed7f50a7774b87f264c42e03e6f8f86285477f8cc57ae066ef0fde237c8d1ddb30000000000000000000000000000000013e313484da4d6b85634c5306444bdbe45d7db823616d72821eb64a2bb5f352a4f7e4273fb6557039fa563ce1b091bea0000000000000000000000000000000009a40a984be66c3442fc8946cc42eca722187dd819be9ab34a9c3b4b0de7de3d5f126c175fe84c51a6f09e18623214f9345fd17367ecb06b29d764b22dc1e262ba1a339b6f0e0c77384245e3d41cda970000000000000000000000000000000008a76db551280cd43d4608e9fc629a021675bfdf9bc5a021546b92f3734acff1e97928850716b94d15b7dbcc4a1e0aee0000000000000000000000000000000000b2262872c268782e8f27ee8fefe0827d45131555e755c0a65a7c8b4185269bd621412b653348d7c1111d681f38d946000000000000000000000000000000000dabcf0f847045e01ef70ceaa32455f4c962e4657b840f97a1cff7cf5073cbf4ca8ea75a4887076f155e27e8d7406c95000000000000000000000000000000000a9c0ed94170eddfc485d9f1a770a8b493d4a59bd7156d6cd4b95b55bffa1b597ae9d6fbe529dc0833634d75906a4aba5ce5e62dd15958e6298cdf4a4e899e53644a48494d04fa6d1f73f2dbd645817c00000000000000000000000000000000170ac69c2bf9b48715f445524cab902b18ce6dea7b258481cc59986ae61c8fcb6708b1457be299a6e2f6f34dfd936fdb00000000000000000000000000000000107e855593b6f3bd2982a65167ecead47039065c9ae6e1bf963f81d441f0ebb411eec4b3ed1cff73044f68a4c114806a00000000000000000000000000000000063b470d158ebb4828e875c3dd0ca29a4fd2cd2af356233885a871cb5b77402090f29709c6d6a78f612c8ca4df2f4119000000000000000000000000000000000db75a60fa0b425b8cd2c955e21846ce3c407cb3f96c472cb412498143cc60212de0dfd0bf4de53ae3b345232180b4ad853396021d32530351deec5c266a65519471dce2087485781f33a1423755ef38000000000000000000000000000000000389e79154f627463a7966252deab10b5e809b0c2a9e90989c56d4076b834e2081ddae1c02a9e01b71d96b772766fc680000000000000000000000000000000009109473c7aa614334fde410951a69ac45967f7550890e01b05279b6dff394775dac51d583ae0aa82edda18ecc5e66240000000000000000000000000000000019dd51ec6783c1618a7f12298e38cc75d4fa32fc31438f67eb15419a2f0e9d4b5f70ea59b69e531c868475cada519569000000000000000000000000000000001121c7a6cbbb54d5e30a11a73c158237dedac46385aa15d93592a30fb64fcd94a674cc77afd21a611f704734337905596dfc62eb59bb84b3b6599bf3ce7af229096a8fd5925d4743a5ea386a26c9a6d000000000000000000000000000000000178670fb06f5eb8a4f182913f46f66147deb3f9f634d620ed55da2ccc88895e75f76f55b979e1ba3c3db29710050c7bd0000000000000000000000000000000011adec68ef139716ee081db7122e911ec5a6e1fd7f681a96a713dddc2b742b6e7cf7485b8f45e7ebdec8b1174c02eaf100000000000000000000000000000000089dac9a47cbdfead8536d6cfe8b94d316123bd92ddf30091e16711ff4651c4e2d8dcaf6c72bc159d7de9fd832c6f5be000000000000000000000000000000000c40b871930f0c6826a943a229112f8bf9a3b7d7e07139e1a7d99f97601b6ca8cf3638e0265743dd732cee17fadf996721d35ee6d29ee4816b91d1664b5957767b4b8066775b37c3b3d08729c949d6e5000000000000000000000000000000001040c4cd3c28a752295b115fd80c8ef0e538e1a3906e0d326e46585d633140bd6b8231f50d50c8e7a9018a625c4bdc530000000000000000000000000000000008b966d9433bfc3bede4ddb005cd0c256a168437c31b8ecc83e6fefa6f4b1f2bfd057c78f82bb76279b74a2f7de493b5000000000000000000000000000000000c0f75db7a17e4b712666b16c31b10bb935e7127eb9a0e59e35ec54814a9de9012210ff1862aef5f765d4f7f673c4962000000000000000000000000000000001015e63589a8b56aa643a79c5a433dcd8f4933a10edc9921bcaa7098af435f7879a40868e25d1ca6f7852800df29c2eb3d283067bac390f556891a531dfacfc4795358229bc9a651c0aa71d601bdd56d000000000000000000000000000000000fab22ab380043b01d312004057488ffc958168f8fe4d9c86af622030121e14a46c4308d711d5fa9a414b9ef75d51ba300000000000000000000000000000000047c738fe5272e695f421ed463ce0d6308e05c23b6bd0973df9b55ca96d89c0771a45d53b4d17f30d8cf08edbf94490c0000000000000000000000000000000017bcb3ed735e5a302f76002ae82f4ac74889fa0e966f0fb611fa6a6a09440bc923f447eb6aebe47eef917753b7427efe000000000000000000000000000000000b189d5b64578eb53ad850c826082265e506ab620a9ab9684cc2a53718f26befc35e9431af012306a6190f144a9632bf873724ba35e4e8b731db36f5067aeafd33f2e966977bd0962fd57cd5ccbfe87b00000000000000000000000000000000049fff545ac239696c995eacc560580a0328af07376f5ec819902e30d5e7e40d5fe07295c4ccf54d5c06134370373c1b000000000000000000000000000000000bff448d5ab544a8cae0cacd216a6b6d48f0abe1b4bc946d95c1a8c4ae44bf049c3b572675a5e20c1b4188fa27a867a70000000000000000000000000000000011dbc52baa00712f66def2fa8fc77bcb07431d3285774e2517dcca65e611f07aac265856cdef0c1637def44c382230fe00000000000000000000000000000000090af0898dd578123c65d1f818c3f33866e4acea19aeafbb31bd8da029ed1daa2d7ab3b22147eb32a09021f7a78fdf2acc5934c02b63797010cc8474e90fa5dc88d73dbe5f9be605bf335057fba47ea3", "Expected": "000000000000000000000000000000000d52fcbe9f1776477a9d2149ca55e0651fe9d098a67209ce2e7d772d4901ff2c70be432b53dc94886651865a81ba8c620000000000000000000000000000000006b54871379e2be969f86c72cda9acab9bc99f73de987f17ab8b25c63c55ffa2cff61b87e8c30d9f712afb62a2b9cfcb0000000000000000000000000000000005652612b19c38650d1babd4772722ae2c560e2914f2e246725cea86dbe1275a981a592eb55077ee4b7c6090e84d2ed3000000000000000000000000000000000ee37a6d42ce69aa67cdcacb19efc230c6c34969a2e081ac77e8f9d45128a6e8fff923c7647a0f168fee18342bc6d845", "Name": "matter_g2_multiexp_85", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f114e56d10dba7945d125fe1ab7871d9510771548d8388a2aec8a481de92572645b73631f9a60285c3eebcacb3bc0f5000000000000000000000000000000000667d3f31955df11e4e7896a1856fbd4e573f1cfc906b3953b5806a5d01dcdb96009d9f148156a3828e822435f722c5e000000000000000000000000000000000d7740ae776eb4766999f5671315c8965ccc84ff71757e361fbbb55babeefb96265c97df8892acdd6a9166641f656e62000000000000000000000000000000000166529d1a76ad784557384cb971728dba298baacc2f2a39ee36516bc7a761e9a7c29e385cf5784efb9f6e60e998b01e864a1ee754f6b0a86923e5501d54e6f47d7ab9e1483294ce98be13b7db52937100000000000000000000000000000000133e0b08430d9318d98bcf58b3d8f51c7b717fab56fe25f434bf521f830c7d4247d87d3df910490be2ad38adaa8eec26000000000000000000000000000000000e15afaee4f1ce6290ddfbc13cb887e540efc3fd8150dfbf3a5e7c759ccb8f334ba26953c7bbc43b5234b857159f6722000000000000000000000000000000000e4cc685524d42ea5e435afec7b3d7d025e93ea06407a28c246a39dee8ae77514a0bb2d5031f7367d658027299762bea0000000000000000000000000000000001b231237f7b0538d51adfa4ff92bf313507996cf5255f191875970ed4d946cffa8620b44045f4bcfd8f89baadd331fd93064d187f7d21b8b0a7092943de13b96c2e1ac9b578637a6e64331e2d40f53900000000000000000000000000000000084128f1848b2b244e4812eccba01287b9d07e85450459c8c42b01180bdd843058d9926f39e2fb5f610651a00233e31f000000000000000000000000000000000055ee70765f2cccac966dc08abd4bba0d004b379a2c6bf188f300f5d413f84e77ca1d462219bfb820d7f585b914a52f0000000000000000000000000000000002dd8f1d1cd85a5e6ac793f7e1e3cff887204aa4a5fed92f2088c06eae95842ab2c04d30d56f4b0fcfe61379e8e7c6940000000000000000000000000000000013e318f8b6f4165a8096c76ada440154901de42d69c38e66d9df4ffe5476666ecf7068e7163f29f04972682c43f3b0fd5e676b40c09f80be5d9398a9ec20cb811cf6819a130445203d792a4d34fc3e950000000000000000000000000000000003415c8bab713aa18d3f0d54e0101ba36793e6e9dd3471f8eed9a15e00d8312732a9ce88b5f0c30207aed92eb173ac680000000000000000000000000000000008a7e145e9576be8ba2fd980fb1735a2b73d1bf5f3e108878b721b6ed8378b5e0f03ecac179a6d148541096ba483b40200000000000000000000000000000000029e5554752db8bb87d58275268f24ccfcf3e0923744d57473d54a72e2cccb847eaa8f3bf638833a934c43930fbf30990000000000000000000000000000000000e0f2ead2697110a132c4ce1643b97fc652dd0660deadaa4e0c45e7ebfa64cb6a6fbbaac7c4e2b725beeadf6881ae5893f63a87972dd11f5239c35ce269e4b9239e3ae906ab117f1f045d3acfd16ca00000000000000000000000000000000014325fcc087aa108f152b42759cbc02cfa24e7e7cb995c78ccaa9a283ec2029c08cd747d599e0685d365ee99eeafca880000000000000000000000000000000011da603d3a1128329af19e596ebeaa4bad034c59581e9fa2e42a0260032f84654bf5ce22ee32c34eed7515d7fb0fade0000000000000000000000000000000000189cdb5b934cc1ec7ea0cf4b8158a1416712bb59c1650e6d244de33bebfffd3691b499b3ff8255b1b513deba709f7d3000000000000000000000000000000000e7ab2b279d0d5933df25d8fc4faeb8ca907e7bb8588e618b92737fcb6959380abc205118d2e3fc128b89a2ead5ca906145e3456d5ca6aa5910430e5a19567c327b757377aef98c4f46fe9a1f52cdc5e000000000000000000000000000000000895b6777e677732c74cfa82d5348c4c8ddd63ce10347836f5140b9a64dfe631804ea3be8e20bd4438f5e7fa14a121d80000000000000000000000000000000002422cc4781f007f732239ff9eedc126777d6ca0f0365dd90bab6b68c9e3d02ce726726a6d30d7d51a1f0b45aec1854100000000000000000000000000000000048af8a79663aefaff77a934f0af3a09ba02077c13a794ddb88e5c679ce348b3ab0fa217954ce1422f4e212d1383ebdc000000000000000000000000000000001190fec6c510b0b16e1505f737b25dc2401e9fc2c95bca92aa5d6e93b284b766bfed93a80b137e5fcb339983a86acd41ce27de5d3a5ef941d058a458f3ad2a386f1d66945789e51fa330fd65da4cd5080000000000000000000000000000000014fbf4d005f43563fb7408d1f20f672c8983120c66462ba9156b64a287e66960fecb41ca129b6b14466a5a0de91b81c50000000000000000000000000000000004fb283724950174d60f64af7bc8a7d059431332c8f17769df33f6607d72633aae3a8d595cb8d5af3f8909297844b3a0000000000000000000000000000000000e187476a19280ad9f33a55c50f37f765e343f92938e247ec9fe099c7f3df65e24af14885539bfcf3efe3bde9f2700ce000000000000000000000000000000000f086e6b9e845fe3b0c5100f82bc8aeaed166bed9fa4d34bc03ed86342a997101c508a4c096c4f67cb5791cc1a1fdb8187bf5c4624e86aaead712987f313e5db8f2fe6787fc33481ed6e5c4d3e96d5be0000000000000000000000000000000018dbe48c54347635d4b6bc17ff5ba390a73925f1b180d2c516eafc0936aa9bddaf7317cc0c211fb2a7f7bb096369a45d0000000000000000000000000000000015544c177a4b8018ed60c2639b43236957c2d995fb0f32523654584b0bf052e0930366a93406e1ec5c6d2edb955e811d000000000000000000000000000000000802d2cdbc5e15b25c77ded4bdba087f1d5760e6ebf9549a37f3314b1e88d3d6f58da9d8c6e9ef85028a271b83dd6242000000000000000000000000000000001577bfeaf213ca8b0983cb178e9634dd18f74baf02f6ca31b2e3b287d80a32d4cf11afc71df09ca5bb0bc8e60fc7ffa968cfa3fd0692c9ce56538bf70e77e2a47534d9472ac702c53f2dbe68217d53df0000000000000000000000000000000007c059044ce0c15bc527b19ce85cade8b1d5a9cc6dd304ce9a3c461e631e17c4feec52a0ab5cfab6a2270c75f73df86e00000000000000000000000000000000076344286cedc8c180e3bd762f12ac08f0ecc51293b9f9b8e7c0056ceba1bbb6fab4ee39cf559fdbd601db6c3d201199000000000000000000000000000000000bf6e708d0a4fd85c7566804e19f21f7a00bcc3bd7135f6639ad30aafef2ed1e72c84c8995b0e59738c2bf1e4040621b0000000000000000000000000000000018ff3d0ade15b690b6e306adaa5c10796b78ed7f8a984f637271cccfd39fd17c1e8288a11b051ca94de2a9bd04fa96d7a36b13ef742bfe88882a4e635b5fdbd9b079e1adf3423dd4962835c68c9617c500000000000000000000000000000000025cb808922f6deb0bed979b80a675d9324cf25c53de373534d771afd919a182af9aa1dc26a2d0284887121bf4d6b6470000000000000000000000000000000018970aa4f456c1b203817322df2e222516bce67ff9ace069599061c6229596e506c0286171f3551302e45b7d3b69a39f000000000000000000000000000000000a57d0da60f03fd4a5664546f9809c771ab6188aca5102c31f26b09950cadc26b0275417ddd9c4f4cf29794b739733cf0000000000000000000000000000000004ebf2bd93d7921d8bd97ee71cadf91145e064a33651da2604ed6fc8e08b1b8305005f12fd4e6b68b7b6a3b5cf123b1324c54daa7de8446e5a26cdbd6741cc90bfd26c544fdf221d47d509c978723c3b000000000000000000000000000000000c8ff29d0333e3f38fd8af91ecdca49e54ea5dced71b60d693b1bbade99ae668e4f994f7a5417a08a8ddafa410d437f300000000000000000000000000000000078ac1d0898a9e6cae29fe6b50e435e5f543d0ee233346728c46d659c4338295f27b42fc4b2851ad5035feab2bea8871000000000000000000000000000000000b3a566d2ef4467f21c27e4a3dec99a26c304b32ba1fcce8276a8518383a7de44de5b4011ba738dbb8761e67e36115560000000000000000000000000000000015a0aab8c3d51fc3fc8aa35dcd07f8a08188976883f9d3ccc87ee148525f2115ca46726a2e3c550167c169977b216d6217ff7a416011549f144a3a65238d62395f4f76afc09496902c064b27739c6d0a00000000000000000000000000000000115589e8e1440edcfe72c008f6e9cdf13fb7baaf70aee16166e7f32f4651db784f4c5cac15d91ee13001169fa777f0d00000000000000000000000000000000000f86710678b01c8f648bab2289e8f90648d9470cb13d5145ade526696d22508a4a59164290586c2c000dfc55b4a20350000000000000000000000000000000019b300961b40b0d9fe6e292e9357d04f0483ab3a8cc6f8f522153c51d22de8e96a812adf720d13ff7d05d1e68264638a000000000000000000000000000000000a80b61ab051ce413ec838167fce393f88c8a25f403bdf07cb60391fb15306a5271a7042d36f7c46b5978106a7b5293c4615de9bd7aebf1acedd9d40fddda34e4a85bc253c5e92c20d984f6c4cec533c000000000000000000000000000000000567c33d22805319418cb1ea7eca6205a6c44f1f881c03e37bf3c66a1baa5153473cc73b8c25d497b0b0057ceb0395960000000000000000000000000000000014d7a2bfeea6a746e709f6108eb32581ba38a617e4450b3567c77a992988d91f4da31b209286f8e9fd0d7b8628aa6c4e000000000000000000000000000000000ae6c9fbf0e06f2e38e91699cd21596ba90f92f6022a4f3c7c8a6557b7e1331283bd4d7a7d31d77d9d7cf70a2945ea1600000000000000000000000000000000066b8132c73e1da8ae7fec9169770a188b686f223fd0306441356040bc9070f34a47fe1bb8c94de9fd7606c18b1d2b1dd38f1a0417a5a366dd2d8f5ce229afb6f34c1b663ad6eb1d9ff12f38412f00f7000000000000000000000000000000001460040d0a19c37fb0736ebdac0324d8a38c94a73fc5f602b7ea5b7255be9d4b6ffc22fea5043d948420e9ae3476f56a000000000000000000000000000000000b37c0078ab8babcefa8874c6cd1c5184d713b976852d087ed84337073fab3054899859d0fac2f4351bb75ee0e534fa70000000000000000000000000000000004150f3b98e6166d9d6b0388342042dd8eff9b8e1239f479330b64c5b316f98fc7bb401b737efb87e1f6663ca4efa26700000000000000000000000000000000043e6131c1ff621fd6f8caf0939487a927550343e24425ada33cf622de757e6e75c9affff9f04373a954557181641617364da9c6b07aada98107447afbb189626180c5eef31f7f2cf26d5d76ab0c74590000000000000000000000000000000009fa1754bbc957d2a8317a2eed859457073571379cc7c6d65bc6a0b5829f8142db77654eb98a2bb0cfa5223a27d756cd000000000000000000000000000000000cfe8b8fbbff7507d3d74f4f550b4c85e19b8929d3728a462e12b4008c79014103153c69ed8dc6b743e1b6fb4720bad00000000000000000000000000000000017ca0c08c320c12502a1dbc841425694bde68b7806eddbb40702e58ed26c7e112f9a821a6c67afed174f51896ec2287300000000000000000000000000000000014d08df9cf825b07a387642ac9959e8cd15ea8e752231a3047fa30816acb1ecb79f1755484af9a98b993f50128c2bf5031aa8d860e3b598ad0c4e9f93f26d153f8a8d8d0dd614ba868ed055c517532f000000000000000000000000000000000273b64e867a9111e257c9b32484655e4d7e676ec50f174d9ebc9fc4262c037b176ada941dd8c1abf645e275dde04f4a0000000000000000000000000000000008a63b9604e96a5034d92e3790411f3112c2c7cdaa056f9f1bdfc0b164c37fc9f58dbb566337132cd1626f9ca2618f800000000000000000000000000000000006a661167c9fb6c26bfe0a3902f309fa683fd22729bfcb433756182e7e1a406bf44ae1d13ef0228534881daa339394e400000000000000000000000000000000193c6c5ec200d225c43c6e37cfd15e16e49b7d87e5515bb7b4c918903966f4f6ae0d42af6b98f6efdedc9b0301fa1c0f290c467c4827c9252b82ff523633ba116c52d15df9cd4e3121ff0e9f754ced5f", "Expected": "000000000000000000000000000000001403c7e3059135ebcf5e752011fdfaf66e348135314f3f4239b066e1c6192ffcaf89bad4228fcc2be19a64f4f5386f5e000000000000000000000000000000000aadbd8d0e53d5b409f7fa508089337bcf36212a3f613b37a95757793dd6b0ca99d1b3578ad8020d46e29c9c4197ea070000000000000000000000000000000019e43bb32f92ed187fc32d9dbe24a486e38316a3cec0fd7f7c19b313af43a10fd63738b78e609e04a083de6761d53a90000000000000000000000000000000001490da7d36ff16304b27f6e57412975497e9f3a6d35cb162464bcf69fe141d34ae27a33afc75a2802eb120e90d4897bb", "Name": "matter_g2_multiexp_86", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000038ee0c2c409d8832437ea450ed705589c82791b8319fd0ba6fb4d302d3c5b73ea0521a0253716e5810f03fca2e9dc720000000000000000000000000000000018c9d748aa685bf6e11e6e4b6ad2290ceff59c8837a088b41a08983fb2c5ef077adb0730b298c5df9aa02a820a19a4bd00000000000000000000000000000000015d248426e362ad2489c0c6a567d80b22d54d6a79e198198a771fae4c4e97eb317da9feba8eaafc9460ef45b1a5e5690000000000000000000000000000000005a2342412801cb37911a04d7ee3b1e5d3dce2a06e0658d59f2ddcaa9ba32804a1ddbe8f4d00f4436aad1346ed1ea5344aaa57782608de34c6334ce5039c67767f6da7b315dcfc772f03aaf3dd1e67b90000000000000000000000000000000019d49748f05458cb9b316e433b0d341e23bb5aaa724b824bd147596761c11efe8f4940eae09e302e563e14e96b814f4a0000000000000000000000000000000018011e7ee4988da168adbcf81cd14a9232edacc06bbfef0fc78dc0f96b5ac86ea67be8661442b5ef60e3889f3137182200000000000000000000000000000000175a2ae3bdade6551b23656c16884ba0fd4247df4ba7471cf81022d7e224b23490db153c8289f95467ddf9671f8b6cf90000000000000000000000000000000013c58c0f55c46bced98faf3865e3b6a836252f252e97b6d2a799b574dc569f09ce33082880a4d0c3b8a2c7c0d4c30eae22c1cde67b0e8ec7217c6ec72f36d8a1e73794297819de9ef6f1e52acbd3ec4a000000000000000000000000000000000ee45d5689a8ea6132d5ace000699a157c1cea3c0c98b38d504153d64fcaf1702ac7a1cb0889539d6b15489fef415aef000000000000000000000000000000000b320e0cdedbdc1fc5733488e6d2aece6386a030adc36b0a69dc3809827319947049f3861c2edc859797d30a3689322b00000000000000000000000000000000194096079b3a1d6ab1080dc71bf6d5734bc7b5e7f30bbb0f9b95c9495a6bc4adf76e198fc66accbbbaac215a8932d8c5000000000000000000000000000000000ec07be0cfa9b3d3a64c016471d9e6d25228b46dcaca6e197be00b9ca5087162c35f1d6326a3cf83f568cb06da8c5220895341f4363b688c4e9660fb0cd17f6c111a5c92e732205fab0d0da0175f6832000000000000000000000000000000000a7f3a3fcf2e7b0ada6d4fce179bdf229454002f1271a39d5e99daae72da549c6ccfc7c574f35bb9784100675c30b1120000000000000000000000000000000000fad14ab095fa09bea919ada313727e7aa5aa06a1cc7746d006e3eaf70f79c5e4001a8a8de03540b45e0598b22710e00000000000000000000000000000000015345ade62c5691690c181da09d8f39c1ead42046987b8c7c975d40690a286a816f8cca519731d0ca23349c54b30d8570000000000000000000000000000000019f0a32361bb6ecd8b1d87c2e15d31c0e0cf995eac9facd5eca123c0799c465f156b0142d98e0f315e9b3595974a7b824c5718fed7503c5e2a97fd6ab0294d6c42b1d35067e9d5ec1077176a4bd3126f0000000000000000000000000000000017af46e78904915e348734d2450fc6e1938bcf002989f855082e3b4ff3366d81ee8d28293609c3c3b11568668b1305f80000000000000000000000000000000018b0b3859763c2654fc00792a5193b7317fa5051bcfd15ea42be2fda0f43adf322219f34e54b2446ef73a4562151f9a70000000000000000000000000000000015c23509a1b324c649ff878d004ab5f253d041670ef172ec4dabec7a525d5ddb8f9f62f383e3f71b0e9c98532e247d560000000000000000000000000000000003a38564a55fdbe05b047281fa153f736edbf48c901749005473255333590f967171a6fc88751eaf57a5335bbfb6ebe86d055ad484f5054e8bd0d073cd556deba05418ef1235d08ecbf8717b550933fa00000000000000000000000000000000100322c4a92c136437714a6586c82a6842027ee218bf1fdfffaf95ce47c9c8b6c8f61115b092dff81ff2e645d0a7a4340000000000000000000000000000000013a91ed8629acb5e770683015c3c248255d673d4b2e6c96334d1c80326d1a8b4b655c81175e4a914a45fb37c1f178bd10000000000000000000000000000000019075c2eea3f64f42be82fdb8f83f2c68c08e858702a0225d869143c0b017b76a7a40d809116ffbdff6700b288f5ca3b000000000000000000000000000000000598ee9ba9d56400b59c7f5977aef1e179855a37179fbfe97b95f19137b6034568e5c7f616943b4aca804272955d42334cccbb062c27a67ae2783ab65a47ce166330cfced1f11b85f87483e0250b138400000000000000000000000000000000025a526b137aaab5ac1b5f8179a18b06feb7c905b4a843cd55e31b7464c2b6d432b569e9bfc3222511c18255102aba5b00000000000000000000000000000000090c20c9f78a242e52daa339d5cc1c3f35aff7ab802a3e4366597db8b6ca43d30fa0fe8d9484e49fa4fd0bf5509f19e6000000000000000000000000000000000e928b2173e32e5fc9c373a2a6f126e1a3a472c01a5e87677be0d29907022b9a7dbec3340cfc89e67377ce472c2d5d4c00000000000000000000000000000000147b4eaa2dcee39b918b7cdf24483b29466120677e5d42b51353a9b2fa207bd911d9b391142a13a212d0ab38adcbe10796111cb1181f048f51349aa2953bba2af50f7b7b5d2328d435bd63a7df5cfe5c00000000000000000000000000000000007790cde9ff8af2d7597d33909f00963eafa228817de1ebf4233ef0831202700b99641318186aec80ac913a1b1143eb0000000000000000000000000000000009d42ea1386d8b019dcd26068ab156f399c35b7d492722a20da0c915f7abe44ba688d9486f4bbb44268542c5a49168930000000000000000000000000000000010611f233bc1c4af0a14e1d1b945c91c077ec3dda592e2f852e2de41e09331664e1a92f9a0b7416c50327bc943a17b9e00000000000000000000000000000000048614243262dd070a754f40652b96a03326fc51273dddabed85df0654890ff38e0da7abb8190e4ebefdd6f78a5fec509d7f0c0c7e927bed3fb930fe2d0109f58678969ac8e14fabdf4ccdd0823f706d0000000000000000000000000000000008451d24fdc873c61db44e57372d43c35a2a8098255f9aad3a6b244913b86bff6444042e391685b1244f009c5ccde935000000000000000000000000000000001177c2da9972a2b96afaf866f97dc149482fbaaa93e194803c09c8334c2c7025e08cad4f7898959a57b07a545ecf76ad0000000000000000000000000000000016f40426cbd1f0f4ca5ae1dfa4c3960a6fbd51a1b5b24ff5d03fb9911e908406a0ecf4f20a78a280d24dc9bdd1c0799b00000000000000000000000000000000194a8c55f549da1842cc3173f3eb7bfd70df26b43a3059a3590992e34fb19b2caac4149f64d442965e166225b9013e2b11ce517fad2609f2ab8d44ae6263623a7903b2cbec683570949a96fad78fc6d3000000000000000000000000000000000a97664c1d7624cae0e969c728a84130fe260581305435ff8ec701cdc51a73977f58c891ecee637eb6b7c972069ebbb80000000000000000000000000000000003f4ed6a9e9f4229f0fb35394bbc10da9adbf4985d4453da64eb312ec88cb15bdc189a3b5df1af3107a36fc001ec92ad000000000000000000000000000000000ac552c5f6170a70563fcdca8e0c6a7c6135af2f9d5ae6f60a2c459d1be4cf76ebcdf9bcd891db8a1e2fc905a23a97b4000000000000000000000000000000001734a46c99e776d1ed4b807f5b313562e0989ad5c67dbcb961c134f8b7b7601c23308839569dc224bdf7c370c4498303b17d28cbcb9efde6d9cdc4c9cda385ce598ac8468d4fc94cc8e98ca3bfadf440000000000000000000000000000000000a523182c886671435ccc75cbc78293274802c6142465acb31a1809e43b1d656ed9c808068de167b1ab126ed0f73a4490000000000000000000000000000000007c4616080b5a002fea3589d54c7510884a3ece705d27dee315851746b1ee748e8a08d3516d8c6afe1c0482b960a9c62000000000000000000000000000000000dd1bd9b4b9c140aeb97887a0266bfb5696813fea034b78bb7d0cf1cca15b5bb0ed92a97841c8d8cc614f7721b8b7e040000000000000000000000000000000012a41a8941b6f0e4c87f8188718f9bc75305d41d6f4441eb9682473340fce0bbb463e1b922d3af8daea32b8a8ac9c3b4a9516e93416bc7b0f3c5ef5da6112abb73fc285a14093ed19d8eddf241169119000000000000000000000000000000001763ab2b361681955735ae00b69f26e06469391af993c8dc6f2e1dffb52ca01e49d58d6e2249e7433ccfb5ddaf8fead40000000000000000000000000000000003858f3bb01b2393aa4d4d7889bdeb0bb9bcde0dcb9b39c4ffe0fcd0b865baaff75b676c715be275929ff4303c416e0800000000000000000000000000000000086d64bd1302b0b3a620b87ac29cac3d9e606513ec8b47898cd852bf552c1364291aaa842616b92c8936e076e59451bd000000000000000000000000000000000967c9f59c15ed02c9b2da6e76fb0bf3d445ba849010afb7f9c994b1ef6a05ad577570d4adad043796eb90e51537ce5187fed462636eb57506f870ed1c8f66e211758327f4c19bf909a6419312c58945000000000000000000000000000000000e6b0da7b406bcac2dbb90fbf430fda6442cc2860ce633ab84404dfbb426949d55ecd72992da1a2e8e1ce229b599232c000000000000000000000000000000000fbe3a345ffc8fb85cedc4b8dedf9d952c41b4ff6f1c7ff4cf91b2276621969d905aa9aae5fc89bc516f96b9bd1bb3c10000000000000000000000000000000018c2a7fcc35099c41bb851ff66abb047e2af9cf4fa9fc45f030124ea2c7efd26e594abbfc7a7f258c8081a3a80d15105000000000000000000000000000000000a27cd33c2121c9c542e27b52a13275ef7e81dc0c6ece883b65e71d2bc3e7246f95aef7c6b41eace382a1400568cf298c373d64034c78482d6673c6906553151887c8aa28ab2930659671b8cb98a595700000000000000000000000000000000158bd8e6198d22b52efb7f3b945668666e1190a4a8e70307ba5c1b737316a8f8568092f219f683c0f53f56f25745d4e600000000000000000000000000000000097e64e4553371c81a9bf553ddd9719f59b329284eca0d76f023d603c29a034d123ab777cf173c5f2bbc66412d69d4ce000000000000000000000000000000001298cd5501e136a06ad4fcf87a75c0c7b96c73e844863b74bf6aa581a0ea98c2b1f608c668743a3e37ad5ca2074af9340000000000000000000000000000000017ff9f1336d7f2152f17daddde9d3e1679cab8120ed2c0288b0908d4e2099a08c9bc6f79425f004ea3ac4d684abff6dcf29c901f9769a42610958a8cd53eaacd9e5c4656106fab536052518b4989911700000000000000000000000000000000115baaab8f0331894da531ab557bb454e2003010ba1dc1d96e3d983d49b1312585c6d4c43d85dc074b23b2fb28c8a1d6000000000000000000000000000000000db1621b721c8a54ece26a355b190af5f3e1dc1b43e0827a1912ace651cbad4b980e77a4c3566aa809157229b234c808000000000000000000000000000000000c594e0ed3f7ee55886e251deef9732aea3de11f094ec53907a843b755add8fa5d00779a66621e615ba7772ee821c4030000000000000000000000000000000004e80aeff6c4b85188903b4d2dcac4f94f7cb4285a38f94b0becb556d83dce8735d1db5810b409d45a8dd1b9a6dde29c125c12599e84b7e648aab52cd68fcca7f1a5f56c854f3c36e0445ab7e2df2b740000000000000000000000000000000000371a74468ce2ad90e19b7fe3f57159dffb1b0422b32ad693b2fe6c45c5d371b97a90054095da887019d25c1ee8197800000000000000000000000000000000010575e1ec9a3e609ca086ef8bca679c4548482d9e0da2e51878158ac8e5b29d824c31ad7ff642041e748efc50c2514e000000000000000000000000000000000ef36130380f1e84b2f462b5f970abb8535431b79813015261015c6d7e74f038b47504de01794840d93fbbb4b386e17500000000000000000000000000000000018419e85fc2d75f007d1e0e02c1975332e03d42c3b41c50c3538c3625e702161cdcf8913babd2995aea7566ff15abf2bb9a1d051e33a617c25e17b7ca8ae6b02f16c759cae0df7fbd403372eb2407f6", "Expected": "00000000000000000000000000000000125406a942ae0119575453beb4c093d2696d3bea7bc031d7a586439197f848e1d5a82b925b4e96138a3460eecf198ffa000000000000000000000000000000000befcee6bd1412c54674a3d519dd2813b87b18f2ab3375a731197e9f539f8f8fff634f15647e7fea3c65b93594343c2000000000000000000000000000000000011e4d432ee6babd502a9cbbb5cf4839dc6da6176b6bb0ba51d99a3587465f5f3f83f4d4cf2c7e6187de93b859ca61d800000000000000000000000000000000168509010b867aa198fc294a5879ce14a51503c1d0e8fbc02ec08cf62afbd357ceac24b633bd0fa99f83dda92e10724b", "Name": "matter_g2_multiexp_87", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000070a0d060c6e9bad0d1bb15417578daaa8b7a5c984c4947dba10fd874d93fd1e3994337c87799d78a674087678d9168f00000000000000000000000000000000128985b69d5d6ea0ad0b19eba7c2b430f5242a7e89626c66fb83b58ca7cb65a479de4b2fca6886cf55b8cfb52394102a000000000000000000000000000000000bb0bced708571662af042d18956b5b7d797b61aba70823618682287deebe69bf1f9a94ca4059e0570e25a39e60b9a8b00000000000000000000000000000000193f0793324dc78c40f356dde030b632feeb1609a1bd75ce88f0d313a0864dbf1f5e92826870866ab9b3c98cd1c12aa508c35887835bf4497d673936f40ed44145c5d5009fae16eb0f3ee9168831abf7000000000000000000000000000000000a61a310f90a5ffde617b78f784b2e699cd77e7c3e7c483a2ccb768f94d68e59a2a4521410c22ef6f21ba589ec3abdcc000000000000000000000000000000000e6568c83e0f7e459b27a28e5bf954983c5dee478a009c244da16041e710ddc67479cdb3da6f47e7203fedb8f765b2490000000000000000000000000000000001c5cf6b948b85a1c426fe932cd87605f1fbf6c932756eb1bfb43beaf012bec4612d8dd0840efd4cba3f5394beb65112000000000000000000000000000000000e02d5bc20c40d7cc2165a21ab37c6e4eb71322c01a43f2085f93b5b02bcabcd668dab90323db0f9288737d757997631a0154f7f8d52319c9e5cd59052e91b84640efe83ac814d95370e46aff4334cf400000000000000000000000000000000165287d72eca1ecda5fe16a555245b0a34a04beaf9177466bfd88bbc675442d206e70f7a2063b6ed0e15e9406232f5ea0000000000000000000000000000000004c0608bd7e01e65a15716b0c505111a3abb0abac3efb846e05e8db59c063950dcee052f04d1c4e9e492bc6740fafe6d000000000000000000000000000000000de897f7ebaf9089f7e198ee41e1efd7d84fbec7327799b9293a489965cd36159442eb0dc1f79f6b1f122f592b013bb30000000000000000000000000000000009774586dc359e5d20486f00dcea6ff93948c5a8b74058645d1048fe46ae3330dd56d85204d328f43f15e674020f353ec252ac28ea29b5459cd2ae5bce4bf08a102280c093b9962cafb481016a212709000000000000000000000000000000000438ee51a560aa419ad6ae45e1014c38b7c43f1f6a512bccc2d4f10a35838369b71799fab4b6a754fd938c1a1b874fc0000000000000000000000000000000000c1491c85965c0b74d08f5866ca727fd30bf641a6ada0ab8363ff01916c37d10b1b7eccff79b396c587d9beca2c826c0000000000000000000000000000000001452f254ceae9626443265ba31a1a750a425f2a7789e69cde16b70eb319c744a6221e74a9e2881c6bafea161d29638df0000000000000000000000000000000011bd6a1bbded174e9cb95d74492f7b07a755339a6c40f2a1a76debccc0f3a32c7017ca4e6679fb2c038c751f19986f526d3bb5ee3410dfad575b0fbe71ac5df2048f74b52e777fe0955d6e244d434f3b00000000000000000000000000000000139157c34aaf70cbfaa82be655281b085e37d6406df4cf8e291b221394e91d9e3cf04d431f15436064d0bfc8cbe13701000000000000000000000000000000000353fcf6e587e71e59d8f05d4085961d37b1f62694dd5c7f40efb5875b90459dd66c4d2d6c01a40834307ae9e82c2e08000000000000000000000000000000000a4975c9872fd167d0ff4cc80a6ce179b1e6e1eb21c8de80321451b1deffe68d8a13db26218f14935b64af25d63644c10000000000000000000000000000000001e8a2824f21cda745a24844ac0336994fb18e30608ac61201a932c0a5a58f1acd56cbd9353bfab4944efcf2859ad5915c30684c596976bf46384e6afb2bad6f821c4a62338d7a6eb204ed75070b1973000000000000000000000000000000000537d7a9d7d9dc451cba4d50630caed32e182cbbd95212577b8c2855c327530e447a4f3d73c7d63fa3ad5111254c9ed90000000000000000000000000000000006984b32955fac4ad3c0d181c81b98534ebaddc316d51a40baa1028bacd6a93a20d4bd6cad6a0f8cf7ade96bcd4d68dd000000000000000000000000000000000720c392a663884ad4d8daeb7279ac41717ea602108c76519da13a45a77d2acafee842828f5ccfcd786bf7ea88afd01600000000000000000000000000000000081f1d3e37ebaacc11671bfe1670ed65ece2aee0e3b5d746a8d618b44bd4b7dea905eb8e958bc026a092b2bd5a7b87cb11009058bb8e23b0a4294b5cae63aff10265e729d3601d85dd7f1e8063ce260a00000000000000000000000000000000005af33731879a574f39dca99c5c1b9517eda13121221be77a0c1bac82fbf29b37889c15a9d32531a3f6bf9137ce82dc000000000000000000000000000000000c62939f00d70a07a85804cd97fd34b9764565bdba225cdd7549729ceb9735bf4d09a80ec3055c483e1e24b66c41e403000000000000000000000000000000000e415677988c9d4656e59f77c608926c83028f91bf4c0634120b5f774ba07180b98141ffdf727cf9d0fc7a4cb52f4393000000000000000000000000000000000c9c37eaca857151a0c4a49b079f2f061e6a8ebb77e11eb32b29227529562f8dc8e2646e25469491eec5a07b11943f203e5489447bb9a5b661bcff2d9a4153a5aad975abdec380301b6d4ce019bf2cdf00000000000000000000000000000000015113f8f9100cd18427ff48038e1070fd835fce6c0812b7bafa679ac733c80bef56492ec3ca08c1117bd0edf19cb26f000000000000000000000000000000000789cd90c0be1de5d0b359c030d4b9d8aef93951e26870e37c375b9e7879cf277971a05babd319a3a6ac53f00f3254e40000000000000000000000000000000019b1cb91c9a1b1ee49c3837339778806bf0c093f171c92c9931ad43e35fc61cc08dafaf55b7b9e0f49dac28a12bcf92d00000000000000000000000000000000066c7864631333226f191e313436453e59f48f91d42e68874fa4da45eeda1f6f7f6342204e64e124d5ecd861f02ef4f00444d520ee01d87407747a4ac37abb7bd4e4c4f1735ca7458cc2e4dcb1d6297c00000000000000000000000000000000129d887d694be0ef2f84c343a9aebd0a2aaf19a4e78586470351ffaf0b1309593363bd9c6e7fe39a6e59445d935414ef000000000000000000000000000000000596d7061c2399b6a9be7d4d495e58c0377b18db1e45cf3eb431d10cb8b15ae42548a86a26086d57b1a71cb5857d7917000000000000000000000000000000000cce7181fc87dfe1bb493043279a5d93cb2d980eed38dab2ace8c9fb335c2890447434d80df6e7c95729933ada7b9d8f000000000000000000000000000000000f0e1274ff70bc6d3f1d0d5b251ae528ed94aa3a1b9bbdb260892bfaa6213892071b8a6407abe26105b2f81df90569492035cab8f8120ea8e91389707a290db4ee69875d7429c6857e74e8bd40dc7360000000000000000000000000000000001192050735b114c19eb2bb9aa01f04d1fd9bed4df877113a14f7fbc9c31acc10db3ed0e0d15d8433e7408bc237c985b9000000000000000000000000000000000a8a66cda780790311b56836fe69479c7b94dbc6c82ed5886887dbb539a40390ebb2683c04078ed105e639a2ed8732a1000000000000000000000000000000001678ddff677b99011c73e0c9875b5b2ba063170f4d565d261b4c6d3263ccce0334b5bbb7ee08692568037fa96782e48b000000000000000000000000000000000ae15f79ad7f790f8ceaf7709f4b5da71642da0c1f7c442eeaeb165c7dacd8a4892fdfc8447a03a7c56e12513499e43c4bec711286827f0941ffbb451a8eba871239341a60e3aaef23487175c9d2e8260000000000000000000000000000000007fcb5ea5358074d06b64c5f46454e682dd9ac2127374c83f3ac5ad46bc5fd2fff7c5a80ffc669a1c159ee8c9a01bd37000000000000000000000000000000001010ada1bd493d6282ac2d3582480f50074a02fdf412c63e93c5857974626ff464150c20bdf23a87692bfe69a075eeb300000000000000000000000000000000086bb5664a8738f02af5517aec4c6db47653a6d76bd4b5e37ba4d8b27a7819e82e6a4c7ba4f8377e06a5878e7c0bffbc000000000000000000000000000000000be1463ab76e468e47e1711c158dc9bb10d1278f5cc676cff937f60ba457061bacdad7b8d3286f40219963b147cce4bd369d91a4d575d4c142b98a53115a792ec50a290608ad316465487762e83f3a86000000000000000000000000000000000c3329d1e1c76b0bcc7ca3766b2cc5ec8169690f45e0ea3e37b7173bfd6c884921c7523ff25391a85b47d5de395ca63b00000000000000000000000000000000081ff066c008d5a4c893a636d24e9752c6a06666dcbf80082167610e73a32d70aae3e58c88ffaa27f05260b86b11f72a000000000000000000000000000000001178e88c652d257888cda1c0b65ee2c0636184194fef9e6ae3791a85417c43a31fe75893773ff3e7b4d4cda9eafa8de40000000000000000000000000000000019657ec4604ab5e8812237a28e5ff320a0d728c60c541142ffd87fec2c703665638e5eebc33e308d5582cd043d08d788ee472561535a7710db521976cef0c92a4ed89861ecb397cbcfafa477756e8e120000000000000000000000000000000010789200f69d8acc70f108145804b62b521a30a04176c449f52bedff5975ad7b273aaf4a32f8461ced8e92b2229e2cef000000000000000000000000000000001178c36174cdb783b5b09d419ae4a154512bf9ce07368521d1576b2f1bf39f98be29bf533bad16ba9d96aae621612aa70000000000000000000000000000000002580f2115d1814667b6178b6bffca6a4d992eb66e9601c0d21e32a5f3b69e3f85e1205c877b2dc2696a0e872c5bbc6c0000000000000000000000000000000002c94d7ff016d57bd5f589971344c6499577bc2234e18e6c8dfd7d27a205442a4236ac54fe279d1bbca76467530140b42cfdcb8240f183abec526344e8ceca6a007c35b757928803f854225d3a6ca36100000000000000000000000000000000108b6fef7396ef71b46339d421726f83b08320599d66da18234011720d2b524d24075a255d2771f1ae904958c50a9046000000000000000000000000000000000723d5045b65c0887da1bb01d874714ac86d21441119a93a1d5758957215f399f5ef1cbc00558db01b295bf0cc988cab000000000000000000000000000000000994914a3df9d3094dab0c0c41a45315dce5968a99e6171fc609ac9e50bee5ccac771efaa04067467e95709bd924973f000000000000000000000000000000000ac746602f804f52e9a485c30412adf92eb9af3f6daa8f23b974339a0ffa6f5aa1b70a80a9f19cde2a69a4b7251ecf5d60659743dc1977a698371cc302b7579b6d7d13632a31b47df369365fb02aff790000000000000000000000000000000000a2ffeaff148dc5f70fcf53e7e8d7b6100cd6e7df5b3fa4aa33bced243f15b4f77f48d25f74366a693404b6ed7d3075000000000000000000000000000000000f3e1b34ac8fde4caedf3d8c3e24db02de3f91487db300f09c779e7e4e96ae55229288abd946abcc3a8adaf18a0c89e000000000000000000000000000000000166a68c5191dd7f9d44eade2ef1a9b522dc062bba9c55e2ff03aef400e5d2765a12816b4ba51e10bc21e06113c8ddc5100000000000000000000000000000000109c00de20f7e827375c1841348e684fdb248fad116e9643dbda8be2bd06b71db264e9f2c40dec2092e7d518540a6d82652a5d4fdf6d6703c857fc7b10a741b95fbce91fe823d827cc7203be3b3bce0a0000000000000000000000000000000014ddb61173359514226c150a3343576b04fb1b06fabd8fe2f921fb3b90baf5513447c107f6d2f96c8b03274bfe451dca0000000000000000000000000000000001d1064860f6c4d62a282147308e80ceb0c5dd62f39b3232a231b1b287e497df31cbc5a3905a7687eb2f24447e50a395000000000000000000000000000000000859611bb3962955f92bff861e03d07bab7fe1f69e90c6bc7928be8d1758c9194ff7a52b16472d04564607b742543eaf0000000000000000000000000000000008a3e8396901a205a071aad06ba9812207171f33775eb358de4232826a5f0ff50ec3e137b1344b583849e8a5b424b46676a30abda185e7d280804952fc0c074ad907fea2aa54da4c3190895270169b20", "Expected": "0000000000000000000000000000000008c9db83241e7f3ae6c2eac8fdcff5f2d35318e24c3b4130e9bb7048a3b84a52fa3f222a8190121d2a5b8835bf911bb200000000000000000000000000000000002db79cbcbabf41bd8c715e024f4687bc0d058d76b8dbe58ffdb80918212ab6e9b35256fde583c0fe903c34a4c41ba70000000000000000000000000000000019f37d05f5c9e65c6f004e1aef03ff0e1899f0739c9cc4e9038e18f9d45678388454d144495b2cd993eb3691bf3e96f5000000000000000000000000000000000d8e0d7715ed71291729bf480f5fee7ae04264015732677488472bedc0dbacf8b35eef7adcce196e3bba9cac0991be81", "Name": "matter_g2_multiexp_88", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000064a134260b753af73df3764ab662e3b1bd624c8f3248e9bcf7676d8fb0825ab85ea33387d4641c81fb8ba3757e0870a000000000000000000000000000000000d67eff1936a395cd3f808ed7fc89f8b6a227c4849a6941d4bf762af6e41ae41c8114aeccc2565ba01fd902df530df1e000000000000000000000000000000000110ca2339832e7a9468844b94b3ced0c9216654bef1c8a5cf66385a99d5d452f978bbb7fe15fb477f56753488fc909b00000000000000000000000000000000173210b548d1b98b926539049996713f53108cd2911105235c1d5258360d5620d330951db67219ffaa304a67fd6219f39f4db766964c7855daea58d1205fe8da572aef06e0ca64912cec7c87bcb2f51f000000000000000000000000000000000f7c3795ac3d511f93a3d85e65261e4c09cd316787f74ced6e472a3993b7b5b0ce5a7c91d99559a8e0791f712cb4e1700000000000000000000000000000000018eacb2c5fa9221881c6311256a69c7616748deb3235c61cc11412860450151a25e3d6a220bb23e0b3e3325044fba68300000000000000000000000000000000121827286873ad31f58cb3889fd01cb7d0f91ff1c241295f6ef2dd0e8aa8638b63a7e6061efc2e7ca1d3579b4868f0460000000000000000000000000000000003a57315175d70880b2b53c67d61831ab066b08d7ac68637364ab1c1f3efad96d42a3cf5189c45012c1f73a1b97bdb4c1deebc727d98bdec47b5a1fc48916dca1e42345ff5474a5fd6cab0ae99e9f10800000000000000000000000000000000180648e5d0bf727101417f515cb9578bdde3e9f6c4176d516454ea7c32c1712610cc8bbed303bd1afd48f580ec11b77c000000000000000000000000000000000d6ffa9b85d69b67abb77f5c8bd776eae82d1cb055d2dcdea31ac66b1825014ec7f7a2aea320ef9f6897c9aac8c0706900000000000000000000000000000000073214fedbade28cc60ecfa4e1fe2fbc05f3d71528aca315312d50214f680956bb9e0fc12783843b00b3f4f0f52efe2700000000000000000000000000000000128f87e7da7b53f28944aeb26ef0f6c99d84038af51a1d242501ec84b5a6a8593ef1a0f6b523478d9fa12e36c2fdbe694b964d74259c216c1eccd7f2b52ffa5fcf151d47bd69bd2768e6466b32eb4fe50000000000000000000000000000000001443980d7450af1e19949fb328776cb7238a9b26240cddc565aa9d52c5592083b1533e8103dc07eac80e4bd830f209f000000000000000000000000000000000afdbea7f1cec534c03d3269d50017372f7ccbcba9f096fdb2754af4d6b4956decbab2b0afb69f97a03beeb20b4ccc31000000000000000000000000000000000a83dfa3197dc65097601457a97d0df7710e001e90657b150e289515609f13997b454167a7589ef218893309460139f300000000000000000000000000000000029c362244510c342358130f877de947acad5a379295f3149d5c713274316e06a169501f889e4b9cbf86f10b9521c1bb124ceb1dbc8004a4b1f8b422d394b0480bca7c0f38aafd8f06ba090a98a1d3c60000000000000000000000000000000010a83f13a185c70ca3f724dd84efcfa3ec463d7c05360056f8b5304864b20025b0a82c9d542ba08b645e2334f176472d000000000000000000000000000000000848a6a18bcf64d083e118190805d68f7ffea8b5a66e0807b9cd3733d31ffa5cc25dbfa6ada604646dcd8dfa622e08a30000000000000000000000000000000009962205c0ba43e5101fc3d5353f429a57a97bcb84baa0942a7e7facdfb0d032b9307aed8bd2ac9094a2e5b1460db7140000000000000000000000000000000019b1012661a10d31a4a73d0cb31f7eec0e7be729a42baf560c1e90a9124fe8d5fe31ecbb6d4954dba7d943a7af773eaa5a2bf15b2ed08b33056a0733c920741f86730dcda9c06aa0e3c135a844cef916000000000000000000000000000000000e7f02c1d2ceae60f314f51374b338c329f2eaa82553c3fc1643c7f1910ca24e277f3d658f552a47f780d4d9e0ac5e030000000000000000000000000000000014b6b56afc4afed5199191ec13dbeedd797f14ed493c25658a9658f031ac8d43de12e6a8c4b1671c9e5ef78da1a55e2600000000000000000000000000000000194d8a50618ff55ba3fa5602d41cbbeadc01a348ad1484c5e9aee5fb7241fcd9018f436e3c6c6dc64beaa241513a6c8300000000000000000000000000000000052681eac4bd59e160b67ebb27582a6d3ad5286d652787a0e160026607acfbfc5b9f38b9b171375079d052cb242b87fe8c3c919f31d72ab414f91938089430bbbeaa53ad7a73224fd3f204b80fa1ab87000000000000000000000000000000000d96ce83d917204e674ad9f5e5728651f5f23df25236b0fe769be48adf482ed8c36ad9c9abb6efa3719bd35324bd700800000000000000000000000000000000107f55ab0e5b60dbcc0632c345a9e93818014d7657b264031709275744e1c6722ec63aa209e655878a57704ca6cb3bc10000000000000000000000000000000018d97fba324431fa28b8845d94f62fc9eacc0253134b923908f06889d375405b51610ac21a75bdfb27e3533dd4debc22000000000000000000000000000000001667856804a5471238ffd64bf3bf266ce3a2351ebc68265674bc86ce6faa8dd50a3dfa00c647fb4265951b3a9607ab99f749063165c6db0eb038cb9f1a573de25bf377e1fee94f31df5987f7b2450aff000000000000000000000000000000000fde2fd0349e7a47a9b6858014d551aea569ef9802629bd9520e303ef0487c9d2d399682ac16ce6fa03adb6f4b478fa5000000000000000000000000000000001858ae58920dd0abd8ad94d2f9f946c53e050fe89c61f62fccad37e17f8723a4fbecb6b1be1e3cb853f045d0dca8e53e00000000000000000000000000000000093615a7f9d12e92c90706a47abe9620c4db41e95e42e478949745d6b73e021422e40b969e9e34263778c8a4d4907445000000000000000000000000000000001006ae7963b1e1c4d8c2c85175aca958758fb380019825b09ca3f728b5356254ae4fc670aa29812320b921b48a069df622d292cbcb836843acdd5a3fb404024174cd5c1cef632d1b9b6a73f2c5f705a3000000000000000000000000000000000ac407b75ea77789748e7607b5d6edb1d891875aeef2802715ddc393818fc8cbe82cde9f96377e3ac60107ddcda7e6610000000000000000000000000000000006e63e49356c38b816736d1d7c360ceaaba875c53c98ec68cb825962531855dc6410a125b914b0ad99f6f4327f5450890000000000000000000000000000000018ffb4ac95b8ffde112c8bdbf07a1c97b1d30a42dd4a97c82617698617ceb169e8702437ff6082a2ae387b462cd86256000000000000000000000000000000000497c4b3788c4d6c9b4cd8b3d3569ac4b4332b2f76c5f03f112e089bb79d33152b2469f7ad3eadb8b954775aab73f47de816dd1bfe025685f2eff0856f9c162d73a58fdeae0dfbeb5ce076e9f9ec1a700000000000000000000000000000000003e16f2f5a2fe15fa02b6217aed7dc688dd2670c09c02791cafeccfceb7d99ce826bccf213f6a7c6064687519f9283de00000000000000000000000000000000095e6638ac74815dc451b3ec85a6a8cc18643b541e8be99052ff6dad39c971f2e8bee976ab2ed5e1cdacf92816249ded000000000000000000000000000000000f2703c08b1d707fb6de215de80b53ffbf2ac48f3dd059d2a952b1031189248fad27beec5c8591ac93625a08e3420f0200000000000000000000000000000000024ae36412ba6f2fdeb0777b892f1ed7bab0527879d93f7b71b62f437f5c1ad1f04a5a7380ae5990a455f11870c7208304f117d41a011d36f55d0cb53d4f98de3b1a6cb55dc8a76b29d393bc21826ea0000000000000000000000000000000000f7ab1908c6d4b152835f950b604b55fdda7eb55c6b90c05e98626ba7cd014683bd3e219fd0d5983e9dcfaaa5d389e560000000000000000000000000000000010b285c2884dbdd540d6dfeca704e00839337f12d2267f6a3fc731fa0f724cde19e268782b4b9c2e11ec3aef9a72a6ed0000000000000000000000000000000014a40cc55570e8f45369bd9dc622e05f03989bce6a98a0d87f4fa7add67eee3e2ad9a297615dde05e64203e86153ec230000000000000000000000000000000007f2b6a092adc595e4857e821579801301396321d4a20bccb3296a031d74a62bd79ea4ea094d2e545943138d2fc930fb6b6f5ee0549b28a1bb317cb020ae0e031dbc381075772ff582718fa49db486d200000000000000000000000000000000108834a685455dc0be10aaf54607a06100673140b012ef23a16d3df204a81dd8505d62ca3e0278a2581abc59e0fbc421000000000000000000000000000000000bca7130de9896e8d6858022f24308af7ca66fb4c91f38b30f717c5491996ef4cdb01f4d38a730f9ba9ca5af5ad1de7700000000000000000000000000000000007d60ded107a06114afaf741dc8826f9e14bac6014eba26089c4e31a73b0f30c4b6e22533ac0db7e73621cecf753590000000000000000000000000000000000b538213a703f7a0bbcffb4aa8ce25ba2a538bf599d3c0251f5e8acddfd596c9912d4cf9a1bd8d3ec070713328ca992205edf9812adf95c9844b2da06f75d96e742c0620d1cb0d47dfd9b68d0bb76128000000000000000000000000000000000cdf0b9bc829cd8537918d665e5bf344d309678d01ee80c71a6d6efb45ee8a7beca35bb5ee046e0a3fac76e1771520ff00000000000000000000000000000000014e5be9dca2f8ee4da18e5ec9c4caa891dd78acc47f553af584308c72988435b85ad21b14abf8421bdb9e25164d568f000000000000000000000000000000000accdde22a1c479e47a17b8da6f1d2b7f780ac278c68a68090e5402977d897bd734f5af8164118d613f480c1f65e5d8e00000000000000000000000000000000029614458afdf6b572bea02a0af987d178c43650ca1c80a297b1d31e259aabd3e2a2c8e4b2c044466924dd6e5e3483e6f64a71e4e7652860038df67c99d97b1e5a063370e65217531253419bf2e6365b0000000000000000000000000000000004e45cc43d4d10ed878e18df156062c799a687b8e6beedad9fa6f66ad855cd053af6918e234ff9a43561da7e67f3dee10000000000000000000000000000000009c9ae47a76c199c93c38e7213c8d6c030cfca709714c703839b9ae9b65207e83486f9c8c16373e2b37756f3fd4355fd0000000000000000000000000000000001594ce9c2e229491b22317452938115747515ce62a0d49f4dd12667f5b3e7b541b3775c9b1363cc185a539b9f7596330000000000000000000000000000000016bf68e05e32168c69ad67331d7bc88a6d130fe8aed3e42eddfeb1d92add266eb69487b246a3ca961ea6ac0a35f8da78059bebd962501b8381b67c22055ba01667d916932713d7ca427cd80d8f76b41900000000000000000000000000000000080d165c57354f87008eb97610d4a596f180e48ed3190779591a0f7e07278f8d2fa6cd21d1b10e6347f11bd9731fdfed0000000000000000000000000000000008d5a1e66ec76743ca366be80fd1cbd5efc9112dbcfa84ce6c44e8df03140ca5f07d4bafc6c6ce5f2f190ede55fe8718000000000000000000000000000000000d0e1d2e5ef384a4fb314fdce54ab7895f895b3bc669acffd48e92c6320024d4f371f42071fceea550c8cf68615b00960000000000000000000000000000000010beae4ffbb68cf6e5d0683dc0629411ee14563f84788d50b1c8755b0b06092cc0f0ef7b55a39d51945b5178e374f8e047b3448b9b404e184f7ff20466aef3dbd4e08375673ca31fdb303c88243fface00000000000000000000000000000000161486d422462460923bd98834f0cc270982087697747fe40eb9153a7923d48eda191e4e7a75964f18f1df9365901a360000000000000000000000000000000017ab168a4ec81c8db4a74d529670fe6332b3870004f696f3a143cd1a62abd747d94afac9485e5dc19b0f4262dd379c990000000000000000000000000000000001e9cc85f03039ea53253f0fa2420012171fe39ed8696ddfbed57b80b73476171e59631388d75fe43aafde52aa14a64100000000000000000000000000000000109a5d5449002f4bdca44c0bd141175d5ca1cee449302f0314fcb5f282f022a7a3cef77f4e9fb515107e797726ff51d767d9d30b38b252a0661c12dc69127ac380f3f756144801633e99bc2ffa2f463c", "Expected": "000000000000000000000000000000000aaa5de171664fcb45439b17a024806ff7e07d02294e0592ca74752a5b66f3365d1b49d6893b3bac3b8b0d10d026e48d000000000000000000000000000000000418354ce1820ecf848321a07ce22117303e5a15169a9cbfd141fb4797de8871d84d577e86270a9cbfe31c088ceed0250000000000000000000000000000000016884caa03ea641e0660a790975d77c5bb03568f873800d0559b69e3e0afcc10ddf031bb5c25c46f136f0791bbd3cc8f0000000000000000000000000000000002bdf659df76cbaaec030448e8f4bbd6b424037a8dfd7c4b8ccaa2224b0852c168f49c6f45c04f23abc85b8df21953ce", "Name": "matter_g2_multiexp_89", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000062bad6816308f1c8c6941980caf71929a4006083dd29827902ffc92ebd9b14f1ef662f3a0125b1e74dabd039f9106400000000000000000000000000000000118e4ae76e2c321a5b89eb19b58f58f44e80dcbc7bd6d619579da40e1156aab32fe81df8eeb1bd047f96d65aed8b3b6a000000000000000000000000000000000c8c93e1beeb4efe52a96e5d5612338721e3e487c13c18b02475f9ccd8fafc2c95101aed291951f2031bee5216dba26f0000000000000000000000000000000016fba44e9aa39a12ae27e3c36de1f14e3f37ffb0ceaf5fed2a0d9815eab02c5aae91b254812a8f3a2e3654cec01a341caaea75e63204e177d404898aa51555767f813c3f3ed283405ed1ee829b04c85c0000000000000000000000000000000013716488daf8586719c52fcec80d35f17d4c595b66c7f2138244f3c8cea69b819778bfb50e49ca1d092e57c51674fca00000000000000000000000000000000019cee25c4731bf48602ceab23b5fc4f764993443e3622107b4c33b29c23d1b5916380431b7ecd94a0ce99811fe6dadba000000000000000000000000000000000562b28b245b7c1ee531a320fa0f4e12d7c171c7e3932ffda6cfebb123fa7f5993e5ed5e7b7d295405e5031b339994bf00000000000000000000000000000000180c4a8158a26d34123c870bc694382352a8e4de712b650d3e45e6baa16d6950ec15d3a4e032c1d1ae8fea18faa6f3d8db48a90ddcd791e6a9debfabcb1c71c88e7ad98f9e739ee752b381b28d7656f20000000000000000000000000000000008472d40e0505d6b8b92500e8e9711112048611fcdcca2377481ae86a7f6da1571f179183301e2194a42dac3873a3ba5000000000000000000000000000000000e2c5b61c050a8a12298f76b5f15383e72b90b001fa26889b67a24bb374b63c1e00979b05450e44ed63e72042af6d46e000000000000000000000000000000000e8723eace9c7a72b3e6097afc9bcadde61462e2ee03fcd5ad1b1c0dcf39f437f80530c2a1c5e6ecdaac14e8715f02e30000000000000000000000000000000002e21e0f451d035a5257fb09e9ed17b27f0994e6d85ddaf8d33153628adb194c97db17656351c029be4d3125bd29dc22ad1795823d3834496b0a1c2c07431f9d76071db77834005fa1228393ad4ce3f40000000000000000000000000000000000dce49634595869d7858e95a301bcff8112eb73dca8a22042137456d6d4887998a541489ff09f8e006176e6beee4e300000000000000000000000000000000010835f7336dc49e62706da4ef21d8e3173629b16742c317c1b397d4f17ced40a56520ea63557d7ac7f251568f4eb3a220000000000000000000000000000000017446ebe659a4510a362ee3b406b636bea8f381503e51ac21031c7cc92acd23046d62c2f32cda01b680c0f107142ae7d0000000000000000000000000000000006ef82deabd8983ebe4255d8e06f4a1b3585c057b2a1ca3c3e1cf04b582b65792e9980e3a1735a8ad58b053b16ca03d036d56e38fe63e573b02203be04ef9e1a044e1754eb2db50c6f9804abc4a40f46000000000000000000000000000000000cd8e7422ee179a0499178c3848cc4fbc87fc25c8c882f036a03cd9d3f273f7f2bf71bd3c9cf5e30c42b1ee6e90b36fb0000000000000000000000000000000005005a471d77a35e922b6d6a45b13a90947c2b31d8e7a2e4b6388265b039ce23ed958495dbf904186bef60fd547b941c0000000000000000000000000000000006c337380065eb8a5f63cb20fc61a9eec4ccf0e23c4e0f231a5bc4d765271b9c5697bbde692b4828ae22ea12423ad932000000000000000000000000000000000f7a0080cbe72a6e6473f66ed729f58683a80815a1748e52f7b67a6bf2846b7df8e7dd8599f87fe63706e9823bfe00d21a6b36f4674ab19202037d59fd8e14369e5d3d71acc3c76985b813d81ca6e24a000000000000000000000000000000000c94834474ac91547546d7d179b2091e33c8812c1b582ff186e69b63011177283a74b549aa342a7f3882ee82ad8ecc03000000000000000000000000000000000d72c4308e9ae695acedb9413445bf6a40d59ca78bd4f74ddbc1bcd8508cfb521bfcca99c98dad8022d3d1ccdd98bca9000000000000000000000000000000001487d006830d00d84a567c5d031019035443fae4791a05253f91249b32a4b3e7b3ce7eae885b8caeaea411a90b3445e0000000000000000000000000000000000d94f17aa100503f605732a48e4f55c394a8df1421a3d7c78bc85f4cb7a53744eadcf76e1620fc54204b123d6071cd3bad85286877fa7e5a9a61dba9df5ce35083beca7c2f5ecad13d226fa32b9720e900000000000000000000000000000000101cfa8d9c7522277f2bb4bae6c09e8b93a876c749c91c61784feeb105be61c2479375abdaa81deafc2fe754ed6cd9da00000000000000000000000000000000089ebbdd489ff670a70218f5aaca78d4e7ade483c7f20de4a84d39217be8f560fbf7bbe36f3f8b8361ba16d17ce609d200000000000000000000000000000000094f094372b2315fabc219099200e7b9e2f3a2f6fef2ede6f83c82f44792da03aaad06b8cd06dc3f140746bee2a45706000000000000000000000000000000000cde6cf9a3a7018b2b1c0c26b5850820080c7e4b56e615d577a78565431c93de78348d2851d5ad9f120ddaa9ff3da31b8fa5387c5712832b52c9c72e10c6f69e9c1c5b278aa379140e75e404c4f50a2c00000000000000000000000000000000059bb8e5dc5f0cd31cf674ea78b80b67b8a8a753e51284a2ab37d3f29459250d904e70ed00481b73556970a7f5424e5900000000000000000000000000000000043c6a53c413bfa2f4bb14ef296afd97ce801a37fe63d11a842f8d66160794c1a651d70f4c836af2c73cb1bc58c706460000000000000000000000000000000003e7b67da1513656f7b08fc5a77682477349ac57e53687c82b6d98772b5f929a2b06b0c7e14481d522aa94fa3a6e1cde00000000000000000000000000000000109e07928216eaea36fbb20a38711e73fdc26e18a6967b54f308b10116a5c8af0c8411406ef6ab1050b61c23bb746b0a3023298162ebe7f4ae6aee45a8a6ba602c3942a8bd6b35636fc6b85596a582e000000000000000000000000000000000166f26d3d26cd48e498578900a8c830ce9b80f162c4b430749651b945d9f60ae6a26306ad7711a1f9d3428946074912d00000000000000000000000000000000165f1bc59c9c36d12754097ea83e9a63fb4ae5d1b93a1b9239a6f338cddf4a9b30415d58076852288c6a467ce9b6b9eb00000000000000000000000000000000198e73619cb93fa6a2bc700cd400519d11a7d3d6d945ffac9754a6faf37da8596b49b7a3a4f2cd899ec9c84f1e79b7ed000000000000000000000000000000000a4740820d60034d37bb85e3e622783852779d36d6e61f81a7eabcd094993dd7d81900277550bb4299d550d2805466aa8ff2430d2f82c6d5e7424836ecea15af0ba2d0bd6498e65c65b6cd281a7b8f28000000000000000000000000000000001714857b0ee07b94ea928ff57aae9fe003c0c85d8564456955d14fc8d4ae14a7c9bc303983af3e2999c6db2d000ea51d0000000000000000000000000000000016512cb60aa372cf5098ad514291d8168ed31bd755861dbd9ef020252c01379d343a9c058839cdec8d14f2fb9da0db80000000000000000000000000000000000af74d8ac711b6590e7041e80ca40dd4db659e42b950bdd68c56d676de654c1a47867bfe6483dfe1971eb7c1d1a70bd10000000000000000000000000000000019e56ca1ef3fffa9e131fc5bc93100577b062cf9b2acd234c79e5e54aa799a389f30002b4bd683edec5fb100f1800d66415eea22058493dbf6ac248fd2ad8b4734ebe33761f2177089a3feda396001c00000000000000000000000000000000019d1d1e1e2dd4ab86df81a8246c902a573d1fd1598050663342e411a1d1b3c8849473c689afcc8e0ce5e51a9dc9c3b6200000000000000000000000000000000190d7c923bdd6336fe3e0509563b2eb6067354d8807f66e6052e97d5997464b9f07f29f3022f78779a5c4ac155a703ce00000000000000000000000000000000128591bb699c18a7b9e6e4e894654853f6a68233dfe8c744b42e057711b8d0efb3a98bab6aaa40ae7675d9200a8427d600000000000000000000000000000000045e0560e0936b16d1e055d3d3f4e0fb42d129546abddebeb78e871d1442f4796d939929d354b0326b95e50fd5208fa9ff79e3ef5d32a751b713180be37d44ae55c59c5a8121c132c5098ff972d8a97400000000000000000000000000000000092373dfd7d4375d6bcffa415e5b36a31499e881a80be32400105a6d56b34d64f4fed09f12640a43289a710f034b71e6000000000000000000000000000000000fa75d6510b3b58a32635a7a6cb4b9255aa7af46905cafc893f29b7866e12565765bcde498dbe87df3d1dd53ab5628320000000000000000000000000000000010dfd3456cb6a8bc853b390380a13f045ab43abd289fd05e7f98839477dea1fb1fbe38ca4f5bdd6691446ac0219e453000000000000000000000000000000000112567397f3fda84db6042817a99aeccd0c46a11fd3ba44e2600deafaaab7014dba98cdcadf81b97272fb7f275ee8a4e039bc7274a3ab172285d853d368da0950203a48ef61b3c7564644762279c1ff30000000000000000000000000000000007b397f093e69874d2bd3592489d93c80d0191b157e71d08a6ebe73063f77e7c5e084a24b34da2aa6354b1815a694185000000000000000000000000000000000fcede3a39dd5f905d072dafdb6f56d85726f6f362f91f079fcd47a8c1d3bdcf199d64edf17e3db1dfc96a3e59f69bfe0000000000000000000000000000000010cfa13c84e750d8af8bbb88bd6d16adf3bc7b532447c2e6accb359a5576be08c1b25f336047fb8e01a4d7f9080d0392000000000000000000000000000000000ca0e88b5c2035bcd3a65e8bf1aa219cf428b6f80617040ae02a0ed41559804844df373ac61a85899bec83e5a6243ed42c47d0b1fd24c1c66a3cb0deb7d51ea19f0fc492f637ed5d4d03e102cbdd055500000000000000000000000000000000021f3b793680e0e3127fa53034e9fcf286f5279cd167ac1e8ba051c440aa265ec6d28fcc2f6d3bad126180efd4503fe900000000000000000000000000000000182b429f27996ee070ed27e7015bd70191b814bd02ca6558a9be81d6898161aa525197c1672ae75da92729f2fae9fa3c000000000000000000000000000000000a20b3922e07da4ef6696de85754eabf1f58f7f5d37accb6cde4f62066e789bc64bc8ad6ac827b8c955acc858b03d053000000000000000000000000000000000814faebd3b60fa1a8fb86b3cb57d36b9c85d4b28e97a2251e6bc1fed1ccb18f17664321f38f3723cf8b09a2161c6aeaab4aca860ae4bc20d33808533c9a70108b153bc4b2256003ad4bbc11dc92898500000000000000000000000000000000159f9d329f929a65e41c7a0d4c05e11db61ca7d6d82f8b92a780bac66568694656f4c845a730861fde9a313fa49bdf0e000000000000000000000000000000000d556bdc8dc959b00f74209dff27023c5521d387a40bf20ae2a98f3f55318eddd347bf1e9d856f43a4b5fcd26c3567ad0000000000000000000000000000000009b4b0cedf477ef1e0f99627bdd7a7afeb9e29afbac553a516fab479913b23a9be5e0b38994215a9e23849bb664201ee0000000000000000000000000000000010899f4dc55ac5d1f56a7b8d55ce7f6a5e0a8647bf1ef6e9050f00c5fcac9f679f138018b9aa611be73d3bdc0af2056e297500a2747f9a68b2d8d9ca5b0390369d919897c53d422cb76c5a283c38669e000000000000000000000000000000000226c8a6b27437972ce29c2ed7e5cca4b6691e3a5dbbe713b5d309ff2f4cbb95e8f1571314444d65ff5fbc3281f9354f000000000000000000000000000000000282a49d0c560d873676967700c1062013a2d4beee96a09af7e14436fda4e3d2a32ab8ee4e591decec39a811ddff130400000000000000000000000000000000167bfe499f1f4609e67134e12ad91aadc37bdabd0055ecf7f96162c39a02a86e62a7b3d39f514f63edd82d04beb1958a00000000000000000000000000000000191673ea5470e4704e361f5ead1c56371d6aee3035d92d9e1b96fd119c4f877cde6451411e441fb45aa9fcb90fe4c66ba87ca4cf226c212c80f3db5e4e781ad7391fb73b1124d01cf893169d1c50ca99", "Expected": "000000000000000000000000000000001488532d83fddf0bfd69b32f965790b3fe4cd9f64e8d17e78189c346518c91e69db2f0b742cdd5804b3db3777dd931230000000000000000000000000000000016205c470c6371d73b012a14d519bf214ff10de458605097da1b798977bd938727c5be19a10f4f492f301d2ab6c38ed000000000000000000000000000000000142cc08f61d3c9bd4c7bfd0b7a0b8693af6120898fcaff49a7fb5abdaf1d15bf70eb033d6ff09a75995547e6856c595f00000000000000000000000000000000164b2807e19135ca3b66bac9aceb371165c930ae063f3cb5a06efb8985a1e0c39023d8f01df517713796083e8c2cceb7", "Name": "matter_g2_multiexp_90", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000023bec14deefcc20a90e439bc16912e90191dc7142234b1870e4e8d70c56f695d5cd30a68930ff9b007bdcae8ca90d870000000000000000000000000000000000053a6e226f3bd82150e08ec3690f36616d5ab745b36a9990baac7ad3429a41bc60c7f7000ceda4cc9298b10043639e000000000000000000000000000000000b81b331589ac332093928faa60d6819d3b5559d32d37d2cc13c78aafa1cc34e32d317695c1c4b4979baa1865ced90150000000000000000000000000000000010dbac5e52f9a046ab88aa36b3c5f6952720e174bf8f1732e886e66e5803aab63642185aa24ea08c991edaf8375bcadd9abfe7e05e8a210604355a77f64386a01323407d9f25397769cc6dd141bc6643000000000000000000000000000000001875ef3f90df03d49ce6cede2c791b4d8503b75acff2dcb1c7c88026394dfe11481da72de4ff58ee9a98e75577b6398c000000000000000000000000000000000c8ee603d1404e64ea3ff08c70b3dbffd318736ae95f9a96ca07ddaa449818e6c5a17b2970f572f53c90be893e5c323b000000000000000000000000000000000f31af63c68481f527092b261d29d5c2daa95873b68899c28ac7753d95a64f455ebabedfe6e72246e494cc5fa2a9bd040000000000000000000000000000000009fd06bc51d4dc51de9fad6d1eb763809cdb5ccdba8e0427859d878904bdf295983b318f311856728078e7cbbecb0c5b64be08e7c2fd15ac0116ca941b85615c6deb38fe85e2c0fd22997e394b8a67690000000000000000000000000000000003ce75ecf6b605ce73f4e215b1aad4799f91e624daf0deae3a273968490bdbdbd0250686ee91a1c24c2e2f2b6024fa49000000000000000000000000000000000e4d9b65d71b7593310fb5145677d170663c0ca29636f7b7c50ec1988bd2d2f1c41d542d4cd8fa23fad94bd6a84aef5b000000000000000000000000000000000fa4accea53a6362651f6c6ad2a68d20b5f549f8eb961718e0c14cd05249a121e442a6a588eafc83d6a43d8baa66882400000000000000000000000000000000121e325406767852620ddc45677495fe3e0851fd3c70922896a3e92033347d2fe8d07f4db8f26b8127ec39d619d596030c391dff1c0c303c77b2a1fff24f50250dc793338f7d7f8f1d54bf7d87ab37da0000000000000000000000000000000003a0ac3ac37932b71672b9c48bdbd368d64c11f57ccb952f633bcd10ec19134c65fb2cbad655d773a90cbec2d9232b3b0000000000000000000000000000000007553c470bd8f38a48490dadea29df81ad901ecaaf1eab35b1f497bb58acce77b883e03e78702930dda72e2277139a2b00000000000000000000000000000000044973913824b3326b72e62ccbabd8c9f1b5dc81b423d0dca37b6f33972d993a681c326730717036bc6f0286da9177430000000000000000000000000000000017b0407d2864cfb39dbb0a5fa8deb4ed4a690a4042153e829f51c56bd0f2953a440d8305a318e6d6f67970d473753021a2d728e013e5fc3e1ca24c105a0c268cbb4f152a97e318f3aae33186ea6bc93a000000000000000000000000000000000b7478dda7053590ed013b7c23431a21626e748c3843e2332bde0bd3890ecea95b6104bac420a8be5f3dd9b075203616000000000000000000000000000000000e6dea641181cf796f62b196652f952ee2a26ba998cce1cfe9d65ae49198d10badffa561e2bd818eb2a7f350c122fa820000000000000000000000000000000003c79917ad5a9c7f046b34e5491ed015695aecb00760f3009dde4cfbf88ad1c03e44117fcb6cdbd5ecaa8df8760a3da100000000000000000000000000000000034e22ddbdeb9dea46c71ca2144ffcc8356c1a525c5ada69a6d5e5c1786aaaf0cf532e31a2f78371e04a72e8222ed4c7e8da0c8da19dc441f53c54551579fec5d820ce2e3599824b24b7c5bf1847c5890000000000000000000000000000000017964112272360a38d3bddf89da922ab50be076bf71a094fc8afde109d3817cc2db633e6408f5716b76d70e30ae00c0d0000000000000000000000000000000009bed28bbf43846ab97b92aab9ce094b077bbc59db648dbb469f21842058ef20318a1a8c18045b3de555bd8c76132ff0000000000000000000000000000000001297110789c7aecb0fec577f6f4a4de14608d9aa26a8de68289adea7f6b53b766b840d315152ea346f8c10b2d2729e730000000000000000000000000000000002b551c6a7846b96c6895e55ec435397af70eb435dc1c562ac71a44c36936c2c6d3e6a1e3545513516513391aedaf9ca76e90965adfc2fe52e4341895e6b6154fd7a097e052b59e4935c8267a6f0e63800000000000000000000000000000000003d463ee4d177d78849fdecba52b7e83ca90d54177ed39e82b4e80c17994a6a2bfd9c46edc0ddb256f8955428f30eca0000000000000000000000000000000011dd976dfeb8ecb7d7f5cd10c235131709fb16d8a827e83d7084266c2504cd1f5276ae3333bc7fbb4ebab48c0d97a9930000000000000000000000000000000005fd19477fffc246f5991603b48085d95256b273631bcfc16f19c6980a3ba01ac098061faa149b475bfce37d586464b800000000000000000000000000000000103ac3dd682aee109dd7fbf60b50c28cf7e37642f05b424773a06f6cfaf7e9fb01d5074ade97ef6cb0ace2e1fe07d54c7f3f352c7b7a9e2eb6c87edfc99e2df3148966760168f6abb13ee482f223a01d0000000000000000000000000000000003208ce7f51a96dee053cbaa66fbdb921c2c3b42ead78b39b4f1df7ab49f05cb88d0f4ac18de5839749416eba5535d4b0000000000000000000000000000000001ff7f9db52aaa0fddc8e96a67b99353b92d7032f59d200bf69da3b446d08435d2ddaeb93584d3b68a1934566187922b0000000000000000000000000000000005f05ccfa5704652cecfb42979c538823fb9d11a00222a963d00f1a4b9a040a0222dcf45baad40c6574d85e5617dbbea0000000000000000000000000000000018637b8c3ef111f6ad4538464c250d780e7f081802bdf720f4c925154f4667c5d50cdbc4dbb7d0b2747b97d2ba2280bfd35c4286f19a9fe8117e37132ce4ce76e28afee25ecca2f66de3cd5e1c83235f000000000000000000000000000000000eb400becfa5521b824a4288885fe46642c31576238e94f95e9b4bcbf62845ee9d9ee122f87d36fbe668f0e605fa2ce00000000000000000000000000000000003c8cbdeea0d09590e1719ddffa0a116723f0fe85585583f3f271ead66fbc2107873181915cc41eed3ec6e2c5669e9d3000000000000000000000000000000000e61c0768561517405952c6462f1c5df95be272251d8a7060624b62f9be310cef64436eb2c4c04e8352d7b75fea1756200000000000000000000000000000000036cd74a8efa8a1fce7587f07d5c2a6c4b7ef161b0faae037c9bbe63bd0c92b83e514c8c1bae4a5d9866c0889b1b914f3c2b40b7968a39fe8e4f24acc25b6c727887c3c44cc89cf62eb14a78ae47e8680000000000000000000000000000000013019d0fc8b93da2c79e473d713d94af33eaffda65a7a49d0cbae9f5259b8323e6f29b83da9608ba7d6ec004fb0710eb000000000000000000000000000000001505d30bf8f7c51994d896d91e8e2259782e2b49bda834015477f18c29e64da4d31f8b96edd080267b77a9539afca06a000000000000000000000000000000000eba929531615d9c0f59c4b33c1fc34b81e9c77cd8c6887099d850b3e39326d7caee1feeb101222f22bea1e9853d06ea0000000000000000000000000000000019d88f62cae047ddf2cefe497495f890d9ab8499e56f72488af65095e992427bf821f63555a67b0afb00d6fb441080a010325465403dbd4898beb740884cc325923ec3e1d7483540377d8bbd02c11382000000000000000000000000000000000b7c8f3d0c56b3b7d96c0a24fea3394551a186f87acbbbbce41d1313b23762945bae2e911725da4211614b456b508c0500000000000000000000000000000000125316f64bdd0c5bcd26a0e5bcfc3139045b3a44c8a8dd1cebbfaeb83b963c5a5abd4a5961465cff261c0e49189278d800000000000000000000000000000000095a327f488b901fe7dcc9f9ce6f4f25876bb09b053b64e9f4de9506a0fb95fc0cd443473c2cc5436750581d39b8e51f0000000000000000000000000000000015d406b31c791ae2d25ce462304c0bcf341686d7967c9dbb6734bc28b02123b1730d0a673fa8071dd90950d9411a2b3909545b90dbe35b0d5764bc72d45717e0c3aca6aa77c73178fa8a3ee9fec9cdb3000000000000000000000000000000000c7029af9422246d0a30784431d6bf9eca09481589438fe9a6d2fe1d5e526ec3d176a3d550204aadb85353d99bfe3ce50000000000000000000000000000000014a0dcb26c40693ad19a1edccda05055a27ca24544e933d01dfb964571071f94c94233f81e1ead0925d24e6d3df2c21500000000000000000000000000000000147a55ebd83c746128ba9c7ac57be125ca5c95f80f891e2c5893caa779484bdc1f9c3b3ccc4223b2343ba939251f7fdc00000000000000000000000000000000125622a040d8b157432ad81b8a83a9b1f0920b92680bbb65050b4862b89017b3bfaf81a3402ccb383265ba7200ce677feef0f8014102664a300ea9a30fdc7afeae3cc338fd45cd421a1bfea98e304c810000000000000000000000000000000013b394fd7a0f3d94e5fe4cf5cce3627d425ec848912395565b3e61ffe89e56be799c4779d3b9a0222ecc6538ca3346e40000000000000000000000000000000014ac1a87b333caed0f557fa5692d1138a8c1e92d1f9acdc9f357e2a46f27513dea42f367b046d389dc831610be4fbcf40000000000000000000000000000000011fa243a0aa8b0c01c7636387d60021afe6efc223b7deb69d030651c369643188b9dd5e08d6d031d71dd11eca1e825ac0000000000000000000000000000000015bf8fd7fe438407db7f1b0b586b2c285777c5b6dbef9e45b46cc0a50dc831f32a70e7d4316d4869bc769ff6de58ac30c8f1e08cdd72ed200253211e3b9947cb2a5fa24079b6920b4a4d3f1fd78146e80000000000000000000000000000000005ea57c269c9d43d3f17a83df04c95ea7e7bd85aad1dc2dd285ccdbd52bfe707a1d2476417e848ab119e62fea30520af000000000000000000000000000000000b99768ffbe95e315b244bf996cf34f8ac356664adda5aa7f4ff8d513b2eb5934b8ffe0fd9af94bc9b934e0a8bbd51ba0000000000000000000000000000000003b02c259df189370dd2700c5cccfc8b212a4b332a083adf9771503f5bd0c9ef040590320fe4a86c555a4ea87531268100000000000000000000000000000000003ebb1e610bd055d037a410cce3ae06aa654950aee0210ed0ee79f7a332be7342e308347d7b17a146a8b4c623029e08a7e25b1a60b6c6080ccf1bfdc37aabbc2bf92079d9356844f7f12867b3e2b2800000000000000000000000000000000015c4da691b5e6242af870e06b29bcde467b4644f01080eca60a28c7f941590192be30e6a4270a36dc8959b80235600aa00000000000000000000000000000000080f3d3d5c35ee24179f51ad854a37ac4ff867a2736a0e3e8f3312ac98c7016beea6ffe2bad1dd4842d6ec77995ff97600000000000000000000000000000000130c29dc633aaefc831b0bccb13fde1212fdce8cdd17beaaf1d06e74ef5b1b69bcc219c8d63f054690af1b6dc7c0d647000000000000000000000000000000000767290aaa1ed4c1dfa5603d976df0715b417599445ca577ded7d99e685118bbec71443fe1d9a65e0f23436353df152cdcb456eaad2b7c71ca32277206c1a1dbfa7e0e84950cbf14aadd455fb58e398a00000000000000000000000000000000133e997857f47f8d6278b8ad86f4692ba0dec9da336f2726704db593af368dda7aefc0b218ce1674f415e0d9e2dee5c60000000000000000000000000000000018db87da1272bd386f7d8b5245dc2de30e82739723b680dedd36f4ac4cf5042bcbada1e1bb307ba444431d73a4248f9c0000000000000000000000000000000006580be3e67c7a615408aaf9c95c0956678af0e2b1f536f1e69588193387f8a05b03d5e1060ca60c4fec9eaf3e72d39900000000000000000000000000000000050bd9879ef9eea147678f552cedacaee84562e6561b3b7338fa8f9d514099291c3f2a3723fdb22c88f1c9243d411ccba6e7b19245341fdfc5927cdae57f59de5f3fc8c37f8653e5aaca87db682034ce", "Expected": "000000000000000000000000000000000d8f69d90c871c08ae09e7b3e62e36514fd056c41fb596fec2fc9ce8509ab4f6675d7e85aa6b4b3197f5ab781f6f2e490000000000000000000000000000000011c4bd3cd156c34065e408efcaa5e13ad23d114458b71c2a6345f4aaf82af76cd4362db7ba9ee7e1e92ce72e242f570a000000000000000000000000000000000712dbbf20e9b24d20511d01717a3783608386408a258c2261fcdad5fbcab36c6bd21473c3d93ef8518975256c65a945000000000000000000000000000000000d13747be82153aea8076fd7813ecd7f60a214c31e88e25b14dee5cdb9336599e40b136d9ae6deb85606d35406b2675d", "Name": "matter_g2_multiexp_91", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017da08f2faa32570d95b9efd2d2fe358faec1ffe304750dca1dc3a273be3427c70904d58864f76afa19b0fe33ab1535f0000000000000000000000000000000017de677b713202f23baecef2b0618da140af624e56b876f2d7a20cd437c3868ea00ff6cd9c8908c1ef323ad294edd9670000000000000000000000000000000011d50aad957c54868aed6d848b2e67094b129282cc2df56c41d6ffe976d02ee83a592c33370d3715588a074db503b3e8000000000000000000000000000000000b8aeb019d120959b21627c1dcfdfb67ade22a948fe433172994d4a34084ac9e1c11333a9c663c87acf50962e21c728e92898d9cbad829a5346c0925c15b585de18869adfe796e46cbd56828540571b70000000000000000000000000000000001312ebeee36fff8152324a3ed24c37eee50b3099619a33c7a6316470ae722548b4b9e0f0640453caf53f374dba504830000000000000000000000000000000005ea81d2e5d9edeb3ed6c200b75beb731c31ad666e6e37db72ffd0265378bffc2724047c7c0c6e3f1598345fd390e9270000000000000000000000000000000017617a836beb12e637c5bbadd4fbf1ca2f5cc3280814ff5cbb5890b31cf2d2faee9e3ea8134af97ad4feace50aa194140000000000000000000000000000000002606deb5d57dce5b3d2e5f7ccec3ad036992beae238673641ad6042479ec3cf83bcc0fd03b7dacb9b4bb6c181ea9cc8c193fe87634fb0bdaa1700466881b557c470a62464e8521be311a95dff65eca6000000000000000000000000000000001203ef36896bfad2a2841689a964328fe4ce3d83798671630d0c8876e67ceda03d99555aac46d984f1d3bc38ffc134c50000000000000000000000000000000013e7461c256c8ff9144b17f8cc2e270aa94b64be62588280baca2ae6b6efc4d32b3800eb84da62561e0e96d5f0387a3f0000000000000000000000000000000009454b6a810647350cf0b364eb1c2b719670af45bdba9d7d1a534e23d4e810c3ef4d9318532e46fd104a83bb10159a30000000000000000000000000000000001034546c4288f642daeccf5b56beed2ca2d946bb4391d056df9c6fd6771048903fa330ec16d59d05540cd715333c4bc73dd9c99a5aea019436e3c91030d03ebefbf6ea6ac69222f1870fadae32f55ae6000000000000000000000000000000000d7782404dc6721f52648fc6969db33a9aa209f8baf5faa9678437c76c9e1635fa6d22d94aedefc90112223bb81ce33f0000000000000000000000000000000001e442e548d3045d1589817d0b57dfcd66fc64ff978186f784bd576faf57607170d49364a72189328c9837c9a2d8b0a0000000000000000000000000000000000da2b207bb7720aeca2e6ea02b65076770b960d4b7a96ed941a7f409757b952031a472384298acc3948bdc485088501c00000000000000000000000000000000048f85bc05ed78c692138f27c3541ced11b6b0ec158b43d133c3450a905416682fbb8c83dea06a06d294c48289ddb829e74ab390c3f73c62eb1435226e9b4f9b921ea1918a61a614b9bdbe9eebd1cd790000000000000000000000000000000017134f787c920bc15cf2228a186dfa1d10194087f28b6dd8f03e1c86226928f0eb1c27020a5cc74d94b50c4b4e36b8020000000000000000000000000000000012fa1fdcbaa81c4cc1e37447cae51beb29e55bb19b91e2b575afa3754589ee0151cd9e83573edaaefd341f381d34f4f8000000000000000000000000000000000ecafd00cc87a773a13909512466ed11288c842716e1ca5c37a4d9a4cd7585136c86f32140fdf02e2997a6e19e3d76a200000000000000000000000000000000104cf007ea863dbd473d7dbab6f55e74062b18986e9bc09bcfdc9c23e4bff8683f73aa998a5cce59ded10499d18a0ecc4dee3e2bfae3820f611c30df232c1d9c6bf58d40b3530858c79f840720d78d72000000000000000000000000000000000ffffc98e55f4ba9a642c40678d625690464bea39d085dbc9c99b4c36ea8bff5154eae3c315e1dec29aa669840accf290000000000000000000000000000000000a3df9595167048c52b8170596d4127968194aef7fbaea4594a27c6af05c54bb772928a7749d74311038d1c115e91b2000000000000000000000000000000000b317a3abd808e94a7197e0d3b2515a147774f78d0cd7d36e1156da28a26e33bfa76d75c6e3ae346f9ace050c9911cc6000000000000000000000000000000000fb5fbcc2f74fc30ae7e32143f219db7dfe5db6ecb09cedad8f087b6df56bf9693c8b7d78aace064e7c31785f6869541795fc8e20dd30622876a94afce1c1a76e3b689d6848903c21103cfce6a8a95680000000000000000000000000000000011e4b907a72f34af899a6c4de211af5fbe0265e5bf24d406798de53ecea273d5df4f4953d13fd7c9dc3bb0f0c143e3e4000000000000000000000000000000001623de5e87b6e1ee920e1b7d979fb9c431c12abb47b93876f9ddfaf28a7b673c18be634f96b813f7e0574c55b628a8790000000000000000000000000000000018ba994b02dad759ee79301b42ea20d7545844c0ea4bff2f95dc9420194cc4196fff12cc09bc0cef03cb7ba868c273700000000000000000000000000000000004b3527c8d148bd9e6006bd298ff8d7fe320748dd3f6d23449e874fc0c2f58d933c1e038a74f60fb6032cce41a3dbf5725b49f325e76733eb3c1a2cee5467157b2ee80987abae43d2c4b93e5157f083800000000000000000000000000000000129641af11fa92056236ef135843b2189d46d870381261d5781a5fd6f2c5cc1861ebb2e801f19f3adf2216609a9e196f0000000000000000000000000000000007b4007c55e47f6bf3aa420ad75fd191ffe0fe824fd30c3f1961a8168922476fdb3869822704999b044feead470e3b8f00000000000000000000000000000000174209113e2d8c363b04f49487176dc6d9eb4ecc0b22daa7ecaa5548d038b3b7c23ebda4f1b6845425cee13493385302000000000000000000000000000000000a58c80a02b7f93db01d2f8e0005839625e6c4f121f3d69115f435526a7f7cb53177caab4db86273bc2d2f0474235f31df49b30dd6aff459f64906eb1a9c9b2067d4f1b75057874b2fee17923bcb906e000000000000000000000000000000001738a03b46a8ca3f3d1f4f4447497c59f114005400f06813b24ff462ebc6f27c1c3c788b5f83f65958cadb34fddd08f40000000000000000000000000000000004dcfff2bc9ca0282016f38df484655cce7b872b1ff047351ae6b903e05f457d7fefae93104f9dfb549980394dfad2760000000000000000000000000000000017cd89434225dba07be137a73892faf0258b3fb19e6c8cec412fcda912c0613f2a925ad50ae485187020a371ff2dbc59000000000000000000000000000000000f1f9f87d3401e7b3b59331a89d9535adc973f869b81bfd8892a37117d8597ebab2800c966e623469792f4ae2a8eb232959e0a33b1fa12e0ba960761b09921b81746b8df23e808a8de09e7f5cbe2bf41000000000000000000000000000000000bdcb1d2a782541ff7884dde4167ba060fbd4b117944ae69aa2ff685b9bd7d475f45adce0c9f92695b4f4ecdd48cb9b50000000000000000000000000000000012a55432678043888bb9e7e47efb17700b3e702e389d0f58dd454224a02da3f190b2fef4c9d3e2074c7bef813fb56fb0000000000000000000000000000000000efa51ba64f1e7a1a269dc083179a222afac916778a967098582f55a41394bff3747f8d024261959f6d399f44a40d0fe000000000000000000000000000000000845dd0974c5789a85c3cb09ea441f2c433f0606928ee1b177eb851530d6e6b620b4fdcaffb8f75623435dff99b3ad9526ca68383528f6a871c237ae5214b49c18c4f3e2f3ef5dfba39e69eb181143d700000000000000000000000000000000180beba92bdb95c7803fca0407e29929ee64e03d61cad96ea0e6c469c5a888cc5ca5eb20983b3418a8da6596a5f1b2ba000000000000000000000000000000001322f7356eb3069fe20063f4be22c44426162dc8fc117e4e382bc4e33bdf3d971ef662fffc1d58ce187c33a43a4c853e000000000000000000000000000000001601a0aadaba846f11ba5c9f48e13bda1007ffdc1b8bbc9e85e83e569e9ee17a1e9e780a50ce617e6c780b8155675f2100000000000000000000000000000000105b2c213aa43ead42d9cfdf1d6c0559c25b4b86af43d4493bd75b76986d0d4f1d9b3bf9e3922b5c08a37a1629cab7d8f1f95a9d1d4e8e7d0f17a954177253709d988c3a77c77d35b8bf70294bb358c20000000000000000000000000000000017bc70346765b7160a0a5e556805c7944304acbecde06cadba474c51f05f22445c3d943674cc8215f973cdf11b9ea2e9000000000000000000000000000000000bfdbe202619a1d95359941c249b25462d3ecf09fabb878943a8a37cb9eb94abd7e6399f8d82f90ffcf904f4466cc5b1000000000000000000000000000000000f048db8530a288fef10a5ef9bb3cdd9f3d3b0ef4824609efad96bdf52d7c3b10ef628fa04f8b6513485e55f653f4b990000000000000000000000000000000004ec35f59287eadb1738bb50b0e2ad9d280bedfdb0a201e72594bfc4322ade0b7ffd6b532ebc7796cfc71f88a194bef4b481f986998d863c98e55a7661136a8f19d7d4c57f6036cd642ae16c82cdcfb30000000000000000000000000000000014424c77af7ace8ebf66f556cf219919712d96d24438466ad620221ce1ae9b2cd75b9c526e25df7fbf3c9250583757f500000000000000000000000000000000198aa00723781714152b3494b76ea3ee043b363b3fa81806cdf7e440b4cea907f226a3c038fb95c932710dc9aad4c9dd000000000000000000000000000000001360e4c775f6fa5e987231dce25ec67f61429ca9fd8160c3074383c30a8c0d7ff068b1d1215b2c0cc87129d9c9aecbc9000000000000000000000000000000001280ee6160800c4b0f82d5c2775238b4b223d8a0ac9a8f8013f138d554ba31c9fedb30e0eb5c330da17f5785b2717422ad872848d72367467094675a819f9aa6107183aa0c8685d5d84c27b3aaab33c1000000000000000000000000000000000f1f84251204d9f9328f79a45d15b311984df0715579633a82b5a9f680f6645cbe748b0fa64b9ce1e696e20a5645d6d300000000000000000000000000000000156901506e502a09917f76d825614824dfbc34d019ed53c2ec5395b51512da512b27541bc53331444eac2f618ffd5357000000000000000000000000000000000ea8736a97a33112bea9d07b729e973e3a942422f1d2b24c30e96637b535ccfc10cb5930bb59ed90bef604453df8772100000000000000000000000000000000187378477f60e3eaa225e89d8532bd95babd4a5c51729cca800d364b61575704992639dc5035138664e8e074ed0820033c2c60541fe17fa8e71d58184a055fa8b1dd0bfd16ac2baa912b4472c6056122000000000000000000000000000000000e5281c1c9210269a7f5ccd02cd5a7d3648b56d9ca6a4ee50beadf151c2601e0291fe7f1b89b694500e6c636d4e445c4000000000000000000000000000000000d5d5399f49697e46013558dfff544383b25f3b60681ba5fa2c5e6edfd3924267d0992abe65cbd5109ba8a1c6eadc7e30000000000000000000000000000000012a2104aa92871dd8e41ae1ae6dc18ceb7d0f361a5a4fc67936454b8866b8aec1602dd596459cccf6d9e1319ec3299d4000000000000000000000000000000000268795f6f9892f5b476c3a534673538647300203a51a8ff60b530094608b5fdf16297f02ab7ba41d6fe556885f064a4ff07c19ad4f10ab47e73b6698f9febf3f28087614759e082e6e717588c1caff7000000000000000000000000000000000a5585961328c52e0fefff16e66e3367e34339dac1a20cbc5e89b78804b8bc265e6e3fec1da6a62cd8a46be2f08a6d960000000000000000000000000000000016fbbd698784beec5a636332c0b20fdcb68fd3015cc6d18b541346a5e6af76613e6fcb14c888a2b8133c0f4132fc079300000000000000000000000000000000041805e0adf2a32153b89d1131226cf0ebd77cde3116a168e792ae8b88ba2edcb1fe7275658a384251b805d282ee039c00000000000000000000000000000000024213e4a8504cbae4875617b9b78473e7842ff72415ceacfaaf2e8b415f9f7e411989bada8101be72f9295dfbddfa3f240c881fdbfc414d3e85ead1cdf166ed6929d0b2ccbc35f0811473757b6b41af", "Expected": "0000000000000000000000000000000003c4f051d528166f256d9356aa9cb885db5680c51990d9474a948848888fb82a9b86daa7a2273725ac8ec564ebbf15db00000000000000000000000000000000010a6c4c7067f511ca8f1b66bf9ffcbb275c7575540909262f7c4332c3d75b2f6d2f3ad2848c0d455410afb1cd60c835000000000000000000000000000000000ee5e582554b3930c5670d4e3542bf32e8b871849d7859eafc077bb2b533e936d462f614057f9fc09c4010afab501c1f0000000000000000000000000000000017fdbcaa065d301adb94a60dd20dbae71512d369fc82c556ea0dff66843be768be942e060752591c6eb0718985d8e313", "Name": "matter_g2_multiexp_92", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001353960aff58d45691c5378a0676a8e837260f5819cbbac9cd75c8cc4c6f1e17b9dc9843eabc0b1dfb27ff7631e4e52d000000000000000000000000000000000d6279a43d3526c035e88b0b640b04d42ea573ed07323aaac1d9d5570a8be64782682892415ba2be5cbb13f56e3a44db000000000000000000000000000000001250fd14fd003f88eb6e0e80e9f2ebe204475fc6c06cd10fa45608a17b7039afe0326474ff80c357f86c2825cdf7a16d00000000000000000000000000000000186cd91cfc8ae625e302946f2b393ea67e1107c0bfe938f5f36d28879fa0c0780c847aac77d0310d43211152c1d5f5d314d5455ff1717bdd545f4daa37e145121e7bd9636d7a2b65633e5ca5a63f2d98000000000000000000000000000000000e55a98e8b1e59600e86cabb5e8db8ee622009b1618ff0df3e93fb55b80985bf2a8ed060aeaba53773274d4186934f75000000000000000000000000000000000bb7215fc43f465f51fc8265477fc8c79493966f040e02f0eacc4ebcb3414b84fd94ded822bd24dd5ad5720f12bb8313000000000000000000000000000000000b23328e15cda8a576ea352b5dd7ce382ec781deca6c23f646e42f0cf63e28669539579ea51e3c0afebbb58e1e8e3243000000000000000000000000000000001716019236169bdb4af7bf7d7ce0aeee7900b74023acbb16f6965c2abcf28917bf88d0f9d5bc26a81710496f7821fd4682cd8da62bd901355a60b37ca14ce65d427bcf9551203cae7c346a49b4fa8626000000000000000000000000000000001718a4d6f5e78524d8df23d2c589abf04e3567d2176539a30b9f73c6251de573caa60c2881f3da99c48d48e9aacd7402000000000000000000000000000000000ce0e35721379077e6eb3b572f7f7718bbf775b116521c14acbd3ff19549c75d50bf70ce84326cbc3f9e5e53605d8ecd0000000000000000000000000000000007cb3305ef0d2cd7de4dceaf25d2eff44d4f437e065f6b244bf1b0611c891626eafc4b759d55b45d76e94b85852df1de0000000000000000000000000000000011cb56d2ed32a46bd951836f8e0f92d3824a4cddf011eecf1e2d92d81bff407a04abdfcffd60ccecda6e9443b328d51eea2c7fc2050e9c1ebd05d15f197b4b1be61c6820c8d27ade57d85109d7f982490000000000000000000000000000000011ba705da23100f853882dd166d81ee1d7621550d156b14f7c2123e2681887ec3724626061db68b2c63987325b27d6230000000000000000000000000000000014271414fe078a80587269398afd127ce34c8dc2a4851f76613b81dc99d766d75c703949c1093b04d66a301a79d89bc30000000000000000000000000000000011b7935ff284b0f812b5da5b28ed338dc4c21ebbc7fee04db834732b11fd76092db0e8d80368255b0f1205129081e9af00000000000000000000000000000000104ff0ad2e3db08d3b4890b2e54f29e456e627cefc3a4f07c1109b764dae4142480e3e5312ada43fec9ba96ce587e8a4e3bf7e661d54796c71437354d7d3182770f10ab450827512a423d3dc82d5b43d000000000000000000000000000000000c60749ef36d63960022f3127d0ab4e12acf05ba1e1a136dec89be388b9d7144c1d78c04df658727763dbaa9725bd8b90000000000000000000000000000000019932b1c205a765bc9de0cc136999deb153222a9dd9e9ec3660fb6daef56242d08791d440888e69ca0da2bbe0fcb7d79000000000000000000000000000000001764790d12f5ff79ee4f2c9fadd5dfb1cf47db70b9e86018bbdbffd1be18df193c7dfa71533afa381053a77e02719c6400000000000000000000000000000000044b2b0211cbb407281ab2abc4725c2cd791b313bab8779954a2461ce445cdae60d4a9efad9f90f80e66b1438514e0f0d3a364e7b217dfd649d1e08f76393372d8768bb0fc85c79ef4652417ef1637fc00000000000000000000000000000000175cf9e7eead650e7ae4fd657bc288b6b6392773bf1bbea48e17172a5019637fbb2bc0a3d0d1e3b8054564935c908db200000000000000000000000000000000136da2a625cf72403d0861b9cd947cdad12b1f1e6cdefc4aab6756536425285a7953a1b892df40ec12ac3430fec889cd000000000000000000000000000000000c2d10c6d71cff4e1deba1984bfd17166571e64659ac91b64c343cdf587c29d52a2266c00a57c01feddb1df6439d21d1000000000000000000000000000000000384a782fb31278f49c840bb8f0552ac2734ef36bb3d115be7df20333aa747c92db990f7e879399235d122fdba0eed76eef7b05d5c725ed31269ae9c56dc7ae35048af39ab114319680d4af69be7e7c3000000000000000000000000000000000a9a821cc63e7c9857b0f39f7444a1e00a422f7cd5d0575c26bc5c6b98313abfde51e3f6d5f4c817193bdf391344e5ba0000000000000000000000000000000010daa8c7194a75cea757b6ae4eee85006eda459ff2cf155b1b5f19c3ad341972f72e28b781c4878e8919c7e5abe9a1d5000000000000000000000000000000001154d5d5764aa2b8818a9dc5dce30ba2197a86d0bdc7dee3e600462e295cc3a69dfbf8db34acf138e7a1f16b62a45717000000000000000000000000000000000b4243a09b05a958d78ba8ae25fd3fa85d520b95e56f1dff44e556b221a075f8dd3370313886d9dbfc56a75697454d72acecaee3dd4dc11e341b3dd0073842d90f641d4dd467a6596f337a6147bd30a9000000000000000000000000000000001820f953fd22b71ce00bbe9e9b78fcf5fb28bcb925f6b5dbf5711e00470ed7fd2f38d7291d40514ab4258807f29150270000000000000000000000000000000007b737b56a2ba33f76bcf66c0b26fb44d5f79879273f6ab21ecbfe6a5744da289464ca2b46c55edaadfe3210b907f3f7000000000000000000000000000000001735d1b39c5369bbf886c5063a96dd12b85e56fd9d8ff9d84520918e1dfeccb62bbbe1c2ab440ccecd0fe66f6ec55853000000000000000000000000000000000e591b7709bf00bb2a87e9edb95720de19adc41a42378cf9ebb930c6d3f5993a1d7b6320040d5c69908685d978be8f980cba585b847bec40515a257cb839c7e5d677d17b7313c258e83d630e65cfb5d2000000000000000000000000000000001732ac410b2a7d10110bbf7709dc6fdc91ce742f8cb9b2c3ba37ba5f0934f8622c675753a26d04a176e24a630d090d81000000000000000000000000000000001111a52da6aca10cf40127fa8ab7683505305e0d474eed28a5e1735ee6877aa00c1bd598420876f2154b814660f3fe7600000000000000000000000000000000098c6d19c2ff42c2c57a4924693325de1a91135e3474ec699b70439d034469e72e844a5511e23dff3948a66cc2a2165300000000000000000000000000000000175fb79e5e54963cdbb133f38dccea2d1abc3cdf005c17e8f2de6dba9b9dbdeff7719983aa9ddb602f0cf966fdd430e0b8cd305c650d2e1cfa91ef0aca9dd0d785d7570d6fb67e61fb9b6817116a05440000000000000000000000000000000004e88468d35d72dba6b3e4b9ca216b75b5d20c447064a48bee6a6ddf994b1e22fd6ee8abd60c627622daffcda219645a0000000000000000000000000000000015eb2ae16e3310b4c4ff557f0615519c13f29109d9863418fdfbe6309b5bac4463456df8ebb0b6d9022e294cc16265ea000000000000000000000000000000001288ffe0ffdb96708558d914bc412758770d048c4d50523e2b134f8468d11a57da97e42bea303ab7137e2d26c0b3b8f30000000000000000000000000000000003ce563b63c50b09a80b71a1a82995238a9de31aaf189c6d29307924b6f0990854507b7dc1644f689c5abcf931dd5a3c825e5f9d81273f306a065fd064ae24bc2c5ce8dbff6b22128753663a218da8a30000000000000000000000000000000009e39ce653485caf699ae1d1d9cf2b8c5ea85b80ea042279e57f0beb81056159e49f73d67e7b1f9ece9f9ece7dcd2cf50000000000000000000000000000000008d6492cc335660c54e4a34b29b337b5800f1ef992d124524c799c04c852ccd3cfc01bf39515cb8b96151753147e8c49000000000000000000000000000000000ca779d87aaa3a6552f9f1a10b0d2e635be90022326db04e6072f326b919ee55d4124b9268f55751dc0f18172bd327ae00000000000000000000000000000000112eea543d6609d0acfaeb7be98be609f03304f50c3814ee8a010283146e6b5dbf170c7314598cac06efb9ced1ac2930307ff9660ad0c24cbb139486638a2556687f88fb93a290a1d174bf87d780b3fd0000000000000000000000000000000006624dd7f6eb043da41a36a15752f370eeb3cb2e6bd88b337b370fe0660c5ba8fe64f62e112f91d2524e9324f3a049fb000000000000000000000000000000000415b964484c9246385cf95461ab955ed0390e20209ed405d84fa8c8af9fa7ab39ce89049691a63c61b12bbf6aa2a4e80000000000000000000000000000000014411d7b2db7c9ee78ea14c6a315df3d90827b511db2e2423d660176384d8f8afd284879b22f5aeed73afb2eca4be52200000000000000000000000000000000105bfb471340e76f28901edbdbfe2ba246a8824b501ae2d4a73cffd2690181347c1e6530804614e88e2bb13a8edef8f4bfa8ee3b44c70ba2512c00a1aaecede2180b08ac3ac8c550d70407f0c12e027d0000000000000000000000000000000002b17f4b0b0231be229d87f075998435560ce9046a8b0e8f15e3a9f07cd52f3316f6d8c00d6a872362e7066715cf990e0000000000000000000000000000000003110eb232154f8a06834e2ddd33c0207ea552f439a6127b652bc261158209a00654e50341d333cd1b206a915fe0691d0000000000000000000000000000000007940e209c8934c185e4392f12fc0afe3d234dd1ef3f92df18d76be8fc42bdcdd6d1ea8d5bb6f07b3f3caecbeb5ef27f00000000000000000000000000000000012ec903a8442f68c03300ab02ddd08ec935d97bec9050d26a5e276584592df3ab87d596f90768d2c0918099b28963be58aa85b50e5f4ffe375599cbb912f41d35acbb85a324880148f9b9003c4265bd0000000000000000000000000000000010fdc16bff0fea02b325c672fe06297e0669094e2710d0baf3838f3e234c3f776bb3fd41b967c9ebbc72a6bc6eca70850000000000000000000000000000000009d64ce322e39d5b2d0872760a61a831877c450b1cfac6cacec52d4070b0f179dce90afbdefdaa8466f6a6e2e83ee8da000000000000000000000000000000000cddca46f3b24e05b76e61b4584bc716ca7036afdd914731a61347e453a26d07549e9808e553ee056bd47e53c75eac8f000000000000000000000000000000000451cccaebe1a188d3eaadd40090ca594f071c8b6d0e0d82f5b2d43fa784f8437e4226104c4cfdb24ece1ed75375aa616810c6cd59b14ef4f6a4c2702cc53c65b3dc84988372c1195980417c583fd7ff0000000000000000000000000000000005832ad778dca8dfcfbe741dcf311024d76341d5920b6830cb75893a112c9d86719583d1dfa7287281fb73fe21650c3500000000000000000000000000000000044feb86b4816e45ffb98e9a670fcb039fd9d8844a2c7ff9b7752f20e619195fe6ab1148f30afa393936d3605fa4c8da0000000000000000000000000000000018db9365370a8c703364ba6d9c48b3512da46cc603a43c3fb91c0a8ee59777d7cf9ac646c3e4274bd950d7de92ebce840000000000000000000000000000000017bd82310e251701cafbf8c4dc5b9e6c88085b0df287b6dde7887e1f64f2d9487a25b31abe07aec7d99a75baa5983195c5ebc09190ba3df49d8ea55cfd18370b9d443f9d9084cf84f2236ef4723d2d470000000000000000000000000000000002c1df194f01dcb503dcc8a283f059b82d141274c8f37cdb6441aa33f84f16dd288d566752a93ca23d26ef5834c0658c000000000000000000000000000000001700fa4459dd4e609453284f4f7dab479342675a87c1cb42b601908296557f39256f1597ed3b9ec38ad0a40a2c728f0d00000000000000000000000000000000135ed4f475eb99397cf204f971215a0303316a3ed8b62b303b4bf756ff753410b7fe263c4e97fd4c4b399c319ff3ad98000000000000000000000000000000000a487e179bf1b73627af9d7d2b43bc0e43127a8fbfeaea7ce958ddd53ecb27741eda187745e3917f1cbb60adf0286f5413a56b176fc835b7e825c817d432b9ec6d51b0a66483dfbf12166ee979b664cc", "Expected": "000000000000000000000000000000001327c57e16f03fbf652bbacd16cf574113860eb87b8f2f6e498dc5dcc4f2fa63859d922d88ccd6683d503d0962db5336000000000000000000000000000000000cb06948c539cbf686f6936b6a1ebef2e148d98c531da36272e0334afca5c2b16a52da542a0fdbc3bf764eb877f5778a0000000000000000000000000000000003acddfb5bc4fd5579d3f592977365840be4d3cff96434e5ff4f01ea798e4401930a1f5d91f8de3ff98504dce398c2ef000000000000000000000000000000000a5a332805f704613eb085d6639f99667d0d9247cae34eabcfa399eed551f24c5d5cb05d6458530ae270b1be682e71f4", "Name": "matter_g2_multiexp_93", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b1b06a76e5bdcb6c1c2f1952b49e1820a9d8557229fbff8740269a0b819b91cfd0de20db0afd76a2cb0fbc5fac12ec5000000000000000000000000000000000347654df2084082efd32cba2b270f66b0ed30fa8713b27949fc9d270ee8eaa9b9a7896d7a52dfd8faa3e0cd112a24e0000000000000000000000000000000000bf5b7a2c0c8bc223ab334bd1df5d9fd4bc0c635379ed2b32da13f6178e07217bb88a4bc2eae0b975f2e566f657d23aa0000000000000000000000000000000017042f8585a07304995853270b1b03bb08484104f7498a12bc865f2a0e37e662fc4b0331b94ee5690efe74056567000bdedf65658ec3cca48fd48e844337159af090c5d1f5e9d713ac6d0fe1e1f193d2000000000000000000000000000000000fcbc73d0628537eae417f8efc67af0a4c9c375d82406086bdff669911fe1307576333c389f189f49677cbbfe2ee98730000000000000000000000000000000019d552b85b1445660ca49518d202afdc67b0eb5be02c8d3482dc1b12e5d40a4ff95a49ce47809e4d6644d04aeb67b3c2000000000000000000000000000000000ed536c0f19f592180291bbce59a72ce5e516199dcbd4fbba736cae2edbe3cfb860ead0325dcc8f8d9be1ac126dc6cda000000000000000000000000000000000f5d4f0c0ae3e76b1c41edbbebcf1ff17c7cefd41e7ef8f75dfc10170834d05820149d5f721a8c6460cd0181571fca97db65ad6bcd6f485eefebda0badfc64e9e7dfe7e911f3ccf4f4fb9528dfebdae6000000000000000000000000000000000d6207f6684f8d2f083c963551bbf0a674ba40e691a34ebe6164ff80ba9bab2cc23024a896d7b906fb74c95016a9adfb00000000000000000000000000000000145855e7d610b50cde39db8995b127145d68fc9bea3f075f65b7793acbb14bbb313a1a39bd96fbea6641baae02612b000000000000000000000000000000000005b533ee83cf72f0e4d9c9ddcc6b91f4364e50a106becf766987c490d559d0f733839ecc706bbc9c2c75b243814068a3000000000000000000000000000000000cd8fba13b9ba7557c7577da183bf50810fb14eec7380e3b3d4f2fed62bb36f2b5ff288736bed0578fb6f47fb6d22ac86e0fa09884a7ff4c801ea0722cf6bfa58a46fc3d36058e8c395ea8fe56d9fca4000000000000000000000000000000000fd6a466f2eb12f6337ae9f9b847ac1481820013142af1a474229c5f5f5e1c0bb2d9678c19c7a3a1aa22cfc7b5052e0e0000000000000000000000000000000002a0340f5a0caf5c66719f7d546972bb4b89147989280542787d281901ff036b7c69d41418c21c43127c0158593aa5cb000000000000000000000000000000000deeee37ef96f26a4907e1a8a8f3f030dc09102799bd0c6dbeb1d208a0c86a423d0da6313e0be03c026da5614a6a576b0000000000000000000000000000000007220475449add59b3cc6570701528dcbdedacb9a3d39674ad4aef4d94114f24d2bff32f40b25af97ba883905ea6838a27a3377d7b9ff3aee2ce1194a22d7115b09a9fd53fcfa5e7f76bd9fdd35559610000000000000000000000000000000009d7023ebb73df81455f74cb2708c14ccecacd49521a0cf67ecb6edc8756e286ede59eed54d89eee5f77f178ea8fdee900000000000000000000000000000000002ad48fc3192634e7b01604678473e286afb0efe67a4377bb885d38b59ea00202241fb28c93232ce7c9a3dabb136a53000000000000000000000000000000001934664f2bfffb254f0415d6769f4e2ac710ee88cd822bf5da5df3a2541f887e4155dbb7e8056efb2a0370d6f9173e3b0000000000000000000000000000000019df518e1ebafe95adf683279729a3298fc8d7eb39c9a3dfe4b6665153f970e243e50dfb16fb87b3be54192f69766659446a62ef5760c995cb3cd0984d607c232c1eb0df5516a501ce448a189a3134d8000000000000000000000000000000001870048d360f397877321904563d35bfd0817ce464e0078e9605a4744e2723f49f9cb21dd3d6f37f1f9aff5a6a99bc530000000000000000000000000000000000e29dd0da13ac451d013d4a38408827cb0e739772e1f250d31e4192ddc13d651ab576ed6b8f4ee44e928fa663244999000000000000000000000000000000001646183099579322e0115ab0b3bd6c814e216ae6b2b80206354925565b7bcd97bc12668b7f3530a95409456ac99bf01200000000000000000000000000000000092f6f594ad0d92c9c64f78c819c44320e6bb5dc1dc8fbe58acc7ce3c101e49a74ae6d50b1a668a3b7436dc445e3da345f0c1a7c2dd281f7d2f006497f99f65d6a1e22f1d9aacb08724b3576aa19e19f0000000000000000000000000000000000428ff447de18dcc11b2c5c679bc2efd125464f589013c6964ea6cab33d9b7cbcce3a5d6177bf43114ee256f23fefa10000000000000000000000000000000000d1ded695e88dae6dfa702375959831f4bda688fc0faa289dcfb90a07f3a7963f2c9070958561909a2051a852cc15e1000000000000000000000000000000000c39bf1d11fc5693167890246c81133faee93a8639f459429757965e0b62e372153ce53c61f2c539247dbe7747b27d1c000000000000000000000000000000000e84ecb6dd9cbd4133c22350f07a976ae13dcbe4c6ae09ccb023f2118fa2dec68c20ba2266f9b571bbe30dde97480e0a94c1476ae0a62c502aa096a371e30ca885dc13fc417e3dc9bc00bcdf516764100000000000000000000000000000000015e040fc8753f06ed1112cc06e2cb7142a4fc984834f01faae718c17cde782d5953547857ca9aeee1c4a7d91df060d330000000000000000000000000000000006789ac15d719a7159b650b757f7d3cf58fca02d3b8f3685478ad5e5b1dca0508dea7a8203ece97c7c6d32b2f194458d000000000000000000000000000000001824d75634043cac3fd17ff0bb141daf7010f70b5941d8f75f1ae076713afaa7e0a0a25fc71038baf1b1255d64c914c6000000000000000000000000000000000a2f71bf85af6392a8a070596e30225bec9e3dc12c70e8df7c545bd6bbcee56799db2c9a8d2504c4f90ecf6a5e18abc9b677bc9f1f7572f808e969aa50efc519192ab8653c71090e5cf8cdeb1a3544dd0000000000000000000000000000000008bd859ff1f22d682f86e1a0e3bdf3a332ae78d64814720687a3de44c9bdd7506d2696b4daf81a94d33f64983967fdc2000000000000000000000000000000000d7b4b958e0087f8edf18a4370ff98700764c126808d5c52afd3e71ee326c766c1e5712dfa351cf5b3c518e52133ce780000000000000000000000000000000013a145331bdd9c93e63edbabb9f6c541a7c4dccb1705f07eb353a0407074a76022a8e5f5f2535b41ecf6474649e257bf000000000000000000000000000000000a12e461b7439bff0dddb560dba21ec53ce88f71fd3dc10723f3d8742ed63a1ab725f7e9619ca1ccb729564dfbdb1be7f5ca580a25a5c87015f57f7c23cc51a0beb5926c84d44659e45512da51aa0cf4000000000000000000000000000000001430a8184c5055008a06ea22ca9c997d1a24ddce7e374937c32ed1e487c80537b238a589b5e50b86fa194666bd3410e80000000000000000000000000000000005c78c94f457bdda242deab79524bd2beac82bb1cb427dcb2872b56d1f46d11fc9d69ba132004958fabc5da7d6d103fc000000000000000000000000000000000e985e8ca038b5dadc9fcaf22699e75cad9d2effa47fe7d4c579ee056b1e34ccc540372111a665041062fc6c39e05d170000000000000000000000000000000018c865243534fbde740de0ffbdeab0d38ee878c20f5d84c0226d1f2b14ed3359f5b5b909808b6b3789bfcab3be75c4cdfa1cc45c35e266a82899d8ea0c9c1f96f96140eace41a8758a87975b088f0231000000000000000000000000000000000c5b10541ec34dc0a8b8e42d9d6fd6f4f71e1fe56b5afa323f4ade35c0170b5e224a66771326d9edbddf2bd38c6c68ce0000000000000000000000000000000019cf33c19936f7489a1bbc095d0f5c6ddc1f43bccf7e8d1b30fb8e8cd1ef747b483b9a8e9faf21cba7cb17fbee887ad70000000000000000000000000000000010e83916faa7bc9de9feb8a7f34ac6f2aced06a771b662cbce846107245edb9c07632782300e838957788a8d88c8253c00000000000000000000000000000000066127bed5ac9f2871500fdd68a03ade57c35449d4b4186b9fac7c89e91b4ebf2f2a02e94d0b578aaf60b32017f147a493d2908aa9266844eb265c2b1c17f8357a5ff039836ba83c837909f6a9d0bc03000000000000000000000000000000000cb5a734a28b44f04d39ffae049fe8b63b138411661ca6dba00c72cadd47b50ad4b71e858e817561682d6ca378ebbe870000000000000000000000000000000000baf4d689baa09aaf763ae7e142b801223c8ff58f2b541ee4c44ab2460fb8f6dfc1e9f61a8d73aeb92d7d08c281cf410000000000000000000000000000000008a0c736f19bd0005c9d25f88565b1355e53fa3403021577de536712ec986567184f4dd626127ee80dd03cdf9044b2ba00000000000000000000000000000000063ffb7a3b4e057a9ffe233296c11fb462136fc4b187be6f9e36f9e6d335a3d673ef8b9ae6f60c146a075a1789f389cf3b94325aad8a2c80971a781bf6f6bebad63ee37405ab7e903fb7094beef14d06000000000000000000000000000000000c33d89595d039722222b9b9ee7ff1a0dae896a8de97f202d3aca00bd81d0169f14676efc4b051bbd339dce862d8b60b000000000000000000000000000000001109a24dc6f70bea47e040b24df395bf561cf5f1ee79e90c9b0480fff0795677483a85e6f2e9ded4f36ca849ff39d6f60000000000000000000000000000000009c7878f3a4e4e3149b72149a7da91bf527c4d7c94b15ba80b02e0e50b02a2c482ecae9f458a881c87e669986514f6d70000000000000000000000000000000004284448e42187c128578b801f76d421fc508cfee9360a7203a91d6f9cc7ccb6ed3211fc5df9e15f14aea98bc298b2f95143a8e734824840346078aec03d6760564870c5ee2b2dc13f8a39ac452be9f5000000000000000000000000000000000271ec1a3f8e3364ba8e101b49c0bb17e2b7c7f27a4aa4d4db5c07203195050f30c1a05d33c524a84b1a2f0ce31a587200000000000000000000000000000000082ce9d1da5d7f192c537b2bd617b36b65f88b308fe1ff85e47c64b62dc62324458493d1cd1da9f5fe308d27545fb6510000000000000000000000000000000000b30356b59eb04258096d0c3f357fb04471583cfe6a060de5279bf2cff4413678c1716ba87d0b6de6b6e79a96ec26030000000000000000000000000000000003c02470a14211fef14d754f6f71efb33a06a76e099093a5b9512f907ff819e1e0e15f14995febe48852007bb5c380bd0dbee37fea759c2a58cf360c654f85298e8ff44b3f900e8229c3f838345d053b00000000000000000000000000000000172df3290c3c5044d590eea59980d02e02d4fc6fe7948168492362de8f0a85df0c3d09d8cd8b206cc4d1608311ef4c130000000000000000000000000000000010e4d14065315a0d9e48204e47955ee9652b08318251a7836f32e6fc015d4856444172de44b3b88efa1b54dad346e9b1000000000000000000000000000000001549b9c85cb2fc2c7495d7ef6aa1452e58937baf58717037069e6bc6d72ced3a163f800991cd26510e71aa64c44f66170000000000000000000000000000000007814c2f1734fcc8cbf9fcba06b936c86d0452a2370f8c9480b97105e42f9babfe0869cecda7e15500e9d8d868290201b92f9db82d0976f4c379622c4028002ede2ab17f647bca3bbfb159045cdb342b0000000000000000000000000000000014f849e9749a5ff6b7b10daac7f5934be5f783d49c8593367c4243664e01b1d3552e878802d7dfee823e0122e9fd46f90000000000000000000000000000000000d0b32d7904dbf08269ca3c6ae3fe582501f55e32337ae361fe4a58dada560db54205e56a399aed33bce8758a05ebcb000000000000000000000000000000000cb21440baba44c3cc6943c8cfa2fe544a652f06423d3de06c2ff734ebbb544da07ba8982b3009b6c4857b73ceca570100000000000000000000000000000000174ef591975fdaa0e3cb05bbb4140abcb38f685ce4de77c95e2cec1911985557b77d9229940b8c9157ccf9fb553e8e0d98df4ba50cd5cb5a02d5f50b3ba23e5f5b0172a46cc315a0a94fed05551a68af", "Expected": "0000000000000000000000000000000006da1222c7ae02843ff289931fcfcb315f621972f45e4fb4160b8bf48cd8102d50fb53d2c699afd36892d91f5e608784000000000000000000000000000000000523048c5de2d0139965c976d8c3328666e99c249104712719e992334442245e955cd6b14a1e3d666220617d78edcc630000000000000000000000000000000009f669d4e7d89fa8d999d8d5a6323da9445583344276bd6a29494a91174aeeb29132926a893d5a0eeee9c3048ebc0dd200000000000000000000000000000000099ee1c33d6f09a8d063393d2a8debeaba93027e31f7b23c5170b6747f56bd6e6494de966dc280dd67a38d39ae35a336", "Name": "matter_g2_multiexp_94", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b46cd281a09b85d977e88cb2251cc61cf13181522cf1c344b114783c4fa22d08f2d008faea3dfee8ea7c56aa35ee39a0000000000000000000000000000000012b530bd34f5b31161355436c7dc444d41d634b0ac3292c0096558618005fe82d189e4b208a48240dfdb4d50ad44dc620000000000000000000000000000000014d334e7835d4bcee2698ca4f643f9692f28d8090ebb8ed8f67c60639c64eb116067e5e8a6d04a0c88c765c608d57ef1000000000000000000000000000000000578cb4e243b4b20c99afefcdc0e0a9e308ab4bec6d655a8c4981a711515c807067472a6fca30060d776213b8ed98d74e49662df81f6bd455ee554704ff0c7d5a589d91e017d7ab4c500d36378c17c8900000000000000000000000000000000046ad1212696acdbb686543d284d7cf2e1e8e8c10af76c6ba51d55f060c006dbab25d3a789c71c428f5bdde9aafbf6d5000000000000000000000000000000000a6a880d52fed6a45bdc61d9ee78d8fe472e76ccbe155bddd0e2a967f4d116bb9f2dd4c62cc6f7224b835c8060213ecd000000000000000000000000000000000786544589eda15edc433edcbaa46d4953da72473f04169ea64dc114b99f0a58181d41dce1fcaf7f3109f66aef02e53900000000000000000000000000000000030759c3bdeafc94fc8fc0b03ddcd96869459bf54ace74582aa06c179323ef076aef89c09ce8e7bf9109ab2e8c8fb0be79eb26c79d78ab84c4d7e48e56889a601fda17901037a74fd79355e7536f3953000000000000000000000000000000000e6addfe0db96a7377fcab1fb92183fd7d7f13ec003fdfe0740bcc8cf03d8cc602d5d808b4bc874f34944a65b249997a0000000000000000000000000000000014a4337107e716113d8ba0fc7f75e85edd1c132e2b3dadb3f9cdec1440f261513646525314b5c0de6fd372472aafe877000000000000000000000000000000000d472ee0484ed831f8ddf7ad86faef5443df8b943c6fd4c3f94c8d52d9eed6fbb53107170a60f25be52219ca4816788f00000000000000000000000000000000035d06ffc452c65a31f80c3f8a0c1e2d15e32d993ec06c50499bc0fb8f669acd3d2182ba23d942489ea922baf61dd49cd2918ddc2bfb7f7cb3d7e74b43b9a972c5b51ac20ea83f41d5b51034b5714c0b000000000000000000000000000000000ef1f5f6b3041939557368d613279043d1aceaf5fee3ed90b3b756ad409d700fb41e62b3758c8c2d325db7a37f339c610000000000000000000000000000000004d66040a8e055399bacb6a1e762b698afbfabf789caeb957fb7a3dccb01d7dff5414e90f5a14961c4e980b298f834ec0000000000000000000000000000000006efe9e66078000c26d375e87ffaca643aae9cd3f8337f5718e0e268b74f4b7838f7661dc0ce60f557e162a21ff467160000000000000000000000000000000014ab782a3b2c06af7e9c2f28f1604cbfa8a676a874853bf38195780751d306936cefd1cc38c2192cb756e28793d2abb3e9a8159fd7915c15db69355514d9dd26c66fbd14af969ee576401b1b782fc6d300000000000000000000000000000000057270788a199a894b37a526a26bc4d293780d365a6b66247e7417884d543dd752ef7c89f2f4b38f4b51e6f9d86b45ad0000000000000000000000000000000000b59fedd6798487ec09d226a7406b27f04f7983075b4659ca6a78c6bb8aa83828fafdc6488518e2cba6fa4193de938c000000000000000000000000000000001105c18d92b4192833302814ee9b176831e57fb64b703ab3c2d3f440ab302c8fdf7ddc81933d3b1adaad16038dd6dc1f00000000000000000000000000000000020509b08e6ed980df29da649051c7095edcd4eed4ce95cd797da430cd09062a110bae21b6f73daff2053fc0289041fac818ce6e33e581595e83cf8d33a62edc26ed38c22f20c6949a94e2652bb954cc0000000000000000000000000000000007be348ccf6a76827d3b9b33e7a89378c133c9b226e47dcb205ee061423ee6e1b838bc262a7befae7c15aa385ced00bf000000000000000000000000000000000689787c19192ad55b9c6c260a5ec3aa203ef71f0b746eebf10f82526c4fadaa8570936d7049c1a46e7f3cdc455a63a6000000000000000000000000000000000306965b09678d481aa4c754d56a0bb4565f16f7523cd0b404fbd39dfc3b6ed483f5239fa30f13aa3e87918ca039d5ee0000000000000000000000000000000000a2586143f9610a96eb0ef86593988770db5ed49663eab72f8c368b9388bdfbcd02fc6bee09f4fe055813d140ca0fa89ab338e94b31d22947dbeb20fce3150127249d2db6107d95bdd032eb24c49645000000000000000000000000000000000018f46dfdde786a88e582ff6addbecb4f58e12c2625e3d6440f2e5b5781beaa95cad6f63b7d132e84700e7bd344fe3200000000000000000000000000000000185a4fc339a95a50551d53c18bb0dc3b74e9c164729c2b0d919392f7aad2be3ebae3b8f676ab81ea05233b3039918ab50000000000000000000000000000000015395b020a9d0bb336066c1347dd91c557b6ae7b8817cd8a2cba9e5bb149ca3401d661227c26d52a9be234faea894c8a00000000000000000000000000000000103d9d7e33a0767554e13b57dc756981488a3c7dfcc026ea84b35b0af21193e301226cb5a4760962707d19a95841be9296acb797236dbd0316fdd355f07b9b45c9bc626f73105e87c376af4d7dc075d30000000000000000000000000000000018359aad8af59cdda484232b885d1b14956ec04b5584684b13a64d97b8310c283e5d66637dd75de405f5f4bc65a6879a000000000000000000000000000000000849fd55e4f3d4dfc643dfede6356826eef21290b84f7e8e226deabbc84273d95f7be5479e9656dc907ec367a7ebf8f60000000000000000000000000000000006ee01b54eb7834b4de53f821ad46f467cadffce6df09751b728d0952bfe615253d7ad173892a52c6181810a815bd90600000000000000000000000000000000161472d45b56dd9fd276fc607f2eef84c5c843ea05799e732d7eb6dce96c632335949e1b3a06815e410e919f4cdc3fb360bc12a8b34e717b2c410d026660c14182250d7c66f8f88dd4cc94e550421caf00000000000000000000000000000000107ef91cf3a3068c4e5644676f7bc7c5f9ecc361524bf3fe2ebfc606f22f8f83b38c0d4bae89f3cdff6119cc27fedf820000000000000000000000000000000006a7f7cad2fa9db8824e4e30da7158f7737d2536554b904ed835c37add0341c07c5220db0f9801da2587a456300c7b75000000000000000000000000000000000f6dc3adda42dbccb1d1e3fea8918f5572e8b26ba3011429e754edd28559b731853761d33777f4e767094f80e63d417700000000000000000000000000000000107d93537a79173ba9367732fa3a28113ec37e053cdf31ce6970dedfa8a9b4cd55238289be9a6f40319e3dfedd132f95537f0f732fee8b882d254a81704d2310c05dde186232f3cffc05401fa98302150000000000000000000000000000000019dc19a1663bb05ebfc0b7cc23ea9e07376de413f77e15a685a3f11fc19bf0ddf38d5671e2a5e6e31624cbcd47a19cf60000000000000000000000000000000019e78aae57f327fbe8ce794afc22bddde08ff9bc9ad3527601cb1fd5dc0b8ed8fdf3b210f86760954b48bf61d74162220000000000000000000000000000000013954a533bf871e99f4a7d81a8b9931c480ce7fc47260c3708c590ade42e6b7bb887d4d24aa18642d010a8170cf85d34000000000000000000000000000000000a561d3f64ba31a6d45ffcf1bcac95f8f665133a1e962e31351ec78e369042bd3afb0c43d12b3087168c1142107241f31a22bc0bec2501a505cc8e00a24792bb380ed451ab6f56fde07ace8b6c9348a20000000000000000000000000000000007149094366e29537b0ad7239ce04bf49f253e4b746b9fe440dbf9b425bfff21064fce66e286e08c87dd83e22a3b499b00000000000000000000000000000000045ead132e0d03c842656cfc82a45c8b4a3b0cee7a5d071c5f235791ff7b5ead071b2c529b446a15aa8837aafc11222d00000000000000000000000000000000013159458f2123698ad4e7d41da47ad7d5083b928839e346a32f2307ee69f643ca11335d50e47d328b0079f1873cc7e800000000000000000000000000000000167edcf807ee723ba70e352367705448047c6b5223fe703381af6bb103cbb24da739ed005b14fab5699fbae6574505a7c7b10c801fb9d929432cbbe994b404d3baa5633628f396d20d047fe2c2ac2914000000000000000000000000000000000feb6f6f85903b3c8e4d6ec2ff234775f12727fdf7c35eade09c9773b004270f659b00248338f0b749d6715778f1f4d90000000000000000000000000000000003300794df19b9e472e8b869a2762c07a9251cdb96b508dfecdbd62fc3c3843b37118d216a64519bc3bdb71e40f9bd700000000000000000000000000000000005fa144135a5d6cf1c73055750ab6582b4c6d368566172b75902b1fc7a6f5de2a251ca7efc7ac6cc6c0bded14df02b700000000000000000000000000000000004239a7bfdefbe78116a588810328024b1bcebaf8f28f09387dcab66dcf2b02c94002df09d12db369fef9dd960783c0b84f2f3f31d9869799ed8bfc2cb129dbbeeb096d771730ae2863c4ddece66158d00000000000000000000000000000000007c8a24005575a3098c12ffa65095bfe227ee59e5e978a7ccab7a9a72391fea61690648c102ce24af723945bbcafece0000000000000000000000000000000000323d57bec7dfbb4614c8c3b286860fbadbf71901fa006149053ea614dafd56b1f3d6a86fa55bf1cbdfe8af4ff08dec000000000000000000000000000000001180b2b0b9c4c12f6d06eec07bbf6f5a220722015fe5365d1c4ca9e58ac9c8f67964d8230152d7a2220575c756bdf8b0000000000000000000000000000000001969a364c447f07d0820586bade587ccc816e50696aa0c5ea4f1daf6cd577769a890b44caa013d93e7f21f5ea269aa85c62206fadb762c23bf77f69f69bd492674bb92edb39248ad2a432f819304e6ea0000000000000000000000000000000008a51c01c3bbed13d42a4da626a8b89e2811db1d83d7de3332b36881ad14a5c8668ece4f5ed2b71204810457aa3d75cb000000000000000000000000000000000658a56aaf627e3f776d3f03caa2c00425bf197c6fa20c92f563f48260109a8f935d0d1638f5039486ce0c0100834fcd00000000000000000000000000000000126d1964f2d964c290cd7364e175ca4a855149e5c4ba488829a436b09ee5e21f6c964e439739f15317873088726bd51f000000000000000000000000000000001803186f88833393bd853970ca4fe414a43b7a619ded1f9c830444b4d43a94e9146146e2284d690436b395bf1e3fad15a6f950de53d07fda75ab43f73982c2684edb06317568df15b8712dff2ef782830000000000000000000000000000000002dc3756c7f4bb47559cd720a3acf4159290d7413e0498877d1fe321cbcb7cdda90b6c8b4ef8e27b2642b82ab9b3174d000000000000000000000000000000000c7490f1ccfdd91aa37a3044d265cb0612bfd9c065c370adb813b2d96f02d44041e79921d1b8935dcdb8c83ea4460ef30000000000000000000000000000000007beb34bfb9ba9b6fb590c7e830400888095d1958b252d187c184de91f165e12599d66345341292fdcb662deadcded030000000000000000000000000000000001ce203d58bebe1eb5b7cbc6038f75b2f7534bce9f50e7e4c91d6cc5ac1bb68d9fd8ce99206c5ec92bcabb71672c6ac195a373fab5176d124f783a36eb2346dddd5c4eba9e24e4c0cdc4f925e2e24cc9000000000000000000000000000000000765acace3e238e51bdaa08c0f6d737c9de55b5ce9ac3523335f0d35bfab6f4e7e2944b8aa4ee031ae9d39d4db96e9ac000000000000000000000000000000000b0fd488a6f9e92c4bdb5e82b52a0035f9a0aed7f69ec65303632017669f34d11552f849326e4dd204d58f50f3ad124800000000000000000000000000000000033991f66588b5e39eb78c7cbf62a74bbde2fa1b7c96164cb58040f0887c485b372e0ef4def9d38da9c6f5c4df2d59a700000000000000000000000000000000187d41fa7905739078d2c2f8775394f830d20352a9d91e97568c6929412f356009239bc9e1da3a8c766e89d09893b5b5319d855218eee020f9cf8e4c0b6004902f0b16eedba8a1c911476af34f65dd40", "Expected": "000000000000000000000000000000000dedf92894c567ee656051a7f02384edc7206152af6d3c5f662ca02559a3cc349c6b034c6fadceeccf652a396dbec6c900000000000000000000000000000000089deb173bda620678247a7218408594efff7ab0cebbf627b93ed37e553cf944e09232b92afe2f5f31d29bb9ae442c26000000000000000000000000000000000178bc39b2ca8b032d3cde53d2da3f8797026d78c76c51381b377c79992f027cf55ba4e182773c99c99ea6293a948e5c00000000000000000000000000000000195d9cb91537e77e7a4be4370b982b6d36190342ef6ebc2250a9cc8ef6ef45211736ce1f41da899178c1adcc4927a9ba", "Name": "matter_g2_multiexp_95", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004638ececd7f626a069b1bc3ad9d0f7cc71e5f0c1b11711fbfee1f81466b574f7a11de8161e55eb574ab367f56b9d6480000000000000000000000000000000013ef4f403f139771afe7e97815d3b3777818a3054d02125d3a25138e504c8c2c6696061572322aa19ace9ffd8e3ff308000000000000000000000000000000001910f776582f5acbaea626d2378e9da133b63afa087f25c2cfbcd1e7b34f6a237f2e9adccc303f9d5efe22496ee2ab75000000000000000000000000000000001963bd62098614c4ca2fc2a9e2d679c2b74bf9d322d34377cc63c3b8e7f8a4eb7d6d440d081e044606402fb3f51b0cee2a397c2f19a8c4e66df0e062f179be2f45a0c5e104588222a1a78447512f299b000000000000000000000000000000001935ecdf4f21cc6b510321b4ed2663e339954cd7399b9d67f1d9e2ea7fb9bfff8531f83ab59d3f0546393dc289ab2dd7000000000000000000000000000000000f390b86fb4cd4c1a072a83e1d1198a57a650fa6e94b69d983b693c592bc0c8fcd9a46c6883adacc4c7e2546dcd079fe00000000000000000000000000000000136beae11ea54ae26a8d69015ea7793675625b2013dbeb081a5ed877832849d67ac709b81fcc4fb322b262ec3776c0c00000000000000000000000000000000011f1df574f63f679b6464df463b58948fd337a4b3f159229ba0313cc040303345e75a3a2b0ed0dedfbefa89d8331d074f193d5a575c80a3e7599923bf5a8ba8a48e8f98322d1d8eb1da42e446d518c1b0000000000000000000000000000000001510378fdcde4027999edc99d49bfb46423ceb0d740829e310f8a381a7632fd0d6b6aa3533c2702a5ca76d386ac0145000000000000000000000000000000000bae237bfcc061552ca07eb14300cf557c974611885aa6894f7933f7dc7a0a1cc3b5587bbe1ea5fa604e3cee1db5f7c9000000000000000000000000000000001743207a1814990c798dc3de272a02b1b194a485bf09faea382dedd957861dc15cbf981f9906cda50cce2899785b9a6300000000000000000000000000000000106f902004c66c80437392e92cad73bed6b73010bdc7b6a75de4c01f0b6fbe5b8d1f47378279bfa42b3af05120854ced07f2013742ddf2d35448feb80b6b7aaf2925d3975ce28ed2b1ac789886ae26e400000000000000000000000000000000123362e41268f7821fcd2294b032c6a51c6d80506eb052ab6132267fa248a1a60c3e4eb2e75a1674bee1c9d46d82b9180000000000000000000000000000000006296670461ca67081cd76528446867e1a4905f88742d0ed8d1f7baf86e0a5e5ee86c8b0eeef07c14dd821dee0143bea00000000000000000000000000000000058bff9544e4e02c063158a52a68c93c7544e8157d37159dbb99b51b09e3d8f5b307bfe63a10fa409e20a35219ac244a000000000000000000000000000000000b135edfbf53187004d0977db94eeabf426ad7bea84ad76c6ac771fa186a073d430af76d717070e3c4057a7a2da095984e637a80a4eb1b2caba68b6828aa18f956c62baa7c5e9e591a15156c5abb605000000000000000000000000000000000133d3a223112dc5665e78fba8fc8d040d133858d984e66d2382d5e629f9369dd127e93c7a4da77fad98a0520ebedfeba000000000000000000000000000000000e88515db391bcdeeed2a9f64d27387af0391bf832164fba79100b560d8150debbd703c140dae3ba9b1ec35c1f45670600000000000000000000000000000000042583722c69a19f413392c6a2b75c8ca969be85eb951056d7e1d94e046dba49c346d5774009b8463a40b0576ccc1a6e000000000000000000000000000000000ee61a9eb6ad497c57405a44d798868e22b4fd5b8c480e9938cfdd3f1817eaaf331a9988368680158c59c2801add0a7a27671631f9afd9d2e86f263f5c17c3c11c7f6e43efb6d75cb2cb8250094f228900000000000000000000000000000000020352de9b4e8ea1acc8589bb22e23dfd0ae3a80de9e21bdb3f6391dd05a012e635de9e1f5f450bf4aab05728c054f8a000000000000000000000000000000001733593b94ec800bb59ed97dacbefda5ad882a8023346bdff8f471c5613c67247e27d72cb4ed8cdaa0f236018dd2128a0000000000000000000000000000000011f272a3b25bc519fc3e229211b846042031e22fbed22ecd0d1a4ef1d05feacf105772d71157e3d7293575aca257cd5f00000000000000000000000000000000153b4b4d7d65f7bd13d20fee4812f04706c96cd1a0d27b7e139c47299805e0ac86e8941aa38d90331c78a61c2dd56aa3c2decb1f482f3eb48e7f52b89f6452b659812ef79bb42fb25f03aa9969faf9bc00000000000000000000000000000000143e1f6dd9397f0e89a46c6ec995bf6c87ec8a72b309f050dc5b3134e00e2a16327767cb0573ca5ea9776215a5815df500000000000000000000000000000000186cb3af2cdb4562bf2d0c180079547cfb345cc3943fd7f9203fabbdc1547079cb9ed854f9b1a47f513e318cd409df83000000000000000000000000000000000c8c9197fa5a1e66b371a653c5d18c01fed8d17a8aa92d89b2cbd954b9fd2931fa61abb6676e4851dc9481732c6195610000000000000000000000000000000009026b259e840cb5264f6aad6ebbb09661f5b6d980389817309aef99e4e0cb228d3a7a06e6c25bdb1aeafe5acdc44441911eb1de54fa8ccb746336b681504fd08f995c864a8dae2aa866862f81f0e7850000000000000000000000000000000007bceb74ba86c07d0fca20e4febd3b12b1fe9f786c9a5da0531550244f40261d7ce728498fbfcfe16cc235db6ed42e11000000000000000000000000000000000883104ffcc0d040d70bda04dcf67c1197c39e200d4d9daf5f3c185638a13dffe3dcac94fce4175187dad867e8d2b78c000000000000000000000000000000001404e48e86f199486db7d40076cc8dc4e2aa2c1b6d4bed8f027512e2c71817905b26ff4f0551f9c08a2a7a27b2075b6c000000000000000000000000000000000b789a6addb98ea43c0f9e85831a75b8ee1977936c17929fb45d4c06b4f1ec33b9b41e32b52cde542c9e4b64d27c686cfd0a61dbcb0c657e824cbcf4670a31a95ecbd47a9b93812cd5124f3ac9450c1b000000000000000000000000000000000654e7f3985bf90dd1e3169382690fdc0f804eb6384ce407a060f539804fe6e0451094abaa0dad611c15d3ee52f31a92000000000000000000000000000000000deeec957d58a2246ff8f7b7448f5198647576c16c1717369ad155ae36d5a6bdb42c8d6a1f0a095891fb0890b6203f950000000000000000000000000000000013a01a6ca4c296f59cfa4a5f5399d28af76ffcb8b218c861d5e6dc603e140f730f632028c8da46c823d87bff5ca703280000000000000000000000000000000003698f659e86b96613ca74a480c81e749bce4b74324976c1d241a0911d078926fb2adfcc3f901a7a015a02f525ddbb808118e9c70cc5def8e7d258e05273937c514131f39e0cc9fd2a3620dbffc7ce3c0000000000000000000000000000000016ce72e1798ffd84b52ac664a184c6cf5ce1ca2aa263c9d056355cf610517e9c7bf7f057c342f6e3ae801b84c2082c0f0000000000000000000000000000000010992af1438eec10881b5e2e3fa3b1e91b6b5313ea58dcc0cd2159f8ba6ce5912d81b38956929620e04b3596f6835a6f0000000000000000000000000000000014315dbebd532d0c835e8e85a02c0814574cf040a20c18d06573718223c8ea15b7ea69f0cf342dd09037258398ba4bef00000000000000000000000000000000136d13a83e72525b2d4af54d14d5e21d8bd9bed18543836b02ae0a7e51d433c93aa1943e85f978a8a9ff4454d8c5d120c445931b79e2b826aca02d1bfbb00c2dfb6d30ac2ef97a4ded18243b1afce7730000000000000000000000000000000002c1bf7dc75006c2941b89a2de52fdcdd1b4fbda5b14fe3fc165915b90fd9d93cdb8105898ef59d5b374707f0afaccd600000000000000000000000000000000049a16efcf81de84e443666bf990f6aad2145f9c9c2c61a752e256e8f447dfb27b462e4553544971807f909a666af12f0000000000000000000000000000000000aa4702fb69d791ef958826753d3f74f61c7a591ab94bb6c1bd5d82d94c5877121ecfc1e769d0d16ebe491b775ad96e0000000000000000000000000000000008cd7f2562eca6c53a37382fcdb04be53998f45c2241bfebac3d1fb08d8e1d4df3182f2bd63861d0de72d58072356ccc982ae6de98df906922e660d461009ba6c04cc6497f3645a66385c775b21b210b000000000000000000000000000000000a6b30c4ddb692ae33c903693cdba00ba48efa48e90b9cec9dc747004e57a8d5a05b5522634fc0de306d38c28390dbf4000000000000000000000000000000000601341b3c4057767a910bf30dd16324ad7abcb55b7e98e73584f26d7f87d8a8d24ff2113c12ceb3077bf65e0912b2360000000000000000000000000000000019dc9c50f613470abdb5c763c0272e88e34ed38e617d6757f4e70d05b8ec9f67a023b4ec1363e7e60e38cff64e18f0510000000000000000000000000000000013fb1858f7efeec5fd03d9f7f4513e3e9103c340eee7bfe48ed3cd3dd073b96add9450a17f12e161f1d44669b1b2f813000674ac5d09c6c599173bbe9a43726c120c3a60a96d43954727a2f33ac4320d000000000000000000000000000000000d6c135bfe0fc7af93571a69b7c37ba691f051d69582cf159cbeb0bd59b48342172a82a3eec2e3d440805934e1574f2a0000000000000000000000000000000001b04e56cb3bb221caedd3582943f89a33b955f624f9e473941f1dd987f2898339142a654d11d87bf8bd2fd0fe0d4c1a000000000000000000000000000000000f185fd420b761a1e38d542558b0beffba916f369b37296fdd8878a7c3d2ac9d3ab1d8e45ad799f0d81bb439b5e5058100000000000000000000000000000000002d10ce460c414fa1094ef2b7de8f1ce024b6d086d10067be0fed4e45dc25c8e50bef361d39a2743be1e1ea4fb7e2ef773f8e9637886d795b75e7ecaee512005c1780e7ab17b9f20ae9232595478bb2000000000000000000000000000000001972ea36bae504d7047639ce6e0e6c3b16afe89fa3d6c6b33c910c8d4b70782d8165912e5bfbe8bd84f78f9f23f7f956000000000000000000000000000000000ae55c4fc1c01f1bbdb060191e8551a7ba5ebd3dbadd138202090d7dc6765fd1ef5fe8204ae76a8bcfa03ee5985a35280000000000000000000000000000000018ebed295805e0fc14f1c7b0e6ee12ca48cb7177c1d367a613e0d6cfaaac5128fefce0e8f38d4e2f11ae0d327be466a400000000000000000000000000000000157068d89fe48e77e0f62e3b5b0293423f35c5f4ffb9e0577f5aa49e91cea6bd312a0e65ec08af9c1f53de6499409c8d759d0bab12ac790cc3a16e88f1a108e670681f117d4fc7d01f8c5a2d6ca7fe8e00000000000000000000000000000000120e4a8935c08032dbfc19a43e2a770b12b05cf1dc229e12f683f0d7f604bc13666bf318fcc38038b618ef83c9448b870000000000000000000000000000000004e3f851be46bd85f37c8b1d84507f4ed63ea76bc305cc26a6f4cfa2135d5affcd3b319d9f57619e21c964c6246fc3f600000000000000000000000000000000138733f352029373b19e1c40d5958a04257e2b344770e1bbb8f377bcfb1c7225ae7a8b0b0e57795ec06a08e13c90d7de00000000000000000000000000000000093e85783c556a017829e28bc42b607b1035890fb9743bf0e279df4dd8a695c1dd07a76a213087c3a8a7e614b29b7a1ecce865074a8a41f8a3f40228046c5be68bdb50ced10bb73ac8472f0525302938000000000000000000000000000000000be1ae00f9ba0a2e57f94728508e0029b1bafd52c91ce718ba41790a3541117d1a9f846d68440978cdef016c3b9ae422000000000000000000000000000000001947683154204c9fc93e3aeac17b417453a24d01804e8acbf6f67947f5962dce875f49d05e6ae65384602828784f852c000000000000000000000000000000000859dc1c00b49cd1292cdc65c6aa4b11e27637b949c7db508930c557ee3ce00f98f9cd3dd0f6d73a646d176a91d75c070000000000000000000000000000000015a7a6984b5f42aadebba1e1f4682aaf1a2d01c9ce2afab7fed2269373467787bb1361b493dcdd862180e9159ec2ad5785e2f9597c9b687150864e90ab042f4f012a54d92cf9d2ece09e4a081ec9773f", "Expected": "00000000000000000000000000000000047cc33d9decfd059724bbb014fb9cd95de187e2dd29cf4a9bf9ad06d415e2cacb5a4e49266c13e0c38f2563d1a21d6a0000000000000000000000000000000011c79d93fa870d541e79ad4037c20b85d3cec053587f9df60dc11e7dc2727d79059f75bef76474c09fe61ed10b317cad0000000000000000000000000000000003df3f0db20c5ffea4dc9f4d9333d76141447bba50da18e521e89aae1e63750c71b392570d79e597967dfc9952e903c60000000000000000000000000000000014e83ea645b1019ac2dfafe370f616af0c5baeabe217ac1f9ecf78877717475b25911b339557422526a8163434439923", "Name": "matter_g2_multiexp_96", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cd1d25f285c2073175ecad5bba4987cc52012eadc7b19dbaa20fa82d7a6cfb8a52f33469b6308d921eb4b3b23f7022d000000000000000000000000000000001707b67a23d9212d30c06f26f0040c38389b185057e80236d2c828a8d9ade4f72eee1d6eccd78e4f4d71e2c28ee9539e0000000000000000000000000000000008e5c04effd14d915b9afc2083afa2b6d4008cfa0e47144a41982d8b5a8e77922a2609384e2c5d18c871ae24a7d505b7000000000000000000000000000000000f414acb056fff2cd6d9b408adb6eb7f34c8f66a66ee93945a3381d46c2d181613047ca6d4067614c190da444223cab685431a1df7678e49ee049b75ea968ca255ef456dd58cce57b64edffac1ac223c0000000000000000000000000000000008ea841aced2d0b8dd688947648a8ff18d0f6f03f63ee1c331f126dd4fc0da3d386535156b80902bdc1f65add7769cd70000000000000000000000000000000017a32ad2763d99c38c954f62466e78c0332e48875e15afbbe9c78376f1bab12346c73a573738353e2162d3928091dede0000000000000000000000000000000010ea738884dbfe5bc35d031bde9aa4109b1fca529502e236aebb5ad0bf71dd2f3db250d924415b0bfca56519f8ca5d290000000000000000000000000000000013699e29cc1871f51a469898be8b3c732b5cf7860286e655e65bd8176832804d17b48d0ff85eb023360db78162581297b6ccbc0b600f11f1b89061d94c6fbdc9b1d389244fb29a5d140dab8842d44eaa00000000000000000000000000000000004d504e62b2825651381ae862fd33407309851d5291591cd0f541fd092800d709ede00a9134e65ee752eaceb0a344b50000000000000000000000000000000016481efba290c37aa4ecbf940c76ee5df199b0c1f90fddebd2db28120bb5a14dd9f4a067b6d4889aeb683cca0f6ab337000000000000000000000000000000001400c89942cc63417ca4cb05c9d81dda3251e5611c27fc7727c3e803170672f103bff26f7216a0b646533aac3171488d0000000000000000000000000000000019889641be9db08880543ff476b9d4c72167092548ba49a3f3ace4518d3874f4f7993ae7b8cec90f092f144ec9d66c1a54dfe31190469897c30ac3736ab166220dd3702df5bc897835347713d03a8d04000000000000000000000000000000001927fe80adc6dbb581349c603103ad8831e645d9275af8669939b83829182cc6e2a30df2fdeda6d3aa2e2a6126e00ba3000000000000000000000000000000000b6d7934d5ca1098a85a0c60acca075220105e221b802b1be97c2967820bffc2937fc3278ed0f26905c60d44d5fd8dc000000000000000000000000000000000057acc1379f23c0d1d37427d400eb1b0a89f3736c83d3ffd797ae279e01e2acddd84082f13f3c8b8f1bf7c275702a9c700000000000000000000000000000000038dbcd7e08d34c553850a52336991a7d48968e98057e930790d78b5c6368eb2fe01571b60c4aefb653ec04122953d56eff1ceff9e5184dd9fea44da4f07529823dc9b100f776cef6f6881120f7de11a00000000000000000000000000000000014052031b88af979b7edb06c99c2e46bd9df2c862c7e1b71321754841fad67fc3242b51141e49ad86b61344aec913f40000000000000000000000000000000014806a86d078ee9bdde99257b67f50dc2ddf9bbf01dde931742ee6f739aa986cfdca06cd32d23d86f2c14c3b09033d29000000000000000000000000000000000e0561e795d35ceb8bd9e3b276406ec1f697a38ada25d1dbe08715a28bdd3d6ce6e0aac01f7dfc7c2b403850ab213b4700000000000000000000000000000000146a65209b09487e00e356e3b29952280ebc6a06343c4ce14efa0c6281bc2482698bd02295bc35125275ff5f5bb867dfb273e4c6266c1f5cf022902fe1310d2191af91c47995486342bc61cd361eab8500000000000000000000000000000000021592cd7f4cf9cab3be53561c889c9ee865961aad51339f6393dd6a0b7dcc8a7c48b753c947b15cd3add01abd3d76d8000000000000000000000000000000000f9e1a80bad58055a8577700c177889c4d702de04343c1202eaed9485a76493158547b20bcb552b66c42a0c86df809ed0000000000000000000000000000000013908dcff1945cf06f038e3caac9a7fbb3a6466ca18627e93468a875759a2b5599a96834ff21fcd6bfbba82b79536b9a0000000000000000000000000000000001b6354665109c5a64613c3bd7d805b3a34098708f3d41c7b77db031ac6fa0b2d4e2f2f70c84ac78687b0c0f9bf334771342b5cd4ad3179f406941ef6ea15d0aecdf9f6d96dc334c39b7dca89d256d4f0000000000000000000000000000000019394063202186e141dcebce7b8f0f267ba6057a0f993bb1cbe22a5bc528323823bfd1597a87017d478186a18f09a47800000000000000000000000000000000148437bcc43d432d70b47dadac8e738616c97d38d0f84dc132599626612f7bba74988bb23ae47ac15e6f70c059d607ed00000000000000000000000000000000180851594710f4bb5be7ae0104a383081c50f59e4e048614660ab5a4e2661e171510f5b112d8cf97a6af27d56d137c860000000000000000000000000000000000599f3f82f29b493ffe9ee3a8363b9a599a5ef3c9c5c680d4e003f4ac5a7de0562cba8e2a4c6da7d07cbe86c3f7bfb85b36620f65ed84fc0bb344b4b73f4eba4b1680a47b28b47f6d10f9ee82398125000000000000000000000000000000000cfdce7997601afbe484901893a1b5fc0b83e8d238d41d2f889a58fd4d884df1c667a000b53b587df2c42ad46aa2c3e0000000000000000000000000000000000c50bf3e06400cb10494cd09bd89f3c96ff49c9f74dd5325f9489ed6be13b59bd7b0b2351411ac854d430405b8a2a3de0000000000000000000000000000000001db313a34ca4073e4fa2287e234ac32bc579742de22e5218f7873b922f5804894826e6054925a394f125fce850f33ef000000000000000000000000000000000e0627a66d286e8d4d3654b32fc5f552a7ca12f0bd47eb6dee0dde22ee48165247c067a0f4c3d422bf3562d38a3c0cf1249ca9bcf879a770b0a054422a6ea97ae795118ae45532c1523c842696de6d170000000000000000000000000000000005285ba39f5bd981fce2fdf853706d70992acab2dc6d4c4198144fab397392a60d631056b580d0d98f3f350414ce554e0000000000000000000000000000000013bddbc1180f155872376fcdfaff2fb12d3d9645b81bd1475a5323ea855cea820ed7eb693791caa9bd3fa5c66036439700000000000000000000000000000000125644d32df397def58dff875d7e3f14166e765ed49a3991f45b38d74db3985fc7f5052058d85594c8b97afcf850e11b000000000000000000000000000000000fca4662eb1b39f576ee820385fba88ddd2fc01fcfb9d9f874453ad725cd5defb357be028fae97ce71bc5ac26d11c1bac014a0aa616e809b674390b4553bf2d9bf325e73d3a935eba94488dddee4e8950000000000000000000000000000000015b97d7c74c8ec102083b41d7ce5490466e1c0e261b5ea5c756d3f9ae79dd2d8ec6eb5075cfb76dfcf7bfdd80442f7d10000000000000000000000000000000016812f845faf96b8b69ac7a6af3c8947aa25877199e3c12552527706a17b768bbea259ea61ea82c4624a96cbcdf4040d00000000000000000000000000000000123ad55e5cb5ac5bdd3ca0a5afa7c3f8e4b98ad91a205f073fb546fe799ffc57b3c1c3a6209547ffc6ef05fd24be6f5d00000000000000000000000000000000017719f31946aedabe0e9d88ef3f90eb6ceda884f5e3d2ece368373785b2d8bf0f9677731803b25accfcb6cb716e0aa4ab722a1c20f068b6955a44073914c418a082345796912ca634e79983a24ec4bb0000000000000000000000000000000000497e3480d58027c780f47cc35a121ee0cd76c4e84d9a2f9002c04a1c286be990167a0138049ad70467132818f48ec9000000000000000000000000000000000ec0ddf938553105400f70989140ca322d996f48ffb1b35641ca36a6ba9ac1daac1603c100822f80cf62ec3bfb442158000000000000000000000000000000000a0b6ebee28a792df46d2f727af812c15fc91a471e0d8e34b25b26048f3b9606d8375b5b268c40fb04ef8f098e1d03340000000000000000000000000000000017843dd19bfabbd0cfa41fb58e70a8900397d17ccea783087ece90962560f5cf090e8d9eaa873a6a6ebac45219ea97a68b314f83cc3ad501caa44b4c3ca8cf68c70ff6920f445d3a7ada212b6a19ba3e000000000000000000000000000000000b27c82d71f7e4aab9a68596669596df3f62071e921e131ba4d9e59d8d81d370e077e93a4a6a43e059661227f40b38c800000000000000000000000000000000093004917ceb2fb4a1b33960ff74943d520f86e83aa02b9a6c85e4b9a489e9331863cd30cb6ad6f099d03289b4ada5520000000000000000000000000000000016f04e35186c7deaf730708e1678089bf3e73c1164bca24bf8f70c4f6cccd5bbb34bbb5dc313ee428aec4ac9c638a01a00000000000000000000000000000000011052348cec9dc3e85e01abcca5a652461f08a9f5d72b3fc27140a6a571137f0065ed7ccf9ec8cebe314ad9a214d5ed94ffab83099c69845cc87727d459ae300a5725ec53176424ab0ec8bd3f80eaff0000000000000000000000000000000007083dfb0738d58ba8933a1f60283e5da8bf90af5aae4053ca573ee7223d3b80e4bdc30b4a831ce6af9f52f393e9742600000000000000000000000000000000130c627b7d3a527c94cfeba9f514e75eac047e1b6088c082229a8c95d0765a0898ce1e45694ca2c7935bb8e41e44e8b10000000000000000000000000000000009610645b074e652a08f2b89dbe594afa3009d795ef211f7c036a56274b1e1bd69a035c4f356b6b21f69b9cec2bf7c32000000000000000000000000000000001020f3cdef468af700269aa1e9d928e71b8c521f23586c9b0155314f0073da7de04ca41ececd5edcc052af72c05f0e4bb1d80be637e2abd98d0433150e14b629d98fc0918c7dfc179204669ab465e90300000000000000000000000000000000123540047f0768b0af841aa4aeceaf3dac31ea832daed86c8cbd1d33ed0282c6f697d5881f9022af032e90ff82efb6bc000000000000000000000000000000000113daffbe413075f5f4f6fb42f37b6e9d5e5822aa24d6f865792f63e6078584246bcf8b17117385db1d6233974f6ed9000000000000000000000000000000001067b46fd221b6995d25d4bf0adb088e0554d858d4e5d9d6b59e1ae2a7d57188d559b0208918a8944aedd62b1ebd4f4700000000000000000000000000000000087dae77e483d5c0baa37b9b96dad5ca92b5869fa253bffad24dd8747446f7ce60858b52438e58233210d86f470f765fe670a57ce4dcfa680e60ef33ba99c437e4fdb160ea1012de36f4b59613a6af8500000000000000000000000000000000039d09a094d655c139cb9714aa258d9548473162548048b0f07c9317a41a7e5dbaa5aca156992c8a509d4071d9ae4394000000000000000000000000000000000f0273a38b1b9d006efa43c15a53f026587a676912d0275968608519e97994ea9c6a147e377f68b1738ebeaa178f9c1000000000000000000000000000000000132cd92417578d2e46884f1c1a1080b1916c8c8404d2533a4de02bf8575c80ce7e8097c2ddd1f95737355521c0ec21ce0000000000000000000000000000000019adbf09a268a3ed8eff936d25fbe8af2874e44d2580c7941dc14fb89c5da963b468a7088c4a763eac89f4d15deaaf5e54a999fdf391d3944318c54680e69b58ce3778683b6f2c607d64450ed32c6d89000000000000000000000000000000000756dced467ea32c3c425590b7690a45e250e464ac6927ad3f5d2d8d2826961b8dd7572db609375c8d06cc3b9bc3a157000000000000000000000000000000000b79b4eecbaf1d0f8a89f9ef8fc144b3aff38148ae260da7c20e9dd3866d946585df7ed12c8b7005e7b0e1387c9db41d000000000000000000000000000000000afc403b008b70e19f17b1ef37c9c396577a585b6c34b23d09621b891efc00ef9460c3f4b5f3e851ef63620dc06c824300000000000000000000000000000000024e06f3f3b18c026a166c41f75d7bcf699480f5b6811463c27606c9ec1232fd249a46235b7f5b5a2ed3b53231b333150563ae7b444cca7ebaba36b8d59aaa5c0e6c1454a4a2907866247e752e640a7d", "Expected": "0000000000000000000000000000000004f2480d0b7e84a996965b76055f6879aab5bab26656e4e5ca7220adc17f14b5946047484327bbc5952d9f2ffa5f92af0000000000000000000000000000000002f7260c55c500b54df4391a55eb4adefa7d19bcbec82a107fc0d222c898b97360a679a02ab3023ce2ebdcffd125ddf30000000000000000000000000000000002cddfa94c8f6b3f29c2fe018b1f8679d0e98c8c2656f86f327b9cbcba574cc52643ab423b458994a03347460deef6570000000000000000000000000000000014eb4c84f71ef5935e707a11a92ba34780677ac7eb198e160585ad92aa5c1ea21e3a77be940fe344e7e170680e2a8d53", "Name": "matter_g2_multiexp_97", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c2c4c039047d297049afd0e8f0375bd4294d628d3a22078d93b684b737e8c4b6ad3ee544ecbeaad6b3c75d8d217f3a20000000000000000000000000000000004c77a2c0943c6f997ce2e785461f8ec253c47273ded4e1af43ae882766ef8c168e66d831abc2b3b3a0849bbc210cbd40000000000000000000000000000000004456a6c267a5cc6b7d9a9f573270855186a1b621cfdc465fe71ddb4d614565d9d36b13985b31396587919226843c6230000000000000000000000000000000009487cdd8a0cf7f40e9087fd3121cb480730f4302339d25fa12128033239662ed65579a59b837bf1bc5fa87db15b15335b59d128b5ac47106b4114cf225dceb621d177141ef5783943f40a54ad94e990000000000000000000000000000000000ba43205e8392168824f77bac344d60c1a9a0b14ab55538c3bfea4a64984cf381a2f61c64f1ba1bcfd8a7973e43f6e80000000000000000000000000000000000e95e5ac415c3e3e7c9feb6e7a2af3e8189afca06ae1fe54bbeb31783810860921ab3c76a475fb227b3c8299e3f1caf00000000000000000000000000000000001e3cb2106a23e77a126013087751c4d2a419a51beedc3a33faa6c933bedb3d34ee9c6450c583642426edb352e04da98000000000000000000000000000000000ab5af4c98aca1fc3fa55355351d12f3bc639662bf8b5b772152988d676b00ef39f767237a2fa3be936e83d1dd77da86a057c0405e24b7373f67197b2109b633a02589711b6a92ff49ca024f893d7ecc0000000000000000000000000000000012f3d927316ba638bd6294f7dd2f3f166d20285ee1662ae4dc145835704a17127078343d26042a5c397bfef31754186200000000000000000000000000000000162893d6252361c340057bcac31986458b8b55a8a4283f5a06ce1730098f9838dad1bca264374e7261bb9d08c177c1820000000000000000000000000000000017264aead0ec41a079827296f3d32c12adfca7cb6c674070d54087438d57b6ccca4822b2337263e60075d469b4ce0ccc000000000000000000000000000000000480cae035bd3bf1b4a4a766bcd5f188833e9587e1aff0e1f10e36ebbf2f3ae76bc0946e7c336efc3ee00bf42e7efbb9677b05905180182427efeb848b2ba2eafbabc7519ab33db14de0746afb607191000000000000000000000000000000000d13375356b1518e37a13b43b7d192eb74bd69636f91c570c41a741a8763c03caf8d13c7364f57c867a4a3983e88060f000000000000000000000000000000000f6f78dffb404faab88ac7373e0c765209c0af80514d438e18393bfcfeb60d9a5e13158d399f43162033571ee4a75dbc0000000000000000000000000000000010c379860638ccf3b6cb8479aa38881b0004197e3e367a1d5ef7c7fcf075689d283b87022e2825b5c789ac6a448467320000000000000000000000000000000002dc392872cf2fcd8e196f10c1ded175300070e4e38aa58c89c81e1aa5faa08d770a5ad90a8295a890551f9329a13cee53e7f69582f4c106ee5bfccba1d5f557736c1b75b6e3777cfde47d552e6bdcac0000000000000000000000000000000010383a21acda7c8f3f3be980bff2d57fa0a5b2dc424164dd2ce53c0b20ca399d6227913b7b550462180b01c231e4813200000000000000000000000000000000078aec90354721f0a31e1377b3652bcb1f388ab36f1866c955f3ea8dfe6ac2c25bc4cea14f54aee71595c2c1bd2dc4910000000000000000000000000000000007dfeec77213d952c183452b98ad936e8854608d950c0c1451262cdc7d6de5aed0db07a8d74b3e8f674967cb4839c4d00000000000000000000000000000000015c09e4ed2ea76d10d196f7a733ccc272b94dc436d6bb5fafad2fae4a96372c2c6f1325d1554746814ae292d8e6b1e3634c87bfb629b817e7ab97def7400b0a83e47af8d628787ff814733fdf34ba8d500000000000000000000000000000000138656fa091cc6613b1fcff04a3efb4f9c393985b2c78fa838eecbbbb8b6dafd88d9c72441f9bc735649480b5187acac000000000000000000000000000000000a35cec4819ca3321917cea5aa589db8cf61882fd1135031dc41a8207a8e71d326312799291b160a646148c382ed086b0000000000000000000000000000000005b6e4c02c9c54630c96271073513cac3a42d47a7272f62a21c7ad4c85c19b60b70d04719626cf4273f6c5691719931700000000000000000000000000000000166a20da734a47d7e28cce8f0c2d679fa6c738a7a1ca9089dc67ba2b1c92a83b024b8991f131e7e8802a617153de4554bebb60069acf431e1671e3d00e4da0d70fa11ed4099b21d45a2b811f99dd9cca000000000000000000000000000000000a4432a544deda931b1f62759320ada2963062e722bc1b748c9bd0d026ffae10f228be36ea0ab076358924f4c06b6feb0000000000000000000000000000000000e955b1b1b28d2044b6be371c58bc85097c77145b239e913bb0729757518c465d9e69338066f7496aa6a2038ea604f900000000000000000000000000000000017ca2a7d52c3a82ab8abf9fc1bc187389b6e4904e161541008e5b3ba0981870e01060d1272a6d59bfcfb294c942403f000000000000000000000000000000001870649a50e0978185551f213eefd9305d33e92b3f8c39752b6ebe18ae86ad97f92acef05971dceee3b3729becea18168b1ee2765e762f1b8c2451270cd5a755758fd733d7922a537aa9f1fd7d0c95960000000000000000000000000000000013713effa20d5039ced751ebafe1516f062f11ee05ffad37281cfee9d7a49ab14c065709832f6674bfbf2c9f379bc9c9000000000000000000000000000000000295f7ef148430209b48c292b024474f05036edfdee082c56aea05a62f1fba3ee7a540955423f78614c8385da8ef60040000000000000000000000000000000007408c97321b6d7c27e5e442a9e35b054e743c34d845874aeb1ccf4e903ca7803ed7fb1288327865f9e0ff0a388e92b400000000000000000000000000000000081808d03722a2d48846a693059c2662dee614f181dc406825544d30a6adc0f9d84a712eff80bddd4a27a036e4bf7359d5009fd559714d5692de5500ec8cae9c04ae1ab1c7c6e08c8738ef22da19ceca000000000000000000000000000000000880b646a674723c15b240ff56d2031e5db724251b1402a68df8b26261ffc9fb60a81abf165c6832137dc7a7293142d200000000000000000000000000000000172354b62bfb8d388b5a984411414738302725a508e8abeacdcb46454371d5e9cf762028fb65921d5c3dd8c67d42a981000000000000000000000000000000000a1af459bc3122dcef78359e468f4094d609ae3da09ca5aa6efb71a7494dafa2373a3906bac1f324d98b3eaa982a27d500000000000000000000000000000000092ac3b47253c7f090df076914cdc08a715faf153e8e365392b4859fca1db14d3f7fb998c97de9ad99b7d0b357252f086330c755ef708d8eb129475785f24be9e7836385ac918c60ad36e80e2f3281b80000000000000000000000000000000003b23eff722c078a781771d8b75d519e7a062ca3e4252ecca877845920158fb20d79a9ce449d9087426b113da0091826000000000000000000000000000000000c9026e8d3fee6282492393db504a2c41db19d8fbb83260624b05ba4107d6cb2c90d645a3c16862b27cc3fcce9bf89840000000000000000000000000000000018b8648d0a42285d474f809519696df9e1ad5c35d8e848ad74fbee37425aee8844a8be8cb4d3331670ee294ddb9a290200000000000000000000000000000000068cad37ee8578f4b502ac2ef4371a10e5432e57fe20d0cb074dc427831872113d3514a0b199d813b796b8357fa2a3dbc2431888d05cae840dde4c26911db1893659fdc345d5433556d9bf75e51fe3740000000000000000000000000000000013200f0aea4c60937be47213b6149b0ae76767f3559e0519f774af4a5d9431e2dd7ea74b42cc3ceb28ccf0d2f01116f30000000000000000000000000000000001c5bff08fd16ecb68f21289a3e7b9a2ec5da1357d604710a18e78ab780f8ef0343d5d9ee7f7988a009329b17e498beb00000000000000000000000000000000125453772eb9d1335ce4dbcc8f2ab8426fe89a0e49fec51d4e96718a38570aa82dbef452368141be2df260fb131c50b2000000000000000000000000000000000432cdd445519775b9914a986a0941cc829b4a15cd361df9ae7129547b24f7a6a15cd8fe9393fa1551db2d761a208b8ec9a72369cda74e5c86c6559cbc4f4db1b3ab24c5150c7decea862ede3c02c505000000000000000000000000000000000396cb6d7b44f92b716ed02985d351b4e8cd1bbb95f239e4f29d7379428470be395e2faeb8e3a910007aaa490d3c336d0000000000000000000000000000000000ad0c0623fdf50c2b504777554dbab3cde1b9705e976561873d7c22b81f49c7654a7c76e558fad1518ed73a0d3c3570000000000000000000000000000000001241d5bed68e02a2ddeb3ccbe109a161abe81edd7affb72182c5163851211c4763e6aecf766053b61ce575de893985f800000000000000000000000000000000183696d2a48feef6088f4e9f75a5055e8c54b3813658b593958490ddd4245ac495a8ff966861b20f26047f07fa8609a0c2f50989b04fc29c4c4a0090fb11e860c15f89a66f3bb8281e4678ba63ff3f9a000000000000000000000000000000000fe0ce41aa9e7cb2bcb4e01721b7b1d99fca4e9b7c4df09bec00bd346fc57c25118ba70d5333b7f3eef2659c64520a470000000000000000000000000000000005c932e09c62b7ddaf3f5c420c60740befa7cdff5bb812e0f089c45098d71b57004b7a207f0cdd34daaa3282cf6e9f7e000000000000000000000000000000001874200ead9776c1ecd6a54a57e5d0f9577910a4b3afb9b051622f658fe3ef6cc5070af60e7ef910562720e9716158d6000000000000000000000000000000000c2c657e58e400a67e59deee8c28234ff4688e781a2f6f2f0d0b186a5e4012695a522dfa0770cfd543f55939a05e20b09fc9abf1c76ff11ab538f46ce768ba597eb5f2f63073ec67e8de10aa1d666720000000000000000000000000000000000f0b561e5860321249b9ff434c604d26c3275824fc4ab9c1ce5c5858605ddaafae83ae27e523bf6006932f6c7f33d0a7000000000000000000000000000000000b47aab85bbd909599aa85c5eda363b67790ac6729fd8b1f4f53f66dd796cf2fa3496407b1bfaea4dc8eae53519054e70000000000000000000000000000000000cab1ebd23bc05c53bc9e8481c469eac3ee1b140af545bebed10a8fe50698d2ed883219881929207c0addf2f687198d0000000000000000000000000000000007742de55b799950e6f786f4eef45d0fb67e0475272ad68a183135b70047abab6c2ed51ede16c39be7b986df334e9e75d4167723682bc0e7476797b3be5e14b8de3e4e23b4ca33c50a2096cda8766dd7000000000000000000000000000000000923861332988bc843a65ec5dd4637f9dca8a15e71b82c780fe60d768213d118d8948ab554e30bb9253e900a9b7d87f200000000000000000000000000000000132b1faef49e7966a05783ba526e71134bfb577b13116548352da37e91e617d7c72ed2645e672ebbc517e079247dfb0e00000000000000000000000000000000000a46a8893a194ebfe077afd05fb25d4680f1e4991a3ec29475fa5651d086d20b38136155a65a4c70af31de5a78af59000000000000000000000000000000001344eb957594028b4228cbdb8efb03cc7cf49ec43b2ca5481eae1df6f2df3d5be9a7c4e4e78f8c39be546e29a83c92f49644c3727f78dd12811092190d5d10adcd5b9fc581dd783c97d4e7b5130f309a0000000000000000000000000000000012d7111303563a6358e5ce9155d7a153b5781062c2f6b919efc67ddfb4c61ef03be8828ca6339397b84763a5f8a7e8330000000000000000000000000000000010a2a0ea9973728d3fb1b5906ee84b2635c687c11398ebf605cad30216df3b7b4e3ee1653d4b323a690e6ba614ebec30000000000000000000000000000000000b93d5de37b892d4de9407a820c73ecfd6cd9fa565db82e7e8c14c8406823f705ff0adf6bd6add5ddc5f72c91e52e840000000000000000000000000000000000dcb320ceba5436df8f099c5a77f34376c96d830f5e8ab80667d156d89f6bf8998c148ef9a53847ed395871ab86f6d280df9846c84354ab7f947caca7800e12e38d8e6651527e6831f4d8b1bd66c4f3d", "Expected": "000000000000000000000000000000000ff3e299e6b9fc488d6db991cf9d226d330846e87c4a5cd3e5d4ac955bc2c3c2d1ee5ff230098b48f594d256495f489800000000000000000000000000000000097fdb8fc95d64c7070d8c71e0fd2a933d1e1ad3fefa230f079bc5743828317cd1b0c6d4253ba9c3c6ec6b12d53afa700000000000000000000000000000000002448bbb179d82eaa453cd5452752b9a083b52694cc65c5d9b47f72eff118d7aa06b0fba18eafe93d2937d7399c001af0000000000000000000000000000000009dec4c0aff2a46b07855c87e08832811633709ddfbbc30dbb7e78b3de43bd95e383baa6ff4c58188f0c7643e0ea5a40", "Name": "matter_g2_multiexp_98", - "Gas": 293920, + "Gas": 240480, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008afabec8a9985cbbc6246825785654c1d2eb7da5a01f76c4af4d0096b9baed3c33dbe492d14a6f9e762f06eb3d198f800000000000000000000000000000000027c592315dee4bcc892acc6f41a6eff5219c308253f7cd715d0e4a32c03c6d0d0e8568e146e9e799ac3025486c77fc30000000000000000000000000000000015b4ee27a3aa518a1ec1b447bb8f9128301c85b7176296d68dad3339b1dee78715b2f031a7fb6ba376145c97ceafeef60000000000000000000000000000000004b7e30ec7cc024ced863ce511cef3cabe954a4e5843dd636d776645a44225a36ed7e153ab5bf5d18f23c6444751875c8a71abe11a893fce872f6b8a020b6d84241df03eb934b50cbf3571df4800a83300000000000000000000000000000000119949d36d8d8e2bc1c26ded5f5fb01225a980a28b934ed3862480dc9297a3758e0f08ccaab3a09b5e5c0e4215e3246c0000000000000000000000000000000004a82dc22316ee6af39d937b662d1f1f2dc855c2ca8f33ec3274d833e87d594633fc7fab247911e0f46564397910d6ce00000000000000000000000000000000196900a09d8504ed960d41f4a8a2cde2e5dac61b008d3f6eb47e86d7b2ce6fcdc0f85157e3ab1571094d9fdaa75d0d500000000000000000000000000000000010c52ef9407eb4ec57844aebbcc3ea5000b1940d035dcc2a873327affaaabdd79e3560cbd29c63ce04f6279056d6eed1bbf28e5bca314391550d3a0fce50b1220965860e72c8c3865a2d4c599d31d3f1000000000000000000000000000000000e43655ae05dc6cfa93113dc26cea895d1c5bc73f20454c7b441dbc5ac80035b290514b13b31b41931ea5336d8d9a6a7000000000000000000000000000000001199a873958c63147e6b82625dfea15ce90dd41ceb4e315f67221eb874ef32c6a2953412e7e981659c72239a7a72bfe6000000000000000000000000000000001845af5936b4d7487ffe59137ba2f86daea3770cf37fd560969ee48243389941a1072205e049ddaa06c0ac56b7edc8930000000000000000000000000000000003cc831177f24614f93a118b896434105f05a277051a852fb9973a775fc54f779c2a1f3d64c457e5231dc22d6aef606b58b208a6845aeb2bf31999042c59b7b130a7ce5297e88023953b1aef63616fe400000000000000000000000000000000005e63584bc85ba58615985f6a466afe05268e545e0062cd7214e0b6fc8b87537c745b754cd9a1144948bc88b3c43acd000000000000000000000000000000000635b6a49090ccede3ed2ef203f0ed164783e3df4d9a7d93319515cb9230bd841b61a097f39e30175793b3e934d8e426000000000000000000000000000000001861e65f47a9da1584c45bc79a66045d86bc1709c2d1cf6cd2930a9fcc8c4efaa6536b5015be8d54789e8f574f93f9f70000000000000000000000000000000009290ce63d55eb436794acf11be9d896f03e7608a1bc8528f61ec9473f054bc9fbbda1072440e58e2f6ba080a01180173b53b6cf9e0ce1661c4960283be790abf956c2d6433529b8f3a32b92b227aebe0000000000000000000000000000000018feed9500bff884d2bb58554da2180c68267b6d3a45c2c7cee4c3f8524252d3faaa5eff971bf40123587e669fe66bbb000000000000000000000000000000001441bd3b58b4a4a87c2459f873c0692f5977b775af984bab46dd76cb9f775d2faebcb77b2854c9f1faa33f6c5de61c6a00000000000000000000000000000000123a890c3362c77e5b5cf9846d9c9e43fb3242d5a831e640ad080993fa0547854c8d11cc22f7f7b426528bf1154d2300000000000000000000000000000000000ff4a59ea98d13cfd353ae61e18d3c7018688f755561e6a1da5f09acc4277e8d49645087115acc64f992ea778a11f39bb049228435ade4c4c565e65f39f13a84c747c312afcdaff352560b9fb3cfebcc0000000000000000000000000000000006b019d005141e82393a2ca04469d1f6fd7b9456001ffef4c34eff6b2e91df58e99fd07944f52b108bd41ab6c4d6bbf200000000000000000000000000000000109ae87042029856befff0c916db5437e1e058a96f2970d8816b3becc93a1a50d6d336d5451303715f3e272147a36caa0000000000000000000000000000000000fc381b8dc9dc02d34db13e34732a10d0dfcf676c224a05a3bffd888b0af7c415b38af0b6afe6b464ffca42947c6ee5000000000000000000000000000000000087040d09c39ccd06c9ecc360fa02147a32e8036ad6e4b6bdf5b3883722a4e5a887dd022d53706d2585fe558696be6656197f5ad17062d2ecbdc8887bcdd32e5ed4c48cefd9e14d622a0b800d970330000000000000000000000000000000000e35c27b29df0fa9298bb9ab6a38b3450782223e2115d79152f9baa924d762d583b3ebe88e42f33028814ec78e5b319d00000000000000000000000000000000190c65667627a16f0af0ac7f23af0803bca810f3986b906b7b4f126d98473d52badf45e90e2e45bb390242fa8c40135100000000000000000000000000000000103f0283a5673c16bcc0f74f259c2eb077061947da04e467dfebf62aa005491e32b85cb73418b624a30dbaa01672921e000000000000000000000000000000000465466955c908607191faf15f0768dce42488c488eb4a065977f21ac7484766bc0abf23961ea2ba46dcc04956abf6c7721d9d7fe10104cafcad71307e785321ab87b2b69593535caecbf0e166cfda5b00000000000000000000000000000000082346e352e845a54cd4267f93b85b2c8623d4650e00c1c56082b73ee31f63588d2c117d3cdecc0378fbbf8956b082040000000000000000000000000000000001a7f43c2bb19cb32345c43c950536f8e85815b86364f278f6ec8169eca80917c2b8fc08d59b20cf55f25dc468e7bd7f00000000000000000000000000000000085a5cb020df10f9b4c7afc01b1d11700579dec1e85e766507def2e6cf5b714174f7be9cce3b18533a5ebfeec2b4e481000000000000000000000000000000001836d7506d1cc984fb777b8ee935d6f5b110644f59e96ff44d8329336d59a3e1d2b53a05d35e97f634baa4fdc11a6cd8461531ecb61365908019c1e8074a4c322df2b356eea3f3eea9aa1e0e1fc5525e000000000000000000000000000000000c1c59828ec6257a02679cff0bee0d665d449d2a158bc6d877e84cc0fe2161c297dde09b778d5e1249c515833e483004000000000000000000000000000000000f5e82589bfb7781e4110f1486752b00cbdf96cdf4191d75053c6d6d646e1c989add011361031a11559e156d64139fbf0000000000000000000000000000000015053afa7fb2b4e4b70f3c8a570fef8288fdc22dd951b6ba8a40b6087b9ab04ede21f0ddfa84d6d18914041bcf244c110000000000000000000000000000000003f399800cba51ab35624d866831ab6506392cb3acf549787153ffaf08cc451acea46c7a612821dd96c45f8b75133d88569c1c1ae2d18bbe36ed50db1bf30957802b09a982fbed49d4968815552e010d000000000000000000000000000000000e26242c8f73116079369ef4265f624abd4377e4e3485c28197663de9de9f5618c3b6ee602ff6bebd1c242aef7295b2200000000000000000000000000000000066ceb3ea6067220bd28fa1164237782859d27c1d3087a42b4d09bcc343611e4ed2be014a27f5b394c67643dc00f57cf00000000000000000000000000000000157f9d30de52110ea7a2a35ddfe67d9fad7223c5e3307e797dd0df3621520a421958a2835205e3c4777923f47d47e5310000000000000000000000000000000016ebb41beb85b9489a6d5482f8a3330a5c5c5e5718e8efb8b67362f9d8e9c313e9e563275ba38c207c5bf3d89c406ea62061d33b2f7e786effbd2e93101a56ba1bb62c1a773a08b72ca82f5183bea35b0000000000000000000000000000000005d1c9109b5b7409f94ae3f7dd9e8ae4908a9b378fea4ea284cbd33d1e59b605577b63892aaa8ec14d415f34e22fec520000000000000000000000000000000005afed05e62599f20f7eca019f41d770c630cf6359cb5601464be821691fba5205c16e7b580e6881047214f938e5104b00000000000000000000000000000000105637a2aa4725d8e080dec3b731a111ea4c94b79f898dfd51f645501ef0c8d68ea8e80fde28ff96e927e44306ebbb1d00000000000000000000000000000000080cfeea754474ceb37973234d5dc3269f8ca99bd862d4d2d1a602321fc709945a3209e5ff2cc962cfa6d03017c9a1354129b150752d2d5551a622231ab067931678454aaeb23f76168219406f0d50ee00000000000000000000000000000000137762ea5c80033aaf17570451b15a062feedde810f11ebdbe9a79a3275dc12613e0505835c122bd5f9afea7dba84203000000000000000000000000000000000d89c04e45e60769a63fcd73df2a138c457bb549195f2c4eebb3be1ea46149f286756795be8328b5b886f497d8167b34000000000000000000000000000000000be43d515083c8c10f467618685a43d4d5f6457204bacd278445943a9f44f7189b561a0e1bc59d2757fcfab2e3f93a4a0000000000000000000000000000000011a52583227c6dcdc1784d3633fd584612a9f3bbc1922477396dcd5af84413e5e9382a34a71b3a72491ea09fab2fc6bf366c32d5d3c132f32a6ac3cfe1dabb649c59ae224338f747ad98b193e8346729000000000000000000000000000000000073acefe33525dd2d5204cce72371ed82c7e4b58d1b4e7f4b4994f9c58b02d9d6206fefb3552446b6b355e860ace43c0000000000000000000000000000000007344eaeaae71e17930e769e02bcb4f44ddf3d040ffa0b081f25901cc125a37a58a6a5d13e7b0ba493802ccdaa054e29000000000000000000000000000000000a65fec6ad29ec3eee9ddc7ded2297f49d03ff18a255f1e6d29d2a67c20713f319d79d513af0c58ae3cddfd1f6240ff50000000000000000000000000000000019d5f00d9e2b271f4e9ac779a096386f08ae124f77fb8183405d48ea7f16e685805442dc67a392aefc643ea95b4f1fcfd997516cac28a3968ac6946b5bffaace0856a52e38fdcca11ddfa16cf5a568f50000000000000000000000000000000018230bf1a873aa04855af1426da30f1b3ef4b64eec613b9f660222e3827b325c318baea031b463c7e9f775165d22ec8f00000000000000000000000000000000017faafa1294fac53e1de8cae9601acc62d76a5f01a39ce49d65f3f5d2cd5cca33eb90bb4116b3ea36f912ae2b81b6cf000000000000000000000000000000000fc3ef5ea59849a87fcd45500989f1744cb5570ee88e34a952cec32cea2eb5900b64d8d0d04ef5c51e8fdcccd46412490000000000000000000000000000000001c53aa8aaae8422fa4fddc86cacdefa89c37592c8e67e472a23627514623a90901a619af79e93561a0dc65215837274e881ec65fdc2f58e46d3ee45a06d0c5ac844ee5b62872c7ba21f6b48621a3371000000000000000000000000000000000e3db6885c2db9244548e11b8c49b73f85e4104b413f54308497262fdff1957495859830114528a22c45d39a554ba82700000000000000000000000000000000181b1bfe2d9a1c563e73356d73f4ed3e7061a79c610bc97c911ab1a0213d123c9f83ed6706e862087a796ce14c5cf53d0000000000000000000000000000000013f5fdceddce771588869b945bd6025e5ce485fe78a362356720b474b83998f27e535cfd8d33ee51cfc68e5d514f915c0000000000000000000000000000000007e8fd7ba457a3cefd50c641847425cf2262deb1d6945a0bd740eadf38dcaa616edc48c3912508d663349f089b8b56fadcd9b95e49473277a665ca0f9a8309df9ed6ee4f25d803aa967fb8f688273e650000000000000000000000000000000004b20b0408da7b704694b47607928a655077015f2174fe01bac9a0b3a61dae087b0b593f58d2947d8d84f75bbfb327c900000000000000000000000000000000106d623b2007c5d7128e03e540325ba763e992a651e2e5c78936f82ee2ff72d89a1a914345486cd0a04440c75beb190b000000000000000000000000000000001847348e5ef429cfdf1ba4d265d8c5ebcbec3d5dd4611ba36e2754fbd3d327273bf2eb7b7ba4b3888d059dc87f034739000000000000000000000000000000000bcb0a9dfe5189bc965e9721407b4cb3ed4171510aa4d4e5d5f0823a1c2827643e1278f9c0ee960c54ef8f6c208eee7b334582482a9038ab906880e43a4a9d39e73b6c63604eba0c8f6399eb5c288638", "Expected": "000000000000000000000000000000001205b70b29ee04212589f8a70a71e004f517d3354e714c1b4fe42cf93faf1a8ed40dbc1b5089ddb53bb052c9cb74c0e8000000000000000000000000000000000f619082734dd9de653b61cf2fb927199f228637db70797bd2a21fdd48b6ecd4c4f712097037534024880a436fdd63680000000000000000000000000000000000592eca560be6ae256abe1796f7ec394a8085c127437f6590c8d41501a482c61456392cb320b9e801044dcba7802df9000000000000000000000000000000000a6d20b8009708ca01a274aed6dece732c5eed5aae5e4c2f3793b5fa1f8cb8c95037ce387bda2e7476e9c493507c7fbc", "Name": "matter_g2_multiexp_99", - "Gas": 293920, + "Gas": 240480, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2multiexp_(1*g2=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2multiexp_(1*p2=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2multiexp_(0*g2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2multiexp_(0*p2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g2multiexp_(x*inf=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2g2+inf)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2p2+inf)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(inf+inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000158d86d94d3fc700f62c8cb601dcf7764e6101cbb8de01f1f7b55fefc5e24e94f70746a7e653f3cd36e70f6f9eeb19a00000000000000000000000000000000017ef47a5a61b00edf11c076760ae3295ea98f5ea8e883133166ffe1e9c0033a3fc3130568d60fbc4ca34dd28143340a90000000000000000000000000000000018a20502ff640f5ccd4ef40c5b2536862bb45dd6d399d32ff4690e2470249ec3f62e5adc675b88097960810714aac65b00000000000000000000000000000000077c18d5153f5fe43e1cad6627c4cc91b9b05cc1f1661770fe873c5bd414ca06f6a660c3b1242dbb7658fbac2a4ec2381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000003b9f634aa9bbe5f1f1868c851ccb6d73772466f13520fbe90ff62ac1a4e9dc259c34f52a8ff80ab0d6e9a5c34e4b6880000000000000000000000000000000000a4e221babe00556ded0646a5dc2413eb0b9f53901ffbcb9828af356d7edf19c92161a3a0f2928260dac7a3748051b2000000000000000000000000000000000b832d19041b8c20daab73c63d140b89cc85b0e93c3e94ddb47c50f4551bc27ea73a8efb29f49a1ffa728eb284d9884f000000000000000000000000000000000f9a7b4a2d3fdf73bf527e56f711d5a774e49c39872902f2504e75548378c77a60d563bc80462a50552ce665327c3aeb", + "Name": "g2msm-1-jwasinger", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000001f3f7d6493293d421c83eb753a4a2e951d9b64841bb6aad436e87817fece70b87afcdc7ec0689b330c71462137feda40000000000000000000000000000000001c672bc28d52311f5b2a5dfb484f2de97da7b791b7280cbdcab636337a8c3ff92ef032e972a9cbce94076ec7a501df1000000000000000000000000000000000cefdd12c2460bb7a6abf1c562acee8a37aac4e080a3a181c5b2a7e4389058b3706d96895e7fda4843de4fdb4e24a5ed000000000000000000000000000000000b28cbe334ba5304c21c79adb2df297fd160cbb44e0fecd63164e7b77b5d6f313ad145461f21ab40c978bce695e40f5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080b4f0f275a065d13ec0757df5f9f5ccb6853690902202f06120b3df7438e62ef8d16dace6e5f3b2fdc461b707fe7e7000000000000000000000000000000000c9b3aaf853954089743824fcb7541a17d25b3b4ad821880280103e62429efd1b450df5636b1886c90e6b9b44049c7770000000000000000000000000000000000efc2727c83b7c58685632373bd043b1cebeda8ca5dce4441092b02c4d9f115e026602f614b3610e9443121285057f3000000000000000000000000000000000f674d8244e3ad6e0f624b9fafbd04da8cca5c0fb72a1029769f702295de353a05bc722862871c883cb0d33b6e31ec131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000140cd965dd0f87812f9dae22df3c53d14f957a3c72092653e142a2776d7dce04e4a4a398155a72de4ebcaad84064733100000000000000000000000000000000152bd340c9a33466215173a7e46c9741f7bb938bfb7c4128eeaa47952ab5d1ed78c5799026d3f3eb3b94876a1f4bd175000000000000000000000000000000001896288360604d3a63f8fd2d9da480ac11c1231f3d6bb9644a34aadf028269fa2ce10e04ab6372f9eacf21af01fa05c9000000000000000000000000000000000fa85a31024cbe2e330f3bed313e028e80a37c45578c429f82c4d15b3b3aeaac8cde593b35700357ac0c6770148ce3be", + "Name": "g2msm-2-jwasinger", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000012955d833439825eb893a3d4ddfe5760dd48d620099a2b18d9cda6a9ad219025bd01db7672047710d92f09403c2b742f00000000000000000000000000000000192ba698fc0ec408187c156e4de78a475cba4f40fa1a707b4a845cb6160ee09e84a7ecc3569f9620895d2e50885dc35d0000000000000000000000000000000013a841e58ec34358fff2921460f9fbed16d68a838a64219392245642c33e61f9cc9b53bfe1489f868e8dc9073d8747bc0000000000000000000000000000000004434fe1406840cca10e0d3b172d8ffd3989485a774f87761df7a3e162d7ae1f7eba45a52f34b5f4b36fc1759fb728251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dfc2680bab8d9093e90c5324e2762c988ffd2d687aaa4c12f1903b468503a70cfe034e3e1e09d4a99332a7f7d2fa0b0000000000000000000000000000000000fae3fb5ca951839ce3bfb0da111a528fb1f8f869fa3d855f4131849744ad12f6dba88b6b22a8b41936dfef7fdc4f6d0000000000000000000000000000000005f26c825332db72e845d750d67db486d5ad3ec46fd0c138e88a01d878bc3074e4394f206b1182b96996926bc3a602c70000000000000000000000000000000018527a6c30b6f68e9a288146aea2fa4ca6cdf7e3f0539b37918f6e70c7ded725f0e1b6991858fd14b6df169cd712fe6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec5b78fcba23383a949d51c7fa511663a72e5e9c3ba97259dd1cf5b69f5775bb071c9ebe4d3557f3ff9a799a90985da0000000000000000000000000000000010053b3de4e313e2a2f3cbf6e53b62e9aaf31761fdf9ca1ddf784a0a7932fe219309d2fbf184dec516d283e0be02f5b5000000000000000000000000000000000ee6c39b3cd62e89b9c1ac3303acaf53c5fb15ed565eb4c7a0471e546610e1dc1e431a26d9e5362535ccb6c91fb59202000000000000000000000000000000001374bf0d6b58211fd62b6a2e674166044b8dc4c237c2ac28fe953e7dadb5a8ec128d2ef25949da1ca5d9131edcb8ec1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000011196b5b47439a23c884c0a809b7dbaab0776672b5c7f0adb2ea5477a731cbe9b2e0bd4a61a77f3bfd8739d2cef8bc23000000000000000000000000000000001647a9e8adc1d49f81a8c3336002925d37855e78ed9641656a392613f25f09b63a03563f6f169c4f208129507566c28f0000000000000000000000000000000009e90cc8f0af86e710bc9ae232f17a821d09ea9fba7bcb1f1103419a3eda7a04f99d4ad4613c5bfe0d768d187595958b0000000000000000000000000000000012258ff09fdf9ccf5727768ddc007b425e5f4f4bd93452d9bf6e3302aa9ff83ee59955a9dd0c66eeb09c47f18178ceae", + "Name": "g2msm-3-jwasinger", + "Gas": 103140, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000034887c26f5c3fcf41e4b6c823ca04b7f6bb3daef74a2c144e0e7eb7c67805b9d22eed1b3cc85b1748a9aa55c700d5df0000000000000000000000000000000017ea215ca57751c8959c5b24e9357b3d4362b22c8f8221156c8bd878ef04c9f5ac933783f50edc2f6e00b1335932e5e70000000000000000000000000000000016c81317773b0089f98201dc34c15512859170ace3c5f2ef2fac285df27c24b261ef8a53615ff4c4f07668d4a1a3144e00000000000000000000000000000000151e1f3f6a122d1aa6f70bdce5b155a8a63727a95f4d47cd159529155623e184b3a31a1481600c67d579597577dbd9141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001829dc871ed0ccf6a3c64f91c32357ad63c81cdca6ca9f73bbfa203d3c2f1288ef8f2febe56f32dc4fbd465dc19e63de00000000000000000000000000000000021abe124ca0135fffc9a0ecb1d1cdf4166d8119bab824dca6b980587420faa0a9fcc96c4a8e4a7d803a60a6862c5a7f0000000000000000000000000000000005e4fe11fdf781275b73e60a19a92f986fb5a4946386d5addde47d4c126968c57aa89a52cfac949045ef4933ec8852de0000000000000000000000000000000000c38b94471eddcff4677f91ee3a91628f19bcd7a677f092ee8311b1418b7cb8fd12d2d24466ffb18bcf4a6d6e5a21231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001952d3a09b2645bd2a01e51b8827bdd5d95fa6731fdad1af01650375f750f1c0a2fd792d953e2fd891e687e279209f600000000000000000000000000000000138cc5807661294959849bed4ae41a1e8b3ca1b79e21292aca549cf53f164696a542eaa61e37045a0b9dd671ee2102bc000000000000000000000000000000001619f340ac11abf2531d44c3a5a6ba0ffbdeee769be768edb86bd4d0eb65293aa8166af3cd5e863f03e7cd4585d5f2d20000000000000000000000000000000012d57a6eb9d4e8eccf0a4827a1b4d88c482b0cd59340ecac9c4444275cf8e09168d4b399538978c4fb77dabaf6a3edbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008882034cecccdbd8c4f2f8287d3496c4d6b1e31042ac8cb0c0c0beda3107a933d8f630607970abebb6c32413bbae0cd0000000000000000000000000000000017f66da5b28f21c8d29d8cef1c84ec6b66c387c5bbe86201526f61e6f4cda43d949c0f291f2ef6e5ad407d92c2649dfb000000000000000000000000000000000d5e6c4bd580f345930e39da587fe206dac9d96c0708b7abcf80bbbe4ee999e139c5b25964946e65f4d20aee7381ee9f0000000000000000000000000000000014d246f0c7f806861f890f1466b4e733804f2d647a133cb1bca2a41fcb0fd56192f5cfdd19a62fe8a14ec05aa184a4111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000002e2f0a92817ef3c58396993b0e467c5dd2840182da56ae69dd7c435491b3e8a57b5b092ae2189281462baa6c02577440000000000000000000000000000000018788afacecd0e2f5907d81074a97bbc4f293776b5ffc54c89d4b3aac5e4b20e68b2d3ec220ef42ec406ae1c18090d6e0000000000000000000000000000000017638dc3893ba2a66fc9e0f3055a3a5d44d36678a4e1a6d3475b7e58eb8a911b28feb1ec42a669bbe3b2efc3b669205c0000000000000000000000000000000015709e5378f7029bae3df1be83e7df9d072ac90783fdca4cd655e21f8e1e027ef06e36a49f7045230906f0fdd0619679", + "Name": "g2msm-4-jwasinger", + "Gas": 115380, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000264b8e6903cde9b853b7f6d147c3a3cafc37dce033b2fabebf812aabb024b7ddb479b347cc703667abf147622cc717900000000000000000000000000000000007fc8ca5e0cbd126c27bcdb89f6017af6e527368b74562dd56fddc36efdb890a8b6ce76cadd2ef90170e4f56f3b1dea00000000000000000000000000000000148a5a728d7cc081384160f8dc35fc9cf9df8700759d619db548991924eb2f5e794e6ac1947fafc0f00a3126f62c882600000000000000000000000000000000015ee82faf674f3de7da345e57145ad8b1c0264ed15e7c47fe73719759127024bab8ed56dc63180ebfb325bc936c81f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c77818e372824dc38d94210d10f68b3a1c09c05e95a85f9e37e2d66acc7d20e79c786d51f586a20228dddf893ff1f0000000000000000000000000000000000334b81064fdf6aa89b1abfd0668639c59cd953d5d056c37d80eb997ae7477928d82164c084bc191af7f266b1b6a499a000000000000000000000000000000000fe8cb86e2cf5d5f61d2a4a928e3eea222d6d04eed35eccfaa86ea7ff7367766622bc95b2b38f82d6022fb1e8d51e0090000000000000000000000000000000011a3ef26f6c283c089b11c3f4603e465f122e7e46141e8370435431faaecfdded7c818d6da4055db864698b52044abe41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076a1bae6858691e77777cb47d827a392f013fc3d2e851a474a0cfbba57f722f8832f1346193a93555ea2d43e0620282000000000000000000000000000000001485e7ab4a1c4e92a31614ee3ecc32baeda2bc405bdacc916ed1476f1909642a0831f6e31ab6df57dc071dd1ac09bdbd0000000000000000000000000000000004551a37a27f0e8bf915f4d5e93f38a349b4b652f9a603fac21b62668f62d1c018b5f614c0f14ff3462f24e1d60a3a22000000000000000000000000000000001144381bf3e4e6a1e6774e7b8cc596a98f815a56eea4f4e264181d39edf75d903efa2dd7563fadd6ad8c3021b8c9e5f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011083556bd3f8638dad279a2cea30ee99e9cf7a5f0a074be6c475df455618ddaac84b928d1453edfef55917c505b31b700000000000000000000000000000000153239eca7f451fa384fb7becf009fd5b7bd2ca95fd23a1c42c9b0f3e55588f31cf2f7c20acda746243e61a6a68acc7600000000000000000000000000000000021c3ba5d1b1959f92d48acaa7bb40780dc73e5890bd292bfe052bdac67463f78a466940e9fc4445809aeadb138941be000000000000000000000000000000000e7b12ccd28eb4c20cde041035e6045ec6e0dfee905a90efa0a0e09eb7953552427e5601511b3adb19810bbdb96ebede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c8676b23e1ec143a3f7e0e790cae44a35d43d271380c0a72f5366cb74945f4e15ae03bd70600e1573ad44ac0b677350000000000000000000000000000000000fbb98e64634c44fa8637a2b88196ae9e781e148ae763fb46a54acd104b81ebe600fa38471378cf8d8ee975ad41aa8f000000000000000000000000000000000184994efaca59e5fc9061029a072994e6a4cbdc5c060f890cf630c1212bc4b13e79b2f67ccc1a2f7a1ef1302689223500000000000000000000000000000000068bc7e51eed6639bcd29da806227dc36c635055806135516aa6e497d52263fc130ab70982268213a19515a0d378723c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000b9622dd89ed150d7644fb3d6388bcaac3c1b83f3f14f0f0b41fdd9b5cdf3cb88dafae1dc7f093ac40324001ad6b4feb000000000000000000000000000000000710b44eb17a94c7374e7d1ca6ebdccdd09ef9e2e6a04ad1ede1676961c3681cdf8926e6b1e9ff124abf1441b72822830000000000000000000000000000000001cd993e8997fe74746cbb2495236c2f1cb60654832505ccaf3dfd4eda333f86208cac0d47afd11e3684a15e45dee13c0000000000000000000000000000000000401204a6fad559d9f80bdb5e88255368f12d8155466aff06aff9ce61375d9138acc6fce5ba43ca18a8bc67dbd71f0a", + "Name": "g2msm-5-jwasinger", + "Gas": 133650, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000003c28b0e784c0bb244f4aeb7b7a50c5b19fdab2231e83303894c16f96d14a58e913ea14082a3e7090fa02ab805fc8201000000000000000000000000000000000a1b92586d69dce9343ef029dae1adf641321ca3a1735eea98c334830c5c97206572584c01756e3224a821ac0da31a59000000000000000000000000000000001179e11173afc532d2535ed888fe9574fec8cc0973ea480ee7198d90b62253861bedb42ab61df556f0a96f063cc3f672000000000000000000000000000000000014081b26b7059c71dab11feb84942dcaa645501bb45c54ec46bc9d0f0daeaff5718149c26eed1a2586b840de48cf4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e8e05fc7786caf9eb246b98ad0db1ad087c64295c644d8d7b3664b062df59196ee502573c897ddc9f5f802da810c610000000000000000000000000000000010f3716b42ace8817fa1598b006ee09ba2b722572778acd13f09aa338a046c90183f44cfda57f279815e2547b4105096000000000000000000000000000000000f7b22389505f89531fb39dcd5a19305907df6bd07f838d5e5df07deaae5f4690d5a80fd0e31d2b00da582c09b318d36000000000000000000000000000000000fda566ba950611732fa913093ed4de14d9ebe7d464c3ab9d3e454982dd73d061fc514d718db01e1f23a21e8820b5b991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6f7e4922d351180e1837f120ae4e24ee16b25319c6392a1b0760b399cb9324ce32322797292e10e87cedea04230ee000000000000000000000000000000000c16431b689d0352afea68f471810267c7a150f37f023d1e5fa99a1ffeafd52b6349b110fd9034ee1757f6cb62653fda000000000000000000000000000000000cb68b09f6b8664c4c7ea111ba4ecf215ce0ba778fd21e26080b754ce3e7dacfaa1f404e270c66a6563423a731d21c560000000000000000000000000000000016c851bd4c7c31d026dcbffce810ef65f519e047496729d853f61f48800a0057cc7b19c62c7edda4da979334cfd94fd81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d96db38649a223d3934173c89879709b9fedba7deda40755731b4e6439942dfcdb3b1ccad148bee73e333558e9a3f000000000000000000000000000000000602cfc2fa34b92bdb6ae12abfc12446a076924fa685a0b0a3425019c087c9bcdcaec7b7072348fb8714afeb9b9cf919000000000000000000000000000000000341350b4b583a014871ddd15cb1667724ada0515a4eaece6692290b780504cd92a3fee6c90d6170ecbf2d5858470eee00000000000000000000000000000000141a45f966ca47d33f352480b9e1cdf5aa3e64d8c64a287ad29dde9a00a2421e7d604034614b90089a4e7a98daf7c3871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010605c2ddad43cc6960723b6509bd8c69aa0b92e886640bdeb592d34eec39fed15595a518f08c0ab87670d7fd75cb15c0000000000000000000000000000000011163e5f6702fe70d4b40aa76dd37352a09d5a8771fbc891d469dc3a3c8be59824a853f226ba80d09861a757451af3e7000000000000000000000000000000001184335a7f4c179727827670e21279bb5ae3e95eca61bd73e4324dd29a2c5eee159341d2bcd8aecd2aa3595718bf51690000000000000000000000000000000000fc8b8c9304f1512a9c8106bf807f8f7503b4954e9e30ad6aa1623349e59bc5fede56d5f1b6136d212c6c8147ce9f6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011ad0b137b369e1e03de266fe9a50fd643a5725ab49bd14c5a35ac918dd022354dc138538018f2096ec129104925273000000000000000000000000000000000152b72b88b7ef02ea5131b256a411cd1775ab63e1d1bdf6ba29ca03e532a964d407fb6149b11c12db0a6fdf371691120000000000000000000000000000000012f4cb12482d070c03451d5beb9f01dc3d9c4aebe5a6d33d730e1a3b1259e7fb038f6d34f8a377408eb76d4744a4489100000000000000000000000000000000182eaf77de135051f31fb43dfc13450173983628fc956ad82140b22ec8b8f15441a526c90d796a3b64fed0592f0276291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000012bdcc0b1abd50c9389903ded99facce7ba0675a2101428f8d2632cc67304c07cddab92beaf5ec72605718604ad1bc8e000000000000000000000000000000000d489d7255979de8ce345cb2187cd2ed0308bbc3ce3d567365829cd99394edc3c77db561b1daccb9744338496cb8ca6d000000000000000000000000000000000da9c3d2e7cc60a2b2e39dd3ccf2f9552dee00f9bb4b578fa99c0c4042b1bb1735f3dea8d421c7e1c05450050fcaa274000000000000000000000000000000000d7a574aa832a8e388180ce22d1de2e1e22e5dc475f7142a6ea91dbacdc88577e2d4e14fce96465c6a152a878ac6eaad", + "Name": "g2msm-6-jwasinger", + "Gas": 147690, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001568b92db6295c37f458af466eae1c494332a6980a29076bbdd3307848ad30e4fdbb2d8af58c4748763c28f0729ce4e30000000000000000000000000000000012d5925beef25addd1cf1b698126ab62b315acd1f4deb017ee0d04d14d1f76c78838b3dde1a09e8b2acb22d8857d84810000000000000000000000000000000010f7748e4119b43556445137ce528ab783c2fc1c8760c0686a17965bab9662e9808704016e6924fe2c92cb6c3794274200000000000000000000000000000000151a2661adfeb23f6e9f00a0b6a0f74b79cda8eee6e7e146901934986613dc50127d6b59a161f3b0f522d65957a3494d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009712947b359bcd80ef6cbd93e00a64f77a00a85d8884c029ad492f04bfcc644f619e1e1b72aaed4843f3529ff36c699000000000000000000000000000000001945ced21239e584a0387da586bfee54b780691d2fcab64dccf34d71501e0d8d91e3581ff5194a99bdf58a149f31e84f000000000000000000000000000000000aa17236fc61c15b162505b8890e51a535cdd3d55421fa770eee997e0321fdbb0ddb7fa8a0b3854440fa3c42904f9a81000000000000000000000000000000000739c89fe7ac697a0f0204ca6ec6e809aa838524de3c1c3021c0d19e1f04e988d058941d43253b836de5e783aacd7e351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fbbdc17a4f5cb310b2cd0687036a4f968e72cb1f017b055c89989eee9e9e2e91db5ff84186e217346855abce33d990000000000000000000000000000000000f6eb30723f5975f9a79541332ad9a5e153e27a5c677f32b67c19713b8c6e347875e1f5e5b9542cde5eee0f66002526a0000000000000000000000000000000008ddf6c1f70c8f94643f85dca5afb344862a93ee5add41625861734848f0e3495a9dc1cb2c8c2d28aef48f12f68eac4200000000000000000000000000000000120afe3fde19116c36085a2d772af34e5499ca3eafc2f6fd6e4d58f16c1bdc895cf4e203155bfcea1c8b35e7b64dcd251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193369de554724ccd465adbb18f150f21d6def7a3d29f0a14407d9f5a8bb43b680b76cbf2904beb9668b55006aca587c000000000000000000000000000000001920d5d4077a24827c328dd5e8f4c9b77d47d3f1e22b33025fd48062ceb2d2cba18dbfe284d3347c9f7410a13f2e0d670000000000000000000000000000000006d5f676a9122459516b3b0dd88c9ae1ce682e81989a8aafa5af304d65c84db0e529c13fc1a81c09d80685af94230f3b0000000000000000000000000000000012bffa58dca487a6d8db92417ce6a56abc5ef22679533f9cba295e782bb8fb6cf08b342dc69ff44d69544ae4583938401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ef3b8290f8b747896421c775add14710260fadbbb7c9c9cef6fcf94b9284b37601adad248f3e9671e380b7176c7a9000000000000000000000000000000000b4de709f6b68efd9f9b2d4a0d4bebdb7d3949c2abcaab2c55b296ce9bc7794cafddee83d96fd18c577f92442bb31aed000000000000000000000000000000000827ef6bbcc4081fdf0f58ad097a0448749f2fa50c7194102dff18f1ad55306ba9ba7bebf20790e38e8353517d48a3b200000000000000000000000000000000094ea63e52ff40098c2fe212edc93a1f81bdf804da9ea0f930c79d733f3b100414523c8149faf3fd8b90b133010be1561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199c117f57283df4e23d9e75d150037f67e48add03fa07b474b2ee15f4d9061258118f135471652506c2a4a20ac3ae4b000000000000000000000000000000000777bd3743b8e43955ba3f62e1f27c2df72ff787fbd69a25841b413c2b33f213212284833be11af2e29c6cd7b5d4f6210000000000000000000000000000000009e129f8c61bf518bbdecb3c87d8f82b8fb51c5644e9bade9f83cfb09e74ee764000df01f8be72cdbf7875fd23db803000000000000000000000000000000000109900bf0b6b0a6187b3f57db279f34973d6d1c7bd8e0bb15c27154ee6262d0993f86a9e0738954a6bf6fbf4ac54b4fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ac228ac522f5346dcf9c904724827874bd4fa988f9335bfd034c0b4266bd8e3f038ebde74bcae289e25a20f208cea00000000000000000000000000000000157daaab922bd0f73d1d939360c69f11f06b4d2e08d6268df2521c2a28cf27d9b2f361d5051c0f6c6d10796a9210396d0000000000000000000000000000000002c39192261482337d32fab6a97865eb32d10f04401c760f6ff8da444c25219793977a3f9bb7a64516b407b07c38259400000000000000000000000000000000079ab4c19fb32a14516e55048ae47e3b472925fba7e0e14da9288c618b5160cb58cf387c859169bed3b7adbc957d2bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000012a89aaa5ca532374c26dd42588c6aba4b2257208fd39226001a462216f36ba62565ffa427706c194c1936895b79fbef0000000000000000000000000000000008b26eee687de31a2447034696aaba5246d903c5e91b6e41a685ea823cb47ea4435c2ea656613b60a0a9bbab3ed3900f000000000000000000000000000000000eb4e9259adee74de0f091d201e6ebc39ad57cbeb007920fd7b32d1e2191be06735845325ae194c2c74b9a20bf07427300000000000000000000000000000000044bb10e1908f5779587f03ed1475cb85667c472b147c216ef297f240ae8b3c0acc21e8ad6f556badc3a78377d5a6d4f", + "Name": "g2msm-7-jwasinger", + "Gas": 157500, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000575ea1f8933e5f55fc5ccad48f195a0da35ff7ca84b8b483fdfc5ab3e4acb73f1074444d43e8c49cb5c555924f2e93700000000000000000000000000000000004cad6b13c7f09505f16e16712180063285918b1219bb9573413ea1d145ff9ec99601d6e7fe95af6edae55b0fc66c4600000000000000000000000000000000093e948124e2f221072f3711a52acba600f1f91d45ae41df55779b8f1f800e83bfecae3208dbf820259dc1ee76f747a900000000000000000000000000000000139a5f3f8ff4441750f4cb325cf45c9fdeea444aea56ca5c9c7e18f249c91bd8a7d893e53df72237a10f3e0048855ad21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045595c3980dd7a591051aa17815635cd625aeaf13ad30bdb5b034d4068945f88645d58ad79aa9781c1b86dd8f022862000000000000000000000000000000000cdb542b7c6645599d126284ef1a2b2e58e1b2054bc676db8ae97f623e2ccf37bdb02d8b6e2fcf2d6ea04de12256469b00000000000000000000000000000000014e1ef7d3a85eec28a763ad5d5b70e4a391f24cca27cc704be084325f1e2f6703e6dc670e5d5a6ea1040fc77ae9324b000000000000000000000000000000001013fa3ffe53d4f310d14928e8c71f946f5b28f8c7b318808c7b352f0e95cd2818590bb8e9512afae75dbdb72dbbf96b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d8b19883c03b99c6362c6dcce333ee1d22255e0bcd0568c0755b60c63243062b9dc587e675b5f5527e05ba8c7a02890000000000000000000000000000000018ecd7994e99a01f1b6fea527c9d3e9ddb64872bc519343853bfbcc0de8ca36c64f8d7f797a04aefb614cf58ad1b812f000000000000000000000000000000000280de32de8d34b3e0a2e81383d0e4b8dfed65bd5c7d260112d6bcf3301dbf4ce8a86cc705c03df34b1e30d7ac8a7e540000000000000000000000000000000019cae4d6a686fb66981a69b4c10e3f991a74b2857b685d396075a97e639874998675c0ad274067c6851cba90653440541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fd66351e373bdbb9436099988f4f27f65381089396ecc641c2daba14b0c058e10de17d7d5a9b73345dcfd47738c4400000000000000000000000000000000012079fbcab20c102f74f72bf8de614bc4f8f995fb70ac5184c3c3b465533708720917b6600d92728a77a6ade55f5ff3e000000000000000000000000000000000a45023e39efa97008fd99c0cd05e05022ad007fc166938f5a5214194603f7b4302d675402cc1c2f56532c1011d91c910000000000000000000000000000000019a01ad236949b0b09037538063d6915021131892125383ba16d2f27837df5de0ec68f413afa9cef1c5185525326a8761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152600e1bbdd1c1b39f31bccffffbeb8d555b4c36372f1fed0d76ed3fb0ee7ac3e1868acb15e235b56522b51f71511900000000000000000000000000000000003c7e41c5928906e5ad26bd4bcfb575321cc1461126faed835b1cb578cd1b52ea83eb1d9abdf7141cb0ebbf5031968970000000000000000000000000000000005ce5b2e43f16380a7cf3a5a61f128800118784f3d27f4d8b525c51704285c3c93ff05c1a39f9ab272649163f138abb00000000000000000000000000000000011ba10720e35c7d9c67c3b86e9fabf64ffd82939e27d5c747890691cc49547a5153e5c32b63f8515d47daf2f67888e501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e19a37aa40fa653a1dec08e719d27dc138732c5f6f7499b852ab3a1625e372d1249d5493f404eed1bf9945dd64113b3000000000000000000000000000000000269294c8fb03e274b3b14f9cda3ffab5051542d71021f21d1f37266ad528ebc720c27024c97d6bfb7662a2d4081ce1f000000000000000000000000000000000941fd8e25bdb097fa74d5a4b6b2b7d067d56d93ada09e1c8565961747b3cb1a89822381a6ce568627aad5826de57d3c0000000000000000000000000000000008327f9bf13158e2ea8b03eaa2ce779fd3b326873dd9e081751c0eb3e9391015685d363921018943918370552d4d4f991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001108d1465cbffaba39c656b0dcd6e6b57503de65de2b78e17928d85c491bc6e5e52a59b1c6c1a4ba7ba0f19d784403f30000000000000000000000000000000009f09f6929e664fb8478688c1a7521e775419385e4fc2b7f0753164bc5ca688a6b258fcc42adf450959748fe606784ed000000000000000000000000000000000e2e60f3bc28a0d2b2304f46bea5fed3c46c9b7c8feef3432e40fc3749159b076f25116ba508b0fbc3e522d2baf216ab0000000000000000000000000000000015306378e771b076dde6587595cc9034f424d63cb21805d45cb8953fe06141048f8f6d7a983e89d329ab9a6deffc51971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e8b7adbe0527ebe07a97e53603f72ded2f53b50e8ec63849c858119cea23be3517227579e73c68fcfbd631663115fd0000000000000000000000000000000003de60f3e9eaa460637b693daa0aba0b7a819d5084bd9bcd5714eeca0538ea5f737756581d9eb3787d1d54f8fad2655600000000000000000000000000000000128acb8acd9be6207516a91e0a33e8489ea5b23f8edde083313deda2efeab74d0b3e6a38cf0d9d3b770950fdb4465e270000000000000000000000000000000014ebc2a17b6aab8264e824e70fb8748ea812e7ea7ece5b14f4fcabf51ae492b3c0618d309ca5aeec168b84bcb6028d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000a8bad24149f85c641f9ece6e047ef5814be0fb078e11df9608325f836737d58995b8b6e616dacd1b7c978532e0880d0000000000000000000000000000000001153ef4fe4278ad03c1a435b15aed7f3ff6c1df8c630e5670337dce06a6c55a1a53c52ac1257d96799449a04b4fcd9ed000000000000000000000000000000000b61e5f1e81c7a07b9657133c5aa033e812494ed2b9bc54ff6f5bd7c87955fdac77aebc6275764c974978b38bde1e21a0000000000000000000000000000000001e02d5a5ca3334a2015db20a933fda95e1fffc018193ed0b8c8548bcdf6b83b2055831f523e3826ac74d1a7317b14f9", + "Name": "g2msm-8-jwasinger", + "Gas": 163080, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001621f0d35f31fcce74617ec24a1482ad75ba0789b0fdf77a88c22dd1cecb4de349af00f7aae786d58f961b148260ed580000000000000000000000000000000009b09b16a22c62519d577601b8bd1290da4203f07ccb2d7b8aaa3b871d089362cd6ce1e702b9337b7c9723c0526fee9f0000000000000000000000000000000009f39d9b34bb0146fa90d238efeb6c7f84b077fd84649169fcc279d1863e35a0b9b8f9e78d41180dbb017b718f10a73500000000000000000000000000000000190924985457ed18019749c2203c853d90ccafdafdc0daf60a0efbba8b8fa3483a3091da0d082075a579c6de85f55c0e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165a09a80c33f5330bc74850e219e0e596eb0775555c4e60a52ef6ed1685b4696af225f179317a0cb9b34e153f41878f000000000000000000000000000000000edb9f192d3a29fcbf0aa47dd7509da9e1cc8157f679e517a20b75d2201b4cd33c77c2143134558ecc4a18621e93a902000000000000000000000000000000000f0a96e6791eb2a3ff16e24841f281b9a97867ab50152d91cd231003ca27b4ae619ad50c6bc66ae27c87387355eed1910000000000000000000000000000000015110f325518a5209e6a1af8add3fa7d6f049c3fc39e5d1b2b0a875cbb3a9f5e28cc1c2f4dba0eb13a28f2e90d3443d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e4704c71440c2f02173335834d75420e81575e6d48ea22d1f98468e5a38ac437180a2637175040c5756c9aeb276c7f000000000000000000000000000000000f6567cae1dc0099851c488b5021c1ae1abb89c9a2f4e7cf43697f2028c70fdd03bd35ae85a318a4b54e881a22ef64dc000000000000000000000000000000000514714b7ca31130e691ec29c263e97ab07df083962929bcfa66b7f924360ad02700fa34f28774a452eac57b995fd82300000000000000000000000000000000025d5913fc4854ab584998dcc740c98ae35f96246f3b19970bc2e17dc417f57b969fa741cbe7e667556a3ee1d57261311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a002aef2af04d7c6d7ac63fb6edb72bb234cbf632d74d43d9c5f231084a0908192f265001f22d0aa5f5129bfb4d69200000000000000000000000000000000002d285f983183ce7e6de746da4d1d2f1513afafba16b813078105d06db6a096dfc325d465998473e86b05ebc2c01262a0000000000000000000000000000000006ef7f5be82136df386e66920d7d9e8009a0b39092f03c6c43e2393f08f8bd95db151f45bb15cf62883e580993aea81e0000000000000000000000000000000016c73809dd371e997a90bd9cb75b439bd93ebb6865ee31b0864fe4f45b79a7a20102035bf5044bf67803b8e7684b16501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000059957fd17f908efb9dc4a69e50d35df422585e2d3fd3d47155b87cc5d8b083631fd735926cb74d5c610f20822619d7e000000000000000000000000000000000da4b42060d9a12441735659893d5c31d5b94b5e9afc85a7947a82fab47ce90f4c598b29a27c662e126331d7dd71577100000000000000000000000000000000003447ec2ab21ade701eddc7a8e9605334f45aac2c9f45d1bfc4608322fe175e1f4d70764cad5f339d91ff818c0667c300000000000000000000000000000000060993a10a1856cf73b64bbdc1ad2f0cd9ffbc6e97e515afb0c14fb8b6a44d7407137bdb17d877785e893f286a8f27dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3326aee61077d4a020721754ee581235c8fe821463b3127bace73e6e4270033badd7858fc7400fa8fec9275d5683420000000000000000000000000000000007499936b653675f6b60acdffe500856c645d1d2c57f71012c188e6fc67d045f12bcced5f8af389c00d6dadb59d019af0000000000000000000000000000000014521e78a2ed57d798a990da4a62c5ca0f375aea24d47001676e59c2e089cecc84aaaff6d6a4d8718c098382f678c0200000000000000000000000000000000016410b170eccc178224c4308cdbc26653c7e511a4e98ebc8ab15c34b9dbdf9fe81237614df77ba59ea3fe88dfb4971841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000104216a309450ed821c26fdbc0b3b3617dc865f20969ed176c2409a7ed4a3c3c7f45c28e740c3fe06d61ead435a750300000000000000000000000000000000080ace8581134aa7c459826ef51f6e75f3a9562609fdd525f0f2d7474d8c77c1ff5a8258aa4e1a5b3a26335caf3e1ba600000000000000000000000000000000084b19b0de645043b101f6bf675b89d3d015a45ebd50312a0b4c5b5ad7221b7c1d513cc809262e5aa7b2b3b6807668c3000000000000000000000000000000000edd873e1689a60b3d0723aa3250f438c8fb96d74358e692a2d394d5cd9f25c84a125faae13fa3636dc8fa1da197f4171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001947dadc31b975d3c5f91d8b95a43644da6420a3edc85abbc26ece40832d94ad67347a9af59e9a663c4cde3534552529000000000000000000000000000000000cf895c88df23ae1d14a37e00e4bfdb051ffee35083af4c7af2e3a7e796bc0077db6cba5a9ca07773db9ab4d3e1b5ffa00000000000000000000000000000000156ccb455eb3272ea3a1b1081b83055746703cff0eeb34805c5b3989a4acdbef2c4fa55d1721e14eb25e717e9c2c24ba00000000000000000000000000000000189d0ee948b73dba11d65b5a88389c97a9720ed47181f0d6d1e2aade537b4f75c779c7a7c33045d4770857998d77f7ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dfc85943c1e0e44fe73bbd1c3a196d8ebe52dec5f9b33e96f9bfac159533b6dec84ed5529064c72261f9511664f21400000000000000000000000000000000184dc627dd2bd64c20a3399cd92242d177d1b0603b61c85e312ebddd2d58c1360fb893ffbd60db3511345c2c9e59bc380000000000000000000000000000000018370f49f7759cb978ca6313dbc18e4fb9dfd2f1f7194fa07632300e7d6163429a1f69a69eceae4d80a2eece38c9dec90000000000000000000000000000000018fb7d2608372060e6bea3c84650c3242d7590fb26e3d919bbf1a79f5174ec143c879a6df46fabea0300f9cc9394a1601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000000f1ed819d666836c267529dc11afcc81e44e83a4a503879c81a835eeb43468d229d3d6ad210e8c1cc89edb6561bde400000000000000000000000000000000007bf57030ad51243c4da76e66bef2024c0200d2b8a735975946a2086074393748269b6359494a12a98993313ad1529dd000000000000000000000000000000000e8e004b23ed9319be41f44ec4d58b2dc17daa7bf50f51eded2b5603eaa5057ddcca559893e9936969970840b1c3de10000000000000000000000000000000000674ba86e7993e9c56d309de3a5df99f0fffde0e991acb8f1222858b2635d073da8799134498e765d9f8a5638dffc64b", + "Name": "g2msm-9-jwasinger", + "Gas": 177390, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000be25c02ea5c498e387e747aa2e976363d1d0e846673f62e596b964bdaeb5f569276e4a45390ecf59acdeea7f409e3e000000000000000000000000000000001438169d876ee4d793c8e19aeeeab14ae06638be9cbcbe2ade830d8e42afe598c59e762eb8d2d68313ae5595f953002e000000000000000000000000000000000eb493df804325610ea6350d7ee9f46ba32c2d0e7e8bb7f7fd2c14f3e8b912588522fd98fd6f5f1de4ed4002632591300000000000000000000000000000000001a6e862b2f27f1914bba24e3cbb1312695207d1c9fc70d1b144903e371c7edb941881455730097e2253fd1d76122f8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000022fdb3e6638255f2d7289f6e3a0407fba28fcd8d4e8cbf04fff7a9bf4adf229c59bb59bec91c6c379ca348d107ac3b00000000000000000000000000000000084645b242d56929a911c9e3867248b1bf4f0c105f7053345e15b181fe72b7c819575caff968e3b53d9c2432fcc2c8bc000000000000000000000000000000000e4cd1027858b45d04b67ea133382331e6e328aabd2b0a68ccdbc6c9c6140ddefffc9a0e79b2b84c9d17ebc5521aeeaf0000000000000000000000000000000008756525a1e56e20eafa20d8beec1769cd84ca378ad81c24015565c8f9b7f371b48254ab9aa6d3ac02700b772cac49b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096f7a561f19ae8c02c2a3caa1e1d2ecac7a4c8b7f6bc77cbbdd01bc7978ef5ddf1505228cacb5093cf1cd8b0a8ee7c2000000000000000000000000000000000f57b593530d2d8df3f492697f5d80174f170f286833e43bbbc5001356b4b24a5e61d9a43672b0ac8673f781e33b47d9000000000000000000000000000000000b8229376c3daef017c82e8dd090ca268c154b8e8a8a77ce490eb4607621c7fff3d6cc26eeaea2f52fb4e4417fa1c7f5000000000000000000000000000000000458fe40dbca2d845a428c785707a7a4ec05b8731cd064e01a4e138df58aa13ad7e16cc2a87f48412ee2a12b191ba7a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188abb04cd4e91731b30688f8f1a550bc35aa195859549cf505ac4d6fd44f3f38c62ac7adc2d2507fb91112134a98fc40000000000000000000000000000000007dcc5f1a5b6c8f1c27e36195a149755760860782d2da5a865ed51993e7ab601dbdbc1e7c5669cb28fb33a2b221be109000000000000000000000000000000000c6e5945dc170e0885cb29f8fbfc8f597e4a0a5e9bf556065286ae0fb950b9685755bfbffd8b4d0c63fe2d8ae885443d0000000000000000000000000000000017fc476b3af209c55d284dfce74979fdf09e6a07546c76a7ddd0c5c3eb01018a512dea01c1802e76925a882ec9cce1531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7a6f882f9025c37148cce592b2761724ddd51c2489749bf64613cf5723eea93ec37f3c594a814e894607fa509516000000000000000000000000000000000000f4a306f58d80368c6c0bf76a53ded3da11073233b1388b744d760fcf5bfba1e13e509a379fb029e76d794d462abd010000000000000000000000000000000009599f6e3aa840698aeffff5930b5c60a94e3073e9585bfbc8d981695ee9267509715cd1333b0c67ebe62d18c1740bf2000000000000000000000000000000000230ef7858576514567ce6256b9887d9f3d29d8b25db893321f1ecf140349078ee1b61b5efe7cdd751dd3c5e9b8dd7a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad1aa5f390dcaf34f7763fe580a04bb3469b2aed70b63daa31ab223239a44ad694889235d7b540b6b8abc7ac78fd62b0000000000000000000000000000000005694cc9a0079ea096c12a177727df08ad58b93173efb09a1eb4876638b43a55c946b71e490e6c80f836f37a0b04991b000000000000000000000000000000000ed0fe4777908b1362ade390d97e6871450ee7d9a972503a4b7dab054d5cf6a5d4b5ffcdef05fa5a42413adc4e523a5e000000000000000000000000000000000300ae41ebbdb6968ba574d7495d160d72c66e94d2ff8c2ceb756f6225e28184424a0d0dd1255ea0dea760a1630c76561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000811d99bae042fdf2be044e7b456ba056a8338accd05d32275c7c04d52400164e1851c7c202ffe6470adf88e7c86228c00000000000000000000000000000000010f98d0abe29f7a7299aea362f135dd1cb76a40efea8b4bcce060a11b52ad432c196c6279624ce6bf6927a0938f57e200000000000000000000000000000000001a87362c2adb0d7e90b9bfb08ebbc8518830020cca53c72035b82bfc08ccd618ffd00c368cc3bfab9b17667c6ccc4700000000000000000000000000000000116bc061d571eb4a105f29fcc990fae9c350cb46747cc261124271ea1f7eb2c80d8e0daf70eb1550563197f06239bbc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016faeaa0b84257f18bb5bc8be672bc6d48d863acd8de48131aec15f21be9941775b983e20ef06675ea48d434f6c7a3c7000000000000000000000000000000001704979d11998af752d1633420809ce7a5276dcc3b12f2d9b775f76852ae804c05f3a859f872a9c3e0ed40622fafe405000000000000000000000000000000000ba589bb52347b7ee22979cb1a66d0123f438fed02c91fb969c8857792dae814ba15f042e57761efdb9efe9e06b409dc000000000000000000000000000000001485529f22b2b852870bd7d7b949bce855cb39331f0e18838363cef8593c26108f3614e73be65ce7de4beb02d940c3431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009239584f9b79df4953f77774ad8045ed80cb9d3bf3c898c35cc8bce486749cad2f00859f16cd82d368d68b5242a217c00000000000000000000000000000000142af6949adde4ae7a4e64b69e616cfacb0689f19c7d61b89bd1a9ad9df9ece9c313432b526213b4d1628fd087f4685a0000000000000000000000000000000017b56b96cb323797ba88f725fed7ebb1fd6b77c51af559f9e549a10085c97f0945791699385e0b7231c889c9bb58e92a000000000000000000000000000000001327dc36c3fb1b15b04c379af912558d9362789e390cc7a95b9a6ac9e34740300d8c5f3c06c92ca0ea56cd00c23fc2ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a27b190ee24457764c53a326aefe801941444b8ae154afe4e767fb02b8836c00080a3c55308bab4f999be28beaf310000000000000000000000000000000001c6c3af694bc0c4fac3c2f57b3b4c16dfce24a4617c231dfbcd5ad5b01c042de3938828b8db14039865f253b33a0ccc0000000000000000000000000000000015b7b2777d09bc0d839b18d0faf666806110d5680c0f5e15963616a0a5d44355844ca88ab40e9bdb3f413b6ae40cee6d0000000000000000000000000000000005417df517082cc414895ea608a120915a89617e5a27998bb0d84c3d2da6a3092635f7a02e83164c653a0071506afeb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000001774b6bf3891cbded4214b6bc9ee92a87909fd0a40dc3c30bac5f08ab53d186b3ed644ed825c1e7e881d25fdbab221d5000000000000000000000000000000001731dcf5e3abe3f72903661ed31dd8f8e66d9fa415bdf54afac1082ef4d21ea78bb7e05eac2736805a8afc73172bfc5c0000000000000000000000000000000006be2608759b08776e344d3fe093f0c04f963ec35f01cc9019aa5e9e4a7593a9f42ae8d768d60b1cdd1055ebc53d9284000000000000000000000000000000000a55f60914e2e99baa61758d43a6e7fbb499265d2603b5f2458952c596e7dd97588919aba8a7707e20d9e0228497be61", + "Name": "g2msm-10-jwasinger", + "Gas": 190350, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000170ba2b9c5b83714330cf91b901672c659c95ff93b21c7007aed1fbb93097d096c20a96187ab3e79295801a156632f77000000000000000000000000000000001910f1a4066a17511fba37247cee3eb00569302016e74ce655c52a4c6b5fd571d463907d901f6773e77c6534ee6234ae00000000000000000000000000000000152c08b790bbaf46067df8f5def65e2d045e3695845dd7729acec5ee3860bf609197885500861c95834ebc3e7d96184c000000000000000000000000000000000200b959936e0660fbe3453dce595f686fa297cf21d558efe485927ca636e93f9a0bea0afd730ce6d9820bca8d2cf4d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000030e531fa2d3ce4d87b1890c712d881e54e22779f1b7db00d806f623508d5a997a569a00c32c5af12cd32f6eef89b97000000000000000000000000000000000c281190700084d7a2c3678d9ae67bacefd2ae7e7e43f8bb3e15d684c2381f4f4e6e1df446566e00fd9c177df60582520000000000000000000000000000000013595138de00cb7cc7f1df4821921cb2078a902d293d625c3e156e7f0d3b3a3763ee2451a11944829cd18b7b791ce99e000000000000000000000000000000000faefd77293fa9fb19f6ce5b55fd7f1b7c2de2cff08a0176f4f44423a63b4454c39aca4dc7a10b7d558fd951211b6b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb5f495968ab1eab77e9a42dccfe5886e81e20aedb73ec3ca106fa75886675a5e918cd01b6b1f0ccbdfd7993cb61a40000000000000000000000000000000015f89521b26cba44dcc585f464728a0556b11fad52bddb563734fc1cb56514bf3279dcac05b87fd105d615be9ef0d0d40000000000000000000000000000000012cfd925e29d9a8163b2c1b609d1fcba42f1432bf4d222e570bfface3d746d1048ce64a4c07e4eee1280d6436bf37a70000000000000000000000000000000000f1a40935cc6777d51ec6c422a0cc431be6de885f594013d9c2a7ca52f8f0dfcdc85d48e354aa37c533df55abc6c8dab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16837140505bc33f7a508f6bc2a60f434559bff7f8ddd073baf74352c95ad35c530b1239b46a6be5d8571023b4c85e00000000000000000000000000000000088a27dcf4cc2e462c42fb38cff1b9e57ddbaced3d20c687263bdd96931bc5906afea98bb04f5afc509dadb839fa3c1c000000000000000000000000000000000a54940cfd303d07d2c56a79e907eef6a78b7c0ec3ed2f69f461d5d5e04d72008ac484bbfb80300b54adb4ce6dc97d3a0000000000000000000000000000000001dcfbd3af189e55c284fc3ececcc4810983a9898a75fe03e2973a762180f9d4264a9bfcdb21c8f60cd915518a93efdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d4548b7c765dfc7c1472e4439a969350d06543cd6b2753b8428c4907b080773f0ed7b0626f176bfd95ff89d5bbfa260000000000000000000000000000000019b4c05fb99be599c74cf2fa333c47fe595b9b09efe59187502a71b961d39f34361e04973c07aad4befd081366c21471000000000000000000000000000000000c7c6e726567b74f1020f6d2c5c233cd69dd376a5b8663d881335453f711af80ca19021427c1bd023428be15b4da5214000000000000000000000000000000000836222ea956757331e86a9a0699b0ef008a5bec05e5195ef1464b5ff6995b87d463b1aef9c3b0d2c28f0649126df8141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac183d4075b2d856c2b26fed5632eb4eaffe1958964b06c3ab86f2da7be2700ad7c86bb4c0197e8a2a76e7f50f490f5000000000000000000000000000000001695c676b22f4d2d9afc01450b6adeda6acc29a78b076650d7effc02ccd1b1a91fae46ea443de6b9e86e57be6648a2b60000000000000000000000000000000016e30c84efbde796c3a87f66be1c0dc1b3cd7c70a65f040177da67af4a2dadf34c49577bb962ec665ffb6954845edf43000000000000000000000000000000000ceb83a44e92644d77e68237bf4764f9b85aa3308cc012ae54df2e3237d793d635de23bdf2d89b97c22a922d687e90f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004fa38d20e6b8795ca83d38e4670e915c0bd9d2267a15269068f633925398c42f3fe75fbb89ee6aa32c15a9e46ba27a000000000000000000000000000000001764cbebb4c2656c71832dc1be7b45bae8c1787af59f56f01f74ad39182a3a53de209f5620f5fd91126d013ee6267377000000000000000000000000000000000e7ebe80c143673b472f0bde0a6405084eed72b536c4991a20d1a0e9bce6e63f0dea19aa4b225f12cb1c93d5c4212fc50000000000000000000000000000000000b3848dc47d694547b8f954859950d7fa69a75dc777c1ea967623a910538d63f5d648499dbc100ecc84770c1be2ad161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001518e9502ce3b13b7390aa476823aa1cf04205c8bae47212b204f8f5d395d9875d9e918b92050faafa6b3fde5f720412000000000000000000000000000000000cd206e4fd5098630169bd2a4c16b50640ea23ad96faf204fb1d60933054eb2189d3be0d0d30b7863d0a294fd46f56c9000000000000000000000000000000000cbac5151187ee126209a12cf4989d73a49952bd5d24fd6e53b382569299f8c0b5dd4e99fc63baea1d9f76e7e2f70c71000000000000000000000000000000000f5a897b7fa734198caae2a709f0a0eda5fc66a4547b454d855788d131442ede46aa2711d2a59b55fdb5c1a286a4757c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b8ba4b924855323b1f1a83e7e9294ad0797dc9c60bc4c8976a200f61692f0d0fe38998cceeda4b92d88c4d7f8c3ad8000000000000000000000000000000000d9c636c1be4533531703081f055b24a826ce1ac3f25cf97d26ac191a09851544f57eef4a8ab9313e31c9c423b5c292e00000000000000000000000000000000038feed24f8fd1c8adfd6a25eb4c60744095c34f88ca71176c698132ccb14dc781033cc0b575c9cbd530462cf379ed61000000000000000000000000000000000f4ffe09e20c53261709bc3c6f67a784a8d7ca92bd954dff9792db5a83378e4fa72973b4bc5cfe86b1cf39ad73f781a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017374f1a5f4e3b6a4d9ffce7025c2d8237ae7031fcc821524fb7a3fee1cd061c47c3882c7b9fd98e4ce1d0c04e2e80cf000000000000000000000000000000000a5c9fe4ca4ec2e2c1560002beb08fdebdabcac2e577dd34df5cebe1832ae2ad0a66f15bbc602fb3133e30dc1a58cbe60000000000000000000000000000000007c83e2fdc817dbea9c27257d745366e818729b8b2748f995edb51edfc748beef40a7275aea546feb2a6a7a2637c7b55000000000000000000000000000000000bae4ae44ff84cce8501370210aba32eabf6065d403b844a4b0e00a5cde519f2e335922b1b31a7a8603e873733ccc0fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000743d56ccddddf1e567a29fb50ed926d21d06eb7c46c693d19a61d2448e6312f7093a75592288c9e0513f8ff29680d08000000000000000000000000000000000e7c082ec15767fc2f74d1fac953f4feeb1bfdc31f9d55ea3304445d1aa590d8f19f3f8e882c4848f098dd893e665c2b000000000000000000000000000000000ff5c4d10cc63062a5f9574e65b23a562b21ad4f1d4629ef5b2661f112d8489ee4646a78e5e9959177cd9a5d315cf62b00000000000000000000000000000000081c117e556c502332efc956a20ae2880edfba794618bcbf95cc9b1f437295aded5ab1d9ce69277b57fc115b43f3fb7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000168fd5aa9b8445b584d6c7e89c018f6c89ccd1f79b1b356d8ca678c564a0addb3b0d8c1848a7f8e977ad9367eca547540000000000000000000000000000000003c787d24b0c6a00c457de286e2d2e169355df03cb4e979db68ba20c9a43aae4cb5473b9f840cd08825d73a51b549b470000000000000000000000000000000001974f33d54fb3a497673dbad193f554a2c6072d64212118c546f56da8815346cfca88ea841ed9c93940c6473ee9736e0000000000000000000000000000000011d585d3e76a4de65a870d6fee3d3a8bb574901746378c41030fd1ae5f24af9b88b221a8f1dff355975da5a3678ac084", + "Name": "g2msm-11-jwasinger", + "Gas": 201960, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008021059f40f3611cbb0b6fe88ab8598717fef4d12a6f97a8bcca2f1b8d8e26a89ef6f3a8f10d8abc4a68e18676a4cfd000000000000000000000000000000000258d198bcd3a192914cef9e8071938afc873107550a236620d6971d27537aa1630a396fb6aae498c5372cedd03473ac0000000000000000000000000000000018be441b4c96b43b05d940fb673ba3fcb2b60846acea3fbc2f9f1c71b8e742e8b22dff6ede7b2e510e83b2563aed1ca70000000000000000000000000000000005be810660776cf03efaadac7c7bf0b0680481a8e022586492da8a003e3d76f3f2383f58fcc72eea001df87a2e7d75bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000686e71b329505a4cbafddd5cb2ab81e139de8a91886d0c916b5c54d8b21fa3b592f5b53612b95c94a047c6c58f59f4f00000000000000000000000000000000153f839f5f5a2fd8ab02b6676b01434d724d4a39cb8e149c45007e7fbc87b73076f3007e4af7cb87dba60dbd0ef593b5000000000000000000000000000000000132e53ebddb09a8bc4b562ffac215c82e0a1b2980a4067fd314e642737f3f7b2dd6386344a751f30651e51758df23ed0000000000000000000000000000000005951a024c8d12d8a5cb9cfb73fac15bfdbfce7c2018c9c2201d42884a93d5bef42f7b29440b0887f6557636ba9b2e941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596ad567e8e2f2e19c61c118b59c3f89016625775d5c0c39df741c7b9f7f18307f17e11c9073ea718fe35e8d5fb46e70000000000000000000000000000000000f471320998958ed942f6ab088718a277df4e69f9f19a6b0be30ff7742ab98ac4726a714484da9371638bd9b8a6b4aa00000000000000000000000000000000102cfa0b735abe2576d93e05cca22f0f387e885972f776db62fd66414e4d354e54702b0f4b79b4480f4c8790616e9700000000000000000000000000000000001419ef155c2b746153626f4012a64627342388398c1dad29b1736149cb6709825b26d7866e56d6bfab5044ee889751391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e4e0705b3cdf80277d4df7b6fe465c224ac77c2f69d8e105851e29afb580d5c34de95d6fd0a4becf286c4de20a9504000000000000000000000000000000000ad556eb3cefa77e243d7735f2ac86c25d052b9348d84431620e83ab137df38322d3fe8dd657074c3cb0e345c38a9079000000000000000000000000000000000fd08f7f0f236568e382ea7dd0de03122450cf85dfa64abaaa0cf04c9da1988f927c6caffe881c3f9537c43f69c133470000000000000000000000000000000007e530159b887ddf2f9912ff7bab6638d5871fcf0c3238fd0fbea7c0a6fe815036297950519f6b30ce02e4fc76177a1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f89dbf32b2ba6c568d2ce8a9d05c77970d7d3f83eb7243ffb91bd9806d52e952ffd1029e9d319f93852c250c459457d000000000000000000000000000000001665200a4f370b7398e448d58fa8b9d7aec4c66f4fde118349666ddddf5ea97eabdd658f0408f3b6cb73594374a5784600000000000000000000000000000000081c14e77b6f7c974e6e03dee7668aafae6a9196dde851829046a784498c6ab2dc258ea2e1355fe73699fbb9c56519710000000000000000000000000000000001fda7ef679cedbe3b920aea656826fa8faba78020fd43d4092ad662481cfc68cb3c39a7808a7a757aca4e5a6039539d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001548cdf40e4daff92ea0970c062b99203346339a8c49acd7e663714366ec2ac562297a3303f917c50ff5dce1473d94a20000000000000000000000000000000016c67ca3387951e121c711866c5b33182727792ddd8bc67a01c5004c7615d6f96bba71b7a24f1f858b01194ff321c9d500000000000000000000000000000000128b57874567d338e1649f8c8ee0b5f7812909310f2e3085d496d64a5b9177b610f0d69800d7342518dd3a94fb67bd620000000000000000000000000000000013eef06e342eec5793bd5d8554516f88431d5078b2130cf00011912bb1da0104f85308415e6b24fba8ae526a2c5323ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004140cf4fd41037fb79dabce0b9373cddd2d48440774f9ecc560b5fecdf0d20d93f6c460883a8be058da750e25fbf0500000000000000000000000000000000050ab0cbb593a2ab42baebb7805a3af12e76b7a5b66aeb8f9697836a296b04670955c0932447d3c9d019208d28d18fe700000000000000000000000000000000185218918dd8342f8939e47c28cb49d00306eaf05f155bcc12ecdf8e29f9723b1f401a176444c9bb56a5c6b357427a4000000000000000000000000000000000151e609cae21ee71c737d04fcfed42f1fabc2047ed308338791211b3b40f8641a17d70391256d8a54f77c2d07f2b2cd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4cea2b372eeb1a7ba9db02dfa31a3e5a44676c43159c1ab0f65c61ad29260503927240d1dacf809b82bdc077ca5bdf000000000000000000000000000000000e3c22343b86af2dcbfaa6f5542d6f8005eb929d4239e968e99ea2357c781a0f1dc5f2ad3bbed2d9a067070c5362120300000000000000000000000000000000052439e0377729712c4736d921ee1d6e68ddd7adf1d4098b5de65bfc6d70981b535049d83728e47b46d35a64df877d4a0000000000000000000000000000000014ee22f6ce93805f2ff60ae79179e9d7e9eda9ec0905f9ce02f262d45d3acea76d510caedac9273e3d0f4c3a7d6a15211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e741397829764310a8c9ab4d8a4d99fda011790d5ed1c11b5c7001e68135b6e8aee43666f73f71a02902af2988a679000000000000000000000000000000000402056d655fcac456eeec6ef33f10abd382228514f5fa0c1358d580bf2f71c35ae638ef97ae602e75ddd9b4191f56620000000000000000000000000000000010815680bb4944b6ff1a3423c9cee175d085684c21703155c466d9360e7b8c82662c759f89ff468b356f89b83c95ebe50000000000000000000000000000000000b03ac823455b72a4e57e1c390118b5b78404e7bb7e891587c03963e496e356a3a1486e27563ef9a52c618daf7b10251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3aeab4e1aab27465954da4964dce671cc10fbf41cbb4dcd33b8b9a968b350d57269e7870c57cb7843bf002dbf408900000000000000000000000000000000001a309e3bc566c782e0fcc425d2ff84f308eb6155bbf3d11ac1f54412107844b96c46a9e69152cf9116d49190c9b962d000000000000000000000000000000000999b2cfee89a0b5e04e5613efc3f2581971e17b9fa4d416ef5e44888d57219ef3e85daa5343329a85dd65c81ed839f100000000000000000000000000000000166c133e98496c1e34dd0cc4f70d320f3a8607c69561751900943eca1293cbe35df8401beb774c33d3579cbb43173df71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002f020bd18e83d6983a2d88684835d77fd138e6881677595795db09d9a1ed51961b39f80330ff133c4c4413f800d6050000000000000000000000000000000017c8d8ba455223931394fd8c85132e0299cee989ba1666a5eda573410348faf41c7aa8be60207da8f4c50edf5d2b74120000000000000000000000000000000014525a1c5fc79b05198350921e931b491a15a92c517f9439d6f2911d51974fb0924991f94ed02da3c7ad65ddf2b02d220000000000000000000000000000000013803248afd68ea1cefc20c1ed41ab14c78c7067ceeadb9425aa96d28049697a53d1db7668e7bbb906ba47522ff5b08a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021340102cd47b30fd393ead273f2e8fa6a8813a46ca502ee01cdaa77828f961388c3a0f38a24b595a5ede1a4e42549e00000000000000000000000000000000089f53b73dc8d0fe934a4b97b8e757b2c32f74597e986637915b389b890e5e5866671ca9ace164d26e615991c01582e50000000000000000000000000000000012ca1e5ec9dd9da00af5d5667c6b46aa5023b4ed7de24ca4639742f6fbe8edcf8285acc8384929f6ba9eef096d05bae10000000000000000000000000000000001647c594ee077c3d0a162f920760f124a5268a065f7229738293aa7114c5b7e37e1980aa80b1870aa7481dcc7b7bf701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000008c64be86e3d75be980ac5f5cc4acdbf7955c8beef520c9c6896386bbea4fb32e22a76aab04f7840b818967c5b9dbc7b000000000000000000000000000000000add9213a6d009e0d5c16adde0bcc1e6fae879ca75bc2363669459ba996ba73a2c7cd13afabef4440fd6b6ed048ac015000000000000000000000000000000000291033ee24f6fbe0d33cb26a7f67912575b4b2cc595fc697446a5cda40cbe41bd0b78fe45e7672b29135acf12dcb0a90000000000000000000000000000000001f32b2597ae1bba016f607a76e9468b89062c67b8eb3e4106a16ee6af9a2e02e15038757083dc257692535941533ced", + "Name": "g2msm-12-jwasinger", + "Gas": 212760, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000125e569dfc47e9dedacc395712b13b765659635af6600c5cf41375c02178508736b4dd941348e3ff812fa7561d07d9c5000000000000000000000000000000000da114714ea8f220b3bcc699f5b493e73f88282e2be12199e174c2fec0787b4e9f17c4bd87c4dddea090c9790b79efd40000000000000000000000000000000011dc057d55baa6a3bfab1c68946afe661493802a3d351517512edd516b8043a3450a8b8d0020a546139084b38622d8e70000000000000000000000000000000014138f5e86be6cdd3770fddce9fa72f622622d16493da222a09162d26330c75f1644289225a3b2150f067d7e3e10e6401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cac7597bd1b94f2700b6aa8cce78c85331763da801f6f8369eb7df9c2b0db5a757a86ed7e7cb47c6a6156ccf1f022b00000000000000000000000000000000131302fcdd3337ead2c564956670ad4acd7167e13d68ca5c36d6133a2273c07ac3db3654d93716bf4c192ffb24fcb7f10000000000000000000000000000000013e44c6898472b9050205d16a44b777c7626cf43e6a419685f5dcc29b5ebc43ed4bf6ae42966b84784414b34a532444d0000000000000000000000000000000017eac13bc51ad518dcb1b5c1d19e375e5311ef394b852a13ccba1955d63682c05d83de6d05e82479c50114d4a2e43fa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007df61b6fecd86c1ebd8eea740e0a0c5b9de167ea8aa03a2e29c1960289f1c1be10ea48c9482a0ce9bcc977232d10f3800000000000000000000000000000000049a3d0f286c117d095ccd6729581d2faafbfa84459a8045bb6ba705cdd0c09e22aa56f66ff748d82684a996051508300000000000000000000000000000000015db9c16a6629b6b2871438ba769ad4a3bcfc0b0f8639081b5bbd863c7adb74b89340d10e98f8c20e40f31c02dc27e880000000000000000000000000000000008b8ba2a3ae2a886965702dc67c7b822b44c9b909d2717f31dba040389ffd8eb6dd5574dc155733ce3d0cbc1ee82dc571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000421e49e2c24c266da1880c54a13bc9d8b4ea469289cf457189bac4db99f6cf83ed9acee2938a7afe452e9b8440ded4d0000000000000000000000000000000010c6b17919d2d2e1a80438f23f9c30166c388471410e498064e8169ebe0813d6ad5d9b2f058973d0f8f3574e22a219cc0000000000000000000000000000000001f1da97038674de5c66144c8a582a46aa7d1adc2d6227228c7524bb9254aef1f6468b7b2ca305edf5c38afeb843e4e90000000000000000000000000000000013e5290fd76ecc159cea7f0740b7848e5ff83722c879a90d2d20c77962e524b6661004379c7318fec1257ceeab1248841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b10c3053adabe7e8a94b78465a84de70451e13f91ba74951de1221547a9e81271039c4c6196b43d39a5767b09fb0ca2000000000000000000000000000000000bdc31f3ca6a8d486d4528c8a6ea8aafa85323b8497d615c5fc0e8ee9f93f8793a956c80339194dfee43ebf6460f4382000000000000000000000000000000000f74f8ffb11b40b8a9ae19578243c67bf66fd0fdf0d1222f66957144681bafe8bda3a5aad2227b0aa68db3675a964b04000000000000000000000000000000001155d62127f2b1979d7ca00c7bd65b5bed5801f9533d80c47e917513b5dca91c941a389cbe4261d84bdbe1dae52968af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000810cd62cb5db7725014fba3ed40992c573c6ad46253af574ce1d32a88be655708edc6e988e6702739e9035ad6252e520000000000000000000000000000000006b231076cfe15fb8ce6f5e54bcc75352294288de0cb6a01770cb6268204eee6a56004a832ea4348f64f2d7f0c168aba000000000000000000000000000000000b06cf163b8aa842ff3cd9a6107e50b5aaa8a869ead5562b14004ffce96be46f9661a902a13550bfc2ffdbda010f502f000000000000000000000000000000000d0a13579ce2b8a6b85b3cea96c05e64f9a3985ea29f3b7ba0a13c0ba56d4d9c3d829dff0009b620e91a944d9e5973be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177d8cfbfe0b13345e557dc914b917707576db4d3cb65f75ae0760b0fe748ac7e503d05252dbdaff302c4e201faa3faa00000000000000000000000000000000168e90e1cd4fb3c1582229e92b71edf59d43d9767c477005b81309b454bfc0b2f6ff6bf56847ff4c1bba3cae9e9a496a00000000000000000000000000000000013b89b6c0dd84befeabd600e81fb02e95bb943d67755e6838a670fa53448410836c1d779a78d370d0fc5d21c9075a84000000000000000000000000000000000d9b14965044f35000ffad89f1d9131a89f9ee6d1286b7236cc3629ebf2bdf49c19353e06a715720a47753c279549ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016bf043d64cc021a08de60a3c473ca3b55012eafe82ed839ead4e0e2e61d4e95fae1edb44a6ceb841e77adad7b140371000000000000000000000000000000000d664ed33f6832c2633d5db1c510fffb446e3cec65bd4821cee132efd188787100eac3af8b6e2a626e6e7d26cfe1d28800000000000000000000000000000000161f46cd08d9dcf23ca2bc51be9d2cfbc46a210c21783b266172c7681d61b02176822fcff928beb50e31f8ee11015499000000000000000000000000000000000fa301b13647501e6b70a6b670f23c3f72c1c8b9c210e16dfba2afd9a718158a508d9bbe7e6305979dcfc739bc1df6161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c5f17579be7d1088692df3f5301ba493d2c215bf37c57a82f059513e54fbd692ca5ffb9ddb7b045cbd600a1e06eafc00000000000000000000000000000000073e8ab2f834f18a39acacee258f70a69c81957aaee5f0ddb5c22fbb3c68be6a15d76e60d1332d8bf8fc6e3121f6413900000000000000000000000000000000123bc15f394cf989f0b949c7afee86e7e02c24982c1ae01797d08104daa1936c62a0e40ca247bda4c0f6165ebdb2a297000000000000000000000000000000000b6233a74db1f492e2d6f853e46de58f67c6e01f6b677740b29552f5d7f4127ae94ab4d5c052291f492ebc4e04caa4361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c582636d12298774561cf0f44c80660da80410c0bfd92c0a0e1fa309a1f4dd8a410137a28b5a805c7b02aa3ca44f3f0000000000000000000000000000000000d7d89e3189649323fd75e67a2e087ddc225a68dc8c55933c0675d237c8b0cd9b46a2e70512da9470adb44455a654a40000000000000000000000000000000003583ac11d5525b073f3bd4d51b0b640ce43b751d28d30e07da35238219eebe56800ab11c18918af833ab953ce72e1a300000000000000000000000000000000116b4ba6304cb6f3b79f80a61d9a8fc083801996b7097e8575960b7167bedb7e997ea183f0dd0078aca51587e45c6c081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000140629bda15c8496f6eb5e65e71b7416b54490a35433f005b8b922b583e619509cbf3b57a71d404a4c8c501437dd2ab500000000000000000000000000000000174419792016ad53e4451853ebf36564184f691159de8b8521c2333ce60b5ae71a63c14735754229261ee0bc67394e5300000000000000000000000000000000160292b0e2c93330dfce76b71c8783a3e29f3035986f9cf8bfba2b5515e92fb779ef5c9223797382d35f9c560d8dc4e40000000000000000000000000000000013dcbd7230e02adf6497817996a7d1177ac351e92b2e501849a7f97b608fe3b4936eb715c4eeef2c9d63440f943161db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a75a9895b070f695ef417c1ae7cb0f31846fba4a8393ca068f5bf8622c272a3590c60268f067bc90b47bd8cc8903ced000000000000000000000000000000001333bf2c3439a6b3c3a994495ce7cab11d878a1735d57dae8b7d5c71a59f592b1b3d98cad3fba4bef9e33d06cef1adad0000000000000000000000000000000015c6696789fa57c6ae894f11c27267be467b9d8effcd1ed26e5f9aa79ca136fa44fa07799c0b892325853aa613960bd7000000000000000000000000000000000961c6e90f910424abd066ac16c342f87afc52f0d7ac0a8070f7e0a5fa60a5bc8ff1075e93d54ec88fe11efeb548c6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034cc93ea8fd68c3dcf53a433fcb6b9d785f7a340f6fd3be806e395ceb055be37fbc7d8eb670719d592d19feaae16b210000000000000000000000000000000008581cfd3298278aa6652880bdf1c0f036f4106b19f9aab539710096afba38ff7b8b8a0775e2393981306b0a035aa52d0000000000000000000000000000000004ad80923ffabad8bb20319955895b919ce2e35ff7a1bd16de3044fb9dee9e229b106ffae4a28a27aeada9663103cc3c0000000000000000000000000000000015998a21555b39b3f93d23e1b5e4fdb8413189392571493629c4d0fbcffd97d678b8a5987009d93a2aa90658fc3956431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000013baefee1d40aa57eb774ba8b5430ae2d35f152bf0f514f5bca34a3a45a50b07237880853cf7a291d628a4dda2d00725000000000000000000000000000000000c1aa48826c086f959a6c8af040e949178bc3d2920c18ce2674a2d300b3f9a244ecfa07a5e497a3140cc1b7d33a4e6d70000000000000000000000000000000019e80fab4bea14c6605d2fe5fa80950f4f78df3531e50278439b3da08fae1969aa60ea6e192a70a71fc386255f7b5ac300000000000000000000000000000000142a13d159dc5f323036d6fcb848d89d18761d57e0d1d5029b02b5a04a3ff898188c6e77ec1f4e050e88cd1238faa72d", + "Name": "g2msm-13-jwasinger", + "Gas": 221715, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001675b0bf5351afea5a97334d5f60b0759707e92455057ac6d2ab6da4c0e962f9830fe34a573a4c15d5805d3fe9afa5df00000000000000000000000000000000053284f9e73d0ea661124f1570e565cf53fcbed871a257f0ae7ad2ad6eee3308ca74a9830f1c9f1d967cf41713537e4400000000000000000000000000000000058fa7935703a53f92c32ef09ce838682b3fb9a6dd62e399d8a12a3834a90a2ae4353d57102cca9bc2091c2fd1e3f197000000000000000000000000000000000e292c94c7fd4572f0ac922c3dddc9933e3e462b13f44f7678bd0fe111a6b098f77569455473e128ea23a92585e11a091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011df2d502b32752bd5356e0dfcbc170a006a644cfd576e15d2955c4b2c084187b016fb02748acded8282fe7f80af4f3b000000000000000000000000000000000c07470b495145abcec20866a4a039142b15645f2281ba1e6ccb831156e90684159fbc7f8251bab8c79bca56283cd5e900000000000000000000000000000000162acff68e87be85214f0471990a76885e9ee2a9146f8e98e59b62ce8d7613fad2b380bccc4bb73303ac22d2d6b8b434000000000000000000000000000000000c46fba20486fc832894e97c866c4a3ed48fde23b76b4c43d3f8c9668c907678d4548d713d18eaf069db534c543bdd8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1787d29ace74ed80fb185966b2cce3832af345c97ebb1332c9796caffcb3930f37b4bb4a81ebad486870f7dda6a56a00000000000000000000000000000000103a60103eabc9d01fe5e3502c0eda239b0bdf261fb0a380b2178ddf2f4fab23fd994c3142e0cdfc3791831f5ddeb77f000000000000000000000000000000000ff536a6eea1bdfd6a8b49b81d189eb75915a2de2ecc2f79d684a519f5e8692340394cbce21d12152757cf88b98bcb4c0000000000000000000000000000000003f3390f1cc81827c177ec45da229ac2a7b6dd9e130c30220e843799d561052942fabcdc73e154bbbf649dac8f23d3851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a017b226f990a17b3bda171913d0e450e37e5d1dad2af29e42678b7cc16f37bdd3589a5c6b498a17ca8a02f442a0e0c000000000000000000000000000000000e6587616992b13eda95eb6647c5860d07f64457fd3a94797be82cd4720603c9b8723900ff562d3624d5e6edbdf075240000000000000000000000000000000004621a0f720cb397c16cd430638f5930a8bd75b391ea7e3c8e135a9e1902aa87bd6f2b29eb69a958052ac8bb3b7c4cd5000000000000000000000000000000000ee486313ef3b270ac16f4742ddd872fe2416fcca96b14a504494fb8138d2e08545658beb27863ded434e7bbfe9575111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2a119b161a6b8665d3d384a3a5068c0b1e6e363a17bf8e6250e2f79c7830bd5d2bd4f07dee660b22f353f3421f980f000000000000000000000000000000000226514feed408e2c7700582c4bfbadb11dc57a20a60e590401733e957fcd9e0383f1c979c77dbcc2f5ffaa192a0157b0000000000000000000000000000000002891a416c475d3ead18fafb3e143e0aa1bf707345d853ce713b96844a5c434cde0446b818628a5c11ba6f46e94b064f000000000000000000000000000000000bce4a7b3043334fb08ba6a2aa6d31fe7a69a666049120b622477d4597f16b9dd181c3a6846cc562b34cd96a05fa64d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192e7b3717f40cadd221f33ec65d77f7ed9a1d9ee634c03788cf51c2bb7a41732940a0986f9713f9fb16eca1cf36c7a3000000000000000000000000000000000c6432bfe40fe766e74ea73777997f0b144d4b4753a70c38dcd0a3f66f8f4cd976be4f3e97e4571b0c4ee761301c7472000000000000000000000000000000000a91c1d5c93caab9622915463e8328a16ba8c353d7b22cba4a419aaf3c11866228520a15440eb7d7d86c900f32f45b6c000000000000000000000000000000000300cee80b0f9767b241f1ea2ce2c802fa183bced933f900bcecbf8bf1bf5de564c93d583ffd60f9f2c8a894ae8d131c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f3bd9225d1a0a745038cee676fed3403608b6c42d8a58b572c3ad9293e51316f6c8930c02e025bf2aa0186b3de970700000000000000000000000000000000010da64d9e61a2f5f12479bd1d3b60031e6bda00cff35b3aef820515c1fe9ad9f01b575ab5b8b22c3d6a044fb48538780000000000000000000000000000000019e94f3b31d77564a30db21e030c0a5cbbcf02df2fd723c8956a5086aec711096c44503ef8c3e66daaca3d9f446455be000000000000000000000000000000000758f246d5b42a281e7ba140bcb397f0d1054a1558765d4fd2be6b1290531786008e3740cfe4275198b63240db224add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000625cf5efb135dee7b4b3a91dc942c25d8f4c4b518012a6f1d18179d9aa147addd8d75a6bebb5063a55750ad0a027bbc0000000000000000000000000000000014b1c5874d7d7e65779a0ffdf05239e4ca96252191048702e9eff22475d2464fcfdfd0aa9640978b1ec710cbfa80a675000000000000000000000000000000000ddb149f99ad4e32e44f2fa93cb6a55aef7909b38f7b9c3b4d048420924de70a37f626e3899047d93adbb645db37f6f800000000000000000000000000000000059c97b18d9965647832c12f2e90359c765bfe38102c4404282b5d8efbcbfcfde91b93b3784689c05bb6ea29d761928d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ed6e17c926002070f77c00d4e781952a2eedae5bc9a6bfb7bb708dcbea68f792251fb0fdd3657488de4c903b2d367a000000000000000000000000000000000e0fd4f768d2a1e554f6d96e40d181ff0213c0364def9b2963691e764eb871dcb6c763dd552d36bafe42344c07994c5e000000000000000000000000000000000c2ab5c169b8ec27e154e7534a996fcb5becc8f423625c71ac853cea8f8e5a3435bb655401e0e79c268224cf01fb17b000000000000000000000000000000000026266f1fb7944b47b9c46091c7879909a5c67e02990e077010a101ea68cd53a812f7a42ed9ab9de1c135315ca0ff0691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a865c262cbaee16a98b8410888a514587e0646d65de00f85e0665232f0f03a9883c6a50fde8f266cd048e3c573213bf0000000000000000000000000000000019102286fcd371b8fea51f06c98d10800ce161c40586ab07890e14d704224187c25e269a5ad892c0fd087ff8aebb1ff0000000000000000000000000000000000e58283086b6244ab41798aa73598e37df131c3ba16943798d6cfbf29db0ae6cc1a0778c4d48897c54bcfb88b46206d5000000000000000000000000000000000938973335eca0d7bc31da6d707514f62fa641905a3570fbb5531fabc1117fe9e1bf229aa13baf0ca541f2e972fcb0151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7c7237076158115e0527ce32b7e2f0e2bfb97b4dfb7cec6b7ffab93edef896e37495c4b8309fb2c43c2d7ca4d0ad11000000000000000000000000000000000b22212fb5acca5649b04d1e1766302ac0599b8d93a0f1206efed2a2db9eaed1e428624a9241575b350512baed0a7e8800000000000000000000000000000000090360d266e428b00594fafaed2d35545cf42b98be6c55ffd7d9316e5f0489f65d42d5a5c679ce253f7ac9f2bced7f430000000000000000000000000000000015639a3d2992df101b79444b1f60b0eec1c23bfc9107c097693d1f1e01000011c0469a684b1f6f32225088a6427c493b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ee6bfe90a62d612516a0b8aca1c4a263b151ed0cb49a086d75d8c08ea3e7361a979fac5c0a61eca2df384ee036afc800000000000000000000000000000000097de8660434a844bf7454a5461b5adf3aeff48e1bacb9a97e3985f085e17c9ca8c370b62b7d8318b11e89bd7d920ca5000000000000000000000000000000000898081fffea5ea32073311ce63e4a99d4c98021bdc653cf67069ed62353bdeb7517e22d68e5badd91e754d99d9a53160000000000000000000000000000000005bf8b59c0584d8d1cd29be3f30adf4cd3c667294c4431c35c502b3b33613ef8f9749b1d115f3ac4e8223fdb43e6f6951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126d53c89900329df7644466505fc0597a8b32aad1144c9b7c797fc253553e55bd82f6bfc32457a32ebff6c58f5f3782000000000000000000000000000000000c804bae4eec145e11e986dde8a4d4c1d8a2319716df5d415f58ea82d68d533a588a244671e9c4455607291fef73491e000000000000000000000000000000001320146088f9048353f1f42236354d9df724f3a4b3a267e735e3d3982fda8f1fe49ddbaca66950725da20f8c7722d8660000000000000000000000000000000000cc083c86c4b5b482d17caa3769164402c85facc64ca7bf93b81822741581dd9bc10ca3e0137cc2e357e0d7a41f76121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000effd30aba827113ad2511fc92e47ad92d3173ebd158dafcb6f1521a0ac1e0f93e95dded5ac38c9a281baf51a272c9350000000000000000000000000000000009a11677280ef6388dbf4578fff30cdd72ef5124113df311f19ce81de1275a3bf2d3564e065244a976b215fb1fd3bee80000000000000000000000000000000018f2f7019fdb19e3a4c817473ed00c45f4d9300438f18b69e52704bd2f526d1adc77c4080fcbd192d34160dbaee8d14b000000000000000000000000000000000e88533f0bd693e96b4820962109d47adb1959e765ba7fc7b9fd968f71806670422c0558c125ccc0db658d063c3dab691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000010fef9f726a0fc131e54a66fede4530131b39382d031a79f1dfa457bb44e931f18c8c43bdea07d5faa5c1c9263d304b30000000000000000000000000000000018923cc680bc64fabebf1d20b420f8720ea5180a568a8f1cff39cded6d8bc7232ede266d9a5dbd907a9ce4685a633084000000000000000000000000000000000fd2d1f1ce4d1e43303ef0dc602b5b8e9dd9524368358625185530542303eee46634c7bd5da93a58b9d899cb5fb6b8650000000000000000000000000000000009ab87a9750c466b7c1f7a9adbf6b9f9ae5ce722346ae99f5c9c1d537f5ee63b5f4bb423e29f0f5983a587fa644d1ec4", + "Name": "g2msm-14-jwasinger", + "Gas": 229320, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000009585f82d0de4b032fff9c7487bd774ba390b8e0c4160e892bb05f80e5826aaf772ee2ea082090e8bbb8d63ec2c46d360000000000000000000000000000000011f2b894f97d30ad271af2cd13d2524424d7ca4e40dbcef4a8a1f09bea98d304035394ad82c1ecfe4889cea7282fafc7000000000000000000000000000000000d7dd773738b88435307f1ab371f424c6afe68d056367e8d60e96e03be384f9bdb852db43e528e7611446852b19adbb8000000000000000000000000000000000d5523327af66e927af025f46dab15136ee9272c89926ea30df5101d86eca077ea38658dfd982efd8aec7b359bde452d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2c1a78e8801ffdce4c00ed6f6f5ee92cc0572e26347828ed548ccb57979885769f483c7ed43a2807b418cccc0dddaa000000000000000000000000000000000e40f7ec8fb2248a8468e3e9de9e18a6178d7d80e8690cde852c67aa91e69d494e3eef846ecf8fef485a4e9fc8fec15c000000000000000000000000000000001424283a510a72eee9c53632a57ea483e5b7167c2f02de256360277486bd60f74489ecb1f1841b61faedf4b625799e8b0000000000000000000000000000000010830aba1e3673d8cf5eb4bec1d70f9e933a13246f5f8dbabcd9f9de1a399e29a6d459a33f865a044703e3569b9483e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363ca31097d9067054e4ec6db6f3eabce58265a7caa3cd3b0b85d3e472db354941ba6edcfb19b1c302180cec245b5530000000000000000000000000000000018c130e92263de9d8ce0edfb46d3a1c3cc3989b7bcd02d91b8135361503b2eda8e9b78e3f47887107cebeb0639ff538a0000000000000000000000000000000001b32ec18187b4580d01a714ad705d4fa21620f9377aedc5d493445a26d5a785c160892ffa81757f707497f94a58ef2d00000000000000000000000000000000003356c415e602b72b21c742b0ceaad89d77cfef996a14c8d947498a0f1b7f2cb64c153f07eb46647957efd4d9589b161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182d682205cf2bedf008ee4fcf6f6f88990f603865ebc076a16f4f88d24d257b934c4a8bd0d23a7674064d1a961b9e97000000000000000000000000000000001096756e101c086d8a028f13003ad511e56523848d1e01d014e336df1d9a6369d5b3f645a5ddeebd723e739f54eb2d560000000000000000000000000000000012ce1c90831c762613a0444810eabb2246e7c029d6c507d95b9ce7a126e54fb57108b6c1fd05944c9e923ce511200351000000000000000000000000000000000e67837eacd96dac48560a5bb176fcb640c04541f13ab4165b5719027daa3a5915413bf8d349a82a86e124df183b6ff21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123cac8ad5c2d6fe9f53756a6b5a0e4136fc7859c1058511d00622729046659b38cff450ec4652b66b7d79ea68b58b3000000000000000000000000000000000196e2aee93d2870444cc0efd7d4b0527e18d0671dbb4649233da2728502b75aca534564c3a927a2612d9514731f4079b000000000000000000000000000000001210ebe4b49081c7de032c96ce7aeddb38b0d4f18e0880bcfe6ac4075700a8a1a64157cb2424126134111d8f2638a0010000000000000000000000000000000003e1bf0a5423be6efe9ed51d9d6b6d89207f256b2c333c94a1770084ea880fe726a24a7e07e2c326609b30d7c64aa6821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120c8afdb5c3d6c962ef29f6d6203dd8378054ff1e80747e9f32d624bf1a6f9566cd55e470d0b897818ae20c8d4691c3000000000000000000000000000000001076dc9486c2fe188f96fc35a8bee4bb5c63b73c75ca8f52d1bc85c35bfae3552aa2701016131b4a1dbd9e4a97d0ac1d00000000000000000000000000000000084a2652be51d54d4abbae4fdfae4a25059a32816ac7b85db04e816df302497a4612e07afe55488aeb0f962be2b332da00000000000000000000000000000000031df8dd51547546488af6b6e457153fefe1f9e9d4f86b23df276dc90dd83d3426cb5e40d63e7586a434872c4f67389e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047659e6f8231dd8b3795cd677d6735c7e07654ca9dad457c10c312e834860a7e2a5b9abef8fbf808e60d625aeaa90980000000000000000000000000000000017bda32ae2829163047d52af952259cf1af64fc173fc914216f44ba4422ab82264b7858a7357337584504758a9b209be0000000000000000000000000000000014cd7c5a8b141a3411e33664761fb157b4b30f8e15debfe7b36b64e02828810a42ec64f453efa7ec60dac56af86ebe860000000000000000000000000000000016a89b8dadfca75f2a079a977a0006e68658c3cec2f7826e6263e4bc0a8abc7d290db071979340f0eab780d7085c5d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192b75967186020c75d8c09e4dee36974308a1462edae90ae24133827f9c3e365f31353ebf16757d23d64ddb8be39f30000000000000000000000000000000001901b5f019822bb210ca9bcbda63d9732fcbe2efb726e54dc2b5dcaaa6d4dfa0e5a6df1a66f9403a244b4f2d35d9637d0000000000000000000000000000000002d175081b980e410615d6c701ba77e8c22f09c494c430f1b7ba733409fbfd023572281a4e1a2d295b9a321c01735b7d0000000000000000000000000000000014309db5c7b3ea2e71ddfdc55b7bedc80c70b9297020cac7c7b52b3d43f8de899f7a5bd98c5a86d428ffca44e8b0391a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017af2836c5b7807288b15832ae410fdf595907159be55f55bc6f13e60b99dcc7a5f6d8a3177ae9f2479170a49a1b32e00000000000000000000000000000000001e11b5c1c90be5bd374b5dfb18e5ce201866ed908dbe20b21b5d58afae00ce3292e13cbbeff687dff38a4dddbd78661000000000000000000000000000000000df3a20c1d6aabdd7c98b4ff45d891227ed7d8fbf07c9be75f5c3925de96417edc53f9521f90fb176f56db4e462c053800000000000000000000000000000000075bf5763f85ddbb8fffbf1cb3d1e616790171b31a3ed46cc651a39a6fb2d0a7d6f370591412cff181005228390bb0bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca9cd18967ac13f7d2a7643107984c03263fdfc1bd6e365f478ff5df9aa9aa2bbe85bb3c52584ca93a603c3c65e20d40000000000000000000000000000000018359c439c1c3df752f26d1eb6da9f54947c3be0551d18455e93b491187bd159458cbdb516ae71d0c73d3e52be02a84200000000000000000000000000000000060942e464929c390b65f0ae0cf461b1499feedb18645f186130129ce7f3c23f3e920288db737d978c677dbc798fa56a000000000000000000000000000000000d92732d969bf6863daab6c50941fa748bd1da03fe31914f3c4b56285279ed890df2b38e17d077001c675b737e9b50c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f39146314f46c600fe075bf609c5aa83212615f3277085c6253aa04812d0bda206eb17dece35908940b98b579f0d1400000000000000000000000000000000156e50026a5e2d186722d40537ec19f102a4c928f3ec1d9d53fb8aa605ee474a09d2423078afc40e69214d1907e0e330000000000000000000000000000000000ee619d0510cfe6dd9d1f0f562d4907fb1081c7dcd58d37bf46e0b1bbc2595780716a210629e1037036d1abf5737f85e0000000000000000000000000000000013ed553587700422ce410305b20ac8b8f50f683997441b9b11faf5e264e3b82f98eeab1c1581a4df17b4dfdb915552cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b785bcf40b4501fe8918afcdf707e5f5c0daacc18ed5371bff0667670d8ac50c7210c8013873508895cb2897fc29a5000000000000000000000000000000000fc7151dbf7263fb513ebfe8c2f3a24946b6ba1e2fa9dd29f099db8684f6c17e1e39b63db98cc4b123e6c416c3b5900b0000000000000000000000000000000003312557c45fef275086b9b824664630ad351e2f25533d19fdc51ea5939e8c3b7a97716717f036a7b8b3478ee00c71c000000000000000000000000000000000195cda923236334d66513744b18e02a0e165c53ee170339711b4df0b72faf44e5a7d46f2aba96058ea7f3c5be3ca8fdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101687419fd635615bb013542735699cf5e3f0e048505da3d0dc8d9ff3116b225c839e23e973427f4378271df1531e8c0000000000000000000000000000000017f8ac8887b5646eedcd9403eaba4937403ef137ee9825d6c5e1d8012099d03ef3a1e49142991b5230f263fcdc7c18ec0000000000000000000000000000000016c729f3e215c2306c7aa24ae4f72c56906c8f00cae210b83d3edaf554e1ca4a73b38b49bffc3bb2025ab50104c21563000000000000000000000000000000001184c64ffc045de677baf6073458307f979cc152e903c6c737af828b6c59e350fdb69e4c9b8fef4bb178b1ca9a4e56391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193019a29a6d230896a62b27548e61bb23739b9bfe57acfcbafd1759d7fbd34339e2269462a5e45b6c3d589a7c2348ec0000000000000000000000000000000013cc2181e6c14ae4770f4fc40702b9df4907f958b99a16ff4ee3f367ecb0f7eba587f0c009b7a28562af3a3064273d900000000000000000000000000000000012387afd79057813c08dc751a929c79c44dac1867a4214065dd16274ff213dc786f1f98d493ccec9fb350ba49b22e4eb0000000000000000000000000000000004b32ca64b1f63b214561253ea1a3ccd37aa1b7d5a5ddc7b913a77bdec4a59d269188a03da94d615ae956f93f6bf31a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008eb48d60f08ec50d74a6f9b4fb7fb162cac8831cfa684facb06cf4372179b55e99c0cbe7f075cdefd30425f9902ec460000000000000000000000000000000014dab58fdc97677ac99b80c22ee7b9d39beb10e3028588d2e54e24336e5a25ae60b90b1117c79c4acb62c9853fd9e2780000000000000000000000000000000019f44ef09d41fa011e1dbcae0dfc85af938dd5d5b9c054238fc8bb79f19fe37aaf31bbf440eef9319609881b0cedf0d0000000000000000000000000000000000eaa75e3c57fbb857eb78519de3d75b5fd9b89d2f21bf05644fd3d0cd1ffc29416231a763ef93a3638e3aa718b4eca3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000b2ff0eab9f556316e3cdc9f3ffcc3cca500f87e78b6f0ea0ae236dd3eccddbf83ee3d2006181bc4ffc7a0c557e5649900000000000000000000000000000000129b1ba7a744174176b6c3c3e618f6eba64a61a77edbacde99a16f0000f4f4ec2f7df293ecc40bfeb374e23eb04d38da00000000000000000000000000000000032dbc598fa6ad4e672103f29ff117693e4a9f38cbea4a02c6a33912cd40ce5a19a940c902bad20554985f8adbafb9f3000000000000000000000000000000000357321fcfa1732b1638522f15cc85e5c1bb7b26d3dfc1b1f5ae401e40bd030d55bdd8a92ff9cd3ffb58b20df8f6e58b", + "Name": "g2msm-15-jwasinger", + "Gas": 235575, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001058d1c8408794e876eb0756c8e3912f4351845642c51cfe647f5929acbcbf5b1ac73ce1fdad37b47f9d7e398e55ac830000000000000000000000000000000016b559edbe17138dae65b7e113deaf062872da451d283b9883436a361f939ff2e4335c361ddff609112887f3df907bec000000000000000000000000000000000f2f3d3cdc02fa73ff20d86b8ffb0d87b44cde00a835b87c19305ee42cb7fe48fb6f6d7eae0cac84007c4c5461c0ce2a000000000000000000000000000000000af87ff37d502fc6b6799e086784e26bdb9bba9491a1e48f0d17ff3544efe150c1cfa6dd35fc8d068dc73af110c8d2241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001648f0cf7080e1bed087a10684b89e4e99205b76d4c557edd5b1211b1214fa052ed609a3cb7d681311aeaf46ef19ec70000000000000000000000000000000006fdefbacf75917ff0b17ba08cf4bd0350de01ced463daeb8a55f149da95abd4233dea334ac50799daf663adeb97e59d000000000000000000000000000000000f286dc4d59f9955f63bcac9a2de7259c939f25075fe5099a3a3cca5a061e9357b9e443430dbc88509aab699887f816d00000000000000000000000000000000052895c6162eee3f9db6561ed540b3b2d300e38ad497f86cfd779220df9741043426212ca5d1d7bb9d7b84251fd847ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f1171e3a146490f761f8396e1b25d5499ad0d9eeda355cb0d9d2c94e00e029567375de2c139afe5ca7d1c34bbfa79f000000000000000000000000000000000744e97177f935081e73159c0ff179fd1432170d8a1e4f49a04a3fdfac29c6e1f6d323a4279350643fd94d0b5e6a54fd0000000000000000000000000000000006fd7d988b54b60f695bef25547d9110b55046602c9e46453e3eff69fdbc65dd13c77687bc44526e73c5ee9bc4d6bdbe000000000000000000000000000000000cc27777d17b9cfc921afa67345a060b497446e85d1bfa4fc18302eeb6c88d5114813322d475d72e66b76caba7d418731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000928724f312b832cc0448dc6cbd9f23846b6369c758e62dc8c4b4038a0ce85b8c34fd872a2561ac0a1649879e16c9af00000000000000000000000000000000019403353bb0fdc9d31246428f8ca07f371a21de827bb6bb7b23f7437a2196a3bef2b6ba78c0aacace2f1d55bf2025da9000000000000000000000000000000000433241c6b5c3b7fc4dee4c795f1725ac92b969ae8cf7efed1385f6bedd9d44c1d2595b6922de323e3548ca46e2d19120000000000000000000000000000000019dc1613f73c4d972dc18ee6b4b249f61e018b8498fa10949d9a318406472e8f62a678f643096025a00c9283c10a376a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001615400eed4603bcf9c2d843f9d4e1399f475d1c7d90715e83e588696805690954ad81e3128f79945d14d1d8489701100000000000000000000000000000000009841383263d0e0028c8874f69b621a776bccbcd3a50705e1b9f3457f5283ed97812dc8051915d555ad94f8bd1e4bab600000000000000000000000000000000119b5b19896d206db2a688043730887d5f4a8443239449c180a33164b4ffdfdc62d4f84c474e4009186e234a45705aff0000000000000000000000000000000005a5288a7ad559e3c840a9b2f04b077112acbcbce27f75ba54e78a160b3de4709532162ad973a3daea30589d27c0e7e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2bcccf91f2f92d8742f43b3ecfd0e86c5c0b571592a4b0229e5d758e7547099622150be509a0eb73faf60b8e6f32c30000000000000000000000000000000012a8ba2e96931e64a4c8d922128b6bb9b33759b4a8b90298dd966e24bc8f2a62c93578a51f1c69d25a985998b0f701b2000000000000000000000000000000000f08d45809ff6353d79ed446a61beddf32b8c10e80320863c14dd6f3963712a82ec08078d870be39c894ae7a115761d10000000000000000000000000000000015b3aacd68e406cffdecfa1862a05d2e86c18f88953c9fcacf4f57ed148b75fe47ee7d520423e10b253812c069249ed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d33f05473dcbd7a6f87aff2c4492c5ee075dbeb240ac3efbf7c10100349a21414d7477a2a9bf8b820fa22cafa8fd2f000000000000000000000000000000001909b11e06993d3b3f8dbcf53af1f84f8f77f2a3b2099e43ad2e388a9f50cd6dfa3016bb8331b9c88f72a5644cc4304d000000000000000000000000000000000c2d1377a29d0f1edb540183986f4be344bde6b0e828e660e237ade096cc93951df423cdb31402db6a58305cd8affc3c000000000000000000000000000000000e00541a59a064e75dca4a34a7dc2b53166aef07c5304d4ef2958eea89e0c03731da0b1d34365d21f6a96abc3f5f3ec61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199577c6aa52005ebc97fbb815f35f5536b32d01832fcd38a928c45bdc74979166b2642e1f5c8105a7c65e1e3e91be160000000000000000000000000000000003b869f8fe45a059b2a0a0e7f881109c82f3670bfde042c5308e47feaf845ce74e61e706a9041a35fe9b5ad1b4c25b64000000000000000000000000000000000402ed4ae3f01663f6379289751b684083d40c08fb001dc3338452587716b31462e1b9edd0f3c958119ad3a99cd6e09b000000000000000000000000000000000dd87de5373639b4e472dceb52c1526489cae7db9449a76c2b6918af7be3324d553057d15b51d62ce4bfdd3eea04142c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb336ef38c387b531ef1297a3653a8ecfde7e9568efbac252f51cc34d493b1d287fcd03ddddc773aa753b075aef804000000000000000000000000000000000002879eff0355790a7c1e598a848c2858ef74ca6026d2f3982e60c0f5d4ad248ce5855fcadb171e959e63e4c0ae2fb7d000000000000000000000000000000000971e792f0dc832dfd3d324afde0fbcd1169565c8ffd6cd90d5e34ee97a6ecd47506f016878dfdefa4efeee1e97689fe000000000000000000000000000000000f01e28c11307cb75040a8c4ee1efffbeb204d5bd9c9ea4646216715cd38ac2a8a78d6960b9f20091a13ca1824c1e7991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b028f2577947445327e7a59d284540e4a70d818d923ccb094a964f229da2e8bc4a8c384e28bc1498971819b752e7b40000000000000000000000000000000000486fb86ee6924a74a6da138e4a33aee6f571fbea13a091dc5d36aba1220046fb5475f1df45846fae5a3bed42b2f086200000000000000000000000000000000128878f7ef1ea3a7d68d82805231665d6ef319e0c6ccd33f8b69574a9e9d3e94dced576aee30f8cd731964da3209a7a4000000000000000000000000000000000efd61a5527cfb0bdea34f81e3c4a0faeb06ed5fbb1b49099219af9241fa1504a2923e1e5d4921819caf74c1da7d20581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ee99d683d95606465110a6c7d701e28b6005f55325ff4dc7eb0530ed76d72f29777001f867e881bf88939a9626743000000000000000000000000000000000005be8ecd6eaa8a09dbe42b5aea039633f1af6a23f6f74dde1af31786d3306c2a2b154763db48ebd83ce35050bf2bffa0000000000000000000000000000000012994045e0a6e31801f8d811cd8474563252114526a5bab5e7ac6aced43bce1a456c1e62222beb6f81d5ad59db330f550000000000000000000000000000000001110a22468be14ee606c79e1982612f270e800dd4d9e5843b576d68de839da7f4c371720b26fd334abd05ccfbfa52161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63af19ef755651fea130b411999a332440484ef0e3c3a8adc57222cb9e73b8dd54a33ddd2840ef7654611cfec8bdc300000000000000000000000000000000190107a5b7a3daa41257ab3a21ac2eddfd20d256a180bdcebcda2dd36fa7c98f3e142930e7a94095e0f858be1ab0728400000000000000000000000000000000074bd4deb184b3146130e2661a5f1c4186ac692450d40a43613e7db4952ac1275d609a9dd28eec54116342552172d1d20000000000000000000000000000000018455386ef333c7558f7258760e17d5ef2a6fb7c94b740e2cd1948abbf06620e2314c4f75fa1706c90c740335b8db8941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f9728915e60dbd472b8f381d0b3b96c850cc63f8a3175c95f82bd14f6e3a91d1587da029725e17bf6f1c4722c7c1f100000000000000000000000000000000185d005d561aeaa3c552c2fb8c7631bc36194eb7597a0f9bbe26fa77b6dce66670dd61f1938acb960a045db1aef98c4e0000000000000000000000000000000016cd91a64a95be7ace42d45523013343a4914fce213f25d3ac3cfe474b8e651df277ad41fb153fb0e3f7007553c8aec20000000000000000000000000000000008e9338c058917689eb01bfaa478debe85ddd665f15b6ba01bd23a8b0f7dbe7ae24c62171dafae6e72114af83044a18e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cade5e723b7b7f9c642302470b99c10eb065bb11ccea7929f6646749af6a49e0397c17db55ba1a1f5d210569c4f1820000000000000000000000000000000000fd4579f392c16763016a702f5e1c02c5f9e7ac279fc38e3a43f124b925ddf09364c33aab23fd178244ff5b8e51f7916000000000000000000000000000000000d74330f40790da1cb2788bd12be55494010969e58a3a90d780d129132a0430ace5552065333d4df33a3845f82e1cd990000000000000000000000000000000014125a57f3b50a5042898fa63221a1b503b6c02df4b30022885f956e7948ba7c98a8abec53ea5179b3c6c36a0fd5847a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b81c9ec882ea6636b0ef5c85d1629bd5c6cc9dee96d8aa623f8fd84aa8edc0d18ea82ce9319d4f7d52408e903325dad0000000000000000000000000000000015c717d944bceb4d49742411ec8e8a73bcc11e208e023e68f7b01f98ac7be8e557babe64da5bf4fbb50c86158748aa1000000000000000000000000000000000109ed3178a5daff7b565664c000192c4ca0270706fc7a0183a071c8cc9222820ccbba90c2957bc8eafe46703f971b58c00000000000000000000000000000000083db7baf34e5d542bc2194cc6e392366dd5895fde33c7a4654f5be6910a37bd2440d32ed6341c4b64f73d1b5f3fad431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179d929ef49df8ae1ebda88a578d530b91eec073b9c31f3f8c81c4d5873a260c97e943714e5831ce5c593a6a60ad081300000000000000000000000000000000071b51a611f6aae8d08dc5a56ab3cedd5eecc1e699dbdafc9fb66094667f4fab3e5066a15c65d84425f72e4f4440ca79000000000000000000000000000000000a3f84ddd786f48da54558b275c8e27afaf4b9fe709a5aab1363011ccc85627e00e949ad78bd3f5e237513d683ac718e000000000000000000000000000000001517a3b22cd6ac2ef59ce2817776f3313b1ed96fe4db283baa431aca0740e2d2ef5e2fc12bd5b0b66c86e6093fd8fce81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000013b03cd0cd2b3da6bcf67f1b66191e2ede276a1c6949a552784d03b02b0377a64b5b9ba19837f751a64d9f15ca5bd2810000000000000000000000000000000013ad666d1a6f34c1f647da9179c367efa2a7c29660913e4c3ee46d47f0e125bc9e264aa48a3c23e4a2d9f5347bd5a4980000000000000000000000000000000002a6c9fb6ca45ed061bd17513ecf6508d8d9ee2d8f918426f65058cad0c5e3aab205874c4452a45ea65aa2bbfcb67ebf000000000000000000000000000000000c2dc22dd05c745c5f9012c6d47075cd385818da8c91d6a70ee9c1e0d7bf497b85d5739285278e51a9fe7f283296d546", + "Name": "g2msm-16-jwasinger", + "Gas": 240480, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001104556aeb45e44cc8c466a67466a4bcc9ce6b62011bc292a2985fa6b43d87bdf8e6206fdf952703c7e441dd8bc753c9000000000000000000000000000000000198c04fb399606cd7cfd4a6aeaedd05cbe8daf953a63c69326c9b359f8048941c888c77602ed810aa83a218ef24eec0000000000000000000000000000000000f0f91aa814be133b06e6cb830cd4b97c8c548e6869005ca34c83dde8f03c9d9ccc879169b4d37e646a3e8df9b3153620000000000000000000000000000000014c6813606a7f77084c0f28b071905c9fb0189bc9abedbbbb30140b3894a13ca851717cd8c91d728fdb22c0bd4aeca801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000376af4856ecafe1e4482d3334dac0b730492eca9c77ccac5133570e2a3d3bd563b4a07e905353a1317d8ba83e2658a400000000000000000000000000000000124a5ef79681ea5b556562c237a35e25ccede8b9c871f70972b25d035dbd30f72ce04954189e2f9cc7add3a94f59bd5a000000000000000000000000000000000fa6de68187bdffe5275af1f590bea2a84ee8bbeb321f60c4c5f885c15d01cacb54de29326693bc239a14d04f012503100000000000000000000000000000000101269f6cf51841f76147147c90b881815476c62b42f7b71961a073a1f184cc4e01b6b3d656c791c1e56ba27965bc2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ba1a5fe02833c8600e725e2ec1a2b7f54be4dbf5ca6345d502c1fc9ab10c00c99d9f6120ece763d5532e83e426a596000000000000000000000000000000000e63dcd5386a32c287783a51492797752924713f7fd1f4ca41064e73c001ea057e9f976e4412b8b68b521837e8eca07a000000000000000000000000000000000d6e3a776dd6e7dbcd71f4666aecb51d214adc4af861a71ff2fbd7063469cb7e0086dd3d6ecfea00e9661c34a0f1ad670000000000000000000000000000000008609cd85edb79f4af9b9b2d68c18bb780d63fe0b2e4b4cb4a6ae1d64b25d9b39ebe3cc0055bb9244538fc048e8518941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f077c324ea0932c6e714b608140ad8177f304e0b133e6d9f42e668dc9a592848099d14b7116e650bc3c2bfe8e8c0e3c00000000000000000000000000000000021e2a8fb0962bf01b8e0b06f6824ab03ca53fbf6a5329c1c7572e6318514a2f17a6bd04b58b5f78a95671b0aaba1d57000000000000000000000000000000000ef2f38be769797fb08c80a01a842e1aa0d31c97ccc668a40efba145e533e9e8ff27f0c16c7699d817474f3195e7fb0d000000000000000000000000000000000c6e68098be8a66438e9bc378426f8c240fb6cf7b85ca5af8802fe42705392becae2f14f6388e11c75840447d0f5d36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2320c070506d317ef35cdfad07e47b664eead07644a8e6baedcb92f26a725baea5a7b433966f6e09cc4ef0a25438b100000000000000000000000000000000030509190d69a4193a2653b430af65a0e420ff2da2f7dfe7f09961a814f40921db2316035982c60bcc3a4b6d24bdbc77000000000000000000000000000000001616ea2634e28558e4a5c11064315629bb83aefedf8e96e4242dca7cef1873116f8e32fb6d7cf28b772ff2b664fab5e400000000000000000000000000000000187b1eeefddf013a2a643e33208488114b67515b025d33b62111bd31a2681046de8912cbe3f9347ff5de476e09d368431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d4068ee6abd320dcf4833f72fe17405e62ccdb38fb46cda3c328f1bb5769399a0f17daceff5ba72a5d0c0e25b89c47000000000000000000000000000000001581ae43f73c970ef95ec34bbd406fe6298a9ab90196a01d20bdbaa207fbdd7405b70de5b2c65f5d5795e2171cfecc0a000000000000000000000000000000000ccbe6c487d3363119acb7ab34e19f95159aad14e123a0a8ddaee7357f311be2583676f24ee0edc702290813af0039660000000000000000000000000000000008dcaa66df2b5976dd8f035f337fd5a8571c7ff68fb97d1194b247bb9d17325e7f9e47dc485986e320748f00edab1aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2b306ea42fa2f504d4641755f00b8a26496b7c1491c9827e335720ede523e72cb1b458861fa0889696615615651b17000000000000000000000000000000001071834c5fbd5be9fb9d76b74597569d912033d3912e15b2f8425c7561cbf27ecd114e272b84b53f325aa03895ebaf17000000000000000000000000000000000aa85beb2d031320e646d2484f60baa7ba7f19d836b46cf7855403c02363accc5a585f6c586975ab090684e4600c6c9f0000000000000000000000000000000003a1524524d3337da6b2598dc50a4d8f87bc0cf5ac1728daed21b2ecb4760ad89725cb65a1cf25d1018602e2ece363011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007accd88917e5ea54211a1b729ab5e008f430233b7d57bb3274e22abc3d0b721dd6d75fc192f5bef97d6b532d4829f1f000000000000000000000000000000000756395995c8e82c4e132df5deb98471e4725b6c0fd65499d64e7f60feb421b831e2c7c664091d2d6ea19309e693281200000000000000000000000000000000078472f3bcf1a22b836a71d0fc26f1e7ef1d1d2449e53219800043a86c55b616b3decb36b6a0dc09d897de07a8a7885300000000000000000000000000000000159afe20a5b84c33f0fc97ffbed58a47b8818ee1a4f7a6a551ee1fdc9f0a4713a8fae4659d1ffc786d3a26a4073c03ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731250638b25d7c233c1ccef3de8e5a21b73539d2a066e40a6361cf02976bb0f808ce5412ea59bf29d87011f39b17c20000000000000000000000000000000001b6a3ba61fad94594c410515f98678d6a57100e1e7782eaa86e556494995b9af16a03477dc224d2d81c67e29aad02c20000000000000000000000000000000016f8cecf491d78b7ef48dc84a00a509872048ed8b8e36aa8195bd743ac383e72c9a1d32e282cc2d6f35f28a05aaedb8200000000000000000000000000000000078531036e75d83a3acc1b35eb0250e340f2460570fa002f9407fe0a3c7da9591c710162c9b9ec07472f3e7706cc51e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9959c588edda60c184b9d22de33453d9c338c7892217b07e3c6c1d95b8d7a8b35e6a650bc14e419d0193123667a34300000000000000000000000000000000029a4f9a79e1505d72130cd287e67abe9567151a0535ad973525a4f13384371ad57c96acdadc2410a8d073638d29e380000000000000000000000000000000000b1d866eb5f67a442a8fd367bd579f96b3ee1f05bf066a1f293a451cf97b211d6a68f6eff542d6f46fb60ea9f06e27ee000000000000000000000000000000000146d6a623164f50a81ea9552be321c26d53e32138c3d23f1b2d1d2cf12e43e65b56ba4fbf5336d5b9e68e2ecd6413541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0ea54358992c5a4c4bbf8e93bb07b7df6ccea95768e4248741ed3bcaa8152dfd13406a6cbddc9a22e440e410a6fa73000000000000000000000000000000000d537c497f954afda663c54144f38e6cc24f662a03f762225617d0f5e4357c6a01eac7f3b927c1978d76d9e1eb0d9245000000000000000000000000000000000db9b4eaaedacdd13132cdbeb1c1bf593b9aac552645604cb00d4df65bbd1efc54417de5939ae478e1394330b0d79ad6000000000000000000000000000000000472a33ba55805c1a1646720f72fded955ad0adc74992400d9a98bf07087407a11d255a6b6f70fb50cf0b57f595a1c651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017983879118e9102e8b2ac54d71799e30bdf1188c638e54b7fbeb5f2bfe39eae62ad18560ed29a2fa2307a6a1d9db027000000000000000000000000000000000e19f4b8defb1b7798eb74a885461373c368ae17fd101cac4039f0de41eace7df689743fb8f9003e7acd04723303682a000000000000000000000000000000000a85f33e410287e5f25739e2a2afed580f12ddb4ffc0c8c4352375589b3b56d1d55cc3bd145aeab54ee3cf039edd3dfb0000000000000000000000000000000015da8e3e3ebea1c51c68c0f3af09dd442a56ba75ee925db8700bea0a5b75f7cddd5d9bb5477dfbcfab6eae9897172f4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf1278667922f7994945f1688c96d373b6a3bac2fd6b277290c9f7ab86e049c4c661de7681b616823a64a6204a4c794000000000000000000000000000000000892aecad822fd54ba816345d36ffd9cc3995f435f9cf5c1990922a8ec9342680cdcfb076f235527e2b504080b1679ca00000000000000000000000000000000106af093f2778f6bd217876fd6403f28413e885f465e1019b83472ce4db3908abe0155334cb497fd44197093f06b0eb80000000000000000000000000000000007011bb29fc0f42ba45b7807be97ab361af719914b501d5325db1110d943af902a8fe070401ff1d77b78a35a5313a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194149f41f5859428a7a0fd746e5af76a527e460679552cdbb9db8de0afe261d7bd53ab72859fdade8b891b6c2d7cc1000000000000000000000000000000000105ab549dba17a7235ad523d02709a222fccad103a1086f8bf658a2c08875122274021aa65017a6d12bb414e9e290e0f0000000000000000000000000000000010667b321329b2bf6219387b9b0940c15065eebc9dd12d397207c94a8b3a1bc4603dc23b799379152a46a7e666ff5a5a0000000000000000000000000000000016a57f08a8ff767661012fca04b227033b418f06f1ae48f11e2a510af89704909b6d830ebae761010ab27cfd333969db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8f0ffbe14511437a93cf5d5a6f41c8b141d0e2203bc72a54123cfd5f4a0bcc2af21d74ab7cae02e64c89c77601bb90000000000000000000000000000000013af57bd94c81ea4a2322c649b7ca7a8046d6dd71f774022a2ecc8214a7f87495a7361d62077740fcfc8ad8162188c760000000000000000000000000000000007623f4ae90d7cf1e3b3b269849e4ab2c8ad42530de2ef36b4ef4177a4b42d52ce1d5db26487bfb66b3bdea1ca5ad9800000000000000000000000000000000015cc4825d19a5824a24e147532588686141a2220e76e4ee45f89e181566efafbbe2928face6c1ba5e7d76290c503e5421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188ef76f3f636614fbd3d9be8dc5ceb80cc3b8ece05fa1ad3bfc2361cd9942decf6b5c97ea3edf5420a8f5d530f4ce5100000000000000000000000000000000105ee34bf0f58fe297ea264ae6307f3f0a14adc34eec12512ecc85a9509176044cdccb1ed1e7234dd336f4759c7c41d500000000000000000000000000000000111cb92d59590dc3c5d97b2ee4ad42be6180e076c41e0360c71a031552fd54665a21b462fd9ad9af9ff0fbbd1e3c111a000000000000000000000000000000000e5fa87346d31866aa046c6597d6b7ade36e71453ba2106ed739b512fb6168c61e2f7d1458137237279354b526ae84a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000beee9a81cefbcfacd5eba208142a6ccdcd40556483345155e4eb64d98eb07dd21c05246b3f4ef786fa45d606e207a1c00000000000000000000000000000000189891e35736b0190e6fb5ee9959380e9a1e1815590e4ccaf0cfee72cdce0c9eb82f87c7ececd102812debc1a51f2f51000000000000000000000000000000000d43e75c52216919c08749cd87f812ef0a95039d22636c8ef7bf0796ce4d84a5d0d25b26194129d071325e64a44594b2000000000000000000000000000000001007fd530a197b73dfa671a8aacc929a94b201f86d56467a72199ebfa39709818e917cdd6663cdbcfbf6bf7a92fae9e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000ae34591f4972146fffd248b35f012ab37061bb015d87b8019964079e8288a814d997c2c62b6d460ee5cec0f445114770000000000000000000000000000000001fe760c518dded13a56b10b8e266ba621b65ad81ffe5d9b7f48bd1f836a50be51449d8bc2bb50668ef6665a7f500b9a0000000000000000000000000000000011e71eb57d8c3fdd4ff08bf07cb79b037d08dcf554688594ed8a1a982678ba9acbfadbf7344a4b3aeacc5b2e273c8fb800000000000000000000000000000000149e4e3cabf0cada1cee16360c62699e4560f950269310b79e5b50732515780e489b1cca49695e4e607ca0258b97456a", + "Name": "g2msm-17-jwasinger", + "Gas": 252450, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000035719ed98fb006b91929459ccdbd9ec3d8a4ee3722fc7a6dae78885a022265c1cc591517c2ee8100d41dbeb6d7cf18f000000000000000000000000000000001996319f8063de95135c754433001dcfe4e07519c069f38c81f29b5c21315f19e259282500996cd64ee7a4cd5cfc393d0000000000000000000000000000000001b88d958e0aca51e2d31040da8444a92ea3f34af2ea0307110baaf16ca11a2b91f27e44e52bea856f2a8000c334971600000000000000000000000000000000102eae8acf7ebc9150b37d09a0cf5b99a6d114fd9fc256e5fe0414ecd5a3a1a533f3db8cd8c4b1afd3bf48f349b404141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050cad5460e28bf5d32db9c3986733f148ae9f36dbbb76a5d8728d29802dfe53f467893372c01072d913c0b83e9b92fc000000000000000000000000000000000e71d19bca2853a29452ae941263071d7b6f6103e2b6f6641aa943a83ae987c2a252742ae35e1c738ec9139e21aed4df000000000000000000000000000000000b78e8d86de0a4927a7a8d25cf0a0029c25b8c6620a7ef33cf6747caa71e29a8f0182f4d00e81e8668c79f3cabd6ece400000000000000000000000000000000033733fa7e65bfa79119196911565917edd32652d0bf11cff8a27569bf22c00d5f3468aa66fdb7e433ed8e5fb4a07cc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b7b2dc69076571e574fd74bc86b1d47327107874e53ba07529ec3e3deeb1316a199a8499f15396f966a815f64bbaf30000000000000000000000000000000018bc97f141aa016ca6ca93aea5805a63c18873fc5f955c5289946d66d5eca77090a347f1f1d39dd8b153f1d855e00a910000000000000000000000000000000002aff2b3dc781bb0a57f04564e299aea6c2351f08a913a7a24ad97f97e1dee894ceac5e2aa2216941d0e689da5ff6773000000000000000000000000000000000d8e5168d7711280795053af55a7eb6822fbd5e0cc413f5779396b345d9b7497405b0c5084f7871f0fb834b2b563448c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012128c36a1d438083dd79a43aa0df1cf069a5f562252c1f274c4c08a0066e8a592dc0ff99e1192f744b9e4de83bfa7d000000000000000000000000000000000ad959e43c6e608ad264fcc133abb4917b54e3db6673ee277aff84774e02a6376ba9b3950cdc413b6fd4051674ab18db0000000000000000000000000000000000e423d1aeaef918ffae49d269c8c8a0ce9158701d60d572ce08af691987803e8c5561a16438914f3b5c8810ae0aa9f90000000000000000000000000000000011634f65fc32ae2271bb957e31314e4cc7adee902bd78e3513aafb77964957a09dd7afbd988fb3debf4eaf32a4ce7a2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016501daa96be2224c9c53e2d918aec64052467edd47d4a51860384a082d487b70ebd869b32e91fa7d4c14caea76fa14c0000000000000000000000000000000008b9f14ff60d996bfa5150bf5a3c2f2559e3f7a9ffec965afcc48be2d8498020b55eb2f64b347bbe8b8a17297edecf680000000000000000000000000000000006848030ecacb1b42fc4d2ca9ce9b67a3b719349f60bc01b663a876d96df736d33e58d534cd71b84b655f5f1356f7be600000000000000000000000000000000076f075f53dc9def4207a6c21a7d85991d4c6e1045a540cd61a8c11f87c91128276fba2e1cfe708627e9a1643bea37481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001489e34a5245bb4198096faba6093cd65f2941e5ef2e2bdafa9509db89e36b0b0d93c260e96cdca3b9b6ce00acfb69fb0000000000000000000000000000000014038bea6c0852ef99321b14c2781e46cb8cf6ecfea7e015a57d0e577be3c60ad4b72cfea35bfa7bddccf62b2ae74350000000000000000000000000000000000121a942d335349275887731fd8134623ff7cfa6468428810ed5bec46318bc0b416fa4daa2e75bf10797d2819cd346780000000000000000000000000000000019b621d92198088a212dbd1c865f5b43b70f96ea719ea675a46e0272b704d89b86cf6dc0eb0738c107409e3b060970501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c35d18f35a311138652d7bc36f0884a2dc0f8b91c3679dfb596f25b5ab4702d1c262b88d811acf363b199d1a6fc2e90000000000000000000000000000000011323676de68c724929dcfaa5f52e4f9aad2e43cfa30ef76afa726ad843f6841befd4dcece238f623e0b9331651cae62000000000000000000000000000000000d695ed55b40264d16c757379e2b38cd251ae2ff0be327b2572cc415554b6a3c4831a462b901b5037c9c55edac28273a00000000000000000000000000000000185e3e5a4c19da26cd7516cdb0176dda8ae913f29a92d69c609d1a6bad1f535eb270756addbb791bc3ce3f7f5cd1ef211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168c03cde2800253784925dce9f31ca98c20b01e2b22d174a10d769f97886ee04cfbb9ac2f9d3dbcebd2461ee4b7b9f90000000000000000000000000000000011074252ab583d934ecab393706005ea724d57f7d29b3b34912a1bad84e599e5ab13f140f80c183f08ff2096bfa8c019000000000000000000000000000000000b36ff32db6dfb354794066938a652d042ee9647bc1d1520a8f32a4f66d9344ab843eb3d347d010503bc6c19b2c9244300000000000000000000000000000000060afd6fa713ff18d4d884b223dd65c4ef16c8e209d32805e51efeb176f43ad7115d2050ac2f434f480ef96d64ccd7761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dd20d5592e48445e11c35ca4eee5e97ddb657b71b64baeef20c158b105638adf9bb5540c3dcd2cf42000a785fe572e000000000000000000000000000000000a54693a993d3f6238ea8303ff857c56f2f3e9e75069c8ffb280ab6b3a12c943e3afa6fc06f299ed0550a5d87ae6aa28000000000000000000000000000000000e364b04ffeb4d738fac3ee31acdc51381606bf6e86b5c27db8fedbfbee6bf7b368160755950f1cfa23764802af4e3a50000000000000000000000000000000015c1c0756f614d002f1365925e73b4b00e618baf5c5e8894bf4ae72665f3e3b40783d309970b170c88e017866c402c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ccf1ae26d6c43eedc0c2403b3367dd8bbe8750fc3ebcb5506b75c81678f94f88f6c916579701d77bd11fefdf18bdc6000000000000000000000000000000000eee7577ebaa852710e6854dda56b99f4b459816f81fea9b5084431580960b7349664340174a5469e77bd7c3ba13308100000000000000000000000000000000128be48b19560b21d6d40a73b8ebe5b63df73169930d3facc710e997e7ae195fd641a0cc70ca835e8840aba48a5162c0000000000000000000000000000000001338804d0ff749c8fe0136e01b1f7f0e73783e03d991bc5109842f18205735a160fec54636240baf43a014783382da1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007008bdcca55692956df3519a9c945a1e48d2ffa1c6393276a7f577056dad11972396c3f1298d6b3544c8c135627817900000000000000000000000000000000179e40e314439c7308e4f6dff7f9c7b7346fe7e3bd5d09848d0d8f6095fef44b9462909447c6f97899295ac682f29e1400000000000000000000000000000000136d33c2ca515c36c0d265e07b830064c6964e7946876154094b37ab7e8e20bfadf3f93a4fb9b7985cfa098811e4df850000000000000000000000000000000000c08cd7dc791227e25e3b6c14054472062e0fa489e56d0861c21be190b5e5097a6e909536d297059ac00b3ae7374c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4963bacac22f80ba7c11169b304eb5866c70a7186625f365d289eeeed97c43e061edcc9e4bcb67edbb4147d9f34e9000000000000000000000000000000000d084653c685b7e36f64e9641f6041c41b1ecf4c30066adc642852ad628081cdd714c48312ae62b7061ccd193f9297f90000000000000000000000000000000008b3597e599aa1477eedf0f20e5276f8ee4d15811b7b49f9fa40ac5fbcea5f53879f7beaf5e44dc2dc83bcec370dbe1c000000000000000000000000000000000b3dd0f5a7c7a0b0a2427e86e2003275ed2e2a8bf62a51d6f6abd18562fc113d999394d5175c419d2c22b2ad431cd3f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001581b30764a1d414ff4e72e5707619ada81b04748d6465d31c5f59ae5cad0aa4b7436442d3e75a1b653b63af791f5b120000000000000000000000000000000010891ac43c75dc38e151ceb409b5085d9cf78307bb27c0846d7e44618bdcc2312ad65374809ce8789416a618ff160bed00000000000000000000000000000000111009eec61f58302425a1d0019b05d5437c447df221ed8d80285c565d5f50fe03a8e4d28dd20683a2184abe648a69710000000000000000000000000000000003bb86312fa9b8155d49c2a975b05a32eb057431a570925af9132e64c29c73754fbabb2acd97d7c6d283e343293096251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d2ae44ed5121abeb05710f27dea8a01218037869a4e11cf15d00ecd8e2603906dd7af6c7c3fc1865adbe9060c2934c000000000000000000000000000000000922107b997a88cbb898dcae58f4651b7e4f4b5726e6da2f591e3619800138899f780d16fdb4e91c31fed5c46cb779b60000000000000000000000000000000015287940736acf6538148a79c00457e0df3bd9bf4328be2d340d269d00dc7ba5037557a352704bc9b0f3eb8f6b69748f000000000000000000000000000000000b15be9d58cc568ee15be155e70506cb59e768f7186d7b563b1d2d1271ff96e170e8a5d9e25fe62747a2d44f32cf4b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ffea71fc64f8c12a57568133dc46d8b8af59dd042f9cb6e62e276ed98bb9308e7e7a9d86cb372809a114e71f2ed460000000000000000000000000000000000aae2c13efa33d014785648c98fddc09130de67d8255d6d79250d408e553627d0cbea4d677d426bf1f9a25cce21c4ec9000000000000000000000000000000001258dccc658812f666a18fd832db1732ff84d08cefaf4e3e9bfbb72357c404d5721ff41cb7753b88dfa3e2209d10795200000000000000000000000000000000122b23779304cb6b46bc3417bafd9f5725309cffe74fe4b0b1daaa866594b8cce40d761cccc32c2e8991955dbe046cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca71ca2b92d46b65ef609d058c3c7f2ba1614753da04fc98b0e75ecd3b701f397326058804c3162a99def024d9b99880000000000000000000000000000000015137873e7a55712fbc20c7875f599b52bd20ff8140de5c152fcdf38aad4811517a2a0d1e4c4323b98c569b37eb6901400000000000000000000000000000000080caadcdcaa4f67763f120e2903071b7651eea27fbb4ebf693651fe986ae63a2e409975d65df7b26b302ad17628efc10000000000000000000000000000000002b082b2cef0a5e458b0a498f021055c1df325f829e7770938bb85ebe59c55011192e8b0d89d70d54760c3433cad19061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110ac8b1d632cbf5ff24b13be7be786641a93138dbf10da4d0d8d64dfb421848075923bf928176e7eae4515990bf0da9000000000000000000000000000000000c76aa56b592213e39e31c24c5183c7ce5c5b9f90f0f69637e1f23da8848e802efb0a579273f329e841b95036b4423bc0000000000000000000000000000000009c74f81ce87f33f41097fb21031e4e332c5eb0539b58e6dc5d8fc780f434949564ac4e5a4b362c565f893942ee0abc9000000000000000000000000000000000d8069dde5a23fa45228c3af354a55a9ebd1138363d1e08f00b4aec37b606218614bb62205b5d28416aa24e1f9b435fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168bad83d30e07baf51db477b513955fd5dcebd46233b36958baddabd191fb02556d280cc6f2bf53337838423508f438000000000000000000000000000000001208bb4851ce728bce46afc4889a9c90340bf5d9093d84c1cbc275114fd478455773619e2168913cfb77eadeecbf049400000000000000000000000000000000113cef76c69edecf152d69ed9c2e402174ab8100141ee041e90ca6b64af9e14c62da0b589a8c461ebbbee6ad276fe67b00000000000000000000000000000000109acf09c71e4c53b15957073f3148bc719d22252996bc350f8f195f7324913febdcefa9aa417ad8993faebb50054e511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000007690d3e54ece0c6dab5d93090807691c391a91f63b9f05721373d2eedf91cd0c6372209383785a25b8891e5cbb1a4cb000000000000000000000000000000000e01ea6d7db007525fa4563493ea8b1dd793ece30c82ad6672bff6ce95ed270f0ae74ce6d02860006c8f1ef7298899620000000000000000000000000000000006fe092c18f6fcd48d7028e1b3f73bf4500b22453ed16f346e1a9b806861f288298db51d8d9a7ebfc0969f6b33b4b2da0000000000000000000000000000000000715059a9f4f325f23fb59c655b0eca4dadbba891249c6f3d0258c14f33b2fd36b7e708b98ceccaf8967eae9c8c1af2", + "Name": "g2msm-18-jwasinger", + "Gas": 264060, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000c91bf16071c210bd2536006eda967351e05136448c5d117c5cbb1688a7706e4da9db374b1de6326dd1e51bf44521c1d00000000000000000000000000000000034d41776748962e7e90570ee764c555d2246c02a25c71056db7db526b07355fffc18c0fe6a63822a51397a19c4b5f6100000000000000000000000000000000026282a86efe2f67d7b705c31a432d9751af03c4dbdc0575c2052ccbcc24fe8fd08874d5b9db7b8432c8375902bbadb30000000000000000000000000000000003fe50bed667d6446f8201bdba34cc92faf2760dc71d0aa0d13992874d74745377488eed34874807d08864d14c0683d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b1fc64541cde28fa3ddd640a33d2d010a65af5d0877a759f7d96c07ddc34469c2ffb4d3b22127d9b88e33f6166c31f0000000000000000000000000000000008e61926c9beb2b61a33e2331ae017d2edd5666d977301a307ca2688066456f846461f60df878056f907850de48d96ce000000000000000000000000000000000b03938811b993f6c5e61f7436573a642539b001628463ca899585c76633bc312104ad276dd8ef38e0711f33e02f2e5f000000000000000000000000000000000511de2e37e24388e0c35cf0014aa305456c4ae7e832c8788cbfb361ea4bd2b7961c871081f822a488f3a7d80ae5f6041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cb69ad4e9b3c07932626844faf207f70d6a4ad387e97d584c0120d2cf71811c505d051efe796ac6c2afe5c8b89258f0000000000000000000000000000000004524e95283bc2df58a3df1711286908b4e6715ae78294e2777960c314085bfa863bee6bb8100b58fa47ab9bb2d3d5e5000000000000000000000000000000000e3b36c1922c77dd0d6f1836d5167a776f29b06006126f86f4aebe0ebfd3239c685fff16fa517d58c2e3bb52bf8010970000000000000000000000000000000002235af179058e1dc3343cae012b9788baa21457a846e276baa10b8c21a598aff439d44bc5c0cc1c33b2f41935b5675e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fadc8f674a9e2c0fe747583f301c23ae9f9c7dc39ab78c80a54ce2bb38d29000dd085e77a7cb7d4dc3b48321d7d2ef3000000000000000000000000000000000439234058aa9b405cc364087ca30784521696700e88ba11924dd90c675b740641dd059fd0d780880d8e916efc2475f1000000000000000000000000000000000fe208f0274da997e803ad54051aef3995508b46439478c03a4626bcef7716ae8c5d8310cf2794f4267c823f6f4aced800000000000000000000000000000000009d280383446dcf7f5242332848cd2bf2926c11eb51dcf17a3be10810fba75b55e3ea9ce9bea09ba9258b3f3bc92e631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c2d912d5b704077d63f16b64aaa8488f9c287b545a5a28ee0794b093a84221c14bd2187c7292450fd18b5877bbb46d00000000000000000000000000000000093c34af567e20b280ca71023dfd63dcf0d6b13f86c1ed5635d4970aa51d15023e9a1499094a81497de6765b2b2c60cf00000000000000000000000000000000137ee6e7169a7acb41ada9caa07ab4c0e4a3cdb5da3a9e9187c990e315c772433609e84eca600e07303be15cd66ff3ff0000000000000000000000000000000000021461bc73aa216fd499b71581581bfc909638d358aeee8d0959aa9e522c90b08d0800d0babc2b62eedb09f5ef72961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e3d9ea82df847002f31ccd13eca5e3a048c74bc52a8a44113119a2c61da28c186e8175b6400ef8d6331d189ff93ae6000000000000000000000000000000000c42b746f98a83238fc5c1c46c53edfe7d78a71071f255d42c2080e6495fba8164ca7cad2cf609f3ca7d28296b7d0e47000000000000000000000000000000001240d63ba7b36bd6db5dc681ada6c70315223631c02f17f1459c90ba7ec1dabc9b67d2d23812c367d9b74814037604de0000000000000000000000000000000014ccd4da05c7118ebb426289e45d214bb940c43dc8e72af906aec699e96826545f214a87fa743475a7c4397d65a740f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014be2ac2cc81d88aafce14ab6e2d0b957edb01c6eaf88da76dd4fa08d7c4754d5cb290f26e96e2c3f3f159340f2dbe360000000000000000000000000000000000e692f453e2568b88f22ad857032fc8bc91a26ca19da612fe1050be7510366f1143d57d6011ac7f927cbf40986002c40000000000000000000000000000000007165af45a85c1cd182c7bf81bd88cc8d6e461eb471acfe357795b99e8fdaf5efdefcd2113684bcf27c2a0fb83fd3fa00000000000000000000000000000000010dc9748f27e02f4fa0ea743908b589a53a75e23a8de853898d883532d660e0c899591a0f7390e02c340b7d8d3dc98d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1890b4d4dffa5a4447016ae85772c0bdbfec6c5d26be7677714af485ff59714d340a22052f2698c1837fed5515b1800000000000000000000000000000000072990f6c153e3a4a5749eb17739336d433f3668be36cd186d2229e0bcfa9a1ea70befa3cb5639d72f6f2e5f34f79626000000000000000000000000000000000bfb221684b2ce498b5199a161ac1ce04b8790c15ec5bd550bb42df81e64205bf5958887a4d89cb21ba9185ad75f5cb9000000000000000000000000000000000d5fa435a1739ddfcaac1d5b3c14bbbd78af3612903473e9834a52ac2ae5a42027182d52925efcf7e700817867b19be61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024026ada856aaa945fae34944e494022545bdf8bba383810c68d15824d0a80b274a0a46ae8c1241385f975af9c3e1a6000000000000000000000000000000000427e0dbe0878f7478f885c4cc5786d3e2ea5149cac6d19beaf903931affd277a033000fa95e11bda7ef3f5f3d729e1b0000000000000000000000000000000010683dc1fd8b4bb10a0f6eccd6a2795392b1787602f5593804ac0d30d821c6003aa9369eff358ec28f367a6d595ef419000000000000000000000000000000000fdbfdee49be804da8ddb8a5460dde677c99669bbd344606be6dba6a00001df826527d78608daa041fedb600d6d32fbb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d0ee130af57a0ab9f28e370dff9aff4cd96c98ee81b11f6c0eef3bf04fb3795242720e6984c96ffba1aa2d46c55fe500000000000000000000000000000000154c7802c70aee1fa597c413cf598c7f590cff095cc54d635b36086cc81f56bfb3477b70139579298f45095077678e5f00000000000000000000000000000000108ad6d3ae1d2e0dcdbdf17397323fbc14f0b48c1dbeb78dcd91d03695aaed3d1df15025f0dc8e262931ebc8047e57ea000000000000000000000000000000000cd0950ea8964c285e0d59c954625246b2523efa09bed7be352625fe9669cfcb73ef34f40e2ffa72e7ec638a3aea30601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a0f0f572d2157e275391323b94e2b2dd34dec5b8d55d046db9af267ded4954d69c2474ea41c7a9d184ea5666d2c2400000000000000000000000000000000096d572953a64e9d40b1c40d43b60a1e807b22d5562cb194374da03c2570a29448c7e8f06b73bd31098d794858c6bb8b000000000000000000000000000000000465a2a55f415daae86e6f6b9345a4a0fb8b9d2c5834b7d8b23a5c89001a549e5757a3bdf336aef693f30fbe8614162c0000000000000000000000000000000015fa5ebeb480bd25dd0b8c4ca0736b0027bf38c54c3191d591cfc03b1d7214fb976cc81669e049fd63938f07d7831cbd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121a45ffb7266cbefc77f70ccd2980e545ea958c8b1670c899aa5cd796f1c0e67756ff64f0c16ba29321b1d7739df4b0000000000000000000000000000000000951dc5539a1a3aefc8e5d19c12a0ef501b980f0cced470a5a7bae1705d451be6a37a0601132f470361c89d8fdb6acc5000000000000000000000000000000000552b54cd7c46ece6bb050b6bcbc648a72104bf9a6302c33e34b25de9edd9a6c1c6b16cfcc72d9634d1691fc0e7235470000000000000000000000000000000003ace193ca007420d21e327ee11e192b76f1f3279edc95abe8211577e0f00aa42c20b5c98763bd194c7f6d8ff84e8b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000862deee31a4267b28f68c6b4d8072fb96649e813058835099e6f7e0089bfa2f65dde0ae39f26f08377d3462b62d4535000000000000000000000000000000000e67769410a7d83423cf56816b7b9c16b0bf7cf65774430a7e5b409971b1cf3eee0d7610e2a83a18d202c15142e0bf070000000000000000000000000000000016911816e58f03c5afd11b3f594aeff05cecb58adfabbce0ab3ef9518d8b57c56914c7da80f0c8dc694405e4bf0e72d70000000000000000000000000000000006021b3c75ab2e839e644f79ebd78dbeb6d981f7485a3c3a7785507f8706e31d268594c7ca3758171723b3f022eb68791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f60a8ac58cefaa986ada5161559f76f315d4a3941926f6039fd42ad046ea4b17f555d645e30b9086fe0ac79db72d73b00000000000000000000000000000000136d02c317e369484beb6f8ff5bbd248e91697c911ce7ec86138686d242b49c3612b26def46b689572a37ec8960053ee0000000000000000000000000000000009eafd39d08da0610701a51742c5bd7f445f2f3f0379ad227fcabdbadb5c96ac962486c32e12a98b68922a2c019a0311000000000000000000000000000000000a688325c3cb618324257308ef898b01e39b740efae721b748ec705fc0b2bd53e4cc4ac6c0307d0823c149203d08cace1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127ee5548f43212192f8e529605729571c2c331dac3a68cf86ec0ad79dd59edbad5e2d70c8d5152cd80af89bc63e73400000000000000000000000000000000018cfd9991304e47c4fe81d116e55ce9b1dba7367fefd654592e739d6269449a34cce78a29b26afedb86b2d09592867850000000000000000000000000000000007f0acac9e1a56123a261ce6b0199c07b6df27974b6212a4483185a4e9cc026dde4bf0ed2a6a34e46a31e62c663aca9000000000000000000000000000000000089e1f4fd8fc4f640729f44735991e5cacb3a1dcfc66799ae6d75e473a17ce738f1dccf55cd3f1ca103f825f277c7cc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e2a0683a04828cf23330a34a0d83da288286cea881bae946d84538cf7fff827bc46b7e7efdbfd1b8e97d8fd0969f0d0000000000000000000000000000000013a5de76f1230656c9cfb6a67efa77148947f2c03b98b58cd9352265f182788aa0128bb8f022f0db290098e393231d050000000000000000000000000000000012921b5ebc6a93b6e408f4c1c39a949a1937f79376cb4b10264e1313c62662ee5a638be4bc063ef0255b66754dc974fd00000000000000000000000000000000123e91bc924a36ef4ced5f4bcca7e95ea3101689d211d67176e3f69ef17d59ae993ded716adf4a860dd26719d1c722bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005024a8dc8f20c6f9a9fc082d79ffa62f08f658687c65baa99d354cb70690b00e3fe94dc98de823441eaa17ca92ccf9700000000000000000000000000000000196fc80d0ea57973027f2e9b30de3ffced35108534b3cc93a9425f9093f94b47836b81c3e6740a2130b155bcf8f3c40c0000000000000000000000000000000014b67f4b6dafbb2f9965d9bc7c5055c05c9662ccf6e4384ca68e2915502594c31e75ff5e37bf2f2f739ca1d4f5189baf0000000000000000000000000000000008dbd838a78bb3a44d26670c295611de82531c23611377775411a7897aaa06454a63fd70eb4a8abd3e40273494e396911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001025f0936d17d59f6cc4e2acbe9ebe5219615d319ec8b275b4bb9f5797d995932905d9399d4f3217603d8eb10a6ef48b00000000000000000000000000000000037402cb72cf583e2240c1f72823b98b76c67aa670733836f4255a0b132012ff86d4e0fb11d675175a6ad893f638671c0000000000000000000000000000000010eccd435cb96983304b01fdbda592b621bb6987234ede0260a16a5fa0fcbbfe48bc9c252212087e09683eb2f7d6ac970000000000000000000000000000000012218dcee30d14117028de2334c5fee50ec2023fe1c7b92d20acb7b1e7524902eb6f6ea4a3ac933a7b693801225ad1f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a666e5a713bca8f6899b90888085ca1f8a1b15753f58cba354bd30dfbcc6a5ef8f4b1cf869892bca1128ce06ecba670000000000000000000000000000000017de6a3422dfff948b2cdf00266e7e084de96422aec023d50383b55dcee605e469d8179789c96db957b2e9081e2d45a60000000000000000000000000000000002d935542ffcba215be258b759cdf34d315022327cab48a669bba812f2a307a01194d88a37f4d911d5a911feb95195bd0000000000000000000000000000000010d3adcc9dc1072da84e2225b5eadbe64b3a7d3668786a1d9b8b0da378ab47f55f0ecc439ccfd80f323491d22c0aa9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000ac45f63bc2426d934848e994fcd07ec5353eff9debacda0c9e73f94b90cae7e8ce658d8b6ac43e001f2381587f29728000000000000000000000000000000000726bc1ccc50a031774ab909dc13c8f90829bd187120319ea5f8691279632c55a3f3d0a9f85ef35206b8eb624537e06a00000000000000000000000000000000119a0e0c1d5ad07b72313753605dd1845dca571c4906e9eeeb172dfb7197b177989604c01ddc8575a254801503fa5edb00000000000000000000000000000000146a7ab3b15a558d91e5d8bfff3bd43837ba9db09f09c58c4007c0d42bdfee962ebe5d09423a67d49cc0509d3e2db6e3", + "Name": "g2msm-19-jwasinger", + "Gas": 275310, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000148b8cda14be26000e73fd38bf6f5f6363b6ec3bbe23e7d54688483f31d331cb8992e45b71220d78f45045c59546c0800000000000000000000000000000000013ad017bb43a34bc478917cddb29eb9de0a6c02ba18afd26168a4f627dc5e35784428aea23cd4050a57d8ddece5f52b10000000000000000000000000000000002d8f0459a0bfe3235bf985e028297017185c83384debe144a86051957701ed2078aa8021cf643063e38de97bd7d06900000000000000000000000000000000018a837d7ba86539449e8a0163cab22ea0beb3dd56a2c163c84aff64b1c7b2ea291d687c4b14f0f9b66bb760c23897f301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193e5f6939fe4e092a7f74072208c815a91743063c0e91158824f1761d250508095477813270a30b69936cd95857d9ea00000000000000000000000000000000055143a310fe4e1cb4902ec611790b859a63de47702e7edce614ee82b74a024c12ac7755a43c64555f545774d2fad240000000000000000000000000000000000bc6f4c38059a65130f4d104285dddc5d4ae2aac4515fb5199e3c679dcf2c20da5251c93ed240a897f37662225949c4a000000000000000000000000000000001018c9bd59938df5f95ab82df112362fcbe7c17534c74c9c3ccd9377ddb588e3ae5a5c0bca356a7a7e5a59fb6b627f391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9a3c19f426c642a26f3d793d609c2a86311e3702c2fd9542e648a64c6570b97a83b0582392b575c1ac0df1297709460000000000000000000000000000000001dc8e6013dfef3b23943e6cf756550e197a400dc0b7132db5f863a51e8f80b78ce25cb70c8c59ab143ca5266e388b5b0000000000000000000000000000000008a02c4f2817964a4d39fc78c102445d9a61bc5d6b5bb2bf883537f56414265d863df173bea34645f1e75c3932ca485e000000000000000000000000000000001256a12c75ce894d69e8454679d753b348c4fce2174848cea041b8d8c14ab169b999a00325bf48e5583ed3e628e9d2aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cd0ec3445f279cad52433bafea18679d0f337054d02b7dd14608ab1955320001a73f54e5a46f56ff3e9692e8cf9a0a0000000000000000000000000000000002af09a6d73fb9fedb74c75f3e164adcc565f0e46c0aa3010a2af82bb634c61051ed85b93f99269f4e8f8c8bbbc8333000000000000000000000000000000000115f7eb05b3872eaa27c5ac4f29f02cc9978169e69d94ac6c2543e7b363046ae38c080ac076d32b1ba48d168c3018b0a0000000000000000000000000000000017f6a0e9d3f1e9989543b1a0ad2852a9c140facca300feaa124eb73ec85b7da627fa3e51c5f8ba01e70a8abc36dd88201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ed7e1acac29789aa95c94a129d9f713ccfcf6f0556a6a78b170cc22a93ed9a6eab92c3a491b48f6942e21e2e318a0b00000000000000000000000000000000191050f1993a031ba286559964f9645efe8d050d6a4b7b5395645a508be3ee9a0080df7c6725d70758c2af623683b8410000000000000000000000000000000018302c4c6ba7874aa0ec9b4da43f35f55a4e0c48fc9b62c47b77da24966228499c99807965716efcc17ed0276ca56811000000000000000000000000000000000d33ba1b47da75fe1747fddb27d8f619e3601bc23eb9572cd0ee2593f59b968b4bdf976cc9dcda7b892e1e0b4d24df0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf42d6d9ea5c339b24e16e8d3b4f3f41c2ffa95bca3c607da2f5af709b2d720c3f9f2f4b0fd1a3c01b483d194f13b9b0000000000000000000000000000000019787ed52be8ba34299af93d361fdeb2dabc58468056fb42e34f5f6c846c8ce527556b3ba746805aa7edc57499a990e2000000000000000000000000000000001497374c96893f08da5b90dfaee78d4ce4082f2b18dc482feda4070de15e1e4ad791ac705fd579e2448daf2d1106f3aa0000000000000000000000000000000003f89d9b704acddd21bfb1e4c0338230ee18d8b9c423a732f6a58776d6a937ae1da0a1a0a7f9a7005e14e13ab0ca9e481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000159a5b54f953c591855ba624d478154575d59c8846e00372f2453fa2601b3433f751964e51cc1409c7e96f487b37a880000000000000000000000000000000000c100c5b8da9d9bce8f50e031dad674f1c92c822b09a76cd086b78394d9790b5b6a23afa1f61cee066b0041369f5b8600000000000000000000000000000000068baaf40e36e12e2932b799c4422060e71f9142903d7e8492505228bb412f9e31c1a62368206494846c274df4643d3d0000000000000000000000000000000014bae9f6afbf3e5c8463d07cabee017794799f2a9035918f1f50d9ecd1179179400db98c030e4ad491c67ad12324db541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031ce7aaa496cb2021a57fa45f965c7f03b9f262f69072ffda3d9468c5b93a104c9b70a55651b1ecbb2e450041bc7d8e000000000000000000000000000000001222937b7f479ea3ec1af8c3194aedf561ef8508ac32f8d83105719370fb329c736fd9031f630597d3ca34a8520de6f8000000000000000000000000000000000c72a1737932a5fa47f9dfcd147c390dadb90cdaa8ef638d49aed6403c7f317bbf1f8180c17f2446e2ba05a79624df91000000000000000000000000000000000f5c314bac423a7414f97ae24b2eb499eb1a6aed5eeda0b4e8a3e52c392feabccaa586b8c793ce0a8dd2ec57b12ea9d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189f35bde68355420dc313ede7bddde6da4134033d08dfeb20d2177732b8c935846d8863d8513e02f7f8276bbf9f9df0000000000000000000000000000000000f85b5be789da2e739d08e885b9cea05c43da75096742cd947a80ce34d7c92bd7192875959d632b95e628f4062f408ea000000000000000000000000000000000949a909353d639529a1036c3811b63aac0f1e3bc0f0dc7f757ea2e79c82ff83040163c1511f4d77c4043bd6b29752f40000000000000000000000000000000002087c2aa2ef4ec5703205acb991b8aae33f33a4818a481a56316317c63296e3a2acf0d3604d00f84e6d3ed0e4da089d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098c85d6098e2e3cfc54c17bb4b00698deea5bc7f04018e514fb162398148cb81af8e0768d528fe0853426cafc5d004800000000000000000000000000000000076ff0a79e54a5fd716861d60f463534d3f9d64115ec72bab2ed6472d0fbd52face7e79d0c63f581e3978b84518fbc44000000000000000000000000000000000c2fbf304a4afee5df499a9040ff36b2358f5281218b6c884021e481f1b0ad2c480b3bec36bcbafa92b235cbcd6de8120000000000000000000000000000000010e8ff204ab55889910d6cde29219ec178d64c78f321f4a4fd98633b661330a474f7de7e0c91222ca5af7636c53416d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fab00a8d97972d3719825ffbc3cad064bc6a88fb4a2df8956c780f07930b20214aa29b339254fdd533839113a90dc780000000000000000000000000000000002f60f27634587c7b567516be673cc5fde7e4e77b00d4da7db2be2ae193d356e101e278d35bd49e114a030f8affb6e3a0000000000000000000000000000000012314a8014346575107a0eb34f7eb359d40e3b7ed29baeb5529cc73f25a151beaf2e3bd0700451c56da61caea596c8bb0000000000000000000000000000000014f9ddb4a24d4729684893936a27123398b340fd96aa763819f4966569c4fa422727b6bf035ce7b399898b31a23c5f3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152d1239444f495c61e3d6b3fd727fe7cf588c6127a0bfd5b3fc7ab9bad9b101c4c21790c7ac05cbaa17afb997dff5310000000000000000000000000000000003514e67ffb9c0b317ec0da5ba6d8893edd3bc4e76e230cde3de7d9c05e97527accc90e1fbabcaccf6f0f9a5a96f56fd0000000000000000000000000000000000da40fd0bccbee905f7e0f1f1e3fac02403ba83a0a3c15be1d3f313aed30feca69907c4d41277f7ad619bb0b3e36f6c00000000000000000000000000000000063f9dd09573d73d89bb783d939fafd6d1b333797a64607985d8317a1091fa4ff0464b7e8c6fcea2c4ff1bc5456a78831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000655d886f504d57faf1515431240c93c4ba13a04754a846aea59b8a779886d1d9b21182c55891018a2c87da722d3a14f0000000000000000000000000000000019ec8f737643ec3cf9af44503cae1e8e5c8028057103a62a7c3311057d208c6e9a06e80b09c63a0c7d5329b7c79d15900000000000000000000000000000000010a504bbee291b5bf5745a345d6a145d6d0a1ee614635923f45f8907dcd5e5a5f0276ce50c27e474d91448a35205c5be000000000000000000000000000000000b345c67a5e86d0b76f9a4e8312180b9dc46ee82208b7973a8c4de268200910bbae6a166d1a032ff0476d4871c1c62801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d34cbfe16be9cb89e4ca692fc9513976e24d8f826112dd93c1864dddf5372b9fde11559e0f17aefbb1b7b84932d3689000000000000000000000000000000000d4b1a482a504e2f47381959c2e43756639a1cd9ae2db035ac12263f040f582488598c2de0affed7acc255f0b2218e9e00000000000000000000000000000000161a4fcd013259e6a65a9d3358d756be6eab673256a73c13df70d4b7f5820b5cf96c3fcd6f6a20d393a3b3f76fa6007d000000000000000000000000000000000603fdd5d73f3d57d5e84c1d7d70d50bdc006df5f30a9eb990b243567a2e05b0c92351ccc5bb6e4049b4732eb9574a461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f75f8bd3d5da8b57b30085bd5dabd39b44c871c7b11f2099df1a86a2af3d963896397c523b7ff540f6e090da10d7a2900000000000000000000000000000000190abe7d06aceb09c4d0436c27c7c5ec5fc7aadcc223412bb5f984a3341148829b0fa4c4bc4eef506c2a91e8ca3012690000000000000000000000000000000004cddbc5d197cb038a32f291b154e57292d471f906dc786d2a7d185ea1521ff6780b51142a4db4e91057fef1ce1285ad0000000000000000000000000000000000be8608d4344ebdbab466ee582ee14f873f1490b6763d1cf10a3d6138b2ef0e95d4f854048fed396a217bace73fe1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d99275b0cb9e093d87b76f7c7a71e15ea9822c22e7cfc4f0864737143d92e5dd3101bda4074de326b844347761c06f0000000000000000000000000000000000f7c9b3030fe62c02ff067e23d9e8db36052b2746013051aa118acd3cc79a53a8af5fa016e72827a70e08c9c20c5773a000000000000000000000000000000000a915a8a18f1a2e43133b88515e645ddee5e99871ecc90f31c1697670765d892445e347f7d1765f48d6a27725048dad40000000000000000000000000000000003246e960dfd5644743e0654a65a755605f28f3c8bd679fcb9d11ffc67227ee4169d91b18f947c3507070eecd6bbfba71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000309ee42999c1333541620f60dfef1aa86e2dd0048173bf8739d116d3912cc38c852a56c15c2bd4a07edfd9d9673d998000000000000000000000000000000000b42acd7799718e6dea5bf2fb76bd9dec576e9ac4f61b92687175362aad0256c8ef845167b4216bfae86ab029390d7f10000000000000000000000000000000005008d39e608f4e4ede942db4654bd14b7ec8def70df20dda982fbc8f0e69a30d2f91adde2b99cd8c468d84620e2df7500000000000000000000000000000000013a39a75098ef70f1f89e24755a708b456997e5d44ce66173a1c1d43366992308f72c7c88e60da9f9ee1796773170071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dad73f84474b92f3a891918925528e7c81b7773cf88890ceddfab0b3c535a5f0637a71b27a6c02ac964998e56154ac5000000000000000000000000000000001196b0c9577a810e33295f5625faba44640486f4b46ee744665e66d271a04383979f69fb68044259bc327e077f99733b00000000000000000000000000000000181772b69f3c8bb7a4c4a8beaedf29297b17d7920020e57b04b58cf8e3e20b74e056f5cdd4de775963f6905ebc0528300000000000000000000000000000000009638b56b40e2dd2857c7a42a341f49d9b32f5fa861d0802fdef175e38194a776db7e9b58023b6cc1a11e283b59412311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e26d1c036e1b0437ea51f331a78863c57267e5de8f7f62d437ab3db8df80750ceacc64c27c75061cc6d3148e419c0de000000000000000000000000000000001413dc9007ffbb3a4ff36ecad179e00da24f49fee810f73b09ce7b219627a471a5bec302f71ba003e8c5b9a3c2789d360000000000000000000000000000000013fbfda0ba359d71604676c4809329de14509e7ff0a076b818f30985579d37b097608700f323ad1cfe1b1525d596df600000000000000000000000000000000001c25db3ee3021ad7a87e6225339f2ac5b8eaf1151a86cb9934e852866432bac0a047da92ac55d26053b03204a4d18e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d44f71bf6ff77fe7fd692213dd2d554b0da78f5eb38565b36ad75b341285a3e8fab5bb0efb5a65c7936c50345f98d70000000000000000000000000000000002b7b2c5916280b9882754f6dd9f9509a9551315eac9f44006115abd594920ece186d591304dfc23211fdaf2f306a7e00000000000000000000000000000000015bffe11fdce13627f1c40c04b102bd66777d8b2ddb430caefb6c787d9323b87d3504d7c7343f9a86598cc7e4a72102f000000000000000000000000000000000948c6669b9593b2a1083aaa6232dcdb25dd2e56b3312ab0aa0a6a226ce5f0dc1ff0fc5917605483bdf071ed2b376b6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000101fe94fa6ce1d05f7c86cab15308d6c6238627aa7666e82d65e8d47135eb27271ac4fbcfbd3c868977e0b3074c48399000000000000000000000000000000000c7a99db64113cf884eb7d6c5f74475867bba483ebcf7201c90e78d54cf652c1d0225c4c3330756f5a145dff43200665000000000000000000000000000000001439d8413d0ea71bb350df353fd3e11309533f7330018a460b5b2bcec56a5ee768aac159d44b480e02853c9fc74f951f0000000000000000000000000000000014f5eab5cb3d83daf0b7cb9b09a08f7d1c8a34c26fe60bdb656907a6a0d921ef70af098381b11e95b94685fb88dd9236", + "Name": "g2msm-20-jwasinger", + "Gas": 286200, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000d39a25a214788fdea5584867a70913b76172e4b2a1e189fa8b6bc2761a5c242efbef62af940e3e094fdebdfc41f167500000000000000000000000000000000115d4efa0fe0c68e0fd4d05a577639bdc8c228f2fc725a4339203236c49555929d1a5cf5c5c1629d998688e1775c5a620000000000000000000000000000000010376622c7b197ae58cdcb741b337ecc712c62f7fa84605cb2ac1a7e8a32467a83a5460a7e516e145f1ab1385a300be900000000000000000000000000000000064af86fb8f9d5939874a1afb6a642eb9f3a9e06574bb5cefc688bc30ce78b3a33f0d43c6f4f0d80416ae090cc03ebc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139d330667ae626b29eec92ae0b4cf8374a26e1058192c61437bdd88c85442942d7e2c37b3c09788bb1df54c7ca2fd75000000000000000000000000000000001871be9f24dd650763ddc222611b6404cc9bbea21ea340b7a6dd6b4fefc3342f34409193ef2f8bea4ba55f74ece8270a000000000000000000000000000000000f278f73c7268f3e6917ba348b7a64d0ee0a976474321e04674b765b5bbeec4e3c869e61a3f336c568fa772e7891dcb700000000000000000000000000000000133274790ff2cda11cd64a8b65a8a9ef4e0f5abeb9d5f49e9b9c01259f94b8d895d059011201203ab1320c710dd1de831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150a4ed57d2ae3bc2c1b03e5917665a9ebe58c900e81139f482892824fde86ccf91b5805182fe2f97828956c4e5dc8880000000000000000000000000000000012810a6931ef0e8e5ee3786b093575cdbce5edc12734b897a6b9548ad4bb18205158af64e800a43273a0e174f901a79000000000000000000000000000000000141586e1111fac7509c0a3a53a37fbaed126d7372097cd7b71ea30a5b5610d1e8ec954f868c8a98d2c37a304f0694aca00000000000000000000000000000000178133ae5e01f992ab21bd72d14df795ff3cc2b3d094149e2201be50f224afaa2b0f4b174cc4664b9768f383ff143e7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b73035aeda3d68f2cb94dc36ec52fc9116d601c133945e9049a5d5abc58520e319f2d8cf913fe3148592f3755ebbc5b000000000000000000000000000000001563a3151250d5f367c1fe2b805faa422d9d64e837be5dfcdd9282ff3c680b1d6c4661fe0babdfea456a7708b1e5790b000000000000000000000000000000000ea5f235859c59bdda2f2691783592b77a22be0ffa146848e7119dfff71a0c136c4af026562e8075e634df4d6bde28b2000000000000000000000000000000000238590423c229e5a438dcecbe1fbd5a11146ae3c1e5fe7def6e7207f6e0414e0c072a7b245604521ac35bc71c9951a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f6659018a7c8f40232bd15c83dcba2aa412477711315c903c78f86b96d6e32db0a458e44a049dc5cc69db8ace9c6d0f0000000000000000000000000000000011e3493dc45a82fadf2ba02ea9860e61b20d6d0ae4327bad0f8b19f4a8703363f7d327aeb8bf3b72635294dad62f131000000000000000000000000000000000002b997f9c44465a398942548e721218fef999f1ce33c35f28ebbe5979313a21c11a02d4132f873b859b095ac34c6247000000000000000000000000000000001597bb4d6db0485e8f69d7631acbe7ed5768b3c6b3e5ee62fc1340ca6552c8885063b3c0ab0b2da91c8337a7e4a826fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114742609b293f5d0a2802edbe72f4493d43bfcd9ec14291724f067671c88f1ed2fef6f557f575f45ea863d465f989db000000000000000000000000000000000477e9694604e26403e6aee5c1fc2a38122c169ee3d5fc00dfef401091cbef2ff13296d6c954fe3923438a6795586c430000000000000000000000000000000015dbabada04bfbdcd138bf7b568e3d51b980b727a4f4d7e12f36e209e2629c9a6687b1871cb7bac70d7557d0161fb4ec000000000000000000000000000000000a705d0f03a2f42a6a236e0c51ddf4c7307cf03750638c4a1f2526db4ac81abf34607be7b130afc8716cdb889d5366321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000089f530739a88ffe4399d2b0b802d67f63424ef8d86c3c7367d04d9c92bb364d1fc2f8119385c33d8ece83a7baa74c500000000000000000000000000000000114c85dfb2f0fabe56cdd50ff499048134bb3d6565988d2f5cbebf04c408cea7ec52051669e0e5ca943849c908c6d1a1000000000000000000000000000000001420aac64a5660c7feab07e9181dc35a13c7bfa05fd60b0fcaf22339884fa71a518a10518ff4284ce3efee9851122d34000000000000000000000000000000001434b08a2121e59e522801045a80f1aa3f92e40fd823f468282975d1880148e01dae50f0f95535b702ce8ecbcab817cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113b776460e5e8c89a088efc50fe10bfa1014a6d56232319532829f11bb1cd3a9a72ad67e680d89ec9c80c0d5317bc970000000000000000000000000000000017281edfc803809453a01d4ddf7a3e2d7c7f282775e6bf64c64e776f09916842b9bb1fb4e3f3882f4a81387c156a8d7b000000000000000000000000000000001568cc939b0dce41e38e59f381a3f06dc9cd1bc6cf96a277474cabe918b430f17d3618e0facdfb8d0cb3e4b60f7b72b8000000000000000000000000000000000e3f5db953a5a53f73befd628e89a96dad3cdb0a0db3068b8160ca2bbafcfb45f6294fbf07a603398b4e010b0d28e0d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001983452b7c305ca10487090f4cfbfe3c5d750663aa4c2de7a7e673d7909601117bbe20c85fb5a9ad374b078436876e3b00000000000000000000000000000000183df904a871ac75362334dbb8ef9d2e4ace53c6ff87f3595dcbd575b55e5288ede43a13ec48010de6a062f9815f7881000000000000000000000000000000000b5a16aa669873ee0bc44bc41d77bc16847c7d4cc8fae9cf2a89e652b77732efeac2ed8e92c2ea23c1dd9b0cb6d2a8a6000000000000000000000000000000000d208ea376c4c3a811b3f751b3c109eaed74349b0b3fbd35e78656cb6835badd6bde3169e8a3e4fce5a8cc59591803771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124646570cb501af343db7fa451aef55069ef1d400249c7b19dfac380ac6787e4a92b6008af86b6b4f663bf93f3bb0580000000000000000000000000000000016b0ba55c6791218d7643ae750b800003d27bc6677d548e7425c10cb9e56063cf0734704cf04723ff8932b8ffbe87bc70000000000000000000000000000000009f47a0596ef35e028550c0825919c8ccae551b1a2ef85ff8a0ed7a67fbc172feba2d1c9099da6f3662b89db1891cf36000000000000000000000000000000000cc38ef0fac3f0cf0f5b48aa71935aa83fc89430ddf6a7c85c95c3083fbf4d46181b1e2b65fec95f55ac8d04ba86dc9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124cf45b64fa4b4ba528daec19307d92b4feb2a3e6846e92439b22cd1db80acbc40bc43ace22f801dcc2bfeb0764d03c00000000000000000000000000000000100d8cf3bc6a20208b7cf6c359efab17fc2f339a7cbfe2cee62877369c3e4cb1e371e892288d54edafdd345df8f4800c0000000000000000000000000000000006476bbda0b56a134261154c1c06a50fb322b31b094921dc7ab0d9e8c02784a2998996b7160e0b88386cbce2e8d42f8f000000000000000000000000000000000f0c6c1bc8ac491099afa7db7c6f7ebbe97d4fbe63da41f97b3bf20b77dd898d376d6097dd8c52fc993deb5daa6606071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4830a361ca30a0d8e5d0d15e2077a455d9c5573a268930c6d737344d30085ec55632ac91fba45bfc8e125a400b2bbc0000000000000000000000000000000001007213896f16df9e2fd8e8d1d569b77581a0c30415ad926103b49cb79fdd57caf0cbd948040692909d95a05662187d0000000000000000000000000000000001227e60229a3cb8fbdd7cea3defa0bc5ef5557e9c8cd41b9503319092b7ab1572e36df10d278a104720def0900542dc0000000000000000000000000000000002af15554df9ff55d3992e7af78215ea0f7e1959d2338b2b0c021750e7473a243120025e0dbd8b0f11b03807efd900ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012c77b9b533616491f85d5225ab9817e165d6cc8c5ce03892c5bcbf7f7e7ca9e6b8a926c2fb90cea6a0994cf2dafee130000000000000000000000000000000018d1338f46a28083fb751312500a34fce24f423583a6880e8245b0fdf1cea4d68f239af7d781dc2b5db27b8a0ca53eaa00000000000000000000000000000000072cac4e346e8ddff9ce3fd6a15766e03288b7519085cfcae8d2fdf89308dec58663106660ffe5f923564c84c9b327210000000000000000000000000000000018f2dbfb9107af43d2618bbd33b4ce6ccd6045e3e2cc715253f404213308ddf05fb000d291061a82428e670e1ac99ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000268ed056ec6fa0c7630d129d74b4a8826d3e40d754a4d7e4b10e7929824e332c8fc26fc42d5da72299f7699cc8762a300000000000000000000000000000000165506025da6ac77470268784ce3d6abcb7b10c403d2de773d4a1adf96054034ff69baa6eb8af2e4662f4ea5a423467400000000000000000000000000000000156f4ffa2e5caca2523c59dc9f7f7c2489895b3979b2daa31f8b9008da33711d778721d9fcb6fb43efd27baa17e6be020000000000000000000000000000000013007c98d5f43ebc81e6328f40b8bdb53852b20237faed89c4cf11afb8d8a510e91addb16906e3198e4812aa0d575aa31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae38e4448a06b3652c0b42073dfffc4b2713d322df0586080d43cc8e01ae16e81569999ef35d393a6c00aad8a2709e0000000000000000000000000000000004f35418dc78dfae10be7e95c23df39c1cf33fd2a6f7db340b3208d782443c4c02ff963e455aa64ce05b143e9083c1ac0000000000000000000000000000000012c7091126dd9119b0d8ed1fa0036c2edf864342a693d8d2f44ff6a121b6f9c4249e2a54718a7771851eac9fb53cb2bf0000000000000000000000000000000006227458b1b300f3b4f6c9e288b9300e9247bdbc33fe06de22eadd58e0c97f140eee9fdb23b112867061921666c810ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e58c3705ed5374d06aea1b14dbcb8a3418147cb6325f39e8b249949ce91990519fa9f8e45ccdd398b1c77ee56dfb656000000000000000000000000000000000839cd9d0b4a10b0b22504886dfd681fae8b66e5c7ede7ee589d236d26f25b146aefd9e73c0f3bbf0ab85e10a49beb3c000000000000000000000000000000000fadddcb58cb45ea6f26b114fa1260a5a9725dfaab21ab3e016868ef09a106a75cbfacc44081bc18f8177510caa5bbd80000000000000000000000000000000007ff48e3d179069032a5944c5d6debc6c138c881651c92be73d0679962cff46b7ec33b934f646633e45d18de01e2a1f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be26a3b063ad70680f41812d645b60317a493c3706ea342067972eea0ce73dc7c9b43223dd9c99c16d03a7906d2af1100000000000000000000000000000000012a58625afd46dcc84e7495f4b691721893b6bda15e3ab29ec26e9d58d5309de4af910f6955a6ff156339d7826195360000000000000000000000000000000008435e735cc279e17d8d788ea4405e31b610a30d0bfb2d95c7e1b7c68f77de83de77423a2b72da8f504bfbc453add3ad0000000000000000000000000000000008e5158acdefd9bad46d8db77a773524530c013d4276d5a1146c7ebc3668c4644f1c30caa4f56b6911ecb0e19244bab91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752b8fc94768ff1b283e49c15b9a9c1c34a4a7b999269a3c998b7d1f0044f153594e7ab6a647c530d8d2ead8216684000000000000000000000000000000000197d128fee889d77d8ca5b7fd759f86d70fc3768ddda49e0646bb493f0a670f84e1585e0c761b47bebeb05bb1f2ae3420000000000000000000000000000000005b3a244b4f6de472c8b49fa6f1a4e76f95f3469d95d7ab85ecd3b8b4b0f1aaffc25a3a7f5813802e506aa52cc6bb937000000000000000000000000000000000ba9510e0e2b5f01e35f0675bfec7c755cf4e945001c3dd4d2cf54c0daaf9bbd7c952b4fa50f7d2a3cf97b85162e12961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036cc22ca8f20a09460ed5da72468bb69c07e734d8eca32e9c9831142de3b7fec683000077e6db4955e971f4674947cc0000000000000000000000000000000008f6461e3e7aec375db4afbd8931cee2ffbcbce5f75b55428c34f4d418ca2aecde09e694d6a613e5a52847d150d4190c000000000000000000000000000000000b7c120d22959585e2876ae06ed92f95091d28999be71e2b692c4e875191e677ca8424270e419b6a2e77008a184656fd0000000000000000000000000000000001135942126dcbf4f0f294f0ea18f287959dda46524a73c31ea18b7c155a64d9bf908a564c535522fb1797ef97cb63111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181a429b07c620cf367096b0ca536b7c97f86d52a87359ba0a847b68909c548b8c30327c9857e71293bce838da140a4c000000000000000000000000000000000135b6e86c3852a6d7961f2bd7f4c5853592bc64d3842ea2ee2b8e088ee84af1f73de34df9c84bd0a352ea788758c455000000000000000000000000000000000e09cb6ac5cdd6046fe06f17f4622c661ee17d1b7d3ac39bd8c59489a187b0c857d0f5aea06c297348f001af350b241b0000000000000000000000000000000010248d6829bdebd6efa3e136ce1f9346929427e19324a1626ee537c415e6e373b8126bfc18643aefc1ef80c0071d3b6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a3a209680af4f754fc1178bbe7f98353d05aae0edecaede00b0c3b6db2e97636325d146286906096e333174c6c0223000000000000000000000000000000000c542cdbc7235badf21918d050c5b6ef59383c476362302221a2a2ac3991b1f0c10d923cb8a40db5e73f4e69594bd89b000000000000000000000000000000000464a7fe7e6ad12deff11477030210cf9ca5cd59ff25607fe16b2fa66011ec29f864f556219a586a138ca5f7745d227c000000000000000000000000000000001201087aeb3b84a41c2168798df567b8c09e71fc4b7261fc74b5f109a08197e54bac4a62173fdcd38f002bd27ec140af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000dd225c85f603cb15f8b19f0c3680726d6d096bbcadadd92eb074341befaa1698cf47bf83cb9965589b53e10193fc76e00000000000000000000000000000000042fb747be70bdcdb93b1be8a8828cbddb19dedbcb383ce417c25c138abb2d086a2d84fa3fe3d6b22ec97efc1588414a000000000000000000000000000000000c810d6b798644d14741635055bc5e3b79735985eea7bc6dae764d5290ab0954b86c2edc32b4205cb3009a9ea446f8dd000000000000000000000000000000000c0024c00b21fbbc0cef50bf2572e3208387c496f74a437e1691c94ce3a47d6e61345a81283bcec4837f3c8f37b1f0f7", + "Name": "g2msm-21-jwasinger", + "Gas": 296730, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000b8781c78411e83b994dc6b0cabeefc6bce0496dd4b02d1bb048f6d1c124af3eb812243fe49e16e96001e2b1a854c36f000000000000000000000000000000000f2aba4600491cc17070c314d6606db197a165deba2e26e5817274961c8f51b2bdb5df3bfc6ebc57243e684f0488736300000000000000000000000000000000140e9c7412da3284c6927f9abd69cb854087f48a874db2516d5f6df187ab7cf8c94adf2ecd328f1654be5ef406b031b90000000000000000000000000000000001a11bb463b2d349d2865d1302469daeff2078e7a0e28f5f60208701f49cfcfc8788618fa68f6f8a1bff98047e2e488d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6db6feae76582eb0ae8aa799876c5fd985ad37b54cb3ab758673b508c75b3fe2ab6ea13c068b046976fead1f844f210000000000000000000000000000000019bbc682ae9570e586cd52e2cef307fcb2e107dcd19aff6a13b1648f6d3f594def99a0e7cdf928e2338ddc38ca7eadcd000000000000000000000000000000000a789526f4e2930d81a190df174134bdd1073921215706dc9bc21b61cede1417d3e11647909bd601d78cd0f50c719aa90000000000000000000000000000000003be552ce382a274dec5b8e3bc8fc4da584b77dbee4dc7afaee856b50c992303fd0bb74a75a9a1b7886ba42c90c5975a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024903c05932d6fcdeb0767306df033b35afaf1404a19918c309f221660d987536993427609702f7019948c6a6afbd62000000000000000000000000000000001034088126b90c116f58a7ac6db4e5f2499712e13dececdd535bcf7b911100f522801c0592d7ca34d41011f6d54d92bc000000000000000000000000000000000a808eca3f7c1d3775bc2991dd81344e54eb066cdb6351e5cad71845753dc5597f8507d87afb9ad5c7de6002eeb1660a0000000000000000000000000000000001487afb91406d1d284187b8209d5d5fb58f0b38d22324d66a36d2d562f68af38d36f1a6c1d35346c8672d03e18b4a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001dcf3408622fe3e87910c4f1c22a7a827ffa2f948f3c0b6cb4d36678c4786acd733f1e12cdb6220bb61d65ad6121a7f000000000000000000000000000000000adb7fe6e7296f71c60cfde98a823c006b6320d9fb4eb9b1fa6d4856dcb8ac5b85c4fe40320e19df112bc4d2eb0e1a740000000000000000000000000000000013299080e68b93a62069c350751ab6a5dd5c8d8ebec1df4549a1f18b89b7395ed81295b022d554fb48810bd37a18b8430000000000000000000000000000000016acb9a1c265c10d8d6d2b1aee4f8bb67c52ea534ec80187d8acacae221fcc5586df92a026907c88600dee1b5bc9f1c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000815e455667ed67aff8ce2200f5ded020385e0746e1b68872314bc7ac9e1682fdb8cf69f48a1b65a2d6217a64833cecc00000000000000000000000000000000021c1482a976ecce6bde5a240849407c4e924bbcb2cf6a504c2ae952809115ab3fb34ae741ae2a92e32d0c3ce639911d0000000000000000000000000000000003d318dac2e4971427c12aebb894c138f7164492723ce4b319422b4e9adc7c8dcaf870e42adef866d7585b105d74e0d9000000000000000000000000000000000df017287bd512f80b4cb62633150e64bb41419ce001fbcdd1a273d04d7c64bc773bfa1de93550a896254dbcb8a777b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f4d8d97484d5ef0b41e33ad7368e1708801d418c43ede1932bfc660cf55f89f592a82e67b4332238d64786ede139b2000000000000000000000000000000000816a4a5ef1ab233dc6b8cd5d40066d27cd8953ab220a47745e27073c324af2b8a4a13e531d1ba79db42166f3bd938ab0000000000000000000000000000000001de3e52dae742e81b2881fb7da2d2eeed801df2d5d52f7679a8584e4be23ab4e7738812c8153c2128abf452693af2cb000000000000000000000000000000000d44da7bf57931175eeb3b0a0751f5e42a2f26aa9e1ec01d2521bc0b54c7d12bc6a783eb12c5bfad8c1956791a25780b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1c4ae2e37fe8f0dbeb08cea7ccaf428ba2738069494a8c6353beb14a1530272d17f8a20ce2a5aa7196a9bc20e7670f0000000000000000000000000000000002f0c69da7751d7917e3d8d1d0e4ecd37222f27d8929e3b885ad91d735b915271cc13ab2781d866f429b1802090c5a5e00000000000000000000000000000000193ce4b6ba605493d34a199e98e7e21262dc2989fe962d6009aa8b1f9e58e5043ce75fa616e165996f49496a3daeeb360000000000000000000000000000000014b32eeec7d833a6d437a2319f9efa5047103cc18d6ddaaaa17449395c25ecbff0a03020aaf0ba3a859d048e37467c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1c90987486f88c8b2a91370e946f2a474985d312d783067c794ac2b92f394aa902058e85370c99324740f74a88ef0a0000000000000000000000000000000012b04200b415af8abf6abff7554f789da2533896f79d8248ec6ce07bc1dcbe66f8fbd154b0c85880d5ded1b0f946da70000000000000000000000000000000000274164ed8921d5623c92bd1e788ceb29cd282375fbbde988028a6def27dcb2fafaa4b1a1d21d20bb8b29b5d7772f97f000000000000000000000000000000000b57883385337edf5f0f96e1fa72a2b7157673b595d7e8525cc0402843a1ffe87668bdd2c2f8564ecc00150d0808dcc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000783188b04df2608dea14416ae634dceaf5c8d1496fe3e956a560cc4835d34ade4a7b28e7e00e43f7f74b240b26ee9eb000000000000000000000000000000001372ad6f9f9ba1328b01ea4bdc8ceef33d0e222049e16086254ad119827f4579233814ab4dddb8115fa041069a96f43e00000000000000000000000000000000054c387ea38fc362a4ed61f09210d00b699841ce86555a95ce278e61ac8f0a5e21d258a093d04b41f32751c29082779a0000000000000000000000000000000005c9afe9ee25fc0c237d0a6eac9fdbdac5248ddcff48432c2201fb114602c8bfece4b40093fe1d1c103ed36f81ae5e721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d83e3974a7cd31419e1421503e0a6b8f7f1fb00f39a25ecbd51bf2950f65d077d666e221c0b786e8e565b67651c178f000000000000000000000000000000001811efe5aa2e91ba296ef5eadf3ec41f80a698c6039bd13f1be6c54dd128f290b262374a4959423cf380f044fce59c1000000000000000000000000000000000195342d27afd5ef6dd1fa88841ea7305092ecee1d789fd7d148027fa60e0fa881a4c84dc2b94373716f55a1eaafaaa4e00000000000000000000000000000000033120cc5ca0252faee9505697932ed25da821790cddef920b5371fe102c92a407a91b356bd43c4c733cef59cdaf768c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000466179a79a138ee6ea87e83525bdbf65d3bd43b619c8e47c79e1baa930d2ceb4324d551b788e2a0d21e2dc0db33be3000000000000000000000000000000000120313a281a7305ecf80d91fe2fc609c9958e9adc4e8804ca686d5348e75bf7521e29c539153adb4d24c26c1745035f5000000000000000000000000000000000e6ca13544d7eb6bbbd8d7d0a1b852d6bfd3339e3ed28f3d0d412c048b05c6a4cd47779bb546c9330d618b953718a27f000000000000000000000000000000000a2671245938ea3bbf536bd720a667ec57bb02d7c60cce0cd9e1efc42b56185e99ce13cd95946889a54190a321522bc31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b82769f03958450f004bf7fd0173290b61ae2c0fa898b2d5ff7c0b67d37fd78e6b405f443d5cfac46c65d28c87bee6000000000000000000000000000000001500c48bcc0030640923b2b62c1a6aa1f53c0b187d7d80ad2d60c822c74ef25f3744e616277101cb5d449e714bb037c60000000000000000000000000000000013d41057ef9dd8bea802a7e9a9943016307545f15b7929da36dc9c7644eefbbeb5aa27ae53d39715db49ac9dcccb8b9a0000000000000000000000000000000014750a69aa6753516e69084a89e305a23b2a9ecfcfcebaf3529e1683dc3aa8be0905a6a4ab616c0b10bdfaa5113a47211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009395af45db78fb3d959c19b106e3a792bfbb1d52813d03f712d344ede0208b90137581e4355d568ceb5493fe85a3726000000000000000000000000000000000730f7dc2707a1d448d656f1e2aaa764bbdd2bd1bc73739ff236d433a3f1ed8ba211cb9a396df2fedad8039c19522f330000000000000000000000000000000006031dc4f93d51c1efa4aa895d902b1886453ceb4c5746e9df96fa15f8c741c607a1540897aed955ea439367d365f427000000000000000000000000000000000d804efe22e55bc2db9066c82c9b26abac303da499b155bc07c6121e369f5be11a6f34c35f604c120553fdd65c54b6be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fc89e4ebe7b181578a07e3bcc40f6eb4c3d998abb13f12510f9ee4b37a63e265a155e2331bf78ef349d4a40222f8d900000000000000000000000000000000176d554a58c23a2b19b267b10577c78a44bc6000d638d9adcbc8cdead61521cd643810db4888a38f24ac02afc63c07a50000000000000000000000000000000008734821dd3bafe78ddf0cc20828dbf46b24cc3e8ef4d39cd4a45357525ed77bb2632b09f99cff6c7afc85950643e62d000000000000000000000000000000000f5e40bbb52c510e1ffbe42f35a8c845a50a2cf69238ab0f00ea6f964e4cffb0d23ba711d1b587d76bd81cc31afb81721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cbe4974098167d71d8a7c1a16350c6f510028be265d3ff3b452112f379b779ba7209ba99e8487d581ec0e97ad0b307000000000000000000000000000000000be87a4237380213a6f11752ce78704a95b99282b696a502df73f354e33d83ea1423ce2fd273836ed7f67dc7dcc93f4c000000000000000000000000000000000becb32187a437fdeb82cd7c2a34a3462ebdbe599849dbd2c2ea4aadab9a4d998aa8e83acc7e4266622075781c7ba6d8000000000000000000000000000000000f2aec3af375042dcac3e812618cf1bf6fd5368cae27615ea7bf56479aa46056a0d3bdf5c98a499b3295d696a289cbb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011aa8bed00b25bf550853f2b075e289f529c0d658fe3933acbeb9bee99918de1a3e6d9f9222e9fe48c9d83add14c83f1000000000000000000000000000000001887a7094663697f14067d525c28fca573a6f111f1e27f4e4a0c4020d6a21d430367450df8ae6ffe1686c2d49a33977900000000000000000000000000000000120e067b592929533aee3158882404493fcc832e981ea2f21f752af7f4b46a7b6d2e7da7134b629f8781653dee9b8435000000000000000000000000000000000e8c216b7d50257c0daf1099d8820be90a85e3d689545b3112d826a927498d501b56c98c32ab1a4f71150411f06e68611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d6339f062886fec71687f9a5001a7850424d7a366f8588e94d9ad9807ae439869a4b6b6e7410f961689e20be7333590000000000000000000000000000000002b6c32061cf3cb70f1f21531ffacc2b4b9226d35a3791602a0095a50c44fac67dd8c7cd708e0adccf5b443c71ac4d010000000000000000000000000000000016e78e3c098056af180109bbfa7d247a1fdab81fd02c083dc267a79a9186df02be730304bf544a12727e72cf8271ad45000000000000000000000000000000000a8436b14fee40e5d1614f3ab43a2a125f97f1e0ce6b3fcdf44ca0d37f3471823dd372799bff7e96ba674d22a2e0456d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000721767593139cbc8cd3c3cbfc0b50697d3b37d9ff557787ad92c8a0d72dcea6768fb883914135ec3d8cb1408636005f000000000000000000000000000000000198c345bc278efe6e0c81d7dbd6e28fa34a5e8c3707ee0e25d7dcc62e864f74655181913b5e1966b5430f1c6c79023b0000000000000000000000000000000005587de601e4d93246e6c0b482d1d6dada7c6b5b27f6b4fc56b99150ffbe7c0f092069644c0948b5a5bb520e3ed2c133000000000000000000000000000000000a9e1e2308123411fba1d812c1ff457cf2d6d86710511845cb3893fdf9cb69393388210cec426334d21e627805ce76911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017faca5f251941d73582ae287db133e0a57fae8f064021bdc3dda70fbaaa155d058fea0d1abb6b16bc272ed4deaaac230000000000000000000000000000000005615e24c9a8db48083019cd55317738e800eb5f1ef2aad8ee166ccb6e197f492380798255fdc300765daf2b9cc02e9d0000000000000000000000000000000004448b229a54a1b0f5783c38b0b888b70bc6d540d6029854a58d8bc7a22be4f5dd484f1ac712f36eb03fb1d831c33c75000000000000000000000000000000000cf1117d62bdaa8ab5e3b738649c64c3ef57909c9020d20a41d7ffb82f9c46abb865f95027ac03912716de511d429ed41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009173d831df901b8c85e739f6129309c81f804b7613bddf09267a102a55a02057d0cf7ef1b3f6e07a13969fdf264f8f70000000000000000000000000000000000b413ed93186f076903eb41b9ac5638e288b317c70ec09c0e5abffa3b376092e6e08d17f9967cdd95f35daae27d38a10000000000000000000000000000000013f19b6f840efeab4d3002dcbce9bdb3cb2c7fd3a47a7bb57937d268146ade463b1c0b1c246edc084d31d84283f8d308000000000000000000000000000000000a73ea2852b9a49821bc19784e8d6beb4bbe6f7a4b820fb6511b3a494d3198e44e5a8ea4ef0b64ad6d5788be9f2a30771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005223315fef4e0b783bffbab63fab52c1f71d27dd8ac1a85acf430eb29b81a51c21764961d1019c2cc4f1c4b31b1b395000000000000000000000000000000000cf89bc10bf946e0a74c0e21f3b3e56701790c778b51bd99a35f9b1b9fe2dece1a15573d3c9776213315126190f462be000000000000000000000000000000000020e8bce554499dbe0f4094ae2680f1466043d2dd21b84a90f3100b5b4d855632ec6ddc11293dbdfeab56e4d6177b70000000000000000000000000000000001030db39218d9d54cfefc38f41b9d298d7e3ab2ffd15ef33074d4a88a74966ff44255ab509d41ea30a393926a88ed63c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dec914f41fa13f1a61ffa7bd48efd3a121eed737000af4cb6eadf45501fd9322d00ad5f280e547d53f814f5ed867990000000000000000000000000000000019259c47668ac612ef14c2580a14918adb3268473940f0945c4e8a26ca3ca032afc8cb054324a021075807ad9b6ae74d000000000000000000000000000000000ae2b72a50c2aecab13cdb040041b727452da7d6a836059e49931471b29c3223f3867eb240437f3173cb023a5a3ee5470000000000000000000000000000000017248f40deaef2b0c64d40af50cb6f0223783880853a2e7ad39e20a60da7e18abc5efaf4add2d59a41ccf94f11f6aaf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000170ec5c26a0557810786be0b2ceda3b427e6d79d8950fd695f2322090f476f6eb94aa75f88910b42ea179bc76d2bb60c00000000000000000000000000000000075341ead4a03c50340461e34893fe82f8bb0144a4cbceeb6fc49f1dc7460e5a7dce7e8f79a8aa9170f7208b7273f1220000000000000000000000000000000007bfadaf2f7444c8890e8390260dfc5089f4b9880dacde3c30f02a8ade793454c4685fc4e88ac484fb54faa18f8f03920000000000000000000000000000000003c821fa013622a2347a90e8f740222d10c694ceff3b8ec781b6262077964313eee3c6733a3109171fd0801fabda4843", + "Name": "g2msm-22-jwasinger", + "Gas": 306900, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000573dafe5336fee19fff6eb837c3c33f8a618365fc85e20737df081bdec328c796f4a038cd958eb93a6f27aede21658a0000000000000000000000000000000016240923f684ebf178fcfbb478e2b1a32e276a35a1e07b9d5ae167154d31aaadf59f10fd412654f68abae35f584e57e800000000000000000000000000000000058980853e950fe1b9fb7e6f4be5949fdd76bcea95a8a21cf42dab68f0986752fc37a11a186595c2395edc301ad469bf000000000000000000000000000000000ad882d1125d9e4d5eb533ed2da808321462f4948a46c945e65a3162a459e3d5c9d7569f4767cbf207a5f4e7b02aa2e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ea173e06b6a71341f802606f01c066cce64c10c787b08171eea333acdb343ee22982a8ae467e3142bbb048d5726e5f00000000000000000000000000000000061bd91dcd7920f741ae362372c2e8295e6b91d2b8ecdc58d1beee0e6338304c3573dad7336beabdada2b8b4f4f5b9760000000000000000000000000000000009794e4064487f8664138e4a238441f32e10644229806e779f8046316e0a9c5a7b2f5b46bd56ddbd70b2927e31cf60430000000000000000000000000000000000d123371104c4e592193cb56e2fd2e71990208911b7b26b5f901ce1d11e0253e3b7dc68650eff589a47d6196b5457171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f9b34e20f2a1c3e8f541eaf1a610470a7b3feffe0fa293cccbdfe7a5c32410c6d9607b00bcdc37c7c99963fff68e70000000000000000000000000000000017c9e7ad85ac4cc2dd17dfcf8c2bf3310cbb16564f2930e619e31f870cce935e502092250213c58b8c07fa7c8f42fc6f00000000000000000000000000000000026a38cc01863f603184ea9253f24865cd1050caa6ac5a1bc415bda639f94334c83cfda5043533459883d77f61f9bccb0000000000000000000000000000000012f015d7d9b7052c9d6b61a4cc28866736ea93767713818e2315cd4dbaa9b0c6a0eb8fb26103c83041e59698c37fe89d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ebe96ea53e5765440d990112c783f40283df08450943f3ce441298fbd968bf4520d0baae2e19ead395498956c0f07700000000000000000000000000000000032a0df00ea111a501cd8afe935f8ec18eaf10e03c37a1f1a271ed6dcc6ba2645d1cfd199464892e3c95a44f847cd7110000000000000000000000000000000006665d4044afce84b0b19b2b3ebfd759ff10354c3a3a17cae4efb3f66aa00ff467a48d5c916c5603b8d505cab3304b360000000000000000000000000000000003a0a5b8ba0512359fa5582d8249479635a9b27ae7f5d36afdbcb1307c2c83bf82364be5d4162835d57b9a5e75ef339a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019480e0a025d0f11a1cea3632c2d02f581d593d1d46d91b9eabb5c7c1e38298f9ab668c091da6d4859a2519916709b4900000000000000000000000000000000185de88460a81409b1ff4fe3260caf19efc9ad9855eb08088c2152d8812cb7d2e97677d12acd7388dae3442c4c9e85a10000000000000000000000000000000002eb5e8459297296cbdf12c9c39ed1f29c2e4c127ac1bed778cb96364445ec264149237b282fd22c1b75f735c629343a000000000000000000000000000000000af81f64b37188155674193d226b8b8b0a238d47180191970df64b2b5faff2d1776c4e653db6fe55ec1677cd259d7cfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001699ee113f8973fa0caccbfd4c1788d97d0072972cf17876befceed63989f07d73ffa266239131c17926b22b0e05956800000000000000000000000000000000049596b37fb9789f016afa032e5df2ae5f745a9faa4f51398ecefa86b4a37f1eff390b5870fe1dd9004d0f9290ac2fa000000000000000000000000000000000176d2a0c9d4b28e4faaccc74c21a100b3f4da7aa53400ab46ab531a56500230f8091132e4d125bc6d087d24a1c297219000000000000000000000000000000000e24da23b7dfb427a0fe7652fc793495a2a4f4b4ddc1c6bcb2f32947775acbee98d0e14cd50083d5a43477008232b0c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006130f031080bc0d10c428e2eb39670eef0b99a587fdf69493fbb6919dc85ffad86790ea6050cc799cbf70d880f0ca9c000000000000000000000000000000000077043bc028ed97005d32b39f81ef0e16ac3534ad2ca3de8680b5dd1ee47adb7654730c1893442ae08c2703d660e70900000000000000000000000000000000130fbb574c5277cbd50ec6c601874e33b4318c66fa884d095aff8aeaa343ce6d3730328713de1b736b346e7411f9a9760000000000000000000000000000000018d4f73a8ec7a988b35238d2327d5a468fc32972a09297102290b3ab3ac21f4ca73667e71f40cfd22579bff0511c57dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001109704851a82d4bbc01db3067e7ffce0f43b62bc41e560eeb7eac2b63f07fa2334da0a54d6302d59f286b55987ca1f300000000000000000000000000000000048fbd6d4ed0d746e5018fd4447bea9ae356f16a0a04b5c0f498208b82b9609d154dbe1c914243309ee3886f759d11aa00000000000000000000000000000000057366a4c2a65d7bf45036159fbc7fefe02c5240d582fb4c35523edfc399edd808cdf1353a5117a66a42664b8388c0ec00000000000000000000000000000000193108eecac90c8c1d70028f4937187b4663d889d75197ed16921a2c3313265e4af4263dcd13eb6e6128f42b02c58ce61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b0a9c1247a2afda11ceffa8aa82a3a2d189434eb86389d018c0beee9e5c94359a0c273704690d741630638bc3d80c000000000000000000000000000000001389bbf2f908fa04c139b88ae891ced443597634c2673d90a5679f5fa803331316ffff653e50a46b019ca76cfd732d7e0000000000000000000000000000000011c8729fc1eb877485875a85be4e10d57e1899a5227edbd716c54c037e2b912f11dc1852423e38414016d9c799faa789000000000000000000000000000000000c4f5d9b1b68e08ebec20c793cbc12bb34af6742cc43950fab789f07adfc377110f4f4fc1612d3ae13184e69ee9fb5a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d63887669096f0c94ce0fa7f2a78b90b83f688d94455cf87fc1cd480995d09c7978bd28c045f2bb84e508cf3f2734fe00000000000000000000000000000000197e3f8cd265ef69716196ce9f33b3367aa3ef19d52b8c878a4f04034e3b8fa6b7b4dc3d3cc21c2ef36d358be7c0715f0000000000000000000000000000000001cfd18eea100691c9d9ddec533402629c3b073a4799bb5e69704944223199fa58e8f513c5150f53a42a16ab87123f6e0000000000000000000000000000000012d86d93700ce189a0672a69c57b639b8ed964aa0131792ae99d5f8e2db87d9112b68283fa8cbfc475ab7ac89de388d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004279f12936723cab202e5ba813b1aef587837a86d58b77210d9c3f39df1fa92480cf4afbaca6f09ba5004b4df011a590000000000000000000000000000000018b75e3cebb5f082bf79a81d20f43d685930ed6eacd6097872a295235c0c219e54c4452378d256dbb90a39b1803f205a000000000000000000000000000000000d8ac4b96a331109c131e1e840f4f26ceab1f518db33af30f3516ee81dc17ba3f3d0b913b6abfd81c65a7ce3512880e90000000000000000000000000000000013db89f8fc14a8e7c0d2f1a87d32ade1355e866277d627e22db9396b32c266993e9410b346e375e5b84f145028c0574c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ce78132de75936116985afcf672ec342784bbf07d08e1c464f54d4cdd1bbb2394e9db13e9b6c55b50e99cd1c75846700000000000000000000000000000000164dca10d7f37bddb4933a13af0f4c43324959fc1b04393e5cb34d7faacef97db9943e2dc081d1b1aed83cdf7c58271200000000000000000000000000000000183339f492ffcb743bcb9b263958f9c301901352b0a3d282bb7ff77619d596ec9afdd579a40587fa6f82b876834c9b8c000000000000000000000000000000000c0216dba404b7877367ff064e45a1276c8dfbbbdb322c037fc6ddbab6ef5c56340aca6e74732688a0373711d2bb6bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f7fd5c2dd07416e8edb2afa28115c4838e4fab00c3d316665fe87c19856b33753fd5ef80551ca1d09efef47230414000000000000000000000000000000000605df65deb0f98ea718af6f16808a845bfc3598b8188d3faf8d4dddd597862e21b3a5433bb0f5752b1de8aa5c1d30e80000000000000000000000000000000008fac76cae6ee474cf3c5c4619030b7cb0b6a4f86badf439f0aa9a235ebd7efb9d0c593e012de498043d118c4cda1edd000000000000000000000000000000000d5950d75a16f745dcae762feb6e63f5b39bd34de624f944b2f0528d9a73bd8f3b5d0dae6cffb4a5aab514b2c36e27f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c6cb30fc014742a6bc8b7a22a58e87cd10ab46a9fa03ada3878b26f4c6f5317743db80fe38f59e5612a5d8e4c70c3c000000000000000000000000000000000b4248c32d9a4366082f54e5018164294237f3aeda1ddd5140a6b3df7652d1087f5b6d5c42ffac9fdfec3d7ad2818d210000000000000000000000000000000012c92b23e5e574881569cef70fb29982c68eb7678daa7f704e645498deec1d61329be4b23c292435fd8f6312209554f300000000000000000000000000000000124528f12bc7bb332dff69be35f9525876533a6e382aa35f94c88d4a365f1a6c140d8169ac89eae2be4175a2087fde8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ce1046a283576be78d4f11a43d8bb85bf47dcf59357f62d474464108160b58d6b478a588d7a6342990b87696b4714d000000000000000000000000000000000b6e69287718b1b8e505e595bb16fca264c0cf8e6b36959c2a2bd3908bf27c271b4dd5a677e9576a32924efa2f03211d000000000000000000000000000000000a6ca15a4485ae81ecc20a775994a87196ef2c144c662335a1cf8cbd950f902398343132cfd94a699f7d5e260c7b7a4b00000000000000000000000000000000156183c19a7b7544a63a807b6cdfd10cdb6d4d7a453aa2ce73f8a6796f24e8d2d30d26ba8bde792bb75371b0c6f255ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000210da1f9f2fbcf2eb109f16c68fd5ff6b4a3877c20933b104aff05e0d5e67ab69431bbb2220fb9ef78cd546c1262ef60000000000000000000000000000000005c9b764256d66ae8e3ed136526ebe0f448c4ba27101b982284c9ecfd33aa80e4755751271922889e07ad32b888d05b400000000000000000000000000000000052ed5c5ca63156239917b2642aba73e37cf93b97364e1b0cc187679f87b030721947ef8da01ea6339eb566fc8f5c98d000000000000000000000000000000000bf4f1a50611bcc0636df65a09cfbd29dec18ddfcb193c4a8413cd73e5674257a9e10d53ef8cb68606aa5dbb94069bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000179160dedcb63e2f35917a6cd8ab70ad59a1af65e51f7d6363460188f6fe596318aa79547722c382575835d5edaf876f00000000000000000000000000000000017de38ba68583930ac90dccf618cd6e1b4e7f3bfe6045dc6299c0e490c8275b426193322b1ab0596e2eed2d4e838943000000000000000000000000000000000ea93d7529e69d6eb18df69ce0530fd1484409ddae8e23bb484abb0c3a540b435e4915acfa0cfa273f7bc1e792031960000000000000000000000000000000000810b1a008474b4914a6231d0a69565120518674fd04ebca8c339a2173629845529e9ef6cd29c522e5753f15b3bf66c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e866151b715237be76f147aef584e63eec98916f28e720fdcfd0504fc3b13112a76f1b14728223dcf8cc4ba00f78d8e000000000000000000000000000000000c471ef3c43c2214bf15021c932e216ebf211691922d7c9b7a3df80468001cc569ea4bb4c83ecc3c30de97dfb9afbbf10000000000000000000000000000000019f1b445b70e55e70e7214e18889ab6aa500844fbe1ccfde75c5994c43f602221c3e697cd6a016696fa02e6205370ed1000000000000000000000000000000000ca7b3ecefcc3cbcd157b61f7d209a01602eadf6e911218eeb8d1e4c80f9222b57cf33bb40c3be4fb7c2494dc9d4e0b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009f8cdfdcf8bcb083d7da9e8e72d18e762486038be553f6677a28301727604fe8ac046b9cb7193c30417701d4e188f5000000000000000000000000000000000153aab72aeedb8a97a2c807822fe696bb4aa299471923c31d20de2280031769f0684ba4c24f98ca7cf70c592c261f8e0000000000000000000000000000000018cd85387a413c60a6ab464751c4dcc35fc0187613defd19b184c64e3afe6dac57f496932c2438b6964a4085efc871c90000000000000000000000000000000003a64fd6aea7fbfb9ce2cb4fff2a0306983b9d90c8e8903c8619f1ba0f760d2391ba6923494a528bbd632d8cf9aee8fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000381cf6a29715a70ce5286dc86e828173ae3fe06c90246079ba2e8694d90a83f6e90288155ae98fdc0d696d98c2fab93000000000000000000000000000000000a7b4da09d96a65a9a3d6573be454a992534fedd1d424855f83261c0fc21835737d4bebc6f99ab30412fb91ddcf42856000000000000000000000000000000000b4d407e0a054b173b8fb03c1d2777ebd98375925e182a71675639d91721295118a1cc95027d062972aed98fc4e82450000000000000000000000000000000000c57240f97ff949e569152100e495927e4e5b0373ca8ada334071947cbcb601026595efb96cf2616f89bdbba0fa7be171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0cef50eb7a5e3035849dfc6eb98979ad86a71d465a193324065a9fb62025cbcbc1af4e96d9f394c32cd027a540fe5800000000000000000000000000000000144297119710930d924376cc65fa3d03cd2e949102d6f1265aded48bf392a89ff7088b421d1752524f27249ee92444c8000000000000000000000000000000000b71324f41b0bb47c1b77376cdd489d84b10d7a44d78f965a266f4afdf73565d549da3efcc4bd01c80fb95d0040ab9c700000000000000000000000000000000090234962b70396d5768f2b38ef24b5768f19a2ce75e1b93566e4c04db71a8ca13c0f80d6769cb8d2555e47554f050151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f377850882e693df1d80382a8c73048463865b0eabedc70787fac38a8ec1bf7d84c9a723144bc29ab5480aa6754e5e000000000000000000000000000000000492d9a94390ea6f83b91eee5abf18b3fecb9d4e5a007b853f9673796776b9f846728812e05eb4d62b912b6b831a337b00000000000000000000000000000000072ba7af7471dd664346819f03068a14dd172dca6688a4553607de7fabdd9eabab0afdd4c16cf4d5f8c49544b5a3cdb6000000000000000000000000000000000e33913cfaa0ce59e7d228465ae74c9ba7cc10886f053aaa8edc9547126e1ffad4de46df8deff9fa32f2e9647e8ffbd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150d2fba6b32294ac134add1744fe56e672fefbe58c26ff6bd1594975520fd6fda6088b1023a98ded22059a3c1d06c7b0000000000000000000000000000000001a383888abd51a0abdb5e9e6eeae39a8347e4b504c92e74fd7e70699ff1165105f4d46c72b18fc993ef0bb66acf2b250000000000000000000000000000000011ea920a04b0a0f352e1377f6738e9444f8edd2618cef4a881920908d296cb2a4e7894637876cb64146072d851a5965c0000000000000000000000000000000006e4658afb854426c63edf7573b26cc0b7d9762bf096d206e5353fa5f24591b67279c433702a3f8bf4b9d1933e20aa121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000014163749a57478e3de4ec207f38805931b6615f9c416cdf03cb2efe3b3523d4adc35e7153730cab351ee5fb3941dab47000000000000000000000000000000000ea40c9c694647efb74698246754599948db5b62df56f60b4d1371ec9952aa0e56b518283a804f25009c5fa1c753f1fe00000000000000000000000000000000195036913cad2da67e2c48a80049daf94b3af739f45dc2ecf2a36c064477e5c5e7c6d93175e06075f6b1cac8aa642c9d0000000000000000000000000000000013f6c7710f3b4aacdf93d0dc262c57a31fed77acb718c6a23d2ea903e9b24a4fdcae4be85d85e8fef721b6e4ddcf71c6", + "Name": "g2msm-23-jwasinger", + "Gas": 316710, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000109865d1a2b55309aa396cced61be00ba4168f8eeef80e1be234bad67e7d031b3be285f3c686be19b4ff31e1a14c039b000000000000000000000000000000000678ce9721031074c11f59bda6943059a4fa1799ec7e2fecbdc633ac793250a427d78d69429c7eb5896ee03eb9490aec000000000000000000000000000000000416e926f86de98af6222db8f8b12b39e390254cff1b987c61893ef03faa00616bd941a7163af5d117d56f98f51615800000000000000000000000000000000005d480012bf94bf1159e5645171e7f3b93fbcc5bb1298807f7808f375dca8f5228dd31f3d4c21c24d77f86e025e351e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001132153104e9603afed940009bc5bdc487b94bef819bad3af410df82bc4487efd3e94fdb37fb359c79832f2747de487d00000000000000000000000000000000187f290cca42b2cc54eb5fb6ef0f28a27eb6832c12f7b69ef6ebc53d28086dd2aca836f8f70b318d24d18f22c3c786fb0000000000000000000000000000000015c3b039b5792ab9d020a024b9e1df28907bda64adafc3e09974a1b59a4771eb7967c3f894d93026f7404574c360c7de00000000000000000000000000000000152c1f9a5e74580a46aaea0245a3921d186f4a718fb82702f8eb0d47690bf6cb21ea292b1f11f48df604faa06f4301f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049616bd63733a3db1a6dc7d8e439641372325700126dc6cc542ba62d9edecc9e5130927a148b7234260cbfe6c08c27600000000000000000000000000000000198cc6e1dc43604503e15369162d91c8b225e142f7996cce939f6b90e691fe81de391e2fb3d0091a8ffcde2f6bdcce99000000000000000000000000000000000de50d0889e7ec35951847bbfc1a3eefbf4802ff1480377786963ed42c41993f669ca90a19e0342b9cc4fd1884d179f9000000000000000000000000000000000a9195097ad62e62fe1da1814d81974b6cdc1112129e22a3ac50fc618cab6ece88b7a286e9845b7020c19c9d5b9b582e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007e168213a4ebc47a3265f345f3550e0c55cbb0468f9958ae9abcaeb2e78f8f923d8b72399eb454a60866959efc0785d00000000000000000000000000000000128843c012e52f69c4f8aa3bbe56a746956346d21b8df78be58cf5f06c8856f7cbe168e5d07ebf8d2473cc7f042c1e8100000000000000000000000000000000001dc911f409f178934441c9cbc6d77a229589b1168c1ca410578e9f53a26ed8e7d9abbad5e8971363723558815c054a0000000000000000000000000000000018df143c7f1a1c34cea98df652e9f505aac522934bf46a2f6a57df15c003dae677a130cd9e4b5d4ca9eeeb38cc45f0e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0d7cde992b6d094a1708e7e0d20258503cf1021a16709634b91e419d680813776e7e6ee9bd1877741b15ee1044df53000000000000000000000000000000000ef1d11338728cebf8c63a9e24201dea161fec32c4345053c2019aef589cba80d7a23d2b30486917de7120739ef391a4000000000000000000000000000000000959e2bc5063d75675768853a1e42cb488c0f7b8ec9f72f9924ece5d759ee0de3a0e38fa9c0663ce196d46b3f15be1fd00000000000000000000000000000000142afc1e9e4fb841ef2237f8f6a79ff58edcb1ce7a6086d520b41acae8d5606beb3614027874492b4e8e38913509b9e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001684545c1218ba9fde0e8325bdd8667f9b561e5d55ab77d46f386876de4ae532164859fed671130bbb540445ab9691f6000000000000000000000000000000000c2b890e62130fc347ba8aef09cdb1fbafc35185c86163680024e5b63c16c7a5602f25c5d37def475bd694d8074b649a000000000000000000000000000000000f7297bee7b0846c636451ebb84c1c38ae8274bab0282a9f83af7e36a3d32a492ac1d970374ce17c9cef7fb810a83e2e000000000000000000000000000000000c63c1709faf67f8748ba31e308dca68569cc86d5274267853151aef56c15398fb62a5ae1a1f269d66ea94c674af08f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e1a6a94e975806963602b9ba19d8ce66712c91a58da1d995d37d01fb58017de2c1b412ea5d9d5adb255c81e736aff000000000000000000000000000000000ae4084e66e05889699c1f568cddb577151fc0e6869d3436e17ff47519a98cb622dc3fdf8ad27d30360957a1c95f703500000000000000000000000000000000182a0d7d43a3955edb182051ee9f0aebfb63c7464704f01c1f9e2c640d2c0e3828c45fcb34a068714095c26bff73bf3c000000000000000000000000000000000f5f0c64a135764d7a9cd31ea971112359dd4eb88dae09aad5d4dc62edf2b10d25ab35815a836b973b8805e39f5778631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009471cc5a5cde491e67a5227bc94e301bb353c3359070f0a0f7177e7e5379ca1df5f0da6fd398150682b6ada6ac3b1630000000000000000000000000000000012c46fd7ec8568f48554fce62a4a44e0b0c22856c4ef526e7ff6741e9911ba4053fc130da9e6191551077a3094dd6c5c000000000000000000000000000000000343947892bb2623d67dd2f51d7b09a8e3af2e3fdfb2327068a9d7903545c621ada924df136e21490d244a427f114d950000000000000000000000000000000011e68e8bc35490b65b1bbde34f3582a10913f1147b8c3ee96804096a83375f36749a9878543d30d31f91033ea1df79d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009582d83d23e74c2ce61641406aed544d6f68155d6f172ed323f94781a0c9c1a64f7038cd4e49b643905b577b8cf02090000000000000000000000000000000010052709b2194ac65033acaa2863ed2c33db45527cf53b3a9038b2e07c6cca08ea497b718c149c96f2a07020ee6ceed60000000000000000000000000000000006ad74180907d6d9550979d68e9b029885d3304f583a5e8758d18dea17b7ce5efeb3b45ece098270e8f552d7c28f381d00000000000000000000000000000000194a7be0f75b3eac392bfd37ea515254a06b64f2880786ca36693c139cd54ec4cc7e0b809f0d07be98a70800b92406be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016be09ebc431180110219678bce1da6d680cd6ba44488a64d0115ef5cd954651116bdc205281771360bd63a8367c121d000000000000000000000000000000000c11280343ed187e208fa8e931a4623e0f7640310af5945f7a12cdf0e0f2083a5adda0fe5f27828a035cdca6ce9392d9000000000000000000000000000000000c4eea08962e98ec2c581a9b4990c89e63a167c157989ef6c806cccb24c51e6e10cb8261285d2d94f5c57b6b83e3df4f00000000000000000000000000000000043b3ff24ef58a0a1f156475311f27bf947ffd210aa391f954ea270f09819e83cf0247109af6ad8df78beae7faeedb481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f277f567130b1d7ec01364e23282ed6d1135fd1f32a2754d35d370c0c7127be2c098c271256208e0ed1e7acd45af72c0000000000000000000000000000000008d74f5ec8885cc079f6c05556f3845dc00c4e36d53ca17e167272c6ca3a28137ebcbe824438b85b290648f23601e34e000000000000000000000000000000000e665a7a21ed9389ccfc957f3d3f1cf57123f07e74d94c64e4d073cfa90971c44fd35aec59ae07bd7d53c36d95e2112f0000000000000000000000000000000003666c7119c745fc22355e9bf5300131b876b331b0c6f552ae9fa4ed1f374fda4a4077e9043e04809c1c0f93c65aff0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a49705939136bcfe4ce068fab6b2f180456acf483ce83b665167e6261fb4e28e2fde80bf1eaf4689900db6d4d4e4aa0000000000000000000000000000000000c3f57dc97bcc76ef1733f7907b4d07e63bcf815b55bdf19999137bba9485303ed6d767cf05c8af912da82359f31641000000000000000000000000000000000411a1136ca402475732f0ae051b9ccde80cbdaf4c6432bfd8923442c47c8b89669c00832fb625983fb9e391ea8a2dbf0000000000000000000000000000000018216a0ba8cbe92f0a09a4b7c5515f538b2236e40031c415538ab425b7d698ceac1941e5c9a5c3857ce3fe3688a388981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000da00c4674f9cc01e66d129ca5a47fa81581a6a5e8527b7638742e2d04a5be8219aaab38ee1df821e91dc2db2d0c9e70000000000000000000000000000000000b4f08ccd4951d4bcb472279a72f948bd104eda4670ca22e4aeeda4dd7f968d068d60a0a90678a65cb13153e88eb588d0000000000000000000000000000000008244cba7d088ee6f4b92d418958263cfbdb0f83ccbaf263f20d6d3eaeabb3a070550735421082f0fe251d159fa40333000000000000000000000000000000000607c9a9caf7d099076b179342779c2e8ef5d36d407b9076cfece2417bf8c37228f2f033b06d827553f4652e50bdb2821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c568736ab3dc7f5dac000bf84a737af6070b557902677cff54b68e524fc9cfe3b49620b95e8289b3796c05cc26ccbee000000000000000000000000000000000ee224acec26335478f915ed9cc0a52e5ed7fb820e89432a5e713bda42c2a981656c5d379276185f7cce6a4f9cbfb6f200000000000000000000000000000000095593da5879ddacb5420ec46cf7aa9af4e26e62f93eb8576544803474c3abcc5b35629d7c5186699d27aa1b7f84e12e0000000000000000000000000000000003f3b1c69ed04ecc14f68bac66d07cee5217ad71fd02d0b5f3d496df0930a467e2abc8ef09043da4eafbb8e02a3ea9de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a6f3b41625d46e012d4a40ff1db95aa22d211a576eb7025973da271fff61d4d95ae613f6e16e538e2f252bafaf1690000000000000000000000000000000000cd1f362402473fb90b84ccbd14ba9e72ecc792b2a935d2b8dd38f941b30a5a9ae96c0fe230410dcd728919d8b7ae3fc000000000000000000000000000000000684ca05384a96e4d802634b17d3c576931c3330f827e2e0f8f198e1158f622a1f8460ae77519283da1250c492ffcd430000000000000000000000000000000014e1d7a84085208e0411525ffc2832b7fe4137241409ea386460e2401c574ddb81c75806ace5e4cfec92ae128875e6731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015a9c663619826060576336ea35004faa2a2cf0b860e1915f7e1a5bb9f3ca8ef5dcb48d5bf05674e9667faf79cee1cb2000000000000000000000000000000000b5718430ee7dc2a56fdb1280c0ff90e0884885f07d2817c279fc720880dcd1333d951d56240ca6b271df3d717b06d89000000000000000000000000000000000d71e58b14bf0c658b59ec38e1c98f9f5c6108c2a1f4887f1e685c36d410b0e5865fdf0f7b2bd7c468d9601d55a18ef800000000000000000000000000000000157fa6c7e879115ef7789961438bc159ed50117bc4bfbea6c50a2978c31827e00aa63ab6aacebf7110dea6960bcbce9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040676a107ab7bcabb5d1bd41a37e0227d8b646347441dd0b8362d4798380aa98d23469b117b5d2692a5fa07a42db03c0000000000000000000000000000000000d5cbe62a304f16b33a210448259bc49c67a92aa3909d3b8796336de93eec26e254b2a078e3f03bd2cb3935d8df19f8000000000000000000000000000000000a3c38fe9efab7fbbc7899402d29e8dc99123db5be2737730a8b077b0dc63f162fe8c289f51cfe309abc33bee885f0b6000000000000000000000000000000000988f9016f721b0f418692c34a4b02232a697e08bed812bdf2bf13f5cadadd09a325c4b46f0015219a35fbc1766bcb5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ede42c330b01942e717e3098ee6692e6918eb1091fb896eacc4ca3b17703d17e6b9fc7ec3b193fcdef863a2b2f64a2000000000000000000000000000000000aad48577ec39dad0b112a2849de88a18c991c7f55168223ce384c8e2b9ff9fe0a243f66c50be099807bcd0bfa98093c0000000000000000000000000000000013f4a655e94a1a71926b92dd7c09b65fe121b93af61433bad33808d7d0bb17a276b71020bb541c67bdc8a8ebd737930b000000000000000000000000000000000cdee44aabb91797019f10280cb5b79917e306f574e21b2ccaf7b0a00ec9db3b36f3247b368b031bdfbbcbac827ee9571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a77802ad0e9f7c48cf6a3228d02989f9ecb00348cba3fc2ac5b4ef4ede200333579e43d4b1576044560fea52f75f57000000000000000000000000000000000be4a23b999a34c94887206f7c1afbfd13d8def10d46041c816cb5bc5391aab0d2d2a843687df527bcd5a635dcdaa2f20000000000000000000000000000000016407c14049f61c7f9b0f2e49d4cdeeb701ce4a4839422147fae1e773df88c6b36c2971768a9246c789ede4f798b57c70000000000000000000000000000000008a6577554240e7bbee830553ac0a38b732cf3ae4713e10f174d391cf6f1e58238b7365ab440c7e872a6dbfd08b2096e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2d366e236f71cfb17bc808ad7f3a9249379648934f9773538c201a5ef668390345e0f384ea2b82fb9941cfa9c126000000000000000000000000000000000013092623bd946511781c9e0c8810f4b0cf78cddb01c3b50ef59c6253ccda85ad91cdad81484a4ed9fedd51bf93bb82a50000000000000000000000000000000010c9e1c4109630faf19401c9cd51ff8b51e5434a79c4421efe87e02a571c14b333a07b6215d12d9a68dd6c42873209b300000000000000000000000000000000190c7d2704b9a55d1592d2f1124a20ff72f545c87ba705f714ebd87aee19ae3c74fb94409601e7d862990b9d1b8368801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018da80402f3c38b1a5d6fb69270c8e2cf98136f6ac7ba24eeb4849ac58f7a4462a3d572ffa5b47bb63615cd83dd8d0860000000000000000000000000000000011b8d8dce5a8c215dafebc1de7f0360c6fd9dfbb382b772b62c81c06d8f65e8293dcb2c8614663dc8f27d0a42b12306000000000000000000000000000000000146e85d62b7f22a341dfcd761d6ac6f1bbd6911847d7ea687f7b0fcd7a8053cb34857bcf444e58eab1fe1e56d4a138430000000000000000000000000000000017d5399f688c96bbf592a160497da7a43f226e1038f9b1b5bccf8ce5e8a8d7af50e4ec4220b74ac1bbfb0cc01c908da11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f81f4dea7cc81860c1a2e571e7d2bfae72353bd064e1fd86d8f625935aad1e6da4b271f4905a986d45c75257aac315000000000000000000000000000000000bd6e1e69d59b79a7ab2eefd803f6357127b920acaac711781cc0689ae04c971418157dfb277a9c0dce4e3deb441eb2600000000000000000000000000000000069c9d5bd9597914115b26ffc743504958d20b630f9124ffd41fca76789320a8dd50a14a37a5466dcb8894d7f671aa910000000000000000000000000000000004178ee76b930cdba15a9e4a5cfee483f25313e03b48cd996280c666bc647305037c8396e951f95696920abb28911b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fb86a7adcdad34a6e76ba34627b5baeb0008198d484302ad5952940410991d6bd5c806b98a7272ed3f4242662f39d90000000000000000000000000000000002e917174ea7b23eaac04026abeb2d0493d8fbebfe44d17330f5fec06d08825161ce4a1ca94d0786c7a9e57486413d2e0000000000000000000000000000000010702803c47d175e5e1a7e84aebd2ec1864058edf5857fc5725ec7c5b2d2081655caf4dab4c66d0d7e54a8f3c7fb18d000000000000000000000000000000000021f48eaf074c2721217dc547d7238b8ab63fcae68d2515bb9f4b95ad3f4b3c6be4f637d7fc7ca108ba59fb3243f34a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a3efa39078b31c23c23a240e9bfb8d09663b81fd81df214cdce9d5aa242906db587e46c373724f2bce325caf16ea380000000000000000000000000000000010d037ab19e47513a728afbb2da278ee80108e39849bdf3395a84efed36e34d370dcefc550089fc7833d29c8cf7c1b0b00000000000000000000000000000000049f9a20d5193d133bec5d98096e17f9aeacae5f83563de13d7e79e4adcd5a841c9d937f0a824ae1b42bf1c21759156e000000000000000000000000000000001959339caae71eac4e92b41df82650e6bd00e413e2334e5efd14cf7ffafb6da4ce75abe59253238e4be0ac3244fe9db71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000137654cf93c749e5264895a0140fb7dfde588c9255d3c6c2f57bb7fb3e6ae91629e79064ad56be0cec161c2914c07984000000000000000000000000000000000dc0bb51207f05f0fbab1114abdabeca56c1284f64881a3afd7dc1b16f96c496e07f90942fb33080a76cbd0f25c105d0000000000000000000000000000000001440d633a7bb379dfe305a829f7ff91f5f282c2d05e127881495a8160e6ec0c735a24ac0c97e17f96c93174f988c61ab00000000000000000000000000000000026dbb34ecbfaf430a029c5cc94aaab214bdec44a542e83ed94d65675f2f66ab31e5fd7e1b7ec491b3daae043bd33459", + "Name": "g2msm-24-jwasinger", + "Gas": 326160, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000001e5b0e9b9f0999306f0d015bcfd39a6330ad4f498e329db3be3d777fc4a06055f8729297edcc8a233749e472dd14c72000000000000000000000000000000001141f5cce35116ab733d2f7e50edbc316fe97a82635438683f212c9edd0aaa82134a7ca98355df16e843074c01ec593a00000000000000000000000000000000021d98390d8c8310184fc0d6c385ea6fac59e09b80c1bd8a8a8843ca952945fb423f9fe9c3eaa7cd5b9d0855248feab400000000000000000000000000000000095fe0a3219857cc8e8eac816e827109a94420f8311ca015c101321afefc894d899c52995719f16b96a0fba4f104a8971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be65aa653fc0a4bc3f076806e486e35c1d1809789cad5399fb69f9d5e73924223e57349234c8e805dadabb79176d99f000000000000000000000000000000000e1312bc5792aad3ef860f87c794b90228b1d59ef6497e78fbc9d8e24aed1009c18744ea5b00398d2c33bf8cb2dd8ce80000000000000000000000000000000006b73f602327857007ff2c91da9726eb5ad84c20808f042906c4e02659fa179e9748d2b2d578ec4e2bccc57256a365340000000000000000000000000000000006455303efa265248a283b4f671966f305562d18f11305a538652ed6cf34f8af3ea5328f15304c6e82ef759b97fb15401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010f08757e8c93a21970f87cf55bcbd870eb5098159354ae37fd620d204b74e253bb5bfc2898656715483d5a7b51168f000000000000000000000000000000001236eaa4c0a1821c732d2bfe0b11478caf4be4c3c2fefa42ed8718b901a3bf45150145dbc71557a215ce2d26e8d586710000000000000000000000000000000017ef5bfea074047c5ebf6e91ac65094fe4c480ab9df4de55bb7323d2e6ba5e01cf07698ee2e24bbc1456ce9940d7fead00000000000000000000000000000000090d0b63f5f7463941b7e768eb6b69382ba4d532363df7ef413cfc9fa3aed5c6a18ab978be63f277028f29ccc54d21fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158689aff14b4ae475a25339d63129c105d348d6be3f3abe81e66a87640157070598b726e911d7b1b144a389830f68bd0000000000000000000000000000000015e89d2fbc7602324de017b06da6e0069561d96d55ee40aeff172dd6935eccb0e333205ac0b51af925478e15e830fc76000000000000000000000000000000000d00904cf9f615c3e88073740d06b49f2fadbaeb079871b711dbb03df9e6a0281f3f886e3e6c6a0d15fcd8663430da7500000000000000000000000000000000082a873a3cf582b8d6e2da576ffbe07bc4a7f39059a683ece1de5e3cda20a86d99dde9ab9cc20893ec82a600a52750511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000096f18a7d453f59dfb7f0776c8f0a73823fbd4e18c6d1387f02096471fb98f732d44dee7f639cfbabfd2bfe8e984b2f00000000000000000000000000000000188259fcd755917e7b00cd50254fea2027bb9e094fdde8883df2275260e6a03b225492ec21da987e308c531399d8b0c9000000000000000000000000000000000abe68e995aaaaf1b11a1d50c971e789a1e21d3f27f15fe4eb4e6f04f6389507f1206d6f6d2a178fd37667ee4fff830b000000000000000000000000000000001813cb814229c0512ead9c0821aecb71654ce5c4b6050704c0f0d9f085432ff9a8572e3f77acd9a35d0b865bdc61c3c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122881fd1f5b60ae6f906d5e79cd6f2dad2a0823eecf0ee2547cff1b95388e0c788ac6ff7ed586baf4768dc2dc251a0c000000000000000000000000000000000116a1b8b19f1a1b0b8041fe5fbd86803230b78d641f64c3a263b2258721b1f30e98360c753a36e8911e45323bf381780000000000000000000000000000000013c7a6e5504372ccf7af11b62d4b5c03afb126e491a87d87103abff27af5fe31b94d39ab9fc24608cb47e5e4371f55c1000000000000000000000000000000000de4fca6d2c0a35398e7dbd0f2d1224edafe7aa4ee5eff131436394de5559630355120688e42740168c4eb856748cf5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000185b5813305b5e9ce03d77a3dc58171f6f51fe0f3ee92675abb245a6d367984e0ccab9d08e947b0d44683dfa2fbcce10000000000000000000000000000000002108d9d924de220e1073c91c456134a1244cd16ea8ceb7934c00b2a96b4eec650050aad11c28a42d738ebd5c86058b1000000000000000000000000000000000ec354d211e0030ff667abb1484612a4fb56c8eb69366cb72229e5c1290e6c5580577a6c0def70de131c490743bb90920000000000000000000000000000000001778c599860ab1d85b98ab1bedcb85eeb7823af2eba115c1963020aee5da5998d0942c87d5908f5a7e035e305d7a5171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166c237b65bdc5c0b9b3ea1d87a6a011c31eb734e25858578bc02f378d731d869baa4294e31af49ce371d2466a05c11d0000000000000000000000000000000018935715b8d63d4b1f4e6b1fbb4f450e5b3cd2dbf3a1ff5c0b03020146a506ff6c493d589b257f63baf9ccd273241d1e000000000000000000000000000000000b000a8c079bd2432b4fbc6fdc2a05db27d775f60a5a353c25a531f1a5c0cedcfa13dd08da2d9cd86206c54158993dd100000000000000000000000000000000104f7191090aaae74bea16f234ed3cf942c089cb3821f555f400755ef4e7026323d632618575f5c2ca11cd52500918871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114b648f0fe373644644f42e2a6475eadcd951e82dc8d1fd0d67c0679ff0f64e9698c9fd1173cefdabf6d2718c01ca0a000000000000000000000000000000000b064556de57d8f946087a403368e99b7c2f661b54b874fb7300dd71c011d7c5f13d970e35f1a9618b3213bf0f79c281000000000000000000000000000000000668d923a8e5104ea1ef7893ecb3195a2d29693da86cf4bdd357eb3870e643337fbe65d043fbecd1b9c1e6a44e3e5a5800000000000000000000000000000000000251ad44c3e4751a686098edc96a00469290e8323ed1abae958ff0a733c4fcd31ad59faba68a961cffad78716d40571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013caee76d15a9f200d0a33f2390d68837821c4a89133a09bcf4663bafa953765f10310648e3edee2555970f44410f8670000000000000000000000000000000016549d4c0bfb31e9c7f4cd050d32f8a8d50a6ab9ae380f8539f14a04ce171973193d116599011ba33f6512e9ff041fc6000000000000000000000000000000000f30b18ea024e3c5d773df3188ad08633fed7f02ad734a3af765e062f0195db5eaf7c9a2d096df4bc42d0a6f478f708a000000000000000000000000000000000eda93cde7dd23345b08c84e84ef379688f7ed8f9794628801c2ef1ef345bc3df80d2eebd9b6dc908911790fb87a75ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181414a164d518599eae38992f79c6d3b8e5d523f939baaf67d7aaad7044ce59bebd6168018d06d1de9ccbd1b6a5aa0d0000000000000000000000000000000017f426c40d9549db66b9fb56cff2b60f6e8a145bfc688b4c8a8e5b5784e6ef776efe474e24de5d1e4a4082deeba8bb4300000000000000000000000000000000071b3af6ae3bb0a65ceb2a40403fa97146e206069fef1f42147d485605cdfc5dc71be6a85a4f6879c0b7f51b3115387b0000000000000000000000000000000017cb7152a5494bdd8590441aef8298097cd4f0205cf6a74b466778a529746847a948c47b5acbc9a229d9b44e3a485a251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd9718e8c66c5133124643b5ea1ff00f02dfeee3bf8f578129e53bee10c82ee6c979e2bf8a4d6b958df4f28fac1ca560000000000000000000000000000000018be48d039c5963aa9d1cac1f9bc95286e08235cb083b45e5a30159e48b050be7c9f49174923d041e027608a12e4f46b000000000000000000000000000000001569409c6b6aad21c30fc7a8eb76e3339a444bebe3f184b976e43d011a527fa4fb0909ec08e1b366c010f9259d5d5f7900000000000000000000000000000000079338ab39171dfaad8320c8d1a5f7462aebf19c78f80c71be95c98b255798dd974971fd96953de700cc645a02b803101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ac1633d6a9ad527bb793767ae7c7697d58d6572c11b246be3b7607cc443ef655b7a130b07407b7389632a21dacc4da0000000000000000000000000000000018a9a4596efda2d945704a5766379f8a63843af8341aea8fd63a5abeb1d43735da19256212b72833253ce25d02d3b8e500000000000000000000000000000000000c6d48029bbde34cf9135689fac4b7bb7a75fe8813a479fc1fb6fba9660eb0e4b71ac3fd89521a07e84063f080be07000000000000000000000000000000001392848d2910b35352fbbd10dd899264501225e3347f47e6ac3d0ae6107eb8165438d01cdb9666dc2374b3ea93a7a0a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041ee1006c843e70b12b93e9ec967c4e29012a2814cb8f06f51351a5df2700489b38fac7d1266f7fd61be766a220eb0d00000000000000000000000000000000177dd92c5800d9e32b3f616948c61de96c5d76bfac2eba80b563beb6eae1dceb66711631c0216c636d629be49e7feb480000000000000000000000000000000001bf08730acc28ba0bb2fc4da448187e3b8801535c9a4ad3c070908b1cfeb902f885b19cb6347e8a15463c82b84ce75d000000000000000000000000000000001322149794ac64e852c27b4df3741edf3c1d68aa217b867d78bf6a6cfec09cfa02e3e6bd9424a1389ac024ecc5b5f2aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb5a9b38afe3636f2fc349d1f58f324fe14b9dd2393e393dee1c85a7a00994c6053cd570ac31796b7dbc9cd8d065aa000000000000000000000000000000000192889afe5265b6174d1dded78fd56bf9b8cb3d9b3bb119467522f895c5d0cbeec58bff48977e89013143eb5db5b31410000000000000000000000000000000017b78fb572364b3d4c741ebb05018dd58a701cdb5a69c193c03c742a45b99d1cb69f9ffc1840a2049535dc424b3a136900000000000000000000000000000000090dab3dc5e7c6b336ef7509058a24a0d4ba582c1c6e94cba9ca5df3d54fe040a56a619accf3218189f7de98a35bddd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c20d82dd42a30f2c0b6fcb126e68e8fd4d3f9ca0577c77183de57e0e874c76e2a0078dcbf309e5dc030e0339b56088000000000000000000000000000000000a494eaad0ec56347d8cef8e4f836c80c8a1e69f8338645a50541a5040da2f8e36dd5f7956ffbbe180c831011fc62e02000000000000000000000000000000001665c0ed27e3a8e39a36c407542e00a3bfc5b9f6b83456bab28b79132abca823c66f4d076df802260024e0b3bc3d8e0600000000000000000000000000000000155430ffe4bdfe8f784ef854bb6c813658cf0707830f682176af31b513e480b169e98039dc4baac67636db60428cc26b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181becc4c9890613a2ae6d96fdc758bd81d89b9363fddfe63820fd2ad5e8a997488a54370402272de2f2ccf9af2214fb0000000000000000000000000000000000ead30838406e3c82046b545e3fadeedfd843743796f41d71f3c8fbc07afb94460861f9b527309ac4ed091ab7b02aa7000000000000000000000000000000000a3f7d7fa655ffd5fb79ed55afe6802dc3eda60f9774258facabc2f3ee220f68f0bf85fd61350571e9bebf990715fd7e000000000000000000000000000000000b73ba70cedcf6c211c72444126533fa068509e5ab6a6bebe8270ad3239c588d7e51b80cbf6b5889fdb8e3a355fc9ea21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf7d8d3afc421722745e07f37d6bc6b1bae37d84ddb4a8ebd71b608af6ba690f0382779713a3958235347a512a41836000000000000000000000000000000000a0f1d38913d0a87293c9607498eb586225919d44cfec8119525db35aa2eaae63c62a9fe907f50e97ac3274047337b25000000000000000000000000000000000c9984174e19426c4f891621a12b93a867ae7f05071616d1dfd349a1089d47e5667eb0048c809add6e1c78f281ce2f520000000000000000000000000000000006c5b5b848cb195b0344a9d1c03825d1962a520b69d8c2fac21528ceef4a7bf222afe62604c0243601ab6a1862ef580a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004cde4d4e374afc2e31c201f7fd2ea48e59395e76a1814f025a706c865d8956b16a601a28666e180aa823bea72e28dec0000000000000000000000000000000015903dbdeaf68d21a53b7c1b4508df8b5f394015213dd9396db0b828993e2d6e6299efab44aaab10ce11529c54a4bb35000000000000000000000000000000000bc260249b64fce303eb35cc60408f701515156b336b0ee783fceacf3ba6f6a5c974e84d069e105714126accb2be99b200000000000000000000000000000000143aa8e878468eab92990f99f2558b09168e6c1ddcd198e92ce189463885592f416b92f5f8efe499e37956faed45a34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011124c28a8d4ec4d3009264f1c88a959f0f099a81d0704d2f92ef44d34a85faa4f96db4d26bc983e075df108c8b1a6f0000000000000000000000000000000000a5ac8d1dd5dbb234907ace0a736fe80b171b14568599725685600d26e9dcc7b3ca8ad3a91c47b09c0a5d21dafc9c70e00000000000000000000000000000000016a0ba5e1a61e820dfa1a8bb70a149a5f2c0526c98adcc4f61e683bc6e8907ae04af04e65385a6208a9ff6c33c54dba00000000000000000000000000000000181a4f5a13e95c7928a2609cf45cdb8e8bd34f78f8d92457d877badd0ff993bea93b52e039cfd4969a56e3cc62f7792e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dfa1b914057df5e8ec729ab3485d16cfb64d23acbb5268da8f2bd46c91b4aadfee745dc0b625356aa65394d96589c3000000000000000000000000000000000dfc2c9e99a6ef09aec9daa12c39580d42ef5cacdfd6fba66759320dc5c3dca73273faf2a35be290d40634ee57fd76350000000000000000000000000000000005a57b840b7fdb736700ea63bb7f9f166d284afeae2070dd1355fb0d4eaf78f5bad2783fbfce0b0b50bbc343c9b0084a0000000000000000000000000000000008848359f48c2cf54a9d11e9525b2b62f3ce5d831e5bd4bafb12694ca7d56f05cecff05e91f1fd4b3a138359b53f99a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e1645a4f01472d207fcc367ef179d101b1066eac6155e20e01fac7894551603bfcfe31dd1f4bb39631dbfcdc59ba48000000000000000000000000000000000ea97bd05666fcafa7234a745622de8819b4d0259c2d2838b6345c160e4d309c73a536e8b53cd3b5843e79ae555cff940000000000000000000000000000000017a6145a5ca8815b581ac7ce6cd2cae1710689e2c10f104574e3076a133be6753387f03050cbc41723c18e751a790ff70000000000000000000000000000000018d77dfc4b2e700314751f5b1ea97157214c59d308c200fa3c473f7a7741aea6d19186073cd312aa9e95058e98366e031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a2d6ca710cbcad434cea93d491ba77383230c90488a3ae274aec1670fe789b1724f8fbb542a2ed59215a4d866be15900000000000000000000000000000000114f44f0bf5787db5a42ffcddc4184edb2b982ef65aa45e69552ee73d60f14b6ed5fc310a82bcfd5f2ca35a5be77ef600000000000000000000000000000000011de3a286920be37bb3725d5f6f46a27dec0d58718d7a8aa8db024a499a2a03135f2de656db900efcd0624301bb672a60000000000000000000000000000000001dd2e17de5afac749761939c660f24aab48482b18ca2d433d4b3f1dc299daf29d84979c329f6457f4c456cd28e7b2911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e501858e820f6fcfe4d68ac94672bbd55b78a3747497ccad933679973dbd3ee5fc00460866f4ce0c535935df1aba20000000000000000000000000000000018a2ca2c471567905c6347073dc366f099f71e4dbb22ea262827f43a3513bc13b274f2230f52dd867205d91fc662c3c300000000000000000000000000000000143bbeadb69f9f62398483eeba5f31b295966a2e13512ed55220e7aea80dab981266e6e218fcc15a997463098be88f84000000000000000000000000000000000a04948d7a40e6e822dde1842c8d7b233cbf2e0656afe9f1f8f4145252a76f501740d2183effc4b7032dcbc6341e5dd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e54526b9ba6727fe4d0b78a5941f01a88bd46fcf3ed6177aa6f7fdf907028d3954ef66cb64fcd7a3ab4d09a3143272000000000000000000000000000000000652522b515d5eb665544948cf5ec2798c77b89b82b19819df0cea4da797b4925d02a8c52cc23a46abbac023a30a9c53000000000000000000000000000000000e253d61845e93a697ab2233ce346ceccc490f6d7fda2f2333dcf982e7329d6d1fa9b335e62a4fb66b43772529b1702d0000000000000000000000000000000019c605dbd244f09df01bd7ba506120a325ebc06389da8e220564ead1f191aaba38a3b8ef911b574d9b3f4e50ecf250fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000129206dc100439db26a0f5442328e35213167e677976f0d5a2a967f16c4f80812c20a088f7be4b09feac7776d61ee443000000000000000000000000000000000656eda529137539dda942ef083bd444552f576f770ee8009ad91ac8a40b3af38680cf632d629213b363135dcf8a478a0000000000000000000000000000000000e907a8f9dc2f2886460a374ec6df1111337c969f4e4c69e567cf7d31eadf9bbd2d8677eebbef2dbdd887255b0cb9610000000000000000000000000000000004c59906f69ed3161bf4769734a2c2a70f25a0873bcdf6b98abb446dbfb63268fc40e50f3b1872db89ddbff968f772d7", + "Name": "g2msm-25-jwasinger", + "Gas": 335250, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000013dd1a8152ebd368d8da76ce266836f7c379ffe033e27ed4976f12cff52af857a14284bb5017d4cb4545cc331402752f000000000000000000000000000000000d800a6eaab1b6d3ed548a6d5c6f8e7af4ca695b8af8e0bb94027481904ef0d7cb54350c93d64c5df969eed85f65a328000000000000000000000000000000000c0007f1f7531e77aa343bae0090a5a747d43287972ba52f6e825f318508be57978427adbb02f6d235033cc1e8c3eeb30000000000000000000000000000000011bdf642b99a1f9105c8f121c712625e02dc1cfdf150eaa01f8cfa8306c55f8d6e280e3f3f77d3ffb06f78d4dcba37c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060884cc5d27b3b53a08b09a35e50f61060d35260d07adab24d0f7157879f85399dc756a2be322b61520fa778205c659000000000000000000000000000000000e9929a6775cb6368baa8a470042d3a7b6c034de3fe5ac6845b5795fc6f7f5abf5dd48e65b3da824172f4abd8d9505580000000000000000000000000000000015ce595ae51fdcb3f3c0d908e69efdb31da0daf3f7cf4a878d96ed0f427fcdd3156906d326a517b287e0666fa33acac9000000000000000000000000000000000fe2bd42dceb8166a57fa05fbf571db860537de12bd55c03654d72f805fbb065dc33d20e017d6e2a6f89b2125c0c5d731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001492b2c433c2718112ae39127d5125f4d360609bc0087d8270fdb3c3c78f84fddc57ea9c5d27c1114075fddbdf54800b00000000000000000000000000000000134386f82ac76bfddd6959ab42cc45b7698a398f475b59b8a35c450601ad8d73abdefc2f73f6a77cab466a73c0259742000000000000000000000000000000000f6deb7eeb6abce474ad01528523ffa39e02a5460d087719b8d00919cabb1b1a1ca739976421ac64433c1f01c55c8db50000000000000000000000000000000009d0ce63a7d8558e4711447dc182cae1df9e3765bc4bb4f52603716f1a2fe093dc2e3b03532d340f4bf97e64eba4b9bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c6c71de74b5de2035f35f7bc79d487ce73e4d53c38f541bae929f17036ef9fea144c3017a10bd45766dafe1cce17da000000000000000000000000000000000ad440a37a68764365002e8373a3a6a690849fd5baacb2aeb1ecbcdc2a6ce121a405f5dc4c5f073b791ff29467566ff50000000000000000000000000000000005f88814ae4d13df1622efdc55cc164732fbb7d673fb661a2ebc77cf3af0862c14ab51f39bab40a57402d8ff55e8be3a000000000000000000000000000000000790087b07d0cc4446030d5af3e655e567ec5bf203475166cceb778cd281b93a11060617f44385fdefa8ee6533d30b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161231eada139db25be678e11bfa18bb940da23262b444d005f33186a951b28df6f415a334abaf36706771e1f9ed13d100000000000000000000000000000000148b9d050ffba4de9d217f7fb35e181f8ba13a41588b0d280f911540569236157901b8cf54c5d8b121a6538759865477000000000000000000000000000000000c08c483cfdd8879e0bbce35a74dd4c338c434ef1a321e43584d02774d3df79c52891f07e442dbddc14f1a31d73f8075000000000000000000000000000000000e0170851505091e265d3e01f6b44b777ebd774a25de3b48a3049ca0943562a4c2a4fff893dfaa4e27dade075755179c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012709e704164e1eb73c2fb05b0c775244ea24aca73eec420435e02182ce093161e510478542b4f42fc9a1478085bd49b0000000000000000000000000000000010ee54b9660fbf5f28d3c8069225291c1148fa3eaba1ede6f64def59881081514de640bc8f2270099b6865904ca0649d00000000000000000000000000000000021f022db589032b3ed58f65fcf69f1cf94f8a99eca279a78520042dd3dc5a5b790a6c02de652e3fa3a790bc388a8da700000000000000000000000000000000111d8975b2911ef7d003fb8ff9fb3c75bdcdfe4d3f5773ad9c0b68abf478d8b0c0dbcc26ee02cc6b20fb5c6a73b4ad421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015179afbc87e9d9546d3d1cebeb7c9af8957f0874fe4ea50d5af9b0d14e0e67c0b11302c1ca3bbaa0cb371b62c9ea4e0000000000000000000000000000000013819bd48580f9cdb17e59ab8fd70781ac73e1e7e3ccc75d897eea5aa7e30b4d39d264d1d6800c9aaeabf74991232fa80000000000000000000000000000000004418df4824ebde248b877e71631a6aa23c17dd5a800d80422ce540fc95dad09bd42637b4092906b53e3d8d409dee4bb000000000000000000000000000000000f8666c460e334789d26a01116d74ad0c8686e86d28eac52fa52b24d6b46b4b1aa3678353116226c193e57b9c2e296021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011deaeaf2ce4f55ae4450c02000e60018162a1736d7cf87d642838d7dfaa753f43d44de1c3e3bc58ef1121c193db685400000000000000000000000000000000044f060243e928eacd93e1061a25475d43ffdc8e8b340981696129bb0af50e5bb075caa7a3c6bbc95cab39f7872db290000000000000000000000000000000000742d18768aff82dd6c9497cd19a5a0a69ada2f1f887de7b2936fb6e2a8ba1bfaf0a40751e0bb49c9c6842b29e14526e0000000000000000000000000000000013b6680c635371c13ba2bef217e733e8f60a568e68b31e2096883323d2f7bd9d34dfb24942a51a6a5d8a790e0ff0ff271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001803419526f3f72df28d9d087b06127c66520a2d5f75bf00420b24ddbdd58b913cb9ca092031129eef5ee0738cf499480000000000000000000000000000000014020aab6c106805ba033d124dea06cd0720dc3e61893f1d9ab6cb55eccec27a49459c085990c67acdd2b26e41dcbc150000000000000000000000000000000009a5b97ccd6b5d544996794d0289ba3d84cf0e1303431cb1a3f1f421413548264c7c7a14458f28c46cb3aca8742ba89200000000000000000000000000000000014e3b14a186f8008e5d25bf9fc39c604a82ea6cd6be546a44be6f2650ab1f9f365b4c3fc989a285c9fd0156b47391e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d20e3e12d9b8d9775b6edf748aa50b143d052b14e5c467ebc97baf6b165a8194d2a684d4f393075432ab0ee22048236000000000000000000000000000000000e0461832b1eb9f83f62c39abccf9dc590823c2ed8819a27b9e739719147c3cca93e3390ebfce521d51b23e27cfe8003000000000000000000000000000000000c2134c12e4ce7e80b2b8ca73353380edb76ab4524531c122b1bf0cd7dee4dab36755df3cb34a77db0187df8c83eee90000000000000000000000000000000000d0695e2124054082dfe79933f13a7a79bf39ad0fcb9b27c41d8df86f2e7c1124d071655a149701417e09504cdc36e561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a68897c046971329440530e969a852ef7c9da1a009772d2280033f8f29d94906dad61e5631fb66cb0b7ad2899d76a14000000000000000000000000000000000964c8c14e460f2ec388e58187b4ad3857f2e09ba7c2e598f952534a93e5a934f063b814b7f7244bc0b7ea98d3b210c50000000000000000000000000000000000a42167b27eb20a61c9a1520691808d6c1eb6f6088bfc35a3684ed8ca11c5e152423dd124c6a17137b9400173197ac900000000000000000000000000000000102a59307c0165316bf4504b0f47b1350e122e29ed9a4feb95a9e4848fd6ad8c41128e46e5e84e4f900ea1159501f6b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004697dc1fdc1949bc1629e5ebbc69ff84aab8cd4a5defbebff8e87611b1dbf2d77985cc931e40ba06e9d707be7f89922000000000000000000000000000000000c9cfa3c76637d5394fa9a1f5fdb712d3af88e29382432f352666903dca9942ac08f278d5c81f4fd163c3c3938638ab300000000000000000000000000000000140d1072216269370197dbf30f307692c6699c2ac994e9b6176c7247f8897fc204942ba22ca5e2031656c99f80b8a39f000000000000000000000000000000000f956e3e0547ec8232c36488a7e24a70a9c6d86dec59893477c90ef6904276471056f628250c614f81cb82d80868de991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0f2e13dee86f099cc1123ab9e006ee7d0ca1c14d80f5268c1f3c21cc74adb50c63c06b1e7f837687094fc7b3d9b87f000000000000000000000000000000000e42ea636f6c4fbc12d0cbfaaea58514c2f984013ab8d6065f565deb436a8578d432e2b282aade0f98f64708dc5306c9000000000000000000000000000000000616e759075d548e20cfc9559f21ccf5259871d3d27da8a77bb346046d95e34ee736cc2139cba2586dd74d8deb43503e0000000000000000000000000000000001bd1ae73d11d4c9a0028009fd38dc305b7cda654e92361028c27363fc09436adde8f4b6a08ef644bd62547f418392851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f50857448d96536d5ef5a3d4a33eb14d511b4f4d3b0ac99e9db29f520157e7b6d6c2d2627b65a3e5613c872fad8a9a0000000000000000000000000000000006854b2cc04bcb2465c58f121ecdef8a6b423cbaa9253bb3e0aa3e7d605d94acb93b0de015f2a4b85b15f3ea3033e88000000000000000000000000000000000187d884c47cad9a3c1c41ed1f1bec9e54c623328a8fde5008d705e5d53d60cfcaeb63e48ed9027add5f24dc85a6089ff0000000000000000000000000000000018161277b9968d0f34456be8dbb7d8994f7301011267cde3e50cae92e58fbb6643a2ae16fd769d6b97d250fdec3f025b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ccf14aa0285ac35afce53ccd0367cb845bbf2e8cd5bddc7e9128a78c5e96e013cd3f538e25526583f4e0910b147f1d5000000000000000000000000000000000dbc9db4dea63cc29caefe7ceab9a72868930efa5a5b4a12b16aaad5d6e826e3bb88b8d1cb82683fe2fd09645c293813000000000000000000000000000000000c09c8100a2d8b5719a0c0f54c6aa8d1e06021bde9e98661ad3818848da49008f21db3553749072656b525ad5e0e5a39000000000000000000000000000000000ba759a2d5faf75978dfd8f5a540a551b9dd2c67f60df87b8bfe991f1b21fbce7ebe5d4835d84108a85f3240fe1177101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166e832b265aecb3f5a6e2ebdd45ae7360ffea4f64bcf8e2fa0b57dcb5c65587ffa87909995d1d2f9fbb011ccadb652c000000000000000000000000000000001640bf86712e0c6f326929b546c40a623719c9fa2af4ff8d3630f5553956c27f7a7af27929a60c202bc911e34fcf27550000000000000000000000000000000019a7a55d357a58a9153d03dcb9cfa12ad277e14138dc25bafadd8304978403fe45f992f7bb92e544bd96fcb287954013000000000000000000000000000000000d8936b3048ef98e2876c7b1d50c4715fc04121337cb3457e707fb67969b7b464091f9d29431b5e6eaa22f8861c0e2e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f02688856c4fcc6f6c570e1c3ad32c96319a7fb5bb95991a3e62ccc1c1b09c6fa756613481be9fa164784b734ce874000000000000000000000000000000001093dcdb9c449293bd6494b022f54bc96cd8da05236d09ce7c2e9422f78673c21433fe1191f6b7a3ae6f4693d07d673e00000000000000000000000000000000016c2353d0bc006295d8fd13e2754683658eeb4e0e9584700e5f1aed9d5d90b380af59d3b10549fb84e34f8fd8ae870e00000000000000000000000000000000107ff5c291597e2e877928483302890c1129e5cf9124d91cf95ce53a58ff94c3cc5d41c4cb6a1e41f8503f17c60e1db21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001302655a302b412023452ec238ddc572fa3ddf3966757813d19d44b5eb3cf251f8758e63461ffcb9c8eefcd152aa83c5000000000000000000000000000000000247d5f87ce634fc0993ef00b1a1aa26b62573060e5682cd2e6d7f4409923c706816da4bf8cdeae32a3ebedff3291a46000000000000000000000000000000001145a7619ca369b7f721db0fc4b3bbc8e7070bb469f9e1587f665ecc2587ea9e738122930df2725cdf25377bb81bd42e000000000000000000000000000000000007b0e1c6c3f270345beef094a644c9c1ad0eb443efa124088f4d519da693d9de271cdf135ea00b9805cacc75adaede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aff7bec9c59d4075164402350cbd7248a272c7ddf7608797ca4783391bf32db5e4e58d166a701057448ebfa818005f100000000000000000000000000000000142e0524abaeb71b84a8b95f1501e1f2ee87781434b509f9bc97c95716f15d28fa755ad905a99e3b09b5a88e44cad716000000000000000000000000000000000ac2a1de84957ace2622630ba3165c44b5969ec41a767a3bf1b541e3064ac633ee8188e2b884f8cbfb8259ed0d5bae6000000000000000000000000000000000187d392cf2d94198fe036404b56bc76bbe6ae9ad153353cd3f70b620da22e069babf34eee14939db2d602cabbcbaa8571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e33edf77f5f20adc62ea7f2468f4074fc507d92b470a29541e76758873d3419644d3052608899afef4dd984d0b25d000000000000000000000000000000001372a6a3c0fdded5de8cfc0f6792246b4cfcebea5a53edee7e21d9a8fd727defc50fd9c367444b38cf78de35ba5aa0f3000000000000000000000000000000000071d7ee9db8811bd5b325f453f26fe83adffb6ac8ef7c7fb6390d86426c535d7577e499fc2aa5b133bbc694bccff2350000000000000000000000000000000005f5e5610d7905ac024fdf8d45efb7856902f0b608c4ec3aa6ac35d7281bf442a07890d87b04124a1c9fbe6129a689ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d5dce62126f2de014f073841b85b77d7319366b856dc30722cb417d94be30921074d0f7e79d13a1e0ebf0943c999ea0000000000000000000000000000000004444a5232e9d9b6aa04bd1e066152b79846f43d108cfd31a6542efa809758e6321924a5dbc119d831c4248326abaaa70000000000000000000000000000000008095fed5191b647fc6703ae68e3abf0a5a2baa482997ae69b477f5e9e06a6ff78c74c6158b6f02d6fc310e68970d74b000000000000000000000000000000000bce8fc6340a5b7ff722ed27d5ee321fd7ff776efbfa7265893ad39b1886bb10d693e3a2f43c01f8bc1c4de19622d1681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051b7a9c0fd37b4c35229c52e75820c84c207fe45abaa6ec40a277a1d27b601ba4a9ca7834fd4a6df7ceb26ddc7e8b940000000000000000000000000000000005773f74858625875b7bc7d0ee281f9fd75296cba4a8269ce3281f6abd5d2a3bc747dad608831ff405dd03afc5717b030000000000000000000000000000000011b7541f9044e38eb7a5e796a00de796b711d5ea7ec6e58877b6a700f808509f4db6e957b1fd23be66204d331e09798d000000000000000000000000000000000038be568c9556ccddfde756399d9ce9381d94f8f352e31811ccfcf2910753984430c8e792c3df57b49d1b4343fce3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e006167a88c4378fcb43b96ca9d69a141d76d3a41457beda5c24d4ce391fc11afff933cfb9436307f87e521bf069000000000000000000000000000000000c069952ce03883d72dc68f51bf515e5d84ec36453ed17863277cd27a90a3705b9f020ae6e3da2f24baf07ab0229ea1b0000000000000000000000000000000019f2653de8f385f4db69f0ca05398025108f71250479a701abe8b7fbc0eb54a935e9546ef3bcb40882232a23724788e100000000000000000000000000000000022decb44afa4c15fcbc3691fa33a97c3f0176983ddac54165c095e118acfe334f11d0cfd22429982a963eccb6e6392e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f5ab67aa74823fbf4eea840040d959411bf1d7ea277cbd7ab906b4b277377fd2aa42d108354b256c5951a040b01f2c00000000000000000000000000000000184f7dc075fa7368b0af95ddb5b936aa21c6594fd9c50bc0879dbc9afa1b82e82415a72dcedf90c68f3eafb6246bbaaf00000000000000000000000000000000059235c4ab09f4a5fe5c2310f65d589a52276ad2c6443351ae18bff6fc165f057e3d82b393cafe3bebc419dea4d946e4000000000000000000000000000000000c7b1d062cb1aab23bd1e5ab7558137ab6d1d0f8189437c9029556feb9b0f7b2184063ec3ea2cc5f5b03176241c318bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ef32bb3e895e074d577ae2f77cd709d215f7eef38b29a721afb4955f34cbff48f6d9ec9122bcac8ab0f5bb4038aef7a000000000000000000000000000000000202d0a71cbdf77a1b4abbe226c04c9e18bb814623ba74c0d22791398e0a4374111f6bcd0d2540a5a965528bf5bf1a8e00000000000000000000000000000000182b9ed7e3d41c69a535669783b2249d8237735457edeedf1da7767489f04b7093a2d87ca03cef263bec2f9fc19684550000000000000000000000000000000009f0b7f16bce7f6d68b22cb75c59cc25c546383ce9f4df786bde94110671f0c9badb591ac26f21cbf6221e8c61daaf361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea27aac8cbbd3851ac4ede681d8b4af2db899cd0fd7e4a006c362991f820f5a96f9f158e8ccfa8baa16d6e8825cc78c0000000000000000000000000000000017ae661ab033e69e0e2a9a29900aea6a30f96609cd60bf7e3f000967e4c3b07be9f24e694956fe551347f44a532e268c000000000000000000000000000000000b99875080448c455aaab8565995c059eff1d0f1ab92d77a753e7a855a189086355e2479232fabe87a9b30aec020e96600000000000000000000000000000000059b301d1077a1a5f9f83b3a10723754aa6dce8995de68df75d8267ac578417bf47c391b0acb77e47f396ee519b74ee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000010e177a9ed4aa48fa03898471df1568ce90b2e827533119e92362e967b5590293edcd9130bfc9c9dfef6300cde93b70200000000000000000000000000000000134a2c70f369fe2404d85a8826b268b3a9d1407d823a04bf60ad7a17229802c1c7426fde5d165ffd9561f42d8fa74057000000000000000000000000000000000588eb0c6c315f04a2f785367ace8a2e7fcce3393e743dfd7e12fdb360f4d64137b3058ad246d0986f8399c3f7772adf000000000000000000000000000000000d518bb657230d98e9293ef49938868d069965310d4082575c7c9721102cc230a4f8c05a104b41317a7d9f0b0eee156c", + "Name": "g2msm-26-jwasinger", + "Gas": 343980, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017b466f5635726ab8cc4e790b3a2b25cd4c895d00057e8cc2ca81111b1857fd336f5b94ec18dc3069f5069cf6a2a1d0b000000000000000000000000000000001491140e66fc8f6b753d1c1ed7f4947d57b5c4e94aaf5883b2f8e2725d586f917bcc2806b74b057241e52ee93a59955100000000000000000000000000000000058a38d7c2a69ed5c8d42d377831fbabe2aa9cb6c9730eb7cbd740075b21fb905f012e182db2f0a7a33a3e579833c8950000000000000000000000000000000014a5dab2f2e5b477a776d2dce6cb194e22b7123a5894c493935ab0049dab148289989a790f44b2615a9d4ad17f4534e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151bbc615a89678c85f4afea0304dd1a061e62ddad74721a92c8f6d271d2589a41efb06594e2e311a5095b4ee49ba055000000000000000000000000000000000e32e24fa5e12393a0c2872556bfe3b15c9df4b297fef463fd36795754ed10b78df15b765a61b2851044c1d844a6db2a000000000000000000000000000000000cca7edd74278ce7547be9b6020bd09c92f77f316f94f2604e2b5872207eca2e703c0c77dd8cfedd82ce15c8943c0bae000000000000000000000000000000000cdabc0c0d08f2a46bd407d82235c1acb4e8175072b10cd719fde744534338729984487d5595cb28dea61ab50ad706a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abc3c5c082c9575b6db14b67300638acd81ca8c633aafcd87747ebc53450e3caad1dbe57da0025cfb9ed48c366081c3000000000000000000000000000000000a8a9e81a2742f8ed63098fef9305532fe03697026434846c345ef34bcae6f03f68312bedc10d9619e678b7e069f0013000000000000000000000000000000000aa8a864a3b2b1be8967400f782575a2bc8f43d813340a16387f26f78f0006b80cf82bcd3621ab90eecd3a85e6d2e9170000000000000000000000000000000012bd87a203e4635ba35eb2f150ba4b33cd9246c83caf899e5ddfba4b0adf862c5d0921b49bb6d40fa9b2402bdb3ca63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5400b15cc3638cb278188c6d608d0314a370dacbb47de8e41a0ff31dba6a56b0c65f7fb1ab1f4b9fbe4f3eb51d38e7000000000000000000000000000000000a7a2dbd18c4e3bfdc3aaead6addebd1c3a0d3c1b61d93d79d2bec6b021295e5601ad3bd03ee40124360a0f913c5cbe00000000000000000000000000000000003ab5030ca9b102ed5486e6ee7c4f10232a761a09cf552e90c0d039f56f4343ac4053daaf92361254559b2e759b19e150000000000000000000000000000000003af1027d3e0ed0cafec41242a1a63e2850ed3a7892bc519729fb86aa163e2297f1176e284548d3099cd14a2dec2c0b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49e1ce5f171c5d42950a3f8f52cad144fc17ac907cd00077bf201385fa71b7342ac626f9b8fc00faa23f84dbbc80d6000000000000000000000000000000001233419883f2cd06173325b95b2d987f5e659f480a94d44a17f4186f9e7fc293f209de645a924202f8ca70c599e1b5820000000000000000000000000000000010eca16b9389b9a281aec6dd1267c302d2839a342f7dc7b65d24b9fefbc852eb445ebc3b0d9606f1679782119332519400000000000000000000000000000000162b7d1f9cc3aac5cd09d43c2a914272303749b747d48667a7c02bb923e297d1fb05cb56f92da9e650fb56154e3e97de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001757baa808967dd431d3c68f602ab5d6e662c5b028c654701915c8cbd744fad0d1613a4fd619984f7732b947d2334e33000000000000000000000000000000000baf539045f029959312ee90b4c222c2553ed343192f5d98acde57bf7d4b159c036e24b3607be3c8adc38f93ca157806000000000000000000000000000000001177841f00f3e1f6ac23563bf697972fb216c2329a66a3c3a2f91b48d1608842e537bb8003798d14590731a423bfca6f0000000000000000000000000000000004244e5cac4d05bf002941ac9e026cd2f26afd0fb7afabdccab4de13d263f86aef058673447a4182d3859441ac4ebebe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f835602b4d70043985f2056dd8553fc62dd28f894271e2f09c58e088237ce5d60048b1c36ed82900f407b8e57a53d400000000000000000000000000000000060fb494ce78f7333f21c9becea0f427e4e471396634093e121c4723c31e555e92fdb42d112d2148d4e7f959862064fc0000000000000000000000000000000019d6eebd41c715ce733c4a84ed434a5e5bc8d657f0fc0a5bdec47d1ef5f496ddcbbc4625524fb21e6dae2c765e5e63cc00000000000000000000000000000000084fe95871d8f1685935ef338e6dc5d698c8a22a7804b1e1a4d399be1ab5c55c855a97db5b3454d347e2bbd89efbc98e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019afa23b7d9bd52ea1cb6d70cf77b2b82395d3e586a4050e84cac1d3c3a834ca9c7ec1141c5f72bcd015d2b5b0de6d3e00000000000000000000000000000000009796f840d334711268390c02e5c8da4f513a7168e468aa6c9188bd47a4ce8c416e59952a5003abe83ab56f8f63a24e000000000000000000000000000000000cc0d94736382cdb24104ee6e698590c9cc6069cd2fbbaf5720c97ba981a187eaffe983427012f997fdfd0f13eb2581b00000000000000000000000000000000070fbff3c4545862f54c8313949fd9eeed684fc2550ebd750d34f6807249674b2539d2ef4b47b3a8962b473091076cb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d51e907cfddc7d34fb58668d264ffa7570afc9fc50b9bab8af566e0c135eeac33a39f7903df7a279f96074e75f240e0000000000000000000000000000000019513e63124c4dc1b4538440e07c119b631742cd53a02ed551293b6b858af0c9af8e55cd6ff5d827bf406f613628f80b0000000000000000000000000000000014ac194565733db257887988048e6f1c3394a8d3b8234b5f2c7c8d1e16c8e2ae8d47e5c49f23734838ff9a075918edc4000000000000000000000000000000000fa82dd5a9c3f4ac2009764b398c74a14c44d0baebdcbeddcd046216a5ec686a025762c447e6eb143978b9a428c621a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bc878d170467864321de521599563a9fcd21679d30bf8e9a5db6ef8549d4c1daca297af108e04f75f1a445b9ccd4ee0000000000000000000000000000000006fd6ac6eeb972720cc434839b9bd16391c0c83792560beb4064b47257cd217f1180b83a38ab55bdf6519dc1ffa02c760000000000000000000000000000000018a517ff253ce3179f5ec9477e8c77c307efd8401244d3604d1e0c473dfc061b9d8fa6d924ad1ab4fb2662d5cb8945850000000000000000000000000000000014b3791060323ba216cd3e458f5184c05ae4603f80f1677c16146cb9c5fd9d5009a4b4118cfab9f07b67c20be2d898bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bebdf5100096ede591d6d13ca10c58275e9f8328b54b33ee8d2d852c7345cd29746d3ecfb64168359c2e3b8770a50a000000000000000000000000000000000141eebb2a0071453cc5ffb21ea9f345726fd06987be26e4bb34ecbe34a85a287bbdc906d9677611241829e029f6fc16000000000000000000000000000000001343c588ae6a0c06232647409611f5f45f3f0ca31e2a269df2122f13b01fde6d85eb3af1185a8b4ff45a9b4f9486d3d10000000000000000000000000000000006ee525a3b4564e57b24b9b1d1355897b912f778ac4cbb17f4bd8f25f96abbedb932fe35b6b11ddea29c33bb223d3e3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f69f755437bd334fc131c71105c24f0eacc161abe06ccd7bd102cf85aef33d01c24a15cd429b25b227be0962b99bbe000000000000000000000000000000000476d24733c3e642eae49ec8234e7874f4bd8aac0cc38f34b94c6d40fb1fb201ef1aceac301a158fdae38796de335fef00000000000000000000000000000000173848165e601dcbfc32d91f8e0182f6113608cb693dc6e27ae92353444763f4f52402d92ca9c5ae8026e3efda2e82f700000000000000000000000000000000005a7c5fd80b145d071461f7aa976186e101157e8129c4cb3c1c724fe09c96366031a46c8bb15fcaa210643ba2c21d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001497ced1d027cf11ced861566b78301ec4d2f9ef815e80193cdb4da398822b66b66728596310c236b054c9c9ce85d6a40000000000000000000000000000000019400c20c4f93b92b21014e081ccf88f80d9df55caa43dcb6ad638d9ae59b6db0b7388fdefafa4a02c226bd6d94d01ee000000000000000000000000000000000ede5826c6c31c6a5103cdbe9d26c250dca6ed2143ba7bf9158891ef4cad5c30ab8f71dbeb481b23e0a532109fbbebe0000000000000000000000000000000000d1a9307e2b3ff45d45252fdb7bf85f052d6933706029b6db3d65f912fa7330aaf66a0ff65cb9c66b56a57fa3954b19d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f117f548c43bfe134a1a8a2e1861d3da3a1e3b93819e7902097fb426f35311c7d2b67ff09557f6873415137d8e926ce000000000000000000000000000000000a17c85d4a209c992bf910592ed3fb48de953404b1b0c6b31a18afd84b47d9201ec115fa829d68ba8f662d28ddd09f4c00000000000000000000000000000000006a22a4f5a69a39fa527ee223df809d86e60df03b084226ef55cced6e7dde476ff22f1f09c9960f91c42b651c74408f00000000000000000000000000000000123ad07333d2440587cec7c73cf058f02dfe6c992ff539b08391f54efd8ee7be10b40b5ac66aa6cf0b6a00f957b381361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077c9b6e94d1aca3994d5cd4dc1bd6c8901a7d34cfaf149d7d8c02f0232d71533c7b2b1579dc68eb87f000fa3dd1b24c000000000000000000000000000000000b6cf279da391cd5d062d10ae52a981acd28b1c7d3fa193015ce625776d7cc9e5736856cb7b3641f594960b98b577d5b00000000000000000000000000000000127e22eb1897edb2830385baf710090a88fee08c4bfa4a7b3370503c7b602c53ed466bd7ef2dfa88727dd676f57f781b000000000000000000000000000000001279071042c07e5ca928d5e7978d44b944011580dfecfe9474a7a64d4552b259de1fb594c57382b18931d1f10bde74021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b39deb6eca09dfeba991241178979e50f267b297a3cb94430b7366269ec87a69838cff538a4d01ab155c6cab830ee6800000000000000000000000000000000074de9246122562a40367621d2ddc9a6ea7412a54d5b3a74b591684bf5c00f7453ee1d4f48f8545f826620f38cb7fd900000000000000000000000000000000005cdd165ac48c4b0c003025fb1fc91b67da2118d0444c5f13611d392f5f3463064ff921d7befb1d90139c05b00b8b8ef000000000000000000000000000000000ecb107cc78107c8f1b743cfc4bd408f3f2a45632e664e3837729b35dd0cdab30e2a78391877d4b5c6211c3305587a2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a76848f53b0031b5512386e1c695b26e1de06a920bf532ab10cb7be4b22ab87df480970a8ff8ecb35476c6181cffdc000000000000000000000000000000000cd966ee4a5e586fc25e89003e5d14fde890bc0bd2af3c563cdde68fe028fbe9c4496c5b88e8e1c6136bc248f207a88000000000000000000000000000000000031199b879ee7dacd87ba21dbcaaa692a36f4cec0b55ab9fce0dfe7adae1dc1e5e582d0297c6a05325ae578e0c8d8a460000000000000000000000000000000005b7f517f3db32e15aaec1a08685432c200ff98588a6fdb7484d265b7915a758db9bd20360810ffadfb98bafb1b574281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac6d95f36e9d04bc6903ffab8714b4102e6b98f5960387bb7aab3b6c052a931a859baaf813d663a0c2e4594f02fee1c0000000000000000000000000000000015be3da50ff8bb3698421043ae5044abe20d64fe0b71b637140bf911b118eb835f2a5db65b850ec1d1f465f635815aee0000000000000000000000000000000014e0a2918eb0ef192ff517f4e808267f11085868c5528a68f1833a3919fa1f0913409e51703134d268eff3bc5d1aa86400000000000000000000000000000000063bb03518833e242962521dd732c20bdb4f672083a593141c9748515da0bbdb698c3c6f4572fbf4ad628c36a355d78c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae24172927010919010d0addb5f9e1e93a360e015db898f4e743bd02f94cefbeaebae1a42f29364f67a57ab01690885000000000000000000000000000000000d954d74338179804f9e4013c6bc89f1ac0bbcfcfea325e21975404e730af896de9a4c9748d665ed33708a754ed6a23a000000000000000000000000000000001402cbc269a4f1ce3a2194ed8c3d729fe76e7ee202d1ec418e83e1d1398ec3c0abf9f47687d7977c23b1890f1337a60400000000000000000000000000000000198321c68182fc313e1fe922ba70bf4676ef1fdcc011ba3805dd8248a1154580caf8944ba896ee4f00d2d9ada0d323fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001014a533e87e44a11c6155c150763c0efdba3f62a98de9c688a60b2e9a19823e4dff26db690f9b648b004bc6a609e8b50000000000000000000000000000000009b9467efbbb1fe42baa62735b4996e52ef5b29533c65529a4e730f91f12ae36dbdb7ddf582f9bfd2a69a223f81f1fa90000000000000000000000000000000012d94723501dc809147db9e6c45c9c1c7af62ac122132a59d71468088d2332f17a0f31bcd460033cdc10ffd26cd62ed00000000000000000000000000000000016c60366c8815048be831b797782150587d4036b6f65ba649d8a785d2b9b917115924b424366f3ed53c7d597826c54181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e25a976a8a12af765aba9215a395039f56236afc43c923a51bd3ce1c1dd016aa6cad6f74a0f5ea4d57474b9b76a7c2400000000000000000000000000000000007698cc2ba5cf928790a90a09aee40d950c1fc29520caaca0546d1cf8c8b024fedac2c6fddb3477314ee0052d57b0dd00000000000000000000000000000000079047c3cf347eb68ef30058578113f00937c07b7319cc0374b94a0fe1ff4c8542aa35bc18461b3f0f962625f1158b910000000000000000000000000000000019fbf94bfbca1bf093acf58a78f136fd9acca8dfc626676eb9570ec9a698f14bc2ef4042a8ebdb2a8e25378993fa819b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f1af6d0309bf888f652d043cbd16528ca3c86e2f05af1bb362d2a1067eeb49d966b401e13cf5665bced8fcc263abcb0000000000000000000000000000000008be680e4e2c6c4417e401d971fb7275df79ee2ff3200bb9aac0d6542f8257a6af3bf8ca7c95a838d86afcc15f157747000000000000000000000000000000000c28cdc2a7019c6565b9b92c47d2cf047534af6d799c0a58047df9a249fd9f36790e418c1a3518ed1b8e610824d2ada80000000000000000000000000000000004896da286ced4feecbf29deca38853e3d586626160024ae1f1da515f81abdea9fd5625f632651e57e6262cee9e876231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002cebf49b9900cda755bbe105d60ec4a47eb79f870921535a00be7c6e2b6689c0437e4478acffa8cdde448c4711e0aa30000000000000000000000000000000004da75fe951f17da29b34fca5c924ad4c6df5a5c6b2b612d25542bc6b779aaf533da07b2abdf646fc24925dcd29829160000000000000000000000000000000004e6f4bd82ac78bbe67bb3522b0f1ed7d632a39d5f31dc5eb2f876bf201f181f94c39e5ecdea60e718e565d5e5c65ba0000000000000000000000000000000000d61aebfd0e86f6e14ab12f38061b29c9025d88b983c0e843f7a438d41f956afb95e762861e732473330a7bd35b65b361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d27e2be7309e7775e3aa1dc94e63d6178cdf7721ec1f64bca85afb84bb20de98204c8f3ba40b36c5aa483980b066fe000000000000000000000000000000000a7a8913f2df351fcf75f4d7a5f1d0125117ee3db2f214d948e7941f9ea8bdcf07f6869ce3ee99d2fa321d5d15daafb000000000000000000000000000000000197fe14215448d7753bfa7d238df37dbc905fad4cf7eebd5103a9cdde6ba93c2d91f87019c387667724d2f61e8cf80680000000000000000000000000000000016e3048a474ee64393bb9913d980dc43a5659c8a37bfe2cd2539d6b8cf4eb75dff68548827662bf9963f00271cbb39e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d90f9f255c6551743de5e571fddccd5c98c844e70c78a90b524d87d894bb854385820a48cfe38bc5e6732ef2ba73ca0000000000000000000000000000000004f139f78b067f05e8bc1cf3ce63370b32b8a163d3926bc661bc5109a694df5c76984eb2bd30e3106ca48bec862d7731000000000000000000000000000000000fbdf8f4c88903aa0e9dea70dc0d21b32af3684499d0a8cfe7ffbfc729513d09f52e83f5670f952ad2789d9b05e3719600000000000000000000000000000000106a9b356cc42a5b1adff8e2e88ff6ba1e341a47211f98f4f1fc5dfcadd63925b64c4849badb2f889bb79da65984b77f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001232f968342d779eeb01286888ce643a1d388648b7868ac866db73584db52d735142b4cd47be856c5def43d251ef6bc60000000000000000000000000000000015b06e1192335b10c85fba76ba8ada9c23846d3e6ee42cc49b5827b57f5b225bb69a0a75ca0869df79e4514d2ec980ea0000000000000000000000000000000014227d905c9900053710d283d7917f5621ac787e22b861cbb5637a6b36df560c2c23b463dc2b1fc58566b36f05b6d2cf0000000000000000000000000000000010121926165535e2f34f413683dc960a3a4a700aa0d80d7e8ec207e7741e8d063b57d41d56118dcaf7b0972a40ec86a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b1411b6078aaa7aab7aa1ea0c9c70b13b28d53b0a04a1b4a877aca37e2c9f5cc48b91985b068ed44c38683826f5ce0a0000000000000000000000000000000003ca3eff9a5b1625f84b479afbbb314c6348ce313e691d8c54f21e72f24e205c8ddafa875f1f2edabb85350b144aaf56000000000000000000000000000000000f510fe91a927846b3667d6a6566cf86d17bf024a861b06095849eb3d2c650ba1df68788a9ee21db8e3cf001552b915600000000000000000000000000000000154cf8d5ffa97f8b855ebee6561540b92ef7b6882deb6f4cfe48adc12c0397292f053ffa84751b49aea9018c5bee62341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000daeffbeac73086ed686e84093a9ae24a9cfc12bd858863228fc9f6b27631b4a11ae912c79ce1b1f610980f5db4daf360000000000000000000000000000000017b27cefdfe6b389f1316f3dbcce81887439fe5709f6cefb8046eef4bb45d93a42a4ffc1790621ae35cc8ef2fb6829a3000000000000000000000000000000000390ea0bb7e10fb98aaedfb38762d0b5a559eb0ce5daf83d1029b9110d3f11c81c2f45ac815440f650299da806f027ac00000000000000000000000000000000062cd79334242309b75cbad6fba6494ca7f79110aab975094484d794c1798508b9eeef0b4374c5ac000ff9893465ce38", + "Name": "g2msm-27-jwasinger", + "Gas": 351135, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000c32c44fadd47baf1caf5f5b2697c249afa20c8e1c4f9c6e09ad5c6af80c9a8b114d264d75a5dbb3bdb5f3f445cdc50d0000000000000000000000000000000002385341a7ca7b442a4532a15311f0c7cfec23dfad40ef095b2a94ed105f386a254025601542be63a4ac001e47b3945200000000000000000000000000000000133f14dee2ee1c61595a337a61d929e47b335ec0b3100ca7024eb97978df4f7c86bfffc6d30d162bea11ea6738a617ff000000000000000000000000000000000ae7788967f9d0a394a2cd395a5877457b0ee584b0c6f008425cd935f8f793e3b918ca7d37d2eef0721f3ea234c7a8341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e467650fa56c6f0681b43454f8eee10569b8b47305ddee63213e0b730c9d1a1fd38a590f5978458721b48482f69cc600000000000000000000000000000000043148f352a9f33c0ac3ecac702f6c684b06cc7f30862d14ff4e9a86f99e55045162320270b7466353c1d157b096f1c900000000000000000000000000000000032479ecf2080199c137f3a0eb9506bebc1d107e83b2bb0e432e5cf6dfc3aabd15daa43fc32a8f0a755bd1b90c9baf080000000000000000000000000000000015d256b0bbdf546eb925584e7a352f151f0921ddeb471d66c8362e8d986f56b7c2a5c2b614976b5c2978dacf0c35e1861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079fa7060654532d8609dcae11401a192f2530314f77bfa5260d767a76742a4abdd6ccde632b3b4da22a8df194e89d990000000000000000000000000000000012fd50ec71c0b06e86b16772acda4b0d2786953df25a837da27534f696f0cc60d4890ebaccf1182b3b73ccc9b726187e000000000000000000000000000000001383fd9023e827f3c834c9bcddf22347f69e5aa2e5feeac824176c191b4fafd225850723f14051462fef7922489c4dfa00000000000000000000000000000000105eae88ce62a71f5ce436112f44f3aeca3a279a16176dd38ed657cdce280553402e2edac3457445177cc3c642f9738f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037c5c4d37eecbfdd4a7d0512186e8452d0eb050ead1fb8f471135dae07394d5b1ea1196e0038a3f1fd4b2c2f18ba726000000000000000000000000000000000974519652446db6592e810bbd5b0ad1691c248a6d09345a225aab4abfc6da327e5878c1c956bd69237f6dc5fc943154000000000000000000000000000000000ca49b517793586030e93bdc32d969ab1855d89735354168d22ffa0dbf240667c610758bd52432841a9cf6537c3ae1b6000000000000000000000000000000000704b031a6c530ec15f84fd61710d313abdf0244ed47bedc75a605eeab477c8b4c6aa1a3de8f83d5b2125e57a27731801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aff348b47627efe9373501b6a643f5e0318d032af1c17b73211e8932dc50602c3866b2c0cb42e605ce0494044a9e3c000000000000000000000000000000000c19d8f3c8f375124eacf0e8effb27c04c54ba5ee44de223d5e336f4d0903197c13107372d00c92f8a795eaa7920f8620000000000000000000000000000000014b7c1f79389acca1370808ecdf9b30aed431f2d317faad299716a423731ab3fd6e1b50ed20a6dcb9cb2ea7cb21023d50000000000000000000000000000000014613edad5cf6baba2b25387c442199ae84883e9b961fb671f84bd2e55b44ad4b6bb0e7d6fdb8ad893354459686c05931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c8add0c4d1b0a0bb17f6fcb2d6d0c5f94202293c7232967bc59ed9cc8a1f59a643a8f8c3619c6584c1b7c1dc860cc13000000000000000000000000000000000e322b288427637d1b8a892c1440851d4b4a8ad53f7a449e396e80707b52101ebe89f7dad1b8a3df99b334b55cd5e03200000000000000000000000000000000029cb43a3f28d085b6179ae8d51fbe6ce1dccf627d3eddbd56cc0360ddb2c9a841e0737bc3a40bcb819d2ffc0dc09cd6000000000000000000000000000000001669ab77d48ff744eadf86f37d86e5bf5627f24ef117750bd48006e9e90121b63f28bedf81aae6fd5165dff675b6b33c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145a016c0e4433f3e01868b4bdfc3e3e05aa88146357548eb02061642b442067442b6e4a307de8a4103a22a59ca59c780000000000000000000000000000000000f2d793d9484a116cbba46ebc6fe2db533548046ed49a9e5e120056969ee6f8c0390aaaeb57f7a6ab3ce225dcb15bbf0000000000000000000000000000000006043991f7fdfdc31c20a0c5cd82f79f7536fcfa5dfd161cd866b8146feab8bafa4e722e8b8cdc7778136e74ff7f8ebd00000000000000000000000000000000038443ced42df60ad556f040ded32506f6e409a4481cde801ce3deab58c6b20e8718cd0ad058d55d5da89444de5428f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afad495b8844a566606922baa029d7e5237f75368a6c13818c4f016164a5016934393c6a5aaeb67246599f4e6fc6c0b000000000000000000000000000000001357d99be4aca05dc46dc0069c5f13ebf6b6635aa0ce83cab4ae7117c15a89ecaa6b75d90b99f87d078967a5aa25e582000000000000000000000000000000000233364039cd0d66d175197f8a13a47fb91b9323ca74364713f9deca73ea1b1e97cce7a33d53b3a4688951dbe6ac9104000000000000000000000000000000001780027a0b443639533d9ed9e2182064a0a8335fb5c474b08f1ecac455ef4e8476c3720aa328e7c9d2c60c76b4fd87dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a092f5f4ae37900d9a46a8f6a0d92d4bc8703c73332814e321f1863a956c7ece319b6ea7c3a1258923cd898627100e0000000000000000000000000000000011e4e1a1f683959b5193999b41abd9ddd647f830b921d69dbd736677e9c865dba82403a0408df67d4d98aaf55099189f0000000000000000000000000000000012308c4376c8bd463f5ed0e861f1b33c30e9c493e6e544b271bd89026edf3d94bd8672a4a64dd9fb0f2c27e23120279c00000000000000000000000000000000003e52b87815031c54f782777a42b3e7f5ff2bf87847d4c3c7734dc6f962e00202f9fcaf7907470dc5e631e0c9b997a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000169802dc492100fefc1058a40c669208fa771fd608608bd8d3eebaf4c6311feffa46d510ec400ae13b08637056e8a0d000000000000000000000000000000000690cd65076937b1c38e887a4a9526a79b67942297f4a53146c834fbe94ec6e6a393361fe90264ea3ac857ad5f43921b000000000000000000000000000000000e96678f6376db41792c9d97ff37479f1dca2ba363561cdcce41cb36353a378d7429588e6588adfdf4d2f0dc74b2945b000000000000000000000000000000000f1e9042941d5a0498758d1cc55914c29bb140129e1a1f1641be5c5b027634f7dce7db76426fbea9890a6fd62085356b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ff4096a7853a31be23cb3808f5338fbbf18db4a719d977e618410888f0d54efe51acf5fe4ec30f128807ae9d7c7fbf0000000000000000000000000000000003efe21c56f305ff3479e06231c54ea577185204731009ac3fd7ada0d71c5283d9408d4238c412cb753bef6b30d05bc20000000000000000000000000000000017c741481aa830cf2d7ee0ad2a137f3767a055318977dfbe45acd66f977959def711cbdf5e325ce6a3b27b8c2cf38dad000000000000000000000000000000001621907bc9e869fe938a37fe050fd5defb558fe760edc8fb2f91069612c284946f8e878b5b7b58a9a7c79ea3457bdc2f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1beb674ff1f0b97386fea532b49ce0daeab0eefecec2af119e16df7ce3e3eea7eba74ae5681720c3f154653fc416010000000000000000000000000000000008a333a20485201dcf576e1577f61e0f0cd979470f94888033b41d51bba9acfa34eb134852d9c6d1de948b1cbccf3308000000000000000000000000000000000399cfdc19a26417ef48665c98a2a4cb2da888f5a604026f8f807d7d852ce774e8c09b8005fd066b1a098ae123828771000000000000000000000000000000000f16207f9b7d25871d2d737bd63557d199e7280393a129ef6d021d1c5bac51d6c14e8898b058b84d259e89f8078ce71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000062b5555f2779d87d835b064616c117cdb46ddc254398ce913d0303a074d165738bc568f9c6522b8b92d7dac752d32a00000000000000000000000000000000132344bf1edd8092e41e9419ec846b9ba197a641068e4dd8f09c7ad9643c21312b6c4f5f95bb6fa002ae155ce76dfcf2000000000000000000000000000000001936e266066d85d12f7c7831c8f6401150ae2c6744a8d1883c374163af75abdc5bb666ac90945176558aee0586e7f9e9000000000000000000000000000000000ac8c26dd493caaa7b6f8777bf89306161a564d9f369a06aa808306ce49ae4ff2d571670c7dcfc1a17f8dad65d8aef651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174ed45b0721698524d545d3ffb91491dbc3a24011071142fadcf1fc0aebea354773ff6071b6e3432cdfe0d01626fffb0000000000000000000000000000000016a297df63a1f9af115382a9cdd33f52ae87b637ac23c13669ee583e42e3304ce26a517604d6eb5f3592bc1ee24103cf000000000000000000000000000000001558093984ba01c3c1d7eac62ef6de58e4c340f4268d388537e2de71ad6da16441618682fb114f7334937a79ecbde3bc00000000000000000000000000000000046adec995a961ba78d1355ac54942f48a2d040e86732b874e45cadd6dec8c97a72e180926c607d220d25f56f320b2551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a3992a2f7493af523a9b8b864333388d2b8990072b0cb927357d072609710d6c2c8ba8faa8d0144e44114a1ded2fa80000000000000000000000000000000007b27fcc27c82eba1e8898e176ce248771144f5b5f989b7cbf9a604e600bae6fde2df0b5bc580a2d8d0bed9a158426cf00000000000000000000000000000000004a58858b2bb28766b4d6c508b15a8294461f98f65b69f257caa6a2885ceaf6a8f69d59a194e8e375bfc2c280ee09cc000000000000000000000000000000000f891227e5d7d79913bdb80710c56ce1c96bff76a2caac15efaaded0386f828389a0d8102ad688e6150613ca35702d6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149853f23488e6b24c4890644d2563b758ca2fd7446069507f5aafc2552a73483b45867714c617ddeec85c085d5919f3000000000000000000000000000000000de47334e2540d9d0e37b9784a4f49cad9b0195c61648b9f6f7214ec3917388fb50cd5ab449ad999f2c92b6a10d559030000000000000000000000000000000015f00cda6697922aa399d0e1860df291a7cd7e417b7bd6a6e8a65ba585afae4f87bb7459de1cffa616be6f9779b9a66000000000000000000000000000000000083cc36154ec20b0b42a1731fafc41e6355a7ce70213914a0c355b064576fbdbe00fa2c626af089bdc9b9c3069f955801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009feec7f4021d9c295007f4dca44ca445c73700159b3f27a759edb0dd09d22856a43fe8a1c1d07629c901fcbe6ed7e010000000000000000000000000000000000f6880b5541c0443f8850b969c4bd280c450a1399b19e2c9c9fc30b13b9862806fdbf1c1bf81e172eb4ea443d5f9c9f0000000000000000000000000000000004f744cfe41d9c07c84da805be6fb0f40db2e26aba48e663db442f0083232b84984b26b27aa3dba491d30e6afc2ec298000000000000000000000000000000000732a3b254a5e2a9d660a196e1afd9e722675277bb4b79074745529410e0fc81581cda9bd0c839437a640a51b7dac4871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001848f8fb198eefa7378d3139ccce119ea9ba588d09c5bbe9782e4f88f996c20f325db0e1e02f24132be773ae7a963ef0000000000000000000000000000000000f8e7c9042b0ec43a0cdd9cc0d0e1a4f4ef9e8fdc891bb3b81d097e760d9e3048bcb342aabeffafeb00bf09207bae1b70000000000000000000000000000000005b323f1fa95529d82a4d458f60a534cac2eb934558a4011bd70a1844d9b82c21824d1e7718d7e93724c92b8b6190059000000000000000000000000000000000b36f327c85d4708708731906a2978ff213f724281a84f80310f113c2c06235a7ca22a185f0ff54de827ee3dbc6f04341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f9b83bf1a2b3f7715cbd6f9f89cef4da5c910e91d796515f92980133785726705175960ffcb84c88a3ccd6b48baeeb50000000000000000000000000000000006859ba4b78789a8cd11964b098dc8c60164977ba05fbd96994d7c3567acf1eb65157cb4c34ada4fc14ff865e5900bc00000000000000000000000000000000005190eeecaadaa56f976cfde4f7c686c1686f96026678554d653ce440f78384676a60413d1accc366281e68ce691fc3900000000000000000000000000000000124081bbade758746f7f76015f37d4eab59184d3c9f3171cc21686cdc2394471e820c2a763d6af6c52c46c0d9b4b6cc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f6ed89d26040c3bfcf2419ae9c9cd83149640ed66c18cac5fe774a15021df2c9257f7b9ca4a894755963e8c3296e67000000000000000000000000000000000d24f1e8d955eb6b4acf8f85a640779eab0e4449ef20a19f40cb20939f0e58821bac93a345be29ce35e8db31a500bcee000000000000000000000000000000001835835d74583072dc033dead2f95407e54d59164ea056ae8d97412db161ed221e2ae072cafb66a4d78f3f0f82eae0bd00000000000000000000000000000000010ec7d42aa2b58e37614308842682d3a069d772de4efa92a6b3858346193f9371e8c334be145c048f5e5330c55974b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003908992f3cb44bba40bef5f87edc157ed299aacef07be539fa78ebde15d1389ccdb32d377da24ff520984261ba5a13a00000000000000000000000000000000177ee731653245970aba6dc8d30dbda17f1a91466fab337a2472eb6303684c2a9df92e3d65fc73b51e2648368923f16c0000000000000000000000000000000008038c18d14f64c15e6f7f9fe259c549f44140b3a9ca19799b717e661975a31b9ce9471e28eb465ef20fb21c1be783a6000000000000000000000000000000000973e0946c2be86276e8df11f8bc0a42e61752f2ee408e2b0e8641a5b0827f360b0cc947db90beef51cf77619ed1e1d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001691677dae70cf2d936692499e9d4a71c4fbb18bf37cc257f76cb13f61e3917f5aac5650400e4a0fc69bc0c43c578eba00000000000000000000000000000000124c792d0920bf766a3291ff82424c2161e3a36285c0d7ad4673fe8b6757dfec41db4647bbe36b8c4b75878b0f6ac7f400000000000000000000000000000000086d048134090c7b521f713efc2c924153de75c6d5386f1a1e2f64018fb066207e9b6286713779c5867bd3773a31e22c000000000000000000000000000000000f566fd41c7d09b728f29a01730e06fce26039240c6cf6ed8e19af27a3add6aa934dc79bdb520bba6c3959c00e15ee571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bcad9a30a850e6127a0aff1742559d23dac3da340217d7e61abf76035fc8e4d42f3d4dd7501fbc511f3505f41052660000000000000000000000000000000010e1ef4952ec07f02fcf5cbcc0b61afc96da97b13b05ca378e486c7e43ac413c06153f8b528e0caa056f37c7d36c02b1000000000000000000000000000000000dcf74043cb3b1311c0f002e467e568d8e1eca2bd51680fc03e4c53ffc3c270fab376c9560582445ad708d1f33fdf7f10000000000000000000000000000000014453d3b080c057cd112b08f2b3caf148461c7ebb3674c14ba6b43e0a41ef04ed568be719175345bc884e867c411fb221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001769a225954c320889c1d762db2cdb782313e014539c69c220c756b1ec086f457807a2d88cbfc5fa8f69ae2c5579c668000000000000000000000000000000001290789de39019dba6084b3730da0ff035be2aa88aa9c314c87c963923fc90d9948991d7fa88fd02364685702f5fafe30000000000000000000000000000000004d3cd2d0f407d9659ad176606ee02064af373a9dbd46e9139d7dc1032dd1d8e408c4ad8a373d7680b87e6fdf944efdb000000000000000000000000000000000bcdc70c547abf66fa66276cac98b16bdf2c31627ca3cdf9e7631f5ac29b7de386aa5f3c94432cc99730f2effe581b851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060edef5431e31c1a3296a5b4a31435a10de20cc0d2ef1e041da56f92ea96180d72f72576213c63d6077432132ef1fff00000000000000000000000000000000145019348dff4d7cd9598e50e9771a4daf6831a6047ba406758be943d8a48e3c2301d7b0b4eb781f78b79ad7791205d50000000000000000000000000000000008a2d007c3e1637ef05893491fa77a3fec188fa73cb4b3090b8023ecbbd0956e0fb1b2e3a6f64e7ae4c2c16665f6d49d000000000000000000000000000000001262fbb56c9d23b2ff386d83ec24a702805d29a987c434e917d9840d0bb03f00464200c2bc291cafbc9e1f229aa348321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084fd881a84f4cfde6b04aea35235016bef0bb8ff307741a8cf5bda7727a3140cd54995efaaffce708a1f5900e74084600000000000000000000000000000000052b491d09383bc4a2dbda0d567086f78b64ac9c851a5845e474b884f54befa938e396d822fa23d2424c3340464471c000000000000000000000000000000000162370332c6f840baefcde9e4ae3dfbb19ca656d2e25c3b89b05ce2bb023f3daef25e99f62837157f6396709feb4b957000000000000000000000000000000000335a2a4e45bed5b0b14f3e02cdaf6990bedf08c8e50d3e7d0f77ab7cb400fe1641e27b4b805773a1298b005dae155601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000832626850b08f620edf4d26245246084b559da0a08594c2ba791fcd644ef74b984b8ae6c6774fde442ede4d7dc2ec61000000000000000000000000000000000dc369fa7327c040c5cd1df23cbcc608e3cec5714ceddf4fadd34424c0204a050de74e49ec0bb05a79946c19fbb63587000000000000000000000000000000000d3423b795953bbfa552165d1935173fddf8efe251c0f8df75da8f48242e5cd61d18a2f760500064a7418da6a2160ff3000000000000000000000000000000000ac01e53065c5e2e5ab865df80cb1a8af7db89241ecc8d235bb99eab0a085fdb3dad0d102ced54574df4be0a7abdbb2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c09cf2c96829b2b3970b3da4bf26de7201f264f7bf34d2c464b6f1fc7a43a4f9118672d87899160e34e8aec4d38f2c0000000000000000000000000000000019e32f7bb9eaea3f5ff3c0f3c05c862a4c0447765344b6583e6c1602615328754c373284e90658328e14df3b206fd0c00000000000000000000000000000000010296afde1bdb4547ab39b33a3d5bd13dd8669b35b5160c8d8a3b117987e02c1f8fe78927720eda1395ef2012bb107b3000000000000000000000000000000000ed73744daf4c697365ba066bdc52ea310e964f43a601687f93a83e03241bafd55b9c6bdddceb1c4eb92cf36eb7c5ffe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000da3b3e467719ac6846145579f4c1504267ff4f3c6d24f367e80ed4c6d30853c7829aadcbaedf94a5cfbf7ebecfdb755000000000000000000000000000000000a09cd8e7a9fa2b2eecf507f6555f01bc96c3d4855c82c0438da19437a52e2ecb6f8c8c212ba1de60b1de36642549f7e00000000000000000000000000000000140c29dce8df8b8f9ec681751aa9edda15020e64f80d6571f921ff82be8537b90f0aa3d26bfafeffe2c0e4968d0da9700000000000000000000000000000000003c7f14c2138ee4cab84bfdd13d7cb9da96ab0f64fc24f6bbbe1c89d0bde17f8eecd43dd3e1f32112741474a6b033aae", + "Name": "g2msm-28-jwasinger", + "Gas": 359100, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000aa48fafe78a2b4376a28048e4c4c1e12176f6c56103daa1606ab6202c8f4eb72ebf5fdf670585c9978e1e87edbac9ff0000000000000000000000000000000009d9deecd468891e55d5f1bfa6723336647cb41f625c3cb351043501b595db1ce4dc200c1db776b69aaad15477280b06000000000000000000000000000000000357229e56063b99ab7bfdac216c1fa7ee5e9f80818afd64ba4108f8ff2e372bddac1b2551ec05b7bd747d3e1364d1710000000000000000000000000000000007d4e5bda6d0f9164758e4fc3d3821fb3a8c0298aa99683cab239ff339b80013909819eeecbd5745c63741d06a7874871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001507090a640fa7d99fd8b208fa6d59aefd7de175d0673d419dc5ffacd857a74f55cb7376ddc6e811f45c8b5dffe7890600000000000000000000000000000000083f9e6c3f0f2430b597099e5267ed7ddea3c59cbeae2c4b4ee8cb2f80b1a82d29c0e2145c126c95998de937d3f1e9190000000000000000000000000000000007399f120fe005bd2b2c6abee1748e915d031311a4a52bbcfb59bac197fd7288c8d15c90167fcdce7b0da325f758ca480000000000000000000000000000000005b0ddd3ca56c70298b4f528d823325171057f4f3b4c9936d4f1a6553a6726a7f5690ac1b5abd07044bcf955b9c809501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016587812fb8963dff82325c7f05f5887ebfa57c57ed541f1c3975ebc6706b252b022e58c38fe1d129c710a627574a28a00000000000000000000000000000000171dccb6214661f66c8e36f1e54206a871fe316ec6fd3d495f2cbfe3404f46c9492edbaf0ded72cca404b82336e7c40600000000000000000000000000000000112f344b3ef0b3d5fcf1d5523bc8141965e0b38c59753d7be12c7d690b4fd7d36037fdd6ab4185c6b330a1d6b4a6516800000000000000000000000000000000083cb4eb6316f22ad5aabf052c5fc95ea61a51f68824f752c88629175cbb74be05db55600d16dc5fe314d1a8e0dfe91a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abd7cd92ecc3411b185d21213b4b3166421771ebc297c2a64b72f1038fb8b1a09dfea6fd9a2a011c0fe74de560308d300000000000000000000000000000000140ca465273d0e99428b79bbee4c8b447130ae4e4ebfd8b21e6f5a103497f23c566f77c4362bb94d061be15797d4e2090000000000000000000000000000000003e458704d3b65a6b5818e45003866a244e3dd15ffdfc305f513ed3c188e363519b6bc354e5218cf2348997b436668f9000000000000000000000000000000000b75ebe347b33a775afc9fec184387d05461f34fcaf45571fd62d119e7d767c7a268e8b3c81d97bdbe09bd516489752f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000829524bbf33e3e8f436de9779c236c0ea4004f339b75706f7fcb188c6f5b0e870292a725191bfe8adcefc0398cfda51000000000000000000000000000000000c34e44c99a5b962b64bbb0e9f270ab7a524ff6cc8af4606fcc71a600ad2ebf8cdb4b60083f264eb4e96d6c4dde7dc4400000000000000000000000000000000113f2713e356f55b4e0f246f94a28ebf8dcc4e71d069e5a4ef76ca34842704a109b7394a67c98334eafc5191e9c40ded000000000000000000000000000000000f1f106b73bd14746bac12561a70326690608e88a37a8091f7c137127de179b2b7923f6b6a1425272433cc96ecbc6e881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539b41e46f218081ec2a02e6f59aef7bdd3d050ddfd350a34561c1b5f00aac65c1386173f4702aa472e2293407650b500000000000000000000000000000000145e0084bb792c726fe629f488b5f7bc07e46f17234c42bdbbae979d333c916b46cec63f18c2e7a7bbb9d3ebc52c7f72000000000000000000000000000000000605c56237757b00f26ee97b2de1e2f5b55033a071ecda57abf247a57c5c2e8a57834331c450d2b7b89fc39716a47972000000000000000000000000000000000c8e2b97dab2733698b3720081bf4e772f0f9de54427ad6a871a37ea6c0d0ac404cdbd6480ffd483b3e1341510e9b4431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e2972abebdcff1cd356c5d60b0024c507a8693b8efd1949049e086d9a4230c418465546badd09992a690814f1ab9110000000000000000000000000000000003858d6c30c4a87b317b4bea982f4191a98850287745a0ab8e72c5e51570bd1cffb060f264baabeef454bc05075c2d550000000000000000000000000000000008fcd3871c10813e27b7c10b5aa7a2b5a829d0402536c4fe0b81c80f581b52cda68bf0f08dd79782d4e41268d6f840c8000000000000000000000000000000000bd97069ada3a0190cf7c9a55ec0e03ac9b3bbc9c71b349be528f8e87f638bdf8078fb373f4358acf136b642293c8dad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f87ab0a664060c237e8ab4dcf61d10ea8002331fde5edc04b72fda604fc4cf9befa9021ea7a1590d601e6ec27d9d990000000000000000000000000000000015b880f1312695ec797223d9aa08e63166b7d958f988ba70f8f39c003b5abcdf993aea7e580d70384434691a262959d00000000000000000000000000000000000da2f26350a8713b6361020a6ffbe60457c55b863179b4e8f38a66b935f45474de7365374360cd36d9a77349bccf91e000000000000000000000000000000000522c27225a640224b35c0ed856ef628ddd614d2085855d687058d132ec7c49a69d660e7899428344ab93318f54cd2331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011528cab84ba8758244c3e424cfc235fcbd04b22a59550e525281cce226572d6670a45d4181910a02c09092b3b4972a50000000000000000000000000000000006eb7deadf6e2c1e4c006f7d97cf17d818e7758ba5d40f840244cd1395aeb496fe78972035c366b2b2549e337b8b80af0000000000000000000000000000000012fb39dea4aab8dafee722c01aaac139e830c73c57dbbdf8ee17b151973cc88492ed9c39832e2be054c57d437ef55ecc00000000000000000000000000000000188c3dd0aaded2140f4d7d424479fb4e2eaa72499b10791b448cdc78c6309864102aed3239dd5d7cc80943cffc63bf841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175431f2468db8f49b52d5f691004084b75d7655f86785f0a829495f637d05377805394ba70653494c11b6c67a0601a20000000000000000000000000000000015a188d2333a58c2acdb9e30c437de9efe2b504b3dbff7a75d5d69b31ce22aa16f5be833bffec2734e29425a6650d64300000000000000000000000000000000121631e432a98f47b218643fa8f0231825df6de554c63711be0066d8359053dad766422471e8bfa2ba10e00b1c47a47e00000000000000000000000000000000001c5f2697a18d7d4b4d7c5a97c2108df05d1981ec9f5b4663f01d64bbac16aaac73d6740eaf7fc5cb0a8537b5d80e621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa6d2680a8ea7a149fc7895547aca4d27c83e032f4f4596c5723b1d731838c46c5d8be8f43dc2708da277b2563010510000000000000000000000000000000019bd4e3ba469faba7b4181b340457345eaf5926d79e5ccbd99b801897dadbfe881fde0de5335028828d920dbae86186900000000000000000000000000000000029d29427b363979a7f689f96e2cb698b031561520a18481ac3caf31eca411ccf853d44a3f04ac8a94072f84cec0a14500000000000000000000000000000000178198f30dc0c6b1f0e342b2730fe87198dc3c6d295edf3715ec690346a482ac7f60320a9271bac492b2a821b83ebea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002793b4dd7f29fdb3476f0f13a4a92376f88b0080d0cce6bf8a65973747314b19570df538a5e58206073d852453fa27b0000000000000000000000000000000008571739c098e0fee34025e3ee3868101a66b07fe19f0401c3b66ee1ae2a96e749977d67cffa2dee723ba01db0400d6500000000000000000000000000000000154e5a901b96124aeb581e239b4deb88f8b542e63edf24eccb907bdb874701dfdf99375848cca31b032e2f96547d322e00000000000000000000000000000000173149e0d6f1105894e59780019612636fd7ef4b448a471766f3acfc6caec551e3f8760a3bb65b423d1c79589f3561dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a19b65d380bf4e4956bd65a5839f71596ab2233adf1587eb4a60b2780fb28877843724845ac8065b1f74b616f678700000000000000000000000000000000063cefeb1291b32c8e45754c6aaa6c363bf06de7bc611f7a1b4927f4d17fbd8da2d939b17b2afaeed8c3d412129bb2b0000000000000000000000000000000001868356d5a51c3618b8280f01d5b7a36e74dc2cf4313a76c9579b90cae1b447d11f4a8bc3183e8938b95010141513118000000000000000000000000000000001299fdcc6953639c3bcb86fd256defbd9b278041f3f58671b02d561417fea98db8236022b1fc2bf5328d7f54699e489a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dbff820a219d9e74dd850fdc91c5a6b6ac4f18e3d2da9cdc06c1098c2bd7e4d23d33da731630eca9dbacd37cebc022000000000000000000000000000000000612f23323f8b468b2a5f8b222af056a4a4cb619e2045ff9572e13221928be2e961ec6bf08870dee81271566ee94a0ac000000000000000000000000000000000617f7aece41db9c7961f063e73ee8b6851a2e0f6bd3bebcfdf03d67e5cc8704433454afd862b7d1a13e8e5bca1ab5030000000000000000000000000000000017fa0bc3d544c0f299fb6ff83273ed28e918bb278726ec2aff725fd5a9b9ba1a16958911ed30249606d35af6f5925c8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c5c7cdf872a072005c11085c7990b78062e97d203763939b5bbde1b43021cf68dcd64260ebd95207d0428ddcd226eb0000000000000000000000000000000008e2c5d6b5261cce780717cc04945c6e6b0f056fd343140baf30fdf8d8e4c7fd0ce274c7761f1aa786b9797f63af931200000000000000000000000000000000008729e66b5f0040044489addc00ce4ed524bdadf835ca54da76ce447e6564e06278e4acc7b27f2ff95e9b5b51a119a20000000000000000000000000000000006dd04ccbb74b57fe14fa4d564ae16f7da40aebd9da05037145f1917e475a51784b8d7ac4ff7c54424c89886d193e9bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d88f718ca5e4bb66cf7cad1587cbe473be2c18c706d7bd3b5032fe38135db7b08df605a401918696d51054dedf3cc40000000000000000000000000000000017b644ac7b6e6fb8468eaddb8bfe45d65511588bbea98e5381cfcf7fafa4a25d727fc7437a0af08e4d50663bb29060b30000000000000000000000000000000007edacbc4649823b8bb1ef798d4d3842fd5b451933a92b1184a5d78c8415714a36cd446bceefc23213481d2495690561000000000000000000000000000000000ff036a27d6c0ab6a2930dbfd99fa7349d45354823b95e097a97f78a82092afcfd61d6550a4dea0012b7a1316653c02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001313459c3a16c613f2b60d84103b35b34bf1c16a03f5bc24bc2f26953884e2d40a47f10487dc45ac531eae33d35b4795000000000000000000000000000000000ce4f22668073da84dcfddfc892056ab6b20ec2c7dda4ac7b3c7cf5423e7ea59d07a6a7516bfb9c2f8dfae876f94e9e30000000000000000000000000000000007946a3dc57a0fc19ceafc7429e4460f04e98a935c373223cb1dfa6758cb336d2d17bb2484546783f082301a566725790000000000000000000000000000000012a548ad8c81060a43ab54e482b9f7c54cfb63d62e30b94bae95912231ad74f04a03d47d0f33d2ff5d21e41db537f4be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bd994e7e4cef99edb0d02fe1330faae8bae8d19bf6ede6c21c1908018b887eb654392e5e10231c297850cdedcbdb83000000000000000000000000000000000b27c5be6e5087fa9fa84600a13f676d185102b8138326fc7aadad39079f4cd276711c033bd90117e9ac81824a1b54df00000000000000000000000000000000002d22fa29a3b931bb38c61765b093f3c9692a9b3b1967dcee90f669142ff5410e8880c5a52a2e558de01281a8dcb24900000000000000000000000000000000137bf2290e637aed7d8934f97cf8eb4278c8697b7736fefcff8b738a54e8f340ddc426c113dca5812680cf901aa73f4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000887db81443eede54af3efdb3bca266929ddc9e9a43a120642033f929912d34ae60a9eb88e0ef03e338f49235403148d0000000000000000000000000000000002aa770576dc800b4c5316042c809f3b6f4d24a6c0f646a65b7ef163ba4930a590f361ab9ba5bd0c85625bf120e64f4f000000000000000000000000000000000144e9b78e3d876551d5733cd1df770f74eb23fab0c4505f7904129a39cf82e0323a2ea27174f1eb98f69a40dea6ade2000000000000000000000000000000000f2042a342232e512fb77ffe9c73751a789d79eefd89c2b4d20a2bffabc421a05d3e935c038fc99b20dc38654f4bba4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fb52d54a514106d10da8b316729a1af301be2ac319dd66c5cb6c0749c624f5c91106e8d42b88f26320598db46edcac000000000000000000000000000000001373329f07b87be139bc5a2f245a522f66081e79d9df80659b582649976d1b036fbf078e9056ab416fae5acea3ffc3f000000000000000000000000000000000160770d40d555dc2ba7563a54be90552411400a0425f9876420665b38d269a202d6926bfb08e5a343a2d32611a9657790000000000000000000000000000000000a4fc529f6ce817d254934d9160be43c28090f01c21a46b9d8a343b945f13a6054b3251f20a8be03eed7952f085f9401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199a57a493b04e40814c9a844de681414df247f5ecb879c495e3f5d01a4fb97beff515ce3d717b6d5c560c190132026400000000000000000000000000000000083c6c6d678aca761f4389324e72cb884c695fba93a992c55e6282e7f57e36616dbe6f0922a1532277637dc76ada322d000000000000000000000000000000000e340e248005b2be75cd19ae8ba96aff10541e70b2d8597c3cec1d00a89f7242bd4cbac0888293f182cbcc00db65fb33000000000000000000000000000000001513bada8318b97a8be4a26394f3f11748ef75fbe438f76573a371260e5359c3f711c45392085777d29e94c9d7a923701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009217278e4ebef81fd3579d265c30d086b782240f14966589992fa8d64f5f2508504db8fb07ffa70f0c0adcd7a42e8360000000000000000000000000000000011f8d5fd83554d971f39fa2fb518733834be58812f3dad21eabca81de0110ca36f9c15eabf4d013a9c7724a552a0dd50000000000000000000000000000000000306260b94b2c4b5461c932ad85a7d7dae1fe6dad06460b71562a08004988fc9e529813aa09c15c6b6f77dfca7e8045100000000000000000000000000000000023145d719e21530f2ead68f799cf2b2970a6bfcbe23d3880e7f1ec8188736884c2e0f21ee1b4b374c3df11268cf2d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001576a4966ac550a5d8bf6024dd2043a71485f9d43e000092a1a06efd63c6e8278ad29c38de54812497ee7fd1af8d83dd0000000000000000000000000000000004c1111a2b00edd4fb0f39be5b576942eee469d37f7b21a523567ac2450846d743291d3bc48e1660600c33c78e3564d9000000000000000000000000000000000e0e76855fe748d3b4f9f2ab7fc41bd52714c446b4a663e849def5e279c6cfcf8d29c0e18dfc4c45437ba94bfbb761c900000000000000000000000000000000102d7d4ec73b871ff72406acc945d6fb7dc2ab4316942b235b0be1a02f97d973e75d0a1e55478f21ccc52a568f3223f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193c1e99ed56aec7f1b168bd7aa359bbdcb2fcd92d918eea303451b639ceb00a32640b44e06d960c146bad59929c90da000000000000000000000000000000000b5d12e7c8db75ca0ac748d5662a4263cd420eb9a32beac5650249b357b9197ee3eed6254bd4a0820011a2af4730b7e20000000000000000000000000000000007a63603bd9f94ab8250c4582429a0cb63d4056f6c49aa018868c40b8595c1af28e66634970354a10f5bafec32552955000000000000000000000000000000001419ac2ffe8fa879eca99a745fe41f215fe61e8dcd5d882ba4a836ccb29c70ecd3489a25be6be7752f244a9f73197a4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e8065d43f90763d365a9ce2ee22a4788011b10cb824886d068dfc3a17177b79910464569bbf41cd66cfaca010c4af200000000000000000000000000000000002fdca6495ac5f397ac17143d39d3d1788471621b54b40441a3ba1cb28dff1b993021089bf71adb661b1521678c17d80000000000000000000000000000000018a62f766a85f8578cca1897ed333d3ece770d10c800c0a65d6412d6ba0febfa495435a270eef1d0f83e05329df1094c0000000000000000000000000000000011f3e53424a279d71674626e26f139367761ecadd085c4941ec45b8d90e25581617a00ca13896cf499dd99d7b223bac51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015564d15414b53e91b52f86bafe8028653125e789fdefe2f88ff0593bc9eea73cc6d76f258a1663ff8704aecd67f16b1000000000000000000000000000000000e3697eb5a8e6c8db1c0ad2caf34267a4fa4d04e919c7b833536a2bb62096edc9ad82d564badd5f52da138fa3db8d43a0000000000000000000000000000000010f6c326a779811325392eaf53be300ae140f35655d53a5f0b69f1492ee4d8dc2b6ce9296fc269b03e9eb555d69b8f420000000000000000000000000000000017d57fb2cc15b838e55318e7d46202ede40ef5cc05e4dc8469135b96479d201bcf72fc6ce37aea70286354f1ba08f5ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fbf328148f76bbae0b3ed2272cbb5233d58b09da8061b720de301a4f35b4a4ee8ae8e97d0126558861741a060bebdde00000000000000000000000000000000120ca59a1dfed010d8edd6d45a5e6aaabcb146c8a1d969f0c673984ba08657d49bde5f673a136b6f792894cf7c3440dc0000000000000000000000000000000006d2d5726ffb08fb2b7c28079f652c551bb298779165bf1762b674f737a27186860e8f411fd5d985f01377c3b2b6477a00000000000000000000000000000000127a99bafb47777b4fb7ecdded23b54eec37383d5943c06c74812c73458bf2ff6a7bb48142489fdfe21ddf35567d51a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6ab8b871dad2ea46d271be5290d1815a7c412c400abccd177db6b31c8f143c7e9c3c618682c6254184438f77d4e035000000000000000000000000000000000ecfee9da433ed8ea9dac251f73d92a19fe25faae8b3b328efea227de7ab405652f1f62f720916096dff6ff78edef9270000000000000000000000000000000016463b46d87866de38dda7008c70ae2cdb7bb9d30c08dabca4218633f396b81d70dab5a621a79f10640a4fcdcedf251e0000000000000000000000000000000001a323dca99ef212926bba5043689788a4b666acc6cfcc3610fba1ebd4d09d37b0692839dcc85d202236252ecde751e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000038efc596eebb9d84bd941e08c79868525d8d384075e7c9c7be206c191f397c6b64a305f89e4818e36f87dbe11b67ffe0000000000000000000000000000000008f928a5d9986521766b72f15fb235850f5213e2fa85a4eea57ea040c0669bd097e291ab87983049a3122756fcd1db5f000000000000000000000000000000000d7b0918dadcef8419d6baf0ad897c976e8355098ba679ec32405d153abdad29f4288e5d36da4d6c94ef1ec13b4fc1d2000000000000000000000000000000001251840c738bd99f1a52f65d9e7d60b3b303379227773e5c2bfd7ee720c62fe8756c58d6506af3ffcc0fce5102a3dcb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000148142228d70d5530cb6e4b5d9f1cf8b9e3a5f589c04eb17254d12477ccd77fa44a4bc38cbe28927303c50ca98cfe44f0000000000000000000000000000000016f448dfa986ce9f305223d47e5bace1e29e481299892c90c5ed8cbc1456179029b06c4124f1c5f42a5cbf426b632866000000000000000000000000000000000d8d49a7ea64ed2e965181cd52e1d73a0b118543db26363eb8c8e29e50f14fd69fb01ddee38ed91f28cfc3ba16656182000000000000000000000000000000000ce5f7aab86a9c402ead61a6d2bd0a578d80868bd643b002c6e7116662f9dd244f213753fb38a634a591aeee8cdc4384", + "Name": "g2msm-29-jwasinger", + "Gas": 366705, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000001843fba3fafb6163d2d6f44be87432830a0c3ffc97674301e63daa5bc30f624b619330016fd5d3b25ff1089180b0911d000000000000000000000000000000000523cea9d2c4a053a5711ad24bb4f93c25c5abc6c3b0fdadffb63029a67abce0406b3dd65bdd41d4e65a10d126d9d4ae000000000000000000000000000000000d5a3e2285919253a4771da89c36272483411f35d7d29722889cb5e59d2fb9dc1a9b0ba74ab100aafcef4519bbaa154a000000000000000000000000000000000c460f2632b593f9f46bbf6151d92b9d90c67b95ca011f33a845afa8d182be74cf5e7cd83c21ac1e95b0a65ab79d0e921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130e1c30240f14c9ad3101094c88d52b364dcd4e3562df00a0574564f6ac25bf7e26bdd182f9606ee1bd781425a1b7e60000000000000000000000000000000010ecf8ff470563d180622842b4cc4fa073c6e83aed8899ad2d78a542734a31002d9120808f219944b59a50306537ab32000000000000000000000000000000000ea41ded7e4077bb6339e54b5ee6cb498a8fa3fffd704e55d7fc74c9cd5785b53183ee9302c140866d12bd59283a38aa000000000000000000000000000000000ff41ad8bc71519dc5582c7d73912fa3c803727e229e9182e331ff0d4cbd492ff7c71b3b0a4c03f44563a7c53bc0c13f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb7973898106279b32fa8794081bad3260eeb70461a316052c97676f85b11d1fd427b09b4f5d07921182a26745cd9a0000000000000000000000000000000007eb11ba3141550bd52f28f0f71d9a0eb4416dfdf007de21972ffed256de46def48221b8036449711ff531c8d4cd7aef00000000000000000000000000000000122e123e1bf9949f4ab82c9b6297f9ea510aa1179bc5c04d8026eb5f928a791d5900dfa296e45c21a3db278117ac0842000000000000000000000000000000000a195a6529a4baff5a4e300f31633a122cee97e5eec417cdeb5cd5cf2d5d38f2dade528304bf17e6c46da23fcf9c4f211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002663204ec5b181046b80ea44b88ca0576b090b99b44aab4e9142f51594e92b064ba4c4e1bbd2e624df87164d4132a7500000000000000000000000000000000158d39819e15d6caa9727efbcd86449a48f9e240b8eecc7da9ede44762ffa7366811d09edaf435589258a6031416afa900000000000000000000000000000000052a0c049a806fde78229535b730ee06ce511590c887c331c7e1f389dccb49890eb523bfa6be7670f4a4b9f91c3b0c1c0000000000000000000000000000000003a59518ee1fd48dd11a6b69fe3a791da090d51e68c56db675c0b305f5545801aa814f6029e7b15e51d6f38fe2cae24c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d6d0239cd85c5c7b666294fb673a1ab92dc54059dee72f58127324dd0084d9da277ab9c75ef2b3b1c18f564f20ae66000000000000000000000000000000000fa6b340557c8d513832a58ac7254b46ec6f13579f0f76a241ac767496812b8899b5fe68e969ec22d7edad56d07cdb07000000000000000000000000000000000e67e6469a5fc08eabefcf2b4dec7da375cfda17efd21253e5f09adb6258c1bbfae1f9160cfc70698b27aebd2d0012390000000000000000000000000000000008a907f0f5438cf58308780265f215f9661c6bc18f9d6891dfa27953f39cbdf9aa2dbac8efd1890ec0aae51739ddf9031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144a68ac59c084d38dab96b5f7faaadb642d53af5413f369b340c15e292448dbb6f504e95a26696d9ccd32f65437021800000000000000000000000000000000104824e1cf15d29c96954b6808816412898c88cb5d11bf08ffb718f9df7a2299d5f9dbe287007d51bb7d973995031ffb000000000000000000000000000000000826b9acc6109a8000ed2627f7b57512a2258c94fbce7cb7b3b4bcd0ad71fc48518494fac9c2c018d8767830c1e611e6000000000000000000000000000000000aabbe550a2147973080cfa0219a5926aad45e10b912b651ac03865f4db8a515f162cb5434b4c563441f741be786cadd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6b1f70807ca67555ce9ca2970b715690d87b23ef0b76f20fbfc3779fd1c30cb3d6b259790514ef67024832e7a746c00000000000000000000000000000000005fe5649ded30720a66faa746f44dad689ee39ec0a0ca45effa0c82bb18bef9601b36b352a40baab6ac774f0ec3ab3a500000000000000000000000000000000194859fec7c6fc72215e641b079e75671d2cd85647cf646ef53bf89d0702acdae542a94ea81e800540d3aded7527a7310000000000000000000000000000000007f85d918a78589754bc8eb9e2e7234e7fb7e2bd3d3addbe76e76884e926dc6f796743f8973a44539b7b999ab3fd85eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163873a4a926cdd600d72e98abd92c702fad8b8a09a88d8c967eebe2e38799de75d72d20ca3886bdb8b4cefe0d2af5e1000000000000000000000000000000001100cb70b45ec19cb3dceb7d0859a2aaf9ace57c7365f9a8d5076824b93925e999a465316e776be16c96857260d01bfb0000000000000000000000000000000016ad120eecbd21d1898e4906e421bc737f24c27bf86572796ed9bd87928ec9bf764a8fe739392f5ba3c9af285f07e60f00000000000000000000000000000000194dbe8faad718436fb8b711701c707c8df619b53a03e809f6f6e258f3e963e3a0dcca644dbf41ae1a9e0a435783757d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd7f3a59b80f50b8b00c5bde398ce1895a3a39a008bd637ad51ffdce62e40051f1dca8dce99a393528286ec78e3445f00000000000000000000000000000000108ff554e46fb6dfa1be318919f2c0e2fe7c89d9a64c46f356e50c021a0aafa1641038a4ae18de62533dc6eaf548689c00000000000000000000000000000000050f861a6a6ae79cfb2ee14a70cd20324d64051c2771197fcb0e0df0a4be9e8b075a58ed81d330b605bf29bb728aaede0000000000000000000000000000000003c1e1f3ee9d9b1ccdd1bc7d3f82e0e9054c84dd522958f9c8fa7ef480a42ced10022b1ec21328e83845439dd8577fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b788b2134d0b2f7ac2bc676c2acaf9ef949913aef81770ae4c058eef26d7d1228164feb78ee8d1b56921d1dd80a77a000000000000000000000000000000000976417866e74d5058419e616560038229db329d12959d5d38843051e7f2924495bad8e9c5f03a7a94d16da290762dde00000000000000000000000000000000101cb024fbb74e39c4a608f593dd1e3c52d08be36a8795a34e52c7ac8569a2e8469fbd5b962518f3cd27e46b01664a1f000000000000000000000000000000001706d4f03160a84dd89be4db244646eae56373a614e92f7323ec55fb57d7bb4d34ddcf1de3afdbee1d4606ff5f88fad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001533fc6f0d483320f6724b8a1710891ad1d7a49e740f32a53ac86996439b4ba306f0594850c82f9837da589c51bac1190000000000000000000000000000000013703a221a1328cab98f3080687dd0452531bb5202413b3763cda20b2e1e313b99cc616f9ce8092d62c8581017323ec2000000000000000000000000000000001583d535bf030af9545ae68d0607488bf68ccddd54692fd699aeb1194fdb0d59aad7c9273bf62a8a6625b87fa37ae0f300000000000000000000000000000000089f5b7c7d6fb9779f12dffa3c4ff7a565ba7a92b0b9f9944cfa29fb3b6f083f16fb6bf3ecd50a237f26b28221df3c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001346f358d75792dff013837c8175f2396c77207b6065c7810a9d7e3688d7d6b00e0b0aaf9d2ee204302859f857e68a4f00000000000000000000000000000000102d012929c79dafc43d2755091a81742276156d354f28ae8d0cf110b0a6404093b6cb2fa78788435b27a9de0763da2600000000000000000000000000000000176c297a742c3fc9fa766445ff945480f580f2049795d5043075289e05a6e395a056ea7b1b54d68fec03edbd281fcee5000000000000000000000000000000000f946c72debaf9ea49e336a43ee0c71c52ab5e273000d786f8d1303e94f30fc3a949d03708257811e06778424bc667211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001787a88e5237c4b918bc1e2a9ddc0c2490d97d4099586c87d49d1a0943503d3ef00ecd068517510a8a5a29809ff630040000000000000000000000000000000007e47859b162e5b13c4d5be78cab0671e4be52446cb29831152b44d4bfff567be2c8bea91ee053d022461f1221c47f1400000000000000000000000000000000096299d93953280d1efd447427f758b5ff7d2fb8ca4f32dff24671633040be456984585d963dde42afb02c444610e73e0000000000000000000000000000000019d947ed09cdd3e5638653fba5c27bac4c7f65626ebb8f6930c0e6ad5d0fd9522ed6b3341593eeb1f5828cb9536a4af91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5a990f728f2f819e364116b77dc29a07a8f31850c1a4cf9a9e915f376828fb552e69e47582f1fce16d6aa55e489aca00000000000000000000000000000000192616c750b9aa9b3f59c17c061cd9823e15bc13958150fb4e738e118f31c1a85cfde10625628da689a0b8a186219273000000000000000000000000000000000cc9df7c72e928cef3fd126ab0689a215d5120624b1e7a872d75d6bfecc113f2ee46027f884d953e8b87bc3f6a747227000000000000000000000000000000000737e28f65ca6e0441a15397e426fbe1a74c459eec561a66049a73ade79eae91aaa6e58b3436285e9dd1f644d0066f061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005646eef0273cc59407ce4c434b4355bb20afecd151e62de8f0de271a8f26ddf0e35b1e23bf206bf815db4cf1aff3bd1000000000000000000000000000000000ab2861a429c5f7205931e3448d8f8aec01b85709f7ffe5ff64b00e2c0ead637df4edb1130f183aed1724f96eef5c6cf0000000000000000000000000000000004d29d7eae734c9de809a505c32444c1f61584a0dabb9ba85773b1a631f8b3e96270b9f7e07e1a1a6f84e6c8d23ca57a000000000000000000000000000000000f329426296056160ba748d6be674ddd1038836a5b581efdc3cf2bcaf558ddb7226b5f595ecff119c01515f68b68a3d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004201010a93c7e5b284db0fb34473f774c6b81c0b819f2c9383c4038f747ba48970520e327d351e2a0f89c0c20d0479e00000000000000000000000000000000101c8a81ff3f734924362ea64c95779d698eee63f1d7b954d570f7532bba45d759e0e0665e737f47b292d31ffd7ab65b000000000000000000000000000000001395e3a216e5e64fbb24e7396a36c14838b46ecb62caae32ef2b39126d3280aba54614dcc41ebe5b91de8dab918da085000000000000000000000000000000000469c734608c7066224816adde8b65b53647f36d5429b3bd23d2448a2cc6b04c93675e1a14a30b2c4a207a939ba73c061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ec79483d7421ad9806f7ec1bf1aa860c2aaac94c9eb0ae876f4c8296ddbe532b44b2a3af39eb976c160445ee6308cc0000000000000000000000000000000000ddb1749fe901d7a3b21248afd78c311f8ba04d1d7096efa85dd5e1d4d3e441d840bbc9a5deaf81d9035fd89f7b2cea000000000000000000000000000000000fc7be1a4872e0fdd4eeab5d1a42258a86e367c7fe146e07e0e740bf9f1ef741de892c21fcf4c018cf6876f5b775e272000000000000000000000000000000000b674bd417ba339d0dde56f3338674edc8aa212b405737c81109783455b1970c1fdb8b0db4609c5bfa8db9f8f4e3cbe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001157fd9c45c95da07d1df13a04b604f026e77d68d3df4b5f5522d24a647a157e99a545f70eb890f158e43564b1a266c7000000000000000000000000000000000a31b41affc520d7ac293735bdf8ec7f8e68ef9619bde73fa49476e727e01a89d6e510e6f68e3e759044e0977c3f1a77000000000000000000000000000000001076fc06ecf326d07aaf682e1a295a6622b982f350ed995faf270e60a438b1b0cbdac1dcbdbe0ff90ba8ad77f1d7ffa10000000000000000000000000000000002927b28470b7f95582253706eeca812af425245eb6920f3da6bd73083c5f47a3ce8058e9e05863c2aa6593041b3861f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001470166a197924188838eea04ec227248cde42e72530ca83d77166c0ff91b41edb78dbdef084d7203e29d39f3aa97df7000000000000000000000000000000001227880b3903da9e50b6d3b6102e5602b520ae6ed27030140d159e30e6f9050ab3d93ac1d4d91f8f4ae7528ba1a7fe6c00000000000000000000000000000000018b1e4f7d81dd63718a302ea537a87ae033c792157d5bfc13cd25f605662982448c88ddef48a063d2d8bb72af3d15730000000000000000000000000000000007074d5efd2f6dd3262421185e24eb1d023410c4162c5c6696c4b8795d4663674f395d0e02aefc4597cd6a453ec86bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f80ebca2d855537542705c2915662052719f898bbd507b590888026d79d3fd17bbd6589c288f3fe5be6d2cb971e6130000000000000000000000000000000019b9be8fad1557e6a590bab42fd41e1a5d633113f7241c34f90d36298f66ef2cd2169153605ebb7d8e32bd22da8cbe0e00000000000000000000000000000000142073e8509fc0c1dae760f9daa3d98396cd3a101c1bf9e88884ba9febdbf12ca23c13d238ee8fd116dcdcd2be0c826100000000000000000000000000000000095786cb4075df368d450d4f18756a8ad38e69ca43c81b7031c337ed5c0cdac9e5ea263a9c47b28232604a4e51ad4df41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012861d7a0b8f9488f514dab456d2c155666c3caa5a1d824403d4c26b2c9570713924fa714d46c83a1eee6dbb6995d69400000000000000000000000000000000037afe3789bef1c203d2fed1d093d2faa1efc15a5f8498610082392cebcc08550a3584406dfd5c7b28f39beaefc9d9830000000000000000000000000000000013c45a37b2675bb887bf246bc82f8e28c0e4e52cfc02d6933f80240f6bfc70977732781a7084e3c350a59f7d1c41ec16000000000000000000000000000000001622651600b43e59a811a132218d9a3e40b1027d597eaebf047b381ba666470c74de071615b75d15d55386598ecb7b4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aa74edf17ec4dbd09b27b87b9b7208c7beaf78f5e7644b51b8db62cfb78eae71cf03ee1e1c48c89835ae269ef206d800000000000000000000000000000000136eef36ee12581357f142f5de9ba449b93ebc6b784200296bbee002cf6f890f7b1f24b79e96fc48b161360a08bc5d610000000000000000000000000000000002ffe16cb6282768d13fd7fca6ea1724f2bc79e5a06d87afa14ad2b16cabfbc67edceb7b801120fe5cc3da787b3125f70000000000000000000000000000000012ad65ae5abf06cee0d290e631cac315eabaa449a22cf439434993cf1e3d0c777b2ddebaafcb3f066948bde0cdbc663c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f43a66daccedc45649ccaf0a8c7541f2bc4b36fa0c2839497d1b5428a3aaafcc5f63aebe3ecbba79bf6c3e2919918de00000000000000000000000000000000115249380550352bcb74aec2598f89186eeace342f91e40a2ccac444f51dbf6f2e2873c847869b897628eb51f2d4b80200000000000000000000000000000000057524a376cd560ef8c4bfdc14f447caef9c3bca9604333aa91a83b4a82661ea177071a4eacb42bfcabd00378bc4d5c80000000000000000000000000000000012b1622aa90a0e2f8153707556a0d754c58b63747a9a3c9c6fd92353b4bbd3a7033177d261caba53f04b011f69b6f39d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b68a1d5ac080c24e1abd5795f2f95fb588f4195527d2527985ccb6b0a0e13c2e8248ffe217711fc441cc5cbac8eed20000000000000000000000000000000015474001a7826e8c308c8730d9e9c7d1e72f20a1f810788d7a6f4f5f26f09aec5d6fc5964c0ea721992bb0d7be559f7400000000000000000000000000000000129ff9f9709d7a4810a0f897164e7fb83d5ea5bf5cfea1e110563e74cbc6df57ba7bf9cba37d4b42105d53a4600bf6f40000000000000000000000000000000018331a163cae4ad3ee137db5ba17268ada85814e0c431f14678679e5e903a9507d9fb9d081f1cc740855ba04ee97a6d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012915ec653a9ce0e0ec7062b3dc72d685e9c89382735016f65ee43e2750835da61584cbf3e7c594c391f6f52195c6a25000000000000000000000000000000001222c5f0fc72e6ad7b725abdc45874524d2bdf3dc2dff2788e04a0c671b1673fe922c90b9c69bdb287eb23ea4d30510100000000000000000000000000000000043f665bd1371cb2cf63d4ec877d80c8bf9a8e5ba08d5e997369d16524a069fb6883b651f8b29f29d56e8683018c27a50000000000000000000000000000000018a654747706b458a8acb41a3a5c9317c4856f47f051e623df2ce9ddab2224f53ecd65583d5f712c8e4608a8cdc08e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055460d8cf2dcbd9467091e632576c45d14225827e27f2693048885094876ac159b01c15fdfa09deec7a0bdeb974d8d40000000000000000000000000000000016b69aade8a21ca56679366b0375c659f38f51008705a4dd73cb85e44c60133c8a928e3e173aa479972f0c15668eb325000000000000000000000000000000000d8a7c3dd7c7ddd6a8f9750fce895bc6a691ce7648fe7aac5abb68969b693eb9b09dab946bd87f9c121171a6e940d542000000000000000000000000000000000b24b366729449d2784fed14b74646c53b909065b29407e3ecf04cbd442592ebd00bfff6acad8c0460befbc7e3dc93001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae220041fc997adffdbb1c1798faca8ef4a3fa72e45fb2bcad05af58bdba057460563aa39d98aa640a11c4aca4ad7930000000000000000000000000000000016a37a5d7f6c0adacba400db65fd4dc1d1e3c32c5a0b157663ea2d9366634e8249b9c0254904427aaef27ec6f58abc83000000000000000000000000000000001354ca37859865ab93fa9ca8ad87fb5b48bb258fe5d31475bc269ec7690fae75c0acf1b18d072e6762d11afa9c13805d0000000000000000000000000000000012f08b54b97e74929f00c0dab3bbfe8133b213edbe641531b01899602d05ff79b3f92f20dafccef0321d9b0fe66b39201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d982372cde62abdc22230a921b05da1e0ca46c057ccba726cd08f1a4ad5d0a45f96db343277b5b24f7a9b1b3f8960490000000000000000000000000000000014d64115525a788139d4cd205f925cbcf6b06781d07e388d91d4ed79a0c76c5c075fbc77bf67c9114263e259589bb0e500000000000000000000000000000000184a80d3ead2a24883117724db5d5cee06351ce180465f8234d85467808d7e0b167efcba5526f50c5577014109859ad4000000000000000000000000000000000b43df100affc20ee26bca4b9f7f28d9dd1ca1451d2847dcaefd131bfa8ee3eeb27d1e49acdf6793f8de21841c1368821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008edf51d1538088179b0da3a42a9fbadc107b7667cdcace78bbe4fb65d3f12e10b7d60fdfbe436bee13ed51489f253290000000000000000000000000000000013525950b14e9b0bc8a6e87889f917e011359b05107cbfc10c9b2b9e5b351e8a89fcb2457575d3f4041051eadfe70c3a00000000000000000000000000000000011947ee7298b45484eeb476389378240e6b717940005865c226cd2b8a354424ec4995e8e8b5e73134bf5890f62ab8330000000000000000000000000000000002d0b54ff8eca3a8664e233a9d2d345cf537b853fa7a59cb4790dec7ab5a802b7b47acc8d3ec503ebf690d247c73aa9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32b8543154a1af01763f4a8315337670d6bfc96392231fbbc7785489432accc1e59d245538bb9d6636ad54962ee5a40000000000000000000000000000000002c2d62de6b255d663f148f8127425bb1be774cf6cac7d7031b10965085fbfb5a4df1ee9c16887ca174fddee005d8366000000000000000000000000000000000efe96a0b3791b046666b2ea5fd4dc8ca2b32bfdd53d022f6d20a6f5a8ee21d69b7b2ee30e1290ac6870dc686008f29a000000000000000000000000000000000572c70eb109894c77e56556be9cf7e4c3fadcdb08b37d68b2b8cfdf82df3dd4351fa056a258bb008b096ea4de99d8641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000013fe2dc53b7954a55cc04fa0956a88afee09015466cc7f06f0bc0d7311775fa9f664c41532a38c26c70e5ed1498dca1c0000000000000000000000000000000002d3746c037827c9026557a38f9bdc1ad421a52230582850429e9b019dd0f4c53a47a2dac14950e7e1a5a69a45ee1b8b00000000000000000000000000000000036223c9518efafaaf8cbfdd21d6b2e347e77ec9f6d4b123ba4928b335ada4298bf5c6f8bfb513ec5f98f4832d97f7d300000000000000000000000000000000148863742ca4fcab2b49929f9628a088c9c67343cc78558598c770eb3c8bb355c52e8f4e10899eee16c23a052a6b0f29", + "Name": "g2msm-30-jwasinger", + "Gas": 373950, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000011fe294de63c0370fc14599ad86839dab91487c8fb4ca8fa3d4e2c5ec7cb0581ed5a963aa4a5ccc1f4d73cc2e45763720000000000000000000000000000000011108c53295a1c34595fbfdd24437dfaa9595e77cc46b828c3a28e4f6974297f18c6381e35c092943839ba327d91b529000000000000000000000000000000000c0cf7592723172d94e9226659032fb0d603af2769fdd97f41094bb41e375975f564040d9be764ff15c2655a0b495735000000000000000000000000000000001342dffeb8ff7daed381e8f3096651fd2fe6faf43bba2eb83d776660fea50f13546576a1fe5cd40d444458979ef61db81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169ab77f5f817e1b7af302d857f0399af06577e10ecdf005cd46b000acd15ff7682f5e1673b6e9fe0fb560ffe1a5af1800000000000000000000000000000000100d5f6162d969466851f26e2e0e362f8d7982863f4ddaa4542ac02e7574cc062b3cab0081c6debf6c0e3b0bb4432b04000000000000000000000000000000001774aaee8665b850b3e5cb57603bf36238b46268fdc00d92215e561c93027161c292d80906de78f473ab5205d7cd41470000000000000000000000000000000011d078f58850cedc57fae057f929e456fb7495a523802bc3a18c18cfe476b7061686231c26f7c0e3ec9f7bc2750d20fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071567180e848385f452f184c508777dc547d55069b3d1001b41c6ba5d2ee9340d8cba37fc8d09fe07098a52e32fec0700000000000000000000000000000000054cd3957217fbaf0e63e376b1c79a50538332bc65906319b2fb2e59f6eef9e772aaad85845661cb88b5de08f3d23ac9000000000000000000000000000000000495a7fcdc1f9abaa599f70d17c1c73386c89ad2de8bd84931b87e96f67e1696bb82ab522a6569e3174dbfb3867698f1000000000000000000000000000000000c27d5b85d3c14ab4f0520009af609b18b87bc6963a97a46428261346741b8bd750e573c80fe3838c420e8e234104c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8de7ab91b842c2e247bcb5078004264877aeb04d726c536fed17956fb5ca4def676b7b6a20f105970dbdf518fd9f7800000000000000000000000000000000049d68f46e7bb4d23a5891af9812ff534da4f7a3fb7d7a703bba82ce7ba1bcdbdafca2cf3651e1273c10a7ce39eae49100000000000000000000000000000000145467ec4f02eaef135691c38eac8123a86f47dcbf5078346ab230511ddd94622263bf136db41144b663355cbdaaff4c00000000000000000000000000000000066158ac9a239bbd00e3041e8444ea5e5cc43c62d722ddb81a19b98937a060b6e94beb95ff7ea449bbb9f05986345d101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090195d26d117281a8598c374706b3f71747a22b7463b5b589576aedcd773f09420f0ca8a63c5cd39cdef2e83b8f8310000000000000000000000000000000000095b90af146fde11c8f400f1246b9c1eafae0788a0d5cd7052cc36b77117a4e4154a0a0006509a5e91d88a6ce40dca10000000000000000000000000000000017aff59b368f3903c9bea49034e3c67c7d120b0e12f8a7a067f92ce871674d3a58764cdf7cb528d3d243f8e8bdae9969000000000000000000000000000000000c219e407dbd8d4b2521cba1dfca35ff2e33bd204fa96d410784c55e776218d8f1cfc9dd9d2ece2845f6c5363d3280311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bcda99a0fe589566296b085c63231040a30356ee10cb693d084f4d7d3c5d61bdaf483739f5173f1f95f6ac1d61e2f000000000000000000000000000000000034026d7e3173caa159b4cf311efa8674dc8b51680c5c6aacd762092fda89e9a6948534fb231369a2c116180bd328b0d00000000000000000000000000000000022710c84ba4081720ca907dbf2860814ec1c1adf017b4b27917c174f604675961c70ad25fea3522b8da13384bd9f1e10000000000000000000000000000000007e2d29ef5eabc6e26637deb393d843d09d0a7c599621bec0b921ae6adaa6e334c1c4438499d3bf7fbb6deea34c0a6fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3577e9c77f0366baeef1729372b7fad18a00d140cae134f5d6eaf8b334349c29a5e949698f9792ea9ffd7e1e6ea8b1000000000000000000000000000000000262fc8bc37a12b14e3945d0f901f892302ac0ad4f6d572186e354f9eb0d510c6d5c9e9e99bfbaf8850ac6c5a3b58097000000000000000000000000000000000d383801798a9536c46a686ed00370c21ce165c0e830053c67417966a4e8e22359a85771cbbea789fea671e74cb6afc30000000000000000000000000000000004581f63e62464cbb3349e41eb2f3aa5a284b0cefd857e16a938b9357b99cdde6c6d1c949600f71795bb2815d1d5e8e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b9e86b13bbe4d72b2a74296bd40fcc7f9688880d4465c4aabbc43b7a9242246f14e218475366739af239f0ac05c46a000000000000000000000000000000000659d60ccfbbea3fae789fa1ef668bf4a0b648b879cd56d45af104bcda9485a2ce68d25e9a76edaad8b7c2891973b10a0000000000000000000000000000000010416c28e8cfd0d6d64eda4a764068242dcf4af0e634c90186393de5e4374dd57d88f6cfa21b4134a92019dfd3dde2600000000000000000000000000000000000a073658f93980c037e9f6dd21e0bacda8c4b5551104d460384be22217e19bf69ac8702888bd7bf888bbb183e3707e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e2c2d8cd631f08e251436e47d8e9e1cfbfdbf27e96f49ee02286d3cf8238f8aaf01dbaa2c134a72170195a5f17494a000000000000000000000000000000001458704068da33793dd44ddd3ca25deac8b82f593baf30f005a77ea1b03ad53ba86f6c6be28d789207d879c9d6ae529200000000000000000000000000000000068b9099a85a6b1de2cdc22ad7c88bbeba607983b168f87c0974d9889c8497bdb6bb0d8c733dfb0a42c124773176fba30000000000000000000000000000000007a02d1824be9c7c25278d2ce3aa9e18d4750e2e733d4145158f9dd61f149afa7d27bb4f9f1820a0dd6484777f3e78331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ed40e8fcdef5b8c17087674872ecb85e653af040eae611b3e487444d5a09cfd77d2e3ff57b616fc7dd02cb134169bb000000000000000000000000000000001509c9550c5c016915f24635c1df6800f610df803c7e693dfeba3223adba3350d4ee2ea23b43203170bf4e631aa9283f00000000000000000000000000000000037e346cd4f033f784c7394b4a13dd4d6eaff2ae28106938d2725f4f4ecc7e031b4d22fbe4321a9a97d0243508260863000000000000000000000000000000001994633aa59c4d85baeaa384f350633a117ba149740507e44d32b46fd7ab7b3e6e2e10bd3b95c6b6a5bd56cd6dc3e8be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117187e61a3ed432dd1d21f1e1581a320207b93d2187697deadc134a150be15ecc665c5f33405375a28a532df2fa016d0000000000000000000000000000000011433b8af3549304e4b2878f8e988a3967a2207e6e011603e15069f290128fd6c7b435bdff8660307979b28485d9ffa0000000000000000000000000000000000d7af0353a8e5d8d8b0b8d355ce2298f2c6d574ad88cfa8b0f2ca231261a5b8fca2b288ac8d259ef064e5ebaa5f05a4d000000000000000000000000000000000149aa6202bf4a90810644e46ce0f37af064739f0df82fb1b826a3f5b0daf0f8c8a1db0c14788a9a64eab5a236a7a5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147533909f6b564ff7188ebc54684f9f1ae46f5d71412a95dac50f3fffeee02466b048c3a623f5b97ec9334fc0af3a6100000000000000000000000000000000104a30ef64a113c0623192f0ed5fe8ca6e4526afe5d8f6137925c3e0d0c6f714cde41e9862047e12ffcb435bdedeaf8c0000000000000000000000000000000017b34c485532d4ba630a865df6bc3cd32a2bdd31556286b685b1bf722077d62c7864027cfd628a2f92cbc357070d20460000000000000000000000000000000019f346e3494f71e87d7af358b7d5685d26f1604e5b87b88e93ee3cce63eaf0e2170c7eef55db14e964df998cec3b088f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d492b8a337b28efe2fb8e76c96cbac2a5ef84a4d5e602676350539858d1d5c50ba34ab7c7de1bc7999fca1bc1dade60000000000000000000000000000000000c8bb2849d9184c6494531450fcbc8bd0988322b6053161e86d7cca130e993a80d229bef4b792f93d75e1890d520344000000000000000000000000000000000e9592f6d1d65d53115953a86aa131ab8ee5e4acd45ded9a888f39552e1423bf35326a66924f350decee64c4b1a479800000000000000000000000000000000016cf54d46f12fde30781fcae890dae9ae1dc5d79ad549e973b3fee0e01285f9c7e8b275fe58805e5b4093e1edf1a30d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8109c209180766d1e01fc7b3307752fbf717403a63774a180c60c07d171974a997da85a1ff5fdaa52a52899ca54b8800000000000000000000000000000000183c720461fe98527ae1cf29d11f6aff4ddc87cee9eb94cd2b7e344e76577bbe354233f2d9ea5b614ca4bb87b094b19c000000000000000000000000000000000a99c91bf62ca2beeb5908f57e73fc5e14d20462f2ddd20058619e86595a44226c7f13a87ed8a31e7ac58a77613e699300000000000000000000000000000000173486da0d9efdcb111ad75636ea21ca864f127d594ad4c78cfe7d6a60ee216254cc4e7ad9ec4c1c94a2c03619a2468a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c9a3c76ad02ad837fcd4f5d85a2d8baf84f0df4fa49ddee43d1421796425d0abcb45fad37bb0d95e77992ce6c4c114000000000000000000000000000000000e0046f3a53de94bb63f960224c7383e0534882aeb9109067c8bd6423186700e74314db3b41368d2a88a5af837fabd02000000000000000000000000000000000f05c7bae8cd2fbac933ef672a92b758ca90e94b5898ee9204258b593e2ae220a816b5021803a5411044429db180721d00000000000000000000000000000000137488ab6873a900bae8a4f42306565cb991b4f9ab0a68fd7321eac4e718b3969719c27cce7b3148f59e41e7e695d2d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115079a34042a252da93323b47237847d29b1f85635874fdd7ca9ed1ed515399636fcd325c328fbf4ca4c337bf4a74260000000000000000000000000000000008eec5be190930f05af995d91858cd097168bc304bfc1de514b0eef4850c9b0e387d8ca2cdd7140b00086679eb8182d20000000000000000000000000000000017125e1ae68d18dab9c37fb8789bd67287ee10a5e1553d141f6d9a7d8339876b034eb01174f407ddad98854601b7c09b000000000000000000000000000000000837c59843eaa08bb887e20d6814fbd9435767d2e2be78753cec2e3e3fe6c2115ee6ef6d4d465a7fb6b55f50015ee6bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcb8d4f0253a9281aa9ec35ff49df054a3bf255e9e69fdd6190a9bd0f50c0a53817ac490984ca0a627b861594f6930800000000000000000000000000000000152ce805c36990c295bf13ee179dbd2dfd05d322564e3d2b3f11492e92c1e2ca2fc5c7776714aa18c7d10e34f97bde290000000000000000000000000000000011bb8f4c926e04b290848d903981c66185a9163905fb2e41951e53ffd3602352148c5b88da2323782940ab6125a4aa23000000000000000000000000000000001545c8c909716babdae2dddfb2dd9dbb21aa687796ae01bdd8616f2b558d6e71938aee86fdd92556c8378b88a60090571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a159dcd8519222e375b4664c03fc50f55d4ce5031c48522c4899922f498671348fd56ad2943484a79e72011604f17a00000000000000000000000000000000000168726d77c4b4ae3cdc5fd66af544e7cde0efac521d6ecf27235486f4b9febbb532d7de2be62232605cb6f95ff137000000000000000000000000000000001220c8c1f4bfd40fd6ad5a0912188c0275e0acdbd5dd064673098211d514beeb43660c3b3a3ee15b7e7c4303407e90c80000000000000000000000000000000002aa452800fb4b967c34f3615d795a497be3bf0cd9fb2783a304d568d8eea3821a98fa4b1fe1de314898966df3f9526b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017008a6c1822705ffdbfa5d5246c3ebb4ee980ec1642c1c8c9ef3e77ab384278d0547204a5052057b39390cf18899bc700000000000000000000000000000000154a4ef11cdd579e48b58a2f7e0dfc8457b6572e67ae7a87dafc137cd3bb6d8ec46e115bfad7f2589a643c1381a1c0610000000000000000000000000000000018f5fa3201a574328b57a266c19df6a3a5f8d55338a51bb618febe69ac0dd9e3a62551bf3d44ffa8c4f283584b0e9723000000000000000000000000000000000b19c5e2bd7183a3afcc14d5ef3736037525b8b3ef404eaa9e0337530f99b3a009f7a5b6648c5cf4471e89bd175bd6a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e55ae39c17949200420cddc2bf962a4bf817b565b05e7aefdde76785bacc9b591af3813510e008dafc113e97c1bdf9700000000000000000000000000000000045c7b30658a547968a430ca68d161d47d3b4f93adef63846c5db5ae921e4eb03c9d9bbd24f537c885abd2ae39d8c3d7000000000000000000000000000000000afd20180357f3ad21307794c6882ea7a705952fa0ef101610ff695b60f1463e4b91aa90f44e07348a1db27cdc9b17430000000000000000000000000000000004ef734bbfa1899f219bff8612f5de6f98ca801daf055f70e8c46cb6eb564ffb0e4217145295ec0d6ef7b207bf78bbd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011679f986f685fbb7d60df586022cdcbbdaf395a93b60fd2b4999fedeaa0ec00feddd7fb96fb2869a4070483345afc7c00000000000000000000000000000000199f6604aa198dc6a42d7b00ef9dd6fbe7f4d07dcf13d58817e8f39a91d59388fbe2f8b04e8fbba9d09c5bee680897a0000000000000000000000000000000000a401f85eafa0a7135efaacf971e11ff3b9612f2f40ea470213c3187efea095dc6c722535ea5bc0023a811771415d8780000000000000000000000000000000001d40a84c8f8d83f3a13412257c77195f057b33d0e7514599a0cc3e2d345974a25d92364c0ae54ade8e9cb589c0ec0221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4ecdd7c4d05eef4aa878283a85250db6cacf2f022bfb2564f325061f5dd72e01b39be9360fa407fdf9ac735779f63000000000000000000000000000000000044bce2fa18795bc62627b4de89d489f2505167c54780bf051881ebc332cb3df398dad4d05edd8702e5df4c0b27177f8000000000000000000000000000000000a1568b982e176e393eb1052a9d8a74a07a01ec7370c9c1fe881d71fd80563d91b0e11feae1c1871e2b92f0069fc315b0000000000000000000000000000000014ac398a9d7df2dc317ee143ed4e56f8ea2a4fba307694745f72695928468ae2f66282735663dd594acba9d83e2c4a4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f53d9423664106a55b92b7945b88f32041187eb44836a803b1a1e61f660c1854e30179e8349d116a91f20f91eaffcde000000000000000000000000000000001895f05e99783ee68b943698f2bf2f037851df090768db976070fd92842c17642de474a615362653fbc01c744b80270800000000000000000000000000000000158dc7ea08fe72554d58ae70cdf4c791b7c9dd422a822d820526c9a545f7cf580beb4d405db438ee7d76cf32154d06b10000000000000000000000000000000015e9c5a8c20097f0f5c9afcd1cf03c8984496dd616241ad0af7cb6942a5a9c9e10b6cfda24e6f918dfc038e0c2e2bb7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008d78b43d9f65e2a4a9c1053ce262b8598fc6fc179188f717af8ad7542f89a10d4a5ce2430f89e49b9da24f62eed1a200000000000000000000000000000000169697779acbf79518f014f42603a4e9a145272edb13d0654e9b6c9b99a32777b8a458acebf1ea513da4b7f5b8659c8f000000000000000000000000000000000a5c767eecb4a98b08e91af9f5799448655743710b4138f180d465fa2c370aeb933695cc7b9272ce9d1209c29a953d050000000000000000000000000000000012b25728b1dee57e12932bdb2696189fbd443b48f79f91bc50ac71d6492fd43dfcb13a177abecb3907cddf7cb05ca2d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001416abef055929ff36493939c670f43f50e16041e9af07e7f60a10b6f35f4b80a5c7b08f1a6f2c7925242a5558cea65500000000000000000000000000000000071d0473d203b27921d1d18903ae0fe2047dc488448fa651afae2cc1331fc266eabc544dbde502b5a52343fc4473b9870000000000000000000000000000000011a723724fb35636f2934b28720d7f2e68ebe2d61b585011e1d185170e1d3205a78c4078ecc58d4e6e339d8b44374f75000000000000000000000000000000000b89654356408ad5f552ef2edc48d19d6f8be692bf09752005bf4f4927a2697226c6f336b036c20cd54f77464fb083171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001255f8a9016725700a6f19af155fc606f62b658d6032d534506dd02682ac912aa326f81a3d50cff51825473ba46d2b6e000000000000000000000000000000000aa146e10e838e6b89a9b73d2d227a828c401f28a4bb1a21d1ceb9d6e33b824c6c07d745f0d2fb12018184a044b8a1b4000000000000000000000000000000000051ce51eda0c3b3d15a1ddb65e0b346c64af7862b855555aa51a6bc29174fb70c7acef46a0901d197fc75436b2098c50000000000000000000000000000000010bbde38f70dd74040338e52d1e1786525cba7cabfc18594d1aa3e5044b13ba4f972d92362bb40b7470a802cc8ec21261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015bce24cf790ddf610333375b28840a261e349fc2f7155636d420cb9ad9728ad4fb13b0a3e88f4e0e8a9beb6bce3dc9500000000000000000000000000000000159618ca7ffe96d11baa38ecd25816eec598df4822587e826716c9ea4a5c81a901457823ad18a1e659d2f414aa1d24b00000000000000000000000000000000007eb42b5851cdbaeaa1a24d202f82a851adfabb852f11f296964d2928d8a8f5f30dadd54255285870298a4cc1d8b5b400000000000000000000000000000000002432af2cbb14536c8c0cdc18f7f56414e432b4b9e07fa31ded9aca3ac7dddd16d7dd93aa274a011f72c6ce0a20c064f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045fa125a9857620a592c8bb6c8199a884880c02e19db7d1694cc28bf5a956279017fa69ad3980a2474d6ec43af8eddf000000000000000000000000000000001359ca4a3d7dc25be649e77561b672f1a9dfb378bbce1ef005ad0da02a73e2a684202a5d32fc930054c4b6fefa6200460000000000000000000000000000000001d57f00981b049cbad4e205e708885e37f67ef40c791b77d318cb0d2ce341be3d9ae58e858dc0eabca7dbe7bf886d220000000000000000000000000000000008c935df115ce7daa7bf178b06bbb40ea9d4d0a96676bc95da9cd0fa6b0b60a5596a050891f719b4d4b11e311ae5ce541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb6bd846ca774707d8c7b539201adee8fa4acbf340d15bcdf4e484ccc9e0b3757344d3585192856ae2c92e4f8dcb9070000000000000000000000000000000017b6b83131c964b15ae933db128b1019f24b85d2680ea7fe5634f23f7b2194c45d041d6ecc80769f168041adb5289dde000000000000000000000000000000000c9c8b38baf6072326c18ac99f08a1273eb9b1dbff9c10b5591f5550d707f2df7aed02e16107444c40dd0e2cd9701b7e000000000000000000000000000000000ed4f6b55469a2cb3ba732adb4f1c2136601f4cc4ccf20ef9d5d9343b952add1d7eccb7acb45b24e3d72ee83d697da1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7a0be376cf6438431c968822996514a62262a634b9b0db438e7485e2f991fd99d30f462f92d3df139f7ed61ab26feb000000000000000000000000000000001970198c9db46369613e7787e56d5b185c17150cbd0a0889f6f9ab8b02c4581d35efa33f26546dcd05fef1163d1f27e5000000000000000000000000000000000cce8d5a55b1aaeafdb50ea2c5470bbbb8dc506c8276cb4ed618212be6425172d8013eb9fc07f39bea77f299d442eee2000000000000000000000000000000000cca501ed9200a901f30f583799d6d5453e97d4d899c8b9772d57ad0bfe9da2d06bcb77d20ae0650b0d5a93b040262ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097980da09d6f498d76335a9eff9d93042c85aebe7b07d047641d0563e4f1fc4daacd4cecff48640bbb93e453021decc00000000000000000000000000000000009c834d0990ca1e4e06858ce7de6ae4fa76b8e9c4d46f88d1da3afca9707f340316b14618b7717f07c22c934cfb07c200000000000000000000000000000000029ac91f0b9df5a39b8a5e1f22e139ef6385ec9ea8fd547fa5eb3912bfa315b5f474a776730ae8c5dfb68871dd96340d0000000000000000000000000000000000d964c9d7373e6ecb40fb8b7dfeeaa63084cc51a0d2e359dc9a88aae2fdce01c7c401289a89ddb779d604d6e612dd5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000952b3501d0fa50d25ad5e135e75a0f50eaec617a147f7d2b893364aea650a2d47bd58bd6c52bae8d7dabf4c4915f4a7000000000000000000000000000000000a31e469510767cc3e0cbb378ee8e883f8e062c157833b4dfafc6bcd7100c4bcd992fe3463cc2d40e7eb0d88a3aaf20d00000000000000000000000000000000083c68123a5175e1bf4d10edef347e8e39cc2241e1d1341b284274b9c380128c963d22df99b8bf674ec4d9837b5932d80000000000000000000000000000000000b12a1ddf39fbe68e0eac6b77d9397d54992f7737958a2270391d9bb716afc477afe6f7879a8897509c720cc4942bf8", + "Name": "g2msm-31-jwasinger", + "Gas": 380835, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000096035d973ce54172e18d3efa7bcaaaac3113f1233af789b5cf0efbd009d63b6a996bf81d7ecf5effbc7ce926bd8d6d200000000000000000000000000000000042ac0a88b1f08c391c4a93f60c7b0bb145e25d2936ee5cc93c2a9a220cbeea14cdd4b597b257bb02478d2ac7c7537fc0000000000000000000000000000000002dbae06ce6bb0802cba7050c74e26f26d5d2be93786e5419865c815902e46678fa80d5acb7bdba0641f641286f71451000000000000000000000000000000000654470bdfe54c60c22433faff0bf66bfe5b80bd70b84befd75b0f302a77294e65344ab35a031fcf298bc16f4ef123ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca87265eac01eda9b2e4fcb35410d543f2abab6edbcae49f8abfc36cf19f4b9005b10b7cb41712d83f08602135200510000000000000000000000000000000018369ac76639691c32f2f45da66b4fb0610d9adadf5412ef8af250d86b8e21e80703f35bd825862dbebc527c4b424d0b0000000000000000000000000000000018c13080eb44986351f442d49e93f6186526159851f95f799aaaadf3e015ec38eea61695d25d3d932d70149c3c555e00000000000000000000000000000000000fcb54a6a326c991a1c6c50906394e0907816d36b4699af6fe09d523d5c173262228778e10ecd4ad3f8289740ee0e3611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b94ff282e5b6e6d9ab33348fb5faf40df38b4c380bfc0b1fb3fd820ab46416d43341da75b9e33cf6b56d65268a5c38000000000000000000000000000000000e5bd9624278f9cfe7693593eb05760c10f04e1178b75346fcd9f373055cb62797cd7c1f8c34823d4fa065cc33090fa80000000000000000000000000000000019ebc3c19dccc7fe2102200180331814f05c7973383bdd98c079c3752ec455851fa779421ee2a02e5c710a722e1e2d5b00000000000000000000000000000000170e11a3d287907204b7a0dbdaf98eafb96118746ca4899b3bc86b5aaad98f4e1b751f447cb485cc990f217b112480ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134428bb054ace91bdc1ebf6f03c0e95e42e333370b07f80510aed1e592cb44bd5e0e617e7f1808d30c5f1e0a7938db90000000000000000000000000000000014be34db195e2a84109e79f2c1fbec1330fd97f84b5e09e5c281d06db2280692a49de70b20fe76f1ed835ac38e12fd4700000000000000000000000000000000180e7c05bbfc07730276c245c58f4731e4ad49b2e06a45d17901b558a7a52f10118a10ce3c85d5cd237b5f86abfda2ba0000000000000000000000000000000000af23524683b3620396b512d7d3140aac7843289f35ae9a325d2a581db78af816a4c6636f5d61a622385e3533b4bef31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ef19e1a3450e813ccd3296d7fc0825014a9723bbdeb1dd64270a562b5656ac25d19f15fb2b759548adf8052f786e890000000000000000000000000000000019d54b2909ae0f3d7fc1b642732e99534463c81d77b0535ae52599b75bcd233d2f362a6cabfaaecfce5aab852479b27c0000000000000000000000000000000000a326473188960f55d5c92cd85d51e365803e55bebe3163d18bca388f8c570e8b972e46fa5a2bc99d7b0887636b4662000000000000000000000000000000000b6aa6729090f9c6a6d87dbd60246acf6bb464636e36c477de0d3394461d44cfb82e472f26407b45eaa8a85567f30b621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aeec1339e6ef01af6db965058c1d697162cca3d1f88c1b31fc1f9c54110eca0da247460cd5db9eec9122a25813ddc30000000000000000000000000000000001429d6f4a5b69f171cbb8e9adc9c7b2e14fcb1cac6d1e440266c93dbffa69b5f5f734272721a96c9e0078d72c79ffea000000000000000000000000000000000825648a95dec95cc130c3c345cf05481d8a571a25d72799824d56f8b64f2bc2ec2190bf5b23a3325cfa16c27829bc23000000000000000000000000000000001779388b901d0f78b95f50a32e99f32cc5d8079dc5c38123712c1b14c3dda3468dd13dedcd8b53665f707293754cceae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034be8fea61ec3872dd0c9e42c043e6732941759188c5586ab73cd57f0c304e1a31bb7c9c40543777f7a6299e673e5ae000000000000000000000000000000000af8dbd6971aa125e51f72686b577155ec4bf2477bdba83bc65d61dc59f7ec05818e02d4af2b13d7a012a5521489978200000000000000000000000000000000054e23ce1d67723d8bb675cc2a2594f73bb2e33e44cc77403d1d6130045e98d7943afb054859143250ed488d30d1a070000000000000000000000000000000001605cd5008efaa93cf562a279679aab202356906f5f39f4a50c0acea0bfb03d919d3844c5031eec99e3b1d79efee750f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019360391645ae62ed727816e3a58f41cc6a3a0195e455956e1a00f1cddde7443e95f50e88a6ae5ebb803259412477e11000000000000000000000000000000000f5647c7ae5012df5198dd77191a758bc2c519f748b07cfc6807b23c0726ecd9023250f3106173c4a80a823e074b9bbe0000000000000000000000000000000015fec9a42ea91098a0d063e7a984f6dcb0d98ede56b9dcad263b010031a57f74afcbaa7c43edf5cc50db582be1f02485000000000000000000000000000000000090afd7343d13004826c6b62d668f4bc77ba770917910b204232492d724f6c50d360bc5d63cedd936c5d47b61bdb30c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f6c6ff2613957d15325d2e4d77e2a7389d0f9aa70fbb48d966ed2960b15e6756843ddc61c2d155fc6eb7a5deec4b300000000000000000000000000000000053dd983719b29e402a9150f140bd08a3d737ef356b9decba631bd6af3068add920ffae6e53556e3bee9664bc8bdd9f60000000000000000000000000000000012c9383ff3a5677fc23d6720d4e88bf2ea16cdc0cdc4b4f6da570f71c7214b0e224786e2032921ec9e36c3bd5d325290000000000000000000000000000000000ef513c79456610a1b4176a501ae9544ec7106e06691adb5cfa39a2fdb8a45a18f67b653c203848ad2a743dae064cdd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000087e5ce2d5ce45772ed7325eb0816e528d6427c3465148312664e855371fb929147e7b0fb8633e5501ad606133ff72810000000000000000000000000000000001a7f24909ab8775290e5a071c635024586d818e80c6d609d1f16f72b536c91409ae3311c97a3a6f093f03872e9d4180000000000000000000000000000000000b9a4522e074034278659c7aafe736e35e4a8377ef6bf646591573d468373ceb306da971a2eb90a0920954e0a4a3645d00000000000000000000000000000000154674bb8cca85491f79badc76b0b84cf6d788ec3bd729d9c0a46cfc04d5fe7c5607189f07284e8b00c8eee51fdf9b9e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f17af3f1b0ae6d8e66b976b3ba82c45efc912e7fcffcba99bbbb516ecfd05439bad343260b50fd89e3d3ed31bf9c3100000000000000000000000000000000041d4356e23e1c13d459797ffc4166070e3357bacc9d62f78d38bf55b415d6f5921271b2b5d83c533272b5006ff898f10000000000000000000000000000000005842e6f29660e99e20779d258b6823d663f618deaeda49a2363f1afff0d9fb6f6044918dfa0df48f9646a01b4b688fe00000000000000000000000000000000147b042eee20371a3c1639bc4f9fcb499a5aae71a51c92fe9255cac836025e7f3c7b0f189009aa8e7f915864702df8881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d114d526f4ecd35fce12727a110b6ced8a25925f957cf493e7261ba14eb1943d80f2c65a0b23953bc5208075aaaff190000000000000000000000000000000011ebfe2fb900ab4e233a6cca08a7d6c9d29780a4c426c89ed94626d41a75a3c984abc49d466ae7600fe2e3df350233bf00000000000000000000000000000000138b7b1575abec5a43c95af492b111865f813991186d9f3eb0efb3dbd810bc7b9f91f60271578c045dd8dff93974ea83000000000000000000000000000000001177c81002b40d881d83e3b9dcfd3c19feba2c51e33769326f6445fb3fc003a70592443b6391149484d7729b294d85021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000adb22e2c987bb0bdd1bf86dcc9f514440826f8d5727e563003bed586d07a0cd95a2da8236959a2758eef7f066cc619a0000000000000000000000000000000003092510625794fcc3487218e5bbb261cecbcc6cc3e2c4b93056876e32eb461239f18071a0c08a276f0631e51a0ed56a0000000000000000000000000000000006098f0a3ef777cf5dbc284df2ad6f445e32f87d7bd8d596652d564112163112802f19ae1e32e26d6ce5431304f5bed40000000000000000000000000000000015a1e30e0a367a56c438c5a83142013627cef89ecfe8ca6b0e277743e64f4d0fc6a744d019fd81c3aa896346611369711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145e51d24bf7f15d99565721d912879d39bd583bbac46f5f652164eeb94bf6dd68530b462123b2bce078ee32b0b4ef500000000000000000000000000000000067831f84432ae2057ed869bad04a5153b33be7a42777a293dad1db5f323c4efbc776a047f2d3c125c3e4b04621d4e25000000000000000000000000000000000114c7bfdc9546cf2f57451eca30885a4aa10dce4ead3b3b7b6c527f6f3844cdb066eb7e0ea5d76e2f0e50ed1e8e629e00000000000000000000000000000000087dca605d1dd4b52fd9aa12c57f61791b46e7ded5479a0be83e39bb8788ec852d6fca1cb1415a92b9c3d787c17aa0211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000500972dfeb78854173c0ae7ed51c8e25899dc3acacb3a8542d8e337403a983b85ef5e5a1e86b509c0364c3ebf5021820000000000000000000000000000000010636bd45a02115f460b927a734cb03f8900532cd8626d01de14bff9cc925beb166f4495fc06094e093bc31e7586bed9000000000000000000000000000000000bcc32fcd96859eedd8d32a12d3ba7feeb8903eb80a5aa118e6feea1095d2223dfad89ba57f7d0233016d971877663a70000000000000000000000000000000019bac8625796126be24f4a49abfebaadfc700f66abc0f327baa1d12b7d6035a03fd31a1b7e9ed9f08a5d25fe08b9f1751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c373216173e65bfa2c619c4432b1009bc10dfb3af495f00ef1220fe0be2d0a415150bdf0f39e590158bd2614e0a7fe000000000000000000000000000000000c5efb0f8f23047f4470aee07e63ddc65c7bad54c001163de4aae5f03e5584137f603ab84bac48397344285ac927d51a0000000000000000000000000000000017fe23e4cc46615e24bc2eb4dd243c3c7eac19fcbbd186dde2646641339800e5c5b0eec1d12192ac29a102c32cbf575c0000000000000000000000000000000007aa4e74a47b7d0dbe47d8d5685745f1acb8035bdab63888402a018e7a8c242441ce375c568bfd6eca8c93aeedbe625a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1444700c2c2e4d94c0d612f6900d82423c4725e665760809823b5165abdc5790be920c27fc3ec39b80d646fb74635c0000000000000000000000000000000006b1d5073762393a3033e4e6ed6030ee19497cf9db86f020502b993da18e3aed1888eb53ec2b43ac92a78f77b0cf10bf00000000000000000000000000000000126b371f95ed69ee2a36c9cda90c94f77ff8d4c9b3c8661a6b9112481bb0f347b930f7243fa1e79c36b720c06efdd28d00000000000000000000000000000000005e1eb4ac90a1197015c742c8bc80a54e1a5fbe6bcd34fda52b2083500f320e6073891dbda16110235d85a5a5ff204b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000056d0361ef2f713a171771475bc84d2476f837019530b0df4186629e7f60c30b9bad5f022d213de07ec4c52f6e1611cb0000000000000000000000000000000018d714bf6f8e4a7394ee1076d4d4b99ee665b3ac23dfe4d6be37cf72f15882e16a6c9b7ec382e9cfff7ff3ba89bb243500000000000000000000000000000000194ec0f45278cc26883adc98707ae9034e3f895286bddb8a33824d1b631da5fef15ba2ae309f0fed790b80e3735d64b00000000000000000000000000000000006f1882ed50baef99619ca6c53c04b73e877842de023d655fea59c80a061ea2d264872c5e1f78ad10f8582d92d8a15b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001455d5376f953757729851c2b54b0469181afc88cbc0b8599d432122da820ff7814d81e06bfa498f3ed2c1c5a52226fa0000000000000000000000000000000019ca2171153e3c7c279144092d4e9dc6f67a858f40f66ea26ee637ae4589aa312c1107ad2604a8c4acda291cf41fd8f2000000000000000000000000000000001418deaf6dc21c51c76fd71d7c0c1a21480f729476770472c8d7d62e93a072ed2e7f734596ed2489cfd25313cc668eeb00000000000000000000000000000000128b88c14927d35b378f5bed440d1e5b9fb83854960eaab1a0cfd4446d8080fe384dd9fb4a4996d0f808b02b7adae70a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ab43ac49111f81945767ed9e858dae6be3d065fc39f0648237f07832cbf1ce128478baa5a8f000513e36010b4e9f210000000000000000000000000000000007ad77e8e31aa341f39bdc587389bcd33c1130fe4ac309f93de220f4d13a4d7a2f17bad4f79f3b32828bc5b4cc2fa2d800000000000000000000000000000000178592962510883039b8e536dd32e530a90770032ce14f3ab73f6b804c8e52dc7e2e6e717afce6f7a4119f1eaba9a966000000000000000000000000000000000fa47605933552027b8bac7e44114cd6b00f90d510b2b2cc6bf6cdc522aa2d6435f231ded9759529de44889230aca5201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001888718e6e0bfcff9d95fcbbb291a5d270d430e66c6f1d30a3f3c0bcb1a85598520e04886b33e00211119ebfe035721b0000000000000000000000000000000008b4a088592638d2f36a7217351a6dd76c57b7d33b4bfde09fb2e0cdcbce7dd06ffbe5c5c76ba1d6844503ad3d29e542000000000000000000000000000000000ddecabfac329c34fdd110a30043b9f2f21f60307648453bb99e06d7e73097fb840edf4e9b04ff4f25e013b9ca2a83750000000000000000000000000000000011564d38f5deca9f9c34031cfbef0c479b7266b9761f047c05e6d50047d7575802e727ed2a7576cdee9d072cd872b7c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012148440ca0d912f0a6402b68fe3a31d2f541014b9f6d8465962d670edb9482a57896d18d428317bb8a2676dd579930000000000000000000000000000000000c983600421e36bea09022fcdf0117d08c9a7e6f57387bbf2dee790fd0336d5db2cb939b2c7eadf04e17702ddb390d4d0000000000000000000000000000000011fbc2c581174bc26347d71af22d72cf725a6b7024a995aaf4857d464db17f4544bf61394a4a2c76bbc36cc89239b6720000000000000000000000000000000019c5facecab3b4f71edf675e0e74e218bbd756fd9af55b0c7c4b845460821d3eff4cc2d28cd8f0d681fecc1051ad63291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001488f3ac7e7e6a3264f6bea8812b499f09b869326cb81ecd7703af1775fd068ec5e551cb67fa339e15c80d66a50a199e000000000000000000000000000000000bb992f0ff3c80f5c1e3d055693f4a86ecb41400438d310f63f3db8bd106a9d6e383fdf8bab37852b31c63f8735e8077000000000000000000000000000000000608fb9d1352c66d34c1ead27caefcf0cc29046440aca78e1c70bda76180bbf6392419ff1c82049cc6fc306ed90b8b8f00000000000000000000000000000000053f74c09dc3cc6a0067ca5fc5dfaa16b6822ae648d4e8516565ef30c89e5d3e618f3e838a8eae7d4a5373762c123fc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c4334c1dc4a2e9bf3f34ab3352ed5ce2db0a62fda1eb0c35359ea6ba094cce088c71f35b5bebcf8639b9480553493000000000000000000000000000000000c2281a34c929848b68394352566cd14dd2019542dff89815637898bbed8155bc774ac21e9f06eaccfc9316f64c67a9d000000000000000000000000000000000183887dd5f90bad6f03e362b7ec131f23ea1510c44e14c2ef3abbcc7f9b34432fec157eb1e83ed5f2b2cb66fd372a90000000000000000000000000000000001428a3282554314a7c08d4034204758b84a9e859a74f68bb19fdbeefbdea268cc176eec04db2e3b2ba1d3d5c0e22f8a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106f59a8907987152b24d2e06b6544fa476f3ef59aa1607a6f2c46f4663e4ee180c734cb99226986389db5f16e24a48f000000000000000000000000000000000bd56287c531cf005a478b2e902acdf00611d80a7dd2fe3a4d8811d83b803ccf64597b0b306dd7c8268769c4f8d60f00000000000000000000000000000000001154483752e73081a2e810b7547c1fc850788608e1d9e535f4858b14cf2a26f25cc1f925da040d6ba8c93e08a8f63af900000000000000000000000000000000077b1b222af0ffaaf18f3b757faaffb2909c861a794e89fe4d176240a9ad7bfb220adaca9f87c3178c986a83b5b3e75c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001590df6fa7fc8e4fc1294202f185bd14050a6653d2229fbf80fa5af4160889c021ba06abc023e4041146291dbb18257c0000000000000000000000000000000001a3e3b925f86b18aadd329b4ee5c7b6189038253cb35142429d83cfe8e27da6c08d3142aae2498c7788f6fb38571990000000000000000000000000000000000173a95e7b82b260b356451b949f6818c94a34f14bfd6abea0588faf5bbfb62954cd36efeeef1afea83009a4660f3c790000000000000000000000000000000018e5ad3fa9e7392f29fffd5d8a8b9201c77fe56414782f40cc3dba1fe45382ea334265f334e9c1362a388ebd3462c5bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005559d24b6d99b28e29892ec08132fb34a5b776d761026e9501f7f0aa70dea13d233ba78590133cc0e263276ab10dc6c000000000000000000000000000000000a3f9eb578d2a5e737e34a9f435f388bc830b4e408740b2b6776d7ba7518daad0e37cabd4266f2da1aea0a44ce4c90cd0000000000000000000000000000000009fc460c171f54a6064955a27b2b559e6c96e3e3bc586ce1adaacc6c3ac09c9ffd027cfdba522dadd2a92dee37dea54a0000000000000000000000000000000005b05fc30a6d14e36c9bdfd07fde0db8c002f24866ef0ffae195f6a56c8e61f026770bf08e119b9b2e7bb63dc16350851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010148761dba4ada506400d62f873df235cf3fcecc858149445c08a36f73c8a0b24c71a5f4339152efb64e765cb151b1d0000000000000000000000000000000004bb6836896e065afca43fd8fd8bb34f470a3dd63102eb01ef700bcbd084625967e03465895142b102ce22f7b763be5700000000000000000000000000000000107b5c3de487d6e22eae4141e4fa6806a6f34ff7895d47926a8023c078a03ce52d2a68faaf692a4b79a21446c2d85aea000000000000000000000000000000000cc0a79cdf9cd11421900358413d16b9b3cd269fd784d0a0835a7bdaa7cb1bd10c675352059af7bdbcc1bec42b21339c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118abf8d965275a6229d17e6b62a4e35b3d3ff078592cc1d76e9f24c9a2b2dc3aeaa75b8ffa406e20c899b0a6b3966f300000000000000000000000000000000192e9cfbd3e60ed2e4f962285c17678f855e16c5301771d2745eea8b069a31a9154860ee77968f5b355144c8fb25ed3c000000000000000000000000000000000020b223adc51f9a62d1f51b7723b837a8025076d6318a4221fbdecce8cb6abe297601d4b305cdfcebcf3f5a8d3a38300000000000000000000000000000000008f14be65eff387e98dca761f66e91f0219bd98e87d4dc42daa6f3fd42c0d7b73a7b358f5e2afb06d89af9290dd5bdce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145d007835d6d1b37e88e301e1567987312e3708f5fdfeede2b96030dc871e442fe45f188a027b214754aa7db707f1ff000000000000000000000000000000000e2c098e63fcf1de15be8b8c2c97819085cd4d949415cd470043374f71127b9a77f9ef8909c47ef0fa74a6c73b2e173300000000000000000000000000000000192bd4353222a6bd22f081a768e6bf23c4c8cddc85f1185dbf0100c9a08aaeb7b8aea464a37a722b5fd4e013ae88d28400000000000000000000000000000000184218c6ce4da2c8fadaf539aa776574affcbafc1b096fb83a20a57a928f584fdfff1834104f590f3c43482e52a748551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029c4a722d92fa5428bb0806321c9cea2043b55de07e47e692e476e4c7acec3786b83dfc61d812253399d3856fe796530000000000000000000000000000000000f7d8390cb1da7367d245a655b1fd2c46255bb7c2ee4ee81d1ef959163154b980001bc40f0f3a16a8a200ac423307070000000000000000000000000000000019cd2783201bc606f6d8f06ea8480d11ba0fb2373a511be2d8e15247c62df140d2a99fa0c285adfeacd8c11e382e22750000000000000000000000000000000000af5ca3391c1cf5781501237dbb0d111f84b6325e217c5bd255a701dedac5ba52c27fb14d34f9d7e9261f35839126e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089503a2f6e76486d5a6feb2e46fd53d3eb97539327e03360c5401167e2de33ad7130cce65b25e3a898b00b12f0fecd7000000000000000000000000000000000328997dd3edae175c47d3b0a59046c97205d7565586c09431f7f2e8d48136c67db03498ef6276c578cdd970a63b873900000000000000000000000000000000042392927e1159f7fc371fd15cb47ce534253f4902b08221fee9e4c6a57e87d8ba71d3cb5fff99ae11cedd20328153690000000000000000000000000000000006eeab2bacb56ab57daf95d03a030f497af1a6f84a33ccee57d9aa1065d496d054519a730cb9a03c21aa22f089257db61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e12304b160f2d5d7ad794af0700a9b05aa2521bff9b7161d935576d2d94329af954d07df6e464cab0208e64e553a0000000000000000000000000000000013ec3e1fabe23e08c543871ce8ba7aa682f12a857b6984e56ac8898be44c213028e320eca9eaa1a04ac64a3841009d510000000000000000000000000000000010d632d747a3760b060050c0ce3cb816ada1fce8ba9a228b6b427846a8680d6a31c065b521c2bcbb1e85453fd5629ee500000000000000000000000000000000155a76cf41e808e36dc5946ba4016c14a0f1b55fa3e52ea69bee3af6547c39872628363c57b148fde707fc67bb4da54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb805540a2b017b3ab7a7514626784628d6c8e2af0c2e881e6f48f12f69662a45fdbc7da18a2ffce52c9d8f702fbe7a0000000000000000000000000000000008b37676cc30d321bcd50525a86363a330e36b2e02a00a882d8ff7a9a8684fa9f47076336a00b3d4a217e7e42ff3c5bb0000000000000000000000000000000019275a296cff3b1595725b57be0a2192808576395c5e2b33981f3c2f0da24699ce8190e459e22b62ee5ad66ee3c81d3b0000000000000000000000000000000014934d0b9c2dd1141018c3ee89e5e183baafd0144f3ca5fccb79b932989cb2245414679ec57a88cb74b8224dbc3958fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d4f6f982f5a24f092c2c1bd613e7b1a8c22072611f5a2d9b89f54415edf81070a30333bcebf4d7d65284bfe716b6a0000000000000000000000000000000000af87dc1fe049fb1c739513b4a9214c0a9e62a811e2e0b58540faea2bd73cf174987e764aa3e83c1ce78e2cc8cfa4ddd00000000000000000000000000000000021b72d4c6b4d84193aa47e41899bd982ac8051e76e7203ca10bdee2b941a4b941c04b51dfff170691e62d99857a377d0000000000000000000000000000000003292ac965b2e6952c4442f7c8927bd042b9acac4f41befc047e572f39d85eeb3ac42ddc064734a139a317132763a0a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cab94de09818e92d50a78da93b7659e46c855701daa95fb435dd73e289f388ba3bb91359a504a4eb577899b6604c5000000000000000000000000000000000e868c81096d55d09d5289def0b9b788994fb9bf4a47d3c15c5a1a4622b2dbe071fec69ecea1d0a8c82af19e05022989000000000000000000000000000000000267233c3050ecaee9a068c58a710927cc440525f4dbb8b3f8920e11cea0c6caea772817357ca9ae510cf74127112110000000000000000000000000000000000e37b9297f6bb78fd6f7ee47efb5d6a27107e73650d3aa96369a666b9a72c98f3c0a6515d280aafe04e2a95da7ddb62d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fea85a96b12b300808f25892c060a72b52dad197705930899221c6a321e0614cad478e09977598341751ad566ad10cf0000000000000000000000000000000017dd12c8e43454363eb1590739d36fe2d9fe223cee6547a152c19dab114092e83bdca6a8c912ba64a656027d97cb32550000000000000000000000000000000003fb1b0a6f08f2f03bebc687b77903234582c808179aa78c1ec160ba76d6a662be3feb5a07588b01c26a370ce8de2ef300000000000000000000000000000000190a14e84d1cfcc0fcc759fb58e700d46d6228970ac4035067554a4070dd9a62fbd52efe025dd8ecef50f0cc53dc37f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000445d7d657e12332b549826b0138f0c47aeb5f50e6f68b6ebc69999622f12bb98fe494aca91babf125562c694af271050000000000000000000000000000000016454090b9be3f3d4ca511bee73e6abebdf81ffc0cc6b1e19ac3e584273721ee006454e0e16ae951eb9d1196a0f69dca0000000000000000000000000000000001cc3df73d05ae25cfe5cd150c66d73de3e2cfae2d3e22c97534e7552220a85a8ef4e9a94e3c74987fb2cb0e3fbf767000000000000000000000000000000000070c5fee39070cff04484b42b11348f950888c492487d101bfb195863d5f3ec93fe5363ebafafed19ed790c8465bf3431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf5142432565c7bb2d23abcc79f1c99ed3ea6b03443a0617dfcae19247c30f9e00fa5ce599b26cd5650aacac8d89405000000000000000000000000000000000180a64ff5a58f505520f62bad618ad50cece1dc4f7ece679edbf688ea597bb31f7e363fecbfcc372ea500bf1c2dcc960000000000000000000000000000000006a9e0e71829899f7b4e93988b760174eb816bc0b8c4040e492658ffa4d331346871f2a0513a3fd10b40a6dc9b6c044a00000000000000000000000000000000099a2f0120cf4f9e503113f8070f0424cebc5f8146c8f44f4e21f09f578d311ef6215bb39ae90cecd17b4ffefe32a1521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000118b97ab86279e157377e79587d93b45d6abb96db28e90d78350ca5e0434bb2b40be33bf68f32d220bc25377a43907b000000000000000000000000000000000c3541d8ff3c798988deeabe76baa8a33ef8e42cdd3c67e24eab2fbfa3ada4bc6353d1ab6fba100cd3d66eedf5c8a88400000000000000000000000000000000156d586569063d4e2c15985f3c9f1b5686d71772e02587cde456bf8c08ab9556aad7d3ca30a155f171923c6f6ae14fc50000000000000000000000000000000004436bbd14611049c6bc011accb248b798f69aa3a130a799fd72dd510f7ab2e2db850b60510c68b828c011c9c229e2411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018ae33f2cab26332f89c8ffb983817a6954c88ed60582ab84936d476ce476b29e6da25e770450403b85f257d61d19fa000000000000000000000000000000000b07df4bf883a70a326095cc7e289bb71ee13936939b7245b2b10500d34e9e2cf07d334d149a4c503418629855eee08600000000000000000000000000000000084c8ec19b2c62155a3a3d595615735a4960c0d9a3b50c06d464de088efdc45f7bd359c5499cfd1046abf493a047f5f800000000000000000000000000000000040495e7d8e7e9726c880793452c80ab5583c539f9f2a05cbaf354b702e74d0f8a6aaf860597cb22aec455e38dad0cd01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098c1ac4462089e04f53c4c1b6b9b380aa92e0ae6d0bd189eabdb94db6c53ff0dc0485397e47ad1ed812aa20a7cfca84000000000000000000000000000000000f51b4b2cd49bf76618865531bdaf018fdd42d5a883d6aed4abb9866c8254c1e5aed9f6c9cc1c085e0fa5067c4cbda490000000000000000000000000000000009cc8c63a3891ccba0bfbdcb72409d933471f76518b30e709a87e9db47737acfb0a399f19a44c99e6a22b40cbde3958b000000000000000000000000000000000bc46fbd5022780a1862c9b3bd73330f1b496c33e8fe7fbdbb3349a1fa2617fec38b0720da4242c07835bf3f2cb739c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed1624555d62e854eaddd66c65bd0c5520a8f01efcc08e1ef76da1c0a42a68c6639e7249b7e0324e86e2a55407d61c3000000000000000000000000000000000fac774e6a9736aa09138b00b08966bf0c491bf0e00dcd45d750015dbcd93b1a1a9d95815fab6ef7b293138e15895d690000000000000000000000000000000016f127cd5bb2f055e738351d713379482b2758f21e6b38ffae59c74994ef327e51939f89a746f65debbdff5cedca23c3000000000000000000000000000000000b34027a1947e4aaafddbd47981cb504b85214c89384d8abb3fc7c17338c413c94aee995d76b87efdf1b486e6fe6f9a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c70ddec848fa4c3ebe8517f614c9ed8889d9c5d349295b81ae8d0bf5bba3f34e878c9ad1b2d23be5c73d03e17349a50000000000000000000000000000000011aa181f0714fad33823d3932d9b07cc1d86ae31959a332de520e685a7f05c317ce7ff0739af78c30b5bcecf03b82e60000000000000000000000000000000000f0158a3de674f7743d4bf831523a3053a851a3fcff21f5212ef43a2e2a32be0bf5c3200ba3ff623088a5b50c3b457ec0000000000000000000000000000000002b1019978178a49063222109b4ac92beabddf1768f2805e6c3d2f8e8a4051a468110d3782251331a5399e94f43d57a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7012462ecc64ccfa21a7f38f6a4c2cb73f72b85a1f60e824702da284151a87d3c5d6176af15b3e231098887221377000000000000000000000000000000001458c575b6fb43514a697e59305752f005abd92a50088867f6ac3328d61cdb66729c8acba780b7f5e1dbbd6ceff72b4a00000000000000000000000000000000143837e6eec33b23b50294b25eb99f8ba70459f55cf9c4c29fb89c70d3f8f8c69bcf3022687f7fdc887145819e633c790000000000000000000000000000000000690676d5e3293abda1edb565641519c6e052a84446eb9cca60e0ca61214d01d9c91080dacc77e92eb9900a933b7dc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c103b1d585bbdb1374ac1915a2056769a82deb25eae6d0b3dedd7023d3f4ec638017902d822d7e11009eee3c361eb00000000000000000000000000000000003de5b171452c27c66a17b9b06cc6dcd90582f3acf005a487c8dde60a0da0c1a9eabae9b078e7bb6685326625c7983060000000000000000000000000000000014f3a8f6fb65893cedaecd91bf97c436e3c7f3d515c20d160ab8a407e14d4613a21b906cf74cc63f4af5fc0d34eab1620000000000000000000000000000000007fc0a2e72c524b0f17e48bb17de67288924bd1286e85cbc8b42f6fe73d3311b753a26076c3ad62968d2ce929c94f2421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d3ffd39a341fdab36e0c3435d3ed1051d5269a5f0b7b6fa430d72e7de0a79a454dc68d098fd648e684b69b8ad59b5a0000000000000000000000000000000017ff7c02f11292749f8299fba00c82c8720e200f3b119e04d5bed67877443d28d79bb23c417110f0496e1257f73c5b4e000000000000000000000000000000000e53c6688390c86b74dc2c29afd4d853a9265c58737135eeb10db034bb233a747dfab6a0a9569ae494657f260afea7360000000000000000000000000000000013d475b4349cf1635a8ee6c5f81fda22d183a1c87f9aaf1c155b598ea08f1c94c30b9fd01cf10d0af87b5882dcffc9951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007698fd918e02cbf27d0f67c587a2394268d29a71553a2b68d21b629cdeeb77bb83f5cc05e264387e57237f592f835a20000000000000000000000000000000017f60f5ad4b8504e33989a9b139ce8c8361eabd0ff10ec77c777831c38d12e7544fed6b392310dbc6f7b65aab5cfafa20000000000000000000000000000000015d402fb6640583d6091c374051037fed0aae24a8f105548779ae9cc9abe95dde78a44a14e54d83bafc4c0b2df7014fd00000000000000000000000000000000187eb5dead0367e3e5387ea795fcd4c82b4b349fb9c19537feb5c67b4979594220884964505ab9a34ad8bb659bf579331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a16994ec5ed74a8bc7d4df0fa6d745addf40deb79d886065556581908204f3d914c62371dd05c08a9f4730ac1181f4d00000000000000000000000000000000103f6a92ce2c3e1fb12b47d46f7f8a24e895c1ef48af26df066f71b94be8b81468a62912673d532fe1ae9cc9277dec5900000000000000000000000000000000028978b42ad0b929ae98890122581c20db193a28103b472b8a337c0ef0eccf4b03157314753bab22b6894e1eb7895216000000000000000000000000000000000e30470638e4f7c5f9acbffcff5d6a9ecad746c2160e1db09b349e4f8b52d6e93f2899a4f00bd595896fada60bbdce3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b06ecf1a79a587780396122fa407f36483272e265abd577e38349dfd627c433cf55f14a5cf2f86122d394ccb330cb00000000000000000000000000000000108ba761933bf2abc8e0f8ba0a8b60079529fc590463d25b3f8b69f31f1deee0200dda237f05a9e44cd480ec3104034a0000000000000000000000000000000008b509a6a62266b0faca794348adc435977149bb1c8a676b3f5447f4f441363afafaa3354f589ba9e0f8ac3cc6bad6980000000000000000000000000000000016b1961ead0f7a684a41cb6423deec76240f6b8e25f86dbda3d9dc398cce0c4c734e5ebbe23b9390d9a67ea6eb0b0d511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d6f4be5e2e7bc87fe2635f58b64f40a5e3824421f3042441df374e4ad592122e765c1723c5df55af952ec43ccbc38920000000000000000000000000000000004354fb79eaf507ddd913f7d22c8c6f9788eb709497f392820d0bd2d29bf5902f62702d3db0461cd078489da4ed0a3f1000000000000000000000000000000000951e2dac11df138e1bdad50f95ebbf07fda31db0e5880b66dbd358c5ecba7781a3b5a75277a1dd8dd1bb89c12aa8d930000000000000000000000000000000015f1646b3093d159313f10cc5df1beb38b7336e772e1403a2b59b4b6ca2a1e7f4447bc9816638503578674b6027a33bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d71c933dc5dc3b49843e6cc0a8659cb621b1ceaefb46e54bd916decef3598f6c24cf53cd520afb8da964b39311406e0000000000000000000000000000000008051472975077a123c20de5fb1c6136919f34d09540715af9fe926b142e061b931d81bf07e59bcf0d96c0b6d9aa51b20000000000000000000000000000000013b0cee58129957ba87fd87263a538aab45e38118aba23fd936b450a1254bc2fada25f33725c4bae050ca2079b5de35200000000000000000000000000000000042a0a8e30f7554a5407bb0327d4f320e7f37cec75248d18c9fb6bd2681024a6f71655cb319ae2588ae9a38f65fa95171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bffc66d5f8be4fbecfd8c2f681be9a8b0fec5fb8b6e29727cf35167489bbbf994f38b5db3b693f8902ad21a76c2cc20000000000000000000000000000000005a09c10dfbe15d15256dcf73c1c6913576861f1fbe9d23dfbcdc62971438345385103b1c621141c928f0588b497b5f900000000000000000000000000000000141c70437c4a1ddad21ac5d8ea3a4c44468a3da4c71bf250f759b094ab652fc5b4ef9dee94d6a215f9c1620d7231373b00000000000000000000000000000000127ce51b386a00d1db60fcfc087daa9447d0fbc0f2c894f8b3b0a853d492713c073da1422090d4a5a0c6a6d16a6485f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e33681fbfaca9dad75d95f02d0a2f2c0ae458675f1a5d8a242b657716538b327f464dd67d5c441e43336082264f4817000000000000000000000000000000000b30970e14724178d5c3db7521103eb7f63a28b5222d3e9dc54ad456f698c88d5106e017fcb87de1570c75d743bf7a30000000000000000000000000000000000bc4d1f80113580f4e7ae3addefdae0c8d9ca2fbb07a9b50f01e435cd0217026a148cfb0d6627d78b995781157f51d6700000000000000000000000000000000157fa23d6ca8db81f46fcff9ec6bd9a55ea8ef74b92b8bb825392e843231c439e6be414cd61ac7d942525daa82df4e781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebe1fe085560e6cec63df2e9be5e4b93fddc0d9f2c106cf2bb090a6140f30dbd750e573f828c3e9995c47aac23e494d0000000000000000000000000000000009918e777dd9d2a862e842b35d610ab5e18131bb9db600a352a8be1404db5e927f5489dbd52fbcada228b940b7d05d1f0000000000000000000000000000000013eb8fd8e3a7ee57e43393b3f04c00b94003aa0bd303f6f9cab56eb0a11aad4f3febb4b851b3a854668d6cd1ae28e95d00000000000000000000000000000000128e836ca52db8703e0ba1aa225be766c866858df0e3d6faf9385a6b2336f3a027b294ca67cb7c9c75989398d02a361f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130686df1ea7843cff4dc3df6beb1cf53b51cc60895a292f77076b006d5f4dc0a902216567332c7f0952571eab09f4be000000000000000000000000000000001508fc91d30635bac7a8d98dac54e8967226fbc34547c6e284221bc75880fa8ac2f2184005a4be2ca06b41cd587b508a000000000000000000000000000000000d4d81edb5697e2e55c89ba3edc8c5d0155de81f1aad06b8f3765a91f92b9f51a2bb51481b98b0e5f50f66ffef2b0d4600000000000000000000000000000000186f3017bc3057bca6e168309521f1f8a6e94005de3d84e1d63f329ec1809327eede1424784f00251bf7f5518595776b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd8a1f7a0d6a6cb86ab876a2140ace1604f81d7df839c50d70b86ce71ae695bc1b531559f1220c13bedc3628a411fc2000000000000000000000000000000001416f6e7cca8f3408831957a64b2351b0b43ba7542ea21d2495c5990c5641315197f14cff29daec0bb5db6c608a38e6f0000000000000000000000000000000005bd126859dd60b6fca78d383556003607e08abd0ca52f7149504ffe204e4101d49759fb0f32c982fcd3c205f32c0b7100000000000000000000000000000000046979f08654aa9411aecf99580c5b07f3192bf5ced8e55a8e225cb9ad021edb3af7744e939be339d7c39e4e8f36e8da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071159f89a8b3a02906941f0aaf002dcddd336b235b531a9cff21c1e072073cba10ae3077181efae0acf0ba2f2202cc300000000000000000000000000000000120e0f802a66aa5e9b582fb0ccb60878e1f0433ccbf2a2f88d2c7d9ea0fe61201d6213ed2f854b17216243255878259c00000000000000000000000000000000136148759086cb411bded88ef18e1ca0574a6b3bc766e3f4e826a21f39b6da4de56301192dad4e00c148b191454f0a860000000000000000000000000000000018bc6cf50034eee58baa3a8ad1a54dada9e7ff4164460435e6c4592db53d3c60d635f27c5bdf794f52138d10bf7a4a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e70178995eea1097369b7868656d24ee7769648d874bcd37484aa03c67b4126277ad480d28a820c20cbf6fa73e5f04b000000000000000000000000000000000adaf569491dd6e7a7b44ee30f6e091dd5c27850811fd82d267dffae514d2c8ceb68990c38b797d66a1f99beea3a3be00000000000000000000000000000000015c4c648991d5049534eb1a008149b869deaae0bc877d7b09f27bb916ea7bd431170eef3d4d28d558e68fe57d9cd371e000000000000000000000000000000000e5667149b1e9420dcc273a0b9309ed888a41163baf627d55cda6a826fdf5538055aec3bf149c284fd64b60e231a6c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002608976378ec8bd9cc7c0295d67c18a3b46c479f2268385e92efeb1645c5f586ee258d8b38d415bac5ccde0adc2a01d000000000000000000000000000000000c3d0ca717f1ec16c9bd1a8b61b99448941d75f38be423bc5a1a3f26f9a32612fba6ed942a00c676332ded0577bd2d300000000000000000000000000000000006eac2a41b22783bc665f4d05e68e386ada295c00e9eaeaa23167a8b5b4888b925c3f2a9ac3164467b499ef77eff5f430000000000000000000000000000000014d445a2fad739c2b5dc5dbebb5cebf02308fd87d8d5a5ed228c174d8dbcb41b8fe876cfd04cb1f4146be1420c2009e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018943335cca4825575ed886566cd3efaf6282a39295b7e376a58daaaa57571134bfb36ea0d19a3d0cb95437dc40b3a3a00000000000000000000000000000000176fb128d85a741e82b72e182732c8ee8064e4625ec743cf675c95f2c3dde2fc89b09e26d260bea408a6833f8d66f974000000000000000000000000000000001987925266de60ccc4a2ca212885a66e9e09987413c8c8b3e2d7af71394b0c40d059d38ff17e2bd8ce6decb2daaf0be30000000000000000000000000000000003fed60acf0fd62308eee4155ae4344926ff113742ff975e89925838c0f9b1bd075983a4724e60775264e55e1363667a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dd19ec56855801d0a0ba2d50eda2b17905ca6fa183be5c7ebd4b9ba2c5ae7a5445e378492176c92eae1e717aa88188100000000000000000000000000000000055cab4dbb6c8635b95e4794a1a6d7b7eead9beac6ea80a6fe885fc174744077dac552afcae981069afe94d87b2816bb000000000000000000000000000000000db9311384e6f983bb75da4d0cf191186f3dd22bce3968dc4d38de07f00ab8d08edc32b015fb1b724189242cbb10f18e00000000000000000000000000000000009be8c974b772e3593086fc429c40e0dc4c5fbfe0b1ae3b29d98edf975f825571f3fca8a3fa6a4e1c29c6fe35ee864b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188257dc1f3b93621ee506da5519790912d461bd624ec515e0f611df97431ff44cc5c0bcfb0379ba707b1d2f232270210000000000000000000000000000000001e8ccb33ce64442b166eb1ff4a710fd4f8604a4af9820590a274d5ebb204b9d2c4ef25ca1e776c79f8a06c3d74bc1ce000000000000000000000000000000000a7217e53c5e98ad07c30f15037beae626afa2b396cf679d0eed440afbea745d124cd352bc099f6b62bdf61a5bc15e010000000000000000000000000000000019769842bad8bb905bfbd787c5680359023949bc03d67135666e8b7c88eb2a44d486c5706dde88962dea791f5125fc1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7f6ee7b57e45163f18e5eb0de457a3df53a1e5e62b81e12b87fab099b022e0d44e08dea4153e7d9f02c2789b3df2fa0000000000000000000000000000000018e82f6683bbf6faf502e88e6c5fb49f1f04299761d9aeaf1f6cb6cc15ead042d7b65f261edf503122fb96f5d19fb13a0000000000000000000000000000000008e8898f68ada22262019ff926d6c5aa6c16ebcfcc0d326cf5ce8f2c211cb253b3faf7f2aa31d0e3a32ef76371c84f3500000000000000000000000000000000062620bad9b4f5421ce177b0fe758faf0c5d404cad3ba2387d711ed6bce9d91fbf062846a1dd63d548431e565fba6bc81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000968e7834b782aad8c38a570a98172e7234c0ea09946e5dbf81b78a1fc8e6b7e897762af504f774dd250c4d5bbebb9480000000000000000000000000000000014d4d7380be984e0269edc8be18f7a8028f234dafcd8c6690392a7e56d6797ae7dce4dae2848d2d7cb9a20b5bf46b90d0000000000000000000000000000000018b68cef920fd129748369cd6967d72d53b569ae272744db405e70baa3d9c942de536c9c28e640999bf0bb00e153ea130000000000000000000000000000000018466c3fd278b30ab4551c2d7346a87b6c3c8abb778e388b18684f9051aa9b797e1f87607388d35dd3b18c4076a7a6ce", + "Name": "g2msm-64-jwasinger", + "Gas": 639360, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000011bf95ad1772f69ad45ac319a445e66408f564ed3daa1c38b617ee03f649f85a099e7a0d73c7fa47baa85b6cb775b6e600000000000000000000000000000000021cd661e557d8f48a7bffd200b55f235a3f004e10230214bbe2be93da31a2f14edb183b68027df610d07105824ba5fe0000000000000000000000000000000017ea617f4622808f353828b1b80a1ea192a4c0e7fcadc9729e88516b4485878e9221353a0f4e83ea32dac98971762efa0000000000000000000000000000000019ca9fcdcad78d5582b52ce9d659de99b7745ed92ef709daca9c4cff3720ee67e84a2b8be13e3ff943944915e4bf70821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000183d05207ac96afd59de75aab7126369244bf25d579a1aa9118272e3412225537515d20caa24801a4465165d3206b66f000000000000000000000000000000000b237f18e6abb7eff816b95ab7b520c371bcae2fe0b3fb2b497ea93fc9821bc2d821d4334b1bd50daa0ff4ba83582443000000000000000000000000000000000b4d3411c277de9c6436dee21c1dec262ebac011861c57790f405671bb103f92bb544a70f68d696d053e22cbe22959b2000000000000000000000000000000000eb9950966acc0a75ff84646151c2bcf0ed130f5cb4735fcdd78e49567ee94ce5c5ee1c6fbc2cec5c5e25216d31ce8581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f818f9305781aa9ac1f2d5747473eb498c1ec52cf6a04ea6850b6d4932631a32fd0d81200ab72b42f72440eb5407f90000000000000000000000000000000001e16b86c72788788152815091e905de94cd7c4544634b5786be5c9c7d548f0b470e8b2704694ad10baefb825945fdcb0000000000000000000000000000000006d22fdc2e0195cf84cc7e1beb4124f197bf294bb870ffe59b155406c9d4061137152afb4cfb0ee95a328f485a04437b0000000000000000000000000000000004db1b1dc6e48b7dc1d4e6483db63fd83f064e53ed49e369f7a6f7d7d6f2482c12b8ce8bbbf7a7a1d50ec85a0e0e7e421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016181cba8431a6a6ba44f0ac2027aa758bc68cfc9c81de414b5382efa57dd2a222003c70825a97a2768ea167451fd0c5000000000000000000000000000000000e22561c73c06767102e03ade2083ee34441ff1f5222f5dc170b5cc665703af8926568e46e8672ec9a518cf87332b7400000000000000000000000000000000001d96bd978693dbcd0b3d193ee0930ef8772773f644e0e8002cb600d59d20a2f632d2b99bc22624ce794f92f9675b5c90000000000000000000000000000000011d53975075b9a9ea263da477138d597938d26eeab1e61591543957edb8407632900665b5e2da92192d8e0637d050fa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000528b8b49b95cce73bc630270ce3878d80b17e14de2f6c15543caf4246600069925ddc3a88715336a70196f63a0260c70000000000000000000000000000000005b2fe13feea37070faaaf0ac37b9ea86f12925f43f0407f6d20ac324bd72dc0fb17a80e723a20e6d52134084ff4533d0000000000000000000000000000000006f7b18d990002898e98af11b7aa4281bfa76fbec6dd0412c58db4d1ab40ca763cf337c78bb39b228320d0ab58ed2de200000000000000000000000000000000163f2c6b661830c103c69a21750bbf4d0624d62edfa7b272f717de925dc88ce8735f9231b34e722008259ed01fd8e8491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d3f67b80a7ea1dab0e0738a35d3c93940520588871565867755ef1279b44d99d9f228caacae8d110e3d7e48f222d54000000000000000000000000000000000991a65a302543152d436e398863e5cf78390fa621fb1ecccf3e27cfeaeed08df571183f238a18243ea17c94ee16d8b100000000000000000000000000000000095c56f87d0ac73281f15793d98a388a6ae48aa3eb5a3d2e52f7a0fc2c6ac508a792526aeb54ef936a70110a3c031b38000000000000000000000000000000000a6e112510134ccc1e0eed83d958b2dce2fa8e3782077cbd418369095e37480e21bfbb5d42dc8e23d23702c5cf3b4e7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017df7be5dde1a88a02c2d41fc0ae70306fa4d43419223cf8bf688bc69f1410b986a7c595e9a7dc350e6abebac45d843d00000000000000000000000000000000036f844b7eb9375b73eda48a93a46ba6f6d1d9447681817c859454382262b323015aad044bfc43314462816e4f8408000000000000000000000000000000000018e2d590bb7f4f5afb796ec26175fcdc6b297811ca0c839ebcc6e7aa3fbe7e31a9cdddbe3014b14d17095b8b1be9c89800000000000000000000000000000000154c986ff4adf5da8c67a1d9d3cb7b72f33091f44ecd143cf08a03bfe2b7327e4d8e062076c9b837924f59a5120ccd421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005dba9d7bf522c7861e59770e85c754826b6c0a1405581f8c0b951e395f12e526189ee280bce7335d9fa600bb6e4c0a10000000000000000000000000000000001e3b35f5b9841c503be6b78531fe35dfcea0621200b98631df020877dd07c464988fa7394b006b72be373337a705cbf000000000000000000000000000000000ffb25f224b9398347fa2aa6c480b0f430ed181804a89ba557b52aba392a46d585d180c0ced63b63fed2aff1e974a20200000000000000000000000000000000165df20728116af2c43d4939c9bf9d574c206ac38a4e5bfc83f74e30a3f7334630171e21f7a435d0dd0f9ca4412f8ebf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a9caa935578255067a7174973e0554aa3a19b95929e60c4d9dc5c6f16ba9c1cc79dd7b708e1f3d2a876d3463a8e3c90000000000000000000000000000000009e7cf8411280bc0193b0a731be8102d0d859be09bc9f209ef1528d08dd72a1ef358a8c3ea5aa8c238951b9ff603e6f00000000000000000000000000000000016989f0d153be7bec06f267c0f05dcdd40d78fb4b166eba9e3a6ea713fdaed4b5fbbc6a22cd905b9c50f6ad9039cafc100000000000000000000000000000000115ac4aac8100852d3e5a0694210a47f13a0fc03d3247529eb7f9c631cb3de95aed6c7ec062d1609ae3e6ef6bd942f571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012f31134bc1912d49dc76c721e2ed2da1f8b4ae0869509d7dae4898a971cd2dfb9317f0bd8482b81053d2fac12bb55e0000000000000000000000000000000007cbb903eab440c287518e1af691220c6261879106b5a93a00521b62f0cb9de25ee537125a8bbf0c411c4b353ef129860000000000000000000000000000000007d005d2afb9df74302cc74383d0252304e3bc8c97dfd74b199a6ff66ebed449689aa9e043548ee3c9630975179bb71e00000000000000000000000000000000184efa9721d267c93dcb18e28d8c46efe05bc940fdf04dbc7de5ba6aa8a6365a0f9509dac55c4243123a01312b79c0261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3f526772ba81c522a45bd5e6177e30bf50d7e95abd1e8ab8ae867d7f3a0a454bec9304fbc7c0a91ee2bb5ace139847000000000000000000000000000000001134ee079e575481300539d0d9815e8b2c2e7e255a15bf7928c11139c1d34a1f4c977a9380532f8940d5c1dfa6d2b7a1000000000000000000000000000000000a83a4b6925852afe2158959a8022e40cb2d4cf980a2a96675f657eb263b42faaa18e2917c24d2ec3d382079de47993d00000000000000000000000000000000030c559fb1b608433bd824a26471711dd7cee802ddd5440f9aca4ad4bcb41097b47ede09f523e02c785a63a0102b9c941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001799796f61018d14d6d87764b0ead89baaf8d7baad27e8654b9ddad269e93928e62924c91f119f05e6420d9b1ad90b720000000000000000000000000000000004c99dc947e4e907a15758d68e48ddd4992a77d4e8288f0612f477323408340c2086e1beb3ea2ee139f2aa6472b3f08d00000000000000000000000000000000187445842a928286f67fdfd7983a775d88cf0c33e9dedc9b1f5de020415809123221e290ada1466e47489d17f9bb490d0000000000000000000000000000000010a169368c6222a06eb6c427e02be4d1a98bf3a4e68d59c3330336a0dcef460af33786de7beb9119cb202444fdecc36a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001032b846395fbd00575eef388436d9667153141559c11088ada3b632c2e821feb3d383501cdaa39f5b8bc1f7273fe62c000000000000000000000000000000000b77ba55af6021fb5482b3ceb55c6f0595b5ad7dc21c2eccace0abd6044f90988deb6e02f8c21cd1c60ec47f55eb0bf90000000000000000000000000000000007eb939057991684219eb08ced81f7fc07e1c2e5d77584be74dd6e7eacf7f37b4236f45c91e2a6cff5f8c37da002571c00000000000000000000000000000000131f788b2be988ffda7ed22cd52199b3c287ad44f9baa2fdf7f36a7bf875fdd2b9336d0083a864d8c93c8ad19d1052191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198f30186cef7b4412668e4873364e94bf126dd00ed3afbfd65c168d961cc40f46372d4c996a12d4b83c1a2c315e18ac000000000000000000000000000000000e8c5af02e9019849426957ba7d11272708879643644165b3eac74b99a70a071d5f287bebdb8f76693fff1017bfb5a1a000000000000000000000000000000000012e046aa90badc0cfb78adc0d06d6440860969fbd884395cc3887eb9d2829785a0184cc2bf812fa9cced0590a694b30000000000000000000000000000000002fd0481d55b95a352579b251a41d6efc5c5ca2888b221b9067c57ed7d64a241a4aba6a2fb72d86c56a6596107b9dbe81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddd58d0a85d73b8a443b76aac1ae70efe56eae01e8f7431c18f28b95341f9f0e136171f65dfd5dd2185c88ced1505960000000000000000000000000000000017064f021904c483279aad0e44627ad492e52482a57b53f065802d4406d19e91bb488a6eca187f904fac67d5030902bf000000000000000000000000000000001370456afdb9dcf3bbef4a9e5747b3ccb93e342775116f54b4826bd8c90f6f63a52d4b0b5f1582d8e650a9782933c21c0000000000000000000000000000000013d318d0cf0955267170480a7b69b429c49e8ac7ee3b3389f360229cef394ff8d80460369a049351149371411acada8f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139f8702b8b767db78da045b4846e55dd13395cd49df355e53cdd4a0e39734422b9d9a7e778f71850f14de459a989beb0000000000000000000000000000000018c2eefa8c6d35ae23e12431fadb12d0a48a2b7cd5902ffb17cd84855dcce4779aad3c7a4260397177b23b3bfdbf49cd00000000000000000000000000000000158c0c849d10c5dd247fe1e8ddcf3b364ee8d27c7da5de8cd482641dd225264f8652815e28ff464da2fc3be2accbd427000000000000000000000000000000000438e0a810626d58cf92e85c365cfebacd6f9c503b540b3432d5278de8f8ffc22a5e6c822e3c49a1e8076ce3fbed5b511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e0f28dcd092149d1ee75ffb1d248162909de3d4ccb434d24a045667c7918b860ad57f29d26137739d9db7adcee000b00000000000000000000000000000000060a0281668b98e6eca3fb0c66f894cbc5af2788355236a8dce5cb4e7e7b202393de4787f871eece9b62a88417ada91e00000000000000000000000000000000197d56944796246c98088f574c984da3db7898c63527bd2a1625f96cf3fd1a16ee52f4dc93006d98e975e1d0f10af24a00000000000000000000000000000000055e939c9891a4d8c1850004b7f27b3d769cadc78dd533ca47409a18f39e1d4b97658cbf3a6829ec60efafa93b151a781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1d69acfe9fe709bdf8b522807659034c32933f6326600cc4fd10ace2d4c7ed5ac590a22ab54c82f27d44fce704be6a0000000000000000000000000000000009c86b430aff2a061ec052a4427654229bf654622cfced2f84961af8941f74fbe59df1802cbff705819b7c62b8d59ddc0000000000000000000000000000000007048feb29124210e4b66ee35a1de37eb993780db55e49ead4c96a5c0c124d9afb4a9116507164f42e742b5ce72667cb000000000000000000000000000000000c4b40e2cd6fbe96903a9268dedaf4f8e15579aa973314a0c3004332bcf42acedc7dd8716cbb17887d926947c52c9ab51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b14f21ddd890a5bca4a2270513575d9e46c95f3cb68c6b98616e2b1a0eac508928296548589d99d0146aeef386a46000000000000000000000000000000000f383dd7a06bebc5b9656774d1a7b9274a91ee213e5492cd1bd3325100b58b1c050c873d5b5fcadf083083a1b9956efe00000000000000000000000000000000139fe25154f059b556489e7e78713ab9d989ff788b75e32f70742f0311d9277c339be25240508d65fa91da115c7c4da80000000000000000000000000000000004f1fe8e6254fdec1968f807c061448a28746096d64d0f1919f51eb3eb23f65b3db1972abe985c48ef47c11b0400ec091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c82b622c68df579283e79c8e5c797de5727fc47956b69d2236f01e3272bd5707911b3c015a05c50c0e55dc7bd81e145000000000000000000000000000000000c15b7437c02b11331a9ec54128f20a1795ec4caa4740552db1d7d6a4b2b4489bbef556b21ff6ed5313236779c5260df00000000000000000000000000000000187f4ecd88c9aaa12c66b318c1e46a5fcb33c96bdc535b2eee47fbd2e8590d9c3a236e59322a367aa74668f3ca55b765000000000000000000000000000000000091fa89d41faa7c66709260fc30efcf8efdbdb2154311e79c1e7ca85aa32f1c431363f4b8e5cddd807fa32591c2ff6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be9ac27751f096b806d84bbe2c6073a3bac48d6d9e0e3cb78d57d53c1d5266bc3457ee4b7f608011c4acbe573ba0a1e000000000000000000000000000000000e59da4d545c63b3a206b2e096421d89fafad3ea2e1132bd1ecdc6e3c891756cb5f931f87c69a4ae6456db78a98c52b30000000000000000000000000000000013fb1e7bd0e80b1bb1080b4c24eb692430a0c7c00385634b4d626a3c69301e0ebc5f1f3930ac0edbba786c9d9f87ba6b000000000000000000000000000000001202bdcc1a174f032176807693c63135edfe432f014d1054fe22abf7a9687e0833f920c114ad4b4c3870572a2c06f48e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4ea28d7db46ad11c95f8081b7ad6520f3906ad1adc747ae04958688ca3f52d08664e5f779353e889f8a52e78f4fb960000000000000000000000000000000015650b4211fbaa984b2fa2045feed77ff29e2f96128a5170d86f4859f881a4d2a212a5b32c0171ffb05edce458a23dd80000000000000000000000000000000014820e8d8989e298cd4bc9294ecb69533db5da7e18e072e0b4875e99c9c00a90c84cce168d8b618c26845b34e2e65e5000000000000000000000000000000000008010a75425d3921b5cbf37e33f342af25297c116e623a2c3da823265fe50a05e67508a04ef0c94142b7a95bc380ae21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001617b619ef259deca8bfc5d2f628e26436ef1037d50fe9750697937f16676b8e83d6acdb79befa04cc8a62a8f6f8336c000000000000000000000000000000000d538ce271dbb8e830cd260c038746170ab7485d2649c08feba271254de32c380e996ef068a7451bda5aa07bdf2e4b0d000000000000000000000000000000000f476f858e7fc0cfb1c63e738ccc17bebf58a23ca3ff3639a06ee8151a886c9c90603b7950b5fd2a3dc5313bd8da9eeb000000000000000000000000000000001891a03697e445ce23b08fe548e40dc7659cc3effc25cacb0e1df2382b0a920a45a49d01e40858a0eea191ec66b89cbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38bd98b3ffcc24ffd5bcaeef7b3714dd67e8399e5fd5205f5fd666c0e41a03af70d696fd3242e14cc152460680042e0000000000000000000000000000000017309c2771f7c4ef4af81ffe7150794232af664574ec45502b677f90c94fcdbae7eb588b73e45c526f25a9683cac2cba0000000000000000000000000000000013da92d3139de87fe537a6da43748dea4306936cbc7366c7f0cb9fad1b27656e2b2537b3c2b940fcb0d5c4811ed0fe13000000000000000000000000000000000e48e63a9d2f5e830a52389f696d0eba03a91c5ed34ee4de8a98bc2172fbe52bbd2d51b371f009260b12e2d5cffbfdf41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085ed6826c51ec127d79932edad21c18f882d2b98f6f33a49add86d4e1c5860356a03f26ec8e9324c967e81e1fa91f6c000000000000000000000000000000000a276b914c7adb3945b88b95bc7a237869b6035cedc606c1f31ab23efd8d4a9a07996e74876acc218b8b42534340d45d0000000000000000000000000000000008ffc3e72045c442786b342ee1f081a9634f9398bc383d752336d0b4a6919012b307bdbd330e7eb3622774262934ed4c0000000000000000000000000000000010b15912daeecac9aa40ddbeaa033b874c04457ff17cce889fe4a5fe2bd0ca68975075396af74d9fb60bea04764e49c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee9e739407b62524d511edc5038651266bd31b635e65c7efd25fda8c1d9f6f135742681372eb318256014a9817a00f30000000000000000000000000000000005c866e07aaabbb4a332e2b3d46e193cfb42a325543663acf14badbc521dfdeed259562c2f4f72ee93f587a4a737984e000000000000000000000000000000000417a4dc3d10b3b04f817130b25697a191abb7b16deaf8dec16d5ff7ed6bc90418835f8a7c98e9bd8ba711d8be83a35f0000000000000000000000000000000019eab00927b6837d3456992f0ac5c57c9109c725ed3a750cf3ee39f3338ebf658da128dc799bb1846cba4e4ed6481ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ac3e2223c56dd5023776f306015a4437569bc21e64f4d4660f244188ce7114bd93ad4c054ce8c508bd6e9bfe75154000000000000000000000000000000000753deb5fdb6ccef5d503fcfa0cd8970ffecb85178aa104581231c26e6b1231d21e4c405fbdff1ac71f75f382f0e3f910000000000000000000000000000000005b31ac04ef418659b5c731e19334cfe4a79357db0eac49de306964d855e1f01e3ed208830aa9c51fa2143922e70934d000000000000000000000000000000000f0e51a992c5a3b3e0d00885224b3c0db8ccb9dd1fff3ff96e4832b06576ddc3b183170ed618d29b428e0a41aef7b3021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000edc2968c5e465ad9dd1e6603ef89e0621acbe64a4d480780d6e8b6b4d4bd6df6eebce7a410fac1dc4bee492ed2afac3000000000000000000000000000000000011f438422c6982811b06e9194090470de878fe605eaa6e6a550c7d4dfd084f5b854fcd1886d589732cf0b9c94c29f1000000000000000000000000000000001834b6000e3b60782a1b9ac42f2c8e5434f3dabd17e47f7273d9ed59e97a980430a62bc686d4fda780bf620dbd8618aa000000000000000000000000000000000182ca9b3256b705d1f55e3c9d318bbdca10e6a220d858689d185ed499e40626ee2a1cc0c3683572fc8c614b01bc00331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf42df84fe1849fcbb748946839eeee5bc832a6fdb3226125321218aab7ac67b4a149aa826c7bc879390e6fd116df55000000000000000000000000000000001517f9434b1c8614c5bd1c19982a652eae0c97ed865b1bca6a66fb62da01fb34908f9f167533ea59fa51ed25a2ae12af000000000000000000000000000000000603640cde6791ed619f152a2e3152442132b6bfab93b08e7df79c8aefb2af9250cdbd5c27d54052b7296ed9b0db10ef0000000000000000000000000000000009f90ebc9e335e266ae53f7f857d228d07675ca1617ad96869b9ea1e5ce9d7e28d27c72c02cab868812be61d6c519ead1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4dbd1ca6a1b59bf797cc715bc9916bf234cf00255d2b7329cc9f69ee6f7fcdea0f00d02bc710cab9687b0b169fbe15000000000000000000000000000000000c6e677e94f191a9768f220e900cb01c5024330b62e2e483c30618513762462176012cb8fff1ac235ea520883735d9570000000000000000000000000000000001667eef259b8fa9367a8dff793a922378313c26912dcf4510f00bff8d551b0c4d83a29522ee86ca4f58040ce969d9eb0000000000000000000000000000000018839d4765e380e66d7e4419161434fd34dc3fb5286fb28451f234b70d7e75b32f2cb509865a9bd76c6667ab504646ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000673f4ff25fb2b482426469ca4b83bb5e6f3db3d116daedaedbfdf6eb1016d4e83eb46fc50cc815f5f1b39e188ee215a0000000000000000000000000000000017da33eb99da88916b42d20ec280ac482b24cbc81bb8ca9acdf1943d7ab7e3393cd396a0303e23aa37a3f42aa9de47ec00000000000000000000000000000000058b58103c7fb9beab8d6e1d87fc4afbc171d3f65fc41c0596c7399796115e3e17f795117bcee8fdd0d0db6c83d6ce590000000000000000000000000000000006d9311b2628195c4a032e976db91d3921e0171dde1fc455faac598e0d9396cc9f02d4cc6ca0a976b934b2c45190f4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001626a6e4ef0b345fed8fd06564df66890990690964f3f64f2fb26c11d8aba05e3a81e6b3f5f331ed3269fd87ccb957df00000000000000000000000000000000192f4fb06bbc52675c2bebc3628c97cf4568a74d71a80eabccbacc138d0523f348d97e411dcc665edd2c0cd66fb7cd9a000000000000000000000000000000000648884fc143d1f9db240e51f1cd57d4949690fa939b335aa1b61fdd9c6d88f8c6f8a4ab2d821c91c974d0317c9ba9960000000000000000000000000000000000be2344a007a4bfe708d037757e791324fc7f6d6e08e7f8403203f6dc20ee271f7b2a14a80aa7a4a6033b98cf7837741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eac23c29960784fe978aaa687772a21c01a91979b5790947b875d6801e07c54f54a49273a75cf807b4e717a7d9c2fb0000000000000000000000000000000007325e10d81093d530b6918eefa8cb455346d02cb104185e3b7d114b2ee1e25ce634653e3bc5c23f99d2f9b9d6a091dc000000000000000000000000000000000f63d667d5ce455c517535efcafab8c39aaa3c11c9b18aaa6d4265916ce805e5c1f6765a8b22093788a6a41edbdfb8680000000000000000000000000000000016508f06b512677cfce2e9372e1ecb04cd82a13f3b35e8a01c052ba1571e56688d7b9bc0d5717eddeb1c6cd680276bfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1c4bec52ac613f60844a9cb72880dc11144edf1c728679a4ad0e013dbe0c02e731fc7d64b4716716604983285b955a0000000000000000000000000000000011e88d8a77fdedd2400896c1a6c435748091cfbc51a7c0d69a2b81dd1ea41d5d7129147ea407e1394a1fc9fdac4edbfa0000000000000000000000000000000016ef1b1492f2396e0e5eedcadee07325ddf725c26b4acd46ae872f4e1a9f79f0762e587b5a64409bf29446b3ffaab01e0000000000000000000000000000000018a952ed206bdc5a50e5ebdac082d2599f6b1d3b9b92d5afa54ba6e16b51021eb254b98f1ae6a24db9d55cd89cccb65b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596bdc0f74a54fe803b986b32d91adc15ba757f56a728e2307c1ccf6a1baa646cdf912a48ce16be39a3dcfcbbf9812300000000000000000000000000000000095a1957d04b344839fe3524ca5f66b3012d03623e9c2f625dc6a94be197fc262a627dc0b77f1525817f5cb7ee3257a8000000000000000000000000000000000b09ab600f78429dfd35753f37cec7cfc3d9bd266a01e71ce3f7ec4cf2b0ac7029f29a21a2b6c61ddd0fe62439cebd5a0000000000000000000000000000000015c70627b160251f895f192779cc8738c390d7fe9ee899716547cf0420a832e75715e6408977005510a26dbf394ab95e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff3b12035e7918ab07539a7095c8bc4dff7754c706201ceaee303d13c0563a15d0a0f2747355c86e3b506a8988a6cbd00000000000000000000000000000000107a0765bdba2ad4bc1de7ddbe8b463358bf9180d76dd46b4005ca22a5cd031bf0bd2e3d7ca843d1265b32e303835be6000000000000000000000000000000000663baf7649adc729dda22d3810596c97dd1c35a22cb1fc436da13e0d7f36d0dcf3737a5779d7fc8c5ce2fdebba8630000000000000000000000000000000000019450d43e61a2c9c6a37cd4866afb20cfdb0cc520f6f6b12d7fc207b1319d4e4b60e0861147bb8b7e88c637ffe705181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b36a968f5bc41ad634c637a79e59039391e9590f6c92b20d4d492e883b783650d362eb4fb525b3932d4af12f9faaf300000000000000000000000000000000186d970f4268f9cab04326b00ea495416645b4d2dcc7b81939f33eec046b64506032739e6d86cb9dd2c70b0b28d8cec60000000000000000000000000000000001af7ef21c0dd79420e1b0c100f09484eeefb99daa4d3d4fd7cb3eaf41f1b1913a43f9bed22a7bf7c67e446709ed914a0000000000000000000000000000000002aa0a78624084204ead60fe307775a57c99212adde1747732c89a1d1f8d950bf78a2ae5dfd9f2be9c8c498d22c727471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b40e159d00ef05e7a516d06dfa3e2548867cc5b33595a7b4d9d4faa0a0f1986b4f73bf1996fcc91eda2af1418ae1b700000000000000000000000000000000084ef0039a12dc2b25b119ec5a24de11bced99a407e418f05a762bd6eeb2a37bbe403a02e277719b92fae19e57932e2f000000000000000000000000000000001790009bbba5c2d81d84037341452ced7ee5656763d1bf677a9a89e80fe3ef641eaec4df62ac7fe6cfc7cfab8ef438690000000000000000000000000000000017897e305c70487ec991202f9d6927257292dca4a99ad9845fb5c30fe9c0c08ccffea99d9015ca86877f5ecd4c53e7381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6ad87103dd219cf3858d66f22ff36fe9b1527330de1a6f4e055ad141df4b8e91ac5e509f63a73b11c7141296dfb01400000000000000000000000000000000013e9e162c38eb166ad82ca7ce5669ebced416e9217b9fdb3b11420d8fc65ecf947750754ac89449ad042ef6f091d7a8000000000000000000000000000000001584660a054e014a22ed8ecf959a760e5c71884b903d40d105153f212d4d18248cbd27f2963e97152af3ec713669935d00000000000000000000000000000000158951e10fa0b55ac24df62261912b87d70568fdbf7af3f4ac35270aaa653c6117ad081dafe34838e99de1fcc3cd648e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae1cd835fb836b1d20fd6e191e0ca3e721bcfc76e783a125f9eb8e191854eab77a5df6bde3a8739778953d2c7ef79f6000000000000000000000000000000000de30670a1ef79737dd98631aec3c7bf10c93f1ec852d09b86504fe9849572ea0b7d36ce2eb998fc338bb819c5b5a946000000000000000000000000000000000a8185e739ddb9a6be17b69702ed7ec63fec7383ae609a8033ac935df77c570cf6e6bc270e740168ea011f41a4f618230000000000000000000000000000000000c0c6fee5bf17d748ba7c6100c55bcba2c0360dcae8618820bb21c60add795af981df3ddf31b4681f8033a87c3487531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c6b0d5645fe1637f9cb1c37eff25b2b58aa98a4c8eaffc679bffc7b47bdd4c9b7c42846de7e71f58b14dbfbb3d30ab0000000000000000000000000000000006d290c3b636159a3b2f0a603f5d516d4dacd6b2416b5b06537cd9dd82d95c9dc1cbd354b4a3bc98633db46766d5216d0000000000000000000000000000000014ea73e8d3071f7e6037f18e818891da140e0c812c5354af220653a5a5f7c86df5ed38b049bb65828d100a6ca2efb4520000000000000000000000000000000006cdbdfe780167f83335774e7aa4c07f8691d1b303ed32dcd6e7f2572eb7ad51b555cace7321b1344317921f9023e4a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024a8f3cc11120a71d8a1be7b81758a7ba3420bf93d05273e678c7601523574aaa2a019034cb128536d5b3fcfb99603e000000000000000000000000000000001020d360f80d5832cbebc88c5758ddb1abcbc3be8ab24af389a104a60d67fedfa658f7223528cf2a8c8a2995c11faa0c000000000000000000000000000000001229decc46e3e1d3752f13af576a7c864216fbdf5c330f603f78d8792a3c38bab42c7a1099a41e608ba54b17584ac2fb000000000000000000000000000000000b210ded3b6818b06d6ac8d2607d2d8abe2f8948d8b82f82648f8d9c5e097e06864825a6a368d9fe96b4fe2df03cc3351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171c7f718e6114701f2b7a11d4f3440c22799ed210cb725da864ad8d435584146a982f71ea5f2dd761d1c0e326f1cd5b00000000000000000000000000000000074c4eb5e88651c25eeb1e0a6959cb5773281cb43ce2012314315b754e359c96c454c28821d51f00eb8e0ec33e213c2d000000000000000000000000000000000b98d81e5b4ea53e613ae0c4a21f9d033caec152776c7f8c2a214b12588541122939b24b115422294541a9214d4619040000000000000000000000000000000019ac99459d70817febd9159a8734f58963473c4b12b132fb2e1c7a3b2e1ce6f13abbacee4ad513e6d1b0dee70da17a611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016674e3e544ce80f249fffa54f104487f01303683ad4c213db73e1dc4452499e338eabdf66eb72641ac8a24b96155d26000000000000000000000000000000001483bb945661c9d57f62915312650015607075075b3335a744e6ba005ac9fd0c5846a89bf375d657054bd25210e6e58700000000000000000000000000000000131843d43d526c1ffa234ba01e6f67902490a73578f69bec299c8252e1505f6efed28cb775488a48c38bf63e4161990a00000000000000000000000000000000141cfef8f8654c2dc7040676b24c8722f52f429bedaf5c945d71d661bad6671a35e61b2cfb43a8199d4071d25744f3cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663983693bbddd104a0b5ce420c872f3669ac9924dc28b25e2ebd0b09b8d9abecb4ce3a7454a5a359ba9feb68c82c8400000000000000000000000000000000015df74dc571319baf292b5c5ce44ea7140c90a5349ef3a17f06aaa3e2eca84f68ffbb0966c795a1c3256b3f97b4f9d8000000000000000000000000000000000bff4764b1b12ea3b47c20cb12fa6dc84184f5601bf37ede172c901a278aab456440a42191d8887d63d46136216b88530000000000000000000000000000000016d9aadb0c95e8162b3edbd5033db4a8757d66210f5fe9bdcd332770047627200ae1c87f45e7fdda1bbf252c34c751851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002991d4ff88e5dcc8a3da5b612ff8e67677529e44af8d921399201f356ce305097d11f62c427e455124bf4b3fb406d57000000000000000000000000000000000547a3b000e0038c69902bcb4185331be5512f7c3dc1d1b03b2e7a967cd37b2b6253421a422a874b96f11561aa9e9d4b0000000000000000000000000000000009332033579e17c5af88af7ff4bbf14008a7845f0831a4e33e565b06ad0cd562866bc0c8e80b9578de45522fe67df4790000000000000000000000000000000009845f21657806f7b3fbbe058375d8ef9c41247e6ea1ee6c0dad2bf0281e77ea5aae7df9bf29d362a384d674ec8fdfeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee973406dc581b232e02ddb24ccc01a284ef1a2350d324f6262f695bd8a0f48b2a1a1622e1e1e72d71e2c2bf62e808e000000000000000000000000000000000fbd8963f89e9bff2f3c1e626b48713258cc855140c1beb5a444585fad5142b3415b803e1f82975a47a0ab15c3d0928200000000000000000000000000000000077204a3376a937906764d1ab8290ba929fb020591bad0c926d0d8c0aee556b4b57f8ae30202f778cafe100e0f658b6d00000000000000000000000000000000066d43af5cba695f03bcd6bbe8e6f903e7d59a5e71bd0b97737bb75629dee3a709fac383ae45fcbcfcc35ff0e31ca22b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007c0eac8579c428bcc340acc15a0c520bf246c1c3e9cef2b9d4ceaf013643646251815a1e8f1a13a7d1aaa455c039b50000000000000000000000000000000005810a33300c8b7ecb77e5c52e0c40966c5167aefe3edafaf27dcb4ca5e0a7574b1e5359a046eaeaf00d4431a014ea930000000000000000000000000000000003fd8d60a61347ab3a52170994689df4a74692760461dff954f004697e377503b05766d756f1a24d9774de6db2d2cdcf000000000000000000000000000000001551c5c08c2a047f835a6482950fb31b93db8e0d89373dd2d206cf42dd421b4f0593b9421bc0cc1375ee67d1a3d5c15b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017db90497a8fee22fb0118f674aeb19148981276e2ddaa0391d31f7c9100808c491ea1cae6cc3f7876c75de6f88d7d900000000000000000000000000000000052b1c086e15d5aeb19f4cb9d701686e81b3dd8878bc3e15612c9ef17da3a2d820ec08efc3a0793e320028f11785e1fe0000000000000000000000000000000016131ad203c90e6e92b4580598cd42e2a8aeb8a3a48e3c89f71b37fed674a6235feff9a6b30836f3030411a2579519ac0000000000000000000000000000000013c2377612c9ee77ae26fe113b7932b79d62eec82ffc19a14a06c3f4622ee1aa5c394b529fcfe99152d6dbf148f415de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea0581916c62da7b0efea831ca102098e92dbc02ddfe38cd4244a151c60160f7bf60771cba4bddd4f6f0a851c5ed5f8000000000000000000000000000000000f0fe9a7f3487e60c776ba375e074425968ae1503ea5fd926d0514432e3b0d04105de98c9181d7660df4d6001924f769000000000000000000000000000000000a518de68b5d47f69165b861d2901c44c0963deb85d0fe84dc582be77422cbd4884113cdb9eb4eea52ab95d8c28d38c40000000000000000000000000000000008f0a654c24ed18b75851895722bf6f127d61c232093ad49e16908c9e0487e8c0f3b4c74b9a85cac5ab2a69bdc8899251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000137319b086088dc00207556410c9870a3aa9c0990c25b473170c1ec46e9f19b718bde81adadddc44d7f13ac0488fec0000000000000000000000000000000000a5baeca2e97b95f561a89ca9313825542610726465565d039a7e004241607a638c47fea035aa39a92254a4b2a47f5130000000000000000000000000000000013bc66a11b569689345bd17316d8a0e4d01f6aa9ec28d73bbc4f51d2d05d771e3c722c0ca782f8b22d39cc06eb8b86c20000000000000000000000000000000009c10117bb32e7feb8d17ce58d33cb74c4c2ce2601caffe24d1d74969c2749c2ed95063e785962e331047ca1bb9bd6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9dd59209c5f7cc27a789d47c7381354afcaa30ae6c066cbbf7538b9600a32c94d19f28d36bdc4abb6b54ba575605e0000000000000000000000000000000000e299453866df6adc6dacc2a334bc944fcee3d6b6f62c9d5a1138589bfd60529623f943f318148420b7788ec912c873a00000000000000000000000000000000189d491e56da3f799f409815988e282b342f42db6ec4d594b40bbaaa144ac008234d664d2c458be840393832fb1d785400000000000000000000000000000000105341369d7dca64970fe9801bca580041421521f38064d6ade2846e1569ec96c6f4e89db9b32cfae29b4834f9145efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0b6626a2d05ee2b9a7852f9dc6beb1cd7f13a024b542cd6fcd01cda938b0cd80dac458b2c7c4590e80592a02760fb000000000000000000000000000000001171ba982883c95c49bacb8517c1a74bc3b887454e3a07c981f94aabb040dbff89b108a8ce2b8f95327e655be3ce822c0000000000000000000000000000000019d0021d984f4d1089ac5f3e146d69c4122f1c721a15b705e434ebefce3637bf80599a8060a967b8d0a552f4f0cd7d6200000000000000000000000000000000090a63ccb5d8eaf564c66c60d89f4c4f04171a36d80c449e5c4b9352c56480d55caeb3e3e3d657c60332fc095af65a7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014026585d15143719a66cdac1abd41fed49bfa1f57af5213a863f05a38541c591a675a4c70fa9a734bedab87e61110580000000000000000000000000000000006e94359d2d9fe706639c87e7fe357c28b795566d5a6d34802b6d67b9c5425e3852587d79ff096a9cef6b220748ee6cc000000000000000000000000000000000e732efe55cd01508e48d62d1115cc4b08eba81da9b80a3e51950c62411330d5e209bbfdd3155593431a98b1550aec1300000000000000000000000000000000023c7a805c284b4da5ffc03a8e2548354b4410a95662056255874c34d43df3738277382782ccb18e3b758bf6805bad2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037864e3243d6339da3bcfc5727b2b62f6b058dd4a60ac852a3dc3e23b374f9be8e7d6d36335cb23eab4a734a90328cf0000000000000000000000000000000002f8dd46f8740f1ef2180a6008383e4375205f0bae3131f899e97db31b3a89fbae51a797a7dab4a86d0466ec0b1a89e70000000000000000000000000000000015ff95d0320c39ab2531ec0a3ad1b62037ad05957e1b2682eef2cf314ea11fca435c4db084f4066ad99eba719bce762d0000000000000000000000000000000003c8d4dd2360a3a994b8cb7910f47c7e6589bbb466b1762312cb59b1f2ce21c6ae15a09dcf79a8eb376c40cf669cf7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef8979cd77124c9d200dd32cea1a5135e5926e92c8ff90ca5a2a3450429ff761b6c5a53bdd5db8eb4cbe0953e7184b0000000000000000000000000000000010c52bcbbcfdc032fba992ce7774640efa94e0a54fee0b99cf9a58664092da94decdfe001d9af89bc18fbea0e1a9153a00000000000000000000000000000000022c240aa672cc3ec13d6d5602d98a36c1c20841a1eb927e2656429fa8dc8af7057e578708bf12ccac5e764b8f5f75e100000000000000000000000000000000044e8e9765e97d5c2e095c61257d8feb3d93553dd81a9e68a5d07949f5404c10c5a45c20338e1b78e64da0279a11bad71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f838227d011430e8910af9c92e59575581a1d34ec13c8af8471a8615f90b98f30520d630a3186da05a2c9df888b28bc0000000000000000000000000000000007bae9130dfb0d74e596e0f76074b114fb178e98e0ce5ba51ac4997684a068530e629a0665d291c92ea99fe29f60935d000000000000000000000000000000000b553caa1d3ef68096226385370ee4ad5c740086ffa3e14095d03785969fb54a4d34e217657d921e9b99985451b751450000000000000000000000000000000009ef0ae1a7a3ba35c27b0433057d39e91a37a86f8ac9a528c9692748b5bc9fd286b921829a224e50c070626006460d711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000034eb2384107b8bca53812d6a061667fecbd25a96ca7b579a71a33acea69e6abc4f0bdcaff5a7c8b028633ea0bf6fbe30000000000000000000000000000000014585b64a280c39fc81a1aab94bf2ab6d89c2e6c883b174ed948be878a442c5914e0ff771865a1fe78cc2253f2cfbe5600000000000000000000000000000000029341146a0849b22b8b88ac9e029a7163176d7d3ce90365281fdaa56cbf5ac1f2ea42c26c29633798f27faa8b0c5d78000000000000000000000000000000001211b75613bac800e4388be3029b520562786925e379a06fe76ec4c615d1dbf25a7e221ea717640d11ebe52d4c6fe8c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069352e6bed45c60c8e201af87d5715dec3ffea9989e291faa1cdb849a3f51dcaf58f872b60319c69db9a4f75a3194e3000000000000000000000000000000000d96171c074d1039795985de56223820ded34425ab4a0b3f622001aa5b8372aa97bade946e80a579c3afc66937f12a61000000000000000000000000000000000d57fa895acb5faa49144c3d5c9ec5193e6a243b905d9a97c65a42a4d01a2ccbccc87695346ae0e275460eb2a41df8e2000000000000000000000000000000001797725e7fdf649d587c72bf4a08f8c96b52b0f3d57dd27160ea120ede9252998735c92b9b6aec0757a19bd1aba961a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd9abd6818f63f9f9a4623261f8adf87e2110058b6934b62c1cab026fb2072edc748efc494036090aaac55c8ee93eeb0000000000000000000000000000000012e78acdcbeaa0d996aff35367f2a81f03398a09ab14b6250c7f0c119d566b3a05887ef1d709ac7a56a2a0486e38ee22000000000000000000000000000000000fe14ca2f5b594450129d97900a680dc021cfcea0ce22037c8446209e40994a05fbe4aa312c589a008ef27470c7e2453000000000000000000000000000000000b997224e72a651a8b8c4edadd8a6c2b8805087e0f30e1f170686ad5937129db47840232a4f4b7de92c0dd3b7c6937901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e37e8a1962fcf0d02112a21666bdf1fb5c047bf2571714159717d693cb5b6d9cbca40d91100410aca6bc20c4719cef0000000000000000000000000000000001ce0d6374d0d265edb6a731cb98e4e0729d21d6ac5d34404a9e1b761eaf8ed1f567fad3e67cdac197c9a2812296d6a90000000000000000000000000000000004432341d99d0b52d58643f547211a427788722497a8b78dfdf1cf54e42d17e26b39f33834fa9466ae1e9ee0a337f5010000000000000000000000000000000006388f558d15244f910ab1d23b1894eba3182fd2588a2c792d530431da4df31389c0e3b4080284f075ccbb34bd1c8a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112250d2f8aef73c7f90f94404af5cd8b335f75caaa1ad7981d93cc065d4f7f3020986e8a59735a0a8773d255c93aa0f0000000000000000000000000000000002100ce50ad29ee217a9d9bafd5dc4bc5c8919b50dd1c01f005339fd1734a39a8ec77542deb5153120ee044cb7114874000000000000000000000000000000000e19f5ce9e9279d7ad05061cce03b47a502a036f81e2d228611a26ff25da7e9ea47203cce5a3c1f16a45d2a96c20add3000000000000000000000000000000000418fe7a1ce837291072f043d6fc63407c0ae0bef0ece6d100e5a90cb10d1a2be1dcfcd90f332c61a28a238907ed24741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e30fd14206f5b6771818deec255780c9b255d079f43d1adca5654019bf53b98f367d07bd9786580ab52c482cc60bd600000000000000000000000000000000098b450b9d1748fe62cea279fd36e830367ae22760f53b8a8a70a26ca6dc4d4c853bbce7997eb240a1c8b37c0bbcaf4f00000000000000000000000000000000152ca0c0f25a88750ad59b07a8af8f394293ff7bec218b784cf2082c3e507bfe65dfdea28ee6dcdd570138e6dd6d8a27000000000000000000000000000000000b044765d7339c0e7e915585e9a29d21ce4866267cbe81261786f8bd4bb0f92cf625dfe1522f849aae215ef3ea67fc221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000036a95be13aa6bf481f2b887440763237fa52026f9710b0847e0787db4e0e452d5f8edb0c1e891d1d3f22b09550863200000000000000000000000000000000165ad369a4b9d1884f1361a96832404021783e8cd01c629462c91b342721bdd5f78d9d8ab395a2d20e23d827fce5306b000000000000000000000000000000000fb0278d086895488935464da4958a87b1409d0adbf6b70440e2896e0d848f783d2760bad64e505196521063f25facdd000000000000000000000000000000000d700621ce274a301b022b0054a95e07f94c4624c2c6ab4fe787608bcc8d285bd102b42caeb26c5efb6e182d191cab3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060a719d92873d4559f91786d235a11c5c9555a10fca4dbcabc5390484c892e7a36307ac9dc4e5ac2c3832f028ba23a00000000000000000000000000000000013d318a9a73d487ab956436611b853c2d2a37a9b47265b8ffa5c0ff61c114919b405d7ee186a51e1cb72e90d59225bde00000000000000000000000000000000176b5f52b45c3790ba81a55641a585322f38a3b6b382bd2fff844079f16a8b85d0e55967916de253cf7124ae6813478a000000000000000000000000000000000ba59d5f9d5583bff1f545454fb3e8d8d7f51c409566cb34e03c8f9523ef5114a1c2470f93292f29a81f403e67435f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e356ccba886651e0551493cfe83d83f9ced0c818c6bb36e5775aecbc7f4a6f774b3fbcf005e13d66798db3e1e47bc21000000000000000000000000000000000f3fa355acedbf4bc5eaa555f3550a8bc88f081e00bc868976b7f3245e3241621f5a80f6a673a00b552859c341f030490000000000000000000000000000000007c542aeaeffa48629ca01c2f804f3d5aab46498d2d9355dea04060a06ee2e3999fa26563b80cd158cacfd439e5afe2200000000000000000000000000000000112aacd15490a9aa6b223bd3ccf39ff1fbb95e3e2141aa3110c508766817616f15174d358e41177c1d2eeec2cccf2efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dde5936af03a239f90b09583b58126df16ddec8398a9f92a70dfc96930041e4c9932f636bda0c150000ce12eee6d340000000000000000000000000000000010c2e9ddf62fb4a6c5193b95bf83389d48801e838d017697566c74cc570b6f49e0088a7c07e8e9c8518137db572d814c000000000000000000000000000000001710029c0a63921bbd7e84854fc55919dadf4951dd83791fe9579672bf85c885a545f4a72646dcbb96f40216850c33ed0000000000000000000000000000000006ae2a0a0de586aa6b6d4792c29c2d5dfac28f532084105c497418dd684119a15c2e9d12b9e9d831f23ab7ea40aa94571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e153d7ac9d57a2054b9d68d824d54935c4bc8384a2ae8f2f44b71f2252608539097bfe7ffe0ed1c99f54809c73d0240000000000000000000000000000000017670f813b6589cfd24a1f3b5cac66c4065bd9e18e334cb4ba90216a31381a7c91133608a9e9a853190a5e1f267bdca0000000000000000000000000000000000cb3aedbf574b480d4c5c623c9c303076961c848c128a0d1260ab06a05c9fc84d968e94bf531b837dac766cff3ba6fcf0000000000000000000000000000000016f465087b927ab1fbc557154f5e785542f08f16ac614a47cfa9ce3a18de62358ad7b410590bef069e605cad87e490961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003699d395733bd61e2546f5314cdfe7fb8f2716c2a19c6333b875bca03c98324b4203655c1b6df3275d76beeef59035100000000000000000000000000000000068a43b91a3aa42af7980e51eccbd85bf1fd22b37ca9efcffd3acac62ace0854107567638e120213e89c99b5faca19fe0000000000000000000000000000000005bc9a4edfd56dac254cfd76bff4fa36a589aa3f1a879976999078175882f5781b4ec596c080dbcd79a4db507d01676a000000000000000000000000000000000543ef09229b5d7daa99c7a191e5847d530d6f9806570eb031a86c48fb37c360df2eea17b6f3b0faccf88228e90cd35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fc451fc06132e6f2be9a4f6831b1a3ec17c39e5f9433cfe1b16f376d200c06b5c2c4d4eaa520ba892b28e8805dcd5200000000000000000000000000000000012af42e1fae6850c0b8a34542a914f151d59028de32fc8f593ab4399cdbbe70816969b78233861bcad080e33d56021b0000000000000000000000000000000014a64566665979313aba10cead1bd0f55a7c871a0c9a4184d56d28ecf05597e956f4a3da52ae36261151f33d3224da8f000000000000000000000000000000000bcbfaef9a59d14a67fc9aa7490a897acc087b8ef06f8f29ba8b74744ad7821d088b7ff135bcd6419fc685b5d19f43c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999080b99dcf945fcd23bd1db3b4269800465b9bea3caca496ac7323304dd4f490b8d56847dfc24e9198a9863b479470000000000000000000000000000000018c39709cf0d94730f3bb0e391293b8031cefb7e1b7ef8d3bdca427210f480a9cb84db80fec0a1864d5ce3b76c19da520000000000000000000000000000000019175f2745d381c285e7bb7efe9c4a605a2e148c796660c9343da686d11bc5e2b62b50ae438d0dc8fbe34a29236adcc70000000000000000000000000000000004b449f730dcecb2c6fa2c964f6d8de70546506580e0916ca698fd8e19ec920e037ff4252fbac07f944fc6983038190c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001892c6be68fd605a592f219d3f80280917d4cedbccbd146c23efb3a8a71acbb78e5ae0aeb9054837249a3ba62a9e5b1e000000000000000000000000000000000d083f08561c3abad5f17bcd5307057b7f65b0ad248d9ffe6b2166a0cbda68cf0657811171d9e8e36ec7503aab0850a40000000000000000000000000000000002724edd9374e87bf13bee0afee2a79e9ce7e7146ce7d3a0cfcdd42a3446b62d44027bfc5ee7b532212af1782ead22c0000000000000000000000000000000000a74f0a0d679dc5b9164e41a1ce76b8b455cc96e0386efee40cc6375d2e8bae5afad2081fa52794ec3d2326472e8004e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e84e2004d4d0eec01dd71a137d210d0bafbec3850c458b98ad4fadabaf85652f80fd47835f8712212db05723c7d1b3000000000000000000000000000000000847ff35f58aa2d76c6185a8cf4ce21a35edf4e2a18fddec94043f0872f47fb661a305114ab9593980a9314afffc8aa30000000000000000000000000000000003610ce1dc87e416f665b629a3f4e979426645005a24acdf719fdc1e21fbb13c0117c1aa43d2782f613af0956cbcb5db0000000000000000000000000000000000075efaf745c0d382156a2f346119c40db8b16d89210e0552481902ab5ec3da708254a559387bfa262c467c0948c9041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a55ef212af9b7a931cc9861c1a0a401fe34a3ac5b15c0ffdba249292d5047ac24c4d903eaad924054cc9916e240a900000000000000000000000000000000123c6f2bc2ae7a22a44826b16498333fa980d4644f5f5b6e1234aef2ba87886f70f1003dd19a5ab5289737430c9daa500000000000000000000000000000000015d755742c9dc5fbf03658f729e0c76ac4a2a7ebe715ad3de9216b99ffa7e0ab55f3bc70c14fff441f29439beba8c01f0000000000000000000000000000000010a0aab9ae64618f7715972dacae1fbef65afc26fa056264e0a77a6a070751d0e4285b5100641b2d5ba35341f9581c371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006aaf1eb1774dfe7fd6244c369b70be72772e83e861d3e7b3e486174a1976ac6d0cec7da0807c9d7c4e3e802775ffabc00000000000000000000000000000000117eb9c3494e23ecc147f22f91e88578cdde99b0255be8c490fe1c5b10813488fc88fa059f0957536817b8dc8a97462200000000000000000000000000000000004da6007f31527853841593d737b2a3135126ca70d229d53ba67bc0837c45aa07f787aa111d85aa90cf7338ca5e2ec00000000000000000000000000000000014a3fdd257a31cb26dfeab9e69b92ed7eeb45a3f88dcfe111b6607f3b8bc8a120998a2698467897bfd1aa1e14a59f5f21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db90e94a8ac25e5e5b7d46400c578c1b8157d615e8e5f7c1fbadaf834f3f5803405f39f0c55ceca8b40134eb3ec736d0000000000000000000000000000000002a48fb6311bc682ee78b9b79addddb6339563d086976489bd55cd92125819f67033a8e4d7c76bd31987a6b0d208416a00000000000000000000000000000000087700c640bc9db46906be04caeafdc663111fe7eea167a3a9d1dab59e1bb0e018150d1dd0a9ba77d14419f92e6122c000000000000000000000000000000000198e9f2d7cd6d84f73592464240389fdf0414a8e17bd0cbc522b6968bb8462ef1f5fd673aa1a939f0695839c6014093d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d49f6c2507386367ee39679c205842e6b3dd9844118038654b8d8d9939ac2e18893a3224de878fb048a7529001472c30000000000000000000000000000000004c572bcaacaca048d5512bd50f9cdda833e190db49909b595ece1ebac2c2ea74a385e8e0de575974c3586cd5d50faa2000000000000000000000000000000000c752eb08309a190000cff1e5cd6710cdd15025534ff8fafcea4a80476b904bbf4608a40d1ce0548a3151750f2b40bfa000000000000000000000000000000000b18d25ed1dcde57a7420692da140807079768c202af7aa185e91b597304aa1b60de620b382b7c02c74ccbe4bd41d3af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121bba2dce6e02380fbc6c77fa80203323289c719e30a11f913736d496e4dfddfb2e0f5ddc4d56a63fa8b8b46792e283000000000000000000000000000000000233223b9276480014498120031e9ebd475260cad0b2bfe86cdba9965bfe0267b870e8c9acfd7be572072e51d5cc2b23000000000000000000000000000000000bf57af59d2d0dfe08675b6d132f24b74f094024cc162c0c7a4bdbdcfa2a39f2415e39b4cc3de5803f3d8607858b535b0000000000000000000000000000000001004172ba68e2c986f2f988648515fdce0679cf2eac66962b31b1929d29e34954956a8dc385f2aed9245567ac52ed671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012474dd50283468810dbefb6ebfdbe34fa5a550a1c39b3990155b176d6e2ae99db78a149c13996d17d0e987cadb1534c00000000000000000000000000000000155e61116bcbbbbd02bb1c4b70abff06e76214be953db7e22a967ab573846ffd6090be688b28ad7fad4b193ee0149f630000000000000000000000000000000009265f830ce88016ff90e50021e4c3b68ff3a38ffcd566aaa8b515668f0c69b16cf6c2fc9ce00cdf3fe0ed15971112a300000000000000000000000000000000013a8be1851741ec6e3c11cadb2287d63e7fd5652e5d7e2d6510dcd1badf036462918cad4247b50c24c59a963222f8811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142be69d657cc54f8a08a0e6bf68030a8369cf84ba2e1127275d5df5f0a1520d532b5126e068ce5ffb4a025f7ce48dc6000000000000000000000000000000000b35abea80e1d5ea189bf2776cae54533d3e4cf521adad0342a3658b200b3033f8b02f4f4ef98a9435565c0f77f6befd0000000000000000000000000000000002ca8d5af9a5cd39fc83fb22def43a6acc7aaa6cb518bc94cbeb1f606d738859ecbc71eac72aa5e63c54eac5c2f5a6600000000000000000000000000000000003bdc3a4f0c7bf0a80008ccd90f183c27d24615e658ef9ccb58736e37bb8bc8011234200fb6dfbfcd78e283f95fa7b841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8567915c8615ce1ffe4e686063128b6df754165250b0ca0ab8f988afca5c4887edde4e8c3b76560149874f834f057c00000000000000000000000000000000185ecc17ff65406d306e845e634fbd47e9d14c819cf5e03d8f8d689e3b84423a36b620db73b4b86d44fe5a29b21af57800000000000000000000000000000000168d01cf433fa1b4a6b1aa9f5fc094257568ad8782b60e4cb7773a0a84420e08d73d9b7f1dde5a9ef1eee07be1d3a73400000000000000000000000000000000121ceb2b2a4e347296de32ab01cf56c6d6022696d7d896123574e99350849493fd9794532ad391ce4234cb7362ca7ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000664aca6737b5cbfcc7c417a9a72ee73624c0a1a9746dd4b610c2e2fd7454f45bf02187054b7655c2045f34395c881b7000000000000000000000000000000000c4287f903cd0d6da4b5405da626f9ea7b02cae24c4315478ef6bfeebb666829aea8416a721e013a46e97be6b73448fe000000000000000000000000000000000ebe121b457bae4f35690ab7948201787ed6640c1eb6b94f7832fdabed91fbba9d24429239528669f6fc4a98b27b2554000000000000000000000000000000001230618fe528e07b5159189cd14b3499f69abba5c5f2fb3e7984864284030f632bbabc6164e257f49c362278237f466c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cb1b7008f8ac267de74b57a3956b60f100fd23904288b908b8c7c402643271f46dd4b495f6a0d9b0153900f4e7636e000000000000000000000000000000000e1a3b1f5223a66de87c03b9db92f829a0130988e7da6fa6f16af0ec7d7e21fc521f1a5abefbc562a7233fd39ec015b30000000000000000000000000000000002c44b67fb1810182a3b7bb9ed724c81fe4d77364b93183e9a3eb1252fde901138d5c214fa779d7578b6381bb4fe0694000000000000000000000000000000001385220c4c642d2e9be54603f2172d51d3ba516db05d1e85a98b7382d1a9a8b512f140c1cbc777f0b0e7192e30bbc1ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a7146f5a2afcf4acd8b0a4b888452e920fb9d6fae64da31cbdcab803d2b3f86f53b9fa5a6f25d1de4848eee472de9d0000000000000000000000000000000015c7062ce2abc98384adc6d78eb5a31523352dc717fb933dafebdbd4b850a59fd008e1256fecf37044619185df9392d3000000000000000000000000000000001682065104919181ed8ffd2ab1b60be876760ffbb047fea1c34e0edabf035c47a4a15be0c5af4829d9502a346c4c96e20000000000000000000000000000000010d87c41226c61c47c0a09a67803d2bee457bf1e0c110a8f52b40430cd201d6281feefa07ca3cfff336363cf2cfdb9ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000939e145429ce755135aad7a3f7e5dfba0cfe204d87cd8aaefa295560e5529319fd033dd07db2a783d8e9047cfac55410000000000000000000000000000000012e743a38a939caeec7941acba1fd0d18982dd2217906b9029dee933f3b55d44c85b49ce8279c58742b0b3b3e631bf560000000000000000000000000000000013c3b3ebf45fc33ccf37dbc3e88f8bcda87c1eec33dcdb2115640a7398114993a3979d0ca883f96345fc844054bb34e50000000000000000000000000000000008c378d2a8566e416cfd98edda6f73ee8f847c647c8c459878411d564c825d330f725cf36a3de497b7e05249abc8e7291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc651734d4db0303a9e6878182c17da646ebceda8b43366a74113ba1aef62f38d0988739c7351624030e7e8c891ac3700000000000000000000000000000000115de0caea2b1d3a168d4b1e89343f5db4bc74da8d138400f3f4fc432c7f732ee089593a192b9f56d5fe2d15b89b727300000000000000000000000000000000016fae4f4134937e909747adcbcb9ff0dad282fa4fe32f87a019cd3bcb9c6b266277cb858aa5aeb9230cdcec4250bb45000000000000000000000000000000000dc45d58ce36d265f110d866af1f4e13cda3c9076c8cc8648cd40738385be64beb680feaf6e3158edae87e19a7e96f311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5d0c277b597f86c5a0e2fb0b3da8386f409d1935f3e2b5a2e4d030fa12247c7d33459e4f8641780aac84c75b96f58e00000000000000000000000000000000006b9e66cfc126e4da7f39093ecd1591af77cdae13131d044eaea775528ca2ca7e64065c375edbae365f5c6fdbdfc055000000000000000000000000000000000233cae1335c93c5727f63ebc33d488d39d5a172df4a7f565b72e71db5eeefd6468746b969fa3895daef15c04c9de4150000000000000000000000000000000009fd9c975726c3c99ec00adc91124a93bc886dda37140eca2b492ae640f80e9197548f748a3ceead795446ff21933dac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f7942ca574d94fb5be40ea228e52a4a01f657fc09e8b6a7d42ec700b0fee7844662f330fbfcc31e9f2ee7dd7aceef700000000000000000000000000000000090967de755f84727dac7b24e04095690dcf52783e5784ad1419e7c2041a20ef1d97cac3fbd39f87a588cd6da216f6ea0000000000000000000000000000000001b3c4ff74aa157004dd3dfe52a7828825579098b77e5bf57bab7df8158303ccc7d505773014e54e574d1ded3b038cf10000000000000000000000000000000015b567e838e4fb2140642f3d22df90b384364eeb7db835725c03bb1d8ab0cfb84bdc0de9e0598c8a91c40187aca5366b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001027d35a2a426ef27e5e755e8d3288cdc33a62e6e7e614cdd8cce0e4cb8995966a9bf06d649701e500d683fd25e19d0000000000000000000000000000000000ed67981993e50e897d5f8a6de7f9870ffe508958ec2e1b6606139d478253fe5a5013deaba8a11678fa91d03d29257cd0000000000000000000000000000000017648aea20f16940557f5420a688e547696e58a6c4cbd665c6666886eedaad7f9e6db67f16722d3bcf8d261a197295e700000000000000000000000000000000080cf4d4eeef4eb7f36d3cf312b4ae33c4182ae0314d4a4bf0c76e1a6db03faeb3c4682c8cf6758a2fe635b9aeda6cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000736cad24713b435111346b91659de945ae352904cf3bc5e4e8cf2b58b0c33a447c48455df9a9b76d0de8926d693f1e7000000000000000000000000000000000bb1e1f0eeabe97ea3fb96c1719585dd63343ac84518823e14423717ac8ed123423e8655085704a02d08b885aaa2f6940000000000000000000000000000000012291e706597cf8c33f09830e757498363532bdc3a479f0788ff8a5626da24c195662f8162079520f22727386e3f71fa000000000000000000000000000000000bd16d235d99633dd4519e8797e9d26f3e8d3912123d2cfdec3527ea56b1675d7c5592191448a0f1ab2019776e370ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123bab130acec842184f52a8485f83edc8e89d6982df2eb4dc5fdf8239ad41d795946c5b10e431698ae2a9ac53153397000000000000000000000000000000000abc22fa93032d6a2feca0b84e2a875d6a88e695de41b8ff1c65c76d9eb78c2b5590bf891d0b45e5f887e72032add5b600000000000000000000000000000000164d4bed37ff4aac1540e7a11b3d7673567cfc8431c9123417c7f8fa276083136771eecde7f896c18bfdaebbc004238900000000000000000000000000000000168cf6222f7dcfadecfeab5ce2d4a6503fe77e65718b39ae8ab02e2f75138419be60775ed908c07772411c1dc818d8ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007bc952dcd24b9c4e1006e3a3e8ceddf5fd1ff7ffd9c6af89753866250c9882c5fc1c0b9ad69012b4ca6b5e7f593d9400000000000000000000000000000000019fcbb31695d18eb5a64dfe2c3ba575da2cf2393f3d6e66ec201bf5c7e904b9f70a25e470ba16f1439850bdd173a3aaf0000000000000000000000000000000015f534d3a7331e1ae6d34f13a87e0bba435d6a674c56221220de63b428fec59649d5c6247963b7bc3583efdd04a17b3000000000000000000000000000000000118f2c13700ea22ffc79fd7630c933496e02fc61dd4465b549bc7ba2a21d02b2c08bc37e12eacb6da94126beac48f0961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180ef9a99379b6263c44129c177f19260a976ac05ab80227b0bac04adbe82f968afe56e39366695cb457c687e122e62b00000000000000000000000000000000054d15fa41a774bf1c99e1acfbd9508bfb8f44b155b513b871b519a70e535977405717a894af1c365cf95bd14ef09bad000000000000000000000000000000000ba5b049fb05eee77bd071d6da31a87a3871ce21f4c2762896a2990384466fde12f820f464c5d009b4617ef4ea04ec3b00000000000000000000000000000000161bae716290446d85e89675d04c68555fecd0cfb977d6fda4a9d5d61e15a520fc333b52988e98893a8155a7780eda761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b8e934e84219047d9a620f5e9632d1193ebaa7d68194d80944ce9e100b9baadc8001572d8a28e1dcb0f450527a2e890000000000000000000000000000000003bc0baacc0e11cc545fe0bc5d7a6c8827f6d2f5594310132badf2aafd0d19d6bb6b9b24d52976c81ce182ee1e59a319000000000000000000000000000000000208bd3f0e94480070900df3951f8d95a759ae7b569c1aa9c1755abeda37ddc567ba94a9bf45c7e9822e3b8ff907843d00000000000000000000000000000000098aad8960ab71bfb8619a8c4474f1ae28a48c97e9c614e0888be6c84555cbe0c030f363b55144fa4c3bf6c16e16e7ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000510699e9cb214b57dd894d926506d76f760362df745356cde004a1241221c3c5f954306e18869cc020cc1078320ece2000000000000000000000000000000000fff4f28847d8aa4e965b6670645e5668360dc1dce32fd122712f308a70de0936fdbb7e455f3b24cd0213f9b47b01ada000000000000000000000000000000000b51490480457f89dadffe19b0c03e48ebcc20f84c027166ecaf2ce09de183efc0628479068e2f3fa929fe21fedccd6800000000000000000000000000000000067fe13f7da4d53bd158199af2981760771aa311eae69e8870030a7aba4a38517f1443d2780af9088bda0533ca74da161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012e45d4ebf9f9b7aac97334a4b8782f522909e05c9ee7588503c64ee3774c40f53a91f27a39a2fb7e28b58b9d133cc8b000000000000000000000000000000000083d2c1af7b5c4190ced6fb566e85e33b274cea7ab3c7fbf4331b46d09be788c696ae1af1aaf050d91044c47fcd177e0000000000000000000000000000000018d806607a6abe8b31bd96b0a34dfff83e66a9d73d788f0cebb16a6cea1f8a451b2bd30a88e648c7ea00ee5de1f2753b00000000000000000000000000000000102b23d5d708d17b4fe8e0868b09ad9b7b37295cc2e14b1c6ee4b5c4ab4af33b0f99ca4d87de38385f35f6630b7ee81b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ec23e9c4baf84b672be2ecd4db60572da83a3d4d452343e6043921a6ed6ec93fa2d6819945606c086ba9ee03998eff00000000000000000000000000000000079177a1fe610e33cf8e37512f71d8bd80ef53b1500889b50773334b3fc5a61417136c5a4fcaab405cbb1bd7c8fb30650000000000000000000000000000000012047c7219f9af5f30e68abddbbce22e6579f2074512d796231bd5dd9e058b0bc16ab7c4162b1f97300455bf6884d8d2000000000000000000000000000000000319ce6412427e20d85c6e36c365e1405ba8fdb689d550fddbe17d3e8dfd900e76182a6cd02617f7edcab84e4bcd67e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9a6a548753c33dcedf77875a0e8835a41c1162d1907d59ccc32b85975c6c1a817fd6315727f21f9175fddec0ee28b000000000000000000000000000000000062a50907dfd0b1d441d4fc73244605e2570483afb608d1632c80fc30144e4709c2d55f9f647e9b09f7b0a3e5f5bf23600000000000000000000000000000000168ffa81b1ab744e941f04f446e9a7b29e499c8dd0d587afcd2c1443a28fe2ee42eff13d00096f2febfb556fb758126f00000000000000000000000000000000189d3ebd84691e001d40fe2fdbf35f7906ff43d5038528eb907e2feb1720fe39a9e37b83a896e50d085e1a4bc4fb954c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008258d5ad6292657fb5f7c661bc61dab6b59abb466f85317fd1b765bfcb2f95c5edb728beabe8ceeb702a690765819100000000000000000000000000000000011c735ca7c5042ef18faee3d4b26886741f25d957e3426b29c706c64f285db9688a9c95c5f3e27cecc5416d45442b3f60000000000000000000000000000000007ffdef518946ed28c840c1f1e4af58c25f6c5351e119b46fcb90dfcdab41111ffd2d1f8df3144436455d4eea6da65960000000000000000000000000000000018deb3bf9983a1fd937a296325945aa34e06cd507288a9aafebd940f5ef6fc1caa2eea0d0d8d3e51bcf822b6be2fafb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005425eeb6220b311da9fbf054aa48924e72b58ea713ce540197bb909318b1cd259a051907deb6287e24f7ec180ce1661000000000000000000000000000000000913ad2ab88cce183a0281389e3c5b942bbb857ae2ddb18227335e3fdd8e7f6e6ebeac3bbc4bc6eac4c0b12ba31c2634000000000000000000000000000000001733be13a4a6aad302fe202b2b32f14185a5bc6d5bfac1005d09009b45bbbd1df6c6f0bbdee5cf9354f610857a312726000000000000000000000000000000000a446de1b1ec697d826b6819f3ccf8539f973410d0cdeb36bd139cf24571bc20529e023dce524fdc39518dba50b824a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95827c95d52e65cd9d99a0b19fe20acc27dadb3f536efd4c6124adefd9d957246adda7b824fae8df633ab7aaced518000000000000000000000000000000000935c4e890dd6710dcc178701a3e8680a3f4379e362427f6ea4a4a08cfe05f5a2e85d099a0dba81351b37cba822e898a00000000000000000000000000000000183e8a2562d8356d312c36313e7a2e224f3b171f0ce6bc652843ed3d5abf5f4f87272da0008ac65cebfcc559567a62810000000000000000000000000000000007e5e6df50a1f7a395f77ad166d205ce6640f5a3c47afdde1b70ba07eeba34139607aa4763aba45d82d1ac7b95783e931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000301dd736cc81ac82a330792e849992d1b1914abcefef007da494b3ee3448bee05f103f3112bfb4e7c200d9d7c0e8e7c0000000000000000000000000000000006e0f298abafc46146e65bc7f733c4c161a0fc9f7374517438997a3f0a583da5282c43db2859639cff7ba9c6eb664e7f00000000000000000000000000000000097b16c06bb885675cecca2bc0413c9605911ad7a32036e9ed13e22d04a9f139029cdb5e1cc9c19c6ca408a7f981bafc000000000000000000000000000000001142cd3bd1b89020c0afa682ca407f71440cc77a6fdf9f88cc19b134bd904c008b3f13e7b7dcb0fb47fdc78ade63e04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001553412a755ca7a354b4f14c670a0d4e41a2989780ecea16df3ec4a06071c5b7f5f4e2aa9e21a74a8f8e9fcff0d3df800000000000000000000000000000000006f91acab3f3e47120804f6fcb8c01411636b916f9811a4bb804ffbcd084713e6135a80a08b6c4ceeb5f1d7e9282412c0000000000000000000000000000000016a3f21943570dba5068fa50de758ac895fa9d5b1034a2b6e3c6b3c3ac8482f9d5e3e5801092f7e5d00858c3f209cf2e00000000000000000000000000000000079674dfd4eb1ef4caef2148e3a632482e8f9452d4c21deaf4a543fb23d667447e4dedd02838897b33914bec99554b9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000999e4e00bf45a7d30faff2fac3140d30ee40881c0fe49c765ea9f817f67f2a97d07f6a51a3f01444eb661c217925f61000000000000000000000000000000000f5a0b7c3ed1634d4aae86e6fa88e2ae8a908364a27fe6d1e974e33ed0c22b8b0bcc8aa1b215c909a3bacfeb43608cf9000000000000000000000000000000000df8c7c8a0d5b0cd283261e80deffd88324af393b3cd65ec7f0d746d6b80c7d6d0a9ffa5082de7d159f89a4ad5a25022000000000000000000000000000000000aeb8da0e7c5760193511a00dc7a24e3f403e5f9a158f2470553377a4f4824c1554d274ffb43c3c44ab72449f045a6c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e60b03df5cc29e90817908897d7fc4322e968d333906ae688beb15a71e5feede0301e0959ac98b9d86ffffccbfcb104000000000000000000000000000000001555da6c3c96117075531a1d3c8fc3fbe8d154ee035135ca3436fd3913aba3537531a1038901a4b31659c694923351e10000000000000000000000000000000010f1426df0ada5b3ec79137ba46446b90d0c1dfe1c3e4d87d2240088f698896a046abe0c2043787c7e36120c366f39630000000000000000000000000000000013954acc7a990a2e35a43eb1c508a98f7bbcd153a3c29c9b51fae3217a01fe9cdaad543e3c4a9dd849937336cd7edcdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000676e2c73390a2602def22d9239af9df7029965346f5bf62e40c16f2303a3c1aa7ea8ea3003bf0e7557c72f77e2eacea000000000000000000000000000000000496c5fcabb30f850c7f31f4be0847d597aa74bb30c0c13f26426d829ce6df0658564a1d0f06e1bc81f74bb111939f1c000000000000000000000000000000000795f3de7328773c9560ff55a0b96cc08f3ec305735ec3d3c789447e1559eb4e74072b31ad071e3a7322c6e5e913fdc300000000000000000000000000000000174b75fc43cee85bd5b702775dcba2e7efb7e01dfdd1d1a980bd1ebf5067df28d25eeb84b3b58a62cea9946a48d827b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000491b8431a72e3e3623c94a52677980843e95223b965be0e62365201dc949f61ebd06c6d53a4c6e948a8c54df151fbc0000000000000000000000000000000000312afbcef9ab0f503fde2acd9404c3834e3488d1781b1cb9c02504ba5a140421b3588cce9e71749eef4fca337af9c190000000000000000000000000000000016e9311dcf5f5e4385e01bc1aeb15e80ff4cacf1f404fb98d184d65dc58cd2ac117627b7d2ca01b68666b62bdb401b8d00000000000000000000000000000000152b69b04bbfc6698123215e3580df72c60b243894786243e7ab161c3ec1dd66ee9adf02512a7b69808bf917437890be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000117e4631d82128c697f34ccc504fe19d1fecfdbb1c27932e798e881526699c89fd616695868cb5eb5aa812773bdc03a600000000000000000000000000000000118393f67df32c5f4e300573cbeda3d115056163b8037e49c6cb67d5b7e614f74840b10f11300045d5a2bdbb12bf5152000000000000000000000000000000000ae07a0ac493daae9abcbdc48b9b284d9955e7983a62180f7085d1c22c7aaa870490e647ad502000df64d4761aa6f7c40000000000000000000000000000000019fdda4afd7f3b6859d9629e4e7963c3b17b74b3bfc9e67c016c83fe5b30baf1dbd5b82aea23b095d95666cdd8f7269c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b936da14f827c19202eeb2478dc0cc3cfc7104993e946be07ac3009366eb63cb1b904a65214242fa6e6ef64dcd6f0d0000000000000000000000000000000018eca6b02fb5e5aa27d54725ab17d5c8198f4e21fd38fa50e3fa4b11c72fde69153ce25e2af4d9cf8e47308c9d0579770000000000000000000000000000000006d8f04020b86ff219097f7b221700342b6b8a03be1d2ac51cd8b995e44309e3daf8f03c384ac96bb82932334cc6318d00000000000000000000000000000000111b9676a416b368b133f7958bfb11b7db9bb537fb7b3a9b2c25d0608b577dfc9c53dea6a30b2fb87d2751b7751df3901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c68c9d41ee543fb3742b2aa639027e18412bb29498c15393b117c99998ad4d4a7bb4758b33c5180eab0402028529f10000000000000000000000000000000011cb0106d12e1b5501c68600fbc64ac2825b537f875cfee53802cc66d7373379d182fd75f02bf4cec3f81b1ac6b17e1c000000000000000000000000000000000812059f1d48f43ae146c9774ff63e6f6a8863be7a51e238bfafb53f5635a316e0e12219bebaf84947d230c42693c3f6000000000000000000000000000000000ee1a7869f5d2a4ec0c04666d554ddea0cd95b8ad32a94a3288eb39c72b55fa3c838a41c173369d64a6a0235d3d3e7d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019109c6756eb217fd6536c93493334c04a2889d42d569e4729a55139032684520c47fd059dc395cdaa0753264a7868fa000000000000000000000000000000000dd46066cbe698d67c58b43cee3b0d9396f76d0af8a2d37ee0a0fbd0d2eab23b52b07207447af104c75e61c1844ff2980000000000000000000000000000000012a3195ea56cc3b9839ca96fc6fe308219f747a40cc64d21037ff76c6ac1e328319248ed8fe220abc5b4fa7f5cfcefad000000000000000000000000000000001150ae374d46aacac3f5899ee44f65a558e4c7e9df35ffe952d188035d19d14e0827081758c7015a54c5cbab7d3f6d211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efdb95daa1dc32f1faa7bf6a99a63930ac91bf7a2417c50e812f0f9817caaf5a8ebaf24ad9077804d37db150cd018cf000000000000000000000000000000001989b01c59456d45031dd73c837c46a18a1e5c0602f0f78e3685f16ff1b068a66601a8e6ce9dcbdf6542fbd7ffecbcac0000000000000000000000000000000008636fe67257406caa75cbd315deb871f0cb4b99cb953a6e47ee98da7960637b340dd17c05581463598605f9fe295e0600000000000000000000000000000000025ba2a380a1b31aea06d22b7f7098c14caa3088a8816bc45f57205d5b96a2d294c60bc6e0ef017efb368da7a3dc08951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007eeaa19b0a784e9c069d74525c9a6bcfebb4daab47da697f38e0e450ebe8bea5b9264e32c4792dd9923d1b821cc98a0000000000000000000000000000000009a9c7bf3461d9dd5221c2c250b53f911b732930508fc578e4e072c3b2668a03a3dd4ca489fd24370c1c72cb15ebf3510000000000000000000000000000000009b5c5935a8745695108602f2214b0c8c0b6400bcaab17bfae9565145445c0dcd0c212354f448fddc1530cc96ce84e480000000000000000000000000000000014b816dd956026b2e3191470c0917b2963b4fc17e6ed2f463bde0d1d549ed51478987c528ab3d9dd3ac31c484db6029e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014cf88b8a310a19cac10acadac6fbbc9657beb1a149ae2731ce034562efe8561652d02a478cf6359315c2be3e74fb1450000000000000000000000000000000001beb10d79840fc88c8c98610f788d82c880d5af50fc72db1774005670f28444a88d12063ba9c366dd46614f281150360000000000000000000000000000000010f1e8bda7fbaf356a3c20c2db310b0783eccc755fc531cc832b5d66f3f3866070b419591aa18247c37d5e2ce3642e94000000000000000000000000000000000abdcffe861dc7f244539548a79922910289312da5330e2b587822f1f668e8e61e7851d4f407b1038b4e8028a9ba9bf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008dafe40b430f0ad083f6b153ea13fc3d06a1d60d3957b969dc2b1f66a5384e52fe4a91e1b3b350c27c5c59937ba14a000000000000000000000000000000000772234bdf8c375c41d7f8d603dd43e18e07bc67b9755d9c44a101100e6101f6ebe1e0d74bda04840f1c6579de5211b30000000000000000000000000000000018d57a51607f295a3867f58350123d1fa91d51c53e55582d927d30ddee96c9f1980fa12584c92f8a1babddb2397b9764000000000000000000000000000000000560ed1bb3e29b4c7a22c9e4b2667cae858a61f52f560ea453ec4021a47f10361fdbe32c9f757a80ea6a00fed1ffe46a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fdaec6bdfb15375d40c3f6f984b4a7b4c0ed9f14a352c2d88436f52a7324f2a1027dbdc459f2c836ea47b6732f1241f000000000000000000000000000000001442d0b17fcd1cd1b96b556e8dd3688f58ba5ef002bca9dbdafc3c63e3a813ab606a88c5a25480f25fdcbe5ba14dafd100000000000000000000000000000000108e00b5d01e6da992a41e18f4bcd250ed453f948e98e795a40d2749252a9b2aac81f0976c9c1359a63236feae4513c9000000000000000000000000000000000a96587606f9d878c4197b314f6bc5a630ff9a830e72ca00ba3085a16d2a8ec41bae19111c8fb4ba2aaad11c650b12941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001841584bfca3ff8712a517890fef4fef3d5d8c7fcc4e1b86aa8487948d2fcdf30a256531caff574566c97ca8b4edaeae000000000000000000000000000000000c80c68ca1ee72f797e142c948c56ec532e1898e992e8f12efce52a39821bc3207e4756dabf4f52bbeca1564a83216f1000000000000000000000000000000000dc844a4d7eaaa74bdb517f70b140e9262ed4a9dc8a2cbd5a6114b0fd100b00651cf0ca4db0620dd46ce914a336ccafd000000000000000000000000000000001132f03438b1daec8220e48d682e6281e75368fe7baab65a40204081c789bf4e42be42ff03e265e6e61ae6dbea8435901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078ee8a3d04e4903d0d7774be33f80ecb55491846f86ed243b63a2fffbfd71f214c4027a8455aaded7b54a3f9122b85f000000000000000000000000000000000298a3ad5d9e7b1c4ed117d00047ff84a486b9feabcfd58e51a653c1edcc532e7622b95294237d137b91c5fec0d11d300000000000000000000000000000000007bd73966a3425bc1ee9d6e7d5f995551df93e9f2b64eec8e7814561aa36b1c878c9ed9507662411001aaff62d0c0e6f0000000000000000000000000000000001d7db3ca29ee1d1ba9ac84cdfcafaed57ae9b78ff6ee8e06f3429cbb8c359a1c606fe9d15ae99ed04cb52006f54defe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109998905009cb999f6535674f36e3fdca7a03b8b02aa6e2b6a704c7a98b399d8336941aaa3c71ed9db866920075f3cf0000000000000000000000000000000013d976203309cdeaf18072b66eeff494619e1766a0411e5df028285e75d6160f1ddbb1dee762087fea9a20bb3ee69a2f0000000000000000000000000000000007bee56f057d8bdd35a0a251585f471dc77032a3d5b501f1995e52eb90f0e985f0543c8ecdebac223dfb53ea3fd71879000000000000000000000000000000001247c7a7d743fd64d798b0ae036fa114411adc76b3bd47164880e39d494b1bc69bb0f83f74330a1c456b5d1956ad64441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c11343853e9c4eb18513d75cf9f6b77fa22197b56e667e6a7fe4a3be1ee482834e4081c349040af3c95c0acdb3d24810000000000000000000000000000000001a811cb3a65837fcd8ba2597ec0ab27e1a27a8be92f928e193aaa7f6b2ce08bf849af9d88c24b72fcc99f6adcdf7f54000000000000000000000000000000000df55d7ba54e67fceb8959178cbce0405946980041a6e6557e58640347ad9509e8244d6d369cdd9a75fbf3b8912c2d3c00000000000000000000000000000000086d045d3ea24c7bfdc4330f2aad5131b1f8abba92acd6161b2d83114888e95b37fb0c80d4d53a0ea7ce28de7626c2d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6e5a667142805e1f89b703d2808453e571e788bb731b06f4eba667ad390ea6d87c4cc9953aa8f6f22acf4d9992677000000000000000000000000000000001223ea8ee9697cdebff911df3cc9dbe019942c74afaba9597c1679533e5a8a4cfd5eb3572aa43a89b0ee7ca6b4cc58e70000000000000000000000000000000014bbcffc4779b8064cb13e4877c012a4bebf44ec7a86fabf2c94630c54815a613bda8356ba12bac86dd90815da6d2eee0000000000000000000000000000000005266b5f86afbb4aa17065d03255eaa02b5f4c2b85a6ec8e339cca7d3b8ae2fae09361a31bdc48e0a2787a038fa2e6281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a63325abc6d1cb5c4caddc18032255c18510f13e93e937d2cce58599e64a819a663370fa96c3d8b8b36ee20f15ea591000000000000000000000000000000000a6ccdedd5b691fdb969102807174937039692a6a4082b78df39edfb20895b9c2b7c478b6611e038aae5d195d75ca7d70000000000000000000000000000000012151c07bfd1af5c9ebb76e5b5fde6b3963c31975ba5be2acd53c6749897ce83f0ea3e03d2fa434bd5382a5dc58914630000000000000000000000000000000003cc1a08f580e8a8aaa6d87411dbaf901f4041a93f4203cb4687c0b18d62e00e9d872c3fe861f95039fd7367cc6d789e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167f0ff730889c06edde438a6d806586701babafd03ccc1deb366dcb7c97051b9c441eb48f8062ef568b965b442a2acc0000000000000000000000000000000007deb2cd4fdc3562df41f517e1e05e444b05c2f1063e7b4c1614e5336e8998a5f7423be09990430c07135797a77ed8c9000000000000000000000000000000000f06eb2c2e74aa089918e012607e6da6eea4f6c7f1de72fe3eb8c8c021db110c8f97a21ca74838ff888317394e6bcb95000000000000000000000000000000000a295dc5dccb8986f29a4aed5d2e704be649124d9df4d039dcca9987db7e87041c30f60f7f7b6fa5f028187163a21e571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010adabfadf7d1631b1237808c2103bbdb0e033b831e8fd23470b4241fe660203957f502207c66167ebf2ef1b5764cbc0000000000000000000000000000000003e5b25259122be028ee8178fad1bb8bc834b3cfa71d9d2530eee683a812a5bff24cfada3d973b164d1b8bcc1394bdfd0000000000000000000000000000000017e70f567389d72dc600bb4df7e4319eb44b367adc70a0b7fe2040733cfa4d156315101055fad15b6302dda8ea005853000000000000000000000000000000000f79679ec963e55be2066336623e3aee4675afc4cb5b1ea1715cfd6e2612bb14029d416a54375b4a8eee83e04b5aefdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000176f95697d95b3920a99aea6a68af38c03f1e20476830a4471938789ce8e111483cbd270fb41d4b3a009f678f723529c0000000000000000000000000000000009c42533681e7c2297bc57a35d01890c3a23d4becbb19e4ea5fc7a07e88679e1c328b97f3e151494b5f0d9938f85e2df0000000000000000000000000000000004968e842aea3fb40c11baf33b00816f8d8b26d84ccfadcca9c6b5b2e873a1858abead404e1a19aa59b4fb4f0c8342f1000000000000000000000000000000001247a08562ea50581b0545da7fdaf40b2ea4587d6838149d1f9eeb78345728027fd2658ad577806ea5bc79d1f04595c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b91f33d80d6569dd2b047ce31f5df752e6cbe326f58f07ad2655fc083ffa1fde9510d43c902e10d268506717b19731000000000000000000000000000000001338f4b650ef1ea266b712aeb1a8eb8e68a57f22fed737bfcdd80ce8bebd36f5d02744376b4d196a6cda89387499270600000000000000000000000000000000002ac28e9d6d48ca54957e8982e00494d96d95cfcda61e78aeffd9561082ba783bbb21f4bf4859ce06c1125bbc470694000000000000000000000000000000000cba2dc2b8c45a02c5d90431726d030c97a820f4c04d9704ec8d091abfcf43d4208eef3d4598b4b5eebdbc1fdbaa32b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d18a19f27cd59f3d0f8728e4563a296f3593bc473ec3ebd8eedb49d21ec42f8572df213d96acca23287f2973bdfaf900000000000000000000000000000000111b2928296d566450c4499e3bdf1a2eeafa84e78b671c176c8df54a7308b7167730cec98db889c79780c0ffebec636c0000000000000000000000000000000018bac4d1649c2bcc1e9c4d9eee2625b79da2cead2a9b23388b87f1cb4db42cf9dc4698ae4dce98ce9c11e8913e32c4690000000000000000000000000000000016b0604b37b08cc541812657f126c8eff042a909401e65d699f76b012408b402419707ad568e66d0f5a9db31aedebd491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f59c2710056be69998ab705af9a19af01a3386de568442fe1302a6b3119c6f5db7c1f74432b74644b044074f9b1f1000000000000000000000000000000000cabbe45978fbcc9f4a898bc0143f336b972afc4e9ee8e75fe69e7ac303a36b57ae1b08c0ab15f6979bc831a54b6296a000000000000000000000000000000000d40a14f6cd2008413027908cd0f17c7ea5b3809f016754c1472b8a326d7abbeb12deb351c013e01223cc32c2c70e599000000000000000000000000000000001874910b6e36f1d067a6320acf59ad21edcaacee5e198a38551e26ca3ee0a33b26a5fe9c322873425b0c590cd8590b1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "000000000000000000000000000000000cb25f65b284efb8a6e02a5040105e87f339d261d9f81e3f152a65bfe9665ebf1b01aac96a527ee79a00b58fffea87ab0000000000000000000000000000000001a42a5963e65742812174174ec1a1d28dbf4b2e5c11b3e6d26779e91a81c8680484edf5f5288936b0365e184292030d00000000000000000000000000000000041ba796453f671c3f4d81e1ae94388c19cbc0233b15228b941628803ad9b6b94a2ed9e54c8af448428169b93e3d194a000000000000000000000000000000000c241833e69b0bd819f24c754e5726bd9afa80631f643550a21324ecbb362a086df145bc21470682d0363270b9384e50", + "Name": "g2msm-128-jwasinger", + "Gas": 1002240, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000ad11bcbbbf592db9e0bb0c97033f732437cfdbd76261dec844136838fdfe09657711a1db7652b0d13058989e876de6d000000000000000000000000000000000872027f5f6ce0e86b926d25ee4763771d276e9f09ec4bd334fdbe869284df3542a6d2fab481ce3d16d82f28c64030490000000000000000000000000000000017263ac18d83252ec4bc85b57047a9ff2902e408f2cbeaf1f88c2eaeffdfcbd51918eaad661ebb0d7634e9d6ff0a0e990000000000000000000000000000000001d368165be8de0cad05e3e98c6526df84a28fe9838386f8ac01d6043cb4d12cd6ddfee625e8e25b03540e9208f384b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000819d94543cc995710e749ca6e874f41adad6ef823ff96ae56af5e7fa510b36a1643d99f9d3d681e6b4197cfd7a858730000000000000000000000000000000002fc380d5d2f76352bf885c442a291bd3460304f9f770a17cbaeda77ceb9bd895eedca323dd2ec39042258045e408aa60000000000000000000000000000000016f8bf2c52d10e32059231b33cc9272d47ff0a77ebac97ad847c5d5a4e2843ae93d207b8330fa76486619ea31addef540000000000000000000000000000000009eb35e34d0311fe5803e2bc22eec8e45c5489f097440848394859858398f3dfc1b32a63031ed2f4d41339fe821c932e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000173252c8f9ef77a05b9510dde93c778434b30afbf534b3029c3e4cc9dc713628bae6ebc17a6b8f5f0d8b88751c3060300000000000000000000000000000000053b2f2c539bd4b4fd76717d2e8e3510910d3f0b5c41961edcc0033d62033c38f2cce5bfbe75b3cfeb1850b5e27b45d9000000000000000000000000000000000b6824b049a59757edc31438bc32b1bfde3056fb07cb3aa4f4b5cbdb2e06f93fe5f0c90bbe1c246c2bbdb42f926d8ef6000000000000000000000000000000001589c2238bec47aca604dff716f9ee389e0f554c5c1f20e0281a79eff41f2ecd1264acc12e5a627c875fb55c2182b6a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb31c82ace608d185f70b387ac5c679885a98cafad74eaafd4c9780da7b5c07c82710b063aca870f6b200cc666bc54b000000000000000000000000000000000aa43f5026eb7b56f1c8af016a2b86509ed822750862b8c264116af52b05c4d5f730a9f9fecef13784ff5705aa2bb3680000000000000000000000000000000019fe715a85302072c2a2d8ebccac7996d3371ded0ef8c3bd6848a06b778a6b11fdbcda1f9b5242dd1c9149703db87c250000000000000000000000000000000005b7bd38dda881c6d9f39d4073478bd9ee57b91291add017788f71ba0bb9deec24c955ecd1a1fa933fe00cf9a912c01e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dcb334e962638f3b65daa96955cd28d709c367dd6b619fdad4b37e52f6322dcb739ece5d32488ffec729dfe1cd7bf4000000000000000000000000000000000692e863b1ac1828b2fa2ee7218395ac1a5971e9bbbe97d156f13eb6e45913a87123c3949b58f21b3fb5c3cf4e78765b00000000000000000000000000000000178df65da50877f327823b57f930a0b734bf81c707c61b3a83eb2b9b6686cde4fdeff5cf2fb25d76d916bc058c1eae8500000000000000000000000000000000123841e3a9ca0878538fb2ed4b6ecce2b450325862e6ffb442ecbe1c6c45e6f757d47ad20b3548228ae76f0b37c6e2531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d671028a0f71c3f436691fa3cb72d606ef0e5154b52f1cd699ab8f372f397c93dbaec751e495b68364c99c4961499e0000000000000000000000000000000016d183df74c8e6fbb9098ad395670e94c21fc859c6859dd0fbf9187c051fcc4ad3cfac16db6ba419594240df0849920b000000000000000000000000000000000f8ec6886555f4fce6421f9b6e5505e349597bec6038e104dddbb4f019317246abe7338192d5b226fab2479d495ccc4c000000000000000000000000000000000816900dff573ce3ba2fb3fe7d0ad7c082a8cebc2803d5e3a15bec2c69c4e3db330a29a4926fc710292708191ad38cad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb0993d237bbb255c6efd7c24b2ebd0b0f49823c4ed4d44446c338183d17e13ed5488ee58a7b1f9084bc81fce4bbd40000000000000000000000000000000006b0310e7aa60323868df4a4228bd8b813fe8aeafe0cc1ae7a8d2efeedbfd30a6fa7167f9d9d54bca11e6690a2c7dc3f000000000000000000000000000000000d06cb585e868bb1e39d2f03176ce5527859ce3c1bb9a41f79c505e2d2890cd4323cfff606557690647e22e084a99c85000000000000000000000000000000000e883e559db42ee7e026e479a8306ca9e13cffb4f9c44b85beb7f19f08d928388aacd9e5706859dc95faece1011719ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d4f1bf2343000a14f450a96469dd310b78d975a32bc83e2a6ae0faf261ce7f9a4e2f75532a65b60708e4b499a9e01700000000000000000000000000000000118262d5ed72f0433eb8e6207c922a26b2ad218f9ed6a0aba77e1bbd5f1fd2cb8907eb7081b37f86e42a4f6aac7161be000000000000000000000000000000000796b9f919b97e67a7739cdaa35501a431d295d13940b95b30470269cb7326f4a90d49f65e2e0a21689590c61670cb0600000000000000000000000000000000168c9146e402259d426b2e2b1dee9b29eaa3cabaa6392f1a1912a1c11096b6c927ccf22ed8918c0876d0d8d126a0a4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000074e3702dcbcc68b3ca7cadff7c04262e883d1a25cd92faa5a383f01265259e1ef023572b63f0405b3c4284c6bab31bb0000000000000000000000000000000012faab84e08ab0b2f01e41585f0324fd1036fbe1b85c01964be9af3c582d72c9f1397807470de55786fa68b30e182fcc0000000000000000000000000000000007adfbf062434f76bb12d90467795f648d9baa2c7747d19e669a28859c62e38f3a48102e5814910d344ca9c98dfcaaff000000000000000000000000000000000829258faea86aef33925448d44746d9a9b8266df6dddffb72130fc0011c7da262019ce35e1ade7cf348d31748612b921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001198c37ebdcebc10b1e639310dfe3919f59459d69bf6edb12d086b935ea2638dedf389ceea39ef9f6a8ff202230cd14900000000000000000000000000000000106cf9a8fa8ab304fd917aff5bda9de6fbb338d548dea56ff1253b2a2d30a0c781c4a5ad5f8e31f41fadec3d4576598500000000000000000000000000000000117c3d0336783faf61724007c78ff7f0f038a35736e65ecf483e81f6b9d5feb5c587fa6ccedc1c97296e4c233c096ede00000000000000000000000000000000004ed03edf1b036eb4f7fefa589fdedd2fe843a8909ab6cf1fbf47dd5d91bcb067c0b3281c8d772dbcc8cef1256d5bec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d94f333d893e0aa4d429cfa4e6563d4d50ea44020195cb06e5fda3a0a10b0d9eaebd8c273e89ee2b78411d6d2440d0000000000000000000000000000000005a1ad530cb9b77c22d980fd6d2a577230484380cdef7258986a93015ddfdd706b85debd37c183285625ca8abebf8338000000000000000000000000000000000dd2c8de00df7395bf2404651229415d4267efbb859bb340b1e4a83bdab7a63c5828ed6d9dbf41d7cd0447e2e8c03dad000000000000000000000000000000000205de65e01062643aa52fa84289688ae63c2d7c0e1af7e1dd28793af8bd49354607c6fbb1d003bd371d67ecca245fd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009a6f6881a56cbe02c718920b0adc7ede32098a9aa85b2f8f6feef11694bab41c0469b76299cad687310ce9da23180d0000000000000000000000000000000019a7cffa4b3105fa424bf069373fd5aac017bcba1b054daa8b16f0b757ee26decdd8670af8556a50398f56ccadd883ca0000000000000000000000000000000010494b89fc3f5daea232059aee0efc189344d36b946e1c83813f4734b4fcda3d361e1d1389e6d114903ff5297c8bff320000000000000000000000000000000008167abcbf9d09a96476742db3c84b372c73203257846ef2d2fd4f8802f03bca21650a5503e242582619455d8a10b81f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ce95e28c993543e4d9ab1f3ede8b0c85226cdecd2f97022f411d45c8122969033d68b4445387b0e433d0a0af5c57d00000000000000000000000000000000199b1d4e20fffa301f4c0c00d61f215d057d15b268f6fa5f9685c8ad5aeb1e2bfd65faa2f04ec0efb8d857b71744063e0000000000000000000000000000000000d5ac3d2f4ec7d5eb12f0f7e2389cc5c0d531fb8f8f913f5fca996e05d761cff58989465395430268846c270db6ee050000000000000000000000000000000012d196a3af8466b4d9cf0b5306821fb79cdfafaf347b69b623438941c25e7bf5abe14aefd556cb60d1df48331d4a86541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe12c7a5ce8e9d69a14e2b31a4bd3ab0f5672186f0ac5107062bc5792f4e449c9db66f33b9de8a9c527819e7a0203c0000000000000000000000000000000000481511be3651ea9ba7afbaffa7b0d9c9df7f2826e259d0fa76e776d81a71055908478e93d67cfb91b342dfbd130b8240000000000000000000000000000000013b33e3efb1a90e005873e88767ccc2fcff2608513334c23de0ce92274354a8cb7c9bbc91a9186734990219313256db7000000000000000000000000000000000959f773ca3180495aef67ab2c7e3b60a6d2f3b2012ef67492a721658a65bc8e9640f4c446fbca486a572a3a450230e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001130c03fa63b0be2e6ca5d70b8b66190f6db697ffe4888660966cf7966218461559d8f8ecda4cf5571116fb6ab5a3476000000000000000000000000000000000f7c36acd03a15d0a8223439c400d99f96e659771a59f99731b4ab2215af2d100bebe079cd1f0be338712072aff189b900000000000000000000000000000000068ceb20758dc0d736dcd957db8d3ce1cdbdff1dfe3cccec3aede6c12afefffccec65585b75050051bfdc4033f262d120000000000000000000000000000000014a30d60a368c79c0a080b0ca879c752ddc016b5a2da551774a8c80254e548c24ebc25691c978cb0e631f242a7bc5ab71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001064014f60540f73b24bd2af7096ea0bc5a9644460406ee258bffc72b79a3e6c1b8569f70c09aa05dca03cbe8d5819b80000000000000000000000000000000008acfd7e36dbd4647a6a5e09c24a3d633162e8e774de3abfb2b4266c7a6da14437cc0065c2a3652ced9fa4f5414a4272000000000000000000000000000000000a1876e0faa2d6098743468e6a9863820b5ce85f7d16d9baff0f8fc125b0f1889e3e8531c1ce148ce48481d8168b62be000000000000000000000000000000000d2cd6f7079d58685ab8bf4e53e84490656043ddfa54ce6df7da75e96ea963cc9a4238edf8344531a84f2cdc198a420a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c477619f311a56a1f94a47f675c40b7bd3433c1d44170348d523ce393fc084994a95de74f5673cf8b2e57ba6036a020000000000000000000000000000000018004427f9a2f481ae6416268921f34343a7dcb4ce20a9f1eaa681964bedd75b05e075a1afe6ed1251b3b6763648521b000000000000000000000000000000001647f4ae2f905ee9576e83fe7891bb1a92509e3616bd44d154b0e6e425767827496a9983caf359a958fa0d511fd8f47e0000000000000000000000000000000016cfe6abd168a9ddd49a05bb8b5ea76edcf67fccb5035d8059852249fb47171ff4a44ee8ccfaf23972da4aa3862f81211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000902476e2fabfc8467068f438eed2f2b79c5d6d12f4551bb6253274491a7c41c82ac5f2d3999e07ad24eb19cc5a3eff90000000000000000000000000000000004ba2aec8fa838c20aacaf2bb87f552d9b312bb15132e2578052605818f4ee13b6b918b5fe0bfce6cb3a0d222530c2ae000000000000000000000000000000000a422974a2199fc5409251cd337208e4db9fe131fc82a2cab283c06ab8785b9d9dcd15449a03083f8f19fafb05884ec0000000000000000000000000000000000387ad9d31f6f292bf84096f7bf14eca71ea71a20a601992f3fcbe9e90a45cdb310e9d603a611a72b47ca2765410dedf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5bfab89ffa5ab018a248b6cd5689d2c035bc563b9c006b00ef73c19a29b8d2ca3b0433e9923797d7e6183b76f7229f00000000000000000000000000000000001722bcb0d655d5517cc3c73b11a2f91473885d9c7c7ab5c16d3461f9560a84e116eb8bf17feb68c100c34e7c4f6f6f0000000000000000000000000000000015833256f99cb127eee594b08841e4257740860e72641b35b60f280e2427fa2fa912807888c3b3e795f9b156f61021ba0000000000000000000000000000000017969067f014ccda9420ed03e09a4740674e37dd9766b9260736d471c4d99431cf93c4b23328e02d7137a78ca4ba4d8c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088c8fb1bed82a11c239bd902fbf56e49546e0672994a24d3ff29e12b61e25161d21e89b2a5d4423c26c25f64cf94bff0000000000000000000000000000000017b2b65cdaade32d044cb98d5f8267e4976d1aa5bb72bacb4d92ec5a1ae4643ad9470ea7e07ce298691c0260d192f47200000000000000000000000000000000064bb96fef71d3f5fbecb02424771044396bd3d95ac42de68611e85b34b05a3f39754d0a781d406596b89d92df6f590e0000000000000000000000000000000009019fbcbd5375ad5564fb9952e101b17568995fcb1125e2f74bdf849a0042641cd56fdc9ce3b944d021fb09587762791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d244238af7f67fcdcac60b1cb5910dc36c213b39df46401ba6b85add951f30c0bf552e62d8a5d1f4af92d7a35a1d2ce00000000000000000000000000000000149bf1b9434d0350b75c9035a2f7fc60e33f5457194d2e61b9a760ae3dcd610b9bc93c4063aa81444bc5ef7c960d85a4000000000000000000000000000000000aadee2641fe7106361a441c9da151a39bf483d4ff511c903de64121deeec8d30d0705c6c86df27ef340f439be0db7fd00000000000000000000000000000000139f6ba23b15359665294d0f8bb5db7f3e134b7898a83cf8439f39791fbb7747a9d971281ba0b598e26fc811fdb43f141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012155c8e851393402ae6098089fef68b544916c2af46a46ef0b9daf2ced8c86813c532dd0aef54fe57609d2974a2099e000000000000000000000000000000000a53b852938617201f6a0920854130712a3e93e187721373f66836e64525105a0ce8c046c2f36a8b5e9eecc161a91c7e0000000000000000000000000000000013ed6995a4b334a220163e0360a4fae4f2f89d83816c4fe9f91d7c97eacbee4adc5636befa99422443030a7d4f5a39220000000000000000000000000000000006846ab5b892b54e8598bf4e880dfd1c99d059c2762340e1be60c5b42181a9b05e0f816ab2056f86152056400deac5be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f296d3cade62b2af314a4df35fac58eabe8b4ff643c218bfcf5e040356a48af5530ed7a09db577e25cf7bf4e2489a9000000000000000000000000000000001209e11b1e1f50156927cb574824b1ef638e7e21de50a45988e4a633fa331e037d5bb415f6a686ebee273dc66419d3470000000000000000000000000000000007457bb3dbc9900b2fcd4884623ab8ba2f0a2c414811038f2fb547a15f005f6bdae4e6537b560b9b88f506c79034f8b50000000000000000000000000000000002e98498231943142cfdfa5e429030ad5f7171bd09bfd5a9e9a72ce80177f6e9bc45c97b062b375d528fb4c4453f0dc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d74b7429c50ce597610b579870590ee92893eda14d9bbb3c8e1b486758e5409682d20ba2256586e18040699eea98f5e0000000000000000000000000000000001af81a5e502d6acb2b09c4fb57a6e37ae31221b1ef182d5377b6a132e52cffc81dad800eaf31c1bae32b44065437eb70000000000000000000000000000000007a289472e7bcdd44f1dd89df7e0a4300e4ed1b3ebf8cb69501d96f4ccfc5cc3daebfb5a0f9ac9ab4f8ed696d58093320000000000000000000000000000000003b635213d689be8c890372fcc03e80038f9f22bad8ffb932e063831014b0a7aaa2c161f7dca216185933e89cbccaa091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015481d84f55a0aa9a7631ce320940e203a723e0b2b430ca12d6d6a7b1d17389305480c3c6e4aac5ef5f31141fb9742c400000000000000000000000000000000195abab435ea8666c8cd86b364d592a5a287a29b126d99acfb44a49b4cb34e0bf94ecc8f01d4147b23f53e73782ac96400000000000000000000000000000000158525f940600794b63f36284af5743c4871c9e397d4aa163bb63c5220ee0855c2703241998f7185aaa8f31faae01596000000000000000000000000000000000ffd1cb0e142d53be55a7c9d4db1893e317ee45df5b5ea2f55d6eda640bb566c81d38b58edd757bf7fb3c227a3fca31c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c85e5eec757fab12d7df2b1f6d18d8439749f4aa520ef7891c29245d0f54554b15b5aeae5cd3d52767d5648fdf85140000000000000000000000000000000016ff0ceb0af2f932925fbfe49686bf833a095a32f2a0e1c04330e4aee6e6fad6bf2b027c4e5f6ae6c0ab9c06ba4ebc4a00000000000000000000000000000000063920264ae74bea33d625175b032171d6412c58da3c17c98338365bfc14ae20040de40a78c681a632e843891f3355300000000000000000000000000000000007fdb9c61b9591f607bbd90225dc2c6b5b439344b163c038fd0fe7d26af5fdd7c7bdbeb99c709408712d78d4d73ccea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e5e35214db0789c725de8dd3b88fd9a6947aee235b94cc9d5e7ef8be8067ae55e0ad4dd5320755af04b4fad06ab6470000000000000000000000000000000011d67d493677b4ed0df628e1fa2e6972651387ba2386026dea21a56e87629d71efe1c78185b6c59163a3a69e07f95d63000000000000000000000000000000000325f09ae03abf48592bc1be1e68b0f3324aa38e2b4a415d127fb0362ea152bc5178820fa184b4fe96f91c27321cf31400000000000000000000000000000000113ea4385695d17d8911df9196e89ab05143b51def50c04fa4edbce7b0e550a860637d0e5feee921ccf56bedd7dbbc551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191534c9997ebf1b209f0010e189dba5f875f6e8fe4fb84f8b067f68eac17177181cf2e18f97f712a4682db35a98af320000000000000000000000000000000001f7180a46254a353cbb66810ecae841a3b16bc5678196a32a8ceedb647f3d7779ce7d4674ed1686186fa98180f0ad3c000000000000000000000000000000000203cac9d66e2b6c8a79e6768aaa9e42c87f0ac07ca12f3add022f4e512921e80d750c26cc3df54619fc1555f0c8295a0000000000000000000000000000000008da29096db7aa601c67a591de8fd4fa8fcdbe1361e7a1b9251f7f66d6a338456e80196ec562176b8e73a100ef34ebb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e2a630936f77c19ae45d618f978edc523e22d494743694c43e69c24f00beed6693fa44f21fdb0e6054abab1325c2a6000000000000000000000000000000000365472a029c53ea32f08063329da918756cb226e5bb67a0db2aa82f668d6c32b4bd4e2331786c8fe82045d7937fd0330000000000000000000000000000000005ff0ac051d6e06b8e4a1dd0dfe0733dbbb3195091bc98708945387993d4b561b4a69fc9a46aa5486691e94398bd038f00000000000000000000000000000000177ab4c59ed4067f5847449334f84e2d675f4bbd11bf01fa461655dddf0699bc843cc18fd0f525626c8cb464238db1321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001200cea27118cd52902cf86aeb08c9dcc29459d342ae956e9040ad516c06a79c0c56608a4d47d995cea76203decbe77000000000000000000000000000000000bbf072782c907749bc49de96a1e077086728e108731f7d56ee98e95a381211844d8dbbed7d679233812810c69152d68000000000000000000000000000000000bca5ed1692470c5d981b0695bf0c0fa23c07c1a784253acec9b2bae16598f3609100442b8d4b96e64eb73e77d7f0d110000000000000000000000000000000019b5345dabeee84f7b7b558dd9142dfbbee73b6e63f27310e88a98d799a237f063b4a188bf4fa11e88a91326dfd0b82c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013456a04934143da14a97e8387b72b58c47f290162037bfebeb2c1a095d2ff728c4cd79b8521d1f7ada1aa593f2d5f8200000000000000000000000000000000124052c7f380a2857293976ade77772130afac6559d78af076bfead8ebca6aa6b3b54c61443dfa64b771eda374e02f7e000000000000000000000000000000001671bac1992d281b2b377c5c34af17d7984d270d1404abe09303a4a70b911ed77e31fd0dc2b7ae730976d26bae5c20760000000000000000000000000000000006bc80dad1f9ffd972de97e2f5a51367ebed67602494035ef681e53faa264e92c0bc12d1c606a75d23c66f17c677f90c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000636632531e70fd162fc7fad34938cfead9d471e7c33144665f122792918e95f243b6ddc650f8196dd2f48424459933e0000000000000000000000000000000016354159de5164284dba467e6ab828ba50e6cefa2bc9382832d6e043d41cedd5fad0810fb0463e92950db65b7a88b0a100000000000000000000000000000000004843a730a96566cf86f4d6625fe16c90524db96962e0042489bf874c7bf30127b9c6c73248f956f6722012cf2b10d800000000000000000000000000000000110b1847a4b65f4818b90e55a4245524ad3e674968a6f4602c044e45ea955c821fcfed89b34a01fc753d6e55069b68ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cac2326ae8989aeecc5518f47d934d952530f7c3b96aac25e30b7bdf7a1d96c2d4a020ae098e39c665ea81a3a8952130000000000000000000000000000000008f3a55c5db23d98f19dd3c2719a2b478be1ac8f509ee4ee2cc29e381a1c873d58f971077eb0ce74de9714545525d4bc00000000000000000000000000000000130e27f453dcd6d9f4dd4b4e8c067a97426217d06ea4efe78a661fde2affadaa3efb39ca7205457b613c1d82d24bee120000000000000000000000000000000009cb5634314aa5068cd48d02f3140814e1e30eadc7b63a78157aa5163539356591de629f0547aeb05d6494645ef543e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000548b4db02d8e4e99ff08ab722e6de7ba1b57ac1829b35615608a4f525d8a4eced9da7c127cb166e0de991ce0bff8130000000000000000000000000000000000af26433f64808886a9f13d4c32c27a48b837938ba8c0ee22ce9b0768b91076e1eb573702592e0dc8c6360b2212cab6000000000000000000000000000000000ab153a6df9bdfb7518a5ea9ef27ff62a935f3e13df467685e61bad6f1c9c2baa881eb0a29b29e746cf82a93f00298aa0000000000000000000000000000000003d00bd940a8348652ca0f5529b73e05484ffa66c4e9abaf9134f0948553da4aa03234737775798006757d4eb8e897c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184369264c8bfa6370cc19cc8648432fef2cce41e98cc06dbd02730a916c1329878efaf66797eeb214c7b71438361d62000000000000000000000000000000000ab9ca1e7cadde3d9beca985109775f43d31bd0a8c24f10368458c4b487879ea1f718e630c9d71242a60144a053f1dbb000000000000000000000000000000000d4fccfb5335abd3ec0849a02acca3dc50f084c95e70a6305a76612bcab9dccf2d2a17efb458959841a6e90993b0e18c0000000000000000000000000000000006d3e9f6592cebfa1447afa88077c82b001a2cff1561d2d3905e606c1789dc4170b55f860b8d16af2a26458d9984d1971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e17796e0e1e854fd252a61f6927e8a66aa3d66ad1180e947412f6d4254b53806ec590b2a5827e51724f432ffb336830000000000000000000000000000000013030795e5e3efb1d7781a3cc77269c84ae08232cc0f77923ad9938f254c724d748d807cda835b5f229cbba25bc2c086000000000000000000000000000000001486bd1cb89dd086dbc111433ee826539bef52a882b558e0d6361e4a27ca3e22cf16e5ccdd30920b435bcf1d7af3e1a30000000000000000000000000000000011d10c451eb7bece593d300cac947e6c243fd18567a141682df6e3da4817cc02fad43e1a437a45d201c26d09153887ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c95cab40f706213e0064985ea58a05331873795b0f79385b4b64dd901432f590ce29c67ad50dede53dd5c3f35a3cf650000000000000000000000000000000016db74f7436c2bd18dcb5fb9637bab86d3f2e3bf57ba78d580f0a4c0bd453031dd2376c5d5a3fd3e072d3c5801541c920000000000000000000000000000000009cc2f5651bf08437242a7595fc5db53d32986951ff20fb048f2990b019c4efdac9a86fbb0101d6e4320f23c73ada7cf00000000000000000000000000000000021df241a9d37d6afe3554b934968de3235bbd4dfa037fcc1c663c6a6113c3da0307ae8511335e5e8868b6356ddc8ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105ef8dad89d8807190c2b58f1c73f8e7551dc416dd6140c194eff5c33f827407db46ad33ca29d7094932056f1e0dc4f0000000000000000000000000000000007b0563877e625942b75f87b0def5f4c96f89372bcaf0cfe81a65a2c1c17f3621789cacd503438269cc8e5a3938d30e40000000000000000000000000000000013c6fc6651c52ab1e25a6c9ad56eb8891eaabaf47ecdeeedb3082a472f5b871e3407b096f473100a5a56933761bbf809000000000000000000000000000000000d79d884ed467701b586049610a94080190feb302bcb1e5b518b5fe5a43f3cec6d392f731cf7dee8caf5a0d587b60c701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173ae734505c698a7edb40cb9cc1b33d166bac2f51f81d8a6de93334a42543d09aed72952fc440860e6f371033ce3b7300000000000000000000000000000000195d9225602576cd4e99f62d1c0696b30ffc785a22269e28bad05b8953f13041df70dbd95209f3adc503e9f3cad72d8c000000000000000000000000000000000694db4e4b96b43cfdc7a5b8b643ca83e1ba3ef13941e1fea31b6f15153e8fc8adc9cf1ac225538f36f48f7bdda333bb0000000000000000000000000000000000e00aa1b504e532e077cb71e1a7cdd5141f52383d5a3c95bb90e79b599147425b89fc67f7ff430d9cff3323706c6ef81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c1afc4c5eb2b007f7ebf51f60bc5ca3d5d5cfe688ed8eca9368f0550cba1bb1f2b99fe3460193dda464ac1f2673927000000000000000000000000000000001771f88f65273d708ebae98ba96b1020010202a1e8f53f5aec05a1d56a24cc2cf83850054ae976cd1e58c31b83a09722000000000000000000000000000000001608000189fc17fffca28b0958adff32860c664d90b85726450167bdd9be48d255a19a3c44a0a8757293a22522c81507000000000000000000000000000000000cc34ae5594baedf21ed26904db71e610632b43fdc40a51395952189269976791ec67810a7bbc6c20cd57119514ec8b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000766bd2d757009047c8392f595fbd24e2a981d5863ba8750d2b633966d16a75c85840df2a2ef36985c8df7a51f94ea9c00000000000000000000000000000000052222303f3fb4f41af3130b400f96c7c53927a67866ccb1cfb1de86609d35c9140d1a2299a7a14b73d4d80aaf118daa0000000000000000000000000000000019739f7c04ce73c50cff6810c690394ec7d9f4cb5b50fde79d71f7222eca5d516d4d1c3730cbd90a7ad38dcdae798aad000000000000000000000000000000000c504de8cbb1d4761cf5008c28ef752d66f5e5de6d4c3b90f6a4aed0b49aa0d3aaa295347ff17f2a3be1f3821b6496a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000683229ad3190c5c937f9c3ac033dd16b2350d13b5399f63ca029577b9725eeb138485048b67c32593c00a037a7a502300000000000000000000000000000000081dd4f491685cd0cf2425880d5dc1a19c8edc839a502319d881217306ea8f3969bc448bda26f98303329c56323d0b0c0000000000000000000000000000000009913591d488445ac5a61ad6299f2632083cdb602f413822273bf07c5af933f534f74a8ca82ad3beea846d1d37d654190000000000000000000000000000000000966f288801378acf8932862b9bd680259fbcac3bcec8ab7bc7b4460af8e0b0ff83ea764e102288e6b3a84b73112c491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000168a9e5b507ce272e1654346f45981fd2bfe4c4d33d819999c4898ea64a505c9637a990a2834a7d136094194468394890000000000000000000000000000000012011e1aca1b25caf596751715dcd8846d4f91dab9db5b0856e3b0117e38b734de887092d209bb35065f05116a095a680000000000000000000000000000000006adf2834569c39ff4e6c92e6d3ff0b2568bc5b20d7d5864764e249c3e4ba41f84c39e57fb3c4c8daf856df96f9924470000000000000000000000000000000004066dcbfdb0a54537150f7fe994b1a2cbaf82c48eb64fd793e763fe8f5ee5f9a13658adcd582b927f8ee22e61d296021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd0e254a3e9ef6fe034f786d3fbc5a1e4adefaa03c668b9c007797fe8c04aae0610471cc8ca9df846af76ae9305032200000000000000000000000000000000016b40812a13b2c0c736585bbefa446e00b83b49fe3a5905fb1c526cce4760fceed35aec4c1972fad26cb4a6d2ce06f1000000000000000000000000000000000dcd97c5745adecfe0190d5d9717cb2ce2a55969b81d035bced4e527997331903cd26451bf96b448a33ad3870fb8596c0000000000000000000000000000000002e6c5da094d341902eab34443d829e9fbe106e09c97dc444fc738d3ab2be85d9d1eff82e02189a9458c4437a3d2b4751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018930335964a936ff68ecb8b8423f740ea7e16b358c9d5603c89d42ebfdf83e17a2e34b6893e1f699072d39d5720e0540000000000000000000000000000000012d4a4a451cff24de1e12fad8434cebdc5b4091aa3bfff60a4679a565a0b26da0392cf923475bbf4ac1620de76973649000000000000000000000000000000000608fde1cbc5346360413b14f42916b1a4e1445df29ffc1f9dabfaf4ca0d60272da82b84978a451273ba0eeb31ba22f60000000000000000000000000000000010629a8a5aee9452d7c96be5370c9614831a5977b7cce7326424d2720675c7f561d09c0cc62ec71aa666753d3039f2361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014312e8de997bcc7163c60f2c3ca93be147c3982e2eebe61f6e903f2b3fe36e4d3986d9a9da202f34362ab120b06a8a70000000000000000000000000000000008415d3357126ea3ab6f5ed47fd91ad116d0e36a9ffd6dd261265eba162ce9dd795275eefbdba5c49ec9d254f224668a00000000000000000000000000000000165fee9fab28be5dff85d977c8a7a1f53ca97388766856c3778177c4c6fbe6a64e8407bc50024c3ffaf0f9d18b5b9a6d000000000000000000000000000000001496a7eb0321eaf1cff120636340fe47212912076e9d7bc627689a18327f55ad5bd7f17d29e36951a2d3473e7a21c1241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ca23ae28b0aac591b3ce787a9472afc1eda5a7598626601e9ef565ec6178495c7ca0a91e60de6ebc77285825178fc0000000000000000000000000000000011a2327eb645d6480ac33006a7c3da7b028f1d310550571715bbf48f230955ff3088114b736356e793cb28a70c7eeef90000000000000000000000000000000003970c4cc6102aea9cd770c66ae79d8270dcee00fc4a45523ed7745a4f85e85a7d51310b28c5ba52eed510c9c7146268000000000000000000000000000000001390f44955e77f2f54adeeb202e857d8313bc08c16fcd89523fafa53147b432059ca40373869fedda304ebb165905b7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f722fe9eb5a4448a0c54f6bf7be58037e2acdf99ec92a7b5bc0d2c180131269eadb88a8f726b14ff12b8ffe6f3c34b1000000000000000000000000000000001378a408f340d94a992c27c1f29d72469e24003e8d027d9334a8be547464f4901d8546c69abfd5b4afb18861aa890cc2000000000000000000000000000000000f9145d64a26c2c9c163372ef9ad9093b9a25ab181450022e68c18378bfa583c360c12e2c6fde9367f7814d72c76904a000000000000000000000000000000000518737c592ab80e6546f97225cb8a09d3e4e8d9c12af3a07fae5ac9c5d34aaec6a1843ea66ffb9b3aec8f477447419b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005e505cb6c28ba517bee7aa2928c10e9b683883290839d9ab6edfa7a4178d30383c35685e9734a355be332de20a062100000000000000000000000000000000096dd27df3963af8e771d7f593363b06a123c90651e42d2d319df36b63abd8b2a7fb432d26de9237ffeed6ac39e88a2400000000000000000000000000000000164f23157a58aaf53634cc0a79528415729f4cd3acd0c513ded44c762e6dd1df98bccdeaf18693b0f03ca2ff3671fa070000000000000000000000000000000011602f353fbd06e93c726f7060f344da137aaa69fd24ba098137b1773393ac430dde9a274f7d193e1725b3b76bce21b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a546ea332ffbc8bf16413f4ef5f34ff8cd7a1497ac2b96696daad82f74d08f679b2e731f99759b732051d6e9360640000000000000000000000000000000019967c1c3cd1db9fc5638dbc4d5fb7ca65f3a9a396f786bfebaf1bcfdb16e5f171a3b5fddfdf8c4ddf84e60b8eb3cc4d0000000000000000000000000000000007d7b8174b61db9761fd152270e3f76d82a03297d256cb95f1ac7af46a08d00dfb9d10066f819dd10bf703447324488a0000000000000000000000000000000010b31d6bd727dc3d27821747e798badd57c2afab652428b13de8d3e1bfae4f4679994ecb929c1a603fe79a463d8b13f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c198e01125410f6320bf7a4acd7a640de530ca27689a44af984c9a15334c03afb96f63307caf879fe7294956eba04a8000000000000000000000000000000000654d9ea5ab3892b243a8e8bf63ffed15d98452d4ef13b60a5ef8d860569bc4b5ca5a170b18f03658322874eeadf7c010000000000000000000000000000000014c2ed0f1d27682596539894614f581f7578aec7a2bf3d8d922b66c0a436194f6ab675abb60129b9ea7aadb383857989000000000000000000000000000000001773a585761559aa03e9b37be81165e189a99f33bab22b55a0e81e78f518a0b6c099d1ecbd7a40013b02d68b96bb35771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000410d641e0787b095fac2022226bec6a5317dca35934873569c26d0aead6485175bdbba5f60c644c083e11dbcbfe2f100000000000000000000000000000000012a0eb417c707237f2f8070b675c645954fab113f650862f2c589b8964f7fa7a022a053ec073f75e720c8ec55f58c0e2000000000000000000000000000000000355b49c718f2e72ec64ca9941459452206706ac88f9b6152b5d2f6727efb136413befeae90215d60e1c5c2e04c6d20c0000000000000000000000000000000016d2e76de6883ec5727dc38b5c8b1421f2e559c3dd79fb985d9422bfdb7ec81084379b86b3f267e3d581611c2f649cc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f7e46b261296f33ab11298e40c87004373ac16a8b3626776ddd0eb4b9222be3611b2ce9530f63383a6f98b1d79c824000000000000000000000000000000000ddfd49dcf4476f13c90e92cdcbd932c41b0e262bcafe6a4fd68829d279c7cce5ff0ec8c3d419836d055dc81899a4ac100000000000000000000000000000000144ab9a165388c99ec8fb6ee42e166699ef4221d3921599ee08fa8513fa8877d427095d3dbc1cfe3ee087b9ee7e8fd4900000000000000000000000000000000062389ee0d36bccc1e18f5263091a2a2b1fbb15d2f395fc2926d5f01a5c59c6d8f50db7ad33bfc6e9a63cc1646eb08cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002029250649194e022128b53404b6b532fc06f69c2b5ee60ead3cc60d91c0627af7ddd615256d7974d0eb1fa33a8005400000000000000000000000000000000005816dd76bcdff34b0cd1a23987799844d64ad61cb3ed9efa8ebd3676a4a7f5c7647ca2a6dc4f6bb710e76b1765cd1d0000000000000000000000000000000013cae4b0ed5ed32061cdf024e10c170f383f0c7e9b21b2f2842d21c1d1e6e1f48685518d0c88fa4bfbf75aa513f3f0af0000000000000000000000000000000002446ceea2cd71fe39f09be26ca1cdd494780c586cb222572851f824105b7a0e820ff079dbda3eb180cffb68c32820411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aed39a259e4c3568ad4ca6ca031d0bedde6ad5e7c72b7ce55aa508c09dcd3b80affd5186acfb981a1d0a84b01f770000000000000000000000000000000000043757f55b145bda8efc3208a450a3a76ead947ff1db47ae240515fb0b251769626b7763cba369ac70cfd6a3a07e669a0000000000000000000000000000000006e946a24b46d345d84aa08df517d05a0883a8411388561a6e7ee3089b2dda4af2d690c0e9cd9d13a9a7f77a3988352200000000000000000000000000000000156bdfeb2cb87308f73f3af162b7ecc54c822505d9a62ef2368c4c4daba4b5caa1c660b177f336aef6c2cd18142a382b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012eb74a548a1d3dae079e689ebcf3860bbd524500371f110af5becb7d4e35d963e41e6ba4f990f3b1afd9a77748837e20000000000000000000000000000000002f5e9645275eae3172f4d169d618adf94e29679d31925df042deee5a76df489bf7f1ce143d090f5b2fa55a9ef4ce8cf000000000000000000000000000000000ff2a2e428a9d4e78bffa713da5c3628292cdcfdbcd1b0f76e84fa6f888c178b02356f66ba66af7617e7ee1b1af62732000000000000000000000000000000000e3aa36b217c9984496d67aa442546ba3fa3c94904010f27d38b48faa6db6d9a356cec7b5e2c7a9972d4fd0e6576006d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dd3ff146ac7d19a5343b1988e2d61cde9d073a5bb69614e12f61fcb3edd07058d983d286c7750ee7d322a4b48c3a3a00000000000000000000000000000000038d8d0ee045c379b8f1e03a5266be5c56adf2f877a256b96e7d86dab3d044706d4563a0f89b397997098a4b870704980000000000000000000000000000000000ae3d39dd2f6e211a5a7607768cf412ada6183d114864d9867fe0b756bf778e5d64dbaa12d8e469232e184e82259b680000000000000000000000000000000008e98ec751f9630746ce0cf76eb60988dd598ecaeb4cceb1b104249d1e489dfbb5037709d7942adcdffe8332836dce181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079738ac68fb9accf8e9ca7ba392d765965b5b8e80db2135d2b61f99509a7d56e0e1743e7549ada55fc93d251790bb81000000000000000000000000000000000b80ba11e833ea904fdae34aa6c85cb445d34d56a9dc85395b144def496efb79fdb83c1daf2fba8f9f7bad2d75e85857000000000000000000000000000000000a8423ae8ca4ac2a5a96bd2eeace97669c5529a9496d601f7390e8d934053af12c9c345b00e9b58346e057da116d68ce000000000000000000000000000000000a5b6be744e34e62ba5d8901a58d8280da920f06ceff0a31e71df6ae6ef6e9df40c8fc6297d14593403eb279a62c6f371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c0941f5b6529a4cdcca75761e03c633564a46a727994b7fa98fc88c08b645f5b6bfa15eb6cbbd68c6d44cafd6616db000000000000000000000000000000000f6f45b3eba6e24d28ffe0fe0218f11e5da6537c1dc1d9abacc5c4477ec96cc3a06c035f9ca75fd742af1e550cc9341c000000000000000000000000000000000dd39c6e93e09e0c9cf445796387649f6042c0a25c0ec2b354f56c1045691b3a2e3b8d94619cea8c5a820be60e8a28170000000000000000000000000000000007d76a1cf79f0dd7380de524d909a24940daf36acce417e8c8c0c33eac57ca246283a359a4bf6533b963fb26d5a557121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119e06ae46adbdeef04d7c67cb860136a91c92c1bed8393d0a3a07159828cbfffbda22c3cfd68374196139ba21c85f4c0000000000000000000000000000000015cc4ce7b76c1605111526dbc37298691d8493391168739eb7a742c55b8c25013c6a0df9578949d61509f35ba463a3dc000000000000000000000000000000000a8b0a36df049be37b4f0866a1f41159d8dd9d507544c1267394932be02e11502cc1609f64338c8d8583a647351c11240000000000000000000000000000000003a80c653ca122873ea273b3a1e0764c944b542414baf07745747b7ce29953ab82e4815af7d9b556ace7a423c7f6c5ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7d0f058317c6356dd2c637b29f305b0c13d7cf173a3373602622f953955e4cefe661e709aa755da700765a74036f7e0000000000000000000000000000000013c09a06ba5793083eac5d26d3d6322301f4b5c1d28394bf3894b370c6b8971cee2d83e567b60fbca66b26c417d747a00000000000000000000000000000000003aee9c68ad01518fe494e9898fdee7d321aa7c5b19e56b47689f3b608e90dca019d552dac286f900dd86073d130403e000000000000000000000000000000000819815295994857911f23ef11aa4c3e87d47addd68632c8baed783632ecc5fc0334f83ed97b27c1e0e2b5ae7bc260f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000947a7d5745234134a6a92fa82bb473952993970676c57111f177a25f91f7e320debef01793b695f9d0ba9e4e58d9fed00000000000000000000000000000000017a716846e63bf0eb295a0d5130b76312698dc014d2fc81ad1547e04aaf7589d2f6086401d067c308ef5d4af0bd95ac0000000000000000000000000000000015d713e8b563ebfd793a9601d9249af5961a5e3d9847f66c092d131a96fd2b324849c0a7cb7d6614c6c4e579eb5b26f40000000000000000000000000000000007447d1ffafc8f2707ff4ae54b52e7698478c6ab603bee5980c8d752be14a50710aa5db0f85a6c5d5a00d8274b086bde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d450b292b6490a838b29a66a884f284f41d7cd06d10c8449762a05de84ec60f632aef87a98341d4b620413b6321810000000000000000000000000000000018753afdb6d354cdf995e8ce5d6cf8c26925095138e9cdcc036d29baf371cc767c90073748944b99ca3e75e4262c6e86000000000000000000000000000000001616f322206a510bd6cb941dd5b356002d9553ee380bc696aba51dde1b4ebfddee526c4d053d4c332a4d3bf371206426000000000000000000000000000000000e37e8bb5392c95f842b4dc5ba20847b395dd655c52273c1545b88b73e776405712d9e2c5958b664eeeb37a0cf02e21e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ab751f154b374d605f7578c4f67373ec40d7cc92ec4da5147187467eea751d367c882175d745886471c0b1096b8461000000000000000000000000000000001067bb335c4932df6bb43cf8e7da53026bdf1d7075e7ae437fc71ff6e44dd2ce8ac44e2400bd096f3ba585de00982b7000000000000000000000000000000000039a4e4a9e5b004c783cb8d63ac99a7d2765eba6e0e23c165257375b6d178f02baa400af6927a6fa19d1324069e0b0de00000000000000000000000000000000142a9b02e7c0a200a1970d8c692eac5e9f3a0c01168fb77201c25b72d50713e838ec284b897a5c1a95a25aabb226d73a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a7b1453c14088090b02721ad06a420df029e422a93a1d6c810a4e8352d1bd724cdbbbaac5b13483e83b31e5e4cbd9e0000000000000000000000000000000000221853aaad3007b02e306348b3d94eddec8bc8efac253db3c30916cf57365daad5520df40f8cd707c5db75a7244b43000000000000000000000000000000000f08805bff583b845ee4975e882c3bffe7f8e3a85b68ca5edda6dafcb1bc512f4886ab82ebee7b3685a3ce024fea2a820000000000000000000000000000000005f1325a3287b7c1908d7c55d0f6b336570df5634602beaf60f6deff7f581ce3fcba2ea1d92fccf35b3dfef8e290fec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f205bf971908ecb4a65c4e63fc306b9b461e8ede63a68c561dc1d551df3081bbee4cbe7172a77ea1ff915163b3cd79300000000000000000000000000000000073bae42f2a4660e23a2cfbeb736d8856846f5b52791246ee827a0a08264cbbccb5b4f71a386f839c495efbcb8f8d64e0000000000000000000000000000000019abd20b6310c806cec9bcdcfbda88de5b768ae0a7586a8fef782ec30a6aa46c39565016c46820fb3a022e7c9f4c54e3000000000000000000000000000000000e40edfd794d78a8a12e5554102cece5d913d9d73a631eb5bcbdb454e83f25f95186c0d473c1ab5285a69fae7e7f5e231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac3f140b916ac41f4951bbde752373ddfcd16bc8751513b2b4dedb0701a8d0506365729babd550eb5a0522fe33eb9450000000000000000000000000000000017bd5b18f07462c8125d319d6114581a5bc062e875cc4923332d764116b046ef3ce5291676e7320a637a51402519d0a700000000000000000000000000000000128fc30d5663160462ac5c37cc7d78b283f581e8314c95483e127cad332c9da6ef806d0fbaa9bc84c2e9300bce8a54f300000000000000000000000000000000108dc8e698873a0986dddac9fc7df093205a310814a3946333809f59530b4e693c1ea76823eacd23a88c1bfd0e9e2ffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001677afe25bc2001bb94ad58564ea21d03ce47e8b9eadf1aac423ae503e530a5293620859826fb9892d286ca5a125dbd40000000000000000000000000000000016a9b7045ab93e06029d496f37c0734d281ee42bfccf51dc205baaae5955c714950eacf781d9d2b988fd0bf824e7497d000000000000000000000000000000000a10fef925eaee2a04071b5541202fcd6a682c595a92442c12d11ccdabc7b856d840e176d0f6e72471b916ffe7391b6a000000000000000000000000000000001199e205ede10a6c03a46948679516b0a7233a060f09772ffea5f9599aea2b7ecdf43114aa971f7f6f5a16a37f0d97ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000918ceec090ed53acb35e344936e5596cf2a49b3012ac8f3fd7d567352bd7732795ba09ececc03fb85855734012affd60000000000000000000000000000000007bd7b4bc967ee3cc426a2c88b38bb9f128e38eeb3385dad84294d07c9484d3b950d074dab4d050991428e21dd9e216e00000000000000000000000000000000045a843bf4dc5e48ae5dc86ae52d5cc12a90a7ae793088c3a8d116e282b3cfe5807b276e9e200ea56d6e0189b2cad68b0000000000000000000000000000000006c6a4fb70531e80e2a74a95ab73671ed1cda57c09a288cbbd5338a3aa5c5b9a981dd598da0150be5312fc375132b8541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001214730589398bcbcc6ed54a42bcdca922882b2de89cb2269b17d05373353a27c7912bed4e72c523a86987086d16601d0000000000000000000000000000000019837596c1decae44ccc730825f089dcabd4c76e75af7d60bc19361b48ddd8844a1b514cc9955970fae28c1d644a7e21000000000000000000000000000000000060fdb650d58ff7d51630882be2824f99edbe66b5033e5ec9d2f31fa553ebdb6fa449278325f142234e77a04a5189bb0000000000000000000000000000000011e98099d16163377acddc2815759e49ccb966a8f9c576e76f170052ec657ea430529e38ec45f8ca081428546b1eb5f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc737a7d8f52197ecbc2146e824af51195d274a54e9e5dbd69e19990e340220cba573f5207dea8b40721e0f56f01f380000000000000000000000000000000001542b62398ff36b3b8728aa7b3ed6804ef413f23bb7e12ea15878f02da86a04a6e9d8a13efc269d8c14581f745856ef0000000000000000000000000000000011810c75066175a635f0cf7754d2e33a1908dcc9bbd7cc3cdac75ac833e8181ab0101c6dec9f224c9aa5574897ff458300000000000000000000000000000000001e094ef463e9a97defd4d56ce3ca1bae2e0a60dc41f73ce40bc079d87e8af49efa159dd9e8342ac66a6bdd6130d97a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048a6225474b874eb2da78811c547fd1e3121c0b50bf6796cf8aed75843d213d697b7d191638013c76f84c471226e3cb0000000000000000000000000000000011162f656c6a7d23f088d9fcd49571916d22a7e6cd3ef2fe86ff726de1bb17c0e7b0b801177a281b859909c50ff0b25900000000000000000000000000000000170be00763f37c24ea9770e1b0d65f0da228fa3058182492d0d76a412716932da3aac7c1475ac7d24047c010c75da50100000000000000000000000000000000042d05e315baa0918953cbaaf5e0405938d530da7b2af79b45d08a7626a350a805548404c227734fac6ec3d9efd275a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c324e5464d181537d0927981369dee4c5096f954c3107c8f833e2b7dd074ee5975309632bae27cb9e9c4452839cf43000000000000000000000000000000000327d814b133e3acd46191a54b1f76c12774dc94b32abb981eafea3fc4973fd9f8b51e6d4b7b2223fdf5dac13993057f0000000000000000000000000000000003acd25c84a06a57d1ab647f4696bad89008700feb71ff5113d33d27de3e8c10cdb76163998bb524e264f58b8023f98300000000000000000000000000000000098f58a050b09257dffc6a0719df7c981d6db50c613c6e729c79e68bbf56cc906d57f13e4ad5c6185492ba4cdce80aae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eadd934078a269b9ec187565eda0995cc5f897d787c0a6d9920795e7e5fd78c1db4a539e8a5cdafae345c6dee076175000000000000000000000000000000000603e7eb63cd030b17165b5552d3cffba2c7e203c79d326a670bf2ca8fba23a61d4da57fca5dc50f0ce7c6979c572d8e000000000000000000000000000000000999ea045d4d06dbe91897679e0be156630a35ab621b608d42168e830ae98c24c24367b942a81f49c3380d93e059e1de00000000000000000000000000000000023104b2cdb9b9b5971c83cae56276f84fb6025d999d6ce6dee6565a0c7515e1623392af69440428f3bb2ffbc879a4371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026edc1261c971704203e2afb96040e4a70f6de7f36fbb12d7d4a81df000da1c5697c89d8a40fb4e5ce369776f72fef5000000000000000000000000000000001210276e48310085d930360a3fbf64af7d66852709484284ec21a63021551b7473c6cfcd0c616df74d983037e9feacca000000000000000000000000000000000a26d98b75d0c6a58f462ed42c3381b63047d2f0d84fda5c6b6130b3fa562f88170546162ca4da276e7c72e4c20756e30000000000000000000000000000000002823783ca66a90030f57c021008e57600a248ca2b6af1e4e0c57a60ca5d569584a64fe2b5d8bd2960500fe823ddcbbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191c3f2b41c25376558e2a3d49b793e24907867bd44a5d19f904d564225562a566d1f65a8ad27ef52873355b63f930400000000000000000000000000000000008c325b1a5a34ca08ae1e9adc5743a3dd773eb221f11ec139a7befa7e40f32743db72e6584fa7f29a8b101e6edbd8d650000000000000000000000000000000019b8ba112353022bf86105b0bc2ef57aa723242510d368f989adeeec423a8b5fb49f97f0866ec6234c45f744b31abfd9000000000000000000000000000000000915abfa431c9f0aead9448094aa436f93b6296dedc09f3bfef135771ffee99e7c15b998d79c408fcc944a370db8a2d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000014ec8956700983e52a2c542c1dca1e416f30dd70c9e2bf7fc06d2385f0688989a17939512a3f06ff4baf7c28167e0750000000000000000000000000000000009578a388e8ec2c6eac0b4b8041788033e92ede9949ba4b2c0877407fd1f08d46a408e2fe8052a6f22a677d8f120d1860000000000000000000000000000000009ba315c61fa5000d2810a2ce4807970dc369a7a555685345ea225e972e75463e6c4bfcd67880eadd92bd29b469b6c6d000000000000000000000000000000000590415b52aa566db9819046dfaab890988e7aa849cd6a2a984e0fe3f34aadb2d9f9990968cd5d231227c5da6e3236421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a12b6d55161025d7124d1010d94a78c2023489b306a114b9ce5b6d92c7b4910bc7081fd8f1efe365f5380b83c6bc9b2000000000000000000000000000000000150deabd12adc63180d68c2ca320bbd5e13b4e6f1f5c08dab6a01ea6976c25bdbb3c7f821534b1bcf67303a6117e3430000000000000000000000000000000001622f25dc9e1942f210ae3a2c8d211879534605733e1d6895d190befe51a94acfd7281da48b49305b37be002692d11f00000000000000000000000000000000043b2de44a3114a7d778227b87cad83539dc9c2ee591f5b12867bf0a7c767d3167eb3650d179db0ec94c51e39bd271d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a366673494482520c33b209f32c884eb16bb28f3b84b0c814515fdd81f5a24c75ec036e29388068ddbdbe3f22a892a000000000000000000000000000000000c2fbe0263cf4dd2b938552ef49ca435f96dabfa799b09f234dc3a77d6dc3b616e288d1712ee51e08f5e24ad3fa184b700000000000000000000000000000000041a6b57f98541ad3415eba58c7796a850132c4028788436172c3ad39e792079a3d1427c6ed968bda1b84b95b1f30e890000000000000000000000000000000006605f6d887052822c1c67e9d327482a3f1efc29ff812fe4d929bdd9b055c0587544a2a646c0d224503a6ceccecfb5461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af33b7db5b9f73006a38559b592e1a7020f4a7f4be7428e27000c3367566606ee7d38c32bcee41c098f58a1b1076e4a000000000000000000000000000000000351d962c78a15fe1daf5e2b865e928ef5aaa3cffdae9f97d3b21acb6177d39365b375fd04de7922bcba3e5da431a7f60000000000000000000000000000000008f4697a47749c2cb8aed7f0b71d56fdb4f2c956fa88e6b5fced446529513955873e3479706cab0815447ebb7fdacfa10000000000000000000000000000000011c17b8d4d15586bad4ca93ac2e744043c59899c8b83ec38e3f9aa989384ed9daddcfabd75842663968bf32f595103ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dbf698bfaabb9ca004e08a97413bbb0c1ba0e95d9f10b0776746f38ce9fa8cc0436cc8027c397af2a14236540544b2000000000000000000000000000000000f1e697c01493493fb566613392b2ecac783e1e9167fd3a58dc4bf059d58132684559cfacc6f814546630bf50eca75c70000000000000000000000000000000011d31cdcb0a0dce0c26d46966a85e2f9055df822cb552a9a7a507331b064861882ce3e011ebe2711d670ecdd0149ce460000000000000000000000000000000019847a13b4e9c1d4c2558dcc38aa99d82585d9fe275930ab9cba66f099dc5034eeafab71002509a86fdca96c166015a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174053c2a210af01ed770e465b91c9fe68cbb4ebc66d7fa78e59ff2020f4bec3bc9b9b334999061768abaf45d47f91c000000000000000000000000000000000186e0c335e42464c15be0906241ce4c825000752eca97e75e5f9aea54c08a17949a38e95bcd2ca22052fd72d834aa55b0000000000000000000000000000000002dd632e73f60bdcacbfb283c4b31e1b13d445b07d27fe8314a9fed1d92d31bdde67511507fedf32923d6701dc2a06b40000000000000000000000000000000001208baba47d33ae9a759a975713fde99ed83753e42d53e7d605d62ac559f41ec7c1e6744cecb4692b53e6abb504a68d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9d16daa2e85bf133889ad7f1d6f0c109785f9a452277df1b09001e42290305c93ba390b12c01859f53a65dc090f5fe0000000000000000000000000000000015683968b9536b8e9671e73270fcfc536800fe281a00d0ba9d94857f901c5f2597ed0ee83efc3b852f542d209c8c8b6e000000000000000000000000000000000ddc09a6a07e48f8397e420aab41ba83b252b87cc4f2c3ab9db72b723186cc58b8c406e98e8990f8aa7f34f4d97bfe7d000000000000000000000000000000001911af855f9286c3d267c3ef5f754dd478790ac984066e9da6fe94b9a4e0435f5324f2afb27a7334bcac4bc16915444b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ea86c0d9142263fe85386c4635dcc0370cde6bffddd6f318b3065a8f36de77d9350bef213ca8d35f2780f0108eab75a00000000000000000000000000000000179428fc33588671f16fc336153cee277c14d2832b985d4d2f7b241b60ba84934564ad8fa64a51b69a9dcb3889bf0329000000000000000000000000000000000830a1ed942f5798e4b2f9d4c52c499a7e38467eea256e4ecfafb086863330857cefe616a4f8295a7ffe284e6d6aa01a0000000000000000000000000000000012fc90b45a63fe384e2d4a28be0ba84c864c1e2f0017748b4ac583231bcc24d3f3f3789f0626af958aa9b853f81a2fad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128b32a0869dbb75a60e111f477f7be506e2c1dbaf60077aaa095708f50d46f1f798e906aebeb61b1de606dbfeb69e01000000000000000000000000000000000b58c2ccc697ad3faf62cffae10b19f397a9cf06e48c44a04fd88e892c94ddddf84d4ff5e704fc8dab885c7191d60fb000000000000000000000000000000000082ebfdee49151e504b0b655a331b3a6f7956f69c9743bac327ad3c409f074bc907fba028b666c7038cb201ff4d80a200000000000000000000000000000000004e7c3c30347b99099171235b9c1fa984f46a4ca28447d25c3e76607234b6c241c54295ed5d02a8f9cd1f461a08af1871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138590925d44de1094c7a96e4655f59952b029596eefc866fa7ad4d0e01d921d522e9c1208e63dee1bae32ec3326fe770000000000000000000000000000000008845e0b9815a4a52af52816d5c16321d6aaac1c626e0c6a56f87ac3eeb3258519d3dd2187ba7eb46b26498c938c1ed5000000000000000000000000000000001523105e3b6372f95b245151fa3f88d48c807f07d9923bf7c070b91dab92a60b632990ff7fa6c40c6ba7e563bf9136f1000000000000000000000000000000000b12962452ef2f26b4177aa5e5865a67dc7991566fedca688d328c81b6d371470df5c31e816d23e92e68be8efa4bcfb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000110b50fa5dd26e83c68db04901f9582d31bc2cfe9bf1aa0485e778a4d0d3a0c23d46c0618ab7cee7a99b045d81a50cda0000000000000000000000000000000000cee5925904ec52e2d1bc6d85c001cb6ad950872f5ad62fdc3f43d786672f6d49b09919d24955a3fe0a0c32d94c28690000000000000000000000000000000010881b06e37f254317399198d97aab0199063e32e0356085fd39bfafbf940a82884873c62fcc77358baee9b27b74be6d00000000000000000000000000000000008e345b7d8c70b4e5d73747d2eda4a728c25f7daf95908f5849f64cc55f16e833473e058f003d49b988bcb9618d56871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d26eb9b04cbf4ef20ac9971c07e097bf2aa2c7a5a7414b70436b2d224d7dc914230f6fa11ea0d09336d37811a593f800000000000000000000000000000000141962f5d7779326e22ad5f832e45cc722fc855bb9a2282e0e8cce5c127da56349023953b5c9101278708f72f6856e8c000000000000000000000000000000000349055eb7d7daf85d67ef573aa9065b54e27f2e604a3b231cc79604e2227674ff97adaa85dc8b93c1e413533564485400000000000000000000000000000000157d8a568192df21246abc0881b3ec5d923ec01cfbeb3043255361ab8d3e511f844d536f85c3e4fc8940c4d7f47a99451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c0990ecac73ec5e0f2a18235ad112cee766e077e6fec2734a7c8a26eff5df3cb086e31284a57e100c9289c977d990e50000000000000000000000000000000015d3e5aad870be61da6c2ef5bc7576a899d3dda98ffb44095ac6b0d5f3ef5700dda3cd6d337a313859b4c20f43b69809000000000000000000000000000000000b6cf8bf5b9a24094f2c5552e6bb7719c43642e6b49011639e627422025074069940a0f5c081d8b7a81b1323e46cf26600000000000000000000000000000000132111b9738632e6324dc37d28f26c4f6056b89cdf0c3fae88ce8f2ae4fe45cdb142c22d4e23a038ffab79b5e2ed52f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190343f783e1f07ae0f1912491fde13c97b9ce6e31f36b58e85ff72d77a76afdcf6055255e4649c26d4f551f8b50714500000000000000000000000000000000010d32ec06a2c8a0bba5aa78bc1aa4d6245e7d0926439a19e5a8dcaa0098a405c6f9de55d9962998aec93458e88930bf000000000000000000000000000000000f89b7c96a73e04d78d8b830b3a3a9053b7cb26435e600566328fc00f7aa7d360e03584d266a237ace3181d4670cb95d00000000000000000000000000000000011f15205cb90f8172f6a20a3e8b79f1cf24d5e501656753027a1a10a348e73dc0f367159f2d231d61fde963a0facf861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028d061359e877e5e0b47d483ba7c4300e165bd82643db3c4080c6687f0ed0036bb6824c5ae2ed2aad3ac23931041a97000000000000000000000000000000000ea1f117083d92e37dc5c4f18f382cb9c4653e3e310e4aebe8376cacada879bf78d02264d818b5d66a11751577443eec000000000000000000000000000000000446c345cc07b77c126cab545f81bbbb2bd032f5bab08f48fa20a89b2f74734589f5724af7ebb3d3ab8029f8ddbd61c7000000000000000000000000000000000158641fcaa72ba48f3b7679374bea18a982f3b7c99ef9a3905599cf265a22a098f574d51b0c76db5046375a198172ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ce5a15102f54033d4d466330e84c69888a3f85b565d2be3cd94c07f50e2ec49ebd8693a27fd6299efe11c9697ae980000000000000000000000000000000000ccf06b5f37a29fc123d4ab2e93ac9007bfc8090101ec836eea6b0dd134658927d4e564d20165583427b33fc831e57cc0000000000000000000000000000000011152f9a638bf19413201b6d23d0a48b62cea08483c07790748b00b94fc6da4c4dfb44d5b9e99f79cdafd49e8de9347b0000000000000000000000000000000005b86e7d7b9cef3577ab1334d3135dfec56608b74c379da56baaadec95a3a756a7218554242ec424f85ca1bdc6b482991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008995fb9d42e98ef10a903667b51264568ef3f94272d96525208bda18b53931feaff4637ae5159e069eb87d6281586cc000000000000000000000000000000000964831905f925e37f68931b28dffd4d3a90041ca45ea1f1ad4c3bfdc1119c5f3b0315d9f5e8fd10a1f67bde61bca38300000000000000000000000000000000051482c6c3ef5e5d61ba4a9887f9e7a1676ae7b75de2d7e67fddb3ee768e9e0aa2ef124ba09c9276c463b1f5dd6f5b9c0000000000000000000000000000000018977c22659c6b83ce7cb08de4a5823f5bce4d519b68c7f656773023df8baf75d4ed199fa9cbf1cb9ff656fd8eba96be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c4e9b32d7bfe385b98110d836675017602a42e8df4f2b7e77e737ebfef996090c0ebfd1bda3db070c612befd51f4c000000000000000000000000000000000db615e4c3106bde31029be8d7f5b5c76ee5f5ba8b7d702cd64f0a047b0d1d80ba97d82db1304306fb73bc9a8140af4d0000000000000000000000000000000008cbf29a7a0ec4ae170640cea4801f7b3ab7c8ccde680838b06f81c655672e9aadfbb608098dae657df1f970a6107f41000000000000000000000000000000000f7c30bb58659b39dbf658d742e4a2205dc65132692fd7d72859ef97e465c958c7bdc651c63778106a3d9406764b53921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000259e94891c1fbec71412fcc61e37b29a42724cb7f90c7c875d96ec06d112cb98d24d771b7b9609175f3deaaa7965880000000000000000000000000000000001359ba3648beda0473c81d10adf3a85889a2a6fec9c10b5f220154fa9b8a624b576c9ff5d64a4cd8d17754d110c181680000000000000000000000000000000005b100daef0a9a86e81d7c39e9bc4c803246a0b8756471b4c7e0e1349074ec1103453dc6723d63d7b13c47daf1e2d21c0000000000000000000000000000000001ceae1ef3bf4500ece7ec465172c4f8aef90f376a0b5d9da5178025c601bafac663b28da2172366ebcf4be9104091711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050b595b77d2d9f109128c8c06d010ae9b8b25aaf8658aeadb51cd6f83346d7a021d93c74f764abda540e33eaf1f0f4a0000000000000000000000000000000010365c72ca04d22bbb30c79537b43bbef502fd75505b1d90b157a0481477ac7edc14181cb4a3f74d257ef0b2be6341ea0000000000000000000000000000000012da222e5586098fed478d3ff55f8c6a8ac89f24e6d92b5357da0eeda4cf0552e001e932054012515842e9548be31e7b000000000000000000000000000000000407c50f2da3f27a8794eac8457d1af8a2885fedf929a1822acfed6af9e0800712eb1d8d14b6e6e0a99cfce84d8f55a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff45aeeb951e36417ef7f1c2978c5430f50b5361e3371d20e2740e2784ac9453ede05704776b133cc649066217d403800000000000000000000000000000000150ed0351c03dd47035c19233281f6e09a1d175c90b54c95142f3e2ef6cf1c08501647e575ac7f6e531180ec26efc15a0000000000000000000000000000000013ed61f0563217180c85f57c62d822139e6a6bbb4684dfd98f0c9eeb053439c447eb0b6f4c1105fabfaf77b1cf5c5ce7000000000000000000000000000000000e1ec166540d0e5cdaada7d7f06f6531d67ae34f784ee56154c1fb4a403fa27476c4516df659a617d44f9f8c7373d2311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001306911074201c6fc5c7befd1f1322edc71eca8aace4cd00edddb86251a03f7d195496ab87efe206a09b18e78b511369000000000000000000000000000000000a34e81ab13d9388d0c22dfa481842adbc36643960e5313d1ec7ff2bb8f3fbd2231b1e4a4fc704cb26a7dccb4b46ed7b0000000000000000000000000000000004b5e015365361589e4d1023d5017362e2ec60132da4f995e533840d3037e155727343d94215897a8caabd3f3399334800000000000000000000000000000000152bb3a60f6df60b43bcf16b4ea92c9af7f2bb0af325632e9882b49df12d8ecaa540b7f1efcbd28ef6a98eb7e8e471111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa8657f202973be657d76c5f04a6b2003652a37ef1e2ba1e4b8ea28d9058bb56516d000b8c1fe5da602ebf11275df70000000000000000000000000000000006a61a1ade9dcaae52c7168eb4dc99eca1444a01d34aa00e9234ed4ca5578460200a43be568943817f94e3bdccd9c74200000000000000000000000000000000006d00305a5b5d58a9d7ecfed94a14b53f7ee40b3d1fd471f42edc3509f303116357f3e914dd0625dc8b16b6d37963f8000000000000000000000000000000000ee4531ad2131a6af47928b7565ddb06f3100e1b773286a558a0f8104afa928a65155a9ab7ca3c641fadc0ff2d5df16c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ece19b680195af6a04fed72fb4f4b053a78b229ec228dc721b96cf64138763374960b2abb176fd2f1a4cc17a9db130000000000000000000000000000000000efc31e647e5ab9d6d2c0f1e0b150744d0f646c0a8d07b13ca8698cd1fcfd03bfb495f171b2fbd05e7fefbb2a66a79a3000000000000000000000000000000001512d2d7b745536b2e11ad76096591d8188310c1a12d9a5502b7ab288806182dbaffae07c996a2cfd7417f68df13b0230000000000000000000000000000000002559ad9aa48cc71e979b24cee9b726d2be63c8eceeda88dc6fc38e5d8057f3ea07a7c3014da122ddb445fcd455faff21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018efb469a3016d798d2e06f2b5bd3bd9b950398abd6e99aeea62b81b7dd69f239bb8f840459ad1f133ff99bc07f10bfd000000000000000000000000000000001868069b022300888a4232789d8f4b6ef18b80a8bd169eb428cd7d901bd9e5298e5f175b7feec01417634c559065fb2d000000000000000000000000000000000c38e93398649ff7bbc106bc8879bc128740b0e99deaa19088b7fbf714ee0e5803a95503f64eb6fb9b5db1002d4446ae000000000000000000000000000000000476664b4f273f369556759d445c36818468d95b17d6cdb578b02e48014e4e50dba33e1d788b8477356964c0d3ac1d3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072d11e49ceff04761075b5bc7baff4f29358c8add84eb9345f549d20ae187d1364d0e90a69ff77ec6671ac5ceece5a7000000000000000000000000000000000cf0db9697145ed6675cf566ace767b3aa3bcf500bdb7b83a226c6564a77982a66f326e7bd96fd38c68caaf1def3f9880000000000000000000000000000000014f29501e1fba6d83667bf0f375e86616c9b8664b0cb3b063aedb182f00f681ad968c3743a226e5a553e6ea6e1a7513c0000000000000000000000000000000014162d123d9bfc2011e8cae0907d34fdd23f81fe523cd405bcbb6c3afa6870d6082463bdb1c6d6a03fc97009e54ccc951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f79a1d41d66a9c297cec3c6700118e1e6f8753b4bede4c4bf49c0967bea8b88f2dcbe3100127873ecaf818bdc828530000000000000000000000000000000009cfc26a7c40ca7af7ced150cc8252fc7255b514cbcbf337c2a71a718b893025bb97e8536d0443ba1be16a9970faa963000000000000000000000000000000001914cd6232cba23e7ed1e4d3033382ac5f294258a582727a6965b4b6a83df4532c75d815027bde64e6531e3e8bc1afea0000000000000000000000000000000003f8defa6d3005fcab86545b77dff0f07070df0f2f11121a33bbcece40a05be565f189b4251067c380ab3822be2237ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ebfdcfda8097e504d1af86f558ca2a05470feeaeb8324217490fceceda9a734583fa8def330c525522c78b31e29fa7a000000000000000000000000000000000310d9b59f6c2c4bfa8fc93d19bd25b1a52549825d693c11c24671bfd8254b8d0fbf56797d7cdabba838620a4f196a2300000000000000000000000000000000079092b483f43135f66d0c56c89e159b7cc9073c314e30ae4339f6cf5743970d0714e61ff9904ae4876dd050e0cae5f6000000000000000000000000000000000b6753396bdcc6e1ec4889d3e387db9cc531295af8d1b342854307316064a082c0b9ca4d17d28dd1bf859117ea3444271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e10f8260ffeea3a67d97b16d8fa7cdd998574d524d7353f7b4ac3f84144ea06d02e0c79819b2fa88490030611fb9df60000000000000000000000000000000003de4a6f22fcf08900b1c567275c297e18f68d8910f35ad796783982852beefdb026345f7c6e99446e318de733eb87580000000000000000000000000000000019634d1c6f0c8c13f3b9e8f886f4df9978c8fec85e0da460e3045f2e6e18313f688e1c49bea57d3b592c551b7f8b4e4e000000000000000000000000000000000b64bced117c9c9706f1176fa14d06e64b744d4fbab32724c18805a6eb328b99be8b8a291a89a0a17113f1c1343b19f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091f69b517fc60e9f42d6ba5eef840e0f70274807344b7d8f245f7eb9f7bb3c41117849923a0363fbb4a9539b2ec7692000000000000000000000000000000001347e16462a3c64ebdad419905daad06b660acb3d260cb366ccd2fa00facd142e90c7453714a5b409b8d0eaed54260630000000000000000000000000000000017c5063061285d7645e59c59ac251dd1e3431099ebacde7d115ac7e10dd1fc30d99793a2b9c163923172a816a26fed510000000000000000000000000000000013062499401e6da94bce3e5dccb1e7d9934d0f53c2d52d86c18ccce7495c2e5afa423bb77c20ad394612517dcbdd47b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ca8d5dee12cf738f2f9f9ecf53d6c2eacaf8d75a492b71500e1eda35da7184ac9ffab308b088f20dd58b551e1cf0d9000000000000000000000000000000000e1974b5a749145b5db2e4ea92a2069d883ff1395cbe86c1b1fd8ce805528f83be7f6e930df5650dc64bd07801e9fc11000000000000000000000000000000000609542cef4458e08646b3cf17810f78924fb8312e78c1e103c29f8bc1abdcc035c60e80ca7707b9edaeb99269708d2a0000000000000000000000000000000019bdd888ada82bc286625bf541bf77eb35c2da7a6f8976bce668de54abc487f1db5c430fd5ffa493468b5e297fa173401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000630ef92f342dc773dae4651b6fcbef4c845575807ba9cd5b8dd6f981cb7fd2fd4b163dddea3972b04d23887ad974680000000000000000000000000000000001fb32b9489d3fc282b2a70b2cec39d99315d186593c3d304ed26c0b14fc20fa54507041dbf43394f0da96a56a0a6cec00000000000000000000000000000000022c499172f999be2af9a93089c80ce7fe57c8ac6e8610978dec5e495b64bbd8ad517a1a61587dd72d043eaf914922610000000000000000000000000000000007939a48a63ffb43539eb30340928d6c58110f4f557f8e4daa197ebf4a0fcd61f822b3b6a52773dfb9bde2b8d39ebd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d5e6ea7c1dddaec5baab08057120b40f196859bf80b5918a2d6c8a3606ef997acfcc3fb66279c5547a55888da2d5c000000000000000000000000000000000b59f58af7ba84ecf55e34aa54466a00e3f998f6f3651d5dee1145324649b7d8d82735e903fa0725c39861419a9ff7b400000000000000000000000000000000051d0cef4f015624d6f77aa843e3b56ef52e5850708fdd77e0c7a0741147c9bc4b031d3397c93c246de9491e9fc6c021000000000000000000000000000000000254db2ea46942d91266c024da71c90893910483d9c9c99e3f8c31a815ce833f4c74744b2e88691bf188b172c6ab621e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f112b4970bc40e072508f6f933a201185ad921b2ec5a3439a0365c6556fd27bb2530b662f1284a561a5267ffd644fc0000000000000000000000000000000016d5ce6d71a3535dbf5be62f1010d5c47c54e9c8b357d829c140002839ac6ab2f3c6ee137811adf197047c1664f466810000000000000000000000000000000011d9be0a5c2a25fd33ff440ab2a0a8f5841c0907eb660d7d1504ae3e62e03994fd717762149124908d7def0db9174d0d00000000000000000000000000000000031206778b98195707c3718cff1cdf92b85d1aabd6757f8dd4dbab0d5120aecde9335b015f83560f334343a81ea9f6161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018cc580f11f3d2e20f97c1970ad668012c5bde978c440b48308fca0016a5474fba3cf47e77cccc9e2ccda2744f39fec00000000000000000000000000000000034d9b5945a68018c6a015180d78def431f65b07676e979e136b3e31e728045be774d97442c26f507a232bb10171286c00000000000000000000000000000000105dd3f37c20bcf2e4ae08cd3149f787e8922a772185e849da92ec0c16aa488adac2fb8109ca26fc4224668c708ab7390000000000000000000000000000000013997689e929c469d8a8f1341f1d8ef8724062c02204378c086758196caa180f632f36c2f2a1a3d1077d15ca355fcbfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8cdbab20f0070a72dfa2db96b4fa7bf30e215d6672c646e5486421b35316a5b80066188e9f64c82aeb198dd800296400000000000000000000000000000000161b5c23b3aea5e0427ac36e9f633d5db4525c7d0ef403951c53c022e662e285ea98e3e928326b0c288a6fc8205de6fc000000000000000000000000000000000955ae20d3f9172cf2ed4d45030111952274d7ccc1eaecf8b520cf7e1f146fb14cfc33e9d3e0eafcce2bb1c3418570d500000000000000000000000000000000179e08d68e86a002f005f6f3b21d6d123c7d7911f5a5073cf14a9c61d9d19be26917c8ccfdf406c38a5861acf9cf3e5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000104fb6888842a21c3eefba8abbdf60bbc28d68aabaa6e90cc3265e3ceb2c3392b8205c42f1ac2ed96225901737100080000000000000000000000000000000010356d6bf42a6c0f58607b4af0159effc96146b244d64fa5402153fd589cdac98d0a35e330a33b24ed68647717766f410000000000000000000000000000000001fe1b4eb81a364e2f85fce8f81245baf3b6b2de5881589fac07e4cf3096190e70b7d5b21db9a4a35822344daa066183000000000000000000000000000000000713173f9e67e528a53f70472749965da803700d8c718f8179acd745839d9a431673a6baa3748d68d7b5e51e08a1c9ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069bf07f285e7fc1d292933e840253cf3861dfff44d1f4dc48bcadc731e326753d898a6105dc5e109a9382868bdb20fc0000000000000000000000000000000008e9faad86dd2f2f8aae2b155b1afd990d8f1d0529c18de847e14577f84cd2dc9e105d805c65cea8ad3053ff56b59fd900000000000000000000000000000000195caf3f8a4be451e7423b3a1a3566c4b55d925f85385182f775d08a93bc50d7fb78446e1842e90776aa8dce02d38e3d000000000000000000000000000000000eac817c9c66c36ad0efb1b1fc92da15a068960e615677dd704b6fb458ed88812854449c2690bf5c9fc31af179c109601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f4ae5f3df2d025f567b37d9e23dde8a8fb23994475c7b85a7ce8a8c56a4fe53ebcb77b911f61cf8818c9c3ec16e5a9700000000000000000000000000000000059f1b087f545bc61192eb91d099a1615216c20d4965ab3246f53205718737bb7199c5c9b09225511b688f982c2a7780000000000000000000000000000000000d09ac5c318c3015dcd1db6ebcc6eabeb1839361c8a8b1e439dfe0127d5eab4b049763fdbca2cd5d1f8e40e823377f8e0000000000000000000000000000000003aa110a7a13a3844433f30f43e4261979fdf7b5aae401cc6d4cec740abc0ec1b853efe4dab9e3835cfda96b59f278061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f56d4a6b60eaa5acbb8eb0d8d143bee088c82731738dd83b74e99ae612525705f62f3ed347d5514f63bbe2a10aa8ee000000000000000000000000000000000474a13ca39f5f3d450c7c6f09fc0ac6f66652999062d41322786273f26eb41fd79d6d10ef5990293adf14edf46b78930000000000000000000000000000000008dddbc39f46dc472b75ae1dd280e7e0b9629e21f1c75b8cd70d951b1bd508b61f814cf9cd2afa15419f1b696ea0f77900000000000000000000000000000000124318028a059cf4c6091b1875a7e8da8325680ab7e71723b3f5af3baa0d8bfbd318208f0a5a8e65e07c26a731f6ba811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f6e589fbefc3b685a86c0804d73157548e741b60c68915a23bd4fb2a5b13976dbd350bffec4d6b699387b4cfb6aef3000000000000000000000000000000000373badb1e0f6de06235a44540801f95d321b9664f0b26b6389e9b5eaa9a3a6f066547b8560bea929c3331b5b56e04760000000000000000000000000000000017b6172dc2bd00fb3e8bda3b141ccffa52acf302dacbbf66c074c8c94f912c6e75190815381dc247d11d3f1d5f8441bf000000000000000000000000000000000beea1124c9f899749d867fcbc1b1b218ea3071ecf972823a3241377436e9e28bc73dca360b5da9ebbacb9d1af3f07961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014851ea2114886c5cf1c7f622d9cb09c0b17d8cb5e3f5338e1e876dc6183e06b3abd0241ac95fbebb58a7993122210b70000000000000000000000000000000018f556b21f923e4af217c90f0a80cc16425b12febd074c9738cb2d72b3cb2f82dcc562b3c012246ac8cd7dbf72906c8b000000000000000000000000000000000a2c855fe630961b9263322ea653187040bb415d2795596e1b2506b0a064163252ad3b12afc20bc80668e02664e33a720000000000000000000000000000000013e847dd86acb7d4d5a95f185311546959c8fb072f08fcc4b87ec2f191db3d96b87239b2b793cc4573861d4f84a12f4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001666d9bd55595213d99f1911ff0b08c86e4ba8688fb1a1e0a4f50474d41f79583c0c60ec849513d1d23a0486a8bb6063000000000000000000000000000000001114c8b5b5196b8b1223bdcaec062f5f25975fda1b6ed1298d6479c0a1229b371959d74fa29ce3f990bb90ab6a374cd400000000000000000000000000000000032c5985b2473e08a258f9aa189dd811ca7f63c5c8f040b7d5c62365f3a0d0c522a2a93927c2a4fe61200e9851e14c17000000000000000000000000000000000be55a6db7193c9953ba680537e7b5868d6395ed6db1f2e34c7ead02cfe86406c32ca17abf59534b7b6525fe01a4e1631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ba83bdff23b63043c05966c7d2713627f0873e47de995d73e273bf8fe112a0fc71ba82081484cf66b037252be4f51e000000000000000000000000000000000e360198c75e4b15c2b930a05ce3c7a59151550d815ff0f3c76f557e3430922e44958639891bfa29b97f33a99a0948340000000000000000000000000000000012b3629de66cdf4a21244d1c1a48521f4498302e3282691c0c2e04b0e8b1ba8a71bcba330e0d7a3829f84e8a59c1ceff0000000000000000000000000000000002a8d8c8ba8f1c3afc2acfae25a898e70d26aa72ec6ebbd61aa878da0a20db105b1f6e6c3c0a07eb8ee07e03bf55d7e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c569a35fa824913d6b33b5af5b1e276e42b7fbc79a6934d55872e33b14249a87e360fe55fa9c2a5c20b8ab99821e71f0000000000000000000000000000000019794a5eea6cdb571fd35243d49f2353081ebaab54f03257141af243acb5d10fbe5dc234e3e3a2b7079a8e764873717b00000000000000000000000000000000157aacc621ad418dfd8918a318311bdba8863683059848fcb9a2de1e53040edf628366482003575b362b728cb55ed15b0000000000000000000000000000000019f1384b27b50225167f47e60adfcb300d0a8ef76a0e6c7d73899db94d7aaa88f7f2071fdac9eb5fff12d48fb08c87bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b23938eec7c38a0fd5e23cb057645f05fb1db34d99b7e9f31feb96b9b614e01b73a84e4679e3aa31da923fe0dab0970000000000000000000000000000000018b47de2d462472d81651156dbecd10a0224a6da783c16d105918d0e1bfe7da122f225f4a8a90395c6e388c909862d6c0000000000000000000000000000000011992a81ada40afec631857b796538a6c80509e3304d9a0ec5d3a4c0c57c0104f69eb5d8508c70df54209c89f908ce9c0000000000000000000000000000000013bf6c1571d5cc1e5bad3836f766949df746b8f4ca801e9cb4f3ef754559a015f66eaf39d39d37dc2d61265769f8925e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000484da6582c0b120909717ca7d6ace183d752661282186224cc87d212badf4414dcf16bea2c8545bc3ddb7d64042b71d0000000000000000000000000000000002a9a4bd97f25d78751f8e777ba2556cba3d2ebf80ae0c7114820e7775218f4c9cee6ef25c767ff49737f998876665910000000000000000000000000000000004a4ee59f280272ea71e3ed2a1f30b604ce3a35cc64bd03a62ec544003a1a73dde59e3492c6356da5d8d2b63661092ba0000000000000000000000000000000008eac18e96c1b4d4cde118d3a81b33687ae5cfd66a02a78afafa47872509d7fc09b44e59c658b46e1ae451ff6b86e6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bdb50d214f8401ca4d4cb9cc2d82b3149679cbe28ad88a156e29607f27c737d2e29296a9cd2085259df5730ee659ef000000000000000000000000000000000e9fa2cd963d1af04102e15e89652997a26e94dd61b6d0211f05d54b9a3530dbf9f7901c6b5402a31f608e7ea807639400000000000000000000000000000000194709c73d0eb70266dfb890f7bac77395f94cbbd82ee08fde88027065bbb3d9574d7320135755ac1b5e8229b486ff47000000000000000000000000000000000767058abbd3ac26cfdf0e0d134962810499d0da5dbd3f3878f05ae5ddb397bdd253c5b1042cd0c159e91066ac2d8e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d93d44ed9338d5e3443901544dca6be218d1c2f7366fcde2d0500d90e2a08a962dfcdb5e5fcf690dab3eb702f03598200000000000000000000000000000000024369733b502268af50b48a142a0ca7b187696fce692a1ba735bdca6902ce28276b154885a4571f5a129f20529c40a40000000000000000000000000000000017993b6eaa970f3c3980caa3187c075e0a039d3b03f44d90c979e2e8727c76813a02b305b810f95ecb2011767fe96974000000000000000000000000000000001289023d71ca945b684c661db8f4cb67fe473ad241eaea27bc8508793934b69e647d794c9ff6e1678a564a927e14b7ad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107d582e8e252379d6536ea1c679fd877c4b081313cad7b5ee6992d10e3f0ba5acb82e1e00ff38e57d3f54a06ad4775100000000000000000000000000000000102c8e8ec91062e6a0cb23afb8ec1dfccdd006270133e1d8bdabfdb4968e83d078b0444e3bf812d1f6f7a4a0aa300b07000000000000000000000000000000000f583cab7dc9d7ee1497123782dd181fb1dcf213e1b4d3d54361d98bfc941cea0a7600d7acf2fd60fb60e88013bf40bd0000000000000000000000000000000008fd545c8c6a4a48bfee639ad9fbc5c7416bace5524117e3670a02aa7ba41146ce8c96961a81f7fac66deb6d891657771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f56c81e0b4a1c039f4a2a3582b1ff9cb15f244287a6f952721f05139ccb9453b85f37d811e28be09a67a49c5119830000000000000000000000000000000000441ed1314c4116b3b80abd10bf1c8a4f9f096ac224318541292110fd0fac4fe1689a63ee1c21ad14f69d123e0105116000000000000000000000000000000000f2874662e7cce59438e36fe378f7ab47f10845ae0053f07306363e42ddc803d1710141f6361c165444c0c48b91091d5000000000000000000000000000000000a74df92ca74c59c1050684511f90a94861569b8629827799de1f436fedc4339a7a7dc21c947fbdb72845684617a6ed61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001140b749d2a793b72eb1f3bc6b7bf399afd699396591879649d3666f04433de7a87d195859bd601bda7be3c0179580af00000000000000000000000000000000000387409869ba81ab3e39e021d50036d7dda56c68c1fef803ceebb6d96903686f52e45f888c7d24fcf2e57912d7c0b000000000000000000000000000000000166e863227ae03b8abd021ca3fbf62d2307a9d78bc0526da8bb483a905ab9a04e66cb828844444afc3926bf7f3f67c6c0000000000000000000000000000000011b4fd5a0246d81cff3acda857b6522ad35712274406de0f9791b4653c404fe1d132520d2f9d02776fde09d2f9cef3c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f05d4a128a71a58cc7b5a850ec072b4fed58ddb433b1f7676c5117745e88d91b19a5ebd3889b6fc4442eb8d4f98659000000000000000000000000000000000f8df5db366f3aad5935a29b94098cd492176be8a29622002ec84eda278b5b66082e7a49d8a224965649308599ab9f7500000000000000000000000000000000167e6977839b5c8ffd01649c661fc6469da1823c641dbd55964d657fcb493e958436e298757b24e8d351d30f5ab88ff10000000000000000000000000000000005b92d340cab98186c56556f50ece3f4e32a655557433a074e282df52e444ca79a4c92374d4047cdcb5de13d251f74411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000229d1f6c9973db384ac9e8e2cb0cbab109e34a9ff4313bae1b410ba4a24e7f6415f757419ccd999604bedda86e544ea000000000000000000000000000000001620c340ac98b2e2bbdce5157faf822fa8ff7a14e696ec2787427d17f8eabdd62c469e4bfc2bf3ffa5dcfa66595fc4ab00000000000000000000000000000000022830aec36bc081c707db713850aaac4452bc48a6e6605895cb3982b3fcdb2794e636ddd79b04b193ce28aa5371dba70000000000000000000000000000000009f026c6a4dd3bb0b534c21a6231d5d5cb870716cb986e7b643c4e43b856c98e8badac3ecfca2bee155ed81927f2ba8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092aa2d6d3b465ab5e509a3a69f91cd362ffecf726ffacbf948bbd1ea92b5ec77a5eb11d3092cab496fd5b791254eeb70000000000000000000000000000000015eef2ffd527782b718d83688175e9af1f7d2b2e432eceebfe07a165751de5ce5f66c241bcd0083eea5683302d874a06000000000000000000000000000000000524795efb4a67c0c9b4d056a0c4e94929388d44124ab664cee1877836a162d82608b4fd69b7f698cda03f59eddc6b740000000000000000000000000000000003c81503950319b3d00ede11ba9e6079076f977e3e882e635091c5ab13f8cd0e4f210d9dff7ae1a8f82a9c56fdcb54f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011430bf125f791ff10023d0ec99286222b96037d82980dff5776ec225c0b7a4d9406ab0631bc821f4118350dca8d10e9000000000000000000000000000000000cf8318aa3535caf14a4a9a1fc6ee354d7277c8297e67861e1057ee1a3e4d8dd14f9a924962cc68cd973fae63c1b844f000000000000000000000000000000000aff41c5b5537dc65f460ba9b9345b0c499a03cf40599250845569f79b5e5f7d4c29585e97ff0cb55973b9095afa4c8c0000000000000000000000000000000006b0c2f5d4f393eab7183d56f94ad7eddbad3a64678f68fdff8b5a567d63ce4dc79abea3f9d51e887e75718d4c281bb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167b9f8504fa52de2e41da1b8bec5138016d0c63b18528a4c92bc017560ba989e79bd2d6147050b6eb8f4785cff173fb0000000000000000000000000000000012f9e65102808da959f421c28d22dc6e7e4daa540e00d1c59ff0ce39d70a24bdc08ccc69c7d7784300a625282eab28c0000000000000000000000000000000000bb3e841c32d79115470b44c15f658a3a4025776c1e2f5f1c94b2f4d599a09992e9c0f598bfbf7f4627a2f9e39de9426000000000000000000000000000000000058012f4a8c3beed3054e32d1c2c1e216a0a41b7f1e64c3d604b3f8ae839f3b5e1891c6d3d1e50b47ac182511cd74c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194cec814380c21010c5831c74b3337d2569a3ccdd65c02e1910c7fa24929b66cc64095ca4d7d1abd585fb610d33720f00000000000000000000000000000000095cbe2e66e78a8be9778a983c806d3c434044df1c49d32e26dddfdc4c549014d368fbc4056110576548c8fe367ed7b500000000000000000000000000000000047fa8f3288b40cd26b03fb394aab6254ece93a0e11bacd90dd1a8900c00cf23470fa3438368c7758d16193ed8dc4ba9000000000000000000000000000000000ba4a684abb610db708470cddb163071a9fc01abf2132d839801d3a391559dfe65aee97c96487175e0e014d3d97fec9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e988de7034af750af33f638c62fa0a8a51186a0f59f17c746a51f926203d6180987f8c6fe486adf68a45c3d4d5a0b00000000000000000000000000000000156a3f22f153f2aca6244e31185359aec663a6d3cd3a15965bc63772d82210cfbc31f5a97780b0a4a9acec0fbb7fd80d00000000000000000000000000000000167a9584b916b3e5edc750001a59b6e93243b72b229340375caac62d17483ae33142ff4ab6e4bf46b8349d64808637fe000000000000000000000000000000000a079db6f23e4945ad18c43a4adc5bca36386f02078435c493f55e0310185d4304572585b409b2e764a2affb950cb6071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c33234da7eea050e79c955469ce0ad23dc8b24f9fcd8d1a5cf88e0aae8288df8047b221f9e935a5de43eb2097546e62000000000000000000000000000000000ffca4840f9406f812f4c1d336d03fb6259f4cea3cda10bfaba7a8cce381fedf3cf140459769908150a3a82e89b283c8000000000000000000000000000000000cfd3df51daf18e7196a6e4995350cba540ae047954373e8117157f2f598dc1371cbdcc72bd41a38fc58e5b60afa012d00000000000000000000000000000000121c8146ecf87a6f6741c9155b50def6cb323fa7529ca64d9d8441585fe5cc2f489a026d5f73c09e030310ef8feba36e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090ed22858be244a4075953b0451357e973f78a5496497828fd389e75f93d1cf125af790edbc1af082fde1a8ee43425f00000000000000000000000000000000137a4207a05c4da33bcd73c327de3b3d9e489a23ac30ae8a3762ce285ce61b8348d0ac0700da5398f078bd916f6883d20000000000000000000000000000000005a8f6c8ea74004f67cf1356f3a142116208432cd060d64aee37720892ab903ad052b0ba60b329f2d2005b6fcf3d1f3f00000000000000000000000000000000052b2b29c3e458e5df5767e0336739756bef3c146f1caf914eb224e5462dedac9e595bd2b4addae60e6d14c6a2edb67d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000945edbfd6162454a85622f3dc7af74ef158da53e4391f63532af2cdfcc5aac34ec09fa674c68c6b09a7c66efda4877f000000000000000000000000000000000d395e75abfb1c613ad98c5a48bb38375bad804f409ac1c34373eeb29d3507296e71fe5e39858dc23976824f68319aa7000000000000000000000000000000000652f6197928167a06d890679ffbc9ff72bb323ef8c7a918daea286a3f9266a44ec615934fc17c27342460bb2dc425b0000000000000000000000000000000000c90ce4c02f58954aebf368124abc39049fb3d8825fee47150c0d0f85334cba2d76598a28fc19092723d8f8e554d27c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158bd33903cb1dbc901c211e8c308ca3b502cda446f7434e7266ab254b51cd9edd96a598ba98762a29c31c5d6718a9550000000000000000000000000000000011e7594d2b0b31bcbb390caa42fa9e332554d13d86f3aee127c65768c119a302d9913cf201e5072aa60996b2039f45b00000000000000000000000000000000003bbdd1dd2c1875650c1881642afd3c0ffc996b1f211f9a48801579afda7677a67f5a0c49361307730fb62ec13efd99b0000000000000000000000000000000019a8bfc09f840a7d959e5675881cb1f0da62290fbe8b9412b2c00f7b0b9b5fe7cd889e615701affc2c890e16f1f3628b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af9bcd5c687f5d1904b45c1fad3f12fa92e41ab546d4badc4da210da832a5dc139c191910345161e5d632417cba45cc000000000000000000000000000000000ddd84fa783bf50e77276ab6cf815359e8550973fcec7a3aa00c43d156aa36df77cf9c34af2dee0ef6945a68528e041b000000000000000000000000000000000ac0fadb2ba465b6d9e1e27ffce8331c37ecaa6f994a29d84a3fcaf574aa8a1945a370f56d136aa006ee660493c620ea00000000000000000000000000000000072bfb0c3352cfce2e8173468a66ee23c81dd7b3d4322ee8805be1d8ad1224bcd81e02ef8e6af594c42d2bcf62f6bd3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f8416c4f75c02dbb04fbd2840d214c3da50f7cb1ae3ea57cf51171f9fb754342ef4c2a7e98fa01ce010a5400c6a640000000000000000000000000000000003f30dd8f1784e9ab30f07233094b67c22437518f4a27210b5762765c3094b9509ed5250e0bf75805e2b3957d43a55b4000000000000000000000000000000000280830549a36746e1e9f2f221385f865f9dcb0f8a7250335a00b8064bf327d2a6859f9ac730347efb6652324fdac00000000000000000000000000000000000050dec11250eb3b516e6c292511e7fa99eefe5a2ec08e0ffa3ecd26ca6c9cc7f683184c2c5019d6d9e85c229dc80e5aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013be3534adce776187a79a1acb16656195dc4c286ced57d10917d768d1ae4dea1f248dc9f12e33f352a4ee95c0d0ed6d00000000000000000000000000000000068f39870a08da3d82f9ca5e82814ce41a301b5c47a326f3f3e66161e186d7fc6a5d8e408bd18f3ffa1c1c91e326419c0000000000000000000000000000000011bd58c82f5d6f2ecb12014ce577adfe9d5dd5a66ebc82d09ff5418ebb1f567e6df884de19988bedf34e386523b7e4fe00000000000000000000000000000000157dd6392b841201c5c95fd92379b1e0547ebfe704168bdf434a227704fbb7b1b6b39aadf95fec74a8fe0e2eb5d9a77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1ed68d2f589049fc661fa95678cdfc3485b460fe496e63d193cb7f67879b377edb342f6b1e0b6d500b1396a0adf88400000000000000000000000000000000157633302c718c7f2f771b4e876f3d3ce1822ff0419f6cf151cfdd91e9174e37e9e57abbb3e9330f63a3c45a8a8cec100000000000000000000000000000000011e8a805da50e60360a8841c13dffda894957209aa7a802a847a111403e1b20a0ee6339c3c60927f36ead0a62f3c349a000000000000000000000000000000000d3479c79fdee6e7aec7640a0045de0b399c2c8df4bb785f639d81270febf55bc97af4cdbd1eba5c514ec5343e57e8211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046c07a1455c91ae8d9828ed569805d7451f9e45c8a2d44eba26a3582e3304ecc9c6afd03b7de00298ef00420a3984ec00000000000000000000000000000000072a8a431e2fbbfddd7f6793c100117f8be2dc2316a603617ddd2c61ed3a56baeed1f55f1721dd78c90d3580d1c94c9b000000000000000000000000000000000033585efb4822784072950e92a259f621739a8ebf70bb39d30c97d3b61924dc1b0e5ac4011a441d564cd2ad58f471a20000000000000000000000000000000000bed9f30ff5c9ccc7c9fab8107294da619f10db4aad2985d5cf3e194d6f88f993f07443544434de0665a24987d668a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a41329637cab7a6a439527edb905c3ea775d86098e24a24c9e4ce94b13174db56a8f6921a6718a06e39e4c2cfd149e000000000000000000000000000000000130ea6b483974b61b14743ab9dd13a21ea2792ececef70604f6d3c5824e9c94f85dc7895ec5af0ba526aa22f00d362000000000000000000000000000000000114b153bdadf64d5af36e2bad386c1a12194ef3bad5b58d4a2e9d57e94364d92c7bb9de2b282545170057ddfaa70ec900000000000000000000000000000000014985bef69873db45683d7e7ad160786c9b97a302345bfc4ea6cfc4bb141ae009bcccf786658797b2f59645aaa6206061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148fa58969a7e14df9547858325b801fd732b66d33e81fa73b994b462be0b937b75a816c47ac9786c70489cb1ef3103c00000000000000000000000000000000029e14faf13de377569f2c92657a617d57de6a2fac40d771a7db8fc09dcf6450582bd272b8bd456aa4a70114202c810a0000000000000000000000000000000011d45c56fb6ed8f16ea72539ae9bda7feb51737444a58dff3a4b2931a5947438e11598be29474270a7fab273682046650000000000000000000000000000000007c099a6c3c5ff9658b21e6fdbd5bae7f72638c40af8bf756cbed4e38a73ce0ea6b46b18c8f5bf3b9d2ec86adcd7f27c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d6d31fdd93c3b2777b3ba6c000f6c03ed95d0eb1ea3fa749340a2ac64a4abe7f8bcbf7e97017ee187cd269e83c5e2e000000000000000000000000000000000a6f32032d64ac1942f2874137c17dc517f184f31568c7ba663d8b9e8f80eaba363f7427723a8d645a70fdabcb767d3f0000000000000000000000000000000010cc8847166d54c47476a41ecfb43bd13dcd2aa9713e52c7a12ecdac81f6934977809d05e86ef47ae9625a8a233380030000000000000000000000000000000002df6dc7abaec263001b00de0263255dfcfefd1d62dcdf6539fc54d9e5a1c1c6762e369807db5d25d59fec7c016afabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e956695307f67e13142528c389ef03b1b30f6eba37fa39fece565ef9efb0d27bf52a1b8e63131561511faf269be0a1f000000000000000000000000000000000dbcfc00f7fef8b6cfad3a14af3e780b3aa6f24e05eccd1590f9e87b9ea902a17c94a357d14f7fcb4adf6bcce2b45755000000000000000000000000000000001323fa5ce5f7143096f8915696f386993945cccef09d34f178c5fd99a5463cdd3fe8b7e938800f990a89b0622e68478e0000000000000000000000000000000005705b775e8b955ed8e7f7e2dadff73f5471302ce81f5ff9e9a32a94f405f52fab2ae4e178f3478bbbdf2f18801c118b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118ed3b4f1abdc298bcc89f1fa21b3491e8a31d479748691b741c1638be6aa7bcfc3fca88f1e3a0e3b061a4375b2d85a000000000000000000000000000000000241996a5498ceac0e5745015e687e96390a0febe60f779925d9bc280c67e1d70c79b18aa80b0d45bd99e8d4584e78a90000000000000000000000000000000006716deb77634e0349612f6cee427631342f983c1d34397d5e48b2b33834ae2be01aa0d90cdcde637de3207d63df250b000000000000000000000000000000000b38dd48dea5e3ed33a78f484c64b4054b7baf2dbab5bcb6c904f2d3f68218f66ec2b06b2bf8f1e82d349d58103419351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6fbb53397b1d8fd41bd0f67328592efef653d1e1273e1f6d9e5fdc614517fb778062c79dd10aba8fb0c9b71530ad4600000000000000000000000000000000124a8b3c42bdf68bfd1481a7530eaed4f8b479b0519a66141c88b8ac22e01f438cc1050cdbc0b76e13c7da88ade43db000000000000000000000000000000000023543819ac26f3ff2718a2b17bcd2ebd9bcf7e646b86e80dc8208591a50c18e02535d33afc901b555cd0fdddb9cfa6700000000000000000000000000000000031adace62048946f92d23515d4414a1091c26b44250f0b3197ff6d6f9b6241874aa6d41559221904500ad05edc49bac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018b15011c164379dbbd6a62b9f6d7c169fed8a0535c1443b0d46cce088192a8ac239a23c6620a420c1d1430381f57c47000000000000000000000000000000000caf0edbe7865541405c620a4f8b4cf2383a9dda32e2cfbb78a21461630bdb998095a7ad020aa4d66319b10844621b14000000000000000000000000000000000b5e9a03f7ec113035ab45b42f31f9e8853a99606d9cf798378e70f38b52388990051d7508d34a69a298db36b87f52460000000000000000000000000000000010f4de7687f5b2084109412094194111dd4af2e0d8a8a11290face8217b9c5bb6e633a858276f3dbb58d3372e99e7a141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000106b4e04353f6a8a8d671c2ab617b6335e83abd0d361375cfe6061dcc22e2755121f1e1b432246c318b0b3ff20c2283c0000000000000000000000000000000010166f90b34b546f21a3c82a4181e20ecde8afbe594206da1dd66b9c609f77df06174419501e8cad06bbea96b35898da000000000000000000000000000000000f72e13fa6546ca33fa0349306bcd6646c6c84347bc288076ad7577d04c71145551a84959f44c8d5fdb3ced1dbe7fb7300000000000000000000000000000000191bcda76b18812a7214e0a4a0be055175e1c6b2a43aebd9a1a2413dc32ab8c358d3c1fa5900cf4e09837fa52a5a82bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107358017387b20c5db682e717595b0480661c1b921e80c8103d2fef217df55aa02e3f7d6941c0c6911d4406f5742b0c000000000000000000000000000000000d241cc4577e78cbd37400a5230bb519d647c51ddb062b892b6ec8badbf86f02e169b9284bef93ffbf857b743c28e1ab0000000000000000000000000000000011a7382f55fcf4539fbb6a9315f65c21a51cb4853a11de2e1faba01b4eb6d7a47a932ec5f5d2f4175d5a941e97dbde81000000000000000000000000000000000842041e7fa19304a79e8c61787cfb7ff2bd37967f685f0ff42cc784730a060b3392202698270584fb7682beb4ebd18f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000193a9dbf6afc1bb9f8852fc0a3e6467e5440816508596bdedb0308522df062ea6c72ada06b7a1023981a93de76f7a16d000000000000000000000000000000000c2cb6bcabf77177941428f632cde41ddbfe6653accfad9d2eb06dcdd587b62202d674db20431ba460a3d9e5eba75e2b0000000000000000000000000000000009dc67648b10fcdfef5113d992404eb93217e048b50c65270bd925bdf64c84dfd6799d58bdd3701f7a904b47091fea000000000000000000000000000000000019eeaf62c27199722fb89f5b119acc8dfd1c9163253df05caa138b091874e31adaa8e2951089ec76682e941cd0fc3c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c26d32e863b5a0a93a502f124a44e7e48c41280c6254f9f4c648a5722a189ff59295308895c39d4f75fc3b1cd6d732a0000000000000000000000000000000007302e6c17e291b19fabcfc10a754a5a4ed9b7de77e1f4c6f87c1ce162f6680bf942eacaae689bb885ea44e6b7a40f3500000000000000000000000000000000195391871b83f086459a8c078d3b25a692fbab2cbe47a6287cb98b47176aecb6522123195bf829620c7163643ef6267f000000000000000000000000000000000683c641c9549b0ac23b42bffa198301b519840b6e92c3586837de2a5925e684b0661384e51a0b8e93761e9fd1e6b2781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126c41359a52c4b60c70086eae8bac5da31d56057c395ee4b17415fa88f5a0fd04d55c217f7f9bc3d442cdf7f4d418d10000000000000000000000000000000018169da30a973e7ef1f491906acba73404c52055fe272e969fd9a7c25d11ec0771d9ef571e6474f7ea479250193b2fcf000000000000000000000000000000000e8bc103708ed76163b5e355c84fd17865b7fa8a0950e39d2acf8c6f3abd9fd273d8060f585f2799cf98a3b0dc10d93a0000000000000000000000000000000016e37d22c7d3c66a114441c96b677d829b53073eb4329ae0f6965b525b6e32166a0eb0cd98e7d690517bb56bafc9f79e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb9fcf8d8760a1b8dfffc1bb281f1fc991b14f79577c2f8f95dab4940b6c13c1d88c37f3b7ec047939fa4120e5c3b72000000000000000000000000000000000ac99677d25a78583d559de1806514442353d8daffb44a4893ada78e1fd394e97b4290b81bf2c85af42ab919115f7b5b00000000000000000000000000000000016b5b61b3384749f935eb7e47072aaed4149b54e1ab5b4ad5608d3c7557363ee84fc0107fcf150fd80f8797248e2370000000000000000000000000000000001983ddb827ffa40ec0f97451108d6f2eb77ed41b379db4477a0562c3865e996b54579d70049febf82880e194fdd73fee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64f53696bfc1742be9c9a36bfda36d7e830c822221521b0927145c0c5813727eac4c4697aadb732c7d89ed3e1f5c080000000000000000000000000000000013f56691eab06db2ac30a39050189592501c16a6b846943e5a9890dbd466cb03e7e7b3bac312da602bdccf1605f12101000000000000000000000000000000000b8917fb95077ca894642cf29ae1ba5cde58c05f10c7a67e472b03816828b2133b9553feda4d81766b8857e609ff36c7000000000000000000000000000000000b4dd66857eb4fc0aca1c6dbccafe8adeb7b1c9a701528e92acb5055b51166beed04ae9855f74ac5ab3e419344773ca61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012feba07773004ab5abd5863aba51c9eaa6239a1ce917f0fc115afc8c28a2f321ab0caf4a6afa243c4e578ba2c84bf7d000000000000000000000000000000000f6ddfd920427a4cfcbfd24cffd0253b3235c84f97dddaeeb79feaf71adeed50ddd4b35463bacbf31c70da0c7dc82e5400000000000000000000000000000000012499f1dd5c2da4632230d37b1a870b6b12f705d867d46d92e6ab3bf7caf4c2da9541b119566be689564390edfc57d60000000000000000000000000000000017e789b489cd4fcfce278d7223c193f96b5df27ce79b7a02ed73c79e8c09e862d8a88f23221fe6234f38474c979a2ba61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011334414efc070d879c30dcd8496d5cb75e09f088c8ff9b4c4b71b96f0952315d8c840d694ffa8be023c5727f0f2ff0c00000000000000000000000000000000051171cf84c64652b00a15342c9435c31f6335b8d43e48481cd214a794f97c9f1cc8c53e00d2c64e3596eb7a1c8db37b0000000000000000000000000000000012e19c2d63b1b17a54e9f7d5daedabcf283a45a7cba86f778f0c1c16d84d42e75cb1a50dd091d33f3d2d02df2c9fc40b0000000000000000000000000000000005d5cbf9554efa3e6214f6353be67f3ab014cf7ac979ff7020932a454dcf9746f114581d6b8ae4055281091bad42125a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001948194d15391fc54b26e989d233bf5080dd91f60021c19c50d81f9a6b465c6bf9d3ebbf6804df8d0e271e20d5739d2e00000000000000000000000000000000044b65f359abdf07142773bb7029f6a779032d7833650efd95f913943e638fdf538b43735c6fac617f5eac5ba88f94a00000000000000000000000000000000008e097ac73988395c07099681f44f9a151dfa75575b86a7c083ad8110ad8bd4d9c24bad6c606d1186ce73c10d76ab7dc000000000000000000000000000000000c5df1bc05244707d6d2a86c515e7c5ea25422679a244fee8056fa513b0ead278d0a3e1addf3bdcd716ae3faa1b0533c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000007c1506da644f85a3e1825dd9b42548b0cd414af498782030ca34a3af02731c4eb25650179ab0f2b18af27b55cb0b370000000000000000000000000000000003e7d6a1dda11cb7f1cd33a71e0238e5a0e11e029bb5f23e21507d3437bbd6dca4e57925eef6760976fa610a3ba574be0000000000000000000000000000000018d72461bdf1f2a43fc932cd6bf1fed07b8670615e356cb75f4470dc6d3b30c58c76a4381ddc275b363d490728315c1500000000000000000000000000000000068fad8cdcb135842dd574542269fc1230c2a07602f3f934d06f24f39188dce6ab32cb7c4e2cb930a118bd6c3ff4e03c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007caa0ef37a25592f5603f7859a9844e79a178bffd60d997013a28fb692547363b2a2281b969d1e1cc18bf0ddca3e4a900000000000000000000000000000000165571effccc21210797627760c7a4fa7fa2b9586740ecc7129c7c2b20b0e0356ce5c29bd59002fc9146c82789674d640000000000000000000000000000000009a2811b3ea7ee8b1d2f742a28ef7757c65d91902d6d4ecfdd908c998be2dfacf03f067e867c5f5cc91342917f528dd6000000000000000000000000000000000c4f3e2f27fce562a06f93d30714d13ddf734648c2f5212c9e79e1f37b5df00cc1e748493e3e47d7282427f4b96fcc661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000319a43d7814ba5af3b66a901d4e39fbf5513c377ecefb4cdae6661f0dd3ed37932d5732c7a308368c1dd162dc4af7b700000000000000000000000000000000064e7386d535e9431e56b743f04b9852f8350afe12a1c11393d03d3f842141c395bd47119f96247f977924089460fb63000000000000000000000000000000000e204c2ede2084e29fbe8057bcd9145dac9537545a631eb9643923dec0ef1f6d477feb0af3ed0946d012f88464dbdb620000000000000000000000000000000014c2750d4267971409bfa62c1692f745f3a59e78667f95b1cdcf056ee119afb8808c1f11dc041227878305a79bd8cff81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a33ea2e5e38d2dccdb7d2fd25ec72a9c8e28679f5af1d30b51bb78048216653f13f4daed2469ce70213947cc71e5d2000000000000000000000000000000000dfcc2f18eccd32258aed1e3d2f13240cbb653e5bb8479ae730e99a96dd7b8c36a7caa052910fba8633b353259a179d80000000000000000000000000000000010cf7bca96576960f916386f27dbfcfc2734f41e87503a16740fecfdb1eb9c0dd86b7490173743d6c2916a4ed022d49c000000000000000000000000000000000dff35cd4eca984221817444ef8a88e478885c0fa981a179f2b42a7ed0c93929a76f83cb3a4ea5ab6eed279da50952971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d13abe80c13d81ec602863e52ca9e599d1f7d4bc952c26b7b9b8715bf1f6bac74432979eebdbdd2393d96b3dc9864e0000000000000000000000000000000006adff586cff085e99925a25aea0c437a2a991beb14b235df6e978a1104330ee152dbdae977b0b72a4e85f710db684f00000000000000000000000000000000007ee67ba0d2a0240e1ce44b8108f7a3e837878ac8d43d916a0a7a8ae0216243707f3f16f7ac05d319bc218a12bce80830000000000000000000000000000000004b25723569ccb3b25911ca1a07f341237f2a053e1325052e6527d35792e4840f2e9d02622a1ef8ecb0dac21df9b08391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001484a040ea2bae04139a34da6f809d74f80aee94af1ece6d06b29b91b2b8f21bc6e15cb5a953320651df2fc5e75380b40000000000000000000000000000000005242c250821bf498ea7a5247d38827286ce758d73c742af398a7ddaf59664944f329268c895dd52224fb0ec500722110000000000000000000000000000000010f6d5b952764d4b6cda0c36fd7d26546fa8df045efcc49db1d766d7d7c0cd76abeae3a169e1aab47e1aec289e1a8cb6000000000000000000000000000000000fe94bc1bf5d8a00e0917ae3886945ccd1df42a1f3f72a3faf02f0aa74cbe7e4b88004052592fe1fee6616c3d61a9b141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039207eb0c0ab8d79fde1e0b0b551c4781abee336d01ad1cc6601362f298d070816ebc370f8fe93b3fd822d4a50428ed000000000000000000000000000000000626ebb9b76ec89ad3efeadb96ef186bfd10f80ed0293c865e440974f8508f5625f329455f42c9494d0c8bc1622f7129000000000000000000000000000000001451e402e8d5487d08e2d3b0c2cb7098e751a4464a24780d1514f1166c33cc376d722f6a10131f561aaf6e2a0b1c03af0000000000000000000000000000000005e5c8ddac9de05efe4bcac5caeef10b2011927b33eefa0626c178fc2d05392e38ebbc5f587ba9bc91ecd846687c63411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000162ec183605c2511dde4bea1a9fbd6743162d26ff0d0de184e0f80d6e3c924d239114e55b9013caaf42bc139a0d05a640000000000000000000000000000000006c39bdd03c1c548c2d2f56281e679e7bd9407367d1367929b8c138ffbc63c3ec27505d01d5991b4b009ebd14efc3b3700000000000000000000000000000000133bbb87d98dc5027357ea143cea22f6136f1c2513e7d843283555378d6460402227f59e2a298a96408393bef880c2d60000000000000000000000000000000008a76540091bc9d3b0f3e717faa9c120806ad922b50ec43f09974f63340c3de068b1708be15cf2eefe95f6a845f83eba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010634708ca838cef03b96ffbd149f32460e9cc83566ce2585c524ba35af17954f78d7e4c38f066886a63df282a4a4708000000000000000000000000000000000b5bd6d673588012be3f1ba0101022924eeea3f0390edcc4ee2fe31e2acce9bc50b6f597ae97cb3c8571c156602f650c000000000000000000000000000000000afb476b6caa7ed864720ddde1f44209a4cf2a0d919464011cf0412e6ab34fb313f7840740ba43cf0a7492997610e53c000000000000000000000000000000000b3a7a785641cfcd2f1b0bae1026ad90ff68b88cce7105856f672c630435b0d924cffdb6c4177023c7123bab00e2d49a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131e849c2526dbfb0c026e63bcd7a4564897d12cf9df178aaddfb1cf7124f3c7e3dc505324d9c733b0cbc568e52abc440000000000000000000000000000000009dfed16626c4577aa2bf8b1f18c7a0f99b0baa67c1f3b605bc7101751dbd958ce2e70091173a0cc2ecad77911368ecb000000000000000000000000000000000db74538bd15c5cf5260bd1513ba24e93177f1b8fb7cca5bb38407f60028b114e686bb8a42af786ab2d38971c26cd71c0000000000000000000000000000000008cb7da1a1cfcae739b2e70da75ebe5ce88003b0e64e76a2bf14f014dfe58668111bad41bce8b04c6f936580e866de5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001910f1b7653d0f6c9f3321091688e0a1af42083a6aa8d857121e0eb15ceb013d5af2596a6d38ae51b2c370a388511f900000000000000000000000000000000007612d86773d41236bdddcb64adc9603c3d3fd7260b02b2bc799ebfaae739be263047f538dd9290704a88ac9173de20000000000000000000000000000000000196cee11ff27df206575e7f1dfc1e66bd34d4e56e12efd4c3336d10a4e8b42fdc5f9e6922c1bd17ec51ef746b1dea399000000000000000000000000000000000434fe2aff07c2cd6814f1200c2b4e3ba8d6a490bed42364e60ca5f148df5662095a816346810dd752fbfdc4a1dbfc681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a834e016100229c31418cd1656c294aa45f9361678eb739771c11b03a96b0a0fda7dfba97e819d32eec5f26d17e71c20000000000000000000000000000000014f717546a63bb591db133ed2a18a9c0c6c17a368064465fc6c15e05e2fceedf301f90401d1793d86d14e97309aa6cf200000000000000000000000000000000129224d30fb0c002970e954bb667769c9419b4b3d9e6cfce7432ec9bce93801b5881803bc76f36d123a453527e014a76000000000000000000000000000000000d5e845e63026b88f86bc1549c7ff33d0bd384be28e21a1be02ffe97b67b31af942995f15fd27a1d98ccd47d8344f2c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001593c45bf67558f518c90dda2a98ceef55813cfc5984522064df540118003ce50e25ed26cbeb13e3de795830d67cdd4100000000000000000000000000000000064fe133f4dbc162e320d7097079ac13bc3b524ab34b354ddebfa2d866e17f9cd7565f3d37e4db1fccec47345f1fdf0c000000000000000000000000000000000b37f17a24d92c63591625e4d664a6e182c25f58915ed1acd53f0d510728289b6f520ff6a83ae5af1adcfc4d2438889f000000000000000000000000000000001951fcb26d7c36ab06b43f8e95a514c73f09a91e798d9c22c99b22b48d4adaac7e052ac8ff662038fab0474a32de36501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0be046229986630f7aa765ece759c26fcd20e027db3da9320877c45c8ba62c9ade50dcd371f0474ae2417091b439b000000000000000000000000000000000033a48e75b898762d71ef38fa87891420befaf2defc79e634db65b694f6e104d6594ffe7a445d41d5e8b846e47804f39000000000000000000000000000000000631aa4436c3791fc0e76387c714efdc12c84eb8516581450731cc3e256ed9c92a41733d497e8a37a00f6603a3a36c35000000000000000000000000000000000c6557a4c602c1a847decd784f3214021536272fcf4593c1e27fb421f3f66e6e4b553330a25723d15ab09dc4c088ce5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8bc0e99e3162d95cc2698c6ee5deca568d160c6f0c407d71c7bfba91e284994b2a724ee10b58c206df751be0d9b5b8000000000000000000000000000000000a554a9495d1e0d2bfc3c43196cdecf63d03dbdb4a647c8dd4bffceebaa5eec05af3a572ca98a0dde92eff2361ed0adb00000000000000000000000000000000046aabecd5644a4bb82ba4e839e7bf92d2bfae8d9c60f07420e0b255a92b6fa0e62a284cd9cce83f343d5994d1d95ae30000000000000000000000000000000013bf2e9ba6033c6cfa448a4e3e35ba2d03fce76ff9c23a780b5e8aab54606caef9b12f3c5593611c591be380d093f2031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c039bc5dd2a0d25ca847b615a069d462f9abd3a7049493c8adde7cc8aab803066dac3ce56cd087c75acf334625895f0000000000000000000000000000000000c1a747f18a01eca9723f9b5ddef72e08371bfbdda517ef1343bae1504aa590b236b5b96446222b0eb5666ba1045d460000000000000000000000000000000000a22a6d4dc38ebb3a132913d4b26f4a0bf6d0d057c5a6db71f0dd05778a50f9e2e9ff17dd9ecd4b1afc69f3cef186e290000000000000000000000000000000003b6fd55fed34f7a8391a289abb360b022c46e4d2bbf4e01dab31a94b871124212a46b3ec663629ba107440a434521801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fa0ad44811ab60f326825657fb5505552af3975646bc2c6b582596a6a9e8a52b331cfc40d782da02ff80610b07631300000000000000000000000000000000106b7382007607f35444f46b3ce4cd66889257ae2c5abc72231380b6e53bb844ceb1756e71788b5b0712ed886c2e1c24000000000000000000000000000000001261c3effa1338ee06a44e6e1cbc3da526396a577196d101cd802443e7fdf11da6c9982e636ee6f44df6ba06f9602146000000000000000000000000000000000707788b1548bea0788a8f8ed7852902d49bdefca9d0402603221bd36827ed4713d99de87d8585574dbdc86f1e3398011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194f1163ad738aa88a47a87701fc3dc06aba35879139dcaf518230fe43524958ad1a0137e348b8b9c13d8ce11ee815bf000000000000000000000000000000000d4c6a6b092a4b6773c06ed0d78641b422750aea26912449f2e0383305d42115fed62b866b01ac35dc9859f201183cea00000000000000000000000000000000097604ba7a791f3e90b439f5d9990d853e4bce39fed54a3f18ebd0582b9fdfd3427bf3a9c8b6074622605f57c85b63160000000000000000000000000000000019171dd195539cbf7e56a577b27c38600a920dd7638479f485f9c2b437f386e6858222dc921490ba0645b5199222fc861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000142ed612879f07123c3affa95d39e9d18ab3dd77b837d70750b1f42c14842a157081179b3ac9daa91e045a9f6fd9f957000000000000000000000000000000000af6f8db1de051835ef33ceca7f978fea1470148ae46119c0b3d24e173b077d5498a5f6d4728651d4b760f73d7449c8a000000000000000000000000000000000eabf34306e207b1987472d9819ffeb38fd30e7a3cb5d99285eb8c8e98c4784806da6ba7456349c9190c7c4b652e6b44000000000000000000000000000000000a774137e2b7260175dca1db65edb85efb394d9df79f68ccc814c057d3a0011743d8f228b41d23cec4519f774f84a7a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011949582891f35b0f5c4c8ade127129470754461055d1d1004eebc535ae0ea779ca6121abf62da3c4328420db28cce9f00000000000000000000000000000000197749429a268b646c8b8799eefc77034edeeace7f9460fdc4ec9df3c2cbffdca8ba45950b8ee6fc6c7abe7bf941956f00000000000000000000000000000000167c2aa82ccb44057850f8b6bc7c9b87ef7683014cd775aec6d0a5b9a261085b1854b0d2809433a049b8eb87a6821ff40000000000000000000000000000000016f08b4c09b3cc4b2c2d7903e06adb29632119fb6e1308f6ddce145bffed791b3a1c888d0b4b95027281131f0060b0bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000771de8e8660d4f9e1c4600da0e3d0abc70ff3ab5da56fff062c05c4e745e54e678c3c855b3e907b9571fed7b1202e140000000000000000000000000000000002826fa00daa313a80a2682720260022bfef9e31f4550ef3344ebf4cc594a6baf2ee29e1eacbd52cdc3407e9e5f72fe20000000000000000000000000000000002eb50bf8ec8ad3439e7ca20445d7951651845760860c1f8d281708669c34d032eb088b434c37757e00f7a1e6ac4961f000000000000000000000000000000000b1811eed32675e657a850f1025370cb22b027f1caedb46ff5ab77cc8a5b62e2dd652b1a65d48691520ad32e8085cde01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191315f046c57742959f2282263f1564f1a0783913bd70f64d752662ea7a14206b13cc685b4d3cf0c6bad5c85674f2900000000000000000000000000000000004994d47674c6098709dc38f2c1a8eddeb5a9ff8f6db29854a0efcf2d26f36d7685b3fe031aba63353e640679e6be0d80000000000000000000000000000000006a1031a1bdab364ef70fbdfb51419d92916ee4ab0112e7c0990a940243ef7fa528494461d016f3f512a005bd33d4b8e000000000000000000000000000000000966b18f7ab411f9f2d4dad1fbf28f466c37f6ae2f3a47c7057b93faa5ecade56e9485f321405b52696f52faafaf66741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091c096c661c61b35216d02dbb1ccc4d639f7cef5f8f611f89ec85a82b4c5d053312b4c7049e3bab5d3a1f914410dfc30000000000000000000000000000000018483fdcc8bd85e12832dc4d1c39dfc5c404d5ff087cb55e89cace3986927c06d45f12376da0e5b2aa66a2b052e3fbac000000000000000000000000000000001597f7397f7fce61422c28a0874c77efaeadae214ab2c63894377de5f8ad56ec0fc22acfd1d8c356c4a614f189ce048200000000000000000000000000000000113921f6c2a0e55ee7bb6727e9d9c879295549b5d340fcf5b80ffaae04c9d9c4c15418cf9b78220906c023f1373d3af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e550be0cff8389005ac05b1d618968aa3c1f0164141649d89c88cf329a4fa645c4d931474f4e43329cddbae25d8747000000000000000000000000000000000e2966975469fe5feea6bdeafc8a66cefead784a49f7c2a5a30da0542d5e9d482d161a7d2d6814c63bf53074d4bcc0460000000000000000000000000000000009c2ec3f0f37968a2d77b4e1610c5e4055bcc7d6891d82abf1e7d2e7a3412af8bd5e644a7dca6efeeff6707fd3f5d8060000000000000000000000000000000017e6f1048e2195fb1ada1532f41116757ddd5f362a1f586047cde15c646a0c045255cfdea17130924ad1223ce0e719931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ab6e2fe9c3d0712e019e992d88b61edf4b6672d4c2fc64e2bb8f686b8708605a139d6f501d9bb5a7dacd28e36aeac900000000000000000000000000000000165246c7d90359dc3f602d5472285ab448b57e9c7ec21bc573879ea4683eba828c5a3d1d42b51a0db562cb526a97169300000000000000000000000000000000131d7adaf84c2af6320904ee49ff7ea6a95c49a655702135b6f4366fbf40c572eaad85a0300c5d23b70f7dd3bd194edf000000000000000000000000000000000f62956db7f0dc593387b399d1a5df2ccbfe94e5faac5ffd2d675fd39f736b260e8807f62a3cf4c98bd03f04656281c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc9cdde86d1778a13d90e1f93bddfb2dfead644bc1960f165e4e8d183638b4f95fcd81bb1ef927961a4a73f0c5627fa00000000000000000000000000000000192829219b8649d8e3c4f8682130eb60b7600eca8ffb07534ef55ac99481eaeb94454d4cdf0eaacfe4e1cd5a7e41458c00000000000000000000000000000000192fcdb07a469717219f34eb84d04400b93c1480986dd89451ee2d40b2eb7eb8944c9dd1b75b2492b3af66f7fe6bef5100000000000000000000000000000000065eca88f2b62fbace2ad31e2fb6eff4900aa8abed8d52d8321eecaed1d03dde09d6c59a019d7ac5ee0e2fef4813c4021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000225162fa81cc1ac5374a949d80c8e647765912cff7cd540042c8cacac963ad3b4357014bf90c9b6575374fede6e267a000000000000000000000000000000000df20bfc6ea454e53ace1c34868e01c0032d4b8434e93aa485e73169dfcca9fcec793b80a1efcca41d71a9c86704fa960000000000000000000000000000000019fdceded049ca0c1062f44ed6dac70976de325046c5472aca8145f00dcf41bd9c574292ad492473cd65c252c58987f2000000000000000000000000000000001470e6df5643e4c30eeadf0bbf2e5013523edb083caf916ff04c5602e78a4cc8fc94f2e2ce478246b85d2347d1e7aa4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001292973848c3142cb601062860cb93df46bf2994901258cc5053616624efddf6d8b56add48d07a213f8e664d62b97f020000000000000000000000000000000011d7336404919b753f7172a0742d495123e03e26c7b561a3282937f63d48111ff59b085f60d0c70a014d91482bf546ee0000000000000000000000000000000017df9d3f3ed74139bc2635222d6fe82650e3dcbae9be1b77d0de8d750675c47566823233bf6051c05ef0359c47a13bf600000000000000000000000000000000092ee128f1843bb015296ae245e321d5a26105f20e1f915fc97ab92f65e440f086f2ccc134a6b523e1666790f6c724fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f98bf2a27ab6a1a8705b26767bd75792643fad01b2b4ba57c604d14f1dda13e8a8849360f3ce25c00f7e19b276f2f6d00000000000000000000000000000000042ddf099c17007004d8429164b7972e86c0034130d37b73d4a2930438a1a570c82817c9890f0f03b742c27abb009eea0000000000000000000000000000000001fb470cb125def3930438cf47465429fa81ee23919bd25dd0a815e9c03bc869d603de16b69a8f788e6fe9682a8f9f71000000000000000000000000000000000246b4d5404367ebda04a0538668937f59cfc33eaa40252d51d90de826b392591ef52773fb020cbf9d8d80d346a9e0a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff5eeabcc968caba8758c5a16f7f99576d9b855eec26432a79b29fb9273842ee04890270c5d13632d9dfd0d01980b10000000000000000000000000000000008ff475df5cabdaf64e953da4ef5ee57f3d781ac235a8aa3f5635bb9538481cec6807b1def40f405400872f2d6bc2eca00000000000000000000000000000000043c5af3ea49a0346cccea47334a7f27db6a5452a21cca7f696bd19cf1458cf9bff0c6a28a21f9d202de761b715dce9d0000000000000000000000000000000001427e0fbc36df1b1e526c7e54d0453107640eb9b3ab95c05d007de80e245eff513b0f3fc65ebda885eb2e04f780f6551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073b3da9bfb751214df7b9c54479a027b62ad4c242ed74f46083a5afe748262a8584a8ecde7e754eee941bf4292181a300000000000000000000000000000000077dfbd5f9d053e578f21beee78927e35d23dbcd1ac61888c37d1a38b70b78055cdf5af382f031bb1f4ffedd43fc83aa000000000000000000000000000000000be94cb71d04b05436d9133883296c6b8786aee9aadc105704eeb39703e5b47eeb0f2310fd0a2fa951877178ae932408000000000000000000000000000000000b41486a755dd51239442ba8262317e26651577e227e12065943cc94a5abe9632dff58d9e35b5960cd24292a39bafe5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019752af76a6e4fed03c3a72d22237ffdf886637095366536436f679239f553703c7ee09ac4833560f931a0da512393be0000000000000000000000000000000016fd40c0ed3b939570ad108a1ea61410c515ebc640bbe2cf204a912210ee502ce933237c4d9ba200e8b10661f32c32f5000000000000000000000000000000000e8fc48dd82fc0b78285b18379d47f9d3a547be383da3eff27fe6ab5e00b843f00f72785836f90c7315d94cde90af6e9000000000000000000000000000000000dddcc29eb358a23540f57632cb784c846e84435f4afc8c300ce9f429d0fc6808fdcfb2c0ec8541692d737d1e9d4f0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc5d1dfc3573bef2ca271287ee24a2914aa5e39d2f8d8d0f382803eca6092bf58cfe66ca5fb1489402b6efaae851bb20000000000000000000000000000000006e653307f7470467421b1299bcaa72f5c272cf599cae6f50ad4581bec5f78361f86617eec683c491585b83840011f8800000000000000000000000000000000186803c8071f6f80ff1dc07b7e5524678be2c82fb8eaef6139f23a67b323cdc309627099cfcc5a0b382121b02ce253e500000000000000000000000000000000012ab3d61bce2b2b6db63f9c50eb7b40b2a3418803e4018a6711fc8c7cd30f5c2c75fccc884267ea3a16a76b49c35b0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a867e19c660666edfe20063f26a58fb2df919dedc80a2399333b52f3d6bbd88279917f851e5c119f9b25b6ba4497d0000000000000000000000000000000011caf4ced309a00ce8076a0220179a4babce3cebf396f8d7346271dd75eb7340ea0d9438463aec43a82c13279246afa700000000000000000000000000000000089dbb0e0787df6f2ea08d64cb5cdf9b83feecdc8704190a791eace58e65c0b4c736a6c7cdde5c2992b504a92d5e957400000000000000000000000000000000152c968c6dec3f13f22ffbd5145905a667bde90e6dcc07959bba3be9a1375faca94ca030c86af69767f3fce541b7d1e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010594f91e0c1640c3ebfa908b3296912f79da618504ff4a552ba377d7dc882d336906463b33442303d188f0ec3d09d3100000000000000000000000000000000147626ed992710b7471d03e9d73ffe17d7462b83d21058a88782fd13b1df83ba46534a047db6a5e161920c6168232bbd000000000000000000000000000000000ea2119c595b81c2cc2b1aaae0cf883b0ef7cd9452ed59369d8e61c20fd7d7c4faa6641bbad00d985cad2441976d7f66000000000000000000000000000000000c106eee2bb71a42b800d40eb28c9711aa227cdbbb7099869195320abafa564cd0d374aeb14f74c9926becd04073ab741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a042bc78a23407d5c42c84feb93663bd5ee833d61d9bf67602586c6e12abee2cc18202e7b13d11988d75bd09624c54600000000000000000000000000000000163e8a4eba3d3cdc2cb0a5575e21e7eeb4740219798d558c9965501e114828825850fb6cf4e8523f8dd90cd9a4266af20000000000000000000000000000000001a090a8383b76048a7f7cc4032d3ee5a13e2e06aeb51ebe96ec7148a0e6d362a64b22ef4935b76b4a72d14474b0a4340000000000000000000000000000000001a7d6a0f9245b39b8bc474cc6102b75f8e44e7870e8040e4cfcdb9244439f8ba478257d7b3cbb3dc47937168dce1d011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020558b0bde515d9f4688cd3d40f08e149866ef0d9ef72ab15c8be20f6e838135d510aeddf269a365a4c2cdd01b2f0110000000000000000000000000000000016901140ed918b7bb92934eec91233fded0053405849c7a752025d4324cda4c8380994bd96d0a71216a12f2b9cd91131000000000000000000000000000000000c4166f5636771c015bb5f960ae052f0bd30ed1947bd0883eaaf0601781041ce2623410f0e872564b486b38cc3189c3f0000000000000000000000000000000015aa95732fbab69a9a0a9eb70c68998aa3b582f0dc67664e25ada1d44c8eba3c073142c1121587407ecba648347eea151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fd6defc299d868e4c5ecafd2e80564ee369602c47fdb5fc162fa11132dab3afcded49af1ffa4cef460535845c90fac0000000000000000000000000000000013af4acbc698129722f58de7e93c5428347fb3d96dad7b308b516ffa02507d6f8450bfec5dd9289ffd9ce891a1986f150000000000000000000000000000000003cc553bbe0184b73133187de0fda87ebfdd7c02ccef169d4fe1576d7bad8e0842ba3217f3b02f79c1c416e4c92154ee0000000000000000000000000000000011abf9ba02b519ab6997c8cb86fe4fdda0622300eb64e1e50171d072f6cee8b8cdeb7f8c0f0de500d1cb44f194d3de981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a212bf2fb60a6f59cd94d916bfb0f77156bad56d4801854e261bc4836317e2afde6ac44855ab1020807997aa18440c60000000000000000000000000000000005093f26bfbc1edda0f4ff1a4f3dc5a7aff530a2785a307addabfc665087a9c3fe2721bb25d97ec5f8aedfa9efb06a910000000000000000000000000000000006ee42ce79e6f194fb96b2c47af26be1bf41ff732b1dc2e743029431b0554c201b41c1246c2e6fbd893d8b375bbea05e000000000000000000000000000000000e7b08abf0706690c0cd56165edb7a17ead5afab9c3ce39e65a0f6042802e18cbeaa45ce3a1ac928f0a361f35d8476c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000431a27b284abfc6cacd5dc404563fc6d524adc5344128e4fb9410db17e8ec91c86e3b1f282f56ccce20decf86f1e06b0000000000000000000000000000000000193469a53aae61229d7c18bdf4b760ac307165d73c1d01ce845dda5e0a3f08b70acafae0798789ff46b535e3043dd60000000000000000000000000000000012b288599902a4744ffb6fe1c7a8b2d2bf445edd7f040becc2d66b9bdb4550d1ed31b18d1c2da0793c0602a82e454d2a000000000000000000000000000000000e731209a792276d07067d84168983502f28dd1fd1cd19d7c9d6069bee0c4331e082ce457b98303932e5ac66f3fe56691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035f24edcab3b860eba731dcaa5eb6d7a5b0ead22a9316d860e1ba7a71107da3e457c52d714bf62e167b2bfee67f542700000000000000000000000000000000121525f4c709fc48f0769324c281a37f03167fd8651cd720a6db56ff20f7daa39ac3aedec2566a69f74a3241ef7315f6000000000000000000000000000000000e1ec42dab5ef9e34118b7e7bd2a3e47b333c2b43208294b22c209636570a0f99df5b094df0b2e2fef3ae1af0de157d100000000000000000000000000000000076f51d368e155dcecf85015e7cbf61dce92a1f1eb384ae11bad76903964dca6dcf4eff24fbbc4e962cccfb0e711a2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807ef356d6e5c36fc52549cb70b6d87d3daf62904e07dddb8cd7d50e55f3e3584392cee98aa6f5f9cb466588dc0f86a00000000000000000000000000000000193453a9df6ce4173b68c8bf2751e3457bedbbd3e6938f3cdd8f2c9f9cc10ecde889f546c37f158cd039e9b66bf5963800000000000000000000000000000000026d4dfbf419de80a9fe1f366b1e590a037a4fa36d30e482547dcf10df2d394b03c6b469ac140c256834310253d062810000000000000000000000000000000008a19496fb44febb18f51254ea41af88640f34f06a26617d6cf9802299684690350a3a40af9adf25e3985eae95f364db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016d5e9786a845c8db93d1dca1af58e34d24e488068564ecf1dd8bea3dde857da7ec61d904ed4a24503d5c4e664d016d000000000000000000000000000000000827a9737aa644c9c1fb2b24dd4c9c1f350e022cf39c60501688f20c6503bb009bf46b153e1cb15025e3393aed1491f8000000000000000000000000000000000c7d723c336ecac4fe15f3307bf430a76ca5d4c389d9ea2009e895319bd3ee4f1c7d74b2fe9d977a3477a58e2c3b263f00000000000000000000000000000000158d4cc467d9a7de2f501c37ad6a99df0c7c7c66f9a08de30de5bdef78aa8b6a7b13ecb31def2d58ff1e59cd53229c551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf63588c89bf35346eaf8dc9cfdeb1a88e499ff22b53bb8717363fd4ef90bed17bb7bb45c300c4f52fcdaae4c11b361000000000000000000000000000000000f74d5de8335492237a2f666fc505e7998da9b9932a3145869f2770322a8c5402dd47b6b09e557fecefb69820b9b709000000000000000000000000000000000115eff20f7c87afafef41598bdc5b38f1585aef556eea7becb87f8fee0960f27c2f527d89722c011bd12f47762d0f52e00000000000000000000000000000000003e7e41acc2aec7f5911a57fe5ea80041587273d11d1540fc7f49aa777afbf4dc90d44971deddbb139ebb2862744cbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2be89d0029915ca37194ee8f6687d109e1b6ea43fff92ef09c4e0fed23d271fb20b0f211565b2896043f5d04ba1da100000000000000000000000000000000184442d2e9dfbff934937ded2bf5e31ca81d7dbe14eaaf77f808ab6288ecaa85baff333cb38accc1fd8cf3b780b7527b000000000000000000000000000000000fa6df31dc666228a444c54ab05a3a4aaea059dfb116ad16fe2ee36ee1676dc5a9a5c3f578337e4ae4405720737837540000000000000000000000000000000009bbc1da045a4f63bdcdb8884d260073de2fd461946d900419579c079887ecccfb394542b4a35684a66bed06144bbdaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017360695c65cce74126ce0de693c99f96c5030889e737b36e5cbc83d25e23b861f7ba2d1804ffe8e3c46d7e4341d83e0000000000000000000000000000000002dbdc94348dba998b532f2e7f3c181ef59bd11c4d95212c81a2780f71db6f25d46c5ed5020e9f17bef240fb316d2f0e0000000000000000000000000000000008e97c3bccbfd87b2b6652d6c17c958de3343253eec415c83e11ae51b602d2480436ca5af4ea12ebf6c053cedc7ef53a000000000000000000000000000000000336934e0f4930b4e18cba0b381437e525da3cc86a83f85348126e4ea0398f00f523aff05e3b460206bb87a8936f06691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a51f80fca3d163b04444cc59789545bdd28ed3f940335ae35f72b697dce043f8cb3d321ca47ea89b0aa08f487efb260000000000000000000000000000000013125a60d6e35923df1dca921eae3e2bb7aaa507fbdc42fbb07956f77b262d921c27fc458a29ffb84cf97d344d0fc3fa00000000000000000000000000000000028c55767be963f97abdec60f903ba0d5cdbb61ce8d5a4fa888050aa37f6451cc548ce9f35acea443efb4eac919bf6c100000000000000000000000000000000006f949d5c3465ffd62181a3f824b230bc7b8e5a06aa70152b32031ae97ba211d007e16fe19953d0c3143fb16b9ac6321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f05e3b8bb4a91ab52d72e0aa085bb31723c1df4b61740d532e50e96e17a1a6fca49b47f290f9b44e693db998fcf66e40000000000000000000000000000000005c16c27754c4631e3ea8200f338df7fe8f53609b94bb1bea474df51b379ace9e37f558cafb4fbe09083744cb8dde10c000000000000000000000000000000001178e4d321ade6015f57daf59eef6608f89faba1ecbc1e1cdbfa2ca72df02ba3894d57243fc3b3f24d5b00e77adaaed20000000000000000000000000000000017e68bfc11b18df40ac2482387209545d4bb6d2dc75b12652516f01fc6e818c5c5fbdbf490172b9273c1fff7274fe43a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000cf7ea90f19b5c0688df62591816fbc43a9262e0eabae4c1bad98dca79772b65e967c594963267d2b3cddaea5578b6d00000000000000000000000000000000053142bac426b797be19429c9c1b75cfed8fdce3e6ffe0ef346fcd8b72bea5c7cc2cd7b0732d8263006a9b070b6141030000000000000000000000000000000017e51585634b3b8f4b9fca43ad903354eac44ec4c69fd7e38d583458f04fc50f66c36e39d6344a9190cfa860d74e8d1000000000000000000000000000000000180fa7820a301145f9c67b829b0312c9011e0df0eae7541f941159b50fd7745e2abcfa705e0de48132164c4d75f7ebaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018691d5f24ddc2c3e342992eb6f0cff29c42ab5985c7be372469995949dd010ab6c3819c77726189b4788bc9dd64f540000000000000000000000000000000002550a8e94233d6778f630962ff75aa68099b599e3a89dd620b3e572ec9fc334dc18235dec7ae67570de9167a814694500000000000000000000000000000000198fc1cb660126f81ac33a260c983b0cf6ca5c877b8c29d1ca1ef7d8c7eea976c21c6b06e0a2558ea12afa40ac1f787400000000000000000000000000000000067c38ca55a91c3d0c16f9ba792b9efa7d44553f79e35d9c0befab943b1c863e93ff3a7fe29c36a0b30c44c821f8a5da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c68af23703d87d31700cfc90f70df92100712167754288d0e047f7916ec12852b5e6b197000e96eb561d67844566490000000000000000000000000000000019fdbd3c18a77cb2521f9b958a39366a982c395c887e64957dd5a0964fc3b3c03f37ef724897fbb89a8a29b068dd485c00000000000000000000000000000000087291b9a2f977f53a3f7a9650a9cc97ead897acfc014056d36693999fa727880c10434b442a4aeddbf3497ad474a42b000000000000000000000000000000001785a50d655afb09982bb31e856f5940bbe1b817ce86dea441a0fecb4af9b8aadf27a999c23e34f296c063e2b82cbac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d81cc6285e18d3600d87880b8b619bfd4bf80d794590b01137051264625cd6be49020bcfda2a39aacc55459de8eb63000000000000000000000000000000000fdfa381fe465d6a832d2a9fd94f4c1d6e4f335b52ef2ce12f242e43ff8eede7a3137899a8fe5ba332d06a668326db920000000000000000000000000000000000ed8429e0e1588d94cbb616c3831096d2da8837229b7c1cbd562e10aa2061ffdff6258a7109a8b3a35c4d5f434616af00000000000000000000000000000000135324129d218f8fa88502ffa3445212260e4766658abce6ef976a731a960d0d4f415735f18657e6152a16bf5531c1301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012502a89815395f8b23cd9d9a075cc59874ff6b884fbbbed3487fe2be27c0c103983e7b13f93698bf4282d94c00da22f000000000000000000000000000000001988e82d8e941de540c474e69dc014bd5bc1b609f3bd8c38dc77cab9f4f95c9486d3375a7fb0dff270403ae0f61c05080000000000000000000000000000000010934e07c97578ebae43c01fd7a30be4d2169e78003287dcb3947f83285d2825634d37faa98cf81841984cfa4f4becb8000000000000000000000000000000000306c0210de723014fa448151f2aa96a85433cb7ba3ced712356b13b3256b8037b58184d4b19c3f22b0226eafdd979031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159ef4308b9c089b96f202e27f078c8a10d54e5f025eb7b5e7db5e1b3fc9f05b7ea804a854e2e814b5a20ee15ff520e40000000000000000000000000000000012e9a4af4c4eefa94b3b9c7fbea5911c055c93468df46da67aff464fe8451cf171c50c096724f8ca4b26e2d0a72adfaf0000000000000000000000000000000015f39f05f518eeaa76d12ff47026106cb84247c21494bea3d4377f96d22599d0a2e36ef32fa7d46bec6226b75b1b24100000000000000000000000000000000013b5b9f7bd3a5e6dfaacbc76a9052a200af114369348f3b52e6baee6f9b57b89c7e97240b467aa71a33f43da6ee528ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fb482a86b75849fd7c8e79546469748b42b667630fa40ca76f9768dcd72086c69f6130aeafd5aa7f474cd70e2f1dc600000000000000000000000000000000020641a3ae3355c13c35725f9084cd3e42a0c839fea4ade23760940f4223826f947da5f346f32178dc07425bb7e78748000000000000000000000000000000000c41edf2531e2ad31a76c74add2c9be2e8eb4beb12dd716a6377808d2ddedc193839a39152ae9202e737428b88db9069000000000000000000000000000000000b965e655a344a82b8cce3aa58c9de7a647ec3496231d217487cc91722fa7098cc3ef8b4b363b19487761f229f9041c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000107920ade33c19eb09a080300b189b6cafe69ca3ff83de9a954e7759898d76e221891e215b37d0c29b536a689b6a5afb0000000000000000000000000000000007a616a02a3a9688dfbbb0846b561a6997dcfddff303b3e1b8f0c2a2fc219ed8df4a390b8ccf42ad713ac056e0b45cab0000000000000000000000000000000009c37ba212c697085bc6190b8992a254d0258db7a2dfc762cd2fce1afa9bf272824272ecd0ff7f13e53beeffb95dc4d9000000000000000000000000000000001257c1434440891e6fccec82aa2f0e768205d5a09972391df032759b2fe1b55531b43497a0313b93c4a56ef5458cded71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e0410d8c0d8ed93d3c4dc7de5a145dd769688b1a7b46f16291d9cbda775129dda2fdcf24e55d06f71f3a6e63e5e6c9b0000000000000000000000000000000011cb62af720b1b01f400e8d58f6b9c5919f5e703dc8ac589be2bd07e2619b214a9be451d2af8a668dff0516b6915b3e0000000000000000000000000000000000218127e535f1cf99b651f24cc1e4f2676673872d6271f6cdbef9130243e89a6606cd1850b40e23cb5e85381d6e721410000000000000000000000000000000018323dc29b6a511c4f6314f40b8c1fa91e8ccc5d4f81fbcdb779b7e037dd720174494998936a5d78e8fbab73cc0feaea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ad82660767ec97aed57da0cc4f2b66c6d42bead4645ab36a29dc72c825aa9f2b3e234e4a2fd9d25a98cf1a1e63d6d4000000000000000000000000000000000e10bb82e15b3b3a6a1bfa521ca50af7c3f2ebbfd2068fed3764f3fde6f4bab50a87daaaf67426d5be4d2dc7cc7c5662000000000000000000000000000000000025c9bc9c10e9d39a328a7dd4cc6c3bcca2f6a850d7c6d51163041e95b6f2740cb9820267f27370b1f44dcbc6a1ee9a000000000000000000000000000000000ccdc248583c4bfea8d68aa455898b0727179fa389e14108df5bec476f287c355e2bd78e0d641c16578efbcdd2c29bff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c78c033b4bed84be35191bc56ac0b570e0339348625943b8867c0c2b45466eb315576119a58c6aac246e21d6f1974f0000000000000000000000000000000015329eb9703797782968359b382d490fe1278d4c2d28836a2e93c6aca67e770b095cfe61fa9f87c78e31862385f1f7ff0000000000000000000000000000000017c519d3aa05d7a59f3f36e2a096e4d5c175405a6e7db050d8cfb117e973b5e1f7a8b008a21f89decce295b30e5eba7f00000000000000000000000000000000015d2e44d46e0b3abb8636de0e57093f7fe238afd983f1c6587a16ad9a1686b71b1316c3a609d523a840db04d91301d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bdbd1cd3bc6cb80a20c7ccd2598d36568ba9ace898b03576f99f05f988f062ff2ae7c5a7824f415ab92a708679a126300000000000000000000000000000000027b72f8e9d039eb44c0d25828da054daa9acd9f6456e336c6e62afa035ce431bc5a6787934ce0ed0f04d7b06d811dfd00000000000000000000000000000000002f9d2573cfa2db40ca629863f744d112628f3618889eb9fa4f75399714d1b6221e6fddde39816cce997cbaf8155fb50000000000000000000000000000000008bb491bac92c0bedc61d62187df1c2f88cde3124c0e35b70c518c82d341931ebc8bd0f3069c6032b080f430aa546aca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187bf4089aea6fc1aeaa28980ec47bfe5d2fb277abc971585276d7df4ccd12a6b2bb713b48ce5c04a078a83ac915b605000000000000000000000000000000000c2f38943e918932faa0280f0c99f46377ce356c01199eef623f5acb4a3fb8daa7bb8f12db427294f85b2ba5c26893ab00000000000000000000000000000000118bd3bdd8cc20c2de66392872b11c82e26c42186ef3015c859f3a1525707d5498add4fb69c23056a55ac1575e3825330000000000000000000000000000000000ba480f726953f5d1e8dbd908c1eb9610d298a1406c88ac48e7c01575dde556919e8e7b158a7ec8c7ad8ce9fd7c10401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135b88b5d588f46fcc6bf8418004496c9b9fadd30d4b31eddf6329977772004d617bdef80892213745da66492b4a77c2000000000000000000000000000000000ba32ec4f32b8a86cc8dd6f42bff7357d3201bdd26f42f45c8c2285c34b58e4cc2c094090966dd72ed4bda7f622a07fd000000000000000000000000000000000e19a55b28e1e4dc78977b88a8e42cb88f7a0b6b0527164961bb2b8c80be4b687df514336d5ea6bb63bb838ee4a83f3f000000000000000000000000000000000d46ac62cdec0c6831e784a2844d1933b98fbbb32dc026fdede8f934973cf573eff7e962611476b0dcbc3964e39befc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067d8678440842e1ed3d4a61805e65e2374d58064344ce1f15e57d1c9b582b81d4c4c1532bb0ca981c2615398ab80b6a0000000000000000000000000000000008b6152f76ed27ef27a6296d1247a0a14dc9303eb4d235e0391a03d98625e1972ccb4a41614308f73d82283c5fa5c7510000000000000000000000000000000018e6f93db5aa60b0bc4e3d1ba43314fc0f7480d888282656f0eea31cf53ee887e41e4d056b4b32e3cbe35aeadf5226350000000000000000000000000000000018c5dd8e6b76ef860f6b68e308f1dc898fb024d36ed795bfe66731758fad9aa36399a85709fc0ba8e3795a85681550a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c698dd3b64edf7de51d4deea49759f447a97eced9941482b5293d6d3e793cd6bb221bc598e31bc4933e7d1ca96904e900000000000000000000000000000000059da03769444de1f4e7a7fd1e622b2cd00b9ea06c70145a63fbe310c338b2fe060c228cb427a3e222faf57f8d4a36b8000000000000000000000000000000000061e9295cc3979d5b17a73102e3604665f151045fae25046ed408cfe30e7a05cde740adb5f66a329c4d7ac24e1d937d000000000000000000000000000000000b567647ee214863e5a0d9ca9ffec691fd9774b3f8cc0d683602a6e2f81f49c67d4b24b9c8cf00fea346900efd3c8dac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cf27ab35238ec70f40c9a57b13f64253a6fd2911394d77fee8084892a4bb9f68d3d05e219ef888faf56f2e8054ed500000000000000000000000000000000013da55c6d3e85bc4cfe183ce9ae6ef3938b25e699ce62fe464f49a770bc1b66c1d1508a150631ea09d0fe843f5aad7af000000000000000000000000000000000bb64d76dc1beacd3bacbbf915e51aad1be1119caa3ce79b86d47055f5148aaa3a2570ad1a34635107af1d5bb3c1e3b90000000000000000000000000000000010a27e79db2c8dbd48567b153a835fddcd441e61fec4e4969b3778251c93e1c700a2adb8d30ce05e22018ee4555acc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f187fe6c1feb1cb91d55140d4f50c7ee9713180c3422c6cfa90c7a9943490998168dc1df5b43a10bc85c41481c3f99000000000000000000000000000000000c9c5e69db4011397da44b5533e6278322a3057a1f778c0cfc5b191ff854fb478df4982e3163e8b5c4cc905e1afdd647000000000000000000000000000000000337f13d6ab830850ca0d79b9bb93d3fb05d6a1ddd61f625d4510a8c44b60dba6139eb3c72404c58a5a8ab758f098a5500000000000000000000000000000000115e9c8f77e585d65a5aae1705df3d2c9a3bca1b719ee9bc7e7379e80d7a28a149a94ac4dd426e6b93d722ae6e74d5051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d33f79aa4dd9116aae5a1b2acef224e9a372893860f45d01fb23c3e81394e6c30bb254dd7cd6d5b682865a7fba92162000000000000000000000000000000001093f868172833ead9ef39c296b5a6049a3be93dad003201016e8fa750bb2c80f30bef185616c3f5f80dd78ec267adc4000000000000000000000000000000000be69e73f8b8af7c876d93488a4190bdf1901c02528ff289ee89967faa58cdedee464a22c905de6ef889a491a5680f0e0000000000000000000000000000000014ca3bf7884b857a43fde4825a2b0cbfc942b418a60edbac1d3a01bbb03e7b7b779252ddb408cb10b4a4fab9bec4278b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd5c024b48219670b9ed72759538924f701bc20099030690b74ad04ea020a41fb6c6f107c73987b5565ffaddd73bb7d0000000000000000000000000000000016551b21419dded301fb80819c85beaf463c9240ef9ebd08d10571cd5041c4393ac9c7894c3e4ae84d0bd7d7aacbf7e3000000000000000000000000000000000c5c703df9a581632e2b4addeb69f8103b1952ab741f5a9e4fb574c1d2a97606e453355e55420735663aac6fad22f3bf00000000000000000000000000000000066087eee4912553cd200d0f3f6f59cdbc658879ae794bb3c5d9a8ba74be1d216fe2ba6f75f6afa510977a608a04236a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077a72e5e85764ab92ce17db7f9ada64d95a4a4f6341fd6191b4f901dc489b4fe955de2fb2bb55da479ad9cb57cc48a400000000000000000000000000000000026505ec2b1ba0e2e497e9e6f1d8792d7cfca3948158b22e6e7664e8f9675851883490e166b5c22f7e132af5d311cb04000000000000000000000000000000001438bfb20e3489fe2e2dc40e5e24d846740bb7947349ae13c7b593875b8e8046cf9a6bcaa2e51941d6530eca211edce10000000000000000000000000000000000954a59b97486fae92211927183babefdea29542158b94ed5f44bea4b0a7fe221c627d1f8d1d3e8aa5623ebb39644761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a641d93e11ee8884de7cb432c61d1c810f7243f3854d36eab9368b579dc305d6360c1f16a71a79088e692f5d5993070000000000000000000000000000000000f54663ae6a97bfd2ea830ab6bbf2223fb11dc7baa55323aeecdec6e52ead211c9eca69d4d34687698556f0c7b7bcd70000000000000000000000000000000018312e5f79ce033f2b6219403ef4a01bf1287864df81cc575acba3571b1281dca7e2348917c5a9aa0be9cb2cc946c4e100000000000000000000000000000000143515bce7314ab8799e2f122ff6c2c495d9a5d570c7972da04b9d2ce19731836f8caead3a1981e4e6b2097d3e0678831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076d32e9cd6145afab1201cfc345eb6e4f55b52c5d8af871683821d0d2e87042117c28b0185059c5d1cf51fd39c43e8e000000000000000000000000000000000367cc21ae344c80f2b529ce27d18fc5c1797c2fc0d68b5c10ba90c6b6c435cb75e7007e33ce1cf416671f1b4126180c000000000000000000000000000000000871375e0cdb52f2eee0b8329f9ac0a44b85f9a8954e8e0420faad9c132a93f6c0801996a8c5ae24f4c3042e3adfeaba00000000000000000000000000000000016c60b2494afffcb1b423c9611230988aff7cca174f7de08d369a564e05ece4a508cf839408a4cbd580f7f20a1e8c5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000374e858c211b479b593dfc63f62adb33def8655f5e3c1b90cb41b62a4055dc9a20f1f534b295e7028273e2c5e9bdfe7000000000000000000000000000000000b371a79f241721c39031bd242ed3732ee07fb1d5ca2bbc754922c016fa63e6543ec0fa7474dfae1bba79fdf1bceea37000000000000000000000000000000000859f389be87eb0d345a5c1385840f9c09d073855fa1550d4fc1aefb6d0545c465ae19fbd8fa313ff0ea6ac30af903700000000000000000000000000000000018e90d560b734ad1e7c949bee7a3875be5cc108c23df9eff40b09259755174048b90209b05278ce17812548ce437c4721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1a42cd7dd56b30e6dcaeab4d521984833fab20059316391a3da58f2a95a71301bb171dda31b9914d36f4970fc90532000000000000000000000000000000000fa25bdf0705b3e3f7f52424f82c54938ebcfa6a6b20454c8ce6db013d05e586c07ff2effce4775553455f50c36437e30000000000000000000000000000000000384f4b5fe0f8dd1f73370298b4958ba0644dafd9694489782c37d3c98a660d03de1113143997b31e15a2667afb612500000000000000000000000000000000162bde8982b7e47561d2d3fd9fee1afef17bf4d46bc329f4346dcbb8dde1e8eec148381abfe39355a3753d6b8aa0c47c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee574dc3ea71cfe44572d913f5df8474bd45fad041da70d5fa8cad8467c6714567618c6f0c3984e081eb106586d2d31000000000000000000000000000000000a1942dea806be3f2d51c8243a8e5534d1358d42fee32cc463ddca9e93d718aa302e29c07d8bc0620ef0d73080cbb3a9000000000000000000000000000000000959b050e5f7215270e7aab888d79ecb704464bf04920234d09af579ba5d805b51ce344fe76c1772551cd116c6bd8b50000000000000000000000000000000000d074dcd6db84d9cb79de6303dd87c7c36cf5649ce7b7c4716f6558733f47be0d450fd8f18d76159c1a16d139abeeb281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000300df5b9d1540b5d3f814f58aa3965323916cab7529f011991b56a20bdec2275a6901112fdc81e39b33c61842448eec000000000000000000000000000000000fd9ecb90022390f196e3d93d3f032c1009c179a00c2a8fcc4e7687c3f975c6b122db61976330ed645e0bb8b276cee180000000000000000000000000000000015ff3f48ce1db7b0cf57a1a497b64104dd5f7bac4f0d48dc344799e6442715c11998d302eb10a89ce948de64956f19a0000000000000000000000000000000001244f202f01ee5f0655d538854e11ad78bbe6ad23cb2564cd87f210b40e1df8a00d69717fa522526236aecb4282fcc6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016bacfc3f203a97b0a19e2c2ec28c4785beb54ddd0b62b6b6cee09030caaf9422b29461b54d038d790a993ca1520819000000000000000000000000000000001888da8178569a652c12413060a9248ee34616e020dc99ff8e960939dcdedecad91643324cca50f10fa530cba697b16e000000000000000000000000000000000c2cf85bbdd6bc0d79502810860eb9b75ebefc81e9933190dce85cc30ddec103ab7da08d633f2a7dff259ce3085dd8bd0000000000000000000000000000000016165312885fd6e9e75abb567bbbfc51b3fdf03fcfbe56317f5a1b1bd27797ba165528cf4cbebee73ce42bb24971116d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000681c0ce8c01703b2615e003c08e3c3345ccd0cc540c79081d6190743fcfbc2a7ec57c996e7c8f3cc8b4ead0f52fcd1c0000000000000000000000000000000008bc643417bf77e835411bfd3491070994c1ecc818c4c91d375b2c3acf35c641cc35b98734f5f396ae842daf25730ef700000000000000000000000000000000184dc9bd6176f9f46f2f4e30963134672c68ef7bb9ab700fd3ca1e5e527eba87aa4cea14c5369478f87d631ba002923d000000000000000000000000000000000894c681c5f1cafc8747c50d0e7948299c9cdc86ae6a06dfa95485be11e8a88af9d17d11ced0faccd0f076a38895372d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f264fccf147b10cac6b2ed684b4f450a4e3434ff955952559f885c3ed936dc63e234f5a0466e5581a74042b520c8ec0000000000000000000000000000000003c7be8aa562a8444ed9111dfcb748088763b7c9b2beae9081a2a2de537123f2c54a4d78b762d35840d63583bc8e153a0000000000000000000000000000000010a6db4c53813ce311119760f35e4e99de88f03c49cea3ebe24c7ad82ac30cd9c31eacd7a89e600b8eb800ff4ec8ffe6000000000000000000000000000000001835815b866e55387b4ee11087fce9cb1818b8126d76b8ff4708d57deddfecd53745ea329c8022c04e698caf4a79ea421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004872105d33ef42dcda9c13373882d8cfbaeff7d152467d542c4289e4575dcde512d4fb4439f9308722bf9c9ef80ca0300000000000000000000000000000000035be1afbd8dab3ce5fbd5e193596990afdc9a2fcf229e3f5986b9e43934e7c7a189ed7745029463e11060561d0f554c0000000000000000000000000000000005bcb6629ff60cb2f2764a1246b7ac6678f66134170c681114d8977321c09a037452ce33c0a212d8bec73cb13aea272a0000000000000000000000000000000003a393349ae82b0c03b605cb7732d0c46122b6c91e84458a15faa17d988067e4618d4a27533cf23fbdd458a994d8710b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005af5ec6c2d823736e7be7d6826d67bdc603d13d2b03074d09760ddeae1a4c59e297aee84dbe2e1792665c193785c038000000000000000000000000000000001041a26288ddb6e13ac17cfc35fcb1bfeb934c48c802b5183b51b2604172bb5586a8cadbffd90f5704b2ba248a2dd0f000000000000000000000000000000000120bc86e2b282ac9f5d2b765ccdee0c7b732c7cac453785b7e2605682408c2fd3716f9a046e41de56bcb5ec9432e443d000000000000000000000000000000000b074d02f0e23793922f4e7af27c483311179484a6c4beb5ef3e359ad49708f60a3317a78ed00ceae623e91b0ee9b7a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf2cd1795caca3f7aa0fca4b54ad4b0d323707b2aa768776baedd18abeee239888b04dbb46a17b9d71aa2ca938f4d80000000000000000000000000000000001b099610cd80b5b0b354b86c92fc57925a88a79475eda2c4becbcc4c871d6f4e50f4d251f54cbea357ed9abfaf0c6ee0000000000000000000000000000000016bdf9d0b7a3c1cf98a92e24e9b40f4fba2312460beb2bc2f70d6f078953194bacabc8c55f04eb8127c56fea3a08609f00000000000000000000000000000000055ae8bac25485be86bc891661fbf4393894465bc5d422dfdb46bc56ec51db2ed83d96a4c8d5a3c1cd003aa59db70cdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad7b0ccb4ce07100ff7371d7bd1ad42d22a8db5f085f335ee7f05a9e23625df0ff058b65af39f9defebee5b1d82abf500000000000000000000000000000000106a963a06874faca6a5ff379f0ef6fb51eb6240329dc5536ec6a9b5eafeb45dfe238c379b69c84d23c62ac43afbd9d800000000000000000000000000000000069c42d8a62662682ec991dc6cfdbc1e9fdee55a4a9bfb90788927758aee3e6693ec49ac7f5aed93162b1487a639725d000000000000000000000000000000001801f5cba7bb4b0aba9168b8526fed7a97bf1dd3ecbc51167dd894835226bbf35bf039da3ffe77cb68eccab4c70dd0f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f290e373105740129ceb0040e0385f74875d9f2d87257ffdd8ff3925ed8768fbf31d361a9dc7acc4b2eb937b30b6d0000000000000000000000000000000000fdbf6af8b698a71ba5c9f79cfa2bfd4eeb901f76c42c0ad6d4bd2624439fd83ba28fa2e463c5f681bc9ac76687894b3000000000000000000000000000000000571b85a217753b2e6b90587cb2ef1a33e3446ec14eae7195d892cc2113aa7f0aaacc80b5a35da87ea027fe35ace5a83000000000000000000000000000000000ca3d90b67300e8a1f661dbfd8fe77265655a9bd6484a08ca75e9bb95d577db3f0d5bcfb080729e8423c3e7fbc4f9bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d18ea6c7b11be8e0af5aea5e9485e830c6011b82da82db1baf5f245bfcda85236d7b415d23312117853c85b16ff046000000000000000000000000000000001450a498d2f9f040ae4117e82df848f745870d42e9e05cdf8b9ca679c892ca8e8f8bd2ffcac959b1a216602149f50677000000000000000000000000000000000197839384739d425e2ec61536e04c70141ef315d68f9fe621775e60014a6eebf0c16226b13996c62016d313e7ed7513000000000000000000000000000000001727eb823dfa81ae9ace88d8f5c6fc6dbb4b079d7a2dffb500e7549239ea13bfadac590646180897527d2d09459329ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006604f456d2950879f3c2d2c8e0e91617d6fdaf7048c2f86d66c2fdc86c6623387070c6270757f5ed6ae2cc14c15ac5b000000000000000000000000000000000b715b310f7e2553feea1125144778fcddbe86f471bf868aa93ce7b2eb7e1e3fcf2d0aa7569b66d95dcadf9c98977d00000000000000000000000000000000000cdc16b6fb1a4d5d3ef696356da958139d219fc561bc2e5bbafb799696a7da9f2da55bf6aab22b856599f64bd74368c2000000000000000000000000000000000402dd55e9764dae5eb3dbc1943abe11de7b49e949dc96ac1409575c75ac1c4f1ace45db823771644d020b8b57cbf7451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055a7c1e2d6e222d0eaddad2977e0db74424ebdd93e30bc737821c00e45deb32d87452618bfa3bf43195eeeb6237686a0000000000000000000000000000000017e71cd105bcce40d3e141ce768fd38dd57e8bab7b22d33f55716f9f33eb002ea659440f894682f6441eb62b41512e6e000000000000000000000000000000000ca1a9c2ec02ddb3c79d8f5813188dbb77d76e32eb40df0a1e25136719decf1c9c996c1515eb1826c8ce24a052cc50710000000000000000000000000000000018f60aec758f64ca2ed60ce09ce62a9e52f2364bf394787127e0771183f549eba5d3ce2f7d1bb4b3840f6730e6f397cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7dab1d47b57d2a32cc682adaec1f832733faaa8ba0af94ff5aec9b4c64e4fb34fbb8206a53b4eda0c31cee7a8d64220000000000000000000000000000000004cfdcef8c0432f68f747ae3182440eee5d9cc512bcc56a1598d0da66b4acb9bb07178521043c2591c9459cc146fb44f000000000000000000000000000000000756397ae20adf42ed477d8e7914c7285e7e7099b5d97b7499b3fa9eae20e73877ca25903b17d56cbc82ce6b323110680000000000000000000000000000000015c148594133d7cacc6512d325fd91a5d4b88a39f6224aa639f81b6586f164bee9883273bd07aa41bab4f7f2d739dfa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8dabfd710d786f53e10aafcb67f03ef29b39f969dc8e6d8d7d48decc72d19f3222da6329124f8c6c40bb61637d01980000000000000000000000000000000004091fd0f1e7be058d0a41c7c6f67f5b7307715e6e8670961a2df9505426a34f47ee4e292154927ad11c9dc14e4cf7e20000000000000000000000000000000002f1f99a7c554fce8963573327e9124ee677a26c1a18dc68ac3e259edcc00db46ef1b8ba91aaa9c983036fa4500af3c0000000000000000000000000000000000e765368fefac0a6505f7d35c6fc71b06b39a8209b3b9e42bf929d6418cf576315cba3b3c42e26315928f39419609bf71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f69cf347464c649dcc1c20507884688b7074bfbb1bcd049cf6bf686bade6b08fd0f1fc68e3c1cf1276eff28c2e6049b0000000000000000000000000000000000bd637fa3ca62fe693130899d96b0d1301e1ed968670499921517830dce791f81e1254ff245ac154e5c9b5227172899000000000000000000000000000000000b4703d1e7d7c4a3d9b2eacd668b8cfb1211cb80caed764dc541767ead7c99cf86b2e335317fb450ed0399886098ae66000000000000000000000000000000000e7adbb14450d2ce1c871be9d275879270227e6991abb6861f10964a7cabab127d4194c9998779d5a39a7cdaf64e29881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000940c8336680f64976adda4a129e32edbe205bd2a5b22ce67cbb2e4a3957aac932baf58b7b154af0edd0dda6860dd3c5000000000000000000000000000000000870b5417683657707a81e28bdf3566ae425f96d040f59cc5ba7b329464ec799d0138048d7ea15ffeb6a38c2fffa83d6000000000000000000000000000000001282c29a647ff6c0da2b6cb4cadba81aadc519f2d40a2b284eb73a4d553ff85a0874f20e12a30988a574c3fadbc8c570000000000000000000000000000000000c1deab1774321229b54d236660d7acb156a1d6bdfa2eff01095db76e2203809244f11bda9a51e1c05b60bc8333bb9261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030e176ce74b18a030abd398c5c7f4afb23c70540e0c97fe37ecf425724cabaf51f4e933a9a0f9c71a755efa291ebce3000000000000000000000000000000000b1cd0dfea1ea74350e0bf37e4dd894361e60f7db9159abfcafa905908f0e194a9f3127141c20d7cd74b2b1e8f9c527c000000000000000000000000000000000a8918a45b1bd109ee715ad059a1700327100c622ade353ca093965d0f383a5c53c1ac52a1d9c2cf2fd3f8123ecd826a0000000000000000000000000000000012752ac0b3f9f08353356eaf524226b9595263789cac18d2c4abecf7004e6cdfbe0306e787cbdb7906df1b119eccb35b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116b81bef4211fbcf210eb74b9ad6a488a587565c80607989826ae30fc5900e9005534b650effdea7fb9e6ba287022f5000000000000000000000000000000000fba5f5c2a9460f5257389bc7e13d1c3aedb3bc060a0ab66f7771f40f5bd708c8c1d212ea7f641fb7edf6894ee5918a2000000000000000000000000000000000904cc70c98f52d08a4c5d375a83ce52a02e4d7f3e9bc17318a35fd80c73a6bba4939e1f88a1bc53a3057e6017d3d60e000000000000000000000000000000000bb534ccde98988422445227319124d8c879e3bfb69eba324ec465a6051a0c4e5d691ed16fbcb3e074936c6c9c5aa0b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bb258439adb464a31a5699ece630f6e82bb0fc8e8428bb65411f0017fe2f42cc2a9ef2b69919d16bde00c661bf1fb70000000000000000000000000000000009bdf623b962fc724b0f25445114f2ba305ceca10755c2e47761d8a15b382aec53e217abf0188f4f6fa025f884d27cda00000000000000000000000000000000143613a42d42318104df1e89968fb55b13869ef40677390e615d1d46b469fc03ad48ce444bbe261bfdea3dbce2eb60b600000000000000000000000000000000127ff9ec0492e240b8ef58de89ae240f5ed77d99efb896b3b68e7d7a86caf70dcdd66a44ac6ce3baae6c63aef564c5071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e10455177e8a37a3cb0704fda8ca376d4f15e56aefcd596b9b06f4085ff2c13816aed1b23746422b07a76414643eab0000000000000000000000000000000015324494db23007989cee1357989c1b38241d126366090df57f1b4ed4be38d687b38a9c4b449d29d31b33cf403ba81090000000000000000000000000000000018b804c8362cd9cd92d64aa19f0532eed011c5ef19fcecd6d2c8eade77dd24ba87901a0a3afb79ec19b1a34b59000d1a0000000000000000000000000000000003df787365366eac38bdab6f64756166eb7d26e06087d3d9c94b084038385d39dda4edf67c9b28be029e4cd9869ab34d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083ed6f5fa455608e172661824e7ebeffaa2fb95e051139d6a0d81cabcb3f1224ff7937fd1ad936173604d7b375588c100000000000000000000000000000000186ec401a2543fa8c2cd754451d4fb7f0d10116929ead484f6033343f75de2756e89c6dcd0efcb41f3832b2bd4678b1d000000000000000000000000000000000a6f2a54455681646ebf030a368e8641bbf9b5ed21dfb741b0beb96b2035f039922d80b214655135c689081e2b5f7599000000000000000000000000000000001762007452670844790e28272ea610d943d13ea60a19f0aa0b472e4fa3f9e996bb1fa4cb874e3b42464b1ce9a3944b1c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "00000000000000000000000000000000014d638dc4afe028be7e3089b7e6c10a456b999d1969e042f065dd1b71658937f5f1a428362139e2fbc65b153897217a000000000000000000000000000000001593404f32e08c40ea6d6f9181742dfb8b0bbe9a6dfc884c955428ba0cc6c252b336a7ebc75857b0eeea96920be44089000000000000000000000000000000001618e6f1c93bbcd2d0c58e615251a7efcfc066c6ccaa881dc81cead71e00e3f3e8b42e65122f93b1ead9df6ae342f5f70000000000000000000000000000000002d1ad7b474fd4df5f41ee64a45813dd76ca997dda8fff0deae486eef6670446d1578cae07a8aa92ad9427af7c126efe", + "Name": "g2msm-256-jwasinger", + "Gas": 2004480, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000052871b5ba2c2f23baa335931812cc7c400a707d7674b38fb8b03f6ddbe2ebc165bfedb907180b27dfc924a1441a42c0000000000000000000000000000000000a6ee537b0790f94905537f08cee4fd9d4655ef8cad394d41ef72dbb3cc1b8f54b09fc2cfdb6cd45fdbb59c255ff387d000000000000000000000000000000000a20ea7b3622100144b35031cc9a209c0bb77f2f6963445dfb5b576498a7728c8abfeff156d74d501d2475f62aab806d000000000000000000000000000000000cab63e41999719df09e92290dbdf7e0528760d446a9e4a57512578d33738449343ba1e8559801a9ae914bdaa71119731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c479f4cab473402b2754300b1a4abccd5ee23a4cf93c6f477055332abd6b711d4cf574e68ce471ff64467d00d1b020000000000000000000000000000000000f38e7258c28d592fb77645e7a86ce4d1be3492bee45d150dde2fad3fb726c89662d5cf265512fa7c834fe057b33f2060000000000000000000000000000000000bec3fa8a2281238f2477710775e79c6e81ed44efe5c5c9464653c6e05cc9c553ea105aee04c70043fff8bc99388e5200000000000000000000000000000000083b2b8855bc25c16e2480ef4b6c2832beefe8aa7f967bc560d25042e3f5ca6ec1ba8ce64104a20a8e53ce51fa54ebe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159bdd1f735123ee7bb77a99d185a3ea65c77a37902b0c893c0ae8d6f5a8d71661115951c2a86c65013c311db7813b0d000000000000000000000000000000000bcc7766060572c440b8c6954224d3053325e1b9b1bfa771116ad60781e900fd3d77492ac08de0641ce1c7648c341ca900000000000000000000000000000000125827384b72387f50ba2cfefbf7d2cbd0d569b98a9aa74deab5236a037c4ac1d64a22c9131bfa1cbec1e5910306d5a000000000000000000000000000000000134b17dae92e50bd24f1d035a071adab470232a5fed90a2bbc6b6b215589eac045716b1b4b353e4ecc9d843a7f37c9ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045504927bd2921120d367665d789d9ca3bda8055506898e85065c8a31c09a5915021991e1bc05a2074f5e058cf9374200000000000000000000000000000000182f5af7da6987529f3603d1236c39a474d7952ce373dc6eb7f169cfa2a3b27505312a72c9b67ec0aff603c258aad6ec0000000000000000000000000000000013c53650e142466ed115a4b09d58621a631f869de013da0dc46149fe917197faa6b715601df6684306e2354dcd4b4700000000000000000000000000000000000030eb07e18eebfe7573fe2ed5af27f30c26d745805a8b5a6c661d9b167c353f2724a8e927a1a62524f6a241c42f62941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000283385874d144e6b9cc94b6f68de7e7bf5726e6abd1eff86310f7603c2e8428553dd87d0e3547acb2808de059036ceb0000000000000000000000000000000019e81a5675d56ce2167cda8dc7b10770ad7c5320a0e0ede8bc686b6df971e628f3f24fb37b9b3219e1000e7a7af74a1e000000000000000000000000000000000153d7ea8b437a08b6d6f94e384dae16ef0658e34fd883fdb77cf095f8187551031648090e4ab81973a138be0ac393aa000000000000000000000000000000000ee3e64357327e32109804a5d9cd16b140d8edfbf08ec38a49ea4cecd1ab245904ea4ca79ee71be0d67183104d2389061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d48e73309c1bd5690f67b9450fb474d48d7fd564cae67d4f3aa865c8c43457a932963c6ed824a0983b7f5a94ea678280000000000000000000000000000000016b42b77ac21dae1c5a09e445243070fac959cc30d625cbf72fd1251b6da33d907e642a411f57fc8840a6bca0a9641490000000000000000000000000000000006eaea88444b7430a168951e5261df18bf7aee2729b54dd5b1580ce27a4690aa459ffa676512678198a38717ef64db1c0000000000000000000000000000000019bd1938539eaa4fd6f4914793cab607982a75a3edb672cba99e45515c0e629136f29a378d960130c483abb81ff3c76d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000261308d64484701aa59a28e286f26bbb62057e06cd5ad4090c7f7238e00b292f9cd52520c989b768ddc31d2a5fee63400000000000000000000000000000000160cdca8787289470723963383690b20aa2c9263bfdc474b809c008667fc32c9c9a7ba2fba30fc7fe3d0bb9400959f40000000000000000000000000000000000e52f34db06ee6a19351fe14ce1cd2e74d45ccbcbe82b3d19c60065c8f80ef20d9ff64c38e52c52bb4816136598103aa0000000000000000000000000000000018f07a5f44255955860991622112051b21c49ae38a679903e96207c681fc813d36e587adcc2fe9c6e3b1a10c190c9e521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017018b2f86ecff208be4b1ce895a379edb2904df68c92c5d66485728b4c81c5bf7c551c73a0cd38f708ce5638fe8d633000000000000000000000000000000000f7d7abc65d5b6293aad06ecf49e69dc5ae19726044cde1ce9a386e982aece1a0190a8a94b7b53203f92d94eb50cd142000000000000000000000000000000000c0a38ef3bbacdbdbd251ebe8c8aa24a3cdfe820dd9ba951895609e35becd703f96f2405a5f666f3007c50ba2a3390a10000000000000000000000000000000015086203a9d471344ce7393273a2dda2df786172b786f8b76b5e4cd77b0431cea5258e4c1da1fd5165372b2226b803f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cf8c388634f5932e3fb3b83c4e2f211fa00108559fcdbeb847e04dff68993828cdabedd2e489c6139dd5f6e053474400000000000000000000000000000000056aa9ddcb13f9c58f448d11d0112b661ba189be679a10cf68554e263ccbf79dce4aca8ecf542a6636702326a1d3d3f50000000000000000000000000000000016a4f0dd3e42ced74aa6f26e57cf09ee8e8f948260d92a21f8d4112efac83acd9052f5ecb19fb1a8914d61dfacd917d7000000000000000000000000000000001682bd8df2af2f2a2cf570a91c57bd8200116404bfba98f43c8fd0dca19c238309e4380da49bf8649ff53a43f295f5471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a482318198aa984d6e89c5840c3ca0e5f7d35f7e53c0001e1edc8fe9482d73f170ba79dee147793e228ced0258efb30000000000000000000000000000000015a4ec001143961b29423af3ed71abe72249f3bb7f3950b21d61cb0594366c8deadc0f9ebc57f32a197fa85ecebbae9200000000000000000000000000000000133e9511866cc253be65603789882c4abff1bea8ac2ef9ea4000625dc40fe11fb0259abf2ad448f5bb6209a793ba7e89000000000000000000000000000000000c583b48aff376e01aba68e58baddbd834bdda13a68b29f55dfcc0e321fa4e136ce222869434dde95b6f8e890dfaa7711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a1a078166adec647e3ab6204b28008365e2bfb8d308921b22eab86810db0005169c1bc80674649b3c82c71371f262f0000000000000000000000000000000008a04282d81ef3b5e438a0d9d0965efa92dda03abe9e8e2cfd76e7f1e6ec598c26aff96c12e271feb61c41f1fbe832a30000000000000000000000000000000015232b871b58a6748a8980e3dd6a21b35ef9387157643415cd5870dd0509a9e5d56d83eb86174407269cd6da69e922e0000000000000000000000000000000000a1f8ae179b5073d4395fabc0e64f1e03735c24f0a8bffb37966c949982e6495bf4816e5ceaac89ff7b09494b51dd9c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a28efb0d782f6a55341be11f305633c4f7467859b7bdef48046cbddbe1b927dc96ba88b9fef900b1e4102efdd35c1e7000000000000000000000000000000000775d5e9a86c7f620555672318085d3af9c2d00449904a4bd45c56a3c831f6389f30e84b212ec56b4a191a6335949b3e000000000000000000000000000000000d949485f8be75e90d5e4ce4d1689f052d0b59f3acafb6dbaf6584a7fb65eb85cb37751dee0a2158991c78572b0ac285000000000000000000000000000000000d4558031672332824cd59bed291dab6411edf7d108e085b69ef93228012344513f968c9bf47dfb3de6fcb8aaf55aea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ebc1d47370b8689c475b703bf10fd48035618dfeeb6e707af3b7e010a646bebf10fbd8d46e432ded47be7373aab14e000000000000000000000000000000000864c45727beb709e81786f848a80042434e90c3fa54f3e882df740e3d3bd21743c2d30e694765bacc283a7d372c3c4b0000000000000000000000000000000017c81df6f19e945a94e180f11308792d615c6a4931c23cbeea8b0079ae63e18c77219bc8fdcc7e0a14127b1bf9daa994000000000000000000000000000000000faed0ccee4cba59ff6180824c45c010c19e5e1239f48a69976c8e80dec91f3b17493561a5c89c8273164635a593ce321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000067b59c35dcd09d697b7b9d7427f6dc2a45ef79371e4ef8bd6bf1f660fe13e293e9349d14a3c6ce83d78011f0c3c7690000000000000000000000000000000005ce370ed332cb3aee56d32d7012fcf0f1f68c6f73447a55be9caeb26145b4712bcc1c1f8dda6692021018cbecebacc6000000000000000000000000000000000e5035fd1d8798553c5ab23b61e3c66bd4662f7d7b50aef44094994163d0a6696679b7c58fb14ec412697b9c29915c2c0000000000000000000000000000000007924dff85364965c207b191dab946951142fac7a9f7bdb4ac2958f7ff0956ab9f03f32d8f8fe0860aa29401156315bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bf142c242098d99f6f04dc5701e1f61b005bff70d33d4e7a569f0e3ca86655f219a1e557022abf5782b54e552d1552000000000000000000000000000000000b97b596875e5166c9a5b53a990281095fbe95e130635330f2d7750feb01a0694b49b66ecfb798c3a4c87b976e5f3b85000000000000000000000000000000000bd0181ab31f8b707ac8bc9421a9db3e7b7897b5eb494e3974fd146d41fd552dc5ddf0ec9952653072fb778f4b853deb00000000000000000000000000000000152537502998b7ea9d7707fb9d96d5c41e5e801049fec075383b59945c032b52581b186f3bfd5cc869b06e9cf1ca062c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b71d2fcdbcb0614d34c009fd3f0b87fe92b2c30ad05bdd85ac322742cf9ec3ea61c7eb6eba6fdc97ac7a045e21b4ba60000000000000000000000000000000004de114840cbaab5bbc630a8666fcebb3fd751965348538eaea15db32095c4a96c04b7064d3747a60f41af5071db38ec00000000000000000000000000000000107baec1e9df7ed94d49fca487edb18148df356654c7ac5fbfb66fe6944792fb5c5a6b919c2471cf56bf4f97634980ca00000000000000000000000000000000052606d51306ef085659da365be47d9a1ba3e02fc26295a87fe5fdac15727d9d7cd924decd0bd1673d725acc0797ffb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5fc61472ea7cb8de64be1ff5b3e52d7c20a31705b1d2b56d8bdaaf2466da4f3cecb6f7b8686a14a5d516b93aa031960000000000000000000000000000000018aa652edce2f8fff59b5786cf209cf93b1d2fdda78c1a109e87b3797a3cc1ce393a637e90dc0217afef449381c6bf12000000000000000000000000000000000bb4a1d4a6452df0ee24f8f2dd017be15582b6f81882837d94925c5f6fbca4a73a97d3b02d329107139c78fe74909ec800000000000000000000000000000000154b3442cde404083d5cec21292006beb14905aa841f042e1bae2ab33be9c341c7b950632226ed5f2f86a932837ab85a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000194532d2b9054c0ff2968f75e7f8ce94fd368628f28f8ca8e0d80cc252030aebdf931e03a82f1871db50531adb32074d00000000000000000000000000000000096858709792a32e47fce14b1910548eca780a96cf92d36585cde7646a26a23ee898824c63b994a5e3586c3d727e7dac0000000000000000000000000000000015e1871332b60af53706058454ac4d2452c4e075d6759c15bd9584c7491ab06df2d45c2552f99173c35dfa173629e2a500000000000000000000000000000000086fc2e317b0c1441256bfdbdf633b08b05d95ad99dcd3a25a9eed51d4f251d5b6eeec0185238b8b872ad3c822ef68301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dce295e9fbb91b1f0888f9bf97028f7bb1a47a47803817be27635145ad6cf1df3b44c64db6661617fa1c91eaeb0549f000000000000000000000000000000000f42365014da8f144407e0e5cbb04703a88441d101fb0e32a23967ee95db5cdda0aa32f03247e44399b2828e874b574a0000000000000000000000000000000005e96546c1086cb355ed9af196ca7cd62b5dbade7039b39e6ceb5bc22522ecba9888707e4a63ff08a24aa13bc5c035eb000000000000000000000000000000000153316d66eab7a14b1d08379e3f614a3b4463b78b44cc20e217c90784b2e3ea2d2b0d4fd023ecce34e3a905d66349361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001271d33938dd1759c6452d947099ac1f91c9da921e48cd76bae17da25ef418899741ec47f6d19832d84c3a579fd2dd4a00000000000000000000000000000000188fd6819263b6f500ac8b92f1cdfe92c2c781290b8b22660010e5a7a3160bc1c69c8bf31884bbb413cb8afc44ec0e5f0000000000000000000000000000000007194effbc9a6c3eac8b7b91b88d3bf8bce25f005b927a6ed4b959c472ca57bf7d88f4a8374add5483ca62c7aba5ed720000000000000000000000000000000008dbbe0ed3b96f0ac9c6b5f376f28d514f8e9895740c28e2de00065a4bd147343faf8756fa00d05ffd9a5e50731833751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9a1238c8909331dabb8a83aa122a818be5ad93461fb08715006002cd04a2499272bbedad21fd6e4cacfcbebca1886000000000000000000000000000000001080ad0e12616f197775f0e8fabd3828e130d283b77f4342b265c459ae35209d15dc09101ea18959624aafa0a6c3c862000000000000000000000000000000000d1ddeda081a119dcef81a4d8740c72ec7bfc9662e0bbf21d27ad68a0fb1eff768b97ad3b482f9115d565b5bb33476df0000000000000000000000000000000006c0ae82584e1f4e530bcc400444a73c3e2f4abad8f282614e769524698ca798d8b4fd104cdf23bc9a8c2b6f7847aa071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bd232992af9c9116d6f1c91f05e672366728f8876ef15948d0ee413a198ba0d9e993713298d025618b322f89873c370000000000000000000000000000000004d51f2d438fde7f261d2335bcab5d2d66eeb19e9c4e7ae3e296a59e656131ba71478e7907c9a641d6f05e653a4a8713000000000000000000000000000000000b16c3ac2b14b6915de4baa4665ad1969c025a788ec4914c15081e737276df1fe6079771075a627cbe18f6241cec87b400000000000000000000000000000000102048acff5366c3316ba0f7101f11e455756da3fa8e6d5294e542986fb67be759cd4c410b1d1bc9c9be778e4819c1c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e067fa40b492a2441284394453b01597714a2f8e269d73e75bf577061a7e383ec69f188e34913645cf791bed526005c00000000000000000000000000000000118b77ef250fbe1d54b2c0124cd5da0196f83322e8cc5eea37ee657aedb44f7055b49177c695dc24d956b99abce8e3d300000000000000000000000000000000194b536d940236b8d0b62fd501badacbcc6a030c0e69936d391ead9d42c7fc198453ea944213ed1493387e8f857e6c42000000000000000000000000000000001864c1133b4c09f719d608afdfd5ed5fa3fe9eba835395b41a1c76831db45c753877e3ed22062dda0c5951410459f1731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f8ddb1edca337f12d275a08f2f82328a3d0884c95222df797a74e3116ad2a58008bf0bcafb951345e91588a89e9f9c0000000000000000000000000000000011e320aed1fe1432aaa829bdf9e35fad456530793ab68502c5f7944a586a3b8deb3559e730f60165ae4ede62fb2f6e14000000000000000000000000000000000b47c612b1bee3152fcf5280b81ba34d570295ba67108b984fe50d54227f2cfdeba8ef9198e57b174121016c5b71d1f30000000000000000000000000000000019e49448544c55c99c736e60339715a6096e0283ecc5e300ca11e81a8f584067984c4f904de56e1f047c7c0fd90c36be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019f6185820fc36dd07c975cf05fb2352257f14723c7e74abd00d1396c56b3206bdde2efab326f06ea36d9c50496719f0000000000000000000000000000000003f25d42845cb51fa000facc1b8d41ac60bf2bec4ab963c0dddbcf3219bbca76a0ad3d3abd2d8686693b4251973a72b100000000000000000000000000000000110b34eedc5669f8d4c07a1c6cb61f5a91d25be39306cb99400156e936664a58fa40a22b1f30d702040c1acd14302358000000000000000000000000000000000bcc657119c54de95011e55d1a3de24605001c938be87af72faa65494f5e77afba27df183496c1c1b9bd8db58537705b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bc3e3c92528405273313f9789d652beb260126740d2c4641de89fa33cb0863927bc9ddae75d346c1397c7b1ef41904000000000000000000000000000000000c302090d420f500b66c4b5515bfbc90a11d2ad637b115e51fce2807b04869078aef954c520a109a395d6ec42504d66a0000000000000000000000000000000002d7158497762a5a0fc790d9c04acea583675ede5c7e532bcdabac6676c1439e5755b9c194a3a09924e81cfa04ccf3c1000000000000000000000000000000001491bc1c3732f503f2aa0931f91a61ef67d0e1e83d9451fb0f44e41535b8254ccdf7480e565c52cafdd5ba509966f2a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021ae11a089d19ffc0822ee89e0d4ee6ec4742a5bae62fae0b350ea698515e83f82f460d6f57e741d4e4091725b360250000000000000000000000000000000013c879ee5192084a89b7785e1f9c7f5fec30fcd850940a54202556f9c11cc7075e719e6a0abc22955af7a91de439087900000000000000000000000000000000098e4ba133e12906a347af023f60a1735cf0c3b696c9cf0fb587f1afe7d8ed3ec98a7d29511caa4bb988257e9c76b35b00000000000000000000000000000000135e7650ba3f08a32476a8554c9f9fef33928a54e25f765ad77bec1a3899114232cd796bfbb1b6c234e6ce78109d698c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116daf89b2b04f02f5a5d208ce339a2b9ba2f71c94b5c92a39a316821835bff50df867ae9cb274318b6f08185e81adf9000000000000000000000000000000001179182cc96a5a333f24480d6172d9940a2ea115420b12bdf71319f45a91e2caaecee5de7094f853810c46778ff88f7b000000000000000000000000000000000425136a2218ed28393b87847458037dd5df34b3be356ffb615b67a9293a17a0ee3cdd76682e833b4525432e0c995e32000000000000000000000000000000001101122b7fa5b38b1eba5f10660c4d24bb8d074cdd8351cbf2d1ecaae31464034c2802e3e35a47035a684d5fbc8bb29e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c46307b5dcb53fb17070bfb5e7a4098142d5e43927db5685e2a68d123e46491fd831d6187d1d0d5e762322ff0afe510000000000000000000000000000000019edc903165b7ef0683a2f1ec4354fc0a2e943bc99baa1b2e1e39f65dede5d22475cd109c04ca2bd278b19adf97c59ce000000000000000000000000000000000fd15280bc9d74e3fda0637f2e145982bbb12bbb8c9141f9cd1a878656dd02d93d467d7014a5c164e40e10bea721c9eb0000000000000000000000000000000012f174e7815db551a91c954879e9d03e0fe9bd818e3e29433968dd00eb498854b7c8dcf20fadfb920981f39d988b7d861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001513b9e950811ac4b3c9aff93fbc2e3435c22244057803f08f0084ea0231953c15ca504f8e359c9efaff8d7a2131eb170000000000000000000000000000000013541c11b878dbb6e45a43b4697032567e55434d7129b5e580b74751c26b4df6726d5a14526177fa0477ceb9e3122246000000000000000000000000000000001051fb83caa28fba8cc3ca1a68a04e03a9399793c59c04dc274057b56515eda2446005e6a70cf447b6b0b8b526dfdf0100000000000000000000000000000000182512afa385310852aadcc5d206ed53e721698b2016ee51edd664d7a64b3e4ff6264821f801183222a72770a095ea1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080016371bcc6718563fd706babd77d630733379f75d58c71ca416f095a16be1246856056a89a5437c841221d14b9dc10000000000000000000000000000000008ef7e000727c7fbbdd2500c76d8b7af5d55c01cdb6d374a632834638d84c47702350aab9190b72e6457db48770e100d0000000000000000000000000000000008d656e9214f56abb1f80ad880e4bef024c1e8623f10333d6bd4e401ade2e8f31aa1135f9431f0e11475d08a0f147af900000000000000000000000000000000004ff1c2c69b27174767ee98e5ae81933aad68c2ff13b0ab9030883243fbd313f9de69de67a89fe8f91a34ed30385f6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016806597ba79852c4eaced0e10463111aa3be5cddb413171688d023ad07b4c4e30708387e1af8a5409aae423a12087c000000000000000000000000000000000143ceee08cdad076340d2f9ab8a9a229dd2d8db2b6b4ac9663902c87f6b9ba3fc8e52bd4087b7df92ccf61d5d59da0c80000000000000000000000000000000002a8e9d5e20404bb416b9d3c3f37545f7374f7136114799e942767448ee3b4b2e35c8e18359a6c01d11ac382803894ca0000000000000000000000000000000003f4373155d2dc66faf10522d437e73fc3983ee916d9d06c5063846f8133ad5c04323f3fb2ab26ce88b1ae15e5c53ecb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019aabf1fa38ba197b0295f00472fb7bcf4247c800d37adab9c174e69b3c5fda5e37300a56a49ab9a8f84967c51530bb8000000000000000000000000000000001497693bd1c85926f6ac7c9d598cfa9b8c1612a6fbea72ee928722d7834c886e6c05fa14c2301e03d0614efbf0eccf380000000000000000000000000000000002aa49ea07cbc663c6910ddc49a5c15d7432194b67ce1958f91cf362146763b7eb00e2712fa91d4a42013136c004ad7f0000000000000000000000000000000006a971fd1e4ae54d487c52de6d2636c05d02c6591694eea7ecf569e3a37bed0c003f3d85cde5bdcc4451e14002d0bb521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d22cc2d0772fd39d9797680e2ab3de4e9b9ca25079d16480b03ed41cea666ba8c23ec701c9cd8abb297a1dfaddef1100000000000000000000000000000000157acb8b4c371f16835f6f61841087d2c9ba58993d2a8ee13ea84edbcea4c9f0d670e2502c4e08b54751ebd846a52d090000000000000000000000000000000008fe6680d7e2e7e211a0fea79ec62cc290ede1d8a7011e19339784db155cb0601e596b45e0050ad81a136713b4b84ee00000000000000000000000000000000017bc88a3dd41d13d6d92e05a6d0753bdde8c4421cc6d87a20a9a00fe8356d8b47be94d2df11330ff4231cf600234070c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f4f02d3243c54be9e02998a690521c4d6a8566e438755a38e0559ecaf988056a7ce6a9e52b029b2e1d81a122637cc00000000000000000000000000000000013c22a66db668e64626b8e864df8071ee5766692b390f533a6268a9ab8f4815488738919ae75d0b73e893460147374c300000000000000000000000000000000169e805461e065314a2d3fba31a305c8bc0291fea3ff05427faf05447af9d1c2725cadcd9f3fbbc9142561c62392ccfb000000000000000000000000000000000ebe3a54234cf4bca0384d73e9b30551ca0e1a35e41572ef7175bd765610573ac5745a2f01805f21473eeb665e143e181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f637826b6dd5383fd29cd95fb1eb54fd798a41c82e99ea41d87736d580fa00557184c1a8382259eecd4997ae62f8700000000000000000000000000000000016f9e2a84a0600e9b059762cecd4d2abd7e0c2b5cae782f6c7a194fab6ae8d4fa121ec2c84f7a66fc7fd0165cae1d841000000000000000000000000000000001412fa940b347f60aa7df350ea8a97c0c652ec2ebf6c459b8f370ca170aa0247a04b2e3b8ce2e9ee96c14ae6ce3ff605000000000000000000000000000000000e18fcf75dad2ddf3bd29db5b16f106a4f0ec46a478615acd6e26d8c5a62ad1700203a785f4a996a473575c5be88d8d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075aac8cda9ebcff86cc717da83e4e2a000680e9978188bd56b468b0a9048bc0787b42c457b2459d18828744f4bef4df0000000000000000000000000000000014dbfed78ee4b8c85ffc44e8096a130738cdcc241cce36a1c10b5942208a7a08fabe890201acc0610f1e267c4aaf4364000000000000000000000000000000000f704c3f081b8ac59df7b78e31350132dbbb2c3017234d489cdddcc370a463bba1533b799d4730cb2d7ebd06400e3e6f0000000000000000000000000000000005de7f7f83267349944f0e87da4c27cc0328484e24355a14f84b4e1de2a48fbbe7bf40d93084401a75d10b477bcb919f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011475989ea243e90d4b896d502862947aa04743f3f910eac8b8b0941951130c55325db8b9f443503f9209070c0bbfea0000000000000000000000000000000000f029768a2f1c1163c493fa77d8568e302e41954db9080b773133ce6b0e8ff0b8cd38a7f88a972656638f854e4012ce20000000000000000000000000000000001c1f0ca237e3103c16d7d0f893079f5c66ccad94484ed53233e7c892c3a0b1674e2e405b8dc5630206456e0ab8cf4bb00000000000000000000000000000000155f724688c35f61e598023efdc8f410ba223a2cbd3150c14fe1429a672df50ab66c54b4033063b3ab39721522d791b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003308b9fd5b8ed798470cb183ae6d40e10fb020b3381bf747d9ef62c2dad08aee9169f410faea7fd4018f3cc09164540000000000000000000000000000000000f7c4f05e489d249ac723eaec7e75ec85152f9df38e963de89b574a6cd49600a8362f4c100af745a4c4d884d9e64443300000000000000000000000000000000149604491248f289c581ecea262f000cb60d893474dbc9c778a77426797762786eccbbdede16474881924a2ccdfc132b0000000000000000000000000000000018ba607f1613fb968e38190808e5604cbfd4146dd208d5a6e15daaf15f37801e36f0a96e924787f0bea8ad6ef7269f701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004d74420a393cba3c540376d78849be97c3520b52f0971a42a571e8ba0872c04a66785ac1e353190265360a442e20920000000000000000000000000000000012add2c21a97d832ffff82fb252593ad6c850594a5c3baa2c4c195fb2421535afd278f69f3b78896babd254fe5656d400000000000000000000000000000000002679f842475c6465e9bc2bc527bded4019f8be092879bd3b6d52f25599b0a166972947f0e5cd5048371128c3d18f76400000000000000000000000000000000166b11888ca58880c7d9104ead2f0c87dfd6973226056d796f9229e6c0353064019aa0c7f1cb289aa12f942131c6d99d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b2f4a146da613da4a32b837db76ba1db12defb10b4fc9a55a3da3e758e2d0c2712f393ef8930bfdc723dff4a0d508c000000000000000000000000000000000ec3b21f1cc682926a2e7826168045f68a605fd7b88b572eb75f5a712dbb367829f2b0d6f294ea9d42c9f610f803966c000000000000000000000000000000000f81d1df9305c0dfd891dfd158f0b95f6e841aa54f4c20dee110214ce7f07918e540391d76633abb574e49aa573c99e60000000000000000000000000000000019101c3d01e7d498e407976ae80e04f87ed7679ee7142161c5f35bb18e0f670d4f40489f1b78a7f66d98afea0ebeaf971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1215dcdc1e3e0410f6acca62f31e60c528bbf66e42c4e995886f8d49f174ec66c4e64ca0bf3e272524e43fe184999000000000000000000000000000000000b6b0b2d0ece956fc3ddf0db430e39b20b8b5c6dca60923f1cd816817ed3b360e74bcf1115372317763299ba1566988f000000000000000000000000000000000b8af9b73a44674153096210edaed8d4aef5f8b7d30d183b9a9fcef63b1c327936e63aa09b0e8820fc1ba7d262baa77e00000000000000000000000000000000154fc4cba0f1b53da2927cb01accb60f2b45d8981f293f21c3953b424db8e4c8f4017690e544421a151e1f17267e86491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9c1cf901fae4ee0ad856cc340f74f420c92d71ad76c1fc52108a2611fb4ef223a5f7a9be2b61b22e3063845c7bb65000000000000000000000000000000001907c3b981cf8a782e2904e4ff1a8f9875ca37a1350769dbfe1a692a35d24b93b13c04d8a1ac272eacfe0d4e446e8cc700000000000000000000000000000000080cd85d1e5cdb02fdbb8cc099102779c37e93d8432ec0c2637cfd1e8135b074b01ff63dcecd694334d7d182c65fc777000000000000000000000000000000000787b19c39cb5ee1dcd8f9cbc4535a689377168f3604284c2854bdaeb3ea7ecb5c17a264d78655fc479bdc25beb62b2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bf9885d825e010509147e72af4c784398c43c8493667ce6811d68d284b6cc2052dd9435b0b7644d8b7505ccde4cde50000000000000000000000000000000017d708e3e1509ab7dc64d1aaf485b17f8b851764dab33098bf986eae3c4c352b72758e4c75fae75c04c794ca68124ab20000000000000000000000000000000003081d02c97fed3af86ae14ec2feef7729714dd29387cb783745d3df6b36d3b60580707c2216ab8b0f890ab0f70495a00000000000000000000000000000000007b2ba4a3dad0dc77e7a9f8b6da7fae907e677f40529828af0711cebcfaff075b9db7433badeed00c5eb6a4650a9c2721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc32fa0801df7f97aefc9a0d43979f5126825220e990c972c48744df7efa8125a4410c6cd6dc44dcace7dc1ad120d890000000000000000000000000000000013300235bbb90bf30531361080d54381e5e8ea68cd530333a487fc96d81764f944c6b3bb6f6e02cdfdaa746564a5b04b0000000000000000000000000000000006c8ed0dfe282ed175208edd2c45cf2118718dd8564b2dd8ca77aa47e225234d302656e2ba50e8594cc92075416545f50000000000000000000000000000000017f74fc1bccbbf3d813cd90f91d750c27027a3f6fe09459d4422cef0e8b25b3fd99a644786861448a25a987971afbdb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195e461e3c7a58204dee46add8a41aef184e4e117e927f115a89aa9223110648229406220bc98f6674b13d86431eb72c000000000000000000000000000000000631721e19fcc66f7fa82e73359ab9231550bcc20a6958b9567e6943de5d744387eafbc8d298c0bf6c1fa3a43b0b1dd60000000000000000000000000000000013004653d9e98ccdbb88b8f56c32575d4cf227707f8dd595d6636d5fb92069ead4f1350cf0f4d51564aa7cf4d4117d6500000000000000000000000000000000153f8e7d62c09fea778aa23ad3485ec99ee604fefc5980dab2e2cf18e42992c56642544cd75136e56b089ca3357e1afc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003423fc99785ad4f2eff7360f6b3229bfa9c6deb3581fcbeef82e6b8aa109986e1891b1078c574dfd9ccc9632fa3268b0000000000000000000000000000000012495f9411896638c70261604df91b5f6f3689b9877d809897f84a3c9f1cd60be2409e37645d529ceb4a041fd5a4dbde000000000000000000000000000000000856a4fb80601f8ce0abb3679104e16d19ee6eeb15003050ace496d54260f298698d402b1a513e687f15822ff929d62c000000000000000000000000000000000c03948fd94be7f0954c9e4fdd1e8e133fdd114b625e06f115b1d8b42f17452609899cae392ad5f8c868c12096cdcf7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001113b93ab9a7d6aa75e26cf836807dc4d761b8114f2d3dc0a4f3e343bc1d5e420a4dbecf8b7267da857b52985b4f7aac0000000000000000000000000000000011afe31c565162a0e89e3e13567953e6468c0d62d3a30c584899b81c883ad0a0a9897668292a005a7135a21628fa07b0000000000000000000000000000000000a996e1b5a5cb52c23f682a38855972d312499e65e35aa3efb7a62c8edbadd869572ed273247423f53dcbdcb3e20c5fa000000000000000000000000000000000d88b734e6816916e0a48ccff25cb31503c0af7e2a28c8935867fb53f4f6a3aa135552c22ad254be869a80c3ee6362eb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9fc3be3fba07f15295d5e48d4345d2e6000771f69aa082a231ec25ec602320a64f6491b19f973a8bdd030b4ab4c5040000000000000000000000000000000002fcf026bdafdae38274ec666889be0a0cb4c9fcc9acb477f3d7408e61a901145cfa1d27472fafb18bd78f9f2e20005c000000000000000000000000000000001570ca33d7e4118ab9b6481a8a9fd78bb567dbc1666ccb4afab5b4ddae50daa134b00cc71be7f6cf11bfcf3defcdf1ce0000000000000000000000000000000011fc0588bd80b7e54d18247c439be386f61ed6c9f5d63863e0f334c5fb97cd0e8f1f77dfe7bb3eafa36bb928ed1ae0ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033cdfb5d0d03470fb5844ad125de8ef4f0f626d9739078de01f74cb785c024a0a55fc54f70d362cf401616dfc7c23ad0000000000000000000000000000000004e66c04fe2e3357c222f0f8f09ea24e9957a29154bfb2fab2a5866d090f82a933ecf1538ab8b2f9b32d8bb191331c360000000000000000000000000000000005abefd27e32b06c2f502f29b9da74211589b58a3cb38cbd7781faeb22ef48ffab0307a54efae1335fda12509a50daac0000000000000000000000000000000010bbd7901850676d43d444bf19396e9dc015518ac71891382685be941a5c6008c39298f84c81d679fcac5eee75a712391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b1a08be282a7d227b9194b8ad60aac51aab78241033c5e70623690aecd71441a6d5e841dcf709b399aaddded0abae6000000000000000000000000000000000911196b60cb518f555fe60c80e8d21426f32b195cd0d5d933ee7a8be8f11460accb69a06f749fc56de495335bf6216200000000000000000000000000000000087eab91b23a6a3207db7e933856ce88842fe47fe63b52ef7cee10056d056b9a187af012cd0b5ffbd39002627d40203c000000000000000000000000000000000c1067c54e9004d7e9e82d3182813bf6a41e0417f584417530844ffdfa924f4a280d009b056d24879b8a0ca561c182701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085028cf5d9983702910f40ef0a354d5b984c82cfbe814e48e39e726dd18a6269ae4a6f2a96617d8340d094fabce85770000000000000000000000000000000005a5fc500e302151c35e0a000dcd5a402dfaa601d74bb37a095aea95d1e09596b317cd406a40364b7a2db95c2ad4554700000000000000000000000000000000017a12f89c6d86ee41352eb7bcaf82caac5d1051727dedd6fdc801d2f4c83ccbf2e9ce5a4f408c96690bcec496ea5ece00000000000000000000000000000000189c93c80612fdca38cf00174c3c322de96b53577b75461fa3882375f29bb1e7bac53747bd96b120e0ba167dc0b102691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191e972dd4db4b25ce7ea746e90258db2308f7bcb2b267beebf1115dd1ea284982f1ae95f6c17af2b4ac556260cde7ba00000000000000000000000000000000021468418a523c2109c93de442d99608206503267c2e9f3b36d1f1913c892af48db5048c764adb2a342398e1e1cce7ea000000000000000000000000000000000391fb11d58ca5c2a706364db484a462a5506277465117a33cae8cc76716cb4be9604fb2e61b9350fd4773145be9695200000000000000000000000000000000047061e9503407173569feb9486faf945e6fb1a9cfadc4b630d3c6629c89816e589c7655b589ae9cf4bd0c61a0ba92f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158855085dda5a4d28fb6d2e94f3afc6b6383f85cc5c5aad70a70370a60a0b8eef477c77175947f3dfdcffab0373d8850000000000000000000000000000000016f62b6a1a67579bc67fa228f1af2a2b1fc7bb2be63a90967b3671f06ed7fe6eb53a41567d887c363e28c03b6aa52d390000000000000000000000000000000016387a95a3757beeea17f6ad94d23531a30d79dc0a30b945308b0740bfc09f238f8d19349143d18570bbdaac3fe691f50000000000000000000000000000000004fd9ce59f494631a1590758b4001de8259cbc123c6254be7e6feb9f199f86e33acb983472776e9691008f63f26bd1b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b9a8019ab6159ec14003771cde97a15ea91b0c86ae7f42804ba920d657a8c2260c53b91c59534f55a9c07885cf9d2a000000000000000000000000000000000fe2dd75e32eb7a130c0cb484f2f158dbdffbbdad245af089a65971ada34fab0a9a8aa924d1622655e2e7747372e080d0000000000000000000000000000000018d6fbf330ecb5de268ed7e4775e7977f13f229eb21200370d08cd0678186716856c562d48ce6ed51f1661c93cbfab1a0000000000000000000000000000000006ced36d057992df92e3cd78876f2719eeee1bbd27bb7dfd8229556be82280ade8d1e0155cbfe8144638bb892ad608531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000032a50bcf20bd4220e02a110bf29e059cf35f22ad5583b3e80f92f58162c7fbcb5eac97e7411611b66d90a7766668b750000000000000000000000000000000013fd121e2a6206b3a533305643a9a3c204a2f51a4368cd226fc8cda760770723bf153436a9b261bb9cb908655d6cf4de0000000000000000000000000000000019afd0c671403eb0bba36a4b12099e981af5dd18df80e54f6294e5d052f4a838c94eb11eb80b4ba96897ce1845e90d070000000000000000000000000000000008ec5b712553a7a254c93ae869ea8897ec6aa6fdec32c5e119bc6a0dc8e273fb3a9b35cb8c45eeaf15eb14e00454e3be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbc0639df7ae17b3684ef5e1799d28cec6398294cf2c99abd6d8e207d8f164c3b0e9639de51dc0e60b85efd824943400000000000000000000000000000000086f459ba06e2e90620e3950653dd448f270c3d499af4d9e0bea18512a0c8f7924de5f1adeb9199decdb5e050791933c0000000000000000000000000000000000a8321e522ae78fc865e12de855d43cfd1bd93e492d5ca4b3c7eb72efde855bdfee249ec8e9694b9124c05362f7aa1a00000000000000000000000000000000179ccc5e9a2dfe6598d6887054c8a08f5900a33804cee26468aafde44d8b5ee538bbd7cfb38aa019927950174036ca3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133ee532d074b053049ee14ba6ab530ed28ed4ffb540ece4f7d1fbebf7a447d986035e1beb7cbe00d8614ad1e0498ced000000000000000000000000000000000630ea8c472e38564eb180c82842ca1605b3129dd9a8cd4b67c1a438fd9aeb74e40bb03f083bdc8adeb84094a21108c5000000000000000000000000000000000c281f5a33236606cfa25f222fe9c37336bf9afd06dac8bc7095e66d15d9f5c9277876ecd0c22413442402fc23937186000000000000000000000000000000000e3cf86b0c56029987736111796ecb12f827c3617bfb505802d17dd9c333816c61362b1709817db4d4892702409272541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc34a62f7380ae1f6078c2be739059397107b0d8e7cf84a065bfa37af13acb5aef2ac854c55c5dd8735ec8617a829500000000000000000000000000000000006fc70e8649364dcb50d505417cbaa81f1e851a2fac8124edb9ba8583ae930bc89829c730cd70f6bb5e54ccb1a7ba9410000000000000000000000000000000009c38bd474646318944b3d6a67ab1b8f4ff28b69297f5bb29f0f366840eb2b39f907617ba43d32204b4a1e8c1d4327e800000000000000000000000000000000000761b0d7b3b6feda82f6391e26f311e85c0f889dd779b8ef39a6a81e24ce7168d3efb0abbd5cb0cf7dd695ea3312c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039e8f44793dd2d51def595508c06016e85602bf124a2c4840bda18c07c1100cb6a4d54532612c8ea28cce9b7e943dce00000000000000000000000000000000003e58d3c4cb61b94c2a4ef89267aa7d8d1b04b2c931f835b04af955229511f9ee18d489353ce25f8803f9ac2dca35fb0000000000000000000000000000000002a019517fb42629d881cc7da5da0795d184701ea2e7b1da1edaf381a3c09be10309824bc6639afbb55145fa3edd0a68000000000000000000000000000000000e5d715d19764daffaacfd70bb91846eda01eba04ca880ff11797a02922db9493ab3957421668599292ea1bf5a7042b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e71755cad448836c83ba58684c5f439d919ffb76b198ad7f998933983505ce3cdc89251bf1ddffa5f24416524d8a310000000000000000000000000000000012453c0e387f3bb0b6e8e5030d1cb2d57323cfb44ccf4158ae9ac03f30846fae20c656b42e6f7f1914dc5ff53a29c69d00000000000000000000000000000000132c2fc27d55025e748964c3e736effae151ac258d6d8b4b48ff149b5926793c9792a16412d3f01b75d297061bce3f530000000000000000000000000000000001db47f50d5a44e2c1c316936b1dee0beef75ced351a0514038b1dcc442cd72e381a40f4702dccccb89457a02dc675a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000055ed694419eb1602959de5215c3314c12b768b8335d4d28c657ce96a27df566653a8a86279f3f75c70969f831082361000000000000000000000000000000000e3cdb690db4bd2b726b80451fc1c6dda7be4b6d441652a46995b3c408123c047b9f69be72e17ecb54d31ab5676ec6030000000000000000000000000000000002c1e18947162d1dee8efea07464819bf22de853951c896bfedc0894bdfa7e5cf432bbe14b8f52c5fc60c15132c851140000000000000000000000000000000016e171cd3db118a187d554ae05d5a18c7c89ef22ed5406b7e6c4d943e2b3ce8998e378b22986b4246c5ec5dc9c3ff3d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e8aa91e2635f006bf780f41e25b6d63f8d142f9028abe0823c892d20816e2a2f1f6030404e7685058ba1e048b5f0d700000000000000000000000000000000085092039a355adaf8961a8c69cbc97d0ebabcc315c96a66106e7b1ee34a7635308e507206e1d1ab858838047082c1e100000000000000000000000000000000147a71ecb74be2f395d8892fd32391887cc003aac7c5b8c1c5d1b338beda8bb8c4e8d3e996597956804b1dfef173342c000000000000000000000000000000000623e15a03d69a04c425a559fa7ece093ecd63fdfc85eca5ca2bfef3cfba72965e7c9d51a8b9e062c0ecf74c613ae0551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b9138af4a2e03dcf085fd96df5188f57deccd8a3b3e460b12d88848ff1d6a25517ffcb3e3b1d02fb6b2d20face9eb2000000000000000000000000000000000a83a2a2ec639e847d64a9ee3544623d7ac4cc69bba6796fa78799f43a787d697bc97add5a4dbef03547d99734cc26440000000000000000000000000000000010db66edb6b34eb0b0420fa2e2f3091737dff9f05d8055a0e13d0fe521b59c424dc5c49298e6b7b4bc6b76bdfdf8d5a1000000000000000000000000000000000cb065b2143a358b98b015bea98fce319162869a30dc3b52ebc83707fae8bcbd8a7b50d29f755c8b4281637bee0268991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca8bd0008c098fab2824b81ff4c1453583f30f94b0aa7ae778079b05a686eee0b96dd9b29caec6a68efbf0d94bec9c50000000000000000000000000000000017115a31b406c8fbd918b50c41148303fa9698d164a81f4bdd5ee7be6ca0c795dfc81738da07a64a9b0c03a2d7b3056e0000000000000000000000000000000002f255bf76896b857941230ec3aa40b90cadb4f25f540e2a2bec5fb8113f4507c9adc5b7c334b3b69ace9421bff911c60000000000000000000000000000000003663d1df92e8d9ef07daaaf50bda0066780a606fdcf0dd347331904eb0161c9ef97e9a1cabf120a8ef4bf03de9659541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a89e28ff57cc16f5f94b5923120ee4f9c9ef20f92a3ba2e0aa2113b09e93d9d962a9b0b5ea95ef394babdc84a94fd000000000000000000000000000000000144feb467d549c3dcf5d5e3081725d005e00d7d53619353a3c12878d8ef34bc4b47b5e5b93b8151b7f8a0063a15fbdd60000000000000000000000000000000008478f5471e1e36f3743079c76fa50fa768e2b35c83a38e04ca3c9c932d86cb4411f75932dd670342b852f725a58ce0b000000000000000000000000000000000e1f390d4433ba006f487feba0fa4ddeade5496e9fe6c9c151948ff175e5a1f130baa7ecd8c9b47c50360aedb8dfdc8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0611f844e12e218ab92539401b39084e38ad3ca13ee410fc5bd6540059095c81163e5b3291c7816a725b34a86ec1cd00000000000000000000000000000000096ec435bee236c2480e2285d4a2cf8de15933acce4650203bc4bbe7c5c6e76e5463074ad6a1f4f9804d39b8910c31dd00000000000000000000000000000000066dd6f01444ec294f64267216a43d065cb6f3495b4a2b2b0e5472838052a0b37f5c5d25f48ca0f54b216e71e9920d640000000000000000000000000000000013a95a519f0663b81354760f9f5abe46c87372140b050e5778ad99509c578147ce0a585935639ba6d5626397c6b723f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036712f2039ce7561a5e8182a113ea9b8dfb43012dc3872055ab39be4a7e44c1b1c3d59e1b00a69eb74dda7ec27dffa8000000000000000000000000000000000152a753ddccd4111b38197b16772b681eb6fb76fc741ca6b126fb4d5c7b69d03c2bc66aa797dcfc75565d3a2cea6c50000000000000000000000000000000000b72b538c64701858f4c9f19f6b52597487bd8f482209ac39c06536b2e7c6f50b847090a87e6a6c6911df330f3b0a720000000000000000000000000000000000e2d4b97d4d16d74e69f018fe5bfc0a5a1e770a323d4f1b8f46b2f3315d1a8e24961613d260a41f4938e7b31682539251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085075f9c660a17c9d200416492dc33a11f1260b1856f65a4f8ab0595e94e0651b29f3b894b06f0b54378827537166f2000000000000000000000000000000000638fed6c1fd4c764ecf3faaf3d2f05d2c57bfc9264133c3cd857a1e769c362408c564b158bce946e8f3de793258599b000000000000000000000000000000001635375c2c79c55ae715893eb621b95fc2dab065e4d7df8a22fedcd686588093008dcd004206fee7281dcf903e1cf93e0000000000000000000000000000000015e70440bd6249933ed2842590db0149ba71ec1b9852361c931bca8c7d7304ad0ffc9afb557fbd254e26be16300abd7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175570400c76d9e368cc656f48223052bc4544383f0c523cd2f30a1f415250f5279813dabf0b77f060a217b17148283100000000000000000000000000000000170692f20c0ae0c3396dd21073f77aa504b0b493cd3027643640aef1244eca09b3a0fef2f8e36a50fca918b2620afd4d00000000000000000000000000000000000605e2106b7d8369e6cd4f5c8a476c62e7c85354924e5c692ad40ee5e3e40bfb0fc62fda94547d1f72de4d744c6b0e000000000000000000000000000000000f12a6a810cc4247a10975446d826d47e077af2e346dfddb59f3cab1e3326d58520c6a09e71cc5a0f2f529b4a785f8b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000008886ae0fd358d4dc149b0366c1db1d50cb26363598b728a82049696553e92c2dcdb2f810fe07b003e328bec08d09030000000000000000000000000000000009c814257e55c44f174bf51a922f9143a2aa2674b70de8953766323a07e25ede861c13321b8189d3d6e6955043c1b62c0000000000000000000000000000000003eb001098f5981e8b966a7ae01d21239330373d5371ec7a12bcccc1bbdeb07358ba3c12e72101451665608f65c15a30000000000000000000000000000000000ebfb130da225e9f8e5c755fe7b21c402285e1c1a5d5b61e1efd0f75caf0c93433937722da0b3d42652846b08e8ec2361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001709a81aeb16ed6b9c4549f906c1a9d404c8ff6e3122cc084814f2d01c9cf16f6055f85e3c63c8f6c7299c18d2f83398000000000000000000000000000000001032b231856afa4071f49c7d7f58b4afdeee61f3862c18c75ba9a46243db2edba3c68dc9c6414d1ec501ecf2c6fabd7400000000000000000000000000000000179bd02b7ce645e658b589743377b5cb49548ee95725b8bdb03edca25a0db46387fc257e533b4c9974f0da7ec212169600000000000000000000000000000000108c1de129985029b73be854f0c13b8d0e9803472839ea68dae7bdc28a04bfa5b640d277362577ebcd27de379102df461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e662365260344eb3f929a99e08786662ffa422e6a5a6bcae331db58a68c5906a193bdcfb5a7d733cbb3c6dbf76823b0000000000000000000000000000000011f73a0e4fbffd8be1047d69abd9e3bae8f2936faaf497045ca740008bcf943ce2d51724fe23ce992cb8e58c042d70ad000000000000000000000000000000001147840d29e5cb11fe6e62322b9b995e46fe5c2d6a879e10f631b607b280e5aac00769b04d9295e676f4cb6067a244c900000000000000000000000000000000180b0dabdc65d76aa6f3961754540bfaf96ca0af31c5092edc632c693e59625e7affe0874f40f53aaffe40636b00c85d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066688e510fcaf65ddb11420ab667c8736718abf790442298aa5c341dbe31382aea702b08702abb788c7be73dee782bc000000000000000000000000000000000da45b1775a48aa8f4fbd264e22b28e6f4682086ac41fd384431c7ff14aa2eb0fac3553e0692f58555e5cd53d897a2280000000000000000000000000000000015ec2c09df35fd9acdc6ed6f4251003a2e2a9882faa038c5ed4f76fad5c48bcdc0ad1bff4da148deea4a0e28123ffb34000000000000000000000000000000000fba2d0fff5a5af498726990dd2dcd0f42fd1efaecdaf111ed8cc6fe38367648a07573eb7941818ee94f2dd259e9cd4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112cee8d07c469f9d4d3efc7b8f2fe405b3ae09cdddae5515010d8eb381f2f1afa8885f4485f1e746ddba9d6b49e925700000000000000000000000000000000098c4e4ec37bfc1cb012d649c368c887864c973951412b470ad4d419005962a3d9eee80af3a7b8957759eff1792b941700000000000000000000000000000000199bd20a602cd70779a9f672639bcffb6562b0d865ee417584af691ddbed10480db780ac7ee946dd65c03d019c506fa100000000000000000000000000000000161962c0eb6a6ea8d94aec981dedbd65ee0d4ded2d7220bad3099daf6588cd7da8115e68d46288dd341306533376bea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019159dfba1593ecf52fff3a1c7e3d23288bc3c8db33e5cc12874a6bb022e35792003a2944a9782a3db866cb67dcdba2300000000000000000000000000000000012212fb5d4152c4a8623e9f5aead224fb12f3cd5dbc3777f4c573b96033e2ea3e7683385e595afc9cc297802a9f2c29000000000000000000000000000000000632f49f610baf38f0b9718b8c1039528f4a1bbc242143d065b1b74bbb5797ec550106c74b5e49769ec4594e5ef783280000000000000000000000000000000002e72f5b22e1b7130055d1cd8797dfda31d39a4c65c4fcd0def65bb3094f9d412b0a675daea6ac3d1f6764085fd370aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bc8ee00fa425229b850af08845f26cf56d169b380d888460f5a2d91291fb775081d706cd2b0a713cd6f61f758427d500000000000000000000000000000000003b4b65e9eb74a94b07f9894b48eb7f4865c5549b8774e532fa54fd73bcfeabdd10591437bada72811d419f0572e00d90000000000000000000000000000000016e4b70e02df08d385829599cb1f8fa3e7cb3286039a15972a9ae7f94a8205bee7a4d82f7db926bf4e107fddefb65ca10000000000000000000000000000000004211b530e029367b40a8d775ac519cfca639c1a092e24380e05554917464437d50f8838936ab71515e5d0af0ffda55e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f70d567babe34fb659a7444e42ae43e4334fffa09f2b9bc32e0116750696f2cad5781bb1f053f249d11058d06c3a31000000000000000000000000000000000c29ed1eae99265188e487d056da3b3ff9314c41c27cea3985fc340cf6698447dcb49d97247f8050fd9025e5b997bdef000000000000000000000000000000001455f3e89ce1e845c11ecf3acdc8a87cc1bc212f2729463ac31fc41f9255ad5a60beb42656f3a9ccfd9f0b69ce83a5670000000000000000000000000000000017207c79fb1b4f03c17f8091dc9fda49e21f47b23028b629ce453a0bebdc77fbbb3d1f850da03afeadcd427d8fd4094e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000152f28834785a27e87012c0ed6d722b989d2056f49133aeded9c5b99bc2dfb0613357442ee0bee2b22a238f1d05982620000000000000000000000000000000005b6a87546d5308af3f0b460628997abac8d563fc14cc6d4dac998a712b57e1c1c018c2fb5b73dc138ed9b8d415debdf000000000000000000000000000000000de2183b1782e661b788300548923864cc203c2d5449052accaaf5f79e32752d48ec05e2b1e833c8e6fb9ddab954774300000000000000000000000000000000110d66c8f8ddcdf71be1833d2c000f4c2f85fdcd9cde4f65b765749f9a63a368eb3673679f6151dc79cf5dc33022b7bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a5e4a980ea5abea6412ea30825338849fcdc844099798a2b33eae3e0d5cb25e7281cef2f90efd65b868946486a5130000000000000000000000000000000000d8e60949c5b9abf56fa4f509ae6acdb90c753708cd4a9eee23285cb502bf2326677b4f3b855d9d3f95332498d02a1680000000000000000000000000000000007e1fcfeee96034571d72a1197ce05ce34e53697d7a6294580ce56aa3dd49d494babc6e4f9fcc22d26ea8efa2e6d4e4f0000000000000000000000000000000001ed8ac2dcd112cf7edd79d51b7aed1bd2c5988edb02a7eb8ca01c4e30794cc246819e24550538bc7e166dbb653875e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148b994874c5ec173c38d591369e80aaf7b23a2a052ca2d280b612e23a23c8d66f70ba15746fa72aa420316767e38da80000000000000000000000000000000008ec0ab60afa123b776e5ee1b0a22d775251a465045f0da9c8f90a28320e3a4b5c2f7f5c6215bbb765b68881290583c50000000000000000000000000000000010394a5855c452bf39bb2a423518444405dc893e767fa9fd42a302b2390a7cdd2ce2dd965c1d334e774391e1b5fb2ce60000000000000000000000000000000003b6ae31ea537db4e2000516316ff3c9f520244ad452705bb576a2a5bb74ea5f7028865587a7766c515c5b2912d5a0c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9acf78e678875babcd5fd3fd9e5f62f19a90929402fd2920016dd555f298a92ea34a049cf6a741a1a9f1543553d8540000000000000000000000000000000015615f7463d0add856a62838ad0d79edb99c7572fe1d6fbb13abb43ae8d3d85d8f708595331802a921f3a357b215a23c0000000000000000000000000000000007ef456a488a08f49636aebdb8690e70520ec29faa8ae60a7fc276b9aef80042f84aaf1d636de75f9473465b9a8a4b2c00000000000000000000000000000000068d732e649bf661d279bd27264b24901c577de167036b52e5b9a091d99e83575fe503f678ff8992a6e8ed7b2f7d5d051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092c48ffa55def1ce34d0dba7cb7b8030f2fee81c2faafe7e149e565f4f70b01332e4eb9fa7c839b6c7939b9089d7eb800000000000000000000000000000000140c67c448118587fb0a78859369d05ced4cd823348830181632291a610b20f26aaf6addb7badf7c8c15977f16e9c265000000000000000000000000000000000717d34024b983f39cf59d31d426f9ff6f76ee8b6089cebf5af5ef9e0e30824546e0e64397fe0f09e493d8f4c4b215c5000000000000000000000000000000000ef10f691ba6b1223a1cf9852f015dee0858bfbdb564b8ff6eab7cfbafc5bfc18881b0671b78c6a8051daae774f9889b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fcae3e13184daf32364bb7986d2d65b91037530127565d70b6140a71cdeaa19f08dd95344a9dc7abfed1d23ce7d3194000000000000000000000000000000000418cce0a2f81969a385a8b210298737133140e07544a2961d05cbb97840fc5074d27ff305838ad3629ed527f88d7d720000000000000000000000000000000006c81ba77a2f1a59e348b3dd0939ee8a0edb9436c1edbbadfa6d9b7538ff22215b8a4ec69b99f731bc6ff3943c44e0dd000000000000000000000000000000000b7b5305f8ed0bb2c848006a036117a7d89b4c216e813b223e1a860a7b26555a6bb0de228010a92551a060cdb9480ea01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018220097f007dcd0a8122cc44be0d23364c7b68f3ec0e6332902eb3ca46ba8f0434589de0d35eaac5baf3f08b5a5cff200000000000000000000000000000000170a44f73678b017b54c58422293acf6dcc8be832f55c0cdd5e124f3bfe1c3289287452825c642de85226977ce75475c000000000000000000000000000000001572796799892e96bc6ec55053c91598edbe707ccb0376ab8759b6b9486f15582ca87323f1308e69c9e690554e895502000000000000000000000000000000001383a327f76862ce0341278bcdb0bf4663edaf6d33e8925440fd2e9fb84e534f2bf340bf31dad16a975a2829367dac461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bace9b608c575d5456ef2418e19bf0e5b40b0aef913380190f54b049dc458852175326bb51072660189fb4489b1a4270000000000000000000000000000000017fba5033f5f5fa6ff7388759a432060de9121c58aae3300559f77e6ad214c04e06ade066c513776d2f2713f572cebf8000000000000000000000000000000000646954a2e21c5cdd51e3743f75e89f1bfbeb99e8cdcc2e1dfec4c14ced9d68d37912c9dba9ff5a1d5492ab2d04946420000000000000000000000000000000007bb38977b6584338b0d40a09b5578bfe1c4350f361413123e4cb96fa37d6ad9651fe8a376077a0a29c9c3d33d133c7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f0c79818f4db2049d8381bde101faa48326cce226c54ef10fc9fb0997176046ba0ad2b1ecfa7fff08d06cf9685614e40000000000000000000000000000000010b2b8277d11a3d204f99bb626ab43fe9f5750a72bcc872fda68c4cddd6a293c40cbe9b610595b1f2c2b6ca78292ad7c000000000000000000000000000000001137391b4883ddbcdb4b22caa8eba53ff82c87e3f7c62677ded8cf4ebfc326c4a0e00dd699fbdede47ba7185f96c14740000000000000000000000000000000018cc75b7d282d192d95277f8889a0190df91c4347adaa0198dd76d643b1852c098658885b5a21f7d4714c221307aab0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001587bb8badaad9d73f4bcac7ec27267748c0c62160fc4a6db8655140671d624b7e9631f9eb699f15958aff07867164020000000000000000000000000000000004ccd119d74c8fa36e0d3fdf8dca487b6b27da877ab548e86b804aee6c1462350818239e438c1fa8a147d6749df89226000000000000000000000000000000000772617477bd9897f27bb602fa3b8e6a447fc08ff9d9311bcf1d35f4675a61a7eeebbfd8d5e5b6dd61eaa28405b101c70000000000000000000000000000000006ccf30b015b1bf92cc2ab1e5390cdd012494d933e05aef7772cbeb2d400be49ca4e88794f8b00c69a51c3b3ee8d35421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037e653978a769203edfe1d17f39674442c748f728bfd6bd8897517a14ab4c045c5d590da5b6cdbd116a645d591d019600000000000000000000000000000000013fc5225de46f535a68a5a21a9ac505ab3c81059dee70295ea18d24b65cff44a081b3967eb071aa72c0474d229cd9300000000000000000000000000000000019e6315c31698af5364366b788f5311df6d03e034e1c5a99fbbbf7f4bf0a63d11cf39c196ed92654825325d3c1b5f1f4000000000000000000000000000000000f84d1bde84578b57da85dc401a8a93a228274d4ce1cb36a602d7b38f9dc2b2fcec870681a92344d39651e23400764671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2c25f41e5dcc785e507952143db7659a4cab91833372e9ded28d8e1f90292a4a8305c93a9d476377247769ab232c70000000000000000000000000000000000f8fb27adfd8236b01b48cbd06e9d51fafc7c5365160e5bafa52606654c638c1051305d6a2f45d465d70fad27cd641f000000000000000000000000000000000b3005d5e5ac6ed721feca1c9b2a6693a89b5c9aba8e0e1e6cfaa673651fe07ddf05e49723b01556eed7ebac513315c4000000000000000000000000000000000545971faceb6aca0748df65d42ece7914e2e8b9e1a3a8f998dc99caee87453dccc689523777e80fbc65dea6f03a17841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030560e81126ce3a748c2a9003d2098c9cad1db18a90c7bb817251bf032180f46955165992fc7cb2d4dcb74f6969f9da00000000000000000000000000000000036122082a8a317bfddb2666c7abfe458004fc9a3bdc08aaa9ea6b7bac5e116c13e99dc7db41ea657dd07111bd7ae3c300000000000000000000000000000000029deac2cdf87e1f6e86897c9faebd91a519bac1e87b91754176acdd99c4e6adf256b4a90dcf4283ce79e3a425848a6a000000000000000000000000000000001627e51f4c11cb74e3127c4412701819b70477c4ab2d627fa674b1e091dfc4f59085889d76a052c92f60a01e4331f0401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016a6d3fa1641825a2c6cb57ebc290f63032889458dafea568c9231a109fc88c17518f2567823e10b2e997de46d2798c70000000000000000000000000000000016322f7ba19ac68a362f93e76610831223935c80481c6347909e830b18a3e9080a415ca03f12005ad0980b5d02652336000000000000000000000000000000001544753b9c8fe12d74edd9e26f912b0cb6f7045a9264c724241e9e21c42e053e5eac56d855736470c8563257177423740000000000000000000000000000000004f7a96969a19c3df7b596939c99e8325fe2db0e5195d8fe0975c4a2323e4493304a904a812f2428faa7616fb67ac9051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018412445aed14377f37cf0883540ecf97086c6761f3692e932c9c1db8ccf44e88b5c91883f90a5ad4f9c8f61a50eca7100000000000000000000000000000000140526c92d058e26d578fdf232a3d982695e0061201c83eca14639edfac4165fbff9b5ee8f231b4107e9d8ae3ef8805d000000000000000000000000000000000669562d2d796a830bba80bc1716af8cff97e03a4ab069b410f491c301c6cb732e571ea280ba1f8fe7121353e2b0827b000000000000000000000000000000000f4165223e932a354e966c8a1f22c6ef2c78a3d97ae65b3ce3484d062fc35d53c5f111d231a7310e083de349c56941691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ffa02cff33f07e0a5357a410527e99e1b13536f669d9f14bd57e0352cf4b8b7558e9477bc3e7b3387ae7f340221df10000000000000000000000000000000009075885df8a5703965e26f84cf78e1fcc5d89b1e5bdecb9ec6493277797a049197c606904fa3693361a96af99a442e7000000000000000000000000000000000852bfd13d7c103d9e5ec7264e6a1ba46a415368bc2ed35cc17132a23301153daec7818e4c0b368cff8fb094261de5a30000000000000000000000000000000008261a627bac489093caff59154ba5353ba7226061d471750d5b301121e082c1a919925e56812ad8020cd444dfe47f131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa54c8111405d0c03f35100b7c10f8989bd574398e818cbacdee17019e68b938418e5d6534d83536f94234c3ce0e796000000000000000000000000000000000908f4029605b99e06360f8913bfa9df9663e1f8581d66d4e477ef3d6cca3390d8b4f8c37cee26a4823cc2417faecf98000000000000000000000000000000000b7b9eb8d8f7e84f8ce76ac2a2d9ea6743974727f8e8024182f64390c942cd982b9ed8fb61cec2dda50438799f967bf3000000000000000000000000000000000fffbac2ddb46c588620d481ae491a2e59dc852cd4c1180fbcb5ab1af3e90626951e8e351edb4d62d0e3f76227f744e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019352a2d4bf1b414a33d6a7688e8fbe1dd15c21592ab325a5deb35549ce0fd30d3d48917cd95df9658762b8c27321585000000000000000000000000000000000c3890a1fc32cfea5ca8a2f35b14367dc04c734a1b69dfaf8d92a8a15dee11d283fbcfa58e93af067855f2c57be2d2c70000000000000000000000000000000014bb622ea21d1878bf27f3db4ac182231156c5f7073a7bce2e06b2341609ae71509af8b2891a3d603f44581c0dbc26770000000000000000000000000000000003b0151220d4858605fdb2d361763faee72a76de0907827994f3bdd4f8a296f44b04e538c91465be19c5d0bffd23e2be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a204612d53db78afca947e0bcfd1cccc2799b519513e0e36c19a9dfa3cc76a25ae86a810e61b034e7c1bb02c5c205140000000000000000000000000000000014fe93fb6683fcd34740a322a6cdb664d2228c083702f7ad1131912fc9e0c65ba67c7b11a864a093c7d3a05a25dbb3ec000000000000000000000000000000001476b6996a63c9bc64488d79f797d19c6b80e067be01bc77c2bc17cb5533f72b1dad5019d76aae722b730408848ca878000000000000000000000000000000000a2385a1f49b090f35d953313bbe66c24ffb1cb6e44aecae6259a66555074316f8f4dca99d67670101e1173e2df764b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d33d6fd3642682b2eb0fb6670b51cb364367eec72be0a53a3cbb18188c84339db3c7aae6e53d7dc93bfaced96f73fd8000000000000000000000000000000000de0f197cf67c821c8ed5deab6ee2a055525d64a29a46a452f1627c27254f0cb7945c911751ea5519eca2df4928a901800000000000000000000000000000000043d5f77b75dad9a05be2548f487cb52df4e5708974823c2e1d06d2dfe1af9f48827c57d064d5c45cc06b6e42829816e0000000000000000000000000000000007da8a0b553346e3970994a40fa5379c8e6c8316d512561e422c34058a01df801abce2bd719fa38ea119823188d2a8441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8f51a0986a0c35674d96ea24b8d2a0ada8a65e32682b3dacdf3008f0f5cb83b7749efee23f27444d731d3eb8fc1ab300000000000000000000000000000000182fc9e0c8d0bb9f79cc8a66c242ca457bf651eb8d1ae530ca11a7181c3ecfb0232ea038d2066083ee6b60d2d1ebc03000000000000000000000000000000000109b3ea91b1490a7372ff2e093fdac429d713e4e96c07619e9a42208a172abb0ede907907dd4dadf18463b7d7ea4fd5c000000000000000000000000000000000b4654e698720ddf4a036401e94b9c39c2bc8ae055a6a1b19b6faa2a0e7ba824ef2f3037af846a2a2f727b982fa77faf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181af21f18a7d595564aa96dc3f02f5a6233dd524a962b76966d594204dcd4b7bb1f480fa568b3c2dd2452026661e25b0000000000000000000000000000000015c1e972c3db61c53664585426a709f873bbfcc068a93c1e86fb7790c48da425b5eacf7599d7171ae93e1b3e8f43a4a80000000000000000000000000000000019b1fa411a8b5c7c457953337185cbfdbdef4cc866fa7899a68a6f3af3d630287a4537b5e8ae71f80d05521eefc9e7b200000000000000000000000000000000152ba8a41a83c201b6e7e33dda1090ab9261313d219fc5407845c65c4e58c2ec0c58153d2bf8df57cc1dafa3b7f8aafc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a7b2ba163195a1845b37661e537a13f3f3b0c1ff63b2d8cadeb327b8b78fa5014eff4c07e1902857d3541148dff221000000000000000000000000000000001115c7ce999d4a332bd74ec9b6ecd67ca6526de7b043bd6f9bf24d0664393d381250adbd326207f60f82dcea2300978b00000000000000000000000000000000114fe0966f42826b191b7e046156cb2a6ead458bb9d69f8682c7e8436157bf1e1f3ea3b143724dbc6f3d24b9652090c0000000000000000000000000000000000e2fd360249488aabea29ba6d2a778b272676125657487f13196bbfbff5d1fe0c8d6833c8c2505401c7aa3e8ea05bf491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007032fb6938856b7b6751c8e44293e15afa939c41cc2eb7947b25b4959521568bb8dd71b94c6fea9d31abdbf262311b30000000000000000000000000000000014cfc5e63024d9fb3972e15383cce25cfd6ebd107da68a8fe736dd2297a97e209a9ee21ecc1deba8b0ca119e2a3bdc6f0000000000000000000000000000000004b52860377fc13f562103935809800507ebe7e7c707eebf64a6cc18b2f73f0ae1e9d7b9961d8342343b8b92923a0390000000000000000000000000000000000f5e1cc23e9610221a474781c6f3cb44342ae3471d457f0411f369e472a7efda951f81d623ef70782982c3cfd4c65e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b7d8b4037b6ec3bd7fd00e99e9f116f9a8b51eeff8551443f862ed6a6f4a05ad1c8f5a905bc95d57cd9ef1e541c24c00000000000000000000000000000000184a677ea38273f7af7f689f8aa2e1b230802b9bbef501f08779f42d6fdf82eca5949f70cae268a8f61a3ade8aa453bb00000000000000000000000000000000090edb16254336cf902f07a360730d22c6f6dea915bf55d4e5ff00799b4055f5a9f467d4a6a59e7d8d2e302a2a461e99000000000000000000000000000000000447f0d73530ec5b68e8f47e97a77aaa6a1abfdb4b046760f50478c33d8b4f22c963b19f146d1c600059ac311658ac6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001165da18a43adcc426c8d1422f8e43ad33f406112679cd702bbef5442617f5defdbc1f7a02e2c5f643b13bd2d4df72a6000000000000000000000000000000000ccf19a5f22b8e3bc419d6a870032431793b94790a60863527b58855bcdfac5ed0496a9c50097067c0c9a9b14ef0b29c000000000000000000000000000000001085f5afd2808c359d2a22cb6e50e195a0b1525f04d8f95b73312ab7c09a15e732c35fd5292868a806b8fed952e1fa6c0000000000000000000000000000000008fe2f68ff11afca8a236fab884ff4ad5a97ae6637fc1f2adb79be630b7587bbe0d7b659b8b8c83efc3de83c7cbbfb111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f33b5121373d8139214ab8359f28791692dc33de2673544458ab4058a02c983f0226b38e926eb6455f15414073c55600000000000000000000000000000000195ef0ab287f17cc11b667e627b69c4dd5fbc976e81a48451e28c6be371256ed682761fcfe9ee5302dbf7078768261c6000000000000000000000000000000000e939114c8cd332043f5e01b8b3e606e48dd4c259264dc02afbadeff9488279d2427734cd1abd890c00364076c1ca5a00000000000000000000000000000000006444f86ded8a99414ecf6ca864321ac29b075aa01337ee689666c949c9ed046b140f31f109733d9d949e9a5598c14821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000aeafd00ed00f02f1c9a2427675e6f2bae46842d02d9864eedc27082f64bb70b47f3a74e65e4565f1c1f14198a2b89900000000000000000000000000000000040318c66bdeae1fbf2195f7c456f1421baeda98240c7bcca59374ea315f04f233844b2f826b79a6d28148ce1044ee0b0000000000000000000000000000000002b727883399298c762502c10c920a5f0ecbfdff7d0f4819b0e72df3657353e42b9817c76ac817910e4b048574284b300000000000000000000000000000000017a22d333462b4d53313f556efb9e29400852051f46b07455f98959578b40705b6bfd01cf4ef4a9c7a0ad8a752287d7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147c2ce6395844cc949a4a963abfdc14f1090e149097b6a14198560114266bada4cdc8861a6070add3a30766afd1b36c0000000000000000000000000000000011570b6e940f932ad6d0295daba39f0fb8705c538e13f877e1ead99057712e34276422bb6216ea7b61340532948dcda30000000000000000000000000000000007f6bdc504a99ee9cd57fa5005fa0e0f26762b646363e61bc507d97f82bcd453dc681b807e31e7d497b19d278dd0ee14000000000000000000000000000000000805a1dd2afd8a1a47fc363a4dc4c6d19f68c078ec58982249576f10f1ba3452d53318087701f2d3ced777955a70d8161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e10319d1b233a6eab491b9604ac2086685d29c19a484155439c1bf8c5ae26dcbfad52adc283a3df59b048b19c95590f000000000000000000000000000000000b17d5d1d1c6a73214ef95323e66e40653ec7069f8b109466f2cefeb1a359948e477df27f55d6294d274f633cc38ded80000000000000000000000000000000002232d2020bf2677ceda4ccc52afedff832115a71d4e589a57f1466ec09e1968621f5c55e126d70cbc02ec2072c693040000000000000000000000000000000012bca67763792c838e436882b59e415b77808d37cb6ba90455a7ca74784a8dd9c63a035cccab545128985b59cfb7e5931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000244b7a88515ae470ab4c535452514bfb99a605eb74122e481247c0332d9ddcc098377ea9a35238ef8e0004a1d6551c1000000000000000000000000000000000038a4f4a41219c9cefed9764ed2698c5ee36a47123080c0fe29a81f4d04ab6079f7c57420b889ea704c8bd5d3cdc5fb00000000000000000000000000000000034381085e74f8717a84e6cd6969407fdf50aeaad39e42bb6d6ee46759ddb5cbdea9a163a5c7f928ce65f69301f4abf400000000000000000000000000000000070cc29ced091bbd0f8ac95ed675cc3d97df4fbe1e7f89872fa354d8a8105a9d15dbdba00b2935f6d18b84b824b3d02a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018606dca928287ab29aae1875021e2f988f9ea1ff28cb82ed1e9a00f983544be4b21d13e16be2abd8b36da001b81fc080000000000000000000000000000000004fd5f248e14dce79fd25766561e88d86a142d310de56e1b132d2d49406c2dc768ed06c0b299145b9576c886f6889bc70000000000000000000000000000000000333f28dc5371481e29c1808b455a5941d3e3a2004767887366b698c208bf51a586ac74075ff23794b62e46540280120000000000000000000000000000000015a6101d66a734130f8cb44b0ad89b0fc57abe45d6cd48f91d35dc57c2b374bedfc5ffaadcae9ef82e43ee0b36a094861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a734395608579021e9ca428ba5f47a0235ac89c7115c467c22ecfa654d6e26ba08243cc76b037bf8d38828896a7f1060000000000000000000000000000000018d19f3448d52b16eb2f09df1d92ef62846097d809a9e4f71b5201716f8b5b7153c6cc94d4c7d6dcccf62f1490c47be8000000000000000000000000000000000e5563686ed6668f70abb9f59f5206b8ba1fe9ceb0efb7ea9785dbdc228a0eca6fb0652ad8e61dcc785c5cc2cf0e06120000000000000000000000000000000017242d006e41ede3dcabd4806431a784328f50b840f05dd4cac3a0d09c8134d1f0e88d41bc07c05111c48d2871bf6c021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000960fc8ed6359bd4f52a4be2042326a2c4d4f6efa191a206504737d171a1aa56f4d07357f1834d645833d0a9f055b56000000000000000000000000000000001407670157b31d38812a82a8eb8b58d80331a367a87d5a6271b93074fdcab2635a3262c36b820e639938043b3bb93ba4000000000000000000000000000000001339ac3270951d45e020398233649e07d1e74b1fd88b6a9174449ae7b6b6bed15094f346aeb5632bcd254a8cb502e45f0000000000000000000000000000000011cf85e4c5fa591ab0c0473a09572c483cb6f4d5553ce4b99ff07899b6f66e5414133dde4ffcb026fd71eabfc55d7a6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118a3b5bd9a8367df6af54b09b83566b6769bd71c95453f8e39ef9c7d452f3b3b3f1acf1f8efdd69a434a7cf308c584d000000000000000000000000000000001499c3eed43d3e84064bf99f64a9846feb2d39855f36371d280dd64e1d066ebb6b530668910dd188f8150b45f9b7fee30000000000000000000000000000000006189be0d9b5d75b72de13b4632344701f7c4544e6a5c0661e9b7cfca7d9c8f2c921778f51c3538a2bfd374cafd88fd1000000000000000000000000000000001835ab6e36a6dbedd7bb79a48186cadc8aa8af6981024ac2057b412446ba01bb322c5d00d2e5b678615c8a296b080a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e49f5e9c6650dde9bbc767b5fb8eb8ea43455653193fd0bb6aeecff8d592eb9646b8c11343dfddbd0a255f4ec4c22800000000000000000000000000000000114b6db8ba79805e930ace5577806707307cd5fb644d01c6b41af665bd90e8b39a7cbb8ba1adaaae2e4db077f980fc38000000000000000000000000000000001215ee646eefb826bc986c6adbc591843aa3e318a6bc6886725185edbac6b3f22bd39593c57c6a9c5249028696dc9a35000000000000000000000000000000000796bc5b4770dcd90556aa5aa9ce03bfde22db4af927970d682af1d1a5c383edcbc86abca431c341981debf16b527c451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000190fb3ff260b07bf49720d832ba515ce384d31a8bbc34bd51777873d98d7730830a4ae9242ac3cfbe6c80a56ed0eadac000000000000000000000000000000001882c15afe9b86b08f26dc6bac2eb69041e3ab058a7bd2fbc2a582c3647788276525f1e3ebdd8dc9c39534df33c14047000000000000000000000000000000000ebf9a3cc852c0e662b770a70b45b946c629d1010fde4248ebef31c50bc7500a809cc0e8cafb3465c2e06a245958859a000000000000000000000000000000000539d0956445a8b86685d67dc64bff935f546641a408c2a506f3a2dc1e57f41b4444841562063cd5ca7ce2eb8d58bfcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111a80b8e17a45740fdbdf94f5fc15505f4ae2c979874cf897bad03c603eac375ffd33cf8a75d71b88f348016b47371c000000000000000000000000000000000890117269dfe3986f2ddcebbd203422d631e93a181681102a691c2553b8969e79a3f709010e4adb25013fe333dc5b9d00000000000000000000000000000000188af64b5818fee9be86e9c0bf11f4e5a51cd6fef97de84df00b6355564bd00f1748b43ec5849dc11282ec4954eeef60000000000000000000000000000000000ca6fb93ce8aaabe7505f059c71e264fcb810dfe2a49bf23a48418666786f29f2b5efff04f459b862ab21274653500591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e2c1b55579b95f8ed370d7118fc276057e73d4baff293da1db3945dd1279e23136c6378d8293668688e45943fb4d430000000000000000000000000000000000c410da02c7c32f2eba77b8e2a085faf20ff9fffe799ba81e8b60c29198fd2a22f12bcdc9553df432861d59a5e307120000000000000000000000000000000002492568d25b596057e1013fc77197df068918bf75bf2095f7f337be7c9aed7e368c7282b935d41ebe94c489cdd4efa4000000000000000000000000000000000a0cd8e4bbef4537fb0cfbe75d13c709c263dfa64ea1b04258559c512a1eabae2d1a36cb7156e509f76ffa8efac7acc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000129bfef481b0fac1c327a2e47af1f9ddd42f782cc0d32b16b91be618b78cb0d0b45415f6bdb82ff5575b7a05868390f800000000000000000000000000000000163a0b1bfd787c1270164997b7ba2e2f0592570972fc9bd6a11d92c00c995c6c4bbf4d7832b88e48029b0cce424d4a550000000000000000000000000000000013364d52522e84ff293d03b7ad2bef4d8fd56612c0a60b8c8208da701166c12415d1b226992580c4c2f1a110aa30486700000000000000000000000000000000142931ddb4d4ccff2b29ead016f55c4effd2ad855afca77b0a3d58e34d3a3c07030663478408eb8fde9b775b67d3a9491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f4eb6e030980cf76714a2e98377c4ed296a248eaa65b63825c71a9df5bd69195782aff300a318c5b0135bee6f180310000000000000000000000000000000008b33313b29587b3d8f892ca9db1d924eb14836cc8926154379fbfde09b11c72a1b2e732a5267862ed1f61257e74bd3900000000000000000000000000000000114e0a4e0f937fbb5d1ad42c8747009e09b6b6fbcccf392ddfc724c57c2dc23215c2a9b6d784dccf21bd099c93d9c3d2000000000000000000000000000000000ad5b8f329bd0ab0ec2e330f92cdd2d8d69ab01415b8fd3b4d743a23290f0c1581f3648989218cb3021e03be447e8e031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007712221ffbc33d76b18787503a3e1049a67af192e78bbeb7faa5d51eff21e1489cccc82d6dd7dddf53c3811c3f2c3480000000000000000000000000000000000b19fd27233e9ac26b011c09d0ca875855e18265133e1a8ec384bb6f4ba317263b8538a37764543ecd16d67594b8ab300000000000000000000000000000000053abcb1a7507e1d94f033666b62ad1970ea372597f13b572db8905f8c94c715888a9ad31e0dce1f56a42e3cdfe9b19000000000000000000000000000000000036bbad31764cee56070df32db5fa3d1886179b125e5bd342a3fa93295d0238731febd01c7d22560bb64b1adef0139271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000068f84c19570bc5eb5d6780f2ebc0419c78dafeacfc6ac486d093114dededa2d2cdcf462559137b79919ce79f5debbe6000000000000000000000000000000000407b5d8793da299da23e747342605823080ed74203a415a9653f2ddf8b399f785ab8aea87005f1a01f35aae247081dd0000000000000000000000000000000011aefa333920867e9bb933a0a72431c09adb236e16274e5e83648cb796fbecf3d1f0a4021aec6ffd0c75e42a154560dd000000000000000000000000000000000584ee068921e9b5f11ae53953ee4b0b49524784c86fc4fa09d0cfcde8fa87417c63a448c10840601293a1e2b46142c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001812281eae1212851ee34d25f27f24b0d931e24cdf04b7323f87a9401966c50d2d9ac4b389c7a9dce4edd4a9f6317662000000000000000000000000000000000a08abd9dc218d21ec91e4377d93bf1a5d673504ee9f60274be05df7dea164391a36c53739c4b174bcb680d5ec0d677b0000000000000000000000000000000009f8a4348bb2cd5f71136125f3049cd8cdc902ac3da99327228364d2397bbd1abda4ba66576bbd8bb0a7a002a90087c70000000000000000000000000000000016d670a483bd40b836b21f39c3b6641a19e7ce61072dd3b14ad371553a1fd9bf39f6d73a7490785d75619bd6569454d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019305f1f36507e0e8521113e3bbc2adec7ce1c049de5a674e0085a102bf6f1d42338522b4f09a3961353b057e6db97b80000000000000000000000000000000012d439f0b94eab2216747fbbe257b0fafaceb41d38e4326023e4af91c840232947bc1b4acc0a2c8c283001aa1f42f66a000000000000000000000000000000000e0d7ebb5b7ba07fd5449df40ffb5f5719079ee0971878f2ca9607139e68249da6bc15bf7519dbcae55e3b1bd1a61fac000000000000000000000000000000000512c644575503d35739f0d605b5eac698a3325960eaf107fef2c2d46ff5cc6cae446a42c2dd09bd2080d060f349124b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000147eecf5f54d9e36215cff57a3104e228dfd6065b1c26f900455e39c04392b3bb183d755349b879770bf3dcc1627e16a0000000000000000000000000000000010432b2166989b922a30f29d2f0beac393c404a4e07c60c45e68f162930d419e037938a499d235d9c800d8257af734080000000000000000000000000000000019e6982286bf1a6e395c043e8c3c96eced51045340fb00d3c1054f1c946bc99c860330ce75fbf901327ef7516b6a4ea10000000000000000000000000000000012d700492a7fb1991c82664a6138ac7d1c9a1cbe684a76847d7ee970b0eac2b7ba990a3ad44054267aac03c8701cd2651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024f7cff881f2c0cfdca829a0a2265c4b129e28c5d57fa3da878b3f2f7474bca258fdff29994333d8ffc11de9bd6a3b40000000000000000000000000000000007ebb0c5f4696859943e60ebb0bf0f945f01c92b17464263b9a0b50a03d54609273d45736c633f5b433729b788b935410000000000000000000000000000000005b614db814123d240cfad4fbe8786649d1e591067b8531c18bc07176e39744641be4d0ad0d5b09a8f734f69e016ccc20000000000000000000000000000000019f20d67b9b6e3c4d62ff1fb6392c8c9c647c014b2e8b32e6fdfd0c3625c0a35c6c93cacc4c4f4a8f712c331daf11eda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b57ade409f3c95cae3672e11894fe94abb3a619454e78bf56a585c511c1374778a809f38985a66f2600a7d3c3468906000000000000000000000000000000000397596b505cef9e1cebb8539635d421954b00c4ef709262f932a27e2c5cce29f005ee1703d725e6b38189c29553626e0000000000000000000000000000000013dc0221eeea9740f34762289859eafd1c4e14f76dc0e4a15557a652c0062e76da199bed52bbfdc1902318e710ff88db00000000000000000000000000000000071e13a72168087b6e1ccca65f7beda0d1ca96bd7dca5f917986868a17d643f20a6140a649bd7ac024cb9293e48d25631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011365b62b61c0f3f6e021cb815c7c8d1b5a005a2169eaaa27bf8a230af1f169aca2ac71a44c2e6139482f0908c95f25f0000000000000000000000000000000007ccd54a9f3a898585d68af29032babb808197c6e60b3f9e41bdb9fb518a3bf5c90620e4bd35e7c533005a1b92f3b4c50000000000000000000000000000000002ea122b9908389c346cd77b5fa725bd338becc89dfd423b4a688209adf9894f34672757c009f2db07d4208c743cf5eb0000000000000000000000000000000014e5b66d4026ebe0bf79008fe22ee9dc3783806f7c0b96a76bbadec13e7312c412e11d63011038b06d32a1a2e0da93c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4a459a3b459eac8ac5258a501a6ba25c8fca39ce1dd89bc921d4bb313db4a536204ce7a1078d27aaffebaa29bcdef700000000000000000000000000000000163ea3ba94263b16e5fe968221a5c454e97d1c15462a36d767478bceadc21f5973d9cc0b3edd89295220655ba13c16450000000000000000000000000000000015034b768dedfeee249b008ff78a64a8bc5582ce06761ea2684b249e4218406d42d56e600235d83463c4bffcec8a9e7900000000000000000000000000000000175100ef2d14210b320998f4e2c3106184065036352b4d7b77733d7b3ea5d91173b16b42ecf04345717644acfcb5c0851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000064ea2b66e11cf7da1438edb1f9e3f72b622217d5b4b2d353de461b0272fa549064eb948620c368bfbe0fb7a6ea80ecd000000000000000000000000000000000c591e5b7b0cfd05435b9a56d0928a2a14c276b6a3896b637564fdadc5153683d672493103122f136cca6143978e2e11000000000000000000000000000000001625529d10ce4564f8edb8d4157afa00719f451297b75e3d095df0a54e4302588caf229f21de0c0372a56f9ec2d7ede0000000000000000000000000000000000bce063fd03f31a20c277434295701e20ce668c4e97ae83edc39336a81d9bbf5725118b608cec15d4becfcb2596ac2601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547818ac7f74d0820a9786e0ecc319696a2c40643a6276f6bd918e5752e49f148f93d1efdacf9fd4b685f1dee3d09a70000000000000000000000000000000014b92c43c212c16334f4d066e00ffe68fab8c9df45da27a72eba6be871c1edb5ca5ab0697d7a7ca1f1fc7007b357a8c40000000000000000000000000000000001ae36b106b160c1c4ba7df26cdf50dec457b3077e709f80877240be5c022d676b3614709679abf7e671835d5b28f713000000000000000000000000000000000e2e0b144cc06e0ec1d6031595786dcee7061264fae10897e2cbc65dfcbe0c1954f7111cfdd30f63dd5a0a33791b92fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000edf04176b736c041bd82b913b9b788ed2b5b9404589d044a672a6069806c01ed07b25b37a7c5310a127f35e6e23925000000000000000000000000000000000fbb3e0f75dbd302453e2b9893decd0dde996860b530027d3ab9261b0874a28da530a0dc5da6fd22c293c143110b2f010000000000000000000000000000000004ea48fc776b6f64c683c8aeab32b0e483040e7c6a569ba91ce2762ef6dcd5f031cb8eb252accff2c90af515755ad70b000000000000000000000000000000000d69b8b4be292e41edd5e02879062477b67f76c483901d3de33ce586df982431b857b32da783ea9deb057ed971f324e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001643b8063e6b0d19e4b6da312c7c50a5c8a9f87ae705be985be581ef99d0df7a85539d0ea9f4680a338fa59ec3e21389000000000000000000000000000000000e244ddcd204e701874401aeea4aee55d4b0d1dc30ea2e486cc7f842ed6be9f39be2f2a577c7088c863a43ac7d3f4d28000000000000000000000000000000000c20f27c6ae0aedf5f7fb0c134fc5a5bdbc68ee6e4109b867bd3751edc7b3f8aa02549d7dc944a24fa69d7f7ae30011a000000000000000000000000000000001129dc6deded0ab3f53c60933a96ff62693a4419d453d8d240ce6f7ebd0a3a776d6100f35428001eb755528f342321941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfb714de3f8c310b0b70525670b5950ddf94da002f74a9a3387a5709e440e805ee8b5f7b631858f51e665c253108c8d000000000000000000000000000000000a20ed389c6f0df832a5ec5bec9c02bf890499d864f9ae088ac755ab811060185bbf9a53516f4b444cddbb0cd30d5468000000000000000000000000000000000d534736b52a7707d863f01ed59f96dd9d3914c03e119a3dc201f302941a26987bb53c77a27a5f06f19413ab74a3d06700000000000000000000000000000000090c7391a190a472f5ca9868f506625b0955138764be339ccf351a0b8e2540d129378cb5528bf0059a040173c56853741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083bc547c87a7dde16ce9826c9795944885ece1d2ce1031298af010d6827dc82a8ce2cc90fe0052a814324dca9ecfdba000000000000000000000000000000001398fc827f4969ac1a80bd0dd1503a34ed0699779ab6c8d902d71a829d786a5f688c694f99a47052c629007e4ea463440000000000000000000000000000000007e1b442d323d82fff49c42a0a48d695c0b14d0332c1c0c00f35d604e12ab70b629adcdb8c94a72c20131573ce495419000000000000000000000000000000000f3fd71f10d3c653f0c89e58ce4676fc148b8ef937b5aacffe7a4208d79763fcf53f26b3280026871a12b68bc511206a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e9d4a5748f2f56c336d84ee51ad589d2c250566d61b26e06357d15b0992ed64afdc436c2b923c5e6e0e3de85bec2a500000000000000000000000000000000172dc799eb04591be7b8680b86653a1de219bd1b91bd8d4a5381ba2bc3c3d769f45aebf1947ee68381ea2040577d45830000000000000000000000000000000000f6d5bdfa4886b16d98f5897b7e412f97e70b39dfd321ed77d479b4cf25e0b5408849fc84235147045007fe8f2156280000000000000000000000000000000003ff23b6c8fc42e3468b257f47efda211668e1ed644c84fba15ce61865bec4011d31e265f94cd04874672428dd94ed551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009effd5f8f5fdda8ac58c42773dffb2255deb9419189648d53f0aa9319f4441c63f9d2649cd3749b82158ff82c48e38c000000000000000000000000000000001356a417895f0e899cf6d330cd0a01db2a8459875dd5073b543c6560dda3cb54b40a5c25f5c15625a4272372d5393023000000000000000000000000000000001405b823df7a69d75f6af34f2cd076eb31a1fbd1a4c4a10b39c5fba46c12b30192dba27c2de47d05344ad496943449c300000000000000000000000000000000078be554c6a065c3c59f9917fe385f5c39bcab66055e4135772b118ae2fba3d5f8b5fb666e35fddded938d9276df04f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019208e29540af53fd32c26fb49ca26b0155610640e03857d8c21e97dd4431cea4adecfa3f94c0ce553de59f1be6664b0000000000000000000000000000000000eea9748af1282cc6922a74cb2907d0f81c112fa61a72b26511cd6cf0f561cce86024cb01f19a1287db4487d392e521c0000000000000000000000000000000002644d56f62dfda92dad99b6557441ec0d4afe5017aabdaf2dc536da0543daacea116ca569ca9c2f37d1472d6c05356a0000000000000000000000000000000000fc515a41dcad4ec5449f73889b9f8d6e3e2dccf73d6af8185987ec0b90953b0c2462dfe64ace2c4e777b704ea321a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007729f8bad404e2e6a20a28dc74d3b6c5c858c287db8e02469e606727d217a260502227dc6b3f5285fdc309f567d2cde00000000000000000000000000000000094332e237f3ee7fbe59b0d7bb355027534b6e6c48fbda8ff4567d336e378866c90e63db33dc411b37c29c84d02abdf700000000000000000000000000000000163336bb5c54f1d4e1ef4f4c8362dacd23a11c3c17456b5b303f749706194ccf15f716a17aac2a42cd187a0dc034c689000000000000000000000000000000000880af8fcbf82fa6054a320b3254df62c3af5760eb5c3498c5a91a44fa323ef0edbb76a8f8bdb98291ba7e9336f0f7231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093182555767eb1933e7f13d4dcca5bead5439c9dd9cd37204ca5079b33bb495bc120552c70fb3202948b5a5a64bc503000000000000000000000000000000001964d32269e0cf5d2aa0e87dacaca0eaf6dcd599d77e39dbb2f0b4623cf95a65a1582e614e85ec5672223753fa345565000000000000000000000000000000000006bfcb0003556f8b521b8d68346cc3d38596da9bf65af64d9dc2dfb4c5c32eaf0d403ce5fae467cb6708cec2bf62e600000000000000000000000000000000053f15ba0aec62869086b6d059a00e1b9c667706c4e3ea50fa2504e5965b3d0629d3d2efeef952f65ed8fa0bb14e278e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012781c6d5af21010d9df03577568e44b3fc9522152d75207a10ba055d1867d1ad81892d4ad6029630b755aa8f32e98a700000000000000000000000000000000012b14e871ca77c2ca89f1a833d277ff4ac297391414b8515fd2f5a25b04f84f03fc32e6cf2c1a7d2b4fe278e1e4a992000000000000000000000000000000000eeca068888ec6c2708e8ea65adb016b48ab6f4a0803f75fc8fd8c6daeb2ba7e38d773d2de2834dcab7115d4ce6c875e0000000000000000000000000000000001271e62542135fb74cde88f9bd8cfb559af51ae1d1ba8e0aaaab010051a6d1964fc21e818a14d5c54a39290ef0c60c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000088d7158364a1e18738d292efba065a3ba87eae7ea9ad1f39516a848d8657dd2bbdd51d4e04561f3711c46d28788f77300000000000000000000000000000000188121891681db0bd2f50d940f649b88ca6ff65b245a0bf5813262db8cfc5776c48629adf71370d9209a87799ebbb90a0000000000000000000000000000000013fb1f9c9c9700617568eeac2f224313fb6c4f6b51aa2debc4a8633e7315386091cb1f23208629a1a71acc71f7bbb77d000000000000000000000000000000001215edb100384734710f8c4c1638ee02820075e93fe359c0acc8fc008822fee0cb83487b486c636d6e9251855b8d491e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d92394bd48d316c86b5e12acf36d408bc345433fe8e10f761ebe4482d1f2a6c9c4530ee51d24e2c6fab5b483b43522c0000000000000000000000000000000018ea43458a75a40c39e041bdeeff36a9871c79fe2f23fc9760c5c30724f6eabbf133d34f817f6305160af9175ba87e0000000000000000000000000000000000038766b05933250a640535b161e7a2331f02eb43eee1423fa8e0e6e0aed58075547e5c6b4168466c700be9c9df22d6d2000000000000000000000000000000001614624332ee3ef2568abcfa71169db6dad3b6d0d04e1dce911b1d6de41922ff688d41e8ac3f78c991483d2b527b43421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004101196603ebd4ccf814d17c48a7536067a5df6cd845289ed861a95732b3ea7cfc6c429dfe1e6ea60095bf61e8f699600000000000000000000000000000000045fddffefd82b8023c0166b571b39ea192dd2ce113685a744d22d61383565cf1117ab311a507889b79e8e8fd8e25e480000000000000000000000000000000001db1ba2a8c43da35268eb174d3d9ab3532f3a37594161fdf2e7daf42431d5aea1dbca463bcd35b82a13fdb4b06be7e30000000000000000000000000000000014c45103a5dcd1696a2df687d235bfc17e35a907c3a28c789da44c02453dd690879709c9b9e4b7046c446e9dc4560fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eab0e4f82c02f0c8ed3dc09ff105cdf8995f512bd321619c6850e35af1b2f0d0d68765f69b1f797f371d051610a189700000000000000000000000000000000057ca23796e4821fe58a5422c546f16c7c6e30c638d0de046d90f2e36e3ca6fa3bf77d5e3b420b5b73b7e9feb0b30c5e000000000000000000000000000000001948178580392a71683b2853416e187c48603033cdd3c8f0f525d3583efca121616b018e1b582b87cb8490a36c9121d00000000000000000000000000000000018dd06b4ebebfb3e97b07ca4eebdad9864021748ce3eaf95222e379f52dd6ab747f398455e306dcd0bdd41f26dfd03031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de9acbfd8f3516f5ba689950f40c97da6797387e8bfa16a97f0d549980e8786d3543f42ce3ecc54aaa4ce63f2a0a7ca000000000000000000000000000000001788fa49c930163850f2350b64fd1a42c217bb27cdf3be7f8d524698c8c18e20c9488c218afa8cf01de88b908315c10200000000000000000000000000000000093b672f370f43a47054c01d361e894e609922d2b6651c57ba7058c85a98a3b420833c265224454e625ee78c33f6c413000000000000000000000000000000000f9cda8b9316cc24542aaa54d2d0419cbf1353e14d49515192ebd77c3d7c20828a3453cc94ddba792d4579450b0eebc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c355bbdff9ed673c80e79d64502109c1512648d71df0f01295e0611d705e405333967ee20856bf982b9463e625b0f10000000000000000000000000000000001535314b0dd4c3b3a597e552907af0f3976fcd65ddcdff390f71f46a8b9dfdedae6c84d8bb12ee83e22d31423f46c960000000000000000000000000000000016f7a039ee125b9a817abe9ec3efbdf46eacd1d1ec08def6ac458fe75644cd24945e74f2d85d3ec6221b5137a36f84350000000000000000000000000000000017e4911a30c85b4f0e993d9f94592cb5c560b0b2ac07283ea98ee3dd6b0318f965ffb1ddfc63abbe0e20c742bc2373731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014367eb296182917dcb756c6b987828798b308cf337d62941ecc1723b85572590175561a7c8f9d8af94273ff99ddba060000000000000000000000000000000009dec83d228d922215a70c50863993a02e99477b1bb0ad898d234af5a9f6b01d888acddeeec2002942b9939122961d7d0000000000000000000000000000000002f633bc90b897c01dfb41bf97652bcff9ee0a1ac57cc5b2d0ca2cbb806dc7eccd29ffc65a675980aad07c8682b3b775000000000000000000000000000000001205cdd1e8f1e74196f0570b078d9c8acfe49f842e0ebc9f8e6e41fab68c26e12aa8ba216d53fee71fa5dc61fac857b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001623a0433b16555d5bc9a004f8c63d5a09d93a78b05ea0264163e8e71de36c66f5900e33506039d99c62ffd051f0dcc70000000000000000000000000000000017963710245fb9e5e8181c66669d4e3f014bb4a637059b26d9a75019f96153dac17b0c663b1d65a4fee6c30e1b80a909000000000000000000000000000000000e21598e5d0c708ec6ec9856fa9afdc6a1dd0133dc9ca1233f739cb1cdba82d5b592e066773c295028279cdfb4dd6d440000000000000000000000000000000004c418427684be1ddcc1ece492b7cf8819c0d3a3ce9d8af1598e0e4b90a24aea3a840b1e7d83de581d15af61a37937b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151637fc0e6878455bb3412da853ab64b0bdd5ce4d247a4b4832c4f4f6c9711ada3f768a27657acb2ec20bac48b278860000000000000000000000000000000015ec9843feb757e81394b8cfdfe6a75f7750fa20b2f307ecba703844ca942cfe789377dcf121e50165264c9e2c72504400000000000000000000000000000000022eccbb8538d28a2b8a624e4326dfc389584d8cd5c3045168b8e5b92fdd5f54a2aba937e25ad51efaeac582465e2c550000000000000000000000000000000010db36d0c7131e033e7583d5fd10b4a87f46385c6422f731303687581cba08accef0d8a5c5d8474f8bb32ea79ec45aee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001977a828aa8ae4737760e4b64e927e75742569825a08d78020eb2ffc85cd189411db95dd838c0cec4850d885b36f6b62000000000000000000000000000000000f7ae64558472c653e9ec0eae5a54078c9d2d3c6569f271cf85ffded2b3366abfcff5add8788948e53c2a4d6d2a2f45000000000000000000000000000000000000efb4fe6e3f12150c2f4478f58c572694f92d8c848c1f3d91b248422228bb9e2311fd1b2d3258c0105d5ba01fdf13c0000000000000000000000000000000019cee947468f86c679255f5f27b5dd69749f4b91b370cc15a159c85b8a469dbe52c8c6d13c0db317db617dc069f351cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198affafb3831c650fe14f2c87e375608e44452ad1117b766807c1de93421a969af08aadfd194c6c51534fa5b394ba6700000000000000000000000000000000125ac71b75ee42bd44a3d45d58c1c4a36fee4b98e5d2049ec6373b5a26a76b28c2dbe48626882493ce4c67ee39121fb1000000000000000000000000000000000cd0ee18860807d8e8e6584f64f53633f691343d9726b4b7f995c25c49d2caf276e2b999c2856d9370454f63cefa2d88000000000000000000000000000000000b0316d713a7f948687843a4a034f11dddea2dcfd5529eb88bf94c0c94608b444b126e25007835080c27ac9ec3c9abe91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ebc7e5f0f9074bb38f8588f189c5bf8485dcb8c8bc8857ed467c7c49e2b9e850b852dbe04ad0c5521c3a09dcb29113000000000000000000000000000000000943acb721210decd22eca5e020ab9300d503b5c36f50d689b9b73c8f31f88ed415bf4e4f1644a643aad52d8a930e0f30000000000000000000000000000000000f15253c7895b4c261987586c69ce860c11052acf3f63fc02d29eb9342ebd84e1508fbbdeb420a9d731a58488d0684b0000000000000000000000000000000013b7ca2d77a1c38d7108c179770298ec3fb978129b4aa9a93f4edd5c614f38dce233f72b20dec0ee3669cc36570dd4651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ecbc2314630e9bc001b99efa8b29eb494f2ad3072ef750b6b3a7db18705965ea40ecbcf4590830cfc522aee67fc4f60000000000000000000000000000000006cff352d6ee367eca73b0447e5a5a895dc9ede9ffc2afe6c109514bbcd90fd4ad767917a018e0682952cafbe72794840000000000000000000000000000000016752aaca020a534d2032065db44e6a2b01e13a53816fe332b7fdd2a85f77481fb052d29829519967d4c1d965480458e000000000000000000000000000000001884dd42206f54aabb2bf8f47d1f926b5ba2415434dec1799ae94c0d336c8be0055d83af25fda1dae00079826a39d9c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033cbe5e6f424886dd87787a5b7a7e02a57f2e05c38dccb1f688b44513882601610f43f457c680d646d0f7f95238bcc600000000000000000000000000000000033ba3f62d8108c6e8b7a8c7204b7801f703a8cadaef024b78ce3b4bcad766211d2508d8e4bdbbc7867bf48b533ca8c9000000000000000000000000000000000967b1c01b12d9674dede0ea2f0c046397d0df2e0d992c87a912e441ff165b516256854b059f464fc80bd9d26cee0cc900000000000000000000000000000000078157ac9967d21c88b0ee816f006b3ebb54e8c7e975fce8f1f09a5ffb5e65b78167f1c599479bf31793ddbff6a7b4341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017376f10006af96071a4b3f472a226edd81a2472deffb5cbd27862e726f3ef3b79387eb1615bcc647d7e6c35e60c39d50000000000000000000000000000000005c13ad000e2ca030dd0acd6edca973e6835f5882fb50ca4e117830005419ee42502dd83c8ea3a08779128442218665800000000000000000000000000000000078242c3b98ea9a6b4efad294381aaff208f7170419005fa6c90791cbc371801e993081b5273d5d7a5824e3a48fd0d4c0000000000000000000000000000000008165587b2f3d6c729a84d225f66fd5d19a751889d686509ac397afda27b8a1e97dfd89eac60d649f8724e17370fd89f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b93119ccd3d7ec4438405ee44c98a26e7dd98049cd42fdb0b3f33dd27002471f966e6c64f75d6c2472556692c9f2d9b000000000000000000000000000000001801a069866f02555d4a5cc624dc2ddb8a496a2c5cfcd97c1cdb6a3f412e39f81437855c1cdaba353ad71a0dc5b8529f000000000000000000000000000000000ea85af9d5e266be36cbb8536025ad2cb852d065e5009a02e15b59f24b8418654b47661c591548f16056801235f380050000000000000000000000000000000000aaca07b3991ee68c91354052523e8e005bbf97ab9a5a0d4962b7310590347a2aa2f8ae66b04f64fa637af2085009971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000851040dc774acc6429188ccf5ff419e737383ce231c8afd990a061a1f4f25052acb287f31fc204e11c8ecb43b197149000000000000000000000000000000000cd1d0a5198f5763f1f75aef19633f8cc145cad79dea6a738a517554fab881663c31b61673f7e0481c15a082fb534b13000000000000000000000000000000000cd876970e1bb865f9991bdfcbbba9429768ebbdd27a693fd8da8b04d17ceb822bbae9b6121a69f59ff0d0c262a659ea000000000000000000000000000000000d432cfbfd8a3f3879c6277b50079d137c9b1e93a2207a21d2d6cc682cba9e9477886e24dc23e666feb2523d0b4530161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018f46989c80f9e161fb24141626a204502036e8f30f5d0f72c0167da9e52d28cb1fe99fbce5a7c8cbcca2c17d53293d0000000000000000000000000000000019641ff726ca947e96e7c607d0bfa8698910542ff9bee8926ab7e2f1b9561dca31a081bb84b699738c905d13f31c53d7000000000000000000000000000000000955c3ec513110766d11c00f5de5bd597b7d8c4968fd30e46600e92fa8117581ebf36f1b8040a22450581239b6d3b22a0000000000000000000000000000000009073fabdf52938925adaed1ab13185126bdf44b2e37f1487a59071ecfc1a3a38e4f6fdc654ec91c46cee2682db373e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5dc7fe04a3da23c66e9d27e602159907dd0bb7b2c9aa9f0a4c3fda1dce9ac96403b40b5f316d70bb8e2a94f54ddc9b00000000000000000000000000000000124eb710ea6ec67fbb1014302c6f01a63dcf53e66d48cdc9be5367777ecdd53d0ffc661dca8f3b40200d9fd0a289f38700000000000000000000000000000000178a403e49fac1a8dbf292f32ad0d05fc3f1308842e9ab0a861605f13260ed805c160b7df91b4aa2623c80f4fc7a1a87000000000000000000000000000000000bc2ef3dcbac9ebca3281f134394646aec6179923bddcd1a6c59959ded0fd3b694176b81b9f8b87aadd2f2cfe6a8031b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fb6a868a0302748e50445e7f01c08e4c635032c10e5313478489b01e18dc88b76415a9ee0fa617d29b200e35e5759d3000000000000000000000000000000000b30fc82e01dfee16c891f96980bf74613d93f7c3271efd99e9c7f120c08d7042bdde202fa63cd8423dc2c83eced25190000000000000000000000000000000013bb082127cc5ed19d50a8daaf95ee590e6b797afe6bf5e5a783d3c98351618c40504466d8a8f7bf7684b92b7b42be200000000000000000000000000000000008f2b843fed1baf1f0bde17036e6a03929e4a6f3a200ecb7d8133e4f06216ead55a074d8c913a9cc8f5be08333bdf5b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab7bef886bc431677c5e31a8cb79d6b975df74a27f62722ff2ac715492a01eceb7c5261169518e3b42c33a6639a94700000000000000000000000000000000144cb81fa9051d520aadc390b183ae653677033b536792be194a161b088e0edaa1025d79b6cc038c253e90c8940cff430000000000000000000000000000000002fb9d2762b88be54ff0f1b5745bd121f3d46f5dc4452263ae881475a93f12f3360f2348010c75ad0e0ffc360acedce7000000000000000000000000000000000452a8ec8f7f8a99324fa831cc7ddd62dbdd899a60ddc60d066020159186f9a16a293e670bfdf2e9699a3825c78dedf81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d430638323adb96658df5c8eef5144616723bcecd595d904af14d5393e0bfccddd7a64bc8112918f5698426e3cb8e9000000000000000000000000000000000e73bc0cc8033d4ab206ebcaa815f3e8742cddfde5606738cb0045174a684cef5a195e12a3053b35f6c560315a2748e10000000000000000000000000000000005ffe4f98a97b8a32e6b85ee45b9e94bb53c7b5785c42beb3a902a0b0bcacfb2327fe54e38419e83da616487928cd5aa0000000000000000000000000000000018ec1d773274d2ed0d3101e6e64df2bc373e9edcd02d5dd267bc39f7094e7ab5b7fcad85b5392cdc41616017eadd8e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085a30f8bcff54fc6f022049e57453215719371d9d12116efcb3fbefbf3848d11ddd66c5855e77db578712d64994fb30000000000000000000000000000000000219a5512287c37ee7865e1f6a5ea2c6d9d24cae15f3f6bb4eb9e9d31bbc23f7a22f43738b686cc66f0762ce975461a60000000000000000000000000000000004602db3bf19b1c8c3491f3f13e171760dbaa2b27b2f999f8cb0d9da6dd3de4a61de6eaa02976dcdc7970498fcba56e0000000000000000000000000000000000de25216f1ec24a522d8581e76714459eb00f09167cdc9e29ae5391fae174ea7cdb4ef3d77ecaf253025d4dc3a02d4d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123009a43a0e3b3344604072fc6388b7cd9f551fb099042d5993fa18a479c7604653dcdd797b2a99b6c5b3fe833225a10000000000000000000000000000000013fffdcbe27be0fe1abed71f6c84695297b1e291cdb9ccecc7f366089bfb0d55c19c195eecb851ede8aaaf39b877f19800000000000000000000000000000000096d505aef28676375c5a5ad3293b6b97ce14dee8007013236dd46c9e0a06ce233936ca8039ab8eae72b749981c36ade00000000000000000000000000000000070e653ac0b803173cb7c853051edff065d8220623deb0adb1f5e06f0c5e17f80a3d45ac2967ef7cde0d9823c2cbd6b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e82dea70048e69cab078fc84834333d66734378650e8a1c90dc937b96f3ddcad0ac0a3eec46d5f52d39e31ddaf92ed00000000000000000000000000000000147c359e258a21832c6f448ec55181d1e5be3901dd3285ac509b2412089b1205295a37092755afe5ca1e9ed007cc064800000000000000000000000000000000155ca4c17a0bc1185492bd07749fccd379cccbefa83a1ab39aa688979dcf5546131d6e85444e0e016491b98eb9c26294000000000000000000000000000000000f92027a6c93ce54bfafe5c2e0312dec1adc14ca81415c6381457ec060efbddef5443c09af2a0f4e20a55b2747ceb4b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000add85a0ce098de0eb4ded550a51c56c2012a7a1998a61fb1c81d5f10182af726fdef1d4f5fd115441efb165e351fb8000000000000000000000000000000000db192936f4bab12411a2fecdaf1ae59917c7c89a3e86cae197d673137223e223869661055dbaec359939297a9cd300c0000000000000000000000000000000008642a35845ed8971b5de3fbab667c8f711c7619af107f0e3ef0a70c9d7e2cb802a4a2d5028bfb5d3b6eef5d6457506f00000000000000000000000000000000128003aeccfb8a57d70c8fe3c5a182dd8b6e6a14860073f75848a844c0c6dd3d8005f3a040c05b74b6be14c59d4775c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090c48f656bd1f6196a7d2d3e64efcfffbbe5b6b7c6ca3e696416284c1aa8fb0cc63be6f4b963008dba83fcc61bdeb42000000000000000000000000000000000c1946b6a22772a27175332c503aa0d9cab20a794962a5110c6b8428da6b1ab65688c49b34de1a5a38013dfd86cb447d000000000000000000000000000000000f77aef75261f71eb7ec6bf5a8180b1c877bcbc8b999fcb7c75327756a28c19079c652d09cf82c77340296c8dc03142d0000000000000000000000000000000011d14bf0de1bd33abdcffa34a2d3f0d3f0e4011d9e3a147b937b0f4ca4bc2acfe1c440933b5dfbed8dd08f4969bc34631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000029b8bedddfac00eedc59ece1be9fcb8909c69f3e9b41b75658c7aab829a80c42aa6a43e78d0e819bc2805b12c08b1d8000000000000000000000000000000000b61d7edc11a58bfdf0c270595979d8dd522412eccfc63c247a98bc8d9c7539ab45fd46e41d50cdd35ca6d835e4071db000000000000000000000000000000000d629048427119a0a320ebd42f0c7eab263b1e344b41ac8ce01c7417a6846019a23267b02d70720da0b07183597e0a690000000000000000000000000000000006eb8c206929fb08b0be2760974ac71e31f2493af0c05595e4ab6487650a0447bb00fb437af29beb9c0529a18c901e501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105584388cd1aae21d6e541527de075dd6fbedaddd63071c0c244b0bc26ec8e58f1f65041ffbceb0cd5f094ce409105b000000000000000000000000000000000bafefc99e5a7a61cd3921bae2a47af5abc231ddc65027451ad800e3a57a3a2cda972c2a93f517222fe8cca56036960f00000000000000000000000000000000174187d745e3714e1c65a666a39df1c783eee92dba03fb0c9abd0df2a19a6a246ecbfc3b3787775a32ef36fd3bf7d22f00000000000000000000000000000000168bafb285d57b82bda2883d2eb7f8af2941ca337ca05474226c2c33f451f00a2932abe2824747673ef6f90c8b3a1be91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145f65a72fe59d45099900953dc949731278a0a01189d29a44bbbd59a3c65fe16e7e430cd6663ea2a31a29001b04b6a6000000000000000000000000000000000409c5e09e71d5ab19776e27d7077c7a004df2ee215502907730ee93d812e5829a791e39bbfb4c7532c4e775552ea3a8000000000000000000000000000000000645040cbe1ab018ccd42becd0d6136a30b5bd06a1847e07484091d06d031e93d410fbd8ad3a09594a42908ce487bd720000000000000000000000000000000003589d8389f2e3b8487d38c77cb3ad89bf8183ae51ee612e64a1685c52fec1434166bc8054d2bc5d8b796cf8999f7aa61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105042e46e6d772f7bf84ccdac8e78a913af633e84d9a68a5ce17900c81cc15f29728acafe208cd9a5314f55ff9af315000000000000000000000000000000000230ff3ae2c883676821b6f2b495c9b510a0d33f4fd6e7144ecef2ba4567091c0de942554692e2898af380c21fa2740800000000000000000000000000000000163b964f735ff1a904613177e494e2c1455e2ba2fabeaf7ca8327ef26770a9855587cc08e2d883104babe65ae244584e0000000000000000000000000000000001f9790483298ad8208f86307ceba8edad75c002bedb5d17520993facdcace6ab8b628d48033782889cad91fccab2cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000109169e02a4de15fde8ac561dac1c5b20270f7e5efbfe2ccd01cf89a12b466e6ed5a4c3e3dbdba3f8a239f844ae8b37100000000000000000000000000000000142bad8573fb25cd4546ee6491941f732f9173c5ab8cee1646a15eee54785629b9c77b14d77c511522f47820735b7340000000000000000000000000000000000f44cc1a8e05be65e79c326d57210f22093ad14f8cf8a829f41b18cc3429773db8dfdac8589b020e1dfec5a2044cffe60000000000000000000000000000000009c82a449a746fafbd3da8c11527c7de14a65d21179323aecbff344f343b106b69bb566bc38e9115244959d99464ea751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005c7e8ab8044d4d32f086b5a028afa5fff9f4e90a8d6cc5016a179f2a35229a6bbad2f3404092447d4c0779d2216fa700000000000000000000000000000000002b5f26901362b209ddfc3bfae8532ec0079f702e3ee6036d83659fbbd6b326bad7dfda1f4fd5efa38372dc3f7399710000000000000000000000000000000001dfd3ec528b8c1e6b875ee6498a1dc7cdbe81fc0acb739a7af033b992d8d1af5c3dfa4138953004dcc876c62e34cc320000000000000000000000000000000005243fc4f50f736dbfbb774c1d5017899d381a77db3708ec10bcd83c629bd447f7037dc2af119b4897db28d6523066111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa48986ccd24a3bb0f06890d2048c34e411cccbbc46368321e56ce2e5b5278cf1c40fc1d6fb6d7b1bbc03f0317faab100000000000000000000000000000000176889454bfe883b43f13bf76c297f45a28a480c84f2b1cf28b34136cf848dfce900800232907b7826583403e82162360000000000000000000000000000000010e2469f64c7d0e8cad10ffc275a0a34166f1a1c8cec08663fe8be79d134271ef9575dac4dc7173f4b7842d405206d910000000000000000000000000000000013e3d0599a97ee929f5eaaa32545517f243a0d68852d4c5cd971e51a7e3584af3c3f8b96178970318d9f1cb4e0acbd9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001a000c96bbf648b42dd699ad7d4d69aff4916dff43aca6b157475697e8998f30010c08dde8fa283756d111827ae4e9c10000000000000000000000000000000007cc985dd9746b0e7acbd0e154231a023e1d6c8be69d468f6775d98d39eb38d3a85ba688e464078002f4d416be47bc5c0000000000000000000000000000000001862e5eaaa9becd72101e827f69dfe3de747857f951d7e2cb2f2c36365bbe2fd16c7520732abe213bb4089b601643ed00000000000000000000000000000000172f379a49a6fc3a8fbb546c83a4ab5361b372b82239c47730c8b69199c5ecd78cc99d6a1190726882e8f130df6af1291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001081bdf9e4b488c9b8fd26aecdcd75693693291c9ee22e20ff2be9a590c4dd4594de5ab96afce3eacf425a3a65651a2700000000000000000000000000000000025a6dc3e32a537fb29f717f818a3abc48ea43f0213b81292cee0400020b494f4710a3ea1136769260e4e7f458ba8c53000000000000000000000000000000000b6d992714594214c4a787485432d95794937717fdc301b177b7b147b43fbf6683fe517859303c1400277d8739dcd38d0000000000000000000000000000000014e6e298319ba0c8baec5a1a822a5573fb8145766fbb4684ba28fdec64943c5a962249ea60b0f3d3dda74812511c39261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001430ad4101ca9ace7553a6ead4e79942fe6d845af8f9e754dbb061eb347d18699b78e54d9a12572d6887998ae17815af000000000000000000000000000000001658800d9decb68cebdc024162f5bb768913a359707852cc96d3d52fc51a232e69626b4f1ce59dde7e2223d6379797cf0000000000000000000000000000000004dc67c66e234fe6671962574f6abe3bfb882c43c539029dc7c1fcd030cf47488463ea8cb58a79954b610e796a596bba0000000000000000000000000000000008d07b04b5d0869f161d1c28a5821b18be7f6d466bfa5ad39d0f098bccd562ac1c258ea3f69ef669bae6a897d3ed98611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f45b8d66ebda8efc12977b7751b5148eeee6742e0570bd1bb4ca772dec9eb1e8a59d50a8c1d8f8b22d062251121cab00000000000000000000000000000000102310fd67a768276f77edfa1616b637a7d4ef4459432b5fdcb0e16a2c8cdf6d8a555f826e4b17769026d7697e73ed4c000000000000000000000000000000000596e7e092fb81548f327349e2a57f76e115ba228035d74cd5841b5ad416f70c3d15e13c6ebdb61a751cff0a9c8944a2000000000000000000000000000000000fb8d9e3c8983a79399db179b7026cd4ef57b7be17c206b841ba1fb2296c8ce59b10fc78e01075668142cc0cd5c13a1d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148c755c34f146bf8333b7dbcd39a315ae441a5f361149aad25d0a655efedfc3d493563a08f389999cde5f24ec30f401000000000000000000000000000000000ff0e24e95f26f28e27e2c01abbec9c5f0e76d327cc0afb3a818651e5664d51d69328c604397cf52547a7d6f101f0122000000000000000000000000000000000615bec32a13443f559ab2741b214c9110d45334178c5d05ddfbc769b81fdd259b56071e46940be99f0865533c153e9f0000000000000000000000000000000010c1fa0ff538b11ca3a4edc058dd0d792d875dc40286eab78118c6f038b6afefd69e0e2fa9eb2f7feb06bf379862f73d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000046bcdb532cc7b8cbab9f1dffb6a638b87605d4720f1077389fb5905dde94a29a180ab4435d80d044594c4290ffd4242000000000000000000000000000000000c5c7fcaa3956c2de88288bb7edbfd44a79bb275a449e2ca6c81f26b1482523bf4fc0209ab1969d4f602f2fe189d3fad00000000000000000000000000000000183596269a830feb8a7f7a7260a642fa2a85727b7d852f90cea8e00e42d386f316004fd7f66944336e7658c8cd7d98b500000000000000000000000000000000007c885a86c7134888a7fb4626dd541059e2260ac20d24088e48b1a1997ea5a126b18fc2834795a173df453c40c6c6fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a38aaad5302e51e3b27be1eaafb13784cf8845401defa2ed27ea258f736fc569cc73e883a221712eb6cd64bbce4da2f0000000000000000000000000000000014f30c9f023fbd7c3a03c3b181d5f735c1313f618064ff941cdedb8371eaa728da8629482c76bb0a8eb411a15393211f00000000000000000000000000000000197a1fe4138aa14b24e598d9c9a4803298ac8acc83612c49aae28ea4eacd980a9f296e34d688302b449d49d2068e42a2000000000000000000000000000000000f3c079216373162bffe8b6c0eff1c620522132f5ba5d474c6d8da65a80797a4322b0a1f4efd80f32300f958a9f2078c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000019e29eeea6c85f41d82170b5a75b1f29fd7fe644df25ea8059a59eeaef6c2a2b38acd6938bcda7971b9753a51a4ae5800000000000000000000000000000000141b54a97c05727802988800cab93e73a3c07acea689e59f1c78e9595373a18d0ec2ea25153bee79bfe4c85958251895000000000000000000000000000000000d800d19c38dbe4f331ef7943b364f6af74e8ee0fbe9096e6fdeafb1f44d869ea843d12c90513026d00d326d66c631130000000000000000000000000000000016db97696bbf0e7398ac0e5444b3d0b3560e417d98aee6247a7125f8d264c1221f1931c7cbaf203792059ffcbe20e5ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e3ce33f11b07dc24a81884fecfd81fc720fc64208a72c79789d8d8f7e85cf239c9d01ca0171bc86a5a6655352a84550000000000000000000000000000000010fa5752db91a6812c9d5e1516e96960eea13d87de2a2a2deb85406fa0c61674758e20d7f5e853fdc2f6042d6555db10000000000000000000000000000000001971834c587a1db1fdf56ee8a359936539393873b886b7d13e55f50211677662e10d073a085e3c92f7091c6d6a007ad6000000000000000000000000000000001848d32240b36992a04236fec35b28ce57d05da145bbc5286638e2c94c9b3ffa21b0fc2c4a1c7deccaf0e2356808746e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180e90e534c01cf113e326051fd249741419269676495603accc7d774745f76798ae8b038313013143d04bb91d93bc9c0000000000000000000000000000000016b7f4897c1c6a52d57927d6aef5ef20d71bf14ba05509ed91611fd47a945d688e7bc07e181562d6c771dcdf62f58a3e000000000000000000000000000000000b189795e59ffcbf38766b70fdbc008b66e4123367f671b2c281ab3b0daad4f3395f8fada834a4837fdfab87a3c84c030000000000000000000000000000000004b903721cce4e2608ad9b4c76104f78992be9b51814a45cc67ecf26182922f100f79366d1f138a990c36cb24c73736d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053b2b2fcbe1e1f21c8975a50490944a2ec002eae2a3787fe1a5f2407e748eeaccb71ec9253ae5baab99bba68244320c000000000000000000000000000000000324e2be2500d713e3d7024e17bf7264b32d4682b9a2260908e136524b21898d13bbbdebe9c0b114b60d3865dcd3e3b50000000000000000000000000000000011555094fe075c812a9bdb67cce6e5276bdd9aa2cd47e08eda8caf27c64fbac993e783a67d4215829361a3d9bc08aeed000000000000000000000000000000000da6bb32156d43fda1e03c4f570507d96a5cfcabd1d06f2ef3e044b338d9fc647b6940d714ec6b6f5bd53cb9813a358f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000152f5e3a4c553685322ca904c7240655c2478d16e1b6d6f0303f1afab9612bb120f52d4cb7730f9a213b6f8c9f70c7e0000000000000000000000000000000005acee9da915ef5d8281ef1713d841a89be846c6a607be3209b49200076f65620c7adc6aa87dba17893261984726bc330000000000000000000000000000000008c4dc3c0fa77bfe29c060d1daa759750de6cc9aff97ebe81c8ffd10be465e7e57b39f1a545ba2f896166d99d38978bc000000000000000000000000000000000a980e08cec0f3a8bef83b9d46095a4081004ace5b70d28cc9cd478c91c50c55cc0220387ec906d28cab94edc821363e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017aa0a980b24c369c3ed66332ee85ead185c25034bb37c58e922e88c64773a431aa3356e8ec7f13960a187c7fdaf4f5c0000000000000000000000000000000013b303817316f19776a4f65b2f6150c484ed5583e0903826fdcdb1ec9dce7da1152462571047eb72b47f483d0632bf6500000000000000000000000000000000174ff23320c45150a950deacf5594b71bfc471b1a9ab2d67763402981110150c2f493e9aea5be1df0f951bf31869f172000000000000000000000000000000000a888193e3158791133bfefe0cb68384a69d180335f9af7d0d7143b072c4bbcbe48e97e5d6658501528df20ff83cc57a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d000c0eb1c1c952486478e2b81126b7b26cfb363451577dbabd7e47f7f834f04c47f90c74dbca9981f97105344db3fb000000000000000000000000000000000357a4e86818a660887d1a8ccb026bd45af74e1261fa4f8666d3d7ce1bcac676b213809d8b1be7619fd5cc54167703750000000000000000000000000000000003e78b2f2495ee9ab2a58f7f699aa7dfa11625ea57e3b8b89bf6e8474fd1b148aeca27e2bdf3aa77eb1803ac8469f1a9000000000000000000000000000000000da0111d3255fcdc941c72d1f099a8412982436be5414301c421fad34cf9fd8d55c79753619e229af030471d912cd1391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ef489090ce97b1f2e868153ffdf92bf8bfc451b14162bdf902ee74afc7ab25764fbca0709aaae47d74cd67e1d1be4b0000000000000000000000000000000003f4c7c3215125bfd2e01f214c32f2cd64331d0f6c0b46910455085162f9e1e1bc66c1d6e3bcd76e549ffe011fc85450000000000000000000000000000000000669ee967d4003f1691044306501b978aca86121c68cea892a924bb97bfc47fdb009047d43863fdeec4ab658c8024bc10000000000000000000000000000000012c0a7cfa7b1ee48bcc268dc596cc4be3c2c71083b24ebd2c3f29a5cb107fd5032a30a56f245238b01953d7c6793b9921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f807cdb1c92baa906a37d23688c0ac08754ff42915eb1fb1454efcac3180e2d57f769fed53ecc31c4865f831428e55d0000000000000000000000000000000008857250dde17e3a4147401995094a9d2a24590f6933aad466415f99c8d61e96ba464e39a6125dd27e92c0d615c77c350000000000000000000000000000000015a47094a686dc357e11cae38b9faeb3d1fed87795202df0080637f965aa871f407192615d519ca464ce0b37267c25200000000000000000000000000000000003a29b4a8a846e17ff0cb1df24e74f7513ad04bc9c6f84c0edd0eddd55ef86649ca331367aade80f6276e3b9593c23651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001585c9a3e0c3a1b302a8e09748a920602163e80a26a57ff15c3460518a348d2f5094ce317904945bb24b875e63ae5b1d000000000000000000000000000000000647dbb0060242d09ecbae5e1b9107bf1884de18641e3c70a4dec87fba584655f282497f5084ac3205a6a236d626d85f000000000000000000000000000000000b7c15137c7e6e9e0a6141f184e8343a75d578cc6408d476d0f7697bd0b054d52344fc30c3592c74f02bb378dcdf58be000000000000000000000000000000000120056c5750ea8c09d04fd86ff12650c95a5f5e35fd76ad46e12d78cbb90c3a2fe65f771e6f4363139577b72401daa51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136fae3065a9a2b332b9ba939d3c861adb4ac28f2cfc9a6774805abaf0f70f2ba8bf74d9423762bea089c0b53f64fe87000000000000000000000000000000001331b5b2817da4c8d91ad601149be8a7a5dadbf91d3c364e71ccb6f33a0bd6206bb53f1ad8b7b8778612efacae6751d00000000000000000000000000000000016f9dbabb5810c09e6b66f4fcf40200c7c59919bb96ee4b5ef5de2e85c3314ce189c5ff67285ce4b2b9cd454abf05a8b000000000000000000000000000000000d029d622e6abff6e6b649da12699f3a66de04a3db4445bf83297fa98372c4dc6ed3854a4b80c3bf89e6edde8a024e3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050a610075da9409c58677b537b3f7fe35937c567fc8ccfdec23097400e2524188dd29a04e651057de01a4f9805084a00000000000000000000000000000000071a18a44b5725b9a67b1fefa7f1a5bbb68efc4a140ad732ff22f2988b0bb5492328beed88a61b25d3a8659186fa1cee0000000000000000000000000000000001f1da005f03b5e93097fe264e84ee6f9e78626ff9e7e9fb87ef0929e92d866fa92ee41f32f87308abd1c289cf67a2170000000000000000000000000000000003ba117ac29758582a66279d8d36e7ed06c830220eeeff06a6353d7d863805e53562c9aa0ae78a16cb37c54ed92b00661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc7d4095871586f1232fc3a1ba9d17639d08a4e0994b748122c0789c6e8ce9750ac50a3573ade3fae607671bbab6fcf00000000000000000000000000000000167346d1b6bbb3c8f969f4e57f4414e4bf22b583b228290cb0e48cc29b1894f6f07081b1d33dbcf0c9583720a5137f7600000000000000000000000000000000104a7e4713995de51dd913cbf88afcb00b6c120fdd9bf76af55423b682e51239855b4b3094147ab925f716f52af26ef5000000000000000000000000000000000e8264d23311028798624c0ac5a4195cf16d220682fd07e603bfe40a22e7ba68b6e7e74fc73785fd78f57129917d6edd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184817d1ee6df137aa76d8283c613f7a0b520414bd04f696517dfb543e493abe60f57203072eef76f8e444a261449b4100000000000000000000000000000000151e7f51922d0c0089c2a0b86e1906773b63eb385b8930be938061716cca9eb011dbd78e333e0acc3ce96bf400b1a21e0000000000000000000000000000000001ba1f2610d99c896ef6888748ac80e6f154d50dd4d719a48b58403549eab6834d1c719fc79664d3afc490a585750d80000000000000000000000000000000000faf8a7543818cdaa68478b81be8dca24c92b60023c38638483dd2e3c8f5ed5de8f41503570ece693b2a39fd274ec5411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048995f6d9dd8a63c0e0c77509a56e0f1a8b4fc4544f82b59eecb4e682eb09866cae72c33b822c817e83253b1400e51e0000000000000000000000000000000010fb277cda05480c9f366a020c6a86691c0c2d4b25c4383a615a43dfc3c8029d3dcb34042732de5c359107d003c5173000000000000000000000000000000000104d8087aa849ce076ba721ce7b0dd74643311fff2dc9738da9788c8d5576a0a42796992555c4c219498dfb0085e09dd00000000000000000000000000000000187dc6e5b87bae5210ebbcd365fdc9a6dcd2e8cd0f8592f652cfeb88b037abf9359e231e4df32890c82d41babdfa84641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f103c0fce55208d3aa190db050a6bce9086245289306987304bc0cd8113b22788ba712de1ea9b07458eaec574bb67700000000000000000000000000000000092fc2bb031006cfcd801faea952757f7859fc111ca3e9da8be67f3c553836fe0955001b45d8b9478e8ca3d91b08119c000000000000000000000000000000000bb954c28fd36b42e85f951c9e0d1e1aacf96ac35e7e28c6f3c47bfdcb447d2df853955cc13761870a57bbddcf1924770000000000000000000000000000000001cb60101f1aa721e6252154448e541d5270c4758245eb8935bc45f3b5938a002a2e02c6732e0eefc6e7c96fa3579fc71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dab3920c3f53ddd302e395c2ee9dcffdccdb2d5281f85d8bdea2d0ba2cde652b37a2dafa180f329123b9fa6b8e83ec800000000000000000000000000000000056677bcf92d552494a17cb6fac3acf41cf6d90bf1c4a74f62d0f54a85a5845e4400e691193d2cd98012aa15bbece41a000000000000000000000000000000000c9e26ccf504ab0fa912b66625331ad5bc8b34bb322843eeb6a3047cf8e964801623b0f771a96b13dca419a003ca6de6000000000000000000000000000000000318c2279316ee0829ea06e96638da096f8056574a500920e39a8cc0194c48e38a51f1c15ff46709a385edec4b1c7da31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d34656742cf47c0a3b70cb106f8591852c6f607d8e2aa3a1ce8954e35d8eca7a98bef8ae9baeb5a19febcdfc66f9050000000000000000000000000000000003aff8954fde8205cd299108c76a9294ec6cdef3b6992ab3895e36ad7bf598c9f98d293918b281e5b864bae3f33849dd00000000000000000000000000000000148a55f0bea0e7757ce521bead33b750f1defc04a750ccc10a69897cd358838e981a11494ba7b6dfec8120f263bb106e0000000000000000000000000000000006d167670a7c8e34b040615a1081d6d80a857bdeddda6bbdc5e5a889937c8b370d1df5d7bcf902984ef858aa5be0ebdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040ebb87878fe33475aa8de8bae409a4722eb545185632ce865c0dc9c458152b73362e3e4fae7153cf6f56fad0a397dc000000000000000000000000000000000333d99289b953538306f12bf97e4c7ba4b235648246be74c14efd491d6947d9cac4983e92bf2c3c64ef1bd467b5e6eb000000000000000000000000000000000542ff7cce89b479b80019b9f2c6d8a872ea679965a2c4c6df6d31ba4948dd2ae2e3c00361d1412de7b829fc7fb0b95000000000000000000000000000000000030193b79c84062c2fb840ee25a95ad4cbe3d35fa47d7c42350205a3cb3a183e018702710ce096db8a7cdf1940f803221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001d30669dd9d0a13782caabf8be76b8309e0611a05be32d233fcabf541c9e01ba340e6f205866796446d643b78c2921800000000000000000000000000000000090fc764825b02e16b463d59558fc80f7cd1345b26e989ec16e0027c366117e6fdde1c39a882a5e969b4a603e91b7c8200000000000000000000000000000000047f4d4356626f56c41c023ebf7b752c94bf27a3db272e22ae14dacbd3df6de973e2254a7eb8b4844361f17edac7679d000000000000000000000000000000000270e63b6b9fa5fbbd8780c9bbe4f33072244b56b3dbdabc0513ee9b4a0672a47f92221c09f50a63198294a57a001ba91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016d4723da07481e5bd1976e5434f793331f0c11823f8c9c27f735c64916bbeca0773692b0f88a0dc656071f9dbbe97040000000000000000000000000000000011bcf27234e13a9391c94c8b76cbef295b59fbf6f2a5ea094935d91387e617c885dc2c85701372c9f61edce0b413f1de00000000000000000000000000000000160816cddc7636d146a7c697625ef3826f9625e826073ce2c618392acdbafea02a2f0a1bb303771692c89c610fca096d000000000000000000000000000000000661d8ed7c6243baf08248cdf291ef9d135b84d10df07777c16d7ad109cc90ce92966e2642d6e5f6d365bafefe6cc76f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001078d7221fd4c1f603f43623b93d60484a71b86f2f515b2f6a31aff4fe20b7165f247ac5ef05dd4310d0f4262afd283000000000000000000000000000000000060ed7b37deb1bd552eed11f8180fdd7386a64b95640115414f205c27a0551a6c3522abd96209198c4b9e50e86b794220000000000000000000000000000000009f0734857c490439ddaa82cae4900dce340e3ead4dd807b41bb28bf1ba477b8b565f16a4cfd73fbf11137eee6458d58000000000000000000000000000000000902a1639d0b1deb30068d01365ca1970ee0644c5e704dd06f7da0a1389c551a27d2795318c5c154a27832e6509199821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004449513367249d021033ca021b459199deaa36c4b1fb7aefb64d720fa66d63e541a5047dd5daa3076ab5fedc2a0cae00000000000000000000000000000000010fff398f66c7d4ae193db24e78fd94fe2bbad10fdc08b93ed024aacd5dab6e657cb3ba568a133e39339b4d765b6aab6000000000000000000000000000000000072ac009b4a4e82db458fe5e6906bb17e6607639f7bf42fd7c203fb03e420f2fd9ddf6d0439c07d5995540e655b8d5500000000000000000000000000000000103dcbaf1a19e5e2a775467c896a65ac61dd5d5183d293307f20a7ba520bc6ac3ace5f911b841fabccbd78d64c0a7e491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ae58b2720348bba4279c824294bb3ed99e54107e6a934198366b9fdd5107bf36f8f9fd396784bbd27238f03e3d04db000000000000000000000000000000000ad2b2a7d11d080fbb931713f1100431eb36172f69b1df4b94fadecb0fd596c40db03508b82a56a3a4932995b6ad5544000000000000000000000000000000000e7fc999e088e01bdbf02e18a38952118e6209145f9aa07a5f6dfb69642319caf721a090cbbf3e631d3befda49001955000000000000000000000000000000000737ec60913434b7f04d1c8570b08a6246dd0c9952dce266c9ab9e72031906a1d350255dfcf7d01aa844ddcfc9902b351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fe219574c6e54ee49d7ab1041bee1395f2738fa0e291ebc3d65f4fce01e84678df22ad370b312cc97095976c14f12c00000000000000000000000000000000025f86f9e7a43106518578d54889e1740f9b2e7bc2635b4ce31031111c9813b9f06f9667b741d03d71b7f935aa8155bc00000000000000000000000000000000152f5bef58a0b7412af239b3e071d1bf3ce0ec09a5cc6a5c3e1afc984c4a8745006002f6fe4d715ff9519b96d1fc32bc0000000000000000000000000000000012238463418c1546770df24a4177c1f3d65c022c6ed47d0592c6e52d089d538bb0aa271cc817f8a9914087cf4a6ce1831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015549c80dd9627118bf4126eb8c8aab23f955a5638461be030769fc05ee9ec33a400700aa6ad6f85fdd4d442423ee2a5000000000000000000000000000000000b1556d30944b820702de2932be12be563acfc162dcc571b355f21be351a0f0f86ca48bff36675fee1e76cb028b5d3fb000000000000000000000000000000000255c6ad5c87aaab7465d7540b5cd8e5d47799247d3bca7826736026edec1f4e88d8765098713dfb4567b1422c8c29d500000000000000000000000000000000194a8a6fbb2ed1a88771a134417d95429756f3c70070f5149acb6ef74bb347734d08de67536a1cda8203ada6622fcfc11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000902ab4576ed4288b7914b9df1aeb6d0ccc2f2cba035e036708d07966e30a782be1acf5d57174d3a418ffc4e40320a2b00000000000000000000000000000000055942db6a5bffea962e757eef91066c6722b53154d0ad6bf0b953e93800ba5a986868a0c5f43bc0ff18c25c37c74c9000000000000000000000000000000000038263fb5773d444b843c830da1c0f0fcdd7fb82208d3dc196fab5a2e4d91727da828317e2a386342a340195e20dff0700000000000000000000000000000000111224fe2410def534eeced92fd2fe1390e73134ad253d7c937cb3338bdbe633c5ff424eb2e82a1bfc85943d80fda0381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007fe3184b6487c9f2b6b5fbfbe50a41bf48a0e36de219f384b9742a9acf4b48879c633782af09c148eb00ba47fe50d75000000000000000000000000000000001935040092d83014a76c9568b829f043a9c7e6f43d9c70449852bf5b744266f2d91f36b3282f43653cee49264ccf01bc0000000000000000000000000000000014fd3040f59ab59bfe7f89defb8eb85e85ef7ef788e07b3adb088687a3c59c304e0cceb4934a684da74dad8d26ffb2c30000000000000000000000000000000018688fc83cc9c9aad55c3ae01bec4af3d90cde232dce82071ef67f84cd665588e4f7c55501b815a3079f068c2ef3d0181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dce5e200f59a7d24ca96431785cc8bc073e46e27265690e897b04a776fbae6e216612f7d23064189ddc36b1246a599000000000000000000000000000000000a32fb098eab0cef5d03628b726a94e14098c051a174761a3a96a30e9e3ed6d611584a675656caf16d53c772e5448ac20000000000000000000000000000000013293bee73df1b802148b4de537e20591fa3c662089deb9954b09fe0a823489b026713b2d63c7bab65d30c68ba266a3e0000000000000000000000000000000015276d35edc7a82ba6b98144b3d988f67cc345d10730e663014367858ea8b593448c37f69289ba8616fd3dadf946644d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000371c497146bf8226251db21b92ad5a6df623f4aef37587801417bf887ac8e80c612958dba15e7115a4a784914932c87000000000000000000000000000000001986cb3949ad5041c2ec2cc3994a6a97a35f3661f68aa68b554605e07a8d98e91602b7ff8cb315e9f628b7aca7eab869000000000000000000000000000000000d94930e790eefb208a414d210f5bdb2bca0ba8e4f97ee0ce10a6841230a940d65416d16d8c5a1e304b79bfdbf0c40510000000000000000000000000000000016aee9dc6497bb8a7db71280b9b55314ad046a82462ff55863de4bf12f52d3926687f4c1a151531c6df95cecda6de1bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54ed6c28b2e15bf939809d144535feddb97f2259a9c0ddd70c3de5410bce4370b341218cc98bc0dba1f68629394b940000000000000000000000000000000009638b9955486d9f6897b85e34b24a0c2b7a5f1f57f7e089256f89cfe4b546281b9361d53ef9cfa45315150a534c6b10000000000000000000000000000000000259807c0b89b846f08a8e62d4e26355aeaeb4f3bb1a97a216ed26e56d3eef6cccb642e7ce0e0879a07080b5eccb04ac000000000000000000000000000000000558c3aac0bdee118d50eb7ab69f67ba87598cdf14aa8ddbe29d04b14333d360ac630db5db4050aafa1f1d3f3a706a741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007aab1673b80eac52a903d3b080f4a2a92e88021f555ce5c1f463a0ae097df183174366bf961d6a61ef7dd67ae5aa5a10000000000000000000000000000000010d7d4af18b5a912891c66424f740995d041c1b7583bc77a8fe3443afc58bd5bf468b0a8e894f0a886c0f0a57d3f63cf000000000000000000000000000000000d0cae1a2d5e97f2f52fc46766c1615b41028efa15ffa4424abf5d8e7ac5121fa0d2a0c716a6c6ab6cd230e5c8f776e30000000000000000000000000000000006d943cf00dcf5808537fbaac9cac62a493f461cc78290a7d5a9d5666b7c13568efbee8d6567d9721db4d1d253f262f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009446f8d5e39970f6d22689492ca6a4be496260a993e8e5a5069edf6e761e6968901b72fd6e6634ef3282913d84856f30000000000000000000000000000000000a638d97f46497148987ff80bdc38767fc3bbf3511ee4652c4bca3aa2992f4677d9c4adee41e50f694602eb6ca5f9b10000000000000000000000000000000008119c87b12859a05cd6f72ed8b2d6f64bd9027b9cd33265b58b16ad21e2c3001a3d7cd063401925ed788ad816d4856e0000000000000000000000000000000013af16fe9e83c565ef2137b8b9ef50f3fc61c3ee17bf38bb980ef33019e08d09c04ebe26df56729925e16ebd9e43cbfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcceeed550e115a4aa0a115cdc4d6ae3a1869c0e5fb2c049889fe0e578aac3356b1e13055e6e2de7355a2ca5748c6b0000000000000000000000000000000017053c8228bef410fc0fefc06587f008c00735c3fe1c9d3976fb23f953b7de481ee94a23590744fb3969ba267ccce02700000000000000000000000000000000050ef4ddba5b4f035fb6fac68b5a50d824f699047e57e03d4aa70d34209bd85e39d9153505d0ec0d1fe80a7b3f1d2a0d0000000000000000000000000000000003a7e3636d3318c39ae88192af7c2330b81b9c061f6072168d27ad3f430f4a62b76dd7580580fa1844454dce1ab89abe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c023a194965dbd6d501d0b14e5b82431f72ca8e89e2ff5af6012628809df362e1fc2c6b5a3ef53a8899844f5c6afae8000000000000000000000000000000001331fe16b8c6f12c3aab4f60b1b3cfe233380a91cb3644e02d10bff29aed55f2e9360e35d499dcda40daf3d6d1d1057e000000000000000000000000000000001394c8e26c4914f0508d383c91fca90b34a1743b641e4be784a8a8062b578b9757b5a126af0195a4fb95ceb65ae6a2160000000000000000000000000000000008e0eb45af2b1b6287e4af8d99f7d9c8a4804009bd0a9514a4eeac8e0f0f22523e5ca3df80340be8f2e172d4713bc6181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167ba605ab88724e15581b02c4716519d9b08fe668107627ebf08f89c37206ab2cb197250af8117bb16d7d37afba08d200000000000000000000000000000000176f4689a652748952e6f0afd847228d8777b0393b84d7b0b3b864739bd9a9b5bbbd16f04e7c44b5c3df24cc3b9165f0000000000000000000000000000000000f19e05fa2a6c1f5e7d76d60cced73397693b92b2c4fbe10043212ff3db0aef54c55de65f589e11f25e82d08f831241a0000000000000000000000000000000000bb2ff9c4428875df45bb1f94f891b90f9fb4368fa5aec469ea4677a1bbdd3e3dfcaad5647130b31e625a4a2563809d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a8281dd9312c99f2f2e657a20170c37e312263c761a63927ea50455bb822e408068df608c9a779f841884bc3fd27d3000000000000000000000000000000000f6e79c687ce34e8ce32b49953a6673a26ecaae69d51b05350b61e800bfae2ea608aba08a7b132d752e07506a656186700000000000000000000000000000000063b606195d719cf5521b21696d0903c4a320868fc4dbe0c9dad8c58dbd778484a9fe01073208e65926b79cfe240cbb00000000000000000000000000000000017b1fee862b90bafb504bcb1d4f9a70a9360704b581c720f49f433142b7bec48b96db31e3b0f5786be4b3b134d754cbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016828dfd30eafe0397ededb8af873ec96e22bc778cba39ab082c4d55bf09790a4e4a845a87a9d6af74b068fe6f86b008000000000000000000000000000000000cf63ba474dbe1525d538fe6a9ffe9af81b1eb9dec37271d51d510b6a8cc21dd4b8f3f02997ef5e7307920b3e3ec40f600000000000000000000000000000000002b53fbf4800506e6e69d45910de04ae542994f7f337ccf97189572d82801de2f283f0d612b739b23f886b69a312a280000000000000000000000000000000008a46670066e0f629705d7446a265e2699369720a491a1044893f0bcce12697b69f155a01b38c53f17dca6f2de87b7af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001330045e6b6db0cd8fb80e4b3b8b804b2830f1f3db171eb54aa3d6c9676ef03a2167df3ff83cdee6ac93098a44740e070000000000000000000000000000000002379177126ff4a8c99ed85f9a072df7e4a2810de0bf123b1a0424540d250c5abaeea65777163ef25c8013383b0f16fb0000000000000000000000000000000018bc9af6eb4a92c78791952b3b63d51258ace3b6d3b0b6f68476e8ce0f893e8f942ef48caf6132e216f24c3450fba72c000000000000000000000000000000000176b33942db6c5e30a46c5bc739d9317f97254c35db71b7d00c9bbea681923133644ad97661aeea7042c3b2798498581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012befc00b4b53c5d2e78be7470bd7a11dde00e8e959664432e295f0665285473512cc3abc24ebe1951baceab56d793aa0000000000000000000000000000000013831f84aba3c6b2d42f3a1bd6ef0ad2cf57af1ecba781f065c8bcf624920c5a1a9e4a352ae8b8e47a8febcb4e289bee000000000000000000000000000000000ab77f632575fccd5d597617a9e411270efaefc276cc42d832cc48100b6aadc95f87612f1b6e2f14d7820349b053d7f3000000000000000000000000000000000589fee99190ba1b47810c8f32513e4cdff95861a1127feabc2eba21a45b46297002e014ef1edf87c186a1de252d36281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b6d88f46d8618d0f64e036d58f39a37f4d33a265dba378a628602d94668bcffa49b37a171071a0da576b3689c40a8700000000000000000000000000000000015bd0c3a546247eb878c789d4beb1b721df31cd78e019834f55970edbc7ab95c057ef03cd6102195e01e222680bc9f3000000000000000000000000000000000ba1d6f73dd55f6010730b61a49c85034315720ab5eb1bc91d5f2d33bf2fc6545f6b1f65b8e907d9147a7e5e97f8cccf0000000000000000000000000000000003a235d5fe02c005de7acdea89bc95bcadc2317082ceb0276631eb4a0467595de0d42463dad70af3e373ed2f6e60c5b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076b85b71e867a23446ee38d46c28b64be9bca94019d50ec47dca07d89b1783056690813812c46b124cf762a7473b194000000000000000000000000000000000bee773592ad08822ded635afb6c4ed9396ee7a81d43463d86d8f67100f55b823880ee41c776fd4f79d273088a6d7d3d0000000000000000000000000000000000cc25edf9db70a73996217897df0d652f93edef2d23878c184d68e1aeb49b00b49a8ee41c71213776318dbc54f2fc4b00000000000000000000000000000000148bae47bd452e29fa49850b3905ecb9e8dcff38e2d30dc27b7fdd99480b3d2c8edc3d3cf8994de941d69a5ae28627e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003719ae6c20753f989aab56d1b204416ed5be8690f84ecf1c8ee085ac917a85aee9f7f7e1c509dafaa03aea620ca3ded000000000000000000000000000000001736e3c4b13dd3242d0645a89a3c8103761769eca64dfb6e9586fa70042b2326f78093de3ff044535fbd8c3cba1495ce0000000000000000000000000000000005ee15315d44b213fdefbee28bbd1ee0d437d42e03553695c26df2324c3952b42b05c5e133301514258aea6309867b6e0000000000000000000000000000000016c3b0cad107b7b2a080cd497b8438d8bd427b7a8c029f77f34ca59a285ee747ff371b21d525100adcf9360bb9d3110d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019910c103644718ea31e7c21f2534dfd3b3fc4b9cdcf72232dacdc7aea251ccc91565e2399a5c1b864826b8aea9ba942000000000000000000000000000000000c794e0d9125990926d797272c7e356242b863d7ce22bd9157419ad3ec1dca12f582232abfaccbed584eb7aaec272fcb000000000000000000000000000000000441ba689544dc52a39c4d0b9c5d2d00f09d28afc8355b95aa03fb57b86abfc3653dce49aa4c5e5dead21bceb683819000000000000000000000000000000000084b5c26084c81a2aa3749be06c2223cfaa534fa3080c29b53205ea90182433c0d2ed58db2e500ac4197770741e215e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148f9044d350b8fd93e2514447f78b71d7d60edfbd49cf806e6f5f210f19742880b7fc41fd2cc1222675943aa2cf1807000000000000000000000000000000000b69968f8df265356d6d6706c9997763e896533a9c96b47bc24a9d0548b060df77304787157507a8417fbb0ed59843b10000000000000000000000000000000005049744786e8e11c226fd8ea9f360381335d93b3935cab343b8f055eb4891760fbeb61265085fd7a77175641701eeb0000000000000000000000000000000000c5022b5aec608817ca9d0e2b9982e2a4013589287c50ca683a05d7136c4175dd1ff97ff6ededcda73e6e07d1b407b5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d087b4d2f7223516b2570db01dfd91dc711f9fc2b9feb53d639b378f9fa7e74b2402bf4f8874448c4eb05d12e6694e000000000000000000000000000000000748667df3b0794a5d327f584d47c31d41cf2ef76ce2bc417a426a83f783a5fde90210ad57c297a11bae77d0d90bd7cd000000000000000000000000000000000fa8a8942a7a1e9c5fc47e093c6de83eb09459725db1ba24ae7cd8a9846e67e877470826808767f981112375793798880000000000000000000000000000000012be61bb9b4bb6fec48b7ef143f8404b6adbd3fedf70ae0c92fb04d766aaa28e661d069fbe697100e964fbc662c480011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1ea3f4098d01b47f2a4dcdaa2cd5d71bcf2dc32645c6a3050a5da911248c45a12facef170a1158b129ec61074f60bd0000000000000000000000000000000011ac8a39d315d27f0862c0aa9f26bab07035924296195a8f4aa5299a7037a6648649d252c384762a3b6e9ed4ad2bccbe00000000000000000000000000000000003ebbf5543e0bb713c776aa84d5b9fbbc81e4c76fdf5f10dc327fe9c64106a66f316bc0adb7fd78b9f3db9e3086c5fe0000000000000000000000000000000003c65fc457d6d9fa8b1dce1a5709acf397cd6acc3a0fc7b72a4ae53c245e090cfa3c90a3d93d1f9fcc3f888ed221209d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001745d38eff77a29d163c85c17de38c93ddbb7fbe995c30fb2ef99a731f49327f86b83ed0773e68cb224a5e985dcae88a0000000000000000000000000000000001b2792b5f82d1cfd4e38305a2bb663dbbb968d92f70d278e5e3206a47c14cbe7b518e45b3877e4392ab6855926422300000000000000000000000000000000007c77d3af4c342721cee88816ff3115c0d6b4ef40f47f0c4a62eebfb9304cf52f446417b8670f23807b5b9411f7fcc31000000000000000000000000000000000fd28acae824f7ce4f8e466173e6e9e3640fdfd669de69405f4365e5323be37634675d3afefdbdb37be419b04d5784291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b7389237d19ff78f72d0a9f96236f90ad87541d50b8a52220e87c16048f776043574bfc91600f7a6a0d69300795b0f200000000000000000000000000000000093e0b1f0d69c759602b247dcf5b98f71d151ef99bc2f5fab37f9bf6275f7b56c43e6667a36e312e78e4fda34b297ea20000000000000000000000000000000000710bf0b2734786f3149bad14423f062854cfd5780b78474ec16ed675fefd2e42839817338b1d713aa9e5dd8c8f2c86000000000000000000000000000000000d46a029c4ef8ac1782dd99bd0932287bde183f18df85b284ae6bfecf96548ab203bdb684f87d1166ade85afb4c8c0d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c22ae873d52e326e25531da24ae6fbdf5e33871433635646f6a4cfd59d13c1edff1445cbe50d5fd1a1894e06679294b000000000000000000000000000000000f388ebafa4f4c36a654bc4c6ef7bada77f3958ac827a5351e087c03fc8389169e99024b67ff7a8f96d481b20f694dad000000000000000000000000000000000d73561f940076c52dc74564558a3f99261ac8658de94d429276bac7df7cab74e492683eb1eeacfd20a85720c7a93457000000000000000000000000000000000c624810c9d1cc475556d5123d6121686c4ed06ce71abf3cb724452b0a54b1bb4b1c64db2f2958fb69604620ce1ac1031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e4e9a57e009c2b6105868ce993e8396f210f8df81a1c024c07ff708b599fba6db1192d9b5bab96d5880d5fb4aae4720000000000000000000000000000000003c5c3795fe1d6bed101c2884b8f9720e4d2fdd25cc7ee2626882266476fe3db0f7d716f55ae84f21856237ea676f1c3000000000000000000000000000000000fef9fcd12ab36262109788279cd29ec85e9e4a3d8ca680f98514a75a3cd614b0c75f85a566337becdbbcc607530e72100000000000000000000000000000000050976ba4ed35914e5be75f5f9de3deaac5788fb0dcd113ecd14fa1e2ed5bbbc358a3bfbca32f72228b305700f929cb11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b2db543374d2f05239be800495b209f1381d47c822e629d0965cf7f77a18f347e23fd20ef473a5558107ff048eb640c000000000000000000000000000000000b55ef580c6f3a8e9c17c412a743b317ce684cfb2b12623de5d03c48f07b3b42be6a50920292413c20ee309d6df2f75e0000000000000000000000000000000002f4928f98d2ac2f1789fdd7341e9698a504b682e6d9e97a78b98550d2cf03e329b77139ff73c11fc0caa21434dfa44a0000000000000000000000000000000015dff7df97f4c9edec3c5b699aa2889b2349056248ad95a02b520125522081c0634e13890bda325bde935ce414fc382a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eac19552236e6e800248ca6037394e45e94b3d628f6e466a8bac835ce08c5183b5680d9f6e12b7018eb7f12faad5a60000000000000000000000000000000015c4046a33cabfa3e938d364cc78c64fb37ab69dff7d462fe07102ff0591b2aff4973371e121ee372b1d3a32dd0f2795000000000000000000000000000000001914c3017968277e4a600fdcf912c7b0476fa6623a503c490e1ca24e764cad562ce2004218a9a5f44d8cdc34edd9dd14000000000000000000000000000000001833086786d28b2ec1841b9c9af80c8a5fdc90611f860b9b2f8ee69cd33b42c44eecd34ec51501b34a8288a1e0e46ea91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000127c476d2232710235e4582b06406cce2e262e6431a638608fb71c7505f27a0971e12fd188cddf3a160d7548d6949065000000000000000000000000000000000c0643520defb6fcf90157845e12e5a94a938f7fce958339768eb2ab54c73c7a27059b658a27fa7303643398d2fd46ca000000000000000000000000000000000aa655149b8a0e3a725123814a95189d18a61701665b6d077abdbd18f1c3bbe63e9804f443aa11433c0a89e1a6f0a8c500000000000000000000000000000000177dc3bbc9983fc35af72839dbff7d84fd3ca425d18341c4ad7c8fd981f2ac3ca6c6ef0b125299c386ef9a2bd56a2dee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb000468f2da1df0e4d3feadf8b9e3eccf0d9f74948b77e8e8551d1d34300260a14b55fe9303bc440cdec44982070a40000000000000000000000000000000011d2d4f0c7302343b731d5a6afd34b35834710496d1b5a2b524480e047b1e87e8f54525b2d93a831cf33923195ad7475000000000000000000000000000000001823dca2011a85949ce46bf5d6eae540f4f1c766f9091e9e8c8775feb64986262dbe28450628350229c0715626aeac1e00000000000000000000000000000000048327b645a1c739e3e02df83244c0cb22beac3ca2f23d02b61754dabb0d9e9b0ec52079a83daa6059ce80a0cb8c04c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5fd51383e04dd3f69b1d6e6701a88c2da9ae998d81aaaf0f5978b4a1020b94be62ca959d3cf377c4d350cc42959dbd00000000000000000000000000000000053b3f3353dc9d983a392c81e9d809d42cedf1c8583affabc7b6e1c8a8f8ec8db4b860283890ac8f8aa0a11a50a8509b0000000000000000000000000000000003b5f4fcc5555c9581e0b19de8d7d1275359efdffc08ff2facf95856ae4f78830e7e2d59d058d7bb2a5e9ebd735f309e0000000000000000000000000000000019a39d175ccab502b15e50ea65d3354ec6564502db5168c8f77aacddd8c2a241359a958089f9670ce9e5752850fb4c881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bcd58a2dd9b4973710b5962c4a655e8fea442f277ae329574740ea3d6a7d39a6697857442a392a2cd4ff070530fcc240000000000000000000000000000000014106676107ba48b462546ae6d0181ba4c18fffe5e27e26afbc942dd0377b0d3fe2c4ae05ebfc56307bb69f21cb3866d00000000000000000000000000000000187e1df43c0637fa537665bf29799de57f9534adc1c46fba91d29813f07bd4b9a20c0d0c802a3f009ab676ae8e1be67900000000000000000000000000000000069798f6e6ff969caf189a99ebc7a946f1cc3961cddbde818345f4f158298aad1cef4414e7232532e917c046262b7cfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001070d9232e7fe7e808f3029dea44fc24da8496b4ed0d457f782dae4c449e27de8fa8fb0ea3f02e05b164c7919b2c15e000000000000000000000000000000000037f4ea013024ff2d375fefd45a781a7c1e153b54f7d829b0c18d85c8d07d77187bba9f75a4831af67353b999de1185a00000000000000000000000000000000141fd5d38544443b981054022e6eb097508f9d8b1a29c9dfeced3c1753a7d1366ee9126b29c831e0c65232efd6ec3a970000000000000000000000000000000016ebcc73410981f7830b6c36d53dc3749e96925670b8a20ae45ebfbffdffe4616ebff0678b232551836b6206f13b78541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083fb8c8f435b1302a7a640d45fddc9b1e4f490ecbcd7eb23a701757be87325498ee3653654b950a99f0109b50fc476f0000000000000000000000000000000012c9b6cfcdbddeec0f0f2fe30b8cd55919a991b738bf5c6230da517933847896fc0673773d82eff70609c30ccc7f5ad40000000000000000000000000000000002fc4fe5a7e0a08369e0187d1aa291618106721bbff8be4bff451f8c1b004e8208ab49cb79cfb6f155a3078f17565d6900000000000000000000000000000000194b09181daa18cb26706a4ddd1fa1227815dd55d844b3ee1aeec37a08c619043ac06ce5dc68032b09ba49c530bd65ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153fd2a33a19bd3d52451c83d3d031460857345097b38321745f437d181a2ccbeba46808ae513707415be4755af4ad02000000000000000000000000000000000b3b0b3afe0b2c0c315b1576eb0b926ae240fac68e1216d24391c7c230fab211bcfd6b82d2ae215441c8bf78a9e4356000000000000000000000000000000000116a63cb7fc0edacc8a988fc65249e2ccadca18761cfe36ea5cdd621d81b03a8984260b576b2a0aa795e85429389a267000000000000000000000000000000000fa0c8239ed77a227e879196fe2af304e9a6a6d6e48a850802b4de8b7c75ae0ce98edbeb6b7c1af1fdc689c1f6e5a1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6d61674dd08be7e14534820ee1a7efbc0fbb9fed751a73af7a832a237800941613faa069f2d029b20de61dc293d6f500000000000000000000000000000000023ffdc232d52e2e5b5a84c2645fb362ba036549cf1878620693bc8177dbefc66879ad2fcd4a225e460381ed04fc6734000000000000000000000000000000000eb782b9405415b138ef2a6922956adde509ce08a67ef8e31c3d39ec9d1f51e11747766b29954534977369ce52b6b0cd000000000000000000000000000000000d0ab9a78b95064056e13a8fa2f60cf66ca1dec33d939f147580d19ef117906b5116662bd15c928095a1e1cb6442e9fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b9c041f2f8441b944fcb591e6ff558eac982c81d325403839adf8065dfd9aaf9b30abe1533e825c5709fb48840dd7c000000000000000000000000000000000b63536c900bb1eaac7b95a01645fe22b7c5fd9230f757048f519113fe5d46c75f7302fda45c2994127b313bfeea6c4800000000000000000000000000000000035f5378da22d7c4d9fd51609b03c1127b4e254386e0bf959592889f2d1eedb30ac85532e6d78966f91f5193c567467200000000000000000000000000000000151a45c6d93d32dfb47e2d89843145c9f6e14d0996089895654b55194c57acf67d2688d2589cb00601f0a8331202d2fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000033c987e7134e090ec98ee57d04afe43b3a03b7f7d77fa4693a9ff48bfb3e04cd49707d27c096659223534848128c2c0000000000000000000000000000000014383c9014e65602495f6f447350474dc2f3aec7494400bc238dea1470db4e56b66cec3630d09cab8c6a572ee4f3ee510000000000000000000000000000000011876456bf1d967ed8a1642e7f9b70498149f1d51949173d9d24659f00bacf5df33e6f8e8d97fa709139606b1347121c0000000000000000000000000000000006f4b89a3aa5967917768caf9850b7adf3c276fd5ec312b6170e737d4943ff5f7f672c64578992df6a7b020cacc2da461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddf3a89451e80848ce315884378b9162512de0d9ab41c749b40f946d026bcd9f70d71b0fb889b23c9fbc764e3a31ade000000000000000000000000000000000e79fc011d79a4a552dc2b9e6466de01d450b7f9a0c3b7704b7ca2a13b766c2d6b28c3a32f2cdc00dea7f7385eb7c799000000000000000000000000000000000881c6d457010180fdf9b120db3a713d905fbe23bfb3c6ed520eb32700ce2c0c9b1a8bc0fd7467a25b612236466580d30000000000000000000000000000000015a30b2c139fec2ef7e50a2bd2b639c6c7625b0de4a1227ae0ffdc20bf694c4c54eafcfc02bad7994215dcf157cf74341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010aa5edcb9c9db6e18ad3cc111fe3fecfa4d8881eaaff662aa9963458612f4d24ca50ea267bca0c2ecfbd36ec0f856640000000000000000000000000000000009b4f263411ba3d5f2a54c9c01afde206a9881f6e8bb669b5c9e37de7428562b72ea9b27c824b4cfa35558d16a20c1350000000000000000000000000000000014355d9f2147417862a4d1ce7121fbdee3ae2e1fe3a7ce410157fb723891fc1433fad4394fdbd9fa68ce42a86c072ac100000000000000000000000000000000087866cc102141fd9f375606b0b4e862cb57b4b56d3d0eee92d05e0467239a906352e42d4a01f36ea55b0d35360754141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5ed72801addeca79b072bf5cb40e3caa818ad5a13ae99e4fbe7147293ff1b86950939e510b9abae7e47d2c53f80ee10000000000000000000000000000000017337eb986aa94d13ec6cbf277c2de721953d91c82314612162f8045cecfb2fdc7aee12ba1bafd71708ffe742f98fa130000000000000000000000000000000019cce38baccfdda9d3365f8eec5df1b14066b8a1cf16a027f553d8070897d47e05b516b55724f99d329ddf33833c1dcc000000000000000000000000000000001918d311ef01fce4f84c47569dc0bf1ac4d908dcba56d420b59da072931755a0c164022c3b4800cb4349cceee050bd211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001147630c19ed87597e257b2c06ff754d4f9f3f2329f3f081c62b5c9b1e6306535cf306d617e4332316b6141a956277ef0000000000000000000000000000000018c55ef22d9195cd21be90d91c8dcd2d9b87505ddc0f37622c05ecc4c614e21af017dd400caaa805e30c3c23a4e0f9f00000000000000000000000000000000019fd38d372aced7ca491e273d823b21c64369d5bbc9529bc4c5a0f757ddf245b38ab79ce3f7a3eac61163c760450fe170000000000000000000000000000000016fe4dfc4a5fcdcb5f4c28e153797be37939d5b7085133146a3be0ab39dc83045ef2a3dc32a61c2b62a29b7f6c0256231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005188a5227d4422623fa652f099b801a9cd34b5690342d7106eb9a66d2621b956f5c943cea313074abcfedc105785fed0000000000000000000000000000000004d28154b5197f878835f0dc971086e3ae1cd6a99fe0649ee69e2170e1f33e5739cb19656ce832555d29781159f1e0b300000000000000000000000000000000077e59f7631d5def46c78a39fb28b6a47dd332b86ad2c53d5158f2adb28faaa63548ff6f76c2a63104c308a8b0d568190000000000000000000000000000000018b23c1adc5d2d5c939914eb5cfd5db13e3603349be404ca9c0cfedb9726af7fe708cce2510f5ce29235e5d876e5ee5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012714f767557c677daf293afa80538592e374b21648921d5e489b6b3d4b8bebc5eac36e33ec97e3689365f6da0ee3a07000000000000000000000000000000001419c0641f6427dd0ab08d42ad885fc6c4c82078065494d1dd735a4843ee9dacc913d5fabd59c439e1ec3bd6a46c47b50000000000000000000000000000000007e4af3e75a92a99432dafa5d3d0bd6b3e8298650e323887bfc3eb76c3f57e047574599d7f578078461c5fb6e6d5a7b000000000000000000000000000000000199459fda236248101c948f8c10131699bf7b1c7acffb186286d0258d2051fff764340eddd9ae21dfdb288c97056e9581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ee2adb697c9f957edfde9c9e1079fd67e86b942af0a632a8818448e398acf1195e399e8496a2739efaec4df0878fd6000000000000000000000000000000001449ea7f322d55954bf0bb9873550eb2de170da04a34131387ee0d0376a1f62b5239c360a4ed3b9257f86b6031e021c8000000000000000000000000000000000eb578417e2cc2ad2db14dc03666f6da952738ee308ae0b55a0e4307631a4bffc69082ecb08ba1c13d9ff5917909f936000000000000000000000000000000000501dd7777ce9fd8a4b05900aebddc83e9227b74972f27a305ea0510debc45633e584c7e50d272ed230cd19187202d881824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001415a0598ce2bf6f8d57693c04cabaa0c3e92cb277983450ed66294561caa1c6206eceb8a71c3397e3a2753563fdb9fa00000000000000000000000000000000096ff981cbda6dc16d80e473a3d8f8446310256a8d450d37448c8de89cc179ac9927eb357d07283afaa60ea11a1f024700000000000000000000000000000000042c914c75aaf1792f82d1d8d369cb7ea2b4dc70413d66a5545d408d2dc437fc24b7f0207a838e04a021245d2ddfa3ea0000000000000000000000000000000002797844f5a14c86f9e5e6649fb82751fd67afec1c349603301facb5b0b7ab9d4f97a466437fdbdb8dea2e34d97402cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003dd2d066b8b5ccc3f76605758ef5e23dcc633f86272156ee71b8ba8cf29a00f8a6e68720987f5aa354f7b265135147d0000000000000000000000000000000003a2b168a9da3a3c0f2e0cd23716e8fefa0128eb65922806fc9a1dc6d54a954f731fd4cca74d6cfa09658c7e9c1857f90000000000000000000000000000000008ab1ebfc50fdb4865dca2ebbacc0f4eb8cfeba3461fd04d94cda523b1e774e71a2678f833b06bc3c1f7890945f8a0d70000000000000000000000000000000012d7b0b95e0220792f45cce9d0e7119d88fbcfd7b8250f7d7cf234f2602090526aaf59bbc2422b15cdb9bad58b73f8cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071699a71df00c4356670c329afea6ac2d04a705b4124a1139597e3cc7bd42615234b726ac301558a129cdcbf430aadd000000000000000000000000000000001500b2f30811891f6bd2f26c410b4bf60ccd65f47786ea8e92582267e50e1710ca3ee692291377901e804a14e4b100280000000000000000000000000000000014daac9bd679388992bc2079b64ef035f69c83a42e0aca06c20ad4aa45c7b846e82de49388fb72ca94457f52bb692c53000000000000000000000000000000000de63e3221cc20ca09f1449a28c632df37bbbec582c7baa24bcc9e1e23b0bf46053e2899ac97df7ea847adb54e77d5801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198032c8e535e475616f4bf7991d77a0d4e79f4645e6a53c042ae255610d7338db7cce4cc8c044b070eea69a3b249edd00000000000000000000000000000000120b243262ef837e42acae5478bd0f4580361f1b1c6e87e915047ca21f8170366adad9b290ae11866780b63cdb068d2b0000000000000000000000000000000013723d94c7bd5a94db119ee890980f2966516819b36947c856aced0b44b375c2fdd29666434dccc3108e8c23855beac4000000000000000000000000000000000820815ae4502f962cebd25763aeaf60c2c93dff78fb938b38b6d24e3719569b8183abd12811c1b9c2b5e662be6246391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c486710ea3db8f58e98af9e52ed16831b1df5c8c97c76bc8f11d81808ff75ba5b6560ba491cedcdbadab3631fb8ba5000000000000000000000000000000000332cd53a6f7351f59e9a50c0fedc6758d854eef0461059ed93b83474f981f2aa52469c124da285ee6026c6255fdae23000000000000000000000000000000000c30bd95fd28232885f019565c22b281f5c3a397978503813cb7911c22ed3c2797fcf936e7d0f6807fb58a45614f916f000000000000000000000000000000000bd300799944e6462cec070c5c57d1179b05a5356cec3e4a1bb52dad4905b27b53a822c6997e2f8569df3c04d6dbdc461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010121ae2c121ba4e165f0eb40c9049ce5f55b027cfe9e27b6ab5e0124b8c2d11194915a6fdac9e271a27e6c9afd5dc24000000000000000000000000000000000d077b079d950147fbf08ebf5479d31e3b94ce46c512c7b9f1e5b4a818a2bfb0bcc71ebe4c39f41a15667404c9acebca0000000000000000000000000000000015a60fb4d100fb649fb7329d458f863a2492e3364d5274ce43ca2b0a0f749127a1fa3e707184186cc862ddf305f46337000000000000000000000000000000000ae9c89a034c0b47a232f23e168509de2ebf10b7f1c6b422ca3d50c2d42f3f3c3d027f523d8d83d8853b16aac5e071be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009883f4f5680cf2e1ed65c3b0ceb125a3062245a1729660816d8d6ae7712f45f41b8fcb069708c90ceea1299623c7d92000000000000000000000000000000000f627209e410dddc44a86d00ab677198dc8476d9acb9652dba2308bbe213b953eb3bacad470ba95bd232f8095128262d00000000000000000000000000000000024e5a84577cb04f2b6b3c92b0057354f6a19a9477acb8059a1fcfb81497e87ca472f7cd71f8af0a72fe1967b91d083200000000000000000000000000000000170d2081c697db5549d674ae72d89672cb8e765232e90bb5b7b58723d2a6a29d73148d4110a61b0093cee013d151570f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016fdcf8d8c4e3c01bed8081559ca5d460194b2c5b416cfe4c4f58ca49631c4c501dd6ac3066069a7635b42f429b3b8010000000000000000000000000000000003c9d620b256da3a216a625c0bdece610b91ee3e7915e177c756fb71bccb0d0114d9edd8a1038cb7da49c7d2c5b445900000000000000000000000000000000012e4e0cbfad1718eaf1afb77aa92f7842d60e333436e1a0756a838c814156a308e936d6e648fa427bcf7ee1dac5936c70000000000000000000000000000000012218ea520639fc3a9e0893567dbcb26df6ac18fffbf8fa969683cdfae6cf572328fd00d1f0256f4d6caad36a0b317271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011492a3635884b6a630d355a17491a2b5390f7183f1977f2610895e9be36725bcc09e65f9e386876e8da06145e15875700000000000000000000000000000000020ff996af2df9baebeed729824e5b12030a178d58ddd41ad36cd6304ce850dc26235b560aa820f891ac28dae010881b0000000000000000000000000000000005d3a5c95972f4ebe79f8770e23b7584002111d79fd960f6bdaed6aa5c87ea2e74f7e205cdfa265199a501b3f445aeb90000000000000000000000000000000001439eb89121b5d9d75af8f7546e2f70599097ec0b6a29f086d60e6ef91fdcfd837b0b3fffdc1d77773aa206ee351c471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e979c5e1f98a756cd280a61c8568b79ebcbdbd6123f4cf98eb8527646b565b1e0f0fdc274847bb6737bf3b18a654c90000000000000000000000000000000010571de2574ad8fe07ad642cc855b3d92da980fd67e7a16e5ed942f20a7540fe67d58c926c30dbec406732f1cd363db50000000000000000000000000000000019c75d79f07750194f661fa22b9f75936a5c30f2b2dcd422941100c80da6f9c79d87ca38ed2afa4192760ee2a092bb160000000000000000000000000000000007115882035f763bb070f5e76c9c3b6ea8dd002918ceec24e511dbcb8fe6da3e9c2b6dc40c0b49b9e3cd13213d64a37e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000185a3ca1c44d30d9bd3f473b1b6f69ff705a44f25fedf4b63e902100b2d794977e2f2b49d1f04eee3d5b1eded45a54040000000000000000000000000000000013b1d42f33ef2ca84c5ea45edac152647c342e76509f61691864c4d5caf64300eb40ac00d891ffd154d5d97ca3fe050100000000000000000000000000000000088c5d048db83c7ec3a0889c5a928eec23ea7f4c4af52a9dcc9d6e5ade5c24d979000c5ce2a6512c40122dcf0517b655000000000000000000000000000000000ca37b17c413ee21979406ab8465e655156cafb57da0b6ffc1e737effb0de4c80e75482d58f5f269cb81ee8f267daf691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e167a36f639a19aba1898d28c727a9d1699ff5c4abadd55ace4af81d677bb937ae8986dc80b41bbe0c3398d4e8b0d60000000000000000000000000000000009033ca53e311fcef91914345ae157cc6a408c14f8b004060005099886e85cf17d816e3519ebf7851a5ded77d61182e4000000000000000000000000000000000426fd54ca458905c613b2e5ac8ad87a5c3d834800b9e40c06c7a8820c3fd3e67ae7ad52dc2a9ca671ed73d1996963d6000000000000000000000000000000000c56ced3e3c519bf54faf1a00cc9f6881afa0f1f607b51ac156b42bd5dc48beff6a0144860a5ec9d5b83b2f3d4b2a0301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c65cf0ae1fa9da0f4dff226a2e34934c5dbfd711559709da9d324a9572a6fa88f63e5075cd8d4f77e218d9ef4b063ec0000000000000000000000000000000002160ce5add4f2d4f111449d353eb8491296148d6a1679dd85f535b444c703277ef496d00c0e5edb6ce0277c526df4eb00000000000000000000000000000000188c69a16df6cab28205c4875659e9638ef7c0d7192ea42604d99e66e9cc007e490c95f4018921d0cf1d2a09005ca5500000000000000000000000000000000005b7031d0da9dd7f91e6cf9355dfe10bf9a0d61f0bfa5379e5567c453ce146242e8892fcfe8579a5e2eef371c2b5781f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b6510c1d380531114c81c5023ecbce33f2a4e833fbf5b1ba3143779e3818d4437557c98e0c69fb0dd67fc36df0d401000000000000000000000000000000000d001286d4e64fd378a0798b5df0877f0c374bf627d06b7d408069c2ecd841f3d20594545f9aa60c030637155b014862000000000000000000000000000000000f377701d5b3f46a1594f46aabf6e082c8504b9d21e56145039077238bfdf38995bd69a4ed2774618e8586a27611a8860000000000000000000000000000000011ddce00250022a5f729f8272cd912c6ac72f7191935e359775c606bb0c6adc514d32289d3c200619c729adf082b8cb61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d43bd24041ae9cd23e5b56fd2d84b23e2a7d892921ca64af8236d2a53efdd40a241b272ef8a2100ba31620ee5b977c9000000000000000000000000000000000ce5480b091f1a30feed8c761603c2f6f73666a676ffb8f709273261863e77a144b09c6bf18795a9198d25689199a2b9000000000000000000000000000000000149ddaaa50629b55a390212adf85be26b016f7facd55110762b002608f2bcd8542e727ca7b4cc419d4ece06460597580000000000000000000000000000000015cc7e476873dd3e373c0848609d1d6e6ca8a2e46da28fbe504875d767c8039bb52b50d97d0703f1e111a3cba214c13b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5c4a901dba02cfe056e17314a9d8b289f518d485128bb206fb5be7baa8b3ffacd48def87b1aa28210fbd9d0d2978ff000000000000000000000000000000001049b47b3de96a8b2b8a9f49c4c59b5bec2c3faa8dd4ff3ddaa619a7998b80bee527b8d062e2614cae1e559017123462000000000000000000000000000000001839beadd746456c6ebaf62553389a62970063534bfa53d523638b4711ed1ef9df79c42bda4d48251efc554ed08d8c23000000000000000000000000000000001410e9aa38301705789b21a6f7971ec0ad10aeb8e1b7d3d6251c047468a2695ae0502221c1f817b9bdefb83f2b16bfb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001504ced093430156036a3c14d619f91bd7b2ba41551a4b6ecddc267e06be4dc3f2c9660cd9c5fb29339c4b0b71df4f72000000000000000000000000000000000c84890b8499b8938c5cdf77824f84dcb5dd5a19821e6ffab80b8ae859e26b4d19b11d04adc5a06b1d05122c4ca51bb70000000000000000000000000000000014eaf94644211db5540eed75e9c562540de9420763425ca866b3919ec3c8d2088682102ee1f42c83c29584728a49007f0000000000000000000000000000000018ac41971257668fd19daa64b629fe7df98fa7c227612308eebd1125225a44162c6a4c4a5424ff04a2fb8dacdd7a7afd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f82fdd1ec962e0334b93e1dff0cf01c5d7f3eef0063914bae6b29ead04e3edbaf9492b20186f580b9e83eb824ebbfd9000000000000000000000000000000000e5c5d38e12208f8c7c4a2d1bca12a384c82bcd93fef7e9e0a5af71dcb0dadacb1606144add1b4e6ab11342f297c50e4000000000000000000000000000000001026dfeda22285f45a3025fbac2184b8482545ef76117f2dc6d5f27ba868ea7125f95587c36bba2a8343910c7e9091ae00000000000000000000000000000000031af3147ae2d4c85f64f16d546737dd8218325f51ca1498642cdbae69bb5193edec901c698ba1433c0c547e217901af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167be99385d7ce93a615efc1d22e11c44789ef828836da3e666a372f8c32cf6b5d602c4b82fdd6aeb53cc5beb850fc96000000000000000000000000000000000300ecf977e41cb01f4d9521ac0a3cde9af237c4bf955d651279d6208158abce0d47290952946a82e9cb8e8f04f76b68000000000000000000000000000000000d6395fdbd07667917b592f18aa48d21edf609b593b27f480fc5ef9a0533bc9bea6c6b0d9e7f4c3092a5ca75eb64ed94000000000000000000000000000000001247acbfd3dadfb9b42dce312a307d40e37ca8fffa1ebf483f5346f449d4609e31eea3571d7d68c6ada08c86f13856b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000627c03f89ad7f78d278bc55474f9e037383486e83d58ada072b2613feb6d9c4d531fcc9fbd0e34d20bf15764c7feb1d000000000000000000000000000000000e144f1bfb8cb28f49d8d7bdbd83c8beac281a97df4152bd17bfcb5c3e72c482c1b8a5047d5619fa3b4f9dee5f667be000000000000000000000000000000000150161d39f6fce15a73c20a4bbd21a875562d03339ab55509ab9714e4352b121fc7832096691f96622ea4f43339b16d80000000000000000000000000000000013652f1b11475fa345c51735914013fcd0df2ee71be5203fa69cc1071a2cf352bfde97b78c819fc6b516c0394b3420521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001607fbeb5ee534f226ed43d05db846992e5d8b0fc79f3ef0cbf2463373caf022f3ad3b8252e1b73ac49a6e94d5c651d10000000000000000000000000000000017b8cb020bfa3356fb8f7c7ec14f10de3fcc54eb7c958a017f02dc91436d7477e873bdc38f788cd5c0fe97dbf5400895000000000000000000000000000000000e51485a12fbea0ab00895c2a2d29d77afe502c54764bccbb02a0fc98d9639246755cede24ad293bcaf6f8821a44f1450000000000000000000000000000000018a30e69b692aece041ea30f5e7016647f7586e70712f1c58d6aa89d4d75d34776cf3b8c30738e9b41dc760414310cda1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d51f2ef6ab5468504dd55007cbd2e71f812ea7fdf10c8e00462cf413b3e8126f42c1b8fa26fa46db1865719e67ade5d00000000000000000000000000000000109a861362d8515c87cb5237f5bcf666e232c2a4540a6c2ff9db7e4a3c0a0d191641915bd1ecb8d1fac619bd991d1a060000000000000000000000000000000010bd509edb0c3327e4178816abf369ba51cac6feadd352f14bca366175b7d91612733bc0d0a43b2758a64aea18cb82bb0000000000000000000000000000000004dadf23688c4367f253d4977f0ef39a0d6da3da8b9d9cca9fbf29e1613a6c8f93ef996fe89d4596cac1e549788d453f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001002c22ac5f90bda3a214f37ebf9d783e6e7319ba617bf2665b872ad05d27c36376c87b80d3f841b8ff927cf2cf8158000000000000000000000000000000000d0ef9aad16171f3832b8dd42ca4ad8f70c240dcaa2ed840fe0fa7e018cffb4fc6c8917e740e3f868727275b8c2eb07900000000000000000000000000000000131de01d402e8f3856225105e3a57b1a6475783c88136b3051d0b56bd0c881b0718ccab8a8ba145a55ec75fc984fe37000000000000000000000000000000000163f65ec4cba28256af978c07dc258f4564255a6c028931e5b80879723be6a8a2cde1f040b940634827c41a24f8f67f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151c950ec89c6a17ac000dd8de3b7b71e9d6cca040df38a2c045c2cab7fedf772618725047a7c10e1916df2e16ecc2550000000000000000000000000000000016c2d6f218a5eaad677c58a6fcc6c4e9fab6adbf3556245f69cfded4ac96ae9b734bf084006208d9d1c3e189aaa757e000000000000000000000000000000000126ca5b3059c9e1b7d3affc4fbf979ec4f8166670da304a61d0eae5b993ebee226b97ce497383fd154bad94a7cf39f190000000000000000000000000000000003c1b024b3a9b6a396fe00ecbff2327a21f0d31318a64c9b620d3c932be1b7b3e895c6f6b1a4cb5caa1fd82085cb86181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ae685dfdee9af24ff299148a0cccbe4b4ec68179c048b7969c6c7ab6e39becaecf88cdf54c8069bf99f34a8c3fdde0000000000000000000000000000000000fced4567e6a328feae68b91f9db6dfd50b7c382e3c48002a5f9a692e99b28352a16fe7416f260b4dbb0dfd893999b0c000000000000000000000000000000000cb7f7daf2a17aba3496461a7fa9d643288f46e26c5a0dda60e53af7a4b79d95699bce96ab2d35255fbd7d392c0b7158000000000000000000000000000000000d6ddb11f6720fb63bf69f90a0131d0d2e2397b0b9c294f4f3bfe5fbdcaa4bcefd979ebc63ffdb1217e44bb5f549dc761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000de0a8981edff6100977073b8f9f66047195cf16820cc7687a34ce3ce75f0ce2efcf4d2f15e8ec02800c355d0119f39400000000000000000000000000000000107a34c8605f711bfcebf0d3376d65a9047edb8e00a80565342dcf58f1f96bb0aa046ec4778e29c6ffccee8d08884be40000000000000000000000000000000003ed2ba135df2e2ee1c93f735ec475adf299fdcc46170473113b4c0a6c43f587db1d1e8b8291343a43d3460bdfbb4749000000000000000000000000000000000cfd85e1f117cbef0089e240ecdc62cbb15747c7d0cfb05291f9cbfd0c1612dacdf3e55fcfdce3cf9ef4db92669158f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cdb53466b02008b2b0f84740f4c05d3762f273efe7ec8b2503fd364f319ad97a715ccd9e833dc29c71424b63bcba19c0000000000000000000000000000000019d167d29bde6e55c7e65ca47069514bf86ef3517a3180d033d64f37f7e9665f8a076d86248156a643f9ed1862775dd7000000000000000000000000000000000bc278eda03903d161032dcea257527869deba9e8add3978f9fe1461a17eee7474f58dab1cc13ef30cb2abaec1ac74020000000000000000000000000000000011a5f4af48bfef7e9132c98977f7754795ebd62a3e0433856d55881b9c6fe58f7cb84beaa1bdad79e54f9aae736e703e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc5eda907f8e7df718d783b80a80b626364d348abaa9fe827154eba6a4b854733d32204e051c9290ad6a83c6999d620000000000000000000000000000000000958c1040f210a636f72076dad2d10a305fc5fb908033e8fc7a958453ae0ba3c186d4a902bb91fd2592196ba6a8308150000000000000000000000000000000018e9a5b8687c334ab67d4c24b3b9e4e5fc3e3b65638e1c41f7888b582029ba4069864d1127c4008fd3f207e9f9a71da70000000000000000000000000000000013caaad600b4b9b65fc05d4ee4ff77158bbff844839a0979ef18f25e68356f9ceb68082f57fd5c7f0a2a5c70f5dc4e081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9e0e938b405ee2877255fc9eef70d264bd21d6ebbc7b4946260d7fbe81e67dd481eb0c16a2c439f07aa4ab6642be16000000000000000000000000000000000b62cfa4812df202efac51189f25ab9bc09c6d877b4a0774a94d830d44a5b133e66dd66c865eac32a444903c10c0a37500000000000000000000000000000000040ec42488043bba3c44c1f25bd002eeda76280b1c42027f0db57c23998634d3ae1963194a57afa3a3412bf6e99f9871000000000000000000000000000000001448596144db1930b323c1da7df385c14c8e24c46088dfa88450368a7bec9a1a9371dcb39e16f3c5b9c3c99ef72ff1a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfdb7c92ec77dce4902831a9b19ea91df6610c97cab6a62c46a2ddd61a5ec95d766162778991ed2b5bbf074a0b0002c0000000000000000000000000000000019123ca1b5e08967b9315b33e9fb34645994c2c2213f89ae36b48a7ab8eac567784e0269793171f6a70cefa4c549002b000000000000000000000000000000000ca81300f7ce8dad4928dcc837b06b74b427bca5ebe52fc97eadcfc122328e6b0f09a7c0ec66ec9b71c1516683b22f12000000000000000000000000000000001627511de7e9f2d2af38e0b5ca15e25aea87f1299846b875300d77346afd1ed1e47685ec08e375b22d3506b053a595071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078c6ab24ff115480c0f0e607831f85895f8aeb2100a1602d716d11a309063b7eab8b2f6a34e384deab016eb365bd884000000000000000000000000000000001139c2fd9caedd11470cfb671adf4c5914fb4880fc698c32bcb50ba8aca0e117ebf3c436c687493e1a03e178a0f555b200000000000000000000000000000000147bb6d621ef12c03b4aca79f93523a488c1eef9e82fd65dba1f5070af7bbfce9b52e8979e9bd6705142273e0e0aa26e0000000000000000000000000000000009114eccef8cfea317dbf8cf6bf7b09cc0b074f458b9dee490ee991d00aa9f4a688eadf64370815cddef502e032cf8e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003754b8f215266866c673796a51492615545c1578b7388b4c61e19f18ec6b9c9d2b4a8cd8f01be05d3b10413a463474100000000000000000000000000000000130c091f20eb463803705f5527f64b67b1abbab358bb3228bacaaa743b8db16a604bdb0a12771b0f9e3cc21938b8c91400000000000000000000000000000000080cbb4f9e69b77bf0e5777ad0e6add6c162e18d0699b27379b29aa9bf33af8aa3100349268a645d1f188401860676fb00000000000000000000000000000000162145aba6c09203b6f155ff61d434294dd90a2a2a2b5c6c3f594fef670b7f3553c0e122c46e1d03b0e6da477b460c221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118bd1f30ca638448536b76fd5521e486ce185b233a95623cec1bb546f228a229e51709cae32a71e791d0241e508ef14000000000000000000000000000000000bedfbd2a373aac9443a761a6f30d43426c0963c624f918f95fedb45b814044606e43436d1912731c28175605d8954ba00000000000000000000000000000000165f1d110cb5cfc51390f470d835120575f8f98931f9cd5fd3ea68a4e57017faca7c248d776d62e0bdacfca6b142d0c5000000000000000000000000000000001311fa6c7c6faaccbdaba38278d587e2dcd4119ce2b73001630f6b2331fd42e3c2d4ba8de3a44ed16f3b634634f04fcd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bf1127e6d95a13fa636f9d40c5411d426e6408cd3b3727130075483f77688074493ebd1206f5591f2e2f604ec5fb670000000000000000000000000000000007e65289d44ff2e83dc806783599b88a6f8bc97c64036a65376ebd2d12129ae9cbac72928a5d5e9f98afb32d7c83b99a0000000000000000000000000000000009dfd75b2d0833cc5b5f8abbe7f45ac5db11a18964fa7699418daf2c169be391da7a3ec0eed882664e6682ea0bd3f7ad0000000000000000000000000000000007b25a92b227cf1f715b00f4dd533afd2baaa06dae0176bc4c7b5cd25a79ec648e65553a812d80849827190ddc678ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001116cab8f8e33cbf79ae02ac214983a394355c9e7d9a0f296c5943f048667344449009804c7bfca870b9924eeffa5347000000000000000000000000000000000fdc3da06a6d3be5aed09e9463f4b56dd4401769b89e868f08b0d11a47bd9513fb7050c69660e6ff18723beb543f02e0000000000000000000000000000000001928afe0d892f8ec9e40172b56a4ce09aa49ef9b41c7f0ef4426ce9f8401d6d06e35664c926e873fc750bb69366e7e890000000000000000000000000000000014632d1304075974d90aca417ea48073898e607acf80a5b05c09767729f6601b81cdf2dc5c923d5790b58c181883f9c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f000f96e6752fb8e8865d621fabefbb8635099c4839d4af797db158b3a6a4ba0c8cc8edff5ec9fffc637a9180a522a0000000000000000000000000000000014a117e8595207889f4a7a786eddaad1a08420e8307434d4f4ee54294ce841bdb5d797479bfa981125274e999d75177b000000000000000000000000000000000f9c1af2906873337ecb6d0098498987eb6789c8962c141f8f7671cbfd56ba03a7de70d20d5fdd55cce4b8275e41a8a1000000000000000000000000000000000eafce8cc3fb77ef17fe45a5483fa76e141e9f8f56b8dc6b0656e4554562f4804790bef4ccf3a3e6be43dcd99816668a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6acd0b2bf66f847f37c1d8c7b83d7efcb7be52163650f6fe07e8f857344830786c6bb99b0115311e3a14171b085667000000000000000000000000000000000a65c3e4a1bade92daf9c8d3fac5c5fac6bfe3081454d16ec178c5d03480b54e29edd8412d4e066f58e09009823dab5a000000000000000000000000000000000d4ccbf3b6a1df77874153c0d6ac75b49ccc9f920297755089bdb6ef496e088409c4028db914b5ece11b4fb54667e489000000000000000000000000000000000626d116c34943527f77fefb43589d7fc2a0184b842eb768d923c811790058f1dc2044a8433f1462ad7c0e59ed6d228e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c425f567bab793982b10acb8289d49c5844db59ae63cd9931da260458c8d545d251b639d359177b2b393ea5839230b0000000000000000000000000000000019f2bdbaf499e5048d391b1a1e3a066d2967bb255cba8e7fe0ad51436ecc0e6b6b37541e6ea1f232574e9259d56e59c2000000000000000000000000000000000c93384e282737220f2cd98ae97ebe15b387e7b1ab9ef6cd1c2094bf0737f6680b84e3d45aed64caadb5b3b581e14295000000000000000000000000000000000eaf9ddb54105337f9a728e1d7fa210765fe2f2f1e0d5aa52ffa110137384a233ef859d1667b9a3aea4db87a97fd3e701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105b4374aa10db4d0c8b0157ac945fe219b98203025437ddca05d29060a351435c2f9ae5cf9e17071e7a43944b5e3526000000000000000000000000000000000ac410b47d70f567fd4fe1a65203e27fecbe49ba4357acbb9c4ecf50b80245b2e69cd0ed5906012d45c717c041f651f50000000000000000000000000000000003f3560b6e61b58d6f6109e6a152d248dba4e41b2477a794ba40d3ae1311e4f4662a2e3e6d7b9ac65e84921148e3e4520000000000000000000000000000000016b6dd9d69231df27217acf3eab8f2d3399e91a990be1561ab67187ccc2fc12107535e734d3050f6d9c2f22dad9b738d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b337f152f9c24eef68acccc9ae3c9caee085d5c5fe26723b0d9b8389ef71d6f75d391067a913212b30a83d8a484af100000000000000000000000000000000061d7ef5a0ee32c264a6cfb9239b6e1255c4d0afce6cc63f24ad9c2cdd800dba5f5b5aad602b7cafe4588504030341f60000000000000000000000000000000006062cc2b33a680bb1aac8f61d0ddc4639524733f42e50950fa04451afefe8c21c1aab2a2aa4b2244c4dd2968a9d349a0000000000000000000000000000000006da48fc92893d3f9a67cb132ace648027bb1e9e148b993a25347af62b4d1fb95eb233f7bd5c6f4131051b08df0efe361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3a9f342e6e9cc17498c680f5ee464eed2b63a922746fbf3dd8a5bebf049526706968acce68aa425aa763451ec3d5a60000000000000000000000000000000019d90a9f6f24ea34e5bc22e34aca3ea9c04ac66f004089cf48e36ace78309c60d8e60db9a9a2065508be992ae094e868000000000000000000000000000000000bd9ade5f9572c3c019b24439cbce753ad59731bb88ead40d85dd3e19c447e0cb9f1323037bbcea3c2b365cef48fbbfc000000000000000000000000000000000d1827e8c1da0f25ea8dd88d32e39e915309a090afae6e4008cade7b4d9e85fc11a78cc9326b45e17a4857158f1187e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3b8676004b4e51b8d5dae14a02842d7e03fb0f2afcad563299a67612b8d2c6a496b2b429db19d413df9cc0b5e750e40000000000000000000000000000000018d2e7213e234390a0dcb74bcc3d4bf39b05597cc3e2dc321dba601f989736a554999e288229e3128a4d304a32894d6b0000000000000000000000000000000019be5a5ac86a997888bb5f4624b6a9874d6296aca3101efea97193e472900119085069d293b5f92cb7b44c371dff850f0000000000000000000000000000000018fbfbad011fda2cb17615d99cd43143ba768f3388604df385b84ca2caaeac79a8d14c13326bf25af59a87799acc87ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000158335feba235ae619cc60ce3ee8d12b0d96cff3a7c1006d38ebf079983f7765f8ecea1244f59ae4e5bdac376c9937c700000000000000000000000000000000080ed9a85756152ad208c793bdc975ebae27106ff680c584a6f598962129b88b6f403582619c0568f20c347c8f4e06b3000000000000000000000000000000000673378e8c9888932919bd70e24e62835242fa0f210a32719f252485b86e938da53bf114189d66d1cf7e5a01d49c30ad000000000000000000000000000000000e718e1b8c171357c5a60cdbc534b5531e3664db2b7e1952cde878c791fb6b0967d21ab6b4902a4e12fb8a8a28548b9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bfba909ce9f84150415553b75c139a7fef75b160a0592f0afa720937c5f10285a8cf21a7eaed3783ffb3375b1fed6240000000000000000000000000000000010844b9e27d1bc8e107aa5fd12810b863aa9ee9bbd24d62bf73e2a231e3993c4ead08fe7724a58c89396b5dcf6da2d6e0000000000000000000000000000000008ed4c7ca4be96d8ccb392a4eb7ab61d1f0a717688b327513b34da93910d1630de5e7f2ec9b7301f9d87c4f4c9b4bad80000000000000000000000000000000001a3778ebeb6d8d896f8a72ac0f7d71fb60e442d3fa4e59339155c24ea81a06ab1c02ad348a05e5f0c6e950a6538110b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a1e4a2602b49e1bd8929699ae37f5d45bf1e9f5c154216161e53e253ae143c941eeaca47ec0eb56657c72d89fccea5000000000000000000000000000000000ee51efbb17ec2aca4b42042fdab789e595bb2c1fa3c39c67e1749c9c92e03c77e9266ad071891f2de1b69cabe2d28f00000000000000000000000000000000014324ee89d4c1cb1f128a4ded80a63ef271cde09bc1c1e9b1d4d4310efa599e7fe2d448e48533a245fdf04910e8bf1e3000000000000000000000000000000000e15739e76cc2567420de9739763f11efc2fa2cc1846718de7a8d89fc4c40af00999ebabdab65e66083642f1680c123a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dd0cf97101c5bb63ccb8f340af277de5e0584f3c3b4475591085cac7db1123ab254c01bc2e082e89b067201d2075b7000000000000000000000000000000000dbc679954d0c48fda994fc25d6d0a044cd98b944be043bf1752838b8e892de075fcd76fbdc8b83722b6e82050d762370000000000000000000000000000000011048a921d07939b7efdb0c57d452e5b0a6b7f0c4fa6c91147442fa4c1556a1fe5cbd15f234ae64d40c6cae2fb75c6cd00000000000000000000000000000000181db8a577109077b6da18d5d01f919330ab5287694467168d99ede2185033460f86016d96989e6ae5f32c3ff05a26b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ff50cccbf8abdced8ee12565eacd721b5834f037e8ace716670707cb82b045a0ca2729adb99f6c3615c164d50c35b3000000000000000000000000000000000f13075033ef2fc4c74de4ccd865998f6b9826f9f4aca52b84b429e21acf2a5c0f7b2c921ad3c66b9ca51ae8c39a66e6000000000000000000000000000000000317bd3ce1e743a827c12c8a89c6f7e654f4f7d2a92d16c3403145c1c02c89a5f3c8c558a4ce9edaac615fed0f39ecc3000000000000000000000000000000001606a62751f73cb6fa4645094994215ee0a85797bb033b24d9f1c2ba6f851f9e52d2c9b9faf6fdb1cb8dde0aae373c121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001910db38a815e2fa228ef6a21ae58ed9be9c39e041e2d14a4d1d7c8548e874de47d124b8d80cb366be8255f27bbcd4a6000000000000000000000000000000001357497d0ce360df0a4277970ebb0bce99c688f7ed08cbd7072aedf76b13926eaeedbe6c6ed7c4007b47d9010ce63303000000000000000000000000000000001072297bd7bed45ea6a616351462fd25b5f7b4d05b04809d1c169dde548f84cb67f74a243a3eb579ad84f32b485aa8b50000000000000000000000000000000013ac185bc16c65075d680000706d760650139e59933b9f5b88cfb2e54cd686b8dc9b80cc2f73311e966d8aef1856158a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ea6ea89e1d2fb8622a973966e7dd61ae6f561f881fd73c96eb5b877084305ebb969c54aaebe8c270e397083b3188c70000000000000000000000000000000014817b91533af60c29764c4e8f9afb55d61990f28d02c0817016006a2e4da28065b4c3d93ad9f8664ee644422cf7ec7e000000000000000000000000000000001096f1f31f64dcb84671ce9484e80d6114841958b66a068e7b905a0578a9e3d261203dcf62e8b097fbd27ebcf8279547000000000000000000000000000000000ffba6fadaa13335ce0ec0219e1dfa78877823bb226819a4783aac88bd3911ce3f09adc8ffee17e0291b99bceaf312cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000075d33b8c71bcbfd368ad0b57e5d0deb7059ccd4ef60e82097dd6311e2d24dfd14f205a8867c77bf19df85d7e8534e6000000000000000000000000000000000041a3a6a3821996f58630fd442872e3aab26ee2525c4db82ed49894fe39bfdffddcbdd182836b027e0d7824c4df716940000000000000000000000000000000016d507a9b31ff41fbe3f77db15845b872de8fa205362f730ddbe07b1b7adbb2a30a2e3a26000f5895f0105718f5c941b0000000000000000000000000000000008434c0b05990d16e7fa6c90169c7aba6d668427d514b3b2846da2b17fd3df3b236754a78f52fc2aef041d7cb341bdf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001752888f3f4fc2091f260cf2b514e86e60a09b5e4b65d66dddc97b9ac6ae63306d5bdca12c6873be687203adf7afb8ad0000000000000000000000000000000013eaea9eba97b2f707622fae8cb46bb075420ec56152d2ad7b013d067d337ef8cbb65c5bc697a699228d204a1b4fee18000000000000000000000000000000001459d872af072da1b207bbd77a5499e661b68b8cac646aa8768e2b979d184e9e764eb05a0bfbee7866cb8fffb58bc9bb000000000000000000000000000000000708e3ad8f488e246876cc98449e1d8d71ee253777b52d700649866f1994c2fec1e022db240983688e273eb5d8ccb34a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014913800445be4b67dd7c4a5f01bd10b72b875429aa7b3b665dd4bfa7402336f0df6e81cfa555590677a4e6b7e3f12e30000000000000000000000000000000016e1b3ee069b5199b0acb75f3c41bbb4d3330f4d08c826c38a5f58966379a6cff0633ba6ad0cd63871fe1276c6298d0d0000000000000000000000000000000017540d56d9612b03aead601d4a7c6c0dec229ffb0145c1303c35798199ac61c05a84bcf8d52ccd364994def9c3b69db70000000000000000000000000000000006640ec7fd66f3059377b1e9f1b221256bf93bab6f2a32e6e3c8392b6aed4ea573de5260dcf10ff4ffdd968ae2a0cfe21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000099073083ed4ca646d5ddf9de0b74af4448bf7c7b1b50a185e630ce37a2725c599bb3cc2ba2bff3bfd86b950e5ff83d00000000000000000000000000000000168c9b647315cf0a4f037249d51d6db74eb89dedae9af2e092c4b3bef08b247e7175cf9b8be46ae69319d52a6608a396000000000000000000000000000000000ae5c29f68910065df260823ea082d6716f47d444a4833267628357320ee0dca4c074710deeebc2d14da127f4386f0c800000000000000000000000000000000189332205cf856c026294a63d0bffe8a033e4a342d165186c111da7b93f61495843863db43c561f04fa94404f12294d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015917c2199ee06fde98e0b2f752ad33824548956fa29d08c313f2ea76df5d7cd1ff87cadea3be11ba884c2b4532075a5000000000000000000000000000000001178446f24e704f70f7c0dc1906561f94eb3fe4d19300f8cba44085d90605d09c4f73363bc4f6b92e043b984641f965d00000000000000000000000000000000061a421fd2f833da0aacab23106fc4ef83f5a5cb69231ef4bcce0ac6ce6f0ee559630a0ac69602370aaf627bdd93a02c00000000000000000000000000000000150e2261b714a80df3a66c7c941b189cda47d1ab111248f0d9973ff09e6e7dfdfaa647cd9d2c46e3c712ebce1730775b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041fcb3ea259e62fd94740c2ecc7b89805345b9157be620a2b11b69a2dc9797a526ade8bf22b21ef483a36fc09e87a45000000000000000000000000000000000f79b2d6a07c8b481becfc673835cb0cab0561fc22efaa7d12f4f86f93628c2641af2ac83f77cb2575397a4ddbfc915c000000000000000000000000000000000fdb44a327084dbc0a0826533923e3b16b1e9c159059f011b3e453fe152fd4c6192b66dafe7e566c799fbe756325f993000000000000000000000000000000001218604085494539799f72acc0daa7fe29b565f80f4d589e17eb82fadb8d7ec2fbd32786aeefd44d066c2cd3b5cdf2f11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007cf0832fbc4c11dd9071a018eb79b17862abeadd210a45a4576518f8850af5307a6962b104d1d09a855c96d94fe0f5b00000000000000000000000000000000026b740f0f0f05e9b88e3a068c973b2df967da1a0a1adf44c434d4bc47ef30f560719b01317a589cd4ed56f04fda92d500000000000000000000000000000000037b0f64c4672215ee839188b3555884885d2bcc1d1a61032b17012ed8b5afd1cde33959f5c3e0fb21fad19fd76fb732000000000000000000000000000000000f43c031e67b97c09774799fc325735cc94cf2c45ed02185118c076a2f86a4b074ebab5563b02c130f9f757856774d921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c899cb48482b18e3b5b0992382a26ca06c53b5342ce5a02fccc51d90f53589867869c7b8c1bcc71426bcfba6ac3fdf00000000000000000000000000000000014435908d66fecf9baf3274960c6d40d66ce30eb03084c75e17695fa127f335aec2620679c3adfacc7c30b80d9e2f6b30000000000000000000000000000000007ced172911f9c97296af3e37315d63da0a1cce84944a33e4a7330a185fe816aed14617ed185591dda3c003840ebfaa6000000000000000000000000000000000b86862d92115712d3116e8c78f0a225257f11eb7f14ef752e93f456e0dc79d2fa56aa3583b5271db0adf2ac0240b8861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba616e789b84f95a39a65ebb3200f6fcc893734f568a9816b127a7392e441e6fa11850012feee8aa247327faf63e590000000000000000000000000000000010c040d69f55e636f82b58d0db13bb34db192ceccb2d6d2067e7c392688492c49116041ee074f1149f7d009a09e36aaf0000000000000000000000000000000019114d9094c833771cccdac6693d51c2c7c1b4aa88ff47cde479fe57651200f301b1920de7615f7cbf877606329fad3100000000000000000000000000000000164347ac00c50c8deb8a3ae98d27ecc5df2b304c8ed287efab6177973d139ea2bdd5c3fb19a6c14fa5c7bbb24e24f7651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c98e8dad75ca42e980705f690014ea2c9e65846cc9c3ee48fb43a23442ac88611a2db11401e1aa4666e0a3d6eb3315e0000000000000000000000000000000009ccf597d764d0721fd5275902ac3084384334554ff6eefec90c791baddc1eac9aad7d7b4b790b9986b0bfe98289175a000000000000000000000000000000001905f28719f1954996dd4c25941164891614e477332dba865857edc85a3c243c7e07d4c343b9fc5c7f7aa024a61ff115000000000000000000000000000000000023a0e9905e03833e0ed31c99e2fedbde47516f4611bdb3a696ce4b2c1890645c020365279edf8560ad5da75345fa811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d82eedad1d74f255fb7c9742078d4dcb51aef276cc6a59040dd71fed8c3513f50c73afcee25cddfb85cec36b4301c80000000000000000000000000000000009f8bb5e9626a113181dd00f014b132ca3b1a76d83c40fe65b2525392c92ed1024fd3ba0e80a5da317d20935519c556a0000000000000000000000000000000010fdf591ea23576378363d88ee2c1b77715d6a59e00afa2762f11b83f6e3181a5de387e4cd1448d5cfaff578a48807b8000000000000000000000000000000000f0589292eec654117f961ee5fea9e04e3fec4d503c93fc1da94813642a035adaf4a69ff7d01a031e6c0e84280803eb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000837420bf7eeabe7f8c4a2a05c37555fac408cd8efde02d3315526c482c592934bc426458084578ffc4037f79af312ef000000000000000000000000000000000fbae4c6ed4ffcb5c3d09109a95ded66a1276a787f919561db0e211bebcf4d6a68fde3a50b4d69bc54ebfaa4e823a3fd0000000000000000000000000000000013fa947ea81006533fc77de51bf6ad0e4314c9e96be064af08e5c0722b187a8368bf5901f491247f815c17f20f57cce0000000000000000000000000000000000c8b818cbe42774efbab957f11ac38c452f6087d661794b8562ddaf6f48ac8b57fdb65887e911fe1a501099fb50a89981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c6db3b2bccecef2a5812941fd3e898c7b5cc09d7d8e091d399616425f8bf1cf5125b76e3afe0f6f35222e74d3ed0d0000000000000000000000000000000000f784fa3f16c45245b9fad88fc02d4b296f00f28a1f800d7cdb5bf70a6b7751fabebe40dbf2e7acb7c423f6c7883fa560000000000000000000000000000000012f78d4b0d4f92d4d506fe670ac221efb2e88f244fa0eac46a16510d6402b53844575b77229e0a9563b901726c4911670000000000000000000000000000000009f9a6148d9f40fd71f97528b87a81140fb3e53f375a9f2c070e338f604c97c90acae7d346e627894219a18b378b55901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000187aa84ddce0d93b6f60d64a4fb02badc2d470ff7d4ad87f30e3113e0967346eebf3791984c4c0e4267d96a17deccbed00000000000000000000000000000000001896b60aafcf0572d17d59d7fa0946ef6c9605b69c2c0df0718ad375327792b736c61b4fa62c4b7fb5e19182502b20000000000000000000000000000000001536a55c0834df904f2febdce0ad87701adf0ee6654087f43700ae3ce7c5753894c8c6bbe11221a4e7b2c6f9c8b121b5000000000000000000000000000000001961d1273aeec167d23e2308880a23fb32f1fea5eabc01d5a01ae6cadfb3191da1bfdd55c3fe9f442210454477209aef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024e40160806508f174c96aa1bd3b8f94c8c2a6d77e57543e9b9a921f76d273375a67a2d655d8f735ffbb7e46880096c000000000000000000000000000000000e7cee95448c9f02702310cb4a5f4ec39a8f9445b00709ce7538566e3da308c76ea601920d8d5bfaac9a4716794211c80000000000000000000000000000000005bdaf41c7ba736a454c8441c5fe08a73052f579c763d867a557e6f9dc07643bced8217c8aa9f14ea408c33135b2100c000000000000000000000000000000000ad7065571de6f6fc8d3bf4085954e5b9a7511f07df9ba6cf848921b0e785259fab379c92c2f88159d2ac29108605c3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001371695d1fa94486c347f8cdfef256e45a1ef0e02950cb0e3a0b6116d304774dfe81815134e6a47f448e93d77f872010000000000000000000000000000000017bb4224391e03813e2317bc794a0de456fde494f270d50df1bfd4779834417a50fcade50c40230f1c49f970b83cf2d00000000000000000000000000000000002b6a799280d902a3b0c388b6aee31dcd16ef9c1c8c5ca689a6e6b74e8567ebdfbb54f00ba69f624f5c80bd5336d1b8e0000000000000000000000000000000005030c6bd9e0d929e7e75624dde3079391bea3d6eafaf7dee07646332cd92d96a0ae6b2c2ab42b58a47e2579e66fc6271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097e13321d25d900703476cf779448540f1b13bbf4855cfb33fe273219b340d4593547f58bc80f764800a8cf053f7de2000000000000000000000000000000000cf9e9e527370480c464b96045e78c0426adce4b52a89ac9e455bad6f239b028fe0ae5aa8629c62b727874428013179e0000000000000000000000000000000014a313d0c6d8c7ee5e3b8ea2c3ce0c7ecba7dfb17a4900e268ee1d0629db4a6b36846217fd74fd6f5b77dcb198b54ae4000000000000000000000000000000000551edbcd2191b4dfb1847b0c47ef5455b60a367742c3681670317fcdca0228b30793cef3be39031865d011b25d929301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000164c6ed712557b843f5a034fda2dcb67dba167e3ae0b4e07c2b7dd5528f69475d751ad2a75657831932d11a9b440775600000000000000000000000000000000060b222455819523f4d013533bb6d30929edaa6b24f7cdf1cfc598118f431786b06438d1ab1ec7c3874e895d81ea71e80000000000000000000000000000000007e6e99c324773855810cc1b269687933bc9215a2cbae14f217a433c731a562092b132b3a5d1941763ca05d08d8e2a3600000000000000000000000000000000159b45de2af00d9c014da15a9edc535dbbbfd6f916037a369e2d8e8ef4573014cba399f2253b31a5b418af85ad02a1f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010757b5220c22f43332a305d424d22fc36d27e0d1d22fdb88f4b06e63f7b4000b1207e1944283ecd20461df068e730070000000000000000000000000000000009fb363e408456f4bf8c48919dec4c2cd5483b175439294a91877a14feee2e22a657f435150f0875fd794765ae5a3a10000000000000000000000000000000001859b0db7aa0692a052803f2a484b7b92026d19cdb69d42a325983d67edd6604134e0706335bfe54ac7f1473dd16260c0000000000000000000000000000000010977a6d115607af211503888d2c61fad3d9c5e477309e5c392e124665bfcb1c564dfbc49ce51259d62efb8b40f7ec6b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013f9aca2b5fc5dbfc35b31bff6bd2970945995075df2ef5dbdf4c248c62856994cb4958a3e7a4f13c014809a61b2071200000000000000000000000000000000181c436480255c1dc070e0822eb1d57e78090e63229dfe4c651a56f84c76a5747696fd19b81af76201bf05621bb711160000000000000000000000000000000000b38229b8aef7cf55c2838fcec8c938e79b5912fc79a6551a925cb404aeed00c491d935e1414019fece1d30bbf82ef200000000000000000000000000000000111edd5e76c6c1be6ec8d1a679e53b74a5c093b5361c8cd1ceb3893c81e5ea3b23657d6b84689cf973b8784ea53958511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6c904d0785fe05a57945b23a50757a05a1c06b6a9dd4c8160bbe17b0c43cbe150abe51ca99cb996bbd1e777f0f6b0e00000000000000000000000000000000034a0bb9f53b6c827edaae4dda09166a9c68e0dc27503bb64638049719de46e9fde92d4f6a582a80f43659ce9d4aa30d000000000000000000000000000000000c7d3d5f43bb643ce937be3028c744d380741903d0eb2926c1daed222edab22365c55970542ed1afc65304766a901bfe000000000000000000000000000000000d5caa56d76c314fac3c624f84f6863f81455c16c47a5a272af4ff09524ff8a077c7d2d5d4b2a8d8d2c88b83582e545b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7a0d86713f61d447f7392d2c440de5b4448cc20d18ff649dac7e3dfff1880b424b0920034eb67404c5c41936e84c190000000000000000000000000000000000ae83d0b1dc1ff9c180abf0fff030ae57605d0c1d786f02e7346b885cfc2952e6de3db17d34c6ffad0ab8109ef532b90000000000000000000000000000000010756234b4fe401763fe4e76bc75d8235fcb043cb77d854246f2408272b3df5728f874a7eb9d6f2f2ad777ddc37c7dd20000000000000000000000000000000006d91067f71dfb7ef83a34724cc10b0ee7a2ced2d3720382e46091edf645d1ad167406ff8929a349f6cd06d7ddbda3ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014073e86b2990b9d220da0fc00d2ae6630a52a8f535de8aab971d0e521537c538ea461769ebc6393cf5f51630a3918280000000000000000000000000000000002259e9ee4fff4e24764c3177d75206de5b7179b90c7c5bdee4464264adf393fc7211c619ea0834406926da9b708beca000000000000000000000000000000000b4fb0bba50ee27380e2d5aec6c1d603f2665f5394b6518d051277703ea1c75bb786551b065cc962e60120e277536fd10000000000000000000000000000000005f6043b4cf155e86137d25664826f50077028c91fe350c5b47edf295b368677256c9e399ad4099877091ac1573b741f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff564af0ee4b31fd5ee56e33e63f75df0aa64a3861287d1e849c9af73433d0539157a1af2787552c37251e7d345d9920000000000000000000000000000000014b6709020de73555841ff3b01a454b23075542218d172518aac55b6bddc01ab63e65422cbb4d42430ff12f7fad6e41a00000000000000000000000000000000026b5b8a9bc22540f02eba500132917ed104f828b38cdd46854be42018689b0d52445ace9dc67806ff7b7f84635969c200000000000000000000000000000000083d370a1b82bb3a4f2149f27c59bad2f0cddb90ca28ccaad867e202b91bbb80cfb93b67202fe79c6879dd3cf3c3600c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a5ee512c097d61df832be506a76b4bb7559a5cc580cd946abc03bd99e964bc675d938b03191c9f6254d013d8d2ac5f30000000000000000000000000000000009c0ff98ac1dbe590a8af1b5d094e86aa3a3a9f1e92988b93def87e9add14052c152e5057ee04f695191c4350076776200000000000000000000000000000000195b0b31a599638748725668fb3b6f117852482ad5462121a2c661cde5043db6979111b0ee46ae075d43acd2322d2d730000000000000000000000000000000019860f5df2d9fbb120150a85e0888c092b89269a00f992665c6809b7627b37d025c088c6be4febcfa1ec3baf4950b8ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108e144a5ee2554ee0a6e14f9be152914c17d063a0f1e1168796aa36ab0f64b43155314c2dea756a9e1899ea9a9bdc5b0000000000000000000000000000000007e75959cdfc19a6d23e6e4dda31f15375127cd5868b4a12a53bfb9f73f71ab9989fed6c80cb2efe9ea93fbe195845f400000000000000000000000000000000042df5c72b66683ccedbade75ea6548c12c51088cc804ea194096d7a4de4ceaa91c7a130976afab451b1a8d44962fb0800000000000000000000000000000000045c95178c37bb1b0ee9dab3522e67bcf5562ebfd115a82a9717ed1eacdef20da49ea87324fb75a2cb0c9493b11ea7f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7cd0d8de1c803d7332d0db23f03d950965483791b2386da9fa80637f4bd664ece71cceff95faabf5fc398c747921550000000000000000000000000000000012b6bf384758da9a1baf0ebbf43863d4d0fb3737ba5e2d27d73b41fcbd0d2ab9f655bae0df88d02574066c26ad9552860000000000000000000000000000000019435743f2abd08fde7e4497bbc1ad4c8aaf26f6978b0a60558bca2a48c279bee9d8ed00a8ebed4f61961beaa2c658ec0000000000000000000000000000000005b6e32abd2fb6d6ab084b750450e2c534e7d1def6a6ed36a3ec81d5f27e26c0e317d9514d368b1279438f102b8538fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ac65d65e59fed9da765ca3ed94e4d832757d961420ac80ebb969dc391da5b65a0e04f5aaf3611a439889599197f5ec000000000000000000000000000000001909ed1729926833cad2c38b42992c47e496761ed9e67cde8d328b3125a7bc7a2c6e046f63203e4354fd1c61e213f5cc000000000000000000000000000000000d0cf89e34ec73c96faf2f006923b963c1eeddaef92ac4e81b21b5bbab1ef77afecf93f423a5e350efeaebc2b0e059a400000000000000000000000000000000013abe7f3a20dbffe873260925c72a3b4745c2e673cf05f8ed59f06b560d0ad9d380e3950b880fa0de05f4a232f26a311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090769d359ac8ec162851f631651ade4bcccd8d116b1a49517511eb96571dbc50ef4034231aa49563bfc82d90a801017000000000000000000000000000000000c7093f63d9d73409c6332ea941cd8691436adbe222c62acb59402bc0ca6df0426205054cfe2c27a9e03e788e4231bda0000000000000000000000000000000019fe0998a0cf4deb1e1de4ed8806c9bfb9b746ec8ad365c2ee3511e72e4fd828d2ea431cd4d6dc1d5f89c655fe0ebd810000000000000000000000000000000019eb8bfeeddd31649711702f81b2a1384c3592baed2b404aa169ad594f96b69d80c83bc2b206684b359f36bae4e16bf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024122957e3dfec5ffb2637c1f8b6d912c983e3db7e3d7227bfeffcbcf0e013ae57e03a9293bc9fedb9b1ecd0b91975f0000000000000000000000000000000017a224ecfdc6f7e4e8e3bff0c81a2bfc15bd51181d875ba3c2f8cdce7fff2c1bdd388faa26c0a99b100804a8f705440d00000000000000000000000000000000036b03eb3d1c24a8c98c63abc081a3f948d95b6164d0625f7c7c0068b4c325c291cec9cb85ad30e3a2d1760e6c0897e20000000000000000000000000000000012602a21dec118b24acac7d9a3d4e1e7154712ca184c4b643b4c9cb3b04d9fd760ba0d3104d6467544f328c4c7b243a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a954856119589afe89aa3ff25a7529175fb112abea4d71d32da93dadf8b5a86e38c5816eabe729517bc37a07ade95a0000000000000000000000000000000003f7edc857c26edcb4ebf6f34feaa4013a67782f4edd76826cc0a91841403cac5772e7406a60033ac3ab66416906c14900000000000000000000000000000000063cf811071daa91ded9ee1dfe5bb2dbf94ea05f8ba819d44e3fb9fc7d56f413a9719bd075caebf12ed0df959809eca300000000000000000000000000000000070a3c9a9aa79edfbfc2e18e08b6f527c1fd23a4664ce8d976ab5787cb7a4b8e8fef6dd6b19ff7b175e069b23be940731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6f1d991ab6ba65d097d58cb736c592efe7d4f9365ebcd66a37c1c9ad1155eab03576e4da2e42ada5d7d7d8e9be29d70000000000000000000000000000000012d654dcaef0afca1fb609daf1f1bb165aae11f97e59c88765021eb2bfe885c9ee00a52ddde4e5073c5bfeb30d0d1aa00000000000000000000000000000000000ea7c891cd5e51618eb2ab7b773a4a787c2a1678f57c20de0517815d7fb70e974d6c9e6fcc05f3f575fdc3d46e3f47000000000000000000000000000000000048d02d1d0a405a947b14f6425cc781cdd6eafbc9a569ce15dcf9ccc42137834fd6bbb2ad65ecf8db1482a48c64dec591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000bab387e78f9394f4df650a9816731be88d7b1ed9f1d106055a0387966b99e58143d0f520c04e2721664030490661ed0000000000000000000000000000000010bb3075c1c08443008d3142587146566012550832aa6ed4e41dfcc75eb7f363719485c2d088483e5267873c25c5fe0e000000000000000000000000000000001669bc2ae7e7294195795f3e47a675c39778e6a61d839307d7290d976e171cbcbbb02f66e6d7ed3a94581197e9edb2530000000000000000000000000000000016c2d8416e21478335ef5e7230189d1f930077690585ccd642d6925c88fdcc839240ef7f7474625925be1bf2b17bae741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191f14203b564fd6c2c4cb768be0197c8a11bd21ecf7948458bcbe31e89ec153d0655778ced8ed6906a17c83b8c6ae920000000000000000000000000000000003023b0d5cd394bb62d9c4f343ed1a73924269f14c71b52b81b5d4e775cdeae618635ab47b4d548909c2623c427daac300000000000000000000000000000000146d979c06e1347280698d81bf0bbfdd821b2e617c61bfb8bff72ce8d45188ac3adbb9425a28f182721961dba5dcfa5e0000000000000000000000000000000013983340442ea5a707aca6139df906c316d230bcb0ecbe97f63e5e078c480f31e49a730ce12c734c353e1868037570b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040c0b02a46f3dfc6cb7e2db63c369ae521c90aedb00b2c0b1146bb9481e4fbb2f80f59b81e392e4d66f2ea6ef34cee10000000000000000000000000000000011eaa51d7e042300d9768c26b00ed8eef5222004cc05a2bf71ef1c510da00cfc9532947ca807d3c568c8dc4e1f2fdab8000000000000000000000000000000001559a0a4a4050f6d7123804ea775b0c5683e39da0823fe5ebbf771760ff5a8a08a01003ba72b91df44365483456b3b2e0000000000000000000000000000000009067766261610cbf5dfd5c8141d12c4597edacd797146120c2d605944c6a58757d19ce96881faf14211a6f9db1914f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161c1d18b8ba8fed10863e5f7489bbe5ba86d64e357427075d3336d7d26c604b60bd68cf38cb6fff8b5a85241fa35cab0000000000000000000000000000000019816e5c0b26df636cb97407ed8855e9ac04976dc4e6cd7b380dc2ee499c80183723bcb7144126e907f051750bc6ad610000000000000000000000000000000001cc0b57708112486a7438b0c2b0a2cdfe18a7a200b6967ca7b8d6766a8a7519e6f6a7dd26fb5ff8734caa0e52f0b562000000000000000000000000000000000c0bb26032c50e4582e7cb631b54afbadd4dbd288f144e29fd67706c60e55d0c8011cc43bf40e2c329eef7dda582e97c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df2353ad63b41264e649dfd712e45b2e9ed7890f28fd50b355159ce067bb34256312ad788a1c579caa5ee0c331e2fb6000000000000000000000000000000000d9bb27d5a8e79b60eefb8625c809e2bf767e68b18ddbc439d2ff0e9fd888ec55d055731b3c30dbb71af2e8188797ca0000000000000000000000000000000000fe65849378b854ff69abf4e1a217f3bf1ac4095ae7572fd773de822aef7ddcfd0b249ab5dc34c627489544863ff17bd00000000000000000000000000000000173274fec7bc9abc6adac1620d27600cd361d8bec1c50e0f81f5faab221c23c8e2047c88dc52dc845cbcf0e7557069e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c43e67f5134e9b73b8c2d2f44f0d8e66b561f5e49c670d3966dffbbcfd3471258bc931fc441bfbcf8743718a2d97a500000000000000000000000000000000013c83909e34a332d40b84310d664b7d1000f5b67c352bb552403ec7e6791ed20e3b2e627acd5d43462b2a5e8c4756cc9000000000000000000000000000000000b7e7b1b9bc484d5117b93a5b9a6c6a4a3714ea54a220e0e38f31f8aaf97ef6738118cf1f8de76f070db27d56c0be9910000000000000000000000000000000005f13ecdaeb40cd6b71a5e0f5605b5c10dacb000165c038fd48241b4d85fbe3b880960eb3c6d239f3f8712e26ef509ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000fbe237bf204bc7b36abb0243af064820bd9505d80e31a1f7beb74c82bd76295895e055d13676d6e432b18af81882f000000000000000000000000000000000136b3701676b909c50ed5f757a863806bda73e64aa78cc1c5b5cfd8a6f4897bf3228237e18d325039e5ae0d30fedc246000000000000000000000000000000000903aa04553b4c71208927331e98e6c42110da7c86f05bc85dda6f9a3e0f6f207f2ab94069f401d1e072fc05fe00c12f0000000000000000000000000000000005a0fefeb20466a76d325f04faa24f5734d8fa557cc9a74ddaca1f283ecdf88c6c018cbc01f9f2feef5da71db1bd9a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffc6f3ad6373b90bf4aec29056caafc0486a3e87c1eede2552fc266c43b7b29412145644d1e87f3a202e9496db4837b0000000000000000000000000000000007a94ada61c0cbb8921ac9e38fd66d3200f798295432a39a9474b40f3cc2d0f24957aae89e5433d714614747f1f5b5e000000000000000000000000000000000020f55981f6d148029279d24577332849ee60e7e9457723bec470c6ba69cce4d2ddef9781063855160ce32e794ec14cc000000000000000000000000000000001831243f125e9270100483f8766727c34e01e52323026be9fba9d85799297eebebffe18c33b89547ec944260c99430851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a585dc65e48c8890c74f000f7990a5a5ab89d849296b679ce71898b1f1e6f97392d152d430cd4ae5fb7daee7d07d3400000000000000000000000000000000177d94b2d9266cfa324069cbb4c341f08cf027346c8b8249d207509e39071e04ce8d70aa7880a1ae0fed509f8c3feac200000000000000000000000000000000112e81570b8f39024fe459b67f847d7122b3ce28f22b2aab80b1fb4473bcbd074d8e12e287faefa4c8728430c6139ab40000000000000000000000000000000005e6b5dec7d1decdc42c14b91e6a4d468121b8f111a7b2072bcb34a8b13b4734593520831fafaf4ce6178d3d80ce3f9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006138f76ed8eed9de440fd118ede46edb66c6a616c0a1640f71119e2ec99be693b1a5cfd70ec07282f76df25b8af2560000000000000000000000000000000016735a7a58c2c38226a096b65fd6aa9a508c3d4add600de29666fd64c68009b46498058596568d326ab73b33507a5bec0000000000000000000000000000000014885fb4689476067b26e56f8cc60d4797648a675ed88b15ae50c366bc85fae9403b54ceaecea525d6e8bd249b1e1ecd0000000000000000000000000000000010c798c1624623c561c251dfadcba65f01d7f4ca9da34ff6ee057c0a59d5f12f2534f668a905af62fb6516cae46fb9b91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000306e2bdc27b78d82da73694d88126809a99ad3059aaca44d0e721bb9abf44f571adf67323209d10ba47c3e4c76568e200000000000000000000000000000000117ee1240b7720274811689acc4487d951b7ad69fffca8e0b6c026e0be18937b37773d9d6c0275353c73a0e3a28d1dd5000000000000000000000000000000000fa6c0eab5b15c5e3a8e1c3daee2a67005e4f22420a306ce458d5afceef5ab6825172a94e3988cacf3e18beea0a700ac00000000000000000000000000000000028373079f51e476c556e4a50be844d8e41db6fd059ac2614f339c239472bdb1aeafed47b931a4f672322893e2dd285a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c9170baf2c611d94ad265d0f9cb57af0bf2b72d0cecec91b43b229ad5c1c6b7aa6219e4abe44d89896225457a8e915000000000000000000000000000000001827a249ab25b2f317f6cfdfe90c8b8c444ac0b32b0c4dad70841d54ae8ad055f890b1e4716b089b0325617cb42ec9380000000000000000000000000000000013e96db93c926e93601656fc2d63ffa7bcfb697a0e83f12a60c7bff997ef7696bbdd1ce2de65c7966824163fed96a5950000000000000000000000000000000000c758dca53d785b8b3310816b1e252ee9ab334946197fa9544878c18372b257ee61eac1ae75836079c65cf33622d0a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffda2ff763dad43d0d7a56c612d810e50db6e8648a0672b1680bb396a0709d8bd1c980a999961eb9dfd0a0f814f231500000000000000000000000000000000157abae6416c66f3020959c42a71b4d5ad76fbc9999413aca517973db9ad7ab7ac6e954949610129653a8e74a6d348860000000000000000000000000000000014b11367f18e78867d1f3ae681dbed58e350c4ba6c9be075ab34a2b1749e4f650d84abcd99ad2f33c9b408c501d7637d000000000000000000000000000000001588eaf9445226a36459378d3423c3aac666d5a8c0a3ea732bfbc5d6661cd39cc486389fdef7a46745f0a8acbccd29771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004d1139d1df3c85e4da6c15b9464749c49c6d3baa2c8fa1b610353ad262880ef7221d703d11212575c61e6376593c4860000000000000000000000000000000010099ebe6d81554c4889028b01cf5b986be147d69ae94b2ce1fc12684b17b4a82e1adc696633b3f9b11d49e294032db700000000000000000000000000000000196ca0167a571cf4eb744dfc1a39ddb4194c074d669bc55f82b20f76dab6b21619ad7ad2612ed48420478561e62dd9cf0000000000000000000000000000000005ba778dd30fd54413d74efd987530536e126595494a2b377a3d3b1d47be7e967a7d7273602b3033e7b697d6cfca5ed11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017eca5aba857534fef740e91fe61adf26da89768eb974cb3ecdb66e21216b99a72c41c88477a9f00c4c9d19468b510c6000000000000000000000000000000000df5272ad64e8602f0b7d03e3dbe34fc16d3c078adaf2e089d6ae3d11ae02e9af2785a0bb11ddb2f40caf99119fde8460000000000000000000000000000000018d6a774d0955a764abfe80c5abcde4c12e72dd4046b01f475175092cabb791661956404d22cebc272e354bf5b3133f50000000000000000000000000000000009d0c610edf48d449e762bcff5b487b7cadf177bd7619ce96bdc92b4843531f141c864f8511a7510334aaa4975b3876a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091fcd8c9edefd53787331797963f9dbf39df879ac418c8825fcb3425c74009c3d6292d8e068688b3049cf05bbd0429f0000000000000000000000000000000012993a4aaccc2e1dcb7c33b94cb7b0d08fa333913004c6245497b763e4576042488bafad29d5911b2168d730a1fbf62200000000000000000000000000000000103dcea329675155e89d772c253cf04a660881e7fabecb4c226d4c8b912998712b43323b015846ef92f1c9b120915ec900000000000000000000000000000000038e53a9413150b7c8a1a118f2714ce045fac51945e9f216c9c3fb0cba914f67b3d3db9f2899277f8203874b6c7a83f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a1847c3ad9130d159e48a89c596eb4b39eb6e5bb64ab89970787793577d25002765210cf5db255a7e24853722529e200000000000000000000000000000000121473b53137efb57317e89ae08961c9752c5ea98d29b90aa1fb6dcbf8cf9f2a10510f049fb9318b0580432521c4db55000000000000000000000000000000001293e7ac15e5447bd1a15139bd43325cec7b1cb7d97dbbc1ad00f2c8a201222bbcbb097047183b8b83491ebfacad68be0000000000000000000000000000000004a6c289207b3ababcf55457da0cdb78a3bdf83aa194ac3c2b37ea924d3c5e9da9bd2bce096c066c8e5df253dbfa66aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000119e4eb01df72bd9ba964dac23b475c2fce5da9be34d50d69afaf835965c46584bde125a674c884db58e21ee724d5a61000000000000000000000000000000001081282f9d052e2459f6e63b85d8adb7cd78dd56971ce2140a6edf29e53a89d7f311fa0308ef3329ffba4f8d8d660465000000000000000000000000000000000e96c5011858843f1e0e16f43ba8df284145e7bc4cf287d87ce2a101288ce9aa0b24fa90836f78ba0b33ef0c3f81f3de00000000000000000000000000000000101df9af40b7db25ed888951fae3e75b967a29489b2071a3225da848d19751532f9d068e7c6034e19c2dbb43f305c01d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbb8519acb4a38bcdf5667b2a8545f10ff88c04b7843a54526d2c78e1a777720e2f1d24327ab44e9264e0a441c949810000000000000000000000000000000010615254777726ab4588cd91e44f746004a2f6b211a2d8e72fec677c9ff03de201f4dd5ba6402414e8ea13da35e3eb3700000000000000000000000000000000183ddd54c5bf1f9fbd06de49931072c37b8521083d92282cde36ac25d6cfb56061c1fd8b4dd05e97a6b35afada12d07200000000000000000000000000000000093e32f236faba44159b1c33d2437aa2d2da3c67a8126ba86a41c3f4a4a7bd2de24c0bc58fc19e93c1cd415a37b183971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073af6337d2247ba5bd0c6c033110528f083b9ab67665712e6cc7a0308d311a7d8435dace8f9f64557ad0f1a0601acc40000000000000000000000000000000018cf2e780cbf7eeb0ffd2f170b49c169aa6e3d784ece12f7e4ea731e60cabae068d6893f0c6391b8aef5493af10694ba0000000000000000000000000000000008d073cee74a9803ad78e5c1281d2961ea287bc0eb93656b381cbc2d317c57b066723163f583b462916bc3f49b5205c10000000000000000000000000000000012e721203cc6cee14bb4f677874ef7714e69368d7d273ab6e2bd77b62a805435cd869a50cbc864a0d7c6cd649b3f57e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000051d488c9770ad6b8dd0bb618b02526fc3c54c7950111582ec2a5fd45ff825a2e2bb2004917a9a98f0200d52c055c8e000000000000000000000000000000000031b4322972391645aa129057a49ae7dd4bbfcc8f6034585cad806f0c14e86f4e566bea1fe20400060d85e34b06e23ea000000000000000000000000000000000b2ff770ce1bf9f84301ad2b3b2487a75950dbec3116ac939baac7e83b7d257e6f99979f9395f9d06cc15c2660f7495700000000000000000000000000000000087cc81fb51c6bb7eacdc31d05cc19e451d6370c25476572976f4192f49df127988077beb820d0e536e5a4cb28e6b7fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d20b5d1510263aedc8d286950c1c5886ef59a9a233748e6e4359eae5f41ce28045e95ac882dee7148b9f6c54416a7500000000000000000000000000000000146b8954bbdad63bfab0d53c260bdacda1750e1165c10b957c01362888b7b3ddf490a7c086e0b0041fcc7c4271c34c04000000000000000000000000000000000f6d3981b0d25e8a106a29ddec0fec8af95fd20392646a6326717f2270cbafc6abea36650c00b505702ca0d4118ca9c200000000000000000000000000000000038ac3666a19d681b6cb298b778fdbd1f154a80cfc41c9dae6d050359f9840b6ae5f55eb3d3a0fa4b1df7777c681eeb21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000165bf6b5a388332f425d6e369f4467f22cdb8c5bd42cb9f91d8cd09993d52289d4e2c1530dfacf3a822a498075d6210000000000000000000000000000000010f6a9119279a8f52fca8e0ae1f609ffd558b70be135d6c3e27bfc9d9e3ecdaa288980f5a1bbf7a85127198d19e4fc290000000000000000000000000000000004fadff49f07d0d332570c52370aac3e9e64d8571ef08eb2e9df777f7093bc0379c704b104beb67e57771c8ead87366c0000000000000000000000000000000008de32229e26f148933b206ff617d7b6a2a89902a0c8b5e00a352b0e75900b5152857632c00fc88061e781c875fad3271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015e8adb0e995d561e3cb84c681ccec3448dbc81bb52baecbf2ec70d92fa2a5af733e4272bf566fb283046716343c9c60000000000000000000000000000000018ac8b7be2ff56ac34852a8dca5b7dd93c75ac710277b95b846f1e1be05ab2af44579d55acf56cf84196adc88cbe7ade0000000000000000000000000000000004102fb6d360f719293136e5a1ed7afcd2a95f5faf52a6b5ca74230f0127c7bd70b6694ee2c3de2d51b2ac89a3880a67000000000000000000000000000000001097a9a5ed0789a9eebae5f1e06a638cda6e5441bdfe31821f55b6d3279b618bef3beafe44d8f72f5e448a63000eff501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000171d8df72e533f4489229b78253278d10c3838ac864270613fe7c02d2b48414ac4563392f465b3e20538fbc720dab749000000000000000000000000000000000d814b590d96568cca4c86f251024207a07953a0bb00e63f2498db22223419c2e027bea597981b8630463d2883c662da00000000000000000000000000000000035a58e3b8a9ad602e9d3c20773a2465841580fb59c486cca7b8fa1385685ac240eab9334742d5ea018ad03feea49d13000000000000000000000000000000000108396dcb7acc3cb44cd090bae59ca9ab3577951fe6bb2cf5d24a4dd3520b956f237a95b8f1885240160c147d3f1da41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019115d734ca7c4dddd9341144098b1f3b76e2018e24e0fd29384b8a43ce973f8514b8eded63284d32d6575bf7778650900000000000000000000000000000000098f6ad035f4a15e4beedcf7531a44f789fb3141f32a2c610b352153132e5fced6e1661d02ccbe0e3748778f944097630000000000000000000000000000000001f691e8fc5c50217de6d5458a500ee5930bdc2c1430462cdfda3a63ef5f0a576c4c141f15dbaa475eebebc76f800ba9000000000000000000000000000000000eb1a3b3bb50b7f00fb7d272816f885e63952e6281556d19c18ae3dda12f894821e286da45a811a3714c90a94832d3831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076cd4e0524f1bae32c15f3f626787a0d1d17b844fde15667f9e9426364716ad52ce75d537f472f777bd6e4fb91473c1000000000000000000000000000000000f9f2036039135539feadf46dea0d4fdd9fe6b0a5405eb1123c10be2688fec9381380995f54521c2ab2a4357eda5bac9000000000000000000000000000000000ec011f3c1f012fc2598411a4dcfac4cb2c71722abba66dfa43686e3ec2bf31b2b64d66e909d4b0573d1122ed00a5d0e0000000000000000000000000000000016f863a9b2af372f6656735cf6c18215ce0fecbd6c6c044334eec5e9ac3c4b6c84c307aa7a8fcd25849bae01f6a312251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000093d6b0da998bd9abdddb6d835b3942f09015c7d97349ed7b8368b20d806480021d368d553102942504032cfeec1334600000000000000000000000000000000094353b724ac4a83c91c6842541443171654b4a00a89736ef292bf61aa9d23ae4a0753b7486dc2061fe8237509181a990000000000000000000000000000000017d247da746446a7a8f7ae41c73a48c8b7ca1b50549e1e0ab28cfc35e8926eef3b22e6b2d060fea3d62599dd5e8db936000000000000000000000000000000000e257160db309af9045ed985d182c04a6b0720d12c5b030e32fe35ad25be516b64f439739a076af13b6e9332af1945fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058a251a92d10727fe08d3f04f2a5b036d77211b4a1c5782e7079d2741906a1d571b8acf83bc050396cf624c46a3735b000000000000000000000000000000000ca7354527093bd3eadafefd6ca855a07f6570eea4f11042db844bb172dd396c9ae47872177ce43694dcbabfb68520cb0000000000000000000000000000000014d4de2b61099557e8897588bdf3dc34f4e7db6729011af9ef8e2d0ad946d6b66d4d080d9ebd10ba950ca00c26acadfd0000000000000000000000000000000015540eb28e1d79bb61f3e037ca3249fe2ecc45f246dbc8b1c2d38d45dc16e56484ba5d61433a4e70bf9f094ad831add21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001562744906fbfb51bbbb06446ea91a5702ceb42f67d6956d640495b9764b1d7f780767a31e2f8273f41b62e0c2eb246d00000000000000000000000000000000130e51539984f815e52b2b344d7e1b20fc86803937e0a6d564fcbce7f978bce04dbb6576036fa0c5096356957c1873b90000000000000000000000000000000016b67dc7c4cf8c2f63a087f17fb5dda391bc93847f9a4b4aa9adb39e094e4d7508fda96c4bf3ee91498beaab69ec2d39000000000000000000000000000000000aaef46d58e246c8c8d71fec279b73cfdeb5d6753b5cd1c05c04f2354e351d4571ff30f2ca4df80a8533c0b03594e4af1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178b8e030c7dcfaecd654cb0302e3d194ffcaa714d76751c508472e745486fb7566d36f076c46be306a2e77a1769eb92000000000000000000000000000000000d0714bac7744a570928a237282d00cc0c837eb4d0687c404ae594ec6be94ed3bf998411bc5580da703078959b021bf60000000000000000000000000000000011c1ae0fd2ab07edc84ef4c847cbcf3f3b22224d7c52db891aa3744838da1c71c89763eed650a1b665568d455378025b00000000000000000000000000000000140ec30b8b229ee2d91f8556c3072cc43b2c24af80e1876070d2de0c8b82b89981c272f3ef0032c7c094a2f2251e4c031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d6fd8bef026009a7ec04ab092cf47ede0d1d522ad3c33da521c99247cc8f4489400b456c13febe5ecad23ecbadd2560000000000000000000000000000000017eb8401e5c78543ddcfc1c5f96dd07ade0e24bedb1001c18064eda866cc7f4e157dc1e85050e83b31f08243d1a6793b00000000000000000000000000000000148317a22edb80770bde7f651af49c4700d2f907a1f49c884c2744e50da893b92c0bd76c101f93ed7d2adc5eb13cebf80000000000000000000000000000000006a7725c10c82b4acd6238e7c155a80daff66dfc60258b93cebbb9e2bf14362d324f5d08b4c822c483f3e91c9b9426931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7bf2f2a2436984b7bd2a85fe840bdfa6a3e48456e2dc1814ad13fdf77d487904ec9b666b16d945cfdb8bc54060a6a00000000000000000000000000000000010cf79538515f7392124e939ac9deda43c379cfb8e74f06723fafc8ad69ec97753a9a2453f0abef688a1cf5e507f504d000000000000000000000000000000000916fa40306bbce7e1cfcbd7ede9cd1ad5a7b158adb351424195e7757ae7d732d3f5a728eaf7b1991db45d88e07879f0000000000000000000000000000000000b4e6707e73e7ffdb2a2e61f7811b4bef34935705c872859c30d14f52f8cbc63e2e269283a8d1583c1db132a1d726d831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000663e52411ce13fb94dae915d8da80df35c247a9a444326a82c2d8632ef5e8fe926b2b900a8c7b897d597a6fedcb5a6e00000000000000000000000000000000122349aa9a90337b2eb05257840145e05f5e51f63bbdd77339df6363f214978f5d947a70756da7eecf96899a4cebaacb00000000000000000000000000000000186fd30e62f6e9f799a501c19123580fd447d8243553fe6228ab9b1571cf3b9f07268d1918f4f06524d33813f53db58c0000000000000000000000000000000017a6bbe105ad54882151e15659c0207f5b8442213bc36621ca05ee03e1ef422f133ce59c1221d6aabd01f25b1ec1adb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018f4b4baa96bbbe725c195b37da2c0e2ceeb1095c89068028b7b515db98c83b44e986132f4a0ab9735e28f008bf9ed84000000000000000000000000000000001161e9d28fff8f7263875cfce715c509b13d880963dc53bac2329510f54d99323f171f66e04b79b93504dd11df1c52d200000000000000000000000000000000136d09931b17a6f822eb4fe0b2b535c1718ef3011d58813f87e50725fea40825feab1f1597aed5a24f9de143271ee0040000000000000000000000000000000003027df0aa589a673dcc9343163c2110dce0e4a10ac81684bc0bc97fc6ef0256e3393de90ac05ddc3c8eeda5926a54d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012a01637bf194eda5074f195bd8122c80ff04748dd98f3da2b13f893b3c8678be1033e4b7a6d17de73087dc1a4a4209c000000000000000000000000000000000c64d41fd1f5259b2f4b33f6beedc942e2851dd2f6addd01fb7dede00bbb374e73d1beaad2ba7d60f888a4433b75b06d00000000000000000000000000000000110d9b36155548e41ca1a74d3b3688993550162a853f4ab9da5dacce3f221ee736ac7de41864d343990e89d2b0a665fc000000000000000000000000000000000ab4ff8d6e2ab2972349f5631a7a09b5516e766120203a5ff8329909a883c4e0a3561920a09250ac285b7b845e0392641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000afa549faa30429e622335ed6b494f29e97e7bed0ecc4f80a03ed29e93740bb26f0f8d00b0d3a93e3698edb40fa11f78000000000000000000000000000000001025fc76d9318b2c9eff1371576ed6d5775dd762b3371b333250357a1186765c487708745a34e60a5c50920fb7c2a29e0000000000000000000000000000000007a220e67a8a4de1f22ac98eb646e115479a1c700befa3d70c4c33f5e2f770e5b457f59b3ed3134c98feb657e2d5bc900000000000000000000000000000000008c9ec26cc10365f6c276f01565a9210c85ced2b96adb368d964b0ac93f248f097e550cb2d48bc4d04105a677ddee6c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028aa73b70cc17b918ec5ccd0f29e2b417a34ab0db8e04522dd39e35a8be0aea3096192f0b81b60bebfce1d22f61b07a00000000000000000000000000000000081ef1737585f73f925eb0d0eb9c3dc03ae3e8c52f0f4069c96298eb747bae9454730b09edfede801368e32a4b59797e000000000000000000000000000000000148cbe1799cac79fe94abfd10e7882109ad82e7dd69925d609fac5f0c5cf61f0cf5de9bc9197d6b0fab77806938f6e3000000000000000000000000000000000e51a233c6065c6af57f613f10428ab17403e6dca59d96299e1e42fcf3fe86af62892b0299fb5cce06de93e3edb71a3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a8ed4ca0e944857a56aaa3d839e8b5548d6e626e8ad05c5813667af05ed776b7cd23095cd9f9621b9eb6c6baa8baca00000000000000000000000000000000176f456b9b28315c3a1a26d1fcf6e863ac33fdf55ef63f38d47f330b5c5ddf879c487b07f603c98ae3bd4823eba6408e00000000000000000000000000000000161da34fd9d8f29c356c70572cb9f90ec9d6a236f18c0464bb8d20e996112dede08ebc1f76c006c5a194386d6ef4430d000000000000000000000000000000001279e0305e842f0b34bb882b7fdf41988852ffbace2d48619fe0173f8819cb6fd27d5c2327d23a14397123750818267a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e970df2b1a6c9e6baf82f1c99c09f2b09e452e08ce528a900354f4d0854777baec0dae344b5f6edcf41cf33e8d8a20000000000000000000000000000000000c36466964f5e4e4d2f307d0df33805067858eb4e6d4a28c12e48a225ed40271706a57168c00e25309b1699861f31eab000000000000000000000000000000001727d33b75915553668558c92fd9f52c40091c59a17276cfe8ef32fb9c93e261443eef70a7dcbed62813be55ac5df63d0000000000000000000000000000000012df9358dab9da9e847c89455b1042fa94c9a9010c178baeb4dd8cb790be25741e450a73ef40977bb1c0e6b0565be3db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e1a7dc8e09f30c7daf552b910b1e6d9dce8c3aab0afd7fc8391776a42923ac23653656e1e6d28c42e31fa6cf16adfd7000000000000000000000000000000000819c3d53327d5e970fc63101edc0045eaa61061e30405070d7f9b474e530236718c96d65b170409345571684891ede000000000000000000000000000000000038dbb62f57eac2de66bbfa072dbcc6f0e6be3beba8a3ac0dceb4c51df86241689baf2eb79621741a50905616c45fa410000000000000000000000000000000005fd424cb23c095c9a6cb35730a33887a8eba7f8b701e422e5c88b617a48338131eda7914cec891bee983db8afe6aa5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071e06ed9d7ad3de3feed90cdd56850c0d316d78e25676f7510444b562a38dd2bd3c87f2b44ed1678901bc5385547928000000000000000000000000000000001682a9a59ab618bec193babbb69434562aa1f2bef691bb69acc2231f2f6e001489504ae6af76872da7df4b47c53e0217000000000000000000000000000000000b46205181a4f65266298631f1bbb8a520c783cd3597c019fa44668fe51ac3fc06a16810e4899bdfe801fa91535378c2000000000000000000000000000000000cea5aaa93ee5feb0af9b29af0e8015b8fd5cd13f45f4f1e740a521c3d90f5aa8619b2ac517f8b3b2a8f16062c33b23c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f9515b3aaaec44d5798a40e1fd7faa87cf5bee610c77918a8bb224cd5a064452d486da6a9c3b4b1a0f18fd4786bb91000000000000000000000000000000001696098bd18e1ae35068af30b352d9e31f610b7136faf976044c8d576b5a4a348a173a484e0a28234fe8010a4cdc55a900000000000000000000000000000000053c8678348b795eb0e9635aaa3b9e0f5ec2801c3f9d749fc26f225a3e6fac8b9794bdb44a8de2904b78cb20ee26ab2f000000000000000000000000000000000f222aa7cd6e197af805153876666a9d959139b7f22537873bbeac9b012fa9a832f7e3e70a7b2834d3fd1643c4b2a52e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000140da99410845d47701dbe9ce0e2451afb065a7a37c3615e954e21fb920dd7475f5e492ff850b71d91cf95b78e33bb40000000000000000000000000000000017851b713293f5f5fa4b97bcce3a28eb362f72582392bd90b1dea69623154a2f9907f93e895c579f3fb0e9f680c923360000000000000000000000000000000006b2c5837ae2c4f257ace740d2bac569c9d269b0118fef54ff02d2137dc770770a8dbca479cb8dc484e6862e8914528e00000000000000000000000000000000171c41e295db325aea6a21089da400811efecc7f39c5a2b7dbd89a2307454f7b364d289bb0c329c82af80607df78dabb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000003d4919618b8c093c2e3f1bc8766aa309723873337f58392a3186b6cae103df78bfd30366e3e7787a6518348f23f1b40000000000000000000000000000000014b3461ba810acf08b43f30f0a823192f09e56f8090da155ae617e008759ee31e6779d09e65ee178e7a0f935035598b400000000000000000000000000000000193d468f4ba46f577d061d9e5d13c9c1f1596d9be63104bb395f4b9f6eb46001f5d580d0859d84612212cec289db0f3f0000000000000000000000000000000009e9bb67d436ce09d22f1065dfcd598768954a8366b0665a21e3631ed2dab00b83eb560c7a418df005f86d0e1accedf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ecf18b15b1913a8d62999fbc9b63005760326c68d8c1ab99abfec38bc60c9b98a6b2e5b51564ef6e852033d1b4d5110000000000000000000000000000000002edee3aee20b89ea1b63a8971a31da3cd78e5fc449f71c5763a22f9d932ed34f8f02309f6f27ac7f47eb35fd4440b10000000000000000000000000000000000793b40f5cbf4283110f0ab18db42b1f8e7ce8759937c521788e101417194502f2b0e5790a6fe13a5cf0aa53521454a200000000000000000000000000000000101c9542049dc352f7d7aa0a2ebcd204c916abf087f64cfe6dffaca3665afa6a07cc8dbda9e0cd7d6e30b89f6db5c65c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009da981994226d2fd4ef921154367646552d830ab8a603b63aa5966aec7dda6afdc26fe241a01884da970ad0a2394ce8000000000000000000000000000000000d015b1b7b90d26d65bc5f3cadb093870e0da62eb8412b28787e57061490224ab71be8f778213ffd35585c290cdfc5b9000000000000000000000000000000000de5e758fc3a95382f141ec7102cbc8bff65bb68cfbb42bb3d497ebb3726e0de2cff1fb3e44cedeff33e3b99150155650000000000000000000000000000000005ea02ccd8d4ae83acc97a8d7970d81515f3fef5a9ec48f5a8b2dda1f112ffed53c4cd9bf467927bcad618d636acee821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002466c4ed7b01e9779358cd4cb2df8176be3693c934446adf31f430425e923e8aa6fc5801b1206c1fc180ab51e79998b0000000000000000000000000000000009262e2c61fe866ae5604cc774f0cbf995b97c67901a93fbcc2174b11a72994edcf0f653be07e5bec20378d9c1ea1695000000000000000000000000000000001592cd7d93cca45a3e8bef8086ad6bbd2373c0011d818bcc7fa922c45403d6928ac6834a7c4cef3715678826db387626000000000000000000000000000000000ea86e8e3bb90103a24e3f5d2d87f38956f1589ecf40cba32361f64e6ee0d73d9a733bdbac7777fc06e0a33ea4488f531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000192ce668a9f162b8f3bb078eb2d116c65ff8e3ddf8813568d98a0d304362ff1d75504de2689d4fc9a6eb24371d8c0fa00000000000000000000000000000000056fe3e69b69e2cde9bbf303af9a37532882c0f77e87d68ab435d4b60e33cc19249b69dbeb90d4c7bd1ff789f96d5c060000000000000000000000000000000002f90136f280ccb05fdebf8a4afd566c21a1136b98dc875aeb58761ce21d6d657304c6e42366154d25831727b8541e89000000000000000000000000000000000dccdf054c7fa1fef8d413ad389ccb9a74f3a1b69473e6fba4063b71bef190bb2e8da68325a2602a3c6919d454b8828a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a9d57ff225c1251744b7bbef77afa32fcab4bc04a03214dba09d29299ef9a7f6d64eb94475453ec1ee46d46a68c6000000000000000000000000000000000c29b723a9efeb891dfb4d2c6ac4da7292d283e96cc51509565dad2623001ecda282bab0a15c966a5adcdd21be0e752b000000000000000000000000000000000d54498733fa68d38d0cca8f0d8f12a76eed3ba7057b448e80445c20a3b54b4d53ac5545925c923a87c37820685c37350000000000000000000000000000000019d2c37968b5b7600f025898310596cd736ba739ea16fdc07d9602d81e49448d88da7c5ec07c79886d8ddf663cfaf38b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000749f9c8e8a202ac6568279abba7981c94c2d81ef64eecc6e3e5cc47cb5df5ce536a2341bd85e1c1e8c5168f5bf455ae000000000000000000000000000000000e4a9d5e3205361ef8490d14444b4bfc0d2883333072f03b7f2d3f50607b4925362ecec81e2d7f0d3f966203492db7040000000000000000000000000000000000f8f96e04493bf61580c4882e4e0b2dd0e0c41899b2c7c2dca8e2426556b047724b8042ac5da4ea167d6790f0901409000000000000000000000000000000001967aa86c51fc1c688a1efcaed6dec94e7fd0fa3059fec629fdb3d816b0d73674aff57bef487f7d70049d5823fcd5a921824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058aed5f1c4d9911dfc0e838b9f19ec117613316a5d956b1b752b9a692790fb80dfec4882acf7bd9719464e11fd95713000000000000000000000000000000000b8fad375b6650daf07ad8524a177da8c43aa002f06a8f7df561ed321e7bc64635b0a26e096342d631ee1c28eb2d1f2d0000000000000000000000000000000019173f1014c8ba22214fd9b43aa7563ac47e3454349fdad5b38f4ad3b987b0ff763b4b51781f093a0e379763d6575d750000000000000000000000000000000011f150858655f94c78bc521c66a65d66df43c515ae503e986e06dd5472c19eef7f1f66e01539749c4a3d38f10e16b94b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e040eef71cbbf816ff2a6e97dcd2202f186a3422bd125502e8f58b3c763416913f660e0c2fe085885ceade21d815a27000000000000000000000000000000000584f38d9e3b117fc078f396d43bf4632fdc2ca9c8760e04fea54183745a3af347c06d3f9fd6485d57fb5872811b0f2e000000000000000000000000000000000c007681cd4aad14ad171d56d9ade7a979c533c7eacd3c67112caced46d14f810ed66adf78552a7c1a753ac45eda2c3b000000000000000000000000000000000c2574a5a87178a1a7c50c7c52a49e25af4bb9e80bcf5017255709377171ff3af28622ab3b73d6732f5c8abae199a1991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d1fb347504f44f3075ba9fc8efee0ad7af187deec47b23a484e12535e5a1e057b513d164339481bdf1b621116661e60000000000000000000000000000000006d60b4cba1a5ec145df68c5991598578d2857c5112abf2459626818dae7824548f0be94d4c994eb1998c6f6ef775ff800000000000000000000000000000000126aa9d653ad940910d82d4399c79988ad7cc11e13c1d01cd266aaabdfafe6adbbecebc2f2e62e2b6c521f1cbc99f8a10000000000000000000000000000000002bab14af46ddbe3568fe83a98dbcf466650b1f358061d8457ed862ec21bae8905ac0516e5f8112b8282cd137f9c34321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007d0174fea59346531a6f9c9df63e0fcee2fe66d9d26d51849024595c20b0e37bf780bb5382b7a1fa09ed92850133b72000000000000000000000000000000001995e537a78f043281be3e56cc5244a46ac65e96bb104b3e7334660aaf010f910f1f49d6d6f685640ffadf511483043000000000000000000000000000000000112f6ad4238fd03aeba61b6ded9f8eb215940e61645eaa5485dc625ae114372c96a90bf750a914e78e35b69dd9c55f8e000000000000000000000000000000000d76230929f88ab08d848e02585d75902da73376197d0df16bc8e3ede33a66580b37b007f64fb1ee76302b98006ca52c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f42bf1faa226d1d2011d769cdc180e5e0afaeadac3c3fbfbd4c6d7d051f6195698c71a718c3ed830f668a8f9a43da04000000000000000000000000000000000c94a68ff2a3d815b65c73f8b79019c0c90bc55d358d337c42cef8296d7dfd17b70dadee89097815a202c35bf2521e2b00000000000000000000000000000000052b39ae3f7d5b22fbd800c8c77dfb73cb325011584085c4d4d8190affd9671d5431af3a19a905a9c7d511db79bd0427000000000000000000000000000000001382e81c34262f9dbb0e16833d7412574de6cbaeb702e203c2bf64d6090863898dda51feb144e5b95703692f5755a7081824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffab82f4eaa01fde821cbccf7ca413bba724fab563037ab147e5a533c4f99595f6a4eb513af5d261e02302fd5ff43a2000000000000000000000000000000000cd4de9fbad27e66cedcd4ef2418ec7901631c05cc4d72ba6d3fdf108b159fac209ef4337f98b47309f2dd5d867ffe0300000000000000000000000000000000196402bc33c82bb2eb4615f2139427858b15432484ee2adac67feb4eb560a321387936d0c0e1f64ee8f88111b4ab1aff00000000000000000000000000000000096e2f7de7fd3f3cf22ff5aca99efdcbb6b5355d24e74f96bf0f6400e57571536e0bb340c02777bd103e1332127b0bd31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001775889c8c3aff9369bbf1a92ceab1b1de0fd7a0720d5ce437300023f7a9642e605662919df661a953ec2524483bb32500000000000000000000000000000000174104a77d2df75a692b25361faca47b16e04dfdd49475b88505818bd1f01907f4f3e22cc988f12f57335ba557bcb1fc000000000000000000000000000000000a7e16d4e5bbc86ef3238b8538387f8d188a370ef4bdc30e44c2e759760df78eb05203fcafb95ad324f7e02b8d1bdb420000000000000000000000000000000011e27c3159ed5d2552f597f34e3cdaf2318174ed03892109344c81bccfbf01fd322324a00a51cd66f3ff4773693a862b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f5aa61b6d11da86879ac53893e0f74314b791a7c597ca7fa4c0e0f6232235220272b4e5c1a42266ac75508b88becd00000000000000000000000000000000013805ebff265bd9468f3ce46a52977af96491f40939c0f99b727057037fa46514504680a757057d6b8d9266cf8c35020000000000000000000000000000000000c68bbdd3dbb97ddd79a56ff0922099268083e131843fa68c51f05f16e4050374806d4eaeacc3c6a84252d6ea80da83500000000000000000000000000000000133c3d15973efccafb18ef4cc65a64f2ea5ea1753b18b82b50a9282d70e8e88d5bc548528ec299f069d6f33e58156e6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078285b536cd3ed8d6d56ea3ad2b73ca842f24e29cfd58b3b1e48a2cccb152d0212abc03040d76893bcd0b80f0d60be70000000000000000000000000000000015ee6c2a8101732709db0c6dcfa3d6f7d3cfc2a6421bdeb3efb83f75d0ccae1663ef7209037d9ced750ef08d02d4a94f000000000000000000000000000000000e2b9e3dbbee317ec7a7d6dce3e58914b6bce7bc5d88b2b809b88deb8dfdfed5f5db56590643c03ab1f7c25bdd7162b400000000000000000000000000000000072b0b3acd33161c0b5a64dfc344fca2d5493f8cc1fca89495705c99829db60b158b0168d7acfbdcfe5e6780966855b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018410837b67fdca6fe90ed41b2016c7e6c1e1e3a9654e7673a893310ea850eb22f7cef09795eb7ac19d242e073497a9c0000000000000000000000000000000011d2c84dd7a198f9a7feb7a845333eab50f130d649c3c41d711bdfe6905c2649075fb22f3578a59abc8d7519d03f28050000000000000000000000000000000008ca2f9f5d53befcb82f50f33e40c497abb84db4489db52cd90b30004892608aaf2168c1efdbf6136a7fb336ef5a862a00000000000000000000000000000000038914c94061e0553223424607c9a2fa6073648367a84177d3b225bb350156cdf613805908500941ed0af1b4b2d910001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001004335e05f22dcddc16b676547f05c3506e0ccc7779a2286f8392cd0f53486f1ce626fd2f83524fedef81022962b52400000000000000000000000000000000174b99eab6a1043dcb718613b7107ec174389ad65bcae5d7db347250f5bbb783a3a93f1537005f59fde688d9dd4b829900000000000000000000000000000000008d2ab5b814fe56a7ec5df725abd3f57474181d1565b37f126de53f9b576ff7aa790a4c006f58283958742a39c56bc4000000000000000000000000000000000db257a1640668e86c1346d87d50aaf631578bb222c1a8dd11564de41bb5e2caab9f794c4276c0afc59852d781326bdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000807d75e4bca80850848161605bb8d663a0ab86843c7f844e72e2591e50032dc255be5f2cc861a1034fb619cbee3f33b000000000000000000000000000000001855bab65fe3c6f743f8a8283dbe70e665fa7d6eca033965a8466dd603f75e609a4fb34efa4bce126b70ae035ef10045000000000000000000000000000000000d433582fa257e610c780834806aa84487d46a7fc3c270178db00f4b390c1d5fa7e37dd2c5a17646a2bdd42b0678ef6f000000000000000000000000000000000a1204356667744d1fc8feed47619037cd030aa826ca86c2e457fe7e4384d2baa310e85b62917e9a62646a7962698e001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cd601bcd60a127592d562d7ec90ec95ff727c3f712872b2232a40271f61c9b11622df969ed462767ffa4941831446400000000000000000000000000000000136375639818ca53fa66151b66a3cd5c8c2d7c02ff2d244b57f2500b143be9c78dc0de9bd9ac59179ee48d102b3a8b640000000000000000000000000000000011f0a41746f628211c2cc5b4dc69023a88ba5ff47fdccc37a63cb8fed7d71fca224e095b28e22549fa1061f071247d6d000000000000000000000000000000000721f6ac28d8dc81918d9acfd0dc1c270b2327226ef1f7a28570dd6c0b20cab880eeb4e04203da283b7381f514bc437e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016931e5efc15bcd3cb42c2a499b609297e87aa20380877c98195d11e877368b6fecc1b7cf34422d84a59b9e34ab0daa50000000000000000000000000000000009eab1f6698c48f514548dd6697da5bb7f70fb2cd4c642dc239e4477316760e85cfb91d62fddff43a60c5c432a3e7a17000000000000000000000000000000000d17751a1843b99634577d6ad06a6fc531e64be3d69b4a446f6f85773c1cdf4e0c001e75378f284d36ee8fb0eb7c6e4d0000000000000000000000000000000008002e976538f21fa9e6c08f9865ae976f818126d4218ac99a21b9e46e43a087b52d5c4adfac3912a2d748179adca9301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000188b3c7918cec9938c635c93ec9be68f1da22bd1148c9eec245aed9c8a45c5eddba6bd56f5846ecd66f11d5cf96dd3380000000000000000000000000000000008a622b09b9f6394e9792381e735367f0a816902a1e03f03201a37c5dec0836518ad7af15de701cda4d1f06f93e7f9ab000000000000000000000000000000000be9c62473c3203be33614525bc9bfe4291128b7dc340e566ba2c1fae3d62a07139298da3f199c9d23beb6dd9a097bfd0000000000000000000000000000000009f66c82895e7738b21171fa8064800fc0bf8f7c29a94304896e37ecfa715a794d67bc2fd92e441940a0c0da819786071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024e8ec5ae4e6a10671d78cd892ad1c959176ae3ae6e7dba532fd24d6c93e80665be61ccf9912421fa5c44600ceec12b000000000000000000000000000000000d6feec9e73e8e980de822d5c99282101a94737457aabf18cdfa1db6ee08c0e7e2662f499f51f7e32915d0a6d639aa8c000000000000000000000000000000000f65a619f1cc78bafda329dbd10fa87020b79e199e9001fcb71598d3749cfd98914dc532e5ac64b307f3ebf413cab2020000000000000000000000000000000003aa0593fd022d636048d2da4aac9572e1e7f00aed2e7f17561614f0288e106e9f39d7bd036f2d874067b7a2abd4f3d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f782e0f6a0c821cb4857a9b8ced530f84d72c47f748337e28f3336ac9c9cd7ab27e98189f6874f2ff1b53bedb38ba780000000000000000000000000000000008f7f862470ca9fde7026de47b63a19150bc9643a9c35bff58af26e3260cf111f1f1eb220ac667e09e623e22fc8bf5b0000000000000000000000000000000000eaee1381a7559c4871075f396d4c94a823779ecaa78721b9eb87b1fff40b09e7b90252167651f54018ac6f00e6c1111000000000000000000000000000000000998af1a34d57327491a763171d65fcfa16e9276e024a5db0dc15b5afd585d2be74f04ac76bdb1c48a166043576db9161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ba3d97b3014b1cc21993c52db64e142b999e6b4465a601c47fb024d8150fb088ee3c94a7eef795ae44984207521847000000000000000000000000000000000e1089c9a02f037e96707f7dd7a22aa87603e0c20c2978febda9c1004fdeaefa9d594eb665f085489128a0510c5a9207000000000000000000000000000000001213395ebeeb024cd3e48649c3f9cdfbee182c589753684d4cf32a804729c33b689dae2c506f28711de5142106375dd10000000000000000000000000000000003d790e95e5548a8e38200becd2c9c4e5e2b7e6323c9aadea209d0ba4257b7822edcbb9e436d024a0b4745fb8b3d6b551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018886c20058aba8e5f065d3ba8cf412610228f7ee6e7375d7cad8fa6333c453b076e1cd84bdf45d13e60d929710372f2000000000000000000000000000000000744f24ea2a234caa355f76074251f6b08c86250ef8065c6c7d22b2e0a493fb4e50075eef3b1e18dbe2d404ab5b807020000000000000000000000000000000006b94c804ead83f59511acfe276908b23ca670c71bb434b9e4924ee83af305aec25d35a6210909891d8a93591991f5e60000000000000000000000000000000006eb1e523d3670f219dd581701088ccf2ca773012a09e8f26b719e220f6ca961748eb488c59ccdbc593817116b3ac6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018de2eb6dfedd4051304932995d53d921bb42ee9f23189044e46a64d5f0236ffbc7c4e6e976f69a8ac5fafae1fa755b5000000000000000000000000000000000222ad5c50d6a60675822794ba6c0ca1622bc79bf2d9c99bf31d90245a6d1c78ca69d94e170208d820688367e645cfd600000000000000000000000000000000051c980111309cdeef42f2c49bc237afe7fbd30dbe99caf47fe05a5d5d156c54226b8c6326c6f15c313a71ab1fcac1ca0000000000000000000000000000000017b004e656bca2effe85acf6c74bd54025a2f5101c7d3ba8555b303a1121c0bcc144a837a2c5037a342b5ee185f89f2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002dc2d7dee31ec70af7db920be7e7a0301860c1c0cf0cdfb2df51307a17722f02743102d59fbd93c35b698bdec9ffff800000000000000000000000000000000127267625917b97475d75842e7000a84eedf8c5f7dd1195bc081a91d76e1a4e183472c4f5112c33273bf27d0e6c3e9ab0000000000000000000000000000000015f24487c96c9d063f0d77fc9e45355074f0519bd41aef22d49fe54565f62d0a322dc11f11c12ea67321488b6aea9617000000000000000000000000000000001796b0be2e9cb82eab98838442b972c679eeccb1c6ebc3e09ec3b31790df36a55ee0a51299e82f9487a9a1dca581c9291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130dab481733f795f53615eb4d9275ba3886556b2ccb1592bcf7ad344e72d2e3df254df66df5f43480c13c3e940dd637000000000000000000000000000000000371096973c7f529481ca98db317ed065c3ed8db284e33b6f530fb3419e6ef880fb415d1d5b866664c22f3f1791b9e930000000000000000000000000000000007ee6d74c425ef8dc9498cc712128d1f4790c5a1a1929e26cfd6cf32321b795738f6f014570a125f52310aa8287dd7b80000000000000000000000000000000007d592ba9cbb8409c485f29b53f2cda358cb0e3cb01ad401520c61f7c0de8eb9b40ccd031ce2262d785838cc0f50fa471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fec88aeceec8d7a550ccdc99c9e1df73bb98d6208286edf6460021abe4dc0f92ecdd77f836d509f6fc529713980e1470000000000000000000000000000000015543244453a07058a9dc04d3d3d7916d632c426958b67f80d0529ce219a27925d200899c2dc44404c4f9d6bd8492fb00000000000000000000000000000000015d129ffa40b8229a084cedea2097a3333cc8110761fe0184f77e400d945399350f51a43a2045627120a1ec390dd7a2d00000000000000000000000000000000049aa89cffc789daa86503b6f81ad398b4abb3e406cce3aed3454e5afc70782f33c4de9bb469f93faa4c43d708dcdd1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111c3d745df57b5c1cb9f8fddbb4ac59b186b12a9585d867cacbe74b8b51c26ad8df2c3e6be641ec4d44168f4d39ba40000000000000000000000000000000000735bcece0fe809aab55e85f52a5a688af3f3e47ea989a53fc8c45de02cbccef23e2fd603aaeb0a9a6c96b1a90a01f8d00000000000000000000000000000000118e13a2b2301fdbbb346de018e41c5ac2d55f08064047e8cdf7270a97b9e04579c52f68597f16ada4dcf0b10a2c073f0000000000000000000000000000000012cdc61d5c0161e444db495e731f966b2385345ccc7faf62ce880d8fb861f4d0663734444e8855c84f62fd22fcfdc77e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000145c8f7f1f1e67165374172bdef4bbc13b35659c19e45c6f5a88ff0e469f2b3ac207e60f43ac89aa06caaa1d01eae82100000000000000000000000000000000128fdf4aec3b2c58f0461073ab1c1ae3062f415e6e3c507793f0060a1b831f6d0b54a39174329e8149072f3272d330fd0000000000000000000000000000000008f4720b4801dbb425d3501cb1c7cb8b9fb937a8771232497f0497bdbca6fa4bf8fa5ba5dd5080805af6babef72c4ad70000000000000000000000000000000013d01bf4d28eb5a0d47ba8664968ce1a47fedcfb400f632eb7e7c9441344c5c9f66cf7115a15618c5abe83455a1257f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a734999ebbf8fac1d7bad9c580f6288c88aeecb2dc56bbbb78a1bc9a1bada3e9285cbd9a746d5c38fa56e7ee6b1b4220000000000000000000000000000000013eb920c4d49e4ce2306391c6ae3155ca42ec66451482515698dcec23d14a3fa8f588a18366af430bd3588aae112b455000000000000000000000000000000001680973fd55f212304b4794fcd73657f72d9c3a2a26f711dc992d7848d6b191d7f1b291a5a05b44c8be74853c52a583600000000000000000000000000000000138e48167b972cb0a6ace87bd447df069b08f01051868853819bb8b1d4e89da3f5df8ceac1e891fc6dde7f0931f63d4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180898b912db5aab074ff174577b3c97f3834d2cbbcacfeb6cd71d8cf8ec85f49c29b27e9ad8d35bcb0478ab3a8d03c00000000000000000000000000000000004029b306cc7f7b96f28bdb6613dee65404351beb8a320b5f42f6f0e3c7740acb5763652bafabb60a75ad4d49e868cda0000000000000000000000000000000008234e079d4f066eb4741f90307f3e23d082ee81fe83a866d8baa8e0326199b450e4a44525ec3b57e32d155923357cac0000000000000000000000000000000006041fdda835f8541dbdbf5c3cbcc1747bdd6058680e6fd28f0b6a2267f59e8af70af94b012ea5ea3e8085f02b4311701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016f797576dc02d8479bb040a39d65ad8a26896c4f86eba7798d562b62a1bc209cd5c393377b237656df889d7b55f3b7d000000000000000000000000000000000d3dd73f97aab7ffef9e6166e234f1249a0ee227e68bab100a7e5bbd3aa9bfac4eb539f24750848671d803b3806985bd0000000000000000000000000000000001d0d4a2455395d6a757262652fc8247da224a1b9ea787c73cf60ed3615f58587b556a228769921823d448fd8aa6cb14000000000000000000000000000000000df6924fba8acfba46b353e2d0740a51816196d0e02fb5229d7381f0fa17f65b976abfb21eaa15a3ae9a440d1b93e71b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab2a294c4be1b37002ac0a799d5c7029f9314a841e2b909f699b1e1dbca7f03fd25f66637c06a4c7550ac6fedbb53ff00000000000000000000000000000000156f9944e24b8a584d886f9617c638e94d9204bcc5ce96194cc61d438b07bded0328634a21a06a71e6e8b9902c9a34ba00000000000000000000000000000000020a455603c3db1da1b5a1e6bda6820a13644ec47c85925361b04b77ba7814c14c782be41093114078918f098a13639f0000000000000000000000000000000004a2a3aa9fddf69b08716e035aca16c6078df90aace92eff273228dba332255e2b97f630b29aa4d794839bb4f3becb4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000048dcc0699771555fd796049b07a73da3c51b659270920ca66005f3fa6a4eaf5dac3f915b96352e427639f873f650ab5000000000000000000000000000000000bc65e331774e058f4625b61cf204aeacbdd7949310f3eb0e89b723b03b0a927eac1550dba7da6f826b38107fbeac4d5000000000000000000000000000000000e7db32142d378294a614993f18aa71c714f6030e6e9a23ca584ea07b8515abd268e5b24912ed7132a50af40feaaab0b0000000000000000000000000000000004c623688fcc110c33295fa1a67c5625033945991c1bb61020e4274ba15e13f1ce0c7f61cf3d99f1f117bad16be3bcfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002761816f76bacb5efa092a028aca0189c9d9c2d7285018668de48dfb8ed0f698417031c6161b4c8683c722b9b767c4c000000000000000000000000000000000766b5b75dbd4330964f0dd53802960ab42118fe0addb13b021b439e1cf0c8ed83ea54292c547ea9e57013f97bb1b55f000000000000000000000000000000000d4e44ae0c1f7500a503c095f29202e427209eec47d0fed6a8c3a7235175024c10bc91b58416e0f767fb2532898401ca00000000000000000000000000000000002fd7b9e3bea99a7cf8df4d190606c1ae21bbcfb929f077ed6190d694fb69babac8ee6232c6984ba6ece7f53dd148fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001547cc973208431fcc7c9ae7139b82cec1fc2e0f112a459935cc93f6203c7c7399b674361c22da069182409cc6423e500000000000000000000000000000000011a1edbce56eee33c1f8ca488a4f6186634835470fe4b32614d978bc05f17447404b95928ec3f8da28e06ba1e007d7d2000000000000000000000000000000000cec04d085f4bee0e0b5c1b9ddd908681c87d619b166c572208a8d5cab63cedfe748bd5af2104225cea873e75129118c000000000000000000000000000000001482fcb626579a9ce02a12fdf961316c942e9fb80a58a4115b0e9c7c151ec7f58af4ea174f648755944b2497557e82451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d972fc019823e4aae36eeaef4b85caa5c88385a2d41597e843275b84a9f3e4bb698c8d3b56b7b244502e1e44a92f7b30000000000000000000000000000000005de897555c15efd2510243b70e0ab00252feb1ec0136551ec12cca1fa6c527108fa1c8a2b30a33fe3f3c30d8c4b47120000000000000000000000000000000018935f3b9a5630e88d791c32b1a4a7ea727af82d7dad934678f801239870b95a66f5373e1a3be98ab8f7922f7e21ec1100000000000000000000000000000000171648a63c99c19e2cbbc2a62e4180825a40ebfe8a1c4007e02a4159ea02a4a06e8fe8c204e1d13100df299df2c2f9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084d464cbe91ff06d34e8b5be2bbab31d8460e2838edaedfb485c95a8499b4127bce7bd9b009abb917e6a7da87bd73fc000000000000000000000000000000000aadfdf51805e6536dc5a8ec9605dca01975a5e74b1c1b730232b84cf3c1c8bb33dd520e68fce55513d545d404de9bb60000000000000000000000000000000016765cd7ec4f04dd855a57f2ed5139db164fed1e8cb91700b4b1fa7605c7c2f9138197691fd12014a4367d5f4f6516050000000000000000000000000000000012bde76dcf910eb1569434f83fc1662606178b7518416739647d3721d4963fd9e77ee14dfa866afb1384b80bed7f86781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e04ff9af791c7a5549a6f32fd7017bd9a777fd165153f3d6fdf9266f3417cbce52c557364f54f4a5517738a7f981920000000000000000000000000000000004f41415bb88dd908a061caa3216bc2ce297c985634df7805ca62f3ad2bea3e3021544720f5dea5b97df60be7d94bfcf000000000000000000000000000000001484523a9da1fe76be8fd04fd5fca187109661b6bbcee44b6c11984e79c48bac2d0fe8c1617d1189c7904961c3255af600000000000000000000000000000000002fa75a986e781bbd295a2eb613de0d515769a090c5e43957d6fda23e91a5d203c9c5296c849d76551643d96a8673391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e01cc12acb6c871808d7c64ae26aac9eff4b9a827520eca39be5a9c414fd351a11cc8a36a688c1dd9deeb60b14619e0000000000000000000000000000000007686101ab3993c9d383f06350e18771205134a8611439db97edb44f024f397bf69f662b4303a8b8653786a9d46a5535000000000000000000000000000000000116858a905b6f82f225e588b846c1c7a7edf9bac0241c2828b917d100d241cbcf5bc00d25848c2471c7244c9e6cbfa200000000000000000000000000000000045914d3c4e48c5f99bb9cbb0716e62501f64cb5ea8a7fe8ee18add2c732d9386d05d00e4862f3e865185a9f0cd6079c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000998e7995633119f1daadf2bc5b3fd55e4f12f024fa965b29075178d826dac0fd9304c8dc3969ce2e99e3a9d8b4054360000000000000000000000000000000013b198108ee1a629ad004f55f742fded40cce51e36a5d6366e53c946a062cb2b40ebc7cddcee80f5fa1866b81f7028ce0000000000000000000000000000000015cad80c664792f0279e70757cfa32fcd4a55e4879289bf3bcd02856bb00baa0ac43860b6da4f58c9f5f3677b41a9f67000000000000000000000000000000001895c504538b1dd783eaca741b2eb1cfdac62a9a8f39dc705fe167c354c4498d725cad60807afa97502ae52d6a75d70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000036e54c23922b2729c6f5d2f4d193ac65d7f0e72b74e1fab8ef74580b8d6bb52a70e4881d6b3236a6d30fe0b585cdb69000000000000000000000000000000000089f6669bfe1fee2599a2a291947f099860c70e44ace42cbd60eb4a5a7156218778bc5a44ca480a4ec0363cbb1ec42b0000000000000000000000000000000016fba274570491f8577aa8acdea156f7cf362ef2f25d42cd2228d16f4c79fcd3dd5b19b1d2dd8c1224761b688a3419780000000000000000000000000000000011a7f75f88493c545155f3ed3a4c77ff9dd1a0d251ab1f1f51a89f72d81772fc7c5bad0042329584925fecebd4e5f25e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a81cbb5f0ed38c0d55b3526a5039a858b9c87001cf363e45d619684901de11a11192dfa1a616f9e836f7a3272538d800000000000000000000000000000000089a9cd7169cff75bfc41a71b4d6f2b76fe16b37ae60640f785c6856f57f938704eb580c14a92b6e71e3cd9f01828285000000000000000000000000000000000574c2842e397f8a633da2d2905739916e6c8889baa6a9ac8c4fad446ddff2542f0aab2af703743d13fd3adea11ff823000000000000000000000000000000000c4f1622b505f09796f765354db60f583e75835ca2137d1dbd115c187fe894ea2e46ce334a122582dbdbc96c9d88dae91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000483748eff10b3cf9debaeda46400d785a827c5545c04f711ccf54143d382177a4bf892f8b6349620820d1d3d0b6bcc30000000000000000000000000000000009cfc6a3677a6093025a829071c32e80d96b669f2fc56be9cabee0b85b160c80cdeded09d24147a81c8f9e8f43338af200000000000000000000000000000000068793a2cfd31752177336c187420486bd0d11be0923c3605affc4e29eb449c442871ffade9348132b6a5b42b134de720000000000000000000000000000000007a4e77309675098bee58b05e6c1e71ca028c1ee9a69d4e518f5010bb0140d340a3af60bcce28c6aff14904be09e27fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e87387196947f1d45157d02b6667ceecd4f8708ccac70a7738bc1878f008c62a7bdbdc0c5049a7643cd17d594df24700000000000000000000000000000000002843e0f085420f74e12ceb8bb4b683719b6f422e555fa2178186440e3740a8de42feaff88e35280ff1a5e9423e23dd50000000000000000000000000000000005267e1ee025371c3bd478d28f649f3a5b030ad58226bc7e6a4e75c2f57fac05e248394ecba6ff0fb9d494a50699acc50000000000000000000000000000000003d2dcc3fe5eb7c7d9b5cb6b7fd023907195e9feae2eef03cb9fe74158223d0d7dfc7881657416c1816564b9ac34b8fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a0b64dc2a5613cc839228d6baa418fbf1c138d929a494e9d56453e8238c9aca05855b2a3356fad9d09c1737dc9bd7b00000000000000000000000000000000079dd3e4fe7f1230159555102e029578a45e763709231bfc1a06a49a555ae99f2edeb2a012788c382c7f28a84a5057380000000000000000000000000000000002adf35810a203b574508e16e0b61bb35250b24e286fd02269aa7242096a40947b377a5d11c600b8509a304bb0a041520000000000000000000000000000000017653192168c165be38380fc102d8825f3b88273ae0f96d0cdd73c0961a35b8951a5f9f2b527a623017735a7abfdbb531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c2baa8da7ac3e766373bb71e220dadfc07dc6116b3c51c76cbcda1f0c4d2afd4ec938efbf72c3942f1d800e5735195400000000000000000000000000000000079bdad850399e251dae9411f43b4d5ac6d514aba9dddeb6d81f1de0b0a492ab81bb55b39512be473a6a4c8851608bca000000000000000000000000000000000d3c0eb82a2ab37b09fc2f8d5c39c5d406b903f0adf71e4bac445f4f46ad406ad66524657207f5757fd853f0d09e985f00000000000000000000000000000000081ef04b174d0e9caa781d081df596a0a7c5e264a46ba9698e5ca535c3dd9c26f9dc1ba9585829bcae0a7b70e00c28831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001650af0e9b1b286646dcdfb398badfc7b7a7e07f7d841d67377e589321f3ac11136975e70852e731c86c6f8674ae4e150000000000000000000000000000000007515b6d8b201314c3e026628f9bd8c58c23b00d89926b08fdccd3ceab478345f59fcfbcef7b5368251f327628b128cb000000000000000000000000000000000a779ac28fae4ca9b6c9ee085702c9c4468d8ddd91c6719c418ec1f61999e7ff6ceabeb9cacfcdc633f50abeddeed2840000000000000000000000000000000012eee851d91854d0ce299be5d84822e23a22c9aaee84f5a728fc48afe81b6d9dadf9ff9de5137ae65b5b5e6f9f6695571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9711071a703e43243c372559663c3aba6d54177c2331b4dc5956fc568f42abc96eeeb68aafaaf19a0d2780c47309da00000000000000000000000000000000061199fecfb76c34a1e1128e11eb339a335ea2f6826dca8ee079c07e01f06aeb44bcd05f05ad8c14b6d7441d962336fd00000000000000000000000000000000081d1a83d642787a68f4362bce9efe8ececccb93461a1b44a0965e887e84bb830062c8940e64f230d07148ce4460dc800000000000000000000000000000000009b0b09d5a07883f73e01039f19346e0eda758dd9ddc459ea0d58eeb07ef9944607a408a09f96b0d7f811ef4dce3be371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f627f9dc9d3b51460899183abd4c9121843a6342611b82bbf19ae9ca53c18959cfb7675d27d7609d664b9fc030f667c00000000000000000000000000000000037bce7919e8409205fbf65a6645982fefa6e49fe0e792116892d6c656f09511e7999e574b70ef713c14e53940f40dde0000000000000000000000000000000002ebbade93249f52d5981d2b4556cf6b2189e526989b14f6d35b8fd0a0b6ca4037e89580e20b03c7176e9739ccf0cb30000000000000000000000000000000000bc2745232b97aba942415df7710094c4c3e5cd5e82142a697ceda5d16daa87c354ad4c616ff62b49e1b50271975bf5c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006599155e7224075d1258ec5f63e9c881c862bdf1405aa3500eb8574f1c6693bb58d23302b71901fc82207a36e53a7d80000000000000000000000000000000006605230b82faa3d74c7ef52a6ff047949fc2780080ba2240c004a35730f5c9631845b3d705a36efeba584d92a1c40f60000000000000000000000000000000006244485c5d3e9a163f7209a8ecdceb79402be005047a0efe5bedf706639c3fa4e865df3d6479d3c3309566cd688b03100000000000000000000000000000000007a9e92a27b3a9b4db4ca1bcd4a9d904d7d12ecaa99adad4edc504cbe5067e698bf84189b09e0c5283cfdfe3a4d904a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee03886ea8a34406dd0d767e49e83cb7ea2dc625bad0f15aac376f466e9704daf048129bd0e491f8c2ad5cffb0f10c4000000000000000000000000000000000c4396c2a0bd1cbdd410f37e4c77c164fb689e6cc57ef076e3bbdde160d856a5caa0caa9f1cec81bf3ac91e545bcdf170000000000000000000000000000000009f34c33d7b517858190d36999df89efcfd6b3d067537f9118baf4da70b112722fdde799105911a8f7a604c2029bd0cb0000000000000000000000000000000018aa91fe89bb9581763259c4b9b2954df3acd31f68741441b68728e9102efe8ffe135151779d54fc8ce9cd549ef6e2cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180b20271e64ac7bd1b54213088283daf4d8c646415484104218b893e5133a2a9a910854e255a9e597af6b5b97a6ab260000000000000000000000000000000009f66ff5ae096bae9dc1a13208501a33ef43b19e3e5d2727dd76aac07803d5c1b89b4604927d10ae9f1112e99b6a1600000000000000000000000000000000000fb4abbc673972249fb451235faccba59eeb8c08535e1aa513464aad83af4fa9a3daee59d873f2eda5248912422b4022000000000000000000000000000000000a838e4905685d4d877dbe8a4b624a7ad7d06d76b14bbac5180f51811034425a46030475a5e6af3faa4c3803227a78551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000060a7741b78e3cde771ca4c2d15b84cf3f0b9dafed26052a66f86b03d6ab5a1725b081f9ae5569ddedd18febb81f7d9d0000000000000000000000000000000010fd5fe1fb483d619485bea22d90174303ea7270507eaa783fec24d2f0c1443510bf8f7d61d5266a04c330efd9c05fe70000000000000000000000000000000007d5ad82f9481c2ad0599e9443c5276c844f48dc265bf5d7495ebdcc1ada3553b97283b439f20b7debf6d5b8d73af112000000000000000000000000000000000d2b0eaf78ed718c12fb9898c8fc6de7cbd8ae0f6a7297cee756164a2a5c29404f4bca988ab7a0d10ee588aebadcb1df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b15b90d34310badee69370d86535c0e2e533576fa7300aa2db533f0347a796b340949ea4934116cdc514899ae5047000000000000000000000000000000000019181b2eb5b44b2667b4b4ca18383edb5a340326ab476c5e854c3c9bb8cec3781d2fe3031eb61f536c9aed2513009ed000000000000000000000000000000000f6c51e7444c88172c62d68f13883edb606216d86f1f0a5d88d644db06f0a9fb9fc3df0258785a222589046bc66dd4990000000000000000000000000000000012670fc922e0e517bfac5face797cac3dc9bc360ee9204209a3c21434eb220ceae4afa71228741999c5a811c7e541acb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085df781c636527f8ea89bce264d34ea7fd4b08af97bf09dd53af298bf43a978115f2102abd621885d11e4483230a7a6000000000000000000000000000000000d03014a968946e85ca58c353e2b287796ae26d8bd90b6c33e92b382434a7eccf94d64e561934ce3c803ef81d96c258a0000000000000000000000000000000000e819c2293926182e21ef5951af7f028caedd9f681e9a89bb99fff9521338136f26742aa01a3db1f9a648d1aef9370f0000000000000000000000000000000018601fc5d88915215378376689fe9ef7da2884587d21cae2f0be72317d5b1742d4d25909517ec6014411a08a64e42a9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003677129dc0a5ac34362c385929b47eb56fb1b1a96b70c0b9ddbac0eef34e653de287d5b40d166e1f0c1b590e436481500000000000000000000000000000000176056f60e1dba6fa443e230c2ba463bac40aa74749141138059322e7809ae7913cf8740077a4f163b7857ac08bfe057000000000000000000000000000000000e3923f40e6e07e116cc68b1d7552805ffd0ae826190677b71853b34e6cdbdb57d433da1f63560eb76fe2994adc2c2ec000000000000000000000000000000001206b8693c4758b90c365457e316b518907d40fdde8e200893b8aa1b0be86d3155ef03fc26eb53774a8f7db079dddbc61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013ccaead2fa5aab80cadb887885ee5fab421ba6064ecd094f6b1f16cf9e1295fded7cf072d7e6402ef9cec211b089e5700000000000000000000000000000000061c6e714c7e04e5ad7640edf94cf45b6b6598792e3d6925c7873aebb4e1816d93f703b1dfbc05e3ec30c9e2cccf01ae0000000000000000000000000000000008ba9d619dc8f2334c826ee0aa350c9e876d00c33cea8a61b89faae8aeeee0238e278237eccdff898482123e91a96aee00000000000000000000000000000000124d4f3b11f691fe7bf025d02ce8dbac0f996e0f1e1eca6d0b189414632c7dcde0b452b5db9d2d08ccce26c911d9e6001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014a1e40d9599fe0c919e0ce3819e67df6a818cf23077740d765041637888f7770cbae1275086d1ca43b7f613590551c600000000000000000000000000000000097ac62e470175fd7229984c9baa3377b1f792a16fea74775d18eb16ab9d387c8d5aecfdb1b83db620e7bb798c3c72c3000000000000000000000000000000000a91497cfc273e48857d3907a1a845f165abe5a58c6d63d5eb2a2c0c346de19881c79564725b0f3528960678a169289a000000000000000000000000000000000cfadf181cb5f16de2b7fbc6fb3967b1e01a5983135798f398ea9737edcc4da44d6d55faf27867cd89eae2da9c03ca7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d67734e50c6e91a003fa82ad7a69c4342ef7a3b2b5acad0a0f86a3155da3b4869032b5ed00a7035c4567961190333900000000000000000000000000000000039402ca2af5fb8f0872c6dd7f2f9110ab070f966296101bc4611d45171bcbd8c9686bcf68ca910c64c92142525b9ee50000000000000000000000000000000004a6ead1dd6897c61541222bece0f4eb175fcb60b5c41543858b7093f443d49150533b0a78027e3b7769a9cadc38fbf100000000000000000000000000000000105f2fe3c76a28ef1524d7340b414587f689d6d47ddf2fc68df2b9549bc3be37f339d19a50316c89d64387a4f3075e3e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bafc3536259579595fec9e0ff45176c3963fc5f84169c5dc8925718421b5532972aa4823f9894c46d2b8031e9f70fe800000000000000000000000000000000047c6e0620974480ca05708b800acaea025effb6f576ad634d69357049b986968c100c05e789097eb7308b3c9c8fa1e30000000000000000000000000000000000959f79e75b4d8128de58e9b8c1cf0d800b3651f78a5a67c6a0e0a34fc780a25ea40f94031d635005f39da5f072cbfe0000000000000000000000000000000004087cd376fffca5d3002428b560dbc056a113710dbdf966241dd6068888d590aa1186acdd4c98398d0bb5820f00aa871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009305f9f1c40ecb59155007bf63dcb9738e9773d140a6193b2c4ac23b68a56174901f9822e930ca1649b6c1475ce6c7a0000000000000000000000000000000015575a0be5c6a3bd9ff313be58e70fc32e7e0bc098146816a95b776cebdc5062004fb2208bea054a463dfab859c5603d000000000000000000000000000000001172a7f96705b9198e59690c4439b3e8b4d3041b9a58a482722fc8166afc27906965fae78bc73082d5a8988120d2076e00000000000000000000000000000000115fea96f22998a3e5f8d2db4bba658b2802f7b182744029a9133bd6a4ba1c6c1d4ca9ea188fbbb0af56da1d9fdbcbd61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098642c2a1ab05b1f23394151c1475362b50cf1954cb645e6c8f3019c96fd1bdac1ba74599c874f7dde168366a838d93000000000000000000000000000000000cee556e7445c10d0710b39ddcb3f81d43786d767ae248f390a2c9bdcf33b0a4db4670a6efeb60169244befbdaa157240000000000000000000000000000000013e2f4b1d2fbc4fe49d3dfa4e08e6e2497afaba8c91ca49d532d936e5d9386be83aee1b30d1731ce9cea4534770041aa00000000000000000000000000000000172ff02c00313cd3177393920aa3ca2b85e7648638d6924e7c4934bc5eb3b826e4c17ff1d29d067ef09644a05cbea53b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102fb317485392c4e425707abc781dca91c7f2be60b194971acc2c6a26461e8ea703f6a5a4fc15d2bc1c6e2a0134b8880000000000000000000000000000000008823e2ec6a98ee2273f5e558b9ef98c35801236c0da4387934383819d6736902ce305ceaf2cebb84e8df147eb5a63c90000000000000000000000000000000003eaf433cbc029c6e0878a2b1c4ef0da210f685e5053c62bfd4e4431615f69d405227748fcc056bed19d46aa279b687500000000000000000000000000000000174928f3976ad6bbc0f2c73c2b31abdaef6701d98a24502317c5043d999466698f65276039edb1c1f71b1acf639349841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121dc77c2eb128285f299e88e12a1ed37092bdae219198eb70d3a20619dcf0847ec92ddfe950aad1e8000c872db82f75000000000000000000000000000000000022a9c924cf5f9323222fabafbe6730426d57235c0049bbd7a2b1600e7f333f7ff0361ceee589495ff70ef2a12940f20000000000000000000000000000000015a9cfcc41ae2210a70572b23d8109e437f356a107651f8e3a32ca18c242f4a7c8dcf2e654a215979143f1e100e897ca0000000000000000000000000000000012df1cb21d1499ea3c1e25f32079af0b09a1bc312c08e5aade2e3eef9c796261821b7022c2da93928591645c44bcfd851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e6db84d49abe48bc8f8e8a25d453ed28a7b1fd919b6782f470c424479ba53b780a3b0937870e1ed68165d194da80a39000000000000000000000000000000000bc70a36eb091ffd44bf898cce1f46c54525ae65290080bb20ba016cb24763a68b81dee32efc778d0e831cc3956c7837000000000000000000000000000000001929e3845d5c5d79fe20a9d5311877080b1349ad0a545d87ca912ad54cf48b78289f6dc3712b04cbc0c1eb4dd9c66df5000000000000000000000000000000000f337010ed9875291bbf22d45c7b9d8cc2429a283a75c5a0f5f16cc34d2c303e3a06a4c569dee4cc6f528dda824d33db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008562868da4df666f6fadc303c73067f18c37596403c801825325106b343dacba5b772499215607a7941bf61061f41730000000000000000000000000000000000274a95afb403d76790a98bda6e49d45bd8ca75e759a425ef5d4a3ef344a1dc742092ce587d1bdd5234812db2bce9c700000000000000000000000000000000114d6b8a3bb801fb4bb0f5a0e211cf0e2335bcb64c51913dc09f8b77b93db54b472f8f94cd4846c9840f0b7ee903e7c80000000000000000000000000000000002b136a50f5561e1a65beb09c1cb57338f5af2818d1dcf5f9dff418ba3c1d0b06553d0e781e241a8cc9100ee7df62ff11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f99f79640ce10014516355b393f2a9cf83b10f5f833507ddce813ca951388368eb5378655bac58753aff67d5a1cce40000000000000000000000000000000006d1aa852572a756019df2a77ed4fccdfeb401409c08025930fefd0a0266531a94eddad1188d6dce6a9b26ca118cd3d200000000000000000000000000000000189d7e92a192b8872ba245d2d7fba9f70922345d05d395d6a20245b4c1015f6828050626457a65f2334d3a1ac8018992000000000000000000000000000000000363297d59fecbbacf7ec9cc9ba49d9565c5090188e9ab9ce422cbe97aa98bb035a28b2f5eeb6ccfe471d3d541572aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001068bcf6ec709042fa31b6e478b30c81fdb5e33233c7d2adf85c7aadb8702556091098318379c2f58a3e88a425ccd05f0000000000000000000000000000000004ac71370378f28d54ca43fb2d03c9e7fbbef33a73e623fdab3a4212f0a6e000f92b72c294bc8e57428ef28c7465b35e00000000000000000000000000000000049d338042bc91f54422838b9cb86ee9d10f36955d88c0cfc1ee50b81a46feac0a5c997955ba33aaa8b7696c8c613478000000000000000000000000000000000dfad4992b9a6defadae6eab9e12ade725b4bcc9bb801a6fccf593862a5a723a8c672a42d8828e4da701de93ec4f03441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000100fc9e940fc569e9631bbe389ac999dfa7990481308f9b992e5bdff872c2ccf8af7b0235c7e33b6824c31f91aebe93100000000000000000000000000000000123e1e5e5c7483564bee4362659c66b9811f02f8907d877004a2c30f80279026b0f00f333f5948c8a4542014d452b41d00000000000000000000000000000000159d0f525998d58716efaabea9853629b471133b24a2829ba29fd31c75b981d73f15f58a5e44c37470db2e7ee26beb5800000000000000000000000000000000199304bc110ca16482e5833be1d8c3d7e55b12adf2b89cbf14b9c1c75d34fbeee1beda17b8cc5af49658efca25fc0ef21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000166f3360b936c172bf49d8b61beebd8b56a436c04c91d63d351a6d94be9a209aabf9b41a82d8e1bb942e8bf8d104c1930000000000000000000000000000000010c3dea2e35624b07df35f45f5dc199f8b4078e3a86dfdeba72e2b8be4246be4f8cefcde2ac1d0989e2eeef275c9e240000000000000000000000000000000000365696b2c3eb56f2388eadf9c473781b69c53f89b80e9bb4635ac209b3cae58fa090b7df45016aaca67a1052ff9da32000000000000000000000000000000000e869c2987fb7370767816bc4f7fd4ff559b1ee44ce1687f0048c31103c6adbc1c63d42d12b59fe844abc693ad49abfb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cb6e0dad157a5ac2718ef700131b8cc85509f7d2b899b7686779e8d4607026bbcc4e305ed46a827c331114a15d745900000000000000000000000000000000189e7c222456eccbe6497961098d58c42de91f2273643755c186830c987191b241d48fc20168a0594906f0eaee41f5a40000000000000000000000000000000008dba00bd1a0df7f979297d2807059d58326a95c5c4fd543a051d030a74e79b41ecf00717f5d73433942dc55a0bd5c62000000000000000000000000000000001065e83484accec90906e206f1bb88d70fcabda7c3779fedefa8d39135d650d3ffab980d883c6032102defc698b9f1bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000b41fef828be98119897f15c380decc81aa6ecda619c44e782289e86eb6ca396016dbe55c426ccd238c0bfb0cd9f67f0000000000000000000000000000000015ff69a1079e09bc20f85eb30961a85eca011475de021c806ac4b4a5a9c0a0feca5fec9e865f9d10656b7e7dd641da320000000000000000000000000000000015ff7a1c0e45bc1c60ceae370e74f217fe4c135906f278ec77620bab39b8d4a52bed8710d362b5e8c6683e50909364c0000000000000000000000000000000000c3f599b48fc3c39de3a9eeeb87e3013383354aa951ded0a6638bd1041c6bda1cc5cb26c6b6fcc8d285fdbead22535481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000045b61660d47d114f18f40ca88e045701c4db0aa6ea45e76e2b640015bd5849c82d92c78ebfe25d481ba3cfa388d0c74000000000000000000000000000000000f1f2dfbddc073d1c6df10c2eaf9b07487d70bcf83ee34aa91f49619ca0f4b3642ddb8a43146fd0145c9ca6c7c30281a0000000000000000000000000000000009a785d47073a0dd21ec43ccb873368ef5e0289c497f79203a6eba07eba478e6c1439f4381060f5b025aa136bbb2c9c3000000000000000000000000000000000298f7a3faa5a0be707257f0315a950401080b8299c3e2d8fe716c6ac9217d78473c8f357a5dddca492ef1c677d16ef91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018cb599845b6155dfdeca1e896931dcc9e48fdb467b098167fac418b5b1b2deff444cc62a339107ec7196b1b9f01fd06000000000000000000000000000000000fbbd0c1e32c0966c42a6adaffbba039db93e09a76470e964e180042bc615729ec1c22a4df40613eacc2f10bba69e1960000000000000000000000000000000001ee478625197a157e3672e05f2e374c81bcff8b1602a4393fca765d98f6e4d655bb2155a7ccf49e42a04260006c7f65000000000000000000000000000000001345f35ed240ed76b6fbc11d59579c35d72bd17f46f2345761b8c71e10c066fcc1f66ec4534e63b0e881b54343733aea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fe304725c729db1c4c1a211658abc844de913b3d6c9298b67f52254d644a211b7468e30256658d8e8f38abbbeb7a3b000000000000000000000000000000000ac59f7fc9967d0baeefb368cf29c5315c2e54b416131e89fc7621065423e79a3932c7ff648fe94f578add1a5573cd6400000000000000000000000000000000199da56d17e8a859f4efb9e4a3b6056be11c2b14f3bafee828b99e11b05d3638eb706e6c00fdd3faaa13878afbca9c8e0000000000000000000000000000000005d3aaab68949d3cc3c14ea18496b6a6053b59f86f9dc50a7fd1daa5e5357669fab91c25a1cddd86cddd8c2a611834fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069d6b32fc6bcbc5ca5cdf4416eb76d8f4710389501900d2fcd2c35a9224d66e1917655e8a64372a40f33f857220e3c70000000000000000000000000000000002277c1091add44571d3b5f60041807b3621079464344b6733c91588f6f778cfc16d1716b94443b5dbf837d5e9b372c100000000000000000000000000000000040bfc7ceae02a883374d2736a94f5d2746b8f208615e8e7ce26d98d954ab5ede7f2dae2b4a209a6f26ce8623f56417a0000000000000000000000000000000015a3327bc495ffb0301ccbc51a16fed7da2bb7a53bc39031d693fdb457d134170cfcb2e08aee757e3f1d857bb4a98d7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ecef1018565e58c7a7537797e6d3e08b53868f10c082a593c8aa459683ec1c34accaf1a6641c74c68960d04efb028d000000000000000000000000000000000cceb7b2e914ce8b2a3243c0d7a2d2a03bf26f6530f44ae02c5984653d5ebd8c7db83c1df6bd250502f1a1144a2127d300000000000000000000000000000000079a6da4ab24946500335f7ba30e604dbac078c19a81f40ba2133d3182aad8ed242b61b62024e67c7eadec4527fc40d60000000000000000000000000000000018f8be9033e761ffe9101da1e5db330ec7aef9c4dec87d69b801d39e5d5aeeb1fdf593d749e74bcce799ca885108ac671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000182fce21d076888bd5926c9e60a45d2476b8e4675454545a0d7a39cccf85270530e158508e7add4433aa51862f1e3f800000000000000000000000000000000007eb465241c5ced98645bc7334941376a492f32d23d8f9111830c658bed22cb0ab03e0359947b13ca605594a0b2e02f000000000000000000000000000000000117127e51f4fc17b37aa9dd4c5af6c5424c436a0c7bacc70255c5908edb7ee3e09e3f5b337f55878debe52fb099b5a050000000000000000000000000000000006793a788a2697d792f8ad18430713bda8fed6450952b01091bd2119b28a7ba09f94457fbbbfc0daba4351176456de6a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d91a947c9f80f8ddbebbe6e9a4b519090f8916667112a782814dbfc4ce233331c73fcf6b9c4c3d66025009362d2590000000000000000000000000000000005c2548ce07194ca016ffba12b58b4e1a93f9c073fb82eb8db441a7bb88a25ed624073cb54bea44a52032463cae18a5f0000000000000000000000000000000010bd2254d04f03c6913d92b9e0df8c581a9c2c6874909440d3591fb82ad95cdbddeb8cc8d43317b47109d3f62ddc0420000000000000000000000000000000000885f665b0105787b484829e469008ebd2afa4a414c0c130663f1bee92c24ad58d590f3bc2352a220a3c2d8f1c17144f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c5b483cb4b8489eac6cd02d242b017085e16653b6239d247eb27d5e8dfd8668ed22d7ba2d53aa5891c5090e081f0ef0000000000000000000000000000000013f732b8c13b77c42dd118bd051314e8e30147922fccc7be7c2b3f4af4d09b8fd74018f7ed0c4e114bce804fb5b7272b000000000000000000000000000000001697d7f748e3f4398e19cc7eed5ac2efd02019ffd363e07a7c099796535b220d6fe0f2bee53bf76759724b75824fec110000000000000000000000000000000016ff3be41145787d05b25ed74d951fbf48cc3787279e74a0627d4a7d67909d3657118bef4acd08dbabda5235a7d95c321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001ef6ed9c1ab4caea80f4da22f128f61a1d45ac07a4fd4617eb2a0c89f4f3baaa613a58e635fc214e38158a88221193e00000000000000000000000000000000136216269dfa5e67bd6e037dd199f286ca71cd1439aabdf765f534d31f6a1a6b033b47607e0c418d7ce3e6289832269100000000000000000000000000000000065eaf4d47df87c637b8b3e2b5c0099dcd91dcbe3b3ecab6ee798e270eab1d0dd1b31f0db989d4e6dd74c048c3d5aa8a000000000000000000000000000000000ee25067233cfb1f191f543ebb28bee671fe5e49f3c05e3ef37f2ee82d99f6fc5b55975f19f03aba359e670e32d8d0391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f125f528fe6f5be6550fc203ad7e72dd4db72b1ce8c92e8a358dcdf74135b7edb97a4e40938440aba4406b6d5be92720000000000000000000000000000000009d7856bad35f707bf021a795a338af413c2d63b558aececd15fc534b2ad9532329cee8f577c4e31eb96fe0746effebd0000000000000000000000000000000014753e6916318e366cf03e535341996657d8e0d35999dee3f5160dedf10cd96d60371a2bd31c6d88e67356f70151e91d0000000000000000000000000000000012ff8be90144c09c435cd5aedbc34f2b649855d3ad31e2c7e08cdc61a23ee0badbcdc0384bbf3820a64953f45a0efa031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8ac1b08de2c765039043a9a2f0a0ae5093cc6a4cf42245a06da09c4081f29d0ef91db8f26688ae7e5466032963b990000000000000000000000000000000013bddbbb3384ecd7917cffc7615444c288650c7b78b00430d04434cfbf77a6dc7bb4973eb4a228a0e63b5b03b8aed428000000000000000000000000000000001631cc8c5ad7af65e58d9bbac4affce7769c7aecbf19002906b830ffd88cdf21204e357def9375eafe9634118e9283230000000000000000000000000000000008d07215ba7c04ec32622b15b665b93ad9243ee3f5cdfe9dfad648b3d134cd307f6469cd2b9b1aa1cd20c5884621f2ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e486c3fb3fb3d4fa6258d08c0b7caf52e2996a27a42aab81ab9c828160b3620de313e0599cd7a0c9139cc8ea4b6e77e000000000000000000000000000000000e637bc6c98dc20cd86f343fcee3a86c14fefab8e8b5a1dbbd256b4f7b2f11204a6ac879f066f8ed6cb060a265a33e470000000000000000000000000000000017de8da98536d6efb5022e6e6063077e03950767f95285bc8bc7b74de7149f4c5e94212879fe3603f5d1bd757f914e4d000000000000000000000000000000000ddfebe58bdef6be0f54e18adcdd79d09c63df4e7b5c7e7707f2511780473abd4103523be4452bf3701db4e788635aeb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011451868f0d217f629a090c4a8463998437677d904b869e5e5f1aa41187546f80e1cb2fb1659591bead773cfa0fbc6f300000000000000000000000000000000029dff210f37540248a22387ef3c43da6eb4583958a37fb23648cb642570901874c5fca27d9a8733a698ec9f19fde32b000000000000000000000000000000001130b8e8493166f5895a6f682f4b2137196d662b7146b046e06bbbddb12689fa652960f2ab7c772d34c18f151e37ff8700000000000000000000000000000000058847782f9c5fbb3abf93a5541866ec2eadc9e6e9f0421c294bc92127d8391a70fe4ebba64fbbaf4bbb7542176547cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011ed4618558db5815033acace98338a9ca114a0c4a58f0643de71bb412ef66aa10158ffd543469259cb1c6f7a861c5970000000000000000000000000000000004bd2b1ce3ec73218556c9a341e8a621e256f0a8551473d74f48bc41172377eccaba85ecf1d16663a902bd3471da091500000000000000000000000000000000180024250a23278190c87f4b7cd471c2d685c88d3d1996ea9c7f9476d6649cc91dacbe107d895a7eeea18dd64a1dff3d0000000000000000000000000000000006028894c51ee25f96adf7d1f3c828cf844196bee002b8ce05c33abda3ff977a424c74e36c18aafb3847671e8ceb102a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004e0e87fd33d616efc15934e87ab2a2971926e36fdd5a3c1285d13ea693a37272281628350d62ee3acde27c1443908ae000000000000000000000000000000000aa3570f35fd5f81e055b90a01f611fc42d4fe2f84cad37fd7b2b60229bc1e9739f3870f1b8d421aeee846b6722196510000000000000000000000000000000007fdba171b5305cc946d6097b32a397c028b964d20f34b668f8fe999fc1165e712546cb61ae324f0d9c6cdef97dfbcda0000000000000000000000000000000009b0e76be2e962545ada81089ca729c7537692d96c4a924ab1dbda71a5b06162862a81203dde1e5ef542f191ff487aa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a5564995ffc82c950b3bb4e4564a3f2ed08848865fcd45de2c6e2508e70eaea47fa933a383b1bf54f429eb31cc15dc0000000000000000000000000000000019681c3fa8e67edc98bae675e441decb3bc0497ebb487c7722ef3f447f22dfea59684fd01b65b8226eab3052601070b00000000000000000000000000000000012ca7b4534ddf8df0039097b98824c1433f47f2ade057c1717431f0484aeaf479bbddfe51ea0ce71ef6550186e66d55b000000000000000000000000000000000dca22f8d6feca38e0b7cc0a3357b305c98cc3769e28987bd910dd88e0e2a0c3e28df225e83554de8307b3a1361ce7421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014846b3cf2ea92ae0372b23f224304aa49af11883780a48fbc8414a8ea00620ef32c8fdc938c05cba51b4de629792b06000000000000000000000000000000000f23b95ccf2e44c71dbae29518cca6826e6128fa7979d95a753eb2d8bec165d489cf92448c8ad743620dd9116bf49659000000000000000000000000000000000019ff5ac47c9ed48033ad33aca786d7a52cd7d169c8623a260539608427b4bbebd61543c303df6a260cd884d5092b050000000000000000000000000000000003b1de62ac79445ba31203e219a0f60a238b21f9e498491919c075371228c616e32122bc912c8ffd0dc7f327119742dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151f65681e5bd0954a4b6afd23978983f0f15f6e728805ce3fd20c7b2a2842a9d636f22d807eaaa31b030bf1d8d67c850000000000000000000000000000000016b24f4fb6386dc6137ca2c019a9520dd40841ffb055c21033120f4279bad13a525ff1e8ce1bc6f1d258172488b49039000000000000000000000000000000000a485ecfde32027b1f02d2734d3d0dcf757224a08b184efcbaac1e016e599c49c494e3da5f8a02518859b5a0332fe9f4000000000000000000000000000000000b6752d929e91140706d7564b1a490aec47be82e7eeac93c9c91ca5e3ce472d4168421c3b0544e2da47133820fa01f281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077b55af1df16da0f7515d0590026879da498192e6a7071df3407e67010c0161f74e58eaa2162226282fb939fa8c309b0000000000000000000000000000000014e7e08d0a4f852ea8593f2330ca6d0876443777a0fb5412661d254825018f1ebbe922fdc608f8fcda72bfb461fcf0b70000000000000000000000000000000005eedc2f8e745a44214e36c6625fb5aaa83fd65241fb99120a43f5072fc4a3d838de4142af40c7b7edeac81435de740300000000000000000000000000000000187d0fa57ae0d0c5c300c58b818197a803aff8d37beee10d895970f7aaefd7e5fd343ede07e64f659ae76b1189631d361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000027ee2508cdcbc83477ce5f0c1c156a0fba981bf887553b4d938824c3d214cb24b4f058addbd1168c01e0da56d89673000000000000000000000000000000000718862216acdb39c9fbb046dc1919567818b45fd4bdb105a5269628085093b26a5daee54b8fb684a3f0efdc0a14b3d10000000000000000000000000000000005991444e1e2c3a8bbe251c043e5769f8b4bb5cb3a4a7635b4cfd981631a099f93f4e183d217ac791e09c38b0854024f0000000000000000000000000000000012a63930bdcd48751e52b97a4002a965472bca25af9d39c3e2e95b3751a383dcc836d026bda27092dd7b8e951dd7d9c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a4798d8553889b21e62c21ad2938193ed25cbfef1eb19b0658c84e80f37c8e8fd0d027949ec5afc670a4034edb1aba0000000000000000000000000000000007de1465cf4e827adfca882f38322885c64305909ff9bbf38249756af76de26cf5c0d31ef035db8783b9df4d3918aec70000000000000000000000000000000003b0a2a5c9458c8b22b5cd92623dfe2f34d3c9e33e03b3b0bbd3493621dd9f67a4baf61c3ff3d8914a00e7023a7c4815000000000000000000000000000000001726d680008a7c651f4d6f627639acfdb1c099bca6ce910cb55bfbaaa67214951acd245b0ecd3e9aec1e13aa358fa3f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000154b0fbcacff55a4afe553eb168735008e50794ab436afd0c66135e234ce418b7cf5b2f514069f90977edea17163b4d600000000000000000000000000000000086a8056793c8555c43b1d42442c10342c2b8cea661c83e5e7f52d0fa4bb85968ab4a6ad94d42ecc5237ab076e2fe00a000000000000000000000000000000000b8d579293b1054463c61b1b7779ccbc2c03b08c4ab06064c4dca6ba99d7351993899f609dfa08460f5993d75651a43400000000000000000000000000000000058f18fb003b5c7e64a8b10fb8d97c047d74ac862802ff610d94b646dbed6def98ef817430228d04730bf61fc53e1a691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005285a0027a75801a12acc133182476b1fe6a1ee65408499fe5b1dad6aad66848b1965ae45b9e66ba6a0b061723efa110000000000000000000000000000000003d4ccc5b38612615b30d4e16b7f96dc4f38706f17a56043516dac4edc2329f1accd574d4539a88176eeeaefe16dd5c00000000000000000000000000000000014ee5fd0856a7f4dc525fe29f2507b5228722c04c136224438add5cd5fa353ed07bc6fd510e2809b54539a112f41deb50000000000000000000000000000000008793474513f0c93cf3007eaf8c94f0fa18c070e24be56c295f5c80b59318a798fbf8fa15a27a4e0f2ecf7c3140bee361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e8a2b63899d53c70d2641b9bea7221ee078cc8f4f4fc675d25b181b4b596f6d4cca45a487dab0373a9e1c5f9c680be000000000000000000000000000000000e8be53c79b90d6a41c55da1594c188b5bf503560ed6bd2d4b4c8f3831cf4896319960003c7e8f78f7f91d471f3569380000000000000000000000000000000013da69ea41c38b5e14978f1bf42a99d57023ad95922b78fd6dd5ed52bc15b91aaa2766f4becedfe195240d8c2236efe6000000000000000000000000000000000c0818da2dc99ddde67d3b8c6e31f1396c533c7d1fd34693107a8a969c1ec97936e25064ffd5314d16678bb44fb19e831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150bb6f851ec10aff0aa158ec3683af344e27692fd9ce61ed0d23f0622a03b87c2497be8516b3772974ed39fd31009d7000000000000000000000000000000001501eda3bf9d458def5ba0d85fbf0e05b441ecc357fcebd0d14f07179a50d4073f547a1415016efd23fe7e20f0b7e79400000000000000000000000000000000002f0c1f2f5b93f4ab5226d9ae969944d66e8ce9f8679e60adee78b55de5e981f04310a4f24e6da9eebf86d6585596020000000000000000000000000000000004343d0f8397f63ef2f96c63d8128154ae1031b5c1cf0e7a8764a56a1ce7a3d4dc4d1b285b47e04e4fba1bc7183170fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e04d1812d8e6e8ad5446aaca4850947179fd81b3670565d2c798b1be39c542d1bdff65030658ec91ea1e8d987a6cd00000000000000000000000000000000018a93b641656ed2da5a9f6a5305c085a0b9c9a45c9869c98703746b738dc4203aa45db947a67323c6176ec27cdd74eea00000000000000000000000000000000005ea7fc32d63aa6d5d5b45d9deb7f1fa093e9c61e4474cd6904d358c8125481659ff33ff2acb83bf226d18f5f016bdd000000000000000000000000000000001185ee05f1e6f9e6de989eec90f6d0fd7758193bd3bfa40c1f00799eb599e0eecf91f6386feb2a19cbf6a4bea1aae4cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001911ea309315b34c220b753037f439936d02d89568e8d3c5890fd6c307675adcc98924c30e472c2f21af6ebc9a9bd1e4000000000000000000000000000000000a2570005ce6ac6bf7606e2642f4c6b7d756efb4bd453db709d47f3abfb87335452a1ac1247f13dc83bd8ce55f24ddf4000000000000000000000000000000000fe3ac2c4658095130414244a1b8ba88377493ecb92d33e2d96227d31420f8cd75cf553513b2b762c117ec9bf6c6519e0000000000000000000000000000000012b51455b8e2eee2c65f35865973b3a6422abb887efab4b44172c5f94963d79e0b3c36117c4bfbc01d2a38e907f2ea2a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001835b8a330f182200a1af6a14753b80755370cbf3e2ca169772543b10f2f99b67a69892ded8ce882b99cfe6cf98e913100000000000000000000000000000000174deeff4c838748f322fbeb8765ae3f461fe901824e3e71d4fab4c9f5ddd4e68b8d8c22fb56ad79735486e963f2405700000000000000000000000000000000101f11f303abfef0597dcf554ce4e9e597127eee719594ebd0d96139e54541bb86bebac47eed9086dd78c1a8c4f9d98800000000000000000000000000000000145f3973aec7c38b2815c75323f9efb33424d26215c174460bbf1c3784525852943e351d721d1091164f95708fdad01a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1093c67adf571f9329ce8e5aafd8cd8dd813dbbc58ddb426b1b5cee3cd49d911079a1a56d1b9086fea56fa104902ce000000000000000000000000000000000b1c4fdd7d121163b6f5c30c87c895decba76f7ba7b3c6628fdac7e51ae5154498deea8c20644a9f13aba4edcfd15105000000000000000000000000000000000485dd49f9f7129e6127b78029ffca4ef83380f102dbf649d0b341fd7a465e7797e1636252bba6dfbdc3ae87d49f079a00000000000000000000000000000000131cde4a18f8cd0b88857717a241490ce8826938ed96754ffeadd5704002c9008d3bf02868e51b830be00c239230c8651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ba2e26d146be538e176d581d4a2b852046f08aaab3856398cc9c16a5c5bc808436f1b9f03f73ef1bbf3ca5398d5f4d00000000000000000000000000000000153742eeac8254b9973a5c6498a2c2e10b41ab3df3f15cc161e6e138d7c0a60d1176b6d4716b5d79c081cf543f00625f0000000000000000000000000000000016dea8dd5fb50a0414a13e6d8d7e909d3b7e96f5e131f2e312983e8402e3bb788d698f1c1f7fa70b33406adecc16a0cf000000000000000000000000000000000ce0921987f510a8c37de17c5b5aa7a531e4ce7cda101ad9c73c274788329f3555581008820470ddeca406e8e28b05a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e336e800d0fd36235586093f9620219e8559722bcd1e763160f181029acb4857e782a54cdd1d193681a96bb00ad278a000000000000000000000000000000000ffdb8b65ad621e42aa9e4b4bd1894b5046a8150cb73e4b24514e832598156f463d8f5f77c5db5580fc65e014348a84b000000000000000000000000000000000df3e1603856984356edfa26d14dbe26f2cb82195c0414ede41cea9d34fdd2c818d001b61bae751f2198e6430f5d3ad300000000000000000000000000000000093f8b217df491b4692f057a5f44a8d042b4b9fe53db11f086d9c0b9dc39728d7912a32341abeabab5b7a1051ef879a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000624dbb6e7da4983c43c0744c996481cd1aebd92a886256da9378948a47860eacd6e31e0640a19c24072899aa2c611aa0000000000000000000000000000000009d3c6d149b672a970b62c44bddfcdbb1661ce134f1d6e87b604d55e8910e00791c2973f14fbbfcbb3cf936c4814a3ac000000000000000000000000000000000b6a44dcc907446a1b8ef21153dcd1df6543231dddad1163073c34442ce85edd4c370796961c5748b6fdf822a8301ced000000000000000000000000000000000538b099aa287a524b87efe2ec96841be18831f3121c39c75fca9f9993eb0d4c6605e64c798ef2e17a14e6642247bbad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c518a751fc60f8cb331eb286b87c314853b71ca61ec9edc72658f96cd7786acb8fffed438f2969f04eb250443524289000000000000000000000000000000001372c1107bde7297cebd8d60123b6646b9a7b1051bcb7beeb272b07b22f1f634b7e18d0ec106c287b2fa91b7460220d80000000000000000000000000000000007ed1f811048b4fa52fe1c04dbc62b9c1c550b32dba824a2b061cd5f6d3f8a3fcb1e68aad20ff33d6bda5b4d7df2e314000000000000000000000000000000000ffa259ad9d606f24509ec338b98a9873c312dad7e2f8c399684a12e203cd78f71296ee602bfd68c56373815b31ca5681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e5f605b936f4feeb1098b6b3dd0b259b6280f936820cb31219db085d01f6d4e774660f65f6707fb082ac56acbb0fb10000000000000000000000000000000001bbd14776c5d4436a90b32cfaa6c0295a267760ea755fa0d4bd129aadba09a45d9502534ec02f9d96b056535be0b9c3000000000000000000000000000000000714408aa3ac01c2c3474dd6ae0464d51e0e9e288f984044971ce01b5900d4fada740dcf75dfb04f8d4923d1033aa0ca00000000000000000000000000000000053377371e22b1ddb94652ec17e17e90fdbf22b4d3db00bab0140e723898e683a8e921b518fefed37e755b4a4e8870741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010000d04ae001faa0a3564b66c4d174cedff410814fc661e3d58c0de2ec7572d52b60b00654185a6f76ffeafc02ec0b8000000000000000000000000000000000535df025e88e673efd55e750bf9a38e95bc7a0cbd22fa7671e0e659b82ef85a0cdf119a9721edf8969600897aad16890000000000000000000000000000000011fbecc80c37f00be295dc338911bf3b1d28015e7e90bcd3b5017e926aec352d3fd82ed8e4719e38f33cf657cbf7104a0000000000000000000000000000000014a00653278b1bda62541c2c7657874cd776278d81278750177328596d5234342011056c800a30341ced0df4b97883981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001104ecd145ca25a781046a69690b30dac5a81a71c87515e74ba19614e14a68df2780803fb8b7147581371ad37f357be500000000000000000000000000000000059ca2bf9007b391e5a6e7878816730cd620e08afc6caf0edefe540a7bf38fe4becae1407ab73a6226e801b0e6d06a7000000000000000000000000000000000123cff1ce16805cd2e54e6dd09821d1cac5d72d4e418575feea8324bc63dd268a52453034f539515114a166b1f0baab40000000000000000000000000000000006be06853d2313deb3b601fa8afd660aa29c1a381ac88e6021c4ac528ef60a07b417afa7f896570ff3940ffbd8ec6bee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000798f7b0e947891a511b950b5a67c78814d62c2c5cf558fadcac0aa2466006c0ea6ca4a086acc0d9f2ff2062409adf510000000000000000000000000000000002d2315395e64ab3a3709dfb0368484e21adccb0e64a0863fae2085946472b7f92f9aea494f0f5e316350b0060892948000000000000000000000000000000000548c41965554c24f1dd5f8193adb4b08a2b6ac9534e02d35bdce7f446ffc4d01f63d3bac174b0873c878f1d23709b710000000000000000000000000000000011c07e776d2e3d8744117ad3926678f266e4caca400b0414c4ce8ab03fb996267f1d0424a065baf0ef638493d25e985b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba0719277e7aad4284414cf07c82cf1d61cfecd25cb6c9092fbfb61c0508b5b5140cb539bff6c253b910ff8e07e41bf0000000000000000000000000000000015681628562ea0d7e74702813e15e28fbb0434fa54c5ad6833c942823c887bf6df5aae96486cdbb43e0babd876c3a2e20000000000000000000000000000000005e44624541b6e2933e107366661276dcfd2c4b9e324ba61020c9761e41d8715781b187cbbe5a5149faa4f881ad85c880000000000000000000000000000000017483a028cd64e65dd4dc35eacaed9bbd774ecbe6a9c18e56977fcf57286f06ca661950ada7c5af6803d846056386f161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001200a62fffb752ced0a376ae8bc2094499f660c2094eec9ee992184cf83431d7895bdf5e3d9a4e161d15331fbfc3bf93000000000000000000000000000000000fb1421b05bf1b57135e4ad03d41523ba116aafbe68a882c11135f01daf6496d7e5f3b0c0604e7b2ca148dd1b67d37d00000000000000000000000000000000000b141a990a43130110c0dde64235ad5c28e0a6f449deab2853860cd6824f98eca6e494b338eb7b8004e67244df9d29d000000000000000000000000000000000201b36256a2341fa22b18244d92e50bb3000929919ecef6d0c7578d8c77640cbc8ae0487a53e4f8190c7eed49192bd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ec8afa397d83c38751b863761ffcd808d5fb12a8bf2a88e2e31dccd25f2fbb18254e40897bfdb2555ba6d19033888400000000000000000000000000000000062a18e095d22451a9bbcd9acdbc7279072df860acd5a268dfe6dffa86f4578038ca2faff70d16beae6ac92891cf331c000000000000000000000000000000000addad44968db4686208b9d7b931c28e46078983b55c8d50b1d006b387928e59a581d77d4d648c5f1318b741f32b6876000000000000000000000000000000000be82a49b884ef629e089fed23612985f5e684275f6cf0b04a8b3a050d0a5e0eab63a55099e48aba468d9712692a4e991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a3f0bbef7d6857d47df9b0c4417cccb79fa270f6156c2a6bde400a3f3354d5ef5d1427ba49f941c2eb74a505a70fa70000000000000000000000000000000019f32b9bff59047894e83ec1ca60a361c5b747de2b260533cca16a58a75207b79939e1fec4544404bde69f9941a2096d0000000000000000000000000000000004824c114a7a3b110b002703acef48f91692adab97384918e49417e44aab2aa782e4eb9886e66d3ed89896d0f4402634000000000000000000000000000000000886be99cc60559febdf89a2844f82f7b1877e0d52f0b729c7ce8643c775b845c261420bc2c5918568c9f91b729a2ad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094dfeb30a080a8132da0211782408cde294dbd9310d4619a08b750718d9359ec46ea92f364611c13f26b06be6635aa1000000000000000000000000000000000ab92fec8913e8d505ea83c99e9e2005ed0f344c05516ad9ba6abd2ec776c21be534196bef8aab146893b487f2d896cb00000000000000000000000000000000166d82400c9cd8ae8aac933c3f635a82572e2cb46178640b50abd21d84db9aca29c4323c40a32178f978b1b0589143f9000000000000000000000000000000001754fc023d49780e4f48fd42e61b62c2d4826dad2be65c3ee69f21b83101c7ca384fbcbf155480a99d3015744cf577061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009b49ff9649278633b9386c342f55f3e08b9fb29972a4f3d274ee32c675cc18b7254a8f008ba94d47652b074e94d817600000000000000000000000000000000011e2682a363b1c3a8ae5832159967711a62c0ea16cbf2a3187117807a9c33c4c8d5a01a51652834805163c15246326c00000000000000000000000000000000063a34737682b06ef9324f8d0b67aac2d81cfee69a7317150854c8eba4850bdb7b592015a81d6e2ff1c2e954072d81740000000000000000000000000000000012440f5cb859efedced0b9022317f962983711ea5880424e2cd5b06484b1abc50608cdc5d202da14a9dd41027e7479621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cfebfede1d1e9281e22a97c63d3211d391b5fbf3e983f086ff21f4290e48e4a885aacc45e23c2abef01e5cc2f70a5d000000000000000000000000000000001925b00addf78c4f4b1161be6dc8e38a723eaac696bcacf977b6994823a9af52c1eabfb7568db4ecaa6646565f46a8eb000000000000000000000000000000000a46159616d391617559fa98db65d4df06d0d27739c93ec33a56dd622a4744442ff832b97466c07946dc00133fe3f69d000000000000000000000000000000000f243b7cd982d0e22d449d4cc898c496fa5ff9a49f60161e27dd82bbc73a96c1a43b721561807293e155a2eb8effdb171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047db7e40bc65e70ea3967c55958f5e472e58cda57d53adedbf910fb45f55aad5a14c03c3be38289c435fc767169257600000000000000000000000000000000068ba3db9da6c3bef087e3f9e6ace7a83a67d94d43a93824b064a8b61a11b3f03e3358b2d8e3aeff88ac9e3d9ac19ad1000000000000000000000000000000000ed52a27cc0bf47914191330aaabd04985331604ec614cf090c54935946f78e3ca60bfd6923674ba2b8e7c6e5d06a4b300000000000000000000000000000000112e10010bf7f5b6361a358a78f20080f7aca4daa9d43133ebde22c0386ecbfc6e954a9526466765764bcabdfb57d28b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a16af8202db60f9edba04ab21cc07f50eb784d8379808a7d03757fac35a46cc8bd78744fee49d3aa4704a53173fb44000000000000000000000000000000000da9870021b8c70a25e58a8355b6e79bfed812088756efdccbd079b1cefa0887f2a18045440fdf4e056bed91090a8398000000000000000000000000000000000a607a1996b03c75711331a27a13e26ec5c6c297869f9d83132c7cb7690fb4364c51cd066ce50c0244a97c59282e5857000000000000000000000000000000000f6ec39c4db9f398f02a38fe8948a65e7e29b8ad5e19a293c278e3c4838e725dea179fa71dfa9362a8074a33fc1b2e741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000080ecadd67299ce3cbcea237b149db12f5ca6bcbc0e5ed3b47d758862df545cff830be94ce35e6ef02f78f65decd426a0000000000000000000000000000000000fecfa7681a39bf36b0f2f53789d8088bc5c2c28b263c9efb81c06d43d32b782170e61f4926df1857c1dbfca8f095a100000000000000000000000000000000198c9619c92e20a64faf201f3add85ec756c148a19f3cd6256fdec42bcfe43de8281675bff422993918a22dc75e1cded00000000000000000000000000000000101bd2fe482e6dd02a6a3c2a772b276b238e35fbde2fdc045bd14da171e770f72a25e36adb10ba499c39ca98c53ba0f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fb10c44e28693dd029a001433d135fe9660639ef55ce219b22115c622fea17f435909a78f81fbac7892b6025e3f5f600000000000000000000000000000000080857c80813bb00f125d418334a53feafb7c91700912b9c6a68f74a14b6e3390bd2b7bc74915245e0e4eb229a57f9cc000000000000000000000000000000001405e2b2ee36a65fbbcc8554780c3478f19c5c4d483ada8b0b62820c77d5dbd5367fae79c6aa1c95302535d14d392fe70000000000000000000000000000000006000db7012a30a41528fde8af185e42c6564c3c0b4f6d13be6ff81bb321d58939ddab0d68a14a9e1c0c0399948882301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ec938b24003e961cb597daf4f2f79090402c5a37fcd5cbabf9c28a19a68f7f919f56588fb0f44582e55fdbe5332dc700000000000000000000000000000000076beb5b3a6c353512e49c365e8ee9b007847a951366e4eb08ede898d6c9b933447f851476a2125edc9e9093d08d6d80000000000000000000000000000000000c3855f8edfb32fe59c85bff768d6c93dade8b6aee1d835df81b9dc6f30173f7213cf1439965b06dd575a852b330bafd0000000000000000000000000000000013b46e91182c997a9b55b5e68185bcee920e83db225de15a274c22c618958b8a4f945e7873e69ab8798bf4647640a0421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f296d079aadd7af995512224e26a93bfa01c5d898a04192c600290a5ff203e2655be1a1acf366a5251f2adb0f66d95000000000000000000000000000000000d0be753f8cc7b3e8fd1346a2abe4eca72a9a13ffdf6d36fa0c8b85e0209a7eb7e819a1d14785dad6d906d86542bec1a00000000000000000000000000000000022c53565dac049d98bfa351f02d62bf3d6977ba0ccf0ec1c93a82b7578786a4be045d30b7d4ad9310c885a5f5cde0260000000000000000000000000000000016e833f68a3175fa43ba6dea78f39b0da6bb163652cd21551fdce566ec8b0c1b6900a6ece8347064060d07fda119a68b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001303037e5dc432e448f9ff7ab3ef59507238dd8fda8c61b206726090dc6562ca2f1ae78cccd252d2cbd162d565e91aad0000000000000000000000000000000015cfe2c3bf760ebc8e44329e70571f80d839bf012a73fce7d44cd154ba6ca84a7987ba2d1a2e13dbb9450105c1e1a74d000000000000000000000000000000000d41ff84fc4e101c7041893d9e166a22ebec64d2a287b29fd5c6c2b15c947452366a649afc7afaadc1477ba3c570def3000000000000000000000000000000000f3c143e7f382a67bbb673143f5fe9ef05bc93915c5e683ab5c674d834329d7a4bbc86f9f725f268f59fa6cd79c765501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769c0ab8072f03fb7c64d7ec9db0ab20196fcd9a3e6ba82b69b49e21a68c320b24b8efe9e43dee7f375ce0daf242b470000000000000000000000000000000008a30a5da46a0e00c03f209b7bb75b32f405e00d592046af2d9ff6cd06ee8ebd79c0e4f7182f18f83679c6a54363d44c000000000000000000000000000000001435037f20451a9f59acc08b00ffd8116f3da7cfb0fe13d9491b4ec755382458660e5d9b997e6a664f0ac77fcacf8bba000000000000000000000000000000000f78970698fdf47c5aa4c36670b7a95a18ada4ef44bd5cf5a563e7f60f5833a36eea1ff1673d73f7e7b788abd3d332941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001428e9cc62915f85cbd82fbb4e84c8f224d9cebc4bcf2a400882444831b6a3d32d7511285933c436dc0a4f0e45213111000000000000000000000000000000000ebd385c73d152a6e24bb67139834e3f2950a8cc7ab4dfa2ca5d050faaf4065930b48b29e3fe69d58f0eaf5e9739ac120000000000000000000000000000000014fc3c0a541e6253981eed9705721aeb965b89040a16c93e94ff985da0e0210c06a41313a9761b1e0cfd904e33a75563000000000000000000000000000000000d97f8c89b991f0d157c42d82f3db9810cb40482fb2c83bcfd3012ff5d031a2338bf55bb05de7fbff4414dc4ebc7800b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ae994375526327591ee21d6b070521704baceb7a23ef5fd42f8fd62182696ece2fb23d38e66dac53e776040e0d34d000000000000000000000000000000001293a72d784e26b49fa2c5bafacea2892bec04ee970bc2d8915813f10a197b8055fcf00d22a6265c0a284da3ee3ad461000000000000000000000000000000001999d54e9e475fd17313d58f8693e49856f1dc2bda6b2a7b35b1abc7c572911e2c635658f7c30a5be7660116037aeb2d000000000000000000000000000000000b0959db3feb0815a17cfa8baa889d8e8645c0431f189453df441bd83cde19978ab687652b80d32ec96207ebbe9e97261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028fab5fbfcc8b3e8c49b742d9d84d1ccfdaf543f0dfaba9303b086858e7f550e88148cd1342de76380fbac084f98b70000000000000000000000000000000000ac31a70f04565d57881cb9283ab48079b47dceda1a182d21b72b3a7ff48fb46a2a9878e367286376ba368ed686e00700000000000000000000000000000000000966b277a027346e818015080a8f3278afac6b501049e354fd31399ca17fa927bef5c919e759aafe31d9db633b9ca41000000000000000000000000000000000651c0ca6b07d5426413c5bd9be11d9cdd0a4fcc57d469681129a5c4d6cbcbd2d1489026bb85523217ac7a8cde86e37f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012d4156b4bf0b87b64d157a2a42daff0703b1b7f104ee679a8b16b17f4dbe24732f62e95373114735f729904318787c0000000000000000000000000000000006240ff98ffb41ef3984750591b67995208f5c6b96099a73370730dd310f79d382841c32ebe08ea7c0ca5a4e25b1854c0000000000000000000000000000000007904a97aa815fbc0b07c1b2c35b173313f87fcc24040b69f0f6ce8e0d9355b69c57ec25013ee591ed826c5e676f9b9f0000000000000000000000000000000015eafa3a9eb18375826a3cb86c4c8bdf201c12ba4bf08482dc78925ead18fd69ea7e53168696b1fb6b7d450c6857a2011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000120ee461f7f44cd60c9567b19e93c1571fce77ca9f2564ba79470b1bbf527085eb519073f93b03501f47ebf4fb9d0f1e00000000000000000000000000000000033f8c64e2878a91acb28f1ab595d74a802194603b3bee8ac89f2d49b6ec8823b28ff13665a01795d57b03246b6fa690000000000000000000000000000000000d0af92e18fdb3f38d86f860bbd6dee233d30a69ed238ad308e9803962c7c8fa03b24e204da902e7839b6d03bff71d1c0000000000000000000000000000000002cb4fcd4d1706731c5d3f873235d63a1b3f037401cc9fcfa7de5342dee5058bfb587c02648515f4c79c00568993f50d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000994dd5c22ef4a8a4818a219f959daaf4f010b9311dee31592b14a34498ea71af911abecc4f0169c99dc3f04d3d6333000000000000000000000000000000000bd79ea7b7a26c3ac6a565b1138e1089d27ea1f9f40c401e838d700d9c5282ef2d7dcc06df440844c867bb19118e53ff000000000000000000000000000000000d8cf04b9a4cf1e8fc07f434e759bc9d2240e53ef1a2d919d0b1c76ff105ed46be998d8398e9b41b0826a11c6031a1b800000000000000000000000000000000112053cd14453052e97c1197d3b9210a4f4788c47e0f13a26066ac2940295e3f73092d9d87003e463d810e0a11a638031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001598bf5da4c6299c2987f71b9c9410c0ce4debb3e6629f4ed5f1e7f81c52998eb874ced3bed3544986aaf277028f2c9b000000000000000000000000000000000050071b7400131a557086bd5cfbfa8f0a2297d59291a21172bce975f7f16e7adcd9412b19bfabab2233e41b02de56bc0000000000000000000000000000000008cca7310581ebfbbf9f5e8b80ba57283de8e5e5a55e3c1666052c0a5e9798faba884ce82d23d0416d36590508fddf5a000000000000000000000000000000000d38cc83d8c3deb05d467b8bcd22fc718ba215a05890f2a4d3db5fda1e3962068999c8c50d36ed8fce7cb24f4d0e1ec71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e015cc35f0b62efcecbf85d1f1cae8c9677ea0b9ff8b117dc4ef6784d9e9015f9b2c19fecfc1fde40322ed84860d990000000000000000000000000000000000cb2c5b4a6267c6ae9cc2b076604ef3a8cc83741e575ada79d49e191a1a83f23fef5276c3007cebf3afa9bedc13855900000000000000000000000000000000008343d7e1392bde7511d19c4cf43267a99e5148c74fe910cc9e477d5e8a49f70f2962a7ee544eca066736dace0f8258b0000000000000000000000000000000010e231d55ab70d9fa79098e3c572f79233301467c2f43cbb474edeefc70f8e19174573cf444d07b36512512f98488d8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000008629fd2f1aef6d9773be17fe9671d15c393701b4493ad8aad0c21a3ef3d4196c8df009d09250965f8562af6f2c448ab00000000000000000000000000000000190dcd8ae4a739c02c62f9100aae52735255bbb96b6557145cb306c40788307b2f831a23d3131e832179862500f106e900000000000000000000000000000000022e9591f2055cee7d31125d9043e6cb45b514efce76eebc58f11dc7055ce42022becfb86e2ecc092f886878696e6ed90000000000000000000000000000000006c5036f276b4b3a88e4144a848a57c931162aa20a684399387684e95ec0eb7c20c7ee1d6a96145bdc1a43d534b56554", + "Name": "g2msm-512-jwasinger", + "Gas": 4008960, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000011b0c313788c4e60520eadad1f3685a4581ea4a4594fabe5e9cd9a9eb19e6be56656421512c4d316b19d4086aba226500000000000000000000000000000000011b4b99dfac236e1212c87f4255da6104bb4ddb3ee1730f517eb6d53d9788b64d1318bad43effda15ae154c43771d03500000000000000000000000000000000029b0560d22293c6525d0e64077bb90f3755fa9d7c67d299224c39064f64c8caf1353ac7ed83b00cc63c982e248dda5c000000000000000000000000000000001081844e26fb8f937e56ecbbca277f8ad87f4ed24e3d57d2c4884ee10bf1dede7968bba2c73434cbb873ce1c2d2bb2a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054cb9a695a5c86c47b29473b23123a72206bb0d522d534beb06453d9cc6815f7a2c4bf63ac6090fa335aa6d391b8a43000000000000000000000000000000000f52a4cfdad49bf02c5ecf9664e33af45e717bb087d1707bdbff10be3f90f81768eeb7e45e426a2d5ad59eabc1c003af000000000000000000000000000000001652bb1e05bcdaac957b87166707bab0728e5c4d8fe288fdb86bcf2e3b89219b8ebe773990a1a0d8df6398b40b3cdf8b0000000000000000000000000000000017b8b43010f7ad716970939bd3a8e61bd73d93de4d8ce4ae3253091f2f1ea4c1ce7b5821e5e2982f90c5cf6b8dabaef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3f52ccb76597b1909861f89518d59bf982951f7b21c52c7ff8bb78e49f1dd1390faa6a6c8f4615328e7585286ec4e7000000000000000000000000000000000e1933193f6ed7f6e243a84823efb3f4faa6be40ec95506950c5e479845d85e7f65f2469ca0d18d9f41d1d5fb228e4680000000000000000000000000000000006d9fe4034708a5d4ba1b74e1dff28a9a77971d8d1680dab413b7baca2a996a44d5d25d5504975ffd99d919ed420f06e00000000000000000000000000000000113715359f0c8d0175d1242007962d4bd4c1058d628226f69f52ce4ebfab8466afa45c53bc75a63a8b37fa2962b1f2f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b4c421c64e22fce3153793f03476b256fad36d42edd97638d8557b6258b0af40495136111a9b41bd558437d8222326000000000000000000000000000000000668c35d4f9ad37f6b3a3fb4c309c8de2b4f2c5cf3c48b4d490fd337d72df4059ef9b6a01847f6eedd5efbd79532644800000000000000000000000000000000063087722c41cc680f59541191c38fd9c716bb7b82cb2b654a32e4972241a4e35b503966e2ea75723a72e3ca6a260f1e0000000000000000000000000000000014e8c5334ed84d0ef98fc94be1efa631c64a5aa4ccb2950811ca0a108b77e3ca5122f2208943c6f07fafd8dd5fab06e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002ebcbdba6bf202df969c191a91fff9e84126588edfc0b14eddf044c013409f1deb95b36568f9def69cbf6d6e7dfb6f0000000000000000000000000000000015c33e391ff84248c925ec4810a59693bf1a62542ad4163a7b63c15440529713fbbb1de069ef869887d92917717efad7000000000000000000000000000000000a549924ec10abf35e1a854222aa8cfc903a8958917c8423ed777fc6f3e55403d6f165835806fd1f497fa2d6bc806485000000000000000000000000000000000d2a9293d373f242d0788a3a40b12cd17b4ada39589e92839c05154ef51c6c40dc94cfdaa21e7b5fa5a762e13228d9131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000054dfff327423b18b418a39c24dca35189daec8a2253c8a2a46614ea45d837578e747e6f925a416f6d6819572903477a000000000000000000000000000000000e8743fee8e5447d5f2ac5c7fbe464b68b851632645c0b3673269fe87ec1debc81854d847cc2c5e0225917ec3546d14800000000000000000000000000000000078a1146f485142222269bac6f021e5ac318f92536d6db2f0bd6590d76345e9688496a2c7ed9d45090e43b9d7857af540000000000000000000000000000000019bc4932a07c037c6716c6e7495616373d37426c95f0d96d3ffc8b7908700de1b5a36fa67277f87c5f8c091a9de322221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008599c2fcc99d7efd655f590ece5e1b3a58d571245f7b63d48bd8f766f30103873981afc482f88012e06d3899206b737000000000000000000000000000000001922a85965903dc172dfe553331755684df947974d3a8939d0d4a6263db3cb0b41bc4a3c61932476f88d787c1f2518f60000000000000000000000000000000005180e5e9ab82b50daac72f2c3aac3433acffaeb8db96bf3e9fcd5b0225a6f550f27bcbc4f3fe249a96cede5455d593e00000000000000000000000000000000035bd07269262193b408d8768e87f7211e25f801b708b1d268caa5dfff380a2afa76dacbdca04c270cd9a079482aaffc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004314aa683db34da4b6eec837870a015456c1e8db4e46ac0fa48adb3de4d13a6e9d24e301841ae6a3e81f74561dd665c0000000000000000000000000000000004f14d246a646b09ae80051d0dbc9cd2b5759d86d19cdf4e9cb4ae94b077bc7f81fa09fe3a0e003e3dfa9f528ccc815600000000000000000000000000000000190c55d788da26dda1a1a188bf4a1988951824e31cd9ec1d076bab1c05c4e134d541cd48cafa0b7a0100009315cf89660000000000000000000000000000000017a01aac43217c9db71d8dfaca68b6a6eae3789c04fde4a0824a0077b02966c8e4b4f42e9a62c2a7de6dbbc3f28755f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000257e3df13541d4ec4eb6c136264c77b20f85e21a20005ada610e3b4a854b19b6434eda2d576dcc3f27ebfb7afe6282c000000000000000000000000000000000741fe5c535492fb3f0b37539045a6410be83e9d2502ab29f4d0ae4aa7b3bff074357a289813510f4f794aad957dc19d0000000000000000000000000000000002146dc9e0d0bad909737d7d3e947061331267f7b62c3b56d9150ef404f6b70287577be05d59ca9ff6edf23ba9f8ae4e00000000000000000000000000000000094c1876f5423974b04fb77234fa040f54dc931996d3e9073a639b03df82ae1df4afd53fd35ce8d79b13df722eefe6e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008c05cf7db37aa0e7ec5a78a110e943b066817d226d63ed39b57cf182f2f02dd1737665ea05edbb000c7eabf7bcb67810000000000000000000000000000000018e9bf6260df1fefb5b3ed0110305ef1453115d602eda4dcce0c6c3fb8fa4e69d78a8f020bdf78fb7063ab89bc220aa600000000000000000000000000000000198c757619f789fd85753e78b4d83c12122adbe456010ab1a98ed3230d0cca77b31704b903816404c5d0278309576c690000000000000000000000000000000014a7bf8f118f46f0b354f90f999e23ea72cba1f1a3b217035beda12876b27613a81b7d279c6b563915c879dec32c4a071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047f301a329f20a66e9de0fac40d9ce43ce2c2e3dddecc21f4c0a14ff9d82b5a31146a26285922585b9f62a0df3e2a320000000000000000000000000000000016a58e3d8caa87160138964786dece59edfdaf204a7a023c2bff47cbd444b30ff8cfdcd194e4b23b5bf243250b99abb90000000000000000000000000000000002eb21d8c8ce36ca0d12fdfe8e591fadf399b61dd2bb2e79adba98824e385fe429458177102be237bae294d492e0579200000000000000000000000000000000077ac450ae8608d9c0550c6df0175a9a1becc8f785ba45a96471e901c4860dcd671270090452e0339d34e75091021e761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009befa3f21e4a42549daa43eebd6093ccc56bcc70f36ed840951e18dc41227cd5ddb94c301953f40905fa30ca6bc81ad0000000000000000000000000000000003547c1604a9e4e07cc27317be52d0a7a580fc9eb058c7d6b327357ff62adeb7bcf13299bbac73da41de0f3dea4763f500000000000000000000000000000000036904f0b220ba6168e1d9671470a53c958612e2949ba8e8cd23e8cf9276977c1bac8edeb600fa6dde4906205cc2afe9000000000000000000000000000000000792491c8866c279be0a740c3b1addbc979eefba1d7b95ce25768af822749d0d1251f38ed3c3846ae120d4b7c854b1ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002f5f1908b357005e4f757953082d598a24d5ed1ab4f0e087bcede2a09d764cd9aec500dd267cddb68368dd50616ec78000000000000000000000000000000000df42b815dba924ca86aed618a8639fa1340c1c166ff0038cefc431517f9191148bf1bf128cb5d2ef6ad3713cd40e2230000000000000000000000000000000017e7d1d0bf1e3e714f2d5133624602cc77d193b4a03ee99d9b4e3bad83f558c205849ea3b0e13e72a162f4c9a81f7caa00000000000000000000000000000000022392b0a5d83d3b69fa0ccdae7af9d490eb76d1a577b3d9625ee1c49ac5caefa9787e0f2ee355ff6c8e917511aa8bf31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2a40210729417a699e48eb963c957d238bdcb54ecd2d8f1ab3c04077774199306f6e0b43d50d8ac565f0f8577c8cda000000000000000000000000000000000b524857d616a4b3c1e2fa5a0b4eac457fc9d50ac474c2789c4d856a2e9939319ff3a87840a5c8ea6954e0076f54b2b60000000000000000000000000000000016b7d0da5c058fcd32b224b598b6775fa77e50d071116839704cbe10b30e6cfca945526f1188cc6a58f8d64e8c5470ba0000000000000000000000000000000003fad7e14729f77e09e6575095485f709bd553c6166c705b00a16e89f8436fffde277390cda206ba9ffd5608cae1bc5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c5616c2f24bd1de048b41a7b890688dcbd1dab85690c817af8f1765b9b043300a2f377dcb80e496c0d0ce6f42e8d51000000000000000000000000000000000211d408ce694cd3e5adad31201d0d370e6fe2aefc7820e4d54bd8467431ccd1b49010f653402f7a781a277b6dbff4b00000000000000000000000000000000019d5baa76bcc1642f7e6522d13bf17c6ee0081a7f401c0312982e604438f9db0bb182f9c23a9084d833836bd70c1ae2800000000000000000000000000000000057ccecf7b7c099e1acf7f6df123a0dea258102c32641ac116b5ec033effbe319178dae3b35037518f3a931242eb80cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001d78e1da3bd442710c622789d29e94833a7e5bff88bd9af492e2a282aeafbb7ab2776fa2674da8ddc199e2ae35a5cb0000000000000000000000000000000014355df1d7cd9ec9eb0c0ffb045bc0096b7e1a54e6284f9f857bece09d7549031ef92b27855c1d07d2ad5b435a124a02000000000000000000000000000000000a468268d5af8aa11e04bbc5f0202b458cc2cc2147cbd36451855cd792df492eb74178cea9ad13436c9851ad10c9eadc0000000000000000000000000000000017f452b4f8c13a7613a29a15efab119148c6adcda63212252bce2f615543f307ac6221027792f6da85472138297b948d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e776a5779f5223ea00ebe7298cf83f99ee55ac49c3595735512ca7e8f0c32fd6973842257693468c4364a7041b07f6000000000000000000000000000000000c536e780a97e3dc52ccf424ab983085c1873dde4fc18dbfd23134bbbddf5ad023a373fc8c9b0e3751aefd79053fab34000000000000000000000000000000000389016c857850f90e0fb2570fe9c5dfced8c0af1c60311d509dc9b59f07fbfaf7954acd2b17f140f80bcb4ced35f8b00000000000000000000000000000000013e6bcfe7cf2dc06a9f281848a1d1c19d276ca2bf4cf60b4fa3dfc097ba5ee5e99056ee802490fb4cd51c836ab65d8721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024a1dc0bc3f7547705f08eb6bea518393ccb907ed45232b90f01c4533ec3887b7b18e886373e58cb9232ebcebcfe1770000000000000000000000000000000000410b2d23721ac77bba94713c0a5cb069a48ee8cacd10b8272fd91c4a16d9571ff74b2da47b84ba3e98c3a281c3a8620000000000000000000000000000000010fe420883c99179c351172adba5dac4dd410df42c4ecd56c502eb857f4d51fc69205e9029de79226257ad4cc557d67c000000000000000000000000000000000c32ac932d1101fcb2ecc23ddf2e481ccedeb31a11de4197ec14baba29afd57545d6b3175f2a18df384ac9501196d7bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122afa709f5cc5dcd006cf9af2eb0fc9f9675e77516d0c3ce9488b497ef4bd47b41fd8ffb618a18ae7e640851cae264b0000000000000000000000000000000014805a2c043290a53ee6d3d84d20987efd9e7147194059b57c59171984039ce4a306c6436b42a2fa0d2f489c282d9ac4000000000000000000000000000000000c42cc7b5dae0b06817b7cd567331cdae7f8b996d7a6a055e8829b78f20dcb90aa469fb88c0549684738b37f24caed490000000000000000000000000000000010cde6152b1ca69fc4a71cb53c7d33fef87d164f52705353ef254f76df6f5c4750e5af1784d9197e9b95c8ace44ae93b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d1c292f508462c38d4ffc391976ad18b86e89e551d169995269252f780d178febb3b2e939ecf1f4f00c8c16446c7a03000000000000000000000000000000000d67539b74aac48ca78cf7cf0065de74a692d6e802ec3959ec227a2febabf5b51b6b052e2448c7302502ba20ed722dd40000000000000000000000000000000018ebe9d93206e330560c9ae29b3df79b64b1cd7cbb84bff5d0f243dcc557e263a24df1761d6c4a5ad7fb6cf72fa7c3f900000000000000000000000000000000013af94d1d9ba772ab2ff59899680b41165f9944a6adc85209bb1ac2f59ee5f22a2a498d0b98aaee00d3f39900729dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d3f34dffb58ab18291103bbe0c44581d88d932ac9db046e42adc2b74f9adb3a801b56d7fbf59fc201bc39267094a3a0000000000000000000000000000000009909e92441307c62032c11846dd94ba3bdeb79d5cd3860b7eb719412a06616a11d8dcf39a3e02744a3161c5563fecc30000000000000000000000000000000015ca1104d0d0584a4f6db38c31cf2f79b28c5067c2134c2463e2231b70b0640fe9153f68e080ba7afb51fdc61e6ba05f000000000000000000000000000000000ea43795f3c2fe2d5bfc3bf9d172efea82ca0a3c42bd60a612457f46ab847e1b60033157f49fea7ab2f067195472bc971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bd4394256b1a04ef0b69bce01f1736331ec4757ab9ce744f63610f5b1d8a754805483f9bc8470486b073465d004b440000000000000000000000000000000008b5652d8fe0ba4617aa000e29b199f2acb77bb2968a93c77797f3f27928f79b9e5e1db195185e66de6663173a6900a4000000000000000000000000000000000f8634fb757e5cfd173dc636f6929235bdf73ec8886881f14939aee72aa5b544b33427de72d1d741b5a46f861f4ae9eb0000000000000000000000000000000003bdadcbfea971a38e11ddb1df62ec1b761e3c86dbd1bb690f7e6ef3746c1bea47dc235d8a0ebea3063da2d27109d79c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661b2af3297740cdad612d5ae8eaa640ad960db4fe74b7ee59c2100a7c4d2f3daec6eedfbcb581aa3871eba9af9a69b000000000000000000000000000000000f3054182e756f299e661f25a91e6dcc64e2d62de2321f2d056ee0f4c8b2a37e00a272ba000b4f65dbff34fc40c8cbf9000000000000000000000000000000001290de4784ebd023bdb2565b1bddf2203672d020cb6f8c808d4d8e117dffdcc7999b59a2ca3a744c9481ec5ab546ec79000000000000000000000000000000000407d338b8e1b27cf0d45293fba0d5d016304fcf69b6cef1bc26482eb84755114b67c7b6c3472b1bbaee38f4ae9afcef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005a10b2298a6cbf67cecf71df8760f49a11a5a6a55a6fb7340f4081fd51681941a0d5f79794aa718a72d3c8ad8d4e90e0000000000000000000000000000000007d0c1d57d5679869b0232ca104d14916231a0e07eb09d269870b0d4df664878f5387b4a25bcf72989de5022189cf3c5000000000000000000000000000000000eb379aac9460add24ef081539b46418c4c810e9c91083975590d6bb9d1d7c4bdef418e7a46e9d6a26771ab385ecbe6c0000000000000000000000000000000012b8cf7b0c4268ab5d5c7e08b10e25f1cccb91655c961f21f117084f3436dabae1324b75422a29a44bb5d641babd97b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001363dfcdb7f0dbec0c2a265aa6532e66c5e7f8316fe29658f2b5f47dfbc7fc829e5ac3679beea66ead02611e0c4463bc0000000000000000000000000000000012b580d164f1fe47fef6edf43a8cd5aa323b87a146d098fd7017251f7ccb3707f4440503be3140ed71f6550d2abeea160000000000000000000000000000000011781f417c94a6f599ed6690321bd960ff934204361f148cdf6743ef175369708a7bb0d2d9d69c79f72a3961234d05080000000000000000000000000000000014222c251d59183b4af49760bb58766c5c9d3cad52307964b940571bcf9b54b9e82c9b60c17a60440e80ac70a960840f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e1f2f9e9c45524e52a46d6258320d19419b25921a75cd6138e7f406827cbce9769ce67b450e3c7c2dbc7ae81b7e1400000000000000000000000000000000015f3bb29b69cb7d911349392b2b17e8134cd54432fb59ca1566a7f12c5903276286a1ef528e82735ccfe7cee9839432f000000000000000000000000000000000d58c81652d25ac74578aeb22258b6efd65be4f73df56989c1e63c12c772f2c1efb1c738b44310976caf10dfb1cb4dbe00000000000000000000000000000000155b78aca4b8b2e52773ef29412e2080fa3e29f597e8945c86a2f21d08c8cf814b80a4ef1ee436039f047b9878df1cca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090a260db5ed4dd9588b66909b974ed9010a5bf5e9fdf93aa06a805d402ce2aec0a47cb254275a598350c6e1ed0a62dd000000000000000000000000000000000514fd7abaa89c3999d01703a471f7285ae2b3868bd317c215176ff97f1dbc9c854304275153f363ea8440cf39dc3db400000000000000000000000000000000195546c56bae59fed1db1caa08912e0bca3ee3e5a7c152e2bbfa65b665a0cf99d494dc2bca026c44d44d11dcfc630b41000000000000000000000000000000000b4071b0109840fd1bfe6c15992965ea7cd590d59f2439cce10135069b4cce0bb48ce338f92857e4a12ba011273708641824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010869dafcb30aaf22bfd4c5abf4aa45f375ae0ee854fa02bf48fbdda7bd8664df67f2ba4bfb95d43444acb3fcd5ca85f0000000000000000000000000000000009e5af86df74f8fb4c22f4d3e30e403075777510ad72f1e8575dff5a39d7d4e6326829744444556a6055c1f775b6ed2900000000000000000000000000000000155fd97236d2afb90c9483f6f2834501256cbab5c3a023bc3c661fc03f9307705d22f239c3e188d59ded071660e074f5000000000000000000000000000000000381a81a97755ae597451ec91e506b944d86fc16983debfd14ee890a9750c23813bd6d1ffc8f89e771cf664d9194ee631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156be6088e70212d268d0bf75eb51134ff35b005cbdcf8d954d88ba2f86122f6105ce6dbc3d2d417a938bf76e4354a7d000000000000000000000000000000000be4cb81bf15920d9516c510733a0d8a70a8aeab1b745eba3df85f76a20e75fc3cefb6918827f34e1222a2900bc20850000000000000000000000000000000000bc71ee969c4f361646718e379a0ad81bdebcd02d8f63a00b2aad166bec55314280a6b075f42c855d6f9dabaf74cb300000000000000000000000000000000000464bbc60408a3bbed72ed4a283307dd948c42005f4c5abc84912646a6e08a1e75624b997f548a404ac2e0f2f59319491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001675abe44e4a833e6727afbbcbec4670ae170745e9c70788d66371928e14fd1475b4fa504317dbbdb166b98fd0ba84c30000000000000000000000000000000018ba996bf2febc7b561ca5d24e78d47e930eb5a4896becd283e72eec0b2f17cd2de265535a01d98f9346f08f2eed371000000000000000000000000000000000057fcbdabb899ad458e0aee47ab3d563aa9c761956f05b9fed93158890d1c89f6d44bb8d915cd23faa5c86b81a8d5b3600000000000000000000000000000000032d09ea67932a901d4317e47834c3b891ced75b04a820546431ce2cd1f779ff238cb9fb34e7a93e32d8bf395fe728621824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001229468a6bb1fcf705cb1c7745507f506af7da14fabc6720a7ae256589dc0e418b9904d32766451a1470b1b48d43730c0000000000000000000000000000000005dba5c5ed25666be7a90e2b5d8ff3ec0f7352f1495f2035a3208bd318586037ead089282f6918f60b8518cd8c99787b0000000000000000000000000000000002bb2345ac84e11231dcd43b7b2a974f71b3b35cb6672d30fdb787002d11c0fada61e869825bff24219eaed8fd1ab68b0000000000000000000000000000000006f9a4c1894b8eafb51d7c9b87c2ba832b9d3013457a5f0d69901f27a3adfb9c2d66fb5e8ae9fea730e075a5610134e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e8a192ceacc1a78e4a46967ce011498edfb9bd3e62e2348136ca030055ce89dcc6d9e6e1c2aefdb7482e735800173400000000000000000000000000000000105f6d597145e31a4bcf771ea2a8215c60608b8275d9efb3883c9f71b31ab4f047824a9d2e41ef31c2d7033ee58d511e00000000000000000000000000000000132b19a33e16ae59839c69ebc9edf9c7e583a5554c513bdbf177d0b905fd565ed1aa339464544d0a6993888f838c1eea000000000000000000000000000000000f0140c57a3415c4db34a264af2f7ca85f25d6307f22cf74c55c97c4d97c7defb25e6f7371e6c8fc73319fcb2a7976401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e366082f445c45b8e25ba492ad780f9aa4c9b26fc05bf5214766ac0c832e13527fdb7024a3fa6e144dee4a94285462a0000000000000000000000000000000010ba69a2a73c96ca62bdd1553414451cd1de7d48ddb4c137708dab3e7da22b6105cf30c52dc6ddf632d5c065ea041f64000000000000000000000000000000000764c54be883ae7026e362dcae6e05e3947b9d381de9c4715fbe5f0c71137d53bcef46f4b358e008ebb6400462d045a80000000000000000000000000000000019ecced2a915c6e3428fe5debb83582b37fa195cc5c6002b16fe035af14a3c61ffe6b3ab031c3062d21c9f086dc7e7721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d16e160b04fe6cd69f86c88ebe446f90403ede270f1eba60fc1121224ad7475c9550130dde9e8d96f5c492196e67be80000000000000000000000000000000012b97fb3bdf47c432f544e31aa73ec634a54e0fc345319f99037297c359dfe656e5028e8a13a65ee52fe33b8b1cb2d1f00000000000000000000000000000000068d4108621be8dd28b66995f9540252ab7dbb7d9d5594aea6e5ff7fe985da413da74c80aacb55c4fb8772e4d5cc1b9800000000000000000000000000000000079dbe7ec178962e85fbb98ccc9be5f41bea5f3599dc9c9cdc223662cca80074ef83cf8deda5c6bc96d5241a620d7c841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000156953a513cb621948cc4afd37fd317f0e054679cae810b47249fa6d40a64b92baf0e651cc85e10a56d6368a2890b07c000000000000000000000000000000000eebccad4f99b480e297cb308ddf265cc5b654fe269aa18cf058317af40f05b94c7786f070012dc82803bb2f184fa9b7000000000000000000000000000000001981a0003b69c0af8dffca9e312609f5dc75a8814bede4e9137d0ff54c60afcb596652f08dd3e4312d0a38a9ac78f2dd00000000000000000000000000000000037612d6913e17b3b3557c0f8e8c4ebbe919fde3f552b7312ab6e2f1ca483ffbf8eced4d04ae3e9299906ba4ab9da2741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000460c0d5d5f0b43e30ceadd462ea274e786e8422dfdbfa410e43ece8452e0ebd66aa04eb6f49200932e3aaa9c926782900000000000000000000000000000000084ba030ac4cae39935d16fab8cd8eea78768720f27e065ee79f0a16670d3ecb94fbdee21d8dfa6f7f392747d36f5a69000000000000000000000000000000001753417c4bc941d0a468d8273251927aaf430611f18b840dc72b8e4838fac52ccd4a4f901117a6395bd571881e27efd4000000000000000000000000000000000720d7955ef2975be8c206ab045040a03cba4963ac3bad65bcd3b0c1e35b146f59e6879e78b5bf9cef6f16828ad8d56c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c17a9c57ebed95ffef219fd166c4c8e61021f3ecc5a6f95bc67799c24af329c3c9608f747a7db8a5d9e32356504522200000000000000000000000000000000054ff100ee9e7cae3778003ca8047c78a9caea26a12f4f5aaf09568d03571a2df637ba693b5366b4e6608382b6b81969000000000000000000000000000000000d50b0caf2f16e76faca3536dd05371e1c05b7f1e3b8a1ca58d6f97365299822b075888364cf6163e11ecaba828b6d970000000000000000000000000000000012fab04d7f13e27fbb3bff43f41dae46fb602797348713521d4758924c6746f1af4ef8445c9f969deae5e9766fc79acd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000332ae5f9be519465d4a83ac584635dafb5132afb07b52a6a20e92a7c01ffbe6a0bf44cd14e9e09b2842c7e356a4ae850000000000000000000000000000000010fc0bf3ac2390e7be17f3f7296b91c0359927a4a85099e085290b52ba7103a0eec509ea456c07d6391b88c7e7af93cb0000000000000000000000000000000009162a59cf32f37ce7254eea89307436ca7e8cd576b28049c4ed14b790403bc0fb87235b61a5652f3b2cd3882ea6fe7f0000000000000000000000000000000005ef225db533d5ac0fa33f29a6b776f5993c63892df47dc68f00fa8cb3d17f4934f8513f4a344e4058828a1f6e4007561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a4006ee51138caeb6d4cfb7fbd828ab480cc50102cc331081959aec97a3d1ea6da11359e8279603dd57695b77c3e2220000000000000000000000000000000008f4bd4cc7c2161673f24b78d959d1aeb4ef38b504cce10c417ffa33b8ac207c89d634fcbd48907e4df4f434ed8c6f7e0000000000000000000000000000000017bdd87a4cd699817ab5005313e1d6a6ed22595834f26018b8b884d3e0836d1272d192c606c148d9214ebaeb56fd6e8e000000000000000000000000000000000ec7ca2feba55fd6ebcbd569dec9def55e95ab7fbd626db004f8e219a0940306a68b2536f32c58c1bc39248c2ceae1f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d05d89a2fb7af5c9e3248ca4ee3508cda574b862d2c77e2d1382f09e8b476dacc530030b80dd14b5a7e7de5cc43b7da000000000000000000000000000000000af62cf1a4313f9e1950a074725b52886107a2d83f6b8a5bf13d29537b0cceb44b855e643f7f1f22024e872cefd94fd00000000000000000000000000000000006771b6f9711c959ec639dc151e4549eb6c9e04b19cf6c3d7c3e931c41c9a38ccc63d8b7a78dfe60ddbf0727865a0ac50000000000000000000000000000000018241ab4442ad7dc01ad6872a1bd4a67352a1d4598d139e02bac607a239ef7bc220b8d279013dd866ffc0b7d599234fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000500edf138cee4937ec746f5d3b9c1035408b6490203fad14f74670ce1e2d86efc60ef879f4ad3675600af903560a88d000000000000000000000000000000000a2b476ce78fd98e05aa3044b5b0a28e1522065e49cd60df3091d2edafbd7c324a87e6e6ea57c6c6128118afec88d0b80000000000000000000000000000000005d1696646bc02832ece30eb72efc5cb81ade55ae3588c0eede1a47714fc093a9c1d6bc9176f228532f7c8ebb98f83800000000000000000000000000000000000d7b6c67782dcc2ec35490267e80864abbd4f89f0c6d1124c35327738617c434a7479e70125ed025677bcb6720e27d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8c8596336da232b706a17886c2b1169fd4e8edcdb1504bde8924617bdd2c306903effc0872b93f2702edcccabbd717000000000000000000000000000000000bce5e4b1ff568aa112b37275b96bf32854692af89fb28aaf4e72f541d9239ea910fdc429b5d40d3ad3086a284301770000000000000000000000000000000000d3cd438abcc1d2071408e4de1150ab63dd267ff5d9e14383df16f6f590c4187b2fa1547580ce2878f3af74ae1aae7130000000000000000000000000000000011fa1868cad43a3b20078c96090861f3fd6e964abdcb14c9895f1df9ff65f20be50e47d60a110d7f9ca9ff4c8db5fcc21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001906e31af33349ca63bd6a10d1f9744d5298eeddd999615c4d18a9dfe4dd142256e9da657e2c2ddf153a1c0eb4e9d7e700000000000000000000000000000000146a890ad84c66c6263e6cdae7966795a3d3fe6baaab6d9dcb4bcace75504686a45d2bfbfaa290dfdac5254a750223ee000000000000000000000000000000000f4358a9282bc67ea0bbdb45763d9553f2aecf46f830747a08e7841c84cc059e8a6e0d832711f3553fdaa2bc59fa5e89000000000000000000000000000000000fa1fb11a793de883a97c33e1852c7bc676b65452c0de6883fb8fddba8dbc607ec81a715e1ad5774524ec682022aa9371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008e03836c60a3cfead50ad0603865b6280b5409293b4a154d56e60308a30f8df3c90d5a92ce8a1a9cd10f3e9904c679100000000000000000000000000000000003a9a6706f02a677d45c87b6e0a81cce2cad32af32623e9b6f479d1094357a04231a20b08657ff07bb79d3f58853756000000000000000000000000000000000aa9d339a4d17f370c2f66bbb0e9a56d4395955c63d8ffa95bee8b890c7df037399f91308cb0af610c6ec46f22161d070000000000000000000000000000000009762ebf13bee4711b9bf94be2d62d53a5393ce033f6e70273177199a059e83a4d7621a1b05bc04ccbb8427f93a52e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000073db19c240fada52a067d45d4108e07ee2c951a6272b529d2429f03b7cc33650e6d426a104e60510b5571d12a841510000000000000000000000000000000000b1143f24f3e6c757f5709590c2df88afe089735ef17962650c4244aaa9765c05bc77afd93dd8564215f80d99f5825550000000000000000000000000000000011b4360e64f0a6d45865f8dffa32d42b34168c5cc16bc4baa209e44b99ac0ece9856231c59e9aecf873cff4f547e2761000000000000000000000000000000000f8907d7c23ac7e80af23f661ec22eef8ed79c3e73ea762edae9eab0bcde5843da1fd17a239d23579332a84b53dd2a751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000017cbc6966fdc577914413cc3fc3498f402e58d93ec0693f831b557c62c2fa1ab3d0ef5f0f13466a270fa67768665b5a000000000000000000000000000000000f33e99fdca45494a658c5c60c917ffd61e523281cc2d4d3dbee78f8d38c7e4f481193c5427e702b7b96341e543e0be000000000000000000000000000000000032a22641b45ca6ecf99bd3edf7155bc56acd971fbcaa3a638dfca070687e3ce3c58e0a5be1eefa7cb2720abc9016ccd0000000000000000000000000000000004ad230c32102ad6457a63ef85ee624acb83d799435c80ad5d8f0be16474f42178ef4a104783d9a1be73e6596aeaf8d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e61ab298954f3b737ea23a9aef44661bf6f42d8e0b9906576ed786a30c9fe42fdd835af8b5fcf596fe5ca074fa76ca400000000000000000000000000000000015f79924291d107130d8da6e23104b17229fb8cb903f718c9331f4f044a07459159b3b13afddb9c212c97e7fdda63370000000000000000000000000000000005fe913d8e9546eecfafb015a288baf36bac413b640f96af607dbad70cfceeb6e4439203f5af2457b0aec1fd40b004b0000000000000000000000000000000001055b5d4162b18bd2bfa1decf2b1bc8145bf83c77938e130fa666b23408f3e7c46a172b30188cefe66d6e3b8e84ba3aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006c1c99dc30b914759d98613d78f857aaabcc233e8b5c2b2167e391fea479d34b059574b9ba68f565643fbd4b178818300000000000000000000000000000000084dd3cae520eda2cb8a398c3e34a5dd5d1f790c7f9728d13788b3caf776b8eadf06760f89a29151689c94dfe8fbd1a000000000000000000000000000000000153ea85bb9c51e6aeb49c6b2f2d95cb27f3d58769d98ecc71d4bd0793ab0da0c893090c53f8af714a7f0659834616175000000000000000000000000000000000014f2b3c1511ba8ba23acfe3926dab3198cbc2cb5cfc76742ffe1d34a936cfd886a8ab621cd68aa161f45584344b2bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c589772f4b5eb3acd2643ab1dee70641ce76385fa4cf9c6582b4acaf8ae9a041889fd6a3f26a8187950bcc8d21ff3c2000000000000000000000000000000000c9a5e3b5e77fe4cdbe7c03f09fca02f150b3d65f63ca6eaa43e58e85ab96d44c2fef4da93d667f6a32c354c803b6d1100000000000000000000000000000000185ad8d9e7a7f214f5ebad350a67effedfa89157d84621974c6e28d09a9bfa1d36a32b09a925383be6154275da6cfe7400000000000000000000000000000000128c410094b18ef99ca51c293b40b6162d339197113f1de3ef1ded94f83af65b8d10283f8c9bbbe2aba87e4f9de358b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d4497b438e636884ebe0b0d181bd93815db97f2978df424804bcbfcb07d5562dea51424407268ba4cb3ebfcdbd4fb5000000000000000000000000000000000d08d7baa6cc3dde8c4f4dc725e2e86716a1a1c9ba14d156151bde0c77e233adc88ec4412ad77bf092b07a0ca3ff626e00000000000000000000000000000000017404580bfe227f75aa08dfce5b85c46fedfb06e16d2449e16cf9bc81238e2734131b7004882d0981762b68bed574eb0000000000000000000000000000000007b2674c1865836ef7026a8579e9ecbb39a5d7806fd92be31ad5af45f4e4372943a8f67dbf6333d15507feac08d20e7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009e011f3eff4ad27b3e1cac496ec95c6985c3d260172347f38e39e77aafb78c7ebba09c073e6bd0e3c8324b2bd9ba3a900000000000000000000000000000000117eedc3d1c9d06663a175fc891a42cc316785b1ba2406d703fd4bbd396fb9990963f264d9785ceaf1c26af2f731a19d000000000000000000000000000000000e22a6017880f63b2134dab76f1b27be918e0693923000f14ea5e0e8195c8b643d3a4589adff0dcb0a881d468e8a7a1f000000000000000000000000000000000abbd069a9f2918fe37fedb343166250d3fd7562f5e70893ec98750655cf1acd4742fbba0de008c3378df8316da519161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007692a0b182fbe1784e60b3ef86c7ca06ace852f26c9f32f49622f9844660ebdc6e43ca6ffc75c3f9f0ba8eb30625b9c000000000000000000000000000000000aafeb601fdef1f076bd027ca4720844bd1db6de7a48d182280da2f81f8dc00cd405765341c7f16a8873d19cfe2e1b8a000000000000000000000000000000000b7cbee977b33dbc59cf5148a913918c3e46482c859fbcaa2bccbe2327da10d0614dfd229646717cffdb2c3a5a2b099300000000000000000000000000000000015f5fff1e874e25648f9d7502e2f7cbe3a3dfed251b26b530c36e277e92da477b1e83c3589c41b1dd6310a94aadbf7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7b9ae9122b92761a85741255fe7183c9b7b239d4b21bbd669de945d37295ecf862691d93a43a3d18e9854fbcd26bec0000000000000000000000000000000007bb1ad0ecc377426ec89a238d50b0f0ac28aa76e32fda1b5873984a1c1dcff80560b463f9889a6dda81ad70466c6d3e000000000000000000000000000000000da826d861474eb69903060a262f79eae4bbdd61adefa5cb53a5fc9735c7c66d726326fa07a5e2ea55e88d979e98a6ff00000000000000000000000000000000023b2d0cd06ba7f5ad356602a7177678d09b2e490aa5ed6ac57e08a1938578d0b7b5cbb87bdb875404169b630710f3221824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb3b100d5ec3422df637970c18c9d8ca3da5966e158b25af12ccaf3dfe1af666e2f2570b91a967ead19f87f7cb92620000000000000000000000000000000000c4811526deabd94a7e837736f3588f3786f9690b3edd64c91e6da2baaef454acb258ab06b85b7594e467191b30e7c580000000000000000000000000000000019d99db246ebeeabee8383ff13660dc49befb6cab8bf254032216d726fcfbd61e35019233519fac46ec45a17b2928103000000000000000000000000000000000b216b7fda65e88c2ac675777dea28a52f23d9acfd05a855ba0e471f5d1276be184279ea1175dab504180d963ec1ad101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001513b6468bbcdb0eabbe0f4a53a70e21f37273503d4d437683f666dc118397c6055e07acc07dcd55b50345ddd79ebf4700000000000000000000000000000000003ef0709f2b15369a1e772665733e1e827f57ddc0da706eeab748954f5a9802de2b6906035195bf37a1751e1e26793400000000000000000000000000000000017a7c7622403061d29f4ddff05541a6dae8ce9b7be3c50ce9620e51d081dd34ff6a2cd51e78f87181f71ecd2d15877c00000000000000000000000000000000146665a1034e2b0d09beb5886a72849f3c27e46010caac57dff6b58388486ed49829a3c39385450be371da07ebb5d6791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000050cb68ce51b25935935ae47c35d564a25e9a9a0a9fc391662ceea18724e663c2577c780f3bc44562bc5107f28330d82000000000000000000000000000000000ac4eaaf5cca3898fb11d70e591949522473b3b58a6ef89e377f7b391b960ef3a61244e97bd4cbd6826ef13257a4f01400000000000000000000000000000000079e3029622d7bf192a3b2453f642763ae28a9105ee56ece44950061745678846a9e9f89c379143ee69a0b53b457020000000000000000000000000000000000184775d86b8c5acf8f8fe4c9647d55aa33bbfa8b8ba61aa4c73a1c3523698160b2c5773d5bb03f135480c1fd25e2dd971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f22f2826da1fa1822d2cfda5e629d977357951dbe975432de71683c9142c43ca895279f187fb0fec08246cc0a71e970000000000000000000000000000000011bd86ea3a95c7436fb3b8d2e9b5912ea86ad236a17e49d86f3eba4b0768361edecdf9440f825e9faadbb6b97459e35e0000000000000000000000000000000018c672c269f91c84b5e0027d3dd974d6bc86b7c2dc0641e8001b8a3881b8eb092e767b63c234de0010933f2e08bc30bf00000000000000000000000000000000018cff72b5e5273f6577a3e3eb7d8fbfa642ff5f8101bbb35c594e69bc08e991bb8041d195f275c85056e57e33b1d0d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ffd7cd5ca0aa27e773a7191d6fc03586f14667f6c556c9d09013fb83f84cd97c7ef9013385c12bbcfd9051bb87f44200000000000000000000000000000000091c05ffb3b28cf8e1c163fbcd3139b0d5fc1d10293e4e2f25f994ea14bd08dc9ac21089d886b704b31f68dd7d3b5c7d0000000000000000000000000000000017c1595ee22590c96134a214a77472410ef609c1e1db9650ac4e1588042ae169128673a05bcf0c8ff2b12d06951d3466000000000000000000000000000000001833df4e5cc1048381445de8de3bfe1d4f241459288478456aaf34978f6a380399acaab868083ad8582185380436ab571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e47184b023d6d35c7ba9093dacb7571947828312ed459956ea2e415c29f5cfbe02b84f1ab648550b3eda24ba13b26c0000000000000000000000000000000013c73d6e310a56b196270406537d0159c86bfc5ff877c852711a7dcae18097278f68945055e0be6b778162e711ca1f43000000000000000000000000000000000acef48c90d7ee271a61d50b3d65aaa1b99ab2f65bf32fc7b7999a7953670507e1ccda97d8919f70148f511506345d660000000000000000000000000000000016acdb8da4193beaa227351df6a55b670210e2a7124e2366eb95214f3ec3e343b5f0205ff0f8c830bef4afc56e17c7311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001395439f868feb6745b64ab1ef355a41611aaacb2a213e6b897bfef3d3d8b8314b9bf12885d3925a4b1db1b5136cd1b9000000000000000000000000000000001400604da6f36e62e8beae30fe197604fb33ef0ba99735f9ddef4039bcb1828114b2953b565f3938aeab320620cef6de00000000000000000000000000000000026d84086887ebf4291ba87a11a30665a754765dbca74bb2f235e570595aa2d76e3d0bd61f0b095fe0f9808ef5b099fd00000000000000000000000000000000005a513a25e59fa12bb1c7ed8d89212485d5d01ea1625b4437745409360a3dc5b9e27a394e818c03117c361b67209b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce8569f08169de51a3706d984b1f4f0c08c4c916138db1be6a57e4e627e0706c41768fe3f49846af82afb43438cf898000000000000000000000000000000001498ef13205ade219aec50d0069338c4fa45bfd6bd689cae24e2dcd9003717a98084a8641d4e9ef30540b29757d252830000000000000000000000000000000005558096f859e13db6fe84869cd99ac7e420294eaae9e428114d32e3391a54b41a5cb200ab4b379a5c0189405ff2968b0000000000000000000000000000000010219ef05b58f74890372c8d3be53836bac20b30c46ed1a4c22f11ed5f019ab81078a4ee7ab1ecfb21f4c351136ae6a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f759777e731df2034c60d29674755f58a2f6092be37e1b02db33c1729c949c3867379bb6279b88c426e0c7cad0265450000000000000000000000000000000015d507d804e6597320433ef73fb505a67738e7d333c989e5e1f8fd61324d29905e5af3696a0c19c3109099d2800106e6000000000000000000000000000000000990339a2af7715452586d9df922d2ebc833fdf2d89d1940a643b11a3d8ff92221452ee3a89fd69c6f5e2a210e61d03d0000000000000000000000000000000014ecc0e4b804708ac7caca8cccc886c910e077875198ae0c2fb247abdf4c599d07437517681469ff8718da2fc628a4d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006efa923c0509e127066c2104122d9c40b24a338e7a3ddf0b60f09721b9f16533c91556fe01ec8d72fbd79186e9d52cf000000000000000000000000000000000278daaf62d08182cf2a0dbf0954aeba29febd95fdef299f38dca7c336495b3c2256d0611aecd5230455f24467d3d9b70000000000000000000000000000000007f9aef123f0bfa3c315fe544c4766e88e011cd9059969b3967a187cecf1c1227c04fafb15508911b927be3186eb941000000000000000000000000000000000051a36e77081f72706e3560ea51400892088bdc7b22b3bd5256a2230ed5b9c4e097dcc093e4162310d520b199af319c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e3eb9ff83995b7f95408097ea4ef531fa92c9523b3286d1df6699646046b9eea67dfe13f9ef9a2df28c7dda2e31d090000000000000000000000000000000011718dd69b25f7abff3395e9564a0b9b5f4a0c00ab4aeacb800055b615e32adc5036690bb186243743660800bfc3b640000000000000000000000000000000000f50a1f5b4f06613074f70ea562eb8a5f844f66a74068e9a2a11a73688424211542a84811bfeb71c6eb27d0b0ea65e1b0000000000000000000000000000000004a005a4d7130848c68b94af93d5fbefc7f6f8cb657931058ceba27724466d2e04579c88be18b77099bd738da6683ab21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014d1dd1dd217a9cde2475e654be17f3a78d85890301c52982dd49706920b7b270cddb2c0bb3671c259a7f8c7ce85e64d0000000000000000000000000000000019c4e618261805f2b5d70a4ac68b00528ba923146b283bd2e17af9fc2b686afd41e658e67b5d704e8ab764c39efe70fb0000000000000000000000000000000018060aee01635d1b937d91ba72e51516353ec0025e3c57669643b00cc6b4b820bfb0b56938e039a53240c94266aa7b06000000000000000000000000000000000abc4cad0eb6f65d7fe0347e7985fc05d74fa937d874ff46794b826ff94445fa997f987ea52caa1e68a1858aa628b95f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030d154a0b134c03ebb9f336789c350903e6c12e775f825f47d24c919dda0e7dc9a722a41715458d87e12ea32de43c87000000000000000000000000000000000c518618c5fc3a8a2b8760d8220e04419d0ac338d6b6f9694bbed5343faa77f850e70475abacb2292ffccb3ffe224ce0000000000000000000000000000000000a0cfe9f3659319f97b3f3948e294b34b42d95dfb6e945dc7a7e03226b0a4146a231864c51c22d55ae811d123a64195300000000000000000000000000000000093a40b8b4643bdd94d7f1571c589d9f3935f09a458f9f16b272f40602e740f8152e45f553a65a7e6b7e3bb3f481dd091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001795f115c7945f0561c338361cee45305215f6c57381df27eb4116fefabdcad82768890122baf6ab393113c24ed7e0da0000000000000000000000000000000017f2cb441759b475eb760343aa2570470104d878240790beb992c747cef57b775c0990f205d5c3ff10c6e909ac25a0da0000000000000000000000000000000007ae540d092e8180a02ba99612ce7494532b7739ec1fd685206c2798d1e61fb04d659a5bcc3600901b559f453cd268c200000000000000000000000000000000125bc7b95f90f0820b39f9450f7e55a85eb743d14073fec50c8162efcbf957fcf664576a73f4f4b7d22ee69af7e209861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf0175f5e7c50e0773ee91508cc3253a95588c2f5a35627443ed50d9f784fa7d86e88ac909a7e2a741130c1aa5c8d95000000000000000000000000000000000179b4e50baa1fc88b34116367889b47c6060f53d62e5c5cbc14d191e2e6d856bf28fdf1a4775b5332950465112b08b3000000000000000000000000000000001449a97876659c4921b4c8d626e008ae6d03a6a015535a711182fefbe59794e1301226f471e10627fe1101e1099ec129000000000000000000000000000000000659493c9cbff875bd2bf2baf02a9496c9732037e6dc08f914b4af6d4485e4232fd9d0d6b560ae1b02546f0794880be01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000859262db2cdc304e4562cd623bbd46490ea59c3937638294f95ff13a2f9b273de03c5de72fd8e1e0fc4badeceff0bc000000000000000000000000000000000c8ed88f4fef993946d877c7507ed9ae1f918fc4cc9b850b8e0ed879e67ea62f46de6ac8a77df759fc89cf0c7ff3198900000000000000000000000000000000046fd12d8ab0927102ab263c49fb1274871e0195b3cfb2d634f11aa4baeb1965385a4ed64d77346505288a4f91a551b8000000000000000000000000000000000afa60724f687e94e1f248dd8bad2c038cafee52f5386d2b8ad8654d59e007127c8b6820ca2a04bbed69bb5434f3b5df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077418a3c46b379eaf47085e21007afffb658a4cf1dea497fdd27b19b69dccf7ab04ff11bfb9e48187a4b7adf056b7830000000000000000000000000000000003eb945cea67d1d5727c1aeb37433bbf15044806882de00b7fb9bb706f8ff9819345d61858e3b9aba336d5b26e630a6d000000000000000000000000000000000477570709fb0f57566649c3bcd126775b706d49dc4267738fc1afa92657dbbe3af9055e066be4ac01b98bb9404a11ea000000000000000000000000000000000d740cae77e960d513050112b469c84de9d0b108647fb8bf73c7e2bc85dc293b12ec1b95fd58594d0d45e52411ad144e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000131c1f2006e29dca0ae2623128d37597261ba5dc652fecb77559882c9c21ea3ad87d2c3d982aababfd83cadbe2d1e348000000000000000000000000000000000aeef643a99ffecca76fa57914ba6fc87b3fb7914adde621f3f16c370375b575178c2c04bec0955323f9ce2b9d9e5db2000000000000000000000000000000000eee97728c17fd8cc4a14b75308496861232e73aae58db3fd6ab96aa5505c64cdbe8e71ed274cdcaaa0d62f1ff47f74d0000000000000000000000000000000011209b5c07cb451382e767805150d26c9d63b1197ea73231f8a0d95c934dbad06bf1d1ec5156e96724137d2a2e4536291824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c7e83627dd9bcb4ca46b32cf79bdebd6d2ab4217f73fade21315a432fc516643239467a57aa035957cbf5eb89072ce00000000000000000000000000000000084c5e2fc847b36cfe3ce7b9fd0471be0c899a759ac435a5328fdf1c29350e293e17d2d9b8f293d435f65091480127310000000000000000000000000000000007d76123b68212141a30c75c013f8e410ea37bc879db5b8a75fffceac0c96bb56505191e2ca6e44c4f894d873847f38a00000000000000000000000000000000148d142cce37b830b7de5b38cd97326a5a90ec5391b0163daccfd7199a4127b31b1335492925b2b6fe576cc1712182511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003d3c1d2f0f11f02edaa76c3e790e99f01f5a27df3177dee4a6853c9ac85c5af8d2306390b153ad57596fd1ba71aecb5000000000000000000000000000000000a2189b3dac8bb078c41ae74c8fa65d51191c8a441f621d6d942c8fafe1a420b3cbd7f5f5e44c638755b006adc98e1500000000000000000000000000000000006b760d7f6e3becb686b27ec56987190d0c3db3777ef532a7ebb7ab43b990aa148d210eec51a10662ce8727878eda19f0000000000000000000000000000000007c343fc7c677e6d96064875ed91fc76805a7108fd487534ef7dd1a5d84ec492a1062ca481b2e629977ba6aa173a6b581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000058e7d62ce9ba970c64679541ae2be236feada2a97d87fe7744e632d7a16c52ffb75dda0af8f8bcdef489b6e8af154030000000000000000000000000000000015f2ba3723391e35b101653700f1e9ed07c4e7554ef2d4f3d2da90f655d3f2e9ab05b0d9eb7d3c37e45347d0a7ed0452000000000000000000000000000000001672f7465e171d0cae38da2ed21055cf9b546c492dac944740e2710d7e5bd2780937b969ac7b99871ddaa3beb99c9d98000000000000000000000000000000000c2d56b6ed9dcc38004c476cd8fe9ece8aaf09ebeb32ed5e41ceb05fb15fdaa92987cf2dd0bb7d1b688192f12d4beede1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f8034bb38d294c61c33559c4226c5d8cb1325b46260e5bf840d2d2f2685de93c6df86a75b26194ab54e5f0d68b95fc000000000000000000000000000000000ee978d7c0b2e3e236b4867229cd4c887b58b5f723752f91a77c6f29dd3bc595d03dbd505718194da745755d7f9fb84400000000000000000000000000000000010d329dd25a76c4b978982bd015a73c1e3c0586f3ccf3bfa2df81e4adcdc51e13d34489e17808d30c36a57af58c332800000000000000000000000000000000013e96497276fdc44a087e6e1d62c0c3c04fc78f5233c4492ea7b9429b68e254a892a0b34886bb3abb3bdc516004e6371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000121dd21b17baeac663e9792966d47a5d715e61041c6fe80c6ec186820413ada72ea12b955c053862d3f7773d83ec847e00000000000000000000000000000000010bf9f2343ab0e208a66824309ef6c51f512dcf8e1e22eecc9e7f56fcfca439d01894519630df9330f218bc87cdd5ad0000000000000000000000000000000013f86142e0281cd038aa57650fd59678de43e7f76ad5391bd0ed20848cda53c1cafc57f130cdaaab308257a4c19659ec0000000000000000000000000000000015da547eadc3d5a99eed8031f63d67c0809e02392a7ca2d28e1b3d94899065f7cfb8069960ac845262e12c83ae6156dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b0714339dad73a7de22f9fa0af58e1585d92abbcdf57d47b1f66c11f3ca3f6ffe903a7427f53be05260f61b819954c00000000000000000000000000000000141af443a4df61c5546c4949086e53596861c900637d3df286a8c68a7566973f073a482076478f18c3b612b2d88f9baa0000000000000000000000000000000009be71b461c07285c7103c92123f13889e6969b94875245bee78e9c98e1003173a698fa967f3a846a7f108a7eed739ac000000000000000000000000000000001562d1c1599a7a4310841e3f97c700643f4a111268cf1b9c989c1f7ca531cd650df67a5ae48dfd43bce0dd0d7f7adbb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000031939d812542c9ef30bd4f1c21e2aa3e33d494ec10617d05cc36757451628be03baea5fc51713a965c844d0c5edab900000000000000000000000000000000122e35986741489a38d97e4248413e5fdb3d887eff462712a27a30b4dd1a3480052497d758206a9760ae4384eac87fe200000000000000000000000000000000095abc9ba44ff55f6b81645ddafbf9f599558f864aec27058363489e4c263256623bf3a127c058c7bb713472efd70fd40000000000000000000000000000000012d06e65f40c4216cb077d5de93a40851fbba01b74fe7d196f5e32b6bc1b332c221242b84f1e9b34042e06d2b6c9e3ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001638baea78946107ec22952918913f87d3018e31378a51b0430c2bd2b1071f63b99c06ac7f4f9fa42555748b7a23b522000000000000000000000000000000000a298e52754fa6cc576a3b578c07fd9718e1aaac6a38d70fc913724af2e7a9b5786d556672f72360b36be598727767fc00000000000000000000000000000000142fce650aeffadde07e3979f7f0d0d22a8e9bf9572bca66182dc412310d23385bad9e2641e462aed90b779be79820b2000000000000000000000000000000001551f9235db2f36d114c1faab8fa3384dbe7c99f78d562f4269296a254346c9990075891fda5697c2c8e05a7282766c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014740f1a7b5eb588b656c234f0ac9f019c482e382e16309bbf1a2f89c360c06ccb5ab60c042e1b628104a886905ec40100000000000000000000000000000000164c2e7f7eda9e0db0074199a2a57f2b406f07008205bcd54dbf0934cc39d5a930f5eadd89a3dd2fd257f0c87f489c1900000000000000000000000000000000055db08413b3ee16a71a93e68eccdc09fe29f60760e69340243fb16c215dd58153ee160890db7f983a2cb5d9e27b3e18000000000000000000000000000000000bdac21c9ab4620ad96b62b2245b1aba6ada4798192358cb6869d950c646dfabd2717a81882c0a5b0b3599f3334cbe401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bc63b523e089395225098b4813c7c710895386428f7c50552036b01333da723c8a2bb4c79455804c3edf0fccea987f0000000000000000000000000000000007f85e66b03faaad161153a1eefbb515a926ba68416d523f8b54e3846a02f3f8d3ced29d5f2129e43f0a974abd362ff10000000000000000000000000000000016585a5da82e782612b97ef9d12dceb6556a437a26aa234889b68e06b950854666330210d751a59d281df4b4bc0a153400000000000000000000000000000000149a2887a0270c240075deb21c1703f2ab2a15496d172251c7daded0c0ccf55742d0d9171ae0f89afd0d168487eabf5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000852cf8a375f3d008cac0d19e9cb72bf5fc1c9aa5b0a3adb24c4f6628558928703860d381869acf14bc358b084e0310000000000000000000000000000000000d64b64983eb51e5a8c012ba571e5d832652fce1f99339a3143f4db0cb206186b5b7888b6914178fe4e5c8c3ddaf4d6700000000000000000000000000000000061019f3f06a4013f1e24356c19732937d4edd4e81beb934f74bbb0ad20c1e7bf85b106d13ca1f1fcb22a0e1889582260000000000000000000000000000000009b023fef413e9ac43f0f87de5a3abf1bfa246f8c415aa18e300e49831164db63c3fb957929e8548af07fcbf8ae698861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb5c7d4f467c24f80654f743a9f83225712ce63e00ba1a86114c86b04fff414ceaf24518c3e936ad444979e21ff381d00000000000000000000000000000000052b32da77e600b0f96b48db6679e6c8a8782cf16d7e86aeab87bbfcfd52f4beb18c2b71d904058063835ae00f2482c6000000000000000000000000000000001553f18e43b5ed0ef74f8f5ed87d30cbc95a0dd51138e9ce556d7bd6107c864d30d30a0701710b6c829236f1c0e003030000000000000000000000000000000014fcbb9cccacc2def9e49866a0f528bffb84cb58f88d852d2ae27c405c75aa28a0542cb7f24678072faff7b15869c04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000098a581ccb98321b916c2e995f960196235a4b806de94212135a02ae2a537a8bf7a58e39be7ecc678ebe1e3ac73f39aa000000000000000000000000000000000e11165ce3d64b3ee070caf89b4f016f43a3f48dd2f5007ba6ac6ff0ff7108015b65236a535798153e88356d4b77d96f0000000000000000000000000000000002136934ad93e33c5e22395ead8a7132c58231c7ee4ea82da55d79795c9e23ed8521f6234997453529c5d4829df3c9f90000000000000000000000000000000005f78cb942f25ac11adac9d2200d308e14f0640810a35b4963e3e75858f6384cf2e9f1e4491a192197299eba9df5126a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f691ab4955e5cce03d8068967abc194d348753a73209f15ba4cc5cbf3f825289f9dcefa659a739674714b08ea712a10000000000000000000000000000000012b3e9c5f4deff1b919d496c6e420bb22e28dad4c15c0f9c5ab9f17d6eefece81094e5fc42fffe7d78994becf63e3221000000000000000000000000000000000748fee3417c6939978ca6cba04cccbdca48dd1f95bd75fd88ad14191d92d218851c2c68105605fffc16f91f7540cfb10000000000000000000000000000000008b9ad7d833160ef1f56935e6382c43d04c0eb9a7949b5cecb4abf2b9bdc3def921c50ca6f2320053a88cd13536d2dc01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016685084dace53c82ed44e49da76e0a13d87096422cdf4baf2d71d18c50de72b8af64f14f5cc6f1acc3fa5111408bb9a0000000000000000000000000000000017b59bf54a27e11a7add43a544d2d2355ae858212ba11ed9c77a0fde7522047cc4bcdbb40faabd80249e70de83169ac50000000000000000000000000000000003fabebbcaa3ce87dacf181b647663a66cb5d3958ac90d72daf10d3043fc249e773b5db09af4e771d4d1517c95d2945c00000000000000000000000000000000092625d8620a75cbd09b6e66bee32c597afafd8871734dd69874ffba53730208bbce11050bc204aef397b4e159ede8591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d708b455a03f86b396c70bf267a220168c7a6fcdb657517db9290d159b8bc33f496b2aa2f9cd0356822e00cbb65a840000000000000000000000000000000013196e82b77ba7386ac233535c3a953c25339131f22a6676b9678b3a9133690c765ad16b06f259b31bd6a86c84ce8a9b000000000000000000000000000000000e889e33c77bb11c674a2864fabcb9174901a333e58bd75b48648bdc870d12128ffedb7f222a9a3543cede121f48bc480000000000000000000000000000000006c84c529828fdce11084e75582aabe6b2bc173f4dab3d4410adbdedbdcd2b84835c32241ad344f1043fabbb9f94aed21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000137d1380c1f0ef858215734af63afefb588077a47543791a0133e90f33baa1cc71ab5f41cd477be04280068a63f0a63200000000000000000000000000000000187bf6045b561af33baa41772435a6e6323f95aeadd195659778841e2a7edff09fdc0158028eb9d62bb60e0f5d2907e90000000000000000000000000000000017b30e1355ad34111d5f7dba6c696ada76ac491f08040b405304b052766e38ecc9475a059357207e596756494f241597000000000000000000000000000000000cb2c01b4927a8726180c5986ea5561ba21d62f781f14f51f95f44479a669c5231c12e3acafcbdad38b2a0a55c9b47a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc703e60f9674a359346992e790078b49fb92bf32bc484f3295e6e73e1a417e2ed885e2fdc7f7286dc4d1839f0e59a50000000000000000000000000000000008d469bb9ddef72a7b90032b3ef2792cd367d2b3f43310270913b2a1c347f329cbcc8833cbcbee036e0ed58b394a64ab0000000000000000000000000000000009e5aa3df44e8817e5d62145aee1c5d769383698e4df692aad232b481de2e0409ac9ca3262c2dbbe7d89ea9c3e809b0400000000000000000000000000000000057f94ddf81a70d2569ff6dc8be4a4f82343a12c878c217fd3d21151645c73031af9458f4ec958a6faf82e4ef79f23ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006167413857edd62f44b21d23ec857228429cfba8a0e41115044080ea23c387b73cd15871a95f9a4c5f777623fd40c7300000000000000000000000000000000160fb4ee7d8fa231ca190ca3c0cfe685b65785282915cbb3afe2935cd2bee49da6150742945f2c37ab7bed4a15b42a240000000000000000000000000000000004468e5345e3b7e28c2ddff769cf421c7942fd1f5541b2cf47bf7a477159b1a080a2cd54da8815f91b3861522acd476700000000000000000000000000000000154a0846bef0146652b797d0b4e598ae1a8eff6e5b5034471eda1c650a56b6f0c2b97d38c5251f90ca93c090fa7e5b501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab3599f00b4a21f09628adaae8ac30108a6d062f709650c8322c77479c04ee589288f5fa3ae9a82ed02815ba2ba899a00000000000000000000000000000000176176cdd4845029f4cc6b5011bd490bbff7f6069a7a5d8fd8cb5069fb3a1b4cbc69c333c6d9e2aa89b139e1b65980190000000000000000000000000000000003b72a3133656b482dd7049bb544acd19924f1451dd86e32d3a7212249e67bc5177fcad037694ecd597ac86c66f274aa0000000000000000000000000000000002d655431dd3b29ddc096a4e664c23779aaad98e16dfa90df14f72903204c0c9f4f66e3992aeace3fa2338f74171263b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ede393b158fe5591f4da6a869143bbd2400365c04539cc12a559acf01e254c0d601a6a12544d636fcf7e3d3135c123c0000000000000000000000000000000011f97f10e4a8bc45322f426c97bd049ccb037a12f4c741ec33943404b300582af74f2e83d48bc9f10a313407b867721d000000000000000000000000000000001497ea1e46d7e4fe89a84763fe3e497a78b675630234a1f1ce3f60f958b42a6aaf0eb509aaa43b244d7ccb9a991c2e1f000000000000000000000000000000000a4198412821b04ba45de4d23c8a9a0c59e0920b7ec6549d75978f4e8f7739b98dbf5f33d7c4507bc47df61ff79a1d761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000053132dae59596dde08c45e7060d07e7f3797729c5b9cd0ecb8326fdc2d1c96d404caf10ee900d9d72c030c6fb648d0000000000000000000000000000000011c5e9d20b46e40418e06f3c3d4188699272c73464202f875951902cf32e9b9dc595d04a80946032352b66fe515fec30000000000000000000000000000000001751bafab5df35df8bd6c28191e88eb7249c42493d18afbe8d6ac7514b4084b7ad4dc49226dddee549622e3c685ae829000000000000000000000000000000000d0ef2be5955673aad69b717953297614ed9aa323541b459ee956b27cbe7728e10a894db3886eb94a75e76249f8429741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000aadac19becac10482a9038428ab74e0ad51016c6557230d51a9138085803970f36af3e2a36f811a3d11b363db5b99e0000000000000000000000000000000018025583b1fa53a790021759b82797c6fa54acd22f7c74f3ad1f5e41f4451e5ea3e20924be461b910bc9e5c28efb7eef000000000000000000000000000000000898956a4d39ad8896fc653525594f44c8d975e088d15f97139b9bfba87d8903b866dc64c45d682367cee414c459c49a0000000000000000000000000000000005d234661f2f86d33e33a48baadfc9656bd376cb825ad86531554858f1269030c93ccea336a019067867b4a33259ccbe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a7eac3bb63de6d876acfb6e3eb81c2a8dedfcef7d3abffd6346e408f795d6dd9c10f6d7f134afdcf75c16baee518190000000000000000000000000000000009747c6f8fb73013a5c3e1e2ea678043e2838ce8bf24bc4f1932d0de55b01877ff9940c3a42c33fef3d5e0bb24aae162000000000000000000000000000000000655e0f82d1044d4805e029cc408b4a57843f5b7e96ac10f488cf51eb41a5b0e09af8125c05685f6623b4b9b1947627800000000000000000000000000000000178d2285aef475e34042db7db1ceff79cd442b76ef98f3a97c33f3777d08983150d530d227a58d3bf14a92e0f57b73c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001218ecf0226f565edb56cc9c0ecfe200086dc34e55139c91e871a8b676c6739e8927e27cad23b894fcf3c06cdb24b1fe000000000000000000000000000000000be54935250e1d066a78c0f09d0f91b33c3a13e5fad51917d901bd99e277923afd80f1047deada6dd37169c845c65e450000000000000000000000000000000017a151f2372cc23d0a4a06e9ff3fd4b4bda0b79d73f43234eab224a90e17a8160671490bc658a0f8b931bbb9a0679f780000000000000000000000000000000011b11b501d68c4cafe67b8c180f014cc0bf3b8994e75dbbe6027fcf6de79ac2bd6234ee5877622a050c77fe6d3cc16f71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019fb50fc64280893acf058da72aebe217ae6b55dd5b6f7f37929e6f3c3181c9019a1ef3c0dfe528d2d559126476069c300000000000000000000000000000000075ee6faf0b30c785dcb45521ff2b9825991a2074436bb7883fd6477a2231d64df2cf31e7da31a05b0d0fa39388f26b900000000000000000000000000000000072dbf2b635f58a2f439d6ae796ce93ee56370f4e6ec80d384cf76d84d15bb1ae19d6548200621523d4d26318ba41b360000000000000000000000000000000002276231690e7de1f538b3392e81d370f937c4d6c2000667cf383c244bd52b16d29795ca7b81293cff969638f98af3e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7395fdc354e072439d74381fc7812f9df508adb03e3e8c32c553e32400cdb45f48f017df0d2cb044be043526268c580000000000000000000000000000000001fbe86b8f93d2aeeea09cd6bea21f601fba7984dc52242ee42c2ed3d6c4999efb56bb2c4a9aa052bbff848b5a43aa97000000000000000000000000000000000d2e568ba0c18a91ade9c289be0f1ac36aee4b08d49e5e771ee0dcbc0b217049b51fd4572e860f75054a7bcdcc933aec00000000000000000000000000000000088c8e3868d192f6a5dff3c9059dca389076ac83c9231d9d52b0e2b5a700c51f77d2d5174e857ea1ecfdcbfa6a0b51ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012597f5a75aa5be46fe55a09f9e209bb879bc4558597b95aba12009b460cb8c3461e9a22ce2ec7740943aa9cdd9946c6000000000000000000000000000000001510b29eeb4159cc4b4404cb06aa19c542fbf57bf955c349440269ec85371fe877204f57100ce537f33344ec8ce9b9f5000000000000000000000000000000000d101b8d0d5e8c7193f2e659749b2e0630300c985cf6e46240a48e234c32f766c8c52785982f1c92fba1f13682ef8cff0000000000000000000000000000000002d1b45f1dd4c736a4fde4331161b3f6190fc902c29497a0e85c1bbc16191ccc4d7c75190b05e80c7011cdad49de38651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee30107e65a436e10af083f982a791eb18cc4f2c667ed31569c4595a602a52130d97eda52ce2460b7acb4a14c95e05300000000000000000000000000000000147830064915009206f9a826b0629ad29f63c5ac9f8371d86f66fc2ce5c67ed6f933a727efd8d7bb358cf1ac60ba71de0000000000000000000000000000000019d437907a3a4b86fc1c51a248977e2d12baebca7ba00d21442e33474de71ef5906fbd4462194cad9870b1caf2e5011600000000000000000000000000000000132b1f2ff463dbaf42e4bc83241ec394062f0a7b3949b351b75d9f4f67de40cba69b0facb8d4e122957b9148c6fd49321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0560ea5e6cac09e58892d9ffcb6c72356894a8c71734157f74338c09ca0b100f63fea224416d0761e17a6746941cf000000000000000000000000000000000efb9fdf0d97d737b13ff0dcc5101735bdb62408188a97ec5a607f2eb9b1ae4af3b1d83baad3b46354bb72d345b667ce0000000000000000000000000000000016dca7ece2f687a6975fe2a836db5d21a96f2549c69ba514a2f57eb29c59209cd2a00f8f46981ad3540a85aad2a1694200000000000000000000000000000000118d6129651bdc2a65413911685dc58d19efa153c0559f43ddecca82f96db70d0b335b4c12b8428d473c5dfa025f60ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a09a4a488c7f1c90e0684f716ca4c5c608d109e791be322c9c4b42fe4c65778846ff3309849c58b36b65a5837cf73ac000000000000000000000000000000000bb4b27a306ac659d903240605ee24ddd1bad4f3b5b5aaad299552fce13578154ff7cd5749a71f618e4c4b3e2d4a061300000000000000000000000000000000065043eea876ea9093372cc2ba7efaa9bdeafccfeafdcd173c19f02edcee289f89008f00ad6b115d3c39ee5a9fe2bab20000000000000000000000000000000014b4ae24a593533f7daeadb32aca1b81cd4e6bd17b1ad85affe03f83515a03fd48416e694777d5cedc77d23c4c756a3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e4fcab4ad53f82427b7e3fc5c6cbe388cb183379fa071319909f853743a0fb24d1ea34393cc45b1054c51b1615a9050000000000000000000000000000000005ad9dfe88a00645318ef8ddb689e470b43059b6d0a91c7036deaa4af9a4ba492ca6b540117c69d79eceb89750894ee800000000000000000000000000000000072a2d5f16e29aba211b2871e9083176881b9075d1e40b9c76902c44dbee784a9c98673f273c4183da0153e0ecf088c9000000000000000000000000000000001229d894c862ea3fadad286780f940123503d7c2c5afe325ec0474a850601bf245ed8a203f4a41597be25599a086aa3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ae8d656429c5f3735de690db51007771e3bdc36cfb9e908e5ed00404833ea9cdf17cc35761a18aa61910d4857b53dc000000000000000000000000000000000ec32b6a6509de2a04ac21fdaa3ed0fa8ab3fd8d6198fe3b3d5cf532d9d962f8c6bbafa991df50991cfce4ae8ceb50c300000000000000000000000000000000010f25ce41d4d831b3037ad030e0c18f5b14c7eadb8632437e75edfd1aeb3355b7c58d62913542373111fffb70853407000000000000000000000000000000000950761ba344414c8ca2738acdaf439442d7fcd7918608cefe231110d6cdb1f3d674e1a1affd0427e46fa87c83e347e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001061bdfe95ebb87209d74b96103dbdbd6ccf9dd7d614d7366ffea4919873a7317706a646c17b16d70e3b32fca3ef72e8000000000000000000000000000000001156d5a3f278c0c3fc7486dee78c52e26f30b9e25e613d147449c558d5392c1f77d94dbd4970133566f7898034e70e2b00000000000000000000000000000000123c1d5c89baaf830bce5f3c65bd5441befc270b5ce189a97ff4e1d2a3a8a9697a50fe66f523325f2d80e34fd620e8d6000000000000000000000000000000000df1065fc6cc99295908df3bb2a3b3fd75862a69dfceb05cabf6c712d97268476ac55635a51372a9161487f0f1bf2e1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000769f5c831832b201453c76bd672a423d2db4e05b93536a9e7ad1d5095e2910c168f51ec10886663b05ee087343e29c400000000000000000000000000000000193d74879104dde9b74379e7d7bcac1d65990520b93d00e8de1c0bc5dc80de91f4663154c5ec8794227aae8bce958730000000000000000000000000000000000d54f6fe9102a6ea945e23192a808416a5b5563c0b4e3f5c6862620003b6e77b416126a7469d5a74b1ed979ab1956ebc000000000000000000000000000000000239e1ab20fd7926b71e7c265e630dbd9cc4b8f208d93273abe9b4dfe19b5543bb478b43a84e85fc97ce4c50aef57a961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000138a62e89c56f22d01c7203cf9bc70112725d4d540ba4e928755bad7446a62e863d15e324a551a539e4d09c2443a78e10000000000000000000000000000000005d235de829d7a9968af5629c2aaf756d66535452ecb6e89121bad3c1641b5283f93c1901346e07c683da326d662b0510000000000000000000000000000000002e2af1bc34878948aaadcaf1d878fe76118276c0253bd034bfb1132c491447c8e127ee0af67595662c42566796923b60000000000000000000000000000000003e5a0aa48246add90dcd48225bf3e01e7e97fd09c1714722041a9ba6208f33c465aaa8cef7d0be1218f2ec0e4d889581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003942cf5bd72b278797346f28252ae4654716a4ec429add3f22975af5f96ba2eea976a37310876dceba9eca5197e163d00000000000000000000000000000000052c2cc3ac43194b1b933bf8a64bcfaad5d4f9a38e547f1ac95a1c72009e10e80cb479a9748869dfaafdc62e8a32aaf1000000000000000000000000000000000dbb927492f61a01c2f1aa23a6c27547793444667ea165bb3effaf4e2e618194c07a7b6e6092033b10f3afee7da875ec0000000000000000000000000000000001f3122dc1a0560e8573b0611c789e38080744f94cc774736be6dd1f54222cf2df53701ced4ea4c8900d400fffc39b611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec2caa8acdcd93315a8bea7f879d4d7dd23e20e2df2f8d325696b9f1ebda9a16d7007d40998742166199930d976fc4d0000000000000000000000000000000014eccc8599ed8a60ff883b78145d6ee2322789b5a187e5555e73e74fe6825df39b7a13a1b578b3210951c341d7446a0d00000000000000000000000000000000094062cda05cc366b6058ed2b92a86c5c5b9c295626c4bb52dd61fc1bdd49e9d53c64aa8f3ca6cb58bbc091015ef8ee9000000000000000000000000000000000d530662c8d163a3c5491203577619a323d42d293eb1d31fc2b5029a13c9b1998df11ddcb9a6dc7c35e473592b399f1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002582c6041056ff4fc1d2367dad1ed78f93eef3f4b5e0f78017a77a5498a0dacc454c74954aad456c4002cac6216260f000000000000000000000000000000000f61690e0c89ce638c43f10b6e57c0d784336dba9f715a86ae59433662ab267fb9914f54c0bfa734f0cf7e3fcf17fcfd0000000000000000000000000000000003734378e57b0ceded072693877931bb8b05fd0152782b888e0f7411c93fc2bacdbc62bcc6b059f6cb7cca5ac467476e000000000000000000000000000000001459d737ca0a3dcc867bd1df41a2872f05c9d2c5dee46bad004b5d04bebca3fdaf2a6bee1ef42bf0f603772ec82654121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4b2767605c0139fa3bc2a0be2d437c1538e5daf87faa9f2f8742e91845f5c61fd9daea20c3809bfb822062a12a0a150000000000000000000000000000000018a216adfea965b17378ab05f25184b3a0a31c263baa7b77990a1c5a481c4f29036e71c79e9cd81dcb81e68ff3b6cc73000000000000000000000000000000000158da59570f52f67677a544f0333dc63a2f6cf4087514ef3012ed967cbd6156455cbab587dd3f73120823081cf804220000000000000000000000000000000018d531488160cfe020bc1c45932f0e5fa303963f81b2294da7bdce32b5c17e101531b01c3821464efdf64676623201a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181d8f3e9a3ae4adfe1c591810c0b4afce2d00bfdfca492e16f21daff95db61b345ddade1d42dedef897646b10d040770000000000000000000000000000000016da12dec4bdf7101866b2de49e261f676d2c82b90038c18a82c82b2f70a4d9ce9b399c394177d93167de864632ec2ba0000000000000000000000000000000010d4fd88a97acd43233cab2844e7b1a6985bd2cc1a82e85185c8d7453b5ffd14e554e7641b543a978d4bde8357b65cc10000000000000000000000000000000012e3824fd448bc2f6a00db0007a2c02b6a06bbfdd9d51e08e709d9897070b59db6358d097ec89c886e6a803dd49af6e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150781b0769c415d377bdab84348ab4bf9ea0278a46781f761a5c7f7d5785e1df86b88a38cc1bb9b20020bfe608002900000000000000000000000000000000012b8748c5bd496e17a03b4004db93528e2541c9b5fcbff687a9c4cfe7bed997e13805180d4b6db9442de1877aff66d1b000000000000000000000000000000001836b670c9b94be7bd732e9dbbd0ff420b1d1d0edcc8ea08cb61f4c7cb8b125a2d9d15a443cc91ad43bf33bd1fcb10e50000000000000000000000000000000010dbb3fc1a2f74a303b1c9ec5fb4182d68c29c695db59d3947f8a13a3eb45e180306eace0b5e958bf87326bbb440cf9d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d53418baf851d031aafa773dcec128ff596a8af0106b94c7cbf1605542bcb01ec1bb6015e89c922a4d2d8ca4ad6b0090000000000000000000000000000000019475786c922f3663b5cdc04b1b61b1957e6a5185329c18c7478725307dd2ce013e247f6ac84f1bdbbc79fc87e388da2000000000000000000000000000000000370879af9df10de8f606dec85944d78bdf46e5bd6321d89513b3b4052e55386714e818c156caef121d5b55dabb95e61000000000000000000000000000000000b68d40a4ef98f44c07b979b897c0c6b5337071946e1fd1f02be3d31a2858d3757115710cde795f8f5180060e9733c191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942586ce3233de1a402661a12cbc229edafeda4704163a98bc22e05589964b211e827724cd2cd1a346ea659bb5e10a10000000000000000000000000000000001ca2a3bb9a199aba3a8c02bdcea6d3716043a73de5562a911592e4a78fd29009898c7ffb1c4ab7189a620eb7cfcaa860000000000000000000000000000000005234d991cf7018a8ede89a30392e66da4149a34625e5030979d79c08e7b3880b1963ae1ea794f0961640ba896593a220000000000000000000000000000000007c38370bf85ee2217e71068bdfca769fd5c6a58adabf39425ca8aa6d8e9e6be18a52ad7d6a6154fb8ec711baaab919f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013c994d8cf8e4499251b7c70832fed4b86dfa255788f8d1c90199a17afeeb705dfdcd87448eb0f3e76e913441f5b732a0000000000000000000000000000000010f8f9bf97c3b41c33a5fecb1095018b7031099385e4382dab1a57d3831ba5af8a04fabde1953d657330ef9ae51bfe1e000000000000000000000000000000000753bff5bf384e0916bdcfa5a5acee046ad0276a94384359722d6fe5d7d42920660ee2e920c6eff2c111de895195f55300000000000000000000000000000000197cf040eb92ecc3d0182612a3f47540955130858d4eda38ab06e32d3eddc6b58152db3fc6efd3febf471f00ff178b0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014dac6e8a15015ff190a74f8e144e6439079f217988955c0c3415369d11397d855d47fdd35f9a381dc7c093180e39a260000000000000000000000000000000002b01762ef3f2f2082d22ff4d0703344ce25ea5767cd907e0b98effa50dffa9c610d2888c3b73e16d132f1b652f01742000000000000000000000000000000001890f862601f4d7948764f29ca6fac6b6d4a7e719d92474b7f03c26ceb7d225c91a20adf0aa8a362e580e95a24121bba00000000000000000000000000000000193bc5466d999634cd98bdf0e73c5f456f7f80663fcf3126e1dbab5ede721b7c7a4d906661967f68861beef99a2de4e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010df820a10ebacdfd0bac38fdaa746d422d991995ccc366b2681991186600fab3e9cfd9101bf4b5b0c786f77a049bd300000000000000000000000000000000099a2f4ff62aa4c792ff1dedb84119051e2c4986970c6210fa793bce2969eaf0ef61705a231edfdc69dd87f1e55d9bad0000000000000000000000000000000007ff8fbd0d1981e77c14a1d47a2aec3333dc696eacc01cfb23c68168c26da8853d31220f6beb7ddae19b3c9d85d29f39000000000000000000000000000000000d95d9c6fabf3136dc210dd43431b62ba27544d965e057ffe8a93fb6328a0bbda40b35d6d21d975a8a7e70cd0ac8feaa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071a984a893a7af2938fa210ef750c8bb4539213062ba53d4c43d9284774d4c2d6eb35b85a46100e16b393e0fd564f48000000000000000000000000000000000aabd48953be8e03867e84347523b40e44125d9899772261a253422033cfa0aaed0898ad4657c45ad31c3b9a216be18a00000000000000000000000000000000117fc1f279706494470571a77f2cba6553dd82a81e25d0c05a19f4a60419c7bf3c8321df5b2c597a2a76f8f424962c870000000000000000000000000000000015eaa9d89e3f651d0399855922bec54945c228e08dea0a2fd6f9b9de5e50db7ed56ee1226d2464712c1a7cb5748e46571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f2dca96e423f4aeba9263db88cb434eda320e17a442be55621c2ce775e2b143c82eb2e6ba15a8bb5938198fe355d8e0000000000000000000000000000000015e154683f585fdac2c9a2faccaf221b0c9d907f0d0bd7cc5ee41f88a9d8b08b8e5eb70c8225a476f972c585724ec82a00000000000000000000000000000000075e59a1710ff6a16d470186ad54872d8b26485518ffda1da4933d1bfc5be9d61fbb121d2d1c00c8787de073f6522513000000000000000000000000000000000fd9267402d667ff53c7cf7e3a7282f11d42fec1653f8d0a5294fb634207429ed63ccaa4ff053881718eff08d57282191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000430d54b947ff648f7399d86f345611e1367f6693dca5ea208fa450fcd0df9f8dd64580e99a0510b4dd79d0090106ffd000000000000000000000000000000000cdc0ff0619d94d8d8f467e7be9682b5945ec4d05b0735887fdd0fbdcb6c71ef4223ed2e29acba32bb1db599638c4fb10000000000000000000000000000000002de61321d844f72287f79372cbf3137a51fc5c277ab55b4c02d7a18fc6b7c2f5c59c187cea4a87dc8c9c744e4a5d7ee000000000000000000000000000000000e9953859401421c7e4f1eb31663cfbbe44766b6ef4929b9093765ffa61847d8fb6072bfc3bc0b0dbe4ba53392d15cfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144197ef8de3e80faabbfdea2e5c174137236e5677e2e33e05661ed3521ef95fae1e8bf0039d8cee18020b089c0157d900000000000000000000000000000000191c3ec1af9cd31cc55ed72ba96eceab258547fbc0df9c45e89b2510a857a2c1541e9b4153ff1f0f43e5a9608e8950e600000000000000000000000000000000032418b0cd38f17f1927ba62769626095115677a0a4355563b0ae2684c6958cf44ea2f3af5157ff6ec3498c5080f15c8000000000000000000000000000000000580f646dcda9cd1b6c866b83e3eb7376f144d61918b21eec578ee1f3ed14e70549964cae768efbfc4f3029d6155a4c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dc7c4fc554363ee1c8971e1bb5ec2277027814cec4555b181d9c074ed6bcbd1c23aa18ca60952e719f4dece2e7234960000000000000000000000000000000009094da02420ffac37202103cefa6007d2db43217ad3fe8713654b26809958a48c63e45df3a418a0feb03938f22af1aa0000000000000000000000000000000001332bab83460db2dab8ba1dfedb2a0a8fd2dbe804b9df1b632ca7dfc243c276607de5bb7a57adcd2040ebb6c6e8a5f800000000000000000000000000000000131c61baa69159c6b842cdb0940e7db74bc2688fb028207d3c3c2dff3b04ee66d9eee902dec1852d3faaea85d3891c251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026c7f0d403a9f0ffadc72acfb6d5d6ffce010e287a103108ab388e15e710abd4b6763b2ba8dbdc7bd65251d7dbe18130000000000000000000000000000000011829e649bbe71605e9dcd7cffec2f693b5bb8376d94bef35780bddbb3127b61233cf657b4431ce2b53f7c3109af91ba00000000000000000000000000000000044e4cccd338f4ca989cfa137db4b62638462ffc5298c2a4319aaab008f9665416dc41032eeacad257a3525da7e180b90000000000000000000000000000000014a9741fe8e4b389d59b454950514b26c5e96888b2540f08dcb0f6940935dedcc4580cc216df578718eac8ef2d5232751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000869bd184e03442a72e020987e53e22b78a8e19ba85f4bca24feb9ba25d230e2e5f1389c3a72d80970e73d0b2b9d3ddc000000000000000000000000000000001392ca32d183c7be512340c3f281843a0078fe122ec772c3251aad67db97f7f29424ebc9dbba9c718e49b584eb97bc79000000000000000000000000000000000841a7fc314edec4fade78880d1f55a481d1c59436ea6d10ae8c873b777e1095f03b6ecd02da4aee6badfb06c3d515fd000000000000000000000000000000000cb4f57c6a4fb92993e08f90e7ac8691f5743df915db919414852317c5dc27de5f015ad35f0f74cb20dc253220229a761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000661b63be1a6e5c8d517f7bc1efba732d28aa6a79d29a0e46016115f3601aa4263b7690f64e3437fa0c7347f0a43134300000000000000000000000000000000054ba61abb44247da16f99ce39bd2a91d893f681d787206be6177ffa6286075dd44ba07ee0138d86cb169aa9094f992d00000000000000000000000000000000079c02e5961dd0bb9f0646f950f5c956e09b6dd495c6b8c2cc4f075fe5cc4a2b2681b9b739b1f38cfbbfb1a7fda814e6000000000000000000000000000000000fe5b0112e3ed319d81de39069e15b6d75b27d66f4683f77691755a60913a354e1e5c20f28ae19dc63ac8cfab27ad1341824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b449d7ef367658ab4431d14276b18fd6820df160f799ca86c7c4100ff2722f99012708ef9dd8dbc8e8df7938857a7d00000000000000000000000000000000071dca4416b8eca004e53f870201ece759737ba88e769ca86017a77aabdfe94bb3d721879491d9765a139182e462b7ea000000000000000000000000000000000d0d352661eff22003c809582cb02ea1bb8e56ea97ecd02cc2e0e86cdacf4950044d5f0532323ff22d0cf2d6eb044733000000000000000000000000000000000d7a0cb8a69e5566e52c8ab297b4778fa06852a1b6133bab46892a04677d266548caf9816cd59d83afb389cb287ce2ce1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041f5f361dd0d5bb7fa89d6a3b9e85af7dd738f3069612161d8163ee17cab59e9d3430415a97f375d25bc962c9863d150000000000000000000000000000000008240c6a28648d4dad94722d11183bc2fce44559f73f0b1cfb2a11b389a4a448a49e38f7368eaac139e56f0a565c14060000000000000000000000000000000016760f38df08899c79dffbec406ae694a18f595c962631cc1269e0d640b69a54dff5a093eda11b42bd21153713fd39860000000000000000000000000000000016f8de7a13d0e7ca228209e066dcc8be4bc3fe2a968c6daab94cbef53370a0c6bda63ae1a488ace02111296cd833710d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c2f8ea70b34b66c90071c62002638e1ecf1594f1efa0b99324d05c805583b44e1a4d385896fbf33de6fe9de7402ab00000000000000000000000000000000169909590f3ac5a4251526376d95700c40709be28c69ebae8d88ebd98aeff63fe54cbfdf205210a694c7e8ce7c9a2aae000000000000000000000000000000001567a3311837f99f35ea37fb6526b3e80776e9ff3907aaeae91e43891d94f3a6337b5646568172763cf376cd4fe1ebad00000000000000000000000000000000110538bd9fce5f280c7e0d5ed7c6e90dd117221e7dec283c8d87315375b5041867c6def97449c370aa118393f38d59a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008501f00568391601db35a5a80a53bbe84f53d28a45b26e9694771e82d453d941dea772eba964f3af0f62eb9dc7ecbc1000000000000000000000000000000000049c816ececbdf6b0add77ab1ead027448f08e7433287eb8a67a44d5d873b36f4d6edc8c2558fa881f52a808c34b1fb00000000000000000000000000000000008fc72234996bcdc1714715d24a2c8bd7e61e4402e7ac691031c816cb74670a2554d21683e8b8090381cad0c52a9c8b00000000000000000000000000000000062dfe200a223cf3cbd8efbc70c20a61a42fe6b6b8ba90d3c717ee6cd224504fe726680f0ed89ef31abe3fd3221ad0191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001ea085a42dbf1b36b2fcaee991e460a83b049e3c19ba9cce27e47670810c5094172e1a6a3ce373ce3e28d7ef87f6f3000000000000000000000000000000001979c2c21a5b78f3f1238ff99df2982823ba683f047a98d1c7cc5a2bb1c2bd6846974cd5733cf503a2d6cff97ec2b50e000000000000000000000000000000000aee615d2d24f25e8c9897c936e99fbd183c8c789be2ab3785cdbbdb2e5fd85831bfdad3154777370194445058ac675300000000000000000000000000000000127fcb6860c393fa199bd6f644fdfd2e2465b7c1f68cf4dd62b5c2509ad76bab7f8d7b1f351de695f59bd401407aa5c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004b855000650d5fac7abd5cdaa58ccfcbf86919c8a7744ea69bf0e966eeb0f2011fff71d94bbe5d4f60ba678cbb9e3f0000000000000000000000000000000006b0970b71690ba25daacdc9a9c36d57d02aa123ea2ea76c58f5c8bf069a35f156e7b115e491f2cded49e5bf93e1f55b000000000000000000000000000000000775f4ff6c24aacd1e2a1dc738031ee8e32d6e47ae6bfdcf539822b7efaf2816b8dd58136bc6bf6a14e725ade134a0a500000000000000000000000000000000188285946e65235b22ff05a2d4aaa9dfd37238c872cd663385b42c54cdb813967fcfbf852e6db3f457adc2b2ad70cfa11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ecfd019ffb86b58e8a5773482b3ac8b58b705c1da2896b885c41b6053c06e25cb76d8dd222280bf5ed1e81d8c8478e0000000000000000000000000000000000c249ca53663917212d185d472419c8777276dcdac08ef9610c54f07e326ddd7ed60198fecc7b6b4fab3ae858fb3f8f0000000000000000000000000000000009922a9469e46e07be39cd9ecfdbfc1cbc030b8bb48f57bc5c8feaa447a3573f06d397134357c48854486d717058151000000000000000000000000000000000177c2d7fd5136df5bbdc2f220ba4b92c1ae97a1f43541afdbe67260f38bd2b0f556ce034212b85cc2a26acb210676bed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001565c7c15bb1763d3289a31155eb9d28243427f07b8db224384fea64d8141f2e5a3592c5ac39e3e373148bf71cbfdf6500000000000000000000000000000000123ba9c99652eb0cdd19fe95a641b1dbcffea425bb3c07f2f099ca226001e6df17f42271f246c595bf872b69e830eb2b000000000000000000000000000000000a25e0580ffde95097d303a9ce76948e40fe7e5b6bf172f7add2f66de0ea715268174fbbf20313ef7ae197b656d4571f0000000000000000000000000000000001eec81ab2eb68675f031af0b425767917a400cf5a0fd02a9178e4486ca9e7367271c644030244532c4d5449daa04f801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004a266245f683e5443d77d63d7995501a5bab7539e980887dc546595f873b88fbd6a84f4dcb5c6ee6d3d8a3869be6dc000000000000000000000000000000000e5e2af537ac763ac1ea6bbd1fbd0eef4217fc53194ebe8a71af44e20f78dee17178b2a82f0471f90ae80ea73521d9f90000000000000000000000000000000017f7ddba179d67e69eacb523cfc100a5b9aaef7c2d8f8a5e360c1f3d274a2816c391cca0e110ceddc7c9f5f62c7facd30000000000000000000000000000000004881af530e0ccb481e7b5b2c0efcb8cc2224cb13d9c4d15f96941982db3db3509641cd5d10aa9f409fa8fafdac896801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002014fee4aa06b8b54df685fa317e6ae66ffe03400bf00a3b4bb9d8582f3cafcf20eeddebf29b42cf38182eb2c9f5969000000000000000000000000000000000e7bc3acd7c665fcaff176bc371d6b1619e71f8ff0d98c934281fa980955a872eda935d312d2be51d1e18ccc794f505f000000000000000000000000000000000139f54c94fd27ed1158ac68a963a3be189e3c5321b5b339734d467a01183a7afc20af10e56a04d05a40c3ef66e5d5f500000000000000000000000000000000082ffaec3f71773b0a337001f7eb83b7127f4bac147506985c22671e5845f9ea43c2fd07ef75ccec9f0b3c4f999d8fa71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d3188ec56b89efdd4140eaf94729db68ad1db5d8409be8812ca2c55f6beb41e288b5f57b7e0e320ac9ba524d5ec775d000000000000000000000000000000000e5d2dfbe3623d9869b2370b44bde33263c983c2b127b2771e8998593dc74b7e95dd3e06331993e02d316f58209f9265000000000000000000000000000000001846dd1057c0c1611d130392b6a85e9c21dc97bb4b7e58a1f2b29feff4189a1d0ac08b848a0d8514c7acff4fee8c9af0000000000000000000000000000000000de97f51f406382a0afc5e8727f78d528e04b138d3e99e38c0e285c556af840759eae9d61a65c99ef08a22f3a97074301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159f056cb7492c136a22a9bed3213a3d719648bbc94c62a11368a59b2df53b2d064fee6b64453e75efe0449c891a2ecf0000000000000000000000000000000008917a967024410371060e279a065f42add5effbaaa3f0d5cc9d50a2d11a1bad2b277b8d20e9a8e0704895b383bc2bec0000000000000000000000000000000013ed48213dddf23ad4582a18d944d031995dc1fd8911aeee63379006adc8bca790791e45994c3950b336a8801badc037000000000000000000000000000000000edd30ec921b9e05f15e506814960d49b561bbec136e4717aa58d217cd1712e45c7a5fa81788d1aac8e1abf37eca463c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030cab3e0e518d8ae1b59222dc4efe3d0df221cf3062891f9df9bbdae0db7b3cc691c19316c563b76ba7d2eecea5768c000000000000000000000000000000001439f17a3c3c78166c8ad39474c3959f34fce0909b8073ea397d5574d61915efa153518005e03896f180adee8dbad2ae000000000000000000000000000000000428dcc93864d930d05371cb0e8cfbebe26e3df67611ed045c68f86462b43144fc47eb7a7a8cd2a60f1c83702112e99c00000000000000000000000000000000009536646d9c7120a3691a347e100da139cc05c2bf8ce351f0710aea25bca104e6aeeedd0463103f459ba920e42f5d401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020489f3c57221e2e98823e40267d8dc7fec5ecc16d6683e6abddfe664d1ec19ad95ac645caf184a6a5a9765cd88187800000000000000000000000000000000141c336c6cc6b48ebc614db0b4a3f06a471619386444b00a16720e924a8afbfd71a262e8639eedc2e58bd32c8a161a000000000000000000000000000000000004f43c1d4b9d18d1859a7b1a0f2694cd619f1d05662ace8095c19d59bf5baedeb8348a6584f2530e2c9fe34c31e505b6000000000000000000000000000000000d1dda7763109331eb3e777b94b9a9d2cd4b055689dd31f26baf3a17f866714a97729808abe2bc7f3f107e4f74fa65551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f64fa02c64668b8c31684dc7d028a674938ed86cb3654695ad4b37c093dd21fcff225927938917a14cb59340808b0ba00000000000000000000000000000000147f9a2ddb46311e9e25784ee360b367ba4566f06a59ff18d525120aee4903bda6de92b8f264d2cc9079594e9df590cc000000000000000000000000000000000dc9eec8d41d4461394585e662b9cf53e71ae86633e7602ade1ed48ca2a249194389a46bb301ebb9abf0aa946a724adb0000000000000000000000000000000015c4b0513f54009dd97fc0a1369f1c4f9f6a4420b88952baac38cb641d0f4bc75be8d64ff2219f0e1eb54c9b117711c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff9450a6384a743c172c50548c5771154fb701bf2676f565ce4ff1fd542c5ec67f5e6246029ff25aa3bc124b528ac83000000000000000000000000000000000df5a88f6679e81e5ce2b04b9f40ea04c0716fe3242a5ea38df33e4f704ae3ef9f0a8dd22d0ec80c739616bac84c6e70000000000000000000000000000000001198ebd3f95f5901c323f5363efdea94bd9504a91f69177348fb0e6499ee07a1c90c1d22c36a6bbfff111f538c36fc5100000000000000000000000000000000190c2e4d307a9f4cae822c5feb1612d89d5879d1e5ee7fdc65006b30f81eef7a9328fa030791a892b2a01790c2ef37551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057ab7a09100254232f3cecdc9f8029948ba29bbe4c02dcf7840c8c9ca799e96436c6de292dd74284f0a1a3b4a823386000000000000000000000000000000000f24cbb3c25de6a49054c22a7312037ca10d7cb29c4c56d8cfefbf14203740b5b44c57f1d94c677b58abe4a7cc862f49000000000000000000000000000000001763d329b41d215e5c83d305a5ada860123eaae55736f1aa9af00113a30911e7999e174c4bf77ca28b373c4ecf1f6da500000000000000000000000000000000180e78b606854b01397b6be1d2d399aa5786de6ceb9dd71b5f0620d6d9a14d5ba8a8d3725c6c4e04d9b627d5a032175f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b4a7ee6a5d8a800a5a6dc52244b4a16be005a5d0f56e26b5f484ae6741bddf0c687864ce91d7034983def161065562500000000000000000000000000000000199ae18d3d872a80c00a0032e086048ccd9f960a916179fad150428f86b4b4c34a4d68402b54e7930c2b8c5e18424c690000000000000000000000000000000015785624871df04325ac9a1adef70b61c5095fb7f04cb8af48e28b3a538893f1ce77f5ef7bc46c9360043e2200a236ef000000000000000000000000000000000be56d37fb902564b9d67b7041fb126afdc19b71695273ddc7db741ec33c5f7b9bee392e171e2f86b2a26d156055f10d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000237fd377466aa897cce1cecac822408d835bea16ca81e3f4d78de1ac9c88f99f7c3060400d576288270db785a11c7690000000000000000000000000000000017e97a5c1180bd4bd1cf6c22f5b2796783908d8920d580131cddcff5073a9c04aa4b6312a010367a72db94e3f71cfdd30000000000000000000000000000000012bbece809142ef3902867698aff9aabae77f30efc79b32f3ab75899b06fbb26618d03661010c92f2c87baa88dcafe19000000000000000000000000000000000ff2bdf42031e500c7dd4796a417ba6543e2dd98ee7612fa345d631bcaa518c7c6f7b66f9cbc54722e0f519752f67cdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa59c8bc43e312392ff3a9e6dea839475962229bc408bd6adc0da18cb60e2b0b534bbe1c008549d597454391c44e5430000000000000000000000000000000016f101a351d3e0b1c4fa4598f1e3177e017b73fe843e0bf980fb570423f91eb9c334827c77d845432dd093ed205c9fb1000000000000000000000000000000001196ebb311900d6868117113d90c552cab49803cb0a0b8cf391b2fd9cdf1990c7649d47dcc2410a0cec6a64a749343c7000000000000000000000000000000000132a5483eedf0731c8659faae2ca4f5a3fff34223ef351aa7f06e4c981ee82945f5beed4682f78d4886c7d5446f50f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010077db5bde3b49ba046709a79a880b655b0f11fa3e4b9912172da0f8058a9a418d609d9896e79418df1ff227737c9ce0000000000000000000000000000000018176b1ad8a805446038336a04c69f98e29980e60c4dbe42dc3a9a69f9081ddb9507a271869169ae302751994ac2169900000000000000000000000000000000050a78400702e9d63d7f9b1ed76d4c94b80b0bd57860b01bbebba1623a859697802de1078f42f699944edf021d75e53b0000000000000000000000000000000019763ddd75a07fabc1ec6ed793b7a844141d264bb439c4356e30497904ac9fb51879252e2f52668970b7cb9a0810fdb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3b26ed3bfa1080d26fb1095bb7aab4da72c0aa90ffe9a7571aec2e623f0951eed48e1b811e0b11deb4e337bd720c640000000000000000000000000000000011241b13882b91e400b9a262be668d516af35e6e5142c247121bccf2b66b0d3e8b597cedd0d845beba4062424286464e0000000000000000000000000000000018d65ca084d05f17eb56bf4701f73590dd942bb9a9835b5588d66eefbeae5469eeb65cc04db75a57155ac24ca253245f0000000000000000000000000000000011043d27631cfddeba611760746df2fee3ea3208ef1b603f741570a98d88c3389c46dbabe5701402758ac12776a198cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee07ba9c2316d44065fb3d9b8d739da7e6d8c4226b8184567e59d14e787123918269c153b3f5e0da0dc077461be3fd3000000000000000000000000000000000d01499b5c0a3ebdc213938656d3ffced0a54c236cdfff93e1a0490074eb428516464779612efd2f683e8693029bbe2f000000000000000000000000000000000aaa270b96987ad5935b4f8a987381791952d8028d2983e71ae71c201d6c583bc2aeff5ca827ee4a1b0bcd801646824b00000000000000000000000000000000064e8e652d228d78f49ad75a6b3b0a273cd4dac8b81e5de5de45040d822a09289460475e2f24260b48d0be2407526f051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001981ee496f2adb595f8d97a1720264670d87f1860486e16f00dea74a945663681b09fbc7fd793492406cd51f7722a7090000000000000000000000000000000000d578a8badf0380362f42eef18a115e482bb2b14f5f7c896ad1b248bce86fe4282804f44ee9ccae8a29ee860b4ee8650000000000000000000000000000000017ecfddad4e5a0f335900d19057274a928cec1a6818f5ce0d81c0bab5bcbddac68a94cc724ad67c0a600e45d879cd3d8000000000000000000000000000000000d81b219565f8554ad1f7bd139e77a96642b51d73f1b89f978db4dc1cf3e781f14a659226b7ff2c524970dcb02a462061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000907c0e117ca2628517b6807a0d023d17b2a5a7188ab50c3660f5a716d05fc78f51d98fa739adc7959d77b16c832f5000000000000000000000000000000000006ccc067a6886a88f7a0b1f370c0ffaa7bb18ab4f4923cbc39aa292257dc69f80ee2d78d6785aa5bfd321368c73e02870000000000000000000000000000000010c13078cbf02f1cbfde48e11f52c5e9b6d74845244316e6482a997bc0c35db14e8c7246627ee2e6844864a775fc168e00000000000000000000000000000000095aa56fdef1eb2b268a0b996c1aa5342303f3dd2b50923c99c4b72ee81f742f7273e78c27a7ab3984af493b574a566b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004349ae0f80d90d9b92e757d4ed27dfb7a003e22719cca7661649a55dcf3a79192bb19b92309cc32af8020b344fac02700000000000000000000000000000000085e2c5493255e911482144788920ebf311bd5e93fe85056ffd08ae76ce666474c11bdd9467515621dbf65f998138a72000000000000000000000000000000000e9767ff8d73500397a43d644fcb3d114d6ce336b75cdf0744978051603e891480613096c6959f279518a49efbd3cefb0000000000000000000000000000000015785fa9647aa5be46d82bc5b257ba4317a0c8bd75ba4f0735c718086abc35b59e9d8761023643fd98d0ee82e4988da51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b5c47ac28de1316725fc048d06d172bf9e5205222802f5293bd3b39869b9451d1c23b4514d7f0d7db1d750a641276a000000000000000000000000000000000ab2fea3c7659635e3d37440e49233335dd18cf3cb4d746738d326b89853ab04da01834a35b02f3eb9c555f4204abf5a000000000000000000000000000000001603ba50751ba1d3af8f8b9a56edeeec42eaeb37ef89e2bb445f058f9a0aa4e94e215f97e51ab747f3357193ff56815400000000000000000000000000000000047e7e88c5e6074ef0ce938ecde5f2d378d510640f049f738d5999c01762bc050ffee6eb9e05cf3452404fbd5c52ca581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065f0436ef74dcd0603b4b6921a150754232aa5a0b36631f9435fe95f189f6f9caa5d41ea0296a77556ec1e6be69ac0c0000000000000000000000000000000003d518363c68dde58f596c2c83424c04aab530359fbc288bce56bdbf0a4275cd9ab5147feb77983b148864528ebf9d56000000000000000000000000000000000d2fbb6f8220f4d7975df76ae86be37f448d13392623942a4dee4fbc16dabe86ca33984c429e1732bad7bf2bf7a63d93000000000000000000000000000000000c1f2e5c07196d59e61cfed0282dbf84aabbbfe0e5aa319dda47f15f663888533730dfc62a3b626f5d647a2174b555c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b63b0f91837899fc3a5c8cebf4fd03de4997a36d7fb2ebbc46e3a0ca62b8d4f5fe193a669ad6499b004580f9a6a67ea0000000000000000000000000000000003fc02cf7a48737eea8e699b090f8a24e597227fea2c4e7c78f03fde6601df9409ad84b3b71204266136f5ec11961224000000000000000000000000000000000e0bf0e94ec6ceb784a16369d446408292e8b3be7137ea066956c16e75bcd29ecba1e76e6f6010189a63d64424deb206000000000000000000000000000000000f4cb04088808b3486a5dab785fefa7eb8bb01d66a9e4b696a2fbab2add7b7b2ecac6905f28f4e53df460376ed77c5351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a001a571fd2a5427a678066c3283226c153f41b38260923a9235717a8f63438ba4630d968ba8b6d35ce6f10df559b300000000000000000000000000000000187fd7ddfc6edfe8c168d0c39f8ebec03bbcbcf5d660a0b7faa4c9c02ab6844505835c97337989be85da128ddbc2987800000000000000000000000000000000191696547c4f4aca3cefcb2e37da58960b2acac1cd7fc3c6ac2ab6575c777cb8c643d51d1aa4b7f1b894413cecd7c14d0000000000000000000000000000000004535f298eaabe35018ea1aa59309445b86c90a6098157ee3514b2ea5bfde659ebb197673d0e84853e006b4413115ef61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c37aa4b763862f685ba6ef89b4d3fcea7cfb1c40c26710a428d20209c2e006ac7eeb04bdb23addd60c6603673d1a12000000000000000000000000000000000af2d501c2cede3ca33e62e38fd9cadf61b1e42f39ca5d8cf96094702572b66fb0a73007bfd8f8bbe35e7f94a83f3507000000000000000000000000000000000fb8aa0bf0065003fe8e7b7d0438c00f3c1d4709c2982380e9c5919f1e1840efee59c01f72a619b092ddb4af50ddb6b3000000000000000000000000000000000030c347b5b289a2099f05d51f576d10518503e40932cbdfd8b2d8728d6ab67731ffd3553ee5a501fe4b256f6f0a8aba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000092003e51e8ba3c7184ce5fa1e841519902228487588950d551df9c73504d26360a226cb287acd00fadec5019af35cb0000000000000000000000000000000001623545a003b3a0dc0f832fccc1ba420b353c2c2a15d77d0d8bc7c52587b79c7c35765cd1cd1de008c7e6bd96d994ab000000000000000000000000000000001986e9f839530a8b6a7ef4bdc2b7126a72b3a73ed2f24d5c7558a34578305ab82bcfc4d6a449a0b844844ffd2386bdd60000000000000000000000000000000006992656873bbdfcab7f4adeb4fd4c8090c132df16325518e4e9ecc94e7e9150067026d554fe333248f5f357e6acb1541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c0644ad831033eb4e58db3f76c94a9bf31bd0be767ef15340d57e45844fc3f55fd29457f81c82bacc9bf6cb97b5b490000000000000000000000000000000015926badcb95f762d0b86c430b67fcc471b9a56a29740d2367a71af1c3c97c8d41b97395ef9c825769986216ef14e5c50000000000000000000000000000000007966fbb5222ee7c60eed0b50be7f52cd4529aa1dd0e8144c1885329e344cf8809728a026fffe8e0f22e5968368aaccd000000000000000000000000000000001900e496c37ed7e743a76bbf121b8998af95a72e624618a5bea3cddc410902242dea40db1a5059fd628bf790b58e17581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000106d9034694c29483e2cac1a3f55e88121f3dae32d08a15537b57058af93e0b125f87381bd5b0c3332e6240c8318a730000000000000000000000000000000003e925789cf8dcf78556647eda280c0f786a86b71d17bd04f8097ab478497f9f3388efda0f8cdbde83ddae70a61ea74c0000000000000000000000000000000018f2826daec8c239ca24395a2d4590b03544b1135558fd049e0eeb4e1e2e68924975527192bbc71e7a7984670af17342000000000000000000000000000000000ce9a748558afd245159bc17244e90df35c3ce08444d3313b8b090e5570bea1ace9c05adf80a381923d87da4cb36d6431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d3c247d59457ac3feec6efe5c1aa07d91058c2f127281f8fedbbc2a65ddf5fbda2b07f92232f5b3f6dae5b28a0186a00000000000000000000000000000000085e33841f02c3883ec3b0184e4502c1277d45734789bdb2ce86e5ea3c03f73d9dd295be09ad99f3709d6c2b657e496b0000000000000000000000000000000003026ed8e4cf8c1b665f396e5c2cadf02c35853a7557d47477022d89a0b1fe8649ab073923f773dd39160bb5c02d6c6800000000000000000000000000000000096775ee4d2b24f1bc76e6e67c52c679a7852e64051b8ac0e0f448f42c4a8739185d585ece6bd91084fe6db7490a0fac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001179123c4e26298dc7757431d6427163d1458d0f16a5333e8cd695f1e0480882fb94bdeb44182e0243726209fc9719d90000000000000000000000000000000010dc8414f9f66cfc9539ef33bf3282d41e4bab53e3b97b88ab19d9bdcfa821532044ac081b22c17a1c7d6101c3b33cc20000000000000000000000000000000009d4f24f3427dcd4e64af0788d9201a2f081657907fe82da6d5a2d0949813aaf7fb0a2a276f4a426eaf0e19baa6eb1c800000000000000000000000000000000163cc177fb48e108539568ce153fa04dc95ef8e394c4cb50e9f087d81c4cf57655b6409aa97ad47849445b2b1bfa24f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cccef0eb0cf89675827ab514e56f05c973a8aef9b9b13022894e9ac115a1f57fdc6e579262aa11a81c38676263620c300000000000000000000000000000000034653e7da449c2084168697fa1b29048e592b6ecd65c4c671c64612167be749effdb3829827c5e49b0e8a875c296add00000000000000000000000000000000192a4dac703e856a587623d0727d8fe1759bbb571757ad70b69757dceea9b3b1d243549ba6ecd88d4e7c505179c8a1b9000000000000000000000000000000000d17d3d6e5c6b07b7768988f7c9234006faa7637d914ed7c40b4be9eed65a9a0261b42c1803c02c3c7eea5f7fd1ee52a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e964e6f7e134ca54bbdab74a6ea0bc19f52d7ee610887afdf058a5e6a855bdf0e1ddd65c40abb714291808d41cce6b1000000000000000000000000000000001705bb063994356c83f2fcf95abb8701b763437a38d4f0736193b14148f6a77cc96de59116a1d64601aa0f5ee6b498890000000000000000000000000000000005182ddf5ce75e21cb8b43367185a90b8712c652cc9d5a8e4931cbc2a347a8426eeec5d034e667c798939095991f7361000000000000000000000000000000001734837acfece89bc74d6b591eabcb09497b6fd9b08c28cfd4168ae75a951cb4b7de8cf7298aabefd1c8a8c088b102e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008140cdb4cb8cfc8389e5cfe143bad14c5d52859418ce201b47e44b591d11847c17a9130de072e3b08b6d9b622628c600000000000000000000000000000000017f9e770eb975b1da79f5eeeeff3db2c256c4d9d0ef26ef6b9c7e84d89827d9e5857f80f3689c917e91fe35ce750316f000000000000000000000000000000001759f95704a6c088d7c32dc9457e6e79e64126f87bfe9e8ada8c3e6f6877c1498df2f4bbded33e8f2a591150f2aef0dd00000000000000000000000000000000042eb28f70e9cb5713ae0f99911b895af1fb136765cfddd49d126ac89c5205f1a9978222b06963823dc327e3555203d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df43fe1fdd5f1db37abe99fc5cc7a0d796c38257fe1cb483ca915acb35f9356051963ef03b3fc7f0896043acfe20007000000000000000000000000000000000de3030e07cfa332158e8c6739651067d015d3cbb7f13e2267d8eda3341b488c792a552a9c4cf37b9d85788858a3b741000000000000000000000000000000001815d4074d940078ebb29d01fd4440a7e903e2594400beeec5a49099158074d0892688d625d90fcdfdb344355865942a0000000000000000000000000000000011dfbf5993989b0918c3e1552c575b34c2ed33e27303480ad6911e9ae406d06f530fbfb75313cf9beda18b9aca8ce34c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015588b2ac123a52c7dba167e56a06abc3e1f54ebe28812a658f208d57ab423bbce08876624c10095132fed8261577f83000000000000000000000000000000000ac654818f3b71caf47cf0715208ebb5bf2afa87b95b85911b8b687f9d96be8cc6b8b94585e12b9611542990f1a1f137000000000000000000000000000000001759fa999db74bcd803aa956004422d9b389c51f5bdd399fbdfe3fa95e180bc0786358b6df2a90dd3bc42ef811213b140000000000000000000000000000000011910f7f1e572a2769b333d622ffc29505243f95d2c14d7cf477a521ae5ca562ab86a40747e3a99aa7b22b78d3c18fdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003110ffcbca535770efc3237fa1361647633fca5d26a0c1365742326e42ae71dce6236f1a394a4cf3457622e5ce2b2d40000000000000000000000000000000019a808f34f27f28d1539aa96ac98f709ad2548594dfae76db7221d70f0358b6cc01b160302017deea95ecd7826d4218c000000000000000000000000000000000456cad0d6d602e87bf9426cbfe9681720dd0840dbfa72a88e23f4dd5ec48f3f6ea6e68835985ddf5e2388d12c380ea00000000000000000000000000000000003fa2d484b9203b926f52db3ce3862ec438ea01cd2b94a98485ac074b92ef2eda7330a8a2968926e48f4bb17268808ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbf62ecf0e0f1f43d05ea4049114d316858feeb5b3f4c87755c8634831768a0ce6fe7956cbe9782d52f7c2c6daf743a00000000000000000000000000000000043fe2d93d8667b324daf6d0c78451469ec4addd89ffe26618cb3513c20b54d1667c4f0f798e0bb57dfff9544b0f41200000000000000000000000000000000001b7562ee8b7c0ca113c1c96354aeae4ae33cf1b7847f9763b8341f47c71f4614d7e6c35356f0b20cc9daeb3e2241910000000000000000000000000000000000da22f72f4c534b4f6a182f55778326f03966e1b6232526a9f61324fa21cf4e9829da54cf98f09f95d2d3d39ee6edc371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001614a7583c4a0e9e75c5c05297b634b23f52aae53fd14fa298e7b9e5e6f396a41b6d14a5172501b6271f38887cd149320000000000000000000000000000000007e13688c00c2d5458328df8a761eb2940beb1d47e5588f6101dcac85889c19100c28e480332e4dcebdaa8ea9b2aacf6000000000000000000000000000000001919ab7983805f8aa845de443968bf0623a81aefe20b92756078f4768682f4ed974b7315ad60a44fbad335957d7044c90000000000000000000000000000000012fb65a7549fa68cdd4c595cb07c0aa17310ba329c2dc81de4ee78e15f801e492be9ebf389ce9f746fd10a27c555fe3f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9dcb9d4e1731040b186c9749f12808d6f9befda70aeadd88ed342c0a655c783ad7c09136a3a8032afe3bb0acd88d900000000000000000000000000000000002fbfe6f827ccda267a37a178718568c327ba19b604d3838e4b27f0690e06d40147171bfbce6533c6fd68c06d9a205f30000000000000000000000000000000019b8bb27f0ddd3c8188dd442a5581ab45512ef49daf22b8eb3fc1c468a0b8835f70986fb036f9fbd571b2eef1d4734d1000000000000000000000000000000000bb135d756b526bb06d728bd1ad3078bf844a8abe2d3cc646aff5f8472f24aecc2683955d1e99775297072a51744918d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001997167a030a1e9b630aa66fc9ef1b5a756cfb164bc4adc1fae2e2fcbac0e79897074d6c21996d7257ca2a8ed3a800d8000000000000000000000000000000000cb934cebdccb1aa8d17d27cd69c11c6afc4f7a4371a159f7043ec12aba4ecccb489733fa0de3ea3dfe5ed2181c47adf0000000000000000000000000000000005f37a6783e54e8652cecf1ae73985a1a032346a2214208aa987b7aa20ed0f25b6661166ae7312fab7cfe4caa6713446000000000000000000000000000000000e43dd67e0e746274dfb00d8d447c8c476225905f82d881eb3d5443eb8ee2e186d0b8e2fade98da52d14c6135ee0ab7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017a3199176836da4cc11b9222b2577335a492710d9550065583e18376f184525748f42124b18f49c8ee15091e3042ce000000000000000000000000000000000104f3bfd72a17e08e27c1269d029b9ca5cb0cf10578d5188cc6959041097982d8ef4c69347571f947f488cd2aea949120000000000000000000000000000000015e173d9a9e9b97a37f307795f5fcbf913cf3af37d2fb6831d6b9e9df56ec0d5bf277d6cbad64edd584efb96472b3e6c000000000000000000000000000000000b33774433dc1b6392d908fe01e6b5e6971980ad9f4c5be1be9faf44e1565c7a595498e9f078bb7e4c94c3aac3090db11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000132e2a31b62ac16f46166a9d6a77e49d627c6d7215165e30acc96ced4ae57b8653a353d6916ead2fcc59886c65b22fcf000000000000000000000000000000000c655f8b367fb8019b19f7f1a72349aa3640f22dba3a1fcdc749c5bf9f5f9c86e0a07dc7ff5cd4316691d977eedd0f4200000000000000000000000000000000171752d3d4f9e701c3514df071f78f13271ed4886adeeb65b4425d349a1c4a2bacbe94497be48a420abc3bde4f7d15110000000000000000000000000000000000ba2bc6a9d908b8760208d91b744543e3e8acc44241f480883c96d3beb169e6ac7229d9c9b23206fa745e3f449fb43b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000065a69c9bb85cac923021f28072283c1a4b77a9a629047a9fba87654365e1fb55833725f699b82d2a99e06214875645000000000000000000000000000000000126ef73f13a52afb960c11628a568dd181e97f7af44abb29f007b3f3acf376d9a428a0eac6ff38bd824835547beac630000000000000000000000000000000000f2846efd22b202ef8cb7fe91e3164749e69f66f449b72dcf34a7503c60c46f4d79da2ebeaa35d4b8bc3a156a546c84b00000000000000000000000000000000088e1d55c8206b4a2034ca0edd4d397c5a10ed3a93d2832e846bc128cb19356d33cbf4b89458d5b5ebedfdc1c7dfde231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a14529c650ce5e1e570a1ae183727810e20f4eabcf9c2352dec714448997a10ce044fb08fbf153da399bc1b4e8f36a000000000000000000000000000000000b4a0f2f1ffc49deb3959984f522ea271d171fb0e69fef232b6e12c50cd4c5f98b8d615b1ad8f53749dc396d1a3556f0000000000000000000000000000000000f08a83857984fb0b25fd2fdf4067264ae0e8940ff73cdeca74530fa85b997264be8bccc439216bf5612a4730361a442000000000000000000000000000000000326b846cf8a34045287effb1fd9f456c4b04dad5e7bb78883d9b938b0ee76ec09f0ad22ab23aefd549613d49f9ae59a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d9b9c8d3b6c3eee769553717b2b8de4b51dcff950444b9644e18d87b676f3dde2732f57e41ea7ceaaeacd8b479736a0000000000000000000000000000000005ddf6a5fb4d7b28c5d4b045245d870415c255815802f9964321c13a38fccc29159e91d630b891111fb1047e1c45c9d80000000000000000000000000000000015e00957e6b97d936d60fdb331f0d78e992cc098d8a240f75caf80ee285cc414c7523a3a43ec90a72ce864151eb0c0770000000000000000000000000000000015de781c05cdaeb24fa6a8fe3497fcff4c4b102048c1a9e758412e69d15fa2112d52ac1f62ae155c967e52e2d7d4c1851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f34fc2e9e857f06ce231cfde4dffff2dc84dbe773dc4d7627bbdf126fd855efd60c644157fa84456be2160b08d397a300000000000000000000000000000000005aeedb4c7e91c93560dfc93aa484bc6180501c29f46a706400db27f3074d69ec239a9d0bab6da90e4233310cbe07c900000000000000000000000000000000170bc381622dbaeeef978b34f16f169575906b58827c0788d4ebf0c635db4e6c5236d3e2df9ed0870e7813863ae5cf3e000000000000000000000000000000001727237da4b3fddaebd04ba922f57675f52bc581edd75502ce970ce24449dcb38e53957094605dc62746e1ac5ae6b83c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f043a8713b5c0cf6b865feb19113927a089864d51918d10bae89f9971bf768f69185107be13e6ca25f60b7c782918c800000000000000000000000000000000187bd05d8348c82b4dce46dd4d325e8c8847d1ac954b888f5e8cda299e5c8d808f04e0dd0eb870ce1141823ea990246c000000000000000000000000000000001244ab6e621390501361028117d7144d0a2662fdcac9fb92c2189f2e1254c0acf4610810b0ab221332e5afcb750dca0f00000000000000000000000000000000105c16a2eabf83e2af2617eabe2ea68afedf9915bbd3d6694126d72df8fe07094014a1c833ee89ad01f3f77bdedf8d611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007b013c832f10d4b31b0162c607f68ec74ec96ebe7078117318438b30267ce2e592e1acb583a3be6f8a714ba0d3d747b0000000000000000000000000000000007766ed0b47b107587682572ffe3155b27681d8a273a51a6aa15dd599fba1109b3cccd8f9ef070263897be0c238f6d0a000000000000000000000000000000001243031f2537fb8ca314b1a5046cb61f2ef464d2a0aea659a1fa38f2ba2d7efbf3d9c6cec33210fd2b511d1d2625830500000000000000000000000000000000069a1819789546594db0bf1d626f8eb39da9256e648dbcd070014880bff3f8276ae15914bfee85c68761ac2ff7e0fe0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b84e51d82ec11f438f79c7df8b7661041c9209e249ad47277cd6e0aeced61026b9af179fcc9856812e1bde581a57da00000000000000000000000000000000033176e1f0a031a70ef1525e1bd05c60a3a771aa3d08cb30c44a637eec12ab429a6643fc77a5c3e67365e187a2de3dbf000000000000000000000000000000000eeb5a8714038d775912b3ac5a153c3008a86b1033bf4ef66bbdc5a2a2e408fca069fed9991d08aeadc1b18fab17fcbf0000000000000000000000000000000014421e823b5deab8fb5b3be584f8ed7f5dcd54016a1b4e321fad29e7c6c60dfcf706d3c648ca8a35dd293d1fbda17b6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000321e7a6a771006db61cf7bd270c2a7e3fe0e967fa54db316fb48290d69d1a1a6579fe257c86bfa27f99fbca3ad30ebd000000000000000000000000000000001373ba6b8d7dadf1f714a9c28f686ef2b8a6c14c03d776f10b2ede5f3b9b789f5e2fe89b660ff4d16a2a2c1e4fb55f100000000000000000000000000000000004949a7b91d9c068f874f2a447d8ae15f7460c5e10a30ea97d1f19301e6c199d83799c3cb96c574adfa3153aef92ce180000000000000000000000000000000004786d19e3602c7e0717bdd04d6a709291cad672df856c52b2602090ef47c7d02a2cb80095cbc2092e79c009d3ba81441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c86095c7a6d66ad54a240b99907aeb19946f899cf4dc3d60cd61ead53f765d728b4009545b36cc71b419762d66e49e00000000000000000000000000000000138c6b9df8753afd528af139fa1d3b419e2abd4d60e8a78695b537b0d7d9adc49d60a8774b69f98263c87422bdbfc9440000000000000000000000000000000008b499f71c538063606c0bf691615b29f9c05de70ad785db0e18e8fa955ee7d5553a3fc6f7492531bb6703f625ba7f4d00000000000000000000000000000000061c4a989bfecfdc2f83f448c2e15f69b87d9208d63c1a5948cde5bfb6e102dfaaa87f2b5448255df53c335b998de16f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017bb7cfd39e1869149d70091d4c103c7504090cbdede75e68464d065c9a535959d9f44ccc7b9185c637fe36526d911ec0000000000000000000000000000000008206f8096d24753e4ac3ddb360a4356dc0960940bd14c796804b4fea6be6c90cbdda053f2283f6de0259a4541f0972a000000000000000000000000000000000a5fa157207c1cfb658a430210d7cbe558962a6c3a9e05a60f3f20217f15a586122bc088a17246b999a3a5947dff5091000000000000000000000000000000000e87a8604f361e3bca64f51aa12636a908fa0792ab0448d6fdfe60e95f0b70bcad7522469f037cc3d53e02424f8e6b711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018aebb8de8351e521add2550f82b0c5fcf2ba3a04278af304b90d4e87627ef822e391b7d01a43be4c3fefff721e95839000000000000000000000000000000000ceca7d82f2880b9667ecb82b87cc0b0902dacc204572d43fdfe534f8fdd9c95e993fbc6f5089fcfc86721378e3934ab000000000000000000000000000000001945eb052b2b18f4b24ba8be1cb8699477a0fb954589c1d54807562ebbc406e0b69afed0da654a43996246aca5e2d03500000000000000000000000000000000068ef5a9de112f857e2405a17aa13d7410e53cc0626a0de84bc5e036b364183b7578948944fe49deb8f1a977e50e64c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016aabd078fa8b7540e63b11ae13cafdfe774e9bd0c10dcc0306af335cf5d6b66059602c0257c4a6dc2bbef489894b63000000000000000000000000000000000aeb8dee867f9ef8b90437f3674ab6d9b6342dafc6fab273567bd09d6a5193ddd7832701082b86a91e81cfc3cc7b66b00000000000000000000000000000000005ab7b43f34f42c768ec878e5ee673e91cc83fa4a475c80462aba328f108ea989e62abf879ff2141cc3b53854336d6cd00000000000000000000000000000000176a4b3ec9d206a83e7584e21224eb9aa150c1ce954e8c9e6f6b3f76b0cadc716022decfe7f3299ba073743d416783421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed417a3b8bb8fb8e45f60f4437544cbd79160ce4d347705a391c2d55bbde1d7b47e32ccf7704e6e7c1b8a10e915cd33000000000000000000000000000000000f96bb3fca666c578a2f7a5369aa18e47c75627c4ec4424449535405bf40ba7b2916ad79897b084b34dfa315c78dacf40000000000000000000000000000000002768383f66145c3ec1759a0980b6dd0ad3ff237b2f8cb4658fc864b9d35208f3a5ea5040c5e8fd40ed9809dcd9a960e00000000000000000000000000000000139e24f49dbc498318fd8a8f64f273958c2c79b8918e0206b6af76a666746e64eeb1c41a55cb8e906bcee31733225fc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018c26537ad03e1d638bd5dec664e1ebb28fd2bc88bca62b722da21e2f3faed434142ea0b01c949ae4b9b56666e015ba4000000000000000000000000000000001107723a19cb9b2e556e8c2ac1c51455c611066e50c3c42278b799e1d84f4b0623f07252ec9c46b330f92f15086c85eb00000000000000000000000000000000022183865069ff29b06be9d6ce9ee9bb73d4e7ea7a0c7192c6ab1d5d72635c84d3b9dca786e024aeadcf891d58a0365200000000000000000000000000000000138ace168e274d2c6951f818a6e56a52451186ca413def4f0961aad4630cd64a5039e410bb66207b6d20238739ae7b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108dae8e88406a1fa26abf9cc78c8bb3e27645e4548ea7edf4e1b98aea1be4ac546c5c8e9003ebf76cc83723c3590c67000000000000000000000000000000001250067057913cf430a3318e62234b53bb02a33f1cbdee6ca35179eb564efd2d547dab883ba7e7211c2c8c5da17909c60000000000000000000000000000000018d94329a21cbbcefdf0d9665430ca682f1ffea43e5a5e96c7d80bd77218e6ffceb58d8ba6e1d151d46270c948f60e24000000000000000000000000000000000dcc981a3f77ade9711f5c0a248ef6373bd9039e26f0b1c06b1404228283c506b5ee64a4fac7b61d12b94265cb9b5ddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002595099e4ca262d5e6fdb7becebe3170644f02a9a444e9e2c6420189f02e1e02529f6cb5792186eb8a124df5ba1775d0000000000000000000000000000000009c893800f2ecf608b0b9d993f47b2adebbe2450653964f20351b25c11a491d93c0bf6bd80f791bc65e469a8e10f3cb900000000000000000000000000000000098c347acc5fc1dacc8875a68da38f997cef2f95438c7243e53f8036153c541ad78fc24e82505038ec830a6213b50bff00000000000000000000000000000000179a8b6c115b77b6b77e7a9a140590bf8ea52d753d9f42f866d199faf11b495fef7bd384478d184fd197e7736231a2351824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001965dae74f5c6ee804d755988dc4a3b73e7c93bc552e88f6a6d5f467011583c3e7823d6a233d44a783d6622aa5a40b650000000000000000000000000000000005a7b26c59d24bb7bdc47e1d71c3cc4520af964a05dca4d4ada5b409c6e0a952fddccc8e7e386862da75824f4d4544e800000000000000000000000000000000112df4a999cbff49f50f150ad8f55357cf56cb0a51f3ecd31c4a9450a6848c5a199fb41432549a529b12a4d9984e175b0000000000000000000000000000000011ab6adaa8c4c8134f0c008f8644fc2c4b8b4fd11080166a8cb87ae259c8f20318083aef79de76e2c64b5f0493ab94391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004bb84d67d6735c35bbe5e3f2fae19cc354965b7394310a822e71012a246c2c240676e2f4278f464ca43dfeae072514e00000000000000000000000000000000048438d5f8f0caafa487a2e52a7ec4db2ba770920d9e3232e63b1d4d66e0ff938927d970e7658fdbb93eaf7dbe32935f00000000000000000000000000000000179f8b4d7bc4c19c4f278d21a3f211d07263ac924716cf4f851f2235d5a6f162594815f6d4753136343f8c6f5996c221000000000000000000000000000000000b3eca2bb18c517f168bcd9e9e577b2750a0d28a6ee7ef412bb8b1147639e4ea0bf89d9b020ba7b45c84535603b709521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e5591dd97664dc06500ad3137921e46f156ee4645caa7b8db0a8c80d7f733da5cc30570d5b3d0715410569b6feb98700000000000000000000000000000000041c61a9d5cf64c543c755c229a0e1a969ec48bb47fee8fbe605fab879866d3ea3c01302c4b0aad573c9fe3c440c52aa0000000000000000000000000000000016e8cb7b3fd46af1a2e9c2064f19d2d37d7fdc3e33ef1ea44c6cb014dafa525bad99407f35c214d61198a39f79c22a6a00000000000000000000000000000000185d87111e9d9baffd69cfacf1f63ecb775edce00c44c1664140b94fae1805f66104adfc77e1d8526cb474b6ba5b83661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084e8a74e7ff97735620353e3b4b45c6c2e80c30b94c04798ab84fc7a47dedd46d3400d53e9a3d47e0567ae840c63c800000000000000000000000000000000001da152972a8d0dde24c788bd13fae8f28f2b2d7eda7617b4512f353d5c17cad542c39b89bb8b1a4d3832f89677bc16b000000000000000000000000000000000d1892e9e5d80fea8ed48c2f4ac9d196a1f98f2d4c1ec02d05da820da917779dc8d7c8257cd326d762ee7a718d715bf30000000000000000000000000000000003dc59c0c5981788515343468a8017e01f1a742e7e83480053d8b970243858859cfd9250d9dbc1bad3ea5d56f893b6501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009982168571eaa4b2d303c69a34a7794fb757d77c5930c4ae2742cc6ff69d3820898306ab8748ee7a2fda37dad051f9700000000000000000000000000000000128ee1222077755c7e8fd2451f2cb15a6ae1c2c29cbca2784b442e00ecbdc218e106ab9f5edeafae693eb2063ad5eda3000000000000000000000000000000000b12e0d0f716c51e8ecf053a8106a1a84768c0dcec09af5eba1f95d3172826294b50f7982df46b22ce0171ebbd25b897000000000000000000000000000000000b540b1ecacd4ed1b433fea300b4b2e17a36e8c6ce0a3395dc8bf7912f56ce8faddcd27ba7d9e3c401ee441d8c6d62f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000077b8a3b43bbb3e79e621e533c93f5691371920cfc48d336fb23f18b1648a718069d61824b5df97e0cf08e14e7ea5af100000000000000000000000000000000189ee4087eb020ca6507bc39b2f41febed4696f3ede735f94256f5b78e3f1b6a0dc194bae5057ea375f3cca6fe9b103f0000000000000000000000000000000002dab31227e89c44c19acdb6d52db136e5e601a73143034b8d9250f06c087be74d4e47a6f3a83f78dc6ffb5aa2ecf1b40000000000000000000000000000000001aeecb95c081310c99a8ba044c06fe35ad7384d2dcce63ba66c2514937d3299f9ba629f723e12f5b13be292e205eb6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005323b2e94ab16fa4150925429c6798b81c0911967f77125ee7b0116eb94b21dd67cc9680a1b4f97cbc849a2d43233940000000000000000000000000000000012fdbe3244c9333142532fdc8c09011a83edd16f96913f087931e215867581c8abccced2f05d0e36d17fdb3878a4abcc0000000000000000000000000000000014daf0112a5156d1cf5a9697df709f18c48f43776263e888123b3deb218b80353d9310bb09eb843855dd2d77aad627e8000000000000000000000000000000000ed7f356223a8b7bce7f935d6a284e20a4457073d44e981492df185c3c159e2abbfe79dc2975b0f7c6a5878eaa5f72651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000985fac75ea1a20930bb698cd4ddae6c35ae385a6c8baf55ff3d5a3d16b9baa6c944bc98de5ba3d63de70c3849e13570000000000000000000000000000000008d7cfd17ace82ae9e8abfb9f7048c8e449775db821f84fc3306a96f35a4fdfd32961ab8b77c8ad371cf2552f4a3804a00000000000000000000000000000000038a81c8b851c445faf6a4af2a16cabc0a177f995d65a88fd97f4a7429266748274d430f57fa5be76162480caa40d76a000000000000000000000000000000000b61ade03e3870a0d6551def66c5d742a91cd75196f0dbca323903f15d47eccfc0135244d729b190d2e2ffb662c29ad91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a761939890ba36010fbb173ab01f4b7f3dc60c034630779061b294520517a4c3828841910fca97987b02a59a9797deb00000000000000000000000000000000194c81f568ba893882c81d5c84e15789b19291d850e684855f27a32f0c621b3a5d7bf9235e845a5164959b4fe06d0b3e000000000000000000000000000000000842987c242e4d98311f6fb0ae2ea80614013700c9d5cf0449bd5e07fc2d0b7306b516aba534883d718635267c09c2440000000000000000000000000000000012609a9ed87e6568a6ee5896dd3a01e58b173d3feef634051fd033b27aeb78949d162b10da14097ca327aee8b2d5c3a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000067fc0a69718226b192ec4c8bb4f254c579343e40e47269e6109776d0e127c3a90ec098ac9aaeb448b0174c51bb5ab96000000000000000000000000000000000fe0e2959b4d38a9e42d819b8386e77b7322b91b9e5a40310955b78385b8ba6f2a0341d84a1e5b26db60e126e4d502a400000000000000000000000000000000111507ab1b27ff88e79d0cbac5a8236a5914692165a104cdf32f93a0435559880b569761564567386fb3a4156569e2cc00000000000000000000000000000000015fef3c4e58d5d0dd073f9b2bac11de877b5cebe571874213664d85b880735e2e289915853ab4bc96516f8f0b5e68911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000041e1fcb9927b7fce1294d3071ac15abcc85e6ea26758a50610d0ffb3e114c92f31bae94c30c2b4aca787cef1221e87c000000000000000000000000000000001430c8371e5fba95ad5bb65e6d53405e5667e0e9034c0e27e34213c423eb4e87d8a97d6acf6210e3e61b8665e8fd1ba30000000000000000000000000000000003e9b1f155f9458dabae1891a9d69d0b8f342c7e3f86cbe1d43f56431b5ca210779eaef73291991fef1624f161c88b9a0000000000000000000000000000000014d2ca7bd0dd239a4930644bab12d1b350eb2bd33367d777ecb695a08ba3f6e3ddf1bd1495b5bb0a04973556c3f4dc511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017afa77238c5e0cb667e08b2a8c8a9508edfc2bacda648703fcc9efda7dad60f347f01ddbffcdd2a8c05c15b26352e74000000000000000000000000000000000dc197ccdf45b4f2503363983229918b8b69fa60778a2a7bd007a5751cb6a383d3ed36ff7b266cd66e68d248cd18263a000000000000000000000000000000000c5ae5ece084e9e7c9884fdd015047f6f7d152f687b887ee333f22a95cb9f3aa3dd23e4dc869ac8a23b5ce3851eda0af0000000000000000000000000000000007b9ed5fd063b75f9fc81d8e6b82d63fddf9c238600a95b3985c9dcd1e31d05f9b1e91f8150b14db48872571a4ef5cff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084c430f0ef1f01b7416715e51187340b4cefa4eb3adbb7a1f5e8459d2d910be20251bee0c8bfa012be3b90d7624d5b40000000000000000000000000000000016cfd5b2639f3298f40ae81f4faebd1e69c08462833e28125817b2732a871423bd4983efb71c12cfed60144311b798c40000000000000000000000000000000010746ba5447ea73a7daeaa61e60334a06e3a4a4506022a07c083fd86dc72ed15f9686a8d3369948704974598bcd89afa000000000000000000000000000000000b225fa5d85caa77fa823886fb2ffc5d7bc9600f0818666eaabec253211af94cdddde8ec8feb4e28972bfde8453f60c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000465439921f86e73931221d277f123cb43621670ded53d220776502df6cbef2002116dd46b8d7bd1cbfe76ef145e400000000000000000000000000000000004e1fc63250b42af245a6b32a21190a7fec583ac87c7375134aaf212d998c7bc4ad3cc00e2f2974a5820d2b6a3056b9700000000000000000000000000000000015466e026fec7d63696f332fc7d8a9a8b0b4919f81dc25e20c8d37cf2b9b6df7e3aeac625a3899dc1091d612e5cdef4000000000000000000000000000000000c33b599cfed8c337472164c9fbaba5c92081ce0d0662d0b4cda47880868c9f6ca610558147db95b653be75f6d8091811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f54ddac20f8ec287bcad0dd245ab866c68338a696aed87a21d7c122943c24d199fb0bc85a56e34a921f508ba847f11000000000000000000000000000000000023e090da52dabd4dd69b66e08f9ab5ea31e377e0a4ba89f36b9756548aa256cfacf52f8825c1596b31644c402cad4200000000000000000000000000000000058f91536572b5f68574b6a8ce16d177655cd92bb3ed56552f797fc4c03d45d16e25de704b7d33d3bb529dc4e8121c60000000000000000000000000000000000bc90836202a58a064e392c63de291ed768dd8ddf44867bea99f6fc00ab8d1a6fcb0cc5217aa4981ab8e0decac715ed81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f63d0a841fbf2d9121c16f09787156e1d22c77c6191ff0e60a96c81d97bb6ed84868a5854d4749053370bb0a5ba3260000000000000000000000000000000018e513210a37174836f0351243fbf23b200af071051822dbab4fd2820e14ab4c159d3526c61cbb396f302211ae5e2e7a000000000000000000000000000000000beafa2465df84f66b15f3e6102f4d0cfb88c208f1583e69e520e83efdfccb2291d62ae662fbfd495e3adca1d11f0965000000000000000000000000000000000cdae97ddad48eb80e89d801ef711514580cead72c91ff40834eea8321c76af62f88c3ac980958387b190f76a606b9801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035af7869f993e75ec07ab76da417b83938a3559a84ec5bc60413e343210b4f1e9eb6da7ae04fa787582378cdc8ae08c0000000000000000000000000000000012a313a5bdc30efa8c9d5a90cd4e91e43eb090aae4cdc594b484dfb4ddf6089dbfd708937940d2ebf583ef5265c6b5350000000000000000000000000000000014efc201d62ebd79da6d97208bf076c8380b8b849e526bfa1d8595c4330f162496124d63fe255f65b56fb285b77917bd0000000000000000000000000000000000d5760211807036dcb74aea4106581b126724692af0eb45da3d12d571a858dffbc564da62ec61dcb70e1a592e08a6f01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a1320c4336f9a93e02b73efe85477e66abec2f6151db7c0fecf734a27ce7ab0d5d12633e9ceae5d223fcddec16a4b80000000000000000000000000000000010b537e65eea8bdcf573c3cd3d89d11bab36af71f4d50b12050201b80ed55bee8ed2d9029f61b407755c20bed2f6d6c50000000000000000000000000000000017a0c6ec237814a3207e006779fcf80b0a07e7d7681b358cb9b07731b2ae4511b251585bca647b9b1896eac90e6c40440000000000000000000000000000000017f95ba366fe9282b139b30b8f1a9821cea66fc5b105c4a2e8754fbc8d42e24337e4f06c2b12d286ecd1ef2b4dfe88cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ee38452b1d060d0b5b594b5d9ddb3ab25804800c64c5ca4f6c95d7fa23b678c7443794c809196a80bbd82193e5f3d9000000000000000000000000000000000fc028a0939b82cd60f0293978bbf62baa5ce2c05ffa9e5121e44afcb5bcd380636e8a4022f29baadc6a89b6f413b508000000000000000000000000000000000f04ac782872244d617c637cf0670decb9661f5b4ef2d602cd6389b888627294118d9ecd50d54d46a804e3820ea91d500000000000000000000000000000000018c843142aebb5f3459dfe0745006edba7d8cb7a258518b1cbd25f5c33b274a94099fe4785ce43994569d230ffe8eaa41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e2d36553b1c03dba20e683412d7d90f8964ebb1a3d4f9eb5b220c32f3e408d178dd8b4017bffdc64f0565402e7228000000000000000000000000000000000a0dcfd4482271b5c9db255f36d011e6534a571ac82ff0f01b85d1655c5851f07854fb748586f7b0bd861f9b0aad2aea000000000000000000000000000000000ebfd8cdf970e76860a2cf7432760cc8117850dc77383178993b62b48c7c04c36cb20ca97d27b1bf43aa05e574a81dc6000000000000000000000000000000000aae79cea783414facc2a4a973b429aaf4443bc5f6ac518b0591e24f939db49e210a836d057917b44bf36a67174a306b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b494ab31945a3a615315ed9e4b9b89e293a55920a66242ca71d857987a6bf85e3c968acd588977e56831f241da124a000000000000000000000000000000000913c4aaa8cf7d57c4de6a49fec1056d6127b332b8b135501899d28e289162d3cfb19eb6bfd5eb2f8c015230c75dd24a00000000000000000000000000000000022dfc79a46220fe1cd8a764d1a0334a90f1f001f408787969bb688e9518f3035db065d645017301af32536e7aa3461800000000000000000000000000000000134c184220d8e8b13400677ce0756f8ef3e00da7d3b4a72458859034b741e45884ce32f3d26288c188fcf1ed1ce01a6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2bb32c2267b9ae69df73799299683583d2d442bec64457824bd2f1efd0c15696af4f0e88e6080f0944648ba1630f410000000000000000000000000000000008aa84b6d962f58ac3312a36d79331e9eb065633a7781f339bb0f7d9fd9af83e0f4ea0a58c0a23bba5f36ce099de39d20000000000000000000000000000000011e6734b0b64a57593e345c93f1a6214d3365c420b28e91d719985b4c09b81a77fdbd7027ab03cf4a369209bebe1ce2d000000000000000000000000000000001753cc3b957c364899724d73eff403e3e4c932f39060260eea3217b8227809dd23391ac77431e35b81fe6b1c76e8d0bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130f6e728bfb833172a003389a6f4bff85f8515804c41d385b2da36979aa035364fcf3ae0ff8c8bcfe6c05592d554aea0000000000000000000000000000000001344e8c7291991a9d96759c0bfb793a1545492fe027ddb898552fc298a4d2054d2d4763192c9ed5559cd6dc20bc384d000000000000000000000000000000000b6616290db82e28c08bdb193d2d17e6dedafcd5bd5a8061fb1a7ca72f4431aae4947a5fedb1026acd350cd1a11072c70000000000000000000000000000000007515e7bd725eadc39eb08229ded6af8735e032ecd6bbe1ebe828cd7bfe242de80e9d62e3de02406bb05067e4d7ec7fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005cbda9dedc1b008da733210b9eaa0602b07f8cabf9e56943d64012ccf4bb2c93396d2d03383ee68b65bc102eaea2ebd0000000000000000000000000000000016d7ee91de2f5a3605194a1d3336b724035ab8dc91ea460dd5e560df7388a58e57e6a6a45c27665de88339a7dab6f19900000000000000000000000000000000064af55ede76999bafef4108ec96923ed74da10f3a9f50c993076ba9669756fb3aca5951641e9608f5cc42416f83efdc0000000000000000000000000000000017067ef5779adc304ff48c7365324a405bf1a48542d200b7e9b4dc4c9e9fc1a6dade7a1c4eea3c2cd0accaf24e7acd121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d446b46a1da8860e7b1b2e5a4c55e002568efe4ca3d89a6fb50611e02171bef6c73cd0ee2c0183a68bd4dcd27f62e0e00000000000000000000000000000000001ec1a911224d214e20b8887dd247c9884f5e935dfb10fce3a282f59beac5e1eed71340ea51ceedf70bedf2614e640c0000000000000000000000000000000013ab6e89eb8ed1d5ef71689d7f36a329a2330c2574142eebf1a06e3ae9fab96293901c64c6303d4ef65f01fc4da140d2000000000000000000000000000000001083204307cc9f15f6768b4b77df2f8a68995dc1ed35e5ed596aba4fc34bd5c1e1fc964987942394f64eac5c2abbeed71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004328e525ed1e89479ae6cc0364688a0e522cd017d13bfee686a3fb92d65055456cf04dd8caf56551e38f21960eb3ff0000000000000000000000000000000000db6c5fa6af10ffbf625d1f69536c7bbcfa4d1c0e8cb0feb7594560b17cb8e81f6de0e840b51f90695f3f411ed66a2f400000000000000000000000000000000124ec35c7026d428a5898aaf4944ea7c7085ac6ea4382486f1f297e20e49990e3961f1a734306f336e0598abb816d92100000000000000000000000000000000073d42fb3dd0e4997957f56f0c177f8b3ce6a7333acbc9fc4f4af76d4d99ed85f23df1bacbfe856e9d5c555d394e59891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000747dbc33ae074b9959935ac56203582fe20645b893084990efa71447e55c824bfd6beeb090066dd0df662543ab2838f000000000000000000000000000000001845fabec5e37b75d9ff1fef67f4132eb2ef8e32dd7b62c5862078ef6d6b3eb5db2f6fc1166f4a23ceba9587810738d2000000000000000000000000000000000c695dc7471908de469d84930d84443560d0defc656fd75f2a6b2c924c43714216100a965fd9edb7f03a812e97c9bdd30000000000000000000000000000000019553238f598b7189f576219db3958598ac7f793418b839d75525b4f2e46733f3710c32488f1dde45012ecb6b56cace51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e37445856444580b397fd12fb7f1651b0ebecff3ca9c46e781571e435bef3ec81cca9baac5c94ce9ac6b8b53d201d39000000000000000000000000000000000e33d411a9c7272e71ca372f6158d42d03cbea01621412c389558bfeefa3135cb9fb0afab676ff669061b7d56604863f00000000000000000000000000000000165a81c2aa2edc8b3a032fbecd022b989c45e67533be7938f65b0a09097f20dc80d8954bc97d2660c8d61c877a7d7ec5000000000000000000000000000000000527e608fbb76005616be5d3bc3f08e046f9bb7f994faebd2f9bafe9e947e0dd8aaa0bca0ca99e894f0aeb010326732c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001019c6036ee2a0fc7445f44eeffd2d5db0b005df7301518719d22ec06e35db46f329c1ee202f65daaef64d930a1c16f40000000000000000000000000000000014960d55e06f8163293b022caaca2a6e5a5b521fc65eecee47a512d8f0d5c242178f0639c2d8566e3541b887b090e0210000000000000000000000000000000009af79097fd2a17735778b799aa7c11b6a5fab703e9997e4b5fc9a1cad3c72f8ef05350ee6af74215e75324a5b7835850000000000000000000000000000000017dfd9e10c4a6e2080892140344dffb971fa0c3a2ef473343fedcf14be46bd6c203b6573b36d30906ed31eebe871ed101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000180f84dfcf52a4efeb2eb62c66bb1bfa37045db287b111c2c491d37e7fcaa4bcaab57c0f9348758d05b7b8d742a60e5e00000000000000000000000000000000105171627eb5209afc2f8548f7741c810aae06c8cc1fb9f10a7b0aa570d9f99b58dcb096b5e24a66851af74e83648cda0000000000000000000000000000000001eb49a075e95ada314d6520fc0ba7b69cf25219e4f45f9b61cc715af4b78884bac6ec0c186cc85091ff00b4d6d4844e00000000000000000000000000000000057d550fa32942ed34be3051a40bb62109c17e81728727e30589c089ba50fbaef14b303f45ae344020f7c24ffc356d441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f07436cfafc0387e4e91a9bf4ec6c2d647cc32cda50a087a147dfbcf56f9816969eb394d7fdb0651a7fab78ab9daffe00000000000000000000000000000000047281dc56046733642436fcc44a5a696f3621b00c6983da544decf80316c4334a4492381f51406c602f2adcb8932bf0000000000000000000000000000000000820f91844679e3a0610a62ede6d5575327250e2fe09cff50dcc3ec86b4db46f5d33dbfcc4af1cdb87803c236e5646590000000000000000000000000000000012b39125b4f0d7b5abd1571b1f70e2a51b9d1f26675b5e66fd5f1e815034cd46c5f07bfa131c77dce08b96868ade1e3a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018381b08dcf7497935420b01d123b56b3d6464332f5f3ae060ad469660b3bafc170e42986a5d08b20b917065baacbc7400000000000000000000000000000000198bf25afcb3cd6ec7a7c63d81ed6f659b3a31c31ea6ccc4f6abc62cd816b65a9d3804f259fefd97ffb7e57bbdd385d0000000000000000000000000000000000a09b90a42456589b0c2959267c3f0fcc27bb39ea331a0b21c33b4dc2139c89dc9bc5a67bb7be9a5f26497d7e941e1a400000000000000000000000000000000138ffd4533246fae7d5459022bddc29d445719a0a64629d6d31265889124accdd7a134b093c23cd4d1492a595c9407191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133305807ee9bf53cb90f0456fab5a6331ce50c5858b63e53e66abf70751939a2ce20dddd4eb1cd3c6521d09709af24500000000000000000000000000000000003e5abe0ce05207439166ba6cd4daae1a42b53a3ae69311e5b25e431361af3119d1a15850d41fb6244725e8f5672d7000000000000000000000000000000000147b1d6c406648bf43800f70e2625b50cda14ae55eb97c5eaabc4d8d408d7ffbbaa196e961d4a1fa3e7e0a3e402b671f000000000000000000000000000000000dff3e5a5c8a1eab0016a13f52b9914e9165a0de9252fb80eb776824e040e3a4d80b1213dc2c7a0f67baa463c52c182d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fc66a36e3fffc39e0524c65e587510ed1142ead5658ca4d2d2fa41703d1aad0b2e088ce3ebb41873af5019d44e98760000000000000000000000000000000010ab928c40e69811f64dc00bcba54c0ecff044a39d5b8dcad8306438793edb56dbd8791942be3d35124d36022b169230000000000000000000000000000000000b1cad3934f954ba05cfda8d62e9dfd821a43c25ab2ff414b35e6a774865725f7ce62270fa80676fc1adf754ac6094d000000000000000000000000000000000195d27ee66a6f9dc11ed948f5b3460a76c2b9f6d83bbab696027f660a6846b79f3a11099704379f56a08e32f5b1c1abf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ab75b888f1ae21333fd83cfb93e171907d8b1b95d45483a551df1c92f213b1de30201e7b04ec8e35e337f35d4fd109000000000000000000000000000000001615776a85a520867052a8c1ea19d8d1536179b7849d4ecab9ec5612687425b46ae84342e0b8b07aaf85d3568b0483430000000000000000000000000000000012d06192ea2a19bb822a2565fbf9f3e76c09c3fa48022724cf44bcfd757775d6c14fd030298719aa3f51d44ac26f3ef0000000000000000000000000000000000047d169f7de3196f91182fb3c78bfb50ffb0c528e3d6b76c97d6429fdf6948f5cfdb3700e34e013745d722e4955c33b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149d4deecb9afdb80204e897446d7d060b7c2d32d1209974f1d0d9683d21bd3060d3bc596286fccd52bee350aea761a20000000000000000000000000000000014b4d08962d26b0ee461903793b60b780cfa7516a322b15ad6694f05f6b6ea4879ec0c406b2d72db315d041ac3131ce00000000000000000000000000000000019cbe0432490e9ebb9072fc995e5666935acaa49adb0bc9129a1fa1799c75dc3689be1bb8a432928383b644adace0bdd0000000000000000000000000000000014a80cd9727a3727e3816b77beeb0c2ffebf164cabf94518cd61a393dfe17df25a539ac59b328fba8b5e2a8c34fbb50e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000553a50fb49c1dd6471d61f6714f12304098a893f56bf84cb1c752470b64350d3250bb652190758255eb5124700c0e9e00000000000000000000000000000000012f049c16b72edc3f9280997e0c4701d877297443af2109931d4e699c3eeb0d842640a96b97de9dec9130f7d14e21fa0000000000000000000000000000000009f68ecf06f2d2921816375c5bd4a53d51e7ed05a1edb368bc26a528cb11c3d1cd57870b96fa6d898ce9cb0d07aec0a900000000000000000000000000000000181850492d5e6649331af0210c98b7f4b79871fd4fcd30a0575ab0214a265720f3fc745ef1826b8c0132124ff09fa5051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000011c4673f5daaf8d246a8536a11e2a0cdcb5164a1e159f5a84c66ac812af2ba01068f9aa0fc9dc25d717608db73728ad000000000000000000000000000000000a4e182f39301aac81b759d0a02cd916a1773f3a84e0e6cf334e5723305642510b9eadc550bc7bc18992d8974791e3570000000000000000000000000000000006831a8f215b2c672807a6e4e83df2dceff10ef7c9b9c588567d7084c9b59113dbaab212004f18978bf386a12757fbcc0000000000000000000000000000000005dd8291e9d7282f3ecaacd9d3496a42e0ed2c248cb737ca0d71738b5f6da02237472689e4c3e015e58c4e25559986571824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189cff90fe76fd51f189b00ba1ccc17246e46b2d8ea3a19a92512db3e9f1a99fe118526488a3de0be0fa6866558622590000000000000000000000000000000013d699c4590c6f3b3fcc78c3de7b194195251c0f556ac641f7f87c6cadd75fdc9a0ab340b340706d17d53253cef19ad000000000000000000000000000000000179ef69c8072cf5d91192c38fe5737d3b7435089447ffcca5d3fce53ff4b013d7876498f47a9f718bc9119b5feb2eb1c00000000000000000000000000000000020057b3ce97c01dd22fa9b9a41d40fb5341c25ad24b5511e6f1cb76f7439e485dc4957bc302f641191bacf81929f9731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df71bb08fb418533d6c515712ab5c2d287e4e3635f7ece08addc8d49a938f475b62ae0b5a598a1dd0fc24b1e52ceaf1000000000000000000000000000000000c075a8624972a038b9e2254cb687a463ea70b82a5982a951457fc1223b4c546999b2645530a7947b9fd79f9119d7c85000000000000000000000000000000001410084d1ac9f4c21013af8f58b21f12a8ec3736d8120771ec88a14e00a468f4ee3183039f99dad7bfbbea3302b4144e0000000000000000000000000000000006ad635e406c52381d509d01235b1fc3c766fee1468faeadb861b8e90185e64b3d1415f965bab67daf683442ee1e3c6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053654574e8f67559d97272a6a63e0e19bbd265500661c974f087e3c669be142fcbb0c7cbe8a1a3a40b6dcc291622cd6000000000000000000000000000000000cc07861c5d539bbf67373ff4a2c28d78ac69ef226789e34ae567d4e717bb6f6a3605fec897561a0680f421d516584da0000000000000000000000000000000014bd17548e310539800ec617a0cab956fc4697c1b667d596a386abc8d8cd89da79bcf563319634324574db6b2a138150000000000000000000000000000000001707b7d55315deed5050e166a9b236d12a9e8b70beea93eedacd6994646bc99cd787e99387848c2a68166bac34fc585e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000134212f232247bb0146903fa71298799206e1dadc81c8a5f310db5af337c705f9e9558c2f2e209a945ee1e1ecb6969dd0000000000000000000000000000000018ea6ac16702d131745da69b4d528c257a7ef0defae1940b224e22ac565a14bb539249192c8aefe1f763168d64125a610000000000000000000000000000000014dab5d9e7201254b90e20b27f224fa29e3593c3dbabc6fc77bc56a5b897359ed24dc887c574aa78a9d80be912f7afcb000000000000000000000000000000001508d2694d9dde8f8eba5913cce7971fd2ff9bc262be0b52916fd9863ef8ca2e92117edefd9e9638f6aeaeea8f1267ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000063ed171793bd5ea72f4bb54a7edbdee5fdf1994e55ed4fba62098d8145f95ac6aa14e2b10e7b2c9a6c716c4eb3171360000000000000000000000000000000002a301c64fff7deb7cec1ac0e62fd85f88836f6fc982f59d7fab10681592c6f083d32fcad434e7d8f55e7928c27c70b000000000000000000000000000000000028325b5057a14876f6a343076681dea465c5eeeabe48496462dd9366d5a3fce059ab8d1cb72389d1f8c2e61b426147a000000000000000000000000000000000c8294dcad1cd634bdd3a61999d0fe014ee2a3bd803c9c0fbbcb8e3c0f9a41446ab3ce51fa26bb243ece93e21441cf271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018073daaadccb7fdffcbd0b46d1e9ba0c9b6fe2ec2e2d5fc862fc3870b9f0e7d18b26943c526887ee01b6c25448c22e7000000000000000000000000000000000725c813a8a04e5f5e49cc773500370e994e0000ab38307e2de0e7c66dbc45154236bd100df2a589dbfab6bf7a970f4c0000000000000000000000000000000003b5a421fd3727ac7680427a3e95c1a2ef43d6383677e9c3df7c54dad239af2812d6873768bb4a0800ff01182d18472b0000000000000000000000000000000001d7474a2c9b17fc62fe996ca755fb34c91aa29ac56337d5cbebd2390246b6a6e400d5b6d2710ffd7012a2f86c6a403c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c095c2d195ccf82c2b7eb53ba940b535289df2315f95074397cb758517c3fddfb3c1f03bf73ef02974ed0af5c49500000000000000000000000000000000006f1a22ee51f26a3c9351678c5818a7168bfa518858c7c7a54df8267fb99ce3216b9f502f88cde8d3dd51e5dc75ba4d400000000000000000000000000000000008dfbf3cfab95dc2b8cc9173758d48171b77226d2613f1aa880e92317d20b5a455e668f5e7fa362ebc90fe73a569c020000000000000000000000000000000009d7e5bbac22580de9b76c56128baa3ea7469b861dd441938df0e90ca7f9697a83a78d82b1bda523feecbccc82623b4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008dc883445fef661285378b6e053f72d1b35d6370a0b720c4a65c3d0a017cacfba8e43856b46ea4fb1a423fe1f8a855d00000000000000000000000000000000102e181f8ca99cd94ca424e8471b51a856f58e2b9b0efce070ab53e48836cba89cff48b174d4c53dafdc0a34226483bd0000000000000000000000000000000005f36f1884589f4943d653266157460ddb048ca3eca86f87a4504cb03494ec842d4a6c7af42512cdbd3cf8e680661da0000000000000000000000000000000000a30548236a367de4f5293ab75aeb15373fdea9013d151c253f4555f751e2ad157ea295024f73a77bb0dfaea3ed386a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f28a3d7bf39c023e9dc1525c40c638d78d67a6aebd12edff007f6b9b45218d9968d3a98990ad6b14b8664e6a23f8f2c0000000000000000000000000000000017b70c626bc47e587b92c66fea71159bbccf3d3c3ebeb34879984aa81dac1fe88ff0dffbe60201028fd8c08740e276840000000000000000000000000000000013640dbef1de512d49b7e7a9190babef1238cf7fe7d69ded9387bd618b4fead5441323454c5379d624a53d1f00c81c500000000000000000000000000000000015094ee89fcf148fd0066539de3b6570fd5b8e4d47da981b275781367a5bf47bc59bf0a24f47e8c40b4847ee28376f201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a1bd75c543ad7af0c979d3b9fabbf20c8362e7a3b7ac2e23cb27c73c5afdb8b67f0ecca73e2e9cf12670e9ae25013700000000000000000000000000000000081567a99428365cb7fed72e455aa79fbd789066ef7a8d501caf02e6978f5e3010dd904a3660ae5a195ebfa2d47444310000000000000000000000000000000005a51918389a1c09e14fe965fcf079825c5704060d100e1574c797d9af0e177c78ba4644aee8484dfdbe98b826e7177000000000000000000000000000000000143d0cb5e6a7527e62a612d35348333b4fcb8280272c1639fecec02a44ca4864e7b017e46438b0430fb3cff4598fecd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011fb3399d231aecfe1ca99625dfa94e4fab53de98304286abec4f14677351890978489e3093ccc48223b2bdb2156d08b0000000000000000000000000000000009ff9b663e90ab72f7a37c47d4d4397c5fcb610daa04bdeb2c8c9a6a66f08ebc13b76252d7db7663be78123e3d4c4ada0000000000000000000000000000000014fa39d8892b67375717446244c3e18877aa4bc6bec1d235959acde5ecab625db53085a75df043f7092d91f586f26666000000000000000000000000000000001468e90a48d3a9b78e8b35abb9096fd11ec88f8a7e3b3da091e122472739915c6aae0677ce185d466b27eaa5235c720d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d9f1aaecec18cbaef602501e20b313ad72679d940edb729b1095a6657d467c80a91eb85877cebc62c0b74322a2202a0000000000000000000000000000000009afcd48687ca83a80da905908744443cd05b3d9b12d7bb311780bd5c6292cdb55a9bf2e00bb8cdcfe861d8d841ed0f4000000000000000000000000000000000c9fa5da50ad903a7f66d9d8aeb332dd26e9e0090199252f53ab231327029e55754b446e93b8dc58d7509a5175a98aeb0000000000000000000000000000000013c30c1cd7d26d9240477f01ca7cfae0d06f1ad4a6c6151b75b4e96b3517fd5c6e4af8480c4e7164b70a2e8b7668e65a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167d0387d68c150151824974945fb46ff605ff5b66d690d519f3143af1116b5e71a6b173881a455357cb0859f14ef39f0000000000000000000000000000000000f193c9f3f1edcc2b9d7619f3eb72754d7458979d804e20574f7e0dffc34378e216bbafbc13e279c312b5be09e930390000000000000000000000000000000009805552fe2979b1ed49eebc77407114bc5aee0cb9091cb3fbebbf0ab909f79b68da3e12b4f5e486257ee7e261df00e30000000000000000000000000000000018aecc8e940beeec9a8955fbcd79fc7c333258f9b6bd70ab488d20411b296c61bdb3715f6f693bfdb058e33686ec25b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025c25b732b0bd6fc5d20fe3533b756e8a4302e05fe65470050559e741a942e32da8133af8e2d823044419e0b38779a10000000000000000000000000000000000d18c9704c8e26e6ee80cbe3f3aa2ebc282e21496f6d74f5b5a8de7bc53e08f1c9331f20cb3ed1b64fb55a6294fd8340000000000000000000000000000000002e3345d57d4335b81d44b88b437c350b12a20e3867e85a8547fca4d618b8cc35122d7e54b7e136503615cfb4d9ccec00000000000000000000000000000000001eb2b67575f30cdd60f052128e0fe44b17a9fa2579d9782bc541ccc552354ebc0f524db84276f59a109fb4b6335692d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d1eeac3986fddeaa9df8424bc7bd44c7c29acb3de60f467e6c812e9b7f14f99b707a4a198d3fc70ce3a39c5ef7509d000000000000000000000000000000000d428063f48d0e330c6477a5c327c1766a2d52ba4ba476f7b83443003495c3198e0487f335d6b79dc9636f576e89805d0000000000000000000000000000000001ff67e92da087fc1fbc722642227e2c1aed8aca10c9d8334971382aec431e85522cc76aace7989027041f38cd31e4ed000000000000000000000000000000000f3d1fdfe3a81da72b59924fd2c71d4007639cada1afd95fdd75e141e86e6bd1a334717538a57f237e744f853c175b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa1513ef7c596d45ecead6af24b8fd3308ad308019de79aa5ae00e70bd0aabc4b8137110d31b8a6c18af843f7062ccf00000000000000000000000000000000168250e755b721750da8dc38e6b20e0f6092eee6d428e49052451973462057e1f31b6a5e4a7e0b3347132369a33f5d8900000000000000000000000000000000185701edcd71430466e0c4a7fd06dbd5abde9cc1678467bd8cf0f7ff5cb83f6afcbfbce74241db2c206222275534b1de000000000000000000000000000000000d5aeb387ac2f52a31f412b28d0e65994bfd71104a41e052061cf4073f890d2e81b11f20f9783d8c879ea0494ce9febc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042dd8764f7f1ddb50f7c8fedb839f416e91c1b4f59666bdeef2bd9cd0c9f6d602e98e368cb0e4d8a1217715eae946c30000000000000000000000000000000016e6ec2c26e447e8a5f9520daae8a74c10ca154902a7e3edcf01efc40927f897f84f28f37ec1ae646236f4ec60e377fa00000000000000000000000000000000027d8c0f382f8b4d99b659ab6aaae365f0a733a44a2f3676adf5bf28a546757b8b09e7724de5d7ec865307657101b1b100000000000000000000000000000000112dea8cf3872944a1fcb334bcc6f331b0c6de8db72e473ea9c9d914febbab6358fb3d7e3830827ef705a515c7f03be31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ce5f7f54026ba1d41d155c9271a0953b25bbd3c6496ed744f6589bd120195c9e9de66973af3f92295c8d99b828072000000000000000000000000000000000d237e432fcf3fff29f6c52ee6096f57345934156013bae091b5674e99b79b5ea37bbcd6c1fa92830a99d39c2d3de188000000000000000000000000000000000099cddb0866b818a3a47391a97eed41e82f119778339e40a336acae9a96ee30cf4dd2848e61f2a72a3535b2118efe67000000000000000000000000000000000d6a97fd54a765f7d7ee5a0e5becf6dfd593ee1cfcb4dc35c6bd2d5a7567e738982fac529549659c820225623e7986241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018207ef47f49a884cd279b216dc439d39eefe4f0c202a25dc246e75ab46b8801eb1ef55d9de6b0dc956d2bf29ff8a89d0000000000000000000000000000000000682fb0db1af5cf1ae28f99e9f704916fa1a89eb9449c9e68b45c9319c55feb699baedb65d44aab493dae61323ace1e000000000000000000000000000000000ad490c4e21f552967797a79a77fec33772045c0bcc0dae7295d07bdd1a502ec7f1ec093f3b839ee083bce6d9be58abc0000000000000000000000000000000011fbf2bcdac191374cd2eb64866cb2864c36a48dd7d81dc30815e6d994f54237bcfe3d253d6badd73125352237089b2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a89b43d6be6666ee0eb1bcc876429946c7f7a37025286475b7ebca27babd263c5c804314b436da846d27a3fab08c99f000000000000000000000000000000001613920fe70fb0a606bdb6f09eb80dea27ea78787b330100ac29ab93e5f830ed35e8e8b49e8438690cf6f8771e62f9af0000000000000000000000000000000010ac3245ec3b9f7e8efa9931bd727829447a5c9d86fc24adc8d159accfcf8344a0f3f026ef35af0bc45637278f9578ce0000000000000000000000000000000003b2ac3248566508a643b0ec64fa5d886dcde11ecf1e1b0f3a55f05bb84e042137aedf168675fc25fa0143a9d4a92fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e84ef00a1b34974ae511b95bcf17845361312b2cd7e9c02323038a6f347d644d3753075af11312e77e8816540281700000000000000000000000000000000008f9ad141fca814ec974d4abd09f01846f1f4c99196934857f8eb49b9a8e0fcd281a9ecc6846cb2dbfd34bfb28cfa08b000000000000000000000000000000000cbb0894ae780c336aa88f479d73764fdcc4b73625e862b610439d627eff601a4ed8b5a8b53f4e2d786a9ca3f74da03d000000000000000000000000000000000b2285fae63c4a7860bd021bc5d6b32336b3629b5f635307c203ccac1f954615e6252c8c5dfdbb5846f6a5fe55d615be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019291c6f7a563074d7bebd65fb39d264de46e5c10cbeacbf409acb534aa2160e1a77f36c3c934fcab6e3e4b179b2b8450000000000000000000000000000000014b374ca1c40554dc70f78f36f838db9c6edb403c2500d8eee09eeb8f685ab565654fd1edce2020d533fbe8062cecdec0000000000000000000000000000000006a6bd2f06d3c54a33e08c659ee028419897243d826a90be227c53c00173de0459aafabde8dced73864cf104d4f668fb00000000000000000000000000000000119bdee636612c560c20208f5023fb6fac042f927ec3bf170d60582f05b27439b222872de2281f9a26e00c37248c3dec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000059944bf832302da5759bd3fbf7190031352df44963275e5b749b8e2a19b1a9cf56ce676a7c8495b1e8fc10daf731e700000000000000000000000000000000145ab4babd61ecd83ad9dd035b3195371dd6a09f7988886a6988d39b93ac74690f8d293c58cadfdf2e52f1a89f1e13e80000000000000000000000000000000000e9d3b2aed2112f91db906d6c33de7df37f4fba17ff2ffd0b7cdf24ccacc3e1b631085e64b6792ea4caeae44aeb8a49000000000000000000000000000000000bd91ea606403ce81e177db5ab9eb3304bd248697f71f6c545a15fef90a9612e447104f4a2becb76213b3f9a3a1537391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000035200183eced81565c8223f52f7eb624ec3f9ec42fac8c084fa52082b439c32d725523f21095c85448fa4075e6264d1000000000000000000000000000000000f9f49db2cdddc9066d1efffb6c3b854668f73699846a99f200e8cb3d36424e706bf7da998d53b3ea25fd6bdb493ff280000000000000000000000000000000019303ea1c21a3d79a1c41d1bb192017d0d9186428095bd996e56bceff7385580095cf4d93be3fe11aa9d1695fe2d8e410000000000000000000000000000000011c972fd52755534001377c98055c13b59d7eca825cfe928829eb54cb27089ee5bc43d98e126e4dcd9901c9eb9a846811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cc09652fff38fe1b94ce9c22989e66aa990d58e54b74adb3b43258a3dd768eae9b0208967746e7b1fc81274d652ca700000000000000000000000000000000112d62b3918e000b487f1e419969dc8f6ff82c126a1e5fe85a9647c3ea2f7c7236ddfe084e4ed61ad417fb1931547b2c0000000000000000000000000000000014cb264217c66e9a53f4ff1d151956a4a98111bbb42bd1d07a528fc26bb8181ebfc51f67bc3a42739834a5319800873300000000000000000000000000000000157e69d3c1c7cd190354cd51ba11e4699f0db61185bc2aff603198c23ac82e6e9f5e5a9a337efa7d66d23df462c95d4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017259b78fa05fd691262b7eba64f90bc01d52189cf368948bdaed8419c679b31148ca3897ac92da3868bb46cbf364f33000000000000000000000000000000000c52df82928f0c1d1b6af11ced001758939b182e612a4efb8fd4748f4353ca2c8fdb818d4f6801f1e1b0372fd463efe00000000000000000000000000000000000acce64cd8bf0ce97d71a80c335cf6f1634d50c44a8489d282397021fe06a8ca8889fe775d909ee4d5062dd5f8e618b00000000000000000000000000000000059ae0973d9afbe900804dca9014c116e378be8d404bb956739af4fc542d55188e00abec42dedd8ca5fe0ad13bc71b461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c27e23a3745c3494256e04b1804fbc26ece509b8f615e8969d28d01225abcb480aea62bf24ffd2897562ffa158464b7000000000000000000000000000000001725c7e705b5fb1ef59a4236c6ce138914e1bd7e9db9448fc89f5a00dfd24c073922d3b1305da378b87213044f472f6b0000000000000000000000000000000007c7b4b5f5267ad22776151ad738d68707c79e43a8344d891599833d09a4f5b202910e49dbb4edca7cc3da966839ff46000000000000000000000000000000000977b438b93819b4390a8a3cc6c7ef0f4dfb2db1927c9045645683e3559241f3bb6ff4ff59f99652c07ed05318c4db1e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163372d3c45f9e2eac9b265bf182d25cca7c46c236e9d91a4cc2db4d735b6cea5840a5623411e6dd7f09f5970a1dd6a40000000000000000000000000000000018433796811c2b9fab0c50c14538560a1828427d60fe422c37f3870a132e5e6a219b91fc769235d3576d246e7eb3817900000000000000000000000000000000077251b75cc7aba05269ec992c40f40b5bccc3cf04670e31b0c11441c6fe5e9f4953f3918b81a2a0efb3611a6e179d5a0000000000000000000000000000000008716216346f3159e5c85cf8078d9f3d29ef8e0990ee3fbb99b17f12a8d76a3ba0526d6eb1f247ab3fc7297e174a53931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007609f1a9a21bb51db41e339de97520003bafa842ec8720daeca8e87fd13deb62cbfc342113a773f7d236c747de99e9d000000000000000000000000000000000a394999aa00a495123b848bc041f1d8141d104b10ff3ce17428c8527d9425fe7f6b956e322db703ab81fd644195fae100000000000000000000000000000000101e1d860ad8429fb74d2e6096359be629016f35b6cfb06b82863648c74ee3b2de1044a41429730c6b6b5607a065c67f000000000000000000000000000000001670e95e6eaddcee88aa9f7ba4135f82ed1712732b0fcb926b940f78998933549d1fad909847d46724eabb8b606e4e5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d51b4fe70fae821aa68dfe507e23afdb2f6c5dfec5bf9dc93f1837f8861fa6b680ddf3a60cade2bfafd6c0513be156f0000000000000000000000000000000001963af7a863bfd4bc34b7ae8e8a401c23f8626b4ef4e73f645b161b0683cd8f8474d718595b2d98da50554ab67fa7680000000000000000000000000000000000e20c4620ba58590dcc0578b6e2e02b5310ba488303ee3fcdcb9d840cd9a7a09c366494ae9e1cb7febffa56cf18e78c000000000000000000000000000000000462f86a7341e0621ed993e7b14badf8aefd132915dbe99890be7d6f3f204135ee16c6ca90e629156770434e77ad1c8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011cde12d75a6e6e62d8a08af6b2fccf448c19a525f5fc7848023affb0c9ed310303c24bf3cbe5c9de81a3134cd1ef031000000000000000000000000000000001386173a8e30a6e7b88474ae9064d9bdbb2c182940449d843858a80202ec9fd7fe558e463f789f226bb211490d181e030000000000000000000000000000000002fb942fcbac015449c0448ff02d562802bfcaf9681661caa78b662e34d44bcf5ab828a5c8b69f7c71ee4e3a073b58e700000000000000000000000000000000166935836a70d0397e751bec1190cfcdf2e80334f04a8db22879f4ac236ecdfcf26b5bd633905227be2f1da4a37b046a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005780ac6e2ce2fe88f13e9cd39e5a2206d450289f216460bf1e49c26ef55c5b85829924babc285e1ddca62935e569f340000000000000000000000000000000017d4335cdc8bf515147f9b856fa8e911c77807e1e94fbb41f7c8ad576eea5201a15e916d357535ce830b4e3b301bab0b000000000000000000000000000000000ec579b70f8c4309b65dedf0826deb04736e8195fa83a6a9623556881372815d0845cd0e6bc7b80915e6f7c76e790fee000000000000000000000000000000000e88e2887831e6cdd4181795a6259bcc91eb61a8cb81651c73c4c6a07eeb9233b960208cb482f9cd8e6803be6646f8a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009007c0b8c2429bb53212c6b84481831b2756ba4ffd6cde21aaf100bf0d682798671120d873d40407e8464d91aeafcb5000000000000000000000000000000000c8e1d8f27d15d989bb3bc8274bcf06747e17971ce8865af10bb5a0cfd2ecfc999133ef012469761369d9029dee795170000000000000000000000000000000002db7c39c99707064e2746248ba53ff6056a3372fe573e3da65298317297382af0bdf78e53f762082ade305e32846362000000000000000000000000000000000e0e7e19f352f348d83ac7cfa8e7ae514533f972850eeafe97ee7efa01f7d9d032289c4dc678ff1dcb9bab4e3ef775b51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013def788f3c083c0143204af94457ca879a68ec67203bbe5c5e0d170fb506d061f9a412895fe6e191aee3f59b768e540000000000000000000000000000000001565e3884f0a538de3eff89df68db64555ea011361689b1219723e79a236596051fd788fed752226ed9d4dcff801ef84000000000000000000000000000000001040c8e0c3fa7d654b947b0279a2cf3a4cbb7c2317889496133585c0b7d7f0f15a3da197409925044d38e05de98bc9310000000000000000000000000000000013300a437ebc507312c0378363e79e2cf7c9c2dfa7ff3e4d1806adf31fc19c8525e5714808b525e2dcaca717a2f177f51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000244c1febe43602487304751606d4e264e922e367d8387dbfb115304e067b1f5f66765c58eed6d9147e3169e6a647f2000000000000000000000000000000000074ea31af02a6aac1eb2b9d43fa35e92caac00d5ee2856ceabf24ecb69ba50bf8582b1b5e9a36a2ff0ad2e20010710c0000000000000000000000000000000003d12fc5cc498aece813ad8b7c9bdbac6683244f765186f39621bf96248d3e0ba8cb7c0164931653df1c101290a6652a000000000000000000000000000000000ebbe0b846c834608cf5c7b6b2da1616257d8cc551386766e43eaabf56b041419d595136e595e589d00ced3c073c2a5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027dfbbe2799b4d17a84b633df3056fbeee5d5254a1cf2740b6b246bbe3c7f7bd41b0ce7c5d4eead51b6f90a34ea628c000000000000000000000000000000000b8cfd51c527b7c68af7f8c2a013bf33ddf39eddd955c97c880539f16ea92e3194aee1fb2ea9da3522a257cb7aaa7a44000000000000000000000000000000000658bf2cd917aa308b881e39110a72a06eff60617eb91f7d864525762eeafde8653ad42ea2e6297820a3d974b20fd3a8000000000000000000000000000000000db6cfdc714a9d5f2d5fdc7715800273079dbe75715f939416472e1154e80c43d6e2bfbde2399453fbd682cd5f1a220a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ffd2ebf6aac8247c18f1a9d111ef187156138dcac9bf7fe01110c19885f0af511ecd5ea261bd4af36c3417b0e0c846b000000000000000000000000000000000ec0f821c0c1a297f5ac974fc0cfedcce1dc154fc0d93be10e6bb3e75a8e638545161fc94d5de27cf063c6bad92f3a30000000000000000000000000000000000dc0c8b13f55e2192fb537d5f6c5da80cc0b935c54c03b02cf2fc493695dd6d87363c07fbcad0cded3b9a4e6b4e296bb000000000000000000000000000000000816213c92aa0e50df698eb435b2ec9d4adad4a4234a5ceca8c2acde7f5513abeea1c4ba2d3acd52d81a5a71b00d8d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001b156b96551f7c49c46f16eb065a1cc07ffdf82d41b0b0ab00b7fdf60748498c0bbf2e8d2558fe3e5414205f7929cd8000000000000000000000000000000000cede2a6e9e959fc87a98155c3065a3174a0f2af45f89f02c58eac5e5806e9a7c82586dae683a7bac52055b63c195bca00000000000000000000000000000000196ec658419b89a73d47eafc8efc018d91e8250b0b3b51eef9ddfe046fb244e6ed509af8afe7e4ec1f04ef0c30d6177d000000000000000000000000000000000126f9f054ab8f5728e4e055cb9bf5a1df678281e74ac9ebd83b9854f170759fb052c81b41f3cd1525b4a221661879b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001514cbe8e0c8959f8076f84aa05f49b80e1050583d946bbfb5c7cdb78c971fe1ef1ab1406ae8b7f8eb892d1e2df7f9f400000000000000000000000000000000098a22a53a99dc2d6c2582327f22cbed632cab7f6a8202d8f4fac48d6df66e70017cd0bb4aa83d817c05000dd6abdf5000000000000000000000000000000000180eedf78a27b9feb2c3aadec66b5287677829989d93af9e25f003b3c11d9002ad76bf8787d5bb37d629496f2040638b0000000000000000000000000000000010c8e1f57eb51ad18a42ca8f02e7ed1250e1515a122571caa5893dbc660bae2d2ce91f4c33e38061493aa6ef2eda94801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd89253b00beada2601f18e95dcf3554e9bd251fc2ff3effa4eb7e05ac50cb0c533f974c61cd4552d9213e6c04c5abb000000000000000000000000000000000a5094c7e506041a1980fdc800058fde643e07009e4a54f2040478158b0e18b3934d9b2c0dc38ca226395173df33f7b600000000000000000000000000000000179edd70799aa786533adf0d788181001f10f3ebbc08f72edb965b77b3adb1c6825cd8413d495efcc2beef03fbddd2c20000000000000000000000000000000011aee05037475887dfb29015355d3adb7487ea9244a920d8851a83654102c2df41264296dfc326ebe927a37ea2f4f44d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042bfbdbb5819cfeba687c3ecd5a729ca9eb471bf4f0ec949e1aa79d179056b53a3836d8245a2dc5455518fbe49b9301000000000000000000000000000000001131e13447835cd01c0f9fbe03653afe64d0177e3fe010dcb071f4c078e86e997fb761ac3c28fe9c0c51f90e62a1018700000000000000000000000000000000043625fadd868b79d5dbc93c29b66bed78d4fa2ee8590d3cab9c039935fcdaa6d1dc24bd5850bf3d0bf2b9d276ded3580000000000000000000000000000000007a0d010e5cb25e9baa577f2ce4cf588a7a5f794c490e389dc7691ad3ef9d36923a6a5e05faf9f8203d393d6f17570041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011313eb2c0368f64834c62ea4a21699025f0b75256a2197aab03846daaf627f0da0816bfe63e84233ffa0eb5717b2680000000000000000000000000000000001743845da7cf3043ef54d90f2f4e178eedac6c8f2ecaf717e6524cd93e29d0317252a2ff6c284afe0ac823fd96837b73000000000000000000000000000000000fb7ee15f22ee8de7fdc4359250c883bb9baec75f2b0ab56ea7ee67e46ab092cd285846c31be8171ee5f240abdf0fc0d0000000000000000000000000000000007ed200d16f2d0446e23bf4908c099c043e19e0a1a036608d0ec8bff652e33e7e15b208bcf7729a55360d324611a0bd21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001677bc58593f530326550b484ae187024e2a087fc3be7c13a99cf6780c227435f5341db8f001f6df9386ed5c37a9153c0000000000000000000000000000000010f9af2a65b0b34902f6eb5c020f4029d24cc46961935e4fc83efce8789b59e90025bfd612e5a8930793f5d28fbf257d000000000000000000000000000000000abebcd8b26f10915f074bd253e052bdc3fb0865ee88745d32328292bbac013602ecb388f059c880d5a4789abc573496000000000000000000000000000000001102d15cb931a34e8eb016db0e46450133429502e343ae10de97b8a407c99d4d7beff207be58e928e6e742ca911adbaf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ecf9a2d036c7f5c5f789bc99a13da40b6f2477afd666f2c9d1b27399f9983a4643f9330bb6e2e5b42813cfd82262a8b000000000000000000000000000000000e075550adb19de7f9edf0c80ce20598ec815b6f622516ab171aa69c697da5d8dea8137dd8d6af6e4f4448014f13ec5e000000000000000000000000000000001872ba58fe674545df41d435d3957b875e612b3b92410b3f30a3ad59de6b2d39ac1f99662c67c37484aa1bbf7e280984000000000000000000000000000000000172d9bd3c908d742d1afc5952fafcb020cdcbf41e2efd725a26a3eb1a40797a487a609a4cbaf6bb02939e4af2553e121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7e4ed9ce55921795e50504edf868c8afd9524cf13fa028e58f02565dd441b75c178321a7c1942fbe70ff3312d6543e000000000000000000000000000000000f1bba6ead692f7986db46196166ba9b9a616894be468cba3982b943ecfc72e4be3e53e3cefe40147c4276814e600ab80000000000000000000000000000000000398fdbe1b93cb02617029fd500c6ff3ba63b883dcdbaba4f0b143fb2cb035874dcd3a6f271b9e06df0d3c12e71123f00000000000000000000000000000000115d8367c5bc1a84af7f4a83d6241823b805d5d35740afab16d232130d7fe0a5dc49a92fe9fa360afca2f09d6eefbf381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006156bf218e8c2c50b927f9596dc17aa82bbf2b5ff85790a1e2fcbb422b61b08f3a976df160ff74623c30c6b88c65800000000000000000000000000000000001701fb001dd1f3335eba33ad5bb740b7ad917f0eabe8ce5d297491ed44391576dad6fac7bb18acd32692c8b92f8b99400000000000000000000000000000000116f035c44caca417117d00c77a558584a9464d1c426bf8d1118f8a3bb4c1b71db36547bfec7dfab188d479b8fc9f3e7000000000000000000000000000000000322591bb68f2409c483d34a1e55581c141f9d6c2032b2c1c72057a9d7ce36974141514029f99b245d32506653ed7e7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101b19b296daa4d12c0581ebeaa04b6dfe5fa3112e8709a7e2fe97242759efaf20e2e13556dc1af09c033f30b1c51253000000000000000000000000000000000794f9adb5ee6355123673c9226b12628517623db368773c1066e28876ffa1c15cdf643569e9e1d29c8c5aeb2f7e307200000000000000000000000000000000093a88cf490c92177c02478e05e340b888a1a257a76c95cb5b998e09c152f28af679405512887c0f7d1bf80297d0cd30000000000000000000000000000000000786a9148c62aaa8bccbb48f31332865dd03f2bb58ca61f116425f5ad935e45ed4074add241b62b659452838c231108b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee1b05dbeec7d3f5c8646f4fee56c58155a4faed7fa29bd0b36316912a1f70b4d6b15c3eeff607a8bdc9caffd800e9c00000000000000000000000000000000028a644639a1f95f696109bd9fd771b7a87b2057ddc5068150cb3048dd57b5ca4199924bbb779a5496a953b3617f5af1000000000000000000000000000000000b71ef7777733fc3f3dfedfee92eb1b883760a00cb22d47e2bcca623efbc229b5cbc443aed34684dc3530841548c3c05000000000000000000000000000000000d4d5f057680ff3c45ade2ac0729e85b433127899df7eebf4660e2864e30cb30ac6d0a9bf2eceec6f68a7a0128ac86d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000016f8ac5504f9b44ca40c1c6af1b4cf9beab80d4e356e20234740ced20614490834d50b264e56594ede33e3b652ef9e50000000000000000000000000000000016c4a07044a62d85c37000c9f696e5bd7fe4376ad22216005fe7d9a8d8c9acdb40d13e36959e03a810f5f9e9cc386e400000000000000000000000000000000009fd2f411d1de7aaf889f01f4ee7d96c2b85d312d025d4c11ccea64ad951adb3e74f235e5d28c5e0b22a4c82ace74a9c0000000000000000000000000000000013069b22e7304768c4040e1a07b79a7517138d97b23c472cf2b1355c940495b931dce2ba62cc6a5d6b9cad6e8e05388e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bc23bd1bdf7d6cfcc5e2eedaae20a4e339cd05cdb131c736338b216765e405196ef09b349721609be9826131d44878000000000000000000000000000000000bf00cbba2e3b686ca4ea3a8fa417cee87fbc7d0de49486846987b6ed995ad49dc177776a95f1ff61340dd74630ed4400000000000000000000000000000000002f9d5215809f8bb74a21916c19aac86e653a7535c43800da58001a5f2a2f2b26e480e6b78ec647fbb51ab129832cd53000000000000000000000000000000000674999cf32314eddd2cf06cc4d646b30ec07cf062a417e4eb17a23fcaaf333e1cffc6a0126d452a854e28cf92b898051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017038fc18ba5ab6fe6e8d3e6d124c6ca9a1505203a9f5087491e8a25862db909f4658b0fdb2e786c7ef816b5bac45c7a00000000000000000000000000000000038e6ec25d840e7317a2883a30331cd1c3e0b2517eb0b26dcf2f001abb77c5a08f1205ed2277380868b22092e1de85fc0000000000000000000000000000000017ea8c69d4ce8e12a5ed137219c9d6e4c662a1d5747ca660414b34f8f810d84c68a08f8fb31e3a0e79a928f5320435cc0000000000000000000000000000000009768b057adf0efc9f74cc761e7d784d46eb0eb388e55e9825704c5e783c640c65f7599cb59febcabb278ba5a950fddb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009d8a5bf87c36be002f5e62faee9a5cf1ff7edabefbdbddda85c82f236cae9b625920194b1b0a27d40b197e16baf1e47000000000000000000000000000000000b370a463ad25fb5812ff7a0ba468d8ddae1c38881cc2f88314df3d5b52dbb61df5db466a31dd26b75a6ef4f3c8c37be0000000000000000000000000000000006094bbc34bbd8a802f775f67ea19feffb2ae007ea7b976876b19575a917eb968c53c8d3bebdf999575eb363c1f229520000000000000000000000000000000010cbaf057b6e32b7faf7ef99c3403e8bbb65040f20f85552d0f38f0e6468a4fa72c314924465632aaabf9b50d8253a381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001996a1974dece1248b83b80a4233fe3c0188c9f687424a4b19ee807be1a24ccc6cf6cb3ed4476e043e4cec57eca5fb66000000000000000000000000000000001997d422dcfc1c375f7755828d2c841826c7627b726d1595fed32a0780365691b5457357a2617c48385279376a0202f20000000000000000000000000000000009854ef3dd4eceef5bc2955316eea0684c6827ace07583b789265d788c44dc7b9ab8673002e98bf766b67f964aed8b700000000000000000000000000000000002e03dc04be97478afe07f0b6d160a4b1a1ab4f339613a6468d92f0a1bb08c6c3f0d6ae5cc6bc213b37c995122b0a6131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000123167916a2b5016bd9031b847d9393888f3be3a862c615f5144598e1be6051cec9c2061bbe590c0f0064704cc160665000000000000000000000000000000000bf74f7eb3decf172813caa3901bd5569159ad30e71085744cb29364098fa94ae3e1dab50bb86f741a62f9b006b9738b000000000000000000000000000000001317ede6ac4224a3fae94a13cfc4210d170a6653aa34459f63f1e4f4a61476d197e177403b604ac33b9cc2de93e63b5f0000000000000000000000000000000007d550e423ff88e849e8ccaee57441c25f481e00f124243f38f2d9fc675d1e8a18845c6319494d5aaa89b4110330736d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000078691635956ca100a47eeb0af5af3b1d0089b3922377eebde4a7d07401a326211505786d011b1f6ee308c286bb20ec000000000000000000000000000000000f7908d5db053e1b57242532c2af87db634beb9fba99631af7037844840fe2c39dd000e8fb18d0559700fddb395c2ae3000000000000000000000000000000000204a1e215e7c01c65ee576a08afe014b4e1204fd4d0e24cde2f561af0b542a788e483a8b2766bec5f6bb84158d9a5290000000000000000000000000000000001f67ed7aae81a9e7e948e4b65ad89e88f9a9a75d015d28cc516aafee6162b410f89d91276e6b58186828639fc2762c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7d078a6785dc1689ec0a5ae460508c87db47c11460b5a27677b598f87a35bf1253b37f53ab83cef0c13d6db4cdc9e000000000000000000000000000000000014cb275bc56ab6e2fe3b657998226e4e6e61351cd98978e5d1860be5d30174ed51b7cbfd849a4725fd0ee371f197fb10000000000000000000000000000000011844dcc9d66a0b018aa1bf0fc5ceacdc984d3c81c4127c29f84fe048b50b6e32d16c5c48892e6081952715f145e0a66000000000000000000000000000000000c590593ca7968d9420bc354e9833dbb856b9c4be2dd1eff8319b348dd716f92f02a00fdf0eda30d3e16548d8098bf7f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bbbea141557723d939844d8d389aaeea923f29572922ecab9df9a4d7aee8298f9052cc7aad8718d804add3674b0fbab00000000000000000000000000000000181323fa4a9cc093181cea0426599d10220f9fc8cf866d4afbfdb1102279ef3511e461890e88198169a7e80b8eef6e19000000000000000000000000000000001045f55e6cc206ff627aee735fcd30b7dcdcd6bca99033b4e5606c80e3cc21bd9cb59c7f3a5e6d6ffb72089f6cd10394000000000000000000000000000000000e657d8cd91f791a98e829024df07d0cec92cf2fa4ded59a77f7afded48d4fa18bc19e04388c7b8ac7c47bbefb1c24661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b66e8c0b0c1068e685663ac8a74fc48bfe98b53630e674516f368b4adcbd066e6b0a71fc67735f8f142a143b62b56e200000000000000000000000000000000127163e526f2c04a4eff66138512aaf06fd1c0d3b0ae6b2b5b0ee96375266257225eeeb4dd7cf13d8c55a49affd7d6510000000000000000000000000000000012c5ca350117c650073362abc9f574d53cb0b629d005d6473d1ce3e7dc2769906efb7c77f1269ffe640c714861fe7da800000000000000000000000000000000042bb4f741538d71567a2ed5658cbc575e24f4f2fae610631f76fbeaf4668583f8c757d474f69131357d9b44a9feb5201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000596f9a2717b501d0052ef7167cb14710a6ffc22ef66239d373a9f8655a42692866e7366c921a9164c876ab1cee68a4b000000000000000000000000000000000c29df6c0191a87fe13c50946dfee8cc5dd6c8168674acfebfdde4c5430fc6e17de9507bf8a878aab88f17f9bcd0c91c0000000000000000000000000000000008fdffb184d72438a4cd355fbb45d2a9d1f92c51ee18c8c4505d1503090382e0479eda005bd8709424ca0eb0afb6aada0000000000000000000000000000000018a4a6b4867bbbfed63544f4f2d7fe6e07dab1fdc8418dbd375b638d7e28f1b30882e57e97387aa6410f21d1083e89b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1d105c03ac0e964fe62a9af0d5e16767ce5bd2feebad246a4b0daa82895707e7795e961e4d7aa264854a263e24d0eb00000000000000000000000000000000154f26eff2b4a9de2308f1ae8fe28cd247e8137df08b5d2aefa2d9552d1c483fa7aae4b2db4950266ba2b3559f71125b0000000000000000000000000000000008f93ce2fbca8452abf1e97a4bc6b997bbf151ba831fe7385fcd7a1135737cf66fcc23688dbcfebcf69f0e02a8340ff80000000000000000000000000000000015eddb9e121ff3a4dd704f52a47957e1630026e832850e74a977bf53ead27affff9fbcfeaaa40fdbb469c0ce92cfc4cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161db7be7e529e00c94958acf7eeddcd5db94327114370302e630855182bc5f68c00a474423ed70ae8387a0870fdcfc40000000000000000000000000000000002122b6b8e70d47ef1b68e23194efc083f573064037069f9c4088accc24552146ee557536e362f52575e7b2193ce3a0a00000000000000000000000000000000064eb7251d50afdb5989e7aa76d35a84c2f9ad011cc44c9039fcd3bb3086943e847e1810a68f67400b664b7a00dbba9c0000000000000000000000000000000008e48c44a5c163547fa43bbc6a1761bfbdc6846ade7d8551228ff8725a56df2815f1222233939440d6f350ea7b866e071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a698abf6d5e08149190a95ac357b5e00b94372ba3e41edaac00532b554d360aecae081a9cf9076073241d86a59458500000000000000000000000000000000024bf59ff07ce6e319346a136df739c603411a0f2c5676d3b100f5ec86266015856782e1e01982dfe5bb3cc623ae4b4f000000000000000000000000000000000df2a5a9022accb780490ce7c73633812c3221c59ac11f82e3aa994f701f77b82ee5812f7a252dff014608ec1c6fd5ff0000000000000000000000000000000019062145773f57a55bd622c1e77541331b744a986523936c0959ba2f90d15842acf0978924d136b929c59e17ba2f1c7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007401ea828b5fc36e7f50609b11bae9861142ac18c4ca0f7f11915391ff84b758ba028fad5c774e9fda0b22ff05040c20000000000000000000000000000000019e6920616c11d2874e224d9d14a65e06121308b59399d48f487bc8d3f3aa505b0a8afb3d039990405961f4cd8cf99ca000000000000000000000000000000000e56226158b3b388de0acd29ae0cb9708425d9047b6d0f1c8cbfdc3b26bac3cf11d30b02d3daa071c2657afa03b2bd7d000000000000000000000000000000000340e4fb653fdd0100ab142032a600f8ce62db208c739b0c021932a9376b91b4f9a3b3c11497415b696b2f22b397d55a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f4422c9c408eea5d315ce6df29de6b7df007490125648b5c1089e1d8eeb82b3b9ac058d71d36a387e472739de8e9ac00000000000000000000000000000000015b0186d8f17e9f2467695379ff10bf85601f4cdefd8d5d248597b42117ad5466a945e033a0ee0ed476df608e2416660000000000000000000000000000000003ae0a4d4f4a6ed15d7cbb7f97e13b56e9819928c264a959fe01fd9d00750c769d9ef0c52c09ffadd7ab2eaf55d9e29c0000000000000000000000000000000000d1058a812761217aa3de189881ed8347942451473eba79d1aab4e2a9db55123f5e33eb47aac6b057337925872c5cae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001444f08505a72a4b256683c9c2ab7c3bcc589626c2222d1d782511888df4c77d72fbaf267e7796d87097ca38e539d33a000000000000000000000000000000000b8cd5bd4b704586914f40d423f4173c1117e7b297a7060e610d1ebe0c5e1e4fd6f385aa726c4868b3b992b3fc7cb77d0000000000000000000000000000000011a701f2014d4dad656cef3410e54d1fbaacdc310374c84e86727fed21bd94b988357b24194555624d3fced3daa719fd00000000000000000000000000000000069d333979d29ece520448c9ead568c5446d78cc84b6fd2910823c58f2bb11f796f42fb2189ceaa20f1a16ca6e83aa781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000169148efb919d35d84241377ccc023352a0b770697aa2b0f83a66ddb57c1729fea06aa72e16d372fc0d83ed75c9f1d37000000000000000000000000000000000334cdd605b44fa7367bfe5c93ac57ec5247841e7e696c96ac1377ed4b9683ff57360ea015014aea144d1514edb4f8200000000000000000000000000000000017f1363dbd8cecae0f690c1d9dda176307a1637b1f2df1521c0f0e3241b59ee1f55b99f9dabea17d29a845f0c2f1e6260000000000000000000000000000000019e4ea16ae986dc4d3a7fd2ac010e0c0918630b1351fe5e262d529382439be1a64e70241526ebaecdc87e796a9e062001824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7abf3fae65765df0e2eb1d40f69a7f8d121f0df539f73b06553d72f9a4fba3f309f2400fab2dd6b59f81caff97f16b0000000000000000000000000000000019b5b7acc105206dc3d524ef370a206e12b6c6078d665d67dea8469e320e25ef269e2247be30e3375e7684189f160d290000000000000000000000000000000011f9a4962ac09651757023cd02f14db921f7b543490fa6f14986a305cb49e9742fb248f6129c2a69fa6c5a090bed27dd0000000000000000000000000000000003108ae6fce2efec5eacab28685328dd10f604afb9a8c55405b0b96c8281554ef77c581d9fd3cd37f4b8426b9551d1441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e713ad7da3a1bf9333fd9724fcc25ac118d183141bf20b11178e489e333f2cd407a6ac599ad9b3e17c3d551c9a308f0000000000000000000000000000000015f5d9aad0ce7b93eabdd99ea74c0d39faa75c9a8b69079348a024f7ba29a4565d13e5731a1912192bfd911c4928d97c000000000000000000000000000000000d1f06be6e153794147a6fd240c2186dbf29de2bdc10e843c73ccdb631806fbbf996200aa4124e6bb00f01ee54c07fda000000000000000000000000000000000fe4e889ba64e5d0b28e20c0f835c88898c8018d590cd2c9083a6eef2c44c72bd06ec000d8e12dda461e6642d03244591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199d59439fbefed56182f7c72f08a67c510e5483faa9372a27b6b709a2a143deb0aeb2934527c39883302eee4506671600000000000000000000000000000000025c38fa6880e79249f278293fbbae06f811ccbdfcedf1f4c5ac33fdbd185b8f14e17f64279c47d9c17eb02372d49b9b0000000000000000000000000000000000877683406bd00449bea64f3d7b0fbe47863693bf0dcd58645357e5a493a775f90c1bd7121adb48992d8c0b8a54711500000000000000000000000000000000016641a2f58e1b60e7a5af9c33811e2c6d7bf77332c72cd587e2bb5c2ba8ae5c3a629da7c20d8a7efeb7da3580c51d4d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e4ee5a9b7785bf824f2a867e45270b1c92b7515d67ca870cb09f51f3f91130ea5c1740e7edae7751aba755e21fbe22f0000000000000000000000000000000001eb233f7e8af97a5d2d956c678a343c76799e7ea0b9d4546bba675f6a1cb1f854a148f92e7816c7081983c4b9187825000000000000000000000000000000000e4e0005dda86fd5057c1ca922e742b1212bc20e561ceb02e70cd52d6ca97ffa1022e7df5781f0da2ab06a2b54ddaa9b0000000000000000000000000000000011187d5204e2487e84b854e058d56b6b2864d7e0a78e0f78db0442b61aaa5f9c5087278103c1bace2255cda048f036a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000167dfdba499597d14d17d2bf0b1c463f53d1b9549183ebf353f144932847fc55b538fa155693e7ac2afe94c2c3c025a0000000000000000000000000000000008c9b3fd35e0f8e77d837eb18cfd4082c1b5657a3f97f007c15812d85fd7656499304709a4aa2e3183806b85f52a76300000000000000000000000000000000007d6f70e1ce9ab6cbe48da75b18c5f159d9753eecd7afd3f61f709e02dd0cde863b1b5802484d1d60e646fee4d8e8365000000000000000000000000000000000ddc3359e379a407a56b530fef478fecfa764c94e70989fe2562f76fa2caba008c0d06647d87f4e4a34eeb7c52b54cd91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb008d43d5df1834599820aecb3adbed20938be01b19d25f828055e231e322a3c8604f64a5ae6c3e93cfe26ad8f59cf0000000000000000000000000000000003bf33c4f3748a204d0b636a9452ef6d37448296b9b26713cd079a7b4fb88869334ad884a8f39b0668cf251ee3a2840e000000000000000000000000000000000a093cea2de68ab15b76c12e1ca701ae13db4c66b511ebd5a282c92f81e2f381f205a74af9b7b6ba0bcc009669b976dc0000000000000000000000000000000003c92b8037398c39fe9e8e6929a400b892bdf09a6616fba001105eb7ff7bfc382e6ef86413195647be774e66d1675ad31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e4b145840c0ffa6ce587adfd9642789f715c167c2c894a4ef390f714d3bacebbcc371524d03787f84be4cb3e8cd32f00000000000000000000000000000000108d71dc01bf5f0d7c8575d11c295fde11703953207610c5bdf4df065a0dfe79cce16f788d72782930167217cb9c3db2000000000000000000000000000000000c8661755b04169f1716fa4c410930e5cdfb8fe2bedaa1dd1268e8e51e747712f9d9db9d57a405c599f334358940a6e500000000000000000000000000000000022e695541f6e113c5e771708cf5f9051964729ead98e2f50486cd9122fc2b388da566c983e10879a8bca3bf766e1f701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000000ca7421aabdfbec158dbe9de40c0eee5c15eef0c0ba847e01c23d6b6816ac651284c3b2d1b573365dde217878f5c770000000000000000000000000000000007b8f0976bdf1663a08839e44ca947d04903c8dac7eb3e0fe223e7c310124831fa84bdb29521c057e3a909ca494c1d950000000000000000000000000000000001718cab76151071956512b1c85ed0d6babd3cc368e4c889d35b90e3f0d0d27bc90849b1ee56614dd0b0500b4b74e4c90000000000000000000000000000000002189f491c3ca8f9f167c8fed28d96acb331f8dd516686d69eb46b2f611bb2c36b6cdeabdd4ba0b743bd7a4968a95bd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f691aed2190e5abfab56b10db02d1c7d39d19e529b927ff410556ddb20f3321e3e8cb09a4dcd0f8f1de67b0dbb1c580000000000000000000000000000000011a7c1b4ca1b2f9b8ce69e90d1ddcfa16f325bcd11f4310ded935d3989771bcd397a22d7e927e0a4ad028fb4e05264a5000000000000000000000000000000001835b6cf50add5f250c03e7cdd2e17a2989022a57a9589adcc8f1a502ec70cba5ce7aa16b0d1ca4c71c9a209ed8f5330000000000000000000000000000000000b7ed12db13b99378ad61732579a00d63ccc305c8caf3766fa8de7b0f1fd08b4437c65aadb6fd4710c4db5ddf4f879fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011bb8aa0b7f6e74b8b886e63574a1e8ad649e72bdd04685bbcf9ba5cd794f9cb27ffdc0e850996e4a56f03b0cb089d36000000000000000000000000000000000d791df192964ee957a0a2107f619bb350cb9187424068535b13053a8ecc6243a76dfcd89c9dffb64a8a1050670c5ff30000000000000000000000000000000004ddf84b683616043d4ed3cf45f2397c5d2716be4402fe47fae04418b0f7b6735fd3101cef4887e06c35884e1ad1e22e000000000000000000000000000000000ef37a06ea0e8059b4c87bb634e59aff4ae4c90f4f90ceb3956581519e8b339b01869763768655fddc66dec82b4dde281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091940c8fbaaab85ee618960bdf8cca22f9f0ebfdab2140c5246899271d794c01e830cf6e13b285767358bcdc54cad91000000000000000000000000000000000b070fc560a1b38d7b19c417d135635647c92593e14ff6bae7921c49e5bc6b58f158552722b55d79a2a37eb0e9cae703000000000000000000000000000000000842abc84325cd6a2e4a5cecacebf9afee586a0c5767d832f1608a70fd81a7bc875de0e3ba3652e883b64d417b1dce9c0000000000000000000000000000000016ee3c8e4f974c577e3498c916ed3fa67db4b38e4f4d7f085aa1d4b6f8ec28ea6f394e66b06206be546e90986199aa991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3744e80ca42a82a2f67f1e87a9e64dd7cb156abe1fdb8edbaa6ee352a9184677b3a432fe42eed9597200e800fb740b00000000000000000000000000000000141580dca3d93416e5d7a9c56a825c226a7d8b06149a0c9f2d7bb54c282acca9f216818b6876a8b6573c6e2fc42b238e0000000000000000000000000000000003b101cc769110e15c2e5462532437512d38cea9add3f02ae7865034f119d80a5b873d4954de57a6560dc477028e8b56000000000000000000000000000000000c50f90e4484559b89cd8d3f24458d6c4c28d26494a6b3e2a872f864719e255ae629f97a95ba39e0621f8d11820deeb51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011772ce4221bbfd558fe842057d26e84339b684670c6304c8a00e178d2ee971ac0db2d6d00ab0e57b03f5afd01fdfe4800000000000000000000000000000000052e3e9b96ec1dad52c8cdeb06cf676c8a386943397ecbb5b9bf0cbf14bddd6f6643e61badcb34fe2d9190526e7e63ba0000000000000000000000000000000017c1a98aa4fd85ab9f2880766d7967330378602af4e99bfe7f0a472c8e5b64f1d1e10324816a63c21f54c7547500aab7000000000000000000000000000000001411eb75df52a00d653dc3ba4cea6879aa468a52d3d84f30244db61f36c7b8f285fb4acdfa62e19db7fa80db4b74078d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f86d6a5df59f0b81e0c067f49e0c4b933aa3704e73ee6a047f53d71cabb5f8059a1d391c8af47cebca3e7a671943fa000000000000000000000000000000000f6144cd8b8a0f761528b1805486a3f8b1796dc44040933c71da3bea8e7c49c08d5f8380548a72ae39538b72ad5f409a0000000000000000000000000000000000a775637b985d7453093b89bcd9791745cd353c026d55d6be9d752e37fd4166224687049920b4e95040602f428cea23000000000000000000000000000000000b35cf8c4cbf2ace949b4f6b8273b3d8957c7381dd7cbe7505ef6e5d4e12646390cb4e628758bc0e137387d00c749d1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003aeb3ad5c88daed98557e6b827c2ead81cd643d51247b776b6e7bbfe2d745089f0d2d97134e04050b21cd205b2336b5000000000000000000000000000000000dc8f567c0a0a4ef1a7b66ad3cb18216499e24deabd420d96a1d445f79ffd37f0d412fa194743eaef4abee0c2705bd230000000000000000000000000000000011a84591a654739b6ac11e63c66bfe768feaa2a48d251ea11ce229d4d18b56d651483e5c6816de68ba08e08e8aa7a91c00000000000000000000000000000000038b16716e8e21ebb570fddf7b42c140d23c6e9f2f4028d414f72af0b49c64d8f913f05969d6f9a37abad2f3e4eee5b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084e88f229205eb8c9f3e2020aaa37d8eb19c9fca80867395d72a78b9b5695c0a8fa07d956e118df2662bd06d686acb300000000000000000000000000000000091481e29e3df01219e2cc9e145f59b42ed517b31586a98f52e3599d25d99e648d876bc12b9322d82f40be0f4817796f000000000000000000000000000000000a24efca5e420e68dcde12c1f99925cc3cae831da86ea6b9894921c02cd8c1bebf657b4953102d07ed15c1aecb823b600000000000000000000000000000000002772f947b555b98ac1313eca35f4104436504156a4165c7a651d67a9528752da72ab34fe0140109d4f3e2cf3e9344531824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000092156d28b4b7f9e76ea486f725ada3d7cd234a2b29e28900dcabe2540d4159215201b504b6e0c84658373b940a01752000000000000000000000000000000000953fc5f4344ea035a1de62de1aafda2971d35a173e857d2a879df5735a9380d184f381b2f4a7f4f1d0290829d0ded6c000000000000000000000000000000000cbad1e52595c079294b168ad5fb5843361f74803f45281eb269253cc1995a72c450c11616cfd7ae1f1f3eee8f2999dd00000000000000000000000000000000034ab533f905c25b9564b9f8518d28acc0f3dc6f4ae13710841fbaede1995703472becbf993203b190798b044b5a35d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bb2dd566af07f70409f5ed9342ab72699d80934324a202c8047ce2767ef9d73760322b503598aad157d2c749804576e0000000000000000000000000000000005e46bde0389840731f2dd19c56f5589a0e7bddade4316918ab9dbf47c9c7d56df36387194c65687a8c73bcfdaef740a0000000000000000000000000000000002e93b8e95cd264252407cc8d7a9f9a432b2850a6f5e261a86a3e6e1180d4147367a9b561d55b5bfdb6e3f2951f60b060000000000000000000000000000000012c0bed900b2160ce809e31bc4ad41f3c3c012adff07b6403d91237d3b3b4a126a2c21d56db02e44a3411409ccee4f321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000031fdf2d52db432b390f7001de96b5028767ce7098032fd4980ca480461168379cbcefbf482cde54ec7a134bdfe3669c0000000000000000000000000000000012184ea06b1911757ef4c6c8fe756374016db70f70da2a39cbc02edc4a6ada034f177611671f13085c15e716261ed87900000000000000000000000000000000049407d3f03a2fd531e4df27f628f7a75cbee7d731a72fc3fb2af1466ae070e0794eb15cba79c6d62ce82b5b3998449c000000000000000000000000000000000a534bd3d848d5675306b97016409872bd65729e4f2091c1ed5561183b7ced144f55e61e341d81d8fc9555f1dc784e9c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163c2bab8239f6ecad1e78801164c587a787fa2c9553d8572adadd9bceff86c5b2b5a52cc90c1c7a8a7aa99ad83a57110000000000000000000000000000000010fca397f41a8252de1c737358627c74a85c3a3090032fa7c7d4d3a045031bd1f4af58c8260bd9d64da9fcc86dfd5fff000000000000000000000000000000000a28170ee4277ae166ccb2fb0cd935b9b746025e19eb7ee640c454ae8694122bb22baf8645e302b8d6b20e5810f99fce0000000000000000000000000000000012e6891d623465229cdbe20bc680cd26193b020cde1e52b1f4467ce31e91ca9268906179290af97940106a78205f41b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5b9c2f304773af73719ed3f9605c7e2a0d4607985c090b4fed44147f22ea3d0e41b19bf42b50796f6b4c05512262d8000000000000000000000000000000000438b1726f06d701907646636cd311c9ed161270ac03be594c2165ccaccbde1cb2c586733e04fba7b27dfa45a7e06399000000000000000000000000000000000d3d74b40628fc547623a2eb4b9585eaaf3d4ab01dfaf5a894f06f9be9e6cda988fe9960a749d6d7446d2ea95a2602ef00000000000000000000000000000000171cab72de82faa190a8f3244549ac5a7540e3b510c8b3ef3b899b9e2191f01aa33b0d8af5e6b84b85f373c4d614e1e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dec8c78dbf2432224a94f7f75871da720084d90473baa95aac2f848bd67110103d21705400b685b551c60d58530a0b000000000000000000000000000000000e9761b36aac6781c3b903668c4cd13bded5af2cae8d951dbb4175b7de4b35409ee20e38bc136aff0feeeffd629873350000000000000000000000000000000011ee5ffc4cc7906fdef9efb2c8fb5695149c36dd0d8c2daa44c42fbade09db3044d4b1cfd62c4144c11a3e4a16072a95000000000000000000000000000000000c4eb5e6a09e4fb485ea04804fa1d62cf503aded33a0e54aab13f79b0a5b8151f25bd03bebf9046267fb3e809e2d9de71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f8b80688f04ac8b498a19a9ff1d3087887d7238b9f82edcf578f408888a7eb1f83c587048174f38069ed105e434d3d000000000000000000000000000000000f86c4654eb6c9e9156b9e573f6b4eeee5d2a24d929a439ad7aaadb72f6de7bdc6b339d03b5a5eb26e1384c318646d3a000000000000000000000000000000000fffb308caff3afb10d956ea31e4680a82ebc147e3ebbbdeb7ad4f6f502fa5ddf03fb47018b966b37bac6754892ea429000000000000000000000000000000000073b1f7330c6414059897e9a316afcb77d6bdff4e5c4c460e09f2a3d4bbea09c81ab4902429afc148c96996e13c51d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c9b65bdb6b282e84d040df38f0df859ea29963f0cafea770e96f48d57203a4f8f626d58e49fa8560a2cfaf0d139a850000000000000000000000000000000018177d3882f4dcb9364db6815a9029f22db7ae4494994ca047d4614c3c9bb217cae7942fae17478ab393b4a909ea4220000000000000000000000000000000000b5048748f40aa1c7b025b9315acba77d8177fe9a358db033d0d38ea27f3255f3a0f560262097246a361cab4626c00400000000000000000000000000000000002f0ca0b2536b02cf0aa1dc53285eb690fb5e1b29d166b7dfb6ff9dbdba460207a051d77a9df602c6afeb5389d436b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000940ec5a6666dc5f885aa3bf8eb285e7c2c8695acfeaf52c5a163d84b665be9e4fdcd4200859c8830c5bbd750ba9ed20000000000000000000000000000000008feec47df6be1f826a2a498c08af3b6abe88dd5de90c9971d62b618cd6df3d0f3aed80ed70f097c697cb9981d70a1f0000000000000000000000000000000000b83bb05ce07dd177a2e8781b964d24d45321a42dce5e388806610a9c2742cc57f4656ae91871d32b56143dd224ec2b8000000000000000000000000000000000da578dd312e865aa4ec90912332246da48d0a3a9c01b07726cb10459af6c7519389ac317e33cd672e2e73866e0207ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010da73562a40b166d7bc485e50e9485c145298120f7156b77fe42d4d118081c86af972c732775148066c55b4167c4d9b000000000000000000000000000000001331cbe4556103f9ebbde20afd9ede0fb4bfd8a13198d7459b3671cd32b68a9e848f899e3f084358868e79ecb166d54e000000000000000000000000000000000eb100445185dbcc81e5a23836b3210c2fa94dd433d9e018c9540942c2a8662dffd75a10dc182fbce54e5410449c642e000000000000000000000000000000000ec9712a33ecb529b6a16d1507c960f808b3b0df141862282056315c2485ef659c4a97c5ed8af3469bb023e9ac6015841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000150de26ea0f5511e4715b0afee411061e64e547efe1aa9b4401db91d0869441cba1f8742878f8c3820574d2cfc22da51000000000000000000000000000000000971b6df1a2f025fd89343f3e678220ddfc8231884c7cc8b5df2a906c412a4a09fdbc97c66d2a1ef24ef0f1511067b5a0000000000000000000000000000000017ef55e0f0789f08f2eaaa2e71617e77df7754ae4a21a83d41ffb07109a4ab44d35d919a53038ee843b5813c91803976000000000000000000000000000000000ea85a8c74c55a5bfca9629752f1bf4772b48f3bff8e8efec5515b5d8e922e9b8639654a2af4352bac599c888a59b7b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b9f81fc55e94af896b5ab0ce8cca90a651fabd55a21721799513e2c34fc9ac491a5d847c1bf12a5f0a2930057ed1860000000000000000000000000000000013abefaf0c2929c6c27168231787035f9ce76bdddf80630926f4e755e80374043a7a7ad5ff44c38861996c026085392700000000000000000000000000000000000f72ef4938bd4701f8d387683eb0623e48b62879378fbfd6aad8e5746cdbb8a3338a5e1bca4f6e3727a9394062f25c000000000000000000000000000000001603d0e04770fa76924a3e7d160870fd541822d9f331697a25a27df4d5fb6220c6d2a459cc205de2d078c055628fdbe61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001bd8867348015794ea44cb8953ca0f03e6e1366be7658a045dd00726e77f66ecbe9be004cbc31553c456f07d9cd80010000000000000000000000000000000005cf9ac85c32d9c7de5c9608f00e37784c1de818958ea2cb490c9faff1773691b25558e6679a06db02b2b04cba0030fa0000000000000000000000000000000017e3debad1a3a0d3213e2cae83772311301930ff279d8f6273a6a2072a82acf2e8543e0c1978b9e9d4915ec0b1d81882000000000000000000000000000000000761937005c8dd98780f769fa5d07612db581d1db7b7257b1abfcadc72a1f7a1577cfa6527835a3f68c5205aebf7027c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da361bb523ece518e0df4c3b81c6d250e1aad8fc5517cd044925a4a656068e55015fff6588595202833a9938a5f5b5000000000000000000000000000000000e7c0cc6e112dd78b5ab418471eb472185ad9df04222b04fde09454222a3ee909d32551c886630fee1b1c96a33c06e26000000000000000000000000000000000945bd09e309cb8f11de66cea612eea8e924388f06050153f9d57b1d4942780fb2e610e0b3729b1199d55a3f9cb5ebb00000000000000000000000000000000018ae9bf5c59dbf687b347765a94789a4764b75ba4c8837e553aa77f7ea943ffe2d46566b29024fd07015abcca4facad41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f7fa3c0cc4af753705d0ab71728e068370fe017449dbcf72bce54e00a2b8ed7fbb9876736a86f522a6dde40bbb626df00000000000000000000000000000000116a9fbdda1d9795e276f2b3fd7fdc302acdfaa1f25b6e53807bb8fb434469b140413f571b90b410102d09339fb6170000000000000000000000000000000000126de033c999e7da01310dc102af4ffa664b254be3038620b1dc6454527297a5d1067c97350b757d2651d48cd659aef100000000000000000000000000000000057460ec73aa03f4b3a7d23764510f8efbe156c88123166c2b2af08acc600343d344d3cdf692fa5c8f90dd380fad993c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014eca02bb0b4009ce30c523a2f929c9d13a8b6bf2b0dc38a75944af5a646b99d131230f4e9475282b0c5dc8485dfeed10000000000000000000000000000000008cc789fd7f28111623ef1350d0e3d7c578bd1fb226d163ad79a623baec0136e82969c8ac0c1cb9dd3436e85b65d650b0000000000000000000000000000000019306443ff9b484afc5f0eb02a848daccbbfac3564a27c1eeb226897d12d49a1ffbd1c275fb15e57658b2e2fa1f5eb50000000000000000000000000000000000e9052d5cc62bbe264fb7a628d5aa761530bfc69b02955840233bd0ffa1550ebd22e81e06ffd97c2043fca37c38800ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018697d54dd19ff8efc61052448373ad96e1c3016c8e69c516d8ea0340c963d39c16f3d1ebc9b9b7c308e3a2cd28797a90000000000000000000000000000000009e37a8aa4c69ca7d3de7137eb67878b8a6a0c82a61025b45ea2993ecd8bf5c37c8c700d353a91eac4116f3ce7560703000000000000000000000000000000000946c6c8e0b5cb80a65254f0e653dc711fd0baa18e1a1fe7682a43f97fb8b6d80a52fccbb5c15e52bd46b3cade5e2d74000000000000000000000000000000000d054b0ec40acf9e605c1822415e1e5f6c10c8428312d951c266ed2c2804e0e4da985c45dc36fd542b1c3a15a60d947f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c2a641fa9b78e5bc887705f2e2cb02f37245f4fe95846cecde02d8d6511a78213b7232bcebab1454d1dc8333076a99000000000000000000000000000000000e6c897ea2ca9047224c0951ae48aac6f30168358ead33ff7efdca9181b794d36e499ff039c553a8796aeea087213c240000000000000000000000000000000012fa557346caf660f97d9e7719a1daa5061e28b3b86ca0e35accd7dba7ca1f2b1746936fe4c51158deb1f1193b0d7d6a0000000000000000000000000000000017a5ec25b331b697d82b43ca750f363fa7d9c8149856a730f4d4055c96e880b65106bcbf9e2a0eea4ba291752f2b17e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000126d72e1958aa856cdb47f3264f8c252b212909b007199a1434dd4fc6614ac9ef676691e483e5500a97a315c5db754bc000000000000000000000000000000000f45331f74ce5a1f998dd825e7ec767d18deeb5ee0f0e5858625e1201252d6ba437989497ac832f8f91ec9f139bd3acb00000000000000000000000000000000051679243271e84152af1ef98952ab27763623c419eb66e39f7caf97042018b69b201954e81a5332a8b822fd39c11cdb00000000000000000000000000000000166bb7976f8305ac908b6ff37a1b6049de9657f573d12664f2fa3b50f2dc85f12b7e57c6f80cef1127ad59a155e1ba631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000196e0bda2ce1bb046a3affbc5e6ad8d40e42117e1e0bb75c2c386fc4b3413d69cee50e2804f1f225daa6e527f20eecea000000000000000000000000000000000beafcdb3c675e06b9df910791bced1a866a11fca019c8e9339e6380289c249449dbc3bbb1670e2c4e27aee1629050f2000000000000000000000000000000000bb412259ff260c7fe0e79eda3fc64d1ed8c5dc94f47b6cb391ec8e138d82bd0c4f3fef8e3134d3f417bbaa6173404420000000000000000000000000000000018c8f8b4e94c1bfa527f7b3155c518a5a8534706b485def7cda06ef930c359ca6074ddea0f60fd7c83903a187ff36cac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000010b3aa26397b4d778824f763d1e2894963e4d71190fee9a07054698d94d78450eed5a26d1719acad128fe4d72be3ba7000000000000000000000000000000000a50c2f13d358f620d31231cfe1cd685ee1d2f0876e85fc564eb8fd5543fbe79d883f169eb64303cd27cacff816d441c000000000000000000000000000000000ccd06265501e021a5a5633390ffa7b6c74e5483447effbe86f2bec06ecbcf3f01e8adf70328ff11e5e778551023e4b900000000000000000000000000000000176d55d2d3c689128c467e24a48828c1c457a482bbf1030d1f415f57088680a292a9509f008db74c333aa9d7fd811c7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5bf446fca039a6c06654ade4cd9a47540188626a8cb19995ace029fb5fed385d3a19eb58415dd5e6573008129c1e570000000000000000000000000000000004ad16ad06bf0b83ede4d6c6c93c406bc8f041aea31a931bec4c15524e9ef5b03216565090618f14f73fa63556582d62000000000000000000000000000000000d0e796ee8165ffee653a593d28303572f975f11ea96c314f7513b79c9f0d0dc2383f54ff92070b5642fcbe61c618c210000000000000000000000000000000003b627fe739426d01ee672d2af287f6e227c9bc312f166069d7097b3ea59c12be548c247c9c2a7141c681e7e4db254861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a97e79631fcd3a2eda627492c3629974979fa35c92108cd20d8ca194299e94d536621e05a4cafca52843e11fa7f7c55000000000000000000000000000000000b67e4a00422cd2f386372e1093eaf1e0c6ab61fcb866bc74e36ed47cd11135b7b0fda1669323948f010a4864e7a2804000000000000000000000000000000000cc8b392227f93591a7d5d4e20dc58b123986d235f25330f4c15ac72f38285c51cb3c05e8cbe18c000f5a30afd670a1400000000000000000000000000000000125e7b769bd524e06d8d4bc169d42ab5907acbc3964f82ad5fc46653d8843b3b9b6c78f98fc0ee2faf309f1db66a6a201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019d26ac13ced53564543bd779c12ed59fd67c4ff04680e8c33ca350b26c55110f7e892d3ba5ac3b94a2ac69aab1a22070000000000000000000000000000000003ce5391468d3cd15a0112f2a85e3e695259fd621adedabcb31e886b276a8c1ea270f694c7fb743c5b897c3e3935b2f30000000000000000000000000000000008e2e8e27088aba2d302adb40e1dbf743491892b2a7d35d3e3fcacffe0a28f53426a071c67d9dea14619e25be07c4397000000000000000000000000000000000dcdeedc0f2dd3e7c751685cb36cf8bb0180b3680ecac5574c01f7f391f29c65f92061a9156e2fd436d00df6be2c12171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000373a92f7c50d6a1759eb0ad307a659d7b63a6fd62a7565c438c298e7aac19939a84d500402a0116b184f52e28102ef00000000000000000000000000000000019b69882700f174ef06bef64ca3c9a350e453af1055fc75c97f4d65872c2d74966cacaefdb83093c204112a03f270cb800000000000000000000000000000000104069b74e662c9cbc4fd31dd730904db523826816d6a90c872e3f4e85284a0fa0fb217d9f9557d9ed032a32d94b262d000000000000000000000000000000000974a4dcf5bef80dec5bbac6ea326d7fe1611c83f07247935b98033d901dcb54359cc8a54ee4c2b75728234d1e285a651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001e9ec8cd073e00cb57852f86bec0fd237ce3800d1089677e7c222b15492e7657436157943b833ecaadfb4e2ac0b325c000000000000000000000000000000000ebe09b93ffa3883dd9b1dc1a2252d46bbfc760e2210dcc9305809ec4d3a631c4673fe73a0100b0df94c0153ed723d2d000000000000000000000000000000000cb36d51b2b3542d0e0abb586e3f648bff887bf3f167ae90663bc7b888c03739b87b12606cef5904b224f68dec6aedf300000000000000000000000000000000110514f7a63ec805e4b937683b367b5afc15581a221051892090eb0ecd33b58bd25540cf057fd5e54d939cdd9d51f53c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000113f5ce01b869b9a2d6c4116d7d9e6802ae56e4cabd7e0541f7d7cb02bbd23e138ede176dd23b7652cafb323321a3d46000000000000000000000000000000001711be3d5d9ee00eb15d8de547ae85984f99fe28db895808c7df12f162f6dd2d49ef4287d7a95e328ba1931aa899635d00000000000000000000000000000000116555db0c03b92375f109c8632f4f32de6d75c485e116bdb7a9c6cb88bd743aa44bc570f8cea8a33457d1d467f8c5900000000000000000000000000000000013e83e6af5363b65d1a9c82693dfe3f12b071add3effd51767313bac84dfeef005227291418912bdf543e605421feb631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c4ec1f9ff2d1e0e3b66f54e026c3ad9850d97bbe9493bdfc66df26433344ee13ab99a6895e584f0805097b085a440e0000000000000000000000000000000005183f6c272feaef68d07a40084da61bb030ccc4fd1561777072e6805f81e7b426845a45b2b0d2ffea223f692dde6db800000000000000000000000000000000006347cb4d58be7b18f6415acec86bd873125c00fb1f3c9ad721a957a949cac96648fad4e3cc2431f436688faf4445e700000000000000000000000000000000097f1ea1e3c1f353ef757681d37cb0582adb5510359424242a4378ded03c753932564f9b8b094af629bd723dccf5ac031824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c769bda6ab1dde0088ba6a98213caced1434fe403f0f15659f57badc90c22ee12924e0cbff3b81bc83d721bf258a84f000000000000000000000000000000000add028dfdb6748a61a9b210b257c8971c2426d894cfde0bdccf2493ae7109139ccbdb22f4490b710b4fa526b82d83e0000000000000000000000000000000000dd69b5cd7dceace2b44b18b1801f1af2f728ccd6a04c34863ac770496bd3c769b94d1a97ba31120c2704c2fb765917200000000000000000000000000000000070cd27fd2bab7357664fef90d8abc1834b373fdbac7ba88d2d23908cddfdc05fc971ffe81eb0de3c7931d2c1f0032f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bd4131619dcd8977b9b7119124bd98735f9ed0a10161ae8990e2ef910da3643408505fdab947d396e63c8ff4791a9380000000000000000000000000000000004441ffc91cab39cb77baedac7656d8954a0887c441280d519363fad626d5ac039218af83d9152ba0335192c3b3c402e0000000000000000000000000000000019cb61cdcb0d4721d2642c27790cb1bff61d606651bf03461578b6101ecf1ccf9f816fd08d22cb780333270397a82990000000000000000000000000000000000e3944c093ffe8b3a063e9625ae99aac83e1bcdd500188525496f2ce0d572bcf138d9d4e53fbffa17cc869580d446f0c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f184b25423d67d60240e51f36f30d44a6edafa6e2aadd0d64c7e408a69efdce29b438401c71a318d23b8f475e287d3b000000000000000000000000000000000c54588a5ac8156cf0a602afea61af59ff4d1129566626c30515e4aeb27ec62ec94c91b14df463d0fb2bd2c7974ab51500000000000000000000000000000000026b8192202435d1df1f7a08f21ee7da8c4364dbba08c6d2411960bc4c3d5c4d934f4f695ed49eaaed0de8bdd39c7df4000000000000000000000000000000001745af385c9faa4d56ed2eea7819b168a902e57079d3e75af09625f24deb03a6898e674b63dca1439c68a5bfa090278e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000327e054f3a9b7a34de5b79c3f4474a123888e963d5293be93acc433a915a45318cc7b0b06196feacffb7c329d0a6bfc000000000000000000000000000000000f425b2c22ed73646036b45b90fab7852e7dbed9b2934c0ee762f92b0fa26b24e2ee3cc78c10b472c71ca2ce45fb397e0000000000000000000000000000000006379217cd6376b7da437913bd788585c99e4d8e9b3e2de36647d46ce9a8e19291c8fe016bdb4a86fa53837a82de83f5000000000000000000000000000000000daefe609ca2f03290bf86471a120a952bb6a76e3a19c50a334fb754fa470c3f269179a66d8025f24ceabafe5b8205ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d54937a1465c1a1f6cdcc3c3424e074cb25b5b8d6ce979382cd5361cc5965c6c8375cb0f59ccccff7d4888d6a6a4f530000000000000000000000000000000017e6152e041d405eab7e7722cebdae7121f8ddb3f0336f67c8cbb37823d377d3d90a3c40615d4707afebbdff78f8f3a70000000000000000000000000000000008fea85099a644721792c55ac1ed6f91967e0b6b8e671930fe4e76fa4a99c5a935fba364650d805797892bd24ea50b6f000000000000000000000000000000000b67a95dd629b70a6b50c845fc72d1efc078fd973bcd0c9a90e1dc5fad6c1aed4c696c8c2dd900ee45377416aad7e15b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fa3c17e8f1bf28d173b0401415093b216e3c0f915f102e1f6459e93837d1beb9510003564b6d6e94e8f1dd9275b51ad000000000000000000000000000000001106ce5694629e4e5cadde964513b211b5545099adee788a6bec3c9f647e0c08daa3c403e4f2c75da49e224438c6017600000000000000000000000000000000021a705f75ee9a4e77205e58219459562c555d62ebb6a28a51cc4b1ea8dd933e551f514d4e477c89ab3a7b7e33622ee60000000000000000000000000000000005eeb353ba43b1dd2b7d088f29e50138591b86346c18939b721f171a7f9a41c4957750f352ac7e0bf3f35668bec6c6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192929f7ed8a0e7845fdc1b8c4a3c6eb8d1cc70a3134ceba27966be7c25c03b9c413963cfdf356afbb0d0284555c700100000000000000000000000000000000076ca0b158f3ae3923bc3360b7707c5575dd3e9a280301545d3a03b2037812bf58d40a5004b4aeaf27d2c9359cf45e45000000000000000000000000000000000bc6a5881954ece3fb95987c6f7ff60fa3e8fad078c2b7a808ede61aa9844f7fdd161d974edcf7c38d0a6d704d88dc9b0000000000000000000000000000000006ab9f6b230097467edb714632a0e48d331c1e6afaa503e18cc1919683f5885436ef97fc7ee84ab71bd44d114311858e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000165d84fe712cb94c9ba14eb23f925e229fafd759d25e7aad2f52ed54d3077981d9144d9641aeaa9a44e1ea8db0ff9f4000000000000000000000000000000000255c9772ab035d5d3ee8942d9b67b0e5c0e5a910775904ca18802ec11e8b1e7042db099240de5432b98a3a1a65f6629000000000000000000000000000000000ea9fe87af77a793811332d2745a4cfc21a089e9175286336717b303330710c27c5296e707a3623572025650e26aabbe0000000000000000000000000000000005b5cf552b9305f669189e66857a62d110b948f82c12e671893ce52d465e21594720c85c5feb215d3d1730d6aa54db421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b9f0db7fd8fc530cd276b1e088e103661cd92590eb1941d1cc529af9ea092721ce3d77e9c23919d64df36c657e0cd9f000000000000000000000000000000000bd0fa7923ef37e2b8ab757f4fc02b0f03ad3bd911ebe2c783d26add27664d997b97526323bae10a509d2a0bc6535fa400000000000000000000000000000000198fb717c39b731638009a32fd38add77143805e837ffcf610b535b0583de03884e09e766c162faf2ddfc800b9c791b900000000000000000000000000000000114b4c2187370bd02168ad24b6af24c81254c7dbf27b177f9664f38cbf0c6cf40d675c186c2d34838e0410d47cc674d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021425276188fa1b56ee332b8653e29ae12ede33627fad4b11c0b7baec66c4ccc766b7d870adbe700b1b9d6ab06bfd130000000000000000000000000000000012c2d581b49c4eecee4e2bc3a89d89fc044c8270b4103e3da503721c971be4c63604fbcf2c4e4f67385b59d2a058c0cb000000000000000000000000000000000ee5044e6e406c64212d4c85aecd60db6dfaa5d9d87e6a4369441c08161cb9d130a56c1eb4fccb7b0165f2d6921613a60000000000000000000000000000000014d2aa6bc7ac017f5648a9c6d84ebbe60d4903ff78beb0d5cf38cfb86b8c7a20d39c56c3194e95e5f94b745cfed169cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000a3890c341086df2f87f53061c1a175f6f712ece1a1d4f3e9e768842309ea10a3c71e2b68ef6c27ee02cfda6f7f33340000000000000000000000000000000019743449fc44aaced93e1ba066f77af00a1f3f764e1f501826f6f8dc6917214b9ab8a68629adbef3ea5f4afd3ce1edfe00000000000000000000000000000000136269fb7c6cebf84dd01d4f6cb0cf56e005b8d8b900c63020d0a2f357968cfa32d9b823b5f5de6e59eeb2f486ea4c400000000000000000000000000000000016d53562e5f0a7dae599c41df3daab457bf3dbb67350022ead1be23daf09283a49472c950026809560c09686433c31541824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001976747f197c2e15b83adc7abade6d7187e911a8674a692bf3588e72e0a446c043f0050d57ca6e24a0f7a19e2c4b1d7f000000000000000000000000000000001919667dfb7babb095e40a42f09ce73d0c8d246eda076196aefcff76268f90bf3fd5b5e362c8375716acfdd1b82dab930000000000000000000000000000000001aff2e3f1acebca71afa78544ad0ec3a63aebe44672db04c857afa15f3e9a2c3b0742e2d406c3d34162d86eab0a7b86000000000000000000000000000000000c50d66141e319dbd611b1663a34f883f778b165f4da579ad9f9cf631cb370870fe8a9edc60a2d3af26eccaa7d10d77d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e15f6c0e14710eaa9d44a21350f25658f7e2f2e12264c6d7c4d079122884ea49eea89b9add556424638ddb2a1bdd0560000000000000000000000000000000010003ebe432571abdb309876926cf6146db05829387ec491149e25fda2c71a45e518477a5e448b4fc720789e0df64cce0000000000000000000000000000000007ce4015d8edfd07cd0b452d64d62a919f7ddac90fae662d64b0224e80bf4025c266a4223d4f98e547af19c36b458410000000000000000000000000000000000d03dbc43f133030a837f198e650f18eb8c20c356f8af680b38225c88bdf8f98a25da98d1ccac1f1d11ffaf131ce8dae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079d76a0933c00df908576f73c529e9061b4afb00ef6a60ebdf23c72824f610122240bbdc2d0de1bdcf38d6197d7ad7100000000000000000000000000000000000616c836b2a78f41c772c05499d29a549d395bd40e2d24f058c8bf9bce2f10e9643b1196f0735da1eb5989ff1884fb0000000000000000000000000000000009216db1fc57889c35bbd921d27ab606ac667d1e5d0cfdf625f5ec59fa0059111d294435f46694b7656c6b1f732de5e400000000000000000000000000000000184d5a9bffaec172d01e9b3dbbf1c8aa523193b2aa18994e35b54d59a3e9c9847d64d1c03a95d4437d6a21b980a4ba491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001a7f9828141de108ba3adb7150a8cf3245dd75e503faba4d09fa9cd4df374478061eee436a13e64a8e9977ada53e28d0000000000000000000000000000000004efbaa96b16996db9838ebeffe831a6797b81712824530df24f79ea25b505fbcabe45994c3395481f822ada6d71c0f600000000000000000000000000000000189e7687248a102d4b6d81856a27f0a3badfd2304bcacb38d8001a7fcbbe90b5d8b19250ab307c4880af87de9c49167d000000000000000000000000000000000b679d584021f7d4ed51837b2d5107fff02a7bd852bd3ea69325728804ca362c332016b6d641175bbedfbe345c138f111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001e1dca7a05a4a76ecce5d48c66eea15232be0bea17c111fee1972e5a466b7003f3930669898de107687a5da6637923000000000000000000000000000000000aeaa77666b0b07dacb2d020378406d42274e2b2679c5fb8277633165b001cecd79f16dbb642f322982dc0a82706ba870000000000000000000000000000000002d8ea6580e039e9299327ad3525847da3bc95571d0038fdc41cf39cd9b4834357704e51f66ade07527d0ed8d2406b70000000000000000000000000000000000745c6d9dcb5c6709f3c678956b1e837308973bf6ab658a9e22ef82e0191cfdab536542035a41e6ce027be69975322b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ae4575214289f7e25d872aa1bdc8ec68a2e3a891226eafefaaca65ff66823417cb9fb1d940b2683ac2ce1e92569528d000000000000000000000000000000001079f904cafdf79694880ff13eda57d6b1bc35a3b420a7f65fc377fc6adf6b61b44e919bd70cb7dd59cde9720779406b0000000000000000000000000000000012508f92554ad575f493728a6b71813a43ea2ae3ee0a1888afd9eeec7553d8cef7bebcd880a178724e2584aa0c9180c50000000000000000000000000000000018f4b6f2564aed7a9a8842a039fb3d3ea51c9a158be8bce308221e27841d8793a18e00d8dfe0630f4cfc9ff5cef763951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000011ad3252b8f513e1685847fbf70d6cd24812934c2bf36778676631735ad2663c0df2cae0a11716b4230846040add780000000000000000000000000000000018fa816185a8b2f46279805adaf67670ea286404b7eebcf1f67cc2f3dfb2a5f746ff4a24fe343d311d6c383e55b44630000000000000000000000000000000000d4acc195a7ec99b707300d7c1a2615692660e0ea2fc619544e4ee022d8fbffcfea13400fe79f91271121c50347de42a000000000000000000000000000000001115fc5429cb3cbf6adc2c0405a865a9d3ea43b9a2de331c22cabb90a68bd6a0d07026eff4b76f9165f945dcc31f894f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149d919957d288550f8485a7388bdda9fea3bf2d184babd40f37091f6a7c75e2fb8f976bc5c18c9b674aa8fbb035cddb00000000000000000000000000000000008c1a688011da56db1a1f4b88a70ec4a6f1f8e6926a4af7a83a8c0a852c89778bd8a2e6ee87d1f8187597a2e0b5811c000000000000000000000000000000000ffb978b9d2936b159688dfbcbb49f04033e0e4682646d3f4d9aee28b93fada76c7a9c5a68eed4d06c03fd4758e42c970000000000000000000000000000000006f409ba8ebe146ab8472157abfb8888dee0386922120ba93593fe316cc28fc4d88aea859baa20f39d499bdf44e676cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ff23917b604fc34c1c704d708c6e86a15f702e2e867cd6092e8ea5f55282664687ba844c1f626860da9294a2b9ec4e300000000000000000000000000000000021eaa431f7de8ffe98f2c844d96f9e32b56da4f7bcd49778a222517b42fc64cbf231b02db851e74cfefd48cf8e98cc900000000000000000000000000000000120d7bb19660e13b544e0306a3977bb97287803a10599ee735e186f1eba2ba234c51e47bce279b0be30b23fca14ea870000000000000000000000000000000001961cd1f54b036de3b1c82adc0191174e232914cbb9841a872bd28515a409783366c64876e5ebe3237d39eae049fdd7c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004172e98cd16572aa4f2456992a3673c6a9cc9205bee4b841f9db84f77eab11b6c4e0b0df92d95fc7e6fdaa88042d6e6000000000000000000000000000000001580fe0cb278d27f18c198d419ca66b3366e893e1ad3f473ee75be521c85bc6e657c2c3164c1cc79add257aa798b3911000000000000000000000000000000000e9c31620c99a6dfcf65f8cce427cb2aad8c500d7ebee93197bfed0b5b487b23d3af36766ddcfd010c49f80ce882fd480000000000000000000000000000000015428c05d02145a347a189ee7e0220b87ef2f00b93886745d41e58a1df055d927acd1d08f10b1985d1304135b862cbfd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012902581e021c0e7b0146a289b35a379594b5506e769c4285a1b1daabdbf52722c5c7532a28e37e2b1e290feb58a866d0000000000000000000000000000000014d281316e2f4cd09423cd54dd62394bce7c91e313f1f0d91c6414de1aad79547532e8ff34d3d964a47f5f1dbbaa573c0000000000000000000000000000000015865130170cc3528a349836f6a4160ee4f868c1253638d4cba61734338a5daab4cf7178531a61b890ff60344c592eb500000000000000000000000000000000128ec1401cac058f19dd22d0436db7fbaa6bbdfb4b986da671ae82aff51c65a5dc2ab9789bf6334838413df4414439e91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c4dda0cd3c81cb10f50fdbf35c84ad2bfb5be5d45e27204b4e2f9d727a1b14080d0958430aaeb69f6c0bf9088bc820c00000000000000000000000000000000111c35a76597ba93de6708c49e2cf0b98602d3ae13c81d1fac0c5a8b1f4e9350d710585f68ce1d30f15bdd2126b20b8f000000000000000000000000000000000b4f05eba6908ed036156f69fb0efb5556ba90a9944e52781a8a4a01911bed0ef641d2e41443f33223c066be00b168c100000000000000000000000000000000006c6c97c53f8613abeb4136c5f3f38580e4c45494ae311ff6f1279e3c8881ce4e4bd3a735533b596c56fb7ce1ad1b3b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cbf050bee1f9a6762990de0296f3e779e82092e2341f30886e316520facce215b8cab9f0ea1eb5bfb99ba9f37b16d2d000000000000000000000000000000001725ddd8f5076e99fa06001e3a84ebe4522ffc36aa925a1af31c3f6933161ddf2cd43f63b185b5eb30fa0000f914502100000000000000000000000000000000176b8c74d77b443af759ab5a1e949c01de483c564fc8bdc36184d6796900c2c5d039744f17de8569df941f065165f0e8000000000000000000000000000000000dd6d733dda7cab83e27611941a7234ff8b68bd97f61b9437eec8a63fcaa4e48f3b484f4f60bac232e794bc9c8a6742d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a123f96417b3678a8a8c84952f6e98faa6615b041a633e7e7ca995cc52e749267c038047762c0fa7f54419ab590e8e0000000000000000000000000000000000807b8d1633d8cd1619d6dee02c08fc8f23fa4893830cfda32ec6b2f9367c18006b7d3d797c0a7385e70a454b1027e5f000000000000000000000000000000000dfa56c5d81fdaf2abf8f82512679858dcd8dd0ca0f142e847746e45a63495b4d33431892bd0e638a5be701ed043190d0000000000000000000000000000000005b2ef1fbebfa15051bf048f65b851e88ac94a5450b7b9a600eb7422a71ba5bd2f67bd727982f4e214ed128f5c4179c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005103ed736439271cbb7cb0372b455998c99b48915616ddbc9fa396e05dbb0dacbe27a2ddd2eadba3ca352dc40a765d7000000000000000000000000000000000d1de628cb79193e939d9a18f0e947f31ea00b5b2ac50dc1827ea41f6f134a59590d72e7cc43c6c17eda264287871bd8000000000000000000000000000000000adfae49d9ae730976b107a54b6d79bf37bd6d418d774a3898b615dfe6f8154ba9e1544f7eebc9fa4094bcdd7677c90000000000000000000000000000000000048ddcc907311c3130ea2cac650e8eb956959d52177f58d3ac96b294c27ed112906fe927291222295ba676e578e380cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000214cfe61508ab939b4a1f34fb795ce58380e4bca74d77b485444ab5b741d4395a78ed9b6b4c00284d6a212664c14e7e0000000000000000000000000000000015b1817974f3da7d3280dd96da5a0fe9a924cce513ebe4c84f80880d23629f1d3720661d4d2178665521163938a55901000000000000000000000000000000001325e02e5e3e57ffd0dfce2f26b70aaaddacce46c91ce6be1bede883166b0441302201e71d1f5a3758dc8f72627dc1ee0000000000000000000000000000000007cd7cf1b798c28e3b09882bef631bae76ce2a3b25e3d7d9b13e5cdfa8c6de4c8832e5524f59549f980a70c2ebf507771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ab0f16219535e39fd396a73af90d105679a8c384ece811c0c8d79cdf4a13141a1517d2223ab64c61b154eb11ceade0f0000000000000000000000000000000018444410033fe9496a0d27c5d82d2769fad952166adcab12b2b026e9d2fa4b1fc363a2e745cc1826e3397822900507d5000000000000000000000000000000000bb0349a8c0b0f6169df3c7efa546bb71b494e95e184fe6855fa4fc2aab5db198cab92517df33e1ea0cc54936c35a11f0000000000000000000000000000000019cad998ee871e6db8995d9e4a848050efe3fe8193b616b4355d5f89f74529f0fe3d7bd8a894deef85252dc2390079861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000071ecdc0b72d9a59b7f5c60b8d331780ce2010295e0f3a8069b75291cd9acfb6729e59736c17628d1f61ee893d1a34fe000000000000000000000000000000000e736b51b42e547b44a0d907fec6b4ff7101d3233a4f4c2190ad4d3cef61309b060cd236b0aa6f81cad80c4e987632f10000000000000000000000000000000005fabbb294c92e9657c998b2c785ab29e2b34e928a5db2b5ac637980d36b173da36841fa4b479e230f6fb64b26589af90000000000000000000000000000000002cabdb05b1db54c3e95d3d6bd5bec6a217af9a7989acd96da302da0bf5b954de69ade2da9edb600af9671a152409e2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000184e9307c980ee860ce798c01babb58c49a0cd4e7ad89f5c88d565be1c7799c2f3b5b5681238b8b89c675491b0a8c9e90000000000000000000000000000000010ad7f1e13b39087cad3051957f4f6e2b059f4efdbd233c90d4ed2ed042d26fa8ca7281df84cd3442717f5b855f60050000000000000000000000000000000000242d502a4242a1ec6679b24716e678b294264f54219f46360dac8aef8340c50cf25fe194b25d78d5d96eb8b8448e29c00000000000000000000000000000000005f183ef23df76c8cb4e94b0faeb01fbe1080ed10ff2ff12a446cab5dcc1822198bc5a2bea9de66b47d86f21d173f5b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009edd9541676d4f8340ab0d57dfdb204b5c0f8c439576efeed3be8e546830ad92a450a97f86335a99b82c54265370260000000000000000000000000000000001762fa5eb1f01e2b72d0be14cfa8bf8faaffdd0fc8129c5e19c02efd8401fd24cf09c51bf0b6a186ad23d46874f0c4140000000000000000000000000000000016f68b1318fee9f749bc490ed7aa3f9910384cf9da77156b9130e41a6c2362e5be9fef7f9d46b2ea0a34a7383b075d6b000000000000000000000000000000000f4096aabd760dde416501117d62189a0936efb6701f47689d864a2e87b004fd24fa7e3eefc414dc06482108dcac9f171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cd03ba323011dc77b4d5ea0616a45e2b1271eadac932ba65bb40ec8caeb404d2e32cbf8ce0c9d6f6906d22e35c570900000000000000000000000000000000109e7ffaccc50db492d0308636f6530d2a8c67982fdde72cbc9a5beffa490a328b6da29ae41895a1f8c90d61c96d1b2d000000000000000000000000000000001102d27bf3ee092097087f1efb844f1c2c16578ac6745b8f80c2ef540df7956bc73857336fdd95fc40f9cd2d182064bb0000000000000000000000000000000017c3eff4919bf69811adfa2eb77d1902e860e0a50ab692f8cb59e13ec055732f3fdff100602135689c40f825cab748451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fe793c1c314fa38d501d26b54a7f515f4d2f3cccd153c23dd64ecc823d780d5e45716df4230de90b94f38ec2b6b47a0000000000000000000000000000000000208ea4ae3926138a0d53418d63f683de6ce9163bbcc1b17a0c2d3a61f9f57dbc43461c343422955bf5e447bac295ee00000000000000000000000000000000004f8b1257410d221a30880052a8c37a63686bb65f503fff02ec629c709e1c5e4989322ef0342ebda1426903b39e765800000000000000000000000000000000178b567544465e7142266a0d7e0c2d2e2876fe6509dbf18b84416d15c0f8e6d2817efd3dc8f10a71632f7324c1f66ec11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f5fcb3c738f5b0191cf66200a7d4c29c54b3903165bfdeec78184cc3679dfe89e68c7ab0c50c0a53a94f88b4b68369800000000000000000000000000000000039ac1d419ccf9d3540a859e51c48decdd0ab7ea1a78f9a2c915ed019f15b4f6efba57da3dd4955b1cb61e2a5a6ee017000000000000000000000000000000000b94813c49d13e3cdd4f6f3d6ce58b8ca9f75746a8324f5e3a4e9161bc3482ad478a9f8cc33f1bc5c2ca51008500a536000000000000000000000000000000000f6079b9a35d6b9c4bd7061275bf97260eb4746c206fe8ae27632f54008aaa2d3b8957c646c2b95ddcd95684e04f58111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057c2a472a04e8d4bab0e8f610fbc3b55a918a7042c5cbecd6e137244a64da6a7cc88a3ea666e232dcff09be460b772c0000000000000000000000000000000007ca4091c90c729f5bee0b8aef643d2a0e96233f5c24a4ae9a46a40a7163a19a01f6dceda55ad2dc6be9603ca7d5e6cf000000000000000000000000000000000d0d6f5b7112d4ecfca98b5f248ae2e4241da7482d14f99d17cfbb0bb8e4091ced8aedb90db6321a6f073671ad5918d40000000000000000000000000000000011fbdd5bb2711ca0b0d7ce837edad45b03faa6a25b9d4bf4e2761279fff6f35e53a2df6ccca2dfa076f69b45fa36e47d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018278c188a10688cafe661fee5bf97d5446f7a4b90efd3ed1324f653f0b2c57b827b0a3ff9218b9e9e3dc3e1ebf95784000000000000000000000000000000001045e38ea40d3261e3a6dacd64810d140a0527b5804ac085e15352bbbddf4a763a2086d62c928c13168745bfb1ac4afb00000000000000000000000000000000193d1ba7fe4266179dfbcfd99e7f8fece3fee75ffa64e6c1bb5559dfeab16212167864ecb6e0ad8e33f815826400577300000000000000000000000000000000062bb1586b9b5fd4818d59778f87a57e6416ccf3744a9a2be59c6058642ddcb9179b5ffa1632b0c19e27d60da3c27ea51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116d1f9ff304f684167c011ba1fc0c68dad640e7d3fae81641403f572fe85274d71e9d77fe27c5e2c2dc92df9e180dc70000000000000000000000000000000012b61248cbfe9cf54d489a259e80c10d444ace10e0a3bae31ee67de990d41dde96c5f55187ce663f22ec1284a6510a300000000000000000000000000000000003293571e8aa2e05e18a4ed3de76a5f75c2a62f14918b18f2ae5c158cc1520756e080394c6c96a8b4ca5b75ac5173208000000000000000000000000000000000bee354716c71f4a9c2e4f0ed6ed56ed0553567ff2a92938d6f3f6e22ff1d2cd7097b6fe65911000859bc50d5e6593251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128c52265ffd0edd5253860d0691d71f95ba0101cc93ef8d86382e7461f3487242b139b31745f19270c6b2a1aa6d8a9d000000000000000000000000000000000f2eda86d5126e3914be6bcd8ca7b41311276e00f5a20740e3f0d11b82a331c841a79e3c60e2b42dbcd932778787556a00000000000000000000000000000000001d7d245194d622ec87a564095d7b9810981c6837e6cd1be1dfe4b01516bb400db3e7f59dfa001f1574750c80716bb300000000000000000000000000000000068809d96854ce40c835e58ad602b7f75be3299b5e064113e2098d292f6a79eb3d112c9d8ad6bff41b06b6d22bd230091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7dfb7a86ba605f5dd3819f0757ee9782fa04a9b5c82ee3dce99b89c5a522cca1486d8d5a49ae7940a622bc54388e00000000000000000000000000000000000fbeefa22d9ea62968cef3d4e8bfa5e81002bd509b209f4b4e10de82a75a995bb7a1cf4b152d3c235eebd323b9b13b22000000000000000000000000000000000ec1fb16b00e6cb3a6fcc1303769fa7f1d5c94b1e122b576daecdd5c484e6f880d18d074f77e7fd83f53d65e4f7abea00000000000000000000000000000000000bc7e58f9cf9ab293ba008c9eccff5ea2606c172bbcf40a058a1eadb012d69995ac23b9f7b0b2f4cb460b4c73ccf0b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005e1c686bc90357fbc853a00e3cd3b0b03df94bc341ef9142da91696f6d46bd8a60589eb361ea068a8623e3ce0f17e96000000000000000000000000000000000acf45ea5a9f7a1cc7c30c11f80fe39d3e2eaccc4f9a2884365d6bb7a94d79786eee3a923788ee5497bc6645a25c54330000000000000000000000000000000018479ab8ff9787272d8b7d8e81175bef7911105fdb6f7903f8e5ceb57c2a487ce125b930251bc44b9a92cfcb082ab594000000000000000000000000000000000d6437faed48743a53caa2983010d0b04024d9c336242a6d2b9b2bdab712fd1b7dbc5f9fccf93a8839a95b500c1538971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017dc679a3c1568af23c75e9d450b47e8e9527538c1539331435d85573181ce998b39e2cca7016c1106b6724e2d2a7b1e000000000000000000000000000000000a2d86622d54542689b9ee01fa4b5c6a8c75712e4f32cb56ba61774110b8ab0bf8b66568a51f945cf2d986e4f7f5e8ed0000000000000000000000000000000008e4211618e1b8acb0e9a48ee5723a745317a24a9ae966fc8a0d0899fd701d59843064c4d0fde980565150534e1fdc3d0000000000000000000000000000000015b1e209d57954ac5a2bf6bb256746bd9c3856378a8dcf2ada78c4b3c2ad21eca26ec1b55896f3b1e4f3385c2f3a9c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a1cbaf9a335c5c4691117ace37384774d53788132b304eced94f31cc9e4a7a05c5e5fc716c7f065cd13f320b2f65c2000000000000000000000000000000001580904030bca5974f21c485d2418585162fe86b33e74206f95da76f1b3566ab5bbbf15710be0a39ad02f4ecf75766d700000000000000000000000000000000120d1b3931d547aebf3a709151a153f07528dd4f0f3a59719836b8de2322ec5fd8a12a0b38e39febecc06d60efb50948000000000000000000000000000000000401c148d0782abb859cb4c87533252b91d481f396d313bb7318c536052a2ecbba9e067473d85d7c29aca75e6e30a5dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001916d97a329bf5754a28c085af6a3a3b1bfcda48446a1654238a584311b726c097092b38f0c3bf97bc94ea278c5058fe000000000000000000000000000000000b9121ac96f6a4b0b2172b4c43a9aa5a69fd483e670a205c093f498447eb898266700952eaa7b6bd3f4ed7e295d078b000000000000000000000000000000000143de548429a6215331bf5345c460a6aac7cd9b0c05035dbc15453b13477509a03f6ce9883a6ccc72546a51435661eb3000000000000000000000000000000000dac265a7b14fd7114492c89fc525b66ff2bbdb232f1eb0608b6d1406f48db9738accb1dba02f5a7457e0a4e678e2b271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000299097df0f7f5394805b7962cf39bc30443fdd85b73d9b38048b6309c9d893cfa4edd94120b2b1b801fe538216dae2d00000000000000000000000000000000162bb0f2bcb5f2fa14f807e38f0d023ceb2e8dd6617d190a9e7fa9185d48b4beef29631d0a66860d7a68b7416be9129e00000000000000000000000000000000110edb24a268e01ddfc79abbbec24c646ee7b3d93383a75b837688fae579f91e0a7f3c5a0b7855716661347522e35b47000000000000000000000000000000000f5bd5692e6ceb572903fc47f8f4e01d43a2e6c72694fe7ced711900d4b00c6b603d4e49e3ae4e097f18b17d5f2c2ccf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006e0453cc3a3c2274346b95bec30934312281306b99c3c054c20513fe31145cb4a5fe04661f2f5063da3bbe53f20894a0000000000000000000000000000000011fa917fe95f6ed0f912cf7aa46e91d7e901b03eaae42657244884ee96b847a0ace2fca43e9c2a3eb418f3292263133600000000000000000000000000000000186430abd0f849cabd821ca1a83a04c88a46795083de8b0ab75919e3f1efce1cbfd118a94c6213f2edc8237c94873632000000000000000000000000000000001541519d0ad580e1fe6375329e9843cfe3fc817833703bcc6ba53061e74e82db9900fa804b1e15ce51f6feb8de08b6c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033be273332f11dc925e221f92168cc4b162d9bd747e3f095036c81700f351f2c6575dfa742ab377ce2759e5c03cb63900000000000000000000000000000000133d4e54c040e7d406b92faa417e71d5867c77d1b0cbb802db3347cde0fb3558c212a843d40165ecbcec55c6a7d1c921000000000000000000000000000000000a045587b79d2b10ff8a1575abf2b0ecba81c9cee72c1ab2025ceaceecb178f47fb9da1d0c432a1bbbdcab7fe46f1fb000000000000000000000000000000000103b644cb11bf19a27a63dda30ad7b069450cc4afbfd8f42df201ce8e729208e286ce6bdfb89bc554e88f0261a5429c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157c33f53db31a060394a04e78a9242531fcf91d3a1a4a24052e873852f717f5e7cb318bd7485601d9a7829eb286f53e000000000000000000000000000000000a9dfb8956e78bb62a88b875a0503371423357b6dbe0754dc7273f2cbcf1500d48d3a2bb907cee8fc9cb05fbb5a230380000000000000000000000000000000018540ab1d16898717b59da2ae57a9627de25fcf3f31ba83ff8a110b3730331381d6515fef1d65022426fd36c35f782e50000000000000000000000000000000006bd1a503c954d9077dc4ac06bb902c141ce8d0f22788abef3d3b57420ab7b42080f7b9509ea66f374040244ffd720e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca5fa07f71e73d0f095f1c540fe4eacf6e3ebc84d0db37499919116255ec32bf7a8e0a68cb238be5b1b216376f35f1c000000000000000000000000000000000612c43fa29e8fb2c0804ef51dfc1263ccc22eeb92dc5dc89a25a96e22cf53aa1cacc66f9900c262115b95473b25883100000000000000000000000000000000030393cf4eb09d96962967e9a79b7cbd2ed077c14001360660e15f9ce2cf8f154acbbed3407dd8fb3216c9b650d1a3df000000000000000000000000000000000ce692802c6894c9c60cdfa1dbe617feee9ecbf65113393295be0fbcfb3ed43e329ad9cff3a87a07621f6b332f02f1431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003491599c9ea078d9627a85da1834b998d10cd06cd57770f5f05aa94dd6c3acf83bfbb4c1d9836bfa87d52d6285fe82600000000000000000000000000000000069a131c4804188c4abd6490a9e8986c4e27c639503307c8e145c15735903990a5a91caa362c5b3d75302b056df633650000000000000000000000000000000006ecac0df7694c696a1550b32eedffca51a344fca10a1a44776f56f43c940199e1680ed3beca99a004e12ce3ad64faac000000000000000000000000000000000d54e73285c45809d11ba8fe29ba21130cd12fc953e22aa91e5b0737c935b784039e54117ae436b086d15f286b0efe661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b583b6ce4ad20c73fc91cf45f0f7cabfa8a06e432bb98d2f05ebf7a0304f61f700512194683a1e939ca13a34faea94a00000000000000000000000000000000181aee787d82adf8f06a2a42b64a8ab5a1782ebfa41ba3128f65ae1363511cca79885a79f3ac428cbf77c62f330543d30000000000000000000000000000000001f50d9987c373eb4399f2ed68fedab85d582076bd268747076abe57217ee5fd74f719e1bd7ee5bc3b1d76cffb3e709c0000000000000000000000000000000012a72bb9fe4f2bb9159180b17e59ab44f94b079a675c6c493acde3c2ed97bee2c5f6af312e9a84ce21b2ca67cbbe1ffb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006d920f35201837f2b70e8b26e5a86ffddeac1a386a118b71087f67f4a0a15c4f4c7d1fd5c136b91e572d318d734ef56000000000000000000000000000000000622ae91637a0316872f7b73b635c99fe87d43783aee14f617d96fa7e777fc4f4f1bbaeff9100779da2b2fbe2ec1118e00000000000000000000000000000000113c43164531b3dcd92365a7e4cd32eb8fc9809828a92f13214bf9532c8f01d57388d66abdd1d2291205026047a594ef000000000000000000000000000000000a2ddf1fe4557279c105aa397e126ff745dbe765b8607b8ed247d5a04d99cd714d345bcd54fdc025b34634a872eb76501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016453bc748429529d164dc126ff61ffa34665e8792d9abd3aa005eb505308bc10cecdd60253a289e88fc9dfa114af5f10000000000000000000000000000000012432249118862887de4b386d14e7ebf88e6dbb46c9cdf350ac8711bb3517a255b3c376e4c577b322519e24dc53541b700000000000000000000000000000000161ca3cc5946a54a08b3d2ffabd0d9d25e144fcfd043da5981aa105b993b254d52dcf646432d7fcb4da491f4a47f16be0000000000000000000000000000000006af4e6098ad590f4bf4e9cee74a0e24be6c8fdd60cf98fb7aad3fb244245062b40a67a63074c8780669badaf9b85c391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019cae2561e04ea32b7bd0bb6a74814b06a33ba057d0f4a5b35f235d6c882ee8f640cde2682212d9eedb920dea3c89e2500000000000000000000000000000000083c2ac5f1aa3a62c5a6b0e5fb93b8c16b9565bfd86bb4882f33af7a1e6cb13b0474869dade71c2ea709a4df945d79500000000000000000000000000000000014239e6f5c7521819b4769b9c81305ff22db4f8da8275ad48eb4ad15a07bd9e85457f869f3cdba7791bbfaf6c0e95c2c0000000000000000000000000000000007399ccd6ee2cc6a70a10ecb9b2cfeb089d169c54086fc233b812a8bea34ed2dfcfb59e58a9a132f396520305dd1e62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008abf98161a1cd76726e248e77549386fdf2e314ee41299b8de9337e5f05c4590ce2420ba754b1aa16a06a17ed13749b00000000000000000000000000000000103ee9f075d71c115e05f7f6e5c5e06ea775534c6fa6a89a6c96c55aed1894921136ddb5f875d680c387e3453ebebc5100000000000000000000000000000000085aaeb0138668b1b965045a41d27319cd67830e47adc0038d7f6d82cfb0a2521c68fcbbbc14d4b2c5254e0a12c747010000000000000000000000000000000014526c7ec33f836a07a761a4da78d2ce89d9f54402be767ee34caf6a3e7be713e30e84931383032987dd91124a26b62a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df8bc66cecc433f08031449139eb77d5d6067ebc927f2cb58dc793fc41c42e4971a7c57789ea282a3369489ca27cf990000000000000000000000000000000010e469d4e2fd2e0dfe4760dafa4c6f2d9eb4db9932175e9e3fdc4707c7fc085b020b8ae115462390d42a94b2dea48c4100000000000000000000000000000000061cc5a890e12bfe57c500670f42740e21080145d81672c3f2f13a90f8e0e9abc4d585204df6919b25bff9a57624e4d50000000000000000000000000000000012e7db8f5f679fe08fdaad3124625896a592fabf2e7269584754e9e9e8494fc071eea025489ffa92efad38e4ad70ec601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000105545e59c4f35137d3b1b498a04b5ac54aec5a938527708a9925ab458ec1901636be021c29ca65daf3d703a84b2e00d0000000000000000000000000000000018a9280c169ea4483efafcb4052ec0c2f48ec2cbbeadd2714bba1e501033b77a579348a85be164d20538f1a478f32331000000000000000000000000000000000bbfeaceb179f3bd1c527549bd9f800c96c7938377ef7f95e5c3e02cc1a466a055c1d5debc75b4ff5060022f5ad4b5d100000000000000000000000000000000163f7822aff84027284112bc38a79f5e5f03f9944152255820165a8dd03575001a00471bf43710173460d3610fccfd361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5be8e013b443c2437af0dafa8f1e90d59ed8ada6f960acbf9077c549cbf4a01e2ccd500011c12c3116b91c8eb4420a00000000000000000000000000000000156a5199187951ae35717401b27daad21b0308f0c689e179fcdc933447d6810d4176774b2f4635c18608d1926521a28700000000000000000000000000000000165301703b4424392724e84579b74a97a7d0151c30bc0a03dd4542ce2e8761c74b329499bb80ad874fd9a2bfddd49a3700000000000000000000000000000000133d7108bf9023949952a328c17d70333ff10bb2fc3058ae1a2f8b53c28763a7973ca37b424081a81a4fd70ea5d604151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa91553438f837a96a1fce86fffad1741a68d65b74f98ef5e9a5ff50bfd1287955e52432c45d5a4d961dafecc9542430000000000000000000000000000000018abfbca49ddb0a759277951edf0ff40f9a7f4d92920afbd2f3aa091ed040bbe2bd875b125281c7f07b00a4593a949da0000000000000000000000000000000018400adf07e8464e6f82bdd636a911ced7598e4da6a5a6be191e980d85955c5b9313aefbe1e5819f562020b5ce32246c000000000000000000000000000000000933bee32d06a70ac1d22f217255d4f9170bd31e3f00112ff7a32a975c320eeb15f9a93584f2e2118fa17a4bd91c78831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000061ea682ffd6209a854551f6ff2efecfca4326fc3100f1b906b584b6981cc34e1058983977213bc9c0065b7ecd1dcfb800000000000000000000000000000000134c05bbbe8ab83ae6983a380a13797aeee052cd10e04f629e5a01f3a151d12fb2e1a389fa2d54c246826f0a1ee4f80500000000000000000000000000000000190aa651cb1ce8d82b1bf1ba00a205da45092b83af683bb35add75baafae08124bd1516d2724094c76036597a55fb7ae000000000000000000000000000000001090e6f35febf7a783b0e4b2e2d20c9816224c940face656bef7843bcf320645ce34feae80a304f59b24ff2da4c2328f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f27f9bb136520ac0fc5ed0e1bfc83f312aa104c522e37dcbcb6b81d04018ca2dc8eb14bd881efd364041c76371c89100000000000000000000000000000000073e18b49f09627f4554c34f898cdbdd1f81eb405caf976be272e40fa79d90a0a69aed387ec1839168083de1923aac4c00000000000000000000000000000000095e2b74256fb640dcc076f3a68cfaadea7b44c5b456c4d1ba8fc8fb755a7de91f9ca99de8736eb3866f3edf1bcf898200000000000000000000000000000000065ef29196b54b6f74a6545c3b047b91e22f64b209bf7c147dbd42f54c24a4cd8d20b8e4340a48d52f6201758380cab41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052225f888d217b3f68f22f1f414967fc8a7f2b2a064055f4be39fc8f0ae36700d12afaf603d7861574315ce9ff6c8fc00000000000000000000000000000000154e32034d449891209a6e07e00f283ff04754d529010586b4395cf0c7a05e62f2d61156b5ce2549ad5068f4cbbac283000000000000000000000000000000001517ba9fbd9d0e821265e881bd11313519f9613a92cd631c6ce501e2a369109b22b2e0fe263d918e3e244f6cefc552ac0000000000000000000000000000000016b7e2e729dbe5947b5ee9153e36a5aa1cba17fd98f4c396eb84af40d95a0076851b1e7484352f4eb9a50c5339393c6d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f5c93830b642d8701552dd48a1cd044d50ec327ba49ce86bd9a3a877051317727977bf713144b213097200cd2eb4310000000000000000000000000000000003c801800afb875de3c7c69a8a62f0da133bd80f7e77f68da71d4a0a5957604e8d9b56b8927d0450f6fb2c905f148d100000000000000000000000000000000002be299a0e4a96404b1d94a1ce7995fe70abfd9fb76f3d2e7e5291aacba20b3a158f6d6470ff34b530608fa019fbf0cc0000000000000000000000000000000009d6a0413987fd5653c47ea7d9a1b64057be59d53d3bb6f1ce9503f48a1fe3eefdce66827d48448ebac82be98b9977831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f89863343d5ab6e340b03300eb3d951d75e88b2f10ed0f5ad3f2ce7c428c8f241fe8dad65db1f8621d16148fcefdac00000000000000000000000000000000006efbd2522170d2da1b5f3ce1757cb0ca29f1d349360e62491f54230642247d9ed8b17f87574e36548d8dc7f8e90ed00000000000000000000000000000000007c163c12031f68ea603cac1c47248315a4bf888feee92ba6c69a09011789ec4985a62cf7cc0dabe582a1c4b1ae495830000000000000000000000000000000018b548add8363e0b6a99c6d40f08dacbc7d9e58b56699f0554faff1463669dc8660aa839fb5c2cb370f493bad6a31a791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003ea1a249d41c107e8fc99c89cf1143da37b5d10c1ecd141f229dd4d0a4ec5a729fa72238c62480d9181790a73a12f1d0000000000000000000000000000000007e07fb727b8fa251c89ef8745391edbb78e867e1b304604943d832935a0803bf4e8c5120d012c986896b9d988974339000000000000000000000000000000000bd5b78773fd33062680d742dd3c92b541c41825075d88801fe91c67d392940abb6638bc045e59fc2f8c221602abb77000000000000000000000000000000000019f99fab2fb70b9924706fe5a4e44417d2debaad7d41cf3954e8392f75ebf4193c8db18a5a6e0cd492ec2a6f68354a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018e8d229c6b22bbf787574ad39c87428ef40eea49fefda1eaa308140e03c310ce265ce7a138ac2f0343e9586ab88f5890000000000000000000000000000000003e8131900adefbbd7ac0b3749e1af4fa7654cbdb7caa737c402e99a74804bad0e1adc3ef8da76ee7a10e8045b8a51290000000000000000000000000000000015298dec35e7e652f808f7b5990f5fa3eb75a6a510109114403adcf698eabc590ae21dafad25fadb2617e03f513153240000000000000000000000000000000005d10ee7585acefde50d07662d79253e2179b9a1b1dadf41c1ca9b07415f0c08726c23762710d4af7e96d5afb34b48fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1e56f0f184a3436d5afd00aca3ab1df438843ac4f4be54489e629e3964a762466d0af711b0f7face917f90d5a93daf000000000000000000000000000000001144b021ab8e8048618bbb3eb17769de37203bc0e068e147319ab49e886d8f97e1bde16c62dedae35c1d46dd138e81b300000000000000000000000000000000191ee9b0e77313b177f5d00bbb9b265804f43441f0ab60f217c777771e3cafeac32abab451651bd68654d459e113712a0000000000000000000000000000000011996b92caf8eeca74ce7d347937f158748d7e556565fe8117c311d94b97c5b71cac6e20340cf10a2e19f9d26971774d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2fd4d20fa2bbe8a36f07b2e1896b783c071f0a16d52a6b6eb065b36ded6a7a7fef512d3a47d7bea4c092451b87ee98000000000000000000000000000000000a5e8d7bf84f4ba86b6fefd500f7587b7e500bfe693d600487755cbc0632d2d1b8ce418758433c53fbecd0167e5c62ed00000000000000000000000000000000017a5b73b813e94f5e6458b9d9bfcf758671d9af84a326951017c6c1f9a419c43fedeb79bd1e52ba01509a3ddb087c5a0000000000000000000000000000000011f5aa33bbbb2c2825fc78133fa5758e73e1f7dadcae362730f25d1c85b68908aeb715603638e8831c181ca0e96dd02f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abaf7a405f23cef690f52229ec51bc8c3a0ffab97167fa969a4d909549818d402a8f53fb304547a051fc3c7961c4c9d0000000000000000000000000000000015f2af9ff22ad3f23372184f7aebf644a0f0e8fe85bf850536f070dae1bc1d0dc2219b1d1279bf83e15d7843d1947fde0000000000000000000000000000000004d1ec46c5defab4a25f3d27af2d004fe5a7c2ae693d8e0892251d456f49c395c58d0f94c489402e5d2b99f8c9993326000000000000000000000000000000000e20f5646fc059fef433364fb948d84ceab0cd36b07ce397aa35ba71184618435b955fe3697a5937db471a5e01729fcc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066ddbd4924b9304fc5e3649e5330220d824f9c9409d0f61190e47751616f4639d796cc1e51941e997ac8f0967cdd9060000000000000000000000000000000008f41bcee28dac19eb10feb91ee7a2b7c4f69e0e846c7fa0d74c8a193cd09e34fae0b21b7023a278cc2d13b06b16dc2c0000000000000000000000000000000013e966abe538a8f5fd03515608ff7a6fe78b0011090c8e68051aa6ed6bdf963a87aff3e6ca46a6d53eee6914b9a60a2e0000000000000000000000000000000013f92a8759497c5b6aac811bec7473fb5b884c14598d6a9e192db7843da569871aa7d299d749c58d2c983470870512761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000033ee9277c9ca0aa5167fd2e0c5c31e035d639d5fcfee18e5511b5db577afb779655e1d5f50d61be281c914346ace674000000000000000000000000000000000d870f7bdffbdeb9c2fc1a457b82fb7df5c8cb04f0a3b97bf90aa451fd36df72f562197dc70e2b89d1c69649cd448d7d0000000000000000000000000000000000735c5eeeafc240dc2cb0adcee2eea2788264459d04d26b850f3acf33ff917246a0d2457e331f4a21d34d97875346400000000000000000000000000000000009d54785de42f34da35f3dd35d9bf7edfb8311a97a190d86ddfca28fcd55b06dd4e93d11ea9496c09621d596dbeab6231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000817029a26cf1106a8f7634563183e1e9b76475dfad7732f8c213f151a1272c47643f3c90de4fc887b91274a3386e2f0000000000000000000000000000000000cc140b5daaf20f2ef7d7a1f978f6ce4b1bc044fda9305873663e3da26453d15332de153ddcd5fee3371a6ab01acd9e2000000000000000000000000000000000cba31d153a5cecebcebba7283a565fe17ee8c0e13d89894e53038e7274353cfde1175ef5fffd5d8d5724094fb7e9370000000000000000000000000000000000e069d4cb4914bc268f5146306d0cac6fec65e97f0c9eee89d41e3485512ca715b2bc6145a13ee40169afeba22cc0d601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c59b7969ef96dbd086d1bfeea835faea99e34a2c80027a3c9944cbbf224807f2a5c72556df07cbfed55442571da7670000000000000000000000000000000010060fc940296ce66c3f0d21f5ae9a91e63a04cb6f50a94a3138bd3a2b3043d33d25035be8946c749db6612938930b41000000000000000000000000000000000e53b5b7ef78be9d98af99b9640ffd6198add5c553d8e3e236246b7cd635146346a69330514292ea18ff63e9b011d3960000000000000000000000000000000015ab50891d6a829aee6b05ff8354eaa9bde44f2937b7ec7a12943b590dfa878c3b02b8a9d3ecba0f9368212af6e2702a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004cb61ef4aa507107bc52c10dcc2f7e2002ed9ffa343a5814fd650d1be3e99474240c67661a6b8b02ea5ac93bec43f30000000000000000000000000000000010f1c31fce5228aefa8280585a550f129ff6af0d58e16041df670129191ceecd45b6ce772488fde181b38444697616010000000000000000000000000000000013e1254096067c28818e382addcc5e33d640b5ff8403ed4692f0493e9977a99faa5e5306accac2ce5cbdbea6804591220000000000000000000000000000000008698cb3edb1b4642c27f90de94751e6c7d83056abdf9fa4d9b8b682b645e76681df65ca8e4d46b04d3bbbec3bccf56a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001030489d08394cb93ce847531d64ac4e3b2dfe328691b7c891afe03270e08efaebe2559b51a2e4e06dba305c1f0fc738000000000000000000000000000000001863b4f06b4657c127b5e3d40403805e4376a8faa4052bdf84aff60423e92e85aaf3e0fbecac3a92c1799e0b5575b6b200000000000000000000000000000000097d5c89dd182c35b5bfab1ab68e35dafd1bc5a24b0b030100af01025fbd5c23538cf5b26c79aed7dd525f9707bef5660000000000000000000000000000000009639ede2635a34430b3f246d8bc141b2addd287923a2181885eb5adcab878a79a42012adefb804346b523ca3b4af1b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009dc0050a638e4306c2995f69423e417b2e6302f26883ce16e7a1180b4acf8e137128a60210ea3d8e23e3e601bde930f0000000000000000000000000000000011d00f7521201a19be2d684bc83fe2fa713706c70efae0152bdcadad1863266e61f9281c2e85328b11617883dd8a8f8600000000000000000000000000000000006cc1c9c2b041ad84c03a3ff9c71b5e146104daf09f48cca5746a40f9700aa8d917cf5d93d528f8fc5e09b0f1be804e0000000000000000000000000000000003e33c96fd850cc43160693892bf1d9bd88b01556573830c995b793d197b0b15cfa2beb5b584f1e49d2c43219efb4b4e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000161e421667b2036f465fe7d95ee7eb34fd87be64e6401c6b3d55e79579a9194f9b73ddb11034efa4c3c32b343ce197d500000000000000000000000000000000040893621ac3b6c204eaa7f12242b331f5377400473bd7ca2abdda4a4b246f3123b9fd2daee859df036c6fea1bd1aa0b0000000000000000000000000000000012d6ed6f54597c5833cbb439f76c30f36debe8a96438ab4192d430728eb773819f70d33f92076d0d9582f95107f63bea0000000000000000000000000000000001572cc131514f004343235ea96f6fb889f91f1d1105cbdf9785e04d4306ba66f41464b6c2e68b422a8029a1a78f06071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000118aad854fb455f167b3743d3e05dccd2b888ac6506fe5d95e60d3c148d48a9d71c6c04bc9c421b0ce65602da60c1b04000000000000000000000000000000001888bc5efb9322bfe8460dbf0800e3e8bd17c464562dde8098d845ae846e6db540880b67f764a6e523cd27f1f9be711a0000000000000000000000000000000009fa95cb1afe5cda866cd26694758b14ff9f04c0e0544c5adbaeb3fb37e6b3847b09a9eccb9cd8c2e90541da2b5d9ba70000000000000000000000000000000018935953ee935a9740ad860c9a7790f8cdd7333646fa55375880363bf29a443750a8efe8a38b0eda0a8b01acb6810c2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006ff65e2e6b09e59c2369cd50ba857592f7bd6615618d4f1199917c95cc2149f30e6bc4e556f8c9ddaa04869b3c2d1a000000000000000000000000000000000182db4c6aff99dd216912d2a9a811ac6e62f0d3973c82647cc06fbf8518d608d49cce6a5c728ea76d17e70a2dd400e61000000000000000000000000000000000afe3cf47b02038bab6c396ab289d0593a2f810c2ee1ba1085abcf9852fbd165ed4c73dd1dec4ac0c44dc3d325b28b7a0000000000000000000000000000000006b296a5ddb1c0d7c4981fc5f44b413cb8308641d3eacdba441187ded4c615326c8ea9d857aea4198c1a84244b2bb5661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130600009fccf0d7904cff657e81c09edb95cd125689e212cee2b897c7b1e642f68384ef15a69fb555ed1d2f3c4341c300000000000000000000000000000000086f7b892266417012c34faec3d88c195fee19ad01824a5c679f5b718e530fe17710a7de7e76d7b2f5f0676f34b3081400000000000000000000000000000000116305d1ef69aa90c2213c7f2f948597ddabeeee23f4a9fa43adf64d93a57f722c969137419b02242824c52cc2b4ae07000000000000000000000000000000000c40d66794e4c4cbefcd74e80f84e42e8da48aca0237cbcca5f2d53791c0c6e72938443d3bd57d57472b9fa49d1383ef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000083c35754c26e767c81831bf730504e2a8e0a0a0b2c7ad50b225b3417b1036838d6fe00c7c23b55be8443fa25ff658d9000000000000000000000000000000000ca0a53c1e59d35853edc03a5833c334f7aba68927195a28c41f062a3e352090be4464b469bf9990f55e4e4ceeef65bb0000000000000000000000000000000005f90d7d3fd01fc46015f86b9ad8e4599e6480158290a1a97898b806e3aee8e2325b508d92678e5e17617befe25f40d8000000000000000000000000000000000c393f193867d66ce261fdf09b13899b819b75a730b76c37bf2b1f4bab189c90444ac1914ca87d1e88ec915ef2d7c1e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008428d3e2e74f0d2db252711c2db2690f52cb51b0ec8522930ae68897e51bfd98430de04b859d95f102b0d07cefb43e900000000000000000000000000000000034857c479858dfb85910aff173a1a5917d262e019115b584e7f8d6ae724ea312360a2eb92359576e5109ca4a40fffeb0000000000000000000000000000000003a1f726ca7ff13ea5eee04a6348a961f6989dacca1764b0b33d2ba21009053c254338b05a92dd6561fbe8e74b55c068000000000000000000000000000000000db0dfaa9140f86c4239ae9463ada5b2ed9dfd0ecfb50cf0a2db9ad1c182f1e2301f0147ca63ffce726625204c2d8d651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141705e857d13900b2b38964448761dd1b4655c9d965ae37115264d55cd407204dc04080bde5f615011608e42bc6a2b40000000000000000000000000000000011aec51c26f824f19f177b7b1b087493605c84741ae6dd95ad31af91de8779dd3df22c9b76616d02fd9a5c7402f987d60000000000000000000000000000000001381eedf77bb6318ec3c5c365cc9febb18ee0938c4b2d98d955b30b8da9d523a262cd4b48cccafb3618e21e44a08bab0000000000000000000000000000000004a9fd82a0d0f29a7fb50da605e662e78bac8e2602c280ca750d09d885bda853c9030ea24eb4012cfd75fade752b80321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000066121bf4edc50efdfb406a2d07b3c70d30de060bfe1a0b5f87328b9694cc2324cfc00fb9e315d7999b15c0aed5a0230000000000000000000000000000000000739a21b57db8c020909659edd56703e2d9b2362f001083dec6f3674816cecdb45d390506c1c7874c050df5c339489d00000000000000000000000000000000112e33366e41e331f01abd7c8c758f86185ceabb0fe73f44dd5ffaed298a774e43aad2ab3a37410e6afb33c55e3379e900000000000000000000000000000000186a697a23fe7cdb81c94d9b62849ba14a9c9651bbdb4f9cdc912700bc77def60072448a42411d593c24f37b73a4bdba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198ab71d32c3e803712f3b9dda32e3a40f5443248657862aa362c80b40b2e5b0b9777ef5dd2be7736249efa50f363c5c0000000000000000000000000000000012b81ac62b7688c68ed3049b75634c9188de0111ed36fde33966fcad5c64960113f39be75096b40b5abf994ff3965026000000000000000000000000000000000099b0ba997b5d85b14cb9a9e84d5f5d4875eaef80816130557f542756c47454d762bb2e127399d841e1e8dcd1dd0a7200000000000000000000000000000000058f24391bdeacfd762fcf69b87c757de18ee586fbee7be9c2c16f7e7d04555ae4a0305eb7542cf467d4e1d9348afa761824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018a8baa8f353630e7acbf6e6de8f7e4c84c00ee7b3ddd6400b3dcbd02125c9452177b5a135852ea98156b68a1d239e08000000000000000000000000000000000ffb411e97e94f621cb467cfda0de928fa29a28d481b14eaf5d37afb6505665299c935a4a2a057103f17caf627345974000000000000000000000000000000000619a7823378645f5be1064d99c44c9af2f0e1ec855ac20e7b40feaa77e3b507578a0b850fb41fd089e01aad172a9ab50000000000000000000000000000000013fbdeaf830296e45aaa64f31d1470c2cf8ba843cd33c32df6f17bcb38eb50995c1606d69fc0ebb59e25ebe8b298a0fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015e73af91d7f28c3301387a3d2f653fb36b9288166b3cf814dfcc96625653ded1233de27acd4f0d32e56fc6bb1995b820000000000000000000000000000000018aa42d9453d8c1b20affcb76ad532dad412ba47998a8ebd2da4240995fba369a3ba8939e647ee151917884917f8f242000000000000000000000000000000001468624419912d192d7eef6cfdab1126f391bee55ade7f759f0cf47e78653b0dd875891ce694397c4b785d80495bea530000000000000000000000000000000016c652f8388a3297cb34509a80f54b5f3517123436596e90657fb44ee142d6fa9d1103df14594cb1bd942ddb73d3d1ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f1beedbc1ce681ffc6b56dbf29cbb95a2cd6305da295d9ca80937a0e5c4892ddbcca561c86884a5db2c7f33b0d544e000000000000000000000000000000000be20ba040103bf078690a0543a554728e972b01c970baaa884c17df674a067bba3e0a13098bc22b32eccda37706dd690000000000000000000000000000000018fc0656520989cc352273d046d6230fe8b22534210a2ca63fc2fdeee72f2c0b2f5ccee39452b37813bdcf3b729f74b10000000000000000000000000000000001df2338ff82a70e24f567a931eba8d2a27050e000b409aefb2305c68656356eefdcb0aaa2e4cfcff7c441b9393dcbfa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000097bbfbff47d4592595a6879edaab1053ff761449814fece45262699a33316a156cf70323720703fed6af04dd9bf4e0e000000000000000000000000000000000e46f5c5d14e009cb89270004d416923e19903837f84b77125cfddc248e1380da69c83cbdde894cf981dc4278df426b9000000000000000000000000000000000dbf70b7352a38e06478ec297d20def1fa1d888e225b0f73cca46dfce6c67dd321dbab00aa3567a3af00f5f171be72750000000000000000000000000000000014761fd503806ee5e525085006f0c46f039cc21e672782b30a401997dab6f0d2964b29741b47613d728363d1c710db491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ad709fd435bc4bad62400505f9e01acfba7acead4fffe78f44b2aa998b6f0a706cc0015d02a11a186170361b3a41c60000000000000000000000000000000010c9eb9e49c8151f0e976d5567d21c1d714fc27e549df12fe447be2d7bbaf396f5b018718cc176ff1ffb381212f9f0010000000000000000000000000000000003236caf1c2985e206ccc20e0656547e95721e2eaa9ec644d4ddd356edbb254bd9437f068c04b066ae55eb852b620ec10000000000000000000000000000000000f5c131bcfda82fb9ce68a935c3d4b4df045137d0cbc004912007facf36c341c15c3ccf5daaa8a26bcc81467f109e801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d2c6f593db751b9cef38abdb85ba9d35cfc06d8d703c7a05ea48864aac90239928bfa050059ea48cf388463c13d73500000000000000000000000000000000101dd3fe101b69063a94e2d029da625c7e7d2b3ac457b640919b9ce22c6897d3292cf12fe4650bd1a6ee354ebb22cf7c00000000000000000000000000000000138543ee48e66e39e0de15e16d01f9a36e879e4bf1f18b14d3edacc23d29f7a846ea761cc5dce2eb95a7c66af533294b0000000000000000000000000000000011dfbed076abc6eba808aa35e6591e3ceec4cc502eb0ea9b764883761b6a71542a505233b7fec4c58a5788b1db7b16661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000136e675a00d7327abb7fdae7e4bea10d08d1189404959f870ccfd46c686e0517886bcf6050e915beda1f81687c4afefd000000000000000000000000000000000bf15c5cefbac681b0aabbd772f0f0d0a7c81315f2441e92c838efc14020b3b423da37d2a20b9f1d5ee379c695ffe11600000000000000000000000000000000161bbaea6288e916b2e08ec7d288571b02c3155d855a177f3642dbf691c3afc3798b2094bd6426d7a9e0582fd93ad000000000000000000000000000000000000eb95d8a0bdf8de65b47aedab665c7f52741d86857e419ba2d13e89456593b675a12927326556979d0b96f58394692e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003668aae4a4ebe846f30d254b9b31132607f87bc3cbf4c65764226cb040d356049a095c0dfd8a647b349f94ed855e2d300000000000000000000000000000000124c558b61ad61841b8bb90f2c52ab047e863c403fb573de0741c06bdcaa95faf42a95db3fd050868808445927fa712e000000000000000000000000000000000c58036b9f85fd8cf4f06f712a4fbfc223ca3bc9665095ecdeb4b15636038986bd66ad16556be3f61cc59ac5445f10dc00000000000000000000000000000000152116318c9a71fcd0d2cfd59954abe0f5287ab6e72c1d79024f7111667769c67956487c1c3175128cfc39c8b9aa138e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018fb747b1ebbb8887c9810a92c29d4bdee0fdd92987b3455248e0d880bf38a82b1b5b4a08d908c2bac22d2f42a8eabbc000000000000000000000000000000000b2c71b0a24a57aa2babb047d4023c4650c75d61370988497d6a339d168fa6972777f21e3c6333c27e2759e2156610b2000000000000000000000000000000000502bc3acb91187fe1dc5eb4099b197acad6fb8855748ecfe9037a06e7f5ea5ee0a11cb90e1848ae826618734b3c14100000000000000000000000000000000002006721c959431a9cc1f0531c59f8cc0f6f765bcc84256e8b63d28584e9bc962c8fabbf6783a5bc11693767aa5fa86c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001344009f4da545c50bbe5d7a3491a74615f6610f717225860e7916699d847a2a49b4d40c4e4a789fb50b9b237840e00700000000000000000000000000000000156f08cbf940b03a82a3c939d184657a6672fbf72075c90273c0f1388abe0ca6f57ae03764d2e56880811143d5ce89150000000000000000000000000000000009e0a74a0866af8e2a4546a5f63f09d9eea8c2868298dbebb681ff19c3a07593cb9be0f5ff778b285167e4855b90ee9000000000000000000000000000000000147767e8094a9baa0b803bd6c65cbaf80be7750af063b507a51ab4d07befb03b8614b4b66b450e41bc2f8447ce20196e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165a03f5079da935d9890bc9ce1cf816ef7856793d6c7005cecd00e5b8190e8e87f50efae92fb5ddc1df570c4888fa79000000000000000000000000000000000b0dc849744767da681793dea031e37436bfe8a6ffc5fed2041c01d60353b8fa92080f007dc527cee59a9cba38dfac400000000000000000000000000000000018218715143377b8ad8cb93644ea665214e183113e51b0365029815ed89a360ff629f47d36ac99a51b7a188800ffb8860000000000000000000000000000000007e9869b2cba574f0fc71ddfe6b571a087f225da7b0d6c9bd7eae45d982ceab242e04e8c29d4fd3ef7a408f64ede73b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004f1b094e46cce2b3d4e73782305e84366a58a96a0692b03cdccbc21f7ba2ea8f5aa3d0aa60a8b2fd304d4f78bb73f69000000000000000000000000000000000beab4bc37813cdd7ea18e2f13dbf43f44f39fb67f5323283f8add7e102c704cbc7bfb6da2f75b8fc0aa5dc5ebbd0cb8000000000000000000000000000000001795353decea43a6196c8edbe9b56e403a67ab926ef758dc696cd1d4804513e5018ef267d3667662c1e1b8dea3ba06cf000000000000000000000000000000000757a38fa8c04040cf35ed700b14db05fe39b7e4cbdda902cf96cabbbd28774a4b6c330c1f7f4caae77c2f32b3aaa7d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000192afb9b6c2b8664038bee39a02411ba628db0177aead44a391adff4c4094c347548c300a5007792898be3c4bcd71a66000000000000000000000000000000000ff6189b269cdf73695607bcdab9d803701061aaea09271aaa8a95935dec7260465af7d795428cbe0769d78677cee3340000000000000000000000000000000019941ba431158354eb60360ae3818fb0c20d31b28bc3c5453f70673c8eceac4334d6bd89338e5925fb4351cbb8dee4070000000000000000000000000000000001d674da7c56b02b9eeca85497d5f92f9c35d353e88892f495e7c63ae711eaf8ee356033179ed19c5899e7a705ce65591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000472bdab72d4b529e9339857437078b362eb85ff345101ab98a60bb1abab672b9ab5b6399f13531f24f0d54f6d498db90000000000000000000000000000000017b7d6a7ebbd712ce804ed176e1e9dfa54e1dae7721b55b6b940827bcbd9918ca50f75c3b51dda8f0bb5b31b2321fa0d000000000000000000000000000000000713554582bc9a2f241082343b3b5f26d95976dea80fca76161dabfbf6a9595cd30ed946db46ceb1857cc33505e719aa000000000000000000000000000000000df0897acc9cff0806e795cb72a6f1b46771a913f7d4fe5a036f2c1041efa1f9de38c0b73fab38714fafe8443e79339d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f135d1b78400549463382d47e1a417e53e29f9c3d898a945f75628fc38160278139164191301bdbe6843ffc591cf520000000000000000000000000000000000008304493477102e0de7610d01ab7a8f2ce3c3e22dd72dcce3843c324dd71ca106a95ace5162f98009574ef8c61490400000000000000000000000000000000167a8f51050d0cec79ad0d576e5a233f8547b85fa30e0fcd6a3bce4f5b7bfd6186491424a8e17f0925e20f589ac0ac1d0000000000000000000000000000000010af43b4e75be6d2fe80c9253a526ec90e47d9035022e084f9065668c2b0f2755808b6870fe40db63fcb1ed576b22ea31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000112ee57f536e59371031c9bdb6f704f058cbf9a776c2aa83bda842794f9f75057456e17b54652781407753b734cfc2eb000000000000000000000000000000000f83454f319542ed9e70a38eb39dd4fdf80409ab005386c20807a9dc0ae1d71afcaa9705fba631dfff22c90ae550d58a00000000000000000000000000000000184797bfa9adca051f09d233de5a642809b0d5ba61c43d679b99d4c791ebbfdd03d0b3836e4a070fc510229afcc8ea2c00000000000000000000000000000000014a7b8cf630f70ebd3c78507a5aedcba397cf6b25a43007cf6bffce4e2eef38cddf11f6f0e33e4831b406d21a3d05321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004b0b4409ffa83ba08277b02ee02e5495c16a5cd2baa4ec73392d3a3e79790b37d504f7aa2c27d409a2b32666a333706000000000000000000000000000000000a1c708f8968508e1eba0cb0b0cb8fbccb4fad0e3ef8bd25c5d2ba176ae455adedae06b0aeccd65bfcc50652446c2c460000000000000000000000000000000004ecb77bd0a209afd80d50b4404979a08266dd94d4562f1a7f91a09b8c25417b5b256f4048dc66d511316819e72db7e100000000000000000000000000000000142297ad4ccc7a1ed6b8d5baa3c565cb1b3e9c367181f6771d78156739f996bce6d5b1881569503dc60568c4f9ee06431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b3a24d6da9473513b83b64c967e9774b70c12d74497582e3f611be88e610e779feccbb69e2213dea2d08587da8a51100000000000000000000000000000000064401dad14899a0ae1410c728cf8631e18ddde99c18b3a0d93a556f679c48fe9f5c37ea70699d9cf8b6d5ea2f696cc800000000000000000000000000000000027b84f45827817ec903fc12e22d105a613e3b95f2221004a06d403ec4d0213951ccfa0859626965cd0b941101b7eeb8000000000000000000000000000000000d1934071870f6c33a6c1713bde7940f93d230fda6fe24af8b8ba080a49c4b2e3799caf8daf7416eb7469cb1454ff8111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b794e15ed55ab8bfde1d9f818cb23455ea22175fa1d91c90f30d57e2b2b72179d308cd37d04b4260038eee439579be500000000000000000000000000000000030218d9b27ff96eb37273775627ce5a267b2e691e978de829717ee7f7ad7ed1d39a24ab95277a7e1f767ebbc9643d13000000000000000000000000000000000d3dcbbb9afeca28465fc10b55bdd611ebb60dd6bdf98530268104e19468ad6f100f56e0473b4029c1b02a2bc6c8baec000000000000000000000000000000000addb637202cda397d7a1b8a989164a382134d4e11c6060881673a1658ad4c35a2f6e815fa361802a15d74fd65ebce061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122d13878822673f38b870c92b65f553a48b6a270be88280f391f44e117c1318f8c74fa6ada11a6b402fdd5d9aeb19e9000000000000000000000000000000000b9cc97ba5ef2d496a4a4a3251965aad39c15b98c8e44670163d40455c79df9e6fd6a2866424e720a3a76b0f005c78e00000000000000000000000000000000013a979abd9a12faed427d96004a4bb6b9f35c4413dd27d57a9434c99aab2f1ccd73579db31ccfb19ae93de7aa703f2ea0000000000000000000000000000000012b25025dc6597acb26b3c58f03a686bb46b8edf041cd6f5b3212cdc6c6f40363cf697af9f2183ccc6df1eac612e99fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001376e515e9c1ba13c091677194b5a24885061815fb10671cf5ad758c176586d16e707aa5107739312e54b69209dce36f00000000000000000000000000000000098fca25cbab13830f919053999e51e6dcd03231637f7ad2fa6352ab5672a7154983fce44f3c6550e62b41ce04ed223100000000000000000000000000000000074f435ef3bd15b9983860d94778028f1e8751e9905d63fe0710ef4fa54fe73274da25b3b5e6296b5742c877b4a5e5750000000000000000000000000000000005c3c1d908cc098b790a7c1d912bbea6869214ec64efbc5fc636de7d348717c2d9c63f04a5d45783b0e0d0b568ca848a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dec626101cb8d4c202e616c467a2909eda7b672c256fe7bd381b0d7ef3c6d9d618839d64ada04c11ed597c98c606b8f00000000000000000000000000000000030fe1fa71f97677e8929a1b6e5f171799100a8a6cdf1b08f4a9b9eb6ca47d46fd0a81db87deb74dda4ab97b6f305837000000000000000000000000000000000e2267760601c8b13846b61bb6264b43464460accc55485d748b4c0fe4c55ed8009197caf63397e4693d2c2b700b21b90000000000000000000000000000000007f46397aaa640f3b8a330c14547d9d0f0a6fb7403ac61fd0c746f2bc7fa2d023aad0dc03efac6d03716a384c7d0813d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012507f86b86cdab8bac48a872a201cd676c626da17e09fd6ef821609b7bad4877edb445a34e9f11161eb4e4f5771f72c000000000000000000000000000000000712cda4c7ea7f9a5c99d83671fee577c825c7d62e7672f4082842a8b0d04351aa3277fed610fd268cba12e4c06c1aef00000000000000000000000000000000103bc815706d9818daea0a01bb53829921efe16c0bed27a10ecb74bb40b4e01ddccea5b7c0419d6ab241c4de6aea09200000000000000000000000000000000008a1c10128ad7f895e1b0a7307bf3f0a491391be183c93be57011003746320ef547c3b5a4f44d0bfe320a37b60f026111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce4fe24aa2659152f311f4c1c877ba637a296da340a1e7a40a85cdffedfeb5ba3deb897a864dfca0a8d785650e3ae6e0000000000000000000000000000000012f3df9a2e9b7643a1d12ea2595efdb907b3b1308cac8aeee16c93e622512f37e58bfcb2fa03dafb73dce7137651895c0000000000000000000000000000000017f71159ad4785d2fafd9d17353a1e9ccf31c602c450dca8109d9d59e9ea8a6a754d6abe8f910b617a9ecc14e78bc1ce0000000000000000000000000000000006f20b68262a34735723b57e3df1755b85f39b186370151ade08b6e24ff43bb6e97d24eee2ddd957027f5b257a3b7f5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001549625a9dcd55b3189e6cb1e18031caba3a06382c10cef2ce9c21f6d1762933567477eb6c4eb2dabe0331916d0fe8c300000000000000000000000000000000112db81c221c95e6ab7ef9d6b125b253a8f17f6b5c7cc36df114e1dd0f1218d6c5d6bac9442d03a9c03535be0c2e3b44000000000000000000000000000000001314074c055f79ae0c5da8245aecd133bceb4e718dd25770f2aad68c55a48c5114469b290834890fd5813879d51f5fa500000000000000000000000000000000005f239211fc88218ecd7189df2af108288047edc6555d610b710ec809564de02eecc19cbc43302df3aa973ed01da5fc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000042d368752875de851ff461366661ebaa61b56f8a367cec34b3b4bf2c1c9b13445e2260ff1c1eea3c8b4b50fb971aa140000000000000000000000000000000019773c9aeb32fa93387e4eee945dafb76a0a4619a86ba9a3c6e918769a941b03b23ca58d3c675e95751d20a407d208230000000000000000000000000000000014b79e7818c49bdce31ec0204d82723196bbea81b7b3e2f4bb92fe6e6a79da6cae910e6d909fc0961a6928b9051eefbb000000000000000000000000000000000f870981d1cf2151fcc3b870f3df969a801bf641da0cdff58905e387ddeb3279b90834ca0a890268cdf9d575b98b1c4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011f8a8e6919574aac5b3d568abb72a2112b058193c10ffd19117323062213f167db231563001400e889896628e2d7b7e000000000000000000000000000000001169392e2f93d071c831b7cf78bbc82e4a05f7b6e733c22329d06c4aba0769201d2e5378e009e966daf19151a9c9742900000000000000000000000000000000140092b33b73472b7a7f8e9617ab1439351152f78604300dcb8ebdc189bca5dcd6d7b244ece13a2c2af24a1647102c9b0000000000000000000000000000000008676cfe15a0007e6fbcc1d7d900f845747bc93a431fc895bbe23abb5076587f369253938c8348111abf6583ed9113ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000198257ee0350232280aa5ff2c095a37faf2ce79bffdfa4cb505c6a522270c3b64d8d7970fe15137d0471f0e281a41de7000000000000000000000000000000000825553090d142c190260a92f972bfe37fe97738eb1bf49969fc947a47a15280d92e5d759fe96feca7990332155e31a80000000000000000000000000000000014470e046b7b29224379c653c0df643b947fffdb4079aefffcd88af2fda33679a9f82e28a897e19bf238cce98832d41900000000000000000000000000000000110073b9bb1050c745e42d92b10b861a9fcdbd2a9f171331f809b8c94163fce7626770245cbf859f038154d3f7b013b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000129a7c7dad0d394ade01926400c666e43f7c01df96c0ee01d1fc66877879565df4482c30f8495d58cf79c8f07ba7e5c000000000000000000000000000000000856c0804822d2336dfc3b8794f33ab11b2bcf45304be69f6abe7afa2e1184099bb27ca50e8ff5d2c6957881249c63640000000000000000000000000000000012783070ea327422376d199ddf5372a8e4ea40f8f1a2968e6ce738565fcdc258588ecbe8407ecea96c626fa5e2e070d500000000000000000000000000000000130e611e35810d447242b8da283e0e4de797d59d7dc6dfe9da6184ce0424c396a51717502b3cf05588ce1cc59e3d70a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ad9dea076235b8ac5be5612004fb2e549ca3003e95a8b5937d3a470c79c21d413568e1096769d445005fbe0d896399000000000000000000000000000000001033cf820bb8ef77630e4e300b563dd1a198b17ff974ce4758362d4911b6f9a5199bf50b3897dbd6b000501cc58909bd0000000000000000000000000000000003bbff8c98ed3f1e5a7f282f4b223cfca702fa9e263c9c88af307ced2877f27c420531858a9c92c96f17c65f27ea8f3d0000000000000000000000000000000007010ada05d1837b57869d68c83353bda1d4b32cf4bf75b18694d05a323ae9576ad93108bf6e37be89e2b247bdfd7a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b544326c5d44231bdf5940063e34ab14116801ff92593fff409cd1bc3b8310a3ecf008c038f9b8e1e94e9df5dfb05a000000000000000000000000000000000ab8c06d72af5b4d5899837c888312427d92652c421b9e1683f891693b300d7c0fb25deb752d3aaf3d1b15ea142b0da20000000000000000000000000000000003c6c02b0bfe20c87ba1157047a163604049b6756501bcfcfc715f33c013adf014a6d8df1a0a52780031c74d0fe82e5f0000000000000000000000000000000014ae3219aa97e6ea1cb4cae2d43075bb181e365a031014e53c42264afa811b4a828850c12f3286918950c9a10d1b1dde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000354afeb8f021cebd47c2906875806f30e61f47ce3ed481002fbbf38caef7f39bd1d7a3e79aae3afd3cfb3ba9a240e64000000000000000000000000000000000b0a1026dfb482622427ebe2fa83b71f14bd720ddc876d7cc71dd512817450f2de03c284c217d277157e0bfc1094b1a40000000000000000000000000000000015e526359d156859e6eae2045cc039c00f2f2b1f14b979ffef55d7797d2c06dcf3c375990bd9dbea0dad7b85086bd4f300000000000000000000000000000000154d3f9415c234003384ecf180221ae56e93e9c690f1eebed7ee063d5de241adbfb50c25febdb59b2c01528797223b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc80112ee014df71381465ff5f990dd7e03271657e3a1fbe22fea597e212159a74b950dc706af28068829c21a4de33f0000000000000000000000000000000016ffe6f2bf7c365e257d496b43248503a1dfd52c34d6f3c43c0a9d484aa51eda456937a40fcb5af0a3d22342432bfc8d000000000000000000000000000000000d355dfc048657dccf4b929d39073ee3f04a8e3837fd81a724794a15e036765723cbb640be7714a782b49782e2c5ee800000000000000000000000000000000007c4532d2d759792cd38ab9b15cac7af7b6417a0b0bc337e3606279883dafdc21e0446e0ceaf7e9ebc2c69e6eaaf38b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b63eed1b3bd84cd4336c7e1e8851566e4478728bb9614e07a350286e03290162b64626d4f8caa3ef879d10ef12198b000000000000000000000000000000001963fcab39e0d2355b372654a5dc94ed87ef709151eedfd1411fafc7efe956f7b86e61adb3792aa6d94542f67af7380200000000000000000000000000000000127661f03ba355e54ae1e47d98b006270b09a2d4b476d65a394cb2085df3f1c80a8d84a8d7a22234580a7b2d08c68f500000000000000000000000000000000002f4feb22a9ee2691e44cbe7993db835ad208ceb8529ae5dab9e2c4269b56fccf325fb3bf569e994c9692447743227d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081faee8ea8ba5e91f6cab8b1fc8ad30285881f1136e5d2fcf342f45cf8f3b88ed0ec7d17bbad67870e8a0ab0632dbdd0000000000000000000000000000000009cb1fe7ff226f260254c92c7445ac82864b1d8b3d68cbbe3f737ff3eb430f866ea477c86bac3cbcfdef376a5cb7a61b0000000000000000000000000000000001da64626e5f09f557d549c6fa18658c32e0ca5e3f9ba30c2a72d123dbd330c461e36b13d1981730555a4013e5ec9872000000000000000000000000000000001314255857ff6c86ca352ccbcfee3394948b5f7309490faa1fac5c2bf6fbb101b1aa52fb199c3624e011f51b1559fe5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000089c63742e437c35c1e488d348f97a20093f198b24dc63c60e8208f0ab73707c10a50b978625194cfd96154e4155450c000000000000000000000000000000001950a8334833ae9cb665f9d712211361cdcdf3d6d7d5d1bff40491054a9aec3decb74aa2b8a6bb11cc23a26c885fd5100000000000000000000000000000000011c971ae8838eae20977ba58cc71ce35fcdf1ad5249d59fcf4bb0b2ce9c050546f9940b3be3bbcb10b37282aee55cb1a00000000000000000000000000000000070739f8dd0c9293ee70511fafd06b0b1ab6b779e8a486ee28a2fa7bb104524b36009beb83bfbaa791bfd615d28f41441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116ab95547ba5acafc6ca254f60391ab04e07c2e125f19da6421051bbb856336c077012eaf8cc03e4bda9b1826c5a5a10000000000000000000000000000000006121937ed728a1f86892a1e66ab589b0d0dab4d0ee53cdd24ff7635af48fb3dd16ebda2efad7982d0bf24cfd9777c8e000000000000000000000000000000000f1a522dc55ebe5297d5d8ba7c4f331134a88347e88dc6eeb7e1abc483b8d638a06bb6550949f87a5c36cdba12f545e80000000000000000000000000000000008e1f0126ae8a2c81b5ff881af612b08e1289bbe1c505a32baf050654d819c951b31c5272c6aeaf7d6b59ff657d2400d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f2cea33c7258b6a6c2b92fe4fb9d49c361f57474528b544b0b3386d499f8f04a4b8b9302497a3899a8054b96ea30e800000000000000000000000000000000013c1e885e8f8caa56658eb118917e4503d30ff6929a2a90818a8006136b4eacd51c8c5d149826f7f2a59f18ec0638270000000000000000000000000000000009563a36d6f545068ebc9e774740773b41f5847858681542d85e036766593e6994f4d83d5574bf54d9a90a945d0117af000000000000000000000000000000000a127553c8b9cece8c5da1dc5731c929928a2f3865e9b8129a864b94972683e2ae3115c2556b011e6b14f76eeac059011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009ce4439a5a3e73b8062f1800f3bcaab8bc848a7f6c246a53c94cc3e8c858c2659aca97b27629c74d5ee021c703e0c04000000000000000000000000000000000798c9ce0c5fedc8e5d07bc57e2086dd7a676a6545d012d169c4adbe63ecf971ddec797433cb642651d1804bd3251a460000000000000000000000000000000012925519e680293ca5d1f71aacdfc17040b2fe3a0bc1915a0adfd08019d3d0da6282f3b00e5ccb06cf85170a2c16cb480000000000000000000000000000000007f7e7e47e383491531aaa75a53192aeb8af70eb66d350c192874e4f465fffd9cca75574565f229783252f906797c7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012316d6d49caaea2882c24a8c78cf9a22d977ae12f6e0c4b2cf2a933c4a897c11db5efa96549a4acc72b3c5f063779d6000000000000000000000000000000000f414870002a26f28549e553a7add1ed4b79fa4c6663ad4c70e9de519428d4bf41fcca9ffa496eba537fe28fe15934850000000000000000000000000000000017c26fb4f0cb9a9d412c515138c4553987dae310868bcc7c25fbca30654f212bb3fd123a384555267295de5dd84d95b0000000000000000000000000000000000d3398a0fb0198ed55e03bd61b3f7301b1909cabb8fcaf7b404fa54774b381c23c5059b39af80752e8ddf7001f3496fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043ac5cb452da2695b6d08572e6738a8cfda5ddd184231d3286b4acc718de4ac2bb748c40d29becb036a623c93064d18000000000000000000000000000000000af3762625ad743c414178536423c15e996169f71122eaf690ce3990f73c42efcccbde7cc90a209dee9f8e99e338b21f0000000000000000000000000000000019742a8a34e1125671f22f1aebde90babe31bf26b1ea30e36b063d3e31fa6aa53e001c4b5dd0630d3461b273e0e592000000000000000000000000000000000016aa2313839ebe9f55dde430caa75faa2f6f51435fdefe0a531beee998cfd8198743b51da99a94de5213d3f0f7895bc41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e0abdbdd5e64a72fbf326bfe327e265aca2d364844e843dd287e33773619067b8fff7278ea245eb14d53627f4300440000000000000000000000000000000012d3296a683f5a1538f7a06e5873bcd36d5d08414aa6c89e6c564eb6e3db1030b96ad9bb3fcc3948cacca8e652a5f7d6000000000000000000000000000000000c228610f01444ef881ea0fbc6d0f1205739fcdfac84e482edc4a1697948b1d93244d3eba901ce0ee7216f11543296490000000000000000000000000000000006990578246c1f863cae375cdecc2c41dfa2313490fa067596ccc17c169c1a7ab73b2b83b0d9a5b2fc63bd1842adfc471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267823cd27b618ec291a456c297f7b91d5eceaeb97022461d5044125e8b82040526bbb5566b5fcd3c9afd756743b9a3000000000000000000000000000000001612be2213706a572d3d764fa06d02097086b2ad9b97a3c351bf8f06bf58a9198109036a43776d4ae49b33c1ff2f04a80000000000000000000000000000000009f15ab9963ba0292338358bceb43d5e58f14482cec904d5afddda501e1d2a7097d05ba14e6e2525c674caa58d48e19a0000000000000000000000000000000008cde8d2d376109aecea0a54383a6e8cd2aac7e5f97a5e0c5d8bf3b5aef888368523fddef2ab8b683c28c473c1b141a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be2a8c20f7e6129f754d6ced6937a491ae518b66c5240a135bb0716e09885cec8acf75117773f8c4e9c125d442dde5c000000000000000000000000000000001990455c88707b2800bf0269c15e78e0e03eec5aa283c6fa1c33cbced3cd6fc0894c3df8b7b0d1bdbdee26286d7fd25a000000000000000000000000000000000811d13d4565cca06de405060d6ea376b92657e9fecc34d751d5453d43af8dfaabce7dffb6a1105c85a19e468d3baba900000000000000000000000000000000012866d7eb581dd6bbec503da9631cc806988c5390e6c5ede4df734c161522425ef8a27cf8324c66fd95f83c8a18605a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f34c85fef6703c6eed85b0022cd1c28b46cefdae09c6ae72a5e0ef8cf3a1a896c6647e325138ff28cc83df999a2641c00000000000000000000000000000000070def530da20bf86e3544ddcdc5920dc01a5ccfecc284b1c7615c978fbf205302d294b8a026f11e8f543cdbf34fd9510000000000000000000000000000000019c765bc6acf3aa2578bc2b3a4a4f5aad4d63175bae3e420a843aed5c6d5ee00856d0b445207ef72f6e94ea11aaebab9000000000000000000000000000000000ca589249a7199676d285573f76a11f1c40fdc0d7e6ca0e5f90826240c50aafce26420efc382d43b8e5d4da2398f739b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e3993148f2064c37248e728bda7f952ed43d7ebb92f0b29c8a298f5d6e6bae46b569ac5f56a716e231f337819cbdcb0000000000000000000000000000000007304e4df5f33f8b3bdf7d396b39535339a8e62cc0fe431492d8bfef549b6e7e18b3b73865eeec09eb774c05a9848d670000000000000000000000000000000004bdfc6b979a2ccb35752715d371b985a5db897aec87facdb28013d587116b91b0a3dc0e63af12a9102134bee588e38d0000000000000000000000000000000004d930e1d20bcd2012bf9d772424fd831b54a18a2e49c2db1ba5afa02cf69f68e3c6c42eac23383647b843830819412d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000242fc169e84cb04d36a7e7f0647cc3303ebc9b4a4848d046c5260a1fa4de8e92c00f43f9f60cb31468b6fa0c0701e7a000000000000000000000000000000001667a670ddc17b2b7ee9777840918ca30e420302b80455d583509fb8a32d80512bd24190eddef23e8d1f3cfbe04c881b00000000000000000000000000000000174ebaf4ea24dbd6ecd32e86d517d856b66b42f5847326003034f0cb7988cb3641a69344a0d3c8f9e0fdc72b4c9975b600000000000000000000000000000000052d2a9fb05a5a45e9870baa27e05fd7a31e6760b5464f4b64612ac784f8a603dc06278abd9ec9a7b2d9e859c3196af31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012ef5dddcdb430726be669f2e6a0badfa1ebc1145624b74ecc544f445774b7af0b2197578116c3cb7097aa0c3d8018a70000000000000000000000000000000005c8333caa2083ced238db58d344ce14046629ac2a683164cd7ec585a1f1d565541a0ff5a8975a85a23a4626fc6d4b9300000000000000000000000000000000067af59ddc23c700d05aee23f6f692af78f6c9d59a92bb58cc9cddb66411061a31f189000e6a66179149df44dd8e1fe200000000000000000000000000000000025b7ee79b9ad300a0944bbe0963460d43b95b8d7a300ba200154262a485839ec0f42a46d2d47210872846f812f5f8ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157e35ab210bd0eed8c13520e205de4673c1ccfdfa46388ce0e5aac2172d5adcf6f55f571ae78aa212ac278f10a5c2aa000000000000000000000000000000000f4e318a625c6ff74c0c95baef5e8f3214b87ac509558f89ed9d76364695e8bd7a1f6eea701af793e71038cc49042c780000000000000000000000000000000008b65e0b6fa3e54c6e204e5ef5696da3d7e62d98a108a6d92a39440329a6dc4f6fd0308cd08c1101ffe5e27526023ed6000000000000000000000000000000000f901478846e605a4cc3c34b83223a31f172b40e8d3dc6c33c5b114cdb75e19300c31ac8c0ae0fdd9f399375fa2996d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003fb0b48c001ae1a5054a8284cac0673989eb10146c463c9cda9a58e36c6c36670e7479d13bb20200ee68b52b3eca73a000000000000000000000000000000001417c52dbf9378c549bd127bc113e64aa725b062e065b4abbe7ee0dc2e0ba766cd49a8d3564f9f46fc65f473ab5e85390000000000000000000000000000000002d96ea029f8cc461bc16c940a704b18f61b6abb83738d340dfd1ce90dfbcf78dcd9af4c084acc060d7a4f54a964b9ae0000000000000000000000000000000000ffcf296dcbbbc8ab3a907c344941beca1bc9f12a14843aeb5dba12210fb1afc83a12cb20779ff9c2706147a239f29f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010968e0ee59c1b362a24b741fa24e94f526315dcdeb34a118ba06a4cd82711b52fe43c9572703d036e262b55629f8626000000000000000000000000000000000f68f4bef24c33a3cf8bf67deb956aff0dfc163f23ae1f77d73d7db92ab0bd5871afd82c2fc855286df81290d6f0f502000000000000000000000000000000000e84300e64a874ec275c51065ff443a1d0c571b8cde6ea6b64860ab838a050106782454d87aeb70b526bfb3b2ffab5f500000000000000000000000000000000031f2ba1b9d67f219f7b3ca567ffe170b720018b8dc84a76f74a5b7474239d7ae2ce7d45e2ceee09282c9ecfa1bd6b441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c24690ceafe25f82ffa628e29a050afa29656c128470a32cbde5f65211bbcfee20205b619a6eeeef4423d859d316008000000000000000000000000000000000f96c850ac8389f1a29ab55485294eea0276112760d4104bc88c7a11e3acca4a55366f55eb4f49585ba18fe9d8c8826c0000000000000000000000000000000017029ca22f428b264fa8c4465ffa11b7ace32019a530b993a964a6101c0fa19567b7efce1549cda5a865ad512c8b5221000000000000000000000000000000001421d2c88aa5cce47dc38ae8e38066a7c8d53f14fa635933059ca45cb7d898f620c69fe58ec2d35ca9736f3b363d1a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010f53a77c7ec5336021349ac04e27db1c514655111f7673fdef9e7f7882e5bb4859a9bf127d600504e5d8beeabce70800000000000000000000000000000000006a4dcad66bb727229b7ba7a40de1794f161df8a6c7181f80cf06b207d4b54174ca4a99b3028b0fd13c9a05f8c6e7b1d00000000000000000000000000000000146586fcd94aab0e00f8ab00a3775b08944cf949e5b80aa711278aa75a039ac8273879578f5be5d6ab37902d2b648276000000000000000000000000000000000b67a5497ea182c4bdc9813be7da5691d1833e91b680ac8e2d99111ab9907e58718b6527ae9e15b7f2e05db22c90cca71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001153783fafd87fe55dbd9734ef2971c49d6a5bf199e68d0bbeb7c2a482bc1d69d638e7e53f8877de2a17fe16e8cc44a00000000000000000000000000000000196cf7ca552109f9b83febcefb2e5c16d6595714056c3fe96bdc9b987268228373c92f54607ec7b73f6978a9ce65c8e40000000000000000000000000000000010aee1938c5f8feb5e50059b9e0fbe32949ad5378054d9f4e4d6ff3223fffdab7f0c744eba63ca5ddcb2716bef1ac91300000000000000000000000000000000138612ec55272e09b7f56c5335684a37caaa5dbbd5b72d4b6bb2487a2621eb779b207bfb662b000c1e1a561d67532b691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000329c1947188b8489824ea0f5c1378c18d2f070206f49855bbcb45e29ff36e1663d9aeb9bddddb0630c9edd43cc41cce00000000000000000000000000000000108c0e7e2cb636ee2b740fe2fcc10f2849dafb872149de4bcf53e98ba7c87fe8391125604c65d9ef5ee33e1dc91cada900000000000000000000000000000000012124fe2eed509f4786a2ce495349f5f03f97bdb58afc112df7f0e2f6ccb46f0739890d4365ff03ec0160548f1ca244000000000000000000000000000000001442e3707d740b9d92b75e70c875f452ce23db0dce240dfaa1cb874ed1ecab568b58343132b52928ede6c1c79e17d4801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015948d862549badd0e40eeb5ca5f51146e0234c02173cda657787093c720a4593970db877f877ecd5c542ac339a76930000000000000000000000000000000000a1449583f2d6f22918f4675158c7913b8b1c37ac2eb0af071a6105c39e96a89cf2681927d306d33641795939f11b78300000000000000000000000000000000009668789e4d6fedb2118cb0954f25680bf50765b17885fd9ecbb475b1490014e65f780df5ff6edde95b4db0ac67dc770000000000000000000000000000000013309b383281f20a4a00c324e13fadcfd5b073ea21636db221b454e8e36e35476e9d47204cffd5bb210b46c8590837a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a2e72917e4d76b643814028db457a6bb26f6ba49e8bd5a92943e9a928d043b5e7ae83efe2ebcb214f57e3e2a45d558d000000000000000000000000000000000e15a41346a7e5ba538223d91ffe1930765e5779f14ffa74c545b755d827ecd47766664d968176a3fcc42cee399515a100000000000000000000000000000000131c324e7da3b1d1798a9948cdce2846100e093d23d24d4d430b268aa4dca4726194fccf5bd5ffcffb81b9b2ec19eb4f0000000000000000000000000000000010a30201e0cea6a71b17071081a92e51149841ab6b5410de881ac9d14082d6403e772acb91d9b780463556fbd4a0ef231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ca9901b40bbd52c153a20561e7a59e4f155fed3a8efb808299879c495201da88a1cd62eac95f28a174df0545f5b1d500000000000000000000000000000000019ff86e033b9ce9131630c788254c5b8aa19edd640781211b5353d513f269e79065a411efd01bf88b23644fb459db0320000000000000000000000000000000018fd8e920ebbc8ec615274aafc5c12424cc62ca4672ff6cebfdfdea3704f7247a82b9575a9461bc9373ac38bc2686bd900000000000000000000000000000000095763c5e23fe263deae9df9cd30926eb10bd6a644feb3a59ca4d636586ddecbfa5c7a6e50092ae270069469737f33731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000191f67fff1dffb867b63827ce6f06a51cba58e58a9645150dbe7000ed52b4dda922e6c5f25998e2b23e3d4ba2feb98ae000000000000000000000000000000000324e3d678b747ad15aed135d493662f774348caa40fb27222c758c99c1d088ae1a6b93a7229beccda308c1de4a9eb6c000000000000000000000000000000000e3cdd3505249f242b43649c77c27f8956846fccaedda21aa0f14bb335c21032563aa712d90ea2fd779e4c998b94b8a90000000000000000000000000000000009afcf38ed6916914ed4657d8f48f2d0aaceb1d0c697e6922865b7e6404c627af16175943139f2477cbdadc3276afc3d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f595dd9e316be096971a6001084c1dbde3cf588eae80ceb5701f03a1469f3b09525d1ed4d849a335c2684546773bc030000000000000000000000000000000007843f62484bbafbd91bd933bd786b40bbe12078c72c9d9092c6a251646e4bdafb907edef6fe5b973e2d4b6a2aca649f000000000000000000000000000000000059d484d5bbd85869d1287dfa5655f89adeaa0d5607c573a32b71ba04808ae09ad117aa79763ceeb3d53c084af7e18200000000000000000000000000000000031a379a5fa709d08f1242d0645b0f1031318d7841121b2da4fc508e29b94bed0bdb792488cd4786017f5295a5e07fd71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001442e00a28a72d473cbe2b96ae2163b402a914bb1a91faf0739ea81c9a4d23924f1172f3b4be6bca27149bbbed73dfe90000000000000000000000000000000008600e6c370e296254d8986903cccabc27fd2828546b00e465a76cc5e77f8703fabff82b5489e88c02e62cb4b39479a500000000000000000000000000000000194c681a57a7fb54c0e8582a077cddfdd02dae579f67df50a569e27e415075f634dfc20b303618ab57f1d11e20feb93a00000000000000000000000000000000194d3df350e3f9487c82006d817c3a16a4d115e688d74aebe388ab40161142eaa6b3ae0e6c07b94f8ce216cbbfde16de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002814f72e642d4685ff1c6dd64a0d70e151a9e05dbc95e12d811347ba502fc0d90ab9cc9f7f1efe9c577b7abe32455eb0000000000000000000000000000000019b5ec11adb99977a43cb05981160ea8d1041f58bee93053f71730149762f5ed8abb5b43074c088c0c642f8d8b7a0c8f00000000000000000000000000000000022e208c8eb857b6b1dac105dbba0350ad79f117d3d6e9ca75ac758e8cf76b475c28c556c1e4d582c8ab23f526a9f3950000000000000000000000000000000002d7750fab5a52ca3ba2c11d3452044971da4d6faa188cb4731e29f83d48b5e7ede94c745e3ab1fff9b54c726018bf051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020e0d4b96689f0158f821cb605befa719b61c775c9a661de6e12b69113a50d53705d1ca9ed1f22a8226714e353433ce0000000000000000000000000000000007c0df3ebfe031b3608d7789bc4b6975e01e33b9b11effcc705f644266ebaeec5c92bc58fd9c1d0a282de7232d364e6c000000000000000000000000000000000f8db63c165fa90453e715a9648750d3748175a6e1d4ff9d4c105811b365cf9886f1b029e9300bc98089fe402b78004c000000000000000000000000000000000d60892d63f1ca7e5da3c7bc160b02104bb5d5ec69623838a2023b72578a63aaf1bb957610b18e9938cf751067ff39791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ead9d57626068c975272098b448e7fa5745ee3a2faa8bc183216efd7f8fa66e8c740b467452752e0f1a79899f41112000000000000000000000000000000000385aedacd1f2f59381abf8c9ab16bcc75d7c79619c1eb42ac8d2eae440f68257cb00be2204a6ffce537255bb2a8f942000000000000000000000000000000000c82dece8246753103a61b5b0b121108dc6e769a2bc04116ac832a7c29d5588495c267e1d222ce74cd178a77eaeecd520000000000000000000000000000000003984b273d4e408aea4ba03beae21741d5c2ad58258b317e8b7478835c06c0778d1317b226e007a704724e55a8f91aae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003f7f16d32cfb19da9ebb5ae2b1f514127e9e9c654ff9d13874c21eaa905745d0bb5ade1818942aa5e04f5fb4a4f6c4d000000000000000000000000000000001788aa04aeea9c873a866844af2ed7f8120da6d4e1314aca6d0365bc277d6a077edbfe3665bd73f57402dd0ee88914cc000000000000000000000000000000000a2dab50f75ee3d5a966f34fe56c8b92678f82a3f511021d5e2dbe8a8acf2d00a8d0d6f7a2033d35ad2fd95412db91f5000000000000000000000000000000000e450139e665e2ce43c8c40a5177a01314a8a292348290712dbecd4024eae2c0c5c4456a90f1b375667b856da821938c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000887a101d3d660853ae6fa29cf457275c2abde75594011a4af48eece1b2ce4d5bdb514be848378f01a73529ca7bda26c0000000000000000000000000000000001a533d895a1a85b987617d82fbc7bf394db327010823ff0f46b0b29464f84e7075184a7602faa5fc67f08d199e3ba1700000000000000000000000000000000149bb4d5dc254c2e306668c1dbeed236453c639c6111b2fad74b091d71c4dd1540aca0ac627a9c36ffa2705cb680e1060000000000000000000000000000000001fe611266ce8487168d333f1b7a0a7f19a1f27b47223722b8fa82a5fb893570a064ba1f5f5cc3dbbdc1a3a3581add481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001144389b54016f1eec4bcf885419b761847e9fd0f7c9b2a51a9cdc9f5fb9a0f91deea363cc1f3e72a58030f13510a53100000000000000000000000000000000174626c2a9e57ff41d0d1f1c53318bc482ccbe5a20845a15e5d77fe297ba9dedad0e52fb8a8a18de1d2e266da8b6ca4e00000000000000000000000000000000127c41fbe226a80693089a7695a4ee15fd22137423942e8ac4493a7b9604c1e7b56e39c555703d79d71d7de65955e1c10000000000000000000000000000000019007acbcbf82ae868a40cb3f477679a72a29de03c7645b338114627d37d437b1bbff5edabb2a1a8278f5dbc4f78eb871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000085d31562b95d636ab26951234926587929c227b9c16d789d1cf939ad1fccfb67b67af86466c43d95518e1245c7bdc9000000000000000000000000000000000062c5860a7efb9434b157d43e692ccac31211e0e0f03df1939977b80566023ee683f275f41043016ae4e2eb0995fc0510000000000000000000000000000000002c81a07054bde110e3ddaf74aa84d807ba273857d3945e394a0a8524f6f3bdd2e3e51db026e08fc3c6b7d84b48fd615000000000000000000000000000000000661700c906eec4773c7cd6cef267658be7f57c68ea2f44b30474d9f2e893db62c4f7ef3214b64a54e852a86ab0e36841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000489b397c308ad508ea1dab14f19f5c11ed38f76617173a1250362c5f41f9abb3d61727c417dc82f22c6b678b5202ea1000000000000000000000000000000000705601673c330a65a4b516c74141d118c43e7f8374351e3f22a6174de161a259dce88c42803caffedf5665beb8239da000000000000000000000000000000000f5543d20e1d06e44d94451bf8e47a274d82a2fffb6c4ebdcd0cb552a588e795930ce3df97dcf3211c2cf79f1bcb64c80000000000000000000000000000000018d5322817b6a780d0fc37e0e2db3085f725b7aa4e64d20b4f1b40feb940bac7401caae0c80f6221df9ae845aca0493b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc07ed168751006e9671613bc92a9adefebbe67936c0bb5e863fd177f284783077234bd26784d938f95b9cf4b7846db0000000000000000000000000000000008e7b5c1d9e23e2938660066a0f6eed6464b63757425f5c75d123990914c3f909a7cc52f4ed2091480cfa307b0888e3000000000000000000000000000000000134fda55c47b0815597f7f6c101a739d14e299269972ca88f0a0cdfccdd9167b8368a967ef834dbbc5626c41eacdfbe30000000000000000000000000000000005055e22f95145e63aec9f495651f2e360e1ff4d4baa6c7ba4986f336bd02494e65b2f90dcdb616adcb9ab55f862910b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019c32b1f49f0573786182a7b3b581c05e55e25f635a216dea33e887158bedb1ee9c4a770aa46314e7ac7b16e6f075ab3000000000000000000000000000000000e5bbf443aac540ab66a86db25c1d05a6e5cb34fbf5cb347965f4d00b1282b87759dbd2955a937a9f67e92f252c35ca60000000000000000000000000000000012b0eb95ce6da766d99393d9f01e01c339022798ea994be45fcd32d8c96e59b14eea6a5a0d5fdf1c94175297fc050189000000000000000000000000000000000778c349d6b1e2ae0f9737821f3be215ba7168cfccc4a83511bccf5bc4f7ae1f2b95c3f9d382491b35a35113f0a8624b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016659d4a5b0d35cf40d35b1e1aaaf04dbf930408f3e054981beb976f0471d7a859e8ff3250877f1bee27e7e906aeb6ff00000000000000000000000000000000056593fcba8a5fdbcda31fa732b81930405b9e34bceee6f83162521761721922e5231724a687deaf2ab5e7ef6abb90c700000000000000000000000000000000189ec6018b5bfb2d5d09b7b307242fc029f34c60e30a4372ccc521524c4c18d5745edd4adc291c5f5ff8adf1d7c745ea0000000000000000000000000000000019228f66fa6bee5ebf1236462e141e4e1b08bbc07a188631c379a571cf5f3b086c7d7e174bcf93f3fc7eedd472c179e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c66addace5e99961bef8f026128719cbe2c58428cdd463898c82de33cf1cdd96fb83d790f2632d5f5e6e0f914debfca0000000000000000000000000000000013c348be0db111dd02dde7bca4e1702c52db76b376e466474b184cb68e91dae08e871c18dc09a793305e3538a30ca7190000000000000000000000000000000007cf33d4e36c92c130bb59fb5087afe5b83c404593dee3c2dd22df20524adaca37612c25eb2e256e2e2e1dcb118704e0000000000000000000000000000000000eb15a38483152dd3c3ec96d27ad8d07356a3f34fe128b34251aefaaf3e9523b14ebe0b6364800330b7a1996c02139dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e8946781d7f4d74b6ca034d57654b996b006660ceca6553313dc5d2b3eacafb9952415eb675089586d43b9adb752be00000000000000000000000000000000035893eca04bd3c5530f878df48482eab6191f67ff41062444379a32e7b68ea4cb60236a4e16ba4ac2b900e93f1591d70000000000000000000000000000000003987238cb5d2eca10dce7d2d70442199c4af82879b22742a4f70b68b47cc6317170804141efee75ca926d709061a794000000000000000000000000000000000fdf0d4de1417bae9e2cd2b14f90cf82d290cb9278e539273cd846698d8f2ef16efcaff9a0068d6fb4c707acbd19e7841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6b896705cd53a1bb031ca0ac7e3e82221460f33b1557f2449b77e60d28288aef47b81cb1be40dc2112d20651c9c83600000000000000000000000000000000018d336b112e486fc054aa67cd7bbd770d364d834ca1f1fab9ab63e3d2bfd964c53ecbbd2a8cda89779ec5dfe8d8cdae000000000000000000000000000000001104fd8a9a6878b2d0d22adfa6cf14c04bb784223b1aeeff2bc8eb280bce00bfd8c3658bd6305478c52c908b07a41d3b000000000000000000000000000000000b601b3d81a2661173202aad276e821adbba2f1746b465ad0531e017845745d2b3f1f972121b6a13dd607bcefdef44d21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cbbeefaea065c55cd84a66de3243b63bbb88b3bcc95194106f42de49cc5774f314d7450c124d654179e771d81724fb000000000000000000000000000000000b0d7d72ee4782ce83064a533ac365edbc9c1214b6ca56a63a484ee35ddeed07f23f0d86f9ba7b9527421ed96961517400000000000000000000000000000000103847d5071512e338773f733430e274881fd2cbc48de91ef4abc3f6549c506acd8f059bfacf602dbd1b316a9d4464bf0000000000000000000000000000000003cc61f71aabfe1e2c135d9508d1d2b557566334f425d139f7a6d5ef556d06f60c566b40a07bf50ae095d8333ab0d5c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001661f515380234c0a59442d7c010ae3d1a1b1035cdbf2b7234153820cf9a92e3311268e51d5db16369a24363927147490000000000000000000000000000000009e8e735f51dc89e2bb06b2c2468dd53ecd58e8c2d0a5d3859a5f289277fd71e72e7f150bb3ef7ea55a42b5838a5cc17000000000000000000000000000000001030aff60617eb181f372b69ad3d1ea53a55bf4de8a1ccf6871bbc940c0e5ff7981ae1637aeaebcea5071e17c287ee0d00000000000000000000000000000000007c2d148dcd7fa902bb932c40ce6f1c92f88fbcb5e224d99f583ededb1805364e410699993039d38624d7aa1cf9a6331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000db79512d8fd8fe4e7eff11b1ec883a40e740a4b08bf7ebebdc31c7cf21f62eea0b9ddb9320ee41b0c8a50a5d162d7750000000000000000000000000000000009962899d2cf55ff1072a150cd8065c1b5d37fe68e79ff4956a18ed1f55d48d48832c7c70cdd0ab481887a62c7a95e390000000000000000000000000000000003a7542b146cb58dd4eee5166f85c64fe0353fc3acfeab029cee0650a9ae292937220c083a3ce45564c8e5d5d4c730a20000000000000000000000000000000002251ce77b5c4b6e7c503fc0b1418be383bdb4002a68d1caff22ac1ff68c612ed722923c0c8f4ea6f8136fe2a64768ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000731ec3415f253a7bc0f86a9564f760eb7dbb11491b6e6690d230724cbb3046c75d29041c5e62f3942cb98d42750c90b0000000000000000000000000000000012ee823a7e4463f78e33599051cdfa85cff07e96009da46ef3989dbeca49ca125408ce8391245477b0cd5eb5d3c839d3000000000000000000000000000000000ab3c2c6f65656cedaa740eb99ee386cba7dc37f8ad63e4a9a9485591b6e49d8fbf3a5a3802a40408fd1c5ec41d3c98d000000000000000000000000000000000b2990209540ab2156920e52b6f93893377373c16acbe21677ddaca425334f6dcdfc614f533afec45d3767eaf0cd1f4f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049646b7eccff3349dc143aada88a2fffb1fd84f8c2e80b87aa882d30789fa145c2573d4acb1735f5e70bf05949b30110000000000000000000000000000000005aeaf963ab3e5623b7de4854559e9778edef9a6f53e3493910bcb5dfbedc8a982bdf55b2b0dbd5a7f2131c2b1ff8eec0000000000000000000000000000000009727bff147cae9bc010b70710f1cb7d31ce8e55410c7ff2e650919ca2435d54d1eec8deeca4eb9cee68f2e4f0fb962c0000000000000000000000000000000007700b87a79f84d77b79f1c297b0decd16d012e45d976d50bbe39728ffba94a687f86a61f5eb79e2ea66fee3e8304f431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7b7b6045249f57034eef7aa38ac269d8494373ce19e3790fdd0f780343707c472191ec0b9401ddf21af84ae42cae1a000000000000000000000000000000000d47983a09d102d71fdbf9e02eeaf515973422f4c7ce6dcacbc25250ab1cd8baa5b6acbe863db83ac090dc84d68763640000000000000000000000000000000011c0cd9c08ba860ee12e7a247d6feec77d13658a3cb43ed0ab2eafb713160962e1c2c9aa83a10b11620ca505c936e0e00000000000000000000000000000000015c802a6ee6c88bcdf486514b2762df039a9b6b3d7c30d1cd26a5f7ed794d2c6b4a2ee46045ca90b00d21992bafe8d981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000115ea66480d6a1baf6894dad0a7dcdea4a2e83232b2e14daadb6ad79bd8ccc4f9ff946a39f9c709f036349fb4036c5ea00000000000000000000000000000000017e21ff69229b1a0f0f91bbeaf72dfc81fd8577ce044072d355adda4bc041d76e4e140fd7dfeb9b97560b9859cfe65b000000000000000000000000000000001238a9360954c5fdaff8ab0041566be11edf76acc5226946024d41dedfefd0c524d51caeb53c296b3749fb0df7b64ffb00000000000000000000000000000000109b068db4330ef999bdfef98488f89e8ec038e5e6f536812b8f30a1896c292c6f18de97ab383ad7433b7dfac36404961824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010a639365357db31fdef35065c3b032e6417f15d7452e7514be10c39360d75344943e1440c2b54e8acf3c16ab11dadd50000000000000000000000000000000005041849f2d6ea6e3e440658bc07891045b5e9ef4987d44a375f955e30b3abfbac55eaa36ea81be8bfcb1cb98f3230d6000000000000000000000000000000000bc2624037db36737824be7805b7e8dc4cbbe495497a48645007afdf68192e8c617de259268d7babdba8ad5c25c8272400000000000000000000000000000000193db7076e86563fab664acfe31aa963dbdb30f07d252f22580c88a9261ba9ac2890d852949294e0cd6853b060685ee11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000396b5832a0978ea80d727857d243ae6424d61f0ae505bda880aadd22f0f1cdf6fbfaf19beeb16d3e1c62a35ff700b6c00000000000000000000000000000000056ce2ef08387c754c2dcd7919ec36e06cf2142392b2c8226af3a1f454a088e035fd4a37ad7b7b48a7372f85906416240000000000000000000000000000000016369dcca2839130df1551e596520e06a4bac33bd769509f45905c7f44ef76c9a3c0100110f5386017cfa2aec49deaa1000000000000000000000000000000000be654adc5e8ef82bb5ab25e8b1ff1fb2b564fd4b50c965fecc02c301e3e7aba58df1ef72c23d9e03dc639d973ef243a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000151acbfa2c8783979960cf61e509641c8fd1836900310a10f0d691cc09030f6baea22f6f153a69b3b5aba1d0f1a93c8a0000000000000000000000000000000000894e002072999e0ca7ede8c726f4c75cc6b82a31bca1740540fffc0e17327f2e642e2135c9f89da8ff740d803fb6470000000000000000000000000000000012be8168df1aa225e871256383297e9cdff6127bfbe92a042fab85c17c5599398b1f53a1108108caf2dc73e930d3a22b0000000000000000000000000000000002a565209a5908151c30af8dcda0b5934d2db6fb37e483c11dd787fbd224192d8cd10b571cc928ee6d616aee8f8782a01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000039d47d5c3369d1e62fcf47d71c811861a5b70345b2becc5787b3e3030abe72295626882e5c9754b95b76fbc213249810000000000000000000000000000000019763951a0f9ac885008cfab44f7825ced5847dd38ab656d6d89ff547b52a69698a577eda8cb610959be3b73775f0d5b00000000000000000000000000000000126d7bf11d1ad4c15f55fcdc340a5c0f2ff945aeb1bc783d6f4bbbf6603e5285630a7d0f34d990b4a6b07cf102b17b8500000000000000000000000000000000029b3e43c9054e0b1653e9fccd4d9a5d96b2e5a7b2504fad8ded8120ef5ba0569c4c79a1138a535f9a851aff6c2204d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157f47295f13df2d2627e6869b7cf056768b9426e8ccae7083bf2ca4a5a10b45b09f741637dab12a60c1de3a85ca0a2e0000000000000000000000000000000008782be2f156ebb382d305ab028ee9cc28976b8f9bb9e07ec91b975c7f0b39ce413b857a5741906892c26f8b4eb0423e0000000000000000000000000000000008c8d45ba88eee71a845c19dbcc97c9b261e9e13937579169fca22c1d9be48e413f7c9b4d38505316a868a027109958d000000000000000000000000000000000f24bcb062e33b2b898e9cfdbd20d7cb7177b868a69fa2ab829f310053bac913059171f56bbba2d4ad6216cc0cd81bef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084698bd604896a0cd2e0eebd4e382e167a6373de1253e546702bd000db04df8117f53abe1ae7344201eb3350bccfe570000000000000000000000000000000018bf63cb594d35e52efa26526fcd2ace057c8d3ff4b969678ebbad585d519532b0ea6b74e165aeb46a1b5867e39ca290000000000000000000000000000000000b2fa9c1340898f1c55c3b67328ee3b533e3f7a052f52a3bd4fc83bcaf12e15c7f216941daa312f653b0d35d86297ac1000000000000000000000000000000000dbc5748707d709d13c78a7b50d5ac5c842fdd8a63d07b9e3e86d0e2fe5ab4b643cabff581e0a54f6bc21eb3c5c98a041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102b7cc4aa54f08da7fdf99d027606114a1e6ca0776be7c3357de89c0c0aebfab12cf8767ed6e16760fc9d5dabb542230000000000000000000000000000000009ec268661082a56ce7149534dbf3027a0fe09e503183e96dc185acc93cfbdf407becf9e14e771d0bebe0dd5a42e733a000000000000000000000000000000000ad4e3af58aa2e2946ca41aedba984ba8d7f09cb667eba750e9052a3f57c62d93eb0392dffcb56f90b71e98d20163ee000000000000000000000000000000000038591cc8ae93647176a0ae5cc915ac98ebd1c9a442497168763217bff127bd12a55383a2458c1512599312187c0b5fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a6938f5c8440af210a5036b70aeb72b522a57fc800960ece6e501b84a6116239ba7bbf26c2eabbe447170f1e07127400000000000000000000000000000000149bee97d410f0c4b0d067fc66d83771758e31daacabb2d5ce812dcf2a9383a44693b86b1904cec13bd7b69b6fb1c90a00000000000000000000000000000000170b96e381c3c2f9c47ef9135541916795dc79d62b27489b0963f1da673a889e6d15ccfe8e04cf5bfb7ed10ac2b2fa8b0000000000000000000000000000000011fa0355ab6533c491c5fdb126ac9e0f8caaba2c0df9675b14e4d6f681894580dec59e00bca329df8db20f7efc7e19491824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001254893cfa1222e898107687c9ea1d456d871933a486e72587a57afe42d4c7d643934a58e15b8dde13b181b4002431ee000000000000000000000000000000000f93889fcad428b2d587855e449ae811b6ebf78fac045304507d26c876514a6d5aa716f568606c3b0352e5c9d556cda4000000000000000000000000000000000c862a99c63cc4f730e364806a6caa7462d63376e6de3c9162e5765fc40456b2889ca3e530f3387b3e4c575099ae2ff1000000000000000000000000000000000ece604cd8c1cf5332695f93c06f8a3c0b9734ab3caed1f1f904e670605064b6c18d6c4e82da5e1378cf45f46214d2151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c47502c58488e45bae96614058688f60f75c93a3aadc2f2164183f16fc92bce8422217e99bff12f137905187fb37e73000000000000000000000000000000000818f48f961c2237d0500d09bc4ddd12e8989b277efc86b23fc418ea2e45de860e20d3bfea4fa36542d5dcc2fe81a26b000000000000000000000000000000000b59c3b766096df4e9aeb1aea7b6306c593b33a8fa69dfe6631a77715fb268e2d48f909e3ab0efc22a40b0def89a16a9000000000000000000000000000000000e3ff59260ef6120087cd3e6cbaece3a40f498be54e77ae8f90643e831fd521c861332d017b7150e3ce9b61b877794e01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bcf01731aea813193f3f12e1fbaaccedb7c66ae7b589f168b7463e454e4af2c331bd4a3f4e429d0a2e5890190377730000000000000000000000000000000012f0d056d9879cefc792f0df1c1e28a6e41180eac7fc7d6406fd97149be577779bd37b6cacbc4721a37777b6e1187ee50000000000000000000000000000000004f34e4b494b21e9005d0911f85218b7fad7cf6cdb6809553e61bdaf920a54e68720534f9fc1196458f12d044fcdf6dc0000000000000000000000000000000002bc6ff2608d055860e191b3eb086692415d42a2aaac2c4fa6ddc20c9234eb81fcf2f96b22763de32641bce904eae8b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011120a58672595b8efe37faa92d7dd8c584ba7e35437e74d5a6055bf894978ee198345d7ab8aea8946d2c9a2f53a93a000000000000000000000000000000000175ddad501f60b4de06256295b581a94e3383df2a61994e5e95b87a38001efe0e20bdd74b5f206ef7e8686e4ecc98fbe0000000000000000000000000000000006e57d04f12204af70e29e72a78497c86242c852615656e090dbd11cf4f39aaa38d3b9fc022a7f74a64606700b9c585b0000000000000000000000000000000012a91cbce10734eda74784ab5eff42faa4a730a31e8710c8b0c0ba65856403a22ce556ee4d560c429e55ca2010b711da1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e38434db2ae79b97486a521f10d89ade3c1e4122e403b4fd4f2bd6a8fa84d8480362b7463b3373ac336831a022d0b0000000000000000000000000000000001186d9310ef488484748ea7faf460cb04c951b041a2c3c9ac8c6f3293cea1d58780f82f9d7e579096afe7ed3293494ce0000000000000000000000000000000013bcb4243a8260e570bbfced687a1ceb858e7fc21313f186cb5480f12566870562c138843080bc063aa54694006291ec0000000000000000000000000000000006de05e8988cc16b3d367a341fc33f9ba2b7d900d45f09d23be924c3b18c0caac93b4a08086bffb94797f9172bd06dec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000420663488b35a491c7f50446e22a4da1371269d2da92715d0d5c6d2b4d93ba5d1c87410760790f1e21af7329e9ef06900000000000000000000000000000000139e3307f1e501bc20a2651effb35d68a015ba6114992a34a78072df2a4c6a04ab2d0d99bc7d613421ed944aba6f0fb7000000000000000000000000000000000faabb750ec4c63567307eebb95c60c81dd996cff14ee1ce3361948bbd404bf07983b564e6b7a46c1f5e95f912f521cd000000000000000000000000000000001272a4dce01b01a353fdd3a7d50e1bf8461e21b8860c8a0fe0b732db60c8843722dc5a895daafbd641893e749d9171d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001c542021024ea92eb805168b2c4fa23c8d08eb5f7a498d4101766985f235d28231a35e753a9f173f0a200577338b935000000000000000000000000000000000caa5089b70dbe494ae28e68080f98c1deaa01a7167f72fa4adb4ddfc19396cca85a94a9c8fe46c85ede833b90657ed50000000000000000000000000000000014ae68c0f46636c233777459d18a686cf192722708e49077640ecfde8296ce5d816e599e272cebf3b0c71306f469e8380000000000000000000000000000000001054e3cb3910fa72eeca0c8bafcd72df30a0c70a2443bc90035d2e5ecd71ab1e04466b22b14b2518383373938136ca51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fd9ca2adb79bde0d55e765febd705872570f46e9e544badb26b57e7be63fb261f25b678346203ceb0628fdc646233970000000000000000000000000000000018e0bda32d5d736522feec43d6f63c2e69a55a19d01eb7d192fccf7a9f90492fc8f1b06667576042e523d866630bcbe2000000000000000000000000000000000ea94b95b21f7fa3035aca5e5d5599ae5ed4a95888f69b551a4626f4ae712a7e3f2a5739e0f0087aba716f43826e38b00000000000000000000000000000000008a3964da6261688cce2137861fb084d5bdcaf3be5e41dd4121eac3ec3db8cec534e2d447a6eaa91f3b4eef8f1f2df521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a217e5b5edfd02f6f99a5f525416932f97cc808e6988d897d7ff1bdacdb034a3f6020873549e28925108da3932d05e500000000000000000000000000000000195c2f24022b05aa87eb8ec34c664af9bb27f79931b51ca690b8799070ae8a179b7de65e42a3811706a5467ed6dc800b00000000000000000000000000000000054fb9f5b95c2e685540b840c6ce5b143f80b755384eead683a5b05602e2f893c39410138af86fdc42267255fb55b0870000000000000000000000000000000008d30063022f4ce11e7349871a1fc8a82dc310fc96dc63f68f51f50be171c37e8efcd09c4e207e648746624038fd2d631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001219e002cf573ce860c209d5239a119275adef27766f8a80f71a174a4e3b8bc78c10c9f50f18b7ec05d20642c93bdf84000000000000000000000000000000000a731847d4ead262109a4b2da537f507c47cf8bd0d223f7961196a3768f14e17347d73cef5b095ca0cb3c9a297eadfa3000000000000000000000000000000000d862192b4ccc5f928b6b462b06e277aeadb9331a7b583c5a82c8dc9c0d4824eda570447ec1433c3b7c086455c3ed1970000000000000000000000000000000014a95b3999bb3cea421dc78d6f8d52c0322670dfa0e3d9f1d2477ff3918b94d86f7f7c5a5562a7b27c938dbc3a93b9bb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004dc0cd7b46d37d091c30a0cbb48fd0e987560fa01bc0d8ffe33a425c5f0b4ce2e4be1ab954da8e005cbdf8735509560000000000000000000000000000000012aa8048d743daa19208a56224a8f833ba3bfe48d0ecbea51a7f8e577f13ca81e41fd8110108bf78b6e2f559721afe4f00000000000000000000000000000000041f51768940f4939808f6e3bdb703b9ef906dcfa6c3d8804ba315e1f979742f8876523fb34b4e39c3f43cc542b07b50000000000000000000000000000000001485722610e27dcd250d2888d86dbee47a3c19ffd00771899f497b85a75055d0f3e3fb55aba760874689d7f89dd24dd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001806068d9ce9371f8913b44cfa2eb0561c137d4e8fe75aa4f0724a82de02f6c4f3d4c56863f11d0ce9d897c6ec14c2150000000000000000000000000000000011891f4ceea81df9c4cd4c981bc8b9bede1308b814fdeb32a4cb46bb78c239999669cfc5277951ce8dc7b5e0e3015ba00000000000000000000000000000000014484c59785be3c0b3e2f39adb4bc58a3e050c88674c72ed8b70838c62e3f8fc069b71124cbd7325db5e2569d06aa163000000000000000000000000000000000b61153c4e58ea62a32ac0557c8aa3e1bc63acb30e62d48e1cfc2df2736fe65a3e9b77780a43081ebb987b35378073cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001596eb58fd2183ce3fbd12a453c2709e05ad578864bcf4319023a8d9130d1713f11d9d16d876cace8dcf85debd45b4c80000000000000000000000000000000019536767c164b10b490ded04d887e0f9abab3aa9e3ef41e943c6ae3c5cdcecc7c6f35a85bbc1c24c87bbce0917ecff9e0000000000000000000000000000000002d3561d12140f2a01ac12ed3266b4dfd91bdee8e4f2e5cf3244c46012ca778124ba966e0b5862309961396695f2ab8700000000000000000000000000000000049c4607dfe57d218c111c6a550ef05e6030dbc8f66a9bee77d2c2bacbe8795efdb8523f3d7efb277faac75086f329a41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000034bf7bc3f17a83272eb2b78dcba1a1561371c0067c0906769e499d3f7163561e5871560329581bc633721fc82fcb9800000000000000000000000000000000198abc566c2b50647994cad427d64a6bbb03ecd6cce2ef503ec88159bcaf161346333099b58e7a8b174afa4aa33d9b20000000000000000000000000000000001561a63042f604486e1a8588a2aa1a021c0e971ff1ee39856a94a6d18fa0d9d1d0da19085bc5e0b1c7274ed2974091320000000000000000000000000000000010703d5ead1b741421abce2e23c090e2621c7c0fb8ccc2b1e7a20ce23af9f0bd93f89d4c8d6ad47945e3655610bc01421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ec67a203a192d981b8759b259425aff045fad249a769c0bec107745a199d31e1b4ba40d19c1208b1b532ae6d3b0cd80000000000000000000000000000000008334ed637b214f5f33c0359d6540405df12db5d707160d5bbf642256d94fc2301b6257619b8f8aca167757cfa4f24a10000000000000000000000000000000001fe8523ad82924a4143e12c03757ba53cb479a51ae427e79f91f0de469cd0fa8ce793505729706c6b4de49f43b3ccb8000000000000000000000000000000000abf6764c325e63b010f83c8de59fd3f0bc811b01ce43739015e3d352dac535f929b7ff0e6e2791f4590eadd10bbe04b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019ed60136b65c5df608c4c5eb0e7f91ee80c0233642013e0e5302c4fe3298ecd821445cc60f9ba4e46701cea1b3981210000000000000000000000000000000011ea7eb246d65dcb87e53c9f42ef0b33a419a67a349b3c3fabc47bb4abb84ad9dc319ec262fff0dc8a724c028b7e3ca1000000000000000000000000000000000b909897a2e0f0099996b70854018deb89de6bd6f1df5dead6b678332735390ca6301cba1367e63f4d42cb3e6668945b000000000000000000000000000000000f5cfdc46bbfa817a776d799f22c8c4c9989b65b3b188d9040c765b31acabb988058f8285e667d3b6c8d69aff00a1e0b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ea8cf19f171bffcb398a648ee7882827870759fc3c1c14743b5f16ddb43a99c58394d52f792b2942c3488c55f86aa9000000000000000000000000000000000a2b8ca69571212fe07b89f7eb60c0e8b1f14b78601ce03107fa23dc9d04ec5c80b2cd7643fcaa42d4951f072131a41000000000000000000000000000000000124054e8d823ef41517902422d316969faabb314371f88e099ada9dbbe53a1bdadc0def8eee2399cbd7a1e51993824fd0000000000000000000000000000000017e2c1c1912cbfa38ec772ee45673e9ddb00416ba62432c756528c9bef3868fe14ea5953508846d623dbfd74715841871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba63691d45869210e4d5c88c4118656ba39b990a3e84d2d4f307a4505c22e877ac9fec6e798eb77a101b8418b24dcc000000000000000000000000000000000497173e0f3babc0301e1380bfaa9725b5965ff0544f64bd9e53efb47fc7d91dc55383d03b0b262525c725032a2e847800000000000000000000000000000000071559248baa95962c3b6ab834b1f785fcfcae2fad1323b4845b589cde98baefe28b5ff71ed99391549835f08afb5806000000000000000000000000000000000554bd633ce9c440e266760dec954d14074c4fd57899bfcd9007959252ecdda9ae63996eed30ecf3b4c24e8bee6d5e361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004227229e86f6f395462f00d6c1a7d380684d6f6d08e2a873573cda75b2b856164d86e675489ab70727475180b83ea6e000000000000000000000000000000000429e75169e9848674ce1cf7149c6f22a539152283c2bba38d1d9546162a1e5f1f0010636755a0b1e7e4cd012e0abdb700000000000000000000000000000000150733f4cedbd2fbd9649cce0fab4337f7855a8a73ecd406094505adda8107f234e7d36e1018cc67c1b4bc839d056a7e0000000000000000000000000000000013a2a21696c04cfa8bf099db8fc352417f54b289688023ac7e911f0c6a9ba21bd15d0dd39740b8143e44f9abc88188d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016885004c57809e7b29fd06fc2c207a9280bc522747cdbcee3cb94362eef81eac9e864ac8013cb5d5953bd1be19dfcf6000000000000000000000000000000000c6add91546fe4fa27f7a164baa2f8f3b4d93dcee48177f131ad83062da1cfc62673050bf486c5b1a47f01bd288b6b3d000000000000000000000000000000001978f26a82445aa10891d0fee103ae94e60bf1a72cd8029656eee28431235ffdd2dcb467d5f936d4e5a6a258cfa4cc94000000000000000000000000000000001822a2574af71405218269e841ac6a3e849da45ad9ce95a27e7933cceb32846fd945b157ada4b670d9cecdacad5cc70c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017e0ab193a264c7199250d280aeb69f8d99b90538443a4174b0fab1359cd1353ab5060453345381344a3397a642b6cf5000000000000000000000000000000000e155af008ed3dafd0976f1f50d18aed8bfaa859a1f3b1804b07cb0986700f2b9e3703165b6482927d5b10803b32b5b700000000000000000000000000000000171af473540c901d42ce187611fc099c6296480807f9825335e0d243627161342ab96e02e670d4efe7cc9c476f0dd411000000000000000000000000000000000370e24d977a0d91a1a2395e504730a26d2fc69a37427e371df8a8e842f94ed355b1cb09bc5b1e7018fcbdf7113f70a61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e3cd5caf573b0b8435456b7db83968f1f86743cfdc2c20ce6c49862f87095c5c8e2a11608390cd6023c1f7171e2385e00000000000000000000000000000000126c0e6dde86e59546630c658859d64c39bea882dede4d2a24f12a0f227071e8457a16f901cbbbe57e01b33f0df7fc9f00000000000000000000000000000000164b399c2b8b049e694bc7077fae3d60449b59e917236430a4f26bbb5a409078f21f98c35de7c265b9cd18c608be760000000000000000000000000000000000184eff9698c49a589a1295e4e4d9b34ed4a8022cbe1e74c97c501519f906cda51b45ab5004091845399c3bb5788b420d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001282b4bade13ac9beb21c0ed9b0d3ea584902b3c21d4fa9dde516c805331971481bf981195983501a6ebd28fc042289b0000000000000000000000000000000001ebb2e77e0eb0143e6b8cf248f725c3bdba886241fd431dee11c038532291d8b1c4fd2e7afece625108d4f4fc5f3a840000000000000000000000000000000005715d058973e4ba63a5f6ce8fad6f9e5336dddcb585bf812f25e37328fc12523175ebaec670086a46ff43a34089d85600000000000000000000000000000000051193b285e46080024ba0299cfedb52708ef5a6034f063bb35d4a5d3049301e8ba47702b85fbfd60f7812e4fe1938651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cf040ded64a384db949a456fbc85798e54fd850b1270c645bbddb6d31747a4a95d2d140a282e1047cbbd5f7e7024ad4000000000000000000000000000000000fb86c3885369ba3b7b138b085dcfd6b3a8bfe9e515a24e51fd98623419a9cc317e94255b7edde66fb5ba862b07eeab900000000000000000000000000000000003fc6c6a35063a35deb6db39c32251310dd7f3b4113832ca1511624df08fce6a1a0baa3d2d3abc7b925d36626e9893200000000000000000000000000000000167b67eba366380138b2631513d2a8c8c5f81fd8bec80fb944f70a5fa1de8450d6d8c69c726156a30d2871c487a3c13d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013b43a4455af23d4190bc53d47f0639ad47162ab9f764632f9d665d173c304134c426fb1605b16ba1726e4bc937cab6e0000000000000000000000000000000004e74ae6145b4c3e04ad2616ee57fecb6edf31111d570ea8a0f006e041dbab4dbbad1d0bf5ad9f5325d5e7e8849276b6000000000000000000000000000000000992e978c1eef0d5e3b5ee5d183cd923a016098536d54b53dda5fa850a7aa8e8e1e0a60e64b4495486e4cae18c51bd1400000000000000000000000000000000169323a1ec687f6e734d77c5de493ee5b092ad5bb1c524610e48f9729ffc3fd35bec3944071c51828d8a4365108ac9b01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000047b15d5129aa3b51e8677e28d7f42a4c4d2a5d3d0921e174a6eb165a5d96765bc2f9f8e8c38bca79552848d2e9f738f000000000000000000000000000000000c340911aa5db25cc79b264caab3129697712f8136c2e723425223ee8456ffb08db08d694a36aa59fd223b5cc95cfee7000000000000000000000000000000000e82e27ab63d757a9b90347145e6bb7de950754bbbc915157f13156da4b9492fa860073ef15c1e28f6c7a0db4099038800000000000000000000000000000000151176932c72b7425a7c6e4d6f570a853bde1c8bdbbef40f18a743bb100b4a037439314b839be3b246f32fc8eba174f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009cb0ea143ed1edeef1a4e2b46a95b92e693eee9165dfe0447009823b134a68af564684a1384d7b0620573001f9ba1150000000000000000000000000000000003ae2466b28224a89eda1a6b3bdcc9e891a321bcff23c204d9519f29f2fe5b3f5ddda5ef80fff7f23de6ceed5298ffae0000000000000000000000000000000015deaf4751dba2071431fbbd70474848b18872cd6f6d7158af0f067b4c4dd5babdac7ac68360ec4bf7d8e61353693aa700000000000000000000000000000000083f6a38fa522a9fafa406d49a5f0fe498c8a6a52d32fc19590bd78f8ca043ef112b72a1de3d15cdbdbaf6d88841e6fb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009265979074f4f889c34e9c48010118004954a5a90d84064501ada8bde715bce4a625116b920d88a22df6b9ffd008a4d00000000000000000000000000000000045d98fb750ed9174977642f248c70aaac20da2d24bee02e4e90528fc5abe44689e26cee2343d90076dd4a8efd95f06f00000000000000000000000000000000070ed8a0064193d012d85ab3a63f32bb9953612ac1aff8b0ab533dd4fd12b93631359a28c50244bd31cd534364ba7ccd000000000000000000000000000000000b2d3c512f019ac2f14b3b656f739e1f5250a0f8149dd7ed58452477ea2c6e4c63918352b93c0d5bc998b782f132984c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000018826051ee4040d30cdab952b102a527dfe311d98863e5fe585bcdd6931e522633dc536015e77f07b29c89ec9ce31130000000000000000000000000000000012a57554408570c3025d8d02a22c1a73009e2f86351812529e12f7d54f6b32dc50deb47b599b7c5d9c6c71dfa1fdbcc9000000000000000000000000000000000e2e64e5d507ea00756a121f988b58045dfed499384cb0d7e19011c43a230d9cfc0d920e12d1ed6970579676ca4905300000000000000000000000000000000009184eeb95f3a7c0d0cf10555231cf3bc09d3cab40fc603152d4fa4f00d7b533f486486d671293d7d290fcd601893add1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cfd112957f6505f3108f08863888abf525f64118d7a421c98d8551a84f77f348e9171aa48dbc39b5b690fa5df9fb12d00000000000000000000000000000000093d89559bc88a157ce4667ef2da6784e6cd7bf19026914feb09c1bec2fc5d233187f07ec5fbda74f863c2feda8327840000000000000000000000000000000013b511ce2727c7bed5ede51ca520e389b3e23968f47b50264ab4fd9a9179c462c05a96fdfbb3532167e270020fae863e000000000000000000000000000000000d2e6506bfef756c04e9d3c4b9671103c76650bf011f3e9ad372c545dcf8736666763c93fa6e7e859ef116ecdee31fb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5e8897efb30169c85c346a8bf1c51be5ef283e353246744af4093847cf3cbc7433d91dc16c86c575129a0c928d3b170000000000000000000000000000000018cf36b7cb42ab433d55d788ffafdf038d19f318fb6df9c2f344e8c780256c6fe5f0ab07baca6b682be88d2f28af9abd000000000000000000000000000000000f3dc995c84dc8fb8cbe47d882d483c1f2fda52744b9714d0bdef3c861ac6d4067749150c1208dc3c9a3da6aec5c0f4b0000000000000000000000000000000004d735b846b627b9683f88f82d65a063ef7c7fea5a51942e47d6004d7b24c8f27715d6e1a66b62226f7c5b02c4449c451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e38664c56e20b34e08e5f8fc856282078cabbbe0a207193fa7eedbd5f37db403ce077767e45d85f9a1bbd6b14e4056400000000000000000000000000000000149d6686cdef272e5acd31c507ed46223977a41de9a9d4acd01dc4b68e2d743a9e5a8786eb920495974f9119ff7637b80000000000000000000000000000000003dab75dde3a9db93920d92ebbb7743e026887fe4807a42d4f55aabafc7ab7d2cba7d3e4c86405dcce8acf5e4280c1c5000000000000000000000000000000000b17b81ba6e9cc6684ea723790da5fe36786f2a541183b7aec2f1660f7f0475edf34425f0ae24d243a123aa87ddc0acc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010ce789b7254f9f44fce5de2c166bffecea342150f66ff47472a2428d767756dc098c53018970fd18718b39352c98d1300000000000000000000000000000000117a853bdbdaa0304132440c4dabfb48a04e6100239df9c3c30c6d408cedb60f1c3875da9da472de1f7abceff52d7f040000000000000000000000000000000009cbfe9a411c3bd5a4d6cf7f2b1e392d65896bf4a98e4e6bd2e16dea7d7365f2f777639cbcfe01a41858bdc01540941e000000000000000000000000000000000269f187fb68af2dd9d2c89ee6b42ed1e8e52c01493b4f949d9c3e2478092da425e0a7f7ef3d8ab87511cda32aacfb0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008b2a69e0f50382feb6a52bec5a619a52af2567a71dec7df9733dbc1563b9a752e7ea037f81da573e070e55a1b9f29c5000000000000000000000000000000000f2590761eb3bc0016d9706ca5951b70c5a0570494e7136e1b9d2ed5f4f852c1ee8c80263cedb8ee0c7d06e76479a2e600000000000000000000000000000000076281189c987570697535506aaa7f1637e5f4ce46ba9cc2ea5db0a902b508c7b13172bb5787d5476f11f8d7770f526800000000000000000000000000000000047ff3ec2b995c447ffc923087edb1591fa3c0ea93a632eadde47398fa0ea0a1d3774e99b5d159d8f82c0252f08093371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d79de5077cbb627c5a4bc6957ea5d00fb5a97ee91aef69d8d77e1b8ab105b099d98fc1024c1ad219de4316275c9e59700000000000000000000000000000000166f2820053055b369b667e5402b080e0cef6b5373302d03861ce02b9270530de1966c8ce87487027eb416fc82278bf0000000000000000000000000000000000aecabe7773b36a21d1de641d26e13788df5b395c61e94d6aa935ef3e10b70a75fbbacadca94c62f780c7ff62385c68a0000000000000000000000000000000003c01c8de89b70754cabfb6f00e29b62c4c5b1f7b9edd06f7990a7f9d032beca685a2b68844b3b399d74f483e9acb45b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fc29de8e6307b77c2c08484e26adb64266acbc071f2f3a43faf7f4ed41ba2f954389a357b5abb49c7a9bdfcc95cce020000000000000000000000000000000004fee77a61817636917db7d8f03babdcff8d3d1e139d8874a1ad6c3995fc3d58969ec5c219d76bc4d8efc2146aca513800000000000000000000000000000000197a1304de74431d6771f9e38fbedebdaca6d8830a165ac289b012fde61418a8889524f4319a3d9e5e4c0223ecd063470000000000000000000000000000000017e6011a6d3cbdb9891a56fa7ea32ea2d89b49b1ae5739dba51dabc0035ebc90b7ecdec4c609fc0034b26f408252c5751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001429a08cb8fff05e88014c2729808667fd9d38bcf1b6f405d20c4471d58fcc68b1cea316d8c15c7d0aabd03d7c5dc675000000000000000000000000000000000831a636f98491333e71b86d86c75d2bd959c04df0d74c3d96fcedbf9c0a5139e88a229b20a8fe52fa2910cfbe68354e000000000000000000000000000000000b3f5aacced744b4f9a85b9a60977606a8ea5b6f20af32a5c9411fad6c7bc62ac4fd79c5b25c90e74479f21191ba4a730000000000000000000000000000000001641a095d25640359111cd47b62acd27318a13f519a62cc652bdca8fa5d45c50dbfeaf4846a9e55428886998cc895a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044ad2ada71dde708fc35e2a75d4c92ae61b3da6187fec5a51777c1cfebf1a00ef24ef5fe71678bc8c756d9e6098871c00000000000000000000000000000000036daa00011b813f90faa3a28e5f7473fd0d0a025caa3cc2eae3b07be9920bbe256080a0c2745e72278381391af67983000000000000000000000000000000000e7f2ee200363c3fd0849b80984e5418535c0156988ad4be3f682f01c33ba05c537371345569c23325c5544f95dcdff9000000000000000000000000000000000d50102e87276992e31aabb20431273357c2dabff73de366a353a0e42c0147c0d49ae12d706157aa40b9636bc467b90c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000005ca3568c7e0d73e64ae72a9569236e9e9e7c7adc75e33ac56c1b11e3f8578c54ce180e4fa093b1f51576fafb309f7b000000000000000000000000000000000d5dc3d2b994e1da6541c68ece2d4711eaf94edeb19fb38b6a5cba383f58e9a064c482549fef4e373fd91ce778f38317000000000000000000000000000000000fc4d0c677cfee9213fb03d0fcc870412575cd73694b6d2b246b356692b55791e1381940a98ab6f8b160ec683334261c0000000000000000000000000000000002dfea3829e250bc04ec481859be8b5e608648488a2abad8545863b9e186afc852b6fa7a069cc4cb2c842c92ab4bcf4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001189ab183dc1e7652515190d1a536be552a50c41c468b1ef1a3bf03c2d1bb4b5604e44fc5c941d585437ee3b902405e3000000000000000000000000000000000f57fab0149dc21cca83403628f98967dd12b3ed6249c8571f92d61ff73fb613ec84f5264775155b0f2afe692fbf33650000000000000000000000000000000002bddf2be26219b8a80ec130ba3c54d9df1af8eea8f588746bcee0e0181a11dcacc27df2ff6c7832c8a2d2d0b1e398b2000000000000000000000000000000000d8b552a4c787605c0b3148c9f01458ca5e9f302ac33695ccfbc8282d81b4c733433c1d9f7a78fdd61b56707b7c26c0d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f4e120eb96e7e5677b3d884791b78d2deff8291162c85d3ee270dc2947cc7c405502bc615f0e157b33aeadfa08811700000000000000000000000000000000041e2cbc8f15c126dc192997e7efcc056d96456c5f828d274fc9e054bc27e3887e33a092d48af4292c90d7d4f04e6e650000000000000000000000000000000006fd2957b52b4568898a6d52194d63e4833f78a97cea4daf25157d13f924704c668505ec09212f57dc44acd698951ddf0000000000000000000000000000000011a40b1780f38293f1f6ea97e84145b579e65da1abb8dea94bf1138c6b263b7574a751cf88ea52efd3419b93b08d2f561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000102a40a6b52635eb364902e3493a6485ac2fd17688b0d3a62b101ce7b7e169c0018e41442f5d5fb6244a06dd052c5071000000000000000000000000000000000f21db1db74bd329ccead2e5d0a773ac478a4297af923e1b2567c4eb2c0ec9308717b711258dbe23b4505f834772cbd500000000000000000000000000000000106602979ffbfa5806033c3b15fe0fe49f81014f76fa5862b187bc3ac86a7e42b9163dec24a38d3002e9969d405f19af000000000000000000000000000000001656a6f5bd0801b25b06be7430a411749848de631e1896db3a9948ddd5e9474792516c9083e34e3a055af866564762131824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019e4477901b302d1e6ffd3279d1595c26ff5e6556c569323bffcc16d7e55b06377af946ed06ed40b783f828a02c60366000000000000000000000000000000000f173bfbcaae854e0f7cdca127cfee99cfc84b57b114006f7cc2a1604f8159586599a60ff807150bd9a9594e91a33c1d00000000000000000000000000000000107c48b722f39dc8431bab90442248ef84bacc0e67718f747adb083bfb8c40b9d4e38c13eaca7bca9846753193adf7ab000000000000000000000000000000000cd2418be5bbdaca2a1603a69e6350327f5292fa8a9e8302ee5660aae0aec1470b47f8af1ed5c7ee1706fc6067c882cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000168ffa983e03e3d4ddbc9fe80fb51be3f2db2d6819a1dfb2c96407c4be7df51f31a06c03be8af084c3264284b24829000000000000000000000000000000000170c5c3a90e560c3e5dbe3bd4e5eaca8c0cd46f0a19516b0cce13919ed1054467a697774a49ba359c47aa117b275635d000000000000000000000000000000001077a0e3866e662faef70dd1fa854ee5b12e92038e24dc55a24a2b3d893ec67a4f13b35a985408a881018477ef31c9930000000000000000000000000000000017d40135930c4782b10f269f5080b65fed4f12193010fce4a1c161c34bfce3142fbea24aa23fef48b2d908048ea3a76c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df8f3890285fee1d3121a786b933e0b35fce71756ba98d1594c1e5c9bbc51c72dc4c307eab7a84ee97acca1045cbdbf0000000000000000000000000000000004e98ea549df24b6a1adb6ad3a6f01af4236b0c271de9fe95e8b9e8ef21283b488f9754ac67a12fa975fd66d595721ec0000000000000000000000000000000019ffb12fa5d0852dcc474690e621c0822ebbe57f44cdd2c515c8e64c152a6240b24f7d698ae1ba59ae69b745ec0dde000000000000000000000000000000000019369898dc67801a5de8b70b190e5bb36625dc7dc480b2992264d361c1ca1ba5036f39df6e7d4a9a79272d14126308831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e096cff78a1ed89b7ce9a048affc5b9fe1cb26ff9c94798ec6436e4f1bcdefee7eec2d6ead17fe1e3e8bb5b4d7d900500000000000000000000000000000000194a60031bfa005e5e6e540163c27db047a01f3c84478ba220b7ddad67e51b50c45baa695c96bed44bd5da5787b199390000000000000000000000000000000001dcb09eb696098747e28a11739ebc77d2252aaa50ad1ad28eb96f6250f1d16f67b785949cfdc7a7cb22363126673abf0000000000000000000000000000000018a063c9107ea44628940784fda8f52d092b5711695a14b89e42ad090b9c751aaecba0868fe8332dfd77cf71625185061824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a670b82f948e1d447c46b2a59759232d2639c32933a01586af0f85b7043b2aebd5da0e08427d6d7d7e3c3b2e5a37a4000000000000000000000000000000001883625bdb964a19b3e3e3e86821ac3a0a17a04cb3609c8087caab44d9320b552e643e53b33485ad829de8114614b2a800000000000000000000000000000000049cdcdd6f4bb89e86803d643d31101aeac5d7f4405e655eb5eb63cc4a3548f2c2b92261bd7a2fb1edd15f310c08f19500000000000000000000000000000000113cd3aece00114467c3e86bf099e56edada7e14442d864a18884bfbf2e5241ccd4c0567b78758b2a26ffbd978e855141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013399d0573f415e333518f342b3f5218d27faa6091caceee8dc06e4b375182d43b4f5cb0cb1603626d8244166b33f4970000000000000000000000000000000017825ef803a0a43c4f720fc29ca1e22d7116977adfda34ec7f6de95708b3b39695881422318e1fac75db7f23c6e98ff90000000000000000000000000000000017cac54453562899bcb5faa0ea866c2365c1e0a9afea9c0527b8a17a2efa654b40a1ffbdef7358d386a1e8793fad51ea000000000000000000000000000000000d129223d0a3b612fdfbea48fc88e3b8fd9b1c383f534a06404ef23ee22dd3ba931b9c1c3ca3f7e978b0ac7c8c9137901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b5af8e8953836b3888803ca1819e4f949e74612f53f96ed0bc3763e77c6f192c67b383e4f0bd8f6867b40c15d1cd8d2000000000000000000000000000000000fbf6658c3bf26002730cdc0dc85371999bb3bb4e903de453f2f300d92b3003aaa0f843c5d39c7c4da28cd5b25bfbf98000000000000000000000000000000000dcf78ee8860f5dc01fe53ba4b60bada638902e67334dcc01088e8648e30355da5c8e1de2885831febfa48ffeca0893500000000000000000000000000000000049b7690ac7708e7f36f7ede214f53540e79dd586685eecee76e0150d45f9b103894d865dfdc9171e126e03208f983831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000057b61a050bed803835d2af0031547096661be9f3a29b6f71dd2d5db9484d6f7321ffd82405d156727b0dc7f2cadabd6000000000000000000000000000000000d25a03e12c5b5e4a69f8f7000881cd48259f4e9cd77a38bb05973c3ca74a6adf2431a4fa8385c5ab5769e0df9fc48360000000000000000000000000000000000411057626036cf7abec0573906e8aeedca814486ab45b48802dd5f406594df2e38ac7a706a5702fe995bbe45581d2600000000000000000000000000000000037d4ad9f294eb2d55b99540aa71141e0e47bb62d68502703a19fb1291cd702911be385e60ebfad1a4fcdc1809237eb71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076762c73c719700a43c451c0ea37a0d2e07859b7632d25ed9c219ac2f8cd573289ccab4362755d78557076978261c43000000000000000000000000000000000126f61c62029d40527ea8d06c29dce68e88531c888e626f863c5529aff5c4e95f011719581d7bf59554d6432bf67ff70000000000000000000000000000000019520e2daa94b8de7909686204d867fdd9b40d9b15d08cae1769489248d790ce6c986288ed2ef1a3469c8a570591842e00000000000000000000000000000000186b7cb63c012ad06cf575b810966f9cf8e88d0b9478315971d7e4700633977f9fa05a3bc926abc309ab8648d1aff8561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002e30edbd003a8b1f35e5b76562284d80b9274495e85f1b78ed8a591fc09bea8ecb015c0316f8821493fa6aaa5fece80000000000000000000000000000000018aa84b77df8c602f087afd32a6b1b4abbed927d57e5b69efb50dcb5229f5a91aeae8f0277f337e6ddfaca145ab9feeb0000000000000000000000000000000015ddaa1f86eb5c20a22a3390284a63f6e14584b22d202117d56155fc6bc1ac63dff60bf046c2af69dadab0df5d730db70000000000000000000000000000000004f2558c5bbb70263071cd5b998fe03c0b1c91d2dc74fa8c5211d2b7257578f99756fe1c425d49dfe0792adfe5280ec91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3ebac605ba794db968286e37279af75bc5b09af7a89463e9fe9382544e1002edcc3bd9b39f501a34fb7051e97fa3f50000000000000000000000000000000001dae26d6dc63e56aab94eeda509057fb70e74b1c541f17bf6958c2afbacf400c1b08408fa6d18f4a9f9d33046cd52ea000000000000000000000000000000001139178537e886e646778fd28b2857d2838e8dae68a0ab63686e34b358ebfaa880192cbd4a8e3a907bb928235e1b78d600000000000000000000000000000000058ec20699de411e7836dd8b285dc2194e643f9d5dac715c886c687c7e0629f849dd68d8176a2285f1a4e6afade67c931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e7f21a14a48ab0ba4aee91c0625885d6b01460fc98b266be345eecfc3cdf1c34769a39f63f4668b01ed27ae507dad6c000000000000000000000000000000000853707f89785a2fd0f91cdb91a3a26eb945dbc1004c5a96739712ce5ac5dd718fd63de4b2cd1c41575210ad5e557649000000000000000000000000000000000a6b1a644e87bdfeedd7d5f5526470df74392c3e23e20b4fe9f22f3772aafda3b8185c36e5284b7cc25f257587a91bd7000000000000000000000000000000000c89bd84eb387935d59cce4171f00a590ca7007ee760d2581edbfce8e6ef8b2cd2acc22351254b0739b240e6126dbfdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000069a0ec0378935cf3101ed6e52baec487477103a6fea80dcda112c3882b31feb45afe4c4d16f96b2e286b15493fa693d00000000000000000000000000000000171d6127a632cbdc8db25e389f60c50ced77989b8d6c116807bfaf7891d460cf287209f9f98ff6b28c118b053f88ea6700000000000000000000000000000000061a6eb11eb9c532b1b08933a61b9067957620b6a0d90e42c48d887509965dc0086b508f37b3bfe93993222cc2dad84600000000000000000000000000000000036638d40d00d948002019b937eb4936fee10601565d324b7b180b0e3ac404138f0d266eaef281be8335cb99ce201e581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001359248cd0bf470c91e2c6707801cb1c663c12204fb2539e04cb2cbc6ce5e119866827f9ec3d89cb7f42729a1bfa5aa40000000000000000000000000000000001e93b0c7438774fa8c7b5fb6ccd58d648247572a38a3b47e3e998efcb8ea1d5cf53bb8f15fc52822e7ebfd238d930a70000000000000000000000000000000011c18f3f677feb36217c1824d9e316c76ed1baf6c8ffd1f938f01b2127e08554851db4901563a5849bb3941b19c1c7d60000000000000000000000000000000008e470e844f51e60e6f744d4426755e4e97bb3639c79fcfd2fc3c60fc12f82e239e654287f6a0a7b7af4ea2b889be1211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aceff7d57bf85828f03febbfa81e512131b9d4ea6cd6a8b466826d3d143f0a8c0147d1c58a35290468cc7f31dc8d6b100000000000000000000000000000000151147df8066284c0165220ac8bbef374a91f36916aef8d2990c957fb34a65e685f4bff37be438d02349d5302c3c7f50000000000000000000000000000000000c5a9b5a3872ab252fdd2ed190f079741c2e3970c97661ff876eda3ad1fc6aafddf4502a7651e7618aa0121a957b49d10000000000000000000000000000000004433a3d4d5f2fc29c141858cedb63354fb863ed365b2c5a03dd96929d37c46f0959ff37463466067476e0f932c387cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb0c8ab6e2b98c5f9d34de3acd3c50c191e012f89796149d8a95d4ca7a9a118541995757e0e1a725d837a364233e09200000000000000000000000000000000181728354e822ac48c67b3e6db100645377ca7c92893e0b599dd350b81bc301aaddfac54e824089a4ed9792e6f0def3e000000000000000000000000000000000563af6098beb4815eeec530cf08f50342f066d08d268138d9cdf5307e284e5a6ddce6bcd0242e00570aca3f13e5a825000000000000000000000000000000000d263de0cab6f2865c75c6f00e878633d33baf30a0a8bd7b637ad786b6511a3bcaed6f86d1c4cc8c8bdf08d2ca9efe6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b098f261f7b36be73527f17037dfaca7d3d7d0654cd8eab5347e00b7a43732ce3063d3dd448d4909bc1c24f35293f240000000000000000000000000000000013ec0125601c2325c749281495841ac6ecc27f82f0bf84a907e3fe0559f425e1cf0b4e476723d6c12913706b0e10d40000000000000000000000000000000000115b837546fcf4eac8f35bb6c33ac3af2dacb6967b5f2b4062575646815d88df26a03b971f2ad20dfb10f18ddc0de36a000000000000000000000000000000000769941fa017e11bb61d304d445c4a6b5f9c012af2ebe84eaf5de7e7355f9c979ee945da67e56f4144cd80c2c5c4e2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000267dba8e4e5d087d44270e623761c7d11c9d00488433a69233f171c9d8a95acd9d38b9a015b7d116ab76b2b7154d2b1000000000000000000000000000000000845f2b24916d1547ab0be03681307219f896cdb5b86fc1f0e53c5b99a8b92b3df5f7fff112fea21d1e8dd940a938899000000000000000000000000000000000bade5301578cf7c77a5c7e01dbf6a42c46b4f01c2d8f386d522b649c8fd03b046a15a19b1cc45df65313b91238a8f4f000000000000000000000000000000000686416d563d90b506192987a5108d094be3c9830172b4599368c4d15fb2f3302474c8db966bf39f43a0ae0a7afd9d311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ddb0d375b76ed7a209c4256be34324730de9b4fe138659a04b4072ec8a39c61bf49b310638f32cb6e4a9a00ee3081b6000000000000000000000000000000000c9a88aea70c3f1de752923eb586923d100e229b032d95b64c64b64e0bb8bb5d66a8de7bce337e94654c99c2fe08fc61000000000000000000000000000000000b00d25fe797e0f0853d05f3f680c8e71ab0003405e23d67e700b26321a49715010e09a4e9969b2315df28420337e2ba00000000000000000000000000000000181869b308b8208570c245d211f54c63c8982a5a49bfd738586903009513becd10ed89270c82c2e382c8d7798940d4471824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000081ec49df044de2aaa613504cf465f72d4ddae77ab22be1ba9ed6836d52babf265628d20bd6131d4be51aa8bd66d0ca0000000000000000000000000000000001575f94dce5530c8948831ce62e9bdf11b5fe74e6b714dcde95614d2087116f505126b68e929c6b6616e625cc07571bb0000000000000000000000000000000013617d667d380884ea04b6709f9046245e7781bbf171f32cc0c533f87f66aafc5d68a7ebb97a26ed948482f7c42e73ed0000000000000000000000000000000000029eaa93844a3da0c1ba0a52d4707ad29175a678439bf3081739117daea7f933b0a4c531d66036c481a56600e3092c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001689ec130c40431d438e491ae5a7bc87cee09becd88ef0e0648d8e8248cf4325c0dc982c6d0e20f7ce192a41762188bb000000000000000000000000000000000cc158f444af97625edf850a4c272d1c7b1d255030ba8b1239babe4e2c2671766ba6adbc8d062de205723ea7625c9ac900000000000000000000000000000000189ae15da3403ed35ce5d7ec407fd7e1247fb10155ec49ccb86c160e84212a6d47115e01c3ae10e72dba94d5f89f930b0000000000000000000000000000000000a3a7c128a2f520c53438ee70fe50783681072c95815027b919433c9a4b028e14236f6259bea12ece2b46e35fd002891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a4214f9de7c9843d047ff728093253cda06a23fda6720b690ab26845a8fe35c5d526be2670fdeb3e2e278fea80217a000000000000000000000000000000000e2ec56ef65c82af4b0eb1cc09248ac73538254b1a60035c7b7b2c845938e7edb4a5c71a44ce81c01d6f35d6dfd86af10000000000000000000000000000000014f0dfafaf14961eba9e3fe5e4d5783eaa364f11c0339a29f8fc7f94aac1ef219c61114390af6a58714deeb41d3b9b85000000000000000000000000000000000a6df933b1ddb9d120eb7df1a65f9b247e6f426f1f0a5f845b0c08ed437b2ee2c1a798997a9dc8da398fca488be78a241824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000709868729d44af981a8d77b241f931904be222bf61d69d75eaa2777c75c14fa24b70849fe30ac607c699c5d2313e6b100000000000000000000000000000000131cc6bf14bd32e234c534b015566815159596bc88f8d4b9a4805912fcf2387757cfaa011be1f5ceaa6de447771d95880000000000000000000000000000000004748caf0b67721fe17c42266be0a00ac8b7236177228bacc2a74d7009cf15b5a713f98155783bda0d0ea8bb21b47b3600000000000000000000000000000000020af8f341527d18b52d39dd221858bfeeec5e33322a08d5b330aa19781ab2901fc6ee9475c6cf4b6d84ce72d51512211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000144df9df4f9f3a274aa347e7a9162bdded981db496f48aaaad98ba54c3c793bb913ef27abf37a1846cb1dcfb2e276c1900000000000000000000000000000000140041f093bd58eba0438122b980da002d1e5e4d71450c00ba63228c14822daa702e4c3c412cb7b4bbd57c92ad3035000000000000000000000000000000000006324b67a55664f1c02361d0f01183397241c14b90c098c3d00bdf8c4b1ca2b26dd8257b565010cf72641628640d81e600000000000000000000000000000000183b82b62f50dee386bae75f5e24e13ed452347dc84240035b0b2221412db58e79ef2ba68ded05330993322bd57918071824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f719bb31f5e1f79a45c12230d3518463c398d97218baae01ab6c7d3f140ed3d04cb7dab2870d811202562bc5a7783d5000000000000000000000000000000000f2fc77e2a11ec4f0a9ed54939cc74f1f8fcbaa9b73c371f58ab979d933570fbbb09a6721661ff2550a526492536bd0800000000000000000000000000000000003b6a4c08f902b8353a0bc93d001d44e626bb0e7720ffe83680352e4ce238129de015f83441a467116337b9166f3739000000000000000000000000000000000fcf44fb32c7f37ff02fe20e4bc20874eaabe24b721ab44c879411bca895562a8b6cc60d191c7226ddd8606442b726aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002724a829e7dafe58fa3f3932387d7c8b136d141d3c6ab18b385248f8e2fbbb91b0b52440606d26cd1b6842840b39a75000000000000000000000000000000000502c0cf101ec4b56c0e212f7783545f68f72b94aa9699de29a0c36568d9124b1ab30e9e4ddc672145048f32cd396a2400000000000000000000000000000000110c6f627595207e936fbde1ccd0588fa2fa66d47178afefe644d44c3840b5d3e661a8a1cd6be88eb49f9456f58c8fa00000000000000000000000000000000003dfa7c1b3070cdb3e31d9cf7e844ccc00cfe46a58ffcc2220d6416f71294d34885414af429c58cac0de9b26944404fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000181afbce13ec8943c79ef2a915d4db5b5abc8be9daf6231f7c8a7f29a22f304c2148285292ca35fc2f2a85f52d542cfe000000000000000000000000000000001525bc110adf22f500d8ed319db2da50ba97e66238120b3a27516c384cd28725ca67586f0d6eda2e65509f6199b86daf0000000000000000000000000000000015d4652569125ab08bf224eaf841dbc3c6a41df4adf45c3c1419d7f6d030993dfaee344d2b5ff4c5ae597ea9e11306430000000000000000000000000000000003ee7c1e38456021733e8603befebd54b9fd7c7ed06a492c108fcefffd2da512da925ac6dbc59653e2b5a526ab47ad631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003e7d1bb17560f275108c2b0933b2fbd5819a8e188127d2171483a4b830d005a950512481369e12615a407aa069fb38200000000000000000000000000000000056013cef223a6f176a39d753b35029d84b9be3e4888afb075ee3004b53c9d50c1397464f19e9c71622500dfa2dfef030000000000000000000000000000000015ffc4d1b37c21b7e8ce5bc2d0985b68fac891101253783a1584a736e35334afc76ac1dfa1042b2af29f70e8cdb2cce4000000000000000000000000000000000c69a89d0ad5d1a10c423ec320ef61f27173a7b3862f6ec5140b42551617723b59f22a1358ef4becfab338b31547295c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000165494a48107c001dac8dac9a3dba18c1bb88cbe7c02da2ff26f190afb145af687c085899c8ce8255e147709c3e616f70000000000000000000000000000000016a7dd65362fb61f713d734b26afaab46fa9eb9641eacea27416c72f4fcf9cad7766a7ba7bab90f4b9c12c889f2347e00000000000000000000000000000000013344386e8265103057b30e0e033a9775c4d2199c7ca8def995f63e1bd5cb72fc6e7f4dad49b7e8989001ff2c94c9b64000000000000000000000000000000000e5939754646b3fa1756ed1fc052d2855752de4626c47343a15663f3c1ac984e34ff0859f71c3906874ea76770772a7b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a5e70e4faa0c58fb8cb8071682b83bf59b05e15beeb110c5f64e6fd92ae0a2396e951de4d7494ac9d22a9636c5c51000000000000000000000000000000000017b29cc701f229e76c2e950618486e43e7a49a1665069369f0bfd562b6bc84fd3eaa2fade85e8c7a49242ab0b8bf686000000000000000000000000000000000ff9d5b8e8e55abd68dc13864c4dadfac324bed8edb82a7f7044f4d002bcfc08818ca34f6fcb40d218119c8f3601bb6800000000000000000000000000000000192ddd284cd3cf707d54847d93ead2d95a64edb9903934a55a661b0496cb37a82ef3d745e23bb6800e847caab5a0c0111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001673100540b2263bb43cfeef25f79203ff9813b53ac74271e511a208c138bf333f0274ec22c2de9e1d0c5b61388d492a0000000000000000000000000000000004952f3c7cb942a5cd603e9ae97fd449a5c89dbb9e4f10067009b525eecef339875d8483e470a6f88573a9501658417d000000000000000000000000000000000710cf44181450c7d921b2f7fcef0482664af80f5b25e1d4ff054723995cd8a5ec4e83e5b40c183f7d33c80898de3987000000000000000000000000000000000aa0a4fee37a5e56187da1a321f63a59006a8e79e8c96c0c8ccaa29a755c0af7e130310ad8adfee2f3af5babd32255b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015dddbc1a2fe5116c220f22b1f66f4aaf84f914ed863b4f89e633fab3e40c307c031c30e4f12e7f103793c499c17808f0000000000000000000000000000000006f932bf8e5814a429be0e14d9b0ee1bdc86b76834f90023017ff05480356d7dd84c0ac8990cdb0af048318f3ef2e0af000000000000000000000000000000000285a67174a5e62716c9007d995d059bf3db978f30f682dc34fbaf35a948731cd88b1f04997e72910a2560df3e1d78a1000000000000000000000000000000000b57de678988fe43e30c1785c8795a2df8e6f49e7c2a3e934a914fc506f52d2992a33cc266647fd884d3a5c1a5fb025c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014338a8d8ff57255377f4b50fa8a268d53c48a134fc3d540b309c560a66652d321489fa97ad4c482b49471ceb7da60880000000000000000000000000000000003b04d2d1dd8b1f7fc216b81e2c20d1dd4f382357aed9b8a65335c39a404ff6a03748d8aab545ac8683debc705f951ad00000000000000000000000000000000128ab8aabe5a12de0ca9a725b8256703a3d5071a05a1ea235e1b51a5953deb6313bbb014521f3a0803c1d6956f23820d000000000000000000000000000000000eb24ccd6830c787321f6de698ab43a404f7a47c21cd502feecd80a1d711dad6336937d68baaec3aabe31cb69e1ae96a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000099ba6f8a88fc0d6384dcc5c79091e4871f0afd07ea655cc9034ba800b324ad05cf206f17b1b34944c6af0e5e166c2890000000000000000000000000000000005ab857ad9430e00a14abb44cb43ed5654ba957a475752677f92bfe1edf18acd31460f3b63ce9518fa667cfb27ea51e6000000000000000000000000000000001175f99fd078c1b24f7952367cd0ca868dded4f7c961d12d950bf70b73fcabd625839d263c2227db1cb7b18ea20d7d290000000000000000000000000000000014dff1f530df08f4af9df5a6530428cc80c430c1a3624ddb084b84c3ec41b81b2c3e1a892d54f851eb7866b9dcac533b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c04c1aa0b9ace3c3b6bcf84e2c466e8c1874fcf483324c6808d2f3f2408da43806fbb56f0e66fcaaa4e4dde8f75aad000000000000000000000000000000000fdbb8ca07dbc7d444e6d9c3f89f6f2e9cfe33cea0b77d43537a1258bc5d63d6ec288205bcece21423d753031094b458000000000000000000000000000000001932e8729fa5bffae3f9f6bee7aa1170d57bf63abad55ca4dd0c541b59668f5b2760034ee0f99e1584126c621180640f0000000000000000000000000000000012cd141f78973fbfd0f270e8efe5aec7e5a096f219859c6cf883916d713e35d5b3f40f5cb5126654c9a6a6fc89ae93721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fa7e94a776ca6df651eaf65bff2a07580394e47c2ee2b3c6b2779efd4077be6132961647d2fa8ecba9e1d207dd29db000000000000000000000000000000000d61ff2a81a962213875bb45cf14260398c9a00c594745fe53943f7630bf1602a9ec03b11757f3042a37fcea8e9dbf8900000000000000000000000000000000126fb94bb500eb760f0ca93ecd665c63040d2b264d23573763f6c655db91736f15ebbaa63ecc0305471407fcf0115769000000000000000000000000000000001789e6c34798e7dc104a46c9ab162efce605d82549148d073cb510fcaec56fae4b8fde37329ea8f89d339151a80a34521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002b4c8c06678d02fadc3ace20e692170b3676faa3d3ca0907a8c015479443b42367d4cb564cd15258de87e29ba4ecbe600000000000000000000000000000000057951498d606a20e2177f4632cf819afc45d03a6bf2e781c125cfe5007debbfb3400f4a61cdd748aa2e267ced3b9dae000000000000000000000000000000000e074b729f8ec07b627737238cf8620eaa41b42182b93c966dd377eb1eba593ca67885926fca46f2fa29408fa9e80d6f000000000000000000000000000000000079eb0f264a3d4be99eb1b3355115d5bba6bbf83cf77ea8da18e33923f47b3b2fb0897cbd4c884bf4c4428d7590e9cc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001917bc809717f34992120edc423236e18bcc06b8d44aac3a0831d3222cc3d532301d8ecb5a4f40bbf485263383c64d300000000000000000000000000000000000eed9c45e8679807531dd7c3688a0d470b2c151e84ccddd40152805488b85aef14fac8adcea7a943cb1c415e87af160000000000000000000000000000000006c9efcff83966a07787c4cb80dadfdce96e2bf79cc4fedfe65e1c91122eda6d3c37e38047ab90d043538aaf8374e0c4000000000000000000000000000000000fc64012cf665e6c20f7a993831ec06ebf367b36b4a9c243f74366db52035bac90855e0600802a4b62e086bd74ec156f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116f5809bc9199b21990d092d1c5d195f58e7be168ad49c261ea38789038dc3123c4f93b055dcd74286c6011dc62a8c900000000000000000000000000000000053b4c190ab3c785a735259d04d23b33c321a5be985e29e90dedb01ac641c937db36f0a36d3ceb9e973a0902c8996b90000000000000000000000000000000000dfc0c99b1456bcbc63cfa571976e4181b99d13644a0a4ca01d75fb1e9b0476404c3bd5b3283d82d9d51fedfec35fd6800000000000000000000000000000000178bbac3bf05705d6265168c1fe8a0cd6dcbc93f126263f756f0e255aece8d474cb592a722697488cb894d124cfe84151824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aa2a2d4118f60b66d1726695735aaeae4ac5ae7366404a62f8ada825aa7b5e1db4cfd81669c92e2c0b284c3daa10b0f000000000000000000000000000000000f0a7181c463e30d1b35758f12dc71b99d8953e34eb934726381a72a98f8dcf3aa3adc57c4aba31f38b901911822c6190000000000000000000000000000000000a341e4af8f24ff69cb37f27a42222640a1a131b52fa83ed2863fcc2a99d02e678e60db0b63a90a750343431e0bdfae000000000000000000000000000000000f2a07b3ea760779691d43a58096458421dfd6f0eb7f150eb68953f7acf98177741c3f273fc3db86857e75f447c4cebb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d475c932cebb0b915bb9d7e0e8c13878186d832debcb7b7f28eb029060af2b5d5aa827bdb7f4d2750fd89d10fea258000000000000000000000000000000000520caf9f6a7cd2254645fdc9b6c7d4489f28078ab4bd40f36012366a079b68a3af995c66c7c6c05e9b4e0a08cc561f70000000000000000000000000000000019cca35e5c162005918693d02b3e45d6362ea66bb2b907a53e0a0d2979da7be7c8396015fdfc621966e3c9b8f37585910000000000000000000000000000000006025ca77a89f47b27c0af17120bcbbc53c1afff891949cf2485d1a897e4c8c8df49630bfa1bcac0fc77dc663d2c11911824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010445e2b83040a3b948df09e5cf39c4804cb3a8b024d9916dbe143fe3ea80dd678a165b3d7e1d707ef85ffc3a1d7b4850000000000000000000000000000000000758b0ea67585b17bf96b0bae92d4893e1abf536cf3449c2cb1318b14d10e30db1e7e203b11790743eef00904511abe000000000000000000000000000000000c62948913b675d591aeebc758a01b17285e36a4cff1c76cf28c8f41998f7bc23e444bf874fcd5af6af75909685c750a00000000000000000000000000000000192b566e3412b2b552a4537f010d2cf46a80334c56e73c58a96f39b2733ec328c0307a1805328298790820f44a75a8bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019689cfe16d252a9c25f07970c30db5c8baf59bd74c6fcb892a4836add6dd8cecde4e6ffb57d238214e66a34035e82d40000000000000000000000000000000009cb3a73b936ad8524e2e47590ed54ce72311835d4efb2211285c4a5b5be5daa5cfad58d71a6708ecc0efda47eab29e60000000000000000000000000000000017beb9d2af62503cdb05aa98624c212780889b9d13440e699b60707f4d3178c6d01305205d5a42d23f5301f6241fdb8a0000000000000000000000000000000008e7411727c49f488502e6674e36bbba6859080a4456893d4f513521f55473a9abf353134bc089b2b7eb28692c70d5de1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000004957b5f6ca75a70b9fe42bb88df63a8d6bf2f01abc52f644a886cf5a08eeac7097f49222c613710058d48aaba158410000000000000000000000000000000009790581d267738075d7a7107479f2cffe447bf319e00a6285fd311323b364d5a97ae8bece2078cf7d0ea380a7e555970000000000000000000000000000000017d0a2c1800089f20c079143a9e3091f48f6f6870f2a58aced227e60d802e8e85b3440aeb2d1b4fd3d36b9c3b53392b40000000000000000000000000000000014f9159460e560eaee29b1c78da7058efe5e1457f7f0c03aa23537c23f648b1ee592693d7c3c87b02224bed6735a457a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177ed297174517dd6ea283733d18bd6c204f5ef00601424a87dd1d2cc24a3a33e50c167624865b6e7b4c4619320d1490000000000000000000000000000000000d3fb5c56bb3f713d61e955f5e5336869649af82d6a73ea9d9dd2bca1dbc89dcc226ad52634e815486fc1f6740e471ef0000000000000000000000000000000005a44c6276945b86ddca5bfc78cfaeee16e30f793fa24b877dd99dddea6dc1dcc1626f99c47aeae79725d81332f1140000000000000000000000000000000000160c0d2b670e9caeb75e1f85bc1245119534cba3160e73db34d412057275c3d728c25206b64a33b3c624ed38ac5e997b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b0d4256916b7c7b5951c4cafb5e2511bb47e412bfe93ca3917ca6b2c6ff3118cef186d54c029b1215683a1a65b1ab4f0000000000000000000000000000000014c3b5b020b255883e9504ce92fe3194e90e4aaf3240226f2066f382096768b4121c73638baf143723e3221f26b2b861000000000000000000000000000000001792c5eefb76255cca680d20cf63983fc2449ebc0296241535ff5471cf095e6c29010e738a1102fd10c016aa0e188da40000000000000000000000000000000018786e5549b2aee0614bb9547b092d687b173aadd5d17231cb3d71aeca4f253bf8af1a00945604211e8a9e39250d53ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010e9eaad650b55002dfc25e4156cedf321dad4524fb4bede2ca949656cd1023a6c0bcbdea861fdd582b22f6d894032d70000000000000000000000000000000019a8710846ea7e0c69e25c1d7744499537bfedb3a86c911482b4b340278cfdf0c0a51e58280477c8e0e016de615983cf00000000000000000000000000000000186e518aed5ea61cde29fca3fec2155c0af008572053a19c7487617ff344b071a79f633f89881644683570256ab932b4000000000000000000000000000000001405795c44d5c04d076e0120b7b61d297d1392ee5d73c1ef300073c86146e99c726c2dee3abd8f1bf1bcb9d8377f51d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abff40939849a038697f19932861d4a76cc10929bc661505f333e0190c2c20082a53c29494414c28b07762b2993593000000000000000000000000000000000060e7d4136ea2a93f5354e4332e338b94ea8afbeb713ad036f6907bd5a1c032ae8e6f7484dadc0cdc97a4d0f0bea539c000000000000000000000000000000000b9bcdeca3100689c0374e83bb95d7325eb55e61c755b5c2aa7540f1c63e9018d217234cc8437f30353b0d1b7fc44574000000000000000000000000000000000741b62a1cc4e2b4d8bcdd33df2b253845da922abad4b98f279553e60caa5dbee82b5129f10ffc7ff46c74a9759a13451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011c62f015bac76db98830b024c7204d1e328293106086fa76418a1f31e0d4e6d53d7a357179de03994fac98ca6f5ee7800000000000000000000000000000000104086c4d3b6449ef507d49d81b1f35e0cedf3aefd7d4543ebc237b4d681bf36ed3735af8cd5ea3d1c9ee26b8a3c382b0000000000000000000000000000000012439681e2f8c76d75b84738bdde804fc779b6ebe2fa64beb28f3ce334b411dff35358839a7ab02c35367a08dc29ee0b00000000000000000000000000000000063a68dd66f63df2067b81f51b2b1b95bc378125f730ebe02456808d2d88446a6be630cf2515f195dc70d7ae029d2d4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000abc17b721b7f2f6d3eb92c918904bc014e2de7ddaca1a7f97aae29d255f6e3f4fe48ca0f0ac040930f0e99cbd6e8e8c000000000000000000000000000000000e0054bd8defbadec7d7e0eb14710361322ee508dbcbd3b4d3c0819f14c80f4dbd61d47c41d0880ea0c8d87794169ce70000000000000000000000000000000015ce6029134cba549dcdd9f73d9de31ab8076e2335091e652519d01e3dd95ff498a784c925146a4393665cfbd18db63d00000000000000000000000000000000198e1e9e2f3c7d33890a6dd5b6db5b6c1ffe7b92dc471a537f26a08362f45efc487468d32e98339ae31f86e824f7b6ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007718137e88a2f8e000652482615281b996b77230148b54b4ed4c470053f995a24a1bc4b5faa3f06a3c153170c45d0a70000000000000000000000000000000005d92c689ffd08736f1f4d4f0d942d9e44fb2822270f80513c84640163aacf4fd3b1014faa135c0afd8d55b10dcebef30000000000000000000000000000000019bfead70a4e1d3cde4b64876da431680280d70c8451c4454b28260c2f3aca32ed533a060ddacb60284f34097022f46f000000000000000000000000000000000fa96e17d8be8a521b166f5fcac3289b2cbdd5498fb3add85103fceee1445d143d93c87f9ec9f5f6a390ce9a036cf5461824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018bf90a4bab9114ee3f2902c4cdea1f69d28e3ff32cc5bfc6e5418065293cbdedc0532c23a45ca27545e5a96ed7f0a6e000000000000000000000000000000000ce224ce4ccb2caecdc8fc9085b2717831d8252ebc045e50e3383645c5a114fa29c24bf01d5c3bc35f957f5b5ba82ea00000000000000000000000000000000016fe0c75a2a9209f603313b133aa355fb52f04ff8a01142d5a97109c9b1797d45769de74fe724897d8e05affc833d0ed0000000000000000000000000000000019d70711101fb25af1a54aad5ce24e386348d62ae0e61e11af69a7f36f815367c4f57e2335cf7b7166d4f3a8509517781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017d842fda881df718865f8b9944f0d485d158f1f013e50851e79a67269839897be046488c8704b0ffd8c92393f856907000000000000000000000000000000000ef30cbae5512176bde58cf6d12429435fd3d3b2f469f74f99f73fb1142801c4c3b895ee6b7955614ab01bf34f125e510000000000000000000000000000000001a5a0a4fcc432f8a523e1153619a5342ff344bb9084a79eef88fef94ad4d7c63d3d0871a698d7d634a462cc3b99a0b0000000000000000000000000000000000cbef2c1e2610479d01969f75b1737316afa401ddf2267808563d2214fadeeae987ef2a496c945cfd43272b50c66cade1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7ae002070dff96ae3645c91b1814d82d96aa7b84ba54d7104154e3f6c190cd3f508ee0a5d53192cc70a0c0c08ab82900000000000000000000000000000000113300e634be6ca3679abe1425737026ac0d330f69471dc409b4eb0d586eed89acdc210363ddb211382df2bd8b27150b000000000000000000000000000000001059d8e200b5ac2fa789f0ad451c3b3146a8aae5a6e9a811e05c2542f1a01ebfcf47d7bb985cc0a693e2a949f369e28c00000000000000000000000000000000092015f406ead8e680c79c1bde27efd43761aee2e68617b3308ec947c292023b732a0e4719f531ec61a0071bc7e739f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003865f377e22b6cd97042f7051c4e1d555e41b559b4d3fadc0243982c82ee6cb1987d56413b25ca35df81b80d8f5bff4000000000000000000000000000000000106d883f74bff33c0b9c2e0d2ae5c4d5849256052a39aab503e096a88e4e8bfdb805c635fa77114f56a7c21929f889f0000000000000000000000000000000001713712649164bd47203f77ea1ca8cac9eff03e579d7c2b16bc4bf49348a0ab37a03649337ed08a573176b1c33a3013000000000000000000000000000000000e5eaf92ecd6781249c4914f71887e6d12e28621eaaee4e63f285e93a22f41e288deda63ca7e40305c7a8b9772dbc4361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b28f5ec052e263b10e818435f3e75fb962da023e544dcc3014ca0d537a62ea1df5e69165bb215ebf27b26f4a05b0670000000000000000000000000000000006ff601642fbd93b29041111202ee8c2c902c783148464615d3e9d676c900530d4b17514abda99a872c4060f164241d600000000000000000000000000000000094338d84cb8f6065c1114149310b107885570cb4fb12f5ce43d3528c4e0628b2d388a37b2f76f1fa3144aa90cd94164000000000000000000000000000000000d1b8cc47a954805bef610dff73d66a49445dc7567443c297b4ff1219b3013c9346ed2fb4dbf91117d2b205e48d0a0971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e6b29457d0f0322111fceb1fbf214c8a8edbac56bcd773e4132c0284922fb5ab60c719c93effebc431f2601001603d000000000000000000000000000000000fb178cdabb181bfd15d805fce2ff5a07c277dd51b082dcadf13fa69b465f4e15091e399f459d0063d5cdc415dcd390c0000000000000000000000000000000005322c49cef01a7137ac0f712c393df7229ff74f1021ef67fea734ba7a0bcaf27901ed269836d5a48384e2799d93a72600000000000000000000000000000000022244755cce1a4b1654f56e8bb9f573bdbbd78512ead3960587a3b5a0c50a9039683294263c3bd87c3fd88dd07ee5a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012b0f165dcce1e88b9508bcd3a752fa8dc8a01e89f6cda2fd469df3454bb0b49105640303766232160c86e7a3124c2d600000000000000000000000000000000109e54d2e4c0144443b0ca391cca156f2df0f92051d85d6a62ddc611ee3ed7f1598d76e83e5dc322278ae78d9ae606da000000000000000000000000000000000c7cf2adf7873052faa09e2331fe7dc9af81c2062d7d35d9d9278496663bed239a84611cf7e28c6b7bb7958acc74098a000000000000000000000000000000000af03dfa488643cc3fce89bc9850cf96490535b7dc6aa64cb9698e311b7aaea295efd3093a7a6aad3807d0bcba3e4c011824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000def3196603d1e047795a08c04c2f645a2c6a56e3bf5fd4ab51ec9e77f6cd6208d194c83b744437e85af5d586b4fbe7600000000000000000000000000000000096d92d089d4c82923d984acb8436a1b3775610fe88db70556e75955a259927ac5051402226b4ca67a121a2176ad5d510000000000000000000000000000000006fca4841d16bf033de4b74f73ece7f9dbebfb9764139826391e9302f1499c7b1566ac1dcfadc14be6879412406ccffc000000000000000000000000000000001753abddf4b24178e91f3ebf00491664e80b8c97c70a26e90419f3880b2f1afdffdd7546c6bf68c04bf83a16b192157c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000777fae0b6cd6f260560c65724985a042da7df7a6f132d27c6fe111c9290f8cecaf06f3624f426250b49b7e7fa89508500000000000000000000000000000000069b4e74cedf01869e6d633aedd210347918fc53f663ea3ef0e53a39d5da9feb616f02aa96016a3ba66b10318e57f4f2000000000000000000000000000000000d0366d217481ad7137df055349a8e9f2292dde0e30610fc19a57f480e6eead369e3cd4ef3896a3a559dbabf1ab766f60000000000000000000000000000000016ed4ca3f38f1435dfdca3d4e63053711660bf1088b6f4f2c3e595ab4d6d83541f0098637a1613fddbff12784ca45e2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7d68f815d6e9e670dd2b3f9e254d5385f3d36db42e0d8c9dc148c41e7564393330d5dd7bcdd099a64676ef2b178304000000000000000000000000000000000765abcedc72d48c62070dd2c2b81ccf0211ca302996ee77b84294d7491f15f005dccb03b994f79060b8392649f48b9e000000000000000000000000000000001862ab3ffcf336cce1498d82f7d72ebfdc28c6fc6af7f8787f5a71ce36170a243a6b6fc72b03c925ab0669a96dccb3360000000000000000000000000000000001a273b2752edfd56381a1b106fe1ed691e173633c3d463c211d474537ece36ca0900b933570d64d6113f2170ac3da971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000189ddc1115f06063281e58e42713da114bcc7fef3ba4cc973881d0f350d3b4f95c3ea1492737b6fa0b47ed6a5dd79cc7000000000000000000000000000000000a5f0d7c0014c0a9adc1f9b2247260bc5813b64c0dd079e523034fe0bf137533757c3e8cd23243ca0c0df9e00cbff3e70000000000000000000000000000000017223b26c89a4d7bbfa44e197c2f54890cfc9bb9d1136a7690b8e9030df9432421dd9280e311d6a1470ec0c36f79ab060000000000000000000000000000000000484502cec0ad39ec237c83dfdb99651bc090b42b8a7edf1e15752a726901e3117d616456d313c3532dfd02bab2555e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008cb3ca43220f0e79eca8ba899a19dcdf2aafd3f7b8728506773ca9c458f8e2e3c44c72ad5f815365d0b98a12ad95244000000000000000000000000000000001683608ff07d3f38dfd3f11cbd368d207139eaba6c5120e18a48bfea68b6a1e3a2c51c49dc148d30b11f69099689ad9e000000000000000000000000000000000426ec6debb43f340c5110f830bc46e2fcaa723ad2bea1d0db3d98414d46172af100cbe27d71e208674dfdd95470f817000000000000000000000000000000000978bc27dabf88d58426510ef4e5e6dece2fb22151df5a8af1ddfcb05a9abae773e94e9d9184881ea9199b43bd2f30941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000066dcb061e83deb38b45233b2fc41417f44d3c7355ac318dcdb122b85df57e4e7d649115b62624b9da4b27c78b74c214000000000000000000000000000000001162d37e829ef40bba082dca59b0c3541a354a31de7f745a3b2e976ff5986ec26f4660f077ea9c7024c912e4616a1d0d0000000000000000000000000000000001ff168f874f3eb9350958a29dffe6a12cd5e262b79f742249ed5f514ceab20ebd1f3451270be153233d02926d93f3bf00000000000000000000000000000000056a0913ebb34ae39fc33691c98805dfe1931d9cad0ceb19dee33fe4a1e45e44863cdbac5d31eafbfe3363030c20f6bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078be24ae206e04e873c8957b9edc91a21b53429dd25e60af0f505c6b7ffb91db832dc283b5e256a080fe295fe41ab38000000000000000000000000000000000caf223a522a5b9b3bc19a4d714de1ab7abc1634db8894ec56654d98d1d5fb5c2c3cf90aa55e0ee550f47533b2aa3d5d0000000000000000000000000000000017151fc25c8f05d41eb4a5bac124ab137061ee13c29888ab2bf111ec468c7d4b02aa0c085d09cc6e45fcc786aec82d580000000000000000000000000000000014d8f39110411107f058cc31b6a3cac03a7d5bcce23e4264b0b6a1e5452ab5c3f5de123c5256b5757a0ec6d3a9bd1ca81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013e73ab575a40b395c247fbd68b4b0d23163c3c30dc093be7aed74ea588d89361a785652d320c5536077d5a89ae4c7a0000000000000000000000000000000000db8c81c0fbdbe4e45548296e36fce418fa559e4fa82272a9e578ba671faed797ea46cc08e572428c95c62ed64cda67e0000000000000000000000000000000009643e46ba839f2d3004405f334eaaef1d2ad888a2456d63e56b5b9957128498d9eed6111062dde4b9fa6344c1748093000000000000000000000000000000000d2f6f7d6c67391b9300bf69f5af2558434fd03cd370fd654699d23702fbb3f33e6b1608c12747000160253ca8ecf5c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014fd247e8e6ae9b4e782b5d84f191f8f5b3a59bde4a0b9aa5fdd22f6597db0dd14a58813dddc0bc5a38c85366ec7f7e200000000000000000000000000000000119c254b242ff185465fa6e081486478d7148789dd86b38e5f75721af9d6baaf6a2679214316b5ca410c60900e33599200000000000000000000000000000000049ac54643db917c4576f724392b86070230e3a081dd94ae70a71ff6ddffaab4b145941e3047e3b4214e92c3df6034020000000000000000000000000000000013498d131a1da8155aa7faed75b7d55b2b60d0b79b4c199de4da6b87b82b90844a5531758b047628c4cfae136bd1413b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005865fe0238422b1da4ff6ab487fe389a5eca786f44164c9ccbdd7bc04dc2d2f7b9ea65153218757091c6402508590570000000000000000000000000000000006ed2fb68e7348168004786796ad4989f6d1a3255fe2d25c4951909298d0fa27666fe21a9e34e23b0db09591dd63011c00000000000000000000000000000000107b541ae7945cc2658836755c7adb4259754cc3f6a0a067fa05d90805cd1be339e81ca122f645b5e87fc376c9a3a4950000000000000000000000000000000010d4b65e277ae18d05cb9c469b749748ec2bcbffd2d661cff9e2f571f43c13a9a342e896b78121206c74306a2b98f4d11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015fce34cc72d56590fa28777db8af7d3a627f5802825bfedbebf9a9d32bf6ae41551f9da2cb81d993cb4d49a79287d580000000000000000000000000000000019458052d819c1ff8d686d893681b7f8411093071c6b03e8619bab346519ae880ad8c8cf50ffd2061caec0598656c06b00000000000000000000000000000000119a1f8007847c0db8774b6d0f2aa5f4a9c12991858927641ec4e7386c387d302eaae74b99042212d2531b300aa78302000000000000000000000000000000000ffbcf865c52c616ebba4236221572d57de4c98add09eb069a41cd86bcffc3450563264927ea45b5aaac5e43765c91e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5bc66f4d00b0be456eca378b5d27b97ecd11ce0e54619e7401b041b22f31731491ef4f50073823f13476be03a1da1c00000000000000000000000000000000113d4d650dc4a031fdaf180f9b8740a99721190ebf417788cecf17872319f40d27ff04342b4992d7ac91c0275ed302dd0000000000000000000000000000000009b6dfb4f31e9f93d331bfee7cf56bdcdd3e6f36019bc5344b8089362edf3ea6dd124030d3cc378281a62cc7138ae51f0000000000000000000000000000000002845de987222a9bd6b69af5632a839e43c6da4ded2e11a4fa55a093bb87d698ad1c53ccd332ff6932aff2cbcde68efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000573d3c745c6f0d7d155e49301f1db01eb4c31d3650ac1bc4c061afcda1d32b2fa4250ef3f206667c13f31a9edf1c90f000000000000000000000000000000000787a1aa0058b38e56106aadc185531d3ac75aa5073b46a1ccfa3a37c000778de7bb5116681a5e2cdae7e71cc17733a20000000000000000000000000000000008b4223ac3ce99b30baab19d00a0faaf46a2ee9257556b54b88e77c202fa77dae0465e5d6b59ca6ac43b0078959c1bad0000000000000000000000000000000000cfef6f7ade50d0bdf917bffc23f59c1256275620349a26b7c4814ad745cbdcfb49372fe2fe7a3c5f8baae14b1397401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eca2ec40415418a0b00d7505d5d49ddfe6af6e1403eb8c8075f666f52479bb0991444f3c0a34daba899af7d599eff000000000000000000000000000000000029654062ddb405e9e0828282b5a939c5bd63358700dcd14d40d312fd0a24cb5addf656501dba301087846e462092bca000000000000000000000000000000001148dbc03051d355430ced38f855119d4781c219e011bf40b0e14eefe3e40d95bd3d3a4362171475a56bccd2822805210000000000000000000000000000000005fd9d7bba5b16749c324c33d846b1d923ada7902c5e66877f238e60fb18281e888b37218cd831ff288223ffa9eed4b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017c868961f18f02faead4479c0a95ca9bc2d7fa9f038eedd645d0a69e41169e40e47c036a53746a697bcccc9433b3cfc0000000000000000000000000000000017dfbaf1c07e26411736267f0cc8dd0b10742a2fb388223c295b6f9ba34c02f15a08cc8a945a668c8abf9925f6797ee90000000000000000000000000000000006504aa29ea99589a7f70bd37a46ff658688d3ae23731a7959461e0ab8d34eba49964acfa4904208deea19c48e498f100000000000000000000000000000000003c6e943be26c1dc313a2d544ef9c5f77593125f44a42d8d1e41c8e53810f88708fbef275490be616502c8468041d4dc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012f646083fff4e3d6ba5cd860682f93031d3332b09bf561d8df2cba9bc6f58f866bdc87405689bac228234528ba2acf50000000000000000000000000000000001e0e095611503a7e916bf04cc85ca4461016e419f04ad6f8389a5c72f9b924ac54079c9f335b288c34eefb8686795de00000000000000000000000000000000019cee62be31a84b05d242b21a6772760b1e9ef2ea9bd3225f60b613a49958b86ec368549be4acbd07832adb7bf3bcb8000000000000000000000000000000000976113df5c659871ef972a42cc7e6963e0f4217667cd0a5d7e923adf8d0cc2eb7e8fba8f916f64558a9518c23f7e9b81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000009b62014432021ea5e304db73fe988ab90a5ec32ae7f13f79ee732edaba2c9fb22f9085019b2a3278024cde677041e7000000000000000000000000000000000a31fca503715ad271cbe652de608c8e9d5825ee7b04a40a1c708a438c2ed96d98dbeba1d2b1cd27859caded1fac9d0e000000000000000000000000000000000d0047285f64738e752642ade541a8332a5ea6f7dcaf6a3f6e0d4bc3ba8c5f185ddad68072885b79cbd294efc3efaa4e0000000000000000000000000000000010c6f24ce85bc819a3519d5f4f31457a40f110a0987137c7b479dc21b25b57ebef55ada63daa4f5589390b8c50c9ced81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e2f35e28c64fb31502e504dd16867167e91bf796ed1fb7c219b26a380ea34daa08a2af7c1fd5f5240900b61e771b0dc0000000000000000000000000000000000b9ac468ba0421cd63f817e56bc75e5d939f3f0761e0eaa884041175a1400090a5fa6f60a9d091d35d8a9efda98232a000000000000000000000000000000000a834bf52722c059456a6a5e5c27617fd3f34e5549966224bfb1f0b103bdea0efd8db1657acc28ca79d3bf93b7017a6c0000000000000000000000000000000009864fa7f76f6ad5babf6b5c1e313e618a0c860efc2d880bcf63929308255e8e69da502e675b413a17109c1ce1a175bc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001057362300cbf5c5cc9755fb6a0c8f82932dd4da6efcbbea52ad30edfe0082d731195843c575fdaeae786ba15dce3b7c000000000000000000000000000000000d27048d7a9c36602bc97d42df08e34d45b7ab097f1201857d788146d0cf7a759ec9d9c151da2e83561cd2efdb92372000000000000000000000000000000000198e29d9115d2b6b7fb59c05216d1f35eb0c1ab9d123fbe1688d883a32c84989151dac23753ce0b3002b5c2f3cb1e2f3000000000000000000000000000000000311bfa53cb8233ddbba8cf52bf7aa4785d9db6a19a3dd84c41b196dee13a5948aa80f04f876cd25c9b7d97b1bb249781824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091fcfda6ee019a71cd4ee26b7552c0eab8a1f056702a80d23db19e9b10f5d8c68283c34732e5b356390387548dde44200000000000000000000000000000000020fbcd1c35b9cfe000f6ed8eef438f8d73d281bb4eae18e8c53bca70fed5782f588e0ce0815472168b613e83763ee8e000000000000000000000000000000000e57e3b4f558924ac1c93fe2c0eac2edbf53bbda1139ec2073af10337dbe5ca1c9aa6b3d0c6a276f1ee32d44dab890e50000000000000000000000000000000003005007d5837562b10432889327f8f5e1a69645b7f0ef737949fca0abf42a6f92ec463534a8f153f8a3f48d0e0542931824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d61cee7f0e3703ce621ab56fe946e4069409673ec30d221534239b16daa9026ffc924ad3e1a8d875be4398f1bc164800000000000000000000000000000000009c5414bbfbc11fae7b74061db6b039612c77314efc0515e6f2a470604cb6268e27b6f6efa3d3c851d89734d2f8ab468000000000000000000000000000000000d898cd8286930f55c07d3ab481bcec5afde71b40f30ec83861bcaa5f00a28ba3dfa86f8efc4cb9c9d35481ffd160cf900000000000000000000000000000000059830dc41bfe09476863c6bf42fca0145a194845d959c28ffcef27f40d79851d774c6d445d54635c4b52136530609991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000116bcc85f3de4a7bb502694425b0cc53702f0cc3f1ce8a89b3f21301c97e290bdd40f920c26f0f3d2b44c33f5b71067f00000000000000000000000000000000130ef144706bdd7de3f639621b4772d2748a5650ea95c9514a247e649a21978575b32d0c50ce1f997d16698bb500669f00000000000000000000000000000000127a6366cebff9a7b65cc902e3704d974d024c7b75d4954644d89981bd015c9ec749cb785c82d79f35ad8468cebf96a80000000000000000000000000000000019ae7097fc64cad02820dea663a58e6bff13ee4a4cb4389754f888614b7d2a5ff4b02a37eb428bf319d6873464d92a171824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049b52beff42d57446d9bcc967fea2052eb55721e8d89a93d67fadbd79270ce9c5702045d3dc00271a07318d6bab7ec80000000000000000000000000000000006c3f4e4a229416276a72b7d8035c3ba6a5202774e392525fcd630d3eeb35258e7aa854979464497c024f2006fe5df8b000000000000000000000000000000000aa14f5945a7976b6cb68c1b3c5e29b983945e868befd4b055db43c1ab68215e9b10e38d5203363d7eaa82f260cfe61b000000000000000000000000000000000bcf2914427f76a26068582e6bca484b78fa6ac134673862cc4a51db214a3f50280a815812888bab63b7c0eac55552ff1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000677555797c0627a120f7c8e1948e0cd56e9d1a404fb59bd4e9ab6820f87d0c3a66e38d4146a95de0dc8ad6fb2cc5fb40000000000000000000000000000000018bfeca1c774a454d6387bbecd9eda3d479f978d7d61dd9f1930dea4479f597a126a25e30f7dc89d0f8920fa2aaf82a10000000000000000000000000000000010eca98132284c3df31b3092d813463bbacb2e4e94ff0b551a251a2341dffd75bf970ba19777bf58d464530c2c8e75b3000000000000000000000000000000001113b849206ce29b7977b9d733b745a8a94bf587fc88a1934554b9ac5dae09ff733612ff69b70e10ec1249fc5a98acc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133c811f9ac0fc8c2120de60cde48c467ca5e668198aab0d507e321cc1299ad783b87af798de9526ff43f6427f9c9772000000000000000000000000000000000e57e5feb6eef8463f99ddc6f9fdd0c8c95eb10a5159059eba4835d522ed1055458176527fea044a14bbafe72788154000000000000000000000000000000000086381552e3e5f747b0de26aa3ff606fdf470c8f3fb5bd2fe32a2c4676ae9bfb899f1be405f79e3f32c54d940dc50db10000000000000000000000000000000016736c2e328873c987a9d1a777b6b9025ce7ddb0297346388ea6283afe68b6f7118998404b5b002a25e03d9fabfe667b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bbdd418783584b0f5c75e68015c63a28626b7a6021feefa6c5dcad0f1188ed559245fec5d678f00e41b8e45938d74f0000000000000000000000000000000015853bc65e68363e78c2b7e75e0b826c9a01721ebda605a6bf292dc4c48cd484aae92881bfa7639c995975a59c92b8060000000000000000000000000000000010f1ce4a87c6a3622844769e6104545c45068e91e22ef0bda4510be21fc61bcb66ccd19e94ca8f01ba20da89ad75de9f0000000000000000000000000000000010acd9cba7fdcbe38e8f9bb07b71ef1c79a082d4d7d21aa49166e3bde0c8e4ff35d7dfd4c5144b333a7c9cbd431391181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cc9bb5399e922540d7f00cb40df3e8f5194cff2c8ad86d6b6f5f356ee2b44bb213bb354ced372b4fefad42dbcc157e50000000000000000000000000000000005b86a1a5758146afbc52911c5cf7fffe3b0deadae6fbc830597be0431ffe190db7a6a7b13c17fae29ee01f1376c0353000000000000000000000000000000000df8d8af518013f1c39ec0c8dac2ca78334cc8b7d36ac57c892862a7d4cf41e232b7399ea275204f7575976ed5a236420000000000000000000000000000000003ecdb633151d2631e09e65c6e60531aa81b8217ac2eb9d4c9c02f3c1491623c840f9a9047695b55e0536167833c80861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000167b2acdc1658ac4888d01105cc027ead3be1219360ad2f3051d5bcda6b0d40689143782099e69d421139925c5b626e5000000000000000000000000000000001869ebbd1a45a542c69448c25d66c996ac93db6448d3e5371d23794597853a0da438b4bb445ab6e25c66a4b12169ac8b0000000000000000000000000000000002ed09ed34be4571563e430588e0a06fe8b986913ff6e350156a629bddfc156e58a4c254b3ffefa479328ee461e5907100000000000000000000000000000000150f09fb1ebb0c4583a9bf5b0b94649e78a668fa3a0b484aaabbc046d72c8a5a8bef2528acbb02d0c6657a8d88e9b9d31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000128fac6c562713b37b25d65b39733d48cf26f9db6e04f86ae5259a9c4a81bc022347cc72d686eb28c07d7c699056e925000000000000000000000000000000000a4708673fc3b587d9c786d26c74052510f214f75ad4eaddb820ffd623b25c7cc65b0020bb7e2a963dab6def12439ff9000000000000000000000000000000000855f569da42b2c6368383dd5cf89471ad73b7e06320c51b5c2b60f4ea73454f22c1383c730b791428ad745ca539668f000000000000000000000000000000000c79e2f552fc22bdc70d056713d060b5ddf808cd430e0f6811aa1f7594fc73244656e39c0e41704262a33d45c773c7bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f2c3b9e321c6792837de46f3cc80c2f0e40a6b53599954caa65aef3674406e47db224e56dbad8ed74c87965f2b179ed000000000000000000000000000000000940dc94e66fbaadd5cc173b41b267a540efdde17550798b5e00e3b1b5b1021f5d024aaf94b438a32fca94f62f64e5690000000000000000000000000000000011945c0cf903972bb1549e5cde5fca4b65433c6df78eed106e78ed13ff7bf7e91b2592bb132d6479b82a4a25dddac025000000000000000000000000000000000309bb2f3cf059ff552d26fe5b3d6af15ff9a6872440ffae64088e00cf8f6503a09c441ba626fb16c8ea0f8f27d03e2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000053c7c7cc29789b497886771b7956959437f8f30b3096977fa0afaecfa7b920ee0e4f10029f1b7044931be331d56e84b000000000000000000000000000000000a65599eacea617f1ddfac947b928b9e638838145cd91587ef1aaf40779591ce9328adf76fe9af573e839ae9a8b78e0d000000000000000000000000000000000bfc7aeb636b07206067e415aa7be74190ad13a7db71c869fa2abf756f8b0671bec8c5581f70de87f277f60de44590220000000000000000000000000000000003f437da111e8a98e22847a849b718e1481d95f33e9c0301f7e9af0fb389a823fb2f020fec7169d332e02aaad89f5c811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000276d9568e9a453e5e912a2ef3d0e0393f44354b876ba00cb4fa5a4f3c78ab8674d36bd08c358b7e29e6bf1d060d55be0000000000000000000000000000000002cc809deb00924be412d03d09e3dbc23aca77456cb6a92465615eee65e13826d5536c16845467867b37c21c52724c9e00000000000000000000000000000000102a3569bb92f49f760a2a2084081067c693dfbb9598b4450d272e130643e2ca442637aaa27e536297abde363b484fa1000000000000000000000000000000000b81ba1fd771dba95e76fbad68abfd3eac31f2a361d85ca9eece02d2763c24a60791466d77853b1ccf5f17cd49e377bd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ded75a6df70a72d41b99cda6fff97b7f40f2233700e7ad5fecf5460cfe6fd9447289848658345f029581b903fe91827000000000000000000000000000000000af19b9ce241193cdc1d229849ea8f52a98be4254e8aaf9cbb8e9233cced5f4bcb53c6d5e6867839e9fd630dbd85db4800000000000000000000000000000000032e13a3377f41c9544e99b68c31df0e4b3265c8e546040382f817584e97f0804a8f4819b2afa645907603d87d7426be0000000000000000000000000000000016a6b82210834d16ca9b75ffa17319f4b7abe9e27d670eb6b084de10184ad8f1cfb8247cda957e1cbd89927d2c6a11691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1f36063132cd14409372133296b82abb09c954e48c0436e65d3825fb1e97b21a447c416bd3ef5b30f1d5cd31ac271a00000000000000000000000000000000177953cbbbf705dbd469ba2fdb49d1116b12b9133ba8aacb58b6bf8c7a56f3fe552f7622a7b1337230d4740ffce0f82f000000000000000000000000000000001535da46034bc92cf6e8cff61e59014f531c1483e6fb2c5dd3c6b90898694ee005516fb05ecbf7eccac210a344c19259000000000000000000000000000000001761ac0ddb458dc3cac31b321c6746979ae08608f86e0e59b84c39c255635ae3ff4ff0a01e803702e954db2d85e8f51a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000026cebde043b9adfc001abd772a5847ce72a5671261ccb809d638f1f54e59860364b15c1a0b363bf927636ed8381bf69000000000000000000000000000000000563f92b65660a1d62702738a85fae4ddbf92aa3fe2e3754e595650653a297b15b07b642b023a1676834fc8b2bb50f5d00000000000000000000000000000000048405bf169c9a765f0ae653cd57c8f2a928088f2a2ffa516b52075dfa1e5f3fb6f5c15bab6c45d8663ab6f5f6b37977000000000000000000000000000000000656c03c520a01b0632aae184f04bad70be7e7e12c4364c411db7af5f2e50faa65d36d0d49d3e9ab6c92df52fd5fe7521824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f68b1c74be63488305cda0417131f23659927b276a3a8674ed03eafb2ad969e5e824f2bb8e50b5e2873075744d2be70000000000000000000000000000000011611f02d72abbb372660c79cbcd05c0271ad8a4eeb294d50946f08f1314266c772bf1a8fddf7547a01dd5eafc6ad76b000000000000000000000000000000000f5972127021fa24e5d7a819c6b457c171b3c538294b8f1c26cba6d75aa82c207a703ec097c9e9172a00c049feb0055d000000000000000000000000000000000eb3503f69471516387585a69fcc553ee4f367d67412da7f6ebd65e13f1de8cb782c540cd090b338e14a3b1ff1c2881d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011474a5ed1ccc1e1c554786bc61efbe7f24008d23a5b0bed5924a8df8e1f80b6202fa51e5fc08fe9bfb3e6d9d2db7e99000000000000000000000000000000000aaab2537c020f72e78ef34c253f7344a124998be9249121301bbb87dcee995659afd65b913749067fde70ed61266a690000000000000000000000000000000000c79f362a55ba6ae051eadcfbca2174e1d78f0c416ac1491542fddd3b32d20b5c6c28814c675b333fa0a3aa92268dfd0000000000000000000000000000000002cebce9fb34978cf0b5b69d0a41b3848bdb024eb0c263799894f31b2c84e7d3a75397172472ffddc0847d7af7f17feb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011e9c29ab7719f842bd439233a6edb540c5e3bca29e9813050f6b51cbf49ecd4d606eb82073c488198c04e67bf72c3b20000000000000000000000000000000007cc2ab4c03a762ba1dfd25df2476ca9fee77c0a9c3069d6e9a061f2913908831f19eaa5a9731661a54073f5e35e960d0000000000000000000000000000000017928018662eae1825abd3c460d02c9abd8c2580fc24ad2e1eaa1db3448ad9a913f162fdee3e705643c9cc1649aa245b000000000000000000000000000000000031c2baad28c6c7311b7d1cd22e5c7f5674a9e857210ae6d7e764b3ff802f1a271653ec15871797eef46cce1c74295d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b88e9241776f5f8ec1989ba1da8592bc3e42c4c67bc15bf28cd51903b2ec74ccaa470a1dacafa8f1da908d2e62dff4f000000000000000000000000000000000ce3fd106496c3d4b9ab0327e695b30f6827afb45c75379206fe8ed8b81664440accdd37a76e0a7eae6a414f612ac8130000000000000000000000000000000018e066eb37ea89ae8baed435e9b07e268c66ae227ce0bfb720935140f76baddf9e08ee390956cd112a6d34d991044ade0000000000000000000000000000000015d3bae286dd8a166527584cd15826540fda53b40af71e4d559708b711d589a356b4ec46c183a244dc15fe4b90610c421824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000103d64c1685555300fde5d9961201e76c53cad947036149c003dab16d09cc2d9bfdf1f83a20f822bb694d1573b5abca100000000000000000000000000000000152660692870127e72359f6ca1d375d580ac3983febc904ae0ad0350ad31a82ad78f8e7d4a097992884b990ecba556b60000000000000000000000000000000004939c5cfc08f76578983ca59d14786244fe8748a3b47f068187667cd37f1f0e72abdf6741def6e1384c308df10916e900000000000000000000000000000000054d5e9ccf0bc635e1fb4570c67fe00cf571c901d59090b5f44f8eeb42f05f62aadbef5d10f66152f05017159c38676b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000318cfd3bfab1360eba1f07b898108bdb5685212efd1a10bbb1e30aa80a28caa9b7c8799c60f9e606ae016acc55c22a10000000000000000000000000000000008d7620147280eb8562ec97c6802bec3a075510e85e5b6dd2c30485e0ddb8bbaf1a3b6d013900c40c0ab9c5954f53eaf000000000000000000000000000000001150c79e35bc45d2ce7ef94c048d6aeed09d55a45b7e22c053e82f7be06f41d314cc5b9f66bed7de7f260f4ceaccde0e0000000000000000000000000000000010f4792df33198a61964a81759260ba9c6b80288b8e1b4c133604c9b71de4ddbab315c78bc3c7ee10b5b75f44dcdbd2d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009fc853672e07ab70fcfc7c7e0c40b349be68bcebcb3a41632791c9f04f1d74c125c62bdb414d77d56aea5683ce636a000000000000000000000000000000000034826e0493904fe118f444555f85a0baa08bd88488d700ee1d0750f4749ee3fbede4a45adba1884db7388c2ec2654860000000000000000000000000000000011e5941880e4c8b8b99c8bdbadf695fe181be75f1f01249ce501186487960ac8e49d35df9796b4220394b8fa72c90013000000000000000000000000000000000b4dab793a4a667d7af2022bc5e18fc8d8a7879b6857cd0d427973f147dcded42bedab845a708002b6f28a8352fe9cb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015c9ab495e5fe7f2bd342fc2efd27490a455079801dcec626af30419975c37f1684f72b5acb41ef98aa56e6482fb270f00000000000000000000000000000000185b4b1668c0e0ed198d5d04b95a3d3a389c801e093e2c1b5727b0ef36f3b99a804926426d6ae1b791f9f06e88db58200000000000000000000000000000000002a399f8dedfb0851f1b6e2a4c23304b16cae8eac6b6b770c9f71a32a48300e209dd25011f2d94b748b95789dc91e3400000000000000000000000000000000000b78c49e9eaaae55372c80df92aca504b7391f10f9fec1dfb4ea63b35c15c09c4c1c4c0743173b55afd987e64413df61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c36d184d69756a2612eb7556537d558b332fe008c635299d2dd81618662803a3479d11eac43ac591c70bb5d4cb1137b0000000000000000000000000000000019243c0afb079774ea0248ffd86d43d68ab9e803358dd1fef446b0d7208e2cd2412289c546028ecdf7a5deaf56175d59000000000000000000000000000000000a500303a89da3795c41e7353b91f0f446ed0118cf96e0907c7022fb1af187e99d74fc83764bc8831f6a6a9281ce398f0000000000000000000000000000000014f08026c48f8485dea8ee48f78527a02a39aad64763e837b99832043941c8b3c0c962d12e5a545a0eb1316b938f16fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052c30760aca7fba6de13ee17ed14b41a2bb32423d4846e0bd19abf2d058589ba504d95ba96e0596a0be12414049e353000000000000000000000000000000000bd79ab008494216b3c71b1c614338f2dac580a4915d5afc2da53ea1d2dd2034e0791cf69a0c45aac015f62fadb4e7c000000000000000000000000000000000166f8a2add5a19b2b4024d9adc20043f259c92384324db829e09e7408a21f42ac9799a9c342629c6363f426902623974000000000000000000000000000000000c2746a502f50e7633dd983f4ff389b9ec25308b96561c97b480f95271974be5d27da266768fd771d2c784f93cb233591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a898e9bf6073147fb1e60102db677162003f1abd25edc5fa5dd6ab049254d4524f2d8b556d29fa3eca6435b05c979d80000000000000000000000000000000001f5ef70cf6a1d05e5aa5c8874def8738b0db2cb49db7c9af351ebfd204434331de56c6c6ef98de04d436fc5bf557fc200000000000000000000000000000000051dc3879cf41087d579bc0e8a7ea5e9064f5841ab44043afee45c0c4e3b32e11720f4aeca328ea39aecef743fe9b18d000000000000000000000000000000001383c1b6994087d9a0dcebfca28eba05350b71ba2425959bb064f868a782a36aa8a63e45a08503463553674b1c821cb91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009412cceab3a86856160fa4bdeb1d58ff1820523e691070850dfe1b103954bb9693f3b3041176689c57f9750bcfdb140000000000000000000000000000000000faca7a963fc6683388a896c30e02d7cf1f240e535eabbc3097ed183c8dbda4a4a3a12dd85e4c3022523e2a380ada35b0000000000000000000000000000000006c4746f6ead0992092871bbda492de9cb83385090bafbd6b0fcabd2ae1ffce99ec57535a4dad5c7f2db8486409899f7000000000000000000000000000000001129304e49fcfbcadf136841f097aa993179013aadc959a2c591bf8a1e641317488464ebad805ac2562994e2712f1c9b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017f5c2f7fa387f1eb2a22fc25e84dbc78ecb4ef72827e3163a3a5a693e336ee722efaa857e114064b4f8a170f628441d00000000000000000000000000000000186b1670491a0ff4a1d9da4d22d35fb3924e47b2839b3c531ab862456e80e2e6854bbb232222f42de1cd85706762656a000000000000000000000000000000000f0851a5c8dffc773be9a02500650b8a7c3af338bd334b4acbeefc5e076d60290137c9328e132ad61e04ed561071407a000000000000000000000000000000000e64ea24961341d10a35700dd2e771ea7f727bd18c2c0211aa8e64df540d4482a3e5a6dc95b24bfd136b3e082523d8db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002c72b172c14d6ce9a4acb132a1263a2fd4c331596657542335bbb149193a8d6f66ca6c2f0eae3e7ed77388b204c669000000000000000000000000000000000cb8ced85fd739869e64a13d15a331172589698d6019963e5863e9500098e1459fd1f960142f5320403f50a43f35cb4d000000000000000000000000000000000e4130995bed7d1a94aee38154766f36cfea3ec89488d2e7cab0b3205dc999ade95e37d1ddba81e496eb298b9a2a1b0c00000000000000000000000000000000103548e88f56e2d285fe630000fba9f9b0b8c0eae22c307d6e4cf9af75f282556e4ee02bb50486990b9b43a0624d1ec81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000273eb86e28dbdd6b2423884bcf55c83487cbbbb853418392cb6656f4f440056f8bd4c5f3d53cc8ca217647f437645cd0000000000000000000000000000000015d85bca79db13c5b3b7a889bf50ed9477def0e17c316ec2d5dafc039df11ddadc98f109a02d4f71680f402ee24d576d0000000000000000000000000000000013ac7ec160094d25148263a22483e84d88a36651facd83f03b1aeeece8d0fd93c0f084f921175c1cc0bc1df19e9c12ba0000000000000000000000000000000016b110d12d8d4563e972bc0886fec621c2ad3544c508d58ad424f9b80eea596799eeaf7cc9fce77ca6e35c43ebe171561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cd9fdb238ff03989b23a6783fc0b0de69de6b295141b98cebbf5f0fa2d316b3fb7698cdd1e6ad369dad4779ef1407c1000000000000000000000000000000000ff358ed45aaa6da0e2b43f850aacd4aa46a133c856289053d3c89134c6dab82f0398cac0df68bae717c4f4eed11751d0000000000000000000000000000000005509f7b37e168a8b03fc8830e9cde61e544b13e03b08d9fd0972ffd34cb07d98d53fee794382faec6ff58f3dfd86928000000000000000000000000000000000fcf3d4e7e1501387c4ad71e146c2cb03b30465fc3c5191ed4e829e37a948ff05dea484d969167a38fb63743ea7426d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019bce9cc56a47d29396f85fcc71486b1737441f95319cfacde19d7fbc53f7a053bce166ec2a38b84fb6221a151543ef3000000000000000000000000000000000ecfcbba6fc001bf16c004b45b869334fae017a57f5f038359633b9c3524f6449b7476c171ab23514e995dc88f77e1f80000000000000000000000000000000016ae2f78dfb78b606eea0ecffe24e4c4f085b49f3f38e41a8d6697e6b8dd32ddafdf1d7eb9ac1755d7942396d6f5e5a40000000000000000000000000000000011223f7d0410f677dadc11718667557ef3cbb8604b0519835f6853b06aefa80be64330ccc3457b7fc3b257cfa8584b0a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1a54fa926de77692d75a3cad9e71be514a3b2552c818ccf6c7fa2408afb6fb9014d2984beb460e9df5c7448d11f8d00000000000000000000000000000000014776766c096b363e1cd5e7128823a2ebe879dbd54face59eb5976ce84901fc5b9f2555a20944ae49c1240473717c17b0000000000000000000000000000000015a31c692b8f24d999ad4485fd1e6c49d1f4f3bb6dfc7f9eac3d20300bf697649a3eb5e3c8466f77096595b4d40b3e2d000000000000000000000000000000000c4a57c719b3262359bac95e3121ae0c651296c9bde0c91ccb6f734692cd0ffd46bbe64c37247a3b754a11f233af37451824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018dc66929e95cb6bb55df334357a7749e5860a0af7df982361c76cd6ee988c966b25a9fb1d8e2d3db9f3248a3496cdd90000000000000000000000000000000016337a847d4b22165257d5739c8d3737b846768f4b700bb9dea3a9921f824555f1133e1503c8f8ff361da013c011cb3c000000000000000000000000000000000701ca35573a82020128bda1f7f339c20a1d0f357dabec6c50394ef9e2ab05a1acf7a1e527cdae8ef7569ae389d7810e000000000000000000000000000000000bd4b9aaa17f6f93255cc93d118abd364a8dc9a1a9e94b794cd61d76dee9e977d622caa43442edfd2737e95a2c5f646d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001150376664173958be2ea5d309142561dedb2bddbd0aba954b6cbfd9db3759c0940bbc79352044706606d7c7a3d03ba3000000000000000000000000000000001636000a4b9423a751072c304051b1413434351556ad7e58b905f46fb0362861303abe34138370102497c16d186c5ccf00000000000000000000000000000000092752b76c60fb756feb4d98dcd5a776c68f8f8eff9962ad4d613007be0d4734fa5dff1154e25271287f7965435771fd0000000000000000000000000000000013637d02a5d90e2b160fef32b57d4aa271cfba5dd8ca373af7fcf3724fa49a7551790a5ee5bf54f5038ef5d75b01a24b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017051ed4d39e0abd5c3145554c90d0a4a478fbd9685572fde9d71be1a4f9815f4e62966f3f2358bba3d46d73d8ca54250000000000000000000000000000000010bcc4c0b57f90257fd3b62c0e79c93da0e5b17de9e4ad20a8c1661b182f7f838e460a34930115f264870e2e03322928000000000000000000000000000000001256736af16c9490b18c649ac67b5e1cce4d20fb5098aa9861d668cd502a69ac2424ded4146e2f08f048fdcf5da56a580000000000000000000000000000000004f81b24a6dd764ba19eca06df9b8fc8710a5821e31541d8c754acab7cc7ff01cdd66686b01ede62d2824d0c185623c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000195ddb1687debed13e531a304727c3f30240e17a1aaca98e517191428c38f5e25a735833f582b6bbc9486b28195a3d82000000000000000000000000000000001092620786f7846ac2dc228269a948a4de3da3bfcff07798a6fa9377c4fd879c46d4519eb0bea59bd49e5d4eaf86a1f4000000000000000000000000000000000ce50660ce6d3fd708fb3ba997b1185276ab8b05fc7ad763d7661bc64f31f0b33308e12c7e8ad2fcae7d9fe24347e40f000000000000000000000000000000000615c39aa9d1454e9ca870d896c4ea74357df18c1c21be9ba6c0477a3b8716e2c8a0e31f460236b23f6f27539d1503fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001955e0c0f1896185ef15437d7198abc66ba02647a4ef4af586c2b7750d71de0d2d39fda884791b0c66a0275f93c26bea00000000000000000000000000000000180176eed7d517031ed3a30a0c58a108c3616e00f6c70d8e020377500b2c44dfb40a0ce049021db1440dec84845bd59800000000000000000000000000000000135299be63c3e74f91978b9bcebad6c2f35378e37528ccdf06b1bd1fbf93e8aba219b40332969d1fb46a77b24f05370300000000000000000000000000000000080ea37e8a2a4f73242d764380a6c9b79b26d936e81977e6e2600af076f7c231d08b5477e7861482a54ac1e64aece7161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133a8dddab8df4f14c06f5b28f117053b02f61ef8c9da1356e3a81f81320804db033e49bac94a5f1e037b4104db396390000000000000000000000000000000008352f81c73310c31e31cd5f267303e49bb1490c13a8b28e09c5bf3d72deee1f7d15f33a1df987c9202ad89e18c36a7500000000000000000000000000000000041d43f619edac2ea8a3a15b9915ac47e31a65a0fb5e62833aa5ec93086d8371c0f9a56c0d8afdb3403141f7735b8a780000000000000000000000000000000000a31e2b5840129cf2f2b7389ef4ba5f5f4c255e81486398a2cf52408f14f5556790fe11aa57a08836c15921baa0e56c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002edf086f489795507935e3b941f89775548b6e897f3544de7bd7c5c759aaa30cd4bf60c0922ddf3c352f9ecf3981e0500000000000000000000000000000000162aeee3f31988622e2f3302774a01a6cc1e8993a2cd3bf8b0684953603994db7367a7d5e5e4a2d1dc8cc476c75d6140000000000000000000000000000000000a9f0a63bb4129716047ee984daf1834ed7d9277739059db13c735a87fee6f8092e218bdbbb7c1a5a6ae1cdb9f448905000000000000000000000000000000000b496b2a1f6e4f031b7764f56b20aa7eb70e5bcddea7bc36ce59f2a9139ad1945b55b907986ce95ea8c7c4a98e8613a11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009aaa77547265b05493ba1875a42cb8ca412fc010d9e706bc66343c15722e6e870ccf47f54d7d218fa4cdc06dcf2ce59000000000000000000000000000000000350878d2d873b3802f80594382e50f66eaba21f8559c61432acf6b24e3126c47a6d377fe39fc4cf89fca9aed09df7be0000000000000000000000000000000011292e077d168103f893090e53bd5abed36c8f81930f5580f8753f527d61a451b73fa142a57a1ea6da91693cdbb7ee4a000000000000000000000000000000000db0b51469338ce21f5a3dfa25e0761ca07f28236f9821dfb2283237c82a1c1bdd1be7ffa27124d00d31fb6812d78e6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000126403343c8dad4dd0d8e800aa59dc0aa60f4196a72f4aab76f07fa4c64ac48b448f12d01721a15ddbeb55257b2a74f0000000000000000000000000000000017d8b47e9033786fee0396e0a04bd3abbe4d014d8f9560502dd65c2c8420f1aacb821e011db7f20ef55f54f19aae6d6c000000000000000000000000000000001572acc3635d24bb78c24b436af8baf966eb167fff2a0be4b1d64b19a0fa881fe917b5caa6ec575db6a9f91281c7068400000000000000000000000000000000111f84b16cdf1c3781c26a3f8ef0b2e85963b1fb640862a7dcfc1aa46fe76560d5796533b60d6b9711bc240424b80e731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000079c8c39f0d403bbd3f44dc94ae92328b345058020b7f33422a7861891cdcf11e6cd4e0c4c77b501fb36ae2440f4ba8c000000000000000000000000000000000985b745a089245da76f6d87aa6d3c9b629ffb0b43905b719e2703bfb00a27aebae3eac37741aaa195fa30e8567b065f00000000000000000000000000000000131d3e353448c195068b752abbf0f4f394e4a8762ed13eebd3183d898f44edc5f6f1306fe82b6cf4935d18474109aaa7000000000000000000000000000000000f8041783b4030af0a3d88b724b4e0276b24238201cbe9753355b10f3a11d53580eea092c52f60882ebe00126128200e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001037cd0e7d7b00136f2702285fc6f73088826d0603ecca0f3f1498ea5d20e1d6a62360c0300047f8436c442f7efe13b0000000000000000000000000000000007906085170bf3493bf0ff17414c76ba19569a10b258e4c7abf23604f8638dbf414f7a20e6d9ed0019ed09b41e8216920000000000000000000000000000000005bf679a8f619e79c7f50f39bb44fd1c02ac18fe4e59f8c1c86cb56619dedbfa5f2137e42328b033f721bfc0a58ff48c00000000000000000000000000000000179ef36a294ff15c4b8efa726e0f500169854bc5cf5ee44def42f6c53e76112604e6899b661718a3f6c9a2db0ba1c3df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d8cbaf19363b801e11efcd5576a7972f0093835ca51077705545eca482bd70e3a666def2ad867416d8a08fd93c655200000000000000000000000000000000079b32498cffa784e0731e39c94229b2eba2bad5606f4aa4b89ad8f813e710d3f51de851cb1a38cdd5f52dd162f82a6c00000000000000000000000000000000034b14c6339705c8fb1c5546bf4c6a10bca33a92eb75dfa70431e65e0a3a1546d6e443082b258241465496231619a93e000000000000000000000000000000000b8e72dbb405bb9b98b62256e41e771c7f2e04ff106ae140f37953a2f84e4b00e97dca8088ae37bd96f50d0f993fd8271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b87d23c37e95b6dfd26eadf7f19cebe18229a04668f32384dcc73b5b17ad67f6375b09f5f11ccde6dcfa2256b4ed75000000000000000000000000000000000f62dbed8bc5090f1244fe1ac509954a97e771e650699541df4887009806392b7e647138a465868fd4d6d8a1a18628f400000000000000000000000000000000103dbfd9571687b5af84aa444cbe4abb314b042c7043101cc78185af539455104ec0edc16bbe6b53abc2e3568b7dca5100000000000000000000000000000000080bc7f1510037f91b1d769f0cbb49a373b06818c56fe8c924242e36bf4766acb3938c496e7621a5d2e9a3767c8a0b9a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f3f13801accf8766c1f3c9d561c3c160c1877474bd26f67479b3e7f82439d9695ce9b6086c18aaa3e34f6173f51feec000000000000000000000000000000000465674bf53e64e5dfe8706e0601ee0a176ac8cf3b34ac91f59180d85d05c22bfa2c3bb7e46779ec8c0503b19f88b7db0000000000000000000000000000000004bfb27e4312d7e090a4ffc5cdc14531cbfb72ec491df77e7de0d9b6938598b8e66e9db94ff38507539cd510c4dd59c4000000000000000000000000000000000154be220943b8ee38326e749a4994c6182ca4f791b314b4cb3d4f4aafa6b5182ab03ae3e3569cde04002d2fa1be55f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ea38a022397ba85a538fb2947e8055fc42002f121d6391f3a0ba92b8359c805d57764a8230b2bc15f708af83c339da000000000000000000000000000000000b39783edd1f7b77a8265198115573ee4088a909827b48b35a8ada6e6f424d334cadd805b19e887af7b18c9350b63ae000000000000000000000000000000000019f581ee78caff7ac187c1a89cb4049323b3ad1239c8a62bd7ed6b4896e386a3789dc4a47a9edc01f31f1e55da44567000000000000000000000000000000000929f30d804ee39c217b45f8cb18de3752a6935fc894a3acc0261baac783f0f30e86e58dcf4a5284eef8d7ce2426b9df1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007dbf0dcd22d0a03961397aa48c05c9b0e4d7ebf877d9fff28fbbd413439680a3c81802b987ae0509164f7777b66a5e20000000000000000000000000000000008349533421f0442a88daf60bab189c157aa17184cae1f1daae4d732efee8203c45f6bb27001e95ca8d583d74e5d65b70000000000000000000000000000000003025f5ce26d2d74c53a2ffc2b320041cbefc19d45349ff9878baa60d284e47bce97938172703fc8c644446a5ce004a2000000000000000000000000000000000ae27390faac2649aebe6a1818d7da58666db23398a044974c783cbc777abb8dbb06da01e735af6e12c70ea042d732991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017b9c67380c949a0a24a75113b4e2c86ab60170fc23659caac0d0f0f8e1b4abfd5b0ee58b9e8fa6c20dbc23703b1581a0000000000000000000000000000000014dc1d46a84e86e64db2274d073f193b43430dc167eba1a92604178bb25609e181765ef6585e778fd7db1229f649ae3a000000000000000000000000000000000f75446b93a2f3c5bc49e9b7a1424262a1ff7a3e742786424ea05334a0e09ba4badb4d9bb93362bb374985e74fc77b6e000000000000000000000000000000000ce56eccc0d98b184dbb892d517fa0acd694bb91dbcae1798f24b0c49d58e40596a092317584d02a63a2bf1cbf4740401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006bce5b221e27b2e3885c693a5b05cb508b317d704bd992e991e42001ac01ec94ae6b3322f77141013243b9f96d27e6300000000000000000000000000000000133520e5e823c6a61e7513b5df1338ead16bbf403a0b1b98754fcd1eb5b143b0b907be55f3bdc8e36ede2dd95c4fe12e0000000000000000000000000000000003fd7501e9b8fbd788a1ed9b786c1681b878917623ffc49c5f317b42947defa58e16ab6b95550c46b260fb46cd5621e00000000000000000000000000000000007f10ae4a3cd2fdc2b43c8e179301283329757971f2ec1fa2a54e1959175afde2aebd879cf182bb7060d379fb824af281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002e1f9f7d0048c82ab84c9b89326f4fa8a6b853df1be9b851705592bfeaa44a1ca6955fe41a8f634ee6097abad5b805c00000000000000000000000000000000159974f70f6e3d670feccae339352803dcc84efce07940d06ce066e34c269539e8e99a508bc5021340fc897bb57ddb5500000000000000000000000000000000077f9ea71f064e76151ff58e0ebfb2fe809f222309b8e86bc7e14fa0284cdfc52b07a38122caa12715d0f1caff1d8b770000000000000000000000000000000015a5241481d9759e8e57a68713e07f2d756129bcb651416aed40ddbd8b9bf8a03f61b272f9f721bf54639ddeb61211dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012b50a5944a9a4b3344c5d4c59db746a2e5731f6f61127b314c6967a8a5d7539431fa82d2ef095335ec590955f07b080000000000000000000000000000000011d8fdf2892ad7ba64f81432364ab96e61b5b27463f467134d885f1490d4219658a287700bff256be0ca9618429ab84400000000000000000000000000000000028f7a22571cc0d04b7e276aa42dda4f67ea8e3a576dce366bb795eff22b38d36b5039c7575ab496eecf6e3c78ac74bb0000000000000000000000000000000006f6d7dce287fa364d19cfae2406cca3fac9e068540d6d2bbd95ea74c62c70ffaa35abc3113a90e79a35c785e49f9b5d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ab06fbf3d816cf6549a7e687b1956ceb1862318b0930a813bd81051976f193926fc4e5d1a2d0f1812ff13819fcc3dd000000000000000000000000000000000df92ec37a7c37079c89c82f0f1e33184e9871d9c039f249dd78e319b1abb024b9315f77220fe94c43c66cafd884267e0000000000000000000000000000000011d8787ca7aa8369b2decb423eb0f8d94dabe02a2c8cdde843cce85738454cdf22c79917095d0ee9d1ee6780fcf571760000000000000000000000000000000008808e276bd25cef7ffd91119165f261656a882673e47ab00cc01573250b0fda3ff1a9750842ecd2b6e7688cf95001771824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019db9e29845dcd0ad33c9b1d0d3dc4abfc126873b637e1d8ab1d830cc9cb6978a303616107211272b996988329866d6100000000000000000000000000000000016e40e0d3c1e9ae56da9b877b03ea498864f2c7c8d5b9424bd29e09c4ad9530633774b83f7c6eb153b39101d4fa2eed000000000000000000000000000000000a54f39e77441ba4750a7f9a524a4368109f571b8535af89f6669531384d4e187d13f098641c1fc81d0db2c8d307303f0000000000000000000000000000000019cb93ee43cf626dc8d7d301e3ec84a41ad94f2c19906205b818ee7f2bf978428f62d23016403f33e0d6f88b979e39701824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019297a4adc7ecfaa534f652a409e598370c46147e7074d0ae847d3b0d20f0455a0f76acff49f7c09ee2fe9b9bdd4b26500000000000000000000000000000000183b0698cde4efc6b43ddf50de20afed7c3c6f385261248cdd22c348cbea3a74d93d202535717fa0c65995ae2e7406ed000000000000000000000000000000000ebe942f591fc05f70d0af5c899ff13e3a9f2c8ba904d972353d85e2584dcd5ff93e7274dab1e0306d9be507d6a9bf420000000000000000000000000000000002fd3ae56e19b0fada08380bc3ccee76ef9960abadbca1c603f9e6e304c01be96b763d9684a9c43dcdb1c8dc244267251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000175b1298f71958411a230be34e16fed58b5b17a0a6aac479d95e67cb3743b1b95b76f4676504702478e0f10ff3e5c0ff0000000000000000000000000000000018a55a478776c7b9fbd60bcfc88e45e8b7836d6458793f5bfcbcad2b8788ec8d3ac3a4542f573cb0449f49ddfc3cf83f00000000000000000000000000000000074b62425f79b4d8ac10bb9bad733ffeccf380f480f537fdf16dfabfa35cdeaec748e80f55a01ac4bab5aafaaaf713830000000000000000000000000000000004c0ef7dcdd20074d611ad06ff60061c1ad25287b4bd085642ea14bb3df8dab3fd2b6536c939b700e2af5057c75ee4c21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007f72e00cb4a5b217ce2b6294359fd979e0ef0918d36ea46471f193c7f4cc9fb86bd6ca1ced232f96d0940f6e00e32d200000000000000000000000000000000172506de01b301dc54980213329bb02ab14d4fb6c523130155b5ae5262767a919eee8165071a9795706a146556d74a3a00000000000000000000000000000000075878e455499f636715eb8543214f39c067873b3282e263c73877f11a4902c42357edf7563d8e9f69cc3336f697cc7c000000000000000000000000000000001821feef28dfb7507b23e29bffe9c53a1ea9abd99a63be06a7f41ef11ef8b848ad5bbf260bee74902b44d39cdc30a6d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049d5e2eec780221fb6a73e21195900ce1544782b7c7c2319ee479a70db21f71223e9556d79978b7a172f9a3b0fa18810000000000000000000000000000000008cc9886fafabf0f4b947fe416e0a4423a113a4f06cd6aa2931f4b51f92645c9710d7223e989a7311b3bfed917fea627000000000000000000000000000000000aa8d5cecbe99fda4813324c2e2803df05f00ce21183e10e46f4c5ac19e1e14f70a07bb9f2b55e37a9b9fd1b98fb5af700000000000000000000000000000000187dc3577bfbb50e1e6cf4e5410400469452230c41f17062c4d11421f885b8bc410954bee0e7aa1e39420799b89530841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000130d38daa9f3b5a0ac75b18c12c51f80f1e49de3a019c91cb82b67523817cd2434fcb557603e372c7cb496b95e935c1f00000000000000000000000000000000082371af4aa99251a204d91748ecda513156f43dee192cc71083cdf73d7d54fddedcdbfbefdb2d66faa91e90bfb0f4d1000000000000000000000000000000000c7f8474821020b02fb36b4b035c4014575aa0899a8a258558aa410ea0f13cb59d404fed21e95f7f97047aa5faf358d70000000000000000000000000000000010e6c26ac6b4fdfb5fa3b9b443d4c70f8edf8b63d4d170853780b3b55a707d0c3ef9986607c4fcda90d7b36c4908c8a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014c801768920ff74331d33930daa4aabb9040e99dccb5c22afd0b430a39942799f56c4205b07a1436f8575db5aa9a0160000000000000000000000000000000003efa318c88a612ef6919681d540a8139d1704f36218d256b01741cbe4a0aad5650f5bedb03baa2fb24f54455745da050000000000000000000000000000000007382864a35024f4b3ebf353b7d5903efade4be2da8f1f4a85b5899eca8007165c59e8d8847a1660e107503c9edd555c000000000000000000000000000000000eac240b773eea4ecc4ba7f4f8213216dd088f0766489d503e361b4d46cad3e1d52d1c28b4064c873d90dce1cecbab6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ee1d1862c3ac2cd03b2ee00c67a8cfec3d668c04d4c75963189a6b27ac32d0d9f606fc153ad3db968f339f7c55632960000000000000000000000000000000004b882ef9badbe9eccfc771b001dab81435a347712ce32cdda52a1d042c606d7423d939cf13c3ab91f5e8f1eb12b858b00000000000000000000000000000000179c72deb6740d42be45aab0d7f606c930558cd83e58fc447d282674178f61c1a94f8f1902d5d11dcfe51f5b504b805c000000000000000000000000000000000ff7bf505a5febe052206aa81022c9799a03d3124fa83db4d8f16f521b760521bfe928dc3d4b510ff93211f5ec5d25b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000679f44cd736a3a44574120a3abeb11516bcd4c6957b3ad0ca16253bfa964b9a151a517a76689a71ce959bee7d7f5ee500000000000000000000000000000000040bb186740a9a6ae78927c839b5121f22c5d16b6708fa3a573b572e9214572e273fe6791dd4f75b918a3415cfb8f35a0000000000000000000000000000000013064b61afc225b673274c2a4a1df3cf89becc2688ed92e42ef9e5bfd7cc2b9a0609e59755a16433ba0c7894d5b83a9900000000000000000000000000000000063f98c43791be32b4c7a07885a6622716e521754a982227258b1cebf4ad7134861d504cfcd4ee42d05716b1d2ec5c141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018d7524ee690a740a5f307238b2a720920bbed7929c2bd135aa25f38f4d73a161957e59fbd87da388bbcf5529ce960fe00000000000000000000000000000000060ec0e83dcb5c628ea715b6f549f37b58f1410897a466f650a9cd6295f3bc877db3a2f838311afc39cdc7582998ab040000000000000000000000000000000017b1128ef973b8bbf2b1b40d147cad2c433a6d180ed06d20df736fe5624d0d3db516b60537e31067860a187aaf7c2c3b00000000000000000000000000000000190988e4d55e5c407c394547cb3373609b3d959b8aad66e87a0d888dde1127c49db2784c5441a21116ce9207d396f6e41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000276312a5b15800f53987193dc84dfb1d2ce5672e5328ae3fc39e1f460eab23d42499f991dbbf0cf6a1e9e39b3ebde5f000000000000000000000000000000000550195b6b7bbd24a776bb0e0c405dd01734e66ddab73bda74f33e1781d9c3a81cf4c114a091b1192cb5e8949716ed6f0000000000000000000000000000000009cd1f1bfccdf21f61c17ae7d5af891631ffd77ee09dec82c8e5664dc3fc81eb3788fb525dfc4ef43323a328186bf93f00000000000000000000000000000000147287aa781dea3ce6ba5db8b25025940da8a8cf9a58ae5fc0cf592d5055e0a6fd848de5d47abf890d79ae715b59ae711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000101dd21251ce5222db7e686167b327a2f6ed2577d46304ccb975d36f547f30db8c0bb3e1905ac47c7c4855f6f77d35860000000000000000000000000000000016dfa1679a2678884f494c8c9deb60f8445a914c84c94a13ba4584ce590011014b9cd35a12c755175ea811fb9f21b50000000000000000000000000000000000192fe2061c167bef84d95c5fe254ea9e074071826eabee6542b3775ebe497fa7c01e0f2a2bc0042cca59533d213e19fa0000000000000000000000000000000018f929f25308da10b2d21ce7fbcabcff4610aef253fbb23c672daec107fa29a2ce82227ac130fad0be6fef8f58d0b8e31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e6b71faf8a7db82c34d89ba0f223c3b518ff14559440f306cc341048cd4155cba42f234c47d0197a59d5750df8fa7f0000000000000000000000000000000012ada1890a934f812332ab2787718dfe9ad95ff5d2d6a15160dcb98a42459d59a622057b46c90eac9883284fca2b73920000000000000000000000000000000012dce874a3e81bdce42560d8cf588f29f0b0e80cb00974f616f467e63f0c2ae924b76a50c4ed5c60c1eaea8561563bdf0000000000000000000000000000000016ca998a066416aca071ec812b5dfce0ce4d50e116c3ddeee5701e006d5d465c541b1cc2cd591329f47aae69498cc9381824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000062363a22ca6261947a218a24ccad5eb75c011fc52a9c001016209f837958ee13cf0b51c58fc41b534a750f5892438600000000000000000000000000000000008ac2ab97a2594a35f6c05dcbc19513378b91d973953f9f1dbc62ff2259e071ae900939409cffd0c10c8eacfcd7061ea00000000000000000000000000000000041e2eebeb6b79654fe232d4ebbf6805d8b963d4bc7bfdbaa3c4f407828c0aa7ca0050c99086498fa689804c18eb482d0000000000000000000000000000000018d10f2adb5978e3b17644cc48c38ef671e82b7fde2509452701abe02e2086f7b8050529e70766de391dd286540ed4391824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bfc68dc03cb8b80b19a2596fb49d682f38a166b907e13240dd6ac8d57b89ae7a390608949c221e771ccb0947a3a8d900000000000000000000000000000000128718b83ca9b9b20d06dd811ecf2bd3e33d3fb49b15006c5cee67ef6abf20b50ec315c990a2b28ef8d4e71490fcd506000000000000000000000000000000001718253f5faea86eb809ea9780cd75dbf2ceac93538c19afff8bcf9cadb3636e2e9bbacd6fba7940dae601ac9d16d543000000000000000000000000000000001090e127447cf3d84d863178b6b39e580aea4e1c7f214d02d3cbecb863145b6916f41bee779a0e383069c9c8d60065fa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000549371d30d49bffc4021f3a926164aae90b87c58cd8579f6857fefef519c52736f7bd154475bdf6bc5378a33c1524b600000000000000000000000000000000017394a396578fcfd49fcbdfa362ff99705624ee067e25f551ad37e03605173556fba0fa0aa52d261df9fb483575f1e30000000000000000000000000000000012e2d0b76b73fe55810acc2b6f6128d672c8acd4fa3bd7377aa81e4f21d87d8103fcc6c965dc798e89291f42a643f837000000000000000000000000000000000599888c960b1c253910311fceb07c21e5cce03f68bccaab3cbeb043fff84d462e81de2f1f6bbc913d59f24f110b5df11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000177294a4e2144b42b011ec7f86ccee70684a5b41eccc86d640386d8bd09f55e27c349404395d6ad8331fc7ed1ee4e8b30000000000000000000000000000000016ca647a9a1ae4a29c0fc3bbc462c3c624915707f4b2b5149b52c96661dc34bea10e5040e25b176a22c677ad9940dfcc000000000000000000000000000000001249f0d55d94e8ed44baf565ba3c14209eaab9b4546b17c04f5b56643aca1ff6f5ea961619036047c08ac2e37a4f23f5000000000000000000000000000000000937c9fe540d74bdb5b0a73d984bf8863a122a22fd06d21534414330b673dd6a7e6ca02833f61e79161234c0032edd1b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009bab0da6a2235936692a0f62f4cfe20521fa94f5d11e52df052c4c8d869fb94d72a64fbb2b805f38af6e7d30236cf1d00000000000000000000000000000000153e914116d1b90a84831b1c53d7bca6b6029a1c58bb65275b552c3170de5f7a3b695e29be51b865e5b85ed8534ecaf8000000000000000000000000000000000eacbe9abce096c8f98a2df5098fc4ae3f9d885926077bc32b52c4b88e054d65306b7a8bacee545df0b6112b850b9fd4000000000000000000000000000000000a27949b36f57bcc14679b2a4dd52aec709c8431fec29de4435a9783976e8b22cc9a30863ac4fb6d0792c76c9dddea2c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010d2300c12bb6218dcba92f96402cda4bc3c039b8c63c546008632ca4106fcebfcf5d8824b745bda87b246d5f8ffeb1b0000000000000000000000000000000013780db322d7b6cce8f35fa17f16f59db5f44b91550d802cb36f7c0c88704f5810b948e3a7d529d4274b0e7f9e05b5280000000000000000000000000000000007034a0e82a33fc50439a6dd4fe5101869571bb6c9933f83d47573da714ee2a5887683bea688238ab1da9761c7a24a86000000000000000000000000000000000b60f798acb7595c3c6f66f254d198a2bbd0e2304e818718ac15cac0ae811c2c98189bb6c2d6f146347af83a34db76c31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ac34afdbe2547d23c6c16a36e877c74fd9fdbc3990b70379f0a9a2a83a770fb2d54bf1126b80df92bdcf264a3679e30000000000000000000000000000000000bfe81abd2cc11486fdc7d455ad814fade8a95e0d9ae4a38cf487d2927e14ca84f6557e1857bf58c573bc6d0285d92500000000000000000000000000000000042e91d8c0cb8dd9562385cf707864786d1dc1c7b5568d1aac58a8709cb4b0f12d27807feed96b12381f246061b9d8350000000000000000000000000000000016cc27312cf0b40ddf2a0e32801c64076b3b82f0e7b13b8e623aac5fba108ecc6e48bc6c2b1af2334ae1e110a01015501824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000135fdff40e206b4172414d72e5e8a2b14365fcd69bd1727aa01a5c183810be819b86c0d80906b27c168021900c0d031600000000000000000000000000000000081fb85f2010e892d50cf843e65bff69a063016b24c9432fddef000f0423a153a17e1d2693c68815fe509bb82727ad77000000000000000000000000000000000e22f5ba0deb00d09bb53f29cc2f74000f28cdcb3808f02b24f393b530066328619b2de26c583babfff0f61e24e3f25800000000000000000000000000000000065ad005050ee95c321d012275ed4a643acc7f4008c2aa92967aa8613cc10807b72159851648e4d9e5404716dad6f1361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fe240eb31ae81e9cf1bd853d66932b2003ed93779286c7f2fad349b1cfd1209d902705fcc3653cec702603246f27ff000000000000000000000000000000000ab7809d6c1e5bc804d4f7c85f31a38de7824cc67ea24cfcfac032b38f724a03b626647b3d4862dcbf58d7de2891c29e00000000000000000000000000000000017727af51675aa339e73f44bfc470b547ddec2a093c41652ebe7afd3c3aaa679418056c44c2d25ed353774cff94569a0000000000000000000000000000000006dd33f65a2252293e3df728c405ed25b4d04e3cd3d699009f5fa81a73570811c82334a466ff1cb92cee8ae4ee9320e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010561cb107e8493fa542f341c9ca67f59f1e3d594cc21f95bb54c720159297e435b4e4b4976d706e28a2b6d1366a5c0c000000000000000000000000000000000a96209093914d1bede9cf3c71c948545f848acffe94c82885219dff5779307070ab5b99ecd899903546c3265f35a60b00000000000000000000000000000000001048989a0e6505ac0679f82f58fc56bd5c7c6ee24a6602093055abcf9deb45a49b0f607fd81506408152b4f2e691390000000000000000000000000000000018daff12269d6aa42ff9a273c61bc53dfc3b5e527e51f0d852e186e67f977d6a139d21b9604afe0545a2e29fcd6004711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006366a86469913eb09d73baf15c2a775be36773b9db2544f9e21fb92fbe11d93cedc4ea0bf480c3b1bd3335e193d974d00000000000000000000000000000000126126a48ad1aa83a743a2d87c1fdfbd62ba65d18b564fef9a58d2c1fa24e3de8e36f1fd06122e72ddc23d51f843704300000000000000000000000000000000011d326b1404e62207ea95efe2e99da412381499d26c4c878ecb278381d870ce87df614d21926988447f66ead84e959f000000000000000000000000000000001699bbfad9448ee94f7cda86d624a47db405efe28fab6bfd88c82a05d6b33941093af0b1f24b50fa33c355d9c294ac231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004c3424afe8eb2df5b554bd8760c6e1a5c7b52c9c4e18142c1107bda305eafa2c1a7266799b8d585f6356810ef4dfc730000000000000000000000000000000013854be6fe7bd5a4819bbd8085d89b868e98d847c572f4ebcb4364afd55765dcb9038eec1969c302b5720d5fd64f512800000000000000000000000000000000004451ca2a146ce88bd007a5352cfb886f2c0d3c85963f4b9bc2e00db68c145c6b341ce5fa2c4e86dc846ed359f3c1da0000000000000000000000000000000000fbf20093dfa5ca56bee01884d75be9814a9b80ed5c1db73a64d1a80dd7b15854936a7bd15dfa0b1f7154068e5f906f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006434964546d700f66e7764334a5d51aa3f2bf0eb9355d957466792aa7bd493a856b4b4b6c81237eeef02e1ebc289e3800000000000000000000000000000000126921ca5e56ee4262fc5d9812e88e4173f7ec393945c67f0df3aa0b84b9e595dfa46f1bc851b46952f184180487d547000000000000000000000000000000000745520de7871d4f3e2cc8443e24170a4ad3696640076562397b6e65eafd235abfd2fcd9c40f799d4a1d8ffc797bf5f00000000000000000000000000000000000f3bb7e229452c2e96df937217e484932488c6903b5f409d2934b71a2422be034934c36bcf892cb648c0d4538a559d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000108cff35edfc19996527bfe881fc7391f4d9dc10b2e5441eabbaa23cc48e9b4050217c74460c779ac7988e124a8c4622000000000000000000000000000000001813f0bd823de40e1a5a0d06b650c22055bf376c38014b85fdba4fdca5ca0578eed080f1d26599ad2abec32a5b176c1500000000000000000000000000000000004a732350bd6b265055bc1475c677f683fe388c972931daf046c43ac36b53b62842a4f685af7dcc2d0702b24db5dde7000000000000000000000000000000000c43328fa78310b94f125c6e1926be7387c181690d18d13d6dc93cf2bb995143cefef631e44bb50e5d6173f52483c7251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b36a7521c4e15d11c7c8bd3b10a74043e36aae4414b860588ff55da7de1df9b397ec40b8dbee7a10af57315b6b98a6600000000000000000000000000000000170e84e5f96eed4d8af494da7e2c8a4377454a6f79bb5df725a02b985aa8077fe34fa9007995f957d039a0d054be843000000000000000000000000000000000059c4c0992e519a159d00c4afbc20b9080bad7b770ad9cf8967b6e4e31d8d3d70615c9b073bd48d26991d4ca8c412e5f0000000000000000000000000000000012a1c6f0f93b3ccd56efaccc1047190c2161e86a9dc1f167c14c87562d8ca4340e4ffb2447724b33797b6233503801741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011313edcdd41e12877b8ae3be5d32bb251f16aeb545d24441e0310c9a9e82bc6fa29053c1f0a49e766301ffc511a6faa000000000000000000000000000000001024985dfde909917c1cbcd32c070b99e485a0695b9eaac558c5bb96a8b517cd3851a3458c8a7021a871132c33e26f3f00000000000000000000000000000000027bab13bfaf0076b436de3f071bbd27276a3cfba3b68d8d0f20eb34e6f16ce617cd09f06aa1cb4e8f3824b4c1adc1a500000000000000000000000000000000070901a56579cc144a2426ad7bda45055c9280cbf84b754262cd337f10a7d2abb635149b337e058b637928321ed32d8e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a9ea39cfcedb8bc4affb781c0789e0d323e61655e5be4d3fd1d5c3bfeafdd1075e400d9a476d5f7b01a8162f782e5e1000000000000000000000000000000000495ce7d909ed7a478eccaac7ff2bacc25c34b71921058920dd46caca34cff8d8e8caca979858d9db72953651975bc4a0000000000000000000000000000000017607b61852ba9d3ced5719df1a4324359cd251948d15091bb19ea443c9fb2fc3556bb3116fea1922d17c9f763c4c207000000000000000000000000000000000ec36466a3dbc41d20b06219aa2e13442e2249868337b707526c6d81e60c861e2c9a0f923c6793fec50ea24cff3479ec1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9b306ddf5e76b4af38833e1881aa1c1327be40b5df157e4c3d18334dedbb8a8a9c7840b3957a6fe0f4c85e7d5bb0da000000000000000000000000000000000accb5bb88a764d71c82baea2e08456959c8970bf60baebbc91162beb3ee876c58a68d6c0fbe2acb2c69eb55d1980cd000000000000000000000000000000000149f49e9c9b7d1d68e45a26cd7cf88bc93fcf90e156790630d1e3819a63f302073adf8531d1fc2a71710ed435205fe99000000000000000000000000000000000d38cc3e3853814d20b1ebb20d396b1b87992754e96af4a6cbbb0d7e9ddcb771b3a82a622a1f786c923c129e82d857861824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009c2996ae6122a98a9fc36425c0c22b6b00b82f9a8a6d86c28b000c4204c67c8e0c5e176193fba8e696e80efd993ddce000000000000000000000000000000000d3b18a731b8bb702ae279d5bc8ce5a20c4be033b502c115f683b2656c3de600ed94088cb77744850c4467aa98314f940000000000000000000000000000000011179b01fb1289efc28fdd7222a72966eb38c63bb4cb00c82a2fb523d341c3c7b0cd015d179a8c1dbf64163b34b7145c000000000000000000000000000000001034eab1f023c61c54b74a9ac7e7c50ecb4a6a889939da3eaf5cf5ad5f6ed33147918dd627caab152860436284f679301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b35738c36134d42a50c2de98cd85b8943987a5fe933de2c92f44805ca1a24ccffbc9e634ea6ad18ac676fbf938a2a7000000000000000000000000000000001538651d78ebc75bf6f48f5df8d7e44d91c4ca1e3b1babf29a7df3059df88188a5c555d963b03dd6bb3b4488cc488490000000000000000000000000000000000fda0a0ad3ed83d7886da108332c34c7099f59d06c9c63977aa41f092ac0a54c51d248bae2a8c7bdf72d683dd92687e4000000000000000000000000000000000a375ca1fb70fa49906cd14ee29a13881e3cd4edf070a1226dde07978d8f619bad96bb61c0fc9fc05c21af7884151f251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019da887951e85e073c7c46cbd86f9fbd821286d41cefdf8bfc376205d9c5fa5f9f936961fa6b7fbda51330408da5bc220000000000000000000000000000000001baf7646092529287a2ee35c5dd9112afccd5c35d4cd81ffd43542c6e828e48d56ad392551e8348fc53d39ffc51a5950000000000000000000000000000000012e987e09e6332e115b672f3b3c118f1f0148155e4ad9fe1aa31492c8a3ec5dfc0f55e448cd296e2486931730e8b0a3100000000000000000000000000000000029bb0c0bb59be221afc85c155cae3c97cefefb6f6d1a0d8c2b3e9b881672afb3618584c82d3c9d40e083739187e68ee1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006a061fd60d00ef87feacc12cdf48fac79cf32ca64fc1fda9bba9b13eb67bd54bf66c86e7cabf3ec1105ccb8b92caf6a0000000000000000000000000000000008249d8e4d8105d4b81940acda2b0c096d4706fa6b1ef604dfc66eaac6a8f104ae7445931db027e18df9d67d2460b4a9000000000000000000000000000000000e66773227bff5fde682a98755290699e743850ac4091f8a3d9904d094e4c6fb60c89e0484c9d6376c5648086790084e00000000000000000000000000000000190b273712deddf0d85454deb4bd92494264c765ae2f10e359819db4ac9bb0ffee8797d7b7adff7d863050bc0d179be81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e08dbadb6ab4b9784aa805a8f73d55655a293f91bd454248dad05cff6ecdd6cf4dcceb1765e52933012a12cbdb7c3eb000000000000000000000000000000000c71d60bf2bb9fb12e570cd4ee6d57e39e2170bc47aa49338bfdb943486ad5298e59d2ff37c0bbe6fabd1bfd403e6c680000000000000000000000000000000010e10fd7cd3284446e8506d577e31401bb730be96418b97160cf994077408fed9c7332d2262909fcffe05e8a2035ea7b000000000000000000000000000000000eb03c999434173772a14d3639f0a4a4dfdb800d34b38e56a993bbdce4b8edc37f6c454be8e3f4adc8541a5872e4e9d01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ce9d0227ba905b527b5901550ac3185ad80ea07847d357ef9b5261e52122f0b21ad41109054b8f530ee6508a366bb1000000000000000000000000000000000b983c40526952f3480da633d6a0a3228057a1804b14748066c8b2e1d848aabb62e44affcd35a7da0134a53722bb4cf90000000000000000000000000000000006eef96420d99b86b95e61e77334fd04a7bf5cd2d0712b0262cabd5d61e85552ccf3742d1af392ec0774cbd19705ef11000000000000000000000000000000000bb9f60235279c80e18976b40a10fa7cee7f40c4f26e88e6c518f23886a2a72f2ebfacd798b15e2794cfcfa2402f122b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002ed80dfd93492bb81c380f2983a48c61033cdcd0c8e65d960d91c88e256ce5dccbc1d867b113a3974507e5d6601247e000000000000000000000000000000000608f9f60a74814aeb7badffad1a3282e8f4468d3cd016a54734733d395f661dfabf9772491736a3df371b51f1519622000000000000000000000000000000001470b48e11901d3b36a8fcae4155090f3ed66665a74a686105c7c9720dc8f8078130beb5e29789c97ecda31620b099e4000000000000000000000000000000000d7bfc7fb471a3068871e08cf8279512f25ecc052c68cae84e3b5609d84ac64c6c39dbd6c3df98b767da729a367cb4101824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eec047b9d63a7b31a5bc7a16ef2ac626a7b1885fe1c6efd24eaa31beee23eb839296cc5ba74cdaa929ebf3d7cd81277000000000000000000000000000000001046a73424a7c9e533361ece7dc2fd0381eed96f6501dfb19025fd9f175f71a4d723d797f02a080c283bbbe1e3922f150000000000000000000000000000000014e451848cec6dd4b2ed6aa4a1976fefa34f382be497205347a521337fa813a6caea7519804bc24a0149c12f073babc60000000000000000000000000000000003e6ee5c2ba37f65de587e48f8b2a0e098ce36c87121896952c86d8db258330c97419c918e51815e60a90a8df3be781f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e17ad9aa80a485ab08b7e3a89bbd402a6b1c0c183759a6090b2c33ab52a79e0319d68f676cfbe9b5cd57c3c502fb8100000000000000000000000000000000092338ca37a12dcd7a2c7991c2e1ca7923508896a8205aa190e17dd1b08e9a87c2a14851ff0d13e47109aa2b5f009bc20000000000000000000000000000000007a463f9c09de4b3c91ddbffa4a337271b7a1bba6462544cf0b9e304570467b82eb5f086ddf24023c7bdb7dfe8c4fd0d0000000000000000000000000000000000732bf09cb2051b59f8cc9b3bb247543b95ba4b8d9ed7a4c6a4b89f03786387f4ab899b6f47eba340d13cf7d12f087d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000006225682eb4ed0e52bed3e85a7960f722346a1efdf53733f4ca4cad1bf92c9e4880b90c705e7306617ad750f2d94939000000000000000000000000000000000d564cb26c440ecf1c73092ad5993199cd74a04f3ca50e5e51819c5562d58d5717ecb3e2b393346a47f70e787ed79472000000000000000000000000000000000efaed6ca12b94442ced852dd6325916b1789b1639559b820c5aab9e854dd47aa49b26318187d5d32ed65f00d4697e1b0000000000000000000000000000000019b73586a45cb579e3c1d9935fb5b63d5e8620054f4f4bff089904bd3537dabcf2885a2fb11fd22bf4f00721876828e71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000178823ed42745258a61944f28c33d4e2e620755561bc44d72f072e3fb933c43737d03eeaa06d901a5182bdb423436a0100000000000000000000000000000000073b0e9307b2a457eca228510164728a261d2ab189754d785c59ed95393560bfbba0d2d0dc8fec7e8ff682d20fd8e71e000000000000000000000000000000000d300ac575472c99f1690af3e52c22931769feebf4b50d99710660431b2a619f4a95926bb7b8e965edc590a24bfd4b5900000000000000000000000000000000028cd64aa95676a2def419a8fa639eb9a4f6361261ae323367c2af982fdb10036b5768b5101f7c501ecf875281d51d741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000072f86f3c90234e4df352f3966e542e9e7577132cba049743f63ad4054b58e30a09e12489bef6cc485162ccd45e00aed0000000000000000000000000000000003edcf4a9db723a43a32b48c81f906cb3536370935e30a3ff46933310d80c8fdf3f1c5c175128f63bed5e3a8829c20ca0000000000000000000000000000000000e0cf2560e89853f0d2b0918c62c801d20845949058badb2d7e0028b19aa35dd020102d6b29f89a41989be41d6d890500000000000000000000000000000000022f3b233d23b1bbc21e703dcab3caeb18a19b009fe4a6989f3e13983ed8a454bbbc7f74d4145625a5b0e85cddedb1581824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000199ad3ea86dc2b02add5d20479049ea669c01ad172082e642014661e956916f08ff31670fe7464cb6a1f4e3ddb77ad94000000000000000000000000000000000ceeda74bf5d6aa1ea8f2e10d284120981cff618c632edd416cf60d2f67636ba93bc964958a12ee75ef24da9559fac350000000000000000000000000000000017b7060ebf3ded9cf1eb236ce0e2c880ba238aabc96e90e1dad35544272b699ff61856ad45860b8928d01a76ef21d55b0000000000000000000000000000000005b0315c2f3a18ac601accdd875d7e9c3ab759f86bfeedc7f184d0e9a38a21dd687049f98983590208c8527c8e4db8d71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ed593ae848e2bbd2542e72875c8f8a07aec2357b3123dfb71a70e2bc7bb42af8c54db20200a21cece183a02f2b834f40000000000000000000000000000000013e59423208b1454f01920da11eaf4c6a2a7431d7b15dffda0df76cbe868f43ef4b85b8ac6734e9b536c550a40bc886400000000000000000000000000000000179f713091a79a157231b9284c78070ededaa3ca1abb43f6e1d4182fce4e43a991404388f8b4d56bebe23164a164c4d600000000000000000000000000000000091e466f622aad04dd2261762588f67ee64a3d831a84983e810b58c97a049e0428ce062b812d0ae44bc9c88b989431a81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e97be158a87113c7f12d9d063cae42dfda54dfa7c6f1647a870e16f2d8bd0309a1f160fd0f790dc2aead4b5282cf831000000000000000000000000000000000665ef19666b2642bda49fc596625dabe772706950120eabe0d8ae7d7c9086de55987f43e2f73d68ce599d2319d85696000000000000000000000000000000000bac6b0bb94b4eab0878d929623b772e82ed8d475303917fd8e694de3cc2ef6bcc733a8c7ca8a1b48d56da6bb00a936600000000000000000000000000000000101c51ae4d592116e7362a630abfd85d78f4d9ca105e722050782d6810b360a954b232df6ef830a78d5fa9cbd2a953b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fea13830b82b15eea4e4d5a7626002f57f24a4be86f23a2bcdd97ad47b77feb6f4534dfc067dce4693052e5336cf47e000000000000000000000000000000000983408c20b090d49c8b10abc85d068a217bd979ecf73f487c3f687aefa13bdba714e0b6a681540a78b4221b9c7a0666000000000000000000000000000000001021c0ec79afc0edf0eee0fed313ba553899ac601faffac0f1dd1a58bac4dd52017d181b4809bfe19f1c52cdbbb11951000000000000000000000000000000000d712fe8c0723b94b9cf67863569a7eae660fed08127f66d183e3e6fb5524db4e6a523620ab05bf87462b0795ded75cd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018049f77560200cdafa9e36123d20bed8e1aca7157d97fd6c95a64cb02eb3f93e5bb41c1017534b7b1a78fc699758067000000000000000000000000000000001243c9c097da84b4bdd82daff0f63d480459f154199b900162d8fdddee11c8ea2ae31fa8a2dccbc0f7d1f6dd99a32d540000000000000000000000000000000010c9a183e439c55a30b2d830ee9f9b5af9b5b11703a3a43f630a195afab19d1ea3d81cdb99306f82a82bd7bcbf3cce5e000000000000000000000000000000001343e22d23306a18c266b9884458a260b6e9106c6ebadd39f2706d4aff343730fb375990ed78684722e7ea3bac069f671824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000163e24391ee67c2e668f18ca2c052d5ccb24ac3b427af592c12bed05d6ad929ae7767745dc99074eeeb8d63e020561e40000000000000000000000000000000010b5f5c330722ff6f4a3ba72fc7cb66c6d73f3da5f1ff144792555ec1dac509b1ce38c567cf8caea42de1e53b5b2168900000000000000000000000000000000160fe4c4dec8a24cf10c04572674132a929e95be253575440c38b107c7184199a1ddc835122a841635ffc2f2a20679d9000000000000000000000000000000000240cb3e0d8217788fef85e7e8a9319b7c70f5b164c580cb02a1a19a0f04ac02fb352d59c12ead81561c0380d34fd69a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006cc624101b30437fbad665a7862ce3a046fa6a1ae2391d54a9a203f20287f939fdb1beb9788cb1fe8d396ce07df0f6e0000000000000000000000000000000002c5cdb6ea3f8be5630799eadb307304a68d24b054643b96b7caf0f0b3e393d6552b38acd6ed8f2eaafe92694397b743000000000000000000000000000000000c0b70e788eac5ce02c2435441ad189a027c8f25190bfc48fd90ad9f2e528e426431422a7b19b484cdf11e5ab3c15f570000000000000000000000000000000015162730efd8432b687b5dff860552c0c899824b2d14adf50b8a2df4854bfa362d3957590b0c088b23ea1fd01354890a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e85d8f9b8f1c734df3f774fe00357f6b8f459a33a72a9d56bb6eab1eaba156bfd620466e7d8b516e824958b6143612a000000000000000000000000000000000ee3389a3e6cd163f0c489b63e0d863195e247042fcb719377ae13655a65a908031418a7ae4733c46b7997d707a848e20000000000000000000000000000000008cdb756ea5a4711b46c4956027a8aad41fce620173a48869cdac139f18fd39ab6c387ee4ae819a1b0474100487d07c7000000000000000000000000000000000d2248c2b03b7532cdb85a3158eeab966216feadb091eab3d5b8f877bf7b6eae9b35d00a0afdaf11698c86a9d9b3335a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011a725d9588491e79f44a2b34d1dca28d36987fe1b415a3d9f7be9d9a5fc2e1b21c096fb3444c0ff1e5421dd3be4c34a00000000000000000000000000000000084f69c3b49ded14de5e7143aaaff1fbe0e5b486b25d27cd19f3d70d87919daf0f426b0627efe414fc99492a6948b040000000000000000000000000000000001674cdde4b113fc1895f588a648545045ffdf123cf9130f462a18a1bdbc5ab8c5b1bca8c0ec642c398b2a4128439a6cc0000000000000000000000000000000012e73fe126a3d373b5536085c3714ca4f3761618b19df85d02b77ecb9acc8bc1110c321bf96e76025e689a0e300c90161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013dcd0eaf26ec02eb73468f8677f388b1ab4b8f7a02b3a7f22c4e87e598070693dbbc62e5e8bdd425db0d1d45d2854ea000000000000000000000000000000000cf94bd98c67887ea70f724f39a1a8afcbea090558611b3f4003facb46aff731bb2f105f7ebb3836d415661be902aff800000000000000000000000000000000086e8d170aa5abb237dabe0a9076b788cf6e549c2e48139fdb53a8b0d204051414bf596f8a4de4f02453692db20e65170000000000000000000000000000000018f200e0609e513136e615fead1f6a0577e6414378b7d35054e1efa713bf579ae103abf43dbe1042643a2ab33e8d779e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000091a48c15a56ca911fb46e7345d85ee4fad8905218904a9aa858d635dcc6044984e932f43779a32daac5937f3750285000000000000000000000000000000000c0476b0f7d091b458b9a455e79d9515d5a128123da8a071d32e5243d784300940fe8359997419d78f835dfcc8e2f7370000000000000000000000000000000009a90c08d8c7096f444a1c39ad2534b15b4da71a048e51845ccedc1f5e2db8faa534afa4eac4f98fd9f7d68cef918a4b0000000000000000000000000000000011301b5780b577be096fa6ddf2faa5b6bf7dd9ea4540c0aa90e5fbcd0793c893330ef2f5be2522575445d2c117de56971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084ce2cb8d38ea2bd4eb48c217472998c614c4c527dcfd8eb5ac56424e8259f5e996053448f0f60ac55cbd915309c16f000000000000000000000000000000001374404961742a306c45eea63ca8437efde40f7bccead29b3475dc0d7824b5a07f03baf913a0b66570a76e7ad99e77d900000000000000000000000000000000014b244d86ffda34171b4760a21d1d24520dccf606b74b96061f56af48d79b7f2af0791f0006ff72a525bf7364dccf840000000000000000000000000000000016a8c96aabb813750d940d7da5f5c43e214d971e615f6dd9c6aee0cda7925fd93003f323ba1c30b60f2c854016878bf51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003225c4f0f420334c2de4f782fdde19e3710151584d1d435f415559f5c3f320bff4fec8b600972ebba5084cb6bed09970000000000000000000000000000000010cadbeafae893a0f6bd09fe3fabea90c551977ee8494b21a4be3c945d7a84d4e438698b7d3f62afded7f4430e685eca000000000000000000000000000000001351aab4be82be8720b1ac0e6d87c88bd714732f5e98e999492f2bde419bc928a73ab4d8445d56d75f1c77f44cd0feac0000000000000000000000000000000000a0191315f15836aa46ee64f3c726ec953fa3604c2a2df121d5a1f6e56a03bd9ba0e9e4653c883b7ae3f0f91358a5261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000be692ae928e281521ab9465f096e533a6b35a9e1436c5cb122c0a71574a03c7980b211b8e4627e1c3ab7a0314024add00000000000000000000000000000000106f396f6b3ac247c6cdc28c14f147de2b007c14ff4028ec2ff36e57e8c03547ec874a33ca569d29088452a3a70f90280000000000000000000000000000000019c58669d1355fbe838019f124e87d8d2adb051cdfd763d70c43a1d958736af0002a0be49997d21fdec7a19fda75b2ed0000000000000000000000000000000016d94d5968c790dc23c5f83a995d7d3e98763a4a05a99b0ceed7c19392932b8ceb729099ea37b94c6d3e671be10881841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8abe44fad75df26c87fe24d81c37f3ad9ae2296d44ceccc55578f1c840d862dbdf05617e35b96976fa18ad4e947cb60000000000000000000000000000000014401d2bbeae4169398f55bc8a68d89c25a179b32d43e33d790a1f57a2905bf76c24993f5c1d0bb8bc5e0da167c8ece70000000000000000000000000000000013cd2e983d82375856105ceff18d4f3d7c1f37a15c985f26bc4dfbd68fa9c17ccd4012b0eb6dd46867c8c11114217bac000000000000000000000000000000000d6d99cb4b90d4085fe9cf943aa24c064049d196b98bb13f4f78e48ea3b8e454eb58b4bf9148e9d2d0d3ed146e544d431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d9351ac36ef705d824943a224e591665ad0c702a5a4f199e414b6e3b5c78e02afcaeb7e168a108e1e08a91e098bc0bf000000000000000000000000000000000ce8984f73998071f6e0e474c880ef422290a090d9718d1ea1ef26f199de2897d54eee65c68c1d07cf605f812b922f6f000000000000000000000000000000000ca78321f8d2e38a9699a653061f6e76a52b9f602780ece6ab9afc19f27cb24034c31fd4b9d4713a0bec252983d25a0200000000000000000000000000000000117c034af42983b7d24a4499e6b0d7b8ededdd1376a1abc951993bfa7f89d20a5157bb724f77489acbaadda17efcb5e51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c740a9380661edfd62409a5c036f734a878e5cc122dee24ed03f277de70d8821f480995003fb361b4ea12c3e2f0ba00000000000000000000000000000000000276cf71f3adef5fa430b8dd2852384036e0474090a586aae38a66d7bcff663dd58a8cf6d341d2d2879b3680c17029b000000000000000000000000000000000a01d0d8a25a66fc3dbe3c4a11aa4c6ccecf5d3b594382836a6c26006a67b3b7488597267a65e1836cf9a89284744d23000000000000000000000000000000000a5ac2b43f92b0640174de668a35dc2f86be6237f40677f47c82821cbf55bf2a9b50498d5c2e7b70d5f2a2db1f8fc6841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000aeeed166d7b11e0c8b1c65092b40d16f8790d7860a9eee4c89f5d0a35f3238b5ebe1d4842662e755b848df09f3bcf730000000000000000000000000000000018ceabbb63ada9a230659ee9728b5f14cf8e857e934181e67bf040c42daf7de4affe5e41743cad6b5d3046ea8f03d25200000000000000000000000000000000049c863eb295b87e6619475e5b4632fc08f275f8f32a31cd97125fb565b8755f316c20677e145e0eec38520e02bf4eb2000000000000000000000000000000001897ba567dfde72cdf30ec183e909e04d808c8c23ebed817dbb4807d589a5ecc4dfd5f2fab486fa1a7767fc62e1e790e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000076e4bd310f4dae8d66d4b53641269e5b379d34400ab954c0452fd194d4346005b1e0771c1c2471109f2eee6dc3c945000000000000000000000000000000000070cd80eb7d8c3ccec94c0f900a301dbf2d372dc8b602bdf3d4a0fa8618d701592852cd36a5dea20eeead5b4f712fee800000000000000000000000000000000156475dec4773a0418f669d40434b3f25eb9c2c96ffea2dd953bd8902a61f33d0d40a1a79b5de6c158b08e7461d027ea0000000000000000000000000000000007d998e9ffc4f02036d0ec51037063420fee16c579c30efd9161b38cac389148b50dca5d01d492b4dc4b9f6ae832d8ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c7a326c00f3dab7a7db7858fabfb10420d369a7d30dbd73e5d69547641c93eb7153cb223f0963c851c3fd55d3eaa45000000000000000000000000000000000054cf6b8cc80016886573e09fbfb3fee0354f2ccd38f1ccf0d212c5379cb04dc4b3878f883316dcbc6552c1fb63360260000000000000000000000000000000011e635736a42174dc7516e0d04027094ff9cc4b93f0d03f44cc00beaf1147056c79b5e543f7e657754a1d8e0ed15dce500000000000000000000000000000000005423a00b8d5be1ffbfbb43669be726c95963d7a8a08683dfca1ec163f99e19b4a38e688094b8855a93be22200c52181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bd22069cd233033f8c1d3b2916470cc28bfb205373d8edbd708750f1757dd2788f54c86ba377ee48053977c71d99f20000000000000000000000000000000000d6a2074905e73acdee2a68962bcc4486a5582f3876698be10c2e5ec0a5f5fd098843481183343ef7475881ea51373b0000000000000000000000000000000008e86f0e94a8492e689adb757ed465d7682f57a8d72461a5109ef11a1d4936f294c5e9b4f5e56607b6345361a4c4c9770000000000000000000000000000000013581fde5f973292678d876c339dd5cbb6ce57521c2c4b2711f464354fe805c30a62568c7e3bacbcbef47cc67ef150791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000114a17e8ad25e7406ee68a36be5102af45f26da1c124f14e4b371f43ebad8a9ff9edc7c4641c4281908751ed217684a90000000000000000000000000000000016501395e9c3adcdb4177be93dde731e2282c7ee8a2447878e671be11c91064e90fa445d548533a3dacde70b1004ddd00000000000000000000000000000000017a998652efe309ac621784d4a165ba2d0bcb907bb5074624f23f469f157b4918f004f4a34d246bb85cbc93401f2270c000000000000000000000000000000000b2e891ee80afbb636ea80a44e5e7a61bb5c7a295bf429e82b8aa98f7b994f9165effd787183db75ba950b0aa95639981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a659d7ea97bbb4443f9b7aedf2ea90628c280773585d76e9ccb934146a01fdaa7030ebe1169e66067dc0a55068bc7850000000000000000000000000000000004ab533e7a52e4f339cb17e52bec0fb7f329392805440333ef27bcc25b040ea37203d35fa7a1b43b8c056d3e3e913d740000000000000000000000000000000013e9e9d260b02bda35b626a96420a956e0757429396301cc1a40e3c50599f18aecce2076d50e9a3c6b75666a53d305fa00000000000000000000000000000000149e04d07d4775efd7f19b8a973c1c1956dc742bd65bce47f3bdb06e0b23ae7bb44e995b64139b72eb55f6ad2c4ee63e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000fe359021b94fc37795bda8c9f934ed1b6979833e2fc31fc3af7d21793d38a292f1fd1f476834e8263c698dae2eb4d530000000000000000000000000000000005a9caa42b02282f87174547ee49ef7207aac3df969049bf38e3f2d3de4ffefdc580003fc6a834ef4ac853212cfa458d00000000000000000000000000000000127c38a8128dc05401e44b950d1073fdfbcfd62c309554b60781ada7faed08548859364e13ae2611a8890c3fa4e4ff92000000000000000000000000000000000fd8dcc05bd1f9a9e0e6d886d7b7ea53df47ea44c61fc8a3f3b35095fe8d8e577966c672089f1faa46e0cf10017cca321824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c90a6913b11501de10f3a49033c880e7c06230a0ee9fd7eb604c86464790228f4bfb5f7804377d25868f75b0a9d733f0000000000000000000000000000000003a4cc92f612b995cc7a0b414d6990e2f8147594c61b8bee7b2dcb20e50f0f98d60bd6b39aa4e7c47d7f59d18ba0d26d0000000000000000000000000000000013d269b30c504d8caa273b0d9877e4efaa87b95a72527ae960655c5833e6279bac03a3114c8f5b67cb7d7672b59a7a840000000000000000000000000000000009b3e68d04cdfd410eaaa29bdc4280292031431444da767ae9d4167c494fc464184d06330140b3a4a1579e16973a65ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c34dd384673fa91d37b444bec4c7d92379ac92bd98f64f9f7ad96f74c91ef190c5a9ec18802909a6fb77fdab582fde3000000000000000000000000000000000d42489679b07b93e23abb4dbe19c4a6b776d8d86c85a0d16ce039cf585c82d010081a4586884019b878ab9cb4b88f15000000000000000000000000000000001876216f281db581a351686d1b7c0c564b40811ee7f968e9bb0ea393d4cb610ec2fa24ef27db7425ca54f8614b55597000000000000000000000000000000000166292886c3728021695e28a18c48323e8afbd6c50f97ec22e89c2285adee2416d057394ee353ddb8de05f76d4678cb41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011076613bffb6cf2b0bc8b22f9b47d379f6cf794877db267b0c489041172ba892ed2887fa4a935633720d15759c20dbd000000000000000000000000000000000d6608ffbdc80952c59255ab400b8d70b5e6ae325cb8c8d3a3130f219f24315de23d951923594bc8aabba23e81037da90000000000000000000000000000000010c8899827fd80778adce74f463a2f859315717492ed9fe9c28b5efbbc450e795d0ce4ee4255464d0575f7dfa66b23d5000000000000000000000000000000000b1132e2c43d4d7121b53765a83b86450b5141e32b1e0de8de4cd99772855f219e80f1960951798a45ec8e0a704b0d4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004a8a6e776a2d079adea228435bed8883731046c1a503768a4e258ec554d960af0f3888f339d8ddd3d9c369e618488d80000000000000000000000000000000004119697ff4b5e5e80d0aeac8907147125fa58fa03da8bf9dfa15bde6a7f6dcd6d22bdab8fbd835704243938cece243500000000000000000000000000000000181d77bf29b0ca13bb0c63465c22e5767171fc1304c2e398e42ce08d736a770a562bf5bbc1b4c1d8bf38a16481ccdb5f0000000000000000000000000000000016522df4083d9fd61cb55268a193e298d6d4ff85e142408a2458f3ccfcaf6629f4f760a9dfa8614335e5f6a54d13e9a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e40b90704e1d011480ba4f23b55b10990806f3893f16f19b5af1b9ff912751fdb697a580ca3636556e5ff8b287ad2d700000000000000000000000000000000008e4cecf52f2173f13af160245d085069d176ccd0fde746536d22a3b6be4ce4600cb96abbe99f514720adf1b7f27c57000000000000000000000000000000000112096263a0f96e7cff6f4e591f81f83179bf31dd2530597d7e2a5672b743bc77a3073b5cb7e2ebbdf4a1d8c822306b0000000000000000000000000000000008564ec67c9e03dd82197dd53f97227a395e994adcbe78b8cc1ae60db7b516c1f655eb578a61af4be250ac80bc6cda991824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012932453f18a7b9636ae94c301ff770ab9d4933ae76f685b1ba974fff080d0353fc7ba6f90baba1974d13c48dc1274e7000000000000000000000000000000000f1400c9fb9b5dd663c2ea0ceb9aebcdf8d278f9a6bfb0ca1bddb34c17bd48dbd9485507ab7216f6a8414dce275cc464000000000000000000000000000000000d4a1ac04a5e2e72ff0c02c4ed6e4f66bc3ae6a5575c3d5dcddb0c7bad3d98a6b6cbe65143f959c4c091b6d04da9431a0000000000000000000000000000000006bd749afd600587773530d214b79ae5229196ce71d86e052534f670bbed9ae3cfb5b61d181d70ef504c935d42d5af361824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c1c65af8305054ef717f1d97871a9fd706e827fcfcb238ac08be2fbc9fe1128e7460dab92bfd3a33a3978d7ac304b470000000000000000000000000000000001aea908dd74c101022c7e21c04af814bbe6f2114b3f790f761e359f1399677eda7ff1393b14a490ce91a0e6f4e8f35300000000000000000000000000000000163f1ff0b9163412551bc66618de7f8b2cfbea9bd3302ddb680566f93582b9514f17f8c38b75d53c5955b9229d0592be00000000000000000000000000000000101518c20316176ad6fd6b939d9b316b15c8c56cb7fbf833c5c1c4c4ba15ce2e4329f64e6c15b05ce1ca29889b5432cb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001553d033b622a1f43074842b5a406beb7e19f4ed5ce7d8091b0e877ff89cf8cd8e021e82c197ede024f776c684dae62d0000000000000000000000000000000005f0ef9eebef4777792fc434b7376fdbfdce36db09093380b9f4c3ba674fcd85eb952ec7d5485178593a4104596594490000000000000000000000000000000013fb72b0e82b1e14ae41893b8c8394ddaf25e358943eaccb3ed912fd19e6f550abd6dce2541bb54b35b61c3a0efa4f9d0000000000000000000000000000000016035bc4c10f7212d1a4659d1d3f8e2696abf8f03def6c5207b8a0fb8dc82c9e543e65bd5692d66a4ff24d2544f32beb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e8db00c8e27f6c9538dca2fb1ed120aed85d6c70f1534992fd69b19ec27a7f5f6574fbec880aea2c6076e2bf01a8bbd0000000000000000000000000000000008f1d3c1d87ca51f68b1101a155c1613bd60ec1aa2325f3f48bb39dd841eaccebed3ba053b389c027d8582a5801bdfde00000000000000000000000000000000169eec186bd18e5019125e8934d2621349de731a8e80c9224e1404f37daa81dc4097e10de3318f13cd6f8fa32aa4d2f4000000000000000000000000000000000d180b02b0fa06eae14ae2e629d57983a6be10c2b648773a1caab83c927d5dab637a8d0f7cf1ffd2d5a6baba3a131abc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003bf543c98b68020e26c5e8d03e81f33a6bdc8fca5b312383f4b055dd198066ae3eb15168b52bf3e4add4e6b0148253200000000000000000000000000000000112a6629a7814c8de9a89685c083f75306ea52ee7f00102f1fcf01065b21ad7c81918ba037af05703cc1bf47ba9c44550000000000000000000000000000000005ed770e9bbfbb323aab5ed5ac9b8d6cc38acbd613f2f2a7f516fe06136fb8cc6a3300a4f7636316886478c457567b8600000000000000000000000000000000090fc0325e97bf20ab51b6e45e77a99de929b7404920c337d811d04db43f829c0eeda9bdc1950fb2f5f8948fbe18b9cf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003596c9296a8f7f6744836a05f7760a0ab6b4318874563e49e688d9c8219af0fb700657ad718123f697be3185ce2e6df0000000000000000000000000000000001031fbc80cea2eb8f5a1426f78851469f56630563c92c1386a198a4efae3f20fddf5724bf2ca43c505b885ff5ac4cf8000000000000000000000000000000000b2ecde10665dc9fa228acfb349c5844e937de601af24270ec9a03bba40fbb46d5369ee84d8b3d19471791f280fd614b00000000000000000000000000000000118c44871160322d1145312ca065430894a08da9ca527b2a874915fc7930f7be78060955cef47c1a56a21953d5526a331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019b3af8dde9b5473c2de6c7ff8630c3a8dc102dd87ad1bfd75181df4f7a8081ec0259dd89a1ba2a4a757a4fd47b243130000000000000000000000000000000015096b7569d790136f95a58d85cca1b1f7cbc65587d45561abe417b3494e4477b773c0d98b36a4274c36c0b750d0b3fd000000000000000000000000000000000b29f95b84a4d18b31973a3b69fd956c873ebff362c6e0253149f98c4f4fdee9b42837a30830ebbebfb189be9eff6492000000000000000000000000000000000aae3ad137e91fecd02105995c393f88c95efc71f860120839a8eff3f47bbe2ff6a4a9f79feba374462c015bcf77ab0f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004263c8d9ea0a330300cb4830ae76b8b7de2700bb5bde6b14491e9c47701960ff5d6c47064a09abc3309da278aa3183d000000000000000000000000000000000f1bf5c6bffe11a5fce0e59977edfa1c3dde1e0244a15e61b60b5afef379713cdc8dcd1118424703937f2dea490a65f2000000000000000000000000000000000cdd880536481144a2b32128659cedac2427cde5afea533a7f4307b1ce7ccb51831a8e8dbf24388de4896a9b0fad21ab0000000000000000000000000000000008c536eb64d2ab3a572c485e9592abcbea7e8d66f0da46cb216ed56f57711ab68c0cedbb24ff06315223ce95c88798b61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001761a37754e58701c38caee53752502dfd1d21ae9593ddb8055ff2232573c3a8cec59d17a9f45a9c28a2437d50cfebe3000000000000000000000000000000000c1a8552a1f059672a1cf33a91815a84725db6008950d60de9c8348b3c40b6fefdcdb96a8b05b0e51df20ec59d95a31f0000000000000000000000000000000014398955c9c4c227ac2914eb88810dffa591357fcced5416daa7ae698712bb6d1fda60f93127874dfe4fc3ffdd703bb70000000000000000000000000000000007ed13ec9d402bf10277f2157fd0322f8e74844b9542c251a81d2f5e2b29d4ea00960707d3334923cb2fc375c4813a8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fc934973a609315413fdd01e5ba712bb388ad1b90653a77eee5785a873805d6ac17e787ee5c3d518ca6546bd4c1bd50000000000000000000000000000000003de2cce604421255271c12173256278c4205902ebc54053f6126f5b7db74a0280a1b937dc345689c40cd3e489e417dc0000000000000000000000000000000013b00489a1be8473d9f5de62a9a04678f21a985f6eb38474997b4cdfe022aea226679457c2b20660f63a297a91d9eb4000000000000000000000000000000000113336de707f7cbfca8c1584eefd11f589b450cb9ffc6a6170952a8a7c83c660105c0b754f6812bd54b25728000093ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000043b6637277d95a91b09d7caaf198a1d12f174879eb949868a117650890be31976dabe4d94172a912df4e1f3bea5b2d0000000000000000000000000000000000b944ed882ded4afb80e38d4bc9198fd514db26a7a2961169b7345c355487ee6f43b834881fb76b1a15d5f110e45ff76000000000000000000000000000000001076a938b6e182483e262ea6460a6176580a7c85415e53eb9e94f8daef239728776dfbe4c9c8a95464c4eb08e0fa2013000000000000000000000000000000000471ed648662035cbcc685da843f14cbb5d4ec416265fbf289b694d11f8d265c49369e4179e4eaa85a235698ccccae2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094741febbf573f8c1abf410fa21015fb14ce5748c0cc9dee332b2cea95eb2c9dd815e24d7cacfa24bd1b81d72a9651e00000000000000000000000000000000066a66b8aa45a66aef71835aa6427ddf37b16eb65887a06864380d41e264df5c2518c11ae38c530b54184d223aa10e7a000000000000000000000000000000000a30edf74548a4a921e2e62c4bdde320f8cc795b4d749dccd832d2050deaeaf452a2b989a15faf212072b76a0bf786e1000000000000000000000000000000000c644125e1541c3eebc18df5b8d1139eb385d8945c6131329ed6167a200871f88c2dc15c7c5e21fba2f99f15d2e84e431824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a58b10792e64bb58871cc738d0adf631a95bb6f006c1eeeb4b7905ed41bbda196ab24662b227e092c9988c5666bb9c0000000000000000000000000000000011fb6a56ba06a9c239b47101e6fa2d85360a55ceb0f6878d24afc2d45e63b367c176075f8a360e87f2b8a19f9d314d0d00000000000000000000000000000000036fba5dc42e68d18e9da3bb57e32eea835608e01d6e2c10becb328cc8423ee4126a5ec7bd1922e3e7e3dd5b70cec6d40000000000000000000000000000000000750f36d2ed2bfad5a9c99479b8e7d8d3113beb70f43b4c00bfe3b545643467a9770e461ab0f370f67512b877b73ef11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000141fd961e4eaec72e6ffc8a6ec1c201533cbed22c71131e05a7af4eb862d749e33ee5b577f51e40ed066d8768b188fd9000000000000000000000000000000000ed253284e17c2860e309b17ac9297b33957d90b148aa181e9b56900ff5be90377f626cc94c85fb507b2ee30bd5210680000000000000000000000000000000008f09499000178f63a9897b78b50002d2977c1fec05aa63c8a38341bef8969eb01652f69f629c147d37a0c8984c69c17000000000000000000000000000000000527ff185fb07c3f50f8b56b5367e57300944830e4bde821e2a21acc81d44b39afd50d7dceab458e1b5a1930782c16841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015da155cd703fb6ba2237128e12445d218e3b8889a32ed0f806ea4dec2f9b5a91df6b87f6d798b6dad8ed1831e0436cf000000000000000000000000000000000e1cfbf18424dafcdddbd8d619fe04bf2a6970746413b443dbb7eae79275e06ae741fc8a5784931a63a15c2dcae43e9b0000000000000000000000000000000015f3beb0fd136cbb327d52efcd57aff1649a69655984b9228f46496dd72b0dc904a2d1622b67c8f646cf35f532e3c4700000000000000000000000000000000002831375e89e596f7fdf494b91af829bc2c5ff26a31685ca1c113886853aa4995d51da8899be70cd71ed5795c519c06e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000025698a7d7adb1b7e214c9021ba8f1c988aac626bd62c8fafc55a446fbe24f22b3c3a346324c153e0768aee21fbd80b20000000000000000000000000000000001591c862a715f208f8759ca439b6ee477457b8dd679b6fa4fa4388c7c83d1ad4329434616ca97d330cea79bd5392f05000000000000000000000000000000000d783ef2c0e9c8a6c0220d2897d207192c46fa13a4f0a965eb1c2e6492ac264e036d975e7993f7e5d24666418c7d8f780000000000000000000000000000000011114f88ea27f2235d6f7025608c0fd2cd6e06284a5c91be92ae123391de35e28d1778ae2cc6a5a399ce9c5d5e5752891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006556405ad63aa3edf0520995023df56aa4ca5f89cb9f88a80df053d9fdcee2a7007d908b0fa54a838f9c1d95419c65a00000000000000000000000000000000106b8ada7fe9f96729ec1b5e597c964d4e410861ae1decd34121b7258b4e4b6eecf7cd57ef3c4256f7c1e5630d73e4e20000000000000000000000000000000003c7e760026812060587bde37f0ee36b1f98cb0dc673931da468b3f5490f0678a8aa3fb2daeac581e6ea4d12a750606400000000000000000000000000000000171666266002f3677e7210996c363f0173d62b633784a8745276a25f239888c89793c0678276b4ce863a3d4d3b9411811824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000091d5864bd824bb9d2557b68f9de3f031f719313fd8b9e53961e410f79e37290eac707fd7a5ee28ccdc4b83359e65c56000000000000000000000000000000000db6f8ed9bfe832899f6bf14b2ac4bca5ebbdc80218403312e72a4bc27c219b0021d831ce57bd2af58915950358fe2c70000000000000000000000000000000010bd2eb5b65cdb72900edeb058e5da09d9071130b68e442d523acdac27220fd5da011b9b7a572516d74d3fd43fdfc733000000000000000000000000000000001624fe0155ec985ea2e3def4263b9b97928620b63793e22b7498bf83218ecc3c6cf9803c447ffb8723c2ca0fbe9f53631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c683dec0c017398b8a33f67077ed8ba39099874a75cfef7b35171c329e4bacb0ea931264ef04f1b1b77e3a93e295ccc0000000000000000000000000000000010ef88938593a56d846065eedbf72185e67a8cde91f78c49ca1cc0dc8b036967442b6b56a22449911c7c4eedf52bbac00000000000000000000000000000000003cf7d6d1515f83c35d9fe1c75340bd05b5284c3f5dcd08de4a0df6480734f6b91d8859ebf506f4b390d5bc937d0062a000000000000000000000000000000000c17332e7f0b062f1b859ebd46a99b7164a6ee9eb2a0ac4610cd79772a0b7f50f4607c267a028ffd642016eec0ede8c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d8cd5a74b0bf0ddeb256cf97f4505247e5b53199dc04be1f3020d0864beaf208c0a241388da9f15997a662dd4f60733000000000000000000000000000000001421d35626d2367b20a0c6553bb00aa59b8df8d6f41ef3c02d4310927fc9ebc37a32392cfd4b858f2d045fa5166915b70000000000000000000000000000000005fcf311b4aed4346027ecb663756651b322e2fbc08aacbedd19cd4d026cf0c1b9a186254df6d0474ec644ed524732ae000000000000000000000000000000000aa7377e3500a797bf5c58179e2cf31398a07dabea5ee995962fb7ee437e1d8c3240dca891446fe6e7ec36f1da957c821824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c466ee9ca224efbeb025f1d69e9b2ce25c2ba096801ef3f51da07d982ead125702f0e11474fdb23c3be32ffd165a6320000000000000000000000000000000019ca6989fca100a5ab0cbcdbec95724f2ac002811cd3993ddb9dfba3cc1cad206e71b612cb0ce3be4a85a42633321322000000000000000000000000000000000ed5fb711a2acd6456ec2da9a4dd2f1542a8c0796ac0fce2e24380cac6cd8573dd79586167a55fb5bc0a2585cc1ea0a800000000000000000000000000000000158c20e4dc1eab22bf97e75d9af4a00bf759739b84824282a2fc4f5ef723510e0ae305e4783c2c6b3f1a658824c19dbf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000015fac153f91d15a5c8158aada69d56fe4fcda32fed73da6141c6eb54feacc96f4ac79deb711f4bb711eaecee2f70b1b0000000000000000000000000000000015c7c796d34ccfda01c014742d0372ab5d172e345c64fc0b9c5eefd3092797cd71596a91a10269698ccc5617dd64a66d000000000000000000000000000000001482f722d2c1cae7d7bf30419b939190d198f6a74e5e29de8236c5f116eeafa013646e328e13a22f98425cb5346cefb10000000000000000000000000000000019747f33ed0ef91f0090353f5da1e607f462391f91f179b89f0e4072cc9151099a78654787b426d3573c99b18a6226be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004dc2cdcdee7ce704348b19f03d9719d25b01f7ae2ef06bdf5019f095022d724f6740d15863cc76f39fb3236005ec041000000000000000000000000000000000e5c695835e591cf4175252b87979ce87dbbdd71bf6f43104d40ce2eebae184e01d0f20011d674f9a1d5593007670f21000000000000000000000000000000000495db7a051e7a410f8f2422820caeb7ba0305321d1d3e4bcb0f28c9fade60c68e325d8ac8277f52d4eeba6f4bdbc459000000000000000000000000000000000135a21462d7a49a7c9cf7912b683b83ff99c9fb8204a88964deeb43174f7caccbd6adfe3986f0b1912ebfdf852d4e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000bf1d665765d7b4a19ee70fffc5521554b428b1b3e76d3b64a4b8072d7800f7ce2f5ae589eb1fa77da63f3f8957c6092000000000000000000000000000000000cd4ae3ca4ecbb7451f942879504ce9b2197fe86c19d75e201f16080ae0e7fea09c3397eabb1256a095722ca94872b17000000000000000000000000000000001506138fb2e2c0c3b37eee21759c5e31f2a2ddcbf89a6389b09c14d0efbecf34b0ef1becbfcbb55ef5f987e8545f80e700000000000000000000000000000000087c6167568d2fd49b8901e0d8a487d776666199ce37a5a022076bf6c45f4ad7980d7144de3c6fdb8079b43d9d530e601824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000094a7138c5791a68a90c2d59366fa12794838eb83f82cf7acb0a7d2657cd55aa83e81b8342426d1e5f180b4176de79ce0000000000000000000000000000000003845ed19a6fe121f4b4c09d50232dad512a51dd0a496e7a2dd37d1c7a5b779c6539e5234fc6cc30bbe3a644127bdc4b00000000000000000000000000000000176b8926a5732adfa97cb3fdb7ab5d70264cbfefc79c1222752e847e5545d278ac466f1bfebf317abc6dce42bd616beb00000000000000000000000000000000048e64336bfbc1c0b004a7bb00f65180f7c7f213b565d1133b0b31e79262eef477cc97362a9b8046d05c7e81037a688c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010797e29a4900b5fe01f75ffe3f640e6484103c80e0b0f3aeaf1c4f79dbf86b154ca8f6d2331c13d8af2c13ca82d5792000000000000000000000000000000000699bee300f14f83c19ee47ea25b4c90cb1191a00120f476e582f3348dfbc78ed50625533117989f15b2f04d6ae9bcae0000000000000000000000000000000017291005915567d8c3d7389bf3986f0bb2428e3a03b6ad0c2b0a9335c3036a5023ad11fa1188078683f1c9ee93746020000000000000000000000000000000000663496a95a79c05fd18ac27a3138a3287f83213e1b76a26bfb194b491a172d7b87df955ccf14eb45a8e57221cf8ac4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003cfc9bfd507e5cc70ba4fa6c9f68eda8ee3f7c0815c8cfff63fb7809087f112293e9b31f8327eff59016f718f68c4e00000000000000000000000000000000002d039735aa9e34261ce3ab102bebca08d157e6ee56126bb8fd1f62eabba1b6364bed9b0515857f49c769715115561390000000000000000000000000000000004946c5d0508945d3a31c4c67d2e1f3b963a05b468dadca126c7ed38255e1d4c69a0da8aaa40c0368581df4ec91316430000000000000000000000000000000017fcd079e55e6f9dbe0890e81f111b11a9e86693b2864a549b884e8d8c10803888943ae1efeb01347dcb392b04767c091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000133f9519d4cfb9e6db6dd9b22a8dd8a566f49c1cc1d0278eec4abd178b44013145363dda08b71814520846feae4ee5b200000000000000000000000000000000014234e365fcfa6c4e8cabd3f4e54d8885b1558111cae3d360dda8f7c039a9300667b7c00443d7736b59c6b324c51c4c000000000000000000000000000000000250ae48806537ad044cbd829105d01bd0687c9991a4d585c2e25f1bda7e48eb05b6bb994f870905265634e2f798464e00000000000000000000000000000000070b9ec7eb94797cb4a02e9969d8c1ed222c0febb84ebfb8f164054b96483423fe828e21ebd59e2d4052f26c286bc0e61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a8167c191c06a896706beacfa8f71b971f1f9f64d8e8555c720f5e8ea1460715e3c441372e60b93253a015aa7e5cae00000000000000000000000000000000056563cdd51061f617754b658fe2bb36e99453ac79b6b5a3ba6638a7458d721fc146316e8112ab5bd3f54b8281bfb5d1000000000000000000000000000000000b36a794b72050b997d60205fa7e0b1fb5f86278e4217263a82b5ed774f88ae6994c9cd0673c2fc10d7ad0481a1e99a4000000000000000000000000000000000961ce2970a0efff0f0b8689d0db831192526ab7b43263966f17d9b9e20f8e24af56939db3f5081255923f73621353691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000122fad5a5f9b8e9e4121a83f5b5b6ab0ab1e7126a4e997be86e9214e786b22ba19a20bc3e54241df3f1a5a0cdc1af2f0000000000000000000000000000000000a6dea66e830b60826397a49b2a96b98adcaeffbf9285da9c813d46880cbd171d8a6799261b970d6a5480565b46f133d0000000000000000000000000000000012e15feb89478bd82e07911636e04a7cbc5b7cba58cfd55ab268274ddcd9d34151ae58962c30e93741d9a99d3bb28fb2000000000000000000000000000000000241e74ac6acbefbb94f23c2a488e59080b0003d9db02646199776a12d621b8678d725a094089134f20b0cca77818af81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014e6d74a7a1616c42c6124c86eb2989c0269f440da7bec470c35e6669d422ae4eb6a7d0b2f1d8cc1632f3eee32498bad000000000000000000000000000000000dfe924c6b386852a8f80ec12db58740389d3ce23b269909485d588324e7d47cbefe051fe4c0f8a225d11b59ff148efe0000000000000000000000000000000007ac6ee8a33a17339860d3f07a63c3cddb72a29d983367c8a77a2011f62379d1de0fa0ed8c5771eb0215f629e7cea952000000000000000000000000000000000dd18723b7069beff825684a49023174865c36082a1ca749c8ba39341d3cf312a28ee0ee48368f5e96516345ec6132e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000388eb87d87878e4b9635865d05492a10c9cf6a23abb605c0aec50e0aeac819272c21277525d8cb8a27f5ff378ad38f00000000000000000000000000000000016cd0031b0c47a0e73d43e0cdb8c25c9225e6c67cad318b55136527285c00884827eab6d7b6753adf6ba61e00effc894000000000000000000000000000000000d85f9850151d07ba16feceb7f7a64585cc22202ae58d5d6637017e61804bf820f9e928b25a0bc1a4b202ddd6545a9dc0000000000000000000000000000000014f7ab9bd0eb8e7da04a8da89c731be6ce0882adcb2588a5880827d6b616e736c798c988c0f084d3ec6e6ffa4cdd22731824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000011d33b656778ca2f10ab3770159671f297046dd1c75f75b3c456b464060d8dc61701a3e0198bd03d646654d5f11fcec10000000000000000000000000000000015eb4d601f16909ec3c3238a6ed4642f006fb61b84327bb16a51c2fbe10bd98ba5ed9e2b136c4d65b8909b10bd3404f0000000000000000000000000000000000d55bcfec98de5904faac277e189506e9dd4d569ee96df512d13f58cc2da9a08effe47be63507314b8d2e392cb7bf079000000000000000000000000000000001139582b42f59692e72dfac3c4fdfa34e95425f11d32609b6e3761922156b8bc493d00cd8c1078cbf127fc3d9463d4561824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001265fb7bc6ae46529c3fc46add2a7c68d997b1227fd4106281174ed8e65622bfdd1d81ffd48f9f7112452748eaca37df000000000000000000000000000000000d1671659a49c4f4de7f5453c07577411d307c88fa64c5c5d9c81cca4c7c9f9c39752f39fa472607ce507b2c05c66a470000000000000000000000000000000017b87dda4b117d3609088eafa8172a3ff91ba3445a6df6115c0756adc27965020e0a605e3acba2fa2ac9dcb922a01745000000000000000000000000000000001044d4ad9f0d70ad50511356a0a17429320b3ed07c963766db84374a50c21f0b4607bf4a4870a0ecb100343308c817ca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ba377a51a85e0e666bffa9a43aacabf498505a460b287523ee29444dbb8d88b4f580cb685e7b6aec86dad08963168f6000000000000000000000000000000000635f9c31e4bae6b2f5407fb5d8ff45d395a051770d47f66f7ffd345b6899f2141557731852e43d505d2c1ccd9b6b776000000000000000000000000000000000263646a22761d58ca1fe0a85a021dc29c648826894e924c312ba92da45ee288304c353a2760b779dacac49e1cfed4380000000000000000000000000000000000bd5d3705bd40e93431ad76e63e4a2215d91e0c456cb8bfec5deac70a8153c01ff7e4ec88e0ddd28df7dc2b4f7f37ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001558820efcd210c4b87210500dbf928bd247ce9f402f3ccde9cbb561e7c8850f279c4c05fef06cd24ccd6f658715798200000000000000000000000000000000189eb6e2ddc6d8bad1615038a32682c9d4f0e46c1fd7e736ce83da55f1d7057f637f2dc94a5091e4416a642b5831cc9800000000000000000000000000000000173fa28171ce4c4327be6d359a83ed75e6903f3af8e73c89845c5848af9c0b0df4e7b0ce5413112c26f10654bfaeb42f000000000000000000000000000000001722a3d3a3b6e639d70850e0e1df37e4984f6309bde6097e80f3de752e98139415c54b8682f03df56cf043f27d70fd311824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000835e86b09c7953c0631e6521d4eb3392f7044944534a7b2022ddb53ab9c7f5ed91ba311196348a3385b5cf503e44bfd00000000000000000000000000000000015c95f00c6908e2bba970b2e08f95b2a9bda9b738cc045f6cfa91c259ddc29d1dcfb4815080cb87595ff77cc27616a300000000000000000000000000000000130dcc0dfffca7fe40aa6a29dd73ac2a7762b5a351e52bcdf11bab5d84538b307bc7f2ddb6d09150d59ef88db8a06a8f0000000000000000000000000000000009d40bfde86b0f658e55ae724660b55076ffa73ce8c8ba19f41abb0c308cc07996552ed61318b737100bab5038fb5a711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c383ba6282e9cd17b676f2ed0e4cee0600b1ff848c156e12108d85de8187e749833bd52d79d247562b1d2647242ca9000000000000000000000000000000000d425a39acead53d8587eec2ffb1dc1e59e335a0449dde28f2a000e31a5ffe4b106512274bbc6a254813481e8b3199770000000000000000000000000000000008e9fcde4c67faa5d243f234f8bae794524fb03d5ccf660798ba764e9754d89f77698a51cc195c82725ac4b712f5a3940000000000000000000000000000000008938bb9d340ca0362f9659eb009286a82da813d5f303dfb3c98caaf6ecb56dd12da34a52b055ad0192d7411cfd0766a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e364372aaabcbbdd1db491bc5498563d2c618a6dd4b945e01269c0d5ac7d9f47cc9fab05dd89e964a32f313a959ab16000000000000000000000000000000000f53d623291a24a7b16b0fe662252823a3cd13f51d7e17737ff6051f126545fa8a9b15f259b171bc80a4c78d6d85f8a3000000000000000000000000000000000a835cd9b48c61a526b54e346a5ac9f18be8aa7b6102ec65b406802ff3e3aa311f18fab0eb94632e67e4d12baa58f29b00000000000000000000000000000000159c9ed69d46f49d0f6bd4af7e04c97fde0396b8bb01bcc2b675c646a7cde81bc5ba7c4e9f9b8aed2e2e03df1e32754a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000834bd07f5ca9adfb4e8a6940c655f53b1754c6c41cf33f13568d8df974a9ed496d2464819d073a5a8d1aea2034e46e000000000000000000000000000000001712e1c7fbcb92df74ffee1fc0e82ffed9d3a27f6c39d1f46415ae06af12e7e6dd1ead5f709615eb064d2ec4634ad922000000000000000000000000000000000f9d5ea43d714f231443a84e751dee453c0fe8b1def06b0657dd2b17acd8c6391a47437600557b790ab01dff96a839d7000000000000000000000000000000000353fa9e8c50f6277cb1b355db14bf424b0b88e90eb99edcde637228a6c98d6454b1efebddeb77b8647f87aebcb39a901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016151999451c18622a388a840ebc1b35e0c038f80d5119ecda1ce780983c999b14a115d101381bbc703171b3a473fb900000000000000000000000000000000014afde5a763a70668dfe631a68cb001369fdcfa1d484d2dab37404c9e587040da68b304e679fdbdb8a11f8be6215e5f80000000000000000000000000000000014acf3cf03328dcb4bc73bb40ca05f590bd1deab34d7173535bad07c501747d12a05f8063b1a38fa821d323011f3c78200000000000000000000000000000000087354b0e64839bf7602c2cc6505ef530b1acf7fca88b05e03486f9abc548f64dc79b21df28b3f6c6b308fc0c2adc8661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005d2b23b040e35db312cb41d76ef57838956d32f459ce074559df425b7ae462f6bcbeda0b715e6ba0bc69283560f6944000000000000000000000000000000000736eed339e66933e7e083cdd4e48b3b931ef4d8afab0d601605536871435442ead4e824ea37a0f2113e50f98c3052a000000000000000000000000000000000130b83a227feb9765ec77ea6ae34d787017eb4f60849f60a78801d3d80b5e3f363e194094f748644b18d2ba12b27c68b0000000000000000000000000000000009c33360e70b2fc08a8ee4d5c5d56ce1078cd5549e90d7246e9462934648bd8b062db2c0be8e8cdab4d6db776b47961a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000024b13eea5366357fa852bda231dd2d17c405fb405e903b3cd0d5538a6b829ac428f565193ebc77e1376f70ff03fc3df00000000000000000000000000000000147d549543c86fe83a7395b6fe5fb9b1c28561eb51f5b6212348183ea1743d6680d048cc881a0e76d605ba372a3e172e000000000000000000000000000000000434cf4cd629703fcd75c5269fd17d92d959acf10f20383849eef29da56947f2f2d6682d4283bcc8dd3412485ac60e320000000000000000000000000000000000683431fa5f360ae2a367cf8d9f39eb261a1e7c4617a4a43cae1cf4b3c1310d91450b26fdf4c5d6261cabdacbedcfef1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010eeb920fe41ce4952c50bc400db650fcca7dcb8bb29ea14f1607b2c1fc604f6fa4d3efeb8d6cbc79231e0216a9d89620000000000000000000000000000000019b7dd44978f46bbf2a2380596fe3551d39f426131421d5f470a5b8ddfacaacc90fd824cc8bc2f8759ef6b6d783dc22100000000000000000000000000000000088de28f137d782a6647bc917e7b1b3e4f17d4ad7098f4beda3373814b0c3bcde6f588fec3bfd5276ccf5ba18bf10e9b0000000000000000000000000000000009829f39d63616a3c3875385b12b9f029cc7de41ded5d26cf7d5432be6c08c9b09f9c4f8464d35c2e9c4252ec0809ce61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d2e1f4a6eecdec53b63317b171dc485192988107c7e2aa9d3ef84f5ca7c3a4006646e9fca3b8b9ad451779a61031cb00000000000000000000000000000000164d567c6d6b8e3f8df6c252c918c124bb0bf36dc9c98fc1298128a909cb5de1827e5cd3dd62ebc42a9968f87bc8c6bc000000000000000000000000000000000c0dc7f3d9b7ae6724cd374b6716da9dc041ddc0b78324076f40e0f9c86a9a02b001c825c09da258b0a8175313b3a5b40000000000000000000000000000000012bced71cb57dd2f70907925a3ad6835900e0acb8b370b7297121641d5abeef473d6e0805a024b99c4e15bb321c0e5d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001539a337111d7f25dc8460aa6f2cb3b1f0b80433cd437bad0addcfc6f376be4736642dfbb8dd4411ffb80e30c4dbd43b000000000000000000000000000000000eaeec4f453cc0e3e814385c9d84fc41e5ab7567b89e9162df0078804ac570432cd8d7e00dbcf45e3f6f40cf7c8e556500000000000000000000000000000000036c6a34c42943a156831c350a8e289f319ca60fdb4208a048197a16d6da6a875356c8b5ac079e49ed0eb44692c2c6b30000000000000000000000000000000006ad0289b4a108d41dd864ee375ac17e513660e55ba0f10c3ee42ca311a9c7dfbbf0b14fbd771d454c56b7baba1bef8d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000017ba8f35367eacdd681b5d24ba9cc39b8f2635975d87fb9899216c51c6445cd6f3d7e7109ea2fac0d0cd4c0767e2d30400000000000000000000000000000000084d88829dace9719d2667b84bd919ae2c5b14f845c38bed640e2fc91b114a568d67fee11e66649fd48760cd60dec3ea000000000000000000000000000000000c1ef628647e9c967eb409a965eed091f47dec4d6810d4fe4a15e3292e1098a8f621afa05e9d0e0a7b77e41944b8ab6b0000000000000000000000000000000006849a02accf1601750c21e11cbd6cfc7022134f19771efe49058000c6994406ac3325054b314b9d9897390c63fda2e11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f8ce4c439446732e3f13c81658f0dd0506ef6ab6232a5d539dacb75d6b01990efa681024af1bb50f91e2f2b57644488000000000000000000000000000000001401520246d9116f2c53f69258a3f6d3bb10b660e3325950cc451f6c125fc375378ff8a359ead4097829d4316f4b46d4000000000000000000000000000000000c4131f86ab7d4864d555b95af31163b5b5f48f03b4358b5ef37b24a957eec32d751a490e28d5679e62f6b4ffc9f52a1000000000000000000000000000000000abec50a41637d879f77091d8db1fa8e1f1ef03cd964c834277699b2c32041ddbd21343bf0c86b5720a2800ca6ee7d4a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016eadbb358edf3863827f7cdaa5c532819a8ad21066335a6f4fffb27588c483cf18ae754a72cb660b6189beffecacee30000000000000000000000000000000007348ac60a9b2d6b288f412134fab783aa15fefc0daa5702621852cfd15a70d9b2d3dec7c9d9598cf871dea1934750a200000000000000000000000000000000100483e1710958f1841f9f4b588850db0ed179fe442579bd20b36bd6de7e2a93818a77e0343f54da6159c55c3aee1ebd0000000000000000000000000000000016a4db9826d9acb35df1f9f59ae04434700acbc62f91a36486ece774d730b8ec0a8d8cc92cae2d050e8cdf68b576714b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000414ec2911d0f8af340d440f3084b90f03a7fa2ee8af36a3759bcdfe47dde74a6868c6141400200b4ca2d42e62588421000000000000000000000000000000000bd6d392c3871d0b23e69081cf347dba0ebe1403a95d221bfac57be00b0ea227b7c1e981d21b63cb67c756229f75d1190000000000000000000000000000000001a2cd89a5f3faee0b57464ef350d5de48e47a938c40ae0aa721dc503d064b4b7f7cd883457f7b86a34820137f1e4546000000000000000000000000000000000df9624b6676b1f5e869c38499816c92143f81dbb01194770e33b8a5ff027b20a33825df3465c575ed14108ca37a360c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001851a9ce9ccda98a388e8b0b057998be89a046b2f6d55a81fe0d47923eeffb249837f01d57679a70d55aa7a5920023b50000000000000000000000000000000014c6bae92d2d6866cd56c3402869acb0e15f888aa5fa76339c8587c136ee8ff7e0eeb5d02d8f97b7fee7fcce496e0fdd0000000000000000000000000000000000293a1d2dd11527df30161cbe1676bb714c31bef22c95282d0d3c29af4450fa581f6af53a2e2c586b964b103f344c9300000000000000000000000000000000179c341177a4fe720d610355c948b7989ef2f93d7214e25fecd270a79d46a352f783af34b20bf950ded31f06765d709a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8e5de0f35982c372c5656645f0def721b5e0ca79a66a6ed57624ecf42103184f6a746dd39c77d94b14abf6b3d8bf1200000000000000000000000000000000019cf04a281f19b9363d0120036f63957c4149595a21a16285dfc2e88938b41e945f2b565b0b249a250aef65cf28e99c00000000000000000000000000000000142bf0169d953d526735d32b4dcc1af7922b94bd388812a539a05c9621c80262e977a46b209110fc963d96d8be97a4460000000000000000000000000000000013b5624a26c5d7b67e79beaef451828c6dde67d11bec99dccbb04b2aee6db1a570a4b4495f344cb64f6bfe5394f5917a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001221dfd9cd5dc7d0b2e1fa532b77447cc405aef2d9a2332f2c515987247adf37f4d6b5db314114b65129c174231ca5e30000000000000000000000000000000011e7009f332391898993d631bbd5a0de29a4226a9555c80fd310c57a965e950578a3d5b7d79d78e40f7046aba94e310e0000000000000000000000000000000009411ab0fc172bc18bb0e6fc2328d351563934cf363878e3e67c9de7f580559109ed312bab68d7457ddb93957d9a10dc000000000000000000000000000000000009eed5fd804bef986f8c15589b0ac94634c7f5fb82641970a9582c7e30fc500726b0fc4a34bc46c2305660a8d5dd511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ed230d374796c86a5ac71fdb6317de85e35da963d242562c5e812b1eed0abc0819049c296bc1b38317e486c8aa7390000000000000000000000000000000013e22f39a8c2bbcf398043d54b1ea8f1106d137d179db281548ad1e0975f87d9c1d4b5b7ce1bc015d1f3c9f93b8b8747000000000000000000000000000000001498cccf4c6d8fc2007c18a7f63798b981fd986452af21f96c67bc453c459d36b49d554666285d1c1aee4bc8f73dfc370000000000000000000000000000000017b6fb9e4bbcdeedf579fe687a40f60ddb4cfe881509684eabf28ae933478f82af6109f2a4714a947eaec73b368645fe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000096461ba3aa19e21b5d2f6d9ee6bd3b2fb5c46917f47e896c751d2bdca571aa16f1ff9f03256c7e268fd73c79d2dfde30000000000000000000000000000000017e79facfef179527ed19f8fd21927a5db2b10fc3c34ad847420d59df6e4999ab24a2ccfe776707ea8a6ba38c807a6da00000000000000000000000000000000159f535a1b2a97410d361c5c3935bd85884fd9bee4355833e1777d24005480eb6563b4479aeb20f42cc461dbbd32a9d0000000000000000000000000000000000202ad2bad33895f5a046b4c13231cdbf7d26fdcf3cd754a512e7a0cf8209852e07443f62f6d70a01815d0f5026221a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090ca17c3a27aea9dd866f3a3f1c49eb98073b42933e2292ce6b74e165d61f71ba2b16a31985987eabd473856b7c1e550000000000000000000000000000000003cc688b3750779e99d9a7acb2692c0b330e6d1d43081dee9060cc85e9c1b1a70fd940d2e236987866f728262b4436b20000000000000000000000000000000002e140e1972fec8b1c975b2ef7dbfc19774630fb64a6b0304f181ea4c5e20c22245ea4b354ea70fc86032d1192e09cd90000000000000000000000000000000009173d4d59ce7fc35d9bf15840f3f56a735c5e0a87108b2ebe5be19d3b4aa690465cd59ef2661d0a3d7e88009c346be61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016307218569b19c148703af5f321698122baf03b59251e0cd0469bcf7a8a20d8b9e54a16d2dc1f4a2e2c2c6fca95ea780000000000000000000000000000000010d8ec69d5ea3897197bffbd494e13679b82fc48f5468e4ed42b4bdcc8d9e0870e84c70c1ef0a997175ecac162f99a54000000000000000000000000000000000abd8f45025a5342284a746e2d6ffc476902279f81a7eff67c161c9212a42f7598b5a213b46711d014f0635ae41caddd0000000000000000000000000000000004747ae66bbc88b9838af8be374a84d914548670cf28885a49fc9a1c8dee736023f8819b1a72c1fcf7bb9e175667038c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d65c68026fec5ba5456025f4c08b63669b486ed1761ed1dfdc40acec99490833109dff7b401ac0ef66b7ff67cd3466b0000000000000000000000000000000014764b47407d0dcd32169e0a1b83fc76c0773c8e511141de9344f64e8ac63f5eb48cd8b5c6c54fba4326791b512525320000000000000000000000000000000000cfcb716c322857a46d7a9d2467d4ef1f520f752b7f264abd4b0ee4e9606d255cd5493849ed3c9ebd6f8681255ce53d00000000000000000000000000000000010ea7f244f9c31c3988c8e8859938881de9380c0d773ae353207a7207fe5e11cf52dadfe79c96e5630e916de41a9da71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000153d27abdf1dd3dee817d9262dd41e54134d8ec21c350fba833c3a9105b7695967e4d1bd5828a42a17a49baaaac7d947000000000000000000000000000000000b88ac63a84dfe3ec5d12bbdc2c91d6b095b2232fb071d81041462a08e6f82cc376fa10821e3df609bf5d26d708d78880000000000000000000000000000000018695c06ed0769453546cd1ab92af6e6cc500b0ad74b664bc378eae8f6ae533c4163316a14e98d084838274527a4e3a5000000000000000000000000000000000afa982eb924c3a70b47920210986d3ee3660e4c1765377055d7c9a087112e68023264f7b1bf2248a91a3c5b3468cdcb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eca2992a6208112a2bd9af4f48b7b4b64f23a4745ccf6e22ab271b88e4d1a9f1dfae50703dc408f4a917a2685e53f70000000000000000000000000000000000c291bdba0e6aead00c842c522baf92fe3c53117618e8a7e3df9bf110619b5f01290d291cb309a651dcb49f65e470f000000000000000000000000000000000179b4eedccdbca1966b94bc7fb5da250656e92243f7c4d301be858733ea73f49516ae25d6f5257e60285865ff26c1ed4000000000000000000000000000000000f1e7a0cb3a9d8c5dfb5b96c6f01afbd2c7cc5542e88184d8e0f72a6c24916e91e4f8fe2690c9af8a9d82cf737f02c111824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002431782eda44ad08e1b0eb24da6effddbe2488ec70bbc81c0e47fc384fab905070bea968fbc1a9fef69ee0163ff0f60000000000000000000000000000000018434211578bbc2be210c29cd3820b1b8f99e4ef9c39e8db8982e6783f1be62ea5d84c8ff98ab420386590b7b0497f080000000000000000000000000000000016b1f18bfc818ac6f8b42b8d725b4e3d108609b55827361734a1b178d567e5a91375118089d59f0096415b02f80fe6ca0000000000000000000000000000000015311675dd364849c0b15b3e68fe3ad222c381185a95be25233e9f72b089b271ba4450db5b5298e9ea9dce5b4f62ee951824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001826b931f8f36dcd99855fdc37f2f76fdc3831484d9ff9d5a4dab19dd80a78f698ea26fb7816438757c7b43f85ac3df00000000000000000000000000000000001cec37a4c3a9cfd37d47199ffed888a4e08b8926cc81c521604a9102f45e5fb45fc696dd5d6c5ff8ed5feaaaaf25d610000000000000000000000000000000014b01fed71c43b1b2763ba6adfbfc77faa1d05d8f92f96b4d1d27513f106cd9308dc4a8d14ed63ca7f885a36c92aadb7000000000000000000000000000000000692cb1c34322d501e07cab7e9f65aa9b7ede69ab1cb51d3a46f3523ba11564b3d6510f42649903d98c6f4f640c1e87d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f63a21485c9b69c46dbe177e5d6aae9e0c0972450575f85cafa41d38b701308fcb4615231bf3670d2c65e5968931e7a000000000000000000000000000000000a2d2a9ecacbf2853dd9657417d1056c42b62904eebb1e2a91297fc73ffe22c09d5a6fe6951b7b3ac799fb779fb8c0d700000000000000000000000000000000170ef99f741779fab6443e58f54131631a337d1a51f50643f3bb67f79ed0c5d4f76ae52541f141e8eb7a12f1fc9a0e5300000000000000000000000000000000017ade664b2250785a250377d3a2d5867c32b8558d886a0391816f200bf90d3d43a69a02461af75f5bc823ebb63241411824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000976091509c439fa6d0a28ef740be1d2a4adbf7adceecc68193884d3c0991f995bc4cd157ff8ba01fefc7fff9fd605e600000000000000000000000000000000195e4b6d8742b8ad41b226ecba866ca0e2e19f132d2421110256e71c8efecd08499928796bf0dfedba7e5a7b5b4ff8e8000000000000000000000000000000000b238a6569412720060d1044e4d22d61279b8bbb5dc7036577a1c7991a2ff18ca04c5522399890b22555ffdd4e3e9e94000000000000000000000000000000000278aee8ef24f25801baafbcf353f1ef8d0b6d78e5dc248791a27b050d207688ef9180512098c45ffa0e342e6971e5871824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e2d0cd0111b5d5078c9194bdd84158c7022ebf87a3853b0ecdb9ad1d661a51d742b2371769f62f4ea8c0b622ec7f5f0000000000000000000000000000000004a4e735ce00444a58212ce7151bfb09af25a9d605f72e3945d7c1a39e06d7be45c65b4602e39708d1aee1c66280831000000000000000000000000000000000181ae1c4fc4bb2e998a3088f025c06d5f0bb1211d162d31bcd30018c3d12b05796458eaf46cea9c99014c40ba3dac6110000000000000000000000000000000019514645ef5c815bfd4900266363a04d76a8aa4846feff37c95425513bd07c413b290e45ef6768546c575ca58ee6a1c71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000159716deafd9486d82c1edd265e334d58daa3f715a89e0b138b2fb5be8273e0cd6af4573804267e3caf1730152b3f838000000000000000000000000000000000c5efd41e630583860e09e28a03aa294da83e21678fa1d66c126cc414d3e86126126c5814a1272152578e8227c66604c000000000000000000000000000000001003959fdc8b53df3e29f8c78e155aeb88fa1338e978fcdc11ed9c0a8c8058be73eb2de6091c8c2c071ea1583360c57400000000000000000000000000000000104ccb8e8cc1edd2aa4a7e856a3d655b3fe3a3cc29fe7ff6431f490dd783cb435bc04f2c0ccab28da7b6b0b9d988cbf61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001212a2c67dde7ea1e34f8847d6c1ede1dcbfb09c9e4fbd60004aca8ad0e116e5a6ef114682a2c3eed89a1155d786746b00000000000000000000000000000000016a6fd89dfb33da0c3ad21f49b24f43622932d5554a51696182137cd2b4e75a182e99f26ab350b724e9fd5a97a145f10000000000000000000000000000000018ca96cd152882ac920b7b3373cbd5d58f956022e3bfe2b5fb943f663a5026c194f32fa0ba66493e92246435ecb27d9d00000000000000000000000000000000135e65ddc9ebcd7587408d79a460eb3a056797199ae736ee24c96ed1fe7af3c0b06181aed64683b2ca54e3585e63ea6c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001146898701b384be18a69f8b8a5502872c07d2dbaf8b9875251ab4932ebeac48516896239dd26e697617628dc7f5ce9f0000000000000000000000000000000000c2e534f3ab1c183ce868f3a8f7f838ed8073873453334e81c66a3c88e25c9c152c1ccc557d7381c6d3ca227743217c0000000000000000000000000000000015c9bd39c476def60654722e7d66a1c67e5f709a79d4863a986932df324d3098baa81f7983a45ee3b9b243dbf5c7f012000000000000000000000000000000000391e16c496f3970d3e651bfba2de04c3ab8d2030832a96b4f9d3e6eb929f8391459ad0b731af382e92afc69c791dcd41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000149c62ca958b77caa3658cd486e350a153216c597a0e2df863f17207ef8023414e87ffedd9365813765f05fd88b0bad7000000000000000000000000000000000502514928161f0a28de23e929e8e5f2113fff4374ea6c6b48982e99a261f46da0d4619d8ed587b714ae84a06b2d4abc000000000000000000000000000000000978b5c010aee3ff492143936547fe42618ad525e95ae9ee8d045435db9b34f8e621cf78e0eb2b05c3ca7896ea8a3ae00000000000000000000000000000000016e2fc63f0066702f5b98441efe6d7177a3396222a35bea29d86296b7520f5fc20d221e2cbe5e4222bf564adaf3a22be1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007ccd685d94a5d4c35ffe3c9205651bed55c4257673bc4e34f1009bee5648cb2ec5fb468876eb4471c4b207adbb3b7de0000000000000000000000000000000009a47a6052acdbc4ae1ce4580bf65df6e62f3309ab7a5dbe3985c88798fa4cff026d698cda16f2b00a9b97e4d0be85d400000000000000000000000000000000016da47d5358e4faff56da4a4285ebb52c4645af82d90886312258eb5c5bbc65e59f8a4686affd0242688eade58324dc000000000000000000000000000000000a43a1e05a86d25657de4a5030a5dcd0093bcc0bc7f639790eca54583d0ae38508a37809a167e508f808d2eeb5c2cd8a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012cf3a001164694b023453a40db3985d13eff8efadd0dc1b6271c794361cb7835b481c9a65a01c1c400b43285d76644e00000000000000000000000000000000165f4933d313e30080651497bb851111f7f5026e19024988fd637ddab6b661820d65d94e8bc3e250ae517b3dc05b7251000000000000000000000000000000000c0dfdabee46f9b0e218ca45a1fec30b31f9eaff8ffc155fbb48fad1ce8aa5fe94628245117dcd8e4771a72c6c32e3120000000000000000000000000000000017bc7378f4fb0e5192da4d093d01dd520f2fbbdb8cd8e61ab153f1a69e57debd4b6503e136ea559d406b09069143c98b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014f2a0e834d4c1edfd89a97226758e4835c6e4d5e1526463e796ec984740d82e9324875fbec8d3f3d6a7e08cf7a878f20000000000000000000000000000000015ebefda39a7113abc5b53488f00cd6c57b1dd388f1025b4e5661dcd22b62aed4d1fb3780fa4e18aeae548a616f4394f0000000000000000000000000000000016cfaea18431f548304b5f2898de0def2bf63c98731e66901b4f41e32f70a5b6c768673dca87441208daea27d0c227a7000000000000000000000000000000000cee61b31e2c3d9a6a8e2bdd24f9c63ab1316a1da37066b50a6d73245e9087b2e4f65f0da1d17164ec561b67b1b63fd51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6c3b69da6de4452ca6d621dbbcf0f54c4684caeec15b382963a00e0a0ca1d34a17d23c02073a0dead7dc8bc0ea67b20000000000000000000000000000000003603466f5b593eb067330695b2bb6ee89ecf48a32e71f70f5e5b6ed9ef99a7af877f762f3171f7843d17ec3813368b700000000000000000000000000000000109d7a34b29f984d742bfeebce03f0b972270be7838ead74cc47e62c4c7ac28c4209c00b81c3a5eb2979f23041fb87d0000000000000000000000000000000000eb9b10f194316243529c3539ee89955635d7673db96c41b7972863c13798b27cff6d0774ec522a55f7e97f49d7eb0851824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012fe84a3486bf8e818643ff42802dfe934b4eb5930e3158dccd0bb46ae4ecdd31367fca882bfe7e63bcc0105c50e31230000000000000000000000000000000002a29dafe28c8b35ef7bd129195b9e9a1a5a7267729577c290e82f13949ad6a78cfc7065091c81025e3fc3c46c978d3a0000000000000000000000000000000001da15e767337f529479b0f29a4ea3bd8a28f1d0dda7ec2dcdac09bc3292c0e336e778226e2ccf0622f3fa60faa186c800000000000000000000000000000000168f2c2a00e33dc93dbbf746974df7d145ceb3928f58fb4b8f345401d972080e18dab0a8a0ed893910d37545c7761ac11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a7d918787cbd36c05ba95bb13b742f3d8694d3accc072a0e7492d8dd13d4375f78c2f1506e86be64bd4814ce041e2390000000000000000000000000000000018842ebba79eaca0b724d072467a4c50827e2e57da5c5b632b82432deb82129789f01f912a192383a7c2513e9df0d9610000000000000000000000000000000015fa7b6924ead3bfe46446bbd55d4e8b8c154ff49742ef3db6e075c813f5900032eae95bc440e3d06f66dbdb65ef61ea0000000000000000000000000000000009691570ec96b20adf3719d0dfa4dfda5b41dba1f94d512f842799a518f39db46b0218cb3bc0a6bc26af3cea83ffe5211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b32fa61a5bb9f7ed055b8e6aad30b278d5404ff56d1b81026c7767f974f9d83face382b7b4f0368b8286e8e1ead8cb700000000000000000000000000000000071a73dd8f89250437b57e28c3e5af365bb363406c4a70a277b57242bc931ce6d2750339d7517f2a7b9b0796976395ea000000000000000000000000000000000d2bfbe18363c73ab189ce5abc02567442ab24f5ac6f8b76a1b5d8242e5d7417679ba1c65a1b1972db6bf8635d49abb10000000000000000000000000000000000c47ff062ddcc7401da07612ccb76bee27b83701b220e7d295b252074e9ae0b340296e8155c585c6e347a0784d3c0831824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000237635eb8189d612dbefe663222be08e27d991a092a9e42db7c2dfbaa55370b4e68a7ec50cd7120f3980d991e485d4200000000000000000000000000000000109b548f41cb900f3660b63cede53454261e7b871c6724b23855fe475882991e7a52fea573cdb2859755d70eeb4b4fb800000000000000000000000000000000094ef53e1a5f745f5c3e23c7bf58600f52e0dbf41296874b43307b8244e3cf6fc4044d5659cfdff4f2fea888a65fa5c90000000000000000000000000000000015e3bc1422f4eec1fe741c6e9ba94f1f9d2d096bb27ef99910316d0c73f78441d473a32ff1d4920a58f6bc39c429d96a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005950540b7f5044c42c34690c88c99bd9705b58abd5dd5142e47ebabf28472452021cb7978a17409820843a2eddaeaec0000000000000000000000000000000008e8cf9c6fe1435a5fc320b3969edca84008aa45688a88c54a882e6ee2c63b6dbcb3af5bffd9bc451dfd6ab8e72106a70000000000000000000000000000000006770f7eeca9627507906a3bc548e21ff0858a4588b93cbfd40ea177fe55ae7354bab74c2a6671dd4de29e7fcb15cbbe00000000000000000000000000000000151cfa452a924f6e5d085bf573bd249ffb6de78844cc369ef6736d82017c455abb5237988b301d5d4b6c28ec6b97b44a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001555d33d3067d263ead52793e6b21662c9dbc0d57cfb4e7287a0715d010013bc14d9c66840774e100ffac3199e6492010000000000000000000000000000000009a80bab7066195381b196e6e84c722235e39c77ca3df5f758be7ca87259011f20ac2540c07dd587ee3d807bdd8d484c0000000000000000000000000000000000a64060b8c54824a49467473efddd469583ac5e31a8a0c95a4308fd9d1dbda21b6497b7d772a059cde2ceb5dc1573be0000000000000000000000000000000012fadce1e622e2a355451283cdd33d0774f17cc425cc1dfcd2e85fdfcabecf013c902597b9a387506dd52caf923c08e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005b77fbc64ef78568a3de70bc0f5b8282b7b3fe2e0d6d4f06dec00e90e78d757edcf3286a4d47d6613c2080c8eb57c3400000000000000000000000000000000083d9a9ac10b128580a3af7aa704ff2dd42c698d38b4635137c8a7491738539d96724fc8c8cbbbe9c7ed0369f8bfaae40000000000000000000000000000000003eb249017248e1791ad9f887f34b447c2c25886dd3e7c3f2a052404877dbf3eaa3764412f4e5000a2b3d53b6d55a337000000000000000000000000000000000939ffda58c435d64123759c0e512444d05908a2834f2547f5278502032eb84f1d6047d67096c706769edb40f67e0a6e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b630173e8d1a00499c6fb7740626e75bf5fdd1e91b875e21163cead3230e8ee9d53b13d53ea116d029767305807431c000000000000000000000000000000001320be7664b46285322d5f767e72a4a9da32463b58d9aca4118a5d738cc40dfd0feca21f6e9f308c8e0c8b61e8b482600000000000000000000000000000000011f5b5ae033d14a8ef8704d07fd409fcc89fd94fb46c50ff8c56d0ce6e35e3ccff78b447f9b7bba1cf075648631d197a000000000000000000000000000000000e2680c618adb8ffc751c5999f68b18eb78efec68573eb212557aca7edc891a2c47c0f96f8cf14149eb1f0c8c67061a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000af258f212fa69a9dec8910015fb968440bc3a3681ea593e8ba16be58526177549ea62493430b22f1cf2e87dbb45ebdb000000000000000000000000000000000510bea33d26c2de27ab23b36803bd4840bd7c399d0ee4329193e6b9c192c109ebd9b37539dd1279e7498084e734573b0000000000000000000000000000000010dcf586845d62a20bf0e63bc8fa02846cff6aa2f2bcaf009823b46e907a428f2eb724290a81587af781c60c55abbcb8000000000000000000000000000000000088ff84e0c3b7ef6825f2527985689fd2f2a54961befc05a76ddaf4c7b8c601a6d0b40200145de06b9b50a6004bb5211824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000441f28adce4619679e982d3f3e3041a2348131a5a54a93d9ac45d62802a862f5610ea21939a0d6df0d3e0253926436500000000000000000000000000000000160a14cf9f2e30d0655580c3d7e998adef7037d2ebbab02885f721637e797c74a53618c7d6d09233e3a80582e3e4572d000000000000000000000000000000001414b0fc8d37d5ca1a24b5e1e1fba58e154069d0ba8143b0b0e105dbf74a20b1bb9c6c95648646edf7cdd58ae507119b000000000000000000000000000000000f22084af73bbe1320971836eaf0e775467b70c55466a6f5cb2f20d9a35107036ba621d3ecae74fde937a2a810e600b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001466de960bf0b18f045bc56f8d6ee6f5e0e293a589dfd396329847a4ae09582b2597ad5bd514009883988766a97daee1000000000000000000000000000000000a31eab509a1fe1a624e6606e95fb54d3ccb8a317c321e616295ce910b854fb0aa4617dadd42c686efe0138848c91d4f00000000000000000000000000000000008a6eecc250f1d648b6d8f4aa9dc72d5ad0d08d69d85178a1b864d5d84b8e121a6bdec3567b9cfdca6bb93b5661bc440000000000000000000000000000000018bb1ec3de6f8f11bd897b9e015a7c3362c396af45fe52feb005f268acebc4019006250a469f01d62074dfe1457a6b281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001954ed78df89916120fc161ee805397543c67d31258ac58d666f56a6dce6e8b9a6ddcaf95121153cb5525901d85a8a23000000000000000000000000000000000baff6b95e1248e9e1aad9d9519683c1ae9a915dcbe270be5113599979539d5b36cad24782d9043ed605221a537ada18000000000000000000000000000000001642fb8c382e2b8bb8cb113b0fa3479b5ffb9806c0959865002501c39fb69e6574544a03f88b9754933cc97fc9307d280000000000000000000000000000000007e3a95e0f01d44cc452713c22d7e712afa190cc81eebe781944632a3e5eb2c2403c08b91dc2233ab96e2b6f02d30dad1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000746613818fb69a7e9b30f2751f8f5d412ffdd5e04dfe14b6fb9547dc40d8a2a5fd90ace85b2c5e5f342e27e6544eda2000000000000000000000000000000001463f79461ab147e2427f886fc360542ae37d53883dace17dbe2493cb57148b3a820d68a9d2d1208268796ce2cd7a3400000000000000000000000000000000014d087ef9d735a798cf78829e5a64b1e5a86dc2f62baf6c8a5e696c196db36a51c602eeabc6a1588ddf5ce1c814e2f7600000000000000000000000000000000149cd177b7b2ca0964653d49e96f6f175c750ca4df30d0560ac6678a5d650083ea14b04b69c2eb7aacc9407fcd2e1c611824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000dce477f427baf54a2620489cbc45289f1df1e9132767c218fd19661de2cf02af74a35a9e66193d44bd395fb96c5f035000000000000000000000000000000000116a85c3ee84147afb19fd112ebcdeca8a6a5f4dd48d33c7cb431264c2a61c96a36605ebfc284a7158840605051717e0000000000000000000000000000000000e752aa973c7f7c46b763f4ca1b8390ff12f241449cd09a95d81bdd532f3d0cc894d51ee2e41d6e41b161d139e39b6f000000000000000000000000000000000e8db82b8019c534a439dc2f09369e74915bcab3b6ae7e9d49427f59d52102cf2b1db043ed11e9da30aaea67b41d56a21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111830b6f009d5e92d2f19f9ee0b51b8d0c82e361046ef0a1ade136dd998ed6e5a0ab1794e22943fcc6a3af4b5074a730000000000000000000000000000000015a06d6ef2aa3780aed246e22365dc2903b4c30ab89c5610e408e64f0deffa66fc39242053c0492538ca023f1d006dbd0000000000000000000000000000000009729686416c78c85e492c922fd9c1b0a7e69009609119abb2dcfdb0877d5f750a84035ad5c04ffa918c6d6b6ff3b2720000000000000000000000000000000006f0502a80a83cc8d787cdc03b0b8891b7d24a693b9903cb08ce4007ce5b6ada13fde360a483da18fe9316d2d6e03faa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012da5a2f312c5c352f3ef7a9fb5015568cfaa56a2a3859d4067802839ec07201c24d9717550854bce3058537ce49742b0000000000000000000000000000000002f270471a3ae6f72647978c850d4f9c3cde09dee309fee2b653d18b5300243c620afe37325fad422ed2d3388294d8740000000000000000000000000000000019e2838c731b3a02bb0faa24dadb5d46ed5edc9a318c5aae8bbff763489db5a35ce78b9c0d6baa0ec8617be6e55bfb6b000000000000000000000000000000000fa8ce31762a18432e8d985e25737b124c8443209d8e0789f3f3238a9e825eda9d162457a017ac3037228a45279e84051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000139ae67f3c4cc1bddbd70e180242f25f4637c1b109b671a667ea72f3e647406f8452d653d04890202bf4acb01786f88900000000000000000000000000000000078513b9f725201cea64ae5e2c6473ed35c61ac335429b1715c75c9cfef7171d894771f402254cfe84fc50ca36c386a000000000000000000000000000000000121a8b1efccbeecaaae7a499479298289c17fbdf1e2d89c0cc4837ad39d3839c7c9736822aea5740f6eca15e001cf56c000000000000000000000000000000000076f73c42dfd90d49803cfe2fb2678df7cf609430b2db58af00135c90b1abdc6307ddf4efffe5f5f416c08c0a7464751824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000600a1682ecd3af6957c599969468bcc1a000f4cf98182645b6aecf256af4c5987375659a76db132607ffd77e4a5134e000000000000000000000000000000000aaab49b490286c29c818144ed6682fa4604fd952f09d134a4de74aeb126b76df32d02fe6a51b62b1acfa303ddf4f2e800000000000000000000000000000000101c4f705ef8014846fe56c3263882dc81d0fbcae85415c7b6ef0644ccfbed27b917030c75f8551f9a354a7299ec2f1f000000000000000000000000000000001241f7e85497fa33da4a6f0ea679551a03481bd31561cb243686c3c62bdc66c2d93b645a54d2d29244e306af1d6f007d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000226156e38cc42de1c0b9bafabd5896e6809c08724aec4d4bcf1db3d397ee539163096ce97286337c189c0a3d4d764320000000000000000000000000000000016c9fa7dda47cd916d8ee2ffff6414ac3b3820d36e7762e3eba836a1d1837c700d4cd4b18bdd56f237e6d5319c438c6b00000000000000000000000000000000107df5fc706e9cb9eab01616d30d001ab32112d1934afc255792f70bd1f341c2ed7fb1272ca62e9ed0efd54a5c6722b300000000000000000000000000000000190db68f1ea0a07e7d236969fb4405507b0dc53088736cde07b11452bddd26a6b3d4ed634632beac36fe5ca01e9bd16c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016aaf6c50b3a4807a9dd34b70c38283ec5021d8aa9420424a352d1578db742cc612b828e0a2a435ba6323c8dda0ee3260000000000000000000000000000000006df2db36b93c9d9c171388d1b09c41412c2099c259a857b93ce99b5350d51d82ba18c37d6064290c6e81beb7dbd82d200000000000000000000000000000000035f2182ff6edf2b95012f2ee57e1a28f167eaa4697a5d4928f1019fc6b4abc27fbc65515454f833beea1f07a8e3aca300000000000000000000000000000000062ac88083ed4ead633678f6dbea62bb89e386d4594a74586293d40d888f10335c306841e519c50032d4964f01fdf6f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000020d2bb77c3b1203e201ce0a2b9b978d3426a1a825a2af0b3e340891e67b3684c8af47b819cfacc90313c595d9d442fc00000000000000000000000000000000022b242ef209d023014e83165f26838bac71e3eaf395d53801de21b1982af93bf250b2d61d9fe570eb0ba328c612242d000000000000000000000000000000000fa61bf491064282b3ece7fc40c3736c0e3e25553aacb0b5cdf277358ea7d251ffc2dfd432ff2bee5cebbf2b6c3bbc530000000000000000000000000000000002d29b91c99b60f6013e00ba867d943d5375c118070e109461ee2d0dc9e0a5f6bab9b9c2fada534955eb1c63face10691824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010446443794bcff7795a3377b3af9b9411d6a7f3cb2568fd2db5a8a0ab931d6a1b217fc9838ace79d18e9c743bedef070000000000000000000000000000000004df7f86aaef2ade996ab857c8ff1b50e78b928451663d444fea75d41cce178dfa2067eed81450854215f2c004b2641100000000000000000000000000000000123e9ef5f5b3961e34d8a194da8f264b468ea89ea9beb305f33ac7f6ea0ceee1ca84656b315aabafaead635a8641ad43000000000000000000000000000000001753c10d98cfb625244e20866260080107fb6eb4e1a9d00ff5f610d5604723f5c69dbaf3057a99d72fa32b04232de89a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001292a864dfe5ad73fa4e057daceafa483dcee68289f1090ea86c4a64a242342067c71c9ff5816725bade360beb6d4273000000000000000000000000000000000a776b048b47e4277e12d896d580f04d964c2129d9fbcb17985eb1bb5cd097b3cbbaaeec0e5c835973a235bc507f282f0000000000000000000000000000000008b6367b731f2f4d8cb6a7c35562457f1ea9c9ed48aaaec963c39a4a0026eae1519beb4c83ffa7876577732f0418f264000000000000000000000000000000000e549976a666dd7c85e9503114de6e1a3c8329b8ad1d29e13249c813af438de2db006bef12cb34bc65e24a1e79bc82f41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f725f0e0b443774734dfa3e2a2e6070b08f88580c1c1c5faf3b65a2fd6dcf8000908939c060b00cd5b821567194ae800000000000000000000000000000000194a7445389d64aa9d29d9e6cda19b2360442a1ca70c883288ac75fe22f5848737eb15929581544b21ce26aa3d876088000000000000000000000000000000000b6de53d5dda1699fb305578c86612fc71652783deed78ebbfd59a2f419b48598d26a9400673c68cce2991d137ff590b0000000000000000000000000000000012d5abc09dceb589932f15f7f756763f1d5047ccb7d5f86ce41aa13ea2c4b7a9357e6c4244afc1495965fe6d92b4e9f61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002c871727a46b0b7aec724b0c5a88f84a45795bdb4f22f8f67bff65a44e6c818ecd577288a2bf913c3b61674abbfc33f0000000000000000000000000000000005d5bcad18543933bc4c120f2da68bba81015b2237975b69ef6896a618f745be72d1145ab62908ace3011ed00beedc5c000000000000000000000000000000000f061c113d4d9cba6c4b402710c7fbc23e81b37dc6fc666196919dfdbcda511ae312b3751faf560e60ba606b90470b750000000000000000000000000000000013e96a9d6f9201a20d25bd4fa96eb0f78d6705cbc44fd8ec4e760043e44fb36f36285ba67f94ac4ffa3012080cfa64db1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009f93cb9617c245969955e2785019c292227038d8f8ab4ce4bd057766420ed88b8c6e08526472275ebe1d4677a912d7d000000000000000000000000000000000e16ac32762f466ac7cc1b0388654610ba1907a1152437de4806c8ea56a827dfb60c9e99a3f5893514bcc1c7d32304ed0000000000000000000000000000000014cb917d35ec93eceef9c5253091c55cc0fb08ec6393a8fdac1bf13aa8f2121ada05871725cbaf9f5b2da3c77b8999b60000000000000000000000000000000009e44894cd7cc95d33d36dba905b780170cdcd416221aec8bc46dfb2e62587a238787b9768c492e8a9e4a6eb4c439fbc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007340a6fb5da118c1e7ca4a4ae1d03268acab0c703be69ecf6cedf37673f7726d7a1fc99ae11e9b2366bea7eca8f0f5e000000000000000000000000000000000ddb53eba1eac64a37b6902f67ecdb97020e3c2fae3ebad9c7c77248986a7b41581e9aeb18f7d9344f12d74662eda6e3000000000000000000000000000000000eb65453a34e6a1b29103e588243c89c424faf793764beef2f76adea8e9373d52734dc431bce6c46769a1258e697b7d10000000000000000000000000000000008f07de200c60859be4ab78263e72b6a326c3c92bf5d29660b050b3ab147ac64cfdc4e20559498b0487fb327c94f3ea41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005c87312005457656a177d97575b4a4e7f5b7c1ed372bd66820b57193493b880cbfbf580f0af64e68186d93238df195c0000000000000000000000000000000019689872835fd016146686e6f104bd9aa40cc1f8a4f58809ce5ba2e142211bda39e89b0cf6edb76cb4ec498c1ed31d820000000000000000000000000000000000720ca78cf5394e60c28f86c28cd73779e1acd9c91d33d75768cf8b2e4d81c20bf86df5b996fa837ecf222a576d42c8000000000000000000000000000000001818e35c64c9bd6885295cf37e96a73b88f67ad793703491f3dcf5cda8a65db0494bc5b47c491536cc3bbbd3ad30bb4b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001243248e664acf6d803966286cb3e13e5651315b509392b89cb511ab5702b8ee92696d9071b64221183804317456ae76000000000000000000000000000000000ea1031d4fdf7860ea01ed3dfff2a8d56c7a588862c22e9895d74ef770743ddd964f681c4a07d95f4a83ff06c4a148b700000000000000000000000000000000034049cf253306bd7d326d40db95adf5b97a5b45e25d27c7fc7478ce4e4d51a4e0080420f5c3b4540d774c259b837d5700000000000000000000000000000000178fa2d33ee61af3aaa5f79f29badabefecf07582dd61eb16e26d9e863e2d222cee9735f0e4cd70a017da649ad342e271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003420a3eaf6d6c088f3abaf983df3caa90bdc2a82170257341595af736dff55e5d071e7e4dd0251d7984ff7199d6dcbc000000000000000000000000000000000db7b8e9a17b49f8af699c1422344bf47d5855ea27e190384384b8e51d2b2151eb7f983bea785e529d1620d076af8c92000000000000000000000000000000000f3d784f5aae94783a5a47ba0ada086ebf722bf27b7eb3fccae56b2b0ce5136815d28463e42620383dad753e39b6b7db000000000000000000000000000000000e1b33e3d2a2720f114d3f3b2c6c73f4d4f222a58f2fdfcb000606d4e047ce636f1ad5f460a2283f6b674b7c2d5747c41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016b7668222e37387e21cdb6b3e0107846b7aa868f687227b7d9d6be27cb1efe57fdb0b719b5401e0d6d4e1a64442b354000000000000000000000000000000000ab894e8a47e8a15904e1760f59249329cdcb7f0f939720629f060b530e4998094a949a34c2316bf7758bc35622003270000000000000000000000000000000007046b0f7c092b0cda5891d405a64829152ef5ad41d4d5164a20bff5d176b1bcd9ac71b6b96ac7f3910dd4ccb134188e000000000000000000000000000000000698dcd91ee30501a9941993085f860e4e30f9cdfaf27ae42c904a923490ed5b845b14a342cf7fca58c841dd85ad92551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d5e0bb49c375ef74222a26899dfadd8e257c2d25d7301a761778e50c629d9cd733470e78178b73ed66e3ac140656b5900000000000000000000000000000000172e59fe16d189e285a09264c39fcbc7d010195019c7ca639ab83982114ac8c54c3c3db4aafe067a791d33a5b3abb849000000000000000000000000000000000cfe5c92cdd431894cd0b9f79fce485e45e377ee549a6bcf4a9b54e776485b52a1e27931a423d1f4e9791d12a21023790000000000000000000000000000000006b728d48057937aba2c06b4a1e11962df778e0189bc89937bc0221b9603c24b50a570a02617fd3c61650aa5ba8a20f31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001729ef90984984e54d57d18cdaf1bc20aa9a4649c25b171aa0b8ee6e82dacc4db41680ef522bfc6e1cb7cefaf4ea7e920000000000000000000000000000000015b89fa758178ba4f1bb19b00d25080055bd81e509260ec9abf09dba87537970d1fb96afcb4e8d98a0b3aa5d2b0d309500000000000000000000000000000000185fd81eca3bd34f4fe0f40ebbccef4b13926a5463976d09f219f44735cdccf3fdeafc220e2e6e89851dbec64137545b0000000000000000000000000000000009404a51e47648befc1f6eb8020ef5398b62da2686475082023af6b875622b54b1fc035855dd102e9d11e8b9333fb3891824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019f7695379d718fa1344007a23e4e2a7eeabb28bf7c968bfa47b3def88c8ba4b1b9c5af136adf18464f6f4ce93b1f51a000000000000000000000000000000000b3c7e3c69de69ca838c461efdf8e24624c8cf6df71ee4cebf7154d0bf91cc9226c0c91eac3ed7a8a55db0287176cbe0000000000000000000000000000000001116fecdb47df938bf45fd6dccf8c047257f2478865dcd484d74693f1f2afa11913b40c23708b77aad16377e00de3d1600000000000000000000000000000000013578c050db7ca7bfa84061f9621d885ec1f0b14af74892eda50523d9392eef2295b0b70df948b3d393310416713ea61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f790f46b0b15e30a76d3a47dbb411756712a0261807e425a4beec395bd48dd17111591bbf6adb86df128c6b68d9d81a00000000000000000000000000000000008ba25aab1b09db4e9d6edce642e9f16ee4a6d9d42af02410cbf728efcdcfca769879cb5201b0b4e40eec2a67c0497a000000000000000000000000000000000a0816ff7c73cd383f1c2ff1ba5702c65d057a1fe7a8a9d049b42057f725c1ecee1418d2fe782fe04b89b0d6ca6bd22500000000000000000000000000000000141fd5d1a31a1827b84397adc3265abd00aee9a2059c3af2bf266f04aa166d28b332a957f5714965bc9b9902eab7303a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019457eb033efa116078c797dd924c056471e6073105b9eff7c6777e3e89eeb5a74e56fa7045b7b772ff3f9139bd9b5c0000000000000000000000000000000001474869e10aa64e32f534fa418d0d006e8ec57fa2bc31c06b5164accbaf389e2d1cac6cbfd41f51080de1b68a38d78540000000000000000000000000000000009ec92685445b1039531f29947af1f4a7d1ab30c1ed25d896ecc7aa23d0caac0c9bbcb95a7536522fbc142dd28548e2a00000000000000000000000000000000104fd0947bf8e74de3d5d626c7fd743a4d0b1b3ac5abdc546072d88e7daf31b8eed60287de7b595ee9b4b7c75121eadc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d893d521ead5cfa993f3ecd441d060b674fe4759fb393dc342b1db428964f71b0864f3682ae75cc696a8401a545c2100000000000000000000000000000000020e5d15f393d571d92b204f6d0dcc66c60e870685b058432e2d18d0968ef9df1f60b7b91c428d2fb03915218d50e2540000000000000000000000000000000006946e5db6a06b0a74f8df5ae252c978e98e5aceac355e41031737b4181e4e30ef51b619fb3209ee91ad089965a15d3c00000000000000000000000000000000023ff23f09d104c9407b0df7fc543b469464e9c09daa7632a6bef2ea7371801b00ac90874d5d8534da964b7d700cee5e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001246150193c62c8d5bd2e35a0fc7c539b27fa1991f3f7309afff45548a2c862a51b8b917026f51e1ccec594e283cec1d00000000000000000000000000000000105bbcdaf24c0e3011428cfdf5511dc08edfda5e318e4148ed442ad069c68d195de02bce17bd1374d47c2bf89e39634a0000000000000000000000000000000015db5c23fb930f1adc6d76f14dfb54b0fa1e19ccb773aa0215251e4ca3f1b6a84c536ae6188924bda4b42531c4544d6b000000000000000000000000000000000c8d52c67dc1b86cdbaa3486385af0c43888c73a9a395a296ee95e2cc5ccb70cc73d5e9be07bd62fb0819025e173f4d61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015b9f0c580d7eb3cffed3afb22235c4c099504d272c5b9aca95d87c17121efcaae42333b0b0c107c17efe7ffee2a07500000000000000000000000000000000019286479995820bad141d275e2c73a14bacd4e5713d3c5e3146992a05636e5419c7c76c960428ae6cead53025a87e70f000000000000000000000000000000000d2faa2e1569f7e57eaa730b98af089f950acdeb36982b88d8f8a9b9ce10573457d4e2fe9ef5fef1db21927278bcf5230000000000000000000000000000000002b88eb2d55e8af15b7677e6fae3d16a20090a7f93b5998f8772cb351d7aa32966a11ed7929a872f8af7274603cdeb661824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001276ad4fcda2f33e43f83bd4498a1ebece3981e8e0876189a4d911320f9697987207b44ce33df7653ca7a9949f1490fe00000000000000000000000000000000002509ce5b2c21e6d6f7656c6e4ba97c5fc55245494d3db4c2ec1737713817d32996150fb8afa32b3d0860162a5cda800000000000000000000000000000000013aee10bcdb8e316173ccc47c6f43181671d9df84c24474166496a09f65d3f7f9acf5e8e05bf9e4e79b747f25586d9080000000000000000000000000000000012a34c91c708d994fb0c20659c5bed3ee1293c11a138d86b1180ff23fcc5808b5883d6b9023b1be67e8d9309a2481c901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018029631bdd03f299fb60ad1fcc7c8d5384b3191d148ceeb1257ab745ee072ee5feb1822a72881faa64e606ca4d38d0d00000000000000000000000000000000143284c6f978c33a329c5b87f8dee7b76ba0b6040e58903684e973eb0c9e3a5645404feaf6dd97d85e56bd57d02c8c240000000000000000000000000000000007bd1c6081c6c472aa18549ea922ff46dcc6429361fc2ed1f67908584021bb4bb634d771a5647f87ae438255d43e9dfd0000000000000000000000000000000005317959b00fe5fbad4f4fa7c10a565049022e8c1b5e168681536156f1b03b96fc8b44df3fd97d56fbccdcc413766f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174b8624208828c62f08f23a7ad6a59501b3e98e80e150e5cc2ee8752318d43fb3faf0bad522bc8aba70a04651df1e130000000000000000000000000000000014776d28af31e64d4038ed0319e64180cbf9b5190a62e3a43fe0607b5cb0717f1fa8cee8b4824d8bbe9a531592084a2f0000000000000000000000000000000015e87692d47baed1bb4326be47df36915e69c24deb68ca0357118a25a4d272f0cf58fa8bc73ae35ef6ed48f38e5bb153000000000000000000000000000000001427e8ae9c2f0619e700310f1e72d8f291c8b8c53e8c751b8f0ea3424650216908bd56d4a76d35d94524e2df5000dbdc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f10bcc727a623b45d9c7f267d22a8ea999631339dfe53d9c3de32cda38d0d131579821fb08c742c2c0f80737aa6593000000000000000000000000000000000f7463f27129241ed2c32b55ef1c38d05e3f05a127a8ca6efed07cc4206393ad06f4bfcf173222ec66d944bd8f4b8f9b000000000000000000000000000000000f05be82493b1a2a0f1285e1b77850e839535533b88a8c6546c6233a0de2d4425876224fe7667562424129ceb393707400000000000000000000000000000000085a9c309021c17e08c15d9f2bb8098fbfdf5c4b3f3bf8a721adf9aba8eca00ca46950a287132bb4031d557effa4074e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005fbd873e62a1242f96e1f5a45cba9457a9cdf3efc80b09a66eb716b245130103ac0b2ddf9751fe501d26c4da179ffbb000000000000000000000000000000000deeb3ab3344392d21ef61529627d7afcd3285db92d09bd5e1df7a3b0667255cca86f6be91f31ff67012c2a6b8e90aeb00000000000000000000000000000000155c6467efb899da51284b1e12aaadc37c20ef270c43f83a3f9a09bfb14a39b62b3444417827cabd7745298ce8097be400000000000000000000000000000000093f491139497f0019e795da164f0102625f49cf7aba1c5903e691418d7e2ad3f353169cb530af25feba698608caa0681824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000064a572a868debd34835b63dab5826cb293d13a83e8f931c199a0764d14acb8b10e00be8a4a7869601467fc4d86c2480000000000000000000000000000000018337b37fcaa71d06b60c7dfdd4db785da6655190a97c4f09fadbcfbb45168f29efd6ca91a8d77776f57032ea7a97853000000000000000000000000000000000066edbd82d76c063b0a91f37fe737e9fdf4967d9db18f4abe707df654c9980f77eb090142693f604774b6e800dc1b6900000000000000000000000000000000181bd9170f327740e4da7189bda44da0fede263d9bf70264b95aca21c6c0dcdaf50cfd107a5555fee1a1ffd299fda25b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003a9e35e9310d75d81bd47d86ad79b532aeeeea8d26f4dd803e74d7e4ec11baea8c70136e0245f801695b1ceb0c71dd5000000000000000000000000000000000578bed25b80cf68dc823acd017a30fe09f20bb7ee4340d9aebf9980e041df3886ebf85b1138a3496c0b4a4d7e21ddf90000000000000000000000000000000008814a11e702fe9af00c3b46c44fb00dd43104832724ddfdd012e07375d7a3e71a33a17ed609fe2df77a58c60af293850000000000000000000000000000000014a20167981a60d9d037c0975ad63e8f9dfd004f9a9d501ee892a9ee3cb2c80ca9f65f3fa850d777908e53c01d9cd5401824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000c11920161a56053346e1156cd06ad339f0f54706ad87d4513e797149322f14bcf56b28589ba1e8bf8e0cf5896a769b0000000000000000000000000000000010eb2aee9bfd8c54d48f4f9406c91233f7e7c4c52a0c64c2f1f828955cda0ce22b370667a5b535d569a51e755f5b5e00000000000000000000000000000000000f55424cd3f70a8bcf02e076f7f05a667205a29f5a88be5ee8659a8ee9ce4f0fa68739379dfc34cb70e7e11d8033728d00000000000000000000000000000000071cd00e983952802087d2697ee63aa0ea29972cea5341cab20013586399e7323d110802a291828c90b4b83a338135021824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c3564953e25d303df3edb5d3b7de4a1f29439e6b72c7cc487edd630b3beef300bfb01b8a2a7c46b2d87e5afde080a14000000000000000000000000000000001545c38231e77bceae49274c7b0f8090cb6ed196d641f79df2f9305ca1588aa2a7de88959560957c3b83cb33db5ebd720000000000000000000000000000000007f569eeea5df71f20809ae8294fa9a4b28541d564027d7b87565871fd78b6cd1cf2bbc04b7109272a57795fbb859dde0000000000000000000000000000000015647a3e0a32dd49deb073963728586ec7b8dc0ad79ba3f732400e3c39b38445e0b5879a9899acccecda11f7afbae8a31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fcb5a2589cfb11a0a1ebf034b016a2f673fc965d068e12a2af726bd97fb2086dc37a33fc82524f556c4ad43aa903cf0000000000000000000000000000000009fd7b3f337e0a5d8232211756d55c4e78d0f73db4570319ae4c978792d0cda5c212a7ff1a733d4ef3cbe35f77142984000000000000000000000000000000000b124553ef8d3c83c60065f9146c93accbe59aaf4dea092ba72095a4a5c94c1db01a6a64d13d7e433755e553ac5258580000000000000000000000000000000008b349e371a6ba1268e2cea53c0c83f8fa13cf442f1056687afdd9e09ba2757be841c00f1a3c0fd6ac6572d8599b2fb31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006dbfa8a278b219fac8e2a97d8be8508e4cd854d28e66a4383688abe8bc3727ea625af720ce454f31c70e159d301fe420000000000000000000000000000000002c36aed8126986c60b1401008ea598aaf9c5c8c92ef2b2b2cb516c059e91fbf66cb455251b0c09345f35eacf7c6add30000000000000000000000000000000018dc9bec0f78e2ed26960bdd3f0c7cbaa607254d8170312ef510701132e365ea0acbe9d3a922c269e5403e0dd10d06a900000000000000000000000000000000005340836d5d7061b4b4a1585e01884ffbede51118f9e9de9ec21983f870fa3c78c3bd861b8c433e876b1ac08cba94651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000157e82195994a1d886043de55f0fe38db6529fea161dc749157f623a21fd377efe72912e8576e7c2d57b994bd52e75830000000000000000000000000000000002c940880e0fa4dc84ce09b3c3bf05f6b3315cbd253f97d66e7c95359b82525e70dc05cd1b490dbcaff16a901d2f13ee000000000000000000000000000000000a6a4083a2b40f734f347920937f58ad0b4958aa2712ed367df1c44131137f17ca1bc264ccc746edcff33320ff32fad80000000000000000000000000000000015920088371d552eed0efc9c0ac20881f9a2d41d5c19b225a29678e3041ff03fa22875bf840d59431f4d005f3532c3d91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cb7f1ffbde73e1e58c2f0706e489072728302ba3ec71f337f6db0bc9644eafa92251763504f72622c21cf80f5b54ef7000000000000000000000000000000000102f6f9a587c3974942ef5eed138df216d9e6198c3bbc51f7208f9f1da98eaf3231d5433a5141fbb2e0120d285c8c690000000000000000000000000000000014ff98db3780c67df0fa65e4743222f76e53568e17d0e43d0801804d1464d1e1dac4968fc2348a8532e282dc3679534a000000000000000000000000000000000a95ff99bbe17d799b3cd8737b88cd211eafb9f9de15fb4b2436cdc33ce9cef17e679bfbe9c0e1897c36850d81ab96c81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000090e255d48b8bd61525d457015c4ad33290e44f423ff30a1354609f39bf2905031a65e7028103e877b8da8080bc9aae90000000000000000000000000000000016f7758c642d6d0ce541bff39f8ff0e0c7538f870fe63bb121d154c17c48acf6a307bc7287412f5ebd352faec70c449b000000000000000000000000000000000b2ed3b4721ae409d60f273268f0c356bc1393670b4116eb25d16f5cdda960348b73d232977f2384e16dbf072174319800000000000000000000000000000000085367b487d6972109041177bbe49f17a2e2186463a1edf8e9006c13ad93afda64b6aaa63c0a4c116ab08f1708652d7e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001456424c37c92b6777a1e00c487c808ad903f79513dae5cfbf1cdd824d1a2eea62ee8fc2da2c9fb18f7a022f45855e660000000000000000000000000000000000e4ce03ff33f8e05a9c01d472bfb7be6f6cb91fde45fc7fded22c53afd16bdaef7669425e74c1670d652f57ab4d1a0200000000000000000000000000000000059946d0b0e64448a93ebbf67298cc7340e85f95773ba4d425385eeb02834f9b456b648de22de9fb8da58d28ee73722a000000000000000000000000000000000ff09ac5240b3e99dbf8a39399a1868ccf7818af33f09c56a50387896ede2b7de959c63ab28e3a6f36da389938e585631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001275616a06d4315888a1bb987459c0f5419063d31ec1c45393fcd31380fc80d4b5932dc9f33b2b5ff3a04e78347fee0f0000000000000000000000000000000012fb1b304e77ba40d324935969bd8f8e294d8665e6cd73469a2d9cab7889cce98e812878baa1b4bead0e41c141e09ebf000000000000000000000000000000001838016e18d55180da13aef58e5e8b90a4f9a2e2ded1f78905b704a29fafb5c1ba236ee6e2d760bf936cf07448e3a2b8000000000000000000000000000000001542d204d553a6ca455f5e15484e58bafe5258710a7a005ff165b1b475d5a11c82bb9478a89466a65fbfe705c9e619b41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000021b2234c619bb27f62e480d4fced211584f115d6cc5dafaf6e8910c8e8a79035dba5fea01ce7a45413c99513c9682e60000000000000000000000000000000000d8989378e1657b66baca43d8cd93e54306d51cfde5a6de93ed506b6b9bb1258e8dd407f1ed9a9fe85d62da2b88533e00000000000000000000000000000000092b4133ccee71b20f7fe2b2de6c001ed2aad927298c0a4c6a1b4125a5db823eae137f8aa5cd854f222fdc8d5417f114000000000000000000000000000000000a82a008f166632a685443add00edb2a1f333c491764fab59cac13dda878c2d67f42fcb4c8a0c6b5040650159930a8b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016cc69cccd75e170a4976c7294c40f99ee26a5cd92e9d4556377d00c08dee587237daed3fbdf9ae4444a4e55f4f8707700000000000000000000000000000000120b40cc8d0d370ce1f894e8276e223e98be9e604d0d23496895a615bbe6da1c1eaea53e4725f8a241278e4126b9290e0000000000000000000000000000000010e0af8399079f7eb3e3cee68be2b33256329558e19bc2870ebe6454958fb72121e3824897d6ba806a6d47598038dd44000000000000000000000000000000000b4797b811ff46f91202ec949b86ff25fa88de3ceeb3fee8a1e1e6e141ed0f1d95b1d34474d902e9fc3579546a27f7e81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003beae7593bc02d5cb0557e56e2b5c973d5a2111b3447f8d03219d9730e8771c7bc4c981117287fea626f2762fece2f60000000000000000000000000000000002b835c09327bfcc970995392dc026f5b34cecaa02a5d9b352ab216c9576f623db15d6d231970da3cd9a1b9c79ccd08a000000000000000000000000000000000ffa66e9703bc4cd31b2255ab05d3f153193634602205d459c81683f4d28bc4594cc462a00379dd490f11c303b0e97a1000000000000000000000000000000000fe651094f4131410ccf9c4dea2c8da727ad9aa16fc1bff55547414a98ba99f532ff92571afd8e7cb4345ae031000bca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ac06a0bfc3c89a103d077e18298a15393a9ac7d06dbc054ece5c2582b9322d6048fd6a11cf8dee6b492bc6e7cac010c000000000000000000000000000000000bed51ad1f2a3efaf8f35f9b5445201987861e77d44513a4ba61c741d4f4f262ac308b5089097817c56c3b697496c52f0000000000000000000000000000000014a0d55188fea736487f7bf71dce35a7ec1dc0bf2363de6643775db68cf8401ae656823ee10a888c09233253fc4727d4000000000000000000000000000000000dd97cdbdf8906b2eb44f50ba0d8d684ab56754cf7d856dc23e4dd2f0e791b32e00268c3049f2a574558c452a01ed3c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000040eb1732f2f122f799a46188d72a8e7bb0a17c93cddf792c99f0db5ec707b46a5edafe54a9893d9f188350b7abc1d7b0000000000000000000000000000000002e86ea84379337869a671751a5c6a860a27f5a8418e5c401933acc151fb4a6208b8f7cf446ae7bd5d30c29c6868bdbd0000000000000000000000000000000005acde871aeaa00c7e7ca769b6ae095cb47177346e024fd2ac7e62ea0e44567242eb68e3bda423df33c3584fd59ae1f400000000000000000000000000000000137ae35eebeca7b534111feb1865343b468cc75c521b8bf12b841455bdb6711f9608112452623f5856d7ac1342724d201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000efa285efd6a028ea9859c7859e4d8d9b873f6d9638e226a4bbc7b77b5c282287182fb24228af36ea497436acdc71a68000000000000000000000000000000000f78674aafd1fbba816e496a3d2bf543069469fbd8f68e79d1aaad766ebe5150bcaef62a008e1dcdd02637c0905de30b0000000000000000000000000000000017c65210c093405cbfae8b839118c874d7a817fa029d3d7f7bed069db01511780224cfc5bc036a6c73794cb2d364d0fa00000000000000000000000000000000109ddd0f6f42d96abd9d21bccfdc3ae626c95d5dda347da3a0675f68b59cd0bdd7263a571a14ff8658eb60a07800ab721824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a468461b04dd30a46758b497b87b3783f0970f258983107bbf76df37e274320e3bbfdb057485d367f7c1085b77d0755000000000000000000000000000000000f0bb22983c5edb6340b34409eab0a119ab730ec3af217c7812fa42f2392228a53d43d266f308d52c1354a9671510c640000000000000000000000000000000014abd8da46e68284d66e65760b531f73266e3036081c456226a8142f0ccd8cf7f2e53924bb596e7e8f9813e0d79f4caa0000000000000000000000000000000010e6ed2a8c023d292998adc162edb02e763f101d4938303fe6460a8cf1e5f3d91288f1ee7745580668a023be8fb0c7841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001771f86eee35691905b3c77b6c49827e260cd5ab39ddb6b16e16cfede00f050a99895b50fbd47c3d5e5ea7408902a5760000000000000000000000000000000010941ab2cb78691c8bca685bf4618dc3b07c68e937f6fc51d693c5bf0c2c49d19d3800332679fe6db6383e75884ac5b8000000000000000000000000000000001216abd3ceb3debb91a4293e67d46a087520f2db4e74929e44b00d5e74dc946f1bc86b8eedafb9c57f8531a18231ab5c0000000000000000000000000000000006d30188b4fbfc168806aab5eaa348f3c6aca17f40932d05b517b26550f7cc53d09021df44ab7f7ed01c1c48ecd5c6e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000028ed057e2c1452a4e8d68bbbea39bee340ff617acb45d2a202a6bf49c55a455ee7932b63168512a0276587ce410a1120000000000000000000000000000000000e93f238e5375538208aafb42c7555f5d271d6ad62f0c4132dbad3531a33d40a9f663e5c365b687fef143c9aa2bf9e6000000000000000000000000000000000bae3df4a6652b898059fec2716f8b9a968c007baa9cd93a94573d7c8c38ea92059f489bab29cb694bf53be9bbc49b6600000000000000000000000000000000063bc330c9a01a770ded61be9cc38d5fd614e5f5075f2325cc6a7ea816e5fcb379fae2a7e5b6cb6b99277274730ae1d81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000f6d816e2086a9c04d415ff83fae52ee2693185596f11b9a625cac512a8cc6a262fe121e0300f707d7f7b2c4ce70258000000000000000000000000000000000559e7ad3de60b5c864f618d5a116a3cf179d4ccc5cce84abf41fc2c7f914b309a3f38cfe4567b99e0b3d766b9b3203f0000000000000000000000000000000000637feb00603156cef80402a44d127e10307ab8705ec283f942bd5525f6bcef890eabb376f644664f7512e0a10e2a9d000000000000000000000000000000000af575d2d87eeae3447630c6972e0a361f7d0584ce67deee0d86d52f1db2870b92bedb2389535bbe93019a21e4dbb82d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d7bbe51498b5d3cddd5d15e4b4743e2e87349f1f6d42e757a929fbae25c11fe027ea68756cb073130152edfbbc99c3a00000000000000000000000000000000071e26257841318822a1c5227e5427b780f6dea649cb4670d410403b1a923291094f3bc7cee658f8e467d9fc994e74790000000000000000000000000000000001f5f87abfb00f0d0114310f15359b99141cdcd3e42a69d0f0e59fe70ef191ab54667f1b7a8249e75dae47096f8b7781000000000000000000000000000000000085adb61c88ae489dda0b4936b29118bf9a8c7610d1ab239c75c4c98a69ead8fd0fca2fb51b0a779d4fc83e2a6dac191824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019122c98fd1b0004c280177eaa2c6a658ddf81bad31db4c1dc7b36eb62bb066009c4266b6a4365c76243a25623b3617300000000000000000000000000000000133cfe42bd773888dd4e6b7729266d7fc060acad5cda2abd65f31dbcfaeff72b3fcb2132174aad467c77b5377ca890740000000000000000000000000000000013e75ad2ac9d4107a8ceacddfaf6ec3275b1a6c39c3b8baad9f9c6f5d1aef2513dc2fe7e21df44c3d9ad5ed2b128891c0000000000000000000000000000000000adf6a14bd108bfd4908531e6ca0e738a3596c080041a7143d0746cd7fa018443f24c6f265ac7eeb3adbfd5d3ee0c981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013fb29e7e495cff757afe9f9cb6d13d3631140de6a75b4c9aba42b9cfba4b2b8a8ae85a19a3113cd6123f5fe855fce5e000000000000000000000000000000000188596b9988acaf27ab8e45a63d8211893e4d88a9c9caaaba6cb37d48778cae5b770c0cb8f574c1b4a9f4930ab467e70000000000000000000000000000000006bbb521062980c2fecda6211e1b40da39b4fd5d7bbdd4a7794e1c9e09bfe0339fca0adaf1113b0b5b06b46842283b800000000000000000000000000000000000273498da932faf53410dbd2bef983e69161d417fc02c527fa75c44e1abfe7ecedcbb6143e9213c4576d694c66e429d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013cf42fbe9ef85b47f0b7974945484e911e63596441731da09750a5f3483fbbdcb6e344f3e78615d7ed5484f3e33d5170000000000000000000000000000000004a4f03c4e9288530f148cfba12b8e646a45ac36e06beecfc27ce8b63674dacff9a9a1d4deb0c8624f440c5de28a71cb00000000000000000000000000000000071aa999afe3a0cfe48fde579e7ccb987f6a5577d0f4e63e91a2bd24b41d3831a5835ec0e2ec143da6502b98641b808d0000000000000000000000000000000007d7c553a045e42c6d8491fdaf838fc6ab4d0818faef3e5babe57b38503b9dfa67543e99d5a53c2800cc91e248a130c91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000d3182d845e0bba57863799f41861c92e11f0a6fe90fa57c210b35d5d520232a1ee098e4b68bcb5e3fb52872c261a78000000000000000000000000000000000a2db4d1ee3ccac7f3178f4a1cc4ce694a43449aa5f1d6a87e14ae3080301574407128ee385e3f8d4f9d922cf9a7a5db000000000000000000000000000000000fe4b2348cb7364c4565f5d7dc4d080aee93b5f9f2144d81aff6925ea5a2f5c66fe77202df692f32c0be9711951ffb0a0000000000000000000000000000000019db314b62e2b68b70b7563bf5ec4a329d352486c64d28218b5f9886963a9c523a0ce3b4baa2e88b8bfe29d9a656684c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b3f70ac266626f2af4fc93e3db2b657d5b627f5d344320dfbfbe3f28a05176c5feb937a7e64fc447f799941b43cf3da000000000000000000000000000000001537583addd88d1c876b00a4f5f707cc272fb3d2bde72b244b061c1a4d689351af7d078606fc752680ac667424412ac9000000000000000000000000000000000a95097e5ae9cecd211349e1b478450756524a1a5e9e02681fbed713c6a2505cb789dbeadda38d692468200dd4039d6a0000000000000000000000000000000014c63db461ed28f80794648f302138dd5ca3db7e6d24e83f0e14b27a077afe9e5ddc6effc694091605f7aa128db93a3c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007c2cab9fde3bdaf9948cd8c9b374cfb627dffefdcfd52fd1df219eada149e7dd9ae2a287a095a519aac1b88fe1ac02a000000000000000000000000000000000a875a456f6c5a2985fc904e56cfdec30f7819fc0a65c863c033d8985aa41b2b74ebac6db2b7c0a59bcbf6f6be1c63820000000000000000000000000000000002dbf1ab764de8aeaa66bdf87b14c1339139346912b735065c8feb810565a9e5894cc5b546aed233671bbe81023d087600000000000000000000000000000000039d228aae06367d612418e3c092d1fdc261956902b6045d3eda215b8acecc96bdb20a5982e672fdc56291fa892601041824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013d9df9a45916d0e7eb0ad9d05e70c794259a686b84d4a9c0707e63d84a2a0cc6b4a69dbe8c63db70a3f844d88fb77f70000000000000000000000000000000000f4bf88fbdb4273783dc53295dba5eac21546c4d582ea563d888fab98965d06ddefb3e1c0163ec33112c17d50a305890000000000000000000000000000000016b14a3cbb66c7ef1c9278972566e5325169bc0171ab4991de7bcdaca63a6416cb0bb7c8b19a764b7ba3f7859439a9c4000000000000000000000000000000000a7bf2c21afa974fd6ed1378a9e4e9a56f1d97f6f24c0550beececa432e7565641cc7af4286c5d3c118d2700e48ccc141824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002663656334d2e29608aa58aa80efce637af86551f55ce3408c6ca1477aa77f64bcfd1b6234916c2a0c2d38d95562fed0000000000000000000000000000000010598728d572aefe58558945aef6ff7948ed424ad2037cff6796bbfaa2d49078d61ed03dd4795b4b6a074fdd6ef7961d00000000000000000000000000000000060f14cc937b8a5acb514c181e64355aad6d70a314b4dfee6b10d327499e31bc331411fbb8a1e11d22ae5bc7b45c56db0000000000000000000000000000000014e148b8d179b63ec8dd1d382ffeb59a699211429f1735ecba9f1d18780f284e0e079e6afe0d1f449031ed3f3ca57f271824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005bcf6a46489f8b0287f31011ec48a12ed66bcdea7be8850f2138a8a4909fc3dcb2bf1598a7be40dc956ec1c6d30726a000000000000000000000000000000000af6f48196e6fb42209ee24bec47389c224c1dc1c87650549470397aa65a20224ebeabd1420171ab4008722b1dfe1c440000000000000000000000000000000016a95b38cec3244d6bf2d86a3fc2d19e5b6d26656625829d2407c6863a26d3a887f10d768384ee44356343cdd6433a2800000000000000000000000000000000038782043207ab8d39639aa267735da9400649acf4fc3cab4a507da1af5e1fe09b76f39a6b133139d6fae346551f61331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001927daac24920e2a9208b9fc7a87533e27681c12c1155d7ace0d78114d522cf8b3e59d991e1f721ad9eadfb13069a43e000000000000000000000000000000000a1965f8c800c6e32e4bedf295c0ac9f914f7e17eb30d3eb908bffdebade6975673617425104db8ae6037d39db54d9a90000000000000000000000000000000001353bb21e4e3518b08349ab35d1dd22c8695c19f442745be6cff44c04cd94059513954012caface5539cc20876d11120000000000000000000000000000000001537d259a51476dfbc80ac0bf0235b21f3fb3ea62a1b737f5ffe8b3c77c22ea06158213dfc309595da0627c6d5720aa1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001fa9bf9b7e624d6b2cfe450bc2a1253e549ce40ce3f8ac7aef6a1a3a3d840d7f0e4a2ed34eafbd25c96b4cafd4f5c040000000000000000000000000000000000a45b09f2be6df22f20a454035a0ddb6b2a9302897b9c7761d0549a0917fa57cd298b60af8f55c0c5cf7e20ff4451f5000000000000000000000000000000001929e10d060820af285d4b799f959617907a649f326cf9d37d3e78a3c3c29fa718912ca9704aba511eacd6f2bf3dc2690000000000000000000000000000000008e017cdb8f4a4ce90464999d9f7b965a1d81cfc6e99258392bf3c6ab351cd9c44ca5aed99b120ad4a12ca4f39e6ed7a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb53b30757e8c7eb901bd27444ef6231431c8d14087574b000cfaeaee9cf711454cda3964bd96b2e7daf04b4b151d800000000000000000000000000000000004f3fb8e3497361d5b4eaa113df7be3820bd75bcda08659612c9223998070d8ce740d040f0e955d172c88b64f424f9500000000000000000000000000000000018eddd36730558f29080e826f081770ac9673085e3458fe2be02d0c0276a9d930c9f005900f2e9c007e56d326fdcd68500000000000000000000000000000000145f47fca33f1e6accd255be7a2b7ecbaed811e6fe68870de808a37ac1f3723bf79387edac8f6cbdc1db29513e8b2bdf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018ea1e9af08df6b37bf2bb257652b7c5de1512d5cfeb8706776d4810e9267c22b8f30ea53bb8b6ffbbf1f57e1d74f45c000000000000000000000000000000001074b6a8f13c29c7d4db7e304756f1f028adbc7cac61d96de2fe24f14207ad581a8abbb3428dd2406b8f12c21f10022400000000000000000000000000000000012e0f514a3d56f07ec8bbbf9a97d1978020fbea1bc4585334460b38dd9f29ab995ee1c24e17721c3a483778eaf070c400000000000000000000000000000000183430201f6154bc626b5bc3153768d3505a76706059d530c0e6468d7d09ceead3a61b8e69f6a625f6f2c2ed2cb7592c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e208f7b22018fea3d6353653edd6e274e51e820419a9d504a98d0ba386140e9c597921725fb2ca52bdc5f18a63d74bc00000000000000000000000000000000043bf3bfba7b951932dea932d79776a8ca3df9a00d7456976c76fa6ce613e404e9df958d784a7e3472c1b59624744c8b0000000000000000000000000000000017b574cc6d5dc483528c7e5d5b60f47d3c7447f5ff1b79b98c9a53b02c60213d890f2ef109899a28a37ad8180dab1b5200000000000000000000000000000000091659c6bf098733e8b451ad25d80326db8bf7f25a0e3faeaa88b7c749ec89e3c700378abd761dcab9396f1e7e71cabe1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ec7c584293e71c57cb09f23190e05219d847bfd95867832d4c8ea616ccee129227fe1e1dddcf5fdc753dac736836bc50000000000000000000000000000000007d75110d8d6f1f8170cc4204191183a9760eb532c92b34cb17226632585ff8732d2be3302dff775edc5914fc9d8607100000000000000000000000000000000167ed8a5ba23e0cefa09830d2ee533923da9d773ff724e4c6cb22aaed6f76dddac3d1c5da8ac562e66363277665d9f2e00000000000000000000000000000000128933190d15c3d33e3069b790d3efb3bd53d0ace163b82cfb1d33789273af6eda14165d58d8b108240bfcb0449dc3fd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001213e44cef05953f75df29b8c9a02617d8a662f6f5153b0838506c295a2e234491997acfa7c7f9cc5ec5e5275a7988490000000000000000000000000000000001ceef3a5dae59f2c5c575417418e4c23e94fd830b3acdc7feeab64cf2514a3e4acd610630ec2c9cbb42b67103a8a2f40000000000000000000000000000000012ba442af36566ded0a4f8df5b9da71769c4aae408c064c427f956469813d1199182dea2b2d52c95373f706784d00749000000000000000000000000000000001991105e87558ec8de90e70451e9b11e675a29efb3ca9839df5ea7db9ffc5a648f3f2959003423bf4c5beb00a045c1ab1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010b3aab5ba6a9ebba028735229e95da5296605c9bddb262050edc50a9924d5d3f41778e50c4e2508c62e9ceba6664dc3000000000000000000000000000000000c5c6c298824358d46f27bab06e1743a5a2ad84e2cf7635f71987fce5c54e8e11d826dc5a04d8a429303d84c0974635a000000000000000000000000000000001603436735afc3bd443dce435c436f1c5e6af47ee49142b668f419552acad8ebf85ea07b32d4c9658e65aa4814b3d9b90000000000000000000000000000000014c5493d1b23df125028e41f6d3bd9fbf633ec81592d9d1d3c77f5dd798bf5f47d701953deaabb46beedb6e3dbdd645e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000207e7bb5ec1e7dadfd583fa6bd777dd7e640caea587572fae42c3ebe5dfa0e0b878d757e70d62c1ef3d41f202c3c2ee000000000000000000000000000000001344915329ac8134f3aed7804be9bf47d77626c6f3a046e92cc38f994b945d18cbbf41697dbeb5aceb7659ea3ed7ff5100000000000000000000000000000000185d4dd392e3a1b1b389683541c55843189832d2179279f4adc09a02575528491e485ce0c67d25db894f83af1b32da96000000000000000000000000000000001740929ad15676b7cd72a41ca786c65160bfd5d51aa9e41c08cd6a8fbce0babd6d7041923e5fba1aff1f421391cef04c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000146ca59a1b0df35244c8c2b89eaee64977895bc41cfc888f03a6bc350c902924ee5a2ebbe98af0d7244294b66394ee6b00000000000000000000000000000000104f9cea6279617e236f25c3cd024fd9cb772cfed74b6a6aa3fae0560955b1e786bcf82d028bf158899386e1561f57200000000000000000000000000000000016e342276a72fa4d2c92bbddfc5cd9157d173b85cd998b65921949a1cea224312a6eb797d266943fc53812fc1beeff9f0000000000000000000000000000000007ebb7ffc650291a0c5a5693dffdee5bc847e18d12d9979abbba0625739953520111923c711dd62cf5c011d2f43f84a51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018691be4655e3904a63d777dd7c77fd31af6f060ef68f72f3c7d151f5bf146ca08b8f0db6979808c0faaaade3bc4215f000000000000000000000000000000000ebdded275e66d5bd8c1dd81c228b1141ab26c2bf4d9a79ac3d952b98528c8a7332eb13f63f858b3a036e5f5439541a7000000000000000000000000000000000389ee6840d1e6d749ecf5d95bd3fde2ced323260d6a80577f53ade8231e2862a34c8010721f9f2c3d7d929c2ccf34670000000000000000000000000000000010173a5bd55bc401a0a1e3d3771c71cf0fc0ce2d0ccfcfd4a07e8ee28ea0672e0e215980e02525eb6cd19279ad5ea54c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014b85eca3b187274008a101ee3566f7ff2cb5d3d0d1570641556fa0b41975e98446ca3a8a7e645d6066340cf6ce4d046000000000000000000000000000000000994935e97b2fdec7cdb02c624da3b3967363e248cfb1bcce3c78d66be3a6a5500afcb6902d4ecb53985e736b62a2dab00000000000000000000000000000000007474204dca97c20b33217cdb8e722d8edcc141aeb4b51f483dd38e4a87b4fc18a5468b536f043476045f82c50e291a00000000000000000000000000000000165b02c0640369897acac7c01555c0b53231b12cb804201ab1ead31035514050b8e72f23a23db3b13c817451da08e6c61824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003836ca3dcdca55164df53c624232f85711579bc9191a6ccc9637ab8fbedc0fbf7e4efdf71a99ea6ba84a6f0d7e9e0290000000000000000000000000000000013d5c830e29de1bf70a78a115ced284ea30e63c4b45e8f7c2e22ae39b8530db5d9b79b6456cf5664b55449c05f82cb850000000000000000000000000000000009dde75b93f423c9e2dd9094194346cd5af81b69c94381ebdb53a69c92ea5cca9910e7d5216b27de6c33028e536412d80000000000000000000000000000000003600e9cddd22fbbf592f0f8af8345558871736c7eb55240e1a9e5c9946911ada4174746e9fe933d5084bfbe285eb5741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000003157427b57a3d8939225e4d9bde6f0b588fc5e617ce70cf44e70dabc8aa48572ceed5898dcf4b755ef5bc7ca1ac19eb0000000000000000000000000000000000f641ffe91f3b74fee1b3a6a78cc5dd513f9bf3418baebc2d22f6e50b8b9038eb320a167bb0c39de6e03433ab3338020000000000000000000000000000000010f3cf0b2b024a575e007f9386b3bac5b0cb67ecb7dcf46cd792b7651d62c989d6c8a8f337663874e1927948a09bf8f60000000000000000000000000000000014e07a0fcfb7ede380c31c662ac9c8b0b0cdc8327b974ba2fb82b09a38b553dc0128f042b41678b07b8ee1378c0e31161824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001169f293b66d53a751e5076e1db96d0787d04af6ca872ae7cea0ecc002a9890a85b01f06a609d46d474b3413a17e4099000000000000000000000000000000000962a5b0e45a93e6e97ec3258bff8724b6bcc024746bddc4eca6963602203f9e8fe5ecf577e292fe67910bc9b21519eb000000000000000000000000000000000ce1ea1a7d995302136a9a3f60f64342ea69c7976ddde65ae603b9bdcc69e4f1df317aa863d14f435824b2da239ec0dc000000000000000000000000000000000bff09658b8512bbcfc77047220a63d9035357f907f7d73e0d27bb70f6ee423e086bbf8d44f16a1e198284065b8353c01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000012ab9938aec52913a167ab4a6aa660178a73aebf72f526a948a31102b425f7bb41212e8d4a87763ac8454a30fbeaf9b00000000000000000000000000000000012407d23128590e274bb206c929dc457c5cf99d26aa8fb5424fe17b7fa23a199ad98346ce7de1148efb4506bb266f860000000000000000000000000000000003477491b9b4512dc642cbc1d1a6b1ad3bad3156e387fa844ba9df9766d3a062ac38100f8099094474c4cd3b2e31af3a0000000000000000000000000000000014c1f3966da30cb1597277af41653ffa0283e8c9709ee5319780ad5e98f4627fd01712945102fc460bcc3759f76ae2b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ce255d82ce850d116392702319478f701caff434ed6018504937815b0deb6884ca99a7845ef61ad9ec40f193f31fc72000000000000000000000000000000000c2f2bb0cbda8d1100f39e79f0f38fada2378bd5578285d5c35fe919f1c7cb114870d19d33695b25418bfae21a09e97100000000000000000000000000000000067e677ef5b8240074a5d356317afeb05ea0cf5d254264238455d9b98668fb7d5961e778df5e8be00b62ed352c6c9e7a000000000000000000000000000000000953f22e389c0a87d7d655508482d42a9c293bf3f3fe40bd0cdfbb21c0a34754e0f0c6bb66f9c5da6ed54483646adbb81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a1640339125bcb4eb91cde756347876cd74600d3ce825194f0b15b8d788e37304b0ab0c50efcea45f695225016f6237000000000000000000000000000000001642a08c000d113f45220777b5cb12501027e8a741d30725a7e61eaf1987d47c30c6bec3aecd094b1ca1e7841316e56f00000000000000000000000000000000102dbe78566e47b4c35f67d2ad04bcdf5622992f08092b27efe17ae5bd885503a205ad5ea3dadfd1cc3f1f2b4b17bf5a000000000000000000000000000000001533a6f9d99c4bec0fdc154dae9e3f5822421ca7dc3676995193ce5f9f89e72d1d27a86e3b9029b348a24d8f340ab9551824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008d7ee6960afcf9d04ff786e666cd869d766d609ed2ff1bd95281e9d731a00d535891cf69786e01e262382f929cd26de00000000000000000000000000000000164599e6263f8908b97becfe105f5864a51704feb01f36f51714c9a834f56042710ef62b0ac7660b3908af410e099f1a000000000000000000000000000000000ee2705c8c7515dc659bafaa07b54c022680769752c2108f4d8ff37888909abd77ecd86cf91329df0a6da4318ab191dd000000000000000000000000000000000e754081405b5e60111a14cb97a7f9831d48984f9740ee482c08d309ef4f00764e9a108d329e0f26f300c306e4514c181824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000eb897ccd128d4ce233afbdcbeda15762cf6fb69ffa509f023d7b8b31865eaef79c38a80a4241168041442a69f9b402000000000000000000000000000000000172694f4a075a69f96eed7c2ad8e7cc133932b725be829d13fef1806b4efaaf2cd34dd201b952d575deddc043d19f84a000000000000000000000000000000000c339d111818e87df3c3bd7dfe935b7d65a77cad6862dc8766437219e45fac306584f8b4a5feca46c54cce17aeff88ec0000000000000000000000000000000019d71963edb7aeff6e7f0b071763cd27ed31399997f865d6e0bfc40e8e7c22491c97cfb428673f0da241aef4f0393b6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000906c00418c225184ff9e2c19d49d74a2246bbba3699badb4c65f8d08bec65a27d4ba1d64240143a1a8fbf260f0fa05f0000000000000000000000000000000011d66f22ce3acd52e43293ae777b03fbd8d557cef0107ad7b3d571fd77f22d887b4d5c36ab09b0ba2e4c3931427fe5a10000000000000000000000000000000000e2df417a8fc4da840da572a314a46e5b45040d32df1542d466a362eb381ad8929d4eaab2fac95bd73b6c7dbe937a380000000000000000000000000000000003d0232a689dbbdfb3b244c886ffa25fac07e993dbe4058b90fbe5aab220b5c80f3d4e52beb1d28d93f8f06c1110a2301824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000365b01425aeda60b4862c75a7d75134543b4e05802c54dfe879381fc6d3363809ab1694e108f27cc658a14136880f570000000000000000000000000000000003c26a9350007404cde07a933176b6e2f6d8bbd81dcadbbe78fc3e1755b61c653258ca27e44fa5328d94893f0205ff670000000000000000000000000000000001b9d0629df9e893eafbc7dcd6626ecce949ba7a660bf2fda2b631f260ab983daa5efbdfd752e80b79578366f88a6a090000000000000000000000000000000012bf88495d371754d40f11e43d0911cfc5c09c6b7cd35b3a33b77777589b32873ad9aba3db8a65272cf753e87e40d72e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001044694288f61226320d910326427620d00c74bde63bfd48440099c5169667a139365b0d21f1944b9840f2b7379a4439000000000000000000000000000000000af35f28dd4db796209b67bbfb437ad0247703c1c16a4e0e61c14b167790137d4617ae0c0fda7593964acbf327305e790000000000000000000000000000000004a276b412f247821e6c78520edc15850aef049ff50cbfa47580c401b83130cea24f54e9d666aad3a3539e48aef7b3da000000000000000000000000000000000a5244c83e3dfb164fb5bf75009c4e024891944e2fb43110d7a4d1c00d808bfb9a751d1a4418b68456d02a43652cd4591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e5cb14edfb45378af4d377c102a75fb31b66f98663f16f0b5825660f4da60aad2559c4532d0914634183d8ea711913c00000000000000000000000000000000005655dc62c085ce8ef4f1a26cc6c2e675b0556d3e16c067de805c8166cc291c95773dfe2abba7864c9883b6ac36e2160000000000000000000000000000000005c64df7724557b6d4c78e6895944b55e769aec01c45611b1013f0653a739a72ebfc550a843cf388bcb388f09b4f77bc000000000000000000000000000000000bed9bda1aab999f3886fbc83184e0c7b4d393aad27e97a6b4f746871c21e4f18b5afe3aeb7a59e1d227744570091c2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000cde4067f09dd264460c862ca6951ccb6d6426471d4eaff297a4073c238a6faf02af758b8fd508d13cb96fd9709a937b0000000000000000000000000000000011f5e85a3d81fe7cf5780994bc5077d3359531a5d59390107bf02ec82ed5a599e200da6a28b0753f3dc47df3632185bb00000000000000000000000000000000009e5b8e5349754616b6cb34b31d3e1942f799beb137892c437b0c7f8be09daaa7448c26bb10ed432d3bce9c1878f90c00000000000000000000000000000000032c24fd4f6c4061335ecc468350f236f03dfa5cfffa3490065efdbca3669c98a3b92b938fa8749e474e01a8f030e4ae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b6b1d8a29050568fea5da7988174c2c62a055d99077fb3f891ae7a983241f7e9200d88672e329aca40782debd2f653a0000000000000000000000000000000005b565ca99fb98f322ff0e38dfc0854615b83065488ace0556059c02e278daf4d525ac16d5e03e6b9ebb6a46321099380000000000000000000000000000000019573fe4511d38edb85c53b0d13ba927ffb79f36239e1de9f6e2cfe162945c7802e800156b4538e353ff7d12256fe2fc000000000000000000000000000000001833895cdcbeece53b87813791c372aea281636f9513e95be98eadad003227e6ea28deb41dc7682ab751942cd961a9a71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002d226368c872b1efd2098b31b7a8b59ba0c7f28fa9759b0acc41fd1a5817714a240c444b2d28865dc98a93bc756ec07000000000000000000000000000000000e7c50673720b873d856e62e4bac71bfce8ca7da762e9698ebebc80f7d54d4f23d7eef148de34ceaecf61b187de7a26b0000000000000000000000000000000018da00c32b1549c028f308e48c26ab47f2cd4a83dac7cd0d2d929f97c721a9708af5bcc6051a357b484d881ecafccc130000000000000000000000000000000004cf897aaec32280235bfc64bca69f7d31849185227d28a2e3cd6e7672223489373edf082589ebdfd2bc2e5ee0c858ea1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000019a9e0696f9ded3be996d5d39add737fc4f07479dbf26444f5b0d74e1a1f1c0a3c249760c46de5a726b93e8a11181f7b0000000000000000000000000000000014df3a0ddf2486f36bb64ffc1db1565cf9d4fb91c74ff3b71be6b017e66620aa2a8a797225da1f8bb7e4c171bec6a69b000000000000000000000000000000001884f21c35e06834dc8607fda3ea84bc2862a22159e608b3e8510c8476efdfe9bde53f210a70327cb151abba9c3ee358000000000000000000000000000000000a3ba7235418478b2ef35b6360707538f1488d2baac6a66b53d52c70b46f1a8d071dd2c2718c520f9ddc73ce6ea3adca1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005f4b4e720a9b8afef57b1874a856b38505040c00de74effca5dce7684bf74a8f5ed32a6f20d7adb7f7dc7ea9ebf71cf000000000000000000000000000000001153633c94b822c13c2195d1c4378acaaf65dcbf0c92254b50ba59097ed05ec41ea3338f7d227c62ad9166e35e86302b000000000000000000000000000000000290837b545e5a05e9bcad16092c161c4b922936a2ddd4efda5b2120d8b382921f05ddc8034d997d4b1234f1da292ef600000000000000000000000000000000173d27b8a441272c97369713ef00e1e753584952c25be71e6cfda910b9377ac7cc647448e8291de2911b5f057d0f72d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008a5533408466ec1dee4d6531266b7012c54ff39cb9d8a35e3d3e8c7ece654c6b29d1074654a21169e5a67d6050fee1800000000000000000000000000000000064b8de7b7ea2e5615c2f8971669bd3fa0283734633c6630c4595f614276a9123b6f1b00f8bc45628b5b7a759f62d7f700000000000000000000000000000000090bb1a3782e13e472ab4ef61fc5ffdfe6a20f404fbc615338660e6fb8242281c6982cdb0852395528d32581eedcfb10000000000000000000000000000000000f12c50168db7ec8a822e5908af746798b99c4ff9a5cadb3b849d8a367ff3b2620fd0c681d0bcc907edd0a88f104b5ac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001f21e6476d659f438868194917daf491ef2b09cb619fb88db44f65bed390c83a9131583572106e90850ea020a447e1f000000000000000000000000000000000c7f0b60f4f0410a40e7daf8ac7f0073a7a7a7412fa1dba907d55aa4fc1f44ef771667fff572dd49532d0905df2105de00000000000000000000000000000000016e23357b61ea66fab4866036fbd3ae07f7a3fc943ca6d294f93e9bb81e4cfc004dae04ec6126984fad59d7529ebf49000000000000000000000000000000000e817957fb0fadfdd00add4117f7a1f2702c4419cc63d41072ffa8bf44663a766019f9e5bf5b5f12e09a5de8114867631824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000002816815337a850c6a70425d12ec3390fe91941d1adfe5f9542a521e7beff090ec7bad56fed028e7016021432ccd1c80000000000000000000000000000000012cf06186331264b8451bcb870714ecdc10bd339bc6c3f6e2f48e6a09c59f505bd2c1f6b8997043fb0bb3dd3a4902d49000000000000000000000000000000000c70e2a07de67066be51c29397a0f496ae20a583d9c09f0d7090572cf6dbc565efa9b9cc0eee942c54ba0b9e02d5811e0000000000000000000000000000000017ffc76c6b38bb859b7fa6f84128e5625b00b4e39a87452edfdac73d0364cfbe5d8e58665d0f05686ae5eeb72f07f7d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b97a5cfdd2774b97fa71e22844dbd689d5c5dcc15afd85723b8f79d8a7fb3ad67d3ef0900afdd6cc54b3874e179632c000000000000000000000000000000000019b76d73e3ed60c2f718fe083f9e0a06f5d7d2484bda1008e143d350f8a913efca3a49fd62fb1862c71fb8335cb3cf0000000000000000000000000000000015590957f25caf26147396846514fb3948a168a72868d7bb93541a0863eec33d18635dfc630a459cde30f2786aa446c40000000000000000000000000000000008a19ed73912b02649e42778622d00f95b422c83dbc94b047bc9a9ea6e9a06b892c69fcf0848b7c585ecdaa36bc923841824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000104d483b82b2211d2924d8e59e54f0f33050d1380a2094d6be75f1f0bff4aa30998c9344b55c573ee7fdaf2d56e7106b000000000000000000000000000000000c743bdf0a67d1414b976ed9109892cc29509e92e87f285b204291c28ce384dc739d773b00a8b61d31e33f31eeca5d4e0000000000000000000000000000000001e3cbb7251dcd9e9eb0fb812f628f03f4cc4626d1b5c1e078fd02677a6509e60226cdabfd57025467706db6d62467140000000000000000000000000000000002d271102c8d3a60d71e1464e5f1edf93fd08a103727c2a358447383cbdc8beaa38c85ef3d0f8474a6edc852d8b754261824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000007a56584f6bbcdbb4c0fd7d04f731d7198392273db59427e4f4002ef453205b56b909785a20407173910fa2a49fd7c0200000000000000000000000000000000173f5f4c45358f3fee629b9c0dc12418b2652603026f91030558fff1c1635ee8214c831032acd249d7b5b9f92d1f26a3000000000000000000000000000000000bffa7fb4ab1ebda1701e000c9507a3519000f432d2ce3a731f9acc3670f61af22e5bc1cce07be824564de6e5ffcda4b0000000000000000000000000000000012fc9a52b0fc78c505abb56db1a74ceda46bc8f4ac20a80ac90b93ea94a593233559d4489eb156360869258d1238224b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004fde13120f9c0a7bc3f5b1aa1b291036830d770685f9f7798ec8228fec661e96a6db77b5a2638255f8954c18bf0d9a8000000000000000000000000000000000aad0fb28039b54c5799ee3c49b8425e3531d2f27fafbc1a66b7b85452d93113f95f983e3ac124e45c2978b12eb7f63b0000000000000000000000000000000014c89c9ecc4b713c409028fbdbb0fd393bd4fd4363a1b43ec43f2c658fb732cbf673d0377a7adb85f47970640855b787000000000000000000000000000000000270f8452abdc0cb63e5140b0d8570454694ce3c14bff3a0594952ae812bc17e850edf53a714a0ca39351f80f2be8e8b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000204b73d4e7b585dcf5df25e8faf02d61f92c8547f9ed0fdd71785a4ceeac79c618e76298f0fe579daa7083f45041e4600000000000000000000000000000000195fdbcd815abca1171946fe4cae5feaf7aa205d129ad8c28f0c2c349b03e497397a726910e56f0f2540397bc4a345cd0000000000000000000000000000000015f95e50aeb525fb4926b81f391a3f05fd3e462a93da3eb8ae927c15466745e64c10d1fe5ac68064478697c026a6c4c6000000000000000000000000000000001032f80ff598999f7e2afb61d77d9fadbce053efbfc254e2ffc2ebbf8279aedb668a2007a8abc3a312872ef0f612392d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d609b1880e6c72c81921c49f7935b56640d8cf0701ff823ae996ddfcee0dfacc31edbf56175bd4e2081164bfe43662e000000000000000000000000000000000105553df601273442739d5f10800990c4ff2d7ad14417337a4ad3bc455a2b3fe3b6d3a6b95f0afa3044091dab88db8c00000000000000000000000000000000048cd7dbd9f125d6664ebbb1a0e0dbe141822a5af05187bb0245361606767206d514883084700554514c64eaa51d1e2000000000000000000000000000000000000e912efc427fe8fa469951ca4b5e4d5c9f9743ee28cae53454f0cfba5fcd3e922c748d5a0aa32eca8a96e6c50ae4b71824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ef1b20c17ea580119863acac8c8d639c5d60491a5bf7edee55676b64c172cd23ce3e4b0087d0c5d460ca13fc3ab200000000000000000000000000000000000958bf34c0106b9ca8b4f98a172515196a94deef9ab569923bef89de4abd35dba845bf7694c4bca6bc3a81248dc010d60000000000000000000000000000000001e0eabebfca330bb5c6a59304dd0d3b003dc7dab5b0104ee09c17a8d79f6f2a9836049fad26c0485d947177ef5eed44000000000000000000000000000000000d9e2193c921f83fc1931a33cabad22700bb716fad5021b0c902f0c71f84645fa0aa2d50cbd1919e765fe3d1bbaf532d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001387a26e4148f81484d3ca7a1be18d0bcf02a8f9d62e277d1f1b8a30b53bc17c10205bb05de743b5a67394ab4d47fa400000000000000000000000000000000008c388d3d3f7673d0356fd2cb043d1494f75959fc39aae1126c3a1c6472425298f3fce0da5d00c7974f6a9da4f94c025000000000000000000000000000000000ea3014f8811f30e51477d3f3c92e1b500657cb5a17a87b1dd103ebb9ccf8042d378e8f4e5acc53b9d9a3fe9c045d6ae0000000000000000000000000000000016e379123eeea3a088001a9e4d196104d2904a6c66939465ace7d815314ffdc35f18d57ebc32d008d6e15f41ab55b6791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000462219e466e1a11e80e9ed687cbd07aa1044eb6b821fb450860daa6ddc27c78254e1d58fa115fe0745157e07174521f00000000000000000000000000000000144e1e18501711daa4cf3abd6221822ff9c42028d2c4f2af34fbb78b99498aa487cb32e5786f0bc2f833203e5f9bbf36000000000000000000000000000000001759941ba0cc06439693e42c7c37d011529a05348580ba8dd58fbae1189ae742cc244242c3ff07a7786ab44a5f73f041000000000000000000000000000000000fc471997e7b0ffd50562f80a5027f397a3d2c62c03260f8691125b550c1b8b59d9b29efe79bca80a098fb8bf44590741824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000014773a4bea92eff773a345e1901454971477aa1c66652d98427c5c6799c1e57aca767f5808a5487db0b867fdedb74313000000000000000000000000000000001596c205b2f73ada312d62bfd465917c9f2dcc5dc8115368630539c250ff5a817ab960d9781479dae1bf4eced86383e20000000000000000000000000000000011b30afd0b167ad733e48eef7886a18b7352a54ddee7dac85f1782cea75f05a58869f9eecb8991ceb1412a3476afd15900000000000000000000000000000000104a3ee1afcd6989b8cc3371e7ee05fce19be23566eab83575b3be9d1bacdbbceeb659e324ae937bd9a5b60d99f907441824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016ea02e5933cbf95186a6ffff469432b17588510bbe6092ca4ac7aadf9493a46a7559f9bac9265c027cc65d9e5e834500000000000000000000000000000000004cb34cd2fdb5c37b68b5db8a346336932f3ab8d34399ec3078c76f21cf4970a380e55ae0afa9597f6ff6ed51078a3800000000000000000000000000000000004ff2fb6b7708cf225512e50a3ec283d0b9be811dba7662e4338f2569add56c1d3cf71e3b063e5fecbe0a78e93a6defc000000000000000000000000000000000b5286e9db99a258c49272676c80bedcd9bc119437d0049f9412a13a0cc3c300b8a9bacf82a7632f7948383a95f7137f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ef3ee375740801712747fa3a3c2428d0fd3220fe1dd5613a614145d45ee44244a9a33d6e50f65bd8da50fb4858ad75000000000000000000000000000000001611d8bc7f50ff2e43040569ad46d58655eab601c18c15bd47fcdc390b77c3252b43436d95d0c8dcf3b9188f5c74092b000000000000000000000000000000000b76d09f4852d8500b4bfcc735c0c3ed1a6b882bd70b1abdbfba870cfbbae87339091a6fc41e904f9a7c123eeea13fdf00000000000000000000000000000000140da05fc3b661b37ea4055586f26db16afe67dcf8c21d3cbc69deb290deae889ea9fc62dc7fe25ed4965e1cd32e16c51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a6609a5ad8e8198d14f3c4f4980206588f38ea32e0107c758d30cbd680eb0b035519ee386a00e9deb2783d221baef8b0000000000000000000000000000000014405950ec3539caa74e01ade48caea3c91aba07839fdfbb45fe7b04ed02274e51ae29f54a8b72bda66c9a6aa5101a84000000000000000000000000000000000f36661c3e23c1acb28f45098b3b2602b6e2ac0f5880bf5f3140e8ee2ea49a425a7039b65003593918b83d074a32ab7200000000000000000000000000000000064c3f493725dadef50f888578d2b021eddd5b2b5667d6967e568245988ff465399cb194c0a861519ada049863feda1f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008f77f9acae4420335aadd5f6881780de8f6a0c7a87f3c8476e49b519a6644636a37598502d6ebd5815eade8ad364968000000000000000000000000000000000ee29e559126c04b325549373926ffae1efbee969da8dcbb3d82bb90e6b01170f02f4d53558fd9035ca98cf4b3c0eb880000000000000000000000000000000002127f4fef39a86365b05c56c783e0597b0621f0ee979475e6156cd40ff44578c784059beaf5db74c6b9b9a2028252330000000000000000000000000000000003aa13aa6d02d04435f4ea1b759a8813a243f0325e1ba8b1895e603de553f9f43396c50bbc11f1c73dd8b8b8929c91801824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000044794895d7275725e59c5ae48db062931e8309dc069d5632adf6fdc8712d2f28d98ef93652ef0432dfba8f5781dfdd00000000000000000000000000000000006c650d984902c0efffd0cd45aa1d87d9c8b24eabe08f21ce4b2fc3cae714512bdd21098d5ec045c8deab145e89661f900000000000000000000000000000000144f9cfde1ac3cf15698eb8c5a4c334cb45d24d81ba7e3c8fc6ab4504f515f944a9ea9db0e0fcbc713324883558a9b34000000000000000000000000000000000486f15ab7f4969e5995b633a7554534a60ea246535b332945af452713f73f1b2dafdffc96910ac496215742fdcba2711824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a9e86df2e099d35fd21d605fd8adf15a97f510e481a8aa61a8b446d98953f1b0f94084dc509305243af3b2ebce21ec00000000000000000000000000000000131d09c3f133d342548bccf841df423b77b748f5bd765140efab6257394a4a119e60593b5030ff1f7db5a38e056bd8580000000000000000000000000000000015f3e6a0378183fca3a20f583f11018adea1656ef89a6ff1ab3739d271fa4c8afc53c7a2bdcc4284c5ebceb651ae74fe00000000000000000000000000000000029fdb63b9c1e448285fa0befe229841ebca3763dee49b3155cef336f085ec010d3583414c754ca959ecb680fea859bf1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c5df1f70ea2693c8e2867c8e55a4d0844956567cfecfa4b9067feca5dcca31ddad34b0020e58f5e8c93865b6b14d4d90000000000000000000000000000000017997fb7d9554c79f2a67ce2081224976e0f7e0dfd7597c8dd8384d7e8dbcadc28a27fcd8c311d22e4e05b7e4a0d9b68000000000000000000000000000000000b12ec93de3c107f858c4c32b090a34cc3161a70f6ae8f473544b9ec5be417d3e35e9d761427947a1df669959d74e55f0000000000000000000000000000000016fe78faef9fe5db3e14e564d6b56b09eabf55685e229af36854282bba6d157b4b928da2a5761a7f4a444038ebb8be5f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d4778ca7c44ad31ab4fb26153d31ad435c54368d96bba290a76265ab70786f125962f53b7bfd7d62d4aa7d7213c45320000000000000000000000000000000015a2f7c68e2431a64ed7c6bfe34d2299828dd7e96ffa635f236bd1e5a447b1d150864a2dc7208461b373d13628bc58cd0000000000000000000000000000000010e7ce0d5d700d83b5f9d6e7e233a5cbed5df706505cfe2256abb7023c0891476bc57976a6833e1a7ee8f086043008610000000000000000000000000000000004f79afccf204d148c09eeb30049cd45db70991689ac9932eb2c527fe45e6404b6787368a0a9eb39397cf6eb1b2e91371824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015d8c87278cab864d10abac16056e279c1d6fa44f115f47b2fcb9e82fca25611a1c6ded85fc2c021d7d960ea81b366e6000000000000000000000000000000000c3ea6748a194fa6cd6b7fb5c0ad8137293524c3214331ed51d1469dcabe0e4f8ee0049e7d1f7f7109647636ec221c0b0000000000000000000000000000000010f44de525b392becbd27c1e7993af943525b233268ab423752d480098c0daa8b3361a7d3878c36a5753c57d72c3c72800000000000000000000000000000000154a47409c7b4faa667e60c22f5b01524f335182f1b2a024537bba273a4322c7bc081da3e722f9a2f0c6b536f4ba2eac1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000078a98c9107c3e149e89e8046b2a37024edd9e29d46ee5fc06e174e20aaa4ee11ffaa5ba44b56a20cb33026a45bb62d30000000000000000000000000000000006c072be91c524f34bca7bb74a18c682f731e435a35916fbebdcfddfa080b4975026dbca44981fceeafb3439ce5d2559000000000000000000000000000000000ad09ee876ec33c20bb1e191cb14091dd09d6fac15a52b00f415737caecf8fcabdcd2e15337eee86e7321b5cd27c10290000000000000000000000000000000010adcd5b1cf5a794dc9fe4b8f3f14cef4230976247cff3f6f0eca97e0b375430ab5a6c07ceb84a9685563f300948f71f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c6cd6056ff955b971f59d05f00f70fbb821fde269bff25cc4f116f8c3a9d5a524be2f194c7e50c4e695aad462e71ce80000000000000000000000000000000002e29fb207bce65d6f54ffdce6a71d2605043e7a3e3e142a72d88370f997b286a3d5825cc54796bde75fb215bb817a000000000000000000000000000000000001b98a04a09ff22546fa1f2abcf48a3f779b2e1b9b46d06e7e72e24946350841e3a1c1bd566dc29cdfe3e3f4444ed64f0000000000000000000000000000000014270a6e91dc58e236745b11f3ddeb2febcd49c75ce1de74347c137432a970dc3ac5f77a19acfbbb50512e69a721604d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000037faf1f2070326c33f5640aac8bfcffaeca6bb8704e279f2f217e6974b5df2a30a35c4ee9582c0ef39fdb0ea8d791550000000000000000000000000000000012e46f36065d4079438b20521643d455fc4a9d151c3a95d273d5e5d46296c671a7d50d34c106d545c9809a26359d87d300000000000000000000000000000000133e4c45ebce459aa2784b1dc27c8a6b4861de225bc944cd93d98b63e7976a8ba89dfd9d2e38a253c2524f43d4c6f32d0000000000000000000000000000000013b9a83d3ca8b4a16a89f54aeb9f0beeff083d30cdd2947868077752ecb0a7cc38a74c0f8416a523febd3d03ad56381d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000f1ab6f87f7291af0ae9ca604ea4dc83a1b9e56d5c515ef5662d033cded5e89a4cf30edf2dced8db27d7266a9cd162ad000000000000000000000000000000000337616207d7383231e6bc0b5926bfe7cb3ead824106656db9ffe39795ae44cb53c0dc78f9ab9ec9706228dcc2b1147800000000000000000000000000000000122dbcc7299137220d9b6228383276b2279ab325690e33e041e415cfc18b6abca3515168df1a410a13fd3fd1897b947c000000000000000000000000000000000238f5634310defab25c59e05bb39d0e620d7c74c1a2b7e882717a1968a5c9aa87a5d9b8064bf1e8998a461bd248f4f81824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000008ea368e4b9e0a3a8c30a985ecf805fc3768e5733c1c388f39c81585326c7c81086286fa67540378c6d0756d2f4cfb330000000000000000000000000000000000f2f626f68b59eaabf9d05b31abf8c8674b980cc31f7f449cfd56f02d15c575fa75601c6e6df78d06010c20efa688fe000000000000000000000000000000000681985e33cf7017bcfba59ce57a3761cce04ee68d8ed853450c07daa20c303fbb9ed704384e2cdfd23e886a030f327300000000000000000000000000000000100a062480edb3bfe23433a8de8da3136a6d66b6fe2c746806708203b0ae552cbf5be8f4b042118a898afdf1211e32971824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015cc32ea1bdfe2741059330b4de20c4a6aeb375fd602c7614535fdecc57a6902ef26fbac4650525045e3e7e0d78cc4ed0000000000000000000000000000000018c97fce161f1fc250b487979509ccdc7e63ef903d7acd6d556767cc2f0d69298f54f8505ca8ca977663f1bc641e1d37000000000000000000000000000000001032f2415560d8b51d32aa0d0de834bbdebe95b829ecc2f0dcba1235637c0502c044e5cc9dddc09d7be5709bec8bd57c0000000000000000000000000000000004fb62efd3944dfd4f1df6c732a96b185047aaba8bda6f5767edc6cd09fe188bb3fb562f1a37fee39a4d12d9e550eb2b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000942365ce762f989fff5188bc91010f952dccf4307104db492a4100e46fd139c394b17d31e805a8374c5476a93e0adc7000000000000000000000000000000000fd364c7109f3576b654f4bddec8aaa9832438b139d58081817b77a925e173729012e3f1274977ac0b33d7bd04ff11f70000000000000000000000000000000006edcd909b473d99f49a50389e7549a2222b062905f5a435271d16e93cc0970167176ed7866f1d232441ce2ce40b1d75000000000000000000000000000000000ea589e1b3d06bdbbfd681799ca49680cdc6ae1169cb7f1370cf30f238c89be862e5cd1cd1ded1f2c9e759bc2e647d6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000145aff2d1569b04e42a7e44272bbb8e605f8cdcb155491b08f52a3cf22a4b7dba8dea9dbf3f88dbe88c3b3c17b8dac9000000000000000000000000000000000a08d25da1324ec8e8759595df36a7159ec2547ca18a5e430f6dc1104b44f351ab7f82e79d10e98e2a9ceccc007cd31e0000000000000000000000000000000019a6ee88832e0395c3c637512a00da0f0d4534fe60a1ea703dfd218fd9ba14e3d1bec2b04177df7afa62e2569f461c35000000000000000000000000000000000ac9773a528f704c156004ba3cb9770a1de86c44cd42e346bdd274a65a837de3a67c9450f01e28be1770b8a3b81530231824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016c5ad4977e509669a1baa2cfbdbdb0592edf7577f90bcf24e0f7011f424e9b2f219341f003082cbe1cab7c2e5c7fc5c00000000000000000000000000000000190c641daafb9c6e925341cbbe3e9e89576786e79960059d6ff2ce9d08e91737cdeb84874e83aa2fbf95eaeffc67337100000000000000000000000000000000159a56b80f0b584658076c1425febbfc03390bc8d97220425decc135a51f93f9c98e207d29d76bf120e7c871ac30f4dc0000000000000000000000000000000017a5a0b7a8b4e719a7cb0eaefe95ac9f7c72955f9ffe7e24131a6d633e087cf8c55c8b6a1fe2a6b23796d1e9361ee6591824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012bd89fd90118d60ea4bf4df35902ea8f930a39e787b01ba0a60b3f40591e52db36b4735cb5c694887e1f2020ade4dfb000000000000000000000000000000000d7580f67007b68109c8aca895045e58bb858055f5adb64e536bd0b975122e35cd62406be60adc3e619e7dc4632fa6d0000000000000000000000000000000000c9a637021f8508b02acc97733f2353528f8068927813eb2937aac6f39e56b38d7ffddec5147d18cbf4b52b20ed7ca8b0000000000000000000000000000000014a251a3aafe4a7fae33acebd223a24237d51f0d7e6c2e36b6993b91d4988a0ac6418a3b65b65cd2e5c356be21854a9f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015558a948d169718e3a33b17c9cb380318d9af9c575d001d44523d442d5ba66be7a85fe66a73615af23c1ba9569c3ed60000000000000000000000000000000010a135b145def15c7dd0247af52d5b893e4f47463f0e7819d415ef06521075a565dc64902b3d5ed61981399820845034000000000000000000000000000000001873a08e7d041279d03e88dec0c700ba91187143ec7687ea1b66ffc84d0e75e2be608eefffbb47f74eaad37c50686aa700000000000000000000000000000000091839cf5b284a11da9d12bff9acc6a082f0503b3e04eda3ecd68a32b5df89f91f7e5373b86df5125c4385ad51263bc91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000b8f4c64fb3f7f3c040cf1811a5cb01c4b04a33db798010f3e7dfa1a974e629308bf9fbb66f2bcfd4efbcfaae7568943000000000000000000000000000000000a82c3cdb469e66c44bfc6aa9efeb452082cb72c98430fb6d1bbefd3d9c64760aa2c38f453a75ce813228d760a345e0c00000000000000000000000000000000018efab4d919e1adeee5b5fcc8e89fd1b9ecbb49de50e80d60f70251d4a7da696c1c5e8c5de0d55b2887101bfcd88b240000000000000000000000000000000002d0ffa855389efdee28281a1e95fc805ef8dfe55dd54861e450a065885c49b7b6f69ebb7099bd9dabe96fd3f65493f91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d0e6156f0099845f81b3e16246bffa9514ac35edd802e9f39a6603f3cb1a2e6056d2a09ed2f2ebccb72371ae0726ae40000000000000000000000000000000008efde50a1e9c7bb4ea222aa69904e89c0995493ec17e4260f09b4663bf9dea0f5939a526bef1684506f836a115112a30000000000000000000000000000000001a24f67ae179255fcb9188fc5011f7cfa3e0010b5c483b524cac9cf5ced6e118ea4d91a9d2839f41099cb13358a118900000000000000000000000000000000090a800d9657928f63d9d1faecad7fb0e40377e56ae3f8c27c61a3d09fd1e9dc2c2b6cf423e0e0f88df6e992b3cbaedb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000702a2dda96def0e19b6c754e784c519b4f42972cb976bfcd973372f17e1fca6ecc0088fa5bd448bd55ba3ae530d2ff00000000000000000000000000000000004e08465aa570c5c4a6205021cb49f2ac325bef823eef8302be8ef884f62de7e68010416fb070bb3d4ed08132055b89c000000000000000000000000000000000f2ac59da7ad3336cbeda881d0e5f6b71db2ed0fda523d0d9eeffab8111e64eff04d21c66afe1fecc8adf6911aaeec1c0000000000000000000000000000000014252236ed41d358902a8e7ef2b3e2f15add33f59efd1b0c553c4b16c4dec0efc5aa34331009582c57fceaf4cd3b77901824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000ad103e1f49b1a099ebf286650b65cc368ec423df1497e624fe5108e6115e4f7e7eae8089108bf019fd5a808fba2133b00000000000000000000000000000000039cb70034dbea094eb5bfd0a854360b378a3d333c55e3b9ab93335f4533ba2cc6dcee25a2eb90e61b1d3c54fe1c9c370000000000000000000000000000000013002ecc2c47cbc64e963d8fde3effff07450cc75322f64ab483074fa93e85e5aa2a17f0a2e85bcad8da09142b0921fb00000000000000000000000000000000074aad861044292daa97ad3f3cc4319c3db7d1eca9b66fbf5cde7e21117e026cbcaa94fb4ecdba15c45b7442f15e85a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015ff622c75fda41e830d83e1f7c2c8d37967b8b2073341b856d17cdc25fed9aa4786f7295960212c5c2ca2945065ad72000000000000000000000000000000001580b7ed98c3b9e3dd0777caeaf42386f683efc9bb8088158c9c43fa4ccd178405307b67b9267c5f8305962a794816df0000000000000000000000000000000012f80580334017c86013329511527829b51311e5d52c46803ad126f62f8d548767b5dd29692b2593a0adac436becf4c60000000000000000000000000000000014144667f1a8c3e4eaae596afb725020992ef1eec41861699ec8d659d23701012610cd5591c98cad72927a3d96f429251824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000001328dcbc880a0f6fa5d244ef89ad81f3c3905a0af36794800089f922e21b72ffe6b72e31f7ea58d1730e840181fbe00000000000000000000000000000000032a3c9f849533af17db9a05b229c8d3b142db58a8ce8ced3921366d27627733608126ba716270e1993b58cb3a1e596400000000000000000000000000000000045331d73f8bff93bc50cfc75302799e4a8898821e165f3de0b7936654beb9320c7ca4d5036a941b5f27ac185a8a234e0000000000000000000000000000000009a1f7b893dde9f0653f64d6a3bfe4a0f505c82a01eea7485a6bb07e39b42511c479a31e8237eeac3d766a3666dcdee91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000df72c38326575a3dfd0c60abe795ff1f91f2d6e84440a16ef6c08eaea96fe445f68dde38fc9da4053e74f201f0063e2000000000000000000000000000000000dd12c1369cc16b00532cf89f17048ee560515a6fc29242e0f9ad16bf90e7ce799344f970f349d7b9c38d6153afcc9a60000000000000000000000000000000010d56040471c724e0111e1012f1c5e643d6829413e8937a7c8f77413df2511d2a4ca41bbd4e4beedda986c40b285e7e1000000000000000000000000000000000d724cf9958bb8036e3f91b09c660a2ac10b9c0a162c2989977d9ec7757d3bcc6b72691287c85b5b05a171e24bc8d61d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000168cf6afe08f62a48660c4bbda1b0e29a6b63c07d2cc86d66cd200dbcc0fdd3f69376296ed71338672a3f7a9262967800000000000000000000000000000000180c5db29ff0e366520db2a55a871e560981a850ce9effd61d544c7253c99a4b61b0cddd0faabc205ea6f205ad3bcd800000000000000000000000000000000018c2251a6903d33ceb0b12abecb7535515d5289b112443aea65f6bb96e303992f01b53a4db7961555163863cebd8c8bc00000000000000000000000000000000005fc705055c3bccf7056c9a64e6f3b9b656b7d58cac5c8a8bae389029ccae818de768c894da3ade62c83cee02ab771f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000765e1b6bea654dc67d999421710ac41965952f53ba835a589441841a6163e7d0ae41ac5406b591c6e5bac71b2f2423000000000000000000000000000000000146f33c010ada3ddeff9d87dbdaa0c4c3be52d0d7295a4da3205909168687d0948ccd1b5275b700f50753a2fd15241b00000000000000000000000000000000018ab48c636b46c8cd24191795679e83876d274fab1ddc3ceb6749fb4fd6c1b0b74998a98a34f03ad4eace16b4f2a231100000000000000000000000000000000193d73264418017fe9d23976533e9e4ec522ef71bf97f2659933f354b19bd08ff423e25a08c0af9a75af77f897a3edb01824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000173d99f70ef55128675174a6d51fe24ac8ad83dd6bae15a9f391da65a4e5c9fe7ca4bac373a478e532739f21027aab6c000000000000000000000000000000000769c12f882e6e02cab80df2733415fe15b389bc0cbc6145013836b51026b236df8296e6da211eca019096131c98704b0000000000000000000000000000000014e7153561ac62442875caec537c4b16f06df2faa89ddfeb3994e0498ed673c4da24b3ca5066292fca1b9c9e1b1610c60000000000000000000000000000000001cc840b59b13af870042bb0ba7231f85b29a7bdc8d9368d5aa379005a7b2aa79cf481e54768c3bd9ab59fb93d0dffdb1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000d2f80834b33e2cd3f3c230d5a9e65fd674f29edfd8c0de3eac11dea59e8a9700585ebfcaac07d1ad59c4afda0a379a2000000000000000000000000000000000d6c27b820729a16a5050b1bc8a1d415f6f61da5c49e8ec83399ededdff4fe236ffedbf58b5a6ee7cda3a2d3977b939e00000000000000000000000000000000190fb3f8c608eec93abcbf1fe57b335919857d26521f30c105289a7a222490214f4147a4417aea594d912564c8e0db790000000000000000000000000000000016b8338eccde031e62fd0127d15ff0ea5f76c33ef2a49d87771228739e06e7de386a7e294bd77bb3b4f8c8a80e85ef5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000052ddae4c6155a2cb711f864e53455aa551f92c76c25130658f6e6392fbb66dd548bedab448ea5bc197d7c781eb01ee90000000000000000000000000000000009237657cf177f84ba2fa09c2efc113d8146f2cee5890fb207daf667b640022decfb6fbfd98c0f6b2ae7248488004e5c00000000000000000000000000000000129704e8b35fc11aa753f3b2c2145fc1b150f87e16ad84fea400ede06149ee453e51c5394cadeda7beee63e04733fab700000000000000000000000000000000128d183c88817bd7297bcd58e33cf1da2e21dbcdbf3e0e7533334133431303ac6c4723e449ea889d1c043c8c99e56e091824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a8b24cfe2db01eb6a20327ac388d08e2d7bfd432097c9e3dcb697a3ff3a05d3ba1dc4e249391deb2eff3d0a08e1763600000000000000000000000000000000129b1c3b9ec9285f6916f279eb15513b87deb860b64ab138493453187d2f705559f840165e337f7e9b76d3361075246a0000000000000000000000000000000005763c17c5358c8fe56cf3a6350a6fe717545e3236f14ff2e2d9c202d8905317595b0e7e20b6ec17a7fcb1486f7f617300000000000000000000000000000000175a813782e259d77769d3f17cd9edafe10af907a8d940364a29e9d3b8b75ec3fe78fb07e9a2d77909326cd49e4ad1941824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000027f79d337b30bce1689db92d77b95fe68519c3299008faeb85235425c983b239789a690613b3a72bb74caaa5299ca1100000000000000000000000000000000173b4961226319cced64538536a0f0dec928b8a79b1f0e8a49f18d0cdcad68bdabfd452e30f96677fb5b2979b82dd8a500000000000000000000000000000000130833412eb66afaf6b445c8b367e6dad4ef1c2558c6c5f75f484371c464a260f860df4837b69d568d89068053d70f1500000000000000000000000000000000076fd9f1d0deeff4d3784c597d12668910dd7d94ea5156f3116390204a75a04f087f6ef5dd5a4ec0ba7270092527907e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000e762c624f0ea97818c0bb83117d5df0afca15407a2641ded8561f00c7ab2e4e24cfe82457876aad20db7d3375254269000000000000000000000000000000000339a65bee3e72fea81701c3d0edfc75c38750e006614c4fd83895b10ac055ba5733ad7be8bd8a0811725a66ca12411a0000000000000000000000000000000012f92ce4b8c842fe0a4b22a3d950b1a1fb190ee09e771ed297369cf8b144198ef352c1d0e3f7e2390705ae1bfe18b2a70000000000000000000000000000000016f5607cdc02f9170619c0fb4e7ea1e24dd226ba67c41ae6cf7105785d18571bcf8fd601512fa824b247e6766af6325b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000c9fb4d154f2dd4fc40bb8cf0a64a36e6027b4ceef0f79516ee6dd5cd8144303ada1ff15f5e9b1603e2ddd6f94fee75500000000000000000000000000000000114dac33b2a522c7f8ddc9fd92925fd325b91a08f67e9d639cf616f517c66c4d1faeaa79cdb784f511ffd550d9dc81c4000000000000000000000000000000000bea9b7c4323d0b54b7101caeae2437f57b44e039c6b205fba391c00ece275fc609e4ab0213e88ee8f998649c6dfd5740000000000000000000000000000000010893701c4e486ccf3e3095d2f3f02a439611d4608a681652f2f4d8207b67c773e20b7805bc84e39f4faa480d8bdc2dd1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004273c66a22783fe880619708d228caa29ed4f3198690ec8ed3be4dc6b675f9ff47468c36df6d290c1456242d15231ec000000000000000000000000000000000358ef987e8d618b057948d354be0d95c8f140adec04e11d98200d66c500e57bbb527044fd415d6b0e6aea1380c620360000000000000000000000000000000009a290f91b985126e3419fd222e53f1bd23aa69ab9b81b9d957ac568d55a5c428bc981e216b7ecec357b6154f79848b90000000000000000000000000000000011d8f3f6aa71e9456a44244def7f0af9bf00e48f076a7163a4b15fda145e310078192ba8e1bfaa499e92f5bcc7b70a051824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000004ba6ba86b644bd96892caacce01841eed057ddf9f460eaebdce8f26fd50d31d9bac315303dd2aef7e3c905386ed6a9000000000000000000000000000000000043d9e7e32e4ac93f0903f0e7bf2e1c94a1dee22812a9d1aff62cae5fb665362ed4f3a7a775fd9ee3e2af252c617b18f00000000000000000000000000000000163e9d42c96fae30f013353e9d97e0b5786a90c8110e712341176504994176be149ae3e238141f7ee5e58b8bd269154e0000000000000000000000000000000001fff186044751ff136e0add91eaa4da0b2ca21e868b73607fbe0acba408596614a86c65e2e1f88b81ca8d8f9fb2289c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006b966bc869f1e1c728cd89b7c99e79d19b7daa0856f4d9ae54fad6c7fcd0772b69a1d00d60c76303a21f46e900f5f770000000000000000000000000000000014cb15361ef896464d79f84b0b3520e94bbcc92927824b4d269c2bbd0af0ae1fa212cbce88ec54346393c4d423ba52b40000000000000000000000000000000007aa57716b7d95726c0b76e9b7bcf7e311da08fffbc81ee15b02f4bf08b3dd41d165115a259d34384d72fd75fe6524f800000000000000000000000000000000008ba06b5a787d2e8ad4c3f910a601a45f30b176e3618c0439c00a871b2bc14e1de0bcc2b72ed593dd69798bf0ab97d51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000111ff17f78120f59943cd9b5007a1c607d787fbc08a3bcce5eca9a6e7336291e6b696a1efb6ce5193b7b7fd3f68fc43f000000000000000000000000000000000b799c1169fb6262224d7e953c3d710db495d88918fa5ca3ea106bd7cefc198f038df0e13db4aeeef4c4a6c6e8b7691c0000000000000000000000000000000012d458b19c9cd7ff654afdc4ea4d3e275271e579e3f083ed6fec04b92192ea19c1b55b921b34e20e1de9cc53a47951a800000000000000000000000000000000097e35ba7cf8b39ac42aa4c3632a0a0d6e8a8f057bc0fd4b11f71aca126ef7686f8f8a2c0241f67eea242e1a2771b1511824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013eb7950960759e13626c7b5be87693bdb5eb05968bed9cdecfa1068cd7d3c97075ccf709ee8e9637c076d727747cd7a0000000000000000000000000000000012ad2c196a4f7fd2d4089484e785062e43839b0bc3e1d604d1630e4f95cfc9ac91bc750fea7f1735b4ff5d01fe6de12b00000000000000000000000000000000113e31c9d50cdc9f50b9b00e8793ac8a07d4b1a84dfd732c53933c43c0cf0b4506ba18037798aa47348d2f1ca24b08b7000000000000000000000000000000000cec9ee9492a05a533a2a35482454592436c4f7edc5695a88f0cda522e106f07f35e3bd72fe01647029b480b6d52ed4c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001439a9fa5602ebdce91b248d2e1bb6d3f937e2d2249f5fe817301553bf36e4ff002d6d066cb63e24ab57ab920e600c59000000000000000000000000000000000da6eec4829a4b940710643495c17232d33bb7bdd767e1eee4915077ed0b831df1a3080da98baea829a6e377e9e0d9eb000000000000000000000000000000000c2a4d773e64c10431842145644ae2f63730555f11da19e1458f9a9ab2adf1c3f1a045d5aa997f8a89ec924a8278c27f0000000000000000000000000000000011ded0635e59e428d88629755a8ea11b8bd23e0b0c60182c73a4e8de4b7e50664399d88e228ead5528189448781166331824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000012d620ec19ed67af168446e21d5dfcce68a5d1d0834a295357facce7e26f4455030993a700ef8cd5a91891b613a3bc38000000000000000000000000000000001630fa86ef31311af9802c43c0e0a873f75109d5b76dddfd2da074d5720b23094dbccbc470358eb192fb5d365bfa7a3c00000000000000000000000000000000032d6422d25d881dd94b629ce2fbb8b6c2ba6cd08d2f3da854f1955affde1eaa6e871a2ab489adb0b5ff978a7df6d3f500000000000000000000000000000000169b3e6864dea595ce86d97bfb9fcf26eb23093ba75aebda1930fc5e3e0cf2f641d27226eb5f994dbec8e47f8120e48a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000ac9f1ef69025b67da31eafb81eed658f6472c2fceacd7cb5ac84b62fca6b04346e8341a02ce589d21e302a390d976c00000000000000000000000000000000175c5f9083b2d98038cf64df48e34222172c42646a57b9b538f02528950fe7260eea0502f6b04699feafe41d59893d6a000000000000000000000000000000000bc921434624de5334fd7f509977d4e8b6b69ba433a61cb20ebdb789a959748b30afde60e6bc6e740c0a9bf2352bf02e00000000000000000000000000000000002b757118fda743829e1d8fc328aa246d28be1b95f95452ddc146bae88660929a96ac6659984ad8d715dbcd6d6bf3481824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000a3b2e15738504b69eff2a74eac44096ce50ca0998a550c3752db69289276feb136c27c7b1eb357f73ed6e4a14810361000000000000000000000000000000000629f1cc9c59201c332c38620a90236031fd803a1ad128d619e643e1d4d532a71eadf8ebaf5a4b45852876b561fef30c0000000000000000000000000000000017d094359487563883715eb07669854e4f025cbf47ec303f7303842c9f022b6ed7a037eb0d9bceac987621c08e8d4ce9000000000000000000000000000000000e1ace86b2e1063619d1282e00565e0d1412482070fd43f400e0a9fc042311b87b348a33ec925f878115b253e08bc4e21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000006f40d0ebdfce6baf1024a669937170ad9e666660813dcd37ff6531d84f4151b6305dd084ff869988d99228fa1b60b410000000000000000000000000000000010b3ae2e95fbd78dee8c29da880747249eadd3334aa9472f08b31fcda74f8ba0678e7d8f44b30f0eea2c00d1f267d2a00000000000000000000000000000000015cdf4a52f79f6ef8aa5d61c4488b7314a71d252face9c87c93627c49e8a981a4b553feedf2240942632000b52a5b56400000000000000000000000000000000072e87ebd1b0d459651b6a3a0421304e5decca06aa8b4fa8e13a5f3bdd75b788014387a43b68388c0d2c34ba3f96d81e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009a4b021f45c78564fa6303113aef811501c61c0624de6dacc963b42f8ffcbb53164ca4deb0e4063c9200e84736aa5c800000000000000000000000000000000173a9c582dda8f313e1f5c14f21a7f00320ec3c2b7558ed6d113ac89729071590b3ec982a79873e20caf3c6fcf565d700000000000000000000000000000000002047ea8f40ff057dfd05b17b67a350f325e78dcc4a0d19a405e64ce23c44a8e56841ca9f57e35b2f7e88771210b31440000000000000000000000000000000015b5688dffc2613c16bd1a11e3410f660d40272d682c2329a8d04956c01806d7eedb9138001a23edba6a738a21ad2fde1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000100e0e2b1b4fc00721c1155022da0e3b394b0d8dcf6d8d29df8847704ec4dd9f6305ad7d2e1ab284c1074ae0e99461e00000000000000000000000000000000139a1bd565aa1f7013a5c0f08fab90bf3c157bf2b4bfdff3ad0de942fc4da05974b522be22478d4bc1b269444303f74e000000000000000000000000000000000e82ede5724d6b42a0b30ef3832c8519df8eccde633f7e2a91c3d25aed3e423752391b8f378d26e329f28f22fc0afe830000000000000000000000000000000006cf72bf453c494798b05ad401d1be0f1987681549869387dc85afcaf7a8e3f7bd4c9c9564e6087c8db68bcbf234d8b31824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000acbbc26ff8082e6201281507ec817e1aa48fc3cd749245e4dbf9813ddde2082f2232fdaa4397ff995b5efd258361ebe0000000000000000000000000000000013c2592b2699e28b4a4a6a55c5077e4e927770937d0b585bf5bff3ff94fff892949a262fa60d19e7a08e11ee278ba49b000000000000000000000000000000000aefb08f71fcc8531b67b5623403305914f4a1242452543c05a67b4d805e04bc2b055ebad1006d2d84384794039d2c80000000000000000000000000000000000df5642c7ca23d3bf49d6978cf0689718bb73c020d503e7cb021db046d16ada87161feb46fd56542c8dde6b382baf3b11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000030aa5bfa6df9718620f17020a39f2f6ae0441b5682e11651070cfd91ca9426061b98daa3eff2dc8cdbb850829949fa800000000000000000000000000000000104d57eac1696ab955e852f2e092b3ed17471bb90bc093d2bfebb75c2704f6ea8c7979117568a18f25d5f88c3a7cebfd00000000000000000000000000000000099415ea067b342246afcfbc0555ca55b6c26e25af9ec43ec087e035fa8675b06eec4aba6161d6ddf145ab33f3089ebb000000000000000000000000000000001384ab642dc21526b26669b9c690741b98244d45e1ae5161255ff1ed444d50d5d4ea9b5fd9906c822cd646a05381b12e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000086963227ebd8ae42e99eb67d87de72e9b8c8c4669cd9526bdd68670a76b4244f2827afc2d41a607dcffe880b466efdf00000000000000000000000000000000095650612c2197d7999241ed00ddae080c1627238d1884c339364931ea26b414e31c78a91bdecb1c7f797f61082748e40000000000000000000000000000000004c8900e47a670376abb302004481cd2cebbf5057115a63d03285afe62942f3c6cb2d165068cbe257895604bd0c107e8000000000000000000000000000000000c216aa20807ed1fc40c1d9a1792943154f77e87610416a26528af6a0571b2f5b61496504140d100ccd673d31dfa47121824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000002a47f12407eb06e902e57c1b44b95f74e367e7f9332fe3f222350169d9874b422f97d51a01271b3b2e6ae250396b72b0000000000000000000000000000000006e429926d5253dbcb6dada8a418be7aa9c80c02b10b201e2d9fe9968c610cd833451f43029f62ca0b1885d7922871d90000000000000000000000000000000018f4170bdcdf38caf19e7d3c9cd2d78d1180ba945228672584eb75b7afdc5083c41aaf5861e876cba452c384bfbccd5d0000000000000000000000000000000002e58256b22339fafb9eee9050aacf7f3b34bd63dbff334844cdf48871f6b5d5650a0ab8d70c48640cf04b3b973e20d41824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000124b19da6d8fb220f7e566499c192778e9b28cb2da5fe31ec2e569a03fcd7a1ba39deddf36d489655f7c69e10675e7ef0000000000000000000000000000000013650d54147ac7d016b4ee94de62e90469534d8f6a2bad6ebfd6e5d50247a7f184ad6a1af804cd43520d47e8c9d6d1780000000000000000000000000000000010d0cd79350974897876b17bcd2d6674636cf970ec3344677e381c72419fee418c15588fc37cd1063c5047a5ffbb5faf000000000000000000000000000000000f5fd55bdd7ea1b1c57702ed40cd6c63912ec6c0d13f954f41b5d8347e2a0befe2af9b900d48428b34ae9f5a038551981824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001400738f1235b9302b86d2128aebfba46088b755cd7095f8e0feb6400a91360eaef54bf8e714be30d743d91803457e3f000000000000000000000000000000000644d3929cc9911c1e292336c0d43d771410d46c199e064bdee825381ea26219d2ee9696e50a291f94ff2752f5e6574d0000000000000000000000000000000004cfac7cba9dba084b0418b147cc7f0a6090ffb3619d6206121477dd8842f09dbfc48e14d5528d7f12bea9ebce41d9b4000000000000000000000000000000001025cd701a8a3dea5097c94c3924350b53c9c8af79b7ed9baaa928065a2833f860baa1a154b61b068e5d9e2840bda52f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084dfbe49f37db531979d235fcbce3b5ee534a654ae64b7c1616bf5ca282b59325bf7f69825a6831c3766b867757f12600000000000000000000000000000000174dc6e4fc2575701da91aaf5c3fff3ba476aa664d183cf57b2634000a82e05b075768a8a442a5cafdf95135c2cc936f0000000000000000000000000000000015574ae00f6dc32ae57f1db04e1ba50c82087cfb269349e98b0f8841f83a7bcacd3785954f8847bd88df0bab01de8444000000000000000000000000000000000cbf903479efb8ae9818a9b824daa117bf8c04c7922cbd7185b6f1456f425049a02f87abac7dddabcc0a183df781bdae1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001039f728d8d83c9e8700063c169395bed6c7490d54dfabea1fbdb714dfead0ef5c86c8d8dcf8b06564ff3bcea2b803b50000000000000000000000000000000014a40ad99055d4c16e76d9922446d27be5761ccb547d22137db5ce8909004c3a39f797b0873a1a5637834ea0da52aac7000000000000000000000000000000001089b3a198f4f532514a35d74d69ef387fd54d8e8805f479b3425c840b256d40016f4972ccb3e1b650f6cbe7e17df05f000000000000000000000000000000000ff6b147cbc7407e1361e9e9f71c62d6b0d81a81be5be90aa6ac2d565fe07661fa73c8f0b604212f3c3a268c1f56c1b21824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000015f3ae1582692e3e33f2442991530517219f9b3ebf88fff03f81237553cc1509a4732155423dca88a6e63e9f036318b400000000000000000000000000000000000f80475ada3353f9f4beea3181004bfbd77033276fc97c73cea875cec86ce00c1c2956c5d45d548436226c4d0a48930000000000000000000000000000000000ced6435f355fe76d88f54401e4fb8f3992567b969177975597bb8f4f085b43dac6c4bf7b79b63d8bc617b1068655340000000000000000000000000000000010599298d7f952758f22e9c64f54b0c637c203b3fcafd205d08a408c20a8869612c7484c88d2843de8ede4c63abff98a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000deed304633e52f8174b8ae6f730f6751676a6e3f8e26ac8c114615f463eb2da71a9bac650ff188f16c1e9b61a2e0c900000000000000000000000000000000166b2764aa0c60dfc3d8d28d4a4fd2710608721be0074505f7c2f6061a48160812488f5918649d973888bcce4263f79000000000000000000000000000000000025811567302686b3d8304c35dca281ccde474b65acc50ab4c57be143cd60e73edd776395aae8ad7fb50d8d8f596ef1b0000000000000000000000000000000019b23e64059448e92ae75cd1dabbd569eb727a74f108552c06c1d64533d6f79b066a60fbfb1070eac8d9d095512d60791824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000148aa82244ac489a6d29cf7a5ed0a2099763db2d5b4c7324073e240271e9f9bf215a234ab16ab5cabffefebb36d8b3d10000000000000000000000000000000002dbac638f7cfc530c9d2bd1cdd3faf64f2c4a6cfb636ef69ea759aed9fd804f890e1d94a6507c1f330a760aa5fc37370000000000000000000000000000000015edbb563b6fb737e9f7eb0ab733b675ee622ea0ad3b27ad2088012434d01e00965c9d08d7d5e29b3e2312ce29d61c48000000000000000000000000000000000586c5fb0a680dcab6c924a7f1b77a4c4c5eecd7906ccc5766f0a9f874d19718cc8c84ec4349f4b2adeab311b259cfc51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000018536c11854b53a080f259976c390546547ebd0216c60f4b992c396297720047a64912403d86d2e7f89958b6a7e196b900000000000000000000000000000000019667de47937d95031897a3fc1b977d5d7194327c62a61181f28d5480a0cc5080be670590f1a3735a5e17e5bd1d9a8000000000000000000000000000000000006a522bb9af0557b0140812716059d749d47e8258254ef496dfff3d33c53ab448ecebf303ade65fed0747539cac0ba30000000000000000000000000000000010fe64b2d4243d5609af091dfea721fa7ac4a7a20e1d6a658ac48cf74fe071136f9245c76839c8324e57da741c40749b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000023284f6bbb674448250470b05317d1d5464aa25d2618ebbfd2c94dfb4242bb24740dc09b088822d53e81fa0c3df684e0000000000000000000000000000000012d0f6105f450da62341fcdf77f85c8635ae876d892fb8b84107cb3e1345eb9e6d4443bb58936b40c3bdef769e6f8f74000000000000000000000000000000001469c571de6025bf61e8d26bf42f2381caf37213428671ca27b5c3418dcc4c07acecbb01ca2b62556c3e04d498d7c2d1000000000000000000000000000000000ffcdaf88a02d1c5e67418ceb2b6dc133d8c35aa080b84efa8ef68ffa330eb85f99f430cd5a06878ac7241c811a160c11824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000001eb0ab3b9f7c535d2cf14bbce867368b830f0832c62877c581ca80c46305e2f2a264279a33c6e0e311881a8d38300ab00000000000000000000000000000000069180f60e9c49d57f3ff7f25698c34842f8d1a08a3c1b3a9c44389091898983571c4100ce9fe30f69d616897ec280820000000000000000000000000000000018f9cfb80f0e064808bc7ab72b07ff4d4cfbac4c2a332a52dc0d8864b87b8b0b28d971b0b55c3e173ee2c34880eb6f620000000000000000000000000000000001d32e89bbb423b49835d05e1ef847e3f60ef7e9c102547ef0d5cf7e8ca3860d64f304a5e9a652e2b00a24cd3ffcf17a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000084fa87381de3b4029a65a89d30748c6b36fdb5dcad5bf9f16a288a50b8ae8390725db0cd7b78fbfc18127cbb50053940000000000000000000000000000000005f29523e7ce25322e5c01696ee6a7b1b8c870e53dfc83918df6dc52d1d0890157c927257b111ecf41bee03bc90f1e9b0000000000000000000000000000000009a428030f019ee2907d46706e120be71ac4cde2f6bbf534bf8ff67d5e025f74f49055034e5e621cbb6fbdcc1024607600000000000000000000000000000000136934b9a77919605cc5cdf267d7ad3e17d3b98c411b824ff02a07f26c565630fc628895560030e9c69f0b174385fd7d1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000016e05e43fea0f6c7b589be17d2fd51e5d2e9e2c8119c391e3a65573dc4a29fa6fc4f134e6988f64ef97fc2ce01c09b040000000000000000000000000000000006da32b477fe9f75ca6c6aefd26e4a6c2adb2f179bd37c9f156380167842e85c86044ca21358363ef2fa4579c432ac94000000000000000000000000000000000a006191d9277dd93264ca4d3d7855f3298905e5c27c46983e91e339b890204d4b3e4bc7924da350dab83516902551d10000000000000000000000000000000007b203cb2e15248c5fbe2ce269c2e3027a5c03b07fa2cec6d2619ad9d9eda38d2e7d96de0ac5c7b9d3976001c5df20651824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000174a53f2ef50d98eceef87abb8ed231ccfbb065fde000854ec8ec55ed1d480ff4022446c06634fc9a7cb71eff99c4a86000000000000000000000000000000000a758cee0ec88392aaba77d7dd3b9c18df2f1da31b2daed006c3d79a196b86d5443388ab9ff3369e87e3ea7a3539fb0c000000000000000000000000000000000902fabb7c99dba8759f77accb5261282efa36bc101908e0f7d9569c7363d880c3b4ebccb93fb04cd6b271010cb524d0000000000000000000000000000000000b217b772f517d90805cb4e6037f2e82839fa9549da1859e85cf76ec8952fe98fa8a9d40e3fecfc7bb1846f1f8fa62a91824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001050cb16ce5ecbdf55d83ec6804945b882602035c3a621376267dd5ece77f083250c3de885ff65adb310e01db32a64380000000000000000000000000000000019da83f5fa1fd94077015622535295a6d4763c4f464ae5cffb3796cf99c3e0c115ec65d28890a3b68d0d62f7bb86452800000000000000000000000000000000102c31f1bd3638a26b7046fcd64919389572a6d2b290d03b0c028a0ab48f2ca5f30dbcf925ea90f68cadef85a239c8c70000000000000000000000000000000019a33801bf1c2977e1586a9ee9cdc74777436aaa069d241f365b13db0946078f5a70c846946488485eb1c19b022991ba1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000049318e9ce756dfa02a47602fef0c5f69c3bad0c1825ecf52afa1c9001e2b60a4bb026fb465eec2b61c040d467890c6100000000000000000000000000000000147015d586e332fa678d2e6567e8814861eda9d25813108e54874c37441349413aee08839bf48dc8050b6ea7cc5b3464000000000000000000000000000000000c87b168ad95ec5981eead6a37d74e30ad575bb09aa3ac17b8bf0e5c6a11bea1b8d40f56f90d347046139c19110ec935000000000000000000000000000000000b8f20662e356ca8b3616dcf03a065a97a859b72936d472ed9f12431959b4fdd69d414b53879f86bcaac130eac8198ed1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001900021195089a4feee22cf8b539dcfba09ca48f828e77f5d905b3c2033404f2ed7b21509faee6ee6248683db7ac3c860000000000000000000000000000000010759a56269209a12894cad47c979c6b46282902cec89511f7adda7392c90bab9e191b5b6a8005f72854ae8e858f0ed400000000000000000000000000000000076bc78ec0a0c097ab589450c886f300a8edca200ffc84c03749b76b484131c620b5db35ec0195ac33edf304057b41bf000000000000000000000000000000000a92607c52d5c7d0ed24738f671d1c6b11e0590f64283df1e7db79ee40a9ea4ae2e38c3cf76225d0facbe93e5eaf8a5a1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd00000000000000000000000000000000001851f0f6db1eab1b69dd7ced468aeccf2df239b455fa38e9313330e5281f18a20a8aa20ca1c5e5bc2f9866aec92a12000000000000000000000000000000000c1c251901260bab20360db5b0b8e050ac8fe5abf074a67c757002403416826c502a8775dfe851d2ba8cce472054337b00000000000000000000000000000000139740ed23b4d29802be95d6f302f54a2be8ab0aa3f183afce973fa9149b89f877a85246cde29676a6ae5ac1e0965c3400000000000000000000000000000000091664122a88acce381e1c405cfc18cc11f8c630bd4f438aecd02e9ddbb0ed85d38da050fa98e6adddc29a7c8c17344b1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000010c65ccae34ff73b68373937aafa307355b32e3c3d0ad250fb062ae82f9cc13beaf298c6a71dd8d5599831fb38a8d315000000000000000000000000000000000aa6a6ed43fa75789d2fac1a0dcc92eac8b9ce5f49d4e2429038141a47144d37e0a8a20a232ab6ebb075e0bc17a26bec000000000000000000000000000000000bd00304bd516b3b64b3ca19235c55e1a4dc2f7d8ad2823992909271bc659fb276bb8c42ad2811a13dd3c37ceb37d88b0000000000000000000000000000000000642dc986bd879cc949e2229935f947a17ad848af0d52fb990504f745152e4e7bb11259ce4a8bdd419480db833424201824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000005ba6a5d12a35ff05fff302c4abfa325db749075b30acdba4897092e9838e24003afd118800182b3a82b24695dd32e150000000000000000000000000000000013ce6eeac487f264fba1f26b6924734b816b88e120aad4a650c6033568e1da2eada3b07f097f7eb5f1433185fc68cc7f00000000000000000000000000000000175f9a6a026830306e7c9ab80dbb19bb0d0dc936141070e1bc165f0cebaa8bb35ddadd090ab8c0d85724eb83751578d60000000000000000000000000000000004ab1eabbbc1b88785770be143c478e059ddbb4a0be5c301449f7abdd358e8db0f1570bde2c37d25c33053a5cca5c49e1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000001393118b0664124d991ac7a98eca8888ee52cc90065b468838bba3371495ba4d5bbcf481d3d642c444bcf17fc8a69cc3000000000000000000000000000000000d3b5e12652096f1d9c6abd0475f9edc3e43998d31488eeba4f53c0d8b7261ee2adb0392168ea23ad8ecc8b4b607fcd70000000000000000000000000000000013b5209b79a78df0465415dec28ddecdc254f8c843199c62c23731a2f7e3f6b4f2f03a5e80565f74173131ac3cfe19270000000000000000000000000000000012947041c7c6f0b5cd83dbf442bab64e0c10cc33e0b53e9fade4354eff20da0b1c7f080fd8d50c429cc036eba2eafa281824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000009213afdc588d27053de6b0ab5df9ed62b313e1d05d6e5b0965d78f7cd8f665c3615ccd7a7759895a4402cca974a32fc0000000000000000000000000000000015c4262ad1b113cc6a65d022d480aba4f3201b519c296ccd5873a72bff4a9c4aaa8b6b1122486e15b1d9063e1379600b000000000000000000000000000000001832b25262ee5b8f100049b7e527f7adf82841f81709593211c3c2b73c20ea2627dd94c4af553d35a48f30416e7fb74a000000000000000000000000000000001776386a29b3457b0852f03e0c5abdf08c98a06809c7f7711038b8fb920f059d0211dcb7203177e37ea88b043d70f42c1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000000749414cbd262bbc05c87e61cf091ec90dae3c703e87b4040503f15cb0a0a9b5d208869cdf4a54baa9f737414717c350000000000000000000000000000000005485e5fe4329edff91541526ad98544953d58bd405b0d03a76aba85174b12910a77c2149f6479752e858bf566032a260000000000000000000000000000000014578447e6068e02f5d13120e72148785efae64bc1d52efaa8594dc0491a3b280ec9be9b06400047710cd7b88927b267000000000000000000000000000000001615ab016fdc2acb99eaa9872b4a896bc11009a66bc2c9cbe5cec0b187b2cc8a213731fbd33c6261d3b636a237e79efc1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd000000000000000000000000000000000292589156be4715b87f0946d868034f2d33c22f3f615ed620faa031be47b86bcd1713c5c6330872390c1632b6c6317b000000000000000000000000000000000c35b7e6e42834831134e7cca1e9fff98c83f8dea9b21baea96d3aea623fe6b30c4edff140784fe9f1581aed28d7d2020000000000000000000000000000000017bbfa07a4746be906e692e09a3ab20629c1be8c07fd275ae37d717b4b4af1f25303cbfa3473588886a614aa04e3e6f600000000000000000000000000000000083f3b8815c245bfde07a139dfa4910743241741ea46876e0c8e0a7c55c394c112b76c71f401d0192afb63af49007f6f1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd0000000000000000000000000000000013a8312c30f3a7f508cbc1cf6f00a6973873309a9cc1ea8cf682f637a73855ba7dc5c10908f306a5282764f66ecd3175000000000000000000000000000000000564c133be0d3be8698ab98a2dafb2b82ca43636a9876eff19fbca8e113e1990ccefc4492b6a6034ea2e2d6ff411e574000000000000000000000000000000000ca0f865c096920be147dc662619a2763817a474ddcad928638de4dbf121ede32f8c5b5d39475b18e8f924054b86a7e300000000000000000000000000000000043f0230d9352dd19767bc715b8d471dff8e4c4b355019321585add13f15e73bd5f7419abb924a300bda1f3f77c01df51824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffd", + "Expected": "0000000000000000000000000000000007ac96192f4225233b4b88f7cf2650464e10f3b8275304e790b72f006637051fdd82b98d791928342b00a57282e81f5a0000000000000000000000000000000007a341a771e2ef772134661c486268c3d354e8332655792b88d6bf7ec3cb8148974141d09b21a76a9af869d30bdc1b750000000000000000000000000000000004e01c938b6e64e5786b7e49b19d1f437d14ea9042b5b25e611789d1eb6c94db812976e75b9cfe635a7e9c8dffe8bdfb0000000000000000000000000000000008da0941af163a46252e9c6057497cd04637924f158f0507ccbff466ae810e2178eac76cb3ff8835804b88951cd44c0e", + "Name": "g2msm-1024-jwasinger", + "Gas": 8017920, "NoBenchmark": false } -] \ No newline at end of file +] diff --git a/core/vm/testdata/precompiles/blsMapG2.json b/core/vm/testdata/precompiles/blsMapG2.json index f30eef6564..0b2ad89ece 100644 --- a/core/vm/testdata/precompiles/blsMapG2.json +++ b/core/vm/testdata/precompiles/blsMapG2.json @@ -3,700 +3,700 @@ "Input": "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350000000000000000000000000000000000e885bb33996e12f07da69073e2c0cc880bc8eff26d2a724299eb12d54f4bcf26f4748bb020e80a7e3794a7b0e47a641", "Expected": "000000000000000000000000000000000d029393d3a13ff5b26fe52bd8953768946c5510f9441f1136f1e938957882db6adbd7504177ee49281ecccba596f2bf000000000000000000000000000000001993f668fb1ae603aefbb1323000033fcb3b65d8ed3bf09c84c61e27704b745f540299a1872cd697ae45a5afd780f1d600000000000000000000000000000000079cb41060ef7a128d286c9ef8638689a49ca19da8672ea5c47b6ba6dbde193ee835d3b87a76a689966037c07159c10d0000000000000000000000000000000017c688ae9a8b59a7069c27f2d58dd2196cb414f4fb89da8510518a1142ab19d158badd1c3bad03408fafb1669903cd6c", "Name": "matter_fp2_to_g2_0", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ba1b6d79150bdc368a14157ebfe8b5f691cf657a6bbe30e79b6654691136577d2ef1b36bfb232e3336e7e4c9352a8ed000000000000000000000000000000000f12847f7787f439575031bcdb1f03cfb79f942f3a9709306e4bd5afc73d3f78fd1c1fef913f503c8cbab58453fb7df2", "Expected": "000000000000000000000000000000000a2bca68ca23f3f03c678140d87465b5b336dbd50926d1219fcc0def162280765fe1093c117d52483d3d8cdc7ab76529000000000000000000000000000000000fe83e3a958d6038569da6132bfa19f0e3dae3bee0d8a60e7cc33e4d7084a9e8c32fe31ec6e617277e2e450699eba1f80000000000000000000000000000000005602683f0ef231cc0b7c8c695765d7933f4efa7503ed9f2aa3c774284eabcdd32fd287b6a3539c9749f2e15b58f5cd50000000000000000000000000000000000b4f17de0db6e9d081723b613b23864c1eeae91b7cbda40ecd24823022aee7fc4068adc41947b97e17009fad9d0d4de", "Name": "matter_fp2_to_g2_1", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001632336631a3c666159b6e5e1fb62ffa21488e571cffb7bc3d75d55a837f242e789a75f0f583ce2b3a969c64c2b46de200000000000000000000000000000000184f1db9ac0fdd6b5ac0307e203d0b4237a50554eb7af37bb1894d9769609c96c8437e9d6d3679ebd5f979eb04035799", "Expected": "00000000000000000000000000000000184af3f8a359dd35dddd3dfcc6f5b55ed327907ed573378289209569244e3c9c02bdf278eb567186f8b64de380c115360000000000000000000000000000000012f5ba8e520c4730ac1fb75dabbfdc0181855e5ba2968a8c0ba36a47ab86ac45d19aa3d55f15a601e120be1f75eefe240000000000000000000000000000000004e313db704b103c2c1e3a58f8e95a470e7199081eb086e9524583131714c4a3db551fd51a3f2314a19a658e7b1765380000000000000000000000000000000004040eab7416a1703b0d103120506f1de2b26b0f48c7a0ea63dca4d9ad1c478ae03b5d7bfd51f4cd6f8cea26212c4edf", "Name": "matter_fp2_to_g2_2", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000732f171d8f6e283dd40a0324dae42ef0209c4caa0bd8ce2b12b206b6a9704f2c6015c918c79f0625fa791051b05c55c000000000000000000000000000000001139e8d932fc0ab10d6d4f6874c757c545b15be27cdb88056ed7c690aa6d924226d83e66b3e2484b2fc3dcd14418ee60", "Expected": "0000000000000000000000000000000017fc341e495bf4ef5da4c159a28320aca97ca28fe3a0441242cf506b0f89bb52f5b5d8c6e038d229ffe67d00151912f00000000000000000000000000000000007666300b7be3d904ae3d19019f7be5cf5ba6161b969c1a78aff639a24387d8fdcc4d0e3cd81ba6f063ebf2d859370f20000000000000000000000000000000007cc705dbfb5c0418beb1cfbd864fa0631bd60eccfdb16b5d55b6ef3558e2ec87dac3b45294dcf04a064d6d1eba5a6eb00000000000000000000000000000000052cb9c982e6b05c1d2ab4eed1d8082f96426b55615ebc6a53bdc320ccad0aad044395ed641b3176b554f19e62d46b73", "Name": "matter_fp2_to_g2_3", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019a9630cce5181fd0ad80677ed5ad8cd8bce3f284cd529175902b78ad4915f0df56f0d8b37c87c9ddb23d0342005f1570000000000000000000000000000000002cdd00b7662569c9f74553a7d0585312a776c8638e54ad016f8d9d25df98651789470b12ce2626fb3ad1373744387ac", "Expected": "0000000000000000000000000000000015ad9155037e03898cb3b706f7105e39d413ff3a5abb65812b8d21d003cab8fbb607d3938ccd6a774bc8debfa30f42760000000000000000000000000000000019d6382bb2d78180a8998a0536d67412d00ec0ef65f4cbce01340b8d6e781c0ff790296f8cada28966b147c69e02f366000000000000000000000000000000001290c2c205b748069d0875a89ca74a3b05ad8218ed46a1570696932302983c090d96e17e0b828a666fdfc3b72cd348bc000000000000000000000000000000000114f2f7ffaa9f90b547e86c863a5d3585819a78b095848dfa39576a10874a905488687b73e613f3d426510f5d1d1ce1", "Name": "matter_fp2_to_g2_4", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e63c4d12a38837354bbcdf4f844e5dfe727ebe292016748007d162e74c1f849787767f7e77fc57a42783fe0b06c24c80000000000000000000000000000000008d879e4891a891f2e7d27eb95aef70d5b785b796620ec43dfbb6ae550b4effb9f24210dc20f401d54420445e21cfdd3", "Expected": "0000000000000000000000000000000012084a53cde353a46af17cd2fb02c477e47b874d8ff58025b5015837759032ff98013dc5bf01253bb964f035183c9071000000000000000000000000000000001659272ab7e3a070a5c7b25a5d3402f7371ed67e58cac8438df41c39c1acd95ac5886b030384bf537d7c4bb8ddb2c538000000000000000000000000000000000852ddcc37a09a0a8f62dfbd1ba5064c1f6afacc9a279a4d998bed643eec5a0d96d6bad95701a04f52c83e8f87f48d5d00000000000000000000000000000000097a399370875398028d42bde8cf4e9641730af7a2971e2f59c95938120603a239c65030ded4323c955f7fd24bebf31b", "Name": "matter_fp2_to_g2_5", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000028d6de947a3958af5b53578b0ceacc7ef89d36526d8f3b6fbe787af69fed2c85cad3001643b81c575a741c4566e617e00000000000000000000000000000000182b56202f0494bd8baf5c03969288a1288b8ed8e6c7f49ec9f7493ee3369eeb42fa8f5fb7b243fb2bcee6be244f02be", "Expected": "0000000000000000000000000000000006f8191123f1e8f6a05e4e663fa763c8a0ade5de3c7cd38ec1c82e1c85f123ab51fffcebd677afec8e9adecd8d11263d0000000000000000000000000000000004fcd825bc55d044eb70e0bdd5ea2ac58ec1487e903b431c57a640c756265a382581b8450fb15dc649cf22a8539088220000000000000000000000000000000015259f83d76490bb868bb88c2a2c3e07a326bd3e97fc2f552adf85722a360a443d720c328076e35224328e09494746e0000000000000000000000000000000000f76b0b960a1343b4267f5aff44901fd6796a778b1a87666b95b773edd0e7ffb6656d4f0cc3b9b38bc6c0ed20cfce153", "Name": "matter_fp2_to_g2_6", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016adb5935f32bafcccb81cf4d177dd8826013d85e11a4aad66e3aa596e1183aeb9d68eb8cf5b716a8a9445ea81b40d7a0000000000000000000000000000000018bee24b0c97af8aec210f15bbb6acbb76168dabe16e669d5558d8d32f00fdf5146471922fa98a28f238974d327996a3", "Expected": "0000000000000000000000000000000018bf5f93dbc2c37479b819f8edccd687c4d3c4dd04f8c73762fd89d0c003674e3b2ed749d23e775f925279b3112689f80000000000000000000000000000000008a033b197aa8ea2213dbd7ed478d98c25dc6e9f91b9924f3c14124da26a67bb196926e02da89b746f2a67b14ad226070000000000000000000000000000000006f7824bdc9c53212609512858278f79d9b094165ff178e3da8776e24311bebbd9deb29f366d4c7693a15c34df118403000000000000000000000000000000000edde25fc24b9ec58b3c317aa3ae48dd5fecdf6397ed9636ea042722d264db0b1a89a15a1e16e892755730ef52796527", "Name": "matter_fp2_to_g2_7", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000114285411713eafd395ee43bf1728f52d17ac512b9d0cddd38c904a9a3a1b30283a3918cd2cc3da6a7d6b4ff923cbb6e0000000000000000000000000000000018a067f91f94b2904c5bb6900f427ec4e93374b5079c84707feabeabde20b5e49801f1f3c7504dd27da94d5e754df4ad", "Expected": "0000000000000000000000000000000002d28025f4b798083aec3ca9a91a051ce27a374b115c944932026b4fe0dcf68b335d5e47212f800c241c2d42fd219635000000000000000000000000000000001742fb6ef8e9a5a7572b0d3fa4ae8ae56c9c6f4daa20d0b88212c40511c6f6b5ee98314a2d1cbe4bbbec907495a1ade8000000000000000000000000000000000d700a511a58c1b8f11153669cb21d88512dfdacbabe38e402431b4f7ba374b5f9a88614da2d56799d39324e9d19e27a000000000000000000000000000000000c6068bc7a43d614b8f1132b13e04f66d2fb5ac0c5bc8501b754a0bcf4f382db92b0994c4999e104c9d1111ef91d5edc", "Name": "matter_fp2_to_g2_8", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000dafa9fa843879038fd1566c319c24119989090c5fd34f6514e57f633d3709f0aa9954dfb289843a6990588e337b63e6000000000000000000000000000000001742a98dd7d3671c2c64aa71023a0040e936fd726c062d520626113bed471e53ff3e85737e5abf9ee8821bae53135f20", "Expected": "000000000000000000000000000000001350c68434a9b02392e60540a3985bae8daf9a170b30336ac73afae6f892c7ae8f5f1cadfb2780d6e5961ebf91cd69ee0000000000000000000000000000000000c20bd286fc1886b9b28dfa40d1a27395cf76a8b73946849ea0a7b5e12530de13c16acef8fe2a2c247ea65ca023eed70000000000000000000000000000000002d8ffd0235fb60fa573662034d46260e0c96396537b2a9d486dd03bdd13c5a1efd2d3cb9849ed11c4376b665f378226000000000000000000000000000000000d90ca1b73a6a9566832f9f19d8530a3b12f22bef853fc44088559b923ca108cebf4291e0d7de8f25c7429d455f5ae46", "Name": "matter_fp2_to_g2_9", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019cda532e5d94f3b193b3f286a038637a736c2b87b804efd4779359db5bd95320e06d6d28da3c229ae48ffc02303fab10000000000000000000000000000000018df89e4a545bfb825bcce2f4c25f2416a72e32633b3dead5205c8b7d69c78f119d0e940e5bde9ae1cf91574e5d6c175", "Expected": "0000000000000000000000000000000013f223602e8d12c3bb51cd393f6f59beb5c55fe80c3fc8fb0bc90eca533d9b7981563a30ebd727ab6cf0111fa2d3099d000000000000000000000000000000000962b0585c681894cb701f17ec06c0c240899db574c02d82d85ed4dabd4b8654c29b84c71d2921986fc2abc542a3ed9f0000000000000000000000000000000000f0e79245e645a6e3fb88b9103ede3e6ecdd7e45d61b5755d7a8d100d80719746af58bb23d3068cee7389b2acf17f8b0000000000000000000000000000000017fa0aac84c58283f34b9bf713cde98c175b38e92503c08205350822d778f3dd5bed8051e185c495831a628aa89335c7", "Name": "matter_fp2_to_g2_10", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ad60829ff001404da40923806e496640a90c5c258a41ef5912f8a1a20eab84ce43b2b5aa4aa7dc4d8b281591d235020000000000000000000000000000000000f13dfef4b3b83aa7f9525eae9913e10502e77c03c55a7aa2de083dc5102c098b6f8e36cb5247b827e30fbcded9e2d3", "Expected": "000000000000000000000000000000001062c97c214b86518660c5e1c33a4e48923ae89ab7d8bc5c798e631de16fc1f104aa957d3e7915aee8551e24aaafc8e6000000000000000000000000000000000e42b785f17f25b87a0dc558a8d57b19d8f41767c3b4fd70c147e95443aff2d9a743003da41d578a2b56d7dc748cf59500000000000000000000000000000000111fd38cd2f5f681bb37f6239a5eea820ce3f01023c685f8e7e244fe9aa9dcbd18f0e50705faa5d8d66b28af9f371c630000000000000000000000000000000004726d3e452f6fcb180ce1d50bbee3a23f7949b635a058f12de1cf5abda19c042168feea53211dbed0bfca489a020930", "Name": "matter_fp2_to_g2_11", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010468e5421a72ec85b63f7f3070a949223105763868111424fd151c8365eb0307dbc9cbc92e5dfb296d06ddfb58d99000000000000000000000000000000000008149ce856d489050ea834452bc66f7f3478c2056969354dca8652f3d0a349e40fae0c4c57ff0f5e022aa93c61f8c844", "Expected": "000000000000000000000000000000001211bb8d3bf65b60efc7237ffecddb4e7e2f0dd36e2a704dfc9f4972897addff1a57182f8e0a0ac08c9af2c98eaa4c560000000000000000000000000000000007e9877280aad45a3b1453b6771ab509e4f53937cc6da73d3add50aff94869b27f49218fb479fe19a6176b9aadd36e35000000000000000000000000000000000ff915801695a281f6642751be77155a813847ae0237d77d2edf836aebac02b659b98d49842d4d10e82d9d146e63a3da000000000000000000000000000000000fae1c8c01a2dd94f17c660353d158ff6f3eed4e6375f1e414ade9d6fd040a48e3ff0d558c882e92e74bd6ef4ab06168", "Name": "matter_fp2_to_g2_12", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006295de7bfec61f06a56fe09afbb74be968329e88ba2e87afffe9ea9bf646ff5b4a03d6088e87644958ced95eceeea08000000000000000000000000000000001443e61dbf14b6c6ed99e1917ecfbe5a4a23ab9bdd3bb089fbba76d795d715d9d2e3c7d8db0b7a9434ad691b68bad3b2", "Expected": "000000000000000000000000000000000dd00d9f31cb5148048125668286c1790cb7294e740df978ac0bdaa6e1c4ba139a04f5770b194c9bcfb123d9b40b6acb00000000000000000000000000000000085d5f4cb831720fa13cef25464a1ba7af33abcc4079d2c5736a219ad9649ebb5dbb8687a2d3952390866587d7088f72000000000000000000000000000000000de377d773e40e1c76e218b969297d15f7819c525ce39aee5114e8405bd7361116682cf9d673574d415a7016b23b567d0000000000000000000000000000000018db26c2097f72b8788ef5aad2d7aa400627e224924afea1ac7c7a6b5cff4a55255e218572614519a536eaaf0f65533c", "Name": "matter_fp2_to_g2_13", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b14b12ecaa94f9656be54772be9b22a2495d4ff873b0bb971c27ab1d8b940c84cabcf921f6f75e93942c38cddeb87500000000000000000000000000000000019eca0daafbfdcd3b56be863dceb21e624b22c0d376fb92ba606456ce3825981713b88e40b7fd801e915f97d5c29ba75", "Expected": "000000000000000000000000000000001853b4c4e6fcdbed29c5d3aa4a9f6d447adc512f66a32fdef06c6ad316c42eb3ca47ffe6f21318ad610d0a68673d7bc300000000000000000000000000000000123d15c37fa8b1a95229e28500c9a767e6286b780138dcff2714bf1f8242f39bebb7d86e2811551914719ca90fb5615f000000000000000000000000000000000537498c2ec64b2ba58aa0a858b69990cac544d5cac29abdf6a42ae9c04061f83580b79c2a6104ebc55939d9a2bc5ae2000000000000000000000000000000000b348c19aad3b67c690512f372d995555ee38bffcdaf33bb827160d6929d2ce598523880f6136f11e1d6482a654cb016", "Name": "matter_fp2_to_g2_14", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000104a452343a4098e9bf07380a8e52050259da95f5fc88f31511a08090bda85f0a08d49cef95bd26c7181aa3eb0be122200000000000000000000000000000000012400aaec3d2f4a1a8cf3f28fd396133c3999c074a565c110354472ae29479b9b62ab67128521c2c6ec4869811ba760", "Expected": "000000000000000000000000000000000994e7b6ccafc996f672c42ab491105ffe1482e65aeb456de2213b531889773ad4d5e6ea1687d6a1f13e74878766f11e000000000000000000000000000000000b89030486a1d622c97970ee7da6189ac341b9cafbb4081463f579ab8b4b049c6e6c8b63157455770a79108424a14f24000000000000000000000000000000000ded43800a991f8c37282d803a39941d3bfbfbdc56dbf7500ef3d16750b27dcb1ad93f89714395fd3dffe318c1771375000000000000000000000000000000001994144b032e1f8c4d688754eef82cdba0018ac47030fcb77e8fd920e0b0336255d2cc8376c03e1074f91269cd2519d1", "Name": "matter_fp2_to_g2_15", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000093e04bfcbd77bc6bafeb77f02d0f794a20b155435ee3af1d667c025e7645d9387abe0ef281386339f461352da93fbe2000000000000000000000000000000000481ffec570d4e155ec10e0cc58effe7a5651795d604cfda6cdbf011676772fdce2c25227e7d5a1a26748d15b1668091", "Expected": "00000000000000000000000000000000195d99406baadc7d8740962cbbf4bc1f22b08eafb52f3cb3c588b6cb3cd89d16cb7b8d388563289f5b5ea466128525c80000000000000000000000000000000004809f70463633595dd763d658354df4f9b409911e1a0328fdaf486d76ffb410d7c6cfcc2d48fd6757d5c2a4834f81fd000000000000000000000000000000000654f8475562098a2cb27ce224674a383283cde35173e1c16b141998b641ac9ee663d766f045451a7f6d600973f0ec520000000000000000000000000000000013bac451a44982c7b1aaac7522dab598cb79b9a3dab77f4d5a4c1c97c154451499979af1f86ced8ce2099bccd400420d", "Name": "matter_fp2_to_g2_16", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013a3c5dd40f7d7fbba7563331917fe19a093d5d25ae7993200c39460e0c46d839e3958b672b4ed195300f398137faa18000000000000000000000000000000000255bc4d313fbd61a270dce8c851f1fa09e6ac5dff9b9e8dfc8a236a1d44548cb079023ee9b8f0f5756b39e44489c3f1", "Expected": "0000000000000000000000000000000016ea88d0bce32981f489438df1bc14e7ade7a45d449ee1ac1a041c1204460cf53ae5c0e111914d8af9e6b3b7fa394484000000000000000000000000000000000db571ca6a55bc8285421553a373048f7877ecb9683d52acf07d48e1026795993e4e7177490921bc6fe1e63d69c2de3c0000000000000000000000000000000011602919de1df6cc0dd36a59c84ebb8e209056534e336f5074c9ae5323f8a03b123dc6354cf85301d838b16518ab64390000000000000000000000000000000004407d30fbd632fd493055bd4d8cbed337767a2ac534411a3eabec570ba41d2ad28ef37512a7da3611ad60b6536b3f07", "Name": "matter_fp2_to_g2_17", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab7b4dec955de92224b234c2d8bb2e3881806c2d36a9a21036e9412f0a8d3946027cbb65b5dd9c975e01b3f235b883f000000000000000000000000000000000ffbb55002d9e926b3d8e7d963ece82c14afaca8b4d8415df8f964a39db606ac99f9e442ff69f7ddbbc4ae563b836192", "Expected": "000000000000000000000000000000000c1e7b188697aa9a053f14e2d907f2c61a59e0b0c72f9cce30faf81dc714a50113500ca9bc3af6657a5d214f52c90616000000000000000000000000000000001544c35d712eaf79d8dd5a22fbab72f8a6843728898412a7f305b205f8a50e03c6c462b87b3ac165e9e6428e0a44a74a00000000000000000000000000000000029ebafd90a1a887669fd0ace762a66bca2bf0a216333b0ac97dedb6bff3dda2bca1e3d0ed5fa9081c2887fe6a8e24cf000000000000000000000000000000000e1a01ca93ed268e0291a937483f7f8e252c91f9bd8bde55271b0c97fcbbb9219009514217dd8bd7e0267f44e9927a93", "Name": "matter_fp2_to_g2_18", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000103469c08562f6f72152db58b48811b0098b68af8de00e652bd5a67246459664cc8c54e15705d702d51e3f1d8ff76a7700000000000000000000000000000000059b326dd567fb2f8a6ae87f41fb22b3edc25122138a5f6732edb48ed7fa1949eda6144297f54faf406d873a016a1510", "Expected": "0000000000000000000000000000000004e8ad9838e7e269cddf0ae5c8f0f57e7467e0b6f2b9e37e7c4bcae965e9582dc46c9c50aa01f5dc761bf2f1ad311eec0000000000000000000000000000000011b1438ccc668900914578c3ec6e1334d0823861c892608817498fe2e538deec73e0034a6e8ba9790f63fdd95af3714a0000000000000000000000000000000005b4c88196425d3ecd22bfc0cb1a95488493f85bb74f50315f0ffcdd57ad2de23c137cd6d2f6f6dca8af2e3f7bb0539c0000000000000000000000000000000017066344a0f345ecf6a2ba66c37ccbce26a3f551524f74636d4c4812bf5adfabffb0645b898b10c332e94e5f2ae2d1c2", "Name": "matter_fp2_to_g2_19", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bd594d2f5e1472f85bfd550df3eb948085781459eb3037fab34186ad9a0204a0767c8fba571af858a054dc231931b8000000000000000000000000000000000087b8398406c1e707fe87a16118e2448d6a5f4fd1d6c9d7174c4d8a4314fc7b2c21f04178533480976dd20e28b278ad5", "Expected": "0000000000000000000000000000000010d393bf893d589c578df58f4d0098ad3cd10d3a1d0f112f51b132a369e68c0284a6b70a5673383ae24a27a9043b16cf0000000000000000000000000000000003402afb77b187b45906d9cce348976ed88c758d75b9962a53352a6c3ee37751a9928097c0d68c6f8a315def4ca875200000000000000000000000000000000019b98631e53a3ffda3fb9165ef7236dad5c0c8d57c3315617cbd3ce77430bd89b9e1d88a019042cae0075594514a5e67000000000000000000000000000000001783bf1c9b0ec44c9191dab01ef5bda0cb2f533dbcd3aeac2b7c6720dbc8e3f770a215ec8ea2035129711ce4b448ba87", "Name": "matter_fp2_to_g2_20", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000673dface7041c3d7503ce4a50af946d344ad48327b515740b45276403d91bf1ef9deba79c8ffa0126be990b62bf3072000000000000000000000000000000000adb42b7eb0f6759a04da7b933bbc2b6aedde47da8571d6fa32268c606dbafcbc810844017eb6377493a12d76ca56c03", "Expected": "00000000000000000000000000000000086ac901098212acd091d9c4d42a1318c3b343480f1130d6e52128d61df9e19fb61ef1ff35de0ef60062cd99202910ff0000000000000000000000000000000019109b7292f1a420f09a56dce9694cb4944808a2ce9f1964cbb6ffd14a710c35abe81300090ffcd9e95f33e0de9f879a0000000000000000000000000000000012660c4e114a215390c6f6eabc4bd6e3d062ee28d0c87e24351c7d43195253cb7b5bcfed2b4abb2fdeb3ac04ee228997000000000000000000000000000000000e56d35a7e40a86ffd2088c81488265ecc4468d6cf02d563c91611cdf8b4333cf66ef50b993fe651b1792d2b242cff94", "Name": "matter_fp2_to_g2_21", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f554e52c4a6c5a94fd09c617f57e8f87af57e73ceaee8997fc62c8ddcb2f875ee805e6594a0fb72738abd3cd4748ddb000000000000000000000000000000001876dd03316ff007a2efb4c5f452d8418edacc2881b20e8340895f6fc768d14fd89bd9db3dcfb53fa98a1e96055fa83e", "Expected": "00000000000000000000000000000000071d3e796fb15d63c2d5cf68f59f11792b0b580b85c8839a02fad96664f14735ede2edfd5ba5b64045b366904f54ab600000000000000000000000000000000013fd1ea38d32772458622731b9e2d9d749f2b747443f7e47ef5e041531b56f86d1775d42a548b2bb201228f49ec9f46800000000000000000000000000000000099c2bd996c8c5ee37de971e8b75a0bdd4f69299778ee3d216973c9dbba97c7a93e40b209d390024bc4b5e82560a1a83000000000000000000000000000000000c4922ed9af845467440b78efa3a53ba904f29adf66e8ac437c8bb6624b5e5ba0772a5639b45fe167b1fb9283747c50f", "Name": "matter_fp2_to_g2_22", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e8b2369fc2c584d78d52037b109aecc87dea0eefc2da46948b5535ad19c9abdb31aee66739f4852a2d3c51f2e7f74e900000000000000000000000000000000168b2d3e4b67390cb8ba5e48a7a823db08edee7d8eff41b88cd653cec1fc0df7a55303d3c91e92a2dc8ebdb327b225fe", "Expected": "000000000000000000000000000000000e413d72fdc3db6fc79ef26ae8b37fe5c4356a80b3598513b5173b3406ffb54708b8794dae158060a1accbe956a39ff30000000000000000000000000000000019ba9dfa74fd241a55a3b47c9f37c6ebd1e8b51f46197881abb64b7f57c0e2d8f18edee35bb9da03702c0dc5cc8749f700000000000000000000000000000000183525156fbc80cc67d6cd15fd2ddf7fb0528656ec1d31b4c275ef101dbb635424abbff1154a3ee04346ac53148fb1f70000000000000000000000000000000011da0dcd666d01180902d8a7fd7d2fbb39f9c7587540451045956108a8579d7c116385a81627dad9d4cb8cfe68927b6d", "Name": "matter_fp2_to_g2_23", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000016cf7b1a9ebafbd20c078948fc974bcca9b8069edc1ca5e8f364f8ca2a52e56e1a424ea6bcc4240f46dc7f262760bf480000000000000000000000000000000011a6a67d4501a8d9b3ab985be59ffc41e79c453bb5548299abff3b83ba9ff951025a68fe6a8ad3eef3c02d39fca8f909", "Expected": "000000000000000000000000000000001932acb1fd0708edf13c293007a035991bdfbfe0089b61c261258e8c5c10d82a5318b2af221b372f0f3f43c391421582000000000000000000000000000000000973650743f0ec8e2acca33f2ef230ee7a05635d14099cdce913ad8678458ec0dde5c5a941097af2ee0c8ffb937d09fd000000000000000000000000000000000bdaf319044101ee9aa27b3accd36a5ecaf8b80deda4548377ddeb97283537be3f7199ad3c190ed23cdb44abb8786a080000000000000000000000000000000006c448827e3fe4f274bfa55a66bc76c5b01e29ac6a8dbebd801855ba4e93bcbd03292ccf804f07f21481260c135b827b", "Name": "matter_fp2_to_g2_24", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010e53fe9fa94ca622cfa370129c1619b2426bd9d50f4b5eb8a3f681479128dbe92adde15477ad8a4463b08f1a02a62d50000000000000000000000000000000014d10a90709789b25369f0376f39b16860aee1ddc3a4340542abff0077a4af8da946cc29fb6afd9930b872ea98749be5", "Expected": "0000000000000000000000000000000004aee050b0ea07118d76f835218b77b39854f5ababc4e2a29d7c8cc7c18a69c30bb22437049a051d049c8a84f7868ad40000000000000000000000000000000003b1b809d5046054924c3814d26fd5fbdc59e03e5505813bab73bc212b0f5bc0d3fc34478311c5e1ac70fd16a01c52800000000000000000000000000000000002249a026af0b49f4659eca2c23dc790fb36a7b2996188828a17d5852003f1420f11699062932835cfe6543d454521e30000000000000000000000000000000008217aea2221f8748cd81cd37777605a95a63aba36a6ddad72c1e1ac57b24d79ff9d9c4ed71a6e3ac8a378129d5475ad", "Name": "matter_fp2_to_g2_25", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000194612afb777e39d0308a290bf823fe706487c3473412d1410dcb2c0016a70706e70e3a009c0bd61e755b1e4c65bcad0000000000000000000000000000000000ade016d06179faa8d44a9ee2542058bb81724d6af2954c0c09a897703d364ec25e62a3a917c5cecce5c96a7cfba924a", "Expected": "000000000000000000000000000000001274f676bcc05e54fa4b0cce234870ba97a0b1626543d6a9f09afebd5a752769000df404e4d434ebfd561f8335f36d0d0000000000000000000000000000000002877c9438fa319dd1a00f381834e8f3d3cdebf4e1f7690cb82559a2e978bedfd2455be020d0353aa56d435c0174b5b10000000000000000000000000000000009487cc9c7a09be901673cb1bd9a51f45e5d2ed30c90cbdd3e2b294c8f866f68da55533b78152e9ef6de30c345fde5b7000000000000000000000000000000000a3a8d4aabdb260203898655745cb695e6dc90c6e7bf0248784f8aa2340390fd5d8f1c6a98eb1990eb97c2a7f103e3fe", "Name": "matter_fp2_to_g2_26", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005aaeba19cb0baff9a8e46b901f15735a0c1f45116fe1f41c22fbe1aba22c0a7678bd4799db5cd9141f3112877e2c5f80000000000000000000000000000000003f54664746a5bc6f64021e2f18d8c175d96b1c8ce895809c0e6fcfbe896b3e8c1ac7f7556b9ef953371bb143bfbdafa", "Expected": "000000000000000000000000000000000ef415dfc1e47f39e9632ed21c9c2bfcc1959299710dcd7935a757e3756a42c8f6c627c720fd62f9c486a8e88a64c76d00000000000000000000000000000000088079108fe7d9ac93590c045be0d41396f3204d83793c4e862c5360ddb3268a63f704a9d14323943fc85874cdadaff1000000000000000000000000000000000cce908e8dbb7ec35820f2db5ae1174e0f675b21ae416fc89a7f242df3ee98764022744842999f65132229156d2627370000000000000000000000000000000011e0e2f8513d0a71b48599139a9a29c8eca090c5b02292baba58e07b1d3898fe158cdeb3bbe8edb4a805e695e896984a", "Name": "matter_fp2_to_g2_27", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010ca243fcabbdb219c5b30092d9d4595a4b8ad1cbed267229eb79a99aef9c5df03d8f24b71db77a5a76917c2fd960ffe00000000000000000000000000000000135d8d92f075c219f8012ce6aebc8e48443b2f33382479a4ca8db0a4f92041d5b6b1e5818b7a3de77a5d30be0e461d13", "Expected": "0000000000000000000000000000000007c6f133647745c312695439f1d8c251e941bad6e988cfe324ec7c959a9e0fb50618984429ff1841d4286922a26873170000000000000000000000000000000008edb220f77ed17fa1f4757a42ec66ad808c1acc25c4b9311be4c09703d547f648d9dd7c8109ffa89d01a35c69ec2685000000000000000000000000000000001595cc05b04f557ed569b19d64c09f4d82e6617437571fddd72a672d07ad94bfbaaed906b3a7e3db519159ec8d0a8c4400000000000000000000000000000000041157d4f40bfcef680af0143ccdd0c4bdd25e598a470dae844d887c398bc498edad715fd7383421fc78758cc9b00326", "Name": "matter_fp2_to_g2_28", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013e042ccfe0cbb7fa3b045a1fa1a86f199ae91721aaed488b96cc4f6de1899402f81842da2ab55c5bfa63f5b19ddce7300000000000000000000000000000000063cee89d1981f27a4f4d4f23c4d1229fd3333fc8f371ebd85c588e751307ccc75d71d151f7481ecba1ef0cffbfdea5b", "Expected": "000000000000000000000000000000000f983607a6d8a5c3b8a577cbd5d81ad2ae936e714199e3f4095cf280b8fd6d3699acf4d2ef251a571dd1ef4ba6d838bc00000000000000000000000000000000048c12f8b95f9537e56479b1bc43a121e4edfb6477fcb090a5ea60c5f4d01071776dd0264b0250902448f62800f4d2ea000000000000000000000000000000001644ba272d7003d0077991ccb4569638de0dcc48fd2e8e9a41cee1d2200aee1a849f2d620f60beeb06b08c31cd4eeacc0000000000000000000000000000000018892d773f7e48247215484ca0c8d996833c43a5291b0380c97607c86f4ab2784e692673a1da012ac4fec2713d156a49", "Name": "matter_fp2_to_g2_29", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e07265d2762e8e398c83efe1c43452d91b90b7a4271c09ff693c83745a6c01b73561ffe3da9300c8e7e1602dbaab0bc000000000000000000000000000000000375579c16a167fd9f9f61d5177705f157aa0df3451971029a9444432db119fb33b8c07de33fc822eab46ed4ae47cf82", "Expected": "000000000000000000000000000000000a06ea8e644d2d762520ad956d41ac2086a588450bc34f6d070b86fdfd73cd0734341a751d823935a009b7517770f86e00000000000000000000000000000000140ef0d6a0482537da7db8d775ac3c4a93b16c15fbe4602b5b1843ce757aada5f7776a74151d0bcf760f7284d4ffe56c000000000000000000000000000000000873c90f56a2b99da2f0a1528b8e376a5912f9cd81a159379ad70b7c10e6ebb7fea0a90d65543d968a34ebd539372e89000000000000000000000000000000000b05ff57079386e4e18e73cbff5f7b0efa329ef7355f083e8be258922203240dbb8926f7d11c22ab4c16d1df4bcbb600", "Name": "matter_fp2_to_g2_30", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aaa37576af2101d090139f562edc2a6e7169b0150af831d053a3a87a3a5518889a51871e02deb3ec154ccbe9dda46df00000000000000000000000000000000158edaeb58b99d9442d608bc8e6024365e9a81e0aa23bbbd466c9ccc8d29415352a153e1f852666505ef097122592ecb", "Expected": "000000000000000000000000000000000e9d6f9e83a2584f2cdacc4711085bd251e060f8c87ff7538ce474d663c6f23361c88971c9da589586e754ed69699c820000000000000000000000000000000003fa90cc1dd81b815704e15c0448bd0e8e8d0cd7ad51237a25d4b8a0f78f532b18ec30a108930b7407b7486aad9824de0000000000000000000000000000000000cb97bce1f75b1df5a4b52745014eb632d2d2230e52a9767e3dfd76754e98252ca81ce274b92a2947f6a65fedbaa3e400000000000000000000000000000000090edabb37f411fae1764792083c8c7412fb470833a9f7399fb312c58687d4afbdc622ecf9d74cdfa3ea87382adcdd5f", "Name": "matter_fp2_to_g2_31", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012bfaf34a8111a01d213f9a9fc90846335cda978b3df23de99cb7b764cf5db1a816f66adad1319aa7e25c0ab89e7de740000000000000000000000000000000000fed118654a128735fd39ffd3b381ad2d71479054b6bccc04dd58fbeed9b255ce2b925e2141a96a12edc3a19188d1f5", "Expected": "000000000000000000000000000000000cd234fcc729a4206233e46875a557027cb52c96322386b56d6e50d95dd9d23b6f8936ddc6f8475b1076a855c1ae23510000000000000000000000000000000010a774120f607bf9ad2d7bc498536cc9d35cefe384f88a2439a75f1a4f6a9e4b4253daff0d2c91b5915ee0e9a99b4582000000000000000000000000000000001496e7181495114abc0314f580c16038a04a8dab43b5564d518dba5f5e48112ce9daca4b16b6ad51c3af54ec9ce915d20000000000000000000000000000000002c61691a96a2120663c726d7fba3ed37524b58c92a024c15fccc659d1d2cdce077ba233a0d4419a6f237ee4e09abf52", "Name": "matter_fp2_to_g2_32", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b693fe53cbcd6f8d8c98900be1f9c85966cc644f0a900c70826c6573ee801ce7863a0b170ce0ef168fb1f0ea484b276000000000000000000000000000000000c6bd688fb883f3097f8b6fd6fd0bc5acef9341f21d62a0706fb3625a70459c45a5200ee36a3802d4bb4912030bfcfc7", "Expected": "00000000000000000000000000000000011cd454f16209b0b7040c744291f2df465ebc786946ce3cde77fe4d4bcc4b60a51573c45b8bb2d209da69107613764b0000000000000000000000000000000018a026f29fc2f81e82015ef8610b4396f2e3514ab1a213356953804d585c5cd6a3c5cffbf70d63d9dfca50129021f0e60000000000000000000000000000000015bdcc8c139e636b05ba7376c1ced4a183eb465df53b1996f4ddc8cbf42cdff4ae2bbc2d24831a8ec8b1134cff4444ee0000000000000000000000000000000017671fc3995babcd2c0a1d2a71c417fea84e29df67fa1096fe6d3ec77c45b64fb8da6ed08a57726ab314fb860899961d", "Name": "matter_fp2_to_g2_33", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ba7f82549ebfdc7f4959dc67cebde4720d76d5d4742af730d45d614133f0a7b0ae7b61ba5b914a997d9dde83b77b031000000000000000000000000000000000b4acd8c203ebd8e3ce12b10cc791b9a4183440309f24bbd60cb2991712c792ecac64d3f878cbe407fa8ca0d09548acb", "Expected": "00000000000000000000000000000000156d8823c37c81d8f03c0b2e61a2342aab6e6c9db36cadc9eb741e085de711e9fda08ca78f21753c4fdd8cec059b6c2800000000000000000000000000000000064d4fc2584c78f1e92f808d4457070b0470eb8de9d558885bba8b03efd8d8e195e4923d8e3382481a0ecee905371ae10000000000000000000000000000000008f1dc4d2ba12e7e3e1b0ef3855df4dbf29468bc99d5cb29fa3058a535af2ba038396bccaa238bba6d538498565c2809000000000000000000000000000000000fc9839b6ee876f7846b5086d487360b8faf133b6f5bd2dbc92a7fe2261b91b15aef8d90c227cd5f8ec05e32d807e022", "Name": "matter_fp2_to_g2_34", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000145f6f774d943a1bb753d5d4876b1a88a4021cb6a6607c0efb07eef2f90ba2a90a6e9dc94586de35f6047332553ce7b5000000000000000000000000000000000b892f1c8d001c8aeddf845c3845c51f2e06c3c77e543e9721d797951b6211a869da97325b569e0de35cf3beda853ac2", "Expected": "000000000000000000000000000000000d40f1c25dd57e36ed305276d4505cb250d2d9da0d5b954fe5e396b2c17a5399613243216586cedb19340e80f898873800000000000000000000000000000000063367c4a622fc925319fc6d119d8592f40f126ae05eed86ee5e4f6707b1d234c747e698c40f292dcb82ac5fe74ea80c00000000000000000000000000000000199ddbb5d4b6cd0fb9225a72c53f4596cf2597de63da56f4a9a18be8321a982de17367b0f3d794fa799657dd8ca10c5f000000000000000000000000000000000f1ed84e4fd958547d40cd2dbf16e2da4cb6d0d02763441067221890ae27ea1f689c26c900b695464ededf083667146d", "Name": "matter_fp2_to_g2_35", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001878e791993186ab76f785b2c6b0fe08588b048007c66fc00c695b55bd17b37bdba71f34ddf75ac441a0c2687711b2990000000000000000000000000000000016598f630f72a0e1f39678e1d0ec6530c4795d7565c5d026fea2389ec0ceb51b434b532466fbb1c92c1c958041283baf", "Expected": "000000000000000000000000000000000ee446310185ce76e31c13e4ca6c43166d971d9b9c539c7d0e8dd8ebbbdd9249922cb674bf6ad6840c203a5e208911fc00000000000000000000000000000000037344752896cff03bc39a9d09757a83c15fbd90f8bc1d8d58dca9b23bc00fa2b0f3f0bd7c9ed857d285825d40afde450000000000000000000000000000000003ef77f0220d1caa7538ecaef1ae2924ac1a180f11004034fc118aeac464fe1ce684b5fc90dae3370e3f79619889f3d7000000000000000000000000000000000fdfa434e7bedec071a1a333088d06299f55735f085a1e907a1c71c312bbb8d27ffa7de7ac69d421ebd675c4afd37594", "Name": "matter_fp2_to_g2_36", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000134725b4d43cb87d2e4d3c43ca98b8df257acfa612ccd61dc0aa1ca749f20bd42c38d933d39f8c3c1a14dd8fec43329200000000000000000000000000000000070ad61a7f5ff9f0b4e7483f5d56b0f315b5f6545b194565ebcf8f0b8d78519ec113af6d70550888be4d661a8403a036", "Expected": "0000000000000000000000000000000000ac465de3832452edcead434729be73be90785158617b5ec3ad53b12653e43721eda7de6742dc51d4d4bb58a291999f00000000000000000000000000000000147c39a5c162afa1f8eef400cfa1bdbe5436bc59d93973f50384022962f828ac934a4f88ab7c3d505b0bc3bb002f5efe00000000000000000000000000000000141bcdad53845a7eb2ec08189a55445059dad24ae5d39fedce869791aa28459f05a6cdf9575676cc6f3dd7d6faf077240000000000000000000000000000000010e9f539a9ced860661472f53147d0347927f065ec09bc32e00c5bc157b07f8b41b05aa4e0eedd1f73c7a287b2d0e5ab", "Name": "matter_fp2_to_g2_37", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000179bc843fecfe713f6e3ccdc8ca0f48759459b675c8b96f5403e1f6da92c2d60449638f564ce179373bce473669965d700000000000000000000000000000000082bd89b49aa62c94ecd4244b3077421569c71efccc62aed3d4bd492bdfe57c0d2cced568df5992a196a7b71bcbe5e3e", "Expected": "0000000000000000000000000000000016479eca30f48bfdaba4c8afca63ddbf59fe3367b2d3c17d15a5869dd2956fc67ebde964530926598cdcb62cfc993d32000000000000000000000000000000000650b4fd24ffbb953ccdb1b112799149d29e2377ee233b9ac97f4db432da63c98b8aad751f6060d04fe1f9262b75fca50000000000000000000000000000000004568dc0b9b430596f2fa59291ea6f923d552683ab9ab93000788145cd7c468c5576efd981c9ecee2ee0c16eca1ecdbe00000000000000000000000000000000154af1490463930d6b8261aa1d066eeda6d65b742cb53c65348e5cd766d86982a1489ad191d1b126233f193d24823b9c", "Name": "matter_fp2_to_g2_38", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fb118c86e974734fc434c3bcb783e4a7f9251d9fcfb9f4419529354c8a7a3d9f2215de2d1b9f0927b185c5b4db838b60000000000000000000000000000000004da0ce78f3068bebd0a59bc2e41e7ade737375f07d6c9ce962be022856c569a33e8bd6ae60c4bb1b53b3ffc2dcc2aee", "Expected": "0000000000000000000000000000000000df692ca763a74877352af3609c8cdbc184eb71bd35fd86334cb88543637b40b3adbb5802dcd7b88f4d722b566aba7700000000000000000000000000000000181495e709d1617f2d912f43487ad3920ac5f8e47395ec4b58bcf0b2d986c674a0c7838830a039bfb5bb59cd2fee2f5c000000000000000000000000000000000d20b482dd8aad583bd5d08ba9c61b3e954f022d48f9f4f62ddc9f5015ac71dab7d206b1d8b885d5e605519bd33d93a20000000000000000000000000000000010d3deccb9364ee386eb35c7117bab373a76d024627b8a031f96465d5f75b029fa992e29ad4a170c4473cd1df585429b", "Name": "matter_fp2_to_g2_39", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001f43b86ec24ad40552dc4874a632b4ff4663eeefe1a8c613a19a798a0ebe321a3d543e2df28277944a941b4586ac770000000000000000000000000000000000baaca6bc34feac790807b5eb5fd173c86c12803b76b50be59b2707df765bd10eb467effe34f8dc3e1e79df8a54fde38", "Expected": "000000000000000000000000000000000a007c914ed40c7f2719fc70def0d4752cbaa775cedae9365c5afb61a5e1a2854f9e1ce19af9fc85bfbfd2c33f5bf095000000000000000000000000000000000d85b0d173c25c2915fee429d2468a9eae01ba43c0f1a661f2ef83c1acd726865c00c40ccbc3aae306f93074e5e7858e000000000000000000000000000000000b3df302ec532c8100c121c9a3455392c713ec60de1f9572b040b0966f8ffb888e8cd768dcf6d63d4835a52d13a730c0000000000000000000000000000000001123c43dda8717d03fbc02fa53c4b1c9a931db6b274162cfb02ef5eec602bd8161dedc37c7f6217c8e82236f06e49e2e", "Name": "matter_fp2_to_g2_40", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005e4751707f3ea7bc7a74d80eff27a0d65cea0c3d2e793425e79cdb0c41e6ad0cfcdbb4de604637c41dbaf30a1e816e60000000000000000000000000000000008f69021794d93826f8207b96d49214b46dfb1778603634a9f5194e92481465702a8be1bc49a7bb57527fe6f963ae04d", "Expected": "0000000000000000000000000000000016d8d9b1b59a22fd830f88b9850576488f75672a87ccb766e52da77f187a8e66071130c7e71f86675f8379b2a8802c4b000000000000000000000000000000000aa4ca84aa23f01ec536ffa25c4b7a6c822f588bc75a4a72ed9237c0588ab892c8474a0f23afc7ff0dbc3b08f8e35b60000000000000000000000000000000001425e759e2537d9e5f0f356ff1d38128eff3a771fa661a839f7a8d0f548347438574ef7d592cd4273ef9b7269c9c5d7f0000000000000000000000000000000012cf1c67d1ce244ae22eec0bf4a400a0f356b9dd075d87a6e61941933872d7c0e42c1d238b2c1704d2cdb2df75169f39", "Name": "matter_fp2_to_g2_41", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000116988a869cf552b2440e16569d8b6e30c6b15430855c4d6bbf80683c5497291bac7999c1f8f08f494fcb4a989451c3b000000000000000000000000000000000e26058d72875fd3d852aa4139f71d35e1edb58242a4939da7986645117d027d20baf85770fc909d537524244da59ce7", "Expected": "0000000000000000000000000000000017f6e2743cb30fb93816d0dc802c24509315363c3652b0244e1395cb9200efb4d7b9fa7642e8d165d28a00740f1a83be000000000000000000000000000000001483644fffd3989ac98cea71843e87b8e446a3d497630419afe99b3f1729a831fa6a49bf763b0c410cfc5390ac4ac1db0000000000000000000000000000000018ad20ae5012266d771b2c86f891f498c2e90a7df19561be240319edc1fbfb316948fb3f8a6b0e3720676b076eb372e10000000000000000000000000000000012f404211899d8fc1221ab5b82db9042ad37e63348871e5ac6cdbddacda0a564888f89d22712069b6096b58c5935edd2", "Name": "matter_fp2_to_g2_42", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078c6cf89561533810b583a88149586b29da5228ced10a75257b2587904217f63499d8b9ad2d536617247e12f8d1657d0000000000000000000000000000000005b016ede9d892fbd7aea4e8ed0f1eab70713557311481735a91308fabf76fe71e44a06dc23ea66ac5d831e982f401b1", "Expected": "000000000000000000000000000000000d4d78f992f12aefb0e3a6b18fbe2411108327a9befe4a822618fecca4def3169972b4f1fb254cc4656a676529d554ad00000000000000000000000000000000145ef33250240a5c9434d4b2cf2404d9e7cc51b55e482ebc6a8aed85caa21ed00623b3cb2d76ce2d96b2f346d395dfc40000000000000000000000000000000011af2ee2514c58078da335c0273cd18b98d1ac6f0e67890677403f71b0e06863fc72611c0cfba39ac894ae500edbdbae00000000000000000000000000000000186863e7c24cbeb45f7a66b5dddc9b57c7e22c5139aa6bdb82e77cd8182bb8d2fb7bddd7d3516b5422f92e08d02606b5", "Name": "matter_fp2_to_g2_43", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007160f36f0e5c4ccbcc7900c6504cd86fd6fd700bfa79af69841e4a6127eaad467ccc93c66baf7d767c3fdb1f31c527a00000000000000000000000000000000043fe62b0b9be76a375f3be0d6ec891d5bf5f2982cb2390125ff8d5db57b6b18c5616c526102e4f615963d601d13f122", "Expected": "0000000000000000000000000000000002af4a301e90c71eb375110e7fe23f8f05e2ede86b1a9b240e8d1d4d70e96f1dc3640fca7ebbcde9918deb91f3592de600000000000000000000000000000000058b5f36cfb6b0adb14b397dee4c3769c7446426eb5719aef4965cde2dcb70e6f2fa60101a5f03517c0040093453d092000000000000000000000000000000000f77b560469cd42c5cf3458ae13020c6678af3cddf9bc559372d12bc5d6b930795e1eb09f27cfdb8215f39fb2a11b30c0000000000000000000000000000000003308985946c742af7bd7d29abc2517ff1d225607b5f11fc66695cefabd8f25e294ebdb7339949d6bc4d98db19533966", "Name": "matter_fp2_to_g2_44", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b9590b1d0d292d9967d759060a551f4e8e4c1c0066a9a3c0be515085847fa26b77462e3bae9e2621f28e01f897df0be0000000000000000000000000000000006ee7c459bb4da96e87eb1d39bd7368de5f60104f85b7b4bcdd7761ce08d48babe1bf5e765282779803bfa972d0e668f", "Expected": "00000000000000000000000000000000093c936d57135b25900bd5dd55cd579aa8b85b9c1b5e8dac6196c4450b624734d9bfc3fda499cedf2e877d79f2da650b000000000000000000000000000000001832306d3ac1c1c61bdaa73c9b6e9c2ccb484c3baa1de6a217a2884c72b72618e864f75fcc2dfaca358181ecbd3347980000000000000000000000000000000002b2e5ff1ee02657fa88c7d6f23cd4c0465152a9daad8479b4b68c97930acb22e4e2eb0011ec4062b8ec46991a7cc630000000000000000000000000000000000712543547e9d24cc78d1c2e3fbe0b51222185f4c6e513256d1ee066ba50beee20321bfd60462e2587c375a0e9395715", "Name": "matter_fp2_to_g2_45", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000044612b42a2baa9d3e1d187b2a4e048773b4851bbd7d4025e0f7f61abee703b5a563397da4515c7379397dcde698228a00000000000000000000000000000000014cbff1000bc0f9b394b18e81124dc81f80e291e841dae6e96e0c86a6f618b9f6aa6103e0e7582e5136319a4dac92fb", "Expected": "000000000000000000000000000000000f52e2f8dff9a93b2985d5c2b8b980e4869af53ce55aa48bc1c9295e557e3b5ff78896e5e6342c2d535d18b11950bf390000000000000000000000000000000013d36cf2805d350c5b748e639d20e592deb4c5bcde99a94fb539dc56d48a862151b925314f21dce4c9130b32e44f54060000000000000000000000000000000017728f485d881b861f626c9de8b3df7d807b266de6cf8dfcba262f40a6248fb5e6506d11e88f460f0b5f1a1907ae5f3e000000000000000000000000000000000c0ab998f63f861c82106dc3ed5ea11a16e98139e8686f8442047a1cf9ac48c3d34b5129263767830144e9a13d4a1f44", "Name": "matter_fp2_to_g2_46", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013da827dd718d3736cfcec53f034d34bce253bc91f7cfd6cd2666819bdebbfc43a9363f82bf4b580a7739b5dda9c94360000000000000000000000000000000010e94039f37d218ad393e88a226dd324a37e8d5352dedf6d84fa2ed2cab2f874ccc5ce94599950f91b8dd6d6c8b84aba", "Expected": "0000000000000000000000000000000003463d887c4d0aaa21acaa308d77f2c7e13d10157efa9ec3fb1586a8db5ff1a9e807c91c86afc4df34c9fcf06e8561d700000000000000000000000000000000128a81efb9f30ed811ea3163c71b6a46ba2cbdbd3a9f93cb8d0f518747cc860431c6e93bdcdf36d00f83838965da4b50000000000000000000000000000000001777802b7c41111b38da3fd8092c280b4925827b2c1592f779a4ddca71f8268858855c413fd5c0057a652155261d75ba000000000000000000000000000000000c88b522d6dc2000cfbb7052e141ddfe15c6cd7fddc970edc4afc36fc59e7f8e31415706a8121e8e84348be0b50d0d88", "Name": "matter_fp2_to_g2_47", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010416da7cfbed2768c77b80957053030d49d535b21a8a3297ab257dee0463c91b87a9e571b86bd874522149d9af0c2900000000000000000000000000000000197ef97f6d02a51b80e6f5629e88a3c60399bcc4a358ab103dac3a55a5877482558abed922585a1ce3228ffb507679b4", "Expected": "0000000000000000000000000000000014be96cfc0dbe09155ac8d8233b71ed584153e279b2b2be88471eb653aa4913fd2c33947547c61f7fd8bedbb552a8b1b00000000000000000000000000000000146b9a0011260e2646920894cf405bdebb101db12da7849b30868655fb5f972113cdf2fc322cc246d3dbd9f20b98fe2f00000000000000000000000000000000104bc20e104da5173dcff3e195f80960819a0d64e922bb484c2739c4b7c22535f7faeb1c85188aa853277740b389eac90000000000000000000000000000000019f5aec599f9ec286aefe48eedca3f929ac6c758c231182b92dc965d6ac1f3db53d93f57d733ca8425a5dde070b0dfa8", "Name": "matter_fp2_to_g2_48", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000025f1ac90f5b0748d57d8f7a928be875c5712801f70af0d057546228c1bf83d3a207884c0d66d0b5dbcaa736bfe0aa10000000000000000000000000000000017f66b472b36717ee0902d685c808bb5f190bbcb2c51d067f1cbec64669f10199a5868d7181dcec0498fcc71f5acaf79", "Expected": "0000000000000000000000000000000004ca0149527817b4df0f08acabd4e8c6329c0d1bd9f2e8211cbea25d69b84009ef158c770f948fd67e4609ccadc938680000000000000000000000000000000004101b351e2a9d34042291f38a289d8575872104bcf76f60bf888c60cca5101c34c247da30f7a8db4f0cf2f32abd302c00000000000000000000000000000000167e668de3207ddc60b8a5d5d246bf2f63ceae3bcbc4309e73eebf4d4234c2785bb13e4d5d8fff9c5f205e4fb942a2f6000000000000000000000000000000000491b965ed005065abdac53e3065781f2fd23f6159debc64f01c9f62073c651da33c05ed84617efcb5ffe08ce05e3b2c", "Name": "matter_fp2_to_g2_49", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f2dd27e3f0ab503a8752c0802ee14c655271e8cfbc734905b4331fb4e70cdfe291ff71053fbaf91680b1dd108f458f000000000000000000000000000000000c62014b7694a3e81370761e0adcc32430547a1bbe33746637e7762dc24f8d04b4bb955f17ca901659482c622d777642", "Expected": "000000000000000000000000000000001541320fb6f8a8c3c67278a7ad05ae7927d3555ad562bc8addb54c6693c51fb1c7355d2e74ff10f6bc3eb182d8f5b88b00000000000000000000000000000000172b65b110935b116ee683c8680ef0a660afdee43b9b8fce08ef3a70b352f8710c06b820348c338fb903a165cc5376da000000000000000000000000000000000df529b0e274e2e8993dd89ffef487aff23d31f502a19dd7d383de08fc77f1308a59ac5bf7cc899e81d377b2422187850000000000000000000000000000000010b40c9063d174b358637ab710d15c80d9230a1b3a056cfac4d583ad8c5b79c3d9bf22a1b0a4e0f629cd09ff7586f886", "Name": "matter_fp2_to_g2_50", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014d1491a45b4b0914a6cb2e4dc7de9d0962f5c175cd571057cae1e17d2c943954d119690ea14f5815f858d277a9ad828000000000000000000000000000000001650771e0f7b33d235f229b7d49a7a5a0f00f78e5f4abaa70f39ec452370198a8532b5873e41f17c449f9c565e6adea5", "Expected": "000000000000000000000000000000000978ff68d94d33703488298658cf2c1b6034d3d8d21c175d71a0545bc2f99eaaf131f061f3e4f55622668e686e691f53000000000000000000000000000000001124804b252f8187178435761897d00c43cf67b588ca69f97c20b0ffad3ed94acc2c0f85f900713dd6ee9f38e5ca94490000000000000000000000000000000010ca2a8ce71b9a096c132c4a060a17365475b6556d4fc6284266ae787e217b3ceaa3a32bdf751375eaf6ab49800132fd000000000000000000000000000000000a43b435b116d9480497f6b2e1bb377550cb1a7ad59e4214bffacd517afc6b7bf91112fe57b17a02a86876ea07361bca", "Name": "matter_fp2_to_g2_51", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeb244909654b3e1df7cbeccf297223be57c2f514474edf0740dff48dcd5898b6e49eb65c787aa56ef79778249f4e07000000000000000000000000000000001007c89a66dab07f54313db8682f9e829baea229b030b4514d9c93686747207939c50a198e83ac2cf50315e02642a24f", "Expected": "000000000000000000000000000000000c3d87b1b78fab65cfc853304c682b39b6ec2b4ed005e9108f69daee5aecbd586c9818c37cdee865ba53eab9302320ce00000000000000000000000000000000062a7203cd2fd04a957cac8b6b6bb51e635ed7165c547ace10f93a32b7f37747a2e63d5767d966684409a6c748d4ee6c000000000000000000000000000000000526b44af8157dd68725aa8743684e020c1e385af7413c9dcebb320568663d18b6f29edea26f2628358852b794ffcc8e00000000000000000000000000000000098126f486ff55c21f64421e85b09a1b54f42d3499dc0e198db6f3bf7dd8476cad97c02b5b366e5ea20d8f83cc223f7c", "Name": "matter_fp2_to_g2_52", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000398d86b5206bae4ceef0bcc6335b1f6bf5d17863ef3a5e8463aaa69d9f73f8227263964659d4b770d6d9813f9399b9d00000000000000000000000000000000096bd18be1176e16a0d80e60f7d7ec9d3b6162f683440e3cde70082a73605da3783c8a058bf76d7e25056f5cd95c31ed", "Expected": "000000000000000000000000000000000f3e76e7d1cadfaad08d16457b02d89c40c157225eec7916d306faca8dbda008f41792888c647dff1acb4d4ba3b43c4900000000000000000000000000000000132bf730456e2afe745a58cdee689e37223292bf682d5b7dafa7df99e40d385559d0b3161bdda0bf5173c43ee46412dd00000000000000000000000000000000141b36ff6890e35db0054358bc0731b3aa0efac1a247a51daeff3515746456216975f44769174a4be41c109d35e4be33000000000000000000000000000000000ca401ee1addff8fe87b600e057ae34ba297886f92c5be8a8c00b360ada71831e31bc4ea1c309c7da31cb28d1011ecad", "Name": "matter_fp2_to_g2_53", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004ca5cb60c32edfa385baa911ccb7fd1f383824c22b945944b0f3f7011db8c123efd8fa70e4fe699d40c6716021f0151000000000000000000000000000000001339adb0dd8d83574c2008f0a7ed001b0808d2fb639b5e57e1d293884247d5c66c948ecc60caeea7bf440a3a44ed296d", "Expected": "0000000000000000000000000000000009d0af77517b654ad97de3ee1dbf69ec1eee901facd0f8c39b4af393d0e63957292a7529b461f7fa58909acad32ba3a2000000000000000000000000000000000fda17cd878ec0f8c294daec1bd1d56c63e875b002a81c9c41146dbb564bab6e4eae2717c9fd718af1ba816a1526e8fa0000000000000000000000000000000017563b7ff22b50b6d9e24b1e0d89ca5c72e68d4d3cc24cce36856191111d087c3dfb392070462dc7850ef5a1422931c600000000000000000000000000000000020001fcff638504055ba35230b360e6d3cb5777b959c194d6f9b038b58d3ead0b82b28bb215378abd85d357b85ea260", "Name": "matter_fp2_to_g2_54", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000089211892a61202b1ad3a85aab9f08f8d028f3e3deb16c1de4d62c1a403fa63c6dbbdf8cec37f0a9d6f346b1c7ee179d0000000000000000000000000000000012a9fc2070b326f4d7e64804b3a2e977f4bb36b6a4afcf27252af757d8535e8172a99dc909fad5a3ff8df23d6d6c5948", "Expected": "0000000000000000000000000000000000d51c77c2443f00d965c0d7ec9b5a8a8003c2a77b0ffce3e47bcb55420e8690a9c2ba9235b62a4b351d79d216a3aad40000000000000000000000000000000013cd46e3ee6cbb3bfb771ee30b5f5faf0a64a9efa1f8fc57024c83ad07a9b25e513f211ea604cfdf319dc42bf4c067d300000000000000000000000000000000009fbe1fffc67220067c948e0c80de23795e045fbe8031c9010eaa69356ffd8e5741cfe12731ec13aa236630f1b1dab4000000000000000000000000000000000e5ecdf808d10d47f041e4b078e79b32520ce9623b50059a3bd8b59daebf9103c31425659ecbaebfb2384d1c2f1b400d", "Name": "matter_fp2_to_g2_55", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b37365748fdb21fcb46f94edf86c586f17d0e042c4683e68c6cb83e7c0ed2c30ed260c15af2c9dce77bb705debfa7590000000000000000000000000000000010d7c02c6c1ba3cf6ac09a05dfe043905e1a7eb32b67f2e8a5dfe82eaca66ef46cce43aaadeff58ca85345dd0d3bf3cb", "Expected": "000000000000000000000000000000000f3e4d2559261829c0f4816f8b571170de1f74d75d74997cba56fdad42932db73504691f9e001f5b4604705a8c1a38e40000000000000000000000000000000018c72136bc7d3050ee693270668e706ebf70f990e447ecc6153a10625cccc9deaf5ae82d2a656b1376bf33b1c1fdc2c9000000000000000000000000000000001754f2725bfa76e92a74ad5b520ec2aa82a1f86e8623a054ebba489adfc9e71d1f14d4692ff9fdd8acc3d768b67e1b7000000000000000000000000000000000096f1373434a8822569cba0679dbd2abf619bd9a8c73e54e078688d4e2615d45431ac8cf3da5e15a83fe77d14b339e49", "Name": "matter_fp2_to_g2_56", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000aeee59421c8ee65f8070b9d036e6bacb39dd2537d02960a3a57da4f0985cc7b27784d60fc1613f5a83c34d2250395c1000000000000000000000000000000001715ddcbaed0a05b38b1c820724405a713cc0215a4c497892f00746c0f9af28b440a3686178d9bfcd41944a224311306", "Expected": "0000000000000000000000000000000018d515b8c99f541c7dd448c3564c1909b84517b662d6a2d1176d3bf5e70abc0a2995c73ae3f1614bfed2f64229e173e80000000000000000000000000000000012126ab671420933cc4fa9206311200cc5241ca3eec54f5d97a426a72642bdde32a65c79735446779cd1744d112d544100000000000000000000000000000000190d836312ffb0d6bf493f4c942263922659abec46ac4de639efc311753148b445509f808c2fd813729b1bd96e0e663f0000000000000000000000000000000006494f9a451460ac658ec17710bef79d59b6e0fca049804c0954c5fc472bbef520f75d34408ccc62cf2da3deeb79acc2", "Name": "matter_fp2_to_g2_57", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ca4b3e1a8351057ba4a2ffaf0cdf1c3c0717ccfe26433f6c40e2cc29e32ed884f63d25979580fb555a5a86c9147bcb00000000000000000000000000000000010c1db593af38aa14ca9dd588f54b219ff1fc9edd25b3d16c595662ffa7939879244326b14d978e0dfdd25e37776964c", "Expected": "00000000000000000000000000000000173fa567aa952bfaa9a60b8232a185475cbb36761ebef49ea5fce900a06043d0e2c1b6024e40eadc9f4bf04b077201450000000000000000000000000000000010fdc32ff84f79fe39351cee1ed6b67dbcf2956020e2518d5bb5b367b61f86f1bce36f75516d9551d74cc3a567e6c2be0000000000000000000000000000000007abdff8a8967eccc4de6b4ce142173841c0e8399f5a67dcf0f7b5e5b4133391b44bf4d41d3ae3426839b19aa4c5d40c000000000000000000000000000000000c99f160062566418c09f10eb80f005f2c8c12825435f354f1d65bec0322e9b8ee968c009a84ba792a7ee7334b32bb3d", "Name": "matter_fp2_to_g2_58", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017cd94e7e672f0dba9a3c1db742d87cb18b9401e8311c4badc24f811a8f40c27942da6485807701c1a12da58076c756b0000000000000000000000000000000012f6de4ac9883e78f9d658cede4c70b44bac6b4c9734cbf24298ddf0df0cf54164aca245d8e313be4aca66ba3cab5d70", "Expected": "0000000000000000000000000000000019dc92f1da66d0855ebc8e7a2ddec623a2f843a97c7385364a631671be7ee3387a0f98940b5a51c8d9e23eb27e3133b00000000000000000000000000000000008493903c5c68b2847869b8c3b0fa9b8ba15bf1f11a40a29e6e82942e2910901044254cc8e8c3c3bf56e1f1b6dab7e86000000000000000000000000000000000bd3c1e302a191094059a6493e59a11ab05a49faf333f36f7680ec9b1043e59dfd7f0fabe9f334b97cd638dbb8bb664b00000000000000000000000000000000141c9b07ff33b6ab55b320dda6be54320082f0057c446236cf3d3a51e674c26a5241f2c702d9989adbae9045942eeab6", "Name": "matter_fp2_to_g2_59", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001b2843d9852feae3145b242cd0999877c07785bc72cc2626f388dca32edfb112bb90f9aefd6953eb15a0babe748573d000000000000000000000000000000000a69bfe809a67ee853cb96b5a7a72798748cda56936e5664d509001544539730f57a7541ecd2396c9225818b9dbfa3c6", "Expected": "000000000000000000000000000000000d0922466c358cfd756727e134b5e64d211244587e4eea036f0959e78570dce3ee264c703cc356cde20637c7560369340000000000000000000000000000000011a66d618f79fb662ac2b2d3b50750a5567e36d7092dfcc72d8f340c04df75ecc0ce4a01b410ea775dc548b8dc66c3d8000000000000000000000000000000000cc49cf4be5e2df6b43054092afa2d6acd66f5a43ef0667f6a2d660beb7fec70558ce02d7acbcd090df91fe833326718000000000000000000000000000000001270b0519db083f903a3dbe0b1b1bd5ce0b0059ea2c2c50335dd80b4bf154fc23a3de1ea753b0e279145254d8e5bd045", "Name": "matter_fp2_to_g2_60", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002479a989dbf27141bd9f467447218dfa6ef60781a7231f089d5f1f1d8dca2ce9606a75c09f63f37f9cc1ee61dceb32500000000000000000000000000000000037c2f1b96170f6847138232bac663e4940bca602717c877f58ff7f5259778246085d499ec6bbeaade18f738df333cc7", "Expected": "0000000000000000000000000000000007826398b4ec35ab58ba9fda5c15ada2a41d3854677172ef6a4a54087b64d0f73fc875ad62236eb7fdcbd94f14c8895b0000000000000000000000000000000016b14fa92de5f6e43988829ea2f851746efd6680b0ea1283264f803c8ffbe85a343bdd42225caefd1b94b8b311d2f4950000000000000000000000000000000018797093ff82bc10e6db60b1da50b9a60da01d67673e9bee8c7af2bfa2d57f409f7b06f53944938e5c73b049c2d3c6500000000000000000000000000000000000c66dcc3d30f35c21b8a9369c8f6de28af404e8b30d3c9a7f09c461b0272ba6d5a29e716012536dbeac1d9672af8427", "Name": "matter_fp2_to_g2_61", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e6fcc48312831b910e52aebbf19869b3b32f05db8310b68905bb244ab784df5732db2e72183de5d231d803d92aacff9000000000000000000000000000000000f61f9e52fe3afc2a6bf12e420cebf83bc55a449d6a167779e5b6ba3281c51d790a045643aa75f2516eaf6ae2a816ac4", "Expected": "00000000000000000000000000000000191aacce60a1a83f2c453fe196bbe5839a3a1178b147580435f7de8a2b0b4f65b3e280ac7a67570aba0fdbce6c11ad9700000000000000000000000000000000075ddd6b256f53a6ae6758a5158508540aa99b78ca069378f0ae3f5621ec24b9acff1f9b61d378334a63682a33fb0561000000000000000000000000000000000b06e11c9f858446fcc90c69d05cc26c33bafed0feda19adbd838c9c24bbf567b673110a1b248d0ee97fc682e561298e0000000000000000000000000000000018c75dc203493e12e1523af50f85ed648130ce5d3e9757f713850c867cc95c7acbb66c9733dc4f53d6a0e64bfaad5832", "Name": "matter_fp2_to_g2_62", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018efc6d366d79a09b7d56c81c17c2eec2ef7395fdb5991f41273329cdcf4537d342bddd83c3994a40d5c18f6afa054c600000000000000000000000000000000127021ce28627a9d6a492720f728acef3b38c12b951f70a932c7fc0ce3f5b6c80783351cec55d7d1bc4ab964bb4913b2", "Expected": "0000000000000000000000000000000012931f51430bea6e96f8ec456ce6b3c9e058b0bd3bbfbfe8b6e84fd6110c3bbbe0001018064e8981797f9c93713a0e4400000000000000000000000000000000196b6093dd2276098853ef2bfac84f0cad06b67a12484e98915dcc756310b818d8136954de1b602eb825ab29a143cf4b0000000000000000000000000000000008284beaa877b25374571dccb218c401cd905b351dd96700853f01920e409d11c4e440e90dc175cdf0fa807cb9d1e93a00000000000000000000000000000000063c6c238485c291fbb60bd2824154a9e23dea374292966d271ae94875391b7ceeee813e3fb9504223bb86f0ea3b6cb4", "Name": "matter_fp2_to_g2_63", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a0277228ab4e880c12f957a6fcdfe49e2155083f3f93d3f00c68622415cd1f5bae183b7df9e08328a8139392772cdc6000000000000000000000000000000000de0ab426e56029790a5ff72f34da97e11c028dc5d31e448c49ede004102804d2bcc36d509640247a4c8bfdf5104a781", "Expected": "0000000000000000000000000000000000f7bd0705cc4ea96ca38314cb85963044164b83a506ffeaea6e5eb8f7c4967cab1f1658f33b5435191427aaf9605bbb0000000000000000000000000000000007a93e2a5c118aff6ceaf2370ddad52a82854946ae595d384ee0b2b4935a574ba758736d84b0ae792f998ec6a707dfbe00000000000000000000000000000000090936add00fe5c7556610b28ecb4466ffc37b95b5cab43e072a585920b3cbe70faad01ef75d1dcb4f7d00d900bd99600000000000000000000000000000000006ae82539c68b7af3143e23229fe320924472c2b3e15a2e27e94cba674d30f083dce94706da094435c53285a43f89e56", "Name": "matter_fp2_to_g2_64", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000170b243c5aa49a0134bf3d6494cc1e55a1c6ebefc6117eca3b343a48ef0a2b077c443ec5b9201b198df015a38e66b7910000000000000000000000000000000019a8ac8a3be1d45318801bb0a654963b312540d24aafec46bb7661cebeec27b0b345275fd53c041d02b1ebfa27fc3854", "Expected": "00000000000000000000000000000000024c1b869fc13191b71d7159a07e869f1b13c11c73231b82e9bd0a7b4c32d7b376fb73d54f7231dd4974713179f235140000000000000000000000000000000012b9f95af661e8452aa5026302a7c28695307f75e9e4e32365caf378ed394fcecc831a3c47b443172188f4d18338fa75000000000000000000000000000000000f52675fb4d112d1d39ff953a253b22dfa0b73d972e756ea7fb673bf87aa992883c5baf32be6f50f880b03dcb740f06c0000000000000000000000000000000008b57726e17c873e12834dc291cff6bd95307f50e7b1d0caebd8c1eeb6eff4acc0520b135bc8e35a257133b7dc640db2", "Name": "matter_fp2_to_g2_65", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fbbd5a10eeb2f358f2b167f1985d4084c4b12accb1520d780ef1c52f6fa80e97aaf190e7a7b241ef96fe8289fc0a9600000000000000000000000000000000155687114e7aa786ba27aeada830fc705aed069c4e3a07e88d7f33923319f416ff3caf6533cbb36e5bbb1b93a191bfd0", "Expected": "00000000000000000000000000000000061938df3365bf910884ccbd74d3cea7c30416bddc1a9b65e7723c15d89aa657da36a45fe10ed50bfa0c2769bb98aa2b0000000000000000000000000000000007b3981054255715826cf8f247210521ac681305aad3928b69804117fc143c5101383eab7017127c8452a79003a857d60000000000000000000000000000000004c745113480fd87212ed3ff30ba43c8716b32e62c1f0091bde53bd4a8fa8fe6bbcf0904144f4791ed1bf12dffa1f17a000000000000000000000000000000001237ba297c7f69e5e240846a12d86c8276a9a6ceb4af977edadc7ebfba3ad3f4ecc0b875da0ea578c83fc3b91f9f31a5", "Name": "matter_fp2_to_g2_66", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000115edef357ccc3432226d9bad796a42b1a278d9c8adfdddc5a0f8a36d32ea1787183877f8b7dfab71424cdd10b63441a0000000000000000000000000000000014b369ce61abe60d942346e049644b95a0fda96316446b2fe7ee427641af52fdd2a654bf125ff6c8c7f3dec98f6cbfb9", "Expected": "000000000000000000000000000000000a0cc3e328b4cfd01afe53dbf971ad78fc74d951050d76210e4c84438109622f0531747e762e185e3d7ecb9faa7c3255000000000000000000000000000000000622ad6092caa727d069b8921f4124d5996f3019705a908ef95d23092c5bb148873a22c227aa25ebee361d4184cc38a10000000000000000000000000000000002938d2ff50cffaab8c056c2844c50013f5bcdbb4f91b3f823836edabb39ba17ed1b8b5862301efad04bd2f5d5bf599b00000000000000000000000000000000072e96136afebbf8c06a37cf9b20c85ef8cb3f7f99d5c71b05a187c193711e5b76f52863c7ef080a1b64b2120ab2ed84", "Name": "matter_fp2_to_g2_67", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d22b7b36ac66b10adb4570f8e7521ed76de2df2a7b94b2d0b9ee4514cdff6fa7c74854d16e7e70f054a91df93c7ebaf0000000000000000000000000000000016867c9cba66dd9f1d0332d31c4e46f8e393eeeeb19af7e6e01effb29ad999b3086b599ee4b371de557d4fafd5da3794", "Expected": "00000000000000000000000000000000142ceeefa9fceb903b25d4dc68f6755833d7529752db0f125f7f65f2b7aeea8c90e599ac409576e82f7b9d6f83c43aa0000000000000000000000000000000001664acd89b482aed04ef40bd4d1ff9f39c80d7738771e2b3ca731af01aa230d865869cb05d83992e94ad99549fd0b8550000000000000000000000000000000013d6ace9b492c014d9a7504b5abe442e3bba13b1ada454aa53177990ec44f616e091f1382d36db87b7e794c11570a9bf00000000000000000000000000000000081b7a8a2906435f8a9242f573225ea62c5429e903bebda9fe9973a18ed2682185d72aaa6584b9848d1cc45ac907dd27", "Name": "matter_fp2_to_g2_68", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000db9258e1257e659e60bf8569ea90c8247a53a1d1eb958481623447a38d0f1f1686c3e40c8f15bd06cf5be9c02485452000000000000000000000000000000000517c87f3df032ff08d960f524939e66f7fa69b4168b0f2507baf7d7231a70dc5690a02d317b26f219365ac3255bee78", "Expected": "000000000000000000000000000000001182e4230f0c360c07913349f89f8436c01841c9615348a0d7057336c7483342024b0369ae52f39d4582f9885f552b5d000000000000000000000000000000000d15433ed130163a85f8ba87468c906aba88ef8610fcc1a8d6b3308cda29907acca351fd7fb19799184f1ad91c751b5e00000000000000000000000000000000111089005c4c5370863b0ea6b629197a865f978f71becb741f50f9b4e49b13162ca63c29aa26287faa9c923f57f4ad4c000000000000000000000000000000000dce405ed2a79ad433123105ad01a26ee85d1ba4e5f3b4e0339fea787058c06e9a6b10f5ec8f6eeb85b211e18b6ea076", "Name": "matter_fp2_to_g2_69", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000b6573c743989fc8613d4ea09c2e500ce965b50cf0c8975ff703116464082efff4b42828c8337809f6938d7cdd3f66e000000000000000000000000000000000896d316629c80ce6e5f240535863b9e064728665c0815f39b21675c236f6995e7dfff1e4aec9ad05861e2122469ea56", "Expected": "000000000000000000000000000000001694cb615d2994a903a13645ad44a63395320f286503902b6009e7c795dc8f024260e0c45bedd864edc9fcb9d1ca6bc1000000000000000000000000000000000f20538af015bd6d213f90fb1a1ebde4d9e2ab2defaf80d791a1f70af2ca7ea1598d43e9eef1cc982f468cf15d223c9d00000000000000000000000000000000046c62bec4c6876a67f5fe68107d677db8fa4d59ac0cb7afe6e706864c6e94744bedac6b34a68e8ebf89c231307b86d3000000000000000000000000000000001839f3b8a6dd8fe8028247670fe5b491bb43ea8fda53116dca87f97da96573a5e701a703fb5fa7bca457ef88a827e061", "Name": "matter_fp2_to_g2_70", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011fd2ccf6883b78fe19cfe7beded503cdbe1cd5dc9ee452aa6b329d2237c2529df6774334b132cfeaa616f20335f88680000000000000000000000000000000009eacceef036ec500e7676f54af703016fac93d69ed19c8943b64ffed2db498b19cd255a0a3437b568eade0f497c7b17", "Expected": "0000000000000000000000000000000009d8725eb8757828a94969ebf40545a62835686897d4504a66484a3078b2f15e39fe918d8dc01bc7560dcb005a7a0dbb000000000000000000000000000000000954a6cc9b2dedca1cf280f72fd0625184b8f83b78ee1ffcaf0f9178ce97900d759e4a74b914c3ddc32f84c3f4c3a8d60000000000000000000000000000000014121b83d2a06390ce7359e570e1593d5ff097cb0e44c38bc74171fbd8a8da0dfffcc2bcb95fb2d80a55933f696a86cb0000000000000000000000000000000016f71d24256de70618a02b0f016c6f31a21d2cc42855886ba30176584a028c2e12367be19b834bf41356cdab21223314", "Name": "matter_fp2_to_g2_71", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004a851380536054f6b69ef7581b57dfd753d1e6201069bd1218ae5766aada087b4b08f65d43b3ce0215640e8d34633310000000000000000000000000000000013579671b64f2d9a2c3ac2737cf95c2148acce3dcecb3db6d019730010c50d1c0504ba4ed42d93771ba296b0b07487d7", "Expected": "000000000000000000000000000000000cd47f0982904ccaf4f3cdaa37091a08e67a5f04af09033b864631300bb6c2aacbad105eca6ddf68a643976fb555d3d80000000000000000000000000000000012332ddb0e91f0ef9e085f21634c6d69576e60d3d24732a0c91a560906791f60f79d09ac0ebf448bd39f047b1dd428450000000000000000000000000000000000a756a869b3cbc5624f0e08019170beda35fd2642a79108b284a503942f8267b75868636302e5a12b4f1505331b15f9000000000000000000000000000000000f60724f6c8200edff41f3299ca003e9ea03b97b01a3e8c63763bdf67b9f7677331a7144915312458c40d041be97b3c8", "Name": "matter_fp2_to_g2_72", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021dc1dedded9b0dd90afa9ab7fa8f9c33930fe4ae68185ea4cce9ed97ce4cc9ff93f96377b11f8d42b02e759a10b06200000000000000000000000000000000034c963fda3bb80043d6d7887661ad59b3c31c88c958b451a8e11684770c132205db6655ad7cbd604ecc3225b0c128b0", "Expected": "00000000000000000000000000000000095cd509e53f10b1ee18b2120e2d18f0905a202a992a9c62480beb6588275fc8b5b151e6abf17a12b6d9cd03a8b37a59000000000000000000000000000000001723bf1a3d79935eb4b39f7feaa1e05cd8f3e7a32e2c406625053d8d8fde33eefec231ee00adb00b0acac16a83dc77fb0000000000000000000000000000000004af528e886dad3f9fa7232605936bc22a6a22622828367791920ec9d31cdb2f290e37f5fc79efaeaf96c86b3f6e39220000000000000000000000000000000015bada14a84fdb09b77397cd2e27836f9f88854924af0cafc6f9125d32be848c8325a3eee1a26de8be8eb80b601f1ad5", "Name": "matter_fp2_to_g2_73", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003e8d1be04f8dbe5c7e1c7553cde8355ae16d26c819dea92fb543cbd9fe9e726359e1e4be0483a7720343f34c6a3fb9200000000000000000000000000000000062bc5fdae812802bdea09e4130c3d9bf80c7518138b116a4b6a302c155b97226a6ccc8a3ace18744e7adece08781f72", "Expected": "000000000000000000000000000000000d8f14042f36bb377655b63dbc37c50e0eb5775d4e4399972a6758cdfa9751cb4b733745ed1a47fe5f2cc434efc5af81000000000000000000000000000000001384016829d028f823e6d062898c042a461bca13ae4627c983d9b5c9e8b4ffff7eb25daa1c52b39e309b9c1e7e4f2e920000000000000000000000000000000004f7904d491a0c2018b1361a9cfec4fc829e607402859fd9b9ded60adcee51e9b522d302f9064130a4eed1327f49bb4f000000000000000000000000000000000ef4fe949fca569b31fc57ae7d0166ea53318c5712311076e052c2967144116f5490fdf56f26adf64aa01beb4f6cd214", "Name": "matter_fp2_to_g2_74", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000014b922157b19ed9debd9ae95cd9435f7980b8d4ea33fd29f99d5e7fb1a96f6d99ae13f7f86239c4bc286c3927d3522a000000000000000000000000000000000f6d4badf78d9115d93783a59ec9576fcfd87a2c29e1c506b6f7e313e71723811a36d64b37650fb6f7b460105a7e13f1", "Expected": "000000000000000000000000000000000f20b3a6505784681331208b573d3a241706692db71b5daf4e9c80adb1fa9bb87023d7ba7f9c65158653c735dee9dfdd000000000000000000000000000000000f7f357407ca6cc5c5fae4b84509d71b2f4de9af226cb4038b4820c0541d4999b7396608efd2f322a00a768129f9800400000000000000000000000000000000138dcc1b9d978adb5eee6356980cec5d18cfbfbf18cf6fd14f4119a563f473f5027af06342e84ea858223ed63d1a16af00000000000000000000000000000000012b63f0d2e8ea361d55aa617a99e066b5feef3af1930b83d2a48b527e0ef304ceadf7cba1415db80c54fdcbbcf66d14", "Name": "matter_fp2_to_g2_75", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000005a54ee5e3dc05c38ade7a42c71baf5a1467938f97c0cdf0742441cd339f22542b1ca6cd215d385b3fd6ba74ec996a4d00000000000000000000000000000000051c6f0ce621e8e27e5017628690fb68f0fea27d67726a0a77b0caf9f524936e123ff096168ff2079b9990c07fa80354", "Expected": "0000000000000000000000000000000015ff2aa94f802d8f9c60ddcb43aee598239cf3ab7f90f8289a487b673f6065f8d9bc92bd4cd28df4a7b0d3bb78fad243000000000000000000000000000000000884b5d4ca3c8abea737cfca05878528890b6cee9bbac0bf027df5d4e0add431829caddf4c1e001818581ce08686eeed0000000000000000000000000000000019b91a7738fde9760240b335457955e963030848e85717858f22dc33ba5a4721156cfdd7341aa86d10d268e2fc9a1d26000000000000000000000000000000000af85e60161795906f3cf705f5e8cb8c15083a90836eac78445c6bc27ffbfc8c2df3009b436989b46b271dd8d1dbc282", "Name": "matter_fp2_to_g2_76", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000094e958d9b7dac39fa4f0143a333b2ccee09046cd23e6a1c0712470a3c2e61d2f8b85aeca37350f71d7ec75aea2b3b6b00000000000000000000000000000000080743cdb5e359e8b8ad3485d53ea286669ad66d841945296edf80dde77b20a158e2c1529dfc33a1fbecf177d75a0c69", "Expected": "0000000000000000000000000000000001bd1fe6a6c373cfdc2bfd488b0c942492b77d55b2560824edef3a91c711ee336bc1366690be40949d04edd39ad48a7500000000000000000000000000000000161476946a5687113c74a34284f49b0658e323fae57aba88b039eae584d6ef28adca669fb083a2fe8f0ef664eb5b957d0000000000000000000000000000000007aead870ae09a04cf9c9fa49d0888f7010782cdc5a0ade4c1340ff15d99cb39b7412d66d4147b95601fcf5a39c39bca00000000000000000000000000000000095cce83dbfec12973e27627bfb2d93fa9a027a2c2af4259a0879d6bda055d74559fc93fb3b4f6b0088f702af29a7643", "Name": "matter_fp2_to_g2_77", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000dec04526dbf7666d2c29db5de1ef0b3da85380a171d871a57ae3df364d2754fceabf9d4d2a3da1ecd94e377abc78430000000000000000000000000000000000d19875fe988ffbd0cf1e9bfefc7019579962ffa3a585ee232615e4a5fce0a07bce0537b203ea00010a90ec05d5b8de7", "Expected": "00000000000000000000000000000000133cdf684c3ff1cdaf07ff787b57a66c215eef06acc2aec4d726a086480e7b2a5dead2cb357d99e298df32d4c6f5029b0000000000000000000000000000000019cd65b830fb17880f40e104ed63a7d49b0fbad8eead7502f18f1b9f85f3f6ba6c275b8a242effc61a7a5d770a4fdaa700000000000000000000000000000000039aeacd163862e476b17a22c76042d7896a04f158489ae71afdd35d27106a3ec276baf5c08e3eed4b3f0a79c3c458d200000000000000000000000000000000125a9bd770c1fea2155a581211bd71d55eb1966645cc892a05d32cf1e4e5b23278ea2fb1336bba7f2c887debe4a93b52", "Name": "matter_fp2_to_g2_78", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000016dd03f0df71b183e42cc29c665f18d57637b65f05df85aed9a0f7b8aa37f7913f6606c10f24a7a8c570f485905583a00000000000000000000000000000000161e62d8be678a114fd4a99a6caeb9481f5eaef145571152fe8a6ed77a34c06a1b6ff66044102d19a94abcaaeb254e73", "Expected": "0000000000000000000000000000000007843268081f61ad2b3f6653336a99086381bb4da4c23b7d59b9c7827f2d4c196d136508c8a1f3d2f939e8c9799b95e10000000000000000000000000000000000e2c57ad95f762115d8230320810a4ea9978e26ca17decd6af4c112789608967a92fafe3fb3e79539d75d1c0bae97740000000000000000000000000000000010951c9839db9dd6ca5ef95bd1b1b9cf60bfd97cf88129fca23b24f19c9d5c71486dffb762e92f23d2a9e9d462556f620000000000000000000000000000000013d35c17b3763fc5db46ac8c44aef996f3f876c49f5278b7c97e844f23ac49f2d50b3af080322d30ead873af7b4257e1", "Name": "matter_fp2_to_g2_79", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000036efffcb0c6f42109bf9b8b7421e32fa3f855373345341e6000eccaca135ef3b2e1c0151bddbd46ae92185acb847d74000000000000000000000000000000000edbd7a40f3e688eaff5e29800159b8d799df07e81f65d59011e84329b4689a28a15ce11537fb560df705be26bf14b1e", "Expected": "0000000000000000000000000000000001aa1919a50b5bad62b839d672d5a11ad345fcc61f75eccc42990e113deb8a486423d1b27e7c81536d8a5799986b9408000000000000000000000000000000001879295d2f7bb3923ec61c063ee4f96d7d7cf7786259e2f4cbc3ccffe7e114af264b3527a5e06dcfad50ec1e2a9c1ae0000000000000000000000000000000001042632662e406c95f3fd44a6d956e526907147e7e6d4219c1c4b28a31e479974d00d4ad6e683f6a834d3d4a20830f4b000000000000000000000000000000000a29ea98ec25e7827bcb349ccdb2a57926809f3cce44d5ff6cd636460278c8103b0db78fa580e9edd4ecd0bdb21018ff", "Name": "matter_fp2_to_g2_80", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000974c7d17cbf91947ad435b30ad2b639671a43d67da6a4edc7f8bdc11fe817d4d42f687dd642a2be89c81bc36e8df592000000000000000000000000000000000efeeb85860877abdabae35672a77ca9d2cf0ed18ed209fb905b591a841c900ed06d2c32c56bed5f7efd469d369b05b8", "Expected": "000000000000000000000000000000000c67498c6751cc27d871b8711c4739398c501a5bfb688d7e1a73dc7db5c47c3e28b633078cb83745bf5b0d5d2dde3ce2000000000000000000000000000000000c205c03305422bd44082715b90e0a0ec178003d6f5e14a0d13bb0f2c38f2270816b884b4870b75db44ab080f88a35e2000000000000000000000000000000000257f378935772d326710ec6efeb22f8c9b6b549c8a4c0205b75740047d750d73da4e71aaa8ff33b9bd8ab7621b08e62000000000000000000000000000000000c386a15f09c849be9f449a59e1332a1e7f16a9394c8de198c01399a05b0f963921c4c57d49916407ae0d202af8da32a", "Name": "matter_fp2_to_g2_81", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015333364f4d0d173ef35e447fc189b9d65ef71b9fc4ecba25fb6c8c1bfe8467f26bb9c55ef10bb34125d714b94aa1df1000000000000000000000000000000000cbba9d8ac191032f03c0746f13108962130c9e2c01d47f01174a4c4d3daa7631268f7dcc08dfda317bd249fb6e73e8a", "Expected": "000000000000000000000000000000000864da537fd94a9ff1bdae733f01e145dc97a894733d0811cd67c2648ba61d0b187241f9ec69d8c011f514894a05a608000000000000000000000000000000000a53ea4ff9c0ff71541ee21127a33daff2b39e74301946a86e51dc7834717e7d8784cf92fa5845bc0613b6b869003f58000000000000000000000000000000000582f5a1fcef3067dfcdfabc6af33871114538abcb02fcad761cb496020c7b423fc52f0075916f160fbe03574df97ea4000000000000000000000000000000001244ede8ba0dc09aacdc5d9f886e59bf963a25885dbbe2c3d1f611bfae82debc556ec4c94f0606492c7b8c7bf976ec34", "Name": "matter_fp2_to_g2_82", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000781e980c167c982c2fc8d0baa3907bc5499eafca675ae20a10b25063c9088fd06f6769df505e5900bcaf99e266c052c00000000000000000000000000000000183c12798438ea92db75d5bf76cf29d320fab3653e4131989205f2817aebcb1b13f161864c084fd13a11459d7d5ccd92", "Expected": "0000000000000000000000000000000016c334aec0e19934665596f0ae37eb398f1d6f0d0c9f08189f1ccc219230395124a9da03858bdba13ec5366da54228af000000000000000000000000000000000b156ea34ae7b5c252dd90997f1c693773a463c26935a69bcc0599b95bde9e6aa31649c48b6ee4ec1f0a56b19273a5170000000000000000000000000000000014b2d69e02418844effcbc0d564b2721deae2872cd1f27f61d544fc0ebd5cadc77c6777ec944ef0500db181a5443618e0000000000000000000000000000000004f0d48a25c1eb81233f385af17ab6abf554e1285b669eeb5e884c64d5815fd5fa1350bb361997cf2e317f7c5e9cd19a", "Name": "matter_fp2_to_g2_83", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000879133a3c0e50c90abf1a6ac75bbeca1121c865ef39e9224ddb160eb725e0850a34aaf9014e42174966773e40e4c99a0000000000000000000000000000000004c66f8f5bd462cb27e9f5e1d93e322bd97582b9e81d07b2877103420262e4cfe6d0e3bc07f9f160701fd754793eae33", "Expected": "0000000000000000000000000000000003c0d6b721cee4e5fdc6a02095674a58075f81b1d28163f81d5b258c82634297009e6bfc8193969e23e196cf7a99ad6c0000000000000000000000000000000013229818411c8e55e50a63df6983150c1d5ead828711131d9c81841850ed76e4712954d3225eb6d7fffd3cb9924f7497000000000000000000000000000000000f42d6e4d5a28dbfda87c806cb0b1bbabb745e63e655c3c6be50411da4dcdc745ae50f71d56e88db8454d40375e325810000000000000000000000000000000000f663ab791b48f76d358e66e8cd8fa40848dff2bbec758ce1d7b3fe02d1f6b3f123cef644d4fd86d6a77b8155feae58", "Name": "matter_fp2_to_g2_84", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a7e855324ef471b8fefb31967cec84d57953407ba555b672fa59364b303030cb02b6c77933cc63fcd1b8c107b263554000000000000000000000000000000000b50c3f7cebdcf538820113acdb017fcd5d41a4fd679af8dfde7b0c330e3576ca79d09eedc724a93a3f5c90d141e7524", "Expected": "00000000000000000000000000000000197865f685e78a8842fa79ddc728d507e9f31b31666d1952a46f6422c97c83fba3087be70e3bb588260556014523f74000000000000000000000000000000000131f5d85ad3beaabd129d5a5675d90ea911ebd02cddb5ddc7a8be28c33061430d684d123d5c516785d21ebf756c99195000000000000000000000000000000000c7a14948f3aa29f845e5ca9877db9f0477af376eaeb45324c21e6f99e738aeec96b89af4df942bffbabbf50172d8e5b000000000000000000000000000000000ed4aea3cb585b0d36972f9ad6943172ca7375b44d1d6e80e0bf97a0b25d74deca4d35ce865c8747f1c7a2771a37c667", "Name": "matter_fp2_to_g2_85", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001706830efca18d3e75ea0f1ca8af23a816017ceeb045694cdbad6d3d9aa5a9ddb123f5097a226a217166de3a82038393000000000000000000000000000000000402132ac383a2fcb17fe73398273ef0c2f2d0d6edabc78f31080d3ecbf7c249ffeef28bb8b37a6ef2a7d726c070dc41", "Expected": "000000000000000000000000000000000a795c2affaaecab6cd2cfd6c8fab6e35cdd646e9cfa7b5e02400ef4abf839a69924ea80152eca7810a5041d1bf58ee800000000000000000000000000000000121426bb945d6f6b385c98a5247b7dadaebd3375dd8b2bff7aa77fddfbe603de89e77baf0e8f36a924c707c53d29a1450000000000000000000000000000000007a6fcb486634186f001c8b99874f0a07a37f1ff4b30599d2f570f1bb4ff290b816547f6ce8b3c1ed33e57630a1d57ab000000000000000000000000000000000fa65924a8f17414eb7dcc54f2a4134568484e91533dd21fd33cbcc37a920f2804516a64f1986e9d887ca189179d07c8", "Name": "matter_fp2_to_g2_86", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024beda2b950efcee233435f0c748e33aa928f54ff29d3db217d7e32b1aac5f4ed11705da4fb8fd38481382486e4aef7000000000000000000000000000000000c85283ad6e35a72d07b74775df1a4660113d50b51426451f454a575adf9cbf9d7be3f521649f6c367c4f4c74b67ff6b", "Expected": "00000000000000000000000000000000049d9ac43e31faa3d02f8255d207b82e4b27e8a9a61ba45fc4f9ad8048e5f89b58d25d98253aabe29334e0dc09d1cd6b000000000000000000000000000000001544f90a0baea38b48d89bcb337cf5a80faaa79334733b7e6126f55358a7e498aeb61419065b9434cab9d10fe8e7fd9f00000000000000000000000000000000139bdd668462a1b5d3ef1299d47aa91ed141ccbeba5b08a8ee31b023aa78c16514a97ba08abf5c8bb1abbd85b3fe87350000000000000000000000000000000005c7dbb8a22403a96aee634cfc67ee6f1069cd61a1e1831e8faa9d7e1aa5e4f7623f51f2e5b739f7fcf3b4ba77c82ff1", "Name": "matter_fp2_to_g2_87", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000cb18f477abe58af92116101c3f52ad4f6074ed92a08c3adcc6660b555df9cff09dd8b34e032ed81e868a62bda50378d0000000000000000000000000000000013c4ab1558dc250c3b5d0f0fae3db62b8df969bb41e9ecc24c10e1e51cb399f1368bed7375a9b9ad9c7653c868eecfe3", "Expected": "000000000000000000000000000000000b8b8bf2b25c2386e5f3be4bdb387d8005cf055e68ab9a5606f17dbedc4fbd7a11314fd646d08bbd6e394485d4f56f5f00000000000000000000000000000000173a45d766682f82ec2d69aed1d80ede2477c276ddaa8fb97f5f4d0515b2c2e370c615cd81c1e361f95db855c9b1b6e200000000000000000000000000000000115868a9187a0465a9309054e865ef224ec3c88a5eafbcc25f9a912ee3b19084757a90b72a4038ba71b10f59fe2f93100000000000000000000000000000000006c5476eb8aa1a471d289af52c7d1df55f6bb1ad53d7eaba6bdc2a97fcb24ec480f9d8e12079d366f2213194c861f016", "Name": "matter_fp2_to_g2_88", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000188f650fdc51b970d16c0637ad5e97aade93c7f1398751439484ec6cc56613814908e51cfa7f68da9d980bb9dac47a400000000000000000000000000000000081834f86f1310135a2cb03265f37d9b7c9459bb149bc54b5a61319a7cde36c6a2a0fb49f8f1fb9d80f07b84f799119f", "Expected": "0000000000000000000000000000000016e8fea4d09831146fc35bcad28e441f2c02e4d17838e04dc7cf909b2133297a13f07ee927722f3d78e36721d6848e3400000000000000000000000000000000114dee8b3a47269e9ada05ee015a874d1cbdfff4acdf5310642f829efd08f78dd6110e1c7a514e7d76aff52046f4ed140000000000000000000000000000000017b9d23f7a865a3ca61197d841fd9195805a9e883d79dc7d36e82f504e6689ade0e84c70a5c5c516fac3e3c643942e160000000000000000000000000000000001ab82b2a0986dec3211507b8adca351829b0a13f25e281f98f54d9e0e32280ea4c638dcb74280eb747a0d9af43b6b74", "Name": "matter_fp2_to_g2_89", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006f66eb49f95f51ec90df86254580f0ae57862bdd8b5f2759ace63c5f14f8c5a762207f744bb82a8962f8c4fa410dfdb0000000000000000000000000000000004e02a80628c30ce336eab890fa37a227f77357a60be72cb87cc2b7442d2163d395fdc59350624ca1322bfe8619a2efd", "Expected": "0000000000000000000000000000000006bc2ae646a603a1f4524b445cdeb99914e4ed19cd0676d511764b828bfe126e81cad2cb566655f04de1a302c14d70bc00000000000000000000000000000000023bd509aabfa41385e90cd4b1cbbfa45d066c4defab56993aaa386dc5b7707b1a3a7d444b8bd295a30d0b8f4bdc572e0000000000000000000000000000000006f82e60e18cc958375cce6f465db461ff46ed9d15cfcc01a3aff455d54c77ebba5a654c2ec788b6ed8ac53c39defdd3000000000000000000000000000000000896fbe6492c4c297f8b6d60295a7f2565734d69eea67b2675211a203fec043f0d181b1348bea425a068b7bc12676ed0", "Name": "matter_fp2_to_g2_90", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001451bcd19495cea3a19393b77760f688fbf17b107dc131c88cbb503eee2a804e2978d6e8a4720d144083d28be73371d70000000000000000000000000000000017db715e8680a0e82e18b513f2c9c7ea136cefe8add71aac6baba146e3e33a498d025c7e0808ced306c915eb02900c61", "Expected": "0000000000000000000000000000000008604a06a198c3e11458de920176842221667d024f9c155892485a37ff56252be1dc629a6fd580fa41f5e598a23f3651000000000000000000000000000000000e008eed25eafeaa67f27e89e1f81b469724a4b00f08dc4ae672aa1587b19dc615330e3fce0fbd98d7526bc2c4afe69e0000000000000000000000000000000015bc1e4ea5ae2a7fde6d5e5c3e58f6ff5df5bcb125ab402f10edd09087bde39fa27dfcdce7d04fd18ce399729e155fae0000000000000000000000000000000006684e9be8bf9fa4badda842a1d8840f0820d9a797e482c64f4004a18cd63986f19abfc93f6bf068d38eb1e491cabbe6", "Name": "matter_fp2_to_g2_91", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013a6e129d4dd4aa93cff5489ee879763e2a2231939e609d2d72f07e630b37d09f3057a36fd5cdfc9c81675c996f8ba0f000000000000000000000000000000000e8d7ad082e8f9a718fc2ea712853ed9ab4e8b1a8ca9988f77c70fc759f1fe2d4bd73696e539f130be13b2862efbdf77", "Expected": "000000000000000000000000000000000f15c3d0b40735babb2e38a2471773faa16b2fa307c3a573ef4cfa5a5559574b2d26cf88b19dee204b77f6e11a1b927c000000000000000000000000000000000d224445f3d31d381bb29c4fdc8130174f5bcb957f451c92f4a652cc3d2b5df985017133a944849b5228a88f99bec771000000000000000000000000000000001338b48bc1fa229f251bcd4828654baec9d149f090b19596ad3b444eacc7bc583f97d9cfc40d5611fdcf89cc9a88e33b000000000000000000000000000000000c30dd2aa51f6577d57175edb3ccc1b324717bc195eb0073c1dff4e5b0d77cf5e41ec233527b3936994e86303f91b172", "Name": "matter_fp2_to_g2_92", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003379bc10acda5ed1014e2bba1e30cf83b72fe69259eb35476a031b8a898e0183bc32ee853a85fb3d738424208fc880900000000000000000000000000000000175a2e5a44ed62744fbbab9581ea7283470bff12436dfc414ad80b4070f895de3786022cbaed55bdbbc4f68db7460548", "Expected": "000000000000000000000000000000001735e1f2fe905839fd6534c95b95322f8cc86a4c482f1ad7691b9b9bb8f55015b4faaa1f243786aa33b5874817cd09c80000000000000000000000000000000013f1a27931ac513145f2601e009cf637ba4bdb18a7604f89534fa3ec8488f5b6eab9963c5d753fdd34cbe7d2f8eb8a5900000000000000000000000000000000092d8f800e7a4bf6f9a25ddd7f64fc403db53b1695ae59c15f229458f347a8e7c2ebc415af2d3849282b670c5cf6f8600000000000000000000000000000000019d22d694e559c55db63521e7b60a1a2342c3cce868d70951e5ed32ec0f5efaeab0e78b21359110f6e769776b745938a", "Name": "matter_fp2_to_g2_93", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b384a9db472c38a5d246da56059b7630f002b5f4663abce7c5f6e896222a1ca1ac02883a1ec95a4ef09bcfab7d0652a000000000000000000000000000000000de09ef45aafa56936e446e18ef9ff97ca8b81c295d35cf7b72416ebd80586d0fc479d86c23295ac54a23489af045ebc", "Expected": "000000000000000000000000000000000d7dc499e5213120b3ccc173c83d3c15dde9e13ef57238cad84889243b35c8e69eea2ac7ef7560051dcd7402b46b733e00000000000000000000000000000000063ad31c17eb17d39cb4b33e45a0b0e951becc11b685b10cb45cff268b6dca40b780f7e1532be91903372c413a11b5be00000000000000000000000000000000140da959456cbd34e041409350d6106ff65ce6dd2ac3149f04959b16eb83dd0456ca11e5990daf4a1e5c23d3f30a6c4b00000000000000000000000000000000195d07ab127d49baf89fcf5eea1f5e4cffea1a577a5c864c0e637fbdfa10182adc1d5d4ebb871949300193e45ae0fbdd", "Name": "matter_fp2_to_g2_94", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014df33e7d3ef2c339b958fee667097ccf146556261f7db4b0b0a3c29897b73a0ca249866cff1461488012bc16df43b0d00000000000000000000000000000000099dda253a43b8cfac580306267d9dfeb2c129ac1818fee43c6df5e582f5fa726ba73e1a2ef6a9e011a387c393529678", "Expected": "0000000000000000000000000000000013ec1ef25b303fe2f10a0bbe9bd77a4b2a055e176c2870c99e63b4baf2b313a835459263351dfbc25c22ea32946d8956000000000000000000000000000000000cb1c3292a2e0c9b1c1ff43cbf7595f39c00fd413b54782681fe75a6f5f231d13912f8d598dd8aaae8159de083dccd8e0000000000000000000000000000000005385f2d4bb6d94d67b2a3bacd3aae31da282707672252c0ab1a12fc85d8e9b9eb75454eb145937542099b860f9d6dce000000000000000000000000000000000e59506f7733a38a7e1da4ea5958de4755b52a9307ba2e5813131b33b86f0e401f97594d9674ff1667068a1ec3c9b145", "Name": "matter_fp2_to_g2_95", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000011c89c8d7e83155a308b2e517a23f05a4a55353332292b44b0a891b6f730fd126bd0b97eb87f0fbdb6c82779791d022f000000000000000000000000000000000da6f02450955bf26e236ec63aaf80a018ac34fd8784bb24a22a1fc5e8bd686244a923009a10cb38b1422534d0997afd", "Expected": "000000000000000000000000000000000f4392a41fb3e58dea97b97fd22e2fe6436c3f9bbcd944585a76a5f1a8f98ea4ee21639208d765b6c3a7d08f8cd3f3f00000000000000000000000000000000002c3d62794996dbb881b665eece98926f41a42c21539125fda6070d9f69e29e0557c886b42e4bcd97b14134d6e9d1d710000000000000000000000000000000004b93f315822aa1be8250c2e736727d390ae3a862c4c7dda452817f70f01c73e6f344df1b0f05f03bd574edecc70902e000000000000000000000000000000000731403981fd6243d00c23d0a42a759016f7907548847743f18421f51b1e72cea92f0c5580328babd4ae3e15bc9c56de", "Name": "matter_fp2_to_g2_96", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015bb227b5c9ccfb8390edcd158b04a69a88a3b99a10ae90e548182751a16448df25493061afde2c9790a0e75e6f409a20000000000000000000000000000000001d7b609155bf3939192eee9642032e6fb10f57d53916674c60211a37b4a7662759899a9569e2dc730febd23f747a7a3", "Expected": "000000000000000000000000000000000b35c6294b70336217eb9334ff1f1bde9d892d109e947de7f4f5681b3830ed00ad1b89ccd7cbad88ce1586449140697d00000000000000000000000000000000032691e5f4597c06496e9e37907041ddcadd18ca8ce64a8b400b1e2e8d63acce5533231edb66b69807fa2dc026c1d2be000000000000000000000000000000000773ccd132cb215cd98aa17d7fc432e0577b08d8faaa35199000d46fdeeb954e8652566384fa0cc5bcd1724942f7075b00000000000000000000000000000000112e951db3694944fc82fb980547cd8b7f2e5ec6fd2051b6aff2573797bd6a28437848ea0627054af1960ad1de0981e5", "Name": "matter_fp2_to_g2_97", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000017599d71686e817cf58b78dd7586d5b359999b32b0dec2d67e33fb6388411418ecfaa2670a2cc9dce3dadaed0fb3364000000000000000000000000000000001773995b540be9ffbfd276a92c0494e4eae296d094f9f7eca975cf4f73ae05e92bd64ea71ac47bba534044f4072a6591", "Expected": "0000000000000000000000000000000018f2eace212eacabd44ff01d886543410ef72b4d27f8d25cb080dbe4b1d4b2b4e57e4dd40723d15789d9b5104b088d9b00000000000000000000000000000000098e9e9b302876ce85ba486609fd028f357314149ce8b530778e6de586ab057fe59648d8c8ae80fe619c4c605b90784a0000000000000000000000000000000016d20a8ca43d37518c8a0f47566ba61a7aade9ea2cdd4a0907ff0ed862c6b7c64815d50397eebec262a05c6010cfaa790000000000000000000000000000000005a70c2fce25acdc4a95fc2bdedb007d71f24b0b5714fa14910ef590215d25442e91a66b6bfea5f7777f0c6d202eff32", "Name": "matter_fp2_to_g2_98", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f470603a402bc134db1b389fd187460f9eb2dd001a2e99f730af386508c62f0e911d831a2562da84bce11d39f2ff13f000000000000000000000000000000000d8c45f4ab20642d0cba9764126e0818b7d731a6ba29ed234d9d6309a5e8ddfbd85193f1fa8b7cfeed3d31b23b904ee9", "Expected": "0000000000000000000000000000000012e74d5a0c005a86ca148e9eff8e34a00bfa8b6e6aadf633d65cd09bb29917e0ceb0d5c9d9650c162d7fe4aa274526850000000000000000000000000000000005f09101a2088712619f9c096403b66855a12f9016c55aef6047372fba933f02d9d59db1a86df7be57978021e245782100000000000000000000000000000000136975b37fe400d1d217a2b496c1552b39be4e9e71dd7ad482f5f0836d271d02959fdb698dda3d0530587fb86e0db1dd0000000000000000000000000000000000bad0aabd9309e92e2dd752f4dd73be07c0de2c5ddd57916b9ffa065d7440d03d44e7c042075cda694414a9fb639bb7", "Name": "matter_fp2_to_g2_99", - "Gas": 110000, + "Gas": 75000, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/blsPairing.json b/core/vm/testdata/precompiles/blsPairing.json index 138b13944a..f41d375943 100644 --- a/core/vm/testdata/precompiles/blsPairing.json +++ b/core/vm/testdata/precompiles/blsPairing.json @@ -3,700 +3,700 @@ "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d2800000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e8490000000000000000000000000000000006e82f6da4520f85c5d27d8f329eccfa05944fd1096b20734c894966d12a9e2a9a9744529d7212d33883113a0cadb9090000000000000000000000000000000017d81038f7d60bee9110d9c0d6d1102fe2d998c957f28e31ec284cc04134df8e47e8f82ff3af2e60a6d9688a4563477c00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_pairing_e(2*G1,3*G2)=e(6*G1,G2)", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d2800000000000000000000000000000000122915c824a0857e2ee414a3dccb23ae691ae54329781315a0c75df1c04d6d7a50a030fc866f09d516020ef82324afae0000000000000000000000000000000009380275bbc8e5dcea7dc4dd7e0550ff2ac480905396eda55062650f8d251c96eb480673937cc6d9d6a44aaa56ca66dc000000000000000000000000000000000b21da7955969e61010c7a1abc1a6f0136961d1e3b20b1a7326ac738fef5c721479dfd948b52fdf2455e44813ecfd8920000000000000000000000000000000008f239ba329b3967fe48d718a36cfe5f62a7e42e0bf1c1ed714150a166bfbd6bcf6b3b58b975b9edea56d53f23a0e8490000000000000000000000000000000010e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc0000000000000000000000000000000016ba437edcc6551e30c10512367494bfb6b01cc6681e8a4c3cd2501832ab5c4abc40b4578b85cbaffbf0bcd70d67c6e200000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_pairing_e(2*G1,3*G2)=e(5*G1,G2)", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a550000000000000000000000000000000004523f5a3915fc57ee889cdb057e3e76109112d125217546ccfe26810c99b130d1b27820595ad61c7527dc5bbb132a9000000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f000000000000000000000000000000000345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c00000000000000000000000000000000083d3baf25e42f2845d8fa594dda2e0f40a4d670dda40f30da0aff0d81c87ac3d687fe84eca72f34c7c755a045668cf100000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000000000051f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e000000000000000000000000000000000b6a63ac48b7d7666ccfcf1e7de0097c5e6e1aacd03507d23fb975d8daec42857b3a471bf3fc471425b63864e045f4df00000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab160000000000000000000000000000000019bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3000000000000000000000000000000000adb3250ba142db6a748a85e4e401fa0490dd10f27068d161bd47cb562cc189b3194ab53a998e48a48c65e071bb541170000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000000000000d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a414950835820000000000000000000000000000000009d0d1f706f1a85a98f3efaf5c35a41c9182afc129285cf2db3212f6ea0da586ca539bc66181f2ccb228485dd8aff0a70000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000000000000073eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086000000000000000000000000000000001825bacd18f695351f843521ebeada20352c3c3965626f98bc4c68e6ff7c4eed38b48f328204bbb9cd461511d24ebfb3000000000000000000000000000000000029ea93c2f1eb48b195815571ea0148198ff1b19462618cab08d037646b592ecab5a66b4bc660ffd02d1b996ca377da000000000000000000000000000000000bb319a4550c981ee89e3c7e6dcc434283454847792807940f72fd2dbf3625b092e0a0c03e581fd9bd9cf74f95ccef15000000000000000000000000000000000abb072b8d9011e81c9f5b23ba86fdb6399c878aa4eadee45fb2486afe594dffc53be643598a23e5428894a36f5ac3ce0000000000000000000000000000000005d04aa0b644faae17d4c76a14aa680c69fdfc6b59fee3ef45641f566165fced60cbbda4ca096e132bb6f58ab4516686000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436000000000000000000000000000000001065f2a2d29a997343765f239c99a018490eced40ac42fc93217dfe20d8b43ee2215f65166aff483b3dc042c5a43b196000000000000000000000000000000000766e4c66f4a442ff1f61a7a4d197d2b47dd226d0e7822a9b065108cfc643cd3f3d5ae59ed2ce4cde13fd9260bb5b7cc0000000000000000000000000000000012251cc6abbabeb7bbe1fdd63eaee10832a748fff24f7e3fdccaea87facb6e99f2e0407a38f27f90450a471b873104620000000000000000000000000000000011181e08c8fba91271adfee9d31681f8412ab7a3f754f7ba4709024c0ad2287e32dd455d71a296b4838072a8ab9d96f2000000000000000000000000000000001252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada0000000000000000000000000000000002a1bc189e36902d1a49b9965eca3cb818ab5c26dffca63ca9af032870f7bbc615ac65f21bed27bd77dd65f2e90f53580000000000000000000000000000000005a7445f55add1ed5c143424ceef3d594280e316c9441a8e68c3ad97377141d015bf878bdfcf0df9fbcd0529f4e8100800000000000000000000000000000000192b52ba08ed509fc84d5775a7182498fd1ff80941d673c53470c9c9f1192f9c0057d68a1dfee0c68fe5df3625cc43bf000000000000000000000000000000000d3fcaf2f727e0eb32c65da9b910dc681b948dda874d0db6f6ed3f063430fbf073385a9a14c2dd78568726124e2b3ea8000000000000000000000000000000001943ce22cdb2387bd5796950dc95d1ace4012ab9bb4afb46223760230c1709e075f1ae76d6b3f2e947ba6b16d458ccd1000000000000000000000000000000001271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4000000000000000000000000000000001407ffc2c1a2fe3b00d1f91e1f4febcda31004f7c301075c9031c55dd3dfa8104b156a6a3b7017fccd27f81c2af222ef000000000000000000000000000000000a29e38da2d42fd4712052800c7c8dd6e94fd9f506e946068aaac799d60b94c2d7515769ffdd32ea95d3910330ec47de000000000000000000000000000000000c60dae92451206390e30b5daa7151d63624dee496753c87dd54eadc92dc9602081fae02a1a53bac97e984a571923a5d00000000000000000000000000000000085f4fda4c72328895f20c683cb49603a37ff2c43d62f66602506dad5b8d1daebfbac7a7db3f50ccf4dfff277deb105c0000000000000000000000000000000005674d005457e0fe1f0fd978d63996c5f3d29f9149ee4eb04c464742dd329ccaef5e5f6b896d986ddfc9f1b2a3aec13100000000000000000000000000000000071bc66d6e2d244afc4a5ce4da1dce3d0c22c303ba61310fdf57843bbd97763ef496833dfa99d14be084bb1a039bb2da0000000000000000000000000000000012c22e047b0af8e2f4bf3bd3633ef0f8264004ca8ea5677a468857a1762f815235a479e53f4ad4741ffda3fb855021c900000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "bls_pairing_10paircheckstrue", - "Gas": 345000, + "Gas": 495000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a550000000000000000000000000000000004523f5a3915fc57ee889cdb057e3e76109112d125217546ccfe26810c99b130d1b27820595ad61c7527dc5bbb132a9000000000000000000000000000000000186a1da343cacf1815b9c8b6c807f536249dbfdb59d77bf4920ad2198a0d83ada21f7c39de6f06a5599f22571cab288d000000000000000000000000000000000ba1ec44f95121bd622932b84bbb4b3d279f69c494ee44db68e3165c86b627ba5e397ee197313fb5b775972798997332000000000000000000000000000000000783e7493e9fb106fa0d085e7c03eb816468d12c65d9b77643ed07c02583d491f4db5db44e565d50d8ccaa9ad8f7f8e80000000000000000000000000000000010a6a5fd90cd5f4fb6545814f5df065b001074bb3f29f649dd2612815df3a19a320f7754dd3d458e48e7fb1b4953978f000000000000000000000000000000000345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c00000000000000000000000000000000083d3baf25e42f2845d8fa594dda2e0f40a4d670dda40f30da0aff0d81c87ac3d687fe84eca72f34c7c755a045668cf100000000000000000000000000000000129c4945fe62538d2806fff056adac24f3bba8e17e42d82122affe6ad2123d68784348a79755f194fde3b3d448924032000000000000000000000000000000000528590e82f409ea8ce953f0c59d15080185dc6e3219b69fcaa3a2c8fc9d0b9e0bc1e75ec6c52638e6eaa4584005b5380000000000000000000000000000000018dc3e893f74729d27dd44f45a5a4f433dcd09a3b485e9d1c2bd0eb5e0e4c9024d928ddc426fdecae931e89885ee4db4000000000000000000000000000000000d6ee02e1fc7e52a8e1ef17e753065882c6fcc14da61da7ffe955fe84a9d2af9ba57562c69db3088652931bf124b0d5300000000000000000000000000000000051f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e000000000000000000000000000000000b6a63ac48b7d7666ccfcf1e7de0097c5e6e1aacd03507d23fb975d8daec42857b3a471bf3fc471425b63864e045f4df00000000000000000000000000000000131747485cce9a5c32837a964b8c0689ff70cb4702c6520f2220ab95192d73ae9508c5b998ffb0be40520926846ce3f100000000000000000000000000000000101e147f8bd7682b47b3a6cc0c552c26ce90b9ce0daef21f7f634b3360483afa14a11e6745e7de01a35c65b396a1a12700000000000000000000000000000000090ca61ed16c4c1e80acfef736eea2db0d7425d9110cb53e6c4a2aa3f8a59ee6c60bdce8df5825011066d44bef84d29600000000000000000000000000000000028207394adcbf30250ac21a8f1db6283580bc5e39159930552e5edb25e6215c66b6450296edc80dbc3a2acd125dab160000000000000000000000000000000019bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3000000000000000000000000000000000adb3250ba142db6a748a85e4e401fa0490dd10f27068d161bd47cb562cc189b3194ab53a998e48a48c65e071bb541170000000000000000000000000000000016cfabbe60d1e55723a0ff72cf802f2d1cf13ed131e17729adc88522a657f320a336078a9399c8e61a3bbde3d52fd3640000000000000000000000000000000009aa9a3c2a6d49d286aa593c6ff644f1786fa9ae471bdb3fe70b150a9ed7584eaa886ac057c30005c3642f65ad5581cc0000000000000000000000000000000001d417894c0cce924955a795b188b27951f8438a5485404b921a42fa79dea03c10e29d0390df2f34d7be13f360a7fada00000000000000000000000000000000189b0b3a04e6c613899d51231dbf0cba6a8a8f507ebed99d24fba7ebac6c97a8859ffde88e6d95c1a9d6b4f0a8f3c417000000000000000000000000000000000d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a414950835820000000000000000000000000000000009d0d1f706f1a85a98f3efaf5c35a41c9182afc129285cf2db3212f6ea0da586ca539bc66181f2ccb228485dd8aff0a70000000000000000000000000000000016cad7807d761f2c0c6ff11e786a9ed296442de8acc50f72a87139b9f1eb7c168e1c2f0b2a1ad7f9579e1e922d0eb309000000000000000000000000000000000d3577c713fcbc0648ca8fbdda0a0bf83c726a6205ee04d2d34cacff92b58725ca3c9766206e22d0791cb232fa8a9bc3000000000000000000000000000000000f5ea1957be1b9ca8956ba5f6b1c37ea72e2529f80d7a1c61df01afcc2df6f99ced81ac0052bd0e1e83f09d76ad8d33b000000000000000000000000000000000aabced4e2b9e4a473e72bf2b1cc0ce7ab13de533107df2205ed9e2bb50fa0217e6a13abcd12fce1bda1ccf84dac237a00000000000000000000000000000000073eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086000000000000000000000000000000001825bacd18f695351f843521ebeada20352c3c3965626f98bc4c68e6ff7c4eed38b48f328204bbb9cd461511d24ebfb3000000000000000000000000000000000029ea93c2f1eb48b195815571ea0148198ff1b19462618cab08d037646b592ecab5a66b4bc660ffd02d1b996ca377da000000000000000000000000000000000bb319a4550c981ee89e3c7e6dcc434283454847792807940f72fd2dbf3625b092e0a0c03e581fd9bd9cf74f95ccef15000000000000000000000000000000000abb072b8d9011e81c9f5b23ba86fdb6399c878aa4eadee45fb2486afe594dffc53be643598a23e5428894a36f5ac3ce0000000000000000000000000000000005d04aa0b644faae17d4c76a14aa680c69fdfc6b59fee3ef45641f566165fced60cbbda4ca096e132bb6f58ab4516686000000000000000000000000000000001098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a000000000000000000000000000000000ea923110b733b531006075f796cc9368f2477fe26020f465468efbb380ce1f8eebaf5c770f31d320f9bd378dc758436000000000000000000000000000000001065f2a2d29a997343765f239c99a018490eced40ac42fc93217dfe20d8b43ee2215f65166aff483b3dc042c5a43b196000000000000000000000000000000000766e4c66f4a442ff1f61a7a4d197d2b47dd226d0e7822a9b065108cfc643cd3f3d5ae59ed2ce4cde13fd9260bb5b7cc0000000000000000000000000000000012251cc6abbabeb7bbe1fdd63eaee10832a748fff24f7e3fdccaea87facb6e99f2e0407a38f27f90450a471b873104620000000000000000000000000000000011181e08c8fba91271adfee9d31681f8412ab7a3f754f7ba4709024c0ad2287e32dd455d71a296b4838072a8ab9d96f2000000000000000000000000000000001252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada0000000000000000000000000000000002a1bc189e36902d1a49b9965eca3cb818ab5c26dffca63ca9af032870f7bbc615ac65f21bed27bd77dd65f2e90f53580000000000000000000000000000000005a7445f55add1ed5c143424ceef3d594280e316c9441a8e68c3ad97377141d015bf878bdfcf0df9fbcd0529f4e8100800000000000000000000000000000000192b52ba08ed509fc84d5775a7182498fd1ff80941d673c53470c9c9f1192f9c0057d68a1dfee0c68fe5df3625cc43bf000000000000000000000000000000000d3fcaf2f727e0eb32c65da9b910dc681b948dda874d0db6f6ed3f063430fbf073385a9a14c2dd78568726124e2b3ea8000000000000000000000000000000001943ce22cdb2387bd5796950dc95d1ace4012ab9bb4afb46223760230c1709e075f1ae76d6b3f2e947ba6b16d458ccd1000000000000000000000000000000001271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4000000000000000000000000000000001407ffc2c1a2fe3b00d1f91e1f4febcda31004f7c301075c9031c55dd3dfa8104b156a6a3b7017fccd27f81c2af222ef000000000000000000000000000000000a29e38da2d42fd4712052800c7c8dd6e94fd9f506e946068aaac799d60b94c2d7515769ffdd32ea95d3910330ec47de000000000000000000000000000000000c60dae92451206390e30b5daa7151d63624dee496753c87dd54eadc92dc9602081fae02a1a53bac97e984a571923a5d00000000000000000000000000000000085f4fda4c72328895f20c683cb49603a37ff2c43d62f66602506dad5b8d1daebfbac7a7db3f50ccf4dfff277deb105c0000000000000000000000000000000005674d005457e0fe1f0fd978d63996c5f3d29f9149ee4eb04c464742dd329ccaef5e5f6b896d986ddfc9f1b2a3aec13100000000000000000000000000000000071bc66d6e2d244afc4a5ce4da1dce3d0c22c303ba61310fdf57843bbd97763ef496833dfa99d14be084bb1a039bb2da0000000000000000000000000000000012c22e047b0af8e2f4bf3bd3633ef0f8264004ca8ea5677a468857a1762f815235a479e53f4ad4741ffda3fb855021c900000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "bls_pairing_10pairchecksfalse", - "Gas": 345000, + "Gas": 495000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_0", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed200000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_1", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f000000000000000000000000000000000a69d6d9f79e19b38e6bf5a245dc820bddbdfe038d50932f76d0e4629d759f8ca6d573fcfc39256305daedf452f9fdf40000000000000000000000000000000015f5949369e58487afcecf8018775d1b0a73e913bf77e13d2e5a843bbbeba7d1978ca27ae8bfc87d30f567dd396b980e00000000000000000000000000000000182198bb38a0353b8db25389e56ab0d8679a1bda008a65dad77e4c95bc6804f6311eb16c761e1a5e2a5f87cfada49fa4000000000000000000000000000000000eb5483959e98c30e71db52615f63521378b156f142d46f3bb285b94aef39d80feacec335b797c5a68dc17ba89d43e0f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_2", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4000000000000000000000000000000000286f09f931c07507ba4aafb7d43befe0b1d25b27ecc9199b19a9dc20bc7ec0329479ef224e00dece67ec0d61f1ca5ae0000000000000000000000000000000014e6ed154b5552be5c463b730b2134f83e0071dcdadfaa68e6c7c7f6e17dabb7daf06e409177bc4b38cfdb8248157618000000000000000000000000000000000f145e998dc6eb0c2b2be87db62949c7bfa63e8b01c8634248010fd623cfaec5d6c6c193331440957d333bf0c988b7b10000000000000000000000000000000002a1ab3eea343cfdea5779f64b3bddbf0769aded60e54a7507338f044310ba239430663394f110e560594d6042a99f1c", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_3", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d3000000000000000000000000000000000d1007ca90451229d3780d66d3aed7c9d8fc82e9d45549e8586600e38eb6763f3c466e2f6ba6ba1dafd8f00cc452dda20000000000000000000000000000000001d017d920a262b6d6597bab532f83270f41526409510e80278d1c3595ceabb9ceba8ae32b1817297ff78ea7a0d252e8000000000000000000000000000000000935b7a59d2e51bbb2f9b54ccb06ebee9d189fa82f0e97d10c8020badb3de7fe15731b5895faed8cad92ae76e2e1b649000000000000000000000000000000000792dadd48a20040ad43facedc109747411895180813349d41d0e5b389176bfb15895d41665be8d1afa80835ef818eca", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_4", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f9000000000000000000000000000000000095353ad699b89ac82ca7ef631775b2b3a6e3ed8dd320440cdb929baa428e63cb902a83857cc0e2621470544c69e84aa000000000000000000000000000000000892559ade1060b0eef2cbc1c74de62a7ff076a3621e5f0f159672a549f1201f2ffb3ac12c8b12cb86ae3e386c33e219000000000000000000000000000000000750df4632a7126ddb08658a4001f949b9764d9cc43a9393cc55d8fdbb15d4a1186dd87a6433d111888a7804540ad9fc0000000000000000000000000000000017554bd444665df044b91b0b2614017bbfcd7acc7f8c5a16cea2861235578ce2b27dcced9fba234999fa478cd3f6e42d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_5", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b00000000000000000000000000000000175dadb6ee656ec6aebf8d0e5edaee3f119c74e0ea64e374be9e8ab9fd3d085fceeedf4ed8de676ebe9065d83b0542ad0000000000000000000000000000000005cd6a875329c23e4918976cf997e93e403957acfc999f8159a630d21ab6f1762925c063784237262bedc82402ad81bb0000000000000000000000000000000003274bcb8db35e50164d136c2a98b5a6d2fb5f9767d0ee11c1358bf7ca5ed96d9122f8c1051ba3c658cc89777d03dfa5000000000000000000000000000000000380a240443dff85b6542f75db28b87c39e278cdb8d9627efbbc63b229e6ce783f6fb0114c8e91c2fd6ea71c95bb99a4", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_6", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a000000000000000000000000000000000834cf1b4149d100c41b1bca0495e455002eb6596bddcb94ae48d0c65957e8b313372f8e0d6e57504664b266f38293150000000000000000000000000000000000de2875fbd14760bac4c2cc7d3f239177efe9f7f61f767be420d44f24c9fb863efd60dcd732986db8c5b72470617ea60000000000000000000000000000000000bc9535ebf11c2dcc8c7d3bcd09d7d14035635fccb5fddb7df29ce8855e79f99809781d6ffbbcb33d1227314609abee00000000000000000000000000000000039bbfb4d969d702255e3be7f255a97529a19687ce38cb70637c37894d4102591feef428b0afe8c9ef50310ae3b83091", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_7", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795000000000000000000000000000000000fc09c241899fa6e8cc3b31830e9c9f2777d2bc6758260c9f6af5fce56c9dc1a8daedb5bcb7d7669005ccf6bfacf71050000000000000000000000000000000018e95921a76bc37308e2f10afb36a812b622afe19c8db84465ab8b3293c7d371948ee0578dbb025eed7ed60686109aa0000000000000000000000000000000001558cdfbac6ea2c4c1f4b9a2e809b19e9f4ba47b78d2b18185ed8c97c2f9c2990beadc78b85c123b4c3c08d5c5b3bbef000000000000000000000000000000000ea4dfdd12b9a4b9a3172671a6eafed7508af296813ec5700b697d9239ae484bcf7ab630e5b6830d6d95675be5174bb2", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_8", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a1900000000000000000000000000000000000b36d8fb9bd156f618ab8049d41dfe0698218764c0abb10e12fae43c8810b8e2a5201364e2778f6f433b199bb8f9a6800000000000000000000000000000000000707eb15411b63722b4308c0ed4288320078d2463ae659ad4fb3f9ef8124f379df92d64e077403e50727388adb59ac00000000000000000000000000000000158e1249d5b91614924acb23899c6bae408697dec0982c10d0459746499f4e6739afb9d5129568106ed1a1caefeaa9640000000000000000000000000000000019e841562e4aa75321143f8ce1e5ec6158fa5cb8b98c839a486188260c18ee8a7600930f23aa39eac2eb520d6a0fba90", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_9", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac94300000000000000000000000000000000186a9661d6fb539e8687ac214301b2d7623caedd76f4055089befba6ef2c96263d810921ad7783d229f82783c9def424000000000000000000000000000000000447f3e20caa1f99fbaccab7bde2bd37fe77cea691ebf2b9499f95bbbb77afe72b7039eb0c05970b61360fcf8ade73730000000000000000000000000000000005e11f828eda86c10a1d7929def547ac06885da278afae59c5d95453caf0a2d8ed186fa7c6d0a7ab6e9142cfa4b338190000000000000000000000000000000003d954e61b6ab71042b19e804efccd4956b56662f27f70a9255cec0c464b86c0e83721ad3785dec62dd4a9dd3d6d5d53", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_10", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e0000000000000000000000000000000002b94534aa0ba923bda34cbe92b3cd7a3e263741b120240ff5bdb8b718f094d3867e3fcabeab4a7be39c8f8c4fdd10d900000000000000000000000000000000048711cf6a82534d64d072355cb8fe647808e7e8b2d9ac9ed52eb7fe121647a721dd1234c71ecd163d91701eb7331cac00000000000000000000000000000000141ef2e23a1ecc7ef2ed3ea915492e79cfffe60b5e0de8441e878bd0653843d79c724e3c5ebe2321361df99f8932ddc200000000000000000000000000000000085513b4009f29b3e00a91c2c4be418368560802ba4194cbd2f4fa3d72a55fcae547014434514a8b2a8fe3e0b28d2773", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_11", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b0000000000000000000000000000000009143507a24313ee33401955fc46562c9b20c9917df3b40ccbd7ed43b1349d4551cfd98a4976d6fec5fc289460c8d89900000000000000000000000000000000060566b79df5cc975e669da8ca3a7fa91bf3f5c9fb871c3d62f4a3e79dbc341b89d38b588e5414bc385d5e3cbf3ab9310000000000000000000000000000000016bf40b8cc4c01a87aafae0c4439b623a51ba9a383756a550b69d627d6f45209f0d87e4f9be9edff35c986f7b9c49e3f000000000000000000000000000000001842d9172bce51a164fbdbdb108d0faae07e4642f21c80e40ac31e737657472ae3dfe552b65349629c210a068c4afc0e", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_12", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a5787681000000000000000000000000000000000ab19bbddd661e9db8fe4cb307ecebdc5e03efbb95c5b44716c7075bd60efcfc67de0bfd7c46ad989a613946c90a4c1000000000000000000000000000000000120800e7f344cda816299fa37f603ade06beb3b10907f5af896d6b4e42f7f865b756f14164db84411c56cb2ea81f60be000000000000000000000000000000000f688ddd257e66362af1437b6922d3397a7c3dd6dea6bca8ebd6375e75bf2de40bc287cbf3434388191e56b92949c83b0000000000000000000000000000000005252465784aff8c1c707da58b5808c69583bf852d68f96912bc53f8dae4536b09ccbbd25a49d9e744118992b92b6792", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_13", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f768000000000000000000000000000000000e3165efe00f69aee84ac56d2161f07c017abfaadeaad34f8c96799d68bae0e6f9b557bbf9137e7826f49f29c58d1ef9000000000000000000000000000000000de0dce7ea371ad60f21f2cb61cb582b5072408a7efc91edf05b36a1a3b58fd9e6cf808d75157eedccc8f1c93a8ae07d0000000000000000000000000000000016d911943d80427385ebac1d1b293914a9e4dd9db06c1d6a758192d63c8fc9368e02eae7fb0e3a7859408f215cfa76ca0000000000000000000000000000000007bfdc6afb8acec625e50ecbc08a5cdb7862b795866323679885ba5cba3fd51f181078e03fe35e96e6383c077eed1bf5", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_14", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931d000000000000000000000000000000000a68dccbe3452731f075580fe6102b8ee5265007ee19c56d95bcb096a3a6ac444f4145b980f41afcb0a865853b279bc600000000000000000000000000000000164767ea55a9038ac2dd254d8c8a4970dba93dacdf5416aecaa407914719cab165e7a32784b2c41652a86358737d831f000000000000000000000000000000000da9441fbc6578c85fdeca49082c9ebbf183de894d67c65158380ee56132d3cdb44b100d72b6d3b82688defb75d2aa390000000000000000000000000000000017d570e4f6e46550679d5d12c347414da207060f594620e2f8db66df8e0b06c912290b207a268e782d4b45db19a199db", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_15", - "Gas": 138000, + "Gas": 108000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd8000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_16", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a67000000000000000000000000000000000013a80ede40df002b72f6b33b1f0e3862d505efbe0721dce495d18920d542c98cdd2daf5164dbd1a2fee917ba943debe0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f900000000000000000000000000000000043c4ff154778330b4d5457b7811b551dbbf9701b402230411c527282fb5d2ba12cb445709718d5999e79fdd74c0a6700000000000000000000000000000000018c690fc5571f69793ec3c82915ac9513726ec891312f4f11dd3ba0ee95cc98b50d925099b0642e58a106e8456bbcbed0000000000000000000000000000000001c2d8d353d5983f22a5313ddd58fdc0d9c994b2915dbc87a9b65b7b98ff00b62e140a27dc322d42b3ad190c1b3728dd0000000000000000000000000000000010412f3625947b38bb380a6ed059f1677b7a7afcb91517837c563dadd0e285b95740a200ddff6570d4d92bb636b625bb0000000000000000000000000000000015f4f9a480a57bd1b2388532ab045a1ba93d2f6589a3022c585fe06a1d611165c99d70be06251812405c9c37d6e9f7730000000000000000000000000000000001a78e6c5062a6634a56e9853ff5afacb2e7cf31fd0ea5f0d8c8ac6174c88133cf2f63450ec4590544c9a0e37daac1f9", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_17", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e880000000000000000000000000000000008d7489c2d78f17b2b9b1d535f21588d8761b8fb323b08fa9af8a60f39b26e98af76aa883522f21e083c8a14c2e7edb6000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae70000000000000000000000000000000009f9a78a70b9973c43182ba54bb6e363c6984d5f7920c1d347c5ff82e6093e73f4fb5e3cd985c9ddf9af936b16200e88000000000000000000000000000000001129c94e0c06f51f1f808a62e42a5449dd159289c14a09c4cc382c91bcfe878b6f3555767c310de1b1c275eb3d17bcf5000000000000000000000000000000000818e567aea83eaf3142984bb736b443743659626c407987b604a30c79756081fa6ae6beeb2e6c652dbfe9cf62d44e3900000000000000000000000000000000193f0317305fde1046acda2c9491e376aa67244f68ef6495845d049e1293082af91f880be935d9d8ad0e25ad918caae200000000000000000000000000000000109224b8178be58ea4e4a194ca66bef9d14f6fc2c625d25feaa4f32e0f4d72d91024d96839bc96e6a624c5ad6221bd94000000000000000000000000000000000e42decf8a987efaeb4ede37236b637e61249bf6245679be7fd4d633e2d814ed4748b73890ad3c4fcbcfb4960cb67ae7", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_18", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000aba6a0b58b49f7c6c2802afd2a5ed1320bf062c7b93135f3c0ed7a1d7b1ee27b2b986cde732a60fa585ca6ab7cc154b000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a79157800000000000000000000000000000000010fcfe8af8403a52400bf79e1bd0058f66b9cab583afe554aa1d82a3e794fffad5f0e19d385263b2dd9ef69d1154f10a000000000000000000000000000000000f46a7dee0cb471ddef3a50670a5bfc443b8455877f1ff602b21faff1eff07fc6bf27930ca2159f01479359548339560000000000000000000000000000000000ca0d865f8c8ce0a476f7a6edb3ce4bd5e6c3a8d905d8fb5a10e66542f4325a9963c2f8d96f804f4d295f8993b5204df0000000000000000000000000000000005a966f6254f0ef4f93f082a97abe07db56f00c2ade047d2f0027edef6f00a0dfecaa24d50faa778fa29087302211f7e00000000000000000000000000000000121c51da366557c09af1bbd927521da88dfab3e2e9a95b6effb0a968795486f281f0c887e37f51837557b9e3808987130000000000000000000000000000000001a5524975400b1e88f3fff8dd34dadf5d75564cfc0026df31ee9c2c1d48b0f69a48e1e4a48cc4b7db61f023a7915780", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_19", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b0900000000000000000000000000000000082543b58a13354d0cce5dc3fb1d91d1de6d5927290b2ff51e4e48f40cdf2d490730843b53a92865140153888d73d4af0000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e0000000000000000000000000000000013c5ebfb853f0c8741f12057b6b845c4cdbf72aecbeafc8f5b5978f186eead8685f2f3f125e536c465ade1a00f212b090000000000000000000000000000000011dbce34af6cb14d3e4d49f2482e1b058609f25dca79e2ca48e289ace9d1c8db177b7bc35daad79aa5fdac77728bd5fc0000000000000000000000000000000002b51851ef3b44481d13f42e5111fa4fec04be0bf6acc7e59dec3a8c8113e5bb7b604c6dbdc5e8eddc2a1ffb81bc2baf0000000000000000000000000000000018ddb483ae75402852b7f285277ff7308ff78a3364cca8b0e0e1fa9182de275fd55c1e8ec3dbde180379c4280787ba8000000000000000000000000000000000170539890c89a4f91acd59efd413b5d1059f0c8fd8718e8f722e865dd106a4eb02e6fb0cd71b34ebc4b94375b52e4dd60000000000000000000000000000000001c2e9392f5d4b75efc5ff10fe97f37e2671cad7e4710765866e92aec99b0130e6ff1314502d069fb7b5f86bfce4300e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_20", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000097ec91c728ae2d290489909bbee1a30048a7fa90bcfd96fe1d9297545867cbfee0939f20f1791329460a4fe1ac719290000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd6700000000000000000000000000000000053a12f6a1cb64272c34e042b7922fabe879275b837ba3b116adfe1eb2a6dc1c1fa6df40c779a7cdb8ed8689b8bc5ba800000000000000000000000000000000108248cdc6f503c7bad30eac875d92a75feccbdbe7b5394f8557a92bb12a796430a2c60ca23c6ecd259e5b01e53891820000000000000000000000000000000011bbc566a10eadf16009c1d2655cfae6adfb0f56f5e55b31dc000414be1b4cee9a0b9f7d9eab4c6829037c327914d5640000000000000000000000000000000009b28329096d8644dfcba6e92477eafff29f7477da4581ce76d1493f03034d7f5d3acaadbe42c76a83ca51db79d456d10000000000000000000000000000000019f75a303fdede5d97f3e521b03ef6b9d7c008d770b59ce3ac38900b340895e008342701ad1b41830b9c010936f4ff1700000000000000000000000000000000161aa1853edbb56fa3bd685c9c6b88e466dfa3c4f194f6774b4d9b1f30b016993bd0d65e8e9d6dea6caa196ff735bd67", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_21", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed302500000000000000000000000000000000130f139ca118869de846d1d938521647b7d27a95b127bbc53578c7b66d88d541adb525e7028a147bf332607bd760deac000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4000000000000000000000000000000001354dd8a230fde7c983dcf06fa9ac075b3ab8f56cdd9f15bf870afce2ae6e7c65ba91a1df6255b6f640bb51d7fed30250000000000000000000000000000000006f1fe4d98675ffc62d4d5dd0af9968faca4d0ef425d56fa31b80aea892820e270f6da17aec9eb83c6cc9f84289ecbff000000000000000000000000000000000ae7289aa9bf20c4a9c807f2b3ac32f0db24e9a0a360c92e5ce4f8253f0e3e7853f771597c8141d705062bef12d4fea80000000000000000000000000000000001d2f610d79110f93145faad2e34f3408316b1dc3a72852e811b324577d9037035e24af25002ddd100cd9283b70ddcad0000000000000000000000000000000012947315d5c0ec670619125eed0de3dd259a008baee4379b82accf2391e70a2bdad264cda04c3bc1b5394a62559fa0ef000000000000000000000000000000001239e687c4d3417c3c9b655035f8d8a649c255f9a8e6f03b785eed0d416a1cd6ef7c8b45563acb4616af24f64dbccac4", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_22", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e70580000000000000000000000000000000010e4280374c532ed0df44ac0bac82572f839afcfb8b696eea617d5bd1261288dfa90a7190200687d470992fb4827ff32000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa0000000000000000000000000000000003f76a6dc6da31a399b93f4431bfabb3e48d86745eaa4b24d6337305006e3c7fc7bfcc85c85e2f3514cd389fec4e705800000000000000000000000000000000091ce9e6c4bab3ad3d275cf5888387646c3d9bb53ace7bd0c118fce3e44fcd96241b58e5af53978272f56d04b7d7ab79000000000000000000000000000000001179ee329771b5913d07818e70f6ce5a58d74ea0b573eaa1bd3d97e45d3eeb27fcc7d37dba127af7a38354cb6ff48f7c000000000000000000000000000000000c898abe6eb76ef99f5143cfb8d840a918bcc9096ce25caa45d0bf5d20814cb01b024f1fd2cbecb6bef65d9456070dd90000000000000000000000000000000008e2a4fd746e86f90484f9b9b7b47b6afe5833762e515ccb276c554f00df88dd9aa0fb792c5f419dda0465cfed838e7c0000000000000000000000000000000012b5e6f7070c0045ade96f548ed6428c5030fa20c6f6f37a42fde9dbb5cd01def0fd8585bf8aeef913e7d42b9ef22efa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_23", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000ebdef273e2288c784c061bef6a45cd49b0306ac1e9faab263c6ff73dea4627189c8f10a823253d86a8752769cc4f8f2000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e0000000000000000000000000000000009439f061c7d5fada6e5431c77fd093222285c98449951f6a6c4c8f225b316144875bc764be5ca51c7895773a9f1a640000000000000000000000000000000000b4322c2fb5d5dd2c65b45f74ca75002c97444d8d4e5680d0369d32d180c93b294e30ef42f21ac274f77ad89633ab1b9000000000000000000000000000000000fe2e61bc8e9085d2b472a6791d4851762d6401fd3e7d3f3ba61620dc70b773f2102df1c9d6f1462144662fb2f15359700000000000000000000000000000000031f160cde626ca11f67613884a977fb5d3248d78ddbf23e50e52c3ba4090268c1f6cd8156fa41d848a482a0ca39eb04000000000000000000000000000000000eb61ba51124be7f3ee9be1488aa83cbd2333aa7e09ae67fef63c890534cb37ca7de3d16046b984e72db21e1f5c57a8a0000000000000000000000000000000006bf6f5d65aa7d19613141018ac8bf5d1e6fe494a9f30da215a2313a0241779006bce33a776aeedae5de5ea6ee5a9b9e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_24", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b10000000000000000000000000000000011efaeec0b1a4057b1e0053263afe40158790229c5bfb08062c90a252f59eca36085ab35e4cbc70483d29880c5c2f8c200000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f000000000000000000000000000000001478ee0ffebf22708a6ab88855081daba5ee2f279b5a2ee5f5f8aec8f97649c8d5634fec3f8b28ad60981e6f29a091b100000000000000000000000000000000081162fe2e65a642993ba283df9bc8d60bfe495b2dc5623f0467c87bc7570980be2654c8cc8838fb362c677f3a3cb1e900000000000000000000000000000000196044a5cdbc5300ee837dca745a44379070e9297697f5db28df4a37307cc740abed45cc778a3f4e3b8c9890ab6c3c70000000000000000000000000000000001176f5de6a3577ad67863bd3d9152ab9e8184964c6ac276e95946788f5a76394047580077c0971d874a40d510eb0443e00000000000000000000000000000000147dd55dff69213c5760e8d22b700dd7a9c7c33c434a3be95bd5281b97b464fb934a3dff7c23f3e59c5d8d26faa426bf0000000000000000000000000000000019efcf03ddb0934b0f0dba3569809d5b48b863d50d3be4973b504244414e1e1db56adff51d33265ce102b320c552781f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_25", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e2728390000000000000000000000000000000006dc2ccb10213d3f6c3f10856888cb2bf6f1c7fcb2a17d6e63596c29281682cafd4c72696ecd6af3cce31c440144ebd10000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f00000000000000000000000000000000150d43c64cb1dbb7b981f455e90b740918e2d63453ca17d8eeecb68e662d2581f8aa1aea5b095cd8fc2a941d6e272839000000000000000000000000000000001324e51f295ea95adedc9730dac2e1ab6d85838840e3955103d76677ce9a7359215f8d954286950bed1be3bbfebabeda0000000000000000000000000000000005d8edbabf37a47a539d84393bb2747d0a35a52b80a7c99616c910479306e204e5db1f0fa3fe69f35af3164c7e5726b50000000000000000000000000000000005015082d6975649fbc172035da04f8aeb6d0dd88fdfac3fbd68ec925dc199413ed670488dc6588f9bd34c4ff527f149000000000000000000000000000000001312d53088ca58dfc325772b8dc0e1b20cebf7b2d5b6b4c560759987b44060bf4a59a68d1a5623bbb3cc5b0bc3986b810000000000000000000000000000000012110cd462c6fabf04f67d652639d19640c46f51aadd6c4f9a6dd7806cffb6192d95c198f4c8284151feaa2e2a0dbc1f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_26", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b0000000000000000000000000000000006d38cc6cc1a950a18e92e16287f201af4c014aba1a17929dd407d0440924ce5f08fad8fe0c50f7f733b285bf282acfc00000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352000000000000000000000000000000000f46bb86e827aa9c0c570d93f4d7d6986668c0099e4853927571199e1ce9e756d9db951f5b0325acafb2bf6e8fec2a1b00000000000000000000000000000000132d85236d655190323279a01acc8cbc6fb736d951e3999589f0559cb61ea93e2e1c526ed08ef08046c3d7a40d7cfdaf00000000000000000000000000000000117fd5016ddb779a6979d2bffe18032d9a5cdc5a6c7feeaa412381983d49ab894cb067f671163ccbe6225c3d85219db6000000000000000000000000000000000dcf01077dcce35c283bea662f4e4d16f871717eb78e630d9f95a200cc104fe67b0d69d95f6704d9812b46c92b1bc9de00000000000000000000000000000000121f212cd7251697ef6a7e3aa93eb0d7d0157cf1247d4411430c36c7277bf8acfccc4ed8590b5e8d0f760e0e4ed7e95a0000000000000000000000000000000007d22d78b486f575e01e21e1239cbedc4628ba7e01ecf4a3459bd78a9716e2969f26ea3f2449685f60397e1ab2aa7352", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_27", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000fb24d3d4063fd054cd5b7288498f107114ff323226aca58d3336444fc79c010db15094ceda6eb99770c168d459f0da0000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a60000000000000000000000000000000010cde0dbf4e18009c94ba648477624bbfb3732481d21663dd13cea914d6c54ec060557010ebe333d5e4b266e1563c631000000000000000000000000000000000a4ec4acf91be994fe45f08dbeb2bbd053275861d11a486693fd6e5bfa3736134396f6b1c3ad146642f2e972ba609d0b000000000000000000000000000000000224cbea61c5136987d8dbc8deafa78ae002255c031bb54335bcf99e56a57768aa127506fca1761e8b835e67e88bb4dd0000000000000000000000000000000018cbf072b544df760c051d394ff68ad2dd5a8c731377fa2a5f61e61481ad5b42645704a2d083c7d45ed4774e5448141e000000000000000000000000000000000740b8b7d7bce78a51809713656c94cf98de72887676050f65f74c57cbe574278dd3634c44e057ea95babcc3d230e3c40000000000000000000000000000000006696058a191c7012a4ee7c973c2005ac51af02a85cbb60e3164809a583b4431dda2b59e1c9ceeb652b3ac7021d116a6", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_28", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe976000000000000000000000000000000000824e1631f054b666893784b1e7edb44b9a53596f718a6e5ba606dc1020cb6e269e9edf828de1768df0dd8ab8440e053000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b592947030000000000000000000000000000000008c0a4c543b7506e9718658902982b4ab7926cd90d4986eceb17b149d8f5122334903300ad419b90c2cb56dc6d2fe9760000000000000000000000000000000011dc30871a7a9b33e2882f6b24ccd192aad215edfc6c6bd9acd064dff4a43f41b4c212068875e896daf127547bbeca58000000000000000000000000000000001522e0a4ccd607f117fc6fc8f9abcd704e9850d96adb95d9bfaab210b76bfb2c5dc75163b922bd7a886541250bc1d8630000000000000000000000000000000018a6e4327d633108a292a51abed43e95230e951e4476dc385ceea9c72ed528bf3e06c42d10cefbd4aa75b134936e4747000000000000000000000000000000001198587188e793ad2ec2fa0fa1d0da9b61ed48444fe6722e523aeac270f17f73f56b1e726ab811bb54a6e42e506d70a20000000000000000000000000000000004bedd94182e0f16c71223ac3d68ab327d28ee0ccdcd2c2db07faf69e1babe3fbf3ba09c28b146eca7ab047b59294703", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_29", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000c2ffe6be05eccd9170b6c181966bb8c1c3ed10e763613112238cabb41370e2a5bb5fef967f4f8f2af944dbef09d265e00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb00000000000000000000000000000000159d94fb0cf6f4e3e26bdeb536d1ee9c511a29d32944da43420e86c3b5818e0f482a7a8af72880d4825a50fee6bc8cd8000000000000000000000000000000000dd1137e592119c134103b9e29e4f14b48387a767d4effae44f807e5b579e7f9c2f60105495f070d0a6ab2410f62844d00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f7295580000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf20000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_30", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c0533455013242330000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad62420000000000000000000000000000000016ad3b981f689f51f46e3e5e166986e4e71655dcc1e928327751ffdcfff8934caec5cc37327b3320202c4efbcfda6ae3000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_31", - "Gas": 161000, + "Gas": 151000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000cbcd06a1c576af16d0d77ff8bcc3669a486d044cc7b85db03661a92f4c5c44a28d028521dfcfc292d8ecd05aed6ab940000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f00000000000000000000000000000000153ba4ab4fecc724c843b8f78db2db1943e91051b8cb9be2eb7e610a570f1f5925b7981334951b505cce1a3992ff05c9000000000000000000000000000000000c1e79925e9ebfd99e5d11489c56a994e0f855a759f0652cc9bb5151877cfea5c37896f56b949167b9cd2226f14333dd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_32", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac50000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c81292925400000000000000000000000000000000065d3d4be1589a6f00c85c208c44916a35349a096b09219704b4c31861ef58e6b4ea5be57a175b429e482b1038718d6c000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000e751ccbd475fe7eda1c62df626c1d37e8ae6853cc9b2109beef3e8c6f26d41a5e4e0a91bbc3371c7ab6ba780b5db41600000000000000000000000000000000184097644c9b44d543ebc0934825610590cc9f8b17ed08e9c06592bf85591d2702b18cf48a70b378926057e541eb8ac50000000000000000000000000000000003299542a0c40efbb55d169a92ad11b4d6d7a6ed949cb0d6477803fbedcf74e4bd74de854c4c8b7f200c85c8129292540000000000000000000000000000000013a3d49e58274c2b4a534b95b7071b6d2f42b17b887bf128627c0f8894c19d3d69c1a419373ca4bd1bb6d4efc78e1d3f000000000000000000000000000000001755d8a095e087ca66f8a118e0d2c7d5e4d8427dda8fe3049080f4aff12a8746f8c2679c310f4be0d94c5bef0414a7a600000000000000000000000000000000069c84c6419ed5c0441975ee8410065a56c65f07a4b545ff596b657dc4620c7405fd4d092b281e272773d2281a6359a8000000000000000000000000000000000b8bf51e6509e81b70ff44d6e0df8f9f7bc8e33126e9f1b5a8419414878a2209c05df56cf590c8e33f484587f4a1f6950000000000000000000000000000000001c07a85ece4a1c5072fe722fb264bd1d3aaabf9db9809d5a6cb3fe17157d8fd1bfa730a26e34c87279ea81abe141fe6", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_33", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c9973900000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda00000000000000000000000000000000055caff20f9f3f2ea27c64caeb6bb1880f326c64eb6ed6ee7d15da7bfeb16518f76a75f061cd347f7322e0cec634f0fc000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000001869606dde1688e5ae9f1c466c5897fce7794f3735234b5af1ad3617f0688529499bbdc9f0b911840a3d99fd9c49150d00000000000000000000000000000000001bfd33df4a6059608ada794e03d7456e78317145eb4d5677c00d482ac4cf470053d33583cf602feb67b6f972c9973900000000000000000000000000000000121b540a0465b39f2f093112c20a9822fc82497105778937c9d5cdcfe039d62998d47d4f41c76482c31f39a79352beda0000000000000000000000000000000014a461f829e0a76ba89f42eb57dffb4f5544df2008163bd0ea1af824f7ff910b27418a0e4f86cb8046dc1f3139cab9af000000000000000000000000000000000213e5d2d46523203ae07f36fdeb6c304fb86f552fb9adb566711c31262629efb0b1561585f85d2ac7be174682229bd8000000000000000000000000000000000b3336b5a4f7c0d16db9615e77bcdd55b7cb5b5c1591d835f34f5c1f1468e3cef954608667fb97a32e4595f43b845612000000000000000000000000000000000197b17c5b695db49c7c8b6fd6f314da7cfdfc4dbe61c76475839c89064870fad5104234c09aee7bafc1660263b6959e0000000000000000000000000000000019e514b65a358640ea90cd3cf547d591f5ff1a13ad99c568ef70c558cbec26dd1e582cc92d849fcfce9749068d361372", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_34", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c30000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000003c0c619be1382199bee84862a0ac6bf4c891d22f722b6af5bfef0edd1ed8c7e9af5efb5d3fc546801f3e019329ae4e80000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa520000000000000000000000000000000002c536dd2f05f4a7eaa33fd884262b22a2ab2a88e7b63cb08ebb67fc0f143da7d6b18dd394c424161f7cf703acdc82f50000000000000000000000000000000002d1d9ff74e20ea9b03c478784f57e7a58a21ca2b1e552319f33305f367f5ae4daf8138505f953db4f86c0ec1d96d5f0000000000000000000000000000000001383bc4d6c748d5c76ab4ba04f8fcd4c0fed9a49ea080c548893440819833ad72a8249f77391d5fbff78329eb319d3830000000000000000000000000000000016404bd07b6c6480af2d23301940e61817ee2e61fc625c100b31e1b324c369a583b61048dd57ab97b80b1fe6cd64c5c30000000000000000000000000000000004ac6e6077d4eddd0e23f30cfd64b7aa1525c85424224e70c15d7535e02aea7a312ef24ba2dcf70b926acb851da2530c0000000000000000000000000000000006ad07d3e8f45cedfb4279913bf0a29e37604810463d6020b4fa8c8c4977d69cffaa33e1149706f04eb237194dcafa5200000000000000000000000000000000173bdb0d0a79f1f2607867ddbf2581b4c1cc20fc0bced60ed8756aa4e79cb87c47fa722b1c8fdbe99a8208fc532327b600000000000000000000000000000000172f37eac49dd7f09adf602ebe562e5d0bd52ee2419fc08dc7fda241c0319b3f43b3ec79ab5aac246a783f13e268d4bb", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_35", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a030000000000000000000000000000000014c22dcacf2e21ff447c94d81067c626b1217e58b7dc98aacab2ea3fc00b1c5e66f660d19f1c69b16571e49d13c8e1d0000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec350000000000000000000000000000000018db123e05404eea8707f9356f417c3966312b9e41765a6fd8449879ddc4c9850c38434481b235a5bc35db1b8ee86d43000000000000000000000000000000000b4162715717e9065a3849a9294cfe39b351e57ab5a6790f3e725ad9fbf0e4b9d6a3554e872af9c37df33bb896dada5c0000000000000000000000000000000006bc68c6510c15a5d7bc6eebce04f7c5fce3bb02f9f89ea14ab0dfb43645b6346af7e25a8e044e842b7a3d06fe9b1a0300000000000000000000000000000000053ee41f6a51c49b069f12de32e3e6b0b355cd2c3ba87a149c7de86136a5d9c5b7b59f2d1237964e548d1b62ec36c8db000000000000000000000000000000001913ce14bcd1d7bbb47f8efd92d7ffd155ed1990a1dbf1ee7d5e6d592a92bcbec6e865199362950afd6c8fc49b3e10a400000000000000000000000000000000020df729079e76cf06f84e3355e683e093dafad38c2ba92cf7a9faa0515f2f44d814f971046ea20116cc4b0014d7ec35000000000000000000000000000000000125ffac343f97afc413ae80d40a309dfe461fe6b20eb84f8eec3a2718ec2c9f1273bcba2fa1ca59fdc924e471173d68000000000000000000000000000000000ebfaf78e267fd93f0e35e0d19feae9db125660a3dde99b028be77c6fac0116a4808aab02a29063c3c0bc4476924d04f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_36", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218080000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d0571200000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000010338047b7c67c122ffb13466935623ef2338b32bbf5452f78f7abe9a13a16824c11f5520c9dac256b9d257da88d92a30000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000f6adad0a3bab3610165be2fadb1b020f25488a0af3d418b7d7cf1165812e17aefcbc23308ebcd31d22ba4ca5773dd87000000000000000000000000000000001657ff792e3d89d5d35767bd0cc788411b0420665a5e0704f4d2399b9d9a5ad3c027ee030fdf495e5a6e2a4c69d0571200000000000000000000000000000000024ca57c2dc2a7deec3082f2f2110b6788c57a8cdc43515044d275fe7d6f20540055bde823b7b091134fb811d23468ce0000000000000000000000000000000009cd91a281b96a881b20946fda164a987243c052378fcd8fee3926b75576dfa1d29a0aaca4b653da4e61da82577218080000000000000000000000000000000008be924b49e05c45419e328340f1cbcdd3350bacf832a372417d8331c942df200493a3f7f2e46ad2cdaf3544cfd8cd8600000000000000000000000000000000028cd100457f4e930fc0f55996a6b588c5361816bb853d1f522806e5ec1c455eb200343476feeb07ca77e961fc2adc1f000000000000000000000000000000000a96371995c5333949b5e9869599fcb67222c2e44447d133e9b3e18a9e9e14a92ee03dcba86832cde7d35b35a88bcd240000000000000000000000000000000003a912710b425cc477c43ff93684249649732b1e99270bba725e990559169b505e8411fba174b6a15f90d5b3962f5399", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_37", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000008418a39124b40643dddcd6afe1dbdf930303bca65226c2fee1b95de6e080e25451f8b4f2b2b7c4633e1de6a5a7d47cb000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c0000000000000000000000000000000004cb55008ccb5b2b8ece69fac7283f5a9ef9e622e2a0e42bed5bdd77faa550882643afc1759b1a327c4f2277e13a3d4f000000000000000000000000000000001690dee40c6c824dc2588fc47dbf93f68ac250b9357e1112db72ded905ed7b101b5f877bdc42d56afb5b6202403a91c4000000000000000000000000000000001305e1b9706c7fc132aea63f0926146557d4dd081b7a2913dae02bab75b0409a515d0f25ffa3eda81cf4764de15741f60000000000000000000000000000000011bf87b12734a6360d3dda4b452deede34470fba8e62a68f79153cc288a8e7fed98c74af862883b9861d2195a58262e0000000000000000000000000000000000a5048d860b997a9fb352e58284ebbc026622d9be73de79b2807a0c9b431f41f379c255a2db0dd67413c18217cb21b7200000000000000000000000000000000045a701a3f46ca801c02a5419c836b2ab3d74ebd6f4fd1e7dddb1965b49c9a278f6e89950e7c35ebc6724569d34e364c000000000000000000000000000000001535bce9acb48b6ebc4d3dbb7c236d7cc57d656210e42e9379d4f528fc0ba59bf868503d3bb8e5cd3dafdd881ec56d5c00000000000000000000000000000000037033062d13644c88c317f1c58c18e0d9b4facbbe0701ac8bbdf3c7f0c37b14034c7882d5112a94bea39dfdbfc518e7", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_38", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb00000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000ada13f88a645bc6082c6321e0cf2b7ac45c633fe2f0cb36aeb187fe2e50e7510df2a86b98979e8551636e94488c8ce000000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000017078538092ace26cc88b94360871fc9a6bb9992172158ef3a16467919955083accf8d55d48c7ec462a743dbbca7b448000000000000000000000000000000000289b703157a02fc1d687a5aa595495be8bbb3eb0d70554728255a44b7820e0ee82d984d5493c800f1d9d8ca0c9381dc0000000000000000000000000000000012662b26f03fc8179f090f29894e86155cff4ec2def43393e054f417bbf375edd79f5032a5333ab4eba4418306ed0153000000000000000000000000000000000f26fdf1af1b8ad442ef4494627c815ca01ae84510944788b87f4aa2c8600ed310b9579318bc617a689b916bb7731dcb00000000000000000000000000000000153cec9690a6420a10e5a5a8ca46fd9d9f90e2a139886a07b375eeecce9083a5f5418e6baf64ef0f34176e432bc5343a000000000000000000000000000000000d87c1f37f83ae78a51af9c420e2584a64337d2d2dd8dc3b64f252c521901924e5eec1d9899594db5e64c93c7a01ef020000000000000000000000000000000002f98cb2305518737e92ee72e2c48d0dbdbbb1f2dc63b9d02d1a8c27dd1ba5a071dc72a8dcc7813b5757bc244357f6630000000000000000000000000000000017775ae72405e39e2db32d5b9db6637b7bbb9799e614bd783f0b785c3f2ee815367e67b15cc037fec8252735f36c28cf", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_39", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a3700000000000000000000000000000000162e49ebd1b50c7837336509e48ace0e7856f00ec45a76b96d1dd88eea300a8118357cafabf32ee2d06b601def523e4800000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b600000000000000000000000000000000048b3e4ba3e2d1e0dbf5955101cf038dc22e87b0855a57b631ef119d1bd19d56c38a1d72376284c8598e866b6dba37530000000000000000000000000000000007c0b98cda33be53cf4ef29d0500ff5e7a3c2df6f83dfc1c36211d7f9c696b77dfa6571169cf7935d2fb5a6463cceac6000000000000000000000000000000001837f0f18bed66841b4ff0b0411da3d5929e59b957a0872bce1c898a4ef0e13350bf4c7c8bcff4e61f24feca1acd5a370000000000000000000000000000000003d2c7fe67cada2213e842ac5ec0dec8ec205b762f2a9c05fa12fa120c80eba30676834f0560d11ce9939fe210ad6c6300000000000000000000000000000000057f975064a29ba6ad20d6e6d97a15bd314d6cd419948d974a16923d52b38b9203f95937a0a0493a693099e4fa17ea540000000000000000000000000000000014396ce4abfc32945a6b2b0eb4896a6b19a041d4eae320ba18507ec3828964e56719fffaa47e57ea4a2e3bd1a149b6b6000000000000000000000000000000001575d39e959d14b96f261265417ca949a248c3d46e2abb093541c103dadf58cd5b21e28c79f17b376070799492457358000000000000000000000000000000001240585d5f4c28467bccb5193e4aad78ea3b1d8dfb4716a3310fb5215a478aac3f05a8ed478486c9e703a59b9c32bfe5", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_40", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d0300000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000efe47bf2b11dd10608a309c8aaefdbcbc2bb5e6adceef375371cface8f79668e2b7c2ce9990063a3b53e419e80e2a79000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba000000000000000000000000000000001172684b21c4dfe02a55e13b57bbf105c954daec849d4c6df5276b02872c004fdf09d24f4eef366bc82eb72fe91bf70d000000000000000000000000000000001151aeb9441c5a8fabe80867b5c791420645241eae1400bbcc064d75bedd39de2ef585138fe9f65725efa1b1e5888d0300000000000000000000000000000000181dc6fd3668d036a37d60b214d68f1a6ffe1949ec6b22f923e69fb373b9c70e8bcc5cdace068024c631c27f28d994e5000000000000000000000000000000000b02ca2b0e6e0989ea917719b89caf1aa84b959e45b6238813bf02f40db95fbb3bf43d3017c3f9c57eab1be617f18032000000000000000000000000000000000b6069a2c375471d34029d2a776e56b86b0210c35d3eb530bf116205b70995e4929fc90349a7db057168dbe6c39857970000000000000000000000000000000014251a0a154731f73513b99d830f70b6fc4bcf05d11f52d2cbe9795ee8ffc5a5f717ad25770b8ecad6d0e9f8066e0cba00000000000000000000000000000000088ea99f17bb06ba20c5c67aeb8fbbd19b2270986ee7c6517209679e6f84f5d43fa22daf6264c993f1d048d016e3b39e0000000000000000000000000000000008af6330f5638c0a9f339f4e8d841b955e322766457112039b2a852b37d3bc45efb67aeb216a09a8940f5e4e1a771da8", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_41", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f000000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c1872290000000000000000000000000000000001099fe889d8f5ddcad09328997c7c3098ef4b4d74ab1d9f6fcbc33a03cafb59c7b28931da67950d1389fbcedca3fb5bb00000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e000000000000000000000000000000001995b9d697bded656236430e78726f0f6ef963db9a5a24d455c12db38aeab0f8629e5dc2d04920156f2a057d69613096000000000000000000000000000000001119b13caf82c18fadcb65c9c166914bfd822534bb9def3feae6c9e572c97c84e97fab3b345cf59358436a404075493d000000000000000000000000000000001329a75975b714c861064d743092866d61c4467e0c0316b78142e6db7e74538a376a09487cb09ee89583d547c187229000000000000000000000000000000000096713619bf088bd9e12752cab83e9cdd58296ada8d338c86a749f00ba014087a3836ce10adaaf2e815f431235bff4f000000000000000000000000000000000161b70d0f384e589d8117938602f3d696f941c24e3c1ca5a9be090b670456c9df315d6fde52daed55c9d8335928a7a3c00000000000000000000000000000000186bb9e6f5ba70dd2c66a641d3b711844977939904c59946d4e9f49ac2d8c00890a43ccb20d4a62bfff63ce4a0a44e8e00000000000000000000000000000000006b5813a1c1f934e8e564a7cad93dc7f57de7a9592aedeb116fa4ed6bc6452bbc0da23be10adfea4ad4fa82969e7a150000000000000000000000000000000008e760ad89fd250a9d5041ec81e51b8b66f5265037e7237f7c4a08bb83e7799f352c54c37cf70a6c61bb95bfbf8a616e", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_42", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a9000000000000000000000000000000001750d2e78525453f113b76f18abf2334de9755c03786fbc9233cda2364d57ed493f4fe6c2b565f4d82ff8113e9b63c4d0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000001bca57e985906695e14882f2aaeef75de5009e8717eb59962e978aa11e9d0a4d9a9e203df774cb1e993b1c6ecd6048c000000000000000000000000000000000695b11cc32740c91546eb7d554ca8b1f3afc942ad977345031be8b94b78b57a87ab049ca2d3676e039efccbf24d0c47000000000000000000000000000000001195502bc48c44b37e3f8f4e6f40295c1156f58dbc00b04b3018d237b574a20512599d18af01c50192db37cb8eb2c8a90000000000000000000000000000000002b03f02b45aa15b39e030c4b88c89a285dff5c4bbfe16f643f3f87d91db774f8ab7019285fda0b236ff7eec16496e5e0000000000000000000000000000000017d1ffcad218efd8b09c68eba34dbbc30b0a62ae250368ee37e5f6fd40479b8580563416afdbd92c0622c341331e20a30000000000000000000000000000000009f0eb3805ed78aa3952a0a437966258ed38cb72912756253a7a2f9113f0dd9a4e187062b0423e0587d93e904d88f50d0000000000000000000000000000000018446c6ba126e030ed071f87189cbd618627419c82065d26044759f6e4c7257f45021dfad1dcb34dd06b4e391329a61f00000000000000000000000000000000136b60cd7658a5d135d4bc38edff042570c7824245ed9f7a6414e9e7ab3840a99700fb620e809891b66003340db29e64", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_43", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb0000000000000000000000000000000001a28b7856a22db6e79ac4165e60addbb7dfe1f19d815032bc68fea905bd0d7709c2dafc65fe51493c964de678a30d32000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb8776600000000000000000000000000000000135b3db43511dbd8b3bd5a91880d6da1a2bd1383000e0d6f0a521bf88a5836a3b5f7cb9c0c02aa861a1c2d339f3c11f20000000000000000000000000000000000e1337271bd3302a1cab762161ccfbf2a18b7800e6efe58cf897d4adbfe4cb3bf14f4b59307fffc548179bda70c18bf000000000000000000000000000000000d7e1651f3e172dcca8774a7a0d58ab47178d3e759933289e1d3eb0da414160ff9e890a608bf8ccdf2820c4aea6e11cb00000000000000000000000000000000185e8671e2ddb8e36380e39fe4eafefbac9769935603c28caac7d3f7f0f3e8ad14e925024b55aeb67d68b219875c9d79000000000000000000000000000000000546a0cb9d9f1ef9ec4a1e576fa0047557a56c0217baed8691c4085b88c84a0e12d44043aab8671393d02c4a764407ee00000000000000000000000000000000131884c1386980a181353548da9602db70ab495a661e76235c4b0a32b54acb0dfd8846e17bebd731e8041c4aebb877660000000000000000000000000000000006a5d436046e0ac1975e4d24bb3e3f35c1ba3801f37705505cdeb6a86c58bf8068b43462a55155799fe2d2cc60c398b900000000000000000000000000000000191fde77c7c2b397a950f0542d2edd183a5e9404e516146697a755561ab2a9705f970b491e4c0003657d864258f391ec", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_44", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e82000000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e270000000000000000000000000000000007c17aaf82c2aa6bf01695157bcd0c2b34734dfbd572b0abe79c8dd3eef7ce6eb9c5e7de55b36ddf87f05e55ba9ac28b00000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df70000000000000000000000000000000012c5b00376a1dd31378ec44f2dc8e321e17185d903cfc5c15345a01c33f2f151b21b938d31816550594a7a1e7216c5b00000000000000000000000000000000013d79f825c44775c68e90932d0496a5cae53f04a1edb19f8abeb5948a3dd325dfec4a8b6f58c7fbca9cf3c09b909d8b2000000000000000000000000000000001454d4a82163a155446467164904cefd7e1e3c67ae99bf65c581a75c72716fb011e2fd030eaf3d36977fbb0ff5156e2700000000000000000000000000000000123f973ab6bd3c2e5b0512a0c77ea0ac3003fd891e1262137f9444cd07b927b564e618205ba09220320ea1aa4564e82000000000000000000000000000000000113dc3354146ca79eb103b31b61fe8bc6f33dcb9c59a7c39d989bd9411c1afce4239034f84e6b00a084be061c73e69c0000000000000000000000000000000000ae33bf68f24978c7ea9fc58d8d76047ec45d01fdbc880e6a5ba02a22a49a3a8253afe0678ecfa6013f4849da3401df700000000000000000000000000000000073b61e6c2de0969138ce3671582c9b58305c5abefb54cfe13eb3284c2be04d26c906c717fd29aaf60b485e18de8e4fb0000000000000000000000000000000006297267dd3b6f3de2329e837302427ab6235b3ad4a9f8c6bb45795852d3c3c61fe75747bbc78043102fc3f646f5d1f9", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_45", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000017147eda83f35d0b6c8894317da5b2e991818479674d7dd1aef6bfaebacbb61ad4b2a17ce7e799939f8c2004af4799530000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c743900000000000000000000000000000000101e143b838c8a3f5f80fb1412081091b875230f1e2f9cf374d4bcd595392f6daa9552dbb6d5834e27b1b3dafe061ed300000000000000000000000000000000072463400b3e875395a1cdd31d73d51396e34347cd86d9f6f43f42253b3cdb24b89ed7434b1522af95ba1ee2d29ed1bb000000000000000000000000000000000178e6828261ee6855b38234ed15c27551bb1648ac6ec9a9e70744643cd1f134b2309dd0c34b1e59ddfe3f831ab814c90000000000000000000000000000000002ec930fb58c898ede931384c5a5f9edd2f5c70b8c3794edb83a12f23be5400949f95e81c96c666c1a72dffb50b811580000000000000000000000000000000006ccaf6c08f831be9c99a97714f5257a985cc2a29b5f5c81bc8d794dd0d8d1a41eb5413bed654c0140dbacfd0dda9e1800000000000000000000000000000000144e9cf91580800dfaa47c98ff7d002a576be76d9e44ae1f8335a3f733e1162af0636372e143174d872c7ea89f4c74390000000000000000000000000000000009e2fdaeb5f35c5aeb9aaca231439c45ac022875d55575cbf25c15cb6177c6b67416ad22fa7e7cb1924d4c2501f98bd80000000000000000000000000000000012dcaeaa2e415f46b579d9e325d7d7c3cd94083d25fe38c872f1907bbb741aff660d28bb663edd502444e11d2d60d8f0", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_46", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f10000000000000000000000000000000016c1c9ca735535f801c58a9e35a80ce122d20abb327b44db4dea31b899982c4e136a2430c51cf3a31adc5611621f9dde000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000eb731bc99cdadf7f2280385c7e17d72d34bcbdbdc725d5bc94e841036115e8cb95df08084221696f9be479821fbdd7400000000000000000000000000000000143ba7d3f66445249d9a81a6949f24ff40e7c4d270fa044a8b80200a4369b07806c5497a0ef9e9dbb87b9e63694623ee0000000000000000000000000000000001ea88d0f329135df49893406b4f9aee0abfd74b62e7eb5576d3ddb329fc4b1649b7c228ec39c6577a069c0811c952f100000000000000000000000000000000033f481fc62ab0a249561d180da39ff641a540c9c109cde41946a0e85d18c9d60b41dbcdec370c5c9f22a9ee9de00ccd000000000000000000000000000000001354146aa546754e10ada6e0fe98f04f5f3a3f8a8350d0295e02b8e9c80735b04c3061412e08ddb13c80ac36e5638e540000000000000000000000000000000012ab26513534b4dc1b71eec46b73199c4157ba9369e66fbe4d2d8f62237fc7c6fad31854ebd878f989b8c5cf35c7cfe0000000000000000000000000000000000b49e02d9fb238a258f3a4307b6a2f64912b7fa91712b5639de24e90c09f9797654e0f7e2d31e968c040b867de03cd370000000000000000000000000000000005c56a16431ba175ad81260faeac87d8238f86b2828b0e74dbb0b296b34745ac17e6b684a25a16240183619c96b986bd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_47", - "Gas": 184000, + "Gas": 194000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe90000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb90000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be100000000000000000000000000000000084486ebc81878331aab7d6f53ca3c773fda7b181b56a93e5ee0bfa189afbb7fd7a05c5bea35ec1054c0e1ddc2e2dac20000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000068edef3169c58920509ed4e7069229bd8038a45d2ce5773451cc18b396d2838c9539ecb52298a27eebd714afacb907c0000000000000000000000000000000004c5346765a62f2d2e700aadccf747acb3322c250435ce2cf358c08f1e286427cabace052327c4b30135c8482c5c0eb90000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be10000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe90000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000137232f722e38e084611ba67d2e28a3b8c73c13f20b6bb4c22141115bd43cdeb555861335f2a75d7cb418eb505341a2f00000000000000000000000000000000153bdd82d3d9b76d1cab9d087654652ab1451f5fef4f449273d81211d88891fc53f131f98e2c3b4cb8c937b7d3a39bf20000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be100000000000000000000000000000000084486ebc81878331aab7d6f53ca3c773fda7b181b56a93e5ee0bfa189afbb7fd7a05c5bea35ec1054c0e1ddc2e2dac20000000000000000000000000000000013a3de1d25380c44ca06321151e89ca22210926c1cd4e3c1a9c3aa6c709ab5fdd00f8df19243ce058bc753ccf03424ed000000000000000000000000000000001657dbebf712cbda6f15d1d387c87b3fb9b386d5d754135049728a2a856ba2944c741024131a93c78655fdb7bfe3c80300000000000000000000000000000000137232f722e38e084611ba67d2e28a3b8c73c13f20b6bb4c22141115bd43cdeb555861335f2a75d7cb418eb505341a2f00000000000000000000000000000000153bdd82d3d9b76d1cab9d087654652ab1451f5fef4f449273d81211d88891fc53f131f98e2c3b4cb8c937b7d3a39bf2", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_48", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c600000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000a5b95d6031e92578f6b5de5b8873e87486fd818214be93814753dcf6665229758248a6529892265fcc2b2ba45f89171000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000f6fdc4e5dceb555c9eb4c912fedbfb3cb1b842345f73ded02cfaf8d397c4378809721094aa4a4113a368e0787effeb500000000000000000000000000000000143ac06258c579c11c05569669a2a10babc63ecc86f85c91791d8ea48af700a2067c5f13d2700b8d5cf59bcca8fbf7c600000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000fa57c1436615442bbb049d08ac46e501c07736cd239298752bb94d1904bd38cc687759987cadd99bd3c4d45ba07193a000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000a91359bdbb1314481305b25135ded23995bc761ad8dd4d264612313bd34b2ab9e14def566af5bee7fc871f8780fabf60000000000000000000000000000000005c65187e0ba6cd92f16511fd9a90bcbb8b10cb86c8cb62dee1343fc6bb9f582182fa0eadee3f4725d0964335703b2e500000000000000000000000000000000120ddc1cd9e3a7b298673b1036d162c31dbb35d6e83b39b2564b3be16e446a836c96907e8a6af1e677e906bf5ed73159000000000000000000000000000000000a5b95d6031e92578f6b5de5b8873e87486fd818214be93814753dcf6665229758248a6529892265fcc2b2ba45f89171000000000000000000000000000000000dd75b4aebed3bd6bd020c3af671aaed67bf1582aceb6c8b5a476968c0c500753e4d0f3276341b79d87af38850893d92000000000000000000000000000000000e9b3be06afd6157eb6df52be4f2db2bcccd650f720661f8d6fcff3f71d69e152e17100ce60b7b90a7f798c4cdd02209000000000000000000000000000000000a91359bdbb1314481305b25135ded23995bc761ad8dd4d264612313bd34b2ab9e14def566af5bee7fc871f8780fabf60000000000000000000000000000000005c65187e0ba6cd92f16511fd9a90bcbb8b10cb86c8cb62dee1343fc6bb9f582182fa0eadee3f4725d0964335703b2e5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_49", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b60000000000000000000000000000000002a534a7e1432aa317f782a581f974d23ec75420611165d0486ecd377660fa7c2e8235f829c64501d1b9bf3131e87289000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc500000000000000000000000000000000192f3e8ae2588f9223de77f5e872115f1edec96d6a0f403a47879410c2562e79853c9a706e423b83fbf3154234edb6f80000000000000000000000000000000015084258d58fd1a07bbdb2e90df5a56ae15a787037eff4fe55f660e45f04820c6fc8982303b5e82074cf0cdcbde61307000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b600000000000000000000000000000000175bdd42583cbbf733242510c152380525aff7649273acef1ec20569804ffba7f029ca06878dbafde84540cece173822000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc50000000000000000000000000000000000d1d35f57275708273d2fc05ad99b78459882178975d2851fa93e90345ac7aa996f658e4311c47bbe0beabdcb11f3b30000000000000000000000000000000004f8cf9163f014f9cf5df4cd3556076c831cd314bb951dc1113a71bc97ac7417aee367dbad9e17df452ff323421997a4000000000000000000000000000000000e3ccaa4fa358a5a885094cbb0b8baa106fbcca66edbe31511ac2f6f3d14edbd8701979d6e4690853555c625091392b60000000000000000000000000000000002a534a7e1432aa317f782a581f974d23ec75420611165d0486ecd377660fa7c2e8235f829c64501d1b9bf3131e87289000000000000000000000000000000000057bbf62cdf3c56e146f60f8ce6b6bdebe7aae7d9410c6902c7a505b589ae26ce3ab67d9b8da047185f9d37ab27595e000000000000000000000000000000000843e55c07bba3573592d3f649938654a5c51f9ced0f92bcb3e4f431141fe91a1de3695324b21e31dd2ae0a328055cc50000000000000000000000000000000000d1d35f57275708273d2fc05ad99b78459882178975d2851fa93e90345ac7aa996f658e4311c47bbe0beabdcb11f3b30000000000000000000000000000000004f8cf9163f014f9cf5df4cd3556076c831cd314bb951dc1113a71bc97ac7417aee367dbad9e17df452ff323421997a4", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_50", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc260000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000d4197b85280f1a5e4cfdd6a7acce516b34a5e12cf55081a858a2ad517d12733aa294a2ca1adf81bc9bf22922fbfd99f000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f000000000000000000000000000000000477b55bd7fff14e0d1807bfc21edb9481be01c12abb1460d78b1aafe42953730167e32e694c2ddfb0d442e8cea57d460000000000000000000000000000000004b884c6ea36f189dbc3c0e9cf88f08baf5d868579998f63b752e61fcce3cf2c901bb9b51959d3597c4ef53cff41fc260000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000cbf7a31e6fef4f4664bca4bc87ec7c0b12ced7224300aa4e1a6a7cbdedfcef07482b5d20fa607e3f03fdd6dd03fd10c000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f0000000000000000000000000000000015895c8e617ff54c3e039ff6812cd142e2b949c3c8c9fe5e8fa5b7f11287a2b11d441cd04807d220092abd17315a2d650000000000000000000000000000000015488d234f48f5106f57e6cc73c2bc4bb519c4ff79eb835bafddec8129cd26f78e90464997fa2ca63db00ac300bdae850000000000000000000000000000000001bc359baeac07a93aca770174ea6444aac9f04affdaa77c8a47b30c60ee2b527c061a4344139264e541d4134f42bfd0000000000000000000000000000000000d4197b85280f1a5e4cfdd6a7acce516b34a5e12cf55081a858a2ad517d12733aa294a2ca1adf81bc9bf22922fbfd99f000000000000000000000000000000000bcec23e092111b38a2f7dc957cf455312ffd33528d084204314492440d29248cb5719346a4f7a490d17ba149e30de5200000000000000000000000000000000194605e5680cc80bd2685949efa3cce90d345b9151ba72f3adf226dd299c23464c4344a42b8834131a51a4156038585f0000000000000000000000000000000015895c8e617ff54c3e039ff6812cd142e2b949c3c8c9fe5e8fa5b7f11287a2b11d441cd04807d220092abd17315a2d650000000000000000000000000000000015488d234f48f5106f57e6cc73c2bc4bb519c4ff79eb835bafddec8129cd26f78e90464997fa2ca63db00ac300bdae85", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_51", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb341500000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa00000000000000000000000000000000145688bf2f7a76a4341564a725a16dd5009b4a5174d766e6bf337a8bcbb11c797b82173d92aa796da6b168e734be90ec00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac800000000000000000000000000000000183b7b917aaaa94f0ea9959273ed4701102346be2a9d72531bd18fef908ecb0579a6ac10ed42a91f1147fc3a05b2e81900000000000000000000000000000000070983b1582a97d9797782e4f960a298aaa8ec509720495acdbf176d8ecb9ec9e041c2b5ed6b7dfb46fdeaae3fb341500000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa0000000000000000000000000000000005aa892b0a056ff61706430f1daa3f0263dc01337eadabd8a7fd58152affd9aaa329e8c11ea98692134d9718cb4119bf00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac80000000000000000000000000000000001c59658bed53d4b3c721223cf5e65d6545404c6c8e7a06c4b5f42b166222b1ea50553edc41156e0a8b703c5fa4cc2920000000000000000000000000000000012f78e38e1554ec0d1a424d149eb0a3eb9ce5f345c64c9649971bb3367e5575a3e6a3d48c3e8820473011551c04c695b0000000000000000000000000000000006b06ae8cb0981bf5167ad51e19d132db77548c4376697f855c8397b835743c42771096ed7b0a4b18af9494e42ee89aa00000000000000000000000000000000145688bf2f7a76a4341564a725a16dd5009b4a5174d766e6bf337a8bcbb11c797b82173d92aa796da6b168e734be90ec00000000000000000000000000000000073341309b6fbabb18f3cf0842817905e9248db98b582dc0efb2b741a80cdbb13d0df4bce920f257996b95029891a36f0000000000000000000000000000000012d19e09dc254bd1e84afce75aa215c96dd38bcac3f6d4cf08d9e2e8d20345b7c534a0b14ffcdfd4fa3600730e2eeac80000000000000000000000000000000001c59658bed53d4b3c721223cf5e65d6545404c6c8e7a06c4b5f42b166222b1ea50553edc41156e0a8b703c5fa4cc2920000000000000000000000000000000012f78e38e1554ec0d1a424d149eb0a3eb9ce5f345c64c9649971bb3367e5575a3e6a3d48c3e8820473011551c04c695b", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_52", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b10000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a030000000000000000000000000000000003942eae34fd3104cead334a2cbb2131eaa10b59d07949479331a8f4cc66761cd5d23eb8a861ae618f3a2e01b25080f9000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b0000000000000000000000000000000010f7bf9f6711ba723bb71a004a90109ee22be6643d56d410da18103ef44a1b3d50f10c4b94222c7f05fd3c28acbdc8ee00000000000000000000000000000000007af41f09e6d0adcb1935d6a93ea1f6156fa0157a63f265a3a7ceffe82f6635b8511e7e8f21e8f3be7a73513ff597b10000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a0300000000000000000000000000000000166ce33c0482b5957c6e746c16908ba579d6402b230bc977d3ff29ac2a4a800748d9c14608f2519e2ac4d1fe4daf29b2000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b000000000000000000000000000000000909524ad26e2c280f648db5f8bb9c38824b6520b62e3eae8d18c2620266dae6cdbaf3b31d31d380b401c3d75341e1bd0000000000000000000000000000000019861dcb2f9915ec800271df9a0d0ae14f07ab6f79212059c38903a10e818fee665ae1802232170bfb848caec00a12fa0000000000000000000000000000000015dc9f87213e4781863ad43f6bbccd547967d9bcf6a35d95d530cbfbf0d7307981aee5bc4ccd41254841651717393a030000000000000000000000000000000003942eae34fd3104cead334a2cbb2131eaa10b59d07949479331a8f4cc66761cd5d23eb8a861ae618f3a2e01b25080f9000000000000000000000000000000000dca3b392f75583b5266a8def02bd66bf44f26b8a0a27aced57299756cffaf9e1af3538beb08b2a5939b745c8f016fee000000000000000000000000000000000d7feafc9ec0935d5b7be7cd5e2a3c57b667aba9fcc87fd5b8a585010be6958c4e7538a6d2a1f46c9641ff7b8598d74b000000000000000000000000000000000909524ad26e2c280f648db5f8bb9c38824b6520b62e3eae8d18c2620266dae6cdbaf3b31d31d380b401c3d75341e1bd0000000000000000000000000000000019861dcb2f9915ec800271df9a0d0ae14f07ab6f79212059c38903a10e818fee665ae1802232170bfb848caec00a12fa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_53", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f60463000000000000000000000000000000000575bd953fc6600f5b48faea1032cf2b6615bf34cc9c526fdcc5042a292812d35fef2884bf51e017eb24c174b2bc20a00000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a0000000000000000000000000000000003a6cc74cc398f38d535b4341faa37c968daf2009c3f05ace1f938b33bbe4002d81d18d30c2c856b21afe7a22b83c37a000000000000000000000000000000000452d1b2da6392f9df1bfd35e4575c565333703b2f83f56e0a88a0c8195968c5321296b07f6750584e23597304a5472e00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f6046300000000000000000000000000000000148b5454f9b9868aefd2accc3318ddabfe618c5026e8c04f8a6bce76cd88e350bebcd779f2021fe7ceda3e8b4d438a0b0000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a00000000000000000000000000000000165a45756d46576175e5f38223a1750dfb9c598457460d12853799edbaf2b621468ee72ba5277a94984f185dd47be7310000000000000000000000000000000015ae40375f1c53a06bffaa805ef450811143db49c4011d515ca831d8dd578d5eec99694e31ecafa76bdba68cfb5a637d00000000000000000000000000000000171fbc9cec717964c4324aa0d7dcf56a59b947c24a9092157f4f8c78ae43b8e4222fd1e8acdbf5989d0d17ea10f60463000000000000000000000000000000000575bd953fc6600f5b48faea1032cf2b6615bf34cc9c526fdcc5042a292812d35fef2884bf51e017eb24c174b2bc20a00000000000000000000000000000000019e05ccf064f7cdad9748d328170b3e4bcfa6787dbfa93011d16f6d031648faa10dbfb7cc4d7c884d75480c4c864bb75000000000000000000000000000000001999d5f54ee66b3c0dedf9f46450e0ed463fa9c6cd9e0db317a35ec6ce78efae9bea9b64e3b2aaf7f70fbcace71b075a00000000000000000000000000000000165a45756d46576175e5f38223a1750dfb9c598457460d12853799edbaf2b621468ee72ba5277a94984f185dd47be7310000000000000000000000000000000015ae40375f1c53a06bffaa805ef450811143db49c4011d515ca831d8dd578d5eec99694e31ecafa76bdba68cfb5a637d", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_54", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e60000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a000000000000000000000000000000000032e4fbb8dab462ff0352c2d3925b0e97ca662189129928ccc1714364e4f01d8b026887d808342091ad442b6e11635910000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf780000000000000000000000000000000007a9cf48dbe005c5c59b2c731cf4117e5fadc9cb2cd8f486f1ed58b2909092ee8f36d88b8f719db94715641b418ab4240000000000000000000000000000000004ba40d4766b91bf8da1cc2526f62791a1b5f6fc24ffc54b522dd30cde2d29a6a6f81e8429d518710843d43705f3b4e60000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a00000000000000000000000000000000016d2c22eabd4a06a5ae67b890a25fbede7d0e96c625b80329b19be6aa861f44b6e85778130d0bdf69f2abd491ee9751a0000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf7800000000000000000000000000000000125742a15d9fe0d485807b4326579b5904c981b9c6ac1e38754379ee662063358f75277321e2624672e99be4be74f687000000000000000000000000000000001546d115c31454dabd79db911c558545c2c15488ce854d741502ff941883cc7d77b3e17a877ee78eb1bb2bc8fa0bf5c50000000000000000000000000000000018724e2b9a2f383329207ee85577805f35d5c5bb9f6903e3c962e57ab7eb9d1639d1e9adbde53499863b299f576325a000000000000000000000000000000000032e4fbb8dab462ff0352c2d3925b0e97ca662189129928ccc1714364e4f01d8b026887d808342091ad442b6e11635910000000000000000000000000000000004506802747afd8777904c46ad9bf0b06859a1b395ca3474a93ca4151ca158d2fd41b3a21e0ce0bc950b3241256e10d800000000000000000000000000000000115f41d2c173c3c2c7ecdff1a4aaa3c2e67c803db7a588d6143fe913961eef743d8b1f9d32e3ef1fc0475f41572faf7800000000000000000000000000000000125742a15d9fe0d485807b4326579b5904c981b9c6ac1e38754379ee662063358f75277321e2624672e99be4be74f687000000000000000000000000000000001546d115c31454dabd79db911c558545c2c15488ce854d741502ff941883cc7d77b3e17a877ee78eb1bb2bc8fa0bf5c5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_55", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df910000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c320000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000ae6134f1fec83a52e5358db260eb9dc6b918f7a803aae5715854ebee2b9bbecea9ab0d955f2e13e2c47a96b234ecb1a0000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c7952820000000000000000000000000000000008ceb842a17953578013ceee519a28ef1b37f73e13564def5ffe08a64dc53aa680784e26138176c89269477ee003d16700000000000000000000000000000000159791b6f2c26ed611ca40bfbd2059c15cfec9d073a84254ad9b509ef786d62d17fdc67ab13092cf0b7b3482866f4c320000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000f1afe9b199362f51cc84edb1d3cf2faf8e5bc0a734a646851ab83e213f73a3734114f255b611ec18db75694dcb0df910000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c79528200000000000000000000000000000000113259a798069342cb07d8c7f1b183e8493f5446e02ec4d00732c9faa8ebbb7d9e33b1d89dd289372795b8811ffbd944000000000000000000000000000000000469803346bd77c4395166f6862b5316077881b47fdcd06ab9958201ff2a1ff706ae398400236d30ae83cb7d79905e790000000000000000000000000000000010fcf5e5e478ac6442b218ce261878d8f61b405c0b9549512e23ead1f26a2240771993f8c039fbce4008a1707aeaaf25000000000000000000000000000000000ae6134f1fec83a52e5358db260eb9dc6b918f7a803aae5715854ebee2b9bbecea9ab0d955f2e13e2c47a96b234ecb1a0000000000000000000000000000000019cc0ec24da141f27b38a53aef0b3d93c4c2b981c1b248014be277002d39d7bde66f6957a659a89adcd3477dfe4f897a000000000000000000000000000000000e4c01d7425e35be84e3cf806aa76a079cf4557732980f7e8f8ce9a879483e28f223694ed8dd45706e12272f4c79528200000000000000000000000000000000113259a798069342cb07d8c7f1b183e8493f5446e02ec4d00732c9faa8ebbb7d9e33b1d89dd289372795b8811ffbd944000000000000000000000000000000000469803346bd77c4395166f6862b5316077881b47fdcd06ab9958201ff2a1ff706ae398400236d30ae83cb7d79905e79", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_56", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000000d9bd58946a4d26e3f97e5fe96e574d6f93562c0fb0c187c0c586208fe9a4d9383d3ca22b272ff3eb7e624ad7fb9ea7000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf000000000000000000000000000000001272c63693873e1dabe2c2739310f627d3d9b5bcaa615402c3849ffd8dfe72b40fea4a068064655f2c8f46f074e6518d0000000000000000000000000000000000161a8e5e1de10938e5bce241ae73d76173022127822d744b23e656095c28f2f8d142ceb48b72a1dbc36b6143f8af95000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000019275491a51599736722295659dd5589f4e3f558e3d45137a66b4c8066c7514ae66ec35c862cd00bce809db528040c04000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf00000000000000000000000000000000078e4bb3a5f8a87c9f38e542b03ab6af909d95c84923bebca3ac32a368b283700ec1b5f830ef9aa08d6fb90f8b19591e0000000000000000000000000000000019eaf75bdb6205911235ead4019d390003044963cc02e54b1c0cec4aed54cd3125dabd2ffcc88d5dde3b949ebc06fb16000000000000000000000000000000000f75bc9feb74110697c9f353686910c6246e587dd71d744aab99917f1aea7165b41deb333e6bd14843f28b2232f799830000000000000000000000000000000000d9bd58946a4d26e3f97e5fe96e574d6f93562c0fb0c187c0c586208fe9a4d9383d3ca22b272ff3eb7e624ad7fb9ea7000000000000000000000000000000000040d03956c821010969a67c91a6546800c5aa7ac392b16a9895136c941f4ca9f378c55446161562feace3b5b65f3c4f000000000000000000000000000000000e4b299f9fb25caec655d21c390bdad3c1256ca29faa33466a13aaa6d86310106d95fc8d8a0409fbd228fd3be7965cdf00000000000000000000000000000000078e4bb3a5f8a87c9f38e542b03ab6af909d95c84923bebca3ac32a368b283700ec1b5f830ef9aa08d6fb90f8b19591e0000000000000000000000000000000019eaf75bdb6205911235ead4019d390003044963cc02e54b1c0cec4aed54cd3125dabd2ffcc88d5dde3b949ebc06fb16", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_57", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e2946000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000f77a58fb4b4165bf86d30b6349b84780d72b24e8eddce16c73a1f5a06de0638045a64978eb9c477d806f1955e818165000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a220000000000000000000000000000000018a236ea02b1971d6e193a6eb92e1298956679d86864042fb6a0c36dd91c0e385944d779dedd0149fa8a1b3d6a07949d00000000000000000000000000000000048eac7d116b5a7906bce070e2b51ee7c4c493f1415abdb6fd2d35676036d3b741d14b7135419645a6906018e9d3f150000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000a896c5a84cbd03e52ae77000eb0285f5704993664a744a89ff6b346efd2efec1a519b67229a3b87e1f80e6aa17e2946000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a2200000000000000000000000000000000015edb0036ce4f7cdd026d478a1d9a3ecf10d1ac8b210e8fb0900f331d94e7ebc5672884d276feb5bf74e4c295f8160e000000000000000000000000000000001572656d28148c21445ec74560968def9fb2b793b22a55086a039d39967a226cdcdab48d7c1269ba136e9fe7162bb95b000000000000000000000000000000000a87d0ccfb9c01148703d48993de04059d22a4cc48c5dabd2571ad4f7e60d6abfbcc5fb3bf363fd311fec675486c2a20000000000000000000000000000000000f77a58fb4b4165bf86d30b6349b84780d72b24e8eddce16c73a1f5a06de0638045a64978eb9c477d806f1955e818165000000000000000000000000000000000b50dc0957eccf5ad941b148a3824e82464bb7345a05125a0aa64f6ba34e34e767d4f679e9916faaacf82b3c79c9bddc00000000000000000000000000000000087152b3cb0db88776a7144fbafc1b210d150b637ca7148e3df600989231bce613fcf8e310fcc53aa2dc934bcbf86a2200000000000000000000000000000000015edb0036ce4f7cdd026d478a1d9a3ecf10d1ac8b210e8fb0900f331d94e7ebc5672884d276feb5bf74e4c295f8160e000000000000000000000000000000001572656d28148c21445ec74560968def9fb2b793b22a55086a039d39967a226cdcdab48d7c1269ba136e9fe7162bb95b", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_58", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000018bc060c3f6be35b724dee72bcda5cc376dc1f35561f7e70c9fe11eda256edd30aca8c19018433483186beb5b9b2792700000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c95384000000000000000000000000000000000003c96c6f20d7ac31ee7ca77d11e8d25ea78cdf13e5f4d317752320e059e19196f14c15b5a18ca712f3a7cc6f09be6d4000000000000000000000000000000000ebd71f61fcddf1652675f577bbaeec26b892dd954965b057ffb431d6e37cc5425a2a42a0059482c2bd75adb2a120b0b000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000001450bddfa14033ed8cdb94386715013ed9b2c4f9d65944e9d32c0b3545a085113e173e5afcfccb78878414a464d318400000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c9538400000000000000000000000000000000019c47b2347726bd72c33dd3e722d1fb179fe7d93b525c58defdea092f112dd0aaf973ea3573b358e8ac483390f63c3d7000000000000000000000000000000000b439ff419b20783f8b4485ec790be14f8ee1dab9eeeb7b9e7358f83887929cff9095bd4b0fab7d38e27a524d5ed9fa0000000000000000000000000000000000d35ffa284655a94c3050213f4f14e927c162818bbfd0480bad2e07000dd3081274056715c96408f243589d83365c9f20000000000000000000000000000000018bc060c3f6be35b724dee72bcda5cc376dc1f35561f7e70c9fe11eda256edd30aca8c19018433483186beb5b9b2792700000000000000000000000000000000094fdcc2119b4f674b5639653dfabcac59c2adb1ee2ec06c55c3f148c9361351ff0acb2519e4638cb2cde98efaec8f4400000000000000000000000000000000051d5edcbd6eadac808222f0423bada165fcb98f98a89f335c981262b0ca7ea1c536d41aa41b49b25f0c43f53c9538400000000000000000000000000000000019c47b2347726bd72c33dd3e722d1fb179fe7d93b525c58defdea092f112dd0aaf973ea3573b358e8ac483390f63c3d7000000000000000000000000000000000b439ff419b20783f8b4485ec790be14f8ee1dab9eeeb7b9e7358f83887929cff9095bd4b0fab7d38e27a524d5ed9fa0", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_59", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f3555650000000000000000000000000000000007f7dc55c90fa181c55c9b83b7736ee84b3f19d960318e75661dd22c0546d62f4c9e07b915f9295a3c9fe6a62c84fc190000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e4000000000000000000000000000000000174ffb89d7715866562d9882acb81ce40758644ca3e0decd546c8f5c349b24fce88214956e7540fac36bcfc105cf34a0000000000000000000000000000000003e06c5f607ccf1e2991828034fcdf91106295e7174b4dca21926169451ee58e737d535af45073e2378206e03c81c421000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f35556500000000000000000000000000000000120935947070451885bf0c328bd83def193831ab9353844a01130074f16a1ff4d20df8459b5ad6a57d5f1959d37aae920000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e400000000000000000000000000000000188c12319c08d113e5b8ce2e18802b092401c540294704d291ea09ab336743d45023deb55a6cabf00dc84303efa2b761000000000000000000000000000000001620a58ad903177c218a25360e4ecd465414b59ddc39c4f5459e7137b1921095ab2eaca3bd038c1d827cf91fc37de68a000000000000000000000000000000000344cafaca754db423544657de1b77025164ccc702f8d45697fb73602302a3cb4511c38f0a76a37415d683398f3555650000000000000000000000000000000007f7dc55c90fa181c55c9b83b7736ee84b3f19d960318e75661dd22c0546d62f4c9e07b915f9295a3c9fe6a62c84fc190000000000000000000000000000000014b0862ac988a169342a4abacfebc5e7e7e8f8ff1166c6ca8fa53613c5fc28fd8b02d9c8d5e7a264b2fa59cd33a0f33c000000000000000000000000000000000f0f79631e7790192c18187144388373d52653cf11dd076688877fa9b5cf58e65fe4332874c301563089b9b3fa2322e400000000000000000000000000000000188c12319c08d113e5b8ce2e18802b092401c540294704d291ea09ab336743d45023deb55a6cabf00dc84303efa2b761000000000000000000000000000000001620a58ad903177c218a25360e4ecd465414b59ddc39c4f5459e7137b1921095ab2eaca3bd038c1d827cf91fc37de68a", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_60", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d4006290000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce0000000000000000000000000000000005b1ce5cb2ae0e9175f2bd557d7869233d65008e0f47c52914fa44c4a6234b70eed236bc5499bb0412d0cbb61c98f93b0000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000b15d92f2301075ab0e3215aa72cf9b130bc8e1bcd9fa36375c4b9d7da430ae3e2b24f417336d8729f44542ee7f561d300000000000000000000000000000000197d90090501e8cdea28eb7963231f1a7b5f716cc3a086acb6e7626600d6544132cac943e8d5cefb5daf0a2f8d4006290000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce00000000000000000000000000000000144f438d86d1d808d528ea60c5d343b427124af6e43d4d9652368ddc508daab32fd9c9425cba44fba72e3449e366b1700000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000eeb38bb167edf3f9a38865b9c1eb32633babd6925e56f5bf16c18c91c6deb403bf9b0bd3e1d278d1abaabd1180a48d800000000000000000000000000000000008381e1347dfdcc60f2bc3ce0288dbce917da182fe48c12b049703af5daa1e2ebe136bac87e31045c4ff5d072bfa4820000000000000000000000000000000008797f704442e133d3b77a5f0020aa304d36ce326ea75ca47e041e4d8a721754e0579ce82b96a69142cb7185998d18ce0000000000000000000000000000000005b1ce5cb2ae0e9175f2bd557d7869233d65008e0f47c52914fa44c4a6234b70eed236bc5499bb0412d0cbb61c98f93b0000000000000000000000000000000006a3a773638c0b4a13e7ea399ac319f5ea55ed533aca32a933d69d8198ae997a66d1e32a02683e7fc5c1ec597106848f00000000000000000000000000000000155ef036f60a5b11697581265293cc4c6eebd3fdf500540529b6997c27a3be31212aee5cdfea6cd95d6d5bf83a8ce5aa000000000000000000000000000000000eeb38bb167edf3f9a38865b9c1eb32633babd6925e56f5bf16c18c91c6deb403bf9b0bd3e1d278d1abaabd1180a48d800000000000000000000000000000000008381e1347dfdcc60f2bc3ce0288dbce917da182fe48c12b049703af5daa1e2ebe136bac87e31045c4ff5d072bfa482", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_61", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d0000000000000000000000000000000007efcb9da7b7ff0f4a1d92489ad76c59158bcc42c5c7a93067772a6d9ef1d3b6df9360d0fc1214e7dec02aaaf7b118bf0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf23000000000000000000000000000000000143db2b6c68dfa02055ea2cbd11bee04a663c2d8fde6b0919355d755bbbc5a5e23021dfc7b6c1a76460020b4748da41a0000000000000000000000000000000008ef405cd76f7649b315d4afa02f9c40634ebbaf96390c7b3292e798ea4b646d36594b06d14a47ffa0adc2180d02c92e00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d0000000000000000000000000000000007efcb9da7b7ff0f4a1d92489ad76c59158bcc42c5c7a93067772a6d9ef1d3b6df9360d0fc1214e7dec02aaaf7b118bf0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf23000000000000000000000000000000000143db2b6c68dfa02055ea2cbd11bee04a663c2d8fde6b0919355d755bbbc5a5e23021dfc7b6c1a76460020b4748da41a0000000000000000000000000000000008ef405cd76f7649b315d4afa02f9c40634ebbaf96390c7b3292e798ea4b646d36594b06d14a47ffa0adc2180d02c92e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_62", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000eb29e948adc9e1816c67a7865517fbc91610b2eb30da1d8a1e15c5f62e71a1fd1f40d4d59b23bea7edeba79829010e6000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000000e7e532ee4b892af39f8a3db7a05cc77a6eb0b3d977c17076bac4a52d5ba003a0ac1f902a4257791a45370eb88426a70000000000000000000000000000000016a556050e4905fa74b5061e3874f05cc7a6c5b049bd3bb7c34adef5a77c393239a600542a4401c3e61978ee6515a30e0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000b4e7355aea3488234552d3dddfa2d1ad3164056407770e6c54f764193c9dc044cb7f2b157a1c4153b2045867d6f99c5000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000019192cb74b345d6f577c1d788bab500fea089ad11a0d514ef0760dfbc95556207dffe06e8711a8869fb9c8f1477b840400000000000000000000000000000000035bbbe52b36e09fd666a1980ad6bc7a9cd085d4a9c7d707a3e5f3ab4f34bcf1e505ffaa870ffe3bd3e587119aea079d0000000000000000000000000000000004b3c0e8b240b79c55f02833c2c20fa158e35c941e9e8e48247b96cb1d4923641b97e766637a3ced9fbef275ca9bd1ea000000000000000000000000000000000eb29e948adc9e1816c67a7865517fbc91610b2eb30da1d8a1e15c5f62e71a1fd1f40d4d59b23bea7edeba79829010e6000000000000000000000000000000001310a8cebed1491bb6399abe3a08fb25ad6ca00feb5db62069bc5bd45a57c167aaf06a628a3f18aa990bb389173855b100000000000000000000000000000000134655489380a9ae9cfbc3f4c6a1aa5b6dbe0a994e681915602c1d197c54bf3da6fb2df54eec3634ea87bf3fa92a69740000000000000000000000000000000019192cb74b345d6f577c1d788bab500fea089ad11a0d514ef0760dfbc95556207dffe06e8711a8869fb9c8f1477b840400000000000000000000000000000000035bbbe52b36e09fd666a1980ad6bc7a9cd085d4a9c7d707a3e5f3ab4f34bcf1e505ffaa870ffe3bd3e587119aea079d", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_63", - "Gas": 207000, + "Gas": 237000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d0000000000000000000000000000000002f2e4467cdc15f1e57d75d6f5c172637df589590863bb437cc5166314e6362b7cd0d7499176b94529979849624cb432000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d29000000000000000000000000000000000264dd2fa407109abaf47d89c3d64542fd6d470579dfe0a98cc73f2fa3f6252bb9356ba39f3c92c1a6343c72d9cc4e5a000000000000000000000000000000000c34a091319b052226395b96f20fa37deb11b766b4b46811fa24799e5b5bfb20813a956524b7be7ea941b63a1c9a5a2c000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d0000000000000000000000000000000002f2e4467cdc15f1e57d75d6f5c172637df589590863bb437cc5166314e6362b7cd0d7499176b94529979849624cb432000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d29000000000000000000000000000000000264dd2fa407109abaf47d89c3d64542fd6d470579dfe0a98cc73f2fa3f6252bb9356ba39f3c92c1a6343c72d9cc4e5a000000000000000000000000000000000c34a091319b052226395b96f20fa37deb11b766b4b46811fa24799e5b5bfb20813a956524b7be7ea941b63a1c9a5a2c000000000000000000000000000000001465358836eb5c6e173e425f675aa231f9c62e9b122584078f2ab9af7440a4ce4ac2cd21ce35a0017b01e4913b40f73d00000000000000000000000000000000170e2da3bca3d0a8659e31df4d8a3a73e681c22beb21577bea6bbc3de1cabff8a1db28b51fdd46ba906767b69db2f679000000000000000000000000000000001360612f80227a2fc50a2dbdb3a49db16bd9f0ae401e2fb69408d990284cec05a1c29696f98b16d83a3dab6eac8678310000000000000000000000000000000001223232338ce1ac91e28b4c00ef4e3561f21f34fc405e479599cced3a86b7c36f541370bfd0176f785326f741699d2900000000000000000000000000000000179c34ba9578d5ff90272a2c7f756794670a047f79a53215da69937152bad0f86576945b12176d3e13cac38d26335c51000000000000000000000000000000000dcc715907e4e17824e24c1f513c09597965941e3ed0aaad6d0c59029b54fb039d716a998c9c418110bd49c5e365507f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_64", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000cab5ed8dc53e9c891df449bd199776adbfc193fc8d6bebf9716610fd4db6def608df059bf29fe43dbf1bf0aa52c1b7f0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c8530000000000000000000000000000000003bdbb702a5d2d8a5b2d10ed605627c1413eff588ac82966ca516dd7c2dc617b46a612308182759201efb7e6c6e1d8b2000000000000000000000000000000000bb2d13f201626fb4a2d6c1dfa03fe41a4fbb60b35d623d640cd430b8fb84afd3ff0b371714aaca303bcd4d3d548827e000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000cab5ed8dc53e9c891df449bd199776adbfc193fc8d6bebf9716610fd4db6def608df059bf29fe43dbf1bf0aa52c1b7f0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c8530000000000000000000000000000000003bdbb702a5d2d8a5b2d10ed605627c1413eff588ac82966ca516dd7c2dc617b46a612308182759201efb7e6c6e1d8b2000000000000000000000000000000000bb2d13f201626fb4a2d6c1dfa03fe41a4fbb60b35d623d640cd430b8fb84afd3ff0b371714aaca303bcd4d3d548827e000000000000000000000000000000000ab6e2a649ed97be4574603b3b4a210f0748d8cddf132079e0543ec776ceb63902e48598b7698cf79fd5130cebaf0250000000000000000000000000000000000d55b3115d2bfcd1b93c631a71b2356c887b32452aae53ffd01a719121d58834be1e0fa4f22a01bbde0d40f55ad38f2c0000000000000000000000000000000002fec3b2e25d9300b9757cbe77857d7220d91a53fc29f3b7a0da5c4e0815882d1cc51a40a60fa8e1ae01296c209eda0a00000000000000000000000000000000041ff1a77aca41f7aaeec13fb5238c24d038e2e566b611203c430d7ac6251d545ed4a60e9e0087d6baa36272c7b1c853000000000000000000000000000000001643567a0f22b90fefee96c8e2f5851623384c2c68bce9589cdf64c933d494a8d805edce2fd18a6db80f4819391dd1f9000000000000000000000000000000000e4e40ab1969bf9f00ee3b984947ae95bf7b9579bdaeeee926638f9566f8ab26debb4c8d4009535cb6422b2c2ab7282d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_65", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf1000000000000000000000000000000001528dcaae381eb764333992e28ed557034ba5413c5b64df40ef3150d2771e5d1cd8c211ca22075c7436e2582960ab3b400000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000fd913e00fb884cc217475cb69e1fafc298d5c38ee3bd5fbf68fa9c777b79f5ec111aff51fa0184023fec7c9cc881bf0000000000000000000000000000000000c45786b44e8dc531f1eb777adb0e146a963e46ab65d49a8ce9978607e5aa5c58b2880b8018a9ac97add3ca5c2e65beb000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf1000000000000000000000000000000001528dcaae381eb764333992e28ed557034ba5413c5b64df40ef3150d2771e5d1cd8c211ca22075c7436e2582960ab3b400000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000fd913e00fb884cc217475cb69e1fafc298d5c38ee3bd5fbf68fa9c777b79f5ec111aff51fa0184023fec7c9cc881bf0000000000000000000000000000000000c45786b44e8dc531f1eb777adb0e146a963e46ab65d49a8ce9978607e5aa5c58b2880b8018a9ac97add3ca5c2e65beb000000000000000000000000000000001654e99ebd103ed5709ae412a6df1751add90d4d56025667a4640c1d51435e7cad5464ff2c8b08cca56e34517b05acf10000000000000000000000000000000004d8353f55fdfb2407e80e881a5e57672fbcf7712dcec4cb583dbd93cf3f1052511fdee20f338a387690da7d69f4f6f700000000000000000000000000000000123a19e1427bac55eabdaec2aeeefadfca6e2b7581a5726c393bede2efd78af04e6cb986aa8d8d5c845bbbc28d62e7a00000000000000000000000000000000018026687f43591dac03a16fce0c4b8020469ec309bdbf9f0f270cf75e262abf4ae55d46f0b4ff130b7bbe2430bd0c9f4000000000000000000000000000000000a27fe0a29c761ce29a731ead969b1db3ae9ef4c05493cc370a128d97ef956c55d9a500991b3e7bf9600383633778ebb000000000000000000000000000000000dbb997ef4970a472bfcf03e959acb90bb13671a3d27c91698975a407856505e93837f46afc965363f21c35a3d194ec0", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_66", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec275080000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c5100000000000000000000000000000000010ee94e9470765ac32b5648f1cd7d745a793dbd46dc95fa32db86929eec385e50cb35755120480be0956a2a342a46d900000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec275080000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000b4d1c17ec6597484ae95466d3ca0656f8226c5127b4068f46fcaef6a77d9418d75f25cc92c1b7fd03c825514cbbaa640000000000000000000000000000000003110cf859c0d28c6ad8c2c0d0481a4d0d09bb2000aab784939e9f819a6dc3a7a18190293cfd2a106149b5c1a13d35a30000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c5100000000000000000000000000000000010ee94e9470765ac32b5648f1cd7d745a793dbd46dc95fa32db86929eec385e50cb35755120480be0956a2a342a46d900000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000b4d1c17ec6597484ae95466d3ca0656f8226c5127b4068f46fcaef6a77d9418d75f25cc92c1b7fd03c825514cbbaa640000000000000000000000000000000003110cf859c0d28c6ad8c2c0d0481a4d0d09bb2000aab784939e9f819a6dc3a7a18190293cfd2a106149b5c1a13d35a30000000000000000000000000000000001bb1e11a1ccc0b70ce46114caca7ac1aba2a607fea8c6a0e01785e17559b271a0e8b5afbfa8705ecb77420473e81c510000000000000000000000000000000018f2289ba50f703f87f0516d517e2f6309fe0dc7aca87cc534554c0e57c4bdc5cde0ca896033b7f3d96995d5cbd563d200000000000000000000000000000000000353798691ffba215b6458a47823d149e4e2e48c9e5f65df61d6b995889f3b0e2b34824e4ffa73296d03148c607c26000000000000000000000000000000001190ba585a928413dc3cef3d77b2cff99b053cadcb13b2529c74171a094d479a259678dd43a3ef2a2e597223eb7fd35c000000000000000000000000000000000eb3f5d24d1a4f520032534f6f81a6806c54df33cbd10c30203423aa4f33620b474cda321e924802b636daaeb34400470000000000000000000000000000000016f004f1dfbf140de042e4f57303928a576d9064f2da5b3ad392331f5c43327c7d2a6fd57456d5ef58b54a3e5ec27508", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_67", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab0000000000000000000000000000000004acd0ba7577ffe37bdeeaf5810b5a8a4a6b51c3c02bec4e0c6f0cfb4f12283120d283c12ecb7e4be7063fefb37a578c0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d00000000000000000000000000000000175da48b3c4c64d6eb26b45475ca7240a0923333b1bf7a6ef37c758ddceb0291da8085580f004814972d4afad7ececab000000000000000000000000000000000a8cb418c0192fdb509c33a79feb88c60226ee228a62a2c1be2b8c1ab9a0f711d11c15eae9f030491dcf70ed47e2678c0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab0000000000000000000000000000000004acd0ba7577ffe37bdeeaf5810b5a8a4a6b51c3c02bec4e0c6f0cfb4f12283120d283c12ecb7e4be7063fefb37a578c0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d00000000000000000000000000000000175da48b3c4c64d6eb26b45475ca7240a0923333b1bf7a6ef37c758ddceb0291da8085580f004814972d4afad7ececab000000000000000000000000000000000a8cb418c0192fdb509c33a79feb88c60226ee228a62a2c1be2b8c1ab9a0f711d11c15eae9f030491dcf70ed47e2678c0000000000000000000000000000000012ecb4c2f259efb4416025e236108eff7862e54f796605cc7eb12f3e5275c80ef42aadd2acfbf84d5206f6884d8e3eab000000000000000000000000000000001554412fc407e6b6cf3cbcc0c240524d1a0bf9c1335926715ac1c5a5a79ecdf2fdd97c3d828881b3d2f8c0104c85531f0000000000000000000000000000000018b0cd0360c5d5bf8254725c19976345cd84d32d0d770286444fe29dfdbc495dd58407ee8d48ec1004971f249453b8460000000000000000000000000000000009a6ea13f5a5a279ec3bb86cc028a1685d84135ed5fe99cd6b6fb380a42c3af5497e3ba5ea558618487cf953172a376d0000000000000000000000000000000002a36d5efd3381c35ff4f361cd813a96c3e5185141c5985073b45d1319c5f392442b7aa6a253b7eb22d1b5052812be00000000000000000000000000000000000f745dd17966b6befa7f740ea360241162505d6269226ffda90546863d0fff124d8fea13c763cfb69c2f8f12b81d431f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_68", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e20000000000000000000000000000000012ee6884c9d68bdabe8f4aa92aa613129993aad6a7aafffef1922c910cbd3f8b4ae8a810c59a0b9de0a79d4e5db13232000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b00000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000001669360d7591ed2362569fc05c4912fcd7ffe60dd26f533087b3099eb6603336863793d2b976bbff0edf4765066dc66c0000000000000000000000000000000006653bf1218a486d94578b5d40ff9a09b4e22325ba3d5abcff3d64652440d68ed5f69e3a215003a1db10c01843704f5000000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e20000000000000000000000000000000012ee6884c9d68bdabe8f4aa92aa613129993aad6a7aafffef1922c910cbd3f8b4ae8a810c59a0b9de0a79d4e5db13232000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000001669360d7591ed2362569fc05c4912fcd7ffe60dd26f533087b3099eb6603336863793d2b976bbff0edf4765066dc66c0000000000000000000000000000000006653bf1218a486d94578b5d40ff9a09b4e22325ba3d5abcff3d64652440d68ed5f69e3a215003a1db10c01843704f5000000000000000000000000000000000010dac3e5885cc55f3e53b3fdd5d28b2d78ceeea2b669757a187de0ce3f28b586e451b119cdb7dc8b97d603f2bb700e2000000000000000000000000000000000712a9656fa95abf8c8c5d0d18a599c4cae3a0ae4bda12c0759ea60fe9f3b698d3c357edebb9f461d95762b1a24e7879000000000000000000000000000000001431c5161fc51024c5708496a1f9545c3d4c05ef9e2c91154e22ebfe251017fc61ba54c679ba2ad6b8314bfd8d6272c900000000000000000000000000000000098f2e8b6d3fcf9fb27e912af57b45d3d35a7c5471b9ea2c85262c0efb44c435cd949f23d7d40f14b6b6d4d92cb8412e000000000000000000000000000000000397dbdcc3edf976e8c507f5e70299da8c7765772115bf8edf7dc9024050c2ed98746c2bf7dd4400ab1fb89af991e43f00000000000000000000000000000000139bd5f917f59e2cb6c41c59024c12cdaf95285f3947b80267f36e3bd2701f9548b561c49003fc5ddeee3fe7bc8f5b5b", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_69", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e5590000000000000000000000000000000006abf7ef1d5e3484992225b5a59791a68cc7e1e0f8aaf2415a9f759f2dff53f62aecf23e0443fdf37bb3775be9f5c981000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b000000000000000000000000000000000082385363502637bd8d030855032ee447fdfd7f0bc1eb14c5f00be2f5a7f30867483a066590a5fa22229e16c2dc00ec0000000000000000000000000000000009aa4ff672d1afdc24d89aa21616fbef5d0eef0b60307c7e193085e89db01dca0666b4201544d9aec8614ca14c22641e000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e5590000000000000000000000000000000006abf7ef1d5e3484992225b5a59791a68cc7e1e0f8aaf2415a9f759f2dff53f62aecf23e0443fdf37bb3775be9f5c981000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b000000000000000000000000000000000082385363502637bd8d030855032ee447fdfd7f0bc1eb14c5f00be2f5a7f30867483a066590a5fa22229e16c2dc00ec0000000000000000000000000000000009aa4ff672d1afdc24d89aa21616fbef5d0eef0b60307c7e193085e89db01dca0666b4201544d9aec8614ca14c22641e000000000000000000000000000000001889ef0e20d5ddbeeb4380b97ed7d4be97ef0def051d232598b2459a72845d97fa5c1264802ab18d76b15d8fbd25e55900000000000000000000000000000000135519fb1c21b215b1f982009db41b30d7af69a3fada207e0c915d01c8b1a22df3bf0dc0ad10020c3e4b88a41609e12a000000000000000000000000000000000caecf650a12bb629ebd3b978ef9c2d4486f8ce21d515451ecdf01d27740f41b719d5a952e737c83641953a8c8b3a1bb000000000000000000000000000000001641ca29ff6016af335499dfc7167b3d961a25b7f61008c27b3cb13d3cb28fb5096413b1c7f1ca18e5d3b5017d6fed1b00000000000000000000000000000000197ed996d62fc0628d8ea4adee487df31c794e05e7c327aaa140c6be0109031bb763c5f84bc35a0597dc61e93d23a9bf000000000000000000000000000000001056c1f3c6ae36be26430d142d34b0e807685c79935496414e004cb85900d85a18454bde9c0f2650f19db35eb3dd468d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_70", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf9250000000000000000000000000000000001b7a86c4142843a854dd0937bdbfd833a34fb15303d753e3f41eaf19f4fd9a6af785804d5ae2c3b99044cc13e6ca4b60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f00000000000000000000000000000000118871ec2ef96fd3a5b465133902c6f108eea08781ff754f1776dc029889a958b56943ad041d3a98a5f8fad5530e0cb2000000000000000000000000000000000d8b09f53d16443f4c1b0272d95999130c034720b02c3874a80a014f170c65c87538e22f0025d5c08da9e3532f0ac62c0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf9250000000000000000000000000000000001b7a86c4142843a854dd0937bdbfd833a34fb15303d753e3f41eaf19f4fd9a6af785804d5ae2c3b99044cc13e6ca4b60000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f00000000000000000000000000000000118871ec2ef96fd3a5b465133902c6f108eea08781ff754f1776dc029889a958b56943ad041d3a98a5f8fad5530e0cb2000000000000000000000000000000000d8b09f53d16443f4c1b0272d95999130c034720b02c3874a80a014f170c65c87538e22f0025d5c08da9e3532f0ac62c0000000000000000000000000000000008726a32d489a5ea1c1b314dc4d400d995d0eb8b49d47e65a6ac8fd0e6ec0cda1c637ee314c0c5d1ad72cd3588ebf925000000000000000000000000000000001849697df83d625fc5cdd722c76faf542a42506fc3479d8127eee7af57611c7d6f33a7f9dba5d3c420fab33ec19305f50000000000000000000000000000000009c7164f8d40c7e9ca571c46f8edf1c4a961779e55f6b10ffc44d76da78adadb83195d757949be39631c6a53d2d67fae0000000000000000000000000000000012cd5149125e7cc21bb5349be7fe03d5854ee73ba515021b6dc87e81ce1e1fa3e386fcb0de80977b9329e72ad54f929f0000000000000000000000000000000008789ffe0a8676c6a56742a30a48e5e65b88aafd71859d704fb9f69e5e274ccb6942bc51ad36c5671406052aacf19df9000000000000000000000000000000000c7607f4fc69a25aff00a54369f213c4587404644358da4abf26d151dfa4905ba9731dcfb12e2a3f2c551cacd0f4e47f", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_71", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000008151a15a13daeee49a82737118d488005fa7ed1869bc458f8af88e7341e0a48b5d8f129f6eb071fb07c11887f4d543800000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000efb08850063e94f4ce935ef65928deaabafa580a1c0a8e92b7f59efc09adf240f5363caedf8a212170e8d39120cbf74000000000000000000000000000000000838486201e313e21e62bbde270d9804a45b41a70e1c072804f4ca2a2f5ba6d151f15cc19958f0f2c6cd337a8b6c69de000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000008151a15a13daeee49a82737118d488005fa7ed1869bc458f8af88e7341e0a48b5d8f129f6eb071fb07c11887f4d543800000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000efb08850063e94f4ce935ef65928deaabafa580a1c0a8e92b7f59efc09adf240f5363caedf8a212170e8d39120cbf74000000000000000000000000000000000838486201e313e21e62bbde270d9804a45b41a70e1c072804f4ca2a2f5ba6d151f15cc19958f0f2c6cd337a8b6c69de000000000000000000000000000000001688c63e325569855bc2e51d668cef112b2479efa33519fe7f45eab89e275e2c4652cf8c2814f179935ccf1d24d8bd0f0000000000000000000000000000000011ebf7d4984237ac0173807f31be64575e7cccb36ce94e666e8149b9c292ebdb68d30ed4ba68f8e00982ee7780b2567300000000000000000000000000000000093c423917d10edc429acd927def56ab4f07254b3892762aa7056f24224528aa0f528fe8538ca996ca63506c84af73270000000000000000000000000000000003fd3ba68878485e25ccaa2539eed0a97743ae9f5b848e9d83c8ea60f7ad0f1cc6d94a59498f79dcab2bfcc2fdbacfed000000000000000000000000000000000b060965391bfd4afe3271c6ddb91eecb8c7a60451c469d63bb178b1361617000f589c33c35b5deda2f072c6edf2eb370000000000000000000000000000000011c8c988379cd2b82cb8ebd81c3e14d2c01c09dde5690b97623c0876c7554f52ccbaa33d17fb0f0cf331cc85749340cd", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_72", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a07060000000000000000000000000000000000876cf6553b21053e0d7a4449cd137fd946f2de0f7032f535f54914a8ae7da5afbe765bdfa3a0cdea0a50e1ed43bce800000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000afb70d8856591b980a2e4144357f4cb75fb367f5319786fb7fa2b656f9ed8facbdfb0b26346349986342ed4f34fae4900000000000000000000000000000000012670f096c4b225332cc181df91d6317c27071668f04226f807b0e17506fed0001c11613598926e38fce506ba02c6c8000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a07060000000000000000000000000000000000876cf6553b21053e0d7a4449cd137fd946f2de0f7032f535f54914a8ae7da5afbe765bdfa3a0cdea0a50e1ed43bce800000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000afb70d8856591b980a2e4144357f4cb75fb367f5319786fb7fa2b656f9ed8facbdfb0b26346349986342ed4f34fae4900000000000000000000000000000000012670f096c4b225332cc181df91d6317c27071668f04226f807b0e17506fed0001c11613598926e38fce506ba02c6c8000000000000000000000000000000000bb6f731b345bb1319b9acab09c186449a51dad8b6526251bc58e958cfd933137067e6f778b019f131cc7b23e08a0706000000000000000000000000000000001979a4f3e444c5950d0e2d71f97e99578b3058a6e414dfca313b898c4e02787e6eed89a2d1b05f31cff4af1e12bbedc300000000000000000000000000000000039d8e90425810a0b2fb5c915905863eb2da363ad4188e42cedce678bdd0f51eca0a96b78ab9e082d59dcd10e3c3c97a000000000000000000000000000000001973250dc31d16f658323d021dddc5439ef4396b6ed735f108cd7b27feb1b508daf863ab6431a77ec0b10cf7e001244f000000000000000000000000000000000f05a111b41a54e0ca78c3a1fff3b80bee7c1505a06b9a4faf36a73b87121d2952cc4f4c4e0dcb6633cad12b0caffc620000000000000000000000000000000018daa0f9a2bb347517eee63463b9d6a5e850446e8a94d0986f2921bf81a9f7541e8fee9d7bbb6d9181021af945fce3e3", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_73", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c2000000000000000000000000000000001093356407cff41779ce8f3d53dfe7a04edc8ce7192ddfeeb4329c38152cf1875d0df9ffeced95f1c7fae7d124649f21000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a903505000000000000000000000000000000000227280838fae5023ab2dcb23f6470b056dd6c87acf848e339d5164981a6abcbfb3c7084235f0749b2f5a4957f17cc62000000000000000000000000000000000b43329a7230c0dc0ee61c43a13e90ce24df40a52a415a2740cb3faa64cfe21058aaae5ea8f69364cd72d2cd6543fe9e00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c2000000000000000000000000000000001093356407cff41779ce8f3d53dfe7a04edc8ce7192ddfeeb4329c38152cf1875d0df9ffeced95f1c7fae7d124649f21000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a903505000000000000000000000000000000000227280838fae5023ab2dcb23f6470b056dd6c87acf848e339d5164981a6abcbfb3c7084235f0749b2f5a4957f17cc62000000000000000000000000000000000b43329a7230c0dc0ee61c43a13e90ce24df40a52a415a2740cb3faa64cfe21058aaae5ea8f69364cd72d2cd6543fe9e00000000000000000000000000000000078cca0bfd6957f9aff9731b45fdbdbeca6691f6fe6bf0b7847859c77478037e14864b202b235953ac7da231367324c200000000000000000000000000000000096ddc8631aff282d14d1878ef6bc537159abe9dda5732d0b2fe3668e184049cc19e05fec4666a0df204182edb9b0b8a000000000000000000000000000000000eff44a5e3b9fc8ffe31771fbcabea6efbd68384c5931216a2b7465aaa2566ee116b7daeea632677f35379107f7334f0000000000000000000000000000000000c3c942373f69c2c9631cef1c6bbb1a4567d5b95500409d4f2c6bf4a66ee263e6f167e22790badea0eac4a541a9035050000000000000000000000000000000017d9e9e2008501981068cb0403e73c270d99defd468cc9dc2d5bbc57750a4a58236f8f7a8df4f8b607095b6a80e7de49000000000000000000000000000000000ebddf4fc74f25be3c358b72a20d1c093f980adfc943b898266592f691e11413c60151a0085d6c9aec8c2d329abbac0d", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_74", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e0000000000000000000000000000000007007c89288b69f16870dc857a02cd071db8178e578fd2b78fcd5edb5050dcded107a1c1c0071d45e4c4af364bc9400800000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000018034dc4ccb64f0700b5e12b89d531cd9ccc7a399c1f36d08bbe277ccd8dd970eb00606d6e12bca68291897a817637d200000000000000000000000000000000069e1dd2b22d8ce5ce1e0969e35e07abcfd97f8f3b6d8fa724a0feb9ea78b603391caea3172f50aa222f5fc82bdb18e5000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e0000000000000000000000000000000007007c89288b69f16870dc857a02cd071db8178e578fd2b78fcd5edb5050dcded107a1c1c0071d45e4c4af364bc9400800000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000018034dc4ccb64f0700b5e12b89d531cd9ccc7a399c1f36d08bbe277ccd8dd970eb00606d6e12bca68291897a817637d200000000000000000000000000000000069e1dd2b22d8ce5ce1e0969e35e07abcfd97f8f3b6d8fa724a0feb9ea78b603391caea3172f50aa222f5fc82bdb18e5000000000000000000000000000000000b3a1dfe2d1b62538ed49648cb2a8a1d66bdc4f7a492eee59942ab810a306876a7d49e5ac4c6bb1613866c158ded993e000000000000000000000000000000001300956110f47ca8e2aacb30c948dfd046bf33f69bf54007d76373c5a66019454da45e3cf14ce2b9d53a50c9b4366aa300000000000000000000000000000000081da74d812a6718e351c062e93f9edb24eff830be5c44c3f21cca606f5b1287de8ba65a60d42cbf9740c9522fcdc9eb000000000000000000000000000000000eb1d38fd394b7e78dfaeb3b3b97d3d928c16472ee74ae0be1ec3efa510b9bb64cec369793219ceab55a0ed0ece23de80000000000000000000000000000000001fdc4256cc997934a65c68ab9767b09c7aad14b5765dbeedb72ab2429231cb333ab9f9143414359376d76857e8972d9000000000000000000000000000000001362f417875259b47cfd9e4c5feda52b949dcbf5b8178318428fd3e70c384020e58f515b9a24af5597cfa037d42491c6", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_75", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000a76ccda2ca736ce935b4b88e08bbf183f69e2b3f5a471662a5de571976e7d4264021db88b919c896bbbb8128732c3e3000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000009060f4c03cbefb8f46332a22d5a2be92b167e493cca773121c9bcb485ff3c100df3404737bb08bae60a9dacc4a5c83f00000000000000000000000000000000058eac9c9eddd5f62da6c450254602ebf94e246b3f1a6c5fd27a26cbe1f1f02da4d1176190537db9e264c7e4f28058ed0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000a76ccda2ca736ce935b4b88e08bbf183f69e2b3f5a471662a5de571976e7d4264021db88b919c896bbbb8128732c3e3000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000009060f4c03cbefb8f46332a22d5a2be92b167e493cca773121c9bcb485ff3c100df3404737bb08bae60a9dacc4a5c83f00000000000000000000000000000000058eac9c9eddd5f62da6c450254602ebf94e246b3f1a6c5fd27a26cbe1f1f02da4d1176190537db9e264c7e4f28058ed0000000000000000000000000000000007c00b3e7e50a860e99cdc92235f45a555c343304a067a71b6aaade016ef99bc50e3b2c5e3335d4bdacb816d3c765630000000000000000000000000000000000f8a45100cd8afcbb7c05c2d62bfedbf250d68d0fde0a1593cd2ed2f5f4278e1baa9e24625c263764e4347ed78cce6c8000000000000000000000000000000000b8e764aa5afa4a6e8227d1bc720eeffd72d963458a4963a3bbe697d3da11186a30d90f7a4eda5630f6967095816913300000000000000000000000000000000085d05b570cd58def6ac2f7e80dc18658dc5d0e6a1f5a5cf4d18745e03494654eb1a6d5399ec2c5288890ade446317d00000000000000000000000000000000010fb029e35b3f6e156b8751415f180ee3960cd3bb6ba9b8e456715ec70b1ba1410b8bfb77998f744d3f462533b59e26c000000000000000000000000000000001472654d9aa210a41d74e3661e05a9eb6b292719b46aa65f94b6abd514bf05f679dae89d21008245d79a381b0d7f51be", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_76", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c00000000000000000000000000000000124a601a06d5094945ec8528c5457ea3f8ca710137b6ad48ee7ad93db53c056059dbc8b02d9edf5e2786c575a0bff89a00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d70000000000000000000000000000000014e04221744944c56495e2cb7789acc9f3cb7456d78c44872d593343fcaa575103fc4ea96e61c4729f0887454fa57d6a000000000000000000000000000000000231121026adca019380e499e795165f297bce1b30c633afb6c00329e21b5872d5545b887bef49a43b2ceb284b72710f000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c00000000000000000000000000000000124a601a06d5094945ec8528c5457ea3f8ca710137b6ad48ee7ad93db53c056059dbc8b02d9edf5e2786c575a0bff89a00000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d70000000000000000000000000000000014e04221744944c56495e2cb7789acc9f3cb7456d78c44872d593343fcaa575103fc4ea96e61c4729f0887454fa57d6a000000000000000000000000000000000231121026adca019380e499e795165f297bce1b30c633afb6c00329e21b5872d5545b887bef49a43b2ceb284b72710f000000000000000000000000000000001517dd04b165c50d2b1ef2f470c821c080f604fe1a23f2fa5481f3a63e0f56e05c89c7403d4067a5f6e59d4a338d0b5c0000000000000000000000000000000007b6b1d032aadd51052f228d7e062e336bacda83bbce657678b5f9634174f0c3c4d0374e83b520a192783a8a5f3fb21100000000000000000000000000000000042280b112fdbbd94f647e5b1f4b51d864f85063a5b66e1f1fe5b1a8d280f9bf1db81ad3588f93f8801ff1a3f66b96330000000000000000000000000000000001e0887904228790d03d8b6d17bebdd8659deafa2ebd9b07069ce89fe228824a39966953d14dda1bd6ccce5faf16e4d7000000000000000000000000000000000520cfc8c536a1d4e685c4eacbc2000d70abd72e1bf8ce3839d79f5cfa069ed31aafb15542f23b8d1af678bab05a2d410000000000000000000000000000000017cfffda12d21c98b79ac31c5bb696783afb7d69c2bedf0fb070cf7714959db14957a4763564b65b7ed214d7b48d399c", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_77", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c04200000000000000000000000000000000001b8c085fd1f34fb273da7d651602b326fef7c357c2fb7845f4c17ce95152042af9e51e7d7699b50f3605bacab563a100000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000012098b001cb819309d0b45df8a37854967f88cfa823a69f262fe9a40c564bad8e8a6be94d3f7939ed38305c6fd2d93b6000000000000000000000000000000000099b6e094a1b1eb0ead2e7117f3f9bbf72db98409ef1234c8b3b60fea1048f9e97e3c61fd568ccca1da89f6a484bbe8000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c04200000000000000000000000000000000001b8c085fd1f34fb273da7d651602b326fef7c357c2fb7845f4c17ce95152042af9e51e7d7699b50f3605bacab563a100000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000012098b001cb819309d0b45df8a37854967f88cfa823a69f262fe9a40c564bad8e8a6be94d3f7939ed38305c6fd2d93b6000000000000000000000000000000000099b6e094a1b1eb0ead2e7117f3f9bbf72db98409ef1234c8b3b60fea1048f9e97e3c61fd568ccca1da89f6a484bbe8000000000000000000000000000000000475e66c9e4e434c4872b8537e0ab930165b39f41e04b208d74d3033e1d69dfb4b134ae3a9dc46347d30a6805508c0420000000000000000000000000000000019e585e1d9adf34a98a7cd38de35aa243d7853c19bc21747213c11240d5fa41ff3b21ae033dd664aaac8fa45354a470a00000000000000000000000000000000137e91115129cbaa1ae2bbb79abe5505436bb51ddceeb011d56dc5c3c396b6b00067d6e6108bafca40fc717737487b27000000000000000000000000000000001592fec7d33bffa7f3eebf038e3194513736cc41a143471fb8c55a44c7521c07e4d8368e5c6ee21ed0478f949f3e224e0000000000000000000000000000000007f786ea1cc7cd69ae1061d6b914278dfc7ebe8a714aa8cd04323860314c3b4b36054169dd5c6c60e67bfa3902d216f50000000000000000000000000000000019675b09a4de34af3c6e79452b57b31b6d499200e996008a9e7d1c910ca0ad2a352dc39cb3fd7333182476095b7aeec3", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_78", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a880000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000c8bd020743550a6d27f0052d0037547db204e3fd752abf6758d899a3793fd3cd50c3073df6258c20a2f8e4797cbab700000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a880000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000a42cfd1e09bd5fdf93d4ffec5a6b312a27dfb7b5e5238dc590158156b613c2d15de1e5a1a4ef2f6751e766874ea788d00000000000000000000000000000000000c87de488d68a3ef74410fe4c892cf62d25fb7d9ef6cbf3cb093184803e12066e86020225e3b9899decf8dbe6a20230000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000c8bd020743550a6d27f0052d0037547db204e3fd752abf6758d899a3793fd3cd50c3073df6258c20a2f8e4797cbab700000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000a42cfd1e09bd5fdf93d4ffec5a6b312a27dfb7b5e5238dc590158156b613c2d15de1e5a1a4ef2f6751e766874ea788d00000000000000000000000000000000000c87de488d68a3ef74410fe4c892cf62d25fb7d9ef6cbf3cb093184803e12066e86020225e3b9899decf8dbe6a20230000000000000000000000000000000002291ff240598e2c129ea12292e4a2fc86e03da9bd9fbbb8bddd6f25797003a4688ba2ed3bafd8dfcf0ddd44c3288c1e000000000000000000000000000000000d7541c9c54a95f3789ca7637348378f8956fd451c3266c8f1a34906bf1cf8e7499fcf8ad1f1a73dafcf71b86833ff3b0000000000000000000000000000000016aed55f56416b8f450283c4afea4c606100eed9bf7b8fea9ab4d04797a7bfe3bf0f10cf229f8ce3156869d75beabe6b0000000000000000000000000000000007e5c03e51a513c6f77179bcb5f7d147dcee32426b4365b1c95f434be7f83a5883d1ee5b0e01a636b3e5377542314b75000000000000000000000000000000000fbe421858e4109c51de57b77da4f9c4c1f950099532d9e30e2f7a8b8b4fb9f708cde1a497050d0944e089978b15321e0000000000000000000000000000000019f48a0bf0f27df65ba766a65e831a0801a4ebcd1995a6002a803f88aead1503b7c39fde8ef5c4672020307241958a88", "Expected": "0000000000000000000000000000000000000000000000000000000000000000", "Name": "matter_pairing_79", - "Gas": 230000, + "Gas": 280000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa000000000000000000000000000000001233421a38d77c59bbe1b83992a7a6c964ede5ef83c5a72bd1ba2c0a81b4205ce9a6925718cabcaf4a72ca3d216fbffc0000000000000000000000000000000016b8c22b35af7d925b5c68b6b7b63442e051fdc45542f233f2d97106c4b960eeb47f204c659d16a3a0d3b65ee38ff1480000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb0000000000000000000000000000000010b6db11d4fc3a2b449b8fd189d2e4ed4591bf4258d7b92b3eb152048cb3a3eecb87782691e9b954377fd1f34b38cb0d0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb9630000000000000000000000000000000018d31bd5a7e94ceb18d803969a2001c6eb3bfbcf82c27e88ca60d4c46807d12f116ca71c67d27270c2332205a4ea11bb00000000000000000000000000000000094a36d86483ac6f068017e4b978c7ea1ee58c429aad5994287f809c69fd5235532487d81f6a46ab827f2e0cb4c6df9e0000000000000000000000000000000016114be17b400ba35875d9009b4d8974023a57d32508c9f658a0d82a8efc6b379ce4a3dbf5ca7130c5581f5008806934000000000000000000000000000000000c68cd7b9d3c3d6c559fa3d52da48ebe68e40a44863c332bb90dd151d1281dd3faa34e6c7b07c277affbdbc1b0a43cfa0000000000000000000000000000000007cdcfd000a86a408f39ef7cb0a4060dff8965956fbf6b939576a69674fcd5c735056da7988943506f8c35c2de8feaaf0000000000000000000000000000000003484fbf03d06907efbf3eff8b95789484254dc09e42208b7457619a31f795356a2cdfb24bb6e95c192b49a11c6fb963", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_80", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b560000000000000000000000000000000016c917abe637da21e60378ea7c2682306aded4ff17ccfea742e9ba63590be1b0fd5432ff0d3b72cdcb15943763cbb6bb00000000000000000000000000000000153bdddfe73f21c3593b128d3885f621935585ba1715e1d989e87cf7271897eea3917b81f0f342790f0f7a330ca0c68f00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000c47feeb1a1d2891d986b1660810859c1bba427d43a69b4e5ddeaf77116418138bfc2b7b4aa4c0cc6df10bd116721d5000000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c00000000000000000000000000000000190f4dc14439eccc46d46c5c9b15eeba0bbf2dbca11af4183408afdb15c7bfa26f107cf5fda0c1e0236aab95728eac2e000000000000000000000000000000000db912ff1f62be087194f6503b3b273b48bd0907afde777109522329e54cde1092afd48366af3f334c0df42ee98d8d5b00000000000000000000000000000000135b96feb4f1e712661ce0d13842de1198c589f335141ab1fd7ffc6b9d58de82c300e9fe6dacdefe8e68b6db9298da5100000000000000000000000000000000046a3563d167d8b0a9f74e0c6514fdabd795110cf48caa014947ca90a9eeda3d07dd7dce58d3f2b7b86fab1143946b56000000000000000000000000000000000337fa3e53480c7865182ecbc7252aa6f9987685dbb814182447183d9da514732157ccffa4188d31eee96bc89c33f3f00000000000000000000000000000000004c5340a5240c4d6f1e095290ac5b6b5d121c5cadc6f30e5dd4855a9cf985e357b1a847cc060bd86aaef85ccf35ee41c", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_81", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000a9e191c9775f57810a511c8bd3dca14b3328e20f0983ca72e42e561b5dd1693209b42a11f2faeecd6307dd34cc01d60000000000000000000000000000000000146061b13546754c74a705776656100a9577f1ff939a82ba990d6b885b27c450f824555829bbb19f9b1f636991799cf00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d8000000000000000000000000000000000062783335b87300c97b38e03e5b1318d15a499b29a473c187f930bf34bc1214b4d822725678cbde978c7b5ae6d4bad5100000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc00000000000000000000000000000000021203675e0ae188ec782160e21492a6ee39fa97d922c1ef9bbfd79b82b3fad54fab11ba633fb8f02cf92249d85d9d800000000000000000000000000000000013d98eb6ddf8b68db36819b25d9a7b4a4ed2b1d2593dd6a6e79dc6adaaefd4d8d129d8d949c7421641374a5192b3fd5a00000000000000000000000000000000117821e6c87bb0e04882e95d36dce18ca33a2c8bd0efd5532b33d597804c08ff1799b2d64a95cc84bd31ba45c3b1e822000000000000000000000000000000000887c07c8a9ebe3154950746a4506ff192bb4a05dccb0f4a1a8ac2b8ca0da07190129ba44d9bc8e6c2666027c67d2ddc000000000000000000000000000000000f62f8cda209f1223a7695ed860de2c2b144bd6402ecd61838eded3f40d3df90fe10bd5d92245112e3ce822cb33f8d4b0000000000000000000000000000000018bb0bcf262b7f4583d1375ecce64bd6bb1fcc64fa4b6a93bd9ffbe870fe79df0f29baa92eb844e5c04d09c966e810dc", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_82", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000e96f685e6f87677cda23177f9fe7fd15726ab31e4d85a5725e93d558bdf61437dbc2c9ebcfc6a94705fa70de88a81bd00000000000000000000000000000000157ce060a46912c992587fde3db4c64a705ab7115717031778176f6ea311cb352f3a76f4839be4658470e4b0b9854f77000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a80000000000000000000000000000000013b5317e3ff7540048b19ceebd47c15538d7eb3bf402823b9c348c464afb1000ce0f7ea4c1cb668af5c8cbf77e6a92510000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34000000000000000000000000000000000e4979375cd880e26d00461de629bac880c12e24ede4a7c702f151c34a728a69a021e37b6a1af520a5f47d3a33f8c8a800000000000000000000000000000000064be06bf988929a026a0ac78603eb822b9f6048ff829083cafc465aabb5e623509c8159ef889974c43634088195185a0000000000000000000000000000000011f9a369401d2c376c77b4b414e345e6108b11594b26521b51afe6318648af232bf9f1455a99dc2f9b0207cc78339510000000000000000000000000000000000863492499f4791e71bd8d58dd2444a34e66dd3e3ca1cb3669f4182fafc9ef080a1d8111b3dd754f2405032350732b32000000000000000000000000000000000b6a1b64528770227d79763e494d2d060d50a0530eacb8684147954b6ad194e0a0efd35ff457956b499f58f2177528ee00000000000000000000000000000000048431899516d3d0b8c327d80596e68cf41c94739c6e0fa7ef196332539f2aeeef71890a2db81b9a358e1b4f467a5b34", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_83", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e0000000000000000000000000000000016002a054bdf3cd916b5f8aca47d97feb170e8864da2eff8bbbf19a5b25ac857dbe6daab97dfe15a4e82455d154652e2000000000000000000000000000000000efc6f6c595368288f5687e710e2faebf12bd63a0ca34a527c05f1d925fcedd23c5e2b6708194069a36f858fa510ee410000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000ae10eb4f791aa31e5bd7b6c4d68b04c6744262d8f5e9469b3987b101ff5a3066794e05694a9167b7050c3944b6d84f60000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a0000000000000000000000000000000017f16cffb737dadd52b3c5be258733dc47301474b7351c8dcb8ddb4c519018be08b64efea3336f2b6cfa78e0669dccf9000000000000000000000000000000000f20033541ee3c68655e2c49f5e2fc8afd33255764267e55b3985790d6bb531db7171fa81caae98449ae3c6bb49225b50000000000000000000000000000000000a8382a5f73a7d15c3ee35e5fcaf7142e6d91d71ef30ce7da9c8db2f80c95441dc93674bed244096b71aea40d43c318000000000000000000000000000000000733e9a022695ed6908caf6ec7e67211c6d5ac16ba3fb8e244227f5da787e69e7311fac1e8d102a2d84e6ba98903ff6e000000000000000000000000000000000400e7e4eda0a9c13465af099ece14d8b30662fea5e222c6ab71b8fb44562dcc42c5255319741ea56b7cbaa2eab957c9000000000000000000000000000000000b04a27de02c7e71bbc51fcf3268b1eb734b754ae6e1c86ceb2ae0c7d0b40851e24dd497a93abf96168f7a705aeebc6a", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_84", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a1000000000000000000000000000000001408beb1c3951d79fa43477c5af6894ee3c2ea9605f8ae64a78b51ee7e16ae9641134a9a75735972dbd7b53dd4c9f3bf000000000000000000000000000000000e6c6c9405ff001faa8d8c06bcbd75ee91140f477ef8283d3c5eb3039f16543ca9e7e4162177a7499edb6f3fdb01643f00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a61685420000000000000000000000000000000016aead8bd8c4d5ddc444e15bc83e8f14d377d5e8d756a0255f1387506b9a9add69592241dbd9cab95474d55ac473886200000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c00000000000000000000000000000000062168f0bfd29c44074430158708a1e3b6808bae633ce9506b32eb9124db1a0668d83f2076adffb568ccf289a6168542000000000000000000000000000000000352645e60bb10bc86d6c65a7b0d1dc290ff759c1c2e729a081d4b508b165b46b552ddbcd57a3546658a2aa53b8c224900000000000000000000000000000000050b449c2425926d961af37c4c88e671eac676a1f828def54b76dc04960d0222fb5832ed44c45d5fbb59549d9d24c236000000000000000000000000000000000c6e811987b30ed77c804e647f867186d425411e514e9bf31099cc0f695195729ae970766b2738a928e776511a44f8a10000000000000000000000000000000005f8533875eac92050d86039e855238880b460eeed8c645abfa580b2789a478ddd98b5643be0a68cde274ac22b35b6ec000000000000000000000000000000000b94a5563380e67aa08e1baf868e36e8d3633c3d748cea822ad21f9d579aa1e774c41be88fdc58b61b2390c024fe466c", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_85", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000018a8b48aabc6c003a58593a40b55e54b122994f9ab58cc229d1a0e6a3670244cfe73854f07117dc77dd5c2c81314a17e00000000000000000000000000000000062f6a0a8b9dd56001f0f57f82bb7468d709fb8f33e6729369b015685995ef27abebff9dda55c38b0d9e88a1e0b9fc6c000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000019049c394e547b9b714b5969adcf068b381def6af2b27d1d361d06e9576273a8febb5bf94b5061ccec7afdb5642c0ae8000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f000000000000000000000000000000000c60b948942652a8214d8776b77a6c559ca77eb3a537b0a9abadc3058eac8c1d7840f091acd6c0056d5a71468a2b1ceb0000000000000000000000000000000000fc75b0eb2b6afed9d04e4c957ca64c2c595c1a00d295a23113cbb79f4e827b1ff0a40566039e32cd84024a9bd39fc3000000000000000000000000000000000a8679f08643ff1c4db54e58de15a4828fc80e3f9d80a932b26b49d5c13831b1dc5dc29af2e080eb08e71938e5010fc400000000000000000000000000000000110957f7e9f8e0806bb3d2a811b91c926feab046ef983495f3f768a6cc6e4a6d95bb92facb77d989e53ce5489aa64b3c0000000000000000000000000000000001585d5f8db92696a596141237f5c78c524db68b482c469cca16c436c040d1d720387aafaa4282383c293d37eceb092d0000000000000000000000000000000013d1a7dfade2113a492ab236c090386e8d6d4ff5bf9ea02bfd80bd389d1b06fc72c00060d6fe3c74ac60775e1f45ae3f", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_86", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000d81a0809479694fde24e5a3ee7d32deacc25e77f241024666bc3372e80379a722863ea8105f345f1d09e462fc5a8c6c0000000000000000000000000000000001a5be923f1ca5ee876d660fbca5896f1634ef6a83ff8c64dca4ed76d1db2ba4875099fa5a39a09f839731278b307fb10000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000009f7d7b21882455e9f1f24ea120f3eb69f739c1320c37eb2b17e0a271cb03ac6e2b0c55d3518548a005f28b5748b7f59000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa0000000000000000000000000000000013fe38343072af8ef1d8247c3d46b4fd190086ceddfeb767787031368da6a6a6ae849cfc26a24ead499338e37fa337e30000000000000000000000000000000010093a3820fda13babfc82cc313c6e20c503af71d2c1940cb5b2c879da00bb5d3bfb3aa17c3bab75b99fd74a8b742b52000000000000000000000000000000000ba48cbd776dd03a5b69aed3a31b7d151a8d98cd9adc3b9987cf2ac94644a364ebf3d30cf31742e2152aeba0eebc9ceb0000000000000000000000000000000008793a44c730949a9e50e9439d579ff0991dfc49a67a29b1701989ab065e6e937b14ac1bbca5a3dbf79a61837ad18394000000000000000000000000000000000c7f7169a5067d4a6cf6c21254ce79f8b7b4ed0d0144107900749f2e0ead7c7cfc25c156a0f4cba09cf51b9d03a51e3f00000000000000000000000000000000185b5357fa6340abc3ae41a686a623684e425c1a6f85865a8a8be52a24d5ca7f975b6604571a5f603667ced874cf2afa", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_87", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b2720000000000000000000000000000000000b76cdde0e1205c918e6e6d324ac3f35d42ebe9bb101f1cd8955acdfa8836f22f1497bced2c93495022b0c335bcaaae0000000000000000000000000000000018340c2a8b079b88595aa50e93251d12e3a5aead2d2add3b72ce82e03a26525aa45fe9b379504392edb0a2a26d7e99dc0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000146696840e8e988d0eab90ea935dd8b5f1272bbb81eb524e523c57d34ad7c5f0f3b721566f51dac4774826b84cc1c82f0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf0000000000000000000000000000000018c6df81d810deaac0b143edf79956c92af7941f7b279db345f838bd583177912fc2eb367616ae165e261014a4d7b1b900000000000000000000000000000000059a7b662af14e0d3c7016cbafedd42173501fc97199c07114f47acdabd930332af4dea84202253b42b6d947b33de27c0000000000000000000000000000000008691df5b245399f24118badfbef3e01a4acd53dc9ab149e407c733df6122fa91f5cbe2f9d247cdbac18b266d3d8f18300000000000000000000000000000000053e6eef4ffdbe239c8bbade8cfc90461d54f281ee6180c271412bf2d64e005d3f0291d3401c324e41067f4dfcc4b272000000000000000000000000000000001949a50c589ec63db98d39491100e8e407345f9b3874f3a28e9b77d2fc28bf31ef976841c4276cb669dc4f3cca42fffd0000000000000000000000000000000001cd05bfae784b11f1c102a7b0268fc480d19cd7c65a3583f4624fc0bc8aa3c97a4c164b3803bc6ccc4e5d5d928110cf", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_88", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c6640000000000000000000000000000000011d7aff6c4512f68031aeb94ce3733ac43659f9fc58fc94c05d99ae80a7656f66b3e3e86843387d1c10f51b4284755150000000000000000000000000000000012a9e7f3804c6b5b25410a82758cd5b6ea1eb150c696b0d67d92cf9eb1f8e17752184d94a4ad2645b1520d6aee1094ed000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d0000000000000000000000000000000009d569f05e69a38231d0f636e1ef040af059a00db4ff09bd2ad82b7e04cc041a33603c2eb9b148e3b1412bdef9740ab400000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be000000000000000000000000000000000c6b634d90c2664b9fa4ccbca35913d23696825350e21f0a6dd5e9abb17497a0a499e1b7b928a57ba8c730158f63b75d00000000000000000000000000000000102ba7f9db164318194ab17f615ca8cc741dab773e8609023c58a722f1e4f209eb4bc3cff7a2b71c08bdd421068b9ff700000000000000000000000000000000042120affcefe4735ae25e192d1cf34e40afdc6d2ebdacde2e23d30709fecfb71960bc9131e3702b27b6fcd5c7a98d170000000000000000000000000000000001998caf5163b0dccec7c8423c4c56a7d0f0b26d9034f707ed07f636f42dac590a2674c1667d70be385c4e626815c66400000000000000000000000000000000082961f3752eb7324800bc217514792b2111abe52df54973615737b8ec3a9f2db36dc1782d20782df8efae4bd7b8559600000000000000000000000000000000075729f6b9337b3f25da9d33cdbed7207a589a342cee61e8e99e030244b814accc93b26a0ca6d9ba08acf29511ef15be", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_89", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca0000000000000000000000000000000018bc90cd83e1271bf0e39b0c80989f0ddcffc960ae466c64ad340cc32607dbdc73eac5b9145e1339fa02a0c3fafcc1df00000000000000000000000000000000124c4bf66a5e015f142e9e4b26421414a60e54ed76c6d4acc0f20b24a25ddf5ec7ef1f561fac9d470a94bcfb2f2698c50000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000e8b0f968ccb230517ef8980be559f410a2c4035a1101e6796d4f7a5ee5c93a19c111d38930bd5bca69405fc35fea7c20000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e60000000000000000000000000000000018129b2f00be24717c906d215beaaa136758aa1730bd0bbe9c0de9b3cbb3c0ea47911817fa322b907cc6fc720cabde05000000000000000000000000000000000b760253acb4c395332c1e3584f60d965a4b0b4f5274f457d05bdafb08546282829ae2c61e482a43136afa03ca0102e90000000000000000000000000000000001462f8080d9b51235a8aa652445f509e3e13e3073769e9a047e8b2bfa5b227f4354bef017d18bf06f7ec98c169abf1e000000000000000000000000000000000070fdbc18112b49bd83f4347922797f2bbd68bf2592ad59041c97948ba7a091bdb3622c804803ad605604ba364dbdca000000000000000000000000000000000144811cb59ebf7e5a380ca9c2b30dc987778224453ea65ab9fcc5ddd0a91a47aac13a459cf5ecc5bffc5f3c0502e8cc0000000000000000000000000000000007b4c5f3cf21e53b36ed096b1d0998c2be68f6977cbe3e12a63ec77c545316c556bce0a891a762b8af6a4304d0d911e6", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_90", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca20000000000000000000000000000000017f93d49ec5c34cdc31931cbe2d5b3ad7a6dcd3ea864862aa7b41d5b2f4618c9c92da01e246ff8f34240bcf1de4c1c450000000000000000000000000000000002180a95dbe57c43171e2607593dd3b54344bdbf409dcd0c5706a9a72ad0e26ed60b9e4cb17ea4e7b460adc5a6f6d2de000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a4700000000000000000000000000000000193118d1f237c68a8a0961fb220c0fd6a08853908a039dd57f8ed334063e5316bf83e8c3c3f44420734abbd7ddda31a600000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd000000000000000000000000000000001667fdc9b89d12fb0704fdec910cab1b51ac04219ef6e50f996688b2ceb26dca0e9e8594c5b81fca2e8fc2c8d8fa9a470000000000000000000000000000000000cff9184748200fc11245bb213f9d00c3eef7f4698174e9e7a1ff6cf072a30d5f28173aed5fbbdf46b444282225790500000000000000000000000000000000156901359e5b399168e90ccad27a054d147aa9c4a731294180e395e8e2d458f5537fdac591cdc82fd8bffa4c9fa126ed00000000000000000000000000000000143872757c0a25d85e95a86c5e09175fdbeaf59bae3d1e8a367902d59c662cc3a293ae252443b3201671ad1dbaed8ca2000000000000000000000000000000000207d4a04d23b1cc880275ea6075f929ea097e464b208c94bf7cb545c76add5a557e5fe08ce4070c77be430e21b38e660000000000000000000000000000000017e907545d9a6a5733fd81aeea0dd92221328dc5b2e745b3102a28f9cbe013b548a061b1ffd55b18059e523a5908d7cd", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_91", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c01300000000000000000000000000000000034f7418d96bdbe4f1ed5996fc9e9e99233a5cb3aad717b3717e91ff94fecaa67250ba5b27dcf59c6e36aae08d22983a00000000000000000000000000000000100cd7ea3c342aa2c15e9c6121a1cfecf611235add08290cf9cb8ea54e8ff523e17a0b5dc41e6d07992e5927e3ff6157000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000007025f1c4a5f85a9c1587d4d4a2e620d83d60568343940ffd85e6b1e4fb0f0f53bb08c4f48bf6f45a7dbc3722ecc951e00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954000000000000000000000000000000000217a4c563d730ef545e452038813301933ccc6638321ee5e217dad0be2e3ddc855a14054d0d72b6bcc692a5fb1ac7300000000000000000000000000000000012feb2cdef2060f089c32a68f91d4ac9e0a1461cbf4bd1bf8ed26782a700052ee2fb73af689490ba12233c8dd133158d00000000000000000000000000000000162ea8f985c83d59361ee6beb49cf2a797d8c909e2eccfc61fdc5359d5ac9b10fbaeef2eebea1667b5b9bf8f5d603d6e0000000000000000000000000000000018344ca9d4913e817264ed8119fe4d136f2041b0a99d4b5fe7f2b7f268256eec9fceb27fa61c4225f47babd17759c0130000000000000000000000000000000016b19dd160140ab5592e4e1f46ad0e3e413ceed148adfb0bf5b240a161b22b7dac5b45a389770a634bc8551f72dd12710000000000000000000000000000000009f439fffd4bbbf789bd0b5521a9dcea6e66282a167ce9b26d6543fba82101003d31f4a0ed3592f820d0a6d81c004954", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_92", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_93", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a7", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_94", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false }, { "Input": "000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Name": "matter_pairing_95", - "Gas": 299000, + "Gas": 409000, "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG1Add.json b/core/vm/testdata/precompiles/fail-blsG1Add.json index e58ec0e90e..86bd3d660f 100644 --- a/core/vm/testdata/precompiles/fail-blsG1Add.json +++ b/core/vm/testdata/precompiles/fail-blsG1Add.json @@ -21,12 +21,12 @@ }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g1add_invalid_field_element" }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g1add_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG1Mul.json b/core/vm/testdata/precompiles/fail-blsG1Mul.json index acb8228aaa..7473d4d35c 100644 --- a/core/vm/testdata/precompiles/fail-blsG1Mul.json +++ b/core/vm/testdata/precompiles/fail-blsG1Mul.json @@ -21,12 +21,12 @@ }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g1mul_invalid_field_element" }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g1mul_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG1MultiExp.json b/core/vm/testdata/precompiles/fail-blsG1MultiExp.json index 2cd28bd3b5..24a46cc0d0 100644 --- a/core/vm/testdata/precompiles/fail-blsG1MultiExp.json +++ b/core/vm/testdata/precompiles/fail-blsG1MultiExp.json @@ -16,7 +16,7 @@ }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g1multiexp_invalid_field_element" }, { @@ -26,7 +26,7 @@ }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g1multiexp_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG2Add.json b/core/vm/testdata/precompiles/fail-blsG2Add.json index b1fe9d5b8d..b28a052b25 100644 --- a/core/vm/testdata/precompiles/fail-blsG2Add.json +++ b/core/vm/testdata/precompiles/fail-blsG2Add.json @@ -21,12 +21,12 @@ }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g2add_invalid_field_element" }, { "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g2add_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG2Mul.json b/core/vm/testdata/precompiles/fail-blsG2Mul.json index c2f0b89c8a..54a13c7f95 100644 --- a/core/vm/testdata/precompiles/fail-blsG2Mul.json +++ b/core/vm/testdata/precompiles/fail-blsG2Mul.json @@ -21,12 +21,12 @@ }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g2mul_invalid_field_element" }, { "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g2mul_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsG2MultiExp.json b/core/vm/testdata/precompiles/fail-blsG2MultiExp.json index 437f8dfca5..1679f17b30 100644 --- a/core/vm/testdata/precompiles/fail-blsG2MultiExp.json +++ b/core/vm/testdata/precompiles/fail-blsG2MultiExp.json @@ -21,12 +21,12 @@ }, { "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_g2multiexp_invalid_field_element" }, { "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_g2multiexp_point_not_on_curve" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsMapG1.json b/core/vm/testdata/precompiles/fail-blsMapG1.json index 8550269f12..8eacca4865 100644 --- a/core/vm/testdata/precompiles/fail-blsMapG1.json +++ b/core/vm/testdata/precompiles/fail-blsMapG1.json @@ -16,7 +16,7 @@ }, { "Input": "000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_mapg1_invalid_fq_element" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsMapG2.json b/core/vm/testdata/precompiles/fail-blsMapG2.json index 397a608b0a..184d3ecbaa 100644 --- a/core/vm/testdata/precompiles/fail-blsMapG2.json +++ b/core/vm/testdata/precompiles/fail-blsMapG2.json @@ -16,7 +16,7 @@ }, { "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_mapg2_invalid_fq_element" } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/fail-blsPairing.json b/core/vm/testdata/precompiles/fail-blsPairing.json index 084e55635c..4314d7335d 100644 --- a/core/vm/testdata/precompiles/fail-blsPairing.json +++ b/core/vm/testdata/precompiles/fail-blsPairing.json @@ -11,7 +11,7 @@ }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac", - "ExpectedError": "must be less than modulus", + "ExpectedError": "invalid fp.Element encoding", "Name": "bls_pairing_invalid_field_element" }, { @@ -21,12 +21,12 @@ }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_pairing_g1_not_on_curve" }, { "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "ExpectedError": "point is not on curve", + "ExpectedError": "invalid point: not on curve", "Name": "bls_pairing_g2_not_on_curve" }, { diff --git a/crypto/bls12381/arithmetic_decl.go b/crypto/bls12381/arithmetic_decl.go deleted file mode 100644 index f6d232d658..0000000000 --- a/crypto/bls12381/arithmetic_decl.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build (amd64 && blsasm) || (amd64 && blsadx) -// +build amd64,blsasm amd64,blsadx - -package bls12381 - -import ( - "golang.org/x/sys/cpu" -) - -func init() { - if !enableADX || !cpu.X86.HasADX || !cpu.X86.HasBMI2 { - mul = mulNoADX - } -} - -// Use ADX backend for default -var mul func(c, a, b *fe) = mulADX - -func square(c, a *fe) { - mul(c, a, a) -} - -func neg(c, a *fe) { - if a.isZero() { - c.set(a) - } else { - _neg(c, a) - } -} - -//go:noescape -func add(c, a, b *fe) - -//go:noescape -func addAssign(a, b *fe) - -//go:noescape -func ladd(c, a, b *fe) - -//go:noescape -func laddAssign(a, b *fe) - -//go:noescape -func double(c, a *fe) - -//go:noescape -func doubleAssign(a *fe) - -//go:noescape -func ldouble(c, a *fe) - -//go:noescape -func sub(c, a, b *fe) - -//go:noescape -func subAssign(a, b *fe) - -//go:noescape -func lsubAssign(a, b *fe) - -//go:noescape -func _neg(c, a *fe) - -//go:noescape -func mulNoADX(c, a, b *fe) - -//go:noescape -func mulADX(c, a, b *fe) diff --git a/crypto/bls12381/arithmetic_fallback.go b/crypto/bls12381/arithmetic_fallback.go deleted file mode 100644 index c09ae0d91c..0000000000 --- a/crypto/bls12381/arithmetic_fallback.go +++ /dev/null @@ -1,567 +0,0 @@ -// Native go field arithmetic code is generated with 'goff' -// https://github.com/ConsenSys/goff -// Many function signature of field operations are renamed. - -// Copyright 2020 ConsenSys AG -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// field modulus q = -// -// 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 -// Code generated by goff DO NOT EDIT -// goff version: v0.1.0 - build: 790f1f56eac432441e043abff8819eacddd1d668 -// fe are assumed to be in Montgomery form in all methods - -// /!\ WARNING /!\ -// this code has not been audited and is provided as-is. In particular, -// there is no security guarantees such as constant time implementation -// or side-channel attack resistance -// /!\ WARNING /!\ - -// Package bls (generated by goff) contains field arithmetics operations - -//go:build !amd64 || (!blsasm && !blsadx) -// +build !amd64 !blsasm,!blsadx - -package bls12381 - -import ( - "math/bits" -) - -func add(z, x, y *fe) { - var carry uint64 - - z[0], carry = bits.Add64(x[0], y[0], 0) - z[1], carry = bits.Add64(x[1], y[1], carry) - z[2], carry = bits.Add64(x[2], y[2], carry) - z[3], carry = bits.Add64(x[3], y[3], carry) - z[4], carry = bits.Add64(x[4], y[4], carry) - z[5], _ = bits.Add64(x[5], y[5], carry) - - // if z > q --> z -= q - // note: this is NOT constant time - if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) { - var b uint64 - z[0], b = bits.Sub64(z[0], 13402431016077863595, 0) - z[1], b = bits.Sub64(z[1], 2210141511517208575, b) - z[2], b = bits.Sub64(z[2], 7435674573564081700, b) - z[3], b = bits.Sub64(z[3], 7239337960414712511, b) - z[4], b = bits.Sub64(z[4], 5412103778470702295, b) - z[5], _ = bits.Sub64(z[5], 1873798617647539866, b) - } -} - -func addAssign(x, y *fe) { - var carry uint64 - - x[0], carry = bits.Add64(x[0], y[0], 0) - x[1], carry = bits.Add64(x[1], y[1], carry) - x[2], carry = bits.Add64(x[2], y[2], carry) - x[3], carry = bits.Add64(x[3], y[3], carry) - x[4], carry = bits.Add64(x[4], y[4], carry) - x[5], _ = bits.Add64(x[5], y[5], carry) - - // if z > q --> z -= q - // note: this is NOT constant time - if !(x[5] < 1873798617647539866 || (x[5] == 1873798617647539866 && (x[4] < 5412103778470702295 || (x[4] == 5412103778470702295 && (x[3] < 7239337960414712511 || (x[3] == 7239337960414712511 && (x[2] < 7435674573564081700 || (x[2] == 7435674573564081700 && (x[1] < 2210141511517208575 || (x[1] == 2210141511517208575 && (x[0] < 13402431016077863595))))))))))) { - var b uint64 - x[0], b = bits.Sub64(x[0], 13402431016077863595, 0) - x[1], b = bits.Sub64(x[1], 2210141511517208575, b) - x[2], b = bits.Sub64(x[2], 7435674573564081700, b) - x[3], b = bits.Sub64(x[3], 7239337960414712511, b) - x[4], b = bits.Sub64(x[4], 5412103778470702295, b) - x[5], _ = bits.Sub64(x[5], 1873798617647539866, b) - } -} - -func ladd(z, x, y *fe) { - var carry uint64 - z[0], carry = bits.Add64(x[0], y[0], 0) - z[1], carry = bits.Add64(x[1], y[1], carry) - z[2], carry = bits.Add64(x[2], y[2], carry) - z[3], carry = bits.Add64(x[3], y[3], carry) - z[4], carry = bits.Add64(x[4], y[4], carry) - z[5], _ = bits.Add64(x[5], y[5], carry) -} - -func laddAssign(x, y *fe) { - var carry uint64 - x[0], carry = bits.Add64(x[0], y[0], 0) - x[1], carry = bits.Add64(x[1], y[1], carry) - x[2], carry = bits.Add64(x[2], y[2], carry) - x[3], carry = bits.Add64(x[3], y[3], carry) - x[4], carry = bits.Add64(x[4], y[4], carry) - x[5], _ = bits.Add64(x[5], y[5], carry) -} - -func double(z, x *fe) { - var carry uint64 - - z[0], carry = bits.Add64(x[0], x[0], 0) - z[1], carry = bits.Add64(x[1], x[1], carry) - z[2], carry = bits.Add64(x[2], x[2], carry) - z[3], carry = bits.Add64(x[3], x[3], carry) - z[4], carry = bits.Add64(x[4], x[4], carry) - z[5], _ = bits.Add64(x[5], x[5], carry) - - // if z > q --> z -= q - // note: this is NOT constant time - if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) { - var b uint64 - z[0], b = bits.Sub64(z[0], 13402431016077863595, 0) - z[1], b = bits.Sub64(z[1], 2210141511517208575, b) - z[2], b = bits.Sub64(z[2], 7435674573564081700, b) - z[3], b = bits.Sub64(z[3], 7239337960414712511, b) - z[4], b = bits.Sub64(z[4], 5412103778470702295, b) - z[5], _ = bits.Sub64(z[5], 1873798617647539866, b) - } -} - -func doubleAssign(z *fe) { - var carry uint64 - - z[0], carry = bits.Add64(z[0], z[0], 0) - z[1], carry = bits.Add64(z[1], z[1], carry) - z[2], carry = bits.Add64(z[2], z[2], carry) - z[3], carry = bits.Add64(z[3], z[3], carry) - z[4], carry = bits.Add64(z[4], z[4], carry) - z[5], _ = bits.Add64(z[5], z[5], carry) - - // if z > q --> z -= q - // note: this is NOT constant time - if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) { - var b uint64 - z[0], b = bits.Sub64(z[0], 13402431016077863595, 0) - z[1], b = bits.Sub64(z[1], 2210141511517208575, b) - z[2], b = bits.Sub64(z[2], 7435674573564081700, b) - z[3], b = bits.Sub64(z[3], 7239337960414712511, b) - z[4], b = bits.Sub64(z[4], 5412103778470702295, b) - z[5], _ = bits.Sub64(z[5], 1873798617647539866, b) - } -} - -func ldouble(z, x *fe) { - var carry uint64 - - z[0], carry = bits.Add64(x[0], x[0], 0) - z[1], carry = bits.Add64(x[1], x[1], carry) - z[2], carry = bits.Add64(x[2], x[2], carry) - z[3], carry = bits.Add64(x[3], x[3], carry) - z[4], carry = bits.Add64(x[4], x[4], carry) - z[5], _ = bits.Add64(x[5], x[5], carry) -} - -func sub(z, x, y *fe) { - var b uint64 - z[0], b = bits.Sub64(x[0], y[0], 0) - z[1], b = bits.Sub64(x[1], y[1], b) - z[2], b = bits.Sub64(x[2], y[2], b) - z[3], b = bits.Sub64(x[3], y[3], b) - z[4], b = bits.Sub64(x[4], y[4], b) - z[5], b = bits.Sub64(x[5], y[5], b) - if b != 0 { - var c uint64 - z[0], c = bits.Add64(z[0], 13402431016077863595, 0) - z[1], c = bits.Add64(z[1], 2210141511517208575, c) - z[2], c = bits.Add64(z[2], 7435674573564081700, c) - z[3], c = bits.Add64(z[3], 7239337960414712511, c) - z[4], c = bits.Add64(z[4], 5412103778470702295, c) - z[5], _ = bits.Add64(z[5], 1873798617647539866, c) - } -} - -func subAssign(z, x *fe) { - var b uint64 - z[0], b = bits.Sub64(z[0], x[0], 0) - z[1], b = bits.Sub64(z[1], x[1], b) - z[2], b = bits.Sub64(z[2], x[2], b) - z[3], b = bits.Sub64(z[3], x[3], b) - z[4], b = bits.Sub64(z[4], x[4], b) - z[5], b = bits.Sub64(z[5], x[5], b) - if b != 0 { - var c uint64 - z[0], c = bits.Add64(z[0], 13402431016077863595, 0) - z[1], c = bits.Add64(z[1], 2210141511517208575, c) - z[2], c = bits.Add64(z[2], 7435674573564081700, c) - z[3], c = bits.Add64(z[3], 7239337960414712511, c) - z[4], c = bits.Add64(z[4], 5412103778470702295, c) - z[5], _ = bits.Add64(z[5], 1873798617647539866, c) - } -} - -func lsubAssign(z, x *fe) { - var b uint64 - z[0], b = bits.Sub64(z[0], x[0], 0) - z[1], b = bits.Sub64(z[1], x[1], b) - z[2], b = bits.Sub64(z[2], x[2], b) - z[3], b = bits.Sub64(z[3], x[3], b) - z[4], b = bits.Sub64(z[4], x[4], b) - z[5], _ = bits.Sub64(z[5], x[5], b) -} - -func neg(z *fe, x *fe) { - if x.isZero() { - z.zero() - return - } - var borrow uint64 - z[0], borrow = bits.Sub64(13402431016077863595, x[0], 0) - z[1], borrow = bits.Sub64(2210141511517208575, x[1], borrow) - z[2], borrow = bits.Sub64(7435674573564081700, x[2], borrow) - z[3], borrow = bits.Sub64(7239337960414712511, x[3], borrow) - z[4], borrow = bits.Sub64(5412103778470702295, x[4], borrow) - z[5], _ = bits.Sub64(1873798617647539866, x[5], borrow) -} - -func mul(z, x, y *fe) { - var t [6]uint64 - var c [3]uint64 - { - // round 0 - v := x[0] - c[1], c[0] = bits.Mul64(v, y[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd1(v, y[1], c[1]) - c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd1(v, y[2], c[1]) - c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd1(v, y[3], c[1]) - c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd1(v, y[4], c[1]) - c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd1(v, y[5], c[1]) - t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - { - // round 1 - v := x[1] - c[1], c[0] = madd1(v, y[0], t[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd2(v, y[1], c[1], t[1]) - c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd2(v, y[2], c[1], t[2]) - c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd2(v, y[3], c[1], t[3]) - c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd2(v, y[4], c[1], t[4]) - c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd2(v, y[5], c[1], t[5]) - t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - { - // round 2 - v := x[2] - c[1], c[0] = madd1(v, y[0], t[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd2(v, y[1], c[1], t[1]) - c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd2(v, y[2], c[1], t[2]) - c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd2(v, y[3], c[1], t[3]) - c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd2(v, y[4], c[1], t[4]) - c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd2(v, y[5], c[1], t[5]) - t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - { - // round 3 - v := x[3] - c[1], c[0] = madd1(v, y[0], t[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd2(v, y[1], c[1], t[1]) - c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd2(v, y[2], c[1], t[2]) - c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd2(v, y[3], c[1], t[3]) - c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd2(v, y[4], c[1], t[4]) - c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd2(v, y[5], c[1], t[5]) - t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - { - // round 4 - v := x[4] - c[1], c[0] = madd1(v, y[0], t[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd2(v, y[1], c[1], t[1]) - c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd2(v, y[2], c[1], t[2]) - c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd2(v, y[3], c[1], t[3]) - c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd2(v, y[4], c[1], t[4]) - c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd2(v, y[5], c[1], t[5]) - t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - { - // round 5 - v := x[5] - c[1], c[0] = madd1(v, y[0], t[0]) - m := c[0] * 9940570264628428797 - c[2] = madd0(m, 13402431016077863595, c[0]) - c[1], c[0] = madd2(v, y[1], c[1], t[1]) - c[2], z[0] = madd2(m, 2210141511517208575, c[2], c[0]) - c[1], c[0] = madd2(v, y[2], c[1], t[2]) - c[2], z[1] = madd2(m, 7435674573564081700, c[2], c[0]) - c[1], c[0] = madd2(v, y[3], c[1], t[3]) - c[2], z[2] = madd2(m, 7239337960414712511, c[2], c[0]) - c[1], c[0] = madd2(v, y[4], c[1], t[4]) - c[2], z[3] = madd2(m, 5412103778470702295, c[2], c[0]) - c[1], c[0] = madd2(v, y[5], c[1], t[5]) - z[5], z[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1]) - } - - // if z > q --> z -= q - // note: this is NOT constant time - if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) { - var b uint64 - z[0], b = bits.Sub64(z[0], 13402431016077863595, 0) - z[1], b = bits.Sub64(z[1], 2210141511517208575, b) - z[2], b = bits.Sub64(z[2], 7435674573564081700, b) - z[3], b = bits.Sub64(z[3], 7239337960414712511, b) - z[4], b = bits.Sub64(z[4], 5412103778470702295, b) - z[5], _ = bits.Sub64(z[5], 1873798617647539866, b) - } -} - -func square(z, x *fe) { - - var p [6]uint64 - - var u, v uint64 - { - // round 0 - u, p[0] = bits.Mul64(x[0], x[0]) - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - var t uint64 - t, u, v = madd1sb(x[0], x[1], u) - C, p[0] = madd2(m, 2210141511517208575, v, C) - t, u, v = madd1s(x[0], x[2], t, u) - C, p[1] = madd2(m, 7435674573564081700, v, C) - t, u, v = madd1s(x[0], x[3], t, u) - C, p[2] = madd2(m, 7239337960414712511, v, C) - t, u, v = madd1s(x[0], x[4], t, u) - C, p[3] = madd2(m, 5412103778470702295, v, C) - _, u, v = madd1s(x[0], x[5], t, u) - p[5], p[4] = madd3(m, 1873798617647539866, v, C, u) - } - { - // round 1 - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - u, v = madd1(x[1], x[1], p[1]) - C, p[0] = madd2(m, 2210141511517208575, v, C) - var t uint64 - t, u, v = madd2sb(x[1], x[2], p[2], u) - C, p[1] = madd2(m, 7435674573564081700, v, C) - t, u, v = madd2s(x[1], x[3], p[3], t, u) - C, p[2] = madd2(m, 7239337960414712511, v, C) - t, u, v = madd2s(x[1], x[4], p[4], t, u) - C, p[3] = madd2(m, 5412103778470702295, v, C) - _, u, v = madd2s(x[1], x[5], p[5], t, u) - p[5], p[4] = madd3(m, 1873798617647539866, v, C, u) - } - { - // round 2 - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - C, p[0] = madd2(m, 2210141511517208575, p[1], C) - u, v = madd1(x[2], x[2], p[2]) - C, p[1] = madd2(m, 7435674573564081700, v, C) - var t uint64 - t, u, v = madd2sb(x[2], x[3], p[3], u) - C, p[2] = madd2(m, 7239337960414712511, v, C) - t, u, v = madd2s(x[2], x[4], p[4], t, u) - C, p[3] = madd2(m, 5412103778470702295, v, C) - _, u, v = madd2s(x[2], x[5], p[5], t, u) - p[5], p[4] = madd3(m, 1873798617647539866, v, C, u) - } - { - // round 3 - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - C, p[0] = madd2(m, 2210141511517208575, p[1], C) - C, p[1] = madd2(m, 7435674573564081700, p[2], C) - u, v = madd1(x[3], x[3], p[3]) - C, p[2] = madd2(m, 7239337960414712511, v, C) - var t uint64 - t, u, v = madd2sb(x[3], x[4], p[4], u) - C, p[3] = madd2(m, 5412103778470702295, v, C) - _, u, v = madd2s(x[3], x[5], p[5], t, u) - p[5], p[4] = madd3(m, 1873798617647539866, v, C, u) - } - { - // round 4 - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - C, p[0] = madd2(m, 2210141511517208575, p[1], C) - C, p[1] = madd2(m, 7435674573564081700, p[2], C) - C, p[2] = madd2(m, 7239337960414712511, p[3], C) - u, v = madd1(x[4], x[4], p[4]) - C, p[3] = madd2(m, 5412103778470702295, v, C) - _, u, v = madd2sb(x[4], x[5], p[5], u) - p[5], p[4] = madd3(m, 1873798617647539866, v, C, u) - } - { - // round 5 - m := p[0] * 9940570264628428797 - C := madd0(m, 13402431016077863595, p[0]) - C, z[0] = madd2(m, 2210141511517208575, p[1], C) - C, z[1] = madd2(m, 7435674573564081700, p[2], C) - C, z[2] = madd2(m, 7239337960414712511, p[3], C) - C, z[3] = madd2(m, 5412103778470702295, p[4], C) - u, v = madd1(x[5], x[5], p[5]) - z[5], z[4] = madd3(m, 1873798617647539866, v, C, u) - } - - // if z > q --> z -= q - // note: this is NOT constant time - if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) { - var b uint64 - z[0], b = bits.Sub64(z[0], 13402431016077863595, 0) - z[1], b = bits.Sub64(z[1], 2210141511517208575, b) - z[2], b = bits.Sub64(z[2], 7435674573564081700, b) - z[3], b = bits.Sub64(z[3], 7239337960414712511, b) - z[4], b = bits.Sub64(z[4], 5412103778470702295, b) - z[5], _ = bits.Sub64(z[5], 1873798617647539866, b) - } -} - -// arith.go -// Copyright 2020 ConsenSys AG -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by goff DO NOT EDIT - -func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) { - var carry uint64 - hi, lo := bits.Mul64(a, b) - v, carry = bits.Add64(lo, v, 0) - u, carry = bits.Add64(hi, u, carry) - t, _ = bits.Add64(t, 0, carry) - return t, u, v -} - -// madd0 hi = a*b + c (discards lo bits) -func madd0(a, b, c uint64) (hi uint64) { - var carry, lo uint64 - hi, lo = bits.Mul64(a, b) - _, carry = bits.Add64(lo, c, 0) - hi, _ = bits.Add64(hi, 0, carry) - return -} - -// madd1 hi, lo = a*b + c -func madd1(a, b, c uint64) (hi uint64, lo uint64) { - var carry uint64 - hi, lo = bits.Mul64(a, b) - lo, carry = bits.Add64(lo, c, 0) - hi, _ = bits.Add64(hi, 0, carry) - return -} - -// madd2 hi, lo = a*b + c + d -func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { - var carry uint64 - hi, lo = bits.Mul64(a, b) - c, carry = bits.Add64(c, d, 0) - hi, _ = bits.Add64(hi, 0, carry) - lo, carry = bits.Add64(lo, c, 0) - hi, _ = bits.Add64(hi, 0, carry) - return -} - -// madd2s superhi, hi, lo = 2*a*b + c + d + e -func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) { - var carry, sum uint64 - - hi, lo = bits.Mul64(a, b) - lo, carry = bits.Add64(lo, lo, 0) - hi, superhi = bits.Add64(hi, hi, carry) - - sum, carry = bits.Add64(c, e, 0) - hi, _ = bits.Add64(hi, 0, carry) - lo, carry = bits.Add64(lo, sum, 0) - hi, _ = bits.Add64(hi, 0, carry) - hi, _ = bits.Add64(hi, 0, d) - return -} - -func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) { - var carry uint64 - - hi, lo = bits.Mul64(a, b) - lo, carry = bits.Add64(lo, lo, 0) - hi, superhi = bits.Add64(hi, hi, carry) - lo, carry = bits.Add64(lo, e, 0) - hi, _ = bits.Add64(hi, 0, carry) - hi, _ = bits.Add64(hi, 0, d) - return -} - -func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) { - var carry, sum uint64 - - hi, lo = bits.Mul64(a, b) - lo, carry = bits.Add64(lo, lo, 0) - hi, superhi = bits.Add64(hi, hi, carry) - - sum, carry = bits.Add64(c, e, 0) - hi, _ = bits.Add64(hi, 0, carry) - lo, carry = bits.Add64(lo, sum, 0) - hi, _ = bits.Add64(hi, 0, carry) - return -} - -func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) { - var carry uint64 - - hi, lo = bits.Mul64(a, b) - lo, carry = bits.Add64(lo, lo, 0) - hi, superhi = bits.Add64(hi, hi, carry) - lo, carry = bits.Add64(lo, e, 0) - hi, _ = bits.Add64(hi, 0, carry) - return -} - -func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { - var carry uint64 - hi, lo = bits.Mul64(a, b) - c, carry = bits.Add64(c, d, 0) - hi, _ = bits.Add64(hi, 0, carry) - lo, carry = bits.Add64(lo, c, 0) - hi, _ = bits.Add64(hi, e, carry) - return -} diff --git a/crypto/bls12381/arithmetic_x86.s b/crypto/bls12381/arithmetic_x86.s deleted file mode 100644 index 2cebbc46f7..0000000000 --- a/crypto/bls12381/arithmetic_x86.s +++ /dev/null @@ -1,2150 +0,0 @@ -// +build amd64,blsasm amd64,blsadx - -#include "textflag.h" - -// addition w/ modular reduction -// a = (a + b) % p -TEXT ·addAssign(SB), NOSPLIT, $0-16 - // | - MOVQ a+0(FP), DI - MOVQ b+8(FP), SI - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - - // | - ADDQ (SI), R8 - ADCQ 8(SI), R9 - ADCQ 16(SI), R10 - ADCQ 24(SI), R11 - ADCQ 32(SI), R12 - ADCQ 40(SI), R13 - - // | - MOVQ R8, R14 - MOVQ R9, R15 - MOVQ R10, CX - MOVQ R11, DX - MOVQ R12, SI - MOVQ R13, BX - MOVQ $0xb9feffffffffaaab, AX - SUBQ AX, R14 - MOVQ $0x1eabfffeb153ffff, AX - SBBQ AX, R15 - MOVQ $0x6730d2a0f6b0f624, AX - SBBQ AX, CX - MOVQ $0x64774b84f38512bf, AX - SBBQ AX, DX - MOVQ $0x4b1ba7b6434bacd7, AX - SBBQ AX, SI - MOVQ $0x1a0111ea397fe69a, AX - SBBQ AX, BX - CMOVQCC R14, R8 - CMOVQCC R15, R9 - CMOVQCC CX, R10 - CMOVQCC DX, R11 - CMOVQCC SI, R12 - CMOVQCC BX, R13 - - // | - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET - -/* | end */ - - -// addition w/ modular reduction -// c = (a + b) % p -TEXT ·add(SB), NOSPLIT, $0-24 - // | - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - - // | - ADDQ (SI), R8 - ADCQ 8(SI), R9 - ADCQ 16(SI), R10 - ADCQ 24(SI), R11 - ADCQ 32(SI), R12 - ADCQ 40(SI), R13 - - // | - MOVQ R8, R14 - MOVQ R9, R15 - MOVQ R10, CX - MOVQ R11, DX - MOVQ R12, SI - MOVQ R13, BX - MOVQ $0xb9feffffffffaaab, DI - SUBQ DI, R14 - MOVQ $0x1eabfffeb153ffff, DI - SBBQ DI, R15 - MOVQ $0x6730d2a0f6b0f624, DI - SBBQ DI, CX - MOVQ $0x64774b84f38512bf, DI - SBBQ DI, DX - MOVQ $0x4b1ba7b6434bacd7, DI - SBBQ DI, SI - MOVQ $0x1a0111ea397fe69a, DI - SBBQ DI, BX - CMOVQCC R14, R8 - CMOVQCC R15, R9 - CMOVQCC CX, R10 - CMOVQCC DX, R11 - CMOVQCC SI, R12 - CMOVQCC BX, R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// addition w/o reduction check -// c = (a + b) -TEXT ·ladd(SB), NOSPLIT, $0-24 - // | - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - - // | - ADDQ (SI), R8 - ADCQ 8(SI), R9 - ADCQ 16(SI), R10 - ADCQ 24(SI), R11 - ADCQ 32(SI), R12 - ADCQ 40(SI), R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// addition w/o reduction check -// a = a + b -TEXT ·laddAssign(SB), NOSPLIT, $0-16 - // | - MOVQ a+0(FP), DI - MOVQ b+8(FP), SI - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - - // | - ADDQ (SI), R8 - ADCQ 8(SI), R9 - ADCQ 16(SI), R10 - ADCQ 24(SI), R11 - ADCQ 32(SI), R12 - ADCQ 40(SI), R13 - - // | - MOVQ a+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// subtraction w/ modular reduction -// c = (a - b) % p -TEXT ·sub(SB), NOSPLIT, $0-24 - // | - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - XORQ AX, AX - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - SUBQ (SI), R8 - SBBQ 8(SI), R9 - SBBQ 16(SI), R10 - SBBQ 24(SI), R11 - SBBQ 32(SI), R12 - SBBQ 40(SI), R13 - - // | - MOVQ $0xb9feffffffffaaab, R14 - MOVQ $0x1eabfffeb153ffff, R15 - MOVQ $0x6730d2a0f6b0f624, CX - MOVQ $0x64774b84f38512bf, DX - MOVQ $0x4b1ba7b6434bacd7, SI - MOVQ $0x1a0111ea397fe69a, BX - CMOVQCC AX, R14 - CMOVQCC AX, R15 - CMOVQCC AX, CX - CMOVQCC AX, DX - CMOVQCC AX, SI - CMOVQCC AX, BX - ADDQ R14, R8 - ADCQ R15, R9 - ADCQ CX, R10 - ADCQ DX, R11 - ADCQ SI, R12 - ADCQ BX, R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// subtraction w/ modular reduction -// a = (a - b) % p -TEXT ·subAssign(SB), NOSPLIT, $0-16 - // | - MOVQ a+0(FP), DI - MOVQ b+8(FP), SI - XORQ AX, AX - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - SUBQ (SI), R8 - SBBQ 8(SI), R9 - SBBQ 16(SI), R10 - SBBQ 24(SI), R11 - SBBQ 32(SI), R12 - SBBQ 40(SI), R13 - - // | - MOVQ $0xb9feffffffffaaab, R14 - MOVQ $0x1eabfffeb153ffff, R15 - MOVQ $0x6730d2a0f6b0f624, CX - MOVQ $0x64774b84f38512bf, DX - MOVQ $0x4b1ba7b6434bacd7, SI - MOVQ $0x1a0111ea397fe69a, BX - CMOVQCC AX, R14 - CMOVQCC AX, R15 - CMOVQCC AX, CX - CMOVQCC AX, DX - CMOVQCC AX, SI - CMOVQCC AX, BX - ADDQ R14, R8 - ADCQ R15, R9 - ADCQ CX, R10 - ADCQ DX, R11 - ADCQ SI, R12 - ADCQ BX, R13 - - // | - MOVQ a+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// subtraction w/o reduction check -// a = (a - b) -TEXT ·lsubAssign(SB), NOSPLIT, $0-16 - // | - MOVQ a+0(FP), DI - MOVQ b+8(FP), SI - - // | - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - SUBQ (SI), R8 - SBBQ 8(SI), R9 - SBBQ 16(SI), R10 - SBBQ 24(SI), R11 - SBBQ 32(SI), R12 - SBBQ 40(SI), R13 - - // | - MOVQ a+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - -// doubling w/ reduction -// c = (2 * a) % p -TEXT ·double(SB), NOSPLIT, $0-16 - // | - MOVQ a+8(FP), DI - - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - ADDQ R8, R8 - ADCQ R9, R9 - ADCQ R10, R10 - ADCQ R11, R11 - ADCQ R12, R12 - ADCQ R13, R13 - - // | - MOVQ R8, R14 - MOVQ R9, R15 - MOVQ R10, CX - MOVQ R11, DX - MOVQ R12, SI - MOVQ R13, BX - MOVQ $0xb9feffffffffaaab, DI - SUBQ DI, R14 - MOVQ $0x1eabfffeb153ffff, DI - SBBQ DI, R15 - MOVQ $0x6730d2a0f6b0f624, DI - SBBQ DI, CX - MOVQ $0x64774b84f38512bf, DI - SBBQ DI, DX - MOVQ $0x4b1ba7b6434bacd7, DI - SBBQ DI, SI - MOVQ $0x1a0111ea397fe69a, DI - SBBQ DI, BX - CMOVQCC R14, R8 - CMOVQCC R15, R9 - CMOVQCC CX, R10 - CMOVQCC DX, R11 - CMOVQCC SI, R12 - CMOVQCC BX, R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// doubling w/ reduction -// a = (2 * a) % p -TEXT ·doubleAssign(SB), NOSPLIT, $0-8 - // | - MOVQ a+0(FP), DI - - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - ADDQ R8, R8 - ADCQ R9, R9 - ADCQ R10, R10 - ADCQ R11, R11 - ADCQ R12, R12 - ADCQ R13, R13 - - // | - MOVQ R8, R14 - MOVQ R9, R15 - MOVQ R10, CX - MOVQ R11, DX - MOVQ R12, SI - MOVQ R13, BX - MOVQ $0xb9feffffffffaaab, AX - SUBQ AX, R14 - MOVQ $0x1eabfffeb153ffff, AX - SBBQ AX, R15 - MOVQ $0x6730d2a0f6b0f624, AX - SBBQ AX, CX - MOVQ $0x64774b84f38512bf, AX - SBBQ AX, DX - MOVQ $0x4b1ba7b6434bacd7, AX - SBBQ AX, SI - MOVQ $0x1a0111ea397fe69a, AX - SBBQ AX, BX - CMOVQCC R14, R8 - CMOVQCC R15, R9 - CMOVQCC CX, R10 - CMOVQCC DX, R11 - CMOVQCC SI, R12 - CMOVQCC BX, R13 - - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// doubling w/o reduction -// c = 2 * a -TEXT ·ldouble(SB), NOSPLIT, $0-16 - // | - MOVQ a+8(FP), DI - - MOVQ (DI), R8 - MOVQ 8(DI), R9 - MOVQ 16(DI), R10 - MOVQ 24(DI), R11 - MOVQ 32(DI), R12 - MOVQ 40(DI), R13 - - // | - ADDQ R8, R8 - ADCQ R9, R9 - ADCQ R10, R10 - ADCQ R11, R11 - ADCQ R12, R12 - ADCQ R13, R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - - RET -/* | end */ - - -TEXT ·_neg(SB), NOSPLIT, $0-16 - // | - MOVQ a+8(FP), DI - - // | - MOVQ $0xb9feffffffffaaab, R8 - MOVQ $0x1eabfffeb153ffff, R9 - MOVQ $0x6730d2a0f6b0f624, R10 - MOVQ $0x64774b84f38512bf, R11 - MOVQ $0x4b1ba7b6434bacd7, R12 - MOVQ $0x1a0111ea397fe69a, R13 - SUBQ (DI), R8 - SBBQ 8(DI), R9 - SBBQ 16(DI), R10 - SBBQ 24(DI), R11 - SBBQ 32(DI), R12 - SBBQ 40(DI), R13 - - // | - MOVQ c+0(FP), DI - MOVQ R8, (DI) - MOVQ R9, 8(DI) - MOVQ R10, 16(DI) - MOVQ R11, 24(DI) - MOVQ R12, 32(DI) - MOVQ R13, 40(DI) - RET -/* | end */ - - -// multiplication without using MULX/ADX -// c = a * b % p -TEXT ·mulNoADX(SB), NOSPLIT, $24-24 - // | - -/* inputs */ - - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - MOVQ $0x00, R9 - MOVQ $0x00, R10 - MOVQ $0x00, R11 - MOVQ $0x00, R12 - MOVQ $0x00, R13 - MOVQ $0x00, R14 - MOVQ $0x00, R15 - - // | - -/* i0 */ - - // | a0 @ CX - MOVQ (DI), CX - - // | a0 * b0 - MOVQ (SI), AX - MULQ CX - MOVQ AX, (SP) - MOVQ DX, R8 - - // | a0 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R8 - ADCQ DX, R9 - - // | a0 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R9 - ADCQ DX, R10 - - // | a0 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R10 - ADCQ DX, R11 - - // | a0 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R11 - ADCQ DX, R12 - - // | a0 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - - // | - -/* i1 */ - - // | a1 @ CX - MOVQ 8(DI), CX - MOVQ $0x00, BX - - // | a1 * b0 - MOVQ (SI), AX - MULQ CX - ADDQ AX, R8 - ADCQ DX, R9 - ADCQ $0x00, R10 - ADCQ $0x00, BX - MOVQ R8, 8(SP) - MOVQ $0x00, R8 - - // | a1 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R9 - ADCQ DX, R10 - ADCQ BX, R11 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a1 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R10 - ADCQ DX, R11 - ADCQ BX, R12 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a1 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R11 - ADCQ DX, R12 - ADCQ BX, R13 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a1 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - ADCQ BX, R14 - - // | a1 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R13 - ADCQ DX, R14 - - // | - -/* i2 */ - - // | a2 @ CX - MOVQ 16(DI), CX - MOVQ $0x00, BX - - // | a2 * b0 - MOVQ (SI), AX - MULQ CX - ADDQ AX, R9 - ADCQ DX, R10 - ADCQ $0x00, R11 - ADCQ $0x00, BX - MOVQ R9, 16(SP) - MOVQ $0x00, R9 - - // | a2 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R10 - ADCQ DX, R11 - ADCQ BX, R12 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a2 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R11 - ADCQ DX, R12 - ADCQ BX, R13 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a2 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - ADCQ BX, R14 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a2 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R13 - ADCQ DX, R14 - ADCQ BX, R15 - - // | a2 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R14 - ADCQ DX, R15 - - // | - -/* i3 */ - - // | a3 @ CX - MOVQ 24(DI), CX - MOVQ $0x00, BX - - // | a3 * b0 - MOVQ (SI), AX - MULQ CX - ADDQ AX, R10 - ADCQ DX, R11 - ADCQ $0x00, R12 - ADCQ $0x00, BX - - // | a3 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R11 - ADCQ DX, R12 - ADCQ BX, R13 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a3 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - ADCQ BX, R14 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a3 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R13 - ADCQ DX, R14 - ADCQ BX, R15 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a3 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R14 - ADCQ DX, R15 - ADCQ BX, R8 - - // | a3 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R15 - ADCQ DX, R8 - - // | - -/* i4 */ - - // | a4 @ CX - MOVQ 32(DI), CX - MOVQ $0x00, BX - - // | a4 * b0 - MOVQ (SI), AX - MULQ CX - ADDQ AX, R11 - ADCQ DX, R12 - ADCQ $0x00, R13 - ADCQ $0x00, BX - - // | a4 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - ADCQ BX, R14 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a4 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R13 - ADCQ DX, R14 - ADCQ BX, R15 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a4 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R14 - ADCQ DX, R15 - ADCQ BX, R8 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a4 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R15 - ADCQ DX, R8 - ADCQ BX, R9 - - // | a4 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R8 - ADCQ DX, R9 - - // | - -/* i5 */ - - // | a5 @ CX - MOVQ 40(DI), CX - MOVQ $0x00, BX - - // | a5 * b0 - MOVQ (SI), AX - MULQ CX - ADDQ AX, R12 - ADCQ DX, R13 - ADCQ $0x00, R14 - ADCQ $0x00, BX - - // | a5 * b1 - MOVQ 8(SI), AX - MULQ CX - ADDQ AX, R13 - ADCQ DX, R14 - ADCQ BX, R15 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a5 * b2 - MOVQ 16(SI), AX - MULQ CX - ADDQ AX, R14 - ADCQ DX, R15 - ADCQ BX, R8 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a5 * b3 - MOVQ 24(SI), AX - MULQ CX - ADDQ AX, R15 - ADCQ DX, R8 - ADCQ BX, R9 - MOVQ $0x00, BX - ADCQ $0x00, BX - - // | a5 * b4 - MOVQ 32(SI), AX - MULQ CX - ADDQ AX, R8 - ADCQ DX, R9 - ADCQ $0x00, BX - - // | a5 * b5 - MOVQ 40(SI), AX - MULQ CX - ADDQ AX, R9 - ADCQ DX, BX - - // | - -/* */ - - // | - // | W - // | 0 (SP) | 1 8(SP) | 2 16(SP) | 3 R10 | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 R9 | 11 BX - - - MOVQ (SP), CX - MOVQ 8(SP), DI - MOVQ 16(SP), SI - MOVQ BX, (SP) - MOVQ R9, 8(SP) - - // | - -/* montgomery reduction */ - - // | - -/* i0 */ - - // | - // | W - // | 0 CX | 1 DI | 2 SI | 3 R10 | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 8(SP) | 11 (SP) - - - // | | u0 = w0 * inp - MOVQ CX, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w0 @ CX - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, CX - ADCQ DX, BX - - // | j1 - - // | w1 @ DI - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, DI - ADCQ $0x00, DX - ADDQ BX, DI - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w2 @ SI - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, SI - ADCQ $0x00, DX - ADDQ BX, SI - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w3 @ R10 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R10 - ADCQ $0x00, DX - ADDQ BX, R10 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w4 @ R11 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R11 - ADCQ $0x00, DX - ADDQ BX, R11 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w5 @ R12 - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ $0x00, DX - ADDQ BX, R12 - - // | w6 @ R13 - ADCQ DX, R13 - ADCQ $0x00, CX - - // | - -/* i1 */ - - // | - // | W - // | 0 - | 1 DI | 2 SI | 3 R10 | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 8(SP) | 11 (SP) - - - // | | u1 = w1 * inp - MOVQ DI, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w1 @ DI - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, DI - ADCQ DX, BX - - // | j1 - - // | w2 @ SI - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, SI - ADCQ $0x00, DX - ADDQ BX, SI - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w3 @ R10 - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, R10 - ADCQ $0x00, DX - ADDQ BX, R10 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w4 @ R11 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R11 - ADCQ $0x00, DX - ADDQ BX, R11 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w5 @ R12 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ $0x00, DX - ADDQ BX, R12 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w6 @ R13 - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, R13 - ADCQ DX, CX - ADDQ BX, R13 - - // | w7 @ R14 - ADCQ CX, R14 - MOVQ $0x00, CX - ADCQ $0x00, CX - - // | - -/* i2 */ - - // | - // | W - // | 0 - | 1 - | 2 SI | 3 R10 | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 8(SP) | 11 (SP) - - - // | | u2 = w2 * inp - MOVQ SI, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w2 @ SI - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, SI - ADCQ DX, BX - - // | j1 - - // | w3 @ R10 - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, R10 - ADCQ $0x00, DX - ADDQ BX, R10 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w4 @ R11 - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, R11 - ADCQ $0x00, DX - ADDQ BX, R11 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w5 @ R12 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ $0x00, DX - ADDQ BX, R12 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w6 @ R13 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R13 - ADCQ $0x00, DX - ADDQ BX, R13 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w7 @ R14 - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, R14 - ADCQ DX, CX - ADDQ BX, R14 - - // | w8 @ R15 - ADCQ CX, R15 - MOVQ $0x00, CX - ADCQ $0x00, CX - - // | - -/* i3 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 R10 | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 8(SP) | 11 (SP) - - - // | | u3 = w3 * inp - MOVQ R10, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w3 @ R10 - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, R10 - ADCQ DX, BX - - // | j1 - - // | w4 @ R11 - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, R11 - ADCQ $0x00, DX - ADDQ BX, R11 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w5 @ R12 - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ $0x00, DX - ADDQ BX, R12 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w6 @ R13 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R13 - ADCQ $0x00, DX - ADDQ BX, R13 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w7 @ R14 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R14 - ADCQ $0x00, DX - ADDQ BX, R14 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w8 @ R15 - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, R15 - ADCQ DX, CX - ADDQ BX, R15 - - // | w9 @ R8 - ADCQ CX, R8 - MOVQ $0x00, CX - ADCQ $0x00, CX - - // | - -/* i4 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 - | 4 R11 | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 8(SP) | 11 (SP) - - - // | | u4 = w4 * inp - MOVQ R11, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w4 @ R11 - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, R11 - ADCQ DX, BX - - // | j1 - - // | w5 @ R12 - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ $0x00, DX - ADDQ BX, R12 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w6 @ R13 - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, R13 - ADCQ $0x00, DX - ADDQ BX, R13 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w7 @ R14 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R14 - ADCQ $0x00, DX - ADDQ BX, R14 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w8 @ R15 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R15 - ADCQ $0x00, DX - ADDQ BX, R15 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w9 @ R8 - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, R8 - ADCQ DX, CX - ADDQ BX, R8 - - // | move to idle register - MOVQ 8(SP), DI - - // | w10 @ DI - ADCQ CX, DI - MOVQ $0x00, CX - ADCQ $0x00, CX - - // | - -/* i5 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 - | 4 - | 5 R12 - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 DI | 11 (SP) - - - // | | u5 = w5 * inp - MOVQ R12, AX - MULQ ·inp+0(SB) - MOVQ AX, R9 - MOVQ $0x00, BX - - // | - -/* */ - - // | j0 - - // | w5 @ R12 - MOVQ ·modulus+0(SB), AX - MULQ R9 - ADDQ AX, R12 - ADCQ DX, BX - - // | j1 - - // | w6 @ R13 - MOVQ ·modulus+8(SB), AX - MULQ R9 - ADDQ AX, R13 - ADCQ $0x00, DX - ADDQ BX, R13 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j2 - - // | w7 @ R14 - MOVQ ·modulus+16(SB), AX - MULQ R9 - ADDQ AX, R14 - ADCQ $0x00, DX - ADDQ BX, R14 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j3 - - // | w8 @ R15 - MOVQ ·modulus+24(SB), AX - MULQ R9 - ADDQ AX, R15 - ADCQ $0x00, DX - ADDQ BX, R15 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j4 - - // | w9 @ R8 - MOVQ ·modulus+32(SB), AX - MULQ R9 - ADDQ AX, R8 - ADCQ $0x00, DX - ADDQ BX, R8 - MOVQ $0x00, BX - ADCQ DX, BX - - // | j5 - - // | w10 @ DI - MOVQ ·modulus+40(SB), AX - MULQ R9 - ADDQ AX, DI - ADCQ DX, CX - ADDQ BX, DI - - // | w11 @ CX - ADCQ (SP), CX - - // | - // | W montgomerry reduction ends - // | 0 - | 1 - | 2 - | 3 - | 4 - | 5 - - // | 6 R13 | 7 R14 | 8 R15 | 9 R8 | 10 DI | 11 CX - - - // | - - -/* modular reduction */ - - MOVQ R13, R10 - SUBQ ·modulus+0(SB), R10 - MOVQ R14, R11 - SBBQ ·modulus+8(SB), R11 - MOVQ R15, R12 - SBBQ ·modulus+16(SB), R12 - MOVQ R8, AX - SBBQ ·modulus+24(SB), AX - MOVQ DI, BX - SBBQ ·modulus+32(SB), BX - MOVQ CX, R9 - SBBQ ·modulus+40(SB), R9 - // | - -/* out */ - - MOVQ c+0(FP), SI - CMOVQCC R10, R13 - MOVQ R13, (SI) - CMOVQCC R11, R14 - MOVQ R14, 8(SI) - CMOVQCC R12, R15 - MOVQ R15, 16(SI) - CMOVQCC AX, R8 - MOVQ R8, 24(SI) - CMOVQCC BX, DI - MOVQ DI, 32(SI) - CMOVQCC R9, CX - MOVQ CX, 40(SI) - RET - - // | - -/* end */ - - -// multiplication -// c = a * b % p -TEXT ·mulADX(SB), NOSPLIT, $16-24 - // | - -/* inputs */ - - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - XORQ AX, AX - - // | - -/* i0 */ - - // | a0 @ DX - MOVQ (DI), DX - - // | a0 * b0 - MULXQ (SI), AX, CX - MOVQ AX, (SP) - - // | a0 * b1 - MULXQ 8(SI), AX, R8 - ADCXQ AX, CX - - // | a0 * b2 - MULXQ 16(SI), AX, R9 - ADCXQ AX, R8 - - // | a0 * b3 - MULXQ 24(SI), AX, R10 - ADCXQ AX, R9 - - // | a0 * b4 - MULXQ 32(SI), AX, R11 - ADCXQ AX, R10 - - // | a0 * b5 - MULXQ 40(SI), AX, R12 - ADCXQ AX, R11 - ADCQ $0x00, R12 - - // | - -/* i1 */ - - // | a1 @ DX - MOVQ 8(DI), DX - XORQ R13, R13 - - // | a1 * b0 - MULXQ (SI), AX, BX - ADOXQ AX, CX - ADCXQ BX, R8 - MOVQ CX, 8(SP) - - // | a1 * b1 - MULXQ 8(SI), AX, BX - ADOXQ AX, R8 - ADCXQ BX, R9 - - // | a1 * b2 - MULXQ 16(SI), AX, BX - ADOXQ AX, R9 - ADCXQ BX, R10 - - // | a1 * b3 - MULXQ 24(SI), AX, BX - ADOXQ AX, R10 - ADCXQ BX, R11 - - // | a1 * b4 - MULXQ 32(SI), AX, BX - ADOXQ AX, R11 - ADCXQ BX, R12 - - // | a1 * b5 - MULXQ 40(SI), AX, BX - ADOXQ AX, R12 - ADOXQ R13, R13 - ADCXQ BX, R13 - - // | - -/* i2 */ - - // | a2 @ DX - MOVQ 16(DI), DX - XORQ R14, R14 - - // | a2 * b0 - MULXQ (SI), AX, BX - ADOXQ AX, R8 - ADCXQ BX, R9 - - // | a2 * b1 - MULXQ 8(SI), AX, BX - ADOXQ AX, R9 - ADCXQ BX, R10 - - // | a2 * b2 - MULXQ 16(SI), AX, BX - ADOXQ AX, R10 - ADCXQ BX, R11 - - // | a2 * b3 - MULXQ 24(SI), AX, BX - ADOXQ AX, R11 - ADCXQ BX, R12 - - // | a2 * b4 - MULXQ 32(SI), AX, BX - ADOXQ AX, R12 - ADCXQ BX, R13 - - // | a2 * b5 - MULXQ 40(SI), AX, BX - ADOXQ AX, R13 - ADOXQ R14, R14 - ADCXQ BX, R14 - - // | - -/* i3 */ - - // | a3 @ DX - MOVQ 24(DI), DX - XORQ R15, R15 - - // | a3 * b0 - MULXQ (SI), AX, BX - ADOXQ AX, R9 - ADCXQ BX, R10 - - // | a3 * b1 - MULXQ 8(SI), AX, BX - ADOXQ AX, R10 - ADCXQ BX, R11 - - // | a3 * b2 - MULXQ 16(SI), AX, BX - ADOXQ AX, R11 - ADCXQ BX, R12 - - // | a3 * b3 - MULXQ 24(SI), AX, BX - ADOXQ AX, R12 - ADCXQ BX, R13 - - // | a3 * b4 - MULXQ 32(SI), AX, BX - ADOXQ AX, R13 - ADCXQ BX, R14 - - // | a3 * b5 - MULXQ 40(SI), AX, BX - ADOXQ AX, R14 - ADOXQ R15, R15 - ADCXQ BX, R15 - - // | - -/* i4 */ - - // | a4 @ DX - MOVQ 32(DI), DX - XORQ CX, CX - - // | a4 * b0 - MULXQ (SI), AX, BX - ADOXQ AX, R10 - ADCXQ BX, R11 - - // | a4 * b1 - MULXQ 8(SI), AX, BX - ADOXQ AX, R11 - ADCXQ BX, R12 - - // | a4 * b2 - MULXQ 16(SI), AX, BX - ADOXQ AX, R12 - ADCXQ BX, R13 - - // | a4 * b3 - MULXQ 24(SI), AX, BX - ADOXQ AX, R13 - ADCXQ BX, R14 - - // | a4 * b4 - MULXQ 32(SI), AX, BX - ADOXQ AX, R14 - ADCXQ BX, R15 - - // | a4 * b5 - MULXQ 40(SI), AX, BX - ADOXQ AX, R15 - ADOXQ CX, CX - ADCXQ BX, CX - - // | - -/* i5 */ - - // | a5 @ DX - MOVQ 40(DI), DX - XORQ DI, DI - - // | a5 * b0 - MULXQ (SI), AX, BX - ADOXQ AX, R11 - ADCXQ BX, R12 - - // | a5 * b1 - MULXQ 8(SI), AX, BX - ADOXQ AX, R12 - ADCXQ BX, R13 - - // | a5 * b2 - MULXQ 16(SI), AX, BX - ADOXQ AX, R13 - ADCXQ BX, R14 - - // | a5 * b3 - MULXQ 24(SI), AX, BX - ADOXQ AX, R14 - ADCXQ BX, R15 - - // | a5 * b4 - MULXQ 32(SI), AX, BX - ADOXQ AX, R15 - ADCXQ BX, CX - - // | a5 * b5 - MULXQ 40(SI), AX, BX - ADOXQ AX, CX - ADOXQ BX, DI - ADCQ $0x00, DI - - // | - -/* */ - - // | - // | W - // | 0 (SP) | 1 8(SP) | 2 R8 | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 DI - - - MOVQ (SP), BX - MOVQ 8(SP), SI - MOVQ DI, (SP) - - // | - // | W ready to mont - // | 0 BX | 1 SI | 2 R8 | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | - -/* montgomery reduction */ - - // | clear flags - XORQ AX, AX - - // | - -/* i0 */ - - // | - // | W - // | 0 BX | 1 SI | 2 R8 | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u0 = w0 * inp - MOVQ BX, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w0 @ BX - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, BX - ADCXQ DI, SI - - // | j1 - - // | w1 @ SI - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, SI - ADCXQ DI, R8 - - // | j2 - - // | w2 @ R8 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R8 - ADCXQ DI, R9 - - // | j3 - - // | w3 @ R9 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R9 - ADCXQ DI, R10 - - // | j4 - - // | w4 @ R10 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R10 - ADCXQ DI, R11 - - // | j5 - - // | w5 @ R11 - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - ADOXQ BX, R12 - ADCXQ BX, BX - MOVQ $0x00, AX - ADOXQ AX, BX - - // | clear flags - XORQ AX, AX - - // | - -/* i1 */ - - // | - // | W - // | 0 - | 1 SI | 2 R8 | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u1 = w1 * inp - MOVQ SI, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w1 @ SI - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, SI - ADCXQ DI, R8 - - // | j1 - - // | w2 @ R8 - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, R8 - ADCXQ DI, R9 - - // | j2 - - // | w3 @ R9 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R9 - ADCXQ DI, R10 - - // | j3 - - // | w4 @ R10 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R10 - ADCXQ DI, R11 - - // | j4 - - // | w5 @ R11 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - - // | j5 - - // | w6 @ R12 - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, R12 - ADCXQ DI, R13 - ADOXQ BX, R13 - ADCXQ SI, SI - MOVQ $0x00, AX - ADOXQ AX, SI - - // | clear flags - XORQ AX, AX - - // | - -/* i2 */ - - // | - // | W - // | 0 - | 1 - | 2 R8 | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u2 = w2 * inp - MOVQ R8, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w2 @ R8 - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, R8 - ADCXQ DI, R9 - - // | j1 - - // | w3 @ R9 - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, R9 - ADCXQ DI, R10 - - // | j2 - - // | w4 @ R10 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R10 - ADCXQ DI, R11 - - // | j3 - - // | w5 @ R11 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - - // | j4 - - // | w6 @ R12 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R12 - ADCXQ DI, R13 - - // | j5 - - // | w7 @ R13 - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, R13 - ADCXQ DI, R14 - ADOXQ SI, R14 - ADCXQ R8, R8 - MOVQ $0x00, AX - ADOXQ AX, R8 - - // | clear flags - XORQ AX, AX - - // | - -/* i3 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 R9 | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u3 = w3 * inp - MOVQ R9, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w3 @ R9 - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, R9 - ADCXQ DI, R10 - - // | j1 - - // | w4 @ R10 - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, R10 - ADCXQ DI, R11 - - // | j2 - - // | w5 @ R11 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - - // | j3 - - // | w6 @ R12 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R12 - ADCXQ DI, R13 - - // | j4 - - // | w7 @ R13 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R13 - ADCXQ DI, R14 - - // | j5 - - // | w8 @ R14 - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, R14 - ADCXQ DI, R15 - ADOXQ R8, R15 - ADCXQ R9, R9 - MOVQ $0x00, AX - ADOXQ AX, R9 - - // | clear flags - XORQ AX, AX - - // | - -/* i4 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 - | 4 R10 | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u4 = w4 * inp - MOVQ R10, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w4 @ R10 - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, R10 - ADCXQ DI, R11 - - // | j1 - - // | w5 @ R11 - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - - // | j2 - - // | w6 @ R12 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R12 - ADCXQ DI, R13 - - // | j3 - - // | w7 @ R13 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R13 - ADCXQ DI, R14 - - // | j4 - - // | w8 @ R14 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R14 - ADCXQ DI, R15 - - // | j5 - - // | w9 @ R15 - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, R15 - ADCXQ DI, CX - ADOXQ R9, CX - ADCXQ R10, R10 - MOVQ $0x00, AX - ADOXQ AX, R10 - - // | clear flags - XORQ AX, AX - - // | - -/* i5 */ - - // | - // | W - // | 0 - | 1 - | 2 - | 3 - | 4 - | 5 R11 - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 (SP) - - - // | | u5 = w5 * inp - MOVQ R11, DX - MULXQ ·inp+0(SB), DX, DI - - // | - -/* */ - - // | j0 - - // | w5 @ R11 - MULXQ ·modulus+0(SB), AX, DI - ADOXQ AX, R11 - ADCXQ DI, R12 - - // | j1 - - // | w6 @ R12 - MULXQ ·modulus+8(SB), AX, DI - ADOXQ AX, R12 - ADCXQ DI, R13 - - // | j2 - - // | w7 @ R13 - MULXQ ·modulus+16(SB), AX, DI - ADOXQ AX, R13 - ADCXQ DI, R14 - - // | j3 - - // | w8 @ R14 - MULXQ ·modulus+24(SB), AX, DI - ADOXQ AX, R14 - ADCXQ DI, R15 - - // | j4 - - // | w9 @ R15 - MULXQ ·modulus+32(SB), AX, DI - ADOXQ AX, R15 - ADCXQ DI, CX - - // | j5 - - // | w10 @ CX - MULXQ ·modulus+40(SB), AX, DI - ADOXQ AX, CX - - // | w11 @ (SP) - // | move to an idle register - MOVQ (SP), BX - ADCXQ DI, BX - ADOXQ R10, BX - - // | - // | W montgomery reduction ends - // | 0 - | 1 - | 2 - | 3 - | 4 - | 5 - - // | 6 R12 | 7 R13 | 8 R14 | 9 R15 | 10 CX | 11 BX - - - // | - -/* modular reduction */ - - MOVQ R12, AX - SUBQ ·modulus+0(SB), AX - MOVQ R13, DI - SBBQ ·modulus+8(SB), DI - MOVQ R14, SI - SBBQ ·modulus+16(SB), SI - MOVQ R15, R8 - SBBQ ·modulus+24(SB), R8 - MOVQ CX, R9 - SBBQ ·modulus+32(SB), R9 - MOVQ BX, R10 - SBBQ ·modulus+40(SB), R10 - - // | - -/* out */ - - MOVQ c+0(FP), R11 - CMOVQCC AX, R12 - MOVQ R12, (R11) - CMOVQCC DI, R13 - MOVQ R13, 8(R11) - CMOVQCC SI, R14 - MOVQ R14, 16(R11) - CMOVQCC R8, R15 - MOVQ R15, 24(R11) - CMOVQCC R9, CX - MOVQ CX, 32(R11) - CMOVQCC R10, BX - MOVQ BX, 40(R11) - RET - - // | - -/* end */ diff --git a/crypto/bls12381/arithmetic_x86_adx.go b/crypto/bls12381/arithmetic_x86_adx.go deleted file mode 100644 index a40c7384eb..0000000000 --- a/crypto/bls12381/arithmetic_x86_adx.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build amd64 && blsadx -// +build amd64,blsadx - -package bls12381 - -// enableADX is true if the ADX/BMI2 instruction set was requested for the BLS -// implementation. The system may still fall back to plain ASM if the necessary -// instructions are unavailable on the CPU. -const enableADX = true diff --git a/crypto/bls12381/arithmetic_x86_noadx.go b/crypto/bls12381/arithmetic_x86_noadx.go deleted file mode 100644 index 679b30ec8c..0000000000 --- a/crypto/bls12381/arithmetic_x86_noadx.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build amd64 && blsasm -// +build amd64,blsasm - -package bls12381 - -// enableADX is true if the ADX/BMI2 instruction set was requested for the BLS -// implementation. The system may still fall back to plain ASM if the necessary -// instructions are unavailable on the CPU. -const enableADX = false diff --git a/crypto/bls12381/bls12_381.go b/crypto/bls12381/bls12_381.go deleted file mode 100644 index 1c1c97765f..0000000000 --- a/crypto/bls12381/bls12_381.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -/* - Field Constants -*/ - -// Base field modulus -// p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab - -// Size of six words -// r = 2 ^ 384 - -// modulus = p -var modulus = fe{0xb9feffffffffaaab, 0x1eabfffeb153ffff, 0x6730d2a0f6b0f624, 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a} - -var ( - // -p^(-1) mod 2^64 - inp uint64 = 0x89f3fffcfffcfffd - // This value is used in assembly code - _ = inp -) - -// r mod p -var r1 = &fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493} - -// r^2 mod p -var r2 = &fe{ - 0xf4df1f341c341746, 0x0a76e6a609d104f1, 0x8de5476c4c95b6d5, 0x67eb88a9939d83c0, 0x9a793e85b519952d, 0x11988fe592cae3aa, -} - -// -1 + 0 * u -var negativeOne2 = &fe2{ - fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, -} - -// 2 ^ (-1) -var twoInv = &fe{0x1804000000015554, 0x855000053ab00001, 0x633cb57c253c276f, 0x6e22d1ec31ebb502, 0xd3916126f2d14ca2, 0x17fbb8571a006596} - -// (p - 3) / 4 -var pMinus3Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaaa") - -// (p + 1) / 4 -var pPlus1Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab") - -// (p - 1) / 2 -var pMinus1Over2 = bigFromHex("0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd555") - -// -1 -var nonResidue1 = &fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206} - -// (1 + 1 * u) -var nonResidue2 = &fe2{ - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, -} - -/* - Curve Constants -*/ - -// b coefficient for G1 -var b = &fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e} - -// b coefficient for G2 -var b2 = &fe2{ - fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e}, - fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e}, -} - -// Curve order -var q = bigFromHex("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") - -// Efficient cofactor of G1 -var cofactorEFFG1 = bigFromHex("0xd201000000010001") - -// Efficient cofactor of G2 -var cofactorEFFG2 = bigFromHex("0x0bc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551") - -var g1One = PointG1{ - fe{0x5cb38790fd530c16, 0x7817fc679976fff5, 0x154f95c7143ba1c1, 0xf0ae6acdf3d0e747, 0xedce6ecc21dbf440, 0x120177419e0bfb75}, - fe{0xbaac93d50ce72271, 0x8c22631a7918fd8e, 0xdd595f13570725ce, 0x51ac582950405194, 0x0e1c8c3fad0059c0, 0x0bbc3efc5008a26a}, - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, -} - -var g2One = PointG2{ - fe2{ - fe{0xf5f28fa202940a10, 0xb3f5fb2687b4961a, 0xa1a893b53e2ae580, 0x9894999d1a3caee9, 0x6f67b7631863366b, 0x058191924350bcd7}, - fe{0xa5a9c0759e23f606, 0xaaa0c59dbccd60c3, 0x3bb17e18e2867806, 0x1b1ab6cc8541b367, 0xc2b6ed0ef2158547, 0x11922a097360edf3}, - }, - fe2{ - fe{0x4c730af860494c4a, 0x597cfa1f5e369c5a, 0xe7e6856caa0a635a, 0xbbefb5e96e0d495f, 0x07d3a975f0ef25a2, 0x083fd8e7e80dae5}, - fe{0xadc0fc92df64b05d, 0x18aa270a2b1461dc, 0x86adac6a3be4eba0, 0x79495c4ec93da33a, 0xe7175850a43ccaed, 0xb2bc2a163de1bf2}, - }, - fe2{ - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, -} - -/* - Frobenious Coeffs -*/ - -var frobeniusCoeffs61 = [6]fe2{ - { - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741}, - }, - { - fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - }, - { - fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160}, - }, -} - -var frobeniusCoeffs62 = [6]fe2{ - { - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, -} - -var frobeniusCoeffs12 = [12]fe2{ - { - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb}, - fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf}, - }, - { - fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8}, - fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2}, - }, - { - fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd}, - fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd}, - }, - { - fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf}, - fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb}, - }, - { - fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2}, - fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8}, - }, - { - fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a}, - fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, - }, - { - fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd}, - fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd}, - }, -} - -/* - x -*/ - -var x = bigFromHex("0xd201000000010000") diff --git a/crypto/bls12381/bls12_381_test.go b/crypto/bls12381/bls12_381_test.go deleted file mode 100644 index 6bf5834105..0000000000 --- a/crypto/bls12381/bls12_381_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package bls12381 - -import ( - "crypto/rand" - "math/big" -) - -var fuz = 10 - -func randScalar(max *big.Int) *big.Int { - a, _ := rand.Int(rand.Reader, max) - return a -} diff --git a/crypto/bls12381/field_element.go b/crypto/bls12381/field_element.go deleted file mode 100644 index 9fdddc6184..0000000000 --- a/crypto/bls12381/field_element.go +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "io" - "math/big" -) - -// fe is base field element representation -type fe [6]uint64 - -// fe2 is element representation of 'fp2' which is quadratic extension of base field 'fp' -// Representation follows c[0] + c[1] * u encoding order. -type fe2 [2]fe - -// fe6 is element representation of 'fp6' field which is cubic extension of 'fp2' -// Representation follows c[0] + c[1] * v + c[2] * v^2 encoding order. -type fe6 [3]fe2 - -// fe12 is element representation of 'fp12' field which is quadratic extension of 'fp6' -// Representation follows c[0] + c[1] * w encoding order. -type fe12 [2]fe6 - -func (fe *fe) setBytes(in []byte) *fe { - size := 48 - l := len(in) - if l >= size { - l = size - } - padded := make([]byte, size) - copy(padded[size-l:], in[:]) - var a int - for i := 0; i < 6; i++ { - a = size - i*8 - fe[i] = uint64(padded[a-1]) | uint64(padded[a-2])<<8 | - uint64(padded[a-3])<<16 | uint64(padded[a-4])<<24 | - uint64(padded[a-5])<<32 | uint64(padded[a-6])<<40 | - uint64(padded[a-7])<<48 | uint64(padded[a-8])<<56 - } - return fe -} - -func (fe *fe) setBig(a *big.Int) *fe { - return fe.setBytes(a.Bytes()) -} - -func (fe *fe) setString(s string) (*fe, error) { - if s[:2] == "0x" { - s = s[2:] - } - bytes, err := hex.DecodeString(s) - if err != nil { - return nil, err - } - return fe.setBytes(bytes), nil -} - -func (fe *fe) set(fe2 *fe) *fe { - fe[0] = fe2[0] - fe[1] = fe2[1] - fe[2] = fe2[2] - fe[3] = fe2[3] - fe[4] = fe2[4] - fe[5] = fe2[5] - return fe -} - -func (fe *fe) bytes() []byte { - out := make([]byte, 48) - var a int - for i := 0; i < 6; i++ { - a = 48 - i*8 - out[a-1] = byte(fe[i]) - out[a-2] = byte(fe[i] >> 8) - out[a-3] = byte(fe[i] >> 16) - out[a-4] = byte(fe[i] >> 24) - out[a-5] = byte(fe[i] >> 32) - out[a-6] = byte(fe[i] >> 40) - out[a-7] = byte(fe[i] >> 48) - out[a-8] = byte(fe[i] >> 56) - } - return out -} - -func (fe *fe) big() *big.Int { - return new(big.Int).SetBytes(fe.bytes()) -} - -func (fe *fe) string() (s string) { - for i := 5; i >= 0; i-- { - s = fmt.Sprintf("%s%16.16x", s, fe[i]) - } - return "0x" + s -} - -func (fe *fe) zero() *fe { - fe[0] = 0 - fe[1] = 0 - fe[2] = 0 - fe[3] = 0 - fe[4] = 0 - fe[5] = 0 - return fe -} - -func (fe *fe) one() *fe { - return fe.set(r1) -} - -func (fe *fe) rand(r io.Reader) (*fe, error) { - bi, err := rand.Int(r, modulus.big()) - if err != nil { - return nil, err - } - return fe.setBig(bi), nil -} - -func (fe *fe) isValid() bool { - return fe.cmp(&modulus) < 0 -} - -func (fe *fe) isOdd() bool { - var mask uint64 = 1 - return fe[0]&mask != 0 -} - -func (fe *fe) isEven() bool { - var mask uint64 = 1 - return fe[0]&mask == 0 -} - -func (fe *fe) isZero() bool { - return (fe[5] | fe[4] | fe[3] | fe[2] | fe[1] | fe[0]) == 0 -} - -func (fe *fe) isOne() bool { - return fe.equal(r1) -} - -func (fe *fe) cmp(fe2 *fe) int { - for i := 5; i >= 0; i-- { - if fe[i] > fe2[i] { - return 1 - } else if fe[i] < fe2[i] { - return -1 - } - } - return 0 -} - -func (fe *fe) equal(fe2 *fe) bool { - return fe2[0] == fe[0] && fe2[1] == fe[1] && fe2[2] == fe[2] && fe2[3] == fe[3] && fe2[4] == fe[4] && fe2[5] == fe[5] -} - -func (e *fe) sign() bool { - r := new(fe) - fromMont(r, e) - return r[0]&1 == 0 -} - -func (fe *fe) div2(e uint64) { - fe[0] = fe[0]>>1 | fe[1]<<63 - fe[1] = fe[1]>>1 | fe[2]<<63 - fe[2] = fe[2]>>1 | fe[3]<<63 - fe[3] = fe[3]>>1 | fe[4]<<63 - fe[4] = fe[4]>>1 | fe[5]<<63 - fe[5] = fe[5]>>1 | e<<63 -} - -func (fe *fe) mul2() uint64 { - e := fe[5] >> 63 - fe[5] = fe[5]<<1 | fe[4]>>63 - fe[4] = fe[4]<<1 | fe[3]>>63 - fe[3] = fe[3]<<1 | fe[2]>>63 - fe[2] = fe[2]<<1 | fe[1]>>63 - fe[1] = fe[1]<<1 | fe[0]>>63 - fe[0] = fe[0] << 1 - return e -} - -func (e *fe2) zero() *fe2 { - e[0].zero() - e[1].zero() - return e -} - -func (e *fe2) one() *fe2 { - e[0].one() - e[1].zero() - return e -} - -func (e *fe2) set(e2 *fe2) *fe2 { - e[0].set(&e2[0]) - e[1].set(&e2[1]) - return e -} - -func (e *fe2) rand(r io.Reader) (*fe2, error) { - a0, err := new(fe).rand(r) - if err != nil { - return nil, err - } - a1, err := new(fe).rand(r) - if err != nil { - return nil, err - } - return &fe2{*a0, *a1}, nil -} - -func (e *fe2) isOne() bool { - return e[0].isOne() && e[1].isZero() -} - -func (e *fe2) isZero() bool { - return e[0].isZero() && e[1].isZero() -} - -func (e *fe2) equal(e2 *fe2) bool { - return e[0].equal(&e2[0]) && e[1].equal(&e2[1]) -} - -func (e *fe2) sign() bool { - r := new(fe) - if !e[0].isZero() { - fromMont(r, &e[0]) - return r[0]&1 == 0 - } - fromMont(r, &e[1]) - return r[0]&1 == 0 -} - -func (e *fe6) zero() *fe6 { - e[0].zero() - e[1].zero() - e[2].zero() - return e -} - -func (e *fe6) one() *fe6 { - e[0].one() - e[1].zero() - e[2].zero() - return e -} - -func (e *fe6) set(e2 *fe6) *fe6 { - e[0].set(&e2[0]) - e[1].set(&e2[1]) - e[2].set(&e2[2]) - return e -} - -func (e *fe6) rand(r io.Reader) (*fe6, error) { - a0, err := new(fe2).rand(r) - if err != nil { - return nil, err - } - a1, err := new(fe2).rand(r) - if err != nil { - return nil, err - } - a2, err := new(fe2).rand(r) - if err != nil { - return nil, err - } - return &fe6{*a0, *a1, *a2}, nil -} - -func (e *fe6) isOne() bool { - return e[0].isOne() && e[1].isZero() && e[2].isZero() -} - -func (e *fe6) isZero() bool { - return e[0].isZero() && e[1].isZero() && e[2].isZero() -} - -func (e *fe6) equal(e2 *fe6) bool { - return e[0].equal(&e2[0]) && e[1].equal(&e2[1]) && e[2].equal(&e2[2]) -} - -func (e *fe12) zero() *fe12 { - e[0].zero() - e[1].zero() - return e -} - -func (e *fe12) one() *fe12 { - e[0].one() - e[1].zero() - return e -} - -func (e *fe12) set(e2 *fe12) *fe12 { - e[0].set(&e2[0]) - e[1].set(&e2[1]) - return e -} - -func (e *fe12) rand(r io.Reader) (*fe12, error) { - a0, err := new(fe6).rand(r) - if err != nil { - return nil, err - } - a1, err := new(fe6).rand(r) - if err != nil { - return nil, err - } - return &fe12{*a0, *a1}, nil -} - -func (e *fe12) isOne() bool { - return e[0].isOne() && e[1].isZero() -} - -func (e *fe12) isZero() bool { - return e[0].isZero() && e[1].isZero() -} - -func (e *fe12) equal(e2 *fe12) bool { - return e[0].equal(&e2[0]) && e[1].equal(&e2[1]) -} diff --git a/crypto/bls12381/field_element_test.go b/crypto/bls12381/field_element_test.go deleted file mode 100644 index 70bbe5cfe5..0000000000 --- a/crypto/bls12381/field_element_test.go +++ /dev/null @@ -1,250 +0,0 @@ -package bls12381 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" -) - -func TestFieldElementValidation(t *testing.T) { - zero := new(fe).zero() - if !zero.isValid() { - t.Fatal("zero must be valid") - } - one := new(fe).one() - if !one.isValid() { - t.Fatal("one must be valid") - } - if modulus.isValid() { - t.Fatal("modulus must be invalid") - } - n := modulus.big() - n.Add(n, big.NewInt(1)) - if new(fe).setBig(n).isValid() { - t.Fatal("number greater than modulus must be invalid") - } -} - -func TestFieldElementEquality(t *testing.T) { - // fe - zero := new(fe).zero() - if !zero.equal(zero) { - t.Fatal("0 == 0") - } - one := new(fe).one() - if !one.equal(one) { - t.Fatal("1 == 1") - } - a, _ := new(fe).rand(rand.Reader) - if !a.equal(a) { - t.Fatal("a == a") - } - b := new(fe) - add(b, a, one) - if a.equal(b) { - t.Fatal("a != a + 1") - } - // fe2 - zero2 := new(fe2).zero() - if !zero2.equal(zero2) { - t.Fatal("0 == 0") - } - one2 := new(fe2).one() - if !one2.equal(one2) { - t.Fatal("1 == 1") - } - a2, _ := new(fe2).rand(rand.Reader) - if !a2.equal(a2) { - t.Fatal("a == a") - } - b2 := new(fe2) - fp2 := newFp2() - fp2.add(b2, a2, one2) - if a2.equal(b2) { - t.Fatal("a != a + 1") - } - // fe6 - zero6 := new(fe6).zero() - if !zero6.equal(zero6) { - t.Fatal("0 == 0") - } - one6 := new(fe6).one() - if !one6.equal(one6) { - t.Fatal("1 == 1") - } - a6, _ := new(fe6).rand(rand.Reader) - if !a6.equal(a6) { - t.Fatal("a == a") - } - b6 := new(fe6) - fp6 := newFp6(fp2) - fp6.add(b6, a6, one6) - if a6.equal(b6) { - t.Fatal("a != a + 1") - } - // fe12 - zero12 := new(fe12).zero() - if !zero12.equal(zero12) { - t.Fatal("0 == 0") - } - one12 := new(fe12).one() - if !one12.equal(one12) { - t.Fatal("1 == 1") - } - a12, _ := new(fe12).rand(rand.Reader) - if !a12.equal(a12) { - t.Fatal("a == a") - } - b12 := new(fe12) - fp12 := newFp12(fp6) - fp12.add(b12, a12, one12) - if a12.equal(b12) { - t.Fatal("a != a + 1") - } -} - -func TestFieldElementHelpers(t *testing.T) { - // fe - zero := new(fe).zero() - if !zero.isZero() { - t.Fatal("'zero' is not zero") - } - one := new(fe).one() - if !one.isOne() { - t.Fatal("'one' is not one") - } - odd := new(fe).setBig(big.NewInt(1)) - if !odd.isOdd() { - t.Fatal("1 must be odd") - } - if odd.isEven() { - t.Fatal("1 must not be even") - } - even := new(fe).setBig(big.NewInt(2)) - if !even.isEven() { - t.Fatal("2 must be even") - } - if even.isOdd() { - t.Fatal("2 must not be odd") - } - // fe2 - zero2 := new(fe2).zero() - if !zero2.isZero() { - t.Fatal("'zero' is not zero, 2") - } - one2 := new(fe2).one() - if !one2.isOne() { - t.Fatal("'one' is not one, 2") - } - // fe6 - zero6 := new(fe6).zero() - if !zero6.isZero() { - t.Fatal("'zero' is not zero, 6") - } - one6 := new(fe6).one() - if !one6.isOne() { - t.Fatal("'one' is not one, 6") - } - // fe12 - zero12 := new(fe12).zero() - if !zero12.isZero() { - t.Fatal("'zero' is not zero, 12") - } - one12 := new(fe12).one() - if !one12.isOne() { - t.Fatal("'one' is not one, 12") - } -} - -func TestFieldElementSerialization(t *testing.T) { - t.Run("zero", func(t *testing.T) { - in := make([]byte, 48) - fe := new(fe).setBytes(in) - if !fe.isZero() { - t.Fatal("bad serialization") - } - if !bytes.Equal(in, fe.bytes()) { - t.Fatal("bad serialization") - } - }) - t.Run("bytes", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b := new(fe).setBytes(a.bytes()) - if !a.equal(b) { - t.Fatal("bad serialization") - } - } - }) - t.Run("big", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b := new(fe).setBig(a.big()) - if !a.equal(b) { - t.Fatal("bad encoding or decoding") - } - } - }) - t.Run("string", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, err := new(fe).setString(a.string()) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad encoding or decoding") - } - } - }) -} - -func TestFieldElementByteInputs(t *testing.T) { - zero := new(fe).zero() - in := make([]byte, 0) - a := new(fe).setBytes(in) - if !a.equal(zero) { - t.Fatal("bad serialization") - } - in = make([]byte, 48) - a = new(fe).setBytes(in) - if !a.equal(zero) { - t.Fatal("bad serialization") - } - in = make([]byte, 64) - a = new(fe).setBytes(in) - if !a.equal(zero) { - t.Fatal("bad serialization") - } - in = make([]byte, 49) - in[47] = 1 - normalOne := &fe{1, 0, 0, 0, 0, 0} - a = new(fe).setBytes(in) - if !a.equal(normalOne) { - t.Fatal("bad serialization") - } -} - -func TestFieldElementCopy(t *testing.T) { - a, _ := new(fe).rand(rand.Reader) - b := new(fe).set(a) - if !a.equal(b) { - t.Fatal("bad copy, 1") - } - a2, _ := new(fe2).rand(rand.Reader) - b2 := new(fe2).set(a2) - if !a2.equal(b2) { - t.Fatal("bad copy, 2") - } - a6, _ := new(fe6).rand(rand.Reader) - b6 := new(fe6).set(a6) - if !a6.equal(b6) { - t.Fatal("bad copy, 6") - } - a12, _ := new(fe12).rand(rand.Reader) - b12 := new(fe12).set(a12) - if !a12.equal(b12) { - t.Fatal("bad copy, 12") - } -} diff --git a/crypto/bls12381/fp.go b/crypto/bls12381/fp.go deleted file mode 100644 index 09f6f49bc0..0000000000 --- a/crypto/bls12381/fp.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math/big" -) - -func fromBytes(in []byte) (*fe, error) { - fe := &fe{} - if len(in) != 48 { - return nil, errors.New("input string should be equal 48 bytes") - } - fe.setBytes(in) - if !fe.isValid() { - return nil, errors.New("must be less than modulus") - } - toMont(fe, fe) - return fe, nil -} - -func fromBig(in *big.Int) (*fe, error) { - fe := new(fe).setBig(in) - if !fe.isValid() { - return nil, errors.New("invalid input string") - } - toMont(fe, fe) - return fe, nil -} - -func fromString(in string) (*fe, error) { - fe, err := new(fe).setString(in) - if err != nil { - return nil, err - } - if !fe.isValid() { - return nil, errors.New("invalid input string") - } - toMont(fe, fe) - return fe, nil -} - -func toBytes(e *fe) []byte { - e2 := new(fe) - fromMont(e2, e) - return e2.bytes() -} - -func toBig(e *fe) *big.Int { - e2 := new(fe) - fromMont(e2, e) - return e2.big() -} - -func toString(e *fe) (s string) { - e2 := new(fe) - fromMont(e2, e) - return e2.string() -} - -func toMont(c, a *fe) { - mul(c, a, r2) -} - -func fromMont(c, a *fe) { - mul(c, a, &fe{1}) -} - -func exp(c, a *fe, e *big.Int) { - z := new(fe).set(r1) - for i := e.BitLen(); i >= 0; i-- { - mul(z, z, z) - if e.Bit(i) == 1 { - mul(z, z, a) - } - } - c.set(z) -} - -func inverse(inv, e *fe) { - if e.isZero() { - inv.zero() - return - } - u := new(fe).set(&modulus) - v := new(fe).set(e) - s := &fe{1} - r := &fe{0} - var k int - var z uint64 - var found = false - // Phase 1 - for i := 0; i < 768; i++ { - if v.isZero() { - found = true - break - } - if u.isEven() { - u.div2(0) - s.mul2() - } else if v.isEven() { - v.div2(0) - z += r.mul2() - } else if u.cmp(v) == 1 { - lsubAssign(u, v) - u.div2(0) - laddAssign(r, s) - s.mul2() - } else { - lsubAssign(v, u) - v.div2(0) - laddAssign(s, r) - z += r.mul2() - } - k += 1 - } - - if !found { - inv.zero() - return - } - - if k < 381 || k > 381+384 { - inv.zero() - return - } - - if r.cmp(&modulus) != -1 || z > 0 { - lsubAssign(r, &modulus) - } - u.set(&modulus) - lsubAssign(u, r) - - // Phase 2 - for i := k; i < 384*2; i++ { - double(u, u) - } - inv.set(u) -} - -func sqrt(c, a *fe) bool { - u, v := new(fe).set(a), new(fe) - exp(c, a, pPlus1Over4) - square(v, c) - return u.equal(v) -} - -func isQuadraticNonResidue(elem *fe) bool { - result := new(fe) - exp(result, elem, pMinus1Over2) - return !result.isOne() -} diff --git a/crypto/bls12381/fp12.go b/crypto/bls12381/fp12.go deleted file mode 100644 index 51e949fe5f..0000000000 --- a/crypto/bls12381/fp12.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math/big" -) - -type fp12 struct { - fp12temp - fp6 *fp6 -} - -type fp12temp struct { - t2 [9]*fe2 - t6 [5]*fe6 - t12 *fe12 -} - -func newFp12Temp() fp12temp { - t2 := [9]*fe2{} - t6 := [5]*fe6{} - for i := 0; i < len(t2); i++ { - t2[i] = &fe2{} - } - for i := 0; i < len(t6); i++ { - t6[i] = &fe6{} - } - return fp12temp{t2, t6, &fe12{}} -} - -func newFp12(fp6 *fp6) *fp12 { - t := newFp12Temp() - if fp6 == nil { - return &fp12{t, newFp6(nil)} - } - return &fp12{t, fp6} -} - -func (e *fp12) fp2() *fp2 { - return e.fp6.fp2 -} - -func (e *fp12) fromBytes(in []byte) (*fe12, error) { - if len(in) != 576 { - return nil, errors.New("input string should be larger than 96 bytes") - } - fp6 := e.fp6 - c1, err := fp6.fromBytes(in[:288]) - if err != nil { - return nil, err - } - c0, err := fp6.fromBytes(in[288:]) - if err != nil { - return nil, err - } - return &fe12{*c0, *c1}, nil -} - -func (e *fp12) toBytes(a *fe12) []byte { - fp6 := e.fp6 - out := make([]byte, 576) - copy(out[:288], fp6.toBytes(&a[1])) - copy(out[288:], fp6.toBytes(&a[0])) - return out -} - -func (e *fp12) new() *fe12 { - return new(fe12) -} - -func (e *fp12) zero() *fe12 { - return new(fe12) -} - -func (e *fp12) one() *fe12 { - return new(fe12).one() -} - -func (e *fp12) add(c, a, b *fe12) { - fp6 := e.fp6 - fp6.add(&c[0], &a[0], &b[0]) - fp6.add(&c[1], &a[1], &b[1]) -} - -func (e *fp12) double(c, a *fe12) { - fp6 := e.fp6 - fp6.double(&c[0], &a[0]) - fp6.double(&c[1], &a[1]) -} - -func (e *fp12) sub(c, a, b *fe12) { - fp6 := e.fp6 - fp6.sub(&c[0], &a[0], &b[0]) - fp6.sub(&c[1], &a[1], &b[1]) -} - -func (e *fp12) neg(c, a *fe12) { - fp6 := e.fp6 - fp6.neg(&c[0], &a[0]) - fp6.neg(&c[1], &a[1]) -} - -func (e *fp12) conjugate(c, a *fe12) { - fp6 := e.fp6 - c[0].set(&a[0]) - fp6.neg(&c[1], &a[1]) -} - -func (e *fp12) square(c, a *fe12) { - fp6, t := e.fp6, e.t6 - fp6.add(t[0], &a[0], &a[1]) - fp6.mul(t[2], &a[0], &a[1]) - fp6.mulByNonResidue(t[1], &a[1]) - fp6.addAssign(t[1], &a[0]) - fp6.mulByNonResidue(t[3], t[2]) - fp6.mulAssign(t[0], t[1]) - fp6.subAssign(t[0], t[2]) - fp6.sub(&c[0], t[0], t[3]) - fp6.double(&c[1], t[2]) -} - -func (e *fp12) cyclotomicSquare(c, a *fe12) { - t, fp2 := e.t2, e.fp2() - e.fp4Square(t[3], t[4], &a[0][0], &a[1][1]) - fp2.sub(t[2], t[3], &a[0][0]) - fp2.doubleAssign(t[2]) - fp2.add(&c[0][0], t[2], t[3]) - fp2.add(t[2], t[4], &a[1][1]) - fp2.doubleAssign(t[2]) - fp2.add(&c[1][1], t[2], t[4]) - e.fp4Square(t[3], t[4], &a[1][0], &a[0][2]) - e.fp4Square(t[5], t[6], &a[0][1], &a[1][2]) - fp2.sub(t[2], t[3], &a[0][1]) - fp2.doubleAssign(t[2]) - fp2.add(&c[0][1], t[2], t[3]) - fp2.add(t[2], t[4], &a[1][2]) - fp2.doubleAssign(t[2]) - fp2.add(&c[1][2], t[2], t[4]) - fp2.mulByNonResidue(t[3], t[6]) - fp2.add(t[2], t[3], &a[1][0]) - fp2.doubleAssign(t[2]) - fp2.add(&c[1][0], t[2], t[3]) - fp2.sub(t[2], t[5], &a[0][2]) - fp2.doubleAssign(t[2]) - fp2.add(&c[0][2], t[2], t[5]) -} - -func (e *fp12) mul(c, a, b *fe12) { - t, fp6 := e.t6, e.fp6 - fp6.mul(t[1], &a[0], &b[0]) - fp6.mul(t[2], &a[1], &b[1]) - fp6.add(t[0], t[1], t[2]) - fp6.mulByNonResidue(t[2], t[2]) - fp6.add(t[3], t[1], t[2]) - fp6.add(t[1], &a[0], &a[1]) - fp6.add(t[2], &b[0], &b[1]) - fp6.mulAssign(t[1], t[2]) - c[0].set(t[3]) - fp6.sub(&c[1], t[1], t[0]) -} - -func (e *fp12) mulAssign(a, b *fe12) { - t, fp6 := e.t6, e.fp6 - fp6.mul(t[1], &a[0], &b[0]) - fp6.mul(t[2], &a[1], &b[1]) - fp6.add(t[0], t[1], t[2]) - fp6.mulByNonResidue(t[2], t[2]) - fp6.add(t[3], t[1], t[2]) - fp6.add(t[1], &a[0], &a[1]) - fp6.add(t[2], &b[0], &b[1]) - fp6.mulAssign(t[1], t[2]) - a[0].set(t[3]) - fp6.sub(&a[1], t[1], t[0]) -} - -func (e *fp12) fp4Square(c0, c1, a0, a1 *fe2) { - t, fp2 := e.t2, e.fp2() - fp2.square(t[0], a0) - fp2.square(t[1], a1) - fp2.mulByNonResidue(t[2], t[1]) - fp2.add(c0, t[2], t[0]) - fp2.add(t[2], a0, a1) - fp2.squareAssign(t[2]) - fp2.subAssign(t[2], t[0]) - fp2.sub(c1, t[2], t[1]) -} - -func (e *fp12) inverse(c, a *fe12) { - fp6, t := e.fp6, e.t6 - fp6.square(t[0], &a[0]) - fp6.square(t[1], &a[1]) - fp6.mulByNonResidue(t[1], t[1]) - fp6.sub(t[1], t[0], t[1]) - fp6.inverse(t[0], t[1]) - fp6.mul(&c[0], &a[0], t[0]) - fp6.mulAssign(t[0], &a[1]) - fp6.neg(&c[1], t[0]) -} - -func (e *fp12) mulBy014Assign(a *fe12, c0, c1, c4 *fe2) { - fp2, fp6, t, t2 := e.fp2(), e.fp6, e.t6, e.t2[0] - fp6.mulBy01(t[0], &a[0], c0, c1) - fp6.mulBy1(t[1], &a[1], c4) - fp2.add(t2, c1, c4) - fp6.add(t[2], &a[1], &a[0]) - fp6.mulBy01Assign(t[2], c0, t2) - fp6.subAssign(t[2], t[0]) - fp6.sub(&a[1], t[2], t[1]) - fp6.mulByNonResidue(t[1], t[1]) - fp6.add(&a[0], t[1], t[0]) -} - -func (e *fp12) exp(c, a *fe12, s *big.Int) { - z := e.one() - for i := s.BitLen() - 1; i >= 0; i-- { - e.square(z, z) - if s.Bit(i) == 1 { - e.mul(z, z, a) - } - } - c.set(z) -} - -func (e *fp12) cyclotomicExp(c, a *fe12, s *big.Int) { - z := e.one() - for i := s.BitLen() - 1; i >= 0; i-- { - e.cyclotomicSquare(z, z) - if s.Bit(i) == 1 { - e.mul(z, z, a) - } - } - c.set(z) -} - -func (e *fp12) frobeniusMap(c, a *fe12, power uint) { - fp6 := e.fp6 - fp6.frobeniusMap(&c[0], &a[0], power) - fp6.frobeniusMap(&c[1], &a[1], power) - switch power { - case 0: - return - case 6: - fp6.neg(&c[1], &c[1]) - default: - fp6.mulByBaseField(&c[1], &c[1], &frobeniusCoeffs12[power]) - } -} - -func (e *fp12) frobeniusMapAssign(a *fe12, power uint) { - fp6 := e.fp6 - fp6.frobeniusMapAssign(&a[0], power) - fp6.frobeniusMapAssign(&a[1], power) - switch power { - case 0: - return - case 6: - fp6.neg(&a[1], &a[1]) - default: - fp6.mulByBaseField(&a[1], &a[1], &frobeniusCoeffs12[power]) - } -} diff --git a/crypto/bls12381/fp2.go b/crypto/bls12381/fp2.go deleted file mode 100644 index 0f1c5a23ac..0000000000 --- a/crypto/bls12381/fp2.go +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math/big" -) - -type fp2Temp struct { - t [4]*fe -} - -type fp2 struct { - fp2Temp -} - -func newFp2Temp() fp2Temp { - t := [4]*fe{} - for i := 0; i < len(t); i++ { - t[i] = &fe{} - } - return fp2Temp{t} -} - -func newFp2() *fp2 { - t := newFp2Temp() - return &fp2{t} -} - -func (e *fp2) fromBytes(in []byte) (*fe2, error) { - if len(in) != 96 { - return nil, errors.New("length of input string should be 96 bytes") - } - c1, err := fromBytes(in[:48]) - if err != nil { - return nil, err - } - c0, err := fromBytes(in[48:]) - if err != nil { - return nil, err - } - return &fe2{*c0, *c1}, nil -} - -func (e *fp2) toBytes(a *fe2) []byte { - out := make([]byte, 96) - copy(out[:48], toBytes(&a[1])) - copy(out[48:], toBytes(&a[0])) - return out -} - -func (e *fp2) new() *fe2 { - return new(fe2).zero() -} - -func (e *fp2) zero() *fe2 { - return new(fe2).zero() -} - -func (e *fp2) one() *fe2 { - return new(fe2).one() -} - -func (e *fp2) add(c, a, b *fe2) { - add(&c[0], &a[0], &b[0]) - add(&c[1], &a[1], &b[1]) -} - -func (e *fp2) addAssign(a, b *fe2) { - addAssign(&a[0], &b[0]) - addAssign(&a[1], &b[1]) -} - -func (e *fp2) ladd(c, a, b *fe2) { - ladd(&c[0], &a[0], &b[0]) - ladd(&c[1], &a[1], &b[1]) -} - -func (e *fp2) double(c, a *fe2) { - double(&c[0], &a[0]) - double(&c[1], &a[1]) -} - -func (e *fp2) doubleAssign(a *fe2) { - doubleAssign(&a[0]) - doubleAssign(&a[1]) -} - -func (e *fp2) ldouble(c, a *fe2) { - ldouble(&c[0], &a[0]) - ldouble(&c[1], &a[1]) -} - -func (e *fp2) sub(c, a, b *fe2) { - sub(&c[0], &a[0], &b[0]) - sub(&c[1], &a[1], &b[1]) -} - -func (e *fp2) subAssign(c, a *fe2) { - subAssign(&c[0], &a[0]) - subAssign(&c[1], &a[1]) -} - -func (e *fp2) neg(c, a *fe2) { - neg(&c[0], &a[0]) - neg(&c[1], &a[1]) -} - -func (e *fp2) mul(c, a, b *fe2) { - t := e.t - mul(t[1], &a[0], &b[0]) - mul(t[2], &a[1], &b[1]) - add(t[0], &a[0], &a[1]) - add(t[3], &b[0], &b[1]) - sub(&c[0], t[1], t[2]) - addAssign(t[1], t[2]) - mul(t[0], t[0], t[3]) - sub(&c[1], t[0], t[1]) -} - -func (e *fp2) mulAssign(a, b *fe2) { - t := e.t - mul(t[1], &a[0], &b[0]) - mul(t[2], &a[1], &b[1]) - add(t[0], &a[0], &a[1]) - add(t[3], &b[0], &b[1]) - sub(&a[0], t[1], t[2]) - addAssign(t[1], t[2]) - mul(t[0], t[0], t[3]) - sub(&a[1], t[0], t[1]) -} - -func (e *fp2) square(c, a *fe2) { - t := e.t - ladd(t[0], &a[0], &a[1]) - sub(t[1], &a[0], &a[1]) - ldouble(t[2], &a[0]) - mul(&c[0], t[0], t[1]) - mul(&c[1], t[2], &a[1]) -} - -func (e *fp2) squareAssign(a *fe2) { - t := e.t - ladd(t[0], &a[0], &a[1]) - sub(t[1], &a[0], &a[1]) - ldouble(t[2], &a[0]) - mul(&a[0], t[0], t[1]) - mul(&a[1], t[2], &a[1]) -} - -func (e *fp2) mulByNonResidue(c, a *fe2) { - t := e.t - sub(t[0], &a[0], &a[1]) - add(&c[1], &a[0], &a[1]) - c[0].set(t[0]) -} - -func (e *fp2) mulByB(c, a *fe2) { - t := e.t - double(t[0], &a[0]) - double(t[1], &a[1]) - doubleAssign(t[0]) - doubleAssign(t[1]) - sub(&c[0], t[0], t[1]) - add(&c[1], t[0], t[1]) -} - -func (e *fp2) inverse(c, a *fe2) { - t := e.t - square(t[0], &a[0]) - square(t[1], &a[1]) - addAssign(t[0], t[1]) - inverse(t[0], t[0]) - mul(&c[0], &a[0], t[0]) - mul(t[0], t[0], &a[1]) - neg(&c[1], t[0]) -} - -func (e *fp2) mulByFq(c, a *fe2, b *fe) { - mul(&c[0], &a[0], b) - mul(&c[1], &a[1], b) -} - -func (e *fp2) exp(c, a *fe2, s *big.Int) { - z := e.one() - for i := s.BitLen() - 1; i >= 0; i-- { - e.square(z, z) - if s.Bit(i) == 1 { - e.mul(z, z, a) - } - } - c.set(z) -} - -func (e *fp2) frobeniusMap(c, a *fe2, power uint) { - c[0].set(&a[0]) - if power%2 == 1 { - neg(&c[1], &a[1]) - return - } - c[1].set(&a[1]) -} - -func (e *fp2) frobeniusMapAssign(a *fe2, power uint) { - if power%2 == 1 { - neg(&a[1], &a[1]) - return - } -} - -func (e *fp2) sqrt(c, a *fe2) bool { - u, x0, a1, alpha := &fe2{}, &fe2{}, &fe2{}, &fe2{} - u.set(a) - e.exp(a1, a, pMinus3Over4) - e.square(alpha, a1) - e.mul(alpha, alpha, a) - e.mul(x0, a1, a) - if alpha.equal(negativeOne2) { - neg(&c[0], &x0[1]) - c[1].set(&x0[0]) - return true - } - e.add(alpha, alpha, e.one()) - e.exp(alpha, alpha, pMinus1Over2) - e.mul(c, alpha, x0) - e.square(alpha, c) - return alpha.equal(u) -} - -func (e *fp2) isQuadraticNonResidue(a *fe2) bool { - // https://github.com/leovt/constructible/wiki/Taking-Square-Roots-in-quadratic-extension-Fields - c0, c1 := new(fe), new(fe) - square(c0, &a[0]) - square(c1, &a[1]) - add(c1, c1, c0) - return isQuadraticNonResidue(c1) -} diff --git a/crypto/bls12381/fp6.go b/crypto/bls12381/fp6.go deleted file mode 100644 index 304173baa3..0000000000 --- a/crypto/bls12381/fp6.go +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math/big" -) - -type fp6Temp struct { - t [6]*fe2 -} - -type fp6 struct { - fp2 *fp2 - fp6Temp -} - -func newFp6Temp() fp6Temp { - t := [6]*fe2{} - for i := 0; i < len(t); i++ { - t[i] = &fe2{} - } - return fp6Temp{t} -} - -func newFp6(f *fp2) *fp6 { - t := newFp6Temp() - if f == nil { - return &fp6{newFp2(), t} - } - return &fp6{f, t} -} - -func (e *fp6) fromBytes(b []byte) (*fe6, error) { - if len(b) < 288 { - return nil, errors.New("input string should be larger than 288 bytes") - } - fp2 := e.fp2 - u2, err := fp2.fromBytes(b[:96]) - if err != nil { - return nil, err - } - u1, err := fp2.fromBytes(b[96:192]) - if err != nil { - return nil, err - } - u0, err := fp2.fromBytes(b[192:]) - if err != nil { - return nil, err - } - return &fe6{*u0, *u1, *u2}, nil -} - -func (e *fp6) toBytes(a *fe6) []byte { - fp2 := e.fp2 - out := make([]byte, 288) - copy(out[:96], fp2.toBytes(&a[2])) - copy(out[96:192], fp2.toBytes(&a[1])) - copy(out[192:], fp2.toBytes(&a[0])) - return out -} - -func (e *fp6) new() *fe6 { - return new(fe6) -} - -func (e *fp6) zero() *fe6 { - return new(fe6) -} - -func (e *fp6) one() *fe6 { - return new(fe6).one() -} - -func (e *fp6) add(c, a, b *fe6) { - fp2 := e.fp2 - fp2.add(&c[0], &a[0], &b[0]) - fp2.add(&c[1], &a[1], &b[1]) - fp2.add(&c[2], &a[2], &b[2]) -} - -func (e *fp6) addAssign(a, b *fe6) { - fp2 := e.fp2 - fp2.addAssign(&a[0], &b[0]) - fp2.addAssign(&a[1], &b[1]) - fp2.addAssign(&a[2], &b[2]) -} - -func (e *fp6) double(c, a *fe6) { - fp2 := e.fp2 - fp2.double(&c[0], &a[0]) - fp2.double(&c[1], &a[1]) - fp2.double(&c[2], &a[2]) -} - -func (e *fp6) doubleAssign(a *fe6) { - fp2 := e.fp2 - fp2.doubleAssign(&a[0]) - fp2.doubleAssign(&a[1]) - fp2.doubleAssign(&a[2]) -} - -func (e *fp6) sub(c, a, b *fe6) { - fp2 := e.fp2 - fp2.sub(&c[0], &a[0], &b[0]) - fp2.sub(&c[1], &a[1], &b[1]) - fp2.sub(&c[2], &a[2], &b[2]) -} - -func (e *fp6) subAssign(a, b *fe6) { - fp2 := e.fp2 - fp2.subAssign(&a[0], &b[0]) - fp2.subAssign(&a[1], &b[1]) - fp2.subAssign(&a[2], &b[2]) -} - -func (e *fp6) neg(c, a *fe6) { - fp2 := e.fp2 - fp2.neg(&c[0], &a[0]) - fp2.neg(&c[1], &a[1]) - fp2.neg(&c[2], &a[2]) -} - -func (e *fp6) mul(c, a, b *fe6) { - fp2, t := e.fp2, e.t - fp2.mul(t[0], &a[0], &b[0]) - fp2.mul(t[1], &a[1], &b[1]) - fp2.mul(t[2], &a[2], &b[2]) - fp2.add(t[3], &a[1], &a[2]) - fp2.add(t[4], &b[1], &b[2]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[1], t[2]) - fp2.subAssign(t[3], t[4]) - fp2.mulByNonResidue(t[3], t[3]) - fp2.add(t[5], t[0], t[3]) - fp2.add(t[3], &a[0], &a[1]) - fp2.add(t[4], &b[0], &b[1]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[0], t[1]) - fp2.subAssign(t[3], t[4]) - fp2.mulByNonResidue(t[4], t[2]) - fp2.add(&c[1], t[3], t[4]) - fp2.add(t[3], &a[0], &a[2]) - fp2.add(t[4], &b[0], &b[2]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[0], t[2]) - fp2.subAssign(t[3], t[4]) - fp2.add(&c[2], t[1], t[3]) - c[0].set(t[5]) -} - -func (e *fp6) mulAssign(a, b *fe6) { - fp2, t := e.fp2, e.t - fp2.mul(t[0], &a[0], &b[0]) - fp2.mul(t[1], &a[1], &b[1]) - fp2.mul(t[2], &a[2], &b[2]) - fp2.add(t[3], &a[1], &a[2]) - fp2.add(t[4], &b[1], &b[2]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[1], t[2]) - fp2.subAssign(t[3], t[4]) - fp2.mulByNonResidue(t[3], t[3]) - fp2.add(t[5], t[0], t[3]) - fp2.add(t[3], &a[0], &a[1]) - fp2.add(t[4], &b[0], &b[1]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[0], t[1]) - fp2.subAssign(t[3], t[4]) - fp2.mulByNonResidue(t[4], t[2]) - fp2.add(&a[1], t[3], t[4]) - fp2.add(t[3], &a[0], &a[2]) - fp2.add(t[4], &b[0], &b[2]) - fp2.mulAssign(t[3], t[4]) - fp2.add(t[4], t[0], t[2]) - fp2.subAssign(t[3], t[4]) - fp2.add(&a[2], t[1], t[3]) - a[0].set(t[5]) -} - -func (e *fp6) square(c, a *fe6) { - fp2, t := e.fp2, e.t - fp2.square(t[0], &a[0]) - fp2.mul(t[1], &a[0], &a[1]) - fp2.doubleAssign(t[1]) - fp2.sub(t[2], &a[0], &a[1]) - fp2.addAssign(t[2], &a[2]) - fp2.squareAssign(t[2]) - fp2.mul(t[3], &a[1], &a[2]) - fp2.doubleAssign(t[3]) - fp2.square(t[4], &a[2]) - fp2.mulByNonResidue(t[5], t[3]) - fp2.add(&c[0], t[0], t[5]) - fp2.mulByNonResidue(t[5], t[4]) - fp2.add(&c[1], t[1], t[5]) - fp2.addAssign(t[1], t[2]) - fp2.addAssign(t[1], t[3]) - fp2.addAssign(t[0], t[4]) - fp2.sub(&c[2], t[1], t[0]) -} - -func (e *fp6) mulBy01Assign(a *fe6, b0, b1 *fe2) { - fp2, t := e.fp2, e.t - fp2.mul(t[0], &a[0], b0) - fp2.mul(t[1], &a[1], b1) - fp2.add(t[5], &a[1], &a[2]) - fp2.mul(t[2], b1, t[5]) - fp2.subAssign(t[2], t[1]) - fp2.mulByNonResidue(t[2], t[2]) - fp2.add(t[5], &a[0], &a[2]) - fp2.mul(t[3], b0, t[5]) - fp2.subAssign(t[3], t[0]) - fp2.add(&a[2], t[3], t[1]) - fp2.add(t[4], b0, b1) - fp2.add(t[5], &a[0], &a[1]) - fp2.mulAssign(t[4], t[5]) - fp2.subAssign(t[4], t[0]) - fp2.sub(&a[1], t[4], t[1]) - fp2.add(&a[0], t[2], t[0]) -} - -func (e *fp6) mulBy01(c, a *fe6, b0, b1 *fe2) { - fp2, t := e.fp2, e.t - fp2.mul(t[0], &a[0], b0) - fp2.mul(t[1], &a[1], b1) - fp2.add(t[2], &a[1], &a[2]) - fp2.mulAssign(t[2], b1) - fp2.subAssign(t[2], t[1]) - fp2.mulByNonResidue(t[2], t[2]) - fp2.add(t[3], &a[0], &a[2]) - fp2.mulAssign(t[3], b0) - fp2.subAssign(t[3], t[0]) - fp2.add(&c[2], t[3], t[1]) - fp2.add(t[4], b0, b1) - fp2.add(t[3], &a[0], &a[1]) - fp2.mulAssign(t[4], t[3]) - fp2.subAssign(t[4], t[0]) - fp2.sub(&c[1], t[4], t[1]) - fp2.add(&c[0], t[2], t[0]) -} - -func (e *fp6) mulBy1(c, a *fe6, b1 *fe2) { - fp2, t := e.fp2, e.t - fp2.mul(t[0], &a[2], b1) - fp2.mul(&c[2], &a[1], b1) - fp2.mul(&c[1], &a[0], b1) - fp2.mulByNonResidue(&c[0], t[0]) -} - -func (e *fp6) mulByNonResidue(c, a *fe6) { - fp2, t := e.fp2, e.t - t[0].set(&a[0]) - fp2.mulByNonResidue(&c[0], &a[2]) - c[2].set(&a[1]) - c[1].set(t[0]) -} - -func (e *fp6) mulByBaseField(c, a *fe6, b *fe2) { - fp2 := e.fp2 - fp2.mul(&c[0], &a[0], b) - fp2.mul(&c[1], &a[1], b) - fp2.mul(&c[2], &a[2], b) -} - -func (e *fp6) exp(c, a *fe6, s *big.Int) { - z := e.one() - for i := s.BitLen() - 1; i >= 0; i-- { - e.square(z, z) - if s.Bit(i) == 1 { - e.mul(z, z, a) - } - } - c.set(z) -} - -func (e *fp6) inverse(c, a *fe6) { - fp2, t := e.fp2, e.t - fp2.square(t[0], &a[0]) - fp2.mul(t[1], &a[1], &a[2]) - fp2.mulByNonResidue(t[1], t[1]) - fp2.subAssign(t[0], t[1]) - fp2.square(t[1], &a[1]) - fp2.mul(t[2], &a[0], &a[2]) - fp2.subAssign(t[1], t[2]) - fp2.square(t[2], &a[2]) - fp2.mulByNonResidue(t[2], t[2]) - fp2.mul(t[3], &a[0], &a[1]) - fp2.subAssign(t[2], t[3]) - fp2.mul(t[3], &a[2], t[2]) - fp2.mul(t[4], &a[1], t[1]) - fp2.addAssign(t[3], t[4]) - fp2.mulByNonResidue(t[3], t[3]) - fp2.mul(t[4], &a[0], t[0]) - fp2.addAssign(t[3], t[4]) - fp2.inverse(t[3], t[3]) - fp2.mul(&c[0], t[0], t[3]) - fp2.mul(&c[1], t[2], t[3]) - fp2.mul(&c[2], t[1], t[3]) -} - -func (e *fp6) frobeniusMap(c, a *fe6, power uint) { - fp2 := e.fp2 - fp2.frobeniusMap(&c[0], &a[0], power) - fp2.frobeniusMap(&c[1], &a[1], power) - fp2.frobeniusMap(&c[2], &a[2], power) - switch power % 6 { - case 0: - return - case 3: - neg(&c[0][0], &a[1][1]) - c[1][1].set(&a[1][0]) - fp2.neg(&a[2], &a[2]) - default: - fp2.mul(&c[1], &c[1], &frobeniusCoeffs61[power%6]) - fp2.mul(&c[2], &c[2], &frobeniusCoeffs62[power%6]) - } -} - -func (e *fp6) frobeniusMapAssign(a *fe6, power uint) { - fp2 := e.fp2 - fp2.frobeniusMapAssign(&a[0], power) - fp2.frobeniusMapAssign(&a[1], power) - fp2.frobeniusMapAssign(&a[2], power) - t := e.t - switch power % 6 { - case 0: - return - case 3: - neg(&t[0][0], &a[1][1]) - a[1][1].set(&a[1][0]) - a[1][0].set(&t[0][0]) - fp2.neg(&a[2], &a[2]) - default: - fp2.mulAssign(&a[1], &frobeniusCoeffs61[power%6]) - fp2.mulAssign(&a[2], &frobeniusCoeffs62[power%6]) - } -} diff --git a/crypto/bls12381/fp_test.go b/crypto/bls12381/fp_test.go deleted file mode 100644 index 0bad35de16..0000000000 --- a/crypto/bls12381/fp_test.go +++ /dev/null @@ -1,1411 +0,0 @@ -package bls12381 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" -) - -func TestFpSerialization(t *testing.T) { - t.Run("zero", func(t *testing.T) { - in := make([]byte, 48) - fe, err := fromBytes(in) - if err != nil { - t.Fatal(err) - } - if !fe.isZero() { - t.Fatal("bad serialization") - } - if !bytes.Equal(in, toBytes(fe)) { - t.Fatal("bad serialization") - } - }) - t.Run("bytes", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, err := fromBytes(toBytes(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad serialization") - } - } - }) - t.Run("string", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, err := fromString(toString(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad encoding or decoding") - } - } - }) - t.Run("big", func(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, err := fromBig(toBig(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad encoding or decoding") - } - } - }) -} - -func TestFpAdditionCrossAgainstBigInt(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - c := new(fe) - big_a := toBig(a) - big_b := toBig(b) - big_c := new(big.Int) - add(c, a, b) - out_1 := toBytes(c) - out_2 := padBytes(big_c.Add(big_a, big_b).Mod(big_c, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied A") - } - double(c, a) - out_1 = toBytes(c) - out_2 = padBytes(big_c.Add(big_a, big_a).Mod(big_c, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied B") - } - sub(c, a, b) - out_1 = toBytes(c) - out_2 = padBytes(big_c.Sub(big_a, big_b).Mod(big_c, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied C") - } - neg(c, a) - out_1 = toBytes(c) - out_2 = padBytes(big_c.Neg(big_a).Mod(big_c, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied D") - } - } -} - -func TestFpAdditionCrossAgainstBigIntAssigned(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - big_a, big_b := toBig(a), toBig(b) - addAssign(a, b) - out_1 := toBytes(a) - out_2 := padBytes(big_a.Add(big_a, big_b).Mod(big_a, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied A") - } - a, _ = new(fe).rand(rand.Reader) - big_a = toBig(a) - doubleAssign(a) - out_1 = toBytes(a) - out_2 = padBytes(big_a.Add(big_a, big_a).Mod(big_a, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied B") - } - a, _ = new(fe).rand(rand.Reader) - b, _ = new(fe).rand(rand.Reader) - big_a, big_b = toBig(a), toBig(b) - subAssign(a, b) - out_1 = toBytes(a) - out_2 = padBytes(big_a.Sub(big_a, big_b).Mod(big_a, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied A") - } - } -} - -func TestFpAdditionProperties(t *testing.T) { - for i := 0; i < fuz; i++ { - zero := new(fe).zero() - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - c_1, c_2 := new(fe), new(fe) - add(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a + 0 == a") - } - sub(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a - 0 == a") - } - double(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("2 * 0 == 0") - } - neg(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("-0 == 0") - } - sub(c_1, zero, a) - neg(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("0-a == -a") - } - double(c_1, a) - add(c_2, a, a) - if !c_1.equal(c_2) { - t.Fatal("2 * a == a + a") - } - add(c_1, a, b) - add(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - sub(c_1, a, b) - sub(c_2, b, a) - neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - c_x, _ := new(fe).rand(rand.Reader) - add(c_1, a, b) - add(c_1, c_1, c_x) - add(c_2, a, c_x) - add(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - sub(c_1, a, b) - sub(c_1, c_1, c_x) - sub(c_2, a, c_x) - sub(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a - b) - c == (a - c ) -b") - } - } -} - -func TestFpAdditionPropertiesAssigned(t *testing.T) { - for i := 0; i < fuz; i++ { - zero := new(fe).zero() - a, b := new(fe), new(fe) - _, _ = a.rand(rand.Reader) - b.set(a) - addAssign(a, zero) - if !a.equal(b) { - t.Fatal("a + 0 == a") - } - subAssign(a, zero) - if !a.equal(b) { - t.Fatal("a - 0 == a") - } - a.set(zero) - doubleAssign(a) - if !a.equal(zero) { - t.Fatal("2 * 0 == 0") - } - a.set(zero) - subAssign(a, b) - neg(b, b) - if !a.equal(b) { - t.Fatal("0-a == -a") - } - _, _ = a.rand(rand.Reader) - b.set(a) - doubleAssign(a) - addAssign(b, b) - if !a.equal(b) { - t.Fatal("2 * a == a + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1, c_2 := new(fe).set(a), new(fe).set(b) - addAssign(c_1, b) - addAssign(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1.set(a) - c_2.set(b) - subAssign(c_1, b) - subAssign(c_2, a) - neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c, _ := new(fe).rand(rand.Reader) - a0 := new(fe).set(a) - addAssign(a, b) - addAssign(a, c) - addAssign(b, c) - addAssign(b, a0) - if !a.equal(b) { - t.Fatal("(a + b) + c == (b + c) + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - _, _ = c.rand(rand.Reader) - a0.set(a) - subAssign(a, b) - subAssign(a, c) - subAssign(a0, c) - subAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a - b) - c == (a - c) -b") - } - } -} - -func TestFpLazyOperations(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - c, _ := new(fe).rand(rand.Reader) - c0 := new(fe) - c1 := new(fe) - ladd(c0, a, b) - add(c1, a, b) - mul(c0, c0, c) - mul(c1, c1, c) - if !c0.equal(c1) { - // l+ operator stands for lazy addition - t.Fatal("(a + b) * c == (a l+ b) * c") - } - _, _ = a.rand(rand.Reader) - b.set(a) - ldouble(a, a) - ladd(b, b, b) - if !a.equal(b) { - t.Fatal("2 l* a = a l+ a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - _, _ = c.rand(rand.Reader) - a0 := new(fe).set(a) - lsubAssign(a, b) - laddAssign(a, &modulus) - mul(a, a, c) - subAssign(a0, b) - mul(a0, a0, c) - if !a.equal(a0) { - t.Fatal("((a l- b) + p) * c = (a-b) * c") - } - } -} - -func TestFpMultiplicationCrossAgainstBigInt(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - c := new(fe) - big_a := toBig(a) - big_b := toBig(b) - big_c := new(big.Int) - mul(c, a, b) - out_1 := toBytes(c) - out_2 := padBytes(big_c.Mul(big_a, big_b).Mod(big_c, modulus.big()).Bytes(), 48) - if !bytes.Equal(out_1, out_2) { - t.Fatal("cross test against big.Int is not satisfied") - } - } -} - -func TestFpMultiplicationProperties(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - zero, one := new(fe).zero(), new(fe).one() - c_1, c_2 := new(fe), new(fe) - mul(c_1, a, zero) - if !c_1.equal(zero) { - t.Fatal("a * 0 == 0") - } - mul(c_1, a, one) - if !c_1.equal(a) { - t.Fatal("a * 1 == a") - } - mul(c_1, a, b) - mul(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a * b == b * a") - } - c_x, _ := new(fe).rand(rand.Reader) - mul(c_1, a, b) - mul(c_1, c_1, c_x) - mul(c_2, c_x, b) - mul(c_2, c_2, a) - if !c_1.equal(c_2) { - t.Fatal("(a * b) * c == (a * c) * b") - } - square(a, zero) - if !a.equal(zero) { - t.Fatal("0^2 == 0") - } - square(a, one) - if !a.equal(one) { - t.Fatal("1^2 == 1") - } - _, _ = a.rand(rand.Reader) - square(c_1, a) - mul(c_2, a, a) - if !c_1.equal(c_1) { - t.Fatal("a^2 == a*a") - } - } -} - -func TestFpExponentiation(t *testing.T) { - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - u := new(fe) - exp(u, a, big.NewInt(0)) - if !u.isOne() { - t.Fatal("a^0 == 1") - } - exp(u, a, big.NewInt(1)) - if !u.equal(a) { - t.Fatal("a^1 == a") - } - v := new(fe) - mul(u, a, a) - mul(u, u, u) - mul(u, u, u) - exp(v, a, big.NewInt(8)) - if !u.equal(v) { - t.Fatal("((a^2)^2)^2 == a^8") - } - p := modulus.big() - exp(u, a, p) - if !u.equal(a) { - t.Fatal("a^p == a") - } - exp(u, a, p.Sub(p, big.NewInt(1))) - if !u.isOne() { - t.Fatal("a^(p-1) == 1") - } - } -} - -func TestFpInversion(t *testing.T) { - for i := 0; i < fuz; i++ { - u := new(fe) - zero, one := new(fe).zero(), new(fe).one() - inverse(u, zero) - if !u.equal(zero) { - t.Fatal("(0^-1) == 0)") - } - inverse(u, one) - if !u.equal(one) { - t.Fatal("(1^-1) == 1)") - } - a, _ := new(fe).rand(rand.Reader) - inverse(u, a) - mul(u, u, a) - if !u.equal(one) { - t.Fatal("(r*a) * r*(a^-1) == r)") - } - v := new(fe) - p := modulus.big() - exp(u, a, p.Sub(p, big.NewInt(2))) - inverse(v, a) - if !v.equal(u) { - t.Fatal("a^(p-2) == a^-1") - } - } -} - -func TestFpSquareRoot(t *testing.T) { - r := new(fe) - if sqrt(r, nonResidue1) { - t.Fatal("non residue cannot have a sqrt") - } - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - aa, rr, r := &fe{}, &fe{}, &fe{} - square(aa, a) - if !sqrt(r, aa) { - t.Fatal("bad sqrt 1") - } - square(rr, r) - if !rr.equal(aa) { - t.Fatal("bad sqrt 2") - } - } -} - -func TestFpNonResidue(t *testing.T) { - if !isQuadraticNonResidue(nonResidue1) { - t.Fatal("element is quadratic non residue, 1") - } - if isQuadraticNonResidue(new(fe).one()) { - t.Fatal("one is not quadratic non residue") - } - if !isQuadraticNonResidue(new(fe).zero()) { - t.Fatal("should accept zero as quadratic non residue") - } - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - square(a, a) - if isQuadraticNonResidue(new(fe).one()) { - t.Fatal("element is not quadratic non residue") - } - } - for i := 0; i < fuz; i++ { - a, _ := new(fe).rand(rand.Reader) - if !sqrt(new(fe), a) { - if !isQuadraticNonResidue(a) { - t.Fatal("element is quadratic non residue, 2", i) - } - } else { - i -= 1 - } - } -} - -func TestFp2Serialization(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - b, err := field.fromBytes(field.toBytes(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad serialization") - } - } -} - -func TestFp2AdditionProperties(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - zero := field.zero() - a, _ := new(fe2).rand(rand.Reader) - b, _ := new(fe2).rand(rand.Reader) - c_1 := field.new() - c_2 := field.new() - field.add(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a + 0 == a") - } - field.sub(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a - 0 == a") - } - field.double(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("2 * 0 == 0") - } - field.neg(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("-0 == 0") - } - field.sub(c_1, zero, a) - field.neg(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("0-a == -a") - } - field.double(c_1, a) - field.add(c_2, a, a) - if !c_1.equal(c_2) { - t.Fatal("2 * a == a + a") - } - field.add(c_1, a, b) - field.add(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - field.sub(c_1, a, b) - field.sub(c_2, b, a) - field.neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - c_x, _ := new(fe2).rand(rand.Reader) - field.add(c_1, a, b) - field.add(c_1, c_1, c_x) - field.add(c_2, a, c_x) - field.add(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - field.sub(c_1, a, b) - field.sub(c_1, c_1, c_x) - field.sub(c_2, a, c_x) - field.sub(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a - b) - c == (a - c ) -b") - } - } -} - -func TestFp2AdditionPropertiesAssigned(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - zero := new(fe2).zero() - a, b := new(fe2), new(fe2) - _, _ = a.rand(rand.Reader) - b.set(a) - field.addAssign(a, zero) - if !a.equal(b) { - t.Fatal("a + 0 == a") - } - field.subAssign(a, zero) - if !a.equal(b) { - t.Fatal("a - 0 == a") - } - a.set(zero) - field.doubleAssign(a) - if !a.equal(zero) { - t.Fatal("2 * 0 == 0") - } - a.set(zero) - field.subAssign(a, b) - field.neg(b, b) - if !a.equal(b) { - t.Fatal("0-a == -a") - } - _, _ = a.rand(rand.Reader) - b.set(a) - field.doubleAssign(a) - field.addAssign(b, b) - if !a.equal(b) { - t.Fatal("2 * a == a + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1, c_2 := new(fe2).set(a), new(fe2).set(b) - field.addAssign(c_1, b) - field.addAssign(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1.set(a) - c_2.set(b) - field.subAssign(c_1, b) - field.subAssign(c_2, a) - field.neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c, _ := new(fe2).rand(rand.Reader) - a0 := new(fe2).set(a) - field.addAssign(a, b) - field.addAssign(a, c) - field.addAssign(b, c) - field.addAssign(b, a0) - if !a.equal(b) { - t.Fatal("(a + b) + c == (b + c) + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - _, _ = c.rand(rand.Reader) - a0.set(a) - field.subAssign(a, b) - field.subAssign(a, c) - field.subAssign(a0, c) - field.subAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a - b) - c == (a - c) -b") - } - } -} - -func TestFp2LazyOperations(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - b, _ := new(fe2).rand(rand.Reader) - c, _ := new(fe2).rand(rand.Reader) - c0 := new(fe2) - c1 := new(fe2) - field.ladd(c0, a, b) - field.add(c1, a, b) - field.mulAssign(c0, c) - field.mulAssign(c1, c) - if !c0.equal(c1) { - // l+ operator stands for lazy addition - t.Fatal("(a + b) * c == (a l+ b) * c") - } - _, _ = a.rand(rand.Reader) - b.set(a) - field.ldouble(a, a) - field.ladd(b, b, b) - if !a.equal(b) { - t.Fatal("2 l* a = a l+ a") - } - } -} - -func TestFp2MultiplicationProperties(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - b, _ := new(fe2).rand(rand.Reader) - zero := field.zero() - one := field.one() - c_1, c_2 := field.new(), field.new() - field.mul(c_1, a, zero) - if !c_1.equal(zero) { - t.Fatal("a * 0 == 0") - } - field.mul(c_1, a, one) - if !c_1.equal(a) { - t.Fatal("a * 1 == a") - } - field.mul(c_1, a, b) - field.mul(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a * b == b * a") - } - c_x, _ := new(fe2).rand(rand.Reader) - field.mul(c_1, a, b) - field.mul(c_1, c_1, c_x) - field.mul(c_2, c_x, b) - field.mul(c_2, c_2, a) - if !c_1.equal(c_2) { - t.Fatal("(a * b) * c == (a * c) * b") - } - field.square(a, zero) - if !a.equal(zero) { - t.Fatal("0^2 == 0") - } - field.square(a, one) - if !a.equal(one) { - t.Fatal("1^2 == 1") - } - _, _ = a.rand(rand.Reader) - field.square(c_1, a) - field.mul(c_2, a, a) - if !c_2.equal(c_1) { - t.Fatal("a^2 == a*a") - } - } -} - -func TestFp2MultiplicationPropertiesAssigned(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - zero, one := new(fe2).zero(), new(fe2).one() - field.mulAssign(a, zero) - if !a.equal(zero) { - t.Fatal("a * 0 == 0") - } - _, _ = a.rand(rand.Reader) - a0 := new(fe2).set(a) - field.mulAssign(a, one) - if !a.equal(a0) { - t.Fatal("a * 1 == a") - } - _, _ = a.rand(rand.Reader) - b, _ := new(fe2).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(b, a0) - if !a.equal(b) { - t.Fatal("a * b == b * a") - } - c, _ := new(fe2).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(a, c) - field.mulAssign(a0, c) - field.mulAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a * b) * c == (a * c) * b") - } - a0.set(a) - field.squareAssign(a) - field.mulAssign(a0, a0) - if !a.equal(a0) { - t.Fatal("a^2 == a*a") - } - } -} - -func TestFp2Exponentiation(t *testing.T) { - field := newFp2() - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - u := field.new() - field.exp(u, a, big.NewInt(0)) - if !u.equal(field.one()) { - t.Fatal("a^0 == 1") - } - field.exp(u, a, big.NewInt(1)) - if !u.equal(a) { - t.Fatal("a^1 == a") - } - v := field.new() - field.mul(u, a, a) - field.mul(u, u, u) - field.mul(u, u, u) - field.exp(v, a, big.NewInt(8)) - if !u.equal(v) { - t.Fatal("((a^2)^2)^2 == a^8") - } - } -} - -func TestFp2Inversion(t *testing.T) { - field := newFp2() - u := field.new() - zero := field.zero() - one := field.one() - field.inverse(u, zero) - if !u.equal(zero) { - t.Fatal("(0 ^ -1) == 0)") - } - field.inverse(u, one) - if !u.equal(one) { - t.Fatal("(1 ^ -1) == 1)") - } - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - field.inverse(u, a) - field.mul(u, u, a) - if !u.equal(one) { - t.Fatal("(r * a) * r * (a ^ -1) == r)") - } - } -} - -func TestFp2SquareRoot(t *testing.T) { - field := newFp2() - for z := 0; z < 1000; z++ { - zi := new(fe) - sub(zi, &modulus, &fe{uint64(z * z)}) - // r = (-z*z, 0) - r := &fe2{*zi, fe{0}} - toMont(&r[0], &r[0]) - toMont(&r[1], &r[1]) - c := field.new() - // sqrt((-z*z, 0)) = (0, z) - if !field.sqrt(c, r) { - t.Fatal("z*z does have a square root") - } - e := &fe2{fe{uint64(0)}, fe{uint64(z)}} - toMont(&e[0], &e[0]) - toMont(&e[1], &e[1]) - field.square(e, e) - field.square(c, c) - if !e.equal(c) { - t.Fatal("square root failed") - } - } - if field.sqrt(field.new(), nonResidue2) { - t.Fatal("non residue cannot have a sqrt") - } - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - aa, rr, r := field.new(), field.new(), field.new() - field.square(aa, a) - if !field.sqrt(r, aa) { - t.Fatal("bad sqrt 1") - } - field.square(rr, r) - if !rr.equal(aa) { - t.Fatal("bad sqrt 2") - } - } -} - -func TestFp2NonResidue(t *testing.T) { - field := newFp2() - if !field.isQuadraticNonResidue(nonResidue2) { - t.Fatal("element is quadratic non residue, 1") - } - if field.isQuadraticNonResidue(new(fe2).one()) { - t.Fatal("one is not quadratic non residue") - } - if !field.isQuadraticNonResidue(new(fe2).zero()) { - t.Fatal("should accept zero as quadratic non residue") - } - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - field.squareAssign(a) - if field.isQuadraticNonResidue(new(fe2).one()) { - t.Fatal("element is not quadratic non residue") - } - } - for i := 0; i < fuz; i++ { - a, _ := new(fe2).rand(rand.Reader) - if !field.sqrt(new(fe2), a) { - if !field.isQuadraticNonResidue(a) { - t.Fatal("element is quadratic non residue, 2", i) - } - } else { - i -= 1 - } - } -} - -func TestFp6Serialization(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe6).rand(rand.Reader) - b, err := field.fromBytes(field.toBytes(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad serialization") - } - } -} - -func TestFp6AdditionProperties(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - zero := field.zero() - a, _ := new(fe6).rand(rand.Reader) - b, _ := new(fe6).rand(rand.Reader) - c_1 := field.new() - c_2 := field.new() - field.add(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a + 0 == a") - } - field.sub(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a - 0 == a") - } - field.double(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("2 * 0 == 0") - } - field.neg(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("-0 == 0") - } - field.sub(c_1, zero, a) - field.neg(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("0-a == -a") - } - field.double(c_1, a) - field.add(c_2, a, a) - if !c_1.equal(c_2) { - t.Fatal("2 * a == a + a") - } - field.add(c_1, a, b) - field.add(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - field.sub(c_1, a, b) - field.sub(c_2, b, a) - field.neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - c_x, _ := new(fe6).rand(rand.Reader) - field.add(c_1, a, b) - field.add(c_1, c_1, c_x) - field.add(c_2, a, c_x) - field.add(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - field.sub(c_1, a, b) - field.sub(c_1, c_1, c_x) - field.sub(c_2, a, c_x) - field.sub(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a - b) - c == (a - c ) -b") - } - } -} - -func TestFp6AdditionPropertiesAssigned(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - zero := new(fe6).zero() - a, b := new(fe6), new(fe6) - _, _ = a.rand(rand.Reader) - b.set(a) - field.addAssign(a, zero) - if !a.equal(b) { - t.Fatal("a + 0 == a") - } - field.subAssign(a, zero) - if !a.equal(b) { - t.Fatal("a - 0 == a") - } - a.set(zero) - field.doubleAssign(a) - if !a.equal(zero) { - t.Fatal("2 * 0 == 0") - } - a.set(zero) - field.subAssign(a, b) - field.neg(b, b) - if !a.equal(b) { - t.Fatal("0-a == -a") - } - _, _ = a.rand(rand.Reader) - b.set(a) - field.doubleAssign(a) - field.addAssign(b, b) - if !a.equal(b) { - t.Fatal("2 * a == a + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1, c_2 := new(fe6).set(a), new(fe6).set(b) - field.addAssign(c_1, b) - field.addAssign(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c_1.set(a) - c_2.set(b) - field.subAssign(c_1, b) - field.subAssign(c_2, a) - field.neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - c, _ := new(fe6).rand(rand.Reader) - a0 := new(fe6).set(a) - field.addAssign(a, b) - field.addAssign(a, c) - field.addAssign(b, c) - field.addAssign(b, a0) - if !a.equal(b) { - t.Fatal("(a + b) + c == (b + c) + a") - } - _, _ = a.rand(rand.Reader) - _, _ = b.rand(rand.Reader) - _, _ = c.rand(rand.Reader) - a0.set(a) - field.subAssign(a, b) - field.subAssign(a, c) - field.subAssign(a0, c) - field.subAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a - b) - c == (a - c) -b") - } - } -} - -func TestFp6SparseMultiplication(t *testing.T) { - fp6 := newFp6(nil) - var a, b, u *fe6 - for j := 0; j < fuz; j++ { - a, _ = new(fe6).rand(rand.Reader) - b, _ = new(fe6).rand(rand.Reader) - u, _ = new(fe6).rand(rand.Reader) - b[2].zero() - fp6.mul(u, a, b) - fp6.mulBy01(a, a, &b[0], &b[1]) - if !a.equal(u) { - t.Fatal("bad mul by 01") - } - } - for j := 0; j < fuz; j++ { - a, _ = new(fe6).rand(rand.Reader) - b, _ = new(fe6).rand(rand.Reader) - u, _ = new(fe6).rand(rand.Reader) - b[2].zero() - b[0].zero() - fp6.mul(u, a, b) - fp6.mulBy1(a, a, &b[1]) - if !a.equal(u) { - t.Fatal("bad mul by 1") - } - } -} - -func TestFp6MultiplicationProperties(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe6).rand(rand.Reader) - b, _ := new(fe6).rand(rand.Reader) - zero := field.zero() - one := field.one() - c_1, c_2 := field.new(), field.new() - field.mul(c_1, a, zero) - if !c_1.equal(zero) { - t.Fatal("a * 0 == 0") - } - field.mul(c_1, a, one) - if !c_1.equal(a) { - t.Fatal("a * 1 == a") - } - field.mul(c_1, a, b) - field.mul(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a * b == b * a") - } - c_x, _ := new(fe6).rand(rand.Reader) - field.mul(c_1, a, b) - field.mul(c_1, c_1, c_x) - field.mul(c_2, c_x, b) - field.mul(c_2, c_2, a) - if !c_1.equal(c_2) { - t.Fatal("(a * b) * c == (a * c) * b") - } - field.square(a, zero) - if !a.equal(zero) { - t.Fatal("0^2 == 0") - } - field.square(a, one) - if !a.equal(one) { - t.Fatal("1^2 == 1") - } - _, _ = a.rand(rand.Reader) - field.square(c_1, a) - field.mul(c_2, a, a) - if !c_2.equal(c_1) { - t.Fatal("a^2 == a*a") - } - } -} - -func TestFp6MultiplicationPropertiesAssigned(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe6).rand(rand.Reader) - zero, one := new(fe6).zero(), new(fe6).one() - field.mulAssign(a, zero) - if !a.equal(zero) { - t.Fatal("a * 0 == 0") - } - _, _ = a.rand(rand.Reader) - a0 := new(fe6).set(a) - field.mulAssign(a, one) - if !a.equal(a0) { - t.Fatal("a * 1 == a") - } - _, _ = a.rand(rand.Reader) - b, _ := new(fe6).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(b, a0) - if !a.equal(b) { - t.Fatal("a * b == b * a") - } - c, _ := new(fe6).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(a, c) - field.mulAssign(a0, c) - field.mulAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a * b) * c == (a * c) * b") - } - } -} - -func TestFp6Exponentiation(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe6).rand(rand.Reader) - u := field.new() - field.exp(u, a, big.NewInt(0)) - if !u.equal(field.one()) { - t.Fatal("a^0 == 1") - } - field.exp(u, a, big.NewInt(1)) - if !u.equal(a) { - t.Fatal("a^1 == a") - } - v := field.new() - field.mul(u, a, a) - field.mul(u, u, u) - field.mul(u, u, u) - field.exp(v, a, big.NewInt(8)) - if !u.equal(v) { - t.Fatal("((a^2)^2)^2 == a^8") - } - } -} - -func TestFp6Inversion(t *testing.T) { - field := newFp6(nil) - for i := 0; i < fuz; i++ { - u := field.new() - zero := field.zero() - one := field.one() - field.inverse(u, zero) - if !u.equal(zero) { - t.Fatal("(0^-1) == 0)") - } - field.inverse(u, one) - if !u.equal(one) { - t.Fatal("(1^-1) == 1)") - } - a, _ := new(fe6).rand(rand.Reader) - field.inverse(u, a) - field.mul(u, u, a) - if !u.equal(one) { - t.Fatal("(r*a) * r*(a^-1) == r)") - } - } -} - -func TestFp12Serialization(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe12).rand(rand.Reader) - b, err := field.fromBytes(field.toBytes(a)) - if err != nil { - t.Fatal(err) - } - if !a.equal(b) { - t.Fatal("bad serialization") - } - } -} - -func TestFp12AdditionProperties(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - zero := field.zero() - a, _ := new(fe12).rand(rand.Reader) - b, _ := new(fe12).rand(rand.Reader) - c_1 := field.new() - c_2 := field.new() - field.add(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a + 0 == a") - } - field.sub(c_1, a, zero) - if !c_1.equal(a) { - t.Fatal("a - 0 == a") - } - field.double(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("2 * 0 == 0") - } - field.neg(c_1, zero) - if !c_1.equal(zero) { - t.Fatal("-0 == 0") - } - field.sub(c_1, zero, a) - field.neg(c_2, a) - if !c_1.equal(c_2) { - t.Fatal("0-a == -a") - } - field.double(c_1, a) - field.add(c_2, a, a) - if !c_1.equal(c_2) { - t.Fatal("2 * a == a + a") - } - field.add(c_1, a, b) - field.add(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a + b = b + a") - } - field.sub(c_1, a, b) - field.sub(c_2, b, a) - field.neg(c_2, c_2) - if !c_1.equal(c_2) { - t.Fatal("a - b = - ( b - a )") - } - c_x, _ := new(fe12).rand(rand.Reader) - field.add(c_1, a, b) - field.add(c_1, c_1, c_x) - field.add(c_2, a, c_x) - field.add(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - field.sub(c_1, a, b) - field.sub(c_1, c_1, c_x) - field.sub(c_2, a, c_x) - field.sub(c_2, c_2, b) - if !c_1.equal(c_2) { - t.Fatal("(a - b) - c == (a - c ) -b") - } - } -} - -func TestFp12MultiplicationProperties(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe12).rand(rand.Reader) - b, _ := new(fe12).rand(rand.Reader) - zero := field.zero() - one := field.one() - c_1, c_2 := field.new(), field.new() - field.mul(c_1, a, zero) - if !c_1.equal(zero) { - t.Fatal("a * 0 == 0") - } - field.mul(c_1, a, one) - if !c_1.equal(a) { - t.Fatal("a * 1 == a") - } - field.mul(c_1, a, b) - field.mul(c_2, b, a) - if !c_1.equal(c_2) { - t.Fatal("a * b == b * a") - } - c_x, _ := new(fe12).rand(rand.Reader) - field.mul(c_1, a, b) - field.mul(c_1, c_1, c_x) - field.mul(c_2, c_x, b) - field.mul(c_2, c_2, a) - if !c_1.equal(c_2) { - t.Fatal("(a * b) * c == (a * c) * b") - } - field.square(a, zero) - if !a.equal(zero) { - t.Fatal("0^2 == 0") - } - field.square(a, one) - if !a.equal(one) { - t.Fatal("1^2 == 1") - } - _, _ = a.rand(rand.Reader) - field.square(c_1, a) - field.mul(c_2, a, a) - if !c_2.equal(c_1) { - t.Fatal("a^2 == a*a") - } - } -} - -func TestFp12MultiplicationPropertiesAssigned(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe12).rand(rand.Reader) - zero, one := new(fe12).zero(), new(fe12).one() - field.mulAssign(a, zero) - if !a.equal(zero) { - t.Fatal("a * 0 == 0") - } - _, _ = a.rand(rand.Reader) - a0 := new(fe12).set(a) - field.mulAssign(a, one) - if !a.equal(a0) { - t.Fatal("a * 1 == a") - } - _, _ = a.rand(rand.Reader) - b, _ := new(fe12).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(b, a0) - if !a.equal(b) { - t.Fatal("a * b == b * a") - } - c, _ := new(fe12).rand(rand.Reader) - a0.set(a) - field.mulAssign(a, b) - field.mulAssign(a, c) - field.mulAssign(a0, c) - field.mulAssign(a0, b) - if !a.equal(a0) { - t.Fatal("(a * b) * c == (a * c) * b") - } - } -} - -func TestFp12SparseMultiplication(t *testing.T) { - fp12 := newFp12(nil) - var a, b, u *fe12 - for j := 0; j < fuz; j++ { - a, _ = new(fe12).rand(rand.Reader) - b, _ = new(fe12).rand(rand.Reader) - u, _ = new(fe12).rand(rand.Reader) - b[0][2].zero() - b[1][0].zero() - b[1][2].zero() - fp12.mul(u, a, b) - fp12.mulBy014Assign(a, &b[0][0], &b[0][1], &b[1][1]) - if !a.equal(u) { - t.Fatal("bad mul by 01") - } - } -} - -func TestFp12Exponentiation(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - a, _ := new(fe12).rand(rand.Reader) - u := field.new() - field.exp(u, a, big.NewInt(0)) - if !u.equal(field.one()) { - t.Fatal("a^0 == 1") - } - field.exp(u, a, big.NewInt(1)) - if !u.equal(a) { - t.Fatal("a^1 == a") - } - v := field.new() - field.mul(u, a, a) - field.mul(u, u, u) - field.mul(u, u, u) - field.exp(v, a, big.NewInt(8)) - if !u.equal(v) { - t.Fatal("((a^2)^2)^2 == a^8") - } - } -} - -func TestFp12Inversion(t *testing.T) { - field := newFp12(nil) - for i := 0; i < fuz; i++ { - u := field.new() - zero := field.zero() - one := field.one() - field.inverse(u, zero) - if !u.equal(zero) { - t.Fatal("(0^-1) == 0)") - } - field.inverse(u, one) - if !u.equal(one) { - t.Fatal("(1^-1) == 1)") - } - a, _ := new(fe12).rand(rand.Reader) - field.inverse(u, a) - field.mul(u, u, a) - if !u.equal(one) { - t.Fatal("(r*a) * r*(a^-1) == r)") - } - } -} - -func BenchmarkMultiplication(t *testing.B) { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - c, _ := new(fe).rand(rand.Reader) - t.ResetTimer() - for i := 0; i < t.N; i++ { - mul(c, a, b) - } -} - -func BenchmarkInverse(t *testing.B) { - a, _ := new(fe).rand(rand.Reader) - b, _ := new(fe).rand(rand.Reader) - t.ResetTimer() - for i := 0; i < t.N; i++ { - inverse(a, b) - } -} - -func padBytes(in []byte, size int) []byte { - out := make([]byte, size) - if len(in) > size { - panic("bad input for padding") - } - copy(out[size-len(in):], in) - return out -} diff --git a/crypto/bls12381/g1.go b/crypto/bls12381/g1.go deleted file mode 100644 index bcb898027a..0000000000 --- a/crypto/bls12381/g1.go +++ /dev/null @@ -1,434 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math" - "math/big" -) - -// PointG1 is type for point in G1. -// PointG1 is both used for Affine and Jacobian point representation. -// If z is equal to one the point is considered as in affine form. -type PointG1 [3]fe - -func (p *PointG1) Set(p2 *PointG1) *PointG1 { - p[0].set(&p2[0]) - p[1].set(&p2[1]) - p[2].set(&p2[2]) - return p -} - -// Zero returns G1 point in point at infinity representation -func (p *PointG1) Zero() *PointG1 { - p[0].zero() - p[1].one() - p[2].zero() - return p -} - -type tempG1 struct { - t [9]*fe -} - -// G1 is struct for G1 group. -type G1 struct { - tempG1 -} - -// NewG1 constructs a new G1 instance. -func NewG1() *G1 { - t := newTempG1() - return &G1{t} -} - -func newTempG1() tempG1 { - t := [9]*fe{} - for i := 0; i < 9; i++ { - t[i] = &fe{} - } - return tempG1{t} -} - -// Q returns group order in big.Int. -func (g *G1) Q() *big.Int { - return new(big.Int).Set(q) -} - -func (g *G1) fromBytesUnchecked(in []byte) (*PointG1, error) { - p0, err := fromBytes(in[:48]) - if err != nil { - return nil, err - } - p1, err := fromBytes(in[48:]) - if err != nil { - return nil, err - } - p2 := new(fe).one() - return &PointG1{*p0, *p1, *p2}, nil -} - -// FromBytes constructs a new point given uncompressed byte input. -// FromBytes does not take zcash flags into account. -// Byte input expected to be larger than 96 bytes. -// First 96 bytes should be concatenation of x and y values. -// Point (0, 0) is considered as infinity. -func (g *G1) FromBytes(in []byte) (*PointG1, error) { - if len(in) != 96 { - return nil, errors.New("input string should be equal or larger than 96") - } - p0, err := fromBytes(in[:48]) - if err != nil { - return nil, err - } - p1, err := fromBytes(in[48:]) - if err != nil { - return nil, err - } - // check if given input points to infinity - if p0.isZero() && p1.isZero() { - return g.Zero(), nil - } - p2 := new(fe).one() - p := &PointG1{*p0, *p1, *p2} - if !g.IsOnCurve(p) { - return nil, errors.New("point is not on curve") - } - return p, nil -} - -// DecodePoint given encoded (x, y) coordinates in 128 bytes returns a valid G1 Point. -func (g *G1) DecodePoint(in []byte) (*PointG1, error) { - if len(in) != 128 { - return nil, errors.New("invalid g1 point length") - } - pointBytes := make([]byte, 96) - // decode x - xBytes, err := decodeFieldElement(in[:64]) - if err != nil { - return nil, err - } - // decode y - yBytes, err := decodeFieldElement(in[64:]) - if err != nil { - return nil, err - } - copy(pointBytes[:48], xBytes) - copy(pointBytes[48:], yBytes) - return g.FromBytes(pointBytes) -} - -// ToBytes serializes a point into bytes in uncompressed form. -// ToBytes does not take zcash flags into account. -// ToBytes returns (0, 0) if point is infinity. -func (g *G1) ToBytes(p *PointG1) []byte { - out := make([]byte, 96) - if g.IsZero(p) { - return out - } - g.Affine(p) - copy(out[:48], toBytes(&p[0])) - copy(out[48:], toBytes(&p[1])) - return out -} - -// EncodePoint encodes a point into 128 bytes. -func (g *G1) EncodePoint(p *PointG1) []byte { - outRaw := g.ToBytes(p) - out := make([]byte, 128) - // encode x - copy(out[16:], outRaw[:48]) - // encode y - copy(out[64+16:], outRaw[48:]) - return out -} - -// New creates a new G1 Point which is equal to zero in other words point at infinity. -func (g *G1) New() *PointG1 { - return g.Zero() -} - -// Zero returns a new G1 Point which is equal to point at infinity. -func (g *G1) Zero() *PointG1 { - return new(PointG1).Zero() -} - -// One returns a new G1 Point which is equal to generator point. -func (g *G1) One() *PointG1 { - p := &PointG1{} - return p.Set(&g1One) -} - -// IsZero returns true if given point is equal to zero. -func (g *G1) IsZero(p *PointG1) bool { - return p[2].isZero() -} - -// Equal checks if given two G1 point is equal in their affine form. -func (g *G1) Equal(p1, p2 *PointG1) bool { - if g.IsZero(p1) { - return g.IsZero(p2) - } - if g.IsZero(p2) { - return g.IsZero(p1) - } - t := g.t - square(t[0], &p1[2]) - square(t[1], &p2[2]) - mul(t[2], t[0], &p2[0]) - mul(t[3], t[1], &p1[0]) - mul(t[0], t[0], &p1[2]) - mul(t[1], t[1], &p2[2]) - mul(t[1], t[1], &p1[1]) - mul(t[0], t[0], &p2[1]) - return t[0].equal(t[1]) && t[2].equal(t[3]) -} - -// InCorrectSubgroup checks whether given point is in correct subgroup. -func (g *G1) InCorrectSubgroup(p *PointG1) bool { - tmp := &PointG1{} - g.MulScalar(tmp, p, q) - return g.IsZero(tmp) -} - -// IsOnCurve checks a G1 point is on curve. -func (g *G1) IsOnCurve(p *PointG1) bool { - if g.IsZero(p) { - return true - } - t := g.t - square(t[0], &p[1]) - square(t[1], &p[0]) - mul(t[1], t[1], &p[0]) - square(t[2], &p[2]) - square(t[3], t[2]) - mul(t[2], t[2], t[3]) - mul(t[2], b, t[2]) - add(t[1], t[1], t[2]) - return t[0].equal(t[1]) -} - -// IsAffine checks a G1 point whether it is in affine form. -func (g *G1) IsAffine(p *PointG1) bool { - return p[2].isOne() -} - -// Affine calculates affine form of given G1 point. -func (g *G1) Affine(p *PointG1) *PointG1 { - if g.IsZero(p) { - return p - } - if !g.IsAffine(p) { - t := g.t - inverse(t[0], &p[2]) - square(t[1], t[0]) - mul(&p[0], &p[0], t[1]) - mul(t[0], t[0], t[1]) - mul(&p[1], &p[1], t[0]) - p[2].one() - } - return p -} - -// Add adds two G1 points p1, p2 and assigns the result to point at first argument. -func (g *G1) Add(r, p1, p2 *PointG1) *PointG1 { - // www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl - if g.IsZero(p1) { - return r.Set(p2) - } - if g.IsZero(p2) { - return r.Set(p1) - } - t := g.t - square(t[7], &p1[2]) - mul(t[1], &p2[0], t[7]) - mul(t[2], &p1[2], t[7]) - mul(t[0], &p2[1], t[2]) - square(t[8], &p2[2]) - mul(t[3], &p1[0], t[8]) - mul(t[4], &p2[2], t[8]) - mul(t[2], &p1[1], t[4]) - if t[1].equal(t[3]) { - if t[0].equal(t[2]) { - return g.Double(r, p1) - } - return r.Zero() - } - sub(t[1], t[1], t[3]) - double(t[4], t[1]) - square(t[4], t[4]) - mul(t[5], t[1], t[4]) - sub(t[0], t[0], t[2]) - double(t[0], t[0]) - square(t[6], t[0]) - sub(t[6], t[6], t[5]) - mul(t[3], t[3], t[4]) - double(t[4], t[3]) - sub(&r[0], t[6], t[4]) - sub(t[4], t[3], &r[0]) - mul(t[6], t[2], t[5]) - double(t[6], t[6]) - mul(t[0], t[0], t[4]) - sub(&r[1], t[0], t[6]) - add(t[0], &p1[2], &p2[2]) - square(t[0], t[0]) - sub(t[0], t[0], t[7]) - sub(t[0], t[0], t[8]) - mul(&r[2], t[0], t[1]) - return r -} - -// Double doubles a G1 point p and assigns the result to the point at first argument. -func (g *G1) Double(r, p *PointG1) *PointG1 { - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - if g.IsZero(p) { - return r.Set(p) - } - t := g.t - square(t[0], &p[0]) - square(t[1], &p[1]) - square(t[2], t[1]) - add(t[1], &p[0], t[1]) - square(t[1], t[1]) - sub(t[1], t[1], t[0]) - sub(t[1], t[1], t[2]) - double(t[1], t[1]) - double(t[3], t[0]) - add(t[0], t[3], t[0]) - square(t[4], t[0]) - double(t[3], t[1]) - sub(&r[0], t[4], t[3]) - sub(t[1], t[1], &r[0]) - double(t[2], t[2]) - double(t[2], t[2]) - double(t[2], t[2]) - mul(t[0], t[0], t[1]) - sub(t[1], t[0], t[2]) - mul(t[0], &p[1], &p[2]) - r[1].set(t[1]) - double(&r[2], t[0]) - return r -} - -// Neg negates a G1 point p and assigns the result to the point at first argument. -func (g *G1) Neg(r, p *PointG1) *PointG1 { - r[0].set(&p[0]) - r[2].set(&p[2]) - neg(&r[1], &p[1]) - return r -} - -// Sub subtracts two G1 points p1, p2 and assigns the result to point at first argument. -func (g *G1) Sub(c, a, b *PointG1) *PointG1 { - d := &PointG1{} - g.Neg(d, b) - g.Add(c, a, d) - return c -} - -// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument. -func (g *G1) MulScalar(c, p *PointG1, e *big.Int) *PointG1 { - q, n := &PointG1{}, &PointG1{} - n.Set(p) - l := e.BitLen() - for i := 0; i < l; i++ { - if e.Bit(i) == 1 { - g.Add(q, q, n) - } - g.Double(n, n) - } - return c.Set(q) -} - -// ClearCofactor maps given a G1 point to correct subgroup -func (g *G1) ClearCofactor(p *PointG1) { - g.MulScalar(p, p, cofactorEFFG1) -} - -// MultiExp calculates multi exponentiation. Given pairs of G1 point and scalar values -// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n -// Length of points and scalars are expected to be equal, otherwise an error is returned. -// Result is assigned to point at first argument. -func (g *G1) MultiExp(r *PointG1, points []*PointG1, powers []*big.Int) (*PointG1, error) { - if len(points) != len(powers) { - return nil, errors.New("point and scalar vectors should be in same length") - } - var c uint32 = 3 - if len(powers) >= 32 { - c = uint32(math.Ceil(math.Log10(float64(len(powers))))) - } - bucketSize, numBits := (1<= 0; i-- { - g.Add(sum, sum, bucket[i]) - g.Add(acc, acc, sum) - } - windows[j] = g.New() - windows[j].Set(acc) - j++ - cur += c - } - acc.Zero() - for i := len(windows) - 1; i >= 0; i-- { - for j := uint32(0); j < c; j++ { - g.Double(acc, acc) - } - g.Add(acc, acc, windows[i]) - } - return r.Set(acc), nil -} - -// MapToCurve given a byte slice returns a valid G1 point. -// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06 -// Input byte slice should be a valid field element, otherwise an error is returned. -func (g *G1) MapToCurve(in []byte) (*PointG1, error) { - u, err := fromBytes(in) - if err != nil { - return nil, err - } - x, y := swuMapG1(u) - isogenyMapG1(x, y) - one := new(fe).one() - p := &PointG1{*x, *y, *one} - g.ClearCofactor(p) - return g.Affine(p), nil -} diff --git a/crypto/bls12381/g1_test.go b/crypto/bls12381/g1_test.go deleted file mode 100644 index 87140459fb..0000000000 --- a/crypto/bls12381/g1_test.go +++ /dev/null @@ -1,284 +0,0 @@ -package bls12381 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func (g *G1) one() *PointG1 { - one, _ := g.fromBytesUnchecked( - common.FromHex("" + - "17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" + - "08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", - ), - ) - return one -} - -func (g *G1) rand() *PointG1 { - k, err := rand.Int(rand.Reader, q) - if err != nil { - panic(err) - } - return g.MulScalar(&PointG1{}, g.one(), k) -} - -func TestG1Serialization(t *testing.T) { - g1 := NewG1() - for i := 0; i < fuz; i++ { - a := g1.rand() - buf := g1.ToBytes(a) - b, err := g1.FromBytes(buf) - if err != nil { - t.Fatal(err) - } - if !g1.Equal(a, b) { - t.Fatal("bad serialization from/to") - } - } - for i := 0; i < fuz; i++ { - a := g1.rand() - encoded := g1.EncodePoint(a) - b, err := g1.DecodePoint(encoded) - if err != nil { - t.Fatal(err) - } - if !g1.Equal(a, b) { - t.Fatal("bad serialization encode/decode") - } - } -} - -func TestG1IsOnCurve(t *testing.T) { - g := NewG1() - zero := g.Zero() - if !g.IsOnCurve(zero) { - t.Fatal("zero must be on curve") - } - one := new(fe).one() - p := &PointG1{*one, *one, *one} - if g.IsOnCurve(p) { - t.Fatal("(1, 1) is not on curve") - } -} - -func TestG1AdditiveProperties(t *testing.T) { - g := NewG1() - t0, t1 := g.New(), g.New() - zero := g.Zero() - for i := 0; i < fuz; i++ { - a, b := g.rand(), g.rand() - g.Add(t0, a, zero) - if !g.Equal(t0, a) { - t.Fatal("a + 0 == a") - } - g.Add(t0, zero, zero) - if !g.Equal(t0, zero) { - t.Fatal("0 + 0 == 0") - } - g.Sub(t0, a, zero) - if !g.Equal(t0, a) { - t.Fatal("a - 0 == a") - } - g.Sub(t0, zero, zero) - if !g.Equal(t0, zero) { - t.Fatal("0 - 0 == 0") - } - g.Neg(t0, zero) - if !g.Equal(t0, zero) { - t.Fatal("- 0 == 0") - } - g.Sub(t0, zero, a) - g.Neg(t0, t0) - if !g.Equal(t0, a) { - t.Fatal(" - (0 - a) == a") - } - g.Double(t0, zero) - if !g.Equal(t0, zero) { - t.Fatal("2 * 0 == 0") - } - g.Double(t0, a) - g.Sub(t0, t0, a) - if !g.Equal(t0, a) || !g.IsOnCurve(t0) { - t.Fatal(" (2 * a) - a == a") - } - g.Add(t0, a, b) - g.Add(t1, b, a) - if !g.Equal(t0, t1) { - t.Fatal("a + b == b + a") - } - g.Sub(t0, a, b) - g.Sub(t1, b, a) - g.Neg(t1, t1) - if !g.Equal(t0, t1) { - t.Fatal("a - b == - ( b - a )") - } - c := g.rand() - g.Add(t0, a, b) - g.Add(t0, t0, c) - g.Add(t1, a, c) - g.Add(t1, t1, b) - if !g.Equal(t0, t1) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - g.Sub(t0, a, b) - g.Sub(t0, t0, c) - g.Sub(t1, a, c) - g.Sub(t1, t1, b) - if !g.Equal(t0, t1) { - t.Fatal("(a - b) - c == (a - c) -b") - } - } -} - -func TestG1MultiplicativeProperties(t *testing.T) { - g := NewG1() - t0, t1 := g.New(), g.New() - zero := g.Zero() - for i := 0; i < fuz; i++ { - a := g.rand() - s1, s2, s3 := randScalar(q), randScalar(q), randScalar(q) - sone := big.NewInt(1) - g.MulScalar(t0, zero, s1) - if !g.Equal(t0, zero) { - t.Fatal(" 0 ^ s == 0") - } - g.MulScalar(t0, a, sone) - if !g.Equal(t0, a) { - t.Fatal(" a ^ 1 == a") - } - g.MulScalar(t0, zero, s1) - if !g.Equal(t0, zero) { - t.Fatal(" 0 ^ s == a") - } - g.MulScalar(t0, a, s1) - g.MulScalar(t0, t0, s2) - s3.Mul(s1, s2) - g.MulScalar(t1, a, s3) - if !g.Equal(t0, t1) { - t.Errorf(" (a ^ s1) ^ s2 == a ^ (s1 * s2)") - } - g.MulScalar(t0, a, s1) - g.MulScalar(t1, a, s2) - g.Add(t0, t0, t1) - s3.Add(s1, s2) - g.MulScalar(t1, a, s3) - if !g.Equal(t0, t1) { - t.Errorf(" (a ^ s1) + (a ^ s2) == a ^ (s1 + s2)") - } - } -} - -func TestG1MultiExpExpected(t *testing.T) { - g := NewG1() - one := g.one() - var scalars [2]*big.Int - var bases [2]*PointG1 - scalars[0] = big.NewInt(2) - scalars[1] = big.NewInt(3) - bases[0], bases[1] = new(PointG1).Set(one), new(PointG1).Set(one) - expected, result := g.New(), g.New() - g.MulScalar(expected, one, big.NewInt(5)) - _, _ = g.MultiExp(result, bases[:], scalars[:]) - if !g.Equal(expected, result) { - t.Fatal("bad multi-exponentiation") - } -} - -func TestG1MultiExpBatch(t *testing.T) { - g := NewG1() - one := g.one() - n := 1000 - bases := make([]*PointG1, n) - scalars := make([]*big.Int, n) - // scalars: [s0,s1 ... s(n-1)] - // bases: [P0,P1,..P(n-1)] = [s(n-1)*G, s(n-2)*G ... s0*G] - for i, j := 0, n-1; i < n; i, j = i+1, j-1 { - scalars[j], _ = rand.Int(rand.Reader, big.NewInt(100000)) - bases[i] = g.New() - g.MulScalar(bases[i], one, scalars[j]) - } - // expected: s(n-1)*P0 + s(n-2)*P1 + s0*P(n-1) - expected, tmp := g.New(), g.New() - for i := 0; i < n; i++ { - g.MulScalar(tmp, bases[i], scalars[i]) - g.Add(expected, expected, tmp) - } - result := g.New() - _, _ = g.MultiExp(result, bases, scalars) - if !g.Equal(expected, result) { - t.Fatal("bad multi-exponentiation") - } -} - -func TestG1MapToCurve(t *testing.T) { - for i, v := range []struct { - u []byte - expected []byte - }{ - { - u: make([]byte, 48), - expected: common.FromHex("11a9a0372b8f332d5c30de9ad14e50372a73fa4c45d5f2fa5097f2d6fb93bcac592f2e1711ac43db0519870c7d0ea415" + "092c0f994164a0719f51c24ba3788de240ff926b55f58c445116e8bc6a47cd63392fd4e8e22bdf9feaa96ee773222133"), - }, - { - u: common.FromHex("07fdf49ea58e96015d61f6b5c9d1c8f277146a533ae7fbca2a8ef4c41055cd961fbc6e26979b5554e4b4f22330c0e16d"), - expected: common.FromHex("1223effdbb2d38152495a864d78eee14cb0992d89a241707abb03819a91a6d2fd65854ab9a69e9aacb0cbebfd490732c" + "0f925d61e0b235ecd945cbf0309291878df0d06e5d80d6b84aa4ff3e00633b26f9a7cb3523ef737d90e6d71e8b98b2d5"), - }, - { - u: common.FromHex("1275ab3adbf824a169ed4b1fd669b49cf406d822f7fe90d6b2f8c601b5348436f89761bb1ad89a6fb1137cd91810e5d2"), - expected: common.FromHex("179d3fd0b4fb1da43aad06cea1fb3f828806ddb1b1fa9424b1e3944dfdbab6e763c42636404017da03099af0dcca0fd6" + "0d037cb1c6d495c0f5f22b061d23f1be3d7fe64d3c6820cfcd99b6b36fa69f7b4c1f4addba2ae7aa46fb25901ab483e4"), - }, - { - u: common.FromHex("0e93d11d30de6d84b8578827856f5c05feef36083eef0b7b263e35ecb9b56e86299614a042e57d467fa20948e8564909"), - expected: common.FromHex("15aa66c77eded1209db694e8b1ba49daf8b686733afaa7b68c683d0b01788dfb0617a2e2d04c0856db4981921d3004af" + "0952bb2f61739dd1d201dd0a79d74cda3285403d47655ee886afe860593a8a4e51c5b77a22d2133e3a4280eaaaa8b788"), - }, - { - u: common.FromHex("015a41481155d17074d20be6d8ec4d46632a51521cd9c916e265bd9b47343b3689979b50708c8546cbc2916b86cb1a3a"), - expected: common.FromHex("06328ce5106e837935e8da84bd9af473422e62492930aa5f460369baad9545defa468d9399854c23a75495d2a80487ee" + "094bfdfe3e552447433b5a00967498a3f1314b86ce7a7164c8a8f4131f99333b30a574607e301d5f774172c627fd0bca"), - }, - } { - g := NewG1() - p0, err := g.MapToCurve(v.u) - if err != nil { - t.Fatal("map to curve fails", i, err) - } - if !bytes.Equal(g.ToBytes(p0), v.expected) { - t.Fatal("map to curve fails", i) - } - } -} - -func BenchmarkG1Add(t *testing.B) { - g1 := NewG1() - a, b, c := g1.rand(), g1.rand(), PointG1{} - t.ResetTimer() - for i := 0; i < t.N; i++ { - g1.Add(&c, a, b) - } -} - -func BenchmarkG1Mul(t *testing.B) { - worstCaseScalar, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) - g1 := NewG1() - a, e, c := g1.rand(), worstCaseScalar, PointG1{} - t.ResetTimer() - for i := 0; i < t.N; i++ { - g1.MulScalar(&c, a, e) - } -} - -func BenchmarkG1MapToCurve(t *testing.B) { - a := make([]byte, 48) - g1 := NewG1() - t.ResetTimer() - for i := 0; i < t.N; i++ { - _, err := g1.MapToCurve(a) - if err != nil { - t.Fatal(err) - } - } -} diff --git a/crypto/bls12381/g2.go b/crypto/bls12381/g2.go deleted file mode 100644 index b942bf94fd..0000000000 --- a/crypto/bls12381/g2.go +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math" - "math/big" -) - -// PointG2 is type for point in G2. -// PointG2 is both used for Affine and Jacobian point representation. -// If z is equal to one the point is considered as in affine form. -type PointG2 [3]fe2 - -// Set copies values of one point to another. -func (p *PointG2) Set(p2 *PointG2) *PointG2 { - p[0].set(&p2[0]) - p[1].set(&p2[1]) - p[2].set(&p2[2]) - return p -} - -// Zero returns G2 point in point at infinity representation -func (p *PointG2) Zero() *PointG2 { - p[0].zero() - p[1].one() - p[2].zero() - return p -} - -type tempG2 struct { - t [9]*fe2 -} - -// G2 is struct for G2 group. -type G2 struct { - f *fp2 - tempG2 -} - -// NewG2 constructs a new G2 instance. -func NewG2() *G2 { - return newG2(nil) -} - -func newG2(f *fp2) *G2 { - if f == nil { - f = newFp2() - } - t := newTempG2() - return &G2{f, t} -} - -func newTempG2() tempG2 { - t := [9]*fe2{} - for i := 0; i < 9; i++ { - t[i] = &fe2{} - } - return tempG2{t} -} - -// Q returns group order in big.Int. -func (g *G2) Q() *big.Int { - return new(big.Int).Set(q) -} - -func (g *G2) fromBytesUnchecked(in []byte) (*PointG2, error) { - p0, err := g.f.fromBytes(in[:96]) - if err != nil { - return nil, err - } - p1, err := g.f.fromBytes(in[96:]) - if err != nil { - return nil, err - } - p2 := new(fe2).one() - return &PointG2{*p0, *p1, *p2}, nil -} - -// FromBytes constructs a new point given uncompressed byte input. -// FromBytes does not take zcash flags into account. -// Byte input expected to be larger than 96 bytes. -// First 192 bytes should be concatenation of x and y values -// Point (0, 0) is considered as infinity. -func (g *G2) FromBytes(in []byte) (*PointG2, error) { - if len(in) != 192 { - return nil, errors.New("input string should be equal or larger than 192") - } - p0, err := g.f.fromBytes(in[:96]) - if err != nil { - return nil, err - } - p1, err := g.f.fromBytes(in[96:]) - if err != nil { - return nil, err - } - // check if given input points to infinity - if p0.isZero() && p1.isZero() { - return g.Zero(), nil - } - p2 := new(fe2).one() - p := &PointG2{*p0, *p1, *p2} - if !g.IsOnCurve(p) { - return nil, errors.New("point is not on curve") - } - return p, nil -} - -// DecodePoint given encoded (x, y) coordinates in 256 bytes returns a valid G2 Point. -func (g *G2) DecodePoint(in []byte) (*PointG2, error) { - if len(in) != 256 { - return nil, errors.New("invalid g2 point length") - } - pointBytes := make([]byte, 192) - x0Bytes, err := decodeFieldElement(in[:64]) - if err != nil { - return nil, err - } - x1Bytes, err := decodeFieldElement(in[64:128]) - if err != nil { - return nil, err - } - y0Bytes, err := decodeFieldElement(in[128:192]) - if err != nil { - return nil, err - } - y1Bytes, err := decodeFieldElement(in[192:]) - if err != nil { - return nil, err - } - copy(pointBytes[:48], x1Bytes) - copy(pointBytes[48:96], x0Bytes) - copy(pointBytes[96:144], y1Bytes) - copy(pointBytes[144:192], y0Bytes) - return g.FromBytes(pointBytes) -} - -// ToBytes serializes a point into bytes in uncompressed form, -// does not take zcash flags into account, -// returns (0, 0) if point is infinity. -func (g *G2) ToBytes(p *PointG2) []byte { - out := make([]byte, 192) - if g.IsZero(p) { - return out - } - g.Affine(p) - copy(out[:96], g.f.toBytes(&p[0])) - copy(out[96:], g.f.toBytes(&p[1])) - return out -} - -// EncodePoint encodes a point into 256 bytes. -func (g *G2) EncodePoint(p *PointG2) []byte { - // outRaw is 96 bytes - outRaw := g.ToBytes(p) - out := make([]byte, 256) - // encode x - copy(out[16:16+48], outRaw[48:96]) - copy(out[80:80+48], outRaw[:48]) - // encode y - copy(out[144:144+48], outRaw[144:]) - copy(out[208:208+48], outRaw[96:144]) - return out -} - -// New creates a new G2 Point which is equal to zero in other words point at infinity. -func (g *G2) New() *PointG2 { - return new(PointG2).Zero() -} - -// Zero returns a new G2 Point which is equal to point at infinity. -func (g *G2) Zero() *PointG2 { - return new(PointG2).Zero() -} - -// One returns a new G2 Point which is equal to generator point. -func (g *G2) One() *PointG2 { - p := &PointG2{} - return p.Set(&g2One) -} - -// IsZero returns true if given point is equal to zero. -func (g *G2) IsZero(p *PointG2) bool { - return p[2].isZero() -} - -// Equal checks if given two G2 point is equal in their affine form. -func (g *G2) Equal(p1, p2 *PointG2) bool { - if g.IsZero(p1) { - return g.IsZero(p2) - } - if g.IsZero(p2) { - return g.IsZero(p1) - } - t := g.t - g.f.square(t[0], &p1[2]) - g.f.square(t[1], &p2[2]) - g.f.mul(t[2], t[0], &p2[0]) - g.f.mul(t[3], t[1], &p1[0]) - g.f.mul(t[0], t[0], &p1[2]) - g.f.mul(t[1], t[1], &p2[2]) - g.f.mul(t[1], t[1], &p1[1]) - g.f.mul(t[0], t[0], &p2[1]) - return t[0].equal(t[1]) && t[2].equal(t[3]) -} - -// InCorrectSubgroup checks whether given point is in correct subgroup. -func (g *G2) InCorrectSubgroup(p *PointG2) bool { - tmp := &PointG2{} - g.MulScalar(tmp, p, q) - return g.IsZero(tmp) -} - -// IsOnCurve checks a G2 point is on curve. -func (g *G2) IsOnCurve(p *PointG2) bool { - if g.IsZero(p) { - return true - } - t := g.t - g.f.square(t[0], &p[1]) - g.f.square(t[1], &p[0]) - g.f.mul(t[1], t[1], &p[0]) - g.f.square(t[2], &p[2]) - g.f.square(t[3], t[2]) - g.f.mul(t[2], t[2], t[3]) - g.f.mul(t[2], b2, t[2]) - g.f.add(t[1], t[1], t[2]) - return t[0].equal(t[1]) -} - -// IsAffine checks a G2 point whether it is in affine form. -func (g *G2) IsAffine(p *PointG2) bool { - return p[2].isOne() -} - -// Affine calculates affine form of given G2 point. -func (g *G2) Affine(p *PointG2) *PointG2 { - if g.IsZero(p) { - return p - } - if !g.IsAffine(p) { - t := g.t - g.f.inverse(t[0], &p[2]) - g.f.square(t[1], t[0]) - g.f.mul(&p[0], &p[0], t[1]) - g.f.mul(t[0], t[0], t[1]) - g.f.mul(&p[1], &p[1], t[0]) - p[2].one() - } - return p -} - -// Add adds two G2 points p1, p2 and assigns the result to point at first argument. -func (g *G2) Add(r, p1, p2 *PointG2) *PointG2 { - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl - if g.IsZero(p1) { - return r.Set(p2) - } - if g.IsZero(p2) { - return r.Set(p1) - } - t := g.t - g.f.square(t[7], &p1[2]) - g.f.mul(t[1], &p2[0], t[7]) - g.f.mul(t[2], &p1[2], t[7]) - g.f.mul(t[0], &p2[1], t[2]) - g.f.square(t[8], &p2[2]) - g.f.mul(t[3], &p1[0], t[8]) - g.f.mul(t[4], &p2[2], t[8]) - g.f.mul(t[2], &p1[1], t[4]) - if t[1].equal(t[3]) { - if t[0].equal(t[2]) { - return g.Double(r, p1) - } - return r.Zero() - } - g.f.sub(t[1], t[1], t[3]) - g.f.double(t[4], t[1]) - g.f.square(t[4], t[4]) - g.f.mul(t[5], t[1], t[4]) - g.f.sub(t[0], t[0], t[2]) - g.f.double(t[0], t[0]) - g.f.square(t[6], t[0]) - g.f.sub(t[6], t[6], t[5]) - g.f.mul(t[3], t[3], t[4]) - g.f.double(t[4], t[3]) - g.f.sub(&r[0], t[6], t[4]) - g.f.sub(t[4], t[3], &r[0]) - g.f.mul(t[6], t[2], t[5]) - g.f.double(t[6], t[6]) - g.f.mul(t[0], t[0], t[4]) - g.f.sub(&r[1], t[0], t[6]) - g.f.add(t[0], &p1[2], &p2[2]) - g.f.square(t[0], t[0]) - g.f.sub(t[0], t[0], t[7]) - g.f.sub(t[0], t[0], t[8]) - g.f.mul(&r[2], t[0], t[1]) - return r -} - -// Double doubles a G2 point p and assigns the result to the point at first argument. -func (g *G2) Double(r, p *PointG2) *PointG2 { - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - if g.IsZero(p) { - return r.Set(p) - } - t := g.t - g.f.square(t[0], &p[0]) - g.f.square(t[1], &p[1]) - g.f.square(t[2], t[1]) - g.f.add(t[1], &p[0], t[1]) - g.f.square(t[1], t[1]) - g.f.sub(t[1], t[1], t[0]) - g.f.sub(t[1], t[1], t[2]) - g.f.double(t[1], t[1]) - g.f.double(t[3], t[0]) - g.f.add(t[0], t[3], t[0]) - g.f.square(t[4], t[0]) - g.f.double(t[3], t[1]) - g.f.sub(&r[0], t[4], t[3]) - g.f.sub(t[1], t[1], &r[0]) - g.f.double(t[2], t[2]) - g.f.double(t[2], t[2]) - g.f.double(t[2], t[2]) - g.f.mul(t[0], t[0], t[1]) - g.f.sub(t[1], t[0], t[2]) - g.f.mul(t[0], &p[1], &p[2]) - r[1].set(t[1]) - g.f.double(&r[2], t[0]) - return r -} - -// Neg negates a G2 point p and assigns the result to the point at first argument. -func (g *G2) Neg(r, p *PointG2) *PointG2 { - r[0].set(&p[0]) - g.f.neg(&r[1], &p[1]) - r[2].set(&p[2]) - return r -} - -// Sub subtracts two G2 points p1, p2 and assigns the result to point at first argument. -func (g *G2) Sub(c, a, b *PointG2) *PointG2 { - d := &PointG2{} - g.Neg(d, b) - g.Add(c, a, d) - return c -} - -// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument. -func (g *G2) MulScalar(c, p *PointG2, e *big.Int) *PointG2 { - q, n := &PointG2{}, &PointG2{} - n.Set(p) - l := e.BitLen() - for i := 0; i < l; i++ { - if e.Bit(i) == 1 { - g.Add(q, q, n) - } - g.Double(n, n) - } - return c.Set(q) -} - -// ClearCofactor maps given a G2 point to correct subgroup -func (g *G2) ClearCofactor(p *PointG2) { - g.MulScalar(p, p, cofactorEFFG2) -} - -// MultiExp calculates multi exponentiation. Given pairs of G2 point and scalar values -// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n -// Length of points and scalars are expected to be equal, otherwise an error is returned. -// Result is assigned to point at first argument. -func (g *G2) MultiExp(r *PointG2, points []*PointG2, powers []*big.Int) (*PointG2, error) { - if len(points) != len(powers) { - return nil, errors.New("point and scalar vectors should be in same length") - } - var c uint32 = 3 - if len(powers) >= 32 { - c = uint32(math.Ceil(math.Log10(float64(len(powers))))) - } - bucketSize, numBits := (1<= 0; i-- { - g.Add(sum, sum, bucket[i]) - g.Add(acc, acc, sum) - } - windows[j] = g.New() - windows[j].Set(acc) - j++ - cur += c - } - acc.Zero() - for i := len(windows) - 1; i >= 0; i-- { - for j := uint32(0); j < c; j++ { - g.Double(acc, acc) - } - g.Add(acc, acc, windows[i]) - } - return r.Set(acc), nil -} - -// MapToCurve given a byte slice returns a valid G2 point. -// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-6.6.2 -// Input byte slice should be a valid field element, otherwise an error is returned. -func (g *G2) MapToCurve(in []byte) (*PointG2, error) { - fp2 := g.f - u, err := fp2.fromBytes(in) - if err != nil { - return nil, err - } - x, y := swuMapG2(fp2, u) - isogenyMapG2(fp2, x, y) - z := new(fe2).one() - q := &PointG2{*x, *y, *z} - g.ClearCofactor(q) - return g.Affine(q), nil -} diff --git a/crypto/bls12381/g2_test.go b/crypto/bls12381/g2_test.go deleted file mode 100644 index 4d1f3a19ac..0000000000 --- a/crypto/bls12381/g2_test.go +++ /dev/null @@ -1,287 +0,0 @@ -package bls12381 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func (g *G2) one() *PointG2 { - one, _ := g.fromBytesUnchecked( - common.FromHex("" + - "13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" + - "024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" + - "0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" + - "0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801", - ), - ) - return one -} - -func (g *G2) rand() *PointG2 { - k, err := rand.Int(rand.Reader, q) - if err != nil { - panic(err) - } - return g.MulScalar(&PointG2{}, g.one(), k) -} - -func TestG2Serialization(t *testing.T) { - g2 := NewG2() - for i := 0; i < fuz; i++ { - a := g2.rand() - buf := g2.ToBytes(a) - b, err := g2.FromBytes(buf) - if err != nil { - t.Fatal(err) - } - if !g2.Equal(a, b) { - t.Fatal("bad serialization from/to") - } - } - for i := 0; i < fuz; i++ { - a := g2.rand() - encoded := g2.EncodePoint(a) - b, err := g2.DecodePoint(encoded) - if err != nil { - t.Fatal(err) - } - if !g2.Equal(a, b) { - t.Fatal("bad serialization encode/decode") - } - } -} - -func TestG2IsOnCurve(t *testing.T) { - g := NewG2() - zero := g.Zero() - if !g.IsOnCurve(zero) { - t.Fatal("zero must be on curve") - } - one := new(fe2).one() - p := &PointG2{*one, *one, *one} - if g.IsOnCurve(p) { - t.Fatal("(1, 1) is not on curve") - } -} - -func TestG2AdditiveProperties(t *testing.T) { - g := NewG2() - t0, t1 := g.New(), g.New() - zero := g.Zero() - for i := 0; i < fuz; i++ { - a, b := g.rand(), g.rand() - _, _, _ = b, t1, zero - g.Add(t0, a, zero) - if !g.Equal(t0, a) { - t.Fatal("a + 0 == a") - } - g.Add(t0, zero, zero) - if !g.Equal(t0, zero) { - t.Fatal("0 + 0 == 0") - } - g.Sub(t0, a, zero) - if !g.Equal(t0, a) { - t.Fatal("a - 0 == a") - } - g.Sub(t0, zero, zero) - if !g.Equal(t0, zero) { - t.Fatal("0 - 0 == 0") - } - g.Neg(t0, zero) - if !g.Equal(t0, zero) { - t.Fatal("- 0 == 0") - } - g.Sub(t0, zero, a) - g.Neg(t0, t0) - if !g.Equal(t0, a) { - t.Fatal(" - (0 - a) == a") - } - g.Double(t0, zero) - if !g.Equal(t0, zero) { - t.Fatal("2 * 0 == 0") - } - g.Double(t0, a) - g.Sub(t0, t0, a) - if !g.Equal(t0, a) || !g.IsOnCurve(t0) { - t.Fatal(" (2 * a) - a == a") - } - g.Add(t0, a, b) - g.Add(t1, b, a) - if !g.Equal(t0, t1) { - t.Fatal("a + b == b + a") - } - g.Sub(t0, a, b) - g.Sub(t1, b, a) - g.Neg(t1, t1) - if !g.Equal(t0, t1) { - t.Fatal("a - b == - ( b - a )") - } - c := g.rand() - g.Add(t0, a, b) - g.Add(t0, t0, c) - g.Add(t1, a, c) - g.Add(t1, t1, b) - if !g.Equal(t0, t1) { - t.Fatal("(a + b) + c == (a + c ) + b") - } - g.Sub(t0, a, b) - g.Sub(t0, t0, c) - g.Sub(t1, a, c) - g.Sub(t1, t1, b) - if !g.Equal(t0, t1) { - t.Fatal("(a - b) - c == (a - c) -b") - } - } -} - -func TestG2MultiplicativeProperties(t *testing.T) { - g := NewG2() - t0, t1 := g.New(), g.New() - zero := g.Zero() - for i := 0; i < fuz; i++ { - a := g.rand() - s1, s2, s3 := randScalar(q), randScalar(q), randScalar(q) - sone := big.NewInt(1) - g.MulScalar(t0, zero, s1) - if !g.Equal(t0, zero) { - t.Fatal(" 0 ^ s == 0") - } - g.MulScalar(t0, a, sone) - if !g.Equal(t0, a) { - t.Fatal(" a ^ 1 == a") - } - g.MulScalar(t0, zero, s1) - if !g.Equal(t0, zero) { - t.Fatal(" 0 ^ s == a") - } - g.MulScalar(t0, a, s1) - g.MulScalar(t0, t0, s2) - s3.Mul(s1, s2) - g.MulScalar(t1, a, s3) - if !g.Equal(t0, t1) { - t.Errorf(" (a ^ s1) ^ s2 == a ^ (s1 * s2)") - } - g.MulScalar(t0, a, s1) - g.MulScalar(t1, a, s2) - g.Add(t0, t0, t1) - s3.Add(s1, s2) - g.MulScalar(t1, a, s3) - if !g.Equal(t0, t1) { - t.Errorf(" (a ^ s1) + (a ^ s2) == a ^ (s1 + s2)") - } - } -} - -func TestG2MultiExpExpected(t *testing.T) { - g := NewG2() - one := g.one() - var scalars [2]*big.Int - var bases [2]*PointG2 - scalars[0] = big.NewInt(2) - scalars[1] = big.NewInt(3) - bases[0], bases[1] = new(PointG2).Set(one), new(PointG2).Set(one) - expected, result := g.New(), g.New() - g.MulScalar(expected, one, big.NewInt(5)) - _, _ = g.MultiExp(result, bases[:], scalars[:]) - if !g.Equal(expected, result) { - t.Fatal("bad multi-exponentiation") - } -} - -func TestG2MultiExpBatch(t *testing.T) { - g := NewG2() - one := g.one() - n := 1000 - bases := make([]*PointG2, n) - scalars := make([]*big.Int, n) - // scalars: [s0,s1 ... s(n-1)] - // bases: [P0,P1,..P(n-1)] = [s(n-1)*G, s(n-2)*G ... s0*G] - for i, j := 0, n-1; i < n; i, j = i+1, j-1 { - scalars[j], _ = rand.Int(rand.Reader, big.NewInt(100000)) - bases[i] = g.New() - g.MulScalar(bases[i], one, scalars[j]) - } - // expected: s(n-1)*P0 + s(n-2)*P1 + s0*P(n-1) - expected, tmp := g.New(), g.New() - for i := 0; i < n; i++ { - g.MulScalar(tmp, bases[i], scalars[i]) - g.Add(expected, expected, tmp) - } - result := g.New() - _, _ = g.MultiExp(result, bases, scalars) - if !g.Equal(expected, result) { - t.Fatal("bad multi-exponentiation") - } -} - -func TestG2MapToCurve(t *testing.T) { - for i, v := range []struct { - u []byte - expected []byte - }{ - { - u: make([]byte, 96), - expected: common.FromHex("0a67d12118b5a35bb02d2e86b3ebfa7e23410db93de39fb06d7025fa95e96ffa428a7a27c3ae4dd4b40bd251ac658892" + "018320896ec9eef9d5e619848dc29ce266f413d02dd31d9b9d44ec0c79cd61f18b075ddba6d7bd20b7ff27a4b324bfce" + "04c69777a43f0bda07679d5805e63f18cf4e0e7c6112ac7f70266d199b4f76ae27c6269a3ceebdae30806e9a76aadf5c" + "0260e03644d1a2c321256b3246bad2b895cad13890cbe6f85df55106a0d334604fb143c7a042d878006271865bc35941"), - }, - { - u: common.FromHex("025fbc07711ba267b7e70c82caa70a16fbb1d470ae24ceef307f5e2000751677820b7013ad4e25492dcf30052d3e5eca" + "0e775d7827adf385b83e20e4445bd3fab21d7b4498426daf3c1d608b9d41e9edb5eda0df022e753b8bb4bc3bb7db4914"), - expected: common.FromHex("0d4333b77becbf9f9dfa3ca928002233d1ecc854b1447e5a71f751c9042d000f42db91c1d6649a5e0ad22bd7bf7398b8" + "027e4bfada0b47f9f07e04aec463c7371e68f2fd0c738cd517932ea3801a35acf09db018deda57387b0f270f7a219e4d" + "0cc76dc777ea0d447e02a41004f37a0a7b1fafb6746884e8d9fc276716ccf47e4e0899548a2ec71c2bdf1a2a50e876db" + "053674cba9ef516ddc218fedb37324e6c47de27f88ab7ef123b006127d738293c0277187f7e2f80a299a24d84ed03da7"), - }, - { - u: common.FromHex("1870a7dbfd2a1deb74015a3546b20f598041bf5d5202997956a94a368d30d3f70f18cdaa1d33ce970a4e16af961cbdcb" + "045ab31ce4b5a8ba7c4b2851b64f063a66cd1223d3c85005b78e1beee65e33c90ceef0244e45fc45a5e1d6eab6644fdb"), - expected: common.FromHex("18f0f87b40af67c056915dbaf48534c592524e82c1c2b50c3734d02c0172c80df780a60b5683759298a3303c5d942778" + "09349f1cb5b2e55489dcd45a38545343451cc30a1681c57acd4fb0a6db125f8352c09f4a67eb7d1d8242cb7d3405f97b" + "10a2ba341bc689ab947b7941ce6ef39be17acaab067bd32bd652b471ab0792c53a2bd03bdac47f96aaafe96e441f63c0" + "02f2d9deb2c7742512f5b8230bf0fd83ea42279d7d39779543c1a43b61c885982b611f6a7a24b514995e8a098496b811"), - }, - { - u: common.FromHex("088fe329b054db8a6474f21a7fbfdf17b4c18044db299d9007af582c3d5f17d00e56d99921d4b5640fce44b05219b5de" + "0b6e6135a4cd31ba980ddbd115ac48abef7ec60e226f264d7befe002c165f3a496f36f76dd524efd75d17422558d10b4"), - expected: common.FromHex("19808ec5930a53c7cf5912ccce1cc33f1b3dcff24a53ce1cc4cba41fd6996dbed4843ccdd2eaf6a0cd801e562718d163" + "149fe43777d34f0d25430dea463889bd9393bdfb4932946db23671727081c629ebb98a89604f3433fba1c67d356a4af7" + "04783e391c30c83f805ca271e353582fdf19d159f6a4c39b73acbb637a9b8ac820cfbe2738d683368a7c07ad020e3e33" + "04c0d6793a766233b2982087b5f4a254f261003ccb3262ea7c50903eecef3e871d1502c293f9e063d7d293f6384f4551"), - }, - { - u: common.FromHex("03df16a66a05e4c1188c234788f43896e0565bfb64ac49b9639e6b284cc47dad73c47bb4ea7e677db8d496beb907fbb6" + "0f45b50647d67485295aa9eb2d91a877b44813677c67c8d35b2173ff3ba95f7bd0806f9ca8a1436b8b9d14ee81da4d7e"), - expected: common.FromHex("0b8e0094c886487870372eb6264613a6a087c7eb9804fab789be4e47a57b29eb19b1983a51165a1b5eb025865e9fc63a" + "0804152cbf8474669ad7d1796ab92d7ca21f32d8bed70898a748ed4e4e0ec557069003732fc86866d938538a2ae95552" + "14c80f068ece15a3936bb00c3c883966f75b4e8d9ddde809c11f781ab92d23a2d1d103ad48f6f3bb158bf3e3a4063449" + "09e5c8242dd7281ad32c03fe4af3f19167770016255fb25ad9b67ec51d62fade31a1af101e8f6172ec2ee8857662be3a"), - }, - } { - g := NewG2() - p0, err := g.MapToCurve(v.u) - if err != nil { - t.Fatal("map to curve fails", i, err) - } - if !bytes.Equal(g.ToBytes(p0), v.expected) { - t.Fatal("map to curve fails", i) - } - } -} - -func BenchmarkG2Add(t *testing.B) { - g2 := NewG2() - a, b, c := g2.rand(), g2.rand(), PointG2{} - t.ResetTimer() - for i := 0; i < t.N; i++ { - g2.Add(&c, a, b) - } -} - -func BenchmarkG2Mul(t *testing.B) { - worstCaseScalar, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) - g2 := NewG2() - a, e, c := g2.rand(), worstCaseScalar, PointG2{} - t.ResetTimer() - for i := 0; i < t.N; i++ { - g2.MulScalar(&c, a, e) - } -} - -func BenchmarkG2SWUMap(t *testing.B) { - a := make([]byte, 96) - g2 := NewG2() - t.ResetTimer() - for i := 0; i < t.N; i++ { - _, err := g2.MapToCurve(a) - if err != nil { - t.Fatal(err) - } - } -} diff --git a/crypto/bls12381/gt.go b/crypto/bls12381/gt.go deleted file mode 100644 index 2ac265e956..0000000000 --- a/crypto/bls12381/gt.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -import ( - "errors" - "math/big" -) - -// E is type for target group element -type E = fe12 - -// GT is type for target multiplicative group GT. -type GT struct { - fp12 *fp12 -} - -func (e *E) Set(e2 *E) *E { - return e.set(e2) -} - -// One sets a new target group element to one -func (e *E) One() *E { - e = new(fe12).one() - return e -} - -// IsOne returns true if given element equals to one -func (e *E) IsOne() bool { - return e.isOne() -} - -// Equal returns true if given two element is equal, otherwise returns false -func (g *E) Equal(g2 *E) bool { - return g.equal(g2) -} - -// NewGT constructs new target group instance. -func NewGT() *GT { - fp12 := newFp12(nil) - return >{fp12} -} - -// Q returns group order in big.Int. -func (g *GT) Q() *big.Int { - return new(big.Int).Set(q) -} - -// FromBytes expects 576 byte input and returns target group element -// FromBytes returns error if given element is not on correct subgroup. -func (g *GT) FromBytes(in []byte) (*E, error) { - e, err := g.fp12.fromBytes(in) - if err != nil { - return nil, err - } - if !g.IsValid(e) { - return e, errors.New("invalid element") - } - return e, nil -} - -// ToBytes serializes target group element. -func (g *GT) ToBytes(e *E) []byte { - return g.fp12.toBytes(e) -} - -// IsValid checks whether given target group element is in correct subgroup. -func (g *GT) IsValid(e *E) bool { - r := g.New() - g.fp12.exp(r, e, q) - return r.isOne() -} - -// New initializes a new target group element which is equal to one -func (g *GT) New() *E { - return new(E).One() -} - -// Add adds two field element `a` and `b` and assigns the result to the element in first argument. -func (g *GT) Add(c, a, b *E) { - g.fp12.add(c, a, b) -} - -// Sub subtracts two field element `a` and `b`, and assigns the result to the element in first argument. -func (g *GT) Sub(c, a, b *E) { - g.fp12.sub(c, a, b) -} - -// Mul multiplies two field element `a` and `b` and assigns the result to the element in first argument. -func (g *GT) Mul(c, a, b *E) { - g.fp12.mul(c, a, b) -} - -// Square squares an element `a` and assigns the result to the element in first argument. -func (g *GT) Square(c, a *E) { - g.fp12.cyclotomicSquare(c, a) -} - -// Exp exponents an element `a` by a scalar `s` and assigns the result to the element in first argument. -func (g *GT) Exp(c, a *E, s *big.Int) { - g.fp12.cyclotomicExp(c, a, s) -} - -// Inverse inverses an element `a` and assigns the result to the element in first argument. -func (g *GT) Inverse(c, a *E) { - g.fp12.inverse(c, a) -} diff --git a/crypto/bls12381/isogeny.go b/crypto/bls12381/isogeny.go deleted file mode 100644 index a63f585dd0..0000000000 --- a/crypto/bls12381/isogeny.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -// isogenyMapG1 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06. -func isogenyMapG1(x, y *fe) { - // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2 - params := isogenyConstantsG1 - degree := 15 - xNum, xDen, yNum, yDen := new(fe), new(fe), new(fe), new(fe) - xNum.set(params[0][degree]) - xDen.set(params[1][degree]) - yNum.set(params[2][degree]) - yDen.set(params[3][degree]) - for i := degree - 1; i >= 0; i-- { - mul(xNum, xNum, x) - mul(xDen, xDen, x) - mul(yNum, yNum, x) - mul(yDen, yDen, x) - add(xNum, xNum, params[0][i]) - add(xDen, xDen, params[1][i]) - add(yNum, yNum, params[2][i]) - add(yDen, yDen, params[3][i]) - } - inverse(xDen, xDen) - inverse(yDen, yDen) - mul(xNum, xNum, xDen) - mul(yNum, yNum, yDen) - mul(yNum, yNum, y) - x.set(xNum) - y.set(yNum) -} - -// isogenyMapG2 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06. -func isogenyMapG2(e *fp2, x, y *fe2) { - if e == nil { - e = newFp2() - } - // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2 - params := isogenyConstantsG2 - degree := 3 - xNum := new(fe2).set(params[0][degree]) - xDen := new(fe2).set(params[1][degree]) - yNum := new(fe2).set(params[2][degree]) - yDen := new(fe2).set(params[3][degree]) - for i := degree - 1; i >= 0; i-- { - e.mul(xNum, xNum, x) - e.mul(xDen, xDen, x) - e.mul(yNum, yNum, x) - e.mul(yDen, yDen, x) - e.add(xNum, xNum, params[0][i]) - e.add(xDen, xDen, params[1][i]) - e.add(yNum, yNum, params[2][i]) - e.add(yDen, yDen, params[3][i]) - } - e.inverse(xDen, xDen) - e.inverse(yDen, yDen) - e.mul(xNum, xNum, xDen) - e.mul(yNum, yNum, yDen) - e.mul(yNum, yNum, y) - x.set(xNum) - y.set(yNum) -} - -var isogenyConstantsG1 = [4][16]*fe{ - { - {0x4d18b6f3af00131c, 0x19fa219793fee28c, 0x3f2885f1467f19ae, 0x23dcea34f2ffb304, 0xd15b58d2ffc00054, 0x0913be200a20bef4}, - {0x898985385cdbbd8b, 0x3c79e43cc7d966aa, 0x1597e193f4cd233a, 0x8637ef1e4d6623ad, 0x11b22deed20d827b, 0x07097bc5998784ad}, - {0xa542583a480b664b, 0xfc7169c026e568c6, 0x5ba2ef314ed8b5a6, 0x5b5491c05102f0e7, 0xdf6e99707d2a0079, 0x0784151ed7605524}, - {0x494e212870f72741, 0xab9be52fbda43021, 0x26f5577994e34c3d, 0x049dfee82aefbd60, 0x65dadd7828505289, 0x0e93d431ea011aeb}, - {0x90ee774bd6a74d45, 0x7ada1c8a41bfb185, 0x0f1a8953b325f464, 0x104c24211be4805c, 0x169139d319ea7a8f, 0x09f20ead8e532bf6}, - {0x6ddd93e2f43626b7, 0xa5482c9aa1ccd7bd, 0x143245631883f4bd, 0x2e0a94ccf77ec0db, 0xb0282d480e56489f, 0x18f4bfcbb4368929}, - {0x23c5f0c953402dfd, 0x7a43ff6958ce4fe9, 0x2c390d3d2da5df63, 0xd0df5c98e1f9d70f, 0xffd89869a572b297, 0x1277ffc72f25e8fe}, - {0x79f4f0490f06a8a6, 0x85f894a88030fd81, 0x12da3054b18b6410, 0xe2a57f6505880d65, 0xbba074f260e400f1, 0x08b76279f621d028}, - {0xe67245ba78d5b00b, 0x8456ba9a1f186475, 0x7888bff6e6b33bb4, 0xe21585b9a30f86cb, 0x05a69cdcef55feee, 0x09e699dd9adfa5ac}, - {0x0de5c357bff57107, 0x0a0db4ae6b1a10b2, 0xe256bb67b3b3cd8d, 0x8ad456574e9db24f, 0x0443915f50fd4179, 0x098c4bf7de8b6375}, - {0xe6b0617e7dd929c7, 0xfe6e37d442537375, 0x1dafdeda137a489e, 0xe4efd1ad3f767ceb, 0x4a51d8667f0fe1cf, 0x054fdf4bbf1d821c}, - {0x72db2a50658d767b, 0x8abf91faa257b3d5, 0xe969d6833764ab47, 0x464170142a1009eb, 0xb14f01aadb30be2f, 0x18ae6a856f40715d}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - }, - { - {0xb962a077fdb0f945, 0xa6a9740fefda13a0, 0xc14d568c3ed6c544, 0xb43fc37b908b133e, 0x9c0b3ac929599016, 0x0165aa6c93ad115f}, - {0x23279a3ba506c1d9, 0x92cfca0a9465176a, 0x3b294ab13755f0ff, 0x116dda1c5070ae93, 0xed4530924cec2045, 0x083383d6ed81f1ce}, - {0x9885c2a6449fecfc, 0x4a2b54ccd37733f0, 0x17da9ffd8738c142, 0xa0fba72732b3fafd, 0xff364f36e54b6812, 0x0f29c13c660523e2}, - {0xe349cc118278f041, 0xd487228f2f3204fb, 0xc9d325849ade5150, 0x43a92bd69c15c2df, 0x1c2c7844bc417be4, 0x12025184f407440c}, - {0x587f65ae6acb057b, 0x1444ef325140201f, 0xfbf995e71270da49, 0xccda066072436a42, 0x7408904f0f186bb2, 0x13b93c63edf6c015}, - {0xfb918622cd141920, 0x4a4c64423ecaddb4, 0x0beb232927f7fb26, 0x30f94df6f83a3dc2, 0xaeedd424d780f388, 0x06cc402dd594bbeb}, - {0xd41f761151b23f8f, 0x32a92465435719b3, 0x64f436e888c62cb9, 0xdf70a9a1f757c6e4, 0x6933a38d5b594c81, 0x0c6f7f7237b46606}, - {0x693c08747876c8f7, 0x22c9850bf9cf80f0, 0x8e9071dab950c124, 0x89bc62d61c7baf23, 0xbc6be2d8dad57c23, 0x17916987aa14a122}, - {0x1be3ff439c1316fd, 0x9965243a7571dfa7, 0xc7f7f62962f5cd81, 0x32c6aa9af394361c, 0xbbc2ee18e1c227f4, 0x0c102cbac531bb34}, - {0x997614c97bacbf07, 0x61f86372b99192c0, 0x5b8c95fc14353fc3, 0xca2b066c2a87492f, 0x16178f5bbf698711, 0x12a6dcd7f0f4e0e8}, - {0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - }, - { - {0x2b567ff3e2837267, 0x1d4d9e57b958a767, 0xce028fea04bd7373, 0xcc31a30a0b6cd3df, 0x7d7b18a682692693, 0x0d300744d42a0310}, - {0x99c2555fa542493f, 0xfe7f53cc4874f878, 0x5df0608b8f97608a, 0x14e03832052b49c8, 0x706326a6957dd5a4, 0x0a8dadd9c2414555}, - {0x13d942922a5cf63a, 0x357e33e36e261e7d, 0xcf05a27c8456088d, 0x0000bd1de7ba50f0, 0x83d0c7532f8c1fde, 0x13f70bf38bbf2905}, - {0x5c57fd95bfafbdbb, 0x28a359a65e541707, 0x3983ceb4f6360b6d, 0xafe19ff6f97e6d53, 0xb3468f4550192bf7, 0x0bb6cde49d8ba257}, - {0x590b62c7ff8a513f, 0x314b4ce372cacefd, 0x6bef32ce94b8a800, 0x6ddf84a095713d5f, 0x64eace4cb0982191, 0x0386213c651b888d}, - {0xa5310a31111bbcdd, 0xa14ac0f5da148982, 0xf9ad9cc95423d2e9, 0xaa6ec095283ee4a7, 0xcf5b1f022e1c9107, 0x01fddf5aed881793}, - {0x65a572b0d7a7d950, 0xe25c2d8183473a19, 0xc2fcebe7cb877dbd, 0x05b2d36c769a89b0, 0xba12961be86e9efb, 0x07eb1b29c1dfde1f}, - {0x93e09572f7c4cd24, 0x364e929076795091, 0x8569467e68af51b5, 0xa47da89439f5340f, 0xf4fa918082e44d64, 0x0ad52ba3e6695a79}, - {0x911429844e0d5f54, 0xd03f51a3516bb233, 0x3d587e5640536e66, 0xfa86d2a3a9a73482, 0xa90ed5adf1ed5537, 0x149c9c326a5e7393}, - {0x462bbeb03c12921a, 0xdc9af5fa0a274a17, 0x9a558ebde836ebed, 0x649ef8f11a4fae46, 0x8100e1652b3cdc62, 0x1862bd62c291dacb}, - {0x05c9b8ca89f12c26, 0x0194160fa9b9ac4f, 0x6a643d5a6879fa2c, 0x14665bdd8846e19d, 0xbb1d0d53af3ff6bf, 0x12c7e1c3b28962e5}, - {0xb55ebf900b8a3e17, 0xfedc77ec1a9201c4, 0x1f07db10ea1a4df4, 0x0dfbd15dc41a594d, 0x389547f2334a5391, 0x02419f98165871a4}, - {0xb416af000745fc20, 0x8e563e9d1ea6d0f5, 0x7c763e17763a0652, 0x01458ef0159ebbef, 0x8346fe421f96bb13, 0x0d2d7b829ce324d2}, - {0x93096bb538d64615, 0x6f2a2619951d823a, 0x8f66b3ea59514fa4, 0xf563e63704f7092f, 0x724b136c4cf2d9fa, 0x046959cfcfd0bf49}, - {0xea748d4b6e405346, 0x91e9079c2c02d58f, 0x41064965946d9b59, 0xa06731f1d2bbe1ee, 0x07f897e267a33f1b, 0x1017290919210e5f}, - {0x872aa6c17d985097, 0xeecc53161264562a, 0x07afe37afff55002, 0x54759078e5be6838, 0xc4b92d15db8acca8, 0x106d87d1b51d13b9}, - }, - { - {0xeb6c359d47e52b1c, 0x18ef5f8a10634d60, 0xddfa71a0889d5b7e, 0x723e71dcc5fc1323, 0x52f45700b70d5c69, 0x0a8b981ee47691f1}, - {0x616a3c4f5535b9fb, 0x6f5f037395dbd911, 0xf25f4cc5e35c65da, 0x3e50dffea3c62658, 0x6a33dca523560776, 0x0fadeff77b6bfe3e}, - {0x2be9b66df470059c, 0x24a2c159a3d36742, 0x115dbe7ad10c2a37, 0xb6634a652ee5884d, 0x04fe8bb2b8d81af4, 0x01c2a7a256fe9c41}, - {0xf27bf8ef3b75a386, 0x898b367476c9073f, 0x24482e6b8c2f4e5f, 0xc8e0bbd6fe110806, 0x59b0c17f7631448a, 0x11037cd58b3dbfbd}, - {0x31c7912ea267eec6, 0x1dbf6f1c5fcdb700, 0xd30d4fe3ba86fdb1, 0x3cae528fbee9a2a4, 0xb1cce69b6aa9ad9a, 0x044393bb632d94fb}, - {0xc66ef6efeeb5c7e8, 0x9824c289dd72bb55, 0x71b1a4d2f119981d, 0x104fc1aafb0919cc, 0x0e49df01d942a628, 0x096c3a09773272d4}, - {0x9abc11eb5fadeff4, 0x32dca50a885728f0, 0xfb1fa3721569734c, 0xc4b76271ea6506b3, 0xd466a75599ce728e, 0x0c81d4645f4cb6ed}, - {0x4199f10e5b8be45b, 0xda64e495b1e87930, 0xcb353efe9b33e4ff, 0x9e9efb24aa6424c6, 0xf08d33680a237465, 0x0d3378023e4c7406}, - {0x7eb4ae92ec74d3a5, 0xc341b4aa9fac3497, 0x5be603899e907687, 0x03bfd9cca75cbdeb, 0x564c2935a96bfa93, 0x0ef3c33371e2fdb5}, - {0x7ee91fd449f6ac2e, 0xe5d5bd5cb9357a30, 0x773a8ca5196b1380, 0xd0fda172174ed023, 0x6cb95e0fa776aead, 0x0d22d5a40cec7cff}, - {0xf727e09285fd8519, 0xdc9d55a83017897b, 0x7549d8bd057894ae, 0x178419613d90d8f8, 0xfce95ebdeb5b490a, 0x0467ffaef23fc49e}, - {0xc1769e6a7c385f1b, 0x79bc930deac01c03, 0x5461c75a23ede3b5, 0x6e20829e5c230c45, 0x828e0f1e772a53cd, 0x116aefa749127bff}, - {0x101c10bf2744c10a, 0xbbf18d053a6a3154, 0xa0ecf39ef026f602, 0xfc009d4996dc5153, 0xb9000209d5bd08d3, 0x189e5fe4470cd73c}, - {0x7ebd546ca1575ed2, 0xe47d5a981d081b55, 0x57b2b625b6d4ca21, 0xb0a1ba04228520cc, 0x98738983c2107ff3, 0x13dddbc4799d81d6}, - {0x09319f2e39834935, 0x039e952cbdb05c21, 0x55ba77a9a2f76493, 0xfd04e3dfc6086467, 0xfb95832e7d78742e, 0x0ef9c24eccaf5e0e}, - {0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - }, -} - -var isogenyConstantsG2 = [4][4]*fe2{ - { - { - fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41}, - fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41}, - }, - { - fe{0, 0, 0, 0, 0, 0}, - fe{0x5fe55555554c71d0, 0x873fffdd236aaaa3, 0x6a6b4619b26ef918, 0x21c2888408874945, 0x2836cda7028cabc5, 0x0ac73310a7fd5abd}, - }, - { - fe{0x0a0c5555555971c3, 0xdb0c00101f9eaaae, 0xb1fb2f941d797997, 0xd3960742ef416e1c, 0xb70040e2c20556f4, 0x149d7861e581393b}, - fe{0xaff2aaaaaaa638e8, 0x439fffee91b55551, 0xb535a30cd9377c8c, 0x90e144420443a4a2, 0x941b66d3814655e2, 0x0563998853fead5e}, - }, - { - fe{0x40aac71c71c725ed, 0x190955557a84e38e, 0xd817050a8f41abc3, 0xd86485d4c87f6fb1, 0x696eb479f885d059, 0x198e1a74328002d2}, - fe{0, 0, 0, 0, 0, 0}, - }, - }, - { - { - fe{0, 0, 0, 0, 0, 0}, - fe{0x1f3affffff13ab97, 0xf25bfc611da3ff3e, 0xca3757cb3819b208, 0x3e6427366f8cec18, 0x03977bc86095b089, 0x04f69db13f39a952}, - }, - { - fe{0x447600000027552e, 0xdcb8009a43480020, 0x6f7ee9ce4a6e8b59, 0xb10330b7c0a95bc6, 0x6140b1fcfb1e54b7, 0x0381be097f0bb4e1}, - fe{0x7588ffffffd8557d, 0x41f3ff646e0bffdf, 0xf7b1e8d2ac426aca, 0xb3741acd32dbb6f8, 0xe9daf5b9482d581f, 0x167f53e0ba7431b8}, - }, - { - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0, 0, 0, 0, 0, 0}, - }, - { - fe{0, 0, 0, 0, 0, 0}, - fe{0, 0, 0, 0, 0, 0}, - }, - }, - { - { - fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3}, - fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3}, - }, - { - fe{0, 0, 0, 0, 0, 0}, - fe{0xbf0a71c71c91b406, 0x4d6d55d28b7638fd, 0x9d82f98e5f205aee, 0xa27aa27b1d1a18d5, 0x02c3b2b2d2938e86, 0x0c7d13420b09807f}, - }, - { - fe{0xd7f9555555531c74, 0x21cffff748daaaa8, 0x5a9ad1866c9bbe46, 0x4870a2210221d251, 0x4a0db369c0a32af1, 0x02b1ccc429ff56af}, - fe{0xe205aaaaaaac8e37, 0xfcdc000768795556, 0x0c96011a8a1537dd, 0x1c06a963f163406e, 0x010df44c82a881e6, 0x174f45260f808feb}, - }, - { - fe{0xa470bda12f67f35c, 0xc0fe38e23327b425, 0xc9d3d0f2c6f0678d, 0x1c55c9935b5a982e, 0x27f6c0e2f0746764, 0x117c5e6e28aa9054}, - fe{0, 0, 0, 0, 0, 0}, - }, - }, - { - { - fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151}, - fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151}, - }, - { - fe{0, 0, 0, 0, 0, 0}, - fe{0x5db0fffffd3b02c5, 0xd713f52358ebfdba, 0x5ea60761a84d161a, 0xbb2c75a34ea6c44a, 0x0ac6735921c1119b, 0x0ee3d913bdacfbf6}, - }, - { - fe{0x66b10000003affc5, 0xcb1400e764ec0030, 0xa73e5eb56fa5d106, 0x8984c913a0fe09a9, 0x11e10afb78ad7f13, 0x05429d0e3e918f52}, - fe{0x534dffffffc4aae6, 0x5397ff174c67ffcf, 0xbff273eb870b251d, 0xdaf2827152870915, 0x393a9cbaca9e2dc3, 0x14be74dbfaee5748}, - }, - { - fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}, - fe{0, 0, 0, 0, 0, 0}, - }, - }, -} diff --git a/crypto/bls12381/pairing.go b/crypto/bls12381/pairing.go deleted file mode 100644 index d292d7c3a5..0000000000 --- a/crypto/bls12381/pairing.go +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -type pair struct { - g1 *PointG1 - g2 *PointG2 -} - -func newPair(g1 *PointG1, g2 *PointG2) pair { - return pair{g1, g2} -} - -// Engine is BLS12-381 elliptic curve pairing engine -type Engine struct { - G1 *G1 - G2 *G2 - fp12 *fp12 - fp2 *fp2 - pairingEngineTemp - pairs []pair -} - -// NewPairingEngine creates new pairing engine instance. -func NewPairingEngine() *Engine { - fp2 := newFp2() - fp6 := newFp6(fp2) - fp12 := newFp12(fp6) - g1 := NewG1() - g2 := newG2(fp2) - return &Engine{ - fp2: fp2, - fp12: fp12, - G1: g1, - G2: g2, - pairingEngineTemp: newEngineTemp(), - } -} - -type pairingEngineTemp struct { - t2 [10]*fe2 - t12 [9]fe12 -} - -func newEngineTemp() pairingEngineTemp { - t2 := [10]*fe2{} - for i := 0; i < 10; i++ { - t2[i] = &fe2{} - } - t12 := [9]fe12{} - return pairingEngineTemp{t2, t12} -} - -// AddPair adds a g1, g2 point pair to pairing engine -func (e *Engine) AddPair(g1 *PointG1, g2 *PointG2) *Engine { - p := newPair(g1, g2) - if !e.isZero(p) { - e.affine(p) - e.pairs = append(e.pairs, p) - } - return e -} - -// AddPairInv adds a G1, G2 point pair to pairing engine. G1 point is negated. -func (e *Engine) AddPairInv(g1 *PointG1, g2 *PointG2) *Engine { - e.G1.Neg(g1, g1) - e.AddPair(g1, g2) - return e -} - -// Reset deletes added pairs. -func (e *Engine) Reset() *Engine { - e.pairs = []pair{} - return e -} - -func (e *Engine) isZero(p pair) bool { - return e.G1.IsZero(p.g1) || e.G2.IsZero(p.g2) -} - -func (e *Engine) affine(p pair) { - e.G1.Affine(p.g1) - e.G2.Affine(p.g2) -} - -func (e *Engine) doublingStep(coeff *[3]fe2, r *PointG2) { - // Adaptation of Formula 3 in https://eprint.iacr.org/2010/526.pdf - fp2 := e.fp2 - t := e.t2 - fp2.mul(t[0], &r[0], &r[1]) - fp2.mulByFq(t[0], t[0], twoInv) - fp2.square(t[1], &r[1]) - fp2.square(t[2], &r[2]) - fp2.double(t[7], t[2]) - fp2.add(t[7], t[7], t[2]) - fp2.mulByB(t[3], t[7]) - fp2.double(t[4], t[3]) - fp2.add(t[4], t[4], t[3]) - fp2.add(t[5], t[1], t[4]) - fp2.mulByFq(t[5], t[5], twoInv) - fp2.add(t[6], &r[1], &r[2]) - fp2.square(t[6], t[6]) - fp2.add(t[7], t[2], t[1]) - fp2.sub(t[6], t[6], t[7]) - fp2.sub(&coeff[0], t[3], t[1]) - fp2.square(t[7], &r[0]) - fp2.sub(t[4], t[1], t[4]) - fp2.mul(&r[0], t[4], t[0]) - fp2.square(t[2], t[3]) - fp2.double(t[3], t[2]) - fp2.add(t[3], t[3], t[2]) - fp2.square(t[5], t[5]) - fp2.sub(&r[1], t[5], t[3]) - fp2.mul(&r[2], t[1], t[6]) - fp2.double(t[0], t[7]) - fp2.add(&coeff[1], t[0], t[7]) - fp2.neg(&coeff[2], t[6]) -} - -func (e *Engine) additionStep(coeff *[3]fe2, r, q *PointG2) { - // Algorithm 12 in https://eprint.iacr.org/2010/526.pdf - fp2 := e.fp2 - t := e.t2 - fp2.mul(t[0], &q[1], &r[2]) - fp2.neg(t[0], t[0]) - fp2.add(t[0], t[0], &r[1]) - fp2.mul(t[1], &q[0], &r[2]) - fp2.neg(t[1], t[1]) - fp2.add(t[1], t[1], &r[0]) - fp2.square(t[2], t[0]) - fp2.square(t[3], t[1]) - fp2.mul(t[4], t[1], t[3]) - fp2.mul(t[2], &r[2], t[2]) - fp2.mul(t[3], &r[0], t[3]) - fp2.double(t[5], t[3]) - fp2.sub(t[5], t[4], t[5]) - fp2.add(t[5], t[5], t[2]) - fp2.mul(&r[0], t[1], t[5]) - fp2.sub(t[2], t[3], t[5]) - fp2.mul(t[2], t[2], t[0]) - fp2.mul(t[3], &r[1], t[4]) - fp2.sub(&r[1], t[2], t[3]) - fp2.mul(&r[2], &r[2], t[4]) - fp2.mul(t[2], t[1], &q[1]) - fp2.mul(t[3], t[0], &q[0]) - fp2.sub(&coeff[0], t[3], t[2]) - fp2.neg(&coeff[1], t[0]) - coeff[2].set(t[1]) -} - -func (e *Engine) preCompute(ellCoeffs *[68][3]fe2, twistPoint *PointG2) { - // Algorithm 5 in https://eprint.iacr.org/2019/077.pdf - if e.G2.IsZero(twistPoint) { - return - } - r := new(PointG2).Set(twistPoint) - j := 0 - for i := x.BitLen() - 2; i >= 0; i-- { - e.doublingStep(&ellCoeffs[j], r) - if x.Bit(i) != 0 { - j++ - ellCoeffs[j] = fe6{} - e.additionStep(&ellCoeffs[j], r, twistPoint) - } - j++ - } -} - -func (e *Engine) millerLoop(f *fe12) { - pairs := e.pairs - ellCoeffs := make([][68][3]fe2, len(pairs)) - for i := 0; i < len(pairs); i++ { - e.preCompute(&ellCoeffs[i], pairs[i].g2) - } - fp12, fp2 := e.fp12, e.fp2 - t := e.t2 - f.one() - j := 0 - for i := 62; /* x.BitLen() - 2 */ i >= 0; i-- { - if i != 62 { - fp12.square(f, f) - } - for i := 0; i <= len(pairs)-1; i++ { - fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1]) - fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0]) - fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0]) - } - if x.Bit(i) != 0 { - j++ - for i := 0; i <= len(pairs)-1; i++ { - fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1]) - fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0]) - fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0]) - } - } - j++ - } - fp12.conjugate(f, f) -} - -func (e *Engine) exp(c, a *fe12) { - fp12 := e.fp12 - fp12.cyclotomicExp(c, a, x) - fp12.conjugate(c, c) -} - -func (e *Engine) finalExp(f *fe12) { - fp12 := e.fp12 - t := e.t12 - // easy part - fp12.frobeniusMap(&t[0], f, 6) - fp12.inverse(&t[1], f) - fp12.mul(&t[2], &t[0], &t[1]) - t[1].set(&t[2]) - fp12.frobeniusMapAssign(&t[2], 2) - fp12.mulAssign(&t[2], &t[1]) - fp12.cyclotomicSquare(&t[1], &t[2]) - fp12.conjugate(&t[1], &t[1]) - // hard part - e.exp(&t[3], &t[2]) - fp12.cyclotomicSquare(&t[4], &t[3]) - fp12.mul(&t[5], &t[1], &t[3]) - e.exp(&t[1], &t[5]) - e.exp(&t[0], &t[1]) - e.exp(&t[6], &t[0]) - fp12.mulAssign(&t[6], &t[4]) - e.exp(&t[4], &t[6]) - fp12.conjugate(&t[5], &t[5]) - fp12.mulAssign(&t[4], &t[5]) - fp12.mulAssign(&t[4], &t[2]) - fp12.conjugate(&t[5], &t[2]) - fp12.mulAssign(&t[1], &t[2]) - fp12.frobeniusMapAssign(&t[1], 3) - fp12.mulAssign(&t[6], &t[5]) - fp12.frobeniusMapAssign(&t[6], 1) - fp12.mulAssign(&t[3], &t[0]) - fp12.frobeniusMapAssign(&t[3], 2) - fp12.mulAssign(&t[3], &t[1]) - fp12.mulAssign(&t[3], &t[6]) - fp12.mul(f, &t[3], &t[4]) -} - -func (e *Engine) calculate() *fe12 { - f := e.fp12.one() - if len(e.pairs) == 0 { - return f - } - e.millerLoop(f) - e.finalExp(f) - return f -} - -// Check computes pairing and checks if result is equal to one -func (e *Engine) Check() bool { - return e.calculate().isOne() -} - -// Result computes pairing and returns target group element as result. -func (e *Engine) Result() *E { - r := e.calculate() - e.Reset() - return r -} - -// GT returns target group instance. -func (e *Engine) GT() *GT { - return NewGT() -} diff --git a/crypto/bls12381/pairing_test.go b/crypto/bls12381/pairing_test.go deleted file mode 100644 index 77676fe9b1..0000000000 --- a/crypto/bls12381/pairing_test.go +++ /dev/null @@ -1,230 +0,0 @@ -package bls12381 - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func TestPairingExpected(t *testing.T) { - bls := NewPairingEngine() - G1, G2 := bls.G1, bls.G2 - GT := bls.GT() - expected, err := GT.FromBytes( - common.FromHex("" + - "0f41e58663bf08cf068672cbd01a7ec73baca4d72ca93544deff686bfd6df543d48eaa24afe47e1efde449383b676631" + - "04c581234d086a9902249b64728ffd21a189e87935a954051c7cdba7b3872629a4fafc05066245cb9108f0242d0fe3ef" + - "03350f55a7aefcd3c31b4fcb6ce5771cc6a0e9786ab5973320c806ad360829107ba810c5a09ffdd9be2291a0c25a99a2" + - "11b8b424cd48bf38fcef68083b0b0ec5c81a93b330ee1a677d0d15ff7b984e8978ef48881e32fac91b93b47333e2ba57" + - "06fba23eb7c5af0d9f80940ca771b6ffd5857baaf222eb95a7d2809d61bfe02e1bfd1b68ff02f0b8102ae1c2d5d5ab1a" + - "19f26337d205fb469cd6bd15c3d5a04dc88784fbb3d0b2dbdea54d43b2b73f2cbb12d58386a8703e0f948226e47ee89d" + - "018107154f25a764bd3c79937a45b84546da634b8f6be14a8061e55cceba478b23f7dacaa35c8ca78beae9624045b4b6" + - "01b2f522473d171391125ba84dc4007cfbf2f8da752f7c74185203fcca589ac719c34dffbbaad8431dad1c1fb597aaa5" + - "193502b86edb8857c273fa075a50512937e0794e1e65a7617c90d8bd66065b1fffe51d7a579973b1315021ec3c19934f" + - "1368bb445c7c2d209703f239689ce34c0378a68e72a6b3b216da0e22a5031b54ddff57309396b38c881c4c849ec23e87" + - "089a1c5b46e5110b86750ec6a532348868a84045483c92b7af5af689452eafabf1a8943e50439f1d59882a98eaa0170f" + - "1250ebd871fc0a92a7b2d83168d0d727272d441befa15c503dd8e90ce98db3e7b6d194f60839c508a84305aaca1789b6", - ), - ) - if err != nil { - t.Fatal(err) - } - r := bls.AddPair(G1.One(), G2.One()).Result() - if !r.Equal(expected) { - t.Fatal("bad pairing") - } - if !GT.IsValid(r) { - t.Fatal("element is not in correct subgroup") - } -} - -func TestPairingNonDegeneracy(t *testing.T) { - bls := NewPairingEngine() - G1, G2 := bls.G1, bls.G2 - g1Zero, g2Zero, g1One, g2One := G1.Zero(), G2.Zero(), G1.One(), G2.One() - GT := bls.GT() - // e(g1^a, g2^b) != 1 - bls.Reset() - { - bls.AddPair(g1One, g2One) - e := bls.Result() - if e.IsOne() { - t.Fatal("pairing result is not expected to be one") - } - if !GT.IsValid(e) { - t.Fatal("pairing result is not valid") - } - } - // e(g1^a, 0) == 1 - bls.Reset() - { - bls.AddPair(g1One, g2Zero) - e := bls.Result() - if !e.IsOne() { - t.Fatal("pairing result is expected to be one") - } - } - // e(0, g2^b) == 1 - bls.Reset() - { - bls.AddPair(g1Zero, g2One) - e := bls.Result() - if !e.IsOne() { - t.Fatal("pairing result is expected to be one") - } - } - // - bls.Reset() - { - bls.AddPair(g1Zero, g2One) - bls.AddPair(g1One, g2Zero) - bls.AddPair(g1Zero, g2Zero) - e := bls.Result() - if !e.IsOne() { - t.Fatal("pairing result is expected to be one") - } - } - // - bls.Reset() - { - expected, err := GT.FromBytes( - common.FromHex("" + - "0f41e58663bf08cf068672cbd01a7ec73baca4d72ca93544deff686bfd6df543d48eaa24afe47e1efde449383b676631" + - "04c581234d086a9902249b64728ffd21a189e87935a954051c7cdba7b3872629a4fafc05066245cb9108f0242d0fe3ef" + - "03350f55a7aefcd3c31b4fcb6ce5771cc6a0e9786ab5973320c806ad360829107ba810c5a09ffdd9be2291a0c25a99a2" + - "11b8b424cd48bf38fcef68083b0b0ec5c81a93b330ee1a677d0d15ff7b984e8978ef48881e32fac91b93b47333e2ba57" + - "06fba23eb7c5af0d9f80940ca771b6ffd5857baaf222eb95a7d2809d61bfe02e1bfd1b68ff02f0b8102ae1c2d5d5ab1a" + - "19f26337d205fb469cd6bd15c3d5a04dc88784fbb3d0b2dbdea54d43b2b73f2cbb12d58386a8703e0f948226e47ee89d" + - "018107154f25a764bd3c79937a45b84546da634b8f6be14a8061e55cceba478b23f7dacaa35c8ca78beae9624045b4b6" + - "01b2f522473d171391125ba84dc4007cfbf2f8da752f7c74185203fcca589ac719c34dffbbaad8431dad1c1fb597aaa5" + - "193502b86edb8857c273fa075a50512937e0794e1e65a7617c90d8bd66065b1fffe51d7a579973b1315021ec3c19934f" + - "1368bb445c7c2d209703f239689ce34c0378a68e72a6b3b216da0e22a5031b54ddff57309396b38c881c4c849ec23e87" + - "089a1c5b46e5110b86750ec6a532348868a84045483c92b7af5af689452eafabf1a8943e50439f1d59882a98eaa0170f" + - "1250ebd871fc0a92a7b2d83168d0d727272d441befa15c503dd8e90ce98db3e7b6d194f60839c508a84305aaca1789b6", - ), - ) - if err != nil { - t.Fatal(err) - } - bls.AddPair(g1Zero, g2One) - bls.AddPair(g1One, g2Zero) - bls.AddPair(g1Zero, g2Zero) - bls.AddPair(g1One, g2One) - e := bls.Result() - if !e.Equal(expected) { - t.Fatal("bad pairing") - } - } -} - -func TestPairingBilinearity(t *testing.T) { - bls := NewPairingEngine() - g1, g2 := bls.G1, bls.G2 - gt := bls.GT() - // e(a*G1, b*G2) = e(G1, G2)^c - { - a, b := big.NewInt(17), big.NewInt(117) - c := new(big.Int).Mul(a, b) - G1, G2 := g1.One(), g2.One() - e0 := bls.AddPair(G1, G2).Result() - P1, P2 := g1.New(), g2.New() - g1.MulScalar(P1, G1, a) - g2.MulScalar(P2, G2, b) - e1 := bls.AddPair(P1, P2).Result() - gt.Exp(e0, e0, c) - if !e0.Equal(e1) { - t.Fatal("bad pairing, 1") - } - } - // e(a * G1, b * G2) = e((a + b) * G1, G2) - { - // scalars - a, b := big.NewInt(17), big.NewInt(117) - c := new(big.Int).Mul(a, b) - // LHS - G1, G2 := g1.One(), g2.One() - g1.MulScalar(G1, G1, c) - bls.AddPair(G1, G2) - // RHS - P1, P2 := g1.One(), g2.One() - g1.MulScalar(P1, P1, a) - g2.MulScalar(P2, P2, b) - bls.AddPairInv(P1, P2) - // should be one - if !bls.Check() { - t.Fatal("bad pairing, 2") - } - } - // e(a * G1, b * G2) = e((a + b) * G1, G2) - { - // scalars - a, b := big.NewInt(17), big.NewInt(117) - c := new(big.Int).Mul(a, b) - // LHS - G1, G2 := g1.One(), g2.One() - g2.MulScalar(G2, G2, c) - bls.AddPair(G1, G2) - // RHS - H1, H2 := g1.One(), g2.One() - g1.MulScalar(H1, H1, a) - g2.MulScalar(H2, H2, b) - bls.AddPairInv(H1, H2) - // should be one - if !bls.Check() { - t.Fatal("bad pairing, 3") - } - } -} - -func TestPairingMulti(t *testing.T) { - // e(G1, G2) ^ t == e(a01 * G1, a02 * G2) * e(a11 * G1, a12 * G2) * ... * e(an1 * G1, an2 * G2) - // where t = sum(ai1 * ai2) - bls := NewPairingEngine() - g1, g2 := bls.G1, bls.G2 - numOfPair := 100 - targetExp := new(big.Int) - // RHS - for i := 0; i < numOfPair; i++ { - // (ai1 * G1, ai2 * G2) - a1, a2 := randScalar(q), randScalar(q) - P1, P2 := g1.One(), g2.One() - g1.MulScalar(P1, P1, a1) - g2.MulScalar(P2, P2, a2) - bls.AddPair(P1, P2) - // accumulate targetExp - // t += (ai1 * ai2) - a1.Mul(a1, a2) - targetExp.Add(targetExp, a1) - } - // LHS - // e(t * G1, G2) - T1, T2 := g1.One(), g2.One() - g1.MulScalar(T1, T1, targetExp) - bls.AddPairInv(T1, T2) - if !bls.Check() { - t.Fatal("fail multi pairing") - } -} - -func TestPairingEmpty(t *testing.T) { - bls := NewPairingEngine() - if !bls.Check() { - t.Fatal("empty check should be accepted") - } - if !bls.Result().IsOne() { - t.Fatal("empty pairing result should be one") - } -} - -func BenchmarkPairing(t *testing.B) { - bls := NewPairingEngine() - g1, g2, gt := bls.G1, bls.G2, bls.GT() - bls.AddPair(g1.One(), g2.One()) - e := gt.New() - t.ResetTimer() - for i := 0; i < t.N; i++ { - e = bls.calculate() - } - _ = e -} diff --git a/crypto/bls12381/swu.go b/crypto/bls12381/swu.go deleted file mode 100644 index e78753b240..0000000000 --- a/crypto/bls12381/swu.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bls12381 - -// swuMapG1 is implementation of Simplified Shallue-van de Woestijne-Ulas Method -// follows the implementation at draft-irtf-cfrg-hash-to-curve-06. -func swuMapG1(u *fe) (*fe, *fe) { - var params = swuParamsForG1 - var tv [4]*fe - for i := 0; i < 4; i++ { - tv[i] = new(fe) - } - square(tv[0], u) - mul(tv[0], tv[0], params.z) - square(tv[1], tv[0]) - x1 := new(fe) - add(x1, tv[0], tv[1]) - inverse(x1, x1) - e1 := x1.isZero() - one := new(fe).one() - add(x1, x1, one) - if e1 { - x1.set(params.zInv) - } - mul(x1, x1, params.minusBOverA) - gx1 := new(fe) - square(gx1, x1) - add(gx1, gx1, params.a) - mul(gx1, gx1, x1) - add(gx1, gx1, params.b) - x2 := new(fe) - mul(x2, tv[0], x1) - mul(tv[1], tv[0], tv[1]) - gx2 := new(fe) - mul(gx2, gx1, tv[1]) - e2 := !isQuadraticNonResidue(gx1) - x, y2 := new(fe), new(fe) - if e2 { - x.set(x1) - y2.set(gx1) - } else { - x.set(x2) - y2.set(gx2) - } - y := new(fe) - sqrt(y, y2) - if y.sign() != u.sign() { - neg(y, y) - } - return x, y -} - -// swuMapG2 is implementation of Simplified Shallue-van de Woestijne-Ulas Method -// defined at draft-irtf-cfrg-hash-to-curve-06. -func swuMapG2(e *fp2, u *fe2) (*fe2, *fe2) { - if e == nil { - e = newFp2() - } - params := swuParamsForG2 - var tv [4]*fe2 - for i := 0; i < 4; i++ { - tv[i] = e.new() - } - e.square(tv[0], u) - e.mul(tv[0], tv[0], params.z) - e.square(tv[1], tv[0]) - x1 := e.new() - e.add(x1, tv[0], tv[1]) - e.inverse(x1, x1) - e1 := x1.isZero() - e.add(x1, x1, e.one()) - if e1 { - x1.set(params.zInv) - } - e.mul(x1, x1, params.minusBOverA) - gx1 := e.new() - e.square(gx1, x1) - e.add(gx1, gx1, params.a) - e.mul(gx1, gx1, x1) - e.add(gx1, gx1, params.b) - x2 := e.new() - e.mul(x2, tv[0], x1) - e.mul(tv[1], tv[0], tv[1]) - gx2 := e.new() - e.mul(gx2, gx1, tv[1]) - e2 := !e.isQuadraticNonResidue(gx1) - x, y2 := e.new(), e.new() - if e2 { - x.set(x1) - y2.set(gx1) - } else { - x.set(x2) - y2.set(gx2) - } - y := e.new() - e.sqrt(y, y2) - if y.sign() != u.sign() { - e.neg(y, y) - } - return x, y -} - -var swuParamsForG1 = struct { - z *fe - zInv *fe - a *fe - b *fe - minusBOverA *fe -}{ - a: &fe{0x2f65aa0e9af5aa51, 0x86464c2d1e8416c3, 0xb85ce591b7bd31e2, 0x27e11c91b5f24e7c, 0x28376eda6bfc1835, 0x155455c3e5071d85}, - b: &fe{0xfb996971fe22a1e0, 0x9aa93eb35b742d6f, 0x8c476013de99c5c4, 0x873e27c3a221e571, 0xca72b5e45a52d888, 0x06824061418a386b}, - z: &fe{0x886c00000023ffdc, 0x0f70008d3090001d, 0x77672417ed5828c3, 0x9dac23e943dc1740, 0x50553f1b9c131521, 0x078c712fbe0ab6e8}, - zInv: &fe{0x0e8a2e8ba2e83e10, 0x5b28ba2ca4d745d1, 0x678cd5473847377a, 0x4c506dd8a8076116, 0x9bcb227d79284139, 0x0e8d3154b0ba099a}, - minusBOverA: &fe{0x052583c93555a7fe, 0x3b40d72430f93c82, 0x1b75faa0105ec983, 0x2527e7dc63851767, 0x99fffd1f34fc181d, 0x097cab54770ca0d3}, -} - -var swuParamsForG2 = struct { - z *fe2 - zInv *fe2 - a *fe2 - b *fe2 - minusBOverA *fe2 -}{ - a: &fe2{ - fe{0, 0, 0, 0, 0, 0}, - fe{0xe53a000003135242, 0x01080c0fdef80285, 0xe7889edbe340f6bd, 0x0b51375126310601, 0x02d6985717c744ab, 0x1220b4e979ea5467}, - }, - b: &fe2{ - fe{0x22ea00000cf89db2, 0x6ec832df71380aa4, 0x6e1b94403db5a66e, 0x75bf3c53a79473ba, 0x3dd3a569412c0a34, 0x125cdb5e74dc4fd1}, - fe{0x22ea00000cf89db2, 0x6ec832df71380aa4, 0x6e1b94403db5a66e, 0x75bf3c53a79473ba, 0x3dd3a569412c0a34, 0x125cdb5e74dc4fd1}, - }, - z: &fe2{ - fe{0x87ebfffffff9555c, 0x656fffe5da8ffffa, 0x0fd0749345d33ad2, 0xd951e663066576f4, 0xde291a3d41e980d3, 0x0815664c7dfe040d}, - fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}, - }, - zInv: &fe2{ - fe{0xacd0000000011110, 0x9dd9999dc88ccccd, 0xb5ca2ac9b76352bf, 0xf1b574bcf4bc90ce, 0x42dab41f28a77081, 0x132fc6ac14cd1e12}, - fe{0xe396ffffffff2223, 0x4fbf332fcd0d9998, 0x0c4bbd3c1aff4cc4, 0x6b9c91267926ca58, 0x29ae4da6aef7f496, 0x10692e942f195791}, - }, - minusBOverA: &fe2{ - fe{0x903c555555474fb3, 0x5f98cc95ce451105, 0x9f8e582eefe0fade, 0xc68946b6aebbd062, 0x467a4ad10ee6de53, 0x0e7146f483e23a05}, - fe{0x29c2aaaaaab85af8, 0xbf133368e30eeefa, 0xc7a27a7206cffb45, 0x9dee04ce44c9425c, 0x04a15ce53464ce83, 0x0b8fcaf5b59dac95}, - }, -} diff --git a/crypto/bn256/cloudflare/gfp_decl.go b/crypto/bn256/cloudflare/gfp_decl.go index cf7f565423..1954d14a4a 100644 --- a/crypto/bn256/cloudflare/gfp_decl.go +++ b/crypto/bn256/cloudflare/gfp_decl.go @@ -13,7 +13,7 @@ import ( //nolint:varcheck,unused,deadcode var hasBMI2 = cpu.X86.HasBMI2 -// go:noescape +//go:noescape func gfpNeg(c, a *gfP) //go:noescape diff --git a/crypto/bn256/google/bn256.go b/crypto/bn256/google/bn256.go index 93953e23a9..aca9cf62de 100644 --- a/crypto/bn256/google/bn256.go +++ b/crypto/bn256/google/bn256.go @@ -29,7 +29,7 @@ import ( ) // BUG(agl): this implementation is not constant time. -// TODO(agl): keep GF(p²) elements in Mongomery form. +// TODO(agl): keep GF(p²) elements in Montgomery form. // G1 is an abstract cyclic group. The zero value is suitable for use as the // output of an operation, but cannot be used as an input. diff --git a/crypto/crypto.go b/crypto/crypto.go index bd9b12756b..f7bfd34e29 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -48,7 +48,7 @@ const RecoveryIDOffset = 64 const DigestLength = 32 var ( - secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) + secp256k1N = S256().Params().N secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2)) keccakState256Cache = fastcache.New(100 * 1024 * 1024) @@ -61,6 +61,15 @@ var keccakState256Pool = sync.Pool{ return sha3.NewLegacyKeccak256().(KeccakState) }} +// EllipticCurve contains curve operations. +type EllipticCurve interface { + elliptic.Curve + + // Point marshaling/unmarshaing. + Marshal(x, y *big.Int) []byte + Unmarshal(data []byte) (x, y *big.Int) +} + // KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports // Read to get a variable amount of data from the hash state. Read is faster than Sum // because it doesn't copy the internal state, but also modifies the internal state. @@ -182,7 +191,7 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) { return nil, errors.New("invalid private key, zero or negative") } - priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) + priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(d) if priv.PublicKey.X == nil { return nil, errors.New("invalid private key") } @@ -199,7 +208,7 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte { // UnmarshalPubkey converts bytes to a secp256k1 public key. func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { - x, y := elliptic.Unmarshal(S256(), pub) //nolint:all //TODO + x, y := S256().Unmarshal(pub) if x == nil { return nil, errInvalidPubkey } @@ -210,7 +219,7 @@ func FromECDSAPub(pub *ecdsa.PublicKey) []byte { if pub == nil || pub.X == nil || pub.Y == nil { return nil } - return elliptic.Marshal(S256(), pub.X, pub.Y) //nolint:all //TODO + return S256().Marshal(pub.X, pub.Y) } // HexToECDSA parses a secp256k1 private key. @@ -312,7 +321,5 @@ func PubkeyToAddress(p ecdsa.PublicKey) common.Address { } func zeroBytes(bytes []byte) { - for i := range bytes { - bytes[i] = 0 - } + clear(bytes) } diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index fec6b75e2b..1b6c9e97c1 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -40,6 +40,8 @@ import ( "hash" "io" "math/big" + + "github.com/ethereum/go-ethereum/crypto" ) var ( @@ -95,15 +97,15 @@ func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { // Generate an elliptic curve public / private keypair. If params is nil, // the recommended default parameters for the key will be chosen. func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { - pb, x, y, err := elliptic.GenerateKey(curve, rand) //nolint:all //TODO + sk, err := ecdsa.GenerateKey(curve, rand) if err != nil { return } prv = new(PrivateKey) - prv.PublicKey.X = x - prv.PublicKey.Y = y + prv.PublicKey.X = sk.X + prv.PublicKey.Y = sk.Y prv.PublicKey.Curve = curve - prv.D = new(big.Int).SetBytes(pb) + prv.D = new(big.Int).Set(sk.D) if params == nil { params = ParamsFromCurve(curve) } @@ -255,12 +257,15 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e d := messageTag(params.Hash, Km, em, s2) - Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y) //nolint:all //TODO - ct = make([]byte, len(Rb)+len(em)+len(d)) - copy(ct, Rb) - copy(ct[len(Rb):], em) - copy(ct[len(Rb)+len(em):], d) - return ct, nil + if curve, ok := pub.Curve.(crypto.EllipticCurve); ok { + Rb := curve.Marshal(R.PublicKey.X, R.PublicKey.Y) + ct = make([]byte, len(Rb)+len(em)+len(d)) + copy(ct, Rb) + copy(ct[len(Rb):], em) + copy(ct[len(Rb)+len(em):], d) + return ct, nil + } + return nil, ErrInvalidCurve } // Decrypt decrypts an ECIES ciphertext. @@ -297,21 +302,24 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) { R := new(PublicKey) R.Curve = prv.PublicKey.Curve - R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen]) //nolint:all //TODO - if R.X == nil { - return nil, ErrInvalidPublicKey - } - z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) - if err != nil { - return nil, err - } - Ke, Km := deriveKeys(hash, z, s1, params.KeyLen) + if curve, ok := R.Curve.(crypto.EllipticCurve); ok { + R.X, R.Y = curve.Unmarshal(c[:rLen]) + if R.X == nil { + return nil, ErrInvalidPublicKey + } - d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) - if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { - return nil, ErrInvalidMessage - } + z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) + if err != nil { + return nil, err + } + Ke, Km := deriveKeys(hash, z, s1, params.KeyLen) - return symDecrypt(params, Ke, c[mStart:mEnd]) + d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) + if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { + return nil, ErrInvalidMessage + } + return symDecrypt(params, Ke, c[mStart:mEnd]) + } + return nil, ErrInvalidCurve } diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index 52124df674..39fdfbe740 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -85,7 +85,7 @@ type Claim [32]byte var useCKZG atomic.Bool // UseCKZG can be called to switch the default Go implementation of KZG to the C -// library if fo some reason the user wishes to do so (e.g. consensus bug in one +// library if for some reason the user wishes to do so (e.g. consensus bug in one // or the other). func UseCKZG(use bool) error { if use && !ckzgAvailable { @@ -105,7 +105,7 @@ func UseCKZG(use bool) error { } // BlobToCommitment creates a small commitment out of a data blob. -func BlobToCommitment(blob Blob) (Commitment, error) { +func BlobToCommitment(blob *Blob) (Commitment, error) { if useCKZG.Load() { return ckzgBlobToCommitment(blob) } @@ -114,7 +114,7 @@ func BlobToCommitment(blob Blob) (Commitment, error) { // ComputeProof computes the KZG proof at the given point for the polynomial // represented by the blob. -func ComputeProof(blob Blob, point Point) (Proof, Claim, error) { +func ComputeProof(blob *Blob, point Point) (Proof, Claim, error) { if useCKZG.Load() { return ckzgComputeProof(blob, point) } @@ -134,7 +134,7 @@ func VerifyProof(commitment Commitment, point Point, claim Claim, proof Proof) e // the commitment. // // This method does not verify that the commitment is correct with respect to blob. -func ComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { +func ComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { if useCKZG.Load() { return ckzgComputeBlobProof(blob, commitment) } @@ -142,7 +142,7 @@ func ComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { } // VerifyBlobProof verifies that the blob data corresponds to the provided commitment. -func VerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error { +func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { if useCKZG.Load() { return ckzgVerifyBlobProof(blob, commitment, proof) } diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index 5400285698..11bc451b58 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -61,10 +61,10 @@ func ckzgInit() { } // ckzgBlobToCommitment creates a small commitment out of a data blob. -func ckzgBlobToCommitment(blob Blob) (Commitment, error) { +func ckzgBlobToCommitment(blob *Blob) (Commitment, error) { ckzgIniter.Do(ckzgInit) - commitment, err := ckzg4844.BlobToKZGCommitment((ckzg4844.Blob)(blob)) + commitment, err := ckzg4844.BlobToKZGCommitment((*ckzg4844.Blob)(blob)) if err != nil { return Commitment{}, err } @@ -73,10 +73,10 @@ func ckzgBlobToCommitment(blob Blob) (Commitment, error) { // ckzgComputeProof computes the KZG proof at the given point for the polynomial // represented by the blob. -func ckzgComputeProof(blob Blob, point Point) (Proof, Claim, error) { +func ckzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) { ckzgIniter.Do(ckzgInit) - proof, claim, err := ckzg4844.ComputeKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes32)(point)) + proof, claim, err := ckzg4844.ComputeKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes32)(point)) if err != nil { return Proof{}, Claim{}, err } @@ -102,10 +102,10 @@ func ckzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Proo // the commitment. // // This method does not verify that the commitment is correct with respect to blob. -func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { +func ckzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { ckzgIniter.Do(ckzgInit) - proof, err := ckzg4844.ComputeBlobKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment)) + proof, err := ckzg4844.ComputeBlobKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment)) if err != nil { return Proof{}, err } @@ -113,10 +113,10 @@ func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { } // ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment. -func ckzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error { +func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { ckzgIniter.Do(ckzgInit) - valid, err := ckzg4844.VerifyBlobKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment), (ckzg4844.Bytes48)(proof)) + valid, err := ckzg4844.VerifyBlobKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment), (ckzg4844.Bytes48)(proof)) if err != nil { return err } diff --git a/crypto/kzg4844/kzg4844_ckzg_nocgo.go b/crypto/kzg4844/kzg4844_ckzg_nocgo.go index ed840c75bb..70a78e80d1 100644 --- a/crypto/kzg4844/kzg4844_ckzg_nocgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_nocgo.go @@ -32,13 +32,13 @@ func ckzgInit() { } // ckzgBlobToCommitment creates a small commitment out of a data blob. -func ckzgBlobToCommitment(blob Blob) (Commitment, error) { +func ckzgBlobToCommitment(blob *Blob) (Commitment, error) { panic("unsupported platform") } // ckzgComputeProof computes the KZG proof at the given point for the polynomial // represented by the blob. -func ckzgComputeProof(blob Blob, point Point) (Proof, Claim, error) { +func ckzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) { panic("unsupported platform") } @@ -52,11 +52,11 @@ func ckzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Proo // the commitment. // // This method does not verify that the commitment is correct with respect to blob. -func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { +func ckzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { panic("unsupported platform") } // ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment. -func ckzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error { +func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { panic("unsupported platform") } diff --git a/crypto/kzg4844/kzg4844_gokzg.go b/crypto/kzg4844/kzg4844_gokzg.go index 3f03bb5273..6f88469269 100644 --- a/crypto/kzg4844/kzg4844_gokzg.go +++ b/crypto/kzg4844/kzg4844_gokzg.go @@ -46,10 +46,10 @@ func gokzgInit() { } // gokzgBlobToCommitment creates a small commitment out of a data blob. -func gokzgBlobToCommitment(blob Blob) (Commitment, error) { +func gokzgBlobToCommitment(blob *Blob) (Commitment, error) { gokzgIniter.Do(gokzgInit) - commitment, err := context.BlobToKZGCommitment((gokzg4844.Blob)(blob), 0) + commitment, err := context.BlobToKZGCommitment(*(*gokzg4844.Blob)(blob), 0) if err != nil { return Commitment{}, err } @@ -58,10 +58,10 @@ func gokzgBlobToCommitment(blob Blob) (Commitment, error) { // gokzgComputeProof computes the KZG proof at the given point for the polynomial // represented by the blob. -func gokzgComputeProof(blob Blob, point Point) (Proof, Claim, error) { +func gokzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) { gokzgIniter.Do(gokzgInit) - proof, claim, err := context.ComputeKZGProof((gokzg4844.Blob)(blob), (gokzg4844.Scalar)(point), 0) + proof, claim, err := context.ComputeKZGProof(*(*gokzg4844.Blob)(blob), (gokzg4844.Scalar)(point), 0) if err != nil { return Proof{}, Claim{}, err } @@ -80,10 +80,10 @@ func gokzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Pro // the commitment. // // This method does not verify that the commitment is correct with respect to blob. -func gokzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { +func gokzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { gokzgIniter.Do(gokzgInit) - proof, err := context.ComputeBlobKZGProof((gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), 0) + proof, err := context.ComputeBlobKZGProof(*(*gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), 0) if err != nil { return Proof{}, err } @@ -91,8 +91,8 @@ func gokzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) { } // gokzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment. -func gokzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error { +func gokzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { gokzgIniter.Do(gokzgInit) - return context.VerifyBlobKZGProof((gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), (gokzg4844.KZGProof)(proof)) + return context.VerifyBlobKZGProof(*(*gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), (gokzg4844.KZGProof)(proof)) } diff --git a/crypto/kzg4844/kzg4844_test.go b/crypto/kzg4844/kzg4844_test.go index fae8a7a76e..a6782d4768 100644 --- a/crypto/kzg4844/kzg4844_test.go +++ b/crypto/kzg4844/kzg4844_test.go @@ -36,13 +36,13 @@ func randFieldElement() [32]byte { return gokzg4844.SerializeScalar(r) } -func randBlob() Blob { +func randBlob() *Blob { var blob Blob for i := 0; i < len(blob); i += gokzg4844.SerializedScalarSize { fieldElementBytes := randFieldElement() copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:]) } - return blob + return &blob } func TestCKZGWithPoint(t *testing.T) { testKZGWithPoint(t, true) } diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index 9b26ab2928..85ba885d6f 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -79,52 +79,52 @@ type BitCurve struct { BitSize int // the size of the underlying field } -func (BitCurve *BitCurve) Params() *elliptic.CurveParams { +func (bitCurve *BitCurve) Params() *elliptic.CurveParams { return &elliptic.CurveParams{ - P: BitCurve.P, - N: BitCurve.N, - B: BitCurve.B, - Gx: BitCurve.Gx, - Gy: BitCurve.Gy, - BitSize: BitCurve.BitSize, + P: bitCurve.P, + N: bitCurve.N, + B: bitCurve.B, + Gx: bitCurve.Gx, + Gy: bitCurve.Gy, + BitSize: bitCurve.BitSize, } } // IsOnCurve returns true if the given (x,y) lies on the BitCurve. -func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { +func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { // y² = x³ + b y2 := new(big.Int).Mul(y, y) //y² - y2.Mod(y2, BitCurve.P) //y²%P + y2.Mod(y2, bitCurve.P) //y²%P x3 := new(big.Int).Mul(x, x) //x² x3.Mul(x3, x) //x³ - x3.Add(x3, BitCurve.B) //x³+B - x3.Mod(x3, BitCurve.P) //(x³+B)%P + x3.Add(x3, bitCurve.B) //x³+B + x3.Mod(x3, bitCurve.P) //(x³+B)%P return x3.Cmp(y2) == 0 } // affineFromJacobian reverses the Jacobian transform. See the comment at the // top of the file. -func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { +func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { if z.Sign() == 0 { return new(big.Int), new(big.Int) } - zinv := new(big.Int).ModInverse(z, BitCurve.P) + zinv := new(big.Int).ModInverse(z, bitCurve.P) zinvsq := new(big.Int).Mul(zinv, zinv) xOut = new(big.Int).Mul(x, zinvsq) - xOut.Mod(xOut, BitCurve.P) + xOut.Mod(xOut, bitCurve.P) zinvsq.Mul(zinvsq, zinv) yOut = new(big.Int).Mul(y, zinvsq) - yOut.Mod(yOut, BitCurve.P) + yOut.Mod(yOut, bitCurve.P) return } // Add returns the sum of (x1,y1) and (x2,y2) -func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { // If one point is at infinity, return the other point. // Adding the point at infinity to any point will preserve the other point. if x1.Sign() == 0 && y1.Sign() == 0 { @@ -135,27 +135,27 @@ func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { } z := new(big.Int).SetInt64(1) if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 { - return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z)) + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z)) } - return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) + return bitCurve.affineFromJacobian(bitCurve.addJacobian(x1, y1, z, x2, y2, z)) } // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and // (x2, y2, z2) and returns their sum, also in Jacobian form. -func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { +func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl z1z1 := new(big.Int).Mul(z1, z1) - z1z1.Mod(z1z1, BitCurve.P) + z1z1.Mod(z1z1, bitCurve.P) z2z2 := new(big.Int).Mul(z2, z2) - z2z2.Mod(z2z2, BitCurve.P) + z2z2.Mod(z2z2, bitCurve.P) u1 := new(big.Int).Mul(x1, z2z2) - u1.Mod(u1, BitCurve.P) + u1.Mod(u1, bitCurve.P) u2 := new(big.Int).Mul(x2, z1z1) - u2.Mod(u2, BitCurve.P) + u2.Mod(u2, bitCurve.P) h := new(big.Int).Sub(u2, u1) if h.Sign() == -1 { - h.Add(h, BitCurve.P) + h.Add(h, bitCurve.P) } i := new(big.Int).Lsh(h, 1) i.Mul(i, i) @@ -163,13 +163,13 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int s1 := new(big.Int).Mul(y1, z2) s1.Mul(s1, z2z2) - s1.Mod(s1, BitCurve.P) + s1.Mod(s1, bitCurve.P) s2 := new(big.Int).Mul(y2, z1) s2.Mul(s2, z1z1) - s2.Mod(s2, BitCurve.P) + s2.Mod(s2, bitCurve.P) r := new(big.Int).Sub(s2, s1) if r.Sign() == -1 { - r.Add(r, BitCurve.P) + r.Add(r, bitCurve.P) } r.Lsh(r, 1) v := new(big.Int).Mul(u1, i) @@ -179,7 +179,7 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int x3.Sub(x3, j) x3.Sub(x3, v) x3.Sub(x3, v) - x3.Mod(x3, BitCurve.P) + x3.Mod(x3, bitCurve.P) y3 := new(big.Int).Set(r) v.Sub(v, x3) @@ -187,33 +187,33 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int s1.Mul(s1, j) s1.Lsh(s1, 1) y3.Sub(y3, s1) - y3.Mod(y3, BitCurve.P) + y3.Mod(y3, bitCurve.P) z3 := new(big.Int).Add(z1, z2) z3.Mul(z3, z3) z3.Sub(z3, z1z1) if z3.Sign() == -1 { - z3.Add(z3, BitCurve.P) + z3.Add(z3, bitCurve.P) } z3.Sub(z3, z2z2) if z3.Sign() == -1 { - z3.Add(z3, BitCurve.P) + z3.Add(z3, bitCurve.P) } z3.Mul(z3, h) - z3.Mod(z3, BitCurve.P) + z3.Mod(z3, bitCurve.P) return x3, y3, z3 } // Double returns 2*(x,y) -func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { z1 := new(big.Int).SetInt64(1) - return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1)) } // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and // returns its double, also in Jacobian form. -func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { +func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l a := new(big.Int).Mul(x, x) //X1² @@ -231,30 +231,30 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D x3.Sub(f, x3) //F-2*D - x3.Mod(x3, BitCurve.P) + x3.Mod(x3, bitCurve.P) y3 := new(big.Int).Sub(d, x3) //D-X3 y3.Mul(e, y3) //E*(D-X3) y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C - y3.Mod(y3, BitCurve.P) + y3.Mod(y3, bitCurve.P) z3 := new(big.Int).Mul(y, z) //Y1*Z1 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 - z3.Mod(z3, BitCurve.P) + z3.Mod(z3, bitCurve.P) return x3, y3, z3 } // ScalarBaseMult returns k*G, where G is the base point of the group and k is // an integer in big-endian form. -func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { - return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) +func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k) } // Marshal converts a point into the form specified in section 4.3.6 of ANSI // X9.62. -func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { - byteLen := (BitCurve.BitSize + 7) >> 3 +func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte { + byteLen := (bitCurve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point flag readBits(x, ret[1:1+byteLen]) @@ -264,8 +264,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { // Unmarshal converts a point, serialised by Marshal, into an x, y pair. On // error, x = nil. -func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { - byteLen := (BitCurve.BitSize + 7) >> 3 +func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { + byteLen := (bitCurve.BitSize + 7) >> 3 if len(data) != 1+2*byteLen { return } diff --git a/crypto/secp256k1/libsecp256k1/include/secp256k1.h b/crypto/secp256k1/libsecp256k1/include/secp256k1.h index f268e309d0..76af839691 100644 --- a/crypto/secp256k1/libsecp256k1/include/secp256k1.h +++ b/crypto/secp256k1/libsecp256k1/include/secp256k1.h @@ -357,7 +357,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( /** Verify an ECDSA signature. * * Returns: 1: correct signature - * 0: incorrect or unparseable signature + * 0: incorrect or unparsable signature * Args: ctx: a secp256k1 context object, initialized for verification. * In: sig: the signature being verified (cannot be NULL) * msg32: the 32-byte message hash being verified (cannot be NULL) diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go index 8afa9d023b..d11c11faf8 100644 --- a/crypto/secp256k1/scalar_mult_cgo.go +++ b/crypto/secp256k1/scalar_mult_cgo.go @@ -21,7 +21,7 @@ extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned */ import "C" -func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { // Ensure scalar is exactly 32 bytes. We pad always, even if // scalar is 32 bytes long, to avoid a timing side channel. if len(scalar) > 32 { @@ -44,12 +44,8 @@ func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, // Unpack the result and clear temporaries. x := new(big.Int).SetBytes(point[:32]) y := new(big.Int).SetBytes(point[32:]) - for i := range point { - point[i] = 0 - } - for i := range padded { - scalar[i] = 0 - } + clear(point) + clear(scalar) if res != 1 { return nil, nil } diff --git a/crypto/secp256k1/scalar_mult_nocgo.go b/crypto/secp256k1/scalar_mult_nocgo.go index 22f53ac6ae..feb13a8dfd 100644 --- a/crypto/secp256k1/scalar_mult_nocgo.go +++ b/crypto/secp256k1/scalar_mult_nocgo.go @@ -9,6 +9,6 @@ package secp256k1 import "math/big" -func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { panic("ScalarMult is not available when secp256k1 is built without cgo") } diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index a135291a79..4827cc5b25 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -10,7 +10,6 @@ package secp256k1 import ( "bytes" "crypto/ecdsa" - "crypto/elliptic" "crypto/rand" "encoding/hex" "io" @@ -24,7 +23,7 @@ func generateKeyPair() (pubkey, privkey []byte) { if err != nil { panic(err) } - pubkey = elliptic.Marshal(S256(), key.X, key.Y) //nolint:all //TODO + pubkey = S256().Marshal(key.X, key.Y) privkey = make([]byte, 32) blob := key.D.Bytes() @@ -49,7 +48,7 @@ func randSig() []byte { } // tests for malleability -// highest bit of signature ECDSA s value must be 0, in the 33th byte +// the highest bit of signature ECDSA s value must be 0, in the 33th byte func compactSigCheck(t *testing.T, sig []byte) { var b = int(sig[32]) if b < 0 { diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go index 0cf0599e32..87289253c0 100644 --- a/crypto/signature_cgo.go +++ b/crypto/signature_cgo.go @@ -21,7 +21,6 @@ package crypto import ( "crypto/ecdsa" - "crypto/elliptic" "errors" "fmt" @@ -40,9 +39,7 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - - x, y := elliptic.Unmarshal(S256(), s) //nolint:all, TODO - return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil + return UnmarshalPubkey(s) } // Sign calculates an ECDSA signature. @@ -84,6 +81,6 @@ func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { } // S256 returns an instance of the secp256k1 curve. -func S256() elliptic.Curve { +func S256() EllipticCurve { return secp256k1.S256() } diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 6d628d758d..5ac3765c71 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -21,9 +21,9 @@ package crypto import ( "crypto/ecdsa" - "crypto/elliptic" "errors" "fmt" + "math/big" "github.com/btcsuite/btcd/btcec/v2" btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" @@ -58,7 +58,13 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - return pub.ToECDSA(), nil + // We need to explicitly set the curve here, because we're wrapping + // the original curve to add (un-)marshalling + return &ecdsa.PublicKey{ + Curve: S256(), + X: pub.X(), + Y: pub.Y(), + }, nil } // Sign calculates an ECDSA signature. @@ -73,7 +79,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { if len(hash) != 32 { return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) } - if prv.Curve != btcec.S256() { + if prv.Curve != S256() { return nil, errors.New("private key curve is not secp256k1") } // ecdsa.PrivateKey -> btcec.PrivateKey @@ -82,10 +88,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { return nil, errors.New("invalid private key") } defer priv.Zero() - sig, err := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey - if err != nil { - return nil, err - } + sig := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey // Convert to Ethereum signature format with 'recovery id' v at the end. v := sig[0] - 27 copy(sig, sig[1:]) @@ -128,7 +131,13 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - return key.ToECDSA(), nil + // We need to explicitly set the curve here, because we're wrapping + // the original curve to add (un-)marshalling + return &ecdsa.PublicKey{ + Curve: S256(), + X: key.X(), + Y: key.Y(), + }, nil } // CompressPubkey encodes a public key to the 33-byte compressed format. The @@ -147,6 +156,38 @@ func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { } // S256 returns an instance of the secp256k1 curve. -func S256() elliptic.Curve { - return btcec.S256() +func S256() EllipticCurve { + return btCurve{btcec.S256()} +} + +type btCurve struct { + *btcec.KoblitzCurve +} + +// Marshal converts a point given as (x, y) into a byte slice. +func (curve btCurve) Marshal(x, y *big.Int) []byte { + byteLen := (curve.Params().BitSize + 7) / 8 + + ret := make([]byte, 1+2*byteLen) + ret[0] = 4 // uncompressed point + + x.FillBytes(ret[1 : 1+byteLen]) + y.FillBytes(ret[1+byteLen : 1+2*byteLen]) + + return ret +} + +// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On +// error, x = nil. +func (curve btCurve) Unmarshal(data []byte) (x, y *big.Int) { + byteLen := (curve.Params().BitSize + 7) / 8 + if len(data) != 1+2*byteLen { + return nil, nil + } + if data[0] != 4 { // uncompressed form + return nil, nil + } + x = new(big.Int).SetBytes(data[1 : 1+byteLen]) + y = new(big.Int).SetBytes(data[1+byteLen:]) + return } diff --git a/crypto/signature_test.go b/crypto/signature_test.go index aecff76bfb..74d683b507 100644 --- a/crypto/signature_test.go +++ b/crypto/signature_test.go @@ -71,7 +71,7 @@ func TestVerifySignature(t *testing.T) { wrongkey := common.CopyBytes(testpubkey) wrongkey[10]++ if VerifySignature(wrongkey, testmsg, sig) { - t.Errorf("signature valid with with wrong public key") + t.Errorf("signature valid with wrong public key") } } diff --git a/crypto/signify/signify_fuzz.go b/crypto/signify/signify_fuzz.go index 457af044d1..239a2134df 100644 --- a/crypto/signify/signify_fuzz.go +++ b/crypto/signify/signify_fuzz.go @@ -134,6 +134,7 @@ func createKeyPair() (string, string) { defer os.Remove(tmpKey.Name()) defer os.Remove(tmpKey.Name() + ".pub") defer os.Remove(tmpKey.Name() + ".sec") + defer tmpKey.Close() cmd := exec.Command("signify", "-G", "-n", "-p", tmpKey.Name()+".pub", "-s", tmpKey.Name()+".sec") if output, err := cmd.CombinedOutput(); err != nil { panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output)) diff --git a/docs/postmortems/2021-08-22-split-postmortem.md b/docs/postmortems/2021-08-22-split-postmortem.md index 0986f00b65..5ec4f37e87 100644 --- a/docs/postmortems/2021-08-22-split-postmortem.md +++ b/docs/postmortems/2021-08-22-split-postmortem.md @@ -62,7 +62,7 @@ Since we had merged the removal of `ETH65`, if the entire network were to upgrad - Announce an upcoming security release on Tuesday (August 24th), via Twitter and official channels, plus reach out to downstream projects. - Temporarily revert the `ETH65`-removal. -- Place the fix into the PR optimizing the jumpdest analysis [233381](https://github.com/ethereum/go-ethereum/pull/23381). +- Place the fix into the PR optimizing the jumpdest analysis [23381](https://github.com/ethereum/go-ethereum/pull/23381). - After 4-8 weeks, release details about the vulnerability. diff --git a/eth/api.go b/eth/api.go index 44e934fd04..6fa2be73f8 100644 --- a/eth/api.go +++ b/eth/api.go @@ -18,7 +18,6 @@ package eth import ( "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" ) // EthereumAPI provides an API to access Ethereum full node-related information. @@ -41,11 +40,6 @@ func (api *EthereumAPI) Coinbase() (common.Address, error) { return api.Etherbase() } -// Hashrate returns the POW hashrate. -func (api *EthereumAPI) Hashrate() hexutil.Uint64 { - return hexutil.Uint64(api.e.Miner().Hashrate()) -} - // Mining returns an indication if this node is currently mining. func (api *EthereumAPI) Mining() bool { return api.e.IsMining() diff --git a/eth/api_backend.go b/eth/api_backend.go index 6a137155ed..673ce2c550 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/parlia" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" @@ -69,7 +70,7 @@ func (b *EthAPIBackend) SetHead(number uint64) { func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { // Pending block is only known by the miner if number == rpc.PendingBlockNumber { - block := b.eth.miner.PendingBlock() + block, _, _ := b.eth.miner.Pending() if block == nil { return nil, errors.New("pending block is not available") } @@ -120,7 +121,7 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { // Pending block is only known by the miner if number == rpc.PendingBlockNumber { - block := b.eth.miner.PendingBlock() + block, _, _ := b.eth.miner.Pending() if block == nil { return nil, errors.New("pending block is not available") } @@ -184,14 +185,14 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r return nil, errors.New("invalid arguments; neither block nor hash specified") } -func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { - return b.eth.miner.PendingBlockAndReceipts() +func (b *EthAPIBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { + return b.eth.miner.Pending() } func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { // Pending state is only known by the miner if number == rpc.PendingBlockNumber { - block, state := b.eth.miner.Pending() + block, _, state := b.eth.miner.Pending() if block == nil || state == nil { return nil, nil, errors.New("pending state is not available") } @@ -272,10 +273,6 @@ func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEven return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch) } -func (b *EthAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { - return b.eth.miner.SubscribePendingLogs(ch) -} - func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return b.eth.BlockChain().SubscribeChainEvent(ch) } @@ -386,7 +383,7 @@ func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) return b.gpo.SuggestTipCap(ctx) } -func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) { +func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, baseFeePerBlobGas []*big.Int, blobGasUsedRatio []float64, err error) { return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles) } @@ -394,6 +391,13 @@ func (b *EthAPIBackend) Chain() *core.BlockChain { return b.eth.BlockChain() } +func (b *EthAPIBackend) BlobBaseFee(ctx context.Context) *big.Int { + if excess := b.CurrentHeader().ExcessBlobGas; excess != nil { + return eip4844.CalcBlobFee(*excess) + } + return nil +} + func (b *EthAPIBackend) ChainDb() ethdb.Database { return b.eth.ChainDb() } @@ -467,7 +471,7 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re return b.eth.stateAtBlock(ctx, block, reexec, base, readOnly, preferDisk) } -func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { +func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) } diff --git a/eth/api_debug.go b/eth/api_debug.go index baedd2632f..d1da2a6059 100644 --- a/eth/api_debug.go +++ b/eth/api_debug.go @@ -56,7 +56,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) { // If we're dumping the pending state, we need to request // both the pending block as well as the pending state from // the miner and operate on those - _, stateDb := api.eth.miner.Pending() + _, _, stateDb := api.eth.miner.Pending() if stateDb == nil { return state.Dump{}, errors.New("pending state is not available") } @@ -144,7 +144,7 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hex // If we're dumping the pending state, we need to request // both the pending block as well as the pending state from // the miner and operate on those - _, stateDb = api.eth.miner.Pending() + _, _, stateDb = api.eth.miner.Pending() if stateDb == nil { return state.Dump{}, errors.New("pending state is not available") } diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index 238d0e4ca8..6b209b7720 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "reflect" + "slices" "strings" "testing" @@ -27,11 +28,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" - "golang.org/x/exp/slices" ) var dumper = spew.ConfigState{Indent: " "} @@ -63,8 +64,9 @@ func TestAccountRange(t *testing.T) { t.Parallel() var ( - statedb = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &triedb.Config{Preimages: true}) - sdb, _ = state.New(types.EmptyRootHash, statedb, nil) + mdb = rawdb.NewMemoryDatabase() + statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), nil) + sdb, _ = state.New(types.EmptyRootHash, statedb) addrs = [AccountRangeMaxResults * 2]common.Address{} m = map[common.Address]bool{} ) @@ -73,17 +75,15 @@ func TestAccountRange(t *testing.T) { hash := common.HexToHash(fmt.Sprintf("%x", i)) addr := common.BytesToAddress(crypto.Keccak256Hash(hash.Bytes()).Bytes()) addrs[i] = addr - sdb.SetBalance(addrs[i], uint256.NewInt(1)) + sdb.SetBalance(addrs[i], uint256.NewInt(1), tracing.BalanceChangeUnspecified) if _, ok := m[addr]; ok { t.Fatalf("bad") } else { m[addr] = true } } - sdb.Finalise(true) - sdb.AccountsIntermediateRoot() - root, _, _ := sdb.Commit(0, nil) - sdb, _ = state.New(root, statedb, nil) + root, _, _ := sdb.Commit(0, true) + sdb, _ = state.New(root, statedb) trie, err := statedb.OpenTrie(root) if err != nil { @@ -136,13 +136,12 @@ func TestEmptyAccountRange(t *testing.T) { t.Parallel() var ( - statedb = state.NewDatabase(rawdb.NewMemoryDatabase()) - st, _ = state.New(types.EmptyRootHash, statedb, nil) + statedb = state.NewDatabaseForTesting() + st, _ = state.New(types.EmptyRootHash, statedb) ) // Commit(although nothing to flush) and re-init the statedb - st.IntermediateRoot(true) - st.Commit(0, nil) - st, _ = state.New(types.EmptyRootHash, statedb, nil) + st.Commit(0, true) + st, _ = state.New(types.EmptyRootHash, statedb) results := st.RawDump(&state.DumpConfig{ SkipCode: true, @@ -163,8 +162,10 @@ func TestStorageRangeAt(t *testing.T) { // Create a state where account 0x010000... has a few storage entries. var ( - db = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &triedb.Config{Preimages: true}) - sdb, _ = state.New(types.EmptyRootHash, db, nil) + mdb = rawdb.NewMemoryDatabase() + tdb = triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}) + db = state.NewDatabase(tdb, nil) + sdb, _ = state.New(types.EmptyRootHash, db) addr = common.Address{0x01} keys = []common.Hash{ // hashes of Keys of storage common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"), @@ -182,10 +183,8 @@ func TestStorageRangeAt(t *testing.T) { for _, entry := range storage { sdb.SetState(addr, *entry.Key, entry.Value) } - sdb.Finalise(false) - sdb.AccountsIntermediateRoot() - root, _, _ := sdb.Commit(0, nil) - sdb, _ = state.New(root, db, nil) + root, _, _ := sdb.Commit(0, false) + sdb, _ = state.New(root, db) // Check a few combinations of limit and start/end. tests := []struct { diff --git a/eth/backend.go b/eth/backend.go index 14053f1450..c33fe32920 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -18,6 +18,7 @@ package eth import ( + "encoding/json" "errors" "fmt" "math/big" @@ -50,6 +51,7 @@ import ( "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/eth/protocols/trust" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/ethapi" @@ -79,17 +81,13 @@ type Config = ethconfig.Config // Ethereum implements the Ethereum full node service. type Ethereum struct { - config *ethconfig.Config - - // Handlers - txPool *txpool.TxPool - blockchain *core.BlockChain - handler *handler - ethDialCandidates enode.Iterator - snapDialCandidates enode.Iterator - trustDialCandidates enode.Iterator - bscDialCandidates enode.Iterator - merger *consensus.Merger + // core protocol objects + config *ethconfig.Config + txPool *txpool.TxPool + blockchain *core.BlockChain + + handler *handler + discmix *enode.FairMix // DB interfaces chainDb ethdb.Database // Block chain database @@ -120,20 +118,17 @@ type Ethereum struct { votePool *vote.VotePool } -// New creates a new Ethereum object (including the -// initialisation of the common Ethereum object) +// New creates a new Ethereum object (including the initialisation of the common Ethereum object), +// whose lifecycle will be managed by the provided node. func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { // Ensure configuration values are compatible and sane - if config.SyncMode == downloader.LightSync { - return nil, errors.New("can't run eth.Ethereum in light sync mode, light mode has been deprecated") - } if !config.SyncMode.IsValid() { return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) } if !config.TriesVerifyMode.IsValid() { return nil, fmt.Errorf("invalid tries verify mode %d", config.TriesVerifyMode) } - if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 { + if config.Miner.GasPrice == nil || config.Miner.GasPrice.Sign() <= 0 { log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice) config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice) } @@ -183,32 +178,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - // Override the chain config with provided settings. - var overrides core.ChainOverrides - if config.OverridePassedForkTime != nil { - chainConfig.ShanghaiTime = config.OverridePassedForkTime - chainConfig.KeplerTime = config.OverridePassedForkTime - chainConfig.FeynmanTime = config.OverridePassedForkTime - chainConfig.FeynmanFixTime = config.OverridePassedForkTime - chainConfig.CancunTime = config.OverridePassedForkTime - chainConfig.HaberTime = config.OverridePassedForkTime - chainConfig.HaberFixTime = config.OverridePassedForkTime - chainConfig.BohrTime = config.OverridePassedForkTime - overrides.OverridePassedForkTime = config.OverridePassedForkTime - } - if config.OverridePascal != nil { - chainConfig.PascalTime = config.OverridePascal - overrides.OverridePascal = config.OverridePascal - } - if config.OverridePrague != nil { - chainConfig.PragueTime = config.OverridePrague - overrides.OverridePrague = config.OverridePrague - } - if config.OverrideVerkle != nil { - chainConfig.VerkleTime = config.OverrideVerkle - overrides.OverrideVerkle = config.OverrideVerkle - } - // startup ancient freeze if err = chainDb.SetupFreezerEnv(ðdb.FreezerEnv{ ChainCfg: chainConfig, @@ -223,7 +192,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } eth := &Ethereum{ config: config, - merger: consensus.NewMerger(chainDb), chainDb: chainDb, eventMux: stack.EventMux(), accountManager: stack.AccountManager(), @@ -234,6 +202,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { bloomRequests: make(chan chan *bloombits.Retrieval), bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), p2pServer: stack.Server(), + discmix: enode.NewFairMix(0), shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb), } @@ -295,6 +264,43 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { JournalFile: config.JournalFileEnabled, } ) + if config.VMTrace != "" { + var traceConfig json.RawMessage + if config.VMTraceJsonConfig != "" { + traceConfig = json.RawMessage(config.VMTraceJsonConfig) + } + t, err := tracers.LiveDirectory.New(config.VMTrace, traceConfig) + if err != nil { + return nil, fmt.Errorf("failed to create tracer %s: %v", config.VMTrace, err) + } + vmConfig.Tracer = t + } + // Override the chain config with provided settings. + var overrides core.ChainOverrides + if config.OverridePassedForkTime != nil { + chainConfig.ShanghaiTime = config.OverridePassedForkTime + chainConfig.KeplerTime = config.OverridePassedForkTime + chainConfig.FeynmanTime = config.OverridePassedForkTime + chainConfig.FeynmanFixTime = config.OverridePassedForkTime + chainConfig.CancunTime = config.OverridePassedForkTime + chainConfig.HaberTime = config.OverridePassedForkTime + chainConfig.HaberFixTime = config.OverridePassedForkTime + chainConfig.BohrTime = config.OverridePassedForkTime + overrides.OverridePassedForkTime = config.OverridePassedForkTime + } + if config.OverridePascal != nil { + chainConfig.PascalTime = config.OverridePascal + overrides.OverridePascal = config.OverridePascal + } + if config.OverridePrague != nil { + chainConfig.PragueTime = config.OverridePrague + overrides.OverridePrague = config.OverridePrague + } + if config.OverrideVerkle != nil { + chainConfig.VerkleTime = config.OverrideVerkle + overrides.OverrideVerkle = config.OverrideVerkle + } + bcOps := make([]core.BlockChainOption, 0) if config.PersistDiff { bcOps = append(bcOps, core.EnablePersistDiff(config.DiffBlock)) @@ -305,7 +311,11 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { peers := newPeerSet() bcOps = append(bcOps, core.EnableBlockValidator(chainConfig, eth.engine, config.TriesVerifyMode, peers)) - eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TransactionHistory, bcOps...) + // TODO (MariusVanDerWijden) get rid of shouldPreserve in a follow-up PR + shouldPreserve := func(header *types.Header) bool { + return false + } + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, shouldPreserve, &config.TransactionHistory, bcOps...) if err != nil { return nil, err } @@ -328,10 +338,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { // Permit the downloader to use the trie cache allowance during fast sync cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit if eth.handler, err = newHandler(&handlerConfig{ + NodeID: eth.p2pServer.Self().ID(), Database: chainDb, Chain: eth.blockchain, TxPool: eth.txPool, - Merger: eth.merger, Network: networkID, Sync: config.SyncMode, BloomCache: uint64(cacheLimit), @@ -344,7 +354,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } - eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock) + eth.miner = miner.New(eth, &config.Miner, eth.EventMux(), eth.engine) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) // Create voteManager instance @@ -379,31 +389,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { log.Info("Create voteManager successfully") } } - - gpoParams := config.GPO - if gpoParams.Default == nil { - gpoParams.Default = config.Miner.GasPrice - } - eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) - - // Setup DNS discovery iterators. - dnsclient := dnsdisc.NewClient(dnsdisc.Config{}) - eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...) - if err != nil { - return nil, err - } - eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...) - if err != nil { - return nil, err - } - eth.trustDialCandidates, err = dnsclient.NewIterator(eth.config.TrustDiscoveryURLs...) - if err != nil { - return nil, err - } - eth.bscDialCandidates, err = dnsclient.NewIterator(eth.config.BscDiscoveryURLs...) - if err != nil { - return nil, err - } + eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, config.GPO, config.Miner.GasPrice) // Start the RPC service eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, networkID) @@ -486,63 +472,6 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) { return common.Address{}, errors.New("etherbase must be explicitly specified") } -// isLocalBlock checks whether the specified block is mined -// by local miner accounts. -// -// We regard two types of accounts as local miner account: etherbase -// and accounts specified via `txpool.locals` flag. -func (s *Ethereum) isLocalBlock(header *types.Header) bool { - author, err := s.engine.Author(header) - if err != nil { - log.Warn("Failed to retrieve block author", "number", header.Number.Uint64(), "hash", header.Hash(), "err", err) - return false - } - // Check whether the given address is etherbase. - s.lock.RLock() - etherbase := s.etherbase - s.lock.RUnlock() - if author == etherbase { - return true - } - // Check whether the given address is specified by `txpool.local` - // CLI flag. - for _, account := range s.config.TxPool.Locals { - if account == author { - return true - } - } - return false -} - -// shouldPreserve checks whether we should preserve the given block -// during the chain reorg depending on whether the author of block -// is a local account. -func (s *Ethereum) shouldPreserve(header *types.Header) bool { - // The reason we need to disable the self-reorg preserving for clique - // is it can be probable to introduce a deadlock. - // - // e.g. If there are 7 available signers - // - // r1 A - // r2 B - // r3 C - // r4 D - // r5 A [X] F G - // r6 [X] - // - // In the round5, the in-turn signer E is offline, so the worst case - // is A, F and G sign the block of round5 and reject the block of opponents - // and in the round6, the last available signer B is offline, the whole - // network is stuck. - if _, ok := s.engine.(*clique.Clique); ok { - return false - } - if _, ok := s.engine.(*parlia.Parlia); ok { - return false - } - return s.isLocalBlock(header) -} - // SetEtherbase sets the mining reward address. func (s *Ethereum) SetEtherbase(etherbase common.Address) { s.lock.Lock() @@ -638,7 +567,6 @@ func (s *Ethereum) Synced() bool { return s.handler.synced func (s *Ethereum) SetSynced() { s.handler.enableSyncedFeatures() } func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning } func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer } -func (s *Ethereum) Merger() *consensus.Merger { return s.merger } func (s *Ethereum) SyncMode() downloader.SyncMode { mode, _ := s.handler.chainSync.modeAndLocalHead() return mode @@ -647,14 +575,14 @@ func (s *Ethereum) SyncMode() downloader.SyncMode { // Protocols returns all the currently configured // network protocols to start. func (s *Ethereum) Protocols() []p2p.Protocol { - protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates) + protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.discmix) if !s.config.DisableSnapProtocol && s.config.SnapshotCache > 0 { - protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...) + protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler))...) } if s.config.EnableTrustProtocol { - protos = append(protos, trust.MakeProtocols((*trustHandler)(s.handler), s.snapDialCandidates)...) + protos = append(protos, trust.MakeProtocols((*trustHandler)(s.handler))...) } - protos = append(protos, bsc.MakeProtocols((*bscHandler)(s.handler), s.bscDialCandidates)...) + protos = append(protos, bsc.MakeProtocols((*bscHandler)(s.handler))...) return protos } @@ -663,7 +591,7 @@ func (s *Ethereum) Protocols() []p2p.Protocol { // Ethereum protocol implementation. func (s *Ethereum) Start() error { eth.StartENRFilter(s.blockchain, s.p2pServer) - eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode()) + s.setupDiscovery() // Start the bloom bits servicing goroutines s.startBloomHandlers(params.BloomBitsBlocks) @@ -671,16 +599,58 @@ func (s *Ethereum) Start() error { // Regularly update shutdown marker s.shutdownTracker.Start() - // Figure out a max peers count based on the server limits - maxPeers := s.p2pServer.MaxPeers - if s.config.LightServ > 0 { - if s.config.LightPeers >= s.p2pServer.MaxPeers { - return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, s.p2pServer.MaxPeers) + // Start the networking layer + s.handler.Start(s.p2pServer.MaxPeers, s.p2pServer.MaxPeersPerIP) + return nil +} + +func (s *Ethereum) setupDiscovery() error { + eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode()) + + // Add eth nodes from DNS. + dnsclient := dnsdisc.NewClient(dnsdisc.Config{}) + if len(s.config.EthDiscoveryURLs) > 0 { + iter, err := dnsclient.NewIterator(s.config.EthDiscoveryURLs...) + if err != nil { + return err } - maxPeers -= s.config.LightPeers + s.discmix.AddSource(iter) } - // Start the networking layer and the light server if requested - s.handler.Start(maxPeers, s.p2pServer.MaxPeersPerIP) + + // Add snap nodes from DNS. + if len(s.config.SnapDiscoveryURLs) > 0 { + iter, err := dnsclient.NewIterator(s.config.SnapDiscoveryURLs...) + if err != nil { + return err + } + s.discmix.AddSource(iter) + } + + // Add trust nodes from DNS. + if len(s.config.TrustDiscoveryURLs) > 0 { + iter, err := dnsclient.NewIterator(s.config.TrustDiscoveryURLs...) + if err != nil { + return err + } + s.discmix.AddSource(iter) + } + + // Add bsc nodes from DNS. + if len(s.config.BscDiscoveryURLs) > 0 { + iter, err := dnsclient.NewIterator(s.config.BscDiscoveryURLs...) + if err != nil { + return err + } + s.discmix.AddSource(iter) + } + + // Add DHT nodes from discv5. + if s.p2pServer.DiscoveryV5() != nil { + filter := eth.NewNodeFilter(s.blockchain) + iter := enode.Filter(s.p2pServer.DiscoveryV5().RandomNodes(), filter) + s.discmix.AddSource(iter) + } + return nil } @@ -688,10 +658,7 @@ func (s *Ethereum) Start() error { // Ethereum protocol. func (s *Ethereum) Stop() error { // Stop all the peer-related stuff first. - s.ethDialCandidates.Close() - s.snapDialCandidates.Close() - s.trustDialCandidates.Close() - s.bscDialCandidates.Close() + s.discmix.Close() s.handler.Stop() // Then stop everything else. diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 4d6dfcb83c..2b1254abf6 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -20,13 +20,16 @@ package catalyst import ( "errors" "fmt" + "strconv" "sync" "time" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" @@ -36,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params/forks" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -81,15 +85,30 @@ var caps = []string{ "engine_forkchoiceUpdatedV1", "engine_forkchoiceUpdatedV2", "engine_forkchoiceUpdatedV3", + "engine_forkchoiceUpdatedWithWitnessV1", + "engine_forkchoiceUpdatedWithWitnessV2", + "engine_forkchoiceUpdatedWithWitnessV3", "engine_exchangeTransitionConfigurationV1", "engine_getPayloadV1", "engine_getPayloadV2", "engine_getPayloadV3", + "engine_getPayloadV4", "engine_newPayloadV1", "engine_newPayloadV2", "engine_newPayloadV3", + "engine_newPayloadV4", + "engine_newPayloadWithWitnessV1", + "engine_newPayloadWithWitnessV2", + "engine_newPayloadWithWitnessV3", + "engine_newPayloadWithWitnessV4", + "engine_executeStatelessPayloadV1", + "engine_executeStatelessPayloadV2", + "engine_executeStatelessPayloadV3", + "engine_executeStatelessPayloadV4", "engine_getPayloadBodiesByHashV1", + "engine_getPayloadBodiesByHashV2", "engine_getPayloadBodiesByRangeV1", + "engine_getPayloadBodiesByRangeV2", "engine_getClientVersionV1", } @@ -190,21 +209,21 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa // attributes. It supports both PayloadAttributesV1 and PayloadAttributesV2. func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { if params != nil { + if params.BeaconRoot != nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("unexpected beacon root")) + } switch api.eth.BlockChain().Config().LatestFork(params.Timestamp) { case forks.Paris: if params.Withdrawals != nil { - return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals before shanghai")) + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("withdrawals before shanghai")) } case forks.Shanghai: if params.Withdrawals == nil { - return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("missing withdrawals")) + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing withdrawals")) } default: return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV2 must only be called with paris and shanghai payloads")) } - if params.BeaconRoot != nil { - return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("unexpected beacon root")) - } } return api.forkchoiceUpdated(update, params, engine.PayloadV2, false) } @@ -213,17 +232,13 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, pa // in the payload attributes. It supports only PayloadAttributesV3. func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { if params != nil { - // TODO(matt): according to https://github.com/ethereum/execution-apis/pull/498, - // payload attributes that are invalid should return error - // engine.InvalidPayloadAttributes. Once hive updates this, we should update - // on our end. if params.Withdrawals == nil { - return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("missing withdrawals")) + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing withdrawals")) } if params.BeaconRoot == nil { - return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("missing beacon root")) + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing beacon root")) } - if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun { + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun && api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Prague { return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV3 must only be called for cancun payloads")) } } @@ -234,7 +249,65 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa return api.forkchoiceUpdated(update, params, engine.PayloadV3, false) } -func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes, payloadVersion engine.PayloadVersion, simulatorMode bool) (engine.ForkChoiceResponse, error) { +// ForkchoiceUpdatedWithWitnessV1 is analogous to ForkchoiceUpdatedV1, only it +// generates an execution witness too if block building was requested. +func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { + if payloadAttributes != nil { + if payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil { + return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals and beacon root not supported in V1")) + } + if api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, payloadAttributes.Timestamp) { + return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("forkChoiceUpdateV1 called post-shanghai")) + } + } + return api.forkchoiceUpdated(update, payloadAttributes, engine.PayloadV1, true) +} + +// ForkchoiceUpdatedWithWitnessV2 is analogous to ForkchoiceUpdatedV2, only it +// generates an execution witness too if block building was requested. +func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV2(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { + if params != nil { + if params.BeaconRoot != nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("unexpected beacon root")) + } + switch api.eth.BlockChain().Config().LatestFork(params.Timestamp) { + case forks.Paris: + if params.Withdrawals != nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("withdrawals before shanghai")) + } + case forks.Shanghai: + if params.Withdrawals == nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing withdrawals")) + } + default: + return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV2 must only be called with paris and shanghai payloads")) + } + } + return api.forkchoiceUpdated(update, params, engine.PayloadV2, true) +} + +// ForkchoiceUpdatedWithWitnessV3 is analogous to ForkchoiceUpdatedV3, only it +// generates an execution witness too if block building was requested. +func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV3(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { + if params != nil { + if params.Withdrawals == nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing withdrawals")) + } + if params.BeaconRoot == nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("missing beacon root")) + } + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun && api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Prague { + return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV3 must only be called for cancun payloads")) + } + } + // TODO(matt): the spec requires that fcu is applied when called on a valid + // hash, even if params are wrong. To do this we need to split up + // forkchoiceUpdate into a function that only updates the head and then a + // function that kicks off block construction. + return api.forkchoiceUpdated(update, params, engine.PayloadV3, true) +} + +func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes, payloadVersion engine.PayloadVersion, payloadWitness bool) (engine.ForkChoiceResponse, error) { api.forkchoiceLock.Lock() defer api.forkchoiceLock.Unlock() @@ -271,12 +344,6 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl finalized := api.remoteBlocks.get(update.FinalizedBlockHash) // Header advertised via a past newPayload request. Start syncing to it. - // Before we do however, make sure any legacy sync in switched off so we - // don't accidentally have 2 cycles running. - if merger := api.eth.Merger(); !merger.TDDReached() { - merger.ReachTTD() - api.eth.Downloader().Cancel() - } context := []interface{}{"number", header.Number, "hash", header.Hash()} if update.FinalizedBlockHash != (common.Hash{}) { if finalized == nil { @@ -338,16 +405,13 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl // If the beacon client also advertised a finalized block, mark the local // chain final and completely in PoS mode. if update.FinalizedBlockHash != (common.Hash{}) { - if merger := api.eth.Merger(); !merger.PoSFinalized() { - merger.FinalizePoS() - } // If the finalized block is not in our canonical tree, something is wrong finalBlock := api.eth.BlockChain().GetBlockByHash(update.FinalizedBlockHash) if finalBlock == nil { log.Warn("Final block not available in database", "hash", update.FinalizedBlockHash) return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("final block not available in database")) } else if rawdb.ReadCanonicalHash(api.eth.ChainDb(), finalBlock.NumberU64()) != update.FinalizedBlockHash { - log.Warn("Final block not in canonical chain", "number", block.NumberU64(), "hash", update.HeadBlockHash) + log.Warn("Final block not in canonical chain", "number", finalBlock.NumberU64(), "hash", update.FinalizedBlockHash) return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("final block not in canonical chain")) } // Set the finalized block @@ -386,20 +450,7 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl if api.localBlocks.has(id) { return valid(&id), nil } - // If the beacon chain is ran by a simulator, then transaction insertion, - // block insertion and block production will happen without any timing - // delay between them. This will cause flaky simulator executions due to - // the transaction pool running its internal reset operation on a back- - // ground thread. To avoid the racey behavior - in simulator mode - the - // pool will be explicitly blocked on its reset before continuing to the - // block production below. - if simulatorMode { - if err := api.eth.TxPool().Sync(); err != nil { - log.Error("Failed to sync transaction pool", "err", err) - return valid(nil), engine.InvalidPayloadAttributes.With(err) - } - } - payload, err := api.eth.Miner().BuildPayload(args) + payload, err := api.eth.Miner().BuildPayload(args, payloadWitness) if err != nil { log.Error("Failed to build payload", "err", err) return valid(nil), engine.InvalidPayloadAttributes.With(err) @@ -468,6 +519,14 @@ func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.Execu return api.getPayload(payloadID, false) } +// GetPayloadV4 returns a cached payload by id. +func (api *ConsensusAPI) GetPayloadV4(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { + if !payloadID.Is(engine.PayloadV3) { + return nil, engine.UnsupportedFork + } + return api.getPayload(payloadID, false) +} + func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*engine.ExecutionPayloadEnvelope, error) { log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID) data := api.localBlocks.get(payloadID, full) @@ -482,7 +541,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl if params.Withdrawals != nil { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) } - return api.newPayload(params, nil, nil) + return api.newPayload(params, nil, nil, false) } // NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. @@ -505,7 +564,7 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl if params.BlobGasUsed != nil { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil blobGasUsed pre-cancun")) } - return api.newPayload(params, nil, nil) + return api.newPayload(params, nil, nil, false) } // NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. @@ -530,10 +589,215 @@ func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHas if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV3 must only be called for cancun payloads")) } - return api.newPayload(params, versionedHashes, beaconRoot) + return api.newPayload(params, versionedHashes, beaconRoot, false) +} + +// NewPayloadV4 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. +// NewPayloadV4 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. +func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) { + if params.Withdrawals == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + if params.ExcessBlobGas == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun")) + } + if params.Deposits == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil deposits post-prague")) + } + + if versionedHashes == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil beaconRoot post-cancun")) + } + + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Prague { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV4 must only be called for prague payloads")) + } + return api.newPayload(params, versionedHashes, beaconRoot, false) } -func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) { +// NewPayloadWithWitnessV1 is analogous to NewPayloadV1, only it also generates +// and returns a stateless witness after running the payload. +func (api *ConsensusAPI) NewPayloadWithWitnessV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) { + if params.Withdrawals != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) + } + return api.newPayload(params, nil, nil, true) +} + +// NewPayloadWithWitnessV2 is analogous to NewPayloadV2, only it also generates +// and returns a stateless witness after running the payload. +func (api *ConsensusAPI) NewPayloadWithWitnessV2(params engine.ExecutableData) (engine.PayloadStatusV1, error) { + if api.eth.BlockChain().Config().IsCancun(api.eth.BlockChain().Config().LondonBlock, params.Timestamp) { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("can't use newPayloadV2 post-cancun")) + } + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) == forks.Shanghai { + if params.Withdrawals == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + } else { + if params.Withdrawals != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai")) + } + } + if params.ExcessBlobGas != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil excessBlobGas pre-cancun")) + } + if params.BlobGasUsed != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil blobGasUsed pre-cancun")) + } + return api.newPayload(params, nil, nil, true) +} + +// NewPayloadWithWitnessV3 is analogous to NewPayloadV3, only it also generates +// and returns a stateless witness after running the payload. +func (api *ConsensusAPI) NewPayloadWithWitnessV3(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) { + if params.Withdrawals == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + if params.ExcessBlobGas == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun")) + } + + if versionedHashes == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil beaconRoot post-cancun")) + } + + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV3 must only be called for cancun payloads")) + } + return api.newPayload(params, versionedHashes, beaconRoot, true) +} + +// NewPayloadWithWitnessV4 is analogous to NewPayloadV4, only it also generates +// and returns a stateless witness after running the payload. +func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) { + if params.Withdrawals == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + if params.ExcessBlobGas == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun")) + } + if params.Deposits == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil deposits post-prague")) + } + + if versionedHashes == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil beaconRoot post-cancun")) + } + + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Prague { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV4 must only be called for prague payloads")) + } + return api.newPayload(params, versionedHashes, beaconRoot, true) +} + +// ExecuteStatelessPayloadV1 is analogous to NewPayloadV1, only it operates in +// a stateless mode on top of a provided witness instead of the local database. +func (api *ConsensusAPI) ExecuteStatelessPayloadV1(params engine.ExecutableData, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + if params.Withdrawals != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) + } + return api.executeStatelessPayload(params, nil, nil, opaqueWitness) +} + +// ExecuteStatelessPayloadV2 is analogous to NewPayloadV2, only it operates in +// a stateless mode on top of a provided witness instead of the local database. +func (api *ConsensusAPI) ExecuteStatelessPayloadV2(params engine.ExecutableData, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + if api.eth.BlockChain().Config().IsCancun(api.eth.BlockChain().Config().LondonBlock, params.Timestamp) { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("can't use newPayloadV2 post-cancun")) + } + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) == forks.Shanghai { + if params.Withdrawals == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + } else { + if params.Withdrawals != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai")) + } + } + if params.ExcessBlobGas != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil excessBlobGas pre-cancun")) + } + if params.BlobGasUsed != nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil blobGasUsed pre-cancun")) + } + return api.executeStatelessPayload(params, nil, nil, opaqueWitness) +} + +// ExecuteStatelessPayloadV3 is analogous to NewPayloadV3, only it operates in +// a stateless mode on top of a provided witness instead of the local database. +func (api *ConsensusAPI) ExecuteStatelessPayloadV3(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + if params.Withdrawals == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + if params.ExcessBlobGas == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun")) + } + + if versionedHashes == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil beaconRoot post-cancun")) + } + + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("executeStatelessPayloadV3 must only be called for cancun payloads")) + } + return api.executeStatelessPayload(params, versionedHashes, beaconRoot, opaqueWitness) +} + +// ExecuteStatelessPayloadV4 is analogous to NewPayloadV4, only it operates in +// a stateless mode on top of a provided witness instead of the local database. +func (api *ConsensusAPI) ExecuteStatelessPayloadV4(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + if params.Withdrawals == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai")) + } + if params.ExcessBlobGas == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun")) + } + if params.Deposits == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil deposits post-prague")) + } + + if versionedHashes == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil beaconRoot post-cancun")) + } + + if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Prague { + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("executeStatelessPayloadV4 must only be called for prague payloads")) + } + return api.executeStatelessPayload(params, versionedHashes, beaconRoot, opaqueWitness) +} + +func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, witness bool) (engine.PayloadStatusV1, error) { // The locking here is, strictly, not required. Without these locks, this can happen: // // 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to @@ -553,7 +817,34 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash) block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot) if err != nil { - log.Warn("Invalid NewPayload params", "params", params, "error", err) + bgu := "nil" + if params.BlobGasUsed != nil { + bgu = strconv.Itoa(int(*params.BlobGasUsed)) + } + ebg := "nil" + if params.ExcessBlobGas != nil { + ebg = strconv.Itoa(int(*params.ExcessBlobGas)) + } + log.Warn("Invalid NewPayload params", + "params.Number", params.Number, + "params.ParentHash", params.ParentHash, + "params.BlockHash", params.BlockHash, + "params.StateRoot", params.StateRoot, + "params.FeeRecipient", params.FeeRecipient, + "params.LogsBloom", common.PrettyBytes(params.LogsBloom), + "params.Random", params.Random, + "params.GasLimit", params.GasLimit, + "params.GasUsed", params.GasUsed, + "params.Timestamp", params.Timestamp, + "params.ExtraData", common.PrettyBytes(params.ExtraData), + "params.BaseFeePerGas", params.BaseFeePerGas, + "params.BlobGasUsed", bgu, + "params.ExcessBlobGas", ebg, + "len(params.Transactions)", len(params.Transactions), + "len(params.Withdrawals)", len(params.Withdrawals), + "len(params.Deposits)", len(params.Deposits), + "beaconRoot", beaconRoot, + "error", err) return api.invalid(err, nil), nil } // Stash away the last update to warn the user if the beacon client goes offline @@ -580,7 +871,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe // update after legit payload executions. parent := api.eth.BlockChain().GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { - return api.delayPayloadImport(block) + return api.delayPayloadImport(block), nil } // We have an existing parent, do some sanity checks to avoid the beacon client // triggering too early @@ -606,16 +897,17 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe // into the database directly will conflict with the assumptions of snap sync // that it has an empty db that it can fill itself. if api.eth.SyncMode() != downloader.FullSync { - return api.delayPayloadImport(block) + return api.delayPayloadImport(block), nil } if !api.eth.BlockChain().HasBlockAndState(block.ParentHash(), block.NumberU64()-1) { api.remoteBlocks.put(block.Hash(), block.Header()) log.Warn("State not available, ignoring new payload") return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil } - log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number) - if err := api.eth.BlockChain().InsertBlockWithoutSetHead(block); err != nil { - log.Warn("NewPayloadV1: inserting block failed", "error", err) + log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number()) + proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(block, witness) + if err != nil { + log.Warn("NewPayload: inserting block failed", "error", err) api.invalidLock.Lock() api.invalidBlocksHits[block.Hash()] = 1 @@ -624,39 +916,96 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe return api.invalid(err, parent.Header()), nil } - // We've accepted a valid payload from the beacon client. Mark the local - // chain transitions to notify other subsystems (e.g. downloader) of the - // behavioral change. - if merger := api.eth.Merger(); !merger.TDDReached() { - merger.ReachTTD() - api.eth.Downloader().Cancel() - } hash := block.Hash() - return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil + + // If witness collection was requested, inject that into the result too + var ow *hexutil.Bytes + if proofs != nil { + ow = new(hexutil.Bytes) + *ow, _ = rlp.EncodeToBytes(proofs) + } + return engine.PayloadStatusV1{Status: engine.VALID, Witness: ow, LatestValidHash: &hash}, nil +} + +func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { + log.Trace("Engine API request received", "method", "ExecuteStatelessPayload", "number", params.Number, "hash", params.BlockHash) + + block, err := engine.ExecutableDataToBlockNoHash(params, versionedHashes, beaconRoot) + if err != nil { + bgu := "nil" + if params.BlobGasUsed != nil { + bgu = strconv.Itoa(int(*params.BlobGasUsed)) + } + ebg := "nil" + if params.ExcessBlobGas != nil { + ebg = strconv.Itoa(int(*params.ExcessBlobGas)) + } + log.Warn("Invalid ExecuteStatelessPayload params", + "params.Number", params.Number, + "params.ParentHash", params.ParentHash, + "params.BlockHash", params.BlockHash, + "params.StateRoot", params.StateRoot, + "params.FeeRecipient", params.FeeRecipient, + "params.LogsBloom", common.PrettyBytes(params.LogsBloom), + "params.Random", params.Random, + "params.GasLimit", params.GasLimit, + "params.GasUsed", params.GasUsed, + "params.Timestamp", params.Timestamp, + "params.ExtraData", common.PrettyBytes(params.ExtraData), + "params.BaseFeePerGas", params.BaseFeePerGas, + "params.BlobGasUsed", bgu, + "params.ExcessBlobGas", ebg, + "len(params.Transactions)", len(params.Transactions), + "len(params.Withdrawals)", len(params.Withdrawals), + "len(params.Deposits)", len(params.Deposits), + "beaconRoot", beaconRoot, + "error", err) + errorMsg := err.Error() + return engine.StatelessPayloadStatusV1{Status: engine.INVALID, ValidationError: &errorMsg}, nil + } + witness := new(stateless.Witness) + if err := rlp.DecodeBytes(opaqueWitness, witness); err != nil { + log.Warn("Invalid ExecuteStatelessPayload witness", "err", err) + errorMsg := err.Error() + return engine.StatelessPayloadStatusV1{Status: engine.INVALID, ValidationError: &errorMsg}, nil + } + // Stash away the last update to warn the user if the beacon client goes offline + api.lastNewPayloadLock.Lock() + api.lastNewPayloadUpdate = time.Now() + api.lastNewPayloadLock.Unlock() + + log.Trace("Executing block statelessly", "number", block.Number(), "hash", params.BlockHash) + stateRoot, receiptRoot, err := core.ExecuteStateless(api.eth.BlockChain().Config(), block, witness) + if err != nil { + log.Warn("ExecuteStatelessPayload: execution failed", "err", err) + errorMsg := err.Error() + return engine.StatelessPayloadStatusV1{Status: engine.INVALID, ValidationError: &errorMsg}, nil + } + return engine.StatelessPayloadStatusV1{Status: engine.VALID, StateRoot: stateRoot, ReceiptsRoot: receiptRoot}, nil } // delayPayloadImport stashes the given block away for import at a later time, // either via a forkchoice update or a sync extension. This method is meant to // be called by the newpayload command when the block seems to be ok, but some // prerequisite prevents it from being processed (e.g. no parent, or snap sync). -func (api *ConsensusAPI) delayPayloadImport(block *types.Block) (engine.PayloadStatusV1, error) { +func (api *ConsensusAPI) delayPayloadImport(block *types.Block) engine.PayloadStatusV1 { // Sanity check that this block's parent is not on a previously invalidated // chain. If it is, mark the block as invalid too. if res := api.checkInvalidAncestor(block.ParentHash(), block.Hash()); res != nil { - return *res, nil + return *res } // Stash the block away for a potential forced forkchoice update to it // at a later time. api.remoteBlocks.put(block.Hash(), block.Header()) // Although we don't want to trigger a sync, if there is one already in - // progress, try to extend if with the current payload request to relieve + // progress, try to extend it with the current payload request to relieve // some strain from the forkchoice update. // err := api.eth.Downloader().BeaconExtend(api.eth.SyncMode(), block.Header()) var err error if err == nil { log.Debug("Payload accepted for sync extension", "number", block.NumberU64(), "hash", block.Hash()) - return engine.PayloadStatusV1{Status: engine.SYNCING}, nil + return engine.PayloadStatusV1{Status: engine.SYNCING} } // Either no beacon sync was started yet, or it rejected the delivered // payload as non-integratable on top of the existing sync. We'll just @@ -673,7 +1022,7 @@ func (api *ConsensusAPI) delayPayloadImport(block *types.Block) (engine.PayloadS // and cannot afford concurrent out-if-band modifications via imports. log.Warn("Ignoring payload while snap syncing", "number", block.NumberU64(), "hash", block.Hash(), "reason", err) } - return engine.PayloadStatusV1{Status: engine.SYNCING}, nil + return engine.PayloadStatusV1{Status: engine.SYNCING} } // checkInvalidAncestor checks whether the specified chain end links to a known @@ -779,26 +1128,25 @@ func (api *ConsensusAPI) heartbeat() { // If there have been no updates for the past while, warn the user // that the beacon client is probably offline - if api.eth.BlockChain().Config().TerminalTotalDifficultyPassed || api.eth.Merger().TDDReached() { - if time.Since(lastForkchoiceUpdate) <= beaconUpdateConsensusTimeout || time.Since(lastNewPayloadUpdate) <= beaconUpdateConsensusTimeout { - offlineLogged = time.Time{} - continue - } - if time.Since(offlineLogged) > beaconUpdateWarnFrequency { - if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() { - if lastTransitionUpdate.IsZero() { - log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!") - } else { - log.Warn("Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!") - } + if time.Since(lastForkchoiceUpdate) <= beaconUpdateConsensusTimeout || time.Since(lastNewPayloadUpdate) <= beaconUpdateConsensusTimeout { + offlineLogged = time.Time{} + continue + } + + if time.Since(offlineLogged) > beaconUpdateWarnFrequency { + if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() { + if lastTransitionUpdate.IsZero() { + log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!") } else { - log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!") + log.Warn("Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!") } - offlineLogged = time.Now() + } else { + log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!") } - continue + offlineLogged = time.Now() } + continue } } @@ -826,8 +1174,25 @@ func (api *ConsensusAPI) GetClientVersionV1(info engine.ClientVersionV1) []engin // GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list // of block bodies by the engine api. -func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBodyV1 { - bodies := make([]*engine.ExecutionPayloadBodyV1, len(hashes)) +func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBody { + bodies := make([]*engine.ExecutionPayloadBody, len(hashes)) + for i, hash := range hashes { + block := api.eth.BlockChain().GetBlockByHash(hash) + body := getBody(block) + if body != nil { + // Nil out the V2 values, clients should know to not request V1 objects + // after Prague. + body.Deposits = nil + } + bodies[i] = body + } + return bodies +} + +// GetPayloadBodiesByHashV2 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list +// of block bodies by the engine api. +func (api *ConsensusAPI) GetPayloadBodiesByHashV2(hashes []common.Hash) []*engine.ExecutionPayloadBody { + bodies := make([]*engine.ExecutionPayloadBody, len(hashes)) for i, hash := range hashes { block := api.eth.BlockChain().GetBlockByHash(hash) bodies[i] = getBody(block) @@ -837,7 +1202,28 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin // GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range // of block bodies by the engine api. -func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBodyV1, error) { +func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) { + bodies, err := api.getBodiesByRange(start, count) + if err != nil { + return nil, err + } + // Nil out the V2 values, clients should know to not request V1 objects + // after Prague. + for i := range bodies { + if bodies[i] != nil { + bodies[i].Deposits = nil + } + } + return bodies, nil +} + +// GetPayloadBodiesByRangeV2 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range +// of block bodies by the engine api. +func (api *ConsensusAPI) GetPayloadBodiesByRangeV2(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) { + return api.getBodiesByRange(start, count) +} + +func (api *ConsensusAPI) getBodiesByRange(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) { if start == 0 || count == 0 { return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count)) } @@ -850,7 +1236,7 @@ func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) if last > current { last = current } - bodies := make([]*engine.ExecutionPayloadBodyV1, 0, uint64(count)) + bodies := make([]*engine.ExecutionPayloadBody, 0, uint64(count)) for i := uint64(start); i <= last; i++ { block := api.eth.BlockChain().GetBlockByNumber(i) bodies = append(bodies, getBody(block)) @@ -858,15 +1244,16 @@ func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) return bodies, nil } -func getBody(block *types.Block) *engine.ExecutionPayloadBodyV1 { +func getBody(block *types.Block) *engine.ExecutionPayloadBody { if block == nil { return nil } var ( - body = block.Body() - txs = make([]hexutil.Bytes, len(body.Transactions)) - withdrawals = body.Withdrawals + body = block.Body() + txs = make([]hexutil.Bytes, len(body.Transactions)) + withdrawals = body.Withdrawals + depositRequests types.Deposits ) for j, tx := range body.Transactions { @@ -878,8 +1265,20 @@ func getBody(block *types.Block) *engine.ExecutionPayloadBodyV1 { withdrawals = make([]*types.Withdrawal, 0) } - return &engine.ExecutionPayloadBodyV1{ + if block.Header().RequestsHash != nil { + // TODO: this isn't future proof because we can't determine if a request + // type has activated yet or if there are just no requests of that type from + // only the block. + for _, req := range block.Requests() { + if d, ok := req.Inner().(*types.Deposit); ok { + depositRequests = append(depositRequests, d) + } + } + } + + return &engine.ExecutionPayloadBody{ TransactionData: txs, Withdrawals: withdrawals, + Deposits: depositRequests, } } diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index 4ae60ed490..1f3d4f635c 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "crypto/sha256" "errors" + "fmt" "math/big" "sync" "time" @@ -30,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" @@ -41,36 +43,46 @@ const devEpochLength = 32 // withdrawalQueue implements a FIFO queue which holds withdrawals that are // pending inclusion. type withdrawalQueue struct { - pending chan *types.Withdrawal + pending types.Withdrawals + mu sync.Mutex + feed event.Feed + subs event.SubscriptionScope } +type newWithdrawalsEvent struct{ Withdrawals types.Withdrawals } + // add queues a withdrawal for future inclusion. func (w *withdrawalQueue) add(withdrawal *types.Withdrawal) error { - select { - case w.pending <- withdrawal: - break - default: - return errors.New("withdrawal queue full") - } + w.mu.Lock() + w.pending = append(w.pending, withdrawal) + w.mu.Unlock() + + w.feed.Send(newWithdrawalsEvent{types.Withdrawals{withdrawal}}) return nil } -// gatherPending returns a number of queued withdrawals up to a maximum count. -func (w *withdrawalQueue) gatherPending(maxCount int) []*types.Withdrawal { - withdrawals := []*types.Withdrawal{} - for { - select { - case withdrawal := <-w.pending: - withdrawals = append(withdrawals, withdrawal) - if len(withdrawals) == maxCount { - break - } - default: - return withdrawals - } - } +// pop dequeues the specified number of withdrawals from the queue. +func (w *withdrawalQueue) pop(count int) types.Withdrawals { + w.mu.Lock() + defer w.mu.Unlock() + + count = min(count, len(w.pending)) + popped := w.pending[0:count] + w.pending = w.pending[count:] + + return popped +} + +// subscribe allows a listener to be updated when new withdrawals are added to +// the queue. +func (w *withdrawalQueue) subscribe(ch chan<- newWithdrawalsEvent) event.Subscription { + sub := w.feed.Subscribe(ch) + return w.subs.Track(sub) } +// SimulatedBeacon drives an Ethereum instance as if it were a real beacon +// client. It can run in period mode where it mines a new block every period +// (seconds) or on every transaction via Commit, Fork and AdjustTime. type SimulatedBeacon struct { shutdownCh chan struct{} eth *eth.Ethereum @@ -86,10 +98,6 @@ type SimulatedBeacon struct { } // NewSimulatedBeacon constructs a new simulated beacon chain. -// Period sets the period in which blocks should be produced. -// -// - If period is set to 0, a block is produced on every transaction. -// via Commit, Fork and AdjustTime. func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) { block := eth.BlockChain().CurrentBlock() current := engine.ForkchoiceStateV1{ @@ -101,7 +109,7 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err // if genesis block, send forkchoiceUpdated to trigger transition to PoS if block.Number.Sign() == 0 { - if _, err := engineAPI.ForkchoiceUpdatedV2(current, nil); err != nil { + if _, err := engineAPI.ForkchoiceUpdatedV3(current, nil); err != nil { return nil, err } } @@ -112,7 +120,6 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err engineAPI: engineAPI, lastBlockTime: block.Time, curForkchoiceState: current, - withdrawals: withdrawalQueue{make(chan *types.Withdrawal, 20)}, }, nil } @@ -156,6 +163,16 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u c.setCurrentState(header.Hash(), *finalizedHash) } + // Because transaction insertion, block insertion, and block production will + // happen without any timing delay between them in simulator mode and the + // transaction pool will be running its internal reset operation on a + // background thread, flaky executions can happen. To avoid the racey + // behavior, the pool will be explicitly blocked on its reset before + // continuing to the block production below. + if err := c.eth.APIBackend.TxPool().Sync(); err != nil { + return fmt.Errorf("failed to sync txpool: %w", err) + } + var random [32]byte rand.Read(random[:]) fcResponse, err := c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, &engine.PayloadAttributes{ @@ -164,13 +181,14 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u Withdrawals: withdrawals, Random: random, BeaconRoot: &common.Hash{}, - }, engine.PayloadV3, true) + }, engine.PayloadV3, false) if err != nil { return err } if fcResponse == engine.STATUS_SYNCING { return errors.New("chain rewind prevented invocation of payload creation") } + envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID, true) if err != nil { return err @@ -208,7 +226,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u c.setCurrentState(payload.BlockHash, finalizedHash) // Mark the block containing the payload as canonical - if _, err = c.engineAPI.ForkchoiceUpdatedV2(c.curForkchoiceState, nil); err != nil { + if _, err = c.engineAPI.ForkchoiceUpdatedV3(c.curForkchoiceState, nil); err != nil { return err } c.lastBlockTime = payload.Timestamp @@ -223,8 +241,7 @@ func (c *SimulatedBeacon) loop() { case <-c.shutdownCh: return case <-timer.C: - withdrawals := c.withdrawals.gatherPending(10) - if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil { + if err := c.sealBlock(c.withdrawals.pop(10), uint64(time.Now().Unix())); err != nil { log.Warn("Error performing sealing work", "err", err) } else { timer.Reset(time.Second * time.Duration(c.period)) @@ -260,7 +277,7 @@ func (c *SimulatedBeacon) setCurrentState(headHash, finalizedHash common.Hash) { // Commit seals a block on demand. func (c *SimulatedBeacon) Commit() common.Hash { - withdrawals := c.withdrawals.gatherPending(10) + withdrawals := c.withdrawals.pop(10) if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil { log.Warn("Error performing sealing work", "err", err) } @@ -279,14 +296,18 @@ func (c *SimulatedBeacon) Rollback() { // Fork sets the head to the provided hash. func (c *SimulatedBeacon) Fork(parentHash common.Hash) error { + // Ensure no pending transactions. + c.eth.TxPool().Sync() if len(c.eth.TxPool().Pending(txpool.PendingFilter{})) != 0 { return errors.New("pending block dirty") } + parent := c.eth.BlockChain().GetBlockByHash(parentHash) if parent == nil { return errors.New("parent not found") } - return c.eth.BlockChain().SetHead(parent.NumberU64()) + _, err := c.eth.BlockChain().SetCanonical(parent) + return err } // AdjustTime creates a new block with an adjusted timestamp. @@ -298,16 +319,14 @@ func (c *SimulatedBeacon) AdjustTime(adjustment time.Duration) error { if parent == nil { return errors.New("parent not found") } - withdrawals := c.withdrawals.gatherPending(10) - return c.sealBlock(withdrawals, parent.Time+uint64(adjustment)) + withdrawals := c.withdrawals.pop(10) + return c.sealBlock(withdrawals, parent.Time+uint64(adjustment/time.Second)) } +// RegisterSimulatedBeaconAPIs registers the simulated beacon's API with the +// stack. func RegisterSimulatedBeaconAPIs(stack *node.Node, sim *SimulatedBeacon) { - api := &api{sim} - if sim.period == 0 { - // mine on demand if period is set to 0 - go api.loop() - } + api := newSimulatedBeaconAPI(sim) stack.RegisterAPIs([]rpc.API{ { Namespace: "dev", diff --git a/eth/catalyst/simulated_beacon_api.go b/eth/catalyst/simulated_beacon_api.go index 73d0a5921d..6687805315 100644 --- a/eth/catalyst/simulated_beacon_api.go +++ b/eth/catalyst/simulated_beacon_api.go @@ -18,44 +18,88 @@ package catalyst import ( "context" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" ) -type api struct { +// simulatedBeaconAPI provides a RPC API for SimulatedBeacon. +type simulatedBeaconAPI struct { sim *SimulatedBeacon } -func (a *api) loop() { +// newSimulatedBeaconAPI returns an instance of simulatedBeaconAPI with a +// buffered commit channel. If period is zero, it starts a goroutine to handle +// new tx events. +func newSimulatedBeaconAPI(sim *SimulatedBeacon) *simulatedBeaconAPI { + api := &simulatedBeaconAPI{sim: sim} + if sim.period == 0 { + // mine on demand if period is set to 0 + go api.loop() + } + return api +} + +// loop is the main loop for the API when it's running in period = 0 mode. It +// ensures that block production is triggered as soon as a new withdrawal or +// transaction is received. +func (a *simulatedBeaconAPI) loop() { var ( - newTxs = make(chan core.NewTxsEvent) - sub = a.sim.eth.TxPool().SubscribeTransactions(newTxs, true) + newTxs = make(chan core.NewTxsEvent) + newWxs = make(chan newWithdrawalsEvent) + newTxsSub = a.sim.eth.TxPool().SubscribeTransactions(newTxs, true) + newWxsSub = a.sim.withdrawals.subscribe(newWxs) + doCommit = make(chan struct{}, 1) ) - defer sub.Unsubscribe() + defer newTxsSub.Unsubscribe() + defer newWxsSub.Unsubscribe() + + // A background thread which signals to the simulator when to commit + // based on messages over doCommit. + go func() { + for range doCommit { + a.sim.Commit() + a.sim.eth.TxPool().Sync() + + // It's worth noting that in case a tx ends up in the pool listed as + // "executable", but for whatever reason the miner does not include it in + // a block -- maybe the miner is enforcing a higher tip than the pool -- + // this code will spinloop. + for { + if executable, _ := a.sim.eth.TxPool().Stats(); executable == 0 { + break + } + a.sim.Commit() + } + } + }() for { select { case <-a.sim.shutdownCh: + close(doCommit) return - case w := <-a.sim.withdrawals.pending: - withdrawals := append(a.sim.withdrawals.gatherPending(9), w) - if err := a.sim.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil { - log.Warn("Error performing sealing work", "err", err) + case <-newWxs: + select { + case doCommit <- struct{}{}: + default: } case <-newTxs: - a.sim.Commit() + select { + case doCommit <- struct{}{}: + default: + } } } } -func (a *api) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error { +// AddWithdrawal adds a withdrawal to the pending queue. +func (a *simulatedBeaconAPI) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error { return a.sim.withdrawals.add(withdrawal) } -func (a *api) SetFeeRecipient(ctx context.Context, feeRecipient common.Address) { +// SetFeeRecipient sets the fee recipient for block building purposes. +func (a *simulatedBeaconAPI) SetFeeRecipient(ctx context.Context, feeRecipient common.Address) { a.sim.setFeeRecipient(feeRecipient) } diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go index 6fa97ad87a..711e8f1d60 100644 --- a/eth/catalyst/simulated_beacon_test.go +++ b/eth/catalyst/simulated_beacon_test.go @@ -29,12 +29,13 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" ) -func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis) (*node.Node, *eth.Ethereum, *SimulatedBeacon) { +func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis, period uint64) (*node.Node, *eth.Ethereum, *SimulatedBeacon) { t.Helper() n, err := node.New(&node.Config{ @@ -48,13 +49,13 @@ func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis) (*node. t.Fatal("can't create node:", err) } - ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256} + ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: miner.DefaultConfig} ethservice, err := eth.New(n, ethcfg) if err != nil { t.Fatal("can't create eth service:", err) } - simBeacon, err := NewSimulatedBeacon(1, ethservice) + simBeacon, err := NewSimulatedBeacon(period, ethservice) if err != nil { t.Fatal("can't create simulated beacon:", err) } @@ -73,7 +74,7 @@ func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis) (*node. // send enough transactions to fill multiple blocks func TestSimulatedBeaconSendWithdrawals(t *testing.T) { var withdrawals []types.Withdrawal - txs := make(map[common.Hash]types.Transaction) + txs := make(map[common.Hash]*types.Transaction) var ( // testKey is a private key to use for funding a tester account. @@ -86,7 +87,7 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { // short period (1 second) for testing purposes var gasLimit uint64 = 10_000_000 genesis := core.DeveloperGenesisBlock(gasLimit, &testAddr) - node, ethService, mock := startSimulatedBeaconEthService(t, genesis) + node, ethService, mock := startSimulatedBeaconEthService(t, genesis, 1) _ = mock defer node.Close() @@ -109,7 +110,7 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { if err != nil { t.Fatalf("error signing transaction, err=%v", err) } - txs[tx.Hash()] = *tx + txs[tx.Hash()] = tx if err := ethService.APIBackend.SendTx(context.Background(), tx); err != nil { t.Fatal("SendTx failed", err) @@ -139,3 +140,65 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) { } } } + +// Tests that zero-period dev mode can handle a lot of simultaneous +// transactions/withdrawals +func TestOnDemandSpam(t *testing.T) { + var ( + withdrawals []types.Withdrawal + txs = make(map[common.Hash]*types.Transaction) + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + gasLimit uint64 = 10_000_000 + genesis = core.DeveloperGenesisBlock(gasLimit, &testAddr) + node, eth, mock = startSimulatedBeaconEthService(t, genesis, 0) + _ = newSimulatedBeaconAPI(mock) + signer = types.LatestSigner(eth.BlockChain().Config()) + chainHeadCh = make(chan core.ChainHeadEvent, 100) + sub = eth.BlockChain().SubscribeChainHeadEvent(chainHeadCh) + ) + defer node.Close() + defer sub.Unsubscribe() + + // generate some withdrawals + for i := 0; i < 20; i++ { + withdrawals = append(withdrawals, types.Withdrawal{Index: uint64(i)}) + if err := mock.withdrawals.add(&withdrawals[i]); err != nil { + t.Fatal("addWithdrawal failed", err) + } + } + + // generate a bunch of transactions + for i := 0; i < 20000; i++ { + tx, err := types.SignTx(types.NewTransaction(uint64(i), common.Address{byte(i), byte(1)}, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil), signer, testKey) + if err != nil { + t.Fatal("error signing transaction", err) + } + txs[tx.Hash()] = tx + if err := eth.APIBackend.SendTx(context.Background(), tx); err != nil { + t.Fatal("error adding txs to pool", err) + } + } + + var ( + includedTxs = make(map[common.Hash]struct{}) + includedWxs []uint64 + ) + for { + select { + case evt := <-chainHeadCh: + for _, itx := range evt.Block.Transactions() { + includedTxs[itx.Hash()] = struct{}{} + } + for _, iwx := range evt.Block.Withdrawals() { + includedWxs = append(includedWxs, iwx.Index) + } + // ensure all withdrawals/txs included. this will take two blocks b/c number of withdrawals > 10 + if len(includedTxs) == len(txs) && len(includedWxs) == len(withdrawals) { + return + } + case <-time.After(10 * time.Second): + t.Fatalf("timed out without including all withdrawals/txs: have txs %d, want %d, have wxs %d, want %d", len(includedTxs), len(txs), len(includedWxs), len(withdrawals)) + } + } +} diff --git a/eth/downloader/api.go b/eth/downloader/api.go index 46a4f4d6b8..daef356744 100644 --- a/eth/downloader/api.go +++ b/eth/downloader/api.go @@ -130,7 +130,7 @@ func (api *DownloaderAPI) eventLoop() { } } -// Syncing provides information when this nodes starts synchronising with the Ethereum network and when it's finished. +// Syncing provides information when this node starts synchronising with the Ethereum network and when it's finished. func (api *DownloaderAPI) Syncing(ctx context.Context) (*rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) if !supported { @@ -150,8 +150,6 @@ func (api *DownloaderAPI) Syncing(ctx context.Context) (*rpc.Subscription, error notifier.Notify(rpcSub.ID, status) case <-rpcSub.Err(): return - case <-notifier.Closed(): - return } } }) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 8338fd9316..bcdf971278 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -40,17 +40,17 @@ import ( ) var ( - MaxBlockFetch = 128 // Amount of blocks to be fetched per retrieval request - MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request - MaxSkeletonSize = 128 // Number of header fetches to need for a skeleton assembly - MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request - MaxStateFetch = 384 // Amount of node state values to allow fetching per request - - maxQueuedHeaders = 32 * 1024 // [eth/62] Maximum number of headers to queue for import (DOS protection) - maxHeadersProcess = 2048 // Number of header download results to import at once into the chain - maxResultsProcess = 2048 // Number of content download results to import at once into the chain - FullMaxForkAncestry uint64 = params.FullImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it) - lightMaxForkAncestry uint64 = params.LightImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it) + MaxBlockFetch = 128 // Number of blocks to be fetched per retrieval request + MaxHeaderFetch = 192 // Number of block headers to be fetched per retrieval request + MaxSkeletonSize = 128 // Number of header fetches needed for a skeleton assembly + MaxReceiptFetch = 256 // Number of transaction receipts to allow fetching per request + MaxStateFetch = 384 // Number of node state values to allow fetching per request + + maxQueuedHeaders = 32 * 1024 // [eth/62] Maximum number of headers to queue for import (DOS protection) + maxHeadersProcess = 2048 // Number of header download results to import at once into the chain + maxResultsProcess = 2048 // Number of content download results to import at once into the chain + FullMaxForkAncestry uint64 = params.FullImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it) + lightMaxForkAncestry uint64 = 30000 // Maximum chain reorganisation (locally redeclared so tests can reduce it) reorgProtThreshold = 48 // Threshold number of recent blocks to disable mini reorg protection reorgProtHeaderDelay = 2 // Number of headers to delay delivering to cover mini reorgs @@ -1240,7 +1240,10 @@ func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode var ( mode = d.getMode() gotHeaders = false // Wait for batches of headers to process + timer = time.NewTimer(time.Second) ) + defer timer.Stop() + for { select { case <-d.cancelCh: @@ -1326,10 +1329,11 @@ func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode if mode == FullSync || mode == SnapSync { // If we've reached the allowed number of pending headers, stall a bit for d.queue.PendingBodies() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders { + timer.Reset(time.Second) select { case <-d.cancelCh: return errCanceled - case <-time.After(time.Second): + case <-timer.C: } } // Otherwise insert the headers for content retrieval @@ -1397,7 +1401,7 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error { ) blocks := make([]*types.Block, len(results)) for i, result := range results { - blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals).WithSidecars(result.Sidecars) + blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(types.Body{Transactions: result.Transactions, Uncles: result.Uncles, Withdrawals: result.Withdrawals}).WithSidecars(result.Sidecars) } // Downloaded blocks are always regarded as trusted after the // transition. Because the downloaded chain is guided by the @@ -1457,7 +1461,10 @@ func (d *Downloader) processSnapSyncContent() error { var ( oldPivot *fetchResult // Locked in pivot block, might change eventually oldTail []*fetchResult // Downloaded content after the pivot + timer = time.NewTimer(time.Second) ) + defer timer.Stop() + for { // Wait for the next batch of downloaded data to be available. If we have // not yet reached the pivot point, wait blockingly as there's no need to @@ -1540,6 +1547,7 @@ func (d *Downloader) processSnapSyncContent() error { oldPivot = P } // Wait for completion, occasionally checking for pivot staleness + timer.Reset(time.Second) select { case <-sync.done: if sync.err != nil { @@ -1550,7 +1558,7 @@ func (d *Downloader) processSnapSyncContent() error { } oldPivot = nil - case <-time.After(time.Second): + case <-timer.C: oldTail = afterP continue } @@ -1608,7 +1616,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state blocks := make([]*types.Block, len(results)) receipts := make([]types.Receipts, len(results)) for i, result := range results { - blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals).WithSidecars(result.Sidecars) + blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(types.Body{Transactions: result.Transactions, Uncles: result.Uncles, Withdrawals: result.Withdrawals}).WithSidecars(result.Sidecars) receipts[i] = result.Receipts } if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil { @@ -1619,7 +1627,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state } func (d *Downloader) commitPivotBlock(result *fetchResult) error { - block := types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals).WithSidecars(result.Sidecars) + block := types.NewBlockWithHeader(result.Header).WithBody(types.Body{Transactions: result.Transactions, Uncles: result.Uncles, Withdrawals: result.Withdrawals}).WithSidecars(result.Sidecars) log.Debug("Committing snap sync pivot as new head", "number", block.Number(), "hash", block.Hash()) // Commit the pivot block as the new head, will require full sync from here on diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 0a007644d2..d65efe509d 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -57,7 +57,7 @@ func newTester(t *testing.T) *downloadTester { return newTesterWithNotification(t, nil) } -// newTester creates a new downloader test mocker. +// newTesterWithNotification creates a new downloader test mocker. func newTesterWithNotification(t *testing.T, success func()) *downloadTester { freezer := t.TempDir() db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false, false) @@ -278,6 +278,7 @@ func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash, sink chan *et txsHashes = make([]common.Hash, len(bodies)) uncleHashes = make([]common.Hash, len(bodies)) withdrawalHashes = make([]common.Hash, len(bodies)) + requestsHashes = make([]common.Hash, len(bodies)) ) hasher := trie.NewStackTrie(nil) for i, body := range bodies { @@ -290,7 +291,7 @@ func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash, sink chan *et res := ð.Response{ Req: req, Res: (*eth.BlockBodiesResponse)(&bodies), - Meta: [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes}, + Meta: [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes, requestsHashes}, Time: 1, Done: make(chan error, 1), // Ignore the returned status } @@ -1333,3 +1334,84 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) { } } */ + +// Tests that synchronisation progress (origin block number and highest block +// number) is tracked and updated correctly in case of manual head reversion +func TestBeaconForkedSyncProgress68Full(t *testing.T) { + testBeaconForkedSyncProgress(t, eth.ETH68, FullSync) +} +func TestBeaconForkedSyncProgress68Snap(t *testing.T) { + testBeaconForkedSyncProgress(t, eth.ETH68, SnapSync) +} +func TestBeaconForkedSyncProgress68Light(t *testing.T) { + testBeaconForkedSyncProgress(t, eth.ETH68, LightSync) +} + +func testBeaconForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) { + success := make(chan struct{}) + tester := newTesterWithNotification(t, func() { + success <- struct{}{} + }) + defer tester.terminate() + + chainA := testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch) + chainB := testChainForkLightB.shorten(len(testChainBase.blocks) + MaxHeaderFetch) + + // Set a sync init hook to catch progress changes + starting := make(chan struct{}) + progress := make(chan struct{}) + + tester.downloader.syncInitHook = func(origin, latest uint64) { + starting <- struct{}{} + <-progress + } + checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) + + // Synchronise with one of the forks and check progress + tester.newPeer("fork A", protocol, chainA.blocks[1:]) + pending := new(sync.WaitGroup) + pending.Add(1) + go func() { + defer pending.Done() + if err := tester.downloader.BeaconSync(mode, chainA.blocks[len(chainA.blocks)-1].Header(), nil); err != nil { + panic(fmt.Sprintf("failed to beacon sync: %v", err)) + } + }() + + <-starting + progress <- struct{}{} + select { + case <-success: + checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ + HighestBlock: uint64(len(chainA.blocks) - 1), + CurrentBlock: uint64(len(chainA.blocks) - 1), + }) + case <-time.NewTimer(time.Second * 3).C: + t.Fatalf("Failed to sync chain in three seconds") + } + + // Set the head to a second fork + tester.newPeer("fork B", protocol, chainB.blocks[1:]) + pending.Add(1) + go func() { + defer pending.Done() + if err := tester.downloader.BeaconSync(mode, chainB.blocks[len(chainB.blocks)-1].Header(), nil); err != nil { + panic(fmt.Sprintf("failed to beacon sync: %v", err)) + } + }() + + <-starting + progress <- struct{}{} + + // reorg below available state causes the state sync to rewind to genesis + select { + case <-success: + checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ + HighestBlock: uint64(len(chainB.blocks) - 1), + CurrentBlock: uint64(len(chainB.blocks) - 1), + StartingBlock: 0, + }) + case <-time.NewTimer(time.Second * 3).C: + t.Fatalf("Failed to sync chain in three seconds") + } +} diff --git a/eth/downloader/fetchers_concurrent_bodies.go b/eth/downloader/fetchers_concurrent_bodies.go index 49f3644fd9..a2b5d3f9ee 100644 --- a/eth/downloader/fetchers_concurrent_bodies.go +++ b/eth/downloader/fetchers_concurrent_bodies.go @@ -89,10 +89,10 @@ func (q *bodyQueue) request(peer *peerConnection, req *fetchRequest, resCh chan // deliver is responsible for taking a generic response packet from the concurrent // fetcher, unpacking the body data and delivering it to the downloader's queue. func (q *bodyQueue) deliver(peer *peerConnection, packet *eth.Response) (int, error) { - txs, uncles, withdrawals, sidecars := packet.Res.(*eth.BlockBodiesResponse).Unpack() - hashsets := packet.Meta.([][]common.Hash) // {txs hashes, uncle hashes, withdrawal hashes} + txs, uncles, withdrawals, sidecars, requests := packet.Res.(*eth.BlockBodiesResponse).Unpack() + hashsets := packet.Meta.([][]common.Hash) // {txs hashes, uncle hashes, withdrawal hashes, requests hashes} - accepted, err := q.queue.DeliverBodies(peer.id, txs, hashsets[0], uncles, hashsets[1], withdrawals, hashsets[2], sidecars) + accepted, err := q.queue.DeliverBodies(peer.id, txs, hashsets[0], uncles, hashsets[1], withdrawals, hashsets[2], sidecars, requests, hashsets[3]) switch { case err == nil && len(txs) == 0: peer.log.Trace("Requested bodies delivered") diff --git a/eth/downloader/modes.go b/eth/downloader/modes.go index d388b9ee4d..340cf7a61a 100644 --- a/eth/downloader/modes.go +++ b/eth/downloader/modes.go @@ -29,7 +29,7 @@ const ( ) func (mode SyncMode) IsValid() bool { - return mode >= FullSync && mode <= LightSync + return mode == FullSync || mode == SnapSync } // String implements the stringer interface. @@ -39,8 +39,6 @@ func (mode SyncMode) String() string { return "full" case SnapSync: return "snap" - case LightSync: - return "light" default: return "unknown" } @@ -52,8 +50,6 @@ func (mode SyncMode) MarshalText() ([]byte, error) { return []byte("full"), nil case SnapSync: return []byte("snap"), nil - case LightSync: - return []byte("light"), nil default: return nil, fmt.Errorf("unknown sync mode %d", mode) } @@ -65,10 +61,8 @@ func (mode *SyncMode) UnmarshalText(text []byte) error { *mode = FullSync case "snap": *mode = SnapSync - case "light": - *mode = LightSync default: - return fmt.Errorf(`unknown sync mode %q, want "full", "snap" or "light"`, text) + return fmt.Errorf(`unknown sync mode %q, want "full" or "snap"`, text) } return nil } diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 72d21c329e..39a3ad18e2 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -90,6 +90,15 @@ func newFetchResult(header *types.Header, fastSync bool, pid string) *fetchResul return item } +// body returns a representation of the fetch result as a types.Body object. +func (f *fetchResult) body() types.Body { + return types.Body{ + Transactions: f.Transactions, + Uncles: f.Uncles, + Withdrawals: f.Withdrawals, + } +} + // SetBodyDone flags the body as finished. func (f *fetchResult) SetBodyDone() { if v := f.pending.Load(); (v & (1 << bodyType)) != 0 { @@ -379,6 +388,7 @@ func (q *queue) Results(block bool) []*fetchResult { for _, tx := range result.Transactions { size += common.StorageSize(tx.Size()) } + size += common.StorageSize(result.Withdrawals.Size()) q.resultSize = common.StorageSize(blockCacheSizeWeight)*size + (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize } @@ -777,7 +787,8 @@ func (q *queue) DeliverHeaders(id string, headers []*types.Header, hashes []comm // also wakes any threads waiting for data delivery. func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListHashes []common.Hash, uncleLists [][]*types.Header, uncleListHashes []common.Hash, - withdrawalLists [][]*types.Withdrawal, withdrawalListHashes []common.Hash, sidecars []types.BlobSidecars) (int, error) { + withdrawalLists [][]*types.Withdrawal, withdrawalListHashes []common.Hash, sidecars []types.BlobSidecars, + requestsLists [][]*types.Request, requestsListHashes []common.Hash) (int, error) { q.lock.Lock() defer q.lock.Unlock() @@ -801,6 +812,19 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH return errInvalidBody } } + if header.RequestsHash == nil { + // nil hash means that requests should not be present in body + if requestsLists[index] != nil { + return errInvalidBody + } + } else { // non-nil hash: body must have requests + if requestsLists[index] == nil { + return errInvalidBody + } + if requestsListHashes[index] != *header.RequestsHash { + return errInvalidBody + } + } // Blocks must have a number of blobs corresponding to the header gas usage, // and zero before the Cancun hardfork. var blobs int diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go index c10483b5b2..39ff499186 100644 --- a/eth/downloader/queue_test.go +++ b/eth/downloader/queue_test.go @@ -18,6 +18,7 @@ package downloader import ( "fmt" + "log/slog" "math/big" "math/rand" "os" @@ -32,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" - "golang.org/x/exp/slog" ) // makeChain creates a chain of n blocks starting at and including parent. @@ -341,7 +341,7 @@ func XTestDelivery(t *testing.T) { uncleHashes[i] = types.CalcUncleHash(uncles) } time.Sleep(100 * time.Millisecond) - _, err := q.DeliverBodies(peer.id, txset, txsHashes, uncleset, uncleHashes, nil, nil, nil) + _, err := q.DeliverBodies(peer.id, txset, txsHashes, uncleset, uncleHashes, nil, nil, nil, nil, nil) if err != nil { fmt.Printf("delivered %d bodies %v\n", len(txset), err) } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 74bea35b97..69bec97daf 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -18,7 +18,6 @@ package ethconfig import ( - "errors" "time" "github.com/ethereum/go-ethereum/common" @@ -54,7 +53,6 @@ var Defaults = Config{ TxLookupLimit: 2350000, TransactionHistory: 2350000, StateHistory: params.FullImmutabilityThreshold, - LightPeers: 100, DatabaseCache: 512, TrieCleanCache: 154, TrieDirtyCache: 256, @@ -96,21 +94,24 @@ type Config struct { DisablePeerTxBroadcast bool // This can be set to list of enrtree:// URLs which will be queried for - // for nodes to connect to. + // nodes to connect to. EthDiscoveryURLs []string SnapDiscoveryURLs []string TrustDiscoveryURLs []string BscDiscoveryURLs []string - NoPruning bool // Whether to disable pruning and flush everything to disk - NoPrefetch bool + // State options. + NoPruning bool // Whether to disable pruning and flush everything to disk + NoPrefetch bool // Whether to disable prefetching and only load state on demand + DirectBroadcast bool DisableSnapProtocol bool // Whether disable snap protocol EnableTrustProtocol bool // Whether enable trust protocol RangeLimit bool - // Deprecated, use 'TransactionHistory' instead. - TxLookupLimit uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved. + // Deprecated: use 'TransactionHistory' instead. + TxLookupLimit uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved. + TransactionHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved. StateHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose state histories are reserved. // State scheme represents the scheme used to store ethereum states and trie @@ -125,14 +126,6 @@ type Config struct { // presence of these blocks for every new peer connection. RequiredBlocks map[uint64]common.Hash `toml:"-"` - // Light client options - LightServ int `toml:",omitempty"` // Maximum percentage of time allowed for serving LES requests - LightIngress int `toml:",omitempty"` // Incoming bandwidth limit for light servers - LightEgress int `toml:",omitempty"` // Outgoing bandwidth limit for light servers - LightPeers int `toml:",omitempty"` // Maximum number of LES client peers - LightNoPrune bool `toml:",omitempty"` // Whether to disable light chain pruning - LightNoSyncServe bool `toml:",omitempty"` // Whether to serve light clients before syncing - // Database options SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` @@ -174,6 +167,10 @@ type Config struct { // Enables tracking of SHA3 preimages in the VM EnablePreimageRecording bool + // Enables VM tracing + VMTrace string + VMTraceJsonConfig string + // Miscellaneous options DocRoot string `toml:"-"` @@ -214,11 +211,5 @@ func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database, ee *et if config.Clique != nil { return clique.New(config.Clique, db), nil } - // If defaulting to proof-of-work, enforce an already merged network since - // we cannot run PoW algorithms anymore, so we cannot even follow a chain - // not coordinated by a beacon node. - if !config.TerminalTotalDifficultyPassed { - return nil, errors.New("ethash is only supported as a historical component of already merged networks") - } return beacon.New(ethash.NewFaker()), nil } diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index ac79812ac7..6ec6540c34 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -38,12 +38,6 @@ func (c Config) MarshalTOML() (interface{}, error) { PathSyncFlush bool `toml:",omitempty"` JournalFileEnabled bool RequiredBlocks map[uint64]common.Hash `toml:"-"` - LightServ int `toml:",omitempty"` - LightIngress int `toml:",omitempty"` - LightEgress int `toml:",omitempty"` - LightPeers int `toml:",omitempty"` - LightNoPrune bool `toml:",omitempty"` - LightNoSyncServe bool `toml:",omitempty"` SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` DatabaseCache int @@ -65,6 +59,8 @@ func (c Config) MarshalTOML() (interface{}, error) { BlobPool blobpool.Config GPO gasprice.Config EnablePreimageRecording bool + VMTrace string + VMTraceJsonConfig string DocRoot string `toml:"-"` RPCGasCap uint64 RPCEVMTimeout time.Duration @@ -97,12 +93,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.PathSyncFlush = c.PathSyncFlush enc.JournalFileEnabled = c.JournalFileEnabled enc.RequiredBlocks = c.RequiredBlocks - enc.LightServ = c.LightServ - enc.LightIngress = c.LightIngress - enc.LightEgress = c.LightEgress - enc.LightPeers = c.LightPeers - enc.LightNoPrune = c.LightNoPrune - enc.LightNoSyncServe = c.LightNoSyncServe enc.SkipBcVersionCheck = c.SkipBcVersionCheck enc.DatabaseHandles = c.DatabaseHandles enc.DatabaseCache = c.DatabaseCache @@ -124,6 +114,8 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.BlobPool = c.BlobPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording + enc.VMTrace = c.VMTrace + enc.VMTraceJsonConfig = c.VMTraceJsonConfig enc.DocRoot = c.DocRoot enc.RPCGasCap = c.RPCGasCap enc.RPCEVMTimeout = c.RPCEVMTimeout @@ -160,12 +152,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { PathSyncFlush *bool `toml:",omitempty"` JournalFileEnabled *bool RequiredBlocks map[uint64]common.Hash `toml:"-"` - LightServ *int `toml:",omitempty"` - LightIngress *int `toml:",omitempty"` - LightEgress *int `toml:",omitempty"` - LightPeers *int `toml:",omitempty"` - LightNoPrune *bool `toml:",omitempty"` - LightNoSyncServe *bool `toml:",omitempty"` SkipBcVersionCheck *bool `toml:"-"` DatabaseHandles *int `toml:"-"` DatabaseCache *int @@ -187,6 +173,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { BlobPool *blobpool.Config GPO *gasprice.Config EnablePreimageRecording *bool + VMTrace *string + VMTraceJsonConfig *string DocRoot *string `toml:"-"` RPCGasCap *uint64 RPCEVMTimeout *time.Duration @@ -264,24 +252,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.RequiredBlocks != nil { c.RequiredBlocks = dec.RequiredBlocks } - if dec.LightServ != nil { - c.LightServ = *dec.LightServ - } - if dec.LightIngress != nil { - c.LightIngress = *dec.LightIngress - } - if dec.LightEgress != nil { - c.LightEgress = *dec.LightEgress - } - if dec.LightPeers != nil { - c.LightPeers = *dec.LightPeers - } - if dec.LightNoPrune != nil { - c.LightNoPrune = *dec.LightNoPrune - } - if dec.LightNoSyncServe != nil { - c.LightNoSyncServe = *dec.LightNoSyncServe - } if dec.SkipBcVersionCheck != nil { c.SkipBcVersionCheck = *dec.SkipBcVersionCheck } @@ -345,6 +315,12 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EnablePreimageRecording != nil { c.EnablePreimageRecording = *dec.EnablePreimageRecording } + if dec.VMTrace != nil { + c.VMTrace = *dec.VMTrace + } + if dec.VMTraceJsonConfig != nil { + c.VMTraceJsonConfig = *dec.VMTraceJsonConfig + } if dec.DocRoot != nil { c.DocRoot = *dec.DocRoot } diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go index 19f8c1ffb8..ba56b1c7c3 100644 --- a/eth/fetcher/block_fetcher.go +++ b/eth/fetcher/block_fetcher.go @@ -18,7 +18,6 @@ package fetcher import ( - "errors" "math/rand" "time" @@ -73,8 +72,6 @@ var ( blockInsertFailGauge = metrics.NewRegisteredGauge("chain/insert/failed", nil) ) -var errTerminated = errors.New("terminated") - // HeaderRetrievalFn is a callback type for retrieving a header from the local chain. type HeaderRetrievalFn func(common.Hash) *types.Header @@ -582,7 +579,7 @@ func (f *BlockFetcher) loop() { case res := <-resCh: res.Done <- nil // Ignoring withdrawals here, will set it to empty later if EmptyWithdrawalsHash in header. - txs, uncles, _, sidecars := res.Res.(*eth.BlockBodiesResponse).Unpack() + txs, uncles, _, sidecars, _ := res.Res.(*eth.BlockBodiesResponse).Unpack() f.FilterBodies(peer, txs, uncles, sidecars, time.Now()) case <-timeout.C: @@ -730,7 +727,7 @@ func (f *BlockFetcher) loop() { // Mark the body matched, reassemble if still unknown matched = true if f.getBlock(hash) == nil { - block := types.NewBlockWithHeader(announce.header).WithBody(task.transactions[i], task.uncles[i]) + block := types.NewBlockWithHeader(announce.header).WithBody(types.Body{Transactions: task.transactions[i], Uncles: task.uncles[i]}) block = block.WithSidecars(task.sidecars[i]) block.ReceivedAt = task.time blocks = append(blocks, block) diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index de472c99e8..e8d7919351 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -17,7 +17,6 @@ package fetcher import ( - "bytes" "errors" "fmt" "math" @@ -36,7 +35,7 @@ import ( ) const ( - // maxTxAnnounces is the maximum number of unique transaction a peer + // maxTxAnnounces is the maximum number of unique transactions a peer // can announce in a short time. maxTxAnnounces = 4096 @@ -108,21 +107,30 @@ var ( txFetcherFetchingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/fetching/hashes", nil) ) +var errTerminated = errors.New("terminated") + // txAnnounce is the notification of the availability of a batch // of new transactions in the network. type txAnnounce struct { origin string // Identifier of the peer originating the notification hashes []common.Hash // Batch of transaction hashes being announced - metas []*txMetadata // Batch of metadatas associated with the hashes (nil before eth/68) + metas []txMetadata // Batch of metadata associated with the hashes } -// txMetadata is a set of extra data transmitted along the announcement for better -// fetch scheduling. +// txMetadata provides the extra data transmitted along with the announcement +// for better fetch scheduling. type txMetadata struct { kind byte // Transaction consensus type size uint32 // Transaction size in bytes } +// txMetadataWithSeq is a wrapper of transaction metadata with an extra field +// tracking the transaction sequence number. +type txMetadataWithSeq struct { + txMetadata + seq uint64 +} + // txRequest represents an in-flight transaction retrieval request destined to // a specific peers. type txRequest struct { @@ -136,7 +144,7 @@ type txRequest struct { type txDelivery struct { origin string // Identifier of the peer originating the notification hashes []common.Hash // Batch of transaction hashes having been delivered - metas []txMetadata // Batch of metadatas associated with the delivered hashes + metas []txMetadata // Batch of metadata associated with the delivered hashes direct bool // Whether this is a direct reply or a broadcast } @@ -158,7 +166,7 @@ type txDrop struct { // The invariants of the fetcher are: // - Each tracked transaction (hash) must only be present in one of the // three stages. This ensures that the fetcher operates akin to a finite -// state automata and there's do data leak. +// state automata and there's no data leak. // - Each peer that announced transactions may be scheduled retrievals, but // only ever one concurrently. This ensures we can immediately know what is // missing from a reply and reschedule it. @@ -168,18 +176,19 @@ type TxFetcher struct { drop chan *txDrop quit chan struct{} + txSeq uint64 // Unique transaction sequence number underpriced *lru.Cache[common.Hash, time.Time] // Transactions discarded as too cheap (don't re-fetch) // Stage 1: Waiting lists for newly discovered transactions that might be // broadcast without needing explicit request/reply round trips. - waitlist map[common.Hash]map[string]struct{} // Transactions waiting for an potential broadcast - waittime map[common.Hash]mclock.AbsTime // Timestamps when transactions were added to the waitlist - waitslots map[string]map[common.Hash]*txMetadata // Waiting announcements grouped by peer (DoS protection) + waitlist map[common.Hash]map[string]struct{} // Transactions waiting for an potential broadcast + waittime map[common.Hash]mclock.AbsTime // Timestamps when transactions were added to the waitlist + waitslots map[string]map[common.Hash]*txMetadataWithSeq // Waiting announcements grouped by peer (DoS protection) // Stage 2: Queue of transactions that waiting to be allocated to some peer // to be retrieved directly. - announces map[string]map[common.Hash]*txMetadata // Set of announced transactions, grouped by origin peer - announced map[common.Hash]map[string]struct{} // Set of download locations, grouped by transaction hash + announces map[string]map[common.Hash]*txMetadataWithSeq // Set of announced transactions, grouped by origin peer + announced map[common.Hash]map[string]struct{} // Set of download locations, grouped by transaction hash // Stage 3: Set of transactions currently being retrieved, some which may be // fulfilled and some rescheduled. Note, this step shares 'announces' from the @@ -217,8 +226,8 @@ func NewTxFetcherForTests( quit: make(chan struct{}), waitlist: make(map[common.Hash]map[string]struct{}), waittime: make(map[common.Hash]mclock.AbsTime), - waitslots: make(map[string]map[common.Hash]*txMetadata), - announces: make(map[string]map[common.Hash]*txMetadata), + waitslots: make(map[string]map[common.Hash]*txMetadataWithSeq), + announces: make(map[string]map[common.Hash]*txMetadataWithSeq), announced: make(map[common.Hash]map[string]struct{}), fetching: make(map[common.Hash]string), requests: make(map[string]*txRequest), @@ -246,7 +255,7 @@ func (f *TxFetcher) Notify(peer string, types []byte, sizes []uint32, hashes []c // loop, so anything caught here is time saved internally. var ( unknownHashes = make([]common.Hash, 0, len(hashes)) - unknownMetas = make([]*txMetadata, 0, len(hashes)) + unknownMetas = make([]txMetadata, 0, len(hashes)) duplicate int64 underpriced int64 @@ -259,11 +268,11 @@ func (f *TxFetcher) Notify(peer string, types []byte, sizes []uint32, hashes []c underpriced++ default: unknownHashes = append(unknownHashes, hash) - if types == nil { - unknownMetas = append(unknownMetas, nil) - } else { - unknownMetas = append(unknownMetas, &txMetadata{kind: types[i], size: sizes[i]}) - } + + // Transaction metadata has been available since eth68, and all + // legacy eth protocols (prior to eth68) have been deprecated. + // Therefore, metadata is always expected in the announcement. + unknownMetas = append(unknownMetas, txMetadata{kind: types[i], size: sizes[i]}) } } txAnnounceKnownMeter.Mark(duplicate) @@ -430,9 +439,19 @@ func (f *TxFetcher) loop() { ann.metas = ann.metas[:want-maxTxAnnounces] } // All is well, schedule the remainder of the transactions - idleWait := len(f.waittime) == 0 - _, oldPeer := f.announces[ann.origin] - + var ( + idleWait = len(f.waittime) == 0 + _, oldPeer = f.announces[ann.origin] + hasBlob bool + + // nextSeq returns the next available sequence number for tagging + // transaction announcement and also bump it internally. + nextSeq = func() uint64 { + seq := f.txSeq + f.txSeq++ + return seq + } + ) for i, hash := range ann.hashes { // If the transaction is already downloading, add it to the list // of possible alternates (in case the current retrieval fails) and @@ -442,9 +461,17 @@ func (f *TxFetcher) loop() { // Stage 2 and 3 share the set of origins per tx if announces := f.announces[ann.origin]; announces != nil { - announces[hash] = ann.metas[i] + announces[hash] = &txMetadataWithSeq{ + txMetadata: ann.metas[i], + seq: nextSeq(), + } } else { - f.announces[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]} + f.announces[ann.origin] = map[common.Hash]*txMetadataWithSeq{ + hash: { + txMetadata: ann.metas[i], + seq: nextSeq(), + }, + } } continue } @@ -455,9 +482,17 @@ func (f *TxFetcher) loop() { // Stage 2 and 3 share the set of origins per tx if announces := f.announces[ann.origin]; announces != nil { - announces[hash] = ann.metas[i] + announces[hash] = &txMetadataWithSeq{ + txMetadata: ann.metas[i], + seq: nextSeq(), + } } else { - f.announces[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]} + f.announces[ann.origin] = map[common.Hash]*txMetadataWithSeq{ + hash: { + txMetadata: ann.metas[i], + seq: nextSeq(), + }, + } } continue } @@ -474,24 +509,47 @@ func (f *TxFetcher) loop() { f.waitlist[hash][ann.origin] = struct{}{} if waitslots := f.waitslots[ann.origin]; waitslots != nil { - waitslots[hash] = ann.metas[i] + waitslots[hash] = &txMetadataWithSeq{ + txMetadata: ann.metas[i], + seq: nextSeq(), + } } else { - f.waitslots[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]} + f.waitslots[ann.origin] = map[common.Hash]*txMetadataWithSeq{ + hash: { + txMetadata: ann.metas[i], + seq: nextSeq(), + }, + } } continue } // Transaction unknown to the fetcher, insert it into the waiting list f.waitlist[hash] = map[string]struct{}{ann.origin: {}} - f.waittime[hash] = f.clock.Now() + // Assign the current timestamp as the wait time, but for blob transactions, + // skip the wait time since they are only announced. + if ann.metas[i].kind != types.BlobTxType { + f.waittime[hash] = f.clock.Now() + } else { + hasBlob = true + f.waittime[hash] = f.clock.Now() - mclock.AbsTime(txArriveTimeout) + } if waitslots := f.waitslots[ann.origin]; waitslots != nil { - waitslots[hash] = ann.metas[i] + waitslots[hash] = &txMetadataWithSeq{ + txMetadata: ann.metas[i], + seq: nextSeq(), + } } else { - f.waitslots[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]} + f.waitslots[ann.origin] = map[common.Hash]*txMetadataWithSeq{ + hash: { + txMetadata: ann.metas[i], + seq: nextSeq(), + }, + } } } // If a new item was added to the waitlist, schedule it into the fetcher - if idleWait && len(f.waittime) > 0 { + if hasBlob || (idleWait && len(f.waittime) > 0) { f.rescheduleWait(waitTimer, waitTrigger) } // If this peer is new and announced something already queued, maybe @@ -515,7 +573,7 @@ func (f *TxFetcher) loop() { if announces := f.announces[peer]; announces != nil { announces[hash] = f.waitslots[peer][hash] } else { - f.announces[peer] = map[common.Hash]*txMetadata{hash: f.waitslots[peer][hash]} + f.announces[peer] = map[common.Hash]*txMetadataWithSeq{hash: f.waitslots[peer][hash]} } delete(f.waitslots[peer], hash) if len(f.waitslots[peer]) == 0 { @@ -784,7 +842,7 @@ func (f *TxFetcher) loop() { // rescheduleWait iterates over all the transactions currently in the waitlist // and schedules the movement into the fetcher for the earliest. // -// The method has a granularity of 'gatherSlack', since there's not much point in +// The method has a granularity of 'txGatherSlack', since there's not much point in // spinning over all the transactions just to maybe find one that should trigger // a few ms earlier. func (f *TxFetcher) rescheduleWait(timer *mclock.Timer, trigger chan struct{}) { @@ -797,7 +855,7 @@ func (f *TxFetcher) rescheduleWait(timer *mclock.Timer, trigger chan struct{}) { for _, instance := range f.waittime { if earliest > instance { earliest = instance - if txArriveTimeout-time.Duration(now-earliest) < gatherSlack { + if txArriveTimeout-time.Duration(now-earliest) < txGatherSlack { break } } @@ -810,7 +868,7 @@ func (f *TxFetcher) rescheduleWait(timer *mclock.Timer, trigger chan struct{}) { // rescheduleTimeout iterates over all the transactions currently in flight and // schedules a cleanup run when the first would trigger. // -// The method has a granularity of 'gatherSlack', since there's not much point in +// The method has a granularity of 'txGatherSlack', since there's not much point in // spinning over all the transactions just to maybe find one that should trigger // a few ms earlier. // @@ -835,7 +893,7 @@ func (f *TxFetcher) rescheduleTimeout(timer *mclock.Timer, trigger chan struct{} } if earliest > req.time { earliest = req.time - if txFetchTimeout-time.Duration(now-earliest) < gatherSlack { + if txFetchTimeout-time.Duration(now-earliest) < txGatherSlack { break } } @@ -872,7 +930,7 @@ func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}, hashes = make([]common.Hash, 0, maxTxRetrievals) bytes uint64 ) - f.forEachAnnounce(f.announces[peer], func(hash common.Hash, meta *txMetadata) bool { + f.forEachAnnounce(f.announces[peer], func(hash common.Hash, meta txMetadata) bool { // If the transaction is already fetching, skip to the next one if _, ok := f.fetching[hash]; ok { return true @@ -891,13 +949,8 @@ func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}, if len(hashes) >= maxTxRetrievals { return false // break in the for-each } - if meta != nil { // Only set eth/68 and upwards - bytes += uint64(meta.size) - if bytes >= maxTxRetrievalSize { - return false - } - } - return true // scheduled, try to add more + bytes += uint64(meta.size) + return bytes < maxTxRetrievalSize }) // If any hashes were allocated, request them from the peer if len(hashes) > 0 { @@ -942,28 +995,26 @@ func (f *TxFetcher) forEachPeer(peers map[string]struct{}, do func(peer string)) } } -// forEachAnnounce does a range loop over a map of announcements in production, -// but during testing it does a deterministic sorted random to allow reproducing -// issues. -func (f *TxFetcher) forEachAnnounce(announces map[common.Hash]*txMetadata, do func(hash common.Hash, meta *txMetadata) bool) { - // If we're running production, use whatever Go's map gives us - if f.rand == nil { - for hash, meta := range announces { - if !do(hash, meta) { - return - } - } - return +// forEachAnnounce loops over the given announcements in arrival order, invoking +// the do function for each until it returns false. We enforce an arrival +// ordering to minimize the chances of transaction nonce-gaps, which result in +// transactions being rejected by the txpool. +func (f *TxFetcher) forEachAnnounce(announces map[common.Hash]*txMetadataWithSeq, do func(hash common.Hash, meta txMetadata) bool) { + type announcement struct { + hash common.Hash + meta txMetadata + seq uint64 } - // We're running the test suite, make iteration deterministic - list := make([]common.Hash, 0, len(announces)) - for hash := range announces { - list = append(list, hash) + // Process announcements by their arrival order + list := make([]announcement, 0, len(announces)) + for hash, entry := range announces { + list = append(list, announcement{hash: hash, meta: entry.txMetadata, seq: entry.seq}) } - sortHashes(list) - rotateHashes(list, f.rand.Intn(len(list))) - for _, hash := range list { - if !do(hash, announces[hash]) { + sort.Slice(list, func(i, j int) bool { + return list[i].seq < list[j].seq + }) + for i := range list { + if !do(list[i].hash, list[i].meta) { return } } @@ -979,26 +1030,3 @@ func rotateStrings(slice []string, n int) { slice[i] = orig[(i+n)%len(orig)] } } - -// sortHashes sorts a slice of hashes. This method is only used in tests in order -// to simulate random map iteration but keep it deterministic. -func sortHashes(slice []common.Hash) { - for i := 0; i < len(slice); i++ { - for j := i + 1; j < len(slice); j++ { - if bytes.Compare(slice[i][:], slice[j][:]) > 0 { - slice[i], slice[j] = slice[j], slice[i] - } - } - } -} - -// rotateHashes rotates the contents of a slice by n steps. This method is only -// used in tests to simulate random map iteration but keep it deterministic. -func rotateHashes(slice []common.Hash, n int) { - orig := make([]common.Hash, len(slice)) - copy(orig, slice) - - for i := 0; i < len(orig); i++ { - slice[i] = orig[(i+n)%len(orig)] - } -} diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index d19bf8cc22..e3b91f320c 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -20,6 +20,7 @@ import ( "errors" "math/big" "math/rand" + "slices" "testing" "time" @@ -44,13 +45,10 @@ var ( type announce struct { hash common.Hash - kind *byte - size *uint32 + kind byte + size uint32 } -func typeptr(t byte) *byte { return &t } -func sizeptr(n uint32) *uint32 { return &n } - type doTxNotify struct { peer string hashes []common.Hash @@ -69,16 +67,10 @@ type doWait struct { type doDrop string type doFunc func() -type isWaitingWithMeta map[string][]announce -type isWaiting map[string][]common.Hash +type isWaiting map[string][]announce -type isScheduledWithMeta struct { - tracking map[string][]announce - fetching map[string][]common.Hash - dangling map[string][]common.Hash -} type isScheduled struct { - tracking map[string][]common.Hash + tracking map[string][]announce fetching map[string][]common.Hash dangling map[string][]common.Hash } @@ -91,104 +83,13 @@ type txFetcherTest struct { steps []interface{} } -// Tests that transaction announcements are added to a waitlist, and none -// of them are scheduled for retrieval until the wait expires. -func TestTransactionFetcherWaiting(t *testing.T) { - testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, - steps: []interface{}{ - // Initial announcement to get something into the waitlist - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, - }), - // Announce from a new peer to check that no overwrite happens - doTxNotify{peer: "B", hashes: []common.Hash{{0x03}, {0x04}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, - "B": {{0x03}, {0x04}}, - }), - // Announce clashing hashes but unique new peer - doTxNotify{peer: "C", hashes: []common.Hash{{0x01}, {0x04}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, - "B": {{0x03}, {0x04}}, - "C": {{0x01}, {0x04}}, - }), - // Announce existing and clashing hashes from existing peer - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x03}, {0x05}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x05}}, - "B": {{0x03}, {0x04}}, - "C": {{0x01}, {0x04}}, - }), - isScheduled{tracking: nil, fetching: nil}, - - // Wait for the arrival timeout which should move all expired items - // from the wait list to the scheduler - doWait{time: txArriveTimeout, step: true}, - isWaiting(nil), - isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x05}}, - "B": {{0x03}, {0x04}}, - "C": {{0x01}, {0x04}}, - }, - fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer - "A": {{0x02}, {0x03}, {0x05}}, - "C": {{0x01}, {0x04}}, - }, - }, - // Queue up a non-fetchable transaction and then trigger it with a new - // peer (weird case to test 1 line in the fetcher) - doTxNotify{peer: "C", hashes: []common.Hash{{0x06}, {0x07}}}, - isWaiting(map[string][]common.Hash{ - "C": {{0x06}, {0x07}}, - }), - doWait{time: txArriveTimeout, step: true}, - isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x05}}, - "B": {{0x03}, {0x04}}, - "C": {{0x01}, {0x04}, {0x06}, {0x07}}, - }, - fetching: map[string][]common.Hash{ - "A": {{0x02}, {0x03}, {0x05}}, - "C": {{0x01}, {0x04}}, - }, - }, - doTxNotify{peer: "D", hashes: []common.Hash{{0x06}, {0x07}}}, - isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x05}}, - "B": {{0x03}, {0x04}}, - "C": {{0x01}, {0x04}, {0x06}, {0x07}}, - "D": {{0x06}, {0x07}}, - }, - fetching: map[string][]common.Hash{ - "A": {{0x02}, {0x03}, {0x05}}, - "C": {{0x01}, {0x04}}, - "D": {{0x06}, {0x07}}, - }, - }, - }, - }) -} - // Tests that transaction announcements with associated metadata are added to a // waitlist, and none of them are scheduled for retrieval until the wait expires. // // This test is an extended version of TestTransactionFetcherWaiting. It's mostly // to cover the metadata checks without bloating up the basic behavioral tests // with all the useless extra fields. -func TestTransactionFetcherWaitingWithMeta(t *testing.T) { +func TestTransactionFetcherWaiting(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { return NewTxFetcher( @@ -201,80 +102,80 @@ func TestTransactionFetcherWaitingWithMeta(t *testing.T) { steps: []interface{}{ // Initial announcement to get something into the waitlist doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, }, }), // Announce from a new peer to check that no overwrite happens doTxNotify{peer: "B", hashes: []common.Hash{{0x03}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{333, 444}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, }), // Announce clashing hashes but unique new peer doTxNotify{peer: "C", hashes: []common.Hash{{0x01}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 444}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, }), // Announce existing and clashing hashes from existing peer. Clashes // should not overwrite previous announcements. doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x03}, {0x05}}, types: []byte{types.LegacyTxType, types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{999, 333, 555}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x05}, types.LegacyTxType, 555}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, }), // Announce clashing hashes with conflicting metadata. Somebody will // be in the wrong, but we don't know yet who. doTxNotify{peer: "D", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.BlobTxType}, sizes: []uint32{999, 222}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x05}, types.LegacyTxType, 555}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "D": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)}, - {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 999}, + {common.Hash{0x02}, types.BlobTxType, 222}, }, }), isScheduled{tracking: nil, fetching: nil}, @@ -283,25 +184,25 @@ func TestTransactionFetcherWaitingWithMeta(t *testing.T) { // from the wait list to the scheduler doWait{time: txArriveTimeout, step: true}, isWaiting(nil), - isScheduledWithMeta{ + isScheduled{ tracking: map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x05}, types.LegacyTxType, 555}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "D": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)}, - {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 999}, + {common.Hash{0x02}, types.BlobTxType, 222}, }, }, fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer @@ -313,34 +214,34 @@ func TestTransactionFetcherWaitingWithMeta(t *testing.T) { // Queue up a non-fetchable transaction and then trigger it with a new // peer (weird case to test 1 line in the fetcher) doTxNotify{peer: "C", hashes: []common.Hash{{0x06}, {0x07}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{666, 777}}, - isWaitingWithMeta(map[string][]announce{ + isWaiting(map[string][]announce{ "C": { - {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)}, - {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)}, + {common.Hash{0x06}, types.LegacyTxType, 666}, + {common.Hash{0x07}, types.LegacyTxType, 777}, }, }), doWait{time: txArriveTimeout, step: true}, - isScheduledWithMeta{ + isScheduled{ tracking: map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x05}, types.LegacyTxType, 555}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, - {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)}, - {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + {common.Hash{0x06}, types.LegacyTxType, 666}, + {common.Hash{0x07}, types.LegacyTxType, 777}, }, "D": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)}, - {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 999}, + {common.Hash{0x02}, types.BlobTxType, 222}, }, }, fetching: map[string][]common.Hash{ @@ -350,31 +251,31 @@ func TestTransactionFetcherWaitingWithMeta(t *testing.T) { }, }, doTxNotify{peer: "E", hashes: []common.Hash{{0x06}, {0x07}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{666, 777}}, - isScheduledWithMeta{ + isScheduled{ tracking: map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x05}, types.LegacyTxType, 555}, }, "B": { - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, }, "C": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)}, - {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)}, - {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)}, + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + {common.Hash{0x06}, types.LegacyTxType, 666}, + {common.Hash{0x07}, types.LegacyTxType, 777}, }, "D": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)}, - {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)}, + {common.Hash{0x01}, types.LegacyTxType, 999}, + {common.Hash{0x02}, types.BlobTxType, 222}, }, "E": { - {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)}, - {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)}, + {common.Hash{0x06}, types.LegacyTxType, 666}, + {common.Hash{0x07}, types.LegacyTxType, 777}, }, }, fetching: map[string][]common.Hash{ @@ -402,17 +303,28 @@ func TestTransactionFetcherSkipWaiting(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + doTxNotify{ + peer: "A", + hashes: []common.Hash{{0x01}, {0x02}}, + types: []byte{types.LegacyTxType, types.LegacyTxType}, + sizes: []uint32{111, 222}, + }, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -420,13 +332,18 @@ func TestTransactionFetcherSkipWaiting(t *testing.T) { }, // Announce overlaps from the same peer, ensure the new ones end up // in stage one, and clashing ones don't get double tracked - doTxNotify{peer: "A", hashes: []common.Hash{{0x02}, {0x03}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x03}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x02}, {0x03}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{222, 333}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x03}, types.LegacyTxType, 333}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -434,15 +351,25 @@ func TestTransactionFetcherSkipWaiting(t *testing.T) { }, // Announce overlaps from a new peer, ensure new transactions end up // in stage one and clashing ones get tracked for the new peer - doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x04}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x03}}, - "B": {{0x03}, {0x04}}, + doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{222, 333, 444}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x03}, types.LegacyTxType, 333}, + }, + "B": { + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, - "B": {{0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -466,17 +393,23 @@ func TestTransactionFetcherSingletonRequesting(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -484,13 +417,19 @@ func TestTransactionFetcherSingletonRequesting(t *testing.T) { }, // Announce a new set of transactions from the same peer and ensure // they do not start fetching since the peer is already busy - doTxNotify{peer: "A", hashes: []common.Hash{{0x03}, {0x04}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x03}, {0x04}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x03}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{333, 444}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -499,8 +438,13 @@ func TestTransactionFetcherSingletonRequesting(t *testing.T) { doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x04}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -508,14 +452,25 @@ func TestTransactionFetcherSingletonRequesting(t *testing.T) { }, // Announce a duplicate set of transactions from a new peer and ensure // uniquely new ones start downloading, even if clashing. - doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x05}, {0x06}}}, - isWaiting(map[string][]common.Hash{ - "B": {{0x05}, {0x06}}, + doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x05}, {0x06}}, types: []byte{types.LegacyTxType, types.LegacyTxType, types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{222, 333, 555, 666}}, + isWaiting(map[string][]announce{ + "B": { + {common.Hash{0x05}, types.LegacyTxType, 555}, + {common.Hash{0x06}, types.LegacyTxType, 666}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}, {0x03}, {0x04}}, - "B": {{0x02}, {0x03}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + {common.Hash{0x04}, types.LegacyTxType, 444}, + }, + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + {common.Hash{0x03}, types.LegacyTxType, 333}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -546,17 +501,23 @@ func TestTransactionFetcherFailedRescheduling(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -564,12 +525,17 @@ func TestTransactionFetcherFailedRescheduling(t *testing.T) { }, // While the original peer is stuck in the request, push in an second // data source. - doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}}, + doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}, types: []byte{types.LegacyTxType}, sizes: []uint32{222}}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, - "B": {{0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}, {0x02}}, @@ -583,8 +549,10 @@ func TestTransactionFetcherFailedRescheduling(t *testing.T) { doWait{time: 0, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "B": {{0x02}}, + tracking: map[string][]announce{ + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "B": {{0x02}}, @@ -616,17 +584,21 @@ func TestTransactionFetcherCleanup(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -656,17 +628,21 @@ func TestTransactionFetcherCleanupEmpty(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -695,17 +671,29 @@ func TestTransactionFetcherMissingRescheduling(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}, + doTxNotify{peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type(), testTxs[2].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size()), uint32(testTxs[2].Size())}, + }, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + {testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + {testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}, @@ -713,10 +701,12 @@ func TestTransactionFetcherMissingRescheduling(t *testing.T) { }, // Deliver the middle transaction requested, the one before which // should be dropped and the one after re-requested. - doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: true}, // This depends on the deterministic random + doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[1]}, direct: true}, isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[2]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[2]}, @@ -742,17 +732,27 @@ func TestTransactionFetcherMissingCleanup(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1]}, + doTxNotify{peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}, + }, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + }, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0], testTxsHashes[1]}, @@ -781,18 +781,23 @@ func TestTransactionFetcherBroadcasts(t *testing.T) { }, steps: []interface{}{ // Set up three transactions to be in different stats, waiting, queued and fetching - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}, types: []byte{testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[1].Size())}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}, types: []byte{testTxs[2].Type()}, sizes: []uint32{uint32(testTxs[2].Size())}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[2]}, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -829,29 +834,40 @@ func TestTransactionFetcherWaitTimerResets(t *testing.T) { ) }, steps: []interface{}{ - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + }, }), isScheduled{nil, nil, nil}, doWait{time: txArriveTimeout / 2, step: false}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + }, }), isScheduled{nil, nil, nil}, - doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}, types: []byte{types.LegacyTxType}, sizes: []uint32{222}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }), isScheduled{nil, nil, nil}, doWait{time: txArriveTimeout / 2, step: true}, - isWaiting(map[string][]common.Hash{ - "A": {{0x02}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}}, @@ -861,8 +877,11 @@ func TestTransactionFetcherWaitTimerResets(t *testing.T) { doWait{time: txArriveTimeout / 2, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}}, @@ -888,17 +907,22 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) { }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + doTxNotify{ + peer: "A", + hashes: []common.Hash{testTxsHashes[0]}, + types: []byte{testTxs[0].Type()}, + sizes: []uint32{uint32(testTxs[0].Size())}, + }, + isWaiting(map[string][]announce{ + "A": {{testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}}, }), isScheduled{tracking: nil, fetching: nil}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + tracking: map[string][]announce{ + "A": {{testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}}, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -915,11 +939,16 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) { }, }, // Ensure that followup announcements don't get scheduled - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}}, + doTxNotify{ + peer: "A", + hashes: []common.Hash{testTxsHashes[1]}, + types: []byte{testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[1].Size())}, + }, doWait{time: txArriveTimeout, step: true}, isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[1]}, + tracking: map[string][]announce{ + "A": {{testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}}, }, fetching: nil, dangling: map[string][]common.Hash{ @@ -930,8 +959,8 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) { doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[1]}, + tracking: map[string][]announce{ + "A": {{testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}}, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[1]}, @@ -953,16 +982,20 @@ func TestTransactionFetcherTimeoutTimerResets(t *testing.T) { ) }, steps: []interface{}{ - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}}, + doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}, types: []byte{types.LegacyTxType}, sizes: []uint32{222}}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}}, - "B": {{0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + }, + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}}, @@ -971,8 +1004,10 @@ func TestTransactionFetcherTimeoutTimerResets(t *testing.T) { }, doWait{time: txFetchTimeout - txArriveTimeout, step: true}, isScheduled{ - tracking: map[string][]common.Hash{ - "B": {{0x02}}, + tracking: map[string][]announce{ + "B": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "B": {{0x02}}, @@ -998,9 +1033,22 @@ func TestTransactionFetcherTimeoutTimerResets(t *testing.T) { // number of them will be requested at a time. func TestTransactionFetcherRateLimiting(t *testing.T) { // Create a slew of transactions and announce them - var hashes []common.Hash + var ( + hashes []common.Hash + ts []byte + sizes []uint32 + announces []announce + ) for i := 0; i < maxTxAnnounces; i++ { - hashes = append(hashes, common.Hash{byte(i / 256), byte(i % 256)}) + hash := common.Hash{byte(i / 256), byte(i % 256)} + hashes = append(hashes, hash) + ts = append(ts, types.LegacyTxType) + sizes = append(sizes, 111) + announces = append(announces, announce{ + hash: hash, + kind: types.LegacyTxType, + size: 111, + }) } testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { @@ -1014,15 +1062,15 @@ func TestTransactionFetcherRateLimiting(t *testing.T) { steps: []interface{}{ // Announce all the transactions, wait a bit and ensure only a small // percentage gets requested - doTxNotify{peer: "A", hashes: hashes}, + doTxNotify{peer: "A", hashes: hashes, types: ts, sizes: sizes}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": hashes, + tracking: map[string][]announce{ + "A": announces, }, fetching: map[string][]common.Hash{ - "A": hashes[1643 : 1643+maxTxRetrievals], + "A": hashes[:maxTxRetrievals], }, }, }, @@ -1064,27 +1112,27 @@ func TestTransactionFetcherBandwidthLimiting(t *testing.T) { }, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), - isScheduledWithMeta{ + isScheduled{ tracking: map[string][]announce{ "A": { - {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)}, - {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)}, - {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)}, - {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)}, + {common.Hash{0x01}, types.LegacyTxType, 48 * 1024}, + {common.Hash{0x02}, types.LegacyTxType, 48 * 1024}, + {common.Hash{0x03}, types.LegacyTxType, 48 * 1024}, + {common.Hash{0x04}, types.LegacyTxType, 48 * 1024}, }, "B": { - {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(maxTxRetrievalSize)}, - {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(maxTxRetrievalSize)}, + {common.Hash{0x05}, types.LegacyTxType, maxTxRetrievalSize}, + {common.Hash{0x06}, types.LegacyTxType, maxTxRetrievalSize}, }, "C": { - {common.Hash{0x07}, typeptr(types.BlobTxType), sizeptr(params.MaxBlobGasPerBlock)}, - {common.Hash{0x08}, typeptr(types.BlobTxType), sizeptr(params.MaxBlobGasPerBlock)}, + {common.Hash{0x07}, types.BlobTxType, params.MaxBlobGasPerBlock}, + {common.Hash{0x08}, types.BlobTxType, params.MaxBlobGasPerBlock}, }, }, fetching: map[string][]common.Hash{ - "A": {{0x02}, {0x03}, {0x04}}, - "B": {{0x06}}, - "C": {{0x08}}, + "A": {{0x01}, {0x02}, {0x03}}, + "B": {{0x05}}, + "C": {{0x07}}, }, }, }, @@ -1095,13 +1143,41 @@ func TestTransactionFetcherBandwidthLimiting(t *testing.T) { // request at the same time is hard capped. func TestTransactionFetcherDoSProtection(t *testing.T) { // Create a slew of transactions and to announce them - var hashesA []common.Hash + var ( + hashesA []common.Hash + typesA []byte + sizesA []uint32 + announceA []announce + ) for i := 0; i < maxTxAnnounces+1; i++ { - hashesA = append(hashesA, common.Hash{0x01, byte(i / 256), byte(i % 256)}) + hash := common.Hash{0x01, byte(i / 256), byte(i % 256)} + hashesA = append(hashesA, hash) + typesA = append(typesA, types.LegacyTxType) + sizesA = append(sizesA, 111) + + announceA = append(announceA, announce{ + hash: hash, + kind: types.LegacyTxType, + size: 111, + }) } - var hashesB []common.Hash + var ( + hashesB []common.Hash + typesB []byte + sizesB []uint32 + announceB []announce + ) for i := 0; i < maxTxAnnounces+1; i++ { - hashesB = append(hashesB, common.Hash{0x02, byte(i / 256), byte(i % 256)}) + hash := common.Hash{0x02, byte(i / 256), byte(i % 256)} + hashesB = append(hashesB, hash) + typesB = append(typesB, types.LegacyTxType) + sizesB = append(sizesB, 111) + + announceB = append(announceB, announce{ + hash: hash, + kind: types.LegacyTxType, + size: 111, + }) } testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { @@ -1114,45 +1190,45 @@ func TestTransactionFetcherDoSProtection(t *testing.T) { }, steps: []interface{}{ // Announce half of the transaction and wait for them to be scheduled - doTxNotify{peer: "A", hashes: hashesA[:maxTxAnnounces/2]}, - doTxNotify{peer: "B", hashes: hashesB[:maxTxAnnounces/2-1]}, + doTxNotify{peer: "A", hashes: hashesA[:maxTxAnnounces/2], types: typesA[:maxTxAnnounces/2], sizes: sizesA[:maxTxAnnounces/2]}, + doTxNotify{peer: "B", hashes: hashesB[:maxTxAnnounces/2-1], types: typesB[:maxTxAnnounces/2-1], sizes: sizesB[:maxTxAnnounces/2-1]}, doWait{time: txArriveTimeout, step: true}, // Announce the second half and keep them in the wait list - doTxNotify{peer: "A", hashes: hashesA[maxTxAnnounces/2 : maxTxAnnounces]}, - doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces/2-1 : maxTxAnnounces-1]}, + doTxNotify{peer: "A", hashes: hashesA[maxTxAnnounces/2 : maxTxAnnounces], types: typesA[maxTxAnnounces/2 : maxTxAnnounces], sizes: sizesA[maxTxAnnounces/2 : maxTxAnnounces]}, + doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces/2-1 : maxTxAnnounces-1], types: typesB[maxTxAnnounces/2-1 : maxTxAnnounces-1], sizes: sizesB[maxTxAnnounces/2-1 : maxTxAnnounces-1]}, // Ensure the hashes are split half and half - isWaiting(map[string][]common.Hash{ - "A": hashesA[maxTxAnnounces/2 : maxTxAnnounces], - "B": hashesB[maxTxAnnounces/2-1 : maxTxAnnounces-1], + isWaiting(map[string][]announce{ + "A": announceA[maxTxAnnounces/2 : maxTxAnnounces], + "B": announceB[maxTxAnnounces/2-1 : maxTxAnnounces-1], }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": hashesA[:maxTxAnnounces/2], - "B": hashesB[:maxTxAnnounces/2-1], + tracking: map[string][]announce{ + "A": announceA[:maxTxAnnounces/2], + "B": announceB[:maxTxAnnounces/2-1], }, fetching: map[string][]common.Hash{ - "A": hashesA[1643 : 1643+maxTxRetrievals], - "B": append(append([]common.Hash{}, hashesB[maxTxAnnounces/2-3:maxTxAnnounces/2-1]...), hashesB[:maxTxRetrievals-2]...), + "A": hashesA[:maxTxRetrievals], + "B": hashesB[:maxTxRetrievals], }, }, // Ensure that adding even one more hash results in dropping the hash - doTxNotify{peer: "A", hashes: []common.Hash{hashesA[maxTxAnnounces]}}, - doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces-1 : maxTxAnnounces+1]}, + doTxNotify{peer: "A", hashes: []common.Hash{hashesA[maxTxAnnounces]}, types: []byte{typesA[maxTxAnnounces]}, sizes: []uint32{sizesA[maxTxAnnounces]}}, + doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces-1 : maxTxAnnounces+1], types: typesB[maxTxAnnounces-1 : maxTxAnnounces+1], sizes: sizesB[maxTxAnnounces-1 : maxTxAnnounces+1]}, - isWaiting(map[string][]common.Hash{ - "A": hashesA[maxTxAnnounces/2 : maxTxAnnounces], - "B": hashesB[maxTxAnnounces/2-1 : maxTxAnnounces], + isWaiting(map[string][]announce{ + "A": announceA[maxTxAnnounces/2 : maxTxAnnounces], + "B": announceB[maxTxAnnounces/2-1 : maxTxAnnounces], }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": hashesA[:maxTxAnnounces/2], - "B": hashesB[:maxTxAnnounces/2-1], + tracking: map[string][]announce{ + "A": announceA[:maxTxAnnounces/2], + "B": announceB[:maxTxAnnounces/2-1], }, fetching: map[string][]common.Hash{ - "A": hashesA[1643 : 1643+maxTxRetrievals], - "B": append(append([]common.Hash{}, hashesB[maxTxAnnounces/2-3:maxTxAnnounces/2-1]...), hashesB[:maxTxRetrievals-2]...), + "A": hashesA[:maxTxRetrievals], + "B": hashesB[:maxTxRetrievals], }, }, }, @@ -1182,15 +1258,23 @@ func TestTransactionFetcherUnderpricedDedup(t *testing.T) { }, steps: []interface{}{ // Deliver a transaction through the fetcher, but reject as underpriced - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}}, + doTxNotify{peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}, + }, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1]}, direct: true}, isScheduled{nil, nil, nil}, // Try to announce the transaction again, ensure it's not scheduled back - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}}, // [2] is needed to force a step in the fetcher - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[2]}, + doTxNotify{peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type(), testTxs[2].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size()), uint32(testTxs[2].Size())}, + }, // [2] is needed to force a step in the fetcher + isWaiting(map[string][]announce{ + "A": {{testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}}, }), isScheduled{nil, nil, nil}, }, @@ -1210,21 +1294,38 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) { for i := 0; i < maxTxUnderpricedSetSize+1; i++ { txs = append(txs, types.NewTransaction(rand.Uint64(), common.Address{byte(rand.Intn(256))}, new(big.Int), 0, new(big.Int), nil)) } - hashes := make([]common.Hash, len(txs)) - for i, tx := range txs { - hashes[i] = tx.Hash() + var ( + hashes []common.Hash + ts []byte + sizes []uint32 + annos []announce + ) + for _, tx := range txs { + hashes = append(hashes, tx.Hash()) + ts = append(ts, tx.Type()) + sizes = append(sizes, uint32(tx.Size())) + annos = append(annos, announce{ + hash: tx.Hash(), + kind: tx.Type(), + size: uint32(tx.Size()), + }) } // Generate a set of steps to announce and deliver the entire set of transactions var steps []interface{} for i := 0; i < maxTxUnderpricedSetSize/maxTxRetrievals; i++ { - steps = append(steps, doTxNotify{peer: "A", hashes: hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals]}) - steps = append(steps, isWaiting(map[string][]common.Hash{ - "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals], + steps = append(steps, doTxNotify{ + peer: "A", + hashes: hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals], + types: ts[i*maxTxRetrievals : (i+1)*maxTxRetrievals], + sizes: sizes[i*maxTxRetrievals : (i+1)*maxTxRetrievals], + }) + steps = append(steps, isWaiting(map[string][]announce{ + "A": annos[i*maxTxRetrievals : (i+1)*maxTxRetrievals], })) steps = append(steps, doWait{time: txArriveTimeout, step: true}) steps = append(steps, isScheduled{ - tracking: map[string][]common.Hash{ - "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals], + tracking: map[string][]announce{ + "A": annos[i*maxTxRetrievals : (i+1)*maxTxRetrievals], }, fetching: map[string][]common.Hash{ "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals], @@ -1252,7 +1353,12 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) { }, steps: append(steps, []interface{}{ // The preparation of the test has already been done in `steps`, add the last check - doTxNotify{peer: "A", hashes: []common.Hash{hashes[maxTxUnderpricedSetSize]}}, + doTxNotify{ + peer: "A", + hashes: []common.Hash{hashes[maxTxUnderpricedSetSize]}, + types: []byte{ts[maxTxUnderpricedSetSize]}, + sizes: []uint32{sizes[maxTxUnderpricedSetSize]}, + }, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{txs[maxTxUnderpricedSetSize]}, direct: true}, isUnderpriced(maxTxUnderpricedSetSize), @@ -1282,18 +1388,23 @@ func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) { isScheduled{nil, nil, nil}, // Set up a few hashes into various stages - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}, types: []byte{testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[1].Size())}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}, types: []byte{testTxs[2].Type()}, sizes: []uint32{uint32(testTxs[2].Size())}}, - isWaiting(map[string][]common.Hash{ - "A": {testTxsHashes[2]}, + isWaiting(map[string][]announce{ + "A": { + {testTxsHashes[2], testTxs[2].Type(), uint32(testTxs[2].Size())}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0], testTxsHashes[1]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -1329,18 +1440,23 @@ func TestTransactionFetcherDrop(t *testing.T) { }, steps: []interface{}{ // Set up a few hashes into various stages - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}, types: []byte{types.LegacyTxType}, sizes: []uint32{222}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "A", hashes: []common.Hash{{0x03}}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x03}}, types: []byte{types.LegacyTxType}, sizes: []uint32{333}}, - isWaiting(map[string][]common.Hash{ - "A": {{0x03}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x03}, types.LegacyTxType, 333}, + }, }), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}, {0x02}}, + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, }, fetching: map[string][]common.Hash{ "A": {{0x01}}, @@ -1352,12 +1468,14 @@ func TestTransactionFetcherDrop(t *testing.T) { isScheduled{nil, nil, nil}, // Push the node into a dangling (timeout) state - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {testTxsHashes[0]}, + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, }, fetching: map[string][]common.Hash{ "A": {testTxsHashes[0]}, @@ -1396,15 +1514,15 @@ func TestTransactionFetcherDropRescheduling(t *testing.T) { }, steps: []interface{}{ // Set up a few hashes into various stages - doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}}, + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, doWait{time: txArriveTimeout, step: true}, - doTxNotify{peer: "B", hashes: []common.Hash{{0x01}}}, + doTxNotify{peer: "B", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "A": {{0x01}}, - "B": {{0x01}}, + tracking: map[string][]announce{ + "A": {{common.Hash{0x01}, types.LegacyTxType, 111}}, + "B": {{common.Hash{0x01}, types.LegacyTxType, 111}}, }, fetching: map[string][]common.Hash{ "A": {{0x01}}, @@ -1414,8 +1532,8 @@ func TestTransactionFetcherDropRescheduling(t *testing.T) { doDrop("A"), isWaiting(nil), isScheduled{ - tracking: map[string][]common.Hash{ - "B": {{0x01}}, + tracking: map[string][]announce{ + "B": {{common.Hash{0x01}, types.LegacyTxType, 111}}, }, fetching: map[string][]common.Hash{ "B": {{0x01}}, @@ -1442,42 +1560,57 @@ func TestInvalidAnnounceMetadata(t *testing.T) { }, steps: []interface{}{ // Initial announcement to get something into the waitlist - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, types: []byte{testTxs[0].Type(), testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}}, - isWaitingWithMeta(map[string][]announce{ + doTxNotify{ + peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}, + }, + isWaiting(map[string][]announce{ "A": { - {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))}, - {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))}, + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, }, }), // Announce from new peers conflicting transactions - doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{1024 + uint32(testTxs[0].Size())}}, - doTxNotify{peer: "C", hashes: []common.Hash{testTxsHashes[1]}, types: []byte{1 + testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[1].Size())}}, - isWaitingWithMeta(map[string][]announce{ + doTxNotify{ + peer: "B", + hashes: []common.Hash{testTxsHashes[0]}, + types: []byte{testTxs[0].Type()}, + sizes: []uint32{1024 + uint32(testTxs[0].Size())}, + }, + doTxNotify{ + peer: "C", + hashes: []common.Hash{testTxsHashes[1]}, + types: []byte{1 + testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[1].Size())}, + }, + isWaiting(map[string][]announce{ "A": { - {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))}, - {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))}, + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, }, "B": { - {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(1024 + uint32(testTxs[0].Size()))}, + {testTxsHashes[0], testTxs[0].Type(), 1024 + uint32(testTxs[0].Size())}, }, "C": { - {testTxsHashes[1], typeptr(1 + testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))}, + {testTxsHashes[1], 1 + testTxs[1].Type(), uint32(testTxs[1].Size())}, }, }), // Schedule all the transactions for retrieval doWait{time: txArriveTimeout, step: true}, - isWaitingWithMeta(nil), - isScheduledWithMeta{ + isWaiting(nil), + isScheduled{ tracking: map[string][]announce{ "A": { - {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))}, - {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))}, + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + {testTxsHashes[1], testTxs[1].Type(), uint32(testTxs[1].Size())}, }, "B": { - {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(1024 + uint32(testTxs[0].Size()))}, + {testTxsHashes[0], testTxs[0].Type(), 1024 + uint32(testTxs[0].Size())}, }, "C": { - {testTxsHashes[1], typeptr(1 + testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))}, + {testTxsHashes[1], 1 + testTxs[1].Type(), uint32(testTxs[1].Size())}, }, }, fetching: map[string][]common.Hash{ @@ -1510,12 +1643,12 @@ func TestTransactionFetcherFuzzCrash01(t *testing.T) { }, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}}, // Notify the dangling transaction once more and crash via a timeout - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txFetchTimeout, step: true}, }, }) @@ -1538,12 +1671,12 @@ func TestTransactionFetcherFuzzCrash02(t *testing.T) { }, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}}, // Notify the dangling transaction once more, re-fetch, and crash via a drop and timeout - doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doDrop("A"), doWait{time: txFetchTimeout, step: true}, @@ -1568,12 +1701,17 @@ func TestTransactionFetcherFuzzCrash03(t *testing.T) { }, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}}, + doTxNotify{ + peer: "A", + hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, + types: []byte{testTxs[0].Type(), testTxs[1].Type()}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}, + }, doWait{time: txFetchTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1]}}, // Notify the dangling transaction once more, partially deliver, clash&crash with a timeout - doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[1]}, direct: true}, @@ -1605,12 +1743,12 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) { }, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast - doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}}, // Notify the dangling transaction once more, re-fetch, and crash via an in-flight disconnect - doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}}, + doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, doWait{time: txArriveTimeout, step: true}, doFunc(func() { proceed <- struct{}{} // Allow peer A to return the failure @@ -1621,6 +1759,76 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) { }) } +// This test ensures the blob transactions will be scheduled for fetching +// once they are announced in the network. +func TestBlobTransactionAnnounce(t *testing.T) { + testTransactionFetcherParallel(t, txFetcherTest{ + init: func() *TxFetcher { + return NewTxFetcher( + func(common.Hash) bool { return false }, + nil, + func(string, []common.Hash) error { return nil }, + nil, + ) + }, + steps: []interface{}{ + // Initial announcement to get something into the waitlist + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + }), + // Announce a blob transaction + doTxNotify{peer: "B", hashes: []common.Hash{{0x03}}, types: []byte{types.BlobTxType}, sizes: []uint32{333}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + "B": { + {common.Hash{0x03}, types.BlobTxType, 333}, + }, + }), + doWait{time: 0, step: true}, // zero time, but the blob fetching should be scheduled + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + }), + isScheduled{ + tracking: map[string][]announce{ + "B": { + {common.Hash{0x03}, types.BlobTxType, 333}, + }, + }, + fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer + "B": {{0x03}}, + }, + }, + doWait{time: txArriveTimeout, step: true}, // zero time, but the blob fetching should be scheduled + isWaiting(nil), + isScheduled{ + tracking: map[string][]announce{ + "A": { + {common.Hash{0x01}, types.LegacyTxType, 111}, + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + "B": { + {common.Hash{0x03}, types.BlobTxType, 333}, + }, + }, + fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer + "A": {{0x01}, {0x02}}, + "B": {{0x03}}, + }, + }, + }, + }) +} + func testTransactionFetcherParallel(t *testing.T, tt txFetcherTest) { t.Parallel() testTransactionFetcher(t, tt) @@ -1651,30 +1859,6 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { // Crunch through all the test steps and execute them for i, step := range tt.steps { - // Auto-expand certain steps to ones with metadata - switch old := step.(type) { - case isWaiting: - new := make(isWaitingWithMeta) - for peer, hashes := range old { - for _, hash := range hashes { - new[peer] = append(new[peer], announce{hash, nil, nil}) - } - } - step = new - - case isScheduled: - new := isScheduledWithMeta{ - tracking: make(map[string][]announce), - fetching: old.fetching, - dangling: old.dangling, - } - for peer, hashes := range old.tracking { - for _, hash := range hashes { - new.tracking[peer] = append(new.tracking[peer], announce{hash, nil, nil}) - } - } - step = new - } // Process the original or expanded steps switch step := step.(type) { case doTxNotify: @@ -1709,7 +1893,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { case doFunc: step() - case isWaitingWithMeta: + case isWaiting: // We need to check that the waiting list (stage 1) internals // match with the expected set. Check the peer->hash mappings // first. @@ -1723,18 +1907,13 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { if meta, ok := waiting[ann.hash]; !ok { t.Errorf("step %d, peer %s: hash %x missing from waitslots", i, peer, ann.hash) } else { - if (meta == nil && (ann.kind != nil || ann.size != nil)) || - (meta != nil && (ann.kind == nil || ann.size == nil)) || - (meta != nil && (meta.kind != *ann.kind || meta.size != *ann.size)) { - t.Errorf("step %d, peer %s, hash %x: waitslot metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, *ann.kind, *ann.size) + if meta.kind != ann.kind || meta.size != ann.size { + t.Errorf("step %d, peer %s, hash %x: waitslot metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, ann.kind, ann.size) } } } for hash, meta := range waiting { - ann := announce{hash: hash} - if meta != nil { - ann.kind, ann.size = &meta.kind, &meta.size - } + ann := announce{hash: hash, kind: meta.kind, size: meta.size} if !containsAnnounce(announces, ann) { t.Errorf("step %d, peer %s: announce %v extra in waitslots", i, peer, ann) } @@ -1779,7 +1958,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { } } - case isScheduledWithMeta: + case isScheduled: // Check that all scheduled announces are accounted for and no // extra ones are present. for peer, announces := range step.tracking { @@ -1792,18 +1971,13 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { if meta, ok := scheduled[ann.hash]; !ok { t.Errorf("step %d, peer %s: hash %x missing from announces", i, peer, ann.hash) } else { - if (meta == nil && (ann.kind != nil || ann.size != nil)) || - (meta != nil && (ann.kind == nil || ann.size == nil)) || - (meta != nil && (meta.kind != *ann.kind || meta.size != *ann.size)) { - t.Errorf("step %d, peer %s, hash %x: announce metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, *ann.kind, *ann.size) + if meta.kind != ann.kind || meta.size != ann.size { + t.Errorf("step %d, peer %s, hash %x: announce metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, ann.kind, ann.size) } } } for hash, meta := range scheduled { - ann := announce{hash: hash} - if meta != nil { - ann.kind, ann.size = &meta.kind, &meta.size - } + ann := announce{hash: hash, kind: meta.kind, size: meta.size} if !containsAnnounce(announces, ann) { t.Errorf("step %d, peer %s: announce %x extra in announces", i, peer, hash) } @@ -1823,12 +1997,12 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { continue } for _, hash := range hashes { - if !containsHash(request.hashes, hash) { + if !slices.Contains(request.hashes, hash) { t.Errorf("step %d, peer %s: hash %x missing from requests", i, peer, hash) } } for _, hash := range request.hashes { - if !containsHash(hashes, hash) { + if !slices.Contains(hashes, hash) { t.Errorf("step %d, peer %s: hash %x extra in requests", i, peer, hash) } } @@ -1850,7 +2024,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { for hash := range fetcher.fetching { var found bool for _, req := range fetcher.requests { - if containsHash(req.hashes, hash) { + if slices.Contains(req.hashes, hash) { found = true break } @@ -1891,12 +2065,12 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { continue } for _, hash := range hashes { - if !containsHash(request.hashes, hash) { + if !slices.Contains(request.hashes, hash) { t.Errorf("step %d, peer %s: hash %x missing from requests", i, peer, hash) } } for _, hash := range request.hashes { - if !containsHash(hashes, hash) { + if !slices.Contains(hashes, hash) { t.Errorf("step %d, peer %s: hash %x extra in requests", i, peer, hash) } } @@ -1909,7 +2083,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { for _, ann := range announces { var found bool for _, hs := range step.fetching { - if containsHash(hs, ann.hash) { + if slices.Contains(hs, ann.hash) { found = true break } @@ -1925,7 +2099,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { } } for hash := range fetcher.announced { - if !containsHash(queued, hash) { + if !slices.Contains(queued, hash) { t.Errorf("step %d: hash %x extra in announced", i, hash) } } @@ -1953,18 +2127,10 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { func containsAnnounce(slice []announce, ann announce) bool { for _, have := range slice { if have.hash == ann.hash { - if have.kind == nil || ann.kind == nil { - if have.kind != ann.kind { - return false - } - } else if *have.kind != *ann.kind { + if have.kind != ann.kind { return false } - if have.size == nil || ann.size == nil { - if have.size != ann.size { - return false - } - } else if *have.size != *ann.size { + if have.size != ann.size { return false } return true @@ -1984,16 +2150,6 @@ func containsHashInAnnounces(slice []announce, hash common.Hash) bool { return false } -// containsHash returns whether a hash is contained within a hash slice. -func containsHash(slice []common.Hash, hash common.Hash) bool { - for _, have := range slice { - if have == hash { - return true - } - } - return false -} - // Tests that a transaction is forgotten after the timeout. func TestTransactionForgotten(t *testing.T) { fetcher := NewTxFetcher( diff --git a/eth/filters/api.go b/eth/filters/api.go index a7ae2aa940..fdac76890c 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -35,10 +35,11 @@ import ( ) var ( - errInvalidTopic = errors.New("invalid topic(s)") - errFilterNotFound = errors.New("filter not found") - errInvalidBlockRange = errors.New("invalid block range params") - errExceedMaxTopics = errors.New("exceed max topics") + errInvalidTopic = errors.New("invalid topic(s)") + errFilterNotFound = errors.New("filter not found") + errInvalidBlockRange = errors.New("invalid block range params") + errPendingLogsUnsupported = errors.New("pending logs are not supported") + errExceedMaxTopics = errors.New("exceed max topics") ) // The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 @@ -184,8 +185,6 @@ func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool) } case <-rpcSub.Err(): return - case <-notifier.Closed(): - return } } }) @@ -245,9 +244,6 @@ func (api *FilterAPI) NewVotes(ctx context.Context) (*rpc.Subscription, error) { case <-rpcSub.Err(): voteSub.Unsubscribe() return - case <-notifier.Closed(): - voteSub.Unsubscribe() - return } } }) @@ -308,8 +304,6 @@ func (api *FilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, error) { notifier.Notify(rpcSub.ID, h) case <-rpcSub.Err(): return - case <-notifier.Closed(): - return } } }) @@ -369,9 +363,6 @@ func (api *FilterAPI) NewFinalizedHeaders(ctx context.Context) (*rpc.Subscriptio case <-rpcSub.Err(): headersSub.Unsubscribe() return - case <-notifier.Closed(): - headersSub.Unsubscribe() - return } } }) @@ -407,8 +398,6 @@ func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subsc } case <-rpcSub.Err(): // client send an unsubscribe request return - case <-notifier.Closed(): // connection dropped - return } } }) @@ -588,7 +577,7 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { f.txs = nil return hashes, nil } - case LogsSubscription, MinedAndPendingLogsSubscription: + case LogsSubscription: logs := f.logs f.logs = nil return returnLogs(logs), nil diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 2fb9d7d58c..f9f535f023 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -20,6 +20,7 @@ import ( "context" "errors" "math/big" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/bloombits" @@ -110,19 +111,9 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return f.blockLogs(ctx, header) } - var ( - beginPending = f.begin == rpc.PendingBlockNumber.Int64() - endPending = f.end == rpc.PendingBlockNumber.Int64() - ) - - // special case for pending logs - if beginPending && !endPending { - return nil, errInvalidBlockRange - } - - // Short-cut if all we care about is pending logs - if beginPending && endPending { - return f.pendingLogs(), nil + // Disallow pending logs. + if f.begin == rpc.PendingBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() { + return nil, errPendingLogsUnsupported } resolveSpecial := func(number int64) (int64, error) { @@ -167,16 +158,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { case log := <-logChan: logs = append(logs, log) case err := <-errChan: - if err != nil { - // if an error occurs during extraction, we do return the extracted data - return logs, err - } - // Append the pending ones - if endPending { - pendingLogs := f.pendingLogs() - logs = append(logs, pendingLogs...) - } - return logs, nil + return logs, err } } } @@ -334,32 +316,6 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ return logs, nil } -// pendingLogs returns the logs matching the filter criteria within the pending block. -func (f *Filter) pendingLogs() []*types.Log { - block, receipts := f.sys.backend.PendingBlockAndReceipts() - if block == nil || receipts == nil { - return nil - } - if bloomFilter(block.Bloom(), f.addresses, f.topics) { - var unfiltered []*types.Log - for _, r := range receipts { - unfiltered = append(unfiltered, r.Logs...) - } - return filterLogs(unfiltered, nil, nil, f.addresses, f.topics) - } - return nil -} - -// includes returns true if the element is present in the list. -func includes[T comparable](things []T, element T) bool { - for _, thing := range things { - if thing == element { - return true - } - } - return false -} - // filterLogs creates a slice of logs matching the given criteria. func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log { var check = func(log *types.Log) bool { @@ -369,7 +325,7 @@ func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []comm if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber { return false } - if len(addresses) > 0 && !includes(addresses, log.Address) { + if len(addresses) > 0 && !slices.Contains(addresses, log.Address) { return false } // If the to filtered topics is greater than the amount of topics in logs, skip. @@ -380,7 +336,7 @@ func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []comm if len(sub) == 0 { continue // empty rule set == wildcard } - if !includes(sub, log.Topics[i]) { + if !slices.Contains(sub, log.Topics[i]) { return false } } diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 21f62b119d..9bac268cd1 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -61,7 +61,6 @@ type Backend interface { GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) - PendingBlockAndReceipts() (*types.Block, types.Receipts) CurrentHeader() *types.Header ChainConfig() *params.ChainConfig @@ -70,7 +69,6 @@ type Backend interface { SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription - SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribeNewVoteEvent(chan<- core.NewVoteEvent) event.Subscription BloomStatus() (uint64, uint64) @@ -96,7 +94,7 @@ func NewFilterSystem(backend Backend, config Config) *FilterSystem { type logCacheElem struct { logs []*types.Log - body atomic.Value + body atomic.Pointer[types.Body] } // cachedLogElem loads block logs from the backend and caches the result. @@ -134,7 +132,7 @@ func (sys *FilterSystem) cachedLogElem(ctx context.Context, blockHash common.Has func (sys *FilterSystem) cachedGetBody(ctx context.Context, elem *logCacheElem, hash common.Hash, number uint64) (*types.Body, error) { if body := elem.body.Load(); body != nil { - return body.(*types.Body), nil + return body, nil } body, err := sys.backend.GetBody(ctx, hash, rpc.BlockNumber(number)) if err != nil { @@ -153,10 +151,6 @@ const ( UnknownSubscription Type = iota // LogsSubscription queries for new or removed (chain reorg) logs LogsSubscription - // PendingLogsSubscription queries for logs in pending blocks - PendingLogsSubscription - // MinedAndPendingLogsSubscription queries for logs in mined and pending blocks. - MinedAndPendingLogsSubscription // PendingTransactionsSubscription queries for pending transactions entering // the pending state PendingTransactionsSubscription @@ -210,7 +204,6 @@ type EventSystem struct { txsSub event.Subscription // Subscription for new transaction event logsSub event.Subscription // Subscription for new log event rmLogsSub event.Subscription // Subscription for removed log event - pendingLogsSub event.Subscription // Subscription for pending log event chainSub event.Subscription // Subscription for new chain event finalizedHeaderSub event.Subscription // Subscription for new finalized header voteSub event.Subscription // Subscription for new vote event @@ -220,7 +213,6 @@ type EventSystem struct { uninstall chan *subscription // remove filter for event notification txsCh chan core.NewTxsEvent // Channel to receive new transactions event logsCh chan []*types.Log // Channel to receive new log event - pendingLogsCh chan []*types.Log // Channel to receive new log event rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event chainCh chan core.ChainEvent // Channel to receive new chain event finalizedHeaderCh chan core.FinalizedHeaderEvent // Channel to receive new finalized header event @@ -242,7 +234,6 @@ func NewEventSystem(sys *FilterSystem) *EventSystem { txsCh: make(chan core.NewTxsEvent, txChanSize), logsCh: make(chan []*types.Log, logsChanSize), rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), - pendingLogsCh: make(chan []*types.Log, logsChanSize), chainCh: make(chan core.ChainEvent, chainEvChanSize), finalizedHeaderCh: make(chan core.FinalizedHeaderEvent, finalizedHeaderEvChanSize), voteCh: make(chan core.NewVoteEvent, voteChanSize), @@ -253,12 +244,11 @@ func NewEventSystem(sys *FilterSystem) *EventSystem { m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh) m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh) m.chainSub = m.backend.SubscribeChainEvent(m.chainCh) - m.pendingLogsSub = m.backend.SubscribePendingLogsEvent(m.pendingLogsCh) m.finalizedHeaderSub = m.backend.SubscribeFinalizedHeaderEvent(m.finalizedHeaderCh) m.voteSub = m.backend.SubscribeNewVoteEvent(m.voteCh) // Make sure none of the subscriptions are empty - if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.pendingLogsSub == nil { + if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil { log.Crit("Subscribe for event system failed") } if m.voteSub == nil || m.finalizedHeaderSub == nil { @@ -334,10 +324,11 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ to = rpc.BlockNumber(crit.ToBlock.Int64()) } - // only interested in pending logs - if from == rpc.PendingBlockNumber && to == rpc.PendingBlockNumber { - return es.subscribePendingLogs(crit, logs), nil + // Pending logs are not supported anymore. + if from == rpc.PendingBlockNumber || to == rpc.PendingBlockNumber { + return nil, errPendingLogsUnsupported } + // only interested in new mined logs if from == rpc.LatestBlockNumber && to == rpc.LatestBlockNumber { return es.subscribeLogs(crit, logs), nil @@ -346,10 +337,6 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ if from >= 0 && to >= 0 && to >= from { return es.subscribeLogs(crit, logs), nil } - // interested in mined logs from a specific block number, new logs and pending logs - if from >= rpc.LatestBlockNumber && to == rpc.PendingBlockNumber { - return es.subscribeMinedPendingLogs(crit, logs), nil - } // interested in logs from a specific block number to new mined blocks if from >= 0 && to == rpc.LatestBlockNumber { return es.subscribeLogs(crit, logs), nil @@ -357,24 +344,6 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ return nil, errInvalidBlockRange } -// subscribeMinedPendingLogs creates a subscription that returned mined and -// pending logs that match the given criteria. -func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: MinedAndPendingLogsSubscription, - logsCrit: crit, - created: time.Now(), - logs: logs, - txs: make(chan []*types.Transaction), - headers: make(chan *types.Header), - votes: make(chan *types.VoteEnvelope), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - // subscribeLogs creates a subscription that will write all logs matching the // given criteria to the given logs channel. func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { @@ -393,24 +362,6 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ return es.subscribe(sub) } -// subscribePendingLogs creates a subscription that writes contract event logs for -// transactions that enter the transaction pool. -func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: PendingLogsSubscription, - logsCrit: crit, - created: time.Now(), - logs: logs, - txs: make(chan []*types.Transaction), - headers: make(chan *types.Header), - votes: make(chan *types.VoteEnvelope), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - // SubscribeNewHeads creates a subscription that writes the header of a block that is // imported in the chain. func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscription { @@ -493,18 +444,6 @@ func (es *EventSystem) handleLogs(filters filterIndex, ev []*types.Log) { } } -func (es *EventSystem) handlePendingLogs(filters filterIndex, ev []*types.Log) { - if len(ev) == 0 { - return - } - for _, f := range filters[PendingLogsSubscription] { - matchedLogs := filterLogs(ev, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics) - if len(matchedLogs) > 0 { - f.logs <- matchedLogs - } - } -} - func (es *EventSystem) handleTxsEvent(filters filterIndex, ev core.NewTxsEvent) { for _, f := range filters[PendingTransactionsSubscription] { f.txs <- ev.Txs @@ -536,7 +475,6 @@ func (es *EventSystem) eventLoop() { es.txsSub.Unsubscribe() es.logsSub.Unsubscribe() es.rmLogsSub.Unsubscribe() - es.pendingLogsSub.Unsubscribe() es.chainSub.Unsubscribe() es.finalizedHeaderSub.Unsubscribe() if es.voteSub != nil { @@ -561,8 +499,6 @@ func (es *EventSystem) eventLoop() { es.handleLogs(index, ev) case ev := <-es.rmLogsCh: es.handleLogs(index, ev.Logs) - case ev := <-es.pendingLogsCh: - es.handlePendingLogs(index, ev) case ev := <-es.chainCh: es.handleChainEvent(index, ev) case ev := <-es.finalizedHeaderCh: @@ -571,23 +507,11 @@ func (es *EventSystem) eventLoop() { es.handleVoteEvent(index, ev) case f := <-es.install: - if f.typ == MinedAndPendingLogsSubscription { - // the type are logs and pending logs subscriptions - index[LogsSubscription][f.id] = f - index[PendingLogsSubscription][f.id] = f - } else { - index[f.typ][f.id] = f - } + index[f.typ][f.id] = f close(f.installed) case f := <-es.uninstall: - if f.typ == MinedAndPendingLogsSubscription { - // the type are logs and pending logs subscriptions - delete(index[LogsSubscription], f.id) - delete(index[PendingLogsSubscription], f.id) - } else { - delete(index[f.typ], f.id) - } + delete(index[f.typ], f.id) close(f.err) // System stopped diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 7e35403425..f0b1631876 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -19,7 +19,6 @@ package filters import ( "context" "errors" - "fmt" "math/big" "math/rand" "reflect" @@ -27,7 +26,6 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -121,10 +119,6 @@ func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash, number uint return logs, nil } -func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { - return b.pendingBlock, b.pendingReceipts -} - func (b *testBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { return b.txFeed.Subscribe(ch) } @@ -137,10 +131,6 @@ func (b *testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript return b.logsFeed.Subscribe(ch) } -func (b *testBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { - return b.pendingLogsFeed.Subscribe(ch) -} - func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return b.chainFeed.Subscribe(ch) } @@ -184,6 +174,11 @@ func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.Matc }() } +func (b *testBackend) setPending(block *types.Block, receipts types.Receipts) { + b.pendingBlock = block + b.pendingReceipts = receipts +} + func newTestFilterSystem(t testing.TB, db ethdb.Database, cfg Config) (*testBackend, *FilterSystem) { backend := &testBackend{db: db} sys := NewFilterSystem(backend, cfg) @@ -201,13 +196,13 @@ func TestBlockSubscription(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) genesis = &core.Genesis{ Config: params.TestChainConfig, BaseFee: big.NewInt(params.InitialBaseFee), } _, chain, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 10, func(i int, gen *core.BlockGen) {}) - chainEvents = []core.ChainEvent{} + chainEvents []core.ChainEvent ) for _, blk := range chain { @@ -256,7 +251,7 @@ func TestPendingTxFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) transactions = []*types.Transaction{ types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), @@ -312,7 +307,7 @@ func TestPendingTxFilterFullTx(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) transactions = []*types.Transaction{ types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), @@ -368,7 +363,7 @@ func TestLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() _, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) testCases = []struct { crit FilterCriteria @@ -380,8 +375,6 @@ func TestLogFilterCreation(t *testing.T) { {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, true}, // "mined" block range to pending {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, true}, - // new mined and pending blocks - {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, true}, // from block "higher" than to block {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}, false}, // from block "higher" than to block @@ -390,7 +383,7 @@ func TestLogFilterCreation(t *testing.T) { {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false}, // from block "higher" than to block {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false}, - // topics more then 4 + // topics more than 4 {FilterCriteria{Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, false}, } ) @@ -417,7 +410,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() _, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) ) // different situations where log filter creation should fail. @@ -443,7 +436,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() _, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") ) @@ -469,7 +462,7 @@ func TestInvalidGetRangeLogsRequest(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() _, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) ) if _, err := api.GetLogs(context.Background(), FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}); err != errInvalidBlockRange { @@ -484,7 +477,7 @@ func TestLogFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") @@ -503,9 +496,6 @@ func TestLogFilter(t *testing.T) { {Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}, } - expectedCase7 = []*types.Log{allLogs[3], allLogs[4], allLogs[0], allLogs[1], allLogs[2], allLogs[3], allLogs[4]} - expectedCase11 = []*types.Log{allLogs[1], allLogs[2], allLogs[1], allLogs[2]} - testCases = []struct { crit FilterCriteria expected []*types.Log @@ -523,20 +513,14 @@ func TestLogFilter(t *testing.T) { 4: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[3:5], ""}, // match logs based on multiple addresses and "or" topics 5: {FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[2:5], ""}, - // logs in the pending block - 6: {FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, allLogs[:2], ""}, - // mined logs with block num >= 2 or pending logs - 7: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, expectedCase7, ""}, // all "mined" logs with block num >= 2 - 8: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs[3:], ""}, + 6: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs[3:], ""}, // all "mined" logs - 9: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""}, + 7: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""}, // all "mined" logs with 1>= block num <=2 and topic secondTopic - 10: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""}, - // all "mined" and pending logs with topic firstTopic - 11: {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), Topics: [][]common.Hash{{firstTopic}}}, expectedCase11, ""}, + 8: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""}, // match all logs due to wildcard topic - 12: {FilterCriteria{Topics: [][]common.Hash{nil}}, allLogs[1:], ""}, + 9: {FilterCriteria{Topics: [][]common.Hash{nil}}, allLogs[1:], ""}, } ) @@ -550,9 +534,6 @@ func TestLogFilter(t *testing.T) { if nsend := backend.logsFeed.Send(allLogs); nsend == 0 { t.Fatal("Logs event not delivered") } - if nsend := backend.pendingLogsFeed.Send(allLogs); nsend == 0 { - t.Fatal("Pending logs event not delivered") - } for i, tt := range testCases { var fetched []*types.Log @@ -560,7 +541,7 @@ func TestLogFilter(t *testing.T) { for { // fetch all expected logs results, err := api.GetFilterChanges(tt.id) if err != nil { - t.Fatalf("Unable to fetch logs: %v", err) + t.Fatalf("test %d: unable to fetch logs: %v", i, err) } fetched = append(fetched, results.([]*types.Log)...) @@ -591,187 +572,6 @@ func TestLogFilter(t *testing.T) { } } -// TestPendingLogsSubscription tests if a subscription receives the correct pending logs that are posted to the event feed. -func TestPendingLogsSubscription(t *testing.T) { - t.Parallel() - - var ( - db = rawdb.NewMemoryDatabase() - backend, sys = newTestFilterSystem(t, db, Config{}) - api = NewFilterAPI(sys, false) - - firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") - secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") - thirdAddress = common.HexToAddress("0x3333333333333333333333333333333333333333") - notUsedAddress = common.HexToAddress("0x9999999999999999999999999999999999999999") - firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") - secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222") - thirdTopic = common.HexToHash("0x3333333333333333333333333333333333333333333333333333333333333333") - fourthTopic = common.HexToHash("0x4444444444444444444444444444444444444444444444444444444444444444") - notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999") - - allLogs = [][]*types.Log{ - {{Address: firstAddr, Topics: []common.Hash{}, BlockNumber: 0}}, - {{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}}, - {{Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 2}}, - {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}}, - {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 4}}, - { - {Address: thirdAddress, Topics: []common.Hash{firstTopic}, BlockNumber: 5}, - {Address: thirdAddress, Topics: []common.Hash{thirdTopic}, BlockNumber: 5}, - {Address: thirdAddress, Topics: []common.Hash{fourthTopic}, BlockNumber: 5}, - {Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 5}, - }, - } - - pendingBlockNumber = big.NewInt(rpc.PendingBlockNumber.Int64()) - - testCases = []struct { - crit ethereum.FilterQuery - expected []*types.Log - c chan []*types.Log - sub *Subscription - err chan error - }{ - // match all - { - ethereum.FilterQuery{FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - flattenLogs(allLogs), - nil, nil, nil, - }, - // match none due to no matching addresses - { - ethereum.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - nil, - nil, nil, nil, - }, - // match logs based on addresses, ignore topics - { - ethereum.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - append(flattenLogs(allLogs[:2]), allLogs[5][3]), - nil, nil, nil, - }, - // match none due to no matching topics (match with address) - { - ethereum.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - nil, - nil, nil, nil, - }, - // match logs based on addresses and topics - { - ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - append(flattenLogs(allLogs[3:5]), allLogs[5][0]), - nil, nil, nil, - }, - // match logs based on multiple addresses and "or" topics - { - ethereum.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - append(flattenLogs(allLogs[2:5]), allLogs[5][0]), - nil, nil, nil, - }, - // multiple pending logs, should match only 2 topics from the logs in block 5 - { - ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, - []*types.Log{allLogs[5][0], allLogs[5][2]}, - nil, nil, nil, - }, - // match none due to only matching new mined logs - { - ethereum.FilterQuery{}, - nil, - nil, nil, nil, - }, - // match none due to only matching mined logs within a specific block range - { - ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, - nil, - nil, nil, nil, - }, - // match all due to matching mined and pending logs - { - ethereum.FilterQuery{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, - flattenLogs(allLogs), - nil, nil, nil, - }, - // match none due to matching logs from a specific block number to new mined blocks - { - ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, - nil, - nil, nil, nil, - }, - } - ) - - // create all subscriptions, this ensures all subscriptions are created before the events are posted. - // on slow machines this could otherwise lead to missing events when the subscription is created after - // (some) events are posted. - for i := range testCases { - testCases[i].c = make(chan []*types.Log) - testCases[i].err = make(chan error, 1) - - var err error - testCases[i].sub, err = api.events.SubscribeLogs(testCases[i].crit, testCases[i].c) - if err != nil { - t.Fatalf("SubscribeLogs %d failed: %v\n", i, err) - } - } - - for n, test := range testCases { - i := n - tt := test - go func() { - defer tt.sub.Unsubscribe() - - var fetched []*types.Log - - timeout := time.After(1 * time.Second) - fetchLoop: - for { - select { - case logs := <-tt.c: - // Do not break early if we've fetched greater, or equal, - // to the number of logs expected. This ensures we do not - // deadlock the filter system because it will do a blocking - // send on this channel if another log arrives. - fetched = append(fetched, logs...) - case <-timeout: - break fetchLoop - } - } - - if len(fetched) != len(tt.expected) { - tt.err <- fmt.Errorf("invalid number of logs for case %d, want %d log(s), got %d", i, len(tt.expected), len(fetched)) - return - } - - for l := range fetched { - if fetched[l].Removed { - tt.err <- fmt.Errorf("expected log not to be removed for log %d in case %d", l, i) - return - } - if !reflect.DeepEqual(fetched[l], tt.expected[l]) { - tt.err <- fmt.Errorf("invalid log on index %d for case %d\n", l, i) - return - } - } - tt.err <- nil - }() - } - - // raise events - for _, ev := range allLogs { - backend.pendingLogsFeed.Send(ev) - } - - for i := range testCases { - err := <-testCases[i].err - if err != nil { - t.Fatalf("test %d failed: %v", i, err) - } - <-testCases[i].sub.Err() - } -} - // TestPendingTxFilterDeadlock tests if the event loop hangs when pending // txes arrive at the same time that one of multiple filters is timing out. // Please refer to #22131 for more details. @@ -782,7 +582,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend, sys = newTestFilterSystem(t, db, Config{Timeout: timeout}) - api = NewFilterAPI(sys, false) + api = NewFilterAPI(sys) done = make(chan struct{}) ) @@ -807,7 +607,9 @@ func TestPendingTxFilterDeadlock(t *testing.T) { subs := make([]*Subscription, 20) for i := 0; i < len(subs); i++ { fid := api.NewPendingTransactionFilter(nil) + api.filtersMu.Lock() f, ok := api.filters[fid] + api.filtersMu.Unlock() if !ok { t.Fatalf("Filter %s should exist", fid) } @@ -835,14 +637,6 @@ func TestPendingTxFilterDeadlock(t *testing.T) { } } -func flattenLogs(pl [][]*types.Log) []*types.Log { - var logs []*types.Log - for _, l := range pl { - logs = append(logs, l...) - } - return logs -} - func TestVoteSubscription(t *testing.T) { t.Parallel() diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 59b6165863..c0fb92d038 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -347,16 +347,16 @@ func TestFilters(t *testing.T) { }, */ { - f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false), - want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`, + f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false), + err: errPendingLogsUnsupported.Error(), }, { - f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false), - want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`, + f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false), + err: errPendingLogsUnsupported.Error(), }, { f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false), - err: errInvalidBlockRange.Error(), + err: errPendingLogsUnsupported.Error(), }, } { logs, err := tc.f.Logs(context.Background()) @@ -378,7 +378,7 @@ func TestFilters(t *testing.T) { } t.Run("timeout", func(t *testing.T) { - f := sys.NewRangeFilter(0, -1, nil, nil, false) + f := sys.NewRangeFilter(0, rpc.LatestBlockNumber.Int64(), nil, nil, false) ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Hour)) defer cancel() _, err := f.Logs(ctx) diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index f07f98956e..d43057dda2 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -80,6 +80,16 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin } available.Sub(available, call.Value) } + if opts.Config.IsCancun(opts.Header.Number, opts.Header.Time) && len(call.BlobHashes) > 0 { + blobGasPerBlob := new(big.Int).SetInt64(params.BlobTxBlobGasPerBlob) + blobBalanceUsage := new(big.Int).SetInt64(int64(len(call.BlobHashes))) + blobBalanceUsage.Mul(blobBalanceUsage, blobGasPerBlob) + blobBalanceUsage.Mul(blobBalanceUsage, call.BlobGasFeeCap) + if blobBalanceUsage.Cmp(available) >= 0 { + return 0, nil, core.ErrInsufficientFunds + } + available.Sub(available, blobBalanceUsage) + } allowance := new(big.Int).Div(available, feeCap) // If the allowance is larger than maximum uint64, skip checking @@ -211,8 +221,16 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil) dirtyState = opts.State.Copy() - evm = vm.NewEVM(evmContext, msgContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true}) ) + // Lower the basefee to 0 to avoid breaking EVM + // invariants (basefee < feecap). + if msgContext.GasPrice.Sign() == 0 { + evmContext.BaseFee = new(big.Int) + } + if msgContext.BlobFeeCap != nil && msgContext.BlobFeeCap.BitLen() == 0 { + evmContext.BlobBaseFee = new(big.Int) + } + evm := vm.NewEVM(evmContext, msgContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true}) // Monitor the outer context and interrupt the EVM upon cancellation. To avoid // a dangling goroutine until the outer estimation finishes, create an internal // context for the lifetime of this method call. diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 086e763e1a..1e625e21c0 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -23,14 +23,16 @@ import ( "fmt" "math" "math/big" + "slices" "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "golang.org/x/exp/slices" ) var ( @@ -42,7 +44,8 @@ const ( // maxBlockFetchers is the max number of goroutines to spin up to pull blocks // for the fee history calculation (mostly relevant for LES). maxBlockFetchers = 4 - maxQueryLimit = 100 + // maxQueryLimit is the max number of requested percentiles. + maxQueryLimit = 100 ) // blockFees represents a single block for processing @@ -64,9 +67,11 @@ type cacheKey struct { // processedFees contains the results of a processed block. type processedFees struct { - reward []*big.Int - baseFee, nextBaseFee *big.Int - gasUsedRatio float64 + reward []*big.Int + baseFee, nextBaseFee *big.Int + gasUsedRatio float64 + blobGasUsedRatio float64 + blobBaseFee, nextBlobBaseFee *big.Int } // txGasAndReward is sorted in ascending order based on reward @@ -79,16 +84,31 @@ type txGasAndReward struct { // the block field filled in, retrieves the block from the backend if not present yet and // fills in the rest of the fields. func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { - chainconfig := oracle.backend.ChainConfig() + config := oracle.backend.ChainConfig() + + // Fill in base fee and next base fee. if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil { bf.results.baseFee = new(big.Int) } - if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) { - bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header) + if config.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) { + bf.results.nextBaseFee = eip1559.CalcBaseFee(config, bf.header) } else { bf.results.nextBaseFee = new(big.Int) } + // Fill in blob base fee and next blob base fee. + if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil { + bf.results.blobBaseFee = eip4844.CalcBlobFee(*excessBlobGas) + bf.results.nextBlobBaseFee = eip4844.CalcBlobFee(eip4844.CalcExcessBlobGas(*excessBlobGas, *bf.header.BlobGasUsed)) + } else { + bf.results.blobBaseFee = new(big.Int) + bf.results.nextBlobBaseFee = new(big.Int) + } + // Compute gas used ratio for normal and blob gas. bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit) + if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil { + bf.results.blobGasUsedRatio = float64(*blobGasUsed) / params.MaxBlobGasPerBlock + } + if len(percentiles) == 0 { // rewards were not requested, return null return @@ -161,7 +181,7 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNum ) switch reqEnd { case rpc.PendingBlockNumber: - if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil { + if pendingBlock, pendingReceipts, _ = oracle.backend.Pending(); pendingBlock != nil { resolved = pendingBlock.Header() } else { // Pending block not supported by backend, process only until latest block. @@ -204,24 +224,26 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNum // or blocks older than a certain age (specified in maxHistory). The first block of the // actually processed range is returned to avoid ambiguity when parts of the requested range // are not available or when the head has changed during processing this request. -// Three arrays are returned based on the processed blocks: +// Five arrays are returned based on the processed blocks: // - reward: the requested percentiles of effective priority fees per gas of transactions in each // block, sorted in ascending order and weighted by gas used. // - baseFee: base fee per gas in the given block // - gasUsedRatio: gasUsed/gasLimit in the given block +// - blobBaseFee: the blob base fee per gas in the given block +// - blobGasUsedRatio: blobGasUsed/blobGasLimit in the given block // -// Note: baseFee includes the next block after the newest of the returned range, because this -// value can be derived from the newest block. -func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { +// Note: baseFee and blobBaseFee both include the next block after the newest of the returned range, +// because this value can be derived from the newest block. +func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) { if blocks < 1 { - return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks + return common.Big0, nil, nil, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks } maxFeeHistory := oracle.maxHeaderHistory if len(rewardPercentiles) != 0 { maxFeeHistory = oracle.maxBlockHistory } if len(rewardPercentiles) > maxQueryLimit { - return common.Big0, nil, nil, nil, fmt.Errorf("%w: over the query limit %d", errInvalidPercentile, maxQueryLimit) + return common.Big0, nil, nil, nil, nil, nil, fmt.Errorf("%w: over the query limit %d", errInvalidPercentile, maxQueryLimit) } if blocks > maxFeeHistory { log.Warn("Sanitizing fee history length", "requested", blocks, "truncated", maxFeeHistory) @@ -229,10 +251,10 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL } for i, p := range rewardPercentiles { if p < 0 || p > 100 { - return common.Big0, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p) + return common.Big0, nil, nil, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p) } if i > 0 && p <= rewardPercentiles[i-1] { - return common.Big0, nil, nil, nil, fmt.Errorf("%w: #%d:%f >= #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p) + return common.Big0, nil, nil, nil, nil, nil, fmt.Errorf("%w: #%d:%f >= #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p) } } var ( @@ -242,7 +264,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL ) pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks) if err != nil || blocks == 0 { - return common.Big0, nil, nil, nil, err + return common.Big0, nil, nil, nil, nil, nil, err } oldestBlock := lastBlock + 1 - blocks @@ -299,19 +321,22 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL }() } var ( - reward = make([][]*big.Int, blocks) - baseFee = make([]*big.Int, blocks+1) - gasUsedRatio = make([]float64, blocks) - firstMissing = blocks + reward = make([][]*big.Int, blocks) + baseFee = make([]*big.Int, blocks+1) + gasUsedRatio = make([]float64, blocks) + blobGasUsedRatio = make([]float64, blocks) + blobBaseFee = make([]*big.Int, blocks+1) + firstMissing = blocks ) for ; blocks > 0; blocks-- { fees := <-results if fees.err != nil { - return common.Big0, nil, nil, nil, fees.err + return common.Big0, nil, nil, nil, nil, nil, fees.err } i := fees.blockNumber - oldestBlock if fees.results.baseFee != nil { reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio + blobGasUsedRatio[i], blobBaseFee[i], blobBaseFee[i+1] = fees.results.blobGasUsedRatio, fees.results.blobBaseFee, fees.results.nextBlobBaseFee } else { // getting no block and no error means we are requesting into the future (might happen because of a reorg) if i < firstMissing { @@ -320,7 +345,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL } } if firstMissing == 0 { - return common.Big0, nil, nil, nil, nil + return common.Big0, nil, nil, nil, nil, nil, nil } if len(rewardPercentiles) != 0 { reward = reward[:firstMissing] @@ -328,5 +353,6 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL reward = nil } baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing] - return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, nil + blobBaseFee, blobGasUsedRatio = blobBaseFee[:firstMissing+1], blobGasUsedRatio[:firstMissing] + return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, blobBaseFee, blobGasUsedRatio, nil } diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index 3b4257496c..4ee892a97c 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -58,10 +58,10 @@ func TestFeeHistory(t *testing.T) { MaxHeaderHistory: c.maxHeader, MaxBlockHistory: c.maxBlock, } - backend := newTestBackend(t, big.NewInt(16), c.pending) - oracle := NewOracle(backend, config) + backend := newTestBackend(t, big.NewInt(16), big.NewInt(28), c.pending) + oracle := NewOracle(backend, config, nil) - first, reward, baseFee, ratio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent) + first, reward, baseFee, ratio, blobBaseFee, blobRatio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent) backend.teardown() expReward := c.expCount if len(c.percent) == 0 { @@ -84,6 +84,12 @@ func TestFeeHistory(t *testing.T) { if len(ratio) != c.expCount { t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio)) } + if len(blobRatio) != c.expCount { + t.Fatalf("Test case %d: blobGasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(blobRatio)) + } + if len(blobBaseFee) != len(baseFee) { + t.Fatalf("Test case %d: blobBaseFee array length mismatch, want %d, got %d", i, len(baseFee), len(blobBaseFee)) + } if err != c.expErr && !errors.Is(err, c.expErr) { t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err) } diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index fefd8211c8..4a2fe36812 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -19,17 +19,18 @@ package gasprice import ( "context" "math/big" + "slices" "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "golang.org/x/exp/slices" ) const sampleNumber = 3 // Number of transactions sampled in a block @@ -44,7 +45,6 @@ type Config struct { Percentile int MaxHeaderHistory uint64 MaxBlockHistory uint64 - Default *big.Int `toml:",omitempty"` MaxPrice *big.Int `toml:",omitempty"` IgnorePrice *big.Int `toml:",omitempty"` OracleThreshold int `toml:",omitempty"` @@ -55,7 +55,7 @@ type OracleBackend interface { HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) - PendingBlockAndReceipts() (*types.Block, types.Receipts) + Pending() (*types.Block, types.Receipts, *state.StateDB) ChainConfig() *params.ChainConfig SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription } @@ -81,7 +81,7 @@ type Oracle struct { // NewOracle returns a new gasprice oracle which can recommend suitable // gasprice for newly created transaction. -func NewOracle(backend OracleBackend, params Config) *Oracle { +func NewOracle(backend OracleBackend, params Config, startPrice *big.Int) *Oracle { blocks := params.Blocks if blocks < 1 { blocks = 1 @@ -117,6 +117,9 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { maxBlockHistory = 1 log.Warn("Sanitizing invalid gasprice oracle max block history", "provided", params.MaxBlockHistory, "updated", maxBlockHistory) } + if startPrice == nil { + startPrice = new(big.Int) + } cache := lru.NewCache[cacheKey, processedFees](2048) headEvent := make(chan core.ChainHeadEvent, 1) @@ -133,7 +136,7 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { return &Oracle{ backend: backend, - lastPrice: params.Default, + lastPrice: startPrice, maxPrice: maxPrice, ignorePrice: ignorePrice, checkBlocks: blocks, @@ -142,7 +145,7 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { maxBlockHistory: maxBlockHistory, historyCache: cache, sampleTxThreshold: params.OracleThreshold, - defaultPrice: params.Default, + defaultPrice: startPrice, } } diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index c6ce443a06..94d8313bf4 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -18,21 +18,27 @@ package gasprice import ( "context" + "crypto/sha256" "errors" + "fmt" "math" "math/big" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/holiman/uint256" ) const testHead = 32 @@ -106,12 +112,16 @@ func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types. return b.chain.GetReceiptsByHash(hash), nil } -func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { +func (b *testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { if b.pending { block := b.chain.GetBlockByNumber(testHead + 1) - return block, b.chain.GetReceiptsByHash(block.Hash()) + stateDb, err := b.chain.StateAt(block.Root()) + if err != nil { + return nil, nil, nil + } + return block, b.chain.GetReceiptsByHash(block.Hash()), stateDb } - return nil, nil + return nil, nil, nil } func (b *testBackend) ChainConfig() *params.ChainConfig { @@ -128,7 +138,10 @@ func (b *testBackend) teardown() { // newTestBackend creates a test backend. OBS: don't forget to invoke tearDown // after use, otherwise the blockchain instance will mem-leak via goroutines. -func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend { +func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pending bool) *testBackend { + if londonBlock != nil && cancunBlock != nil && londonBlock.Cmp(cancunBlock) == 1 { + panic("cannot define test backend with cancun before london") + } var ( key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key.PublicKey) @@ -138,6 +151,11 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, } signer = types.LatestSigner(gspec.Config) + + // Compute empty blob hash. + emptyBlob = kzg4844.Blob{} + emptyBlobCommit, _ = kzg4844.BlobToCommitment(&emptyBlob) + emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) ) config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock @@ -147,11 +165,18 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke config.PlatoBlock = nil config.HertzBlock = nil config.HertzfixBlock = nil - config.TerminalTotalDifficulty = common.Big0 - engine := ethash.NewFaker() + var engine consensus.Engine = beacon.New(ethash.NewFaker()) + td := params.GenesisDifficulty.Uint64() + + if cancunBlock != nil { + ts := gspec.Timestamp + cancunBlock.Uint64()*10 // fixed 10 sec block time in blockgen + config.ShanghaiTime = &ts + config.CancunTime = &ts + signer = types.LatestSigner(gspec.Config) + } // Generate testing blocks - _, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, testHead+1, func(i int, b *core.BlockGen) { + db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, testHead+1, func(i int, b *core.BlockGen) { b.SetCoinbase(common.Address{1}) var txdata types.TxData @@ -176,16 +201,42 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke } } b.AddTx(types.MustSignNewTx(key, signer, txdata)) + + if cancunBlock != nil && b.Number().Cmp(cancunBlock) >= 0 { + b.SetPoS() + + // put more blobs in each new block + for j := 0; j < i && j < 6; j++ { + blobTx := &types.BlobTx{ + ChainID: uint256.MustFromBig(gspec.Config.ChainID), + Nonce: b.TxNonce(addr), + To: common.Address{}, + Gas: 30000, + GasFeeCap: uint256.NewInt(100 * params.GWei), + GasTipCap: uint256.NewInt(uint64(i+1) * params.GWei), + Data: []byte{}, + BlobFeeCap: uint256.NewInt(1), + BlobHashes: []common.Hash{emptyBlobVHash}, + Value: uint256.NewInt(100), + Sidecar: nil, + } + b.AddTx(types.MustSignNewTx(key, signer, blobTx)) + } + } + td += b.Difficulty().Uint64() }) // Construct testing chain - chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil, nil) + gspec.Config.TerminalTotalDifficulty = new(big.Int).SetUint64(td) + chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create local chain, %v", err) } - _, err = chain.InsertChain(blocks) - if err != nil { - t.Fatalf("Failed to insert blocks, %v", err) + if i, err := chain.InsertChain(blocks); err != nil { + panic(fmt.Errorf("error inserting block %d: %w", i, err)) } + chain.SetFinalized(chain.GetBlockByNumber(25).Header()) + chain.SetSafe(chain.GetBlockByNumber(25).Header()) + return &testBackend{chain: chain, pending: pending} } @@ -201,7 +252,6 @@ func TestSuggestTipCap(t *testing.T) { config := Config{ Blocks: 3, Percentile: 60, - Default: big.NewInt(params.GWei), } var cases = []struct { fork *big.Int // London fork number @@ -214,8 +264,8 @@ func TestSuggestTipCap(t *testing.T) { {big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future } for _, c := range cases { - backend := newTestBackend(t, c.fork, false) - oracle := NewOracle(backend, config) + backend := newTestBackend(t, c.fork, nil, false) + oracle := NewOracle(backend, config, big.NewInt(params.GWei)) // The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G got, err := oracle.SuggestTipCap(context.Background()) diff --git a/eth/handler.go b/eth/handler.go index f26162024b..e107756b1d 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -26,7 +26,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" @@ -34,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/eth/protocols/bsc" @@ -45,6 +45,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" ) const ( @@ -111,11 +112,11 @@ type votePool interface { // handlerConfig is the collection of initialization parameters to create a full // node network handler. type handlerConfig struct { + NodeID enode.ID // P2P node ID used for tx propagation topology Database ethdb.Database // Database for direct sync insertions Chain *core.BlockChain // Blockchain to serve data from TxPool txPool // Transaction pool to propagate from VotePool votePool - Merger *consensus.Merger // The manager for eth1/2 transition Network uint64 // Network identifier to adfvertise Sync downloader.SyncMode // Whether to snap or full sync BloomCache uint64 // Megabytes to alloc for snap sync bloom @@ -127,6 +128,7 @@ type handlerConfig struct { } type handler struct { + nodeID enode.ID networkID uint64 forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node disablePeerTxBroadcast bool @@ -149,7 +151,6 @@ type handler struct { blockFetcher *fetcher.BlockFetcher txFetcher *fetcher.TxFetcher peers *peerSet - merger *consensus.Merger eventMux *event.TypeMux txsCh chan core.NewTxsEvent @@ -184,6 +185,7 @@ func newHandler(config *handlerConfig) (*handler, error) { config.PeerSet = newPeerSet() // Nicety initialization for tests } h := &handler{ + nodeID: config.NodeID, networkID: config.Network, forkFilter: forkid.NewFilter(config.Chain), disablePeerTxBroadcast: config.DisablePeerTxBroadcast, @@ -193,7 +195,6 @@ func newHandler(config *handlerConfig) (*handler, error) { votepool: config.VotePool, chain: config.Chain, peers: config.PeerSet, - merger: config.Merger, peersPerIP: make(map[string]int), requiredBlocks: config.RequiredBlocks, directBroadcast: config.DirectBroadcast, @@ -242,12 +243,6 @@ func newHandler(config *handlerConfig) (*handler, error) { // Construct the fetcher (short sync) validator := func(header *types.Header) error { - // All the block fetcher activities should be disabled - // after the transition. Print the warning log. - if h.merger.PoSFinalized() { - log.Warn("Unexpected validation activity", "hash", header.Hash(), "number", header.Number) - return errors.New("unexpected behavior after transition") - } // Reject all the PoS style headers in the first place. No matter // the chain has finished the transition or not, the PoS headers // should only come from the trusted consensus layer instead of @@ -270,20 +265,6 @@ func newHandler(config *handlerConfig) (*handler, error) { return fblock.Number.Uint64() } inserter := func(blocks types.Blocks) (int, error) { - // All the block fetcher activities should be disabled - // after the transition. Print the warning log. - if h.merger.PoSFinalized() { - var ctx []interface{} - ctx = append(ctx, "blocks", len(blocks)) - if len(blocks) > 0 { - ctx = append(ctx, "firsthash", blocks[0].Hash()) - ctx = append(ctx, "firstnumber", blocks[0].Number()) - ctx = append(ctx, "lasthash", blocks[len(blocks)-1].Hash()) - ctx = append(ctx, "lastnumber", blocks[len(blocks)-1].Number()) - } - log.Warn("Unexpected insertion activity", ctx...) - return 0, errors.New("unexpected behavior after transition") - } // If snap sync is running, deny importing weird blocks. This is a problematic // clause when starting up a new network, because snap-syncing miners might not // accept each others' blocks until a restart. Unfortunately we haven't figured @@ -293,29 +274,6 @@ func newHandler(config *handlerConfig) (*handler, error) { log.Warn("Syncing, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash()) return 0, nil } - if h.merger.TDDReached() { - // The blocks from the p2p network is regarded as untrusted - // after the transition. In theory block gossip should be disabled - // entirely whenever the transition is started. But in order to - // handle the transition boundary reorg in the consensus-layer, - // the legacy blocks are still accepted, but only for the terminal - // pow blocks. Spec: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3675.md#halt-the-importing-of-pow-blocks - for i, block := range blocks { - ptd := h.chain.GetTd(block.ParentHash(), block.NumberU64()-1) - if ptd == nil { - return 0, nil - } - td := new(big.Int).Add(ptd, block.Difficulty()) - if !h.chain.Config().IsTerminalPoWBlock(ptd, td) { - log.Info("Filtered out non-terminal pow block", "number", block.NumberU64(), "hash", block.Hash()) - return 0, nil - } - if err := h.chain.InsertBlockWithoutSetHead(block); err != nil { - return i, err - } - } - return 0, nil - } return h.chain.InsertChain(blocks) } @@ -779,11 +737,6 @@ func (h *handler) Stop() { // BroadcastBlock will either propagate a block to a subset of its peers, or // will only announce its availability (depending what's requested). func (h *handler) BroadcastBlock(block *types.Block, propagate bool) { - // Disable the block propagation if the chain has already entered the PoS - // stage. The block propagation is delegated to the consensus layer. - if h.merger.PoSFinalized() { - return - } // Disable the block propagation if it's the post-merge block. if beacon, ok := h.chain.Engine().(*beacon.Beacon); ok { if beacon.IsPoSHeader(block.Header()) { @@ -837,47 +790,72 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) { largeTxs int // Number of large transactions to announce only directCount int // Number of transactions sent directly to peers (duplicates included) - directPeers int // Number of peers that were sent transactions directly annCount int // Number of transactions announced across all peers (duplicates included) - annPeers int // Number of peers announced about transactions txset = make(map[*ethPeer][]common.Hash) // Set peer->hash to transfer directly annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce ) // Broadcast transactions to a batch of peers not knowing about it - for _, tx := range txs { - peers := h.peers.peersWithoutTransaction(tx.Hash()) + direct := big.NewInt(int64(math.Sqrt(float64(h.peers.len())))) // Approximate number of peers to broadcast to + if direct.BitLen() == 0 { + direct = big.NewInt(1) + } + total := new(big.Int).Exp(direct, big.NewInt(2), nil) // Stabilise total peer count a bit based on sqrt peers - var numDirect int + var ( + signer = types.LatestSignerForChainID(h.chain.Config().ChainID) // Don't care about chain status, we just need *a* sender + hasher = crypto.NewKeccakState() + hash = make([]byte, 32) + ) + for _, tx := range txs { + var maybeDirect bool switch { case tx.Type() == types.BlobTxType: blobTxs++ case tx.Size() > txMaxBroadcastSize: largeTxs++ default: - numDirect = int(math.Sqrt(float64(len(peers)))) - } - // Send the tx unconditionally to a subset of our peers - for _, peer := range peers[:numDirect] { - txset[peer] = append(txset[peer], tx.Hash()) - } - // For the remaining peers, send announcement only - for _, peer := range peers[numDirect:] { - annos[peer] = append(annos[peer], tx.Hash()) + maybeDirect = true + } + // Send the transaction (if it's small enough) directly to a subset of + // the peers that have not received it yet, ensuring that the flow of + // transactions is grouped by account to (try and) avoid nonce gaps. + // + // To do this, we hash the local enode IW with together with a peer's + // enode ID together with the transaction sender and broadcast if + // `sha(self, peer, sender) mod peers < sqrt(peers)`. + for _, peer := range h.peers.peersWithoutTransaction(tx.Hash()) { + var broadcast bool + if maybeDirect { + hasher.Reset() + hasher.Write(h.nodeID.Bytes()) + hasher.Write(peer.Node().ID().Bytes()) + + from, _ := types.Sender(signer, tx) // Ignore error, we only use the addr as a propagation target splitter + hasher.Write(from.Bytes()) + + hasher.Read(hash) + if new(big.Int).Mod(new(big.Int).SetBytes(hash), total).Cmp(direct) < 0 { + broadcast = true + } + } + if broadcast { + txset[peer] = append(txset[peer], tx.Hash()) + } else { + annos[peer] = append(annos[peer], tx.Hash()) + } } } for peer, hashes := range txset { - directPeers++ directCount += len(hashes) peer.AsyncSendTransactions(hashes) } for peer, hashes := range annos { - annPeers++ annCount += len(hashes) peer.AsyncSendPooledTransactionHashes(hashes) } log.Debug("Distributed transactions", "plaintxs", len(txs)-blobTxs-largeTxs, "blobtxs", blobTxs, "largetxs", largeTxs, - "bcastpeers", directPeers, "bcastcount", directCount, "annpeers", annPeers, "anncount", annCount) + "bcastpeers", len(txset), "bcastcount", directCount, "annpeers", len(annos), "anncount", annCount) } // ReannounceTransactions will announce a batch of local pending transactions diff --git a/eth/handler_eth.go b/eth/handler_eth.go index dd119fdf6e..8722d97c03 100644 --- a/eth/handler_eth.go +++ b/eth/handler_eth.go @@ -89,12 +89,6 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error { // handleBlockAnnounces is invoked from a peer's message handler when it transmits a // batch of block announcements for the local node to process. func (h *ethHandler) handleBlockAnnounces(peer *eth.Peer, hashes []common.Hash, numbers []uint64) error { - // Drop all incoming block announces from the p2p network if - // the chain already entered the pos stage and disconnect the - // remote peer. - if h.merger.PoSFinalized() { - return errors.New("disallowed block announcement") - } // Schedule all the unknown hashes for retrieval var ( unknownHashes = make([]common.Hash, 0, len(hashes)) @@ -116,12 +110,6 @@ func (h *ethHandler) handleBlockAnnounces(peer *eth.Peer, hashes []common.Hash, // handleBlockBroadcast is invoked from a peer's message handler when it transmits a // block broadcast for the local node to process. func (h *ethHandler) handleBlockBroadcast(peer *eth.Peer, packet *eth.NewBlockPacket) error { - // Drop all incoming block announces from the p2p network if - // the chain already entered the pos stage and disconnect the - // remote peer. - if h.merger.PoSFinalized() { - return errors.New("disallowed block broadcast") - } block := packet.Block td := packet.TD sidecars := packet.Sidecars diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index c35bf0f4ce..40c88e2c37 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -25,7 +25,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" @@ -128,7 +127,6 @@ func testForkIDSplit(t *testing.T, protocol uint) { Chain: chainNoFork, TxPool: newTestTxPool(), VotePool: newTestVotePool(), - Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, BloomCache: 1, @@ -138,7 +136,6 @@ func testForkIDSplit(t *testing.T, protocol uint) { Chain: chainProFork, TxPool: newTestTxPool(), VotePool: newTestVotePool(), - Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, BloomCache: 1, @@ -487,7 +484,7 @@ func testTransactionPropagation(t *testing.T, protocol uint) { } // Interconnect all the sink handlers with the source handler for i, sink := range sinks { - sink := sink // Closure for gorotuine below + sink := sink // Closure for goroutine below sourcePipe, sinkPipe := p2p.MsgPipe() defer sourcePipe.Close() diff --git a/eth/handler_test.go b/eth/handler_test.go index 5584afe857..39373cd43a 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -192,7 +192,6 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { Database: db, Chain: chain, TxPool: txpool, - Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), VotePool: votepool, Network: 1, Sync: downloader.SnapSync, @@ -294,7 +293,6 @@ func newTestParliaHandlerAfterCancun(t *testing.T, config *params.ChainConfig, m Database: db, Chain: chain, TxPool: txpool, - Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), VotePool: votepool, Network: 1, Sync: mode, diff --git a/eth/peerset.go b/eth/peerset.go index ff4215eda3..38a3471139 100644 --- a/eth/peerset.go +++ b/eth/peerset.go @@ -196,7 +196,7 @@ func (ps *peerSet) registerBscExtension(peer *bsc.Peer) error { return nil } -// waitExtensions blocks until all satellite protocols are connected and tracked +// waitSnapExtension blocks until all satellite protocols are connected and tracked // by the peerset. func (ps *peerSet) waitSnapExtension(peer *eth.Peer) (*snap.Peer, error) { // If the peer does not support a compatible `snap`, don't wait diff --git a/eth/protocols/bsc/handler.go b/eth/protocols/bsc/handler.go index e993f255f3..9595c42688 100644 --- a/eth/protocols/bsc/handler.go +++ b/eth/protocols/bsc/handler.go @@ -35,13 +35,7 @@ type Backend interface { } // MakeProtocols constructs the P2P protocol definitions for `bsc`. -func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { - // Filter the discovery iterator for nodes advertising vote support. - dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool { - var vote enrEntry - return n.Load(&vote) == nil - }) - +func MakeProtocols(backend Backend) []p2p.Protocol { protocols := make([]p2p.Protocol, len(ProtocolVersions)) for i, version := range ProtocolVersions { version := version // Closure @@ -64,8 +58,7 @@ func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { PeerInfo: func(id enode.ID) interface{} { return backend.PeerInfo(id) }, - Attributes: []enr.Entry{&enrEntry{}}, - DialCandidates: dnsdisc, + Attributes: []enr.Entry{&enrEntry{}}, } } return protocols diff --git a/eth/protocols/eth/discovery.go b/eth/protocols/eth/discovery.go index 91df2cf77e..b24243a084 100644 --- a/eth/protocols/eth/discovery.go +++ b/eth/protocols/eth/discovery.go @@ -70,3 +70,17 @@ func currentENREntry(chain *core.BlockChain) *enrEntry { ForkID: forkid.NewID(chain.Config(), chain.Genesis(), head.Number.Uint64(), head.Time), } } + +// NewNodeFilter returns a filtering function that returns whether the provided +// enode advertises a forkid compatible with the current chain. +func NewNodeFilter(chain *core.BlockChain) func(*enode.Node) bool { + filter := forkid.NewFilter(chain) + return func(n *enode.Node) bool { + var entry enrEntry + if err := n.Load(entry); err != nil { + return false + } + err := filter(entry.ForkID) + return err == nil + } +} diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index 2d69ecdc83..6eb0d04f6b 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -113,8 +113,7 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2 PeerInfo: func(id enode.ID) interface{} { return backend.PeerInfo(id) }, - Attributes: []enr.Entry{currentENREntry(backend.Chain())}, - DialCandidates: dnsdisc, + Attributes: []enr.Entry{currentENREntry(backend.Chain())}, }) } return protocols @@ -123,7 +122,7 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2 // NodeInfo represents a short summary of the `eth` sub-protocol metadata // known about the host peer. type NodeInfo struct { - Network uint64 `json:"network"` // Ethereum network ID (1=Mainnet, Goerli=5) + Network uint64 `json:"network"` // Ethereum network ID (1=Mainnet, Holesky=17000) Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index de49912e57..cda5b8cacf 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -69,7 +69,7 @@ func newTestBackend(blocks int) *testBackend { return newTestBackendWithGenerator(blocks, false, nil) } -// newTestBackend creates a chain with a number of explicitly defined blocks and +// newTestBackendWithGenerator creates a chain with a number of explicitly defined blocks and // wraps it into a mock backend. func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, *core.BlockGen)) *testBackend { var ( diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index 583dd2f67c..b4d996a3bd 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -41,6 +41,9 @@ func handleGetBlockHeaders(backend Backend, msg Decoder, peer *Peer) error { // ServiceGetBlockHeadersQuery assembles the response to a header query. It is // exposed to allow external packages to test protocol behavior. func ServiceGetBlockHeadersQuery(chain *core.BlockChain, query *GetBlockHeadersRequest, peer *Peer) []rlp.RawValue { + if query.Amount == 0 { + return nil + } if query.Skip == 0 { // The fast path: when the request is for a contiguous segment of headers. return serviceContiguousBlockHeaderQuery(chain, query) @@ -189,7 +192,7 @@ func serviceContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBlockHe return headers } { // Last mode: deliver ancestors of H - for i := uint64(1); header != nil && i < count; i++ { + for i := uint64(1); i < count; i++ { header = chain.GetHeaderByHash(header.ParentHash) if header == nil { break @@ -361,6 +364,7 @@ func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error { txsHashes = make([]common.Hash, len(res.BlockBodiesResponse)) uncleHashes = make([]common.Hash, len(res.BlockBodiesResponse)) withdrawalHashes = make([]common.Hash, len(res.BlockBodiesResponse)) + requestsHashes = make([]common.Hash, len(res.BlockBodiesResponse)) ) hasher := trie.NewStackTrie(nil) for i, body := range res.BlockBodiesResponse { @@ -369,8 +373,11 @@ func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error { if body.Withdrawals != nil { withdrawalHashes[i] = types.DeriveSha(types.Withdrawals(body.Withdrawals), hasher) } + if body.Requests != nil { + requestsHashes[i] = types.DeriveSha(types.Requests(body.Requests), hasher) + } } - return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes} + return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes, requestsHashes} } return peer.dispatchResponse(&Response{ id: res.RequestId, diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 7720d9bd44..3d3e6305ae 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -56,14 +56,6 @@ const ( maxQueuedBlockAnns = 4 ) -// max is a helper function which returns the larger of the two given integers. -func max(a, b int) int { - if a > b { - return a - } - return b -} - // Peer is a collection of relevant information we have about a `eth` peer. type Peer struct { id string // Unique ID for the peer, cached diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 46bc97fbb8..ddc64e63de 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -279,22 +279,23 @@ type BlockBody struct { Uncles []*types.Header // Uncles contained within a block Withdrawals []*types.Withdrawal `rlp:"optional"` // Withdrawals contained within a block Sidecars types.BlobSidecars `rlp:"optional"` // Sidecars contained within a block + Requests []*types.Request `rlp:"optional"` // Requests contained within a block } // Unpack retrieves the transactions and uncles from the range packet and returns // them in a split flat format that's more consistent with the internal data structures. -func (p *BlockBodiesResponse) Unpack() ([][]*types.Transaction, [][]*types.Header, [][]*types.Withdrawal, []types.BlobSidecars) { - // TODO(matt): add support for withdrawals to fetchers +func (p *BlockBodiesResponse) Unpack() ([][]*types.Transaction, [][]*types.Header, [][]*types.Withdrawal, []types.BlobSidecars, [][]*types.Request) { var ( txset = make([][]*types.Transaction, len(*p)) uncleset = make([][]*types.Header, len(*p)) withdrawalset = make([][]*types.Withdrawal, len(*p)) sidecarset = make([]types.BlobSidecars, len(*p)) + requestset = make([][]*types.Request, len(*p)) ) for i, body := range *p { - txset[i], uncleset[i], withdrawalset[i], sidecarset[i] = body.Transactions, body.Uncles, body.Withdrawals, body.Sidecars + txset[i], uncleset[i], withdrawalset[i], sidecarset[i], requestset[i] = body.Transactions, body.Uncles, body.Withdrawals, body.Sidecars, body.Requests } - return txset, uncleset, withdrawalset, sidecarset + return txset, uncleset, withdrawalset, sidecarset, requestset } // GetReceiptsRequest represents a block receipts query. diff --git a/eth/protocols/snap/gentrie.go b/eth/protocols/snap/gentrie.go new file mode 100644 index 0000000000..5126d26777 --- /dev/null +++ b/eth/protocols/snap/gentrie.go @@ -0,0 +1,321 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package snap + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" +) + +// genTrie interface is used by the snap syncer to generate merkle tree nodes +// based on a received batch of states. +type genTrie interface { + // update inserts the state item into generator trie. + update(key, value []byte) error + + // delete removes the state item from the generator trie. + delete(key []byte) error + + // commit flushes the right boundary nodes if complete flag is true. This + // function must be called before flushing the associated database batch. + commit(complete bool) common.Hash +} + +// pathTrie is a wrapper over the stackTrie, incorporating numerous additional +// logics to handle the semi-completed trie and potential leftover dangling +// nodes in the database. It is utilized for constructing the merkle tree nodes +// in path mode during the snap sync process. +type pathTrie struct { + owner common.Hash // identifier of trie owner, empty for account trie + tr *trie.StackTrie // underlying raw stack trie + first []byte // the path of first committed node by stackTrie + last []byte // the path of last committed node by stackTrie + + // This flag indicates whether nodes on the left boundary are skipped for + // committing. If set, the left boundary nodes are considered incomplete + // due to potentially missing left children. + skipLeftBoundary bool + db ethdb.KeyValueReader + batch ethdb.Batch +} + +// newPathTrie initializes the path trie. +func newPathTrie(owner common.Hash, skipLeftBoundary bool, db ethdb.KeyValueReader, batch ethdb.Batch) *pathTrie { + tr := &pathTrie{ + owner: owner, + skipLeftBoundary: skipLeftBoundary, + db: db, + batch: batch, + } + tr.tr = trie.NewStackTrie(tr.onTrieNode) + return tr +} + +// onTrieNode is invoked whenever a new node is committed by the stackTrie. +// +// As the committed nodes might be incomplete if they are on the boundaries +// (left or right), this function has the ability to detect the incomplete +// ones and filter them out for committing. +// +// Additionally, the assumption is made that there may exist leftover dangling +// nodes in the database. This function has the ability to detect the dangling +// nodes that fall within the path space of committed nodes (specifically on +// the path covered by internal extension nodes) and remove them from the +// database. This property ensures that the entire path space is uniquely +// occupied by committed nodes. +// +// Furthermore, all leftover dangling nodes along the path from committed nodes +// to the trie root (left and right boundaries) should be removed as well; +// otherwise, they might potentially disrupt the state healing process. +func (t *pathTrie) onTrieNode(path []byte, hash common.Hash, blob []byte) { + // Filter out the nodes on the left boundary if skipLeftBoundary is + // configured. Nodes are considered to be on the left boundary if + // it's the first one to be committed, or the parent/ancestor of the + // first committed node. + if t.skipLeftBoundary && (t.first == nil || bytes.HasPrefix(t.first, path)) { + if t.first == nil { + // Memorize the path of first committed node, which is regarded + // as left boundary. Deep-copy is necessary as the path given + // is volatile. + t.first = append([]byte{}, path...) + + // The left boundary can be uniquely determined by the first committed node + // from stackTrie (e.g., N_1), as the shared path prefix between the first + // two inserted state items is deterministic (the path of N_3). The path + // from trie root towards the first committed node is considered the left + // boundary. The potential leftover dangling nodes on left boundary should + // be cleaned out. + // + // +-----+ + // | N_3 | shared path prefix of state_1 and state_2 + // +-----+ + // /- -\ + // +-----+ +-----+ + // First committed node | N_1 | | N_2 | latest inserted node (contain state_2) + // +-----+ +-----+ + // + // The node with the path of the first committed one (e.g, N_1) is not + // removed because it's a sibling of the nodes we want to commit, not + // the parent or ancestor. + for i := 0; i < len(path); i++ { + t.deleteNode(path[:i], false) + } + } + return + } + // If boundary filtering is not configured, or the node is not on the left + // boundary, commit it to database. + // + // Note: If the current committed node is an extension node, then the nodes + // falling within the path between itself and its standalone (not embedded + // in parent) child should be cleaned out for exclusively occupy the inner + // path. + // + // This is essential in snap sync to avoid leaving dangling nodes within + // this range covered by extension node which could potentially break the + // state healing. + // + // The extension node is detected if its path is the prefix of last committed + // one and path gap is larger than one. If the path gap is only one byte, + // the current node could either be a full node, or an extension with single + // byte key. In either case, no gaps will be left in the path. + if t.last != nil && bytes.HasPrefix(t.last, path) && len(t.last)-len(path) > 1 { + for i := len(path) + 1; i < len(t.last); i++ { + t.deleteNode(t.last[:i], true) + } + } + t.write(path, blob) + + // Update the last flag. Deep-copy is necessary as the provided path is volatile. + if t.last == nil { + t.last = append([]byte{}, path...) + } else { + t.last = append(t.last[:0], path...) + } +} + +// write commits the node write to provided database batch in path mode. +func (t *pathTrie) write(path []byte, blob []byte) { + if t.owner == (common.Hash{}) { + rawdb.WriteAccountTrieNode(t.batch, path, blob) + } else { + rawdb.WriteStorageTrieNode(t.batch, t.owner, path, blob) + } +} + +func (t *pathTrie) deleteAccountNode(path []byte, inner bool) { + if inner { + accountInnerLookupGauge.Inc(1) + } else { + accountOuterLookupGauge.Inc(1) + } + if !rawdb.HasAccountTrieNode(t.db, path) { + return + } + if inner { + accountInnerDeleteGauge.Inc(1) + } else { + accountOuterDeleteGauge.Inc(1) + } + rawdb.DeleteAccountTrieNode(t.batch, path) +} + +func (t *pathTrie) deleteStorageNode(path []byte, inner bool) { + if inner { + storageInnerLookupGauge.Inc(1) + } else { + storageOuterLookupGauge.Inc(1) + } + if !rawdb.HasStorageTrieNode(t.db, t.owner, path) { + return + } + if inner { + storageInnerDeleteGauge.Inc(1) + } else { + storageOuterDeleteGauge.Inc(1) + } + rawdb.DeleteStorageTrieNode(t.batch, t.owner, path) +} + +// deleteNode commits the node deletion to provided database batch in path mode. +func (t *pathTrie) deleteNode(path []byte, inner bool) { + if t.owner == (common.Hash{}) { + t.deleteAccountNode(path, inner) + } else { + t.deleteStorageNode(path, inner) + } +} + +// update implements genTrie interface, inserting a (key, value) pair into the +// stack trie. +func (t *pathTrie) update(key, value []byte) error { + return t.tr.Update(key, value) +} + +// delete implements genTrie interface, deleting the item from the stack trie. +func (t *pathTrie) delete(key []byte) error { + // Commit the trie since the right boundary is incomplete because + // of the deleted item. This will implicitly discard the last inserted + // item and clean some ancestor trie nodes of the last committed + // item in the database. + t.commit(false) + + // Reset the trie and all the internal trackers + t.first = nil + t.last = nil + t.tr.Reset() + + // Explicitly mark the left boundary as incomplete, as the left-side + // item of the next one has been deleted. Be aware that the next item + // to be inserted will be ignored from committing as well as it's on + // the left boundary. + t.skipLeftBoundary = true + + // Explicitly delete the potential leftover nodes on the specific + // path from the database. + tkey := t.tr.TrieKey(key) + for i := 0; i <= len(tkey); i++ { + t.deleteNode(tkey[:i], false) + } + return nil +} + +// commit implements genTrie interface, flushing the right boundary if it's +// considered as complete. Otherwise, the nodes on the right boundary are +// discarded and cleaned up. +// +// Note, this function must be called before flushing database batch, otherwise, +// dangling nodes might be left in database. +func (t *pathTrie) commit(complete bool) common.Hash { + // If the right boundary is claimed as complete, flush them out. + // The nodes on both left and right boundary will still be filtered + // out if left boundary filtering is configured. + if complete { + // Commit all inserted but not yet committed nodes(on the right + // boundary) in the stackTrie. + hash := t.tr.Hash() + if t.skipLeftBoundary { + return common.Hash{} // hash is meaningless if left side is incomplete + } + return hash + } + // Discard nodes on the right boundary as it's claimed as incomplete. These + // nodes might be incomplete due to missing children on the right side. + // Furthermore, the potential leftover nodes on right boundary should also + // be cleaned out. + // + // The right boundary can be uniquely determined by the last committed node + // from stackTrie (e.g., N_1), as the shared path prefix between the last + // two inserted state items is deterministic (the path of N_3). The path + // from trie root towards the last committed node is considered the right + // boundary (root to N_3). + // + // +-----+ + // | N_3 | shared path prefix of last two states + // +-----+ + // /- -\ + // +-----+ +-----+ + // Last committed node | N_1 | | N_2 | latest inserted node (contain last state) + // +-----+ +-----+ + // + // Another interesting scenario occurs when the trie is committed due to + // too many items being accumulated in the batch. To flush them out to + // the database, the path of the last inserted node (N_2) is temporarily + // treated as an incomplete right boundary, and nodes on this path are + // removed (e.g. from root to N_3). + // However, this path will be reclaimed as an internal path by inserting + // more items after the batch flush. New nodes on this path can be committed + // with no issues as they are actually complete. Also, from a database + // perspective, first deleting and then rewriting is a valid data update. + for i := 0; i < len(t.last); i++ { + t.deleteNode(t.last[:i], false) + } + return common.Hash{} // the hash is meaningless for incomplete commit +} + +// hashTrie is a wrapper over the stackTrie for implementing genTrie interface. +type hashTrie struct { + tr *trie.StackTrie +} + +// newHashTrie initializes the hash trie. +func newHashTrie(batch ethdb.Batch) *hashTrie { + return &hashTrie{tr: trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + rawdb.WriteLegacyTrieNode(batch, hash, blob) + })} +} + +// update implements genTrie interface, inserting a (key, value) pair into +// the stack trie. +func (t *hashTrie) update(key, value []byte) error { + return t.tr.Update(key, value) +} + +// delete implements genTrie interface, ignoring the state item for deleting. +func (t *hashTrie) delete(key []byte) error { return nil } + +// commit implements genTrie interface, committing the nodes on right boundary. +func (t *hashTrie) commit(complete bool) common.Hash { + if !complete { + return common.Hash{} // the hash is meaningless for incomplete commit + } + return t.tr.Hash() // return hash only if it's claimed as complete +} diff --git a/eth/protocols/snap/gentrie_test.go b/eth/protocols/snap/gentrie_test.go new file mode 100644 index 0000000000..2da4f3c866 --- /dev/null +++ b/eth/protocols/snap/gentrie_test.go @@ -0,0 +1,695 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package snap + +import ( + "bytes" + "math/rand" + "slices" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/testrand" + "github.com/ethereum/go-ethereum/trie" +) + +type replayer struct { + paths []string // sort in fifo order + hashes []common.Hash // empty for deletion + unknowns int // counter for unknown write +} + +func newBatchReplay() *replayer { + return &replayer{} +} + +func (r *replayer) decode(key []byte, value []byte) { + account := rawdb.IsAccountTrieNode(key) + storage := rawdb.IsStorageTrieNode(key) + if !account && !storage { + r.unknowns += 1 + return + } + var path []byte + if account { + _, path = rawdb.ResolveAccountTrieNodeKey(key) + } else { + _, owner, inner := rawdb.ResolveStorageTrieNode(key) + path = append(owner.Bytes(), inner...) + } + r.paths = append(r.paths, string(path)) + + if len(value) == 0 { + r.hashes = append(r.hashes, common.Hash{}) + } else { + r.hashes = append(r.hashes, crypto.Keccak256Hash(value)) + } +} + +// updates returns a set of effective mutations. Multiple mutations targeting +// the same node path will be merged in FIFO order. +func (r *replayer) modifies() map[string]common.Hash { + set := make(map[string]common.Hash) + for i, path := range r.paths { + set[path] = r.hashes[i] + } + return set +} + +// updates returns the number of updates. +func (r *replayer) updates() int { + var count int + for _, hash := range r.modifies() { + if hash == (common.Hash{}) { + continue + } + count++ + } + return count +} + +// Put inserts the given value into the key-value data store. +func (r *replayer) Put(key []byte, value []byte) error { + r.decode(key, value) + return nil +} + +// Delete removes the key from the key-value data store. +func (r *replayer) Delete(key []byte) error { + r.decode(key, nil) + return nil +} + +func byteToHex(str []byte) []byte { + l := len(str) * 2 + var nibbles = make([]byte, l) + for i, b := range str { + nibbles[i*2] = b / 16 + nibbles[i*2+1] = b % 16 + } + return nibbles +} + +// innerNodes returns the internal nodes narrowed by two boundaries along with +// the leftmost and rightmost sub-trie roots. +func innerNodes(first, last []byte, includeLeft, includeRight bool, nodes map[string]common.Hash, t *testing.T) (map[string]common.Hash, []byte, []byte) { + var ( + leftRoot []byte + rightRoot []byte + firstHex = byteToHex(first) + lastHex = byteToHex(last) + inner = make(map[string]common.Hash) + ) + for path, hash := range nodes { + if hash == (common.Hash{}) { + t.Fatalf("Unexpected deletion, %v", []byte(path)) + } + // Filter out the siblings on the left side or the left boundary nodes. + if !includeLeft && (bytes.Compare(firstHex, []byte(path)) > 0 || bytes.HasPrefix(firstHex, []byte(path))) { + continue + } + // Filter out the siblings on the right side or the right boundary nodes. + if !includeRight && (bytes.Compare(lastHex, []byte(path)) < 0 || bytes.HasPrefix(lastHex, []byte(path))) { + continue + } + inner[path] = hash + + // Track the path of the leftmost sub trie root + if leftRoot == nil || bytes.Compare(leftRoot, []byte(path)) > 0 { + leftRoot = []byte(path) + } + // Track the path of the rightmost sub trie root + if rightRoot == nil || + (bytes.Compare(rightRoot, []byte(path)) < 0) || + (bytes.Compare(rightRoot, []byte(path)) > 0 && bytes.HasPrefix(rightRoot, []byte(path))) { + rightRoot = []byte(path) + } + } + return inner, leftRoot, rightRoot +} + +func buildPartial(owner common.Hash, db ethdb.KeyValueReader, batch ethdb.Batch, entries []*kv, first, last int) *replayer { + tr := newPathTrie(owner, first != 0, db, batch) + for i := first; i <= last; i++ { + tr.update(entries[i].k, entries[i].v) + } + tr.commit(last == len(entries)-1) + + replay := newBatchReplay() + batch.Replay(replay) + + return replay +} + +// TestPartialGentree verifies if the trie constructed with partial states can +// generate consistent trie nodes that match those of the full trie. +func TestPartialGentree(t *testing.T) { + for round := 0; round < 100; round++ { + var ( + n = rand.Intn(1024) + 10 + entries []*kv + ) + for i := 0; i < n; i++ { + var val []byte + if rand.Intn(3) == 0 { + val = testrand.Bytes(3) + } else { + val = testrand.Bytes(32) + } + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: val, + }) + } + slices.SortFunc(entries, (*kv).cmp) + + nodes := make(map[string]common.Hash) + tr := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + nodes[string(path)] = hash + }) + for i := 0; i < len(entries); i++ { + tr.Update(entries[i].k, entries[i].v) + } + tr.Hash() + + check := func(first, last int) { + var ( + db = rawdb.NewMemoryDatabase() + batch = db.NewBatch() + ) + // Build the partial tree with specific boundaries + r := buildPartial(common.Hash{}, db, batch, entries, first, last) + if r.unknowns > 0 { + t.Fatalf("Unknown database write: %d", r.unknowns) + } + + // Ensure all the internal nodes are produced + var ( + set = r.modifies() + inner, _, _ = innerNodes(entries[first].k, entries[last].k, first == 0, last == len(entries)-1, nodes, t) + ) + for path, hash := range inner { + if _, ok := set[path]; !ok { + t.Fatalf("Missing nodes %v", []byte(path)) + } + if hash != set[path] { + t.Fatalf("Inconsistent node, want %x, got: %x", hash, set[path]) + } + } + if r.updates() != len(inner) { + t.Fatalf("Unexpected node write detected, want: %d, got: %d", len(inner), r.updates()) + } + } + for j := 0; j < 100; j++ { + var ( + first int + last int + ) + for { + first = rand.Intn(len(entries)) + last = rand.Intn(len(entries)) + if first <= last { + break + } + } + check(first, last) + } + var cases = []struct { + first int + last int + }{ + {0, len(entries) - 1}, // full + {1, len(entries) - 1}, // no left + {2, len(entries) - 1}, // no left + {2, len(entries) - 2}, // no left and right + {2, len(entries) - 2}, // no left and right + {len(entries) / 2, len(entries) / 2}, // single + {0, 0}, // single first + {len(entries) - 1, len(entries) - 1}, // single last + } + for _, c := range cases { + check(c.first, c.last) + } + } +} + +// TestGentreeDanglingClearing tests if the dangling nodes falling within the +// path space of constructed tree can be correctly removed. +func TestGentreeDanglingClearing(t *testing.T) { + for round := 0; round < 100; round++ { + var ( + n = rand.Intn(1024) + 10 + entries []*kv + ) + for i := 0; i < n; i++ { + var val []byte + if rand.Intn(3) == 0 { + val = testrand.Bytes(3) + } else { + val = testrand.Bytes(32) + } + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: val, + }) + } + slices.SortFunc(entries, (*kv).cmp) + + nodes := make(map[string]common.Hash) + tr := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + nodes[string(path)] = hash + }) + for i := 0; i < len(entries); i++ { + tr.Update(entries[i].k, entries[i].v) + } + tr.Hash() + + check := func(first, last int) { + var ( + db = rawdb.NewMemoryDatabase() + batch = db.NewBatch() + ) + // Write the junk nodes as the dangling + var injects []string + for path := range nodes { + for i := 0; i < len(path); i++ { + _, ok := nodes[path[:i]] + if ok { + continue + } + injects = append(injects, path[:i]) + } + } + if len(injects) == 0 { + return + } + for _, path := range injects { + rawdb.WriteAccountTrieNode(db, []byte(path), testrand.Bytes(32)) + } + + // Build the partial tree with specific range + replay := buildPartial(common.Hash{}, db, batch, entries, first, last) + if replay.unknowns > 0 { + t.Fatalf("Unknown database write: %d", replay.unknowns) + } + set := replay.modifies() + + // Make sure the injected junks falling within the path space of + // committed trie nodes are correctly deleted. + _, leftRoot, rightRoot := innerNodes(entries[first].k, entries[last].k, first == 0, last == len(entries)-1, nodes, t) + for _, path := range injects { + if bytes.Compare([]byte(path), leftRoot) < 0 && !bytes.HasPrefix(leftRoot, []byte(path)) { + continue + } + if bytes.Compare([]byte(path), rightRoot) > 0 { + continue + } + if hash, ok := set[path]; !ok || hash != (common.Hash{}) { + t.Fatalf("Missing delete, %v", []byte(path)) + } + } + } + for j := 0; j < 100; j++ { + var ( + first int + last int + ) + for { + first = rand.Intn(len(entries)) + last = rand.Intn(len(entries)) + if first <= last { + break + } + } + check(first, last) + } + var cases = []struct { + first int + last int + }{ + {0, len(entries) - 1}, // full + {1, len(entries) - 1}, // no left + {2, len(entries) - 1}, // no left + {2, len(entries) - 2}, // no left and right + {2, len(entries) - 2}, // no left and right + {len(entries) / 2, len(entries) / 2}, // single + {0, 0}, // single first + {len(entries) - 1, len(entries) - 1}, // single last + } + for _, c := range cases { + check(c.first, c.last) + } + } +} + +// TestFlushPartialTree tests the gentrie can produce complete inner trie nodes +// even with lots of batch flushes. +func TestFlushPartialTree(t *testing.T) { + var entries []*kv + for i := 0; i < 1024; i++ { + var val []byte + if rand.Intn(3) == 0 { + val = testrand.Bytes(3) + } else { + val = testrand.Bytes(32) + } + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: val, + }) + } + slices.SortFunc(entries, (*kv).cmp) + + nodes := make(map[string]common.Hash) + tr := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + nodes[string(path)] = hash + }) + for i := 0; i < len(entries); i++ { + tr.Update(entries[i].k, entries[i].v) + } + tr.Hash() + + var cases = []struct { + first int + last int + }{ + {0, len(entries) - 1}, // full + {1, len(entries) - 1}, // no left + {10, len(entries) - 1}, // no left + {10, len(entries) - 2}, // no left and right + {10, len(entries) - 10}, // no left and right + {11, 11}, // single + {0, 0}, // single first + {len(entries) - 1, len(entries) - 1}, // single last + } + for _, c := range cases { + var ( + db = rawdb.NewMemoryDatabase() + batch = db.NewBatch() + combined = db.NewBatch() + ) + inner, _, _ := innerNodes(entries[c.first].k, entries[c.last].k, c.first == 0, c.last == len(entries)-1, nodes, t) + + tr := newPathTrie(common.Hash{}, c.first != 0, db, batch) + for i := c.first; i <= c.last; i++ { + tr.update(entries[i].k, entries[i].v) + if rand.Intn(2) == 0 { + tr.commit(false) + + batch.Replay(combined) + batch.Write() + batch.Reset() + } + } + tr.commit(c.last == len(entries)-1) + + batch.Replay(combined) + batch.Write() + batch.Reset() + + r := newBatchReplay() + combined.Replay(r) + + // Ensure all the internal nodes are produced + set := r.modifies() + for path, hash := range inner { + if _, ok := set[path]; !ok { + t.Fatalf("Missing nodes %v", []byte(path)) + } + if hash != set[path] { + t.Fatalf("Inconsistent node, want %x, got: %x", hash, set[path]) + } + } + if r.updates() != len(inner) { + t.Fatalf("Unexpected node write detected, want: %d, got: %d", len(inner), r.updates()) + } + } +} + +// TestBoundSplit ensures two consecutive trie chunks are not overlapped with +// each other. +func TestBoundSplit(t *testing.T) { + var entries []*kv + for i := 0; i < 1024; i++ { + var val []byte + if rand.Intn(3) == 0 { + val = testrand.Bytes(3) + } else { + val = testrand.Bytes(32) + } + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: val, + }) + } + slices.SortFunc(entries, (*kv).cmp) + + for j := 0; j < 100; j++ { + var ( + next int + last int + db = rawdb.NewMemoryDatabase() + + lastRightRoot []byte + ) + for { + if next == len(entries) { + break + } + last = rand.Intn(len(entries)-next) + next + + r := buildPartial(common.Hash{}, db, db.NewBatch(), entries, next, last) + set := r.modifies() + + // Skip if the chunk is zero-size + if r.updates() == 0 { + next = last + 1 + continue + } + + // Ensure the updates in two consecutive chunks are not overlapped. + // The only overlapping part should be deletion. + if lastRightRoot != nil && len(set) > 0 { + // Derive the path of left-most node in this chunk + var leftRoot []byte + for path, hash := range r.modifies() { + if hash == (common.Hash{}) { + t.Fatalf("Unexpected deletion %v", []byte(path)) + } + if leftRoot == nil || bytes.Compare(leftRoot, []byte(path)) > 0 { + leftRoot = []byte(path) + } + } + if bytes.HasPrefix(lastRightRoot, leftRoot) || bytes.HasPrefix(leftRoot, lastRightRoot) { + t.Fatalf("Two chunks are not correctly separated, lastRight: %v, left: %v", lastRightRoot, leftRoot) + } + } + + // Track the updates as the last chunk + var rightRoot []byte + for path := range set { + if rightRoot == nil || + (bytes.Compare(rightRoot, []byte(path)) < 0) || + (bytes.Compare(rightRoot, []byte(path)) > 0 && bytes.HasPrefix(rightRoot, []byte(path))) { + rightRoot = []byte(path) + } + } + lastRightRoot = rightRoot + next = last + 1 + } + } +} + +// TestTinyPartialTree tests if the partial tree is too tiny(has less than two +// states), then nothing should be committed. +func TestTinyPartialTree(t *testing.T) { + var entries []*kv + for i := 0; i < 1024; i++ { + var val []byte + if rand.Intn(3) == 0 { + val = testrand.Bytes(3) + } else { + val = testrand.Bytes(32) + } + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: val, + }) + } + slices.SortFunc(entries, (*kv).cmp) + + for i := 0; i < len(entries); i++ { + next := i + last := i + 1 + if last >= len(entries) { + last = len(entries) - 1 + } + db := rawdb.NewMemoryDatabase() + r := buildPartial(common.Hash{}, db, db.NewBatch(), entries, next, last) + + if next != 0 && last != len(entries)-1 { + if r.updates() != 0 { + t.Fatalf("Unexpected data writes, got: %d", r.updates()) + } + } + } +} + +func TestTrieDelete(t *testing.T) { + var entries []*kv + for i := 0; i < 1024; i++ { + entries = append(entries, &kv{ + k: testrand.Bytes(32), + v: testrand.Bytes(32), + }) + } + slices.SortFunc(entries, (*kv).cmp) + + nodes := make(map[string]common.Hash) + tr := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { + nodes[string(path)] = hash + }) + for i := 0; i < len(entries); i++ { + tr.Update(entries[i].k, entries[i].v) + } + tr.Hash() + + check := func(index []int) { + var ( + db = rawdb.NewMemoryDatabase() + batch = db.NewBatch() + marks = map[int]struct{}{} + neighbors = map[int]struct{}{} + ) + for _, n := range index { + marks[n] = struct{}{} + } + for _, n := range index { + if n != 0 { + if _, ok := marks[n-1]; !ok { + neighbors[n-1] = struct{}{} + } + } + if n != len(entries)-1 { + if _, ok := neighbors[n+1]; !ok { + neighbors[n+1] = struct{}{} + } + } + } + // Write the junk nodes as the dangling + var injects []string + for _, n := range index { + nibbles := byteToHex(entries[n].k) + for i := 0; i <= len(nibbles); i++ { + injects = append(injects, string(nibbles[:i])) + } + } + for _, path := range injects { + rawdb.WriteAccountTrieNode(db, []byte(path), testrand.Bytes(32)) + } + tr := newPathTrie(common.Hash{}, false, db, batch) + for i := 0; i < len(entries); i++ { + if _, ok := marks[i]; ok { + tr.delete(entries[i].k) + } else { + tr.update(entries[i].k, entries[i].v) + } + } + tr.commit(true) + + r := newBatchReplay() + batch.Replay(r) + batch.Write() + + for _, path := range injects { + if rawdb.HasAccountTrieNode(db, []byte(path)) { + t.Fatalf("Unexpected leftover node %v", []byte(path)) + } + } + + // ensure all the written nodes match with the complete tree + set := make(map[string]common.Hash) + for path, hash := range r.modifies() { + if hash == (common.Hash{}) { + continue + } + n, ok := nodes[path] + if !ok { + t.Fatalf("Unexpected trie node: %v", []byte(path)) + } + if n != hash { + t.Fatalf("Unexpected trie node content: %v, want: %x, got: %x", []byte(path), n, hash) + } + set[path] = hash + } + + // ensure all the missing nodes either on the deleted path, or + // on the neighbor paths. + isMissing := func(path []byte) bool { + for n := range marks { + key := byteToHex(entries[n].k) + if bytes.HasPrefix(key, path) { + return true + } + } + for n := range neighbors { + key := byteToHex(entries[n].k) + if bytes.HasPrefix(key, path) { + return true + } + } + return false + } + for path := range nodes { + if _, ok := set[path]; ok { + continue + } + if !isMissing([]byte(path)) { + t.Fatalf("Missing node %v", []byte(path)) + } + } + } + var cases = []struct { + index []int + }{ + // delete the first + {[]int{0}}, + + // delete the last + {[]int{len(entries) - 1}}, + + // delete the first two + {[]int{0, 1}}, + + // delete the last two + {[]int{len(entries) - 2, len(entries) - 1}}, + + {[]int{ + 0, 2, 4, 6, + len(entries) - 1, + len(entries) - 3, + len(entries) - 5, + len(entries) - 7, + }}, + } + for _, c := range cases { + check(c.index) + } +} diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go index bd7ce9e715..a6c60bc075 100644 --- a/eth/protocols/snap/handler.go +++ b/eth/protocols/snap/handler.go @@ -82,13 +82,7 @@ type Backend interface { } // MakeProtocols constructs the P2P protocol definitions for `snap`. -func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { - // Filter the discovery iterator for nodes advertising snap support. - dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool { - var snap enrEntry - return n.Load(&snap) == nil - }) - +func MakeProtocols(backend Backend) []p2p.Protocol { protocols := make([]p2p.Protocol, len(ProtocolVersions)) for i, version := range ProtocolVersions { version := version // Closure @@ -108,8 +102,7 @@ func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { PeerInfo: func(id enode.ID) interface{} { return backend.PeerInfo(id) }, - Attributes: []enr.Entry{&enrEntry{}}, - DialCandidates: dnsdisc, + Attributes: []enr.Entry{&enrEntry{}}, } } return protocols @@ -332,11 +325,7 @@ func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePac return nil, nil } } - var proofs [][]byte - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } - return accounts, proofs + return accounts, proof.List() } func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesPacket) ([][]*StorageData, [][]byte) { @@ -438,9 +427,7 @@ func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesP return nil, nil } } - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } + proofs = append(proofs, proof.List()...) // Proof terminates the reply as proofs are only added if a node // refuses to serve more data (exception when a contract fetch is // finishing, but that's that). diff --git a/eth/protocols/snap/metrics.go b/eth/protocols/snap/metrics.go index a7d071953f..6878e5b280 100644 --- a/eth/protocols/snap/metrics.go +++ b/eth/protocols/snap/metrics.go @@ -17,7 +17,7 @@ package snap import ( - metrics "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics" ) var ( @@ -27,21 +27,28 @@ var ( IngressRegistrationErrorMeter = metrics.NewRegisteredMeter(ingressRegistrationErrorName, nil) EgressRegistrationErrorMeter = metrics.NewRegisteredMeter(egressRegistrationErrorName, nil) - // deletionGauge is the metric to track how many trie node deletions - // are performed in total during the sync process. - deletionGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete", nil) + // accountInnerDeleteGauge is the metric to track how many dangling trie nodes + // covered by extension node in account trie are deleted during the sync. + accountInnerDeleteGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete/account/inner", nil) - // lookupGauge is the metric to track how many trie node lookups are - // performed to determine if node needs to be deleted. - lookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/lookup", nil) + // storageInnerDeleteGauge is the metric to track how many dangling trie nodes + // covered by extension node in storage trie are deleted during the sync. + storageInnerDeleteGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete/storage/inner", nil) + + // accountOuterDeleteGauge is the metric to track how many dangling trie nodes + // above the committed nodes in account trie are deleted during the sync. + accountOuterDeleteGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete/account/outer", nil) - // boundaryAccountNodesGauge is the metric to track how many boundary trie - // nodes in account trie are met. - boundaryAccountNodesGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/boundary/account", nil) + // storageOuterDeleteGauge is the metric to track how many dangling trie nodes + // above the committed nodes in storage trie are deleted during the sync. + storageOuterDeleteGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete/storage/outer", nil) - // boundaryAccountNodesGauge is the metric to track how many boundary trie - // nodes in storage tries are met. - boundaryStorageNodesGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/boundary/storage", nil) + // lookupGauge is the metric to track how many trie node lookups are + // performed to determine if node needs to be deleted. + accountInnerLookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/account/lookup/inner", nil) + accountOuterLookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/account/lookup/outer", nil) + storageInnerLookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/lookup/inner", nil) + storageOuterLookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/lookup/outer", nil) // smallStorageGauge is the metric to track how many storages are small enough // to retrieved in one or two request. @@ -54,4 +61,9 @@ var ( // skipStorageHealingGauge is the metric to track how many storages are retrieved // in multiple requests but healing is not necessary. skipStorageHealingGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/noheal", nil) + + // largeStorageDiscardGauge is the metric to track how many chunked storages are + // discarded during the snap sync. + largeStorageDiscardGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/chunk/discard", nil) + largeStorageResumedGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/chunk/resume", nil) ) diff --git a/eth/protocols/snap/progress_test.go b/eth/protocols/snap/progress_test.go new file mode 100644 index 0000000000..1d9a6b8474 --- /dev/null +++ b/eth/protocols/snap/progress_test.go @@ -0,0 +1,154 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package snap + +import ( + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// Legacy sync progress definitions +type legacyStorageTask struct { + Next common.Hash // Next account to sync in this interval + Last common.Hash // Last account to sync in this interval +} + +type legacyAccountTask struct { + Next common.Hash // Next account to sync in this interval + Last common.Hash // Last account to sync in this interval + SubTasks map[common.Hash][]*legacyStorageTask // Storage intervals needing fetching for large contracts +} + +type legacyProgress struct { + Tasks []*legacyAccountTask // The suspended account tasks (contract tasks within) +} + +func compareProgress(a legacyProgress, b SyncProgress) bool { + if len(a.Tasks) != len(b.Tasks) { + return false + } + for i := 0; i < len(a.Tasks); i++ { + if a.Tasks[i].Next != b.Tasks[i].Next { + return false + } + if a.Tasks[i].Last != b.Tasks[i].Last { + return false + } + // new fields are not checked here + + if len(a.Tasks[i].SubTasks) != len(b.Tasks[i].SubTasks) { + return false + } + for addrHash, subTasksA := range a.Tasks[i].SubTasks { + subTasksB, ok := b.Tasks[i].SubTasks[addrHash] + if !ok || len(subTasksB) != len(subTasksA) { + return false + } + for j := 0; j < len(subTasksA); j++ { + if subTasksA[j].Next != subTasksB[j].Next { + return false + } + if subTasksA[j].Last != subTasksB[j].Last { + return false + } + } + } + } + return true +} + +func makeLegacyProgress() legacyProgress { + return legacyProgress{ + Tasks: []*legacyAccountTask{ + { + Next: common.Hash{}, + Last: common.Hash{0x77}, + SubTasks: map[common.Hash][]*legacyStorageTask{ + {0x1}: { + { + Next: common.Hash{}, + Last: common.Hash{0xff}, + }, + }, + }, + }, + { + Next: common.Hash{0x88}, + Last: common.Hash{0xff}, + }, + }, + } +} + +func convertLegacy(legacy legacyProgress) SyncProgress { + var progress SyncProgress + for i, task := range legacy.Tasks { + subTasks := make(map[common.Hash][]*storageTask) + for owner, list := range task.SubTasks { + var cpy []*storageTask + for i := 0; i < len(list); i++ { + cpy = append(cpy, &storageTask{ + Next: list[i].Next, + Last: list[i].Last, + }) + } + subTasks[owner] = cpy + } + accountTask := &accountTask{ + Next: task.Next, + Last: task.Last, + SubTasks: subTasks, + } + if i == 0 { + accountTask.StorageCompleted = []common.Hash{{0xaa}, {0xbb}} // fulfill new fields + } + progress.Tasks = append(progress.Tasks, accountTask) + } + return progress +} + +func TestSyncProgressCompatibility(t *testing.T) { + // Decode serialized bytes of legacy progress, backward compatibility + legacy := makeLegacyProgress() + blob, err := json.Marshal(legacy) + if err != nil { + t.Fatalf("Failed to marshal progress %v", err) + } + var dec SyncProgress + if err := json.Unmarshal(blob, &dec); err != nil { + t.Fatalf("Failed to unmarshal progress %v", err) + } + if !compareProgress(legacy, dec) { + t.Fatal("sync progress is not backward compatible") + } + + // Decode serialized bytes of new format progress + progress := convertLegacy(legacy) + blob, err = json.Marshal(progress) + if err != nil { + t.Fatalf("Failed to marshal progress %v", err) + } + var legacyDec legacyProgress + if err := json.Unmarshal(blob, &legacyDec); err != nil { + t.Fatalf("Failed to unmarshal progress %v", err) + } + if !compareProgress(legacyDec, progress) { + t.Fatal("sync progress is not forward compatible") + } +} diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index 56d48649dd..87ce5287f8 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -43,7 +43,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" - "golang.org/x/crypto/sha3" ) const ( @@ -95,6 +94,9 @@ const ( // trienodeHealThrottleDecrease is the divisor for the throttle when the // rate of arriving data is lower than the rate of processing it. trienodeHealThrottleDecrease = 1.25 + + // batchSizeThreshold is the maximum size allowed for gentrie batch. + batchSizeThreshold = 8 * 1024 * 1024 ) var ( @@ -102,7 +104,7 @@ var ( // to allow concurrent retrievals. accountConcurrency = 16 - // storageConcurrency is the number of chunks to split the a large contract + // storageConcurrency is the number of chunks to split a large contract // storage trie into to allow concurrent retrievals. storageConcurrency = 16 ) @@ -296,11 +298,19 @@ type bytecodeHealResponse struct { // accountTask represents the sync task for a chunk of the account snapshot. type accountTask struct { - // These fields get serialized to leveldb on shutdown + // These fields get serialized to key-value store on shutdown Next common.Hash // Next account to sync in this interval Last common.Hash // Last account to sync in this interval SubTasks map[common.Hash][]*storageTask // Storage intervals needing fetching for large contracts + // This is a list of account hashes whose storage are already completed + // in this cycle. This field is newly introduced in v1.14 and will be + // empty if the task is resolved from legacy progress data. Furthermore, + // this additional field will be ignored by legacy Geth. The only side + // effect is that these contracts might be resynced in the new cycle, + // retaining the legacy behavior. + StorageCompleted []common.Hash `json:",omitempty"` + // These fields are internals used during runtime req *accountRequest // Pending request to fill this task res *accountResponse // Validate response filling this task @@ -310,15 +320,40 @@ type accountTask struct { needState []bool // Flags whether the filling accounts need storage retrieval needHeal []bool // Flags whether the filling accounts's state was chunked and need healing - codeTasks map[common.Hash]struct{} // Code hashes that need retrieval - stateTasks map[common.Hash]common.Hash // Account hashes->roots that need full state retrieval + codeTasks map[common.Hash]struct{} // Code hashes that need retrieval + stateTasks map[common.Hash]common.Hash // Account hashes->roots that need full state retrieval + stateCompleted map[common.Hash]struct{} // Account hashes whose storage have been completed - genBatch ethdb.Batch // Batch used by the node generator - genTrie *trie.StackTrie // Node generator from storage slots + genBatch ethdb.Batch // Batch used by the node generator + genTrie genTrie // Node generator from storage slots done bool // Flag whether the task can be removed } +// activeSubTasks returns the set of storage tasks covered by the current account +// range. Normally this would be the entire subTask set, but on a sync interrupt +// and later resume it can happen that a shorter account range is retrieved. This +// method ensures that we only start up the subtasks covered by the latest account +// response. +// +// Nil is returned if the account range is empty. +func (task *accountTask) activeSubTasks() map[common.Hash][]*storageTask { + if len(task.res.hashes) == 0 { + return nil + } + var ( + tasks = make(map[common.Hash][]*storageTask) + last = task.res.hashes[len(task.res.hashes)-1] + ) + for hash, subTasks := range task.SubTasks { + subTasks := subTasks // closure + if hash.Cmp(last) <= 0 { + tasks[hash] = subTasks + } + } + return tasks +} + // storageTask represents the sync task for a chunk of the storage snapshot. type storageTask struct { Next common.Hash // Next account to sync in this interval @@ -328,8 +363,8 @@ type storageTask struct { root common.Hash // Storage root hash for this instance req *storageRequest // Pending request to fill this task - genBatch ethdb.Batch // Batch used by the node generator - genTrie *trie.StackTrie // Node generator from storage slots + genBatch ethdb.Batch // Batch used by the node generator + genTrie genTrie // Node generator from storage slots done bool // Flag whether the task can be removed } @@ -717,19 +752,6 @@ func (s *Syncer) Sync(root common.Hash, cancel chan struct{}) error { } } -// cleanPath is used to remove the dangling nodes in the stackTrie. -func (s *Syncer) cleanPath(batch ethdb.Batch, owner common.Hash, path []byte) { - if owner == (common.Hash{}) && rawdb.ExistsAccountTrieNode(s.db.StateStoreReader(), path) { - rawdb.DeleteAccountTrieNode(batch, path) - deletionGauge.Inc(1) - } - if owner != (common.Hash{}) && rawdb.ExistsStorageTrieNode(s.db.StateStoreReader(), owner, path) { - rawdb.DeleteStorageTrieNode(batch, owner, path) - deletionGauge.Inc(1) - } - lookupGauge.Inc(1) -} - // loadSyncStatus retrieves a previously aborted sync status from the database, // or generates a fresh one if none is available. func (s *Syncer) loadSyncStatus() { @@ -747,28 +769,27 @@ func (s *Syncer) loadSyncStatus() { for _, task := range s.tasks { task := task // closure for task.genBatch in the stacktrie writer callback + // Restore the completed storages + task.stateCompleted = make(map[common.Hash]struct{}) + for _, hash := range task.StorageCompleted { + task.stateCompleted[hash] = struct{}{} + } + task.StorageCompleted = nil + + // Allocate batch for account trie generation task.genBatch = ethdb.HookedBatch{ Batch: stateDiskDB.NewBatch(), OnPut: func(key []byte, value []byte) { s.accountBytes += common.StorageSize(len(key) + len(value)) }, } - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(task.genBatch, common.Hash{}, path, hash, blob, s.scheme) - }) + if s.scheme == rawdb.HashScheme { + task.genTrie = newHashTrie(task.genBatch) + } if s.scheme == rawdb.PathScheme { - // Configure the dangling node cleaner and also filter out boundary nodes - // only in the context of the path scheme. Deletion is forbidden in the - // hash scheme, as it can disrupt state completeness. - options = options.WithCleaner(func(path []byte) { - s.cleanPath(task.genBatch, common.Hash{}, path) - }) - // Skip the left boundary if it's not the first range. - // Skip the right boundary if it's not the last range. - options = options.WithSkipBoundary(task.Next != (common.Hash{}), task.Last != common.MaxHash, boundaryAccountNodesGauge) + task.genTrie = newPathTrie(common.Hash{}, task.Next != common.Hash{}, s.db, task.genBatch) } - task.genTrie = trie.NewStackTrie(options) + // Restore leftover storage tasks for accountHash, subtasks := range task.SubTasks { for _, subtask := range subtasks { subtask := subtask // closure for subtask.genBatch in the stacktrie writer callback @@ -779,23 +800,12 @@ func (s *Syncer) loadSyncStatus() { s.storageBytes += common.StorageSize(len(key) + len(value)) }, } - owner := accountHash // local assignment for stacktrie writer closure - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(subtask.genBatch, owner, path, hash, blob, s.scheme) - }) + if s.scheme == rawdb.HashScheme { + subtask.genTrie = newHashTrie(subtask.genBatch) + } if s.scheme == rawdb.PathScheme { - // Configure the dangling node cleaner and also filter out boundary nodes - // only in the context of the path scheme. Deletion is forbidden in the - // hash scheme, as it can disrupt state completeness. - options = options.WithCleaner(func(path []byte) { - s.cleanPath(subtask.genBatch, owner, path) - }) - // Skip the left boundary if it's not the first range. - // Skip the right boundary if it's not the last range. - options = options.WithSkipBoundary(subtask.Next != common.Hash{}, subtask.Last != common.MaxHash, boundaryStorageNodesGauge) + subtask.genTrie = newPathTrie(accountHash, subtask.Next != common.Hash{}, s.db, subtask.genBatch) } - subtask.genTrie = trie.NewStackTrie(options) } } } @@ -847,27 +857,20 @@ func (s *Syncer) loadSyncStatus() { s.accountBytes += common.StorageSize(len(key) + len(value)) }, } - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(batch, common.Hash{}, path, hash, blob, s.scheme) - }) + var tr genTrie + if s.scheme == rawdb.HashScheme { + tr = newHashTrie(batch) + } if s.scheme == rawdb.PathScheme { - // Configure the dangling node cleaner and also filter out boundary nodes - // only in the context of the path scheme. Deletion is forbidden in the - // hash scheme, as it can disrupt state completeness. - options = options.WithCleaner(func(path []byte) { - s.cleanPath(batch, common.Hash{}, path) - }) - // Skip the left boundary if it's not the first range. - // Skip the right boundary if it's not the last range. - options = options.WithSkipBoundary(next != common.Hash{}, last != common.MaxHash, boundaryAccountNodesGauge) + tr = newPathTrie(common.Hash{}, next != common.Hash{}, s.db, batch) } s.tasks = append(s.tasks, &accountTask{ - Next: next, - Last: last, - SubTasks: make(map[common.Hash][]*storageTask), - genBatch: batch, - genTrie: trie.NewStackTrie(options), + Next: next, + Last: last, + SubTasks: make(map[common.Hash][]*storageTask), + genBatch: batch, + stateCompleted: make(map[common.Hash]struct{}), + genTrie: tr, }) log.Debug("Created account sync task", "from", next, "last", last) next = common.BigToHash(new(big.Int).Add(last.Big(), common.Big1)) @@ -878,16 +881,31 @@ func (s *Syncer) loadSyncStatus() { func (s *Syncer) saveSyncStatus() { // Serialize any partial progress to disk before spinning down for _, task := range s.tasks { + // Claim the right boundary as incomplete before flushing the + // accumulated nodes in batch, the nodes on right boundary + // will be discarded and cleaned up by this call. + task.genTrie.commit(false) if err := task.genBatch.Write(); err != nil { log.Error("Failed to persist account slots", "err", err) } for _, subtasks := range task.SubTasks { for _, subtask := range subtasks { + // Same for account trie, discard and cleanup the + // incomplete right boundary. + subtask.genTrie.commit(false) if err := subtask.genBatch.Write(); err != nil { log.Error("Failed to persist storage slots", "err", err) } } } + // Save the account hashes of completed storage. + task.StorageCompleted = make([]common.Hash, 0, len(task.stateCompleted)) + for hash := range task.stateCompleted { + task.StorageCompleted = append(task.StorageCompleted, hash) + } + if len(task.StorageCompleted) > 0 { + log.Debug("Leftover completed storages", "number", len(task.StorageCompleted), "next", task.Next, "last", task.Last) + } } // Store the actual progress markers progress := &SyncProgress{ @@ -972,6 +990,10 @@ func (s *Syncer) cleanStorageTasks() { delete(task.SubTasks, account) task.pend-- + // Mark the state as complete to prevent resyncing, regardless + // if state healing is necessary. + task.stateCompleted[account] = struct{}{} + // If this was the last pending task, forward the account task if task.pend == 0 { s.forwardAccountTask(task) @@ -1212,7 +1234,8 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st continue } // Skip tasks that are already retrieving (or done with) all small states - if len(task.SubTasks) == 0 && len(task.stateTasks) == 0 { + storageTasks := task.activeSubTasks() + if len(storageTasks) == 0 && len(task.stateTasks) == 0 { continue } // Task pending retrieval, try to find an idle peer. If no such peer @@ -1256,7 +1279,7 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st roots = make([]common.Hash, 0, storageSets) subtask *storageTask ) - for account, subtasks := range task.SubTasks { + for account, subtasks := range storageTasks { for _, st := range subtasks { // Skip any subtasks already filling if st.req != nil { @@ -1855,11 +1878,11 @@ func (s *Syncer) processAccountResponse(res *accountResponse) { res.task.res = res // Ensure that the response doesn't overflow into the subsequent task - last := res.task.Last.Big() + lastBig := res.task.Last.Big() for i, hash := range res.hashes { // Mark the range complete if the last is already included. // Keep iteration to delete the extra states if exists. - cmp := hash.Big().Cmp(last) + cmp := hash.Big().Cmp(lastBig) if cmp == 0 { res.cont = false continue @@ -1895,7 +1918,21 @@ func (s *Syncer) processAccountResponse(res *accountResponse) { } // Check if the account is a contract with an unknown storage trie if account.Root != types.EmptyRootHash { - if !rawdb.HasTrieNode(s.db.StateStoreReader(), res.hashes[i], nil, account.Root, s.scheme) { + // If the storage was already retrieved in the last cycle, there's no need + // to resync it again, regardless of whether the storage root is consistent + // or not. + if _, exist := res.task.stateCompleted[res.hashes[i]]; exist { + // The leftover storage tasks are not expected, unless system is + // very wrong. + if _, ok := res.task.SubTasks[res.hashes[i]]; ok { + panic(fmt.Errorf("unexpected leftover storage tasks, owner: %x", res.hashes[i])) + } + // Mark the healing tag if storage root node is inconsistent, or + // it's non-existent due to storage chunking. + if !rawdb.HasTrieNode(s.db.StateStoreReader(), res.hashes[i], nil, account.Root, s.scheme) { + res.task.needHeal[i] = true + } + } else { // If there was a previous large state retrieval in progress, // don't restart it from scratch. This happens if a sync cycle // is interrupted and resumed later. However, *do* update the @@ -1907,7 +1944,12 @@ func (s *Syncer) processAccountResponse(res *accountResponse) { } res.task.needHeal[i] = true resumed[res.hashes[i]] = struct{}{} + largeStorageResumedGauge.Inc(1) } else { + // It's possible that in the hash scheme, the storage, along + // with the trie nodes of the given root, is already present + // in the database. Schedule the storage task anyway to simplify + // the logic here. res.task.stateTasks[res.hashes[i]] = account.Root } res.task.needState[i] = true @@ -1915,13 +1957,29 @@ func (s *Syncer) processAccountResponse(res *accountResponse) { } } } - // Delete any subtasks that have been aborted but not resumed. This may undo - // some progress if a new peer gives us less accounts than an old one, but for - // now we have to live with that. - for hash := range res.task.SubTasks { - if _, ok := resumed[hash]; !ok { - log.Debug("Aborting suspended storage retrieval", "account", hash) - delete(res.task.SubTasks, hash) + // Delete any subtasks that have been aborted but not resumed. It's essential + // as the corresponding contract might be self-destructed in this cycle(it's + // no longer possible in ethereum as self-destruction is disabled in Cancun + // Fork, but the condition is still necessary for other networks). + // + // Keep the leftover storage tasks if they are not covered by the responded + // account range which should be picked up in next account wave. + if len(res.hashes) > 0 { + // The hash of last delivered account in the response + last := res.hashes[len(res.hashes)-1] + for hash := range res.task.SubTasks { + // TODO(rjl493456442) degrade the log level before merging. + if hash.Cmp(last) > 0 { + log.Info("Keeping suspended storage retrieval", "account", hash) + continue + } + // TODO(rjl493456442) degrade the log level before merging. + // It should never happen in ethereum. + if _, ok := resumed[hash]; !ok { + log.Error("Aborting suspended storage retrieval", "account", hash) + delete(res.task.SubTasks, hash) + largeStorageDiscardGauge.Inc(1) + } } } // If the account range contained no contracts, or all have been fully filled @@ -2032,6 +2090,7 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { if res.subTask == nil && res.mainTask.needState[j] && (i < len(res.hashes)-1 || !res.cont) { res.mainTask.needState[j] = false res.mainTask.pend-- + res.mainTask.stateCompleted[account] = struct{}{} // mark it as completed smallStorageGauge.Inc(1) } // If the last contract was chunked, mark it as needing healing @@ -2080,25 +2139,20 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { s.storageBytes += common.StorageSize(len(key) + len(value)) }, } - owner := account // local assignment for stacktrie writer closure - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(batch, owner, path, hash, blob, s.scheme) - }) + var tr genTrie + if s.scheme == rawdb.HashScheme { + tr = newHashTrie(batch) + } if s.scheme == rawdb.PathScheme { - options = options.WithCleaner(func(path []byte) { - s.cleanPath(batch, owner, path) - }) // Keep the left boundary as it's the first range. - // Skip the right boundary if it's not the last range. - options = options.WithSkipBoundary(false, r.End() != common.MaxHash, boundaryStorageNodesGauge) + tr = newPathTrie(account, false, s.db, batch) } tasks = append(tasks, &storageTask{ Next: common.Hash{}, Last: r.End(), root: acc.Root, genBatch: batch, - genTrie: trie.NewStackTrie(options), + genTrie: tr, }) for r.Next() { batch := ethdb.HookedBatch{ @@ -2107,27 +2161,19 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { s.storageBytes += common.StorageSize(len(key) + len(value)) }, } - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(batch, owner, path, hash, blob, s.scheme) - }) + var tr genTrie + if s.scheme == rawdb.HashScheme { + tr = newHashTrie(batch) + } if s.scheme == rawdb.PathScheme { - // Configure the dangling node cleaner and also filter out boundary nodes - // only in the context of the path scheme. Deletion is forbidden in the - // hash scheme, as it can disrupt state completeness. - options = options.WithCleaner(func(path []byte) { - s.cleanPath(batch, owner, path) - }) - // Skip the left boundary as it's not the first range - // Skip the right boundary if it's not the last range. - options = options.WithSkipBoundary(true, r.End() != common.MaxHash, boundaryStorageNodesGauge) + tr = newPathTrie(account, true, s.db, batch) } tasks = append(tasks, &storageTask{ Next: r.Start(), Last: r.End(), root: acc.Root, genBatch: batch, - genTrie: trie.NewStackTrie(options), + genTrie: tr, }) } for _, task := range tasks { @@ -2173,26 +2219,18 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { if i < len(res.hashes)-1 || res.subTask == nil { // no need to make local reassignment of account: this closure does not outlive the loop - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(batch, account, path, hash, blob, s.scheme) - }) + var tr genTrie + if s.scheme == rawdb.HashScheme { + tr = newHashTrie(batch) + } if s.scheme == rawdb.PathScheme { - // Configure the dangling node cleaner only in the context of the - // path scheme. Deletion is forbidden in the hash scheme, as it can - // disrupt state completeness. - // - // Notably, boundary nodes can be also kept because the whole storage - // trie is complete. - options = options.WithCleaner(func(path []byte) { - s.cleanPath(batch, account, path) - }) + // Keep the left boundary as it's complete + tr = newPathTrie(account, false, s.db, batch) } - tr := trie.NewStackTrie(options) for j := 0; j < len(res.hashes[i]); j++ { - tr.Update(res.hashes[i][j][:], res.slots[i][j]) + tr.update(res.hashes[i][j][:], res.slots[i][j]) } - tr.Commit() + tr.commit(true) } // Persist the received storage segments. These flat state maybe // outdated during the sync, but it can be fixed later during the @@ -2206,14 +2244,14 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { // If we're storing large contracts, generate the trie nodes // on the fly to not trash the gluing points if i == len(res.hashes)-1 && res.subTask != nil { - res.subTask.genTrie.Update(res.hashes[i][j][:], res.slots[i][j]) + res.subTask.genTrie.update(res.hashes[i][j][:], res.slots[i][j]) } } } // Large contracts could have generated new trie nodes, flush them to disk if res.subTask != nil { if res.subTask.done { - root := res.subTask.genTrie.Commit() + root := res.subTask.genTrie.commit(res.subTask.Last == common.MaxHash) if err := res.subTask.genBatch.Write(); err != nil { log.Error("Failed to persist stack slots", "err", err) } @@ -2222,7 +2260,7 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { // If the chunk's root is an overflown but full delivery, // clear the heal request. accountHash := res.accounts[len(res.accounts)-1] - if root == res.subTask.root && rawdb.HasStorageTrieNode(s.db.StateStoreReader(), accountHash, nil, root) { + if root == res.subTask.root && rawdb.HasTrieNode(s.db.StateStoreReader(), accountHash, nil, root, s.scheme) { for i, account := range res.mainTask.res.hashes { if account == accountHash { res.mainTask.needHeal[i] = false @@ -2230,8 +2268,8 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { } } } - } - if res.subTask.genBatch.ValueSize() > ethdb.IdealBatchSize { + } else if res.subTask.genBatch.ValueSize() > batchSizeThreshold { + res.subTask.genTrie.commit(false) if err := res.subTask.genBatch.Write(); err != nil { log.Error("Failed to persist stack slots", "err", err) } @@ -2354,7 +2392,7 @@ func (s *Syncer) commitHealer(force bool) { err = s.healer.scheduler.Commit(batch, nil) } if err != nil { - log.Error("Failed to commit healing data", "err", err) + log.Crit("Failed to commit healing data", "err", err) } if err := batch.Write(); err != nil { log.Crit("Failed to persist healing data", "err", err) @@ -2425,14 +2463,21 @@ func (s *Syncer) forwardAccountTask(task *accountTask) { slim := types.SlimAccountRLP(*res.accounts[i]) rawdb.WriteAccountSnapshot(batch, hash, slim) - // If the task is complete, drop it into the stack trie to generate - // account trie nodes for it if !task.needHeal[i] { + // If the storage task is complete, drop it into the stack trie + // to generate account trie nodes for it full, err := types.FullAccountRLP(slim) // TODO(karalabe): Slim parsing can be omitted if err != nil { panic(err) // Really shouldn't ever happen } - task.genTrie.Update(hash[:], full) + task.genTrie.update(hash[:], full) + } else { + // If the storage task is incomplete, explicitly delete the corresponding + // account item from the account trie to ensure that all nodes along the + // path to the incomplete storage trie are cleaned up. + if err := task.genTrie.delete(hash[:]); err != nil { + panic(err) // Really shouldn't ever happen + } } } // Flush anything written just now and update the stats @@ -2448,17 +2493,30 @@ func (s *Syncer) forwardAccountTask(task *accountTask) { return } task.Next = incHash(hash) + + // Remove the completion flag once the account range is pushed + // forward. The leftover accounts will be skipped in the next + // cycle. + delete(task.stateCompleted, hash) } // All accounts marked as complete, track if the entire task is done task.done = !res.cont + // Error out if there is any leftover completion flag. + if task.done && len(task.stateCompleted) != 0 { + panic(fmt.Errorf("storage completion flags should be emptied, %d left", len(task.stateCompleted))) + } // Stack trie could have generated trie nodes, push them to disk (we need to // flush after finalizing task.done. It's fine even if we crash and lose this // write as it will only cause more data to be downloaded during heal. if task.done { - task.genTrie.Commit() - } - if task.genBatch.ValueSize() > ethdb.IdealBatchSize || task.done { + task.genTrie.commit(task.Last == common.MaxHash) + if err := task.genBatch.Write(); err != nil { + log.Error("Failed to persist stack account", "err", err) + } + task.genBatch.Reset() + } else if task.genBatch.ValueSize() > batchSizeThreshold { + task.genTrie.commit(false) if err := task.genBatch.Write(); err != nil { log.Error("Failed to persist stack account", "err", err) } @@ -2640,7 +2698,7 @@ func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error // Cross reference the requested bytecodes with the response to find gaps // that the serving node is missing - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher := crypto.NewKeccakState() hash := make([]byte, 32) codes := make([][]byte, len(req.hashes)) @@ -2888,7 +2946,7 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error // Cross reference the requested trienodes with the response to find gaps // that the serving node is missing var ( - hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher = crypto.NewKeccakState() hash = make([]byte, 32) nodes = make([][]byte, len(req.hashes)) fills uint64 @@ -2994,7 +3052,7 @@ func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) e // Cross reference the requested bytecodes with the response to find gaps // that the serving node is missing - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher := crypto.NewKeccakState() hash := make([]byte, 32) codes := make([][]byte, len(req.hashes)) @@ -3238,9 +3296,9 @@ func (t *healRequestSort) Merge() []TrieNodePathSet { // sortByAccountPath takes hashes and paths, and sorts them. After that, it generates // the TrieNodePaths and merges paths which belongs to the same account path. func sortByAccountPath(paths []string, hashes []common.Hash) ([]string, []common.Hash, []trie.SyncPath, []TrieNodePathSet) { - var syncPaths []trie.SyncPath - for _, path := range paths { - syncPaths = append(syncPaths, trie.NewSyncPath([]byte(path))) + syncPaths := make([]trie.SyncPath, len(paths)) + for i, path := range paths { + syncPaths[i] = trie.NewSyncPath([]byte(path)) } n := &healRequestSort{paths, hashes, syncPaths} sort.Sort(n) diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index b780868b4e..c97c3b99b3 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -23,6 +23,7 @@ import ( "fmt" "math/big" mrand "math/rand" + "slices" "sync" "testing" "time" @@ -32,16 +33,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/testutil" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" "golang.org/x/crypto/sha3" - "golang.org/x/exp/slices" ) func TestHashing(t *testing.T) { @@ -64,7 +64,7 @@ func TestHashing(t *testing.T) { } } var new = func() { - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher := crypto.NewKeccakState() var hash = make([]byte, 32) for i := 0; i < len(bytecodes); i++ { hasher.Reset() @@ -96,7 +96,7 @@ func BenchmarkHashing(b *testing.B) { } } var new = func() { - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) + hasher := crypto.NewKeccakState() var hash = make([]byte, 32) for i := 0; i < len(bytecodes); i++ { hasher.Reset() @@ -286,10 +286,7 @@ func createAccountRequestResponse(t *testPeer, root common.Hash, origin common.H t.logger.Error("Could not prove last item", "error", err) } } - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } - return keys, vals, proofs + return keys, vals, proof.List() } // defaultStorageRequestHandler is a well-behaving storage request handler @@ -371,9 +368,7 @@ func createStorageRequestResponse(t *testPeer, root common.Hash, accounts []comm t.logger.Error("Could not prove last item", "error", err) } } - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } + proofs = append(proofs, proof.List()...) break } } @@ -430,9 +425,7 @@ func createStorageRequestResponseAlwaysProve(t *testPeer, root common.Hash, acco t.logger.Error("Could not prove last item", "error", err) } } - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } + proofs = append(proofs, proof.List()...) break } } @@ -586,9 +579,8 @@ func testSyncBloatedProof(t *testing.T, scheme string) { source.accountRequestHandler = func(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error { var ( - proofs [][]byte - keys []common.Hash - vals [][]byte + keys []common.Hash + vals [][]byte ) // The values for _, entry := range t.accountValues { @@ -618,10 +610,7 @@ func testSyncBloatedProof(t *testing.T, scheme string) { keys = append(keys[:1], keys[2:]...) vals = append(vals[:1], vals[2:]...) } - for _, blob := range proof.List() { - proofs = append(proofs, blob) - } - if err := t.remote.OnAccounts(t, requestId, keys, vals, proofs); err != nil { + if err := t.remote.OnAccounts(t, requestId, keys, vals, proof.List()); err != nil { t.logger.Info("remote error on delivery (as expected)", "error", err) t.term() // This is actually correct, signal to exit the test successfully @@ -839,7 +828,7 @@ func testMultiSyncManyUseless(t *testing.T, scheme string) { verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t) } -// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all +// TestMultiSyncManyUselessWithLowTimeout contains one good peer, and many which doesn't return anything valuable at all func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) { t.Parallel() @@ -1378,7 +1367,7 @@ func testSyncWithStorageAndNonProvingPeer(t *testing.T, scheme string) { verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t) } -// TestSyncWithStorage tests basic sync using accounts + storage + code, against +// TestSyncWithStorageMisbehavingProve tests basic sync using accounts + storage + code, against // a peer who insists on delivering full storage sets _and_ proofs. This triggered // an error, where the recipient erroneously clipped the boundary nodes, but // did not mark the account for healing. @@ -1502,7 +1491,7 @@ func getCodeByHash(hash common.Hash) []byte { return nil } -// makeAccountTrieNoStorage spits out a trie, along with the leafs +// makeAccountTrieNoStorage spits out a trie, along with the leaves func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv) { var ( db = triedb.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme)) @@ -1525,7 +1514,7 @@ func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv) // Commit the state changes into db and re-create the trie // for accessing later. - root, nodes, _ := accTrie.Commit(false) + root, nodes := accTrie.Commit(false) db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil) accTrie, _ = trie.New(trie.StateTrieID(root), db) @@ -1587,7 +1576,7 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) { // Commit the state changes into db and re-create the trie // for accessing later. - root, nodes, _ := accTrie.Commit(false) + root, nodes := accTrie.Commit(false) db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil) accTrie, _ = trie.New(trie.StateTrieID(root), db) @@ -1633,7 +1622,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots slices.SortFunc(entries, (*kv).cmp) // Commit account trie - root, set, _ := accTrie.Commit(true) + root, set := accTrie.Commit(true) nodes.Merge(set) // Commit gathered dirty nodes into database @@ -1650,7 +1639,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots return db.Scheme(), accTrie, entries, storageTries, storageEntries } -// makeAccountTrieWithStorage spits out a trie, along with the leafs +// makeAccountTrieWithStorage spits out a trie, along with the leaves func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, boundary bool, uneven bool) (*trie.Trie, []*kv, map[common.Hash]*trie.Trie, map[common.Hash][]*kv) { var ( db = triedb.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme)) @@ -1700,7 +1689,7 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda slices.SortFunc(entries, (*kv).cmp) // Commit account trie - root, set, _ := accTrie.Commit(true) + root, set := accTrie.Commit(true) nodes.Merge(set) // Commit gathered dirty nodes into database @@ -1742,7 +1731,7 @@ func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *triedb.Datab entries = append(entries, elem) } slices.SortFunc(entries, (*kv).cmp) - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) return root, nodes, entries } @@ -1793,7 +1782,7 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *triedb.Database) (com entries = append(entries, elem) } slices.SortFunc(entries, (*kv).cmp) - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) return root, nodes, entries } @@ -1816,8 +1805,8 @@ func makeUnevenStorageTrie(owner common.Hash, slots int, db *triedb.Database) (c break } for j := 0; j < slots/3; j++ { - key := append([]byte{byte(n)}, testutil.RandBytes(31)...) - val, _ := rlp.EncodeToBytes(testutil.RandBytes(32)) + key := append([]byte{byte(n)}, testrand.Bytes(31)...) + val, _ := rlp.EncodeToBytes(testrand.Bytes(32)) elem := &kv{key, val} tr.MustUpdate(elem.k, elem.v) @@ -1825,7 +1814,7 @@ func makeUnevenStorageTrie(owner common.Hash, slots int, db *triedb.Database) (c } } slices.SortFunc(entries, (*kv).cmp) - root, nodes, _ := tr.Commit(false) + root, nodes := tr.Commit(false) return root, nodes, entries } @@ -1873,8 +1862,9 @@ func verifyTrie(scheme string, db ethdb.KeyValueStore, root common.Hash, t *test // TestSyncAccountPerformance tests how efficient the snap algo is at minimizing // state healing func TestSyncAccountPerformance(t *testing.T) { - t.Parallel() - + // These tests must not run in parallel: they modify the + // global var accountConcurrency + // t.Parallel() testSyncAccountPerformance(t, rawdb.HashScheme) testSyncAccountPerformance(t, rawdb.PathScheme) } diff --git a/eth/protocols/trust/handler.go b/eth/protocols/trust/handler.go index 6f214a8a50..5d27d78d75 100644 --- a/eth/protocols/trust/handler.go +++ b/eth/protocols/trust/handler.go @@ -31,13 +31,7 @@ type Backend interface { } // MakeProtocols constructs the P2P protocol definitions for `trust`. -func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { - // Filter the discovery iterator for nodes advertising trust support. - dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool { - var trust enrEntry - return n.Load(&trust) == nil - }) - +func MakeProtocols(backend Backend) []p2p.Protocol { protocols := make([]p2p.Protocol, len(ProtocolVersions)) for i, version := range ProtocolVersions { version := version // Closure @@ -58,8 +52,7 @@ func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { PeerInfo: func(id enode.ID) interface{} { return backend.PeerInfo(id) }, - Attributes: []enr.Entry{&enrEntry{}}, - DialCandidates: dnsdisc, + Attributes: []enr.Entry{&enrEntry{}}, } } return protocols diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 946b292926..43396867a9 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/systemcontracts" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -71,8 +72,9 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u // the internal junks created by tracing will be persisted into the disk. // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. - database = state.NewDatabaseWithConfig(eth.chainDb, triedb.HashDefaults) - if statedb, err = state.New(block.Root(), database, nil); err == nil { + tdb := triedb.NewDatabase(eth.chainDb, triedb.HashDefaults) + database = state.NewDatabase(tdb, nil) + if statedb, err = state.New(block.Root(), database); err == nil { log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number()) return statedb, noopReleaser, nil } @@ -92,13 +94,13 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults) - database = state.NewDatabaseWithNodeDB(eth.chainDb, tdb) + database = state.NewDatabase(tdb, nil) // If we didn't check the live database, do check state over ephemeral database, // otherwise we would rewind past a persisted block (specific corner case is // chain tracing from the genesis). if !readOnly { - statedb, err = state.New(current.Root(), database, nil) + statedb, err = state.New(current.Root(), database) if err == nil { return statedb, noopReleaser, nil } @@ -117,7 +119,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u } current = parent - statedb, err = state.New(current.Root(), database, nil) + statedb, err = state.New(current.Root(), database) if err == nil { break } @@ -152,19 +154,17 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u if current = eth.blockchain.GetBlockByNumber(next); current == nil { return nil, nil, fmt.Errorf("block #%d not found", next) } - statedb, _, _, _, err := eth.blockchain.Processor().Process(current, statedb, vm.Config{}) + _, err := eth.blockchain.Processor().Process(current, statedb, vm.Config{}) if err != nil { return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err) } // Finalize the state so any modifications are written to the trie - statedb.Finalise(eth.blockchain.Config().IsEIP158(current.Number())) - statedb.AccountsIntermediateRoot() - root, _, err := statedb.Commit(current.NumberU64(), nil) + root, _, err := statedb.Commit(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number())) if err != nil { return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w", current.NumberU64(), current.Root().Hex(), err) } - statedb, err = state.New(root, database, nil) // nolint:staticcheck + statedb, err = state.New(root, database) if err != nil { return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err) } @@ -225,7 +225,7 @@ func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexe } // stateAtTransaction returns the execution environment of a certain transaction. -func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { +func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { // Short circuit if it's genesis block. if block.NumberU64() == 0 { return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis") @@ -245,6 +245,18 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, if !eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) { systemcontracts.UpgradeBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb) } + // Insert parent beacon block root in the state as per EIP-4788. + if beaconRoot := block.BeaconRoot(); beaconRoot != nil { + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, eth.blockchain.Config(), vm.Config{}) + core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) + } + // If prague hardfork, insert parent block hash in the state as per EIP-2935. + if eth.blockchain.Config().IsPrague(block.Number(), block.Time()) { + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, eth.blockchain.Config(), vm.Config{}) + core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb) + } if txIndex == 0 && len(block.Transactions()) == 0 { return nil, vm.BlockContext{}, statedb, release, nil } @@ -260,8 +272,8 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(block.Header().Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified) } if eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) { @@ -277,7 +289,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) if idx == txIndex { - return msg, context, statedb, release, nil + return tx, context, statedb, release, nil } // Not yet the searched for transaction, execute on top of the current state vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{}) diff --git a/eth/sync.go b/eth/sync.go index db0ec62617..e887f86df7 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -142,17 +142,6 @@ func (cs *chainSyncer) nextSyncOp() *chainSyncOp { if cs.doneCh != nil { return nil // Sync already running } - // If a beacon client once took over control, disable the entire legacy sync - // path from here on end. Note, there is a slight "race" between reaching TTD - // and the beacon client taking over. The downloader will enforce that nothing - // above the first TTD will be delivered to the chain for import. - // - // An alternative would be to check the local chain for exceeding the TTD and - // avoid triggering a sync in that case, but that could also miss sibling or - // other family TTD block being accepted. - if cs.handler.chain.Config().TerminalTotalDifficultyPassed || cs.handler.merger.TDDReached() { - return nil - } // Ensure we're at minimum peer count. minPeers := defaultMinSyncPeers if cs.forced { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index f18a8536c2..27e357b916 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "math/big" "os" "runtime" "sync" @@ -35,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/systemcontracts" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/logger" @@ -89,7 +91,7 @@ type Backend interface { Engine() consensus.Engine ChainDb() ethdb.Database StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) - StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) + StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) } // API is the collection of tracing APIs exposed over the private debugging endpoint. @@ -231,7 +233,7 @@ func (api *API) TraceChain(ctx context.Context, start, end rpc.BlockNumber, conf } sub := notifier.CreateSubscription() - resCh := api.traceChain(from, to, config, notifier.Closed()) + resCh := api.traceChain(from, to, config, sub.Err()) go func() { for result := range resCh { notifier.Notify(sub.ID, result) @@ -245,7 +247,7 @@ func (api *API) TraceChain(ctx context.Context, start, end rpc.BlockNumber, conf // the end block but excludes the start one. The return value will be one item per // transaction, dependent on the requested tracer. // The tracing procedure should be aborted in case the closed signal is received. -func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed <-chan interface{}) chan *blockTraceResult { +func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed <-chan error) chan *blockTraceResult { reexec := defaultTraceReexec if config != nil && config.Reexec != nil { reexec = *config.Reexec @@ -282,8 +284,8 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed if isSystem, _ := posa.IsSystemTransaction(tx, task.block.Header()); isSystem { balance := task.statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - task.statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - task.statedb.AddBalance(blockCtx.Coinbase, balance) + task.statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + task.statedb.AddBalance(blockCtx.Coinbase, balance, tracing.BalanceChangeUnspecified) } if api.backend.ChainConfig().IsFeynman(task.block.Number(), task.block.Time()) { @@ -301,14 +303,12 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed TxIndex: i, TxHash: tx.Hash(), } - res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config, !beforeSystemTx) + res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, task.statedb, config, !beforeSystemTx) if err != nil { task.results[i] = &txTraceResult{TxHash: tx.Hash(), Error: err.Error()} log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err) break } - // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect - task.statedb.Finalise(api.backend.ChainConfig().IsEIP158(task.block.Number())) task.results[i] = &txTraceResult{TxHash: tx.Hash(), Result: res} } // Tracing state is used up, queue it for de-referencing. Note the @@ -402,6 +402,19 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed failed = err break } + // Insert block's parent beacon block root in the state + // as per EIP-4788. + if beaconRoot := next.BeaconRoot(); beaconRoot != nil { + context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) + core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) + } + // Insert parent hash in history contract. + if api.backend.ChainConfig().IsPrague(next.Number(), next.Time()) { + context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) + core.ProcessParentBlockHash(next.ParentHash(), vmenv, statedb) + } // Clean out any pending release functions of trace state. Note this // step must be done after constructing tracing state, because the // tracing state of block next depends on the parent state and construction @@ -562,6 +575,13 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) beforeSystemTx = true ) + if beaconRoot := block.BeaconRoot(); beaconRoot != nil { + vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) + } + if chainConfig.IsPrague(block.Number(), block.Time()) { + core.ProcessParentBlockHash(block.ParentHash(), vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{}), statedb) + } for i, tx := range block.Transactions() { if err := ctx.Err(); err != nil { return nil, err @@ -576,8 +596,8 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(vmctx.Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(vmctx.Coinbase, balance, tracing.BalanceChangeUnspecified) } if beforeSystemTx && api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) { @@ -658,12 +678,19 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac var ( txs = block.Transactions() blockHash = block.Hash() - is158 = api.backend.ChainConfig().IsEIP158(block.Number()) blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) results = make([]*txTraceResult, len(txs)) beforeSystemTx = true ) + if beaconRoot := block.BeaconRoot(); beaconRoot != nil { + vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) + core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) + } + if api.backend.ChainConfig().IsPrague(block.Number(), block.Time()) { + vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) + core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb) + } for i, tx := range txs { // upgrade build-in system contract before system txs if Feynman is enabled if beforeSystemTx { @@ -671,8 +698,8 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(blockCtx.Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(blockCtx.Coinbase, balance, tracing.BalanceChangeUnspecified) } if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) { @@ -691,14 +718,11 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac TxIndex: i, TxHash: tx.Hash(), } - res, err := api.traceTx(ctx, msg, txctx, blockCtx, statedb, config, !beforeSystemTx) + res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, statedb, config, !beforeSystemTx) if err != nil { return nil, err } results[i] = &txTraceResult{TxHash: tx.Hash(), Result: res} - // Finalize the state so any modifications are written to the trie - // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect - statedb.Finalise(is158) } return results, nil } @@ -711,7 +735,6 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat var ( txs = block.Transactions() blockHash = block.Hash() - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) results = make([]*txTraceResult, len(txs)) pend sync.WaitGroup @@ -724,7 +747,6 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat for th := 0; th < threads; th++ { pend.Add(1) gopool.Submit(func() { - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) defer pend.Done() // Fetch and execute the next transaction trace tasks for task := range jobs { @@ -735,7 +757,12 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat TxIndex: task.index, TxHash: txs[task.index].Hash(), } - res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config, task.isSystemTx) + // Reconstruct the block context for each transaction + // as the GetHash function of BlockContext is not safe for + // concurrent use. + // See: https://github.com/ethereum/go-ethereum/issues/29114 + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config, task.isSystemTx) if err != nil { results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()} continue @@ -755,6 +782,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat failed error beforeSystemTx = true ) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) txloop: for i, tx := range txs { // upgrade build-in system contract before system txs if Feynman is enabled @@ -763,8 +791,8 @@ txloop: if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(block.Header().Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified) } if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) { @@ -868,7 +896,14 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Note: This copies the config, to not screw up the main config chainConfig, canon = overrideConfig(chainConfig, config.Overrides) } - + if beaconRoot := block.BeaconRoot(); beaconRoot != nil { + vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) + } + if chainConfig.IsPrague(block.Number(), block.Time()) { + vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb) + } for i, tx := range block.Transactions() { // upgrade build-in system contract before system txs if Feynman is enabled if beforeSystemTx { @@ -876,8 +911,8 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(vmctx.Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(vmctx.Coinbase, balance, tracing.BalanceChangeUnspecified) } if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) { @@ -920,7 +955,13 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Execute the transaction and flush any traces to disk vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf) statedb.SetTxContext(tx.Hash(), i) - _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)) + if vmConf.Tracer.OnTxStart != nil { + vmConf.Tracer.OnTxStart(vmenv.GetVMContext(), tx, msg.From) + } + vmRet, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)) + if vmConf.Tracer.OnTxEnd != nil { + vmConf.Tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, err) + } if writer != nil { writer.Flush() } @@ -977,11 +1018,15 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * if err != nil { return nil, err } - msg, vmctx, statedb, release, err := api.backend.StateAtTransaction(ctx, block, int(index), reexec) + tx, vmctx, statedb, release, err := api.backend.StateAtTransaction(ctx, block, int(index), reexec) if err != nil { return nil, err } defer release() + msg, err := core.TransactionToMessage(tx, types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()), block.BaseFee()) + if err != nil { + return nil, err + } var isSystemTx bool if posa, ok := api.backend.Engine().(consensus.PoSA); ok { @@ -996,7 +1041,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * TxIndex: int(index), TxHash: hash, } - return api.traceTx(ctx, msg, txctx, vmctx, statedb, config, isSystemTx) + return api.traceTx(ctx, tx, msg, txctx, vmctx, statedb, config, isSystemTx) } // TraceCall lets you trace a given eth_call. It collects the structured logs @@ -1062,46 +1107,67 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) // Apply the customization rules if required. if config != nil { - if err := config.StateOverrides.Apply(statedb); err != nil { + config.BlockOverrides.Apply(&vmctx) + rules := api.backend.ChainConfig().Rules(vmctx.BlockNumber, vmctx.Random != nil, vmctx.Time) + + precompiles := vm.ActivePrecompiledContracts(rules) + if err := config.StateOverrides.Apply(statedb, precompiles); err != nil { return nil, err } - config.BlockOverrides.Apply(&vmctx) } // Execute the trace - msg, err := args.ToMessage(api.backend.RPCGasCap(), vmctx.BaseFee) - if err != nil { + if err := args.CallDefaults(api.backend.RPCGasCap(), vmctx.BaseFee, api.backend.ChainConfig().ChainID); err != nil { return nil, err } - - var traceConfig *TraceConfig + var ( + msg = args.ToMessage(vmctx.BaseFee, true, true) + tx = args.ToTransaction(types.LegacyTxType) + traceConfig *TraceConfig + ) + // Lower the basefee to 0 to avoid breaking EVM + // invariants (basefee < feecap). + if msg.GasPrice.Sign() == 0 { + vmctx.BaseFee = new(big.Int) + } + if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 { + vmctx.BlobBaseFee = new(big.Int) + } if config != nil { traceConfig = &config.TraceConfig } - return api.traceTx(ctx, msg, new(Context), vmctx, statedb, traceConfig, false) + return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig, false) } // traceTx configures a new tracer according to the provided configuration, and // executes the given message in the provided environment. The return value will // be tracer dependent. -func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig, isSystemTx bool) (interface{}, error) { +func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig, isSystemTx bool) (interface{}, error) { var ( - tracer Tracer - err error - timeout = defaultTraceTimeout - txContext = core.NewEVMTxContext(message) + tracer *Tracer + err error + timeout = defaultTraceTimeout + usedGas uint64 ) if config == nil { config = &TraceConfig{} } // Default tracer is the struct logger - tracer = logger.NewStructLogger(config.Config) - if config.Tracer != nil { + if config.Tracer == nil { + logger := logger.NewStructLogger(config.Config) + tracer = &Tracer{ + Hooks: logger.Hooks(), + GetResult: logger.GetResult, + Stop: logger.Stop, + } + } else { tracer, err = DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig) if err != nil { return nil, err } } - vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer, NoBaseFee: true}) + // The actual TxContext will be created as part of ApplyTransactionWithEVM. + vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap}, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true}) + statedb.SetLogger(tracer.Hooks) // Define a meaningful timeout of a single transaction trace if config.Timeout != nil { @@ -1128,7 +1194,8 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte // Call Prepare to clear out the statedb access list statedb.SetTxContext(txctx.TxHash, txctx.TxIndex) - if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit)); err != nil { + _, err = core.ApplyTransactionWithEVM(message, api.backend.ChainConfig(), new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, vmenv) + if err != nil { return nil, fmt.Errorf("tracing failed: %w", err) } tracer.CaptureSystemTxEnd(intrinsicGas) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index cd07b0638b..e1507ef375 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -24,6 +24,7 @@ import ( "fmt" "math/big" "reflect" + "slices" "sync/atomic" "testing" "time" @@ -31,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" @@ -43,7 +45,6 @@ import ( "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "golang.org/x/exp/slices" ) var ( @@ -61,7 +62,7 @@ type testBackend struct { relHook func() // Hook is invoked when the requested state is released } -// testBackend creates a new test backend. OBS: After test is done, teardown must be +// newTestBackend creates a new test backend. OBS: After test is done, teardown must be // invoked in order to release associated resources. func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend { backend := &testBackend{ @@ -156,7 +157,7 @@ func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reex return statedb, release, nil } -func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) { +func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) { parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { return nil, vm.BlockContext{}, nil, nil, errBlockNotFound @@ -175,7 +176,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), b.chain, nil) if idx == txIndex { - return msg, context, statedb, release, nil + return tx, context, statedb, release, nil } vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { @@ -312,7 +313,7 @@ func TestTraceCall(t *testing.T) { config: &TraceCallConfig{TxIndex: uintPtr(1)}, expectErr: fmt.Errorf("tracing failed: insufficient funds for gas * price + value: address %s have 1000000000000000000 want 1000000000000000100", accounts[2].addr), }, - // After the target transaction, should be succeed + // After the target transaction, should be succeeded { blockNumber: rpc.BlockNumber(genBlocks - 1), call: ethapi.TransactionArgs{ @@ -667,7 +668,6 @@ func TestTracingWithOverrides(t *testing.T) { From: &accounts[0].addr, // BLOCKNUMBER PUSH1 MSTORE Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")), - // &hexutil.Bytes{0x43}, // blocknumber }, config: &TraceCallConfig{ BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))}, @@ -844,7 +844,7 @@ func TestTracingWithOverrides(t *testing.T) { byte(vm.PUSH1), 00, byte(vm.RETURN), }), - StateDiff: &map[common.Hash]common.Hash{ + StateDiff: map[common.Hash]common.Hash{ common.HexToHash("0x03"): common.HexToHash("0x11"), }, }, @@ -899,9 +899,9 @@ func newAccounts(n int) (accounts []Account) { return accounts } -func newRPCBalance(balance *big.Int) **hexutil.Big { +func newRPCBalance(balance *big.Int) *hexutil.Big { rpcBalance := (*hexutil.Big)(balance) - return &rpcBalance + return rpcBalance } func newRPCBytes(bytes []byte) *hexutil.Bytes { @@ -909,7 +909,7 @@ func newRPCBytes(bytes []byte) *hexutil.Bytes { return &rpcBytes } -func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.Hash { +func newStates(keys []common.Hash, vals []common.Hash) map[common.Hash]common.Hash { if len(keys) != len(vals) { panic("invalid input") } @@ -917,7 +917,7 @@ func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.H for i := 0; i < len(keys); i++ { m[keys[i]] = vals[i] } - return &m + return m } func TestTraceChain(t *testing.T) { @@ -996,3 +996,90 @@ func TestTraceChain(t *testing.T) { } } } + +// newTestMergedBackend creates a post-merge chain +func newTestMergedBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend { + backend := &testBackend{ + chainConfig: gspec.Config, + engine: beacon.NewFaker(), + chaindb: rawdb.NewMemoryDatabase(), + } + // Generate blocks for testing + _, blocks, _ := core.GenerateChainWithGenesis(gspec, backend.engine, n, generator) + + // Import the canonical chain + cacheConfig := &core.CacheConfig{ + TrieCleanLimit: 256, + TrieDirtyLimit: 256, + TrieTimeLimit: 5 * time.Minute, + SnapshotLimit: 0, + TrieDirtyDisabled: true, // Archive mode + } + chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, gspec, nil, backend.engine, vm.Config{}, nil, nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + backend.chain = chain + return backend +} + +func TestTraceBlockWithBasefee(t *testing.T) { + t.Parallel() + accounts := newAccounts(1) + target := common.HexToAddress("0x1111111111111111111111111111111111111111") + genesis := &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(1 * params.Ether)}, + target: {Nonce: 1, Code: []byte{ + byte(vm.BASEFEE), byte(vm.STOP), + }}, + }, + } + genBlocks := 1 + signer := types.HomesteadSigner{} + var txHash common.Hash + var baseFee = new(big.Int) + backend := newTestMergedBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) { + tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: uint64(i), + To: &target, + Value: big.NewInt(0), + Gas: 5 * params.TxGas, + GasPrice: b.BaseFee(), + Data: nil}), + signer, accounts[0].key) + b.AddTx(tx) + txHash = tx.Hash() + baseFee.Set(b.BaseFee()) + }) + defer backend.chain.Stop() + api := NewAPI(backend) + + var testSuite = []struct { + blockNumber rpc.BlockNumber + config *TraceConfig + want string + }{ + // Trace head block + { + blockNumber: rpc.BlockNumber(genBlocks), + want: fmt.Sprintf(`[{"txHash":"%#x","result":{"gas":21002,"failed":false,"returnValue":"","structLogs":[{"pc":0,"op":"BASEFEE","gas":84000,"gasCost":2,"depth":1,"stack":[]},{"pc":1,"op":"STOP","gas":83998,"gasCost":0,"depth":1,"stack":["%#x"]}]}}]`, txHash, baseFee), + }, + } + for i, tc := range testSuite { + result, err := api.TraceBlockByNumber(context.Background(), tc.blockNumber, tc.config) + if err != nil { + t.Errorf("test %d, want no error, have %v", i, err) + continue + } + have, _ := json.Marshal(result) + want := tc.want + if string(have) != want { + t.Errorf("test %d, result mismatch\nhave: %v\nwant: %v\n", i, string(have), want) + } + } +} diff --git a/eth/tracers/tracers.go b/eth/tracers/dir.go similarity index 71% rename from eth/tracers/tracers.go rename to eth/tracers/dir.go index 7b43b7cf83..92ed662d8b 100644 --- a/eth/tracers/tracers.go +++ b/eth/tracers/dir.go @@ -14,17 +14,14 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package tracers is a manager for transaction tracing engines. package tracers import ( "encoding/json" - "errors" - "fmt" "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/tracing" ) // Context contains some contextual infos for a transaction execution that is not @@ -36,17 +33,20 @@ type Context struct { TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) } -// Tracer interface extends vm.EVMLogger and additionally -// allows collecting the tracing result. -type Tracer interface { - vm.EVMLogger - GetResult() (json.RawMessage, error) +// The set of methods that must be exposed by a tracer +// for it to be available through the RPC interface. +// This involves a method to retrieve results and one to +// stop tracing. +type Tracer struct { + *tracing.Hooks + GetResult func() (json.RawMessage, error) + CaptureSystemTxEnd func(intrinsicGas uint64) // Stop terminates execution of the tracer at the first opportune moment. - Stop(err error) + Stop func(err error) } -type ctorFn func(*Context, json.RawMessage) (Tracer, error) -type jsCtorFn func(string, *Context, json.RawMessage) (Tracer, error) +type ctorFn func(*Context, json.RawMessage) (*Tracer, error) +type jsCtorFn func(string, *Context, json.RawMessage) (*Tracer, error) type elem struct { ctor ctorFn @@ -79,7 +79,7 @@ func (d *directory) RegisterJSEval(f jsCtorFn) { // New returns a new instance of a tracer, by iterating through the // registered lookups. Name is either name of an existing tracer // or an arbitrary JS code. -func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (Tracer, error) { +func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (*Tracer, error) { if elem, ok := d.elems[name]; ok { return elem.ctor(ctx, cfg) } @@ -97,27 +97,3 @@ func (d *directory) IsJS(name string) bool { // JS eval will execute JS code return true } - -const ( - memoryPadLimit = 1024 * 1024 -) - -// GetMemoryCopyPadded returns offset + size as a new slice. -// It zero-pads the slice if it extends beyond memory bounds. -func GetMemoryCopyPadded(m *vm.Memory, offset, size int64) ([]byte, error) { - if offset < 0 || size < 0 { - return nil, errors.New("offset or size must not be negative") - } - if int(offset+size) < m.Len() { // slice fully inside memory - return m.GetCopy(offset, size), nil - } - paddingNeeded := int(offset+size) - m.Len() - if paddingNeeded > memoryPadLimit { - return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded) - } - cpy := make([]byte, size) - if overlap := int64(m.Len()) - offset; overlap > 0 { - copy(cpy, m.GetPtr(offset, overlap)) - } - return cpy, nil -} diff --git a/eth/tracers/internal/tracetest/README.md b/eth/tracers/internal/tracetest/README.md new file mode 100644 index 0000000000..8c3d5d275f --- /dev/null +++ b/eth/tracers/internal/tracetest/README.md @@ -0,0 +1,10 @@ +# Filling test cases + +To fill test cases for the built-in tracers, the `makeTest.js` script can be used. Given a transaction on a dev/test network, `makeTest.js` will fetch its prestate and then traces with the given configuration. +In the Geth console do: + +```terminal +let tx = '0x...' +loadScript('makeTest.js') +makeTest(tx, { tracer: 'callTracer' }) +``` \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 6216a16ced..31b2ef6d16 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -18,6 +18,7 @@ package tracetest import ( "encoding/json" + "fmt" "math/big" "os" "path/filepath" @@ -26,25 +27,17 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" ) -type callContext struct { - Number math.HexOrDecimal64 `json:"number"` - Difficulty *math.HexOrDecimal256 `json:"difficulty"` - Time math.HexOrDecimal64 `json:"timestamp"` - GasLimit math.HexOrDecimal64 `json:"gasLimit"` - Miner common.Address `json:"miner"` -} - // callLog is the result of LOG opCode type callLog struct { Address common.Address `json:"address"` @@ -123,17 +116,8 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { // Configure a blockchain with the given prestate var ( signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: test.Genesis.BaseFee, - } - state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) + context = test.Context.toBlockContext(test.Genesis) + state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) state.Close() @@ -141,15 +125,19 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { if err != nil { t.Fatalf("failed to create call tracer: %v", err) } + + state.StateDB.SetLogger(tracer.Hooks) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) + evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) + tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { t.Fatalf("failed to execute transaction: %v", err) } + tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, nil) // Retrieve the trace result and compare against the expected. res, err := tracer.GetResult() if err != nil { @@ -245,7 +233,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { if err != nil { b.Fatalf("failed to create call tracer: %v", err) } - evm := vm.NewEVM(context, txContext, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) + evm := vm.NewEVM(context, txContext, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) snap := state.StateDB.Snapshot() st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if _, err = st.TransitionDb(); err != nil { @@ -260,13 +248,13 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { func TestInternals(t *testing.T) { var ( + config = params.MainnetChainConfig to = common.HexToAddress("0x00000000000000000000000000000000deadbeef") - origin = common.HexToAddress("0x00000000000000000000000000000000feed") - txContext = vm.TxContext{ - Origin: origin, - GasPrice: big.NewInt(1), - } - context = vm.BlockContext{ + originHex = "0x71562b71999873db5b286df957af199ec94617f7" + origin = common.HexToAddress(originHex) + signer = types.LatestSigner(config) + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + context = vm.BlockContext{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, Coinbase: common.Address{}, @@ -274,9 +262,10 @@ func TestInternals(t *testing.T) { Time: 5, Difficulty: big.NewInt(0x30000), GasLimit: uint64(6000000), + BaseFee: new(big.Int), } ) - mkTracer := func(name string, cfg json.RawMessage) tracers.Tracer { + mkTracer := func(name string, cfg json.RawMessage) *tracers.Tracer { tr, err := tracers.DefaultDirectory.New(name, nil, cfg) if err != nil { t.Fatalf("failed to create call tracer: %v", err) @@ -287,7 +276,7 @@ func TestInternals(t *testing.T) { for _, tc := range []struct { name string code []byte - tracer tracers.Tracer + tracer *tracers.Tracer want string }{ { @@ -301,13 +290,13 @@ func TestInternals(t *testing.T) { byte(vm.CALL), }, tracer: mkTracer("callTracer", nil), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0xe01a","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}`, + want: fmt.Sprintf(`{"from":"%s","gas":"0x13880","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0xe01a","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}`, originHex), }, { name: "Stack depletion in LOG0", code: []byte{byte(vm.LOG3)}, tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x13880","to":"0x00000000000000000000000000000000deadbeef","input":"0x","error":"stack underflow (0 \u003c=\u003e 5)","value":"0x0","type":"CALL"}`, + want: fmt.Sprintf(`{"from":"%s","gas":"0x13880","gasUsed":"0x13880","to":"0x00000000000000000000000000000000deadbeef","input":"0x","error":"stack underflow (0 \u003c=\u003e 5)","value":"0x0","type":"CALL"}`, originHex), }, { name: "Mem expansion in LOG0", @@ -320,7 +309,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","position":"0x0"}],"value":"0x0","type":"CALL"}`, + want: fmt.Sprintf(`{"from":"%s","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","position":"0x0"}],"value":"0x0","type":"CALL"}`, originHex), }, { // Leads to OOM on the prestate tracer @@ -339,7 +328,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, tracer: mkTracer("prestateTracer", nil), - want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"}}`, + want: fmt.Sprintf(`{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), }, { // CREATE2 which requires padding memory by prestate tracer @@ -358,7 +347,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, tracer: mkTracer("prestateTracer", nil), - want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"0x91ff9a805d36f54e3e272e230f3e3f5c1b330804":{"balance":"0x0"}}`, + want: fmt.Sprintf(`{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), }, } { t.Run(tc.name, func(t *testing.T) { @@ -372,22 +361,31 @@ func TestInternals(t *testing.T) { }, }, false, rawdb.HashScheme) defer state.Close() - - evm := vm.NewEVM(context, txContext, state.StateDB, params.MainnetChainConfig, vm.Config{Tracer: tc.tracer}) - msg := &core.Message{ - To: &to, - From: origin, - Value: big.NewInt(0), - GasLimit: 80000, - GasPrice: big.NewInt(0), - GasFeeCap: big.NewInt(0), - GasTipCap: big.NewInt(0), - SkipAccountChecks: false, + state.StateDB.SetLogger(tc.tracer.Hooks) + tx, err := types.SignNewTx(key, signer, &types.LegacyTx{ + To: &to, + Value: big.NewInt(0), + Gas: 80000, + GasPrice: big.NewInt(1), + }) + if err != nil { + t.Fatalf("test %v: failed to sign transaction: %v", tc.name, err) } - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)) - if _, err := st.TransitionDb(); err != nil { + txContext := vm.TxContext{ + Origin: origin, + GasPrice: tx.GasPrice(), + } + evm := vm.NewEVM(context, txContext, state.StateDB, config, vm.Config{Tracer: tc.tracer.Hooks}) + msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0)) + if err != nil { + t.Fatalf("test %v: failed to create message: %v", tc.name, err) + } + tc.tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) + if err != nil { t.Fatalf("test %v: failed to execute transaction: %v", tc.name, err) } + tc.tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, nil) // Retrieve the trace result and compare against the expected res, err := tc.tracer.GetResult() if err != nil { diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index abee488917..ec7a944b91 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -16,11 +16,9 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" - - // Force-load the native, to trigger registration - "github.com/ethereum/go-ethereum/eth/tracers" ) // flatCallTrace is the result of a callTracerParity run. @@ -63,8 +61,8 @@ type flatCallTraceResult struct { // flatCallTracerTest defines a single test to check the call tracer against. type flatCallTracerTest struct { - Genesis core.Genesis `json:"genesis"` - Context callContext `json:"context"` + Genesis *core.Genesis `json:"genesis"` + Context *callContext `json:"context"` Input string `json:"input"` TracerConfig json.RawMessage `json:"tracerConfig"` Result []flatCallTrace `json:"result"` @@ -86,15 +84,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string return fmt.Errorf("failed to parse testcase input: %v", err) } signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - } + context := test.Context.toBlockContext(test.Genesis) state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) defer state.Close() @@ -103,16 +93,19 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string if err != nil { return fmt.Errorf("failed to create call tracer: %v", err) } + + state.StateDB.SetLogger(tracer.Hooks) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) if err != nil { return fmt.Errorf("failed to prepare transaction for tracing: %v", err) } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - - if _, err = st.TransitionDb(); err != nil { + evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) + tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) + if err != nil { return fmt.Errorf("failed to execute transaction: %v", err) } + tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, nil) // Retrieve the trace result and compare against the etalon res, err := tracer.GetResult() @@ -124,7 +117,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string return fmt.Errorf("failed to unmarshal trace result: %v", err) } if !jsonEqualFlat(ret, test.Result) { - t.Logf("tracer name: %s", tracerName) + t.Logf("test %s failed", filename) // uncomment this for easier debugging // have, _ := json.MarshalIndent(ret, "", " ") @@ -170,7 +163,7 @@ func testFlatCallTracer(tracerName string, dirPath string, t *testing.T) { } } -// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to +// jsonEqualFlat is similar to reflect.DeepEqual, but does a 'bounce' via json prior to // comparison func jsonEqualFlat(x, y interface{}) bool { xTrace := new([]flatCallTrace) diff --git a/eth/tracers/internal/tracetest/makeTest.js b/eth/tracers/internal/tracetest/makeTest.js new file mode 100644 index 0000000000..7a50748930 --- /dev/null +++ b/eth/tracers/internal/tracetest/makeTest.js @@ -0,0 +1,54 @@ +// makeTest generates a test for the configured tracer by running +// a prestate reassembled and a call trace run, assembling all the +// gathered information into a test case. +var makeTest = function(tx, traceConfig) { + // Generate the genesis block from the block, transaction and prestate data + var block = eth.getBlock(eth.getTransaction(tx).blockHash); + var genesis = eth.getBlock(block.parentHash); + + delete genesis.gasUsed; + delete genesis.logsBloom; + delete genesis.parentHash; + delete genesis.receiptsRoot; + delete genesis.sha3Uncles; + delete genesis.size; + delete genesis.transactions; + delete genesis.transactionsRoot; + delete genesis.uncles; + + genesis.gasLimit = genesis.gasLimit.toString(); + genesis.number = genesis.number.toString(); + genesis.timestamp = genesis.timestamp.toString(); + + genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer"}); + for (var key in genesis.alloc) { + var nonce = genesis.alloc[key].nonce; + if (nonce) { + genesis.alloc[key].nonce = nonce.toString(); + } + } + genesis.config = admin.nodeInfo.protocols.eth.config; + + // Generate the call trace and produce the test input + var result = debug.traceTransaction(tx, traceConfig); + delete result.time; + + var context = { + number: block.number.toString(), + difficulty: block.difficulty, + timestamp: block.timestamp.toString(), + gasLimit: block.gasLimit.toString(), + miner: block.miner, + }; + if (block.baseFeePerGas) { + context.baseFeePerGas = block.baseFeePerGas.toString(); + } + + console.log(JSON.stringify({ + genesis: genesis, + context: context, + input: eth.getRawTransaction(tx), + result: result, + tracerConfig: traceConfig.tracerConfig, + }, null, 2)); +} diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 38097ff334..9cbd126694 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -25,7 +25,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" @@ -94,38 +93,28 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { // Configure a blockchain with the given prestate var ( signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: test.Genesis.BaseFee, - } - state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) + context = test.Context.toBlockContext(test.Genesis) + state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) defer state.Close() - if test.Genesis.ExcessBlobGas != nil && test.Genesis.BlobGasUsed != nil { - excessBlobGas := eip4844.CalcExcessBlobGas(*test.Genesis.ExcessBlobGas, *test.Genesis.BlobGasUsed) - context.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas) - } - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) if err != nil { t.Fatalf("failed to create call tracer: %v", err) } + + state.StateDB.SetLogger(tracer.Hooks) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err = st.TransitionDb(); err != nil { + evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) + tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) + vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) + if err != nil { t.Fatalf("failed to execute transaction: %v", err) } + tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, nil) // Retrieve the trace result and compare against the expected res, err := tracer.GetResult() if err != nil { diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go new file mode 100644 index 0000000000..d608b1e002 --- /dev/null +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -0,0 +1,613 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tracetest + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "math/big" + "os" + "path" + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" + + // Force-load live packages, to trigger registration + _ "github.com/ethereum/go-ethereum/eth/tracers/live" +) + +type supplyInfoIssuance struct { + GenesisAlloc *hexutil.Big `json:"genesisAlloc,omitempty"` + Reward *hexutil.Big `json:"reward,omitempty"` + Withdrawals *hexutil.Big `json:"withdrawals,omitempty"` +} + +type supplyInfoBurn struct { + EIP1559 *hexutil.Big `json:"1559,omitempty"` + Blob *hexutil.Big `json:"blob,omitempty"` + Misc *hexutil.Big `json:"misc,omitempty"` +} + +type supplyInfo struct { + Issuance *supplyInfoIssuance `json:"issuance,omitempty"` + Burn *supplyInfoBurn `json:"burn,omitempty"` + + // Block info + Number uint64 `json:"blockNumber"` + Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash"` +} + +func emptyBlockGenerationFunc(b *core.BlockGen) {} + +func TestSupplyOmittedFields(t *testing.T) { + var ( + config = *params.MergedTestChainConfig + gspec = &core.Genesis{ + Config: &config, + } + ) + + gspec.Config.TerminalTotalDifficulty = big.NewInt(0) + + out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) { + b.SetPoS() + }) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + expected := supplyInfo{ + Number: 0, + Hash: common.HexToHash("0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703"), + ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + } + actual := out[expected.Number] + + compareAsJSON(t, expected, actual) +} + +func TestSupplyGenesisAlloc(t *testing.T) { + var ( + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + eth1 = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + + config = *params.AllEthashProtocolChanges + + gspec = &core.Genesis{ + Config: &config, + Alloc: types.GenesisAlloc{ + addr1: {Balance: eth1}, + addr2: {Balance: eth1}, + }, + } + ) + + expected := supplyInfo{ + Issuance: &supplyInfoIssuance{ + GenesisAlloc: (*hexutil.Big)(new(big.Int).Mul(common.Big2, big.NewInt(params.Ether))), + }, + Number: 0, + Hash: common.HexToHash("0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca"), + ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + } + + out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + actual := out[expected.Number] + + compareAsJSON(t, expected, actual) +} + +func TestSupplyRewards(t *testing.T) { + var ( + config = *params.AllEthashProtocolChanges + + gspec = &core.Genesis{ + Config: &config, + } + ) + + expected := supplyInfo{ + Issuance: &supplyInfoIssuance{ + Reward: (*hexutil.Big)(new(big.Int).Mul(common.Big2, big.NewInt(params.Ether))), + }, + Number: 1, + Hash: common.HexToHash("0xcbb08370505be503dafedc4e96d139ea27aba3cbc580148568b8a307b3f51052"), + ParentHash: common.HexToHash("0xadeda0a83e337b6c073e3f0e9a17531a04009b397a9588c093b628f21b8bc5a3"), + } + + out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + actual := out[expected.Number] + + compareAsJSON(t, expected, actual) +} + +func TestSupplyEip1559Burn(t *testing.T) { + var ( + config = *params.AllEthashProtocolChanges + + aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") + // A sender who makes transactions, has some eth1 + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + gwei5 = new(big.Int).Mul(big.NewInt(5), big.NewInt(params.GWei)) + eth1 = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + + gspec = &core.Genesis{ + Config: &config, + BaseFee: big.NewInt(params.InitialBaseFee), + Alloc: types.GenesisAlloc{ + addr1: {Balance: eth1}, + }, + } + ) + + signer := types.LatestSigner(gspec.Config) + + eip1559BlockGenerationFunc := func(b *core.BlockGen) { + txdata := &types.DynamicFeeTx{ + ChainID: gspec.Config.ChainID, + Nonce: 0, + To: &aa, + Gas: 21000, + GasFeeCap: gwei5, + GasTipCap: big.NewInt(2), + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key1) + + b.AddTx(tx) + } + + out, chain, err := testSupplyTracer(t, gspec, eip1559BlockGenerationFunc) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + var ( + head = chain.CurrentBlock() + reward = new(big.Int).Mul(common.Big2, big.NewInt(params.Ether)) + burn = new(big.Int).Mul(big.NewInt(21000), head.BaseFee) + expected = supplyInfo{ + Issuance: &supplyInfoIssuance{ + Reward: (*hexutil.Big)(reward), + }, + Burn: &supplyInfoBurn{ + EIP1559: (*hexutil.Big)(burn), + }, + Number: 1, + Hash: head.Hash(), + ParentHash: head.ParentHash, + } + ) + + actual := out[expected.Number] + compareAsJSON(t, expected, actual) +} + +func TestSupplyWithdrawals(t *testing.T) { + var ( + config = *params.MergedTestChainConfig + gspec = &core.Genesis{ + Config: &config, + } + ) + + withdrawalsBlockGenerationFunc := func(b *core.BlockGen) { + b.SetPoS() + + b.AddWithdrawal(&types.Withdrawal{ + Validator: 42, + Address: common.Address{0xee}, + Amount: 1337, + }) + } + + out, chain, err := testSupplyTracer(t, gspec, withdrawalsBlockGenerationFunc) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + var ( + head = chain.CurrentBlock() + expected = supplyInfo{ + Issuance: &supplyInfoIssuance{ + Withdrawals: (*hexutil.Big)(big.NewInt(1337000000000)), + }, + Number: 1, + Hash: head.Hash(), + ParentHash: head.ParentHash, + } + actual = out[expected.Number] + ) + + compareAsJSON(t, expected, actual) +} + +// Tests fund retrieval after contract's selfdestruct. +// Contract A calls contract B which selfdestructs, but B receives eth1 +// after the selfdestruct opcode executes from Contract A. +// Because Contract B is removed only at the end of the transaction +// the ether sent in between is burnt before Cancun hard fork. +func TestSupplySelfdestruct(t *testing.T) { + var ( + config = *params.TestChainConfig + + aa = common.HexToAddress("0x1111111111111111111111111111111111111111") + bb = common.HexToAddress("0x2222222222222222222222222222222222222222") + dad = common.HexToAddress("0x0000000000000000000000000000000000000dad") + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + gwei5 = new(big.Int).Mul(big.NewInt(5), big.NewInt(params.GWei)) + eth1 = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + + gspec = &core.Genesis{ + Config: &config, + BaseFee: big.NewInt(params.InitialBaseFee), + Alloc: types.GenesisAlloc{ + addr1: {Balance: eth1}, + aa: { + Code: common.FromHex("0x61face60f01b6000527322222222222222222222222222222222222222226000806002600080855af160008103603457600080fd5b60008060008034865af1905060008103604c57600080fd5b5050"), + // Nonce: 0, + Balance: big.NewInt(0), + }, + bb: { + Code: common.FromHex("0x6000357fface000000000000000000000000000000000000000000000000000000000000808203602f57610dad80ff5b5050"), + Nonce: 0, + Balance: eth1, + }, + }, + } + ) + + gspec.Config.TerminalTotalDifficulty = big.NewInt(0) + + signer := types.LatestSigner(gspec.Config) + + testBlockGenerationFunc := func(b *core.BlockGen) { + b.SetPoS() + + txdata := &types.LegacyTx{ + Nonce: 0, + To: &aa, + Value: gwei5, + Gas: 150000, + GasPrice: gwei5, + Data: []byte{}, + } + + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key1) + + b.AddTx(tx) + } + + // 1. Test pre Cancun + preCancunOutput, preCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + if err != nil { + t.Fatalf("Pre-cancun failed to test supply tracer: %v", err) + } + + // Check balance at state: + // 1. 0x0000...000dad has 1 ether + // 2. A has 0 ether + // 3. B has 0 ether + statedb, _ := preCancunChain.State() + if got, exp := statedb.GetBalance(dad), eth1; got.CmpBig(exp) != 0 { + t.Fatalf("Pre-cancun address \"%v\" balance, got %v exp %v\n", dad, got, exp) + } + if got, exp := statedb.GetBalance(aa), big.NewInt(0); got.CmpBig(exp) != 0 { + t.Fatalf("Pre-cancun address \"%v\" balance, got %v exp %v\n", aa, got, exp) + } + if got, exp := statedb.GetBalance(bb), big.NewInt(0); got.CmpBig(exp) != 0 { + t.Fatalf("Pre-cancun address \"%v\" balance, got %v exp %v\n", bb, got, exp) + } + + head := preCancunChain.CurrentBlock() + // Check live trace output + expected := supplyInfo{ + Burn: &supplyInfoBurn{ + EIP1559: (*hexutil.Big)(big.NewInt(55289500000000)), + Misc: (*hexutil.Big)(big.NewInt(5000000000)), + }, + Number: 1, + Hash: head.Hash(), + ParentHash: head.ParentHash, + } + + actual := preCancunOutput[expected.Number] + + compareAsJSON(t, expected, actual) + + // 2. Test post Cancun + cancunTime := uint64(0) + gspec.Config.ShanghaiTime = &cancunTime + gspec.Config.CancunTime = &cancunTime + + postCancunOutput, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + if err != nil { + t.Fatalf("Post-cancun failed to test supply tracer: %v", err) + } + + // Check balance at state: + // 1. 0x0000...000dad has 1 ether + // 3. A has 0 ether + // 3. B has 5 gwei + statedb, _ = postCancunChain.State() + if got, exp := statedb.GetBalance(dad), eth1; got.CmpBig(exp) != 0 { + t.Fatalf("Post-shanghai address \"%v\" balance, got %v exp %v\n", dad, got, exp) + } + if got, exp := statedb.GetBalance(aa), big.NewInt(0); got.CmpBig(exp) != 0 { + t.Fatalf("Post-shanghai address \"%v\" balance, got %v exp %v\n", aa, got, exp) + } + if got, exp := statedb.GetBalance(bb), gwei5; got.CmpBig(exp) != 0 { + t.Fatalf("Post-shanghai address \"%v\" balance, got %v exp %v\n", bb, got, exp) + } + + // Check live trace output + head = postCancunChain.CurrentBlock() + expected = supplyInfo{ + Burn: &supplyInfoBurn{ + EIP1559: (*hexutil.Big)(big.NewInt(55289500000000)), + }, + Number: 1, + Hash: head.Hash(), + ParentHash: head.ParentHash, + } + + actual = postCancunOutput[expected.Number] + + compareAsJSON(t, expected, actual) +} + +// Tests selfdestructing contract to send its balance to itself (burn). +// It tests both cases of selfdestructing succeeding and being reverted. +// - Contract A calls B and D. +// - Contract B selfdestructs and sends the eth1 to itself (Burn amount to be counted). +// - Contract C selfdestructs and sends the eth1 to itself. +// - Contract D calls C and reverts (Burn amount of C +// has to be reverted as well). +func TestSupplySelfdestructItselfAndRevert(t *testing.T) { + var ( + config = *params.TestChainConfig + + aa = common.HexToAddress("0x1111111111111111111111111111111111111111") + bb = common.HexToAddress("0x2222222222222222222222222222222222222222") + cc = common.HexToAddress("0x3333333333333333333333333333333333333333") + dd = common.HexToAddress("0x4444444444444444444444444444444444444444") + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + gwei5 = new(big.Int).Mul(big.NewInt(5), big.NewInt(params.GWei)) + eth1 = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + eth2 = new(big.Int).Mul(common.Big2, big.NewInt(params.Ether)) + eth5 = new(big.Int).Mul(big.NewInt(5), big.NewInt(params.Ether)) + + gspec = &core.Genesis{ + Config: &config, + // BaseFee: big.NewInt(params.InitialBaseFee), + Alloc: types.GenesisAlloc{ + addr1: {Balance: eth1}, + aa: { + // Contract code in YUL: + // + // object "ContractA" { + // code { + // let B := 0x2222222222222222222222222222222222222222 + // let D := 0x4444444444444444444444444444444444444444 + + // // Call to Contract B + // let resB:= call(gas(), B, 0, 0x0, 0x0, 0, 0) + + // // Call to Contract D + // let resD := call(gas(), D, 0, 0x0, 0x0, 0, 0) + // } + // } + Code: common.FromHex("0x73222222222222222222222222222222222222222273444444444444444444444444444444444444444460006000600060006000865af160006000600060006000865af150505050"), + Balance: common.Big0, + }, + bb: { + // Contract code in YUL: + // + // object "ContractB" { + // code { + // let self := address() + // selfdestruct(self) + // } + // } + Code: common.FromHex("0x3080ff50"), + Balance: eth5, + }, + cc: { + Code: common.FromHex("0x3080ff50"), + Balance: eth1, + }, + dd: { + // Contract code in YUL: + // + // object "ContractD" { + // code { + // let C := 0x3333333333333333333333333333333333333333 + + // // Call to Contract C + // let resC := call(gas(), C, 0, 0x0, 0x0, 0, 0) + + // // Revert + // revert(0, 0) + // } + // } + Code: common.FromHex("0x73333333333333333333333333333333333333333360006000600060006000855af160006000fd5050"), + Balance: eth2, + }, + }, + } + ) + + gspec.Config.TerminalTotalDifficulty = big.NewInt(0) + + signer := types.LatestSigner(gspec.Config) + + testBlockGenerationFunc := func(b *core.BlockGen) { + b.SetPoS() + + txdata := &types.LegacyTx{ + Nonce: 0, + To: &aa, + Value: common.Big0, + Gas: 150000, + GasPrice: gwei5, + Data: []byte{}, + } + + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key1) + + b.AddTx(tx) + } + + output, chain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + // Check balance at state: + // 1. A has 0 ether + // 2. B has 0 ether, burned + // 3. C has 2 ether, selfdestructed but parent D reverted + // 4. D has 1 ether, reverted + statedb, _ := chain.State() + if got, exp := statedb.GetBalance(aa), common.Big0; got.CmpBig(exp) != 0 { + t.Fatalf("address \"%v\" balance, got %v exp %v\n", aa, got, exp) + } + if got, exp := statedb.GetBalance(bb), common.Big0; got.CmpBig(exp) != 0 { + t.Fatalf("address \"%v\" balance, got %v exp %v\n", bb, got, exp) + } + if got, exp := statedb.GetBalance(cc), eth1; got.CmpBig(exp) != 0 { + t.Fatalf("address \"%v\" balance, got %v exp %v\n", bb, got, exp) + } + if got, exp := statedb.GetBalance(dd), eth2; got.CmpBig(exp) != 0 { + t.Fatalf("address \"%v\" balance, got %v exp %v\n", bb, got, exp) + } + + // Check live trace output + block := chain.GetBlockByNumber(1) + + expected := supplyInfo{ + Burn: &supplyInfoBurn{ + EIP1559: (*hexutil.Big)(new(big.Int).Mul(block.BaseFee(), big.NewInt(int64(block.GasUsed())))), + Misc: (*hexutil.Big)(eth5), // 5ETH burned from contract B + }, + Number: 1, + Hash: block.Hash(), + ParentHash: block.ParentHash(), + } + + actual := output[expected.Number] + + compareAsJSON(t, expected, actual) +} + +func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) { + var ( + engine = beacon.New(ethash.NewFaker()) + ) + + traceOutputPath := filepath.ToSlash(t.TempDir()) + traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl") + + // Load supply tracer + tracer, err := tracers.LiveDirectory.New("supply", json.RawMessage(fmt.Sprintf(`{"path":"%s"}`, traceOutputPath))) + if err != nil { + return nil, nil, fmt.Errorf("failed to create call tracer: %v", err) + } + + chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), core.DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, engine, vm.Config{Tracer: tracer}, nil, nil) + if err != nil { + return nil, nil, fmt.Errorf("failed to create tester chain: %v", err) + } + defer chain.Stop() + + _, blocks, _ := core.GenerateChainWithGenesis(genesis, engine, 1, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{1}) + gen(b) + }) + + if n, err := chain.InsertChain(blocks); err != nil { + return nil, chain, fmt.Errorf("block %d: failed to insert into chain: %v", n, err) + } + + // Check and compare the results + file, err := os.OpenFile(traceOutputFilename, os.O_RDONLY, 0666) + if err != nil { + return nil, chain, fmt.Errorf("failed to open output file: %v", err) + } + defer file.Close() + + var output []supplyInfo + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + blockBytes := scanner.Bytes() + + var info supplyInfo + if err := json.Unmarshal(blockBytes, &info); err != nil { + return nil, chain, fmt.Errorf("failed to unmarshal result: %v", err) + } + + output = append(output, info) + } + + return output, chain, nil +} + +func compareAsJSON(t *testing.T, expected interface{}, actual interface{}) { + want, err := json.Marshal(expected) + if err != nil { + t.Fatalf("failed to marshal expected value to JSON: %v", err) + } + + have, err := json.Marshal(actual) + if err != nil { + t.Fatalf("failed to marshal actual value to JSON: %v", err) + } + + if !bytes.Equal(want, have) { + t.Fatalf("incorrect supply info: expected %s, got %s", string(want), string(have)) + } +} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json new file mode 100644 index 0000000000..b974151c1b --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/blob_tx.json @@ -0,0 +1,66 @@ +{ + "genesis": { + "baseFeePerGas": "7", + "blobGasUsed": "0", + "difficulty": "0", + "excessBlobGas": "36306944", + "extraData": "0xd983010e00846765746888676f312e32312e308664617277696e", + "gasLimit": "15639172", + "hash": "0xc682259fda061bb9ce8ccb491d5b2d436cb73daf04e1025dd116d045ce4ad28c", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0xae1a5ba939a4c9ac38aabeff361169fb55a6fc2c9511457e0be6eff9514faec0", + "nonce": "0x0000000000000000", + "number": "315", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a", + "timestamp": "1709626771", + "withdrawals": [], + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x272e0528" + }, + "0x0c2c51a0990aee1d73c1228de158688341557508": { + "balance": "0xde0b6b3a7640000" + } + }, + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true + } + }, + "context": { + "number": "316", + "difficulty": "0", + "timestamp": "1709626785", + "gasLimit": "15654443", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "7" + }, + "input": "0x03f8b1820539806485174876e800825208940c2c51a0990aee1d73c1228de1586883415575088080c083020000f842a00100c9fbdf97f747e85847b4f3fff408f89c26842f77c882858bf2c89923849aa00138e3896f3c27f2389147507f8bcec52028b0efca6ee842ed83c9158873943880a0dbac3f97a532c9b00e6239b29036245a5bfbb96940b9d848634661abee98b945a03eec8525f261c2e79798f7b45a5d6ccaefa24576d53ba5023e919b86841c0675", + "result": { + "from": "0x0c2c51a0990aee1d73c1228de158688341557508", + "gas": "0x5208", + "gasUsed": "0x5208", + "to": "0x0c2c51a0990aee1d73c1228de158688341557508", + "input": "0x", + "value": "0x0", + "type": "CALL" + } +} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer/create.json index df0b2872b4..621a6a97a4 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/create.json @@ -41,8 +41,7 @@ "nonce": "0x93363bbd2c95f410", "number": "2294701", "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" + "timestamp": "1513676127" }, "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json index 975616064a..0b38caec2c 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json @@ -104,8 +104,7 @@ "nonce": "0x38dee147326a8d40", "number": "25000", "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" + "timestamp": "1479891517" }, "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json index 6a2cda7dc9..4dd96e2f79 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json @@ -57,8 +57,7 @@ "nonce": "0x684129f283aaef18", "number": "11494", "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" + "timestamp": "1479735912" }, "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json index bb16a4a430..8b3b1e3d93 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json @@ -49,8 +49,7 @@ "nonce": "0x28c446f1cb9748c1", "number": "2290743", "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" + "timestamp": "1513616414" }, "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json index 9b45b52fe9..e69df9d1f9 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json @@ -10,7 +10,6 @@ "number": "24973", "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", "timestamp": "1479891145", - "totalDifficulty": "1892250259406", "alloc": { "0x6c06b16512b332e6cd8293a2974872674716ce18": { "balance": "0x0", @@ -56,6 +55,16 @@ "value": "0x0", "gas": "0x1f97e", "gasUsed": "0x72de", - "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000" + "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000", + "calls": [{ + "from":"0x6c06b16512b332e6cd8293a2974872674716ce18", + "gas":"0x8fc", + "gasUsed":"0x0", + "to":"0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", + "input":"0x", + "error":"insufficient balance for transfer", + "value":"0x14d1120d7b160000", + "type":"CALL" + }] } } diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json index ad0627ccd6..09ff53d104 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json @@ -11,7 +11,6 @@ "number": "0", "stateRoot": "0xa775801d572e9b79585eb131d18d79f8a0f71895455ab9a5b656911428e11708", "timestamp": "0", - "totalDifficulty": "1", "alloc": { "0x3623191d4ccfbbdf09e8ebf6382a1f8257417bc1": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7" @@ -45,7 +44,8 @@ "difficulty": "2", "timestamp": "1665537018", "gasLimit": "11511229", - "miner": "0x0000000000000000000000000000000000000000" + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "875000000" }, "input": "0x02f9029d82053980849502f90085010c388d00832dc6c08080b90241608060405234801561001057600080fd5b50600060405161001f906100a2565b604051809103906000f08015801561003b573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c04062266040518163ffffffff1660e01b815260040160006040518083038186803b15801561008457600080fd5b505afa158015610098573d6000803e3d6000fd5b50505050506100af565b610145806100fc83390190565b603f806100bd6000396000f3fe6080604052600080fdfea264697066735822122077f7dbd3450d6e817079cf3fe27107de5768bb3163a402b94e2206b468eb025664736f6c63430008070033608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033c001a07566181071cabaf58b70fc41557eb813bfc7a24f5c58554e7fed0bf7c031f169a0420af50b5fe791a4d839e181a676db5250b415dfb35cb85d544db7a1475ae2cc", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json index a023ed6d9b..17442f15b9 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json @@ -52,8 +52,7 @@ "nonce": "0x810f923ff4b450a1", "number": "2295103", "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" + "timestamp": "1513681246" }, "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json index 333bdd038c..e28958a69e 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json @@ -43,8 +43,7 @@ "nonce": "0xd1bdb150f6fd170e", "number": "2294630", "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" + "timestamp": "1513675347" }, "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json index 3207a298a9..f69bb72e0a 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json @@ -41,8 +41,7 @@ "nonce": "0xbc5d43adc2c30c7d", "number": "2294500", "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" + "timestamp": "1513673552" }, "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json index f02e5c6863..add992f5aa 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json @@ -46,8 +46,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json index 620df1d614..73960ea607 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json @@ -47,8 +47,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json index 6c7d01de1f..b923b903bf 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json index affb4ab033..d1aa2a58b4 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "tracerConfig": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json index 499b449a6e..d439d2b284 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json @@ -45,8 +45,7 @@ "nonce": "0x70849d5838dee2e9", "number": "25008", "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" + "timestamp": "1479891641" }, "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json index 617f52a14e..26495dfbce 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json @@ -10,7 +10,6 @@ "number": "1719576", "stateRoot": "0xab5eec2177a92d633e282936af66c46e24cfa8f2fdc2b8155f33885f483d06f3", "timestamp": "1466150166", - "totalDifficulty": "28295412423546970038", "alloc": { "0xf8bda96b67036ee48107f2a0695ea673479dda56": { "balance": "0x1529e844f9ecdeec", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json index c796804a4b..72a4db6901 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json @@ -10,7 +10,6 @@ "number": "1555278", "stateRoot": "0x5f56d8323ee384b0c8d1de49d63e150e17283eea813483698362bc0ec9e0242a", "timestamp": "1590795319", - "totalDifficulty": "2242614315030", "alloc": { "0x0000000000000000000000000000000000000004": { "balance": "0x0", @@ -63,12 +62,27 @@ "address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224" }, "traceAddress": [], - "subtraces": 0, + "subtraces": 1, "transactionPosition": 74, "transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4", "blockNumber": 1555279, "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46", "time": "209.346µs" + }, + { + "action": { + "balance": "0x0", + "callType": "callcode", + "from": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224", + "gas": "0xaf64", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x13" + }, + "error": "insufficient balance for transfer", + "result": {}, + "subtraces": 0, + "traceAddress": [0], + "type": "call" } ] } diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json index fb29e49660..0c4d29dd5b 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json @@ -10,7 +10,6 @@ "number": "1555277", "stateRoot": "0x6290d79215a2eebc25d5e456b35876c6d78ffc1ea47bdd70e375ebb3cf325620", "timestamp": "1590795308", - "totalDifficulty": "2242609643446", "alloc": { "0x0000000000000000000000000000000000000001": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json index 3c1e370f91..5538a708ea 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json @@ -10,7 +10,6 @@ "number": "1555274", "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5", "timestamp": "1590795228", - "totalDifficulty": "2242595605834", "alloc": { "0x0000000000000000000000000000000000000009": { "balance": "0x0", @@ -57,7 +56,7 @@ "gas": "0x1a034", "init": "0x36600060003760406103e8366000600060095af26001556103e8516002556104085160035500" }, - "error": "out of gas", + "error": "out of gas: not enough gas for reentrancy sentry", "traceAddress": [], "subtraces": 1, "transactionPosition": 117, diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json index 11bc4eae02..83d20fb078 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json @@ -41,8 +41,7 @@ "nonce": "0x93363bbd2c95f410", "number": "2294701", "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" + "timestamp": "1513676127" }, "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json index 375a163614..12754e9da9 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json @@ -104,8 +104,7 @@ "nonce": "0x38dee147326a8d40", "number": "25000", "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" + "timestamp": "1479891517" }, "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json index e5a37cbfdd..08ba48f123 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json @@ -57,8 +57,7 @@ "nonce": "0x684129f283aaef18", "number": "11494", "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" + "timestamp": "1479735912" }, "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json index 177912420a..c8d66ef2d5 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json @@ -7,7 +7,6 @@ "stateRoot": "0xfc01993ad96a8fb8790a093cea4f505f8db1b0e1143c5f57bb1d173db0baa9e3", "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", "difficulty": "1926740", - "totalDifficulty": "482216286599", "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", "gasLimit": "19388354", "timestamp": "1577558314", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json index d977dbe30d..250c402808 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json @@ -10,7 +10,6 @@ "number": "1555274", "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5", "timestamp": "1590795228", - "totalDifficulty": "2242595605834", "alloc": { "0x0000000000000000000000000000000000000001": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json index 0f28c07a9b..8da637a9e0 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json @@ -7,7 +7,6 @@ "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02", "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", "difficulty": "1813945", - "totalDifficulty": "469107641961", "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", "gasLimit": "6321166", "timestamp": "1577471202", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json index 6c4ce18063..3747d7f0f8 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json @@ -49,8 +49,7 @@ "nonce": "0x28c446f1cb9748c1", "number": "2290743", "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" + "timestamp": "1513616414" }, "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json index 4de08f2cca..1cea8175b3 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json @@ -10,7 +10,6 @@ "number": "24973", "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", "timestamp": "1479891145", - "totalDifficulty": "1892250259406", "alloc": { "0x6c06b16512b332e6cd8293a2974872674716ce18": { "balance": "0x0", @@ -64,9 +63,23 @@ "gasUsed": "0x72de", "output": "0x" }, - "subtraces": 0, + "subtraces": 1, "traceAddress": [], "type": "call" + }, + { + "action": { + "callType": "call", + "from": "0x6c06b16512b332e6cd8293a2974872674716ce18", + "gas": "0x8fc", + "to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", + "value": "0x14d1120d7b160000" + }, + "error": "insufficient balance for transfer", + "result": {}, + "subtraces": 0, + "traceAddress": [0], + "type": "call" } ] } diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json index 70442fdb9a..a8c11e8351 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json @@ -7,7 +7,6 @@ "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02", "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", "difficulty": "1813945", - "totalDifficulty": "469107641961", "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", "gasLimit": "6321166", "timestamp": "1577471202", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json index bc94708718..5473ef6343 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json @@ -52,8 +52,7 @@ "nonce": "0x810f923ff4b450a1", "number": "2295103", "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" + "timestamp": "1513681246" }, "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json index 3fcc61fc80..7dc6cc8098 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json @@ -10,7 +10,6 @@ "number": "555461", "stateRoot": "0xba8272acd0dfeb5f04376328e8bfc5b276b177697000c204a060f6f7b629ae32", "timestamp": "1577423350", - "totalDifficulty": "462222992438", "alloc": { "0xcf5b3467dfa45cdc8e5358a7a1ba4deb02e5faed": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json index 0eaa3f867a..82692d181a 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json @@ -10,7 +10,6 @@ "number": "1555160", "stateRoot": "0x95067c12148e2362fcd4a89df286ff0b1739ef097a40ca42ae7f698af9a9d913", "timestamp": "1590793999", - "totalDifficulty": "2242063623471", "alloc": { "0x8785e369f0ef0a4e5c5a5f929680427dc75273a5": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json index 132b84df36..d9595a7210 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json @@ -10,7 +10,6 @@ "number": "1555169", "stateRoot": "0xc4b9703de3e59ff795baae2c3afa010cf039c37244a7a6af7f3f491a10601348", "timestamp": "1590794111", - "totalDifficulty": "2242105342155", "alloc": { "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d": { "balance": "0x0", @@ -57,7 +56,7 @@ "gas": "0x19ee4", "init": "0x5a600055600060006000f0505a60015500" }, - "error": "out of gas", + "error": "out of gas: not enough gas for reentrancy sentry", "traceAddress": [], "subtraces": 1, "transactionPosition": 63, diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json index 28e96684b2..cb4954d9b7 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json @@ -10,7 +10,6 @@ "number": "839246", "stateRoot": "0x4bb3b02ec70b837651233957fb61a6ea3fc6a4244c1f55df7a713c154829ec0a", "timestamp": "1581179375", - "totalDifficulty": "1023985623933", "alloc": { "0x76554b33410b6d90b7dc889bfed0451ad195f27e": { "balance": "0x0", @@ -70,12 +69,25 @@ "output": "0x" }, "traceAddress": [], - "subtraces": 0, + "subtraces": 1, "transactionPosition": 26, "transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4", "blockNumber": 839247, "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c", "time": "182.267µs" + }, + { + "action": { + "from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e", + "gas": "0x25a18", + "init": "0x0000000000000000000000000000000000000000000000000000000000000000", + "value": "0xa" + }, + "error": "insufficient balance for transfer", + "result": {}, + "subtraces": 0, + "traceAddress": [0], + "type": "create" } ] } \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json index c3191d61bc..89f642db20 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json @@ -7,7 +7,6 @@ "stateRoot": "0x7f54db248a004ca182fe87fdfa6efda97163908b4f0cc84b36a6d60699d5d1be", "miner": "0x0000000000000000000000000000000000000000", "difficulty": "1", - "totalDifficulty": "24766", "extraData": "0xf09f928e20407072796c616273206e6f64652d3020f09f928e000000000000001d32ac3baf238e163e18ed6d77b67b0b54b08ad9781dc4ffd93c5ede1ca12c5f21b36ac39c7ebb88dff65da91f5b9461f19873a02602230b931ba388a809119f00", "gasLimit": "8000000", "timestamp": "1549153003", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json index bd6059faef..ea02454d3b 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json @@ -43,8 +43,7 @@ "nonce": "0xd1bdb150f6fd170e", "number": "2294630", "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" + "timestamp": "1513675347" }, "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json index 8888d3e68a..e914ca52b6 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json @@ -43,8 +43,7 @@ "nonce": "0xd1bdb150f6fd170e", "number": "2294630", "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" + "timestamp": "1513675347" }, "tracerConfig": { "convertParityErrors": true diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json index 62baf333b6..f6215a2b3f 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json @@ -10,7 +10,6 @@ "number": "553415", "stateRoot": "0x8f89e79109c19fa00e72b400502448540dc4773ad92dddd341dbba20c710a3b5", "timestamp": "1577396195", - "totalDifficulty": "458361299240", "alloc": { "0x531f76bad925f6a925474996c7d738c1008045f6": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json index b0346d8603..75ca39feee 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json @@ -41,8 +41,7 @@ "nonce": "0xbc5d43adc2c30c7d", "number": "2294500", "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" + "timestamp": "1513673552" }, "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json index 6759b05e52..8e5c7cd28e 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json @@ -46,8 +46,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json index 74fd87cc6c..c8c6dc65c1 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json @@ -10,7 +10,6 @@ "number": "1555145", "stateRoot": "0x565873b05f71b98595133e37a52d79c3476ce820c05ebedaddd35541b0e894a3", "timestamp": "1590793819", - "totalDifficulty": "2241994078605", "alloc": { "0x119f569a45e9d0089d51d7f9529f5ea9bf5785e2": { "balance": "0x0", @@ -63,13 +62,26 @@ "address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca" }, "traceAddress": [], - "subtraces": 1, + "subtraces": 2, "transactionPosition": 14, "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", "blockNumber": 1555146, "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e", "time": "187.145µs" }, + { + "action": { + "from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca", + "gas": "0x50ac", + "init": "0x5a", + "value": "0x1" + }, + "error": "insufficient balance for transfer", + "result": {}, + "subtraces": 0, + "traceAddress": [0], + "type": "create" + }, { "type": "suicide", "action": { @@ -79,7 +91,7 @@ }, "result": null, "traceAddress": [ - 0 + 1 ], "subtraces": 0, "transactionPosition": 14, diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json index a7244e9747..1a9ddb8c7a 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json index 5fbdf55d22..b2b462c34b 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "tracerConfig": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json index 96060d5545..a25f2383d6 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json @@ -10,7 +10,6 @@ "number": "1555284", "stateRoot": "0x9fe125b361b72d5479b24ad9be9964b74228c73a2dfb0065060a79b4a6dfaa1e", "timestamp": "1590795374", - "totalDifficulty": "2242642335405", "alloc": { "0xe85df1413eebe1b191c26260e19783a274a6b041": { "balance": "0x0", @@ -59,12 +58,25 @@ }, "error": "out of gas", "traceAddress": [], - "subtraces": 0, + "subtraces": 1, "transactionPosition": 16, "transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05", "blockNumber": 1555285, "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f", "time": "665.278µs" + }, + { + "action": { + "from": "0xf84bf5189ccd19f5897739756d214fa0dc099e0d", + "gas": "0x1d5c", + "init": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "value": "0xc350" + }, + "error": "insufficient balance for transfer", + "result": {}, + "subtraces": 0, + "traceAddress": [0], + "type": "create" } ] } \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json index 45ffbe2db9..e3ac8b8300 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json @@ -10,7 +10,6 @@ "number": "567687", "stateRoot": "0x7b4b193fe73ef87101c7c325954681861cc240c299d03459784b2b11c9c522ae", "timestamp": "1577578008", - "totalDifficulty": "485254950048", "alloc": { "0x8521f13dd5e4bc3dab3cf0f01a195a5af899e851": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json index 16d43767d5..f759536934 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json @@ -7,7 +7,6 @@ "stateRoot": "0x40b5f53d610108947688a04fb68838ff9c0aa0dd6e54156b682537192171ff5c", "miner": "0x774c398d763161f55b66a646f17edda4addad2ca", "difficulty": "1928226", - "totalDifficulty": "457857582215", "extraData": "0xd983010907846765746888676f312e31332e358664617277696e", "gasLimit": "7999473", "timestamp": "1577392669", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json index a001178a42..52e1299eb1 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json @@ -45,8 +45,7 @@ "nonce": "0x70849d5838dee2e9", "number": "25008", "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" + "timestamp": "1479891641" }, "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", "result": [ diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json index df0b2872b4..621a6a97a4 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json @@ -41,8 +41,7 @@ "nonce": "0x93363bbd2c95f410", "number": "2294701", "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" + "timestamp": "1513676127" }, "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json index 80fc0b0ada..82980679d4 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json @@ -104,8 +104,7 @@ "nonce": "0x38dee147326a8d40", "number": "25000", "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" + "timestamp": "1479891517" }, "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json index 2cd28bacc4..4fa866df18 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json @@ -57,8 +57,7 @@ "nonce": "0x684129f283aaef18", "number": "11494", "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" + "timestamp": "1479735912" }, "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json index 07fda21d4b..b83b743632 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json @@ -49,8 +49,7 @@ "nonce": "0x28c446f1cb9748c1", "number": "2290743", "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" + "timestamp": "1513616414" }, "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json index 16e4136230..ff30558874 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json @@ -10,7 +10,6 @@ "number": "24973", "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", "timestamp": "1479891145", - "totalDifficulty": "1892250259406", "alloc": { "0x6c06b16512b332e6cd8293a2974872674716ce18": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json index a023ed6d9b..17442f15b9 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json @@ -52,8 +52,7 @@ "nonce": "0x810f923ff4b450a1", "number": "2295103", "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" + "timestamp": "1513681246" }, "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json index 333bdd038c..e28958a69e 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json @@ -43,8 +43,7 @@ "nonce": "0xd1bdb150f6fd170e", "number": "2294630", "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" + "timestamp": "1513675347" }, "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json index 3207a298a9..f69bb72e0a 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json @@ -41,8 +41,7 @@ "nonce": "0xbc5d43adc2c30c7d", "number": "2294500", "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" + "timestamp": "1513673552" }, "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json index 5c7e5629e9..563ae9126e 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json @@ -46,8 +46,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json index 11b23a990e..be9acf1409 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json @@ -47,8 +47,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json index 37723f17dd..b152d43a3e 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json index 499b449a6e..d439d2b284 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json @@ -45,8 +45,7 @@ "nonce": "0x70849d5838dee2e9", "number": "25008", "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" + "timestamp": "1479891641" }, "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json index dbece7229d..cef0c1c5a8 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json @@ -10,7 +10,6 @@ "number": "995200", "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94", "timestamp": "1455322761", - "totalDifficulty": "7077231809278509672", "alloc": { "0x200edd17f30485a8735878661960cd7a9a95733f": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json index 2b03dbb8dd..0ae76e92f9 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json @@ -10,7 +10,6 @@ "number": "2340152", "stateRoot": "0x38295a2634c9c62d48bcbf2ef2ae83768b9055c1f5e6469d17a5d1bcb052072e", "timestamp": "1475034708", - "totalDifficulty": "66488249547380413902", "alloc": { "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/frontier_create_outofstorage.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/frontier_create_outofstorage.json new file mode 100644 index 0000000000..049f24d932 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/frontier_create_outofstorage.json @@ -0,0 +1,189 @@ +{ + "genesis": { + "difficulty": "7797655526461", + "extraData": "0xd583010203844765746885676f312e35856c696e7578", + "gasLimit": "3141592", + "hash": "0x4ad333086cb86a6d261329504c9e1ca4d571212f56d6635dd213b700e1e85a6f", + "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", + "mixHash": "0xdaca4c8bd9a6e6707059736633543ebf50f97c07700a9ed55859b97275c19ea5", + "nonce": "0x894c15d74e8ae8bd", + "number": "469666", + "stateRoot": "0xf9c50965ffae3f99310483a7836c545a025cc680303adaf3671dbeef99edf03a", + "timestamp": "1446318401", + "alloc": { + "0x0000000000000000000000000000000000000004": { + "balance": "0x0" + }, + "0x0047a8033cc6d6ca2ed5044674fd421f44884de8": { + "balance": "0x44f5ced08fe37cf7", + "nonce": "872" + }, + "0x1d11e5eae3112dbd44f99266872ff1d07c77dce8": { + "balance": "0x0", + "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806338cc48311461004f578063767800de14610088578063d1d80fdf146100c15761004d565b005b61005c60048050506100ff565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61009560048050506100d9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100d7600480803590602001909190505061012e565b005b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061012b565b90565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018a57610002565b80600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b5056", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f631e3b3aafa084bc51c714825aacf505d2059be" + } + }, + "0xe48430c4e88a929bba0ee3dce284866a9937b609": { + "balance": "0x26758774d51d8677a", + "nonce": "261" + }, + "0xf631e3b3aafa084bc51c714825aacf505d2059be": { + "balance": "0x0", + "code": "0x606060405236156100da5760e060020a600035046323dc42e781146100ff5780632ef3accc146101a5578063385928321461021d57806345362978146102b65780634c7737951461034a578063524f38891461035c5780635c242c59146103ad578063772286591461044a5780637e1c42051461052457806381ade30714610601578063a2ec191a14610696578063adf59f991461071b578063ae815843146107b5578063bf1fe4201461084f578063de4b326214610890578063e8025731146108d4578063e839e65e14610970578063fbf8041814610a44575b610b20604051600160a060020a03331690600090349082818181858883f15050505050565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050505050505060008260006000610c0b83335b60006113fd8362030d40846101f5565b6040805160206004803580820135601f8101849004840285018401909552848452610b22949193602493909291840191908190840183828082843750949650509335935050505060006113fd8383335b600160a060020a03811660009081526003602052604081205460ff168114156114b557610b57565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050506000610d5885858585610841565b6040805160206004803580820135601f8101849004840285018401909552848452610b2294919360249390929184019190819084018382808284375050604080516020601f8935808c01359182018390048302840183019094528083529799986044989297509290920194509250829150840183828082843750949650505050505050600082600060006114068333610195565b610b34600154600160a060020a031681565b6040805160206004803580820135601f8101849004840285018401909552848452610b2294919360249390929184019190819084018382808284375094965050505050505060006114008233610195565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b60008360006000610d5f8333610195565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050505050505060008360006000610cb88333610195565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505050505b60008460006000610f288333610195565b6040805160206004803580820135601f8101849004840285018401909552848452610b2294919360249390929184019190819084018382808284375050604080516020601f8935808c0135918201839004830284018301909452808352979998604498929750929092019450925082915084018382808284375094965050505050505060006113fd6000848462030d40610439565b6040805160206004803580820135601f8101849004840285018401909552848452610b209491936024939092918401919081908401838280828437509496505093359350505050600254600090600160a060020a039081163391909116148015906107115750600154600160a060020a039081163390911614155b156111fd57610002565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000610c0484848462030d40610439565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b6000610d5885858585610439565b610b20600435600254600160a060020a039081163391909116148015906108865750600154600160a060020a039081163390911614155b156114b057610002565b610b20600435600254600090600160a060020a039081163391909116148015906108ca5750600154600160a060020a039081163390911614155b1561134d57610002565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505093359350505050600083600060006111618333610195565b6040805160206004803580820135601f8101849004840285018401909552848452610b2294919360249390929184019190819084018382808284375050604080516020601f8935808c01359182018390048302840183019094528083529799986044989297509290920194509250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050505050505060008360006000610b5e8333610195565b60408051602060046024803582810135601f8101859004850286018501909652858552610b229583359593946044949392909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760849791965060249190910194509092508291508401838280828437509496505093359350505050600084600060006112a68333610195565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b93505050505b9392505050565b91508160001415610b8d57600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f15050503484900392508211159050610bee57604051600160a060020a03331690600090839082818181858883f150505050505b610b51600088888862030d406105f0565b610002565b9050610b57565b91508160001415610c3a57600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f15050503484900392508211159050610c9b57604051600160a060020a03331690600090839082818181858883f150505050505b610b5187878762030d40610439565b93505050505b949350505050565b91508160001415610ce757600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f15050503484900392508211159050610d4857604051600160a060020a03331690600090839082818181858883f150505050505b610caa8888888862030d406105f0565b9050610cb0565b91508160001415610d8e57600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f15050503484900392508211159050610def57604051600160a060020a03331690600090839082818181858883f150505050505b604080516000805442810183528351928390036020908101842060019290920183558184528381018d9052608084018a905260a09484018581528c51958501959095528b519198507f1f28d876aff267c3302a63cd25ebcca53e6f60691049df42275b6d06ab455c679489948e948e948e948e9492606085019260c086019289810192829185918391869190600490601f850104600302600f01f150905090810190601f168015610eb45780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610f0d5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a150610cb0915050565b91508160001415610f5757600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f15050503484900392508211159050610fb857604051600160a060020a03331690600090839082818181858883f150505050505b60006000505442016040518082815260200191505060405180910390209350835060006000818150548092919060010191905055507f4e65aab8959da44521dc50a6ce3dfbd65016d8cfab70a47ea7541458206c4d5b848a8a8a8a8a604051808781526020018681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561108e5780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110e75780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156111405780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390a15050505b95945050505050565b9150816000141561119057600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f150505034849003925082111590506111f157604051600160a060020a03331690600090839082818181858883f150505050505b610caa88888888610439565b82604051808280519060200190808383829060006004602084601f0104600302600f01f1506007805491909301849003909320600184018084559095508594509192918391508280158290116112765781836000526020600020918201910161127691905b808211156112a25760008155600101611262565b505050815481101561000257600091825260208083209091019290925591825260069052604090205550565b5090565b915081600014156112d557600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f1505050348490039250821115905061133657604051600160a060020a03331690600090839082818181858883f150505050505b61134389898989896105f0565b9350505050611158565b50600481905560005b6007548110156113f957600780546006916000918490811015610002575080547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6888501548352602093909352604082205485029260059291908590811015610002579082527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688018150548152602081019190915260400160002055600101611356565b5050565b90505b92915050565b9150816000141561143557600160a060020a0333166000908152600360205260409020805460ff191660011790555b34829010610bff5760405173f65b3b60010d57d0bb8478aa6ced15fe720621b490600090849082818181858883f1505050348490039250821115905061149657604051600160a060020a03331690600090839082818181858883f150505050505b6114a66000878762030d40610439565b9350505050611400565b600855565b6005600050600085604051808280519060200190808383829060006004602084601f0104600302600f01f1509091018290039091208352505060209190915260409020546008548402019050610b5756", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000004", + "0xde5cab2c6836c23f6388364c9a0e20bd1c8c7e6c3b5d0339cd8a2f7c4b36208c": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0xf65b3b60010d57d0bb8478aa6ced15fe720621b4": { + "balance": "0x2c52a97273d2164" + } + }, + "config": { + "chainId": 1, + "homesteadBlock": 1150000, + "daoForkBlock": 1920000, + "daoForkSupport": true, + "eip150Block": 2463000, + "eip155Block": 2675000, + "eip158Block": 2675000, + "byzantiumBlock": 4370000, + "constantinopleBlock": 7280000, + "petersburgBlock": 7280000, + "istanbulBlock": 9069000, + "muirGlacierBlock": 9200000, + "berlinBlock": 12244000, + "londonBlock": 12965000, + "arrowGlacierBlock": 13773000, + "grayGlacierBlock": 15050000, + "shanghaiTime": 1681338455, + "terminalTotalDifficulty": 7797655526461000, + "terminalTotalDifficultyPassed": true, + "ethash": {} + } + }, + "context": { + "number": "469667", + "difficulty": "7793848077478", + "timestamp": "1446318425", + "gasLimit": "3141592", + "miner": "0xe48430c4e88a929bba0ee3dce284866a9937b609" + }, + "input": "0xf91ec7820368850ba43b7400831b77408080b91e72606060405260018054600160a060020a0319163317905561036f600360609081527f55524c0000000000000000000000000000000000000000000000000000000000608052610120604052604c60a09081527f6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f707560c0527f626c69632f5469636b65723f706169723d455448584254292e726573756c742e60e0527f58455448585842542e632e3000000000000000000000000000000000000000006101005261037d919062030d417f38cc483100000000000000000000000000000000000000000000000000000000610120908152600090731d11e5eae3112dbd44f99266872ff1d07c77dce89081906338cc4831906101249060209060048188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc8887604051837c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156102255780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f11561000257505060405180517f385928320000000000000000000000000000000000000000000000000000000082526004828101888152606484018a90526080602485018181528d5160848701528d519496508a958e958e958e9594604484019360a40192909181908490829085908e906020601f850104600302600f01f150905090810190601f1680156102e65780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561033f5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f11561000257505060405151979650505050505050565b611af2806103806000396000f35b5056606060405236156100985760e060020a6000350463056e1059811461009a57806327dc297e14610391578063346b306a146103e257806341c0e1b51461075e578063489306eb146107855780635731f35714610a5e57806365a4dfb314610de05780637975c56e14611179578063a2e6204514611458578063ae152cf414611528578063b77644751461181b578063d594877014611876575b005b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561025e5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103085780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f115610002575050604051519350610dd892505050565b60408051602060248035600481810135601f81018590048502860185019096528585526100989581359591946044949293909201918190840183828082843750949650505050505050611a2761187a565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156105d15780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106795780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106d25780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561072b5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b9392505050565b610098600154600160a060020a03908116339091161415611a255733600160a060020a0316ff5b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109345780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150600087876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109d75780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610a305780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f115610002575050604051519695505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610c535780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610cfa5780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610d535780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610dac5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b949350505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663fbf80418600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc89876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610fe45780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015089898989896040518760e060020a028152600401808681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110935780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110ec5780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156111455780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038185886185025a03f115610002575050604051519998505050505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561132e5780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f11561000257505050604051805190602001508787876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156113d05780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156114295780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6100985b611aef604060405190810160405280600381526020017f55524c0000000000000000000000000000000000000000000000000000000000815260200150608060405190810160405280604c81526020017f6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f707581526020017f626c69632f5469636b65723f706169723d455448584254292e726573756c742e81526020017f58455448585842542e632e30000000000000000000000000000000000000000081526020015062030d416115ae565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f810183900483028401830190945283835297999860449892975091909101945090925082915084018382808284375094965050933593505050505b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156116e75780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117925780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117eb5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6040805160028054602060018216156101000260001901909116829004601f81018290048202840182019094528383526119679390830182828015611a1d5780601f106119f257610100808354040283529160200191611a1d565b6119d55b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604080518051855473ffffffffffffffffffffffffffffffffffffffff1916178086557f4c7737950000000000000000000000000000000000000000000000000000000082529151600160a060020a03929092169250634c773795916004828101926020929190829003018188876161da5a03f115610002575050604051519250505090565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156119c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311611a0057829003601f168201915b505050505081565b565b600160a060020a031633600160a060020a0316141515611a4657610002565b8060026000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611aad57805160ff19168380011785555b50611add9291505b80821115611ae75760008155600101611a99565b82800160010185558215611a91579182015b82811115611a91578251826000505591602001919060010190611abf565b5050611aeb61145c565b5090565b5050565b50561ca083d25971e732af3acb0a223dea6258f37407bf2d075fd852a83312238fca7cdea01f5a1189b054e947a0a140c565c4fc829b584e7348c9a7f65a890fe688e8b67f", + "tracerConfig": { + "withLog": true + }, + "result": { + "from": "0x0047a8033cc6d6ca2ed5044674fd421f44884de8", + "gas": "0x1b7740", + "gasUsed": "0x9274f", + "to": "0xc24431c1a1147456414355b1f1769de450e524da", + "input": "0x606060405260018054600160a060020a0319163317905561036f600360609081527f55524c0000000000000000000000000000000000000000000000000000000000608052610120604052604c60a09081527f6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f707560c0527f626c69632f5469636b65723f706169723d455448584254292e726573756c742e60e0527f58455448585842542e632e3000000000000000000000000000000000000000006101005261037d919062030d417f38cc483100000000000000000000000000000000000000000000000000000000610120908152600090731d11e5eae3112dbd44f99266872ff1d07c77dce89081906338cc4831906101249060209060048188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc8887604051837c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156102255780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f11561000257505060405180517f385928320000000000000000000000000000000000000000000000000000000082526004828101888152606484018a90526080602485018181528d5160848701528d519496508a958e958e958e9594604484019360a40192909181908490829085908e906020601f850104600302600f01f150905090810190601f1680156102e65780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561033f5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f11561000257505060405151979650505050505050565b611af2806103806000396000f35b5056606060405236156100985760e060020a6000350463056e1059811461009a57806327dc297e14610391578063346b306a146103e257806341c0e1b51461075e578063489306eb146107855780635731f35714610a5e57806365a4dfb314610de05780637975c56e14611179578063a2e6204514611458578063ae152cf414611528578063b77644751461181b578063d594877014611876575b005b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561025e5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103085780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f115610002575050604051519350610dd892505050565b60408051602060248035600481810135601f81018590048502860185019096528585526100989581359591946044949293909201918190840183828082843750949650505050505050611a2761187a565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156105d15780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106795780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106d25780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561072b5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b9392505050565b610098600154600160a060020a03908116339091161415611a255733600160a060020a0316ff5b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109345780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150600087876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109d75780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610a305780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f115610002575050604051519695505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610c535780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610cfa5780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610d535780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610dac5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b949350505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663fbf80418600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc89876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610fe45780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015089898989896040518760e060020a028152600401808681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110935780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110ec5780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156111455780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038185886185025a03f115610002575050604051519998505050505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561132e5780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f11561000257505050604051805190602001508787876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156113d05780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156114295780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6100985b611aef604060405190810160405280600381526020017f55524c0000000000000000000000000000000000000000000000000000000000815260200150608060405190810160405280604c81526020017f6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f707581526020017f626c69632f5469636b65723f706169723d455448584254292e726573756c742e81526020017f58455448585842542e632e30000000000000000000000000000000000000000081526020015062030d416115ae565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f810183900483028401830190945283835297999860449892975091909101945090925082915084018382808284375094965050933593505050505b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156116e75780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117925780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117eb5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6040805160028054602060018216156101000260001901909116829004601f81018290048202840182019094528383526119679390830182828015611a1d5780601f106119f257610100808354040283529160200191611a1d565b6119d55b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604080518051855473ffffffffffffffffffffffffffffffffffffffff1916178086557f4c7737950000000000000000000000000000000000000000000000000000000082529151600160a060020a03929092169250634c773795916004828101926020929190829003018188876161da5a03f115610002575050604051519250505090565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156119c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311611a0057829003601f168201915b505050505081565b565b600160a060020a031633600160a060020a0316141515611a4657610002565b8060026000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611aad57805160ff19168380011785555b50611add9291505b80821115611ae75760008155600101611a99565b82800160010185558215611a91579182015b82811115611a91578251826000505591602001919060010190611abf565b5050611aeb61145c565b5090565b5050565b5056", + "output": "0x606060405236156100985760e060020a6000350463056e1059811461009a57806327dc297e14610391578063346b306a146103e257806341c0e1b51461075e578063489306eb146107855780635731f35714610a5e57806365a4dfb314610de05780637975c56e14611179578063a2e6204514611458578063ae152cf414611528578063b77644751461181b578063d594877014611876575b005b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561025e5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103085780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f115610002575050604051519350610dd892505050565b60408051602060248035600481810135601f81018590048502860185019096528585526100989581359591946044949293909201918190840183828082843750949650505050505050611a2761187a565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156105d15780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106795780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106d25780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561072b5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b9392505050565b610098600154600160a060020a03908116339091161415611a255733600160a060020a0316ff5b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109345780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150600087876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156109d75780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610a305780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f115610002575050604051519695505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166377228659600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610c535780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f1156100025750505060405180519060200150888888886040518660e060020a028152600401808581526020018060200180602001806020018481038452878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610cfa5780820380516001836020036101000a031916815260200191505b508481038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610d535780820380516001836020036101000a031916815260200191505b508481038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610dac5780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038185886185025a03f1156100025750506040515193505050505b949350505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024919091019450909250829150840183828082843750949650509335935050505060006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663fbf80418600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc89876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015610fe45780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015089898989896040518760e060020a028152600401808681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110935780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156110ec5780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156111455780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038185886185025a03f115610002575050604051519998505050505050505050565b60408051602060248035600481810135601f81018590048502860185019096528585526119559581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160e060020a6338cc48310281529051959760009750731d11e5eae3112dbd44f99266872ff1d07c77dce8968796506338cc4831955082820194506020935091829003018188876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a031663adf59f99600060009054906101000a9004600160a060020a0316600160a060020a031663524f3889876040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561132e5780820380516001836020036101000a031916815260200191505b50925050506020604051808303816000876161da5a03f11561000257505050604051805190602001508787876040518560e060020a0281526004018084815260200180602001806020018381038352858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156113d05780820380516001836020036101000a031916815260200191505b508381038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156114295780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6100985b611aef604060405190810160405280600381526020017f55524c0000000000000000000000000000000000000000000000000000000000815260200150608060405190810160405280604c81526020017f6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f707581526020017f626c69632f5469636b65723f706169723d455448584254292e726573756c742e81526020017f58455448585842542e632e30000000000000000000000000000000000000000081526020015062030d416115ae565b6040805160206004803580820135601f8101849004840285018401909552848452611955949193602493909291840191908190840183828082843750506040805160208835808b0135601f810183900483028401830190945283835297999860449892975091909101945090925082915084018382808284375094965050933593505050505b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150600060006101000a815481600160a060020a0302191690830217905550600060009054906101000a9004600160a060020a0316600160a060020a03166338592832600060009054906101000a9004600160a060020a0316600160a060020a0316632ef3accc88876040518360e060020a02815260040180806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156116e75780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050506040518051906020015060008888886040518660e060020a0281526004018085815260200180602001806020018481526020018381038352868181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117925780820380516001836020036101000a031916815260200191505b508381038252858181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156117eb5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038185886185025a03f11561000257505060405151935061075792505050565b6040805160028054602060018216156101000260001901909116829004601f81018290048202840182019094528383526119679390830182828015611a1d5780601f106119f257610100808354040283529160200191611a1d565b6119d55b60006000731d11e5eae3112dbd44f99266872ff1d07c77dce8905080600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604080518051855473ffffffffffffffffffffffffffffffffffffffff1916178086557f4c7737950000000000000000000000000000000000000000000000000000000082529151600160a060020a03929092169250634c773795916004828101926020929190829003018188876161da5a03f115610002575050604051519250505090565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156119c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311611a0057829003601f168201915b505050505081565b565b600160a060020a031633600160a060020a0316141515611a4657610002565b8060026000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611aad57805160ff19168380011785555b50611add9291505b80821115611ae75760008155600101611a99565b82800160010185558215611a91579182015b82811115611a91578251826000505591602001919060010190611abf565b5050611aeb61145c565b5090565b5050565b5056", + "calls": [ + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x12c54b", + "gasUsed": "0x106", + "to": "0x1d11e5eae3112dbd44f99266872ff1d07c77dce8", + "input": "0x38cc4831", + "output": "0x000000000000000000000000f631e3b3aafa084bc51c714825aacf505d2059be", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x12", + "gasUsed": "0x12", + "to": "0x0000000000000000000000000000000000000004", + "input": "0x55524c", + "output": "0x55524c", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x127270", + "gasUsed": "0x26b", + "to": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "input": "0x2ef3accc00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000030d41000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000", + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x12", + "gasUsed": "0x12", + "to": "0x0000000000000000000000000000000000000004", + "input": "0x55524c", + "output": "0x55524c", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x18", + "gasUsed": "0x18", + "to": "0x0000000000000000000000000000000000000004", + "input": "0x6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e30", + "output": "0x6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e30", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xc24431c1a1147456414355b1f1769de450e524da", + "gas": "0x124995", + "gasUsed": "0x78f5", + "to": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "input": "0x385928320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000030d41000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e300000000000000000000000000000000000000000", + "output": "0x55bc8431ce52389ac668a9b14a0943290cb7263732251186e960bc8b249b5f32", + "calls": [ + { + "from": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "gas": "0x0", + "gasUsed": "0x0", + "to": "0xf65b3b60010d57d0bb8478aa6ced15fe720621b4", + "input": "0x", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "gas": "0x12", + "gasUsed": "0x12", + "to": "0x0000000000000000000000000000000000000004", + "input": "0x55524c", + "output": "0x55524c", + "value": "0x0", + "type": "CALL" + }, + { + "from": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "gas": "0x18", + "gasUsed": "0x18", + "to": "0x0000000000000000000000000000000000000004", + "input": "0x6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e30", + "output": "0x6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e30", + "value": "0x0", + "type": "CALL" + } + ], + "logs":[ + { + "address": "0xf631e3b3aafa084bc51c714825aacf505d2059be", + "topics": ["0x1f28d876aff267c3302a63cd25ebcca53e6f60691049df42275b6d06ab455c67"], + "data":"0x55bc8431ce52389ac668a9b14a0943290cb7263732251186e960bc8b249b5f32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000030d41000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c6a736f6e2868747470733a2f2f6170692e6b72616b656e2e636f6d2f302f7075626c69632f5469636b65723f706169723d455448584254292e726573756c742e58455448585842542e632e300000000000000000000000000000000000000000", + "position":"0x3" + } + ], + "value": "0x0", + "type": "CALL" + } + ], + "value": "0x0", + "type": "CREATE" + } +} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json index 263e88d6e1..5cc3013f80 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json @@ -10,7 +10,6 @@ "number": "1881283", "stateRoot": "0x6e3832bc2e4e66170a1e716449083e08fbb70e7b2a9f1f34e0c57e66ce40c50f", "timestamp": "1468467284", - "totalDifficulty": "37186898441932102239", "alloc": { "0x0000000000000000000000000000000000000004": { "balance": "0x0" diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json index 66d4582008..c931ed63fc 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json @@ -10,7 +10,6 @@ "number": "595531", "stateRoot": "0x79d00dd270bffc48d89fa55842f63f840981121378da8c6de4d479535f25ed6a", "timestamp": "1448471472", - "totalDifficulty": "3448100174991667199", "alloc": { "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { "balance": "0x44dc051cccdfd2e132", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json index 762ccbe58f..42fc872554 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json @@ -10,7 +10,6 @@ "number": "1725115", "stateRoot": "0xca08a341c1f95fcba0821c4a27662ef162d39e1f9f5722717531f510d54112b0", "timestamp": "1466232982", - "totalDifficulty": "28554024908214037524", "alloc": { "0x0000000000000000000000000000000000000004": { "balance": "0x0" diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json index 64941dd4db..5300d341b8 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json @@ -10,7 +10,6 @@ "number": "765824", "stateRoot": "0x8d96cb027a29f8ca0ccd6d31f9ea0656136ec8030ecda70bb9231849ed6f41a2", "timestamp": "1451389443", - "totalDifficulty": "4838314986494741271", "alloc": { "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb": { "balance": "0x14203bee2ea6fbe8c", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json index 30346d07f1..d5c2f864c1 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json @@ -10,7 +10,6 @@ "number": "1968179", "stateRoot": "0x6420003b1779cca3bcdab698c239bbc63623c0a7e4deeedbdb8190b9e7fd7520", "timestamp": "1469713675", - "totalDifficulty": "42284028928878034360", "alloc": { "0x10abb5efecdc09581f8b7cb95791fe2936790b4e": { "balance": "0x81f158e2814b4ab624c", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json index 6faf898a0f..1267160d13 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json @@ -10,7 +10,6 @@ "number": "1646451", "stateRoot": "0x2bd193b9911caf43204960cc7661ce864bf0bac7f9b60191aa02bbff24f061fb", "timestamp": "1465103859", - "totalDifficulty": "24813742796574158431", "alloc": { "0x01115b41bd2731353dd3e6abf44818fdc035aaf1": { "balance": "0x16d99e16e809000", diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json index e73081107f..38d96a6bd0 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json @@ -10,7 +10,6 @@ "number": "995200", "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94", "timestamp": "1455322761", - "totalDifficulty": "7077231809278509672", "alloc": { "0x200edd17f30485a8735878661960cd7a9a95733f": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json index 315481aff5..444eba450b 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/blob_tx.json @@ -14,7 +14,6 @@ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a", "timestamp": "1709626771", - "totalDifficulty": "1", "withdrawals": [], "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "alloc": { @@ -51,7 +50,8 @@ "difficulty": "0", "timestamp": "1709626785", "gasLimit": "15654443", - "miner": "0x0000000000000000000000000000000000000000" + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "7" }, "input": "0x03f8b1820539806485174876e800825208940c2c51a0990aee1d73c1228de1586883415575088080c083020000f842a00100c9fbdf97f747e85847b4f3fff408f89c26842f77c882858bf2c89923849aa00138e3896f3c27f2389147507f8bcec52028b0efca6ee842ed83c9158873943880a0dbac3f97a532c9b00e6239b29036245a5bfbb96940b9d848634661abee98b945a03eec8525f261c2e79798f7b45a5d6ccaefa24576d53ba5023e919b86841c0675", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json new file mode 100644 index 0000000000..b013d520c1 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_create.json @@ -0,0 +1,62 @@ +{ + "genesis": { + "baseFeePerGas": "875000000", + "difficulty": "0", + "extraData": "0xd983010d05846765746888676f312e32312e318664617277696e", + "gasLimit": "11511229", + "hash": "0xd462585c6c5a3b3bf14850ebcde71b6615b9aaf6541403f9a0457212dd0502e0", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0xfa51e868d6a7c0728f18800e4cc8d4cc1c87430cc9975e947eb6c9c03599b4e2", + "nonce": "0x0000000000000000", + "number": "1", + "stateRoot": "0xd2ebe0a7f3572ffe3e5b4c78147376d3fca767f236e4dd23f9151acfec7cb0d1", + "timestamp": "1699617692", + "withdrawals": [], + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x5208" + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0x8ac7230489e80000" + } + }, + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "isDev": true + } + }, + "context": { + "number": "2", + "difficulty": "0", + "timestamp": "1699617847", + "gasLimit": "11522469", + "miner": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "765625000" + }, + "input": "0x02f902b48205398084b2d05e0085011b1f3f8083031ca88080b90258608060405234801561001057600080fd5b5060405161001d906100e3565b604051809103906000f080158015610039573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b039290921691821781556040517fc66247bafd1305823857fb4c3e651e684d918df8554ef560bbbcb025fdd017039190a26000546040516360fe47b160e01b8152600560048201526001600160a01b03909116906360fe47b190602401600060405180830381600087803b1580156100c657600080fd5b505af11580156100da573d6000803e3d6000fd5b505050506100ef565b60ca8061018e83390190565b6091806100fd6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806380de699314602d575b600080fd5b600054603f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f3fea2646970667358221220dab781465e7f4cf20304cc388130a763508e20edd25b4bc8ea8f57743a0de8da64736f6c634300081700336080604052348015600f57600080fd5b5060ac8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146049575b600080fd5b60476042366004605e565b600055565b005b60005460405190815260200160405180910390f35b600060208284031215606f57600080fd5b503591905056fea264697066735822122049e09da6320793487d58eaa7b97f802618a062cbc35f08ca1ce92c17349141f864736f6c63430008170033c080a01d4fce93ad08bf413052645721f20e6136830cf5a2759fa57e76a134e90899a7a0399a72832d52118991dc04c4f9e1c0fec3d5e441ad7d4b055f0cf03130d8f815", + "result": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x5208" + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0x8ac7230489e80000" + } + } +} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json index a34d3b759e..64a3b16cb1 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json @@ -10,7 +10,6 @@ "number": "243825", "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf", "timestamp": "1442424328", - "totalDifficulty": "1035061827427752845", "alloc": { "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { "balance": "0xc820f93200f4000", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_post_eip158.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_post_eip158.json new file mode 100644 index 0000000000..78e4a887f1 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_post_eip158.json @@ -0,0 +1,64 @@ +{ + "genesis": { + "baseFeePerGas": "7", + "difficulty": "2", + "extraData": "0xd983010d0e846765746888676f312e32312e318664617277696e0000000000001713699f05f79a59abec177c7a87b90ceda79b72ff5edc9197dd7627a447cde45b079bbc3765a236cdf680e2d4d2247135d0e6bb6fd92b50638b92504ddb274f00", + "gasLimit": "30000000", + "hash": "0x6ad5258175c66f4e883d238a92a08428d8ebcbeac631ab7b972634cc05effab3", + "miner": "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": "39137", + "stateRoot": "0x715f00df764dbadd4863247a215ac44b5420beafde3ec458b15db7aafa89be0c", + "timestamp": "1709022192", + "alloc": { + "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { + "balance": "0x10f06447a8d44dba190", + "nonce": "2" + }, + "0x82211934c340b29561381392348d48413e15adc8": { + "balance": "0x6abd7a808913ed2", + "nonce": "64" + } + }, + "config": { + "chainId": 12345, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "clique": { + "period": 5, + "epoch": 30000 + } + } + }, + "context": { + "number": "39138", + "difficulty": "2", + "timestamp": "1709022197", + "gasLimit": "30000000", + "miner": "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0", + "baseFeePerGas": "7" + }, + "input": "0x02f902af823039408459682f008459682f088302b3538080b90254608060405234801561001057600080fd5b50610234806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806309ce9ccb1461003b5780633fb5c1cb14610059575b600080fd5b610043610075565b60405161005091906100e2565b60405180910390f35b610073600480360381019061006e919061012e565b61007b565b005b60005481565b80600081905550600a8111156100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906101de565b60405180910390fd5b50565b6000819050919050565b6100dc816100c9565b82525050565b60006020820190506100f760008301846100d3565b92915050565b600080fd5b61010b816100c9565b811461011657600080fd5b50565b60008135905061012881610102565b92915050565b600060208284031215610144576101436100fd565b5b600061015284828501610119565b91505092915050565b600082825260208201905092915050565b7f4e756d6265722069732067726561746572207468616e2031302c207472616e7360008201527f616374696f6e2072657665727465642e00000000000000000000000000000000602082015250565b60006101c860308361015b565b91506101d38261016c565b604082019050919050565b600060208201905081810360008301526101f7816101bb565b905091905056fea264697066735822122069018995fecf03bda91a88b6eafe41641709dee8b4a706fe301c8a569fe8c1b364736f6c63430008130033c001a0a8cf4729b7e4664687abb3e2559853d7d489eb441519be2a17493061fb4c3a03a04b5a904ba8a6e59c6c40049c4d14a73233aeb8a45b38403199f304630dc0d453", + "result": { + "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { + "balance": "0x10f06447a8d44dba190", + "nonce": 2 + }, + "0x82211934c340b29561381392348d48413e15adc8": { + "balance": "0x6abd7a808913ed2", + "nonce": 64 + } + } +} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json index 7204bfcbfe..9811f87c4f 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json index 44b1f08dd3..a4cb3f60e4 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "result": { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json index 1b09622474..6eea6085b8 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json @@ -10,7 +10,6 @@ "number": "1061221", "stateRoot": "0x5402c04d481414248d824c3b61e924e0c9307adbc9fbaae774a74cce30a4163d", "timestamp": "1456458069", - "totalDifficulty": "7930751135586064334", "alloc": { "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { "balance": "0x9fb6b81e112638b886", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json index 561ead05b6..ae7f7e97f5 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json @@ -1,6 +1,6 @@ { "genesis": { - "baseFeePerGas": "51088069741", + "baseFeePerGas": "4573728117", "difficulty": "14315558652874667", "extraData": "0xd883010a10846765746888676f312e31362e35856c696e7578", "gasLimit": "30058590", @@ -64,7 +64,8 @@ "difficulty": "14322823549655084", "timestamp": "1651623279", "gasLimit": "30029237", - "miner": "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7" + "miner": "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7", + "baseFeePerGas": "4002012103" }, "input": "0x02f8b4018312acfc8459682f00851a46bcf47a8302b1a194ffa397285ce46fb78c588a9e993286aac68c37cd80b844fb90b3200000000000000000000000002a549b4af9ec39b03142da6dc32221fc390b553300000000000000000000000000000000000000000000000000000000000cb3d5c001a03002079d2873f7963c4278200c43aa71efad262b2150bc8524480acfc38b5faaa077d44aa09d56b9cf99443c7f55aaad1bbae9cfb5bbb9de31eaf7a8f9e623e980", "tracerConfig": { @@ -83,7 +84,7 @@ }, "post": { "0x808b4da0be6c9512e948521452227efc619bea52": { - "balance": "0x2cd987071ba2346b6", + "balance": "0x2cdb5f8e62cc9ad1c", "nonce": 1223933 }, "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json new file mode 100644 index 0000000000..19e1f08bb7 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json @@ -0,0 +1,82 @@ +{ + "genesis": { + "baseFeePerGas": "7", + "difficulty": "2", + "extraData": "0xd983010d0e846765746888676f312e32312e318664617277696e0000000000001713699f05f79a59abec177c7a87b90ceda79b72ff5edc9197dd7627a447cde45b079bbc3765a236cdf680e2d4d2247135d0e6bb6fd92b50638b92504ddb274f00", + "gasLimit": "30000000", + "hash": "0x6ad5258175c66f4e883d238a92a08428d8ebcbeac631ab7b972634cc05effab3", + "miner": "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": "39137", + "stateRoot": "0x715f00df764dbadd4863247a215ac44b5420beafde3ec458b15db7aafa89be0c", + "timestamp": "1709022192", + "alloc": { + "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { + "balance": "0x10f06447a8d44dba190", + "nonce": "2" + }, + "0x82211934c340b29561381392348d48413e15adc8": { + "balance": "0x6abd7a808913ed2", + "nonce": "64" + } + }, + "config": { + "chainId": 12345, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "clique": { + "period": 5, + "epoch": 30000 + } + } + }, + "context": { + "number": "39138", + "difficulty": "2", + "timestamp": "1709022197", + "gasLimit": "30000000", + "miner": "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0", + "baseFeePerGas": "7" + }, + "input": "0x02f902af823039408459682f008459682f088302b3538080b90254608060405234801561001057600080fd5b50610234806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806309ce9ccb1461003b5780633fb5c1cb14610059575b600080fd5b610043610075565b60405161005091906100e2565b60405180910390f35b610073600480360381019061006e919061012e565b61007b565b005b60005481565b80600081905550600a8111156100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906101de565b60405180910390fd5b50565b6000819050919050565b6100dc816100c9565b82525050565b60006020820190506100f760008301846100d3565b92915050565b600080fd5b61010b816100c9565b811461011657600080fd5b50565b60008135905061012881610102565b92915050565b600060208284031215610144576101436100fd565b5b600061015284828501610119565b91505092915050565b600082825260208201905092915050565b7f4e756d6265722069732067726561746572207468616e2031302c207472616e7360008201527f616374696f6e2072657665727465642e00000000000000000000000000000000602082015250565b60006101c860308361015b565b91506101d38261016c565b604082019050919050565b600060208201905081810360008301526101f7816101bb565b905091905056fea264697066735822122069018995fecf03bda91a88b6eafe41641709dee8b4a706fe301c8a569fe8c1b364736f6c63430008130033c001a0a8cf4729b7e4664687abb3e2559853d7d489eb441519be2a17493061fb4c3a03a04b5a904ba8a6e59c6c40049c4d14a73233aeb8a45b38403199f304630dc0d453", + "tracerConfig": { + "diffMode": true + }, + "result": { + "post": { + "0x1bda2f8e4735507930bd6cfe873bf0bf0f4ab1de": { + "code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806309ce9ccb1461003b5780633fb5c1cb14610059575b600080fd5b610043610075565b60405161005091906100e2565b60405180910390f35b610073600480360381019061006e919061012e565b61007b565b005b60005481565b80600081905550600a8111156100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906101de565b60405180910390fd5b50565b6000819050919050565b6100dc816100c9565b82525050565b60006020820190506100f760008301846100d3565b92915050565b600080fd5b61010b816100c9565b811461011657600080fd5b50565b60008135905061012881610102565b92915050565b600060208284031215610144576101436100fd565b5b600061015284828501610119565b91505092915050565b600082825260208201905092915050565b7f4e756d6265722069732067726561746572207468616e2031302c207472616e7360008201527f616374696f6e2072657665727465642e00000000000000000000000000000000602082015250565b60006101c860308361015b565b91506101d38261016c565b604082019050919050565b600060208201905081810360008301526101f7816101bb565b905091905056fea264697066735822122069018995fecf03bda91a88b6eafe41641709dee8b4a706fe301c8a569fe8c1b364736f6c63430008130033", + "nonce": 1 + }, + "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { + "balance": "0x10f0645688331eb5690" + }, + "0x82211934c340b29561381392348d48413e15adc8": { + "balance": "0x6aae9b21b6ee855", + "nonce": 65 + } + }, + "pre": { + "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { + "balance": "0x10f06447a8d44dba190", + "nonce": 2 + }, + "0x82211934c340b29561381392348d48413e15adc8": { + "balance": "0x6abd7a808913ed2", + "nonce": 64 + } + } + } +} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json index fdeb0e5067..cf8f03bd09 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json @@ -10,7 +10,6 @@ "number": "243825", "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf", "timestamp": "1442424328", - "totalDifficulty": "1035061827427752845", "alloc": { "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { "balance": "0xc820f93200f4000", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json index 9c0030a0a8..e6d6f2435b 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json @@ -10,7 +10,6 @@ "number": "1062502", "stateRoot": "0x1df615df5fdbc8d5397bf3574f462f6d9696428eb8796d8e9252bccc8e3a8996", "timestamp": "1456480432", - "totalDifficulty": "7948153536501153741", "alloc": { "0x0000000000000000000000000000000000000004": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json index 01cc3c5058..22932ebc95 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json @@ -52,8 +52,7 @@ "nonce": "0x4eb12e19c16d43da", "number": "2289805", "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" + "timestamp": "1513601261" }, "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", "tracerConfig": { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json index 5021bda192..3f07146871 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json @@ -10,7 +10,6 @@ "number": "422908", "stateRoot": "0xd914c6440edf9f4a6f997a9b3ecb6e1a9ca2310f74b0b6890c0d0d4a3c28e4d3", "timestamp": "1445530335", - "totalDifficulty": "2148894717741690476", "alloc": { "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": { "balance": "0x0", diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index 95d292c924..a74a96f8a4 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -1,67 +1,21 @@ package tracetest import ( + "math/big" "strings" "unicode" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/vm" + // Force-load native and js packages, to trigger registration _ "github.com/ethereum/go-ethereum/eth/tracers/js" _ "github.com/ethereum/go-ethereum/eth/tracers/native" ) -// To generate a new callTracer test, copy paste the makeTest method below into -// a Geth console and call it with a transaction hash you which to export. - -/* -// makeTest generates a callTracer test by running a prestate reassembled and a -// call trace run, assembling all the gathered information into a test case. -var makeTest = function(tx, rewind) { - // Generate the genesis block from the block, transaction and prestate data - var block = eth.getBlock(eth.getTransaction(tx).blockHash); - var genesis = eth.getBlock(block.parentHash); - - delete genesis.gasUsed; - delete genesis.logsBloom; - delete genesis.parentHash; - delete genesis.receiptsRoot; - delete genesis.sha3Uncles; - delete genesis.size; - delete genesis.transactions; - delete genesis.transactionsRoot; - delete genesis.uncles; - - genesis.gasLimit = genesis.gasLimit.toString(); - genesis.number = genesis.number.toString(); - genesis.timestamp = genesis.timestamp.toString(); - - genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind}); - for (var key in genesis.alloc) { - var nonce = genesis.alloc[key].nonce; - if (nonce) { - genesis.alloc[key].nonce = nonce.toString(); - } - } - genesis.config = admin.nodeInfo.protocols.eth.config; - - // Generate the call trace and produce the test input - var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind}); - delete result.time; - - console.log(JSON.stringify({ - genesis: genesis, - context: { - number: block.number.toString(), - difficulty: block.difficulty, - timestamp: block.timestamp.toString(), - gasLimit: block.gasLimit.toString(), - miner: block.miner, - }, - input: eth.getRawTransaction(tx), - result: result, - }, null, 2)); -} -*/ - // camel converts a snake cased input string into a camel cased output. func camel(str string) string { pieces := strings.Split(str, "_") @@ -70,3 +24,32 @@ func camel(str string) string { } return strings.Join(pieces, "") } + +type callContext struct { + Number math.HexOrDecimal64 `json:"number"` + Difficulty *math.HexOrDecimal256 `json:"difficulty"` + Time math.HexOrDecimal64 `json:"timestamp"` + GasLimit math.HexOrDecimal64 `json:"gasLimit"` + Miner common.Address `json:"miner"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` +} + +func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { + context := vm.BlockContext{ + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: c.Miner, + BlockNumber: new(big.Int).SetUint64(uint64(c.Number)), + Time: uint64(c.Time), + Difficulty: (*big.Int)(c.Difficulty), + GasLimit: uint64(c.GasLimit), + } + if genesis.Config.IsLondon(context.BlockNumber) { + context.BaseFee = (*big.Int)(c.BaseFee) + } + if genesis.ExcessBlobGas != nil && genesis.BlobGasUsed != nil { + excessBlobGas := eip4844.CalcExcessBlobGas(*genesis.ExcessBlobGas, *genesis.BlobGasUsed) + context.BlobBaseFee = eip4844.CalcBlobFee(excessBlobGas) + } + return context +} diff --git a/eth/tracers/internal/util.go b/eth/tracers/internal/util.go new file mode 100644 index 0000000000..347af43d51 --- /dev/null +++ b/eth/tracers/internal/util.go @@ -0,0 +1,81 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package internal + +import ( + "errors" + "fmt" + + "github.com/holiman/uint256" +) + +const ( + memoryPadLimit = 1024 * 1024 +) + +// GetMemoryCopyPadded returns offset + size as a new slice. +// It zero-pads the slice if it extends beyond memory bounds. +func GetMemoryCopyPadded(m []byte, offset, size int64) ([]byte, error) { + if offset < 0 || size < 0 { + return nil, errors.New("offset or size must not be negative") + } + length := int64(len(m)) + if offset+size < length { // slice fully inside memory + return memoryCopy(m, offset, size), nil + } + paddingNeeded := offset + size - length + if paddingNeeded > memoryPadLimit { + return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded) + } + cpy := make([]byte, size) + if overlap := length - offset; overlap > 0 { + copy(cpy, MemoryPtr(m, offset, overlap)) + } + return cpy, nil +} + +func memoryCopy(m []byte, offset, size int64) (cpy []byte) { + if size == 0 { + return nil + } + + if len(m) > int(offset) { + cpy = make([]byte, size) + copy(cpy, m[offset:offset+size]) + + return + } + + return +} + +// MemoryPtr returns a pointer to a slice of memory. +func MemoryPtr(m []byte, offset, size int64) []byte { + if size == 0 { + return nil + } + + if len(m) > int(offset) { + return m[offset : offset+size] + } + + return nil +} + +// StackBack returns the n'th item in stack +func StackBack(st []uint256.Int, n int) *uint256.Int { + return &st[len(st)-n-1] +} diff --git a/eth/tracers/internal/util_test.go b/eth/tracers/internal/util_test.go new file mode 100644 index 0000000000..6a467314cc --- /dev/null +++ b/eth/tracers/internal/util_test.go @@ -0,0 +1,60 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package internal + +import ( + "testing" + + "github.com/ethereum/go-ethereum/core/vm" +) + +func TestMemCopying(t *testing.T) { + for i, tc := range []struct { + memsize int64 + offset int64 + size int64 + wantErr string + wantSize int + }{ + {0, 0, 100, "", 100}, // Should pad up to 100 + {0, 100, 0, "", 0}, // No need to pad (0 size) + {100, 50, 100, "", 100}, // Should pad 100-150 + {100, 50, 5, "", 5}, // Wanted range fully within memory + {100, -50, 0, "offset or size must not be negative", 0}, // Error + {0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Error + {10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Error + + } { + mem := vm.NewMemory() + mem.Resize(uint64(tc.memsize)) + cpy, err := GetMemoryCopyPadded(mem.Data(), tc.offset, tc.size) + if want := tc.wantErr; want != "" { + if err == nil { + t.Fatalf("test %d: want '%v' have no error", i, want) + } + if have := err.Error(); want != have { + t.Fatalf("test %d: want '%v' have '%v'", i, want, have) + } + continue + } + if err != nil { + t.Fatalf("test %d: unexpected error: %v", i, err) + } + if want, have := tc.wantSize, len(cpy); have != want { + t.Fatalf("test %d: want %v have %v", i, want, have) + } + } +} diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index feeb45c649..4b2adc7e47 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -21,14 +21,19 @@ import ( "errors" "fmt" "math/big" + "slices" "github.com/dop251/goja" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/eth/tracers/internal" + "github.com/holiman/uint256" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth/tracers" jsassets "github.com/ethereum/go-ethereum/eth/tracers/js/internal/tracers" ) @@ -41,9 +46,9 @@ func init() { if err != nil { panic(err) } - type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error) + type ctorFn = func(*tracers.Context, json.RawMessage) (*tracers.Tracer, error) lookup := func(code string) ctorFn { - return func(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { + return func(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { return newJsTracer(code, ctx, cfg) } } @@ -96,7 +101,7 @@ func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value, allowString b // JS functions on the relevant EVM hooks. It uses Goja as its JS engine. type jsTracer struct { vm *goja.Runtime - env *vm.EVM + env *tracing.VMContext toBig toBigFn // Converts a hex string into a JS bigint toBuf toBufFn // Converts a []byte into a JS buffer fromBuf fromBufFn // Converts an array, hex string or Uint8Array to a []byte @@ -104,7 +109,6 @@ type jsTracer struct { activePrecompiles []common.Address // List of active precompiles at current block traceStep bool // True if tracer object exposes a `step()` method traceFrame bool // True if tracer object exposes the `enter()` and `exit()` methods - gasLimit uint64 // Amount of gas bought for the whole tx err error // Any error that should stop tracing obj *goja.Object // Trace object @@ -134,7 +138,7 @@ type jsTracer struct { // The methods `result` and `fault` are required to be present. // The methods `step`, `enter`, and `exit` are optional, but note that // `enter` and `exit` always go together. -func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { +func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { vm := goja.New() // By default field names are exported to JS as is, i.e. capitalized. vm.SetFieldNameMapper(goja.UncapFieldNameMapper()) @@ -217,32 +221,72 @@ func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracer t.frameValue = t.frame.setupObject() t.frameResultValue = t.frameResult.setupObject() t.logValue = t.log.setupObject() - return t, nil + + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil } -// CaptureTxStart implements the Tracer interface and is invoked at the beginning of +func (t *jsTracer) CaptureSystemTxEnd(intrinsicGas uint64) {} + +// OnTxStart implements the Tracer interface and is invoked at the beginning of // transaction processing. -func (t *jsTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit +func (t *jsTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + t.env = env + // Need statedb access for db object + db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf} + t.dbValue = db.setupObject() + // Update list of precompiles based on current block + rules := env.ChainConfig.Rules(env.BlockNumber, env.Random != nil, env.Time) + t.activePrecompiles = vm.ActivePrecompiles(rules) + t.ctx["block"] = t.vm.ToValue(t.env.BlockNumber.Uint64()) + t.ctx["gas"] = t.vm.ToValue(tx.Gas()) + gasPriceBig, err := t.toBig(t.vm, env.GasPrice.String()) + if err != nil { + t.err = err + return + } + t.ctx["gasPrice"] = gasPriceBig + coinbase, err := t.toBuf(t.vm, env.Coinbase.Bytes()) + if err != nil { + t.err = err + return + } + t.ctx["coinbase"] = t.vm.ToValue(coinbase) } -// CaptureTxEnd implements the Tracer interface and is invoked at the end of +// OnTxEnd implements the Tracer interface and is invoked at the end of // transaction processing. -func (t *jsTracer) CaptureTxEnd(restGas uint64) { - t.ctx["gasUsed"] = t.vm.ToValue(t.gasLimit - restGas) +func (t *jsTracer) OnTxEnd(receipt *types.Receipt, err error) { + if t.err != nil { + return + } + if err != nil { + // Don't override vm error + if _, ok := t.ctx["error"]; !ok { + t.ctx["error"] = t.vm.ToValue(err.Error()) + } + return + } + if receipt != nil { + t.ctx["gasUsed"] = t.vm.ToValue(receipt.GasUsed) + } } -func (t *jsTracer) CaptureSystemTxEnd(intrinsicGas uint64) {} - -// CaptureStart implements the Tracer interface to initialize the tracing operation. -func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - cancel := func(err error) { - t.err = err - t.env.Cancel() +// onStart implements the Tracer interface to initialize the tracing operation. +func (t *jsTracer) onStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { + if t.err != nil { + return } - t.env = env - db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf} - t.dbValue = db.setupObject() if create { t.ctx["type"] = t.vm.ToValue("CREATE") } else { @@ -250,43 +294,32 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr } fromVal, err := t.toBuf(t.vm, from.Bytes()) if err != nil { - cancel(err) + t.err = err return } t.ctx["from"] = fromVal toVal, err := t.toBuf(t.vm, to.Bytes()) if err != nil { - cancel(err) + t.err = err return } t.ctx["to"] = toVal inputVal, err := t.toBuf(t.vm, input) if err != nil { - cancel(err) + t.err = err return } t.ctx["input"] = inputVal - t.ctx["gas"] = t.vm.ToValue(t.gasLimit) - gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String()) - if err != nil { - cancel(err) - return - } - t.ctx["gasPrice"] = gasPriceBig valueBig, err := t.toBig(t.vm, value.String()) if err != nil { - cancel(err) + t.err = err return } t.ctx["value"] = valueBig - t.ctx["block"] = t.vm.ToValue(env.Context.BlockNumber.Uint64()) - // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time) - t.activePrecompiles = vm.ActivePrecompiles(rules) } -// CaptureState implements the Tracer interface to trace a single step of VM execution. -func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +// OnOpcode implements the Tracer interface to trace a single step of VM execution. +func (t *jsTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { if !t.traceStep { return } @@ -295,10 +328,10 @@ func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope } log := t.log - log.op.op = op - log.memory.memory = scope.Memory - log.stack.stack = scope.Stack - log.contract.contract = scope.Contract + log.op.op = vm.OpCode(op) + log.memory.memory = scope.MemoryData() + log.stack.stack = scope.StackData() + log.contract.scope = scope log.pc = pc log.gas = gas log.cost = cost @@ -310,20 +343,23 @@ func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope } } -// CaptureFault implements the Tracer interface to trace an execution fault -func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { +// OnFault implements the Tracer interface to trace an execution fault +func (t *jsTracer) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) { if t.err != nil { return } - // Other log fields have been already set as part of the last CaptureState. + // Other log fields have been already set as part of the last OnOpcode. t.log.err = err if _, err := t.fault(t.obj, t.logValue, t.dbValue); err != nil { t.onError("fault", err) } } -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { +// onEnd is called after the call finishes to finalize the tracing. +func (t *jsTracer) onEnd(output []byte, gasUsed uint64, err error, reverted bool) { + if t.err != nil { + return + } if err != nil { t.ctx["error"] = t.vm.ToValue(err.Error()) } @@ -335,16 +371,20 @@ func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { t.ctx["output"] = outputVal } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - if !t.traceFrame { +// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct). +func (t *jsTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if t.err != nil { return } - if t.err != nil { + if depth == 0 { + t.onStart(from, to, vm.OpCode(typ) == vm.CREATE, input, gas, value) + return + } + if !t.traceFrame { return } - t.frame.typ = typ.String() + t.frame.typ = vm.OpCode(typ).String() t.frame.from = from t.frame.to = to t.frame.input = common.CopyBytes(input) @@ -359,9 +399,16 @@ func (t *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Ad } } -// CaptureExit is called when EVM exits a scope, even if the scope didn't +// OnExit is called when EVM exits a scope, even if the scope didn't // execute any code. -func (t *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) { +func (t *jsTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if t.err != nil { + return + } + if depth == 0 { + t.onEnd(output, gasUsed, err, reverted) + return + } if !t.traceFrame { return } @@ -377,6 +424,9 @@ func (t *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) { // GetResult calls the Javascript 'result' function and returns its value, or any accumulated error func (t *jsTracer) GetResult() (json.RawMessage, error) { + if t.err != nil { + return nil, t.err + } ctx := t.vm.ToValue(t.ctx) res, err := t.result(t.obj, ctx, t.dbValue) if err != nil { @@ -386,7 +436,7 @@ func (t *jsTracer) GetResult() (json.RawMessage, error) { if err != nil { return nil, err } - return json.RawMessage(encoded), t.err + return encoded, t.err } // Stop terminates execution of the tracer at the first opportune moment. @@ -399,9 +449,6 @@ func (t *jsTracer) Stop(err error) { // execution. func (t *jsTracer) onError(context string, err error) { t.err = wrapError(context, err) - // `env` is set on CaptureStart which comes before any JS execution. - // So it should be non-nil. - t.env.Cancel() } func wrapError(context string, err error) error { @@ -493,13 +540,7 @@ func (t *jsTracer) setBuiltinFunctions() { vm.Interrupt(err) return false } - addr := common.BytesToAddress(a) - for _, p := range t.activePrecompiles { - if p == addr { - return true - } - } - return false + return slices.Contains(t.activePrecompiles, common.BytesToAddress(a)) }) vm.Set("slice", func(slice goja.Value, start, end int64) goja.Value { b, err := t.fromBuf(vm, slice, false) @@ -580,7 +621,7 @@ func (o *opObj) setupObject() *goja.Object { } type memoryObj struct { - memory *vm.Memory + memory []byte vm *goja.Runtime toBig toBigFn toBuf toBufFn @@ -608,7 +649,7 @@ func (mo *memoryObj) slice(begin, end int64) ([]byte, error) { if end < begin || begin < 0 { return nil, fmt.Errorf("tracer accessed out of bound memory: offset %d, end %d", begin, end) } - slice, err := tracers.GetMemoryCopyPadded(mo.memory, begin, end-begin) + slice, err := internal.GetMemoryCopyPadded(mo.memory, begin, end-begin) if err != nil { return nil, err } @@ -631,26 +672,26 @@ func (mo *memoryObj) GetUint(addr int64) goja.Value { // getUint returns the 32 bytes at the specified address interpreted as a uint. func (mo *memoryObj) getUint(addr int64) (*big.Int, error) { - if mo.memory.Len() < int(addr)+32 || addr < 0 { - return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", mo.memory.Len(), addr, 32) + if len(mo.memory) < int(addr)+32 || addr < 0 { + return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", len(mo.memory), addr, 32) } - return new(big.Int).SetBytes(mo.memory.GetPtr(addr, 32)), nil + return new(big.Int).SetBytes(internal.MemoryPtr(mo.memory, addr, 32)), nil } func (mo *memoryObj) Length() int { - return mo.memory.Len() + return len(mo.memory) } -func (m *memoryObj) setupObject() *goja.Object { - o := m.vm.NewObject() - o.Set("slice", m.vm.ToValue(m.Slice)) - o.Set("getUint", m.vm.ToValue(m.GetUint)) - o.Set("length", m.vm.ToValue(m.Length)) +func (mo *memoryObj) setupObject() *goja.Object { + o := mo.vm.NewObject() + o.Set("slice", mo.vm.ToValue(mo.Slice)) + o.Set("getUint", mo.vm.ToValue(mo.GetUint)) + o.Set("length", mo.vm.ToValue(mo.Length)) return o } type stackObj struct { - stack *vm.Stack + stack []uint256.Int vm *goja.Runtime toBig toBigFn } @@ -671,14 +712,14 @@ func (s *stackObj) Peek(idx int) goja.Value { // peek returns the nth-from-the-top element of the stack. func (s *stackObj) peek(idx int) (*big.Int, error) { - if len(s.stack.Data()) <= idx || idx < 0 { - return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack.Data()), idx) + if len(s.stack) <= idx || idx < 0 { + return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack), idx) } - return s.stack.Back(idx).ToBig(), nil + return internal.StackBack(s.stack, idx).ToBig(), nil } func (s *stackObj) Length() int { - return len(s.stack.Data()) + return len(s.stack) } func (s *stackObj) setupObject() *goja.Object { @@ -689,7 +730,7 @@ func (s *stackObj) setupObject() *goja.Object { } type dbObj struct { - db vm.StateDB + db tracing.StateDB vm *goja.Runtime toBig toBigFn toBuf toBufFn @@ -781,14 +822,14 @@ func (do *dbObj) setupObject() *goja.Object { } type contractObj struct { - contract *vm.Contract - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn + scope tracing.OpContext + vm *goja.Runtime + toBig toBigFn + toBuf toBufFn } func (co *contractObj) GetCaller() goja.Value { - caller := co.contract.Caller().Bytes() + caller := co.scope.Caller().Bytes() res, err := co.toBuf(co.vm, caller) if err != nil { co.vm.Interrupt(err) @@ -798,7 +839,7 @@ func (co *contractObj) GetCaller() goja.Value { } func (co *contractObj) GetAddress() goja.Value { - addr := co.contract.Address().Bytes() + addr := co.scope.Address().Bytes() res, err := co.toBuf(co.vm, addr) if err != nil { co.vm.Interrupt(err) @@ -808,7 +849,7 @@ func (co *contractObj) GetAddress() goja.Value { } func (co *contractObj) GetValue() goja.Value { - value := co.contract.Value() + value := co.scope.CallValue() res, err := co.toBig(co.vm, value.String()) if err != nil { co.vm.Interrupt(err) @@ -818,7 +859,7 @@ func (co *contractObj) GetValue() goja.Value { } func (co *contractObj) GetInput() goja.Value { - input := common.CopyBytes(co.contract.Input) + input := common.CopyBytes(co.scope.CallInput()) res, err := co.toBuf(co.vm, input) if err != nil { co.vm.Interrupt(err) @@ -827,12 +868,12 @@ func (co *contractObj) GetInput() goja.Value { return res } -func (c *contractObj) setupObject() *goja.Object { - o := c.vm.NewObject() - o.Set("getCaller", c.vm.ToValue(c.GetCaller)) - o.Set("getAddress", c.vm.ToValue(c.GetAddress)) - o.Set("getValue", c.vm.ToValue(c.GetValue)) - o.Set("getInput", c.vm.ToValue(c.GetInput)) +func (co *contractObj) setupObject() *goja.Object { + o := co.vm.NewObject() + o.Set("getCaller", co.vm.ToValue(co.GetCaller)) + o.Set("getAddress", co.vm.ToValue(co.GetAddress)) + o.Set("getValue", co.vm.ToValue(co.GetValue)) + o.Set("getInput", co.vm.ToValue(co.GetInput)) return o } diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 2e3d84661b..970f9ef161 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" @@ -61,9 +62,9 @@ func testCtx() *vmContext { return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}} } -func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) { +func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) { var ( - env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer}) + env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer.Hooks}) gasLimit uint64 = 31000 startGas uint64 = 10000 value = uint256.NewInt(0) @@ -74,12 +75,12 @@ func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCon contract.Code = contractCode } - tracer.CaptureTxStart(gasLimit) - tracer.CaptureStart(env, contract.Caller(), contract.Address(), false, []byte{}, startGas, value.ToBig()) + tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit}), contract.Caller()) + tracer.OnEnter(0, byte(vm.CALL), contract.Caller(), contract.Address(), []byte{}, startGas, value.ToBig()) ret, err := env.Interpreter().Run(contract, []byte{}, false) - tracer.CaptureEnd(ret, startGas-contract.Gas, err) + tracer.OnExit(0, ret, startGas-contract.Gas, err, true) // Rest gas assumes no refund - tracer.CaptureTxEnd(contract.Gas) + tracer.OnTxEnd(&types.Receipt{GasUsed: gasLimit - contract.Gas}, nil) if err != nil { return nil, err } @@ -153,6 +154,9 @@ func TestTracer(t *testing.T) { want: "", fail: "reached limit for padding memory slice: 1049568 at step (:1:83(20)) in server-side tracer function 'step'", contract: []byte{byte(vm.PUSH1), byte(0xff), byte(vm.PUSH1), byte(0x00), byte(vm.MSTORE8), byte(vm.STOP)}, + }, { // tests ctx.coinbase + code: "{lengths: [], step: function(log) { }, fault: function() {}, result: function(ctx) { var coinbase = ctx.coinbase; return toAddress(coinbase); }}", + want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`, }, } { if have, err := execTracer(tt.code, tt.contract); tt.want != string(have) || tt.fail != err { @@ -181,15 +185,16 @@ func TestHaltBetweenSteps(t *testing.T) { if err != nil { t.Fatal(err) } - env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) scope := &vm.ScopeContext{ Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), } - tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 0, big.NewInt(0)) - tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) + env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer.Hooks}) + tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{}) + tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 0, big.NewInt(0)) + tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil) timeout := errors.New("stahp") tracer.Stop(timeout) - tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) + tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil) if _, err := tracer.GetResult(); !strings.Contains(err.Error(), timeout.Error()) { t.Errorf("Expected timeout error, got %v", err) @@ -205,9 +210,10 @@ func TestNoStepExec(t *testing.T) { if err != nil { t.Fatal(err) } - env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) - tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 1000, big.NewInt(0)) - tracer.CaptureEnd(nil, 0, nil) + env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer.Hooks}) + tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{}) + tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 1000, big.NewInt(0)) + tracer.OnExit(0, nil, 0, nil, false) ret, err := tracer.GetResult() if err != nil { t.Fatal(err) @@ -276,8 +282,8 @@ func TestEnterExit(t *testing.T) { scope := &vm.ScopeContext{ Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), } - tracer.CaptureEnter(vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int)) - tracer.CaptureExit([]byte{}, 400, nil) + tracer.OnEnter(1, byte(vm.CALL), scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int)) + tracer.OnExit(1, []byte{}, 400, nil, false) have, err := tracer.GetResult() if err != nil { diff --git a/eth/tracers/live.go b/eth/tracers/live.go new file mode 100644 index 0000000000..ffb2303af4 --- /dev/null +++ b/eth/tracers/live.go @@ -0,0 +1,31 @@ +package tracers + +import ( + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/core/tracing" +) + +type ctorFunc func(config json.RawMessage) (*tracing.Hooks, error) + +// LiveDirectory is the collection of tracers which can be used +// during normal block import operations. +var LiveDirectory = liveDirectory{elems: make(map[string]ctorFunc)} + +type liveDirectory struct { + elems map[string]ctorFunc +} + +// Register registers a tracer constructor by name. +func (d *liveDirectory) Register(name string, f ctorFunc) { + d.elems[name] = f +} + +// New instantiates a tracer by name. +func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) { + if f, ok := d.elems[name]; ok { + return f(config) + } + return nil, errors.New("not found") +} diff --git a/eth/tracers/live/gen_supplyinfoburn.go b/eth/tracers/live/gen_supplyinfoburn.go new file mode 100644 index 0000000000..d01eda3975 --- /dev/null +++ b/eth/tracers/live/gen_supplyinfoburn.go @@ -0,0 +1,49 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package live + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var _ = (*supplyInfoBurnMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (s supplyInfoBurn) MarshalJSON() ([]byte, error) { + type supplyInfoBurn struct { + EIP1559 *hexutil.Big `json:"1559,omitempty"` + Blob *hexutil.Big `json:"blob,omitempty"` + Misc *hexutil.Big `json:"misc,omitempty"` + } + var enc supplyInfoBurn + enc.EIP1559 = (*hexutil.Big)(s.EIP1559) + enc.Blob = (*hexutil.Big)(s.Blob) + enc.Misc = (*hexutil.Big)(s.Misc) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (s *supplyInfoBurn) UnmarshalJSON(input []byte) error { + type supplyInfoBurn struct { + EIP1559 *hexutil.Big `json:"1559,omitempty"` + Blob *hexutil.Big `json:"blob,omitempty"` + Misc *hexutil.Big `json:"misc,omitempty"` + } + var dec supplyInfoBurn + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.EIP1559 != nil { + s.EIP1559 = (*big.Int)(dec.EIP1559) + } + if dec.Blob != nil { + s.Blob = (*big.Int)(dec.Blob) + } + if dec.Misc != nil { + s.Misc = (*big.Int)(dec.Misc) + } + return nil +} diff --git a/eth/tracers/live/gen_supplyinfoissuance.go b/eth/tracers/live/gen_supplyinfoissuance.go new file mode 100644 index 0000000000..e2536ee325 --- /dev/null +++ b/eth/tracers/live/gen_supplyinfoissuance.go @@ -0,0 +1,49 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package live + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var _ = (*supplyInfoIssuanceMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (s supplyInfoIssuance) MarshalJSON() ([]byte, error) { + type supplyInfoIssuance struct { + GenesisAlloc *hexutil.Big `json:"genesisAlloc,omitempty"` + Reward *hexutil.Big `json:"reward,omitempty"` + Withdrawals *hexutil.Big `json:"withdrawals,omitempty"` + } + var enc supplyInfoIssuance + enc.GenesisAlloc = (*hexutil.Big)(s.GenesisAlloc) + enc.Reward = (*hexutil.Big)(s.Reward) + enc.Withdrawals = (*hexutil.Big)(s.Withdrawals) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (s *supplyInfoIssuance) UnmarshalJSON(input []byte) error { + type supplyInfoIssuance struct { + GenesisAlloc *hexutil.Big `json:"genesisAlloc,omitempty"` + Reward *hexutil.Big `json:"reward,omitempty"` + Withdrawals *hexutil.Big `json:"withdrawals,omitempty"` + } + var dec supplyInfoIssuance + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.GenesisAlloc != nil { + s.GenesisAlloc = (*big.Int)(dec.GenesisAlloc) + } + if dec.Reward != nil { + s.Reward = (*big.Int)(dec.Reward) + } + if dec.Withdrawals != nil { + s.Withdrawals = (*big.Int)(dec.Withdrawals) + } + return nil +} diff --git a/eth/tracers/live/noop.go b/eth/tracers/live/noop.go new file mode 100644 index 0000000000..7433c28840 --- /dev/null +++ b/eth/tracers/live/noop.go @@ -0,0 +1,96 @@ +package live + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" +) + +func init() { + tracers.LiveDirectory.Register("noop", newNoopTracer) +} + +// noop is a no-op live tracer. It's there to +// catch changes in the tracing interface, as well as +// for testing live tracing performance. Can be removed +// as soon as we have a real live tracer. +type noop struct{} + +func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) { + t := &noop{} + return &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + OnGasChange: t.OnGasChange, + OnBlockchainInit: t.OnBlockchainInit, + OnBlockStart: t.OnBlockStart, + OnBlockEnd: t.OnBlockEnd, + OnSkippedBlock: t.OnSkippedBlock, + OnGenesisBlock: t.OnGenesisBlock, + OnBalanceChange: t.OnBalanceChange, + OnNonceChange: t.OnNonceChange, + OnCodeChange: t.OnCodeChange, + OnStorageChange: t.OnStorageChange, + OnLog: t.OnLog, + }, nil +} + +func (t *noop) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { +} + +func (t *noop) OnFault(pc uint64, op byte, gas, cost uint64, _ tracing.OpContext, depth int, err error) { +} + +func (t *noop) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +} + +func (t *noop) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { +} + +func (t *noop) OnTxStart(vm *tracing.VMContext, tx *types.Transaction, from common.Address) { +} + +func (t *noop) OnTxEnd(receipt *types.Receipt, err error) { +} + +func (t *noop) OnBlockStart(ev tracing.BlockEvent) { +} + +func (t *noop) OnBlockEnd(err error) { +} + +func (t *noop) OnSkippedBlock(ev tracing.BlockEvent) {} + +func (t *noop) OnBlockchainInit(chainConfig *params.ChainConfig) { +} + +func (t *noop) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) { +} + +func (t *noop) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { +} + +func (t *noop) OnNonceChange(a common.Address, prev, new uint64) { +} + +func (t *noop) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) { +} + +func (t *noop) OnStorageChange(a common.Address, k, prev, new common.Hash) { +} + +func (t *noop) OnLog(l *types.Log) { + +} + +func (t *noop) OnGasChange(old, new uint64, reason tracing.GasChangeReason) { +} diff --git a/eth/tracers/live/supply.go b/eth/tracers/live/supply.go new file mode 100644 index 0000000000..96f7059454 --- /dev/null +++ b/eth/tracers/live/supply.go @@ -0,0 +1,308 @@ +package live + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "path/filepath" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/log" + "gopkg.in/natefinch/lumberjack.v2" +) + +func init() { + tracers.LiveDirectory.Register("supply", newSupply) +} + +type supplyInfoIssuance struct { + GenesisAlloc *big.Int `json:"genesisAlloc,omitempty"` + Reward *big.Int `json:"reward,omitempty"` + Withdrawals *big.Int `json:"withdrawals,omitempty"` +} + +//go:generate go run github.com/fjl/gencodec -type supplyInfoIssuance -field-override supplyInfoIssuanceMarshaling -out gen_supplyinfoissuance.go +type supplyInfoIssuanceMarshaling struct { + GenesisAlloc *hexutil.Big + Reward *hexutil.Big + Withdrawals *hexutil.Big +} + +type supplyInfoBurn struct { + EIP1559 *big.Int `json:"1559,omitempty"` + Blob *big.Int `json:"blob,omitempty"` + Misc *big.Int `json:"misc,omitempty"` +} + +//go:generate go run github.com/fjl/gencodec -type supplyInfoBurn -field-override supplyInfoBurnMarshaling -out gen_supplyinfoburn.go +type supplyInfoBurnMarshaling struct { + EIP1559 *hexutil.Big + Blob *hexutil.Big + Misc *hexutil.Big +} + +type supplyInfo struct { + Issuance *supplyInfoIssuance `json:"issuance,omitempty"` + Burn *supplyInfoBurn `json:"burn,omitempty"` + + // Block info + Number uint64 `json:"blockNumber"` + Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash"` +} + +type supplyTxCallstack struct { + calls []supplyTxCallstack + burn *big.Int +} + +type supply struct { + delta supplyInfo + txCallstack []supplyTxCallstack // Callstack for current transaction + logger *lumberjack.Logger +} + +type supplyTracerConfig struct { + Path string `json:"path"` // Path to the directory where the tracer logs will be stored + MaxSize int `json:"maxSize"` // MaxSize is the maximum size in megabytes of the tracer log file before it gets rotated. It defaults to 100 megabytes. +} + +func newSupply(cfg json.RawMessage) (*tracing.Hooks, error) { + var config supplyTracerConfig + if cfg != nil { + if err := json.Unmarshal(cfg, &config); err != nil { + return nil, fmt.Errorf("failed to parse config: %v", err) + } + } + if config.Path == "" { + return nil, errors.New("supply tracer output path is required") + } + + // Store traces in a rotating file + logger := &lumberjack.Logger{ + Filename: filepath.Join(config.Path, "supply.jsonl"), + } + if config.MaxSize > 0 { + logger.MaxSize = config.MaxSize + } + + t := &supply{ + delta: newSupplyInfo(), + logger: logger, + } + return &tracing.Hooks{ + OnBlockStart: t.OnBlockStart, + OnBlockEnd: t.OnBlockEnd, + OnGenesisBlock: t.OnGenesisBlock, + OnTxStart: t.OnTxStart, + OnBalanceChange: t.OnBalanceChange, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnClose: t.OnClose, + }, nil +} + +func newSupplyInfo() supplyInfo { + return supplyInfo{ + Issuance: &supplyInfoIssuance{ + GenesisAlloc: big.NewInt(0), + Reward: big.NewInt(0), + Withdrawals: big.NewInt(0), + }, + Burn: &supplyInfoBurn{ + EIP1559: big.NewInt(0), + Blob: big.NewInt(0), + Misc: big.NewInt(0), + }, + + Number: 0, + Hash: common.Hash{}, + ParentHash: common.Hash{}, + } +} + +func (s *supply) resetDelta() { + s.delta = newSupplyInfo() +} + +func (s *supply) OnBlockStart(ev tracing.BlockEvent) { + s.resetDelta() + + s.delta.Number = ev.Block.NumberU64() + s.delta.Hash = ev.Block.Hash() + s.delta.ParentHash = ev.Block.ParentHash() + + // Calculate Burn for this block + if ev.Block.BaseFee() != nil { + burn := new(big.Int).Mul(new(big.Int).SetUint64(ev.Block.GasUsed()), ev.Block.BaseFee()) + s.delta.Burn.EIP1559 = burn + } + // Blob burnt gas + if blobGas := ev.Block.BlobGasUsed(); blobGas != nil && *blobGas > 0 && ev.Block.ExcessBlobGas() != nil { + var ( + excess = *ev.Block.ExcessBlobGas() + baseFee = eip4844.CalcBlobFee(excess) + burn = new(big.Int).Mul(new(big.Int).SetUint64(*blobGas), baseFee) + ) + s.delta.Burn.Blob = burn + } +} + +func (s *supply) OnBlockEnd(err error) { + s.write(s.delta) +} + +func (s *supply) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) { + s.resetDelta() + + s.delta.Number = b.NumberU64() + s.delta.Hash = b.Hash() + s.delta.ParentHash = b.ParentHash() + + // Initialize supply with total allocation in genesis block + for _, account := range alloc { + s.delta.Issuance.GenesisAlloc.Add(s.delta.Issuance.GenesisAlloc, account.Balance) + } + + s.write(s.delta) +} + +func (s *supply) OnBalanceChange(a common.Address, prevBalance, newBalance *big.Int, reason tracing.BalanceChangeReason) { + diff := new(big.Int).Sub(newBalance, prevBalance) + + // NOTE: don't handle "BalanceIncreaseGenesisBalance" because it is handled in OnGenesisBlock + switch reason { + case tracing.BalanceIncreaseRewardMineUncle: + case tracing.BalanceIncreaseRewardMineBlock: + s.delta.Issuance.Reward.Add(s.delta.Issuance.Reward, diff) + case tracing.BalanceIncreaseWithdrawal: + s.delta.Issuance.Withdrawals.Add(s.delta.Issuance.Withdrawals, diff) + case tracing.BalanceDecreaseSelfdestructBurn: + // BalanceDecreaseSelfdestructBurn is non-reversible as it happens + // at the end of the transaction. + s.delta.Burn.Misc.Sub(s.delta.Burn.Misc, diff) + default: + return + } +} + +func (s *supply) OnTxStart(vm *tracing.VMContext, tx *types.Transaction, from common.Address) { + s.txCallstack = make([]supplyTxCallstack, 0, 1) +} + +// internalTxsHandler handles internal transactions burned amount +func (s *supply) internalTxsHandler(call *supplyTxCallstack) { + // Handle Burned amount + if call.burn != nil { + s.delta.Burn.Misc.Add(s.delta.Burn.Misc, call.burn) + } + + // Recursively handle internal calls + for _, call := range call.calls { + callCopy := call + s.internalTxsHandler(&callCopy) + } +} + +func (s *supply) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + call := supplyTxCallstack{ + calls: make([]supplyTxCallstack, 0), + } + + // This is a special case of burned amount which has to be handled here + // which happens when type == selfdestruct and from == to. + if vm.OpCode(typ) == vm.SELFDESTRUCT && from == to && value.Cmp(common.Big0) == 1 { + call.burn = value + } + + // Append call to the callstack, so we can fill the details in CaptureExit + s.txCallstack = append(s.txCallstack, call) +} + +func (s *supply) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth == 0 { + // No need to handle Burned amount if transaction is reverted + if !reverted { + s.internalTxsHandler(&s.txCallstack[0]) + } + return + } + + size := len(s.txCallstack) + if size <= 1 { + return + } + // Pop call + call := s.txCallstack[size-1] + s.txCallstack = s.txCallstack[:size-1] + size -= 1 + + // In case of a revert, we can drop the call and all its subcalls. + // Caution, that this has to happen after popping the call from the stack. + if reverted { + return + } + s.txCallstack[size-1].calls = append(s.txCallstack[size-1].calls, call) +} + +func (s *supply) OnClose() { + if err := s.logger.Close(); err != nil { + log.Warn("failed to close supply tracer log file", "error", err) + } +} + +func (s *supply) write(data any) { + supply, ok := data.(supplyInfo) + if !ok { + log.Warn("failed to cast supply tracer data on write to log file") + return + } + + // Remove empty fields + if supply.Issuance.GenesisAlloc.Sign() == 0 { + supply.Issuance.GenesisAlloc = nil + } + + if supply.Issuance.Reward.Sign() == 0 { + supply.Issuance.Reward = nil + } + + if supply.Issuance.Withdrawals.Sign() == 0 { + supply.Issuance.Withdrawals = nil + } + + if supply.Issuance.GenesisAlloc == nil && supply.Issuance.Reward == nil && supply.Issuance.Withdrawals == nil { + supply.Issuance = nil + } + + if supply.Burn.EIP1559.Sign() == 0 { + supply.Burn.EIP1559 = nil + } + + if supply.Burn.Blob.Sign() == 0 { + supply.Burn.Blob = nil + } + + if supply.Burn.Misc.Sign() == 0 { + supply.Burn.Misc = nil + } + + if supply.Burn.EIP1559 == nil && supply.Burn.Blob == nil && supply.Burn.Misc == nil { + supply.Burn = nil + } + + out, _ := json.Marshal(supply) + if _, err := s.logger.Write(out); err != nil { + log.Warn("failed to write to supply tracer log file", "error", err) + } + if _, err := s.logger.Write([]byte{'\n'}); err != nil { + log.Warn("failed to write to supply tracer log file", "error", err) + } +} diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index 91a2428d79..f1280797d3 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -17,9 +17,10 @@ package logger import ( - "math/big" + "maps" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) @@ -72,22 +73,14 @@ func (al accessList) equal(other accessList) bool { // Accounts match, cross reference the storage slots too for addr, slots := range al { otherslots := other[addr] - - if len(slots) != len(otherslots) { + if !maps.Equal(slots, otherslots) { return false } - // Given that len(slots) == len(otherslots), we only need to check that - // all the items from slots are in otherslots. - for hash := range slots { - if _, ok := otherslots[hash]; !ok { - return false - } - } } return true } -// accesslist converts the accesslist to a types.AccessList. +// accessList converts the accesslist to a types.AccessList. func (al accessList) accessList() types.AccessList { acl := make(types.AccessList, 0, len(al)) for addr, slots := range al { @@ -132,17 +125,20 @@ func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompi } } -func (a *AccessListTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +func (a *AccessListTracer) Hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnOpcode: a.OnOpcode, + } } -// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist. -func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - stack := scope.Stack - stackData := stack.Data() +// OnOpcode captures all opcodes that touch storage or addresses and adds them to the accesslist. +func (a *AccessListTracer) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + stackData := scope.StackData() stackLen := len(stackData) + op := vm.OpCode(opcode) if (op == vm.SLOAD || op == vm.SSTORE) && stackLen >= 1 { slot := common.Hash(stackData[stackLen-1].Bytes32()) - a.list.addSlot(scope.Contract.Address(), slot) + a.list.addSlot(scope.Address(), slot) } if (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT) && stackLen >= 1 { addr := common.Address(stackData[stackLen-1].Bytes20()) @@ -158,20 +154,6 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6 } } -func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {} - -func (*AccessListTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (*AccessListTracer) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (*AccessListTracer) CaptureTxStart(gasLimit uint64) {} - -func (*AccessListTracer) CaptureTxEnd(restGas uint64) {} - func (*AccessListTracer) CaptureSystemTxEnd(intrinsicGas uint64) {} // AccessList returns the current accesslist maintained by the tracer. diff --git a/eth/tracers/logger/gen_callframe.go b/eth/tracers/logger/gen_callframe.go new file mode 100644 index 0000000000..b7b2cc2881 --- /dev/null +++ b/eth/tracers/logger/gen_callframe.go @@ -0,0 +1,65 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package logger + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" +) + +var _ = (*callFrameMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (c callFrame) MarshalJSON() ([]byte, error) { + type callFrame struct { + From common.Address `json:"from"` + To common.Address `json:"to"` + Input hexutil.Bytes `json:"input,omitempty"` + Gas math.HexOrDecimal64 `json:"gas"` + Value *hexutil.Big `json:"value"` + Type string `json:"type"` + } + var enc callFrame + enc.From = c.From + enc.To = c.To + enc.Input = c.Input + enc.Gas = math.HexOrDecimal64(c.Gas) + enc.Value = (*hexutil.Big)(c.Value) + enc.Type = c.Type() + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (c *callFrame) UnmarshalJSON(input []byte) error { + type callFrame struct { + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Input *hexutil.Bytes `json:"input,omitempty"` + Gas *math.HexOrDecimal64 `json:"gas"` + Value *hexutil.Big `json:"value"` + } + var dec callFrame + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.From != nil { + c.From = *dec.From + } + if dec.To != nil { + c.To = *dec.To + } + if dec.Input != nil { + c.Input = *dec.Input + } + if dec.Gas != nil { + c.Gas = uint64(*dec.Gas) + } + if dec.Value != nil { + c.Value = (*big.Int)(dec.Value) + } + return nil +} diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 6f3a20f9c0..7a901c83e7 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -108,14 +109,13 @@ func (s *StructLog) ErrorString() string { // contract their storage. type StructLogger struct { cfg Config - env *vm.EVM + env *tracing.VMContext - storage map[common.Address]Storage - logs []StructLog - output []byte - err error - gasLimit uint64 - usedGas uint64 + storage map[common.Address]Storage + logs []StructLog + output []byte + err error + usedGas uint64 interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption @@ -132,6 +132,15 @@ func NewStructLogger(cfg *Config) *StructLogger { return logger } +func (l *StructLogger) Hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnTxStart: l.OnTxStart, + OnTxEnd: l.OnTxEnd, + OnExit: l.OnExit, + OnOpcode: l.OnOpcode, + } +} + // Reset clears the data held by the logger. func (l *StructLogger) Reset() { l.storage = make(map[common.Address]Storage) @@ -140,15 +149,10 @@ func (l *StructLogger) Reset() { l.err = nil } -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - l.env = env -} - -// CaptureState logs a new structured log message and pushes it out to the environment +// OnOpcode logs a new structured log message and pushes it out to the environment // -// CaptureState also tracks SLOAD/SSTORE ops to track storage change. -func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +// OnOpcode also tracks SLOAD/SSTORE ops to track storage change. +func (l *StructLogger) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { // If tracing was interrupted, set the error and stop if l.interrupt.Load() { return @@ -158,49 +162,47 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s return } - memory := scope.Memory - stack := scope.Stack - contract := scope.Contract + op := vm.OpCode(opcode) + memory := scope.MemoryData() + stack := scope.StackData() // Copy a snapshot of the current memory state to a new buffer var mem []byte if l.cfg.EnableMemory { - mem = make([]byte, len(memory.Data())) - copy(mem, memory.Data()) + mem = make([]byte, len(memory)) + copy(mem, memory) } // Copy a snapshot of the current stack state to a new buffer var stck []uint256.Int if !l.cfg.DisableStack { - stck = make([]uint256.Int, len(stack.Data())) - for i, item := range stack.Data() { - stck[i] = item - } + stck = make([]uint256.Int, len(stack)) + copy(stck, stack) } - stackData := stack.Data() - stackLen := len(stackData) + contractAddr := scope.Address() + stackLen := len(stack) // Copy a snapshot of the current storage to a new container var storage Storage if !l.cfg.DisableStorage && (op == vm.SLOAD || op == vm.SSTORE) { // initialise new changed values storage container for this contract // if not present. - if l.storage[contract.Address()] == nil { - l.storage[contract.Address()] = make(Storage) + if l.storage[contractAddr] == nil { + l.storage[contractAddr] = make(Storage) } // capture SLOAD opcodes and record the read entry in the local storage if op == vm.SLOAD && stackLen >= 1 { var ( - address = common.Hash(stackData[stackLen-1].Bytes32()) - value = l.env.StateDB.GetState(contract.Address(), address) + address = common.Hash(stack[stackLen-1].Bytes32()) + value = l.env.StateDB.GetState(contractAddr, address) ) - l.storage[contract.Address()][address] = value - storage = l.storage[contract.Address()].Copy() + l.storage[contractAddr][address] = value + storage = l.storage[contractAddr].Copy() } else if op == vm.SSTORE && stackLen >= 2 { // capture SSTORE opcodes and record the written entry in the local storage. var ( - value = common.Hash(stackData[stackLen-2].Bytes32()) - address = common.Hash(stackData[stackLen-1].Bytes32()) + value = common.Hash(stack[stackLen-2].Bytes32()) + address = common.Hash(stack[stackLen-1].Bytes32()) ) - l.storage[contract.Address()][address] = value - storage = l.storage[contract.Address()].Copy() + l.storage[contractAddr][address] = value + storage = l.storage[contractAddr].Copy() } } var rdata []byte @@ -209,17 +211,15 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s copy(rdata, rData) } // create a new snapshot of the EVM. - log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err} + log := StructLog{pc, op, gas, cost, mem, len(memory), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err} l.logs = append(l.logs, log) } -// CaptureFault implements the EVMLogger interface to trace an execution fault -// while running an opcode. -func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { +// OnExit is called a call frame finishes processing. +func (l *StructLogger) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth != 0 { + return + } l.output = output l.err = err if l.cfg.Debug { @@ -230,12 +230,6 @@ func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { } } -func (l *StructLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) { -} - func (l *StructLogger) GetResult() (json.RawMessage, error) { // Tracing aborted if l.reason != nil { @@ -262,12 +256,21 @@ func (l *StructLogger) Stop(err error) { l.interrupt.Store(true) } -func (l *StructLogger) CaptureTxStart(gasLimit uint64) { - l.gasLimit = gasLimit +func (l *StructLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + l.env = env } -func (l *StructLogger) CaptureTxEnd(restGas uint64) { - l.usedGas = l.gasLimit - restGas +func (l *StructLogger) OnTxEnd(receipt *types.Receipt, err error) { + if err != nil { + // Don't override vm error + if l.err == nil { + l.err = err + } + return + } + if receipt != nil { + l.usedGas = receipt.GasUsed + } } func (l *StructLogger) CaptureSystemTxEnd(intrinsicGas uint64) { @@ -333,7 +336,7 @@ func WriteLogs(writer io.Writer, logs []*types.Log) { type mdLogger struct { out io.Writer cfg *Config - env *vm.EVM + env *tracing.VMContext } // NewMarkdownLogger creates a logger which outputs information in a format adapted @@ -346,8 +349,25 @@ func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger { return l } -func (t *mdLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +func (t *mdLogger) Hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + } +} + +func (t *mdLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { t.env = env +} + +func (t *mdLogger) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if depth != 0 { + return + } + create := vm.OpCode(typ) == vm.CREATE if !create { fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `%#x`\nGas: `%d`\nValue `%v` wei\n", from.String(), to.String(), @@ -364,15 +384,22 @@ func (t *mdLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Addr `) } -// CaptureState also tracks SLOAD/SSTORE ops to track storage change. -func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - stack := scope.Stack - fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost) +func (t *mdLogger) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth == 0 { + fmt.Fprintf(t.out, "\nOutput: `%#x`\nConsumed gas: `%d`\nError: `%v`\n", + output, gasUsed, err) + } +} + +// OnOpcode also tracks SLOAD/SSTORE ops to track storage change. +func (t *mdLogger) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + stack := scope.StackData() + fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, vm.OpCode(op).String(), cost) if !t.cfg.DisableStack { // format stack var a []string - for _, elem := range stack.Data() { + for _, elem := range stack { a = append(a, elem.Hex()) } b := fmt.Sprintf("[%v]", strings.Join(a, ",")) @@ -385,24 +412,10 @@ func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope } } -func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { +func (t *mdLogger) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) { fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) } -func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { - fmt.Fprintf(t.out, "\nOutput: `%#x`\nConsumed gas: `%d`\nError: `%v`\n", - output, gasUsed, err) -} - -func (t *mdLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (t *mdLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (*mdLogger) CaptureTxStart(gasLimit uint64) {} - -func (*mdLogger) CaptureTxEnd(restGas uint64) {} - func (*mdLogger) CaptureSystemTxEnd(intrinsicGas uint64) {} // ExecutionResult groups all structured logs emitted by the EVM diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index fe56c21a7a..be63cd87f9 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -22,55 +22,104 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) -type JSONLogger struct { +//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe.go + +// overrides for gencodec +type callFrameMarshaling struct { + Input hexutil.Bytes + Gas math.HexOrDecimal64 + Value *hexutil.Big + Type string `json:"type"` // adds call to Type() in MarshalJSON +} + +// callFrame is emitted every call frame entered. +type callFrame struct { + op vm.OpCode + From common.Address `json:"from"` + To common.Address `json:"to"` + Input []byte `json:"input,omitempty"` + Gas uint64 `json:"gas"` + Value *big.Int `json:"value"` +} + +// Type formats the call type in a human-readable format. +func (c *callFrame) Type() string { + return c.op.String() +} + +type jsonLogger struct { encoder *json.Encoder cfg *Config - env *vm.EVM + env *tracing.VMContext + hooks *tracing.Hooks } // NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects // into the provided stream. -func NewJSONLogger(cfg *Config, writer io.Writer) *JSONLogger { - l := &JSONLogger{encoder: json.NewEncoder(writer), cfg: cfg} +func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.Hooks { + l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} if l.cfg == nil { l.cfg = &Config{} } - return l + l.hooks = &tracing.Hooks{ + OnTxStart: l.OnTxStart, + OnSystemCallStart: l.onSystemCallStart, + OnExit: l.OnEnd, + OnOpcode: l.OnOpcode, + OnFault: l.OnFault, + } + return l.hooks } -func (l *JSONLogger) CaptureStart(env *vm.EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - l.env = env +// NewJSONLoggerWithCallFrames creates a new EVM tracer that prints execution steps as JSON objects +// into the provided stream. It also includes call frames in the output. +func NewJSONLoggerWithCallFrames(cfg *Config, writer io.Writer) *tracing.Hooks { + l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} + if l.cfg == nil { + l.cfg = &Config{} + } + l.hooks = &tracing.Hooks{ + OnTxStart: l.OnTxStart, + OnSystemCallStart: l.onSystemCallStart, + OnEnter: l.OnEnter, + OnExit: l.OnExit, + OnOpcode: l.OnOpcode, + OnFault: l.OnFault, + } + return l.hooks } -func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost uint64, scope *vm.ScopeContext, depth int, err error) { +func (l *jsonLogger) OnFault(pc uint64, op byte, gas uint64, cost uint64, scope tracing.OpContext, depth int, err error) { // TODO: Add rData to this interface as well - l.CaptureState(pc, op, gas, cost, scope, nil, depth, err) + l.OnOpcode(pc, op, gas, cost, scope, nil, depth, err) } -// CaptureState outputs state information on the logger. -func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - memory := scope.Memory - stack := scope.Stack +func (l *jsonLogger) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + memory := scope.MemoryData() + stack := scope.StackData() log := StructLog{ Pc: pc, - Op: op, + Op: vm.OpCode(op), Gas: gas, GasCost: cost, - MemorySize: memory.Len(), + MemorySize: len(memory), Depth: depth, RefundCounter: l.env.StateDB.GetRefund(), Err: err, } if l.cfg.EnableMemory { - log.Memory = memory.Data() + log.Memory = memory } if !l.cfg.DisableStack { - log.Stack = stack.Data() + log.Stack = stack } if l.cfg.EnableReturnData { log.ReturnData = rData @@ -78,8 +127,39 @@ func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco l.encoder.Encode(log) } -// CaptureEnd is triggered at end of execution. -func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { +func (l *jsonLogger) onSystemCallStart() { + // Process no events while in system call. + hooks := *l.hooks + *l.hooks = tracing.Hooks{ + OnSystemCallEnd: func() { + *l.hooks = hooks + }, + } +} + +// OnEnter is not enabled by default. +func (l *jsonLogger) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + frame := callFrame{ + op: vm.OpCode(typ), + From: from, + To: to, + Gas: gas, + Value: value, + } + if l.cfg.EnableMemory { + frame.Input = input + } + l.encoder.Encode(frame) +} + +func (l *jsonLogger) OnEnd(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth > 0 { + return + } + l.OnExit(depth, output, gasUsed, err, false) +} + +func (l *jsonLogger) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { type endLog struct { Output string `json:"output"` GasUsed math.HexOrDecimal64 `json:"gasUsed"` @@ -92,13 +172,8 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), errMsg}) } -func (l *JSONLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (l *jsonLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + l.env = env } -func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {} - -func (l *JSONLogger) CaptureTxEnd(restGas uint64) {} - -func (l *JSONLogger) CaptureSystemTxEnd(intrinsicGas uint64) {} +func (l *jsonLogger) CaptureSystemTxEnd(intrinsicGas uint64) {} diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go index 1d8eb320f6..137608f884 100644 --- a/eth/tracers/logger/logger_test.go +++ b/eth/tracers/logger/logger_test.go @@ -56,12 +56,12 @@ func (*dummyStatedb) SetState(_ common.Address, _ common.Hash, _ common.Hash) {} func TestStoreCapture(t *testing.T) { var ( logger = NewStructLogger(nil) - env = vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger}) + env = vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()}) contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 100000) ) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)} var index common.Hash - logger.CaptureStart(env, common.Address{}, contract.Address(), false, nil, 0, nil) + logger.OnTxStart(env.GetVMContext(), nil, common.Address{}) _, err := env.Interpreter().Run(contract, []byte{}, false) if err != nil { t.Fatal(err) diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 79b9339069..08c217b02e 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -23,6 +23,8 @@ import ( "sync/atomic" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" ) @@ -46,20 +48,26 @@ func init() { // 0xc281d19e-0: 1 // } type fourByteTracer struct { - noopTracer ids map[string]int // ids aggregates the 4byte ids found interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption - activePrecompiles []common.Address // Updated on CaptureStart based on given rules + activePrecompiles []common.Address // Updated on tx start based on given rules } // newFourByteTracer returns a native go tracer which collects // 4 byte-identifiers of a tx, and implements vm.EVMLogger. -func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { +func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) { t := &fourByteTracer{ ids: make(map[string]int), } - return t, nil + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnEnter: t.OnEnter, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil } // isPrecompiled returns whether the addr is a precompile. Logic borrowed from newJsTracer in eth/tracers/js/tracer.go @@ -78,20 +86,14 @@ func (t *fourByteTracer) store(id []byte, size int) { t.ids[key] += 1 } -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +func (t *fourByteTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time) + rules := env.ChainConfig.Rules(env.BlockNumber, env.Random != nil, env.Time) t.activePrecompiles = vm.ActivePrecompiles(rules) - - // Save the outer calldata also - if len(input) >= 4 { - t.store(input[0:4], len(input)-4) - } } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct). +func (t *fourByteTracer) OnEnter(depth int, opcode byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { // Skip if tracing was interrupted if t.interrupt.Load() { return @@ -99,6 +101,7 @@ func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to comm if len(input) < 4 { return } + op := vm.OpCode(opcode) // primarily we want to avoid CREATE/CREATE2/SELFDESTRUCT if op != vm.DELEGATECALL && op != vm.STATICCALL && op != vm.CALL && op != vm.CALLCODE { diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 0a22936784..1eb21f902a 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -25,9 +25,10 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" - "github.com/ethereum/go-ethereum/log" ) //go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go @@ -59,7 +60,8 @@ type callFrame struct { Logs []callLog `json:"logs,omitempty" rlp:"optional"` // Placed at end on purpose. The RLP will be decoded to 0 instead of // nil if there are non-empty elements after in the struct. - Value *big.Int `json:"value,omitempty" rlp:"optional"` + Value *big.Int `json:"value,omitempty" rlp:"optional"` + revertedSnapshot bool } func (f callFrame) TypeString() string { @@ -67,16 +69,22 @@ func (f callFrame) TypeString() string { } func (f callFrame) failed() bool { - return len(f.Error) > 0 + return len(f.Error) > 0 && f.revertedSnapshot } -func (f *callFrame) processOutput(output []byte, err error) { +func (f *callFrame) processOutput(output []byte, err error, reverted bool) { output = common.CopyBytes(output) + // Clear error if tx wasn't reverted. This happened + // for pre-homestead contract storage OOG. + if err != nil && !reverted { + err = nil + } if err == nil { f.Output = output return } f.Error = err.Error() + f.revertedSnapshot = reverted if f.Type == vm.CREATE || f.Type == vm.CREATE2 { f.To = nil } @@ -102,10 +110,10 @@ type callFrameMarshaling struct { } type callTracer struct { - noopTracer callstack []callFrame config callTracerConfig gasLimit uint64 + depth int interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption } @@ -117,7 +125,25 @@ type callTracerConfig struct { // newCallTracer returns a native go tracer which tracks // call frames of a tx, and implements vm.EVMLogger. -func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { +func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { + t, err := newCallTracerObject(ctx, cfg) + if err != nil { + return nil, err + } + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnLog: t.OnLog, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil +} + +func newCallTracerObject(ctx *tracers.Context, cfg json.RawMessage) (*callTracer, error) { var config callTracerConfig if cfg != nil { if err := json.Unmarshal(cfg, &config); err != nil { @@ -126,84 +152,13 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, e } // First callframe contains tx context info // and is populated on start and end. - return &callTracer{callstack: make([]callFrame, 1), config: config}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - toCopy := to - t.callstack[0] = callFrame{ - Type: vm.CALL, - From: from, - To: &toCopy, - Input: common.CopyBytes(input), - Gas: t.gasLimit, - Value: value, - } - if create { - t.callstack[0].Type = vm.CREATE - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - t.callstack[0].processOutput(output, err) -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - // skip if the previous op caused an error - if err != nil { - return - } - // Only logs need to be captured via opcode processing - if !t.config.WithLog { - return - } - // Avoid processing nested calls when only caring about top call - if t.config.OnlyTopCall && depth > 1 { - return - } - // Skip if tracing was interrupted - if t.interrupt.Load() { - return - } - switch op { - case vm.LOG0, vm.LOG1, vm.LOG2, vm.LOG3, vm.LOG4: - size := int(op - vm.LOG0) - - stack := scope.Stack - stackData := stack.Data() - - // Don't modify the stack - mStart := stackData[len(stackData)-1] - mSize := stackData[len(stackData)-2] - topics := make([]common.Hash, size) - for i := 0; i < size; i++ { - topic := stackData[len(stackData)-2-(i+1)] - topics[i] = common.Hash(topic.Bytes32()) - } - - data, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(mStart.Uint64()), int64(mSize.Uint64())) - if err != nil { - // mSize was unrealistically large - log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "callTracer", "offset", mStart, "size", mSize) - return - } - - log := callLog{ - Address: scope.Contract.Address(), - Topics: topics, - Data: hexutil.Bytes(data), - Position: hexutil.Uint(len(t.callstack[len(t.callstack)-1].Calls)), - } - t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log) - } + return &callTracer{callstack: make([]callFrame, 0, 1), config: config}, nil } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - if t.config.OnlyTopCall { +// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct). +func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + t.depth = depth + if t.config.OnlyTopCall && depth > 0 { return } // Skip if tracing was interrupted @@ -213,42 +168,66 @@ func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common. toCopy := to call := callFrame{ - Type: typ, + Type: vm.OpCode(typ), From: from, To: &toCopy, Input: common.CopyBytes(input), Gas: gas, Value: value, } + if depth == 0 { + call.Gas = t.gasLimit + } t.callstack = append(t.callstack, call) } -// CaptureExit is called when EVM exits a scope, even if the scope didn't +// OnExit is called when EVM exits a scope, even if the scope didn't // execute any code. -func (t *callTracer) CaptureExit(output []byte, gasUsed uint64, err error) { +func (t *callTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth == 0 { + t.captureEnd(output, gasUsed, err, reverted) + return + } + + t.depth = depth - 1 if t.config.OnlyTopCall { return } + size := len(t.callstack) if size <= 1 { return } - // pop call + // Pop call. call := t.callstack[size-1] t.callstack = t.callstack[:size-1] size -= 1 call.GasUsed = gasUsed - call.processOutput(output, err) + call.processOutput(output, err, reverted) + // Nest call into parent. t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call) } -func (t *callTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit +func (t *callTracer) captureEnd(output []byte, gasUsed uint64, err error, reverted bool) { + if len(t.callstack) != 1 { + return + } + t.callstack[0].processOutput(output, err, reverted) +} + +func (t *callTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + t.gasLimit = tx.Gas() } -func (t *callTracer) CaptureTxEnd(restGas uint64) { - t.callstack[0].GasUsed = t.gasLimit - restGas +func (t *callTracer) OnTxEnd(receipt *types.Receipt, err error) { + // Error happened during tx validation. + if err != nil { + return + } + if receipt != nil { + t.callstack[0].GasUsed = receipt.GasUsed + } if t.config.WithLog { // Logs are not emitted when the call fails clearFailedLogs(&t.callstack[0], false) @@ -259,6 +238,28 @@ func (t *callTracer) CaptureSystemTxEnd(intrinsicGas uint64) { t.callstack[0].GasUsed -= intrinsicGas } +func (t *callTracer) OnLog(log *types.Log) { + // Only logs need to be captured via opcode processing + if !t.config.WithLog { + return + } + // Avoid processing nested calls when only caring about top call + if t.config.OnlyTopCall && t.depth > 0 { + return + } + // Skip if tracing was interrupted + if t.interrupt.Load() { + return + } + l := callLog{ + Address: log.Address, + Topics: log.Topics, + Data: log.Data, + Position: hexutil.Uint(len(t.callstack[len(t.callstack)-1].Calls)), + } + t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, l) +} + // GetResult returns the json-encoded nested list of call traces, and any // error arising from the encoding or forceful termination (via `Stop`). func (t *callTracer) GetResult() (json.RawMessage, error) { @@ -270,7 +271,7 @@ func (t *callTracer) GetResult() (json.RawMessage, error) { if err != nil { return nil, err } - return json.RawMessage(res), t.reason + return res, t.reason } // Stop terminates execution of the tracer at the first opportune moment. diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index b552c20424..3b158ddb1b 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -21,10 +21,14 @@ import ( "errors" "fmt" "math/big" + "slices" "strings" + "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" ) @@ -111,8 +115,8 @@ type flatCallTracer struct { tracer *callTracer config flatCallTracerConfig ctx *tracers.Context // Holds tracer context data - reason error // Textual reason for the interruption - activePrecompiles []common.Address // Updated on CaptureStart based on given rules + interrupt atomic.Bool // Atomic flag to signal execution interruption + activePrecompiles []common.Address // Updated on tx start based on given rules } type flatCallTracerConfig struct { @@ -121,7 +125,7 @@ type flatCallTracerConfig struct { } // newFlatCallTracer returns a new flatCallTracer. -func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { +func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { var config flatCallTracerConfig if cfg != nil { if err := json.Unmarshal(cfg, &config); err != nil { @@ -131,45 +135,34 @@ func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Trace // Create inner call tracer with default configuration, don't forward // the OnlyTopCall or WithLog to inner for now - tracer, err := tracers.DefaultDirectory.New("callTracer", ctx, nil) + t, err := newCallTracerObject(ctx, nil) if err != nil { return nil, err } - t, ok := tracer.(*callTracer) - if !ok { - return nil, errors.New("internal error: embedded tracer has wrong type") - } - - return &flatCallTracer{tracer: t, ctx: ctx, config: config}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *flatCallTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.tracer.CaptureStart(env, from, to, create, input, gas, value) - // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time) - t.activePrecompiles = vm.ActivePrecompiles(rules) -} -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *flatCallTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - t.tracer.CaptureEnd(output, gasUsed, err) -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *flatCallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - t.tracer.CaptureState(pc, op, gas, cost, scope, rData, depth, err) -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *flatCallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - t.tracer.CaptureFault(pc, op, gas, cost, scope, depth, err) + ft := &flatCallTracer{tracer: t, ctx: ctx, config: config} + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: ft.OnTxStart, + OnTxEnd: ft.OnTxEnd, + OnEnter: ft.OnEnter, + OnExit: ft.OnExit, + }, + Stop: ft.Stop, + GetResult: ft.GetResult, + }, nil } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - t.tracer.CaptureEnter(typ, from, to, input, gas, value) +// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct). +func (t *flatCallTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if t.interrupt.Load() { + return + } + t.tracer.OnEnter(depth, typ, from, to, input, gas, value) + if depth == 0 { + return + } // Child calls must have a value, even if it's zero. // Practically speaking, only STATICCALL has nil value. Set it to zero. if t.tracer.callstack[len(t.tracer.callstack)-1].Value == nil && value == nil { @@ -177,11 +170,17 @@ func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to com } } -// CaptureExit is called when EVM exits a scope, even if the scope didn't +// OnExit is called when EVM exits a scope, even if the scope didn't // execute any code. -func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - t.tracer.CaptureExit(output, gasUsed, err) +func (t *flatCallTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if t.interrupt.Load() { + return + } + t.tracer.OnExit(depth, output, gasUsed, err, reverted) + if depth == 0 { + return + } // Parity traces don't include CALL/STATICCALLs to precompiles. // By default we remove them from the callstack. if t.config.IncludePrecompiles { @@ -201,12 +200,21 @@ func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) { } } -func (t *flatCallTracer) CaptureTxStart(gasLimit uint64) { - t.tracer.CaptureTxStart(gasLimit) +func (t *flatCallTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + if t.interrupt.Load() { + return + } + t.tracer.OnTxStart(env, tx, from) + // Update list of precompiles based on current block + rules := env.ChainConfig.Rules(env.BlockNumber, env.Random != nil, env.Time) + t.activePrecompiles = vm.ActivePrecompiles(rules) } -func (t *flatCallTracer) CaptureTxEnd(restGas uint64) { - t.tracer.CaptureTxEnd(restGas) +func (t *flatCallTracer) OnTxEnd(receipt *types.Receipt, err error) { + if t.interrupt.Load() { + return + } + t.tracer.OnTxEnd(receipt, err) } func (t *flatCallTracer) CaptureSystemTxEnd(intrinsicGas uint64) { @@ -228,22 +236,18 @@ func (t *flatCallTracer) GetResult() (json.RawMessage, error) { if err != nil { return nil, err } - return res, t.reason + return res, t.tracer.reason } // Stop terminates execution of the tracer at the first opportune moment. func (t *flatCallTracer) Stop(err error) { t.tracer.Stop(err) + t.interrupt.Store(true) } // isPrecompiled returns whether the addr is a precompile. func (t *flatCallTracer) isPrecompiled(addr common.Address) bool { - for _, p := range t.activePrecompiles { - if p == addr { - return true - } - } - return false + return slices.Contains(t.activePrecompiles, addr) } func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx *tracers.Context) (output []flatCallFrame, err error) { @@ -274,16 +278,14 @@ func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx } output = append(output, *frame) - if len(input.Calls) > 0 { - for i, childCall := range input.Calls { - childAddr := childTraceAddress(traceAddress, i) - childCallCopy := childCall - flat, err := flatFromNested(&childCallCopy, childAddr, convertErrs, ctx) - if err != nil { - return nil, err - } - output = append(output, flat...) + for i, childCall := range input.Calls { + childAddr := childTraceAddress(traceAddress, i) + childCallCopy := childCall + flat, err := flatFromNested(&childCallCopy, childAddr, convertErrs, ctx) + if err != nil { + return nil, err } + output = append(output, flat...) } return output, nil diff --git a/eth/tracers/native/call_flat_test.go b/eth/tracers/native/call_flat_test.go new file mode 100644 index 0000000000..d5481b868b --- /dev/null +++ b/eth/tracers/native/call_flat_test.go @@ -0,0 +1,64 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package native_test + +import ( + "errors" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +func TestCallFlatStop(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("flatCallTracer", &tracers.Context{}, nil) + require.NoError(t, err) + + // this error should be returned by GetResult + stopError := errors.New("stop error") + + // simulate a transaction + tx := types.NewTx(&types.LegacyTx{ + Nonce: 0, + To: &common.Address{}, + Value: big.NewInt(0), + Gas: 0, + GasPrice: big.NewInt(0), + Data: nil, + }) + + tracer.OnTxStart(&tracing.VMContext{ + ChainConfig: params.MainnetChainConfig, + }, tx, common.Address{}) + + tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, nil, 0, big.NewInt(0)) + + // stop before the transaction is finished + tracer.Stop(stopError) + + tracer.OnTxEnd(&types.Receipt{GasUsed: 0}, nil) + + // check that the error is returned by GetResult + _, tracerError := tracer.GetResult() + require.Equal(t, stopError, tracerError) +} diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index f447cf50ae..3a0c698a71 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -21,7 +21,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers" ) @@ -33,18 +34,18 @@ func init() { // runs multiple tracers in one go. type muxTracer struct { names []string - tracers []tracers.Tracer + tracers []*tracers.Tracer } // newMuxTracer returns a new mux tracer. -func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { +func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { var config map[string]json.RawMessage if cfg != nil { if err := json.Unmarshal(cfg, &config); err != nil { return nil, err } } - objects := make([]tracers.Tracer, 0, len(config)) + objects := make([]*tracers.Tracer, 0, len(config)) names := make([]string, 0, len(config)) for k, v := range config { t, err := tracers.DefaultDirectory.New(k, ctx, v) @@ -55,61 +56,120 @@ func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, er names = append(names, k) } - return &muxTracer{names: names, tracers: objects}, nil + t := &muxTracer{names: names, tracers: objects} + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + OnGasChange: t.OnGasChange, + OnBalanceChange: t.OnBalanceChange, + OnNonceChange: t.OnNonceChange, + OnCodeChange: t.OnCodeChange, + OnStorageChange: t.OnStorageChange, + OnLog: t.OnLog, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil } -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *muxTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +func (t *muxTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { for _, t := range t.tracers { - t.CaptureStart(env, from, to, create, input, gas, value) + if t.OnOpcode != nil { + t.OnOpcode(pc, op, gas, cost, scope, rData, depth, err) + } + } +} + +func (t *muxTracer) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) { + for _, t := range t.tracers { + if t.OnFault != nil { + t.OnFault(pc, op, gas, cost, scope, depth, err) + } + } +} + +func (t *muxTracer) OnGasChange(old, new uint64, reason tracing.GasChangeReason) { + for _, t := range t.tracers { + if t.OnGasChange != nil { + t.OnGasChange(old, new, reason) + } + } +} + +func (t *muxTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + for _, t := range t.tracers { + if t.OnEnter != nil { + t.OnEnter(depth, typ, from, to, input, gas, value) + } + } +} + +func (t *muxTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + for _, t := range t.tracers { + if t.OnExit != nil { + t.OnExit(depth, output, gasUsed, err, reverted) + } } } -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *muxTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { +func (t *muxTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { for _, t := range t.tracers { - t.CaptureEnd(output, gasUsed, err) + if t.OnTxStart != nil { + t.OnTxStart(env, tx, from) + } } } -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +func (t *muxTracer) OnTxEnd(receipt *types.Receipt, err error) { for _, t := range t.tracers { - t.CaptureState(pc, op, gas, cost, scope, rData, depth, err) + if t.OnTxEnd != nil { + t.OnTxEnd(receipt, err) + } } } -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { +func (t *muxTracer) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { for _, t := range t.tracers { - t.CaptureFault(pc, op, gas, cost, scope, depth, err) + if t.OnBalanceChange != nil { + t.OnBalanceChange(a, prev, new, reason) + } } } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *muxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (t *muxTracer) OnNonceChange(a common.Address, prev, new uint64) { for _, t := range t.tracers { - t.CaptureEnter(typ, from, to, input, gas, value) + if t.OnNonceChange != nil { + t.OnNonceChange(a, prev, new) + } } } -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *muxTracer) CaptureExit(output []byte, gasUsed uint64, err error) { +func (t *muxTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) { for _, t := range t.tracers { - t.CaptureExit(output, gasUsed, err) + if t.OnCodeChange != nil { + t.OnCodeChange(a, prevCodeHash, prev, codeHash, code) + } } } -func (t *muxTracer) CaptureTxStart(gasLimit uint64) { +func (t *muxTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) { for _, t := range t.tracers { - t.CaptureTxStart(gasLimit) + if t.OnStorageChange != nil { + t.OnStorageChange(a, k, prev, new) + } } } -func (t *muxTracer) CaptureTxEnd(restGas uint64) { +func (t *muxTracer) OnLog(log *types.Log) { for _, t := range t.tracers { - t.CaptureTxEnd(restGas) + if t.OnLog != nil { + t.OnLog(log) + } } } diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index a647ffbcd7..26ffdf9e2e 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -21,7 +21,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers" ) @@ -34,38 +35,58 @@ func init() { type noopTracer struct{} // newNoopTracer returns a new noop tracer. -func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { - return &noopTracer{}, nil +func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) { + t := &noopTracer{} + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + OnGasChange: t.OnGasChange, + OnBalanceChange: t.OnBalanceChange, + OnNonceChange: t.OnNonceChange, + OnCodeChange: t.OnCodeChange, + OnStorageChange: t.OnStorageChange, + OnLog: t.OnLog, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil } -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *noopTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +func (t *noopTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { } -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { +func (t *noopTracer) OnFault(pc uint64, op byte, gas, cost uint64, _ tracing.OpContext, depth int, err error) { } -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +func (t *noopTracer) OnGasChange(old, new uint64, reason tracing.GasChangeReason) {} + +func (t *noopTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) { +func (t *noopTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { } -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *noopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (*noopTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { } -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *noopTracer) CaptureExit(output []byte, gasUsed uint64, err error) { +func (*noopTracer) OnTxEnd(receipt *types.Receipt, err error) {} + +func (*noopTracer) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { +} + +func (*noopTracer) OnNonceChange(a common.Address, prev, new uint64) {} + +func (*noopTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) { } -func (*noopTracer) CaptureTxStart(gasLimit uint64) {} +func (*noopTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) {} -func (*noopTracer) CaptureTxEnd(restGas uint64) {} +func (*noopTracer) OnLog(log *types.Log) {} func (*noopTracer) CaptureSystemTxEnd(intrinsicGas uint64) {} diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index c737506d31..1a3a812967 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -24,11 +24,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/eth/tracers/internal" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" ) //go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go @@ -37,13 +39,14 @@ func init() { tracers.DefaultDirectory.Register("prestateTracer", newPrestateTracer, false) } -type state = map[common.Address]*account +type stateMap = map[common.Address]*account type account struct { Balance *big.Int `json:"balance,omitempty"` Code []byte `json:"code,omitempty"` Nonce uint64 `json:"nonce,omitempty"` Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + empty bool } func (a *account) exists() bool { @@ -56,13 +59,10 @@ type accountMarshaling struct { } type prestateTracer struct { - noopTracer - env *vm.EVM - pre state - post state - create bool + env *tracing.VMContext + pre stateMap + post stateMap to common.Address - gasLimit uint64 // Amount of gas bought for the whole tx config prestateTracerConfig interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption @@ -74,73 +74,33 @@ type prestateTracerConfig struct { DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications } -func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { +func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) { var config prestateTracerConfig if cfg != nil { if err := json.Unmarshal(cfg, &config); err != nil { return nil, err } } - return &prestateTracer{ - pre: state{}, - post: state{}, + t := &prestateTracer{ + pre: stateMap{}, + post: stateMap{}, config: config, created: make(map[common.Address]bool), deleted: make(map[common.Address]bool), - }, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.env = env - t.create = create - t.to = to - - t.lookupAccount(from) - t.lookupAccount(to) - t.lookupAccount(env.Context.Coinbase) - - // The recipient balance includes the value transferred. - toBal := new(big.Int).Sub(t.pre[to].Balance, value) - t.pre[to].Balance = toBal - - // The sender balance is after reducing: value and gasLimit. - // We need to re-add them to get the pre-tx balance. - fromBal := new(big.Int).Set(t.pre[from].Balance) - gasPrice := env.TxContext.GasPrice - consumedGas := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(t.gasLimit)) - fromBal.Add(fromBal, new(big.Int).Add(value, consumedGas)) - - // Add blob fee to the sender's balance. - if env.Context.BlobBaseFee != nil && len(env.TxContext.BlobHashes) > 0 { - blobGas := uint64(params.BlobTxBlobGasPerBlob * len(env.TxContext.BlobHashes)) - fromBal.Add(fromBal, new(big.Int).Mul(env.Context.BlobBaseFee, new(big.Int).SetUint64(blobGas))) - } - t.pre[from].Balance = fromBal - t.pre[from].Nonce-- - - if create && t.config.DiffMode { - t.created[to] = true - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - if t.config.DiffMode { - return - } - - if t.create { - // Keep existing account prior to contract creation at that address - if s := t.pre[t.to]; s != nil && !s.exists() { - // Exclude newly created contract. - delete(t.pre, t.to) - } } + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnOpcode: t.OnOpcode, + }, + GetResult: t.GetResult, + Stop: t.Stop, + }, nil } -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +// OnOpcode implements the EVMLogger interface to trace a single step of VM execution. +func (t *prestateTracer) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { if err != nil { return } @@ -148,10 +108,10 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, if t.interrupt.Load() { return } - stack := scope.Stack - stackData := stack.Data() + op := vm.OpCode(opcode) + stackData := scope.StackData() stackLen := len(stackData) - caller := scope.Contract.Address() + caller := scope.Address() switch { case stackLen >= 1 && (op == vm.SLOAD || op == vm.SSTORE): slot := common.Hash(stackData[stackLen-1].Bytes32()) @@ -173,7 +133,7 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, case stackLen >= 4 && op == vm.CREATE2: offset := stackData[stackLen-2] size := stackData[stackLen-3] - init, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(offset.Uint64()), int64(size.Uint64())) + init, err := internal.GetMemoryCopyPadded(scope.MemoryData(), int64(offset.Uint64()), int64(size.Uint64())) if err != nil { log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size) return @@ -186,15 +146,62 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, } } -func (t *prestateTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit +func (t *prestateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + t.env = env + if tx.To() == nil { + t.to = crypto.CreateAddress(from, env.StateDB.GetNonce(from)) + t.created[t.to] = true + } else { + t.to = *tx.To() + } + + t.lookupAccount(from) + t.lookupAccount(t.to) + t.lookupAccount(env.Coinbase) } -func (t *prestateTracer) CaptureTxEnd(restGas uint64) { - if !t.config.DiffMode { +func (t *prestateTracer) OnTxEnd(receipt *types.Receipt, err error) { + if err != nil { return } + if t.config.DiffMode { + t.processDiffState() + } + // the new created contracts' prestate were empty, so delete them + for a := range t.created { + // the created contract maybe exists in statedb before the creating tx + if s := t.pre[a]; s != nil && s.empty { + delete(t.pre, a) + } + } +} + +// GetResult returns the json-encoded nested list of call traces, and any +// error arising from the encoding or forceful termination (via `Stop`). +func (t *prestateTracer) GetResult() (json.RawMessage, error) { + var res []byte + var err error + if t.config.DiffMode { + res, err = json.Marshal(struct { + Post stateMap `json:"post"` + Pre stateMap `json:"pre"` + }{t.post, t.pre}) + } else { + res, err = json.Marshal(t.pre) + } + if err != nil { + return nil, err + } + return json.RawMessage(res), t.reason +} + +// Stop terminates execution of the tracer at the first opportune moment. +func (t *prestateTracer) Stop(err error) { + t.reason = err + t.interrupt.Store(true) +} +func (t *prestateTracer) processDiffState() { for addr, state := range t.pre { // The deleted account's state is pruned from `post` but kept in `pre` if _, ok := t.deleted[addr]; ok { @@ -244,42 +251,10 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) { delete(t.pre, addr) } } - // the new created contracts' prestate were empty, so delete them - for a := range t.created { - // the created contract maybe exists in statedb before the creating tx - if s := t.pre[a]; s != nil && !s.exists() { - delete(t.pre, a) - } - } } func (t *prestateTracer) CaptureSystemTxEnd(intrinsicGas uint64) {} -// GetResult returns the json-encoded nested list of call traces, and any -// error arising from the encoding or forceful termination (via `Stop`). -func (t *prestateTracer) GetResult() (json.RawMessage, error) { - var res []byte - var err error - if t.config.DiffMode { - res, err = json.Marshal(struct { - Post state `json:"post"` - Pre state `json:"pre"` - }{t.post, t.pre}) - } else { - res, err = json.Marshal(t.pre) - } - if err != nil { - return nil, err - } - return json.RawMessage(res), t.reason -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *prestateTracer) Stop(err error) { - t.reason = err - t.interrupt.Store(true) -} - // lookupAccount fetches details of an account and adds it to the prestate // if it doesn't exist there. func (t *prestateTracer) lookupAccount(addr common.Address) { @@ -287,12 +262,16 @@ func (t *prestateTracer) lookupAccount(addr common.Address) { return } - t.pre[addr] = &account{ + acc := &account{ Balance: t.env.StateDB.GetBalance(addr).ToBig(), Nonce: t.env.StateDB.GetNonce(addr), Code: t.env.StateDB.GetCode(addr), Storage: make(map[common.Hash]common.Hash), } + if !acc.exists() { + acc.empty = true + } + t.pre[addr] = acc } // lookupStorage fetches the requested storage slot and adds diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 6ac266e06d..3cce7bffa1 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -89,7 +89,7 @@ func BenchmarkTransactionTrace(b *testing.B) { //EnableMemory: false, //EnableReturnData: false, }) - evm := vm.NewEVM(context, txContext, state.StateDB, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer}) + evm := vm.NewEVM(context, txContext, state.StateDB, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer.Hooks()}) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) if err != nil { b.Fatalf("failed to prepare transaction for tracing: %v", err) @@ -111,41 +111,3 @@ func BenchmarkTransactionTrace(b *testing.B) { tracer.Reset() } } - -func TestMemCopying(t *testing.T) { - for i, tc := range []struct { - memsize int64 - offset int64 - size int64 - wantErr string - wantSize int - }{ - {0, 0, 100, "", 100}, // Should pad up to 100 - {0, 100, 0, "", 0}, // No need to pad (0 size) - {100, 50, 100, "", 100}, // Should pad 100-150 - {100, 50, 5, "", 5}, // Wanted range fully within memory - {100, -50, 0, "offset or size must not be negative", 0}, // Error - {0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Error - {10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Error - - } { - mem := vm.NewMemory() - mem.Resize(uint64(tc.memsize)) - cpy, err := GetMemoryCopyPadded(mem, tc.offset, tc.size) - if want := tc.wantErr; want != "" { - if err == nil { - t.Fatalf("test %d: want '%v' have no error", i, want) - } - if have := err.Error(); want != have { - t.Fatalf("test %d: want '%v' have '%v'", i, want, have) - } - continue - } - if err != nil { - t.Fatalf("test %d: unexpected error: %v", i, err) - } - if want, have := tc.wantSize, len(cpy); have != want { - t.Fatalf("test %d: want %v have %v", i, want, have) - } - } -} diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 1a586ec039..40ead6a787 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -154,6 +154,7 @@ type rpcBlock struct { Transactions []rpcTransaction `json:"transactions"` UncleHashes []common.Hash `json:"uncles"` Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` + Requests []*types.Request `json:"requests,omitempty"` } func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) { @@ -222,7 +223,13 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface } txs[i] = tx.tx } - return types.NewBlockWithHeader(head).WithBody(txs, uncles).WithWithdrawals(body.Withdrawals), nil + return types.NewBlockWithHeader(head).WithBody( + types.Body{ + Transactions: txs, + Uncles: uncles, + Withdrawals: body.Withdrawals, + Requests: body.Requests, + }), nil } // HeaderByHash returns the block header with the given hash. @@ -461,7 +468,7 @@ func (ec *Client) NetworkID(ctx context.Context) (*big.Int, error) { if err := ec.c.CallContext(ctx, &ver, "net_version"); err != nil { return nil, err } - if _, ok := version.SetString(ver, 10); !ok { + if _, ok := version.SetString(ver, 0); !ok { return nil, fmt.Errorf("invalid net_version result %q", ver) } return version, nil diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 7abc104fd1..27f7a4a907 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -311,7 +311,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { t.Fatalf("can't create new node: %v", err) } // Create Ethereum Service - config := ðconfig.Config{Genesis: genesis} + config := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000} config.SnapshotCache = 256 config.TriesInMemory = 128 ethservice, err := eth.New(n, config) diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index b1678b6766..02b2598b37 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -328,9 +328,9 @@ func (o BlockOverrides) MarshalJSON() ([]byte, error) { Difficulty *hexutil.Big `json:"difficulty,omitempty"` Time hexutil.Uint64 `json:"time,omitempty"` GasLimit hexutil.Uint64 `json:"gasLimit,omitempty"` - Coinbase *common.Address `json:"coinbase,omitempty"` - Random *common.Hash `json:"random,omitempty"` - BaseFee *hexutil.Big `json:"baseFee,omitempty"` + Coinbase *common.Address `json:"feeRecipient,omitempty"` + Random *common.Hash `json:"prevRandao,omitempty"` + BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty"` } output := override{ diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index 158886475e..36ea290a85 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -57,7 +57,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { t.Fatalf("can't create new node: %v", err) } // Create Ethereum Service - config := ðconfig.Config{Genesis: genesis} + config := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000} ethservice, err := eth.New(n, config) if err != nil { t.Fatalf("can't create new ethereum service: %v", err) @@ -65,7 +65,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { filterSystem := filters.NewFilterSystem(ethservice.APIBackend, filters.Config{}) n.RegisterAPIs([]rpc.API{{ Namespace: "eth", - Service: filters.NewFilterAPI(filterSystem, false), + Service: filters.NewFilterAPI(filterSystem), }}) // Import the test chain. @@ -146,7 +146,7 @@ func TestGethClient(t *testing.T) { func(t *testing.T) { testCallContractWithBlockOverrides(t, client) }, }, // The testaccesslist is a bit time-sensitive: the newTestBackend imports - // one block. The `testAcessList` fails if the miner has not yet created a + // one block. The `testAccessList` fails if the miner has not yet created a // new pending-block after the import event. // Hence: this test should be last, execute the tests serially. { @@ -299,7 +299,7 @@ func testGetProofNonExistent(t *testing.T, client *rpc.Client) { t.Fatalf("invalid nonce, want: %v got: %v", 0, result.Nonce) } // test balance - if result.Balance.Cmp(big.NewInt(0)) != 0 { + if result.Balance.Sign() != 0 { t.Fatalf("invalid balance, want: %v got: %v", 0, result.Balance) } // test storage @@ -510,7 +510,7 @@ func TestBlockOverridesMarshal(t *testing.T) { bo: BlockOverrides{ Coinbase: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - want: `{"coinbase":"0x1111111111111111111111111111111111111111"}`, + want: `{"feeRecipient":"0x1111111111111111111111111111111111111111"}`, }, { bo: BlockOverrides{ @@ -520,7 +520,7 @@ func TestBlockOverridesMarshal(t *testing.T) { GasLimit: 4, BaseFee: big.NewInt(5), }, - want: `{"number":"0x1","difficulty":"0x2","time":"0x3","gasLimit":"0x4","baseFee":"0x5"}`, + want: `{"number":"0x1","difficulty":"0x2","time":"0x3","gasLimit":"0x4","baseFeePerGas":"0x5"}`, }, } { marshalled, err := json.Marshal(&tt.bo) diff --git a/ethclient/simulated/backend.go b/ethclient/simulated/backend.go index a577343df3..2ba8add7ce 100644 --- a/ethclient/simulated/backend.go +++ b/ethclient/simulated/backend.go @@ -18,6 +18,7 @@ package simulated import ( "context" + "errors" "time" "github.com/ethereum/go-ethereum" @@ -69,7 +70,7 @@ type simClient struct { // Backend is a simulated blockchain. You can use it to test your contracts or // other code that interacts with the Ethereum chain. type Backend struct { - eth *eth.Ethereum + node *node.Node beacon *catalyst.SimulatedBeacon client simClient } @@ -120,7 +121,7 @@ func newWithNode(stack *node.Node, conf *eth.Config, blockPeriod uint64) (*Backe filterSystem := filters.NewFilterSystem(backend.APIBackend, filters.Config{}) stack.RegisterAPIs([]rpc.API{{ Namespace: "eth", - Service: filters.NewFilterAPI(filterSystem, false), + Service: filters.NewFilterAPI(filterSystem), }}) // Start the node if err := stack.Start(); err != nil { @@ -136,7 +137,7 @@ func newWithNode(stack *node.Node, conf *eth.Config, blockPeriod uint64) (*Backe return nil, err } return &Backend{ - eth: backend, + node: stack, beacon: beacon, client: simClient{ethclient.NewClient(stack.Attach())}, }, nil @@ -149,12 +150,16 @@ func (n *Backend) Close() error { n.client.Close() n.client = simClient{} } + var err error if n.beacon != nil { - err := n.beacon.Stop() + err = n.beacon.Stop() n.beacon = nil - return err } - return nil + if n.node != nil { + err = errors.Join(err, n.node.Close()) + n.node = nil + } + return err } // Commit seals a block and moves the chain forward to a new empty block. diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index a8fd7913c3..37f4dbbf7b 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -106,7 +106,7 @@ func TestAdjustTime(t *testing.T) { block2, _ := client.BlockByNumber(context.Background(), nil) prevTime := block1.Time() newTime := block2.Time() - if newTime-prevTime != uint64(time.Minute) { + if newTime-prevTime != 60 { t.Errorf("adjusted time not equal to 60 seconds. prev: %v, new: %v", prevTime, newTime) } } @@ -194,8 +194,8 @@ func TestFork(t *testing.T) { // 2. Send a transaction. // 3. Check that the TX is included in block 1. // 4. Fork by using the parent block as ancestor. -// 5. Mine a block, Re-send the transaction and mine another one. -// 6. Check that the TX is now included in block 2. +// 5. Mine a block. We expect the out-forked tx to have trickled to the pool, and into the new block. +// 6. Check that the TX is now included in (the new) block 1. func TestForkResendTx(t *testing.T) { t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) @@ -213,7 +213,9 @@ func TestForkResendTx(t *testing.T) { if err != nil { t.Fatalf("could not create transaction: %v", err) } - client.SendTransaction(ctx, tx) + if err := client.SendTransaction(ctx, tx); err != nil { + t.Fatalf("sending transaction: %v", err) + } sim.Commit() // 3. @@ -229,12 +231,8 @@ func TestForkResendTx(t *testing.T) { // 5. sim.Commit() - if err := client.SendTransaction(ctx, tx); err != nil { - t.Fatalf("sending transaction: %v", err) - } - sim.Commit() receipt, _ = client.TransactionReceipt(ctx, tx.Hash()) - if h := receipt.BlockNumber.Uint64(); h != 2 { + if h := receipt.BlockNumber.Uint64(); h != 1 { t.Errorf("TX included in wrong block: %d", h) } } @@ -256,11 +254,10 @@ func TestCommitReturnValue(t *testing.T) { } // Create a block in the original chain (containing a transaction to force different block hashes) - head, _ := client.HeaderByNumber(ctx, nil) // Should be child's, good enough - gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) - _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) - tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) - client.SendTransaction(ctx, tx) + tx, _ := newTx(sim, testKey) + if err := client.SendTransaction(ctx, tx); err != nil { + t.Errorf("sending transaction: %v", err) + } h2 := sim.Commit() diff --git a/ethclient/simulated/options.go b/ethclient/simulated/options.go index 6db995c917..40bcb37bd1 100644 --- a/ethclient/simulated/options.go +++ b/ethclient/simulated/options.go @@ -46,7 +46,7 @@ func WithCallGasLimit(gaslimit uint64) func(nodeConf *node.Config, ethConf *ethc // 0 is not possible as a live Geth node would reject that due to DoS protection, // so the simulated backend will replicate that behavior for consistency. func WithMinerMinTip(tip *big.Int) func(nodeConf *node.Config, ethConf *ethconfig.Config) { - if tip == nil || tip.Cmp(new(big.Int)) <= 0 { + if tip == nil || tip.Sign() <= 0 { panic("invalid miner minimum tip") } return func(nodeConf *node.Config, ethConf *ethconfig.Config) { diff --git a/ethdb/database.go b/ethdb/database.go index 5d7d54353c..66bf229e44 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -43,8 +43,8 @@ type KeyValueWriter interface { // KeyValueStater wraps the Stat method of a backing data store. type KeyValueStater interface { - // Stat returns a particular internal stat of the database. - Stat(property string) (string, error) + // Stat returns the statistic data of the database. + Stat() (string, error) } // Compacter wraps the Compact method of a backing data store. @@ -68,7 +68,6 @@ type KeyValueStore interface { Batcher Iteratee Compacter - Snapshotter io.Closer } @@ -92,8 +91,8 @@ type AncientReaderOp interface { // Ancients returns the ancient item numbers in the ancient store. Ancients() (uint64, error) - // Tail returns the number of first stored item in the freezer. - // This number can also be interpreted as the total deleted item numbers. + // Tail returns the number of first stored item in the ancient store. + // This number can also be interpreted as the total deleted items. Tail() (uint64, error) // AncientSize returns the ancient size of the specified category. @@ -111,7 +110,7 @@ type AncientReader interface { AncientReaderOp // ReadAncients runs the given read operation while ensuring that no writes take place - // on the underlying freezer. + // on the underlying ancient store. ReadAncients(fn func(AncientReaderOp) error) (err error) } @@ -136,11 +135,6 @@ type AncientWriter interface { // Sync flushes all in-memory ancient store data to disk. Sync() error - // MigrateTable processes and migrates entries of a given table to a new format. - // The second argument is a function that takes a raw entry and returns it - // in the newest format. - MigrateTable(string, func([]byte) ([]byte, error)) error - // TruncateTableTail will truncate certain table to new tail TruncateTableTail(kind string, tail uint64) (uint64, error) @@ -168,11 +162,15 @@ type AncientWriteOp interface { AppendRaw(kind string, number uint64, item []byte) error } -// AncientStater wraps the Stat method of a backing data store. +// AncientStater wraps the Stat method of a backing ancient store. type AncientStater interface { - // AncientDatadir returns the path of root ancient directory. Empty string - // will be returned if ancient store is not enabled at all. The returned - // path can be used to construct the path of other freezers. + // AncientDatadir returns the path of the ancient store directory. + // + // If the ancient store is not activated, an error is returned. + // If an ephemeral ancient store is used, an empty path is returned. + // + // The path returned by AncientDatadir can be used as the root path + // of the ancient store to construct paths for other sub ancient stores. AncientDatadir() (string, error) } @@ -221,7 +219,7 @@ type Stater interface { } // AncientStore contains all the methods required to allow handling different -// ancient data stores backing immutable chain data store. +// ancient data stores backing immutable data store. type AncientStore interface { AncientReader AncientWriter @@ -245,8 +243,16 @@ type BlockStore interface { HasSeparateBlockStore() bool } +// ResettableAncientStore extends the AncientStore interface by adding a Reset method. +type ResettableAncientStore interface { + AncientStore + + // Reset is designed to reset the entire ancient store to its default state. + Reset() error +} + // Database contains all the methods required by the high level database to not -// only access the key-value data store but also the chain freezer. +// only access the key-value data store but also the ancient chain store. type Database interface { Reader Writer @@ -257,7 +263,6 @@ type Database interface { Iteratee Stater Compacter - Snapshotter AncientFreezer io.Closer } diff --git a/ethdb/dbtest/testsuite.go b/ethdb/dbtest/testsuite.go index 29bd24364e..1af55a0e38 100644 --- a/ethdb/dbtest/testsuite.go +++ b/ethdb/dbtest/testsuite.go @@ -19,12 +19,11 @@ package dbtest import ( "bytes" "crypto/rand" - "reflect" + "slices" "sort" "testing" "github.com/ethereum/go-ethereum/ethdb" - "golang.org/x/exp/slices" ) // TestDatabaseSuite runs a suite of tests against a KeyValueStore database @@ -149,7 +148,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { if err := it.Error(); err != nil { t.Fatal(err) } - if !reflect.DeepEqual(got, want) { + if !slices.Equal(got, want) { t.Errorf("Iterator: got: %s; want: %s", got, want) } } @@ -160,7 +159,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { if err := it.Error(); err != nil { t.Fatal(err) } - if !reflect.DeepEqual(got, want) { + if !slices.Equal(got, want) { t.Errorf("IteratorWith(1,nil): got: %s; want: %s", got, want) } } @@ -171,7 +170,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { if err := it.Error(); err != nil { t.Fatal(err) } - if !reflect.DeepEqual(got, want) { + if !slices.Equal(got, want) { t.Errorf("IteratorWith(5,nil): got: %s; want: %s", got, want) } } @@ -182,7 +181,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { if err := it.Error(); err != nil { t.Fatal(err) } - if !reflect.DeepEqual(got, want) { + if !slices.Equal(got, want) { t.Errorf("IteratorWith(nil,2): got: %s; want: %s", got, want) } } @@ -193,7 +192,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { if err := it.Error(); err != nil { t.Fatal(err) } - if !reflect.DeepEqual(got, want) { + if !slices.Equal(got, want) { t.Errorf("IteratorWith(nil,5): got: %s; want: %s", got, want) } } @@ -262,7 +261,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { { it := db.NewIterator(nil, nil) - if got, want := iterateKeys(it), []string{"1", "2", "3", "4"}; !reflect.DeepEqual(got, want) { + if got, want := iterateKeys(it), []string{"1", "2", "3", "4"}; !slices.Equal(got, want) { t.Errorf("got: %s; want: %s", got, want) } } @@ -286,7 +285,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { { it := db.NewIterator(nil, nil) - if got, want := iterateKeys(it), []string{"2", "3", "4", "5", "6"}; !reflect.DeepEqual(got, want) { + if got, want := iterateKeys(it), []string{"2", "3", "4", "5", "6"}; !slices.Equal(got, want) { t.Errorf("got: %s; want: %s", got, want) } } @@ -314,75 +313,12 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) { } it := db.NewIterator(nil, nil) - if got := iterateKeys(it); !reflect.DeepEqual(got, want) { + if got := iterateKeys(it); !slices.Equal(got, want) { t.Errorf("got: %s; want: %s", got, want) } }) - t.Run("Snapshot", func(t *testing.T) { - db := New() - defer db.Close() - - initial := map[string]string{ - "k1": "v1", "k2": "v2", "k3": "", "k4": "", - } - for k, v := range initial { - db.Put([]byte(k), []byte(v)) - } - snapshot, err := db.NewSnapshot() - if err != nil { - t.Fatal(err) - } - for k, v := range initial { - got, err := snapshot.Get([]byte(k)) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(got, []byte(v)) { - t.Fatalf("Unexpected value want: %v, got %v", v, got) - } - } - - // Flush more modifications into the database, ensure the snapshot - // isn't affected. - var ( - update = map[string]string{"k1": "v1-b", "k3": "v3-b"} - insert = map[string]string{"k5": "v5-b"} - delete = map[string]string{"k2": ""} - ) - for k, v := range update { - db.Put([]byte(k), []byte(v)) - } - for k, v := range insert { - db.Put([]byte(k), []byte(v)) - } - for k := range delete { - db.Delete([]byte(k)) - } - for k, v := range initial { - got, err := snapshot.Get([]byte(k)) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(got, []byte(v)) { - t.Fatalf("Unexpected value want: %v, got %v", v, got) - } - } - for k := range insert { - got, err := snapshot.Get([]byte(k)) - if err == nil || len(got) != 0 { - t.Fatal("Unexpected value") - } - } - for k := range delete { - got, err := snapshot.Get([]byte(k)) - if err != nil || len(got) == 0 { - t.Fatal("Unexpected deletion") - } - } - }) - - t.Run("OperatonsAfterClose", func(t *testing.T) { + t.Run("OperationsAfterClose", func(t *testing.T) { db := New() db.Put([]byte("key"), []byte("value")) db.Close() @@ -514,7 +450,7 @@ func iterateKeys(it ethdb.Iterator) []string { return keys } -// randomHash generates a random blob of data and returns it as a hash. +// randBytes generates a random blob of data. func randBytes(len int) []byte { buf := make([]byte, len) if n, err := rand.Read(buf); n != len || err != nil { @@ -531,7 +467,7 @@ func makeDataset(size, ksize, vsize int, order bool) ([][]byte, [][]byte) { vals = append(vals, randBytes(vsize)) } if order { - slices.SortFunc(keys, func(a, b []byte) int { return bytes.Compare(a, b) }) + slices.SortFunc(keys, bytes.Compare) } return keys, vals } diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index e58efbddbe..24925a4f04 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -22,7 +22,6 @@ package leveldb import ( "fmt" - "strings" "sync" "time" @@ -231,27 +230,53 @@ func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator { return db.db.NewIterator(bytesPrefixRange(prefix, start), nil) } -// NewSnapshot creates a database snapshot based on the current state. -// The created snapshot will not be affected by all following mutations -// happened on the database. -// Note don't forget to release the snapshot once it's used up, otherwise -// the stale data will never be cleaned up by the underlying compactor. -func (db *Database) NewSnapshot() (ethdb.Snapshot, error) { - snap, err := db.db.GetSnapshot() - if err != nil { - return nil, err +// Stat returns the statistic data of the database. +func (db *Database) Stat() (string, error) { + var stats leveldb.DBStats + if err := db.db.Stats(&stats); err != nil { + return "", err } - return &snapshot{db: snap}, nil -} - -// Stat returns a particular internal stat of the database. -func (db *Database) Stat(property string) (string, error) { - if property == "" { - property = "leveldb.stats" - } else if !strings.HasPrefix(property, "leveldb.") { - property = "leveldb." + property + var ( + message string + totalRead int64 + totalWrite int64 + totalSize int64 + totalTables int + totalDuration time.Duration + ) + if len(stats.LevelSizes) > 0 { + message += " Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB)\n" + + "-------+------------+---------------+---------------+---------------+---------------\n" + for level, size := range stats.LevelSizes { + read := stats.LevelRead[level] + write := stats.LevelWrite[level] + duration := stats.LevelDurations[level] + tables := stats.LevelTablesCounts[level] + + if tables == 0 && duration == 0 { + continue + } + totalTables += tables + totalSize += size + totalRead += read + totalWrite += write + totalDuration += duration + message += fmt.Sprintf(" %3d | %10d | %13.5f | %13.5f | %13.5f | %13.5f\n", + level, tables, float64(size)/1048576.0, duration.Seconds(), + float64(read)/1048576.0, float64(write)/1048576.0) + } + message += "-------+------------+---------------+---------------+---------------+---------------\n" + message += fmt.Sprintf(" Total | %10d | %13.5f | %13.5f | %13.5f | %13.5f\n", + totalTables, float64(totalSize)/1048576.0, totalDuration.Seconds(), + float64(totalRead)/1048576.0, float64(totalWrite)/1048576.0) + message += "-------+------------+---------------+---------------+---------------+---------------\n\n" } - return db.db.GetProperty(property) + message += fmt.Sprintf("Read(MB):%.5f Write(MB):%.5f\n", float64(stats.IORead)/1048576.0, float64(stats.IOWrite)/1048576.0) + message += fmt.Sprintf("BlockCache(MB):%.5f FileCache:%d\n", float64(stats.BlockCacheSize)/1048576.0, stats.OpenedTablesCount) + message += fmt.Sprintf("MemoryCompaction:%d Level0Compaction:%d NonLevel0Compaction:%d SeekCompaction:%d\n", stats.MemComp, stats.Level0Comp, stats.NonLevel0Comp, stats.SeekComp) + message += fmt.Sprintf("WriteDelayCount:%d WriteDelayDuration:%s Paused:%t\n", stats.WriteDelayCount, common.PrettyDuration(stats.WriteDelayDuration), stats.WritePaused) + message += fmt.Sprintf("Snapshots:%d Iterators:%d\n", stats.AliveSnapshots, stats.AliveIterators) + return message, nil } // Compact flattens the underlying data store for the given key range. In essence, @@ -400,7 +425,7 @@ func (b *batch) Put(key, value []byte) error { return nil } -// Delete inserts the a key removal into the batch for later committing. +// Delete inserts the key removal into the batch for later committing. func (b *batch) Delete(key []byte) error { b.b.Delete(key) b.size += len(key) @@ -460,26 +485,3 @@ func bytesPrefixRange(prefix, start []byte) *util.Range { r.Start = append(r.Start, start...) return r } - -// snapshot wraps a leveldb snapshot for implementing the Snapshot interface. -type snapshot struct { - db *leveldb.Snapshot -} - -// Has retrieves if a key is present in the snapshot backing by a key-value -// data store. -func (snap *snapshot) Has(key []byte) (bool, error) { - return snap.db.Has(key, nil) -} - -// Get retrieves the given key if it's present in the snapshot backing by -// key-value data store. -func (snap *snapshot) Get(key []byte) ([]byte, error) { - return snap.db.Get(key, nil) -} - -// Release releases associated resources. Release should always succeed and can -// be called multiple times without causing error. -func (snap *snapshot) Release() { - snap.db.Release() -} diff --git a/ethdb/memorydb/memorydb.go b/ethdb/memorydb/memorydb.go index fa2456e3ee..df5afb5e11 100644 --- a/ethdb/memorydb/memorydb.go +++ b/ethdb/memorydb/memorydb.go @@ -36,10 +36,6 @@ var ( // the provided memory database. errMemorydbNotFound = errors.New("not found") - // errSnapshotReleased is returned if callers want to retrieve data from a - // released snapshot. - errSnapshotReleased = errors.New("snapshot released") - // errNotSupported is returned if the database doesn't support the required operation. errNotSupported = errors.New("this operation is not supported") ) @@ -256,16 +252,9 @@ func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator { } } -// NewSnapshot creates a database snapshot based on the current state. -// The created snapshot will not be affected by all following mutations -// happened on the database. -func (db *Database) NewSnapshot() (ethdb.Snapshot, error) { - return newSnapshot(db), nil -} - -// Stat returns a particular internal stat of the database. -func (db *Database) Stat(property string) (string, error) { - return "", errors.New("unknown property") +// Stat returns the statistic data of the database. +func (db *Database) Stat() (string, error) { + return "", nil } // Compact is not supported on a memory database, but there's no need either as @@ -306,16 +295,6 @@ func (db *Database) BlockStoreWriter() ethdb.Writer { return db.blockStore } -// convertLegacyFn takes a raw freezer entry in an older format and -// returns it in the new format. -type convertLegacyFn = func([]byte) ([]byte, error) - -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (db *Database) MigrateTable(kind string, convert convertLegacyFn) error { - return errNotSupported -} - // keyvalue is a key-value tuple tagged with a deletion field to allow creating // memory-database write batches. type keyvalue struct { @@ -339,7 +318,7 @@ func (b *batch) Put(key, value []byte) error { return nil } -// Delete inserts the a key removal into the batch for later committing. +// Delete inserts the key removal into the batch for later committing. func (b *batch) Delete(key []byte) error { b.writes = append(b.writes, keyvalue{string(key), nil, true}) b.size += len(key) @@ -444,59 +423,3 @@ func (it *iterator) Value() []byte { func (it *iterator) Release() { it.index, it.keys, it.values = -1, nil, nil } - -// snapshot wraps a batch of key-value entries deep copied from the in-memory -// database for implementing the Snapshot interface. -type snapshot struct { - db map[string][]byte - lock sync.RWMutex -} - -// newSnapshot initializes the snapshot with the given database instance. -func newSnapshot(db *Database) *snapshot { - db.lock.RLock() - defer db.lock.RUnlock() - - copied := make(map[string][]byte, len(db.db)) - for key, val := range db.db { - copied[key] = common.CopyBytes(val) - } - return &snapshot{db: copied} -} - -// Has retrieves if a key is present in the snapshot backing by a key-value -// data store. -func (snap *snapshot) Has(key []byte) (bool, error) { - snap.lock.RLock() - defer snap.lock.RUnlock() - - if snap.db == nil { - return false, errSnapshotReleased - } - _, ok := snap.db[string(key)] - return ok, nil -} - -// Get retrieves the given key if it's present in the snapshot backing by -// key-value data store. -func (snap *snapshot) Get(key []byte) ([]byte, error) { - snap.lock.RLock() - defer snap.lock.RUnlock() - - if snap.db == nil { - return nil, errSnapshotReleased - } - if entry, ok := snap.db[string(key)]; ok { - return common.CopyBytes(entry), nil - } - return nil, errMemorydbNotFound -} - -// Release releases associated resources. Release should always succeed and can -// be called multiple times without causing error. -func (snap *snapshot) Release() { - snap.lock.Lock() - defer snap.lock.Unlock() - - snap.db = nil -} diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index aa339bf2d6..0d05aa4854 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -212,7 +212,7 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e // The default compaction concurrency(1 thread), // Here use all available CPUs for faster compaction. - MaxConcurrentCompactions: func() int { return runtime.NumCPU() }, + MaxConcurrentCompactions: runtime.NumCPU, // Per-level options. Options for at least one level must be specified. The // options for the last level are used for all subsequent levels. @@ -250,19 +250,19 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e } db.db = innerDB - db.compTimeMeter = metrics.NewRegisteredMeter(namespace+"compact/time", nil) - db.compReadMeter = metrics.NewRegisteredMeter(namespace+"compact/input", nil) - db.compWriteMeter = metrics.NewRegisteredMeter(namespace+"compact/output", nil) - db.diskSizeGauge = metrics.NewRegisteredGauge(namespace+"disk/size", nil) - db.diskReadMeter = metrics.NewRegisteredMeter(namespace+"disk/read", nil) - db.diskWriteMeter = metrics.NewRegisteredMeter(namespace+"disk/write", nil) - db.writeDelayMeter = metrics.NewRegisteredMeter(namespace+"compact/writedelay/duration", nil) - db.writeDelayNMeter = metrics.NewRegisteredMeter(namespace+"compact/writedelay/counter", nil) - db.memCompGauge = metrics.NewRegisteredGauge(namespace+"compact/memory", nil) - db.level0CompGauge = metrics.NewRegisteredGauge(namespace+"compact/level0", nil) - db.nonlevel0CompGauge = metrics.NewRegisteredGauge(namespace+"compact/nonlevel0", nil) - db.seekCompGauge = metrics.NewRegisteredGauge(namespace+"compact/seek", nil) - db.manualMemAllocGauge = metrics.NewRegisteredGauge(namespace+"memory/manualalloc", nil) + db.compTimeMeter = metrics.GetOrRegisterMeter(namespace+"compact/time", nil) + db.compReadMeter = metrics.GetOrRegisterMeter(namespace+"compact/input", nil) + db.compWriteMeter = metrics.GetOrRegisterMeter(namespace+"compact/output", nil) + db.diskSizeGauge = metrics.GetOrRegisterGauge(namespace+"disk/size", nil) + db.diskReadMeter = metrics.GetOrRegisterMeter(namespace+"disk/read", nil) + db.diskWriteMeter = metrics.GetOrRegisterMeter(namespace+"disk/write", nil) + db.writeDelayMeter = metrics.GetOrRegisterMeter(namespace+"compact/writedelay/duration", nil) + db.writeDelayNMeter = metrics.GetOrRegisterMeter(namespace+"compact/writedelay/counter", nil) + db.memCompGauge = metrics.GetOrRegisterGauge(namespace+"compact/memory", nil) + db.level0CompGauge = metrics.GetOrRegisterGauge(namespace+"compact/level0", nil) + db.nonlevel0CompGauge = metrics.GetOrRegisterGauge(namespace+"compact/nonlevel0", nil) + db.seekCompGauge = metrics.GetOrRegisterGauge(namespace+"compact/seek", nil) + db.manualMemAllocGauge = metrics.GetOrRegisterGauge(namespace+"memory/manualalloc", nil) // Start up the metrics gathering and return go db.meter(metricsGatheringInterval, namespace) @@ -303,7 +303,9 @@ func (d *Database) Has(key []byte) (bool, error) { } else if err != nil { return false, err } - closer.Close() + if err = closer.Close(); err != nil { + return false, err + } return true, nil } @@ -320,7 +322,9 @@ func (d *Database) Get(key []byte) ([]byte, error) { } ret := make([]byte, len(dat)) copy(ret, dat) - closer.Close() + if err = closer.Close(); err != nil { + return nil, err + } return ret, nil } @@ -361,55 +365,6 @@ func (d *Database) NewBatchWithSize(size int) ethdb.Batch { } } -// snapshot wraps a pebble snapshot for implementing the Snapshot interface. -type snapshot struct { - db *pebble.Snapshot -} - -// NewSnapshot creates a database snapshot based on the current state. -// The created snapshot will not be affected by all following mutations -// happened on the database. -// Note don't forget to release the snapshot once it's used up, otherwise -// the stale data will never be cleaned up by the underlying compactor. -func (d *Database) NewSnapshot() (ethdb.Snapshot, error) { - snap := d.db.NewSnapshot() - return &snapshot{db: snap}, nil -} - -// Has retrieves if a key is present in the snapshot backing by a key-value -// data store. -func (snap *snapshot) Has(key []byte) (bool, error) { - _, closer, err := snap.db.Get(key) - if err != nil { - if err != pebble.ErrNotFound { - return false, err - } else { - return false, nil - } - } - closer.Close() - return true, nil -} - -// Get retrieves the given key if it's present in the snapshot backing by -// key-value data store. -func (snap *snapshot) Get(key []byte) ([]byte, error) { - dat, closer, err := snap.db.Get(key) - if err != nil { - return nil, err - } - ret := make([]byte, len(dat)) - copy(ret, dat) - closer.Close() - return ret, nil -} - -// Release releases associated resources. Release should always succeed and can -// be called multiple times without causing error. -func (snap *snapshot) Release() { - snap.db.Close() -} - // upperBound returns the upper bound for the given prefix func upperBound(prefix []byte) (limit []byte) { for i := len(prefix) - 1; i >= 0; i-- { @@ -426,10 +381,8 @@ func upperBound(prefix []byte) (limit []byte) { } // Stat returns the internal metrics of Pebble in a text format. It's a developer -// method to read everything there is to read independent of Pebble version. -// -// The property is unused in Pebble as there's only one thing to retrieve. -func (d *Database) Stat(property string) (string, error) { +// method to read everything there is to read, independent of Pebble version. +func (d *Database) Stat() (string, error) { return d.db.Metrics().String(), nil } @@ -553,7 +506,7 @@ func (d *Database) meter(refresh time.Duration, namespace string) { for i, level := range stats.Levels { // Append metrics for additional layers if i >= len(d.levelsGauge) { - d.levelsGauge = append(d.levelsGauge, metrics.NewRegisteredGauge(namespace+fmt.Sprintf("tables/level%v", i), nil)) + d.levelsGauge = append(d.levelsGauge, metrics.GetOrRegisterGauge(namespace+fmt.Sprintf("tables/level%v", i), nil)) } d.levelsGauge[i].Update(level.NumFiles) } @@ -580,14 +533,18 @@ type batch struct { // Put inserts the given value into the batch for later committing. func (b *batch) Put(key, value []byte) error { - b.b.Set(key, value, nil) + if err := b.b.Set(key, value, nil); err != nil { + return err + } b.size += len(key) + len(value) return nil } -// Delete inserts the a key removal into the batch for later committing. +// Delete inserts the key removal into the batch for later committing. func (b *batch) Delete(key []byte) error { - b.b.Delete(key, nil) + if err := b.b.Delete(key, nil); err != nil { + return err + } b.size += len(key) return nil } @@ -619,19 +576,22 @@ func (b *batch) Replay(w ethdb.KeyValueWriter) error { for { kind, k, v, ok, err := reader.Next() if !ok || err != nil { - break + return err } // The (k,v) slices might be overwritten if the batch is reset/reused, // and the receiver should copy them if they are to be retained long-term. if kind == pebble.InternalKeyKindSet { - w.Put(k, v) + if err = w.Put(k, v); err != nil { + return err + } } else if kind == pebble.InternalKeyKindDelete { - w.Delete(k) + if err = w.Delete(k); err != nil { + return err + } } else { return fmt.Errorf("unhandled operation, keytype: %v", kind) } } - return nil } // pebbleIterator is a wrapper of underlying iterator in storage engine. diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index f755dd16bc..e0fd9d1f8a 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -176,10 +176,6 @@ func (db *Database) Sync() error { return nil } -func (db *Database) MigrateTable(s string, f func([]byte) ([]byte, error)) error { - panic("not supported") -} - func (db *Database) NewBatch() ethdb.Batch { panic("not supported") } @@ -192,8 +188,8 @@ func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator { panic("not supported") } -func (db *Database) Stat(property string) (string, error) { - panic("not supported") +func (db *Database) Stat() (string, error) { + return "", nil } func (db *Database) AncientDatadir() (string, error) { @@ -204,10 +200,6 @@ func (db *Database) Compact(start []byte, limit []byte) error { return nil } -func (db *Database) NewSnapshot() (ethdb.Snapshot, error) { - panic("not supported") -} - func (db *Database) Close() error { db.remote.Close() return nil diff --git a/ethdb/snapshot.go b/ethdb/snapshot.go deleted file mode 100644 index 03b7794a77..0000000000 --- a/ethdb/snapshot.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ethdb - -type Snapshot interface { - // Has retrieves if a key is present in the snapshot backing by a key-value - // data store. - Has(key []byte) (bool, error) - - // Get retrieves the given key if it's present in the snapshot backing by - // key-value data store. - Get(key []byte) ([]byte, error) - - // Release releases associated resources. Release should always succeed and can - // be called multiple times without causing error. - Release() -} - -// Snapshotter wraps the Snapshot method of a backing data store. -type Snapshotter interface { - // NewSnapshot creates a database snapshot based on the current state. - // The created snapshot will not be affected by all following mutations - // happened on the database. - // Note don't forget to release the snapshot once it's used up, otherwise - // the stale data will never be cleaned up by the underlying compactor. - NewSnapshot() (Snapshot, error) -} diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 61ceec443e..61c755d542 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -552,10 +552,13 @@ func (s *Service) reportLatency(conn *connWrapper) error { return err } // Wait for the pong request to arrive back + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { case <-s.pongCh: // Pong delivered, report the latency - case <-time.After(5 * time.Second): + case <-timer.C: // Ping timeout, abort return errors.New("ping timed out") } @@ -778,7 +781,6 @@ type nodeStats struct { Active bool `json:"active"` Syncing bool `json:"syncing"` Mining bool `json:"mining"` - Hashrate int `json:"hashrate"` Peers int `json:"peers"` GasPrice int `json:"gasPrice"` Uptime int `json:"uptime"` @@ -790,7 +792,6 @@ func (s *Service) reportStats(conn *connWrapper) error { // Gather the syncing and mining infos from the local miner instance var ( mining bool - hashrate int syncing bool gasprice int ) @@ -798,7 +799,6 @@ func (s *Service) reportStats(conn *connWrapper) error { if fullBackend, ok := s.backend.(fullNodeBackend); ok { if miningBackend, ok := s.backend.(miningNodeBackend); ok { mining = miningBackend.Miner().Mining() - hashrate = int(miningBackend.Miner().Hashrate()) } sync := fullBackend.SyncProgress() @@ -821,7 +821,6 @@ func (s *Service) reportStats(conn *connWrapper) error { "stats": &nodeStats{ Active: true, Mining: mining, - Hashrate: hashrate, Peers: s.server.PeerCount(), GasPrice: gasprice, Syncing: syncing, diff --git a/event/multisub.go b/event/multisub.go index 5c8d2df48c..1f0af2a292 100644 --- a/event/multisub.go +++ b/event/multisub.go @@ -17,7 +17,7 @@ package event // JoinSubscriptions joins multiple subscriptions to be able to track them as -// one entity and collectively cancel them of consume any errors from them. +// one entity and collectively cancel them or consume any errors from them. func JoinSubscriptions(subs ...Subscription) Subscription { return NewSubscription(func(unsubbed <-chan struct{}) error { // Unsubscribe all subscriptions before returning diff --git a/go.mod b/go.mod index 55c619ba3b..fb0f416c42 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,12 @@ module github.com/ethereum/go-ethereum -go 1.21 +go 1.22 + +toolchain go1.22.0 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 - github.com/Microsoft/go-winio v0.6.1 + github.com/Microsoft/go-winio v0.6.2 github.com/VictoriaMetrics/fastcache v1.12.2 github.com/aws/aws-sdk-go-v2 v1.21.2 github.com/aws/aws-sdk-go-v2/config v1.18.45 @@ -15,42 +17,43 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/cespare/cp v1.1.1 github.com/cloudflare/cloudflare-go v0.79.0 - github.com/cockroachdb/pebble v1.1.0 + github.com/cockroachdb/pebble v1.1.2 github.com/cometbft/cometbft v0.37.0 github.com/consensys/gnark-crypto v0.12.1 - github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c github.com/crate-crypto/go-kzg-4844 v0.7.0 github.com/davecgh/go-spew v1.1.1 - github.com/deckarep/golang-set/v2 v2.5.0 + github.com/deckarep/golang-set/v2 v2.6.0 + github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 - github.com/ethereum/c-kzg-4844 v0.4.0 + github.com/ethereum/c-kzg-4844 v1.0.0 + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 github.com/fatih/color v1.16.0 github.com/fatih/structs v1.1.0 github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 - github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 github.com/gofrs/flock v0.8.1 github.com/golang-jwt/jwt/v4 v4.5.0 - github.com/golang/protobuf v1.5.4 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/gofuzz v1.2.0 github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 github.com/google/uuid v1.5.0 + github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.1 github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-bexpr v0.1.10 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 github.com/holiman/bloomfilter/v2 v2.0.3 - github.com/holiman/uint256 v1.2.4 + github.com/holiman/uint256 v1.3.1 github.com/huin/goupnp v1.3.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 - github.com/julienschmidt/httprouter v1.3.0 - github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c + github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 + github.com/kilic/bls12-381 v0.1.0 github.com/kylelemons/godebug v1.1.0 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/mattn/go-colorable v0.1.13 @@ -61,14 +64,16 @@ require ( github.com/peterh/liner v1.2.0 github.com/pkg/errors v0.9.1 github.com/prometheus/tsdb v0.10.0 - github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 + github.com/protolambda/bls12-381-util v0.1.0 + github.com/protolambda/zrnt v0.32.2 + github.com/protolambda/ztyp v0.2.2 github.com/prysmaticlabs/prysm/v5 v5.0.3 github.com/rs/cors v1.8.2 github.com/shirou/gopsutil v3.21.11+incompatible github.com/status-im/keycard-go v0.2.0 - github.com/stretchr/testify v1.8.4 - github.com/supranational/blst v0.3.11 - github.com/syndtr/goleveldb v1.0.1 + github.com/stretchr/testify v1.9.0 + github.com/supranational/blst v0.3.13 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/go-amino v0.14.1 github.com/tendermint/iavl v0.12.0 github.com/tendermint/tendermint v0.31.15 @@ -78,14 +83,15 @@ require ( github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 github.com/willf/bitset v1.1.3 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.22.0 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a - golang.org/x/sync v0.6.0 - golang.org/x/sys v0.20.0 + golang.org/x/sync v0.7.0 + golang.org/x/sys v0.22.0 golang.org/x/text v0.14.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.18.0 - gopkg.in/natefinch/lumberjack.v2 v2.0.0 + golang.org/x/tools v0.20.0 + google.golang.org/protobuf v1.34.2 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -108,11 +114,12 @@ require ( github.com/aws/smithy-go v1.15.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.11.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cockroachdb/errors v1.11.1 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect @@ -134,7 +141,7 @@ require ( github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect - github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -149,10 +156,10 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect @@ -170,7 +177,6 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect github.com/klauspost/compress v1.17.6 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect @@ -270,17 +276,16 @@ require ( go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.19.0 // indirect google.golang.org/api v0.44.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apimachinery v0.20.0 // indirect @@ -296,6 +301,5 @@ require ( replace ( github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.3.1 github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 - github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.16 ) diff --git a/go.sum b/go.sum index e6940c07b4..b7deac6893 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,8 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1: github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -157,8 +157,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.11.0 h1:RMyy2mBBShArUAhfVRZJ2xyBO58KCBCtZFShw3umo6k= -github.com/bits-and-blooms/bitset v1.11.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bnb-chain/fastssz v0.1.2 h1:vTcXw5SwCtRYnl/BEclujiml7GXiVOZ74tub4GHpvlM= github.com/bnb-chain/fastssz v0.1.2/go.mod h1:KcabV+OEw2QwgyY8Fc88ZG79CKYkFdu0kKWyfA3dI6o= @@ -185,8 +185,9 @@ github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -210,12 +211,14 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= -github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= -github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= @@ -250,8 +253,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= @@ -266,8 +269,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/deckarep/golang-set/v2 v2.5.0 h1:hn6cEZtQ0h3J8kFrHR/NrzyOoTnjgW1+FmNJzQ7y/sA= -github.com/deckarep/golang-set/v2 v2.5.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -294,6 +297,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao= +github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= @@ -322,8 +327,10 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= -github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= @@ -355,12 +362,10 @@ github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILD github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= -github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -611,8 +616,9 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= @@ -665,12 +671,11 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c h1:AqsttAyEyIEsNz5WLRwuRwjiT5CMDUfLk6cFJDVPebs= -github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -1002,8 +1007,12 @@ github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c= -github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= +github.com/protolambda/bls12-381-util v0.1.0 h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk= +github.com/protolambda/bls12-381-util v0.1.0/go.mod h1:cdkysJTRpeFeuUVx/TXGDQNMTiRAalk1vQw3TYTHcE4= +github.com/protolambda/zrnt v0.32.2 h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM= +github.com/protolambda/zrnt v0.32.2/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs= +github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= +github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 h1:c3p3UzV4vFA7xaCDphnDWOjpxcadrQ26l5b+ypsvyxo= github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= @@ -1118,8 +1127,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1130,11 +1140,11 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -1283,8 +1293,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1323,8 +1333,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1376,8 +1386,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1408,8 +1418,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1500,13 +1510,13 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1592,8 +1602,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1735,8 +1745,8 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7 google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC2f0epmp1elRCiEGJTKAWbwxZ2nvqZdHl3FQXCY= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1758,8 +1768,8 @@ gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eR gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/graphql/graphql.go b/graphql/graphql.go index fd782206fb..e498f69d93 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -906,18 +906,6 @@ func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) { return header.Bloom.Bytes(), nil } -func (b *Block) TotalDifficulty(ctx context.Context) (hexutil.Big, error) { - hash, err := b.Hash(ctx) - if err != nil { - return hexutil.Big{}, err - } - td := b.r.backend.GetTd(ctx, hash) - if td == nil { - return hexutil.Big{}, fmt.Errorf("total difficulty not found %x", hash) - } - return hexutil.Big(*td), nil -} - func (b *Block) RawHeader(ctx context.Context) (hexutil.Bytes, error) { header, err := b.resolveHeader(ctx) if err != nil { @@ -1517,7 +1505,7 @@ func (s *SyncState) TxIndexRemainingBlocks() hexutil.Uint64 { } // Syncing returns false in case the node is currently not syncing with the network. It can be up-to-date or has not -// yet received the latest block headers from its pears. In case it is synchronizing: +// yet received the latest block headers from its peers. In case it is synchronizing: // - startingBlock: block number this node started to synchronize from // - currentBlock: block number this node is currently importing // - highestBlock: block number of the highest block header this node has received from peers diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index f3f9d1778a..a6be589a0f 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -338,8 +338,8 @@ func TestGraphQLConcurrentResolvers(t *testing.T) { }, // Multiple fields of block race to resolve header and body. { - body: "{ block { number hash gasLimit ommerCount transactionCount totalDifficulty } }", - want: fmt.Sprintf(`{"block":{"number":"0x1","hash":"%s","gasLimit":"0xaf79e0","ommerCount":"0x0","transactionCount":"0x3","totalDifficulty":"0x200000"}}`, chain[len(chain)-1].Hash()), + body: "{ block { number hash gasLimit ommerCount transactionCount } }", + want: fmt.Sprintf(`{"block":{"number":"0x1","hash":"%s","gasLimit":"0xaf79e0","ommerCount":"0x0","transactionCount":"0x3"}}`, chain[len(chain)-1].Hash()), }, // Multiple fields of a block race to resolve the header and body. { @@ -453,6 +453,7 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge TrieDirtyCache: 5, TrieTimeout: 60 * time.Minute, SnapshotCache: 5, + RPCGasCap: 1000000, StateScheme: rawdb.HashScheme, } var engine consensus.Engine = ethash.NewFaker() diff --git a/graphql/schema.go b/graphql/schema.go index 8264f1c286..15e4557915 100644 --- a/graphql/schema.go +++ b/graphql/schema.go @@ -232,9 +232,6 @@ const schema string = ` mixHash: Bytes32! # Difficulty is a measure of the difficulty of mining this block. difficulty: BigInt! - # TotalDifficulty is the sum of all difficulty values up to and including - # this block. - totalDifficulty: BigInt! # OmmerCount is the number of ommers (AKA uncles) associated with this # block. If ommers are unavailable, this field will be null. ommerCount: Long diff --git a/internal/build/archive.go b/internal/build/archive.go index 5b37c0edfa..645921c690 100644 --- a/internal/build/archive.go +++ b/internal/build/archive.go @@ -272,17 +272,22 @@ func extractFile(arpath string, armode os.FileMode, data io.Reader, dest string) return fmt.Errorf("path %q escapes archive destination", target) } - // Ensure the destination directory exists. + // Remove the preivously-extracted file if it exists + if err := os.RemoveAll(target); err != nil { + return err + } + + // Recreate the destination directory if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { return err } // Copy file data. - file, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, armode) + file, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, armode) if err != nil { return err } - if _, err := io.Copy(file, data); err != nil { + if _, err = io.Copy(file, data); err != nil { file.Close() os.Remove(target) return err diff --git a/internal/build/download.go b/internal/build/download.go index fda573df83..50268227a5 100644 --- a/internal/build/download.go +++ b/internal/build/download.go @@ -57,7 +57,7 @@ func (db *ChecksumDB) Verify(path string) error { } fileHash := hex.EncodeToString(h.Sum(nil)) if !db.findHash(filepath.Base(path), fileHash) { - return fmt.Errorf("invalid file hash %s for %s", fileHash, filepath.Base(path)) + return fmt.Errorf("invalid file hash: %s %s", fileHash, filepath.Base(path)) } return nil } @@ -84,10 +84,12 @@ func (db *ChecksumDB) DownloadFile(url, dstPath string) error { resp, err := http.Get(url) if err != nil { return fmt.Errorf("download error: %v", err) - } else if resp.StatusCode != http.StatusOK { - return fmt.Errorf("download error: status %d", resp.StatusCode) } defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("download error: status %d", resp.StatusCode) + } if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { return err } @@ -101,7 +103,6 @@ func (db *ChecksumDB) DownloadFile(url, dstPath string) error { if err != nil { return err } - return db.Verify(dstPath) } diff --git a/internal/build/env.go b/internal/build/env.go index 0854fba249..35b2cd6ae7 100644 --- a/internal/build/env.go +++ b/internal/build/env.go @@ -111,6 +111,7 @@ func LocalEnv() Environment { commitRe, _ := regexp.Compile("^([0-9a-f]{40})$") if commit := commitRe.FindString(head); commit != "" && env.Commit == "" { env.Commit = commit + env.Date = getDate(env.Commit) } return env } diff --git a/internal/build/util.go b/internal/build/util.go index b41014a16f..aee8bf0fc8 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -27,7 +27,6 @@ import ( "log" "os" "os/exec" - "path" "path/filepath" "strconv" "strings" @@ -112,7 +111,7 @@ func RunGit(args ...string) string { // readGitFile returns content of file in .git directory. func readGitFile(file string) string { - content, err := os.ReadFile(path.Join(".git", file)) + content, err := os.ReadFile(filepath.Join(".git", file)) if err != nil { return "" } @@ -175,7 +174,7 @@ func UploadSFTP(identityFile, host, dir string, files []string) error { } in := io.MultiWriter(stdin, os.Stdout) for _, f := range files { - fmt.Fprintln(in, "put", f, path.Join(dir, filepath.Base(f))) + fmt.Fprintln(in, "put", f, filepath.Join(dir, filepath.Base(f))) } fmt.Fprintln(in, "exit") // Some issue with the PPA sftp server makes it so the server does not diff --git a/internal/debug/api.go b/internal/debug/api.go index 482989e0d0..5e93585bf8 100644 --- a/internal/debug/api.go +++ b/internal/debug/api.go @@ -37,7 +37,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/hashicorp/go-bexpr" - "golang.org/x/exp/slog" ) // Handler is the global debugging handler. @@ -57,7 +56,7 @@ type HandlerT struct { // Verbosity sets the log verbosity ceiling. The verbosity of individual packages // and source files can be raised using Vmodule. func (*HandlerT) Verbosity(level int) { - glogger.Verbosity(slog.Level(level)) + glogger.Verbosity(log.FromLegacyLevel(level)) } // Vmodule sets the log verbosity pattern. See package log for details on the diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 29f7142587..0e05975c7e 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -19,6 +19,7 @@ package debug import ( "fmt" "io" + "log/slog" "net" "net/http" _ "net/http/pprof" @@ -33,7 +34,6 @@ import ( "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" - "golang.org/x/exp/slog" "gopkg.in/natefinch/lumberjack.v2" ) diff --git a/internal/era/accumulator.go b/internal/era/accumulator.go index 8be05cfff4..795c829b0e 100644 --- a/internal/era/accumulator.go +++ b/internal/era/accumulator.go @@ -17,6 +17,7 @@ package era import ( + "errors" "fmt" "math/big" @@ -29,7 +30,7 @@ import ( // accumulator of header records. func ComputeAccumulator(hashes []common.Hash, tds []*big.Int) (common.Hash, error) { if len(hashes) != len(tds) { - return common.Hash{}, fmt.Errorf("must have equal number hashes as td values") + return common.Hash{}, errors.New("must have equal number hashes as td values") } if len(hashes) > MaxEra1Size { return common.Hash{}, fmt.Errorf("too many records: have %d, max %d", len(hashes), MaxEra1Size) diff --git a/internal/era/builder.go b/internal/era/builder.go index 9217c049f3..75782a08c2 100644 --- a/internal/era/builder.go +++ b/internal/era/builder.go @@ -18,6 +18,7 @@ package era import ( "bytes" "encoding/binary" + "errors" "fmt" "io" "math/big" @@ -158,7 +159,7 @@ func (b *Builder) AddRLP(header, body, receipts []byte, number uint64, hash comm // corresponding e2store entries. func (b *Builder) Finalize() (common.Hash, error) { if b.startNum == nil { - return common.Hash{}, fmt.Errorf("finalize called on empty builder") + return common.Hash{}, errors.New("finalize called on empty builder") } // Compute accumulator root and write entry. root, err := ComputeAccumulator(b.hashes, b.tds) diff --git a/internal/era/e2store/e2store.go b/internal/era/e2store/e2store.go index d85b3e44e9..8e4d5dd24a 100644 --- a/internal/era/e2store/e2store.go +++ b/internal/era/e2store/e2store.go @@ -18,6 +18,7 @@ package e2store import ( "encoding/binary" + "errors" "fmt" "io" ) @@ -160,7 +161,7 @@ func (r *Reader) ReadMetadataAt(off int64) (typ uint16, length uint32, err error // Check reserved bytes of header. if b[6] != 0 || b[7] != 0 { - return 0, 0, fmt.Errorf("reserved bytes are non-zero") + return 0, 0, errors.New("reserved bytes are non-zero") } return typ, length, nil diff --git a/internal/era/e2store/e2store_test.go b/internal/era/e2store/e2store_test.go index febcffe4cf..353942f0bd 100644 --- a/internal/era/e2store/e2store_test.go +++ b/internal/era/e2store/e2store_test.go @@ -18,7 +18,7 @@ package e2store import ( "bytes" - "fmt" + "errors" "io" "testing" @@ -26,6 +26,8 @@ import ( ) func TestEncode(t *testing.T) { + t.Parallel() + for _, test := range []struct { entries []Entry want string @@ -53,6 +55,7 @@ func TestEncode(t *testing.T) { tt := test t.Run(tt.name, func(t *testing.T) { t.Parallel() + var ( b = bytes.NewBuffer(nil) w = NewWriter(b) @@ -83,6 +86,8 @@ func TestEncode(t *testing.T) { } func TestDecode(t *testing.T) { + t.Parallel() + for i, tt := range []struct { have string err error @@ -92,7 +97,7 @@ func TestDecode(t *testing.T) { }, { // basic invalid decoding have: "ffff000000000001", - err: fmt.Errorf("reserved bytes are non-zero"), + err: errors.New("reserved bytes are non-zero"), }, { // no more entries to read, returns EOF have: "", diff --git a/internal/era/era.go b/internal/era/era.go index a0e701b7e0..6ad7339b36 100644 --- a/internal/era/era.go +++ b/internal/era/era.go @@ -18,6 +18,7 @@ package era import ( "encoding/binary" + "errors" "fmt" "io" "math/big" @@ -127,7 +128,7 @@ func (e *Era) Close() error { func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) { if e.m.start > num || e.m.start+e.m.count <= num { - return nil, fmt.Errorf("out-of-bounds") + return nil, errors.New("out-of-bounds") } off, err := e.readOffset(num) if err != nil { @@ -150,7 +151,7 @@ func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) { if err := rlp.Decode(r, &body); err != nil { return nil, err } - return types.NewBlockWithHeader(&header).WithBody(body.Transactions, body.Uncles), nil + return types.NewBlockWithHeader(&header).WithBody(body), nil } // Accumulator reads the accumulator entry in the Era1 file. @@ -228,7 +229,7 @@ func (e *Era) readOffset(n uint64) (int64, error) { ) e.mu.Lock() defer e.mu.Unlock() - clearBuffer(e.buf[:]) + clear(e.buf[:]) if _, err := e.f.ReadAt(e.buf[:], offOffset); err != nil { return 0, err } @@ -238,7 +239,7 @@ func (e *Era) readOffset(n uint64) (int64, error) { return blockIndexRecordOffset + int64(binary.LittleEndian.Uint64(e.buf[:])), nil } -// newReader returns a snappy.Reader for the e2store entry value at off. +// newSnappyReader returns a snappy.Reader for the e2store entry value at off. func newSnappyReader(e *e2store.Reader, expectedType uint16, off int64) (io.Reader, int64, error) { r, n, err := e.ReaderAt(expectedType, off) if err != nil { @@ -247,13 +248,6 @@ func newSnappyReader(e *e2store.Reader, expectedType uint16, off int64) (io.Read return snappy.NewReader(r), int64(n), err } -// clearBuffer zeroes out the buffer. -func clearBuffer(buf []byte) { - for i := 0; i < len(buf); i++ { - buf[i] = 0 - } -} - // metadata wraps the metadata in the block index. type metadata struct { start uint64 diff --git a/internal/era/era_test.go b/internal/era/era_test.go index ee5d9e82a0..d0f56b6f88 100644 --- a/internal/era/era_test.go +++ b/internal/era/era_test.go @@ -34,6 +34,8 @@ type testchain struct { } func TestEra1Builder(t *testing.T) { + t.Parallel() + // Get temp directory. f, err := os.CreateTemp("", "era1-test") if err != nil { @@ -125,6 +127,8 @@ func TestEra1Builder(t *testing.T) { } func TestEraFilename(t *testing.T) { + t.Parallel() + for i, tt := range []struct { network string epoch int @@ -132,7 +136,6 @@ func TestEraFilename(t *testing.T) { expected string }{ {"mainnet", 1, common.Hash{1}, "mainnet-00001-01000000.era1"}, - {"goerli", 99999, common.HexToHash("0xdeadbeef00000000000000000000000000000000000000000000000000000000"), "goerli-99999-deadbeef.era1"}, } { got := Filename(tt.network, tt.epoch, tt.root) if tt.expected != got { diff --git a/internal/era/iterator.go b/internal/era/iterator.go index e74a8154b1..f48aab46b4 100644 --- a/internal/era/iterator.go +++ b/internal/era/iterator.go @@ -17,7 +17,7 @@ package era import ( - "fmt" + "errors" "io" "math/big" @@ -30,7 +30,7 @@ type Iterator struct { inner *RawIterator } -// NewRawIterator returns a new Iterator instance. Next must be immediately +// NewIterator returns a new Iterator instance. Next must be immediately // called on new iterators to load the first item. func NewIterator(e *Era) (*Iterator, error) { inner, err := NewRawIterator(e) @@ -61,7 +61,7 @@ func (it *Iterator) Error() error { // Block returns the block for the iterator's current position. func (it *Iterator) Block() (*types.Block, error) { if it.inner.Header == nil || it.inner.Body == nil { - return nil, fmt.Errorf("header and body must be non-nil") + return nil, errors.New("header and body must be non-nil") } var ( header types.Header @@ -73,13 +73,13 @@ func (it *Iterator) Block() (*types.Block, error) { if err := rlp.Decode(it.inner.Body, &body); err != nil { return nil, err } - return types.NewBlockWithHeader(&header).WithBody(body.Transactions, body.Uncles), nil + return types.NewBlockWithHeader(&header).WithBody(body), nil } // Receipts returns the receipts for the iterator's current position. func (it *Iterator) Receipts() (types.Receipts, error) { if it.inner.Receipts == nil { - return nil, fmt.Errorf("receipts must be non-nil") + return nil, errors.New("receipts must be non-nil") } var receipts types.Receipts err := rlp.Decode(it.inner.Receipts, &receipts) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0f029a503d..772cc1a304 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -21,12 +21,12 @@ import ( "encoding/hex" "errors" "fmt" + "maps" "math/big" "strings" "time" "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/scwallet" @@ -39,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -81,20 +82,20 @@ func NewEthereumAPI(b Backend) *EthereumAPI { } // GasPrice returns a suggestion for a gas price for legacy transactions. -func (s *EthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { - tipcap, err := s.b.SuggestGasTipCap(ctx) +func (api *EthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { + tipcap, err := api.b.SuggestGasTipCap(ctx) if err != nil { return nil, err } - if head := s.b.CurrentHeader(); head.BaseFee != nil { + if head := api.b.CurrentHeader(); head.BaseFee != nil { tipcap.Add(tipcap, head.BaseFee) } return (*hexutil.Big)(tipcap), err } // MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. -func (s *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { - tipcap, err := s.b.SuggestGasTipCap(ctx) +func (api *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { + tipcap, err := api.b.SuggestGasTipCap(ctx) if err != nil { return nil, err } @@ -102,15 +103,17 @@ func (s *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, e } type feeHistoryResult struct { - OldestBlock *hexutil.Big `json:"oldestBlock"` - Reward [][]*hexutil.Big `json:"reward,omitempty"` - BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` - GasUsedRatio []float64 `json:"gasUsedRatio"` + OldestBlock *hexutil.Big `json:"oldestBlock"` + Reward [][]*hexutil.Big `json:"reward,omitempty"` + BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` + GasUsedRatio []float64 `json:"gasUsedRatio"` + BlobBaseFee []*hexutil.Big `json:"baseFeePerBlobGas,omitempty"` + BlobGasUsedRatio []float64 `json:"blobGasUsedRatio,omitempty"` } // FeeHistory returns the fee market history. -func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecimal64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { - oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, uint64(blockCount), lastBlock, rewardPercentiles) +func (api *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecimal64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { + oldest, reward, baseFee, gasUsed, blobBaseFee, blobGasUsed, err := api.b.FeeHistory(ctx, uint64(blockCount), lastBlock, rewardPercentiles) if err != nil { return nil, err } @@ -133,18 +136,32 @@ func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecim results.BaseFee[i] = (*hexutil.Big)(v) } } + if blobBaseFee != nil { + results.BlobBaseFee = make([]*hexutil.Big, len(blobBaseFee)) + for i, v := range blobBaseFee { + results.BlobBaseFee[i] = (*hexutil.Big)(v) + } + } + if blobGasUsed != nil { + results.BlobGasUsedRatio = blobGasUsed + } return results, nil } +// BlobBaseFee returns the base fee for blob gas at the current head. +func (api *EthereumAPI) BlobBaseFee(ctx context.Context) *hexutil.Big { + return (*hexutil.Big)(api.b.BlobBaseFee(ctx)) +} + // Syncing returns false in case the node is currently not syncing with the network. It can be up-to-date or has not -// yet received the latest block headers from its pears. In case it is synchronizing: +// yet received the latest block headers from its peers. In case it is synchronizing: // - startingBlock: block number this node started to synchronize from // - currentBlock: block number this node is currently importing // - highestBlock: block number of the highest block header this node has received from peers // - pulledStates: number of state entries processed until now // - knownStates: number of known state entries that still need to be pulled -func (s *EthereumAPI) Syncing() (interface{}, error) { - progress := s.b.SyncProgress() +func (api *EthereumAPI) Syncing() (interface{}, error) { + progress := api.b.SyncProgress() // Return not syncing if the synchronisation already completed if progress.Done() { @@ -183,18 +200,18 @@ func NewTxPoolAPI(b Backend) *TxPoolAPI { } // Content returns the transactions contained within the transaction pool. -func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { +func (api *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { content := map[string]map[string]map[string]*RPCTransaction{ "pending": make(map[string]map[string]*RPCTransaction), "queued": make(map[string]map[string]*RPCTransaction), } - pending, queue := s.b.TxPoolContent() - curHeader := s.b.CurrentHeader() + pending, queue := api.b.TxPoolContent() + curHeader := api.b.CurrentHeader() // Flatten the pending transactions for account, txs := range pending { dump := make(map[string]*RPCTransaction) for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) + dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) } content["pending"][account.Hex()] = dump } @@ -202,7 +219,7 @@ func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { for account, txs := range queue { dump := make(map[string]*RPCTransaction) for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) + dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) } content["queued"][account.Hex()] = dump } @@ -210,22 +227,22 @@ func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { } // ContentFrom returns the transactions contained within the transaction pool. -func (s *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction { +func (api *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction { content := make(map[string]map[string]*RPCTransaction, 2) - pending, queue := s.b.TxPoolContentFrom(addr) - curHeader := s.b.CurrentHeader() + pending, queue := api.b.TxPoolContentFrom(addr) + curHeader := api.b.CurrentHeader() // Build the pending transactions dump := make(map[string]*RPCTransaction, len(pending)) for _, tx := range pending { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) + dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) } content["pending"] = dump // Build the queued transactions dump = make(map[string]*RPCTransaction, len(queue)) for _, tx := range queue { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) + dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) } content["queued"] = dump @@ -233,8 +250,8 @@ func (s *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCT } // Status returns the number of pending and queued transaction in the pool. -func (s *TxPoolAPI) Status() map[string]hexutil.Uint { - pending, queue := s.b.Stats() +func (api *TxPoolAPI) Status() map[string]hexutil.Uint { + pending, queue := api.b.Stats() return map[string]hexutil.Uint{ "pending": hexutil.Uint(pending), "queued": hexutil.Uint(queue), @@ -243,12 +260,12 @@ func (s *TxPoolAPI) Status() map[string]hexutil.Uint { // Inspect retrieves the content of the transaction pool and flattens it into an // easily inspectable list. -func (s *TxPoolAPI) Inspect() map[string]map[string]map[string]string { +func (api *TxPoolAPI) Inspect() map[string]map[string]map[string]string { content := map[string]map[string]map[string]string{ "pending": make(map[string]map[string]string), "queued": make(map[string]map[string]string), } - pending, queue := s.b.TxPoolContent() + pending, queue := api.b.TxPoolContent() // Define a formatter to flatten a transaction into a string var format = func(tx *types.Transaction) string { @@ -288,8 +305,8 @@ func NewEthereumAccountAPI(am *accounts.Manager) *EthereumAccountAPI { } // Accounts returns the collection of accounts this node manages. -func (s *EthereumAccountAPI) Accounts() []common.Address { - return s.am.Accounts() +func (api *EthereumAccountAPI) Accounts() []common.Address { + return api.am.Accounts() } // PersonalAccountAPI provides an API to access accounts managed by this node. @@ -311,8 +328,8 @@ func NewPersonalAccountAPI(b Backend, nonceLock *AddrLocker) *PersonalAccountAPI } // ListAccounts will return a list of addresses for accounts this node manages. -func (s *PersonalAccountAPI) ListAccounts() []common.Address { - return s.am.Accounts() +func (api *PersonalAccountAPI) ListAccounts() []common.Address { + return api.am.Accounts() } // rawWallet is a JSON representation of an accounts.Wallet interface, with its @@ -325,9 +342,9 @@ type rawWallet struct { } // ListWallets will return a list of wallets this node manages. -func (s *PersonalAccountAPI) ListWallets() []rawWallet { +func (api *PersonalAccountAPI) ListWallets() []rawWallet { wallets := make([]rawWallet, 0) // return [] instead of nil if empty - for _, wallet := range s.am.Wallets() { + for _, wallet := range api.am.Wallets() { status, failure := wallet.Status() raw := rawWallet{ @@ -347,8 +364,8 @@ func (s *PersonalAccountAPI) ListWallets() []rawWallet { // connection and attempting to authenticate via the provided passphrase. Note, // the method may return an extra challenge requiring a second open (e.g. the // Trezor PIN matrix challenge). -func (s *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error { - wallet, err := s.am.Wallet(url) +func (api *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error { + wallet, err := api.am.Wallet(url) if err != nil { return err } @@ -361,8 +378,8 @@ func (s *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error { // DeriveAccount requests an HD wallet to derive a new account, optionally pinning // it for later reuse. -func (s *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { - wallet, err := s.am.Wallet(url) +func (api *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { + wallet, err := api.am.Wallet(url) if err != nil { return accounts.Account{}, err } @@ -377,8 +394,8 @@ func (s *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) ( } // NewAccount will create a new account and returns the address for the new account. -func (s *PersonalAccountAPI) NewAccount(password string) (common.AddressEIP55, error) { - ks, err := fetchKeystore(s.am) +func (api *PersonalAccountAPI) NewAccount(password string) (common.AddressEIP55, error) { + ks, err := fetchKeystore(api.am) if err != nil { return common.AddressEIP55{}, err } @@ -403,12 +420,12 @@ func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { // ImportRawKey stores the given hex encoded ECDSA key into the key directory, // encrypting it with the passphrase. -func (s *PersonalAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { +func (api *PersonalAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { key, err := crypto.HexToECDSA(privkey) if err != nil { return common.Address{}, err } - ks, err := fetchKeystore(s.am) + ks, err := fetchKeystore(api.am) if err != nil { return common.Address{}, err } @@ -419,11 +436,11 @@ func (s *PersonalAccountAPI) ImportRawKey(privkey string, password string) (comm // UnlockAccount will unlock the account associated with the given address with // the given password for duration seconds. If duration is nil it will use a // default of 300 seconds. It returns an indication if the account was unlocked. -func (s *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { +func (api *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { // When the API is exposed by external RPC(http, ws etc), unless the user // explicitly specifies to allow the insecure account unlocking, otherwise // it is disabled. - if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { + if api.b.ExtRPCEnabled() && !api.b.AccountManager().Config().InsecureUnlockAllowed { return false, errors.New("account unlock with HTTP access is forbidden") } @@ -436,7 +453,7 @@ func (s *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Addr } else { d = time.Duration(*duration) * time.Second } - ks, err := fetchKeystore(s.am) + ks, err := fetchKeystore(api.am) if err != nil { return false, err } @@ -448,8 +465,8 @@ func (s *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Addr } // LockAccount will lock the account associated with the given address when it's unlocked. -func (s *PersonalAccountAPI) LockAccount(addr common.Address) bool { - if ks, err := fetchKeystore(s.am); err == nil { +func (api *PersonalAccountAPI) LockAccount(addr common.Address) bool { + if ks, err := fetchKeystore(api.am); err == nil { return ks.Lock(addr) == nil } return false @@ -458,49 +475,49 @@ func (s *PersonalAccountAPI) LockAccount(addr common.Address) bool { // signTransaction sets defaults and signs the given transaction // NOTE: the caller needs to ensure that the nonceLock is held, if applicable, // and release it after the transaction has been submitted to the tx pool -func (s *PersonalAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) { +func (api *PersonalAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: args.from()} - wallet, err := s.am.Find(account) + wallet, err := api.am.Find(account) if err != nil { return nil, err } // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b, false); err != nil { + if err := args.setDefaults(ctx, api.b, false); err != nil { return nil, err } // Assemble the transaction and sign with the wallet - tx := args.toTransaction() + tx := args.ToTransaction(types.LegacyTxType) - return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) + return wallet.SignTxWithPassphrase(account, passwd, tx, api.b.ChainConfig().ChainID) } // SendTransaction will create a transaction from the given arguments and // tries to sign it with the key associated with args.From. If the given // passwd isn't able to decrypt the key it fails. -func (s *PersonalAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) { +func (api *PersonalAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) { if args.Nonce == nil { // Hold the mutex around signing to prevent concurrent assignment of // the same nonce to multiple accounts. - s.nonceLock.LockAddr(args.from()) - defer s.nonceLock.UnlockAddr(args.from()) + api.nonceLock.LockAddr(args.from()) + defer api.nonceLock.UnlockAddr(args.from()) } if args.IsEIP4844() { return common.Hash{}, errBlobTxNotSupported } - signed, err := s.signTransaction(ctx, &args, passwd) + signed, err := api.signTransaction(ctx, &args, passwd) if err != nil { log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) return common.Hash{}, err } - return SubmitTransaction(ctx, s.b, signed) + return SubmitTransaction(ctx, api.b, signed) } // SignTransaction will create a transaction from the given arguments and // tries to sign it with the key associated with args.From. If the given passwd isn't // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast // to other nodes -func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) { +func (api *PersonalAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) { // No need to obtain the noncelock mutex, since we won't be sending this // tx into the transaction pool, but right back to the user if args.From == nil { @@ -519,11 +536,11 @@ func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args Transacti return nil, errors.New("nonce not specified") } // Before actually signing the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction() - if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { + tx := args.ToTransaction(types.LegacyTxType) + if err := checkTxFee(tx.GasPrice(), tx.Gas(), api.b.RPCTxFeeCap()); err != nil { return nil, err } - signed, err := s.signTransaction(ctx, &args, passwd) + signed, err := api.signTransaction(ctx, &args, passwd) if err != nil { log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) return nil, err @@ -544,11 +561,11 @@ func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args Transacti // The key used to calculate the signature is decrypted with the given password. // // https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-sign -func (s *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { +func (api *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: addr} - wallet, err := s.b.AccountManager().Find(account) + wallet, err := api.b.AccountManager().Find(account) if err != nil { return nil, err } @@ -572,7 +589,7 @@ func (s *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr // the V value must be 27 or 28 for legacy reasons. // // https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-ecrecover -func (s *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { +func (api *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { if len(sig) != crypto.SignatureLength { return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength) } @@ -589,8 +606,8 @@ func (s *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.By } // InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. -func (s *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { - wallet, err := s.am.Wallet(url) +func (api *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { + wallet, err := api.am.Wallet(url) if err != nil { return "", err } @@ -616,8 +633,8 @@ func (s *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) ( } // Unpair deletes a pairing between wallet and geth. -func (s *PersonalAccountAPI) Unpair(ctx context.Context, url string, pin string) error { - wallet, err := s.am.Wallet(url) +func (api *PersonalAccountAPI) Unpair(ctx context.Context, url string, pin string) error { + wallet, err := api.am.Wallet(url) if err != nil { return err } @@ -651,16 +668,16 @@ func (api *BlockChainAPI) ChainId() *hexutil.Big { } // BlockNumber returns the block number of the chain head. -func (s *BlockChainAPI) BlockNumber() hexutil.Uint64 { - header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available +func (api *BlockChainAPI) BlockNumber() hexutil.Uint64 { + header, _ := api.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available return hexutil.Uint64(header.Number.Uint64()) } // GetBalance returns the amount of wei for the given address in the state of the // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta // block numbers are also allowed. -func (s *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) +func (api *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -699,7 +716,7 @@ func (n *proofList) Delete(key []byte) error { } // GetProof returns the Merkle-proof for a given account and optionally some storage keys. -func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { +func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { var ( keys = make([]common.Hash, len(storageKeys)) keyLengths = make([]int, len(storageKeys)) @@ -713,7 +730,7 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st return nil, err } } - statedb, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + statedb, header, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if statedb == nil || err != nil { return nil, err } @@ -799,10 +816,10 @@ func decodeHash(s string) (h common.Hash, inputLength int, err error) { // - When blockNr is -2 the chain latest header is returned. // - When blockNr is -3 the chain finalized header is returned. // - When blockNr is -4 the chain safe header is returned. -func (s *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - header, err := s.b.HeaderByNumber(ctx, number) +func (api *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + header, err := api.b.HeaderByNumber(ctx, number) if header != nil && err == nil { - response := s.rpcMarshalHeader(ctx, header) + response := RPCMarshalHeader(header) if number == rpc.PendingBlockNumber { // Pending header need to nil out a few fields for _, field := range []string{"hash", "nonce", "miner"} { @@ -815,10 +832,10 @@ func (s *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockN } // GetHeaderByHash returns the requested header by hash. -func (s *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { - header, _ := s.b.HeaderByHash(ctx, hash) +func (api *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { + header, _ := api.b.HeaderByHash(ctx, hash) if header != nil { - return s.rpcMarshalHeader(ctx, header) + return RPCMarshalHeader(header) } return nil } @@ -830,27 +847,27 @@ func (s *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) m // - When blockNr is -4 the chain safe block is returned. // - When fullTx is true all transactions in the block are returned, otherwise // only the transaction hash is returned. -func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, number) +func (api *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { + block, err := api.b.BlockByNumber(ctx, number) if block != nil && err == nil { - response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) - if err == nil && number == rpc.PendingBlockNumber { + response := RPCMarshalBlock(block, true, fullTx, api.b.ChainConfig()) + if number == rpc.PendingBlockNumber { // Pending blocks need to nil out a few fields for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil } } - return response, err + return response, nil } return nil, err } // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full // detail, otherwise only the transaction hash is returned. -func (s *BlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, hash) +func (api *BlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { + block, err := api.b.BlockByHash(ctx, hash) if block != nil { - return s.rpcMarshalBlock(ctx, block, true, fullTx) + return RPCMarshalBlock(block, true, fullTx, api.b.ChainConfig()), nil } return nil, err } @@ -933,8 +950,8 @@ func (s *BlockChainAPI) GetFinalizedBlock(ctx context.Context, verifiedValidator } // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. -func (s *BlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, blockNr) +func (api *BlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { + block, err := api.b.BlockByNumber(ctx, blockNr) if block != nil { uncles := block.Uncles() if index >= hexutil.Uint(len(uncles)) { @@ -942,14 +959,14 @@ func (s *BlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, block return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return s.rpcMarshalBlock(ctx, block, false, false) + return RPCMarshalBlock(block, false, false, api.b.ChainConfig()), nil } return nil, err } // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. -func (s *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, blockHash) +func (api *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { + block, err := api.b.BlockByHash(ctx, blockHash) if block != nil { uncles := block.Uncles() if index >= hexutil.Uint(len(uncles)) { @@ -957,14 +974,14 @@ func (s *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHa return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return s.rpcMarshalBlock(ctx, block, false, false) + return RPCMarshalBlock(block, false, false, api.b.ChainConfig()), nil } return nil, err } // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number -func (s *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { +func (api *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { + if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { n := hexutil.Uint(len(block.Uncles())) return &n } @@ -972,8 +989,8 @@ func (s *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr } // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash -func (s *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { +func (api *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { + if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { n := hexutil.Uint(len(block.Uncles())) return &n } @@ -981,8 +998,8 @@ func (s *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash } // GetCode returns the code stored at the given address in the state for the given block number. -func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) +func (api *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -993,8 +1010,8 @@ func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blo // GetStorageAt returns the storage from the state at the given address, key and // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block // numbers are also allowed. -func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) +func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -1007,14 +1024,14 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address } // GetBlockReceipts returns the block receipts for the given block hash or number or tag. -func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { - block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) +func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { + block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) if block == nil || err != nil { // When the block doesn't exist, the RPC method should return JSON null // as per specification. return nil, nil } - receipts, err := s.b.GetReceipts(ctx, block.Hash()) + receipts, err := api.b.GetReceipts(ctx, block.Hash()) if err != nil { return nil, err } @@ -1024,7 +1041,7 @@ func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc. } // Derive the sender. - signer := types.MakeSigner(s.b.ChainConfig(), block.Number(), block.Time()) + signer := types.MakeSigner(api.b.ChainConfig(), block.Number(), block.Time()) result := make([]map[string]interface{}, len(receipts)) for i, receipt := range receipts { @@ -1088,102 +1105,167 @@ func (s *BlockChainAPI) GetBlobSidecarByTxHash(ctx context.Context, hash common. // of a message call. // Note, state and stateDiff can't be specified at the same time. If state is // set, message execution will only use the data in the given state. Otherwise -// if statDiff is set, all diff will be applied first and then execute the call +// if stateDiff is set, all diff will be applied first and then execute the call // message. type OverrideAccount struct { - Nonce *hexutil.Uint64 `json:"nonce"` - Code *hexutil.Bytes `json:"code"` - Balance **hexutil.Big `json:"balance"` - State *map[common.Hash]common.Hash `json:"state"` - StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` + Nonce *hexutil.Uint64 `json:"nonce"` + Code *hexutil.Bytes `json:"code"` + Balance *hexutil.Big `json:"balance"` + State map[common.Hash]common.Hash `json:"state"` + StateDiff map[common.Hash]common.Hash `json:"stateDiff"` + MovePrecompileTo *common.Address `json:"movePrecompileToAddress"` } // StateOverride is the collection of overridden accounts. type StateOverride map[common.Address]OverrideAccount +func (diff *StateOverride) has(address common.Address) bool { + _, ok := (*diff)[address] + return ok +} + // Apply overrides the fields of specified accounts into the given state. -func (diff *StateOverride) Apply(state *state.StateDB) error { +func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.PrecompiledContracts) error { if diff == nil { return nil } + // Tracks destinations of precompiles that were moved. + dirtyAddrs := make(map[common.Address]struct{}) for addr, account := range *diff { + // If a precompile was moved to this address already, it can't be overridden. + if _, ok := dirtyAddrs[addr]; ok { + return fmt.Errorf("account %s has already been overridden by a precompile", addr.Hex()) + } + p, isPrecompile := precompiles[addr] + // The MoveTo feature makes it possible to move a precompile + // code to another address. If the target address is another precompile + // the code for the latter is lost for this session. + // Note the destination account is not cleared upon move. + if account.MovePrecompileTo != nil { + if !isPrecompile { + return fmt.Errorf("account %s is not a precompile", addr.Hex()) + } + // Refuse to move a precompile to an address that has been + // or will be overridden. + if diff.has(*account.MovePrecompileTo) { + return fmt.Errorf("account %s is already overridden", account.MovePrecompileTo.Hex()) + } + precompiles[*account.MovePrecompileTo] = p + dirtyAddrs[*account.MovePrecompileTo] = struct{}{} + } + if isPrecompile { + delete(precompiles, addr) + } // Override account nonce. if account.Nonce != nil { - state.SetNonce(addr, uint64(*account.Nonce)) + statedb.SetNonce(addr, uint64(*account.Nonce)) } // Override account(contract) code. if account.Code != nil { - state.SetCode(addr, *account.Code) + statedb.SetCode(addr, *account.Code) } // Override account balance. if account.Balance != nil { - u256Balance, _ := uint256.FromBig((*big.Int)(*account.Balance)) - state.SetBalance(addr, u256Balance) + u256Balance, _ := uint256.FromBig((*big.Int)(account.Balance)) + statedb.SetBalance(addr, u256Balance, tracing.BalanceChangeUnspecified) } if account.State != nil && account.StateDiff != nil { return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) } // Replace entire state if caller requires. if account.State != nil { - state.SetStorage(addr, *account.State) + statedb.SetStorage(addr, account.State) } // Apply state diff into specified accounts. if account.StateDiff != nil { - for key, value := range *account.StateDiff { - state.SetState(addr, key, value) + for key, value := range account.StateDiff { + statedb.SetState(addr, key, value) } } } // Now finalize the changes. Finalize is normally performed between transactions. // By using finalize, the overrides are semantically behaving as // if they were created in a transaction just before the tracing occur. - state.Finalise(false) + statedb.Finalise(false) return nil } // BlockOverrides is a set of header fields to override. type BlockOverrides struct { - Number *hexutil.Big - Difficulty *hexutil.Big - Time *hexutil.Uint64 - GasLimit *hexutil.Uint64 - Coinbase *common.Address - Random *common.Hash - BaseFee *hexutil.Big - BlobBaseFee *hexutil.Big + Number *hexutil.Big + Difficulty *hexutil.Big // No-op if we're simulating post-merge calls. + Time *hexutil.Uint64 + GasLimit *hexutil.Uint64 + FeeRecipient *common.Address + PrevRandao *common.Hash + BaseFeePerGas *hexutil.Big + BlobBaseFee *hexutil.Big } // Apply overrides the given header fields into the given block context. -func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) { - if diff == nil { +func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) { + if o == nil { return } - if diff.Number != nil { - blockCtx.BlockNumber = diff.Number.ToInt() + if o.Number != nil { + blockCtx.BlockNumber = o.Number.ToInt() } - if diff.Difficulty != nil { - blockCtx.Difficulty = diff.Difficulty.ToInt() + if o.Difficulty != nil { + blockCtx.Difficulty = o.Difficulty.ToInt() } - if diff.Time != nil { - blockCtx.Time = uint64(*diff.Time) + if o.Time != nil { + blockCtx.Time = uint64(*o.Time) } - if diff.GasLimit != nil { - blockCtx.GasLimit = uint64(*diff.GasLimit) + if o.GasLimit != nil { + blockCtx.GasLimit = uint64(*o.GasLimit) } - if diff.Coinbase != nil { - blockCtx.Coinbase = *diff.Coinbase + if o.FeeRecipient != nil { + blockCtx.Coinbase = *o.FeeRecipient } - if diff.Random != nil { - blockCtx.Random = diff.Random + if o.PrevRandao != nil { + blockCtx.Random = o.PrevRandao } - if diff.BaseFee != nil { - blockCtx.BaseFee = diff.BaseFee.ToInt() + if o.BaseFeePerGas != nil { + blockCtx.BaseFee = o.BaseFeePerGas.ToInt() } - if diff.BlobBaseFee != nil { - blockCtx.BlobBaseFee = diff.BlobBaseFee.ToInt() + if o.BlobBaseFee != nil { + blockCtx.BlobBaseFee = o.BlobBaseFee.ToInt() } } +// MakeHeader returns a new header object with the overridden +// fields. +// Note: MakeHeader ignores BlobBaseFee if set. That's because +// header has no such field. +func (o *BlockOverrides) MakeHeader(header *types.Header) *types.Header { + if o == nil { + return header + } + h := types.CopyHeader(header) + if o.Number != nil { + h.Number = o.Number.ToInt() + } + if o.Difficulty != nil { + h.Difficulty = o.Difficulty.ToInt() + } + if o.Time != nil { + h.Time = uint64(*o.Time) + } + if o.GasLimit != nil { + h.GasLimit = uint64(*o.GasLimit) + } + if o.FeeRecipient != nil { + h.Coinbase = *o.FeeRecipient + } + if o.PrevRandao != nil { + h.MixDigest = *o.PrevRandao + } + if o.BaseFeePerGas != nil { + h.BaseFee = o.BaseFeePerGas.ToInt() + } + return h +} + // ChainContextBackend provides methods required to implement ChainContext. type ChainContextBackend interface { Engine() consensus.Engine @@ -1217,9 +1299,16 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H } func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { - if err := overrides.Apply(state); err != nil { + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + if blockOverrides != nil { + blockOverrides.Apply(&blockCtx) + } + rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time) + precompiles := maps.Clone(vm.ActivePrecompiledContracts(rules)) + if err := overrides.Apply(state, precompiles); err != nil { return nil, err } + // Setup context so it may be cancelled the call has completed // or, in case of unmetered gas, setup a context with a timeout. var cancel context.CancelFunc @@ -1231,18 +1320,38 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S // Make sure the context is cancelled when the call has completed // this makes sure resources are cleaned up. defer cancel() + gp := new(core.GasPool) + if globalGasCap == 0 { + gp.AddGas(math.MaxUint64) + } else { + gp.AddGas(globalGasCap) + } + return applyMessage(ctx, b, args, state, header, timeout, gp, &blockCtx, &vm.Config{NoBaseFee: true}, precompiles, true) +} +func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, timeout time.Duration, gp *core.GasPool, blockContext *vm.BlockContext, vmConfig *vm.Config, precompiles vm.PrecompiledContracts, skipChecks bool) (*core.ExecutionResult, error) { // Get a new instance of the EVM. - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) - if blockOverrides != nil { - blockOverrides.Apply(&blockCtx) - } - msg, err := args.ToMessage(globalGasCap, blockCtx.BaseFee) - if err != nil { + if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil { return nil, err } - evm := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx) + msg := args.ToMessage(header.BaseFee, skipChecks, skipChecks) + // Lower the basefee to 0 to avoid breaking EVM + // invariants (basefee < feecap). + if msg.GasPrice.Sign() == 0 { + blockContext.BaseFee = new(big.Int) + } + if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 { + blockContext.BlobBaseFee = new(big.Int) + } + evm := b.GetEVM(ctx, msg, state, header, vmConfig, blockContext) + if precompiles != nil { + evm.SetPrecompiles(precompiles) + } + + return applyMessageWithEVM(ctx, evm, msg, state, timeout, gp) +} +func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, state *state.StateDB, timeout time.Duration, gp *core.GasPool) (*core.ExecutionResult, error) { // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) gopool.Submit(func() { @@ -1251,7 +1360,6 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S }) // Execute the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) result, err := core.ApplyMessage(evm, msg, gp) if err := state.Error(); err != nil { return nil, err @@ -1274,7 +1382,6 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash if state == nil || err != nil { return nil, err } - return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap) } @@ -1284,12 +1391,12 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash // // Note, this function doesn't make and changes in the state/blockchain and is // useful to execute and retrieve values. -func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) { +func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) { if blockNrOrHash == nil { latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) blockNrOrHash = &latest } - result, err := DoCall(ctx, s.b, args, *blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) + result, err := DoCall(ctx, api.b, args, *blockNrOrHash, overrides, blockOverrides, api.b.RPCEVMTimeout(), api.b.RPCGasCap()) if err != nil { return nil, err } @@ -1300,6 +1407,45 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO return result.Return(), result.Err } +// SimulateV1 executes series of transactions on top of a base state. +// The transactions are packed into blocks. For each block, block header +// fields can be overridden. The state can also be overridden prior to +// execution of each block. +// +// Note, this function doesn't make any changes in the state/blockchain and is +// useful to execute and retrieve values. +func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { + if len(opts.BlockStateCalls) == 0 { + return nil, &invalidParamsError{message: "empty input"} + } else if len(opts.BlockStateCalls) > maxSimulateBlocks { + return nil, &clientLimitExceededError{message: "too many blocks"} + } + if blockNrOrHash == nil { + n := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + blockNrOrHash = &n + } + state, base, err := api.b.StateAndHeaderByNumberOrHash(ctx, *blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + gasCap := api.b.RPCGasCap() + if gasCap == 0 { + gasCap = math.MaxUint64 + } + sim := &simulator{ + b: api.b, + state: state, + base: base, + chainConfig: api.b.ChainConfig(), + // Each tx and all the series of txes shouldn't consume more gas than cap + gp: new(core.GasPool).AddGas(gasCap), + traceTransfers: opts.TraceTransfers, + validate: opts.Validation, + fullTx: opts.ReturnFullTransactions, + } + return sim.execute(ctx, opts.BlockStateCalls) +} + // DoEstimateGas returns the lowest possible gas limit that allows the transaction to run // successfully at block `blockNrOrHash`. It returns error if the transaction would revert, or if // there are unexpected failures. The gas limit is capped by both `args.Gas` (if non-nil & @@ -1310,7 +1456,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if state == nil || err != nil { return 0, err } - if err = overrides.Apply(state); err != nil { + if err := overrides.Apply(state, nil); err != nil { return 0, err } // Construct the gas estimator option from the user input @@ -1321,11 +1467,17 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr State: state, ErrorRatio: estimateGasErrorRatio, } - // Run the gas estimation andwrap any revertals into a custom return - call, err := args.ToMessage(gasCap, header.BaseFee) - if err != nil { + // Set any required transaction default, but make sure the gas cap itself is not messed with + // if it was not specified in the original argument list. + if args.Gas == nil { + args.Gas = new(hexutil.Uint64) + } + if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil { return 0, err } + call := args.ToMessage(header.BaseFee, true, true) + + // Run the gas estimation and wrap any revertals into a custom return estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap) if err != nil { if len(revert) > 0 { @@ -1342,12 +1494,12 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr // value is capped by both `args.Gas` (if non-nil & non-zero) and the backend's RPCGasCap // configuration (if non-zero). // Note: Required blob gas is not computed in this method. -func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Uint64, error) { +func (api *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Uint64, error) { bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } - return DoEstimateGas(ctx, s.b, args, bNrOrHash, overrides, s.b.RPCGasCap()) + return DoEstimateGas(ctx, api.b, args, bNrOrHash, overrides, api.b.RPCGasCap()) } func (s *BlockChainAPI) needToReplay(ctx context.Context, block *types.Block, accounts []common.Address) (bool, error) { @@ -1466,8 +1618,8 @@ func (s *BlockChainAPI) replay(ctx context.Context, block *types.Block, accounts if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) if balance.Cmp(common.U2560) > 0 { - statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0)) - statedb.AddBalance(block.Header().Coinbase, balance) + statedb.SetBalance(consensus.SystemAddress, uint256.NewInt(0), tracing.BalanceChangeUnspecified) + statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified) } } } @@ -1561,6 +1713,9 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { if head.ParentBeaconRoot != nil { result["parentBeaconBlockRoot"] = head.ParentBeaconRoot } + if head.RequestsHash != nil { + result["requestsRoot"] = head.RequestsHash + } return result } @@ -1596,25 +1751,10 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param if block.Header().WithdrawalsHash != nil { fields["withdrawals"] = block.Withdrawals() } - return fields -} - -// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires -// a `BlockchainAPI`. -func (s *BlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { - fields := RPCMarshalHeader(header) - fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) - return fields -} - -// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires -// a `BlockchainAPI`. -func (s *BlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields := RPCMarshalBlock(b, inclTx, fullTx, s.b.ChainConfig()) - if inclTx { - fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) + if block.Header().RequestsHash != nil { + fields["requests"] = block.Requests() } - return fields, nil + return fields } // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction @@ -1787,12 +1927,12 @@ type accessListResult struct { // CreateAccessList creates an EIP-2930 type AccessList for the given transaction. // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. -func (s *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { +func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } - acl, gasUsed, vmerr, err := AccessList(ctx, s.b, bNrOrHash, args) + acl, gasUsed, vmerr, err := AccessList(ctx, api.b, bNrOrHash, args) if err != nil { return nil, err } @@ -1823,7 +1963,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH } else { to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) } - isPostMerge := header.Difficulty.Cmp(common.Big0) == 0 + isPostMerge := header.Difficulty.Sign() == 0 // Retrieve the precompiles since they don't need to be added to the access list precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, isPostMerge, header.Time)) @@ -1833,6 +1973,9 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH prevTracer = logger.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) } for { + if err := ctx.Err(); err != nil { + return nil, 0, nil, err + } // Retrieve the current access list to expand accessList := prevTracer.AccessList() log.Trace("Creating access list", "input", accessList) @@ -1841,18 +1984,23 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH statedb := db.Copy() // Set the accesslist to the last al args.AccessList = &accessList - msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee) - if err != nil { - return nil, 0, nil, err - } + msg := args.ToMessage(header.BaseFee, true, true) // Apply the transaction with the access list tracer tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles) - config := vm.Config{Tracer: tracer, NoBaseFee: true} + config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true} vmenv := b.GetEVM(ctx, msg, statedb, header, &config, nil) + // Lower the basefee to 0 to avoid breaking EVM + // invariants (basefee < feecap). + if msg.GasPrice.Sign() == 0 { + vmenv.Context.BaseFee = new(big.Int) + } + if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 { + vmenv.Context.BlobBaseFee = new(big.Int) + } res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)) if err != nil { - return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) + return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction(types.LegacyTxType).Hash(), err) } if tracer.Equal(prevTracer) { return accessList, res.UsedGas, res.Err, nil @@ -1877,8 +2025,8 @@ func NewTransactionAPI(b Backend, nonceLock *AddrLocker) *TransactionAPI { } // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. -func (s *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { +func (api *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { + if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { n := hexutil.Uint(len(block.Transactions())) return &n } @@ -1886,8 +2034,8 @@ func (s *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, b } // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. -func (s *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { +func (api *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { + if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { n := hexutil.Uint(len(block.Transactions())) return &n } @@ -1903,49 +2051,49 @@ func (s *TransactionAPI) GetTransactionsByBlockNumber(ctx context.Context, block } // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. -func (s *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig()) +func (api *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { + if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()) } return nil } // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. -func (s *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig()) +func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { + if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()) } return nil } // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. -func (s *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { +func (api *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { + if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { return newRPCRawTransactionFromBlockIndex(block, uint64(index)) } return nil } // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. -func (s *TransactionAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { +func (api *TransactionAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { + if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { return newRPCRawTransactionFromBlockIndex(block, uint64(index)) } return nil } // GetTransactionCount returns the number of transactions the given address has sent for the given block number -func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { +func (api *TransactionAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { // Ask transaction pool for the nonce which includes pending transactions if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { - nonce, err := s.b.GetPoolNonce(ctx, address) + nonce, err := api.b.GetPoolNonce(ctx, address) if err != nil { return nil, err } return (*hexutil.Uint64)(&nonce), nil } // Resolve block number and use its state to ask for the nonce - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -1954,32 +2102,32 @@ func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common } // GetTransactionByHash returns the transaction for the given hash -func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { +func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { // Try to return an already finalized transaction - found, tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) + found, tx, blockHash, blockNumber, index, err := api.b.GetTransaction(ctx, hash) if !found { // No finalized transaction, try to retrieve it from the pool - if tx := s.b.GetPoolTransaction(hash); tx != nil { - return NewRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil + if tx := api.b.GetPoolTransaction(hash); tx != nil { + return NewRPCPendingTransaction(tx, api.b.CurrentHeader(), api.b.ChainConfig()), nil } if err == nil { return nil, nil } return nil, NewTxIndexingError() } - header, err := s.b.HeaderByHash(ctx, blockHash) + header, err := api.b.HeaderByHash(ctx, blockHash) if err != nil { return nil, err } - return newRPCTransaction(tx, blockHash, blockNumber, header.Time, index, header.BaseFee, s.b.ChainConfig()), nil + return newRPCTransaction(tx, blockHash, blockNumber, header.Time, index, header.BaseFee, api.b.ChainConfig()), nil } // GetRawTransactionByHash returns the bytes of the transaction for the given hash. -func (s *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { // Retrieve a finalized transaction, or a pooled otherwise - found, tx, _, _, _, err := s.b.GetTransaction(ctx, hash) + found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash) if !found { - if tx = s.b.GetPoolTransaction(hash); tx != nil { + if tx = api.b.GetPoolTransaction(hash); tx != nil { return tx.MarshalBinary() } if err == nil { @@ -2106,19 +2254,19 @@ func (s *TransactionAPI) GetTransactionDataAndReceipt(ctx context.Context, hash } // GetTransactionReceipt returns the transaction receipt for the given transaction hash. -func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { - found, tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) +func (api *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { + found, tx, blockHash, blockNumber, index, err := api.b.GetTransaction(ctx, hash) if err != nil { return nil, NewTxIndexingError() // transaction is not fully indexed } if !found { return nil, nil // transaction is not existent or reachable } - header, err := s.b.HeaderByHash(ctx, blockHash) + header, err := api.b.HeaderByHash(ctx, blockHash) if err != nil { return nil, err } - receipts, err := s.b.GetReceipts(ctx, blockHash) + receipts, err := api.b.GetReceipts(ctx, blockHash) if err != nil { return nil, err } @@ -2128,7 +2276,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common. receipt := receipts[index] // Derive the sender. - signer := types.MakeSigner(s.b.ChainConfig(), header.Number, header.Time) + signer := types.MakeSigner(api.b.ChainConfig(), header.Number, header.Time) return marshalReceipt(receipt, blockHash, blockNumber, signer, tx, int(index)), nil } @@ -2204,16 +2352,16 @@ func marshalBlob(blobTxSidecar types.BlobTxSidecar, fullBlob bool) map[string]in } // sign is a helper function that signs a transaction with the private key of the given address. -func (s *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { +func (api *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: addr} - wallet, err := s.b.AccountManager().Find(account) + wallet, err := api.b.AccountManager().Find(account) if err != nil { return nil, err } // Request the wallet to sign the transaction - return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) + return wallet.SignTx(account, tx, api.b.ChainConfig().ChainID) } // SubmitTransaction is a helper function that submits tx to txPool and logs a message. @@ -2250,11 +2398,11 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c // SendTransaction creates a transaction for the given argument, sign it and submit it to the // transaction pool. -func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) { +func (api *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: args.from()} - wallet, err := s.b.AccountManager().Find(account) + wallet, err := api.b.AccountManager().Find(account) if err != nil { return common.Hash{}, err } @@ -2262,39 +2410,39 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr if args.Nonce == nil { // Hold the mutex around signing to prevent concurrent assignment of // the same nonce to multiple accounts. - s.nonceLock.LockAddr(args.from()) - defer s.nonceLock.UnlockAddr(args.from()) + api.nonceLock.LockAddr(args.from()) + defer api.nonceLock.UnlockAddr(args.from()) } if args.IsEIP4844() { return common.Hash{}, errBlobTxNotSupported } // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b, false); err != nil { + if err := args.setDefaults(ctx, api.b, false); err != nil { return common.Hash{}, err } // Assemble the transaction and sign with the wallet - tx := args.toTransaction() + tx := args.ToTransaction(types.LegacyTxType) - signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) + signed, err := wallet.SignTx(account, tx, api.b.ChainConfig().ChainID) if err != nil { return common.Hash{}, err } - return SubmitTransaction(ctx, s.b, signed) + return SubmitTransaction(ctx, api.b, signed) } // FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) // on a given unsigned transaction, and returns it to the caller for further // processing (signing + broadcast). -func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { +func (api *TransactionAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { args.blobSidecarAllowed = true // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b, false); err != nil { + if err := args.setDefaults(ctx, api.b, false); err != nil { return nil, err } // Assemble the transaction and obtain rlp - tx := args.toTransaction() + tx := args.ToTransaction(types.LegacyTxType) data, err := tx.MarshalBinary() if err != nil { return nil, err @@ -2304,12 +2452,12 @@ func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionAr // SendRawTransaction will add the signed transaction to the transaction pool. // The sender is responsible for signing the transaction and using the correct nonce. -func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { +func (api *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { tx := new(types.Transaction) if err := tx.UnmarshalBinary(input); err != nil { return common.Hash{}, err } - return SubmitTransaction(ctx, s.b, tx) + return SubmitTransaction(ctx, api.b, tx) } // SendRawTransactionConditional will add the signed transaction to the transaction pool. @@ -2339,11 +2487,11 @@ func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, inpu // The account associated with addr must be unlocked. // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign -func (s *TransactionAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { +func (api *TransactionAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: addr} - wallet, err := s.b.AccountManager().Find(account) + wallet, err := api.b.AccountManager().Find(account) if err != nil { return nil, err } @@ -2364,31 +2512,40 @@ type SignTransactionResult struct { // SignTransaction will sign the given transaction with the from account. // The node needs to have the private key of the account corresponding with // the given from address and it needs to be unlocked. -func (s *TransactionAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { +func (api *TransactionAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { + args.blobSidecarAllowed = true + if args.Gas == nil { return nil, errors.New("gas not specified") } if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") } - if args.IsEIP4844() { - return nil, errBlobTxNotSupported - } if args.Nonce == nil { return nil, errors.New("nonce not specified") } - if err := args.setDefaults(ctx, s.b, false); err != nil { + if err := args.setDefaults(ctx, api.b, false); err != nil { return nil, err } // Before actually sign the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction() - if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { + tx := args.ToTransaction(types.LegacyTxType) + if err := checkTxFee(tx.GasPrice(), tx.Gas(), api.b.RPCTxFeeCap()); err != nil { return nil, err } - signed, err := s.sign(args.from(), tx) + signed, err := api.sign(args.from(), tx) if err != nil { return nil, err } + // If the transaction-to-sign was a blob transaction, then the signed one + // no longer retains the blobs, only the blob hashes. In this step, we need + // to put back the blob(s). + if args.IsEIP4844() { + signed = signed.WithBlobTxSidecar(&types.BlobTxSidecar{ + Blobs: args.Blobs, + Commitments: args.Commitments, + Proofs: args.Proofs, + }) + } data, err := signed.MarshalBinary() if err != nil { return nil, err @@ -2398,23 +2555,23 @@ func (s *TransactionAPI) SignTransaction(ctx context.Context, args TransactionAr // PendingTransactions returns the transactions that are in the transaction pool // and have a from address that is one of the accounts this node manages. -func (s *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) { - pending, err := s.b.GetPoolTransactions() +func (api *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) { + pending, err := api.b.GetPoolTransactions() if err != nil { return nil, err } accounts := make(map[common.Address]struct{}) - for _, wallet := range s.b.AccountManager().Wallets() { + for _, wallet := range api.b.AccountManager().Wallets() { for _, account := range wallet.Accounts() { accounts[account.Address] = struct{}{} } } - curHeader := s.b.CurrentHeader() + curHeader := api.b.CurrentHeader() transactions := make([]*RPCTransaction, 0, len(pending)) for _, tx := range pending { - from, _ := types.Sender(s.signer, tx) + from, _ := types.Sender(api.signer, tx) if _, exists := accounts[from]; exists { - transactions = append(transactions, NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())) + transactions = append(transactions, NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig())) } } return transactions, nil @@ -2422,14 +2579,14 @@ func (s *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) { // Resend accepts an existing transaction and a new gas price and limit. It will remove // the given transaction from the pool and reinsert it with the new gas price and limit. -func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { +func (api *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { if sendArgs.Nonce == nil { return common.Hash{}, errors.New("missing transaction nonce in transaction spec") } - if err := sendArgs.setDefaults(ctx, s.b, false); err != nil { + if err := sendArgs.setDefaults(ctx, api.b, false); err != nil { return common.Hash{}, err } - matchTx := sendArgs.toTransaction() + matchTx := sendArgs.ToTransaction(types.LegacyTxType) // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. var price = matchTx.GasPrice() @@ -2440,18 +2597,18 @@ func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, g if gasLimit != nil { gas = uint64(*gasLimit) } - if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil { + if err := checkTxFee(price, gas, api.b.RPCTxFeeCap()); err != nil { return common.Hash{}, err } // Iterate the pending list for replacement - pending, err := s.b.GetPoolTransactions() + pending, err := api.b.GetPoolTransactions() if err != nil { return common.Hash{}, err } for _, p := range pending { - wantSigHash := s.signer.Hash(matchTx) - pFrom, err := types.Sender(s.signer, p) - if err == nil && pFrom == sendArgs.from() && s.signer.Hash(p) == wantSigHash { + wantSigHash := api.signer.Hash(matchTx) + pFrom, err := types.Sender(api.signer, p) + if err == nil && pFrom == sendArgs.from() && api.signer.Hash(p) == wantSigHash { // Match. Re-sign and send the transaction. if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { sendArgs.GasPrice = gasPrice @@ -2459,11 +2616,11 @@ func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, g if gasLimit != nil && *gasLimit != 0 { sendArgs.Gas = gasLimit } - signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction()) + signedTx, err := api.sign(sendArgs.from(), sendArgs.ToTransaction(types.LegacyTxType)) if err != nil { return common.Hash{}, err } - if err = s.b.SendTx(ctx, signedTx); err != nil { + if err = api.b.SendTx(ctx, signedTx); err != nil { return common.Hash{}, err } return signedTx.Hash(), nil @@ -2549,11 +2706,11 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block } // GetRawTransaction returns the bytes of the transaction for the given hash. -func (s *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { // Retrieve a finalized transaction, or a pooled otherwise - found, tx, _, _, _, err := s.b.GetTransaction(ctx, hash) + found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash) if !found { - if tx = s.b.GetPoolTransaction(hash); tx != nil { + if tx = api.b.GetPoolTransaction(hash); tx != nil { return tx.MarshalBinary() } if err == nil { @@ -2574,8 +2731,8 @@ func (api *DebugAPI) PrintBlock(ctx context.Context, number uint64) (string, err } // ChaindbProperty returns leveldb properties of the key-value database. -func (api *DebugAPI) ChaindbProperty(property string) (string, error) { - return api.b.ChainDb().Stat(property) +func (api *DebugAPI) ChaindbProperty() (string, error) { + return api.b.ChainDb().Stat() } // ChaindbCompact flattens the entire key-value database into a single level, @@ -2616,18 +2773,18 @@ func NewNetAPI(net *p2p.Server, networkVersion uint64) *NetAPI { } // Listening returns an indication if the node is listening for network connections. -func (s *NetAPI) Listening() bool { +func (api *NetAPI) Listening() bool { return true // always listening } // PeerCount returns the number of connected peers -func (s *NetAPI) PeerCount() hexutil.Uint { - return hexutil.Uint(s.net.PeerCount()) +func (api *NetAPI) PeerCount() hexutil.Uint { + return hexutil.Uint(api.net.PeerCount()) } // Version returns the current ethereum protocol version. -func (s *NetAPI) Version() string { - return fmt.Sprintf("%d", s.networkVersion) +func (api *NetAPI) Version() string { + return fmt.Sprintf("%d", api.networkVersion) } // NodeInfo retrieves all the information we know about the host node at the diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 8f1b8e3b0f..2bd7431f03 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -24,10 +24,13 @@ import ( "encoding/json" "errors" "fmt" + "maps" "math/big" "os" "path/filepath" "reflect" + "slices" + "strings" "testing" "time" @@ -56,6 +59,9 @@ import ( "github.com/ethereum/go-ethereum/internal/blocktest" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/triedb" + "github.com/holiman/uint256" + "github.com/stretchr/testify/require" ) var emptyBlob = kzg4844.Blob{} @@ -64,7 +70,6 @@ var emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) var emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) { - t.Parallel() var ( signer = types.LatestSigner(config) key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -101,6 +106,8 @@ func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainCo } func TestTransaction_RoundTripRpcJSON(t *testing.T) { + t.Parallel() + var ( config = params.AllEthashProtocolChanges tests = allTransactionTypes(common.Address{0xde, 0xad}, config) @@ -109,6 +116,8 @@ func TestTransaction_RoundTripRpcJSON(t *testing.T) { } func TestTransactionBlobTx(t *testing.T) { + t.Parallel() + config := *params.TestChainConfig config.ShanghaiTime = new(uint64) config.CancunTime = new(uint64) @@ -480,17 +489,18 @@ func (b testBackend) Chain() *core.BlockChain { return b.chain } -func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { - return nil, nil, nil, nil, nil +func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) { + return nil, nil, nil, nil, nil, nil, nil } -func (b testBackend) ChainDb() ethdb.Database { return b.db } -func (b testBackend) AccountManager() *accounts.Manager { return b.accman } -func (b testBackend) ExtRPCEnabled() bool { return false } -func (b testBackend) RPCGasCap() uint64 { return 10000000 } -func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second } -func (b testBackend) RPCTxFeeCap() float64 { return 0 } -func (b testBackend) UnprotectedAllowed() bool { return false } -func (b testBackend) SetHead(number uint64) {} +func (b testBackend) BlobBaseFee(ctx context.Context) *big.Int { return new(big.Int) } +func (b testBackend) ChainDb() ethdb.Database { return b.db } +func (b testBackend) AccountManager() *accounts.Manager { return b.accman } +func (b testBackend) ExtRPCEnabled() bool { return false } +func (b testBackend) RPCGasCap() uint64 { return 10000000 } +func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second } +func (b testBackend) RPCTxFeeCap() float64 { return 0 } +func (b testBackend) UnprotectedAllowed() bool { return false } +func (b testBackend) SetHead(number uint64) {} func (b testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { if number == rpc.LatestBlockNumber { return b.chain.CurrentBlock(), nil @@ -512,7 +522,8 @@ func (b testBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc } panic("unknown type rpc.BlockNumberOrHash") } -func (b testBackend) CurrentHeader() *types.Header { return b.chain.CurrentBlock() } + +func (b testBackend) CurrentHeader() *types.Header { return b.chain.CurrentHeader() } func (b testBackend) CurrentBlock() *types.Header { return b.chain.CurrentBlock() } func (b testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { if number == rpc.LatestBlockNumber { @@ -559,7 +570,7 @@ func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOr } panic("only implemented for number") } -func (b testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { panic("implement me") } +func (b testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { panic("implement me") } func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { header, err := b.HeaderByHash(ctx, hash) if header == nil || err != nil { @@ -798,7 +809,7 @@ func TestEstimateGas(t *testing.T) { From: &accounts[0].addr, To: &accounts[1].addr, Value: (*hexutil.Big)(big.NewInt(1)), - BlobHashes: []common.Hash{common.Hash{0x01, 0x22}}, + BlobHashes: []common.Hash{{0x01, 0x22}}, BlobFeeCap: (*hexutil.Big)(big.NewInt(1)), }, want: 21000, @@ -828,15 +839,24 @@ func TestEstimateGas(t *testing.T) { func TestCall(t *testing.T) { t.Parallel() + // Initialize test accounts var ( accounts = newAccounts(3) + dad = common.HexToAddress("0x0000000000000000000000000000000000000dad") genesis = &core.Genesis{ Config: params.MergedTestChainConfig, Alloc: types.GenesisAlloc{ accounts[0].addr: {Balance: big.NewInt(params.Ether)}, accounts[1].addr: {Balance: big.NewInt(params.Ether)}, accounts[2].addr: {Balance: big.NewInt(params.Ether)}, + dad: { + Balance: big.NewInt(params.Ether), + Nonce: 1, + Storage: map[common.Hash]common.Hash{ + common.Hash{}: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"), + }, + }, }, } genBlocks = 10 @@ -852,6 +872,7 @@ func TestCall(t *testing.T) { })) randomAccounts := newAccounts(3) var testSuite = []struct { + name string blockNumber rpc.BlockNumber overrides StateOverride call TransactionArgs @@ -861,6 +882,7 @@ func TestCall(t *testing.T) { }{ // transfer on genesis { + name: "transfer-on-genesis", blockNumber: rpc.BlockNumber(0), call: TransactionArgs{ From: &accounts[0].addr, @@ -872,6 +894,7 @@ func TestCall(t *testing.T) { }, // transfer on the head { + name: "transfer-on-the-head", blockNumber: rpc.BlockNumber(genBlocks), call: TransactionArgs{ From: &accounts[0].addr, @@ -883,6 +906,7 @@ func TestCall(t *testing.T) { }, // transfer on a non-existent block, error expects { + name: "transfer-non-existent-block", blockNumber: rpc.BlockNumber(genBlocks + 1), call: TransactionArgs{ From: &accounts[0].addr, @@ -893,6 +917,7 @@ func TestCall(t *testing.T) { }, // transfer on the latest block { + name: "transfer-latest-block", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &accounts[0].addr, @@ -904,6 +929,7 @@ func TestCall(t *testing.T) { }, // Call which can only succeed if state is state overridden { + name: "state-override-success", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &randomAccounts[0].addr, @@ -917,6 +943,7 @@ func TestCall(t *testing.T) { }, // Invalid call without state overriding { + name: "insufficient-funds-simple", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &randomAccounts[0].addr, @@ -942,6 +969,7 @@ func TestCall(t *testing.T) { // } // } { + name: "simple-contract-call", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &randomAccounts[0].addr, @@ -951,13 +979,14 @@ func TestCall(t *testing.T) { overrides: StateOverride{ randomAccounts[2].addr: OverrideAccount{ Code: hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"), - StateDiff: &map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))}, + StateDiff: map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))}, }, }, want: "0x000000000000000000000000000000000000000000000000000000000000007b", }, // Block overrides should work { + name: "block-override", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &accounts[1].addr, @@ -970,8 +999,36 @@ func TestCall(t *testing.T) { blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, want: "0x000000000000000000000000000000000000000000000000000000000000000b", }, + // Clear storage trie + { + name: "clear-storage-trie", + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[1].addr, + // Yul: + // object "Test" { + // code { + // let dad := 0x0000000000000000000000000000000000000dad + // if eq(balance(dad), 0) { + // revert(0, 0) + // } + // let slot := sload(0) + // mstore(0, slot) + // return(0, 32) + // } + // } + Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"), + }, + overrides: StateOverride{ + dad: OverrideAccount{ + State: map[common.Hash]common.Hash{}, + }, + }, + want: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, // Invalid blob tx { + name: "invalid-blob-tx", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &accounts[1].addr, @@ -982,11 +1039,12 @@ func TestCall(t *testing.T) { }, // BLOBHASH opcode { + name: "blobhash-opcode", blockNumber: rpc.LatestBlockNumber, call: TransactionArgs{ From: &accounts[1].addr, To: &randomAccounts[2].addr, - BlobHashes: []common.Hash{common.Hash{0x01, 0x22}}, + BlobHashes: []common.Hash{{0x01, 0x22}}, BlobFeeCap: (*hexutil.Big)(big.NewInt(1)), }, overrides: StateOverride{ @@ -996,29 +1054,1202 @@ func TestCall(t *testing.T) { }, want: "0x0122000000000000000000000000000000000000000000000000000000000000", }, + // Clear the entire storage set + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[1].addr, + // Yul: + // object "Test" { + // code { + // let dad := 0x0000000000000000000000000000000000000dad + // if eq(balance(dad), 0) { + // revert(0, 0) + // } + // let slot := sload(0) + // mstore(0, slot) + // return(0, 32) + // } + // } + Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"), + }, + overrides: StateOverride{ + dad: OverrideAccount{ + State: map[common.Hash]common.Hash{}, + }, + }, + want: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, } - for i, tc := range testSuite { + for _, tc := range testSuite { result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) if tc.expectErr != nil { if err == nil { - t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr) + t.Errorf("test %s: want error %v, have nothing", tc.name, tc.expectErr) continue } if !errors.Is(err, tc.expectErr) { // Second try if !reflect.DeepEqual(err, tc.expectErr) { - t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err) + t.Errorf("test %s: error mismatch, want %v, have %v", tc.name, tc.expectErr, err) } } continue } if err != nil { - t.Errorf("test %d: want no error, have %v", i, err) + t.Errorf("test %s: want no error, have %v", tc.name, err) continue } if !reflect.DeepEqual(result.String(), tc.want) { - t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, result.String(), tc.want) + t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, result.String(), tc.want) + } + } +} + +func TestSimulateV1(t *testing.T) { + t.Parallel() + // Initialize test accounts + var ( + accounts = newAccounts(3) + fixedAccount = newTestAccount() + genBlocks = 10 + signer = types.HomesteadSigner{} + cac = common.HexToAddress("0x0000000000000000000000000000000000000cac") + bab = common.HexToAddress("0x0000000000000000000000000000000000000bab") + coinbase = "0x000000000000000000000000000000000000ffff" + genesis = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(params.Ether)}, + accounts[1].addr: {Balance: big.NewInt(params.Ether)}, + accounts[2].addr: {Balance: big.NewInt(params.Ether)}, + // Yul: + // object "Test" { + // code { + // let dad := 0x0000000000000000000000000000000000000dad + // selfdestruct(dad) + // } + // } + cac: {Balance: big.NewInt(params.Ether), Code: common.Hex2Bytes("610dad80ff")}, + bab: { + Balance: big.NewInt(1), + // object "Test" { + // code { + // let value1 := sload(1) + // let value2 := sload(2) + // + // // Shift value1 by 128 bits to the left by multiplying it with 2^128 + // value1 := mul(value1, 0x100000000000000000000000000000000) + // + // // Concatenate value1 and value2 + // let concatenatedValue := add(value1, value2) + // + // // Store the result in memory and return it + // mstore(0, concatenatedValue) + // return(0, 0x20) + // } + // } + Code: common.FromHex("0x600154600254700100000000000000000000000000000000820291508082018060005260206000f3"), + Storage: map[common.Hash]common.Hash{ + common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(10)), + common.BigToHash(big.NewInt(2)): common.BigToHash(big.NewInt(12)), + }, + }, + }, } + sha256Address = common.BytesToAddress([]byte{0x02}) + ) + api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { + b.SetCoinbase(common.HexToAddress(coinbase)) + // Transfer from account[0] to account[1] + // value: 1000 wei + // fee: 0 wei + tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: uint64(i), + To: &accounts[1].addr, + Value: big.NewInt(1000), + Gas: params.TxGas, + GasPrice: b.BaseFee(), + Data: nil, + }), signer, accounts[0].key) + b.AddTx(tx) + })) + var ( + randomAccounts = newAccounts(4) + latest = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + includeTransfers = true + validation = true + ) + type log struct { + Address common.Address `json:"address"` + Topics []common.Hash `json:"topics"` + Data hexutil.Bytes `json:"data"` + BlockNumber hexutil.Uint64 `json:"blockNumber"` + // Skip txHash + //TxHash common.Hash `json:"transactionHash" gencodec:"required"` + TxIndex hexutil.Uint `json:"transactionIndex"` + //BlockHash common.Hash `json:"blockHash"` + Index hexutil.Uint `json:"logIndex"` + } + type callErr struct { + Message string + Code int + } + type callRes struct { + ReturnValue string `json:"returnData"` + Error callErr + Logs []log + GasUsed string + Status string + } + type blockRes struct { + Number string + //Hash string + // Ignore timestamp + GasLimit string + GasUsed string + Miner string + BaseFeePerGas string + Calls []callRes + } + var testSuite = []struct { + name string + blocks []simBlock + tag rpc.BlockNumberOrHash + includeTransfers *bool + validation *bool + expectErr error + want []blockRes + }{ + // State build-up over calls: + // First value transfer OK after state override. + // Second one should succeed because of first transfer. + { + name: "simple", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))}, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, { + From: &randomAccounts[1].addr, + To: &randomAccounts[2].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, { + To: &randomAccounts[3].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xf618", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, { + // State build-up over blocks. + name: "simple-multi-block", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))}, + }, + Calls: []TransactionArgs{ + { + From: &randomAccounts[0].addr, + To: &randomAccounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, { + From: &randomAccounts[0].addr, + To: &randomAccounts[3].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, + }, + }, { + StateOverrides: &StateOverride{ + randomAccounts[3].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))}, + }, + Calls: []TransactionArgs{ + { + From: &randomAccounts[1].addr, + To: &randomAccounts[2].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, + }, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xa410", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0x5208", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, { + // insufficient funds + name: "insufficient-funds", + tag: latest, + blocks: []simBlock{{ + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }}, + want: nil, + expectErr: &invalidTxError{Message: fmt.Sprintf("err: insufficient funds for gas * price + value: address %s have 0 want 1000 (supplied gas 4712388)", randomAccounts[0].addr.String()), Code: errCodeInsufficientFunds}, + }, { + // EVM error + name: "evm-error", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: OverrideAccount{Code: hex2Bytes("f3")}, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x47e7c4", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + Error: callErr{Message: "stack underflow (0 <=> 2)", Code: errCodeVMError}, + GasUsed: "0x47e7c4", + Logs: []log{}, + Status: "0x0", + }}, + }}, + }, { + // Block overrides should work, each call is simulated on a different block number + name: "block-overrides", + tag: latest, + blocks: []simBlock{{ + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(11)), + FeeRecipient: &cac, + }, + Calls: []TransactionArgs{ + { + From: &accounts[0].addr, + Input: &hexutil.Bytes{ + 0x43, // NUMBER + 0x60, 0x00, 0x52, // MSTORE offset 0 + 0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN + }, + }, + }, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(12)), + }, + Calls: []TransactionArgs{{ + From: &accounts[1].addr, + Input: &hexutil.Bytes{ + 0x43, // NUMBER + 0x60, 0x00, 0x52, // MSTORE offset 0 + 0x60, 0x20, 0x60, 0x00, 0xf3, + }, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xe891", + Miner: strings.ToLower(cac.String()), + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000b", + GasUsed: "0xe891", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0xe891", + Miner: strings.ToLower(cac.String()), + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000c", + GasUsed: "0xe891", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Block numbers must be in order. + { + name: "block-number-order", + tag: latest, + blocks: []simBlock{{ + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(12)), + }, + Calls: []TransactionArgs{{ + From: &accounts[1].addr, + Input: &hexutil.Bytes{ + 0x43, // NUMBER + 0x60, 0x00, 0x52, // MSTORE offset 0 + 0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN + }, + }}, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(11)), + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + Input: &hexutil.Bytes{ + 0x43, // NUMBER + 0x60, 0x00, 0x52, // MSTORE offset 0 + 0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN + }, + }}, + }}, + want: []blockRes{}, + expectErr: &invalidBlockNumberError{message: "block numbers must be in order: 11 <= 12"}, + }, + // Test on solidity storage example. Set value in one call, read in next. + { + name: "storage-contract", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: OverrideAccount{ + Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"), + }, + }, + Calls: []TransactionArgs{{ + // Set value to 5 + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + Input: hex2Bytes("6057361d0000000000000000000000000000000000000000000000000000000000000005"), + }, { + // Read value + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + Input: hex2Bytes("2e64cec1"), + }, + }, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x10683", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0xaacc", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x0000000000000000000000000000000000000000000000000000000000000005", + GasUsed: "0x5bb7", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Test logs output. + { + name: "logs", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: OverrideAccount{ + // Yul code: + // object "Test" { + // code { + // let hash:u256 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + // log1(0, 0, hash) + // return (0, 0) + // } + // } + Code: hex2Bytes("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3"), + }, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x5508", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + Logs: []log{{ + Address: randomAccounts[2].addr, + Topics: []common.Hash{common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")}, + BlockNumber: hexutil.Uint64(11), + Data: hexutil.Bytes{}, + }}, + GasUsed: "0x5508", + Status: "0x1", + }}, + }}, + }, + // Test ecrecover override + { + name: "ecrecover-override", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: OverrideAccount{ + // Yul code that returns ecrecover(0, 0, 0, 0). + // object "Test" { + // code { + // // Free memory pointer + // let free_ptr := mload(0x40) + // + // // Initialize inputs with zeros + // mstore(free_ptr, 0) // Hash + // mstore(add(free_ptr, 0x20), 0) // v + // mstore(add(free_ptr, 0x40), 0) // r + // mstore(add(free_ptr, 0x60), 0) // s + // + // // Call ecrecover precompile (at address 1) with all 0 inputs + // let success := staticcall(gas(), 1, free_ptr, 0x80, free_ptr, 0x20) + // + // // Check if the call was successful + // if eq(success, 0) { + // revert(0, 0) + // } + // + // // Return the recovered address + // return(free_ptr, 0x14) + // } + // } + Code: hex2Bytes("6040516000815260006020820152600060408201526000606082015260208160808360015afa60008103603157600080fd5b601482f3"), + }, + common.BytesToAddress([]byte{0x01}): OverrideAccount{ + // Yul code that returns the address of the caller. + // object "Test" { + // code { + // let c := caller() + // mstore(0, c) + // return(0xc, 0x14) + // } + // } + Code: hex2Bytes("33806000526014600cf3"), + }, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x52f6", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + // Caller is in this case the contract that invokes ecrecover. + ReturnValue: strings.ToLower(randomAccounts[2].addr.String()), + GasUsed: "0x52f6", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Test moving the sha256 precompile. + { + name: "precompile-move", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + sha256Address: OverrideAccount{ + // Yul code that returns the calldata. + // object "Test" { + // code { + // let size := calldatasize() // Get the size of the calldata + // + // // Allocate memory to store the calldata + // let memPtr := msize() + // + // // Copy calldata to memory + // calldatacopy(memPtr, 0, size) + // + // // Return the calldata from memory + // return(memPtr, size) + // } + // } + Code: hex2Bytes("365981600082378181f3"), + MovePrecompileTo: &randomAccounts[2].addr, + }, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[2].addr, + Input: hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"), + }, { + From: &randomAccounts[0].addr, + To: &sha256Address, + Input: hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xa58c", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5", + GasUsed: "0x52dc", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x0000000000000000000000000000000000000000000000000000000000000001", + GasUsed: "0x52b0", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Test ether transfers. + { + name: "transfer-logs", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[0].addr: OverrideAccount{ + Balance: newRPCBalance(big.NewInt(100)), + // Yul code that transfers 100 wei to address passed in calldata: + // object "Test" { + // code { + // let recipient := shr(96, calldataload(0)) + // let value := 100 + // let success := call(gas(), recipient, value, 0, 0, 0, 0) + // if eq(success, 0) { + // revert(0, 0) + // } + // } + // } + Code: hex2Bytes("60003560601c606460008060008084865af160008103601d57600080fd5b505050"), + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[0].addr, + Value: (*hexutil.Big)(big.NewInt(50)), + Input: hex2Bytes(strings.TrimPrefix(fixedAccount.addr.String(), "0x")), + }}, + }}, + includeTransfers: &includeTransfers, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x77dc", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x77dc", + Logs: []log{{ + Address: transferAddress, + Topics: []common.Hash{ + transferTopic, + addressToHash(accounts[0].addr), + addressToHash(randomAccounts[0].addr), + }, + Data: hexutil.Bytes(common.BigToHash(big.NewInt(50)).Bytes()), + BlockNumber: hexutil.Uint64(11), + }, { + Address: transferAddress, + Topics: []common.Hash{ + transferTopic, + addressToHash(randomAccounts[0].addr), + addressToHash(fixedAccount.addr), + }, + Data: hexutil.Bytes(common.BigToHash(big.NewInt(100)).Bytes()), + BlockNumber: hexutil.Uint64(11), + Index: hexutil.Uint(1), + }}, + Status: "0x1", + }}, + }}, + }, + // Tests selfdestructed contract. + { + name: "selfdestruct", + tag: latest, + blocks: []simBlock{{ + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &cac, + }, { + From: &accounts[0].addr, + // Check that cac is selfdestructed and balance transferred to dad. + // object "Test" { + // code { + // let cac := 0x0000000000000000000000000000000000000cac + // let dad := 0x0000000000000000000000000000000000000dad + // if gt(balance(cac), 0) { + // revert(0, 0) + // } + // if gt(extcodesize(cac), 0) { + // revert(0, 0) + // } + // if eq(balance(dad), 0) { + // revert(0, 0) + // } + // } + // } + Input: hex2Bytes("610cac610dad600082311115601357600080fd5b6000823b1115602157600080fd5b6000813103602e57600080fd5b5050"), + }}, + }, { + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + Input: hex2Bytes("610cac610dad600082311115601357600080fd5b6000823b1115602157600080fd5b6000813103602e57600080fd5b5050"), + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x1b83f", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0xd166", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x", + GasUsed: "0xe6d9", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0xe6d9", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0xe6d9", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Enable validation checks. + { + name: "validation-checks", + tag: latest, + blocks: []simBlock{{ + Calls: []TransactionArgs{{ + From: &accounts[2].addr, + To: &cac, + Nonce: newUint64(2), + }}, + }}, + validation: &validation, + want: nil, + expectErr: &invalidTxError{Message: fmt.Sprintf("err: nonce too high: address %s, tx: 2 state: 0 (supplied gas 4712388)", accounts[2].addr), Code: errCodeNonceTooHigh}, + }, + // Contract sends tx in validation mode. + { + name: "validation-checks-from-contract", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: OverrideAccount{ + Balance: newRPCBalance(big.NewInt(2098640803896784)), + Code: hex2Bytes("00"), + Nonce: newUint64(1), + }, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[2].addr, + To: &cac, + Nonce: newUint64(1), + MaxFeePerGas: newInt(233138868), + MaxPriorityFeePerGas: newInt(1), + }}, + }}, + validation: &validation, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xd166", + Miner: coinbase, + BaseFeePerGas: "0xde56ab3", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0xd166", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Successful validation + { + name: "validation-checks-success", + tag: latest, + blocks: []simBlock{{ + BlockOverrides: &BlockOverrides{ + BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)), + }, + StateOverrides: &StateOverride{ + randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))}, + }, + Calls: []TransactionArgs{{ + From: &randomAccounts[0].addr, + To: &randomAccounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + MaxFeePerGas: (*hexutil.Big)(big.NewInt(2)), + }}, + }}, + validation: &validation, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x5208", + Miner: coinbase, + BaseFeePerGas: "0x1", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x5208", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + // Clear storage. + { + name: "clear-storage", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: { + Code: newBytes(genesis.Alloc[bab].Code), + StateDiff: map[common.Hash]common.Hash{ + common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(2)), + common.BigToHash(big.NewInt(2)): common.BigToHash(big.NewInt(3)), + }, + }, + bab: { + State: map[common.Hash]common.Hash{ + common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(1)), + }, + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + }, { + From: &accounts[0].addr, + To: &bab, + }}, + }, { + StateOverrides: &StateOverride{ + randomAccounts[2].addr: { + State: map[common.Hash]common.Hash{ + common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(5)), + }, + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xc542", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x0000000000000000000000000000000200000000000000000000000000000003", + GasUsed: "0x62a1", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x0000000000000000000000000000000100000000000000000000000000000000", + GasUsed: "0x62a1", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0x62a1", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x0000000000000000000000000000000500000000000000000000000000000000", + GasUsed: "0x62a1", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + { + name: "blockhash-opcode", + tag: latest, + blocks: []simBlock{{ + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(12)), + }, + StateOverrides: &StateOverride{ + randomAccounts[2].addr: { + Code: hex2Bytes("600035804060008103601057600080fd5b5050"), + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // Phantom block after base. + Input: uint256ToBytes(uint256.NewInt(11)), + }, { + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // Canonical block. + Input: uint256ToBytes(uint256.NewInt(8)), + }, { + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // base block. + Input: uint256ToBytes(uint256.NewInt(10)), + }}, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(16)), + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // blocks[0] + Input: uint256ToBytes(uint256.NewInt(12)), + }, { + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // Phantom after blocks[0] + Input: uint256ToBytes(uint256.NewInt(13)), + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x0", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0xf864", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x52cc", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x", + GasUsed: "0x52cc", + Logs: []log{}, + Status: "0x1", + }, { + + ReturnValue: "0x", + GasUsed: "0x52cc", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xd", + GasLimit: "0x47e7c4", + GasUsed: "0x0", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{}, + }, { + Number: "0xe", + GasLimit: "0x47e7c4", + GasUsed: "0x0", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{}, + }, { + Number: "0xf", + GasLimit: "0x47e7c4", + GasUsed: "0x0", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{}, + }, { + Number: "0x10", + GasLimit: "0x47e7c4", + GasUsed: "0xa598", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x", + GasUsed: "0x52cc", + Logs: []log{}, + Status: "0x1", + }, { + + ReturnValue: "0x", + GasUsed: "0x52cc", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + { + name: "basefee-non-validation", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: { + // Yul code: + // object "Test" { + // code { + // // Get the gas price from the transaction + // let gasPrice := gasprice() + // + // // Get the base fee from the block + // let baseFee := basefee() + // + // // Store gasPrice and baseFee in memory + // mstore(0x0, gasPrice) + // mstore(0x20, baseFee) + // + // // Return the data + // return(0x0, 0x40) + // } + // } + Code: hex2Bytes("3a489060005260205260406000f3"), + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // 0 gas price + }, { + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // non-zero gas price + MaxPriorityFeePerGas: newInt(1), + MaxFeePerGas: newInt(2), + }, + }, + }, { + BlockOverrides: &BlockOverrides{ + BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)), + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // 0 gas price + }, { + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + // non-zero gas price + MaxPriorityFeePerGas: newInt(1), + MaxFeePerGas: newInt(2), + }, + }, + }, { + // Base fee should be 0 to zero even if it was set in previous block. + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + }}, + }}, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0xa44e", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xc", + GasLimit: "0x47e7c4", + GasUsed: "0xa44e", + Miner: coinbase, + BaseFeePerGas: "0x1", + Calls: []callRes{{ + ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }, { + ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }}, + }, { + Number: "0xd", + GasLimit: "0x47e7c4", + GasUsed: "0x5227", + Miner: coinbase, + BaseFeePerGas: "0x0", + Calls: []callRes{{ + ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, { + name: "basefee-validation-mode", + tag: latest, + blocks: []simBlock{{ + StateOverrides: &StateOverride{ + randomAccounts[2].addr: { + // Yul code: + // object "Test" { + // code { + // // Get the gas price from the transaction + // let gasPrice := gasprice() + // + // // Get the base fee from the block + // let baseFee := basefee() + // + // // Store gasPrice and baseFee in memory + // mstore(0x0, gasPrice) + // mstore(0x20, baseFee) + // + // // Return the data + // return(0x0, 0x40) + // } + // } + Code: hex2Bytes("3a489060005260205260406000f3"), + }, + }, + Calls: []TransactionArgs{{ + From: &accounts[0].addr, + To: &randomAccounts[2].addr, + MaxFeePerGas: newInt(233138868), + MaxPriorityFeePerGas: newInt(1), + }}, + }}, + validation: &validation, + want: []blockRes{{ + Number: "0xb", + GasLimit: "0x47e7c4", + GasUsed: "0x5227", + Miner: coinbase, + BaseFeePerGas: "0xde56ab3", + Calls: []callRes{{ + ReturnValue: "0x000000000000000000000000000000000000000000000000000000000de56ab4000000000000000000000000000000000000000000000000000000000de56ab3", + GasUsed: "0x5227", + Logs: []log{}, + Status: "0x1", + }}, + }}, + }, + } + + for _, tc := range testSuite { + t.Run(tc.name, func(t *testing.T) { + opts := simOpts{BlockStateCalls: tc.blocks} + if tc.includeTransfers != nil && *tc.includeTransfers { + opts.TraceTransfers = true + } + if tc.validation != nil && *tc.validation { + opts.Validation = true + } + result, err := api.SimulateV1(context.Background(), opts, &tc.tag) + if tc.expectErr != nil { + if err == nil { + t.Fatalf("test %s: want error %v, have nothing", tc.name, tc.expectErr) + } + if !errors.Is(err, tc.expectErr) { + // Second try + if !reflect.DeepEqual(err, tc.expectErr) { + t.Errorf("test %s: error mismatch, want %v, have %v", tc.name, tc.expectErr, err) + } + } + return + } + if err != nil { + t.Fatalf("test %s: want no error, have %v", tc.name, err) + } + // Turn result into res-struct + var have []blockRes + resBytes, _ := json.Marshal(result) + if err := json.Unmarshal(resBytes, &have); err != nil { + t.Fatalf("failed to unmarshal result: %v", err) + } + if !reflect.DeepEqual(have, tc.want) { + t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, have, tc.want) + } + }) } } @@ -1086,11 +2317,8 @@ func TestSignBlobTransaction(t *testing.T) { } _, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address)) - if err == nil { - t.Fatalf("should fail on blob transaction") - } - if !errors.Is(err, errBlobTxNotSupported) { - t.Errorf("error mismatch. Have: %v, want: %v", err, errBlobTxNotSupported) + if err != nil { + t.Fatalf("should not fail on blob transaction") } } @@ -1113,7 +2341,7 @@ func TestSendBlobTransaction(t *testing.T) { From: &b.acc.Address, To: &to, Value: (*hexutil.Big)(big.NewInt(1)), - BlobHashes: []common.Hash{common.Hash{0x01, 0x22}}, + BlobHashes: []common.Hash{{0x01, 0x22}}, }) if err != nil { t.Fatalf("failed to fill tx defaults: %v\n", err) @@ -1137,6 +2365,11 @@ func TestFillBlobTransaction(t *testing.T) { Config: params.MergedTestChainConfig, Alloc: types.GenesisAlloc{}, } + emptyBlob = new(kzg4844.Blob) + emptyBlobs = []kzg4844.Blob{*emptyBlob} + emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) + emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) + emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) ) b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { b.SetPoS() @@ -1216,14 +2449,14 @@ func TestFillBlobTransaction(t *testing.T) { From: &b.acc.Address, To: &to, Value: (*hexutil.Big)(big.NewInt(1)), - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, Sidecar: &types.BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, @@ -1236,14 +2469,14 @@ func TestFillBlobTransaction(t *testing.T) { To: &to, Value: (*hexutil.Big)(big.NewInt(1)), BlobHashes: []common.Hash{emptyBlobHash}, - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, Sidecar: &types.BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, @@ -1256,7 +2489,7 @@ func TestFillBlobTransaction(t *testing.T) { To: &to, Value: (*hexutil.Big)(big.NewInt(1)), BlobHashes: []common.Hash{{0x01, 0x22}}, - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, @@ -1268,12 +2501,12 @@ func TestFillBlobTransaction(t *testing.T) { From: &b.acc.Address, To: &to, Value: (*hexutil.Big)(big.NewInt(1)), - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, Sidecar: &types.BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, + Blobs: emptyBlobs, Commitments: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}, }, @@ -1282,11 +2515,13 @@ func TestFillBlobTransaction(t *testing.T) { } for _, tc := range suite { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + res, err := api.FillTransaction(context.Background(), tc.args) if len(tc.err) > 0 { if err == nil { t.Fatalf("missing error. want: %s", tc.err) - } else if err != nil && err.Error() != tc.err { + } else if err.Error() != tc.err { t.Fatalf("error mismatch. want: %s, have: %s", tc.err, err.Error()) } return @@ -1314,10 +2549,14 @@ func TestFillBlobTransaction(t *testing.T) { func argsFromTransaction(tx *types.Transaction, from common.Address) TransactionArgs { var ( - gas = tx.Gas() - nonce = tx.Nonce() - input = tx.Data() + gas = tx.Gas() + nonce = tx.Nonce() + input = tx.Data() + accessList *types.AccessList ) + if acl := tx.AccessList(); acl != nil { + accessList = &acl + } return TransactionArgs{ From: &from, To: tx.To(), @@ -1328,10 +2567,9 @@ func argsFromTransaction(tx *types.Transaction, from common.Address) Transaction Nonce: (*hexutil.Uint64)(&nonce), Input: (*hexutil.Bytes)(&input), ChainID: (*hexutil.Big)(tx.ChainId()), - // TODO: impl accessList conversion - //AccessList: tx.AccessList(), - BlobFeeCap: (*hexutil.Big)(tx.BlobGasFeeCap()), - BlobHashes: tx.BlobHashes(), + AccessList: accessList, + BlobFeeCap: (*hexutil.Big)(tx.BlobGasFeeCap()), + BlobHashes: tx.BlobHashes(), } } @@ -1350,16 +2588,40 @@ func newAccounts(n int) (accounts []account) { return accounts } -func newRPCBalance(balance *big.Int) **hexutil.Big { +func newTestAccount() account { + // testKey is a private key to use for funding a tester account. + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + // testAddr is the Ethereum address of the tester account. + addr := crypto.PubkeyToAddress(key.PublicKey) + return account{key: key, addr: addr} +} + +func newRPCBalance(balance *big.Int) *hexutil.Big { rpcBalance := (*hexutil.Big)(balance) - return &rpcBalance + return rpcBalance } func hex2Bytes(str string) *hexutil.Bytes { - rpcBytes := hexutil.Bytes(common.Hex2Bytes(str)) + rpcBytes := hexutil.Bytes(common.FromHex(str)) return &rpcBytes } +func newUint64(v uint64) *hexutil.Uint64 { + rpcUint64 := hexutil.Uint64(v) + return &rpcUint64 +} + +func newBytes(b []byte) *hexutil.Bytes { + rpcBytes := hexutil.Bytes(b) + return &rpcBytes +} + +func uint256ToBytes(v *uint256.Int) *hexutil.Bytes { + b := v.Bytes32() + r := hexutil.Bytes(b[:]) + return &r +} + func TestRPCMarshalBlock(t *testing.T) { t.Parallel() var ( @@ -1390,7 +2652,7 @@ func TestRPCMarshalBlock(t *testing.T) { } txs = append(txs, tx) } - block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, txs, nil, nil, blocktest.NewHasher()) + block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, &types.Body{Transactions: txs}, nil, blocktest.NewHasher()) var testSuite = []struct { inclTx bool @@ -1601,7 +2863,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) { Address: common.Address{0x12, 0x34}, Amount: 10, } - pending = types.NewBlockWithWithdrawals(&types.Header{Number: big.NewInt(11), Time: 42}, []*types.Transaction{tx}, nil, nil, []*types.Withdrawal{withdrawal}, blocktest.NewHasher()) + pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher()) ) backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1] @@ -2198,6 +3460,7 @@ func TestRPCGetBlobSidecars(t *testing.T) { test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(7)), fullBlob: false, file: "block-with-blobSidecars-show-little", + file: "block-with-blobSidecars-show-little", }, } @@ -2215,6 +3478,97 @@ func TestRPCGetBlobSidecars(t *testing.T) { } } +type precompileContract struct{} + +func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 } + +func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil } + +func TestStateOverrideMovePrecompile(t *testing.T) { + db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) + statedb, err := state.New(common.Hash{}, db) + if err != nil { + t.Fatalf("failed to create statedb: %v", err) + } + precompiles := map[common.Address]vm.PrecompiledContract{ + common.BytesToAddress([]byte{0x1}): &precompileContract{}, + common.BytesToAddress([]byte{0x2}): &precompileContract{}, + } + bytes2Addr := func(b []byte) *common.Address { + a := common.BytesToAddress(b) + return &a + } + var testSuite = []struct { + overrides StateOverride + expectedPrecompiles map[common.Address]struct{} + fail bool + }{ + { + overrides: StateOverride{ + common.BytesToAddress([]byte{0x1}): { + Code: hex2Bytes("0xff"), + MovePrecompileTo: bytes2Addr([]byte{0x2}), + }, + common.BytesToAddress([]byte{0x2}): { + Code: hex2Bytes("0x00"), + }, + }, + // 0x2 has already been touched by the moveTo. + fail: true, + }, { + overrides: StateOverride{ + common.BytesToAddress([]byte{0x1}): { + Code: hex2Bytes("0xff"), + MovePrecompileTo: bytes2Addr([]byte{0xff}), + }, + common.BytesToAddress([]byte{0x3}): { + Code: hex2Bytes("0x00"), + MovePrecompileTo: bytes2Addr([]byte{0xfe}), + }, + }, + // 0x3 is not a precompile. + fail: true, + }, { + overrides: StateOverride{ + common.BytesToAddress([]byte{0x1}): { + Code: hex2Bytes("0xff"), + MovePrecompileTo: bytes2Addr([]byte{0xff}), + }, + common.BytesToAddress([]byte{0x2}): { + Code: hex2Bytes("0x00"), + MovePrecompileTo: bytes2Addr([]byte{0xfe}), + }, + }, + expectedPrecompiles: map[common.Address]struct{}{common.BytesToAddress([]byte{0xfe}): {}, common.BytesToAddress([]byte{0xff}): {}}, + }, + } + + for i, tt := range testSuite { + cpy := maps.Clone(precompiles) + // Apply overrides + err := tt.overrides.Apply(statedb, cpy) + if tt.fail { + if err == nil { + t.Errorf("test %d: want error, have nothing", i) + } + continue + } + if err != nil { + t.Errorf("test %d: want no error, have %v", i, err) + continue + } + // Precompile keys + if len(cpy) != len(tt.expectedPrecompiles) { + t.Errorf("test %d: precompile mismatch, want %d, have %d", i, len(tt.expectedPrecompiles), len(cpy)) + } + for k := range tt.expectedPrecompiles { + if _, ok := cpy[k]; !ok { + t.Errorf("test %d: precompile not found: %s", i, k.String()) + } + } + } +} + func TestGetBlobSidecarByTxHash(t *testing.T) { t.Parallel() var ( @@ -2294,3 +3648,7 @@ func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc s } require.JSONEqf(t, string(want), string(data), "test %d: json not match, want: %s, have: %s", testid, string(want), string(data)) } + +func addressToHash(a common.Address) common.Hash { + return common.BytesToHash(a.Bytes()) +} diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 0cb3fb25cd..6cc486a112 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -44,9 +44,10 @@ type Backend interface { SyncProgress() ethereum.SyncProgress SuggestGasTipCap(ctx context.Context) (*big.Int, error) - FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) Chain() *core.BlockChain + FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) + BlobBaseFee(ctx context.Context) *big.Int ChainDb() ethdb.Database AccountManager() *accounts.Manager ExtRPCEnabled() bool @@ -67,9 +68,8 @@ type Backend interface { BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) - PendingBlockAndReceipts() (*types.Block, types.Receipts) + Pending() (*types.Block, types.Receipts, *state.StateDB) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) - GetTd(ctx context.Context, hash common.Hash) *big.Int GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription @@ -99,7 +99,6 @@ type Backend interface { GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription - SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription BloomStatus() (uint64, uint64) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription diff --git a/internal/ethapi/errors.go b/internal/ethapi/errors.go index b5e668a805..ae38061234 100644 --- a/internal/ethapi/errors.go +++ b/internal/ethapi/errors.go @@ -17,10 +17,12 @@ package ethapi import ( + "errors" "fmt" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" ) @@ -76,3 +78,93 @@ func (e *TxIndexingError) ErrorCode() int { // ErrorData returns the hex encoded revert reason. func (e *TxIndexingError) ErrorData() interface{} { return "transaction indexing is in progress" } + +type callError struct { + Message string `json:"message"` + Code int `json:"code"` + Data string `json:"data,omitempty"` +} + +type invalidTxError struct { + Message string `json:"message"` + Code int `json:"code"` +} + +func (e *invalidTxError) Error() string { return e.Message } +func (e *invalidTxError) ErrorCode() int { return e.Code } + +const ( + errCodeNonceTooHigh = -38011 + errCodeNonceTooLow = -38010 + errCodeIntrinsicGas = -38013 + errCodeInsufficientFunds = -38014 + errCodeBlockGasLimitReached = -38015 + errCodeBlockNumberInvalid = -38020 + errCodeBlockTimestampInvalid = -38021 + errCodeSenderIsNotEOA = -38024 + errCodeMaxInitCodeSizeExceeded = -38025 + errCodeClientLimitExceeded = -38026 + errCodeInternalError = -32603 + errCodeInvalidParams = -32602 + errCodeReverted = -32000 + errCodeVMError = -32015 +) + +func txValidationError(err error) *invalidTxError { + if err == nil { + return nil + } + switch { + case errors.Is(err, core.ErrNonceTooHigh): + return &invalidTxError{Message: err.Error(), Code: errCodeNonceTooHigh} + case errors.Is(err, core.ErrNonceTooLow): + return &invalidTxError{Message: err.Error(), Code: errCodeNonceTooLow} + case errors.Is(err, core.ErrSenderNoEOA): + return &invalidTxError{Message: err.Error(), Code: errCodeSenderIsNotEOA} + case errors.Is(err, core.ErrFeeCapVeryHigh): + return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams} + case errors.Is(err, core.ErrTipVeryHigh): + return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams} + case errors.Is(err, core.ErrTipAboveFeeCap): + return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams} + case errors.Is(err, core.ErrFeeCapTooLow): + return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams} + case errors.Is(err, core.ErrInsufficientFunds): + return &invalidTxError{Message: err.Error(), Code: errCodeInsufficientFunds} + case errors.Is(err, core.ErrIntrinsicGas): + return &invalidTxError{Message: err.Error(), Code: errCodeIntrinsicGas} + case errors.Is(err, core.ErrInsufficientFundsForTransfer): + return &invalidTxError{Message: err.Error(), Code: errCodeInsufficientFunds} + case errors.Is(err, core.ErrMaxInitCodeSizeExceeded): + return &invalidTxError{Message: err.Error(), Code: errCodeMaxInitCodeSizeExceeded} + } + return &invalidTxError{ + Message: err.Error(), + Code: errCodeInternalError, + } +} + +type invalidParamsError struct{ message string } + +func (e *invalidParamsError) Error() string { return e.message } +func (e *invalidParamsError) ErrorCode() int { return errCodeInvalidParams } + +type clientLimitExceededError struct{ message string } + +func (e *clientLimitExceededError) Error() string { return e.message } +func (e *clientLimitExceededError) ErrorCode() int { return errCodeClientLimitExceeded } + +type invalidBlockNumberError struct{ message string } + +func (e *invalidBlockNumberError) Error() string { return e.message } +func (e *invalidBlockNumberError) ErrorCode() int { return errCodeBlockNumberInvalid } + +type invalidBlockTimestampError struct{ message string } + +func (e *invalidBlockTimestampError) Error() string { return e.message } +func (e *invalidBlockTimestampError) ErrorCode() int { return errCodeBlockTimestampInvalid } + +type blockGasLimitReachedError struct{ message string } + +func (e *blockGasLimitReachedError) Error() string { return e.message } +func (e *blockGasLimitReachedError) ErrorCode() int { return errCodeBlockGasLimitReached } diff --git a/internal/ethapi/logtracer.go b/internal/ethapi/logtracer.go new file mode 100644 index 0000000000..456aa93736 --- /dev/null +++ b/internal/ethapi/logtracer.go @@ -0,0 +1,151 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethapi + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" +) + +var ( + // keccak256("Transfer(address,address,uint256)") + transferTopic = common.HexToHash("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") + // ERC-7528 + transferAddress = common.HexToAddress("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE") +) + +// tracer is a simple tracer that records all logs and +// ether transfers. Transfers are recorded as if they +// were logs. Transfer events include: +// - tx value +// - call value +// - self destructs +// +// The log format for a transfer is: +// - address: 0x0000000000000000000000000000000000000000 +// - data: Value +// - topics: +// - Transfer(address,address,uint256) +// - Sender address +// - Recipient address +type tracer struct { + // logs keeps logs for all open call frames. + // This lets us clear logs for failed calls. + logs [][]*types.Log + count int + traceTransfers bool + blockNumber uint64 + blockHash common.Hash + txHash common.Hash + txIdx uint +} + +func newTracer(traceTransfers bool, blockNumber uint64, blockHash, txHash common.Hash, txIndex uint) *tracer { + return &tracer{ + traceTransfers: traceTransfers, + blockNumber: blockNumber, + blockHash: blockHash, + txHash: txHash, + txIdx: txIndex, + } +} + +func (t *tracer) Hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnEnter: t.onEnter, + OnExit: t.onExit, + OnLog: t.onLog, + } +} + +func (t *tracer) onEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + t.logs = append(t.logs, make([]*types.Log, 0)) + if vm.OpCode(typ) != vm.DELEGATECALL && value != nil && value.Cmp(common.Big0) > 0 { + t.captureTransfer(from, to, value) + } +} + +func (t *tracer) onExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { + if depth == 0 { + t.onEnd(reverted) + return + } + size := len(t.logs) + if size <= 1 { + return + } + // pop call + call := t.logs[size-1] + t.logs = t.logs[:size-1] + size-- + + // Clear logs if call failed. + if !reverted { + t.logs[size-1] = append(t.logs[size-1], call...) + } +} + +func (t *tracer) onEnd(reverted bool) { + if reverted { + t.logs[0] = nil + } +} + +func (t *tracer) onLog(log *types.Log) { + t.captureLog(log.Address, log.Topics, log.Data) +} + +func (t *tracer) captureLog(address common.Address, topics []common.Hash, data []byte) { + t.logs[len(t.logs)-1] = append(t.logs[len(t.logs)-1], &types.Log{ + Address: address, + Topics: topics, + Data: data, + BlockNumber: t.blockNumber, + BlockHash: t.blockHash, + TxHash: t.txHash, + TxIndex: t.txIdx, + Index: uint(t.count), + }) + t.count++ +} + +func (t *tracer) captureTransfer(from, to common.Address, value *big.Int) { + if !t.traceTransfers { + return + } + topics := []common.Hash{ + transferTopic, + common.BytesToHash(from.Bytes()), + common.BytesToHash(to.Bytes()), + } + t.captureLog(transferAddress, topics, common.BigToHash(value).Bytes()) +} + +// reset prepares the tracer for the next transaction. +func (t *tracer) reset(txHash common.Hash, txIdx uint) { + t.logs = nil + t.txHash = txHash + t.txIdx = txIdx +} + +func (t *tracer) Logs() []*types.Log { + return t.logs[0] +} diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go new file mode 100644 index 0000000000..4371a42464 --- /dev/null +++ b/internal/ethapi/simulate.go @@ -0,0 +1,415 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethapi + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "maps" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc/eip1559" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" +) + +const ( + // maxSimulateBlocks is the maximum number of blocks that can be simulated + // in a single request. + maxSimulateBlocks = 256 + + // timestampIncrement is the default increment between block timestamps. + timestampIncrement = 1 +) + +// simBlock is a batch of calls to be simulated sequentially. +type simBlock struct { + BlockOverrides *BlockOverrides + StateOverrides *StateOverride + Calls []TransactionArgs +} + +// simCallResult is the result of a simulated call. +type simCallResult struct { + ReturnValue hexutil.Bytes `json:"returnData"` + Logs []*types.Log `json:"logs"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + Status hexutil.Uint64 `json:"status"` + Error *callError `json:"error,omitempty"` +} + +func (r *simCallResult) MarshalJSON() ([]byte, error) { + type callResultAlias simCallResult + // Marshal logs to be an empty array instead of nil when empty + if r.Logs == nil { + r.Logs = []*types.Log{} + } + return json.Marshal((*callResultAlias)(r)) +} + +// simOpts are the inputs to eth_simulateV1. +type simOpts struct { + BlockStateCalls []simBlock + TraceTransfers bool + Validation bool + ReturnFullTransactions bool +} + +// simulator is a stateful object that simulates a series of blocks. +// it is not safe for concurrent use. +type simulator struct { + b Backend + state *state.StateDB + base *types.Header + chainConfig *params.ChainConfig + gp *core.GasPool + traceTransfers bool + validate bool + fullTx bool +} + +// execute runs the simulation of a series of blocks. +func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[string]interface{}, error) { + if err := ctx.Err(); err != nil { + return nil, err + } + var ( + cancel context.CancelFunc + timeout = sim.b.RPCEVMTimeout() + ) + if timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, timeout) + } else { + ctx, cancel = context.WithCancel(ctx) + } + // Make sure the context is cancelled when the call has completed + // this makes sure resources are cleaned up. + defer cancel() + + var err error + blocks, err = sim.sanitizeChain(blocks) + if err != nil { + return nil, err + } + // Prepare block headers with preliminary fields for the response. + headers, err := sim.makeHeaders(blocks) + if err != nil { + return nil, err + } + var ( + results = make([]map[string]interface{}, len(blocks)) + parent = sim.base + ) + for bi, block := range blocks { + result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout) + if err != nil { + return nil, err + } + enc := RPCMarshalBlock(result, true, sim.fullTx, sim.chainConfig) + enc["calls"] = callResults + results[bi] = enc + + parent = headers[bi] + } + return results, nil +} + +func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, parent *types.Header, headers []*types.Header, timeout time.Duration) (*types.Block, []simCallResult, error) { + // Set header fields that depend only on parent block. + // Parent hash is needed for evm.GetHashFn to work. + header.ParentHash = parent.Hash() + if sim.chainConfig.IsLondon(header.Number) { + // In non-validation mode base fee is set to 0 if it is not overridden. + // This is because it creates an edge case in EVM where gasPrice < baseFee. + // Base fee could have been overridden. + if header.BaseFee == nil { + if sim.validate { + header.BaseFee = eip1559.CalcBaseFee(sim.chainConfig, parent) + } else { + header.BaseFee = big.NewInt(0) + } + } + } + if sim.chainConfig.IsCancun(header.Number, header.Time) { + var excess uint64 + if sim.chainConfig.IsCancun(parent.Number, parent.Time) { + excess = eip4844.CalcExcessBlobGas(*parent.ExcessBlobGas, *parent.BlobGasUsed) + } else { + excess = eip4844.CalcExcessBlobGas(0, 0) + } + header.ExcessBlobGas = &excess + } + blockContext := core.NewEVMBlockContext(header, sim.newSimulatedChainContext(ctx, headers), nil) + if block.BlockOverrides.BlobBaseFee != nil { + blockContext.BlobBaseFee = block.BlockOverrides.BlobBaseFee.ToInt() + } + precompiles := sim.activePrecompiles(sim.base) + // State overrides are applied prior to execution of a block + if err := block.StateOverrides.Apply(sim.state, precompiles); err != nil { + return nil, nil, err + } + var ( + gasUsed, blobGasUsed uint64 + txes = make([]*types.Transaction, len(block.Calls)) + callResults = make([]simCallResult, len(block.Calls)) + receipts = make([]*types.Receipt, len(block.Calls)) + // Block hash will be repaired after execution. + tracer = newTracer(sim.traceTransfers, blockContext.BlockNumber.Uint64(), common.Hash{}, common.Hash{}, 0) + vmConfig = &vm.Config{ + NoBaseFee: !sim.validate, + Tracer: tracer.Hooks(), + } + evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, sim.state, sim.chainConfig, *vmConfig) + ) + sim.state.SetLogger(tracer.Hooks()) + // It is possible to override precompiles with EVM bytecode, or + // move them to another address. + if precompiles != nil { + evm.SetPrecompiles(precompiles) + } + for i, call := range block.Calls { + if err := ctx.Err(); err != nil { + return nil, nil, err + } + if err := sim.sanitizeCall(&call, sim.state, header, blockContext, &gasUsed); err != nil { + return nil, nil, err + } + tx := call.ToTransaction(types.DynamicFeeTxType) + txes[i] = tx + tracer.reset(tx.Hash(), uint(i)) + // EoA check is always skipped, even in validation mode. + msg := call.ToMessage(header.BaseFee, !sim.validate, true) + evm.Reset(core.NewEVMTxContext(msg), sim.state) + result, err := applyMessageWithEVM(ctx, evm, msg, sim.state, timeout, sim.gp) + if err != nil { + txErr := txValidationError(err) + return nil, nil, txErr + } + // Update the state with pending changes. + var root []byte + if sim.chainConfig.IsByzantium(blockContext.BlockNumber) { + sim.state.Finalise(true) + } else { + root = sim.state.IntermediateRoot(sim.chainConfig.IsEIP158(blockContext.BlockNumber)).Bytes() + } + gasUsed += result.UsedGas + receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root) + blobGasUsed += receipts[i].BlobGasUsed + logs := tracer.Logs() + callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)} + if result.Failed() { + callRes.Status = hexutil.Uint64(types.ReceiptStatusFailed) + if errors.Is(result.Err, vm.ErrExecutionReverted) { + // If the result contains a revert reason, try to unpack it. + revertErr := newRevertError(result.Revert()) + callRes.Error = &callError{Message: revertErr.Error(), Code: errCodeReverted, Data: revertErr.ErrorData().(string)} + } else { + callRes.Error = &callError{Message: result.Err.Error(), Code: errCodeVMError} + } + } else { + callRes.Status = hexutil.Uint64(types.ReceiptStatusSuccessful) + } + callResults[i] = callRes + } + header.Root = sim.state.IntermediateRoot(true) + header.GasUsed = gasUsed + if sim.chainConfig.IsCancun(header.Number, header.Time) { + header.BlobGasUsed = &blobGasUsed + } + var withdrawals types.Withdrawals + if sim.chainConfig.IsShanghai(header.Number, header.Time) { + withdrawals = make([]*types.Withdrawal, 0) + } + b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil)) + repairLogs(callResults, b.Hash()) + return b, callResults, nil +} + +// repairLogs updates the block hash in the logs present in the result of +// a simulated block. This is needed as during execution when logs are collected +// the block hash is not known. +func repairLogs(calls []simCallResult, hash common.Hash) { + for i := range calls { + for j := range calls[i].Logs { + calls[i].Logs[j].BlockHash = hash + } + } +} + +func (sim *simulator) sanitizeCall(call *TransactionArgs, state *state.StateDB, header *types.Header, blockContext vm.BlockContext, gasUsed *uint64) error { + if call.Nonce == nil { + nonce := state.GetNonce(call.from()) + call.Nonce = (*hexutil.Uint64)(&nonce) + } + // Let the call run wild unless explicitly specified. + if call.Gas == nil { + remaining := blockContext.GasLimit - *gasUsed + call.Gas = (*hexutil.Uint64)(&remaining) + } + if *gasUsed+uint64(*call.Gas) > blockContext.GasLimit { + return &blockGasLimitReachedError{fmt.Sprintf("block gas limit reached: %d >= %d", gasUsed, blockContext.GasLimit)} + } + if err := call.CallDefaults(sim.gp.Gas(), header.BaseFee, sim.chainConfig.ChainID); err != nil { + return err + } + return nil +} + +func (sim *simulator) activePrecompiles(base *types.Header) vm.PrecompiledContracts { + var ( + isMerge = (base.Difficulty.Sign() == 0) + rules = sim.chainConfig.Rules(base.Number, isMerge, base.Time) + ) + return maps.Clone(vm.ActivePrecompiledContracts(rules)) +} + +// sanitizeChain checks the chain integrity. Specifically it checks that +// block numbers and timestamp are strictly increasing, setting default values +// when necessary. Gaps in block numbers are filled with empty blocks. +// Note: It modifies the block's override object. +func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) { + var ( + res = make([]simBlock, 0, len(blocks)) + base = sim.base + prevNumber = base.Number + prevTimestamp = base.Time + ) + for _, block := range blocks { + if block.BlockOverrides == nil { + block.BlockOverrides = new(BlockOverrides) + } + if block.BlockOverrides.Number == nil { + n := new(big.Int).Add(prevNumber, big.NewInt(1)) + block.BlockOverrides.Number = (*hexutil.Big)(n) + } + diff := new(big.Int).Sub(block.BlockOverrides.Number.ToInt(), prevNumber) + if diff.Cmp(common.Big0) <= 0 { + return nil, &invalidBlockNumberError{fmt.Sprintf("block numbers must be in order: %d <= %d", block.BlockOverrides.Number.ToInt().Uint64(), prevNumber)} + } + if total := new(big.Int).Sub(block.BlockOverrides.Number.ToInt(), base.Number); total.Cmp(big.NewInt(maxSimulateBlocks)) > 0 { + return nil, &clientLimitExceededError{message: "too many blocks"} + } + if diff.Cmp(big.NewInt(1)) > 0 { + // Fill the gap with empty blocks. + gap := new(big.Int).Sub(diff, big.NewInt(1)) + // Assign block number to the empty blocks. + for i := uint64(0); i < gap.Uint64(); i++ { + n := new(big.Int).Add(prevNumber, big.NewInt(int64(i+1))) + t := prevTimestamp + timestampIncrement + b := simBlock{BlockOverrides: &BlockOverrides{Number: (*hexutil.Big)(n), Time: (*hexutil.Uint64)(&t)}} + prevTimestamp = t + res = append(res, b) + } + } + // Only append block after filling a potential gap. + prevNumber = block.BlockOverrides.Number.ToInt() + var t uint64 + if block.BlockOverrides.Time == nil { + t = prevTimestamp + timestampIncrement + block.BlockOverrides.Time = (*hexutil.Uint64)(&t) + } else { + t = uint64(*block.BlockOverrides.Time) + if t <= prevTimestamp { + return nil, &invalidBlockTimestampError{fmt.Sprintf("block timestamps must be in order: %d <= %d", t, prevTimestamp)} + } + } + prevTimestamp = t + res = append(res, block) + } + return res, nil +} + +// makeHeaders makes header object with preliminary fields based on a simulated block. +// Some fields have to be filled post-execution. +// It assumes blocks are in order and numbers have been validated. +func (sim *simulator) makeHeaders(blocks []simBlock) ([]*types.Header, error) { + var ( + res = make([]*types.Header, len(blocks)) + base = sim.base + header = base + ) + for bi, block := range blocks { + if block.BlockOverrides == nil || block.BlockOverrides.Number == nil { + return nil, errors.New("empty block number") + } + overrides := block.BlockOverrides + + var withdrawalsHash *common.Hash + if sim.chainConfig.IsShanghai(overrides.Number.ToInt(), (uint64)(*overrides.Time)) { + withdrawalsHash = &types.EmptyWithdrawalsHash + } + var parentBeaconRoot *common.Hash + if sim.chainConfig.IsCancun(overrides.Number.ToInt(), (uint64)(*overrides.Time)) { + parentBeaconRoot = &common.Hash{} + } + header = overrides.MakeHeader(&types.Header{ + UncleHash: types.EmptyUncleHash, + ReceiptHash: types.EmptyReceiptsHash, + TxHash: types.EmptyTxsHash, + Coinbase: header.Coinbase, + Difficulty: header.Difficulty, + GasLimit: header.GasLimit, + WithdrawalsHash: withdrawalsHash, + ParentBeaconRoot: parentBeaconRoot, + }) + res[bi] = header + } + return res, nil +} + +func (sim *simulator) newSimulatedChainContext(ctx context.Context, headers []*types.Header) *ChainContext { + return NewChainContext(ctx, &simBackend{base: sim.base, b: sim.b, headers: headers}) +} + +type simBackend struct { + b ChainContextBackend + base *types.Header + headers []*types.Header +} + +func (b *simBackend) Engine() consensus.Engine { + return b.b.Engine() +} + +func (b *simBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + if uint64(number) == b.base.Number.Uint64() { + return b.base, nil + } + if uint64(number) < b.base.Number.Uint64() { + // Resolve canonical header. + return b.b.HeaderByNumber(ctx, number) + } + // Simulated block. + for _, header := range b.headers { + if header.Number.Uint64() == uint64(number) { + return header, nil + } + } + return nil, errors.New("header not found") +} diff --git a/internal/ethapi/simulate_test.go b/internal/ethapi/simulate_test.go new file mode 100644 index 0000000000..37883924ac --- /dev/null +++ b/internal/ethapi/simulate_test.go @@ -0,0 +1,120 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethapi + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +func TestSimulateSanitizeBlockOrder(t *testing.T) { + type result struct { + number uint64 + timestamp uint64 + } + for i, tc := range []struct { + baseNumber int + baseTimestamp uint64 + blocks []simBlock + expected []result + err string + }{ + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{}, {}, {}}, + expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}}, + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(70)}}, {}}, + expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 70}, {number: 14, timestamp: 71}}, + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &BlockOverrides{Number: newInt(14)}}, {}}, + expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}, {number: 14, timestamp: 54}, {number: 15, timestamp: 55}}, + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13)}}, {BlockOverrides: &BlockOverrides{Number: newInt(12)}}}, + err: "block numbers must be in order: 12 <= 13", + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(52)}}}, + err: "block timestamps must be in order: 52 <= 52", + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &BlockOverrides{Number: newInt(12), Time: newUint64(55)}}}, + err: "block timestamps must be in order: 55 <= 60", + }, + { + baseNumber: 10, + baseTimestamp: 50, + blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(61)}}}, + err: "block timestamps must be in order: 61 <= 61", + }, + } { + sim := &simulator{base: &types.Header{Number: big.NewInt(int64(tc.baseNumber)), Time: tc.baseTimestamp}} + res, err := sim.sanitizeChain(tc.blocks) + if err != nil { + if err.Error() == tc.err { + continue + } else { + t.Fatalf("testcase %d: error mismatch. Want '%s', have '%s'", i, tc.err, err.Error()) + } + } + if err == nil && tc.err != "" { + t.Fatalf("testcase %d: expected err", i) + } + if len(res) != len(tc.expected) { + t.Errorf("testcase %d: mismatch number of blocks. Want %d, have %d", i, len(tc.expected), len(res)) + } + for bi, b := range res { + if b.BlockOverrides == nil { + t.Fatalf("testcase %d: block overrides nil", i) + } + if b.BlockOverrides.Number == nil { + t.Fatalf("testcase %d: block number not set", i) + } + if b.BlockOverrides.Time == nil { + t.Fatalf("testcase %d: block time not set", i) + } + if uint64(*b.BlockOverrides.Time) != tc.expected[bi].timestamp { + t.Errorf("testcase %d: block timestamp mismatch. Want %d, have %d", i, tc.expected[bi].timestamp, uint64(*b.BlockOverrides.Time)) + } + have := b.BlockOverrides.Number.ToInt().Uint64() + if have != tc.expected[bi].number { + t.Errorf("testcase %d: block number mismatch. Want %d, have %d", i, tc.expected[bi].number, have) + } + } + } +} + +func newInt(n int64) *hexutil.Big { + return (*hexutil.Big)(big.NewInt(n)) +} diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json index 73da1b1752..11c0545ffa 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x4acfcd1a6ab9f5e62411021ecd8a749976ae50b0590e967471264b372d7ac55b", "timestamp": "0xa", - "totalDifficulty": "0x1", "transactions": [ "0x644a31c354391520d00e95b9affbbb010fc79ac268144ab8e28207f4cf51097e" ], diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-genesis.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-genesis.json index d2bdbacd73..134d60c67a 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-genesis.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-genesis.json @@ -16,7 +16,6 @@ "size": "0x200", "stateRoot": "0xd883f48b83cc9c1e8389453beb4ad4e572462eec049ca4fffbe16ecefb3fe937", "timestamp": "0x0", - "totalDifficulty": "0x1", "transactions": [], "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncles": [] diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json index 8e0748def9..3c8d42c9a9 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x78b2b19ef1a0276dbbc23a875dbf60ae5d10dafa0017098473c4871abd3e7b5c", "timestamp": "0x5a", - "totalDifficulty": "0x1", "transactions": [ { "blockHash": "0xedb9ccf3a85f67c095ad48abfb0fa09d47179bb0f902078d289042d12428aca5", diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json index 6e914e37d0..13876b5a52 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x118f1433ae23c4d1c12f5bd652baddb72611c55ac1cd6af6620d209db222f9e6", "timestamp": "0x64", - "totalDifficulty": "0x1", "transactions": [ "0x3ee4094ca1e0b07a66dd616a057e081e53144ca7e9685a126fd4dda9ca042644" ], diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-0.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-0.json index d2bdbacd73..134d60c67a 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-0.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-0.json @@ -16,7 +16,6 @@ "size": "0x200", "stateRoot": "0xd883f48b83cc9c1e8389453beb4ad4e572462eec049ca4fffbe16ecefb3fe937", "timestamp": "0x0", - "totalDifficulty": "0x1", "transactions": [], "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncles": [] diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json index 73da1b1752..11c0545ffa 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x4acfcd1a6ab9f5e62411021ecd8a749976ae50b0590e967471264b372d7ac55b", "timestamp": "0xa", - "totalDifficulty": "0x1", "transactions": [ "0x644a31c354391520d00e95b9affbbb010fc79ac268144ab8e28207f4cf51097e" ], diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json index 8e0748def9..3c8d42c9a9 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x78b2b19ef1a0276dbbc23a875dbf60ae5d10dafa0017098473c4871abd3e7b5c", "timestamp": "0x5a", - "totalDifficulty": "0x1", "transactions": [ { "blockHash": "0xedb9ccf3a85f67c095ad48abfb0fa09d47179bb0f902078d289042d12428aca5", diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json index 6e914e37d0..13876b5a52 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json @@ -16,7 +16,6 @@ "size": "0x26a", "stateRoot": "0x118f1433ae23c4d1c12f5bd652baddb72611c55ac1cd6af6620d209db222f9e6", "timestamp": "0x64", - "totalDifficulty": "0x1", "transactions": [ "0x3ee4094ca1e0b07a66dd616a057e081e53144ca7e9685a126fd4dda9ca042644" ], diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json index 1d524d6ece..60f18bc114 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json @@ -15,7 +15,6 @@ "size": "0x256", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x2a", - "totalDifficulty": null, "transactions": [ { "blockHash": "0x6cebd9f966ea686f44b981685e3f0eacea28591a7a86d7fbbe521a86e9f81165", diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json index c0e2b07bb8..dda2d93213 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json @@ -15,7 +15,6 @@ "size": "0x256", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x2a", - "totalDifficulty": null, "transactions": [ "0x4afee081df5dff7a025964032871f7d4ba4d21baf5f6376a2f4a9f79fc506298" ], diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-0.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-0.json index 1bd68888b6..e1e64a3093 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-0.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-0.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0xd883f48b83cc9c1e8389453beb4ad4e572462eec049ca4fffbe16ecefb3fe937", "timestamp": "0x0", - "totalDifficulty": "0x1", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json index cf662cad75..adfac5110c 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x4acfcd1a6ab9f5e62411021ecd8a749976ae50b0590e967471264b372d7ac55b", "timestamp": "0xa", - "totalDifficulty": "0x1", "transactionsRoot": "0xca0ebcce920d2cdfbf9e1dbe90ed3441a1a576f344bd80e60508da814916f4e7" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json index 4721dd1e7a..39209a86db 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x78b2b19ef1a0276dbbc23a875dbf60ae5d10dafa0017098473c4871abd3e7b5c", "timestamp": "0x5a", - "totalDifficulty": "0x1", "transactionsRoot": "0x0767ed8359337dc6a8fdc77fe52db611bed1be87aac73c4556b1bf1dd3d190a5" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json index 4dd5909159..5313348a50 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x118f1433ae23c4d1c12f5bd652baddb72611c55ac1cd6af6620d209db222f9e6", "timestamp": "0x64", - "totalDifficulty": "0x1", "transactionsRoot": "0xb0893d21a4a44dc26a962a6e91abae66df87fb61ac9c60e936aee89c76331445" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-0.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-0.json index 1bd68888b6..e1e64a3093 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-0.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-0.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0xd883f48b83cc9c1e8389453beb4ad4e572462eec049ca4fffbe16ecefb3fe937", "timestamp": "0x0", - "totalDifficulty": "0x1", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json index cf662cad75..adfac5110c 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x4acfcd1a6ab9f5e62411021ecd8a749976ae50b0590e967471264b372d7ac55b", "timestamp": "0xa", - "totalDifficulty": "0x1", "transactionsRoot": "0xca0ebcce920d2cdfbf9e1dbe90ed3441a1a576f344bd80e60508da814916f4e7" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json index 4721dd1e7a..39209a86db 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x78b2b19ef1a0276dbbc23a875dbf60ae5d10dafa0017098473c4871abd3e7b5c", "timestamp": "0x5a", - "totalDifficulty": "0x1", "transactionsRoot": "0x0767ed8359337dc6a8fdc77fe52db611bed1be87aac73c4556b1bf1dd3d190a5" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json index 4dd5909159..5313348a50 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json @@ -15,6 +15,5 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x118f1433ae23c4d1c12f5bd652baddb72611c55ac1cd6af6620d209db222f9e6", "timestamp": "0x64", - "totalDifficulty": "0x1", "transactionsRoot": "0xb0893d21a4a44dc26a962a6e91abae66df87fb61ac9c60e936aee89c76331445" } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json index da177f2189..289ff5fece 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json @@ -14,7 +14,6 @@ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x2a", - "totalDifficulty": null, "transactionsRoot": "0x98d9f6dd0aa479c0fb448f2627e9f1964aca699fccab8f6e95861547a4699e37", "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" } \ No newline at end of file diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index d424476691..37c45fd401 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -97,7 +97,7 @@ func (args *TransactionArgs) data() []byte { // setDefaults fills in default values for unspecified tx fields. func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGasEstimation bool) error { - if err := args.setBlobTxSidecar(ctx, b); err != nil { + if err := args.setBlobTxSidecar(ctx); err != nil { return err } if err := args.setFeeDefaults(ctx, b); err != nil { @@ -292,7 +292,7 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ } // setBlobTxSidecar adds the blob tx -func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) error { +func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context) error { // No blobs, we're done. if args.Blobs == nil { return nil @@ -328,12 +328,12 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) er commitments := make([]kzg4844.Commitment, n) proofs := make([]kzg4844.Proof, n) for i, b := range args.Blobs { - c, err := kzg4844.BlobToCommitment(b) + c, err := kzg4844.BlobToCommitment(&b) if err != nil { return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err) } commitments[i] = c - p, err := kzg4844.ComputeBlobProof(b, c) + p, err := kzg4844.ComputeBlobProof(&b, c) if err != nil { return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) } @@ -343,7 +343,7 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) er args.Proofs = proofs } else { for i, b := range args.Blobs { - if err := kzg4844.VerifyBlobProof(b, args.Commitments[i], args.Proofs[i]); err != nil { + if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil { return fmt.Errorf("failed to verify blob proof: %v", err) } } @@ -366,41 +366,71 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) er return nil } -// ToMessage converts the transaction arguments to the Message type used by the -// core evm. This method is used in calls and traces that do not require a real -// live transaction. -func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*core.Message, error) { +// CallDefaults sanitizes the transaction arguments, often filling in zero values, +// for the purpose of eth_call class of RPC methods. +func (args *TransactionArgs) CallDefaults(globalGasCap uint64, baseFee *big.Int, chainID *big.Int) error { // Reject invalid combinations of pre- and post-1559 fee styles if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") + return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") } - // Set sender address or use zero address if none specified. - addr := args.from() - - // Set default gas & gas price if none were set - gas := globalGasCap - if gas == 0 { - gas = uint64(math.MaxUint64 / 2) + if args.ChainID == nil { + args.ChainID = (*hexutil.Big)(chainID) + } else { + if have := (*big.Int)(args.ChainID); have.Cmp(chainID) != 0 { + return fmt.Errorf("chainId does not match node's (have=%v, want=%v)", have, chainID) + } + } + if args.Gas == nil { + gas := globalGasCap + if gas == 0 { + gas = uint64(math.MaxUint64 / 2) + } + args.Gas = (*hexutil.Uint64)(&gas) + } else { + if globalGasCap > 0 && globalGasCap < uint64(*args.Gas) { + log.Warn("Caller gas above allowance, capping", "requested", args.Gas, "cap", globalGasCap) + args.Gas = (*hexutil.Uint64)(&globalGasCap) + } } - if args.Gas != nil { - gas = uint64(*args.Gas) + if args.Nonce == nil { + args.Nonce = new(hexutil.Uint64) } - if globalGasCap != 0 && globalGasCap < gas { - log.Debug("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) - gas = globalGasCap + if args.Value == nil { + args.Value = new(hexutil.Big) } - var ( - gasPrice *big.Int - gasFeeCap *big.Int - gasTipCap *big.Int - blobFeeCap *big.Int - ) if baseFee == nil { // If there's no basefee, then it must be a non-1559 execution - gasPrice = new(big.Int) - if args.GasPrice != nil { - gasPrice = args.GasPrice.ToInt() + if args.GasPrice == nil { + args.GasPrice = new(hexutil.Big) + } + } else { + // A basefee is provided, necessitating 1559-type execution + if args.MaxFeePerGas == nil { + args.MaxFeePerGas = new(hexutil.Big) } + if args.MaxPriorityFeePerGas == nil { + args.MaxPriorityFeePerGas = new(hexutil.Big) + } + } + if args.BlobFeeCap == nil && args.BlobHashes != nil { + args.BlobFeeCap = new(hexutil.Big) + } + + return nil +} + +// ToMessage converts the transaction arguments to the Message type used by the +// core evm. This method is used in calls and traces that do not require a real +// live transaction. +// Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called. +func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoACheck bool) *core.Message { + var ( + gasPrice *big.Int + gasFeeCap *big.Int + gasTipCap *big.Int + ) + if baseFee == nil { + gasPrice = args.GasPrice.ToInt() gasFeeCap, gasTipCap = gasPrice, gasPrice } else { // A basefee is provided, necessitating 1559-type execution @@ -410,14 +440,8 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (* gasFeeCap, gasTipCap = gasPrice, gasPrice } else { // User specified 1559 gas fields (or none), use those - gasFeeCap = new(big.Int) - if args.MaxFeePerGas != nil { - gasFeeCap = args.MaxFeePerGas.ToInt() - } - gasTipCap = new(big.Int) - if args.MaxPriorityFeePerGas != nil { - gasTipCap = args.MaxPriorityFeePerGas.ToInt() - } + gasFeeCap = args.MaxFeePerGas.ToInt() + gasTipCap = args.MaxPriorityFeePerGas.ToInt() // Backfill the legacy gasPrice for EVM execution, unless we're all zeroes gasPrice = new(big.Int) if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 { @@ -425,43 +449,47 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (* } } } - if args.BlobFeeCap != nil { - blobFeeCap = args.BlobFeeCap.ToInt() - } else if args.BlobHashes != nil { - blobFeeCap = new(big.Int) - } - value := new(big.Int) - if args.Value != nil { - value = args.Value.ToInt() - } - data := args.data() var accessList types.AccessList if args.AccessList != nil { accessList = *args.AccessList } - msg := &core.Message{ - From: addr, - To: args.To, - Value: value, - GasLimit: gas, - GasPrice: gasPrice, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Data: data, - AccessList: accessList, - BlobGasFeeCap: blobFeeCap, - BlobHashes: args.BlobHashes, - SkipAccountChecks: true, - } - return msg, nil + return &core.Message{ + From: args.from(), + To: args.To, + Value: (*big.Int)(args.Value), + Nonce: uint64(*args.Nonce), + GasLimit: uint64(*args.Gas), + GasPrice: gasPrice, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Data: args.data(), + AccessList: accessList, + BlobGasFeeCap: (*big.Int)(args.BlobFeeCap), + BlobHashes: args.BlobHashes, + SkipNonceChecks: skipNonceCheck, + SkipFromEOACheck: skipEoACheck, + } } -// toTransaction converts the arguments to a transaction. +// ToTransaction converts the arguments to a transaction. // This assumes that setDefaults has been called. -func (args *TransactionArgs) toTransaction() *types.Transaction { - var data types.TxData +func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { + usedType := types.LegacyTxType switch { - case args.BlobHashes != nil: + case args.BlobHashes != nil || defaultType == types.BlobTxType: + usedType = types.BlobTxType + case args.MaxFeePerGas != nil || defaultType == types.DynamicFeeTxType: + usedType = types.DynamicFeeTxType + case args.AccessList != nil || defaultType == types.AccessListTxType: + usedType = types.AccessListTxType + } + // Make it possible to default to newer tx, but use legacy if gasprice is provided + if args.GasPrice != nil { + usedType = types.LegacyTxType + } + var data types.TxData + switch usedType { + case types.BlobTxType: al := types.AccessList{} if args.AccessList != nil { al = *args.AccessList @@ -487,7 +515,7 @@ func (args *TransactionArgs) toTransaction() *types.Transaction { } } - case args.MaxFeePerGas != nil: + case types.DynamicFeeTxType: al := types.AccessList{} if args.AccessList != nil { al = *args.AccessList @@ -504,7 +532,7 @@ func (args *TransactionArgs) toTransaction() *types.Transaction { AccessList: al, } - case args.AccessList != nil: + case types.AccessListTxType: data = &types.AccessListTx{ To: args.To, ChainID: (*big.Int)(args.ChainID), diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index cc00e839d6..63b0bda8cf 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -42,6 +42,8 @@ import ( // TestSetFeeDefaults tests the logic for filling in default fee values works as expected. func TestSetFeeDefaults(t *testing.T) { + t.Parallel() + type test struct { name string fork string // options: legacy, london, cancun @@ -314,13 +316,15 @@ func (b *backendMock) setFork(fork string) error { func (b *backendMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { return big.NewInt(42), nil } +func (b *backendMock) BlobBaseFee(ctx context.Context) *big.Int { return big.NewInt(42) } + func (b *backendMock) CurrentHeader() *types.Header { return b.current } func (b *backendMock) ChainConfig() *params.ChainConfig { return b.config } // Other methods needed to implement Backend interface. func (b *backendMock) SyncProgress() ethereum.SyncProgress { return ethereum.SyncProgress{} } -func (b *backendMock) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { - return nil, nil, nil, nil, nil +func (b *backendMock) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) { + return nil, nil, nil, nil, nil, nil, nil } func (b *backendMock) Chain() *core.BlockChain { return nil } @@ -360,7 +364,7 @@ func (b *backendMock) StateAndHeaderByNumber(ctx context.Context, number rpc.Blo func (b *backendMock) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { return nil, nil, nil } -func (b *backendMock) PendingBlockAndReceipts() (*types.Block, types.Receipts) { return nil, nil } +func (b *backendMock) Pending() (*types.Block, types.Receipts, *state.StateDB) { return nil, nil, nil } func (b *backendMock) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return nil, nil } @@ -407,9 +411,6 @@ func (b *backendMock) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscr func (b *backendMock) BloomStatus() (uint64, uint64) { return 0, 0 } func (b *backendMock) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {} func (b *backendMock) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { return nil } -func (b *backendMock) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { - return nil -} func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { return nil } diff --git a/internal/flags/categories.go b/internal/flags/categories.go index 382f7559d9..611c80e568 100644 --- a/internal/flags/categories.go +++ b/internal/flags/categories.go @@ -20,7 +20,7 @@ import "github.com/urfave/cli/v2" const ( EthCategory = "ETHEREUM" - LightCategory = "LIGHT CLIENT" + BeaconCategory = "BEACON CHAIN" DevCategory = "DEVELOPER CHAIN" StateCategory = "STATE HISTORY MANAGEMENT" EthashCategory = "ETHASH" diff --git a/internal/flags/flags_test.go b/internal/flags/flags_test.go index 681586b46c..cfe16b340e 100644 --- a/internal/flags/flags_test.go +++ b/internal/flags/flags_test.go @@ -24,6 +24,8 @@ import ( ) func TestPathExpansion(t *testing.T) { + t.Parallel() + user, _ := user.Current() var tests map[string]string @@ -53,9 +55,13 @@ func TestPathExpansion(t *testing.T) { os.Setenv(`DDDXXX`, `/tmp`) for test, expected := range tests { - got := expandPath(test) - if got != expected { - t.Errorf(`test %s, got %s, expected %s\n`, test, got, expected) - } + t.Run(test, func(t *testing.T) { + t.Parallel() + + got := expandPath(test) + if got != expected { + t.Errorf(`test %s, got %s, expected %s\n`, test, got, expected) + } + }) } } diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go index f682daac91..573898d7d0 100644 --- a/internal/guide/guide_test.go +++ b/internal/guide/guide_test.go @@ -35,6 +35,8 @@ import ( // Tests that the account management snippets work correctly. func TestAccountManagement(t *testing.T) { + t.Parallel() + // Create a temporary folder to work with workdir := t.TempDir() diff --git a/internal/jsre/completion_test.go b/internal/jsre/completion_test.go index 953bc5026d..8fbddbc299 100644 --- a/internal/jsre/completion_test.go +++ b/internal/jsre/completion_test.go @@ -23,6 +23,8 @@ import ( ) func TestCompleteKeywords(t *testing.T) { + t.Parallel() + re := New("", os.Stdout) re.Run(` function theClass() { @@ -85,9 +87,13 @@ func TestCompleteKeywords(t *testing.T) { }, } for _, test := range tests { - cs := re.CompleteKeywords(test.input) - if !reflect.DeepEqual(cs, test.want) { - t.Errorf("wrong completions for %q\ngot %v\nwant %v", test.input, cs, test.want) - } + t.Run(test.input, func(t *testing.T) { + t.Parallel() + + cs := re.CompleteKeywords(test.input) + if !reflect.DeepEqual(cs, test.want) { + t.Errorf("wrong completions for %q\ngot %v\nwant %v", test.input, cs, test.want) + } + }) } } diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 0e6b13ae10..b64e77ecc6 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3887,7 +3887,6 @@ var outputBlockFormatter = function(block) { block.number = utils.toDecimal(block.number); block.difficulty = utils.toBigNumber(block.difficulty); - block.totalDifficulty = utils.toBigNumber(block.totalDifficulty); if (utils.isArray(block.transactions)) { block.transactions.forEach(function(item){ @@ -5585,6 +5584,11 @@ var properties = function () { getter: 'eth_gasPrice', outputFormatter: formatters.outputBigNumberFormatter }), + new Property({ + name: 'blobBaseFee', + getter: 'eth_blobBaseFee', + outputFormatter: formatters.outputBigNumberFormatter + }), new Property({ name: 'accounts', getter: 'eth_accounts' diff --git a/internal/jsre/jsre_test.go b/internal/jsre/jsre_test.go index bb4ff5fa4f..a812d6116d 100644 --- a/internal/jsre/jsre_test.go +++ b/internal/jsre/jsre_test.go @@ -18,7 +18,7 @@ package jsre import ( "os" - "path" + "path/filepath" "reflect" "testing" "time" @@ -42,7 +42,7 @@ func (no *testNativeObjectBinding) TestMethod(call goja.FunctionCall) goja.Value func newWithTestJS(t *testing.T, testjs string) *JSRE { dir := t.TempDir() if testjs != "" { - if err := os.WriteFile(path.Join(dir, "test.js"), []byte(testjs), os.ModePerm); err != nil { + if err := os.WriteFile(filepath.Join(dir, "test.js"), []byte(testjs), os.ModePerm); err != nil { t.Fatal("cannot create test.js:", err) } } @@ -51,6 +51,8 @@ func newWithTestJS(t *testing.T, testjs string) *JSRE { } func TestExec(t *testing.T) { + t.Parallel() + jsre := newWithTestJS(t, `msg = "testMsg"`) err := jsre.Exec("test.js") @@ -73,6 +75,8 @@ func TestExec(t *testing.T) { } func TestNatto(t *testing.T) { + t.Parallel() + jsre := newWithTestJS(t, `setTimeout(function(){msg = "testMsg"}, 1);`) err := jsre.Exec("test.js") @@ -96,6 +100,8 @@ func TestNatto(t *testing.T) { } func TestBind(t *testing.T) { + t.Parallel() + jsre := New("", os.Stdout) defer jsre.Stop(false) @@ -108,6 +114,8 @@ func TestBind(t *testing.T) { } func TestLoadScript(t *testing.T) { + t.Parallel() + jsre := newWithTestJS(t, `msg = "testMsg"`) _, err := jsre.Run(`loadScript("test.js")`) diff --git a/internal/testlog/testlog.go b/internal/testlog/testlog.go index 037b7ee9c1..ad61af9eac 100644 --- a/internal/testlog/testlog.go +++ b/internal/testlog/testlog.go @@ -21,11 +21,11 @@ import ( "bytes" "context" "fmt" + "log/slog" "sync" "testing" "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/slog" ) const ( @@ -47,24 +47,29 @@ type bufHandler struct { buf []slog.Record attrs []slog.Attr level slog.Level + mu sync.Mutex } func (h *bufHandler) Handle(_ context.Context, r slog.Record) error { + h.mu.Lock() + defer h.mu.Unlock() h.buf = append(h.buf, r) return nil } func (h *bufHandler) Enabled(_ context.Context, lvl slog.Level) bool { - return lvl <= h.level + return lvl >= h.level } func (h *bufHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + h.mu.Lock() + defer h.mu.Unlock() records := make([]slog.Record, len(h.buf)) copy(records[:], h.buf[:]) return &bufHandler{ - records, - append(h.attrs, attrs...), - h.level, + buf: records, + attrs: append(h.attrs, attrs...), + level: h.level, } } @@ -75,9 +80,9 @@ func (h *bufHandler) WithGroup(_ string) slog.Handler { // Logger returns a logger which logs to the unit test log of t. func Logger(t *testing.T, level slog.Level) log.Logger { handler := bufHandler{ - []slog.Record{}, - []slog.Attr{}, - level, + buf: []slog.Record{}, + attrs: []slog.Attr{}, + level: level, } return &logger{ t: t, @@ -98,6 +103,10 @@ func LoggerWithHandler(t *testing.T, handler slog.Handler) log.Logger { } } +func (l *logger) Handler() slog.Handler { + return l.l.Handler() +} + func (l *logger) Write(level slog.Level, msg string, ctx ...interface{}) {} func (l *logger) Enabled(ctx context.Context, level slog.Level) bool { @@ -196,6 +205,8 @@ func (h *bufHandler) terminalFormat(r slog.Record) string { // flush writes all buffered messages and clears the buffer. func (l *logger) flush() { l.t.Helper() + l.h.mu.Lock() + defer l.h.mu.Unlock() for _, r := range l.h.buf { l.t.Logf("%s", l.h.terminalFormat(r)) } diff --git a/trie/testutil/utils.go b/internal/testrand/rand.go similarity index 61% rename from trie/testutil/utils.go rename to internal/testrand/rand.go index a75d0431b0..690993de05 100644 --- a/trie/testutil/utils.go +++ b/internal/testrand/rand.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package testutil +package testrand import ( crand "crypto/rand" @@ -22,11 +22,9 @@ import ( mrand "math/rand" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/trie/trienode" ) -// Prng is a pseudo random number generator seeded by strong randomness. +// prng is a pseudo random number generator seeded by strong randomness. // The randomness is printed on startup in order to make failures reproducible. var prng = initRand() @@ -37,25 +35,19 @@ func initRand() *mrand.Rand { return rnd } -// RandBytes generates a random byte slice with specified length. -func RandBytes(n int) []byte { +// Bytes generates a random byte slice with specified length. +func Bytes(n int) []byte { r := make([]byte, n) prng.Read(r) return r } -// RandomHash generates a random blob of data and returns it as a hash. -func RandomHash() common.Hash { - return common.BytesToHash(RandBytes(common.HashLength)) +// Hash generates a random hash. +func Hash() common.Hash { + return common.BytesToHash(Bytes(common.HashLength)) } -// RandomAddress generates a random blob of data and returns it as an address. -func RandomAddress() common.Address { - return common.BytesToAddress(RandBytes(common.AddressLength)) -} - -// RandomNode generates a random node. -func RandomNode() *trienode.Node { - val := RandBytes(100) - return trienode.New(crypto.Keccak256Hash(val), val) +// Address generates a random address. +func Address() common.Address { + return common.BytesToAddress(Bytes(common.AddressLength)) } diff --git a/internal/utesting/utesting_test.go b/internal/utesting/utesting_test.go index 31c7911c52..526d36bab1 100644 --- a/internal/utesting/utesting_test.go +++ b/internal/utesting/utesting_test.go @@ -24,6 +24,8 @@ import ( ) func TestTest(t *testing.T) { + t.Parallel() + tests := []Test{ { Name: "successful test", @@ -90,6 +92,8 @@ var outputTests = []Test{ } func TestOutput(t *testing.T) { + t.Parallel() + var buf bytes.Buffer RunTests(outputTests, &buf) @@ -116,6 +120,8 @@ $`[1:]) } func TestOutputTAP(t *testing.T) { + t.Parallel() + var buf bytes.Buffer RunTAP(outputTests, &buf) diff --git a/internal/version/version.go b/internal/version/version.go index 0daea02b57..2cca54b20f 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -65,7 +65,7 @@ func ClientName(clientIdentifier string) string { ) } -// runtimeInfo returns build and platform information about the current binary. +// Info returns build and platform information about the current binary. // // If the package that is currently executing is a prefixed by our go-ethereum // module path, it will print out commit and date VCS information. Otherwise, diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 361c46f9c0..5ac68c2cf6 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -261,7 +261,6 @@ web3._extend({ new web3._extend.Method({ name: 'chaindbProperty', call: 'debug_chaindbProperty', - params: 1, outputFormatter: console.log }), new web3._extend.Method({ @@ -609,6 +608,12 @@ web3._extend({ params: 4, inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null], }), + new web3._extend.Method({ + name: 'simulateV1', + call: 'eth_simulateV1', + params: 2, + inputFormatter: [null, web3._extend.formatters.inputDefaultBlockNumberFormatter], + }), new web3._extend.Method({ name: 'getBlockReceipts', call: 'eth_getBlockReceipts', @@ -711,10 +716,6 @@ web3._extend({ call: 'miner_setRecommitInterval', params: 1, }), - new web3._extend.Method({ - name: 'getHashrate', - call: 'miner_getHashrate' - }), ], properties: [] }); diff --git a/log/format.go b/log/format.go index 71bee8a6ff..1dae5c4fc5 100644 --- a/log/format.go +++ b/log/format.go @@ -3,6 +3,7 @@ package log import ( "bytes" "fmt" + "log/slog" "math/big" "reflect" "strconv" @@ -10,7 +11,6 @@ import ( "unicode/utf8" "github.com/holiman/uint256" - "golang.org/x/exp/slog" ) var ( @@ -83,24 +83,18 @@ func (h *TerminalHandler) format(buf []byte, r slog.Record, usecolor bool) []byt } func (h *TerminalHandler) formatAttributes(buf *bytes.Buffer, r slog.Record, color string) { - // tmp is a temporary buffer we use, until bytes.Buffer.AvailableBuffer() (1.21) - // can be used. - var tmp = make([]byte, 40) writeAttr := func(attr slog.Attr, first, last bool) { buf.WriteByte(' ') if color != "" { buf.WriteString(color) - //buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key)) - buf.Write(appendEscapeString(tmp[:0], attr.Key)) + buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key)) buf.WriteString("\x1b[0m=") } else { - //buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key)) - buf.Write(appendEscapeString(tmp[:0], attr.Key)) + buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key)) buf.WriteByte('=') } - //val := FormatSlogValue(attr.Value, true, buf.AvailableBuffer()) - val := FormatSlogValue(attr.Value, tmp[:0]) + val := FormatSlogValue(attr.Value, buf.AvailableBuffer()) padding := h.fieldPadding[attr.Key] @@ -358,7 +352,7 @@ func writeTimeTermFormat(buf *bytes.Buffer, t time.Time) { // writePosIntWidth writes non-negative integer i to the buffer, padded on the left // by zeroes to the given width. Use a width of 0 to omit padding. -// Adapted from golang.org/x/exp/slog/internal/buffer/buffer.go +// Adapted from pkg.go.dev/log/slog/internal/buffer func writePosIntWidth(b *bytes.Buffer, i, width int) { // Cheap integer to fixed-width decimal ASCII. // Copied from log/log.go. diff --git a/log/handler.go b/log/handler.go index f048cba80c..478e272ffc 100644 --- a/log/handler.go +++ b/log/handler.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "log/slog" "math/big" "os" "path" @@ -12,7 +13,6 @@ import ( "time" "github.com/holiman/uint256" - "golang.org/x/exp/slog" ) type discardHandler struct{} @@ -103,10 +103,10 @@ func (h *TerminalHandler) WithAttrs(attrs []slog.Attr) slog.Handler { } // ResetFieldPadding zeroes the field-padding for all attribute pairs. -func (t *TerminalHandler) ResetFieldPadding() { - t.mu.Lock() - t.fieldPadding = make(map[string]int) - t.mu.Unlock() +func (h *TerminalHandler) ResetFieldPadding() { + h.mu.Lock() + h.fieldPadding = make(map[string]int) + h.mu.Unlock() } type leveler struct{ minLevel slog.Level } @@ -117,8 +117,15 @@ func (l *leveler) Level() slog.Level { // JSONHandler returns a handler which prints records in JSON format. func JSONHandler(wr io.Writer) slog.Handler { + return JSONHandlerWithLevel(wr, levelMaxVerbosity) +} + +// JSONHandlerWithLevel returns a handler which prints records in JSON format that are less than or equal to +// the specified verbosity level. +func JSONHandlerWithLevel(wr io.Writer, level slog.Level) slog.Handler { return slog.NewJSONHandler(wr, &slog.HandlerOptions{ ReplaceAttr: builtinReplaceJSON, + Level: &leveler{level}, }) } diff --git a/log/handler_glog.go b/log/handler_glog.go index f51bae2a4a..739f8c5b42 100644 --- a/log/handler_glog.go +++ b/log/handler_glog.go @@ -20,14 +20,14 @@ import ( "context" "errors" "fmt" + "log/slog" + "maps" "regexp" "runtime" "strconv" "strings" "sync" "sync/atomic" - - "golang.org/x/exp/slog" ) // errVmoduleSyntax is returned when a user vmodule pattern is invalid. @@ -139,17 +139,18 @@ func (h *GlogHandler) Vmodule(ruleset string) error { return nil } +// Enabled implements slog.Handler, reporting whether the handler handles records +// at the given level. func (h *GlogHandler) Enabled(ctx context.Context, lvl slog.Level) bool { // fast-track skipping logging if override not enabled and the provided verbosity is above configured return h.override.Load() || slog.Level(h.level.Load()) <= lvl } +// WithAttrs implements slog.Handler, returning a new Handler whose attributes +// consist of both the receiver's attributes and the arguments. func (h *GlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { h.lock.RLock() - siteCache := make(map[uintptr]slog.Level) - for k, v := range h.siteCache { - siteCache[k] = v - } + siteCache := maps.Clone(h.siteCache) h.lock.RUnlock() patterns := []pattern{} @@ -167,12 +168,16 @@ func (h *GlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return &res } +// WithGroup implements slog.Handler, returning a new Handler with the given +// group appended to the receiver's existing groups. +// +// Note, this function is not implemented. func (h *GlogHandler) WithGroup(name string) slog.Handler { panic("not implemented") } -// Log implements Handler.Log, filtering a log record through the global, local -// and backtrace filters, finally emitting it if either allow it through. +// Handle implements slog.Handler, filtering a log record through the global, +// local and backtrace filters, finally emitting it if either allow it through. func (h *GlogHandler) Handle(_ context.Context, r slog.Record) error { // If the global log level allows, fast track logging if slog.Level(h.level.Load()) <= r.Level { diff --git a/log/logger.go b/log/logger.go index 91c9fed097..f4e7acba36 100644 --- a/log/logger.go +++ b/log/logger.go @@ -3,12 +3,11 @@ package log import ( "context" "fmt" + "log/slog" "math" "os" "runtime" "time" - - "golang.org/x/exp/slog" ) const errorKey = "LOG_ERROR" @@ -37,7 +36,7 @@ const ( LvlDebug = LevelDebug ) -// convert from old Geth verbosity level constants +// FromLegacyLevel converts from old Geth verbosity level constants // to levels defined by slog func FromLegacyLevel(lvl int) slog.Level { switch lvl { @@ -130,7 +129,7 @@ type Logger interface { // With returns a new Logger that has this logger's attributes plus the given attributes With(ctx ...interface{}) Logger - // With returns a new Logger that has this logger's attributes plus the given attributes. Identical to 'With'. + // New returns a new Logger that has this logger's attributes plus the given attributes. Identical to 'With'. New(ctx ...interface{}) Logger // Log logs a message at the specified level with context key/value pairs @@ -159,6 +158,9 @@ type Logger interface { // Enabled reports whether l emits log records at the given context and level. Enabled(ctx context.Context, level slog.Level) bool + + // Handler returns the underlying handler of the inner logger. + Handler() slog.Handler } type logger struct { @@ -172,7 +174,11 @@ func NewLogger(h slog.Handler) Logger { } } -// write logs a message at the specified level: +func (l *logger) Handler() slog.Handler { + return l.inner.Handler() +} + +// Write logs a message at the specified level. func (l *logger) Write(level slog.Level, msg string, attrs ...any) { if !l.inner.Enabled(context.Background(), level) { return diff --git a/log/logger_test.go b/log/logger_test.go index 8be8509ef5..067e1a0265 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "log/slog" "math/big" "os" "strings" @@ -12,7 +13,6 @@ import ( "time" "github.com/holiman/uint256" - "golang.org/x/exp/slog" ) // TestLoggingWithVmodule checks that vmodule works. @@ -26,7 +26,7 @@ func TestLoggingWithVmodule(t *testing.T) { logger.Trace("a message", "foo", "bar") have := out.String() // The timestamp is locale-dependent, so we want to trim that off - // "INFO [01-01|00:00:00.000] a messag ..." -> "a messag..." + // "INFO [01-01|00:00:00.000] a message ..." -> "a message..." have = strings.Split(have, "]")[1] want := " a message foo=bar\n" if have != want { @@ -42,7 +42,7 @@ func TestTerminalHandlerWithAttrs(t *testing.T) { logger.Trace("a message", "foo", "bar") have := out.String() // The timestamp is locale-dependent, so we want to trim that off - // "INFO [01-01|00:00:00.000] a messag ..." -> "a messag..." + // "INFO [01-01|00:00:00.000] a message ..." -> "a message..." have = strings.Split(have, "]")[1] want := " a message baz=bat foo=bar\n" if have != want { @@ -50,6 +50,25 @@ func TestTerminalHandlerWithAttrs(t *testing.T) { } } +// Make sure the default json handler outputs debug log lines +func TestJSONHandler(t *testing.T) { + out := new(bytes.Buffer) + handler := JSONHandler(out) + logger := slog.New(handler) + logger.Debug("hi there") + if len(out.String()) == 0 { + t.Error("expected non-empty debug log output from default JSON Handler") + } + + out.Reset() + handler = JSONHandlerWithLevel(out, slog.LevelInfo) + logger = slog.New(handler) + logger.Debug("hi there") + if len(out.String()) != 0 { + t.Errorf("expected empty debug log output, but got: %v", out.String()) + } +} + func BenchmarkTraceLogging(b *testing.B) { SetDefault(NewLogger(NewTerminalHandler(os.Stderr, true))) b.ResetTimer() @@ -78,7 +97,7 @@ func benchmarkLogger(b *testing.B, l Logger) { tt = time.Now() bigint = big.NewInt(100) nilbig *big.Int - err = errors.New("Oh nooes it's crap") + err = errors.New("oh nooes it's crap") ) b.ReportAllocs() b.ResetTimer() @@ -107,7 +126,7 @@ func TestLoggerOutput(t *testing.T) { tt = time.Time{} bigint = big.NewInt(100) nilbig *big.Int - err = errors.New("Oh nooes it's crap") + err = errors.New("oh nooes it's crap") smallUint = uint256.NewInt(500_000) bigUint = &uint256.Int{0xff, 0xff, 0xff, 0xff} ) @@ -131,7 +150,7 @@ func TestLoggerOutput(t *testing.T) { have := out.String() t.Logf("output %v", out.String()) - want := `INFO [11-07|19:14:33.821] This is a message foo=123 bytes="[0 0 0 0 0 0 0 0 0 0]" bonk="a string with text" time=0001-01-01T00:00:00+0000 bigint=100 nilbig= err="Oh nooes it's crap" struct="{A:Foo B:12}" struct="{A:Foo\nLinebreak B:122}" ptrstruct="&{A:Foo B:12}" smalluint=500,000 bigUint=1,600,660,942,523,603,594,864,898,306,482,794,244,293,965,082,972,225,630,372,095 + want := `INFO [11-07|19:14:33.821] This is a message foo=123 bytes="[0 0 0 0 0 0 0 0 0 0]" bonk="a string with text" time=0001-01-01T00:00:00+0000 bigint=100 nilbig= err="oh nooes it's crap" struct="{A:Foo B:12}" struct="{A:Foo\nLinebreak B:122}" ptrstruct="&{A:Foo B:12}" smalluint=500,000 bigUint=1,600,660,942,523,603,594,864,898,306,482,794,244,293,965,082,972,225,630,372,095 ` if !bytes.Equal([]byte(have)[25:], []byte(want)[25:]) { t.Errorf("Error\nhave: %q\nwant: %q", have, want) diff --git a/log/root.go b/log/root.go index 355991b260..c0c73a2632 100644 --- a/log/root.go +++ b/log/root.go @@ -1,11 +1,10 @@ package log import ( + "log/slog" "os" "sync/atomic" "time" - - "golang.org/x/exp/slog" ) var root atomic.Value diff --git a/metrics/README.md b/metrics/README.md index e2d7945008..85b119470a 100644 --- a/metrics/README.md +++ b/metrics/README.md @@ -100,24 +100,6 @@ go influxdb.InfluxDB(metrics.DefaultRegistry, ) ``` -Periodically upload every metric to Librato using the [Librato client](https://github.com/mihasya/go-metrics-librato): - -**Note**: the client included with this repository under the `librato` package -has been deprecated and moved to the repository linked above. - -```go -import "github.com/mihasya/go-metrics-librato" - -go librato.Librato(metrics.DefaultRegistry, - 10e9, // interval - "example@example.com", // account owner email address - "token", // Librato API token - "hostname", // source - []float64{0.95}, // percentiles to send - time.Millisecond, // time unit -) -``` - Periodically emit every metric to StatHat: ```go @@ -157,7 +139,6 @@ Publishing Metrics Clients are available for the following destinations: -* Librato - https://github.com/mihasya/go-metrics-librato * Graphite - https://github.com/cyberdelia/go-metrics-graphite * InfluxDB - https://github.com/vrischmann/go-metrics-influxdb * Ganglia - https://github.com/appscode/metlia diff --git a/metrics/config.go b/metrics/config.go index 2eb09fb48a..72f94dd194 100644 --- a/metrics/config.go +++ b/metrics/config.go @@ -19,7 +19,7 @@ package metrics // Config contains the configuration for the metric collection. type Config struct { Enabled bool `toml:",omitempty"` - EnabledExpensive bool `toml:",omitempty"` + EnabledExpensive bool `toml:"-"` HTTP string `toml:",omitempty"` Port int `toml:",omitempty"` EnableInfluxDB bool `toml:",omitempty"` diff --git a/metrics/debug.go b/metrics/debug.go index de4a2739fe..9dfee1a866 100644 --- a/metrics/debug.go +++ b/metrics/debug.go @@ -19,18 +19,18 @@ var ( gcStats debug.GCStats ) -// Capture new values for the Go garbage collector statistics exported in -// debug.GCStats. This is designed to be called as a goroutine. +// CaptureDebugGCStats captures new values for the Go garbage collector statistics +// exported in debug.GCStats. This is designed to be called as a goroutine. func CaptureDebugGCStats(r Registry, d time.Duration) { for range time.Tick(d) { CaptureDebugGCStatsOnce(r) } } -// Capture new values for the Go garbage collector statistics exported in -// debug.GCStats. This is designed to be called in a background goroutine. -// Giving a registry which has not been given to RegisterDebugGCStats will -// panic. +// CaptureDebugGCStatsOnce captures new values for the Go garbage collector +// statistics exported in debug.GCStats. This is designed to be called in +// a background goroutine. Giving a registry which has not been given to +// RegisterDebugGCStats will panic. // // Be careful (but much less so) with this because debug.ReadGCStats calls // the C function runtime·lock(runtime·mheap) which, while not a stop-the-world @@ -50,9 +50,9 @@ func CaptureDebugGCStatsOnce(r Registry) { debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal)) } -// Register metrics for the Go garbage collector statistics exported in -// debug.GCStats. The metrics are named by their fully-qualified Go symbols, -// i.e. debug.GCStats.PauseTotal. +// RegisterDebugGCStats registers metrics for the Go garbage collector statistics +// exported in debug.GCStats. The metrics are named by their fully-qualified Go +// symbols, i.e. debug.GCStats.PauseTotal. func RegisterDebugGCStats(r Registry) { debugMetrics.GCStats.LastGC = NewGauge() debugMetrics.GCStats.NumGC = NewGauge() diff --git a/metrics/gauge.go b/metrics/gauge.go index 5933df3107..6d10bbf856 100644 --- a/metrics/gauge.go +++ b/metrics/gauge.go @@ -74,7 +74,7 @@ func (g *StandardGauge) Update(v int64) { g.value.Store(v) } -// Update updates the gauge's value if v is larger then the current value. +// UpdateIfGt updates the gauge's value if v is larger then the current value. func (g *StandardGauge) UpdateIfGt(v int64) { for { exist := g.value.Load() diff --git a/metrics/influxdb/influxdb.go b/metrics/influxdb/influxdb.go index bbc4fc024b..5c8501fd9d 100644 --- a/metrics/influxdb/influxdb.go +++ b/metrics/influxdb/influxdb.go @@ -98,20 +98,23 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf } return measurement, fields case metrics.ResettingTimer: - t := metric.Snapshot() - if t.Count() == 0 { + ms := metric.Snapshot() + if ms.Count() == 0 { break } - ps := t.Percentiles([]float64{0.50, 0.95, 0.99}) - measurement := fmt.Sprintf("%s%s.span", namespace, name) + ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}) + measurement := fmt.Sprintf("%s%s.timer", namespace, name) fields := map[string]interface{}{ - "count": t.Count(), - "max": t.Max(), - "mean": t.Mean(), - "min": t.Min(), - "p50": int(ps[0]), - "p95": int(ps[1]), - "p99": int(ps[2]), + "count": ms.Count(), + "max": ms.Max(), + "mean": ms.Mean(), + "min": ms.Min(), + "p50": ps[0], + "p75": ps[1], + "p95": ps[2], + "p99": ps[3], + "p999": ps[4], + "p9999": ps[5], } return measurement, fields } diff --git a/metrics/influxdb/influxdb_test.go b/metrics/influxdb/influxdb_test.go index 6daeb1aa03..2b757897d5 100644 --- a/metrics/influxdb/influxdb_test.go +++ b/metrics/influxdb/influxdb_test.go @@ -38,6 +38,10 @@ func TestMain(m *testing.M) { } func TestExampleV1(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("test skipped on ARM64 due to floating point precision differences") + } + r := internal.ExampleMetrics() var have, want string ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -70,6 +74,10 @@ func TestExampleV1(t *testing.T) { } func TestExampleV2(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("test skipped on ARM64 due to floating point precision differences") + } + r := internal.ExampleMetrics() var have, want string ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/metrics/influxdb/testdata/influxdbv1.want b/metrics/influxdb/testdata/influxdbv1.want index 9443faedc5..ded9434c73 100644 --- a/metrics/influxdb/testdata/influxdbv1.want +++ b/metrics/influxdb/testdata/influxdbv1.want @@ -7,5 +7,5 @@ goth.test/gauge_float64.gauge value=34567.89 978307200000000000 goth.test/gauge_info.gauge value="{\"arch\":\"amd64\",\"commit\":\"7caa2d8163ae3132c1c2d6978c76610caee2d949\",\"os\":\"linux\",\"protocol_versions\":\"64 65 66\",\"version\":\"1.10.18-unstable\"}" 978307200000000000 goth.test/histogram.histogram count=3i,max=3i,mean=2,min=1i,p25=1,p50=2,p75=3,p95=3,p99=3,p999=3,p9999=3,stddev=0.816496580927726,variance=0.6666666666666666 978307200000000000 goth.test/meter.meter count=0i,m1=0,m15=0,m5=0,mean=0 978307200000000000 -goth.test/resetting_timer.span count=6i,max=120000000i,mean=30000000,min=10000000i,p50=12500000i,p95=120000000i,p99=120000000i 978307200000000000 +goth.test/resetting_timer.timer count=6i,max=120000000i,mean=30000000,min=10000000i,p50=12500000,p75=40500000,p95=120000000,p99=120000000,p999=120000000,p9999=120000000 978307200000000000 goth.test/timer.timer count=6i,m1=0,m15=0,m5=0,max=120000000i,mean=38333333.333333336,meanrate=0,min=20000000i,p50=22500000,p75=48000000,p95=120000000,p99=120000000,p999=120000000,p9999=120000000,stddev=36545253.529775314,variance=1335555555555555.2 978307200000000000 diff --git a/metrics/influxdb/testdata/influxdbv2.want b/metrics/influxdb/testdata/influxdbv2.want index 9443faedc5..ded9434c73 100644 --- a/metrics/influxdb/testdata/influxdbv2.want +++ b/metrics/influxdb/testdata/influxdbv2.want @@ -7,5 +7,5 @@ goth.test/gauge_float64.gauge value=34567.89 978307200000000000 goth.test/gauge_info.gauge value="{\"arch\":\"amd64\",\"commit\":\"7caa2d8163ae3132c1c2d6978c76610caee2d949\",\"os\":\"linux\",\"protocol_versions\":\"64 65 66\",\"version\":\"1.10.18-unstable\"}" 978307200000000000 goth.test/histogram.histogram count=3i,max=3i,mean=2,min=1i,p25=1,p50=2,p75=3,p95=3,p99=3,p999=3,p9999=3,stddev=0.816496580927726,variance=0.6666666666666666 978307200000000000 goth.test/meter.meter count=0i,m1=0,m15=0,m5=0,mean=0 978307200000000000 -goth.test/resetting_timer.span count=6i,max=120000000i,mean=30000000,min=10000000i,p50=12500000i,p95=120000000i,p99=120000000i 978307200000000000 +goth.test/resetting_timer.timer count=6i,max=120000000i,mean=30000000,min=10000000i,p50=12500000,p75=40500000,p95=120000000,p99=120000000,p999=120000000,p9999=120000000 978307200000000000 goth.test/timer.timer count=6i,m1=0,m15=0,m5=0,max=120000000i,mean=38333333.333333336,meanrate=0,min=20000000i,p50=22500000,p75=48000000,p95=120000000,p99=120000000,p999=120000000,p9999=120000000,stddev=36545253.529775314,variance=1335555555555555.2 978307200000000000 diff --git a/metrics/json.go b/metrics/json.go index 2087d8211e..6b134d477b 100644 --- a/metrics/json.go +++ b/metrics/json.go @@ -26,6 +26,6 @@ func WriteJSONOnce(r Registry, w io.Writer) { json.NewEncoder(w).Encode(r) } -func (p *PrefixedRegistry) MarshalJSON() ([]byte, error) { - return json.Marshal(p.GetAll()) +func (r *PrefixedRegistry) MarshalJSON() ([]byte, error) { + return json.Marshal(r.GetAll()) } diff --git a/metrics/librato/client.go b/metrics/librato/client.go deleted file mode 100644 index f1b9e1e916..0000000000 --- a/metrics/librato/client.go +++ /dev/null @@ -1,104 +0,0 @@ -package librato - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" -) - -const Operations = "operations" -const OperationsShort = "ops" - -type LibratoClient struct { - Email, Token string -} - -// property strings -const ( - // display attributes - Color = "color" - DisplayMax = "display_max" - DisplayMin = "display_min" - DisplayUnitsLong = "display_units_long" - DisplayUnitsShort = "display_units_short" - DisplayStacked = "display_stacked" - DisplayTransform = "display_transform" - // special gauge display attributes - SummarizeFunction = "summarize_function" - Aggregate = "aggregate" - - // metric keys - Name = "name" - Period = "period" - Description = "description" - DisplayName = "display_name" - Attributes = "attributes" - - // measurement keys - MeasureTime = "measure_time" - Source = "source" - Value = "value" - - // special gauge keys - Count = "count" - Sum = "sum" - Max = "max" - Min = "min" - SumSquares = "sum_squares" - - // batch keys - Counters = "counters" - Gauges = "gauges" - - MetricsPostUrl = "https://metrics-api.librato.com/v1/metrics" -) - -type Measurement map[string]interface{} -type Metric map[string]interface{} - -type Batch struct { - Gauges []Measurement `json:"gauges,omitempty"` - Counters []Measurement `json:"counters,omitempty"` - MeasureTime int64 `json:"measure_time"` - Source string `json:"source"` -} - -func (c *LibratoClient) PostMetrics(batch Batch) (err error) { - var ( - js []byte - req *http.Request - resp *http.Response - ) - - if len(batch.Counters) == 0 && len(batch.Gauges) == 0 { - return nil - } - - if js, err = json.Marshal(batch); err != nil { - return - } - - if req, err = http.NewRequest(http.MethodPost, MetricsPostUrl, bytes.NewBuffer(js)); err != nil { - return - } - - req.Header.Set("Content-Type", "application/json") - req.SetBasicAuth(c.Email, c.Token) - - resp, err = http.DefaultClient.Do(req) - if err != nil { - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - var body []byte - if body, err = io.ReadAll(resp.Body); err != nil { - body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err)) - } - err = fmt.Errorf("unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body)) - } - return -} diff --git a/metrics/librato/librato.go b/metrics/librato/librato.go deleted file mode 100644 index a86f758637..0000000000 --- a/metrics/librato/librato.go +++ /dev/null @@ -1,254 +0,0 @@ -package librato - -import ( - "fmt" - "log" - "math" - "regexp" - "time" - - "github.com/ethereum/go-ethereum/metrics" -) - -// a regexp for extracting the unit from time.Duration.String -var unitRegexp = regexp.MustCompile(`[^\\d]+$`) - -// a helper that turns a time.Duration into librato display attributes for timer metrics -func translateTimerAttributes(d time.Duration) (attrs map[string]interface{}) { - attrs = make(map[string]interface{}) - attrs[DisplayTransform] = fmt.Sprintf("x/%d", int64(d)) - attrs[DisplayUnitsShort] = string(unitRegexp.Find([]byte(d.String()))) - return -} - -type Reporter struct { - Email, Token string - Namespace string - Source string - Interval time.Duration - Registry metrics.Registry - Percentiles []float64 // percentiles to report on histogram metrics - TimerAttributes map[string]interface{} // units in which timers will be displayed - intervalSec int64 -} - -func NewReporter(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) *Reporter { - return &Reporter{e, t, "", s, d, r, p, translateTimerAttributes(u), int64(d / time.Second)} -} - -func Librato(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) { - NewReporter(r, d, e, t, s, p, u).Run() -} - -func (rep *Reporter) Run() { - log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015") - ticker := time.NewTicker(rep.Interval) - defer ticker.Stop() - metricsApi := &LibratoClient{rep.Email, rep.Token} - for now := range ticker.C { - var metrics Batch - var err error - if metrics, err = rep.BuildRequest(now, rep.Registry); err != nil { - log.Printf("ERROR constructing librato request body %s", err) - continue - } - if err := metricsApi.PostMetrics(metrics); err != nil { - log.Printf("ERROR sending metrics to librato %s", err) - continue - } - } -} - -// calculate sum of squares from data provided by metrics.Histogram -// see http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods -func sumSquares(icount int64, mean, stDev float64) float64 { - count := float64(icount) - sumSquared := math.Pow(count*mean, 2) - sumSquares := math.Pow(count*stDev, 2) + sumSquared/count - if math.IsNaN(sumSquares) { - return 0.0 - } - return sumSquares -} -func sumSquaresTimer(t metrics.TimerSnapshot) float64 { - count := float64(t.Count()) - sumSquared := math.Pow(count*t.Mean(), 2) - sumSquares := math.Pow(count*t.StdDev(), 2) + sumSquared/count - if math.IsNaN(sumSquares) { - return 0.0 - } - return sumSquares -} - -func (rep *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) { - snapshot = Batch{ - // coerce timestamps to a stepping fn so that they line up in Librato graphs - MeasureTime: (now.Unix() / rep.intervalSec) * rep.intervalSec, - Source: rep.Source, - } - snapshot.Gauges = make([]Measurement, 0) - snapshot.Counters = make([]Measurement, 0) - histogramGaugeCount := 1 + len(rep.Percentiles) - r.Each(func(name string, metric interface{}) { - if rep.Namespace != "" { - name = fmt.Sprintf("%s.%s", rep.Namespace, name) - } - measurement := Measurement{} - measurement[Period] = rep.Interval.Seconds() - switch m := metric.(type) { - case metrics.Counter: - ms := m.Snapshot() - if ms.Count() > 0 { - measurement[Name] = fmt.Sprintf("%s.%s", name, "count") - measurement[Value] = float64(ms.Count()) - measurement[Attributes] = map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - } - snapshot.Counters = append(snapshot.Counters, measurement) - } - case metrics.CounterFloat64: - if count := m.Snapshot().Count(); count > 0 { - measurement[Name] = fmt.Sprintf("%s.%s", name, "count") - measurement[Value] = count - measurement[Attributes] = map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - } - snapshot.Counters = append(snapshot.Counters, measurement) - } - case metrics.Gauge: - measurement[Name] = name - measurement[Value] = float64(m.Snapshot().Value()) - snapshot.Gauges = append(snapshot.Gauges, measurement) - case metrics.GaugeFloat64: - measurement[Name] = name - measurement[Value] = m.Snapshot().Value() - snapshot.Gauges = append(snapshot.Gauges, measurement) - case metrics.GaugeInfo: - measurement[Name] = name - measurement[Value] = m.Snapshot().Value() - snapshot.Gauges = append(snapshot.Gauges, measurement) - case metrics.Histogram: - ms := m.Snapshot() - if ms.Count() > 0 { - gauges := make([]Measurement, histogramGaugeCount) - measurement[Name] = fmt.Sprintf("%s.%s", name, "hist") - measurement[Count] = uint64(ms.Count()) - measurement[Max] = float64(ms.Max()) - measurement[Min] = float64(ms.Min()) - measurement[Sum] = float64(ms.Sum()) - measurement[SumSquares] = sumSquares(ms.Count(), ms.Mean(), ms.StdDev()) - gauges[0] = measurement - for i, p := range rep.Percentiles { - gauges[i+1] = Measurement{ - Name: fmt.Sprintf("%s.%.2f", measurement[Name], p), - Value: ms.Percentile(p), - Period: measurement[Period], - } - } - snapshot.Gauges = append(snapshot.Gauges, gauges...) - } - case metrics.Meter: - ms := m.Snapshot() - measurement[Name] = name - measurement[Value] = float64(ms.Count()) - snapshot.Counters = append(snapshot.Counters, measurement) - snapshot.Gauges = append(snapshot.Gauges, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "1min"), - Value: ms.Rate1(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "5min"), - Value: ms.Rate5(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "15min"), - Value: ms.Rate15(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - ) - case metrics.Timer: - ms := m.Snapshot() - measurement[Name] = name - measurement[Value] = float64(ms.Count()) - snapshot.Counters = append(snapshot.Counters, measurement) - if ms.Count() > 0 { - libratoName := fmt.Sprintf("%s.%s", name, "timer.mean") - gauges := make([]Measurement, histogramGaugeCount) - gauges[0] = Measurement{ - Name: libratoName, - Count: uint64(ms.Count()), - Sum: ms.Mean() * float64(ms.Count()), - Max: float64(ms.Max()), - Min: float64(ms.Min()), - SumSquares: sumSquaresTimer(ms), - Period: int64(rep.Interval.Seconds()), - Attributes: rep.TimerAttributes, - } - for i, p := range rep.Percentiles { - gauges[i+1] = Measurement{ - Name: fmt.Sprintf("%s.timer.%2.0f", name, p*100), - Value: ms.Percentile(p), - Period: int64(rep.Interval.Seconds()), - Attributes: rep.TimerAttributes, - } - } - snapshot.Gauges = append(snapshot.Gauges, gauges...) - snapshot.Gauges = append(snapshot.Gauges, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "rate.1min"), - Value: ms.Rate1(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "rate.5min"), - Value: ms.Rate5(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - Measurement{ - Name: fmt.Sprintf("%s.%s", name, "rate.15min"), - Value: ms.Rate15(), - Period: int64(rep.Interval.Seconds()), - Attributes: map[string]interface{}{ - DisplayUnitsLong: Operations, - DisplayUnitsShort: OperationsShort, - DisplayMin: "0", - }, - }, - ) - } - } - }) - return -} diff --git a/metrics/meter.go b/metrics/meter.go index 22475ef6eb..432838f4ef 100644 --- a/metrics/meter.go +++ b/metrics/meter.go @@ -173,7 +173,7 @@ type meterArbiter struct { var arbiter = meterArbiter{ticker: time.NewTicker(5 * time.Second), meters: make(map[*StandardMeter]struct{})} -// Ticks meters on the scheduled interval +// tick meters on the scheduled interval func (ma *meterArbiter) tick() { for range ma.ticker.C { ma.tickMeters() diff --git a/metrics/metrics.go b/metrics/metrics.go index fba6781b97..213ebf6b56 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -24,24 +24,13 @@ import ( // for less cluttered pprof profiles. var Enabled = false -// EnabledExpensive is a soft-flag meant for external packages to check if costly -// metrics gathering is allowed or not. The goal is to separate standard metrics -// for health monitoring and debug metrics that might impact runtime performance. -var EnabledExpensive = false - // enablerFlags is the CLI flag names to use to enable metrics collections. var enablerFlags = []string{"metrics"} // enablerEnvVars is the env var names to use to enable metrics collections. var enablerEnvVars = []string{"GETH_METRICS"} -// expensiveEnablerFlags is the CLI flag names to use to enable metrics collections. -var expensiveEnablerFlags = []string{"metrics.expensive"} - -// expensiveEnablerEnvVars is the env var names to use to enable metrics collections. -var expensiveEnablerEnvVars = []string{"GETH_METRICS_EXPENSIVE"} - -// Init enables or disables the metrics system. Since we need this to run before +// init enables or disables the metrics system. Since we need this to run before // any other code gets to create meters and timers, we'll actually do an ugly hack // and peek into the command line args for the metrics flag. func init() { @@ -53,14 +42,6 @@ func init() { } } } - for _, enabler := range expensiveEnablerEnvVars { - if val, found := syscall.Getenv(enabler); found && !EnabledExpensive { - if enable, _ := strconv.ParseBool(val); enable { // ignore error, flag parser will choke on it later - log.Info("Enabling expensive metrics collection") - EnabledExpensive = true - } - } - } for _, arg := range os.Args { flag := strings.TrimLeft(arg, "-") @@ -70,12 +51,6 @@ func init() { Enabled = true } } - for _, enabler := range expensiveEnablerFlags { - if !EnabledExpensive && flag == enabler { - log.Info("Enabling expensive metrics collection") - EnabledExpensive = true - } - } } } diff --git a/metrics/prometheus/collector.go b/metrics/prometheus/collector.go index a6a93ce0ee..f330e62a2e 100644 --- a/metrics/prometheus/collector.go +++ b/metrics/prometheus/collector.go @@ -128,12 +128,13 @@ func (c *collector) addResettingTimer(name string, m metrics.ResettingTimerSnaps if m.Count() <= 0 { return } - ps := m.Percentiles([]float64{0.50, 0.95, 0.99}) + pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} + ps := m.Percentiles(pv) c.writeSummaryCounter(name, m.Count()) c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name))) - c.writeSummaryPercentile(name, "0.50", ps[0]) - c.writeSummaryPercentile(name, "0.95", ps[1]) - c.writeSummaryPercentile(name, "0.99", ps[2]) + for i := range pv { + c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) + } c.buff.WriteRune('\n') } diff --git a/metrics/prometheus/testdata/prometheus.want b/metrics/prometheus/testdata/prometheus.want index 861c5f5cf0..a999d83801 100644 --- a/metrics/prometheus/testdata/prometheus.want +++ b/metrics/prometheus/testdata/prometheus.want @@ -53,9 +53,12 @@ test_meter 0 test_resetting_timer_count 6 # TYPE test_resetting_timer summary -test_resetting_timer {quantile="0.50"} 1.25e+07 +test_resetting_timer {quantile="0.5"} 1.25e+07 +test_resetting_timer {quantile="0.75"} 4.05e+07 test_resetting_timer {quantile="0.95"} 1.2e+08 test_resetting_timer {quantile="0.99"} 1.2e+08 +test_resetting_timer {quantile="0.999"} 1.2e+08 +test_resetting_timer {quantile="0.9999"} 1.2e+08 # TYPE test_timer_count counter test_timer_count 6 diff --git a/metrics/registry.go b/metrics/registry.go index 0dd7cf9bba..57324160f8 100644 --- a/metrics/registry.go +++ b/metrics/registry.go @@ -8,8 +8,8 @@ import ( "sync" ) -// DuplicateMetric is the error returned by Registry.Register when a metric -// already exists. If you mean to Register that metric you must first +// DuplicateMetric is the error returned by Registry. Register when a metric +// already exists. If you mean to Register that metric you must first // Unregister the existing metric. type DuplicateMetric string @@ -20,11 +20,11 @@ func (err DuplicateMetric) Error() string { // A Registry holds references to a set of metrics by name and can iterate // over them, calling callback functions provided by the user. // -// This is an interface so as to encourage other structs to implement +// This is an interface to encourage other structs to implement // the Registry API as appropriate. type Registry interface { - // Call the given function for each registered metric. + // Each call the given function for each registered metric. Each(func(string, interface{})) // Get the metric by the given name or nil if none is registered. @@ -33,7 +33,7 @@ type Registry interface { // GetAll metrics in the Registry. GetAll() map[string]map[string]interface{} - // Gets an existing metric or registers the given one. + // GetOrRegister gets an existing metric or registers the given one. // The interface can be the metric to register if not found in registry, // or a function returning the metric for lazy instantiation. GetOrRegister(string, interface{}) interface{} @@ -41,7 +41,7 @@ type Registry interface { // Register the given metric under the given name. Register(string, interface{}) error - // Run all registered healthchecks. + // RunHealthchecks run all registered healthchecks. RunHealthchecks() // Unregister the metric with the given name. @@ -52,7 +52,7 @@ type orderedRegistry struct { StandardRegistry } -// Call the given function for each registered metric. +// Each call the given function for each registered metric. func (r *orderedRegistry) Each(f func(string, interface{})) { var names []string reg := r.registered() @@ -75,13 +75,13 @@ func NewOrderedRegistry() Registry { return new(orderedRegistry) } -// The standard implementation of a Registry uses sync.map +// StandardRegistry the standard implementation of a Registry uses sync.map // of names to metrics. type StandardRegistry struct { metrics sync.Map } -// Call the given function for each registered metric. +// Each call the given function for each registered metric. func (r *StandardRegistry) Each(f func(string, interface{})) { for name, i := range r.registered() { f(name, i) @@ -94,7 +94,7 @@ func (r *StandardRegistry) Get(name string) interface{} { return item } -// Gets an existing metric or creates and registers a new one. Threadsafe +// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe // alternative to calling Get and Register on failure. // The interface can be the metric to register if not found in registry, // or a function returning the metric for lazy instantiation. @@ -114,7 +114,7 @@ func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} return item } -// Register the given metric under the given name. Returns a DuplicateMetric +// Register the given metric under the given name. Returns a DuplicateMetric // if a metric by the given name is already registered. func (r *StandardRegistry) Register(name string, i interface{}) error { // fast path @@ -133,7 +133,7 @@ func (r *StandardRegistry) Register(name string, i interface{}) error { return nil } -// Run all registered healthchecks. +// RunHealthchecks run all registered healthchecks. func (r *StandardRegistry) RunHealthchecks() { r.metrics.Range(func(key, value any) bool { if h, ok := value.(Healthcheck); ok { @@ -263,7 +263,7 @@ func NewPrefixedChildRegistry(parent Registry, prefix string) Registry { } } -// Call the given function for each registered metric. +// Each call the given function for each registered metric. func (r *PrefixedRegistry) Each(fn func(string, interface{})) { wrappedFn := func(prefix string) func(string, interface{}) { return func(name string, iface interface{}) { @@ -295,7 +295,7 @@ func (r *PrefixedRegistry) Get(name string) interface{} { return r.underlying.Get(realName) } -// Gets an existing metric or registers the given one. +// GetOrRegister gets an existing metric or registers the given one. // The interface can be the metric to register if not found in registry, // or a function returning the metric for lazy instantiation. func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} { @@ -309,7 +309,7 @@ func (r *PrefixedRegistry) Register(name string, metric interface{}) error { return r.underlying.Register(realName, metric) } -// Run all registered healthchecks. +// RunHealthchecks run all registered healthchecks. func (r *PrefixedRegistry) RunHealthchecks() { r.underlying.RunHealthchecks() } @@ -331,7 +331,7 @@ var ( AccountingRegistry = NewRegistry() // registry used in swarm ) -// Call the given function for each registered metric. +// Each call the given function for each registered metric. func Each(f func(string, interface{})) { DefaultRegistry.Each(f) } @@ -341,7 +341,7 @@ func Get(name string) interface{} { return DefaultRegistry.Get(name) } -// Gets an existing metric or creates and registers a new one. Threadsafe +// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe // alternative to calling Get and Register on failure. func GetOrRegister(name string, i interface{}) interface{} { return DefaultRegistry.GetOrRegister(name, i) @@ -353,7 +353,7 @@ func Register(name string, i interface{}) error { return DefaultRegistry.Register(name, i) } -// Register the given metric under the given name. Panics if a metric by the +// MustRegister register the given metric under the given name. Panics if a metric by the // given name is already registered. func MustRegister(name string, i interface{}) { if err := Register(name, i); err != nil { @@ -361,7 +361,7 @@ func MustRegister(name string, i interface{}) { } } -// Run all registered healthchecks. +// RunHealthchecks run all registered healthchecks. func RunHealthchecks() { DefaultRegistry.RunHealthchecks() } diff --git a/metrics/sample.go b/metrics/sample.go index 5398dd42d5..17b2bee28f 100644 --- a/metrics/sample.go +++ b/metrics/sample.go @@ -3,10 +3,9 @@ package metrics import ( "math" "math/rand" + "slices" "sync" "time" - - "golang.org/x/exp/slices" ) const rescaleThreshold = time.Hour @@ -148,13 +147,13 @@ func (NilSample) Clear() {} func (NilSample) Snapshot() SampleSnapshot { return (*emptySnapshot)(nil) } func (NilSample) Update(v int64) {} -// SamplePercentiles returns an arbitrary percentile of the slice of int64. +// SamplePercentile returns an arbitrary percentile of the slice of int64. func SamplePercentile(values []int64, p float64) float64 { return CalculatePercentiles(values, []float64{p})[0] } // CalculatePercentiles returns a slice of arbitrary percentiles of the slice of -// int64. This method returns interpolated results, so e.g if there are only two +// int64. This method returns interpolated results, so e.g. if there are only two // values, [0, 10], a 50% percentile will land between them. // // Note: As a side-effect, this method will also sort the slice of values. diff --git a/metrics/sample_test.go b/metrics/sample_test.go index 7967357055..4227b43ef7 100644 --- a/metrics/sample_test.go +++ b/metrics/sample_test.go @@ -87,13 +87,6 @@ func BenchmarkUniformSample1028(b *testing.B) { benchmarkSample(b, NewUniformSample(1028)) } -func min(a, b int) int { - if a < b { - return a - } - return b -} - func TestExpDecaySample(t *testing.T) { for _, tc := range []struct { reservoirSize int @@ -110,18 +103,18 @@ func TestExpDecaySample(t *testing.T) { } snap := sample.Snapshot() if have, want := int(snap.Count()), tc.updates; have != want { - t.Errorf("have %d want %d", have, want) + t.Errorf("unexpected count: have %d want %d", have, want) } if have, want := snap.Size(), min(tc.updates, tc.reservoirSize); have != want { - t.Errorf("have %d want %d", have, want) + t.Errorf("unexpected size: have %d want %d", have, want) } values := snap.(*sampleSnapshot).values if have, want := len(values), min(tc.updates, tc.reservoirSize); have != want { - t.Errorf("have %d want %d", have, want) + t.Errorf("unexpected values length: have %d want %d", have, want) } for _, v := range values { if v > int64(tc.updates) || v < 0 { - t.Errorf("out of range [0, %d): %v", tc.updates, v) + t.Errorf("out of range [0, %d]: %v", tc.updates, v) } } } @@ -132,12 +125,12 @@ func TestExpDecaySample(t *testing.T) { // The priority becomes +Inf quickly after starting if this is done, // effectively freezing the set of samples until a rescale step happens. func TestExpDecaySampleNanosecondRegression(t *testing.T) { - sw := NewExpDecaySample(100, 0.99) - for i := 0; i < 100; i++ { + sw := NewExpDecaySample(1000, 0.99) + for i := 0; i < 1000; i++ { sw.Update(10) } time.Sleep(1 * time.Millisecond) - for i := 0; i < 100; i++ { + for i := 0; i < 1000; i++ { sw.Update(20) } s := sw.Snapshot() @@ -202,7 +195,7 @@ func TestUniformSample(t *testing.T) { } for _, v := range values { if v > 1000 || v < 0 { - t.Errorf("out of range [0, 100): %v\n", v) + t.Errorf("out of range [0, 1000]: %v\n", v) } } } @@ -258,6 +251,9 @@ func benchmarkSample(b *testing.B, s Sample) { } func testExpDecaySampleStatistics(t *testing.T, s SampleSnapshot) { + if sum := s.Sum(); sum != 496598 { + t.Errorf("s.Sum(): 496598 != %v\n", sum) + } if count := s.Count(); count != 10000 { t.Errorf("s.Count(): 10000 != %v\n", count) } diff --git a/metrics/timer.go b/metrics/timer.go index bb8def82fb..fc2a88f508 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -10,7 +10,7 @@ type TimerSnapshot interface { MeterSnapshot } -// Timers capture the duration and rate of events. +// Timer capture the duration and rate of events. type Timer interface { Snapshot() TimerSnapshot Stop() @@ -99,14 +99,14 @@ func (t *StandardTimer) Stop() { t.meter.Stop() } -// Record the duration of the execution of the given function. +// Time record the duration of the execution of the given function. func (t *StandardTimer) Time(f func()) { ts := time.Now() f() t.Update(time.Since(ts)) } -// Record the duration of an event, in nanoseconds. +// Update the duration of an event, in nanoseconds. func (t *StandardTimer) Update(d time.Duration) { t.mutex.Lock() defer t.mutex.Unlock() @@ -114,7 +114,7 @@ func (t *StandardTimer) Update(d time.Duration) { t.meter.Mark(1) } -// Record the duration of an event that started at a time and ends now. +// UpdateSince update the duration of an event that started at a time and ends now. // The record uses nanoseconds. func (t *StandardTimer) UpdateSince(ts time.Time) { t.Update(time.Since(ts)) diff --git a/metrics/writer.go b/metrics/writer.go index 098da45c27..c211c5046b 100644 --- a/metrics/writer.go +++ b/metrics/writer.go @@ -3,10 +3,9 @@ package metrics import ( "fmt" "io" + "slices" "strings" "time" - - "golang.org/x/exp/slices" ) // Write sorts writes each metric in the given registry periodically to the diff --git a/metrics/writer_test.go b/metrics/writer_test.go index 8376bf8975..edcfe955ab 100644 --- a/metrics/writer_test.go +++ b/metrics/writer_test.go @@ -1,9 +1,8 @@ package metrics import ( + "slices" "testing" - - "golang.org/x/exp/slices" ) func TestMetricsSorting(t *testing.T) { diff --git a/miner/bid_simulator.go b/miner/bid_simulator.go index 498f1ec2b2..ab01f09c05 100644 --- a/miner/bid_simulator.go +++ b/miner/bid_simulator.go @@ -59,7 +59,7 @@ var ( ) type bidWorker interface { - prepareWork(params *generateParams) (*environment, error) + prepareWork(params *generateParams, witness bool) (*environment, error) etherbase() common.Address fillTransactions(interruptCh chan int32, env *environment, stopTimer *time.Timer, bidTxs mapset.Set[common.Hash]) (err error) } @@ -566,7 +566,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { if bidRuntime.env, err = b.bidWorker.prepareWork(&generateParams{ parentHash: bidRuntime.bid.ParentHash, coinbase: b.bidWorker.etherbase(), - }); err != nil { + }, false); err != nil { return } diff --git a/miner/miner.go b/miner/miner.go index ebf53199e9..ebc77a0696 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -54,8 +54,7 @@ type Config struct { Recommit time.Duration // The time interval for miner to re-create mining work. VoteEnable bool // Whether to vote when mining - NewPayloadTimeout time.Duration // The maximum time allowance for creating a new payload - DisableVoteAttestation bool // Whether to skip assembling vote attestation + DisableVoteAttestation bool // Whether to skip assembling vote attestation Mev MevConfig // Mev configuration } @@ -69,14 +68,14 @@ var DefaultConfig = Config{ // consensus-layer usually will wait a half slot of time(6s) // for payload generation. It should be enough for Geth to // run 3 rounds. - Recommit: 3 * time.Second, - NewPayloadTimeout: 2 * time.Second, - DelayLeftOver: 50 * time.Millisecond, + Recommit: 3 * time.Second, + DelayLeftOver: 50 * time.Millisecond, Mev: DefaultMevConfig, } -// Miner creates blocks and searches for proof-of-work values. +// Miner is the main object which takes care of submitting new work to consensus +// engine and gathering the sealing result. type Miner struct { mux *event.TypeMux eth Backend @@ -91,7 +90,7 @@ type Miner struct { wg sync.WaitGroup } -func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(header *types.Header) bool) *Miner { +func New(eth Backend, config *Config, mux *event.TypeMux, engine consensus.Engine) *Miner { miner := &Miner{ mux: mux, eth: eth, @@ -99,10 +98,10 @@ func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *even exitCh: make(chan struct{}), startCh: make(chan struct{}), stopCh: make(chan struct{}), - worker: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock, false), + worker: newWorker(config, eth.BlockChain().Config(), engine, eth, mux, false), } - miner.bidSimulator = newBidSimulator(&config.Mev, config.DelayLeftOver, config.GasPrice, eth, chainConfig, engine, miner.worker) + miner.bidSimulator = newBidSimulator(&config.Mev, config.DelayLeftOver, config.GasPrice, eth, eth.BlockChain().Config(), engine, miner.worker) miner.worker.setBestBidFetcher(miner.bidSimulator) miner.wg.Add(1) @@ -206,13 +205,29 @@ func (miner *Miner) InTurn() bool { return miner.worker.inTurn() } -func (miner *Miner) Hashrate() uint64 { - if pow, ok := miner.engine.(consensus.PoW); ok { - return uint64(pow.Hashrate()) +// Pending returns the currently pending block and associated receipts, logs +// and statedb. The returned values can be nil in case the pending block is +// not initialized. +func (miner *Miner) Pending() (*types.Block, types.Receipts, *state.StateDB) { + if miner.worker.isRunning() { + pendingBlock, pendingReceipts, pendingState := miner.worker.pending() + if pendingState != nil && pendingBlock != nil { + return pendingBlock, pendingReceipts, pendingState + } + } + // fallback to latest block + block := miner.worker.chain.CurrentBlock() + if block == nil { + return nil, nil, nil + } + stateDb, err := miner.worker.chain.StateAt(block.Root) + if err != nil { + return nil, nil, nil } - return 0 + return miner.worker.chain.GetBlockByHash(block.Hash()), miner.worker.chain.GetReceiptsByHash(block.Hash()), stateDb } +// SetExtra sets the content used to initialize the block extra field. func (miner *Miner) SetExtra(extra []byte) error { if uint64(len(extra)) > params.MaximumExtraDataSize { return fmt.Errorf("extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) @@ -231,50 +246,6 @@ func (miner *Miner) SetRecommitInterval(interval time.Duration) { miner.worker.setRecommitInterval(interval) } -// Pending returns the currently pending block and associated state. The returned -// values can be nil in case the pending block is not initialized -func (miner *Miner) Pending() (*types.Block, *state.StateDB) { - if miner.worker.isRunning() { - pendingBlock, pendingState := miner.worker.pending() - if pendingState != nil && pendingBlock != nil { - return pendingBlock, pendingState - } - } - // fallback to latest block - block := miner.worker.chain.CurrentBlock() - if block == nil { - return nil, nil - } - stateDb, err := miner.worker.chain.StateAt(block.Root) - if err != nil { - return nil, nil - } - return miner.worker.chain.GetBlockByHash(block.Hash()), stateDb -} - -// PendingBlock returns the currently pending block. The returned block can be -// nil in case the pending block is not initialized. -// -// Note, to access both the pending block and the pending state -// simultaneously, please use Pending(), as the pending state can -// change between multiple method calls -func (miner *Miner) PendingBlock() *types.Block { - if miner.worker.isRunning() { - pendingBlock := miner.worker.pendingBlock() - if pendingBlock != nil { - return pendingBlock - } - } - // fallback to latest block - return miner.worker.chain.GetBlockByHash(miner.worker.chain.CurrentBlock().Hash()) -} - -// PendingBlockAndReceipts returns the currently pending block and corresponding receipts. -// The returned values can be nil in case the pending block is not initialized. -func (miner *Miner) PendingBlockAndReceipts() (*types.Block, types.Receipts) { - return miner.worker.pendingBlockAndReceipts() -} - func (miner *Miner) SetEtherbase(addr common.Address) { miner.worker.setEtherbase(addr) } @@ -292,8 +263,8 @@ func (miner *Miner) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscript } // BuildPayload builds the payload according to the provided parameters. -func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) { - return miner.worker.buildPayload(args) +func (miner *Miner) BuildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) { + return miner.buildPayload(args, witness) } func (miner *Miner) GasCeil() uint64 { diff --git a/miner/miner_test.go b/miner/miner_test.go index 5907fb4464..ce35f9a648 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -84,7 +84,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { } func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { - return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) + return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil)) } func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { @@ -314,7 +314,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) { if err != nil { t.Fatalf("can't create new chain %v", err) } - statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache(), nil) + statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache()) blockchain := &testBlockChain{bc.Genesis().Root(), chainConfig, statedb, 10000000, new(event.Feed)} pool := legacypool.New(testTxPoolConfig, blockchain) @@ -324,7 +324,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) { // Create event Mux mux := new(event.TypeMux) // Create Miner - miner := New(backend, &config, chainConfig, mux, engine, nil) + miner := New(backend, &config, mux, engine) cleanup := func(skipMiner bool) { bc.Stop() engine.Close() diff --git a/miner/payload_building.go b/miner/payload_building.go index 1ac3cd1c5a..f463000963 100644 --- a/miner/payload_building.go +++ b/miner/payload_building.go @@ -25,6 +25,8 @@ import ( "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -46,7 +48,6 @@ type BuildPayloadArgs struct { // Id computes an 8-byte identifier by hashing the components of the payload arguments. func (args *BuildPayloadArgs) Id() engine.PayloadID { - // Hash hasher := sha256.New() hasher.Write(args.Parent[:]) binary.Write(hasher, binary.BigEndian, args.Timestamp) @@ -68,22 +69,25 @@ func (args *BuildPayloadArgs) Id() engine.PayloadID { // the revenue. Therefore, the empty-block here is always available and full-block // will be set/updated afterwards. type Payload struct { - id engine.PayloadID - empty *types.Block - full *types.Block - sidecars types.BlobSidecars - fullFees *big.Int - stop chan struct{} - lock sync.Mutex - cond *sync.Cond + id engine.PayloadID + empty *types.Block + emptyWitness *stateless.Witness + full *types.Block + fullWitness *stateless.Witness + sidecars types.BlobSidecars + fullFees *big.Int + stop chan struct{} + lock sync.Mutex + cond *sync.Cond } // newPayload initializes the payload object. -func newPayload(empty *types.Block, id engine.PayloadID) *Payload { +func newPayload(empty *types.Block, witness *stateless.Witness, id engine.PayloadID) *Payload { payload := &Payload{ - id: id, - empty: empty, - stop: make(chan struct{}), + id: id, + empty: empty, + emptyWitness: witness, + stop: make(chan struct{}), } log.Info("Starting work on payload", "id", payload.id) payload.cond = sync.NewCond(&payload.lock) @@ -107,6 +111,7 @@ func (payload *Payload) update(r *newPayloadResult, elapsed time.Duration) { payload.full = r.block payload.fullFees = r.fees payload.sidecars = r.sidecars + payload.fullWitness = r.witness feesInEther := new(big.Float).Quo(new(big.Float).SetInt(r.fees), big.NewFloat(params.Ether)) log.Info("Updated payload", @@ -136,9 +141,19 @@ func (payload *Payload) Resolve() *engine.ExecutionPayloadEnvelope { close(payload.stop) } if payload.full != nil { - return engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars) + envelope := engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars) + if payload.fullWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.fullWitness) // cannot fail + } + return envelope + } + envelope := engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil) + if payload.emptyWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.emptyWitness) // cannot fail } - return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil) + return envelope } // ResolveEmpty is basically identical to Resolve, but it expects empty block only. @@ -147,7 +162,12 @@ func (payload *Payload) ResolveEmpty() *engine.ExecutionPayloadEnvelope { payload.lock.Lock() defer payload.lock.Unlock() - return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil) + envelope := engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil) + if payload.emptyWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.emptyWitness) // cannot fail + } + return envelope } // ResolveFull is basically identical to Resolve, but it expects full block only. @@ -173,11 +193,16 @@ func (payload *Payload) ResolveFull() *engine.ExecutionPayloadEnvelope { default: close(payload.stop) } - return engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars) + envelope := engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars) + if payload.fullWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.fullWitness) // cannot fail + } + return envelope } // buildPayload builds the payload according to the provided parameters. -func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) { +func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) { // Build the initial version with no transaction included. It should be fast // enough to run. The empty payload can at least make sure there is something // to deliver for not missing slot. @@ -191,13 +216,12 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) { beaconRoot: args.BeaconRoot, noTxs: true, } - empty := w.getSealingBlock(emptyParams) + empty := miner.worker.getSealingBlock(emptyParams) if empty.err != nil { return nil, empty.err } - // Construct a payload object for return. - payload := newPayload(empty.block, args.Id()) + payload := newPayload(empty.block, empty.witness, args.Id()) // Spin up a routine for updating the payload in background. This strategy // can maximum the revenue for including transactions with highest fee. @@ -227,11 +251,13 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) { select { case <-timer.C: start := time.Now() - r := w.getSealingBlock(fullParams) + r := miner.worker.getSealingBlock(fullParams) if r.err == nil { payload.update(r, time.Since(start)) + } else { + log.Info("Error while generating work", "id", payload.id, "err", r.err) } - timer.Reset(w.recommit) + timer.Reset(miner.worker.recommit) case <-payload.stop: log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") return diff --git a/miner/payload_building_test.go b/miner/payload_building_test.go index 708072b5ec..862e177bfa 100644 --- a/miner/payload_building_test.go +++ b/miner/payload_building_test.go @@ -17,18 +17,135 @@ package miner import ( + "math/big" "reflect" "testing" "time" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/txpool" + "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" ) +var ( + // Test chain configurations + testTxPoolConfig legacypool.Config + ethashChainConfig *params.ChainConfig + cliqueChainConfig *params.ChainConfig + + // Test accounts + testBankKey, _ = crypto.GenerateKey() + testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) + testBankFunds = big.NewInt(1000000000000000000) + + testUserKey, _ = crypto.GenerateKey() + testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey) + + // Test transactions + pendingTxs []*types.Transaction + newTxs []*types.Transaction + + testConfig = Config{ + PendingFeeRecipient: testBankAddress, + Recommit: time.Second, + GasCeil: params.GenesisGasLimit, + } +) + +func init() { + testTxPoolConfig = legacypool.DefaultConfig + testTxPoolConfig.Journal = "" + ethashChainConfig = new(params.ChainConfig) + *ethashChainConfig = *params.TestChainConfig + cliqueChainConfig = new(params.ChainConfig) + *cliqueChainConfig = *params.TestChainConfig + cliqueChainConfig.Clique = ¶ms.CliqueConfig{ + Period: 10, + Epoch: 30000, + } + + signer := types.LatestSigner(params.TestChainConfig) + tx1 := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{ + ChainID: params.TestChainConfig.ChainID, + Nonce: 0, + To: &testUserAddress, + Value: big.NewInt(1000), + Gas: params.TxGas, + GasPrice: big.NewInt(params.InitialBaseFee), + }) + pendingTxs = append(pendingTxs, tx1) + + tx2 := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{ + Nonce: 1, + To: &testUserAddress, + Value: big.NewInt(1000), + Gas: params.TxGas, + GasPrice: big.NewInt(params.InitialBaseFee), + }) + newTxs = append(newTxs, tx2) +} + +// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing. +type testWorkerBackend struct { + db ethdb.Database + txPool *txpool.TxPool + chain *core.BlockChain + genesis *core.Genesis +} + +func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, n int) *testWorkerBackend { + var gspec = &core.Genesis{ + Config: chainConfig, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + } + switch e := engine.(type) { + case *clique.Clique: + gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength) + copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes()) + e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) { + return crypto.Sign(crypto.Keccak256(data), testBankKey) + }) + case *ethash.Ethash: + default: + t.Fatalf("unexpected consensus engine type: %T", engine) + } + chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec, nil, engine, vm.Config{}, nil, nil) + if err != nil { + t.Fatalf("core.NewBlockChain failed: %v", err) + } + pool := legacypool.New(testTxPoolConfig, chain) + txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, chain, []txpool.SubPool{pool}) + + return &testWorkerBackend{ + db: db, + chain: chain, + txPool: txpool, + genesis: gspec, + } +} + +func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain } +func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool } + +func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*Miner, *testWorkerBackend) { + backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks) + backend.txPool.Add(pendingTxs, true, true) + w := New(backend, testConfig, engine) + return w, backend +} + func TestBuildPayload(t *testing.T) { t.Parallel() var ( @@ -45,7 +162,7 @@ func TestBuildPayload(t *testing.T) { Random: common.Hash{}, FeeRecipient: recipient, } - payload, err := w.buildPayload(args) + payload, err := w.buildPayload(args, false) if err != nil { t.Fatalf("Failed to build payload %v", err) } diff --git a/miner/pending.go b/miner/pending.go new file mode 100644 index 0000000000..bb91fe8969 --- /dev/null +++ b/miner/pending.go @@ -0,0 +1,67 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package miner + +import ( + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" +) + +// pendingTTL indicates the period of time a generated pending block should +// exist to serve RPC requests before being discarded if the parent block +// has not changed yet. The value is chosen to align with the recommit interval. +const pendingTTL = 2 * time.Second + +// pending wraps a pending block with additional metadata. +type pending struct { + created time.Time + parentHash common.Hash + result *newPayloadResult + lock sync.Mutex +} + +// resolve retrieves the cached pending result if it's available. Nothing will be +// returned if the parentHash is not matched or the result is already too old. +// +// Note, don't modify the returned payload result. +func (p *pending) resolve(parentHash common.Hash) *newPayloadResult { + p.lock.Lock() + defer p.lock.Unlock() + + if p.result == nil { + return nil + } + if parentHash != p.parentHash { + return nil + } + if time.Since(p.created) > pendingTTL { + return nil + } + return p.result +} + +// update refreshes the cached pending block with newly created one. +func (p *pending) update(parent common.Hash, result *newPayloadResult) { + p.lock.Lock() + defer p.lock.Unlock() + + p.parentHash = parent + p.result = result + p.created = time.Now() +} diff --git a/miner/stress/clique/main.go b/miner/stress/clique/main.go deleted file mode 100644 index 2bebe881b1..0000000000 --- a/miner/stress/clique/main.go +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// This file contains a miner stress test based on the Clique consensus engine. -package main - -import ( - "bytes" - "crypto/ecdsa" - "math/big" - "math/rand" - "os" - "os/signal" - "time" - - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/fdlimit" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/txpool/legacypool" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/eth/downloader" - "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/miner" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/params" -) - -func main() { - log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) - fdlimit.Raise(2048) - - // Generate a batch of accounts to seal and fund with - faucets := make([]*ecdsa.PrivateKey, 128) - for i := 0; i < len(faucets); i++ { - faucets[i], _ = crypto.GenerateKey() - } - sealers := make([]*ecdsa.PrivateKey, 4) - for i := 0; i < len(sealers); i++ { - sealers[i], _ = crypto.GenerateKey() - } - // Create a Clique network based off of the Sepolia config - genesis := makeGenesis(faucets, sealers) - - // Handle interrupts. - interruptCh := make(chan os.Signal, 5) - signal.Notify(interruptCh, os.Interrupt) - - var ( - stacks []*node.Node - nodes []*eth.Ethereum - enodes []*enode.Node - ) - for _, sealer := range sealers { - // Start the node and wait until it's up - stack, ethBackend, err := makeSealer(genesis) - if err != nil { - panic(err) - } - defer stack.Close() - - for stack.Server().NodeInfo().Ports.Listener == 0 { - time.Sleep(250 * time.Millisecond) - } - // Connect the node to all the previous ones - for _, n := range enodes { - stack.Server().AddPeer(n) - } - // Start tracking the node and its enode - stacks = append(stacks, stack) - nodes = append(nodes, ethBackend) - enodes = append(enodes, stack.Server().Self()) - - // Inject the signer key and start sealing with it - ks := keystore.NewKeyStore(stack.KeyStoreDir(), keystore.LightScryptN, keystore.LightScryptP) - signer, err := ks.ImportECDSA(sealer, "") - if err != nil { - panic(err) - } - if err := ks.Unlock(signer, ""); err != nil { - panic(err) - } - stack.AccountManager().AddBackend(ks) - } - - // Iterate over all the nodes and start signing on them - time.Sleep(3 * time.Second) - for _, node := range nodes { - if err := node.StartMining(); err != nil { - panic(err) - } - } - time.Sleep(3 * time.Second) - - // Start injecting transactions from the faucet like crazy - nonces := make([]uint64, len(faucets)) - for { - // Stop when interrupted. - select { - case <-interruptCh: - for _, node := range stacks { - node.Close() - } - return - default: - } - - // Pick a random signer node - index := rand.Intn(len(faucets)) - backend := nodes[index%len(nodes)] - - // Create a self transaction and inject into the pool - tx, err := types.SignTx(types.NewTransaction(nonces[index], crypto.PubkeyToAddress(faucets[index].PublicKey), new(big.Int), 21000, big.NewInt(100000000000), nil), types.HomesteadSigner{}, faucets[index]) - if err != nil { - panic(err) - } - if err := backend.TxPool().Add([]*types.Transaction{tx}, true, false); err != nil { - panic(err) - } - nonces[index]++ - - // Wait if we're too saturated - if pend, _ := backend.TxPool().Stats(); pend > 2048 { - time.Sleep(100 * time.Millisecond) - } - } -} - -// makeGenesis creates a custom Clique genesis block based on some pre-defined -// signer and faucet accounts. -func makeGenesis(faucets []*ecdsa.PrivateKey, sealers []*ecdsa.PrivateKey) *core.Genesis { - // Create a Clique network based off of the Rinkeby config - genesis := core.DefaultGenesisBlock() - genesis.GasLimit = 25000000 - - genesis.Config.ChainID = big.NewInt(18) - genesis.Config.Clique.Period = 1 - - genesis.Alloc = types.GenesisAlloc{} - for _, faucet := range faucets { - genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = types.Account{ - Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil), - } - } - // Sort the signers and embed into the extra-data section - signers := make([]common.Address, len(sealers)) - for i, sealer := range sealers { - signers[i] = crypto.PubkeyToAddress(sealer.PublicKey) - } - for i := 0; i < len(signers); i++ { - for j := i + 1; j < len(signers); j++ { - if bytes.Compare(signers[i][:], signers[j][:]) > 0 { - signers[i], signers[j] = signers[j], signers[i] - } - } - } - genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) - for i, signer := range signers { - copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) - } - // Return the genesis block for initialization - return genesis -} - -func makeSealer(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) { - // Define the basic configurations for the Ethereum node - datadir, _ := os.MkdirTemp("", "") - config := &node.Config{ - Name: "geth", - Version: params.Version, - DataDir: datadir, - P2P: p2p.Config{ - ListenAddr: "0.0.0.0:0", - NoDiscovery: true, - MaxPeers: 25, - }, - } - // Start the node and configure a full Ethereum node on it - stack, err := node.New(config) - if err != nil { - return nil, nil, err - } - // Create and register the backend - ethBackend, err := eth.New(stack, ðconfig.Config{ - Genesis: genesis, - NetworkId: genesis.Config.ChainID.Uint64(), - SyncMode: downloader.FullSync, - DatabaseCache: 256, - DatabaseHandles: 256, - TxPool: legacypool.DefaultConfig, - GPO: ethconfig.Defaults.GPO, - Miner: miner.Config{ - GasCeil: genesis.GasLimit * 11 / 10, - GasPrice: big.NewInt(1), - Recommit: time.Second, - }, - }) - if err != nil { - return nil, nil, err - } - - err = stack.Start() - return stack, ethBackend, err -} diff --git a/miner/worker.go b/miner/worker.go index 135dc45327..bd0b559a24 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/parlia" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/systemcontracts" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" @@ -104,6 +105,8 @@ type environment struct { receipts []*types.Receipt sidecars types.BlobSidecars blobs int + + witness *stateless.Witness } // copy creates a deep copy of environment. @@ -172,6 +175,9 @@ type newPayloadResult struct { block *types.Block fees *big.Int // total block fees sidecars types.BlobSidecars // collected blobs of blob transactions + stateDB *state.StateDB // StateDB after executing the transactions + receipts []*types.Receipt // Receipts collected during construction + witness *stateless.Witness // Witness is an optional stateless proof } // getWorkReq represents a request for getting a new sealing work with provided parameters. @@ -234,20 +240,10 @@ type worker struct { running atomic.Bool // The indicator whether the consensus engine is running or not. syncing atomic.Bool // The indicator whether the node is still syncing. - // newpayloadTimeout is the maximum timeout allowance for creating payload. - // The default value is 2 seconds but node operator can set it to arbitrary - // large value. A large timeout allowance may cause Geth to fail creating - // a non-empty payload within the specified time and eventually miss the slot - // in case there are some computation expensive transactions in txpool. - newpayloadTimeout time.Duration - // recommit is the time interval to re-create sealing work or to re-build // payload in proof-of-stake stage. recommit time.Duration - // External functions - isLocalBlock func(header *types.Header) bool // Function used to determine whether the specified block is mined by local miner. - // Test hooks newTaskHook func(*task) // Method to call upon receiving a new sealing task. skipSealHook func(*task) bool // Method to decide whether skipping the sealing. @@ -256,17 +252,16 @@ type worker struct { recentMinedBlocks *lru.Cache } -func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(header *types.Header) bool, init bool) *worker { +func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, init bool) *worker { recentMinedBlocks, _ := lru.New(recentMinedCacheLimit) worker := &worker{ - prefetcher: core.NewStatePrefetcher(chainConfig, eth.BlockChain(), engine), + prefetcher: core.NewStatePrefetcher(chainConfig, eth.BlockChain().HeadChain()), config: config, chainConfig: chainConfig, engine: engine, eth: eth, chain: eth.BlockChain(), mux: mux, - isLocalBlock: isLocalBlock, coinbase: config.Etherbase, extra: config.ExtraData, tip: uint256.MustFromBig(config.GasPrice), @@ -292,17 +287,6 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus } worker.recommit = recommit - // Sanitize the timeout config for creating payload. - newpayloadTimeout := worker.config.NewPayloadTimeout - if newpayloadTimeout == 0 { - // log.Warn("Sanitizing new payload timeout to default", "provided", newpayloadTimeout, "updated", DefaultConfig.NewPayloadTimeout) - newpayloadTimeout = DefaultConfig.NewPayloadTimeout - } - if newpayloadTimeout < time.Millisecond*100 { - log.Warn("Low payload timeout may cause high amount of non-full blocks", "provided", newpayloadTimeout, "default", DefaultConfig.NewPayloadTimeout) - } - worker.newpayloadTimeout = newpayloadTimeout - worker.wg.Add(4) go worker.mainLoop() go worker.newWorkLoop(recommit) @@ -369,31 +353,15 @@ func (w *worker) setRecommitInterval(interval time.Duration) { } } -// pending returns the pending state and corresponding block. The returned -// values can be nil in case the pending block is not initialized. -func (w *worker) pending() (*types.Block, *state.StateDB) { +// Pending returns the currently pending block, associated receipts and statedb. +// The returned values can be nil in case the pending block is not initialized. +func (w *worker) pending() (*types.Block, types.Receipts, *state.StateDB) { w.snapshotMu.RLock() defer w.snapshotMu.RUnlock() if w.snapshotState == nil { - return nil, nil + return nil, nil, nil } - return w.snapshotBlock, w.snapshotState.Copy() -} - -// pendingBlock returns pending block. The returned block can be nil in case the -// pending block is not initialized. -func (w *worker) pendingBlock() *types.Block { - w.snapshotMu.RLock() - defer w.snapshotMu.RUnlock() - return w.snapshotBlock -} - -// pendingBlockAndReceipts returns pending block and corresponding receipts. -// The returned values can be nil in case the pending block is not initialized. -func (w *worker) pendingBlockAndReceipts() (*types.Block, types.Receipts) { - w.snapshotMu.RLock() - defer w.snapshotMu.RUnlock() - return w.snapshotBlock, w.snapshotReceipts + return w.snapshotBlock, w.snapshotReceipts, w.snapshotState.Copy() } // start sets the running status as 1 and triggers new work submitting. @@ -531,7 +499,7 @@ func (w *worker) mainLoop() { w.commitWork(req.interruptCh, req.timestamp) case req := <-w.getWorkCh: - req.result <- w.generateWork(req.params) + req.result <- w.generateWork(req.params, false) // System stopped case <-w.exitCh: @@ -695,15 +663,22 @@ func (w *worker) resultLoop() { // makeEnv creates a new environment for the sealing block. func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address, - prevEnv *environment) (*environment, error) { + prevEnv *environment, witness bool) (*environment, error) { // Retrieve the parent state to execute on top and start a prefetcher for // the miner to speed block sealing up a bit state, err := w.chain.StateAt(parent.Root) if err != nil { return nil, err } + if witness { + bundle, err := stateless.NewWitness(header, w.chain) + if err != nil { + return nil, err + } + state.StartPrefetcher("miner", bundle) + } if prevEnv == nil { - state.StartPrefetcher("miner") + state.StartPrefetcher("miner", nil) } else { state.TransferPrefetcher(prevEnv.state) } @@ -714,6 +689,7 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co state: state, coinbase: coinbase, header: header, + witness: state.Witness(), } // Keep track of transactions which return errors so they can be removed env.tcount = 0 @@ -727,8 +703,7 @@ func (w *worker) updateSnapshot(env *environment) { w.snapshotBlock = types.NewBlock( env.header, - env.txs, - nil, + &types.Body{Transactions: env.txs}, env.receipts, trie.NewStackTrie(nil), ) @@ -783,7 +758,7 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, recei gp = env.gasPool.Gas() ) - receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, *w.chain.GetVMConfig(), receiptProcessors...) + receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, vm.Config{}, receiptProcessors...) if err != nil { env.state.RevertToSnapshot(snap) env.gasPool.SetGas(gp) @@ -911,7 +886,7 @@ LOOP: continue } // Error may be ignored here. The error has already been checked - // during transaction acceptance is the transaction pool. + // during transaction acceptance in the transaction pool. from, _ := types.Sender(env.signer, tx) // Check whether the tx is replay protected. If we're not in the EIP155 hf @@ -980,7 +955,7 @@ type generateParams struct { // prepareWork constructs the sealing task according to the given parameters, // either based on the last chain head or specified parent. In this function // the pending transactions are not filled yet, only the empty task returned. -func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { +func (w *worker) prepareWork(genParams *generateParams, witness bool) (*environment, error) { w.mu.RLock() defer w.mu.RUnlock() @@ -1055,7 +1030,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // Could potentially happen if starting to mine in an odd state. // Note genParams.coinbase can be different with header.Coinbase // since clique algorithm can modify the coinbase field in header. - env, err := w.makeEnv(parent, header, genParams.coinbase, genParams.prevWork) + env, err := w.makeEnv(parent, header, genParams.coinbase, genParams.prevWork, witness) if err != nil { log.Error("Failed to create sealing context", "err", err) return nil, err @@ -1072,6 +1047,12 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) } + if w.chainConfig.IsPrague(header.Number, header.Time) { + context := core.NewEVMBlockContext(header, w.chain, nil) + vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{}) + core.ProcessParentBlockHash(header.ParentHash, vmenv, env.state) + } + env.size = uint32(env.header.Size()) return env, nil @@ -1164,8 +1145,8 @@ func (w *worker) fillTransactions(interruptCh chan int32, env *environment, stop } // generateWork generates a sealing block based on the given parameters. -func (w *worker) generateWork(params *generateParams) *newPayloadResult { - work, err := w.prepareWork(params) +func (w *worker) generateWork(params *generateParams, witness bool) *newPayloadResult { + work, err := w.prepareWork(params, witness) if err != nil { return &newPayloadResult{err: err} } @@ -1174,7 +1155,7 @@ func (w *worker) generateWork(params *generateParams) *newPayloadResult { if !params.noTxs { err := w.fillTransactions(nil, work, nil, nil) if errors.Is(err, errBlockInterruptedByTimeout) { - log.Warn("Block building is interrupted", "allowance", common.PrettyDuration(w.newpayloadTimeout)) + log.Warn("Block building is interrupted", "allowance", common.PrettyDuration(w.recommit)) } } fees := work.state.GetBalance(consensus.SystemAddress) @@ -1187,6 +1168,7 @@ func (w *worker) generateWork(params *generateParams) *newPayloadResult { block: block, fees: fees.ToBig(), sidecars: work.sidecars, + witness: work.witness, } } @@ -1238,7 +1220,7 @@ LOOP: timestamp: uint64(timestamp), coinbase: coinbase, prevWork: prevWork, - }) + }, false) if err != nil { return } diff --git a/miner/worker_test.go b/miner/worker_test.go index 268f3f69a5..86128fb50a 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -161,7 +161,7 @@ func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction { func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*worker, *testWorkerBackend) { backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks) backend.txPool.Add(pendingTxs, true, false) - w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), nil, false) + w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), false) w.setEtherbase(testBankAddress) return w, backend } diff --git a/node/api.go b/node/api.go index f11ab722d6..c11e2b97cd 100644 --- a/node/api.go +++ b/node/api.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/rpc" ) @@ -40,6 +41,9 @@ func (n *Node) apis() []rpc.API { }, { Namespace: "debug", Service: debug.Handler, + }, { + Namespace: "debug", + Service: &p2pDebugAPI{n}, }, { Namespace: "web3", Service: &web3API{n}, @@ -146,8 +150,6 @@ func (api *adminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) return case <-rpcSub.Err(): return - case <-notifier.Closed(): - return } } }) @@ -336,3 +338,16 @@ func (s *web3API) ClientVersion() string { func (s *web3API) Sha3(input hexutil.Bytes) hexutil.Bytes { return crypto.Keccak256(input) } + +// p2pDebugAPI provides access to p2p internals for debugging. +type p2pDebugAPI struct { + stack *Node +} + +func (s *p2pDebugAPI) DiscoveryV4Table() [][]discover.BucketNode { + disc := s.stack.server.DiscoveryV4() + if disc != nil { + return disc.TableBuckets() + } + return nil +} diff --git a/node/node.go b/node/node.go index 069269de0c..88674d6d82 100644 --- a/node/node.go +++ b/node/node.go @@ -26,6 +26,7 @@ import ( "path" "path/filepath" "reflect" + "slices" "strings" "sync" @@ -36,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/leveldb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" @@ -325,16 +327,6 @@ func (n *Node) openEndpoints() error { return err } -// containsLifecycle checks if 'lfs' contains 'l'. -func containsLifecycle(lfs []Lifecycle, l Lifecycle) bool { - for _, obj := range lfs { - if obj == l { - return true - } - } - return false -} - // stopServices terminates running services, RPC and p2p networking. // It is the inverse of Start. func (n *Node) stopServices(running []Lifecycle) error { @@ -386,15 +378,9 @@ func (n *Node) closeDataDir() { } } -// obtainJWTSecret loads the jwt-secret, either from the provided config, -// or from the default location. If neither of those are present, it generates -// a new secret and stores to the default location. -func (n *Node) obtainJWTSecret(cliParam string) ([]byte, error) { - fileName := cliParam - if len(fileName) == 0 { - // no path provided, use default - fileName = n.ResolvePath(datadirJWTKey) - } +// ObtainJWTSecret loads the jwt-secret from the provided config. If the file is not +// present, it generates a new secret and stores to the given location. +func ObtainJWTSecret(fileName string) ([]byte, error) { // try reading from file if data, err := os.ReadFile(fileName); err == nil { jwtSecret := common.FromHex(strings.TrimSpace(string(data))) @@ -420,6 +406,18 @@ func (n *Node) obtainJWTSecret(cliParam string) ([]byte, error) { return jwtSecret, nil } +// obtainJWTSecret loads the jwt-secret, either from the provided config, +// or from the default location. If neither of those are present, it generates +// a new secret and stores to the default location. +func (n *Node) obtainJWTSecret(cliParam string) ([]byte, error) { + fileName := cliParam + if len(fileName) == 0 { + // no path provided, use default + fileName = n.ResolvePath(datadirJWTKey) + } + return ObtainJWTSecret(fileName) +} + // startRPC is a helper method to configure all the various RPC endpoints during node // startup. It's not meant to be called at any time afterwards as it makes certain // assumptions about the state of the node. @@ -612,7 +610,7 @@ func (n *Node) RegisterLifecycle(lifecycle Lifecycle) { if n.state != initializingState { panic("can't register lifecycle on running/stopped node") } - if containsLifecycle(n.lifecycles, lifecycle) { + if slices.Contains(n.lifecycles, lifecycle) { panic(fmt.Sprintf("attempt to register lifecycle %T more than once", lifecycle)) } n.lifecycles = append(n.lifecycles, lifecycle) @@ -871,7 +869,7 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient, var db ethdb.Database var err error if n.config.DataDir == "" { - db = rawdb.NewMemoryDatabase() + db, err = rawdb.NewDatabaseWithFreezer(memorydb.New(), "", namespace, readonly, false, false, false, false) } else { db, err = rawdb.Open(rawdb.OpenOptions{ Type: n.config.DBEngine, diff --git a/node/node_auth_test.go b/node/node_auth_test.go index 597cd8531f..900f53440c 100644 --- a/node/node_auth_test.go +++ b/node/node_auth_test.go @@ -22,7 +22,7 @@ import ( "fmt" "net/http" "os" - "path" + "path/filepath" "testing" "time" @@ -98,7 +98,7 @@ func TestAuthEndpoints(t *testing.T) { t.Fatalf("failed to create jwt secret: %v", err) } // Geth must read it from a file, and does not support in-memory JWT secrets, so we create a temporary file. - jwtPath := path.Join(t.TempDir(), "jwt_secret") + jwtPath := filepath.Join(t.TempDir(), "jwt_secret") if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil { t.Fatalf("failed to prepare jwt secret file: %v", err) } diff --git a/node/node_test.go b/node/node_test.go index 04810a815b..82e814cada 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -23,6 +23,7 @@ import ( "net" "net/http" "reflect" + "slices" "strings" "testing" @@ -116,7 +117,7 @@ func TestLifecycleRegistry_Successful(t *testing.T) { noop := NewNoop() stack.RegisterLifecycle(noop) - if !containsLifecycle(stack.lifecycles, noop) { + if !slices.Contains(stack.lifecycles, Lifecycle(noop)) { t.Fatalf("lifecycle was not properly registered on the node, %v", err) } } @@ -415,21 +416,6 @@ func TestRegisterHandler_Successful(t *testing.T) { assert.Equal(t, "success", string(buf)) } -// Tests that the given handler will not be successfully mounted since no HTTP server -// is enabled for RPC -func TestRegisterHandler_Unsuccessful(t *testing.T) { - node, err := New(&DefaultConfig) - if err != nil { - t.Fatalf("could not create new node: %v", err) - } - - // create and mount handler - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("success")) - }) - node.RegisterHandler("test", "/test", handler) -} - // Tests whether websocket requests can be handled on the same port as a regular http server. func TestWebsocketHTTPOnSamePort_WebsocketRequest(t *testing.T) { node := startHTTP(t, 0, 0) diff --git a/node/rpcstack.go b/node/rpcstack.go index 1790e051a0..6d3828ec2b 100644 --- a/node/rpcstack.go +++ b/node/rpcstack.go @@ -336,7 +336,7 @@ func (h *httpServer) enableWS(apis []rpc.API, config wsConfig) error { defer h.mu.Unlock() if h.wsAllowed() { - return fmt.Errorf("JSON-RPC over WebSocket is already enabled") + return errors.New("JSON-RPC over WebSocket is already enabled") } // Create RPC server and handler. srv := rpc.NewServer() @@ -597,7 +597,7 @@ func newIPCServer(log log.Logger, endpoint string) *ipcServer { return &ipcServer{log: log, endpoint: endpoint} } -// Start starts the httpServer's http.Server +// start starts the httpServer's http.Server func (is *ipcServer) start(apis []rpc.API) error { is.mu.Lock() defer is.mu.Unlock() diff --git a/node/rpcstack_test.go b/node/rpcstack_test.go index e41cc51ad3..c6f598b774 100644 --- a/node/rpcstack_test.go +++ b/node/rpcstack_test.go @@ -383,7 +383,7 @@ func TestJWT(t *testing.T) { expFail := []func() string{ // future func() string { - return fmt.Sprintf("Bearer %v", issueToken(secret, nil, testClaim{"iat": time.Now().Unix() + int64(jwtExpiryTimeout.Seconds()) + 1})) + return fmt.Sprintf("Bearer %v", issueToken(secret, nil, testClaim{"iat": time.Now().Unix() + int64(jwtExpiryTimeout.Seconds()) + 60})) }, // stale func() string { diff --git a/oss-fuzz.sh b/oss-fuzz.sh index 8978de70dd..7993dc9c64 100644 --- a/oss-fuzz.sh +++ b/oss-fuzz.sh @@ -208,6 +208,14 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ FuzzCrossPairing fuzz_cross_pairing\ $repo/tests/fuzzers/bls12381/bls12381_test.go +compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ + FuzzG1SubgroupChecks fuzz_g1_subgroup_checks\ + $repo/tests/fuzzers/bls12381/bls12381_test.go + +compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \ + FuzzG2SubgroupChecks fuzz_g2_subgroup_checks\ + $repo/tests/fuzzers/bls12381/bls12381_test.go + compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/secp256k1 \ Fuzz fuzzSecp256k1\ $repo/tests/fuzzers/secp256k1/secp_test.go diff --git a/p2p/dial.go b/p2p/dial.go index 9c3f1cd4d9..be8e153b80 100644 --- a/p2p/dial.go +++ b/p2p/dial.go @@ -25,6 +25,7 @@ import ( mrand "math/rand" "net" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common/gopool" @@ -65,11 +66,8 @@ type tcpDialer struct { } func (t tcpDialer) Dial(ctx context.Context, dest *enode.Node) (net.Conn, error) { - return t.d.DialContext(ctx, "tcp", nodeAddr(dest).String()) -} - -func nodeAddr(n *enode.Node) net.Addr { - return &net.TCPAddr{IP: n.IP(), Port: n.TCP()} + addr, _ := dest.TCPEndpoint() + return t.d.DialContext(ctx, "tcp", addr.String()) } // checkDial errors: @@ -248,13 +246,13 @@ loop: select { case node := <-nodesCh: if err := d.checkDial(node); err != nil { - d.log.Trace("Discarding dial candidate", "id", node.ID(), "ip", node.IP(), "reason", err) + d.log.Trace("Discarding dial candidate", "id", node.ID(), "ip", node.IPAddr(), "reason", err) } else { d.startDial(newDialTask(node, dynDialedConn)) } case task := <-d.doneCh: - id := task.dest.ID() + id := task.dest().ID() delete(d.dialing, id) d.updateStaticPool(id) d.doneSinceLastLog++ @@ -282,7 +280,7 @@ loop: case node := <-d.addStaticCh: id := node.ID() _, exists := d.static[id] - d.log.Trace("Adding static node", "id", id, "ip", node.IP(), "added", !exists) + d.log.Trace("Adding static node", "id", id, "ip", node.IPAddr(), "added", !exists) if exists { continue loop } @@ -381,7 +379,7 @@ func (d *dialScheduler) checkDial(n *enode.Node) error { if n.ID() == d.self { return errSelf } - if n.IP() != nil && n.TCP() == 0 { + if n.IPAddr().IsValid() && n.TCP() == 0 { // This check can trigger if a non-TCP node is found // by discovery. If there is no IP, the node is a static // node and the actual endpoint will be resolved later in dialTask. @@ -393,7 +391,7 @@ func (d *dialScheduler) checkDial(n *enode.Node) error { if _, ok := d.peers[n.ID()]; ok { return errAlreadyConnected } - if d.netRestrict != nil && !d.netRestrict.Contains(n.IP()) { + if d.netRestrict != nil && !d.netRestrict.ContainsAddr(n.IPAddr()) { return errNetRestrict } if d.history.contains(string(n.ID().Bytes())) { @@ -416,7 +414,7 @@ func (d *dialScheduler) startStaticDials(n int) (started int) { // updateStaticPool attempts to move the given static dial back into staticPool. func (d *dialScheduler) updateStaticPool(id enode.ID) { task, ok := d.static[id] - if ok && task.staticPoolIndex < 0 && d.checkDial(task.dest) == nil { + if ok && task.staticPoolIndex < 0 && d.checkDial(task.dest()) == nil { d.addToStaticPool(task) } } @@ -443,10 +441,11 @@ func (d *dialScheduler) removeFromStaticPool(idx int) { // startDial runs the given dial task in a separate goroutine. func (d *dialScheduler) startDial(task *dialTask) { - d.log.Trace("Starting p2p dial", "id", task.dest.ID(), "ip", task.dest.IP(), "flag", task.flags) - hkey := string(task.dest.ID().Bytes()) + node := task.dest() + d.log.Trace("Starting p2p dial", "id", node.ID(), "ip", node.IPAddr(), "flag", task.flags) + hkey := string(node.ID().Bytes()) d.history.add(hkey, d.clock.Now().Add(dialHistoryExpiration)) - d.dialing[task.dest.ID()] = task + d.dialing[node.ID()] = task gopool.Submit(func() { task.run(d) d.doneCh <- task @@ -457,39 +456,46 @@ func (d *dialScheduler) startDial(task *dialTask) { type dialTask struct { staticPoolIndex int flags connFlag + // These fields are private to the task and should not be // accessed by dialScheduler while the task is running. - dest *enode.Node + destPtr atomic.Pointer[enode.Node] lastResolved mclock.AbsTime resolveDelay time.Duration } func newDialTask(dest *enode.Node, flags connFlag) *dialTask { - return &dialTask{dest: dest, flags: flags, staticPoolIndex: -1} + t := &dialTask{flags: flags, staticPoolIndex: -1} + t.destPtr.Store(dest) + return t } type dialError struct { error } +func (t *dialTask) dest() *enode.Node { + return t.destPtr.Load() +} + func (t *dialTask) run(d *dialScheduler) { if t.needResolve() && !t.resolve(d) { return } - err := t.dial(d, t.dest) + err := t.dial(d, t.dest()) if err != nil { // For static nodes, resolve one more time if dialing fails. if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 { if t.resolve(d) { - t.dial(d, t.dest) + t.dial(d, t.dest()) } } } } func (t *dialTask) needResolve() bool { - return t.flags&staticDialedConn != 0 && t.dest.IP() == nil + return t.flags&staticDialedConn != 0 && !t.dest().IPAddr().IsValid() } // resolve attempts to find the current endpoint for the destination @@ -508,29 +514,33 @@ func (t *dialTask) resolve(d *dialScheduler) bool { if t.lastResolved > 0 && time.Duration(d.clock.Now()-t.lastResolved) < t.resolveDelay { return false } - resolved := d.resolver.Resolve(t.dest) + + node := t.dest() + resolved := d.resolver.Resolve(node) t.lastResolved = d.clock.Now() if resolved == nil { t.resolveDelay *= 2 if t.resolveDelay > maxResolveDelay { t.resolveDelay = maxResolveDelay } - d.log.Debug("Resolving node failed", "id", t.dest.ID(), "newdelay", t.resolveDelay) + d.log.Debug("Resolving node failed", "id", node.ID(), "newdelay", t.resolveDelay) return false } // The node was found. t.resolveDelay = initialResolveDelay - t.dest = resolved - d.log.Debug("Resolved node", "id", t.dest.ID(), "addr", &net.TCPAddr{IP: t.dest.IP(), Port: t.dest.TCP()}) + t.destPtr.Store(resolved) + resAddr, _ := resolved.TCPEndpoint() + d.log.Debug("Resolved node", "id", resolved.ID(), "addr", resAddr) return true } // dial performs the actual connection attempt. func (t *dialTask) dial(d *dialScheduler, dest *enode.Node) error { dialMeter.Mark(1) - fd, err := d.dialer.Dial(d.ctx, t.dest) + fd, err := d.dialer.Dial(d.ctx, dest) if err != nil { - d.log.Trace("Dial error", "id", t.dest.ID(), "addr", nodeAddr(t.dest), "conn", t.flags, "err", cleanupDialErr(err)) + addr, _ := dest.TCPEndpoint() + d.log.Trace("Dial error", "id", dest.ID(), "addr", addr, "conn", t.flags, "err", cleanupDialErr(err)) dialConnectionError.Mark(1) return &dialError{err} } @@ -538,8 +548,9 @@ func (t *dialTask) dial(d *dialScheduler, dest *enode.Node) error { } func (t *dialTask) String() string { - id := t.dest.ID() - return fmt.Sprintf("%v %x %v:%d", t.flags, id[:8], t.dest.IP(), t.dest.TCP()) + node := t.dest() + id := node.ID() + return fmt.Sprintf("%v %x %v:%d", t.flags, id[:8], node.IPAddr(), node.TCP()) } func cleanupDialErr(err error) error { diff --git a/p2p/discover/common.go b/p2p/discover/common.go index d09479269c..371e1b0c10 100644 --- a/p2p/discover/common.go +++ b/p2p/discover/common.go @@ -18,8 +18,13 @@ package discover import ( "crypto/ecdsa" + crand "crypto/rand" + "encoding/binary" "fmt" + "math/rand" "net" + "net/netip" + "sync" "time" "github.com/ethereum/go-ethereum/common/mclock" @@ -35,8 +40,8 @@ import ( // UDPConn is a network connection on which discovery can operate. type UDPConn interface { - ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) - WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error) + ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) + WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (n int, err error) Close() error LocalAddr() net.Addr } @@ -79,9 +84,10 @@ type Config struct { Unhandled chan<- ReadPacket // unhandled packets are sent on this channel // Node table configuration: - Bootnodes []*enode.Node // list of bootstrap nodes - PingInterval time.Duration // speed of node liveness check - RefreshInterval time.Duration // used in bucket refresh + Bootnodes []*enode.Node // list of bootstrap nodes + PingInterval time.Duration // speed of node liveness check + RefreshInterval time.Duration // used in bucket refresh + NoFindnodeLivenessCheck bool // turns off validation of table nodes in FINDNODE handler // The options below are useful in very specific cases, like in unit tests. V5ProtocolID *[6]byte @@ -96,7 +102,7 @@ type Config struct { func (cfg Config) withDefaults() Config { // Node table configuration: if cfg.PingInterval == 0 { - cfg.PingInterval = 10 * time.Second + cfg.PingInterval = 3 * time.Second } if cfg.RefreshInterval == 0 { cfg.RefreshInterval = 30 * time.Minute @@ -124,12 +130,46 @@ func ListenUDP(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { // channel if configured. type ReadPacket struct { Data []byte - Addr *net.UDPAddr + Addr netip.AddrPort } -func min(x, y int) int { - if x > y { - return y - } - return x +type randomSource interface { + Intn(int) int + Int63n(int64) int64 + Shuffle(int, func(int, int)) +} + +// reseedingRandom is a random number generator that tracks when it was last re-seeded. +type reseedingRandom struct { + mu sync.Mutex + cur *rand.Rand +} + +func (r *reseedingRandom) seed() { + var b [8]byte + crand.Read(b[:]) + seed := binary.BigEndian.Uint64(b[:]) + new := rand.New(rand.NewSource(int64(seed))) + + r.mu.Lock() + r.cur = new + r.mu.Unlock() +} + +func (r *reseedingRandom) Intn(n int) int { + r.mu.Lock() + defer r.mu.Unlock() + return r.cur.Intn(n) +} + +func (r *reseedingRandom) Int63n(n int64) int64 { + r.mu.Lock() + defer r.mu.Unlock() + return r.cur.Int63n(n) +} + +func (r *reseedingRandom) Shuffle(n int, swap func(i, j int)) { + r.mu.Lock() + defer r.mu.Unlock() + r.cur.Shuffle(n, swap) } diff --git a/p2p/discover/lookup.go b/p2p/discover/lookup.go index 4aa3e8889c..9f024ed96f 100644 --- a/p2p/discover/lookup.go +++ b/p2p/discover/lookup.go @@ -30,16 +30,16 @@ import ( // not need to be an actual node identifier. type lookup struct { tab *Table - queryfunc func(*node) ([]*node, error) - replyCh chan []*node + queryfunc queryFunc + replyCh chan []*enode.Node cancelCh <-chan struct{} asked, seen map[enode.ID]bool result nodesByDistance - replyBuffer []*node + replyBuffer []*enode.Node queries int } -type queryFunc func(*node) ([]*node, error) +type queryFunc func(*enode.Node) ([]*enode.Node, error) func newLookup(ctx context.Context, tab *Table, target enode.ID, q queryFunc) *lookup { it := &lookup{ @@ -48,7 +48,7 @@ func newLookup(ctx context.Context, tab *Table, target enode.ID, q queryFunc) *l asked: make(map[enode.ID]bool), seen: make(map[enode.ID]bool), result: nodesByDistance{target: target}, - replyCh: make(chan []*node, alpha), + replyCh: make(chan []*enode.Node, alpha), cancelCh: ctx.Done(), queries: -1, } @@ -62,7 +62,7 @@ func newLookup(ctx context.Context, tab *Table, target enode.ID, q queryFunc) *l func (it *lookup) run() []*enode.Node { for it.advance() { } - return unwrapNodes(it.result.entries) + return it.result.entries } // advance advances the lookup until any new nodes have been found. @@ -142,33 +142,14 @@ func (it *lookup) slowdown() { } } -func (it *lookup) query(n *node, reply chan<- []*node) { - fails := it.tab.db.FindFails(n.ID(), n.IP()) +func (it *lookup) query(n *enode.Node, reply chan<- []*enode.Node) { r, err := it.queryfunc(n) - if errors.Is(err, errClosed) { - // Avoid recording failures on shutdown. - reply <- nil - return - } else if len(r) == 0 { - fails++ - it.tab.db.UpdateFindFails(n.ID(), n.IP(), fails) - // Remove the node from the local table if it fails to return anything useful too - // many times, but only if there are enough other nodes in the bucket. - dropped := false - if fails >= maxFindnodeFailures && it.tab.bucketLen(n.ID()) >= bucketSize/2 { - dropped = true - it.tab.delete(n) + if !errors.Is(err, errClosed) { // avoid recording failures on shutdown. + success := len(r) > 0 + it.tab.trackRequest(n, success, r) + if err != nil { + it.tab.log.Trace("FINDNODE failed", "id", n.ID(), "err", err) } - it.tab.log.Trace("FINDNODE failed", "id", n.ID(), "failcount", fails, "dropped", dropped, "err", err) - } else if fails > 0 { - // Reset failure counter because it counts _consecutive_ failures. - it.tab.db.UpdateFindFails(n.ID(), n.IP(), 0) - } - - // Grab as many nodes as possible. Some of them might not be alive anymore, but we'll - // just remove those again during revalidation. - for _, n := range r { - it.tab.addSeenNode(n) } reply <- r } @@ -176,7 +157,7 @@ func (it *lookup) query(n *node, reply chan<- []*node) { // lookupIterator performs lookup operations and iterates over all seen nodes. // When a lookup finishes, a new one is created through nextLookup. type lookupIterator struct { - buffer []*node + buffer []*enode.Node nextLookup lookupFunc ctx context.Context cancel func() @@ -195,7 +176,7 @@ func (it *lookupIterator) Node() *enode.Node { if len(it.buffer) == 0 { return nil } - return unwrapNode(it.buffer[0]) + return it.buffer[0] } // Next moves to the next node. diff --git a/p2p/discover/metrics.go b/p2p/discover/metrics.go index 3cd0ab0414..9261ae1376 100644 --- a/p2p/discover/metrics.go +++ b/p2p/discover/metrics.go @@ -19,6 +19,7 @@ package discover import ( "fmt" "net" + "net/netip" "github.com/ethereum/go-ethereum/metrics" ) @@ -47,7 +48,7 @@ func init() { // meteredUdpConn is a wrapper around a net.UDPConn that meters both the // inbound and outbound network traffic. type meteredUdpConn struct { - UDPConn + udpConn UDPConn } func newMeteredConn(conn UDPConn) UDPConn { @@ -55,19 +56,27 @@ func newMeteredConn(conn UDPConn) UDPConn { if !metrics.Enabled { return conn } - return &meteredUdpConn{UDPConn: conn} + return &meteredUdpConn{udpConn: conn} } -// ReadFromUDP delegates a network read to the underlying connection, bumping the udp ingress traffic meter along the way. -func (c *meteredUdpConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { - n, addr, err = c.UDPConn.ReadFromUDP(b) +func (c *meteredUdpConn) Close() error { + return c.udpConn.Close() +} + +func (c *meteredUdpConn) LocalAddr() net.Addr { + return c.udpConn.LocalAddr() +} + +// ReadFromUDPAddrPort delegates a network read to the underlying connection, bumping the udp ingress traffic meter along the way. +func (c *meteredUdpConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) { + n, addr, err = c.udpConn.ReadFromUDPAddrPort(b) ingressTrafficMeter.Mark(int64(n)) return n, addr, err } -// Write delegates a network write to the underlying connection, bumping the udp egress traffic meter along the way. -func (c *meteredUdpConn) WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error) { - n, err = c.UDPConn.WriteToUDP(b, addr) +// WriteToUDPAddrPort delegates a network write to the underlying connection, bumping the udp egress traffic meter along the way. +func (c *meteredUdpConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (n int, err error) { + n, err = c.udpConn.WriteToUDPAddrPort(b, addr) egressTrafficMeter.Mark(int64(n)) return n, err } diff --git a/p2p/discover/node.go b/p2p/discover/node.go index 9ffe101ccf..87d43bd33b 100644 --- a/p2p/discover/node.go +++ b/p2p/discover/node.go @@ -17,81 +17,89 @@ package discover import ( - "crypto/ecdsa" - "crypto/elliptic" - "errors" - "math/big" "net" + "slices" + "sort" "time" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enode" ) -// node represents a host on the network. -// The fields of Node may not be modified. -type node struct { - enode.Node - addedAt time.Time // time when the node was added to the table - livenessChecks uint // how often liveness was checked +type BucketNode struct { + Node *enode.Node `json:"node"` + AddedToTable time.Time `json:"addedToTable"` + AddedToBucket time.Time `json:"addedToBucket"` + Checks int `json:"checks"` + Live bool `json:"live"` } -type encPubkey [64]byte - -func encodePubkey(key *ecdsa.PublicKey) encPubkey { - var e encPubkey - math.ReadBits(key.X, e[:len(e)/2]) - math.ReadBits(key.Y, e[len(e)/2:]) - return e +// tableNode is an entry in Table. +type tableNode struct { + *enode.Node + revalList *revalidationList + addedToTable time.Time // first time node was added to bucket or replacement list + addedToBucket time.Time // time it was added in the actual bucket + livenessChecks uint // how often liveness was checked + isValidatedLive bool // true if existence of node is considered validated right now } -func decodePubkey(curve elliptic.Curve, e []byte) (*ecdsa.PublicKey, error) { - if len(e) != len(encPubkey{}) { - return nil, errors.New("wrong size public key data") - } - p := &ecdsa.PublicKey{Curve: curve, X: new(big.Int), Y: new(big.Int)} - half := len(e) / 2 - p.X.SetBytes(e[:half]) - p.Y.SetBytes(e[half:]) - if !p.Curve.IsOnCurve(p.X, p.Y) { - return nil, errors.New("invalid curve point") +func unwrapNodes(ns []*tableNode) []*enode.Node { + result := make([]*enode.Node, len(ns)) + for i, n := range ns { + result[i] = n.Node } - return p, nil + return result } -func (e encPubkey) id() enode.ID { - return enode.ID(crypto.Keccak256Hash(e[:])) +func (n *tableNode) addr() *net.UDPAddr { + return &net.UDPAddr{IP: n.IP(), Port: n.UDP()} } -func wrapNode(n *enode.Node) *node { - return &node{Node: *n} +func (n *tableNode) String() string { + return n.Node.String() } -func wrapNodes(ns []*enode.Node) []*node { - result := make([]*node, len(ns)) - for i, n := range ns { - result[i] = wrapNode(n) - } - return result +// nodesByDistance is a list of nodes, ordered by distance to target. +type nodesByDistance struct { + entries []*enode.Node + target enode.ID } -func unwrapNode(n *node) *enode.Node { - return &n.Node -} +// push adds the given node to the list, keeping the total size below maxElems. +func (h *nodesByDistance) push(n *enode.Node, maxElems int) { + ix := sort.Search(len(h.entries), func(i int) bool { + return enode.DistCmp(h.target, h.entries[i].ID(), n.ID()) > 0 + }) -func unwrapNodes(ns []*node) []*enode.Node { - result := make([]*enode.Node, len(ns)) - for i, n := range ns { - result[i] = unwrapNode(n) + end := len(h.entries) + if len(h.entries) < maxElems { + h.entries = append(h.entries, n) + } + if ix < end { + // Slide existing entries down to make room. + // This will overwrite the entry we just appended. + copy(h.entries[ix+1:], h.entries[ix:]) + h.entries[ix] = n } - return result } -func (n *node) addr() *net.UDPAddr { - return &net.UDPAddr{IP: n.IP(), Port: n.UDP()} +type nodeType interface { + ID() enode.ID } -func (n *node) String() string { - return n.Node.String() +// containsID reports whether ns contains a node with the given ID. +func containsID[N nodeType](ns []N, id enode.ID) bool { + for _, n := range ns { + if n.ID() == id { + return true + } + } + return false +} + +// deleteNode removes a node from the list. +func deleteNode[N nodeType](list []N, id enode.ID) []N { + return slices.DeleteFunc(list, func(n N) bool { + return n.ID() == id + }) } diff --git a/p2p/discover/ntp.go b/p2p/discover/ntp.go index 3f9157808f..c8b82ef7e8 100644 --- a/p2p/discover/ntp.go +++ b/p2p/discover/ntp.go @@ -22,10 +22,10 @@ package discover import ( "fmt" "net" + "slices" "time" "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/slices" ) const ( diff --git a/p2p/discover/table.go b/p2p/discover/table.go index dcd8d48ca8..3802242152 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -24,18 +24,15 @@ package discover import ( "context" - crand "crypto/rand" - "encoding/binary" - "errors" "fmt" - mrand "math/rand" - "net" - "sort" + "net/netip" + "slices" "sync" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/gopool" + "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p/enode" @@ -58,22 +55,22 @@ const ( bucketIPLimit, bucketSubnet = 2, 24 // at most 2 addresses from the same /24 tableIPLimit, tableSubnet = 10, 24 - copyNodesInterval = 30 * time.Second - seedMinTableTime = 5 * time.Minute - seedCount = 30 - seedMaxAge = 5 * 24 * time.Hour + seedMinTableTime = 5 * time.Minute + seedCount = 30 + seedMaxAge = 5 * 24 * time.Hour ) // Table is the 'node table', a Kademlia-like index of neighbor nodes. The table keeps // itself up-to-date by verifying the liveness of neighbors and requesting their node // records when announcements of a new record version are received. type Table struct { - mutex sync.Mutex // protects buckets, bucket content, nursery, rand - buckets [nBuckets]*bucket // index of known nodes by distance - bucketSize int // size of bucket - nursery []*node // bootstrap nodes - rand *mrand.Rand // source of randomness, periodically reseeded - ips netutil.DistinctNetSet + mutex sync.Mutex // protects buckets, bucket content, nursery, rand + buckets [nBuckets]*bucket // index of known nodes by distance + bucketSize int // size of bucket + nursery []*enode.Node // bootstrap nodes + rand reseedingRandom // source of randomness, periodically reseeded + ips netutil.DistinctNetSet + revalidation tableRevalidation db *enode.DB // database of known nodes net transport @@ -81,15 +78,19 @@ type Table struct { log log.Logger // loop channels - refreshReq chan chan struct{} - initDone chan struct{} - closeReq chan struct{} - closed chan struct{} + refreshReq chan chan struct{} + revalResponseCh chan revalidationResponse + addNodeCh chan addNodeOp + addNodeHandled chan bool + trackRequestCh chan trackRequestOp + initDone chan struct{} + closeReq chan struct{} + closed chan struct{} enrFilter NodeFilterFunc - nodeAddedHook func(*bucket, *node) - nodeRemovedHook func(*bucket, *node) + nodeAddedHook func(*bucket, *tableNode) + nodeRemovedHook func(*bucket, *tableNode) } // transport is implemented by the UDP transports. @@ -104,75 +105,80 @@ type transport interface { // bucket contains nodes, ordered by their last activity. the entry // that was most recently active is the first element in entries. type bucket struct { - entries []*node // live entries, sorted by time of last contact - replacements []*node // recently seen nodes to be used if revalidation fails + entries []*tableNode // live entries, sorted by time of last contact + replacements []*tableNode // recently seen nodes to be used if revalidation fails ips netutil.DistinctNetSet index int } +type addNodeOp struct { + node *enode.Node + isInbound bool + forceSetLive bool // for tests +} + +type trackRequestOp struct { + node *enode.Node + foundNodes []*enode.Node + success bool +} + func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) { cfg = cfg.withDefaults() tab := &Table{ - net: t, - db: db, - cfg: cfg, - log: cfg.Log, - refreshReq: make(chan chan struct{}), - initDone: make(chan struct{}), - closeReq: make(chan struct{}), - closed: make(chan struct{}), - rand: mrand.New(mrand.NewSource(0)), - ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit}, - enrFilter: cfg.FilterFunction, - bucketSize: bucketSize, + net: t, + db: db, + cfg: cfg, + log: cfg.Log, + refreshReq: make(chan chan struct{}), + revalResponseCh: make(chan revalidationResponse), + addNodeCh: make(chan addNodeOp), + addNodeHandled: make(chan bool), + trackRequestCh: make(chan trackRequestOp), + initDone: make(chan struct{}), + closeReq: make(chan struct{}), + closed: make(chan struct{}), + ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit}, + enrFilter: cfg.FilterFunction, + bucketSize: bucketSize, } if cfg.IsBootnode { tab.bucketSize = bootNodeBucketSize } - if err := tab.setFallbackNodes(cfg.Bootnodes); err != nil { - return nil, err - } for i := range tab.buckets { tab.buckets[i] = &bucket{ index: i, ips: netutil.DistinctNetSet{Subnet: bucketSubnet, Limit: bucketIPLimit}, } } - tab.seedRand() - tab.loadSeedNodes() - - return tab, nil -} + tab.rand.seed() + tab.revalidation.init(&cfg) -func newMeteredTable(t transport, db *enode.DB, cfg Config) (*Table, error) { - tab, err := newTable(t, db, cfg) - if err != nil { + // initial table content + if err := tab.setFallbackNodes(cfg.Bootnodes); err != nil { return nil, err } - if metrics.Enabled { - tab.nodeAddedHook = func(b *bucket, n *node) { - bucketsCounter[b.index].Inc(1) - } - tab.nodeRemovedHook = func(b *bucket, n *node) { - bucketsCounter[b.index].Dec(1) - } - } + tab.loadSeedNodes() + return tab, nil } // Nodes returns all nodes contained in the table. -func (tab *Table) Nodes() []*enode.Node { - if !tab.isInitDone() { - return nil - } - +func (tab *Table) Nodes() [][]BucketNode { tab.mutex.Lock() defer tab.mutex.Unlock() - var nodes []*enode.Node - for _, b := range &tab.buckets { - for _, n := range b.entries { - nodes = append(nodes, unwrapNode(n)) + nodes := make([][]BucketNode, len(tab.buckets)) + for i, b := range &tab.buckets { + nodes[i] = make([]BucketNode, len(b.entries)) + for j, n := range b.entries { + nodes[i][j] = BucketNode{ + Node: n.Node, + Checks: int(n.livenessChecks), + Live: n.isValidatedLive, + AddedToTable: n.addedToTable, + AddedToBucket: n.addedToBucket, + } } } return nodes @@ -182,15 +188,6 @@ func (tab *Table) self() *enode.Node { return tab.net.Self() } -func (tab *Table) seedRand() { - var b [8]byte - crand.Read(b[:]) - - tab.mutex.Lock() - tab.rand.Seed(int64(binary.BigEndian.Uint64(b[:]))) - tab.mutex.Unlock() -} - // getNode returns the node with the given ID or nil if it isn't in the table. func (tab *Table) getNode(id enode.ID) *enode.Node { tab.mutex.Lock() @@ -199,7 +196,7 @@ func (tab *Table) getNode(id enode.ID) *enode.Node { b := tab.bucket(id) for _, e := range b.entries { if e.ID() == id { - return unwrapNode(e) + return e.Node } } return nil @@ -215,16 +212,16 @@ func (tab *Table) close() { // are used to connect to the network if the table is empty and there // are no known nodes in the database. func (tab *Table) setFallbackNodes(nodes []*enode.Node) error { - nursery := make([]*node, 0, len(nodes)) + nursery := make([]*enode.Node, 0, len(nodes)) for _, n := range nodes { if err := n.ValidateComplete(); err != nil { return fmt.Errorf("bad bootstrap node %q: %v", n, err) } - if tab.cfg.NetRestrict != nil && !tab.cfg.NetRestrict.Contains(n.IP()) { - tab.log.Error("Bootstrap node filtered by netrestrict", "id", n.ID(), "ip", n.IP()) + if tab.cfg.NetRestrict != nil && !tab.cfg.NetRestrict.ContainsAddr(n.IPAddr()) { + tab.log.Error("Bootstrap node filtered by netrestrict", "id", n.ID(), "ip", n.IPAddr()) continue } - nursery = append(nursery, wrapNode(n)) + nursery = append(nursery, n) } tab.nursery = nursery return nil @@ -250,19 +247,126 @@ func (tab *Table) refresh() <-chan struct{} { return done } -// loop schedules runs of doRefresh, doRevalidate and copyLiveNodes. +// findnodeByID returns the n nodes in the table that are closest to the given id. +// This is used by the FINDNODE/v4 handler. +// +// The preferLive parameter says whether the caller wants liveness-checked results. If +// preferLive is true and the table contains any verified nodes, the result will not +// contain unverified nodes. However, if there are no verified nodes at all, the result +// will contain unverified nodes. +func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *nodesByDistance { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + // Scan all buckets. There might be a better way to do this, but there aren't that many + // buckets, so this solution should be fine. The worst-case complexity of this loop + // is O(tab.len() * nresults). + nodes := &nodesByDistance{target: target} + liveNodes := &nodesByDistance{target: target} + for _, b := range &tab.buckets { + for _, n := range b.entries { + nodes.push(n.Node, nresults) + if preferLive && n.isValidatedLive { + liveNodes.push(n.Node, nresults) + } + } + } + + if preferLive && len(liveNodes.entries) > 0 { + return liveNodes + } + return nodes +} + +// appendBucketNodes adds nodes at the given distance to the result slice. +// This is used by the FINDNODE/v5 handler. +func (tab *Table) appendBucketNodes(dist uint, result []*enode.Node, checkLive bool) []*enode.Node { + if dist > 256 { + return result + } + if dist == 0 { + return append(result, tab.self()) + } + + tab.mutex.Lock() + for _, n := range tab.bucketAtDistance(int(dist)).entries { + if !checkLive || n.isValidatedLive { + result = append(result, n.Node) + } + } + tab.mutex.Unlock() + + // Shuffle result to avoid always returning same nodes in FINDNODE/v5. + tab.rand.Shuffle(len(result), func(i, j int) { + result[i], result[j] = result[j], result[i] + }) + return result +} + +// len returns the number of nodes in the table. +func (tab *Table) len() (n int) { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + for _, b := range &tab.buckets { + n += len(b.entries) + } + return n +} + +// addFoundNode adds a node which may not be live. If the bucket has space available, +// adding the node succeeds immediately. Otherwise, the node is added to the replacements +// list. +// +// The caller must not hold tab.mutex. +func (tab *Table) addFoundNode(n *enode.Node, forceSetLive bool) bool { + op := addNodeOp{node: n, isInbound: false, forceSetLive: forceSetLive} + select { + case tab.addNodeCh <- op: + return <-tab.addNodeHandled + case <-tab.closeReq: + return false + } +} + +// addInboundNode adds a node from an inbound contact. If the bucket has no space, the +// node is added to the replacements list. +// +// There is an additional safety measure: if the table is still initializing the node is +// not added. This prevents an attack where the table could be filled by just sending ping +// repeatedly. +// +// The caller must not hold tab.mutex. +func (tab *Table) addInboundNode(n *enode.Node) bool { + op := addNodeOp{node: n, isInbound: true} + select { + case tab.addNodeCh <- op: + return <-tab.addNodeHandled + case <-tab.closeReq: + return false + } +} + +func (tab *Table) trackRequest(n *enode.Node, success bool, foundNodes []*enode.Node) { + op := trackRequestOp{n, foundNodes, success} + select { + case tab.trackRequestCh <- op: + case <-tab.closeReq: + } +} + +// loop is the main loop of Table. func (tab *Table) loop() { var ( - revalidate = time.NewTimer(tab.nextRevalidateTime()) - refresh = time.NewTimer(tab.nextRefreshTime()) - copyNodes = time.NewTicker(copyNodesInterval) - refreshDone = make(chan struct{}) // where doRefresh reports completion - revalidateDone chan struct{} // where doRevalidate reports completion - waiting = []chan struct{}{tab.initDone} // holds waiting callers while doRefresh runs + refresh = time.NewTimer(tab.nextRefreshTime()) + refreshDone = make(chan struct{}) // where doRefresh reports completion + waiting = []chan struct{}{tab.initDone} // holds waiting callers while doRefresh runs + revalTimer = mclock.NewAlarm(tab.cfg.Clock) + reseedRandTimer = time.NewTicker(10 * time.Minute) ) defer refresh.Stop() - defer revalidate.Stop() - defer copyNodes.Stop() + defer revalTimer.Stop() + defer reseedRandTimer.Stop() // Start initial refresh. gopool.Submit(func() { @@ -270,15 +374,35 @@ func (tab *Table) loop() { }) loop: for { + nextTime := tab.revalidation.run(tab, tab.cfg.Clock.Now()) + revalTimer.Schedule(nextTime) + select { + case <-reseedRandTimer.C: + tab.rand.seed() + + case <-revalTimer.C(): + + case r := <-tab.revalResponseCh: + tab.revalidation.handleResponse(tab, r) + + case op := <-tab.addNodeCh: + tab.mutex.Lock() + ok := tab.handleAddNode(op) + tab.mutex.Unlock() + tab.addNodeHandled <- ok + + case op := <-tab.trackRequestCh: + tab.handleTrackRequest(op) + case <-refresh.C: - tab.seedRand() if refreshDone == nil { refreshDone = make(chan struct{}) gopool.Submit(func() { tab.doRefresh(refreshDone) }) } + case req := <-tab.refreshReq: waiting = append(waiting, req) if refreshDone == nil { @@ -288,24 +412,13 @@ loop: tab.doRefresh(refreshDone) }) } + case <-refreshDone: for _, ch := range waiting { close(ch) } waiting, refreshDone = nil, nil refresh.Reset(tab.nextRefreshTime()) - case <-revalidate.C: - revalidateDone = make(chan struct{}) - gopool.Submit(func() { - tab.doRevalidate(revalidateDone) - }) - case <-revalidateDone: - revalidate.Reset(tab.nextRevalidateTime()) - revalidateDone = nil - case <-copyNodes.C: - gopool.Submit(func() { - tab.copyLiveNodes() - }) case <-tab.closeReq: break loop @@ -318,9 +431,6 @@ loop: for _, ch := range waiting { close(ch) } - if revalidateDone != nil { - <-revalidateDone - } close(tab.closed) } @@ -349,183 +459,26 @@ func (tab *Table) doRefresh(done chan struct{}) { } func (tab *Table) loadSeedNodes() { - seeds := wrapNodes(tab.db.QuerySeeds(seedCount, seedMaxAge)) + seeds := tab.db.QuerySeeds(seedCount, seedMaxAge) seeds = append(seeds, tab.nursery...) for i := range seeds { seed := seeds[i] if tab.log.Enabled(context.Background(), log.LevelTrace) { - age := time.Since(tab.db.LastPongReceived(seed.ID(), seed.IP())) - tab.log.Trace("Found seed node in database", "id", seed.ID(), "addr", seed.addr(), "age", age) - } - tab.addSeenNode(seed) - } -} - -// doRevalidate checks that the last node in a random bucket is still live and replaces or -// deletes the node if it isn't. -func (tab *Table) doRevalidate(done chan<- struct{}) { - defer func() { done <- struct{}{} }() - - last, bi := tab.nodeToRevalidate() - if last == nil { - // No non-empty bucket found. - return - } - - // Ping the selected node and wait for a pong. - remoteSeq, err := tab.net.ping(unwrapNode(last)) - - // Also fetch record if the node replied and returned a higher sequence number. - if last.Seq() < remoteSeq { - n, enrErr := tab.net.RequestENR(unwrapNode(last)) - if enrErr != nil { - tab.log.Debug("ENR request failed", "id", last.ID(), "addr", last.addr(), "err", enrErr) - } else { - if tab.enrFilter != nil { - if !tab.enrFilter(n.Record()) { - tab.log.Trace("ENR record filter out", "id", last.ID(), "addr", last.addr()) - err = errors.New("filtered node") - } - } - last = &node{Node: *n, addedAt: last.addedAt, livenessChecks: last.livenessChecks} - } - } - - tab.mutex.Lock() - defer tab.mutex.Unlock() - b := tab.buckets[bi] - if err == nil { - // The node responded, move it to the front. - last.livenessChecks++ - tab.log.Debug("Revalidated node", "b", bi, "id", last.ID(), "checks", last.livenessChecks) - tab.bumpInBucket(b, last) - return - } - // No reply received, pick a replacement or delete the node if there aren't - // any replacements. - if r := tab.replace(b, last); r != nil { - tab.log.Debug("Replaced dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks, "r", r.ID(), "rip", r.IP()) - } else { - tab.log.Debug("Removed dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks) - } -} - -// nodeToRevalidate returns the last node in a random, non-empty bucket. -func (tab *Table) nodeToRevalidate() (n *node, bi int) { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - for _, bi = range tab.rand.Perm(len(tab.buckets)) { - b := tab.buckets[bi] - if len(b.entries) > 0 { - last := b.entries[len(b.entries)-1] - return last, bi + age := time.Since(tab.db.LastPongReceived(seed.ID(), seed.IPAddr())) + addr, _ := seed.UDPEndpoint() + tab.log.Trace("Found seed node in database", "id", seed.ID(), "addr", addr, "age", age) } + tab.mutex.Lock() + tab.handleAddNode(addNodeOp{node: seed, isInbound: false}) + tab.mutex.Unlock() } - return nil, 0 -} - -func (tab *Table) nextRevalidateTime() time.Duration { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - return time.Duration(tab.rand.Int63n(int64(tab.cfg.PingInterval))) } func (tab *Table) nextRefreshTime() time.Duration { - tab.mutex.Lock() - defer tab.mutex.Unlock() - half := tab.cfg.RefreshInterval / 2 return half + time.Duration(tab.rand.Int63n(int64(half))) } -// copyLiveNodes adds nodes from the table to the database if they have been in the table -// longer than seedMinTableTime. -func (tab *Table) copyLiveNodes() { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - now := time.Now() - for _, b := range &tab.buckets { - for _, n := range b.entries { - if n.livenessChecks > 0 && now.Sub(n.addedAt) >= seedMinTableTime { - tab.db.UpdateNode(unwrapNode(n)) - } - } - } -} - -// findnodeByID returns the n nodes in the table that are closest to the given id. -// This is used by the FINDNODE/v4 handler. -// -// The preferLive parameter says whether the caller wants liveness-checked results. If -// preferLive is true and the table contains any verified nodes, the result will not -// contain unverified nodes. However, if there are no verified nodes at all, the result -// will contain unverified nodes. -func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *nodesByDistance { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - // Scan all buckets. There might be a better way to do this, but there aren't that many - // buckets, so this solution should be fine. The worst-case complexity of this loop - // is O(tab.len() * nresults). - nodes := &nodesByDistance{target: target} - liveNodes := &nodesByDistance{target: target} - for _, b := range &tab.buckets { - for _, n := range b.entries { - nodes.push(n, nresults) - if preferLive && n.livenessChecks > 0 { - liveNodes.push(n, nresults) - } - } - } - - if preferLive && len(liveNodes.entries) > 0 { - return liveNodes - } - return nodes -} - -// appendLiveNodes adds nodes at the given distance to the result slice. -func (tab *Table) appendLiveNodes(dist uint, result []*enode.Node) []*enode.Node { - if dist > 256 { - return result - } - if dist == 0 { - return append(result, tab.self()) - } - - tab.mutex.Lock() - defer tab.mutex.Unlock() - for _, n := range tab.bucketAtDistance(int(dist)).entries { - if n.livenessChecks >= 1 { - node := n.Node // avoid handing out pointer to struct field - result = append(result, &node) - } - } - return result -} - -// len returns the number of nodes in the table. -func (tab *Table) len() (n int) { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - for _, b := range &tab.buckets { - n += len(b.entries) - } - return n -} - -// bucketLen returns the number of nodes in the bucket for the given ID. -func (tab *Table) bucketLen(id enode.ID) int { - tab.mutex.Lock() - defer tab.mutex.Unlock() - - return len(tab.bucket(id).entries) -} - // bucket returns the bucket for the given node ID hash. func (tab *Table) bucket(id enode.ID) *bucket { d := enode.LogDist(tab.self().ID(), id) @@ -539,58 +492,11 @@ func (tab *Table) bucketAtDistance(d int) *bucket { return tab.buckets[d-bucketMinDistance-1] } -// addSeenNode adds a node which may or may not be live to the end of a bucket. If the -// bucket has space available, adding the node succeeds immediately. Otherwise, the node is -// added to the replacements list. -// -// The caller must not hold tab.mutex. -func (tab *Table) addSeenNode(n *node) { - gopool.Submit(func() { - tab.addSeenNodeSync(n) - }) -} - -func (tab *Table) addSeenNodeSync(n *node) { - if n.ID() == tab.self().ID() { - return - } - - if tab.filterNode(n) { - return - } - - tab.mutex.Lock() - defer tab.mutex.Unlock() - b := tab.bucket(n.ID()) - if contains(b.entries, n.ID()) { - // Already in bucket, don't add. - return - } - if len(b.entries) >= tab.bucketSize { - // Bucket full, maybe add as replacement. - tab.addReplacement(b, n) - return - } - if !tab.addIP(b, n.IP()) { - // Can't add: IP limit reached. - return - } - - // Add to end of bucket: - b.entries = append(b.entries, n) - b.replacements = deleteNode(b.replacements, n) - n.addedAt = time.Now() - - if tab.nodeAddedHook != nil { - tab.nodeAddedHook(b, n) - } -} - -func (tab *Table) filterNode(n *node) bool { +func (tab *Table) filterNode(n *tableNode) bool { if tab.enrFilter == nil { return false } - if node, err := tab.net.RequestENR(unwrapNode(n)); err != nil { + if node, err := tab.net.RequestENR(n.Node); err != nil { tab.log.Debug("ENR request failed", "id", n.ID(), "addr", n.addr(), "err", err) return false } else if !tab.enrFilter(node.Record()) { @@ -600,177 +506,222 @@ func (tab *Table) filterNode(n *node) bool { return false } -// addVerifiedNode adds a node whose existence has been verified recently to the front of a -// bucket. If the node is already in the bucket, it is moved to the front. If the bucket -// has no space, the node is added to the replacements list. -// -// There is an additional safety measure: if the table is still initializing the node -// is not added. This prevents an attack where the table could be filled by just sending -// ping repeatedly. -// -// The caller must not hold tab.mutex. - -func (tab *Table) addVerifiedNode(n *node) { - gopool.Submit(func() { - tab.addVerifiedNodeSync(n) - }) +func (tab *Table) addIP(b *bucket, ip netip.Addr) bool { + if !ip.IsValid() || ip.IsUnspecified() { + return false // Nodes without IP cannot be added. + } + if netutil.AddrIsLAN(ip) { + return true + } + if !tab.ips.AddAddr(ip) { + tab.log.Debug("IP exceeds table limit", "ip", ip) + return false + } + if !b.ips.AddAddr(ip) { + tab.log.Debug("IP exceeds bucket limit", "ip", ip) + tab.ips.RemoveAddr(ip) + return false + } + return true } -func (tab *Table) addVerifiedNodeSync(n *node) { - if !tab.isInitDone() { +func (tab *Table) removeIP(b *bucket, ip netip.Addr) { + if netutil.AddrIsLAN(ip) { return } - if n.ID() == tab.self().ID() { - return + tab.ips.RemoveAddr(ip) + b.ips.RemoveAddr(ip) +} + +// handleAddNode adds the node in the request to the table, if there is space. +// The caller must hold tab.mutex. +func (tab *Table) handleAddNode(req addNodeOp) bool { + if req.node.ID() == tab.self().ID() { + return false } - if tab.filterNode(n) { - return + + // For nodes from inbound contact, there is an additional safety measure: if the table + // is still initializing the node is not added. + if req.isInbound && !tab.isInitDone() { + return false } - tab.mutex.Lock() - defer tab.mutex.Unlock() - b := tab.bucket(n.ID()) - if tab.bumpInBucket(b, n) { - // Already in bucket, moved to front. - return + + b := tab.bucket(req.node.ID()) + n, _ := tab.bumpInBucket(b, req.node, req.isInbound) + if n != nil { + // Already in bucket. + return false } - if len(b.entries) >= tab.bucketSize { + if len(b.entries) >= bucketSize { // Bucket full, maybe add as replacement. - tab.addReplacement(b, n) - return + tab.addReplacement(b, req.node) + return false } - if !tab.addIP(b, n.IP()) { + if !tab.addIP(b, req.node.IPAddr()) { // Can't add: IP limit reached. - return + return false } - // Add to front of bucket. - b.entries, _ = pushNode(b.entries, n, tab.bucketSize) - b.replacements = deleteNode(b.replacements, n) - n.addedAt = time.Now() - - if tab.nodeAddedHook != nil { - tab.nodeAddedHook(b, n) + // Add to bucket. + wn := &tableNode{Node: req.node} + if req.forceSetLive { + wn.livenessChecks = 1 + wn.isValidatedLive = true } -} -// delete removes an entry from the node table. It is used to evacuate dead nodes. -func (tab *Table) delete(node *node) { - tab.mutex.Lock() - defer tab.mutex.Unlock() + if tab.filterNode(wn) { + return false + } - tab.deleteInBucket(tab.bucket(node.ID()), node) + b.entries = append(b.entries, wn) + b.replacements = deleteNode(b.replacements, wn.ID()) + tab.nodeAdded(b, wn) + return true } -func (tab *Table) addIP(b *bucket, ip net.IP) bool { - if len(ip) == 0 { - return false // Nodes without IP cannot be added. - } - if netutil.IsLAN(ip) { - return true +// addReplacement adds n to the replacement cache of bucket b. +func (tab *Table) addReplacement(b *bucket, n *enode.Node) { + if containsID(b.replacements, n.ID()) { + // TODO: update ENR + return } - if !tab.ips.Add(ip) { - tab.log.Debug("IP exceeds table limit", "ip", ip) - return false + if !tab.addIP(b, n.IPAddr()) { + return } - if !b.ips.Add(ip) { - tab.log.Debug("IP exceeds bucket limit", "ip", ip) - tab.ips.Remove(ip) - return false + + wn := &tableNode{Node: n, addedToTable: time.Now()} + var removed *tableNode + b.replacements, removed = pushNode(b.replacements, wn, maxReplacements) + if removed != nil { + tab.removeIP(b, removed.IPAddr()) } - return true } -func (tab *Table) removeIP(b *bucket, ip net.IP) { - if netutil.IsLAN(ip) { - return +func (tab *Table) nodeAdded(b *bucket, n *tableNode) { + if n.addedToTable == (time.Time{}) { + n.addedToTable = time.Now() + } + n.addedToBucket = time.Now() + tab.revalidation.nodeAdded(tab, n) + if tab.nodeAddedHook != nil { + tab.nodeAddedHook(b, n) + } + if metrics.Enabled { + bucketsCounter[b.index].Inc(1) } - tab.ips.Remove(ip) - b.ips.Remove(ip) } -func (tab *Table) addReplacement(b *bucket, n *node) { - for _, e := range b.replacements { - if e.ID() == n.ID() { - return // already in list - } - } - if !tab.addIP(b, n.IP()) { - return +func (tab *Table) nodeRemoved(b *bucket, n *tableNode) { + tab.revalidation.nodeRemoved(n) + if tab.nodeRemovedHook != nil { + tab.nodeRemovedHook(b, n) } - var removed *node - b.replacements, removed = pushNode(b.replacements, n, maxReplacements) - if removed != nil { - tab.removeIP(b, removed.IP()) + if metrics.Enabled { + bucketsCounter[b.index].Dec(1) } } -// replace removes n from the replacement list and replaces 'last' with it if it is the -// last entry in the bucket. If 'last' isn't the last entry, it has either been replaced -// with someone else or became active. -func (tab *Table) replace(b *bucket, last *node) *node { - if len(b.entries) == 0 || b.entries[len(b.entries)-1].ID() != last.ID() { - // Entry has moved, don't replace it. +// deleteInBucket removes node n from the table. +// If there are replacement nodes in the bucket, the node is replaced. +func (tab *Table) deleteInBucket(b *bucket, id enode.ID) *tableNode { + index := slices.IndexFunc(b.entries, func(e *tableNode) bool { return e.ID() == id }) + if index == -1 { + // Entry has been removed already. return nil } - // Still the last entry. + + // Remove the node. + n := b.entries[index] + b.entries = slices.Delete(b.entries, index, index+1) + tab.removeIP(b, n.IPAddr()) + tab.nodeRemoved(b, n) + + // Add replacement. if len(b.replacements) == 0 { - tab.deleteInBucket(b, last) + tab.log.Debug("Removed dead node", "b", b.index, "id", n.ID(), "ip", n.IPAddr()) return nil } - r := b.replacements[tab.rand.Intn(len(b.replacements))] - b.replacements = deleteNode(b.replacements, r) - b.entries[len(b.entries)-1] = r - tab.removeIP(b, last.IP()) - return r -} - -// bumpInBucket moves the given node to the front of the bucket entry list -// if it is contained in that list. -func (tab *Table) bumpInBucket(b *bucket, n *node) bool { - for i := range b.entries { - if b.entries[i].ID() == n.ID() { - if !n.IP().Equal(b.entries[i].IP()) { - // Endpoint has changed, ensure that the new IP fits into table limits. - tab.removeIP(b, b.entries[i].IP()) - if !tab.addIP(b, n.IP()) { - // It doesn't, put the previous one back. - tab.addIP(b, b.entries[i].IP()) - return false - } - } - // Move it to the front. - copy(b.entries[1:], b.entries[:i]) - b.entries[0] = n - return true + rindex := tab.rand.Intn(len(b.replacements)) + rep := b.replacements[rindex] + b.replacements = slices.Delete(b.replacements, rindex, rindex+1) + b.entries = append(b.entries, rep) + tab.nodeAdded(b, rep) + tab.log.Debug("Replaced dead node", "b", b.index, "id", n.ID(), "ip", n.IPAddr(), "r", rep.ID(), "rip", rep.IPAddr()) + return rep +} + +// bumpInBucket updates a node record if it exists in the bucket. +// The second return value reports whether the node's endpoint (IP/port) was updated. +func (tab *Table) bumpInBucket(b *bucket, newRecord *enode.Node, isInbound bool) (n *tableNode, endpointChanged bool) { + i := slices.IndexFunc(b.entries, func(elem *tableNode) bool { + return elem.ID() == newRecord.ID() + }) + if i == -1 { + return nil, false // not in bucket + } + n = b.entries[i] + + // For inbound updates (from the node itself) we accept any change, even if it sets + // back the sequence number. For found nodes (!isInbound), seq has to advance. Note + // this check also ensures found discv4 nodes (which always have seq=0) can't be + // updated. + if newRecord.Seq() <= n.Seq() && !isInbound { + return n, false + } + + // Check endpoint update against IP limits. + ipchanged := newRecord.IPAddr() != n.IPAddr() + portchanged := newRecord.UDP() != n.UDP() + if ipchanged { + tab.removeIP(b, n.IPAddr()) + if !tab.addIP(b, newRecord.IPAddr()) { + // It doesn't fit with the limit, put the previous record back. + tab.addIP(b, n.IPAddr()) + return n, false } } - return false + + // Apply update. + n.Node = newRecord + if ipchanged || portchanged { + // Ensure node is revalidated quickly for endpoint changes. + tab.revalidation.nodeEndpointChanged(tab, n) + return n, true + } + return n, false } -func (tab *Table) deleteInBucket(b *bucket, n *node) { - // Check if the node is actually in the bucket so the removed hook - // isn't called multiple times for the same node. - if !contains(b.entries, n.ID()) { - return +func (tab *Table) handleTrackRequest(op trackRequestOp) { + var fails int + if op.success { + // Reset failure counter because it counts _consecutive_ failures. + tab.db.UpdateFindFails(op.node.ID(), op.node.IPAddr(), 0) + } else { + fails = tab.db.FindFails(op.node.ID(), op.node.IPAddr()) + fails++ + tab.db.UpdateFindFails(op.node.ID(), op.node.IPAddr(), fails) } - b.entries = deleteNode(b.entries, n) - tab.removeIP(b, n.IP()) - if tab.nodeRemovedHook != nil { - tab.nodeRemovedHook(b, n) + + tab.mutex.Lock() + defer tab.mutex.Unlock() + + b := tab.bucket(op.node.ID()) + // Remove the node from the local table if it fails to return anything useful too + // many times, but only if there are enough other nodes in the bucket. This latter + // condition specifically exists to make bootstrapping in smaller test networks more + // reliable. + if fails >= maxFindnodeFailures && len(b.entries) >= bucketSize/4 { + tab.deleteInBucket(b, op.node.ID()) } -} -func contains(ns []*node, id enode.ID) bool { - for _, n := range ns { - if n.ID() == id { - return true - } + // Add found nodes. + for _, n := range op.foundNodes { + tab.handleAddNode(addNodeOp{n, false, false}) } - return false } // pushNode adds n to the front of list, keeping at most max items. -func pushNode(list []*node, n *node, max int) ([]*node, *node) { +func pushNode(list []*tableNode, n *tableNode, max int) ([]*tableNode, *tableNode) { if len(list) < max { list = append(list, nil) } @@ -779,37 +730,3 @@ func pushNode(list []*node, n *node, max int) ([]*node, *node) { list[0] = n return list, removed } - -// deleteNode removes n from list. -func deleteNode(list []*node, n *node) []*node { - for i := range list { - if list[i].ID() == n.ID() { - return append(list[:i], list[i+1:]...) - } - } - return list -} - -// nodesByDistance is a list of nodes, ordered by distance to target. -type nodesByDistance struct { - entries []*node - target enode.ID -} - -// push adds the given node to the list, keeping the total size below maxElems. -func (h *nodesByDistance) push(n *node, maxElems int) { - ix := sort.Search(len(h.entries), func(i int) bool { - return enode.DistCmp(h.target, h.entries[i].ID(), n.ID()) > 0 - }) - - end := len(h.entries) - if len(h.entries) < maxElems { - h.entries = append(h.entries, n) - } - if ix < end { - // Slide existing entries down to make room. - // This will overwrite the entry we just appended. - copy(h.entries[ix+1:], h.entries[ix:]) - h.entries[ix] = n - } -} diff --git a/p2p/discover/table_reval.go b/p2p/discover/table_reval.go new file mode 100644 index 0000000000..9e9abc5aa4 --- /dev/null +++ b/p2p/discover/table_reval.go @@ -0,0 +1,255 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discover + +import ( + "errors" + "fmt" + "math" + "slices" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +const never = mclock.AbsTime(math.MaxInt64) + +const slowRevalidationFactor = 3 + +// tableRevalidation implements the node revalidation process. +// It tracks all nodes contained in Table, and schedules sending PING to them. +type tableRevalidation struct { + fast revalidationList + slow revalidationList + activeReq map[enode.ID]struct{} +} + +type revalidationResponse struct { + n *tableNode + newRecord *enode.Node + didRespond bool +} + +func (tr *tableRevalidation) init(cfg *Config) { + tr.activeReq = make(map[enode.ID]struct{}) + tr.fast.nextTime = never + tr.fast.interval = cfg.PingInterval + tr.fast.name = "fast" + tr.slow.nextTime = never + tr.slow.interval = cfg.PingInterval * slowRevalidationFactor + tr.slow.name = "slow" +} + +// nodeAdded is called when the table receives a new node. +func (tr *tableRevalidation) nodeAdded(tab *Table, n *tableNode) { + tr.fast.push(n, tab.cfg.Clock.Now(), &tab.rand) +} + +// nodeRemoved is called when a node was removed from the table. +func (tr *tableRevalidation) nodeRemoved(n *tableNode) { + if n.revalList == nil { + panic(fmt.Errorf("removed node %v has nil revalList", n.ID())) + } + n.revalList.remove(n) +} + +// nodeEndpointChanged is called when a change in IP or port is detected. +func (tr *tableRevalidation) nodeEndpointChanged(tab *Table, n *tableNode) { + n.isValidatedLive = false + tr.moveToList(&tr.fast, n, tab.cfg.Clock.Now(), &tab.rand) +} + +// run performs node revalidation. +// It returns the next time it should be invoked, which is used in the Table main loop +// to schedule a timer. However, run can be called at any time. +func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) (nextTime mclock.AbsTime) { + reval := func(list *revalidationList) { + if list.nextTime <= now { + if n := list.get(now, &tab.rand, tr.activeReq); n != nil { + tr.startRequest(tab, n) + } + // Update nextTime regardless if any requests were started because + // current value has passed. + list.schedule(now, &tab.rand) + } + } + reval(&tr.fast) + reval(&tr.slow) + + return min(tr.fast.nextTime, tr.slow.nextTime) +} + +// startRequest spawns a revalidation request for node n. +func (tr *tableRevalidation) startRequest(tab *Table, n *tableNode) { + if _, ok := tr.activeReq[n.ID()]; ok { + panic(fmt.Errorf("duplicate startRequest (node %v)", n.ID())) + } + tr.activeReq[n.ID()] = struct{}{} + resp := revalidationResponse{n: n} + + // Fetch the node while holding lock. + tab.mutex.Lock() + node := n.Node + tab.mutex.Unlock() + + go tab.doRevalidate(resp, node) +} + +func (tab *Table) doRevalidate(resp revalidationResponse, node *enode.Node) { + // Ping the selected node and wait for a pong response. + remoteSeq, err := tab.net.ping(node) + resp.didRespond = err == nil + + // Also fetch record if the node replied and returned a higher sequence number. + if remoteSeq > node.Seq() { + newrec, err := tab.net.RequestENR(node) + if err != nil { + tab.log.Debug("ENR request failed", "id", node.ID(), "err", err) + } else { + if tab.enrFilter != nil && !tab.enrFilter(newrec.Record()) { + tab.log.Trace("ENR record filter out", "id", node.ID(), "err", errors.New("filtered node")) + // TODO: use didRespond to express failure temporarily + resp.didRespond = false + } else { + resp.newRecord = newrec + } + } + } + + select { + case tab.revalResponseCh <- resp: + case <-tab.closed: + } +} + +// handleResponse processes the result of a revalidation request. +func (tr *tableRevalidation) handleResponse(tab *Table, resp revalidationResponse) { + var ( + now = tab.cfg.Clock.Now() + n = resp.n + b = tab.bucket(n.ID()) + ) + delete(tr.activeReq, n.ID()) + + // If the node was removed from the table while getting checked, we need to stop + // processing here to avoid re-adding it. + if n.revalList == nil { + return + } + + // Store potential seeds in database. + // This is done via defer to avoid holding Table lock while writing to DB. + defer func() { + if n.isValidatedLive && n.livenessChecks > 5 { + tab.db.UpdateNode(resp.n.Node) + } + }() + + // Remaining logic needs access to Table internals. + tab.mutex.Lock() + defer tab.mutex.Unlock() + + if !resp.didRespond { + n.livenessChecks /= 3 + if n.livenessChecks <= 0 { + tab.deleteInBucket(b, n.ID()) + } else { + tab.log.Debug("Node revalidation failed", "b", b.index, "id", n.ID(), "checks", n.livenessChecks, "q", n.revalList.name) + tr.moveToList(&tr.fast, n, now, &tab.rand) + } + return + } + + // The node responded. + n.livenessChecks++ + n.isValidatedLive = true + tab.log.Debug("Node revalidated", "b", b.index, "id", n.ID(), "checks", n.livenessChecks, "q", n.revalList.name) + var endpointChanged bool + if resp.newRecord != nil { + _, endpointChanged = tab.bumpInBucket(b, resp.newRecord, false) + } + + // Node moves to slow list if it passed and hasn't changed. + if !endpointChanged { + tr.moveToList(&tr.slow, n, now, &tab.rand) + } +} + +// moveToList ensures n is in the 'dest' list. +func (tr *tableRevalidation) moveToList(dest *revalidationList, n *tableNode, now mclock.AbsTime, rand randomSource) { + if n.revalList == dest { + return + } + if n.revalList != nil { + n.revalList.remove(n) + } + dest.push(n, now, rand) +} + +// revalidationList holds a list nodes and the next revalidation time. +type revalidationList struct { + nodes []*tableNode + nextTime mclock.AbsTime + interval time.Duration + name string +} + +// get returns a random node from the queue. Nodes in the 'exclude' map are not returned. +func (list *revalidationList) get(now mclock.AbsTime, rand randomSource, exclude map[enode.ID]struct{}) *tableNode { + if len(list.nodes) == 0 { + return nil + } + for i := 0; i < len(list.nodes)*3; i++ { + n := list.nodes[rand.Intn(len(list.nodes))] + _, excluded := exclude[n.ID()] + if !excluded { + return n + } + } + return nil +} + +func (list *revalidationList) schedule(now mclock.AbsTime, rand randomSource) { + list.nextTime = now.Add(time.Duration(rand.Int63n(int64(list.interval)))) +} + +func (list *revalidationList) push(n *tableNode, now mclock.AbsTime, rand randomSource) { + list.nodes = append(list.nodes, n) + if list.nextTime == never { + list.schedule(now, rand) + } + n.revalList = list +} + +func (list *revalidationList) remove(n *tableNode) { + i := slices.Index(list.nodes, n) + if i == -1 { + panic(fmt.Errorf("node %v not found in list", n.ID())) + } + list.nodes = slices.Delete(list.nodes, i, i+1) + if len(list.nodes) == 0 { + list.nextTime = never + } + n.revalList = nil +} + +func (list *revalidationList) contains(id enode.ID) bool { + return slices.ContainsFunc(list.nodes, func(n *tableNode) bool { + return n.ID() == id + }) +} diff --git a/p2p/discover/table_reval_test.go b/p2p/discover/table_reval_test.go new file mode 100644 index 0000000000..3605443934 --- /dev/null +++ b/p2p/discover/table_reval_test.go @@ -0,0 +1,119 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discover + +import ( + "net" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" +) + +// This test checks that revalidation can handle a node disappearing while +// a request is active. +func TestRevalidation_nodeRemoved(t *testing.T) { + var ( + clock mclock.Simulated + transport = newPingRecorder() + tab, db = newInactiveTestTable(transport, Config{Clock: &clock}) + tr = &tab.revalidation + ) + defer db.Close() + + // Add a node to the table. + node := nodeAtDistance(tab.self().ID(), 255, net.IP{77, 88, 99, 1}) + tab.handleAddNode(addNodeOp{node: node}) + + // Start a revalidation request. Schedule once to get the next start time, + // then advance the clock to that point and schedule again to start. + next := tr.run(tab, clock.Now()) + clock.Run(time.Duration(next + 1)) + tr.run(tab, clock.Now()) + if len(tr.activeReq) != 1 { + t.Fatal("revalidation request did not start:", tr.activeReq) + } + + // Delete the node. + tab.deleteInBucket(tab.bucket(node.ID()), node.ID()) + + // Now finish the revalidation request. + var resp revalidationResponse + select { + case resp = <-tab.revalResponseCh: + case <-time.After(1 * time.Second): + t.Fatal("timed out waiting for revalidation") + } + tr.handleResponse(tab, resp) + + // Ensure the node was not re-added to the table. + if tab.getNode(node.ID()) != nil { + t.Fatal("node was re-added to Table") + } + if tr.fast.contains(node.ID()) || tr.slow.contains(node.ID()) { + t.Fatal("removed node contained in revalidation list") + } +} + +// This test checks that nodes with an updated endpoint remain in the fast revalidation list. +func TestRevalidation_endpointUpdate(t *testing.T) { + var ( + clock mclock.Simulated + transport = newPingRecorder() + tab, db = newInactiveTestTable(transport, Config{Clock: &clock}) + tr = &tab.revalidation + ) + defer db.Close() + + // Add node to table. + node := nodeAtDistance(tab.self().ID(), 255, net.IP{77, 88, 99, 1}) + tab.handleAddNode(addNodeOp{node: node}) + + // Update the record in transport, including endpoint update. + record := node.Record() + record.Set(enr.IP{100, 100, 100, 100}) + record.Set(enr.UDP(9999)) + nodev2 := enode.SignNull(record, node.ID()) + transport.updateRecord(nodev2) + + // Start a revalidation request. Schedule once to get the next start time, + // then advance the clock to that point and schedule again to start. + next := tr.run(tab, clock.Now()) + clock.Run(time.Duration(next + 1)) + tr.run(tab, clock.Now()) + if len(tr.activeReq) != 1 { + t.Fatal("revalidation request did not start:", tr.activeReq) + } + + // Now finish the revalidation request. + var resp revalidationResponse + select { + case resp = <-tab.revalResponseCh: + case <-time.After(1 * time.Second): + t.Fatal("timed out waiting for revalidation") + } + tr.handleResponse(tab, resp) + + if tr.fast.nodes[0].ID() != node.ID() { + t.Fatal("node not contained in fast revalidation list") + } + if tr.fast.nodes[0].isValidatedLive { + t.Fatal("node is marked live after endpoint change") + } +} diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go index ffe055e843..a6666fdcbf 100644 --- a/p2p/discover/table_test.go +++ b/p2p/discover/table_test.go @@ -20,16 +20,19 @@ import ( "crypto/ecdsa" "fmt" "math/rand" - "net" "reflect" + "slices" "testing" "testing/quick" "time" + "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testlog" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/netutil" @@ -53,106 +56,109 @@ func TestTable_pingReplace(t *testing.T) { } func testPingReplace(t *testing.T, newNodeIsResponding, lastInBucketIsResponding bool) { + simclock := new(mclock.Simulated) transport := newPingRecorder() - tab, db := newTestTable(transport) + tab, db := newTestTable(transport, Config{ + Clock: simclock, + Log: testlog.Logger(t, log.LevelTrace), + }) defer db.Close() defer tab.close() <-tab.initDone // Fill up the sender's bucket. - pingKey, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") - pingSender := wrapNode(enode.NewV4(&pingKey.PublicKey, net.IP{127, 0, 0, 1}, 99, 99)) - last := fillBucket(tab, pingSender) + replacementNodeKey, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") + replacementNode := enode.NewV4(&replacementNodeKey.PublicKey, net.IP{127, 0, 0, 1}, 99, 99) + last := fillBucket(tab, replacementNode.ID()) + tab.mutex.Lock() + nodeEvents := newNodeEventRecorder(128) + tab.nodeAddedHook = nodeEvents.nodeAdded + tab.nodeRemovedHook = nodeEvents.nodeRemoved + tab.mutex.Unlock() - // Add the sender as if it just pinged us. Revalidate should replace the last node in - // its bucket if it is unresponsive. Revalidate again to ensure that + // The revalidation process should replace + // this node in the bucket if it is unresponsive. transport.dead[last.ID()] = !lastInBucketIsResponding - transport.dead[pingSender.ID()] = !newNodeIsResponding - tab.addSeenNodeSync(pingSender) - tab.doRevalidate(make(chan struct{}, 1)) - tab.doRevalidate(make(chan struct{}, 1)) - - if !transport.pinged[last.ID()] { - // Oldest node in bucket is pinged to see whether it is still alive. - t.Error("table did not ping last node in bucket") + transport.dead[replacementNode.ID()] = !newNodeIsResponding + + // Add replacement node to table. + tab.addFoundNode(replacementNode, false) + + t.Log("last:", last.ID()) + t.Log("replacement:", replacementNode.ID()) + + // Wait until the last node was pinged. + waitForRevalidationPing(t, transport, tab, last.ID()) + + if !lastInBucketIsResponding { + if !nodeEvents.waitNodeAbsent(last.ID(), 2*time.Second) { + t.Error("last node was not removed") + } + if !nodeEvents.waitNodePresent(replacementNode.ID(), 2*time.Second) { + t.Error("replacement node was not added") + } + + // If a replacement is expected, we also need to wait until the replacement node + // was pinged and added/removed. + waitForRevalidationPing(t, transport, tab, replacementNode.ID()) + if !newNodeIsResponding { + if !nodeEvents.waitNodeAbsent(replacementNode.ID(), 2*time.Second) { + t.Error("replacement node was not removed") + } + } } + // Check bucket content. tab.mutex.Lock() defer tab.mutex.Unlock() wantSize := bucketSize if !lastInBucketIsResponding && !newNodeIsResponding { wantSize-- } - if l := len(tab.bucket(pingSender.ID()).entries); l != wantSize { - t.Errorf("wrong bucket size after bond: got %d, want %d", l, wantSize) + bucket := tab.bucket(replacementNode.ID()) + if l := len(bucket.entries); l != wantSize { + t.Errorf("wrong bucket size after revalidation: got %d, want %d", l, wantSize) } - if found := contains(tab.bucket(pingSender.ID()).entries, last.ID()); found != lastInBucketIsResponding { - t.Errorf("last entry found: %t, want: %t", found, lastInBucketIsResponding) + if ok := containsID(bucket.entries, last.ID()); ok != lastInBucketIsResponding { + t.Errorf("revalidated node found: %t, want: %t", ok, lastInBucketIsResponding) } wantNewEntry := newNodeIsResponding && !lastInBucketIsResponding - if found := contains(tab.bucket(pingSender.ID()).entries, pingSender.ID()); found != wantNewEntry { - t.Errorf("new entry found: %t, want: %t", found, wantNewEntry) + if ok := containsID(bucket.entries, replacementNode.ID()); ok != wantNewEntry { + t.Errorf("replacement node found: %t, want: %t", ok, wantNewEntry) } } -func TestBucket_bumpNoDuplicates(t *testing.T) { - t.Parallel() - cfg := &quick.Config{ - MaxCount: 1000, - Rand: rand.New(rand.NewSource(time.Now().Unix())), - Values: func(args []reflect.Value, rand *rand.Rand) { - // generate a random list of nodes. this will be the content of the bucket. - n := rand.Intn(bucketSize-1) + 1 - nodes := make([]*node, n) - for i := range nodes { - nodes[i] = nodeAtDistance(enode.ID{}, 200, intIP(200)) - } - args[0] = reflect.ValueOf(nodes) - // generate random bump positions. - bumps := make([]int, rand.Intn(100)) - for i := range bumps { - bumps[i] = rand.Intn(len(nodes)) - } - args[1] = reflect.ValueOf(bumps) - }, - } - - prop := func(nodes []*node, bumps []int) (ok bool) { - tab, db := newTestTable(newPingRecorder()) - defer db.Close() - defer tab.close() +// waitForRevalidationPing waits until a PING message is sent to a node with the given id. +func waitForRevalidationPing(t *testing.T, transport *pingRecorder, tab *Table, id enode.ID) *enode.Node { + t.Helper() - b := &bucket{entries: make([]*node, len(nodes))} - copy(b.entries, nodes) - for i, pos := range bumps { - tab.bumpInBucket(b, b.entries[pos]) - if hasDuplicates(b.entries) { - t.Logf("bucket has duplicates after %d/%d bumps:", i+1, len(bumps)) - for _, n := range b.entries { - t.Logf(" %p", n) - } - return false - } + simclock := tab.cfg.Clock.(*mclock.Simulated) + maxAttempts := tab.len() * 8 + for i := 0; i < maxAttempts; i++ { + simclock.Run(tab.cfg.PingInterval * slowRevalidationFactor) + p := transport.waitPing(2 * time.Second) + if p == nil { + continue + } + if id == (enode.ID{}) || p.ID() == id { + return p } - checkIPLimitInvariant(t, tab) - return true - } - if err := quick.Check(prop, cfg); err != nil { - t.Error(err) } + t.Fatalf("Table did not ping node %v (%d attempts)", id, maxAttempts) + return nil } // This checks that the table-wide IP limit is applied correctly. func TestTable_IPLimit(t *testing.T) { transport := newPingRecorder() - tab, db := newTestTable(transport) + tab, db := newTestTable(transport, Config{}) defer db.Close() defer tab.close() for i := 0; i < tableIPLimit+1; i++ { n := nodeAtDistance(tab.self().ID(), i, net.IP{172, 0, 1, byte(i)}) - tab.addSeenNodeSync(n) + tab.addFoundNode(n, false) } if tab.len() > tableIPLimit { t.Errorf("too many nodes in table") @@ -163,14 +169,14 @@ func TestTable_IPLimit(t *testing.T) { // This checks that the per-bucket IP limit is applied correctly. func TestTable_BucketIPLimit(t *testing.T) { transport := newPingRecorder() - tab, db := newTestTable(transport) + tab, db := newTestTable(transport, Config{}) defer db.Close() defer tab.close() d := 3 for i := 0; i < bucketIPLimit+1; i++ { n := nodeAtDistance(tab.self().ID(), d, net.IP{172, 0, 1, byte(i)}) - tab.addSeenNode(n) + tab.addFoundNode(n, false) } if tab.len() > bucketIPLimit { t.Errorf("too many nodes in table") @@ -186,7 +192,7 @@ func checkIPLimitInvariant(t *testing.T, tab *Table) { tabset := netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit} for _, b := range tab.buckets { for _, n := range b.entries { - tabset.Add(n.IP()) + tabset.AddAddr(n.IPAddr()) } } if tabset.String() != tab.ips.String() { @@ -200,7 +206,7 @@ func TestTable_findnodeByID(t *testing.T) { test := func(test *closeTest) bool { // for any node table, Target and N transport := newPingRecorder() - tab, db := newTestTable(transport) + tab, db := newTestTable(transport, Config{}) defer db.Close() defer tab.close() fillTable(tab, test.All, true) @@ -231,7 +237,7 @@ func TestTable_findnodeByID(t *testing.T) { // check that the result nodes have minimum distance to target. for _, b := range tab.buckets { for _, n := range b.entries { - if contains(result, n.ID()) { + if containsID(result, n.ID()) { continue // don't run the check below for nodes in result } farthestResult := result[len(result)-1].ID() @@ -254,7 +260,7 @@ func TestTable_findnodeByID(t *testing.T) { type closeTest struct { Self enode.ID Target enode.ID - All []*node + All []*enode.Node N int } @@ -266,16 +272,15 @@ func (*closeTest) Generate(rand *rand.Rand, size int) reflect.Value { } for _, id := range gen([]enode.ID{}, rand).([]enode.ID) { r := new(enr.Record) - r.Set(enr.IP(genIP(rand))) - n := wrapNode(enode.SignNull(r, id)) - n.livenessChecks = 1 + r.Set(enr.IPv4Addr(netutil.RandomAddr(rand, true))) + n := enode.SignNull(r, id) t.All = append(t.All, n) } return reflect.ValueOf(t) } -func TestTable_addVerifiedNode(t *testing.T) { - tab, db := newTestTable(newPingRecorder()) +func TestTable_addInboundNode(t *testing.T) { + tab, db := newTestTable(newPingRecorder(), Config{}) <-tab.initDone defer db.Close() defer tab.close() @@ -283,31 +288,29 @@ func TestTable_addVerifiedNode(t *testing.T) { // Insert two nodes. n1 := nodeAtDistance(tab.self().ID(), 256, net.IP{88, 77, 66, 1}) n2 := nodeAtDistance(tab.self().ID(), 256, net.IP{88, 77, 66, 2}) - tab.addSeenNodeSync(n1) - tab.addSeenNodeSync(n2) + tab.addFoundNode(n1, false) + tab.addFoundNode(n2, false) + checkBucketContent(t, tab, []*enode.Node{n1, n2}) - // Verify bucket content: - bcontent := []*node{n1, n2} - if !reflect.DeepEqual(tab.bucket(n1.ID()).entries, bcontent) { - t.Fatalf("wrong bucket content: %v", tab.bucket(n1.ID()).entries) - } - - // Add a changed version of n2. + // Add a changed version of n2. The bucket should be updated. newrec := n2.Record() newrec.Set(enr.IP{99, 99, 99, 99}) - newn2 := wrapNode(enode.SignNull(newrec, n2.ID())) - tab.addVerifiedNodeSync(newn2) - - // Check that bucket is updated correctly. - newBcontent := []*node{newn2, n1} - if !reflect.DeepEqual(tab.bucket(n1.ID()).entries, newBcontent) { - t.Fatalf("wrong bucket content after update: %v", tab.bucket(n1.ID()).entries) - } - checkIPLimitInvariant(t, tab) + n2v2 := enode.SignNull(newrec, n2.ID()) + tab.addInboundNode(n2v2) + checkBucketContent(t, tab, []*enode.Node{n1, n2v2}) + + // Try updating n2 without sequence number change. The update is accepted + // because it's inbound. + newrec = n2.Record() + newrec.Set(enr.IP{100, 100, 100, 100}) + newrec.SetSeq(n2.Seq()) + n2v3 := enode.SignNull(newrec, n2.ID()) + tab.addInboundNode(n2v3) + checkBucketContent(t, tab, []*enode.Node{n1, n2v3}) } -func TestTable_addSeenNode(t *testing.T) { - tab, db := newTestTable(newPingRecorder()) +func TestTable_addFoundNode(t *testing.T) { + tab, db := newTestTable(newPingRecorder(), Config{}) <-tab.initDone defer db.Close() defer tab.close() @@ -315,25 +318,86 @@ func TestTable_addSeenNode(t *testing.T) { // Insert two nodes. n1 := nodeAtDistance(tab.self().ID(), 256, net.IP{88, 77, 66, 1}) n2 := nodeAtDistance(tab.self().ID(), 256, net.IP{88, 77, 66, 2}) - tab.addSeenNodeSync(n1) - tab.addSeenNodeSync(n2) - - // Verify bucket content: - bcontent := []*node{n1, n2} - if !reflect.DeepEqual(tab.bucket(n1.ID()).entries, bcontent) { - t.Fatalf("wrong bucket content: %v", tab.bucket(n1.ID()).entries) - } + tab.addFoundNode(n1, false) + tab.addFoundNode(n2, false) + checkBucketContent(t, tab, []*enode.Node{n1, n2}) - // Add a changed version of n2. + // Add a changed version of n2. The bucket should be updated. newrec := n2.Record() newrec.Set(enr.IP{99, 99, 99, 99}) - newn2 := wrapNode(enode.SignNull(newrec, n2.ID())) - tab.addSeenNodeSync(newn2) + n2v2 := enode.SignNull(newrec, n2.ID()) + tab.addFoundNode(n2v2, false) + checkBucketContent(t, tab, []*enode.Node{n1, n2v2}) + + // Try updating n2 without a sequence number change. + // The update should not be accepted. + newrec = n2.Record() + newrec.Set(enr.IP{100, 100, 100, 100}) + newrec.SetSeq(n2.Seq()) + n2v3 := enode.SignNull(newrec, n2.ID()) + tab.addFoundNode(n2v3, false) + checkBucketContent(t, tab, []*enode.Node{n1, n2v2}) +} - // Check that bucket content is unchanged. - if !reflect.DeepEqual(tab.bucket(n1.ID()).entries, bcontent) { - t.Fatalf("wrong bucket content after update: %v", tab.bucket(n1.ID()).entries) +// This test checks that discv4 nodes can update their own endpoint via PING. +func TestTable_addInboundNodeUpdateV4Accept(t *testing.T) { + tab, db := newTestTable(newPingRecorder(), Config{}) + <-tab.initDone + defer db.Close() + defer tab.close() + + // Add a v4 node. + key, _ := crypto.HexToECDSA("dd3757a8075e88d0f2b1431e7d3c5b1562e1c0aab9643707e8cbfcc8dae5cfe3") + n1 := enode.NewV4(&key.PublicKey, net.IP{88, 77, 66, 1}, 9000, 9000) + tab.addInboundNode(n1) + checkBucketContent(t, tab, []*enode.Node{n1}) + + // Add an updated version with changed IP. + // The update will be accepted because it is inbound. + n1v2 := enode.NewV4(&key.PublicKey, net.IP{99, 99, 99, 99}, 9000, 9000) + tab.addInboundNode(n1v2) + checkBucketContent(t, tab, []*enode.Node{n1v2}) +} + +// This test checks that discv4 node entries will NOT be updated when a +// changed record is found. +func TestTable_addFoundNodeV4UpdateReject(t *testing.T) { + tab, db := newTestTable(newPingRecorder(), Config{}) + <-tab.initDone + defer db.Close() + defer tab.close() + + // Add a v4 node. + key, _ := crypto.HexToECDSA("dd3757a8075e88d0f2b1431e7d3c5b1562e1c0aab9643707e8cbfcc8dae5cfe3") + n1 := enode.NewV4(&key.PublicKey, net.IP{88, 77, 66, 1}, 9000, 9000) + tab.addFoundNode(n1, false) + checkBucketContent(t, tab, []*enode.Node{n1}) + + // Add an updated version with changed IP. + // The update won't be accepted because it isn't inbound. + n1v2 := enode.NewV4(&key.PublicKey, net.IP{99, 99, 99, 99}, 9000, 9000) + tab.addFoundNode(n1v2, false) + checkBucketContent(t, tab, []*enode.Node{n1}) +} + +func checkBucketContent(t *testing.T, tab *Table, nodes []*enode.Node) { + t.Helper() + + b := tab.bucket(nodes[0].ID()) + if reflect.DeepEqual(unwrapNodes(b.entries), nodes) { + return + } + t.Log("wrong bucket content. have nodes:") + for _, n := range b.entries { + t.Logf(" %v (seq=%v, ip=%v)", n.ID(), n.Seq(), n.IPAddr()) } + t.Log("want nodes:") + for _, n := range nodes { + t.Logf(" %v (seq=%v, ip=%v)", n.ID(), n.Seq(), n.IPAddr()) + } + t.FailNow() + + // Also check IP limits. checkIPLimitInvariant(t, tab) } @@ -341,7 +405,10 @@ func TestTable_addSeenNode(t *testing.T) { // announces a new sequence number, the new record should be pulled. func TestTable_revalidateSyncRecord(t *testing.T) { transport := newPingRecorder() - tab, db := newTestTable(transport) + tab, db := newTestTable(transport, Config{ + Clock: new(mclock.Simulated), + Log: testlog.Logger(t, log.LevelTrace), + }) <-tab.initDone defer db.Close() defer tab.close() @@ -350,15 +417,19 @@ func TestTable_revalidateSyncRecord(t *testing.T) { var r enr.Record r.Set(enr.IP(net.IP{127, 0, 0, 1})) id := enode.ID{1} - n1 := wrapNode(enode.SignNull(&r, id)) - tab.addSeenNodeSync(n1) + n1 := enode.SignNull(&r, id) + tab.addFoundNode(n1, false) // Update the node record. r.Set(enr.WithEntry("foo", "bar")) n2 := enode.SignNull(&r, id) transport.updateRecord(n2) - tab.doRevalidate(make(chan struct{}, 1)) + // Wait for revalidation. We wait for the node to be revalidated two times + // in order to synchronize with the update in the table. + waitForRevalidationPing(t, transport, tab, n2.ID()) + waitForRevalidationPing(t, transport, tab, n2.ID()) + intable := tab.getNode(id) if !reflect.DeepEqual(intable, n2) { t.Fatalf("table contains old record with seq %d, want seq %d", intable.Seq(), n2.Seq()) @@ -400,6 +471,47 @@ func TestTable_filterNode(t *testing.T) { t.Logf("Check correct genesis ENR record - passed") } +func TestNodesPush(t *testing.T) { + var target enode.ID + n1 := nodeAtDistance(target, 255, intIP(1)) + n2 := nodeAtDistance(target, 254, intIP(2)) + n3 := nodeAtDistance(target, 253, intIP(3)) + perm := [][]*enode.Node{ + {n3, n2, n1}, + {n3, n1, n2}, + {n2, n3, n1}, + {n2, n1, n3}, + {n1, n3, n2}, + {n1, n2, n3}, + } + + // Insert all permutations into lists with size limit 3. + for _, nodes := range perm { + list := nodesByDistance{target: target} + for _, n := range nodes { + list.push(n, 3) + } + if !slices.EqualFunc(list.entries, perm[0], nodeIDEqual) { + t.Fatal("not equal") + } + } + + // Insert all permutations into lists with size limit 2. + for _, nodes := range perm { + list := nodesByDistance{target: target} + for _, n := range nodes { + list.push(n, 2) + } + if !slices.EqualFunc(list.entries, perm[0][:2], nodeIDEqual) { + t.Fatal("not equal") + } + } +} + +func nodeIDEqual[N nodeType](n1, n2 N) bool { + return n1.ID() == n2.ID() +} + // gen wraps quick.Value so it's easier to use. // it generates a random value of the given value's type. func gen(typ interface{}, rand *rand.Rand) interface{} { @@ -410,12 +522,6 @@ func gen(typ interface{}, rand *rand.Rand) interface{} { return v.Interface() } -func genIP(rand *rand.Rand) net.IP { - ip := make(net.IP, 4) - rand.Read(ip) - return ip -} - func quickcfg() *quick.Config { return &quick.Config{ MaxCount: 5000, diff --git a/p2p/discover/table_util_test.go b/p2p/discover/table_util_test.go index 0ac25f957c..fe10883fe6 100644 --- a/p2p/discover/table_util_test.go +++ b/p2p/discover/table_util_test.go @@ -24,13 +24,15 @@ import ( "fmt" "math/rand" "net" + "slices" "sync" + "sync/atomic" + "time" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover/v4wire" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "golang.org/x/exp/slices" ) var nullNode *enode.Node @@ -41,27 +43,32 @@ func init() { nullNode = enode.SignNull(&r, enode.ID{}) } -func newTestTable(t transport) (*Table, *enode.DB) { - cfg := Config{Log: log.Root()} +func newTestTable(t transport, cfg Config) (*Table, *enode.DB) { + tab, db := newInactiveTestTable(t, cfg) + go tab.loop() + return tab, db +} + +// newInactiveTestTable creates a Table without running the main loop. +func newInactiveTestTable(t transport, cfg Config) (*Table, *enode.DB) { db, _ := enode.OpenDB("") tab, _ := newTable(t, db, cfg) - go tab.loop() return tab, db } // nodeAtDistance creates a node for which enode.LogDist(base, n.id) == ld. -func nodeAtDistance(base enode.ID, ld int, ip net.IP) *node { +func nodeAtDistance(base enode.ID, ld int, ip net.IP) *enode.Node { var r enr.Record r.Set(enr.IP(ip)) r.Set(enr.UDP(30303)) - return wrapNode(enode.SignNull(&r, idAtDistance(base, ld))) + return enode.SignNull(&r, idAtDistance(base, ld)) } // nodesAtDistance creates n nodes for which enode.LogDist(base, node.ID()) == ld. func nodesAtDistance(base enode.ID, ld int, n int) []*enode.Node { results := make([]*enode.Node, n) for i := range results { - results[i] = unwrapNode(nodeAtDistance(base, ld, intIP(i))) + results[i] = nodeAtDistance(base, ld, intIP(i)) } return results } @@ -94,36 +101,39 @@ func idAtDistance(a enode.ID, n int) (b enode.ID) { return b } +// intIP returns a LAN IP address based on i. func intIP(i int) net.IP { - return net.IP{byte(i), 0, 2, byte(i)} + return net.IP{10, 0, byte(i >> 8), byte(i & 0xFF)} } // fillBucket inserts nodes into the given bucket until it is full. -func fillBucket(tab *Table, n *node) (last *node) { - ld := enode.LogDist(tab.self().ID(), n.ID()) - b := tab.bucket(n.ID()) +func fillBucket(tab *Table, id enode.ID) (last *tableNode) { + ld := enode.LogDist(tab.self().ID(), id) + b := tab.bucket(id) for len(b.entries) < bucketSize { - b.entries = append(b.entries, nodeAtDistance(tab.self().ID(), ld, intIP(ld))) + node := nodeAtDistance(tab.self().ID(), ld, intIP(ld)) + if !tab.addFoundNode(node, false) { + panic("node not added") + } } return b.entries[bucketSize-1] } // fillTable adds nodes the table to the end of their corresponding bucket // if the bucket is not full. The caller must not hold tab.mutex. -func fillTable(tab *Table, nodes []*node, setLive bool) { +func fillTable(tab *Table, nodes []*enode.Node, setLive bool) { for _, n := range nodes { - if setLive { - n.livenessChecks = 1 - } - tab.addSeenNodeSync(n) + tab.addFoundNode(n, setLive) } } type pingRecorder struct { - mu sync.Mutex - dead, pinged map[enode.ID]bool - records map[enode.ID]*enode.Node - n *enode.Node + mu sync.Mutex + cond *sync.Cond + dead map[enode.ID]bool + records map[enode.ID]*enode.Node + pinged []*enode.Node + n *enode.Node } func newPingRecorder() *pingRecorder { @@ -131,12 +141,13 @@ func newPingRecorder() *pingRecorder { r.Set(enr.IP{0, 0, 0, 0}) n := enode.SignNull(&r, enode.ID{}) - return &pingRecorder{ + t := &pingRecorder{ dead: make(map[enode.ID]bool), - pinged: make(map[enode.ID]bool), records: make(map[enode.ID]*enode.Node), n: n, } + t.cond = sync.NewCond(&t.mu) + return t } // updateRecord updates a node record. Future calls to ping and @@ -152,12 +163,40 @@ func (t *pingRecorder) Self() *enode.Node { return nullNode } func (t *pingRecorder) lookupSelf() []*enode.Node { return nil } func (t *pingRecorder) lookupRandom() []*enode.Node { return nil } +func (t *pingRecorder) waitPing(timeout time.Duration) *enode.Node { + t.mu.Lock() + defer t.mu.Unlock() + + // Wake up the loop on timeout. + var timedout atomic.Bool + timer := time.AfterFunc(timeout, func() { + timedout.Store(true) + t.cond.Broadcast() + }) + defer timer.Stop() + + // Wait for a ping. + for { + if timedout.Load() { + return nil + } + if len(t.pinged) > 0 { + n := t.pinged[0] + t.pinged = append(t.pinged[:0], t.pinged[1:]...) + return n + } + t.cond.Wait() + } +} + // ping simulates a ping request. func (t *pingRecorder) ping(n *enode.Node) (seq uint64, err error) { t.mu.Lock() defer t.mu.Unlock() - t.pinged[n.ID()] = true + t.pinged = append(t.pinged, n) + t.cond.Broadcast() + if t.dead[n.ID()] { return 0, errTimeout } @@ -178,7 +217,7 @@ func (t *pingRecorder) RequestENR(n *enode.Node) (*enode.Node, error) { return t.records[n.ID()], nil } -func hasDuplicates(slice []*node) bool { +func hasDuplicates(slice []*enode.Node) bool { seen := make(map[enode.ID]bool, len(slice)) for i, e := range slice { if e == nil { @@ -217,17 +256,17 @@ NotEqual: } func nodeEqual(n1 *enode.Node, n2 *enode.Node) bool { - return n1.ID() == n2.ID() && n1.IP().Equal(n2.IP()) + return n1.ID() == n2.ID() && n1.IPAddr() == n2.IPAddr() } -func sortByID(nodes []*enode.Node) { - slices.SortFunc(nodes, func(a, b *enode.Node) int { +func sortByID[N nodeType](nodes []N) { + slices.SortFunc(nodes, func(a, b N) int { return bytes.Compare(a.ID().Bytes(), b.ID().Bytes()) }) } -func sortedByDistanceTo(distbase enode.ID, slice []*node) bool { - return slices.IsSortedFunc(slice, func(a, b *node) int { +func sortedByDistanceTo(distbase enode.ID, slice []*enode.Node) bool { + return slices.IsSortedFunc(slice, func(a, b *enode.Node) int { return enode.DistCmp(distbase, a.ID(), b.ID()) }) } @@ -246,7 +285,7 @@ func hexEncPrivkey(h string) *ecdsa.PrivateKey { } // hexEncPubkey decodes h as a public key. -func hexEncPubkey(h string) (ret encPubkey) { +func hexEncPubkey(h string) (ret v4wire.Pubkey) { b, err := hex.DecodeString(h) if err != nil { panic(err) @@ -257,3 +296,57 @@ func hexEncPubkey(h string) (ret encPubkey) { copy(ret[:], b) return ret } + +type nodeEventRecorder struct { + evc chan recordedNodeEvent +} + +type recordedNodeEvent struct { + node *tableNode + added bool +} + +func newNodeEventRecorder(buffer int) *nodeEventRecorder { + return &nodeEventRecorder{ + evc: make(chan recordedNodeEvent, buffer), + } +} + +func (set *nodeEventRecorder) nodeAdded(b *bucket, n *tableNode) { + select { + case set.evc <- recordedNodeEvent{n, true}: + default: + panic("no space in event buffer") + } +} + +func (set *nodeEventRecorder) nodeRemoved(b *bucket, n *tableNode) { + select { + case set.evc <- recordedNodeEvent{n, false}: + default: + panic("no space in event buffer") + } +} + +func (set *nodeEventRecorder) waitNodePresent(id enode.ID, timeout time.Duration) bool { + return set.waitNodeEvent(id, timeout, true) +} + +func (set *nodeEventRecorder) waitNodeAbsent(id enode.ID, timeout time.Duration) bool { + return set.waitNodeEvent(id, timeout, false) +} + +func (set *nodeEventRecorder) waitNodeEvent(id enode.ID, timeout time.Duration, added bool) bool { + timer := time.NewTimer(timeout) + defer timer.Stop() + for { + select { + case ev := <-set.evc: + if ev.node.ID() == id && ev.added == added { + return true + } + case <-timer.C: + return false + } + } +} diff --git a/p2p/discover/v4_lookup_test.go b/p2p/discover/v4_lookup_test.go index 8867a5a8ac..29a9dd6645 100644 --- a/p2p/discover/v4_lookup_test.go +++ b/p2p/discover/v4_lookup_test.go @@ -19,14 +19,15 @@ package discover import ( "crypto/ecdsa" "fmt" - "net" + "net/netip" + "slices" + "sync" "testing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/discover/v4wire" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "golang.org/x/exp/slices" ) func TestUDPv4_Lookup(t *testing.T) { @@ -34,13 +35,13 @@ func TestUDPv4_Lookup(t *testing.T) { test := newUDPTest(t) // Lookup on empty table returns no nodes. - targetKey, _ := decodePubkey(crypto.S256(), lookupTestnet.target[:]) + targetKey, _ := v4wire.DecodePubkey(crypto.S256(), lookupTestnet.target) if results := test.udp.LookupPubkey(targetKey); len(results) > 0 { t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results) } // Seed table with initial node. - fillTable(test.table, []*node{wrapNode(lookupTestnet.node(256, 0))}, true) + fillTable(test.table, []*enode.Node{lookupTestnet.node(256, 0)}, true) // Start the lookup. resultC := make(chan []*enode.Node, 1) @@ -56,7 +57,7 @@ func TestUDPv4_Lookup(t *testing.T) { results := <-resultC t.Logf("results:") for _, e := range results { - t.Logf(" ld=%d, %x", enode.LogDist(lookupTestnet.target.id(), e.ID()), e.ID().Bytes()) + t.Logf(" ld=%d, %x", enode.LogDist(lookupTestnet.target.ID(), e.ID()), e.ID().Bytes()) } if len(results) != bucketSize { t.Errorf("wrong number of results: got %d, want %d", len(results), bucketSize) @@ -67,15 +68,23 @@ func TestUDPv4_Lookup(t *testing.T) { func TestUDPv4_LookupIterator(t *testing.T) { t.Parallel() test := newUDPTest(t) - defer test.close() + var wg sync.WaitGroup + defer func() { + test.close() + wg.Wait() + }() // Seed table with initial nodes. - bootnodes := make([]*node, len(lookupTestnet.dists[256])) + bootnodes := make([]*enode.Node, len(lookupTestnet.dists[256])) for i := range lookupTestnet.dists[256] { - bootnodes[i] = wrapNode(lookupTestnet.node(256, i)) + bootnodes[i] = lookupTestnet.node(256, i) } fillTable(test.table, bootnodes, true) - go serveTestnet(test, lookupTestnet) + wg.Add(1) + go func() { + serveTestnet(test, lookupTestnet) + wg.Done() + }() // Create the iterator and collect the nodes it yields. iter := test.udp.RandomNodes() @@ -102,15 +111,24 @@ func TestUDPv4_LookupIterator(t *testing.T) { func TestUDPv4_LookupIteratorClose(t *testing.T) { t.Parallel() test := newUDPTest(t) - defer test.close() + var wg sync.WaitGroup + defer func() { + test.close() + wg.Wait() + }() // Seed table with initial nodes. - bootnodes := make([]*node, len(lookupTestnet.dists[256])) + bootnodes := make([]*enode.Node, len(lookupTestnet.dists[256])) for i := range lookupTestnet.dists[256] { - bootnodes[i] = wrapNode(lookupTestnet.node(256, i)) + bootnodes[i] = lookupTestnet.node(256, i) } fillTable(test.table, bootnodes, true) - go serveTestnet(test, lookupTestnet) + + wg.Add(1) + go func() { + serveTestnet(test, lookupTestnet) + wg.Done() + }() it := test.udp.RandomNodes() if ok := it.Next(); !ok || it.Node() == nil { @@ -136,13 +154,13 @@ func TestUDPv4_LookupIteratorClose(t *testing.T) { func serveTestnet(test *udpTest, testnet *preminedTestnet) { for done := false; !done; { - done = test.waitPacketOut(func(p v4wire.Packet, to *net.UDPAddr, hash []byte) { + done = test.waitPacketOut(func(p v4wire.Packet, to netip.AddrPort, hash []byte) { n, key := testnet.nodeByAddr(to) switch p.(type) { case *v4wire.Ping: test.packetInFrom(nil, key, to, &v4wire.Pong{Expiration: futureExp, ReplyTok: hash}) case *v4wire.Findnode: - dist := enode.LogDist(n.ID(), testnet.target.id()) + dist := enode.LogDist(n.ID(), testnet.target.ID()) nodes := testnet.nodesAtDistance(dist - 1) test.packetInFrom(nil, key, to, &v4wire.Neighbors{Expiration: futureExp, Nodes: nodes}) } @@ -156,12 +174,12 @@ func checkLookupResults(t *testing.T, tn *preminedTestnet, results []*enode.Node t.Helper() t.Logf("results:") for _, e := range results { - t.Logf(" ld=%d, %x", enode.LogDist(tn.target.id(), e.ID()), e.ID().Bytes()) + t.Logf(" ld=%d, %x", enode.LogDist(tn.target.ID(), e.ID()), e.ID().Bytes()) } - if hasDuplicates(wrapNodes(results)) { + if hasDuplicates(results) { t.Errorf("result set contains duplicate entries") } - if !sortedByDistanceTo(tn.target.id(), wrapNodes(results)) { + if !sortedByDistanceTo(tn.target.ID(), results) { t.Errorf("result set not sorted by distance to target") } wantNodes := tn.closest(len(results)) @@ -231,7 +249,7 @@ var lookupTestnet = &preminedTestnet{ } type preminedTestnet struct { - target encPubkey + target v4wire.Pubkey dists [hashBits + 1][]*ecdsa.PrivateKey } @@ -264,9 +282,10 @@ func (tn *preminedTestnet) node(dist, index int) *enode.Node { return n } -func (tn *preminedTestnet) nodeByAddr(addr *net.UDPAddr) (*enode.Node, *ecdsa.PrivateKey) { - dist := int(addr.IP[1])<<8 + int(addr.IP[2]) - index := int(addr.IP[3]) +func (tn *preminedTestnet) nodeByAddr(addr netip.AddrPort) (*enode.Node, *ecdsa.PrivateKey) { + ip := addr.Addr().As4() + dist := int(ip[1])<<8 + int(ip[2]) + index := int(ip[3]) key := tn.dists[dist][index] return tn.node(dist, index), key } @@ -274,7 +293,7 @@ func (tn *preminedTestnet) nodeByAddr(addr *net.UDPAddr) (*enode.Node, *ecdsa.Pr func (tn *preminedTestnet) nodesAtDistance(dist int) []v4wire.Node { result := make([]v4wire.Node, len(tn.dists[dist])) for i := range result { - result[i] = nodeToRPC(wrapNode(tn.node(dist, i))) + result[i] = nodeToRPC(tn.node(dist, i)) } return result } @@ -285,7 +304,7 @@ func (tn *preminedTestnet) neighborsAtDistances(base *enode.Node, distances []ui for i := range lookupTestnet.dists[d] { n := lookupTestnet.node(d, i) d := enode.LogDist(base.ID(), n.ID()) - if containsUint(uint(d), distances) { + if slices.Contains(distances, uint(d)) { result = append(result, n) if len(result) >= elems { return result @@ -303,7 +322,7 @@ func (tn *preminedTestnet) closest(n int) (nodes []*enode.Node) { } } slices.SortFunc(nodes, func(a, b *enode.Node) int { - return enode.DistCmp(tn.target.id(), a.ID(), b.ID()) + return enode.DistCmp(tn.target.ID(), a.ID(), b.ID()) }) return nodes[:n] } @@ -318,11 +337,11 @@ func (tn *preminedTestnet) mine() { tn.dists[i] = nil } - targetSha := tn.target.id() + targetSha := tn.target.ID() found, need := 0, 40 for found < need { k := newkey() - ld := enode.LogDist(targetSha, encodePubkey(&k.PublicKey).id()) + ld := enode.LogDist(targetSha, v4wire.EncodePubkey(&k.PublicKey).ID()) if len(tn.dists[ld]) < 8 { tn.dists[ld] = append(tn.dists[ld], k) found++ diff --git a/p2p/discover/v4_udp.go b/p2p/discover/v4_udp.go index 6312821e0d..95cbe13abd 100644 --- a/p2p/discover/v4_udp.go +++ b/p2p/discover/v4_udp.go @@ -25,7 +25,7 @@ import ( "errors" "fmt" "io" - "net" + "net/netip" "sync" "time" @@ -46,6 +46,7 @@ var ( errClockWarp = errors.New("reply deadline too far in the future") errClosed = errors.New("socket closed") errLowPort = errors.New("low port") + errNoUDPEndpoint = errors.New("node has no UDP endpoint") ) const ( @@ -94,7 +95,7 @@ type UDPv4 struct { type replyMatcher struct { // these fields must match in the reply. from enode.ID - ip net.IP + ip netip.Addr ptype byte // time when the request must complete @@ -120,7 +121,7 @@ type replyMatchFunc func(v4wire.Packet) (matched bool, requestDone bool) // reply is a reply packet from a certain node. type reply struct { from enode.ID - ip net.IP + ip netip.Addr data v4wire.Packet // loop indicates whether there was // a matching request by sending on this channel. @@ -143,7 +144,7 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { log: cfg.Log, } - tab, err := newMeteredTable(t, ln.Database(), cfg) + tab, err := newTable(t, ln.Database(), cfg) if err != nil { return nil, err } @@ -202,9 +203,12 @@ func (t *UDPv4) Resolve(n *enode.Node) *enode.Node { } func (t *UDPv4) ourEndpoint() v4wire.Endpoint { - n := t.Self() - a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} - return v4wire.NewEndpoint(a, uint16(n.TCP())) + node := t.Self() + addr, ok := node.UDPEndpoint() + if !ok { + return v4wire.Endpoint{} + } + return v4wire.NewEndpoint(addr, uint16(node.TCP())) } // Ping sends a ping message to the given node. @@ -215,7 +219,11 @@ func (t *UDPv4) Ping(n *enode.Node) error { // ping sends a ping message to the given node and waits for a reply. func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) { - rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil) + addr, ok := n.UDPEndpoint() + if !ok { + return 0, errNoUDPEndpoint + } + rm := t.sendPing(n.ID(), addr, nil) if err = <-rm.errc; err == nil { seq = rm.reply.(*v4wire.Pong).ENRSeq } @@ -224,7 +232,7 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) { // sendPing sends a ping message to the given node and invokes the callback // when the reply arrives. -func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher { +func (t *UDPv4) sendPing(toid enode.ID, toaddr netip.AddrPort, callback func()) *replyMatcher { req := t.makePing(toaddr) packet, hash, err := v4wire.Encode(t.priv, req) if err != nil { @@ -234,7 +242,7 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r } // Add a matcher for the reply to the pending reply queue. Pongs are matched if they // reference the ping we're about to send. - rm := t.pending(toid, toaddr.IP, v4wire.PongPacket, func(p v4wire.Packet) (matched bool, requestDone bool) { + rm := t.pending(toid, toaddr.Addr(), v4wire.PongPacket, func(p v4wire.Packet) (matched bool, requestDone bool) { matched = bytes.Equal(p.(*v4wire.Pong).ReplyTok, hash) if matched && callback != nil { callback() @@ -247,7 +255,7 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r return rm } -func (t *UDPv4) makePing(toaddr *net.UDPAddr) *v4wire.Ping { +func (t *UDPv4) makePing(toaddr netip.AddrPort) *v4wire.Ping { return &v4wire.Ping{ Version: 4, From: t.ourEndpoint(), @@ -264,7 +272,7 @@ func (t *UDPv4) LookupPubkey(key *ecdsa.PublicKey) []*enode.Node { // case and run the bootstrapping logic. <-t.tab.refresh() } - return t.newLookup(t.closeCtx, encodePubkey(key)).run() + return t.newLookup(t.closeCtx, v4wire.EncodePubkey(key)).run() } // RandomNodes is an iterator yielding nodes from a random walk of the DHT. @@ -279,47 +287,51 @@ func (t *UDPv4) lookupRandom() []*enode.Node { // lookupSelf implements transport. func (t *UDPv4) lookupSelf() []*enode.Node { - return t.newLookup(t.closeCtx, encodePubkey(&t.priv.PublicKey)).run() + pubkey := v4wire.EncodePubkey(&t.priv.PublicKey) + return t.newLookup(t.closeCtx, pubkey).run() } func (t *UDPv4) newRandomLookup(ctx context.Context) *lookup { - var target encPubkey + var target v4wire.Pubkey crand.Read(target[:]) return t.newLookup(ctx, target) } -func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup { +func (t *UDPv4) newLookup(ctx context.Context, targetKey v4wire.Pubkey) *lookup { target := enode.ID(crypto.Keccak256Hash(targetKey[:])) - ekey := v4wire.Pubkey(targetKey) - it := newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) { - return t.findnode(n.ID(), n.addr(), ekey) + it := newLookup(ctx, t.tab, target, func(n *enode.Node) ([]*enode.Node, error) { + addr, ok := n.UDPEndpoint() + if !ok { + return nil, errNoUDPEndpoint + } + return t.findnode(n.ID(), addr, targetKey) }) return it } // findnode sends a findnode request to the given node and waits until // the node has sent up to k neighbors. -func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubkey) ([]*node, error) { - t.ensureBond(toid, toaddr) +func (t *UDPv4) findnode(toid enode.ID, toAddrPort netip.AddrPort, target v4wire.Pubkey) ([]*enode.Node, error) { + t.ensureBond(toid, toAddrPort) // Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is // active until enough nodes have been received. - nodes := make([]*node, 0, bucketSize) + nodes := make([]*enode.Node, 0, bucketSize) nreceived := 0 - rm := t.pending(toid, toaddr.IP, v4wire.NeighborsPacket, func(r v4wire.Packet) (matched bool, requestDone bool) { + rm := t.pending(toid, toAddrPort.Addr(), v4wire.NeighborsPacket, func(r v4wire.Packet) (matched bool, requestDone bool) { reply := r.(*v4wire.Neighbors) for _, rn := range reply.Nodes { nreceived++ - n, err := t.nodeFromRPC(toaddr, rn) + n, err := t.nodeFromRPC(toAddrPort, rn) if err != nil { - t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err) + t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toAddrPort, "err", err) continue } nodes = append(nodes, n) } return true, nreceived >= bucketSize }) - t.send(toaddr, toid, &v4wire.Findnode{ + t.send(toAddrPort, toid, &v4wire.Findnode{ Target: target, Expiration: uint64(time.Now().Add(expiration).Unix()), }) @@ -337,7 +349,7 @@ func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubke // RequestENR sends ENRRequest to the given node and waits for a response. func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { - addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} + addr, _ := n.UDPEndpoint() t.ensureBond(n.ID(), addr) req := &v4wire.ENRRequest{ @@ -350,7 +362,7 @@ func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { // Add a matcher for the reply to the pending reply queue. Responses are matched if // they reference the request we're about to send. - rm := t.pending(n.ID(), addr.IP, v4wire.ENRResponsePacket, func(r v4wire.Packet) (matched bool, requestDone bool) { + rm := t.pending(n.ID(), addr.Addr(), v4wire.ENRResponsePacket, func(r v4wire.Packet) (matched bool, requestDone bool) { matched = bytes.Equal(r.(*v4wire.ENRResponse).ReplyTok, hash) return matched, matched }) @@ -370,15 +382,19 @@ func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { if respN.Seq() < n.Seq() { return n, nil // response record is older } - if err := netutil.CheckRelayIP(addr.IP, respN.IP()); err != nil { + if err := netutil.CheckRelayAddr(addr.Addr(), respN.IPAddr()); err != nil { return nil, fmt.Errorf("invalid IP in response record: %v", err) } return respN, nil } +func (t *UDPv4) TableBuckets() [][]BucketNode { + return t.tab.Nodes() +} + // pending adds a reply matcher to the pending reply queue. // see the documentation of type replyMatcher for a detailed explanation. -func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchFunc) *replyMatcher { +func (t *UDPv4) pending(id enode.ID, ip netip.Addr, ptype byte, callback replyMatchFunc) *replyMatcher { ch := make(chan error, 1) p := &replyMatcher{from: id, ip: ip, ptype: ptype, callback: callback, errc: ch} select { @@ -392,7 +408,7 @@ func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchF // handleReply dispatches a reply packet, invoking reply matchers. It returns // whether any matcher considered the packet acceptable. -func (t *UDPv4) handleReply(from enode.ID, fromIP net.IP, req v4wire.Packet) bool { +func (t *UDPv4) handleReply(from enode.ID, fromIP netip.Addr, req v4wire.Packet) bool { matched := make(chan bool, 1) select { case t.gotreply <- reply{from, fromIP, req, matched}: @@ -465,7 +481,7 @@ func (t *UDPv4) loop(isBootNode bool) { var matched bool // whether any replyMatcher considered the reply acceptable. for el := plist.Front(); el != nil; el = el.Next() { p := el.Value.(*replyMatcher) - if p.from == r.from && p.ptype == r.data.Kind() && p.ip.Equal(r.ip) { + if p.from == r.from && p.ptype == r.data.Kind() && p.ip == r.ip { ok, requestDone := p.callback(r.data) matched = matched || ok p.reply = r.data @@ -509,7 +525,7 @@ func (t *UDPv4) loop(isBootNode bool) { } } -func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]byte, error) { +func (t *UDPv4) send(toaddr netip.AddrPort, toid enode.ID, req v4wire.Packet) ([]byte, error) { packet, hash, err := v4wire.Encode(t.priv, req) if err != nil { return hash, err @@ -517,8 +533,8 @@ func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]b return hash, t.write(toaddr, toid, req.Name(), packet) } -func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error { - _, err := t.conn.WriteToUDP(packet, toaddr) +func (t *UDPv4) write(toaddr netip.AddrPort, toid enode.ID, what string, packet []byte) error { + _, err := t.conn.WriteToUDPAddrPort(packet, toaddr) t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err) return err } @@ -532,7 +548,7 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { buf := make([]byte, maxPacketSize) for { - nbytes, from, err := t.conn.ReadFromUDP(buf) + nbytes, from, err := t.conn.ReadFromUDPAddrPort(buf) if netutil.IsTemporaryError(err) { // Ignore temporary read errors. t.log.Debug("Temporary UDP read error", "err", err) @@ -544,7 +560,9 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { } return } - if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil { + if err := t.handlePacket(from, buf[:nbytes]); err != nil && unhandled == nil { + t.log.Debug("Bad discv4 packet", "addr", from, "err", err) + } else if err != nil && unhandled != nil { select { case unhandled <- ReadPacket{buf[:nbytes], from}: default: @@ -553,15 +571,19 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { } } -func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error { +func (t *UDPv4) handlePacket(from netip.AddrPort, buf []byte) error { + // Unwrap IPv4-in-6 source address. + if from.Addr().Is4In6() { + from = netip.AddrPortFrom(netip.AddrFrom4(from.Addr().As4()), from.Port()) + } + rawpacket, fromKey, hash, err := v4wire.Decode(buf) if err != nil { - t.log.Debug("Bad discv4 packet", "addr", from, "err", err) return err } packet := t.wrapPacket(rawpacket) fromID := fromKey.ID() - if err == nil && packet.preverify != nil { + if packet.preverify != nil { err = packet.preverify(packet, from, fromID, fromKey) } t.log.Trace("<< "+packet.Name(), "id", fromID, "addr", from, "err", err) @@ -572,15 +594,15 @@ func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error { } // checkBond checks if the given node has a recent enough endpoint proof. -func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool { - return time.Since(t.db.LastPongReceived(id, ip)) < bondExpiration +func (t *UDPv4) checkBond(id enode.ID, ip netip.AddrPort) bool { + return time.Since(t.db.LastPongReceived(id, ip.Addr())) < bondExpiration } // ensureBond solicits a ping from a node if we haven't seen a ping from it for a while. // This ensures there is a valid endpoint proof on the remote end. -func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) { - tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration - if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures { +func (t *UDPv4) ensureBond(toid enode.ID, toaddr netip.AddrPort) { + tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.Addr())) > bondExpiration + if tooOld || t.db.FindFails(toid, toaddr.Addr()) > maxFindnodeFailures { rm := t.sendPing(toid, toaddr, nil) <-rm.errc // Wait for them to ping back and process our pong. @@ -588,11 +610,11 @@ func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) { } } -func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*node, error) { +func (t *UDPv4) nodeFromRPC(sender netip.AddrPort, rn v4wire.Node) (*enode.Node, error) { if rn.UDP <= 1024 { return nil, errLowPort } - if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil { + if err := netutil.CheckRelayIP(sender.Addr().AsSlice(), rn.IP); err != nil { return nil, err } if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) { @@ -602,12 +624,12 @@ func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*node, error) if err != nil { return nil, err } - n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP))) + n := enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP)) err = n.ValidateComplete() return n, err } -func nodeToRPC(n *node) v4wire.Node { +func nodeToRPC(n *enode.Node) v4wire.Node { var key ecdsa.PublicKey var ekey v4wire.Pubkey if err := n.Load((*enode.Secp256k1)(&key)); err == nil { @@ -646,14 +668,14 @@ type packetHandlerV4 struct { senderKey *ecdsa.PublicKey // used for ping // preverify checks whether the packet is valid and should be handled at all. - preverify func(p *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error + preverify func(p *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error // handle handles the packet. - handle func(req *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) + handle func(req *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) } // PING/v4 -func (t *UDPv4) verifyPing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { +func (t *UDPv4) verifyPing(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { req := h.Packet.(*v4wire.Ping) if v4wire.Expired(req.Expiration) { @@ -667,7 +689,7 @@ func (t *UDPv4) verifyPing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I return nil } -func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) { +func (t *UDPv4) handlePing(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) { req := h.Packet.(*v4wire.Ping) // Reply. @@ -679,45 +701,48 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I }) // Ping back if our last pong on file is too far in the past. - n := wrapNode(enode.NewV4(h.senderKey, from.IP, int(req.From.TCP), from.Port)) - if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration { + fromIP := from.Addr().AsSlice() + n := enode.NewV4(h.senderKey, fromIP, int(req.From.TCP), int(from.Port())) + if time.Since(t.db.LastPongReceived(n.ID(), from.Addr())) > bondExpiration { t.sendPing(fromID, from, func() { - t.tab.addVerifiedNode(n) + t.tab.addInboundNode(n) }) } else { - t.tab.addVerifiedNode(n) + t.tab.addInboundNode(n) } // Update node database and endpoint predictor. - t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now()) - t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) + t.db.UpdateLastPingReceived(n.ID(), from.Addr(), time.Now()) + toaddr := netip.AddrPortFrom(netutil.IPToAddr(req.To.IP), req.To.UDP) + t.localNode.UDPEndpointStatement(from, toaddr) } // PONG/v4 -func (t *UDPv4) verifyPong(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { +func (t *UDPv4) verifyPong(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { req := h.Packet.(*v4wire.Pong) if v4wire.Expired(req.Expiration) { return errExpired } - if !t.handleReply(fromID, from.IP, req) { + if !t.handleReply(fromID, from.Addr(), req) { return errUnsolicitedReply } - t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) - t.db.UpdateLastPongReceived(fromID, from.IP, time.Now()) + toaddr := netip.AddrPortFrom(netutil.IPToAddr(req.To.IP), req.To.UDP) + t.localNode.UDPEndpointStatement(from, toaddr) + t.db.UpdateLastPongReceived(fromID, from.Addr(), time.Now()) return nil } // FINDNODE/v4 -func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { +func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { req := h.Packet.(*v4wire.Findnode) if v4wire.Expired(req.Expiration) { return errExpired } - if !t.checkBond(fromID, from.IP) { + if !t.checkBond(fromID, from) { // No endpoint proof pong exists, we don't process the packet. This prevents an // attack vector where the discovery protocol could be used to amplify traffic in a // DDOS attack. A malicious actor would send a findnode request with the IP address @@ -729,19 +754,20 @@ func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno return nil } -func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) { +func (t *UDPv4) handleFindnode(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) { req := h.Packet.(*v4wire.Findnode) // Determine closest nodes. target := enode.ID(crypto.Keccak256Hash(req.Target[:])) - closest := t.tab.findnodeByID(target, bucketSize, true).entries + preferLive := !t.tab.cfg.NoFindnodeLivenessCheck + closest := t.tab.findnodeByID(target, bucketSize, preferLive).entries // Send neighbors in chunks with at most maxNeighbors per packet // to stay below the packet size limit. p := v4wire.Neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())} var sent bool for _, n := range closest { - if netutil.CheckRelayIP(from.IP, n.IP()) == nil { + if netutil.CheckRelayAddr(from.Addr(), n.IPAddr()) == nil { p.Nodes = append(p.Nodes, nodeToRPC(n)) } if len(p.Nodes) == v4wire.MaxNeighbors { @@ -757,13 +783,13 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno // NEIGHBORS/v4 -func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { +func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { req := h.Packet.(*v4wire.Neighbors) if v4wire.Expired(req.Expiration) { return errExpired } - if !t.handleReply(fromID, from.IP, h.Packet) { + if !t.handleReply(fromID, from.Addr(), h.Packet) { return errUnsolicitedReply } return nil @@ -771,19 +797,19 @@ func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from *net.UDPAddr, fromID en // ENRREQUEST/v4 -func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { +func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { req := h.Packet.(*v4wire.ENRRequest) if v4wire.Expired(req.Expiration) { return errExpired } - if !t.checkBond(fromID, from.IP) { + if !t.checkBond(fromID, from) { return errUnknownNode } return nil } -func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) { +func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) { t.send(from, fromID, &v4wire.ENRResponse{ ReplyTok: mac, Record: *t.localNode.Node().Record(), @@ -792,8 +818,8 @@ func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e // ENRRESPONSE/v4 -func (t *UDPv4) verifyENRResponse(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error { - if !t.handleReply(fromID, from.IP, h.Packet) { +func (t *UDPv4) verifyENRResponse(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error { + if !t.handleReply(fromID, from.Addr(), h.Packet) { return errUnsolicitedReply } return nil diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go index 361e379626..1af31f4f1b 100644 --- a/p2p/discover/v4_udp_test.go +++ b/p2p/discover/v4_udp_test.go @@ -26,6 +26,7 @@ import ( "io" "math/rand" "net" + "net/netip" "reflect" "sync" "testing" @@ -55,7 +56,7 @@ type udpTest struct { udp *UDPv4 sent [][]byte localkey, remotekey *ecdsa.PrivateKey - remoteaddr *net.UDPAddr + remoteaddr netip.AddrPort } func newUDPTest(t *testing.T) *udpTest { @@ -64,7 +65,7 @@ func newUDPTest(t *testing.T) *udpTest { pipe: newpipe(), localkey: newkey(), remotekey: newkey(), - remoteaddr: &net.UDPAddr{IP: net.IP{10, 0, 1, 99}, Port: 30303}, + remoteaddr: netip.MustParseAddrPort("10.0.1.99:30303"), } test.db, _ = enode.OpenDB("") @@ -92,7 +93,7 @@ func (test *udpTest) packetIn(wantError error, data v4wire.Packet) { } // handles a packet as if it had been sent to the transport by the key/endpoint. -func (test *udpTest) packetInFrom(wantError error, key *ecdsa.PrivateKey, addr *net.UDPAddr, data v4wire.Packet) { +func (test *udpTest) packetInFrom(wantError error, key *ecdsa.PrivateKey, addr netip.AddrPort, data v4wire.Packet) { test.t.Helper() enc, _, err := v4wire.Encode(key, data) @@ -106,7 +107,7 @@ func (test *udpTest) packetInFrom(wantError error, key *ecdsa.PrivateKey, addr * } // waits for a packet to be sent by the transport. -// validate should have type func(X, *net.UDPAddr, []byte), where X is a packet type. +// validate should have type func(X, netip.AddrPort, []byte), where X is a packet type. func (test *udpTest) waitPacketOut(validate interface{}) (closed bool) { test.t.Helper() @@ -128,7 +129,7 @@ func (test *udpTest) waitPacketOut(validate interface{}) (closed bool) { test.t.Errorf("sent packet type mismatch, got: %v, want: %v", reflect.TypeOf(p), exptype) return false } - fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(&dgram.to), reflect.ValueOf(hash)}) + fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(dgram.to), reflect.ValueOf(hash)}) return false } @@ -236,7 +237,7 @@ func TestUDPv4_findnodeTimeout(t *testing.T) { test := newUDPTest(t) defer test.close() - toaddr := &net.UDPAddr{IP: net.ParseIP("1.2.3.4"), Port: 2222} + toaddr := netip.AddrPortFrom(netip.MustParseAddr("1.2.3.4"), 2222) toid := enode.ID{1, 2, 3, 4} target := v4wire.Pubkey{4, 5, 6, 7} result, err := test.udp.findnode(toid, toaddr, target) @@ -261,33 +262,32 @@ func TestUDPv4_findnode(t *testing.T) { for i := 0; i < numCandidates; i++ { key := newkey() ip := net.IP{10, 13, 0, byte(i)} - n := wrapNode(enode.NewV4(&key.PublicKey, ip, 0, 2000)) + n := enode.NewV4(&key.PublicKey, ip, 0, 2000) // Ensure half of table content isn't verified live yet. if i > numCandidates/2 { - n.livenessChecks = 1 live[n.ID()] = true } + test.table.addFoundNode(n, live[n.ID()]) nodes.push(n, numCandidates) } - fillTable(test.table, nodes.entries, false) // ensure there's a bond with the test node, // findnode won't be accepted otherwise. remoteID := v4wire.EncodePubkey(&test.remotekey.PublicKey).ID() - test.table.db.UpdateLastPongReceived(remoteID, test.remoteaddr.IP, time.Now()) + test.table.db.UpdateLastPongReceived(remoteID, test.remoteaddr.Addr(), time.Now()) // check that closest neighbors are returned. expected := test.table.findnodeByID(testTarget.ID(), bucketSize, true) test.packetIn(nil, &v4wire.Findnode{Target: testTarget, Expiration: futureExp}) - waitNeighbors := func(want []*node) { - test.waitPacketOut(func(p *v4wire.Neighbors, to *net.UDPAddr, hash []byte) { + waitNeighbors := func(want []*enode.Node) { + test.waitPacketOut(func(p *v4wire.Neighbors, to netip.AddrPort, hash []byte) { if len(p.Nodes) != len(want) { - t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), bucketSize) + t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), len(want)) return } for i, n := range p.Nodes { if n.ID.ID() != want[i].ID() { - t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, n, expected.entries[i]) + t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, n, expected.entries[i]) } if !live[n.ID.ID()] { t.Errorf("result includes dead node %v", n.ID.ID()) @@ -309,12 +309,12 @@ func TestUDPv4_findnodeMultiReply(t *testing.T) { defer test.close() rid := enode.PubkeyToIDV4(&test.remotekey.PublicKey) - test.table.db.UpdateLastPingReceived(rid, test.remoteaddr.IP, time.Now()) + test.table.db.UpdateLastPingReceived(rid, test.remoteaddr.Addr(), time.Now()) // queue a pending findnode request - resultc, errc := make(chan []*node, 1), make(chan error, 1) + resultc, errc := make(chan []*enode.Node, 1), make(chan error, 1) go func() { - rid := encodePubkey(&test.remotekey.PublicKey).id() + rid := v4wire.EncodePubkey(&test.remotekey.PublicKey).ID() ns, err := test.udp.findnode(rid, test.remoteaddr, testTarget) if err != nil && len(ns) == 0 { errc <- err @@ -325,18 +325,18 @@ func TestUDPv4_findnodeMultiReply(t *testing.T) { // wait for the findnode to be sent. // after it is sent, the transport is waiting for a reply - test.waitPacketOut(func(p *v4wire.Findnode, to *net.UDPAddr, hash []byte) { + test.waitPacketOut(func(p *v4wire.Findnode, to netip.AddrPort, hash []byte) { if p.Target != testTarget { t.Errorf("wrong target: got %v, want %v", p.Target, testTarget) } }) // send the reply as two packets. - list := []*node{ - wrapNode(enode.MustParse("enode://ba85011c70bcc5c04d8607d3a0ed29aa6179c092cbdda10d5d32684fb33ed01bd94f588ca8f91ac48318087dcb02eaf36773a7a453f0eedd6742af668097b29c@10.0.1.16:30303?discport=30304")), - wrapNode(enode.MustParse("enode://81fa361d25f157cd421c60dcc28d8dac5ef6a89476633339c5df30287474520caca09627da18543d9079b5b288698b542d56167aa5c09111e55acdbbdf2ef799@10.0.1.16:30303")), - wrapNode(enode.MustParse("enode://9bffefd833d53fac8e652415f4973bee289e8b1a5c6c4cbe70abf817ce8a64cee11b823b66a987f51aaa9fba0d6a91b3e6bf0d5a5d1042de8e9eeea057b217f8@10.0.1.36:30301?discport=17")), - wrapNode(enode.MustParse("enode://1b5b4aa662d7cb44a7221bfba67302590b643028197a7d5214790f3bac7aaa4a3241be9e83c09cf1f6c69d007c634faae3dc1b1221793e8446c0b3a09de65960@10.0.1.16:30303")), + list := []*enode.Node{ + enode.MustParse("enode://ba85011c70bcc5c04d8607d3a0ed29aa6179c092cbdda10d5d32684fb33ed01bd94f588ca8f91ac48318087dcb02eaf36773a7a453f0eedd6742af668097b29c@10.0.1.16:30303?discport=30304"), + enode.MustParse("enode://81fa361d25f157cd421c60dcc28d8dac5ef6a89476633339c5df30287474520caca09627da18543d9079b5b288698b542d56167aa5c09111e55acdbbdf2ef799@10.0.1.16:30303"), + enode.MustParse("enode://9bffefd833d53fac8e652415f4973bee289e8b1a5c6c4cbe70abf817ce8a64cee11b823b66a987f51aaa9fba0d6a91b3e6bf0d5a5d1042de8e9eeea057b217f8@10.0.1.36:30301?discport=17"), + enode.MustParse("enode://1b5b4aa662d7cb44a7221bfba67302590b643028197a7d5214790f3bac7aaa4a3241be9e83c09cf1f6c69d007c634faae3dc1b1221793e8446c0b3a09de65960@10.0.1.16:30303"), } rpclist := make([]v4wire.Node, len(list)) for i := range list { @@ -368,8 +368,8 @@ func TestUDPv4_pingMatch(t *testing.T) { crand.Read(randToken) test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp}) - test.waitPacketOut(func(*v4wire.Pong, *net.UDPAddr, []byte) {}) - test.waitPacketOut(func(*v4wire.Ping, *net.UDPAddr, []byte) {}) + test.waitPacketOut(func(*v4wire.Pong, netip.AddrPort, []byte) {}) + test.waitPacketOut(func(*v4wire.Ping, netip.AddrPort, []byte) {}) test.packetIn(errUnsolicitedReply, &v4wire.Pong{ReplyTok: randToken, To: testLocalAnnounced, Expiration: futureExp}) } @@ -379,10 +379,10 @@ func TestUDPv4_pingMatchIP(t *testing.T) { defer test.close() test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp}) - test.waitPacketOut(func(*v4wire.Pong, *net.UDPAddr, []byte) {}) + test.waitPacketOut(func(*v4wire.Pong, netip.AddrPort, []byte) {}) - test.waitPacketOut(func(p *v4wire.Ping, to *net.UDPAddr, hash []byte) { - wrongAddr := &net.UDPAddr{IP: net.IP{33, 44, 1, 2}, Port: 30000} + test.waitPacketOut(func(p *v4wire.Ping, to netip.AddrPort, hash []byte) { + wrongAddr := netip.MustParseAddrPort("33.44.1.2:30000") test.packetInFrom(errUnsolicitedReply, test.remotekey, wrongAddr, &v4wire.Pong{ ReplyTok: hash, To: testLocalAnnounced, @@ -393,41 +393,36 @@ func TestUDPv4_pingMatchIP(t *testing.T) { func TestUDPv4_successfulPing(t *testing.T) { test := newUDPTest(t) - added := make(chan *node, 1) - test.table.nodeAddedHook = func(b *bucket, n *node) { added <- n } + added := make(chan *tableNode, 1) + test.table.nodeAddedHook = func(b *bucket, n *tableNode) { added <- n } defer test.close() // The remote side sends a ping packet to initiate the exchange. go test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp}) // The ping is replied to. - test.waitPacketOut(func(p *v4wire.Pong, to *net.UDPAddr, hash []byte) { + test.waitPacketOut(func(p *v4wire.Pong, to netip.AddrPort, hash []byte) { pinghash := test.sent[0][:32] if !bytes.Equal(p.ReplyTok, pinghash) { t.Errorf("got pong.ReplyTok %x, want %x", p.ReplyTok, pinghash) } - wantTo := v4wire.Endpoint{ - // The mirrored UDP address is the UDP packet sender - IP: test.remoteaddr.IP, UDP: uint16(test.remoteaddr.Port), - // The mirrored TCP port is the one from the ping packet - TCP: testRemote.TCP, - } + // The mirrored UDP address is the UDP packet sender. + // The mirrored TCP port is the one from the ping packet. + wantTo := v4wire.NewEndpoint(test.remoteaddr, testRemote.TCP) if !reflect.DeepEqual(p.To, wantTo) { t.Errorf("got pong.To %v, want %v", p.To, wantTo) } }) // Remote is unknown, the table pings back. - test.waitPacketOut(func(p *v4wire.Ping, to *net.UDPAddr, hash []byte) { - if !reflect.DeepEqual(p.From, test.udp.ourEndpoint()) { + test.waitPacketOut(func(p *v4wire.Ping, to netip.AddrPort, hash []byte) { + wantFrom := test.udp.ourEndpoint() + wantFrom.IP = net.IP{} + if !reflect.DeepEqual(p.From, wantFrom) { t.Errorf("got ping.From %#v, want %#v", p.From, test.udp.ourEndpoint()) } - wantTo := v4wire.Endpoint{ - // The mirrored UDP address is the UDP packet sender. - IP: test.remoteaddr.IP, - UDP: uint16(test.remoteaddr.Port), - TCP: 0, - } + // The mirrored UDP address is the UDP packet sender. + wantTo := v4wire.NewEndpoint(test.remoteaddr, 0) if !reflect.DeepEqual(p.To, wantTo) { t.Errorf("got ping.To %v, want %v", p.To, wantTo) } @@ -438,15 +433,15 @@ func TestUDPv4_successfulPing(t *testing.T) { // pong packet. select { case n := <-added: - rid := encodePubkey(&test.remotekey.PublicKey).id() + rid := v4wire.EncodePubkey(&test.remotekey.PublicKey).ID() if n.ID() != rid { t.Errorf("node has wrong ID: got %v, want %v", n.ID(), rid) } - if !n.IP().Equal(test.remoteaddr.IP) { - t.Errorf("node has wrong IP: got %v, want: %v", n.IP(), test.remoteaddr.IP) + if n.IPAddr() != test.remoteaddr.Addr() { + t.Errorf("node has wrong IP: got %v, want: %v", n.IPAddr(), test.remoteaddr.Addr()) } - if n.UDP() != test.remoteaddr.Port { - t.Errorf("node has wrong UDP port: got %v, want: %v", n.UDP(), test.remoteaddr.Port) + if n.UDP() != int(test.remoteaddr.Port()) { + t.Errorf("node has wrong UDP port: got %v, want: %v", n.UDP(), test.remoteaddr.Port()) } if n.TCP() != int(testRemote.TCP) { t.Errorf("node has wrong TCP port: got %v, want: %v", n.TCP(), testRemote.TCP) @@ -469,12 +464,12 @@ func TestUDPv4_EIP868(t *testing.T) { // Perform endpoint proof and check for sequence number in packet tail. test.packetIn(nil, &v4wire.Ping{Expiration: futureExp}) - test.waitPacketOut(func(p *v4wire.Pong, addr *net.UDPAddr, hash []byte) { + test.waitPacketOut(func(p *v4wire.Pong, addr netip.AddrPort, hash []byte) { if p.ENRSeq != wantNode.Seq() { t.Errorf("wrong sequence number in pong: %d, want %d", p.ENRSeq, wantNode.Seq()) } }) - test.waitPacketOut(func(p *v4wire.Ping, addr *net.UDPAddr, hash []byte) { + test.waitPacketOut(func(p *v4wire.Ping, addr netip.AddrPort, hash []byte) { if p.ENRSeq != wantNode.Seq() { t.Errorf("wrong sequence number in ping: %d, want %d", p.ENRSeq, wantNode.Seq()) } @@ -483,7 +478,7 @@ func TestUDPv4_EIP868(t *testing.T) { // Request should work now. test.packetIn(nil, &v4wire.ENRRequest{Expiration: futureExp}) - test.waitPacketOut(func(p *v4wire.ENRResponse, addr *net.UDPAddr, hash []byte) { + test.waitPacketOut(func(p *v4wire.ENRResponse, addr netip.AddrPort, hash []byte) { n, err := enode.New(enode.ValidSchemes, &p.Record) if err != nil { t.Fatalf("invalid record: %v", err) @@ -584,7 +579,7 @@ type dgramPipe struct { } type dgram struct { - to net.UDPAddr + to netip.AddrPort data []byte } @@ -597,8 +592,8 @@ func newpipe() *dgramPipe { } } -// WriteToUDP queues a datagram. -func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) { +// WriteToUDPAddrPort queues a datagram. +func (c *dgramPipe) WriteToUDPAddrPort(b []byte, to netip.AddrPort) (n int, err error) { msg := make([]byte, len(b)) copy(msg, b) c.mu.Lock() @@ -606,15 +601,15 @@ func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) { if c.closed { return 0, errors.New("closed") } - c.queue = append(c.queue, dgram{*to, b}) + c.queue = append(c.queue, dgram{to, b}) c.cond.Signal() return len(b), nil } -// ReadFromUDP just hangs until the pipe is closed. -func (c *dgramPipe) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { +// ReadFromUDPAddrPort just hangs until the pipe is closed. +func (c *dgramPipe) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) { <-c.closing - return 0, nil, io.EOF + return 0, netip.AddrPort{}, io.EOF } func (c *dgramPipe) Close() error { diff --git a/p2p/discover/v4wire/v4wire.go b/p2p/discover/v4wire/v4wire.go index 9c59359fb2..958cca324d 100644 --- a/p2p/discover/v4wire/v4wire.go +++ b/p2p/discover/v4wire/v4wire.go @@ -25,6 +25,7 @@ import ( "fmt" "math/big" "net" + "net/netip" "time" "github.com/ethereum/go-ethereum/common/math" @@ -150,14 +151,15 @@ type Endpoint struct { } // NewEndpoint creates an endpoint. -func NewEndpoint(addr *net.UDPAddr, tcpPort uint16) Endpoint { - ip := net.IP{} - if ip4 := addr.IP.To4(); ip4 != nil { - ip = ip4 - } else if ip6 := addr.IP.To16(); ip6 != nil { - ip = ip6 +func NewEndpoint(addr netip.AddrPort, tcpPort uint16) Endpoint { + var ip net.IP + if addr.Addr().Is4() || addr.Addr().Is4In6() { + ip4 := addr.Addr().As4() + ip = ip4[:] + } else { + ip = addr.Addr().AsSlice() } - return Endpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort} + return Endpoint{IP: ip, UDP: addr.Port(), TCP: tcpPort} } type Packet interface { diff --git a/p2p/discover/v5_talk.go b/p2p/discover/v5_talk.go index 5d396f689e..feca3105ac 100644 --- a/p2p/discover/v5_talk.go +++ b/p2p/discover/v5_talk.go @@ -18,6 +18,7 @@ package discover import ( "net" + "net/netip" "sync" "time" @@ -70,7 +71,7 @@ func (t *talkSystem) register(protocol string, handler TalkRequestHandler) { } // handleRequest handles a talk request. -func (t *talkSystem) handleRequest(id enode.ID, addr *net.UDPAddr, req *v5wire.TalkRequest) { +func (t *talkSystem) handleRequest(id enode.ID, addr netip.AddrPort, req *v5wire.TalkRequest) { t.mutex.Lock() handler, ok := t.handlers[req.Protocol] t.mutex.Unlock() @@ -88,7 +89,8 @@ func (t *talkSystem) handleRequest(id enode.ID, addr *net.UDPAddr, req *v5wire.T case <-t.slots: go func() { defer func() { t.slots <- struct{}{} }() - respMessage := handler(id, addr, req.Message) + udpAddr := &net.UDPAddr{IP: addr.Addr().AsSlice(), Port: int(addr.Port())} + respMessage := handler(id, udpAddr, req.Message) resp := &v5wire.TalkResponse{ReqID: req.ReqID, Message: respMessage} t.transport.sendFromAnotherThread(id, addr, resp) }() diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 71f8d8dd08..4453d10695 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -25,6 +25,8 @@ import ( "fmt" "io" "net" + "net/netip" + "slices" "sync" "time" @@ -100,14 +102,14 @@ type UDPv5 struct { type sendRequest struct { destID enode.ID - destAddr *net.UDPAddr + destAddr netip.AddrPort msg v5wire.Packet } // callV5 represents a remote procedure call against another node. type callV5 struct { id enode.ID - addr *net.UDPAddr + addr netip.AddrPort node *enode.Node // This is required to perform handshakes. packet v5wire.Packet @@ -174,7 +176,7 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { cancelCloseCtx: cancelCloseCtx, } t.talk = newTalkSystem(t) - tab, err := newMeteredTable(t, t.db, cfg) + tab, err := newTable(t, t.db, cfg) if err != nil { return nil, err } @@ -232,7 +234,7 @@ func (t *UDPv5) AllNodes() []*enode.Node { for _, b := range &t.tab.buckets { for _, n := range b.entries { - nodes = append(nodes, unwrapNode(n)) + nodes = append(nodes, n.Node) } } return nodes @@ -265,7 +267,7 @@ func (t *UDPv5) TalkRequest(n *enode.Node, protocol string, request []byte) ([]b } // TalkRequestToID sends a talk request to a node and waits for a response. -func (t *UDPv5) TalkRequestToID(id enode.ID, addr *net.UDPAddr, protocol string, request []byte) ([]byte, error) { +func (t *UDPv5) TalkRequestToID(id enode.ID, addr netip.AddrPort, protocol string, request []byte) ([]byte, error) { req := &v5wire.TalkRequest{Protocol: protocol, Message: request} resp := t.callToID(id, addr, v5wire.TalkResponseMsg, req) defer t.callDone(resp) @@ -313,26 +315,26 @@ func (t *UDPv5) newRandomLookup(ctx context.Context) *lookup { } func (t *UDPv5) newLookup(ctx context.Context, target enode.ID) *lookup { - return newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) { + return newLookup(ctx, t.tab, target, func(n *enode.Node) ([]*enode.Node, error) { return t.lookupWorker(n, target) }) } // lookupWorker performs FINDNODE calls against a single node during lookup. -func (t *UDPv5) lookupWorker(destNode *node, target enode.ID) ([]*node, error) { +func (t *UDPv5) lookupWorker(destNode *enode.Node, target enode.ID) ([]*enode.Node, error) { var ( dists = lookupDistances(target, destNode.ID()) nodes = nodesByDistance{target: target} err error ) var r []*enode.Node - r, err = t.findnode(unwrapNode(destNode), dists) + r, err = t.findnode(destNode, dists) if errors.Is(err, errClosed) { return nil, err } for _, n := range r { if n.ID() != t.Self().ID() { - nodes.push(wrapNode(n), findnodeResultLimit) + nodes.push(n, findnodeResultLimit) } } return nodes.entries, err @@ -426,10 +428,10 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s if err != nil { return nil, err } - if err := netutil.CheckRelayIP(c.addr.IP, node.IP()); err != nil { + if err := netutil.CheckRelayAddr(c.addr.Addr(), node.IPAddr()); err != nil { return nil, err } - if t.netrestrict != nil && !t.netrestrict.Contains(node.IP()) { + if t.netrestrict != nil && !t.netrestrict.ContainsAddr(node.IPAddr()) { return nil, errors.New("not contained in netrestrict list") } if node.UDP() <= 1024 { @@ -437,7 +439,7 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s } if distances != nil { nd := enode.LogDist(c.id, node.ID()) - if !containsUint(uint(nd), distances) { + if !slices.Contains(distances, uint(nd)) { return nil, errors.New("does not match any requested distance") } } @@ -448,26 +450,17 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s return node, nil } -func containsUint(x uint, xs []uint) bool { - for _, v := range xs { - if x == v { - return true - } - } - return false -} - // callToNode sends the given call and sets up a handler for response packets (of message // type responseType). Responses are dispatched to the call's response channel. func (t *UDPv5) callToNode(n *enode.Node, responseType byte, req v5wire.Packet) *callV5 { - addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} + addr, _ := n.UDPEndpoint() c := &callV5{id: n.ID(), addr: addr, node: n} t.initCall(c, responseType, req) return c } // callToID is like callToNode, but for cases where the node record is not available. -func (t *UDPv5) callToID(id enode.ID, addr *net.UDPAddr, responseType byte, req v5wire.Packet) *callV5 { +func (t *UDPv5) callToID(id enode.ID, addr netip.AddrPort, responseType byte, req v5wire.Packet) *callV5 { c := &callV5{id: id, addr: addr} t.initCall(c, responseType, req) return c @@ -627,12 +620,12 @@ func (t *UDPv5) sendCall(c *callV5) { // sendResponse sends a response packet to the given node. // This doesn't trigger a handshake even if no keys are available. -func (t *UDPv5) sendResponse(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet) error { +func (t *UDPv5) sendResponse(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet) error { _, err := t.send(toID, toAddr, packet, nil) return err } -func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet) { +func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet) { select { case t.sendCh <- sendRequest{toID, toAddr, packet}: case <-t.closeCtx.Done(): @@ -640,7 +633,7 @@ func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr *net.UDPAddr, packet } // send sends a packet to the given node. -func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet, c *v5wire.Whoareyou) (v5wire.Nonce, error) { +func (t *UDPv5) send(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet, c *v5wire.Whoareyou) (v5wire.Nonce, error) { addr := toAddr.String() t.logcontext = append(t.logcontext[:0], "id", toID, "addr", addr) t.logcontext = packet.AppendLogInfo(t.logcontext) @@ -652,7 +645,7 @@ func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet, c return nonce, err } - _, err = t.conn.WriteToUDP(enc, toAddr) + _, err = t.conn.WriteToUDPAddrPort(enc, toAddr) t.log.Trace(">> "+packet.Name(), t.logcontext...) return nonce, err } @@ -663,7 +656,7 @@ func (t *UDPv5) readLoop() { buf := make([]byte, maxPacketSize) for range t.readNextCh { - nbytes, from, err := t.conn.ReadFromUDP(buf) + nbytes, from, err := t.conn.ReadFromUDPAddrPort(buf) if netutil.IsTemporaryError(err) { // Ignore temporary read errors. t.log.Debug("Temporary UDP read error", "err", err) @@ -680,7 +673,11 @@ func (t *UDPv5) readLoop() { } // dispatchReadPacket sends a packet into the dispatch loop. -func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool { +func (t *UDPv5) dispatchReadPacket(from netip.AddrPort, content []byte) bool { + // Unwrap IPv4-in-6 source address. + if from.Addr().Is4In6() { + from = netip.AddrPortFrom(netip.AddrFrom4(from.Addr().As4()), from.Port()) + } select { case t.packetInCh <- ReadPacket{content, from}: return true @@ -690,7 +687,7 @@ func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool { } // handlePacket decodes and processes an incoming packet from the network. -func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error { +func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr netip.AddrPort) error { addr := fromAddr.String() fromID, fromNode, packet, err := t.codec.Decode(rawpacket, addr) if err != nil { @@ -707,7 +704,7 @@ func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error { } if fromNode != nil { // Handshake succeeded, add to table. - t.tab.addSeenNode(wrapNode(fromNode)) + t.tab.addInboundNode(fromNode) } if packet.Kind() != v5wire.WhoareyouPacket { // WHOAREYOU logged separately to report errors. @@ -720,13 +717,13 @@ func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error { } // handleCallResponse dispatches a response packet to the call waiting for it. -func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr *net.UDPAddr, p v5wire.Packet) bool { +func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr netip.AddrPort, p v5wire.Packet) bool { ac := t.activeCallByNode[fromID] if ac == nil || !bytes.Equal(p.RequestID(), ac.reqid) { t.log.Debug(fmt.Sprintf("Unsolicited/late %s response", p.Name()), "id", fromID, "addr", fromAddr) return false } - if !fromAddr.IP.Equal(ac.addr.IP) || fromAddr.Port != ac.addr.Port { + if fromAddr != ac.addr { t.log.Debug(fmt.Sprintf("%s from wrong endpoint", p.Name()), "id", fromID, "addr", fromAddr) return false } @@ -751,7 +748,7 @@ func (t *UDPv5) getNode(id enode.ID) *enode.Node { } // handle processes incoming packets according to their message type. -func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr) { +func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) { switch p := p.(type) { case *v5wire.Unknown: t.handleUnknown(p, fromID, fromAddr) @@ -761,7 +758,8 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr) t.handlePing(p, fromID, fromAddr) case *v5wire.Pong: if t.handleCallResponse(fromID, fromAddr, p) { - t.localNode.UDPEndpointStatement(fromAddr, &net.UDPAddr{IP: p.ToIP, Port: int(p.ToPort)}) + toAddr := netip.AddrPortFrom(netutil.IPToAddr(p.ToIP), p.ToPort) + t.localNode.UDPEndpointStatement(fromAddr, toAddr) } case *v5wire.Findnode: t.handleFindnode(p, fromID, fromAddr) @@ -775,7 +773,7 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr) } // handleUnknown initiates a handshake by responding with WHOAREYOU. -func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr *net.UDPAddr) { +func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) { challenge := &v5wire.Whoareyou{Nonce: p.Nonce} crand.Read(challenge.IDNonce[:]) if n := t.getNode(fromID); n != nil { @@ -791,7 +789,7 @@ var ( ) // handleWhoareyou resends the active call as a handshake packet. -func (t *UDPv5) handleWhoareyou(p *v5wire.Whoareyou, fromID enode.ID, fromAddr *net.UDPAddr) { +func (t *UDPv5) handleWhoareyou(p *v5wire.Whoareyou, fromID enode.ID, fromAddr netip.AddrPort) { c, err := t.matchWithCall(fromID, p.Nonce) if err != nil { t.log.Debug("Invalid "+p.Name(), "addr", fromAddr, "err", err) @@ -825,32 +823,34 @@ func (t *UDPv5) matchWithCall(fromID enode.ID, nonce v5wire.Nonce) (*callV5, err } // handlePing sends a PONG response. -func (t *UDPv5) handlePing(p *v5wire.Ping, fromID enode.ID, fromAddr *net.UDPAddr) { - remoteIP := fromAddr.IP - // Handle IPv4 mapped IPv6 addresses in the - // event the local node is binded to an - // ipv6 interface. - if remoteIP.To4() != nil { - remoteIP = remoteIP.To4() +func (t *UDPv5) handlePing(p *v5wire.Ping, fromID enode.ID, fromAddr netip.AddrPort) { + var remoteIP net.IP + // Handle IPv4 mapped IPv6 addresses in the event the local node is binded + // to an ipv6 interface. + if fromAddr.Addr().Is4() || fromAddr.Addr().Is4In6() { + ip4 := fromAddr.Addr().As4() + remoteIP = ip4[:] + } else { + remoteIP = fromAddr.Addr().AsSlice() } t.sendResponse(fromID, fromAddr, &v5wire.Pong{ ReqID: p.ReqID, ToIP: remoteIP, - ToPort: uint16(fromAddr.Port), + ToPort: fromAddr.Port(), ENRSeq: t.localNode.Node().Seq(), }) } // handleFindnode returns nodes to the requester. -func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr *net.UDPAddr) { - nodes := t.collectTableNodes(fromAddr.IP, p.Distances, findnodeResultLimit) +func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr netip.AddrPort) { + nodes := t.collectTableNodes(fromAddr.Addr(), p.Distances, findnodeResultLimit) for _, resp := range packNodes(p.ReqID, nodes) { t.sendResponse(fromID, fromAddr, resp) } } // collectTableNodes creates a FINDNODE result set for the given distances. -func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*enode.Node { +func (t *UDPv5) collectTableNodes(rip netip.Addr, distances []uint, limit int) []*enode.Node { var bn []*enode.Node var nodes []*enode.Node var processed = make(map[uint]struct{}) @@ -862,10 +862,11 @@ func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*en } processed[dist] = struct{}{} - for _, n := range t.tab.appendLiveNodes(dist, bn[:0]) { + checkLive := !t.tab.cfg.NoFindnodeLivenessCheck + for _, n := range t.tab.appendBucketNodes(dist, bn[:0], checkLive) { // Apply some pre-checks to avoid sending invalid nodes. // Note liveness is checked by appendLiveNodes. - if netutil.CheckRelayIP(rip, n.IP()) != nil { + if netutil.CheckRelayAddr(rip, n.IPAddr()) != nil { continue } nodes = append(nodes, n) diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 62e8ea92a7..ef21784c4e 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -23,18 +23,20 @@ import ( "fmt" "math/rand" "net" + "net/netip" "reflect" + "slices" "testing" "time" "github.com/ethereum/go-ethereum/internal/testlog" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover/v4wire" "github.com/ethereum/go-ethereum/p2p/discover/v5wire" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" - "golang.org/x/exp/slices" ) // Real sockets, real crypto: this test checks end-to-end connectivity for UDPv5. @@ -103,7 +105,7 @@ func TestUDPv5_pingHandling(t *testing.T) { defer test.close() test.packetIn(&v5wire.Ping{ReqID: []byte("foo")}) - test.waitPacketOut(func(p *v5wire.Pong, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Pong, addr netip.AddrPort, _ v5wire.Nonce) { if !bytes.Equal(p.ReqID, []byte("foo")) { t.Error("wrong request ID in response:", p.ReqID) } @@ -135,16 +137,16 @@ func TestUDPv5_unknownPacket(t *testing.T) { // Unknown packet from unknown node. test.packetIn(&v5wire.Unknown{Nonce: nonce}) - test.waitPacketOut(func(p *v5wire.Whoareyou, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { check(p, 0) }) // Make node known. n := test.getNode(test.remotekey, test.remoteaddr).Node() - test.table.addSeenNodeSync(wrapNode(n)) + test.table.addFoundNode(n, false) test.packetIn(&v5wire.Unknown{Nonce: nonce}) - test.waitPacketOut(func(p *v5wire.Whoareyou, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) { check(p, n.Seq()) }) } @@ -159,9 +161,9 @@ func TestUDPv5_findnodeHandling(t *testing.T) { nodes253 := nodesAtDistance(test.table.self().ID(), 253, 16) nodes249 := nodesAtDistance(test.table.self().ID(), 249, 4) nodes248 := nodesAtDistance(test.table.self().ID(), 248, 10) - fillTable(test.table, wrapNodes(nodes253), true) - fillTable(test.table, wrapNodes(nodes249), true) - fillTable(test.table, wrapNodes(nodes248), true) + fillTable(test.table, nodes253, true) + fillTable(test.table, nodes249, true) + fillTable(test.table, nodes248, true) // Requesting with distance zero should return the node's own record. test.packetIn(&v5wire.Findnode{ReqID: []byte{0}, Distances: []uint{0}}) @@ -199,7 +201,7 @@ func (test *udpV5Test) expectNodes(wantReqID []byte, wantTotal uint8, wantNodes } for { - test.waitPacketOut(func(p *v5wire.Nodes, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Nodes, addr netip.AddrPort, _ v5wire.Nonce) { if !bytes.Equal(p.ReqID, wantReqID) { test.t.Fatalf("wrong request ID %v in response, want %v", p.ReqID, wantReqID) } @@ -238,7 +240,7 @@ func TestUDPv5_pingCall(t *testing.T) { _, err := test.udp.ping(remote) done <- err }() - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {}) + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {}) if err := <-done; err != errTimeout { t.Fatalf("want errTimeout, got %q", err) } @@ -248,7 +250,7 @@ func TestUDPv5_pingCall(t *testing.T) { _, err := test.udp.ping(remote) done <- err }() - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) { test.packetInFrom(test.remotekey, test.remoteaddr, &v5wire.Pong{ReqID: p.ReqID}) }) if err := <-done; err != nil { @@ -260,8 +262,8 @@ func TestUDPv5_pingCall(t *testing.T) { _, err := test.udp.ping(remote) done <- err }() - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) { - wrongAddr := &net.UDPAddr{IP: net.IP{33, 44, 55, 22}, Port: 10101} + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) { + wrongAddr := netip.MustParseAddrPort("33.44.55.22:10101") test.packetInFrom(test.remotekey, wrongAddr, &v5wire.Pong{ReqID: p.ReqID}) }) if err := <-done; err != errTimeout { @@ -291,7 +293,7 @@ func TestUDPv5_findnodeCall(t *testing.T) { }() // Serve the responses: - test.waitPacketOut(func(p *v5wire.Findnode, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Findnode, addr netip.AddrPort, _ v5wire.Nonce) { if !reflect.DeepEqual(p.Distances, distances) { t.Fatalf("wrong distances in request: %v", p.Distances) } @@ -337,15 +339,15 @@ func TestUDPv5_callResend(t *testing.T) { }() // Ping answered by WHOAREYOU. - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) { test.packetIn(&v5wire.Whoareyou{Nonce: nonce}) }) // Ping should be re-sent. - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) { test.packetIn(&v5wire.Pong{ReqID: p.ReqID}) }) // Answer the other ping. - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) { test.packetIn(&v5wire.Pong{ReqID: p.ReqID}) }) if err := <-done; err != nil { @@ -370,11 +372,11 @@ func TestUDPv5_multipleHandshakeRounds(t *testing.T) { }() // Ping answered by WHOAREYOU. - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) { test.packetIn(&v5wire.Whoareyou{Nonce: nonce}) }) // Ping answered by WHOAREYOU again. - test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) { test.packetIn(&v5wire.Whoareyou{Nonce: nonce}) }) if err := <-done; err != errTimeout { @@ -401,7 +403,7 @@ func TestUDPv5_callTimeoutReset(t *testing.T) { }() // Serve two responses, slowly. - test.waitPacketOut(func(p *v5wire.Findnode, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Findnode, addr netip.AddrPort, _ v5wire.Nonce) { time.Sleep(respTimeout - 50*time.Millisecond) test.packetIn(&v5wire.Nodes{ ReqID: p.ReqID, @@ -439,7 +441,7 @@ func TestUDPv5_talkHandling(t *testing.T) { Protocol: "test", Message: []byte("test request"), }) - test.waitPacketOut(func(p *v5wire.TalkResponse, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.TalkResponse, addr netip.AddrPort, _ v5wire.Nonce) { if !bytes.Equal(p.ReqID, []byte("foo")) { t.Error("wrong request ID in response:", p.ReqID) } @@ -458,7 +460,7 @@ func TestUDPv5_talkHandling(t *testing.T) { Protocol: "wrong", Message: []byte("test request"), }) - test.waitPacketOut(func(p *v5wire.TalkResponse, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.TalkResponse, addr netip.AddrPort, _ v5wire.Nonce) { if !bytes.Equal(p.ReqID, []byte("2")) { t.Error("wrong request ID in response:", p.ReqID) } @@ -485,7 +487,7 @@ func TestUDPv5_talkRequest(t *testing.T) { _, err := test.udp.TalkRequest(remote, "test", []byte("test request")) done <- err }() - test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) {}) + test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) {}) if err := <-done; err != errTimeout { t.Fatalf("want errTimeout, got %q", err) } @@ -495,7 +497,7 @@ func TestUDPv5_talkRequest(t *testing.T) { _, err := test.udp.TalkRequest(remote, "test", []byte("test request")) done <- err }() - test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) { if p.Protocol != "test" { t.Errorf("wrong protocol ID in talk request: %q", p.Protocol) } @@ -516,7 +518,7 @@ func TestUDPv5_talkRequest(t *testing.T) { _, err := test.udp.TalkRequestToID(remote.ID(), test.remoteaddr, "test", []byte("test request 2")) done <- err }() - test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) { if p.Protocol != "test" { t.Errorf("wrong protocol ID in talk request: %q", p.Protocol) } @@ -575,7 +577,7 @@ func TestUDPv5_lookup(t *testing.T) { test := newUDPV5Test(t) // Lookup on empty table returns no nodes. - if results := test.udp.Lookup(lookupTestnet.target.id()); len(results) > 0 { + if results := test.udp.Lookup(lookupTestnet.target.ID()); len(results) > 0 { t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results) } @@ -583,25 +585,26 @@ func TestUDPv5_lookup(t *testing.T) { for d, nn := range lookupTestnet.dists { for i, key := range nn { n := lookupTestnet.node(d, i) - test.getNode(key, &net.UDPAddr{IP: n.IP(), Port: n.UDP()}) + addr, _ := n.UDPEndpoint() + test.getNode(key, addr) } } // Seed table with initial node. initialNode := lookupTestnet.node(256, 0) - fillTable(test.table, []*node{wrapNode(initialNode)}, true) + fillTable(test.table, []*enode.Node{initialNode}, true) // Start the lookup. resultC := make(chan []*enode.Node, 1) go func() { - resultC <- test.udp.Lookup(lookupTestnet.target.id()) + resultC <- test.udp.Lookup(lookupTestnet.target.ID()) test.close() }() // Answer lookup packets. asked := make(map[enode.ID]bool) for done := false; !done; { - done = test.waitPacketOut(func(p v5wire.Packet, to *net.UDPAddr, _ v5wire.Nonce) { + done = test.waitPacketOut(func(p v5wire.Packet, to netip.AddrPort, _ v5wire.Nonce) { recipient, key := lookupTestnet.nodeByAddr(to) switch p := p.(type) { case *v5wire.Ping: @@ -652,11 +655,8 @@ func TestUDPv5_PingWithIPV4MappedAddress(t *testing.T) { test := newUDPV5Test(t) defer test.close() - rawIP := net.IPv4(0xFF, 0x12, 0x33, 0xE5) - test.remoteaddr = &net.UDPAddr{ - IP: rawIP.To16(), - Port: 0, - } + rawIP := netip.AddrFrom4([4]byte{0xFF, 0x12, 0x33, 0xE5}) + test.remoteaddr = netip.AddrPortFrom(netip.AddrFrom16(rawIP.As16()), 0) remote := test.getNode(test.remotekey, test.remoteaddr).Node() done := make(chan struct{}, 1) @@ -665,14 +665,14 @@ func TestUDPv5_PingWithIPV4MappedAddress(t *testing.T) { test.udp.handlePing(&v5wire.Ping{ENRSeq: 1}, remote.ID(), test.remoteaddr) done <- struct{}{} }() - test.waitPacketOut(func(p *v5wire.Pong, addr *net.UDPAddr, _ v5wire.Nonce) { + test.waitPacketOut(func(p *v5wire.Pong, addr netip.AddrPort, _ v5wire.Nonce) { if len(p.ToIP) == net.IPv6len { t.Error("Received untruncated ip address") } if len(p.ToIP) != net.IPv4len { t.Errorf("Received ip address with incorrect length: %d", len(p.ToIP)) } - if !p.ToIP.Equal(rawIP) { + if !p.ToIP.Equal(rawIP.AsSlice()) { t.Errorf("Received incorrect ip address: wanted %s but received %s", rawIP.String(), p.ToIP.String()) } }) @@ -688,9 +688,9 @@ type udpV5Test struct { db *enode.DB udp *UDPv5 localkey, remotekey *ecdsa.PrivateKey - remoteaddr *net.UDPAddr + remoteaddr netip.AddrPort nodesByID map[enode.ID]*enode.LocalNode - nodesByIP map[string]*enode.LocalNode + nodesByIP map[netip.Addr]*enode.LocalNode } // testCodec is the packet encoding used by protocol tests. This codec does not perform encryption. @@ -750,9 +750,9 @@ func newUDPV5Test(t *testing.T) *udpV5Test { pipe: newpipe(), localkey: newkey(), remotekey: newkey(), - remoteaddr: &net.UDPAddr{IP: net.IP{10, 0, 1, 99}, Port: 30303}, + remoteaddr: netip.MustParseAddrPort("10.0.1.99:30303"), nodesByID: make(map[enode.ID]*enode.LocalNode), - nodesByIP: make(map[string]*enode.LocalNode), + nodesByIP: make(map[netip.Addr]*enode.LocalNode), } test.db, _ = enode.OpenDB("") ln := enode.NewLocalNode(test.db, test.localkey) @@ -777,8 +777,8 @@ func (test *udpV5Test) packetIn(packet v5wire.Packet) { test.packetInFrom(test.remotekey, test.remoteaddr, packet) } -// handles a packet as if it had been sent to the transport by the key/endpoint. -func (test *udpV5Test) packetInFrom(key *ecdsa.PrivateKey, addr *net.UDPAddr, packet v5wire.Packet) { +// packetInFrom handles a packet as if it had been sent to the transport by the key/endpoint. +func (test *udpV5Test) packetInFrom(key *ecdsa.PrivateKey, addr netip.AddrPort, packet v5wire.Packet) { test.t.Helper() ln := test.getNode(key, addr) @@ -793,22 +793,22 @@ func (test *udpV5Test) packetInFrom(key *ecdsa.PrivateKey, addr *net.UDPAddr, pa } // getNode ensures the test knows about a node at the given endpoint. -func (test *udpV5Test) getNode(key *ecdsa.PrivateKey, addr *net.UDPAddr) *enode.LocalNode { - id := encodePubkey(&key.PublicKey).id() +func (test *udpV5Test) getNode(key *ecdsa.PrivateKey, addr netip.AddrPort) *enode.LocalNode { + id := v4wire.EncodePubkey(&key.PublicKey).ID() ln := test.nodesByID[id] if ln == nil { db, _ := enode.OpenDB("") ln = enode.NewLocalNode(db, key) - ln.SetStaticIP(addr.IP) - ln.Set(enr.UDP(addr.Port)) + ln.SetStaticIP(addr.Addr().AsSlice()) + ln.Set(enr.UDP(addr.Port())) test.nodesByID[id] = ln } - test.nodesByIP[string(addr.IP)] = ln + test.nodesByIP[addr.Addr()] = ln return ln } // waitPacketOut waits for the next output packet and handles it using the given 'validate' -// function. The function must be of type func (X, *net.UDPAddr, v5wire.Nonce) where X is +// function. The function must be of type func (X, netip.AddrPort, v5wire.Nonce) where X is // assignable to packetV5. func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) { test.t.Helper() @@ -823,7 +823,7 @@ func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) { if err == errTimeout { test.t.Fatalf("timed out waiting for %v", exptype) } - ln := test.nodesByIP[string(dgram.to.IP)] + ln := test.nodesByIP[dgram.to.Addr()] if ln == nil { test.t.Fatalf("attempt to send to non-existing node %v", &dgram.to) } @@ -837,7 +837,7 @@ func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) { test.t.Errorf("sent packet type mismatch, got: %v, want: %v", reflect.TypeOf(p), exptype) return false } - fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(&dgram.to), reflect.ValueOf(frame.AuthTag)}) + fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(dgram.to), reflect.ValueOf(frame.AuthTag)}) return false } diff --git a/p2p/discover/v5wire/crypto.go b/p2p/discover/v5wire/crypto.go index fc0a0edef5..00fc3b4564 100644 --- a/p2p/discover/v5wire/crypto.go +++ b/p2p/discover/v5wire/crypto.go @@ -129,9 +129,7 @@ func deriveKeys(hash hashFn, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, n1, n sec := session{writeKey: make([]byte, aesKeySize), readKey: make([]byte, aesKeySize)} kdf.Read(sec.writeKey) kdf.Read(sec.readKey) - for i := range eph { - eph[i] = 0 - } + clear(eph) return &sec } diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index a5387311a5..8dd02620eb 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -30,6 +30,7 @@ import ( "testing" "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/crypto" @@ -283,9 +284,38 @@ func TestDecodeErrorsV5(t *testing.T) { b = make([]byte, 63) net.nodeA.expectDecodeErr(t, errInvalidHeader, b) - // TODO some more tests would be nice :) - // - check invalid authdata sizes - // - check invalid handshake data sizes + t.Run("invalid-handshake-datasize", func(t *testing.T) { + requiredNumber := 108 + + testDataFile := filepath.Join("testdata", "v5.1-ping-handshake"+".txt") + enc := hexFile(testDataFile) + //delete some byte from handshake to make it invalid + enc = enc[:len(enc)-requiredNumber] + net.nodeB.expectDecodeErr(t, errMsgTooShort, enc) + }) + + t.Run("invalid-auth-datasize", func(t *testing.T) { + testPacket := []byte{} + testDataFiles := []string{"v5.1-whoareyou", "v5.1-ping-handshake"} + for counter, name := range testDataFiles { + file := filepath.Join("testdata", name+".txt") + enc := hexFile(file) + if counter == 0 { + //make whoareyou header + testPacket = enc[:sizeofStaticPacketData-1] + testPacket = append(testPacket, 255) + } + if counter == 1 { + //append invalid auth size + testPacket = append(testPacket, enc[sizeofStaticPacketData:]...) + } + } + + wantErr := "invalid auth size" + if _, err := net.nodeB.decode(testPacket); strings.HasSuffix(err.Error(), wantErr) { + t.Fatal(fmt.Errorf("(%s) got err %q, want %q", net.nodeB.ln.ID().TerminalString(), err, wantErr)) + } + }) } // This test checks that all test vectors can be decoded. @@ -576,7 +606,7 @@ func (n *handshakeTestNode) n() *enode.Node { } func (n *handshakeTestNode) addr() string { - return n.ln.Node().IP().String() + return n.ln.Node().IPAddr().String() } func (n *handshakeTestNode) id() enode.ID { diff --git a/p2p/dnsdisc/client_test.go b/p2p/dnsdisc/client_test.go index abc35ddbd3..01912e1eab 100644 --- a/p2p/dnsdisc/client_test.go +++ b/p2p/dnsdisc/client_test.go @@ -20,6 +20,7 @@ import ( "context" "crypto/ecdsa" "errors" + "maps" "reflect" "testing" "time" @@ -214,7 +215,7 @@ func TestIteratorNodeUpdates(t *testing.T) { // Ensure RandomNode returns the new nodes after the tree is updated. updateSomeNodes(keys, nodes) tree2, _ := makeTestTree("n", nodes, nil) - resolver.clear() + clear(resolver) resolver.add(tree2.ToTXT("n")) t.Log("tree updated") @@ -255,7 +256,7 @@ func TestIteratorRootRecheckOnFail(t *testing.T) { // Ensure RandomNode returns the new nodes after the tree is updated. updateSomeNodes(keys, nodes) tree2, _ := makeTestTree("n", nodes, nil) - resolver.clear() + clear(resolver) resolver.add(tree2.ToTXT("n")) t.Log("tree updated") @@ -446,16 +447,8 @@ func newMapResolver(maps ...map[string]string) mapResolver { return mr } -func (mr mapResolver) clear() { - for k := range mr { - delete(mr, k) - } -} - func (mr mapResolver) add(m map[string]string) { - for k, v := range m { - mr[k] = v - } + maps.Copy(mr, m) } func (mr mapResolver) LookupTXT(ctx context.Context, name string) ([]string, error) { diff --git a/p2p/dnsdisc/tree.go b/p2p/dnsdisc/tree.go index dfac4fb372..a8295ac9eb 100644 --- a/p2p/dnsdisc/tree.go +++ b/p2p/dnsdisc/tree.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "io" + "slices" "strings" "github.com/ethereum/go-ethereum/crypto" @@ -31,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" "golang.org/x/crypto/sha3" - "golang.org/x/exp/slices" ) // Tree is a merkle tree of node records. diff --git a/p2p/enode/idscheme.go b/p2p/enode/idscheme.go index 6ad7f809a7..db7841c047 100644 --- a/p2p/enode/idscheme.go +++ b/p2p/enode/idscheme.go @@ -157,5 +157,5 @@ func SignNull(r *enr.Record, id ID) *Node { if err := r.SetSig(NullID{}, []byte{}); err != nil { panic(err) } - return &Node{r: *r, id: id} + return newNodeWithID(r, id) } diff --git a/p2p/enode/localnode.go b/p2p/enode/localnode.go index a18204e752..6e79c9cbdc 100644 --- a/p2p/enode/localnode.go +++ b/p2p/enode/localnode.go @@ -20,8 +20,8 @@ import ( "crypto/ecdsa" "fmt" "net" + "net/netip" "reflect" - "strconv" "sync" "sync/atomic" "time" @@ -175,8 +175,8 @@ func (ln *LocalNode) delete(e enr.Entry) { } } -func (ln *LocalNode) endpointForIP(ip net.IP) *lnEndpoint { - if ip.To4() != nil { +func (ln *LocalNode) endpointForIP(ip netip.Addr) *lnEndpoint { + if ip.Is4() { return &ln.endpoint4 } return &ln.endpoint6 @@ -188,7 +188,7 @@ func (ln *LocalNode) SetStaticIP(ip net.IP) { ln.mu.Lock() defer ln.mu.Unlock() - ln.endpointForIP(ip).staticIP = ip + ln.endpointForIP(netutil.IPToAddr(ip)).staticIP = ip ln.updateEndpoints() } @@ -198,7 +198,7 @@ func (ln *LocalNode) SetFallbackIP(ip net.IP) { ln.mu.Lock() defer ln.mu.Unlock() - ln.endpointForIP(ip).fallbackIP = ip + ln.endpointForIP(netutil.IPToAddr(ip)).fallbackIP = ip ln.updateEndpoints() } @@ -215,21 +215,21 @@ func (ln *LocalNode) SetFallbackUDP(port int) { // UDPEndpointStatement should be called whenever a statement about the local node's // UDP endpoint is received. It feeds the local endpoint predictor. -func (ln *LocalNode) UDPEndpointStatement(fromaddr, endpoint *net.UDPAddr) { +func (ln *LocalNode) UDPEndpointStatement(fromaddr, endpoint netip.AddrPort) { ln.mu.Lock() defer ln.mu.Unlock() - ln.endpointForIP(endpoint.IP).track.AddStatement(fromaddr.String(), endpoint.String()) + ln.endpointForIP(endpoint.Addr()).track.AddStatement(fromaddr.Addr(), endpoint) ln.updateEndpoints() } // UDPContact should be called whenever the local node has announced itself to another node // via UDP. It feeds the local endpoint predictor. -func (ln *LocalNode) UDPContact(toaddr *net.UDPAddr) { +func (ln *LocalNode) UDPContact(toaddr netip.AddrPort) { ln.mu.Lock() defer ln.mu.Unlock() - ln.endpointForIP(toaddr.IP).track.AddContact(toaddr.String()) + ln.endpointForIP(toaddr.Addr()).track.AddContact(toaddr.Addr()) ln.updateEndpoints() } @@ -268,29 +268,13 @@ func (e *lnEndpoint) get() (newIP net.IP, newPort uint16) { } if e.staticIP != nil { newIP = e.staticIP - } else if ip, port := predictAddr(e.track); ip != nil { - newIP = ip - newPort = port + } else if ap := e.track.PredictEndpoint(); ap.IsValid() { + newIP = ap.Addr().AsSlice() + newPort = ap.Port() } return newIP, newPort } -// predictAddr wraps IPTracker.PredictEndpoint, converting from its string-based -// endpoint representation to IP and port types. -func predictAddr(t *netutil.IPTracker) (net.IP, uint16) { - ep := t.PredictEndpoint() - if ep == "" { - return nil, 0 - } - ipString, portString, _ := net.SplitHostPort(ep) - ip := net.ParseIP(ipString) - port, err := strconv.ParseUint(portString, 10, 16) - if err != nil { - return nil, 0 - } - return ip, uint16(port) -} - func (ln *LocalNode) invalidate() { ln.cur.Store((*Node)(nil)) } @@ -314,7 +298,7 @@ func (ln *LocalNode) sign() { panic(fmt.Errorf("enode: can't verify local record: %v", err)) } ln.cur.Store(n) - log.Info("New local node record", "seq", ln.seq, "id", n.ID(), "ip", n.IP(), "udp", n.UDP(), "tcp", n.TCP()) + log.Info("New local node record", "seq", ln.seq, "id", n.ID(), "ip", n.IPAddr(), "udp", n.UDP(), "tcp", n.TCP()) } func (ln *LocalNode) bumpSeq() { diff --git a/p2p/enode/localnode_test.go b/p2p/enode/localnode_test.go index 7f97ad392f..86b962a74e 100644 --- a/p2p/enode/localnode_test.go +++ b/p2p/enode/localnode_test.go @@ -17,12 +17,14 @@ package enode import ( - "crypto/rand" + "math/rand" "net" + "net/netip" "testing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/stretchr/testify/assert" ) @@ -88,6 +90,7 @@ func TestLocalNodeSeqPersist(t *testing.T) { // This test checks behavior of the endpoint predictor. func TestLocalNodeEndpoint(t *testing.T) { var ( + rng = rand.New(rand.NewSource(4)) fallback = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: 80} predicted = &net.UDPAddr{IP: net.IP{127, 0, 1, 2}, Port: 81} staticIP = net.IP{127, 0, 1, 2} @@ -96,6 +99,7 @@ func TestLocalNodeEndpoint(t *testing.T) { defer db.Close() // Nothing is set initially. + assert.Equal(t, netip.Addr{}, ln.Node().IPAddr()) assert.Equal(t, net.IP(nil), ln.Node().IP()) assert.Equal(t, 0, ln.Node().UDP()) initialSeq := ln.Node().Seq() @@ -103,26 +107,30 @@ func TestLocalNodeEndpoint(t *testing.T) { // Set up fallback address. ln.SetFallbackIP(fallback.IP) ln.SetFallbackUDP(fallback.Port) + assert.Equal(t, netutil.IPToAddr(fallback.IP), ln.Node().IPAddr()) assert.Equal(t, fallback.IP, ln.Node().IP()) assert.Equal(t, fallback.Port, ln.Node().UDP()) assert.Equal(t, initialSeq+1, ln.Node().Seq()) // Add endpoint statements from random hosts. for i := 0; i < iptrackMinStatements; i++ { + assert.Equal(t, netutil.IPToAddr(fallback.IP), ln.Node().IPAddr()) assert.Equal(t, fallback.IP, ln.Node().IP()) assert.Equal(t, fallback.Port, ln.Node().UDP()) assert.Equal(t, initialSeq+1, ln.Node().Seq()) - from := &net.UDPAddr{IP: make(net.IP, 4), Port: 90} - rand.Read(from.IP) - ln.UDPEndpointStatement(from, predicted) + from := netip.AddrPortFrom(netutil.RandomAddr(rng, true), 9000) + endpoint := netip.AddrPortFrom(netutil.IPToAddr(predicted.IP), uint16(predicted.Port)) + ln.UDPEndpointStatement(from, endpoint) } + assert.Equal(t, netutil.IPToAddr(predicted.IP), ln.Node().IPAddr()) assert.Equal(t, predicted.IP, ln.Node().IP()) assert.Equal(t, predicted.Port, ln.Node().UDP()) assert.Equal(t, initialSeq+2, ln.Node().Seq()) // Static IP overrides prediction. ln.SetStaticIP(staticIP) + assert.Equal(t, netutil.IPToAddr(staticIP), ln.Node().IPAddr()) assert.Equal(t, staticIP, ln.Node().IP()) assert.Equal(t, fallback.Port, ln.Node().UDP()) assert.Equal(t, initialSeq+3, ln.Node().Seq()) diff --git a/p2p/enode/node.go b/p2p/enode/node.go index d7a1a9a156..4d93d3f6be 100644 --- a/p2p/enode/node.go +++ b/p2p/enode/node.go @@ -24,6 +24,7 @@ import ( "fmt" "math/bits" "net" + "net/netip" "strings" "github.com/ethereum/go-ethereum/p2p/enr" @@ -36,6 +37,10 @@ var errMissingPrefix = errors.New("missing 'enr:' prefix for base64-encoded reco type Node struct { r enr.Record id ID + // endpoint information + ip netip.Addr + udp uint16 + tcp uint16 } // New wraps a node record. The record must be valid according to the given @@ -44,11 +49,76 @@ func New(validSchemes enr.IdentityScheme, r *enr.Record) (*Node, error) { if err := r.VerifySignature(validSchemes); err != nil { return nil, err } - node := &Node{r: *r} - if n := copy(node.id[:], validSchemes.NodeAddr(&node.r)); n != len(ID{}) { - return nil, fmt.Errorf("invalid node ID length %d, need %d", n, len(ID{})) + var id ID + if n := copy(id[:], validSchemes.NodeAddr(r)); n != len(id) { + return nil, fmt.Errorf("invalid node ID length %d, need %d", n, len(id)) + } + return newNodeWithID(r, id), nil +} + +func newNodeWithID(r *enr.Record, id ID) *Node { + n := &Node{r: *r, id: id} + // Set the preferred endpoint. + // Here we decide between IPv4 and IPv6, choosing the 'most global' address. + var ip4 netip.Addr + var ip6 netip.Addr + n.Load((*enr.IPv4Addr)(&ip4)) + n.Load((*enr.IPv6Addr)(&ip6)) + valid4 := validIP(ip4) + valid6 := validIP(ip6) + switch { + case valid4 && valid6: + if localityScore(ip4) >= localityScore(ip6) { + n.setIP4(ip4) + } else { + n.setIP6(ip6) + } + case valid4: + n.setIP4(ip4) + case valid6: + n.setIP6(ip6) + } + return n +} + +// validIP reports whether 'ip' is a valid node endpoint IP address. +func validIP(ip netip.Addr) bool { + return ip.IsValid() && !ip.IsMulticast() +} + +func localityScore(ip netip.Addr) int { + switch { + case ip.IsUnspecified(): + return 0 + case ip.IsLoopback(): + return 1 + case ip.IsLinkLocalUnicast(): + return 2 + case ip.IsPrivate(): + return 3 + default: + return 4 + } +} + +func (n *Node) setIP4(ip netip.Addr) { + n.ip = ip + n.Load((*enr.UDP)(&n.udp)) + n.Load((*enr.TCP)(&n.tcp)) +} + +func (n *Node) setIP6(ip netip.Addr) { + if ip.Is4In6() { + n.setIP4(ip) + return + } + n.ip = ip + if err := n.Load((*enr.UDP6)(&n.udp)); err != nil { + n.Load((*enr.UDP)(&n.udp)) + } + if err := n.Load((*enr.TCP6)(&n.tcp)); err != nil { + n.Load((*enr.TCP)(&n.tcp)) } - return node, nil } // MustParse parses a node record or enode:// URL. It panics if the input is invalid. @@ -89,43 +159,59 @@ func (n *Node) Seq() uint64 { return n.r.Seq() } -// Incomplete returns true for nodes with no IP address. -func (n *Node) Incomplete() bool { - return n.IP() == nil -} - // Load retrieves an entry from the underlying record. func (n *Node) Load(k enr.Entry) error { return n.r.Load(k) } -// IP returns the IP address of the node. This prefers IPv4 addresses. +// IP returns the IP address of the node. func (n *Node) IP() net.IP { - var ( - ip4 enr.IPv4 - ip6 enr.IPv6 - ) - if n.Load(&ip4) == nil { - return net.IP(ip4) - } - if n.Load(&ip6) == nil { - return net.IP(ip6) - } - return nil + return net.IP(n.ip.AsSlice()) +} + +// IPAddr returns the IP address of the node. +func (n *Node) IPAddr() netip.Addr { + return n.ip } // UDP returns the UDP port of the node. func (n *Node) UDP() int { - var port enr.UDP - n.Load(&port) - return int(port) + return int(n.udp) } // TCP returns the TCP port of the node. func (n *Node) TCP() int { - var port enr.TCP - n.Load(&port) - return int(port) + return int(n.tcp) +} + +// UDPEndpoint returns the announced UDP endpoint. +func (n *Node) UDPEndpoint() (netip.AddrPort, bool) { + if !n.ip.IsValid() || n.ip.IsUnspecified() || n.udp == 0 { + return netip.AddrPort{}, false + } + return netip.AddrPortFrom(n.ip, n.udp), true +} + +// TCPEndpoint returns the announced TCP endpoint. +func (n *Node) TCPEndpoint() (netip.AddrPort, bool) { + if !n.ip.IsValid() || n.ip.IsUnspecified() || n.tcp == 0 { + return netip.AddrPort{}, false + } + return netip.AddrPortFrom(n.ip, n.tcp), true +} + +// QUICEndpoint returns the announced QUIC endpoint. +func (n *Node) QUICEndpoint() (netip.AddrPort, bool) { + var quic uint16 + if n.ip.Is4() || n.ip.Is4In6() { + n.Load((*enr.QUIC)(&quic)) + } else if n.ip.Is6() { + n.Load((*enr.QUIC6)(&quic)) + } + if !n.ip.IsValid() || n.ip.IsUnspecified() || quic == 0 { + return netip.AddrPort{}, false + } + return netip.AddrPortFrom(n.ip, quic), true } // Pubkey returns the secp256k1 public key of the node, if present. @@ -147,16 +233,15 @@ func (n *Node) Record() *enr.Record { // ValidateComplete checks whether n has a valid IP and UDP port. // Deprecated: don't use this method. func (n *Node) ValidateComplete() error { - if n.Incomplete() { + if !n.ip.IsValid() { return errors.New("missing IP address") } - if n.UDP() == 0 { - return errors.New("missing UDP port") - } - ip := n.IP() - if ip.IsMulticast() || ip.IsUnspecified() { + if n.ip.IsMulticast() || n.ip.IsUnspecified() { return errors.New("invalid IP (multicast/unspecified)") } + if n.udp == 0 { + return errors.New("missing UDP port") + } // Validate the node key (on curve, etc.). var key Secp256k1 return n.Load(&key) diff --git a/p2p/enode/node_test.go b/p2p/enode/node_test.go index d15859c477..f38c77415e 100644 --- a/p2p/enode/node_test.go +++ b/p2p/enode/node_test.go @@ -21,6 +21,7 @@ import ( "encoding/hex" "fmt" "math/big" + "net/netip" "testing" "testing/quick" @@ -64,6 +65,229 @@ func TestPythonInterop(t *testing.T) { } } +func TestNodeEndpoints(t *testing.T) { + id := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") + type endpointTest struct { + name string + node *Node + wantIP netip.Addr + wantUDP int + wantTCP int + wantQUIC int + } + tests := []endpointTest{ + { + name: "no-addr", + node: func() *Node { + var r enr.Record + return SignNull(&r, id) + }(), + }, + { + name: "udp-only", + node: func() *Node { + var r enr.Record + r.Set(enr.UDP(9000)) + return SignNull(&r, id) + }(), + }, + { + name: "tcp-only", + node: func() *Node { + var r enr.Record + r.Set(enr.TCP(9000)) + return SignNull(&r, id) + }(), + }, + { + name: "quic-only", + node: func() *Node { + var r enr.Record + r.Set(enr.QUIC(9000)) + return SignNull(&r, id) + }(), + }, + { + name: "quic6-only", + node: func() *Node { + var r enr.Record + r.Set(enr.QUIC6(9000)) + return SignNull(&r, id) + }(), + }, + { + name: "ipv4-only-loopback", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1"))) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("127.0.0.1"), + }, + { + name: "ipv4-only-unspecified", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0"))) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("0.0.0.0"), + }, + { + name: "ipv4-only", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("99.22.33.1"), + }, + { + name: "ipv6-only", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + }, + { + name: "ipv4-loopback-and-ipv6-global", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1"))) + r.Set(enr.UDP(30304)) + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + r.Set(enr.UDP6(30306)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + wantUDP: 30306, + }, + { + name: "ipv4-unspecified-and-ipv6-loopback", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0"))) + r.Set(enr.IPv6Addr(netip.MustParseAddr("::1"))) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("::1"), + }, + { + name: "ipv4-private-and-ipv6-global", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) + r.Set(enr.UDP(30304)) + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + r.Set(enr.UDP6(30306)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + wantUDP: 30306, + }, + { + name: "ipv4-local-and-ipv6-global", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("169.254.2.6"))) + r.Set(enr.UDP(30304)) + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + r.Set(enr.UDP6(30306)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + wantUDP: 30306, + }, + { + name: "ipv4-private-and-ipv6-private", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) + r.Set(enr.UDP(30304)) + r.Set(enr.IPv6Addr(netip.MustParseAddr("fd00::abcd:1"))) + r.Set(enr.UDP6(30306)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("192.168.2.2"), + wantUDP: 30304, + }, + { + name: "ipv4-private-and-ipv6-link-local", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) + r.Set(enr.UDP(30304)) + r.Set(enr.IPv6Addr(netip.MustParseAddr("fe80::1"))) + r.Set(enr.UDP6(30306)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("192.168.2.2"), + wantUDP: 30304, + }, + { + name: "ipv4-quic", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) + r.Set(enr.QUIC(9001)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("99.22.33.1"), + wantQUIC: 9001, + }, + { // Because the node is IPv4, the quic6 entry won't be loaded. + name: "ipv4-quic6", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) + r.Set(enr.QUIC6(9001)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("99.22.33.1"), + }, + { + name: "ipv6-quic", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + r.Set(enr.QUIC(9001)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + }, + { + name: "ipv6-quic6", + node: func() *Node { + var r enr.Record + r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) + r.Set(enr.QUIC6(9001)) + return SignNull(&r, id) + }(), + wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), + wantQUIC: 9001, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.wantIP != test.node.IPAddr() { + t.Errorf("node has wrong IP %v, want %v", test.node.IPAddr(), test.wantIP) + } + if test.wantUDP != test.node.UDP() { + t.Errorf("node has wrong UDP port %d, want %d", test.node.UDP(), test.wantUDP) + } + if test.wantTCP != test.node.TCP() { + t.Errorf("node has wrong TCP port %d, want %d", test.node.TCP(), test.wantTCP) + } + if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) { + t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC) + } + }) + } +} + func TestHexID(t *testing.T) { ref := ID{0, 0, 0, 0, 0, 0, 0, 128, 106, 217, 182, 31, 165, 174, 1, 67, 7, 235, 220, 150, 66, 83, 173, 205, 159, 44, 10, 57, 42, 161, 26, 188} id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index cff14e8bba..22b8181430 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -21,12 +21,13 @@ import ( "crypto/rand" "encoding/binary" "fmt" - "net" + "net/netip" "os" "sync" "time" "github.com/ethereum/go-ethereum/common/gopool" + "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/errors" @@ -66,7 +67,7 @@ var ( errInvalidIP = errors.New("invalid IP") ) -var zeroIP = make(net.IP, 16) +var zeroIP = netip.IPv6Unspecified() // DB is the node database, storing previously seen nodes and any collected metadata about // them for QoS purposes. @@ -85,7 +86,7 @@ func OpenDB(path string) (*DB, error) { return newPersistentDB(path) } -// newMemoryNodeDB creates a new in-memory node database without a persistent backend. +// newMemoryDB creates a new in-memory node database without a persistent backend. func newMemoryDB() (*DB, error) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { @@ -94,7 +95,7 @@ func newMemoryDB() (*DB, error) { return &DB{lvl: db, quit: make(chan struct{})}, nil } -// newPersistentNodeDB creates/opens a leveldb backed persistent node database, +// newPersistentDB creates/opens a leveldb backed persistent node database, // also flushing its contents in case of a version mismatch. func newPersistentDB(path string) (*DB, error) { opts := &opt.Options{OpenFilesCacheCapacity: 5} @@ -151,39 +152,37 @@ func splitNodeKey(key []byte) (id ID, rest []byte) { } // nodeItemKey returns the database key for a node metadata field. -func nodeItemKey(id ID, ip net.IP, field string) []byte { - ip16 := ip.To16() - if ip16 == nil { - panic(fmt.Errorf("invalid IP (length %d)", len(ip))) +func nodeItemKey(id ID, ip netip.Addr, field string) []byte { + if !ip.IsValid() { + panic("invalid IP") } - return bytes.Join([][]byte{nodeKey(id), ip16, []byte(field)}, []byte{':'}) + ip16 := ip.As16() + return bytes.Join([][]byte{nodeKey(id), ip16[:], []byte(field)}, []byte{':'}) } // splitNodeItemKey returns the components of a key created by nodeItemKey. -func splitNodeItemKey(key []byte) (id ID, ip net.IP, field string) { +func splitNodeItemKey(key []byte) (id ID, ip netip.Addr, field string) { id, key = splitNodeKey(key) // Skip discover root. if string(key) == dbDiscoverRoot { - return id, nil, "" + return id, netip.Addr{}, "" } key = key[len(dbDiscoverRoot)+1:] // Split out the IP. - ip = key[:16] - if ip4 := ip.To4(); ip4 != nil { - ip = ip4 - } + ip, _ = netip.AddrFromSlice(key[:16]) key = key[16+1:] // Field is the remainder of key. field = string(key) return id, ip, field } -func v5Key(id ID, ip net.IP, field string) []byte { +func v5Key(id ID, ip netip.Addr, field string) []byte { + ip16 := ip.As16() return bytes.Join([][]byte{ []byte(dbNodePrefix), id[:], []byte(dbDiscv5Root), - ip.To16(), + ip16[:], []byte(field), }, []byte{':'}) } @@ -243,13 +242,14 @@ func (db *DB) Node(id ID) *Node { } func mustDecodeNode(id, data []byte) *Node { - node := new(Node) - if err := rlp.DecodeBytes(data, &node.r); err != nil { + var r enr.Record + if err := rlp.DecodeBytes(data, &r); err != nil { panic(fmt.Errorf("p2p/enode: can't decode node %x in DB: %v", id, err)) } - // Restore node id cache. - copy(node.id[:], id) - return node + if len(id) != len(ID{}) { + panic(fmt.Errorf("invalid id length %d", len(id))) + } + return newNodeWithID(&r, ID(id)) } // UpdateNode inserts - potentially overwriting - a node into the peer database. @@ -367,24 +367,24 @@ func (db *DB) expireNodes() { // LastPingReceived retrieves the time of the last ping packet received from // a remote node. -func (db *DB) LastPingReceived(id ID, ip net.IP) time.Time { - if ip = ip.To16(); ip == nil { +func (db *DB) LastPingReceived(id ID, ip netip.Addr) time.Time { + if !ip.IsValid() { return time.Time{} } return time.Unix(db.fetchInt64(nodeItemKey(id, ip, dbNodePing)), 0) } // UpdateLastPingReceived updates the last time we tried contacting a remote node. -func (db *DB) UpdateLastPingReceived(id ID, ip net.IP, instance time.Time) error { - if ip = ip.To16(); ip == nil { +func (db *DB) UpdateLastPingReceived(id ID, ip netip.Addr, instance time.Time) error { + if !ip.IsValid() { return errInvalidIP } return db.storeInt64(nodeItemKey(id, ip, dbNodePing), instance.Unix()) } // LastPongReceived retrieves the time of the last successful pong from remote node. -func (db *DB) LastPongReceived(id ID, ip net.IP) time.Time { - if ip = ip.To16(); ip == nil { +func (db *DB) LastPongReceived(id ID, ip netip.Addr) time.Time { + if !ip.IsValid() { return time.Time{} } // Launch expirer @@ -393,40 +393,40 @@ func (db *DB) LastPongReceived(id ID, ip net.IP) time.Time { } // UpdateLastPongReceived updates the last pong time of a node. -func (db *DB) UpdateLastPongReceived(id ID, ip net.IP, instance time.Time) error { - if ip = ip.To16(); ip == nil { +func (db *DB) UpdateLastPongReceived(id ID, ip netip.Addr, instance time.Time) error { + if !ip.IsValid() { return errInvalidIP } return db.storeInt64(nodeItemKey(id, ip, dbNodePong), instance.Unix()) } // FindFails retrieves the number of findnode failures since bonding. -func (db *DB) FindFails(id ID, ip net.IP) int { - if ip = ip.To16(); ip == nil { +func (db *DB) FindFails(id ID, ip netip.Addr) int { + if !ip.IsValid() { return 0 } return int(db.fetchInt64(nodeItemKey(id, ip, dbNodeFindFails))) } // UpdateFindFails updates the number of findnode failures since bonding. -func (db *DB) UpdateFindFails(id ID, ip net.IP, fails int) error { - if ip = ip.To16(); ip == nil { +func (db *DB) UpdateFindFails(id ID, ip netip.Addr, fails int) error { + if !ip.IsValid() { return errInvalidIP } return db.storeInt64(nodeItemKey(id, ip, dbNodeFindFails), int64(fails)) } // FindFailsV5 retrieves the discv5 findnode failure counter. -func (db *DB) FindFailsV5(id ID, ip net.IP) int { - if ip = ip.To16(); ip == nil { +func (db *DB) FindFailsV5(id ID, ip netip.Addr) int { + if !ip.IsValid() { return 0 } return int(db.fetchInt64(v5Key(id, ip, dbNodeFindFails))) } // UpdateFindFailsV5 stores the discv5 findnode failure counter. -func (db *DB) UpdateFindFailsV5(id ID, ip net.IP, fails int) error { - if ip = ip.To16(); ip == nil { +func (db *DB) UpdateFindFailsV5(id ID, ip netip.Addr, fails int) error { + if !ip.IsValid() { return errInvalidIP } return db.storeInt64(v5Key(id, ip, dbNodeFindFails), int64(fails)) @@ -473,7 +473,7 @@ seek: id[0] = 0 continue seek // iterator exhausted } - if now.Sub(db.LastPongReceived(n.ID(), n.IP())) > maxAge { + if now.Sub(db.LastPongReceived(n.ID(), n.IPAddr())) > maxAge { continue seek } for i := range nodes { @@ -501,7 +501,11 @@ func nextNode(it iterator.Iterator) *Node { // Close flushes and closes the database files. func (db *DB) Close() { - close(db.quit) + select { + case <-db.quit: // already closed + default: + close(db.quit) + } db.lvl.Close() } diff --git a/p2p/enode/nodedb_test.go b/p2p/enode/nodedb_test.go index 38764f31b1..bc0291665d 100644 --- a/p2p/enode/nodedb_test.go +++ b/p2p/enode/nodedb_test.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "net" + "net/netip" "path/filepath" "reflect" "testing" @@ -48,8 +49,10 @@ func TestDBNodeKey(t *testing.T) { } func TestDBNodeItemKey(t *testing.T) { - wantIP := net.IP{127, 0, 0, 3} + wantIP := netip.MustParseAddr("127.0.0.3") + wantIP4in6 := netip.AddrFrom16(wantIP.As16()) wantField := "foobar" + enc := nodeItemKey(keytestID, wantIP, wantField) want := []byte{ 'n', ':', @@ -69,7 +72,7 @@ func TestDBNodeItemKey(t *testing.T) { if id != keytestID { t.Errorf("splitNodeItemKey returned wrong ID: %v", id) } - if !ip.Equal(wantIP) { + if ip != wantIP4in6 { t.Errorf("splitNodeItemKey returned wrong IP: %v", ip) } if field != wantField { @@ -123,33 +126,33 @@ func TestDBFetchStore(t *testing.T) { defer db.Close() // Check fetch/store operations on a node ping object - if stored := db.LastPingReceived(node.ID(), node.IP()); stored.Unix() != 0 { + if stored := db.LastPingReceived(node.ID(), node.IPAddr()); stored.Unix() != 0 { t.Errorf("ping: non-existing object: %v", stored) } - if err := db.UpdateLastPingReceived(node.ID(), node.IP(), inst); err != nil { + if err := db.UpdateLastPingReceived(node.ID(), node.IPAddr(), inst); err != nil { t.Errorf("ping: failed to update: %v", err) } - if stored := db.LastPingReceived(node.ID(), node.IP()); stored.Unix() != inst.Unix() { + if stored := db.LastPingReceived(node.ID(), node.IPAddr()); stored.Unix() != inst.Unix() { t.Errorf("ping: value mismatch: have %v, want %v", stored, inst) } // Check fetch/store operations on a node pong object - if stored := db.LastPongReceived(node.ID(), node.IP()); stored.Unix() != 0 { + if stored := db.LastPongReceived(node.ID(), node.IPAddr()); stored.Unix() != 0 { t.Errorf("pong: non-existing object: %v", stored) } - if err := db.UpdateLastPongReceived(node.ID(), node.IP(), inst); err != nil { + if err := db.UpdateLastPongReceived(node.ID(), node.IPAddr(), inst); err != nil { t.Errorf("pong: failed to update: %v", err) } - if stored := db.LastPongReceived(node.ID(), node.IP()); stored.Unix() != inst.Unix() { + if stored := db.LastPongReceived(node.ID(), node.IPAddr()); stored.Unix() != inst.Unix() { t.Errorf("pong: value mismatch: have %v, want %v", stored, inst) } // Check fetch/store operations on a node findnode-failure object - if stored := db.FindFails(node.ID(), node.IP()); stored != 0 { + if stored := db.FindFails(node.ID(), node.IPAddr()); stored != 0 { t.Errorf("find-node fails: non-existing object: %v", stored) } - if err := db.UpdateFindFails(node.ID(), node.IP(), num); err != nil { + if err := db.UpdateFindFails(node.ID(), node.IPAddr(), num); err != nil { t.Errorf("find-node fails: failed to update: %v", err) } - if stored := db.FindFails(node.ID(), node.IP()); stored != num { + if stored := db.FindFails(node.ID(), node.IPAddr()); stored != num { t.Errorf("find-node fails: value mismatch: have %v, want %v", stored, num) } // Check fetch/store operations on an actual node object @@ -266,7 +269,7 @@ func testSeedQuery() error { if err := db.UpdateNode(seed.node); err != nil { return fmt.Errorf("node %d: failed to insert: %v", i, err) } - if err := db.UpdateLastPongReceived(seed.node.ID(), seed.node.IP(), seed.pong); err != nil { + if err := db.UpdateLastPongReceived(seed.node.ID(), seed.node.IPAddr(), seed.pong); err != nil { return fmt.Errorf("node %d: failed to insert bondTime: %v", i, err) } } @@ -427,7 +430,7 @@ func TestDBExpiration(t *testing.T) { t.Fatalf("node %d: failed to insert: %v", i, err) } } - if err := db.UpdateLastPongReceived(seed.node.ID(), seed.node.IP(), seed.pong); err != nil { + if err := db.UpdateLastPongReceived(seed.node.ID(), seed.node.IPAddr(), seed.pong); err != nil { t.Fatalf("node %d: failed to update bondTime: %v", i, err) } } @@ -438,13 +441,13 @@ func TestDBExpiration(t *testing.T) { unixZeroTime := time.Unix(0, 0) for i, seed := range nodeDBExpirationNodes { node := db.Node(seed.node.ID()) - pong := db.LastPongReceived(seed.node.ID(), seed.node.IP()) + pong := db.LastPongReceived(seed.node.ID(), seed.node.IPAddr()) if seed.exp { if seed.storeNode && node != nil { t.Errorf("node %d (%s) shouldn't be present after expiration", i, seed.node.ID().TerminalString()) } if !pong.Equal(unixZeroTime) { - t.Errorf("pong time %d (%s %v) shouldn't be present after expiration", i, seed.node.ID().TerminalString(), seed.node.IP()) + t.Errorf("pong time %d (%s %v) shouldn't be present after expiration", i, seed.node.ID().TerminalString(), seed.node.IPAddr()) } } else { if seed.storeNode && node == nil { @@ -463,7 +466,7 @@ func TestDBExpireV5(t *testing.T) { db, _ := OpenDB("") defer db.Close() - ip := net.IP{127, 0, 0, 1} + ip := netip.MustParseAddr("127.0.0.1") db.UpdateFindFailsV5(ID{}, ip, 4) db.expireNodes() } diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index 0272eee987..a55dfa6632 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -181,7 +181,7 @@ func (n *Node) URLv4() string { nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:]) } u := url.URL{Scheme: "enode"} - if n.Incomplete() { + if !n.ip.IsValid() { u.Host = nodeid } else { addr := net.TCPAddr{IP: n.IP(), Port: n.TCP()} diff --git a/p2p/enr/enr_test.go b/p2p/enr/enr_test.go index b85ee209d5..4fccb0cce9 100644 --- a/p2p/enr/enr_test.go +++ b/p2p/enr/enr_test.go @@ -48,7 +48,7 @@ func TestGetSetID(t *testing.T) { assert.Equal(t, id, id2) } -// TestGetSetIP4 tests encoding/decoding and setting/getting of the IP key. +// TestGetSetIPv4 tests encoding/decoding and setting/getting of the IP key. func TestGetSetIPv4(t *testing.T) { ip := IPv4{192, 168, 0, 3} var r Record @@ -59,7 +59,7 @@ func TestGetSetIPv4(t *testing.T) { assert.Equal(t, ip, ip2) } -// TestGetSetIP6 tests encoding/decoding and setting/getting of the IP6 key. +// TestGetSetIPv6 tests encoding/decoding and setting/getting of the IP6 key. func TestGetSetIPv6(t *testing.T) { ip := IPv6{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68} var r Record diff --git a/p2p/enr/entries.go b/p2p/enr/entries.go index 9945a436c9..58e660c154 100644 --- a/p2p/enr/entries.go +++ b/p2p/enr/entries.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net" + "net/netip" "github.com/ethereum/go-ethereum/rlp" ) @@ -76,6 +77,16 @@ type UDP6 uint16 func (v UDP6) ENRKey() string { return "udp6" } +// QUIC is the "quic" key, which holds the QUIC port of the node. +type QUIC uint16 + +func (v QUIC) ENRKey() string { return "quic" } + +// QUIC6 is the "quic6" key, which holds the IPv6-specific quic6 port of the node. +type QUIC6 uint16 + +func (v QUIC6) ENRKey() string { return "quic6" } + // ID is the "id" key, which holds the name of the identity scheme. type ID string @@ -167,6 +178,60 @@ func (v *IPv6) DecodeRLP(s *rlp.Stream) error { return nil } +// IPv4Addr is the "ip" key, which holds the IP address of the node. +type IPv4Addr netip.Addr + +func (v IPv4Addr) ENRKey() string { return "ip" } + +// EncodeRLP implements rlp.Encoder. +func (v IPv4Addr) EncodeRLP(w io.Writer) error { + addr := netip.Addr(v) + if !addr.Is4() { + return errors.New("address is not IPv4") + } + enc := rlp.NewEncoderBuffer(w) + bytes := addr.As4() + enc.WriteBytes(bytes[:]) + return enc.Flush() +} + +// DecodeRLP implements rlp.Decoder. +func (v *IPv4Addr) DecodeRLP(s *rlp.Stream) error { + var bytes [4]byte + if err := s.ReadBytes(bytes[:]); err != nil { + return err + } + *v = IPv4Addr(netip.AddrFrom4(bytes)) + return nil +} + +// IPv6Addr is the "ip6" key, which holds the IP address of the node. +type IPv6Addr netip.Addr + +func (v IPv6Addr) ENRKey() string { return "ip6" } + +// EncodeRLP implements rlp.Encoder. +func (v IPv6Addr) EncodeRLP(w io.Writer) error { + addr := netip.Addr(v) + if !addr.Is6() { + return errors.New("address is not IPv6") + } + enc := rlp.NewEncoderBuffer(w) + bytes := addr.As16() + enc.WriteBytes(bytes[:]) + return enc.Flush() +} + +// DecodeRLP implements rlp.Decoder. +func (v *IPv6Addr) DecodeRLP(s *rlp.Stream) error { + var bytes [16]byte + if err := s.ReadBytes(bytes[:]); err != nil { + return err + } + *v = IPv6Addr(netip.AddrFrom16(bytes)) + return nil +} + // KeyError is an error related to a key. type KeyError struct { Key string diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index 46b786a42c..979faa3edf 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -140,8 +140,10 @@ func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", ne // These do nothing. -func (ExtIP) AddMapping(string, int, int, string, time.Duration) (uint16, error) { return 0, nil } -func (ExtIP) DeleteMapping(string, int, int) error { return nil } +func (ExtIP) AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) (uint16, error) { + return uint16(extport), nil +} +func (ExtIP) DeleteMapping(string, int, int) error { return nil } // Any returns a port mapper that tries to discover any supported // mechanism on the local network. diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index 387c1dc1cb..5605efa1aa 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -27,7 +27,7 @@ import ( natpmp "github.com/jackpal/go-nat-pmp" ) -// natPMPClient adapts the NAT-PMP protocol implementation so it conforms to +// pmp adapts the NAT-PMP protocol implementation so it conforms to // the common interface. type pmp struct { gw net.IP diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index c90c4f3de8..f1bb955892 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -205,8 +205,8 @@ func discoverUPnP() Interface { return nil } -// finds devices matching the given target and calls matcher for all -// advertised services of each device. The first non-nil service found +// discover finds devices matching the given target and calls matcher for +// all advertised services of each device. The first non-nil service found // is sent into out. If no service matched, nil is sent. func discover(out chan<- *upnp, target string, matcher func(goupnp.ServiceClient) *upnp) { devs, err := goupnp.DiscoverDevices(target) diff --git a/p2p/netutil/addrutil.go b/p2p/netutil/addrutil.go index fb6d8d2731..b8b318571b 100644 --- a/p2p/netutil/addrutil.go +++ b/p2p/netutil/addrutil.go @@ -16,18 +16,53 @@ package netutil -import "net" +import ( + "fmt" + "math/rand" + "net" + "net/netip" +) -// AddrIP gets the IP address contained in addr. It returns nil if no address is present. -func AddrIP(addr net.Addr) net.IP { +// AddrAddr gets the IP address contained in addr. The result will be invalid if the +// address type is unsupported. +func AddrAddr(addr net.Addr) netip.Addr { switch a := addr.(type) { case *net.IPAddr: - return a.IP + return IPToAddr(a.IP) case *net.TCPAddr: - return a.IP + return IPToAddr(a.IP) case *net.UDPAddr: - return a.IP + return IPToAddr(a.IP) default: - return nil + return netip.Addr{} } } + +// IPToAddr converts net.IP to netip.Addr. Note that unlike netip.AddrFromSlice, this +// function will always ensure that the resulting Addr is IPv4 when the input is. +func IPToAddr(ip net.IP) netip.Addr { + if ip4 := ip.To4(); ip4 != nil { + addr, _ := netip.AddrFromSlice(ip4) + return addr + } else if ip6 := ip.To16(); ip6 != nil { + addr, _ := netip.AddrFromSlice(ip6) + return addr + } + return netip.Addr{} +} + +// RandomAddr creates a random IP address. +func RandomAddr(rng *rand.Rand, ipv4 bool) netip.Addr { + var bytes []byte + if ipv4 || rng.Intn(2) == 0 { + bytes = make([]byte, 4) + } else { + bytes = make([]byte, 16) + } + rng.Read(bytes) + addr, ok := netip.AddrFromSlice(bytes) + if !ok { + panic(fmt.Errorf("BUG! invalid IP %v", bytes)) + } + return addr +} diff --git a/p2p/netutil/iptrack.go b/p2p/netutil/iptrack.go index a070499e19..5140ac7539 100644 --- a/p2p/netutil/iptrack.go +++ b/p2p/netutil/iptrack.go @@ -17,6 +17,7 @@ package netutil import ( + "net/netip" "time" "github.com/ethereum/go-ethereum/common/mclock" @@ -29,14 +30,14 @@ type IPTracker struct { contactWindow time.Duration minStatements int clock mclock.Clock - statements map[string]ipStatement - contact map[string]mclock.AbsTime + statements map[netip.Addr]ipStatement + contact map[netip.Addr]mclock.AbsTime lastStatementGC mclock.AbsTime lastContactGC mclock.AbsTime } type ipStatement struct { - endpoint string + endpoint netip.AddrPort time mclock.AbsTime } @@ -51,9 +52,9 @@ func NewIPTracker(window, contactWindow time.Duration, minStatements int) *IPTra return &IPTracker{ window: window, contactWindow: contactWindow, - statements: make(map[string]ipStatement), + statements: make(map[netip.Addr]ipStatement), minStatements: minStatements, - contact: make(map[string]mclock.AbsTime), + contact: make(map[netip.Addr]mclock.AbsTime), clock: mclock.System{}, } } @@ -74,12 +75,15 @@ func (it *IPTracker) PredictFullConeNAT() bool { } // PredictEndpoint returns the current prediction of the external endpoint. -func (it *IPTracker) PredictEndpoint() string { +func (it *IPTracker) PredictEndpoint() netip.AddrPort { it.gcStatements(it.clock.Now()) // The current strategy is simple: find the endpoint with most statements. - counts := make(map[string]int, len(it.statements)) - maxcount, max := 0, "" + var ( + counts = make(map[netip.AddrPort]int, len(it.statements)) + maxcount int + max netip.AddrPort + ) for _, s := range it.statements { c := counts[s.endpoint] + 1 counts[s.endpoint] = c @@ -91,7 +95,7 @@ func (it *IPTracker) PredictEndpoint() string { } // AddStatement records that a certain host thinks our external endpoint is the one given. -func (it *IPTracker) AddStatement(host, endpoint string) { +func (it *IPTracker) AddStatement(host netip.Addr, endpoint netip.AddrPort) { now := it.clock.Now() it.statements[host] = ipStatement{endpoint, now} if time.Duration(now-it.lastStatementGC) >= it.window { @@ -101,7 +105,7 @@ func (it *IPTracker) AddStatement(host, endpoint string) { // AddContact records that a packet containing our endpoint information has been sent to a // certain host. -func (it *IPTracker) AddContact(host string) { +func (it *IPTracker) AddContact(host netip.Addr) { now := it.clock.Now() it.contact[host] = now if time.Duration(now-it.lastContactGC) >= it.contactWindow { diff --git a/p2p/netutil/iptrack_test.go b/p2p/netutil/iptrack_test.go index ee3bba861e..81653a2733 100644 --- a/p2p/netutil/iptrack_test.go +++ b/p2p/netutil/iptrack_test.go @@ -19,6 +19,7 @@ package netutil import ( crand "crypto/rand" "fmt" + "net/netip" "testing" "time" @@ -42,37 +43,37 @@ func TestIPTracker(t *testing.T) { tests := map[string][]iptrackTestEvent{ "minStatements": { {opPredict, 0, "", ""}, - {opStatement, 0, "127.0.0.1", "127.0.0.2"}, + {opStatement, 0, "127.0.0.1:8000", "127.0.0.2"}, {opPredict, 1000, "", ""}, - {opStatement, 1000, "127.0.0.1", "127.0.0.3"}, + {opStatement, 1000, "127.0.0.1:8000", "127.0.0.3"}, {opPredict, 1000, "", ""}, - {opStatement, 1000, "127.0.0.1", "127.0.0.4"}, - {opPredict, 1000, "127.0.0.1", ""}, + {opStatement, 1000, "127.0.0.1:8000", "127.0.0.4"}, + {opPredict, 1000, "127.0.0.1:8000", ""}, }, "window": { - {opStatement, 0, "127.0.0.1", "127.0.0.2"}, - {opStatement, 2000, "127.0.0.1", "127.0.0.3"}, - {opStatement, 3000, "127.0.0.1", "127.0.0.4"}, - {opPredict, 10000, "127.0.0.1", ""}, + {opStatement, 0, "127.0.0.1:8000", "127.0.0.2"}, + {opStatement, 2000, "127.0.0.1:8000", "127.0.0.3"}, + {opStatement, 3000, "127.0.0.1:8000", "127.0.0.4"}, + {opPredict, 10000, "127.0.0.1:8000", ""}, {opPredict, 10001, "", ""}, // first statement expired - {opStatement, 10100, "127.0.0.1", "127.0.0.2"}, - {opPredict, 10200, "127.0.0.1", ""}, + {opStatement, 10100, "127.0.0.1:8000", "127.0.0.2"}, + {opPredict, 10200, "127.0.0.1:8000", ""}, }, "fullcone": { {opContact, 0, "", "127.0.0.2"}, - {opStatement, 10, "127.0.0.1", "127.0.0.2"}, + {opStatement, 10, "127.0.0.1:8000", "127.0.0.2"}, {opContact, 2000, "", "127.0.0.3"}, - {opStatement, 2010, "127.0.0.1", "127.0.0.3"}, + {opStatement, 2010, "127.0.0.1:8000", "127.0.0.3"}, {opContact, 3000, "", "127.0.0.4"}, - {opStatement, 3010, "127.0.0.1", "127.0.0.4"}, + {opStatement, 3010, "127.0.0.1:8000", "127.0.0.4"}, {opCheckFullCone, 3500, "false", ""}, }, "fullcone_2": { {opContact, 0, "", "127.0.0.2"}, - {opStatement, 10, "127.0.0.1", "127.0.0.2"}, + {opStatement, 10, "127.0.0.1:8000", "127.0.0.2"}, {opContact, 2000, "", "127.0.0.3"}, - {opStatement, 2010, "127.0.0.1", "127.0.0.3"}, - {opStatement, 3000, "127.0.0.1", "127.0.0.4"}, + {opStatement, 2010, "127.0.0.1:8000", "127.0.0.3"}, + {opStatement, 3000, "127.0.0.1:8000", "127.0.0.4"}, {opContact, 3010, "", "127.0.0.4"}, {opCheckFullCone, 3500, "true", ""}, }, @@ -93,12 +94,19 @@ func runIPTrackerTest(t *testing.T, evs []iptrackTestEvent) { clock.Run(evtime - time.Duration(clock.Now())) switch ev.op { case opStatement: - it.AddStatement(ev.from, ev.ip) + it.AddStatement(netip.MustParseAddr(ev.from), netip.MustParseAddrPort(ev.ip)) case opContact: - it.AddContact(ev.from) + it.AddContact(netip.MustParseAddr(ev.from)) case opPredict: - if pred := it.PredictEndpoint(); pred != ev.ip { - t.Errorf("op %d: wrong prediction %q, want %q", i, pred, ev.ip) + pred := it.PredictEndpoint() + if ev.ip == "" { + if pred.IsValid() { + t.Errorf("op %d: wrong prediction %v, expected invalid", i, pred) + } + } else { + if pred != netip.MustParseAddrPort(ev.ip) { + t.Errorf("op %d: wrong prediction %v, want %q", i, pred, ev.ip) + } } case opCheckFullCone: pred := fmt.Sprintf("%t", it.PredictFullConeNAT()) @@ -121,12 +129,11 @@ func TestIPTrackerForceGC(t *testing.T) { it.clock = &clock for i := 0; i < 5*max; i++ { - e1 := make([]byte, 4) - e2 := make([]byte, 4) - crand.Read(e1) - crand.Read(e2) - it.AddStatement(string(e1), string(e2)) - it.AddContact(string(e1)) + var e1, e2 [4]byte + crand.Read(e1[:]) + crand.Read(e2[:]) + it.AddStatement(netip.AddrFrom4(e1), netip.AddrPortFrom(netip.AddrFrom4(e2), 9000)) + it.AddContact(netip.AddrFrom4(e1)) clock.Run(rate) } if len(it.contact) > 2*max { diff --git a/p2p/netutil/net.go b/p2p/netutil/net.go index d5da3c694f..7d8da88670 100644 --- a/p2p/netutil/net.go +++ b/p2p/netutil/net.go @@ -22,21 +22,19 @@ import ( "errors" "fmt" "net" - "sort" + "net/netip" + "slices" "strings" + + "golang.org/x/exp/maps" ) -var lan4, lan6, special4, special6 Netlist +var special4, special6 Netlist func init() { // Lists from RFC 5735, RFC 5156, // https://www.iana.org/assignments/iana-ipv4-special-registry/ - lan4.Add("0.0.0.0/8") // "This" network - lan4.Add("10.0.0.0/8") // Private Use - lan4.Add("172.16.0.0/12") // Private Use - lan4.Add("192.168.0.0/16") // Private Use - lan6.Add("fe80::/10") // Link-Local - lan6.Add("fc00::/7") // Unique-Local + special4.Add("0.0.0.0/8") // "This" network. special4.Add("192.0.0.0/29") // IPv4 Service Continuity special4.Add("192.0.0.9/32") // PCP Anycast special4.Add("192.0.0.170/32") // NAT64/DNS64 Discovery @@ -66,7 +64,7 @@ func init() { } // Netlist is a list of IP networks. -type Netlist []net.IPNet +type Netlist []netip.Prefix // ParseNetlist parses a comma-separated list of CIDR masks. // Whitespace and extra commas are ignored. @@ -78,11 +76,11 @@ func ParseNetlist(s string) (*Netlist, error) { if mask == "" { continue } - _, n, err := net.ParseCIDR(mask) + prefix, err := netip.ParsePrefix(mask) if err != nil { return nil, err } - l = append(l, *n) + l = append(l, prefix) } return &l, nil } @@ -103,11 +101,11 @@ func (l *Netlist) UnmarshalTOML(fn func(interface{}) error) error { return err } for _, mask := range masks { - _, n, err := net.ParseCIDR(mask) + prefix, err := netip.ParsePrefix(mask) if err != nil { return err } - *l = append(*l, *n) + *l = append(*l, prefix) } return nil } @@ -115,15 +113,20 @@ func (l *Netlist) UnmarshalTOML(fn func(interface{}) error) error { // Add parses a CIDR mask and appends it to the list. It panics for invalid masks and is // intended to be used for setting up static lists. func (l *Netlist) Add(cidr string) { - _, n, err := net.ParseCIDR(cidr) + prefix, err := netip.ParsePrefix(cidr) if err != nil { panic(err) } - *l = append(*l, *n) + *l = append(*l, prefix) } // Contains reports whether the given IP is contained in the list. func (l *Netlist) Contains(ip net.IP) bool { + return l.ContainsAddr(IPToAddr(ip)) +} + +// ContainsAddr reports whether the given IP is contained in the list. +func (l *Netlist) ContainsAddr(ip netip.Addr) bool { if l == nil { return false } @@ -137,25 +140,39 @@ func (l *Netlist) Contains(ip net.IP) bool { // IsLAN reports whether an IP is a local network address. func IsLAN(ip net.IP) bool { + return AddrIsLAN(IPToAddr(ip)) +} + +// AddrIsLAN reports whether an IP is a local network address. +func AddrIsLAN(ip netip.Addr) bool { + if ip.Is4In6() { + ip = netip.AddrFrom4(ip.As4()) + } if ip.IsLoopback() { return true } - if v4 := ip.To4(); v4 != nil { - return lan4.Contains(v4) - } - return lan6.Contains(ip) + return ip.IsPrivate() || ip.IsLinkLocalUnicast() } // IsSpecialNetwork reports whether an IP is located in a special-use network range // This includes broadcast, multicast and documentation addresses. func IsSpecialNetwork(ip net.IP) bool { + return AddrIsSpecialNetwork(IPToAddr(ip)) +} + +// AddrIsSpecialNetwork reports whether an IP is located in a special-use network range +// This includes broadcast, multicast and documentation addresses. +func AddrIsSpecialNetwork(ip netip.Addr) bool { + if ip.Is4In6() { + ip = netip.AddrFrom4(ip.As4()) + } if ip.IsMulticast() { return true } - if v4 := ip.To4(); v4 != nil { - return special4.Contains(v4) + if ip.Is4() { + return special4.ContainsAddr(ip) } - return special6.Contains(ip) + return special6.ContainsAddr(ip) } var ( @@ -175,19 +192,31 @@ var ( // - LAN addresses are OK if relayed by a LAN host. // - All other addresses are always acceptable. func CheckRelayIP(sender, addr net.IP) error { - if len(addr) != net.IPv4len && len(addr) != net.IPv6len { + return CheckRelayAddr(IPToAddr(sender), IPToAddr(addr)) +} + +// CheckRelayAddr reports whether an IP relayed from the given sender IP +// is a valid connection target. +// +// There are four rules: +// - Special network addresses are never valid. +// - Loopback addresses are OK if relayed by a loopback host. +// - LAN addresses are OK if relayed by a LAN host. +// - All other addresses are always acceptable. +func CheckRelayAddr(sender, addr netip.Addr) error { + if !addr.IsValid() { return errInvalid } if addr.IsUnspecified() { return errUnspecified } - if IsSpecialNetwork(addr) { + if AddrIsSpecialNetwork(addr) { return errSpecial } if addr.IsLoopback() && !sender.IsLoopback() { return errLoopback } - if IsLAN(addr) && !IsLAN(sender) { + if AddrIsLAN(addr) && !AddrIsLAN(sender) { return errLAN } return nil @@ -221,17 +250,22 @@ type DistinctNetSet struct { Subnet uint // number of common prefix bits Limit uint // maximum number of IPs in each subnet - members map[string]uint - buf net.IP + members map[netip.Prefix]uint } // Add adds an IP address to the set. It returns false (and doesn't add the IP) if the // number of existing IPs in the defined range exceeds the limit. func (s *DistinctNetSet) Add(ip net.IP) bool { + return s.AddAddr(IPToAddr(ip)) +} + +// AddAddr adds an IP address to the set. It returns false (and doesn't add the IP) if the +// number of existing IPs in the defined range exceeds the limit. +func (s *DistinctNetSet) AddAddr(ip netip.Addr) bool { key := s.key(ip) - n := s.members[string(key)] + n := s.members[key] if n < s.Limit { - s.members[string(key)] = n + 1 + s.members[key] = n + 1 return true } return false @@ -239,20 +273,30 @@ func (s *DistinctNetSet) Add(ip net.IP) bool { // Remove removes an IP from the set. func (s *DistinctNetSet) Remove(ip net.IP) { + s.RemoveAddr(IPToAddr(ip)) +} + +// RemoveAddr removes an IP from the set. +func (s *DistinctNetSet) RemoveAddr(ip netip.Addr) { key := s.key(ip) - if n, ok := s.members[string(key)]; ok { + if n, ok := s.members[key]; ok { if n == 1 { - delete(s.members, string(key)) + delete(s.members, key) } else { - s.members[string(key)] = n - 1 + s.members[key] = n - 1 } } } -// Contains whether the given IP is contained in the set. +// Contains reports whether the given IP is contained in the set. func (s DistinctNetSet) Contains(ip net.IP) bool { + return s.ContainsAddr(IPToAddr(ip)) +} + +// ContainsAddr reports whether the given IP is contained in the set. +func (s DistinctNetSet) ContainsAddr(ip netip.Addr) bool { key := s.key(ip) - _, ok := s.members[string(key)] + _, ok := s.members[key] return ok } @@ -265,54 +309,30 @@ func (s DistinctNetSet) Len() int { return int(n) } -// key encodes the map key for an address into a temporary buffer. -// -// The first byte of key is '4' or '6' to distinguish IPv4/IPv6 address types. -// The remainder of the key is the IP, truncated to the number of bits. -func (s *DistinctNetSet) key(ip net.IP) net.IP { +// key returns the map key for ip. +func (s *DistinctNetSet) key(ip netip.Addr) netip.Prefix { // Lazily initialize storage. if s.members == nil { - s.members = make(map[string]uint) - s.buf = make(net.IP, 17) - } - // Canonicalize ip and bits. - typ := byte('6') - if ip4 := ip.To4(); ip4 != nil { - typ, ip = '4', ip4 + s.members = make(map[netip.Prefix]uint) } - bits := s.Subnet - if bits > uint(len(ip)*8) { - bits = uint(len(ip) * 8) - } - // Encode the prefix into s.buf. - nb := int(bits / 8) - mask := ^byte(0xFF >> (bits % 8)) - s.buf[0] = typ - buf := append(s.buf[:1], ip[:nb]...) - if nb < len(ip) && mask != 0 { - buf = append(buf, ip[nb]&mask) + p, err := ip.Prefix(int(s.Subnet)) + if err != nil { + panic(err) } - return buf + return p } // String implements fmt.Stringer func (s DistinctNetSet) String() string { + keys := maps.Keys(s.members) + slices.SortFunc(keys, func(a, b netip.Prefix) int { + return strings.Compare(a.String(), b.String()) + }) + var buf bytes.Buffer buf.WriteString("{") - keys := make([]string, 0, len(s.members)) - for k := range s.members { - keys = append(keys, k) - } - sort.Strings(keys) for i, k := range keys { - var ip net.IP - if k[0] == '4' { - ip = make(net.IP, 4) - } else { - ip = make(net.IP, 16) - } - copy(ip, k[1:]) - fmt.Fprintf(&buf, "%v×%d", ip, s.members[k]) + fmt.Fprintf(&buf, "%v×%d", k, s.members[k]) if i != len(keys)-1 { buf.WriteString(" ") } diff --git a/p2p/netutil/net_test.go b/p2p/netutil/net_test.go index 3a6aa081f2..569c7ac454 100644 --- a/p2p/netutil/net_test.go +++ b/p2p/netutil/net_test.go @@ -18,7 +18,9 @@ package netutil import ( "fmt" + "math/rand" "net" + "net/netip" "reflect" "testing" "testing/quick" @@ -29,7 +31,7 @@ import ( func TestParseNetlist(t *testing.T) { var tests = []struct { input string - wantErr error + wantErr string wantList *Netlist }{ { @@ -38,25 +40,27 @@ func TestParseNetlist(t *testing.T) { }, { input: "127.0.0.0/8", - wantErr: nil, - wantList: &Netlist{{IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(8, 32)}}, + wantList: &Netlist{netip.MustParsePrefix("127.0.0.0/8")}, }, { input: "127.0.0.0/44", - wantErr: &net.ParseError{Type: "CIDR address", Text: "127.0.0.0/44"}, + wantErr: `netip.ParsePrefix("127.0.0.0/44"): prefix length out of range`, }, { input: "127.0.0.0/16, 23.23.23.23/24,", wantList: &Netlist{ - {IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(16, 32)}, - {IP: net.IP{23, 23, 23, 0}, Mask: net.CIDRMask(24, 32)}, + netip.MustParsePrefix("127.0.0.0/16"), + netip.MustParsePrefix("23.23.23.23/24"), }, }, } for _, test := range tests { l, err := ParseNetlist(test.input) - if !reflect.DeepEqual(err, test.wantErr) { + if err == nil && test.wantErr != "" { + t.Errorf("%q: got no error, expected %q", test.input, test.wantErr) + continue + } else if err != nil && err.Error() != test.wantErr { t.Errorf("%q: got error %q, want %q", test.input, err, test.wantErr) continue } @@ -70,14 +74,12 @@ func TestParseNetlist(t *testing.T) { func TestNilNetListContains(t *testing.T) { var list *Netlist - checkContains(t, list.Contains, nil, []string{"1.2.3.4"}) + checkContains(t, list.Contains, list.ContainsAddr, nil, []string{"1.2.3.4"}) } func TestIsLAN(t *testing.T) { - checkContains(t, IsLAN, + checkContains(t, IsLAN, AddrIsLAN, []string{ // included - "0.0.0.0", - "0.2.0.8", "127.0.0.1", "10.0.1.1", "10.22.0.3", @@ -86,25 +88,35 @@ func TestIsLAN(t *testing.T) { "fe80::f4a1:8eff:fec5:9d9d", "febf::ab32:2233", "fc00::4", + // 4-in-6 + "::ffff:127.0.0.1", + "::ffff:10.10.0.2", }, []string{ // excluded "192.0.2.1", "1.0.0.0", "172.32.0.1", "fec0::2233", + // 4-in-6 + "::ffff:88.99.100.2", }, ) } func TestIsSpecialNetwork(t *testing.T) { - checkContains(t, IsSpecialNetwork, + checkContains(t, IsSpecialNetwork, AddrIsSpecialNetwork, []string{ // included + "0.0.0.0", + "0.2.0.8", "192.0.2.1", "192.0.2.44", "2001:db8:85a3:8d3:1319:8a2e:370:7348", "255.255.255.255", "224.0.0.22", // IPv4 multicast "ff05::1:3", // IPv6 multicast + // 4-in-6 + "::ffff:255.255.255.255", + "::ffff:192.0.2.1", }, []string{ // excluded "192.0.3.1", @@ -115,15 +127,21 @@ func TestIsSpecialNetwork(t *testing.T) { ) } -func checkContains(t *testing.T, fn func(net.IP) bool, inc, exc []string) { +func checkContains(t *testing.T, fn func(net.IP) bool, fn2 func(netip.Addr) bool, inc, exc []string) { for _, s := range inc { if !fn(parseIP(s)) { - t.Error("returned false for included address", s) + t.Error("returned false for included net.IP", s) + } + if !fn2(netip.MustParseAddr(s)) { + t.Error("returned false for included netip.Addr", s) } } for _, s := range exc { if fn(parseIP(s)) { - t.Error("returned true for excluded address", s) + t.Error("returned true for excluded net.IP", s) + } + if fn2(netip.MustParseAddr(s)) { + t.Error("returned true for excluded netip.Addr", s) } } } @@ -244,14 +262,22 @@ func TestDistinctNetSet(t *testing.T) { } func TestDistinctNetSetAddRemove(t *testing.T) { - cfg := &quick.Config{} - fn := func(ips []net.IP) bool { + cfg := &quick.Config{ + Values: func(s []reflect.Value, rng *rand.Rand) { + slice := make([]netip.Addr, rng.Intn(20)+1) + for i := range slice { + slice[i] = RandomAddr(rng, false) + } + s[0] = reflect.ValueOf(slice) + }, + } + fn := func(ips []netip.Addr) bool { s := DistinctNetSet{Limit: 3, Subnet: 2} for _, ip := range ips { - s.Add(ip) + s.AddAddr(ip) } for _, ip := range ips { - s.Remove(ip) + s.RemoveAddr(ip) } return s.Len() == 0 } diff --git a/p2p/nodestate/nodestate.go b/p2p/nodestate/nodestate.go deleted file mode 100644 index 1e1757559c..0000000000 --- a/p2p/nodestate/nodestate.go +++ /dev/null @@ -1,1023 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package nodestate - -import ( - "errors" - "reflect" - "sync" - "time" - "unsafe" - - "github.com/ethereum/go-ethereum/common/mclock" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/rlp" -) - -var ( - ErrInvalidField = errors.New("invalid field type") - ErrClosed = errors.New("already closed") -) - -type ( - // NodeStateMachine implements a network node-related event subscription system. - // It can assign binary state flags and fields of arbitrary type to each node and allows - // subscriptions to flag/field changes which can also modify further flags and fields, - // potentially triggering further subscriptions. An operation includes an initial change - // and all resulting subsequent changes and always ends in a consistent global state. - // It is initiated by a "top level" SetState/SetField call that blocks (also blocking other - // top-level functions) until the operation is finished. Callbacks making further changes - // should use the non-blocking SetStateSub/SetFieldSub functions. The tree of events - // resulting from the initial changes is traversed in a breadth-first order, ensuring for - // each subscription callback that all other callbacks caused by the same change triggering - // the current callback are processed before anything is triggered by the changes made in the - // current callback. In practice this logic ensures that all subscriptions "see" events in - // the logical order, callbacks are never called concurrently and "back and forth" effects - // are also possible. The state machine design should ensure that infinite event cycles - // cannot happen. - // The caller can also add timeouts assigned to a certain node and a subset of state flags. - // If the timeout elapses, the flags are reset. If all relevant flags are reset then the timer - // is dropped. State flags with no timeout are persisted in the database if the flag - // descriptor enables saving. If a node has no state flags set at any moment then it is discarded. - // Note: in order to avoid mutex deadlocks the callbacks should never lock a mutex that - // might be locked when the top level SetState/SetField functions are called. If a function - // potentially performs state/field changes then it is recommended to mention this fact in the - // function description, along with whether it should run inside an operation callback. - NodeStateMachine struct { - started, closed bool - lock sync.Mutex - clock mclock.Clock - db ethdb.KeyValueStore - dbNodeKey []byte - nodes map[enode.ID]*nodeInfo - offlineCallbackList []offlineCallback - opFlag bool // an operation has started - opWait *sync.Cond // signaled when the operation ends - opPending []func() // pending callback list of the current operation - - // Registered state flags or fields. Modifications are allowed - // only when the node state machine has not been started. - setup *Setup - fields []*fieldInfo - saveFlags bitMask - - // Installed callbacks. Modifications are allowed only when the - // node state machine has not been started. - stateSubs []stateSub - - // Testing hooks, only for testing purposes. - saveNodeHook func(*nodeInfo) - } - - // Flags represents a set of flags from a certain setup - Flags struct { - mask bitMask - setup *Setup - } - - // Field represents a field from a certain setup - Field struct { - index int - setup *Setup - } - - // flagDefinition describes a node state flag. Each registered instance is automatically - // mapped to a bit of the 64 bit node states. - // If persistent is true then the node is saved when state machine is shutdown. - flagDefinition struct { - name string - persistent bool - } - - // fieldDefinition describes an optional node field of the given type. The contents - // of the field are only retained for each node as long as at least one of the - // state flags is set. - fieldDefinition struct { - name string - ftype reflect.Type - encode func(interface{}) ([]byte, error) - decode func([]byte) (interface{}, error) - } - - // Setup contains the list of flags and fields used by the application - Setup struct { - Version uint - flags []flagDefinition - fields []fieldDefinition - } - - // bitMask describes a node state or state mask. It represents a subset - // of node flags with each bit assigned to a flag index (LSB represents flag 0). - bitMask uint64 - - // StateCallback is a subscription callback which is called when one of the - // state flags that is included in the subscription state mask is changed. - // Note: oldState and newState are also masked with the subscription mask so only - // the relevant bits are included. - StateCallback func(n *enode.Node, oldState, newState Flags) - - // FieldCallback is a subscription callback which is called when the value of - // a specific field is changed. - FieldCallback func(n *enode.Node, state Flags, oldValue, newValue interface{}) - - // nodeInfo contains node state, fields and state timeouts - nodeInfo struct { - node *enode.Node - state bitMask - timeouts []*nodeStateTimeout - fields []interface{} - fieldCount int - db, dirty bool - } - - nodeInfoEnc struct { - Enr enr.Record - Version uint - State bitMask - Fields [][]byte - } - - stateSub struct { - mask bitMask - callback StateCallback - } - - nodeStateTimeout struct { - mask bitMask - timer mclock.Timer - } - - fieldInfo struct { - fieldDefinition - subs []FieldCallback - } - - offlineCallback struct { - node *nodeInfo - state bitMask - fields []interface{} - } -) - -// offlineState is a special state that is assumed to be set before a node is loaded from -// the database and after it is shut down. -const offlineState = bitMask(1) - -// NewFlag creates a new node state flag -func (s *Setup) NewFlag(name string) Flags { - if s.flags == nil { - s.flags = []flagDefinition{{name: "offline"}} - } - f := Flags{mask: bitMask(1) << uint(len(s.flags)), setup: s} - s.flags = append(s.flags, flagDefinition{name: name}) - return f -} - -// NewPersistentFlag creates a new persistent node state flag -func (s *Setup) NewPersistentFlag(name string) Flags { - if s.flags == nil { - s.flags = []flagDefinition{{name: "offline"}} - } - f := Flags{mask: bitMask(1) << uint(len(s.flags)), setup: s} - s.flags = append(s.flags, flagDefinition{name: name, persistent: true}) - return f -} - -// OfflineFlag returns the system-defined offline flag belonging to the given setup -func (s *Setup) OfflineFlag() Flags { - return Flags{mask: offlineState, setup: s} -} - -// NewField creates a new node state field -func (s *Setup) NewField(name string, ftype reflect.Type) Field { - f := Field{index: len(s.fields), setup: s} - s.fields = append(s.fields, fieldDefinition{ - name: name, - ftype: ftype, - }) - return f -} - -// NewPersistentField creates a new persistent node field -func (s *Setup) NewPersistentField(name string, ftype reflect.Type, encode func(interface{}) ([]byte, error), decode func([]byte) (interface{}, error)) Field { - f := Field{index: len(s.fields), setup: s} - s.fields = append(s.fields, fieldDefinition{ - name: name, - ftype: ftype, - encode: encode, - decode: decode, - }) - return f -} - -// flagOp implements binary flag operations and also checks whether the operands belong to the same setup -func flagOp(a, b Flags, trueIfA, trueIfB, trueIfBoth bool) Flags { - if a.setup == nil { - if a.mask != 0 { - panic("Node state flags have no setup reference") - } - a.setup = b.setup - } - if b.setup == nil { - if b.mask != 0 { - panic("Node state flags have no setup reference") - } - b.setup = a.setup - } - if a.setup != b.setup { - panic("Node state flags belong to a different setup") - } - res := Flags{setup: a.setup} - if trueIfA { - res.mask |= a.mask & ^b.mask - } - if trueIfB { - res.mask |= b.mask & ^a.mask - } - if trueIfBoth { - res.mask |= a.mask & b.mask - } - return res -} - -// And returns the set of flags present in both a and b -func (a Flags) And(b Flags) Flags { return flagOp(a, b, false, false, true) } - -// AndNot returns the set of flags present in a but not in b -func (a Flags) AndNot(b Flags) Flags { return flagOp(a, b, true, false, false) } - -// Or returns the set of flags present in either a or b -func (a Flags) Or(b Flags) Flags { return flagOp(a, b, true, true, true) } - -// Xor returns the set of flags present in either a or b but not both -func (a Flags) Xor(b Flags) Flags { return flagOp(a, b, true, true, false) } - -// HasAll returns true if b is a subset of a -func (a Flags) HasAll(b Flags) bool { return flagOp(a, b, false, true, false).mask == 0 } - -// HasNone returns true if a and b have no shared flags -func (a Flags) HasNone(b Flags) bool { return flagOp(a, b, false, false, true).mask == 0 } - -// Equals returns true if a and b have the same flags set -func (a Flags) Equals(b Flags) bool { return flagOp(a, b, true, true, false).mask == 0 } - -// IsEmpty returns true if a has no flags set -func (a Flags) IsEmpty() bool { return a.mask == 0 } - -// MergeFlags merges multiple sets of state flags -func MergeFlags(list ...Flags) Flags { - if len(list) == 0 { - return Flags{} - } - res := list[0] - for i := 1; i < len(list); i++ { - res = res.Or(list[i]) - } - return res -} - -// String returns a list of the names of the flags specified in the bit mask -func (f Flags) String() string { - if f.mask == 0 { - return "[]" - } - s := "[" - comma := false - for index, flag := range f.setup.flags { - if f.mask&(bitMask(1)< 8*int(unsafe.Sizeof(bitMask(0))) { - panic("Too many node state flags") - } - ns := &NodeStateMachine{ - db: db, - dbNodeKey: dbKey, - clock: clock, - setup: setup, - nodes: make(map[enode.ID]*nodeInfo), - fields: make([]*fieldInfo, len(setup.fields)), - } - ns.opWait = sync.NewCond(&ns.lock) - stateNameMap := make(map[string]int, len(setup.flags)) - for index, flag := range setup.flags { - if _, ok := stateNameMap[flag.name]; ok { - panic("Node state flag name collision: " + flag.name) - } - stateNameMap[flag.name] = index - if flag.persistent { - ns.saveFlags |= bitMask(1) << uint(index) - } - } - fieldNameMap := make(map[string]int, len(setup.fields)) - for index, field := range setup.fields { - if _, ok := fieldNameMap[field.name]; ok { - panic("Node field name collision: " + field.name) - } - ns.fields[index] = &fieldInfo{fieldDefinition: field} - fieldNameMap[field.name] = index - } - return ns -} - -// stateMask checks whether the set of flags belongs to the same setup and returns its internal bit mask -func (ns *NodeStateMachine) stateMask(flags Flags) bitMask { - if flags.setup != ns.setup && flags.mask != 0 { - panic("Node state flags belong to a different setup") - } - return flags.mask -} - -// fieldIndex checks whether the field belongs to the same setup and returns its internal index -func (ns *NodeStateMachine) fieldIndex(field Field) int { - if field.setup != ns.setup { - panic("Node field belongs to a different setup") - } - return field.index -} - -// SubscribeState adds a node state subscription. The callback is called while the state -// machine mutex is not held and it is allowed to make further state updates using the -// non-blocking SetStateSub/SetFieldSub functions. All callbacks of an operation are running -// from the thread/goroutine of the initial caller and parallel operations are not permitted. -// Therefore the callback is never called concurrently. It is the responsibility of the -// implemented state logic to avoid deadlocks and to reach a stable state in a finite amount -// of steps. -// State subscriptions should be installed before loading the node database or making the -// first state update. -func (ns *NodeStateMachine) SubscribeState(flags Flags, callback StateCallback) { - ns.lock.Lock() - defer ns.lock.Unlock() - - if ns.started { - panic("state machine already started") - } - ns.stateSubs = append(ns.stateSubs, stateSub{ns.stateMask(flags), callback}) -} - -// SubscribeField adds a node field subscription. Same rules apply as for SubscribeState. -func (ns *NodeStateMachine) SubscribeField(field Field, callback FieldCallback) { - ns.lock.Lock() - defer ns.lock.Unlock() - - if ns.started { - panic("state machine already started") - } - f := ns.fields[ns.fieldIndex(field)] - f.subs = append(f.subs, callback) -} - -// newNode creates a new nodeInfo -func (ns *NodeStateMachine) newNode(n *enode.Node) *nodeInfo { - return &nodeInfo{node: n, fields: make([]interface{}, len(ns.fields))} -} - -// checkStarted checks whether the state machine has already been started and panics otherwise. -func (ns *NodeStateMachine) checkStarted() { - if !ns.started { - panic("state machine not started yet") - } -} - -// Start starts the state machine, enabling state and field operations and disabling -// further subscriptions. -func (ns *NodeStateMachine) Start() { - ns.lock.Lock() - if ns.started { - panic("state machine already started") - } - ns.started = true - if ns.db != nil { - ns.loadFromDb() - } - - ns.opStart() - ns.offlineCallbacks(true) - ns.opFinish() - ns.lock.Unlock() -} - -// Stop stops the state machine and saves its state if a database was supplied -func (ns *NodeStateMachine) Stop() { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if !ns.opStart() { - panic("already closed") - } - for _, node := range ns.nodes { - fields := make([]interface{}, len(node.fields)) - copy(fields, node.fields) - ns.offlineCallbackList = append(ns.offlineCallbackList, offlineCallback{node, node.state, fields}) - } - if ns.db != nil { - ns.saveToDb() - } - ns.offlineCallbacks(false) - ns.closed = true - ns.opFinish() -} - -// loadFromDb loads persisted node states from the database -func (ns *NodeStateMachine) loadFromDb() { - it := ns.db.NewIterator(ns.dbNodeKey, nil) - for it.Next() { - var id enode.ID - if len(it.Key()) != len(ns.dbNodeKey)+len(id) { - log.Error("Node state db entry with invalid length", "found", len(it.Key()), "expected", len(ns.dbNodeKey)+len(id)) - continue - } - copy(id[:], it.Key()[len(ns.dbNodeKey):]) - ns.decodeNode(id, it.Value()) - } -} - -type dummyIdentity enode.ID - -func (id dummyIdentity) Verify(r *enr.Record, sig []byte) error { return nil } -func (id dummyIdentity) NodeAddr(r *enr.Record) []byte { return id[:] } - -// decodeNode decodes a node database entry and adds it to the node set if successful -func (ns *NodeStateMachine) decodeNode(id enode.ID, data []byte) { - var enc nodeInfoEnc - if err := rlp.DecodeBytes(data, &enc); err != nil { - log.Error("Failed to decode node info", "id", id, "error", err) - return - } - n, _ := enode.New(dummyIdentity(id), &enc.Enr) - node := ns.newNode(n) - node.db = true - - if enc.Version != ns.setup.Version { - log.Debug("Removing stored node with unknown version", "current", ns.setup.Version, "stored", enc.Version) - ns.deleteNode(id) - return - } - if len(enc.Fields) > len(ns.setup.fields) { - log.Error("Invalid node field count", "id", id, "stored", len(enc.Fields)) - return - } - // Resolve persisted node fields - for i, encField := range enc.Fields { - if len(encField) == 0 { - continue - } - if decode := ns.fields[i].decode; decode != nil { - if field, err := decode(encField); err == nil { - node.fields[i] = field - node.fieldCount++ - } else { - log.Error("Failed to decode node field", "id", id, "field name", ns.fields[i].name, "error", err) - return - } - } else { - log.Error("Cannot decode node field", "id", id, "field name", ns.fields[i].name) - return - } - } - // It's a compatible node record, add it to set. - ns.nodes[id] = node - node.state = enc.State - fields := make([]interface{}, len(node.fields)) - copy(fields, node.fields) - ns.offlineCallbackList = append(ns.offlineCallbackList, offlineCallback{node, node.state, fields}) - log.Debug("Loaded node state", "id", id, "state", Flags{mask: enc.State, setup: ns.setup}) -} - -// saveNode saves the given node info to the database -func (ns *NodeStateMachine) saveNode(id enode.ID, node *nodeInfo) error { - if ns.db == nil { - return nil - } - - storedState := node.state & ns.saveFlags - for _, t := range node.timeouts { - storedState &= ^t.mask - } - enc := nodeInfoEnc{ - Enr: *node.node.Record(), - Version: ns.setup.Version, - State: storedState, - Fields: make([][]byte, len(ns.fields)), - } - log.Debug("Saved node state", "id", id, "state", Flags{mask: enc.State, setup: ns.setup}) - lastIndex := -1 - for i, f := range node.fields { - if f == nil { - continue - } - encode := ns.fields[i].encode - if encode == nil { - continue - } - blob, err := encode(f) - if err != nil { - return err - } - enc.Fields[i] = blob - lastIndex = i - } - if storedState == 0 && lastIndex == -1 { - if node.db { - node.db = false - ns.deleteNode(id) - } - node.dirty = false - return nil - } - enc.Fields = enc.Fields[:lastIndex+1] - data, err := rlp.EncodeToBytes(&enc) - if err != nil { - return err - } - if err := ns.db.Put(append(ns.dbNodeKey, id[:]...), data); err != nil { - return err - } - node.dirty, node.db = false, true - - if ns.saveNodeHook != nil { - ns.saveNodeHook(node) - } - return nil -} - -// deleteNode removes a node info from the database -func (ns *NodeStateMachine) deleteNode(id enode.ID) { - ns.db.Delete(append(ns.dbNodeKey, id[:]...)) -} - -// saveToDb saves the persistent flags and fields of all nodes that have been changed -func (ns *NodeStateMachine) saveToDb() { - for id, node := range ns.nodes { - if node.dirty { - err := ns.saveNode(id, node) - if err != nil { - log.Error("Failed to save node", "id", id, "error", err) - } - } - } -} - -// updateEnode updates the enode entry belonging to the given node if it already exists -func (ns *NodeStateMachine) updateEnode(n *enode.Node) (enode.ID, *nodeInfo) { - id := n.ID() - node := ns.nodes[id] - if node != nil && n.Seq() > node.node.Seq() { - node.node = n - node.dirty = true - } - return id, node -} - -// Persist saves the persistent state and fields of the given node immediately -func (ns *NodeStateMachine) Persist(n *enode.Node) error { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if id, node := ns.updateEnode(n); node != nil && node.dirty { - err := ns.saveNode(id, node) - if err != nil { - log.Error("Failed to save node", "id", id, "error", err) - } - return err - } - return nil -} - -// SetState updates the given node state flags and blocks until the operation is finished. -// If a flag with a timeout is set again, the operation removes or replaces the existing timeout. -func (ns *NodeStateMachine) SetState(n *enode.Node, setFlags, resetFlags Flags, timeout time.Duration) error { - ns.lock.Lock() - defer ns.lock.Unlock() - - if !ns.opStart() { - return ErrClosed - } - ns.setState(n, setFlags, resetFlags, timeout) - ns.opFinish() - return nil -} - -// SetStateSub updates the given node state flags without blocking (should be called -// from a subscription/operation callback). -func (ns *NodeStateMachine) SetStateSub(n *enode.Node, setFlags, resetFlags Flags, timeout time.Duration) { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.opCheck() - ns.setState(n, setFlags, resetFlags, timeout) -} - -func (ns *NodeStateMachine) setState(n *enode.Node, setFlags, resetFlags Flags, timeout time.Duration) { - ns.checkStarted() - set, reset := ns.stateMask(setFlags), ns.stateMask(resetFlags) - id, node := ns.updateEnode(n) - if node == nil { - if set == 0 { - return - } - node = ns.newNode(n) - ns.nodes[id] = node - } - oldState := node.state - newState := (node.state & (^reset)) | set - changed := oldState ^ newState - node.state = newState - - // Remove the timeout callbacks for all reset and set flags, - // even they are not existent(it's noop). - ns.removeTimeouts(node, set|reset) - - // Register the timeout callback if required - if timeout != 0 && set != 0 { - ns.addTimeout(n, set, timeout) - } - if newState == oldState { - return - } - if newState == 0 && node.fieldCount == 0 { - delete(ns.nodes, id) - if node.db { - ns.deleteNode(id) - } - } else { - if changed&ns.saveFlags != 0 { - node.dirty = true - } - } - callback := func() { - for _, sub := range ns.stateSubs { - if changed&sub.mask != 0 { - sub.callback(n, Flags{mask: oldState & sub.mask, setup: ns.setup}, Flags{mask: newState & sub.mask, setup: ns.setup}) - } - } - } - ns.opPending = append(ns.opPending, callback) -} - -// opCheck checks whether an operation is active -func (ns *NodeStateMachine) opCheck() { - if !ns.opFlag { - panic("Operation has not started") - } -} - -// opStart waits until other operations are finished and starts a new one -func (ns *NodeStateMachine) opStart() bool { - for ns.opFlag { - ns.opWait.Wait() - } - if ns.closed { - return false - } - ns.opFlag = true - return true -} - -// opFinish finishes the current operation by running all pending callbacks. -// Callbacks resulting from a state/field change performed in a previous callback are always -// put at the end of the pending list and therefore processed after all callbacks resulting -// from the previous state/field change. -func (ns *NodeStateMachine) opFinish() { - for len(ns.opPending) != 0 { - list := ns.opPending - ns.lock.Unlock() - for _, cb := range list { - cb() - } - ns.lock.Lock() - ns.opPending = ns.opPending[len(list):] - } - ns.opPending = nil - ns.opFlag = false - ns.opWait.Broadcast() -} - -// Operation calls the given function as an operation callback. This allows the caller -// to start an operation with multiple initial changes. The same rules apply as for -// subscription callbacks. -func (ns *NodeStateMachine) Operation(fn func()) error { - ns.lock.Lock() - started := ns.opStart() - ns.lock.Unlock() - if !started { - return ErrClosed - } - fn() - ns.lock.Lock() - ns.opFinish() - ns.lock.Unlock() - return nil -} - -// offlineCallbacks calls state update callbacks at startup or shutdown -func (ns *NodeStateMachine) offlineCallbacks(start bool) { - for _, cb := range ns.offlineCallbackList { - cb := cb - callback := func() { - for _, sub := range ns.stateSubs { - offState := offlineState & sub.mask - onState := cb.state & sub.mask - if offState == onState { - continue - } - if start { - sub.callback(cb.node.node, Flags{mask: offState, setup: ns.setup}, Flags{mask: onState, setup: ns.setup}) - } else { - sub.callback(cb.node.node, Flags{mask: onState, setup: ns.setup}, Flags{mask: offState, setup: ns.setup}) - } - } - for i, f := range cb.fields { - if f == nil || ns.fields[i].subs == nil { - continue - } - for _, fsub := range ns.fields[i].subs { - if start { - fsub(cb.node.node, Flags{mask: offlineState, setup: ns.setup}, nil, f) - } else { - fsub(cb.node.node, Flags{mask: offlineState, setup: ns.setup}, f, nil) - } - } - } - } - ns.opPending = append(ns.opPending, callback) - } - ns.offlineCallbackList = nil -} - -// AddTimeout adds a node state timeout associated to the given state flag(s). -// After the specified time interval, the relevant states will be reset. -func (ns *NodeStateMachine) AddTimeout(n *enode.Node, flags Flags, timeout time.Duration) error { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if ns.closed { - return ErrClosed - } - ns.addTimeout(n, ns.stateMask(flags), timeout) - return nil -} - -// addTimeout adds a node state timeout associated to the given state flag(s). -func (ns *NodeStateMachine) addTimeout(n *enode.Node, mask bitMask, timeout time.Duration) { - _, node := ns.updateEnode(n) - if node == nil { - return - } - mask &= node.state - if mask == 0 { - return - } - ns.removeTimeouts(node, mask) - t := &nodeStateTimeout{mask: mask} - t.timer = ns.clock.AfterFunc(timeout, func() { - ns.lock.Lock() - defer ns.lock.Unlock() - - if !ns.opStart() { - return - } - ns.setState(n, Flags{}, Flags{mask: t.mask, setup: ns.setup}, 0) - ns.opFinish() - }) - node.timeouts = append(node.timeouts, t) - if mask&ns.saveFlags != 0 { - node.dirty = true - } -} - -// removeTimeout removes node state timeouts associated to the given state flag(s). -// If a timeout was associated to multiple flags which are not all included in the -// specified remove mask then only the included flags are de-associated and the timer -// stays active. -func (ns *NodeStateMachine) removeTimeouts(node *nodeInfo, mask bitMask) { - for i := 0; i < len(node.timeouts); i++ { - t := node.timeouts[i] - match := t.mask & mask - if match == 0 { - continue - } - t.mask -= match - if t.mask != 0 { - continue - } - t.timer.Stop() - node.timeouts[i] = node.timeouts[len(node.timeouts)-1] - node.timeouts = node.timeouts[:len(node.timeouts)-1] - i-- - if match&ns.saveFlags != 0 { - node.dirty = true - } - } -} - -// GetField retrieves the given field of the given node. Note that when used in a -// subscription callback the result can be out of sync with the state change represented -// by the callback parameters so extra safety checks might be necessary. -func (ns *NodeStateMachine) GetField(n *enode.Node, field Field) interface{} { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if ns.closed { - return nil - } - if _, node := ns.updateEnode(n); node != nil { - return node.fields[ns.fieldIndex(field)] - } - return nil -} - -// GetState retrieves the current state of the given node. Note that when used in a -// subscription callback the result can be out of sync with the state change represented -// by the callback parameters so extra safety checks might be necessary. -func (ns *NodeStateMachine) GetState(n *enode.Node) Flags { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if ns.closed { - return Flags{} - } - if _, node := ns.updateEnode(n); node != nil { - return Flags{mask: node.state, setup: ns.setup} - } - return Flags{} -} - -// SetField sets the given field of the given node and blocks until the operation is finished -func (ns *NodeStateMachine) SetField(n *enode.Node, field Field, value interface{}) error { - ns.lock.Lock() - defer ns.lock.Unlock() - - if !ns.opStart() { - return ErrClosed - } - err := ns.setField(n, field, value) - ns.opFinish() - return err -} - -// SetFieldSub sets the given field of the given node without blocking (should be called -// from a subscription/operation callback). -func (ns *NodeStateMachine) SetFieldSub(n *enode.Node, field Field, value interface{}) error { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.opCheck() - return ns.setField(n, field, value) -} - -func (ns *NodeStateMachine) setField(n *enode.Node, field Field, value interface{}) error { - ns.checkStarted() - id, node := ns.updateEnode(n) - if node == nil { - if value == nil { - return nil - } - node = ns.newNode(n) - ns.nodes[id] = node - } - fieldIndex := ns.fieldIndex(field) - f := ns.fields[fieldIndex] - if value != nil && reflect.TypeOf(value) != f.ftype { - log.Error("Invalid field type", "type", reflect.TypeOf(value), "required", f.ftype) - return ErrInvalidField - } - oldValue := node.fields[fieldIndex] - if value == oldValue { - return nil - } - if oldValue != nil { - node.fieldCount-- - } - if value != nil { - node.fieldCount++ - } - node.fields[fieldIndex] = value - if node.state == 0 && node.fieldCount == 0 { - delete(ns.nodes, id) - if node.db { - ns.deleteNode(id) - } - } else { - if f.encode != nil { - node.dirty = true - } - } - state := node.state - callback := func() { - for _, cb := range f.subs { - cb(n, Flags{mask: state, setup: ns.setup}, oldValue, value) - } - } - ns.opPending = append(ns.opPending, callback) - return nil -} - -// ForEach calls the callback for each node having all of the required and none of the -// disabled flags set. -// Note that this callback is not an operation callback but ForEach can be called from an -// Operation callback or Operation can also be called from a ForEach callback if necessary. -func (ns *NodeStateMachine) ForEach(requireFlags, disableFlags Flags, cb func(n *enode.Node, state Flags)) { - ns.lock.Lock() - ns.checkStarted() - type callback struct { - node *enode.Node - state bitMask - } - require, disable := ns.stateMask(requireFlags), ns.stateMask(disableFlags) - var callbacks []callback - for _, node := range ns.nodes { - if node.state&require == require && node.state&disable == 0 { - callbacks = append(callbacks, callback{node.node, node.state & (require | disable)}) - } - } - ns.lock.Unlock() - for _, c := range callbacks { - cb(c.node, Flags{mask: c.state, setup: ns.setup}) - } -} - -// GetNode returns the enode currently associated with the given ID -func (ns *NodeStateMachine) GetNode(id enode.ID) *enode.Node { - ns.lock.Lock() - defer ns.lock.Unlock() - - ns.checkStarted() - if node := ns.nodes[id]; node != nil { - return node.node - } - return nil -} - -// AddLogMetrics adds logging and/or metrics for nodes entering, exiting and currently -// being in a given set specified by required and disabled state flags -func (ns *NodeStateMachine) AddLogMetrics(requireFlags, disableFlags Flags, name string, inMeter, outMeter metrics.Meter, gauge metrics.Gauge) { - var count int64 - ns.SubscribeState(requireFlags.Or(disableFlags), func(n *enode.Node, oldState, newState Flags) { - oldMatch := oldState.HasAll(requireFlags) && oldState.HasNone(disableFlags) - newMatch := newState.HasAll(requireFlags) && newState.HasNone(disableFlags) - if newMatch == oldMatch { - return - } - - if newMatch { - count++ - if name != "" { - log.Debug("Node entered", "set", name, "id", n.ID(), "count", count) - } - if inMeter != nil { - inMeter.Mark(1) - } - } else { - count-- - if name != "" { - log.Debug("Node left", "set", name, "id", n.ID(), "count", count) - } - if outMeter != nil { - outMeter.Mark(1) - } - } - if gauge != nil { - gauge.Update(count) - } - }) -} diff --git a/p2p/nodestate/nodestate_test.go b/p2p/nodestate/nodestate_test.go deleted file mode 100644 index d06ad755e2..0000000000 --- a/p2p/nodestate/nodestate_test.go +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package nodestate - -import ( - "errors" - "fmt" - "reflect" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common/mclock" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/rlp" -) - -func testSetup(flagPersist []bool, fieldType []reflect.Type) (*Setup, []Flags, []Field) { - setup := &Setup{} - flags := make([]Flags, len(flagPersist)) - for i, persist := range flagPersist { - if persist { - flags[i] = setup.NewPersistentFlag(fmt.Sprintf("flag-%d", i)) - } else { - flags[i] = setup.NewFlag(fmt.Sprintf("flag-%d", i)) - } - } - fields := make([]Field, len(fieldType)) - for i, ftype := range fieldType { - switch ftype { - case reflect.TypeOf(uint64(0)): - fields[i] = setup.NewPersistentField(fmt.Sprintf("field-%d", i), ftype, uint64FieldEnc, uint64FieldDec) - case reflect.TypeOf(""): - fields[i] = setup.NewPersistentField(fmt.Sprintf("field-%d", i), ftype, stringFieldEnc, stringFieldDec) - default: - fields[i] = setup.NewField(fmt.Sprintf("field-%d", i), ftype) - } - } - return setup, flags, fields -} - -func testNode(b byte) *enode.Node { - r := &enr.Record{} - r.SetSig(dummyIdentity{b}, []byte{42}) - n, _ := enode.New(dummyIdentity{b}, r) - return n -} - -func TestCallback(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, _ := testSetup([]bool{false, false, false}, nil) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - set0 := make(chan struct{}, 1) - set1 := make(chan struct{}, 1) - set2 := make(chan struct{}, 1) - ns.SubscribeState(flags[0], func(n *enode.Node, oldState, newState Flags) { set0 <- struct{}{} }) - ns.SubscribeState(flags[1], func(n *enode.Node, oldState, newState Flags) { set1 <- struct{}{} }) - ns.SubscribeState(flags[2], func(n *enode.Node, oldState, newState Flags) { set2 <- struct{}{} }) - - ns.Start() - - ns.SetState(testNode(1), flags[0], Flags{}, 0) - ns.SetState(testNode(1), flags[1], Flags{}, time.Second) - ns.SetState(testNode(1), flags[2], Flags{}, 2*time.Second) - - for i := 0; i < 3; i++ { - select { - case <-set0: - case <-set1: - case <-set2: - case <-time.After(time.Second): - t.Fatalf("failed to invoke callback") - } - } -} - -func TestPersistentFlags(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, _ := testSetup([]bool{true, true, true, false}, nil) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - saveNode := make(chan *nodeInfo, 5) - ns.saveNodeHook = func(node *nodeInfo) { - saveNode <- node - } - - ns.Start() - - ns.SetState(testNode(1), flags[0], Flags{}, time.Second) // state with timeout should not be saved - ns.SetState(testNode(2), flags[1], Flags{}, 0) - ns.SetState(testNode(3), flags[2], Flags{}, 0) - ns.SetState(testNode(4), flags[3], Flags{}, 0) - ns.SetState(testNode(5), flags[0], Flags{}, 0) - ns.Persist(testNode(5)) - select { - case <-saveNode: - case <-time.After(time.Second): - t.Fatalf("Timeout") - } - ns.Stop() - - for i := 0; i < 2; i++ { - select { - case <-saveNode: - case <-time.After(time.Second): - t.Fatalf("Timeout") - } - } - select { - case <-saveNode: - t.Fatalf("Unexpected saveNode") - case <-time.After(time.Millisecond * 100): - } -} - -func TestSetField(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf("")}) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - saveNode := make(chan *nodeInfo, 1) - ns.saveNodeHook = func(node *nodeInfo) { - saveNode <- node - } - - ns.Start() - - // Set field before setting state - ns.SetField(testNode(1), fields[0], "hello world") - field := ns.GetField(testNode(1), fields[0]) - if field == nil { - t.Fatalf("Field should be set before setting states") - } - ns.SetField(testNode(1), fields[0], nil) - field = ns.GetField(testNode(1), fields[0]) - if field != nil { - t.Fatalf("Field should be unset") - } - // Set field after setting state - ns.SetState(testNode(1), flags[0], Flags{}, 0) - ns.SetField(testNode(1), fields[0], "hello world") - field = ns.GetField(testNode(1), fields[0]) - if field == nil { - t.Fatalf("Field should be set after setting states") - } - if err := ns.SetField(testNode(1), fields[0], 123); err == nil { - t.Fatalf("Invalid field should be rejected") - } - // Dirty node should be written back - ns.Stop() - select { - case <-saveNode: - case <-time.After(time.Second): - t.Fatalf("Timeout") - } -} - -func TestSetState(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, _ := testSetup([]bool{false, false, false}, nil) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - type change struct{ old, new Flags } - set := make(chan change, 1) - ns.SubscribeState(flags[0].Or(flags[1]), func(n *enode.Node, oldState, newState Flags) { - set <- change{ - old: oldState, - new: newState, - } - }) - - ns.Start() - - check := func(expectOld, expectNew Flags, expectChange bool) { - if expectChange { - select { - case c := <-set: - if !c.old.Equals(expectOld) { - t.Fatalf("Old state mismatch") - } - if !c.new.Equals(expectNew) { - t.Fatalf("New state mismatch") - } - case <-time.After(time.Second): - } - return - } - select { - case <-set: - t.Fatalf("Unexpected change") - case <-time.After(time.Millisecond * 100): - return - } - } - ns.SetState(testNode(1), flags[0], Flags{}, 0) - check(Flags{}, flags[0], true) - - ns.SetState(testNode(1), flags[1], Flags{}, 0) - check(flags[0], flags[0].Or(flags[1]), true) - - ns.SetState(testNode(1), flags[2], Flags{}, 0) - check(Flags{}, Flags{}, false) - - ns.SetState(testNode(1), Flags{}, flags[0], 0) - check(flags[0].Or(flags[1]), flags[1], true) - - ns.SetState(testNode(1), Flags{}, flags[1], 0) - check(flags[1], Flags{}, true) - - ns.SetState(testNode(1), Flags{}, flags[2], 0) - check(Flags{}, Flags{}, false) - - ns.SetState(testNode(1), flags[0].Or(flags[1]), Flags{}, time.Second) - check(Flags{}, flags[0].Or(flags[1]), true) - clock.Run(time.Second) - check(flags[0].Or(flags[1]), Flags{}, true) -} - -func uint64FieldEnc(field interface{}) ([]byte, error) { - if u, ok := field.(uint64); ok { - enc, err := rlp.EncodeToBytes(&u) - return enc, err - } - return nil, errors.New("invalid field type") -} - -func uint64FieldDec(enc []byte) (interface{}, error) { - var u uint64 - err := rlp.DecodeBytes(enc, &u) - return u, err -} - -func stringFieldEnc(field interface{}) ([]byte, error) { - if s, ok := field.(string); ok { - return []byte(s), nil - } - return nil, errors.New("invalid field type") -} - -func stringFieldDec(enc []byte) (interface{}, error) { - return string(enc), nil -} - -func TestPersistentFields(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf(uint64(0)), reflect.TypeOf("")}) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - ns.Start() - ns.SetState(testNode(1), flags[0], Flags{}, 0) - ns.SetField(testNode(1), fields[0], uint64(100)) - ns.SetField(testNode(1), fields[1], "hello world") - ns.Stop() - - ns2 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - ns2.Start() - field0 := ns2.GetField(testNode(1), fields[0]) - if !reflect.DeepEqual(field0, uint64(100)) { - t.Fatalf("Field changed") - } - field1 := ns2.GetField(testNode(1), fields[1]) - if !reflect.DeepEqual(field1, "hello world") { - t.Fatalf("Field changed") - } - - s.Version++ - ns3 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - ns3.Start() - if ns3.GetField(testNode(1), fields[0]) != nil { - t.Fatalf("Old field version should have been discarded") - } -} - -func TestFieldSub(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf(uint64(0))}) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - var ( - lastState Flags - lastOldValue, lastNewValue interface{} - ) - ns.SubscribeField(fields[0], func(n *enode.Node, state Flags, oldValue, newValue interface{}) { - lastState, lastOldValue, lastNewValue = state, oldValue, newValue - }) - check := func(state Flags, oldValue, newValue interface{}) { - if !lastState.Equals(state) || lastOldValue != oldValue || lastNewValue != newValue { - t.Fatalf("Incorrect field sub callback (expected [%v %v %v], got [%v %v %v])", state, oldValue, newValue, lastState, lastOldValue, lastNewValue) - } - } - ns.Start() - ns.SetState(testNode(1), flags[0], Flags{}, 0) - ns.SetField(testNode(1), fields[0], uint64(100)) - check(flags[0], nil, uint64(100)) - ns.Stop() - check(s.OfflineFlag(), uint64(100), nil) - - ns2 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - ns2.SubscribeField(fields[0], func(n *enode.Node, state Flags, oldValue, newValue interface{}) { - lastState, lastOldValue, lastNewValue = state, oldValue, newValue - }) - ns2.Start() - check(s.OfflineFlag(), nil, uint64(100)) - ns2.SetState(testNode(1), Flags{}, flags[0], 0) - ns2.SetField(testNode(1), fields[0], nil) - check(Flags{}, uint64(100), nil) - ns2.Stop() -} - -func TestDuplicatedFlags(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, _ := testSetup([]bool{true}, nil) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - type change struct{ old, new Flags } - set := make(chan change, 1) - ns.SubscribeState(flags[0], func(n *enode.Node, oldState, newState Flags) { - set <- change{oldState, newState} - }) - - ns.Start() - defer ns.Stop() - - check := func(expectOld, expectNew Flags, expectChange bool) { - if expectChange { - select { - case c := <-set: - if !c.old.Equals(expectOld) { - t.Fatalf("Old state mismatch") - } - if !c.new.Equals(expectNew) { - t.Fatalf("New state mismatch") - } - case <-time.After(time.Second): - } - return - } - select { - case <-set: - t.Fatalf("Unexpected change") - case <-time.After(time.Millisecond * 100): - return - } - } - ns.SetState(testNode(1), flags[0], Flags{}, time.Second) - check(Flags{}, flags[0], true) - ns.SetState(testNode(1), flags[0], Flags{}, 2*time.Second) // extend the timeout to 2s - check(Flags{}, flags[0], false) - - clock.Run(2 * time.Second) - check(flags[0], Flags{}, true) -} - -func TestCallbackOrder(t *testing.T) { - mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{} - - s, flags, _ := testSetup([]bool{false, false, false, false}, nil) - ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s) - - ns.SubscribeState(flags[0], func(n *enode.Node, oldState, newState Flags) { - if newState.Equals(flags[0]) { - ns.SetStateSub(n, flags[1], Flags{}, 0) - ns.SetStateSub(n, flags[2], Flags{}, 0) - } - }) - ns.SubscribeState(flags[1], func(n *enode.Node, oldState, newState Flags) { - if newState.Equals(flags[1]) { - ns.SetStateSub(n, flags[3], Flags{}, 0) - } - }) - lastState := Flags{} - ns.SubscribeState(MergeFlags(flags[1], flags[2], flags[3]), func(n *enode.Node, oldState, newState Flags) { - if !oldState.Equals(lastState) { - t.Fatalf("Wrong callback order") - } - lastState = newState - }) - - ns.Start() - defer ns.Stop() - - ns.SetState(testNode(1), flags[0], Flags{}, 0) -} diff --git a/p2p/peer.go b/p2p/peer.go index ed80b226bf..61b62fcf3c 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net" + "slices" "sync" "time" @@ -31,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) var ( diff --git a/p2p/simulations/pipes/pipes.go b/p2p/pipes/pipe.go similarity index 85% rename from p2p/simulations/pipes/pipes.go rename to p2p/pipes/pipe.go index ec277c0d14..cf1f3e2a80 100644 --- a/p2p/simulations/pipes/pipes.go +++ b/p2p/pipes/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 The go-ethereum Authors +// Copyright 2024 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -16,17 +16,9 @@ package pipes -import ( - "net" -) +import "net" -// NetPipe wraps net.Pipe in a signature returning an error -func NetPipe() (net.Conn, net.Conn, error) { - p1, p2 := net.Pipe() - return p1, p2, nil -} - -// TCPPipe creates an in process full duplex pipe based on a localhost TCP socket +// TCPPipe creates an in process full duplex pipe based on a localhost TCP socket. func TCPPipe() (net.Conn, net.Conn, error) { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { diff --git a/p2p/rlpx/rlpx.go b/p2p/rlpx/rlpx.go index 7427c01b9a..dd14822dee 100644 --- a/p2p/rlpx/rlpx.go +++ b/p2p/rlpx/rlpx.go @@ -22,7 +22,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/ecdsa" - "crypto/elliptic" "crypto/hmac" "crypto/rand" "encoding/binary" @@ -605,6 +604,11 @@ func (h *handshakeState) readMsg(msg interface{}, prv *ecdsa.PrivateKey, r io.Re } size := binary.BigEndian.Uint16(prefix) + // baseProtocolMaxMsgSize = 2 * 1024 + if size > 2048 { + return nil, errors.New("message too big") + } + // Read the handshake packet. packet, err := h.rbuf.read(r, int(size)) if err != nil { @@ -664,7 +668,10 @@ func exportPubkey(pub *ecies.PublicKey) []byte { if pub == nil { panic("nil pubkey") } - return elliptic.Marshal(pub.Curve, pub.X, pub.Y)[1:] //nolint:all //TODO + if curve, ok := pub.Curve.(crypto.EllipticCurve); ok { + return curve.Marshal(pub.X, pub.Y)[1:] + } + return []byte{} } func xor(one, other []byte) (xor []byte) { diff --git a/p2p/rlpx/rlpx_test.go b/p2p/rlpx/rlpx_test.go index 136cb1b5bf..27d51546e7 100644 --- a/p2p/rlpx/rlpx_test.go +++ b/p2p/rlpx/rlpx_test.go @@ -31,7 +31,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/ecies" - "github.com/ethereum/go-ethereum/p2p/simulations/pipes" + "github.com/ethereum/go-ethereum/p2p/pipes" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/assert" ) diff --git a/p2p/server.go b/p2p/server.go index a334166737..12221e84ed 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -19,12 +19,15 @@ package p2p import ( "bytes" + "cmp" "crypto/ecdsa" "encoding/hex" "errors" "fmt" "net" + "net/netip" "regexp" + "slices" "sync" "sync/atomic" "time" @@ -42,7 +45,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) const ( @@ -208,8 +210,8 @@ type Server struct { nodedb *enode.DB localnode *enode.LocalNode - ntab *discover.UDPv4 - DiscV5 *discover.UDPv5 + discv4 *discover.UDPv4 + discv5 *discover.UDPv5 discmix *enode.FairMix dialsched *dialScheduler @@ -434,6 +436,16 @@ func (srv *Server) Self() *enode.Node { return ln.Node() } +// DiscoveryV4 returns the discovery v4 instance, if configured. +func (srv *Server) DiscoveryV4() *discover.UDPv4 { + return srv.discv4 +} + +// DiscoveryV5 returns the discovery v5 instance, if configured. +func (srv *Server) DiscoveryV5() *discover.UDPv5 { + return srv.discv5 +} + // Stop terminates the server and all active peer connections. // It blocks until all active connections have been closed. func (srv *Server) Stop() { @@ -470,11 +482,11 @@ type sharedUDPConn struct { unhandled chan discover.ReadPacket } -// ReadFromUDP implements discover.UDPConn -func (s *sharedUDPConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { +// ReadFromUDPAddrPort implements discover.UDPConn +func (s *sharedUDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) { packet, ok := <-s.unhandled if !ok { - return 0, nil, errors.New("connection was closed") + return 0, netip.AddrPort{}, errors.New("connection was closed") } l := len(packet.Data) if l > len(b) { @@ -617,13 +629,13 @@ func (srv *Server) setupDiscovery() error { ) // If both versions of discovery are running, setup a shared // connection, so v5 can read unhandled messages from v4. - if srv.DiscoveryV4 && srv.DiscoveryV5 { + if srv.Config.DiscoveryV4 && srv.Config.DiscoveryV5 { unhandled = make(chan discover.ReadPacket, 100) sconn = &sharedUDPConn{conn, unhandled} } // Start discovery services. - if srv.DiscoveryV4 { + if srv.Config.DiscoveryV4 { cfg := discover.Config{ PrivateKey: srv.PrivateKey, NetRestrict: srv.NetRestrict, @@ -636,10 +648,10 @@ func (srv *Server) setupDiscovery() error { if err != nil { return err } - srv.ntab = ntab + srv.discv4 = ntab srv.discmix.AddSource(ntab.RandomNodes()) } - if srv.DiscoveryV5 { + if srv.Config.DiscoveryV5 { cfg := discover.Config{ PrivateKey: srv.PrivateKey, NetRestrict: srv.NetRestrict, @@ -647,7 +659,7 @@ func (srv *Server) setupDiscovery() error { Log: srv.log, FilterFunction: f, } - srv.DiscV5, err = discover.ListenV5(sconn, srv.localnode, cfg) + srv.discv5, err = discover.ListenV5(sconn, srv.localnode, cfg) if err != nil { return err } @@ -674,8 +686,8 @@ func (srv *Server) setupDialScheduler() { dialer: srv.Dialer, clock: srv.clock, } - if srv.ntab != nil { - config.resolver = srv.ntab + if srv.discv4 != nil { + config.resolver = srv.discv4 } if config.dialer == nil { config.dialer = tcpDialer{&net.Dialer{Timeout: defaultDialTimeout}} @@ -884,11 +896,11 @@ running: srv.log.Trace("P2P networking is spinning down") // Terminate discovery. If there is a running lookup it will terminate soon. - if srv.ntab != nil { - srv.ntab.Close() + if srv.discv4 != nil { + srv.discv4.Close() } - if srv.DiscV5 != nil { - srv.DiscV5.Close() + if srv.discv5 != nil { + srv.discv5.Close() } // Disconnect all peers. for _, p := range peers { @@ -992,14 +1004,14 @@ func (srv *Server) listenLoop() { break } - remoteIP := netutil.AddrIP(fd.RemoteAddr()) + remoteIP := netutil.AddrAddr(fd.RemoteAddr()) if err := srv.checkInboundConn(remoteIP); err != nil { srv.log.Debug("Rejected inbound connection", "addr", fd.RemoteAddr(), "err", err) fd.Close() slots <- struct{}{} continue } - if remoteIP != nil { + if remoteIP.IsValid() { fd = newMeteredConn(fd) serveMeter.Mark(1) srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr()) @@ -1011,19 +1023,20 @@ func (srv *Server) listenLoop() { } } -func (srv *Server) checkInboundConn(remoteIP net.IP) error { - if remoteIP == nil { +func (srv *Server) checkInboundConn(remoteIP netip.Addr) error { + if !remoteIP.IsValid() { + // This case happens for internal test connections without remote address. return nil } // Reject connections that do not match NetRestrict. - if srv.NetRestrict != nil && !srv.NetRestrict.Contains(remoteIP) { + if srv.NetRestrict != nil && !srv.NetRestrict.ContainsAddr(remoteIP) { return errors.New("not in netrestrict list") } // Reject Internet peers that try too often. now := srv.clock.Now() srv.inboundHistory.expire(now, nil) - if !netutil.IsLAN(remoteIP) && srv.inboundHistory.contains(remoteIP.String()) { + if !netutil.AddrIsLAN(remoteIP) && srv.inboundHistory.contains(remoteIP.String()) { return errors.New("too many attempts") } srv.inboundHistory.add(remoteIP.String(), now.Add(inboundThrottleTime)) @@ -1048,7 +1061,7 @@ func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) c.transport = srv.newTransport(fd, dialDest.Pubkey()) } - err := srv.setupConn(c, flags, dialDest) + err := srv.setupConn(c, dialDest) if err != nil { if !c.is(inboundConn) { markDialError(err) @@ -1060,7 +1073,7 @@ func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) return err } -func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) error { +func (srv *Server) setupConn(c *conn, dialDest *enode.Node) error { // Prevent leftover pending conns from entering the handshake. srv.lock.Lock() running := srv.running @@ -1207,7 +1220,7 @@ func (srv *Server) NodeInfo() *NodeInfo { Name: srv.Name, Enode: node.URLv4(), ID: node.ID().String(), - IP: node.IP().String(), + IP: node.IPAddr().String(), ListenAddr: srv.ListenAddr, Protocols: make(map[string]interface{}), } @@ -1238,13 +1251,10 @@ func (srv *Server) PeersInfo() []*PeerInfo { } } // Sort the result array alphabetically by node identifier - for i := 0; i < len(infos); i++ { - for j := i + 1; j < len(infos); j++ { - if infos[i].ID > infos[j].ID { - infos[i], infos[j] = infos[j], infos[i] - } - } - } + slices.SortFunc(infos, func(a, b *PeerInfo) int { + return cmp.Compare(a.ID, b.ID) + }) + return infos } diff --git a/p2p/server_nat.go b/p2p/server_nat.go index 299d275490..933993bc1f 100644 --- a/p2p/server_nat.go +++ b/p2p/server_nat.go @@ -125,7 +125,7 @@ func (srv *Server) portMappingLoop() { if err != nil { log.Debug("Couldn't get external IP", "err", err, "interface", srv.NAT) } else if !ip.Equal(lastExtIP) { - log.Debug("External IP changed", "ip", extip, "interface", srv.NAT) + log.Debug("External IP changed", "ip", ip, "interface", srv.NAT) } else { continue } diff --git a/p2p/server_nat_test.go b/p2p/server_nat_test.go index de935fcfc5..7e19387210 100644 --- a/p2p/server_nat_test.go +++ b/p2p/server_nat_test.go @@ -18,6 +18,7 @@ package p2p import ( "net" + "net/netip" "sync/atomic" "testing" "time" @@ -35,6 +36,7 @@ func TestServerPortMapping(t *testing.T) { PrivateKey: newkey(), NoDial: true, ListenAddr: ":0", + DiscAddr: ":0", NAT: mockNAT, Logger: testlog.Logger(t, log.LvlTrace), clock: clock, @@ -64,8 +66,8 @@ func TestServerPortMapping(t *testing.T) { t.Error("wrong request count:", reqCount) } enr := srv.LocalNode().Node() - if enr.IP().String() != "192.0.2.0" { - t.Error("wrong IP in ENR:", enr.IP()) + if enr.IPAddr() != netip.MustParseAddr("192.0.2.0") { + t.Error("wrong IP in ENR:", enr.IPAddr()) } if enr.TCP() != 30000 { t.Error("wrong TCP port in ENR:", enr.TCP()) diff --git a/p2p/simulations/README.md b/p2p/simulations/README.md deleted file mode 100644 index 023f73a098..0000000000 --- a/p2p/simulations/README.md +++ /dev/null @@ -1,169 +0,0 @@ -# devp2p Simulations - -The `p2p/simulations` package implements a simulation framework that supports -creating a collection of devp2p nodes, connecting them to form a -simulation network, performing simulation actions in that network and then -extracting useful information. - -## Nodes - -Each node in a simulation network runs multiple services by wrapping a collection -of objects which implement the `node.Service` interface meaning they: - -* can be started and stopped -* run p2p protocols -* expose RPC APIs - -This means that any object which implements the `node.Service` interface can be -used to run a node in the simulation. - -## Services - -Before running a simulation, a set of service initializers must be registered -which can then be used to run nodes in the network. - -A service initializer is a function with the following signature: - -```go -func(ctx *adapters.ServiceContext) (node.Service, error) -``` - -These initializers should be registered by calling the `adapters.RegisterServices` -function in an `init()` hook: - -```go -func init() { - adapters.RegisterServices(adapters.Services{ - "service1": initService1, - "service2": initService2, - }) -} -``` - -## Node Adapters - -The simulation framework includes multiple "node adapters" which are -responsible for creating an environment in which a node runs. - -### SimAdapter - -The `SimAdapter` runs nodes in-memory, connecting them using an in-memory, -synchronous `net.Pipe` and connecting to their RPC server using an in-memory -`rpc.Client`. - -### ExecAdapter - -The `ExecAdapter` runs nodes as child processes of the running simulation. - -It does this by executing the binary which is running the simulation but -setting `argv[0]` (i.e. the program name) to `p2p-node` which is then -detected by an init hook in the child process which runs the `node.Service` -using the devp2p node stack rather than executing `main()`. - -The nodes listen for devp2p connections and WebSocket RPC clients on random -localhost ports. - -## Network - -A simulation network is created with an ID and default service. The default -service is used if a node is created without an explicit service. The -network has exposed methods for creating, starting, stopping, connecting -and disconnecting nodes. It also emits events when certain actions occur. - -### Events - -A simulation network emits the following events: - -* node event - when nodes are created / started / stopped -* connection event - when nodes are connected / disconnected -* message event - when a protocol message is sent between two nodes - -The events have a "control" flag which when set indicates that the event is the -outcome of a controlled simulation action (e.g. creating a node or explicitly -connecting two nodes). - -This is in contrast to a non-control event, otherwise called a "live" event, -which is the outcome of something happening in the network as a result of a -control event (e.g. a node actually started up or a connection was actually -established between two nodes). - -Live events are detected by the simulation network by subscribing to node peer -events via RPC when the nodes start up. - -## Testing Framework - -The `Simulation` type can be used in tests to perform actions in a simulation -network and then wait for expectations to be met. - -With a running simulation network, the `Simulation.Run` method can be called -with a `Step` which has the following fields: - -* `Action` - a function that performs some action in the network - -* `Expect` - an expectation function which returns whether or not a - given node meets the expectation - -* `Trigger` - a channel that receives node IDs which then trigger a check - of the expectation function to be performed against that node - -As a concrete example, consider a simulated network of Ethereum nodes. An -`Action` could be the sending of a transaction, `Expect` it being included in -a block, and `Trigger` a check for every block that is mined. - -On return, the `Simulation.Run` method returns a `StepResult` which can be used -to determine if all nodes met the expectation, how long it took them to meet -the expectation and what network events were emitted during the step run. - -## HTTP API - -The simulation framework includes a HTTP API that can be used to control the -simulation. - -The API is initialised with a particular node adapter and has the following -endpoints: - -``` -GET / Get network information -POST /start Start all nodes in the network -POST /stop Stop all nodes in the network -GET /events Stream network events -GET /snapshot Take a network snapshot -POST /snapshot Load a network snapshot -POST /nodes Create a node -GET /nodes Get all nodes in the network -GET /nodes/:nodeid Get node information -POST /nodes/:nodeid/start Start a node -POST /nodes/:nodeid/stop Stop a node -POST /nodes/:nodeid/conn/:peerid Connect two nodes -DELETE /nodes/:nodeid/conn/:peerid Disconnect two nodes -GET /nodes/:nodeid/rpc Make RPC requests to a node via WebSocket -``` - -For convenience, `nodeid` in the URL can be the name of a node rather than its -ID. - -## Command line client - -`p2psim` is a command line client for the HTTP API, located in -`cmd/p2psim`. - -It provides the following commands: - -``` -p2psim show -p2psim events [--current] [--filter=FILTER] -p2psim snapshot -p2psim load -p2psim node create [--name=NAME] [--services=SERVICES] [--key=KEY] -p2psim node list -p2psim node show -p2psim node start -p2psim node stop -p2psim node connect -p2psim node disconnect -p2psim node rpc [] [--subscribe] -``` - -## Example - -See [p2p/simulations/examples/README.md](examples/README.md). diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go deleted file mode 100644 index 63cc4936c1..0000000000 --- a/p2p/simulations/adapters/exec.go +++ /dev/null @@ -1,564 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package adapters - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "net/http" - "os" - "os/exec" - "os/signal" - "path/filepath" - "strings" - "sync" - "syscall" - "time" - - "github.com/ethereum/go-ethereum/internal/reexec" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/rpc" - "github.com/gorilla/websocket" - "golang.org/x/exp/slog" -) - -func init() { - // Register a reexec function to start a simulation node when the current binary is - // executed as "p2p-node" (rather than whatever the main() function would normally do). - reexec.Register("p2p-node", execP2PNode) -} - -// ExecAdapter is a NodeAdapter which runs simulation nodes by executing the current binary -// as a child process. -type ExecAdapter struct { - // BaseDir is the directory under which the data directories for each - // simulation node are created. - BaseDir string - - nodes map[enode.ID]*ExecNode -} - -// NewExecAdapter returns an ExecAdapter which stores node data in -// subdirectories of the given base directory -func NewExecAdapter(baseDir string) *ExecAdapter { - return &ExecAdapter{ - BaseDir: baseDir, - nodes: make(map[enode.ID]*ExecNode), - } -} - -// Name returns the name of the adapter for logging purposes -func (e *ExecAdapter) Name() string { - return "exec-adapter" -} - -// NewNode returns a new ExecNode using the given config -func (e *ExecAdapter) NewNode(config *NodeConfig) (Node, error) { - if len(config.Lifecycles) == 0 { - return nil, errors.New("node must have at least one service lifecycle") - } - for _, service := range config.Lifecycles { - if _, exists := lifecycleConstructorFuncs[service]; !exists { - return nil, fmt.Errorf("unknown node service %q", service) - } - } - - // create the node directory using the first 12 characters of the ID - // as Unix socket paths cannot be longer than 256 characters - dir := filepath.Join(e.BaseDir, config.ID.String()[:12]) - if err := os.Mkdir(dir, 0755); err != nil { - return nil, fmt.Errorf("error creating node directory: %s", err) - } - - err := config.initDummyEnode() - if err != nil { - return nil, err - } - - // generate the config - conf := &execNodeConfig{ - Stack: node.DefaultConfig, - Node: config, - } - if config.DataDir != "" { - conf.Stack.DataDir = config.DataDir - } else { - conf.Stack.DataDir = filepath.Join(dir, "data") - } - - // these parameters are crucial for execadapter node to run correctly - conf.Stack.WSHost = "127.0.0.1" - conf.Stack.WSPort = 0 - conf.Stack.WSOrigins = []string{"*"} - conf.Stack.WSExposeAll = true - conf.Stack.P2P.EnableMsgEvents = config.EnableMsgEvents - conf.Stack.P2P.NoDiscovery = true - conf.Stack.P2P.NAT = nil - - // Listen on a localhost port, which we set when we - // initialise NodeConfig (usually a random port) - conf.Stack.P2P.ListenAddr = fmt.Sprintf(":%d", config.Port) - - node := &ExecNode{ - ID: config.ID, - Dir: dir, - Config: conf, - adapter: e, - } - node.newCmd = node.execCommand - e.nodes[node.ID] = node - return node, nil -} - -// ExecNode starts a simulation node by exec'ing the current binary and -// running the configured services -type ExecNode struct { - ID enode.ID - Dir string - Config *execNodeConfig - Cmd *exec.Cmd - Info *p2p.NodeInfo - - adapter *ExecAdapter - client *rpc.Client - wsAddr string - newCmd func() *exec.Cmd -} - -// Addr returns the node's enode URL -func (n *ExecNode) Addr() []byte { - if n.Info == nil { - return nil - } - return []byte(n.Info.Enode) -} - -// Client returns an rpc.Client which can be used to communicate with the -// underlying services (it is set once the node has started) -func (n *ExecNode) Client() (*rpc.Client, error) { - return n.client, nil -} - -// Start exec's the node passing the ID and service as command line arguments -// and the node config encoded as JSON in an environment variable. -func (n *ExecNode) Start(snapshots map[string][]byte) (err error) { - if n.Cmd != nil { - return errors.New("already started") - } - defer func() { - if err != nil { - n.Stop() - } - }() - - // encode a copy of the config containing the snapshot - confCopy := *n.Config - confCopy.Snapshots = snapshots - confCopy.PeerAddrs = make(map[string]string) - for id, node := range n.adapter.nodes { - confCopy.PeerAddrs[id.String()] = node.wsAddr - } - confData, err := json.Marshal(confCopy) - if err != nil { - return fmt.Errorf("error generating node config: %s", err) - } - // expose the admin namespace via websocket if it's not enabled - exposed := confCopy.Stack.WSExposeAll - if !exposed { - for _, api := range confCopy.Stack.WSModules { - if api == "admin" { - exposed = true - break - } - } - } - if !exposed { - confCopy.Stack.WSModules = append(confCopy.Stack.WSModules, "admin") - } - // start the one-shot server that waits for startup information - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - statusURL, statusC := n.waitForStartupJSON(ctx) - - // start the node - cmd := n.newCmd() - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Env = append(os.Environ(), - envStatusURL+"="+statusURL, - envNodeConfig+"="+string(confData), - ) - if err := cmd.Start(); err != nil { - return fmt.Errorf("error starting node: %s", err) - } - n.Cmd = cmd - - // Wait for the node to start. - status := <-statusC - if status.Err != "" { - return errors.New(status.Err) - } - client, err := rpc.DialWebsocket(ctx, status.WSEndpoint, "") - if err != nil { - return fmt.Errorf("can't connect to RPC server: %v", err) - } - - // Node ready :) - n.client = client - n.wsAddr = status.WSEndpoint - n.Info = status.NodeInfo - return nil -} - -// waitForStartupJSON runs a one-shot HTTP server to receive a startup report. -func (n *ExecNode) waitForStartupJSON(ctx context.Context) (string, chan nodeStartupJSON) { - var ( - ch = make(chan nodeStartupJSON, 1) - quitOnce sync.Once - srv http.Server - ) - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - ch <- nodeStartupJSON{Err: err.Error()} - return "", ch - } - quit := func(status nodeStartupJSON) { - quitOnce.Do(func() { - l.Close() - ch <- status - }) - } - srv.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - var status nodeStartupJSON - if err := json.NewDecoder(r.Body).Decode(&status); err != nil { - status.Err = fmt.Sprintf("can't decode startup report: %v", err) - } - quit(status) - }) - // Run the HTTP server, but don't wait forever and shut it down - // if the context is canceled. - go srv.Serve(l) - go func() { - <-ctx.Done() - quit(nodeStartupJSON{Err: "didn't get startup report"}) - }() - - url := "http://" + l.Addr().String() - return url, ch -} - -// execCommand returns a command which runs the node locally by exec'ing -// the current binary but setting argv[0] to "p2p-node" so that the child -// runs execP2PNode -func (n *ExecNode) execCommand() *exec.Cmd { - return &exec.Cmd{ - Path: reexec.Self(), - Args: []string{"p2p-node", strings.Join(n.Config.Node.Lifecycles, ","), n.ID.String()}, - } -} - -// Stop stops the node by first sending SIGTERM and then SIGKILL if the node -// doesn't stop within 5s -func (n *ExecNode) Stop() error { - if n.Cmd == nil { - return nil - } - defer func() { - n.Cmd = nil - }() - - if n.client != nil { - n.client.Close() - n.client = nil - n.wsAddr = "" - n.Info = nil - } - - if err := n.Cmd.Process.Signal(syscall.SIGTERM); err != nil { - return n.Cmd.Process.Kill() - } - waitErr := make(chan error, 1) - go func() { - waitErr <- n.Cmd.Wait() - }() - select { - case err := <-waitErr: - return err - case <-time.After(5 * time.Second): - return n.Cmd.Process.Kill() - } -} - -// NodeInfo returns information about the node -func (n *ExecNode) NodeInfo() *p2p.NodeInfo { - info := &p2p.NodeInfo{ - ID: n.ID.String(), - } - if n.client != nil { - n.client.Call(&info, "admin_nodeInfo") - } - return info -} - -// ServeRPC serves RPC requests over the given connection by dialling the -// node's WebSocket address and joining the two connections -func (n *ExecNode) ServeRPC(clientConn *websocket.Conn) error { - conn, _, err := websocket.DefaultDialer.Dial(n.wsAddr, nil) - if err != nil { - return err - } - var wg sync.WaitGroup - wg.Add(2) - go wsCopy(&wg, conn, clientConn) - go wsCopy(&wg, clientConn, conn) - wg.Wait() - conn.Close() - return nil -} - -func wsCopy(wg *sync.WaitGroup, src, dst *websocket.Conn) { - defer wg.Done() - for { - msgType, r, err := src.NextReader() - if err != nil { - return - } - w, err := dst.NextWriter(msgType) - if err != nil { - return - } - if _, err = io.Copy(w, r); err != nil { - return - } - } -} - -// Snapshots creates snapshots of the services by calling the -// simulation_snapshot RPC method -func (n *ExecNode) Snapshots() (map[string][]byte, error) { - if n.client == nil { - return nil, errors.New("RPC not started") - } - var snapshots map[string][]byte - return snapshots, n.client.Call(&snapshots, "simulation_snapshot") -} - -// execNodeConfig is used to serialize the node configuration so it can be -// passed to the child process as a JSON encoded environment variable -type execNodeConfig struct { - Stack node.Config `json:"stack"` - Node *NodeConfig `json:"node"` - Snapshots map[string][]byte `json:"snapshots,omitempty"` - PeerAddrs map[string]string `json:"peer_addrs,omitempty"` -} - -func initLogging() { - // Initialize the logging by default first. - var innerHandler slog.Handler - innerHandler = slog.NewTextHandler(os.Stderr, nil) - glogger := log.NewGlogHandler(innerHandler) - glogger.Verbosity(log.LevelInfo) - log.SetDefault(log.NewLogger(glogger)) - - confEnv := os.Getenv(envNodeConfig) - if confEnv == "" { - return - } - var conf execNodeConfig - if err := json.Unmarshal([]byte(confEnv), &conf); err != nil { - return - } - var writer = os.Stderr - if conf.Node.LogFile != "" { - logWriter, err := os.Create(conf.Node.LogFile) - if err != nil { - return - } - writer = logWriter - } - var verbosity = log.LevelInfo - if conf.Node.LogVerbosity <= log.LevelTrace && conf.Node.LogVerbosity >= log.LevelCrit { - verbosity = log.FromLegacyLevel(int(conf.Node.LogVerbosity)) - } - // Reinitialize the logger - innerHandler = log.NewTerminalHandler(writer, true) - glogger = log.NewGlogHandler(innerHandler) - glogger.Verbosity(verbosity) - log.SetDefault(log.NewLogger(glogger)) -} - -// execP2PNode starts a simulation node when the current binary is executed with -// argv[0] being "p2p-node", reading the service / ID from argv[1] / argv[2] -// and the node config from an environment variable. -func execP2PNode() { - initLogging() - - statusURL := os.Getenv(envStatusURL) - if statusURL == "" { - log.Crit("missing " + envStatusURL) - } - - // Start the node and gather startup report. - var status nodeStartupJSON - stack, stackErr := startExecNodeStack() - if stackErr != nil { - status.Err = stackErr.Error() - } else { - status.WSEndpoint = stack.WSEndpoint() - status.NodeInfo = stack.Server().NodeInfo() - } - - // Send status to the host. - statusJSON, _ := json.Marshal(status) - resp, err := http.Post(statusURL, "application/json", bytes.NewReader(statusJSON)) - if err != nil { - log.Crit("Can't post startup info", "url", statusURL, "err", err) - } - resp.Body.Close() - if stackErr != nil { - os.Exit(1) - } - - // Stop the stack if we get a SIGTERM signal. - go func() { - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, syscall.SIGTERM) - defer signal.Stop(sigc) - <-sigc - log.Info("Received SIGTERM, shutting down...") - stack.Close() - }() - stack.Wait() // Wait for the stack to exit. -} - -func startExecNodeStack() (*node.Node, error) { - // read the services from argv - serviceNames := strings.Split(os.Args[1], ",") - - // decode the config - confEnv := os.Getenv(envNodeConfig) - if confEnv == "" { - return nil, fmt.Errorf("missing " + envNodeConfig) - } - var conf execNodeConfig - if err := json.Unmarshal([]byte(confEnv), &conf); err != nil { - return nil, fmt.Errorf("error decoding %s: %v", envNodeConfig, err) - } - - // create enode record - nodeTcpConn, _ := net.ResolveTCPAddr("tcp", conf.Stack.P2P.ListenAddr) - if nodeTcpConn.IP == nil { - nodeTcpConn.IP = net.IPv4(127, 0, 0, 1) - } - conf.Node.initEnode(nodeTcpConn.IP, nodeTcpConn.Port, nodeTcpConn.Port) - conf.Stack.P2P.PrivateKey = conf.Node.PrivateKey - conf.Stack.Logger = log.New("node.id", conf.Node.ID.String()) - - // initialize the devp2p stack - stack, err := node.New(&conf.Stack) - if err != nil { - return nil, fmt.Errorf("error creating node stack: %v", err) - } - - // Register the services, collecting them into a map so they can - // be accessed by the snapshot API. - services := make(map[string]node.Lifecycle, len(serviceNames)) - for _, name := range serviceNames { - lifecycleFunc, exists := lifecycleConstructorFuncs[name] - if !exists { - return nil, fmt.Errorf("unknown node service %q", err) - } - ctx := &ServiceContext{ - RPCDialer: &wsRPCDialer{addrs: conf.PeerAddrs}, - Config: conf.Node, - } - if conf.Snapshots != nil { - ctx.Snapshot = conf.Snapshots[name] - } - service, err := lifecycleFunc(ctx, stack) - if err != nil { - return nil, err - } - services[name] = service - } - - // Add the snapshot API. - stack.RegisterAPIs([]rpc.API{{ - Namespace: "simulation", - Service: SnapshotAPI{services}, - }}) - - if err = stack.Start(); err != nil { - err = fmt.Errorf("error starting stack: %v", err) - } - return stack, err -} - -const ( - envStatusURL = "_P2P_STATUS_URL" - envNodeConfig = "_P2P_NODE_CONFIG" -) - -// nodeStartupJSON is sent to the simulation host after startup. -type nodeStartupJSON struct { - Err string - WSEndpoint string - NodeInfo *p2p.NodeInfo -} - -// SnapshotAPI provides an RPC method to create snapshots of services -type SnapshotAPI struct { - services map[string]node.Lifecycle -} - -func (api SnapshotAPI) Snapshot() (map[string][]byte, error) { - snapshots := make(map[string][]byte) - for name, service := range api.services { - if s, ok := service.(interface { - Snapshot() ([]byte, error) - }); ok { - snap, err := s.Snapshot() - if err != nil { - return nil, err - } - snapshots[name] = snap - } - } - return snapshots, nil -} - -type wsRPCDialer struct { - addrs map[string]string -} - -// DialRPC implements the RPCDialer interface by creating a WebSocket RPC -// client of the given node -func (w *wsRPCDialer) DialRPC(id enode.ID) (*rpc.Client, error) { - addr, ok := w.addrs[id.String()] - if !ok { - return nil, fmt.Errorf("unknown node: %s", id) - } - return rpc.DialWebsocket(context.Background(), addr, "http://localhost") -} diff --git a/p2p/simulations/adapters/inproc.go b/p2p/simulations/adapters/inproc.go deleted file mode 100644 index 349e496b2f..0000000000 --- a/p2p/simulations/adapters/inproc.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package adapters - -import ( - "context" - "errors" - "fmt" - "math" - "net" - "sync" - - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/pipes" - "github.com/ethereum/go-ethereum/rpc" - "github.com/gorilla/websocket" -) - -// SimAdapter is a NodeAdapter which creates in-memory simulation nodes and -// connects them using net.Pipe -type SimAdapter struct { - pipe func() (net.Conn, net.Conn, error) - mtx sync.RWMutex - nodes map[enode.ID]*SimNode - lifecycles LifecycleConstructors -} - -// NewSimAdapter creates a SimAdapter which is capable of running in-memory -// simulation nodes running any of the given services (the services to run on a -// particular node are passed to the NewNode function in the NodeConfig) -// the adapter uses a net.Pipe for in-memory simulated network connections -func NewSimAdapter(services LifecycleConstructors) *SimAdapter { - return &SimAdapter{ - pipe: pipes.NetPipe, - nodes: make(map[enode.ID]*SimNode), - lifecycles: services, - } -} - -// Name returns the name of the adapter for logging purposes -func (s *SimAdapter) Name() string { - return "sim-adapter" -} - -// NewNode returns a new SimNode using the given config -func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) { - s.mtx.Lock() - defer s.mtx.Unlock() - - id := config.ID - // verify that the node has a private key in the config - if config.PrivateKey == nil { - return nil, fmt.Errorf("node is missing private key: %s", id) - } - - // check a node with the ID doesn't already exist - if _, exists := s.nodes[id]; exists { - return nil, fmt.Errorf("node already exists: %s", id) - } - - // check the services are valid - if len(config.Lifecycles) == 0 { - return nil, errors.New("node must have at least one service") - } - for _, service := range config.Lifecycles { - if _, exists := s.lifecycles[service]; !exists { - return nil, fmt.Errorf("unknown node service %q", service) - } - } - - err := config.initDummyEnode() - if err != nil { - return nil, err - } - - n, err := node.New(&node.Config{ - P2P: p2p.Config{ - PrivateKey: config.PrivateKey, - MaxPeers: math.MaxInt32, - NoDiscovery: true, - Dialer: s, - EnableMsgEvents: config.EnableMsgEvents, - }, - ExternalSigner: config.ExternalSigner, - Logger: log.New("node.id", id.String()), - }) - if err != nil { - return nil, err - } - - simNode := &SimNode{ - ID: id, - config: config, - node: n, - adapter: s, - running: make(map[string]node.Lifecycle), - } - s.nodes[id] = simNode - return simNode, nil -} - -// Dial implements the p2p.NodeDialer interface by connecting to the node using -// an in-memory net.Pipe -func (s *SimAdapter) Dial(ctx context.Context, dest *enode.Node) (conn net.Conn, err error) { - node, ok := s.GetNode(dest.ID()) - if !ok { - return nil, fmt.Errorf("unknown node: %s", dest.ID()) - } - srv := node.Server() - if srv == nil { - return nil, fmt.Errorf("node not running: %s", dest.ID()) - } - // SimAdapter.pipe is net.Pipe (NewSimAdapter) - pipe1, pipe2, err := s.pipe() - if err != nil { - return nil, err - } - // this is simulated 'listening' - // asynchronously call the dialed destination node's p2p server - // to set up connection on the 'listening' side - go srv.SetupConn(pipe1, 0, nil) - return pipe2, nil -} - -// DialRPC implements the RPCDialer interface by creating an in-memory RPC -// client of the given node -func (s *SimAdapter) DialRPC(id enode.ID) (*rpc.Client, error) { - node, ok := s.GetNode(id) - if !ok { - return nil, fmt.Errorf("unknown node: %s", id) - } - return node.node.Attach(), nil -} - -// GetNode returns the node with the given ID if it exists -func (s *SimAdapter) GetNode(id enode.ID) (*SimNode, bool) { - s.mtx.RLock() - defer s.mtx.RUnlock() - node, ok := s.nodes[id] - return node, ok -} - -// SimNode is an in-memory simulation node which connects to other nodes using -// net.Pipe (see SimAdapter.Dial), running devp2p protocols directly over that -// pipe -type SimNode struct { - lock sync.RWMutex - ID enode.ID - config *NodeConfig - adapter *SimAdapter - node *node.Node - running map[string]node.Lifecycle - client *rpc.Client - registerOnce sync.Once -} - -// Close closes the underlying node.Node to release -// acquired resources. -func (sn *SimNode) Close() error { - return sn.node.Close() -} - -// Addr returns the node's discovery address -func (sn *SimNode) Addr() []byte { - return []byte(sn.Node().String()) -} - -// Node returns a node descriptor representing the SimNode -func (sn *SimNode) Node() *enode.Node { - return sn.config.Node() -} - -// Client returns an rpc.Client which can be used to communicate with the -// underlying services (it is set once the node has started) -func (sn *SimNode) Client() (*rpc.Client, error) { - sn.lock.RLock() - defer sn.lock.RUnlock() - if sn.client == nil { - return nil, errors.New("node not started") - } - return sn.client, nil -} - -// ServeRPC serves RPC requests over the given connection by creating an -// in-memory client to the node's RPC server. -func (sn *SimNode) ServeRPC(conn *websocket.Conn) error { - handler, err := sn.node.RPCHandler() - if err != nil { - return err - } - codec := rpc.NewFuncCodec(conn, func(v any, _ bool) error { return conn.WriteJSON(v) }, conn.ReadJSON) - handler.ServeCodec(codec, 0) - return nil -} - -// Snapshots creates snapshots of the services by calling the -// simulation_snapshot RPC method -func (sn *SimNode) Snapshots() (map[string][]byte, error) { - sn.lock.RLock() - services := make(map[string]node.Lifecycle, len(sn.running)) - for name, service := range sn.running { - services[name] = service - } - sn.lock.RUnlock() - if len(services) == 0 { - return nil, errors.New("no running services") - } - snapshots := make(map[string][]byte) - for name, service := range services { - if s, ok := service.(interface { - Snapshot() ([]byte, error) - }); ok { - snap, err := s.Snapshot() - if err != nil { - return nil, err - } - snapshots[name] = snap - } - } - return snapshots, nil -} - -// Start registers the services and starts the underlying devp2p node -func (sn *SimNode) Start(snapshots map[string][]byte) error { - // ensure we only register the services once in the case of the node - // being stopped and then started again - var regErr error - sn.registerOnce.Do(func() { - for _, name := range sn.config.Lifecycles { - ctx := &ServiceContext{ - RPCDialer: sn.adapter, - Config: sn.config, - } - if snapshots != nil { - ctx.Snapshot = snapshots[name] - } - serviceFunc := sn.adapter.lifecycles[name] - service, err := serviceFunc(ctx, sn.node) - if err != nil { - regErr = err - break - } - // if the service has already been registered, don't register it again. - if _, ok := sn.running[name]; ok { - continue - } - sn.running[name] = service - } - }) - if regErr != nil { - return regErr - } - - if err := sn.node.Start(); err != nil { - return err - } - - // create an in-process RPC client - client := sn.node.Attach() - sn.lock.Lock() - sn.client = client - sn.lock.Unlock() - - return nil -} - -// Stop closes the RPC client and stops the underlying devp2p node -func (sn *SimNode) Stop() error { - sn.lock.Lock() - if sn.client != nil { - sn.client.Close() - sn.client = nil - } - sn.lock.Unlock() - return sn.node.Close() -} - -// Service returns a running service by name -func (sn *SimNode) Service(name string) node.Lifecycle { - sn.lock.RLock() - defer sn.lock.RUnlock() - return sn.running[name] -} - -// Services returns a copy of the underlying services -func (sn *SimNode) Services() []node.Lifecycle { - sn.lock.RLock() - defer sn.lock.RUnlock() - services := make([]node.Lifecycle, 0, len(sn.running)) - for _, service := range sn.running { - services = append(services, service) - } - return services -} - -// ServiceMap returns a map by names of the underlying services -func (sn *SimNode) ServiceMap() map[string]node.Lifecycle { - sn.lock.RLock() - defer sn.lock.RUnlock() - services := make(map[string]node.Lifecycle, len(sn.running)) - for name, service := range sn.running { - services[name] = service - } - return services -} - -// Server returns the underlying p2p.Server -func (sn *SimNode) Server() *p2p.Server { - return sn.node.Server() -} - -// SubscribeEvents subscribes the given channel to peer events from the -// underlying p2p.Server -func (sn *SimNode) SubscribeEvents(ch chan *p2p.PeerEvent) event.Subscription { - srv := sn.Server() - if srv == nil { - panic("node not running") - } - return srv.SubscribeEvents(ch) -} - -// NodeInfo returns information about the node -func (sn *SimNode) NodeInfo() *p2p.NodeInfo { - server := sn.Server() - if server == nil { - return &p2p.NodeInfo{ - ID: sn.ID.String(), - Enode: sn.Node().String(), - } - } - return server.NodeInfo() -} diff --git a/p2p/simulations/adapters/inproc_test.go b/p2p/simulations/adapters/inproc_test.go deleted file mode 100644 index 2a61508fe1..0000000000 --- a/p2p/simulations/adapters/inproc_test.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package adapters - -import ( - "bytes" - "encoding/binary" - "fmt" - "sync" - "testing" - - "github.com/ethereum/go-ethereum/p2p/simulations/pipes" -) - -func TestTCPPipe(t *testing.T) { - c1, c2, err := pipes.TCPPipe() - if err != nil { - t.Fatal(err) - } - - msgs := 50 - size := 1024 - for i := 0; i < msgs; i++ { - msg := make([]byte, size) - binary.PutUvarint(msg, uint64(i)) - if _, err := c1.Write(msg); err != nil { - t.Fatal(err) - } - } - - for i := 0; i < msgs; i++ { - msg := make([]byte, size) - binary.PutUvarint(msg, uint64(i)) - out := make([]byte, size) - if _, err := c2.Read(out); err != nil { - t.Fatal(err) - } - if !bytes.Equal(msg, out) { - t.Fatalf("expected %#v, got %#v", msg, out) - } - } -} - -func TestTCPPipeBidirections(t *testing.T) { - c1, c2, err := pipes.TCPPipe() - if err != nil { - t.Fatal(err) - } - - msgs := 50 - size := 7 - for i := 0; i < msgs; i++ { - msg := []byte(fmt.Sprintf("ping %02d", i)) - if _, err := c1.Write(msg); err != nil { - t.Fatal(err) - } - } - - for i := 0; i < msgs; i++ { - expected := []byte(fmt.Sprintf("ping %02d", i)) - out := make([]byte, size) - if _, err := c2.Read(out); err != nil { - t.Fatal(err) - } - - if !bytes.Equal(expected, out) { - t.Fatalf("expected %#v, got %#v", out, expected) - } else { - msg := []byte(fmt.Sprintf("pong %02d", i)) - if _, err := c2.Write(msg); err != nil { - t.Fatal(err) - } - } - } - - for i := 0; i < msgs; i++ { - expected := []byte(fmt.Sprintf("pong %02d", i)) - out := make([]byte, size) - if _, err := c1.Read(out); err != nil { - t.Fatal(err) - } - if !bytes.Equal(expected, out) { - t.Fatalf("expected %#v, got %#v", out, expected) - } - } -} - -func TestNetPipe(t *testing.T) { - c1, c2, err := pipes.NetPipe() - if err != nil { - t.Fatal(err) - } - - msgs := 50 - size := 1024 - var wg sync.WaitGroup - defer wg.Wait() - - // netPipe is blocking, so writes are emitted asynchronously - wg.Add(1) - go func() { - defer wg.Done() - - for i := 0; i < msgs; i++ { - msg := make([]byte, size) - binary.PutUvarint(msg, uint64(i)) - if _, err := c1.Write(msg); err != nil { - t.Error(err) - } - } - }() - - for i := 0; i < msgs; i++ { - msg := make([]byte, size) - binary.PutUvarint(msg, uint64(i)) - out := make([]byte, size) - if _, err := c2.Read(out); err != nil { - t.Error(err) - } - if !bytes.Equal(msg, out) { - t.Errorf("expected %#v, got %#v", msg, out) - } - } -} - -func TestNetPipeBidirections(t *testing.T) { - c1, c2, err := pipes.NetPipe() - if err != nil { - t.Fatal(err) - } - - msgs := 1000 - size := 8 - pingTemplate := "ping %03d" - pongTemplate := "pong %03d" - var wg sync.WaitGroup - defer wg.Wait() - - // netPipe is blocking, so writes are emitted asynchronously - wg.Add(1) - go func() { - defer wg.Done() - - for i := 0; i < msgs; i++ { - msg := []byte(fmt.Sprintf(pingTemplate, i)) - if _, err := c1.Write(msg); err != nil { - t.Error(err) - } - } - }() - - // netPipe is blocking, so reads for pong are emitted asynchronously - wg.Add(1) - go func() { - defer wg.Done() - - for i := 0; i < msgs; i++ { - expected := []byte(fmt.Sprintf(pongTemplate, i)) - out := make([]byte, size) - if _, err := c1.Read(out); err != nil { - t.Error(err) - } - if !bytes.Equal(expected, out) { - t.Errorf("expected %#v, got %#v", expected, out) - } - } - }() - - // expect to read pings, and respond with pongs to the alternate connection - for i := 0; i < msgs; i++ { - expected := []byte(fmt.Sprintf(pingTemplate, i)) - - out := make([]byte, size) - _, err := c2.Read(out) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(expected, out) { - t.Errorf("expected %#v, got %#v", expected, out) - } else { - msg := []byte(fmt.Sprintf(pongTemplate, i)) - if _, err := c2.Write(msg); err != nil { - t.Fatal(err) - } - } - } -} diff --git a/p2p/simulations/adapters/types.go b/p2p/simulations/adapters/types.go deleted file mode 100644 index fb8463d221..0000000000 --- a/p2p/simulations/adapters/types.go +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package adapters - -import ( - "crypto/ecdsa" - "encoding/hex" - "encoding/json" - "fmt" - "net" - "os" - "strconv" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/internal/reexec" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/rpc" - "github.com/gorilla/websocket" - "golang.org/x/exp/slog" -) - -// Node represents a node in a simulation network which is created by a -// NodeAdapter, for example: -// -// - SimNode, an in-memory node in the same process -// - ExecNode, a child process node -// - DockerNode, a node running in a Docker container -type Node interface { - // Addr returns the node's address (e.g. an Enode URL) - Addr() []byte - - // Client returns the RPC client which is created once the node is - // up and running - Client() (*rpc.Client, error) - - // ServeRPC serves RPC requests over the given connection - ServeRPC(*websocket.Conn) error - - // Start starts the node with the given snapshots - Start(snapshots map[string][]byte) error - - // Stop stops the node - Stop() error - - // NodeInfo returns information about the node - NodeInfo() *p2p.NodeInfo - - // Snapshots creates snapshots of the running services - Snapshots() (map[string][]byte, error) -} - -// NodeAdapter is used to create Nodes in a simulation network -type NodeAdapter interface { - // Name returns the name of the adapter for logging purposes - Name() string - - // NewNode creates a new node with the given configuration - NewNode(config *NodeConfig) (Node, error) -} - -// NodeConfig is the configuration used to start a node in a simulation -// network -type NodeConfig struct { - // ID is the node's ID which is used to identify the node in the - // simulation network - ID enode.ID - - // PrivateKey is the node's private key which is used by the devp2p - // stack to encrypt communications - PrivateKey *ecdsa.PrivateKey - - // Enable peer events for Msgs - EnableMsgEvents bool - - // Name is a human friendly name for the node like "node01" - Name string - - // Use an existing database instead of a temporary one if non-empty - DataDir string - - // Lifecycles are the names of the service lifecycles which should be run when - // starting the node (for SimNodes it should be the names of service lifecycles - // contained in SimAdapter.lifecycles, for other nodes it should be - // service lifecycles registered by calling the RegisterLifecycle function) - Lifecycles []string - - // Properties are the names of the properties this node should hold - // within running services (e.g. "bootnode", "lightnode" or any custom values) - // These values need to be checked and acted upon by node Services - Properties []string - - // ExternalSigner specifies an external URI for a clef-type signer - ExternalSigner string - - // Enode - node *enode.Node - - // ENR Record with entries to overwrite - Record enr.Record - - // function to sanction or prevent suggesting a peer - Reachable func(id enode.ID) bool - - Port uint16 - - // LogFile is the log file name of the p2p node at runtime. - // - // The default value is empty so that the default log writer - // is the system standard output. - LogFile string - - // LogVerbosity is the log verbosity of the p2p node at runtime. - // - // The default verbosity is INFO. - LogVerbosity slog.Level -} - -// nodeConfigJSON is used to encode and decode NodeConfig as JSON by encoding -// all fields as strings -type nodeConfigJSON struct { - ID string `json:"id"` - PrivateKey string `json:"private_key"` - Name string `json:"name"` - Lifecycles []string `json:"lifecycles"` - Properties []string `json:"properties"` - EnableMsgEvents bool `json:"enable_msg_events"` - Port uint16 `json:"port"` - LogFile string `json:"logfile"` - LogVerbosity int `json:"log_verbosity"` -} - -// MarshalJSON implements the json.Marshaler interface by encoding the config -// fields as strings -func (n *NodeConfig) MarshalJSON() ([]byte, error) { - confJSON := nodeConfigJSON{ - ID: n.ID.String(), - Name: n.Name, - Lifecycles: n.Lifecycles, - Properties: n.Properties, - Port: n.Port, - EnableMsgEvents: n.EnableMsgEvents, - LogFile: n.LogFile, - LogVerbosity: int(n.LogVerbosity), - } - if n.PrivateKey != nil { - confJSON.PrivateKey = hex.EncodeToString(crypto.FromECDSA(n.PrivateKey)) - } - return json.Marshal(confJSON) -} - -// UnmarshalJSON implements the json.Unmarshaler interface by decoding the json -// string values into the config fields -func (n *NodeConfig) UnmarshalJSON(data []byte) error { - var confJSON nodeConfigJSON - if err := json.Unmarshal(data, &confJSON); err != nil { - return err - } - - if confJSON.ID != "" { - if err := n.ID.UnmarshalText([]byte(confJSON.ID)); err != nil { - return err - } - } - - if confJSON.PrivateKey != "" { - key, err := hex.DecodeString(confJSON.PrivateKey) - if err != nil { - return err - } - privKey, err := crypto.ToECDSA(key) - if err != nil { - return err - } - n.PrivateKey = privKey - } - - n.Name = confJSON.Name - n.Lifecycles = confJSON.Lifecycles - n.Properties = confJSON.Properties - n.Port = confJSON.Port - n.EnableMsgEvents = confJSON.EnableMsgEvents - n.LogFile = confJSON.LogFile - n.LogVerbosity = slog.Level(confJSON.LogVerbosity) - - return nil -} - -// Node returns the node descriptor represented by the config. -func (n *NodeConfig) Node() *enode.Node { - return n.node -} - -// RandomNodeConfig returns node configuration with a randomly generated ID and -// PrivateKey -func RandomNodeConfig() *NodeConfig { - prvkey, err := crypto.GenerateKey() - if err != nil { - panic("unable to generate key") - } - - port, err := assignTCPPort() - if err != nil { - panic("unable to assign tcp port") - } - - enodId := enode.PubkeyToIDV4(&prvkey.PublicKey) - return &NodeConfig{ - PrivateKey: prvkey, - ID: enodId, - Name: fmt.Sprintf("node_%s", enodId.String()), - Port: port, - EnableMsgEvents: true, - LogVerbosity: log.LvlInfo, - } -} - -func assignTCPPort() (uint16, error) { - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return 0, err - } - l.Close() - _, port, err := net.SplitHostPort(l.Addr().String()) - if err != nil { - return 0, err - } - p, err := strconv.ParseUint(port, 10, 16) - if err != nil { - return 0, err - } - return uint16(p), nil -} - -// ServiceContext is a collection of options and methods which can be utilised -// when starting services -type ServiceContext struct { - RPCDialer - - Config *NodeConfig - Snapshot []byte -} - -// RPCDialer is used when initialising services which need to connect to -// other nodes in the network (for example a simulated Swarm node which needs -// to connect to a Geth node to resolve ENS names) -type RPCDialer interface { - DialRPC(id enode.ID) (*rpc.Client, error) -} - -// LifecycleConstructor allows a Lifecycle to be constructed during node start-up. -// While the service-specific package usually takes care of Lifecycle creation and registration, -// for testing purposes, it is useful to be able to construct a Lifecycle on spot. -type LifecycleConstructor func(ctx *ServiceContext, stack *node.Node) (node.Lifecycle, error) - -// LifecycleConstructors stores LifecycleConstructor functions to call during node start-up. -type LifecycleConstructors map[string]LifecycleConstructor - -// lifecycleConstructorFuncs is a map of registered services which are used to boot devp2p -// nodes -var lifecycleConstructorFuncs = make(LifecycleConstructors) - -// RegisterLifecycles registers the given Services which can then be used to -// start devp2p nodes using either the Exec or Docker adapters. -// -// It should be called in an init function so that it has the opportunity to -// execute the services before main() is called. -func RegisterLifecycles(lifecycles LifecycleConstructors) { - for name, f := range lifecycles { - if _, exists := lifecycleConstructorFuncs[name]; exists { - panic(fmt.Sprintf("node service already exists: %q", name)) - } - lifecycleConstructorFuncs[name] = f - } - - // now we have registered the services, run reexec.Init() which will - // potentially start one of the services if the current binary has - // been exec'd with argv[0] set to "p2p-node" - if reexec.Init() { - os.Exit(0) - } -} - -// adds the host part to the configuration's ENR, signs it -// creates and the corresponding enode object to the configuration -func (n *NodeConfig) initEnode(ip net.IP, tcpport int, udpport int) error { - enrIp := enr.IP(ip) - n.Record.Set(&enrIp) - enrTcpPort := enr.TCP(tcpport) - n.Record.Set(&enrTcpPort) - enrUdpPort := enr.UDP(udpport) - n.Record.Set(&enrUdpPort) - - err := enode.SignV4(&n.Record, n.PrivateKey) - if err != nil { - return fmt.Errorf("unable to generate ENR: %v", err) - } - nod, err := enode.New(enode.V4ID{}, &n.Record) - if err != nil { - return fmt.Errorf("unable to create enode: %v", err) - } - log.Trace("simnode new", "record", n.Record) - n.node = nod - return nil -} - -func (n *NodeConfig) initDummyEnode() error { - return n.initEnode(net.IPv4(127, 0, 0, 1), int(n.Port), 0) -} diff --git a/p2p/simulations/connect.go b/p2p/simulations/connect.go deleted file mode 100644 index ede96b34c1..0000000000 --- a/p2p/simulations/connect.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "errors" - "strings" - - "github.com/ethereum/go-ethereum/p2p/enode" -) - -var ( - ErrNodeNotFound = errors.New("node not found") -) - -// ConnectToLastNode connects the node with provided NodeID -// to the last node that is up, and avoiding connection to self. -// It is useful when constructing a chain network topology -// when Network adds and removes nodes dynamically. -func (net *Network) ConnectToLastNode(id enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - ids := net.getUpNodeIDs() - l := len(ids) - if l < 2 { - return nil - } - last := ids[l-1] - if last == id { - last = ids[l-2] - } - return net.connectNotConnected(last, id) -} - -// ConnectToRandomNode connects the node with provided NodeID -// to a random node that is up. -func (net *Network) ConnectToRandomNode(id enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - selected := net.getRandomUpNode(id) - if selected == nil { - return ErrNodeNotFound - } - return net.connectNotConnected(selected.ID(), id) -} - -// ConnectNodesFull connects all nodes one to another. -// It provides a complete connectivity in the network -// which should be rarely needed. -func (net *Network) ConnectNodesFull(ids []enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - if ids == nil { - ids = net.getUpNodeIDs() - } - for i, lid := range ids { - for _, rid := range ids[i+1:] { - if err = net.connectNotConnected(lid, rid); err != nil { - return err - } - } - } - return nil -} - -// ConnectNodesChain connects all nodes in a chain topology. -// If ids argument is nil, all nodes that are up will be connected. -func (net *Network) ConnectNodesChain(ids []enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - return net.connectNodesChain(ids) -} - -func (net *Network) connectNodesChain(ids []enode.ID) (err error) { - if ids == nil { - ids = net.getUpNodeIDs() - } - l := len(ids) - for i := 0; i < l-1; i++ { - if err := net.connectNotConnected(ids[i], ids[i+1]); err != nil { - return err - } - } - return nil -} - -// ConnectNodesRing connects all nodes in a ring topology. -// If ids argument is nil, all nodes that are up will be connected. -func (net *Network) ConnectNodesRing(ids []enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - if ids == nil { - ids = net.getUpNodeIDs() - } - l := len(ids) - if l < 2 { - return nil - } - if err := net.connectNodesChain(ids); err != nil { - return err - } - return net.connectNotConnected(ids[l-1], ids[0]) -} - -// ConnectNodesStar connects all nodes into a star topology -// If ids argument is nil, all nodes that are up will be connected. -func (net *Network) ConnectNodesStar(ids []enode.ID, center enode.ID) (err error) { - net.lock.Lock() - defer net.lock.Unlock() - - if ids == nil { - ids = net.getUpNodeIDs() - } - for _, id := range ids { - if center == id { - continue - } - if err := net.connectNotConnected(center, id); err != nil { - return err - } - } - return nil -} - -func (net *Network) connectNotConnected(oneID, otherID enode.ID) error { - return ignoreAlreadyConnectedErr(net.connect(oneID, otherID)) -} - -func ignoreAlreadyConnectedErr(err error) error { - if err == nil || strings.Contains(err.Error(), "already connected") { - return nil - } - return err -} diff --git a/p2p/simulations/connect_test.go b/p2p/simulations/connect_test.go deleted file mode 100644 index 0154a18b03..0000000000 --- a/p2p/simulations/connect_test.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "testing" - - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" -) - -func newTestNetwork(t *testing.T, nodeCount int) (*Network, []enode.ID) { - t.Helper() - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "noopwoop": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - return NewNoopService(nil), nil - }, - }) - - // create network - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "noopwoop", - }) - - // create and start nodes - ids := make([]enode.ID, nodeCount) - for i := range ids { - conf := adapters.RandomNodeConfig() - node, err := network.NewNodeWithConfig(conf) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - if err := network.Start(node.ID()); err != nil { - t.Fatalf("error starting node: %s", err) - } - ids[i] = node.ID() - } - - if len(network.Conns) > 0 { - t.Fatal("no connections should exist after just adding nodes") - } - - return network, ids -} - -func TestConnectToLastNode(t *testing.T) { - net, ids := newTestNetwork(t, 10) - defer net.Shutdown() - - first := ids[0] - if err := net.ConnectToLastNode(first); err != nil { - t.Fatal(err) - } - - last := ids[len(ids)-1] - for i, id := range ids { - if id == first || id == last { - continue - } - - if net.GetConn(first, id) != nil { - t.Errorf("connection must not exist with node(ind: %v, id: %v)", i, id) - } - } - - if net.GetConn(first, last) == nil { - t.Error("first and last node must be connected") - } -} - -func TestConnectToRandomNode(t *testing.T) { - net, ids := newTestNetwork(t, 10) - defer net.Shutdown() - - err := net.ConnectToRandomNode(ids[0]) - if err != nil { - t.Fatal(err) - } - - var cc int - for i, a := range ids { - for _, b := range ids[i:] { - if net.GetConn(a, b) != nil { - cc++ - } - } - } - - if cc != 1 { - t.Errorf("expected one connection, got %v", cc) - } -} - -func TestConnectNodesFull(t *testing.T) { - tests := []struct { - name string - nodeCount int - }{ - {name: "no node", nodeCount: 0}, - {name: "single node", nodeCount: 1}, - {name: "2 nodes", nodeCount: 2}, - {name: "3 nodes", nodeCount: 3}, - {name: "even number of nodes", nodeCount: 12}, - {name: "odd number of nodes", nodeCount: 13}, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - net, ids := newTestNetwork(t, test.nodeCount) - defer net.Shutdown() - - err := net.ConnectNodesFull(ids) - if err != nil { - t.Fatal(err) - } - - VerifyFull(t, net, ids) - }) - } -} - -func TestConnectNodesChain(t *testing.T) { - net, ids := newTestNetwork(t, 10) - defer net.Shutdown() - - err := net.ConnectNodesChain(ids) - if err != nil { - t.Fatal(err) - } - - VerifyChain(t, net, ids) -} - -func TestConnectNodesRing(t *testing.T) { - net, ids := newTestNetwork(t, 10) - defer net.Shutdown() - - err := net.ConnectNodesRing(ids) - if err != nil { - t.Fatal(err) - } - - VerifyRing(t, net, ids) -} - -func TestConnectNodesStar(t *testing.T) { - net, ids := newTestNetwork(t, 10) - defer net.Shutdown() - - pivotIndex := 2 - - err := net.ConnectNodesStar(ids, ids[pivotIndex]) - if err != nil { - t.Fatal(err) - } - - VerifyStar(t, net, ids, pivotIndex) -} diff --git a/p2p/simulations/events.go b/p2p/simulations/events.go deleted file mode 100644 index d0d03794ed..0000000000 --- a/p2p/simulations/events.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "fmt" - "time" -) - -// EventType is the type of event emitted by a simulation network -type EventType string - -const ( - // EventTypeNode is the type of event emitted when a node is either - // created, started or stopped - EventTypeNode EventType = "node" - - // EventTypeConn is the type of event emitted when a connection is - // is either established or dropped between two nodes - EventTypeConn EventType = "conn" - - // EventTypeMsg is the type of event emitted when a p2p message it - // sent between two nodes - EventTypeMsg EventType = "msg" -) - -// Event is an event emitted by a simulation network -type Event struct { - // Type is the type of the event - Type EventType `json:"type"` - - // Time is the time the event happened - Time time.Time `json:"time"` - - // Control indicates whether the event is the result of a controlled - // action in the network - Control bool `json:"control"` - - // Node is set if the type is EventTypeNode - Node *Node `json:"node,omitempty"` - - // Conn is set if the type is EventTypeConn - Conn *Conn `json:"conn,omitempty"` - - // Msg is set if the type is EventTypeMsg - Msg *Msg `json:"msg,omitempty"` - - //Optionally provide data (currently for simulation frontends only) - Data interface{} `json:"data"` -} - -// NewEvent creates a new event for the given object which should be either a -// Node, Conn or Msg. -// -// The object is copied so that the event represents the state of the object -// when NewEvent is called. -func NewEvent(v interface{}) *Event { - event := &Event{Time: time.Now()} - switch v := v.(type) { - case *Node: - event.Type = EventTypeNode - event.Node = v.copy() - case *Conn: - event.Type = EventTypeConn - conn := *v - event.Conn = &conn - case *Msg: - event.Type = EventTypeMsg - msg := *v - event.Msg = &msg - default: - panic(fmt.Sprintf("invalid event type: %T", v)) - } - return event -} - -// ControlEvent creates a new control event -func ControlEvent(v interface{}) *Event { - event := NewEvent(v) - event.Control = true - return event -} - -// String returns the string representation of the event -func (e *Event) String() string { - switch e.Type { - case EventTypeNode: - return fmt.Sprintf(" id: %s up: %t", e.Node.ID().TerminalString(), e.Node.Up()) - case EventTypeConn: - return fmt.Sprintf(" nodes: %s->%s up: %t", e.Conn.One.TerminalString(), e.Conn.Other.TerminalString(), e.Conn.Up) - case EventTypeMsg: - return fmt.Sprintf(" nodes: %s->%s proto: %s, code: %d, received: %t", e.Msg.One.TerminalString(), e.Msg.Other.TerminalString(), e.Msg.Protocol, e.Msg.Code, e.Msg.Received) - default: - return "" - } -} diff --git a/p2p/simulations/examples/README.md b/p2p/simulations/examples/README.md deleted file mode 100644 index 822a48dcb6..0000000000 --- a/p2p/simulations/examples/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# devp2p simulation examples - -## ping-pong - -`ping-pong.go` implements a simulation network which contains nodes running a -simple "ping-pong" protocol where nodes send a ping message to all their -connected peers every 10s and receive pong messages in return. - -To run the simulation, run `go run ping-pong.go` in one terminal to start the -simulation API and `./ping-pong.sh` in another to start and connect the nodes: - -``` -$ go run ping-pong.go -INFO [08-15|13:53:49] using sim adapter -INFO [08-15|13:53:49] starting simulation server on 0.0.0.0:8888... -``` - -``` -$ ./ping-pong.sh ----> 13:58:12 creating 10 nodes -Created node01 -Started node01 -... -Created node10 -Started node10 ----> 13:58:13 connecting node01 to all other nodes -Connected node01 to node02 -... -Connected node01 to node10 ----> 13:58:14 done -``` - -Use the `--adapter` flag to choose the adapter type: - -``` -$ go run ping-pong.go --adapter exec -INFO [08-15|14:01:14] using exec adapter tmpdir=/var/folders/k6/wpsgfg4n23ddbc6f5cnw5qg00000gn/T/p2p-example992833779 -INFO [08-15|14:01:14] starting simulation server on 0.0.0.0:8888... -``` diff --git a/p2p/simulations/examples/ping-pong.go b/p2p/simulations/examples/ping-pong.go deleted file mode 100644 index f093c9a98b..0000000000 --- a/p2p/simulations/examples/ping-pong.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package main - -import ( - "flag" - "fmt" - "io" - "net/http" - "os" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/common/gopool" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" -) - -var adapterType = flag.String("adapter", "sim", `node adapter to use (one of "sim", "exec" or "docker")`) - -// main() starts a simulation network which contains nodes running a simple -// ping-pong protocol -func main() { - flag.Parse() - - // set the log level to Trace - log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, false))) - - // register a single ping-pong service - services := map[string]adapters.LifecycleConstructor{ - "ping-pong": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - pps := newPingPongService(ctx.Config.ID) - stack.RegisterProtocols(pps.Protocols()) - return pps, nil - }, - } - adapters.RegisterLifecycles(services) - - // create the NodeAdapter - var adapter adapters.NodeAdapter - - switch *adapterType { - - case "sim": - log.Info("using sim adapter") - adapter = adapters.NewSimAdapter(services) - - case "exec": - tmpdir, err := os.MkdirTemp("", "p2p-example") - if err != nil { - log.Crit("error creating temp dir", "err", err) - } - defer os.RemoveAll(tmpdir) - log.Info("using exec adapter", "tmpdir", tmpdir) - adapter = adapters.NewExecAdapter(tmpdir) - - default: - log.Crit(fmt.Sprintf("unknown node adapter %q", *adapterType)) - } - - // start the HTTP API - log.Info("starting simulation server on 0.0.0.0:8888...") - network := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ - DefaultService: "ping-pong", - }) - if err := http.ListenAndServe(":8888", simulations.NewServer(network)); err != nil { - log.Crit("error starting simulation server", "err", err) - } -} - -// pingPongService runs a ping-pong protocol between nodes where each node -// sends a ping to all its connected peers every 10s and receives a pong in -// return -type pingPongService struct { - id enode.ID - log log.Logger - received atomic.Int64 -} - -func newPingPongService(id enode.ID) *pingPongService { - return &pingPongService{ - id: id, - log: log.New("node.id", id), - } -} - -func (p *pingPongService) Protocols() []p2p.Protocol { - return []p2p.Protocol{{ - Name: "ping-pong", - Version: 1, - Length: 2, - Run: p.Run, - NodeInfo: p.Info, - }} -} - -func (p *pingPongService) Start() error { - p.log.Info("ping-pong service starting") - return nil -} - -func (p *pingPongService) Stop() error { - p.log.Info("ping-pong service stopping") - return nil -} - -func (p *pingPongService) Info() interface{} { - return struct { - Received int64 `json:"received"` - }{ - p.received.Load(), - } -} - -const ( - pingMsgCode = iota - pongMsgCode -) - -// Run implements the ping-pong protocol which sends ping messages to the peer -// at 10s intervals, and responds to pings with pong messages. -func (p *pingPongService) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { - log := p.log.New("peer.id", peer.ID()) - - errC := make(chan error, 1) - gopool.Submit(func() { - for range time.Tick(10 * time.Second) { - log.Info("sending ping") - if err := p2p.Send(rw, pingMsgCode, "PING"); err != nil { - errC <- err - return - } - } - }) - gopool.Submit(func() { - for { - msg, err := rw.ReadMsg() - if err != nil { - errC <- err - return - } - payload, err := io.ReadAll(msg.Payload) - if err != nil { - errC <- err - return - } - log.Info("received message", "msg.code", msg.Code, "msg.payload", string(payload)) - p.received.Add(1) - if msg.Code == pingMsgCode { - log.Info("sending pong") - gopool.Submit(func() { p2p.Send(rw, pongMsgCode, "PONG") }) - } - } - }) - return <-errC -} diff --git a/p2p/simulations/examples/ping-pong.sh b/p2p/simulations/examples/ping-pong.sh deleted file mode 100755 index 47936bd9a0..0000000000 --- a/p2p/simulations/examples/ping-pong.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# -# Boot a ping-pong network simulation using the HTTP API started by ping-pong.go - -set -e - -main() { - if ! which p2psim &>/dev/null; then - fail "missing p2psim binary (you need to build cmd/p2psim and put it in \$PATH)" - fi - - info "creating 10 nodes" - for i in $(seq 1 10); do - p2psim node create --name "$(node_name $i)" - p2psim node start "$(node_name $i)" - done - - info "connecting node01 to all other nodes" - for i in $(seq 2 10); do - p2psim node connect "node01" "$(node_name $i)" - done - - info "done" -} - -node_name() { - local num=$1 - echo "node$(printf '%02d' $num)" -} - -info() { - echo -e "\033[1;32m---> $(date +%H:%M:%S) ${@}\033[0m" -} - -fail() { - echo -e "\033[1;31mERROR: ${@}\033[0m" >&2 - exit 1 -} - -main "$@" diff --git a/p2p/simulations/http.go b/p2p/simulations/http.go deleted file mode 100644 index 34521b4778..0000000000 --- a/p2p/simulations/http.go +++ /dev/null @@ -1,743 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "bufio" - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "html" - "io" - "net/http" - "strconv" - "strings" - "sync" - - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" - "github.com/ethereum/go-ethereum/rpc" - "github.com/gorilla/websocket" - "github.com/julienschmidt/httprouter" -) - -// DefaultClient is the default simulation API client which expects the API -// to be running at http://localhost:8888 -var DefaultClient = NewClient("http://localhost:8888") - -// Client is a client for the simulation HTTP API which supports creating -// and managing simulation networks -type Client struct { - URL string - - client *http.Client -} - -// NewClient returns a new simulation API client -func NewClient(url string) *Client { - return &Client{ - URL: url, - client: http.DefaultClient, - } -} - -// GetNetwork returns details of the network -func (c *Client) GetNetwork() (*Network, error) { - network := &Network{} - return network, c.Get("/", network) -} - -// StartNetwork starts all existing nodes in the simulation network -func (c *Client) StartNetwork() error { - return c.Post("/start", nil, nil) -} - -// StopNetwork stops all existing nodes in a simulation network -func (c *Client) StopNetwork() error { - return c.Post("/stop", nil, nil) -} - -// CreateSnapshot creates a network snapshot -func (c *Client) CreateSnapshot() (*Snapshot, error) { - snap := &Snapshot{} - return snap, c.Get("/snapshot", snap) -} - -// LoadSnapshot loads a snapshot into the network -func (c *Client) LoadSnapshot(snap *Snapshot) error { - return c.Post("/snapshot", snap, nil) -} - -// SubscribeOpts is a collection of options to use when subscribing to network -// events -type SubscribeOpts struct { - // Current instructs the server to send events for existing nodes and - // connections first - Current bool - - // Filter instructs the server to only send a subset of message events - Filter string -} - -// SubscribeNetwork subscribes to network events which are sent from the server -// as a server-sent-events stream, optionally receiving events for existing -// nodes and connections and filtering message events -func (c *Client) SubscribeNetwork(events chan *Event, opts SubscribeOpts) (event.Subscription, error) { - url := fmt.Sprintf("%s/events?current=%t&filter=%s", c.URL, opts.Current, opts.Filter) - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return nil, err - } - req.Header.Set("Accept", "text/event-stream") - res, err := c.client.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode != http.StatusOK { - response, _ := io.ReadAll(res.Body) - res.Body.Close() - return nil, fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response) - } - - // define a producer function to pass to event.Subscription - // which reads server-sent events from res.Body and sends - // them to the events channel - producer := func(stop <-chan struct{}) error { - defer res.Body.Close() - - // read lines from res.Body in a goroutine so that we are - // always reading from the stop channel - lines := make(chan string) - errC := make(chan error, 1) - go func() { - s := bufio.NewScanner(res.Body) - for s.Scan() { - select { - case lines <- s.Text(): - case <-stop: - return - } - } - errC <- s.Err() - }() - - // detect any lines which start with "data:", decode the data - // into an event and send it to the events channel - for { - select { - case line := <-lines: - if !strings.HasPrefix(line, "data:") { - continue - } - data := strings.TrimSpace(strings.TrimPrefix(line, "data:")) - event := &Event{} - if err := json.Unmarshal([]byte(data), event); err != nil { - return fmt.Errorf("error decoding SSE event: %s", err) - } - select { - case events <- event: - case <-stop: - return nil - } - case err := <-errC: - return err - case <-stop: - return nil - } - } - } - - return event.NewSubscription(producer), nil -} - -// GetNodes returns all nodes which exist in the network -func (c *Client) GetNodes() ([]*p2p.NodeInfo, error) { - var nodes []*p2p.NodeInfo - return nodes, c.Get("/nodes", &nodes) -} - -// CreateNode creates a node in the network using the given configuration -func (c *Client) CreateNode(config *adapters.NodeConfig) (*p2p.NodeInfo, error) { - node := &p2p.NodeInfo{} - return node, c.Post("/nodes", config, node) -} - -// GetNode returns details of a node -func (c *Client) GetNode(nodeID string) (*p2p.NodeInfo, error) { - node := &p2p.NodeInfo{} - return node, c.Get(fmt.Sprintf("/nodes/%s", nodeID), node) -} - -// StartNode starts a node -func (c *Client) StartNode(nodeID string) error { - return c.Post(fmt.Sprintf("/nodes/%s/start", nodeID), nil, nil) -} - -// StopNode stops a node -func (c *Client) StopNode(nodeID string) error { - return c.Post(fmt.Sprintf("/nodes/%s/stop", nodeID), nil, nil) -} - -// ConnectNode connects a node to a peer node -func (c *Client) ConnectNode(nodeID, peerID string) error { - return c.Post(fmt.Sprintf("/nodes/%s/conn/%s", nodeID, peerID), nil, nil) -} - -// DisconnectNode disconnects a node from a peer node -func (c *Client) DisconnectNode(nodeID, peerID string) error { - return c.Delete(fmt.Sprintf("/nodes/%s/conn/%s", nodeID, peerID)) -} - -// RPCClient returns an RPC client connected to a node -func (c *Client) RPCClient(ctx context.Context, nodeID string) (*rpc.Client, error) { - baseURL := strings.Replace(c.URL, "http", "ws", 1) - return rpc.DialWebsocket(ctx, fmt.Sprintf("%s/nodes/%s/rpc", baseURL, nodeID), "") -} - -// Get performs a HTTP GET request decoding the resulting JSON response -// into "out" -func (c *Client) Get(path string, out interface{}) error { - return c.Send(http.MethodGet, path, nil, out) -} - -// Post performs a HTTP POST request sending "in" as the JSON body and -// decoding the resulting JSON response into "out" -func (c *Client) Post(path string, in, out interface{}) error { - return c.Send(http.MethodPost, path, in, out) -} - -// Delete performs a HTTP DELETE request -func (c *Client) Delete(path string) error { - return c.Send(http.MethodDelete, path, nil, nil) -} - -// Send performs a HTTP request, sending "in" as the JSON request body and -// decoding the JSON response into "out" -func (c *Client) Send(method, path string, in, out interface{}) error { - var body []byte - if in != nil { - var err error - body, err = json.Marshal(in) - if err != nil { - return err - } - } - req, err := http.NewRequest(method, c.URL+path, bytes.NewReader(body)) - if err != nil { - return err - } - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - res, err := c.client.Do(req) - if err != nil { - return err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated { - response, _ := io.ReadAll(res.Body) - return fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response) - } - if out != nil { - if err := json.NewDecoder(res.Body).Decode(out); err != nil { - return err - } - } - return nil -} - -// Server is an HTTP server providing an API to manage a simulation network -type Server struct { - router *httprouter.Router - network *Network - mockerStop chan struct{} // when set, stops the current mocker - mockerMtx sync.Mutex // synchronises access to the mockerStop field -} - -// NewServer returns a new simulation API server -func NewServer(network *Network) *Server { - s := &Server{ - router: httprouter.New(), - network: network, - } - - s.OPTIONS("/", s.Options) - s.GET("/", s.GetNetwork) - s.POST("/start", s.StartNetwork) - s.POST("/stop", s.StopNetwork) - s.POST("/mocker/start", s.StartMocker) - s.POST("/mocker/stop", s.StopMocker) - s.GET("/mocker", s.GetMockers) - s.POST("/reset", s.ResetNetwork) - s.GET("/events", s.StreamNetworkEvents) - s.GET("/snapshot", s.CreateSnapshot) - s.POST("/snapshot", s.LoadSnapshot) - s.POST("/nodes", s.CreateNode) - s.GET("/nodes", s.GetNodes) - s.GET("/nodes/:nodeid", s.GetNode) - s.POST("/nodes/:nodeid/start", s.StartNode) - s.POST("/nodes/:nodeid/stop", s.StopNode) - s.POST("/nodes/:nodeid/conn/:peerid", s.ConnectNode) - s.DELETE("/nodes/:nodeid/conn/:peerid", s.DisconnectNode) - s.GET("/nodes/:nodeid/rpc", s.NodeRPC) - - return s -} - -// GetNetwork returns details of the network -func (s *Server) GetNetwork(w http.ResponseWriter, req *http.Request) { - s.JSON(w, http.StatusOK, s.network) -} - -// StartNetwork starts all nodes in the network -func (s *Server) StartNetwork(w http.ResponseWriter, req *http.Request) { - if err := s.network.StartAll(); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusOK) -} - -// StopNetwork stops all nodes in the network -func (s *Server) StopNetwork(w http.ResponseWriter, req *http.Request) { - if err := s.network.StopAll(); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusOK) -} - -// StartMocker starts the mocker node simulation -func (s *Server) StartMocker(w http.ResponseWriter, req *http.Request) { - s.mockerMtx.Lock() - defer s.mockerMtx.Unlock() - if s.mockerStop != nil { - http.Error(w, "mocker already running", http.StatusInternalServerError) - return - } - mockerType := req.FormValue("mocker-type") - mockerFn := LookupMocker(mockerType) - if mockerFn == nil { - http.Error(w, fmt.Sprintf("unknown mocker type %q", html.EscapeString(mockerType)), http.StatusBadRequest) - return - } - nodeCount, err := strconv.Atoi(req.FormValue("node-count")) - if err != nil { - http.Error(w, "invalid node-count provided", http.StatusBadRequest) - return - } - s.mockerStop = make(chan struct{}) - go mockerFn(s.network, s.mockerStop, nodeCount) - - w.WriteHeader(http.StatusOK) -} - -// StopMocker stops the mocker node simulation -func (s *Server) StopMocker(w http.ResponseWriter, req *http.Request) { - s.mockerMtx.Lock() - defer s.mockerMtx.Unlock() - if s.mockerStop == nil { - http.Error(w, "stop channel not initialized", http.StatusInternalServerError) - return - } - close(s.mockerStop) - s.mockerStop = nil - - w.WriteHeader(http.StatusOK) -} - -// GetMockers returns a list of available mockers -func (s *Server) GetMockers(w http.ResponseWriter, req *http.Request) { - list := GetMockerList() - s.JSON(w, http.StatusOK, list) -} - -// ResetNetwork resets all properties of a network to its initial (empty) state -func (s *Server) ResetNetwork(w http.ResponseWriter, req *http.Request) { - s.network.Reset() - - w.WriteHeader(http.StatusOK) -} - -// StreamNetworkEvents streams network events as a server-sent-events stream -func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) { - events := make(chan *Event) - sub := s.network.events.Subscribe(events) - defer sub.Unsubscribe() - - // write writes the given event and data to the stream like: - // - // event: - // data: - // - write := func(event, data string) { - fmt.Fprintf(w, "event: %s\n", event) - fmt.Fprintf(w, "data: %s\n\n", data) - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - } - writeEvent := func(event *Event) error { - data, err := json.Marshal(event) - if err != nil { - return err - } - write("network", string(data)) - return nil - } - writeErr := func(err error) { - write("error", err.Error()) - } - - // check if filtering has been requested - var filters MsgFilters - if filterParam := req.URL.Query().Get("filter"); filterParam != "" { - var err error - filters, err = NewMsgFilters(filterParam) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - } - - w.Header().Set("Content-Type", "text/event-stream; charset=utf-8") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "\n\n") - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - - // optionally send the existing nodes and connections - if req.URL.Query().Get("current") == "true" { - snap, err := s.network.Snapshot() - if err != nil { - writeErr(err) - return - } - for _, node := range snap.Nodes { - event := NewEvent(&node.Node) - if err := writeEvent(event); err != nil { - writeErr(err) - return - } - } - for _, conn := range snap.Conns { - conn := conn - event := NewEvent(&conn) - if err := writeEvent(event); err != nil { - writeErr(err) - return - } - } - } - - clientGone := req.Context().Done() - for { - select { - case event := <-events: - // only send message events which match the filters - if event.Msg != nil && !filters.Match(event.Msg) { - continue - } - if err := writeEvent(event); err != nil { - writeErr(err) - return - } - case <-clientGone: - return - } - } -} - -// NewMsgFilters constructs a collection of message filters from a URL query -// parameter. -// -// The parameter is expected to be a dash-separated list of individual filters, -// each having the format ':', where is the name of a -// protocol and is a comma-separated list of message codes. -// -// A message code of '*' or '-1' is considered a wildcard and matches any code. -func NewMsgFilters(filterParam string) (MsgFilters, error) { - filters := make(MsgFilters) - for _, filter := range strings.Split(filterParam, "-") { - proto, codes, found := strings.Cut(filter, ":") - if !found || proto == "" || codes == "" { - return nil, fmt.Errorf("invalid message filter: %s", filter) - } - - for _, code := range strings.Split(codes, ",") { - if code == "*" || code == "-1" { - filters[MsgFilter{Proto: proto, Code: -1}] = struct{}{} - continue - } - n, err := strconv.ParseUint(code, 10, 64) - if err != nil { - return nil, fmt.Errorf("invalid message code: %s", code) - } - filters[MsgFilter{Proto: proto, Code: int64(n)}] = struct{}{} - } - } - return filters, nil -} - -// MsgFilters is a collection of filters which are used to filter message -// events -type MsgFilters map[MsgFilter]struct{} - -// Match checks if the given message matches any of the filters -func (m MsgFilters) Match(msg *Msg) bool { - // check if there is a wildcard filter for the message's protocol - if _, ok := m[MsgFilter{Proto: msg.Protocol, Code: -1}]; ok { - return true - } - - // check if there is a filter for the message's protocol and code - if _, ok := m[MsgFilter{Proto: msg.Protocol, Code: int64(msg.Code)}]; ok { - return true - } - - return false -} - -// MsgFilter is used to filter message events based on protocol and message -// code -type MsgFilter struct { - // Proto is matched against a message's protocol - Proto string - - // Code is matched against a message's code, with -1 matching all codes - Code int64 -} - -// CreateSnapshot creates a network snapshot -func (s *Server) CreateSnapshot(w http.ResponseWriter, req *http.Request) { - snap, err := s.network.Snapshot() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, snap) -} - -// LoadSnapshot loads a snapshot into the network -func (s *Server) LoadSnapshot(w http.ResponseWriter, req *http.Request) { - snap := &Snapshot{} - if err := json.NewDecoder(req.Body).Decode(snap); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - if err := s.network.Load(snap); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, s.network) -} - -// CreateNode creates a node in the network using the given configuration -func (s *Server) CreateNode(w http.ResponseWriter, req *http.Request) { - config := &adapters.NodeConfig{} - - err := json.NewDecoder(req.Body).Decode(config) - if err != nil && !errors.Is(err, io.EOF) { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - node, err := s.network.NewNodeWithConfig(config) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusCreated, node.NodeInfo()) -} - -// GetNodes returns all nodes which exist in the network -func (s *Server) GetNodes(w http.ResponseWriter, req *http.Request) { - nodes := s.network.GetNodes() - - infos := make([]*p2p.NodeInfo, len(nodes)) - for i, node := range nodes { - infos[i] = node.NodeInfo() - } - - s.JSON(w, http.StatusOK, infos) -} - -// GetNode returns details of a node -func (s *Server) GetNode(w http.ResponseWriter, req *http.Request) { - node := req.Context().Value("node").(*Node) - - s.JSON(w, http.StatusOK, node.NodeInfo()) -} - -// StartNode starts a node -func (s *Server) StartNode(w http.ResponseWriter, req *http.Request) { - node := req.Context().Value("node").(*Node) - - if err := s.network.Start(node.ID()); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, node.NodeInfo()) -} - -// StopNode stops a node -func (s *Server) StopNode(w http.ResponseWriter, req *http.Request) { - node := req.Context().Value("node").(*Node) - - if err := s.network.Stop(node.ID()); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, node.NodeInfo()) -} - -// ConnectNode connects a node to a peer node -func (s *Server) ConnectNode(w http.ResponseWriter, req *http.Request) { - node := req.Context().Value("node").(*Node) - peer := req.Context().Value("peer").(*Node) - - if err := s.network.Connect(node.ID(), peer.ID()); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, node.NodeInfo()) -} - -// DisconnectNode disconnects a node from a peer node -func (s *Server) DisconnectNode(w http.ResponseWriter, req *http.Request) { - node := req.Context().Value("node").(*Node) - peer := req.Context().Value("peer").(*Node) - - if err := s.network.Disconnect(node.ID(), peer.ID()); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - s.JSON(w, http.StatusOK, node.NodeInfo()) -} - -// Options responds to the OPTIONS HTTP method by returning a 200 OK response -// with the "Access-Control-Allow-Headers" header set to "Content-Type" -func (s *Server) Options(w http.ResponseWriter, req *http.Request) { - w.Header().Set("Access-Control-Allow-Headers", "Content-Type") - w.WriteHeader(http.StatusOK) -} - -var wsUpgrade = websocket.Upgrader{ - CheckOrigin: func(*http.Request) bool { return true }, -} - -// NodeRPC forwards RPC requests to a node in the network via a WebSocket -// connection -func (s *Server) NodeRPC(w http.ResponseWriter, req *http.Request) { - conn, err := wsUpgrade.Upgrade(w, req, nil) - if err != nil { - return - } - defer conn.Close() - node := req.Context().Value("node").(*Node) - node.ServeRPC(conn) -} - -// ServeHTTP implements the http.Handler interface by delegating to the -// underlying httprouter.Router -func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s.router.ServeHTTP(w, req) -} - -// GET registers a handler for GET requests to a particular path -func (s *Server) GET(path string, handle http.HandlerFunc) { - s.router.GET(path, s.wrapHandler(handle)) -} - -// POST registers a handler for POST requests to a particular path -func (s *Server) POST(path string, handle http.HandlerFunc) { - s.router.POST(path, s.wrapHandler(handle)) -} - -// DELETE registers a handler for DELETE requests to a particular path -func (s *Server) DELETE(path string, handle http.HandlerFunc) { - s.router.DELETE(path, s.wrapHandler(handle)) -} - -// OPTIONS registers a handler for OPTIONS requests to a particular path -func (s *Server) OPTIONS(path string, handle http.HandlerFunc) { - s.router.OPTIONS("/*path", s.wrapHandler(handle)) -} - -// JSON sends "data" as a JSON HTTP response -func (s *Server) JSON(w http.ResponseWriter, status int, data interface{}) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - json.NewEncoder(w).Encode(data) -} - -// wrapHandler returns an httprouter.Handle which wraps an http.HandlerFunc by -// populating request.Context with any objects from the URL params -func (s *Server) wrapHandler(handler http.HandlerFunc) httprouter.Handle { - return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") - - ctx := req.Context() - - if id := params.ByName("nodeid"); id != "" { - var nodeID enode.ID - var node *Node - if nodeID.UnmarshalText([]byte(id)) == nil { - node = s.network.GetNode(nodeID) - } else { - node = s.network.GetNodeByName(id) - } - if node == nil { - http.NotFound(w, req) - return - } - ctx = context.WithValue(ctx, "node", node) - } - - if id := params.ByName("peerid"); id != "" { - var peerID enode.ID - var peer *Node - if peerID.UnmarshalText([]byte(id)) == nil { - peer = s.network.GetNode(peerID) - } else { - peer = s.network.GetNodeByName(id) - } - if peer == nil { - http.NotFound(w, req) - return - } - ctx = context.WithValue(ctx, "peer", peer) - } - - handler(w, req.WithContext(ctx)) - } -} diff --git a/p2p/simulations/http_test.go b/p2p/simulations/http_test.go deleted file mode 100644 index c53a49797b..0000000000 --- a/p2p/simulations/http_test.go +++ /dev/null @@ -1,871 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "context" - "flag" - "fmt" - "math/rand" - "net/http/httptest" - "os" - "reflect" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" - "github.com/ethereum/go-ethereum/rpc" - "github.com/mattn/go-colorable" - "golang.org/x/exp/slog" -) - -func TestMain(m *testing.M) { - loglevel := flag.Int("loglevel", 2, "verbosity of logs") - - flag.Parse() - log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.Level(*loglevel), true))) - os.Exit(m.Run()) -} - -// testService implements the node.Service interface and provides protocols -// and APIs which are useful for testing nodes in a simulation network -type testService struct { - id enode.ID - - // peerCount is incremented once a peer handshake has been performed - peerCount int64 - - peers map[enode.ID]*testPeer - peersMtx sync.Mutex - - // state stores []byte which is used to test creating and loading - // snapshots - state atomic.Value -} - -func newTestService(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - svc := &testService{ - id: ctx.Config.ID, - peers: make(map[enode.ID]*testPeer), - } - svc.state.Store(ctx.Snapshot) - - stack.RegisterProtocols(svc.Protocols()) - stack.RegisterAPIs(svc.APIs()) - return svc, nil -} - -type testPeer struct { - testReady chan struct{} - dumReady chan struct{} -} - -func (t *testService) peer(id enode.ID) *testPeer { - t.peersMtx.Lock() - defer t.peersMtx.Unlock() - if peer, ok := t.peers[id]; ok { - return peer - } - peer := &testPeer{ - testReady: make(chan struct{}), - dumReady: make(chan struct{}), - } - t.peers[id] = peer - return peer -} - -func (t *testService) Protocols() []p2p.Protocol { - return []p2p.Protocol{ - { - Name: "test", - Version: 1, - Length: 3, - Run: t.RunTest, - }, - { - Name: "dum", - Version: 1, - Length: 1, - Run: t.RunDum, - }, - { - Name: "prb", - Version: 1, - Length: 1, - Run: t.RunPrb, - }, - } -} - -func (t *testService) APIs() []rpc.API { - return []rpc.API{{ - Namespace: "test", - Version: "1.0", - Service: &TestAPI{ - state: &t.state, - peerCount: &t.peerCount, - }, - }} -} - -func (t *testService) Start() error { - return nil -} - -func (t *testService) Stop() error { - return nil -} - -// handshake performs a peer handshake by sending and expecting an empty -// message with the given code -func (t *testService) handshake(rw p2p.MsgReadWriter, code uint64) error { - errc := make(chan error, 2) - go func() { errc <- p2p.SendItems(rw, code) }() - go func() { errc <- p2p.ExpectMsg(rw, code, struct{}{}) }() - for i := 0; i < 2; i++ { - if err := <-errc; err != nil { - return err - } - } - return nil -} - -func (t *testService) RunTest(p *p2p.Peer, rw p2p.MsgReadWriter) error { - peer := t.peer(p.ID()) - - // perform three handshakes with three different message codes, - // used to test message sending and filtering - if err := t.handshake(rw, 2); err != nil { - return err - } - if err := t.handshake(rw, 1); err != nil { - return err - } - if err := t.handshake(rw, 0); err != nil { - return err - } - - // close the testReady channel so that other protocols can run - close(peer.testReady) - - // track the peer - atomic.AddInt64(&t.peerCount, 1) - defer atomic.AddInt64(&t.peerCount, -1) - - // block until the peer is dropped - for { - _, err := rw.ReadMsg() - if err != nil { - return err - } - } -} - -func (t *testService) RunDum(p *p2p.Peer, rw p2p.MsgReadWriter) error { - peer := t.peer(p.ID()) - - // wait for the test protocol to perform its handshake - <-peer.testReady - - // perform a handshake - if err := t.handshake(rw, 0); err != nil { - return err - } - - // close the dumReady channel so that other protocols can run - close(peer.dumReady) - - // block until the peer is dropped - for { - _, err := rw.ReadMsg() - if err != nil { - return err - } - } -} -func (t *testService) RunPrb(p *p2p.Peer, rw p2p.MsgReadWriter) error { - peer := t.peer(p.ID()) - - // wait for the dum protocol to perform its handshake - <-peer.dumReady - - // perform a handshake - if err := t.handshake(rw, 0); err != nil { - return err - } - - // block until the peer is dropped - for { - _, err := rw.ReadMsg() - if err != nil { - return err - } - } -} - -func (t *testService) Snapshot() ([]byte, error) { - return t.state.Load().([]byte), nil -} - -// TestAPI provides a test API to: -// * get the peer count -// * get and set an arbitrary state byte slice -// * get and increment a counter -// * subscribe to counter increment events -type TestAPI struct { - state *atomic.Value - peerCount *int64 - counter int64 - feed event.Feed -} - -func (t *TestAPI) PeerCount() int64 { - return atomic.LoadInt64(t.peerCount) -} - -func (t *TestAPI) Get() int64 { - return atomic.LoadInt64(&t.counter) -} - -func (t *TestAPI) Add(delta int64) { - atomic.AddInt64(&t.counter, delta) - t.feed.Send(delta) -} - -func (t *TestAPI) GetState() []byte { - return t.state.Load().([]byte) -} - -func (t *TestAPI) SetState(state []byte) { - t.state.Store(state) -} - -func (t *TestAPI) Events(ctx context.Context) (*rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return nil, rpc.ErrNotificationsUnsupported - } - - rpcSub := notifier.CreateSubscription() - - go func() { - events := make(chan int64) - sub := t.feed.Subscribe(events) - defer sub.Unsubscribe() - - for { - select { - case event := <-events: - notifier.Notify(rpcSub.ID, event) - case <-sub.Err(): - return - case <-rpcSub.Err(): - return - case <-notifier.Closed(): - return - } - } - }() - - return rpcSub, nil -} - -var testServices = adapters.LifecycleConstructors{ - "test": newTestService, -} - -func testHTTPServer(t *testing.T) (*Network, *httptest.Server) { - t.Helper() - adapter := adapters.NewSimAdapter(testServices) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - return network, httptest.NewServer(NewServer(network)) -} - -// TestHTTPNetwork tests interacting with a simulation network using the HTTP -// API -func TestHTTPNetwork(t *testing.T) { - // start the server - network, s := testHTTPServer(t) - defer s.Close() - - // subscribe to events so we can check them later - client := NewClient(s.URL) - events := make(chan *Event, 100) - var opts SubscribeOpts - sub, err := client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - - // check we can retrieve details about the network - gotNetwork, err := client.GetNetwork() - if err != nil { - t.Fatalf("error getting network: %s", err) - } - if gotNetwork.ID != network.ID { - t.Fatalf("expected network to have ID %q, got %q", network.ID, gotNetwork.ID) - } - - // start a simulation network - nodeIDs := startTestNetwork(t, client) - - // check we got all the events - x := &expectEvents{t, events, sub} - x.expect( - x.nodeEvent(nodeIDs[0], false), - x.nodeEvent(nodeIDs[1], false), - x.nodeEvent(nodeIDs[0], true), - x.nodeEvent(nodeIDs[1], true), - x.connEvent(nodeIDs[0], nodeIDs[1], false), - x.connEvent(nodeIDs[0], nodeIDs[1], true), - ) - - // reconnect the stream and check we get the current nodes and conns - events = make(chan *Event, 100) - opts.Current = true - sub, err = client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - x = &expectEvents{t, events, sub} - x.expect( - x.nodeEvent(nodeIDs[0], true), - x.nodeEvent(nodeIDs[1], true), - x.connEvent(nodeIDs[0], nodeIDs[1], true), - ) -} - -func startTestNetwork(t *testing.T, client *Client) []string { - // create two nodes - nodeCount := 2 - nodeIDs := make([]string, nodeCount) - for i := 0; i < nodeCount; i++ { - config := adapters.RandomNodeConfig() - node, err := client.CreateNode(config) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - nodeIDs[i] = node.ID - } - - // check both nodes exist - nodes, err := client.GetNodes() - if err != nil { - t.Fatalf("error getting nodes: %s", err) - } - if len(nodes) != nodeCount { - t.Fatalf("expected %d nodes, got %d", nodeCount, len(nodes)) - } - for i, nodeID := range nodeIDs { - if nodes[i].ID != nodeID { - t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, nodes[i].ID) - } - node, err := client.GetNode(nodeID) - if err != nil { - t.Fatalf("error getting node %d: %s", i, err) - } - if node.ID != nodeID { - t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, node.ID) - } - } - - // start both nodes - for _, nodeID := range nodeIDs { - if err := client.StartNode(nodeID); err != nil { - t.Fatalf("error starting node %q: %s", nodeID, err) - } - } - - // connect the nodes - for i := 0; i < nodeCount-1; i++ { - peerId := i + 1 - if i == nodeCount-1 { - peerId = 0 - } - if err := client.ConnectNode(nodeIDs[i], nodeIDs[peerId]); err != nil { - t.Fatalf("error connecting nodes: %s", err) - } - } - - return nodeIDs -} - -type expectEvents struct { - *testing.T - - events chan *Event - sub event.Subscription -} - -func (t *expectEvents) nodeEvent(id string, up bool) *Event { - config := &adapters.NodeConfig{ID: enode.HexID(id)} - return &Event{Type: EventTypeNode, Node: newNode(nil, config, up)} -} - -func (t *expectEvents) connEvent(one, other string, up bool) *Event { - return &Event{ - Type: EventTypeConn, - Conn: &Conn{ - One: enode.HexID(one), - Other: enode.HexID(other), - Up: up, - }, - } -} - -func (t *expectEvents) expectMsgs(expected map[MsgFilter]int) { - actual := make(map[MsgFilter]int) - timeout := time.After(10 * time.Second) -loop: - for { - select { - case event := <-t.events: - t.Logf("received %s event: %v", event.Type, event) - - if event.Type != EventTypeMsg || event.Msg.Received { - continue loop - } - if event.Msg == nil { - t.Fatal("expected event.Msg to be set") - } - filter := MsgFilter{ - Proto: event.Msg.Protocol, - Code: int64(event.Msg.Code), - } - actual[filter]++ - if actual[filter] > expected[filter] { - t.Fatalf("received too many msgs for filter: %v", filter) - } - if reflect.DeepEqual(actual, expected) { - return - } - - case err := <-t.sub.Err(): - t.Fatalf("network stream closed unexpectedly: %s", err) - - case <-timeout: - t.Fatal("timed out waiting for expected events") - } - } -} - -func (t *expectEvents) expect(events ...*Event) { - t.Helper() - timeout := time.After(10 * time.Second) - i := 0 - for { - select { - case event := <-t.events: - t.Logf("received %s event: %v", event.Type, event) - - expected := events[i] - if event.Type != expected.Type { - t.Fatalf("expected event %d to have type %q, got %q", i, expected.Type, event.Type) - } - - switch expected.Type { - case EventTypeNode: - if event.Node == nil { - t.Fatal("expected event.Node to be set") - } - if event.Node.ID() != expected.Node.ID() { - t.Fatalf("expected node event %d to have id %q, got %q", i, expected.Node.ID().TerminalString(), event.Node.ID().TerminalString()) - } - if event.Node.Up() != expected.Node.Up() { - t.Fatalf("expected node event %d to have up=%t, got up=%t", i, expected.Node.Up(), event.Node.Up()) - } - - case EventTypeConn: - if event.Conn == nil { - t.Fatal("expected event.Conn to be set") - } - if event.Conn.One != expected.Conn.One { - t.Fatalf("expected conn event %d to have one=%q, got one=%q", i, expected.Conn.One.TerminalString(), event.Conn.One.TerminalString()) - } - if event.Conn.Other != expected.Conn.Other { - t.Fatalf("expected conn event %d to have other=%q, got other=%q", i, expected.Conn.Other.TerminalString(), event.Conn.Other.TerminalString()) - } - if event.Conn.Up != expected.Conn.Up { - t.Fatalf("expected conn event %d to have up=%t, got up=%t", i, expected.Conn.Up, event.Conn.Up) - } - } - - i++ - if i == len(events) { - return - } - - case err := <-t.sub.Err(): - t.Fatalf("network stream closed unexpectedly: %s", err) - - case <-timeout: - t.Fatal("timed out waiting for expected events") - } - } -} - -// TestHTTPNodeRPC tests calling RPC methods on nodes via the HTTP API -func TestHTTPNodeRPC(t *testing.T) { - // start the server - _, s := testHTTPServer(t) - defer s.Close() - - // start a node in the network - client := NewClient(s.URL) - - config := adapters.RandomNodeConfig() - node, err := client.CreateNode(config) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - if err := client.StartNode(node.ID); err != nil { - t.Fatalf("error starting node: %s", err) - } - - // create two RPC clients - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - rpcClient1, err := client.RPCClient(ctx, node.ID) - if err != nil { - t.Fatalf("error getting node RPC client: %s", err) - } - rpcClient2, err := client.RPCClient(ctx, node.ID) - if err != nil { - t.Fatalf("error getting node RPC client: %s", err) - } - - // subscribe to events using client 1 - events := make(chan int64, 1) - sub, err := rpcClient1.Subscribe(ctx, "test", events, "events") - if err != nil { - t.Fatalf("error subscribing to events: %s", err) - } - defer sub.Unsubscribe() - - // call some RPC methods using client 2 - if err := rpcClient2.CallContext(ctx, nil, "test_add", 10); err != nil { - t.Fatalf("error calling RPC method: %s", err) - } - var result int64 - if err := rpcClient2.CallContext(ctx, &result, "test_get"); err != nil { - t.Fatalf("error calling RPC method: %s", err) - } - if result != 10 { - t.Fatalf("expected result to be 10, got %d", result) - } - - // check we got an event from client 1 - select { - case event := <-events: - if event != 10 { - t.Fatalf("expected event to be 10, got %d", event) - } - case <-ctx.Done(): - t.Fatal(ctx.Err()) - } -} - -// TestHTTPSnapshot tests creating and loading network snapshots -func TestHTTPSnapshot(t *testing.T) { - // start the server - network, s := testHTTPServer(t) - defer s.Close() - - var eventsDone = make(chan struct{}, 1) - count := 1 - eventsDoneChan := make(chan *Event) - eventSub := network.Events().Subscribe(eventsDoneChan) - go func() { - defer eventSub.Unsubscribe() - for event := range eventsDoneChan { - if event.Type == EventTypeConn && !event.Control { - count-- - if count == 0 { - eventsDone <- struct{}{} - return - } - } - } - }() - - // create a two-node network - client := NewClient(s.URL) - nodeCount := 2 - nodes := make([]*p2p.NodeInfo, nodeCount) - for i := 0; i < nodeCount; i++ { - config := adapters.RandomNodeConfig() - node, err := client.CreateNode(config) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - if err := client.StartNode(node.ID); err != nil { - t.Fatalf("error starting node: %s", err) - } - nodes[i] = node - } - if err := client.ConnectNode(nodes[0].ID, nodes[1].ID); err != nil { - t.Fatalf("error connecting nodes: %s", err) - } - - // store some state in the test services - states := make([]string, nodeCount) - for i, node := range nodes { - rpc, err := client.RPCClient(context.Background(), node.ID) - if err != nil { - t.Fatalf("error getting RPC client: %s", err) - } - defer rpc.Close() - state := fmt.Sprintf("%x", rand.Int()) - if err := rpc.Call(nil, "test_setState", []byte(state)); err != nil { - t.Fatalf("error setting service state: %s", err) - } - states[i] = state - } - <-eventsDone - // create a snapshot - snap, err := client.CreateSnapshot() - if err != nil { - t.Fatalf("error creating snapshot: %s", err) - } - for i, state := range states { - gotState := snap.Nodes[i].Snapshots["test"] - if string(gotState) != state { - t.Fatalf("expected snapshot state %q, got %q", state, gotState) - } - } - - // create another network - network2, s := testHTTPServer(t) - defer s.Close() - client = NewClient(s.URL) - count = 1 - eventSub = network2.Events().Subscribe(eventsDoneChan) - go func() { - defer eventSub.Unsubscribe() - for event := range eventsDoneChan { - if event.Type == EventTypeConn && !event.Control { - count-- - if count == 0 { - eventsDone <- struct{}{} - return - } - } - } - }() - - // subscribe to events so we can check them later - events := make(chan *Event, 100) - var opts SubscribeOpts - sub, err := client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - - // load the snapshot - if err := client.LoadSnapshot(snap); err != nil { - t.Fatalf("error loading snapshot: %s", err) - } - <-eventsDone - - // check the nodes and connection exists - net, err := client.GetNetwork() - if err != nil { - t.Fatalf("error getting network: %s", err) - } - if len(net.Nodes) != nodeCount { - t.Fatalf("expected network to have %d nodes, got %d", nodeCount, len(net.Nodes)) - } - for i, node := range nodes { - id := net.Nodes[i].ID().String() - if id != node.ID { - t.Fatalf("expected node %d to have ID %s, got %s", i, node.ID, id) - } - } - if len(net.Conns) != 1 { - t.Fatalf("expected network to have 1 connection, got %d", len(net.Conns)) - } - conn := net.Conns[0] - if conn.One.String() != nodes[0].ID { - t.Fatalf("expected connection to have one=%q, got one=%q", nodes[0].ID, conn.One) - } - if conn.Other.String() != nodes[1].ID { - t.Fatalf("expected connection to have other=%q, got other=%q", nodes[1].ID, conn.Other) - } - if !conn.Up { - t.Fatal("should be up") - } - - // check the node states were restored - for i, node := range nodes { - rpc, err := client.RPCClient(context.Background(), node.ID) - if err != nil { - t.Fatalf("error getting RPC client: %s", err) - } - defer rpc.Close() - var state []byte - if err := rpc.Call(&state, "test_getState"); err != nil { - t.Fatalf("error getting service state: %s", err) - } - if string(state) != states[i] { - t.Fatalf("expected snapshot state %q, got %q", states[i], state) - } - } - - // check we got all the events - x := &expectEvents{t, events, sub} - x.expect( - x.nodeEvent(nodes[0].ID, false), - x.nodeEvent(nodes[0].ID, true), - x.nodeEvent(nodes[1].ID, false), - x.nodeEvent(nodes[1].ID, true), - x.connEvent(nodes[0].ID, nodes[1].ID, false), - x.connEvent(nodes[0].ID, nodes[1].ID, true), - ) -} - -// TestMsgFilterPassMultiple tests streaming message events using a filter -// with multiple protocols -func TestMsgFilterPassMultiple(t *testing.T) { - // start the server - _, s := testHTTPServer(t) - defer s.Close() - - // subscribe to events with a message filter - client := NewClient(s.URL) - events := make(chan *Event, 10) - opts := SubscribeOpts{ - Filter: "prb:0-test:0", - } - sub, err := client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - - // start a simulation network - startTestNetwork(t, client) - - // check we got the expected events - x := &expectEvents{t, events, sub} - x.expectMsgs(map[MsgFilter]int{ - {"test", 0}: 2, - {"prb", 0}: 2, - }) -} - -// TestMsgFilterPassWildcard tests streaming message events using a filter -// with a code wildcard -func TestMsgFilterPassWildcard(t *testing.T) { - // start the server - _, s := testHTTPServer(t) - defer s.Close() - - // subscribe to events with a message filter - client := NewClient(s.URL) - events := make(chan *Event, 10) - opts := SubscribeOpts{ - Filter: "prb:0,2-test:*", - } - sub, err := client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - - // start a simulation network - startTestNetwork(t, client) - - // check we got the expected events - x := &expectEvents{t, events, sub} - x.expectMsgs(map[MsgFilter]int{ - {"test", 2}: 2, - {"test", 1}: 2, - {"test", 0}: 2, - {"prb", 0}: 2, - }) -} - -// TestMsgFilterPassSingle tests streaming message events using a filter -// with a single protocol and code -func TestMsgFilterPassSingle(t *testing.T) { - // start the server - _, s := testHTTPServer(t) - defer s.Close() - - // subscribe to events with a message filter - client := NewClient(s.URL) - events := make(chan *Event, 10) - opts := SubscribeOpts{ - Filter: "dum:0", - } - sub, err := client.SubscribeNetwork(events, opts) - if err != nil { - t.Fatalf("error subscribing to network events: %s", err) - } - defer sub.Unsubscribe() - - // start a simulation network - startTestNetwork(t, client) - - // check we got the expected events - x := &expectEvents{t, events, sub} - x.expectMsgs(map[MsgFilter]int{ - {"dum", 0}: 2, - }) -} - -// TestMsgFilterPassSingle tests streaming message events using an invalid -// filter -func TestMsgFilterFailBadParams(t *testing.T) { - // start the server - _, s := testHTTPServer(t) - defer s.Close() - - client := NewClient(s.URL) - events := make(chan *Event, 10) - opts := SubscribeOpts{ - Filter: "foo:", - } - _, err := client.SubscribeNetwork(events, opts) - if err == nil { - t.Fatalf("expected event subscription to fail but succeeded!") - } - - opts.Filter = "bzz:aa" - _, err = client.SubscribeNetwork(events, opts) - if err == nil { - t.Fatalf("expected event subscription to fail but succeeded!") - } - - opts.Filter = "invalid" - _, err = client.SubscribeNetwork(events, opts) - if err == nil { - t.Fatalf("expected event subscription to fail but succeeded!") - } -} diff --git a/p2p/simulations/mocker.go b/p2p/simulations/mocker.go deleted file mode 100644 index 0dc04e65f9..0000000000 --- a/p2p/simulations/mocker.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package simulations simulates p2p networks. -// A mocker simulates starting and stopping real nodes in a network. -package simulations - -import ( - "fmt" - "math/rand" - "sync" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" -) - -// a map of mocker names to its function -var mockerList = map[string]func(net *Network, quit chan struct{}, nodeCount int){ - "startStop": startStop, - "probabilistic": probabilistic, - "boot": boot, -} - -// LookupMocker looks a mocker by its name, returns the mockerFn -func LookupMocker(mockerType string) func(net *Network, quit chan struct{}, nodeCount int) { - return mockerList[mockerType] -} - -// GetMockerList returns a list of mockers (keys of the map) -// Useful for frontend to build available mocker selection -func GetMockerList() []string { - list := make([]string, 0, len(mockerList)) - for k := range mockerList { - list = append(list, k) - } - return list -} - -// The boot mockerFn only connects the node in a ring and doesn't do anything else -func boot(net *Network, quit chan struct{}, nodeCount int) { - _, err := connectNodesInRing(net, nodeCount) - if err != nil { - panic("Could not startup node network for mocker") - } -} - -// The startStop mockerFn stops and starts nodes in a defined period (ticker) -func startStop(net *Network, quit chan struct{}, nodeCount int) { - nodes, err := connectNodesInRing(net, nodeCount) - if err != nil { - panic("Could not startup node network for mocker") - } - tick := time.NewTicker(10 * time.Second) - defer tick.Stop() - for { - select { - case <-quit: - log.Info("Terminating simulation loop") - return - case <-tick.C: - id := nodes[rand.Intn(len(nodes))] - log.Info("stopping node", "id", id) - if err := net.Stop(id); err != nil { - log.Error("error stopping node", "id", id, "err", err) - return - } - - select { - case <-quit: - log.Info("Terminating simulation loop") - return - case <-time.After(3 * time.Second): - } - - log.Debug("starting node", "id", id) - if err := net.Start(id); err != nil { - log.Error("error starting node", "id", id, "err", err) - return - } - } - } -} - -// The probabilistic mocker func has a more probabilistic pattern -// (the implementation could probably be improved): -// nodes are connected in a ring, then a varying number of random nodes is selected, -// mocker then stops and starts them in random intervals, and continues the loop -func probabilistic(net *Network, quit chan struct{}, nodeCount int) { - nodes, err := connectNodesInRing(net, nodeCount) - if err != nil { - select { - case <-quit: - //error may be due to abortion of mocking; so the quit channel is closed - return - default: - panic("Could not startup node network for mocker") - } - } - for { - select { - case <-quit: - log.Info("Terminating simulation loop") - return - default: - } - var lowid, highid int - var wg sync.WaitGroup - randWait := time.Duration(rand.Intn(5000)+1000) * time.Millisecond - rand1 := rand.Intn(nodeCount - 1) - rand2 := rand.Intn(nodeCount - 1) - if rand1 <= rand2 { - lowid = rand1 - highid = rand2 - } else if rand1 > rand2 { - highid = rand1 - lowid = rand2 - } - var steps = highid - lowid - wg.Add(steps) - for i := lowid; i < highid; i++ { - select { - case <-quit: - log.Info("Terminating simulation loop") - return - case <-time.After(randWait): - } - log.Debug(fmt.Sprintf("node %v shutting down", nodes[i])) - err := net.Stop(nodes[i]) - if err != nil { - log.Error("Error stopping node", "node", nodes[i]) - wg.Done() - continue - } - go func(id enode.ID) { - time.Sleep(randWait) - err := net.Start(id) - if err != nil { - log.Error("Error starting node", "node", id) - } - wg.Done() - }(nodes[i]) - } - wg.Wait() - } -} - -// connect nodeCount number of nodes in a ring -func connectNodesInRing(net *Network, nodeCount int) ([]enode.ID, error) { - ids := make([]enode.ID, nodeCount) - for i := 0; i < nodeCount; i++ { - conf := adapters.RandomNodeConfig() - node, err := net.NewNodeWithConfig(conf) - if err != nil { - log.Error("Error creating a node!", "err", err) - return nil, err - } - ids[i] = node.ID() - } - - for _, id := range ids { - if err := net.Start(id); err != nil { - log.Error("Error starting a node!", "err", err) - return nil, err - } - log.Debug(fmt.Sprintf("node %v starting up", id)) - } - for i, id := range ids { - peerID := ids[(i+1)%len(ids)] - if err := net.Connect(id, peerID); err != nil { - log.Error("Error connecting a node to a peer!", "err", err) - return nil, err - } - } - - return ids, nil -} diff --git a/p2p/simulations/mocker_test.go b/p2p/simulations/mocker_test.go deleted file mode 100644 index 0112ee5cfd..0000000000 --- a/p2p/simulations/mocker_test.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package simulations simulates p2p networks. -// A mocker simulates starting and stopping real nodes in a network. -package simulations - -import ( - "encoding/json" - "net/http" - "net/url" - "strconv" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/p2p/enode" -) - -func TestMocker(t *testing.T) { - //start the simulation HTTP server - _, s := testHTTPServer(t) - defer s.Close() - - //create a client - client := NewClient(s.URL) - - //start the network - err := client.StartNetwork() - if err != nil { - t.Fatalf("Could not start test network: %s", err) - } - //stop the network to terminate - defer func() { - err = client.StopNetwork() - if err != nil { - t.Fatalf("Could not stop test network: %s", err) - } - }() - - //get the list of available mocker types - resp, err := http.Get(s.URL + "/mocker") - if err != nil { - t.Fatalf("Could not get mocker list: %s", err) - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - t.Fatalf("Invalid Status Code received, expected 200, got %d", resp.StatusCode) - } - - //check the list is at least 1 in size - var mockerlist []string - err = json.NewDecoder(resp.Body).Decode(&mockerlist) - if err != nil { - t.Fatalf("Error decoding JSON mockerlist: %s", err) - } - - if len(mockerlist) < 1 { - t.Fatalf("No mockers available") - } - - nodeCount := 10 - var wg sync.WaitGroup - - events := make(chan *Event, 10) - var opts SubscribeOpts - sub, err := client.SubscribeNetwork(events, opts) - defer sub.Unsubscribe() - - // wait until all nodes are started and connected - // store every node up event in a map (value is irrelevant, mimic Set datatype) - nodemap := make(map[enode.ID]bool) - nodesComplete := false - connCount := 0 - wg.Add(1) - go func() { - defer wg.Done() - - for connCount < (nodeCount-1)*2 { - select { - case event := <-events: - if isNodeUp(event) { - //add the correspondent node ID to the map - nodemap[event.Node.Config.ID] = true - //this means all nodes got a nodeUp event, so we can continue the test - if len(nodemap) == nodeCount { - nodesComplete = true - } - } else if event.Conn != nil && nodesComplete { - connCount += 1 - } - case <-time.After(30 * time.Second): - t.Errorf("Timeout waiting for nodes being started up!") - return - } - } - }() - - //take the last element of the mockerlist as the default mocker-type to ensure one is enabled - mockertype := mockerlist[len(mockerlist)-1] - //still, use hardcoded "probabilistic" one if available ;) - for _, m := range mockerlist { - if m == "probabilistic" { - mockertype = m - break - } - } - //start the mocker with nodeCount number of nodes - resp, err = http.PostForm(s.URL+"/mocker/start", url.Values{"mocker-type": {mockertype}, "node-count": {strconv.Itoa(nodeCount)}}) - if err != nil { - t.Fatalf("Could not start mocker: %s", err) - } - resp.Body.Close() - if resp.StatusCode != 200 { - t.Fatalf("Invalid Status Code received for starting mocker, expected 200, got %d", resp.StatusCode) - } - - wg.Wait() - - //check there are nodeCount number of nodes in the network - nodesInfo, err := client.GetNodes() - if err != nil { - t.Fatalf("Could not get nodes list: %s", err) - } - - if len(nodesInfo) != nodeCount { - t.Fatalf("Expected %d number of nodes, got: %d", nodeCount, len(nodesInfo)) - } - - //stop the mocker - resp, err = http.Post(s.URL+"/mocker/stop", "", nil) - if err != nil { - t.Fatalf("Could not stop mocker: %s", err) - } - resp.Body.Close() - if resp.StatusCode != 200 { - t.Fatalf("Invalid Status Code received for stopping mocker, expected 200, got %d", resp.StatusCode) - } - - //reset the network - resp, err = http.Post(s.URL+"/reset", "", nil) - if err != nil { - t.Fatalf("Could not reset network: %s", err) - } - resp.Body.Close() - - //now the number of nodes in the network should be zero - nodesInfo, err = client.GetNodes() - if err != nil { - t.Fatalf("Could not get nodes list: %s", err) - } - - if len(nodesInfo) != 0 { - t.Fatalf("Expected empty list of nodes, got: %d", len(nodesInfo)) - } -} - -func isNodeUp(event *Event) bool { - return event.Node != nil && event.Node.Up() -} diff --git a/p2p/simulations/network.go b/p2p/simulations/network.go deleted file mode 100644 index 4735e5cfa6..0000000000 --- a/p2p/simulations/network.go +++ /dev/null @@ -1,1090 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "math/rand" - "sync" - "time" - - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" -) - -var DialBanTimeout = 200 * time.Millisecond - -// NetworkConfig defines configuration options for starting a Network -type NetworkConfig struct { - ID string `json:"id"` - DefaultService string `json:"default_service,omitempty"` -} - -// Network models a p2p simulation network which consists of a collection of -// simulated nodes and the connections which exist between them. -// -// The Network has a single NodeAdapter which is responsible for actually -// starting nodes and connecting them together. -// -// The Network emits events when nodes are started and stopped, when they are -// connected and disconnected, and also when messages are sent between nodes. -type Network struct { - NetworkConfig - - Nodes []*Node `json:"nodes"` - nodeMap map[enode.ID]int - - // Maps a node property string to node indexes of all nodes that hold this property - propertyMap map[string][]int - - Conns []*Conn `json:"conns"` - connMap map[string]int - - nodeAdapter adapters.NodeAdapter - events event.Feed - lock sync.RWMutex - quitc chan struct{} -} - -// NewNetwork returns a Network which uses the given NodeAdapter and NetworkConfig -func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network { - return &Network{ - NetworkConfig: *conf, - nodeAdapter: nodeAdapter, - nodeMap: make(map[enode.ID]int), - propertyMap: make(map[string][]int), - connMap: make(map[string]int), - quitc: make(chan struct{}), - } -} - -// Events returns the output event feed of the Network. -func (net *Network) Events() *event.Feed { - return &net.events -} - -// NewNodeWithConfig adds a new node to the network with the given config, -// returning an error if a node with the same ID or name already exists -func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) { - net.lock.Lock() - defer net.lock.Unlock() - - if conf.Reachable == nil { - conf.Reachable = func(otherID enode.ID) bool { - _, err := net.InitConn(conf.ID, otherID) - if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 { - return false - } - return true - } - } - - // check the node doesn't already exist - if node := net.getNode(conf.ID); node != nil { - return nil, fmt.Errorf("node with ID %q already exists", conf.ID) - } - if node := net.getNodeByName(conf.Name); node != nil { - return nil, fmt.Errorf("node with name %q already exists", conf.Name) - } - - // if no services are configured, use the default service - if len(conf.Lifecycles) == 0 { - conf.Lifecycles = []string{net.DefaultService} - } - - // use the NodeAdapter to create the node - adapterNode, err := net.nodeAdapter.NewNode(conf) - if err != nil { - return nil, err - } - node := newNode(adapterNode, conf, false) - log.Trace("Node created", "id", conf.ID) - - nodeIndex := len(net.Nodes) - net.nodeMap[conf.ID] = nodeIndex - net.Nodes = append(net.Nodes, node) - - // Register any node properties with the network-level propertyMap - for _, property := range conf.Properties { - net.propertyMap[property] = append(net.propertyMap[property], nodeIndex) - } - - // emit a "control" event - net.events.Send(ControlEvent(node)) - - return node, nil -} - -// Config returns the network configuration -func (net *Network) Config() *NetworkConfig { - return &net.NetworkConfig -} - -// StartAll starts all nodes in the network -func (net *Network) StartAll() error { - for _, node := range net.Nodes { - if node.Up() { - continue - } - if err := net.Start(node.ID()); err != nil { - return err - } - } - return nil -} - -// StopAll stops all nodes in the network -func (net *Network) StopAll() error { - for _, node := range net.Nodes { - if !node.Up() { - continue - } - if err := net.Stop(node.ID()); err != nil { - return err - } - } - return nil -} - -// Start starts the node with the given ID -func (net *Network) Start(id enode.ID) error { - return net.startWithSnapshots(id, nil) -} - -// startWithSnapshots starts the node with the given ID using the give -// snapshots -func (net *Network) startWithSnapshots(id enode.ID, snapshots map[string][]byte) error { - net.lock.Lock() - defer net.lock.Unlock() - - node := net.getNode(id) - if node == nil { - return fmt.Errorf("node %v does not exist", id) - } - if node.Up() { - return fmt.Errorf("node %v already up", id) - } - log.Trace("Starting node", "id", id, "adapter", net.nodeAdapter.Name()) - if err := node.Start(snapshots); err != nil { - log.Warn("Node startup failed", "id", id, "err", err) - return err - } - node.SetUp(true) - log.Info("Started node", "id", id) - ev := NewEvent(node) - net.events.Send(ev) - - // subscribe to peer events - client, err := node.Client() - if err != nil { - return fmt.Errorf("error getting rpc client for node %v: %s", id, err) - } - events := make(chan *p2p.PeerEvent) - sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") - if err != nil { - return fmt.Errorf("error getting peer events for node %v: %s", id, err) - } - go net.watchPeerEvents(id, events, sub) - return nil -} - -// watchPeerEvents reads peer events from the given channel and emits -// corresponding network events -func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub event.Subscription) { - defer func() { - sub.Unsubscribe() - - // assume the node is now down - net.lock.Lock() - defer net.lock.Unlock() - - node := net.getNode(id) - if node == nil { - return - } - node.SetUp(false) - ev := NewEvent(node) - net.events.Send(ev) - }() - for { - select { - case event, ok := <-events: - if !ok { - return - } - peer := event.Peer - switch event.Type { - case p2p.PeerEventTypeAdd: - net.DidConnect(id, peer) - - case p2p.PeerEventTypeDrop: - net.DidDisconnect(id, peer) - - case p2p.PeerEventTypeMsgSend: - net.DidSend(id, peer, event.Protocol, *event.MsgCode) - - case p2p.PeerEventTypeMsgRecv: - net.DidReceive(peer, id, event.Protocol, *event.MsgCode) - } - - case err := <-sub.Err(): - if err != nil { - log.Error("Error in peer event subscription", "id", id, "err", err) - } - return - } - } -} - -// Stop stops the node with the given ID -func (net *Network) Stop(id enode.ID) error { - // IMPORTANT: node.Stop() must NOT be called under net.lock as - // node.Reachable() closure has a reference to the network and - // calls net.InitConn() what also locks the network. => DEADLOCK - // That holds until the following ticket is not resolved: - - var err error - - node, err := func() (*Node, error) { - net.lock.Lock() - defer net.lock.Unlock() - - node := net.getNode(id) - if node == nil { - return nil, fmt.Errorf("node %v does not exist", id) - } - if !node.Up() { - return nil, fmt.Errorf("node %v already down", id) - } - node.SetUp(false) - return node, nil - }() - if err != nil { - return err - } - - err = node.Stop() // must be called without net.lock - - net.lock.Lock() - defer net.lock.Unlock() - - if err != nil { - node.SetUp(true) - return err - } - log.Info("Stopped node", "id", id, "err", err) - ev := ControlEvent(node) - net.events.Send(ev) - return nil -} - -// Connect connects two nodes together by calling the "admin_addPeer" RPC -// method on the "one" node so that it connects to the "other" node -func (net *Network) Connect(oneID, otherID enode.ID) error { - net.lock.Lock() - defer net.lock.Unlock() - return net.connect(oneID, otherID) -} - -func (net *Network) connect(oneID, otherID enode.ID) error { - log.Debug("Connecting nodes with addPeer", "id", oneID, "other", otherID) - conn, err := net.initConn(oneID, otherID) - if err != nil { - return err - } - client, err := conn.one.Client() - if err != nil { - return err - } - net.events.Send(ControlEvent(conn)) - return client.Call(nil, "admin_addPeer", string(conn.other.Addr())) -} - -// Disconnect disconnects two nodes by calling the "admin_removePeer" RPC -// method on the "one" node so that it disconnects from the "other" node -func (net *Network) Disconnect(oneID, otherID enode.ID) error { - conn := net.GetConn(oneID, otherID) - if conn == nil { - return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID) - } - if !conn.Up { - return fmt.Errorf("%v and %v already disconnected", oneID, otherID) - } - client, err := conn.one.Client() - if err != nil { - return err - } - net.events.Send(ControlEvent(conn)) - return client.Call(nil, "admin_removePeer", string(conn.other.Addr())) -} - -// DidConnect tracks the fact that the "one" node connected to the "other" node -func (net *Network) DidConnect(one, other enode.ID) error { - net.lock.Lock() - defer net.lock.Unlock() - conn, err := net.getOrCreateConn(one, other) - if err != nil { - return fmt.Errorf("connection between %v and %v does not exist", one, other) - } - if conn.Up { - return fmt.Errorf("%v and %v already connected", one, other) - } - conn.Up = true - net.events.Send(NewEvent(conn)) - return nil -} - -// DidDisconnect tracks the fact that the "one" node disconnected from the -// "other" node -func (net *Network) DidDisconnect(one, other enode.ID) error { - net.lock.Lock() - defer net.lock.Unlock() - conn := net.getConn(one, other) - if conn == nil { - return fmt.Errorf("connection between %v and %v does not exist", one, other) - } - if !conn.Up { - return fmt.Errorf("%v and %v already disconnected", one, other) - } - conn.Up = false - conn.initiated = time.Now().Add(-DialBanTimeout) - net.events.Send(NewEvent(conn)) - return nil -} - -// DidSend tracks the fact that "sender" sent a message to "receiver" -func (net *Network) DidSend(sender, receiver enode.ID, proto string, code uint64) error { - msg := &Msg{ - One: sender, - Other: receiver, - Protocol: proto, - Code: code, - Received: false, - } - net.events.Send(NewEvent(msg)) - return nil -} - -// DidReceive tracks the fact that "receiver" received a message from "sender" -func (net *Network) DidReceive(sender, receiver enode.ID, proto string, code uint64) error { - msg := &Msg{ - One: sender, - Other: receiver, - Protocol: proto, - Code: code, - Received: true, - } - net.events.Send(NewEvent(msg)) - return nil -} - -// GetNode gets the node with the given ID, returning nil if the node does not -// exist -func (net *Network) GetNode(id enode.ID) *Node { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getNode(id) -} - -func (net *Network) getNode(id enode.ID) *Node { - i, found := net.nodeMap[id] - if !found { - return nil - } - return net.Nodes[i] -} - -// GetNodeByName gets the node with the given name, returning nil if the node does -// not exist -func (net *Network) GetNodeByName(name string) *Node { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getNodeByName(name) -} - -func (net *Network) getNodeByName(name string) *Node { - for _, node := range net.Nodes { - if node.Config.Name == name { - return node - } - } - return nil -} - -// GetNodeIDs returns the IDs of all existing nodes -// Nodes can optionally be excluded by specifying their enode.ID. -func (net *Network) GetNodeIDs(excludeIDs ...enode.ID) []enode.ID { - net.lock.RLock() - defer net.lock.RUnlock() - - return net.getNodeIDs(excludeIDs) -} - -func (net *Network) getNodeIDs(excludeIDs []enode.ID) []enode.ID { - // Get all current nodeIDs - nodeIDs := make([]enode.ID, 0, len(net.nodeMap)) - for id := range net.nodeMap { - nodeIDs = append(nodeIDs, id) - } - - if len(excludeIDs) > 0 { - // Return the difference of nodeIDs and excludeIDs - return filterIDs(nodeIDs, excludeIDs) - } - return nodeIDs -} - -// GetNodes returns the existing nodes. -// Nodes can optionally be excluded by specifying their enode.ID. -func (net *Network) GetNodes(excludeIDs ...enode.ID) []*Node { - net.lock.RLock() - defer net.lock.RUnlock() - - return net.getNodes(excludeIDs) -} - -func (net *Network) getNodes(excludeIDs []enode.ID) []*Node { - if len(excludeIDs) > 0 { - nodeIDs := net.getNodeIDs(excludeIDs) - return net.getNodesByID(nodeIDs) - } - return net.Nodes -} - -// GetNodesByID returns existing nodes with the given enode.IDs. -// If a node doesn't exist with a given enode.ID, it is ignored. -func (net *Network) GetNodesByID(nodeIDs []enode.ID) []*Node { - net.lock.RLock() - defer net.lock.RUnlock() - - return net.getNodesByID(nodeIDs) -} - -func (net *Network) getNodesByID(nodeIDs []enode.ID) []*Node { - nodes := make([]*Node, 0, len(nodeIDs)) - for _, id := range nodeIDs { - node := net.getNode(id) - if node != nil { - nodes = append(nodes, node) - } - } - - return nodes -} - -// GetNodesByProperty returns existing nodes that have the given property string registered in their NodeConfig -func (net *Network) GetNodesByProperty(property string) []*Node { - net.lock.RLock() - defer net.lock.RUnlock() - - return net.getNodesByProperty(property) -} - -func (net *Network) getNodesByProperty(property string) []*Node { - nodes := make([]*Node, 0, len(net.propertyMap[property])) - for _, nodeIndex := range net.propertyMap[property] { - nodes = append(nodes, net.Nodes[nodeIndex]) - } - - return nodes -} - -// GetNodeIDsByProperty returns existing node's enode IDs that have the given property string registered in the NodeConfig -func (net *Network) GetNodeIDsByProperty(property string) []enode.ID { - net.lock.RLock() - defer net.lock.RUnlock() - - return net.getNodeIDsByProperty(property) -} - -func (net *Network) getNodeIDsByProperty(property string) []enode.ID { - nodeIDs := make([]enode.ID, 0, len(net.propertyMap[property])) - for _, nodeIndex := range net.propertyMap[property] { - node := net.Nodes[nodeIndex] - nodeIDs = append(nodeIDs, node.ID()) - } - - return nodeIDs -} - -// GetRandomUpNode returns a random node on the network, which is running. -func (net *Network) GetRandomUpNode(excludeIDs ...enode.ID) *Node { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getRandomUpNode(excludeIDs...) -} - -// GetRandomUpNode returns a random node on the network, which is running. -func (net *Network) getRandomUpNode(excludeIDs ...enode.ID) *Node { - return net.getRandomNode(net.getUpNodeIDs(), excludeIDs) -} - -func (net *Network) getUpNodeIDs() (ids []enode.ID) { - for _, node := range net.Nodes { - if node.Up() { - ids = append(ids, node.ID()) - } - } - return ids -} - -// GetRandomDownNode returns a random node on the network, which is stopped. -func (net *Network) GetRandomDownNode(excludeIDs ...enode.ID) *Node { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getRandomNode(net.getDownNodeIDs(), excludeIDs) -} - -func (net *Network) getDownNodeIDs() (ids []enode.ID) { - for _, node := range net.Nodes { - if !node.Up() { - ids = append(ids, node.ID()) - } - } - return ids -} - -// GetRandomNode returns a random node on the network, regardless of whether it is running or not -func (net *Network) GetRandomNode(excludeIDs ...enode.ID) *Node { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getRandomNode(net.getNodeIDs(nil), excludeIDs) // no need to exclude twice -} - -func (net *Network) getRandomNode(ids []enode.ID, excludeIDs []enode.ID) *Node { - filtered := filterIDs(ids, excludeIDs) - - l := len(filtered) - if l == 0 { - return nil - } - return net.getNode(filtered[rand.Intn(l)]) -} - -func filterIDs(ids []enode.ID, excludeIDs []enode.ID) []enode.ID { - exclude := make(map[enode.ID]bool) - for _, id := range excludeIDs { - exclude[id] = true - } - var filtered []enode.ID - for _, id := range ids { - if _, found := exclude[id]; !found { - filtered = append(filtered, id) - } - } - return filtered -} - -// GetConn returns the connection which exists between "one" and "other" -// regardless of which node initiated the connection -func (net *Network) GetConn(oneID, otherID enode.ID) *Conn { - net.lock.RLock() - defer net.lock.RUnlock() - return net.getConn(oneID, otherID) -} - -// GetOrCreateConn is like GetConn but creates the connection if it doesn't -// already exist -func (net *Network) GetOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { - net.lock.Lock() - defer net.lock.Unlock() - return net.getOrCreateConn(oneID, otherID) -} - -func (net *Network) getOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { - if conn := net.getConn(oneID, otherID); conn != nil { - return conn, nil - } - - one := net.getNode(oneID) - if one == nil { - return nil, fmt.Errorf("node %v does not exist", oneID) - } - other := net.getNode(otherID) - if other == nil { - return nil, fmt.Errorf("node %v does not exist", otherID) - } - conn := &Conn{ - One: oneID, - Other: otherID, - one: one, - other: other, - } - label := ConnLabel(oneID, otherID) - net.connMap[label] = len(net.Conns) - net.Conns = append(net.Conns, conn) - return conn, nil -} - -func (net *Network) getConn(oneID, otherID enode.ID) *Conn { - label := ConnLabel(oneID, otherID) - i, found := net.connMap[label] - if !found { - return nil - } - return net.Conns[i] -} - -// InitConn retrieves the connection model for the connection between -// peers 'oneID' and 'otherID', or creates a new one if it does not exist -// the order of nodes does not matter, i.e., Conn(i,j) == Conn(j, i) -// it checks if the connection is already up, and if the nodes are running -// NOTE: -// it also checks whether there has been recent attempt to connect the peers -// this is cheating as the simulation is used as an oracle and know about -// remote peers attempt to connect to a node which will then not initiate the connection -func (net *Network) InitConn(oneID, otherID enode.ID) (*Conn, error) { - net.lock.Lock() - defer net.lock.Unlock() - return net.initConn(oneID, otherID) -} - -func (net *Network) initConn(oneID, otherID enode.ID) (*Conn, error) { - if oneID == otherID { - return nil, fmt.Errorf("refusing to connect to self %v", oneID) - } - conn, err := net.getOrCreateConn(oneID, otherID) - if err != nil { - return nil, err - } - if conn.Up { - return nil, fmt.Errorf("%v and %v already connected", oneID, otherID) - } - if time.Since(conn.initiated) < DialBanTimeout { - return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID) - } - - err = conn.nodesUp() - if err != nil { - log.Trace("Nodes not up", "err", err) - return nil, fmt.Errorf("nodes not up: %v", err) - } - log.Debug("Connection initiated", "id", oneID, "other", otherID) - conn.initiated = time.Now() - return conn, nil -} - -// Shutdown stops all nodes in the network and closes the quit channel -func (net *Network) Shutdown() { - for _, node := range net.Nodes { - log.Debug("Stopping node", "id", node.ID()) - if err := node.Stop(); err != nil { - log.Warn("Can't stop node", "id", node.ID(), "err", err) - } - } - close(net.quitc) -} - -// Reset resets all network properties: -// empties the nodes and the connection list -func (net *Network) Reset() { - net.lock.Lock() - defer net.lock.Unlock() - - //re-initialize the maps - net.connMap = make(map[string]int) - net.nodeMap = make(map[enode.ID]int) - net.propertyMap = make(map[string][]int) - - net.Nodes = nil - net.Conns = nil -} - -// Node is a wrapper around adapters.Node which is used to track the status -// of a node in the network -type Node struct { - adapters.Node `json:"-"` - - // Config if the config used to created the node - Config *adapters.NodeConfig `json:"config"` - - // up tracks whether or not the node is running - up bool - upMu *sync.RWMutex -} - -func newNode(an adapters.Node, ac *adapters.NodeConfig, up bool) *Node { - return &Node{Node: an, Config: ac, up: up, upMu: new(sync.RWMutex)} -} - -func (n *Node) copy() *Node { - configCpy := *n.Config - return newNode(n.Node, &configCpy, n.Up()) -} - -// Up returns whether the node is currently up (online) -func (n *Node) Up() bool { - n.upMu.RLock() - defer n.upMu.RUnlock() - return n.up -} - -// SetUp sets the up (online) status of the nodes with the given value -func (n *Node) SetUp(up bool) { - n.upMu.Lock() - defer n.upMu.Unlock() - n.up = up -} - -// ID returns the ID of the node -func (n *Node) ID() enode.ID { - return n.Config.ID -} - -// String returns a log-friendly string -func (n *Node) String() string { - return fmt.Sprintf("Node %v", n.ID().TerminalString()) -} - -// NodeInfo returns information about the node -func (n *Node) NodeInfo() *p2p.NodeInfo { - // avoid a panic if the node is not started yet - if n.Node == nil { - return nil - } - info := n.Node.NodeInfo() - info.Name = n.Config.Name - return info -} - -// MarshalJSON implements the json.Marshaler interface so that the encoded -// JSON includes the NodeInfo -func (n *Node) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - Info *p2p.NodeInfo `json:"info,omitempty"` - Config *adapters.NodeConfig `json:"config,omitempty"` - Up bool `json:"up"` - }{ - Info: n.NodeInfo(), - Config: n.Config, - Up: n.Up(), - }) -} - -// UnmarshalJSON implements json.Unmarshaler interface so that we don't lose Node.up -// status. IMPORTANT: The implementation is incomplete; we lose p2p.NodeInfo. -func (n *Node) UnmarshalJSON(raw []byte) error { - // TODO: How should we turn back NodeInfo into n.Node? - // Ticket: https://github.com/ethersphere/go-ethereum/issues/1177 - var node struct { - Config *adapters.NodeConfig `json:"config,omitempty"` - Up bool `json:"up"` - } - if err := json.Unmarshal(raw, &node); err != nil { - return err - } - *n = *newNode(nil, node.Config, node.Up) - return nil -} - -// Conn represents a connection between two nodes in the network -type Conn struct { - // One is the node which initiated the connection - One enode.ID `json:"one"` - - // Other is the node which the connection was made to - Other enode.ID `json:"other"` - - // Up tracks whether or not the connection is active - Up bool `json:"up"` - // Registers when the connection was grabbed to dial - initiated time.Time - - one *Node - other *Node -} - -// nodesUp returns whether both nodes are currently up -func (c *Conn) nodesUp() error { - if !c.one.Up() { - return fmt.Errorf("one %v is not up", c.One) - } - if !c.other.Up() { - return fmt.Errorf("other %v is not up", c.Other) - } - return nil -} - -// String returns a log-friendly string -func (c *Conn) String() string { - return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString()) -} - -// Msg represents a p2p message sent between two nodes in the network -type Msg struct { - One enode.ID `json:"one"` - Other enode.ID `json:"other"` - Protocol string `json:"protocol"` - Code uint64 `json:"code"` - Received bool `json:"received"` -} - -// String returns a log-friendly string -func (m *Msg) String() string { - return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString()) -} - -// ConnLabel generates a deterministic string which represents a connection -// between two nodes, used to compare if two connections are between the same -// nodes -func ConnLabel(source, target enode.ID) string { - var first, second enode.ID - if bytes.Compare(source.Bytes(), target.Bytes()) > 0 { - first = target - second = source - } else { - first = source - second = target - } - return fmt.Sprintf("%v-%v", first, second) -} - -// Snapshot represents the state of a network at a single point in time and can -// be used to restore the state of a network -type Snapshot struct { - Nodes []NodeSnapshot `json:"nodes,omitempty"` - Conns []Conn `json:"conns,omitempty"` -} - -// NodeSnapshot represents the state of a node in the network -type NodeSnapshot struct { - Node Node `json:"node,omitempty"` - - // Snapshots is arbitrary data gathered from calling node.Snapshots() - Snapshots map[string][]byte `json:"snapshots,omitempty"` -} - -// Snapshot creates a network snapshot -func (net *Network) Snapshot() (*Snapshot, error) { - return net.snapshot(nil, nil) -} - -func (net *Network) SnapshotWithServices(addServices []string, removeServices []string) (*Snapshot, error) { - return net.snapshot(addServices, removeServices) -} - -func (net *Network) snapshot(addServices []string, removeServices []string) (*Snapshot, error) { - net.lock.Lock() - defer net.lock.Unlock() - snap := &Snapshot{ - Nodes: make([]NodeSnapshot, len(net.Nodes)), - } - for i, node := range net.Nodes { - snap.Nodes[i] = NodeSnapshot{Node: *node.copy()} - if !node.Up() { - continue - } - snapshots, err := node.Snapshots() - if err != nil { - return nil, err - } - snap.Nodes[i].Snapshots = snapshots - for _, addSvc := range addServices { - haveSvc := false - for _, svc := range snap.Nodes[i].Node.Config.Lifecycles { - if svc == addSvc { - haveSvc = true - break - } - } - if !haveSvc { - snap.Nodes[i].Node.Config.Lifecycles = append(snap.Nodes[i].Node.Config.Lifecycles, addSvc) - } - } - if len(removeServices) > 0 { - var cleanedServices []string - for _, svc := range snap.Nodes[i].Node.Config.Lifecycles { - haveSvc := false - for _, rmSvc := range removeServices { - if rmSvc == svc { - haveSvc = true - break - } - } - if !haveSvc { - cleanedServices = append(cleanedServices, svc) - } - } - snap.Nodes[i].Node.Config.Lifecycles = cleanedServices - } - } - for _, conn := range net.Conns { - if conn.Up { - snap.Conns = append(snap.Conns, *conn) - } - } - return snap, nil -} - -// longrunning tests may need a longer timeout -var snapshotLoadTimeout = 900 * time.Second - -// Load loads a network snapshot -func (net *Network) Load(snap *Snapshot) error { - // Start nodes. - for _, n := range snap.Nodes { - if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil { - return err - } - if !n.Node.Up() { - continue - } - if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil { - return err - } - } - - // Prepare connection events counter. - allConnected := make(chan struct{}) // closed when all connections are established - done := make(chan struct{}) // ensures that the event loop goroutine is terminated - defer close(done) - - // Subscribe to event channel. - // It needs to be done outside of the event loop goroutine (created below) - // to ensure that the event channel is blocking before connect calls are made. - events := make(chan *Event) - sub := net.Events().Subscribe(events) - defer sub.Unsubscribe() - - go func() { - // Expected number of connections. - total := len(snap.Conns) - // Set of all established connections from the snapshot, not other connections. - // Key array element 0 is the connection One field value, and element 1 connection Other field. - connections := make(map[[2]enode.ID]struct{}, total) - - for { - select { - case e := <-events: - // Ignore control events as they do not represent - // connect or disconnect (Up) state change. - if e.Control { - continue - } - // Detect only connection events. - if e.Type != EventTypeConn { - continue - } - connection := [2]enode.ID{e.Conn.One, e.Conn.Other} - // Nodes are still not connected or have been disconnected. - if !e.Conn.Up { - // Delete the connection from the set of established connections. - // This will prevent false positive in case disconnections happen. - delete(connections, connection) - log.Warn("load snapshot: unexpected disconnection", "one", e.Conn.One, "other", e.Conn.Other) - continue - } - // Check that the connection is from the snapshot. - for _, conn := range snap.Conns { - if conn.One == e.Conn.One && conn.Other == e.Conn.Other { - // Add the connection to the set of established connections. - connections[connection] = struct{}{} - if len(connections) == total { - // Signal that all nodes are connected. - close(allConnected) - return - } - - break - } - } - case <-done: - // Load function returned, terminate this goroutine. - return - } - } - }() - - // Start connecting. - for _, conn := range snap.Conns { - if !net.GetNode(conn.One).Up() || !net.GetNode(conn.Other).Up() { - //in this case, at least one of the nodes of a connection is not up, - //so it would result in the snapshot `Load` to fail - continue - } - if err := net.Connect(conn.One, conn.Other); err != nil { - return err - } - } - - select { - // Wait until all connections from the snapshot are established. - case <-allConnected: - // Make sure that we do not wait forever. - case <-time.After(snapshotLoadTimeout): - return errors.New("snapshot connections not established") - } - return nil -} - -// Subscribe reads control events from a channel and executes them -func (net *Network) Subscribe(events chan *Event) { - for { - select { - case event, ok := <-events: - if !ok { - return - } - if event.Control { - net.executeControlEvent(event) - } - case <-net.quitc: - return - } - } -} - -func (net *Network) executeControlEvent(event *Event) { - log.Trace("Executing control event", "type", event.Type, "event", event) - switch event.Type { - case EventTypeNode: - if err := net.executeNodeEvent(event); err != nil { - log.Error("Error executing node event", "event", event, "err", err) - } - case EventTypeConn: - if err := net.executeConnEvent(event); err != nil { - log.Error("Error executing conn event", "event", event, "err", err) - } - case EventTypeMsg: - log.Warn("Ignoring control msg event") - } -} - -func (net *Network) executeNodeEvent(e *Event) error { - if !e.Node.Up() { - return net.Stop(e.Node.ID()) - } - - if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil { - return err - } - return net.Start(e.Node.ID()) -} - -func (net *Network) executeConnEvent(e *Event) error { - if e.Conn.Up { - return net.Connect(e.Conn.One, e.Conn.Other) - } - return net.Disconnect(e.Conn.One, e.Conn.Other) -} diff --git a/p2p/simulations/network_test.go b/p2p/simulations/network_test.go deleted file mode 100644 index 4ed1e4e6c3..0000000000 --- a/p2p/simulations/network_test.go +++ /dev/null @@ -1,872 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "reflect" - "strconv" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/simulations/adapters" -) - -// Tests that a created snapshot with a minimal service only contains the expected connections -// and that a network when loaded with this snapshot only contains those same connections -func TestSnapshot(t *testing.T) { - // PART I - // create snapshot from ring network - - // this is a minimal service, whose protocol will take exactly one message OR close of connection before quitting - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "noopwoop": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - return NewNoopService(nil), nil - }, - }) - - // create network - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "noopwoop", - }) - // \todo consider making a member of network, set to true threadsafe when shutdown - runningOne := true - defer func() { - if runningOne { - network.Shutdown() - } - }() - - // create and start nodes - nodeCount := 20 - ids := make([]enode.ID, nodeCount) - for i := 0; i < nodeCount; i++ { - conf := adapters.RandomNodeConfig() - node, err := network.NewNodeWithConfig(conf) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - if err := network.Start(node.ID()); err != nil { - t.Fatalf("error starting node: %s", err) - } - ids[i] = node.ID() - } - - // subscribe to peer events - evC := make(chan *Event) - sub := network.Events().Subscribe(evC) - defer sub.Unsubscribe() - - // connect nodes in a ring - // spawn separate thread to avoid deadlock in the event listeners - connectErr := make(chan error, 1) - go func() { - for i, id := range ids { - peerID := ids[(i+1)%len(ids)] - if err := network.Connect(id, peerID); err != nil { - connectErr <- err - return - } - } - }() - - // collect connection events up to expected number - ctx, cancel := context.WithTimeout(context.TODO(), time.Second) - defer cancel() - checkIds := make(map[enode.ID][]enode.ID) - connEventCount := nodeCount -OUTER: - for { - select { - case <-ctx.Done(): - t.Fatal(ctx.Err()) - case err := <-connectErr: - t.Fatal(err) - case ev := <-evC: - if ev.Type == EventTypeConn && !ev.Control { - // fail on any disconnect - if !ev.Conn.Up { - t.Fatalf("unexpected disconnect: %v -> %v", ev.Conn.One, ev.Conn.Other) - } - checkIds[ev.Conn.One] = append(checkIds[ev.Conn.One], ev.Conn.Other) - checkIds[ev.Conn.Other] = append(checkIds[ev.Conn.Other], ev.Conn.One) - connEventCount-- - log.Debug("ev", "count", connEventCount) - if connEventCount == 0 { - break OUTER - } - } - } - } - - // create snapshot of current network - snap, err := network.Snapshot() - if err != nil { - t.Fatal(err) - } - j, err := json.Marshal(snap) - if err != nil { - t.Fatal(err) - } - log.Debug("snapshot taken", "nodes", len(snap.Nodes), "conns", len(snap.Conns), "json", string(j)) - - // verify that the snap element numbers check out - if len(checkIds) != len(snap.Conns) || len(checkIds) != len(snap.Nodes) { - t.Fatalf("snapshot wrong node,conn counts %d,%d != %d", len(snap.Nodes), len(snap.Conns), len(checkIds)) - } - - // shut down sim network - runningOne = false - sub.Unsubscribe() - network.Shutdown() - - // check that we have all the expected connections in the snapshot - for nodid, nodConns := range checkIds { - for _, nodConn := range nodConns { - var match bool - for _, snapConn := range snap.Conns { - if snapConn.One == nodid && snapConn.Other == nodConn { - match = true - break - } else if snapConn.Other == nodid && snapConn.One == nodConn { - match = true - break - } - } - if !match { - t.Fatalf("snapshot missing conn %v -> %v", nodid, nodConn) - } - } - } - log.Info("snapshot checked") - - // PART II - // load snapshot and verify that exactly same connections are formed - - adapter = adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "noopwoop": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - return NewNoopService(nil), nil - }, - }) - network = NewNetwork(adapter, &NetworkConfig{ - DefaultService: "noopwoop", - }) - defer func() { - network.Shutdown() - }() - - // subscribe to peer events - // every node up and conn up event will generate one additional control event - // therefore multiply the count by two - evC = make(chan *Event, (len(snap.Conns)*2)+(len(snap.Nodes)*2)) - sub = network.Events().Subscribe(evC) - defer sub.Unsubscribe() - - // load the snapshot - // spawn separate thread to avoid deadlock in the event listeners - err = network.Load(snap) - if err != nil { - t.Fatal(err) - } - - // collect connection events up to expected number - ctx, cancel = context.WithTimeout(context.TODO(), time.Second*3) - defer cancel() - - connEventCount = nodeCount - -OuterTwo: - for { - select { - case <-ctx.Done(): - t.Fatal(ctx.Err()) - case ev := <-evC: - if ev.Type == EventTypeConn && !ev.Control { - // fail on any disconnect - if !ev.Conn.Up { - t.Fatalf("unexpected disconnect: %v -> %v", ev.Conn.One, ev.Conn.Other) - } - log.Debug("conn", "on", ev.Conn.One, "other", ev.Conn.Other) - checkIds[ev.Conn.One] = append(checkIds[ev.Conn.One], ev.Conn.Other) - checkIds[ev.Conn.Other] = append(checkIds[ev.Conn.Other], ev.Conn.One) - connEventCount-- - log.Debug("ev", "count", connEventCount) - if connEventCount == 0 { - break OuterTwo - } - } - } - } - - // check that we have all expected connections in the network - for _, snapConn := range snap.Conns { - var match bool - for nodid, nodConns := range checkIds { - for _, nodConn := range nodConns { - if snapConn.One == nodid && snapConn.Other == nodConn { - match = true - break - } else if snapConn.Other == nodid && snapConn.One == nodConn { - match = true - break - } - } - } - if !match { - t.Fatalf("network missing conn %v -> %v", snapConn.One, snapConn.Other) - } - } - - // verify that network didn't generate any other additional connection events after the ones we have collected within a reasonable period of time - ctx, cancel = context.WithTimeout(context.TODO(), time.Second) - defer cancel() - select { - case <-ctx.Done(): - case ev := <-evC: - if ev.Type == EventTypeConn { - t.Fatalf("Superfluous conn found %v -> %v", ev.Conn.One, ev.Conn.Other) - } - } - - // This test validates if all connections from the snapshot - // are created in the network. - t.Run("conns after load", func(t *testing.T) { - // Create new network. - n := NewNetwork( - adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "noopwoop": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - return NewNoopService(nil), nil - }, - }), - &NetworkConfig{ - DefaultService: "noopwoop", - }, - ) - defer n.Shutdown() - - // Load the same snapshot. - err := n.Load(snap) - if err != nil { - t.Fatal(err) - } - - // Check every connection from the snapshot - // if it is in the network, too. - for _, c := range snap.Conns { - if n.GetConn(c.One, c.Other) == nil { - t.Errorf("missing connection: %s -> %s", c.One, c.Other) - } - } - }) -} - -// TestNetworkSimulation creates a multi-node simulation network with each node -// connected in a ring topology, checks that all nodes successfully handshake -// with each other and that a snapshot fully represents the desired topology -func TestNetworkSimulation(t *testing.T) { - // create simulation network with 20 testService nodes - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - nodeCount := 20 - ids := make([]enode.ID, nodeCount) - for i := 0; i < nodeCount; i++ { - conf := adapters.RandomNodeConfig() - node, err := network.NewNodeWithConfig(conf) - if err != nil { - t.Fatalf("error creating node: %s", err) - } - if err := network.Start(node.ID()); err != nil { - t.Fatalf("error starting node: %s", err) - } - ids[i] = node.ID() - } - - // perform a check which connects the nodes in a ring (so each node is - // connected to exactly two peers) and then checks that all nodes - // performed two handshakes by checking their peerCount - action := func(_ context.Context) error { - for i, id := range ids { - peerID := ids[(i+1)%len(ids)] - if err := network.Connect(id, peerID); err != nil { - return err - } - } - return nil - } - check := func(ctx context.Context, id enode.ID) (bool, error) { - // check we haven't run out of time - select { - case <-ctx.Done(): - return false, ctx.Err() - default: - } - - // get the node - node := network.GetNode(id) - if node == nil { - return false, fmt.Errorf("unknown node: %s", id) - } - - // check it has exactly two peers - client, err := node.Client() - if err != nil { - return false, err - } - var peerCount int64 - if err := client.CallContext(ctx, &peerCount, "test_peerCount"); err != nil { - return false, err - } - switch { - case peerCount < 2: - return false, nil - case peerCount == 2: - return true, nil - default: - return false, fmt.Errorf("unexpected peerCount: %d", peerCount) - } - } - - timeout := 30 * time.Second - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - // trigger a check every 100ms - trigger := make(chan enode.ID) - go triggerChecks(ctx, ids, trigger, 100*time.Millisecond) - - result := NewSimulation(network).Run(ctx, &Step{ - Action: action, - Trigger: trigger, - Expect: &Expectation{ - Nodes: ids, - Check: check, - }, - }) - if result.Error != nil { - t.Fatalf("simulation failed: %s", result.Error) - } - - // take a network snapshot and check it contains the correct topology - snap, err := network.Snapshot() - if err != nil { - t.Fatal(err) - } - if len(snap.Nodes) != nodeCount { - t.Fatalf("expected snapshot to contain %d nodes, got %d", nodeCount, len(snap.Nodes)) - } - if len(snap.Conns) != nodeCount { - t.Fatalf("expected snapshot to contain %d connections, got %d", nodeCount, len(snap.Conns)) - } - for i, id := range ids { - conn := snap.Conns[i] - if conn.One != id { - t.Fatalf("expected conn[%d].One to be %s, got %s", i, id, conn.One) - } - peerID := ids[(i+1)%len(ids)] - if conn.Other != peerID { - t.Fatalf("expected conn[%d].Other to be %s, got %s", i, peerID, conn.Other) - } - } -} - -func createTestNodes(count int, network *Network) (nodes []*Node, err error) { - for i := 0; i < count; i++ { - nodeConf := adapters.RandomNodeConfig() - node, err := network.NewNodeWithConfig(nodeConf) - if err != nil { - return nil, err - } - if err := network.Start(node.ID()); err != nil { - return nil, err - } - - nodes = append(nodes, node) - } - - return nodes, nil -} - -func createTestNodesWithProperty(property string, count int, network *Network) (propertyNodes []*Node, err error) { - for i := 0; i < count; i++ { - nodeConf := adapters.RandomNodeConfig() - nodeConf.Properties = append(nodeConf.Properties, property) - - node, err := network.NewNodeWithConfig(nodeConf) - if err != nil { - return nil, err - } - if err := network.Start(node.ID()); err != nil { - return nil, err - } - - propertyNodes = append(propertyNodes, node) - } - - return propertyNodes, nil -} - -// TestGetNodeIDs creates a set of nodes and attempts to retrieve their IDs,. -// It then tests again whilst excluding a node ID from being returned. -// If a node ID is not returned, or more node IDs than expected are returned, the test fails. -func TestGetNodeIDs(t *testing.T) { - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - - numNodes := 5 - nodes, err := createTestNodes(numNodes, network) - if err != nil { - t.Fatalf("Could not create test nodes %v", err) - } - - gotNodeIDs := network.GetNodeIDs() - if len(gotNodeIDs) != numNodes { - t.Fatalf("Expected %d nodes, got %d", numNodes, len(gotNodeIDs)) - } - - for _, node1 := range nodes { - match := false - for _, node2ID := range gotNodeIDs { - if bytes.Equal(node1.ID().Bytes(), node2ID.Bytes()) { - match = true - break - } - } - - if !match { - t.Fatalf("A created node was not returned by GetNodes(), ID: %s", node1.ID().String()) - } - } - - excludeNodeID := nodes[3].ID() - gotNodeIDsExcl := network.GetNodeIDs(excludeNodeID) - if len(gotNodeIDsExcl) != numNodes-1 { - t.Fatalf("Expected one less node ID to be returned") - } - for _, nodeID := range gotNodeIDsExcl { - if bytes.Equal(excludeNodeID.Bytes(), nodeID.Bytes()) { - t.Fatalf("GetNodeIDs returned the node ID we excluded, ID: %s", nodeID.String()) - } - } -} - -// TestGetNodes creates a set of nodes and attempts to retrieve them again. -// It then tests again whilst excluding a node from being returned. -// If a node is not returned, or more nodes than expected are returned, the test fails. -func TestGetNodes(t *testing.T) { - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - - numNodes := 5 - nodes, err := createTestNodes(numNodes, network) - if err != nil { - t.Fatalf("Could not create test nodes %v", err) - } - - gotNodes := network.GetNodes() - if len(gotNodes) != numNodes { - t.Fatalf("Expected %d nodes, got %d", numNodes, len(gotNodes)) - } - - for _, node1 := range nodes { - match := false - for _, node2 := range gotNodes { - if bytes.Equal(node1.ID().Bytes(), node2.ID().Bytes()) { - match = true - break - } - } - - if !match { - t.Fatalf("A created node was not returned by GetNodes(), ID: %s", node1.ID().String()) - } - } - - excludeNodeID := nodes[3].ID() - gotNodesExcl := network.GetNodes(excludeNodeID) - if len(gotNodesExcl) != numNodes-1 { - t.Fatalf("Expected one less node to be returned") - } - for _, node := range gotNodesExcl { - if bytes.Equal(excludeNodeID.Bytes(), node.ID().Bytes()) { - t.Fatalf("GetNodes returned the node we excluded, ID: %s", node.ID().String()) - } - } -} - -// TestGetNodesByID creates a set of nodes and attempts to retrieve a subset of them by ID -// If a node is not returned, or more nodes than expected are returned, the test fails. -func TestGetNodesByID(t *testing.T) { - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - - numNodes := 5 - nodes, err := createTestNodes(numNodes, network) - if err != nil { - t.Fatalf("Could not create test nodes: %v", err) - } - - numSubsetNodes := 2 - subsetNodes := nodes[0:numSubsetNodes] - var subsetNodeIDs []enode.ID - for _, node := range subsetNodes { - subsetNodeIDs = append(subsetNodeIDs, node.ID()) - } - - gotNodesByID := network.GetNodesByID(subsetNodeIDs) - if len(gotNodesByID) != numSubsetNodes { - t.Fatalf("Expected %d nodes, got %d", numSubsetNodes, len(gotNodesByID)) - } - - for _, node1 := range subsetNodes { - match := false - for _, node2 := range gotNodesByID { - if bytes.Equal(node1.ID().Bytes(), node2.ID().Bytes()) { - match = true - break - } - } - - if !match { - t.Fatalf("A created node was not returned by GetNodesByID(), ID: %s", node1.ID().String()) - } - } -} - -// TestGetNodesByProperty creates a subset of nodes with a property assigned. -// GetNodesByProperty is then checked for correctness by comparing the nodes returned to those initially created. -// If a node with a property is not found, or more nodes than expected are returned, the test fails. -func TestGetNodesByProperty(t *testing.T) { - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - - numNodes := 3 - _, err := createTestNodes(numNodes, network) - if err != nil { - t.Fatalf("Failed to create nodes: %v", err) - } - - numPropertyNodes := 3 - propertyTest := "test" - propertyNodes, err := createTestNodesWithProperty(propertyTest, numPropertyNodes, network) - if err != nil { - t.Fatalf("Failed to create nodes with property: %v", err) - } - - gotNodesByProperty := network.GetNodesByProperty(propertyTest) - if len(gotNodesByProperty) != numPropertyNodes { - t.Fatalf("Expected %d nodes with a property, got %d", numPropertyNodes, len(gotNodesByProperty)) - } - - for _, node1 := range propertyNodes { - match := false - for _, node2 := range gotNodesByProperty { - if bytes.Equal(node1.ID().Bytes(), node2.ID().Bytes()) { - match = true - break - } - } - - if !match { - t.Fatalf("A created node with property was not returned by GetNodesByProperty(), ID: %s", node1.ID().String()) - } - } -} - -// TestGetNodeIDsByProperty creates a subset of nodes with a property assigned. -// GetNodeIDsByProperty is then checked for correctness by comparing the node IDs returned to those initially created. -// If a node ID with a property is not found, or more nodes IDs than expected are returned, the test fails. -func TestGetNodeIDsByProperty(t *testing.T) { - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "test": newTestService, - }) - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "test", - }) - defer network.Shutdown() - - numNodes := 3 - _, err := createTestNodes(numNodes, network) - if err != nil { - t.Fatalf("Failed to create nodes: %v", err) - } - - numPropertyNodes := 3 - propertyTest := "test" - propertyNodes, err := createTestNodesWithProperty(propertyTest, numPropertyNodes, network) - if err != nil { - t.Fatalf("Failed to created nodes with property: %v", err) - } - - gotNodeIDsByProperty := network.GetNodeIDsByProperty(propertyTest) - if len(gotNodeIDsByProperty) != numPropertyNodes { - t.Fatalf("Expected %d nodes with a property, got %d", numPropertyNodes, len(gotNodeIDsByProperty)) - } - - for _, node1 := range propertyNodes { - match := false - id1 := node1.ID() - for _, id2 := range gotNodeIDsByProperty { - if bytes.Equal(id1.Bytes(), id2.Bytes()) { - match = true - break - } - } - - if !match { - t.Fatalf("Not all nodes IDs were returned by GetNodeIDsByProperty(), ID: %s", id1.String()) - } - } -} - -func triggerChecks(ctx context.Context, ids []enode.ID, trigger chan enode.ID, interval time.Duration) { - tick := time.NewTicker(interval) - defer tick.Stop() - for { - select { - case <-tick.C: - for _, id := range ids { - select { - case trigger <- id: - case <-ctx.Done(): - return - } - } - case <-ctx.Done(): - return - } - } -} - -// \todo: refactor to implement snapshots -// and connect configuration methods once these are moved from -// swarm/network/simulations/connect.go -func BenchmarkMinimalService(b *testing.B) { - b.Run("ring/32", benchmarkMinimalServiceTmp) -} - -func benchmarkMinimalServiceTmp(b *testing.B) { - // stop timer to discard setup time pollution - args := strings.Split(b.Name(), "/") - nodeCount, err := strconv.ParseInt(args[2], 10, 16) - if err != nil { - b.Fatal(err) - } - - for i := 0; i < b.N; i++ { - // this is a minimal service, whose protocol will close a channel upon run of protocol - // making it possible to bench the time it takes for the service to start and protocol actually to be run - protoCMap := make(map[enode.ID]map[enode.ID]chan struct{}) - adapter := adapters.NewSimAdapter(adapters.LifecycleConstructors{ - "noopwoop": func(ctx *adapters.ServiceContext, stack *node.Node) (node.Lifecycle, error) { - protoCMap[ctx.Config.ID] = make(map[enode.ID]chan struct{}) - svc := NewNoopService(protoCMap[ctx.Config.ID]) - return svc, nil - }, - }) - - // create network - network := NewNetwork(adapter, &NetworkConfig{ - DefaultService: "noopwoop", - }) - defer network.Shutdown() - - // create and start nodes - ids := make([]enode.ID, nodeCount) - for i := 0; i < int(nodeCount); i++ { - conf := adapters.RandomNodeConfig() - node, err := network.NewNodeWithConfig(conf) - if err != nil { - b.Fatalf("error creating node: %s", err) - } - if err := network.Start(node.ID()); err != nil { - b.Fatalf("error starting node: %s", err) - } - ids[i] = node.ID() - } - - // ready, set, go - b.ResetTimer() - - // connect nodes in a ring - for i, id := range ids { - peerID := ids[(i+1)%len(ids)] - if err := network.Connect(id, peerID); err != nil { - b.Fatal(err) - } - } - - // wait for all protocols to signal to close down - ctx, cancel := context.WithTimeout(context.TODO(), time.Second) - defer cancel() - for nodid, peers := range protoCMap { - for peerid, peerC := range peers { - log.Debug("getting ", "node", nodid, "peer", peerid) - select { - case <-ctx.Done(): - b.Fatal(ctx.Err()) - case <-peerC: - } - } - } - } -} - -func TestNode_UnmarshalJSON(t *testing.T) { - t.Run("up_field", func(t *testing.T) { - runNodeUnmarshalJSON(t, casesNodeUnmarshalJSONUpField()) - }) - t.Run("config_field", func(t *testing.T) { - runNodeUnmarshalJSON(t, casesNodeUnmarshalJSONConfigField()) - }) -} - -func runNodeUnmarshalJSON(t *testing.T, tests []nodeUnmarshalTestCase) { - t.Helper() - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var got *Node - if err := json.Unmarshal([]byte(tt.marshaled), &got); err != nil { - expectErrorMessageToContain(t, err, tt.wantErr) - got = nil - } - expectNodeEquality(t, got, tt.want) - }) - } -} - -type nodeUnmarshalTestCase struct { - name string - marshaled string - want *Node - wantErr string -} - -func expectErrorMessageToContain(t *testing.T, got error, want string) { - t.Helper() - if got == nil && want == "" { - return - } - - if got == nil && want != "" { - t.Errorf("error was expected, got: nil, want: %v", want) - return - } - - if !strings.Contains(got.Error(), want) { - t.Errorf( - "unexpected error message, got %v, want: %v", - want, - got, - ) - } -} - -func expectNodeEquality(t *testing.T, got, want *Node) { - t.Helper() - if !reflect.DeepEqual(got, want) { - t.Errorf("Node.UnmarshalJSON() = %v, want %v", got, want) - } -} - -func casesNodeUnmarshalJSONUpField() []nodeUnmarshalTestCase { - return []nodeUnmarshalTestCase{ - { - name: "empty json", - marshaled: "{}", - want: newNode(nil, nil, false), - }, - { - name: "a stopped node", - marshaled: "{\"up\": false}", - want: newNode(nil, nil, false), - }, - { - name: "a running node", - marshaled: "{\"up\": true}", - want: newNode(nil, nil, true), - }, - { - name: "invalid JSON value on valid key", - marshaled: "{\"up\": foo}", - wantErr: "invalid character", - }, - { - name: "invalid JSON key and value", - marshaled: "{foo: bar}", - wantErr: "invalid character", - }, - { - name: "bool value expected but got something else (string)", - marshaled: "{\"up\": \"true\"}", - wantErr: "cannot unmarshal string into Go struct", - }, - } -} - -func casesNodeUnmarshalJSONConfigField() []nodeUnmarshalTestCase { - // Don't do a big fuss around testing, as adapters.NodeConfig should - // handle it's own serialization. Just do a sanity check. - return []nodeUnmarshalTestCase{ - { - name: "Config field is omitted", - marshaled: "{}", - want: newNode(nil, nil, false), - }, - { - name: "Config field is nil", - marshaled: "{\"config\": null}", - want: newNode(nil, nil, false), - }, - { - name: "a non default Config field", - marshaled: "{\"config\":{\"name\":\"node_ecdd0\",\"port\":44665}}", - want: newNode(nil, &adapters.NodeConfig{Name: "node_ecdd0", Port: 44665}, false), - }, - } -} diff --git a/p2p/simulations/simulation.go b/p2p/simulations/simulation.go deleted file mode 100644 index ae62c42b9c..0000000000 --- a/p2p/simulations/simulation.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "context" - "time" - - "github.com/ethereum/go-ethereum/p2p/enode" -) - -// Simulation provides a framework for running actions in a simulated network -// and then waiting for expectations to be met -type Simulation struct { - network *Network -} - -// NewSimulation returns a new simulation which runs in the given network -func NewSimulation(network *Network) *Simulation { - return &Simulation{ - network: network, - } -} - -// Run performs a step of the simulation by performing the step's action and -// then waiting for the step's expectation to be met -func (s *Simulation) Run(ctx context.Context, step *Step) (result *StepResult) { - result = newStepResult() - - result.StartedAt = time.Now() - defer func() { result.FinishedAt = time.Now() }() - - // watch network events for the duration of the step - stop := s.watchNetwork(result) - defer stop() - - // perform the action - if err := step.Action(ctx); err != nil { - result.Error = err - return - } - - // wait for all node expectations to either pass, error or timeout - nodes := make(map[enode.ID]struct{}, len(step.Expect.Nodes)) - for _, id := range step.Expect.Nodes { - nodes[id] = struct{}{} - } - for len(result.Passes) < len(nodes) { - select { - case id := <-step.Trigger: - // skip if we aren't checking the node - if _, ok := nodes[id]; !ok { - continue - } - - // skip if the node has already passed - if _, ok := result.Passes[id]; ok { - continue - } - - // run the node expectation check - pass, err := step.Expect.Check(ctx, id) - if err != nil { - result.Error = err - return - } - if pass { - result.Passes[id] = time.Now() - } - case <-ctx.Done(): - result.Error = ctx.Err() - return - } - } - - return -} - -func (s *Simulation) watchNetwork(result *StepResult) func() { - stop := make(chan struct{}) - done := make(chan struct{}) - events := make(chan *Event) - sub := s.network.Events().Subscribe(events) - go func() { - defer close(done) - defer sub.Unsubscribe() - for { - select { - case event := <-events: - result.NetworkEvents = append(result.NetworkEvents, event) - case <-stop: - return - } - } - }() - return func() { - close(stop) - <-done - } -} - -type Step struct { - // Action is the action to perform for this step - Action func(context.Context) error - - // Trigger is a channel which receives node ids and triggers an - // expectation check for that node - Trigger chan enode.ID - - // Expect is the expectation to wait for when performing this step - Expect *Expectation -} - -type Expectation struct { - // Nodes is a list of nodes to check - Nodes []enode.ID - - // Check checks whether a given node meets the expectation - Check func(context.Context, enode.ID) (bool, error) -} - -func newStepResult() *StepResult { - return &StepResult{ - Passes: make(map[enode.ID]time.Time), - } -} - -type StepResult struct { - // Error is the error encountered whilst running the step - Error error - - // StartedAt is the time the step started - StartedAt time.Time - - // FinishedAt is the time the step finished - FinishedAt time.Time - - // Passes are the timestamps of the successful node expectations - Passes map[enode.ID]time.Time - - // NetworkEvents are the network events which occurred during the step - NetworkEvents []*Event -} diff --git a/p2p/simulations/test.go b/p2p/simulations/test.go deleted file mode 100644 index 0edb07b127..0000000000 --- a/p2p/simulations/test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package simulations - -import ( - "testing" - - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/rpc" -) - -// NoopService is the service that does not do anything -// but implements node.Service interface. -type NoopService struct { - c map[enode.ID]chan struct{} -} - -func NewNoopService(ackC map[enode.ID]chan struct{}) *NoopService { - return &NoopService{ - c: ackC, - } -} - -func (t *NoopService) Protocols() []p2p.Protocol { - return []p2p.Protocol{ - { - Name: "noop", - Version: 666, - Length: 0, - Run: func(peer *p2p.Peer, rw p2p.MsgReadWriter) error { - if t.c != nil { - t.c[peer.ID()] = make(chan struct{}) - close(t.c[peer.ID()]) - } - rw.ReadMsg() - return nil - }, - NodeInfo: func() interface{} { - return struct{}{} - }, - PeerInfo: func(id enode.ID) interface{} { - return struct{}{} - }, - Attributes: []enr.Entry{}, - }, - } -} - -func (t *NoopService) APIs() []rpc.API { - return []rpc.API{} -} - -func (t *NoopService) Start() error { - return nil -} - -func (t *NoopService) Stop() error { - return nil -} - -func VerifyRing(t *testing.T, net *Network, ids []enode.ID) { - t.Helper() - n := len(ids) - for i := 0; i < n; i++ { - for j := i + 1; j < n; j++ { - c := net.GetConn(ids[i], ids[j]) - if i == j-1 || (i == 0 && j == n-1) { - if c == nil { - t.Errorf("nodes %v and %v are not connected, but they should be", i, j) - } - } else { - if c != nil { - t.Errorf("nodes %v and %v are connected, but they should not be", i, j) - } - } - } - } -} - -func VerifyChain(t *testing.T, net *Network, ids []enode.ID) { - t.Helper() - n := len(ids) - for i := 0; i < n; i++ { - for j := i + 1; j < n; j++ { - c := net.GetConn(ids[i], ids[j]) - if i == j-1 { - if c == nil { - t.Errorf("nodes %v and %v are not connected, but they should be", i, j) - } - } else { - if c != nil { - t.Errorf("nodes %v and %v are connected, but they should not be", i, j) - } - } - } - } -} - -func VerifyFull(t *testing.T, net *Network, ids []enode.ID) { - t.Helper() - n := len(ids) - var connections int - for i, lid := range ids { - for _, rid := range ids[i+1:] { - if net.GetConn(lid, rid) != nil { - connections++ - } - } - } - - want := n * (n - 1) / 2 - if connections != want { - t.Errorf("wrong number of connections, got: %v, want: %v", connections, want) - } -} - -func VerifyStar(t *testing.T, net *Network, ids []enode.ID, centerIndex int) { - t.Helper() - n := len(ids) - for i := 0; i < n; i++ { - for j := i + 1; j < n; j++ { - c := net.GetConn(ids[i], ids[j]) - if i == centerIndex || j == centerIndex { - if c == nil { - t.Errorf("nodes %v and %v are not connected, but they should be", i, j) - } - } else { - if c != nil { - t.Errorf("nodes %v and %v are connected, but they should not be", i, j) - } - } - } - } -} diff --git a/p2p/transport_test.go b/p2p/transport_test.go index 24e06c5a06..01695cd3af 100644 --- a/p2p/transport_test.go +++ b/p2p/transport_test.go @@ -24,7 +24,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/p2p/simulations/pipes" + "github.com/ethereum/go-ethereum/p2p/pipes" ) func TestProtocolHandshake(t *testing.T) { diff --git a/params/config.go b/params/config.go index faa3178639..6790e99eea 100644 --- a/params/config.go +++ b/params/config.go @@ -65,8 +65,10 @@ var ( TerminalTotalDifficultyPassed: true, ShanghaiTime: newUint64(1681338455), CancunTime: newUint64(1710338135), + DepositContractAddress: common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"), Ethash: new(EthashConfig), } + // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. SepoliaChainConfig = &ChainConfig{ ChainID: big.NewInt(11155111), @@ -93,7 +95,7 @@ var ( Ethash: new(EthashConfig), } - // just for prysm compile pass + // just for prysm compile pass // GoerliChainConfig contains the chain parameters to run a node on the Görli test network. GoerliChainConfig = &ChainConfig{ ChainID: big.NewInt(5), @@ -537,8 +539,12 @@ type ChainConfig struct { // TerminalTotalDifficultyPassed is a flag specifying that the network already // passed the terminal total difficulty. Its purpose is to disable legacy sync // even without having seen the TTD locally (safer long term). + // + // TODO(karalabe): Drop this field eventually (always assuming PoS mode) TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"` + DepositContractAddress common.Address `json:"depositContractAddress,omitempty"` + RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated) NielsBlock *big.Int `json:"nielsBlock,omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated) MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated) @@ -552,6 +558,7 @@ type ChainConfig struct { PlatoBlock *big.Int `json:"platoBlock,omitempty"` // platoBlock switch block (nil = no fork, 0 = already activated) HertzBlock *big.Int `json:"hertzBlock,omitempty"` // hertzBlock switch block (nil = no fork, 0 = already activated) HertzfixBlock *big.Int `json:"hertzfixBlock,omitempty"` // hertzfixBlock switch block (nil = no fork, 0 = already activated) + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -562,7 +569,7 @@ type ChainConfig struct { type EthashConfig struct{} // String implements the stringer interface, returning the consensus engine details. -func (c *EthashConfig) String() string { +func (c EthashConfig) String() string { return "ethash" } @@ -573,8 +580,8 @@ type CliqueConfig struct { } // String implements the stringer interface, returning the consensus engine details. -func (c *CliqueConfig) String() string { - return "clique" +func (c CliqueConfig) String() string { + return fmt.Sprintf("clique(period: %d, epoch: %d)", c.Period, c.Epoch) } // ParliaConfig is the consensus engine configs for proof-of-staked-authority based sealing. @@ -961,7 +968,7 @@ func (c *ChainConfig) IsOnFeynmanFix(currentBlockNumber *big.Int, lastBlockTime return !c.IsFeynmanFix(lastBlockNumber, lastBlockTime) && c.IsFeynmanFix(currentBlockNumber, currentBlockTime) } -// IsCancun returns whether num is either equal to the Cancun fork time or greater. +// IsCancun returns whether time is either equal to the Cancun fork time or greater. func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.CancunTime, time) } @@ -1013,16 +1020,21 @@ func (c *ChainConfig) IsOnPascal(currentBlockNumber *big.Int, lastBlockTime uint return !c.IsPascal(lastBlockNumber, lastBlockTime) && c.IsPascal(currentBlockNumber, currentBlockTime) } -// IsPrague returns whether num is either equal to the Prague fork time or greater. +// IsPrague returns whether time is either equal to the Prague fork time or greater. func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) } -// IsVerkle returns whether num is either equal to the Verkle fork time or greater. +// IsVerkle returns whether time is either equal to the Verkle fork time or greater. func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) } +// IsEIP4762 returns whether eip 4762 has been activated at given block. +func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool { + return c.IsVerkle(num, time) +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { @@ -1395,9 +1407,11 @@ func (err *ConfigCompatError) Error() string { return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) } - if err.StoredTime == nil { + if err.StoredTime == nil && err.NewTime == nil { + return "" + } else if err.StoredTime == nil && err.NewTime != nil { return fmt.Sprintf("mismatching %s in database (have timestamp nil, want timestamp %d, rewindto timestamp %d)", err.What, *err.NewTime, err.RewindToTime) - } else if err.NewTime == nil { + } else if err.StoredTime != nil && err.NewTime == nil { return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp nil, rewindto timestamp %d)", err.What, *err.StoredTime, err.RewindToTime) } return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, *err.StoredTime, *err.NewTime, err.RewindToTime) @@ -1411,6 +1425,7 @@ func (err *ConfigCompatError) Error() string { type Rules struct { ChainID *big.Int IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool + IsEIP2929, IsEIP4762 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge bool @@ -1433,6 +1448,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules } // disallow setting Merge out of order isMerge = isMerge && c.IsLondon(num) + isVerkle := isMerge && c.IsVerkle(num, timestamp) return Rules{ ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), @@ -1444,6 +1460,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsBerlin: c.IsBerlin(num), + IsEIP2929: c.IsBerlin(num) && !isVerkle, IsLondon: c.IsLondon(num), IsMerge: isMerge, IsNano: c.IsNano(num), @@ -1462,5 +1479,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsPascal: c.IsPascal(num, timestamp), IsPrague: c.IsPrague(num, timestamp), IsVerkle: c.IsVerkle(num, timestamp), + IsEIP4762: isVerkle, } } diff --git a/params/config_test.go b/params/config_test.go index bf8ce2fc5e..fa444a1d0b 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common/math" + "github.com/stretchr/testify/require" ) func TestCheckCompatible(t *testing.T) { @@ -137,3 +138,20 @@ func TestConfigRules(t *testing.T) { t.Errorf("expected %v to be shanghai", stamp) } } + +func TestTimestampCompatError(t *testing.T) { + require.Equal(t, new(ConfigCompatError).Error(), "") + + errWhat := "Shanghai fork timestamp" + require.Equal(t, newTimestampCompatError(errWhat, nil, newUint64(1681338455)).Error(), + "mismatching Shanghai fork timestamp in database (have timestamp nil, want timestamp 1681338455, rewindto timestamp 1681338454)") + + require.Equal(t, newTimestampCompatError(errWhat, newUint64(1681338455), nil).Error(), + "mismatching Shanghai fork timestamp in database (have timestamp 1681338455, want timestamp nil, rewindto timestamp 1681338454)") + + require.Equal(t, newTimestampCompatError(errWhat, newUint64(1681338455), newUint64(600624000)).Error(), + "mismatching Shanghai fork timestamp in database (have timestamp 1681338455, want timestamp 600624000, rewindto timestamp 600623999)") + + require.Equal(t, newTimestampCompatError(errWhat, newUint64(0), newUint64(1681338455)).Error(), + "mismatching Shanghai fork timestamp in database (have timestamp 0, want timestamp 1681338455, rewindto timestamp 0)") +} diff --git a/params/network_params.go b/params/network_params.go index 4ab2a63a54..19683a6e5e 100644 --- a/params/network_params.go +++ b/params/network_params.go @@ -24,43 +24,12 @@ const ( // contains on the server side. BloomBitsBlocks uint64 = 4096 - // BloomBitsBlocksClient is the number of blocks a single bloom bit section vector - // contains on the light client side - BloomBitsBlocksClient uint64 = 32768 - // BloomConfirms is the number of confirmation blocks before a bloom section is // considered probably final and its rotated bits are calculated. BloomConfirms = 256 - // CHTFrequency is the block frequency for creating CHTs - CHTFrequency = 32768 - - // BloomTrieFrequency is the block frequency for creating BloomTrie on both - // server/client sides. - BloomTrieFrequency = 32768 - - // HelperTrieConfirmations is the number of confirmations before a client is expected - // to have the given HelperTrie available. - HelperTrieConfirmations = 2048 - - // HelperTrieProcessConfirmations is the number of confirmations before a HelperTrie - // is generated - HelperTrieProcessConfirmations = 256 - - // CheckpointFrequency is the block frequency for creating checkpoint - CheckpointFrequency = 32768 - - // CheckpointProcessConfirmations is the number before a checkpoint is generated - CheckpointProcessConfirmations = 256 - // StableStateThreshold is the reserve number of block state save to disk before delete ancientdb StableStateThreshold uint64 = 128 - - // LightImmutabilityThreshold is the number of blocks after which a header chain - // segment is considered immutable for light client(i.e. soft finality). It is used by - // the downloader as a hard limit against deep ancestors, by the blockchain against deep - // reorgs, by the light pruner as the pruning validity guarantee. - LightImmutabilityThreshold = 30000 ) var ( diff --git a/params/protocol_params.go b/params/protocol_params.go index a032f2759e..d86070983e 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -91,6 +91,7 @@ const ( LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction. Create2Gas uint64 = 32000 // Once per CREATE2 operation + CreateNGasEip4762 uint64 = 1000 // Once per CREATEn operations post-verkle SelfdestructRefundGas uint64 = 24000 // Refunded following a selfdestruct operation. MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. @@ -163,14 +164,14 @@ const ( Bn256PairingPerPointGasByzantium uint64 = 80000 // Byzantium per-point price for an elliptic curve pairing check Bn256PairingPerPointGasIstanbul uint64 = 34000 // Per-point price for an elliptic curve pairing check - Bls12381G1AddGas uint64 = 600 // Price for BLS12-381 elliptic curve G1 point addition - Bls12381G1MulGas uint64 = 12000 // Price for BLS12-381 elliptic curve G1 point scalar multiplication - Bls12381G2AddGas uint64 = 4500 // Price for BLS12-381 elliptic curve G2 point addition - Bls12381G2MulGas uint64 = 55000 // Price for BLS12-381 elliptic curve G2 point scalar multiplication - Bls12381PairingBaseGas uint64 = 115000 // Base gas price for BLS12-381 elliptic curve pairing check - Bls12381PairingPerPairGas uint64 = 23000 // Per-point pair gas price for BLS12-381 elliptic curve pairing check - Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation - Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation + Bls12381G1AddGas uint64 = 500 // Price for BLS12-381 elliptic curve G1 point addition + Bls12381G1MulGas uint64 = 12000 // Price for BLS12-381 elliptic curve G1 point scalar multiplication + Bls12381G2AddGas uint64 = 800 // Price for BLS12-381 elliptic curve G2 point addition + Bls12381G2MulGas uint64 = 45000 // Price for BLS12-381 elliptic curve G2 point scalar multiplication + Bls12381PairingBaseGas uint64 = 65000 // Base gas price for BLS12-381 elliptic curve pairing check + Bls12381PairingPerPairGas uint64 = 43000 // Per-point pair gas price for BLS12-381 elliptic curve pairing check + Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation + Bls12381MapG2Gas uint64 = 75000 // Gas price for BLS12-381 mapping field element to G2 operation P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price @@ -188,6 +189,8 @@ const ( BlobTxTargetBlobGasPerBlock = 3 * BlobTxBlobGasPerBlob // Target consumable blob gas for data blobs per block (for 1559-like pricing) MaxBlobGasPerBlock = 6 * BlobTxBlobGasPerBlob // Maximum consumable blob gas for data blobs per block + + HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. ) var ( @@ -212,6 +215,14 @@ var ( // BeaconRootsAddress is the address where historical beacon roots are stored as per EIP-4788 BeaconRootsAddress = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") + + // BeaconRootsCode is the code where historical beacon roots are stored as per EIP-4788 + BeaconRootsCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") + // SystemAddress is where the system-transaction is sent from as per EIP-4788 SystemAddress = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe") + // HistoryStorageAddress is where the historical block hashes are stored. + HistoryStorageAddress = common.HexToAddress("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e") + // HistoryStorageCode is the code with getters for historical block hashes. + HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500") ) diff --git a/core/blocks.go b/params/verkle_params.go similarity index 55% rename from core/blocks.go rename to params/verkle_params.go index f20ba4aaf2..93d4f7cd64 100644 --- a/core/blocks.go +++ b/params/verkle_params.go @@ -1,4 +1,4 @@ -// Copyright 2015 The go-ethereum Authors +// Copyright 2023 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,12 +14,23 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package params -import "github.com/ethereum/go-ethereum/common" +// Verkle tree EIP: costs associated to witness accesses +var ( + WitnessBranchReadCost uint64 = 1900 + WitnessChunkReadCost uint64 = 200 + WitnessBranchWriteCost uint64 = 3000 + WitnessChunkWriteCost uint64 = 500 + WitnessChunkFillCost uint64 = 6200 +) -// BadHashes represent a set of manually tracked bad hashes (usually hard forks) -var BadHashes = map[common.Hash]bool{ - common.HexToHash("05bef30ef572270f654746da22639a7a0c97dd97a7050b9e252391996aaeb689"): true, - common.HexToHash("7d05d08cbc596a2e5e4f13b80a743e53e09221b5323c3a61946b20873e58583f"): true, +// ClearVerkleWitnessCosts sets all witness costs to 0, which is necessary +// for historical block replay simulations. +func ClearVerkleWitnessCosts() { + WitnessBranchReadCost = 0 + WitnessChunkReadCost = 0 + WitnessBranchWriteCost = 0 + WitnessChunkWriteCost = 0 + WitnessChunkFillCost = 0 } diff --git a/rlp/decode.go b/rlp/decode.go index 9b17d2d810..0fbca243ee 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -158,17 +158,17 @@ func makeDecoder(typ reflect.Type, tags rlpstruct.Tags) (dec decoder, err error) switch { case typ == rawValueType: return decodeRawValue, nil - case typ.AssignableTo(reflect.PtrTo(bigInt)): + case typ.AssignableTo(reflect.PointerTo(bigInt)): return decodeBigInt, nil case typ.AssignableTo(bigInt): return decodeBigIntNoPtr, nil - case typ == reflect.PtrTo(u256Int): + case typ == reflect.PointerTo(u256Int): return decodeU256, nil case typ == u256Int: return decodeU256NoPtr, nil case kind == reflect.Ptr: return makePtrDecoder(typ, tags) - case reflect.PtrTo(typ).Implements(decoderInterface): + case reflect.PointerTo(typ).Implements(decoderInterface): return decodeDecoder, nil case isUint(kind): return decodeUint, nil @@ -262,7 +262,7 @@ func decodeU256(s *Stream, val reflect.Value) error { func makeListDecoder(typ reflect.Type, tag rlpstruct.Tags) (decoder, error) { etype := typ.Elem() - if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { + if etype.Kind() == reflect.Uint8 && !reflect.PointerTo(etype).Implements(decoderInterface) { if typ.Kind() == reflect.Array { return decodeByteArray, nil } @@ -474,7 +474,7 @@ func makeSimplePtrDecoder(etype reflect.Type, etypeinfo *typeinfo) decoder { // // This decoder is used for pointer-typed struct fields with struct tag "nil". func makeNilPtrDecoder(etype reflect.Type, etypeinfo *typeinfo, ts rlpstruct.Tags) decoder { - typ := reflect.PtrTo(etype) + typ := reflect.PointerTo(etype) nilPtr := reflect.Zero(typ) // Determine the value kind that results in nil pointer. @@ -1105,9 +1105,7 @@ func (s *Stream) readUint(size byte) (uint64, error) { return uint64(b), err default: buffer := s.uintbuf[:8] - for i := range buffer { - buffer[i] = 0 - } + clear(buffer) start := int(8 - size) if err := s.readFull(buffer[start:]); err != nil { return 0, err diff --git a/rlp/encode.go b/rlp/encode.go index ffb42b2997..3645bbfda0 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -141,17 +141,17 @@ func makeWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { switch { case typ == rawValueType: return writeRawValue, nil - case typ.AssignableTo(reflect.PtrTo(bigInt)): + case typ.AssignableTo(reflect.PointerTo(bigInt)): return writeBigIntPtr, nil case typ.AssignableTo(bigInt): return writeBigIntNoPtr, nil - case typ == reflect.PtrTo(u256Int): + case typ == reflect.PointerTo(u256Int): return writeU256IntPtr, nil case typ == u256Int: return writeU256IntNoPtr, nil case kind == reflect.Ptr: return makePtrWriter(typ, ts) - case reflect.PtrTo(typ).Implements(encoderInterface): + case reflect.PointerTo(typ).Implements(encoderInterface): return makeEncoderWriter(typ), nil case isUint(kind): return writeUint, nil diff --git a/rlp/iterator.go b/rlp/iterator.go index 6be574572e..95bd3f2582 100644 --- a/rlp/iterator.go +++ b/rlp/iterator.go @@ -23,7 +23,6 @@ type listIterator struct { } // NewListIterator creates an iterator for the (list) represented by data -// TODO: Consider removing this implementation, as it is no longer used. func NewListIterator(data RawValue) (*listIterator, error) { k, t, c, err := readKind(data) if err != nil { diff --git a/rlp/raw.go b/rlp/raw.go index 773aa7e614..879e3bfe5d 100644 --- a/rlp/raw.go +++ b/rlp/raw.go @@ -30,33 +30,33 @@ var rawValueType = reflect.TypeOf(RawValue{}) // StringSize returns the encoded size of a string. func StringSize(s string) uint64 { - switch { - case len(s) == 0: + switch n := len(s); n { + case 0: return 1 - case len(s) == 1: + case 1: if s[0] <= 0x7f { return 1 } else { return 2 } default: - return uint64(headsize(uint64(len(s))) + len(s)) + return uint64(headsize(uint64(n)) + n) } } // BytesSize returns the encoded size of a byte slice. func BytesSize(b []byte) uint64 { - switch { - case len(b) == 0: + switch n := len(b); n { + case 0: return 1 - case len(b) == 1: + case 1: if b[0] <= 0x7f { return 1 } else { return 2 } default: - return uint64(headsize(uint64(len(b))) + len(b)) + return uint64(headsize(uint64(n)) + n) } } @@ -105,18 +105,20 @@ func SplitUint64(b []byte) (x uint64, rest []byte, err error) { if err != nil { return 0, b, err } - switch { - case len(content) == 0: + switch n := len(content); n { + case 0: return 0, rest, nil - case len(content) == 1: + case 1: if content[0] == 0 { return 0, b, ErrCanonInt } return uint64(content[0]), rest, nil - case len(content) > 8: - return 0, b, errUintOverflow default: - x, err = readSize(content, byte(len(content))) + if n > 8 { + return 0, b, errUintOverflow + } + + x, err = readSize(content, byte(n)) if err != nil { return 0, b, ErrCanonInt } diff --git a/rlp/rlpgen/gen.go b/rlp/rlpgen/gen.go index 0c65864826..ff39874737 100644 --- a/rlp/rlpgen/gen.go +++ b/rlp/rlpgen/gen.go @@ -158,7 +158,7 @@ type op interface { // basicOp handles basic types bool, uint*, string. type basicOp struct { typ types.Type - writeMethod string // calle write the value + writeMethod string // EncoderBuffer writer method name writeArgType types.Type // parameter type of writeMethod decMethod string decResultType types.Type // return type of decMethod diff --git a/rlp/typecache.go b/rlp/typecache.go index 3e37c9d2fc..eebf4cd611 100644 --- a/rlp/typecache.go +++ b/rlp/typecache.go @@ -18,6 +18,7 @@ package rlp import ( "fmt" + "maps" "reflect" "sync" "sync/atomic" @@ -90,10 +91,7 @@ func (c *typeCache) generate(typ reflect.Type, tags rlpstruct.Tags) *typeinfo { } // Copy cur to next. - c.next = make(map[typekey]*typeinfo, len(cur)+1) - for k, v := range cur { - c.next[k] = v - } + c.next = maps.Clone(cur) // Generate. info := c.infoWhileGenerating(typ, tags) diff --git a/rlp/unsafe.go b/rlp/unsafe.go index 7218be45ad..10868caaf2 100644 --- a/rlp/unsafe.go +++ b/rlp/unsafe.go @@ -26,10 +26,5 @@ import ( // byteArrayBytes returns a slice of the byte array v. func byteArrayBytes(v reflect.Value, length int) []byte { - var s []byte - hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) //nolint:all //TODO - hdr.Data = v.UnsafeAddr() - hdr.Cap = length - hdr.Len = length - return s + return unsafe.Slice((*byte)(unsafe.Pointer(v.UnsafeAddr())), length) } diff --git a/rpc/client.go b/rpc/client.go index 7c680f1fa9..dcf3e8c3df 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -45,6 +45,7 @@ var ( const ( defaultDialTimeout = 10 * time.Second // used if context has no deadline subscribeTimeout = 10 * time.Second // overall timeout eth_subscribe, rpc_modules calls + unsubscribeTimeout = 10 * time.Second // timeout for *_unsubscribe calls ) const ( @@ -70,7 +71,7 @@ type BatchElem struct { // discarded. Result interface{} // Error is set if the server returns an error for this request, or if - // unmarshaling into Result fails. It is not set for I/O errors. + // unmarshalling into Result fails. It is not set for I/O errors. Error error } @@ -431,7 +432,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error { } // Wait for all responses to come back. - for n := 0; n < len(batchresp) && err == nil; n++ { + for n := 0; n < len(batchresp); n++ { resp := batchresp[n] if resp == nil { // Ignore null responses. These can happen for batches sent via HTTP. diff --git a/rpc/client_test.go b/rpc/client_test.go index ac02ad33cf..b7607adfce 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -253,6 +253,7 @@ func TestClientBatchRequestLimit(t *testing.T) { defer server.Stop() server.SetBatchLimits(2, 100000) client := DialInProc(server) + defer client.Close() batch := []BatchElem{ {Method: "foo"}, @@ -342,6 +343,7 @@ func testClientCancel(transport string, t *testing.T) { default: panic("unknown transport: " + transport) } + defer client.Close() // The actual test starts here. var ( @@ -516,6 +518,70 @@ func TestClientCloseUnsubscribeRace(t *testing.T) { } } +// unsubscribeBlocker will wait for the quit channel to process an unsubscribe +// request. +type unsubscribeBlocker struct { + ServerCodec + quit chan struct{} +} + +func (b *unsubscribeBlocker) readBatch() ([]*jsonrpcMessage, bool, error) { + msgs, batch, err := b.ServerCodec.readBatch() + for _, msg := range msgs { + if msg.isUnsubscribe() { + <-b.quit + } + } + return msgs, batch, err +} + +// TestUnsubscribeTimeout verifies that calling the client's Unsubscribe +// function will eventually timeout and not block forever in case the serve does +// not respond. +// It reproducers the issue https://github.com/ethereum/go-ethereum/issues/30156 +func TestUnsubscribeTimeout(t *testing.T) { + srv := NewServer() + srv.RegisterName("nftest", new(notificationTestService)) + + // Setup middleware to block on unsubscribe. + p1, p2 := net.Pipe() + blocker := &unsubscribeBlocker{ServerCodec: NewCodec(p1), quit: make(chan struct{})} + defer close(blocker.quit) + + // Serve the middleware. + go srv.ServeCodec(blocker, OptionMethodInvocation|OptionSubscriptions) + defer srv.Stop() + + // Create the client on the other end of the pipe. + cfg := new(clientConfig) + client, _ := newClient(context.Background(), cfg, func(context.Context) (ServerCodec, error) { + return NewCodec(p2), nil + }) + defer client.Close() + + // Start subscription. + sub, err := client.Subscribe(context.Background(), "nftest", make(chan int), "someSubscription", 1, 1) + if err != nil { + t.Fatalf("failed to subscribe: %v", err) + } + + // Now on a separate thread, attempt to unsubscribe. Since the middleware + // won't return, the function will only return if it times out on the request. + done := make(chan struct{}) + go func() { + sub.Unsubscribe() + done <- struct{}{} + }() + + // Wait for the timeout. If the expected time for the timeout elapses, the + // test is considered failed. + select { + case <-done: + case <-time.After(unsubscribeTimeout + 3*time.Second): + t.Fatalf("Unsubscribe did not return within %s", unsubscribeTimeout) + } +} + // unsubscribeRecorder collects the subscription IDs of *_unsubscribe calls. type unsubscribeRecorder struct { ServerCodec @@ -592,6 +658,7 @@ func TestClientSubscriptionChannelClose(t *testing.T) { srv.RegisterName("nftest", new(notificationTestService)) client, _ := Dial(wsURL) + defer client.Close() for i := 0; i < 100; i++ { ch := make(chan int, 100) @@ -708,7 +775,6 @@ func TestClientHTTP(t *testing.T) { errc = make(chan error, len(results)) wantResult = echoResult{"a", 1, new(echoArgs)} ) - defer client.Close() for i := range results { i := i go func() { diff --git a/rpc/handler.go b/rpc/handler.go index 8f799a41fb..24310a373e 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -17,8 +17,11 @@ package rpc import ( + "bytes" "context" "encoding/json" + "errors" + "fmt" "reflect" "strconv" "strings" @@ -331,7 +334,7 @@ func (h *handler) addRequestOp(op *requestOp) { } } -// removeRequestOps stops waiting for the given request IDs. +// removeRequestOp stops waiting for the given request IDs. func (h *handler) removeRequestOp(op *requestOp) { for _, id := range op.ids { delete(h.respWait, string(id)) @@ -395,7 +398,7 @@ func (h *handler) startCallProc(fn func(*callProc)) { }) } -// handleResponse processes method call responses. +// handleResponses processes method call responses. func (h *handler) handleResponses(batch []*jsonrpcMessage, handleCall func(*jsonrpcMessage)) { var resolvedops []*requestOp handleResp := func(msg *jsonrpcMessage) { @@ -475,8 +478,8 @@ func (h *handler) handleCallMsg(ctx *callProc, reqCtx context.Context, msg *json case msg.isCall(): resp := h.handleCall(ctx, msg) - var ctx []interface{} - ctx = append(ctx, "reqid", idForLog{msg.ID}, "duration", time.Since(start)) + var logctx []any + logctx = append(logctx, "reqid", idForLog{msg.ID}, "duration", time.Since(start)) if resp.Error != nil { xForward := reqCtx.Value("X-Forwarded-For") h.log.Warn("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start), "err", resp.Error.Message, "X-Forwarded-For", xForward) @@ -486,13 +489,13 @@ func (h *handler) handleCallMsg(ctx *callProc, reqCtx context.Context, msg *json accountBlacklistRpcCounter.Inc(1) log.Warn("blacklist account detected from direct rpc", "remoteAddr", h.conn.remoteAddr()) } - ctx = append(ctx, "err", resp.Error.Message) + logctx = append(logctx, "err", resp.Error.Message) if resp.Error.Data != nil { - ctx = append(ctx, "errdata", resp.Error.Data) + logctx = append(logctx, "errdata", formatErrorData(resp.Error.Data)) } - h.log.Warn("Served "+msg.Method, ctx...) + h.log.Warn("Served "+msg.Method, logctx...) } else { - h.log.Debug("Served "+msg.Method, ctx...) + h.log.Debug("Served "+msg.Method, logctx...) } return resp @@ -607,3 +610,33 @@ func (id idForLog) String() string { } return string(id.RawMessage) } + +var errTruncatedOutput = errors.New("truncated output") + +type limitedBuffer struct { + output []byte + limit int +} + +func (buf *limitedBuffer) Write(data []byte) (int, error) { + avail := max(buf.limit, len(buf.output)) + if len(data) < avail { + buf.output = append(buf.output, data...) + return len(data), nil + } + buf.output = append(buf.output, data[:avail]...) + return avail, errTruncatedOutput +} + +func formatErrorData(v any) string { + buf := limitedBuffer{limit: 1024} + err := json.NewEncoder(&buf).Encode(v) + switch { + case err == nil: + return string(bytes.TrimRight(buf.output, "\n")) + case errors.Is(err, errTruncatedOutput): + return fmt.Sprintf("%s... (truncated)", buf.output) + default: + return fmt.Sprintf("bad error data (err=%v)", err) + } +} diff --git a/rpc/http.go b/rpc/http.go index 14f998995b..14bd8ec0d8 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -236,7 +236,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos if _, err := buf.ReadFrom(resp.Body); err == nil { body = buf.Bytes() } - + resp.Body.Close() return nil, HTTPError{ Status: resp.Status, StatusCode: resp.StatusCode, diff --git a/rpc/ipc_unix.go b/rpc/ipc_unix.go index 33c1cad549..588bf62605 100644 --- a/rpc/ipc_unix.go +++ b/rpc/ipc_unix.go @@ -25,14 +25,16 @@ import ( "net" "os" "path/filepath" + "syscall" "github.com/ethereum/go-ethereum/log" ) const ( - // On Linux, sun_path is 108 bytes in size - // see http://man7.org/linux/man-pages/man7/unix.7.html - maxPathSize = int(108) + // The limit of unix domain socket path diverse between OS, on Darwin it's 104 bytes + // but on Linux it's 108 byte, so we should depend on syscall.RawSockaddrUnix's + // definition dynamically + maxPathSize = len(syscall.RawSockaddrUnix{}.Path) ) // ipcListen will create a Unix socket on the given endpoint. diff --git a/rpc/json.go b/rpc/json.go index 5557a80760..e932389d17 100644 --- a/rpc/json.go +++ b/rpc/json.go @@ -266,7 +266,7 @@ func (c *jsonCodec) close() { }) } -// Closed returns a channel which will be closed when Close is called +// closed returns a channel which will be closed when Close is called func (c *jsonCodec) closed() <-chan interface{} { return c.closeCh } diff --git a/rpc/server.go b/rpc/server.go index bea7bd9e9b..17c3bd82bc 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -18,7 +18,9 @@ package rpc import ( "context" + "errors" "io" + "net" "sync" "sync/atomic" @@ -88,7 +90,7 @@ func (s *Server) SetHTTPBodyLimit(limit int) { } // RegisterName creates a service for the given receiver type under the given name. When no -// methods on the given receiver match the criteria to be either a RPC method or a +// methods on the given receiver match the criteria to be either an RPC method or a // subscription an error is returned. Otherwise a new service is created and added to the // service collection this server provides to clients. func (s *Server) RegisterName(name string, receiver interface{}) error { @@ -151,8 +153,8 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { reqs, batch, err := codec.readBatch() if err != nil { - if err != io.EOF { - resp := errorMessage(&invalidMessageError{"parse error"}) + if msg := messageForReadError(err); msg != "" { + resp := errorMessage(&invalidMessageError{msg}) codec.writeJSON(ctx, resp, true) } return @@ -164,6 +166,20 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { } } +func messageForReadError(err error) string { + var netErr net.Error + if errors.As(err, &netErr) { + if netErr.Timeout() { + return "read timeout" + } else { + return "read error" + } + } else if err != io.EOF { + return "parse error" + } + return "" +} + // Stop stops reading new requests, waits for stopPendingRequestTimeout to allow pending // requests to finish, then closes all codecs which will cancel pending requests and // subscriptions. diff --git a/rpc/service.go b/rpc/service.go index a180b8db93..d50090e9fb 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -110,7 +110,7 @@ func (r *serviceRegistry) subscription(service, name string) *callback { } // suitableCallbacks iterates over the methods of the given type. It determines if a method -// satisfies the criteria for a RPC callback or a subscription callback and adds it to the +// satisfies the criteria for an RPC callback or a subscription callback and adds it to the // collection of callbacks. See server documentation for a summary of these criteria. func suitableCallbacks(receiver reflect.Value) map[string]*callback { typ := receiver.Type() @@ -227,7 +227,7 @@ func isSubscriptionType(t reflect.Type) bool { return t == subscriptionType } -// isPubSub tests whether the given method has as as first argument a context.Context and +// isPubSub tests whether the given method's first argument is a context.Context and // returns the pair (Subscription, error). func isPubSub(methodType reflect.Type) bool { // numIn(0) is the receiver type diff --git a/rpc/subscription.go b/rpc/subscription.go index 9cb0727547..9e400c8b60 100644 --- a/rpc/subscription.go +++ b/rpc/subscription.go @@ -97,7 +97,7 @@ func NotifierFromContext(ctx context.Context) (*Notifier, bool) { return n, ok } -// Notifier is tied to a RPC connection that supports subscriptions. +// Notifier is tied to an RPC connection that supports subscriptions. // Server callbacks use the notifier to send notifications. type Notifier struct { h *handler @@ -145,12 +145,6 @@ func (n *Notifier) Notify(id ID, data any) error { return nil } -// Closed returns a channel that is closed when the RPC connection is closed. -// Deprecated: use subscription error channel -func (n *Notifier) Closed() <-chan interface{} { - return n.h.conn.closed() -} - // takeSubscription returns the subscription (if one has been created). No subscription can // be created after this call. func (n *Notifier) takeSubscription() *Subscription { @@ -377,5 +371,8 @@ func (sub *ClientSubscription) unmarshal(result json.RawMessage) (interface{}, e func (sub *ClientSubscription) requestUnsubscribe() error { var result interface{} - return sub.client.Call(&result, sub.namespace+unsubscribeMethodSuffix, sub.subid) + ctx, cancel := context.WithTimeout(context.Background(), unsubscribeTimeout) + defer cancel() + err := sub.client.CallContext(ctx, &result, sub.namespace+unsubscribeMethodSuffix, sub.subid) + return err } diff --git a/rpc/subscription_test.go b/rpc/subscription_test.go index 3a131c8e6b..ab40ab169f 100644 --- a/rpc/subscription_test.go +++ b/rpc/subscription_test.go @@ -235,10 +235,10 @@ func (c *mockConn) writeJSON(ctx context.Context, msg interface{}, isError bool) return c.enc.Encode(msg) } -// Closed returns a channel which is closed when the connection is closed. +// closed returns a channel which is closed when the connection is closed. func (c *mockConn) closed() <-chan interface{} { return nil } -// RemoteAddr returns the peer address of the connection. +// remoteAddr returns the peer address of the connection. func (c *mockConn) remoteAddr() string { return "" } // BenchmarkNotify benchmarks the performance of notifying a subscription. @@ -267,13 +267,9 @@ func TestNotify(t *testing.T) { sub: &Subscription{ID: id}, activated: true, } - msg := &types.Header{ - ParentHash: common.HexToHash("0x01"), - Number: big.NewInt(100), - } - notifier.Notify(id, msg) + notifier.Notify(id, "hello") have := strings.TrimSpace(out.String()) - want := `{"jsonrpc":"2.0","method":"_subscription","params":{"subscription":"test","result":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000001","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":null,"number":"0x64","gasLimit":"0x0","gasUsed":"0x0","timestamp":"0x0","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":null,"withdrawalsRoot":null,"blobGasUsed":null,"excessBlobGas":null,"parentBeaconBlockRoot":null,"hash":"0xe5fb877dde471b45b9742bb4bb4b3d74a761e2fb7cb849a3d2b687eed90fb604"}}}` + want := `{"jsonrpc":"2.0","method":"_subscription","params":{"subscription":"test","result":"hello"}}` if have != want { t.Errorf("have:\n%v\nwant:\n%v\n", have, want) } diff --git a/rpc/testservice_test.go b/rpc/testservice_test.go index 7d873af667..69199e21b7 100644 --- a/rpc/testservice_test.go +++ b/rpc/testservice_test.go @@ -195,10 +195,7 @@ func (s *notificationTestService) SomeSubscription(ctx context.Context, n, val i return } } - select { - case <-notifier.Closed(): - case <-subscription.Err(): - } + <-subscription.Err() if s.unsubscribed != nil { s.unsubscribed <- string(subscription.ID) } diff --git a/rpc/types.go b/rpc/types.go index d124081786..2e53174b87 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -38,7 +38,7 @@ type API struct { } // ServerCodec implements reading, parsing and writing RPC messages for the server side of -// a RPC session. Implementations must be go-routine safe since the codec can be called in +// an RPC session. Implementations must be go-routine safe since the codec can be called in // multiple go-routines concurrently. type ServerCodec interface { peerInfo() PeerInfo diff --git a/rpc/types_test.go b/rpc/types_test.go index 617f441d91..2fa74f9899 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -45,9 +45,11 @@ func TestBlockNumberJSONUnmarshal(t *testing.T) { 11: {`"pending"`, false, PendingBlockNumber}, 12: {`"latest"`, false, LatestBlockNumber}, 13: {`"earliest"`, false, EarliestBlockNumber}, - 14: {`someString`, true, BlockNumber(0)}, - 15: {`""`, true, BlockNumber(0)}, - 16: {``, true, BlockNumber(0)}, + 14: {`"safe"`, false, SafeBlockNumber}, + 15: {`"finalized"`, false, FinalizedBlockNumber}, + 16: {`someString`, true, BlockNumber(0)}, + 17: {`""`, true, BlockNumber(0)}, + 18: {``, true, BlockNumber(0)}, } for i, test := range tests { @@ -87,18 +89,22 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { 11: {`"pending"`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, 12: {`"latest"`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, 13: {`"earliest"`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, - 14: {`someString`, true, BlockNumberOrHash{}}, - 15: {`""`, true, BlockNumberOrHash{}}, - 16: {``, true, BlockNumberOrHash{}}, - 17: {`"0x0000000000000000000000000000000000000000000000000000000000000000"`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 18: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 19: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":false}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 20: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":true}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), true)}, - 21: {`{"blockNumber":"0x1"}`, false, BlockNumberOrHashWithNumber(1)}, - 22: {`{"blockNumber":"pending"}`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, - 23: {`{"blockNumber":"latest"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, - 24: {`{"blockNumber":"earliest"}`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, - 25: {`{"blockNumber":"0x1", "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, true, BlockNumberOrHash{}}, + 14: {`"safe"`, false, BlockNumberOrHashWithNumber(SafeBlockNumber)}, + 15: {`"finalized"`, false, BlockNumberOrHashWithNumber(FinalizedBlockNumber)}, + 16: {`someString`, true, BlockNumberOrHash{}}, + 17: {`""`, true, BlockNumberOrHash{}}, + 18: {``, true, BlockNumberOrHash{}}, + 19: {`"0x0000000000000000000000000000000000000000000000000000000000000000"`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 20: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 21: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":false}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 22: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":true}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), true)}, + 23: {`{"blockNumber":"0x1"}`, false, BlockNumberOrHashWithNumber(1)}, + 24: {`{"blockNumber":"pending"}`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, + 25: {`{"blockNumber":"latest"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, + 26: {`{"blockNumber":"earliest"}`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, + 27: {`{"blockNumber":"safe"}`, false, BlockNumberOrHashWithNumber(SafeBlockNumber)}, + 28: {`{"blockNumber":"finalized"}`, false, BlockNumberOrHashWithNumber(FinalizedBlockNumber)}, + 29: {`{"blockNumber":"0x1", "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, true, BlockNumberOrHash{}}, } for i, test := range tests { @@ -133,6 +139,8 @@ func TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal(t *testing.T) { {"pending", int64(PendingBlockNumber)}, {"latest", int64(LatestBlockNumber)}, {"earliest", int64(EarliestBlockNumber)}, + {"safe", int64(SafeBlockNumber)}, + {"finalized", int64(FinalizedBlockNumber)}, } for _, test := range tests { test := test @@ -160,6 +168,8 @@ func TestBlockNumberOrHash_StringAndUnmarshal(t *testing.T) { BlockNumberOrHashWithNumber(PendingBlockNumber), BlockNumberOrHashWithNumber(LatestBlockNumber), BlockNumberOrHashWithNumber(EarliestBlockNumber), + BlockNumberOrHashWithNumber(SafeBlockNumber), + BlockNumberOrHashWithNumber(FinalizedBlockNumber), BlockNumberOrHashWithNumber(32), BlockNumberOrHashWithHash(common.Hash{0xaa}, false), } diff --git a/rpc/websocket.go b/rpc/websocket.go index 538e53a31b..9f67caf859 100644 --- a/rpc/websocket.go +++ b/rpc/websocket.go @@ -122,6 +122,10 @@ func (e wsHandshakeError) Error() string { return s } +func (e wsHandshakeError) Unwrap() error { + return e.err +} + func originIsAllowed(allowedOrigins mapset.Set[string], browserOrigin string) bool { it := allowedOrigins.Iterator() for origin := range it.C { diff --git a/rpc/websocket_test.go b/rpc/websocket_test.go index 8d2bd9d802..c6ea325d29 100644 --- a/rpc/websocket_test.go +++ b/rpc/websocket_test.go @@ -187,6 +187,7 @@ func TestWebsocketPeerInfo(t *testing.T) { if err != nil { t.Fatal(err) } + defer c.Close() // Request peer information. var connInfo PeerInfo @@ -273,6 +274,7 @@ func TestClientWebsocketLargeMessage(t *testing.T) { if err != nil { t.Fatal(err) } + defer c.Close() var r string if err := c.Call(&r, "test_largeResp"); err != nil { diff --git a/signer/core/api.go b/signer/core/api.go index a32f24cb18..23ddcd0a20 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -590,7 +590,10 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args apitypes.SendTxA return nil, err } // Convert fields into a real transaction - var unsignedTx = result.Transaction.ToTransaction() + unsignedTx, err := result.Transaction.ToTransaction() + if err != nil { + return nil, err + } // Get the password for the transaction pw, err := api.lookupOrQueryPassword(acc.Address, "Account password", fmt.Sprintf("Please enter the password for account %s", acc.Address.String())) diff --git a/signer/core/apitypes/signed_data_internal_test.go b/signer/core/apitypes/signed_data_internal_test.go index 8067893c21..8b4a839c1d 100644 --- a/signer/core/apitypes/signed_data_internal_test.go +++ b/signer/core/apitypes/signed_data_internal_test.go @@ -240,3 +240,49 @@ func TestConvertAddressDataToSlice(t *testing.T) { t.Fatal(err) } } + +func TestTypedDataArrayValidate(t *testing.T) { + t.Parallel() + + typedData := TypedData{ + Types: Types{ + "BulkOrder": []Type{ + // Should be able to accept fixed size arrays + {Name: "tree", Type: "OrderComponents[2][2]"}, + }, + "OrderComponents": []Type{ + {Name: "offerer", Type: "address"}, + {Name: "amount", Type: "uint8"}, + }, + "EIP712Domain": []Type{ + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint8"}, + {Name: "verifyingContract", Type: "address"}, + }, + }, + PrimaryType: "BulkOrder", + Domain: TypedDataDomain{ + VerifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", + }, + Message: TypedDataMessage{}, + } + + if err := typedData.validate(); err != nil { + t.Errorf("expected typed data to pass validation, got: %v", err) + } + + // Should be able to accept dynamic arrays + typedData.Types["BulkOrder"][0].Type = "OrderComponents[]" + + if err := typedData.validate(); err != nil { + t.Errorf("expected typed data to pass validation, got: %v", err) + } + + // Should be able to accept standard types + typedData.Types["BulkOrder"][0].Type = "OrderComponents" + + if err := typedData.validate(); err != nil { + t.Errorf("expected typed data to pass validation, got: %v", err) + } +} diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index af2c2cb723..fc503193cd 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -18,12 +18,14 @@ package apitypes import ( "bytes" + "crypto/sha256" "encoding/json" "errors" "fmt" "math/big" "reflect" "regexp" + "slices" "sort" "strconv" "strings" @@ -34,9 +36,11 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/holiman/uint256" ) -var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\])?$`) +var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\d*\])*$`) type ValidationInfo struct { Typ string `json:"type"` @@ -63,9 +67,9 @@ func (vs *ValidationMessages) Info(msg string) { } // GetWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present -func (v *ValidationMessages) GetWarnings() error { +func (vs *ValidationMessages) GetWarnings() error { var messages []string - for _, msg := range v.Messages { + for _, msg := range vs.Messages { if msg.Typ == WARN || msg.Typ == CRIT { messages = append(messages, msg.Message) } @@ -92,12 +96,21 @@ type SendTxArgs struct { // We accept "data" and "input" for backwards-compatibility reasons. // "input" is the newer name and should be preferred by clients. // Issue detail: https://github.com/ethereum/go-ethereum/issues/15628 - Data *hexutil.Bytes `json:"data"` + Data *hexutil.Bytes `json:"data,omitempty"` Input *hexutil.Bytes `json:"input,omitempty"` // For non-legacy transactions AccessList *types.AccessList `json:"accessList,omitempty"` ChainID *hexutil.Big `json:"chainId,omitempty"` + + // For BlobTxType + BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` + BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + + // For BlobTxType transactions with blob sidecar + Blobs []kzg4844.Blob `json:"blobs,omitempty"` + Commitments []kzg4844.Commitment `json:"commitments,omitempty"` + Proofs []kzg4844.Proof `json:"proofs,omitempty"` } func (args SendTxArgs) String() string { @@ -108,24 +121,56 @@ func (args SendTxArgs) String() string { return err.Error() } +// data retrieves the transaction calldata. Input field is preferred. +func (args *SendTxArgs) data() []byte { + if args.Input != nil { + return *args.Input + } + if args.Data != nil { + return *args.Data + } + return nil +} + // ToTransaction converts the arguments to a transaction. -func (args *SendTxArgs) ToTransaction() *types.Transaction { +func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) { // Add the To-field, if specified var to *common.Address if args.To != nil { dstAddr := args.To.Address() to = &dstAddr } - - var input []byte - if args.Input != nil { - input = *args.Input - } else if args.Data != nil { - input = *args.Data + if err := args.validateTxSidecar(); err != nil { + return nil, err } - var data types.TxData switch { + case args.BlobHashes != nil: + al := types.AccessList{} + if args.AccessList != nil { + al = *args.AccessList + } + data = &types.BlobTx{ + To: *to, + ChainID: uint256.MustFromBig((*big.Int)(args.ChainID)), + Nonce: uint64(args.Nonce), + Gas: uint64(args.Gas), + GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)), + GasTipCap: uint256.MustFromBig((*big.Int)(args.MaxPriorityFeePerGas)), + Value: uint256.MustFromBig((*big.Int)(&args.Value)), + Data: args.data(), + AccessList: al, + BlobHashes: args.BlobHashes, + BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)), + } + if args.Blobs != nil { + data.(*types.BlobTx).Sidecar = &types.BlobTxSidecar{ + Blobs: args.Blobs, + Commitments: args.Commitments, + Proofs: args.Proofs, + } + } + case args.MaxFeePerGas != nil: al := types.AccessList{} if args.AccessList != nil { @@ -139,7 +184,7 @@ func (args *SendTxArgs) ToTransaction() *types.Transaction { GasFeeCap: (*big.Int)(args.MaxFeePerGas), GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), Value: (*big.Int)(&args.Value), - Data: input, + Data: args.data(), AccessList: al, } case args.AccessList != nil: @@ -150,7 +195,7 @@ func (args *SendTxArgs) ToTransaction() *types.Transaction { Gas: uint64(args.Gas), GasPrice: (*big.Int)(args.GasPrice), Value: (*big.Int)(&args.Value), - Data: input, + Data: args.data(), AccessList: *args.AccessList, } default: @@ -160,10 +205,81 @@ func (args *SendTxArgs) ToTransaction() *types.Transaction { Gas: uint64(args.Gas), GasPrice: (*big.Int)(args.GasPrice), Value: (*big.Int)(&args.Value), - Data: input, + Data: args.data(), + } + } + + return types.NewTx(data), nil +} + +// validateTxSidecar validates blob data, if present +func (args *SendTxArgs) validateTxSidecar() error { + // No blobs, we're done. + if args.Blobs == nil { + return nil + } + + n := len(args.Blobs) + // Assume user provides either only blobs (w/o hashes), or + // blobs together with commitments and proofs. + if args.Commitments == nil && args.Proofs != nil { + return errors.New(`blob proofs provided while commitments were not`) + } else if args.Commitments != nil && args.Proofs == nil { + return errors.New(`blob commitments provided while proofs were not`) + } + + // len(blobs) == len(commitments) == len(proofs) == len(hashes) + if args.Commitments != nil && len(args.Commitments) != n { + return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n) + } + if args.Proofs != nil && len(args.Proofs) != n { + return fmt.Errorf("number of blobs and proofs mismatch (have=%d, want=%d)", len(args.Proofs), n) + } + if args.BlobHashes != nil && len(args.BlobHashes) != n { + return fmt.Errorf("number of blobs and hashes mismatch (have=%d, want=%d)", len(args.BlobHashes), n) + } + + if args.Commitments == nil { + // Generate commitment and proof. + commitments := make([]kzg4844.Commitment, n) + proofs := make([]kzg4844.Proof, n) + for i, b := range args.Blobs { + c, err := kzg4844.BlobToCommitment(&b) + if err != nil { + return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err) + } + commitments[i] = c + p, err := kzg4844.ComputeBlobProof(&b, c) + if err != nil { + return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) + } + proofs[i] = p } + args.Commitments = commitments + args.Proofs = proofs + } else { + for i, b := range args.Blobs { + if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil { + return fmt.Errorf("failed to verify blob proof: %v", err) + } + } + } + + hashes := make([]common.Hash, n) + hasher := sha256.New() + for i, c := range args.Commitments { + hashes[i] = kzg4844.CalcBlobHashV1(hasher, &c) } - return types.NewTx(data) + if args.BlobHashes != nil { + for i, h := range hashes { + if h != args.BlobHashes[i] { + return fmt.Errorf("blob hash verification failed (have=%s, want=%s)", args.BlobHashes[i], h) + } + } + } else { + args.BlobHashes = hashes + } + return nil } type SigFormat struct { @@ -220,8 +336,9 @@ func (t *Type) isArray() bool { // typeName returns the canonical name of the type. If the type is 'Person[]', then // this method returns 'Person' func (t *Type) typeName() string { - if strings.HasSuffix(t.Type, "[]") { - return strings.TrimSuffix(t.Type, "[]") + if strings.Contains(t.Type, "[") { + re := regexp.MustCompile(`\[\d*\]`) + return re.ReplaceAllString(t.Type, "") } return t.Type } @@ -275,16 +392,8 @@ func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage // Dependencies returns an array of custom types ordered by their hierarchical reference tree func (typedData *TypedData) Dependencies(primaryType string, found []string) []string { primaryType = strings.TrimSuffix(primaryType, "[]") - includes := func(arr []string, str string) bool { - for _, obj := range arr { - if obj == str { - return true - } - } - return false - } - if includes(found, primaryType) { + if slices.Contains(found, primaryType) { return found } if typedData.Types[primaryType] == nil { @@ -293,7 +402,7 @@ func (typedData *TypedData) Dependencies(primaryType string, found []string) []s found = append(found, primaryType) for _, field := range typedData.Types[primaryType] { for _, dep := range typedData.Dependencies(field.Type, found) { - if !includes(found, dep) { + if !slices.Contains(found, dep) { found = append(found, dep) } } @@ -708,7 +817,7 @@ func formatPrimitiveValue(encType string, encValue interface{}) (string, error) return "", fmt.Errorf("unhandled type %v", encType) } -// Validate checks if the types object is conformant to the specs +// validate checks if the types object is conformant to the specs func (t Types) validate() error { for typeKey, typeArr := range t { if len(typeKey) == 0 { @@ -739,39 +848,35 @@ func (t Types) validate() error { return nil } -// Checks if the primitive value is valid -func isPrimitiveTypeValid(primitiveType string) bool { - if primitiveType == "address" || - primitiveType == "address[]" || - primitiveType == "bool" || - primitiveType == "bool[]" || - primitiveType == "string" || - primitiveType == "string[]" || - primitiveType == "bytes" || - primitiveType == "bytes[]" || - primitiveType == "int" || - primitiveType == "int[]" || - primitiveType == "uint" || - primitiveType == "uint[]" { - return true +var validPrimitiveTypes = map[string]struct{}{} + +// build the set of valid primitive types +func init() { + // Types those are trivially valid + for _, t := range []string{ + "address", "address[]", "bool", "bool[]", "string", "string[]", + "bytes", "bytes[]", "int", "int[]", "uint", "uint[]", + } { + validPrimitiveTypes[t] = struct{}{} } // For 'bytesN', 'bytesN[]', we allow N from 1 to 32 for n := 1; n <= 32; n++ { - // e.g. 'bytes28' or 'bytes28[]' - if primitiveType == fmt.Sprintf("bytes%d", n) || primitiveType == fmt.Sprintf("bytes%d[]", n) { - return true - } + validPrimitiveTypes[fmt.Sprintf("bytes%d", n)] = struct{}{} + validPrimitiveTypes[fmt.Sprintf("bytes%d[]", n)] = struct{}{} } // For 'intN','intN[]' and 'uintN','uintN[]' we allow N in increments of 8, from 8 up to 256 for n := 8; n <= 256; n += 8 { - if primitiveType == fmt.Sprintf("int%d", n) || primitiveType == fmt.Sprintf("int%d[]", n) { - return true - } - if primitiveType == fmt.Sprintf("uint%d", n) || primitiveType == fmt.Sprintf("uint%d[]", n) { - return true - } + validPrimitiveTypes[fmt.Sprintf("int%d", n)] = struct{}{} + validPrimitiveTypes[fmt.Sprintf("int%d[]", n)] = struct{}{} + validPrimitiveTypes[fmt.Sprintf("uint%d", n)] = struct{}{} + validPrimitiveTypes[fmt.Sprintf("uint%d[]", n)] = struct{}{} } - return false +} + +// Checks if the primitive value is valid +func isPrimitiveTypeValid(primitiveType string) bool { + _, ok := validPrimitiveTypes[primitiveType] + return ok } // validate checks if the given domain is valid, i.e. contains at least diff --git a/signer/core/apitypes/types_test.go b/signer/core/apitypes/types_test.go index b5aa3d1e93..7ea32f298c 100644 --- a/signer/core/apitypes/types_test.go +++ b/signer/core/apitypes/types_test.go @@ -16,7 +16,16 @@ package apitypes -import "testing" +import ( + "crypto/sha256" + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/holiman/uint256" +) func TestIsPrimitive(t *testing.T) { t.Parallel() @@ -39,3 +48,96 @@ func TestIsPrimitive(t *testing.T) { } } } + +func TestTxArgs(t *testing.T) { + for i, tc := range []struct { + data []byte + want common.Hash + wantType uint8 + }{ + { + data: []byte(`{"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","accessList":[],"blobVersionedHashes":["0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"],"chainId":"0x7","gas":"0x124f8","gasPrice":"0x693d4ca8","input":"0x","maxFeePerBlobGas":"0x3b9aca00","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","nonce":"0x0","r":"0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1","s":"0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","type":"0x1","v":"0x0","value":"0x0","yParity":"0x0"}`), + want: common.HexToHash("0x7d53234acc11ac5b5948632c901a944694e228795782f511887d36fd76ff15c4"), + wantType: types.BlobTxType, + }, + { + // on input, we don't read the type, but infer the type from the arguments present + data: []byte(`{"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","accessList":[],"chainId":"0x7","gas":"0x124f8","gasPrice":"0x693d4ca8","input":"0x","maxFeePerBlobGas":"0x3b9aca00","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","nonce":"0x0","r":"0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1","s":"0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","type":"0x12","v":"0x0","value":"0x0","yParity":"0x0"}`), + want: common.HexToHash("0x7919e2b0b9b543cb87a137b6ff66491ec7ae937cb88d3c29db4d9b28073dce53"), + wantType: types.DynamicFeeTxType, + }, + } { + var txArgs SendTxArgs + if err := json.Unmarshal(tc.data, &txArgs); err != nil { + t.Fatal(err) + } + tx, err := txArgs.ToTransaction() + if err != nil { + t.Fatal(err) + } + if have := tx.Type(); have != tc.wantType { + t.Errorf("test %d, have type %d, want type %d", i, have, tc.wantType) + } + if have := tx.Hash(); have != tc.want { + t.Errorf("test %d: have %v, want %v", i, have, tc.want) + } + d2, err := json.Marshal(txArgs) + if err != nil { + t.Fatal(err) + } + var txArgs2 SendTxArgs + if err := json.Unmarshal(d2, &txArgs2); err != nil { + t.Fatal(err) + } + tx1, _ := txArgs.ToTransaction() + tx2, _ := txArgs2.ToTransaction() + if have, want := tx1.Hash(), tx2.Hash(); have != want { + t.Errorf("test %d: have %v, want %v", i, have, want) + } + } + /* + End to end testing: + + $ go run ./cmd/clef --advanced --suppress-bootwarn + + $ go run ./cmd/geth --nodiscover --maxpeers 0 --signer /home/user/.clef/clef.ipc console + + > tx={"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","gas":"0x124f8","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","value":"0x0","nonce":"0x0","input":"0x","accessList":[],"maxFeePerBlobGas":"0x3b9aca00","blobVersionedHashes":["0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"]} + > eth.signTransaction(tx) + */ +} + +func TestBlobTxs(t *testing.T) { + blob := kzg4844.Blob{0x1} + commitment, err := kzg4844.BlobToCommitment(&blob) + if err != nil { + t.Fatal(err) + } + proof, err := kzg4844.ComputeBlobProof(&blob, commitment) + if err != nil { + t.Fatal(err) + } + + hash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment) + b := &types.BlobTx{ + ChainID: uint256.NewInt(6), + Nonce: 8, + GasTipCap: uint256.NewInt(500), + GasFeeCap: uint256.NewInt(600), + Gas: 21000, + BlobFeeCap: uint256.NewInt(700), + BlobHashes: []common.Hash{hash}, + Value: uint256.NewInt(100), + Sidecar: &types.BlobTxSidecar{ + Blobs: []kzg4844.Blob{blob}, + Commitments: []kzg4844.Commitment{commitment}, + Proofs: []kzg4844.Proof{proof}, + }, + } + tx := types.NewTx(b) + data, err := json.Marshal(tx) + if err != nil { + t.Fatal(err) + } + t.Logf("tx %v", string(data)) +} diff --git a/signer/core/auditlog.go b/signer/core/auditlog.go index d2207c9eb8..78785a3b02 100644 --- a/signer/core/auditlog.go +++ b/signer/core/auditlog.go @@ -19,6 +19,7 @@ package core import ( "context" "encoding/json" + "log/slog" "os" "github.com/ethereum/go-ethereum/common" @@ -26,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/signer/core/apitypes" - "golang.org/x/exp/slog" ) type AuditLogger struct { diff --git a/signer/core/cliui.go b/signer/core/cliui.go index b1bd3206ed..e04077865d 100644 --- a/signer/core/cliui.go +++ b/signer/core/cliui.go @@ -128,7 +128,7 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro fmt.Printf("chainid: %v\n", chainId) } if list := request.Transaction.AccessList; list != nil { - fmt.Printf("Accesslist\n") + fmt.Printf("Accesslist:\n") for i, el := range *list { fmt.Printf(" %d. %v\n", i, el.Address) for j, slot := range el.StorageKeys { @@ -136,6 +136,12 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro } } } + if len(request.Transaction.BlobHashes) > 0 { + fmt.Printf("Blob hashes:\n") + for _, bh := range request.Transaction.BlobHashes { + fmt.Printf(" %v\n", bh) + } + } if request.Transaction.Data != nil { d := *request.Transaction.Data if len(d) > 0 { diff --git a/signer/core/signed_data.go b/signer/core/signed_data.go index 5312f87516..5bc6cbc613 100644 --- a/signer/core/signed_data.go +++ b/signer/core/signed_data.go @@ -307,7 +307,7 @@ func fromHex(data any) ([]byte, error) { return nil, fmt.Errorf("wrong type %T", data) } -// typeDataRequest tries to convert the data into a SignDataRequest. +// typedDataRequest tries to convert the data into a SignDataRequest. func typedDataRequest(data any) (*SignDataRequest, error) { var typedData apitypes.TypedData if td, ok := data.(apitypes.TypedData); ok { diff --git a/signer/core/signed_data_test.go b/signer/core/signed_data_test.go index 1cf8b4bf38..d0637010ba 100644 --- a/signer/core/signed_data_test.go +++ b/signer/core/signed_data_test.go @@ -23,7 +23,7 @@ import ( "fmt" "math/big" "os" - "path" + "path/filepath" "strings" "testing" @@ -385,7 +385,7 @@ func TestJsonFiles(t *testing.T) { continue } expectedFailure := strings.HasPrefix(fInfo.Name(), "expfail") - data, err := os.ReadFile(path.Join("testdata", fInfo.Name())) + data, err := os.ReadFile(filepath.Join("testdata", fInfo.Name())) if err != nil { t.Errorf("Failed to read file %v: %v", fInfo.Name(), err) continue @@ -411,14 +411,14 @@ func TestJsonFiles(t *testing.T) { // crashes or hangs. func TestFuzzerFiles(t *testing.T) { t.Parallel() - corpusdir := path.Join("testdata", "fuzzing") + corpusdir := filepath.Join("testdata", "fuzzing") testfiles, err := os.ReadDir(corpusdir) if err != nil { t.Fatalf("failed reading files: %v", err) } verbose := false for i, fInfo := range testfiles { - data, err := os.ReadFile(path.Join(corpusdir, fInfo.Name())) + data, err := os.ReadFile(filepath.Join(corpusdir, fInfo.Name())) if err != nil { t.Errorf("Failed to read file %v: %v", fInfo.Name(), err) continue @@ -671,7 +671,7 @@ func TestGnosisTypedDataWithChainId(t *testing.T) { } } -// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe +// TestGnosisCustomDataWithChainId tests the scenario where a user submits only the gnosis-safe // specific data, and we fill the TypedData struct on our side func TestGnosisCustomDataWithChainId(t *testing.T) { t.Parallel() diff --git a/signer/core/uiapi.go b/signer/core/uiapi.go index b8c3acfb4d..43edfe7d97 100644 --- a/signer/core/uiapi.go +++ b/signer/core/uiapi.go @@ -52,9 +52,9 @@ func NewUIServerAPI(extapi *SignerAPI) *UIServerAPI { // the full Account object and not only Address. // Example call // {"jsonrpc":"2.0","method":"clef_listAccounts","params":[], "id":4} -func (s *UIServerAPI) ListAccounts(ctx context.Context) ([]accounts.Account, error) { +func (api *UIServerAPI) ListAccounts(ctx context.Context) ([]accounts.Account, error) { var accs []accounts.Account - for _, wallet := range s.am.Wallets() { + for _, wallet := range api.am.Wallets() { accs = append(accs, wallet.Accounts()...) } return accs, nil @@ -72,9 +72,9 @@ type rawWallet struct { // ListWallets will return a list of wallets that clef manages // Example call // {"jsonrpc":"2.0","method":"clef_listWallets","params":[], "id":5} -func (s *UIServerAPI) ListWallets() []rawWallet { +func (api *UIServerAPI) ListWallets() []rawWallet { wallets := make([]rawWallet, 0) // return [] instead of nil if empty - for _, wallet := range s.am.Wallets() { + for _, wallet := range api.am.Wallets() { status, failure := wallet.Status() raw := rawWallet{ @@ -94,8 +94,8 @@ func (s *UIServerAPI) ListWallets() []rawWallet { // it for later reuse. // Example call // {"jsonrpc":"2.0","method":"clef_deriveAccount","params":["ledger://","m/44'/60'/0'", false], "id":6} -func (s *UIServerAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { - wallet, err := s.am.Wallet(url) +func (api *UIServerAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { + wallet, err := api.am.Wallet(url) if err != nil { return accounts.Account{}, err } @@ -122,7 +122,7 @@ func fetchKeystore(am *accounts.Manager) *keystore.KeyStore { // encrypting it with the passphrase. // Example call (should fail on password too short) // {"jsonrpc":"2.0","method":"clef_importRawKey","params":["1111111111111111111111111111111111111111111111111111111111111111","test"], "id":6} -func (s *UIServerAPI) ImportRawKey(privkey string, password string) (accounts.Account, error) { +func (api *UIServerAPI) ImportRawKey(privkey string, password string) (accounts.Account, error) { key, err := crypto.HexToECDSA(privkey) if err != nil { return accounts.Account{}, err @@ -131,7 +131,7 @@ func (s *UIServerAPI) ImportRawKey(privkey string, password string) (accounts.Ac return accounts.Account{}, fmt.Errorf("password requirements not met: %v", err) } // No error - return fetchKeystore(s.am).ImportECDSA(key, password) + return fetchKeystore(api.am).ImportECDSA(key, password) } // OpenWallet initiates a hardware wallet opening procedure, establishing a USB @@ -140,8 +140,8 @@ func (s *UIServerAPI) ImportRawKey(privkey string, password string) (accounts.Ac // Trezor PIN matrix challenge). // Example // {"jsonrpc":"2.0","method":"clef_openWallet","params":["ledger://",""], "id":6} -func (s *UIServerAPI) OpenWallet(url string, passphrase *string) error { - wallet, err := s.am.Wallet(url) +func (api *UIServerAPI) OpenWallet(url string, passphrase *string) error { + wallet, err := api.am.Wallet(url) if err != nil { return err } @@ -155,24 +155,24 @@ func (s *UIServerAPI) OpenWallet(url string, passphrase *string) error { // ChainId returns the chainid in use for Eip-155 replay protection // Example call // {"jsonrpc":"2.0","method":"clef_chainId","params":[], "id":8} -func (s *UIServerAPI) ChainId() math.HexOrDecimal64 { - return (math.HexOrDecimal64)(s.extApi.chainID.Uint64()) +func (api *UIServerAPI) ChainId() math.HexOrDecimal64 { + return (math.HexOrDecimal64)(api.extApi.chainID.Uint64()) } // SetChainId sets the chain id to use when signing transactions. // Example call to set Ropsten: // {"jsonrpc":"2.0","method":"clef_setChainId","params":["3"], "id":8} -func (s *UIServerAPI) SetChainId(id math.HexOrDecimal64) math.HexOrDecimal64 { - s.extApi.chainID = new(big.Int).SetUint64(uint64(id)) - return s.ChainId() +func (api *UIServerAPI) SetChainId(id math.HexOrDecimal64) math.HexOrDecimal64 { + api.extApi.chainID = new(big.Int).SetUint64(uint64(id)) + return api.ChainId() } // Export returns encrypted private key associated with the given address in web3 keystore format. // Example // {"jsonrpc":"2.0","method":"clef_export","params":["0x19e7e376e7c213b7e7e7e46cc70a5dd086daff2a"], "id":4} -func (s *UIServerAPI) Export(ctx context.Context, addr common.Address) (json.RawMessage, error) { +func (api *UIServerAPI) Export(ctx context.Context, addr common.Address) (json.RawMessage, error) { // Look up the wallet containing the requested signer - wallet, err := s.am.Find(accounts.Account{Address: addr}) + wallet, err := api.am.Find(accounts.Account{Address: addr}) if err != nil { return nil, err } diff --git a/signer/fourbyte/validation.go b/signer/fourbyte/validation.go index 58111e8e00..8bff011925 100644 --- a/signer/fourbyte/validation.go +++ b/signer/fourbyte/validation.go @@ -20,7 +20,6 @@ import ( "bytes" "errors" "fmt" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/signer/core/apitypes" @@ -36,6 +35,11 @@ func (db *Database) ValidateTransaction(selector *string, tx *apitypes.SendTxArg if tx.Data != nil && tx.Input != nil && !bytes.Equal(*tx.Data, *tx.Input) { return nil, errors.New(`ambiguous request: both "data" and "input" are set and are not identical`) } + // ToTransaction validates, among other things, that blob hashes match with blobs, and also + // populates the hashes if they were previously unset. + if _, err := tx.ToTransaction(); err != nil { + return nil, err + } // Place data on 'data', and nil 'input' var data []byte if tx.Input != nil { @@ -52,7 +56,7 @@ func (db *Database) ValidateTransaction(selector *string, tx *apitypes.SendTxArg // e.g. https://github.com/ethereum/go-ethereum/issues/16106. if len(data) == 0 { // Prevent sending ether into black hole (show stopper) - if tx.Value.ToInt().Cmp(big.NewInt(0)) > 0 { + if tx.Value.ToInt().Sign() > 0 { return nil, errors.New("transaction will create a contract with value but empty code") } // No value submitted at least, critically Warn, but don't blow up diff --git a/signer/storage/aes_gcm_storage_test.go b/signer/storage/aes_gcm_storage_test.go index a223b1a6b4..b895269f95 100644 --- a/signer/storage/aes_gcm_storage_test.go +++ b/signer/storage/aes_gcm_storage_test.go @@ -20,13 +20,13 @@ import ( "bytes" "encoding/json" "fmt" + "log/slog" "os" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/mattn/go-colorable" - "golang.org/x/exp/slog" ) func TestEncryption(t *testing.T) { diff --git a/tests/block_test.go b/tests/block_test.go index 5d6669e9d4..855a462d6a 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -18,7 +18,6 @@ package tests import ( "math/rand" - "runtime" "testing" "github.com/ethereum/go-ethereum/common" @@ -27,11 +26,11 @@ import ( func TestBlockchain(t *testing.T) { bt := new(testMatcher) - // General state tests are 'exported' as blockchain tests, but we can run them natively. - // For speedier CI-runs, the line below can be uncommented, so those are skipped. - // For now, in hardfork-times (Berlin), we run the tests both as StateTests and - // as blockchain tests, since the latter also covers things like receipt root - // bt.skipLoad(`^GeneralStateTests/`) + + // We are running most of GeneralStatetests to tests witness support, even + // though they are ran as state tests too. Still, the performance tests are + // less about state andmore about EVM number crunching, so skip those. + bt.skipLoad(`^GeneralStateTests/VMTests/vmPerformance`) // Skip random failures due to selfish mining test bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`) @@ -52,9 +51,6 @@ func TestBlockchain(t *testing.T) { bt.skipLoad(`.*randomStatetest94.json.*`) bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { - if runtime.GOARCH == "386" && runtime.GOOS == "windows" && rand.Int63()%2 == 0 { - t.Skip("test (randomly) skipped on 32-bit windows") - } execBlockTest(t, bt, test) }) // There is also a LegacyTests folder, containing blockchain tests generated @@ -75,20 +71,25 @@ func TestExecutionSpecBlocktests(t *testing.T) { } func execBlockTest(t *testing.T, bt *testMatcher, test *BlockTest) { - if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil, nil)); err != nil { - t.Errorf("test in hash mode without snapshotter failed: %v", err) - return - } - if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil, nil)); err != nil { - t.Errorf("test in hash mode with snapshotter failed: %v", err) - return + // Define all the different flag combinations we should run the tests with, + // picking only one for short tests. + // + // Note, witness building and self-testing is always enabled as it's a very + // good test to ensure that we don't break it. + var ( + snapshotConf = []bool{false, true} + dbschemeConf = []string{rawdb.HashScheme, rawdb.PathScheme} + ) + if testing.Short() { + snapshotConf = []bool{snapshotConf[rand.Int()%2]} + dbschemeConf = []string{dbschemeConf[rand.Int()%2]} } - if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil, nil)); err != nil { - t.Errorf("test in path mode without snapshotter failed: %v", err) - return - } - if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil, nil)); err != nil { - t.Errorf("test in path mode with snapshotter failed: %v", err) - return + for _, snapshot := range snapshotConf { + for _, dbscheme := range dbschemeConf { + if err := bt.checkFailure(t, test.Run(snapshot, dbscheme, true, nil, nil)); err != nil { + t.Errorf("test with config {snapshotter:%v, scheme:%v} failed: %v", snapshot, dbscheme, err) + return + } + } } } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 52cbf1e1ac..819662ad17 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/log" @@ -109,7 +110,7 @@ type btHeaderMarshaling struct { ExcessBlobGas *math.HexOrDecimal64 } -func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger, postCheck func(error, *core.BlockChain)) (result error) { +func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.Hooks, postCheck func(error, *core.BlockChain)) (result error) { config, ok := Forks[t.json.Network] if !ok { return UnsupportedForkError{t.json.Network} @@ -150,7 +151,8 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger, po cache.SnapshotWait = true } chain, err := core.NewBlockChain(db, cache, gspec, nil, engine, vm.Config{ - Tracer: tracer, + Tracer: tracer, + StatelessSelfValidation: witness, }, nil, nil) if err != nil { return err diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go index 9a5c566540..4efc749b6f 100644 --- a/tests/fuzzers/bls12381/bls12381_fuzz.go +++ b/tests/fuzzers/bls12381/bls12381_fuzz.go @@ -31,10 +31,46 @@ import ( "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto/bls12381" + bls12381 "github.com/kilic/bls12-381" blst "github.com/supranational/blst/bindings/go" ) +func fuzzG1SubgroupChecks(data []byte) int { + input := bytes.NewReader(data) + kpG1, cpG1, blG1, err := getG1Points(input) + if err != nil { + return 0 + } + inSubGroupKilic := bls12381.NewG1().InCorrectSubgroup(kpG1) + inSubGroupGnark := cpG1.IsInSubGroup() + inSubGroupBLST := blG1.InG1() + if inSubGroupKilic != inSubGroupGnark { + panic(fmt.Sprintf("differing subgroup check, kilic %v, gnark %v", inSubGroupKilic, inSubGroupGnark)) + } + if inSubGroupKilic != inSubGroupBLST { + panic(fmt.Sprintf("differing subgroup check, kilic %v, blst %v", inSubGroupKilic, inSubGroupBLST)) + } + return 1 +} + +func fuzzG2SubgroupChecks(data []byte) int { + input := bytes.NewReader(data) + kpG2, cpG2, blG2, err := getG2Points(input) + if err != nil { + return 0 + } + inSubGroupKilic := bls12381.NewG2().InCorrectSubgroup(kpG2) + inSubGroupGnark := cpG2.IsInSubGroup() + inSubGroupBLST := blG2.InG2() + if inSubGroupKilic != inSubGroupGnark { + panic(fmt.Sprintf("differing subgroup check, kilic %v, gnark %v", inSubGroupKilic, inSubGroupGnark)) + } + if inSubGroupKilic != inSubGroupBLST { + panic(fmt.Sprintf("differing subgroup check, kilic %v, blst %v", inSubGroupKilic, inSubGroupBLST)) + } + return 1 +} + func fuzzCrossPairing(data []byte) int { input := bytes.NewReader(data) @@ -51,7 +87,7 @@ func fuzzCrossPairing(data []byte) int { } // compute pairing using geth - engine := bls12381.NewPairingEngine() + engine := bls12381.NewEngine() engine.AddPair(kpG1, kpG2) kResult := engine.Result() @@ -180,7 +216,7 @@ func fuzzCrossG2Add(data []byte) int { func fuzzCrossG1MultiExp(data []byte) int { var ( input = bytes.NewReader(data) - gethScalars []*big.Int + gethScalars []*bls12381.Fr gnarkScalars []fr.Element gethPoints []*bls12381.PointG1 gnarkPoints []gnark.G1Affine @@ -197,7 +233,7 @@ func fuzzCrossG1MultiExp(data []byte) int { if err != nil { break } - gethScalars = append(gethScalars, s) + gethScalars = append(gethScalars, bls12381.NewFr().FromBytes(s.Bytes())) var gnarkScalar = &fr.Element{} gnarkScalar = gnarkScalar.SetBigInt(s) gnarkScalars = append(gnarkScalars, *gnarkScalar) diff --git a/tests/fuzzers/bls12381/bls12381_test.go b/tests/fuzzers/bls12381/bls12381_test.go index 3e88979d16..fd782f7813 100644 --- a/tests/fuzzers/bls12381/bls12381_test.go +++ b/tests/fuzzers/bls12381/bls12381_test.go @@ -98,3 +98,15 @@ func FuzzMapG2(f *testing.F) { fuzz(blsMapG2, data) }) } + +func FuzzG1SubgroupChecks(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + fuzzG1SubgroupChecks(data) + }) +} + +func FuzzG2SubgroupChecks(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + fuzzG2SubgroupChecks(data) + }) +} diff --git a/tests/fuzzers/bls12381/precompile_fuzzer.go b/tests/fuzzers/bls12381/precompile_fuzzer.go index 763ed56e9f..4df4db73d1 100644 --- a/tests/fuzzers/bls12381/precompile_fuzzer.go +++ b/tests/fuzzers/bls12381/precompile_fuzzer.go @@ -25,15 +25,15 @@ import ( ) const ( - blsG1Add = byte(10) - blsG1Mul = byte(11) - blsG1MultiExp = byte(12) - blsG2Add = byte(13) - blsG2Mul = byte(14) - blsG2MultiExp = byte(15) - blsPairing = byte(16) - blsMapG1 = byte(17) - blsMapG2 = byte(18) + blsG1Add = byte(11) + blsG1Mul = byte(12) + blsG1MultiExp = byte(13) + blsG2Add = byte(14) + blsG2Mul = byte(15) + blsG2MultiExp = byte(16) + blsPairing = byte(17) + blsMapG1 = byte(18) + blsMapG2 = byte(19) ) func checkInput(id byte, inputLen int) bool { diff --git a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go index dcafebb265..4d94d31c0c 100644 --- a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go +++ b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go @@ -21,13 +21,13 @@ import ( "encoding/binary" "fmt" "io" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" - "golang.org/x/exp/slices" ) type kv struct { diff --git a/tests/init.go b/tests/init.go index 99b7e4d333..4bb83f9300 100644 --- a/tests/init.go +++ b/tests/init.go @@ -212,7 +212,7 @@ var Forks = map[string]*params.ChainConfig{ LondonBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0), }, - "ArrowGlacierToMergeAtDiffC0000": { + "ArrowGlacierToParisAtDiffC0000": { ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -246,6 +246,23 @@ var Forks = map[string]*params.ChainConfig{ ArrowGlacierBlock: big.NewInt(0), GrayGlacierBlock: big.NewInt(0), }, + "Paris": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + }, "Merge": { ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), @@ -281,7 +298,7 @@ var Forks = map[string]*params.ChainConfig{ TerminalTotalDifficulty: big.NewInt(0), ShanghaiTime: u64(0), }, - "MergeToShanghaiAtTime15k": { + "ParisToShanghaiAtTime15k": { ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -337,6 +354,48 @@ var Forks = map[string]*params.ChainConfig{ ShanghaiTime: u64(0), CancunTime: u64(15_000), }, + "Prague": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + }, + "CancunToPragueAtTime15k": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + }, } // AvailableForks returns the set of defined fork names diff --git a/tests/init_test.go b/tests/init_test.go index 2e2c4fa11d..645a9811ad 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -108,7 +108,7 @@ type testFailure struct { reason string } -// skipShortMode skips tests matching when the -short flag is used. +// slow adds expected slow tests matching the pattern. func (tm *testMatcher) slow(pattern string) { tm.slowpat = append(tm.slowpat, regexp.MustCompile(pattern)) } diff --git a/tests/state_test.go b/tests/state_test.go index 47f7bb3363..58fd10f838 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -25,7 +25,6 @@ import ( "os" "path/filepath" "reflect" - "runtime" "strings" "testing" "time" @@ -58,6 +57,11 @@ func initMatcher(st *testMatcher) { // Broken tests: // EOF is not part of cancun st.skipLoad(`^stEOF/`) + + // The tests under Pyspecs are the ones that are published as execution-spec tests. + // We run these tests separately, no need to _also_ run them as part of the + // reference tests. + st.skipLoad(`^Pyspecs/`) } func TestState(t *testing.T) { @@ -99,15 +103,20 @@ func TestExecutionSpecState(t *testing.T) { } func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { - if runtime.GOARCH == "386" && runtime.GOOS == "windows" && rand.Int63()%2 == 0 { - t.Skip("test (randomly) skipped on 32-bit windows") - return - } for _, subtest := range test.Subtests() { subtest := subtest key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index) + // If -short flag is used, we don't execute all four permutations, only + // one. + executionMask := 0xf + if testing.Short() { + executionMask = (1 << (rand.Int63() & 4)) + } t.Run(key+"/hash/trie", func(t *testing.T) { + if executionMask&0x1 == 0 { + t.Skip("test (randomly) skipped due to short-tag") + } withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { var result error test.Run(subtest, vmconfig, false, rawdb.HashScheme, func(err error, state *StateTestState) { @@ -117,6 +126,9 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { }) }) t.Run(key+"/hash/snap", func(t *testing.T) { + if executionMask&0x2 == 0 { + t.Skip("test (randomly) skipped due to short-tag") + } withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { var result error test.Run(subtest, vmconfig, true, rawdb.HashScheme, func(err error, state *StateTestState) { @@ -132,6 +144,9 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { }) }) t.Run(key+"/path/trie", func(t *testing.T) { + if executionMask&0x4 == 0 { + t.Skip("test (randomly) skipped due to short-tag") + } withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { var result error test.Run(subtest, vmconfig, false, rawdb.PathScheme, func(err error, state *StateTestState) { @@ -141,6 +156,9 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { }) }) t.Run(key+"/path/snap", func(t *testing.T) { + if executionMask&0x8 == 0 { + t.Skip("test (randomly) skipped due to short-tag") + } withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { var result error test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, state *StateTestState) { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 5f1694ae7b..da3be0891f 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -221,21 +222,21 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo if logs := rlpHash(st.StateDB.Logs()); logs != common.Hash(post.Logs) { return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs) } - st.StateDB, _ = state.New(root, st.StateDB.Database(), st.Snapshots) + st.StateDB, _ = state.New(root, st.StateDB.Database()) return nil } // RunNoVerify runs a specific subtest and returns the statedb and post-state root. // Remember to call state.Close after verifying the test result! -func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (state StateTestState, root common.Hash, err error) { +func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (st StateTestState, root common.Hash, err error) { config, eips, err := GetChainConfig(subtest.Fork) if err != nil { - return state, common.Hash{}, UnsupportedForkError{subtest.Fork} + return st, common.Hash{}, UnsupportedForkError{subtest.Fork} } vmconfig.ExtraEips = eips block := t.genesis(config).ToBlock() - state = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme) + st = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme) var baseFee *big.Int if config.IsLondon(new(big.Int)) { @@ -249,7 +250,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh post := t.json.Post[subtest.Fork][subtest.Index] msg, err := t.json.Tx.toMessage(post, baseFee) if err != nil { - return state, common.Hash{}, err + return st, common.Hash{}, err } { // Blob transactions may be present after the Cancun fork. @@ -259,7 +260,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // Here, we just do this shortcut smaller fix, since state tests do not // utilize those codepaths if len(msg.BlobHashes)*params.BlobTxBlobGasPerBlob > params.MaxBlobGasPerBlock { - return state, common.Hash{}, errors.New("blob gas exceeds maximum") + return st, common.Hash{}, errors.New("blob gas exceeds maximum") } } @@ -268,10 +269,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh var ttx types.Transaction err := ttx.UnmarshalBinary(post.TxBytes) if err != nil { - return state, common.Hash{}, err + return st, common.Hash{}, err } if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil { - return state, common.Hash{}, err + return st, common.Hash{}, err } } @@ -292,15 +293,21 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil { context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas) } - evm := vm.NewEVM(context, txContext, state.StateDB, config, vmconfig) + evm := vm.NewEVM(context, txContext, st.StateDB, config, vmconfig) + if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil { + tracer.OnTxStart(evm.GetVMContext(), nil, msg.From) + } // Execute the message. - snapshot := state.StateDB.Snapshot() + snapshot := st.StateDB.Snapshot() gaspool := new(core.GasPool) gaspool.AddGas(block.GasLimit()) - _, err = core.ApplyMessage(evm, msg, gaspool) + vmRet, err := core.ApplyMessage(evm, msg, gaspool) if err != nil { - state.StateDB.RevertToSnapshot(snapshot) + st.StateDB.RevertToSnapshot(snapshot) + if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil { + evm.Config.Tracer.OnTxEnd(nil, err) + } } // Commit block @@ -309,12 +316,16 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // - the coinbase self-destructed, or // - there are only 'bad' transactions, which aren't executed. In those cases, // the coinbase gets no txfee, so isn't created, and thus needs to be touched - state.StateDB.AddBalance(block.Coinbase(), new(uint256.Int)) - // And _now_ get the state root - root = state.StateDB.IntermediateRoot(config.IsEIP158(block.Number())) - state.StateDB.SetExpectedStateRoot(root) - root, _, _ = state.StateDB.Commit(block.NumberU64(), nil) - return state, root, err + st.StateDB.AddBalance(block.Coinbase(), new(uint256.Int), tracing.BalanceChangeUnspecified) + + // Commit state mutations into database. + st.StateDB.SetExpectedStateRoot(root) + root, _, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number())) + if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil { + receipt := &types.Receipt{GasUsed: vmRet.UsedGas} + tracer.OnTxEnd(receipt, nil) + } + return st, root, err } func (t *StateTest) gasLimit(subtest StateSubtest) uint64 { @@ -454,12 +465,12 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo tconf.PathDB = pathdb.Defaults } triedb := triedb.NewDatabase(db, tconf) - sdb := state.NewDatabaseWithNodeDB(db, triedb) - statedb, _ := state.New(types.EmptyRootHash, sdb, nil) + sdb := state.NewDatabase(triedb, nil) + statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) statedb.SetNonce(addr, a.Nonce) - statedb.SetBalance(addr, uint256.MustFromBig(a.Balance)) + statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceChangeUnspecified) for k, v := range a.Storage { statedb.SetState(addr, k, v) } @@ -468,7 +479,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo // Commit and re-open to start with a clean state. root := statedb.IntermediateRoot(false) statedb.SetExpectedStateRoot(root) - root, _, _ = statedb.Commit(0, nil) + root, _, _ = statedb.Commit(0, false) // If snapshot is requested, initialize the snapshotter and use it in state. var snaps *snapshot.Tree @@ -481,7 +492,8 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo } snaps, _ = snapshot.New(snapconfig, db, triedb, root, 128, false) } - statedb, _ = state.New(root, sdb, snaps) + sdb = state.NewDatabase(triedb, snaps) + statedb, _ = state.New(root, sdb) return StateTestState{statedb, triedb, snaps} } diff --git a/tests/transaction_test.go b/tests/transaction_test.go index cb0f262318..5179fc9afe 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -26,20 +26,17 @@ func TestTransaction(t *testing.T) { t.Parallel() txt := new(testMatcher) - // These can't be parsed, invalid hex in RLP - txt.skipLoad("^ttWrongRLP/.*") // We don't allow more than uint64 in gas amount // This is a pseudo-consensus vulnerability, but not in practice // because of the gas limit txt.skipLoad("^ttGasLimit/TransactionWithGasLimitxPriceOverflow.json") // We _do_ allow more than uint64 in gas price, as opposed to the tests // This is also not a concern, as long as tx.Cost() uses big.Int for - // calculating the final cozt - txt.skipLoad(".*TransactionWithGasPriceOverflow.*") + // calculating the final cost + txt.skipLoad("^ttGasPrice/TransactionWithGasPriceOverflow.json") - // The nonce is too large for uint64. Not a concern, it means geth won't - // accept transactions at a certain point in the distant future - txt.skipLoad("^ttNonce/TransactionWithHighNonce256.json") + // The maximum value of nonce is 2^64 - 1 + txt.skipLoad("^ttNonce/TransactionWithHighNonce64Minus1.json") // The value is larger than uint64, which according to the test is invalid. // Geth accepts it, which is not a consensus issue since we use big.Int's diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 391aa57584..d3dbbd5db2 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -29,7 +29,11 @@ import ( // TransactionTest checks RLP decoding and sender derivation of transactions. type TransactionTest struct { - RLP hexutil.Bytes `json:"rlp"` + Txbytes hexutil.Bytes `json:"txbytes"` + Result ttResult +} + +type ttResult struct { Byzantium ttFork Constantinople ttFork Istanbul ttFork @@ -73,15 +77,15 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { isHomestead bool isIstanbul bool }{ - {"Frontier", types.FrontierSigner{}, tt.Frontier, false, false}, - {"Homestead", types.HomesteadSigner{}, tt.Homestead, true, false}, - {"EIP150", types.HomesteadSigner{}, tt.EIP150, true, false}, - {"EIP158", types.NewEIP155Signer(config.ChainID), tt.EIP158, true, false}, - {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Byzantium, true, false}, - {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Constantinople, true, false}, - {"Istanbul", types.NewEIP155Signer(config.ChainID), tt.Istanbul, true, true}, + {"Frontier", types.FrontierSigner{}, tt.Result.Frontier, false, false}, + {"Homestead", types.HomesteadSigner{}, tt.Result.Homestead, true, false}, + {"EIP150", types.HomesteadSigner{}, tt.Result.EIP150, true, false}, + {"EIP158", types.NewEIP155Signer(config.ChainID), tt.Result.EIP158, true, false}, + {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Result.Byzantium, true, false}, + {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Result.Constantinople, true, false}, + {"Istanbul", types.NewEIP155Signer(config.ChainID), tt.Result.Istanbul, true, true}, } { - sender, txhash, err := validateTx(tt.RLP, testcase.signer, testcase.isHomestead, testcase.isIstanbul) + sender, txhash, err := validateTx(tt.Txbytes, testcase.signer, testcase.isHomestead, testcase.isIstanbul) if testcase.fork.Sender == (common.UnprefixedAddress{}) { if err == nil { diff --git a/trie/committer.go b/trie/committer.go index 7de13242b2..e3ea8293fb 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -183,12 +183,8 @@ func estimateSize(n node) int { } } -// MerkleResolver the children resolver in merkle-patricia-tree. -type MerkleResolver struct{} - -// ForEach implements childResolver, decodes the provided node and -// traverses the children inside. -func (resolver MerkleResolver) ForEach(node []byte, onChild func(common.Hash)) { +// ForGatherChildren decodes the provided node and traverses the children inside. +func ForGatherChildren(node []byte, onChild func(common.Hash)) { forGatherChildren(mustDecodeNodeUnsafe(nil, node), onChild) } diff --git a/trie/dummy_trie.go b/trie/dummy_trie.go index 41478253d9..59e301dee7 100644 --- a/trie/dummy_trie.go +++ b/trie/dummy_trie.go @@ -48,7 +48,7 @@ func (t *EmptyTrie) UpdateStorage(_ common.Address, key, value []byte) error { } // TryUpdateAccount abstract an account write in the trie. -func (t *EmptyTrie) UpdateAccount(address common.Address, account *types.StateAccount) error { +func (t *EmptyTrie) UpdateAccount(address common.Address, account *types.StateAccount, codeLen int) error { return nil } @@ -64,8 +64,8 @@ func (t *EmptyTrie) DeleteAccount(address common.Address) error { return nil } -func (t *EmptyTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { - return common.Hash{}, nil, nil +func (t *EmptyTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { + return common.Hash{}, nil } func (t *EmptyTrie) Hash() common.Hash { @@ -87,3 +87,12 @@ func (t *EmptyTrie) Copy() *EmptyTrie { cpy := *t return &cpy } + +func (t *EmptyTrie) IsVerkle() bool { + return false +} + +// Witness returns a set containing all trie nodes that have been accessed. +func (t *EmptyTrie) Witness() map[string]struct{} { + panic("not implemented") +} diff --git a/trie/errors.go b/trie/errors.go index 7be7041c7f..ce5cb13423 100644 --- a/trie/errors.go +++ b/trie/errors.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// ErrCommitted is returned when a already committed trie is requested for usage. +// ErrCommitted is returned when an already committed trie is requested for usage. // The potential usages can be `Get`, `Update`, `Delete`, `NodeIterator`, `Prove` // and so on. var ErrCommitted = errors.New("trie is already committed") diff --git a/trie/hasher.go b/trie/hasher.go index 1e063d8020..abf654c709 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -21,7 +21,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // hasher is a type used for the trie Hash operation. A hasher has some @@ -38,7 +37,7 @@ var hasherPool = sync.Pool{ New: func() interface{} { return &hasher{ tmp: make([]byte, 0, 550), // cap is as large as a full fullNode. - sha: sha3.NewLegacyKeccak256().(crypto.KeccakState), + sha: crypto.NewKeccakState(), encbuf: rlp.NewEncoderBuffer(nil), } }, diff --git a/trie/iterator.go b/trie/iterator.go index 83ccc0740f..fa01611063 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -135,7 +135,7 @@ type nodeIteratorState struct { node node // Trie node being iterated parent common.Hash // Hash of the first full ancestor node (nil if current is the root) index int // Child to be processed next - pathlen int // Length of the path to this node + pathlen int // Length of the path to the parent node } type nodeIterator struct { @@ -145,7 +145,7 @@ type nodeIterator struct { err error // Failure set in case of an internal error in the iterator resolver NodeResolver // optional node resolver for avoiding disk hits - pool []*nodeIteratorState // local pool for iteratorstates + pool []*nodeIteratorState // local pool for iterator states } // errIteratorEnd is stored in nodeIterator.err when iteration is done. @@ -304,6 +304,7 @@ func (it *nodeIterator) seek(prefix []byte) error { // The path we're looking for is the hex encoded key without terminator. key := keybytesToHex(prefix) key = key[:len(key)-1] + // Move forward until we're just before the closest match to key. for { state, parentIndex, path, err := it.peekSeek(key) @@ -311,7 +312,7 @@ func (it *nodeIterator) seek(prefix []byte) error { return errIteratorEnd } else if err != nil { return seekError{prefix, err} - } else if bytes.Compare(path, key) >= 0 { + } else if reachedPath(path, key) { return nil } it.push(state, parentIndex, path) @@ -339,7 +340,6 @@ func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, er // If we're skipping children, pop the current node first it.pop() } - // Continue iteration to the next child for len(it.stack) > 0 { parent := it.stack[len(it.stack)-1] @@ -372,7 +372,6 @@ func (it *nodeIterator) peekSeek(seekKey []byte) (*nodeIteratorState, *int, []by // If we're skipping children, pop the current node first it.pop() } - // Continue iteration to the next child for len(it.stack) > 0 { parent := it.stack[len(it.stack)-1] @@ -449,16 +448,18 @@ func (it *nodeIterator) findChild(n *fullNode, index int, ancestor common.Hash) state *nodeIteratorState childPath []byte ) - for ; index < len(n.Children); index++ { + for ; index < len(n.Children); index = nextChildIndex(index) { if n.Children[index] != nil { child = n.Children[index] hash, _ := child.cache() + state = it.getFromPool() state.hash = common.BytesToHash(hash) state.node = child state.parent = ancestor state.index = -1 state.pathlen = len(path) + childPath = append(childPath, path...) childPath = append(childPath, byte(index)) return child, state, childPath, index @@ -471,8 +472,8 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has switch node := parent.node.(type) { case *fullNode: // Full node, move to the first non-nil child. - if child, state, path, index := it.findChild(node, parent.index+1, ancestor); child != nil { - parent.index = index - 1 + if child, state, path, index := it.findChild(node, nextChildIndex(parent.index), ancestor); child != nil { + parent.index = prevChildIndex(index) return state, path, true } case *shortNode: @@ -498,23 +499,23 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H switch n := parent.node.(type) { case *fullNode: // Full node, move to the first non-nil child before the desired key position - child, state, path, index := it.findChild(n, parent.index+1, ancestor) + child, state, path, index := it.findChild(n, nextChildIndex(parent.index), ancestor) if child == nil { // No more children in this fullnode return parent, it.path, false } // If the child we found is already past the seek position, just return it. - if bytes.Compare(path, key) >= 0 { - parent.index = index - 1 + if reachedPath(path, key) { + parent.index = prevChildIndex(index) return state, path, true } // The child is before the seek position. Try advancing for { - nextChild, nextState, nextPath, nextIndex := it.findChild(n, index+1, ancestor) + nextChild, nextState, nextPath, nextIndex := it.findChild(n, nextChildIndex(index), ancestor) // If we run out of children, or skipped past the target, return the // previous one - if nextChild == nil || bytes.Compare(nextPath, key) >= 0 { - parent.index = index - 1 + if nextChild == nil || reachedPath(nextPath, key) { + parent.index = prevChildIndex(index) return state, path, true } // We found a better child closer to the target @@ -541,7 +542,7 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path [] it.path = path it.stack = append(it.stack, state) if parentIndex != nil { - *parentIndex++ + *parentIndex = nextChildIndex(*parentIndex) } } @@ -550,8 +551,54 @@ func (it *nodeIterator) pop() { it.path = it.path[:last.pathlen] it.stack[len(it.stack)-1] = nil it.stack = it.stack[:len(it.stack)-1] - // last is now unused - it.putInPool(last) + + it.putInPool(last) // last is now unused +} + +// reachedPath normalizes a path by truncating a terminator if present, and +// returns true if it is greater than or equal to the target. Using this, +// the path of a value node embedded a full node will compare less than the +// full node's children. +func reachedPath(path, target []byte) bool { + if hasTerm(path) { + path = path[:len(path)-1] + } + return bytes.Compare(path, target) >= 0 +} + +// A value embedded in a full node occupies the last slot (16) of the array of +// children. In order to produce a pre-order traversal when iterating children, +// we jump to this last slot first, then go back iterate the child nodes (and +// skip the last slot at the end): + +// prevChildIndex returns the index of a child in a full node which precedes +// the given index when performing a pre-order traversal. +func prevChildIndex(index int) int { + switch index { + case 0: // We jumped back to iterate the children, from the value slot + return 16 + case 16: // We jumped to the embedded value slot at the end, from the placeholder index + return -1 + case 17: // We skipped the value slot after iterating all the children + return 15 + default: // We are iterating the children in sequence + return index - 1 + } +} + +// nextChildIndex returns the index of a child in a full node which follows +// the given index when performing a pre-order traversal. +func nextChildIndex(index int) int { + switch index { + case -1: // Jump from the placeholder index to the embedded value slot + return 16 + case 15: // Skip the value slot after iterating the children + return 17 + case 16: // From the embedded value slot, jump back to iterate the children + return 0 + default: // Iterate children in sequence + return index + 1 + } } func compareNodes(a, b NodeIterator) int { diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 41e83f6cb6..b463294b09 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -59,7 +59,7 @@ func TestIterator(t *testing.T) { all[val.k] = val.v trie.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -182,14 +182,14 @@ func testNodeIteratorCoverage(t *testing.T, scheme string) { type kvs struct{ k, v string } var testdata1 = []kvs{ + {"bar", "b"}, {"barb", "ba"}, {"bard", "bc"}, {"bars", "bb"}, - {"bar", "b"}, {"fab", "z"}, + {"foo", "a"}, {"food", "ab"}, {"foos", "aa"}, - {"foo", "a"}, } var testdata2 = []kvs{ @@ -218,7 +218,7 @@ func TestIteratorSeek(t *testing.T) { // Seek to a non-existent key. it = NewIterator(trie.MustNodeIterator([]byte("barc"))) - if err := checkIteratorOrder(testdata1[1:], it); err != nil { + if err := checkIteratorOrder(testdata1[2:], it); err != nil { t.Fatal(err) } @@ -227,6 +227,12 @@ func TestIteratorSeek(t *testing.T) { if err := checkIteratorOrder(nil, it); err != nil { t.Fatal(err) } + + // Seek to a key for which a prefixing key exists. + it = NewIterator(trie.MustNodeIterator([]byte("food"))) + if err := checkIteratorOrder(testdata1[6:], it); err != nil { + t.Fatal(err) + } } func checkIteratorOrder(want []kvs, it *Iterator) error { @@ -251,7 +257,7 @@ func TestDifferenceIterator(t *testing.T) { for _, val := range testdata1 { triea.MustUpdate([]byte(val.k), []byte(val.v)) } - rootA, nodesA, _ := triea.Commit(false) + rootA, nodesA := triea.Commit(false) dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)) triea, _ = New(TrieID(rootA), dba) @@ -260,7 +266,7 @@ func TestDifferenceIterator(t *testing.T) { for _, val := range testdata2 { trieb.MustUpdate([]byte(val.k), []byte(val.v)) } - rootB, nodesB, _ := trieb.Commit(false) + rootB, nodesB := trieb.Commit(false) dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB)) trieb, _ = New(TrieID(rootB), dbb) @@ -293,7 +299,7 @@ func TestUnionIterator(t *testing.T) { for _, val := range testdata1 { triea.MustUpdate([]byte(val.k), []byte(val.v)) } - rootA, nodesA, _ := triea.Commit(false) + rootA, nodesA := triea.Commit(false) dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)) triea, _ = New(TrieID(rootA), dba) @@ -302,7 +308,7 @@ func TestUnionIterator(t *testing.T) { for _, val := range testdata2 { trieb.MustUpdate([]byte(val.k), []byte(val.v)) } - rootB, nodesB, _ := trieb.Commit(false) + rootB, nodesB := trieb.Commit(false) dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB)) trieb, _ = New(TrieID(rootB), dbb) @@ -311,16 +317,16 @@ func TestUnionIterator(t *testing.T) { all := []struct{ k, v string }{ {"aardvark", "c"}, + {"bar", "b"}, {"barb", "ba"}, {"barb", "bd"}, {"bard", "bc"}, {"bars", "bb"}, {"bars", "be"}, - {"bar", "b"}, {"fab", "z"}, + {"foo", "a"}, {"food", "ab"}, {"foos", "aa"}, - {"foo", "a"}, {"jars", "d"}, } @@ -365,7 +371,7 @@ func testIteratorContinueAfterError(t *testing.T, memonly bool, scheme string) { for _, val := range testdata1 { tr.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := tr.Commit(false) + root, nodes := tr.Commit(false) tdb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) if !memonly { tdb.Commit(root) @@ -475,7 +481,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool, scheme strin for _, val := range testdata1 { ctr.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := ctr.Commit(false) + root, nodes := ctr.Commit(false) for path, n := range nodes.Nodes { if n.Hash == barNodeHash { barNodePath = []byte(path) @@ -512,7 +518,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool, scheme strin rawdb.WriteTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, barNodeBlob, triedb.Scheme()) } // Check that iteration produces the right set of values. - if err := checkIteratorOrder(testdata1[2:], NewIterator(it)); err != nil { + if err := checkIteratorOrder(testdata1[3:], NewIterator(it)); err != nil { t.Fatal(err) } } @@ -555,7 +561,7 @@ func testIteratorNodeBlob(t *testing.T, scheme string) { all[val.k] = val.v trie.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) triedb.Commit(root) diff --git a/trie/proof.go b/trie/proof.go index fd892fb4be..a39d6b4ea3 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -372,7 +372,7 @@ func unset(parent node, child node, key []byte, pos int, removeLeft bool) error return unset(cld, cld.Children[key[pos]], key, pos+1, removeLeft) case *shortNode: if len(key[pos:]) < len(cld.Key) || !bytes.Equal(cld.Key, key[pos:pos+len(cld.Key)]) { - // Find the fork point, it's an non-existent branch. + // Find the fork point, it's a non-existent branch. if removeLeft { if bytes.Compare(cld.Key, key[pos:]) < 0 { // The key of fork shortnode is less than the path diff --git a/trie/proof_test.go b/trie/proof_test.go index 5471d0efa6..fab3a97650 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -22,13 +22,13 @@ import ( "encoding/binary" "fmt" mrand "math/rand" + "slices" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb/memorydb" - "golang.org/x/exp/slices" ) // Prng is a pseudo random number generator seeded by strong randomness. @@ -198,7 +198,7 @@ func TestRangeProof(t *testing.T) { } } -// TestRangeProof tests normal range proof with two non-existent proofs. +// TestRangeProofWithNonExistentProof tests normal range proof with two non-existent proofs. // The test cases are generated randomly. func TestRangeProofWithNonExistentProof(t *testing.T) { trie, vals := randomTrie(4096) diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 5462f6eb7e..e28809a81e 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -24,6 +24,16 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) +// preimageStore wraps the methods of a backing store for reading and writing +// trie node preimages. +type preimageStore interface { + // Preimage retrieves the preimage of the specified hash. + Preimage(hash common.Hash) []byte + + // InsertPreimage commits a set of preimages along with their hashes. + InsertPreimage(preimages map[common.Hash][]byte) +} + // SecureTrie is the old name of StateTrie. // Deprecated: use StateTrie. type SecureTrie = StateTrie @@ -52,6 +62,7 @@ func NewSecure(stateRoot common.Hash, owner common.Hash, root common.Hash, db da type StateTrie struct { trie Trie db database.Database + preimages preimageStore hashKeyBuf [common.HashLength]byte //nolint:unused secKeyCache map[string][]byte secKeyCacheOwner *StateTrie // Pointer to self, replace the key cache on mismatch @@ -70,7 +81,14 @@ func NewStateTrie(id *ID, db database.Database) (*StateTrie, error) { if err != nil { return nil, err } - return &StateTrie{trie: *trie, db: db}, nil + tr := &StateTrie{trie: *trie, db: db} + + // link the preimage store if it's supported + preimages, ok := db.(preimageStore) + if ok { + tr.preimages = preimages + } + return tr, nil } // MustGet returns the value for key stored in the trie. @@ -164,7 +182,7 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { } // UpdateAccount will abstract the write of an account to the secure trie. -func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { +func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount, _ int) error { hk := t.hashKey(address.Bytes()) data, err := rlp.EncodeToBytes(acc) if err != nil { @@ -211,7 +229,15 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte { if key, ok := t.getSecKeyCache()[string(shaKey)]; ok { return key } - return t.db.Preimage(common.BytesToHash(shaKey)) + if t.preimages == nil { + return nil + } + return t.preimages.Preimage(common.BytesToHash(shaKey)) +} + +// Witness returns a set containing all trie nodes that have been accessed. +func (t *StateTrie) Witness() map[string]struct{} { + return t.trie.Witness() } // Commit collects all dirty nodes in the trie and replaces them with the @@ -221,14 +247,16 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte { // All cached preimages will be also flushed if preimages recording is enabled. // Once the trie is committed, it's not usable anymore. A new trie must // be created with new root and updated trie database for following usage -func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { +func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { // Write all the pre-images to the actual disk database if len(t.getSecKeyCache()) > 0 { - preimages := make(map[common.Hash][]byte) - for hk, key := range t.secKeyCache { - preimages[common.BytesToHash([]byte(hk))] = key + if t.preimages != nil { + preimages := make(map[common.Hash][]byte, len(t.secKeyCache)) + for hk, key := range t.secKeyCache { + preimages[common.BytesToHash([]byte(hk))] = key + } + t.preimages.InsertPreimage(preimages) } - t.db.InsertPreimage(preimages) t.secKeyCache = make(map[string][]byte) } // Commit the trie and return its modified nodeset. @@ -298,3 +326,7 @@ func (t *StateTrie) getSecKeyCache() map[string][]byte { } return t.secKeyCache } + +func (t *StateTrie) IsVerkle() bool { + return false +} diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go index 2f0ef5f046..9053d16c63 100644 --- a/trie/secure_trie_test.go +++ b/trie/secure_trie_test.go @@ -61,7 +61,7 @@ func makeTestStateTrie() (*testDb, *StateTrie, map[string][]byte) { trie.MustUpdate(key, val) } } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil { panic(fmt.Errorf("failed to commit db %v", err)) } diff --git a/trie/stacktrie.go b/trie/stacktrie.go index f2f5355c49..d194cbf0ae 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -23,8 +23,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" ) var ( @@ -32,62 +30,32 @@ var ( _ = types.TrieHasher((*StackTrie)(nil)) ) -// StackTrieOptions contains the configured options for manipulating the stackTrie. -type StackTrieOptions struct { - Writer func(path []byte, hash common.Hash, blob []byte) // The function to commit the dirty nodes - Cleaner func(path []byte) // The function to clean up dangling nodes - - SkipLeftBoundary bool // Flag whether the nodes on the left boundary are skipped for committing - SkipRightBoundary bool // Flag whether the nodes on the right boundary are skipped for committing - boundaryGauge metrics.Gauge // Gauge to track how many boundary nodes are met -} - -// NewStackTrieOptions initializes an empty options for stackTrie. -func NewStackTrieOptions() *StackTrieOptions { return &StackTrieOptions{} } - -// WithWriter configures trie node writer within the options. -func (o *StackTrieOptions) WithWriter(writer func(path []byte, hash common.Hash, blob []byte)) *StackTrieOptions { - o.Writer = writer - return o -} - -// WithCleaner configures the cleaner in the option for removing dangling nodes. -func (o *StackTrieOptions) WithCleaner(cleaner func(path []byte)) *StackTrieOptions { - o.Cleaner = cleaner - return o -} - -// WithSkipBoundary configures whether the left and right boundary nodes are -// filtered for committing, along with a gauge metrics to track how many -// boundary nodes are met. -func (o *StackTrieOptions) WithSkipBoundary(skipLeft, skipRight bool, gauge metrics.Gauge) *StackTrieOptions { - o.SkipLeftBoundary = skipLeft - o.SkipRightBoundary = skipRight - o.boundaryGauge = gauge - return o -} +// OnTrieNode is a callback method invoked when a trie node is committed +// by the stack trie. The node is only committed if it's considered complete. +// +// The caller should not modify the contents of the returned path and blob +// slice, and their contents may be changed after the call. It is up to the +// `onTrieNode` receiver function to deep-copy the data if it wants to retain +// it after the call ends. +type OnTrieNode func(path []byte, hash common.Hash, blob []byte) // StackTrie is a trie implementation that expects keys to be inserted // in order. Once it determines that a subtree will no longer be inserted // into, it will hash it and free up the memory it uses. type StackTrie struct { - options *StackTrieOptions - root *stNode - h *hasher - - first []byte // The (hex-encoded without terminator) key of first inserted entry, tracked as left boundary. - last []byte // The (hex-encoded without terminator) key of last inserted entry, tracked as right boundary. + root *stNode + h *hasher + last []byte + onTrieNode OnTrieNode } -// NewStackTrie allocates and initializes an empty trie. -func NewStackTrie(options *StackTrieOptions) *StackTrie { - if options == nil { - options = NewStackTrieOptions() - } +// NewStackTrie allocates and initializes an empty trie. The committed nodes +// will be discarded immediately if no callback is configured. +func NewStackTrie(onTrieNode OnTrieNode) *StackTrie { return &StackTrie{ - options: options, - root: stPool.Get().(*stNode), - h: newHasher(false), + root: stPool.Get().(*stNode), + h: newHasher(false), + onTrieNode: onTrieNode, } } @@ -96,15 +64,10 @@ func (t *StackTrie) Update(key, value []byte) error { if len(value) == 0 { return errors.New("trying to insert empty (deletion)") } - k := keybytesToHex(key) - k = k[:len(k)-1] // chop the termination flag + k := t.TrieKey(key) if bytes.Compare(t.last, k) >= 0 { return errors.New("non-ascending key order") } - // track the first and last inserted entries. - if t.first == nil { - t.first = append([]byte{}, k...) - } if t.last == nil { t.last = append([]byte{}, k...) // allocate key slice } else { @@ -114,22 +77,19 @@ func (t *StackTrie) Update(key, value []byte) error { return nil } -// MustUpdate is a wrapper of Update and will omit any encountered error but -// just print out an error message. -func (t *StackTrie) MustUpdate(key, value []byte) { - if err := t.Update(key, value); err != nil { - log.Error("Unhandled trie error in StackTrie.Update", "err", err) - } -} - // Reset resets the stack trie object to empty state. func (t *StackTrie) Reset() { - t.options = NewStackTrieOptions() t.root = stPool.Get().(*stNode) - t.first = nil t.last = nil } +// TrieKey returns the internal key representation for the given user key. +func (t *StackTrie) TrieKey(key []byte) []byte { + k := keybytesToHex(key) + k = k[:len(k)-1] // chop the termination flag + return k +} + // stNode represents a node within a StackTrie type stNode struct { typ uint8 // node type (as in branch, ext, leaf) @@ -346,10 +306,7 @@ func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { // // This method also sets 'st.type' to hashedNode, and clears 'st.key'. func (t *StackTrie) hash(st *stNode, path []byte) { - var ( - blob []byte // RLP-encoded node blob - internal [][]byte // List of node paths covered by the extension node - ) + var blob []byte // RLP-encoded node blob switch st.typ { case hashedNode: return @@ -384,15 +341,6 @@ func (t *StackTrie) hash(st *stNode, path []byte) { // recursively hash and commit child as the first step t.hash(st.children[0], append(path, st.key...)) - // Collect the path of internal nodes between shortNode and its **in disk** - // child. This is essential in the case of path mode scheme to avoid leaving - // danging nodes within the range of this internal path on disk, which would - // break the guarantee for state healing. - if len(st.children[0].val) >= 32 && t.options.Cleaner != nil { - for i := 1; i < len(st.key); i++ { - internal = append(internal, append(path, st.key[:i]...)) - } - } // encode the extension node n := shortNode{Key: hexToCompactInPlace(st.key)} if len(st.children[0].val) < 32 { @@ -416,11 +364,12 @@ func (t *StackTrie) hash(st *stNode, path []byte) { default: panic("invalid node type") } - + // Convert the node type to hashNode and reset the key slice. st.typ = hashedNode st.key = st.key[:0] - // Skip committing the non-root node if the size is smaller than 32 bytes. + // Skip committing the non-root node if the size is smaller than 32 bytes + // as tiny nodes are always embedded in their parent except root node. if len(blob) < 32 && len(path) > 0 { st.val = common.CopyBytes(blob) return @@ -429,51 +378,20 @@ func (t *StackTrie) hash(st *stNode, path []byte) { // input values. st.val = t.h.hashData(blob) - // Short circuit if the stack trie is not configured for writing. - if t.options.Writer == nil { - return - } - // Skip committing if the node is on the left boundary and stackTrie is - // configured to filter the boundary. - if t.options.SkipLeftBoundary && bytes.HasPrefix(t.first, path) { - if t.options.boundaryGauge != nil { - t.options.boundaryGauge.Inc(1) - } - return - } - // Skip committing if the node is on the right boundary and stackTrie is - // configured to filter the boundary. - if t.options.SkipRightBoundary && bytes.HasPrefix(t.last, path) { - if t.options.boundaryGauge != nil { - t.options.boundaryGauge.Inc(1) - } - return - } - // Clean up the internal dangling nodes covered by the extension node. - // This should be done before writing the node to adhere to the committing - // order from bottom to top. - for _, path := range internal { - t.options.Cleaner(path) + // Invoke the callback it's provided. Notably, the path and blob slices are + // volatile, please deep-copy the slices in callback if the contents need + // to be retained. + if t.onTrieNode != nil { + t.onTrieNode(path, common.BytesToHash(st.val), blob) } - t.options.Writer(path, common.BytesToHash(st.val), blob) } // Hash will firstly hash the entire trie if it's still not hashed and then commit -// all nodes to the associated database. Actually most of the trie nodes have been -// committed already. The main purpose here is to commit the nodes on right boundary. -// -// For stack trie, Hash and Commit are functionally identical. +// all leftover nodes to the associated database. Actually most of the trie nodes +// have been committed already. The main purpose here is to commit the nodes on +// right boundary. func (t *StackTrie) Hash() common.Hash { n := t.root t.hash(n, nil) return common.BytesToHash(n.val) } - -// Commit will firstly hash the entire trie if it's still not hashed and then commit -// all nodes to the associated database. Actually most of the trie nodes have been -// committed already. The main purpose here is to commit the nodes on right boundary. -// -// For stack trie, Hash and Commit are functionally identical. -func (t *StackTrie) Commit() common.Hash { - return t.Hash() -} diff --git a/trie/stacktrie_fuzzer_test.go b/trie/stacktrie_fuzzer_test.go index 50b5c4de52..df487d16bf 100644 --- a/trie/stacktrie_fuzzer_test.go +++ b/trie/stacktrie_fuzzer_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/binary" "fmt" + "slices" "testing" "github.com/ethereum/go-ethereum/common" @@ -27,8 +28,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/trie/trienode" - "golang.org/x/crypto/sha3" - "golang.org/x/exp/slices" ) func FuzzStackTrie(f *testing.F) { @@ -41,16 +40,14 @@ func fuzz(data []byte, debugging bool) { // This spongeDb is used to check the sequence of disk-db-writes var ( input = bytes.NewReader(data) - spongeA = &spongeDb{sponge: sha3.NewLegacyKeccak256()} + spongeA = &spongeDb{sponge: crypto.NewKeccakState()} dbA = newTestDatabase(rawdb.NewDatabase(spongeA), rawdb.HashScheme) trieA = NewEmpty(dbA) - spongeB = &spongeDb{sponge: sha3.NewLegacyKeccak256()} + spongeB = &spongeDb{sponge: crypto.NewKeccakState()} dbB = newTestDatabase(rawdb.NewDatabase(spongeB), rawdb.HashScheme) - - options = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { + trieB = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { rawdb.WriteTrieNode(spongeB, common.Hash{}, path, hash, blob, dbB.Scheme()) }) - trieB = NewStackTrie(options) vals []*kv maxElements = 10000 // operate on unique keys only @@ -82,10 +79,7 @@ func fuzz(data []byte, debugging bool) { return } // Flush trie -> database - rootA, nodes, err := trieA.Commit(false) - if err != nil { - panic(err) - } + rootA, nodes := trieA.Commit(false) if nodes != nil { dbA.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) } @@ -99,10 +93,9 @@ func fuzz(data []byte, debugging bool) { if debugging { fmt.Printf("{\"%#x\" , \"%#x\"} // stacktrie.Update\n", kv.k, kv.v) } - trieB.MustUpdate(kv.k, kv.v) + trieB.Update(kv.k, kv.v) } rootB := trieB.Hash() - trieB.Commit() if rootA != rootB { panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootB)) } @@ -114,20 +107,19 @@ func fuzz(data []byte, debugging bool) { // Ensure all the nodes are persisted correctly var ( - nodeset = make(map[string][]byte) // path -> blob - optionsC = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { + nodeset = make(map[string][]byte) // path -> blob + trieC = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { if crypto.Keccak256Hash(blob) != hash { panic("invalid node blob") } nodeset[string(path)] = common.CopyBytes(blob) }) - trieC = NewStackTrie(optionsC) checked int ) for _, kv := range vals { - trieC.MustUpdate(kv.k, kv.v) + trieC.Update(kv.k, kv.v) } - rootC := trieC.Commit() + rootC := trieC.Hash() if rootA != rootC { panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootC)) } diff --git a/trie/stacktrie_test.go b/trie/stacktrie_test.go index 3a0e1cb260..f053b5112d 100644 --- a/trie/stacktrie_test.go +++ b/trie/stacktrie_test.go @@ -19,15 +19,12 @@ package trie import ( "bytes" "math/big" - "math/rand" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/trie/testutil" "github.com/stretchr/testify/assert" - "golang.org/x/exp/slices" ) func TestStackTrieInsertAndHash(t *testing.T) { @@ -381,90 +378,6 @@ func TestStacktrieNotModifyValues(t *testing.T) { } } -func buildPartialTree(entries []*kv, t *testing.T) map[string]common.Hash { - var ( - options = NewStackTrieOptions() - nodes = make(map[string]common.Hash) - ) - var ( - first int - last = len(entries) - 1 - - noLeft bool - noRight bool - ) - // Enter split mode if there are at least two elements - if rand.Intn(5) != 0 { - for { - first = rand.Intn(len(entries)) - last = rand.Intn(len(entries)) - if first <= last { - break - } - } - if first != 0 { - noLeft = true - } - if last != len(entries)-1 { - noRight = true - } - } - options = options.WithSkipBoundary(noLeft, noRight, nil) - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - nodes[string(path)] = hash - }) - tr := NewStackTrie(options) - - for i := first; i <= last; i++ { - tr.MustUpdate(entries[i].k, entries[i].v) - } - tr.Commit() - return nodes -} - -func TestPartialStackTrie(t *testing.T) { - for round := 0; round < 100; round++ { - var ( - n = rand.Intn(100) + 1 - entries []*kv - ) - for i := 0; i < n; i++ { - var val []byte - if rand.Intn(3) == 0 { - val = testutil.RandBytes(3) - } else { - val = testutil.RandBytes(32) - } - entries = append(entries, &kv{ - k: testutil.RandBytes(32), - v: val, - }) - } - slices.SortFunc(entries, (*kv).cmp) - - var ( - nodes = make(map[string]common.Hash) - options = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { - nodes[string(path)] = hash - }) - ) - tr := NewStackTrie(options) - - for i := 0; i < len(entries); i++ { - tr.MustUpdate(entries[i].k, entries[i].v) - } - tr.Commit() - - for j := 0; j < 100; j++ { - for path, hash := range buildPartialTree(entries, t) { - if nodes[path] != hash { - t.Errorf("%v, want %x, got %x", []byte(path), nodes[path], hash) - } - } - } - } -} - func TestStackTrieErrors(t *testing.T) { s := NewStackTrie(nil) // Deletion diff --git a/trie/sync.go b/trie/sync.go index 5c74dfcc03..d0f3866c37 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -22,9 +22,11 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" @@ -148,15 +150,42 @@ type CodeSyncResult struct { // nodeOp represents an operation upon the trie node. It can either represent a // deletion to the specific node or a node write for persisting retrieved node. type nodeOp struct { + del bool // flag if op stands for a delete operation owner common.Hash // identifier of the trie (empty for account trie) path []byte // path from the root to the specified node. blob []byte // the content of the node (nil for deletion) hash common.Hash // hash of the node content (empty for node deletion) } -// isDelete indicates if the operation is a database deletion. -func (op *nodeOp) isDelete() bool { - return len(op.blob) == 0 +// valid checks whether the node operation is valid. +func (op *nodeOp) valid() bool { + if op.del && len(op.blob) != 0 { + return false + } + if !op.del && len(op.blob) == 0 { + return false + } + return true +} + +// string returns the node operation in string representation. +func (op *nodeOp) string() string { + var node string + if op.owner == (common.Hash{}) { + node = fmt.Sprintf("node: (%v)", op.path) + } else { + node = fmt.Sprintf("node: (%x-%v)", op.owner, op.path) + } + var blobHex string + if len(op.blob) == 0 { + blobHex = "nil" + } else { + blobHex = hexutil.Encode(op.blob) + } + if op.del { + return fmt.Sprintf("del %s %s %s", node, blobHex, op.hash.Hex()) + } + return fmt.Sprintf("write %s %s %s", node, blobHex, op.hash.Hex()) } // syncMemBatch is an in-memory buffer of successfully downloaded but not yet @@ -219,6 +248,7 @@ func (batch *syncMemBatch) delNode(owner common.Hash, path []byte) { batch.size += common.HashLength + uint64(len(path)) } batch.nodes = append(batch.nodes, nodeOp{ + del: true, owner: owner, path: path, }) @@ -427,7 +457,10 @@ func (s *Sync) Commit(dbw ethdb.Batch, stateBatch ethdb.Batch) error { storage int ) for _, op := range s.membatch.nodes { - if op.isDelete() { + if !op.valid() { + return fmt.Errorf("invalid op, %s", op.string()) + } + if op.del { // node deletion is only supported in path mode. if op.owner == (common.Hash{}) { if stateBatch != nil { @@ -558,9 +591,9 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { // the performance impact negligible. var exists bool if owner == (common.Hash{}) { - exists = rawdb.ExistsAccountTrieNode(s.database.StateStoreReader(), append(inner, key[:i]...)) + exists = rawdb.HasAccountTrieNode(s.database.StateStoreReader(), append(inner, key[:i]...)) } else { - exists = rawdb.ExistsStorageTrieNode(s.database.StateStoreReader(), owner, append(inner, key[:i]...)) + exists = rawdb.HasStorageTrieNode(s.database.StateStoreReader(), owner, append(inner, key[:i]...)) } if exists { s.membatch.delNode(owner, append(inner, key[:i]...)) @@ -703,13 +736,14 @@ func (s *Sync) hasNode(owner common.Hash, path []byte, hash common.Hash) (exists } // If node is running with path scheme, check the presence with node path. var blob []byte - var dbHash common.Hash if owner == (common.Hash{}) { - blob, dbHash = rawdb.ReadAccountTrieNode(s.database.StateStoreReader(), path) + blob = rawdb.ReadAccountTrieNode(s.database.StateStoreReader(), path) } else { - blob, dbHash = rawdb.ReadStorageTrieNode(s.database.StateStoreReader(), owner, path) + blob = rawdb.ReadStorageTrieNode(s.database.StateStoreReader(), owner, path) } - exists = hash == dbHash + h := newBlobHasher() + defer h.release() + exists = hash == h.hash(blob) inconsistent = !exists && len(blob) != 0 return exists, inconsistent } @@ -724,3 +758,23 @@ func ResolvePath(path []byte) (common.Hash, []byte) { } return owner, path } + +// blobHasher is used to compute the sha256 hash of the provided data. +type blobHasher struct{ state crypto.KeccakState } + +// blobHasherPool is the pool for reusing pre-allocated hash state. +var blobHasherPool = sync.Pool{ + New: func() interface{} { return &blobHasher{state: crypto.NewKeccakState()} }, +} + +func newBlobHasher() *blobHasher { + return blobHasherPool.Get().(*blobHasher) +} + +func (h *blobHasher) hash(data []byte) common.Hash { + return crypto.HashData(h.state, data) +} + +func (h *blobHasher) release() { + blobHasherPool.Put(h) +} diff --git a/trie/sync_test.go b/trie/sync_test.go index df2c1f59f1..7841c6a0d2 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -19,6 +19,7 @@ package trie import ( "bytes" "fmt" + "maps" "math/rand" "testing" @@ -56,7 +57,7 @@ func makeTestTrie(scheme string) (ethdb.Database, *testDb, *StateTrie, map[strin trie.MustUpdate(key, val) } } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil { panic(fmt.Errorf("failed to commit db %v", err)) } @@ -769,7 +770,7 @@ func testSyncMovingTarget(t *testing.T, scheme string) { srcTrie.MustUpdate(key, val) diff[string(key)] = val } - root, nodes, _ := srcTrie.Commit(false) + root, nodes := srcTrie.Commit(false) if err := srcDb.Update(root, preRoot, trienode.NewWithNodeSet(nodes)); err != nil { panic(err) } @@ -794,7 +795,7 @@ func testSyncMovingTarget(t *testing.T, scheme string) { srcTrie.MustUpdate([]byte(k), val) reverted[k] = val } - root, nodes, _ = srcTrie.Commit(false) + root, nodes = srcTrie.Commit(false) if err := srcDb.Update(root, preRoot, trienode.NewWithNodeSet(nodes)); err != nil { panic(err) } @@ -836,13 +837,6 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) { tr.Update(key, val) states[string(key)] = common.CopyBytes(val) } - copyStates = func(states map[string][]byte) map[string][]byte { - cpy := make(map[string][]byte) - for k, v := range states { - cpy[k] = v - } - return cpy - } ) stateA := make(map[string][]byte) writeFn([]byte{0x01, 0x23}, nil, srcTrie, stateA) @@ -852,7 +846,7 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) { writeFn([]byte{0x02, 0x34}, nil, srcTrie, stateA) writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateA) - rootA, nodesA, _ := srcTrie.Commit(false) + rootA, nodesA := srcTrie.Commit(false) if err := srcTrieDB.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)); err != nil { panic(err) } @@ -865,13 +859,13 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) { checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateA, true) // Delete element to collapse trie - stateB := copyStates(stateA) + stateB := maps.Clone(stateA) srcTrie, _ = New(TrieID(rootA), srcTrieDB) deleteFn([]byte{0x02, 0x34}, srcTrie, stateB) deleteFn([]byte{0x13, 0x44}, srcTrie, stateB) writeFn([]byte{0x01, 0x24}, nil, srcTrie, stateB) - rootB, nodesB, _ := srcTrie.Commit(false) + rootB, nodesB := srcTrie.Commit(false) if err := srcTrieDB.Update(rootB, rootA, trienode.NewWithNodeSet(nodesB)); err != nil { panic(err) } @@ -882,14 +876,14 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) { checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateB, true) // Add elements to expand trie - stateC := copyStates(stateB) + stateC := maps.Clone(stateB) srcTrie, _ = New(TrieID(rootB), srcTrieDB) writeFn([]byte{0x01, 0x24}, stateA[string([]byte{0x01, 0x24})], srcTrie, stateC) writeFn([]byte{0x02, 0x34}, nil, srcTrie, stateC) writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateC) - rootC, nodesC, _ := srcTrie.Commit(false) + rootC, nodesC := srcTrie.Commit(false) if err := srcTrieDB.Update(rootC, rootB, trienode.NewWithNodeSet(nodesC)); err != nil { panic(err) } @@ -940,13 +934,6 @@ func testSyncAbort(t *testing.T, scheme string) { tr.Update(key, val) states[string(key)] = common.CopyBytes(val) } - copyStates = func(states map[string][]byte) map[string][]byte { - cpy := make(map[string][]byte) - for k, v := range states { - cpy[k] = v - } - return cpy - } ) var ( stateA = make(map[string][]byte) @@ -958,7 +945,7 @@ func testSyncAbort(t *testing.T, scheme string) { } writeFn(key, val, srcTrie, stateA) - rootA, nodesA, _ := srcTrie.Commit(false) + rootA, nodesA := srcTrie.Commit(false) if err := srcTrieDB.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)); err != nil { panic(err) } @@ -971,11 +958,11 @@ func testSyncAbort(t *testing.T, scheme string) { checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateA, true) // Delete the element from the trie - stateB := copyStates(stateA) + stateB := maps.Clone(stateA) srcTrie, _ = New(TrieID(rootA), srcTrieDB) deleteFn(key, srcTrie, stateB) - rootB, nodesB, _ := srcTrie.Commit(false) + rootB, nodesB := srcTrie.Commit(false) if err := srcTrieDB.Update(rootB, rootA, trienode.NewWithNodeSet(nodesB)); err != nil { panic(err) } @@ -998,11 +985,11 @@ func testSyncAbort(t *testing.T, scheme string) { }}) // Add elements to expand trie - stateC := copyStates(stateB) + stateC := maps.Clone(stateB) srcTrie, _ = New(TrieID(rootB), srcTrieDB) writeFn(key, val, srcTrie, stateC) - rootC, nodesC, _ := srcTrie.Commit(false) + rootC, nodesC := srcTrie.Commit(false) if err := srcTrieDB.Update(rootC, rootB, trienode.NewWithNodeSet(nodesC)); err != nil { panic(err) } diff --git a/trie/tracer.go b/trie/tracer.go index 5786af4d3e..90b9666f0b 100644 --- a/trie/tracer.go +++ b/trie/tracer.go @@ -17,6 +17,8 @@ package trie import ( + "maps" + "github.com/ethereum/go-ethereum/common" ) @@ -92,23 +94,13 @@ func (t *tracer) reset() { // copy returns a deep copied tracer instance. func (t *tracer) copy() *tracer { - var ( - inserts = make(map[string]struct{}) - deletes = make(map[string]struct{}) - accessList = make(map[string][]byte) - ) - for path := range t.inserts { - inserts[path] = struct{}{} - } - for path := range t.deletes { - deletes[path] = struct{}{} - } + accessList := make(map[string][]byte, len(t.accessList)) for path, blob := range t.accessList { accessList[path] = common.CopyBytes(blob) } return &tracer{ - inserts: inserts, - deletes: deletes, + inserts: maps.Clone(t.inserts), + deletes: maps.Clone(t.deletes), accessList: accessList, } } diff --git a/trie/tracer_test.go b/trie/tracer_test.go index 27e42d497a..6344e481fd 100644 --- a/trie/tracer_test.go +++ b/trie/tracer_test.go @@ -52,6 +52,15 @@ var ( } ) +// copySet returns a deep-copied set. +func copySet[k comparable](set map[k][]byte) map[k][]byte { + copied := make(map[k][]byte, len(set)) + for key, val := range set { + copied[key] = common.CopyBytes(val) + } + return copied +} + func TestTrieTracer(t *testing.T) { testTrieTracer(t, tiny) testTrieTracer(t, nonAligned) @@ -70,7 +79,7 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { } insertSet := copySet(trie.tracer.inserts) // copy before commit deleteSet := copySet(trie.tracer.deletes) // copy before commit - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) seen := setKeys(iterNodes(db, root)) @@ -137,7 +146,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -152,7 +161,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustUpdate([]byte(val.k), randBytes(32)) } - root, nodes, _ = trie.Commit(false) + root, nodes = trie.Commit(false) db.Update(root, parent, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -170,7 +179,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { keys = append(keys, string(key)) trie.MustUpdate(key, randBytes(32)) } - root, nodes, _ = trie.Commit(false) + root, nodes = trie.Commit(false) db.Update(root, parent, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -185,7 +194,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { for _, key := range keys { trie.MustUpdate([]byte(key), nil) } - root, nodes, _ = trie.Commit(false) + root, nodes = trie.Commit(false) db.Update(root, parent, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -200,7 +209,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustUpdate([]byte(val.k), nil) } - root, nodes, _ = trie.Commit(false) + root, nodes = trie.Commit(false) db.Update(root, parent, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) @@ -219,7 +228,7 @@ func TestAccessListLeak(t *testing.T) { for _, val := range standard { trie.MustUpdate([]byte(val.k), []byte(val.v)) } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) var cases = []struct { @@ -269,7 +278,7 @@ func TestTinyTree(t *testing.T) { for _, val := range tiny { trie.MustUpdate([]byte(val.k), randBytes(32)) } - root, set, _ := trie.Commit(false) + root, set := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(set)) parent := root @@ -278,7 +287,7 @@ func TestTinyTree(t *testing.T) { for _, val := range tiny { trie.MustUpdate([]byte(val.k), []byte(val.v)) } - root, set, _ = trie.Commit(false) + root, set = trie.Commit(false) db.Update(root, parent, trienode.NewWithNodeSet(set)) trie, _ = New(TrieID(root), db) diff --git a/trie/trie.go b/trie/trie.go index a65bd596f5..e97ac46e86 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -53,7 +53,6 @@ type Trie struct { reader *trieReader // tracer is the tool to track the trie changes. - // It will be reset after each commit operation. tracer *tracer } @@ -608,8 +607,7 @@ func (t *Trie) Hash() common.Hash { // The returned nodeset can be nil if the trie is clean (nothing to commit). // Once the trie is committed, it's not usable anymore. A new trie must // be created with new root and updated trie database for following usage -func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { - defer t.tracer.reset() +func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { defer func() { t.committed = true }() @@ -620,13 +618,13 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) if t.root == nil { paths := t.tracer.deletedNodes() if len(paths) == 0 { - return types.EmptyRootHash, nil, nil // case (a) + return types.EmptyRootHash, nil // case (a) } nodes := trienode.NewNodeSet(t.owner) for _, path := range paths { nodes.AddNode([]byte(path), trienode.NewDeleted()) } - return types.EmptyRootHash, nodes, nil // case (b) + return types.EmptyRootHash, nodes // case (b) } // Derive the hash for all dirty nodes first. We hold the assumption // in the following procedure that all nodes are hashed. @@ -638,14 +636,14 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) // Replace the root node with the origin hash in order to // ensure all resolved nodes are dropped after the commit. t.root = hashedNode - return rootHash, nil, nil + return rootHash, nil } nodes := trienode.NewNodeSet(t.owner) for _, path := range t.tracer.deletedNodes() { nodes.AddNode([]byte(path), trienode.NewDeleted()) } t.root = newCommitter(nodes, t.tracer, collectLeaf).Commit(t.root) - return rootHash, nodes, nil + return rootHash, nodes } // hashRoot calculates the root hash of the given trie @@ -663,6 +661,18 @@ func (t *Trie) hashRoot() (node, node) { return hashed, cached } +// Witness returns a set containing all trie nodes that have been accessed. +func (t *Trie) Witness() map[string]struct{} { + if len(t.tracer.accessList) == 0 { + return nil + } + witness := make(map[string]struct{}, len(t.tracer.accessList)) + for _, node := range t.tracer.accessList { + witness[string(node)] = struct{}{} + } + return witness +} + // Reset drops the referenced root node and cleans all internal state. func (t *Trie) Reset() { t.root = nil diff --git a/trie/trie_reader.go b/trie/trie_reader.go index 42bc4316fe..adbf43d287 100644 --- a/trie/trie_reader.go +++ b/trie/trie_reader.go @@ -20,7 +20,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/triedb/database" ) @@ -72,23 +71,3 @@ func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) { } return blob, nil } - -// MerkleLoader implements triestate.TrieLoader for constructing tries. -type MerkleLoader struct { - db database.Database -} - -// NewMerkleLoader creates the merkle trie loader. -func NewMerkleLoader(db database.Database) *MerkleLoader { - return &MerkleLoader{db: db} -} - -// OpenTrie opens the main account trie. -func (l *MerkleLoader) OpenTrie(root common.Hash) (triestate.Trie, error) { - return New(TrieID(root), l.db) -} - -// OpenStorageTrie opens the storage trie of an account. -func (l *MerkleLoader) OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (triestate.Trie, error) { - return New(StorageTrieID(stateRoot, addrHash, root), l.db) -} diff --git a/trie/trie_test.go b/trie/trie_test.go index 73a72222f4..505b517bc5 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -95,7 +95,7 @@ func testMissingNode(t *testing.T, memonly bool, scheme string) { trie := NewEmpty(triedb) updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer") updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf") - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) if !memonly { @@ -184,7 +184,7 @@ func TestInsert(t *testing.T) { updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab") - root, _, _ = trie.Commit(false) + root, _ = trie.Commit(false) if root != exp { t.Errorf("case 2: exp %x got %x", exp, root) } @@ -209,7 +209,7 @@ func TestGet(t *testing.T) { if i == 1 { return } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) } @@ -282,7 +282,7 @@ func TestReplication(t *testing.T) { for _, val := range vals { updateString(trie, val.k, val.v) } - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) // create a new trie on top of the database and check that lookups work. @@ -295,7 +295,7 @@ func TestReplication(t *testing.T) { t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v) } } - hash, nodes, _ := trie2.Commit(false) + hash, nodes := trie2.Commit(false) if hash != root { t.Errorf("root failure. expected %x got %x", root, hash) } @@ -531,7 +531,7 @@ func runRandTest(rt randTest) error { case opHash: tr.Hash() case opCommit: - root, nodes, _ := tr.Commit(true) + root, nodes := tr.Commit(true) if nodes != nil { triedb.Update(root, origin, trienode.NewWithNodeSet(nodes)) } @@ -768,7 +768,7 @@ func TestCommitAfterHash(t *testing.T) { if exp != root { t.Errorf("got %x, exp %x", root, exp) } - root, _, _ = trie.Commit(false) + root, _ = trie.Commit(false) if exp != root { t.Errorf("got %x, exp %x", root, exp) } @@ -819,8 +819,7 @@ func (s *spongeDb) Get(key []byte) ([]byte, error) { return nil, error func (s *spongeDb) Delete(key []byte) error { panic("implement me") } func (s *spongeDb) NewBatch() ethdb.Batch { return &spongeBatch{s} } func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch { return &spongeBatch{s} } -func (s *spongeDb) NewSnapshot() (ethdb.Snapshot, error) { panic("implement me") } -func (s *spongeDb) Stat(property string) (string, error) { panic("implement me") } +func (s *spongeDb) Stat() (string, error) { panic("implement me") } func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") } func (s *spongeDb) Close() error { return nil } func (s *spongeDb) Put(key []byte, value []byte) error { @@ -886,7 +885,7 @@ func TestCommitSequence(t *testing.T) { } { addresses, accounts := makeAccounts(tc.count) // This spongeDb is used to check the sequence of disk-db-writes - s := &spongeDb{sponge: sha3.NewLegacyKeccak256()} + s := &spongeDb{sponge: crypto.NewKeccakState()} db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) trie := NewEmpty(db) // Fill the trie with elements @@ -894,7 +893,7 @@ func TestCommitSequence(t *testing.T) { trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) } // Flush trie -> database - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) // Flush memdb -> disk (sponge) db.Commit(root) @@ -917,7 +916,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { } { prng := rand.New(rand.NewSource(int64(i))) // This spongeDb is used to check the sequence of disk-db-writes - s := &spongeDb{sponge: sha3.NewLegacyKeccak256()} + s := &spongeDb{sponge: crypto.NewKeccakState()} db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) trie := NewEmpty(db) // Fill the trie with elements @@ -935,7 +934,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { trie.MustUpdate(key, val) } // Flush trie -> database - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) // Flush memdb -> disk (sponge) db.Commit(root) @@ -963,11 +962,9 @@ func TestCommitSequenceStackTrie(t *testing.T) { id: "b", values: make(map[string]string), } - options := NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { + stTrie := NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { rawdb.WriteTrieNode(stackTrieSponge, common.Hash{}, path, hash, blob, db.Scheme()) }) - stTrie := NewStackTrie(options) // Fill the trie with elements for i := 0; i < count; i++ { @@ -986,14 +983,14 @@ func TestCommitSequenceStackTrie(t *testing.T) { stTrie.Update(key, val) } // Flush trie -> database - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) // Flush memdb -> disk (sponge) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) db.Commit(root) s.Flush() // And flush stacktrie -> disk - stRoot := stTrie.Commit() + stRoot := stTrie.Hash() if stRoot != root { t.Fatalf("root wrong, got %x exp %x", stRoot, root) } @@ -1034,12 +1031,9 @@ func TestCommitSequenceSmallRoot(t *testing.T) { id: "b", values: make(map[string]string), } - options := NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { + stTrie := NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { rawdb.WriteTrieNode(stackTrieSponge, common.Hash{}, path, hash, blob, db.Scheme()) }) - stTrie := NewStackTrie(options) - // Add a single small-element to the trie(s) key := make([]byte, 5) key[0] = 1 @@ -1047,13 +1041,13 @@ func TestCommitSequenceSmallRoot(t *testing.T) { stTrie.Update(key, []byte{0x1}) // Flush trie -> database - root, nodes, _ := trie.Commit(false) + root, nodes := trie.Commit(false) // Flush memdb -> disk (sponge) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) db.Commit(root) // And flush stacktrie -> disk - stRoot := stTrie.Commit() + stRoot := stTrie.Hash() if stRoot != root { t.Fatalf("root wrong, got %x exp %x", stRoot, root) } @@ -1066,7 +1060,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) { } } -// BenchmarkHashFixedSize benchmarks the Commit (after Hash) of a fixed number of updates to a trie. +// BenchmarkHashFixedSize benchmarks the hash of a fixed number of updates to a trie. // This benchmark is meant to capture the difference on efficiency of small versus large changes. Typically, // storage tries are small (a couple of entries), whereas the full post-block account trie update is large (a couple // of thousand entries) diff --git a/trie/trienode/node.go b/trie/trienode/node.go index 95315c2e9a..09f355f3b5 100644 --- a/trie/trienode/node.go +++ b/trie/trienode/node.go @@ -78,7 +78,7 @@ func NewNodeSet(owner common.Hash) *NodeSet { // ForEachWithOrder iterates the nodes with the order from bottom to top, // right to left, nodes with the longest path will be iterated first. func (set *NodeSet) ForEachWithOrder(callback func(path string, n *Node)) { - var paths []string + paths := make([]string, 0, len(set.Nodes)) for path := range set.Nodes { paths = append(paths, path) } @@ -114,7 +114,12 @@ func (set *NodeSet) Merge(owner common.Hash, nodes map[string]*Node) error { set.updates -= 1 } } - set.AddNode([]byte(path), node) + if node.IsDeleted() { + set.deletes += 1 + } else { + set.updates += 1 + } + set.Nodes[path] = node } return nil } @@ -130,30 +135,18 @@ func (set *NodeSet) Size() (int, int) { return set.updates, set.deletes } -// Hashes returns the hashes of all updated nodes. TODO(rjl493456442) how can -// we get rid of it? -func (set *NodeSet) Hashes() []common.Hash { - var ret []common.Hash - for _, node := range set.Nodes { - ret = append(ret, node.Hash) - } - return ret -} - // Summary returns a string-representation of the NodeSet. func (set *NodeSet) Summary() string { var out = new(strings.Builder) fmt.Fprintf(out, "nodeset owner: %v\n", set.Owner) - if set.Nodes != nil { - for path, n := range set.Nodes { - // Deletion - if n.IsDeleted() { - fmt.Fprintf(out, " [-]: %x\n", path) - continue - } - // Insertion or update - fmt.Fprintf(out, " [+/*]: %x -> %v \n", path, n.Hash) + for path, n := range set.Nodes { + // Deletion + if n.IsDeleted() { + fmt.Fprintf(out, " [-]: %x\n", path) + continue } + // Insertion or update + fmt.Fprintf(out, " [+/*]: %x -> %v \n", path, n.Hash) } for _, n := range set.Leaves { fmt.Fprintf(out, "[leaf]: %v\n", n) @@ -191,7 +184,7 @@ func (set *MergedNodeSet) Merge(other *NodeSet) error { // Flatten returns a two-dimensional map for internal nodes. func (set *MergedNodeSet) Flatten() map[common.Hash]map[string]*Node { - nodes := make(map[common.Hash]map[string]*Node) + nodes := make(map[common.Hash]map[string]*Node, len(set.Sets)) for owner, set := range set.Sets { nodes[owner] = set.Nodes } diff --git a/trie/trienode/node_test.go b/trie/trienode/node_test.go new file mode 100644 index 0000000000..bcb3a2202b --- /dev/null +++ b/trie/trienode/node_test.go @@ -0,0 +1,61 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see + +package trienode + +import ( + "crypto/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +func BenchmarkMerge(b *testing.B) { + b.Run("1K", func(b *testing.B) { + benchmarkMerge(b, 1000) + }) + b.Run("10K", func(b *testing.B) { + benchmarkMerge(b, 10_000) + }) +} + +func benchmarkMerge(b *testing.B, count int) { + x := NewNodeSet(common.Hash{}) + y := NewNodeSet(common.Hash{}) + addNode := func(s *NodeSet) { + path := make([]byte, 4) + rand.Read(path) + blob := make([]byte, 32) + rand.Read(blob) + hash := crypto.Keccak256Hash(blob) + s.AddNode(path, New(hash, blob)) + } + for i := 0; i < count; i++ { + // Random path of 4 nibbles + addNode(x) + addNode(y) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + // Store set x into a backup + z := NewNodeSet(common.Hash{}) + z.Merge(common.Hash{}, x.Nodes) + // Merge y into x + x.Merge(common.Hash{}, y.Nodes) + x = z + } +} diff --git a/trie/trienode/proof.go b/trie/trienode/proof.go index 012f0087dd..d3075ecccf 100644 --- a/trie/trienode/proof.go +++ b/trie/trienode/proof.go @@ -102,14 +102,14 @@ func (db *ProofSet) DataSize() int { return db.dataSize } -// List converts the node set to a ProofList -func (db *ProofSet) List() ProofList { +// List converts the node set to a slice of bytes. +func (db *ProofSet) List() [][]byte { db.lock.RLock() defer db.lock.RUnlock() - var values ProofList - for _, key := range db.order { - values = append(values, db.nodes[key]) + values := make([][]byte, len(db.order)) + for i, key := range db.order { + values[i] = db.nodes[key] } return values } diff --git a/trie/triestate/state.go b/trie/triestate/state.go index 4c47e9c397..62a9043873 100644 --- a/trie/triestate/state.go +++ b/trie/triestate/state.go @@ -16,61 +16,22 @@ package triestate -import ( - "errors" - "fmt" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie/trienode" - "golang.org/x/crypto/sha3" -) - -// Trie is an Ethereum state trie, can be implemented by Ethereum Merkle Patricia -// tree or Verkle tree. -type Trie interface { - // Get returns the value for key stored in the trie. - Get(key []byte) ([]byte, error) - - // Update associates key with value in the trie. - Update(key, value []byte) error - - // Delete removes any existing value for key from the trie. - Delete(key []byte) error - - // Commit the trie and returns a set of dirty nodes generated along with - // the new root hash. - Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) -} - -// TrieLoader wraps functions to load tries. -type TrieLoader interface { - // OpenTrie opens the main account trie. - OpenTrie(root common.Hash) (Trie, error) - - // OpenStorageTrie opens the storage trie of an account. - OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (Trie, error) -} +import "github.com/ethereum/go-ethereum/common" // Set represents a collection of mutated states during a state transition. // The value refers to the original content of state before the transition // is made. Nil means that the state was not present previously. type Set struct { - Accounts map[common.Address][]byte // Mutated account set, nil means the account was not present - Storages map[common.Address]map[common.Hash][]byte // Mutated storage set, nil means the slot was not present - Incomplete map[common.Address]struct{} // Indicator whether the storage is incomplete due to large deletion - size common.StorageSize // Approximate size of set + Accounts map[common.Address][]byte // Mutated account set, nil means the account was not present + Storages map[common.Address]map[common.Hash][]byte // Mutated storage set, nil means the slot was not present + size common.StorageSize // Approximate size of set } // New constructs the state set with provided data. -func New(accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, incomplete map[common.Address]struct{}) *Set { +func New(accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte) *Set { return &Set{ - Accounts: accounts, - Storages: storages, - Incomplete: incomplete, + Accounts: accounts, + Storages: storages, } } @@ -88,189 +49,5 @@ func (s *Set) Size() common.StorageSize { } s.size += common.StorageSize(common.AddressLength) } - s.size += common.StorageSize(common.AddressLength * len(s.Incomplete)) return s.size } - -// context wraps all fields for executing state diffs. -type context struct { - prevRoot common.Hash - postRoot common.Hash - accounts map[common.Address][]byte - storages map[common.Address]map[common.Hash][]byte - accountTrie Trie - nodes *trienode.MergedNodeSet -} - -// Apply traverses the provided state diffs, apply them in the associated -// post-state and return the generated dirty trie nodes. The state can be -// loaded via the provided trie loader. -func Apply(prevRoot common.Hash, postRoot common.Hash, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, loader TrieLoader) (map[common.Hash]map[string]*trienode.Node, error) { - tr, err := loader.OpenTrie(postRoot) - if err != nil { - return nil, err - } - ctx := &context{ - prevRoot: prevRoot, - postRoot: postRoot, - accounts: accounts, - storages: storages, - accountTrie: tr, - nodes: trienode.NewMergedNodeSet(), - } - for addr, account := range accounts { - var err error - if len(account) == 0 { - err = deleteAccount(ctx, loader, addr) - } else { - err = updateAccount(ctx, loader, addr) - } - if err != nil { - return nil, fmt.Errorf("failed to revert state, err: %w", err) - } - } - root, result, err := tr.Commit(false) - if err != nil { - return nil, err - } - if root != prevRoot { - return nil, fmt.Errorf("failed to revert state, want %#x, got %#x", prevRoot, root) - } - if err := ctx.nodes.Merge(result); err != nil { - return nil, err - } - return ctx.nodes.Flatten(), nil -} - -// updateAccount the account was present in prev-state, and may or may not -// existent in post-state. Apply the reverse diff and verify if the storage -// root matches the one in prev-state account. -func updateAccount(ctx *context, loader TrieLoader, addr common.Address) error { - // The account was present in prev-state, decode it from the - // 'slim-rlp' format bytes. - h := newHasher() - defer h.release() - - addrHash := h.hash(addr.Bytes()) - prev, err := types.FullAccount(ctx.accounts[addr]) - if err != nil { - return err - } - // The account may or may not existent in post-state, try to - // load it and decode if it's found. - blob, err := ctx.accountTrie.Get(addrHash.Bytes()) - if err != nil { - return err - } - post := types.NewEmptyStateAccount() - if len(blob) != 0 { - if err := rlp.DecodeBytes(blob, &post); err != nil { - return err - } - } - // Apply all storage changes into the post-state storage trie. - st, err := loader.OpenStorageTrie(ctx.postRoot, addrHash, post.Root) - if err != nil { - return err - } - for key, val := range ctx.storages[addr] { - var err error - if len(val) == 0 { - err = st.Delete(key.Bytes()) - } else { - err = st.Update(key.Bytes(), val) - } - if err != nil { - return err - } - } - root, result, err := st.Commit(false) - if err != nil { - return err - } - if root != prev.Root { - return errors.New("failed to reset storage trie") - } - // The returned set can be nil if storage trie is not changed - // at all. - if result != nil { - if err := ctx.nodes.Merge(result); err != nil { - return err - } - } - // Write the prev-state account into the main trie - full, err := rlp.EncodeToBytes(prev) - if err != nil { - return err - } - return ctx.accountTrie.Update(addrHash.Bytes(), full) -} - -// deleteAccount the account was not present in prev-state, and is expected -// to be existent in post-state. Apply the reverse diff and verify if the -// account and storage is wiped out correctly. -func deleteAccount(ctx *context, loader TrieLoader, addr common.Address) error { - // The account must be existent in post-state, load the account. - h := newHasher() - defer h.release() - - addrHash := h.hash(addr.Bytes()) - blob, err := ctx.accountTrie.Get(addrHash.Bytes()) - if err != nil { - return err - } - if len(blob) == 0 { - return fmt.Errorf("account is non-existent %#x", addrHash) - } - var post types.StateAccount - if err := rlp.DecodeBytes(blob, &post); err != nil { - return err - } - st, err := loader.OpenStorageTrie(ctx.postRoot, addrHash, post.Root) - if err != nil { - return err - } - for key, val := range ctx.storages[addr] { - if len(val) != 0 { - return errors.New("expect storage deletion") - } - if err := st.Delete(key.Bytes()); err != nil { - return err - } - } - root, result, err := st.Commit(false) - if err != nil { - return err - } - if root != types.EmptyRootHash { - return errors.New("failed to clear storage trie") - } - // The returned set can be nil if storage trie is not changed - // at all. - if result != nil { - if err := ctx.nodes.Merge(result); err != nil { - return err - } - } - // Delete the post-state account from the main trie. - return ctx.accountTrie.Delete(addrHash.Bytes()) -} - -// hasher is used to compute the sha256 hash of the provided data. -type hasher struct{ sha crypto.KeccakState } - -var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} }, -} - -func newHasher() *hasher { - return hasherPool.Get().(*hasher) -} - -func (h *hasher) hash(data []byte) common.Hash { - return crypto.HashData(h.sha, data) -} - -func (h *hasher) release() { - hasherPool.Put(h) -} diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go index ce059edc64..12e02de9a4 100644 --- a/trie/utils/verkle.go +++ b/trie/utils/verkle.go @@ -23,18 +23,18 @@ import ( "github.com/crate-crypto/go-ipa/bandersnatch/fr" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/metrics" - "github.com/gballet/go-verkle" + "github.com/ethereum/go-verkle" "github.com/holiman/uint256" ) const ( - // The spec of verkle key encoding can be found here. - // https://notes.ethereum.org/@vbuterin/verkle_tree_eip#Tree-embedding - VersionLeafKey = 0 - BalanceLeafKey = 1 - NonceLeafKey = 2 - CodeKeccakLeafKey = 3 - CodeSizeLeafKey = 4 + BasicDataLeafKey = 0 + CodeHashLeafKey = 1 + + BasicDataVersionOffset = 0 + BasicDataCodeSizeOffset = 5 + BasicDataNonceOffset = 8 + BasicDataBalanceOffset = 16 ) var ( @@ -177,44 +177,24 @@ func GetTreeKeyWithEvaluatedAddress(evaluated *verkle.Point, treeIndex *uint256. return pointToHash(ret, subIndex) } -// VersionKey returns the verkle tree key of the version field for the specified account. -func VersionKey(address []byte) []byte { - return GetTreeKey(address, zero, VersionLeafKey) -} - -// BalanceKey returns the verkle tree key of the balance field for the specified account. -func BalanceKey(address []byte) []byte { - return GetTreeKey(address, zero, BalanceLeafKey) -} - -// NonceKey returns the verkle tree key of the nonce field for the specified account. -func NonceKey(address []byte) []byte { - return GetTreeKey(address, zero, NonceLeafKey) -} - -// CodeKeccakKey returns the verkle tree key of the code keccak field for +// BasicDataKey returns the verkle tree key of the basic data field for // the specified account. -func CodeKeccakKey(address []byte) []byte { - return GetTreeKey(address, zero, CodeKeccakLeafKey) +func BasicDataKey(address []byte) []byte { + return GetTreeKey(address, zero, BasicDataLeafKey) } -// CodeSizeKey returns the verkle tree key of the code size field for the -// specified account. -func CodeSizeKey(address []byte) []byte { - return GetTreeKey(address, zero, CodeSizeLeafKey) +// CodeHashKey returns the verkle tree key of the code hash field for +// the specified account. +func CodeHashKey(address []byte) []byte { + return GetTreeKey(address, zero, CodeHashLeafKey) } func codeChunkIndex(chunk *uint256.Int) (*uint256.Int, byte) { var ( - chunkOffset = new(uint256.Int).Add(codeOffset, chunk) - treeIndex = new(uint256.Int).Div(chunkOffset, verkleNodeWidth) - subIndexMod = new(uint256.Int).Mod(chunkOffset, verkleNodeWidth) + chunkOffset = new(uint256.Int).Add(codeOffset, chunk) + treeIndex, subIndexMod = new(uint256.Int).DivMod(chunkOffset, verkleNodeWidth, new(uint256.Int)) ) - var subIndex byte - if len(subIndexMod) != 0 { - subIndex = byte(subIndexMod[0]) - } - return treeIndex, subIndex + return treeIndex, byte(subIndexMod.Uint64()) } // CodeChunkKey returns the verkle tree key of the code chunk for the @@ -224,7 +204,7 @@ func CodeChunkKey(address []byte, chunk *uint256.Int) []byte { return GetTreeKey(address, treeIndex, subIndex) } -func storageIndex(bytes []byte) (*uint256.Int, byte) { +func StorageIndex(bytes []byte) (*uint256.Int, byte) { // If the storage slot is in the header, we need to add the header offset. var key uint256.Int key.SetBytes(bytes) @@ -250,43 +230,22 @@ func storageIndex(bytes []byte) (*uint256.Int, byte) { // StorageSlotKey returns the verkle tree key of the storage slot for the // specified account. func StorageSlotKey(address []byte, storageKey []byte) []byte { - treeIndex, subIndex := storageIndex(storageKey) + treeIndex, subIndex := StorageIndex(storageKey) return GetTreeKey(address, treeIndex, subIndex) } -// VersionKeyWithEvaluatedAddress returns the verkle tree key of the version -// field for the specified account. The difference between VersionKey is the -// address evaluation is already computed to minimize the computational overhead. -func VersionKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { - return GetTreeKeyWithEvaluatedAddress(evaluated, zero, VersionLeafKey) -} - -// BalanceKeyWithEvaluatedAddress returns the verkle tree key of the balance -// field for the specified account. The difference between BalanceKey is the -// address evaluation is already computed to minimize the computational overhead. -func BalanceKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { - return GetTreeKeyWithEvaluatedAddress(evaluated, zero, BalanceLeafKey) -} - -// NonceKeyWithEvaluatedAddress returns the verkle tree key of the nonce -// field for the specified account. The difference between NonceKey is the -// address evaluation is already computed to minimize the computational overhead. -func NonceKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { - return GetTreeKeyWithEvaluatedAddress(evaluated, zero, NonceLeafKey) -} - -// CodeKeccakKeyWithEvaluatedAddress returns the verkle tree key of the code -// keccak for the specified account. The difference between CodeKeccakKey is the +// BasicDataKeyWithEvaluatedAddress returns the verkle tree key of the basic data +// field for the specified account. The difference between BasicDataKey is the // address evaluation is already computed to minimize the computational overhead. -func CodeKeccakKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { - return GetTreeKeyWithEvaluatedAddress(evaluated, zero, CodeKeccakLeafKey) +func BasicDataKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { + return GetTreeKeyWithEvaluatedAddress(evaluated, zero, BasicDataLeafKey) } -// CodeSizeKeyWithEvaluatedAddress returns the verkle tree key of the code -// size for the specified account. The difference between CodeSizeKey is the +// CodeHashKeyWithEvaluatedAddress returns the verkle tree key of the code +// hash for the specified account. The difference between CodeHashKey is the // address evaluation is already computed to minimize the computational overhead. -func CodeSizeKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { - return GetTreeKeyWithEvaluatedAddress(evaluated, zero, CodeSizeLeafKey) +func CodeHashKeyWithEvaluatedAddress(evaluated *verkle.Point) []byte { + return GetTreeKeyWithEvaluatedAddress(evaluated, zero, CodeHashLeafKey) } // CodeChunkKeyWithEvaluatedAddress returns the verkle tree key of the code @@ -301,7 +260,7 @@ func CodeChunkKeyWithEvaluatedAddress(addressPoint *verkle.Point, chunk *uint256 // slot for the specified account. The difference between StorageSlotKey is the // address evaluation is already computed to minimize the computational overhead. func StorageSlotKeyWithEvaluatedAddress(evaluated *verkle.Point, storageKey []byte) []byte { - treeIndex, subIndex := storageIndex(storageKey) + treeIndex, subIndex := StorageIndex(storageKey) return GetTreeKeyWithEvaluatedAddress(evaluated, treeIndex, subIndex) } diff --git a/trie/utils/verkle_test.go b/trie/utils/verkle_test.go index 28b059c379..dbec29685b 100644 --- a/trie/utils/verkle_test.go +++ b/trie/utils/verkle_test.go @@ -20,7 +20,7 @@ import ( "bytes" "testing" - "github.com/gballet/go-verkle" + "github.com/ethereum/go-verkle" "github.com/holiman/uint256" ) @@ -33,20 +33,11 @@ func TestTreeKey(t *testing.T) { smallStorage = []byte{0x1} largeStorage = bytes.Repeat([]byte{0xff}, 16) ) - if !bytes.Equal(VersionKey(address), VersionKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched version key") + if !bytes.Equal(BasicDataKey(address), BasicDataKeyWithEvaluatedAddress(addressEval)) { + t.Fatal("Unmatched basic data key") } - if !bytes.Equal(BalanceKey(address), BalanceKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched balance key") - } - if !bytes.Equal(NonceKey(address), NonceKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched nonce key") - } - if !bytes.Equal(CodeKeccakKey(address), CodeKeccakKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched code keccak key") - } - if !bytes.Equal(CodeSizeKey(address), CodeSizeKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched code size key") + if !bytes.Equal(CodeHashKey(address), CodeHashKeyWithEvaluatedAddress(addressEval)) { + t.Fatal("Unmatched code hash key") } if !bytes.Equal(CodeChunkKey(address, smallIndex), CodeChunkKeyWithEvaluatedAddress(addressEval, smallIndex)) { t.Fatal("Unmatched code chunk key") @@ -76,7 +67,7 @@ func BenchmarkTreeKey(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - BalanceKey([]byte{0x01}) + BasicDataKey([]byte{0x01}) } } @@ -96,7 +87,7 @@ func BenchmarkTreeKeyWithEvaluation(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - BalanceKeyWithEvaluatedAddress(eval) + BasicDataKeyWithEvaluatedAddress(eval) } } diff --git a/trie/verkle.go b/trie/verkle.go index 01d813d9ec..6bd9d3d1af 100644 --- a/trie/verkle.go +++ b/trie/verkle.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/utils" "github.com/ethereum/go-ethereum/triedb/database" - "github.com/gballet/go-verkle" + "github.com/ethereum/go-verkle" "github.com/holiman/uint256" ) @@ -69,6 +69,10 @@ func NewVerkleTrie(root common.Hash, db database.Database, cache *utils.PointCac }, nil } +func (t *VerkleTrie) FlatdbNodeResolver(path []byte) ([]byte, error) { + return t.reader.node(path, common.Hash{}) +} + // GetKey returns the sha3 preimage of a hashed key that was previously used // to store a value. func (t *VerkleTrie) GetKey(key []byte) []byte { @@ -96,20 +100,10 @@ func (t *VerkleTrie) GetAccount(addr common.Address) (*types.StateAccount, error if values == nil { return nil, nil } - // Decode nonce in little-endian - if len(values[utils.NonceLeafKey]) > 0 { - acc.Nonce = binary.LittleEndian.Uint64(values[utils.NonceLeafKey]) - } - // Decode balance in little-endian - var balance [32]byte - copy(balance[:], values[utils.BalanceLeafKey]) - for i := 0; i < len(balance)/2; i++ { - balance[len(balance)-i-1], balance[i] = balance[i], balance[len(balance)-i-1] - } - acc.Balance = new(uint256.Int).SetBytes32(balance[:]) - - // Decode codehash - acc.CodeHash = values[utils.CodeKeccakLeafKey] + basicData := values[utils.BasicDataLeafKey] + acc.Nonce = binary.BigEndian.Uint64(basicData[utils.BasicDataNonceOffset:]) + acc.Balance = new(uint256.Int).SetBytes(basicData[utils.BasicDataBalanceOffset : utils.BasicDataBalanceOffset+16]) + acc.CodeHash = values[utils.CodeHashLeafKey] // TODO account.Root is leave as empty. How should we handle the legacy account? return acc, nil @@ -129,38 +123,36 @@ func (t *VerkleTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) // UpdateAccount implements state.Trie, writing the provided account into the tree. // If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount) error { +func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount, codeLen int) error { var ( - err error - nonce, balance [32]byte - values = make([][]byte, verkle.NodeWidth) + err error + basicData [32]byte + values = make([][]byte, verkle.NodeWidth) + stem = t.cache.GetStem(addr[:]) ) - values[utils.VersionLeafKey] = zero[:] - values[utils.CodeKeccakLeafKey] = acc.CodeHash[:] - - // Encode nonce in little-endian - binary.LittleEndian.PutUint64(nonce[:], acc.Nonce) - values[utils.NonceLeafKey] = nonce[:] - - // Encode balance in little-endian - bytes := acc.Balance.Bytes() - if len(bytes) > 0 { - for i, b := range bytes { - balance[len(bytes)-i-1] = b - } + + // Code size is encoded in BasicData as a 3-byte big-endian integer. Spare bytes are present + // before the code size to support bigger integers in the future. PutUint32(...) requires + // 4 bytes, so we need to shift the offset 1 byte to the left. + binary.BigEndian.PutUint32(basicData[utils.BasicDataCodeSizeOffset-1:], uint32(codeLen)) + binary.BigEndian.PutUint64(basicData[utils.BasicDataNonceOffset:], acc.Nonce) + if acc.Balance.ByteLen() > 16 { + panic("balance too large") } - values[utils.BalanceLeafKey] = balance[:] + acc.Balance.WriteToSlice(basicData[utils.BasicDataBalanceOffset : utils.BasicDataBalanceOffset+16]) + values[utils.BasicDataLeafKey] = basicData[:] + values[utils.CodeHashLeafKey] = acc.CodeHash[:] - switch n := t.root.(type) { + switch root := t.root.(type) { case *verkle.InternalNode: - err = n.InsertValuesAtStem(t.cache.GetStem(addr[:]), values, t.nodeResolver) - if err != nil { - return fmt.Errorf("UpdateAccount (%x) error: %v", addr, err) - } + err = root.InsertValuesAtStem(stem, values, t.nodeResolver) default: return errInvalidRootType } - // TODO figure out if the code size needs to be updated, too + if err != nil { + return fmt.Errorf("UpdateAccount (%x) error: %v", addr, err) + } + return nil } @@ -201,6 +193,44 @@ func (t *VerkleTrie) DeleteAccount(addr common.Address) error { return nil } +// RollBackAccount removes the account info + code from the tree, unlike DeleteAccount +// that will overwrite it with 0s. The first 64 storage slots are also removed. +func (t *VerkleTrie) RollBackAccount(addr common.Address) error { + var ( + evaluatedAddr = t.cache.Get(addr.Bytes()) + basicDataKey = utils.BasicDataKeyWithEvaluatedAddress(evaluatedAddr) + ) + basicDataBytes, err := t.root.Get(basicDataKey, t.nodeResolver) + if err != nil { + return fmt.Errorf("rollback: error finding code size: %w", err) + } + if len(basicDataBytes) == 0 { + return errors.New("rollback: basic data is not existent") + } + // The code size is encoded in BasicData as a 3-byte big-endian integer. Spare bytes are present + // before the code size to support bigger integers in the future. + // LittleEndian.Uint32(...) expects 4-bytes, so we need to shift the offset 1-byte to the left. + codeSize := binary.BigEndian.Uint32(basicDataBytes[utils.BasicDataCodeSizeOffset-1:]) + + // Delete the account header + first 64 slots + first 128 code chunks + _, err = t.root.(*verkle.InternalNode).DeleteAtStem(basicDataKey[:31], t.nodeResolver) + if err != nil { + return fmt.Errorf("error rolling back account header: %w", err) + } + + // Delete all further code + for i, chunknr := uint64(31*128), uint64(128); i < uint64(codeSize); i, chunknr = i+31*256, chunknr+256 { + // evaluate group key at the start of a new group + offset := uint256.NewInt(chunknr) + key := utils.CodeChunkKeyWithEvaluatedAddress(evaluatedAddr, offset) + + if _, err = t.root.(*verkle.InternalNode).DeleteAtStem(key[:], t.nodeResolver); err != nil { + return fmt.Errorf("error deleting code chunk stem (addr=%x, offset=%d) error: %w", addr[:], offset, err) + } + } + return nil +} + // DeleteStorage implements state.Trie, deleting the specified storage slot from // the trie. If the storage slot was not existent in the trie, no error will be // returned. If the trie is corrupted, an error will be returned. @@ -217,22 +247,21 @@ func (t *VerkleTrie) Hash() common.Hash { } // Commit writes all nodes to the tree's memory database. -func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) { - root, ok := t.root.(*verkle.InternalNode) - if !ok { - return common.Hash{}, nil, errors.New("unexpected root node type") - } +func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet) { + root := t.root.(*verkle.InternalNode) nodes, err := root.BatchSerialize() if err != nil { - return common.Hash{}, nil, fmt.Errorf("serializing tree nodes: %s", err) + // Error return from this function indicates error in the code logic + // of BatchSerialize, and we fail catastrophically if this is the case. + panic(fmt.Errorf("BatchSerialize failed: %v", err)) } nodeset := trienode.NewNodeSet(common.Hash{}) for _, node := range nodes { - // hash parameter is not used in pathdb + // Hash parameter is not used in pathdb nodeset.AddNode(node.Path, trienode.New(common.Hash{}, node.SerializedBytes)) } // Serialize root commitment form - return t.Hash(), nodeset, nil + return t.Hash(), nodeset } // NodeIterator implements state.Trie, returning an iterator that returns @@ -270,6 +299,27 @@ func (t *VerkleTrie) IsVerkle() bool { return true } +// Proof builds and returns the verkle multiproof for keys, built against +// the pre tree. The post tree is passed in order to add the post values +// to that proof. +func (t *VerkleTrie) Proof(posttrie *VerkleTrie, keys [][]byte, resolver verkle.NodeResolverFn) (*verkle.VerkleProof, verkle.StateDiff, error) { + var postroot verkle.VerkleNode + if posttrie != nil { + postroot = posttrie.root + } + proof, _, _, _, err := verkle.MakeVerkleMultiProof(t.root, postroot, keys, resolver) + if err != nil { + return nil, nil, err + } + + p, kvps, err := verkle.SerializeProof(proof) + if err != nil { + return nil, nil, err + } + + return p, kvps, nil +} + // ChunkedCode represents a sequence of 32-bytes chunks of code (31 bytes of which // are actual code, and 1 byte is the pushdata offset). type ChunkedCode []byte @@ -327,6 +377,7 @@ func ChunkifyCode(code []byte) ChunkedCode { // UpdateContractCode implements state.Trie, writing the provided contract code // into the trie. +// Note that the code-size *must* be already saved by a previous UpdateAccount call. func (t *VerkleTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error { var ( chunks = ChunkifyCode(code) @@ -342,12 +393,6 @@ func (t *VerkleTrie) UpdateContractCode(addr common.Address, codeHash common.Has } values[groupOffset] = chunks[i : i+32] - // Reuse the calculated key to also update the code size. - if i == 0 { - cs := make([]byte, 32) - binary.LittleEndian.PutUint64(cs, uint64(len(code))) - values[utils.CodeSizeLeafKey] = cs - } if groupOffset == 255 || len(chunks)-i <= 32 { switch root := t.root.(type) { case *verkle.InternalNode: @@ -370,3 +415,8 @@ func (t *VerkleTrie) ToDot() string { func (t *VerkleTrie) nodeResolver(path []byte) ([]byte, error) { return t.reader.node(path, common.Hash{}) } + +// Witness returns a set containing all trie nodes that have been accessed. +func (t *VerkleTrie) Witness() map[string]struct{} { + panic("not implemented") +} diff --git a/trie/verkle_test.go b/trie/verkle_test.go index 0cbe28bf01..4cd1717c0e 100644 --- a/trie/verkle_test.go +++ b/trie/verkle_test.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) @@ -60,7 +61,7 @@ func TestVerkleTreeReadWrite(t *testing.T) { tr, _ := NewVerkleTrie(types.EmptyVerkleHash, db, utils.NewPointCache(100)) for addr, acct := range accounts { - if err := tr.UpdateAccount(addr, acct); err != nil { + if err := tr.UpdateAccount(addr, acct, 0); err != nil { t.Fatalf("Failed to update account, %v", err) } for key, val := range storages[addr] { @@ -89,3 +90,84 @@ func TestVerkleTreeReadWrite(t *testing.T) { } } } + +func TestVerkleRollBack(t *testing.T) { + db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme) + tr, _ := NewVerkleTrie(types.EmptyVerkleHash, db, utils.NewPointCache(100)) + + for addr, acct := range accounts { + // create more than 128 chunks of code + code := make([]byte, 129*32) + for i := 0; i < len(code); i += 2 { + code[i] = 0x60 + code[i+1] = byte(i % 256) + } + if err := tr.UpdateAccount(addr, acct, len(code)); err != nil { + t.Fatalf("Failed to update account, %v", err) + } + for key, val := range storages[addr] { + if err := tr.UpdateStorage(addr, key.Bytes(), val); err != nil { + t.Fatalf("Failed to update account, %v", err) + } + } + hash := crypto.Keccak256Hash(code) + if err := tr.UpdateContractCode(addr, hash, code); err != nil { + t.Fatalf("Failed to update contract, %v", err) + } + } + + // Check that things were created + for addr, acct := range accounts { + stored, err := tr.GetAccount(addr) + if err != nil { + t.Fatalf("Failed to get account, %v", err) + } + if !reflect.DeepEqual(stored, acct) { + t.Fatal("account is not matched") + } + for key, val := range storages[addr] { + stored, err := tr.GetStorage(addr, key.Bytes()) + if err != nil { + t.Fatalf("Failed to get storage, %v", err) + } + if !bytes.Equal(stored, val) { + t.Fatal("storage is not matched") + } + } + } + + // ensure there is some code in the 2nd group + keyOf2ndGroup := []byte{141, 124, 185, 236, 50, 22, 185, 39, 244, 47, 97, 209, 96, 235, 22, 13, 205, 38, 18, 201, 128, 223, 0, 59, 146, 199, 222, 119, 133, 13, 91, 0} + chunk, err := tr.root.Get(keyOf2ndGroup, nil) + if err != nil { + t.Fatalf("Failed to get account, %v", err) + } + if len(chunk) == 0 { + t.Fatal("account was not created ") + } + + // Rollback first account and check that it is gone + addr1 := common.Address{1} + err = tr.RollBackAccount(addr1) + if err != nil { + t.Fatalf("error rolling back address 1: %v", err) + } + + // ensure the account is gone + stored, err := tr.GetAccount(addr1) + if err != nil { + t.Fatalf("Failed to get account, %v", err) + } + if stored != nil { + t.Fatal("account was not deleted") + } + + // ensure that the last code chunk is also gone from the tree + chunk, err = tr.root.Get(keyOf2ndGroup, nil) + if err != nil { + t.Fatalf("Failed to get account, %v", err) + } + if len(chunk) != 0 { + t.Fatal("account was not deleted") + } +} diff --git a/triedb/database.go b/triedb/database.go index 66c2740911..3399813faf 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -24,7 +24,6 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/triedb/database" @@ -46,15 +45,21 @@ type Config struct { // default settings. var HashDefaults = &Config{ Preimages: false, + IsVerkle: false, HashDB: hashdb.Defaults, } +// VerkleDefaults represents a config for holding verkle trie data +// using path-based scheme with default settings. +var VerkleDefaults = &Config{ + Preimages: false, + IsVerkle: true, + PathDB: pathdb.Defaults, +} + // backend defines the methods needed to access/update trie nodes in different // state scheme. type backend interface { - // Scheme returns the identifier of used storage scheme. - Scheme() string - // Initialized returns an indicator if the state data is already initialized // according to the state scheme. Initialized(genesisRoot common.Hash) bool @@ -77,12 +82,17 @@ type backend interface { // Close closes the trie database backend and releases all held resources. Close() error + + // Reader returns a reader for accessing all trie nodes with provided state + // root. An error will be returned if the requested state is not available. + Reader(root common.Hash) (database.Reader, error) } // Database is the wrapper of the underlying backend which is shared by different // types of node backend as an entrypoint. It's responsible for all interactions // relevant with trie nodes and node preimages. type Database struct { + disk ethdb.Database config *Config // Configuration for trie database diskdb ethdb.Database // Persistent database to store the snapshot preimages *preimageStore // The store for caching preimages @@ -124,8 +134,9 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database { preimages = newPreimageStore(triediskdb) } db := &Database{ + disk: diskdb, config: config, - diskdb: triediskdb, + diskdb: diskdb, preimages: preimages, } /* @@ -137,29 +148,22 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database { if rawdb.ReadStateScheme(triediskdb) == rawdb.PathScheme { log.Warn("Incompatible state scheme", "old", rawdb.PathScheme, "new", rawdb.HashScheme) } - db.backend = hashdb.New(triediskdb, config.HashDB, trie.MerkleResolver{}) + db.backend = hashdb.New(triediskdb, config.HashDB) } else if config.PathDB != nil { if rawdb.ReadStateScheme(triediskdb) == rawdb.HashScheme { log.Warn("Incompatible state scheme", "old", rawdb.HashScheme, "new", rawdb.PathScheme) } - db.backend = pathdb.New(triediskdb, config.PathDB) + db.backend = pathdb.New(triediskdb, config.PathDB, config.IsVerkle) } else if strings.Compare(dbScheme, rawdb.PathScheme) == 0 { if config.PathDB == nil { config.PathDB = pathdb.Defaults } - db.backend = pathdb.New(triediskdb, config.PathDB) + db.backend = pathdb.New(triediskdb, config.PathDB, config.IsVerkle) } else { - var resolver hashdb.ChildResolver - if config.IsVerkle { - // TODO define verkle resolver - log.Crit("Verkle node resolver is not defined") - } else { - resolver = trie.MerkleResolver{} - } if config.HashDB == nil { config.HashDB = hashdb.Defaults } - db.backend = hashdb.New(triediskdb, config.HashDB, resolver) + db.backend = hashdb.New(triediskdb, config.HashDB) } return db } @@ -175,13 +179,7 @@ func (db *Database) DiskDB() ethdb.Database { // Reader returns a reader for accessing all trie nodes with provided state root. // An error will be returned if the requested state is not available. func (db *Database) Reader(blockRoot common.Hash) (database.Reader, error) { - switch b := db.backend.(type) { - case *hashdb.Database: - return b.Reader(blockRoot) - case *pathdb.Database: - return b.Reader(blockRoot) - } - return nil, errors.New("unknown backend") + return db.backend.Reader(blockRoot) } // Update performs a state transition by committing dirty nodes contained in the @@ -231,7 +229,10 @@ func (db *Database) Initialized(genesisRoot common.Hash) bool { // Scheme returns the node scheme used in the database. func (db *Database) Scheme() string { - return db.backend.Scheme() + if db.config.PathDB != nil { + return rawdb.PathScheme + } + return rawdb.HashScheme } // Close flushes the dangling preimages to disk and closes the trie database. @@ -315,14 +316,7 @@ func (db *Database) Recover(target common.Hash) error { if !ok { return errors.New("not supported") } - var loader triestate.TrieLoader - if db.config.IsVerkle { - // TODO define verkle loader - log.Crit("Verkle loader is not defined") - } else { - loader = trie.NewMerkleLoader(db) - } - return pdb.Recover(target, loader) + return pdb.Recover(target) } // Recoverable returns the indicator if the specified state is enabled to be @@ -409,3 +403,8 @@ func (db *Database) GetAllRooHash() [][]string { func (db *Database) IsVerkle() bool { return db.config.IsVerkle } + +// Disk returns the underlying disk database. +func (db *Database) Disk() ethdb.Database { + return db.disk +} diff --git a/triedb/database/database.go b/triedb/database/database.go index 18a8f454e2..9bd5da08d1 100644 --- a/triedb/database/database.go +++ b/triedb/database/database.go @@ -16,32 +16,21 @@ package database -import ( - "github.com/ethereum/go-ethereum/common" -) +import "github.com/ethereum/go-ethereum/common" // Reader wraps the Node method of a backing trie reader. type Reader interface { // Node retrieves the trie node blob with the provided trie identifier, // node path and the corresponding node hash. No error will be returned // if the node is not found. + // + // Don't modify the returned byte slice since it's not deep-copied and + // still be referenced by database. Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) } -// PreimageStore wraps the methods of a backing store for reading and writing -// trie node preimages. -type PreimageStore interface { - // Preimage retrieves the preimage of the specified hash. - Preimage(hash common.Hash) []byte - - // InsertPreimage commits a set of preimages along with their hashes. - InsertPreimage(preimages map[common.Hash][]byte) -} - // Database wraps the methods of a backing trie store. type Database interface { - PreimageStore - // Reader returns a node reader associated with the specific state. // An error will be returned if the specified state is not available. Reader(stateRoot common.Hash) (Reader, error) diff --git a/triedb/hashdb/database.go b/triedb/hashdb/database.go index a2c8e977d4..41a2a39fc1 100644 --- a/triedb/hashdb/database.go +++ b/triedb/hashdb/database.go @@ -31,8 +31,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" + "github.com/ethereum/go-ethereum/triedb/database" ) var ( @@ -59,12 +61,6 @@ var ( memcacheCommitBytesMeter = metrics.NewRegisteredMeter("hashdb/memcache/commit/bytes", nil) ) -// ChildResolver defines the required method to decode the provided -// trie node and iterate the children on top. -type ChildResolver interface { - ForEach(node []byte, onChild func(common.Hash)) -} - // Config contains the settings for database. type Config struct { CleanCacheSize int // Maximum memory allowance (in bytes) for caching clean nodes @@ -83,9 +79,7 @@ var Defaults = &Config{ // the disk database. The aim is to accumulate trie writes in-memory and only // periodically flush a couple tries to disk, garbage collecting the remainder. type Database struct { - diskdb ethdb.Database // Persistent storage for matured trie nodes - resolver ChildResolver // The handler to resolve children of nodes - + diskdb ethdb.Database // Persistent storage for matured trie nodes cleans *fastcache.Cache // GC friendly memory cache of clean node RLPs dirties map[common.Hash]*cachedNode // Data and references relationships of dirty trie nodes oldest common.Hash // Oldest tracked node, flush-list head @@ -123,15 +117,15 @@ var cachedNodeSize = int(reflect.TypeOf(cachedNode{}).Size()) // forChildren invokes the callback for all the tracked children of this node, // both the implicit ones from inside the node as well as the explicit ones // from outside the node. -func (n *cachedNode) forChildren(resolver ChildResolver, onChild func(hash common.Hash)) { +func (n *cachedNode) forChildren(onChild func(hash common.Hash)) { for child := range n.external { onChild(child) } - resolver.ForEach(n.node, onChild) + trie.ForGatherChildren(n.node, onChild) } // New initializes the hash-based node database. -func New(diskdb ethdb.Database, config *Config, resolver ChildResolver) *Database { +func New(diskdb ethdb.Database, config *Config) *Database { if config == nil { config = Defaults } @@ -140,10 +134,9 @@ func New(diskdb ethdb.Database, config *Config, resolver ChildResolver) *Databas cleans = fastcache.New(config.CleanCacheSize) } return &Database{ - diskdb: diskdb, - resolver: resolver, - cleans: cleans, - dirties: make(map[common.Hash]*cachedNode), + diskdb: diskdb, + cleans: cleans, + dirties: make(map[common.Hash]*cachedNode), } } @@ -162,7 +155,7 @@ func (db *Database) insert(hash common.Hash, node []byte) { node: node, flushPrev: db.newest, } - entry.forChildren(db.resolver, func(child common.Hash) { + entry.forChildren(func(child common.Hash) { if c := db.dirties[child]; c != nil { c.parents++ } @@ -315,7 +308,7 @@ func (db *Database) dereference(hash common.Hash) { db.dirties[node.flushNext].flushPrev = node.flushPrev } // Dereference all children and delete the node - node.forChildren(db.resolver, func(child common.Hash) { + node.forChildren(func(child common.Hash) { db.dereference(child) }) delete(db.dirties, hash) @@ -466,7 +459,7 @@ func (db *Database) commit(hash common.Hash, batch ethdb.Batch, uncacher *cleane var err error // Dereference all children and delete the node - node.forChildren(db.resolver, func(child common.Hash) { + node.forChildren(func(child common.Hash) { if err == nil { err = db.commit(child, batch, uncacher) } @@ -621,19 +614,13 @@ func (db *Database) Size() (common.StorageSize, common.StorageSize, common.Stora func (db *Database) Close() error { if db.cleans != nil { db.cleans.Reset() - db.cleans = nil } return nil } -// Scheme returns the node scheme used in the database. -func (db *Database) Scheme() string { - return rawdb.HashScheme -} - // Reader retrieves a node reader belonging to the given state root. // An error will be returned if the requested state is not available. -func (db *Database) Reader(root common.Hash) (*reader, error) { +func (db *Database) Reader(root common.Hash) (database.Reader, error) { if _, err := db.node(root); err != nil { return nil, fmt.Errorf("state %#x is not available, %v", root, err) } diff --git a/triedb/history.go b/triedb/history.go new file mode 100644 index 0000000000..f663cdd7c2 --- /dev/null +++ b/triedb/history.go @@ -0,0 +1,72 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package triedb + +import ( + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/triedb/pathdb" +) + +// AccountHistory inspects the account history within the specified range. +// +// Start: State ID of the first history object for the query. 0 implies the first +// available object is selected as the starting point. +// +// End: State ID of the last history for the query. 0 implies the last available +// object is selected as the starting point. Note end is included for query. +// +// This function is only supported by path mode database. +func (db *Database) AccountHistory(address common.Address, start, end uint64) (*pathdb.HistoryStats, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return nil, errors.New("not supported") + } + return pdb.AccountHistory(address, start, end) +} + +// StorageHistory inspects the storage history within the specified range. +// +// Start: State ID of the first history object for the query. 0 implies the first +// available object is selected as the starting point. +// +// End: State ID of the last history for the query. 0 implies the last available +// object is selected as the starting point. Note end is included for query. +// +// Note, slot refers to the hash of the raw slot key. +// +// This function is only supported by path mode database. +func (db *Database) StorageHistory(address common.Address, slot common.Hash, start uint64, end uint64) (*pathdb.HistoryStats, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return nil, errors.New("not supported") + } + return pdb.StorageHistory(address, slot, start, end) +} + +// HistoryRange returns the block numbers associated with earliest and latest +// state history in the local store. +// +// This function is only supported by path mode database. +func (db *Database) HistoryRange() (uint64, uint64, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return 0, 0, errors.New("not supported") + } + return pdb.HistoryRange() +} diff --git a/triedb/pathdb/asyncnodebuffer.go b/triedb/pathdb/asyncnodebuffer.go index a94fab4461..71c90991bb 100644 --- a/triedb/pathdb/asyncnodebuffer.go +++ b/triedb/pathdb/asyncnodebuffer.go @@ -1,6 +1,7 @@ package pathdb import ( + "bytes" "errors" "fmt" "sync" @@ -48,18 +49,18 @@ func newAsyncNodeBuffer(limit int, nodes map[common.Hash]map[string]*trienode.No } // node retrieves the trie node with given node info. -func (a *asyncnodebuffer) node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) { +func (a *asyncnodebuffer) node(owner common.Hash, path []byte) (*trienode.Node, bool) { a.mux.RLock() defer a.mux.RUnlock() - node, err := a.current.node(owner, path, hash) - if err != nil { - return nil, err + node, found := a.current.node(owner, path) + if !found { + return nil, false } if node == nil { - return a.background.node(owner, path, hash) + return a.background.node(owner, path) } - return node, nil + return node, true } // commit merges the dirty nodes into the nodebuffer. This operation won't take @@ -215,21 +216,16 @@ func newNodeCache(limit, size uint64, nodes map[common.Hash]map[string]*trienode } } -func (nc *nodecache) node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) { +func (nc *nodecache) node(owner common.Hash, path []byte) (*trienode.Node, bool) { subset, ok := nc.nodes[owner] if !ok { - return nil, nil + return nil, false } n, ok := subset[string(path)] if !ok { - return nil, nil - } - if n.Hash != hash { - dirtyFalseMeter.Mark(1) - log.Error("Unexpected trie node in async node buffer", "owner", owner, "path", path, "expect", hash, "got", n.Hash) - return nil, newUnexpectedNodeError("dirty", hash, n.Hash, owner, path, n.Blob) + return nil, false } - return n, nil + return n, true } func (nc *nodecache) commit(nodes map[common.Hash]map[string]*trienode.Node) error { @@ -416,14 +412,13 @@ func (nc *nodecache) revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[s // // In case of database rollback, don't panic if this "clean" // node occurs which is not present in buffer. - var nhash common.Hash + var blob []byte if owner == (common.Hash{}) { - _, nhash = rawdb.ReadAccountTrieNode(db, []byte(path)) + blob = rawdb.ReadAccountTrieNode(db, []byte(path)) } else { - _, nhash = rawdb.ReadStorageTrieNode(db, owner, []byte(path)) + blob = rawdb.ReadStorageTrieNode(db, owner, []byte(path)) } - // Ignore the clean node in the case described above. - if nhash == n.Hash { + if bytes.Equal(blob, n.Blob) { continue } panic(fmt.Sprintf("non-existent node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex())) diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index f60677fc93..c3427a7b93 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -37,9 +38,6 @@ import ( ) const ( - // maxDiffLayers is the maximum diff layers allowed in the layer tree. - maxDiffLayers = 128 - // defaultCleanSize is the default memory allowance of clean cache. defaultCleanSize = 16 * 1024 * 1024 @@ -72,14 +70,20 @@ const ( JournalFileType ) +var ( + // maxDiffLayers is the maximum diff layers allowed in the layer tree. + maxDiffLayers = 128 +) + // layer is the interface implemented by all state layers which includes some // public methods and some additional methods for internal usage. type layer interface { - // Node retrieves the trie node with the node info. An error will be returned - // if the read operation exits abnormally. For example, if the layer is already - // stale, or the associated state is regarded as corrupted. Notably, no error - // will be returned if the requested node is not found in database. - Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) + // node retrieves the trie node with the node info. An error will be returned + // if the read operation exits abnormally. Specifically, if the layer is + // already stale. + // + // Note, no error will be returned if the requested node is not found in database. + node(owner common.Hash, path []byte, depth int) ([]byte, common.Hash, *nodeLoc, error) // rootHash returns the root hash for which this layer was made. rootHash() common.Hash @@ -150,27 +154,37 @@ type Database struct { // readOnly is the flag whether the mutation is allowed to be applied. // It will be set automatically when the database is journaled during // the shutdown to reject all following unexpected mutations. - readOnly bool // Flag if database is opened in read only mode - waitSync bool // Flag if database is deactivated due to initial state sync - bufferSize int // Memory allowance (in bytes) for caching dirty nodes - config *Config // Configuration for database - diskdb ethdb.Database // Persistent storage for matured trie nodes - tree *layerTree // The group for all known layers - freezer *rawdb.ResettableFreezer // Freezer for storing trie histories, nil possible in tests - lock sync.RWMutex // Lock to prevent mutations from happening at the same time + readOnly bool // Flag if database is opened in read only mode + waitSync bool // Flag if database is deactivated due to initial state sync + isVerkle bool // Flag if database is used for verkle tree + bufferSize int // Memory allowance (in bytes) for caching dirty nodes + config *Config // Configuration for database + diskdb ethdb.Database // Persistent storage for matured trie nodes + tree *layerTree // The group for all known layers + freezer ethdb.ResettableAncientStore // Freezer for storing trie histories, nil possible in tests + lock sync.RWMutex // Lock to prevent mutations from happening at the same time } // New attempts to load an already existing layer from a persistent key-value // store (with a number of memory layers from a journal). If the journal is not // matched with the base persistent layer, all the recorded diff layers are discarded. -func New(diskdb ethdb.Database, config *Config) *Database { +func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { if config == nil { config = Defaults } config = config.sanitize() + // Establish a dedicated database namespace tailored for verkle-specific + // data, ensuring the isolation of both verkle and merkle tree data. It's + // important to note that the introduction of a prefix won't lead to + // substantial storage overhead, as the underlying database will efficiently + // compress the shared key prefix. + if isVerkle { + diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) + } db := &Database{ readOnly: config.ReadOnly, + isVerkle: isVerkle, bufferSize: config.DirtyCacheSize, config: config, diskdb: diskdb, @@ -179,46 +193,10 @@ func New(diskdb ethdb.Database, config *Config) *Database { // and in-memory layer journal. db.tree = newLayerTree(db.loadLayers()) - // Open the freezer for state history if the passed database contains an - // ancient store. Otherwise, all the relevant functionalities are disabled. - // - // Because the freezer can only be opened once at the same time, this - // mechanism also ensures that at most one **non-readOnly** database - // is opened at the same time to prevent accidental mutation. - if ancient, err := diskdb.AncientDatadir(); err == nil && ancient != "" && !db.readOnly && !config.NoTries { - offset := uint64(0) // differ from in block data, only metadata is used in state data - freezer, err := rawdb.NewStateFreezer(ancient, false, offset) - if err != nil { - log.Crit("Failed to open state history freezer", "err", err) - } - db.freezer = freezer - - diskLayerID := db.tree.bottom().stateID() - if diskLayerID == 0 { - // Reset the entire state histories in case the trie database is - // not initialized yet, as these state histories are not expected. - frozen, err := db.freezer.Ancients() - if err != nil { - log.Crit("Failed to retrieve head of state history", "err", err) - } - if frozen != 0 { - err := db.freezer.Reset() - if err != nil { - log.Crit("Failed to reset state histories", "err", err) - } - log.Info("Truncated extraneous state history") - } - } else { - // Truncate the extra state histories above in freezer in case - // it's not aligned with the disk layer. - pruned, err := truncateFromHead(db.diskdb, freezer, diskLayerID) - if err != nil { - log.Crit("Failed to truncate extra state histories", "err", err) - } - if pruned != 0 { - log.Warn("Truncated extra state histories", "number", pruned) - } - } + // Repair the state history, which might not be aligned with the state + // in the key-value store due to an unclean shutdown. + if err := db.repairHistory(); err != nil { + log.Crit("Failed to repair pathdb", "err", err) } // Disable database in case node is still in the initial state sync stage. if rawdb.ReadSnapSyncStatusFlag(diskdb) == rawdb.StateSyncRunning && !db.readOnly { @@ -229,13 +207,57 @@ func New(diskdb ethdb.Database, config *Config) *Database { return db } -// Reader retrieves a layer belonging to the given state root. -func (db *Database) Reader(root common.Hash) (layer, error) { - l := db.tree.get(root) - if l == nil { - return nil, fmt.Errorf("state %#x is not available", root) +// repairHistory truncates leftover state history objects, which may occur due +// to an unclean shutdown or other unexpected reasons. +func (db *Database) repairHistory() error { + if !db.config.NoTries { + return nil + } + // Open the freezer for state history. This mechanism ensures that + // only one database instance can be opened at a time to prevent + // accidental mutation. + ancient, err := db.diskdb.AncientDatadir() + if err != nil { + // TODO error out if ancient store is disabled. A tons of unit tests + // disable the ancient store thus the error here will immediately fail + // all of them. Fix the tests first. + return nil + } + offset := uint64(0) // differ from in block data, only metadata is used in state data + freezer, err := rawdb.NewStateFreezer(ancient, db.isVerkle, db.readOnly, offset) + if err != nil { + log.Crit("Failed to open state history freezer", "err", err) + } + db.freezer = freezer + + // Reset the entire state histories if the trie database is not initialized + // yet. This action is necessary because these state histories are not + // expected to exist without an initialized trie database. + id := db.tree.bottom().stateID() + if id == 0 { + frozen, err := db.freezer.Ancients() + if err != nil { + log.Crit("Failed to retrieve head of state history", "err", err) + } + if frozen != 0 { + err := db.freezer.Reset() + if err != nil { + log.Crit("Failed to reset state histories", "err", err) + } + log.Info("Truncated extraneous state history") + } + return nil } - return l, nil + // Truncate the extra state histories above in freezer in case it's not + // aligned with the disk layer. It might happen after a unclean shutdown. + pruned, err := truncateFromHead(db.diskdb, db.freezer, id) + if err != nil { + log.Crit("Failed to truncate extra state histories", "err", err) + } + if pruned != 0 { + log.Warn("Truncated extra state histories", "number", pruned) + } + return nil } // Update adds a new layer into the tree, if that can be linked to an existing @@ -319,7 +341,10 @@ func (db *Database) Enable(root common.Hash) error { } // Ensure the provided state root matches the stored one. root = types.TrieRootHash(root) - _, stored := rawdb.ReadAccountTrieNode(db.diskdb, nil) + stored := types.EmptyRootHash + if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { + stored = crypto.Keccak256Hash(blob) + } if stored != root { return fmt.Errorf("state root mismatch: stored %x, synced %x", stored, root) } @@ -355,7 +380,7 @@ func (db *Database) Enable(root common.Hash) error { // Recover rollbacks the database to a specified historical point. // The state is supported as the rollback destination only if it's // canonical state and the corresponding trie histories are existent. -func (db *Database) Recover(root common.Hash, loader triestate.TrieLoader) error { +func (db *Database) Recover(root common.Hash) error { db.lock.Lock() defer db.lock.Unlock() @@ -381,7 +406,7 @@ func (db *Database) Recover(root common.Hash, loader triestate.TrieLoader) error if err != nil { return err } - dl, err = dl.revert(h, loader) + dl, err = dl.revert(h) if err != nil { return err } @@ -414,17 +439,20 @@ func (db *Database) Recoverable(root common.Hash) bool { if *id >= dl.stateID() { return false } + // This is a temporary workaround for the unavailability of the freezer in + // dev mode. As a consequence, the Pathdb loses the ability for deep reorg + // in certain cases. + // TODO(rjl493456442): Implement the in-memory ancient store. + if db.freezer == nil { + return false + } // Ensure the requested state is a canonical state and all state // histories in range [id+1, disklayer.ID] are present and complete. - parent := root return checkHistories(db.freezer, *id+1, dl.stateID()-*id, func(m *meta) error { - if m.parent != parent { + if m.parent != root { return errors.New("unexpected state history") } - if len(m.incomplete) > 0 { - return errors.New("incomplete state history") - } - parent = m.root + root = m.root return nil }) == nil } @@ -572,3 +600,33 @@ func (db *Database) DeleteTrieJournal(writer ethdb.KeyValueWriter) error { } return nil } + +// AccountHistory inspects the account history within the specified range. +// +// Start: State ID of the first history object for the query. 0 implies the first +// available object is selected as the starting point. +// +// End: State ID of the last history for the query. 0 implies the last available +// object is selected as the ending point. Note end is included in the query. +func (db *Database) AccountHistory(address common.Address, start, end uint64) (*HistoryStats, error) { + return accountHistory(db.freezer, address, start, end) +} + +// StorageHistory inspects the storage history within the specified range. +// +// Start: State ID of the first history object for the query. 0 implies the first +// available object is selected as the starting point. +// +// End: State ID of the last history for the query. 0 implies the last available +// object is selected as the ending point. Note end is included in the query. +// +// Note, slot refers to the hash of the raw slot key. +func (db *Database) StorageHistory(address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) { + return storageHistory(db.freezer, address, slot, start, end) +} + +// HistoryRange returns the block numbers associated with earliest and latest +// state history in the local store. +func (db *Database) HistoryRange() (uint64, uint64, error) { + return historyRange(db.freezer) +} diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 368f1e5a8f..be2c052047 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -27,34 +27,40 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie/testutil" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" "github.com/holiman/uint256" ) -func updateTrie(addrHash common.Hash, root common.Hash, dirties, cleans map[common.Hash][]byte) (common.Hash, *trienode.NodeSet) { - h, err := newTestHasher(addrHash, root, cleans) +func updateTrie(db *Database, stateRoot common.Hash, addrHash common.Hash, root common.Hash, dirties map[common.Hash][]byte) (common.Hash, *trienode.NodeSet) { + var id *trie.ID + if addrHash == (common.Hash{}) { + id = trie.StateTrieID(stateRoot) + } else { + id = trie.StorageTrieID(stateRoot, addrHash, root) + } + tr, err := trie.New(id, db) if err != nil { - panic(fmt.Errorf("failed to create hasher, err: %w", err)) + panic(fmt.Errorf("failed to load trie, err: %w", err)) } for key, val := range dirties { if len(val) == 0 { - h.Delete(key.Bytes()) + tr.Delete(key.Bytes()) } else { - h.Update(key.Bytes(), val) + tr.Update(key.Bytes(), val) } } - root, nodes, _ := h.Commit(false) - return root, nodes + return tr.Commit(false) } func generateAccount(storageRoot common.Hash) types.StateAccount { return types.StateAccount{ Nonce: uint64(rand.Intn(100)), Balance: uint256.NewInt(rand.Uint64()), - CodeHash: testutil.RandBytes(32), + CodeHash: testrand.Bytes(32), Root: storageRoot, } } @@ -67,6 +73,7 @@ const ( ) type genctx struct { + stateRoot common.Hash accounts map[common.Hash][]byte storages map[common.Hash]map[common.Hash][]byte accountOrigin map[common.Address][]byte @@ -74,8 +81,9 @@ type genctx struct { nodes *trienode.MergedNodeSet } -func newCtx() *genctx { +func newCtx(stateRoot common.Hash) *genctx { return &genctx{ + stateRoot: stateRoot, accounts: make(map[common.Hash][]byte), storages: make(map[common.Hash]map[common.Hash][]byte), accountOrigin: make(map[common.Address][]byte), @@ -101,9 +109,9 @@ func newTester(t *testing.T, historyLimit uint64) *tester { disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) db = New(disk, &Config{ StateHistory: historyLimit, - CleanCacheSize: 256 * 1024, - DirtyCacheSize: 256 * 1024, - }) + CleanCacheSize: 16 * 1024, + DirtyCacheSize: 16 * 1024, + }, false) obj = &tester{ db: db, preimages: make(map[common.Hash]common.Address), @@ -113,7 +121,7 @@ func newTester(t *testing.T, historyLimit uint64) *tester { snapStorages: make(map[common.Hash]map[common.Hash]map[common.Hash][]byte), } ) - for i := 0; i < 2*128; i++ { + for i := 0; i < 12; i++ { var parent = types.EmptyRootHash if len(obj.roots) != 0 { parent = obj.roots[len(obj.roots)-1] @@ -146,13 +154,13 @@ func (t *tester) generateStorage(ctx *genctx, addr common.Address) common.Hash { origin = make(map[common.Hash][]byte) ) for i := 0; i < 10; i++ { - v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testutil.RandBytes(32))) - hash := testutil.RandomHash() + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) + hash := testrand.Hash() storage[hash] = v origin[hash] = nil } - root, set := updateTrie(addrHash, types.EmptyRootHash, storage, nil) + root, set := updateTrie(t.db, ctx.stateRoot, addrHash, types.EmptyRootHash, storage) ctx.storages[addrHash] = storage ctx.storageOrigin[addr] = origin @@ -175,13 +183,13 @@ func (t *tester) mutateStorage(ctx *genctx, addr common.Address, root common.Has } } for i := 0; i < 3; i++ { - v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testutil.RandBytes(32))) - hash := testutil.RandomHash() + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) + hash := testrand.Hash() storage[hash] = v origin[hash] = nil } - root, set := updateTrie(crypto.Keccak256Hash(addr.Bytes()), root, storage, t.storages[addrHash]) + root, set := updateTrie(t.db, ctx.stateRoot, crypto.Keccak256Hash(addr.Bytes()), root, storage) ctx.storages[addrHash] = storage ctx.storageOrigin[addr] = origin @@ -199,7 +207,7 @@ func (t *tester) clearStorage(ctx *genctx, addr common.Address, root common.Hash origin[hash] = val storage[hash] = nil } - root, set := updateTrie(addrHash, root, storage, t.storages[addrHash]) + root, set := updateTrie(t.db, ctx.stateRoot, addrHash, root, storage) if root != types.EmptyRootHash { panic("failed to clear storage trie") } @@ -211,14 +219,14 @@ func (t *tester) clearStorage(ctx *genctx, addr common.Address, root common.Hash func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNodeSet, *triestate.Set) { var ( - ctx = newCtx() + ctx = newCtx(parent) dirties = make(map[common.Hash]struct{}) ) for i := 0; i < 20; i++ { switch rand.Intn(opLen) { case createAccountOp: // account creation - addr := testutil.RandomAddress() + addr := testrand.Address() addrHash := crypto.Keccak256Hash(addr.Bytes()) if _, ok := t.accounts[addrHash]; ok { continue @@ -272,7 +280,7 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode ctx.accountOrigin[addr] = account } } - root, set := updateTrie(common.Hash{}, parent, ctx.accounts, t.accounts) + root, set := updateTrie(t.db, parent, common.Hash{}, parent, ctx.accounts) ctx.nodes.Merge(set) // Save state snapshot before commit @@ -298,8 +306,11 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode t.storages[addrHash][sHash] = slot } } + if len(t.storages[addrHash]) == 0 { + delete(t.storages, addrHash) + } } - return root, ctx.nodes, triestate.New(ctx.accountOrigin, ctx.storageOrigin, nil) + return root, ctx.nodes, triestate.New(ctx.accountOrigin, ctx.storageOrigin) } // lastHash returns the latest root hash, or empty if nothing is cached. @@ -311,23 +322,31 @@ func (t *tester) lastHash() common.Hash { } func (t *tester) verifyState(root common.Hash) error { - reader, err := t.db.Reader(root) + tr, err := trie.New(trie.StateTrieID(root), t.db) if err != nil { return err } - _, err = reader.Node(common.Hash{}, nil, root) - if err != nil { - return errors.New("root node is not available") - } for addrHash, account := range t.snapAccounts[root] { - blob, err := reader.Node(common.Hash{}, addrHash.Bytes(), crypto.Keccak256Hash(account)) + blob, err := tr.Get(addrHash.Bytes()) if err != nil || !bytes.Equal(blob, account) { return fmt.Errorf("account is mismatched: %w", err) } } for addrHash, slots := range t.snapStorages[root] { + blob := t.snapAccounts[root][addrHash] + if len(blob) == 0 { + return fmt.Errorf("account %x is missing", addrHash) + } + account := new(types.StateAccount) + if err := rlp.DecodeBytes(blob, account); err != nil { + return err + } + storageIt, err := trie.New(trie.StorageTrieID(root, addrHash, account.Root), t.db) + if err != nil { + return err + } for hash, slot := range slots { - blob, err := reader.Node(addrHash, hash.Bytes(), crypto.Keccak256Hash(slot)) + blob, err := storageIt.Get(hash.Bytes()) if err != nil || !bytes.Equal(blob, slot) { return fmt.Errorf("slot is mismatched: %w", err) } @@ -379,6 +398,12 @@ func (t *tester) bottomIndex() int { } func TestDatabaseRollback(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + // Verify state histories tester := newTester(t, 0) defer tester.release() @@ -388,16 +413,18 @@ func TestDatabaseRollback(t *testing.T) { } // Revert database from top to bottom for i := tester.bottomIndex(); i >= 0; i-- { - root := tester.roots[i] parent := types.EmptyRootHash if i > 0 { parent = tester.roots[i-1] } - loader := newHashLoader(tester.snapAccounts[root], tester.snapStorages[root]) - if err := tester.db.Recover(parent, loader); err != nil { + if err := tester.db.Recover(parent); err != nil { t.Fatalf("Failed to revert db, err: %v", err) } - tester.verifyState(parent) + if i > 0 { + if err := tester.verifyState(parent); err != nil { + t.Fatalf("Failed to verify state, err: %v", err) + } + } } if tester.db.tree.len() != 1 { t.Fatal("Only disk layer is expected") @@ -405,6 +432,12 @@ func TestDatabaseRollback(t *testing.T) { } func TestDatabaseRecoverable(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + var ( tester = newTester(t, 0) index = tester.bottomIndex() @@ -444,18 +477,24 @@ func TestDatabaseRecoverable(t *testing.T) { } func TestDisable(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + tester := newTester(t, 0) defer tester.release() - _, stored := rawdb.ReadAccountTrieNode(tester.db.diskdb, nil) + stored := crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)) if err := tester.db.Disable(); err != nil { - t.Fatal("Failed to deactivate database") + t.Fatalf("Failed to deactivate database: %v", err) } if err := tester.db.Enable(types.EmptyRootHash); err == nil { - t.Fatalf("Invalid activation should be rejected") + t.Fatal("Invalid activation should be rejected") } if err := tester.db.Enable(stored); err != nil { - t.Fatal("Failed to activate database") + t.Fatalf("Failed to activate database: %v", err) } // Ensure journal is deleted from disk @@ -480,6 +519,12 @@ func TestDisable(t *testing.T) { } func TestCommit(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + tester := newTester(t, 0) defer tester.release() @@ -504,6 +549,12 @@ func TestCommit(t *testing.T) { } func TestJournal(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + tester := newTester(t, 0) defer tester.release() @@ -511,7 +562,7 @@ func TestJournal(t *testing.T) { t.Errorf("Failed to journal, err: %v", err) } tester.db.Close() - tester.db = New(tester.db.diskdb, nil) + tester.db = New(tester.db.diskdb, nil, false) // Verify states including disk layer and all diff on top. for i := 0; i < len(tester.roots); i++ { @@ -528,6 +579,12 @@ func TestJournal(t *testing.T) { } func TestCorruptedJournal(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + tester := newTester(t, 0) defer tester.release() @@ -535,15 +592,15 @@ func TestCorruptedJournal(t *testing.T) { t.Errorf("Failed to journal, err: %v", err) } tester.db.Close() - _, root := rawdb.ReadAccountTrieNode(tester.db.diskdb, nil) + root := crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)) // Mutate the journal in disk, it should be regarded as invalid blob := rawdb.ReadTrieJournal(tester.db.diskdb) - blob[0] = 1 + blob[0] = 0xa rawdb.WriteTrieJournal(tester.db.diskdb, blob) // Verify states, all not-yet-written states should be discarded - tester.db = New(tester.db.diskdb, nil) + tester.db = New(tester.db.diskdb, nil, false) for i := 0; i < len(tester.roots); i++ { if tester.roots[i] == root { if err := tester.verifyState(root); err != nil { @@ -570,11 +627,17 @@ func TestCorruptedJournal(t *testing.T) { // truncating the tail histories. This ensures that the ID of the persistent state // always falls within the range of [oldest-history-id, latest-history-id]. func TestTailTruncateHistory(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + tester := newTester(t, 10) defer tester.release() tester.db.Close() - tester.db = New(tester.db.diskdb, &Config{StateHistory: 10}) + tester.db = New(tester.db.diskdb, &Config{StateHistory: 10}, false) head, err := tester.db.freezer.Ancients() if err != nil { diff --git a/triedb/pathdb/difflayer.go b/triedb/pathdb/difflayer.go index fca184adfe..b370925f62 100644 --- a/triedb/pathdb/difflayer.go +++ b/triedb/pathdb/difflayer.go @@ -218,10 +218,9 @@ func (dl *diffLayer) parentLayer() layer { return dl.parent } -// node retrieves the node with provided node information. It's the internal -// version of Node function with additional accessed layer tracked. No error -// will be returned if node is not found. -func (dl *diffLayer) node(owner common.Hash, path []byte, hash common.Hash, depth int) ([]byte, error) { +// node implements the layer interface, retrieving the trie node blob with the +// provided node information. No error will be returned if the node is not found. +func (dl *diffLayer) node(owner common.Hash, path []byte, depth int) ([]byte, common.Hash, *nodeLoc, error) { // Hold the lock, ensure the parent won't be changed during the // state accessing. dl.lock.RLock() @@ -232,57 +231,14 @@ func (dl *diffLayer) node(owner common.Hash, path []byte, hash common.Hash, dept if ok { n, ok := subset[string(path)] if ok { - // If the trie node is not hash matched, or marked as removed, - // bubble up an error here. It shouldn't happen at all. - if n.Hash != hash { - dirtyFalseMeter.Mark(1) - log.Error("Unexpected trie node in diff layer", "owner", owner, "path", path, "expect", hash, "got", n.Hash) - return nil, newUnexpectedNodeError("diff", hash, n.Hash, owner, path, n.Blob) - } dirtyHitMeter.Mark(1) dirtyNodeHitDepthHist.Update(int64(depth)) dirtyReadMeter.Mark(int64(len(n.Blob))) - return n.Blob, nil + return n.Blob, n.Hash, &nodeLoc{loc: locDiffLayer, depth: depth}, nil } } // Trie node unknown to this layer, resolve from parent - if diff, ok := dl.parent.(*diffLayer); ok { - return diff.node(owner, path, hash, depth+1) - } - // Failed to resolve through diff layers, fallback to disk layer - return dl.parent.Node(owner, path, hash) -} - -// Node implements the layer interface, retrieving the trie node blob with the -// provided node information. No error will be returned if the node is not found. -func (dl *diffLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { - if n := dl.cache.Get(hash); n != nil { - // The query from the hash map is fastpath, - // avoiding recursive query of 128 difflayers. - diffHashCacheHitMeter.Mark(1) - diffHashCacheReadMeter.Mark(int64(len(n.Blob))) - return n.Blob, nil - } - diffHashCacheMissMeter.Mark(1) - - persistLayer := dl.originDiskLayer() - if persistLayer != nil { - blob, err := persistLayer.Node(owner, path, hash) - if err != nil { - // This is a bad case with a very low probability. - // r/w the difflayer cache and r/w the disklayer are not in the same lock, - // so in extreme cases, both reading the difflayer cache and reading the disklayer may fail, eg, disklayer is stale. - // In this case, fallback to the original 128-layer recursive difflayer query path. - diffHashCacheSlowPathMeter.Mark(1) - log.Debug("Retry difflayer due to query origin failed", "owner", owner, "path", path, "hash", hash.String(), "error", err) - return dl.node(owner, path, hash, 0) - } else { // This is the fastpath. - return blob, nil - } - } - diffHashCacheSlowPathMeter.Mark(1) - log.Debug("Retry difflayer due to origin is nil", "owner", owner, "path", path, "hash", hash.String()) - return dl.node(owner, path, hash, 0) + return dl.parent.node(owner, path, depth+1) } // update implements the layer interface, creating a new layer on top of the diff --git a/triedb/pathdb/difflayer_test.go b/triedb/pathdb/difflayer_test.go index ab69a24d3d..14e021c88c 100644 --- a/triedb/pathdb/difflayer_test.go +++ b/triedb/pathdb/difflayer_test.go @@ -22,13 +22,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/trie/testutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/trie/trienode" ) func emptyLayer() *diskLayer { return &diskLayer{ - db: New(rawdb.NewMemoryDatabase(), nil), + db: New(rawdb.NewMemoryDatabase(), nil, false), buffer: newNodeBuffer(DefaultDirtyBufferSize, nil, 0), } } @@ -57,7 +58,6 @@ func BenchmarkSearch1Layer(b *testing.B) { benchmarkSearch(b, 127, 128) } func benchmarkSearch(b *testing.B, depth int, total int) { var ( npath []byte - nhash common.Hash nblob []byte ) // First, we set up 128 diff layers, with 3K items each @@ -66,14 +66,14 @@ func benchmarkSearch(b *testing.B, depth int, total int) { nodes[common.Hash{}] = make(map[string]*trienode.Node) for i := 0; i < 3000; i++ { var ( - path = testutil.RandBytes(32) - node = testutil.RandomNode() + path = testrand.Bytes(32) + blob = testrand.Bytes(100) + node = trienode.New(crypto.Keccak256Hash(blob), blob) ) - nodes[common.Hash{}][string(path)] = trienode.New(node.Hash, node.Blob) + nodes[common.Hash{}][string(path)] = node if npath == nil && depth == index { npath = common.CopyBytes(path) - nblob = common.CopyBytes(node.Blob) - nhash = node.Hash + nblob = common.CopyBytes(blob) } } return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil) @@ -90,7 +90,7 @@ func benchmarkSearch(b *testing.B, depth int, total int) { err error ) for i := 0; i < b.N; i++ { - have, err = layer.Node(common.Hash{}, npath, nhash) + have, _, _, err = layer.node(common.Hash{}, npath, 0) if err != nil { b.Fatal(err) } @@ -112,10 +112,11 @@ func BenchmarkPersist(b *testing.B) { nodes[common.Hash{}] = make(map[string]*trienode.Node) for i := 0; i < 3000; i++ { var ( - path = testutil.RandBytes(32) - node = testutil.RandomNode() + path = testrand.Bytes(32) + blob = testrand.Bytes(100) + node = trienode.New(crypto.Keccak256Hash(blob), blob) ) - nodes[common.Hash{}][string(path)] = trienode.New(node.Hash, node.Blob) + nodes[common.Hash{}][string(path)] = node } return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil) } @@ -149,10 +150,11 @@ func BenchmarkJournal(b *testing.B) { nodes[common.Hash{}] = make(map[string]*trienode.Node) for i := 0; i < 3000; i++ { var ( - path = testutil.RandBytes(32) - node = testutil.RandomNode() + path = testrand.Bytes(32) + blob = testrand.Bytes(100) + node = trienode.New(crypto.Keccak256Hash(blob), blob) ) - nodes[common.Hash{}][string(path)] = trienode.New(node.Hash, node.Blob) + nodes[common.Hash{}][string(path)] = node } // TODO(rjl493456442) a non-nil state set is expected. return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil) diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index d14b29e189..c421133e4f 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -17,7 +17,6 @@ package pathdb import ( - "errors" "fmt" "sync" @@ -29,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" - "golang.org/x/crypto/sha3" ) // trienodebuffer is a collection of modified trie nodes to aggregate the disk @@ -37,7 +35,7 @@ import ( // disk (since it basically is not-yet-written data). type trienodebuffer interface { // node retrieves the trie node with given node info. - node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) + node(owner common.Hash, path []byte) (*trienode.Node, bool) // commit merges the dirty nodes into the trienodebuffer. This operation won't take // the ownership of the nodes map which belongs to the bottom-most diff layer. @@ -114,7 +112,7 @@ func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *fastcache.C } } -// root implements the layer interface, returning root hash of corresponding state. +// rootHash implements the layer interface, returning root hash of corresponding state. func (dl *diskLayer) rootHash() common.Hash { return dl.root } @@ -124,7 +122,7 @@ func (dl *diskLayer) stateID() uint64 { return dl.id } -// parent implements the layer interface, returning nil as there's no layer +// parentLayer implements the layer interface, returning nil as there's no layer // below the disk. func (dl *diskLayer) parentLayer() layer { return nil @@ -150,68 +148,53 @@ func (dl *diskLayer) markStale() { dl.stale = true } -// Node implements the layer interface, retrieving the trie node with the +// node implements the layer interface, retrieving the trie node with the // provided node info. No error will be returned if the node is not found. -func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { +func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, common.Hash, *nodeLoc, error) { dl.lock.RLock() defer dl.lock.RUnlock() if dl.stale { - return nil, errSnapshotStale + return nil, common.Hash{}, nil, errSnapshotStale } // Try to retrieve the trie node from the not-yet-written // node buffer first. Note the buffer is lock free since // it's impossible to mutate the buffer before tagging the // layer as stale. - n, err := dl.buffer.node(owner, path, hash) - if err != nil { - return nil, err - } - if n != nil { + n, found := dl.buffer.node(owner, path) + if found { dirtyHitMeter.Mark(1) dirtyReadMeter.Mark(int64(len(n.Blob))) - return n.Blob, nil + dirtyNodeHitDepthHist.Update(int64(depth)) + return n.Blob, n.Hash, &nodeLoc{loc: locDirtyCache, depth: depth}, nil } dirtyMissMeter.Mark(1) // Try to retrieve the trie node from the clean memory cache + h := newHasher() + defer h.release() + key := cacheKey(owner, path) if dl.cleans != nil { if blob := dl.cleans.Get(nil, key); len(blob) > 0 { - h := newHasher() - defer h.release() - - got := h.hash(blob) - if got == hash { - cleanHitMeter.Mark(1) - cleanReadMeter.Mark(int64(len(blob))) - return blob, nil - } - cleanFalseMeter.Mark(1) - log.Error("Unexpected trie node in clean cache", "owner", owner, "path", path, "expect", hash, "got", got) + cleanHitMeter.Mark(1) + cleanReadMeter.Mark(int64(len(blob))) + return blob, h.hash(blob), &nodeLoc{loc: locCleanCache, depth: depth}, nil } cleanMissMeter.Mark(1) } // Try to retrieve the trie node from the disk. - var ( - nBlob []byte - nHash common.Hash - ) + var blob []byte if owner == (common.Hash{}) { - nBlob, nHash = rawdb.ReadAccountTrieNode(dl.db.diskdb, path) + blob = rawdb.ReadAccountTrieNode(dl.db.diskdb, path) } else { - nBlob, nHash = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path) + blob = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path) } - if nHash != hash { - diskFalseMeter.Mark(1) - log.Error("Unexpected trie node in disk", "owner", owner, "path", path, "expect", hash, "got", nHash) - return nil, newUnexpectedNodeError("disk", hash, nHash, owner, path, nBlob) + if dl.cleans != nil && len(blob) > 0 { + dl.cleans.Set(key, blob) + cleanWriteMeter.Mark(int64(len(blob))) } - if dl.cleans != nil && len(nBlob) > 0 { - dl.cleans.Set(key, nBlob) - cleanWriteMeter.Mark(int64(len(nBlob))) - } - return nBlob, nil + return blob, h.hash(blob), &nodeLoc{loc: locDiskLayer, depth: depth}, nil } // update implements the layer interface, returning a new diff layer on top @@ -293,23 +276,17 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { } // revert applies the given state history and return a reverted disk layer. -func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer, error) { +func (dl *diskLayer) revert(h *history) (*diskLayer, error) { if h.meta.root != dl.rootHash() { return nil, errUnexpectedHistory } - // Reject if the provided state history is incomplete. It's due to - // a large construct SELF-DESTRUCT which can't be handled because - // of memory limitation. - if len(h.meta.incomplete) > 0 { - return nil, errors.New("incomplete state history") - } if dl.id == 0 { return nil, fmt.Errorf("%w: zero state id", errStateUnrecoverable) } // Apply the reverse state changes upon the current state. This must // be done before holding the lock in order to access state in "this" // layer. - nodes, err := triestate.Apply(h.meta.parent, h.meta.root, h.accounts, h.storages, loader) + nodes, err := apply(dl.db, h.meta.parent, h.meta.root, h.accounts, h.storages) if err != nil { return nil, err } @@ -381,7 +358,7 @@ func (dl *diskLayer) resetCache() { type hasher struct{ sha crypto.KeccakState } var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} }, + New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} }, } func newHasher() *hasher { diff --git a/triedb/pathdb/errors.go b/triedb/pathdb/errors.go index 46b986f884..451c38815e 100644 --- a/triedb/pathdb/errors.go +++ b/triedb/pathdb/errors.go @@ -16,13 +16,7 @@ package pathdb -import ( - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) +import "errors" var ( // errDatabaseReadOnly is returned if the database is opened in read only mode @@ -34,7 +28,7 @@ var ( errDatabaseWaitSync = errors.New("waiting for sync") // errSnapshotStale is returned from data accessors if the underlying layer - // layer had been invalidated due to the chain progressing forward far enough + // had been invalidated due to the chain progressing forward far enough // to not maintain the layer's original state. errSnapshotStale = errors.New("layer stale") @@ -46,10 +40,6 @@ var ( // a destination without associated state history available. errStateUnrecoverable = errors.New("state is unrecoverable") - // errUnexpectedNode is returned if the requested node with specified path is - // not hash matched with expectation. - errUnexpectedNode = errors.New("unexpected node") - // errWriteImmutable is returned if write to background immutable nodecache // under asyncnodebuffer errWriteImmutable = errors.New("write immutable nodecache") @@ -64,11 +54,3 @@ var ( // errRevertImmutable is returned if revert the background immutable nodecache errRevertImmutable = errors.New("revert immutable nodecache") ) - -func newUnexpectedNodeError(loc string, expHash common.Hash, gotHash common.Hash, owner common.Hash, path []byte, blob []byte) error { - blobHex := "nil" - if len(blob) > 0 { - blobHex = hexutil.Encode(blob) - } - return fmt.Errorf("%w, loc: %s, node: (%x %v), %x!=%x, blob: %s", errUnexpectedNode, loc, owner, path, expHash, gotHash, blobHex) -} diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go new file mode 100644 index 0000000000..9074e4debf --- /dev/null +++ b/triedb/pathdb/execute.go @@ -0,0 +1,186 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see + +package pathdb + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-ethereum/triedb/database" +) + +// context wraps all fields for executing state diffs. +type context struct { + prevRoot common.Hash + postRoot common.Hash + accounts map[common.Address][]byte + storages map[common.Address]map[common.Hash][]byte + nodes *trienode.MergedNodeSet + + // TODO (rjl493456442) abstract out the state hasher + // for supporting verkle tree. + accountTrie *trie.Trie +} + +// apply processes the given state diffs, updates the corresponding post-state +// and returns the trie nodes that have been modified. +func apply(db database.Database, prevRoot common.Hash, postRoot common.Hash, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte) (map[common.Hash]map[string]*trienode.Node, error) { + tr, err := trie.New(trie.TrieID(postRoot), db) + if err != nil { + return nil, err + } + ctx := &context{ + prevRoot: prevRoot, + postRoot: postRoot, + accounts: accounts, + storages: storages, + accountTrie: tr, + nodes: trienode.NewMergedNodeSet(), + } + for addr, account := range accounts { + var err error + if len(account) == 0 { + err = deleteAccount(ctx, db, addr) + } else { + err = updateAccount(ctx, db, addr) + } + if err != nil { + return nil, fmt.Errorf("failed to revert state, err: %w", err) + } + } + root, result := tr.Commit(false) + if root != prevRoot { + return nil, fmt.Errorf("failed to revert state, want %#x, got %#x", prevRoot, root) + } + if err := ctx.nodes.Merge(result); err != nil { + return nil, err + } + return ctx.nodes.Flatten(), nil +} + +// updateAccount the account was present in prev-state, and may or may not +// existent in post-state. Apply the reverse diff and verify if the storage +// root matches the one in prev-state account. +func updateAccount(ctx *context, db database.Database, addr common.Address) error { + // The account was present in prev-state, decode it from the + // 'slim-rlp' format bytes. + h := newHasher() + defer h.release() + + addrHash := h.hash(addr.Bytes()) + prev, err := types.FullAccount(ctx.accounts[addr]) + if err != nil { + return err + } + // The account may or may not existent in post-state, try to + // load it and decode if it's found. + blob, err := ctx.accountTrie.Get(addrHash.Bytes()) + if err != nil { + return err + } + post := types.NewEmptyStateAccount() + if len(blob) != 0 { + if err := rlp.DecodeBytes(blob, &post); err != nil { + return err + } + } + // Apply all storage changes into the post-state storage trie. + st, err := trie.New(trie.StorageTrieID(ctx.postRoot, addrHash, post.Root), db) + if err != nil { + return err + } + for key, val := range ctx.storages[addr] { + var err error + if len(val) == 0 { + err = st.Delete(key.Bytes()) + } else { + err = st.Update(key.Bytes(), val) + } + if err != nil { + return err + } + } + root, result := st.Commit(false) + if root != prev.Root { + return errors.New("failed to reset storage trie") + } + // The returned set can be nil if storage trie is not changed + // at all. + if result != nil { + if err := ctx.nodes.Merge(result); err != nil { + return err + } + } + // Write the prev-state account into the main trie + full, err := rlp.EncodeToBytes(prev) + if err != nil { + return err + } + return ctx.accountTrie.Update(addrHash.Bytes(), full) +} + +// deleteAccount the account was not present in prev-state, and is expected +// to be existent in post-state. Apply the reverse diff and verify if the +// account and storage is wiped out correctly. +func deleteAccount(ctx *context, db database.Database, addr common.Address) error { + // The account must be existent in post-state, load the account. + h := newHasher() + defer h.release() + + addrHash := h.hash(addr.Bytes()) + blob, err := ctx.accountTrie.Get(addrHash.Bytes()) + if err != nil { + return err + } + if len(blob) == 0 { + return fmt.Errorf("account is non-existent %#x", addrHash) + } + var post types.StateAccount + if err := rlp.DecodeBytes(blob, &post); err != nil { + return err + } + st, err := trie.New(trie.StorageTrieID(ctx.postRoot, addrHash, post.Root), db) + if err != nil { + return err + } + for key, val := range ctx.storages[addr] { + if len(val) != 0 { + return errors.New("expect storage deletion") + } + if err := st.Delete(key.Bytes()); err != nil { + return err + } + } + root, result := st.Commit(false) + if root != types.EmptyRootHash { + return errors.New("failed to clear storage trie") + } + // The returned set can be nil if storage trie is not changed + // at all. + if result != nil { + if err := ctx.nodes.Merge(result); err != nil { + return err + } + } + // Delete the post-state account from the main trie. + return ctx.accountTrie.Delete(addrHash.Bytes()) +} diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 051e122bec..d77f7aa04d 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -21,6 +21,7 @@ import ( "encoding/binary" "errors" "fmt" + "slices" "time" "github.com/ethereum/go-ethereum/common" @@ -28,7 +29,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie/triestate" - "golang.org/x/exp/slices" + "golang.org/x/exp/maps" ) // State history records the state changes involved in executing a block. The @@ -66,7 +67,7 @@ import ( const ( accountIndexSize = common.AddressLength + 13 // The length of encoded account index slotIndexSize = common.HashLength + 5 // The length of encoded slot index - historyMetaSize = 9 + 2*common.HashLength // The length of fixed size part of meta object + historyMetaSize = 9 + 2*common.HashLength // The length of encoded history meta stateHistoryVersion = uint8(0) // initial version of state history structure. ) @@ -192,23 +193,19 @@ func (i *slotIndex) decode(blob []byte) { // meta describes the meta data of state history object. type meta struct { - version uint8 // version tag of history object - parent common.Hash // prev-state root before the state transition - root common.Hash // post-state root after the state transition - block uint64 // associated block number - incomplete []common.Address // list of address whose storage set is incomplete + version uint8 // version tag of history object + parent common.Hash // prev-state root before the state transition + root common.Hash // post-state root after the state transition + block uint64 // associated block number } // encode packs the meta object into byte stream. func (m *meta) encode() []byte { - buf := make([]byte, historyMetaSize+len(m.incomplete)*common.AddressLength) + buf := make([]byte, historyMetaSize) buf[0] = m.version copy(buf[1:1+common.HashLength], m.parent.Bytes()) copy(buf[1+common.HashLength:1+2*common.HashLength], m.root.Bytes()) binary.BigEndian.PutUint64(buf[1+2*common.HashLength:historyMetaSize], m.block) - for i, h := range m.incomplete { - copy(buf[i*common.AddressLength+historyMetaSize:], h.Bytes()) - } return buf[:] } @@ -219,20 +216,13 @@ func (m *meta) decode(blob []byte) error { } switch blob[0] { case stateHistoryVersion: - if len(blob) < historyMetaSize { + if len(blob) != historyMetaSize { return fmt.Errorf("invalid state history meta, len: %d", len(blob)) } - if (len(blob)-historyMetaSize)%common.AddressLength != 0 { - return fmt.Errorf("corrupted state history meta, len: %d", len(blob)) - } m.version = blob[0] m.parent = common.BytesToHash(blob[1 : 1+common.HashLength]) m.root = common.BytesToHash(blob[1+common.HashLength : 1+2*common.HashLength]) m.block = binary.BigEndian.Uint64(blob[1+2*common.HashLength : historyMetaSize]) - for pos := historyMetaSize; pos < len(blob); { - m.incomplete = append(m.incomplete, common.BytesToAddress(blob[pos:pos+common.AddressLength])) - pos += common.AddressLength - } return nil default: return fmt.Errorf("unknown version %d", blob[0]) @@ -255,35 +245,22 @@ type history struct { // newHistory constructs the state history object with provided state change set. func newHistory(root common.Hash, parent common.Hash, block uint64, states *triestate.Set) *history { var ( - accountList []common.Address + accountList = maps.Keys(states.Accounts) storageList = make(map[common.Address][]common.Hash) - incomplete []common.Address ) - for addr := range states.Accounts { - accountList = append(accountList, addr) - } slices.SortFunc(accountList, common.Address.Cmp) for addr, slots := range states.Storages { - slist := make([]common.Hash, 0, len(slots)) - for slotHash := range slots { - slist = append(slist, slotHash) - } + slist := maps.Keys(slots) slices.SortFunc(slist, common.Hash.Cmp) storageList[addr] = slist } - for addr := range states.Incomplete { - incomplete = append(incomplete, addr) - } - slices.SortFunc(incomplete, common.Address.Cmp) - return &history{ meta: &meta{ - version: stateHistoryVersion, - parent: parent, - root: root, - block: block, - incomplete: incomplete, + version: stateHistoryVersion, + parent: parent, + root: root, + block: block, }, accounts: states.Accounts, accountList: accountList, @@ -402,10 +379,11 @@ func (r *decoder) readAccount(pos int) (accountIndex, []byte, error) { func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common.Hash][]byte, error) { var ( last common.Hash - list []common.Hash - storage = make(map[common.Hash][]byte) + count = int(accIndex.storageSlots) + list = make([]common.Hash, 0, count) + storage = make(map[common.Hash][]byte, count) ) - for j := 0; j < int(accIndex.storageSlots); j++ { + for j := 0; j < count; j++ { var ( index slotIndex start = (accIndex.storageOffset + uint32(j)) * uint32(slotIndexSize) @@ -448,9 +426,10 @@ func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common. // decode deserializes the account and storage data from the provided byte stream. func (h *history) decode(accountData, storageData, accountIndexes, storageIndexes []byte) error { var ( - accounts = make(map[common.Address][]byte) + count = len(accountIndexes) / accountIndexSize + accounts = make(map[common.Address][]byte, count) storages = make(map[common.Address]map[common.Hash][]byte) - accountList []common.Address + accountList = make([]common.Address, 0, count) storageList = make(map[common.Address][]common.Hash) r = &decoder{ @@ -463,7 +442,7 @@ func (h *history) decode(accountData, storageData, accountIndexes, storageIndexe if err := r.verify(); err != nil { return err } - for i := 0; i < len(accountIndexes)/accountIndexSize; i++ { + for i := 0; i < count; i++ { // Resolve account first accIndex, accData, err := r.readAccount(i) if err != nil { @@ -490,8 +469,8 @@ func (h *history) decode(accountData, storageData, accountIndexes, storageIndexe } // readHistory reads and decodes the state history object by the given id. -func readHistory(freezer *rawdb.ResettableFreezer, id uint64) (*history, error) { - blob := rawdb.ReadStateHistoryMeta(freezer, id) +func readHistory(reader ethdb.AncientReader, id uint64) (*history, error) { + blob := rawdb.ReadStateHistoryMeta(reader, id) if len(blob) == 0 { return nil, fmt.Errorf("state history not found %d", id) } @@ -501,10 +480,10 @@ func readHistory(freezer *rawdb.ResettableFreezer, id uint64) (*history, error) } var ( dec = history{meta: &m} - accountData = rawdb.ReadStateAccountHistory(freezer, id) - storageData = rawdb.ReadStateStorageHistory(freezer, id) - accountIndexes = rawdb.ReadStateAccountIndex(freezer, id) - storageIndexes = rawdb.ReadStateStorageIndex(freezer, id) + accountData = rawdb.ReadStateAccountHistory(reader, id) + storageData = rawdb.ReadStateStorageHistory(reader, id) + accountIndexes = rawdb.ReadStateAccountIndex(reader, id) + storageIndexes = rawdb.ReadStateStorageIndex(reader, id) ) if err := dec.decode(accountData, storageData, accountIndexes, storageIndexes); err != nil { return nil, err @@ -513,7 +492,7 @@ func readHistory(freezer *rawdb.ResettableFreezer, id uint64) (*history, error) } // writeHistory persists the state history with the provided state set. -func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error { +func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error { // Short circuit if state set is not available. if dl.states == nil { return errors.New("state change set is not available") @@ -527,7 +506,7 @@ func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error { indexSize := common.StorageSize(len(accountIndex) + len(storageIndex)) // Write history data into five freezer table respectively. - rawdb.WriteStateHistory(freezer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData) + rawdb.WriteStateHistory(writer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData) historyDataBytesMeter.Mark(int64(dataSize)) historyIndexBytesMeter.Mark(int64(indexSize)) @@ -539,13 +518,13 @@ func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error { // checkHistories retrieves a batch of meta objects with the specified range // and performs the callback on each item. -func checkHistories(freezer *rawdb.ResettableFreezer, start, count uint64, check func(*meta) error) error { +func checkHistories(reader ethdb.AncientReader, start, count uint64, check func(*meta) error) error { for count > 0 { number := count if number > 10000 { number = 10000 // split the big read into small chunks } - blobs, err := rawdb.ReadStateHistoryMetaList(freezer, start, number) + blobs, err := rawdb.ReadStateHistoryMetaList(reader, start, number) if err != nil { return err } @@ -566,12 +545,12 @@ func checkHistories(freezer *rawdb.ResettableFreezer, start, count uint64, check // truncateFromHead removes the extra state histories from the head with the given // parameters. It returns the number of items removed from the head. -func truncateFromHead(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, nhead uint64) (int, error) { - ohead, err := freezer.Ancients() +func truncateFromHead(db ethdb.Batcher, store ethdb.AncientStore, nhead uint64) (int, error) { + ohead, err := store.Ancients() if err != nil { return 0, err } - otail, err := freezer.Tail() + otail, err := store.Tail() if err != nil { return 0, err } @@ -584,7 +563,7 @@ func truncateFromHead(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, nhead return 0, nil } // Load the meta objects in range [nhead+1, ohead] - blobs, err := rawdb.ReadStateHistoryMetaList(freezer, nhead+1, ohead-nhead) + blobs, err := rawdb.ReadStateHistoryMetaList(store, nhead+1, ohead-nhead) if err != nil { return 0, err } @@ -599,7 +578,7 @@ func truncateFromHead(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, nhead if err := batch.Write(); err != nil { return 0, err } - ohead, err = freezer.TruncateHead(nhead) + ohead, err = store.TruncateHead(nhead) if err != nil { return 0, err } @@ -608,12 +587,12 @@ func truncateFromHead(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, nhead // truncateFromTail removes the extra state histories from the tail with the given // parameters. It returns the number of items removed from the tail. -func truncateFromTail(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, ntail uint64) (int, error) { - ohead, err := freezer.Ancients() +func truncateFromTail(db ethdb.Batcher, store ethdb.AncientStore, ntail uint64) (int, error) { + ohead, err := store.Ancients() if err != nil { return 0, err } - otail, err := freezer.Tail() + otail, err := store.Tail() if err != nil { return 0, err } @@ -626,7 +605,7 @@ func truncateFromTail(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, ntail return 0, nil } // Load the meta objects in range [otail+1, ntail] - blobs, err := rawdb.ReadStateHistoryMetaList(freezer, otail+1, ntail-otail) + blobs, err := rawdb.ReadStateHistoryMetaList(store, otail+1, ntail-otail) if err != nil { return 0, err } @@ -641,7 +620,7 @@ func truncateFromTail(db ethdb.Batcher, freezer *rawdb.ResettableFreezer, ntail if err := batch.Write(); err != nil { return 0, err } - otail, err = freezer.TruncateTail(ntail) + otail, err = store.TruncateTail(ntail) if err != nil { return 0, err } diff --git a/triedb/pathdb/history_inspect.go b/triedb/pathdb/history_inspect.go new file mode 100644 index 0000000000..240474da37 --- /dev/null +++ b/triedb/pathdb/history_inspect.go @@ -0,0 +1,151 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see first { + first = start + } + // Load the id of the last history object in local store. + head, err := freezer.Ancients() + if err != nil { + return 0, 0, err + } + last := head - 1 + if end != 0 && end < last { + last = end + } + // Make sure the range is valid + if first >= last { + return 0, 0, fmt.Errorf("range is invalid, first: %d, last: %d", first, last) + } + return first, last, nil +} + +func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory func(*history, *HistoryStats)) (*HistoryStats, error) { + var ( + stats = &HistoryStats{} + init = time.Now() + logged = time.Now() + ) + start, end, err := sanitizeRange(start, end, freezer) + if err != nil { + return nil, err + } + for id := start; id <= end; id += 1 { + // The entire history object is decoded, although it's unnecessary for + // account inspection. TODO(rjl493456442) optimization is worthwhile. + h, err := readHistory(freezer, id) + if err != nil { + return nil, err + } + if id == start { + stats.Start = h.meta.block + } + if id == end { + stats.End = h.meta.block + } + onHistory(h, stats) + + if time.Since(logged) > time.Second*8 { + logged = time.Now() + eta := float64(time.Since(init)) / float64(id-start+1) * float64(end-id) + log.Info("Inspecting state history", "checked", id-start+1, "left", end-id, "elapsed", common.PrettyDuration(time.Since(init)), "eta", common.PrettyDuration(eta)) + } + } + log.Info("Inspected state history", "total", end-start+1, "elapsed", common.PrettyDuration(time.Since(init))) + return stats, nil +} + +// accountHistory inspects the account history within the range. +func accountHistory(freezer ethdb.AncientReader, address common.Address, start, end uint64) (*HistoryStats, error) { + return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) { + blob, exists := h.accounts[address] + if !exists { + return + } + stats.Blocks = append(stats.Blocks, h.meta.block) + stats.Origins = append(stats.Origins, blob) + }) +} + +// storageHistory inspects the storage history within the range. +func storageHistory(freezer ethdb.AncientReader, address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) { + return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) { + slots, exists := h.storages[address] + if !exists { + return + } + blob, exists := slots[slot] + if !exists { + return + } + stats.Blocks = append(stats.Blocks, h.meta.block) + stats.Origins = append(stats.Origins, blob) + }) +} + +// historyRange returns the block number range of local state histories. +func historyRange(freezer ethdb.AncientReader) (uint64, uint64, error) { + // Load the id of the first history object in local store. + tail, err := freezer.Tail() + if err != nil { + return 0, 0, err + } + first := tail + 1 + + // Load the id of the last history object in local store. + head, err := freezer.Ancients() + if err != nil { + return 0, 0, err + } + last := head - 1 + + fh, err := readHistory(freezer, first) + if err != nil { + return 0, 0, err + } + lh, err := readHistory(freezer, last) + if err != nil { + return 0, 0, err + } + return fh.meta.block, lh.meta.block, nil +} diff --git a/triedb/pathdb/history_test.go b/triedb/pathdb/history_test.go index 0a024bec2b..586f907fe4 100644 --- a/triedb/pathdb/history_test.go +++ b/triedb/pathdb/history_test.go @@ -26,8 +26,8 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie/testutil" "github.com/ethereum/go-ethereum/trie/triestate" ) @@ -38,20 +38,20 @@ func randomStateSet(n int) *triestate.Set { storages = make(map[common.Address]map[common.Hash][]byte) ) for i := 0; i < n; i++ { - addr := testutil.RandomAddress() + addr := testrand.Address() storages[addr] = make(map[common.Hash][]byte) for j := 0; j < 3; j++ { - v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testutil.RandBytes(32))) - storages[addr][testutil.RandomHash()] = v + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) + storages[addr][testrand.Hash()] = v } account := generateAccount(types.EmptyRootHash) accounts[addr] = types.SlimAccountRLP(account) } - return triestate.New(accounts, storages, nil) + return triestate.New(accounts, storages) } func makeHistory() *history { - return newHistory(testutil.RandomHash(), types.EmptyRootHash, 0, randomStateSet(3)) + return newHistory(testrand.Hash(), types.EmptyRootHash, 0, randomStateSet(3)) } func makeHistories(n int) []*history { @@ -60,7 +60,7 @@ func makeHistories(n int) []*history { result []*history ) for i := 0; i < n; i++ { - root := testutil.RandomHash() + root := testrand.Hash() h := newHistory(root, parent, uint64(i), randomStateSet(3)) parent = root result = append(result, h) @@ -102,7 +102,7 @@ func TestEncodeDecodeHistory(t *testing.T) { } } -func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer *rawdb.ResettableFreezer, id uint64, root common.Hash, exist bool) { +func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, id uint64, root common.Hash, exist bool) { blob := rawdb.ReadStateHistoryMeta(freezer, id) if exist && len(blob) == 0 { t.Fatalf("Failed to load trie history, %d", id) @@ -118,7 +118,7 @@ func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer *rawdb.Resettab } } -func checkHistoriesInRange(t *testing.T, db ethdb.KeyValueReader, freezer *rawdb.ResettableFreezer, from, to uint64, roots []common.Hash, exist bool) { +func checkHistoriesInRange(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, from, to uint64, roots []common.Hash, exist bool) { for i, j := from, 0; i <= to; i, j = i+1, j+1 { checkHistory(t, db, freezer, i, roots[j], exist) } @@ -129,7 +129,7 @@ func TestTruncateHeadHistory(t *testing.T) { roots []common.Hash hs = makeHistories(10) db = rawdb.NewMemoryDatabase() - freezer, _ = openFreezer(t.TempDir(), false) + freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -157,7 +157,7 @@ func TestTruncateTailHistory(t *testing.T) { roots []common.Hash hs = makeHistories(10) db = rawdb.NewMemoryDatabase() - freezer, _ = openFreezer(t.TempDir(), false) + freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -200,7 +200,7 @@ func TestTruncateTailHistories(t *testing.T) { roots []common.Hash hs = makeHistories(10) db = rawdb.NewMemoryDatabase() - freezer, _ = openFreezer(t.TempDir()+fmt.Sprintf("%d", i), false) + freezer, _ = rawdb.NewStateFreezer(t.TempDir()+fmt.Sprintf("%d", i), false, false) ) defer freezer.Close() @@ -228,7 +228,7 @@ func TestTruncateOutOfRange(t *testing.T) { var ( hs = makeHistories(10) db = rawdb.NewMemoryDatabase() - freezer, _ = openFreezer(t.TempDir(), false) + freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -268,11 +268,6 @@ func TestTruncateOutOfRange(t *testing.T) { } } -// openFreezer initializes the freezer instance for storing state histories. -func openFreezer(datadir string, readOnly bool) (*rawdb.ResettableFreezer, error) { - return rawdb.NewStateFreezer(datadir, readOnly, 0) -} - func compareSet[k comparable](a, b map[k][]byte) bool { if len(a) != len(b) { return false diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 3150ed1795..1bd447cfce 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -45,7 +45,13 @@ var ( errUnmatchedJournal = errors.New("unmatched journal") ) -const journalVersion uint64 = 0 +// journalVersion ensures that an incompatible journal is detected and discarded. +// +// Changelog: +// +// - Version 0: initial version +// - Version 1: storage.Incomplete field is removed +const journalVersion uint64 = 1 // journalNode represents a trie node persisted in the journal. type journalNode struct { @@ -68,10 +74,9 @@ type journalAccounts struct { // journalStorage represents a list of storage slots belong to an account. type journalStorage struct { - Incomplete bool - Account common.Address - Hashes []common.Hash - Slots [][]byte + Account common.Address + Hashes []common.Hash + Slots [][]byte } type JournalWriter interface { @@ -245,9 +250,10 @@ func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) { // loadLayers loads a pre-existing state layer backed by a key-value store. func (db *Database) loadLayers() layer { // Retrieve the root node of persistent state. - _, root := rawdb.ReadAccountTrieNode(db.diskdb, nil) - root = types.TrieRootHash(root) - + var root = types.EmptyRootHash + if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { + root = crypto.Keccak256Hash(blob) + } // Load the layers by resolving the journal head, err := db.loadJournal(root) if err == nil { @@ -382,11 +388,10 @@ func (db *Database) loadDiffLayer(parent layer, r *rlp.Stream, journalTypeForRea } // Read state changes from journal var ( - jaccounts journalAccounts - jstorages []journalStorage - accounts = make(map[common.Address][]byte) - storages = make(map[common.Address]map[common.Hash][]byte) - incomplete = make(map[common.Address]struct{}) + jaccounts journalAccounts + jstorages []journalStorage + accounts = make(map[common.Address][]byte) + storages = make(map[common.Address]map[common.Hash][]byte) ) if err := journalBuf.Decode(&jaccounts); err != nil { return nil, fmt.Errorf("load diff accounts: %v", err) @@ -406,9 +411,6 @@ func (db *Database) loadDiffLayer(parent layer, r *rlp.Stream, journalTypeForRea set[h] = nil } } - if entry.Incomplete { - incomplete[entry.Account] = struct{}{} - } storages[entry.Account] = set } @@ -426,7 +428,7 @@ func (db *Database) loadDiffLayer(parent layer, r *rlp.Stream, journalTypeForRea log.Debug("Loaded diff layer journal", "root", root, "parent", parent.rootHash(), "id", parent.stateID()+1, "block", block) - return db.loadDiffLayer(newDiffLayer(parent, root, parent.stateID()+1, block, nodes, triestate.New(accounts, storages, incomplete)), r, journalTypeForReader) + return db.loadDiffLayer(newDiffLayer(parent, root, parent.stateID()+1, block, nodes, triestate.New(accounts, storages)), r, journalTypeForReader) } // journal implements the layer interface, marshaling the un-flushed trie nodes @@ -526,9 +528,6 @@ func (dl *diffLayer) journal(w io.Writer, journalType JournalType) error { storage := make([]journalStorage, 0, len(dl.states.Storages)) for addr, slots := range dl.states.Storages { entry := journalStorage{Account: addr} - if _, ok := dl.states.Incomplete[addr]; ok { - entry.Incomplete = true - } for slotHash, slot := range slots { entry.Hashes = append(entry.Hashes, slotHash) entry.Slots = append(entry.Slots, slot) @@ -594,14 +593,13 @@ func (db *Database) Journal(root common.Hash) error { if err := rlp.Encode(journal, journalVersion); err != nil { return err } - // The stored state in disk might be empty, convert the - // root to emptyRoot in this case. - _, diskroot := rawdb.ReadAccountTrieNode(db.diskdb, nil) - diskroot = types.TrieRootHash(diskroot) - // Secondly write out the state root in disk, ensure all layers // on top are continuous with disk. - if err := rlp.Encode(journal, diskroot); err != nil { + diskRoot := types.EmptyRootHash + if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { + diskRoot = crypto.Keccak256Hash(blob) + } + if err := rlp.Encode(journal, diskRoot); err != nil { return err } // Finally write out the journal of each layer in reverse order. diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 67267b666a..327cca2a91 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -33,6 +33,7 @@ var ( cleanFalseMeter = metrics.NewRegisteredMeter("pathdb/clean/false", nil) dirtyFalseMeter = metrics.NewRegisteredMeter("pathdb/dirty/false", nil) diskFalseMeter = metrics.NewRegisteredMeter("pathdb/disk/false", nil) + diffFalseMeter = metrics.NewRegisteredMeter("pathdb/diff/false", nil) commitTimeTimer = metrics.NewRegisteredTimer("pathdb/commit/time", nil) commitNodesMeter = metrics.NewRegisteredMeter("pathdb/commit/nodes", nil) diff --git a/triedb/pathdb/nodebuffer.go b/triedb/pathdb/nodebuffer.go index a978d559b4..dd40898ada 100644 --- a/triedb/pathdb/nodebuffer.go +++ b/triedb/pathdb/nodebuffer.go @@ -17,7 +17,9 @@ package pathdb import ( + "bytes" "fmt" + "maps" "time" "github.com/VictoriaMetrics/fastcache" @@ -61,21 +63,16 @@ func newNodeBuffer(limit int, nodes map[common.Hash]map[string]*trienode.Node, l } // node retrieves the trie node with given node info. -func (b *nodebuffer) node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) { +func (b *nodebuffer) node(owner common.Hash, path []byte) (*trienode.Node, bool) { subset, ok := b.nodes[owner] if !ok { - return nil, nil + return nil, false } n, ok := subset[string(path)] if !ok { - return nil, nil + return nil, false } - if n.Hash != hash { - dirtyFalseMeter.Mark(1) - log.Error("Unexpected trie node in node buffer", "owner", owner, "path", path, "expect", hash, "got", n.Hash) - return nil, newUnexpectedNodeError("dirty", hash, n.Hash, owner, path, n.Blob) - } - return n, nil + return n, true } // commit merges the dirty nodes into the nodebuffer. This operation won't take @@ -96,12 +93,10 @@ func (b *nodebuffer) commit(nodes map[common.Hash]map[string]*trienode.Node) tri // The nodes belong to original diff layer are still accessible even // after merging, thus the ownership of nodes map should still belong // to original layer and any mutation on it should be prevented. - current = make(map[string]*trienode.Node) for path, n := range subset { - current[path] = n delta += int64(len(n.Blob) + len(path) + len(owner)) } - b.nodes[owner] = current + b.nodes[owner] = maps.Clone(subset) continue } for path, n := range subset { @@ -155,14 +150,14 @@ func (b *nodebuffer) revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[s // // In case of database rollback, don't panic if this "clean" // node occurs which is not present in buffer. - var nhash common.Hash + var blob []byte if owner == (common.Hash{}) { - _, nhash = rawdb.ReadAccountTrieNode(db, []byte(path)) + blob = rawdb.ReadAccountTrieNode(db, []byte(path)) } else { - _, nhash = rawdb.ReadStorageTrieNode(db, owner, []byte(path)) + blob = rawdb.ReadStorageTrieNode(db, owner, []byte(path)) } // Ignore the clean node in the case described above. - if nhash == n.Hash { + if bytes.Equal(blob, n.Blob) { continue } panic(fmt.Sprintf("non-existent node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex())) @@ -206,6 +201,19 @@ func (b *nodebuffer) setSize(size int, db ethdb.KeyValueStore, clean *fastcache. return b.flush(db, clean, id, false) } +// allocBatch returns a database batch with pre-allocated buffer. +func (b *nodebuffer) allocBatch(db ethdb.KeyValueStore) ethdb.Batch { + var metasize int + for owner, nodes := range b.nodes { + if owner == (common.Hash{}) { + metasize += len(nodes) * len(rawdb.TrieNodeAccountPrefix) // database key prefix + } else { + metasize += len(nodes) * (len(rawdb.TrieNodeStoragePrefix) + common.HashLength) // database key prefix + owner + } + } + return db.NewBatchWithSize((metasize + int(b.size)) * 11 / 10) // extra 10% for potential pebble internal stuff +} + // flush persists the in-memory dirty trie node into the disk if the configured // memory threshold is reached. Note, all data must be written atomically. func (b *nodebuffer) flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64, force bool) error { @@ -219,11 +227,7 @@ func (b *nodebuffer) flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id ui } var ( start = time.Now() - // Although the calculation of b.size has been as accurate as possible, - // some omissions were still found during testing and code review, but - // we are still not sure if it is completely accurate. For better protection, - // some redundancy is added here. - batch = db.NewBatchWithSize(int(float64(b.size) * DefaultBatchRedundancyRate)) + batch = b.allocBatch(db) ) nodes := writeNodes(batch, b.nodes, clean) rawdb.WritePersistentStateID(batch, id) diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go new file mode 100644 index 0000000000..6a58493ba6 --- /dev/null +++ b/triedb/pathdb/reader.go @@ -0,0 +1,94 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see + +package pathdb + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/triedb/database" +) + +// The types of locations where the node is found. +const ( + locDirtyCache = "dirty" // dirty cache + locCleanCache = "clean" // clean cache + locDiskLayer = "disk" // persistent state + locDiffLayer = "diff" // diff layers +) + +// nodeLoc is a helpful structure that contains the location where the node +// is found, as it's useful for debugging purposes. +type nodeLoc struct { + loc string + depth int +} + +// string returns the string representation of node location. +func (loc *nodeLoc) string() string { + return fmt.Sprintf("loc: %s, depth: %d", loc.loc, loc.depth) +} + +// reader implements the database.Reader interface, providing the functionalities to +// retrieve trie nodes by wrapping the internal state layer. +type reader struct { + layer layer + noHashCheck bool +} + +// Node implements database.Reader interface, retrieving the node with specified +// node info. Don't modify the returned byte slice since it's not deep-copied +// and still be referenced by database. +func (r *reader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { + blob, got, loc, err := r.layer.node(owner, path, 0) + if err != nil { + return nil, err + } + // Error out if the local one is inconsistent with the target. + if !r.noHashCheck && got != hash { + // Location is always available even if the node + // is not found. + switch loc.loc { + case locCleanCache: + cleanFalseMeter.Mark(1) + case locDirtyCache: + dirtyFalseMeter.Mark(1) + case locDiffLayer: + diffFalseMeter.Mark(1) + case locDiskLayer: + diskFalseMeter.Mark(1) + } + blobHex := "nil" + if len(blob) > 0 { + blobHex = hexutil.Encode(blob) + } + log.Error("Unexpected trie node", "location", loc.loc, "owner", owner.Hex(), "path", path, "expect", hash.Hex(), "got", got.Hex(), "blob", blobHex) + return nil, fmt.Errorf("unexpected node: (%x %v), %x!=%x, %s, blob: %s", owner, path, hash, got, loc.string(), blobHex) + } + return blob, nil +} + +// Reader retrieves a layer belonging to the given state root. +func (db *Database) Reader(root common.Hash) (database.Reader, error) { + layer := db.tree.get(root) + if layer == nil { + return nil, fmt.Errorf("state %#x is not available", root) + } + return &reader{layer: layer, noHashCheck: db.isVerkle}, nil +} diff --git a/triedb/pathdb/testutils.go b/triedb/pathdb/testutils.go deleted file mode 100644 index d6fdacb421..0000000000 --- a/triedb/pathdb/testutils.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package pathdb - -import ( - "bytes" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/trie/trienode" - "github.com/ethereum/go-ethereum/trie/triestate" - "golang.org/x/exp/slices" -) - -// testHasher is a test utility for computing root hash of a batch of state -// elements. The hash algorithm is to sort all the elements in lexicographical -// order, concat the key and value in turn, and perform hash calculation on -// the concatenated bytes. Except the root hash, a nodeset will be returned -// once Commit is called, which contains all the changes made to hasher. -type testHasher struct { - owner common.Hash // owner identifier - root common.Hash // original root - dirties map[common.Hash][]byte // dirty states - cleans map[common.Hash][]byte // clean states -} - -// newTestHasher constructs a hasher object with provided states. -func newTestHasher(owner common.Hash, root common.Hash, cleans map[common.Hash][]byte) (*testHasher, error) { - if cleans == nil { - cleans = make(map[common.Hash][]byte) - } - if got, _ := hash(cleans); got != root { - return nil, fmt.Errorf("state root mismatched, want: %x, got: %x", root, got) - } - return &testHasher{ - owner: owner, - root: root, - dirties: make(map[common.Hash][]byte), - cleans: cleans, - }, nil -} - -// Get returns the value for key stored in the trie. -func (h *testHasher) Get(key []byte) ([]byte, error) { - hash := common.BytesToHash(key) - val, ok := h.dirties[hash] - if ok { - return val, nil - } - return h.cleans[hash], nil -} - -// Update associates key with value in the trie. -func (h *testHasher) Update(key, value []byte) error { - h.dirties[common.BytesToHash(key)] = common.CopyBytes(value) - return nil -} - -// Delete removes any existing value for key from the trie. -func (h *testHasher) Delete(key []byte) error { - h.dirties[common.BytesToHash(key)] = nil - return nil -} - -// Commit computes the new hash of the states and returns the set with all -// state changes. -func (h *testHasher) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { - var ( - nodes = make(map[common.Hash][]byte) - set = trienode.NewNodeSet(h.owner) - ) - for hash, val := range h.cleans { - nodes[hash] = val - } - for hash, val := range h.dirties { - nodes[hash] = val - if bytes.Equal(val, h.cleans[hash]) { - continue - } - if len(val) == 0 { - set.AddNode(hash.Bytes(), trienode.NewDeleted()) - } else { - set.AddNode(hash.Bytes(), trienode.New(crypto.Keccak256Hash(val), val)) - } - } - root, blob := hash(nodes) - - // Include the dirty root node as well. - if root != types.EmptyRootHash && root != h.root { - set.AddNode(nil, trienode.New(root, blob)) - } - if root == types.EmptyRootHash && h.root != types.EmptyRootHash { - set.AddNode(nil, trienode.NewDeleted()) - } - return root, set, nil -} - -// hash performs the hash computation upon the provided states. -func hash(states map[common.Hash][]byte) (common.Hash, []byte) { - var hs []common.Hash - for hash := range states { - hs = append(hs, hash) - } - slices.SortFunc(hs, common.Hash.Cmp) - - var input []byte - for _, hash := range hs { - if len(states[hash]) == 0 { - continue - } - input = append(input, hash.Bytes()...) - input = append(input, states[hash]...) - } - if len(input) == 0 { - return types.EmptyRootHash, nil - } - return crypto.Keccak256Hash(input), input -} - -type hashLoader struct { - accounts map[common.Hash][]byte - storages map[common.Hash]map[common.Hash][]byte -} - -func newHashLoader(accounts map[common.Hash][]byte, storages map[common.Hash]map[common.Hash][]byte) *hashLoader { - return &hashLoader{ - accounts: accounts, - storages: storages, - } -} - -// OpenTrie opens the main account trie. -func (l *hashLoader) OpenTrie(root common.Hash) (triestate.Trie, error) { - return newTestHasher(common.Hash{}, root, l.accounts) -} - -// OpenStorageTrie opens the storage trie of an account. -func (l *hashLoader) OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (triestate.Trie, error) { - return newTestHasher(addrHash, root, l.storages[addrHash]) -}